summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore306
-rw-r--r--.gitmirrorselective1
-rw-r--r--BuildToolsVersion.txt2
-rw-r--r--CMakeLists.txt130
-rw-r--r--Documentation/README.md2
-rw-r--r--Documentation/botr/README.md (renamed from Documentation/botr/_tableOfContents.md)0
-rw-r--r--Documentation/botr/clr-abi.md6
-rw-r--r--Documentation/botr/exceptions.md12
-rw-r--r--Documentation/botr/garbage-collection.md2
-rw-r--r--Documentation/building/crossgen.md43
-rw-r--r--Documentation/building/linux-instructions.md8
-rw-r--r--Documentation/building/osx-instructions.md20
-rw-r--r--Documentation/building/testing-with-corefx.md6
-rw-r--r--Documentation/building/viewing-jit-dumps.md2
-rw-r--r--Documentation/building/windows-instructions.md196
-rw-r--r--Documentation/coding-guidelines/clr-code-guide.md5
-rw-r--r--Documentation/design-docs/multi-reg-call-nodes.md230
-rw-r--r--Documentation/project-docs/adding_new_public_apis.md23
-rw-r--r--Documentation/project-docs/ci-trigger-phrases.md112
-rw-r--r--Documentation/project-docs/glossary.md2
-rw-r--r--Documentation/workflow/EditingAndDebugging.md49
-rw-r--r--Documentation/workflow/IssuesFeedbackEngagement.md37
-rw-r--r--Documentation/workflow/OfficalAndDailyBuilds.md79
-rw-r--r--Documentation/workflow/RunningTests.md10
-rw-r--r--Documentation/workflow/UsingCoreRun.md83
-rw-r--r--Documentation/workflow/UsingYourBuild.md215
-rw-r--r--DotnetCLIVersion.txt2
-rw-r--r--README.md292
-rwxr-xr-xbinclash.log0
-rw-r--r--build-packages.cmd36
-rwxr-xr-xbuild-packages.sh90
-rw-r--r--build-test.cmd82
-rw-r--r--build.cmd89
-rw-r--r--build.proj4
-rwxr-xr-xbuild.sh171
-rw-r--r--clean.cmd2
-rw-r--r--clr.coreclr.props3
-rw-r--r--clr.defines.targets3
-rw-r--r--clrdefinitions.cmake17
-rw-r--r--config.json113
-rw-r--r--cross/arm/sources.list.jessie3
-rw-r--r--cross/arm/sources.list.xenial11
-rw-r--r--cross/arm64/sources.list.xenial11
-rwxr-xr-xcross/build-rootfs.sh96
-rw-r--r--cross/x86/sources.list.trusty11
-rw-r--r--cross/x86/sources.list.vivid11
-rw-r--r--cross/x86/sources.list.wily11
-rw-r--r--cross/x86/sources.list.xenial11
-rw-r--r--cross/x86/toolchain.cmake40
-rw-r--r--cross/x86/tryrun.cmake127
-rw-r--r--crosscomponents.cmake1
-rw-r--r--dependencies.props24
-rw-r--r--dir.props8
-rwxr-xr-xextract-from-json.py56
-rw-r--r--functions.cmake18
-rw-r--r--init-tools.cmd18
-rw-r--r--init-tools.log539
-rwxr-xr-xinit-tools.sh224
-rwxr-xr-xnetci.groovy838
-rw-r--r--perf.groovy141
-rw-r--r--pgosupport.cmake14
-rw-r--r--publish-packages.cmd4
-rwxr-xr-xpublish-packages.sh3
-rw-r--r--run.cmd8
-rwxr-xr-xrun.sh4
-rw-r--r--src/.gitmirrorselective2
-rw-r--r--src/.nuget/Microsoft.NETCore.ILAsm/Microsoft.NETCore.ILAsm.builds16
-rw-r--r--src/.nuget/Microsoft.NETCore.ILAsm/Microsoft.NETCore.ILAsm.pkgproj14
-rw-r--r--src/.nuget/Microsoft.NETCore.ILAsm/alpine/3.4.3/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/ubuntu/14.04/Microsoft.NETCore.ILAsm.pkgproj6
-rw-r--r--src/.nuget/Microsoft.NETCore.ILAsm/ubuntu/16.04/Microsoft.NETCore.ILAsm.pkgproj6
-rw-r--r--src/.nuget/Microsoft.NETCore.ILDAsm/Microsoft.NETCore.ILDAsm.builds16
-rw-r--r--src/.nuget/Microsoft.NETCore.ILDAsm/Microsoft.NETCore.ILDAsm.pkgproj14
-rw-r--r--src/.nuget/Microsoft.NETCore.ILDAsm/alpine/3.4.3/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/ubuntu/14.04/Microsoft.NETCore.ILDAsm.pkgproj6
-rw-r--r--src/.nuget/Microsoft.NETCore.ILDAsm/ubuntu/16.04/Microsoft.NETCore.ILDAsm.pkgproj6
-rw-r--r--src/.nuget/Microsoft.NETCore.Jit/Microsoft.NETCore.Jit.builds16
-rw-r--r--src/.nuget/Microsoft.NETCore.Jit/Microsoft.NETCore.Jit.pkgproj14
-rw-r--r--src/.nuget/Microsoft.NETCore.Jit/alpine/3.4.3/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/ubuntu/14.04/Microsoft.NETCore.Jit.pkgproj6
-rw-r--r--src/.nuget/Microsoft.NETCore.Jit/ubuntu/16.04/Microsoft.NETCore.Jit.pkgproj6
-rw-r--r--src/.nuget/Microsoft.NETCore.Jit/win/Microsoft.NETCore.Jit.pkgproj1
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/Microsoft.NETCore.Runtime.CoreCLR.builds17
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/Microsoft.NETCore.Runtime.CoreCLR.pkgproj29
-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/linux/Microsoft.NETCore.Runtime.CoreCLR.pkgproj56
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/ubuntu/14.04/Microsoft.NETCore.Runtime.CoreCLR.pkgproj10
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/ubuntu/16.04/Microsoft.NETCore.Runtime.CoreCLR.pkgproj10
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/win/Microsoft.NETCore.Runtime.CoreCLR.pkgproj6
-rw-r--r--src/.nuget/Microsoft.NETCore.TestHost/Microsoft.NETCore.TestHost.builds16
-rw-r--r--src/.nuget/Microsoft.NETCore.TestHost/Microsoft.NETCore.TestHost.pkgproj19
-rw-r--r--src/.nuget/Microsoft.NETCore.TestHost/alpine/3.4.3/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/ubuntu/14.04/Microsoft.NETCore.TestHost.pkgproj6
-rw-r--r--src/.nuget/Microsoft.NETCore.TestHost/ubuntu/16.04/Microsoft.NETCore.TestHost.pkgproj6
-rw-r--r--src/.nuget/optdata/project.json11
-rw-r--r--src/.nuget/packages.builds3
-rw-r--r--src/ToolBox/.gitmirror1
-rw-r--r--src/ToolBox/.gitmirrorselective1
-rw-r--r--src/ToolBox/SOS/NETCore/SymbolReader.cs97
-rw-r--r--src/ToolBox/SOS/NETCore/project.json2
-rw-r--r--src/ToolBox/SOS/Strike/CMakeLists.txt11
-rw-r--r--src/ToolBox/SOS/Strike/ExpressionNode.cpp20
-rw-r--r--src/ToolBox/SOS/Strike/ExpressionNode.h14
-rw-r--r--src/ToolBox/SOS/Strike/datatarget.cpp4
-rw-r--r--src/ToolBox/SOS/Strike/sildasm.cpp2
-rw-r--r--src/ToolBox/SOS/Strike/sos_stacktrace.h8
-rw-r--r--src/ToolBox/SOS/Strike/sosdocsunix.txt1
-rw-r--r--src/ToolBox/SOS/Strike/stressLogDump.cpp2
-rw-r--r--src/ToolBox/SOS/Strike/strike.cpp65
-rw-r--r--src/ToolBox/SOS/Strike/util.cpp66
-rw-r--r--src/ToolBox/SOS/Strike/util.h16
-rw-r--r--src/ToolBox/SOS/Strike/vm.cpp10
-rw-r--r--src/ToolBox/SOS/lldbplugin/CMakeLists.txt7
-rw-r--r--src/ToolBox/SOS/lldbplugin/services.cpp2
-rw-r--r--src/ToolBox/SOS/tests/OnCrash.do2
-rw-r--r--src/ToolBox/SOS/tests/README.md43
-rw-r--r--src/ToolBox/SOS/tests/Test.cs94
-rw-r--r--src/ToolBox/SOS/tests/dumpil.py26
-rw-r--r--src/ToolBox/SOS/tests/dumpmodule.py26
-rw-r--r--src/ToolBox/SOS/tests/runprocess.py34
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_bpmd_clear.py62
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_bpmd_clearall.py62
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_bpmd_methoddesc.py45
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_bpmd_module_function.py43
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_bpmd_module_function_iloffset.py43
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_bpmd_nofuturemodule_module_function.py48
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_clrstack.py36
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_clrthreads.py31
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_clru.py46
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_dso.py31
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_dumpclass.py68
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_dumpheap.py31
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_dumpil.py38
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_dumplog.py31
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_dumpmd.py46
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_dumpmodule.py46
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_dumpmt.py68
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_dumpobj.py69
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_dumpstack.py31
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_eeheap.py31
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_eestack.py31
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_gcroot.py61
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_histclear.py31
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_histinit.py31
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_histobj.py61
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_histobjfind.py61
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_histroot.py61
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_ip2md.py53
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_name2ee.py46
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_pe.py28
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_sos.py31
-rw-r--r--src/ToolBox/SOS/tests/t_cmd_soshelp.py31
-rw-r--r--src/ToolBox/SOS/tests/test_libsosplugin.py338
-rw-r--r--src/ToolBox/SOS/tests/testutils.py234
-rw-r--r--src/ToolBox/dirs.proj2
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/compileresult.h2
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/icorjitcompilerimpl.h4
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h4
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/logging.cpp6
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/lwmlist.h1
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/mclist.cpp2
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp34
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/methodcontext.h13
-rw-r--r--src/ToolBox/superpmi/superpmi-shim-collector/icorjitcompiler.cpp2
-rw-r--r--src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp8
-rw-r--r--src/ToolBox/superpmi/superpmi-shim-counter/icorjitcompiler.cpp2
-rw-r--r--src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp4
-rw-r--r--src/ToolBox/superpmi/superpmi-shim-simple/icorjitcompiler.cpp2
-rw-r--r--src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp4
-rw-r--r--src/ToolBox/superpmi/superpmi/icorjitinfo.cpp9
-rw-r--r--src/ToolBox/superpmi/superpmi/methodstatsemitter.cpp22
-rw-r--r--src/ToolBox/superpmi/superpmi/neardiffer.cpp2
-rw-r--r--src/ToolBox/superpmi/superpmi/parallelsuperpmi.cpp6
-rw-r--r--src/ToolBox/superpmi/superpmi/superpmi.cpp2
-rw-r--r--src/ToolBox/superpmi/superpmi/superpmi.h3
-rw-r--r--src/classlibnative/bcltype/arraynative.cpp4
-rw-r--r--src/classlibnative/bcltype/number.cpp6
-rw-r--r--src/classlibnative/bcltype/system.cpp12
-rw-r--r--src/classlibnative/bcltype/system.h1
-rw-r--r--src/classlibnative/float/floatsingle.cpp228
-rw-r--r--src/classlibnative/inc/floatsingle.h19
-rw-r--r--src/classlibnative/inc/nlsinfo.h13
-rw-r--r--src/classlibnative/nls/nlsinfo.cpp131
-rw-r--r--src/coreclr/hosts/coreconsole/coreconsole.cpp11
-rw-r--r--src/coreclr/hosts/corerun/corerun.cpp9
-rw-r--r--src/coreclr/hosts/unixcoreruncommon/coreruncommon.cpp3
-rw-r--r--src/corefx/System.Globalization.Native/CMakeLists.txt40
-rw-r--r--src/corefx/System.Globalization.Native/calendarData.cpp2
-rw-r--r--src/corefx/System.Globalization.Native/casing.cpp3
-rw-r--r--src/corefx/System.Globalization.Native/collation.cpp44
-rw-r--r--src/corefx/System.Globalization.Native/errors.h8
-rw-r--r--src/corefx/System.Globalization.Native/holders.h8
-rw-r--r--src/corefx/System.Globalization.Native/icushim.cpp226
-rw-r--r--src/corefx/System.Globalization.Native/icushim.h243
-rw-r--r--src/corefx/System.Globalization.Native/idna.cpp2
-rw-r--r--src/corefx/System.Globalization.Native/locale.cpp51
-rw-r--r--src/corefx/System.Globalization.Native/locale.hpp2
-rw-r--r--src/corefx/System.Globalization.Native/localeNumberData.cpp3
-rw-r--r--src/corefx/System.Globalization.Native/localeStringData.cpp104
-rw-r--r--src/corefx/System.Globalization.Native/normalization.cpp2
-rw-r--r--src/corefx/System.Globalization.Native/timeZoneInfo.cpp2
-rw-r--r--src/debug/daccess/daccess.cpp18
-rw-r--r--src/debug/daccess/daccess.targets6
-rw-r--r--src/debug/daccess/dacdbiimpl.cpp35
-rw-r--r--src/debug/daccess/dacdbiimpl.h10
-rw-r--r--src/debug/daccess/dacfn.cpp4
-rw-r--r--src/debug/daccess/enummem.cpp11
-rw-r--r--src/debug/daccess/fntableaccess.cpp5
-rw-r--r--src/debug/daccess/fntableaccess.h3
-rw-r--r--src/debug/daccess/nidump.cpp21
-rw-r--r--src/debug/daccess/request.cpp78
-rw-r--r--src/debug/daccess/request_svr.cpp4
-rw-r--r--src/debug/di/breakpoint.cpp2
-rw-r--r--src/debug/di/module.cpp377
-rw-r--r--src/debug/di/process.cpp14
-rw-r--r--src/debug/di/rsenumerator.hpp6
-rw-r--r--src/debug/di/rsmain.cpp2
-rw-r--r--src/debug/di/rspriv.h86
-rw-r--r--src/debug/di/rspriv.inl2
-rw-r--r--src/debug/di/rsthread.cpp11
-rw-r--r--src/debug/di/rstype.cpp122
-rw-r--r--src/debug/ee/controller.cpp6
-rw-r--r--src/debug/ee/controller.h14
-rw-r--r--src/debug/ee/debugger.cpp13
-rw-r--r--src/debug/ee/debugger.h4
-rw-r--r--src/debug/ee/functioninfo.cpp43
-rw-r--r--src/debug/ee/i386/dbghelpers.S70
-rw-r--r--src/debug/ee/wks/CMakeLists.txt4
-rw-r--r--src/debug/ildbsymlib/symwrite.h3
-rw-r--r--src/debug/inc/common.h24
-rw-r--r--src/debug/inc/dacdbiinterface.h27
-rw-r--r--src/debug/shared/dbgtransportsession.cpp36
-rw-r--r--src/dlls/dbgshim/dbgshim.cpp2
-rw-r--r--src/dlls/mscordac/CMakeLists.txt8
-rw-r--r--src/dlls/mscordac/mscordac_unixexports.src16
-rw-r--r--src/dlls/mscoree/coreclr/coreclr.nativeproj6
-rw-r--r--src/dlls/mscoree/mscoree.cpp2
-rw-r--r--src/dlls/mscoree/mscorwks_unixexports.src1
-rw-r--r--src/dlls/mscoree/unixinterface.cpp26
-rw-r--r--src/dlls/mscorpe/ceefilegenwriter.cpp19
-rw-r--r--src/gc/CMakeLists.txt12
-rw-r--r--src/gc/env/gcenv.base.h2
-rw-r--r--src/gc/env/gcenv.ee.h38
-rw-r--r--src/gc/env/gcenv.object.h2
-rw-r--r--src/gc/env/gcenv.os.h3
-rw-r--r--src/gc/gc.cpp972
-rw-r--r--src/gc/gc.h571
-rw-r--r--src/gc/gccommon.cpp67
-rw-r--r--src/gc/gcee.cpp226
-rw-r--r--src/gc/gcenv.ee.standalone.inl176
-rw-r--r--src/gc/gcenv.unix.cpp308
-rw-r--r--src/gc/gcenv.windows.cpp625
-rw-r--r--src/gc/gcimpl.h72
-rw-r--r--src/gc/gcinterface.ee.h133
-rw-r--r--src/gc/gcinterface.h622
-rw-r--r--src/gc/gcpriv.h57
-rw-r--r--src/gc/gcrecord.h2
-rw-r--r--src/gc/gcscan.cpp23
-rw-r--r--src/gc/gcscan.h6
-rw-r--r--src/gc/handletable.cpp8
-rw-r--r--src/gc/handletablecache.cpp6
-rw-r--r--src/gc/handletablecore.cpp7
-rw-r--r--src/gc/handletablescan.cpp12
-rw-r--r--src/gc/objecthandle.cpp137
-rw-r--r--src/gc/objecthandle.h7
-rw-r--r--src/gc/sample/CMakeLists.txt4
-rw-r--r--src/gc/sample/GCSample.cpp10
-rw-r--r--src/gc/sample/GCSample.vcxproj7
-rw-r--r--src/gc/sample/GCSample.vcxproj.filters2
-rw-r--r--src/gc/sample/gcenv.ee.cpp54
-rw-r--r--src/gc/sample/gcenv.h13
-rw-r--r--src/gc/sample/gcenv.unix.cpp14
-rw-r--r--src/gc/sample/gcenv.windows.cpp453
-rw-r--r--src/gc/softwarewritewatch.cpp1
-rw-r--r--src/gcdump/gcdump.cpp2
-rw-r--r--src/gcdump/gcdumpnonx86.cpp4
-rw-r--r--src/gcdump/i386/gcdumpx86.cpp26
-rw-r--r--src/gcinfo/gcinfoencoder.cpp143
-rw-r--r--src/ilasm/CMakeLists.txt11
-rw-r--r--src/ilasm/assembler.cpp2
-rw-r--r--src/ilasm/main.cpp2
-rw-r--r--src/ilasm/prebuilt/asmparse.c4907
-rw-r--r--src/ilasm/prebuilt/asmparse.cpp4907
-rw-r--r--src/ildasm/dis.cpp6
-rw-r--r--src/ildasm/dres.cpp4
-rw-r--r--src/ildasm/gui.cpp2
-rw-r--r--src/ildasm/windasm.cpp40
-rw-r--r--src/inc/CMakeLists.txt9
-rw-r--r--src/inc/bitposition.h6
-rw-r--r--src/inc/clrconfigvalues.h24
-rw-r--r--src/inc/clrnt.h12
-rw-r--r--src/inc/corcompile.h16
-rw-r--r--src/inc/cordebug.idl135
-rw-r--r--src/inc/corinfo.h28
-rw-r--r--src/inc/corjit.h170
-rw-r--r--src/inc/corprof.idl87
-rw-r--r--src/inc/daccess.h4
-rw-r--r--src/inc/dacprivate.h113
-rw-r--r--src/inc/dacvars.h14
-rw-r--r--src/inc/debugreturn.h12
-rw-r--r--src/inc/eetwain.h54
-rw-r--r--src/inc/eventtrace.h22
-rw-r--r--src/inc/fstring.h3
-rw-r--r--src/inc/gcdecoder.cpp372
-rw-r--r--src/inc/gcdump.h12
-rw-r--r--src/inc/gcinfo.h20
-rw-r--r--src/inc/gcinfodecoder.h91
-rw-r--r--src/inc/gcinfoencoder.h11
-rw-r--r--src/inc/gcinfotypes.h95
-rw-r--r--src/inc/jithelpers.h17
-rw-r--r--src/inc/livedatatarget.h2
-rw-r--r--src/inc/longfilepathwrappers.h8
-rw-r--r--src/inc/shash.inl4
-rw-r--r--src/inc/sortversioning.h12
-rw-r--r--src/inc/stacktrace.h6
-rw-r--r--src/inc/stresslog.h2
-rw-r--r--src/inc/utilcode.h20
-rw-r--r--src/inc/winwrap.h7
-rw-r--r--src/inc/xmlparser_i.cpp (renamed from src/inc/xmlparser_i.c)0
-rw-r--r--src/inc/zapper.h2
-rw-r--r--src/ipcman/ipcshared.h4
-rw-r--r--src/jit/CMakeLists.txt27
-rw-r--r--src/jit/ICorJitInfo_API_names.h171
-rw-r--r--src/jit/ICorJitInfo_API_wrapper.hpp1666
-rw-r--r--src/jit/assertionprop.cpp119
-rw-r--r--src/jit/bitsetasuint64.h2
-rw-r--r--src/jit/block.cpp37
-rw-r--r--src/jit/block.h24
-rwxr-xr-xsrc/jit/codegen.h36
-rw-r--r--src/jit/codegenarm.cpp1078
-rw-r--r--src/jit/codegenarm64.cpp1441
-rw-r--r--src/jit/codegenclassic.h7
-rw-r--r--[-rwxr-xr-x]src/jit/codegencommon.cpp622
-rw-r--r--src/jit/codegeninterface.h6
-rw-r--r--src/jit/codegenlegacy.cpp448
-rw-r--r--src/jit/codegenlinear.cpp1773
-rw-r--r--src/jit/codegenlinear.h78
-rw-r--r--src/jit/codegenxarch.cpp3899
-rw-r--r--src/jit/compatjit/.gitmirror (renamed from .gitmirror)0
-rw-r--r--src/jit/compatjit/CMakeLists.txt66
-rw-r--r--src/jit/compiler.cpp1399
-rw-r--r--src/jit/compiler.h297
-rw-r--r--src/jit/compiler.hpp110
-rw-r--r--src/jit/compphases.h15
-rw-r--r--src/jit/crossgen/CMakeLists.txt4
-rw-r--r--src/jit/decomposelongs.cpp1056
-rw-r--r--src/jit/decomposelongs.h12
-rw-r--r--src/jit/dll/CMakeLists.txt10
-rw-r--r--src/jit/dll/jit.nativeproj6
-rw-r--r--src/jit/earlyprop.cpp42
-rw-r--r--[-rwxr-xr-x]src/jit/ee_il_dll.cpp53
-rw-r--r--src/jit/ee_il_dll.hpp4
-rw-r--r--src/jit/emit.cpp80
-rw-r--r--src/jit/emit.h27
-rw-r--r--src/jit/emitarm.cpp20
-rw-r--r--src/jit/emitarm64.cpp2
-rw-r--r--src/jit/emitxarch.cpp710
-rw-r--r--src/jit/emitxarch.h118
-rw-r--r--src/jit/error.cpp4
-rw-r--r--src/jit/error.h199
-rw-r--r--src/jit/flowgraph.cpp2347
-rw-r--r--src/jit/gcencode.cpp267
-rw-r--r--src/jit/gentree.cpp1311
-rw-r--r--src/jit/gentree.h563
-rw-r--r--src/jit/gschecks.cpp48
-rw-r--r--src/jit/gtlist.h333
-rw-r--r--src/jit/gtstructs.h4
-rw-r--r--src/jit/importer.cpp760
-rw-r--r--src/jit/inline.cpp138
-rw-r--r--src/jit/inline.def10
-rw-r--r--src/jit/inline.h17
-rw-r--r--src/jit/inlinepolicy.cpp232
-rw-r--r--src/jit/inlinepolicy.h98
-rw-r--r--src/jit/instr.cpp14
-rw-r--r--src/jit/instr.h10
-rw-r--r--src/jit/instrsxarch.h19
-rw-r--r--src/jit/jit.h49
-rw-r--r--src/jit/jit.settings.targets3
-rw-r--r--src/jit/jitconfig.h2
-rw-r--r--src/jit/jitconfigvalues.h50
-rw-r--r--src/jit/jitee.h264
-rw-r--r--src/jit/jiteh.cpp12
-rw-r--r--src/jit/jitgcinfo.h3
-rw-r--r--src/jit/lclvars.cpp97
-rw-r--r--src/jit/legacyjit/.gitmirror (renamed from src/.gitmirror)0
-rw-r--r--src/jit/legacyjit/CMakeLists.txt62
-rw-r--r--src/jit/lir.cpp49
-rw-r--r--src/jit/liveness.cpp37
-rw-r--r--src/jit/loopcloning.cpp2
-rw-r--r--src/jit/lower.cpp742
-rw-r--r--src/jit/lower.h18
-rw-r--r--src/jit/lowerarm.cpp138
-rw-r--r--src/jit/lowerarm64.cpp149
-rw-r--r--src/jit/lowerxarch.cpp1104
-rw-r--r--src/jit/lsra.cpp1051
-rw-r--r--src/jit/lsra.h87
-rw-r--r--src/jit/morph.cpp1656
-rw-r--r--src/jit/nodeinfo.h47
-rw-r--r--src/jit/optcse.cpp88
-rw-r--r--src/jit/optimizer.cpp688
-rw-r--r--src/jit/protojit/CMakeLists.txt8
-rw-r--r--src/jit/rangecheck.cpp5
-rw-r--r--src/jit/rationalize.cpp250
-rw-r--r--src/jit/regalloc.cpp208
-rw-r--r--src/jit/regalloc.h24
-rw-r--r--src/jit/registerfp.cpp6
-rw-r--r--src/jit/regset.cpp10
-rw-r--r--src/jit/scopeinfo.cpp18
-rw-r--r--src/jit/sideeffects.h6
-rw-r--r--src/jit/simd.cpp137
-rw-r--r--src/jit/simd.h15
-rw-r--r--src/jit/simdcodegenxarch.cpp698
-rw-r--r--src/jit/simdintrinsiclist.h9
-rw-r--r--src/jit/ssabuilder.cpp223
-rw-r--r--src/jit/stackfp.cpp23
-rw-r--r--src/jit/standalone/CMakeLists.txt21
-rw-r--r--src/jit/target.h47
-rw-r--r--src/jit/tinyarray.h2
-rw-r--r--src/jit/unwindamd64.cpp15
-rw-r--r--src/jit/utils.cpp24
-rw-r--r--src/jit/valuenum.cpp246
-rw-r--r--src/jit/valuenum.h59
-rw-r--r--src/jit/valuenumfuncs.h4
-rw-r--r--src/md/ceefilegen/cceegen.cpp24
-rw-r--r--src/md/winmd/adapter.cpp28
-rw-r--r--src/md/winmd/inc/adapter.h2
-rw-r--r--src/md/winmd/winmdimport.cpp30
-rw-r--r--src/mscorlib/Common/PinnableBufferCache.cs97
-rw-r--r--src/mscorlib/System.Private.CoreLib.csproj4
-rw-r--r--src/mscorlib/System.Private.CoreLib.sln5
-rw-r--r--src/mscorlib/corefx/Debug.cs29
-rw-r--r--src/mscorlib/corefx/Interop/Unix/Interop.Errors.cs207
-rw-r--r--src/mscorlib/corefx/Interop/Unix/Interop.IOErrors.cs170
-rw-r--r--src/mscorlib/corefx/Interop/Unix/Interop.Libraries.cs7
-rw-r--r--src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Collation.cs5
-rw-r--r--src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Idna.cs21
-rw-r--r--src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Locale.cs3
-rw-r--r--src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Normalization.cs19
-rw-r--r--src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.ResultCode.cs1
-rw-r--r--src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Close.cs15
-rw-r--r--src/mscorlib/corefx/Interop/Unix/System.Native/Interop.FLock.cs31
-rw-r--r--src/mscorlib/corefx/Interop/Unix/System.Native/Interop.FSync.cs15
-rw-r--r--src/mscorlib/corefx/Interop/Unix/System.Native/Interop.FTruncate.cs15
-rw-r--r--src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Fcntl.cs21
-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/Unix/System.Native/Interop.LSeek.cs22
-rw-r--r--src/mscorlib/corefx/Interop/Unix/System.Native/Interop.MksTemps.cs17
-rw-r--r--src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Open.cs15
-rw-r--r--src/mscorlib/corefx/Interop/Unix/System.Native/Interop.OpenFlags.cs27
-rw-r--r--src/mscorlib/corefx/Interop/Unix/System.Native/Interop.PathConf.cs73
-rw-r--r--src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Permissions.cs32
-rw-r--r--src/mscorlib/corefx/Interop/Unix/System.Native/Interop.PosixFAdvise.cs36
-rw-r--r--src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Read.cs25
-rw-r--r--src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Stat.cs59
-rw-r--r--src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Unlink.cs15
-rw-r--r--src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Write.cs27
-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/Crypt32/Interop.CryptProtectMemory.cs22
-rw-r--r--src/mscorlib/corefx/Interop/Windows/Interop.BOOL.cs21
-rw-r--r--src/mscorlib/corefx/Interop/Windows/Interop.Libraries.cs82
-rw-r--r--src/mscorlib/corefx/Interop/Windows/NtDll/Interop.ZeroMemory.cs19
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.CancelIoEx.cs16
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.CloseHandle.cs16
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.CreateFile.cs40
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.Errors.cs74
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.FileOperations.cs35
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.FileTypes.cs16
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.FlushFileBuffers.cs17
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.FormatMessage.cs112
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.GetFileInformationByHandleEx.cs26
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.GetFileType_SafeHandle.cs15
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.GetFullPathNameW.cs18
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.GetLongPathNameW.cs18
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.GetTempFileNameW.cs16
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.GetTempPathW.cs16
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.Idna.cs37
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.LockFile.cs20
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.ReadFile_SafeHandle_IntPtr.cs21
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.ReadFile_SafeHandle_NativeOverlapped.cs22
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.SECURITY_ATTRIBUTES.cs21
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.SafeCreateFile.cs45
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.SecurityOptions.cs18
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.SetEndOfFile.cs15
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.SetErrorMode.cs14
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.SetFileInformationByHandle.cs72
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.SetFilePointerEx.cs15
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.ThreadPoolIO.cs27
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.UnsafeCreateFile.cs25
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.WideCharToMultiByte.cs22
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.WriteFile_SafeHandle_IntPtr.cs24
-rw-r--r--src/mscorlib/corefx/Interop/Windows/mincore/Interop.WriteFile_SafeHandle_NativeOverlapped.cs22
-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/SafeFileHandle.Unix.cs122
-rw-r--r--src/mscorlib/corefx/Microsoft/Win32/SafeHandles/SafeFileHandle.Windows.cs50
-rw-r--r--src/mscorlib/corefx/Microsoft/Win32/SafeHandles/SafeThreadPoolIOHandle.cs28
-rw-r--r--src/mscorlib/corefx/SR.cs823
-rw-r--r--src/mscorlib/corefx/System/Buffers/ArrayPool.cs113
-rw-r--r--src/mscorlib/corefx/System/Buffers/ArrayPoolEventSource.cs78
-rw-r--r--src/mscorlib/corefx/System/Buffers/ConfigurableArrayPool.cs265
-rw-r--r--src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.Unix.cs28
-rw-r--r--src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.Windows.cs20
-rw-r--r--src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs328
-rw-r--r--src/mscorlib/corefx/System/Buffers/Utilities.cs35
-rw-r--r--src/mscorlib/corefx/System/Globalization/Calendar.cs42
-rw-r--r--src/mscorlib/corefx/System/Globalization/CalendarAlgorithmType.cs20
-rw-r--r--src/mscorlib/corefx/System/Globalization/CalendarData.Unix.cs3
-rw-r--r--src/mscorlib/corefx/System/Globalization/CalendarData.cs8
-rw-r--r--src/mscorlib/corefx/System/Globalization/CalendricalCalculationsHelper.cs31
-rw-r--r--src/mscorlib/corefx/System/Globalization/CharUnicodeInfo.cs110
-rw-r--r--src/mscorlib/corefx/System/Globalization/CharUnicodeInfoData.cs25
-rw-r--r--src/mscorlib/corefx/System/Globalization/ChineseLunisolarCalendar.cs4
-rw-r--r--src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs140
-rw-r--r--src/mscorlib/corefx/System/Globalization/CompareInfo.Windows.cs78
-rw-r--r--src/mscorlib/corefx/System/Globalization/CompareInfo.cs283
-rw-r--r--src/mscorlib/corefx/System/Globalization/CultureData.Unix.cs164
-rw-r--r--src/mscorlib/corefx/System/Globalization/CultureData.Windows.cs132
-rw-r--r--src/mscorlib/corefx/System/Globalization/CultureData.cs392
-rw-r--r--src/mscorlib/corefx/System/Globalization/CultureInfo.Windows.cs6
-rw-r--r--src/mscorlib/corefx/System/Globalization/CultureInfo.cs528
-rw-r--r--src/mscorlib/corefx/System/Globalization/CultureNotFoundException.cs35
-rw-r--r--src/mscorlib/corefx/System/Globalization/CultureTypes.cs28
-rw-r--r--src/mscorlib/corefx/System/Globalization/DateTimeFormatInfo.cs343
-rw-r--r--src/mscorlib/corefx/System/Globalization/DayLightTime.cs49
-rw-r--r--src/mscorlib/corefx/System/Globalization/DigitShapes.cs17
-rw-r--r--src/mscorlib/corefx/System/Globalization/EastAsianLunisolarCalendar.cs41
-rw-r--r--src/mscorlib/corefx/System/Globalization/GregorianCalendar.cs57
-rw-r--r--src/mscorlib/corefx/System/Globalization/GregorianCalendarHelper.cs24
-rw-r--r--src/mscorlib/corefx/System/Globalization/HebrewCalendar.cs43
-rw-r--r--src/mscorlib/corefx/System/Globalization/HebrewNumber.cs11
-rw-r--r--src/mscorlib/corefx/System/Globalization/HijriCalendar.Win32.cs86
-rw-r--r--src/mscorlib/corefx/System/Globalization/HijriCalendar.WinRT.cs16
-rw-r--r--src/mscorlib/corefx/System/Globalization/HijriCalendar.Windows.cs16
-rw-r--r--src/mscorlib/corefx/System/Globalization/HijriCalendar.cs31
-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/JapaneseCalendar.Unix.cs3
-rw-r--r--src/mscorlib/corefx/System/Globalization/JapaneseCalendar.Win32.cs209
-rw-r--r--src/mscorlib/corefx/System/Globalization/JapaneseCalendar.WinRT.cs (renamed from src/mscorlib/corefx/System/Globalization/JapaneseCalendar.Windows.cs)0
-rw-r--r--src/mscorlib/corefx/System/Globalization/JapaneseCalendar.cs18
-rw-r--r--src/mscorlib/corefx/System/Globalization/JulianCalendar.cs37
-rw-r--r--src/mscorlib/corefx/System/Globalization/KoreanCalendar.cs11
-rw-r--r--src/mscorlib/corefx/System/Globalization/KoreanLunisolarCalendar.cs4
-rw-r--r--src/mscorlib/corefx/System/Globalization/LocaleData.Unix.cs4572
-rw-r--r--src/mscorlib/corefx/System/Globalization/NumberFormatInfo.cs91
-rw-r--r--src/mscorlib/corefx/System/Globalization/PersianCalendar.cs54
-rw-r--r--src/mscorlib/corefx/System/Globalization/RegionInfo.cs117
-rw-r--r--src/mscorlib/corefx/System/Globalization/STUBS.cs180
-rw-r--r--src/mscorlib/corefx/System/Globalization/SortKey.cs209
-rw-r--r--src/mscorlib/corefx/System/Globalization/SortVersion.cs101
-rw-r--r--src/mscorlib/corefx/System/Globalization/StringInfo.cs89
-rw-r--r--src/mscorlib/corefx/System/Globalization/TaiwanCalendar.cs13
-rw-r--r--src/mscorlib/corefx/System/Globalization/TextElementEnumerator.cs10
-rw-r--r--src/mscorlib/corefx/System/Globalization/TextInfo.Unix.cs5
-rw-r--r--src/mscorlib/corefx/System/Globalization/TextInfo.Windows.cs6
-rw-r--r--src/mscorlib/corefx/System/Globalization/TextInfo.cs324
-rw-r--r--src/mscorlib/corefx/System/Globalization/ThaiBuddhistCalendar.cs11
-rw-r--r--src/mscorlib/corefx/System/Globalization/UmAlQuraCalendar.cs40
-rw-r--r--src/mscorlib/corefx/System/HResults.cs236
-rw-r--r--src/mscorlib/corefx/System/IO/Error.cs44
-rw-r--r--src/mscorlib/corefx/System/IO/FileStream.NetStandard17.cs76
-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/FileStream.cs654
-rw-r--r--src/mscorlib/corefx/System/IO/FileStreamCompletionSource.Win32.cs221
-rw-r--r--src/mscorlib/corefx/System/IO/Path.Unix.cs256
-rw-r--r--src/mscorlib/corefx/System/IO/Path.Win32.cs36
-rw-r--r--src/mscorlib/corefx/System/IO/Path.Windows.cs153
-rw-r--r--src/mscorlib/corefx/System/IO/Path.cs578
-rw-r--r--src/mscorlib/corefx/System/IO/PathHelper.Windows.cs389
-rw-r--r--src/mscorlib/corefx/System/IO/PathInternal.CaseSensitivity.cs75
-rw-r--r--src/mscorlib/corefx/System/IO/PathInternal.Unix.cs122
-rw-r--r--src/mscorlib/corefx/System/IO/PathInternal.Windows.StringBuffer.cs89
-rw-r--r--src/mscorlib/corefx/System/IO/PathInternal.Windows.cs482
-rw-r--r--src/mscorlib/corefx/System/IO/PathInternal.cs230
-rw-r--r--src/mscorlib/corefx/System/IO/Win32Marshal.cs134
-rw-r--r--src/mscorlib/corefx/System/Runtime/InteropServices/NativeBuffer.cs157
-rw-r--r--src/mscorlib/corefx/System/Runtime/InteropServices/SafeHeapHandle.cs109
-rw-r--r--src/mscorlib/corefx/System/Runtime/InteropServices/SafeHeapHandleCache.cs97
-rw-r--r--src/mscorlib/corefx/System/Runtime/InteropServices/StringBuffer.cs354
-rw-r--r--src/mscorlib/corefx/System/Security/CryptographicException.cs44
-rw-r--r--src/mscorlib/corefx/System/Security/SafeBSTRHandle.cs81
-rw-r--r--src/mscorlib/corefx/System/Security/SecureString.Unix.cs295
-rw-r--r--src/mscorlib/corefx/System/Security/SecureString.Windows.cs310
-rw-r--r--src/mscorlib/corefx/System/Security/SecureString.cs189
-rw-r--r--src/mscorlib/corefx/System/Threading/ClrThreadPoolBoundHandle.cs319
-rw-r--r--src/mscorlib/corefx/System/Threading/ClrThreadPoolBoundHandleOverlapped.cs52
-rw-r--r--src/mscorlib/corefx/System/Threading/ClrThreadPoolPreAllocatedOverlapped.cs105
-rw-r--r--src/mscorlib/corefx/System/Threading/DeferredDisposableLifetime.cs116
-rw-r--r--src/mscorlib/facade/TypeForwards.cs37
-rw-r--r--src/mscorlib/facade/mscorlib.csproj37
-rw-r--r--src/mscorlib/facade/project.json1
-rw-r--r--src/mscorlib/model.xml1110
-rw-r--r--src/mscorlib/mscorlib.shared.sources.props220
-rw-r--r--src/mscorlib/ref/mscorlib.cs839
-rw-r--r--src/mscorlib/src/Internal/Runtime/Augments/EnvironmentAugments.cs7
-rw-r--r--src/mscorlib/src/Internal/Runtime/Augments/RuntimeThread.cs198
-rw-r--r--src/mscorlib/src/Microsoft/Win32/OAVariantLib.cs6
-rw-r--r--src/mscorlib/src/Microsoft/Win32/Registry.cs24
-rw-r--r--src/mscorlib/src/Microsoft/Win32/RegistryKey.cs296
-rw-r--r--src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.cs43
-rw-r--r--src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFileMappingHandle.cs4
-rw-r--r--src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFindHandle.cs3
-rw-r--r--src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeLibraryHandle.cs12
-rw-r--r--src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeLocalAllocHandle.cs6
-rw-r--r--src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeRegistryHandle.cs4
-rw-r--r--src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeViewOfFileHandle.cs4
-rw-r--r--src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeWaitHandle.cs2
-rw-r--r--src/mscorlib/src/Microsoft/Win32/SafeHandles/Win32SafeHandles.cs25
-rw-r--r--src/mscorlib/src/Microsoft/Win32/UnsafeNativeMethods.cs8
-rw-r--r--src/mscorlib/src/Microsoft/Win32/Win32Native.cs115
-rw-r--r--src/mscorlib/src/System.Private.CoreLib.txt1251
-rw-r--r--src/mscorlib/src/System/Action.cs43
-rw-r--r--src/mscorlib/src/System/Activator.cs136
-rw-r--r--src/mscorlib/src/System/AggregateException.cs17
-rw-r--r--src/mscorlib/src/System/AppContext/AppContext.cs56
-rw-r--r--src/mscorlib/src/System/AppContext/AppContextDefaultValues.Defaults.cs12
-rw-r--r--src/mscorlib/src/System/AppContext/AppContextDefaultValues.cs6
-rw-r--r--src/mscorlib/src/System/AppContext/AppContextSwitches.cs30
-rw-r--r--src/mscorlib/src/System/AppDomain.cs2188
-rw-r--r--src/mscorlib/src/System/AppDomainManager.cs171
-rw-r--r--src/mscorlib/src/System/AppDomainSetup.cs469
-rw-r--r--src/mscorlib/src/System/ApplicationId.cs6
-rw-r--r--src/mscorlib/src/System/ArgIterator.cs11
-rw-r--r--src/mscorlib/src/System/ArgumentException.cs3
-rw-r--r--src/mscorlib/src/System/ArgumentNullException.cs1
-rw-r--r--src/mscorlib/src/System/ArgumentOutOfRangeException.cs3
-rw-r--r--src/mscorlib/src/System/Array.cs433
-rw-r--r--src/mscorlib/src/System/ArraySegment.cs96
-rw-r--r--src/mscorlib/src/System/Attribute.cs137
-rw-r--r--src/mscorlib/src/System/BCLDebug.cs32
-rw-r--r--src/mscorlib/src/System/BadImageFormatException.cs3
-rw-r--r--src/mscorlib/src/System/BitConverter.cs61
-rw-r--r--src/mscorlib/src/System/Boolean.cs2
-rw-r--r--src/mscorlib/src/System/Buffer.cs50
-rw-r--r--src/mscorlib/src/System/ByReference.cs31
-rw-r--r--src/mscorlib/src/System/Byte.cs4
-rw-r--r--src/mscorlib/src/System/CLRConfig.cs2
-rw-r--r--src/mscorlib/src/System/CfgParser.cs14
-rw-r--r--src/mscorlib/src/System/Char.cs94
-rw-r--r--src/mscorlib/src/System/Collections/ArrayList.cs179
-rw-r--r--src/mscorlib/src/System/Collections/BitArray.cs524
-rw-r--r--src/mscorlib/src/System/Collections/CollectionBase.cs10
-rw-r--r--src/mscorlib/src/System/Collections/Comparer.cs5
-rw-r--r--src/mscorlib/src/System/Collections/CompatibleComparer.cs2
-rw-r--r--src/mscorlib/src/System/Collections/Concurrent/ConcurrentDictionary.cs216
-rw-r--r--src/mscorlib/src/System/Collections/Concurrent/ConcurrentQueue.cs21
-rw-r--r--src/mscorlib/src/System/Collections/Concurrent/ConcurrentStack.cs91
-rw-r--r--src/mscorlib/src/System/Collections/Concurrent/IProducerConsumerCollection.cs2
-rw-r--r--src/mscorlib/src/System/Collections/Concurrent/OrderablePartitioner.cs1
-rw-r--r--src/mscorlib/src/System/Collections/Concurrent/Partitioner.cs1
-rw-r--r--src/mscorlib/src/System/Collections/Concurrent/PartitionerStatic.cs104
-rw-r--r--src/mscorlib/src/System/Collections/DictionaryEntry.cs7
-rw-r--r--src/mscorlib/src/System/Collections/EmptyReadOnlyDictionaryInternal.cs20
-rw-r--r--src/mscorlib/src/System/Collections/Generic/ArraySortHelper.cs452
-rw-r--r--src/mscorlib/src/System/Collections/Generic/Comparer.cs18
-rw-r--r--src/mscorlib/src/System/Collections/Generic/DebugView.cs2
-rw-r--r--src/mscorlib/src/System/Collections/Generic/Dictionary.cs101
-rw-r--r--src/mscorlib/src/System/Collections/Generic/EqualityComparer.cs171
-rw-r--r--src/mscorlib/src/System/Collections/Generic/KeyValuePair.cs17
-rw-r--r--src/mscorlib/src/System/Collections/Generic/List.cs116
-rw-r--r--src/mscorlib/src/System/Collections/Hashtable.cs187
-rw-r--r--src/mscorlib/src/System/Collections/ListDictionaryInternal.cs30
-rw-r--r--src/mscorlib/src/System/Collections/ObjectModel/Collection.cs8
-rw-r--r--src/mscorlib/src/System/Collections/ObjectModel/KeyedCollection.cs4
-rw-r--r--src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyCollection.cs8
-rw-r--r--src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyDictionary.cs14
-rw-r--r--src/mscorlib/src/System/Collections/SortedList.cs39
-rw-r--r--src/mscorlib/src/System/Collections/Stack.cs13
-rw-r--r--src/mscorlib/src/System/CompatibilitySwitches.cs72
-rw-r--r--src/mscorlib/src/System/ContextBoundObject.cs24
-rw-r--r--src/mscorlib/src/System/ContextStaticAttribute.cs32
-rw-r--r--src/mscorlib/src/System/Convert.cs80
-rw-r--r--src/mscorlib/src/System/Currency.cs2
-rw-r--r--src/mscorlib/src/System/CurrentTimeZone.cs276
-rw-r--r--src/mscorlib/src/System/DBNull.cs1
-rw-r--r--src/mscorlib/src/System/DateTime.cs86
-rw-r--r--src/mscorlib/src/System/DateTimeOffset.cs34
-rw-r--r--src/mscorlib/src/System/Decimal.cs60
-rw-r--r--src/mscorlib/src/System/DefaultBinder.cs26
-rw-r--r--src/mscorlib/src/System/Delegate.cs107
-rw-r--r--src/mscorlib/src/System/DelegateSerializationHolder.cs29
-rw-r--r--src/mscorlib/src/System/Diagnostics/Assert.cs18
-rw-r--r--src/mscorlib/src/System/Diagnostics/AssertFilter.cs1
-rw-r--r--src/mscorlib/src/System/Diagnostics/Contracts/Contracts.cs19
-rw-r--r--src/mscorlib/src/System/Diagnostics/Contracts/ContractsBCL.cs62
-rw-r--r--src/mscorlib/src/System/Diagnostics/Debugger.cs9
-rw-r--r--src/mscorlib/src/System/Diagnostics/DebuggerAttributes.cs20
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/ActivityTracker.cs13
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/EventProvider.cs66
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/EventSource.cs465
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/EventSource_CoreCLR.cs4
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/DataCollector.cs1
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventPayload.cs9
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventSourceActivity.cs2
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/FieldMetadata.cs2
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyValue.cs7
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/SimpleTypeInfos.cs3
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/Statics.cs2
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingDataCollector.cs1
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventSource.cs18
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventTypes.cs10
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingMetadataCollector.cs6
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingTypeInfo.cs4
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/XplatEventLogger.cs28
-rw-r--r--src/mscorlib/src/System/Diagnostics/LogSwitch.cs7
-rw-r--r--src/mscorlib/src/System/Diagnostics/Stackframe.cs23
-rw-r--r--src/mscorlib/src/System/Diagnostics/Stacktrace.cs79
-rw-r--r--src/mscorlib/src/System/Diagnostics/SymbolStore/ISymWriter.cs30
-rw-r--r--src/mscorlib/src/System/Diagnostics/log.cs5
-rw-r--r--src/mscorlib/src/System/Double.cs8
-rw-r--r--src/mscorlib/src/System/Empty.cs3
-rw-r--r--src/mscorlib/src/System/Enum.cs174
-rw-r--r--src/mscorlib/src/System/Environment.cs1154
-rw-r--r--src/mscorlib/src/System/Exception.cs88
-rw-r--r--src/mscorlib/src/System/FormattableString.cs2
-rw-r--r--src/mscorlib/src/System/GC.cs172
-rw-r--r--src/mscorlib/src/System/Globalization/Calendar.cs18
-rw-r--r--src/mscorlib/src/System/Globalization/CalendarData.cs6
-rw-r--r--src/mscorlib/src/System/Globalization/CalendricalCalculationsHelper.cs17
-rw-r--r--src/mscorlib/src/System/Globalization/CharUnicodeInfo.cs66
-rw-r--r--src/mscorlib/src/System/Globalization/ChineseLunisolarCalendar.cs4
-rw-r--r--src/mscorlib/src/System/Globalization/CompareInfo.cs171
-rw-r--r--src/mscorlib/src/System/Globalization/CultureData.cs445
-rw-r--r--src/mscorlib/src/System/Globalization/CultureInfo.cs167
-rw-r--r--src/mscorlib/src/System/Globalization/CultureNotFoundException.cs3
-rw-r--r--src/mscorlib/src/System/Globalization/DateTimeFormat.cs134
-rw-r--r--src/mscorlib/src/System/Globalization/DateTimeFormatInfo.cs248
-rw-r--r--src/mscorlib/src/System/Globalization/DateTimeFormatInfoScanner.cs3
-rw-r--r--src/mscorlib/src/System/Globalization/DateTimeParse.cs90
-rw-r--r--src/mscorlib/src/System/Globalization/DaylightTime.cs23
-rw-r--r--src/mscorlib/src/System/Globalization/EastAsianLunisolarCalendar.cs26
-rw-r--r--src/mscorlib/src/System/Globalization/EncodingDataItem.cs7
-rw-r--r--src/mscorlib/src/System/Globalization/EncodingTable.Unix.cs9
-rw-r--r--src/mscorlib/src/System/Globalization/EncodingTable.cs16
-rw-r--r--src/mscorlib/src/System/Globalization/GlobalizationAssembly.cs8
-rw-r--r--src/mscorlib/src/System/Globalization/GregorianCalendar.cs50
-rw-r--r--src/mscorlib/src/System/Globalization/GregorianCalendarHelper.cs24
-rw-r--r--src/mscorlib/src/System/Globalization/HebrewCalendar.cs31
-rw-r--r--src/mscorlib/src/System/Globalization/HebrewNumber.cs3
-rw-r--r--src/mscorlib/src/System/Globalization/HijriCalendar.cs24
-rw-r--r--src/mscorlib/src/System/Globalization/IdnMapping.cs156
-rw-r--r--src/mscorlib/src/System/Globalization/JapaneseCalendar.cs5
-rw-r--r--src/mscorlib/src/System/Globalization/JulianCalendar.cs18
-rw-r--r--src/mscorlib/src/System/Globalization/KoreanCalendar.cs2
-rw-r--r--src/mscorlib/src/System/Globalization/KoreanLunisolarCalendar.cs4
-rw-r--r--src/mscorlib/src/System/Globalization/NumberFormatInfo.cs66
-rw-r--r--src/mscorlib/src/System/Globalization/PersianCalendar.cs37
-rw-r--r--src/mscorlib/src/System/Globalization/RegionInfo.cs200
-rw-r--r--src/mscorlib/src/System/Globalization/SortKey.cs7
-rw-r--r--src/mscorlib/src/System/Globalization/StringInfo.cs29
-rw-r--r--src/mscorlib/src/System/Globalization/TaiwanCalendar.cs4
-rw-r--r--src/mscorlib/src/System/Globalization/TextElementEnumerator.cs7
-rw-r--r--src/mscorlib/src/System/Globalization/TextInfo.cs77
-rw-r--r--src/mscorlib/src/System/Globalization/ThaiBuddhistCalendar.cs2
-rw-r--r--src/mscorlib/src/System/Globalization/TimeSpanFormat.cs30
-rw-r--r--src/mscorlib/src/System/Globalization/TimeSpanParse.cs33
-rw-r--r--src/mscorlib/src/System/Globalization/UmAlQuraCalendar.cs31
-rw-r--r--src/mscorlib/src/System/Guid.cs37
-rw-r--r--src/mscorlib/src/System/IAppDomain.cs246
-rw-r--r--src/mscorlib/src/System/IAppDomainPauseManager.cs15
-rw-r--r--src/mscorlib/src/System/IO/BinaryReader.cs46
-rw-r--r--src/mscorlib/src/System/IO/BinaryWriter.cs37
-rw-r--r--src/mscorlib/src/System/IO/BufferedStream.cs1320
-rw-r--r--src/mscorlib/src/System/IO/Directory.cs642
-rw-r--r--src/mscorlib/src/System/IO/DirectoryInfo.cs265
-rw-r--r--src/mscorlib/src/System/IO/DriveInfo.cs281
-rw-r--r--src/mscorlib/src/System/IO/EncodingCache.cs13
-rw-r--r--src/mscorlib/src/System/IO/File.cs658
-rw-r--r--src/mscorlib/src/System/IO/FileAttributes.cs20
-rw-r--r--src/mscorlib/src/System/IO/FileInfo.cs207
-rw-r--r--src/mscorlib/src/System/IO/FileLoadException.cs14
-rw-r--r--src/mscorlib/src/System/IO/FileNotFoundException.cs11
-rw-r--r--src/mscorlib/src/System/IO/FileSecurityState.cs133
-rw-r--r--src/mscorlib/src/System/IO/FileSecurityStateAccess.cs32
-rw-r--r--src/mscorlib/src/System/IO/FileStream.cs2695
-rw-r--r--src/mscorlib/src/System/IO/FileSystemEnumerable.cs185
-rw-r--r--src/mscorlib/src/System/IO/FileSystemInfo.cs137
-rw-r--r--src/mscorlib/src/System/IO/LongPathHelper.cs521
-rw-r--r--src/mscorlib/src/System/IO/MemoryStream.cs112
-rw-r--r--src/mscorlib/src/System/IO/Path.cs1435
-rw-r--r--src/mscorlib/src/System/IO/PathHelper.cs448
-rw-r--r--src/mscorlib/src/System/IO/PathInternal.cs806
-rw-r--r--src/mscorlib/src/System/IO/PinnedBufferMemoryStream.cs6
-rw-r--r--src/mscorlib/src/System/IO/Stream.cs144
-rw-r--r--src/mscorlib/src/System/IO/StreamHelpers.CopyValidation.cs46
-rw-r--r--src/mscorlib/src/System/IO/StreamReader.cs100
-rw-r--r--src/mscorlib/src/System/IO/StreamWriter.cs175
-rw-r--r--src/mscorlib/src/System/IO/StringReader.cs187
-rw-r--r--src/mscorlib/src/System/IO/StringWriter.cs196
-rw-r--r--src/mscorlib/src/System/IO/TextReader.cs36
-rw-r--r--src/mscorlib/src/System/IO/TextWriter.cs37
-rw-r--r--src/mscorlib/src/System/IO/UnmanagedMemoryAccessor.cs215
-rw-r--r--src/mscorlib/src/System/IO/UnmanagedMemoryStream.cs187
-rw-r--r--src/mscorlib/src/System/IO/UnmanagedMemoryStreamWrapper.cs9
-rw-r--r--src/mscorlib/src/System/IO/__DebugOutputTextWriter.cs76
-rw-r--r--src/mscorlib/src/System/IO/__Error.cs12
-rw-r--r--src/mscorlib/src/System/Int16.cs3
-rw-r--r--src/mscorlib/src/System/Int32.cs4
-rw-r--r--src/mscorlib/src/System/Int64.cs4
-rw-r--r--src/mscorlib/src/System/IntPtr.cs27
-rw-r--r--src/mscorlib/src/System/Internal.cs19
-rw-r--r--src/mscorlib/src/System/InvalidTimeZoneException.cs12
-rw-r--r--src/mscorlib/src/System/Lazy.cs23
-rw-r--r--src/mscorlib/src/System/LowLevelConsole.cs3
-rw-r--r--src/mscorlib/src/System/MarshalByRefObject.cs245
-rw-r--r--src/mscorlib/src/System/Math.cs191
-rw-r--r--src/mscorlib/src/System/MathF.cs253
-rw-r--r--src/mscorlib/src/System/MissingFieldException.cs1
-rw-r--r--src/mscorlib/src/System/MissingMemberException.cs5
-rw-r--r--src/mscorlib/src/System/MissingMethodException.cs1
-rw-r--r--src/mscorlib/src/System/MulticastDelegate.cs40
-rw-r--r--src/mscorlib/src/System/NotFiniteNumberException.cs3
-rw-r--r--src/mscorlib/src/System/Nullable.cs2
-rw-r--r--src/mscorlib/src/System/Number.cs191
-rw-r--r--src/mscorlib/src/System/Numerics/Hashing/HashHelpers.cs19
-rw-r--r--src/mscorlib/src/System/Object.cs48
-rw-r--r--src/mscorlib/src/System/ObjectDisposedException.cs1
-rw-r--r--src/mscorlib/src/System/OleAutBinder.cs21
-rw-r--r--src/mscorlib/src/System/OperatingSystem.cs7
-rw-r--r--src/mscorlib/src/System/ParseNumbers.cs8
-rw-r--r--src/mscorlib/src/System/Progress.cs4
-rw-r--r--src/mscorlib/src/System/Random.cs74
-rw-r--r--src/mscorlib/src/System/ReadOnlySpan.cs397
-rw-r--r--src/mscorlib/src/System/Reflection/Assembly.cs1048
-rw-r--r--src/mscorlib/src/System/Reflection/AssemblyAttributes.cs2
-rw-r--r--src/mscorlib/src/System/Reflection/AssemblyName.cs274
-rw-r--r--src/mscorlib/src/System/Reflection/Associates.cs9
-rw-r--r--src/mscorlib/src/System/Reflection/ComInterfaces.cs572
-rw-r--r--src/mscorlib/src/System/Reflection/ConstructorInfo.cs145
-rw-r--r--src/mscorlib/src/System/Reflection/CustomAttribute.cs168
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/AQNBuilder.cs30
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/AssemblyBuilder.cs1145
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderAccess.cs6
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderData.cs40
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/ComInterfaces.cs173
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/ConstructorBuilder.cs61
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/CustomAttributeBuilder.cs143
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/DynamicILGenerator.cs69
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/DynamicMethod.cs224
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/EnumBuilder.cs30
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/EventBuilder.cs47
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/FieldBuilder.cs54
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/FlowControl.cs3
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs3
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/ILGenerator.cs111
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/ISymWrapperCore.cs136
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/LocalBuilder.cs22
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/MethodBuilder.cs165
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/ModuleBuilder.cs489
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/ModuleBuilderData.cs6
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/Opcode.cs118
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/OpcodeType.cs3
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/OperandType.cs3
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/ParameterBuilder.cs35
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/PropertyBuilder.cs49
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/SignatureHelper.cs69
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/SymbolMethod.cs1
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/SymbolType.cs2
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/TypeBuilder.cs324
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs4
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/UnmanagedMarshal.cs1
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/XXXOnTypeBuilderInstantiation.cs13
-rw-r--r--src/mscorlib/src/System/Reflection/EventInfo.cs55
-rw-r--r--src/mscorlib/src/System/Reflection/FieldInfo.cs98
-rw-r--r--src/mscorlib/src/System/Reflection/IntrospectionExtensions.cs23
-rw-r--r--src/mscorlib/src/System/Reflection/InvalidFilterCriteriaException.cs4
-rw-r--r--src/mscorlib/src/System/Reflection/LoaderAllocator.cs2
-rw-r--r--src/mscorlib/src/System/Reflection/MdConstant.cs1
-rw-r--r--src/mscorlib/src/System/Reflection/MdImport.cs55
-rw-r--r--src/mscorlib/src/System/Reflection/MemberInfo.cs31
-rw-r--r--src/mscorlib/src/System/Reflection/MemberInfoSerializationHolder.cs6
-rw-r--r--src/mscorlib/src/System/Reflection/Metadata/AssemblyExtensions.cs4
-rw-r--r--src/mscorlib/src/System/Reflection/MethodBase.cs50
-rw-r--r--src/mscorlib/src/System/Reflection/MethodBody.cs3
-rw-r--r--src/mscorlib/src/System/Reflection/MethodInfo.cs164
-rw-r--r--src/mscorlib/src/System/Reflection/Missing.cs3
-rw-r--r--src/mscorlib/src/System/Reflection/Module.cs158
-rw-r--r--src/mscorlib/src/System/Reflection/ParameterInfo.cs90
-rw-r--r--src/mscorlib/src/System/Reflection/Pointer.cs14
-rw-r--r--src/mscorlib/src/System/Reflection/PropertyInfo.cs51
-rw-r--r--src/mscorlib/src/System/Reflection/ReflectionContext.cs2
-rw-r--r--src/mscorlib/src/System/Reflection/ReflectionTypeLoadException.cs3
-rw-r--r--src/mscorlib/src/System/Reflection/RuntimeReflectionExtensions.cs4
-rw-r--r--src/mscorlib/src/System/Reflection/StrongNameKeyPair.cs115
-rw-r--r--src/mscorlib/src/System/Reflection/TargetException.cs4
-rw-r--r--src/mscorlib/src/System/Reflection/TargetInvocationException.cs4
-rw-r--r--src/mscorlib/src/System/Reflection/TargetParameterCountException.cs4
-rw-r--r--src/mscorlib/src/System/Reflection/TypeDelegator.cs5
-rw-r--r--src/mscorlib/src/System/Resources/FileBasedResourceGroveler.cs31
-rw-r--r--src/mscorlib/src/System/Resources/IResourceGroveler.cs5
-rw-r--r--src/mscorlib/src/System/Resources/LooselyLinkedResourceReference.cs10
-rw-r--r--src/mscorlib/src/System/Resources/ManifestBasedResourceGroveler.cs153
-rw-r--r--src/mscorlib/src/System/Resources/NeutralResourcesLanguageAttribute.cs4
-rw-r--r--src/mscorlib/src/System/Resources/ResourceFallbackManager.cs14
-rw-r--r--src/mscorlib/src/System/Resources/ResourceManager.cs306
-rw-r--r--src/mscorlib/src/System/Resources/ResourceReader.cs71
-rw-r--r--src/mscorlib/src/System/Resources/ResourceSet.cs21
-rw-r--r--src/mscorlib/src/System/Resources/RuntimeResourceSet.cs9
-rw-r--r--src/mscorlib/src/System/Resources/SatelliteContractVersionAttribute.cs2
-rw-r--r--src/mscorlib/src/System/Resources/__FastResourceComparer.cs14
-rw-r--r--src/mscorlib/src/System/RtType.cs861
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/AsyncMethodBuilder.cs58
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/CallingConvention.cs30
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs905
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/DecimalConstantAttribute.cs7
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/FormattableStringFactory.cs4
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/HasCopySemanticsAttribute.cs14
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IDispatchConstantAttribute.cs26
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/INotifyCompletion.cs1
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IUnknownConstantAttribute.cs27
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IsBoxed.cs11
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IsByValue.cs11
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IsConst.cs11
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IsCopyConstructed.cs11
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IsExplicitlyDereferenced.cs22
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IsImplicitlyDereferenced.cs22
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IsJitIntrinsic.cs12
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IsLong.cs18
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IsPinned.cs11
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IsSignUnspecifiedByte.cs16
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IsUdtReturn.cs11
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/NativeCppClassAttribute.cs16
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/RequiredAttributeAttribute.cs26
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs92
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/RuntimeWrappedException.cs3
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/ScopelessEnumAttribute.cs14
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/TaskAwaiter.cs23
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/TypeDependencyAttribute.cs2
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/TypeForwardedFromAttribute.cs2
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/TypeForwardedToAttribute.cs1
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/Unsafe.cs80
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/YieldAwaitable.cs6
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/jithelpers.cs52
-rw-r--r--src/mscorlib/src/System/Runtime/ExceptionServices/ExceptionNotification.cs41
-rw-r--r--src/mscorlib/src/System/Runtime/ExceptionServices/ExceptionServicesCommon.cs2
-rw-r--r--src/mscorlib/src/System/Runtime/GcSettings.cs7
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ArrayWithOffset.cs2
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/Attributes.cs12
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/BStrWrapper.cs8
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/COMException.cs1
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComEventsHelper.cs16
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComEventsInfo.cs5
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComEventsSink.cs9
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/CriticalHandle.cs11
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/CurrencyWrapper.cs2
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/DispatchWrapper.cs4
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ErrorWrapper.cs6
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ExtensibleClassFactory.cs1
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ExternalException.cs2
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/GcHandle.cs21
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ICustomQueryInterface.cs1
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/IException.cs48
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/IRegistrationServices.cs6
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/Marshal.cs622
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/NativeBuffer.cs175
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/NativeMethods.cs4
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/NonPortable.cs34
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/RegistrationServices.cs52
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/RuntimeEnvironment.cs57
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/SafeBuffer.cs28
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/SafeHandle.cs13
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/SafeHeapHandle.cs115
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/StringBuffer.cs402
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventProviderWriter.cs67
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventSinkHelperWriter.cs9
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/TypeLibConverter.cs595
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/Variant.cs1
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/BindableVectorToCollectionAdapter.cs11
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/BindableVectorToListAdapter.cs30
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIPropertyValueImpl.cs8
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIReferenceImpl.cs11
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ConstantSplittableMap.cs4
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CustomPropertyImpl.cs6
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryKeyCollection.cs8
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryToMapAdapter.cs12
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryValueCollection.cs8
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/EnumeratorToIteratorAdapter.cs7
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IClosable.cs8
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ICustomPropertyProvider.cs7
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IMapViewToIReadOnlyDictionaryAdapter.cs29
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IReadOnlyDictionaryToIMapViewAdapter.cs6
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IReadOnlyListToIVectorViewAdapter.cs8
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IRestrictedErrorInfo.cs2
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IVectorViewToIReadOnlyListAdapter.cs8
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IteratorToEnumeratorAdapter.cs19
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToBindableVectorAdapter.cs15
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToBindableVectorViewAdapter.cs4
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToVectorAdapter.cs19
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ManagedActivationFactory.cs5
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapToCollectionAdapter.cs14
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapToDictionaryAdapter.cs23
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapViewToReadOnlyCollectionAdapter.cs4
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/NativeMethods.cs7
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/RuntimeClass.cs9
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorToCollectionAdapter.cs14
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorToListAdapter.cs24
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorViewToReadOnlyCollectionAdapter.cs4
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeBufferHelper.cs2
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMarshal.cs52
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMetadata.cs5
-rw-r--r--src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs92
-rw-r--r--src/mscorlib/src/System/Runtime/MemoryFailPoint.cs16
-rw-r--r--src/mscorlib/src/System/Runtime/ProfileOptimization.cs4
-rw-r--r--src/mscorlib/src/System/Runtime/Reliability/CriticalFinalizerObject.cs6
-rw-r--r--src/mscorlib/src/System/Runtime/Remoting/ObjectHandle.cs42
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/FormatterConverter.cs34
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/FormatterServices.cs76
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/IObjectReference.cs1
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/ISerializable.cs1
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/ISerializationSurrogate.cs2
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/ISurrogateSelector.cs3
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/SafeSerializationManager.cs446
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/SerializationFieldInfo.cs36
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/SerializationInfo.cs98
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/SerializationInfoEnumerator.cs15
-rw-r--r--src/mscorlib/src/System/Runtime/Versioning/BinaryCompatibility.cs485
-rw-r--r--src/mscorlib/src/System/Runtime/Versioning/CompatibilitySwitch.cs5
-rw-r--r--src/mscorlib/src/System/Runtime/Versioning/ComponentGuaranteesAttribute.cs44
-rw-r--r--src/mscorlib/src/System/Runtime/Versioning/ResourceAttributes.cs237
-rw-r--r--src/mscorlib/src/System/Runtime/Versioning/TargetFrameworkAttribute.cs2
-rw-r--r--src/mscorlib/src/System/RuntimeHandles.cs273
-rw-r--r--src/mscorlib/src/System/SByte.cs3
-rw-r--r--src/mscorlib/src/System/Security/AccessControl/Enums.cs6
-rw-r--r--src/mscorlib/src/System/Security/Attributes.cs11
-rw-r--r--src/mscorlib/src/System/Security/BuiltInPermissionSets.cs103
-rw-r--r--src/mscorlib/src/System/Security/CodeAccessPermission.cs69
-rw-r--r--src/mscorlib/src/System/Security/CodeAccessSecurityEngine.cs468
-rw-r--r--src/mscorlib/src/System/Security/FrameSecurityDescriptor.cs31
-rw-r--r--src/mscorlib/src/System/Security/HostProtectionException.cs5
-rw-r--r--src/mscorlib/src/System/Security/HostSecurityManager.cs131
-rw-r--r--src/mscorlib/src/System/Security/IEvidenceFactory.cs15
-rw-r--r--src/mscorlib/src/System/Security/ISecurityEncodable.cs18
-rw-r--r--src/mscorlib/src/System/Security/ISecurityPolicyEncodable.cs17
-rw-r--r--src/mscorlib/src/System/Security/NamedPermissionSet.cs202
-rw-r--r--src/mscorlib/src/System/Security/PermissionListSet.cs29
-rw-r--r--src/mscorlib/src/System/Security/PermissionSet.cs1100
-rw-r--r--src/mscorlib/src/System/Security/PermissionSetEnumerator.cs14
-rw-r--r--src/mscorlib/src/System/Security/PermissionSetTriple.cs20
-rw-r--r--src/mscorlib/src/System/Security/PermissionToken.cs202
-rw-r--r--src/mscorlib/src/System/Security/Permissions/EnvironmentPermission.cs60
-rw-r--r--src/mscorlib/src/System/Security/Permissions/FileDialogPermission.cs33
-rw-r--r--src/mscorlib/src/System/Security/Permissions/FileIOPermission.cs304
-rw-r--r--src/mscorlib/src/System/Security/Permissions/GACIdentityPermission.cs16
-rw-r--r--src/mscorlib/src/System/Security/Permissions/HostProtectionPermission.cs34
-rw-r--r--src/mscorlib/src/System/Security/Permissions/IsolatedStorageFilePermission.cs13
-rw-r--r--src/mscorlib/src/System/Security/Permissions/IsolatedStoragePermission.cs91
-rw-r--r--src/mscorlib/src/System/Security/Permissions/PermissionAttributes.cs314
-rw-r--r--src/mscorlib/src/System/Security/Permissions/ReflectionPermission.cs39
-rw-r--r--src/mscorlib/src/System/Security/Permissions/RegistryPermission.cs131
-rw-r--r--src/mscorlib/src/System/Security/Permissions/SecurityPermission.cs96
-rw-r--r--src/mscorlib/src/System/Security/Permissions/SiteIdentityPermission.cs108
-rw-r--r--src/mscorlib/src/System/Security/Permissions/StrongNameIdentityPermission.cs90
-rw-r--r--src/mscorlib/src/System/Security/Permissions/StrongNamePublicKeyBlob.cs2
-rw-r--r--src/mscorlib/src/System/Security/Permissions/UIPermission.cs44
-rw-r--r--src/mscorlib/src/System/Security/Permissions/URLIdentityPermission.cs111
-rw-r--r--src/mscorlib/src/System/Security/Permissions/ZoneIdentityPermission.cs101
-rw-r--r--src/mscorlib/src/System/Security/Permissions/keycontainerpermission.cs72
-rw-r--r--src/mscorlib/src/System/Security/Policy/ApplicationTrust.cs573
-rw-r--r--src/mscorlib/src/System/Security/Policy/Evidence.cs1865
-rw-r--r--src/mscorlib/src/System/Security/Policy/EvidenceBase.cs31
-rw-r--r--src/mscorlib/src/System/Security/Policy/EvidenceTypeDescriptor.cs20
-rw-r--r--src/mscorlib/src/System/Security/Policy/IDelayEvaluatedEvidence.cs1
-rw-r--r--src/mscorlib/src/System/Security/Policy/PolicyStatement.cs302
-rw-r--r--src/mscorlib/src/System/Security/Policy/Site.cs29
-rw-r--r--src/mscorlib/src/System/Security/Policy/StrongName.cs59
-rw-r--r--src/mscorlib/src/System/Security/Policy/URL.cs29
-rw-r--r--src/mscorlib/src/System/Security/Policy/Zone.cs66
-rw-r--r--src/mscorlib/src/System/Security/Principal/TokenImpersonationLevel.cs9
-rw-r--r--src/mscorlib/src/System/Security/SafeSecurityHandles.cs16
-rw-r--r--src/mscorlib/src/System/Security/SecurityContext.cs238
-rw-r--r--src/mscorlib/src/System/Security/SecurityElement.cs100
-rw-r--r--src/mscorlib/src/System/Security/SecurityException.cs608
-rw-r--r--src/mscorlib/src/System/Security/SecurityManager.cs524
-rw-r--r--src/mscorlib/src/System/Security/SecurityRuntime.cs156
-rw-r--r--src/mscorlib/src/System/Security/SecurityState.cs10
-rw-r--r--src/mscorlib/src/System/Security/Util/Config.cs48
-rw-r--r--src/mscorlib/src/System/Security/Util/Hex.cs2
-rw-r--r--src/mscorlib/src/System/Security/Util/StringExpressionSet.cs41
-rw-r--r--src/mscorlib/src/System/Security/Util/TokenBasedSet.cs32
-rw-r--r--src/mscorlib/src/System/Security/Util/URLString.cs17
-rw-r--r--src/mscorlib/src/System/Security/Util/XMLUtil.cs272
-rw-r--r--src/mscorlib/src/System/Security/securestring.cs31
-rw-r--r--src/mscorlib/src/System/SharedStatics.cs64
-rw-r--r--src/mscorlib/src/System/Single.cs16
-rw-r--r--src/mscorlib/src/System/Span.cs477
-rw-r--r--src/mscorlib/src/System/String.Comparison.cs82
-rw-r--r--src/mscorlib/src/System/String.Manipulation.cs475
-rw-r--r--src/mscorlib/src/System/String.Searching.cs36
-rw-r--r--src/mscorlib/src/System/String.cs126
-rw-r--r--src/mscorlib/src/System/StringComparer.cs35
-rw-r--r--src/mscorlib/src/System/StubHelpers.cs161
-rw-r--r--src/mscorlib/src/System/Text/ASCIIEncoding.cs77
-rw-r--r--src/mscorlib/src/System/Text/BaseCodePageEncoding.cs30
-rw-r--r--src/mscorlib/src/System/Text/CodePageEncoding.cs13
-rw-r--r--src/mscorlib/src/System/Text/DBCSCodePageEncoding.cs102
-rw-r--r--src/mscorlib/src/System/Text/Decoder.cs32
-rw-r--r--src/mscorlib/src/System/Text/DecoderBestFitFallback.cs9
-rw-r--r--src/mscorlib/src/System/Text/DecoderFallback.cs13
-rw-r--r--src/mscorlib/src/System/Text/DecoderNLS.cs43
-rw-r--r--src/mscorlib/src/System/Text/DecoderReplacementFallback.cs9
-rw-r--r--src/mscorlib/src/System/Text/EUCJPEncoding.cs3
-rw-r--r--src/mscorlib/src/System/Text/Encoder.cs32
-rw-r--r--src/mscorlib/src/System/Text/EncoderBestFitFallback.cs12
-rw-r--r--src/mscorlib/src/System/Text/EncoderExceptionFallback.cs6
-rw-r--r--src/mscorlib/src/System/Text/EncoderFallback.cs8
-rw-r--r--src/mscorlib/src/System/Text/EncoderNLS.cs43
-rw-r--r--src/mscorlib/src/System/Text/EncoderReplacementFallback.cs10
-rw-r--r--src/mscorlib/src/System/Text/Encoding.cs222
-rw-r--r--src/mscorlib/src/System/Text/EncodingForwarder.cs98
-rw-r--r--src/mscorlib/src/System/Text/EncodingNLS.cs4
-rw-r--r--src/mscorlib/src/System/Text/EncodingProvider.cs2
-rw-r--r--src/mscorlib/src/System/Text/GB18030Encoding.cs60
-rw-r--r--src/mscorlib/src/System/Text/ISCIIEncoding.cs88
-rw-r--r--src/mscorlib/src/System/Text/ISO2022Encoding.cs74
-rw-r--r--src/mscorlib/src/System/Text/Latin1Encoding.cs66
-rw-r--r--src/mscorlib/src/System/Text/MLangCodePageEncoding.cs19
-rw-r--r--src/mscorlib/src/System/Text/Normalization.Unix.cs123
-rw-r--r--src/mscorlib/src/System/Text/Normalization.Windows.cs286
-rw-r--r--src/mscorlib/src/System/Text/Normalization.cs314
-rw-r--r--src/mscorlib/src/System/Text/SBCSCodePageEncoding.cs93
-rw-r--r--src/mscorlib/src/System/Text/StringBuilder.cs309
-rw-r--r--src/mscorlib/src/System/Text/SurrogateEncoder.cs7
-rw-r--r--src/mscorlib/src/System/Text/UTF32Encoding.cs71
-rw-r--r--src/mscorlib/src/System/Text/UTF7Encoding.cs55
-rw-r--r--src/mscorlib/src/System/Text/UTF8Encoding.cs96
-rw-r--r--src/mscorlib/src/System/Text/UnicodeEncoding.cs92
-rw-r--r--src/mscorlib/src/System/Threading/AsyncLocal.cs387
-rw-r--r--src/mscorlib/src/System/Threading/AutoResetEvent.cs1
-rw-r--r--src/mscorlib/src/System/Threading/CancellationToken.cs14
-rw-r--r--src/mscorlib/src/System/Threading/CancellationTokenRegistration.cs1
-rw-r--r--src/mscorlib/src/System/Threading/CancellationTokenSource.cs37
-rw-r--r--src/mscorlib/src/System/Threading/CountdownEvent.cs23
-rw-r--r--src/mscorlib/src/System/Threading/EventWaitHandle.cs69
-rw-r--r--src/mscorlib/src/System/Threading/ExecutionContext.cs1222
-rw-r--r--src/mscorlib/src/System/Threading/Interlocked.cs17
-rw-r--r--src/mscorlib/src/System/Threading/LazyInitializer.cs4
-rw-r--r--src/mscorlib/src/System/Threading/LockRecursionException.cs3
-rw-r--r--src/mscorlib/src/System/Threading/ManualResetEvent.cs1
-rw-r--r--src/mscorlib/src/System/Threading/ManualResetEventSlim.cs33
-rw-r--r--src/mscorlib/src/System/Threading/Monitor.cs26
-rw-r--r--src/mscorlib/src/System/Threading/Mutex.cs208
-rw-r--r--src/mscorlib/src/System/Threading/Overlapped.cs42
-rw-r--r--src/mscorlib/src/System/Threading/ReaderWriterLock.cs36
-rw-r--r--src/mscorlib/src/System/Threading/Semaphore.cs35
-rw-r--r--src/mscorlib/src/System/Threading/SemaphoreFullException.cs3
-rw-r--r--src/mscorlib/src/System/Threading/SemaphoreSlim.cs50
-rw-r--r--src/mscorlib/src/System/Threading/SpinLock.cs110
-rw-r--r--src/mscorlib/src/System/Threading/SpinWait.cs18
-rw-r--r--src/mscorlib/src/System/Threading/SynchronizationContext.cs90
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/AsyncCausalityTracer.cs4
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/BeginEndAwaitableAdapter.cs16
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs42
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/FutureFactory.cs148
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/Parallel.cs229
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/ParallelLoopState.cs7
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/ParallelRangeManager.cs9
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/ProducerConsumerQueues.cs12
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/TPLETWProvider.cs12
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/Task.cs229
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/TaskCompletionSource.cs6
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/TaskContinuation.cs64
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/TaskExceptionHolder.cs36
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/TaskFactory.cs100
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/TaskScheduler.cs21
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/TaskToApm.cs5
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs7
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/future.cs27
-rw-r--r--src/mscorlib/src/System/Threading/Thread.cs633
-rw-r--r--src/mscorlib/src/System/Threading/ThreadAbortException.cs1
-rw-r--r--src/mscorlib/src/System/Threading/ThreadLocal.cs17
-rw-r--r--src/mscorlib/src/System/Threading/ThreadPool.cs230
-rw-r--r--src/mscorlib/src/System/Threading/Timer.cs79
-rw-r--r--src/mscorlib/src/System/Threading/Volatile.cs6
-rw-r--r--src/mscorlib/src/System/Threading/WaitHandle.cs83
-rw-r--r--src/mscorlib/src/System/Threading/WaitHandleCannotBeOpenedException.cs4
-rw-r--r--src/mscorlib/src/System/Threading/WaitHandleExtensions.cs46
-rw-r--r--src/mscorlib/src/System/ThrowHelper.cs211
-rw-r--r--src/mscorlib/src/System/TimeSpan.cs28
-rw-r--r--src/mscorlib/src/System/TimeZone.cs4
-rw-r--r--src/mscorlib/src/System/TimeZoneInfo.cs641
-rw-r--r--src/mscorlib/src/System/TimeZoneNotFoundException.cs3
-rw-r--r--src/mscorlib/src/System/Tuple.cs23
-rw-r--r--src/mscorlib/src/System/Type.cs144
-rw-r--r--src/mscorlib/src/System/TypeInitializationException.cs1
-rw-r--r--src/mscorlib/src/System/TypeLoadException.cs9
-rw-r--r--src/mscorlib/src/System/TypeNameParser.cs30
-rw-r--r--src/mscorlib/src/System/TypedReference.cs10
-rw-r--r--src/mscorlib/src/System/UInt16.cs4
-rw-r--r--src/mscorlib/src/System/UInt32.cs4
-rw-r--r--src/mscorlib/src/System/UInt64.cs4
-rw-r--r--src/mscorlib/src/System/UIntPtr.cs25
-rw-r--r--src/mscorlib/src/System/UnSafeCharBuffer.cs57
-rw-r--r--src/mscorlib/src/System/UnhandledExceptionEventHandler.cs3
-rw-r--r--src/mscorlib/src/System/UnitySerializationHolder.cs4
-rw-r--r--src/mscorlib/src/System/ValueType.cs4
-rw-r--r--src/mscorlib/src/System/Variant.cs27
-rw-r--r--src/mscorlib/src/System/Version.cs164
-rw-r--r--src/mscorlib/src/System/WeakReference.cs23
-rw-r--r--src/mscorlib/src/System/WeakReferenceOfT.cs10
-rw-r--r--src/mscorlib/src/System/_LocalDataStore.cs6
-rw-r--r--src/mscorlib/src/System/_LocalDataStoreMgr.cs13
-rw-r--r--src/mscorlib/src/System/__ComObject.cs13
-rw-r--r--src/mscorlib/src/System/cominterfaces.cs34
-rw-r--r--src/mscorlib/src/System/mda.cs11
-rw-r--r--src/mscorlib/src/mscorlib.Friends.cs2
-rw-r--r--src/mscorlib/src/mscorlib.txt3494
-rw-r--r--src/nativeresources/resourcestring.cpp10
-rw-r--r--src/pal/inc/mbusafecrt.h16
-rw-r--r--src/pal/inc/pal.h196
-rw-r--r--src/pal/inc/pal_char16.h3
-rw-r--r--src/pal/inc/pal_mstypes.h11
-rw-r--r--src/pal/inc/rt/palrt.h180
-rw-r--r--src/pal/inc/rt/safecrt.h13
-rw-r--r--src/pal/inc/strsafe.h1512
-rw-r--r--src/pal/inc/unixasmmacros.inc4
-rw-r--r--src/pal/inc/unixasmmacrosamd64.inc2
-rw-r--r--src/pal/inc/unixasmmacrosarm.inc3
-rw-r--r--src/pal/inc/unixasmmacrosarm64.inc2
-rw-r--r--src/pal/inc/unixasmmacrosx86.inc87
-rw-r--r--src/pal/prebuilt/idl/clrdata_i.cpp (renamed from src/pal/prebuilt/idl/clrdata_i.c)0
-rw-r--r--src/pal/prebuilt/idl/clrinternal_i.cpp (renamed from src/pal/prebuilt/idl/clrinternal_i.c)0
-rw-r--r--src/pal/prebuilt/idl/clrprivappxhosting_i.cpp (renamed from src/pal/prebuilt/idl/clrprivappxhosting_i.c)0
-rw-r--r--src/pal/prebuilt/idl/clrprivbinding_i.cpp (renamed from src/pal/prebuilt/idl/clrprivbinding_i.c)0
-rw-r--r--src/pal/prebuilt/idl/clrprivhosting_i.cpp (renamed from src/pal/prebuilt/idl/clrprivhosting_i.c)0
-rw-r--r--src/pal/prebuilt/idl/clrprivruntimebinders_i.cpp (renamed from src/pal/prebuilt/idl/clrprivruntimebinders_i.c)0
-rw-r--r--src/pal/prebuilt/idl/cordebug_i.c451
-rw-r--r--src/pal/prebuilt/idl/cordebug_i.cpp463
-rw-r--r--src/pal/prebuilt/idl/corprof_i.c134
-rw-r--r--src/pal/prebuilt/idl/corprof_i.cpp140
-rw-r--r--src/pal/prebuilt/idl/corpub_i.cpp (renamed from src/pal/prebuilt/idl/corpub_i.c)0
-rw-r--r--src/pal/prebuilt/idl/corsym_i.cpp (renamed from src/pal/prebuilt/idl/corsym_i.c)0
-rw-r--r--src/pal/prebuilt/idl/fusionpriv_i.cpp (renamed from src/pal/prebuilt/idl/fusionpriv_i.c)0
-rw-r--r--src/pal/prebuilt/idl/gchost_i.cpp (renamed from src/pal/prebuilt/idl/gchost_i.c)0
-rw-r--r--src/pal/prebuilt/idl/ivalidator_i.cpp (renamed from src/pal/prebuilt/idl/ivalidator_i.c)0
-rw-r--r--src/pal/prebuilt/idl/ivehandler_i.cpp (renamed from src/pal/prebuilt/idl/ivehandler_i.c)0
-rw-r--r--src/pal/prebuilt/idl/mscorsvc_i.cpp (renamed from src/pal/prebuilt/idl/mscorsvc_i.c)0
-rw-r--r--src/pal/prebuilt/idl/sospriv_i.c100
-rw-r--r--src/pal/prebuilt/idl/sospriv_i.cpp98
-rw-r--r--src/pal/prebuilt/idl/tlbimpexp_i.cpp (renamed from src/pal/prebuilt/idl/tlbimpexp_i.c)0
-rw-r--r--src/pal/prebuilt/idl/xclrdata_i.cpp (renamed from src/pal/prebuilt/idl/xclrdata_i.c)0
-rw-r--r--src/pal/prebuilt/idl/xcordebug_i.cpp (renamed from src/pal/prebuilt/idl/xcordebug_i.c)0
-rw-r--r--src/pal/prebuilt/inc/cordebug.h485
-rw-r--r--src/pal/prebuilt/inc/corprof.h1714
-rw-r--r--src/pal/prebuilt/inc/xclrdata.h12
-rw-r--r--src/pal/src/CMakeLists.txt108
-rw-r--r--src/pal/src/arch/amd64/activationhandlerwrapper.S (renamed from src/pal/src/arch/i386/activationhandlerwrapper.S)0
-rw-r--r--src/pal/src/arch/amd64/asmconstants.h106
-rw-r--r--src/pal/src/arch/amd64/context.S (renamed from src/pal/src/arch/i386/context.S)0
-rw-r--r--src/pal/src/arch/amd64/context2.S259
-rw-r--r--src/pal/src/arch/amd64/debugbreak.S12
-rw-r--r--src/pal/src/arch/amd64/dispatchexceptionwrapper.S (renamed from src/pal/src/arch/i386/dispatchexceptionwrapper.S)0
-rw-r--r--src/pal/src/arch/amd64/exceptionhelper.S42
-rw-r--r--src/pal/src/arch/amd64/optimizedtls.cpp237
-rw-r--r--src/pal/src/arch/amd64/processor.cpp64
-rw-r--r--src/pal/src/arch/arm/exceptionhelper.S2
-rw-r--r--src/pal/src/arch/i386/asmconstants.h76
-rw-r--r--src/pal/src/arch/i386/context2.S354
-rw-r--r--src/pal/src/arch/i386/exceptionhelper.S47
-rw-r--r--src/pal/src/arch/i386/optimizedtls.cpp237
-rw-r--r--src/pal/src/config.h.in1
-rw-r--r--src/pal/src/configure.cmake11
-rw-r--r--src/pal/src/cruntime/lstr.cpp210
-rw-r--r--src/pal/src/cruntime/math.cpp367
-rw-r--r--src/pal/src/cruntime/mbstring.cpp54
-rw-r--r--src/pal/src/cruntime/path.cpp482
-rw-r--r--src/pal/src/cruntime/printf.cpp202
-rw-r--r--src/pal/src/cruntime/string.cpp55
-rw-r--r--src/pal/src/cruntime/wchar.cpp211
-rw-r--r--src/pal/src/debug/debug.cpp1087
-rw-r--r--src/pal/src/examples/CMakeLists.txt2
-rw-r--r--src/pal/src/examples/example1.cpp (renamed from src/pal/src/examples/example1.c)0
-rw-r--r--src/pal/src/exception/machexception.cpp7
-rw-r--r--src/pal/src/exception/machmessage.cpp2
-rw-r--r--src/pal/src/exception/machmessage.h4
-rw-r--r--src/pal/src/exception/seh-unwind.cpp76
-rw-r--r--src/pal/src/exception/seh.cpp8
-rw-r--r--src/pal/src/exception/signal.cpp6
-rw-r--r--src/pal/src/file/find.cpp10
-rw-r--r--src/pal/src/include/pal/context.h24
-rw-r--r--src/pal/src/include/pal/palinternal.h45
-rw-r--r--src/pal/src/init/pal.cpp3
-rw-r--r--src/pal/src/map/virtual.cpp5
-rw-r--r--src/pal/src/misc/sysinfo.cpp2
-rw-r--r--src/pal/src/safecrt/input.inl4
-rw-r--r--src/pal/src/safecrt/makepath_s.cpp (renamed from src/pal/src/safecrt/makepath_s.c)0
-rw-r--r--src/pal/src/safecrt/mbusafecrt.c254
-rw-r--r--src/pal/src/safecrt/mbusafecrt.cpp249
-rw-r--r--src/pal/src/safecrt/memcpy_s.cpp (renamed from src/pal/src/safecrt/memcpy_s.c)0
-rw-r--r--src/pal/src/safecrt/memmove_s.cpp (renamed from src/pal/src/safecrt/memmove_s.c)0
-rw-r--r--src/pal/src/safecrt/output.inl39
-rw-r--r--src/pal/src/safecrt/safecrt_input_s.cpp (renamed from src/pal/src/safecrt/safecrt_input_s.c)0
-rw-r--r--src/pal/src/safecrt/safecrt_output_l.cpp (renamed from src/pal/src/safecrt/safecrt_output_l.c)0
-rw-r--r--src/pal/src/safecrt/safecrt_output_s.cpp (renamed from src/pal/src/safecrt/safecrt_output_s.c)0
-rw-r--r--src/pal/src/safecrt/safecrt_winput_s.cpp (renamed from src/pal/src/safecrt/safecrt_winput_s.c)0
-rw-r--r--src/pal/src/safecrt/safecrt_woutput_s.cpp (renamed from src/pal/src/safecrt/safecrt_woutput_s.c)0
-rw-r--r--src/pal/src/safecrt/snprintf.c18
-rw-r--r--src/pal/src/safecrt/snprintf.cpp18
-rw-r--r--src/pal/src/safecrt/splitpath_s.cpp (renamed from src/pal/src/safecrt/splitpath_s.c)0
-rw-r--r--src/pal/src/safecrt/sprintf.c98
-rw-r--r--src/pal/src/safecrt/sprintf_s.cpp98
-rw-r--r--src/pal/src/safecrt/sscanf.c249
-rw-r--r--src/pal/src/safecrt/sscanf_s.cpp249
-rw-r--r--src/pal/src/safecrt/strcat_s.cpp (renamed from src/pal/src/safecrt/strcat_s.c)0
-rw-r--r--src/pal/src/safecrt/strcpy_s.cpp (renamed from src/pal/src/safecrt/strcpy_s.c)0
-rw-r--r--src/pal/src/safecrt/strlen_s.c58
-rw-r--r--src/pal/src/safecrt/strlen_s.cpp58
-rw-r--r--src/pal/src/safecrt/strncat_s.cpp (renamed from src/pal/src/safecrt/strncat_s.c)0
-rw-r--r--src/pal/src/safecrt/strncpy_s.cpp (renamed from src/pal/src/safecrt/strncpy_s.c)0
-rw-r--r--src/pal/src/safecrt/strtok_s.cpp (renamed from src/pal/src/safecrt/strtok_s.c)0
-rw-r--r--src/pal/src/safecrt/swprintf.c120
-rw-r--r--src/pal/src/safecrt/swprintf.cpp120
-rw-r--r--src/pal/src/safecrt/vsprintf.c268
-rw-r--r--src/pal/src/safecrt/vsprintf.cpp268
-rw-r--r--src/pal/src/safecrt/vswprint.c282
-rw-r--r--src/pal/src/safecrt/vswprint.cpp211
-rw-r--r--src/pal/src/safecrt/wcscat_s.cpp (renamed from src/pal/src/safecrt/wcscat_s.c)0
-rw-r--r--src/pal/src/safecrt/wcscpy_s.cpp (renamed from src/pal/src/safecrt/wcscpy_s.c)0
-rw-r--r--src/pal/src/safecrt/wcslen_s.cpp (renamed from src/pal/src/safecrt/wcslen_s.c)0
-rw-r--r--src/pal/src/safecrt/wcsncat_s.cpp (renamed from src/pal/src/safecrt/wcsncat_s.c)0
-rw-r--r--src/pal/src/safecrt/wcsncpy_s.cpp (renamed from src/pal/src/safecrt/wcsncpy_s.c)0
-rw-r--r--src/pal/src/safecrt/wcstok_s.cpp (renamed from src/pal/src/safecrt/wcstok_s.c)0
-rw-r--r--src/pal/src/safecrt/wmakepath_s.cpp (renamed from src/pal/src/safecrt/wmakepath_s.c)0
-rw-r--r--src/pal/src/safecrt/wsplitpath_s.cpp (renamed from src/pal/src/safecrt/wsplitpath_s.c)0
-rw-r--r--src/pal/src/safecrt/xtoa_s.cpp (renamed from src/pal/src/safecrt/xtoa_s.c)0
-rw-r--r--src/pal/src/safecrt/xtow_s.cpp (renamed from src/pal/src/safecrt/xtow_s.c)0
-rw-r--r--src/pal/src/safecrt/xtox_s.inl29
-rw-r--r--src/pal/src/synchmgr/synchmanager.cpp2
-rw-r--r--src/pal/src/thread/context.cpp108
-rw-r--r--src/pal/src/thread/process.cpp12
-rw-r--r--src/pal/tests/CMakeLists.txt15
-rw-r--r--src/pal/tests/palsuite/c_runtime/CMakeLists.txt35
-rw-r--r--src/pal/tests/palsuite/c_runtime/__iscsym/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/__iscsym/test1/__iscsym.cpp (renamed from src/pal/tests/palsuite/c_runtime/__iscsym/test1/__iscsym.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_alloca/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_alloca/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/_alloca/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_ecvt/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_ecvt/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/_ecvt/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_fdopen/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_fdopen/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/_fdopen/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_finite/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_finite/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/_finite/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_finitef/CMakeLists.txt3
-rw-r--r--src/pal/tests/palsuite/c_runtime/_finitef/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_finitef/test1/test1.c119
-rw-r--r--src/pal/tests/palsuite/c_runtime/_finitef/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/c_runtime/_fullpath/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_fullpath/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/_fullpath/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_gcvt/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_gcvt/test1/_gcvt.cpp (renamed from src/pal/tests/palsuite/c_runtime/_gcvt/test1/_gcvt.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_gcvt/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_gcvt/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/_gcvt/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_getw/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_getw/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/_getw/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_isnan/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_isnan/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/_isnan/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_isnanf/CMakeLists.txt3
-rw-r--r--src/pal/tests/palsuite/c_runtime/_isnanf/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_isnanf/test1/test1.c115
-rw-r--r--src/pal/tests/palsuite/c_runtime/_isnanf/test1/testinfo.dat16
-rw-r--r--src/pal/tests/palsuite/c_runtime/_itow/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_itow/test1/test1.c102
-rw-r--r--src/pal/tests/palsuite/c_runtime/_itow/test1/test1.cpp101
-rw-r--r--src/pal/tests/palsuite/c_runtime/_itow/test1/testinfo.dat6
-rw-r--r--src/pal/tests/palsuite/c_runtime/_makepath/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_makepath/test1/test1.c65
-rw-r--r--src/pal/tests/palsuite/c_runtime/_makepath/test1/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_mbsdec/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_mbsdec/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/_mbsdec/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_mbsinc/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_mbsinc/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/_mbsinc/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_mbslen/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/c_runtime/_mbslen/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_mbslen/test1/test1.c66
-rw-r--r--src/pal/tests/palsuite/c_runtime/_mbslen/test1/testinfo.dat15
-rw-r--r--src/pal/tests/palsuite/c_runtime/_mbsninc/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_mbsninc/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/_mbsninc/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_open_osfhandle/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_open_osfhandle/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/_open_osfhandle/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_open_osfhandle/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_open_osfhandle/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/_open_osfhandle/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_putenv/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_putenv/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/_putenv/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_putenv/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_putenv/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/_putenv/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_putenv/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_putenv/test3/test3.cpp (renamed from src/pal/tests/palsuite/c_runtime/_putenv/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_putenv/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_putenv/test4/test4.cpp (renamed from src/pal/tests/palsuite/c_runtime/_putenv/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_putw/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_putw/test1/test1.c112
-rw-r--r--src/pal/tests/palsuite/c_runtime/_putw/test1/test1.cpp112
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/CMakeLists.txt22
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/_snprintf.h194
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test1/test1.c58
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test1/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test10/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test10/test10.c55
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test10/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test11/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test11/test11.c54
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test11/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test12/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test12/test12.c55
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test12/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test13/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test13/test13.c55
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test13/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test14/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test14/test14.c57
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test14/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test15/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test15/test15.c56
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test15/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test16/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test16/test16.c52
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test16/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test17/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test17/test17.c53
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test17/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test18/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test18/test18.c53
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test18/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test19/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test19/test19.c76
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test19/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test2/test2.c44
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test2/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test3/test3.c45
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test3/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test4/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test4/test4.c69
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test4/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test5/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test5/test5.c61
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test5/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test6/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test6/test6.c47
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test6/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test7/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test7/test7.c47
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test7/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test8/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test8/test8.c56
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test8/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test9/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test9/test9.c55
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf/test9/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/CMakeLists.txt21
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/_snprintf_s.h194
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test1/test1.cpp58
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test1/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test10/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test10/test10.cpp55
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test10/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test11/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test11/test11.cpp54
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test11/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test12/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test12/test12.cpp55
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test12/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test13/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test13/test13.cpp55
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test13/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test14/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test14/test14.cpp57
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test14/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test15/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test15/test15.cpp56
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test15/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test16/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test16/test16.cpp52
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test16/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test17/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test17/test17.cpp53
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test17/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test18/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test18/test18.cpp53
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test18/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test19/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test19/test19.cpp70
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test19/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test2/test2.cpp44
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test2/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test3/test3.cpp45
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test3/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test4/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test4/test4.cpp69
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test4/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test6/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test6/test6.cpp47
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test6/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test7/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test7/test7.cpp47
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test7/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test8/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test8/test8.cpp56
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test8/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test9/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test9/test9.cpp55
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snprintf_s/test9/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/CMakeLists.txt22
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/_snwprintf.h199
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test1/test1.c62
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test1/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test10/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test10/test10.c54
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test10/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test11/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test11/test11.c54
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test11/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test12/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test12/test12.c54
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test12/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test13/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test13/test13.c54
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test13/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test14/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test14/test14.c66
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test14/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test15/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test15/test15.c67
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test15/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test16/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test16/test16.c65
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test16/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test17/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test17/test17.c68
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test17/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test18/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test18/test18.c69
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test18/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test19/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test19/test19.c90
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test19/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test2/test2.c44
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test2/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test3/test3.c44
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test3/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test4/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test4/test4.c71
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test4/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test5/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test5/test5.c63
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test5/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test6/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test6/test6.c46
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test6/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test7/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test7/test7.c46
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test7/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test8/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test8/test8.c53
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test8/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test9/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test9/test9.c53
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf/test9/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/CMakeLists.txt21
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/_snwprintf_s.h199
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test1/test1.cpp62
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test1/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test10/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test10/test10.cpp54
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test10/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test11/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test11/test11.cpp54
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test11/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test12/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test12/test12.cpp54
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test12/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test13/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test13/test13.cpp54
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test13/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test14/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test14/test14.cpp66
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test14/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test15/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test15/test15.cpp67
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test15/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test16/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test16/test16.cpp65
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test16/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test17/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test17/test17.cpp68
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test17/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test18/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test18/test18.cpp69
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test18/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test19/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test19/test19.cpp82
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test19/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test2/test2.cpp44
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test2/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test3/test3.cpp44
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test3/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test4/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test4/test4.cpp71
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test4/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test6/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test6/test6.cpp46
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test6/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test7/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test7/test7.cpp46
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test7/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test8/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test8/test8.cpp53
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test8/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test9/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test9/test9.cpp53
-rw-r--r--src/pal/tests/palsuite/c_runtime/_snwprintf_s/test9/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/_splitpath/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/c_runtime/_splitpath/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_splitpath/test1/test1.c108
-rw-r--r--src/pal/tests/palsuite/c_runtime/_splitpath/test1/testinfo.dat15
-rw-r--r--src/pal/tests/palsuite/c_runtime/_stricmp/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_stricmp/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/_stricmp/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_strlwr/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_strlwr/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/_strlwr/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_strnicmp/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_strnicmp/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/_strnicmp/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_swab/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/c_runtime/_swab/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_swab/test1/test1.c45
-rw-r--r--src/pal/tests/palsuite/c_runtime/_swab/test1/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/_vsnprintf.h14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/_vsnprintf/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test1/testinfo.dat2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test10/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test10/test10.cpp (renamed from src/pal/tests/palsuite/c_runtime/_vsnprintf/test10/test10.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test10/testinfo.dat2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test11/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test11/test11.cpp (renamed from src/pal/tests/palsuite/c_runtime/_vsnprintf/test11/test11.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test11/testinfo.dat2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test12/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test12/test12.cpp (renamed from src/pal/tests/palsuite/c_runtime/_vsnprintf/test12/test12.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test12/testinfo.dat2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test13/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test13/test13.cpp (renamed from src/pal/tests/palsuite/c_runtime/_vsnprintf/test13/test13.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test13/testinfo.dat2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test14/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test14/test14.cpp (renamed from src/pal/tests/palsuite/c_runtime/_vsnprintf/test14/test14.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test14/testinfo.dat2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test15/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test15/test15.cpp (renamed from src/pal/tests/palsuite/c_runtime/_vsnprintf/test15/test15.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test15/testinfo.dat2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test16/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test16/test16.cpp (renamed from src/pal/tests/palsuite/c_runtime/_vsnprintf/test16/test16.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test16/testinfo.dat2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test17/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test17/test17.cpp (renamed from src/pal/tests/palsuite/c_runtime/_vsnprintf/test17/test17.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test17/testinfo.dat2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test18/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test18/test18.cpp (renamed from src/pal/tests/palsuite/c_runtime/_vsnprintf/test18/test18.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test18/testinfo.dat2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test19/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test19/test19.c103
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test19/test19.cpp103
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test19/testinfo.dat2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/_vsnprintf/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test2/testinfo.dat2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test3/test3.cpp (renamed from src/pal/tests/palsuite/c_runtime/_vsnprintf/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test3/testinfo.dat2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test4/test4.cpp (renamed from src/pal/tests/palsuite/c_runtime/_vsnprintf/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test4/testinfo.dat2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test5/test5.cpp (renamed from src/pal/tests/palsuite/c_runtime/_vsnprintf/test5/test5.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test5/testinfo.dat2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test6/test6.cpp (renamed from src/pal/tests/palsuite/c_runtime/_vsnprintf/test6/test6.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test6/testinfo.dat2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test7/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test7/test7.cpp (renamed from src/pal/tests/palsuite/c_runtime/_vsnprintf/test7/test7.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test7/testinfo.dat2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test8/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test8/test8.cpp (renamed from src/pal/tests/palsuite/c_runtime/_vsnprintf/test8/test8.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test8/testinfo.dat2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test9/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test9/test9.cpp (renamed from src/pal/tests/palsuite/c_runtime/_vsnprintf/test9/test9.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnprintf/test9/testinfo.dat2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/CMakeLists.txt22
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/_vsnwprintf.h133
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test1/test1.c60
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test1/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test10/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test10/test10.c50
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test10/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test11/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test11/test11.c50
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test11/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test12/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test12/test12.c50
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test12/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test13/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test13/test13.c50
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test13/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test14/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test14/test14.c63
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test14/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test15/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test15/test15.c64
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test15/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test16/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test16/test16.c63
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test16/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test17/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test17/test17.c65
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test17/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test18/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test18/test18.c65
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test18/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test19/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test19/test19.c139
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test19/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test2/test2.c40
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test2/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test3/test3.c40
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test3/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test4/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test4/test4.c121
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test4/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test5/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test5/test5.c81
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test5/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test6/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test6/test6.c43
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test6/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test7/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test7/test7.c43
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test7/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test8/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test8/test8.c49
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test8/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test9/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test9/test9.c49
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf/test9/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/CMakeLists.txt21
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/_vsnwprintf_s.h133
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test1/test1.cpp60
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test1/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test10/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test10/test10.cpp50
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test10/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test11/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test11/test11.cpp50
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test11/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test12/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test12/test12.cpp50
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test12/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test13/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test13/test13.cpp50
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test13/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test14/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test14/test14.cpp63
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test14/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test15/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test15/test15.cpp64
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test15/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test16/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test16/test16.cpp63
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test16/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test17/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test17/test17.cpp65
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test17/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test18/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test18/test18.cpp65
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test18/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test19/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test19/test19.cpp139
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test19/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test2/test2.cpp40
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test2/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test3/test3.cpp40
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test3/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test4/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test4/test4.cpp121
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test4/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test6/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test6/test6.cpp43
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test6/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test7/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test7/test7.cpp43
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test7/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test8/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test8/test8.cpp49
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test8/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test9/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test9/test9.cpp49
-rw-r--r--src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test9/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wcsicmp/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wcsicmp/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/_wcsicmp/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wcslwr/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wcslwr/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/_wcslwr/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wcsnicmp/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wcsnicmp/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/_wcsnicmp/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wfopen/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wfopen/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/_wfopen/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wfopen/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wfopen/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/_wfopen/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wfopen/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wfopen/test3/test3.cpp (renamed from src/pal/tests/palsuite/c_runtime/_wfopen/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wfopen/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wfopen/test4/test4.cpp (renamed from src/pal/tests/palsuite/c_runtime/_wfopen/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wfopen/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wfopen/test5/test5.cpp (renamed from src/pal/tests/palsuite/c_runtime/_wfopen/test5/test5.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wfopen/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wfopen/test6/test6.cpp (renamed from src/pal/tests/palsuite/c_runtime/_wfopen/test6/test6.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wfopen/test7/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wfopen/test7/test7.cpp (renamed from src/pal/tests/palsuite/c_runtime/_wfopen/test7/test7.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wmakepath/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wmakepath/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wmakepath/test1/test1.c76
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wmakepath/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wsplitpath/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wsplitpath/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wsplitpath/test1/test1.c151
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wsplitpath/test1/testinfo.dat15
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wtoi/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/_wtoi/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/_wtoi/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/abs/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/abs/test1/abs.cpp (renamed from src/pal/tests/palsuite/c_runtime/abs/test1/abs.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/acos/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/acos/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/acos/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/acosf/CMakeLists.txt3
-rw-r--r--src/pal/tests/palsuite/c_runtime/acosf/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/acosf/test1/test1.c129
-rw-r--r--src/pal/tests/palsuite/c_runtime/acosf/test1/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/asin/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/asin/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/asin/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/asinf/CMakeLists.txt3
-rw-r--r--src/pal/tests/palsuite/c_runtime/asinf/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/asinf/test1/test1.c145
-rw-r--r--src/pal/tests/palsuite/c_runtime/asinf/test1/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/atan/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/atan/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/atan/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/atan2/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/atan2/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/atan2/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/atan2f/CMakeLists.txt3
-rw-r--r--src/pal/tests/palsuite/c_runtime/atan2f/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/atan2f/test1/test1.c147
-rw-r--r--src/pal/tests/palsuite/c_runtime/atan2f/test1/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/atanf/CMakeLists.txt3
-rw-r--r--src/pal/tests/palsuite/c_runtime/atanf/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/atanf/test1/test1.c127
-rw-r--r--src/pal/tests/palsuite/c_runtime/atanf/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/c_runtime/atof/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/atof/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/atof/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/atoi/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/atoi/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/atoi/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/atol/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/atol/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/atol/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/bsearch/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/bsearch/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/bsearch/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/bsearch/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/bsearch/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/bsearch/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/ceil/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/ceil/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/ceil/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/ceilf/CMakeLists.txt3
-rw-r--r--src/pal/tests/palsuite/c_runtime/ceilf/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/ceilf/test1/test1.c131
-rw-r--r--src/pal/tests/palsuite/c_runtime/ceilf/test1/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/cos/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/cos/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/cos/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/cosf/CMakeLists.txt3
-rw-r--r--src/pal/tests/palsuite/c_runtime/cosf/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/cosf/test1/test1.c130
-rw-r--r--src/pal/tests/palsuite/c_runtime/cosf/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/c_runtime/cosh/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/cosh/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/cosh/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/coshf/CMakeLists.txt3
-rw-r--r--src/pal/tests/palsuite/c_runtime/coshf/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/coshf/test1/test1.c129
-rw-r--r--src/pal/tests/palsuite/c_runtime/coshf/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/c_runtime/ctime/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/ctime/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/ctime/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/errno/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/errno/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/errno/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/errno/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/errno/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/errno/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/exit/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/exit/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/exit/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/exit/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/exit/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/exit/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/exp/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/exp/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/exp/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/expf/CMakeLists.txt3
-rw-r--r--src/pal/tests/palsuite/c_runtime/expf/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/expf/test1/test1.c137
-rw-r--r--src/pal/tests/palsuite/c_runtime/expf/test1/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/fabs/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fabs/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/fabs/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fabsf/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fabsf/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/fabsf/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fclose/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fclose/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/fclose/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fclose/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fclose/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/fclose/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/feof/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/feof/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/feof/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/ferror/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/ferror/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/ferror/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/ferror/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/ferror/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/ferror/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fflush/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fflush/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/fflush/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fgets/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fgets/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/fgets/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fgets/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fgets/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/fgets/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fgets/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fgets/test3/test3.cpp (renamed from src/pal/tests/palsuite/c_runtime/fgets/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/floor/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/floor/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/floor/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/floorf/CMakeLists.txt3
-rw-r--r--src/pal/tests/palsuite/c_runtime/floorf/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/floorf/test1/test1.c131
-rw-r--r--src/pal/tests/palsuite/c_runtime/floorf/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/c_runtime/fmod/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fmod/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/fmod/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fmodf/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fmodf/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/fmodf/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fopen/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fopen/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/fopen/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fopen/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fopen/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/fopen/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fopen/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fopen/test3/test3.cpp (renamed from src/pal/tests/palsuite/c_runtime/fopen/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fopen/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fopen/test4/test4.cpp (renamed from src/pal/tests/palsuite/c_runtime/fopen/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fopen/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fopen/test5/test5.cpp (renamed from src/pal/tests/palsuite/c_runtime/fopen/test5/test5.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fopen/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fopen/test6/test6.cpp (renamed from src/pal/tests/palsuite/c_runtime/fopen/test6/test6.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fopen/test7/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fopen/test7/test7.cpp (renamed from src/pal/tests/palsuite/c_runtime/fopen/test7/test7.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/fprintf.h14
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/fprintf/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test10/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test10/test10.cpp (renamed from src/pal/tests/palsuite/c_runtime/fprintf/test10/test10.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test11/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test11/test11.cpp (renamed from src/pal/tests/palsuite/c_runtime/fprintf/test11/test11.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test12/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test12/test12.cpp (renamed from src/pal/tests/palsuite/c_runtime/fprintf/test12/test12.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test13/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test13/test13.cpp (renamed from src/pal/tests/palsuite/c_runtime/fprintf/test13/test13.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test14/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test14/test14.cpp (renamed from src/pal/tests/palsuite/c_runtime/fprintf/test14/test14.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test15/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test15/test15.cpp (renamed from src/pal/tests/palsuite/c_runtime/fprintf/test15/test15.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test16/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test16/test16.cpp (renamed from src/pal/tests/palsuite/c_runtime/fprintf/test16/test16.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test17/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test17/test17.cpp (renamed from src/pal/tests/palsuite/c_runtime/fprintf/test17/test17.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test18/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test18/test18.cpp (renamed from src/pal/tests/palsuite/c_runtime/fprintf/test18/test18.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test19/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test19/test19.cpp (renamed from src/pal/tests/palsuite/c_runtime/fprintf/test19/test19.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/fprintf/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test3/test3.cpp (renamed from src/pal/tests/palsuite/c_runtime/fprintf/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test4/test4.cpp (renamed from src/pal/tests/palsuite/c_runtime/fprintf/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test5/test5.cpp (renamed from src/pal/tests/palsuite/c_runtime/fprintf/test5/test5.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test6/test6.cpp (renamed from src/pal/tests/palsuite/c_runtime/fprintf/test6/test6.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test7/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test7/test7.cpp (renamed from src/pal/tests/palsuite/c_runtime/fprintf/test7/test7.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test8/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test8/test8.cpp (renamed from src/pal/tests/palsuite/c_runtime/fprintf/test8/test8.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test9/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fprintf/test9/test9.cpp (renamed from src/pal/tests/palsuite/c_runtime/fprintf/test9/test9.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fputs/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fputs/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/fputs/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fputs/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fputs/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/fputs/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fread/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fread/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/fread/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fread/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fread/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/fread/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fread/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fread/test3/test3.cpp (renamed from src/pal/tests/palsuite/c_runtime/fread/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/free/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/free/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/free/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fseek/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fseek/test1/test1.c193
-rw-r--r--src/pal/tests/palsuite/c_runtime/fseek/test1/test1.cpp193
-rw-r--r--src/pal/tests/palsuite/c_runtime/ftell/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/ftell/test1/ftell.cpp (renamed from src/pal/tests/palsuite/c_runtime/ftell/test1/ftell.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/fwprintf.h34
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/fwprintf/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test10/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test10/test10.cpp (renamed from src/pal/tests/palsuite/c_runtime/fwprintf/test10/test10.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test11/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test11/test11.cpp (renamed from src/pal/tests/palsuite/c_runtime/fwprintf/test11/test11.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test12/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test12/test12.cpp (renamed from src/pal/tests/palsuite/c_runtime/fwprintf/test12/test12.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test13/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test13/test13.cpp (renamed from src/pal/tests/palsuite/c_runtime/fwprintf/test13/test13.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test14/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test14/test14.cpp (renamed from src/pal/tests/palsuite/c_runtime/fwprintf/test14/test14.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test15/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test15/test15.cpp (renamed from src/pal/tests/palsuite/c_runtime/fwprintf/test15/test15.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test16/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test16/test16.cpp (renamed from src/pal/tests/palsuite/c_runtime/fwprintf/test16/test16.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test17/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test17/test17.cpp (renamed from src/pal/tests/palsuite/c_runtime/fwprintf/test17/test17.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test18/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test18/test18.cpp (renamed from src/pal/tests/palsuite/c_runtime/fwprintf/test18/test18.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test19/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test19/test19.c81
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test19/test19.cpp81
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/fwprintf/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test3/test3.cpp (renamed from src/pal/tests/palsuite/c_runtime/fwprintf/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test4/test4.cpp (renamed from src/pal/tests/palsuite/c_runtime/fwprintf/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test5/test5.cpp (renamed from src/pal/tests/palsuite/c_runtime/fwprintf/test5/test5.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test6/test6.cpp (renamed from src/pal/tests/palsuite/c_runtime/fwprintf/test6/test6.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test7/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test7/test7.cpp (renamed from src/pal/tests/palsuite/c_runtime/fwprintf/test7/test7.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test8/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test8/test8.cpp (renamed from src/pal/tests/palsuite/c_runtime/fwprintf/test8/test8.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test9/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwprintf/test9/test9.cpp (renamed from src/pal/tests/palsuite/c_runtime/fwprintf/test9/test9.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwrite/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/fwrite/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/fwrite/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/getc/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/getc/test1/getc.cpp (renamed from src/pal/tests/palsuite/c_runtime/getc/test1/getc.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/getenv/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/getenv/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/getenv/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/getenv/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/getenv/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/getenv/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/getenv/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/getenv/test3/test3.cpp (renamed from src/pal/tests/palsuite/c_runtime/getenv/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/isalnum/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/isalnum/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/isalnum/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/isalpha/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/isalpha/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/isalpha/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/isdigit/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/isdigit/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/isdigit/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/islower/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/islower/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/islower/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/isprint/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/isprint/test1/isprint.cpp (renamed from src/pal/tests/palsuite/c_runtime/isprint/test1/isprint.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/isprint/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/isprint/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/isprint/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/isspace/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/isspace/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/isspace/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/isupper/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/isupper/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/isupper/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/iswdigit/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/iswdigit/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/iswdigit/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/iswprint/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/iswprint/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/iswprint/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/iswspace/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/iswspace/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/iswspace/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/iswupper/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/iswupper/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/iswupper/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/iswxdigit/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/iswxdigit/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/iswxdigit/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/isxdigit/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/isxdigit/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/isxdigit/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/labs/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/labs/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/labs/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/llabs/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/llabs/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/llabs/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/localtime/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/localtime/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/localtime/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/log/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/log/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/log/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/log10/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/log10/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/log10/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/log10f/CMakeLists.txt3
-rw-r--r--src/pal/tests/palsuite/c_runtime/log10f/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/log10f/test1/test1.c144
-rw-r--r--src/pal/tests/palsuite/c_runtime/log10f/test1/testinfo.dat17
-rw-r--r--src/pal/tests/palsuite/c_runtime/logf/CMakeLists.txt3
-rw-r--r--src/pal/tests/palsuite/c_runtime/logf/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/logf/test1/test1.c139
-rw-r--r--src/pal/tests/palsuite/c_runtime/logf/test1/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/c_runtime/malloc/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/malloc/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/malloc/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/malloc/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/malloc/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/malloc/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/memchr/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/memchr/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/memchr/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/memcmp/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/memcmp/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/memcmp/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/memcpy/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/memcpy/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/memcpy/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/memmove/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/memmove/test1/test1.c116
-rw-r--r--src/pal/tests/palsuite/c_runtime/memmove/test1/test1.cpp116
-rw-r--r--src/pal/tests/palsuite/c_runtime/memset/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/memset/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/memset/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/modf/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/modf/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/modf/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/modff/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/modff/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/modff/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/pow/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/pow/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/pow/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/powf/CMakeLists.txt3
-rw-r--r--src/pal/tests/palsuite/c_runtime/powf/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/powf/test1/test1.c229
-rw-r--r--src/pal/tests/palsuite/c_runtime/powf/test1/testinfo.dat17
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/printf.h34
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/printf/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test10/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test10/test10.cpp (renamed from src/pal/tests/palsuite/c_runtime/printf/test10/test10.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test11/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test11/test11.cpp (renamed from src/pal/tests/palsuite/c_runtime/printf/test11/test11.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test12/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test12/test12.cpp (renamed from src/pal/tests/palsuite/c_runtime/printf/test12/test12.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test13/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test13/test13.cpp (renamed from src/pal/tests/palsuite/c_runtime/printf/test13/test13.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test14/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test14/test14.cpp (renamed from src/pal/tests/palsuite/c_runtime/printf/test14/test14.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test15/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test15/test15.cpp (renamed from src/pal/tests/palsuite/c_runtime/printf/test15/test15.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test16/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test16/test16.cpp (renamed from src/pal/tests/palsuite/c_runtime/printf/test16/test16.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test17/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test17/test17.cpp (renamed from src/pal/tests/palsuite/c_runtime/printf/test17/test17.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test18/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test18/test18.cpp (renamed from src/pal/tests/palsuite/c_runtime/printf/test18/test18.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test19/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test19/test19.c76
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test19/test19.cpp76
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/printf/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test3/test3.cpp (renamed from src/pal/tests/palsuite/c_runtime/printf/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test4/test4.cpp (renamed from src/pal/tests/palsuite/c_runtime/printf/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test5/test5.cpp (renamed from src/pal/tests/palsuite/c_runtime/printf/test5/test5.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test6/test6.cpp (renamed from src/pal/tests/palsuite/c_runtime/printf/test6/test6.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test7/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test7/test7.cpp (renamed from src/pal/tests/palsuite/c_runtime/printf/test7/test7.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test8/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test8/test8.cpp (renamed from src/pal/tests/palsuite/c_runtime/printf/test8/test8.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test9/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/printf/test9/test9.cpp (renamed from src/pal/tests/palsuite/c_runtime/printf/test9/test9.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/qsort/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/qsort/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/qsort/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/qsort/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/qsort/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/qsort/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/rand_srand/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/rand_srand/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/rand_srand/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/realloc/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/realloc/test1/test1.c66
-rw-r--r--src/pal/tests/palsuite/c_runtime/realloc/test1/test1.cpp66
-rw-r--r--src/pal/tests/palsuite/c_runtime/sin/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/sin/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/sin/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/sinf/CMakeLists.txt3
-rw-r--r--src/pal/tests/palsuite/c_runtime/sinf/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sinf/test1/test1.c130
-rw-r--r--src/pal/tests/palsuite/c_runtime/sinf/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/c_runtime/sinh/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/sinh/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/sinh/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/sinhf/CMakeLists.txt3
-rw-r--r--src/pal/tests/palsuite/c_runtime/sinhf/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sinhf/test1/test1.c129
-rw-r--r--src/pal/tests/palsuite/c_runtime/sinhf/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/CMakeLists.txt22
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/sprintf.h195
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test1/test1.c45
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test1/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test10/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test10/test10.c55
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test10/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test11/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test11/test11.c55
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test11/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test12/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test12/test12.c56
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test12/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test13/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test13/test13.c56
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test13/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test14/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test14/test14.c53
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test14/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test15/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test15/test15.c53
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test15/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test16/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test16/test16.c52
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test16/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test17/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test17/test17.c54
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test17/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test18/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test18/test18.c53
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test18/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test19/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test19/test19.c78
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test19/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test2/test2.c47
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test2/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test3/test3.c47
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test3/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test4/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test4/test4.c69
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test4/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test5/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test5/test5.c62
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test5/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test6/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test6/test6.c50
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test6/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test7/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test7/test7.c49
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test7/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test8/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test8/test8.c55
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test8/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test9/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test9/test9.c55
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf/test9/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/CMakeLists.txt21
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/sprintf_s.h195
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test1/test1.cpp45
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test1/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test10/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test10/test10.cpp55
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test10/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test11/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test11/test11.cpp55
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test11/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test12/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test12/test12.cpp56
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test12/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test13/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test13/test13.cpp56
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test13/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test14/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test14/test14.cpp53
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test14/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test15/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test15/test15.cpp53
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test15/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test16/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test16/test16.cpp52
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test16/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test17/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test17/test17.cpp54
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test17/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test18/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test18/test18.cpp53
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test18/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test19/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test19/test19.cpp71
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test19/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test2/test2.cpp47
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test2/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test3/test3.cpp47
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test3/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test4/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test4/test4.cpp69
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test4/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test6/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test6/test6.cpp50
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test6/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test7/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test7/test7.cpp49
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test7/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test8/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test8/test8.cpp55
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test8/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test9/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test9/test9.cpp55
-rw-r--r--src/pal/tests/palsuite/c_runtime/sprintf_s/test9/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sqrt/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/sqrt/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/sqrt/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/sqrtf/CMakeLists.txt (renamed from src/pal/tests/palsuite/c_runtime/_makepath/CMakeLists.txt)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/sqrtf/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sqrtf/test1/test1.c122
-rw-r--r--src/pal/tests/palsuite/c_runtime/sqrtf/test1/testinfo.dat17
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/sscanf.h246
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test1/test1.c53
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test1/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test10/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test10/test10.c37
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test10/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test11/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test11/test11.c36
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test11/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test12/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test12/test12.c35
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test12/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test13/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test13/test13.c37
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test13/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test14/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test14/test14.c36
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test14/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test15/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test15/test15.c36
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test15/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test16/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test16/test16.c37
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test16/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test17/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test17/test17.c37
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test17/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test2/test2.c44
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test2/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test3/test3.c35
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test3/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test4/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test4/test4.c44
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test4/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test5/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test5/test5.c43
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test5/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test6/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test6/test6.c43
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test6/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test7/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test7/test7.c43
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test7/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test8/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test8/test8.c43
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test8/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test9/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test9/test9.c38
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf/test9/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/CMakeLists.txt (renamed from src/pal/tests/palsuite/c_runtime/sscanf/CMakeLists.txt)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/sscanf_s.h246
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test1/test1.cpp53
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test1/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test10/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test10/test10.cpp37
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test10/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test11/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test11/test11.cpp36
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test11/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test12/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test12/test12.cpp35
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test12/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test13/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test13/test13.cpp37
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test13/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test14/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test14/test14.cpp36
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test14/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test15/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test15/test15.cpp36
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test15/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test16/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test16/test16.cpp37
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test16/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test17/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test17/test17.cpp37
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test17/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test2/test2.cpp44
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test2/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test3/test3.cpp35
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test3/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test4/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test4/test4.cpp44
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test4/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test5/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test5/test5.cpp43
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test5/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test6/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test6/test6.cpp43
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test6/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test7/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test7/test7.cpp43
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test7/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test8/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test8/test8.cpp43
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test8/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test9/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test9/test9.cpp38
-rw-r--r--src/pal/tests/palsuite/c_runtime/sscanf_s/test9/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/c_runtime/strcat/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/strcat/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/strcat/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/strchr/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/strchr/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/strchr/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/strcmp/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/strcmp/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/strcmp/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/strcpy/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/strcpy/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/strcpy/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/strcspn/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/strcspn/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/strcspn/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/strlen/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/strlen/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/strlen/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/strncat/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/strncat/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/strncat/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/strncmp/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/strncmp/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/strncmp/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/strncpy/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/strncpy/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/strncpy/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/strpbrk/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/strpbrk/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/strpbrk/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/strrchr/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/strrchr/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/strrchr/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/strspn/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/strspn/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/strspn/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/strstr/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/strstr/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/strstr/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/strtod/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/strtod/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/strtod/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/strtod/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/strtod/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/strtod/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/strtok/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/strtok/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/strtok/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/strtoul/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/strtoul/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/strtoul/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/swprintf.h32
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/swprintf/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test10/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test10/test10.cpp (renamed from src/pal/tests/palsuite/c_runtime/swprintf/test10/test10.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test11/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test11/test11.cpp (renamed from src/pal/tests/palsuite/c_runtime/swprintf/test11/test11.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test12/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test12/test12.cpp (renamed from src/pal/tests/palsuite/c_runtime/swprintf/test12/test12.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test13/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test13/test13.cpp (renamed from src/pal/tests/palsuite/c_runtime/swprintf/test13/test13.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test14/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test14/test14.cpp (renamed from src/pal/tests/palsuite/c_runtime/swprintf/test14/test14.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test15/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test15/test15.cpp (renamed from src/pal/tests/palsuite/c_runtime/swprintf/test15/test15.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test16/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test16/test16.cpp (renamed from src/pal/tests/palsuite/c_runtime/swprintf/test16/test16.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test17/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test17/test17.cpp (renamed from src/pal/tests/palsuite/c_runtime/swprintf/test17/test17.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test18/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test18/test18.cpp (renamed from src/pal/tests/palsuite/c_runtime/swprintf/test18/test18.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test19/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test19/test19.c109
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test19/test19.cpp109
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/swprintf/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test3/test3.cpp (renamed from src/pal/tests/palsuite/c_runtime/swprintf/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test4/test4.cpp (renamed from src/pal/tests/palsuite/c_runtime/swprintf/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test5/test5.cpp (renamed from src/pal/tests/palsuite/c_runtime/swprintf/test5/test5.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test6/test6.cpp (renamed from src/pal/tests/palsuite/c_runtime/swprintf/test6/test6.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test7/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test7/test7.cpp (renamed from src/pal/tests/palsuite/c_runtime/swprintf/test7/test7.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test8/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test8/test8.cpp (renamed from src/pal/tests/palsuite/c_runtime/swprintf/test8/test8.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test9/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swprintf/test9/test9.cpp (renamed from src/pal/tests/palsuite/c_runtime/swprintf/test9/test9.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/swscanf.h22
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/swscanf/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test10/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test10/test10.cpp (renamed from src/pal/tests/palsuite/c_runtime/swscanf/test10/test10.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test11/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test11/test11.cpp (renamed from src/pal/tests/palsuite/c_runtime/swscanf/test11/test11.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test12/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test12/test12.cpp (renamed from src/pal/tests/palsuite/c_runtime/swscanf/test12/test12.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test13/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test13/test13.cpp (renamed from src/pal/tests/palsuite/c_runtime/swscanf/test13/test13.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test14/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test14/test14.cpp (renamed from src/pal/tests/palsuite/c_runtime/swscanf/test14/test14.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test15/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test15/test15.cpp (renamed from src/pal/tests/palsuite/c_runtime/swscanf/test15/test15.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test16/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test16/test16.cpp (renamed from src/pal/tests/palsuite/c_runtime/swscanf/test16/test16.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test17/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test17/test17.cpp (renamed from src/pal/tests/palsuite/c_runtime/swscanf/test17/test17.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/swscanf/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test3/test3.cpp (renamed from src/pal/tests/palsuite/c_runtime/swscanf/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test4/test4.cpp (renamed from src/pal/tests/palsuite/c_runtime/swscanf/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test5/test5.cpp (renamed from src/pal/tests/palsuite/c_runtime/swscanf/test5/test5.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test6/test6.cpp (renamed from src/pal/tests/palsuite/c_runtime/swscanf/test6/test6.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test7/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test7/test7.cpp (renamed from src/pal/tests/palsuite/c_runtime/swscanf/test7/test7.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test8/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test8/test8.cpp (renamed from src/pal/tests/palsuite/c_runtime/swscanf/test8/test8.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test9/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/swscanf/test9/test9.cpp (renamed from src/pal/tests/palsuite/c_runtime/swscanf/test9/test9.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/tan/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/tan/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/tan/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/tanf/CMakeLists.txt3
-rw-r--r--src/pal/tests/palsuite/c_runtime/tanf/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/tanf/test1/test1.c136
-rw-r--r--src/pal/tests/palsuite/c_runtime/tanf/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/c_runtime/tanh/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/tanh/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/tanh/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/tanhf/CMakeLists.txt3
-rw-r--r--src/pal/tests/palsuite/c_runtime/tanhf/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/c_runtime/tanhf/test1/test1.c129
-rw-r--r--src/pal/tests/palsuite/c_runtime/tanhf/test1/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/c_runtime/time/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/time/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/time/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/tolower/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/tolower/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/tolower/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/toupper/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/toupper/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/toupper/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/towlower/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/towlower/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/towlower/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/towupper/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/towupper/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/towupper/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/ungetc/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/ungetc/test1/ungetc.cpp (renamed from src/pal/tests/palsuite/c_runtime/ungetc/test1/ungetc.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/ungetc/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/ungetc/test2/ungetc.cpp (renamed from src/pal/tests/palsuite/c_runtime/ungetc/test2/ungetc.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/vfprintf/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test10/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test10/test10.cpp (renamed from src/pal/tests/palsuite/c_runtime/vfprintf/test10/test10.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test11/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test11/test11.cpp (renamed from src/pal/tests/palsuite/c_runtime/vfprintf/test11/test11.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test12/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test12/test12.cpp (renamed from src/pal/tests/palsuite/c_runtime/vfprintf/test12/test12.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test13/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test13/test13.cpp (renamed from src/pal/tests/palsuite/c_runtime/vfprintf/test13/test13.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test14/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test14/test14.cpp (renamed from src/pal/tests/palsuite/c_runtime/vfprintf/test14/test14.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test15/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test15/test15.cpp (renamed from src/pal/tests/palsuite/c_runtime/vfprintf/test15/test15.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test16/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test16/test16.cpp (renamed from src/pal/tests/palsuite/c_runtime/vfprintf/test16/test16.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test17/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test17/test17.cpp (renamed from src/pal/tests/palsuite/c_runtime/vfprintf/test17/test17.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test18/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test18/test18.cpp (renamed from src/pal/tests/palsuite/c_runtime/vfprintf/test18/test18.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test19/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test19/test19.c76
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test19/test19.cpp76
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/vfprintf/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test3/test3.cpp (renamed from src/pal/tests/palsuite/c_runtime/vfprintf/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test4/test4.cpp (renamed from src/pal/tests/palsuite/c_runtime/vfprintf/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test5/test5.cpp (renamed from src/pal/tests/palsuite/c_runtime/vfprintf/test5/test5.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test6/test6.cpp (renamed from src/pal/tests/palsuite/c_runtime/vfprintf/test6/test6.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test7/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test7/test7.cpp (renamed from src/pal/tests/palsuite/c_runtime/vfprintf/test7/test7.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test8/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test8/test8.cpp (renamed from src/pal/tests/palsuite/c_runtime/vfprintf/test8/test8.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test9/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/test9/test9.cpp (renamed from src/pal/tests/palsuite/c_runtime/vfprintf/test9/test9.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vfprintf/vfprintf.h34
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/vprintf/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test10/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test10/test10.cpp (renamed from src/pal/tests/palsuite/c_runtime/vprintf/test10/test10.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test11/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test11/test11.cpp (renamed from src/pal/tests/palsuite/c_runtime/vprintf/test11/test11.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test12/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test12/test12.cpp (renamed from src/pal/tests/palsuite/c_runtime/vprintf/test12/test12.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test13/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test13/test13.cpp (renamed from src/pal/tests/palsuite/c_runtime/vprintf/test13/test13.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test14/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test14/test14.cpp (renamed from src/pal/tests/palsuite/c_runtime/vprintf/test14/test14.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test15/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test15/test15.cpp (renamed from src/pal/tests/palsuite/c_runtime/vprintf/test15/test15.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test16/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test16/test16.cpp (renamed from src/pal/tests/palsuite/c_runtime/vprintf/test16/test16.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test17/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test17/test17.cpp (renamed from src/pal/tests/palsuite/c_runtime/vprintf/test17/test17.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test18/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test18/test18.cpp (renamed from src/pal/tests/palsuite/c_runtime/vprintf/test18/test18.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test19/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test19/test19.c76
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test19/test19.cpp76
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/vprintf/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test3/test3.cpp (renamed from src/pal/tests/palsuite/c_runtime/vprintf/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test4/test4.cpp (renamed from src/pal/tests/palsuite/c_runtime/vprintf/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test5/test5.cpp (renamed from src/pal/tests/palsuite/c_runtime/vprintf/test5/test5.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test6/test6.cpp (renamed from src/pal/tests/palsuite/c_runtime/vprintf/test6/test6.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test7/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test7/test7.cpp (renamed from src/pal/tests/palsuite/c_runtime/vprintf/test7/test7.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test8/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test8/test8.cpp (renamed from src/pal/tests/palsuite/c_runtime/vprintf/test8/test8.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test9/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/test9/test9.cpp (renamed from src/pal/tests/palsuite/c_runtime/vprintf/test9/test9.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vprintf/vprintf.h34
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/vsprintf/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test10/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test10/test10.cpp (renamed from src/pal/tests/palsuite/c_runtime/vsprintf/test10/test10.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test11/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test11/test11.cpp (renamed from src/pal/tests/palsuite/c_runtime/vsprintf/test11/test11.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test12/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test12/test12.cpp (renamed from src/pal/tests/palsuite/c_runtime/vsprintf/test12/test12.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test13/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test13/test13.cpp (renamed from src/pal/tests/palsuite/c_runtime/vsprintf/test13/test13.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test14/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test14/test14.cpp (renamed from src/pal/tests/palsuite/c_runtime/vsprintf/test14/test14.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test15/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test15/test15.cpp (renamed from src/pal/tests/palsuite/c_runtime/vsprintf/test15/test15.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test16/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test16/test16.cpp (renamed from src/pal/tests/palsuite/c_runtime/vsprintf/test16/test16.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test17/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test17/test17.cpp (renamed from src/pal/tests/palsuite/c_runtime/vsprintf/test17/test17.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test18/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test18/test18.cpp (renamed from src/pal/tests/palsuite/c_runtime/vsprintf/test18/test18.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test19/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test19/test19.c67
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test19/test19.cpp67
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/vsprintf/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test3/test3.cpp (renamed from src/pal/tests/palsuite/c_runtime/vsprintf/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test4/test4.cpp (renamed from src/pal/tests/palsuite/c_runtime/vsprintf/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test5/test5.cpp (renamed from src/pal/tests/palsuite/c_runtime/vsprintf/test5/test5.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test6/test6.cpp (renamed from src/pal/tests/palsuite/c_runtime/vsprintf/test6/test6.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test7/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test7/test7.cpp (renamed from src/pal/tests/palsuite/c_runtime/vsprintf/test7/test7.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test8/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test8/test8.cpp (renamed from src/pal/tests/palsuite/c_runtime/vsprintf/test8/test8.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test9/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/test9/test9.cpp (renamed from src/pal/tests/palsuite/c_runtime/vsprintf/test9/test9.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vsprintf/vsprintf.h34
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/vswprintf/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test10/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test10/test10.cpp (renamed from src/pal/tests/palsuite/c_runtime/vswprintf/test10/test10.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test11/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test11/test11.cpp (renamed from src/pal/tests/palsuite/c_runtime/vswprintf/test11/test11.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test12/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test12/test12.cpp (renamed from src/pal/tests/palsuite/c_runtime/vswprintf/test12/test12.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test13/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test13/test13.cpp (renamed from src/pal/tests/palsuite/c_runtime/vswprintf/test13/test13.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test14/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test14/test14.cpp (renamed from src/pal/tests/palsuite/c_runtime/vswprintf/test14/test14.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test15/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test15/test15.cpp (renamed from src/pal/tests/palsuite/c_runtime/vswprintf/test15/test15.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test16/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test16/test16.cpp (renamed from src/pal/tests/palsuite/c_runtime/vswprintf/test16/test16.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test17/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test17/test17.cpp (renamed from src/pal/tests/palsuite/c_runtime/vswprintf/test17/test17.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test18/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test18/test18.cpp (renamed from src/pal/tests/palsuite/c_runtime/vswprintf/test18/test18.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test19/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test19/test19.c137
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test19/test19.cpp137
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/vswprintf/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test3/test3.cpp (renamed from src/pal/tests/palsuite/c_runtime/vswprintf/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test4/test4.cpp (renamed from src/pal/tests/palsuite/c_runtime/vswprintf/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test5/test5.cpp (renamed from src/pal/tests/palsuite/c_runtime/vswprintf/test5/test5.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test6/test6.cpp (renamed from src/pal/tests/palsuite/c_runtime/vswprintf/test6/test6.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test7/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test7/test7.cpp (renamed from src/pal/tests/palsuite/c_runtime/vswprintf/test7/test7.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test8/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test8/test8.cpp (renamed from src/pal/tests/palsuite/c_runtime/vswprintf/test8/test8.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test9/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/test9/test9.cpp (renamed from src/pal/tests/palsuite/c_runtime/vswprintf/test9/test9.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/vswprintf/vswprintf.h14
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcscat/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcscat/test1/test1.c71
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcscat/test1/test1.cpp71
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcschr/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcschr/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/wcschr/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcscmp/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcscmp/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/wcscmp/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcscpy/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcscpy/test1/test1.c47
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcscpy/test1/test1.cpp47
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcslen/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcslen/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/wcslen/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcsncat/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcsncat/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/wcsncat/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcsncmp/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcsncmp/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/wcsncmp/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcsncpy/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcsncpy/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/wcsncpy/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcspbrk/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcspbrk/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/wcspbrk/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcsrchr/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcsrchr/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/wcsrchr/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcsstr/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcsstr/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/wcsstr/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstod/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstod/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/wcstod/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstod/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstod/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/wcstod/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstok/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstok/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/wcstok/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstol/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstol/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/wcstol/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstol/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstol/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/wcstol/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstol/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstol/test3/test3.cpp (renamed from src/pal/tests/palsuite/c_runtime/wcstol/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstol/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstol/test4/test4.cpp (renamed from src/pal/tests/palsuite/c_runtime/wcstol/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstol/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstol/test5/test5.cpp (renamed from src/pal/tests/palsuite/c_runtime/wcstol/test5/test5.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstol/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstol/test6/test6.cpp (renamed from src/pal/tests/palsuite/c_runtime/wcstol/test6/test6.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstoul/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstoul/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/wcstoul/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstoul/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstoul/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/wcstoul/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstoul/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstoul/test3/test3.cpp (renamed from src/pal/tests/palsuite/c_runtime/wcstoul/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstoul/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstoul/test4/test4.cpp (renamed from src/pal/tests/palsuite/c_runtime/wcstoul/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstoul/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstoul/test5/test5.cpp (renamed from src/pal/tests/palsuite/c_runtime/wcstoul/test5/test5.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstoul/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wcstoul/test6/test6.cpp (renamed from src/pal/tests/palsuite/c_runtime/wcstoul/test6/test6.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/wprintf/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wprintf/test1/test1.cpp (renamed from src/pal/tests/palsuite/c_runtime/wprintf/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/wprintf/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/c_runtime/wprintf/test2/test2.cpp (renamed from src/pal/tests/palsuite/c_runtime/wprintf/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/c_runtime/wprintf/wprintf.h32
-rw-r--r--src/pal/tests/palsuite/common/palsuite.h6
-rw-r--r--src/pal/tests/palsuite/composite/object_management/event/nonshared/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/composite/object_management/event/nonshared/event.cpp (renamed from src/pal/tests/palsuite/composite/object_management/event/nonshared/event.c)0
-rw-r--r--src/pal/tests/palsuite/composite/object_management/event/nonshared/main.cpp (renamed from src/pal/tests/palsuite/composite/object_management/event/nonshared/main.c)0
-rw-r--r--src/pal/tests/palsuite/composite/object_management/event/shared/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/composite/object_management/event/shared/event.cpp (renamed from src/pal/tests/palsuite/composite/object_management/event/shared/event.c)0
-rw-r--r--src/pal/tests/palsuite/composite/object_management/event/shared/main.cpp (renamed from src/pal/tests/palsuite/composite/object_management/event/shared/main.c)0
-rw-r--r--src/pal/tests/palsuite/composite/object_management/mutex/nonshared/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/composite/object_management/mutex/nonshared/main.cpp (renamed from src/pal/tests/palsuite/composite/object_management/mutex/nonshared/main.c)0
-rw-r--r--src/pal/tests/palsuite/composite/object_management/mutex/nonshared/mutex.cpp (renamed from src/pal/tests/palsuite/composite/object_management/mutex/nonshared/mutex.c)0
-rw-r--r--src/pal/tests/palsuite/composite/object_management/mutex/shared/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/composite/object_management/mutex/shared/main.cpp (renamed from src/pal/tests/palsuite/composite/object_management/mutex/shared/main.c)0
-rw-r--r--src/pal/tests/palsuite/composite/object_management/mutex/shared/mutex.cpp (renamed from src/pal/tests/palsuite/composite/object_management/mutex/shared/mutex.c)0
-rw-r--r--src/pal/tests/palsuite/composite/object_management/semaphore/nonshared/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/composite/object_management/semaphore/nonshared/main.cpp (renamed from src/pal/tests/palsuite/composite/object_management/semaphore/nonshared/main.c)0
-rw-r--r--src/pal/tests/palsuite/composite/object_management/semaphore/nonshared/semaphore.cpp (renamed from src/pal/tests/palsuite/composite/object_management/semaphore/nonshared/semaphore.c)0
-rw-r--r--src/pal/tests/palsuite/composite/object_management/semaphore/shared/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/composite/object_management/semaphore/shared/main.cpp (renamed from src/pal/tests/palsuite/composite/object_management/semaphore/shared/main.c)0
-rw-r--r--src/pal/tests/palsuite/composite/object_management/semaphore/shared/semaphore.cpp (renamed from src/pal/tests/palsuite/composite/object_management/semaphore/shared/semaphore.c)0
-rw-r--r--src/pal/tests/palsuite/composite/synchronization/criticalsection/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/composite/synchronization/criticalsection/criticalsection.cpp (renamed from src/pal/tests/palsuite/composite/synchronization/criticalsection/criticalsection.c)0
-rw-r--r--src/pal/tests/palsuite/composite/synchronization/criticalsection/mainWrapper.cpp (renamed from src/pal/tests/palsuite/composite/synchronization/criticalsection/mainWrapper.c)0
-rw-r--r--src/pal/tests/palsuite/composite/synchronization/nativecriticalsection/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/composite/synchronization/nativecriticalsection/pal_composite_native_cs.cpp (renamed from src/pal/tests/palsuite/composite/synchronization/nativecriticalsection/pal_composite_native_cs.c)0
-rw-r--r--src/pal/tests/palsuite/composite/synchronization/nativecs_interlocked/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/composite/synchronization/nativecs_interlocked/pal_composite_native_cs.cpp (renamed from src/pal/tests/palsuite/composite/synchronization/nativecs_interlocked/pal_composite_native_cs.c)0
-rw-r--r--src/pal/tests/palsuite/composite/threading/threadsuspension/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/composite/threading/threadsuspension/mainWrapper.cpp (renamed from src/pal/tests/palsuite/composite/threading/threadsuspension/mainWrapper.c)0
-rw-r--r--src/pal/tests/palsuite/composite/threading/threadsuspension/threadsuspension.cpp (renamed from src/pal/tests/palsuite/composite/threading/threadsuspension/threadsuspension.c)0
-rw-r--r--src/pal/tests/palsuite/composite/threading/threadsuspension_switchthread/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/composite/threading/threadsuspension_switchthread/mainWrapper.cpp (renamed from src/pal/tests/palsuite/composite/threading/threadsuspension_switchthread/mainWrapper.c)0
-rw-r--r--src/pal/tests/palsuite/composite/threading/threadsuspension_switchthread/threadsuspension.cpp (renamed from src/pal/tests/palsuite/composite/threading/threadsuspension_switchthread/threadsuspension.c)0
-rw-r--r--src/pal/tests/palsuite/composite/wfmo/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/composite/wfmo/main.cpp (renamed from src/pal/tests/palsuite/composite/wfmo/main.c)0
-rw-r--r--src/pal/tests/palsuite/composite/wfmo/mutex.cpp (renamed from src/pal/tests/palsuite/composite/wfmo/mutex.c)0
-rw-r--r--src/pal/tests/palsuite/debug_api/DebugBreak/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/debug_api/DebugBreak/test1/test1.cpp (renamed from src/pal/tests/palsuite/debug_api/DebugBreak/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/debug_api/OutputDebugStringA/test1/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/debug_api/OutputDebugStringA/test1/helper.cpp (renamed from src/pal/tests/palsuite/debug_api/OutputDebugStringA/test1/helper.c)0
-rw-r--r--src/pal/tests/palsuite/debug_api/OutputDebugStringA/test1/test1.cpp (renamed from src/pal/tests/palsuite/debug_api/OutputDebugStringA/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/debug_api/OutputDebugStringW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/debug_api/OutputDebugStringW/test1/test1.cpp (renamed from src/pal/tests/palsuite/debug_api/OutputDebugStringW/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/helper.c243
-rw-r--r--src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/helper.cpp243
-rw-r--r--src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/test1.c189
-rw-r--r--src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/test1.cpp189
-rw-r--r--src/pal/tests/palsuite/debug_api/WriteProcessMemory/test3/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/debug_api/WriteProcessMemory/test3/helper.cpp (renamed from src/pal/tests/palsuite/debug_api/WriteProcessMemory/test3/helper.c)0
-rw-r--r--src/pal/tests/palsuite/debug_api/WriteProcessMemory/test3/test3.c205
-rw-r--r--src/pal/tests/palsuite/debug_api/WriteProcessMemory/test3/test3.cpp205
-rw-r--r--src/pal/tests/palsuite/debug_api/WriteProcessMemory/test4/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/debug_api/WriteProcessMemory/test4/helper.cpp (renamed from src/pal/tests/palsuite/debug_api/WriteProcessMemory/test4/helper.c)0
-rw-r--r--src/pal/tests/palsuite/debug_api/WriteProcessMemory/test4/test4.cpp (renamed from src/pal/tests/palsuite/debug_api/WriteProcessMemory/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test1/PAL_EXCEPT_FILTER.cpp (renamed from src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test1/PAL_EXCEPT_FILTER.c)0
-rw-r--r--src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test2/pal_except_filter.cpp (renamed from src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test2/pal_except_filter.c)0
-rw-r--r--src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test3/pal_except_filter.cpp (renamed from src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test3/pal_except_filter.c)0
-rw-r--r--src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test1/PAL_EXCEPT_FILTER_EX.cpp (renamed from src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test1/PAL_EXCEPT_FILTER_EX.c)0
-rw-r--r--src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test2/pal_except_filter_ex.cpp (renamed from src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test2/pal_except_filter_ex.c)0
-rw-r--r--src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test3/pal_except_filter.cpp (renamed from src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test3/pal_except_filter.c)0
-rw-r--r--src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT/test1/PAL_TRY_EXCEPT.cpp (renamed from src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT/test1/PAL_TRY_EXCEPT.c)0
-rw-r--r--src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT/test2/PAL_TRY_EXCEPT.cpp (renamed from src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT/test2/PAL_TRY_EXCEPT.c)0
-rw-r--r--src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test1/PAL_TRY_EXCEPT_EX.cpp (renamed from src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test1/PAL_TRY_EXCEPT_EX.c)0
-rw-r--r--src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test2/PAL_TRY_EXCEPT_EX.cpp (renamed from src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test2/PAL_TRY_EXCEPT_EX.c)0
-rw-r--r--src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test3/PAL_TRY_EXCEPT_EX.cpp (renamed from src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test3/PAL_TRY_EXCEPT_EX.c)0
-rw-r--r--src/pal/tests/palsuite/exception_handling/PAL_TRY_LEAVE_FINALLY/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/exception_handling/PAL_TRY_LEAVE_FINALLY/test1/PAL_TRY_LEAVE_FINALLY.cpp (renamed from src/pal/tests/palsuite/exception_handling/PAL_TRY_LEAVE_FINALLY/test1/PAL_TRY_LEAVE_FINALLY.c)0
-rw-r--r--src/pal/tests/palsuite/exception_handling/SetUnhandledExceptionFilter/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/exception_handling/SetUnhandledExceptionFilter/test1/test1.cpp (renamed from src/pal/tests/palsuite/exception_handling/SetUnhandledExceptionFilter/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/exception_handling/pal_except/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/exception_handling/pal_except/test1/test1.cpp (renamed from src/pal/tests/palsuite/exception_handling/pal_except/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/exception_handling/pal_except/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/exception_handling/pal_except/test2/test2.cpp (renamed from src/pal/tests/palsuite/exception_handling/pal_except/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/exception_handling/pal_except/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/exception_handling/pal_except/test3/test3.cpp (renamed from src/pal/tests/palsuite/exception_handling/pal_except/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/exception_handling/pal_except/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/exception_handling/pal_except/test4/test4.cpp (renamed from src/pal/tests/palsuite/exception_handling/pal_except/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/exception_handling/pal_except/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/exception_handling/pal_except/test5/test5.cpp (renamed from src/pal/tests/palsuite/exception_handling/pal_except/test5/test5.c)0
-rw-r--r--src/pal/tests/palsuite/exception_handling/pal_except/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/exception_handling/pal_except/test6/test6.cpp (renamed from src/pal/tests/palsuite/exception_handling/pal_except/test6/test6.c)0
-rw-r--r--src/pal/tests/palsuite/exception_handling/pal_except/test7/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/exception_handling/pal_except/test7/test7.cpp (renamed from src/pal/tests/palsuite/exception_handling/pal_except/test7/test7.c)0
-rw-r--r--src/pal/tests/palsuite/exception_handling/pal_finally/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/exception_handling/pal_finally/test1/pal_finally.cpp (renamed from src/pal/tests/palsuite/exception_handling/pal_finally/test1/pal_finally.c)0
-rw-r--r--src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest1.cpp14
-rw-r--r--src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest2.cpp14
-rw-r--r--src/pal/tests/palsuite/file_io/AreFileApisANSI/test1/AreFileApisANSI.cpp (renamed from src/pal/tests/palsuite/file_io/AreFileApisANSI/test1/AreFileApisANSI.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/AreFileApisANSI/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/CompareFileTime/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/CompareFileTime/test1/CompareFileTime.cpp (renamed from src/pal/tests/palsuite/file_io/CompareFileTime/test1/CompareFileTime.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileA/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileA/test1/CopyFileA.cpp (renamed from src/pal/tests/palsuite/file_io/CopyFileA/test1/CopyFileA.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileA/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileA/test2/test2.cpp (renamed from src/pal/tests/palsuite/file_io/CopyFileA/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileA/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileA/test3/test3.cpp (renamed from src/pal/tests/palsuite/file_io/CopyFileA/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileA/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileA/test4/test4.cpp (renamed from src/pal/tests/palsuite/file_io/CopyFileA/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileW/test1/CopyFileW.cpp (renamed from src/pal/tests/palsuite/file_io/CopyFileW/test1/CopyFileW.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileW/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileW/test2/test2.cpp (renamed from src/pal/tests/palsuite/file_io/CopyFileW/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileW/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/CopyFileW/test3/test3.cpp (renamed from src/pal/tests/palsuite/file_io/CopyFileW/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/CreateDirectoryA/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/CreateDirectoryA/test1/CreateDirectoryA.c296
-rw-r--r--src/pal/tests/palsuite/file_io/CreateDirectoryA/test1/CreateDirectoryA.cpp296
-rw-r--r--src/pal/tests/palsuite/file_io/CreateDirectoryA/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/CreateDirectoryA/test2/createdirectorya.cpp (renamed from src/pal/tests/palsuite/file_io/CreateDirectoryA/test2/createdirectorya.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/CreateDirectoryW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/CreateDirectoryW/test1/CreateDirectoryW.c347
-rw-r--r--src/pal/tests/palsuite/file_io/CreateDirectoryW/test1/CreateDirectoryW.cpp347
-rw-r--r--src/pal/tests/palsuite/file_io/CreateDirectoryW/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/CreateDirectoryW/test2/createdirectoryw.cpp (renamed from src/pal/tests/palsuite/file_io/CreateDirectoryW/test2/createdirectoryw.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/CreateFileA/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/CreateFileA/test1/CreateFileA.c145
-rw-r--r--src/pal/tests/palsuite/file_io/CreateFileA/test1/CreateFileA.cpp145
-rw-r--r--src/pal/tests/palsuite/file_io/CreateFileW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/CreateFileW/test1/CreateFileW.c152
-rw-r--r--src/pal/tests/palsuite/file_io/CreateFileW/test1/CreateFileW.cpp152
-rw-r--r--src/pal/tests/palsuite/file_io/DeleteFileW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/DeleteFileW/test1/DeleteFileW.cpp (renamed from src/pal/tests/palsuite/file_io/DeleteFileW/test1/DeleteFileW.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/FILECanonicalizePath/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/FILECanonicalizePath/FILECanonicalizePath.c83
-rw-r--r--src/pal/tests/palsuite/file_io/FILECanonicalizePath/FILECanonicalizePath.cpp83
-rw-r--r--src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/test1/test1.cpp (renamed from src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/FindClose/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/FindClose/test1/FindClose.cpp (renamed from src/pal/tests/palsuite/file_io/FindClose/test1/FindClose.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/FindFirstFileA/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/FindFirstFileA/test1/FindFirstFileA.cpp (renamed from src/pal/tests/palsuite/file_io/FindFirstFileA/test1/FindFirstFileA.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/FindFirstFileW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/FindFirstFileW/test1/FindFirstFileW.cpp (renamed from src/pal/tests/palsuite/file_io/FindFirstFileW/test1/FindFirstFileW.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/FindNextFileA/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/FindNextFileA/test1/FindNextFileA.cpp (renamed from src/pal/tests/palsuite/file_io/FindNextFileA/test1/FindNextFileA.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/FindNextFileA/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/FindNextFileA/test2/findnextfilea.cpp (renamed from src/pal/tests/palsuite/file_io/FindNextFileA/test2/findnextfilea.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/FindNextFileW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/FindNextFileW/test1/FindNextFileW.cpp (renamed from src/pal/tests/palsuite/file_io/FindNextFileW/test1/FindNextFileW.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/FindNextFileW/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/FindNextFileW/test2/findnextfilew.cpp (renamed from src/pal/tests/palsuite/file_io/FindNextFileW/test2/findnextfilew.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/FlushFileBuffers/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/FlushFileBuffers/test1/FlushFileBuffers.cpp (renamed from src/pal/tests/palsuite/file_io/FlushFileBuffers/test1/FlushFileBuffers.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetConsoleCP/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetConsoleCP/test1/GetConsoleCP.cpp (renamed from src/pal/tests/palsuite/file_io/GetConsoleCP/test1/GetConsoleCP.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetConsoleOutputCP/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetConsoleOutputCP/test1/GetConsoleOutputCP.cpp (renamed from src/pal/tests/palsuite/file_io/GetConsoleOutputCP/test1/GetConsoleOutputCP.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/test1/GetCurrentDirectoryA.cpp (renamed from src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/test1/GetCurrentDirectoryA.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/test1/GetCurrentDirectoryW.cpp (renamed from src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/test1/GetCurrentDirectoryW.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test1/GetDiskFreeSpaceW.cpp (renamed from src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test1/GetDiskFreeSpaceW.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test2/getdiskfreespacew.cpp (renamed from src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test2/getdiskfreespacew.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/GetFileAttributesA.cpp (renamed from src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/GetFileAttributesA.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/test1.cpp (renamed from src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesExW/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesExW/test2/test2.cpp (renamed from src/pal/tests/palsuite/file_io/GetFileAttributesExW/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/GetFileAttributesW.cpp (renamed from src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/GetFileAttributesW.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileSize/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileSize/test1/GetFileSize.cpp (renamed from src/pal/tests/palsuite/file_io/GetFileSize/test1/GetFileSize.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileSizeEx/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileSizeEx/test1/GetFileSizeEx.cpp (renamed from src/pal/tests/palsuite/file_io/GetFileSizeEx/test1/GetFileSizeEx.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test1/GetFileTime.cpp (renamed from src/pal/tests/palsuite/file_io/GetFileTime/test1/GetFileTime.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test2/GetFileTime.cpp (renamed from src/pal/tests/palsuite/file_io/GetFileTime/test2/GetFileTime.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test3/GetFileTime.cpp (renamed from src/pal/tests/palsuite/file_io/GetFileTime/test3/GetFileTime.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test4/GetFileTime.cpp (renamed from src/pal/tests/palsuite/file_io/GetFileTime/test4/GetFileTime.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test5/getfiletime.cpp (renamed from src/pal/tests/palsuite/file_io/GetFileTime/test5/getfiletime.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test6/getfiletime.cpp (renamed from src/pal/tests/palsuite/file_io/GetFileTime/test6/getfiletime.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test7/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileTime/test7/getfiletime.cpp (renamed from src/pal/tests/palsuite/file_io/GetFileTime/test7/getfiletime.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileType/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileType/test1/GetFileType.cpp (renamed from src/pal/tests/palsuite/file_io/GetFileType/test1/GetFileType.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileType/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileType/test2/getfiletype.cpp (renamed from src/pal/tests/palsuite/file_io/GetFileType/test2/getfiletype.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileType/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFileType/test3/getfiletype.cpp (renamed from src/pal/tests/palsuite/file_io/GetFileType/test3/getfiletype.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameA/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameA/test1/GetFullPathNameA.cpp (renamed from src/pal/tests/palsuite/file_io/GetFullPathNameA/test1/GetFullPathNameA.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameA/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameA/test2/test2.cpp (renamed from src/pal/tests/palsuite/file_io/GetFullPathNameA/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameA/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameA/test3/test3.cpp (renamed from src/pal/tests/palsuite/file_io/GetFullPathNameA/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameA/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameA/test4/test4.cpp (renamed from src/pal/tests/palsuite/file_io/GetFullPathNameA/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameW/test1/GetFullPathNameW.cpp (renamed from src/pal/tests/palsuite/file_io/GetFullPathNameW/test1/GetFullPathNameW.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameW/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameW/test2/test2.cpp (renamed from src/pal/tests/palsuite/file_io/GetFullPathNameW/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameW/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameW/test3/test3.cpp (renamed from src/pal/tests/palsuite/file_io/GetFullPathNameW/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameW/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetFullPathNameW/test4/test4.cpp (renamed from src/pal/tests/palsuite/file_io/GetFullPathNameW/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetLongPathNameW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetLongPathNameW/test1/GetLongPathNameW.cpp (renamed from src/pal/tests/palsuite/file_io/GetLongPathNameW/test1/GetLongPathNameW.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetLongPathNameW/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetLongPathNameW/test2/getlongpathnamew.cpp (renamed from src/pal/tests/palsuite/file_io/GetLongPathNameW/test2/getlongpathnamew.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetStdHandle/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetStdHandle/test1/GetStdHandle.cpp (renamed from src/pal/tests/palsuite/file_io/GetStdHandle/test1/GetStdHandle.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetStdHandle/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetStdHandle/test2/GetStdHandle.cpp (renamed from src/pal/tests/palsuite/file_io/GetStdHandle/test2/GetStdHandle.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetSystemTime/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetSystemTime/test1/test.cpp (renamed from src/pal/tests/palsuite/file_io/GetSystemTime/test1/test.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/test1/GetSystemTimeAsFileTime.cpp (renamed from src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/test1/GetSystemTimeAsFileTime.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameA/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameA/test1/GetTempFileNameA.c125
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameA/test1/GetTempFileNameA.cpp125
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameA/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameA/test2/GetTempFileNameA.cpp (renamed from src/pal/tests/palsuite/file_io/GetTempFileNameA/test2/GetTempFileNameA.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameA/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameA/test3/gettempfilenamea.cpp (renamed from src/pal/tests/palsuite/file_io/GetTempFileNameA/test3/gettempfilenamea.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameW/test1/GetTempFileNameW.cpp (renamed from src/pal/tests/palsuite/file_io/GetTempFileNameW/test1/GetTempFileNameW.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameW/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameW/test2/GetTempFileNameW.cpp (renamed from src/pal/tests/palsuite/file_io/GetTempFileNameW/test2/GetTempFileNameW.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameW/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempFileNameW/test3/gettempfilenamew.cpp (renamed from src/pal/tests/palsuite/file_io/GetTempFileNameW/test3/gettempfilenamew.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempPathW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempPathW/test1/GetTempPathW.c103
-rw-r--r--src/pal/tests/palsuite/file_io/GetTempPathW/test1/GetTempPathW.cpp103
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileA/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileA/test1/MoveFileA.c469
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileA/test1/MoveFileA.cpp469
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileExA/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileExA/test1/MoveFileExA.cpp (renamed from src/pal/tests/palsuite/file_io/MoveFileExA/test1/MoveFileExA.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileExW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileExW/test1/MoveFileExW.cpp (renamed from src/pal/tests/palsuite/file_io/MoveFileExW/test1/MoveFileExW.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileW/test1/MoveFileW.c478
-rw-r--r--src/pal/tests/palsuite/file_io/MoveFileW/test1/MoveFileW.cpp478
-rw-r--r--src/pal/tests/palsuite/file_io/ReadFile/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/ReadFile/test1/ReadFile.cpp (renamed from src/pal/tests/palsuite/file_io/ReadFile/test1/ReadFile.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/ReadFile/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/ReadFile/test2/ReadFile.cpp (renamed from src/pal/tests/palsuite/file_io/ReadFile/test2/ReadFile.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/ReadFile/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/ReadFile/test3/ReadFile.cpp (renamed from src/pal/tests/palsuite/file_io/ReadFile/test3/ReadFile.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/ReadFile/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/ReadFile/test4/readfile.cpp (renamed from src/pal/tests/palsuite/file_io/ReadFile/test4/readfile.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/RemoveDirectoryA.cpp12
-rw-r--r--src/pal/tests/palsuite/file_io/RemoveDirectoryW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/RemoveDirectoryW/test1/RemoveDirectoryW.c282
-rw-r--r--src/pal/tests/palsuite/file_io/RemoveDirectoryW/test1/RemoveDirectoryW.cpp282
-rw-r--r--src/pal/tests/palsuite/file_io/SearchPathA/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SearchPathA/test1/SearchPathA.c144
-rw-r--r--src/pal/tests/palsuite/file_io/SearchPathA/test1/SearchPathA.cpp139
-rw-r--r--src/pal/tests/palsuite/file_io/SearchPathW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SearchPathW/test1/SearchPathW.c198
-rw-r--r--src/pal/tests/palsuite/file_io/SearchPathW/test1/SearchPathW.cpp193
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test1/SetCurrentDirectoryA.c215
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test1/SetCurrentDirectoryA.cpp215
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test2/setcurrentdirectorya.c142
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test2/setcurrentdirectorya.cpp142
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test3/setcurrentdirectorya.cpp (renamed from src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test3/setcurrentdirectorya.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test1/SetCurrentDirectoryW.c178
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test1/SetCurrentDirectoryW.cpp178
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test2/setcurrentdirectoryw.c147
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test2/setcurrentdirectoryw.cpp147
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test3/setcurrentdirectoryw.cpp (renamed from src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test3/setcurrentdirectoryw.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/SetEndOfFile/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetEndOfFile/test1/SetEndOfFile.cpp (renamed from src/pal/tests/palsuite/file_io/SetEndOfFile/test1/SetEndOfFile.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/SetEndOfFile/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetEndOfFile/test2/SetEndOfFile.cpp (renamed from src/pal/tests/palsuite/file_io/SetEndOfFile/test2/SetEndOfFile.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/SetEndOfFile/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetEndOfFile/test3/SetEndOfFile.cpp (renamed from src/pal/tests/palsuite/file_io/SetEndOfFile/test3/SetEndOfFile.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/SetEndOfFile/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetEndOfFile/test4/setendoffile.cpp (renamed from src/pal/tests/palsuite/file_io/SetEndOfFile/test4/setendoffile.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/SetEndOfFile/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetEndOfFile/test5/test5.cpp (renamed from src/pal/tests/palsuite/file_io/SetEndOfFile/test5/test5.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesA/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesA/test1/SetFileAttributesA.cpp (renamed from src/pal/tests/palsuite/file_io/SetFileAttributesA/test1/SetFileAttributesA.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/SetFileAttributesA.cpp (renamed from src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/SetFileAttributesA.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesA/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesA/test3/SetFileAttributesA.cpp (renamed from src/pal/tests/palsuite/file_io/SetFileAttributesA/test3/SetFileAttributesA.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesA/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesA/test4/SetFileAttributesA.cpp (renamed from src/pal/tests/palsuite/file_io/SetFileAttributesA/test4/SetFileAttributesA.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesW/test1/SetFileAttributesW.cpp (renamed from src/pal/tests/palsuite/file_io/SetFileAttributesW/test1/SetFileAttributesW.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/SetFileAttributesW.cpp (renamed from src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/SetFileAttributesW.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesW/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesW/test3/SetFileAttributesW.cpp (renamed from src/pal/tests/palsuite/file_io/SetFileAttributesW/test3/SetFileAttributesW.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesW/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileAttributesW/test4/SetFileAttributesW.cpp (renamed from src/pal/tests/palsuite/file_io/SetFileAttributesW/test4/SetFileAttributesW.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test1/SetFilePointer.cpp (renamed from src/pal/tests/palsuite/file_io/SetFilePointer/test1/SetFilePointer.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test2/SetFilePointer.cpp (renamed from src/pal/tests/palsuite/file_io/SetFilePointer/test2/SetFilePointer.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test3/SetFilePointer.cpp (renamed from src/pal/tests/palsuite/file_io/SetFilePointer/test3/SetFilePointer.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test4/SetFilePointer.cpp (renamed from src/pal/tests/palsuite/file_io/SetFilePointer/test4/SetFilePointer.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test5/SetFilePointer.cpp (renamed from src/pal/tests/palsuite/file_io/SetFilePointer/test5/SetFilePointer.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test6/SetFilePointer.cpp (renamed from src/pal/tests/palsuite/file_io/SetFilePointer/test6/SetFilePointer.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test7/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetFilePointer/test7/SetFilePointer.cpp (renamed from src/pal/tests/palsuite/file_io/SetFilePointer/test7/SetFilePointer.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileTime/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileTime/test1/SetFileTime.cpp (renamed from src/pal/tests/palsuite/file_io/SetFileTime/test1/SetFileTime.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileTime/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileTime/test2/SetFileTime.cpp (renamed from src/pal/tests/palsuite/file_io/SetFileTime/test2/SetFileTime.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileTime/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileTime/test3/SetFileTime.cpp (renamed from src/pal/tests/palsuite/file_io/SetFileTime/test3/SetFileTime.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileTime/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/SetFileTime/test4/SetFileTime.cpp (renamed from src/pal/tests/palsuite/file_io/SetFileTime/test4/SetFileTime.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/test1/WriteFile.cpp (renamed from src/pal/tests/palsuite/file_io/WriteFile/test1/WriteFile.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/test2/WriteFile.cpp (renamed from src/pal/tests/palsuite/file_io/WriteFile/test2/WriteFile.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/test3/WriteFile.cpp (renamed from src/pal/tests/palsuite/file_io/WriteFile/test3/WriteFile.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/test4/writefile.cpp (renamed from src/pal/tests/palsuite/file_io/WriteFile/test4/writefile.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/WriteFile/test5/writefile.cpp (renamed from src/pal/tests/palsuite/file_io/WriteFile/test5/writefile.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/errorpathnotfound/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/errorpathnotfound/test1/test1.cpp (renamed from src/pal/tests/palsuite/file_io/errorpathnotfound/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/errorpathnotfound/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/errorpathnotfound/test2/test2.cpp (renamed from src/pal/tests/palsuite/file_io/errorpathnotfound/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/errorpathnotfound/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/errorpathnotfound/test3/test3.cpp (renamed from src/pal/tests/palsuite/file_io/errorpathnotfound/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/errorpathnotfound/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/errorpathnotfound/test4/test4.cpp (renamed from src/pal/tests/palsuite/file_io/errorpathnotfound/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/file_io/gettemppatha/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/file_io/gettemppatha/test1/gettemppatha.cpp (renamed from src/pal/tests/palsuite/file_io/gettemppatha/test1/gettemppatha.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test1/CreateFileMapping.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test1/CreateFileMapping.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test3/CreateFileMapping.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test3/CreateFileMapping.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test4/CreateFileMapping.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test4/CreateFileMapping.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test5/CreateFileMapping.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test5/CreateFileMapping.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test6/CreateFileMapping.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test6/CreateFileMapping.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test7/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test7/createfilemapping.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test7/createfilemapping.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test8/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test8/createfilemapping.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test8/createfilemapping.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test9/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test9/createfilemapping.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test9/createfilemapping.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/CreateFileMapping_neg1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/CreateFileMapping_neg1/CreateFileMapping_neg.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/CreateFileMapping_neg1/CreateFileMapping_neg.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test1/CreateFileMappingW.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test1/CreateFileMappingW.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test2/CreateFileMappingW.c124
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test2/CreateFileMappingW.cpp124
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test3/CreateFileMappingW.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test3/CreateFileMappingW.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test4/CreateFileMappingW.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test4/CreateFileMappingW.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test5/CreateFileMappingW.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test5/CreateFileMappingW.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test6/CreateFileMappingW.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test6/CreateFileMappingW.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test7/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test7/createfilemapping.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test7/createfilemapping.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test8/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test8/createfilemapping.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test8/createfilemapping.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test9/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test9/createfilemapping.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test9/createfilemapping.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test1/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test1/FreeLibrary.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test1/FreeLibrary.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test1/dlltest.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test1/dlltest.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test2/test2.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/FreeLibraryAndExitThread/test1/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/FreeLibraryAndExitThread/test1/dlltest.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/FreeLibraryAndExitThread/test1/dlltest.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/FreeLibraryAndExitThread/test1/test1.c183
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/FreeLibraryAndExitThread/test1/test1.cpp183
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameA/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameA/test1/GetModuleFileNameA.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameA/test1/GetModuleFileNameA.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameA/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameA/test2/GetModuleFileNameA.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameA/test2/GetModuleFileNameA.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameW/test1/GetModuleFileNameW.c112
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameW/test1/GetModuleFileNameW.cpp112
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameW/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameW/test2/GetModuleFileNameW.c57
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameW/test2/GetModuleFileNameW.cpp57
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/test1.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/testlib.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/testlib.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test2/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test2/test2.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test2/testlib.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test2/testlib.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/GetProcessHeap/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/GetProcessHeap/test1/GetProcessHeap.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/GetProcessHeap/test1/GetProcessHeap.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test1/HeapAlloc.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test1/HeapAlloc.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test2/HeapAlloc.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test2/HeapAlloc.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test3/HeapAlloc.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test3/HeapAlloc.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/HeapFree/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/HeapFree/test1/HeapFree.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/HeapFree/test1/HeapFree.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test1/test1.c72
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test1/test1.cpp72
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test2/test2.c79
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test2/test2.cpp79
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test3/test3.c78
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test3/test3.cpp78
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test4/test4.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test5/test5.c69
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test5/test5.cpp69
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/LocalAlloc/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/LocalAlloc/test1/LocalAlloc.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/LocalAlloc/test1/LocalAlloc.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/LocalFree/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/LocalFree/test1/LocalFree.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/LocalFree/test1/LocalFree.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/LocalFree/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/LocalFree/test2/LocalFree.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/LocalFree/test2/LocalFree.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/LockFile/test1/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/LockFile/test1/helper.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/LockFile/test1/helper.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/LockFile/test1/test1.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/LockFile/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/LockFile/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/LockFile/test2/test2.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/LockFile/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/LockFile/test3/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/LockFile/test3/helper.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/LockFile/test3/helper.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/LockFile/test3/test3.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/LockFile/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/LockFile/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/LockFile/test4/test4.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/LockFile/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/LockFile/test5/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/LockFile/test5/helper.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/LockFile/test5/helper.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/LockFile/test5/test5.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/LockFile/test5/test5.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/LockFile/test6/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/LockFile/test6/helper.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/LockFile/test6/helper.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/LockFile/test6/test6.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/LockFile/test6/test6.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/LockFile/test7/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/LockFile/test7/test7.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/LockFile/test7/test7.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test1/MapViewOfFile.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test1/MapViewOfFile.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test2/MapViewOfFile.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test2/MapViewOfFile.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test3/MapViewOfFile.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test3/MapViewOfFile.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test4/mapviewoffile.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test4/mapviewoffile.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test5/mapviewoffile.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test5/mapviewoffile.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test6/mapviewoffile.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test6/mapviewoffile.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test1/OpenFileMappingA.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test1/OpenFileMappingA.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test2/OpenFileMappingA.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test2/OpenFileMappingA.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test3/OpenFileMappingA.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test3/OpenFileMappingA.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test1/OpenFileMappingW.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test1/OpenFileMappingW.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test2/OpenFileMappingW.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test2/OpenFileMappingW.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test3/OpenFileMappingW.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test3/OpenFileMappingW.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/CMakeLists.txt5
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/ProbeMemory_neg1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/ProbeMemory_neg1/ProbeMemory_neg.cpp95
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/ProbeMemory_neg1/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/test1/ProbeMemory.cpp94
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/test1/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/CMakeLists.txt6
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/ReadProcessMemory_neg1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/ReadProcessMemory_neg1/ReadProcessMemory_neg.c127
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/ReadProcessMemory_neg1/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test1/ReadProcessMemory.c126
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test1/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test2/CMakeLists.txt36
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test2/commonconsts.h48
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test2/helper.c249
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test2/test2.c258
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test2/testinfo.dat18
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test1/test1.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test3/test3.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test4/test4.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test5/test5.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test5/test5.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test1/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test1/helper.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test1/helper.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test1/test1.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test2/test2.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test3/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test3/helper.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test3/helper.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test3/test3.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test4/test4.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/UnmapViewOfFile/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/UnmapViewOfFile/test1/UnmapViewOfFile.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/UnmapViewOfFile/test1/UnmapViewOfFile.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/UnmapViewOfFile/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/UnmapViewOfFile/test2/unmapviewoffile.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/UnmapViewOfFile/test2/unmapviewoffile.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/CMakeLists.txt1
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test1/VirtualAlloc.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test1/VirtualAlloc.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test10/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test10/VirtualAlloc.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test10/VirtualAlloc.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test11/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test11/VirtualAlloc.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test11/VirtualAlloc.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test12/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test12/VirtualAlloc.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test12/VirtualAlloc.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test13/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test13/VirtualAlloc.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test13/VirtualAlloc.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test14/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test14/VirtualAlloc.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test14/VirtualAlloc.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test15/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test15/VirtualAlloc.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test15/VirtualAlloc.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test16/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test16/VirtualAlloc.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test16/VirtualAlloc.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test17/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test17/VirtualAlloc.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test17/VirtualAlloc.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test18/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test18/VirtualAlloc.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test18/VirtualAlloc.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test19/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test19/VirtualAlloc.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test19/VirtualAlloc.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test2/VirtualAlloc.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test2/VirtualAlloc.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test20/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test20/virtualalloc.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test20/virtualalloc.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test21/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test21/virtualalloc.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test21/virtualalloc.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test22/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test22/VirtualAlloc.cpp44
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test22/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test3/VirtualAlloc.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test3/VirtualAlloc.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test4/VirtualAlloc.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test4/VirtualAlloc.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test5/VirtualAlloc.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test5/VirtualAlloc.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test6/VirtualAlloc.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test6/VirtualAlloc.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test7/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test7/VirtualAlloc.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test7/VirtualAlloc.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test8/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test8/VirtualAlloc.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test8/VirtualAlloc.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test9/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test9/VirtualAlloc.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test9/VirtualAlloc.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test1/VirtualFree.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test1/VirtualFree.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test2/VirtualFree.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test2/VirtualFree.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test3/VirtualFree.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test3/VirtualFree.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test1/VirtualProtect.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test1/VirtualProtect.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test2/VirtualProtect.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test2/VirtualProtect.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test3/VirtualProtect.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test3/VirtualProtect.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test4/VirtualProtect.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test4/VirtualProtect.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test6/VirtualProtect.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test6/VirtualProtect.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test7/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test7/VirtualProtect.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test7/VirtualProtect.c)0
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualQuery/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/VirtualQuery/test1/VirtualQuery.cpp (renamed from src/pal/tests/palsuite/filemapping_memmgt/VirtualQuery/test1/VirtualQuery.c)0
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryA/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryA/test1/LoadLibraryA.cpp (renamed from src/pal/tests/palsuite/loader/LoadLibraryA/test1/LoadLibraryA.c)0
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryA/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryA/test2/LoadLibraryA.cpp (renamed from src/pal/tests/palsuite/loader/LoadLibraryA/test2/LoadLibraryA.c)0
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryA/test2/MyModule.cpp (renamed from src/pal/tests/palsuite/loader/LoadLibraryA/test2/MyModule.c)0
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryA/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryA/test3/loadlibrarya.cpp (renamed from src/pal/tests/palsuite/loader/LoadLibraryA/test3/loadlibrarya.c)0
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryA/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryA/test5/loadlibrarya.c67
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryA/test5/loadlibrarya.cpp67
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryA/test6/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryA/test6/dlltest.cpp (renamed from src/pal/tests/palsuite/loader/LoadLibraryA/test6/dlltest.c)0
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryA/test6/loadlibrarya.cpp (renamed from src/pal/tests/palsuite/loader/LoadLibraryA/test6/loadlibrarya.c)0
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryA/test7/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryA/test7/LoadLibraryA.cpp (renamed from src/pal/tests/palsuite/loader/LoadLibraryA/test7/LoadLibraryA.c)0
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryA/test8/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryA/test8/dlltest.cpp (renamed from src/pal/tests/palsuite/loader/LoadLibraryA/test8/dlltest.c)0
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryA/test8/loadlibrarya.cpp (renamed from src/pal/tests/palsuite/loader/LoadLibraryA/test8/loadlibrarya.c)0
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryW/test1/LoadLibraryW.cpp (renamed from src/pal/tests/palsuite/loader/LoadLibraryW/test1/LoadLibraryW.c)0
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryW/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryW/test2/loadlibraryw.cpp (renamed from src/pal/tests/palsuite/loader/LoadLibraryW/test2/loadlibraryw.c)0
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryW/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryW/test3/loadlibraryw.cpp (renamed from src/pal/tests/palsuite/loader/LoadLibraryW/test3/loadlibraryw.c)0
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryW/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryW/test5/loadlibraryw.c71
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryW/test5/loadlibraryw.cpp71
-rw-r--r--src/pal/tests/palsuite/locale_info/CompareStringA/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/CompareStringA/test1/test1.cpp (renamed from src/pal/tests/palsuite/locale_info/CompareStringA/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/CompareStringW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/CompareStringW/test1/test1.cpp (renamed from src/pal/tests/palsuite/locale_info/CompareStringW/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/GetACP/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/GetACP/test1/test1.cpp (renamed from src/pal/tests/palsuite/locale_info/GetACP/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/GetCPInfo/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/GetCPInfo/test1/test1.cpp (renamed from src/pal/tests/palsuite/locale_info/GetCPInfo/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/GetCPInfo/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/GetCPInfo/test2/test2.cpp (renamed from src/pal/tests/palsuite/locale_info/GetCPInfo/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/GetCPInfo/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/GetCPInfo/test3/test3.cpp (renamed from src/pal/tests/palsuite/locale_info/GetCPInfo/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/GetLocaleInfoW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/GetLocaleInfoW/test1/test1.cpp (renamed from src/pal/tests/palsuite/locale_info/GetLocaleInfoW/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/GetLocaleInfoW/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/GetLocaleInfoW/test2/test2.cpp (renamed from src/pal/tests/palsuite/locale_info/GetLocaleInfoW/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/GetStringTypeExW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/GetStringTypeExW/test1/test1.cpp (renamed from src/pal/tests/palsuite/locale_info/GetStringTypeExW/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/GetStringTypeExW/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/GetStringTypeExW/test2/test2.cpp (renamed from src/pal/tests/palsuite/locale_info/GetStringTypeExW/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/GetSystemDefaultLangID/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/GetSystemDefaultLangID/test1/test1.cpp (renamed from src/pal/tests/palsuite/locale_info/GetSystemDefaultLangID/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/GetThreadLocale/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/GetThreadLocale/test1/test1.cpp (renamed from src/pal/tests/palsuite/locale_info/GetThreadLocale/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/GetTimeZoneInformation/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/GetTimeZoneInformation/test1/test1.cpp (renamed from src/pal/tests/palsuite/locale_info/GetTimeZoneInformation/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/GetUserDefaultLCID/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/GetUserDefaultLCID/test1/test1.cpp (renamed from src/pal/tests/palsuite/locale_info/GetUserDefaultLCID/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/GetUserDefaultLangID/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/GetUserDefaultLangID/test1/test1.cpp (renamed from src/pal/tests/palsuite/locale_info/GetUserDefaultLangID/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/IsDBCSLeadByte/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/IsDBCSLeadByte/test1/test1.cpp (renamed from src/pal/tests/palsuite/locale_info/IsDBCSLeadByte/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/IsDBCSLeadByteEx/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/IsDBCSLeadByteEx/test1/test1.cpp (renamed from src/pal/tests/palsuite/locale_info/IsDBCSLeadByteEx/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/IsValidCodePage/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/IsValidCodePage/test1/test1.cpp (renamed from src/pal/tests/palsuite/locale_info/IsValidCodePage/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/IsValidCodePage/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/IsValidCodePage/test2/test2.cpp (renamed from src/pal/tests/palsuite/locale_info/IsValidCodePage/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/IsValidLocale/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/IsValidLocale/test1/test1.cpp (renamed from src/pal/tests/palsuite/locale_info/IsValidLocale/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test1/test1.cpp (renamed from src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test2/test2.cpp (renamed from src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test3/test3.cpp (renamed from src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/test4.c230
-rw-r--r--src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/test4.cpp230
-rw-r--r--src/pal/tests/palsuite/locale_info/SetThreadLocale/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/SetThreadLocale/test1/test1.cpp (renamed from src/pal/tests/palsuite/locale_info/SetThreadLocale/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/test1.cpp (renamed from src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/test2.cpp (renamed from src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/test3.cpp (renamed from src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test4/test4.cpp (renamed from src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/test5.c154
-rw-r--r--src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/test5.cpp154
-rw-r--r--src/pal/tests/palsuite/miscellaneous/CMakeLists.txt6
-rw-r--r--src/pal/tests/palsuite/miscellaneous/CharNextA/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/CharNextA/test1/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/CharNextA/test1/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/CharNextA/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/CharNextA/test2/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/CharNextA/test2/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/CharNextExA/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/CharNextExA/test1/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/CharNextExA/test1/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/CharNextExA/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/CharNextExA/test2/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/CharNextExA/test2/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/CloseHandle/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/CloseHandle/test1/test.c64
-rw-r--r--src/pal/tests/palsuite/miscellaneous/CloseHandle/test1/test.cpp64
-rw-r--r--src/pal/tests/palsuite/miscellaneous/CloseHandle/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/CloseHandle/test2/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/CloseHandle/test2/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/CreatePipe/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/CreatePipe/test1/test1.cpp (renamed from src/pal/tests/palsuite/miscellaneous/CreatePipe/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/FlushInstructionCache/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/FlushInstructionCache/test1/test1.cpp (renamed from src/pal/tests/palsuite/miscellaneous/FlushInstructionCache/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/FormatMessageW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/FormatMessageW/test1/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/FormatMessageW/test1/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/FormatMessageW/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/FormatMessageW/test2/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/FormatMessageW/test2/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/FormatMessageW/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/FormatMessageW/test3/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/FormatMessageW/test3/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/FormatMessageW/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/FormatMessageW/test4/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/FormatMessageW/test4/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/FormatMessageW/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/FormatMessageW/test5/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/FormatMessageW/test5/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/FormatMessageW/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/FormatMessageW/test6/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/FormatMessageW/test6/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/FreeEnvironmentStringsW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/FreeEnvironmentStringsW/test1/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/FreeEnvironmentStringsW/test1/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/FreeEnvironmentStringsW/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/FreeEnvironmentStringsW/test2/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/FreeEnvironmentStringsW/test2/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetCalendarInfoW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetCalendarInfoW/test1/GetCalendarInfoW.cpp (renamed from src/pal/tests/palsuite/miscellaneous/GetCalendarInfoW/test1/GetCalendarInfoW.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetCalendarInfoW/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetCalendarInfoW/test2/GetCalendarInfoW.cpp (renamed from src/pal/tests/palsuite/miscellaneous/GetCalendarInfoW/test2/GetCalendarInfoW.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetCommandLineW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetCommandLineW/test1/test.c71
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetCommandLineW/test1/test.cpp71
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetComputerNameW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetComputerNameW/test1/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/GetComputerNameW/test1/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetDateFormatW/GetDateFormatW_neg1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetDateFormatW/GetDateFormatW_neg1/GetDateFormatW_neg.c85
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetDateFormatW/GetDateFormatW_neg1/GetDateFormatW_neg.cpp85
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetDateFormatW/GetDateFormatW_neg2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetDateFormatW/GetDateFormatW_neg2/GetDateFormatW_neg.c98
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetDateFormatW/GetDateFormatW_neg2/GetDateFormatW_neg.cpp98
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetDateFormatW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetDateFormatW/test1/GetDateFormatW.c100
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetDateFormatW/test1/GetDateFormatW.cpp100
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentStringsW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentStringsW/test1/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/GetEnvironmentStringsW/test1/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test1/test.c84
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test1/test.cpp84
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test2/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test2/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test3/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test3/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test4/test.c75
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test4/test.cpp75
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test5/test5.c145
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test5/test5.cpp145
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test6/test6.c99
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test6/test6.cpp99
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test1/test.c79
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test1/test.cpp79
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test2/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test2/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test3/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test3/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test4/test.c63
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test4/test.cpp63
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test5/test5.c144
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test5/test5.cpp144
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test6/test6.c99
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test6/test6.cpp99
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetLastError/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetLastError/test1/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/GetLastError/test1/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetSystemInfo/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetSystemInfo/test1/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/GetSystemInfo/test1/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetTickCount/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetTickCount/test1/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/GetTickCount/test1/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetUserNameW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetUserNameW/test1/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/GetUserNameW/test1/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/IsBadCodePtr/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/IsBadCodePtr/test1/test1.cpp (renamed from src/pal/tests/palsuite/miscellaneous/IsBadCodePtr/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/IsBadReadPtr/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/IsBadReadPtr/test1/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/IsBadReadPtr/test1/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test1/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test1/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test2/test2.cpp (renamed from src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test3/test3.cpp (renamed from src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/MessageBoxW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/MessageBoxW/test1/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/MessageBoxW/test1/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/MessageBoxW/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/MessageBoxW/test2/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/MessageBoxW/test2/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test1/test1.cpp (renamed from src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test2/test2.cpp (renamed from src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test3/test3.c144
-rw-r--r--src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test3/test3.cpp144
-rw-r--r--src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test4/test4.c100
-rw-r--r--src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test4/test4.cpp100
-rw-r--r--src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test1/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test1/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test2/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test2/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test3/test3.c143
-rw-r--r--src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test3/test3.cpp143
-rw-r--r--src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test4/test4.c99
-rw-r--r--src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test4/test4.cpp99
-rw-r--r--src/pal/tests/palsuite/miscellaneous/SetLastError/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/SetLastError/test1/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/SetLastError/test1/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/_i64tow/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/_i64tow/test1/test1.c76
-rw-r--r--src/pal/tests/palsuite/miscellaneous/_i64tow/test1/test1.cpp76
-rw-r--r--src/pal/tests/palsuite/miscellaneous/_i64tow/test1/testinfo.dat6
-rw-r--r--src/pal/tests/palsuite/miscellaneous/_ui64tow/CMakeLists.txt5
-rw-r--r--src/pal/tests/palsuite/miscellaneous/_ui64tow/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/_ui64tow/test1/_ui64tow.c101
-rw-r--r--src/pal/tests/palsuite/miscellaneous/_ui64tow/test1/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/miscellaneous/_ui64tow/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/_ui64tow/test2/_ui64tow.c88
-rw-r--r--src/pal/tests/palsuite/miscellaneous/_ui64tow/test2/testinfo.dat13
-rw-r--r--src/pal/tests/palsuite/miscellaneous/lstrcatW/CMakeLists.txt7
-rw-r--r--src/pal/tests/palsuite/miscellaneous/lstrcatW/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/lstrcatW/test1/test.c59
-rw-r--r--src/pal/tests/palsuite/miscellaneous/lstrcatW/test1/testinfo.dat16
-rw-r--r--src/pal/tests/palsuite/miscellaneous/lstrcatW/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/lstrcatW/test2/test2.c53
-rw-r--r--src/pal/tests/palsuite/miscellaneous/lstrcatW/test2/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/miscellaneous/lstrcatW/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/lstrcatW/test3/test3.c46
-rw-r--r--src/pal/tests/palsuite/miscellaneous/lstrcatW/test3/testinfo.dat26
-rw-r--r--src/pal/tests/palsuite/miscellaneous/lstrcatW/test4/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/lstrcatW/test4/test4.c101
-rw-r--r--src/pal/tests/palsuite/miscellaneous/lstrcatW/test4/testinfo.dat28
-rw-r--r--src/pal/tests/palsuite/miscellaneous/lstrcpyW/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/miscellaneous/lstrcpyW/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/lstrcpyW/test1/test.c66
-rw-r--r--src/pal/tests/palsuite/miscellaneous/lstrcpyW/test1/testinfo.dat16
-rw-r--r--src/pal/tests/palsuite/miscellaneous/lstrcpynW/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/miscellaneous/lstrcpynW/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/lstrcpynW/test1/test.c73
-rw-r--r--src/pal/tests/palsuite/miscellaneous/lstrcpynW/test1/testinfo.dat16
-rw-r--r--src/pal/tests/palsuite/miscellaneous/lstrlenA/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/lstrlenA/test1/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/lstrlenA/test1/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/lstrlenW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/lstrlenW/test1/test.cpp (renamed from src/pal/tests/palsuite/miscellaneous/lstrlenW/test1/test.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/queryperformancecounter/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/queryperformancecounter/test1/test1.cpp (renamed from src/pal/tests/palsuite/miscellaneous/queryperformancecounter/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/queryperformancefrequency/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/queryperformancefrequency/test1/test1.cpp (renamed from src/pal/tests/palsuite/miscellaneous/queryperformancefrequency/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/CMakeLists.txt13
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test1/test.c58
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test1/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test11/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test11/test.c128
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test11/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test12/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test12/test.c119
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test12/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test13/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test13/test.c120
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test13/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test2/test.c123
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test2/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test3/test.c121
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test3/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test6/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test6/test.c114
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test6/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test7/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test7/test.c112
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test7/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test8/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test8/test.c120
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test8/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test9/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test9/test.c122
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfA/test9/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/CMakeLists.txt13
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test1/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test1/test.c64
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test1/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test11/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test11/test.c139
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test11/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test12/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test12/test.c128
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test12/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test13/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test13/test.c126
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test13/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test2/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test2/test.c108
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test2/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test3/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test3/test.c127
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test3/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test6/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test6/test.c115
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test6/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test7/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test7/test.c117
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test7/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test8/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test8/test.c128
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test8/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test9/CMakeLists.txt19
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test9/test.c128
-rw-r--r--src/pal/tests/palsuite/miscellaneous/wsprintfW/test9/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/pal_specific/PAL_GetPALDirectoryW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/pal_specific/PAL_GetPALDirectoryW/test1/PAL_GetPALDirectoryW.c78
-rw-r--r--src/pal/tests/palsuite/pal_specific/PAL_GetPALDirectoryW/test1/PAL_GetPALDirectoryW.cpp78
-rw-r--r--src/pal/tests/palsuite/pal_specific/PAL_GetUserTempDirectoryW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/pal_specific/PAL_GetUserTempDirectoryW/test1/PAL_GetUserTempDirectoryW.cpp (renamed from src/pal/tests/palsuite/pal_specific/PAL_GetUserTempDirectoryW/test1/PAL_GetUserTempDirectoryW.c)0
-rw-r--r--src/pal/tests/palsuite/pal_specific/PAL_Initialize_Terminate/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/pal_specific/PAL_Initialize_Terminate/test1/PAL_Initialize_Terminate.cpp (renamed from src/pal/tests/palsuite/pal_specific/PAL_Initialize_Terminate/test1/PAL_Initialize_Terminate.c)0
-rw-r--r--src/pal/tests/palsuite/pal_specific/PAL_Initialize_Terminate/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/pal_specific/PAL_Initialize_Terminate/test2/pal_initialize_twice.cpp (renamed from src/pal/tests/palsuite/pal_specific/PAL_Initialize_Terminate/test2/pal_initialize_twice.c)0
-rw-r--r--src/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test1/PAL_RegisterLibraryW_UnregisterLibraryW.c64
-rw-r--r--src/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test1/PAL_RegisterLibraryW_UnregisterLibraryW.cpp64
-rw-r--r--src/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test2_neg/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test2_neg/reg_unreg_libraryw_neg.c62
-rw-r--r--src/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test2_neg/reg_unreg_libraryw_neg.cpp62
-rw-r--r--src/pal/tests/palsuite/pal_specific/PAL_errno/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/pal_specific/PAL_errno/test1/PAL_errno.cpp (renamed from src/pal/tests/palsuite/pal_specific/PAL_errno/test1/PAL_errno.c)0
-rw-r--r--src/pal/tests/palsuite/pal_specific/PAL_get_stderr/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/pal_specific/PAL_get_stderr/test1/PAL_get_stderr.cpp (renamed from src/pal/tests/palsuite/pal_specific/PAL_get_stderr/test1/PAL_get_stderr.c)0
-rw-r--r--src/pal/tests/palsuite/pal_specific/PAL_get_stdin/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/pal_specific/PAL_get_stdin/test1/PAL_get_stdin.cpp (renamed from src/pal/tests/palsuite/pal_specific/PAL_get_stdin/test1/PAL_get_stdin.c)0
-rw-r--r--src/pal/tests/palsuite/pal_specific/PAL_get_stdout/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/pal_specific/PAL_get_stdout/test1/PAL_get_stdout.cpp (renamed from src/pal/tests/palsuite/pal_specific/PAL_get_stdout/test1/PAL_get_stdout.c)0
-rw-r--r--src/pal/tests/palsuite/pal_specific/pal_entrypoint/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/pal_specific/pal_entrypoint/test1/pal_entrypoint.cpp (renamed from src/pal/tests/palsuite/pal_specific/pal_entrypoint/test1/pal_entrypoint.c)0
-rw-r--r--src/pal/tests/palsuite/pal_specific/pal_initializedebug/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/pal_specific/pal_initializedebug/test1/pal_initializedebug.cpp (renamed from src/pal/tests/palsuite/pal_specific/pal_initializedebug/test1/pal_initializedebug.c)0
-rw-r--r--src/pal/tests/palsuite/paltestlist.txt226
-rw-r--r--src/pal/tests/palsuite/paltestlist_to_be_reviewed.txt9
-rw-r--r--src/pal/tests/palsuite/palverify.dat210
-rw-r--r--src/pal/tests/palsuite/samples/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/samples/test1/test.cpp (renamed from src/pal/tests/palsuite/samples/test1/test.c)0
-rw-r--r--src/pal/tests/palsuite/samples/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/samples/test2/test.cpp (renamed from src/pal/tests/palsuite/samples/test2/test.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CreateEventA/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CreateEventA/test1/test1.cpp (renamed from src/pal/tests/palsuite/threading/CreateEventA/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CreateEventA/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CreateEventA/test2/test2.cpp (renamed from src/pal/tests/palsuite/threading/CreateEventA/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CreateEventA/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CreateEventA/test3/test3.cpp (renamed from src/pal/tests/palsuite/threading/CreateEventA/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CreateEventW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CreateEventW/test1/test1.cpp (renamed from src/pal/tests/palsuite/threading/CreateEventW/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CreateEventW/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CreateEventW/test2/test2.cpp (renamed from src/pal/tests/palsuite/threading/CreateEventW/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CreateEventW/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CreateEventW/test3/test3.cpp (renamed from src/pal/tests/palsuite/threading/CreateEventW/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test1/CreateMutexA.cpp (renamed from src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test1/CreateMutexA.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test2/CreateMutexA.c331
-rw-r--r--src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test2/CreateMutexA.cpp331
-rw-r--r--src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test1/CreateMutexW.cpp (renamed from src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test1/CreateMutexW.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test2/CreateMutexW.cpp (renamed from src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test2/CreateMutexW.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CreateProcessA/test1/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/threading/CreateProcessA/test1/childProcess.cpp (renamed from src/pal/tests/palsuite/threading/CreateProcessA/test1/childProcess.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CreateProcessA/test1/parentProcess.cpp (renamed from src/pal/tests/palsuite/threading/CreateProcessA/test1/parentProcess.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CreateProcessA/test2/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/threading/CreateProcessA/test2/childprocess.cpp (renamed from src/pal/tests/palsuite/threading/CreateProcessA/test2/childprocess.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CreateProcessA/test2/parentprocess.cpp (renamed from src/pal/tests/palsuite/threading/CreateProcessA/test2/parentprocess.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CreateProcessW/test1/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/threading/CreateProcessW/test1/childProcess.c150
-rw-r--r--src/pal/tests/palsuite/threading/CreateProcessW/test1/childProcess.cpp150
-rw-r--r--src/pal/tests/palsuite/threading/CreateProcessW/test1/parentProcess.cpp (renamed from src/pal/tests/palsuite/threading/CreateProcessW/test1/parentProcess.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CreateProcessW/test2/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/threading/CreateProcessW/test2/childprocess.cpp (renamed from src/pal/tests/palsuite/threading/CreateProcessW/test2/childprocess.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CreateProcessW/test2/parentprocess.cpp (renamed from src/pal/tests/palsuite/threading/CreateProcessW/test2/parentprocess.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test1/CreateSemaphore.cpp (renamed from src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test1/CreateSemaphore.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test2/CreateSemaphore.cpp (renamed from src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test2/CreateSemaphore.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test3/createsemaphore.cpp (renamed from src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test3/createsemaphore.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test1/CreateSemaphore.cpp (renamed from src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test1/CreateSemaphore.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test2/CreateSemaphore.cpp (renamed from src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test2/CreateSemaphore.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test3/createsemaphore.cpp (renamed from src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test3/createsemaphore.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CreateThread/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CreateThread/test1/test1.c119
-rw-r--r--src/pal/tests/palsuite/threading/CreateThread/test1/test1.cpp119
-rw-r--r--src/pal/tests/palsuite/threading/CreateThread/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CreateThread/test2/test2.c184
-rw-r--r--src/pal/tests/palsuite/threading/CreateThread/test2/test2.cpp184
-rw-r--r--src/pal/tests/palsuite/threading/CreateThread/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CreateThread/test3/test3.cpp (renamed from src/pal/tests/palsuite/threading/CreateThread/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CriticalSectionFunctions/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CriticalSectionFunctions/test1/InitializeCriticalSection.cpp (renamed from src/pal/tests/palsuite/threading/CriticalSectionFunctions/test1/InitializeCriticalSection.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CriticalSectionFunctions/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CriticalSectionFunctions/test2/test2.cpp (renamed from src/pal/tests/palsuite/threading/CriticalSectionFunctions/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CriticalSectionFunctions/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CriticalSectionFunctions/test3/test3.cpp (renamed from src/pal/tests/palsuite/threading/CriticalSectionFunctions/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CriticalSectionFunctions/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CriticalSectionFunctions/test4/test4.cpp (renamed from src/pal/tests/palsuite/threading/CriticalSectionFunctions/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CriticalSectionFunctions/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CriticalSectionFunctions/test5/test5.cpp (renamed from src/pal/tests/palsuite/threading/CriticalSectionFunctions/test5/test5.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CriticalSectionFunctions/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CriticalSectionFunctions/test6/test6.cpp (renamed from src/pal/tests/palsuite/threading/CriticalSectionFunctions/test6/test6.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CriticalSectionFunctions/test7/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CriticalSectionFunctions/test7/test7.cpp (renamed from src/pal/tests/palsuite/threading/CriticalSectionFunctions/test7/test7.c)0
-rw-r--r--src/pal/tests/palsuite/threading/CriticalSectionFunctions/test8/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/CriticalSectionFunctions/test8/test8.cpp (renamed from src/pal/tests/palsuite/threading/CriticalSectionFunctions/test8/test8.c)0
-rw-r--r--src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test1/test1.cpp (renamed from src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test1/testlib.cpp (renamed from src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test1/testlib.c)0
-rw-r--r--src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/dllmain1.cpp (renamed from src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/dllmain1.c)0
-rw-r--r--src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/dllmain2.cpp (renamed from src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/dllmain2.c)0
-rw-r--r--src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/test2.cpp (renamed from src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/threading/DuplicateHandle/CMakeLists.txt1
-rw-r--r--src/pal/tests/palsuite/threading/DuplicateHandle/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/DuplicateHandle/test1/test1.cpp (renamed from src/pal/tests/palsuite/threading/DuplicateHandle/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/threading/DuplicateHandle/test10/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/DuplicateHandle/test10/test10.cpp (renamed from src/pal/tests/palsuite/threading/DuplicateHandle/test10/test10.c)0
-rw-r--r--src/pal/tests/palsuite/threading/DuplicateHandle/test11/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/threading/DuplicateHandle/test11/childprocess.cpp (renamed from src/pal/tests/palsuite/threading/DuplicateHandle/test11/childprocess.c)0
-rw-r--r--src/pal/tests/palsuite/threading/DuplicateHandle/test11/test11.cpp (renamed from src/pal/tests/palsuite/threading/DuplicateHandle/test11/test11.c)0
-rw-r--r--src/pal/tests/palsuite/threading/DuplicateHandle/test12/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/DuplicateHandle/test12/test12.cpp (renamed from src/pal/tests/palsuite/threading/DuplicateHandle/test12/test12.c)0
-rw-r--r--src/pal/tests/palsuite/threading/DuplicateHandle/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/DuplicateHandle/test2/test2.cpp (renamed from src/pal/tests/palsuite/threading/DuplicateHandle/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/threading/DuplicateHandle/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/DuplicateHandle/test3/test3.cpp (renamed from src/pal/tests/palsuite/threading/DuplicateHandle/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/threading/DuplicateHandle/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/DuplicateHandle/test4/test4.cpp (renamed from src/pal/tests/palsuite/threading/DuplicateHandle/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/threading/DuplicateHandle/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/DuplicateHandle/test5/test5.cpp (renamed from src/pal/tests/palsuite/threading/DuplicateHandle/test5/test5.c)0
-rw-r--r--src/pal/tests/palsuite/threading/DuplicateHandle/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/DuplicateHandle/test6/test6.cpp (renamed from src/pal/tests/palsuite/threading/DuplicateHandle/test6/test6.c)0
-rw-r--r--src/pal/tests/palsuite/threading/DuplicateHandle/test7/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/DuplicateHandle/test7/test7.cpp (renamed from src/pal/tests/palsuite/threading/DuplicateHandle/test7/test7.c)0
-rw-r--r--src/pal/tests/palsuite/threading/DuplicateHandle/test8/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/DuplicateHandle/test8/test8.cpp (renamed from src/pal/tests/palsuite/threading/DuplicateHandle/test8/test8.c)0
-rw-r--r--src/pal/tests/palsuite/threading/DuplicateHandle/test9/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/DuplicateHandle/test9/test9.cpp (renamed from src/pal/tests/palsuite/threading/DuplicateHandle/test9/test9.c)0
-rw-r--r--src/pal/tests/palsuite/threading/ExitProcess/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/ExitProcess/test1/ExitProcess.cpp (renamed from src/pal/tests/palsuite/threading/ExitProcess/test1/ExitProcess.c)0
-rw-r--r--src/pal/tests/palsuite/threading/ExitProcess/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/ExitProcess/test2/test2.cpp (renamed from src/pal/tests/palsuite/threading/ExitProcess/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/threading/ExitProcess/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/ExitProcess/test3/test3.cpp (renamed from src/pal/tests/palsuite/threading/ExitProcess/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/threading/ExitThread/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/ExitThread/test1/test1.c114
-rw-r--r--src/pal/tests/palsuite/threading/ExitThread/test1/test1.cpp114
-rw-r--r--src/pal/tests/palsuite/threading/ExitThread/test2/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/threading/ExitThread/test2/childprocess.cpp (renamed from src/pal/tests/palsuite/threading/ExitThread/test2/childprocess.c)0
-rw-r--r--src/pal/tests/palsuite/threading/ExitThread/test2/test2.cpp (renamed from src/pal/tests/palsuite/threading/ExitThread/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/threading/ExitThread/test3/dllmain.cpp (renamed from src/pal/tests/palsuite/threading/ExitThread/test3/dllmain.c)0
-rw-r--r--src/pal/tests/palsuite/threading/ExitThread/test3/test3.cpp (renamed from src/pal/tests/palsuite/threading/ExitThread/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/threading/GetCurrentProcess/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/GetCurrentProcess/test1/process.cpp (renamed from src/pal/tests/palsuite/threading/GetCurrentProcess/test1/process.c)0
-rw-r--r--src/pal/tests/palsuite/threading/GetCurrentProcessId/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/GetCurrentProcessId/test1/processId.cpp (renamed from src/pal/tests/palsuite/threading/GetCurrentProcessId/test1/processId.c)0
-rw-r--r--src/pal/tests/palsuite/threading/GetCurrentThread/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/GetCurrentThread/test1/thread.cpp (renamed from src/pal/tests/palsuite/threading/GetCurrentThread/test1/thread.c)0
-rw-r--r--src/pal/tests/palsuite/threading/GetCurrentThread/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/GetCurrentThread/test2/test2.cpp (renamed from src/pal/tests/palsuite/threading/GetCurrentThread/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/threading/GetCurrentThreadId/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/GetCurrentThreadId/test1/threadId.cpp (renamed from src/pal/tests/palsuite/threading/GetCurrentThreadId/test1/threadId.c)0
-rw-r--r--src/pal/tests/palsuite/threading/GetExitCodeProcess/test1/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/threading/GetExitCodeProcess/test1/childProcess.cpp (renamed from src/pal/tests/palsuite/threading/GetExitCodeProcess/test1/childProcess.c)0
-rw-r--r--src/pal/tests/palsuite/threading/GetExitCodeProcess/test1/test1.cpp (renamed from src/pal/tests/palsuite/threading/GetExitCodeProcess/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/threading/GetProcessTimes/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/GetProcessTimes/test2/test2.c122
-rw-r--r--src/pal/tests/palsuite/threading/GetProcessTimes/test2/test2.cpp122
-rw-r--r--src/pal/tests/palsuite/threading/GetThreadTimes/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/GetThreadTimes/test1/test1.c102
-rw-r--r--src/pal/tests/palsuite/threading/GetThreadTimes/test1/test1.cpp102
-rw-r--r--src/pal/tests/palsuite/threading/NamedMutex/test1/namedmutex.cpp12
-rw-r--r--src/pal/tests/palsuite/threading/OpenEventW/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/OpenEventW/test1/test1.cpp (renamed from src/pal/tests/palsuite/threading/OpenEventW/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/threading/OpenEventW/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/OpenEventW/test2/test2.cpp (renamed from src/pal/tests/palsuite/threading/OpenEventW/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/threading/OpenEventW/test3/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/threading/OpenEventW/test3/childprocess.cpp (renamed from src/pal/tests/palsuite/threading/OpenEventW/test3/childprocess.c)0
-rw-r--r--src/pal/tests/palsuite/threading/OpenEventW/test3/test3.c187
-rw-r--r--src/pal/tests/palsuite/threading/OpenEventW/test3/test3.cpp187
-rw-r--r--src/pal/tests/palsuite/threading/OpenEventW/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/OpenEventW/test4/test4.cpp (renamed from src/pal/tests/palsuite/threading/OpenEventW/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/threading/OpenEventW/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/OpenEventW/test5/test5.cpp (renamed from src/pal/tests/palsuite/threading/OpenEventW/test5/test5.c)0
-rw-r--r--src/pal/tests/palsuite/threading/OpenProcess/test1/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/threading/OpenProcess/test1/childProcess.cpp (renamed from src/pal/tests/palsuite/threading/OpenProcess/test1/childProcess.c)0
-rw-r--r--src/pal/tests/palsuite/threading/OpenProcess/test1/test1.cpp (renamed from src/pal/tests/palsuite/threading/OpenProcess/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/threading/QueryThreadCycleTime/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/QueryThreadCycleTime/test1/test1.c98
-rw-r--r--src/pal/tests/palsuite/threading/QueryThreadCycleTime/test1/test1.cpp98
-rw-r--r--src/pal/tests/palsuite/threading/QueueUserAPC/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/QueueUserAPC/test1/test1.cpp (renamed from src/pal/tests/palsuite/threading/QueueUserAPC/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/threading/QueueUserAPC/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/QueueUserAPC/test2/test2.cpp (renamed from src/pal/tests/palsuite/threading/QueueUserAPC/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/threading/QueueUserAPC/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/QueueUserAPC/test3/test3.cpp (renamed from src/pal/tests/palsuite/threading/QueueUserAPC/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/threading/QueueUserAPC/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/QueueUserAPC/test4/test4.cpp (renamed from src/pal/tests/palsuite/threading/QueueUserAPC/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/threading/QueueUserAPC/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/QueueUserAPC/test5/test5.cpp (renamed from src/pal/tests/palsuite/threading/QueueUserAPC/test5/test5.c)0
-rw-r--r--src/pal/tests/palsuite/threading/QueueUserAPC/test6/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/QueueUserAPC/test6/test6.cpp (renamed from src/pal/tests/palsuite/threading/QueueUserAPC/test6/test6.c)0
-rw-r--r--src/pal/tests/palsuite/threading/QueueUserAPC/test7/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/QueueUserAPC/test7/test7.cpp (renamed from src/pal/tests/palsuite/threading/QueueUserAPC/test7/test7.c)0
-rw-r--r--src/pal/tests/palsuite/threading/ReleaseMutex/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/ReleaseMutex/test3/ReleaseMutex.cpp (renamed from src/pal/tests/palsuite/threading/ReleaseMutex/test3/ReleaseMutex.c)0
-rw-r--r--src/pal/tests/palsuite/threading/ResetEvent/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/ResetEvent/test1/test1.cpp (renamed from src/pal/tests/palsuite/threading/ResetEvent/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/threading/ResetEvent/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/ResetEvent/test2/test2.cpp (renamed from src/pal/tests/palsuite/threading/ResetEvent/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/threading/ResetEvent/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/ResetEvent/test3/test3.cpp (renamed from src/pal/tests/palsuite/threading/ResetEvent/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/threading/ResetEvent/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/ResetEvent/test4/test4.cpp (renamed from src/pal/tests/palsuite/threading/ResetEvent/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/threading/ResumeThread/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/ResumeThread/test1/test1.c141
-rw-r--r--src/pal/tests/palsuite/threading/ResumeThread/test1/test1.cpp141
-rw-r--r--src/pal/tests/palsuite/threading/SetErrorMode/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/SetErrorMode/test1/test1.cpp (renamed from src/pal/tests/palsuite/threading/SetErrorMode/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/threading/SetEvent/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/SetEvent/test1/test1.cpp (renamed from src/pal/tests/palsuite/threading/SetEvent/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/threading/SetEvent/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/SetEvent/test2/test2.cpp (renamed from src/pal/tests/palsuite/threading/SetEvent/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/threading/SetEvent/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/SetEvent/test3/test3.cpp (renamed from src/pal/tests/palsuite/threading/SetEvent/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/threading/SetEvent/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/SetEvent/test4/test4.cpp (renamed from src/pal/tests/palsuite/threading/SetEvent/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/threading/Sleep/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/Sleep/test1/Sleep.cpp (renamed from src/pal/tests/palsuite/threading/Sleep/test1/Sleep.c)0
-rw-r--r--src/pal/tests/palsuite/threading/Sleep/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/Sleep/test2/sleep.cpp (renamed from src/pal/tests/palsuite/threading/Sleep/test2/sleep.c)0
-rw-r--r--src/pal/tests/palsuite/threading/SleepEx/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/SleepEx/test1/test1.cpp (renamed from src/pal/tests/palsuite/threading/SleepEx/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/threading/SleepEx/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/SleepEx/test2/test2.cpp (renamed from src/pal/tests/palsuite/threading/SleepEx/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/threading/SwitchToThread/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/SwitchToThread/test1/test1.cpp (renamed from src/pal/tests/palsuite/threading/SwitchToThread/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/threading/TLS/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/TLS/test1/TLS.cpp (renamed from src/pal/tests/palsuite/threading/TLS/test1/TLS.c)0
-rw-r--r--src/pal/tests/palsuite/threading/TLS/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/TLS/test2/TLS.cpp (renamed from src/pal/tests/palsuite/threading/TLS/test2/TLS.c)0
-rw-r--r--src/pal/tests/palsuite/threading/TLS/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/TLS/test3/TLS.cpp (renamed from src/pal/tests/palsuite/threading/TLS/test3/TLS.c)0
-rw-r--r--src/pal/tests/palsuite/threading/TLS/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/TLS/test4/test4.cpp (renamed from src/pal/tests/palsuite/threading/TLS/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/threading/TLS/test5/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/TLS/test5/test5.cpp (renamed from src/pal/tests/palsuite/threading/TLS/test5/test5.c)0
-rw-r--r--src/pal/tests/palsuite/threading/TLS/test6_optimizedtls/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/TLS/test6_optimizedtls/test.cpp (renamed from src/pal/tests/palsuite/threading/TLS/test6_optimizedtls/test.c)0
-rw-r--r--src/pal/tests/palsuite/threading/TerminateProcess/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/TerminateProcess/test1/TerminateProcess.cpp (renamed from src/pal/tests/palsuite/threading/TerminateProcess/test1/TerminateProcess.c)0
-rw-r--r--src/pal/tests/palsuite/threading/ThreadPriority/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/ThreadPriority/test1/ThreadPriority.cpp (renamed from src/pal/tests/palsuite/threading/ThreadPriority/test1/ThreadPriority.c)0
-rw-r--r--src/pal/tests/palsuite/threading/WaitForMultipleObjects/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/WaitForMultipleObjects/test1/test1.cpp (renamed from src/pal/tests/palsuite/threading/WaitForMultipleObjects/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test1/test1.cpp (renamed from src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test2/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test2/test2.cpp (renamed from src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test2/test2.c)0
-rw-r--r--src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test3/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test3/test3.cpp (renamed from src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test3/test3.c)0
-rw-r--r--src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test4/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test4/test4.cpp (renamed from src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test4/test4.c)0
-rw-r--r--src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test5/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test5/helper.c122
-rw-r--r--src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test5/helper.cpp122
-rw-r--r--src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test5/test5.c506
-rw-r--r--src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test5/test5.cpp506
-rw-r--r--src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test6/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test6/child6.c211
-rw-r--r--src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test6/child6.cpp211
-rw-r--r--src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test6/test6.c709
-rw-r--r--src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test6/test6.cpp709
-rw-r--r--src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExMutexTest/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExMutexTest/WFSOExMutexTest.cpp (renamed from src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExMutexTest/WFSOExMutexTest.c)0
-rw-r--r--src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExSemaphoreTest/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExSemaphoreTest/WFSOExSemaphoreTest.cpp (renamed from src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExSemaphoreTest/WFSOExSemaphoreTest.c)0
-rw-r--r--src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExThreadTest/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExThreadTest/WFSOExThreadTest.cpp (renamed from src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExThreadTest/WFSOExThreadTest.c)0
-rw-r--r--src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOMutexTest/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOMutexTest/WFSOMutexTest.c184
-rw-r--r--src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOMutexTest/WFSOMutexTest.cpp184
-rw-r--r--src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOProcessTest/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOProcessTest/ChildProcess.cpp (renamed from src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOProcessTest/ChildProcess.c)0
-rw-r--r--src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOProcessTest/WFSOProcessTest.cpp (renamed from src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOProcessTest/WFSOProcessTest.c)0
-rw-r--r--src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOSemaphoreTest/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOSemaphoreTest/WFSOSemaphoreTest.c183
-rw-r--r--src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOSemaphoreTest/WFSOSemaphoreTest.cpp183
-rw-r--r--src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOThreadTest/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOThreadTest/WFSOThreadTest.c179
-rw-r--r--src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOThreadTest/WFSOThreadTest.cpp179
-rw-r--r--src/pal/tests/palsuite/threading/WaitForSingleObject/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/WaitForSingleObject/test1/test1.cpp (renamed from src/pal/tests/palsuite/threading/WaitForSingleObject/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/threading/YieldProcessor/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/YieldProcessor/test1/test1.cpp (renamed from src/pal/tests/palsuite/threading/YieldProcessor/test1/test1.c)0
-rw-r--r--src/pal/tests/palsuite/threading/releasesemaphore/test1/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/threading/releasesemaphore/test1/test.cpp (renamed from src/pal/tests/palsuite/threading/releasesemaphore/test1/test.c)0
-rwxr-xr-xsrc/pal/tools/gen-buildsys-clang.sh19
-rw-r--r--src/pal/tools/gen-buildsys-win.bat2
-rw-r--r--src/palrt/path.cpp23
-rw-r--r--src/palrt/urlpars.cpp6
-rw-r--r--src/publish.proj13
-rw-r--r--src/strongname/api/common.h4
-rw-r--r--src/syncAzure.proj7
-rw-r--r--src/tools/crossgen/crossgen.cpp15
-rw-r--r--src/utilcode/CMakeLists.txt2
-rw-r--r--src/utilcode/clrhost_nodependencies.cpp4
-rw-r--r--src/utilcode/debug.cpp20
-rw-r--r--src/utilcode/fstring.cpp12
-rw-r--r--src/utilcode/longfilepathwrappers.cpp4
-rw-r--r--src/utilcode/makepath.cpp2
-rw-r--r--src/utilcode/md5.cpp2
-rw-r--r--src/utilcode/opinfo.cpp5
-rw-r--r--src/utilcode/regutil.cpp3
-rw-r--r--src/utilcode/securitywrapper.cpp35
-rw-r--r--src/utilcode/splitpath.cpp4
-rw-r--r--src/utilcode/sstring.cpp4
-rw-r--r--src/utilcode/stacktrace.cpp4
-rw-r--r--src/utilcode/stresslog.cpp2
-rw-r--r--src/vm/CMakeLists.txt25
-rw-r--r--src/vm/amd64/CrtHelpers.asm734
-rw-r--r--src/vm/amd64/asmconstants.h4
-rw-r--r--src/vm/amd64/cgencpu.h6
-rw-r--r--src/vm/amd64/excepamd64.cpp2
-rw-r--r--src/vm/amd64/jitinterfaceamd64.cpp2
-rw-r--r--src/vm/amd64/umthunkstub.S2
-rw-r--r--src/vm/appdomain.cpp53
-rw-r--r--src/vm/appdomain.hpp14
-rw-r--r--src/vm/arm/asmconstants.h4
-rw-r--r--src/vm/arm/cgencpu.h6
-rw-r--r--src/vm/arm/stubs.cpp2
-rw-r--r--src/vm/assemblynative.cpp35
-rw-r--r--src/vm/assemblynative.hpp1
-rw-r--r--src/vm/assemblyspec.hpp14
-rw-r--r--src/vm/callhelpers.cpp88
-rw-r--r--src/vm/callingconvention.h4
-rw-r--r--src/vm/ceeload.cpp30
-rw-r--r--src/vm/ceeload.h22
-rw-r--r--src/vm/ceemain.cpp37
-rw-r--r--src/vm/cgensys.h11
-rw-r--r--src/vm/class.cpp4
-rw-r--r--src/vm/class.h5
-rw-r--r--src/vm/class.inl2
-rw-r--r--src/vm/classcompat.cpp2
-rw-r--r--src/vm/classnames.h3
-rw-r--r--src/vm/clrprivbinderwinrt.cpp11
-rw-r--r--src/vm/clsload.hpp2
-rw-r--r--src/vm/codeman.cpp158
-rw-r--r--src/vm/codeman.h46
-rw-r--r--src/vm/comdelegate.cpp128
-rw-r--r--src/vm/comdependenthandle.cpp21
-rw-r--r--src/vm/comdependenthandle.h2
-rw-r--r--src/vm/commemoryfailpoint.cpp2
-rw-r--r--src/vm/commethodrental.cpp4
-rw-r--r--src/vm/commodule.cpp3
-rw-r--r--src/vm/common.h2
-rw-r--r--src/vm/compile.cpp64
-rw-r--r--src/vm/compile.h2
-rw-r--r--src/vm/comsynchronizable.cpp6
-rw-r--r--src/vm/comthreadpool.cpp17
-rw-r--r--src/vm/comutilnative.cpp62
-rw-r--r--src/vm/constrainedexecutionregion.cpp5
-rw-r--r--src/vm/constrainedexecutionregion.h3
-rw-r--r--src/vm/corhost.cpp10
-rw-r--r--src/vm/crossgen/CMakeLists.txt7
-rw-r--r--src/vm/crossgen_mscorlib/mscorlib_crossgen.nativeproj7
-rw-r--r--src/vm/crossgencompile.cpp4
-rw-r--r--src/vm/crst.cpp4
-rw-r--r--src/vm/customattribute.cpp84
-rw-r--r--src/vm/dac/dacwks.targets1
-rw-r--r--src/vm/dataimage.cpp2
-rw-r--r--src/vm/debugdebugger.cpp42
-rw-r--r--src/vm/debughelp.cpp21
-rw-r--r--src/vm/dllimport.cpp22
-rw-r--r--src/vm/dllimportcallback.cpp26
-rw-r--r--src/vm/dllimportcallback.h16
-rw-r--r--src/vm/domainfile.cpp4
-rw-r--r--src/vm/dwreport.cpp2
-rw-r--r--src/vm/ecalllist.h113
-rw-r--r--src/vm/eedbginterfaceimpl.cpp4
-rw-r--r--src/vm/eepolicy.cpp2
-rw-r--r--src/vm/eetoprofinterfaceimpl.cpp164
-rw-r--r--src/vm/eetoprofinterfaceimpl.h15
-rw-r--r--src/vm/eetoprofinterfaceimpl.inl6
-rw-r--r--src/vm/eetwain.cpp209
-rw-r--r--src/vm/encee.cpp15
-rw-r--r--src/vm/eventtrace.cpp37
-rw-r--r--src/vm/eventtracepriv.h5
-rw-r--r--src/vm/excep.cpp95
-rw-r--r--src/vm/excep.h7
-rw-r--r--src/vm/exceptionhandling.cpp2
-rw-r--r--src/vm/exceptmacros.h2
-rw-r--r--src/vm/exinfo.cpp8
-rw-r--r--src/vm/exinfo.h2
-rw-r--r--src/vm/finalizerthread.cpp28
-rw-r--r--src/vm/frames.cpp2
-rw-r--r--src/vm/frames.h8
-rw-r--r--src/vm/frameworkexceptionloader.cpp2
-rw-r--r--src/vm/gc.h5
-rw-r--r--src/vm/gccover.cpp36
-rw-r--r--src/vm/gcenv.ee.cpp437
-rw-r--r--src/vm/gcenv.ee.h46
-rw-r--r--src/vm/gcenv.h2
-rw-r--r--src/vm/gcenv.os.cpp67
-rw-r--r--src/vm/gcheaputilities.cpp19
-rw-r--r--src/vm/gcheaputilities.h129
-rw-r--r--src/vm/gchelpers.cpp89
-rw-r--r--src/vm/gchost.cpp12
-rw-r--r--src/vm/gcinfodecoder.cpp197
-rw-r--r--src/vm/gcinterface.h5
-rw-r--r--src/vm/gcstress.h12
-rw-r--r--src/vm/gdbjit.cpp2054
-rw-r--r--src/vm/gdbjit.h386
-rw-r--r--src/vm/gdbjithelpers.h2
-rw-r--r--src/vm/hash.cpp4
-rw-r--r--src/vm/i386/RedirectedHandledJITCase.asm2
-rw-r--r--src/vm/i386/asmconstants.h18
-rw-r--r--src/vm/i386/asmhelpers.S1140
-rw-r--r--src/vm/i386/asmhelpers.asm28
-rw-r--r--src/vm/i386/cgencpu.h9
-rw-r--r--src/vm/i386/cgenx86.cpp79
-rw-r--r--src/vm/i386/excepcpu.h31
-rw-r--r--src/vm/i386/excepx86.cpp86
-rw-r--r--src/vm/i386/gmsasm.S28
-rw-r--r--src/vm/i386/gmsx86.cpp136
-rw-r--r--src/vm/i386/jithelp.S749
-rw-r--r--src/vm/i386/jithelp.asm30
-rw-r--r--src/vm/i386/jitinterfacex86.cpp18
-rw-r--r--src/vm/i386/stublinkerx86.cpp27
-rw-r--r--src/vm/i386/stublinkerx86.h19
-rw-r--r--src/vm/i386/umthunkstub.S177
-rw-r--r--src/vm/i386/unixstubs.cpp106
-rw-r--r--src/vm/i386/virtualcallstubcpu.hpp2
-rw-r--r--src/vm/ilmarshalers.cpp2
-rw-r--r--src/vm/ilstubcache.cpp2
-rw-r--r--src/vm/ilstubresolver.cpp10
-rw-r--r--src/vm/ilstubresolver.h6
-rw-r--r--src/vm/interoputil.cpp2
-rw-r--r--src/vm/interpreter.cpp27
-rw-r--r--src/vm/interpreter.h2
-rw-r--r--src/vm/jithelpers.cpp32
-rw-r--r--src/vm/jitinterface.cpp456
-rw-r--r--src/vm/jitinterface.h24
-rw-r--r--src/vm/jitinterfacegen.cpp2
-rw-r--r--src/vm/marshalnative.cpp2
-rw-r--r--src/vm/marshalnative.h2
-rw-r--r--src/vm/mdaassistants.cpp4
-rw-r--r--src/vm/memberload.cpp2
-rw-r--r--src/vm/message.cpp2
-rw-r--r--src/vm/metasig.h3
-rw-r--r--src/vm/method.cpp4
-rw-r--r--src/vm/method.hpp18
-rw-r--r--src/vm/methodtable.cpp8
-rw-r--r--src/vm/methodtablebuilder.cpp47
-rw-r--r--src/vm/methodtablebuilder.h1
-rw-r--r--src/vm/microsoft.comservices_i.c16
-rw-r--r--src/vm/mlinfo.cpp4
-rw-r--r--src/vm/mscorlib.h36
-rw-r--r--src/vm/multicorejitplayer.cpp2
-rw-r--r--src/vm/nativeoverlapped.cpp24
-rw-r--r--src/vm/nativeoverlapped.h3
-rw-r--r--src/vm/object.cpp32
-rw-r--r--src/vm/object.h25
-rw-r--r--src/vm/prestub.cpp66
-rw-r--r--src/vm/profattach.cpp2
-rw-r--r--src/vm/profilinghelper.cpp2
-rw-r--r--src/vm/proftoeeinterfaceimpl.cpp368
-rw-r--r--src/vm/proftoeeinterfaceimpl.h24
-rw-r--r--src/vm/rcwwalker.cpp4
-rw-r--r--src/vm/readytoruninfo.cpp82
-rw-r--r--src/vm/reflectioninvocation.cpp8
-rw-r--r--src/vm/reflectioninvocation.h6
-rw-r--r--src/vm/rejit.cpp11
-rw-r--r--src/vm/rexcep.h4
-rw-r--r--src/vm/runtimecallablewrapper.cpp7
-rw-r--r--src/vm/safehandle.cpp4
-rw-r--r--src/vm/securityattributes.cpp7
-rw-r--r--src/vm/securitydeclarativecache.cpp9
-rw-r--r--src/vm/securityprincipal.h4
-rw-r--r--src/vm/siginfo.cpp2
-rw-r--r--src/vm/stacksampler.cpp10
-rw-r--r--src/vm/stacksampler.h4
-rw-r--r--src/vm/stackwalk.cpp8
-rw-r--r--src/vm/stackwalk.h4
-rw-r--r--src/vm/stubcache.h2
-rw-r--r--src/vm/stubgen.cpp39
-rw-r--r--src/vm/stubgen.h2
-rw-r--r--src/vm/stubhelpers.cpp12
-rw-r--r--src/vm/syncblk.cpp16
-rw-r--r--src/vm/syncclean.cpp2
-rw-r--r--src/vm/testhookmgr.cpp2
-rw-r--r--src/vm/threadpoolrequest.cpp4
-rw-r--r--src/vm/threads.cpp133
-rw-r--r--src/vm/threads.h16
-rw-r--r--src/vm/threadsuspend.cpp70
-rw-r--r--src/vm/typeparse.cpp6
-rw-r--r--src/vm/typeparse.h7
-rw-r--r--src/vm/util.cpp40
-rw-r--r--src/vm/vars.cpp9
-rw-r--r--src/vm/vars.hpp11
-rw-r--r--src/vm/virtualcallstub.cpp2
-rw-r--r--src/vm/vm.settings7
-rw-r--r--src/vm/win32threadpool.cpp22
-rw-r--r--src/vm/win32threadpool.h8
-rw-r--r--src/vm/winrtredirector.h2
-rw-r--r--src/vm/wks/wks.targets1
-rw-r--r--src/zap/zapcode.cpp2
-rw-r--r--src/zap/zapheaders.cpp136
-rw-r--r--src/zap/zapheaders.h34
-rw-r--r--src/zap/zapimage.cpp51
-rw-r--r--src/zap/zapimage.h2
-rw-r--r--src/zap/zapinfo.cpp71
-rw-r--r--src/zap/zapinfo.h2
-rw-r--r--src/zap/zapmetadata.cpp4
-rw-r--r--src/zap/zapper.cpp69
-rw-r--r--src/zap/zapreadytorun.cpp3
-rw-r--r--sync.cmd5
-rw-r--r--tests/arm64/Tests.lst84
-rw-r--r--tests/build.proj1
-rw-r--r--tests/debugger_tests/ConfigFilesGenerators/ConfigTemplate.txt32
-rw-r--r--tests/debugger_tests/ConfigFilesGenerators/GenerateConfig.cmd53
-rw-r--r--tests/debugger_tests/ConfigFilesGenerators/GenerateConfig.sh65
-rw-r--r--tests/debugger_tests/ScriptGenerator/Program.csbin0 -> 8256 bytes
-rw-r--r--tests/debugger_tests/ScriptGenerator/project.jsonbin0 -> 1106 bytes
-rw-r--r--tests/debugger_tests/setup-debuggertests.cmd119
-rw-r--r--tests/debugger_tests/setup-debuggertests.shbin0 -> 6494 bytes
-rw-r--r--tests/dir.props3
-rw-r--r--tests/helix.targets78
-rw-r--r--tests/issues.targets65
-rw-r--r--tests/override.targets2
-rw-r--r--tests/publishdependency.targets189
-rw-r--r--tests/runtest.cmd58
-rw-r--r--tests/runtest.proj50
-rwxr-xr-xtests/runtest.sh72
-rwxr-xr-xtests/scripts/arm32_ci_script.sh66
-rw-r--r--tests/scripts/arm64_post_build.py311
-rw-r--r--tests/scripts/format.py46
-rwxr-xr-xtests/scripts/perf-prep.sh78
-rw-r--r--tests/scripts/project.json23
-rw-r--r--tests/scripts/run-xunit-perf.cmd52
-rwxr-xr-x[-rw-r--r--]tests/scripts/run-xunit-perf.sh70
-rwxr-xr-xtests/setup-runtime-dependencies.cmd2
-rwxr-xr-xtests/setup-runtime-dependencies.sh4
-rw-r--r--tests/src/CLRTest.Execute.Bash.targets11
-rw-r--r--tests/src/CLRTest.Execute.Batch.targets11
-rw-r--r--tests/src/CLRTest.Execute.targets1
-rw-r--r--tests/src/CLRTest.Jit.targets86
-rw-r--r--tests/src/Common/Platform/platformdefines.cpp4
-rw-r--r--tests/src/Common/Platform/platformdefines.h6
-rw-r--r--tests/src/Common/build_against_pkg_dependencies/build_against_pkg_dependencies.csproj15
-rw-r--r--tests/src/Common/build_against_pkg_dependencies/project.json32
-rw-r--r--tests/src/Common/empty/project.json2
-rw-r--r--tests/src/Common/netcoreapp/project.json74
-rw-r--r--tests/src/Common/targeting_pack_ref/project.json22
-rw-r--r--tests/src/Common/targeting_pack_ref/targeting_pack_ref.csproj12
-rw-r--r--tests/src/Common/test_dependencies/project.json136
-rw-r--r--tests/src/Common/test_dependencies/test_dependencies.csproj4
-rw-r--r--tests/src/Common/test_runtime/project.json5
-rw-r--r--tests/src/Common/test_runtime/test_runtime.csproj4
-rw-r--r--tests/src/CoreMangLib/cti/system/datetime/datetimeparse1.cs8
-rw-r--r--tests/src/CoreMangLib/system/span/BasicSpanTest.cs804
-rw-r--r--tests/src/GC/API/GC/GetGenerationWR2.csproj1
-rw-r--r--tests/src/GC/API/GCHandleCollector/Usage.cs3
-rw-r--r--tests/src/GC/Features/HeapExpansion/pluggaps.csproj1
-rw-r--r--tests/src/GC/Performance/Framework/GCPerfTestFramework.csproj31
-rw-r--r--tests/src/GC/Performance/Framework/packages.config24
-rw-r--r--tests/src/GC/Regressions/v2.0-rtm/494226/494226.csproj3
-rw-r--r--tests/src/GC/Scenarios/DoublinkList/dlcollect.cs6
-rw-r--r--tests/src/GC/Scenarios/DoublinkList/dlstack.cs6
-rw-r--r--tests/src/GC/Scenarios/DoublinkList/doublinkgen.cs6
-rw-r--r--tests/src/GC/Scenarios/FinalizeTimeout/FinalizeTimeout.cs7
-rw-r--r--tests/src/GC/Scenarios/ServerModel/servermodel.csproj1
-rw-r--r--tests/src/GC/Stress/Framework/ReliabilityFramework.csproj2
-rw-r--r--tests/src/GC/Stress/Tests/dir.targets6
-rw-r--r--tests/src/Interop/ArrayMarshalling/ByValArray/MarshalArrayByValNative.cpp130
-rw-r--r--tests/src/Interop/PrimitiveMarshalling/Bool/BoolNative.cpp2
-rwxr-xr-xtests/src/Interop/RefCharArray/RefCharArrayNative.cpp2
-rw-r--r--tests/src/Interop/SimpleStruct/SimpleStructNative.cpp4
-rw-r--r--tests/src/Interop/StringMarshalling/UTF8/UTF8TestNative.cpp4
-rw-r--r--tests/src/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.cpp53
-rw-r--r--tests/src/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.h173
-rwxr-xr-xtests/src/Interop/common/types.h4
-rw-r--r--tests/src/JIT/CodeGenBringUpTests/Rotate.cs96
-rw-r--r--tests/src/JIT/CodeGenBringUpTests/Shift.cs86
-rw-r--r--tests/src/JIT/CodeGenBringUpTests/Shift.csproj40
-rw-r--r--tests/src/JIT/Directed/pinvoke/pinvoke-examples.cs223
-rw-r--r--tests/src/JIT/Directed/pinvoke/pinvoke-examples.csproj44
-rw-r--r--tests/src/JIT/Methodical/fp/exgen/10w5d_cs_d.csproj5
-rw-r--r--tests/src/JIT/Methodical/fp/exgen/10w5d_cs_r.csproj5
-rw-r--r--tests/src/JIT/Methodical/structs/systemvbringup/structpinvoketests.cs1096
-rw-r--r--tests/src/JIT/Methodical/structs/valuetuple.cs95
-rw-r--r--tests/src/JIT/Methodical/structs/valuetuple.csproj41
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchF/Adams/Adams.cs9
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchF/BenchMk2/BenchMk2.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchF/BenchMrk/BenchMrk.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchF/Bisect/Bisect.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchF/DMath/DMath.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchF/FFT/FFT.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchF/InProd/InProd.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchF/InvMt/InvMt.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchF/LLoops/LLoops.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchF/Lorenz/Lorenz.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchF/MatInv4/MatInv4.cs17
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchF/NewtE/NewtE.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchF/NewtR/NewtR.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchF/Regula/Regula.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchF/Romber/Romber.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchF/Secant/Secant.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchF/Simpsn/Simpsn.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchF/SqMtx/SqMtx.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchF/Trap/Trap.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchF/Whetsto/Whetsto.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchI/8Queens/8Queens.cs7
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchI/Ackermann/Ackermann.cs7
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchI/AddArray/AddArray.cs9
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchI/AddArray2/AddArray2.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchI/Array1/Array1.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchI/Array2/Array2.cs7
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchI/BenchE/BenchE.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchI/BubbleSort/BubbleSort.cs7
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchI/BubbleSort2/BubbleSort2.cs5
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchI/CSieve/CSieve.cs5
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchI/Fib/Fib.cs7
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchI/HeapSort/HeapSort.cs7
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchI/IniArray/IniArray.cs5
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchI/LogicArray/LogicArray.cs5
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchI/Midpoint/Midpoint.cs5
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchI/MulMatrix/MulMatrix.cs7
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchI/NDhrystone/NDhrystone.cs45
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchI/Permutate/Permutate.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchI/Pi/Pi.cs5
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchI/Puzzle/Puzzle.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchI/QuickSort/QuickSort.cs7
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchI/TreeInsert/TreeInsert.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchI/TreeSort/TreeSort.cs9
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchI/XposMatrix/XposMatrix.cs7
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchmarksGame/binarytrees/binarytrees.csharp.cs7
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchmarksGame/fasta/fasta.csharp-2.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchmarksGame/fastaredux/fastaredux.csharp.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchmarksGame/nbody/nbody.csharp-3.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchmarksGame/pidigits/pi-digits.cs5
-rw-r--r--tests/src/JIT/Performance/CodeQuality/BenchmarksGame/spectralnorm/spectralnorm.cs9
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsByte.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsChar.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsDouble.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsFloat.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsInt.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsLong.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsSByte.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsShort.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsString.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsUInt.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsULong.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsUShort.cs3
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/InlineGCStruct.cs148
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/InlineGCStruct.csproj44
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Inlining/NoThrowInline.cs5
-rw-r--r--tests/src/JIT/Performance/CodeQuality/SIMD/ConsoleMandel/ConsoleMandel.cs4
-rw-r--r--tests/src/JIT/Performance/CodeQuality/SIMD/RayTracer/RayTracerBench.cs7
-rw-r--r--tests/src/JIT/Performance/CodeQuality/SIMD/SeekUnroll/SeekUnroll.cs159
-rw-r--r--tests/src/JIT/Performance/CodeQuality/SIMD/SeekUnroll/SeekUnroll.csproj43
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Serialization/Deserialize.cs7
-rw-r--r--tests/src/JIT/Performance/CodeQuality/Serialization/Serialize.cs5
-rw-r--r--tests/src/JIT/Performance/CodeQuality/V8/Crypto/Crypto.cs2
-rw-r--r--tests/src/JIT/Performance/CodeQuality/V8/DeltaBlue/DeltaBlue.cs5
-rw-r--r--tests/src/JIT/Performance/CodeQuality/V8/Richards/Richards.cs18
-rw-r--r--tests/src/JIT/Performance/RunBenchmarks/RunBenchmarks.cmd2
-rwxr-xr-xtests/src/JIT/Performance/RunBenchmarks/RunBenchmarks.sh53
-rw-r--r--tests/src/JIT/Regression/CLR-x86-JIT/V2.0-RTM/b475589/b475589.il71
-rw-r--r--tests/src/JIT/Regression/CLR-x86-JIT/V2.0-RTM/b475589/b475589.ilproj40
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_142976/DevDiv_142976.cs56
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_142976/DevDiv_142976.csproj46
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_255294/DevDiv_255294.cs62374
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_255294/DevDiv_255294.csproj46
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_278365/DevDiv_278365.cs49
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_278365/DevDiv_278365.csproj46
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_278369/DevDiv_278369.il58
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_278369/DevDiv_278369.ilproj41
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_278371/DevDiv_278371.il88
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_278371/DevDiv_278371.ilproj41
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_278372/DevDiv_278372.il156
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_278372/DevDiv_278372.ilproj51
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_278375/DevDiv_278375.cs131
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_278375/DevDiv_278375.csproj46
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_278376/DevDiv_278376.cs36
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_278376/DevDiv_278376.csproj46
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_278523/DevDiv_278523.il113
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_278523/DevDiv_278523.ilproj41
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_278526/DevDiv_278526.cs47
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_278526/DevDiv_278526.csproj46
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_279396/DevDiv_279396.il39
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_279396/DevDiv_279396.ilproj41
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_279829/DevDiv_279829.il36
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_279829/DevDiv_279829.ilproj46
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_280120/DevDiv_280120.cs22
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_280120/DevDiv_280120.csproj56
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_280123/DevDiv_280123.cs42
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_280123/DevDiv_280123.csproj46
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_280127/DevDiv_280127.cs37
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_280127/DevDiv_280127.csproj46
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_283795/DevDiv_283795.cs55
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_283795/DevDiv_283795.csproj46
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_284785/DevDiv_284785.cs39
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_284785/DevDiv_284785.csproj46
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_288222/DevDiv_288222.cs50
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_288222/DevDiv_288222.csproj46
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_359734/DevDiv_359734.il118
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_359734/DevDiv_359734.ilproj41
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_359736/DevDiv_359736.cs42
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_359736/DevDiv_359736_d.csproj45
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_359736/DevDiv_359736_do.csproj45
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_359736/DevDiv_359736_r.csproj45
-rw-r--r--tests/src/JIT/Regression/JitBlue/DevDiv_359736/DevDiv_359736_ro.csproj45
-rw-r--r--tests/src/JIT/Regression/JitBlue/GitHub_7906/GitHub_7906.cs47
-rw-r--r--tests/src/JIT/Regression/JitBlue/GitHub_7906/GitHub_7906.csproj44
-rw-r--r--tests/src/JIT/Regression/JitBlue/GitHub_7907/GitHub_7907.cs53
-rw-r--r--tests/src/JIT/Regression/JitBlue/GitHub_7907/GitHub_7907.csproj46
-rw-r--r--tests/src/JIT/Regression/JitBlue/GitHub_8133/GitHub_8133.il112
-rw-r--r--tests/src/JIT/Regression/JitBlue/GitHub_8133/GitHub_8133.ilproj41
-rw-r--r--tests/src/JIT/Regression/JitBlue/GitHub_8170/GitHub_8170.cs23
-rw-r--r--tests/src/JIT/Regression/JitBlue/GitHub_8170/GitHub_8170.csproj46
-rw-r--r--tests/src/JIT/Regression/JitBlue/GitHub_8220/GitHub_8220.cs170
-rw-r--r--tests/src/JIT/Regression/JitBlue/GitHub_8220/GitHub_8220.csproj45
-rw-r--r--tests/src/JIT/Regression/JitBlue/GitHub_8231/GitHub_8231.cs62
-rw-r--r--tests/src/JIT/Regression/JitBlue/GitHub_8231/GitHub_8231.csproj39
-rw-r--r--tests/src/JIT/Regression/JitBlue/GitHub_8460/GitHub_8460.cs38
-rw-r--r--tests/src/JIT/Regression/JitBlue/GitHub_8460/GitHub_8460.csproj46
-rw-r--r--tests/src/JIT/Regression/JitBlue/GitHub_8599/GitHub_8599.cs42
-rw-r--r--tests/src/JIT/Regression/JitBlue/GitHub_8599/GitHub_8599.csproj46
-rw-r--r--tests/src/JIT/Regression/JitBlue/GitHub_CoreRT_2073/GitHub_CoreRT_2073.il55
-rw-r--r--tests/src/JIT/Regression/JitBlue/GitHub_CoreRT_2073/GitHub_CoreRT_2073.ilproj38
-rw-r--r--tests/src/JIT/Regression/VS-ia64-JIT/V2.0-Beta2/b311420/b311420.csproj5
-rwxr-xr-xtests/src/JIT/SIMD/Vector3Interop.cs6
-rw-r--r--tests/src/JIT/SIMD/VectorDot.cs7
-rw-r--r--tests/src/JIT/SIMD/VectorIntEquals.cs61
-rw-r--r--tests/src/JIT/SIMD/VectorUtil.cs2
-rw-r--r--tests/src/JIT/config/benchmark+roslyn/project.json46
-rw-r--r--tests/src/JIT/config/benchmark+serialize/project.json43
-rw-r--r--tests/src/JIT/config/benchmark/project.json51
-rw-r--r--tests/src/JIT/config/extra/project.json34
-rw-r--r--tests/src/JIT/config/minimal/project.json12
-rw-r--r--tests/src/JIT/config/threading+thread/project.json16
-rw-r--r--tests/src/JIT/config/threading/project.json12
-rw-r--r--tests/src/JIT/jit64/opt/cse/HugeArray.csproj5
-rw-r--r--tests/src/JIT/jit64/verif/sniff/fg/ver_fg_13.il7
-rw-r--r--tests/src/JIT/opt/Inline/regression/mismatch32/mismatch32.il6
-rw-r--r--tests/src/JIT/opt/Inline/regression/mismatch64/mismatch64.il6
-rw-r--r--tests/src/JIT/opt/Tailcall/TailcallVerifyWithPrefix.il30
-rw-r--r--tests/src/JIT/opt/virtualstubdispatch/bigvtbl/bigvtbl_cs_d.csproj3
-rw-r--r--tests/src/JIT/opt/virtualstubdispatch/bigvtbl/bigvtbl_cs_r.csproj3
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase0.il21
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase1.il20
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase2.il20
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase3.il20
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase4.il22
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase5.il20
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase6.il20
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase0.il21
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase1.il20
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase2.il20
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase3.il20
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase4.il20
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase5.il19
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase6.il18
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase0.il21
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase1.il20
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase2.il20
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase3.il20
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase4.il20
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase5.il20
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase6.il20
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase0.il21
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase1.il20
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase2.il20
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase3.il20
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase4.il20
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase5.il20
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase6.il20
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/TestCase0.il15
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/TestCase1.il18
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/TestCase2.il18
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/TestCase3.il18
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/TestCase4.il18
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/TestCase5.il18
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/TestCase6.il18
-rw-r--r--tests/src/Loader/classloader/InterfaceFolding/TestCase7.il19
-rw-r--r--tests/src/Loader/classloader/PrivateInterfaceImpl/Test2_NonFriendPriInterface.csproj35
-rw-r--r--tests/src/Loader/classloader/generics/Visibility/A_Types.csproj35
-rw-r--r--tests/src/Loader/classloader/generics/Visibility/B_Types.csproj35
-rw-r--r--tests/src/Loader/classloader/methodoverriding/regressions/549411/exploit.csproj1
-rw-r--r--tests/src/Loader/classloader/regressions/dev10_710121/dev10_710121.il15
-rw-r--r--tests/src/TestWrappersConfig/project.json13
-rw-r--r--tests/src/baseservices/compilerservices/FixedAddressValueType/FixedAddressValueType.cs60
-rw-r--r--tests/src/baseservices/compilerservices/FixedAddressValueType/FixedAddressValueType.csproj44
-rw-r--r--tests/src/baseservices/compilerservices/RuntimeHelpers/ExecuteCodeWithGuaranteedCleanup.cs62
-rw-r--r--tests/src/baseservices/compilerservices/RuntimeHelpers/ExecuteCodeWithGuaranteedCleanup.csproj42
-rw-r--r--tests/src/baseservices/compilerservices/RuntimeWrappedException/RuntimeWrappedException.cs63
-rw-r--r--tests/src/baseservices/compilerservices/RuntimeWrappedException/RuntimeWrappedException.csproj45
-rw-r--r--tests/src/baseservices/compilerservices/RuntimeWrappedException/StringThrower.il40
-rw-r--r--tests/src/baseservices/compilerservices/RuntimeWrappedException/StringThrower.ilproj40
-rw-r--r--tests/src/baseservices/compilerservices/modulector/moduleCctor.il110
-rw-r--r--tests/src/baseservices/compilerservices/modulector/moduleCctor.ilproj40
-rw-r--r--tests/src/baseservices/compilerservices/modulector/runmoduleconstructor.cs38
-rw-r--r--tests/src/baseservices/compilerservices/modulector/runmoduleconstructor.csproj45
-rw-r--r--tests/src/dir.common.props7
-rw-r--r--tests/src/dir.props13
-rw-r--r--tests/src/dir.targets28
-rw-r--r--tests/src/jit/Directed/pinvoke/pinvoke-bug.cs60
-rw-r--r--tests/src/jit/Directed/pinvoke/pinvoke-bug.csproj44
-rw-r--r--tests/src/performance/perflab/BlockCopyPerf.cs29
-rw-r--r--tests/src/performance/perflab/CastingPerf.cs644
-rw-r--r--tests/src/performance/perflab/CastingPerf2.cs34
-rw-r--r--tests/src/performance/perflab/DelegatePerf.cs144
-rw-r--r--tests/src/performance/perflab/EnumPerf.cs109
-rw-r--r--tests/src/performance/perflab/LowLevelPerf.cs1283
-rw-r--r--tests/src/performance/perflab/ReflectionPerf.cs6317
-rw-r--r--tests/src/performance/perflab/StackWalk.cs129
-rw-r--r--tests/src/performance/perflab/ThreadingPerf.cs111
-rw-r--r--tests/src/performance/project.json54
-rw-r--r--tests/src/readytorun/generics.cs92
-rw-r--r--tests/src/readytorun/main.cs14
-rw-r--r--tests/src/reflection/ldtoken/byrefs.il88
-rw-r--r--tests/src/reflection/ldtoken/byrefs.ilproj35
-rw-r--r--tests/tests.targets4
-rw-r--r--tests/testsFailingOutsideWindows.txt3
-rw-r--r--tests/testsUnsupportedOnARM32.txt9
-rw-r--r--tests/testsUnsupportedOutsideWindows.txt1
-rw-r--r--tests/x86/compatjit_x86_testenv.cmd8
-rw-r--r--tests/x86/legacyjit_x86_testenv.cmd52
-rw-r--r--tests/x86/ryujit_x86_testenv.cmd58
-rw-r--r--tests/x86_jit32_issues.targets8
-rw-r--r--tests/x86_legacy_backend_issues.targets23
-rw-r--r--tests/xunitwrapper.targets2
-rwxr-xr-xverify-so.sh20
4534 files changed, 186978 insertions, 120154 deletions
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index b3ac01be87..0000000000
--- a/.gitignore
+++ /dev/null
@@ -1,306 +0,0 @@
-syntax: glob
-
-[Bb]inaries/
-
-# Build tools related files
-/[Tt]ools/
-
-### VisualStudio ###
-
-# User-specific files
-*.suo
-*.user
-*.userosscache
-*.sln.docstates
-
-# Build results
-[Dd]ebug/
-[Dd]ebugPublic/
-[Rr]elease/
-[Rr]eleases/
-x64/
-x86/
-build/
-bld/
-[Bb]in/
-[Oo]bj/
-msbuild.log
-
-# Visual Studio 2015
-.vs/
-
-# Visual Studio 2015 Pre-CTP6
-*.sln.ide
-*.ide/
-
-# MSTest test Results
-[Tt]est[Rr]esult*/
-[Bb]uild[Ll]og.*
-
-#NUNIT
-*.VisualState.xml
-TestResult.xml
-
-# Build Results of an ATL Project
-[Dd]ebugPS/
-[Rr]eleasePS/
-dlldata.c
-
-*_i.c
-*_p.c
-*_i.h
-*.ilk
-*.meta
-*.obj
-*.pch
-*.pdb
-*.pgc
-*.pgd
-*.rsp
-*.sbr
-*.tlb
-*.tli
-*.tlh
-*.tmp
-*.tmp_proj
-*.log
-*.html
-*.vspscc
-*.vssscc
-.builds
-*.pidb
-*.svclog
-*.scc
-
-# Chutzpah Test files
-_Chutzpah*
-
-# Visual C++ cache files
-ipch/
-*.aps
-*.ncb
-*.opendb
-*.opensdf
-*.sdf
-*.cachefile
-*.VC.db
-
-# Visual Studio profiler
-*.psess
-*.vsp
-*.vspx
-
-# TFS 2012 Local Workspace
-$tf/
-
-# Guidance Automation Toolkit
-*.gpState
-
-# ReSharper is a .NET coding add-in
-_ReSharper*/
-*.[Rr]e[Ss]harper
-*.DotSettings.user
-
-# JustCode is a .NET coding addin-in
-.JustCode
-
-# TeamCity is a build add-in
-_TeamCity*
-
-# DotCover is a Code Coverage Tool
-*.dotCover
-
-# NCrunch
-_NCrunch_*
-.*crunch*.local.xml
-
-# MightyMoose
-*.mm.*
-AutoTest.Net/
-
-# Web workbench (sass)
-.sass-cache/
-
-# Installshield output folder
-[Ee]xpress/
-
-# DocProject is a documentation generator add-in
-DocProject/buildhelp/
-DocProject/Help/*.HxT
-DocProject/Help/*.HxC
-DocProject/Help/*.hhc
-DocProject/Help/*.hhk
-DocProject/Help/*.hhp
-DocProject/Help/Html2
-DocProject/Help/html
-
-# Click-Once directory
-publish/
-
-# Publish Web Output
-*.[Pp]ublish.xml
-*.azurePubxml
-*.pubxml
-*.publishproj
-
-# NuGet Packages
-*.nupkg
-**/packages/*
-project.lock.json
-
-# Windows Azure Build Output
-csx/
-*.build.csdef
-
-# Windows Store app package directory
-AppPackages/
-
-# Others
-sql/
-*.Cache
-ClientBin/
-[Ss]tyle[Cc]op.*
-~$*
-*.dbmdl
-*.dbproj.schemaview
-*.pfx
-*.publishsettings
-node_modules/
-*.metaproj
-*.metaproj.tmp
-.atom-build.json
-tags
-TAGS
-
-# RIA/Silverlight projects
-Generated_Code/
-
-# Backup & report files from converting an old project file
-# to a newer Visual Studio version. Backup files are not needed,
-# because we have git ;-)
-_UpgradeReport_Files/
-Backup*/
-UpgradeLog*.XML
-UpgradeLog*.htm
-
-# SQL Server files
-*.mdf
-*.ldf
-
-# Business Intelligence projects
-*.rdl.data
-*.bim.layout
-*.bim_*.settings
-
-# Microsoft Fakes
-FakesAssemblies/
-
-# C/C++ extension for Visual Studio Code
-browse.VC.db
-
-# Local settings folder for Visual Studio Code
-.vscode/
-
-### MonoDevelop ###
-
-*.pidb
-*.userprefs
-
-### Windows ###
-
-# Windows image file caches
-Thumbs.db
-ehthumbs.db
-
-# Folder config file
-Desktop.ini
-
-# Recycle Bin used on file shares
-$RECYCLE.BIN/
-
-# Windows Installer files
-*.cab
-*.msi
-*.msm
-*.msp
-
-# Windows shortcuts
-*.lnk
-
-# Common binary extensions on Windows
-*.exe
-*.dll
-*.lib
-
-### Linux ###
-
-*~
-\#*\#
-
-# KDE directory preferences
-.directory
-
-### OSX ###
-
-.DS_Store
-.AppleDouble
-.LSOverride
-
-# Icon must end with two \r
-Icon
-
-# Thumbnails
-._*
-
-# Files that might appear on external disk
-.Spotlight-V100
-.Trashes
-
-# Directories potentially created on remote AFP share
-.AppleDB
-.AppleDesktop
-Network Trash Folder
-Temporary Items
-.apdisk
-
-# We have some checked in prebuilt generated files
-!src/pal/prebuilt/idl/*_i.c
-
-# Valid 'debug' folder, that contains CLR debugging code
-!src/debug
-
-# Ignore folders created by the test build
-TestWrappers_x64_[d|D]ebug
-TestWrappers_x64_[c|C]hecked
-TestWrappers_x64_[r|R]elease
-TestWrappers_x86_[d|D]ebug
-TestWrappers_x86_[c|C]hecked
-TestWrappers_x86_[r|R]elease
-TestWrappers_arm_[d|D]ebug
-TestWrappers_arm_[c|C]hecked
-TestWrappers_arm_[r|R]elease
-TestWrappers_arm64_[d|D]ebug
-TestWrappers_arm64_[c|C]hecked
-TestWrappers_arm64_[r|R]elease
-tests/src/common/test_runtime/project.json
-
-Vagrantfile
-.vagrant
-
-# CMake files
-CMakeFiles/
-cmake_install.cmake
-CMakeCache.txt
-Makefile
-
-# Cross compilation
-cross/rootfs/*
-
-#python import files
-*.pyc
-
-# JIT32 files
-src/jit32
-
-# performance testing sandbox
-sandbox
diff --git a/.gitmirrorselective b/.gitmirrorselective
new file mode 100644
index 0000000000..e8310385c5
--- /dev/null
+++ b/.gitmirrorselective
@@ -0,0 +1 @@
+src \ No newline at end of file
diff --git a/BuildToolsVersion.txt b/BuildToolsVersion.txt
index acf5f592d1..f2717879e1 100644
--- a/BuildToolsVersion.txt
+++ b/BuildToolsVersion.txt
@@ -1 +1 @@
-1.0.26-prerelease-00719-02 \ No newline at end of file
+1.0.27-prerelease-01008-01 \ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a257421721..61c689b6d0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -14,7 +14,6 @@ include(functions.cmake)
if (WIN32)
message(STATUS "VS_PLATFORM_TOOLSET is ${CMAKE_VS_PLATFORM_TOOLSET}")
message(STATUS "VS_PLATFORM_NAME is ${CMAKE_VS_PLATFORM_NAME}")
- message(STATUS "VS_WINDOWS_TARGET_PLATFORM_VERSION is ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}")
endif (WIN32)
# Set commonly used directory names
@@ -40,11 +39,19 @@ endif()
# Ensure other tools are present
if (WIN32)
if(CLR_CMAKE_HOST_ARCH STREQUAL arm)
+
+ # Confirm that Windows SDK is present
+ if(NOT DEFINED CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION OR CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION STREQUAL "" )
+ message(FATAL_ERROR "Windows SDK is required for the Arm32 build.")
+ else()
+ message("Using Windows SDK version ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}")
+ endif()
+
# Explicitly specify the assembler to be used for Arm32 compile
file(TO_CMAKE_PATH "$ENV{VCINSTALLDIR}\\bin\\x86_arm\\armasm.exe" CMAKE_ASM_COMPILER)
set(CMAKE_ASM_MASM_COMPILER ${CMAKE_ASM_COMPILER})
- message(CMAKE_ASM_MASM_COMPILER explicitly set to: ${CMAKE_ASM_MASM_COMPILER})
+ message("CMAKE_ASM_MASM_COMPILER explicitly set to: ${CMAKE_ASM_MASM_COMPILER}")
# Enable generic assembly compilation to avoid CMake generate VS proj files that explicitly
# use ml[64].exe as the assembler.
@@ -94,9 +101,11 @@ else (WIN32)
else (CMAKE_SYSTEM_NAME STREQUAL Darwin)
# Ensure that objcopy is present
- if (DEFINED ENV{CROSSCOMPILE})
+ if (DEFINED ENV{CROSSCOMPILE} AND NOT DEFINED CLR_CROSS_COMPONENTS_BUILD)
if (CMAKE_SYSTEM_PROCESSOR STREQUAL armv7l OR CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64)
find_program(OBJCOPY ${TOOLCHAIN}-objcopy)
+ elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL i686)
+ find_program(OBJCOPY objcopy)
else()
clr_unknown_arch()
endif()
@@ -113,25 +122,52 @@ endif(WIN32)
#----------------------------------------
# Detect and set platform variable names
-# - for non-windows build platform & architecture is detected using inbuilt CMAKE variables
+# - for non-windows build platform & architecture is detected using inbuilt CMAKE variables and cross target component configure
# - for windows we use the passed in parameter to CMAKE to determine build arch
#----------------------------------------
if(CMAKE_SYSTEM_NAME STREQUAL Linux)
set(CLR_CMAKE_PLATFORM_UNIX 1)
- # CMAKE_SYSTEM_PROCESSOR returns the value of `uname -p`.
- # For the AMD/Intel 64bit architecure two different strings are common.
- # Linux and Darwin identify it as "x86_64" while FreeBSD and netbsd uses the
- # "amd64" string. Accept either of the two here.
- if(CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL amd64)
- set(CLR_CMAKE_PLATFORM_UNIX_AMD64 1)
- elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL armv7l)
- set(CLR_CMAKE_PLATFORM_UNIX_ARM 1)
- elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64)
- set(CLR_CMAKE_PLATFORM_UNIX_ARM64 1)
+ if(CLR_CROSS_COMPONENTS_BUILD)
+ # CMAKE_HOST_SYSTEM_PROCESSOR returns the value of `uname -p` on host.
+ if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL x86_64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL amd64)
+ if(CLR_CMAKE_TARGET_ARCH STREQUAL "arm")
+ set(CLR_CMAKE_PLATFORM_UNIX_X86 1)
+ else()
+ set(CLR_CMAKE_PLATFORM_UNIX_AMD64 1)
+ endif()
+ elseif(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL i686)
+ set(CLR_CMAKE_PLATFORM_UNIX_X86 1)
+ else()
+ clr_unknown_arch()
+ endif()
else()
- clr_unknown_arch()
+ # CMAKE_SYSTEM_PROCESSOR returns the value of `uname -p` on target.
+ # For the AMD/Intel 64bit architecure two different strings are common.
+ # Linux and Darwin identify it as "x86_64" while FreeBSD and netbsd uses the
+ # "amd64" string. Accept either of the two here.
+ if(CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL amd64)
+ set(CLR_CMAKE_PLATFORM_UNIX_AMD64 1)
+ elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL armv7l)
+ set(CLR_CMAKE_PLATFORM_UNIX_ARM 1)
+ elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64)
+ set(CLR_CMAKE_PLATFORM_UNIX_ARM64 1)
+ elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL i686)
+ set(CLR_CMAKE_PLATFORM_UNIX_X86 1)
+ else()
+ clr_unknown_arch()
+ endif()
endif()
set(CLR_CMAKE_PLATFORM_LINUX 1)
+
+ # Detect Alpine Linux
+ SET(OS_RELEASE_FILENAME "/etc/os-release")
+ if (EXISTS ${OS_RELEASE_FILENAME})
+ file(READ ${OS_RELEASE_FILENAME} OS_RELEASE)
+ string(FIND "${OS_RELEASE}" "ID=alpine" CLR_CMAKE_PLATFORM_ALPINE_LINUX)
+ if(CLR_CMAKE_PLATFORM_ALPINE_LINUX EQUAL -1)
+ unset(CLR_CMAKE_PLATFORM_ALPINE_LINUX)
+ endif(CLR_CMAKE_PLATFORM_ALPINE_LINUX EQUAL -1)
+ endif(EXISTS ${OS_RELEASE_FILENAME})
endif(CMAKE_SYSTEM_NAME STREQUAL Linux)
if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
@@ -190,27 +226,30 @@ endif(CMAKE_SYSTEM_NAME STREQUAL SunOS)
#-------------------------------------------------------------
# Set HOST architecture variables
if(CLR_CMAKE_PLATFORM_UNIX_ARM)
- set(CLR_CMAKE_PLATFORM_ARCH_ARM 1)
- set(CLR_CMAKE_HOST_ARCH "arm")
+ set(CLR_CMAKE_PLATFORM_ARCH_ARM 1)
+ set(CLR_CMAKE_HOST_ARCH "arm")
elseif(CLR_CMAKE_PLATFORM_UNIX_ARM64)
- set(CLR_CMAKE_PLATFORM_ARCH_ARM64 1)
- set(CLR_CMAKE_HOST_ARCH "arm64")
+ set(CLR_CMAKE_PLATFORM_ARCH_ARM64 1)
+ set(CLR_CMAKE_HOST_ARCH "arm64")
elseif(CLR_CMAKE_PLATFORM_UNIX_AMD64)
- set(CLR_CMAKE_PLATFORM_ARCH_AMD64 1)
- set(CLR_CMAKE_HOST_ARCH "x64")
-elseif(WIN32)
- # CLR_CMAKE_HOST_ARCH is passed in as param to cmake
- if (CLR_CMAKE_HOST_ARCH STREQUAL x64)
set(CLR_CMAKE_PLATFORM_ARCH_AMD64 1)
- elseif(CLR_CMAKE_HOST_ARCH STREQUAL x86)
+ set(CLR_CMAKE_HOST_ARCH "x64")
+elseif(CLR_CMAKE_PLATFORM_UNIX_X86)
set(CLR_CMAKE_PLATFORM_ARCH_I386 1)
- elseif(CLR_CMAKE_HOST_ARCH STREQUAL arm)
- set(CLR_CMAKE_PLATFORM_ARCH_ARM 1)
- elseif(CLR_CMAKE_HOST_ARCH STREQUAL arm64)
- set(CLR_CMAKE_PLATFORM_ARCH_ARM64 1)
- else()
- clr_unknown_arch()
- endif()
+ set(CLR_CMAKE_HOST_ARCH "x86")
+elseif(WIN32)
+ # CLR_CMAKE_HOST_ARCH is passed in as param to cmake
+ if (CLR_CMAKE_HOST_ARCH STREQUAL x64)
+ set(CLR_CMAKE_PLATFORM_ARCH_AMD64 1)
+ elseif(CLR_CMAKE_HOST_ARCH STREQUAL x86)
+ set(CLR_CMAKE_PLATFORM_ARCH_I386 1)
+ elseif(CLR_CMAKE_HOST_ARCH STREQUAL arm)
+ set(CLR_CMAKE_PLATFORM_ARCH_ARM 1)
+ elseif(CLR_CMAKE_HOST_ARCH STREQUAL arm64)
+ set(CLR_CMAKE_PLATFORM_ARCH_ARM64 1)
+ else()
+ clr_unknown_arch()
+ endif()
endif()
# Set TARGET architecture variables
@@ -235,9 +274,9 @@ endif()
# check if host & target arch combination are valid
if(NOT(CLR_CMAKE_TARGET_ARCH STREQUAL CLR_CMAKE_HOST_ARCH))
- if(NOT((CLR_CMAKE_PLATFORM_ARCH_AMD64 AND CLR_CMAKE_TARGET_ARCH_ARM64) OR (CLR_CMAKE_PLATFORM_ARCH_I386 AND CLR_CMAKE_TARGET_ARCH_ARM)))
- message(FATAL_ERROR "Invalid host and target arch combination")
- endif()
+ if(NOT((CLR_CMAKE_PLATFORM_ARCH_AMD64 AND CLR_CMAKE_TARGET_ARCH_ARM64) OR (CLR_CMAKE_PLATFORM_ARCH_I386 AND CLR_CMAKE_TARGET_ARCH_ARM)))
+ message(FATAL_ERROR "Invalid host and target arch combination")
+ endif()
endif()
#-----------------------------------------------------
@@ -265,10 +304,8 @@ if (WIN32)
endforeach (Definition)
endforeach (Config)
- if(NOT CLR_CMAKE_PLATFORM_ARCH_ARM64)
- set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /guard:cf")
- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /guard:cf")
- endif (NOT CLR_CMAKE_PLATFORM_ARCH_ARM64)
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /guard:cf")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /guard:cf")
# Incremental linking with CFG is broken until next VS release.
# This needs to be appended to the last for each build type to override the default flag.
@@ -278,7 +315,15 @@ if (WIN32)
#
# Disable the following line for UNIX altjit on Windows
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /MANIFEST:NO") #Do not create Side-by-Side Assembly Manifest
- set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SUBSYSTEM:WINDOWS,6.00") #windows subsystem
+
+ if (CLR_CMAKE_PLATFORM_ARCH_ARM)
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SUBSYSTEM:WINDOWS,6.02") #windows subsystem - arm minimum is 6.02
+ elseif(CLR_CMAKE_PLATFORM_ARCH_ARM64)
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SUBSYSTEM:WINDOWS,6.03") #windows subsystem - arm64 minimum is 6.03
+ else ()
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SUBSYSTEM:WINDOWS,6.01") #windows subsystem
+ endif ()
+
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /LARGEADDRESSAWARE") # can handle addresses larger than 2 gigabytes
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /RELEASE") #sets the checksum in the header
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /NXCOMPAT") #Compatible with Data Execution Prevention
@@ -425,6 +470,9 @@ if (CLR_CMAKE_PLATFORM_UNIX)
elseif(CLR_CMAKE_PLATFORM_UNIX_ARM64)
message("Detected Linux ARM64")
add_definitions(-DLINUX64)
+ elseif(CLR_CMAKE_PLATFORM_UNIX_X86)
+ message("Detected Linux i686")
+ add_definitions(-DLINUX32)
else()
clr_unknown_arch()
endif()
@@ -567,4 +615,4 @@ if(CLR_CMAKE_BUILD_TESTS)
add_subdirectory(tests)
endif(CLR_CMAKE_BUILD_TESTS)
-include(definitionsconsistencycheck.cmake) \ No newline at end of file
+include(definitionsconsistencycheck.cmake)
diff --git a/Documentation/README.md b/Documentation/README.md
index 7e29013bb2..1a3906b969 100644
--- a/Documentation/README.md
+++ b/Documentation/README.md
@@ -59,7 +59,7 @@ Book of the Runtime
The Book of the Runtime is a set of chapters that go in depth into various
interesting aspects of the design of the .NET Framework.
-- [Book of the Runtime](botr/_tableOfContents.md)
+- [Book of the Runtime](botr/README.md)
For your convenience, here are a few quick links to popular chapters:
diff --git a/Documentation/botr/_tableOfContents.md b/Documentation/botr/README.md
index db4ffc121c..db4ffc121c 100644
--- a/Documentation/botr/_tableOfContents.md
+++ b/Documentation/botr/README.md
diff --git a/Documentation/botr/clr-abi.md b/Documentation/botr/clr-abi.md
index cbd5fc903c..caa5c7add9 100644
--- a/Documentation/botr/clr-abi.md
+++ b/Documentation/botr/clr-abi.md
@@ -6,6 +6,8 @@ It describes requirements that the Just-In-Time (JIT) compiler imposes on the VM
A note on the JIT codebases: JIT32 refers to the original JIT codebase that originally generated x86 code and was later ported to generate ARM code. Later, it was ported and re-architected to generate AMD64 code (making its name something of a confusing misnomer). This work is referred to as RyuJIT. RyuJIT is being ported to generate ARM64 code. JIT64 refers to the legacy codebase that supports AMD64.
+CoreRT refers to https://github.com/dotnet/corert runtime that is optimized for AOT. The CoreRT ABI differs in a few details for simplicity and consistency across platforms.
+
# Getting started
Read everything in the documented Windows ABI.
@@ -289,6 +291,8 @@ On ARM and ARM64, for all second pass funclets (finally, fault, catch, and filte
Catch, Filter, and Filter-handlers also get an Exception object (GC ref) as an argument (`REG_EXCEPTION_OBJECT`). On AMD64 it is the second argument and thus passed in RDX. On ARM and ARM64 this is the first argument and passed in R0.
+CoreRT does not use PSPSym. For filter funclets the VM sets the frame register to be the same as the parent function. For second pass funclets the VM restores all non-volatile registers. The same convention is used across all platforms.
+
(Note that the JIT64 source code contains a comment that says, "The current CLR doesn't always pass the correct establisher frame to the funclet. Funclet may receive establisher frame of funclet when expecting that of original routine." It indicates this is the reason that a PSPSym is required in all funclets as well as the main function, whereas if the establisher frame was correctly reported, the PSPSym could be omitted in some cases.)
## Funclet Return Values
@@ -468,7 +472,7 @@ Filters are invoked in the 1st pass of EH processing and as such execution might
Duplicated clauses are a special set of entries in the EH tables to assist the VM. Specifically, if handler 'A' is also protected by an outer EH clause 'B', then the JIT must emit a duplicated clause, a duplicate of 'B', that marks the whole handler 'A' (which is now lexically disjoint for the range of code for the corresponding try body 'A') as being protected by the handler for 'B'.
-Duplicated clauses are not needed for x86.
+Duplicated clauses are not needed for x86 and for CoreRT ABI.
During exception dispatch the VM uses these duplicated clauses to know when to skip any frames between the handler and its parent function. After skipping to the parent function, due to a duplicated clause, the VM searches for a regular/non-duplicate clause in the parent function. The order of duplicated clauses is important. They should appear after all of the main function clauses. They should still follow the normal sorting rules (inner-to-outer, top-to-bottom), but because the try-start/try-end will all be the same for a given handler, they should maintain the ordering, regarding inner-to-outer, as the corresponding original clause.
diff --git a/Documentation/botr/exceptions.md b/Documentation/botr/exceptions.md
index daa684bf8b..8e4b77a051 100644
--- a/Documentation/botr/exceptions.md
+++ b/Documentation/botr/exceptions.md
@@ -278,10 +278,16 @@ To use the callout filter, instead of this:
write this:
BOOL OneShot = TRUE;
-
- PAL_TRY
+ struct Param {
+ BSTR* pBSTR;
+ int length;
+ };
+ struct Param param;
+ param.pBSTR = pBSTR;
+
+ PAL_TRY(Param*, pParam, &param)
{
- length = SysStringLen(pBSTR);
+ pParam->length = SysStringLen(pParam->pBSTR);
}
PAL_EXCEPT_FILTER(CallOutFilter, &OneShot)
{
diff --git a/Documentation/botr/garbage-collection.md b/Documentation/botr/garbage-collection.md
index 9e16131114..789c4e92ff 100644
--- a/Documentation/botr/garbage-collection.md
+++ b/Documentation/botr/garbage-collection.md
@@ -2,7 +2,7 @@ Garbage Collection Design
=========================
Author: Maoni Stephens ([@maoni0](https://github.com/maoni0)) - 2015
-Note: See the The Garbage Collection Handbook referenced in the resources section at the end of this document to learn more about garbage collection topics.
+Note: See _The Garbage Collection Handbook_ (referenced in the resources section at the end of this document) to learn more about garbage collection topics.
Component Architecture
======================
diff --git a/Documentation/building/crossgen.md b/Documentation/building/crossgen.md
index c74a5e680a..bf013e2285 100644
--- a/Documentation/building/crossgen.md
+++ b/Documentation/building/crossgen.md
@@ -7,7 +7,7 @@ Introduction
When you create a .NET assembly using C# compiler, your assembly contains only MSIL code.
When the app runs, the JIT compiler translates the MSIL code into native code, before the CPU can execute them.
This execution model has some advantages. For example, your assembly code can be portable across all platforms and architectures that support .NET Core.
-However, this portability comes with a performance penalty. Your app starts up slower, because the JIT compiler has to spend time to translate the code.
+However, this portability comes with a performance cost. Your app starts up more slowly, because the JIT compiler has to spend time to translate the code.
To help make your app start up faster, CoreCLR includes a tool called CrossGen, which can pre-compile the MSIL code into native code.
@@ -18,7 +18,7 @@ If you build CoreCLR yourself, the CrossGen tool (`crossgen.exe` on Windows, or
If you install CoreCLR using a NuGet package, you can find CrossGen in the `tools` folder of the NuGet package.
Regardless of how you obtain CrossGen, it is very important that it must match other CoreCLR binaries.
-- If you build CrossGen yourself, you should use it with coreclr and mscorlib generated from the same build. Do not attempt to mix CrossGen from one build with binaries generated from another build.
+- If you build CrossGen yourself, you should use it with runtime and `System.Private.CoreLib.dll` generated from the same build. Do not attempt to mix CrossGen from one build with binaries generated from another build.
- If you install CrossGen from NuGet, make sure you use CrossGen from exactly the same NuGet package as the rest of your CoreCLR binaries. Do not attempt to mix binaries from multiple NuGet packages.
If you do not follow the above rules, you are likely to encounter errors while running CrossGen.
@@ -26,26 +26,30 @@ If you do not follow the above rules, you are likely to encounter errors while r
Using CrossGen
--------------
-In most cases, the build script automatically runs CrossGen to create the native image for mscorlib.
-When this happens, you will find both `mscorlib.dll` and `mscorlib.ni.dll` in your output directory.
-`mscorlib.dll` is the MSIL assembly created by the C# compiler, while `mscorlib.ni.dll` is the native image that contains CPU-specific code.
-Once the build is done, you only need `mscorlib.ni.dll` to use CoreCLR.
-As a matter of fact, most CoreCLR NuGet packages contain only `mscorlib.ni.dll`, without `mscorlib.dll`
+In most cases, the build script automatically runs CrossGen to create the native image for `System.Private.CoreLib.dll` and `mscorlib.dll`.
+When this happens, you will find `System.Private.CoreLib.ni.dll` and `mscorlib.ni.dll` in your output directory.
+`System.Private.CoreLib.dll` and `mscorlib.dll` are the MSIL assemblies created by the C# compiler, while `System.Private.CoreLib.ni.dll` and `mscorlib.ni.dll` are the native images that contain CPU-specific code.
+Once the build is done, you only need `System.Private.CoreLib.ni.dll` and `mscorlib.ni.dll` to use CoreCLR.
+The original MSIL assemblies are no longer needed by the runtime.
-If for some reason you did not get `mscorlib.ni.dll` with the rest of your CoreCLR, you can easily create it yourself using CrossGen.
-First, make sure you have `crossgen.exe` (on Windows) or `crossgen` (other platforms) in the same directory as `mscorlib.dll`.
-Then, run one of the following two commands (first command for Windows, second command for other platforms):
+If you installed CoreCLR from a NuGet package, `System.Private.CoreLib.ni.dll` and `mscorlib.ni.dll` are included in the package.
+If for some reason you did not get `System.Private.CoreLib.dll` or `mscorlib.ni.dll` with the rest of your CoreCLR, you can easily create it yourself using CrossGen.
+
+If your `System.Private.CoreLib.dll`, `mscorlib.dll` and JIT compiler (`clrjit.dll` on Windows or `libclrjit.*` on other platforms) are all in the same directory as CrossGen itself, you can compile `System.Private.CoreLib.dll` and `mscorlib.dll` with the following commands (first two commands for Windows, next two commands for other platforms):
+
+ .\crossgen.exe System.Private.CoreLib.dll
.\crossgen.exe mscorlib.dll
+ ./crossgen System.Private.CoreLib.dll
./crossgen mscorlib.dll
-To create native images for other assemblies, the command line is slightly more complex:
+If your files are scattered in different directories, or if you want to create native images for other assemblies, the command line is slightly more complex:
- .\crossgen.exe /Platform_Assemblies_Paths "path1;path2;..." assemblyName.dll
- ./crossgen /Platform_Assemblies_Paths "path1:path2:..." assemblyName.dll
+ .\crossgen.exe /JITPath path\clrjit.dll /Platform_Assemblies_Paths "path1;path2;..." path\assemblyName.dll
+ ./crossgen -JITPath path/libclrjit.so -Platform_Assemblies_Paths "path1:path2:..." path/assemblyName.dll
-The /Platform_Assemblies_Paths is used to specify the location of all the dependencies of the input assembly.
-You should use full paths for this locations. Relative paths do not always work.
+The /Platform_Assemblies_Paths is used to specify the locations of all the dependencies of the input assembly, including the input assembly itself.
+You should use full paths for these locations. Relative paths do not always work.
If there are multiple paths, separate them with semicolons (`;`) on Windows, or colons (`:`) on non-Windows platforms.
It is generally a good idea to enclose the path list in quotes to protect any special characters from the shell.
@@ -53,14 +57,13 @@ Using native images
-------------------
Running CrossGen on an assembly creates a "native image" file, with the extension of `.ni.dll` or `.ni.exe`.
-You should include the native images in your app, at the same location where you normally install the MSIL assemblies.
-Once you have included native images, you do not need to include the original MSIL assemblies in your apps.
+You should include the native images in your app, either by replacing the original MSIL assmblies with the native images, or by putting the native images next to the MSIL assemblies.
+When the native images are present, CoreCLR runtime will automatically use it instead of the original MSIL assemblies.
Common errors
-------------
The following are some of the command errors while creating or using native images:
-- "Could not load file or assembly 'mscorlib.dll' or one of its dependencies. The native image could not be loaded, because it was generated for use by a different version of the runtime. (Exception from HRESULT: 0x80131059)": This error indicates that there is a mismatch between CrossGen and mscorlib.ni.dll. Make sure to use CrossGen and mscorlib.ni.dll from the same build or NuGet package.
- "Error: Could not load file or assembly '...' or one of its dependencies. The system cannot find the file specified. (Exception from HRESULT: 0x80070002)": CrossGen wasn't able to find a particular dependency that it needs. Verify that you have the assembly specified in the error message, and make sure its location is included in `/Platform_Assemblies_Paths`.
-- CoreCLR unable to initialize: While there are many possible causes of this error, one possibility is a mismatch between mscorlib.ni.dll and coreclr.dll (or libcoreclr.so). Make sure they come from the same build or NuGet package.
-- "Unable to load Jit Compiler": Please get a copy of `clrjit.dll` (or `libclrjit.so` or `libclrjit.dylib`, depending on your platform), and place it in the same directory as CrossGen. You can either build `clrjit.dll` yourself, or get it from `Microsoft.NETCore.Jit` NuGet package. To avoid possible issues, please use `clrjit.dll` from the same build as `crossgen.exe` if possible.
+- CoreCLR unable to initialize: While there are many possible causes of this error, one possibility is a mismatch between System.Private.CoreLib.ni.dll and coreclr.dll (or libcoreclr.so). Make sure they come from the same build or NuGet package.
+- "Unable to load Jit Compiler": Please get a copy of `clrjit.dll` (or `libclrjit.so` or `libclrjit.dylib`, depending on your platform), and place it in the same directory as CrossGen (or use /JITPath option). You can either build `clrjit.dll` yourself, or get it from `Microsoft.NETCore.Jit` NuGet package. To avoid possible issues, please use `clrjit.dll` from the same build as `crossgen.exe` if possible.
diff --git a/Documentation/building/linux-instructions.md b/Documentation/building/linux-instructions.md
index c948ecde20..ddd4274b83 100644
--- a/Documentation/building/linux-instructions.md
+++ b/Documentation/building/linux-instructions.md
@@ -47,6 +47,10 @@ ellismg@linux:~$ sudo apt-get install cmake llvm-3.5 clang-3.5 lldb-3.6 lldb-3.6
You now have all the required components.
+If you are using Fedora 23 or 24, then you will need to install the following packages:
+
+`$ sudo dnf install llvm cmake clang lldb-devel libunwind-devel lttng-ust-devel libuuid-devel libicu-devel`
+
Git Setup
---------
@@ -57,6 +61,10 @@ Set the maximum number of file-handles
To ensure that your system can allocate enough file-handles for the corefx build run `sysctl fs.file-max`. If it is less than 100000, add `fs.file-max = 100000` to `/etc/sysctl.conf`, and then run `sudo sysctl -p`.
+On Fedora 23 or 24:
+
+`$ sudo dnf install mono-devel`
+
Build the Runtime and Microsoft Core Library
=============================================
diff --git a/Documentation/building/osx-instructions.md b/Documentation/building/osx-instructions.md
index 6d3469b2d9..9e6b913675 100644
--- a/Documentation/building/osx-instructions.md
+++ b/Documentation/building/osx-instructions.md
@@ -51,7 +51,25 @@ The CoreFX cryptography libraries are built on OpenSSL. The version of OpenSSL i
```sh
brew install openssl
-brew link --force openssl
+
+# We need to make the runtime libraries discoverable, as well as make
+# pkg-config be able to find the headers and current ABI version.
+#
+# Ensure the paths we will need exist
+mkdir -p /usr/local/lib/pkgconfig
+
+# The rest of these instructions assume a default Homebrew path of
+# /usr/local/opt/<module>, with /usr/local being the answer to
+# `brew --prefix`.
+#
+# Runtime dependencies
+ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/
+ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/
+
+# Compile-time dependences (for pkg-config)
+ln -s /usr/local/opt/openssl/lib/pkgconfig/libcrypto.pc /usr/local/lib/pkgconfig/
+ln -s /usr/local/opt/openssl/lib/pkgconfig/libssl.pc /usr/local/lib/pkgconfig/
+ln -s /usr/local/opt/openssl/lib/pkgconfig/openssl.pc /usr/local/lib/pkgconfig/
```
Build the Runtime and Microsoft Core Library
diff --git a/Documentation/building/testing-with-corefx.md b/Documentation/building/testing-with-corefx.md
index 6609a0aaa7..4f9886f78d 100644
--- a/Documentation/building/testing-with-corefx.md
+++ b/Documentation/building/testing-with-corefx.md
@@ -7,7 +7,11 @@ It may be valuable to use CoreFX tests to validate your changes to CoreCLR or ms
As part of building tests, CoreFX restores a copy of the runtime from myget, in order to update the runtime that is deployed, a special build property `BUILDTOOLS_OVERRIDE_RUNTIME` can be used. If this is set, the CoreFX testing targets will copy all the files in the folder it points to into the test folder, overwriting any files that exist.
-To run tests, follow the procedure for [running tests in CoreFX](https://github.com/dotnet/corefx/blob/master/Documentation/building/windows-instructions.md). You can pass `/p:BUILDTOOLS_OVERRIDE_RUNTIME=<path-to-coreclr>\bin\Product\Windows_NT.x64.Release` to build.cmd to set this property.
+To run tests, follow the procedure for [running tests in CoreFX](https://github.com/dotnet/corefx/blob/master/Documentation/building/windows-instructions.md). You can pass `/p:BUILDTOOLS_OVERRIDE_RUNTIME=<path-to-coreclr>\bin\Product\Windows_NT.x64.Release` to build.cmd to set this property, e.g. (note the space between the "--" and the "/p" option):
+
+```
+build.cmd -Release -- /p:BUILDTOOLS_OVERRIDE_RUNTIME=<root of coreclr repo>\bin\Product\Windows_NT.x64.Checked
+```
**FreeBSD, Linux, NetBSD, OS X**
diff --git a/Documentation/building/viewing-jit-dumps.md b/Documentation/building/viewing-jit-dumps.md
index 5303b47626..607c5e63a0 100644
--- a/Documentation/building/viewing-jit-dumps.md
+++ b/Documentation/building/viewing-jit-dumps.md
@@ -35,7 +35,7 @@ The first thing we want to do is setup the .NET Core app we want to dump. Here a
}
```
-You can find a list of RIDs and their corresponding OSes [here](http://dotnet.github.io/docs/core-concepts/rid-catalog.html).
+You can find a list of RIDs and their corresponding OSes [here](https://docs.microsoft.com/en-us/dotnet/articles/core/rid-catalog).
* Edit `Program.cs`, and call the method(s) you want to dump in there. Make sure they are, directly or indirectly, called from `Main`. In this example, we'll be looking at the disassembly of our custom function `InefficientJoin`:
diff --git a/Documentation/building/windows-instructions.md b/Documentation/building/windows-instructions.md
index f68ed2c8c7..8ba021bbf9 100644
--- a/Documentation/building/windows-instructions.md
+++ b/Documentation/building/windows-instructions.md
@@ -1,21 +1,19 @@
Build CoreCLR on Windows
========================
-These instructions will lead you through building CoreCLR and running a "Hello World" demo on Windows.
+These instructions will lead you through building CoreCLR.
-Environment
-===========
+----------------
+#Environment
You must install several components to build the CoreCLR and CoreFX repos. These instructions were tested on Windows 7+.
-Visual Studio
--------------
+## Visual Studio
Visual Studio must be installed. Supported versions:
+- [Visual Studio 2015](https://www.visualstudio.com/downloads/visual-studio-2015-downloads-vs) (Community, Professional, Enterprise). The community version is completely free.
-- [Visual Studio 2015](https://www.visualstudio.com/downloads/visual-studio-2015-downloads-vs) (Community, Professional, Enterprise)
-
-To debug managed code, ensure you have installed atleast [Visual Studio 2015 Update 3](https://www.visualstudio.com/en-us/news/releasenotes/vs2015-update3-vs).
+To debug managed code, ensure you have installed at least [Visual Studio 2015 Update 3](https://www.visualstudio.com/en-us/news/releasenotes/vs2015-update3-vs).
Make sure that you install "VC++ Tools". By default, they will not be installed.
@@ -23,166 +21,100 @@ To build for Arm32, you need to have [Windows SDK for Windows 10](https://develo
Visual Studio Express is not supported.
-CMake
------
+##CMake
The CoreCLR repo build has been validated using CMake 3.5.2.
- Install [CMake](http://www.cmake.org/download) for Windows.
-- Add it to the PATH environment variable.
+- Add its location (e.g. C:\Program Files (x86)\CMake\bin) to the PATH environment variable.
+ The installation script has a check box to do this, but you can do it yourself after the fact
+ following the instructions at [Adding to the Default PATH variable](#adding-to-the-default-path-variable)
+
+
+##Python
-Python
----------
Python is used in the build system. We are currently using python 2.7.9, although
any recent (2.4+) version of Python should work, including Python 3.
- Install [Python](https://www.python.org/downloads/) for Windows.
-- Add it to the PATH environment variable.
-
-PowerShell
-----------
-PowerShell is used in the build system. Ensure that it is accessible via the PATH environment variable. Typically this is %SYSTEMROOT%\System32\WindowsPowerShell\v1.0\.
+- Add its location (e.g. C:\Python*\) to the PATH environment variable.
+ The installation script has a check box to do this, but you can do it yourself after the fact
+ following the instructions at [Adding to the Default PATH variable](#adding-to-the-default-path-variable)
-Powershell version must be 3.0 or higher. This should be the case for Windows 8 and later builds.
-- Windows 7 SP1 can install Powershell version 4 [here](https://www.microsoft.com/en-us/download/details.aspx?id=40855).
+##Git
-Git Setup
----------
+For actual user operations, it is often more convinient to use the GIT features built into Visual Studio 2015.
+However the CoreCLR and the tests use the GIT command line utilities directly so you need to install them
+for these to work properly. You can get it from
-Clone the CoreCLR and CoreFX repositories (either upstream or a fork).
+- Install [Git For Windows](https://git-for-windows.github.io/)
+- Add its location (e.g. C:\Program Files\Git\cmd) to the PATH environment variable.
+ The installation script has a check box to do this, but you can do it yourself after the fact
+ following the instructions at [Adding to the Default PATH variable](#adding-to-the-default-path-variable)
-```bat
-C:\git>git clone https://github.com/dotnet/coreclr
-C:\git>git clone https://github.com/dotnet/corefx
-```
+##PowerShell
+PowerShell is used in the build system. Ensure that it is accessible via the PATH environment variable.
+Typically this is %SYSTEMROOT%\System32\WindowsPowerShell\v1.0\.
-This guide assumes that you've cloned the CoreCLR and CoreFX repositories into C:\git using the default repo names. If your setup is different, you'll need to pay attention to the commands you run. The guide will always show you the current directory.
+Powershell version must be 3.0 or higher. This should be the case for Windows 8 and later builds.
+- Windows 7 SP1 can install Powershell version 4 [here](https://www.microsoft.com/en-us/download/details.aspx?id=40855).
-The repository is configured to allow Git to make the right decision about handling CRLF. Specifically, if you are working on **Windows**, please ensure that **core.autocrlf** is set to **true**. On **non-Windows** platforms, please set it to **input**.
+##DotNet Core SDK
+While not strictly needed to build or tests the .NET Core repository, having the .NET Core SDK installed lets
+you use the dotnet.exe command to run .NET Core applications in the 'normal' way. We use this in the
+[Using Your Build](Documentation/workflow/UsingYourBuild.md) instructions. Visual Studio 2015 (update 3) should have
+installed the .NET Core SDK, but in case it did not you can get it from the [Installing the .Net Core SDK](https://www.microsoft.com/net/core) page.
-Demo directory
---------------
+##Adding to the default PATH variable
-In order to keep everything tidy, create a new directory for the files that you will build or acquire.
+The commands above need to be on your command lookup path. Some installers will automatically add them to
+the path as part of installation, but if not here is how you can do it.
-```bat
-c:\git>mkdir \coreclr-demo\runtime
-c:\git>mkdir \coreclr-demo\ref
+You can of course add a directory to the PATH environment variable with the syntax
+```
+ set PATH=%PATH%;DIRECTORY_TO_ADD_TO_PATH
```
+However the change above will only last until the command windows closes. You can make your change to
+the PATH variable persistent by going to Control Panel -> System And Security -> System -> Advanced system settings -> Environment Variables,
+and select the 'Path' variable in the 'System variables' (if you want to change it for all users) or 'User variables' (if you only want
+to change it for the currnet user). Simply edit the PATH variable's value and add the directory (with a semicolon separator).
-Build the Runtime
-=================
+-------------------------------------
+#Building
-To build CoreCLR, run `build.cmd` from the root of the coreclr repository. This will do a x64/Debug build of CoreCLR, its native components, mscorlib.dll, and the tests.
+Once all the necessary tools are in place, building is trivial. Simply run build build.cmd script that lives at
+the base of the repository.
- C:\git\coreclr>build -rebuild
+```bat
+ .\build
[Lots of build spew]
- Repo successfully built.
-
Product binaries are available at C:\git\coreclr\bin\Product\Windows_NT.x64.debug
Test binaries are available at C:\git\coreclr\bin\tests\Windows_NT.x64.debug
+```
-**Note:** To avoid building the tests, pass the 'skiptestbuild' option to build.
-
-**build -?** will list supported parameters.
-
-Check the build output.
+As shown above the product will be placed in
- Product binaries will be dropped in `bin\Product\<OS>.<arch>.<flavor>` folder.
- A NuGet package, Microsoft.Dotnet.CoreCLR, will be created under `bin\Product\<OS>.<arch>.<flavor>\.nuget` folder.
- Test binaries will be dropped under `bin\Tests\<OS>.<arch>.<flavor>` folder
-You will see several files. The interesting ones are:
-
-- `corerun`: The command line host. This program loads and starts the CoreCLR runtime and passes the managed program you want to run to it.
-- `coreclr.dll`: The CoreCLR runtime itself.
-- `mscorlib.dll`: The core managed library for CoreCLR, which contains all of the fundamental data types and functionality.
-
-Copy these files into the demo directory.
-
-```bat
-C:\git\coreclr>copy bin\Product\Windows_NT.x64.debug\clrjit.dll \coreclr-demo\runtime
-C:\git\coreclr>copy bin\Product\Windows_NT.x64.debug\CoreRun.exe \coreclr-demo\runtime
-C:\git\coreclr>copy bin\Product\Windows_NT.x64.debug\coreclr.dll \coreclr-demo\runtime
-C:\git\coreclr>copy bin\Product\Windows_NT.x64.debug\mscorlib.dll \coreclr-demo\runtime
-C:\git\coreclr>copy bin\Product\Windows_NT.x64.debug\System.Private.CoreLib.dll \coreclr-demo\runtime
-```
-
-Build the Framework
-===================
-
-Build the framework out of the corefx directory.
+By default build generates a 'Debug' build type, that has extra checking (assert) compiled into it. You can
+also build the 'release' version which does not have these checks
- c:\git\corefx>build.cmd
+The build places logs in `bin\Logs` and these are useful when the build fails.
- [Lots of build spew]
-
- 0 Warning(s)
- 0 Error(s)
- Time Elapsed 00:03:14.53
- Build Exit Code = 0
-
-It's also possible to add -rebuild to build.cmd to force it to delete the previously built assemblies.
-
-For the purposes of this demo, you need to copy a few required assemblies to the demo folder.
-
-```bat
-C:\git\corefx>copy bin\Windows_NT.AnyCPU.Debug\System.Console\System.Console.dll \coreclr-demo\runtime
-C:\git\corefx>copy bin\Windows_NT.AnyCPU.Debug\System.Diagnostics.Debug\System.Diagnostics.Debug.dll \coreclr-demo\runtime
-C:\git\corefx>copy bin\AnyOS.AnyCPU.Debug\System.IO\System.IO.dll \coreclr-demo\runtime
-C:\git\corefx>copy bin\AnyOS.AnyCPU.Debug\System.IO.FileSystem.Primitives\System.IO.FileSystem.Primitives.dll \coreclr-demo\runtime
-C:\git\corefx>copy bin\AnyOS.AnyCPU.Debug\System.Runtime\System.Runtime.dll \coreclr-demo\runtime
-C:\git\corefx>copy bin\AnyOS.AnyCPU.Debug\System.Runtime.InteropServices\System.Runtime.InteropServices.dll \coreclr-demo\runtime
-C:\git\corefx>copy bin\AnyOS.AnyCPU.Debug\System.Text.Encoding\System.Text.Encoding.dll \coreclr-demo\runtime
-C:\git\corefx>copy bin\AnyOS.AnyCPU.Debug\System.Text.Encoding.Extensions\System.Text.Encoding.Extensions.dll \coreclr-demo\runtime
-C:\git\corefx>copy bin\AnyOS.AnyCPU.Debug\System.Threading\System.Threading.dll \coreclr-demo\runtime
-C:\git\corefx>copy bin\AnyOS.AnyCPU.Debug\System.Threading.Tasks\System.Threading.Tasks.dll \coreclr-demo\runtime
-```
-
-You also need to copy reference assemblies, which will be used during compilation.
-
-```bat
-C:\git\corefx>copy bin\ref\System.Runtime\4.0.0.0\System.Runtime.dll \coreclr-demo\ref
-C:\git\corefx>copy bin\ref\System.Console\4.0.0.0\System.Console.dll \coreclr-demo\ref
-```
-
-Compile the Demo
-================
+The build places all of its output in the `bin` directory, so if you remove that directory you can force a
+full rebuild.
-Now you need a Hello World application to run. You can write your own, if you'd like. Here's a very simple one:
+Build has a number of options that you can learn about using build -?. Some of the more important options are
-```C#
-using System;
+ * skiptests - don't build the tests. This can shorten build times quite a bit, but means you can't run tests.
+ * release - build the 'Release' build type that does not have extra development-time checking compiled in.
+ * -rebuild - force the build not to be incremental but to recompile everything.
+ You want this if you are going to do performance testing on your build.
-public class Program
-{
- public static void Main()
- {
- Console.WriteLine("Hello, Windows");
- Console.WriteLine("Love from CoreCLR.");
- }
-}
-```
-
-Personally, I'm partial to the one on corefxlab which will print a picture for you. Download the [corefxlab demo](https://raw.githubusercontent.com/dotnet/corefxlab/master/demos/CoreClrConsoleApplications/HelloWorld/HelloWorld.cs) to `\coreclr-demo`.
-
-Then you just need to build it, with csc, the .NET Framework C# compiler. It may be easier to do this step within the "Developer Command Prompt for VS2015", if csc is not in your path. Because you need to compile the app against the .NET Core surface area, you need to pass references to the contract assemblies you restored using NuGet:
-
-```bat
-csc /nostdlib /noconfig /r:ref\System.Runtime.dll /r:ref\System.Console.dll /out:runtime\hello.exe hello.cs
-```
-
-Run the demo
-============
-
-You're ready to run Hello World! To do that, run corerun, passing the path to the managed exe, plus any arguments. In this case, no arguments are necessary.
-
-```bat
-C:\coreclr-demo>cd runtime
-C:\coreclr-demo\runtime>CoreRun.exe hello.exe
-```
+See [Using Your Build](../workflow/UsingYourBuild.md) for instructions on running code with your build.
-If `CoreRun.exe` fails for some reason, you will see an empty output. To diagnose the issue, you can use `/v` to switch verbose mode on: `CoreRun.exe /v hello.exe`.
+See [Running Tests](../workflow/RunningTests.md) for instructions on running the tests.
-Over time, this process will get easier. Thanks for trying out CoreCLR. Feel free to try a more interesting demo.
diff --git a/Documentation/coding-guidelines/clr-code-guide.md b/Documentation/coding-guidelines/clr-code-guide.md
index 84ba5f2321..c1f69b04d2 100644
--- a/Documentation/coding-guidelines/clr-code-guide.md
+++ b/Documentation/coding-guidelines/clr-code-guide.md
@@ -27,7 +27,7 @@ Written in 2006, by:
* [2.1.10 How to know if a function can trigger a GC](#2.1.10)
* [2.1.10.1 GC_NOTRIGGER/TRIGGERSGC on a scope](#2.1.10.1)
* [2.2 Are you using holders to track your resources?](#2.2)
- * [2.2.1 What are holders and we are they important?](#2.2.1)
+ * [2.2.1 What are holders and why are they important?](#2.2.1)
* [2.2.2 An example of holder usage:](#2.2.2)
* [2.2.3 Common Features of Holders](#2.2.3)
* [2.2.4 Where do I find a holder?](#2.2.4)
@@ -462,7 +462,7 @@ One difference between the standalone TRIGGERSGC and the contract GC_TRIGGERS: t
## <a name="2.2"/>2.2 Are you using holders to track your resources?
-### <a name="2.2.1"/>2.2.1 What are holders and we are they important?
+### <a name="2.2.1"/>2.2.1 What are holders and why are they important?
The CLR team has coined the name **holder** to refer to the infrastructure that encapsulates the common grunt work of writing robust **backout code**. **Backout code** is code that deallocate resources or restore CLR data structure consistency when we abort an operation due to an error or an asynchronous event. Oftentimes, the same backout code will execute in non-error paths for resources allocated for use of a single scope, but error-time backout is still needed even for longer lived resources.
@@ -616,6 +616,7 @@ Holders consistently release on destruction – that's their whole purpose. Sadl
#### <a name="2.2.8.4"/>2.2.8.4 Critical Section Holder
**Wrong:**
+
pCrst->Enter();
pCrst->Leave();
diff --git a/Documentation/design-docs/multi-reg-call-nodes.md b/Documentation/design-docs/multi-reg-call-nodes.md
new file mode 100644
index 0000000000..e89ca2af62
--- /dev/null
+++ b/Documentation/design-docs/multi-reg-call-nodes.md
@@ -0,0 +1,230 @@
+Support for multiple destination regs, GT_CALL and GT_RETURN nodes that return a value in multiple registers:
+============================================================================================================
+
+The following targets allow a GT_CALL/GT_RETURN node to return a value in more than one register:
+
+x64 Unix:
+Structs of size betwee 9-16 bytes will be returned in RAX/RDX and/or XMM0/XMM1.
+
+Arm64:
+HFA structs will be returned in 1-4 successive VFP registers s0-s3 or d0-d3.
+Structs of size 16-bytes will be returned in two return registers.
+
+Arm32:
+Long type value is returned in two return registers r0 and r1.
+HFA structs will be returned in 1-4 successive VFP registers s0-s3 or d0-d3
+
+x86:
+Long type value is returned in two return registers EDX and EAX.
+
+Legacy backend used reg-pairs for representing long return value on 32-bit targets, which makes reg allocation and codegen complex. Also this approach doesn't scale well to types that are returned in more than 2 registers. Arm32 HFA support in Legacy backend requires that HFA return value of a call is always stored to local in memory and with the local marked as not promotable. Original implementation of multi-reg return of structs on x64 Unix was similar to Arm32 and further LSRA was not ware of multi-reg call nodes because of which Codegen made some assumptions (e.g. multi-reg return value of a call node is never spilled) that are not always guaranteed.
+
+This doc proposes new IR forms and an implementation design to support multi-reg call nodes in RyuJIT that is scalable without the limitations/complexity that Legacy backend implementation had.
+
+Post Importation IR Forms
+-------------------------
+In importer any call returning a (struct or long type) value in two or more registers is forced to a temp
+and temp is used in place of call node subsequently in IR. Note that creation of 'tmp' is avoided if return value of call is getting assigned to a local in IL.
+
+```
+// tmp = GT_CALL, where tmp is of TYP_STRUCT or TYP_LONG
+GT_ASG(TYP_STRUCT or TYP_LONG, tmp, GT_CALL node)
+```
+
+Similarly importer will force IR of GT_RETURN node returning a value in multiple return registers to be
+of the following form if operand of GT_RETURN is anything but a lclVar.
+
+```
+GT_ASG(TYP_STRUCT or TYP_LONG, tmp, op1)
+GT_RETURN(tmp)
+```
+
+Post struct promotion IR forms
+------------------------------
+Before global morph of basic blocks, struct promotion takes place. It will give rise to the following
+three cases:
+
+Case 1:
+tmp is not struct promoted or Type Dependently Promoted (P-DEP).
+
+Case 2:
+tmp is Type Independently Promoted (P-INDEP) but its field layout doesn't match the layout of return registers or tmp is P-FULL promoted struct (e.g. SIMD type structs).
+
+For example, tmp could be a struct of 4 integers. But on x64 unix, two fields of such a struct
+will be returned in one 8-byte return register.
+
+Case 3:
+tmp is P-INDEP promoted and its field layout matches the layout of return registers. That is one promoted field will get mapped to a single, un-shared register in the ABI for returning values.
+An example is a struct containing two fields of `{TYP_REF, TYP_DOUBLE} `on X64 Unix.
+
+Post Global Morph, IR forms of tmp=GT_CALL where tmp is of TYP_STRUCT
+---------------------------------------------------------------------
+Case 3 is morphed into
+
+ `GT_STORE_MULTI_VAR(TYP_STRUCT, <FieldLcl1, FieldLcl2, FieldLcl3, FieldLcl4>, op1 = GT_CALL)`
+
+ Where FieldLcl[1..4] are lcl numbers of P-INDEP promoted fields of tmp. The limit of 2-4 locals
+ is statically dependent on target platform/architecture.
+
+ GT_STORE_MULTI_VAR is a new GenTree node to represent the store operation to 2-4 locals
+ using multi-reg/mem value of a call/lclvar respectively. It also will have additional fields
+ to store the registers into which FieldLcl[1..4] need to be stored and also a spill mask
+ to indicate which of the locals needs to be spilled.
+
+ During codegen, return value of call in multiple return registers need to be stored to the
+ corresponding registers of the locals by properly handling any circular dependencies.
+
+Case 1 is morphed as
+ `GT_OBJ(&tmp) = GT_CALL`
+
+ Post rationalization this will get converted to GT_STORE_OBJ/BLK(&tmp, GT_CALL) and
+ block op codegen will special case for multi-reg call case. This case simpler because, although it is
+ consuming multiple registers from the call, it doesn't have the complication of multiple
+ destination registers.
+
+Case 2 can be handled one of the following two ways
+ a) Force tmp to memory and morph it as in case 1 above
+ b) Create 2-4 temp locals matching the type of respective return registers of GT_CALL and
+ use them to create following IR
+
+```
+GT_STORE_MULTI_VAR(TYP_STRUCT, <tmpLcl1, tmpLcl2, tmpLcl3, tmpLcl4>, op1 = GT_CALL)
+```
+
+ Example: say on x64 unix, return type is a struct with 3 fields: TYP_INT, TYP_INT and TYP_REF.
+ First two fields would be combined into a single local of TYP_LONG and third field would
+ would go into a single local of TYP_REF.
+
+ Additional IR nodes can be created to extract/assemble fields of tmp struct from individual tmpLcls.
+
+Platform agnostic ReturnTypeDesc on a GT_CALL node
+--------------------------------------------------
+Every GT_CALL node will have a light-weight ReturnTypeDesc that provides a platform independent interface to query the following:
+ - Respective return types of a multi-reg return value
+ - Respective Return register numbers in which the value is returned.
+
+ReturnTypeDesc is initialized during importation while creating GenTreeCall node.
+
+GT_CALL node is augmented with the following additional state:
+ gtOtherRegs - an array of MAX_RET_REG_COUNT-1 reg numbers of multi-reg return. gtRegNum field
+ will always be the first return reg.
+ gtSpillFlags - an array to hold GTF_SPILL/GTF_SPILLED state of each reg. This allows us to
+ spill/reload individual return registers of a multi-reg call node work.
+
+Post Global Morph, IR forms of GT_RETURN(tmp) where tmp is of TYP_STRUCT
+------------------------------------------------------------------------
+Case 3 is morphed into
+
+```
+ GT_RETURN (TYP_STRUCT, op1 = GT_MULTI_VAR(TYP_STRUCT, <Fieldlcl1, FieldLcl2, FieldLcl3, FieldLcl4>))
+```
+
+ Where FieldLcl[1..4] are lcl numbers of independently promoted fields of tmp and
+ GT_MULTI_VAR is a new node that represents 2-4 independent local vars.
+
+Case 1 remains unchanged
+
+ `GT_RETURN(TYP_STRUCT, op1 = tmp)`
+
+Case 2 is handled as follows:
+ a) Force tmp to memory and morph it as in case 1 above
+ b) Create 2-4 temp locals matching the type of respective return registers of GT_RETURN and
+ use them to extract individual fields from tmp and morph it as in case 3 above.
+
+ tmpLcl1 = GenTree Nodes to extract first 8-bytes from tmp
+ tmpLcl2 = GenTree Nodes to extract next 8-bytes from tmp and so on
+
+```
+ GT_RETURN(TYP_STRUCT, op1 = GT_STORE_MULTI_VAR(TYP_STRUCT, <tmpLcl1, tmpLcl2, tmpLcl3, tmpLcl4>, tmp))
+```
+
+
+Post Lowering, IR forms of GT_CALL node returning TYP_LONG value
+----------------------------------------------------------------
+During Lowering, such call nodes are lowered into tmp=GT_CALL if the return value of call node is not already assigned to a local. Further tmp is decomposed into GT_LONG.
+
+Post IR lowering, GT_CALL will be transformed into
+
+```
+ GT_STORE_LCL_VAR(TYP_LONG, lcl Num of tmp, op1 = GT_CALL)
+```
+
+ where tmp is decomposed into GT_LONG(GT_LCL_VAR(tmpHi), GT_LCL_VAR(tmpLo))
+ and finally GT_STORE_LCL_VAR is transformed into
+
+```
+ GT_STORE_MULTI_VAR(TYP_LONG, <tmpHi, tmpLo>, op1=GT_CALL)
+```
+
+ where tmpHi and tmpLo are promoted lcl fields of tmp.
+
+Post Lowering, IR forms of GT_RETURN(tmp) where tmp is of TYP_LONG
+------------------------------------------------------------------
+LclVar tmp will be decomposed into two locals and the resulting IR would be GT_RETURN(GT_LONG)
+
+Lowering Register specification
+--------------------------------
+DstCount of GT_CALL node returning multi-reg return value will be set to 2 or 3 or 4 depending on the number of return registers and its dstCandidates is set to the fixed mask of return registers.
+
+SrcCount and DstCount of GT_STORE_MULTI_VAR will be set 2 or 3 or 4 depending on the number of locals to which a value is assigned. Note that those locals that do not require a value to be assigned are represented as BAD_VAR_NUM.
+
+SrcCount of GT_RETURN returning a multi-reg value will be set to 2 or 3 or 4 depending on the number of return registers.
+
+LSRA Considerations
+-------------------
+LSRA needs to add support for multi-reg destination GT_CALL, GT_MULTI_VAR and GT_STORE_MULTI_VAR nodes.
+
+Codegen Considerations
+----------------------
+genProduceReg()/genConsumeReg() code paths need to support mullti-reg destination GT_CALL, GT_MULTI_VAR and GT_STORE_MULTI_VAR nodes.
+
+GT_RETURN(tmp) where tmp is of TYP_STRUCT
+ - tmp would either be in memory GT_LCL_VAR or GT_MULTI_VAR of TYP_STRUCT
+
+GT_RETURN(op1) where op1 is of TYP_LONG
+ - op1 should be always of the form GT_LONG(tmpLclHi, tmpLclLo)
+
+
+Sub work items
+--------------
+
+The following are the sub work items and against each is indicated its current status:
+
+1. (Done) Refactor code to abstract structDesc field of GenTreeCall node
+ReturnTypeDesc would abstract away existing structDesc (x64 unix) and implement
+an API and replace all uses of structDesc of call node with the API. This would be
+a pure code refactoring with the addition of ReturnTypeDesc on a GenTreeCall node.
+
+2. (Done) Get rid of structDesc and replace it with ReturnTypeDesc.
+Note that on x64 Unix, we still query structDesc from VM and use it to initialize ReturnTypeDesc.
+
+3. (Done) Phase 1 Implementation of multi-reg GT_CALL/GT_RETURN node support for x64 Unix
+ - Importer changes to force IR to be of the form tmp=call always for multi-reg call nodes
+ - Importer changes to force IR to be of the form GT_RETURN(tmp) always for multi-reg return
+ - tmp will always be an in memory lcl var.
+ - Till First class struct support for GT_OBJ/GT_STORE_OBJ comes on-line IR will be of the form
+
+ `GT_STORE_LCL_VAR(tmpLcl, op1 = GT_CALL)`
+
+ where tmpLcl will always be an in memory lcl var of TYP_STRUCT
+ - Lowering/LSRA/Codegen support to allocate multiple regs to GT_CALL nodes.
+ - GT_CALL nodes will be governed by a single spill flag i.e. all return registers are spilled together.
+ - GT_RETURN(tmp) - lowering will mark op1=tmp as contained and generate code as existing code does.
+
+4. Phase 2 implementation of multi-reg GT_CALL/GT_RETURN node support for x64 unix
+ - Add new gentree nodes GT_MULTI_VAR and GT_STORE_MULTI_VAR and plumb through rest of JIT phases.
+ - Global morph code changes to support Case 3 (i.e P-DEP promoted structs)
+ - Lowering/LSRA/Codegen changes to support GT_MULTI_VAR and GT_STORE_MULTI_VAR
+
+5. When First class structs support comes on-line, leverage GT_OBJ/GT_STORE_OBJ to store multi-reg
+return value of a GT_CALL node to memory cleaning up the code in GT_STORE_LCL_VAR.
+
+6. (Done) HFA and multi-reg struct return support for Arm64
+
+7. (Done) x86 long return support
+
+8. (Optimization) Phase 3 implementation of multi-reg GT_CALL/GT_RETURN node support for x64 unix
+ - Global morph code changes to support some of the important Case 2 efficiently
+
+9. HFA struct and long return support for Arm32 RyuJIT - we should be able to leverage x86 long return and Arm64 HFA struct return work here.
+
diff --git a/Documentation/project-docs/adding_new_public_apis.md b/Documentation/project-docs/adding_new_public_apis.md
index dbf305d542..289ba7de77 100644
--- a/Documentation/project-docs/adding_new_public_apis.md
+++ b/Documentation/project-docs/adding_new_public_apis.md
@@ -1,26 +1,25 @@
-Adding new public APIs to mscorlib
-==================================
+Adding new public APIs to System.Private.CoreLib
+================================================
-Many of the CoreFX libraries type-forward their public APIs to the implementations in mscorlib.
-- The CoreFX build uses published contracts for mscorlib, and the CoreFX test build uses published contracts for some of the CoreFX libraries.
-- Some of the CoreFX libraries are not built in the CoreFX repository. For example, System.Runtime.Loader.dll is purely a facade and type-forwards everything to mscorlib. These libraries are built and published through a separate process.
-- Hence, when adding a new public API to mscorlib, changes must be staged to ensure that new prerequisites are published before they are used.
+Many of the CoreFX libraries type-forward their public APIs to the implementations in System.Private.CoreLib.
+- The CoreFX build uses System.Private.CoreLib via Microsoft.TargetingPack.Private.CoreCLR Nuget package.
+- Some of the CoreFX libraries are not built in the CoreFX repository. For example, System.Runtime.Loader.dll is purely a facade and type-forwards everything to System.Private.CoreLib. These libraries are built and published through a separate process.
+- Hence, when adding a new public API to System.Private.CoreLib, changes must be staged to ensure that new prerequisites are published before they are used.
**Staging the changes**
-Make the changes to CoreCLR, including mscorlib
+Make the changes to CoreCLR, including System.Private.CoreLib
- Update `coreclr/src/mscorlib/model.xml` with the new APIs. APIs that are not listed in this file will be stripped out prior to publishing.
-- Note that at the moment, merging changes with new public APIs will cause an internal build failure. Please work with your PR reviewer to have these build breaks be fixed soon after merging, otherwise it will block the publishing process.
- Merge the changes
-- Wait for a new mscorlib contract to be published. Check the latest published version [here](http://myget.org/gallery/dotnet-core).
+- Wait for a new System.Private.CoreLib to be published. Check the latest published version [here](https://dotnet.myget.org/feed/dotnet-core/package/nuget/Microsoft.TargetingPack.Private.CoreCLR).
-Make the changes to CoreFX consuming the new APIs in mscorlib
+Make the changes to CoreFX consuming the new APIs in System.Private.CoreLib
- If the changes are to libraries that are built out of the CoreFX repository:
- - You will likely see a build failure until a new mscorlib contract is published
+ - You will likely see a build failure until a new System.Private.CoreLib contract is published
- If the changes are to libraries that are **not** built out of the CoreFX repository:
- For example, pure facades such as System.Runtime.Loader.dll
- There will likely not be a build failure
- - But you will still need to wait for the new mscorlib contract to be published before merging the change, otherwise, facade generation will fail
+ - But you will still need to wait for the new System.Private.CoreLib contract to be published before merging the change, otherwise, facade generation will fail
- Merge the changes
- Wait for new contracts to be published for libraries with new APIs. Check the latest published versions [here](http://myget.org/gallery/dotnet-core).
diff --git a/Documentation/project-docs/ci-trigger-phrases.md b/Documentation/project-docs/ci-trigger-phrases.md
index 3652565498..03e071d79d 100644
--- a/Documentation/project-docs/ci-trigger-phrases.md
+++ b/Documentation/project-docs/ci-trigger-phrases.md
@@ -3,6 +3,8 @@
When submitting a PR to the CoreCLR repo, you may want to run more test suites than are included in the default set of checks run with each PR. In this document you will find a list of all possible jobs to trigger, as well as the phrase that will trigger that job.
+You can also ask the CI system to show you all to available trigger phrases by using `@dotnet-bot help`.
+
These phrases are ordered by OS. They will usually be in the form of "{OS} {Architecture} {Configuration} {Scenario}", so use that format if you are trying to ctrl-f a certain job.
To trigger a job, post a comment on your PR with "@dotnet-bot {trigger-phrase}".
@@ -79,64 +81,64 @@ To trigger a job, post a comment on your PR with "@dotnet-bot {trigger-phrase}".
- **Windows_NT x64 Checked CoreFX JitStressRegs=8 Build & Test:** "test Windows_NT corefx_jitstressregs8"
- **Windows_NT x64 Checked CoreFX JitStressRegs=0x10 Build & Test:** "test Windows_NT corefx_jitstressregs0x10"
- **Windows_NT x64 Checked CoreFX JitStressRegs=0x80 Build & Test:** "test Windows_NT corefx_jitstressregs0x80"
-- **Windows_NT x86 RyuJit Checked Priority 0 Build & Test:** "test Windows_NT x86 ryujit"
+- **Windows_NT x86 Checked Priority 0 Build & Test:** "test Windows_NT x86"
- **Windows_NT x86 legacy_backend Checked Priority 0 Build & Test:** "test Windows_NT x86 legacy_backend"
-- **Windows_NT x86 RyuJit Release Ready-To-Run Priority 0 Build & Test:** "test Windows_NT x86 ryujit Release r2r"
+- **Windows_NT x86 Release Ready-To-Run Priority 0 Build & Test:** "test Windows_NT x86 Release r2r"
- **Windows_NT x86 legacy_backend Release Ready-To-Run Priority 0 Build & Test:** "test Windows_NT x86 legacy_backend Release r2r"
-- **Windows_NT x86 RyuJit Release Ready-To-Run Priority 1 Build & Test:** "test Windows_NT x86 ryujit Release pri1r2r"
+- **Windows_NT x86 Release Ready-To-Run Priority 1 Build & Test:** "test Windows_NT x86 Release pri1r2r"
- **Windows_NT x86 legacy_backend Release Ready-To-Run Priority 1 Build & Test:** "test Windows_NT x86 legacy_backend Release pri1r2r"
-- **Windows_NT x86 RyuJit Release GCStress=15 Ready-To-Run Priority 1 Build & Test:** "test Windows_NT x86 ryujit Release gcstress15_pri1r2r"
+- **Windows_NT x86 Release GCStress=15 Ready-To-Run Priority 1 Build & Test:** "test Windows_NT x86 Release gcstress15_pri1r2r"
- **Windows_NT x86 legacy_backend Release GCStress=15 Ready-To-Run Priority 1 Build & Test:** "test Windows_NT x86 legacy_backend Release gcstress15_pri1r2r"
-- **Windows_NT x86 RyuJit Release jitstress1 R2R Build & Test:** "test Windows_NT x86 ryujit Release jitstress1 R2R"
-- **Windows_NT x86 RyuJit Checked jitstress1 R2R Build & Test:** "test Windows_NT x86 ryujit Checked jitstress1 R2R"
-- **Windows_NT x86 RyuJit Release jitstress2 R2R Build & Test:** "test Windows_NT x86 ryujit Release jitstress2 R2R"
-- **Windows_NT x86 RyuJit Checked jitstress2 R2R Build & Test:** "test Windows_NT x86 ryujit Checked jitstress2 R2R"
-- **Windows_NT x86 RyuJit Release jitstressregs1 R2R Build & Test:** "test Windows_NT x86 ryujit Release jitstressregs1 R2R"
-- **Windows_NT x86 RyuJit Checked jitstressregs1 R2R Build & Test:** "test Windows_NT x86 ryujit Checked jitstressregs1 R2R"
-- **Windows_NT x86 RyuJit Release jitstressregs2 R2R Build & Test:** "test Windows_NT x86 ryujit Release jitstressregs2 R2R"
-- **Windows_NT x86 RyuJit Checked jitstressregs2 R2R Build & Test:** "test Windows_NT x86 ryujit Checked jitstressregs2 R2R"
-- **Windows_NT x86 RyuJit Release jitstressregs3 R2R Build & Test:** "test Windows_NT x86 ryujit Release jitstressregs3 R2R"
-- **Windows_NT x86 RyuJit Checked jitstressregs3 R2R Build & Test:** "test Windows_NT x86 ryujit Checked jitstressregs3 R2R"
-- **Windows_NT x86 RyuJit Release jitstressregs4 R2R Build & Test:** "test Windows_NT x86 ryujit Release jitstressregs4 R2R"
-- **Windows_NT x86 RyuJit Checked jitstressregs4 R2R Build & Test:** "test Windows_NT x86 ryujit Checked jitstressregs4 R2R"
-- **Windows_NT x86 RyuJit Release jitstressregs8 R2R Build & Test:** "test Windows_NT x86 ryujit Release jitstressregs8 R2R"
-- **Windows_NT x86 RyuJit Checked jitstressregs8 R2R Build & Test:** "test Windows_NT x86 ryujit Checked jitstressregs8 R2R"
-- **Windows_NT x86 RyuJit Release jitstressregsx10 R2R Build & Test:** "test Windows_NT x86 ryujit Release jitstressregsx10 R2R"
-- **Windows_NT x86 RyuJit Checked jitstressregsx10 R2R Build & Test:** "test Windows_NT x86 ryujit Checked jitstressregsx10 R2R"
-- **Windows_NT x86 RyuJit Release jitstressregsx80 R2R Build & Test:** "test Windows_NT x86 ryujit Release jitstressregsx80 R2R"
-- **Windows_NT x86 RyuJit Checked jitstressregsx80 R2R Build & Test:** "test Windows_NT x86 ryujit Checked jitstressregsx80 R2R"
-- **Windows_NT x86 RyuJit Release JITMinOpts R2R Build & Test:** "test Windows_NT x86 ryujit Release JITMinOpts R2R"
-- **Windows_NT x86 RyuJit Checked JITMinOpts R2R Build & Test:** "test Windows_NT x86 ryujit Checked JITMinOpts R2R"
-- **Windows_NT x86 RyuJit Release ForceRelocs R2R Build & Test:** "test Windows_NT x86 ryujit Release ForceRelocs R2R"
-- **Windows_NT x86 RyuJit Checked ForceRelocs R2R Build & Test:** "test Windows_NT x86 ryujit Checked ForceRelocs R2R"
-- **Windows_NT x86 RyuJit Checked JIT MinOpts Build & Test:** "test Windows_NT x86 ryujit minopts"
-- **Windows_NT x86 RyuJit Checked JITStress=1 Build & Test:** "test Windows_NT x86 ryujit jitstress1"
-- **Windows_NT x86 RyuJit Checked JITStress=2 Build & Test:** "test Windows_NT x86 ryujit jitstress2"
-- **Windows_NT x86 RyuJit Checked Jit ForceRelocs Build & Test:** "test Windows_NT x86 ryujit forcerelocs"
-- **Windows_NT x86 RyuJit Checked JITStressRegs=1 Build & Test:** "test Windows_NT x86 ryujit jitstressregs1"
-- **Windows_NT x86 RyuJit Checked JITStressRegs=2 Build & Test:** "test Windows_NT x86 ryujit jitstressregs2"
-- **Windows_NT x86 RyuJit Checked JITStressRegs=3 Build & Test:** "test Windows_NT x86 ryujit jitstressregs3"
-- **Windows_NT x86 RyuJit Checked JITStressRegs=4 Build & Test:** "test Windows_NT x86 ryujit jitstressregs4"
-- **Windows_NT x86 RyuJit Checked JITStressRegs=8 Build & Test:** "test Windows_NT x86 ryujit jitstressregs8"
-- **Windows_NT x86 RyuJit Checked JITStressRegs=0x10 Build & Test:** "test Windows_NT x86 ryujit jitstressregs0x10"
-- **Windows_NT x86 RyuJit Checked JITStressRegs=0x80 Build & Test:** "test Windows_NT x86 ryujit jitstressregs0x80"
-- **Windows_NT x86 RyuJit Checked JitStress=2 JITStressRegs=1 Build & Test:** "test Windows_NT x86 ryujit jitstress2_jitstressregs1"
-- **Windows_NT x86 RyuJit Checked JitStress=2 JITStressRegs=2 Build & Test:** "test Windows_NT x86 ryujit jitstress2_jitstressregs2"
-- **Windows_NT x86 RyuJit Checked JitStress=2 JITStressRegs=3 Build & Test:** "test Windows_NT x86 ryujit jitstress2_jitstressregs3"
-- **Windows_NT x86 RyuJit Checked JitStress=2 JITStressRegs=4 Build & Test:** "test Windows_NT x86 ryujit jitstress2_jitstressregs4"
-- **Windows_NT x86 RyuJit Checked JitStress=2 JITStressRegs=8 Build & Test:** "test Windows_NT x86 ryujit jitstress2_jitstressregs8"
-- **Windows_NT x86 RyuJit Checked JitStress=2 JITStressRegs=0x10 Build & Test:** "test Windows_NT x86 ryujit jitstress2_jitstressregs0x10"
-- **Windows_NT x86 RyuJit Checked JitStress=2 JITStressRegs=0x80 Build & Test:** "test Windows_NT x86 ryujit jitstress2_jitstressregs0x80"
-- **Windows_NT x86 RyuJit Checked GCStress=0x3 Build & Test:** "test Windows_NT x86 ryujit gcstress0x3"
-- **Windows_NT x86 RyuJit Checked GCStress=0xc Build & Test:** "test Windows_NT x86 ryujit gcstress0xc"
-- **Windows_NT x86 RyuJit Checked zapdisable Build & Test:** "test Windows_NT x86 ryujit zapdisable"
-- **Windows_NT x86 RyuJit Checked Heap Verify 1 Build & Test:** "test Windows_NT x86 ryujit heapverify1"
-- **Windows_NT x86 RyuJit Checked GCStress=0xc zapdisable Build & Test:** "test Windows_NT x86 ryujit gcstress0xc_zapdisable"
-- **Windows_NT x86 RyuJit Checked GCStress=0xc JitStress=2 zapdisable Build & Test:** "test Windows_NT x86 ryujit gcstress0xc_zapdisable_jitstress2"
-- **Windows_NT x86 RyuJit Checked GCStress=0xc zapdisable Heap Verify 1 Build & Test:** "test Windows_NT x86 ryujit gcstress0xc_zapdisable_heapverify1"
-- **Windows_NT x86 RyuJit Checked GCStress=0xc JitStress=1 Build & Test:** "test Windows_NT x86 ryujit gcstress0xc_jitstress1"
-- **Windows_NT x86 RyuJit Checked GCStress=0xc JitStress=2 Build & Test:** "test Windows_NT x86 ryujit gcstress0xc_jitstress2"
-- **Windows_NT x86 RyuJit Checked GCStress=0xc MinOpts Heap Verify 1 Build & Test:** "test Windows_NT x86 ryujit gcstress0xc_minopts_heapverify1"
+- **Windows_NT x86 Release jitstress1 R2R Build & Test:** "test Windows_NT x86 Release jitstress1 R2R"
+- **Windows_NT x86 Checked jitstress1 R2R Build & Test:** "test Windows_NT x86 Checked jitstress1 R2R"
+- **Windows_NT x86 Release jitstress2 R2R Build & Test:** "test Windows_NT x86 Release jitstress2 R2R"
+- **Windows_NT x86 Checked jitstress2 R2R Build & Test:** "test Windows_NT x86 Checked jitstress2 R2R"
+- **Windows_NT x86 Release jitstressregs1 R2R Build & Test:** "test Windows_NT x86 Release jitstressregs1 R2R"
+- **Windows_NT x86 Checked jitstressregs1 R2R Build & Test:** "test Windows_NT x86 Checked jitstressregs1 R2R"
+- **Windows_NT x86 Release jitstressregs2 R2R Build & Test:** "test Windows_NT x86 Release jitstressregs2 R2R"
+- **Windows_NT x86 Checked jitstressregs2 R2R Build & Test:** "test Windows_NT x86 Checked jitstressregs2 R2R"
+- **Windows_NT x86 Release jitstressregs3 R2R Build & Test:** "test Windows_NT x86 Release jitstressregs3 R2R"
+- **Windows_NT x86 Checked jitstressregs3 R2R Build & Test:** "test Windows_NT x86 Checked jitstressregs3 R2R"
+- **Windows_NT x86 Release jitstressregs4 R2R Build & Test:** "test Windows_NT x86 Release jitstressregs4 R2R"
+- **Windows_NT x86 Checked jitstressregs4 R2R Build & Test:** "test Windows_NT x86 Checked jitstressregs4 R2R"
+- **Windows_NT x86 Release jitstressregs8 R2R Build & Test:** "test Windows_NT x86 Release jitstressregs8 R2R"
+- **Windows_NT x86 Checked jitstressregs8 R2R Build & Test:** "test Windows_NT x86 Checked jitstressregs8 R2R"
+- **Windows_NT x86 Release jitstressregsx10 R2R Build & Test:** "test Windows_NT x86 Release jitstressregsx10 R2R"
+- **Windows_NT x86 Checked jitstressregsx10 R2R Build & Test:** "test Windows_NT x86 Checked jitstressregsx10 R2R"
+- **Windows_NT x86 Release jitstressregsx80 R2R Build & Test:** "test Windows_NT x86 Release jitstressregsx80 R2R"
+- **Windows_NT x86 Checked jitstressregsx80 R2R Build & Test:** "test Windows_NT x86 Checked jitstressregsx80 R2R"
+- **Windows_NT x86 Release JITMinOpts R2R Build & Test:** "test Windows_NT x86 Release JITMinOpts R2R"
+- **Windows_NT x86 Checked JITMinOpts R2R Build & Test:** "test Windows_NT x86 Checked JITMinOpts R2R"
+- **Windows_NT x86 Release ForceRelocs R2R Build & Test:** "test Windows_NT x86 Release ForceRelocs R2R"
+- **Windows_NT x86 Checked ForceRelocs R2R Build & Test:** "test Windows_NT x86 Checked ForceRelocs R2R"
+- **Windows_NT x86 Checked JIT MinOpts Build & Test:** "test Windows_NT x86 minopts"
+- **Windows_NT x86 Checked JITStress=1 Build & Test:** "test Windows_NT x86 jitstress1"
+- **Windows_NT x86 Checked JITStress=2 Build & Test:** "test Windows_NT x86 jitstress2"
+- **Windows_NT x86 Checked Jit ForceRelocs Build & Test:** "test Windows_NT x86 forcerelocs"
+- **Windows_NT x86 Checked JITStressRegs=1 Build & Test:** "test Windows_NT x86 jitstressregs1"
+- **Windows_NT x86 Checked JITStressRegs=2 Build & Test:** "test Windows_NT x86 jitstressregs2"
+- **Windows_NT x86 Checked JITStressRegs=3 Build & Test:** "test Windows_NT x86 jitstressregs3"
+- **Windows_NT x86 Checked JITStressRegs=4 Build & Test:** "test Windows_NT x86 jitstressregs4"
+- **Windows_NT x86 Checked JITStressRegs=8 Build & Test:** "test Windows_NT x86 jitstressregs8"
+- **Windows_NT x86 Checked JITStressRegs=0x10 Build & Test:** "test Windows_NT x86 jitstressregs0x10"
+- **Windows_NT x86 Checked JITStressRegs=0x80 Build & Test:** "test Windows_NT x86 jitstressregs0x80"
+- **Windows_NT x86 Checked JitStress=2 JITStressRegs=1 Build & Test:** "test Windows_NT x86 jitstress2_jitstressregs1"
+- **Windows_NT x86 Checked JitStress=2 JITStressRegs=2 Build & Test:** "test Windows_NT x86 jitstress2_jitstressregs2"
+- **Windows_NT x86 Checked JitStress=2 JITStressRegs=3 Build & Test:** "test Windows_NT x86 jitstress2_jitstressregs3"
+- **Windows_NT x86 Checked JitStress=2 JITStressRegs=4 Build & Test:** "test Windows_NT x86 jitstress2_jitstressregs4"
+- **Windows_NT x86 Checked JitStress=2 JITStressRegs=8 Build & Test:** "test Windows_NT x86 jitstress2_jitstressregs8"
+- **Windows_NT x86 Checked JitStress=2 JITStressRegs=0x10 Build & Test:** "test Windows_NT x86 jitstress2_jitstressregs0x10"
+- **Windows_NT x86 Checked JitStress=2 JITStressRegs=0x80 Build & Test:** "test Windows_NT x86 jitstress2_jitstressregs0x80"
+- **Windows_NT x86 Checked GCStress=0x3 Build & Test:** "test Windows_NT x86 gcstress0x3"
+- **Windows_NT x86 Checked GCStress=0xc Build & Test:** "test Windows_NT x86 gcstress0xc"
+- **Windows_NT x86 Checked zapdisable Build & Test:** "test Windows_NT x86 zapdisable"
+- **Windows_NT x86 Checked Heap Verify 1 Build & Test:** "test Windows_NT x86 heapverify1"
+- **Windows_NT x86 Checked GCStress=0xc zapdisable Build & Test:** "test Windows_NT x86 gcstress0xc_zapdisable"
+- **Windows_NT x86 Checked GCStress=0xc JitStress=2 zapdisable Build & Test:** "test Windows_NT x86 gcstress0xc_zapdisable_jitstress2"
+- **Windows_NT x86 Checked GCStress=0xc zapdisable Heap Verify 1 Build & Test:** "test Windows_NT x86 gcstress0xc_zapdisable_heapverify1"
+- **Windows_NT x86 Checked GCStress=0xc JitStress=1 Build & Test:** "test Windows_NT x86 gcstress0xc_jitstress1"
+- **Windows_NT x86 Checked GCStress=0xc JitStress=2 Build & Test:** "test Windows_NT x86 gcstress0xc_jitstress2"
+- **Windows_NT x86 Checked GCStress=0xc MinOpts Heap Verify 1 Build & Test:** "test Windows_NT x86 gcstress0xc_minopts_heapverify1"
- **Windows_NT x86 legacy_backend Release jitstress1 R2R Build & Test:** "test Windows_NT x86 legacy_backend Release jitstress1 R2R"
- **Windows_NT x86 legacy_backend Checked jitstress1 R2R Build & Test:** "test Windows_NT x86 legacy_backend Checked jitstress1 R2R"
- **Windows_NT x86 legacy_backend Release jitstress2 R2R Build & Test:** "test Windows_NT x86 legacy_backend Release jitstress2 R2R"
@@ -159,7 +161,7 @@ To trigger a job, post a comment on your PR with "@dotnet-bot {trigger-phrase}".
- **Windows_NT x86 legacy_backend Checked JITMinOpts R2R Build & Test:** "test Windows_NT x86 legacy_backend Checked JITMinOpts R2R"
- **Windows_NT x86 legacy_backend Release ForceRelocs R2R Build & Test:** "test Windows_NT x86 legacy_backend Release ForceRelocs R2R"
- **Windows_NT x86 legacy_backend Checked ForceRelocs R2R Build & Test:** "test Windows_NT x86 legacy_backend Checked ForceRelocs R2R"
-- **Windows_NT x86 RyuJit Release Long-Running GC Build & Test:** "test Windows_NT x86 ryujit Release longgc"
+- **Windows_NT x86 Release Long-Running GC Build & Test:** "test Windows_NT x86 Release longgc"
- **Windows_NT x86 legacy_backend Release Long-Running GC Build & Test:** "test Windows_NT x86 legacy_backend Release longgc"
- **Ubuntu x64 Release Priority 1 Build & Test:** "test Ubuntu pri1"
- **Ubuntu x64 Release IL RoundTrip Build & Test:** "test Ubuntu ilrt"
diff --git a/Documentation/project-docs/glossary.md b/Documentation/project-docs/glossary.md
index 6b13ba82d3..670254ddb6 100644
--- a/Documentation/project-docs/glossary.md
+++ b/Documentation/project-docs/glossary.md
@@ -15,6 +15,7 @@ As much as possible, we should link to the most authoritative and recent source
* JIT: [Just-in-Time](https://github.com/dotnet/coreclr/blob/master/Documentation/botr/ryujit-overview.md) compiler. RyuJIT is the code name for the next generation Just-in-Time(aka "JIT") for the .NET runtime.
* LCG: Lightweight Code Generation. An early name for [dynamic methods](https://github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/Reflection/Emit/DynamicMethod.cs).
* NGen: Native Image Generator.
+* NYI: Not Yet Implemented
* PAL: [Platform Adaptation Layer](http://archive.oreilly.com/pub/a/dotnet/2002/03/04/rotor.html). Provides an abstraction layer between the runtime and the operating system
* PE: Portable Executable.
* ProjectN: Codename for the first version of [.NET Native for UWP](https://msdn.microsoft.com/en-us/vstudio/dotnetnative.aspx).
@@ -22,6 +23,7 @@ As much as possible, we should link to the most authoritative and recent source
* Redhawk: Codename for experimental minimal managed code runtime that evolved into [CoreRT](https://github.com/dotnet/corert/).
* SOS: [Son of Strike](http://blogs.msdn.com/b/jasonz/archive/2003/10/21/53581.aspx). The debugging extension for DbgEng based debuggers. Uses the DAC as an abstraction layer for its operation.
* SVR: The CLR used to be built as two variants, with one called "mscorsvr.dll", to mean the "server" version. In particular, it contained the server GC implementation, which was intended for multi-threaded apps capable of taking advantage of multiple processors. In the .NET Framework 2 release, the two variants were merged into "mscorwks.dll". The WKS version was the default, however the SVR version remained available.
+* TPA: Trusted Platform Assemblies used to be a special set of assemblies that comprised the platform assemblies, when it was originally designed. As of today, it is simply the set of assemblies known to constitute the application.
* URT: Universal Runtime. Ancient name for what ended up being .NET, is used in the WinError facility name FACILITY_URT.
* VSD: [Virtual Stub Dispatch](../botr/virtual-stub-dispatch.md). Technique of using stubs for virtual method invocations instead of the traditional virtual method table.
* VM: Virtual machine.
diff --git a/Documentation/workflow/EditingAndDebugging.md b/Documentation/workflow/EditingAndDebugging.md
new file mode 100644
index 0000000000..66b4d4fcfd
--- /dev/null
+++ b/Documentation/workflow/EditingAndDebugging.md
@@ -0,0 +1,49 @@
+
+# Editing and Debugging
+
+If you are editing on the Windows Operating system, Using Visual Studio 2015 is a good option for editing
+the code in this repository. You can of course also use the editor of your choice. One further option
+is to use [VSCode](https://code.visualstudio.com/) which is a light weight, cross-platform tool that like
+Visual Studio, is optimized for development workflow (code editing and debugging) but works on more platforms
+(in particular OSX and Linux)
+
+[VSCode](https://code.visualstudio.com/) has built-in support for syntax highlighting and previewing
+markdown (`*.md`) files that GIT repositories like this one use for documentation. If you want to modify
+the docs, VSCode is a good choice. See [Markdown and VSCOde](https://code.visualstudio.com/Docs/languages/markdown)
+for more on VSCode support and [Mastering Markdown](https://guides.github.com/features/mastering-markdown/) for
+more on Markdown in general.
+
+# Visual Studio Solutions
+
+The repository has a number of Visual Studio Solutions files (`*.sln`) that are useful for editing parts of
+what are in the repository. In particular
+
+ * `src\mscorlib\System.Private.CorLib.sln` - This solution is for all managed (C#) code that is defined
+ in the runtime itself. This is all class library support of one form or another.
+ * `bin\obj\Windows_NT.<Arch>.<BuildType>\CoreCLR.sln` - this solution contains most native (C++) projects
+ associated with the repository, including
+ * `coreclr` - This is the main runtime DLL (the GC, class loader, interop are all here)
+ * `corjit` - This is the Just In Time (JIT) compiler that compiles .NET Intermediate language to native code.
+ * `corerun` - This is the simple host program that can load the CLR and run a .NET Core application
+ * `crossgen` - This is the host program that runs the JIT compiler and produces .NET Native images (`*.ni.dll`)
+ for C# code.
+
+Thus opening one of these two solution files (double clicking on them in Explorer) is typically all you need
+to do most editing.
+
+Notice that the CoreCLR solution is under the 'bin' directory. This is because it is created as part of the build.
+Thus you can only launch this solution after you have built at least once.
+
+* See [Debugging](../building/debugging-instructions.md)
+
+### Interacting with GIT in Visual Studio
+
+Most interactions with GIT can be done from within Visual Studio. See the following for more details.
+* [Setting up with a fork with Visual Studio 2015](https://github.com/Microsoft/perfview/blob/master/documentation/OpenSourceGitWorkflow.md)
+
+# See Also
+
+Before you make modifications, you probably want to learn more about the general architecture of .NET Core.
+See the following docs for more.
+
+ * [Documentation on the .NET Core Runtime](../README.md)
diff --git a/Documentation/workflow/IssuesFeedbackEngagement.md b/Documentation/workflow/IssuesFeedbackEngagement.md
new file mode 100644
index 0000000000..a6c0550e08
--- /dev/null
+++ b/Documentation/workflow/IssuesFeedbackEngagement.md
@@ -0,0 +1,37 @@
+
+# Engage, Log Issues and Provide Feedback
+
+## Reporting Problems (Bugs)
+
+We track bugs, feature requests and other issues [in this repo](https://github.com/dotnet/coreclr/issues).
+If you have a problem and believe that the issue is in the native runtime you should log it there. If in the managed code log it in the [CoreFX repo](https://github.com/dotnet/corefx/issues) _even if the code is in this CoreCLR repo_ (ie., in mscorlib/System.Private.Corelib). The reason for this is we sometimes move managed types between the two and it makes sense to keep all the issues together.
+
+Before you log a new issue, you should try using the search tool on the issue page on a few keywords to see if the issue was already logged.
+
+### NET Forums
+If you want to ask a question, or want wider discussion (to see if others share you issue), we encourage you to start a thread
+in the [.NET Foundation forums](http://forums.dotnetfoundation.org/).
+
+###Chat with the CoreCLR Community
+
+For more real-time feedback you can also start a chat session by clicking on the icons below.
+
+[![.NET Slack Status](https://aspnetcoreslack.herokuapp.com/badge.svg?2)](http://tattoocoder.com/aspnet-slack-sign-up/) [![Join the chat at https://gitter.im/dotnet/coreclr](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/dotnet/coreclr?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+
+### Security issues
+
+To avoid tipping off malicious users wishing to exploit a vulnerability,
+security issues and bugs should be reported privately, via email, to the
+Microsoft Security Response Center (MSRC) <secure@microsoft.com>. You should
+receive a response within 24 hours. If for some reason you do not, please follow
+up via email to ensure we received your original message. Further information,
+including the MSRC PGP key, can be found in the
+[Security TechCenter](https://technet.microsoft.com/en-us/security/ff852094.aspx)
+
+### Issues with the .NET Desktop runtime
+
+The .NET Core repository is not an appropriate place to log issues for the 'Desktop' .NET Framework built into the Windows
+operating system. If you are having issues with the Full .NET Framework or .NET Runtime the best ways to file a bug
+are at [Connect](http://connect.microsoft.com/VisualStudio) or through
+[Product Support](https://support.microsoft.com/en-us/contactus?ws=support) if you have a contract.
+
diff --git a/Documentation/workflow/OfficalAndDailyBuilds.md b/Documentation/workflow/OfficalAndDailyBuilds.md
new file mode 100644
index 0000000000..5a36af6f46
--- /dev/null
+++ b/Documentation/workflow/OfficalAndDailyBuilds.md
@@ -0,0 +1,79 @@
+# Official Releases and Daily Builds of CoreCLR and CoreFX components
+
+If you are not planning on actually making bug fixes or experimenting with new features, then you probably
+don't need to don't need build CoreCLR yourself, as the .NET Runtime team routinely does this for you.
+
+Roughly every three months, the .NET Runtime team publishes a new version of .NET Core to Nuget. .NET Core's
+official home on NuGet is
+
+ * <https://www.nuget.org/packages/Microsoft.NETCore.Runtime.CoreCLR/>
+
+and you can expect to see new versions roughly three months. However it is also the case that the .NET
+Team publishes **daily builds** of all sorts of packages including those built by the CoreCLR and CoreFX
+repositories. You can see what is available from
+
+ * <https://dotnet.myget.org/gallery/dotnet-core>, and in particular you can see the builds of CoreCLR at
+ * <https://dotnet.myget.org/feed/dotnet-core/package/nuget/Microsoft.NETCore.Runtime.CoreCLR>.
+
+Thus if your goal is just to get the latest bug fixes and features, you don't need to build CoreCLR yourself you
+can simply add <https://dotnet.myget.org/F/dotnet-core/api/v3/index.json> to your Nuget Feed list.
+
+## Package Version Numbers
+
+Version numbers for Nuget packages look like the following
+```
+ 1.0.24214.01
+```
+Which have the form
+```
+ <major>.<minor>.<buildNumberMajor>.<buildNumberMinor>
+```
+
+* The major version number represents a compatibility band. If the next release of the package is not
+ backward compatible (most apps that run on version N-1 will run on version N) then this number is increased.
+ This number is not likely to change (we care about compatibility alot)
+
+* The minor number is increased every time interesting new features are added (not just minor bug fixes).
+ For CoreCLR we tend to update this every time we create a public release (every 3 months).
+
+* The Major Build Number is a number that represents a daily build. The last 2 digits of this build number
+ is the **day of the month** of the GIT commit that is being built. Thus we know in the example above this
+ build's last commit to GIT happened on the 14th day of the month. The most significant digits represents
+ the month count since April 1996. In the example above 242 represents Jun 2016.
+
+* The Minor Build number is something that disambiguates different builds that share the same
+ commit (or the different commits on the same day). It is a sequential number and is typically 1 for
+ official builds, and 0 for developer builds. (You can set the environment variable BuildNumberMinor if
+ you wish to set it for your own builds).
+
+
+
+See the [Package and File Versioning](https://github.com/dotnet/corefx/blob/master/Documentation/building/versioning.md) page
+for more details on how the build version number is generated.
+
+
+
+# Build/Test Status of the repository
+
+As mentioned we build the CoreCLR repository daily, and as part of that build we also run all
+the tests associted with this repository. Below is a table of the most recent results for all
+the different operating systems and architectures that we routinely build.
+
+If you click on the images below, you can get more details about the build (including the binaries)
+and the exact test results (in case your build is failing tests and you are wondering if it is
+something affecting all builds).
+
+| | Debug | Release |
+|---|:-----:|:-------:|
+|**CentOS 7.1**|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/debug_centos7.1.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/debug_centos7.1)|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/release_centos7.1.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/release_centos7.1)|
+|**Debian 8.4**|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/debug_debian8.4.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/debug_debian8.4)|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/release_debian8.4.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/release_debian8.4)|
+|**FreeBSD 10.1**|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/debug_freebsd.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/debug_freebsd)|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/release_freebsd.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/release_freebsd)|
+|**openSUSE 13.2**|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/debug_opensuse13.2.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/debug_opensuse13.2)|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/release_opensuse13.2.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/release_opensuse13.2)|
+|**openSUSE 42.1**|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/debug_opensuse42.1.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/debug_opensuse42.1)|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/release_opensuse42.1.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/release_opensuse42.1)|
+|**OS X 10.11**|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/debug_osx.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/debug_osx)|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/release_osx.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/release_osx)|
+|**Red Hat 7.2**|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/debug_rhel7.2.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/debug_rhel7.2)|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/release_rhel7.2.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/release_rhel7.2)|
+|**Fedora 23**|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/debug_fedora23.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/debug_fedora23)|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/release_fedora23.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/release_fedora23)|
+|**Ubuntu 14.04**|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/debug_ubuntu.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/debug_ubuntu)|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/release_ubuntu.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/release_ubuntu)|
+|**Ubuntu 16.04**|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/debug_ubuntu16.04.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/debug_ubuntu16.04)|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/release_ubuntu16.04.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/release_ubuntu16.04)|
+|**Ubuntu 16.10**|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/debug_ubuntu16.10.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/debug_ubuntu16.10)|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/release_ubuntu16.10.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/release_ubuntu16.10)|
+|**Windows 8.1**|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/debug_windows_nt.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/debug_windows_nt)<br/>[![arm64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/arm64_cross_debug_windows_nt.svg?label=arm64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/arm64_cross_debug_windows_nt)|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/release_windows_nt.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/release_windows_nt)<br/>[![arm64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/arm64_cross_release_windows_nt.svg?label=arm64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/arm64_cross_release_windows_nt)|
diff --git a/Documentation/workflow/RunningTests.md b/Documentation/workflow/RunningTests.md
new file mode 100644
index 0000000000..0cf84be125
--- /dev/null
+++ b/Documentation/workflow/RunningTests.md
@@ -0,0 +1,10 @@
+
+#Running .NET Core Tests
+
+TODO - Incomplete.
+
+See [Windows Instructions](../building/windows-test-instructions.md)
+See [Unix Instructions](../building/unix-test-instructions.md)
+
+
+
diff --git a/Documentation/workflow/UsingCoreRun.md b/Documentation/workflow/UsingCoreRun.md
new file mode 100644
index 0000000000..3979f135b0
--- /dev/null
+++ b/Documentation/workflow/UsingCoreRun.md
@@ -0,0 +1,83 @@
+
+# Using corerun To Run .NET Core Application
+
+In page [Using Your Build](UsingYourBuild.md) gives detailed instructions on using the standard
+command line host and SDK, dotnet.exe to run a .NET application with the modified build of the
+.NET Core runtime built here. This is the preferred mechanism for you to officially deploy
+your changes to other people since dotnet.exe and Nuget insure that you end up with a consistent
+set of DLLs that can work together.
+
+However packing and unpacking the runtime DLLs adds extra steps to the deployment process and when
+you are in the tight code-build-debug loop these extra steps are an issue.
+
+For this situation there is an alternative host to dotnet.exe called corerun.exe that is well suited
+for this. It does not know about Nuget at all, and has very simple rules. It needs to find the
+.NET Core runtime (that is coreclr.dll) and additionally any class library DLLs (e.g. System.Runtime.dll System.IO.dll ...).
+
+It does this by looking at two environment variables.
+
+
+ * `CORE_ROOT` - The directory where to find the runtime DLLs itself (e.g. CoreCLR.dll).
+ Defaults to be next to the corerun.exe host itself.
+ * `CORE_LIBRARIES` - A Semicolon separated list of directories to look for DLLS to resolve any assembly references.
+ It defaults CORE_ROOT if it is not specified.
+
+These simple rules can be used in a number of ways
+
+## Getting the class library from the shared system-wide runtime
+
+Consider that you already have a .NET application DLL called HelloWorld.dll and wish to run it
+(You could make such a DLL by using 'dotnet new' 'dotnet restore' 'dotnet build' in a 'HelloWorld' directory).
+
+If you execute the following
+```bat
+ set PATH=%PATH%;%CoreCLR%\bin\Product\Windows_NT.x64.Debug
+ set CORE_LIBRARIES=%ProgramFiles%\dotnet\shared\Microsoft.NETCore.App\1.0.0
+
+
+ corerun HelloWorld.dll
+```
+
+for Linux use /usr/share for %Program Files%
+
+Where %CoreCLR% is the base of your CoreCLR repository, then it will run your HelloWorld. application.
+You can see why this works. The first line puts build output directory (Your OS, architecture, and buildType
+may be different) and thus corerun.exe you just built is on your path.
+The second line tells corerun.exe where to find class library files, in this case we tell it
+to find them where the installation of dotnet.exe placed its copy. (Note that version number in the path above may change)
+
+Thus when you run 'corerun HelloWorld.dll' Corerun knows where to get the DLLs it needs. Notice that once
+you set up the path and CORE_LIBRARIES environment, after a rebuild you can simply use corerun to run your
+application (you don't have to move DLLs around)
+
+## Using corerun.exe to Execute a Published Application
+
+When 'dotnet publish' publishes an application it deploys all the class libraries needed as well.
+Thus if you simply change the CORE_LIBRARIES definition in the previous instructions to point at
+that publication directory but RUN the corerun from your build output the effect will be that you
+run your new runtime getting all the other code needed from that deployed application. This is
+very convenient because you don't need to modify the deployed application in order to test
+your new runtime.
+
+## How CoreCLR Tests use corerun.exe
+
+When you execute 'tests\runTest.cmd' one of the things that it does is set up a directory where it
+gathers the CoreCLR that has just been built with the pieces of the class library that tests need.
+It places this runtime in the directory
+```bat
+ bin\Product\<OS>.<Arch>.<BuildType>\test
+```
+off the CoreCLR Repository. The way the tests are expected to work is that you set the environment
+variable CORE_ROOT to this directory
+(you don't have to set CORE_LIBRARIES) and you can run any tests. For example after building the tests
+(running build-test at the repository base) and running 'test\runtest') you can do the following
+
+```bat
+ set PATH=%PATH%;%CoreCLR%\bin\Product\Windows_NT.x64.Debug
+ set CORE_ROOT=%CoreCLR%\bin\tests\Windows_NT.x64.Debug\Tests\Core_Root
+```
+sets you up so that corerun can run any of the test. For example
+```bat
+ corerun bin\tests\Windows_NT.X64.Debug\GC\Features\Finalizer\finalizeio\finalizeio\finalizeio.exe
+```
+runs the finalizerio test. \ No newline at end of file
diff --git a/Documentation/workflow/UsingYourBuild.md b/Documentation/workflow/UsingYourBuild.md
new file mode 100644
index 0000000000..c783dd1e19
--- /dev/null
+++ b/Documentation/workflow/UsingYourBuild.md
@@ -0,0 +1,215 @@
+
+# Using your .NET Core Runtime Build
+
+We assume that you have successfully built CoreCLR repository and thus have file of the form
+```
+ bin\Product\<OS>.<arch>.<flavor>\.nuget\pkg\Microsoft.NETCore.Runtime.CoreCLR.<version>.nupkg
+```
+And now you wish to try it out. We will be using Windows OS as an example and thus will use \ rather
+than / for directory separators and things like Windows_NT instead of Linux but it should be
+pretty obvious how to adapt these instructions for other operating systems.
+
+To run your newly built .NET Core Runtime in addition to the application itself, you will need
+a 'host' program that will load the Runtime as well as all the other .NET Core Framework
+code that your application needs. The easiest way to get all this other stuff is to simply use the
+standard 'dotnet' host that installs with .NET Core SDK.
+
+The released version of 'dotnet' tool may not be compatible with the live CoreCLR repository. The following steps
+assume use of unreleased version of 'dotnet' tool that is downloaded as part of the CoreCLR repository
+build at `<repo root>\Tools\dotnetcli`. [Add `Tools\dotnetcli` directory to your path](../building/windows-instructions.md#adding-to-the-default-path-variable)
+and type:
+
+* dotnet -?
+
+and it prints some help text, you are ready.
+
+### Step 1: Create a App using the Default Runtime
+At this point you can create a new 'Hello World' program in the standard way.
+
+```bat
+mkdir HelloWorld
+cd HelloWorld
+dotnet new
+```
+
+### Step 2: Get the Version number of the CoreCLR package you built.
+
+This makes a 'standard' hello world application but uses the .NET Core Runtime version that
+came with the dotnet.exe tool. First you need to modify your app to ask for the .NET Core
+you have built, and to do that, we need to know the version number of what you built. Get
+this by simply listing the name of the Microsoft.NETCore.Runtime.CoreCLR you built.
+
+```bat
+ dir bin\Product\Windows_NT.x64.Release\.nuget\pkg
+```
+
+and you will get name of the which looks something like this
+
+```
+ Microsoft.NETCore.Runtime.CoreCLR.1.2.0-beta-24528-0.nupkg
+```
+
+This gets us the version number, in the above case it is 1.2.0-beta-24528-0. We will
+use this in the next step.
+
+### Step 3: Modify the Project.json for the App to refer to your Runtime.
+
+Replace the HelloWorld\project.json with [project.json](../../tests/src/Common/netcoreapp/project.json), and update
+`1.2.0-beta-XXXXX-X` version number in the dependencies section with the version number for your build of the runtime.
+This is the line that tells the tools that you want YOUR version of the CoreCLR runtime.
+```
+ "Microsoft.NETCore.Runtime.CoreCLR": "1.2.0-beta-24528-0"
+```
+
+The differences between the project.json generated by the tool and the replacement:
+
+- Removed Microsoft.NETCore.App platform dependency (`"type": "platform"`). This tells the build system that you don't want to
+use runtime and libraries that came with the dotnet.exe tool but to fetch the dependencies from the Nuget cache. If you don't do this
+the tools will ignore your request to make the app use an explicitly specified runtime.
+- Added the 'runtimes' line at the top level. The runtime name includes the OS name and the architecture name
+you can find the appropriate name for your OS [here](https://github.com/dotnet/core-docs/blob/master/docs/core/rid-catalog.md).
+This tells the tools exactly which flavor of OS and processor architecture you are running on, so it can find the right
+Nuget package for the runtime.
+- Changed netcoreapp1.0 to netcoreapp1.1. This tells the tools that you want to use the latest .NET Core Framework.
+- Expanded Microsoft.NETCore.App metapackage into explicit list of the .NET Core Framework packages because of there is no good published
+build of Microsoft.NETCore.App metapackage for netcoreapp1.1 yet.
+
+### Step 4: Place your build directory and beta .NET Core Framework feed on your Nuget Path
+
+You can do this by creating a file named Nuget.Config in the 'HelloWorld' directory with the following XML
+Obviously **you need to update path in the XML to be the path to output directory for your build**.
+On Windows you also have the alternative of modifying the Nuget.Config
+at %HOMEPATH%\AppData\Roaming\Nuget\Nuget.Config (~/.nuget/NuGet/NuGet.Config on Linux) with the new location.
+This will allow your new
+runtime to be used on any 'dotnet restore' run by the current user.
+Alternatively you can skip creating this file and pass the path to your package directory using
+the -s SOURCE qualifer on the dotnet restore command below. The important part is that somehow
+you have told the tools where to find your new package.
+
+```xml
+<configuration>
+ <packageRestore>
+ <add key="enabled" value="True" />
+ </packageRestore>
+ <packageSources>
+ <add key="Local CoreCLR" value="C:\Users\User\Source\Repos\coreclr-vancem\bin\Product\Windows_NT.x64.Release\.nuget\pkg" />
+ <add key="myget.org dotnet-core" value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json" />
+ </packageSources>
+ <activePackageSource>
+ <add key="All" value="(Aggregate source)" />
+ </activePackageSource>
+</configuration>
+```
+
+### Step 5: Restore the Nuget Packages for your application
+
+This consist of simply running the command
+```
+ dotnet restore
+```
+which should find the .NET Runtime package in your build output and unpacks it to the local Nuget cache (on windows this is in %HOMEPATH%\.nuget\packages)
+
+
+### Step 6: Run your application
+
+You can run your 'HelloWorld' applications by simply executing the following in the 'HelloWorld' directory.
+
+```
+ dotnet run
+```
+This will compile and run your app. What the command is really doing is building files in helloWorld\bin\Debug\netcoreapp1.1\win7-x64\
+and then running 'dotnet helloWorld\bin\Debug\netcoreapp1.1\win7-x64\HelloWorld.dll' to actually run the app.
+
+### Step 6: (Optional) Publish your application
+
+In Step 5 you will notice that the helloWorld\bin\Debug\netcoreapp1.1\win7-x64 directory does NOT actually contain your Runtime code.
+What is going on is that runtime is being loaded directly out of the local Nuget cache (on windows this is in %HOMEPATH%\.nuget\packages).
+The app can find this cache because of the HelloWorld.runtimeconfig.dev.json file which specifies that that this location should be
+added to the list of places to look for dependencies.
+
+This setup fine for development time, but is not a reasonable way of allowing end users to use your new runtime. Instead what
+you want all the necessary code to be gather up so that the app is self-contained. This is what the following command does.
+```
+ dotnet publish
+```
+After running this in the 'HelloWorld' directory you will see that the following path
+
+* helloWorld\bin\Debug\netcoreapp1.1\win7-x64\publish
+
+Has all the binaries needed, including the CoreCLR.dll and System.Private.CoreLib.dll that you build locally. To
+run the application simple run the EXE that is in this publish directory (it is the name of the app, or specified
+in the project.json file). Thus at this point this directory has NO dependency outside this publication directory
+(including dotnet.exe). You can copy this publication directory to another machine and run( the exe in it and
+will 'just work'. Note that your managed app's code is still in the 'app'.dll file, the 'app'.exe file is
+actually simply a rename of dotnet.exe.
+
+### Step 7: (Optional) Confirm that the app used your new runtime
+
+Congratulations, you have successfully used your newly built runtime. To confirm that everything worked, you
+should compare the file creation timestamps for the CoreCLR.dll and System.Private.Runtime.dll in the publishing
+directory and the build output directory. They should be identical. If not, something went wrong and the
+dotnet tool picked up a different version of your runtime.
+
+### Step 8: Update BuildNumberMinor Environment Variable!
+
+One possible problem with the technique above is that Nuget assumes that distinct builds have distinct version numbers.
+Thus if you modify the source and create a new NuGet package you must it a new version number and use that in your
+application's project.json. Otherwise the dotnet.exe tool will assume that the existing version is fine and you
+won't get the updated bits. This is what the Minor Build number is all about. By default it is 0, but you can
+give it a value by setting the BuildNumberMinor environment variable.
+```bat
+ set BuildNumberMinor=3
+```
+before packaging. You should see this number show up in the version number (e.g. 1.2.0-beta-24521-03).
+
+As an alternative you can delete the existing copy of the package from the Nuget cache. For example on
+windows (on Linux substitute ~/ for %HOMEPATH%) you could delete
+```bat
+ %HOMEPATH%\.nuget\packages\Microsoft.NETCore.Runtime.CoreCLR\1.2.0-beta-24521-02
+```
+which should make things work (but is fragile, confirm wile file timestamps that you are getting the version you expect)
+
+
+## Step 8.1 (Optional) Quick updates in place.
+
+The 'dotnet publish' step in step 6 above creates a directory that has all the files necessary to run your app
+including the CoreCLR and the parts of CoreFX that were needed. You can use this fact to skip some steps if
+you wish to update the DLLs. For example typically when you update CoreCLR you end up updating one of two DLLs
+
+* coreclr.dll - Most modifications (with the exception of the JIT compiler and tools) that are C++ code update
+ this DLL.
+* System.Private.CoreLib.dll - If you modified C# it will end up here.
+* System.Private.CoreLib.ni.dll - the native image (code) for System.Private.Corelib. If you modify C# code
+you will want to update both of these together in the target installation.
+
+Thus after making a change and building, you can simply copy the updated binary from the `bin\Product\<OS>.<arch>.<flavor>`
+directory to your publication directory (e.g. `helloWorld\bin\Debug\netcoreapp1.1\win7-x64\publish`) to quickly
+deploy your new bits. You can build just the .NET Library part of the build by doing (debug, for release add 'release qualifier)
+(on Linux / OSX us ./build.sh)
+```bat
+ .\build skiptests skipnative
+```
+Which builds System.Private.CoreLib.dll AND System.Private.CoreLib.ni.dll (you will always want both) if you modify
+C# code. If you wish to only compile the coreclr.dll you can do
+ ```bat
+ .\build skiptests skipmscorlib
+```
+Note that this technique does not work on .NET Apps that have not been published (that is you have not created
+a directory with all DLLs needed to run the all) That is because the runtime is either fetched from the system-wide
+location that dotnet.exe installed, OR it is fetched from the local nuget package cache (which is where your
+build was put when you did a 'dotnet restore' and had a dependency on your particular runtime). In theory you
+could update these locations in place, but that is not recommended since they are shared more widely.
+
+### Using your Runtime For Real.
+
+You can see that it is straightforward for anyone to use your runtime. They just need to modify their project.json
+and modify their NuGet search path. This is the expected way of distributing your modified runtime.
+
+--------------------------
+## Using CoreRun to run your .NET Core Application
+
+Generally using dotnet.exe tool to run your .NET Core application is the preferred mechanism to run .NET Core Apps.
+However there is a simpler 'host' for .NET Core applications called 'CoreRun' that can also be used. The value
+of this host is that it is simpler (in particular it knows nothing about NuGet), but precisely because of this
+it can be harder to use (since you are responsible for insuring all the dependencies you need are gather together)
+See [Using CoreRun To Run .NET Core Application](UsingCoreRun.md) for more.
diff --git a/DotnetCLIVersion.txt b/DotnetCLIVersion.txt
index dd7bc318fa..b0f8213885 100644
--- a/DotnetCLIVersion.txt
+++ b/DotnetCLIVersion.txt
@@ -1 +1 @@
-1.0.0-preview2-002733 \ No newline at end of file
+1.0.0-preview3-003223 \ No newline at end of file
diff --git a/README.md b/README.md
index ffcffff5b9..98dcb1abad 100644
--- a/README.md
+++ b/README.md
@@ -1,106 +1,232 @@
-.NET Core Runtime (CoreCLR)
+.NET Core Common Language Runtime (CoreCLR)
===========================
-The CoreCLR repo contains the complete runtime implementation for [.NET Core](http://github.com/dotnet/core). It includes RyuJIT, the .NET GC, native interop and many other components. It is cross-platform, with multiple OS and CPU ports in progress.
+This repository contains complete source code the runtime of [.NET Core](http://dotnet.github.io).
+If you are new to .NET Core start with the [About .NET](https://docs.microsoft.com/en-us/dotnet/articles/about/)
+that quickly points you to [.NET Core Tutorials](https://docs.microsoft.com/en-us/dotnet/articles/core/getting-started)
+
+
+.NET Core is best thought of as 'agile .NET'. Generally speaking it is the same as
+the [Desktop .NET Framework](https://en.wikipedia.org/wiki/.NET_Framework)
+distributed as part of the Windows operating system, but it is a cross platform
+(Windows, Linux, OSX) and cross architecture (x86, x64, arm) subset that can be deployed
+as part of the application (if desired), and thus can be updated quickly to fix bugs or add features.
+
+## If You Just Want to Use .NET Core
+
+Most users don't need to build .NET Core from source since there is already an built and tested version for any supported platform.
+You can get the latest **released** version of the .NET Core SDK by following the instructions on
+the [.NET Core Getting Started](http://dotnet.github.io/getting-started/) page.
+If you need the most up to date (daily) version of this .NET Core installer you can get it from the
+[latest Installers of .NET Core and .NET Core SDK](https://github.com/dotnet/cli#installers-and-binaries).
+
+## Are you Here for Something Besides the Source Code?
+
+In addition to providing the source code, this repository also acts as a useful nexus for things
+related to .NET Core including:
+
+ * Want to **learn more** about .NET Runtime Internals? See the [Documentation on the .NET Core Runtime](Documentation/README.md) page.
+ * Need to **log a issue** or Provide Feedback? See then [Issues and Feedback Page](Documentation/workflow/IssuesFeedbackEngagement.md) page.
+ * Want to **chat** with other members of the CoreCLR community? See the [Chat Section](Documentation/workflow/IssuesFeedbackEngagement.md#Chat-with-the-CoreCLR-community) page.
+ * Need a **current build** or **test results** of the CoreCLR repository? See the [Official and Daily Builds](Documentation/workflow/OfficalAndDailyBuilds.md) page.
+ * If you want powerful search of the source code for both CoreClr and CoreFx see [.NET Source Code Index](https://source.dot.net)
+
+## What Can you Make from this Repository?
+
+.NET Core relies heavily on the [Nuget](https://en.wikipedia.org/wiki/NuGet) package manager,
+which is a system to package, distribute and version software components. See [https://www.nuget.org/](https://www.nuget.org/)
+for more information on Nuget. For now it is enough to know Nuget is a system that
+bundles components into `*.nupkg` files (which are ZIP archives) and these packages can be 'published'
+either through a local file system path or by a URL (e.g. https://www.nuget.org/). There are then tools
+(e.g. Nuget.exe, Visual Studio, dotnet.exe) that based on a configuration file (project.json) know
+how to search these publishing locations and pull down consistent set of packages for the
+application.
+
+In concrete terms, this repository is best thought of as the source code for the following Nuget package
+
+ * **Microsoft.NETCore.Runtime.CoreCLR** - Represents the object allocator, garbage collector (GC), class
+ loader, type system, interop and the most fundamental parts of the .NET class library (e.g.
+ System.Object, System.String ...)
+
+It also contains the source code for the following closely related support packages.
+
+ * **Microsoft.NETCore.Jit** - The Just In Time (JIT) compiler for the
+ [.NET Intermediate language (IL)](https://en.wikipedia.org/wiki/Common_Intermediate_Language)
+ * **Microsoft.NETCore.ILAsm** - An assembler for the
+ [.NET Intermediate language (IL)](https://en.wikipedia.org/wiki/Common_Intermediate_Language)
+ * **Microsoft.NETCore.ILDAsm** - A disassembler (Pretty printer) for the
+ [.NET Intermediate language (IL)](https://en.wikipedia.org/wiki/Common_Intermediate_Language)
+ * **Microsoft.NETCore.TestHost** - This contains the corehost.exe program, which is a small wrapper
+ that uses the .NET Runtime to run IL DLLs passed to it on the command line.
+ * **Microsoft.TargetingPack.Private.CoreCLR** - A set of assemblies that represent the compile time surface
+ area of the class library implemented by the runtime itself.
+
+## Relationship with the [CoreFX](https://github.com/dotnet/corefx) Repository
+
+By itself, the Microsoft.NETCore.Runtime.CoreCLR package is actually not enough to do much.
+One reason for this is that the CoreCLR package tries to minimize the amount of the class library that it implements.
+Only types that have a strong dependency on the internal workings of the runtime are included (e.g,
+System.Object, System.String System.Thread, System.Threading.Tasks.Task and most foundational interfaces).
+Instead most of the class library is implemented as independent Nuget packages that simply use the .NET Core
+runtime as a dependency. Many of the most familiar classes (System.Collections, System.IO, System.Xml and
+so on), live in packages defined in the [dotnet/corefx](https://github.com/dotnet/corefx) repository.
+
+But the main reason you can't do much with CoreCLR is that **ALL** of the types in the class library **LOOK**
+like they are defined by the CoreFX framework and not CoreCLR. Any library code defined here
+lives in a single DLL called System.Private.CoreLib.dll and as its name suggests is private (hidden).
+Instead for any particular PUBLIC type defined in CoreCLR, we found the 'right' package in CoreFX where it naturally
+belongs and use that package as its **public publishing** point. That 'facade' package then forwards references
+to the (private) implementation in System.Private.CoreLib.dll defined here.
+For example the *System.Runtime* package defined in CoreFX declares the PUBLIC name for types like
+System.Object and System.String. Thus from an applications point of view these types live in System.Runtime.dll.
+However, System.Runtime.dll (defined in the CoreFX repo) forwards references ultimately to System.Private.CoreLib.dll
+which is defined here.
+
+Thus in order to run an application, you need BOTH the Microsoft.NETCore.Runtime.CoreCLR Nuget package
+(defined in this repository) as well as packages for whatever you actually reference that were defined
+in the CoreFX repository (which at a minimum includes the System.Runtime package). You also need some
+sort of 'host' executable that loads the CoreCLR package as well as the CoreFX packages and starts your code (typically
+you use dotnet.exe for this).
+
+These extra pieces are not defined here, however you don't need to build them in order to use the CoreCLR
+Nuget package you create here. There are already versions of the CoreFX packages published on
+https://www.nuget.org/ so you can have your test application's project.json specify the CoreCLR you
+built and it will naturally pull anything else it needs from the official location https://www.nuget.org/ to
+make a complete application. More on this in the [Using Your Build](Documentation/workflow/UsingYourBuild.md) page.
+
+--------------------------
+## Setting up your GIT Clone of the CoreCLR Repository
+
+The first step in making a build of the CoreCLR Repository is to clone it locally. If you already know
+how to do this, just skip this section. Otherwise if you are developing on windows you can see
+[Setting Up A Git Repository In Visual Studio 2015](https://github.com/Microsoft/perfview/blob/master/documentation/SettingUpRepoInVS2015.md)
+for for instructions on setting up. This link uses a different repository as an example, but the issues (do you fork or not) and
+the procedure are equally applicable to this repository.
+
+--------------------------
+## Building the Repository
+
+The build depends on GIT, CMAKE, Python and of course a C++ compiler. Once these prerequisites are installed
+the build is simply a matter of invoking the 'Build' script (Build.cmd or build.sh) at the base of the
+repository.
+
+The details of installing the components differ depending on the operating system. See the following
+pages based on your OS. There is no cross-building across OS (only for ARM, which is built on X64).
+You have to be on the particular platform to build that platform.
+
+ * [Windows Build Instructions](Documentation/building/windows-instructions.md)
+ * [Linux Build Instructions](Documentation/building/linux-instructions.md)
+ * [OSX Build Instructions](Documentation/building/osx-instructions.md)
+ * [FreeBSD Build Instructions](Documentation/building/freebsd-instructions.md)
+ * [NetBSD Build Instructions](Documentation/building/netbsd-instructions.md)
+
+The build has two main 'buildTypes'
+
+ * Debug (default)- This compiles the runtime with additional runtime checks (asserts). These checks slow
+ runtime execution but are really valuable for debugging, and is recommended for normal development and testing.
+ * Release - This compiles without any development time runtime checks. This is what end users will use but
+ can be difficult to debug. Passing 'release' to the build script select this.
+
+In addition, by default the build will not only create the runtime executables, but it will also
+build all the tests. There are quite a few tests so this does take a significant amount of time
+that is not necessary if you want to experiment with changes. You can submit the building
+of the tests with the 'skiptests' argument to the build script.
+
+Thus to get a build as quickly as possible type the following (using \ as the directory separator, use / on Unix machines)
+```bat
+ .\build skiptests
+```
+which will build the Debug flavor which has development time checks (asserts), or
+```bat
+ .\build release skiptests
+```
+to build the release (full speed) flavor. You can find more build options with build by using the -? or -help qualifier.
+
+## Using Your Build
+
+The build places all of its generated files under the 'bin' directory at the base of the repository. There
+is a 'bin\Log' directory that contains log files generated during the build (Most useful when the build fails).
+The the actual output is placed in a directory like this
+
+* bin\Product\Windows_NT.x64.Release
+
+Where you can see the operating system and CPU architecture, and the build type are part of the name. While
+the 'raw' output of the build is sometimes useful, normally you are only interested in the Nuget packages
+that were built, which are placed in the directory
+
+* bin\Product\Windows_NT.x64.Release\.nuget\pkg
+
+These packages are the 'output' of your build.
+
+There are two basic techniques for using your new runtime.
+
+ 1. **Use dotnet.exe and Nuget to compose an application**. See [Using Your Build](Documentation/workflow/UsingYourBuild.md) for
+ instructions on creating a program that uses
+ your new runtime by using the NuGet packages you just created and the'dotnet' command line interface. This
+ is the expected way non-runtime developers are likely to consume your new runtime.
+
+ 2. **Use corerun.exe to run an application using unpackaged Dlls**. This repository also defines a simple host called
+ corerun.exe that does NOT take any dependency on NuGet. Basically it has to be told where to get all the
+ necessary DLLs you actually use, and you have to gather them together 'by hand'. This is the technique that
+ all the tests in the repo use, and is useful for quick local 'edit-compile-debug' loop (e.g. preliminary unit testsing).
+ See [Executing .NET Core Apps with CoreRun.exe](Documentation/workflow/UsingCoreRun.md) for details on using
+ this technique.
+
+## Editing and Debugging
-Note that the library implementation CoreFX (System.Collections, System.IO, System.Xml and so on) lives in another repo [dotnet/corefx](https://github.com/dotnet/corefx).
+Typically users run through the build and use instructions first with an unmodified build, just to familiarize
+themselves with the procedures and to confirm that the instructions work. After that you will want to actually
+make modifications and debug any issues those modifications might cause. See the following links for more.
-Build Status
-------------
+ * [Editing and Debugging](Documentation/workflow/EditingAndDebugging.md) and
+ * [Documentation on the .NET Core Runtime](Documentation/README.md)
-| | Debug | Release |
-|---|:-----:|:-------:|
-|**CentOS 7.1**|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/debug_centos7.1.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/debug_centos7.1)|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/release_centos7.1.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/release_centos7.1)|
-|**Debian 8.4**|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/debug_debian8.4.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/debug_debian8.4)|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/release_debian8.4.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/release_debian8.4)|
-|**FreeBSD 10.1**|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/debug_freebsd.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/debug_freebsd)|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/release_freebsd.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/release_freebsd)|
-|**openSUSE 13.2**|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/debug_opensuse13.2.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/debug_opensuse13.2)|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/release_opensuse13.2.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/release_opensuse13.2)|
-|**openSUSE 42.1**|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/debug_opensuse42.1.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/debug_opensuse42.1)|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/release_opensuse42.1.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/release_opensuse42.1)|
-|**OS X 10.11**|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/debug_osx.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/debug_osx)|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/release_osx.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/release_osx)|
-|**Red Hat 7.2**|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/debug_rhel7.2.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/debug_rhel7.2)|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/release_rhel7.2.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/release_rhel7.2)|
-|**Fedora 23**|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/debug_fedora23.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/debug_fedora23)|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/release_fedora23.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/release_fedora23)|
-|**Ubuntu 14.04**|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/debug_ubuntu.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/debug_ubuntu)|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/release_ubuntu.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/release_ubuntu)|
-|**Ubuntu 16.04**|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/debug_ubuntu16.04.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/debug_ubuntu16.04)|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/release_ubuntu16.04.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/release_ubuntu16.04)|
-|**Windows 8.1**|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/debug_windows_nt.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/debug_windows_nt)<br/>[![arm64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/arm64_cross_debug_windows_nt.svg?label=arm64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/arm64_cross_debug_windows_nt)|[![x64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/release_windows_nt.svg?label=x64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/release_windows_nt)<br/>[![arm64 status](https://img.shields.io/jenkins/s/http/dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/arm64_cross_release_windows_nt.svg?label=arm64)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr/job/master/job/arm64_cross_release_windows_nt)|
+## Running Tests
-Building the Repo
--------------
+After you have your modification basically working, and want to determine if you have broken anything it is
+time to runt tests. See [Running .NET Core Tests](Documentation/workflow/RunningTests.md) for more.
-|Linux |Windows |Mac OS X |FreeBSD | NetBSD |
-|--------|--------|---------|---------|--------|
-| [Instructions](Documentation/building/linux-instructions.md) | [Instructions](Documentation/building/windows-instructions.md) | [Instructions](Documentation/building/osx-instructions.md) | [Instructions](Documentation/building/freebsd-instructions.md) | [Instructions](Documentation/building/netbsd-instructions.md) |
+## Contributing to Repository
-Get .NET Core
-----------------------
-You can get the latest released .NET Core SDK from the [.NET Core Getting started](http://dotnet.github.io/getting-started/) page. You can also get the latest development builds of .NET Core and the SDK from the [dotnet/cli repo](https://github.com/dotnet/cli#installers-and-binaries).
-
-Chat Room
----------
-
-Want to chat with other members of the CoreCLR community?
-
-[![.NET Slack Status](https://aspnetcoreslack.herokuapp.com/badge.svg?2)](http://tattoocoder.com/aspnet-slack-sign-up/) [![Join the chat at https://gitter.im/dotnet/coreclr](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/dotnet/coreclr?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-
-Learn about CoreCLR and .NET Core
----------------------------------
-
-The best ways to learn about CoreCLR are to try out the product instructions and to read the "Book of the Runtime" architecture documents that describe the inner workings of the product. New devs to the CLR team are encouraged to read these documents before making substative changes to the product. They are equally useful for open source contributors.
-
-- [.NET Core Roadmap](https://github.com/dotnet/core/blob/master/roadmap.md)
-- [Product instructions](Documentation/README.md)
-- [Introduction to the Common Language Runtime](Documentation/botr/intro-to-clr.md)
-- [Book of the Runtime](Documentation/README.md#book-of-the-runtime)
-- [CoreCLR Documents](Documentation)
-
-.NET Core is part of ASP.NET Core and is a subset of the .NET Framework. You can learn more about .NET Core and how and where you can use it in the [CoreCLR is open source][coreclr blog post] blog post.
-
-The [.NET Core Libraries][corefx] repo contains the base class libraries, which provides data types and base functionality (ex: String, Collections, HttpClient) on top of CoreCLR. The two repos together make up .NET Core. The [.NET Core is Open Source][.NET Core oss] and [Introducing .NET Core][Introducing .NET Core] blog posts describes our .NET Core OSS strategy and road map in more detail.
-
-Engage, Contribute and Provide Feedback
----------------------------------------
-
-Some of the best ways to contribute are to try things out, file bugs, and join in design conversations. You are encouraged to start a discussion by filing an issue, or starting a thread in the [.NET Foundation forums](http://forums.dotnetfoundation.org/). If you are having issues with the Full .NET Framework or .NET Runtime the best ways to file a bug are at [Connect](http://connect.microsoft.com/VisualStudio) or through [Product Support](https://support.microsoft.com/en-us/contactus?ws=support) if you have a contract.
-
-Looking for something to work on? The list of [up-for-grabs issues](https://github.com/dotnet/coreclr/issues?q=is%3Aopen+is%3Aissue+label%3Aup-for-grabs) is a great place to start.
+Looking for something to work on? The list
+of [up-for-grabs issues](https://github.com/dotnet/coreclr/issues?q=is%3Aopen+is%3Aissue+label%3Aup-for-grabs) is a great place to start.
Please read the following documents to get started.
* [Contributing Guide](Documentation/project-docs/contributing.md)
* [Developer Guide](Documentation/project-docs/developer-guide.md)
-This project has adopted the code of conduct defined by the [Contributor Covenant](http://contributor-covenant.org/) to clarify expected behavior in our community. For more information, see the [.NET Foundation Code of Conduct](http://www.dotnetfoundation.org/code-of-conduct).
+This project has adopted the code of conduct defined by the [Contributor Covenant](http://contributor-covenant.org/)
+to clarify expected behavior in our community. For more information, see the [.NET Foundation Code of Conduct](http://www.dotnetfoundation.org/code-of-conduct).
-### Reporting security issues and security bugs
+-------------------
+## Related Projects
-Security issues and bugs should be reported privately, via email, to the
-Microsoft Security Response Center (MSRC) <secure@microsoft.com>. You should
-receive a response within 24 hours. If for some reason you do not, please follow
-up via email to ensure we received your original message. Further information,
-including the MSRC PGP key, can be found in the
-[Security TechCenter](https://technet.microsoft.com/en-us/security/ff852094.aspx).
+As noted above, the CoreCLR Repository does not contain all the source code that makes up the .NET Core distribution.
+Here is a list of the other repositories that complete the picture.
-License
--------
+* [dotnet/corefx](https://github.com/dotnet/corefx) - Source for the most common classes in the .NET Framework library.
+* [dotnet/core-setup](https://github.com/dotnet/core-setup) - Source code for the dotnet.exe program and the policy logic
+to launch basic .NET Core code (hostfxr, hostpolicy) which allow you to say 'dotnet SOME_CORE_CLR_DLL' to run the app.
+* [dotnet/cli repo](https://github.com/dotnet/cli) - Source for build time actions supported by dotnet.exe Command line Interface (CLI).
+Thus this is the code that runs when you do 'dotnet build', 'dotnet restore' or 'dotnet publish'.
+* [dotnet/core-docs](https://github.com/dotnet/core-docs) - Master copy of documentation for
+[http://docs.microsoft.com/en-us/dotnet/](https://docs.microsoft.com/en-us/dotnet/)
-.NET Core (including the coreclr repo) is licensed under the [MIT license](LICENSE.TXT).
-
-.NET Foundation
----------------
+## See Also
-.NET Core is a [.NET Foundation](http://www.dotnetfoundation.org/projects) project.
+* [Dotnet.github.io](http://dotnet.github.io) is a good place to discover .NET Foundation projects.
+* .NET Core is a [.NET Foundation](http://www.dotnetfoundation.org/projects) project.
+* [.NET home repo](https://github.com/Microsoft/dotnet) links to 100s of .NET projects, from Microsoft and the community.
+* The [.NET Core repo](https://github.com/dotnet/core) links to .NET Core related projects from Microsoft.
+* The [ASP.NET home repo](https://github.com/aspnet/home) is the best place to start learning about ASP.NET Core.
-Related Projects
-----------------
+## Important Blog Entries
-There are many .NET projects on GitHub.
+* [Announcement of .NET Core Open Source Project](http://blogs.msdn.com/b/dotnet/archive/2014/11/12/net-core-is-open-source.aspx)
+* [Introducing .NET Core](http://blogs.msdn.com/b/dotnet/archive/2014/12/04/introducing-net-core.aspx)
+* [Announcement of CoreCLR](http://blogs.msdn.com/b/dotnet/archive/2015/02/03/coreclr-is-now-open-source.aspx)
-- The
-[.NET home repo](https://github.com/Microsoft/dotnet) links to 100s of .NET projects, from Microsoft and the community.
-- The [.NET Core repo](https://github.com/dotnet/core) links to .NET Core related projects from Microsoft.
-- The [ASP.NET home repo](https://github.com/aspnet/home) is the best place to start learning about ASP.NET Core.
-- [dotnet.github.io](http://dotnet.github.io) is a good place to discover .NET Foundation projects.
+## License
-[.NET Core oss]: http://blogs.msdn.com/b/dotnet/archive/2014/11/12/net-core-is-open-source.aspx
-[Introducing .NET Core]: http://blogs.msdn.com/b/dotnet/archive/2014/12/04/introducing-net-core.aspx
-[coreclr blog post]: http://blogs.msdn.com/b/dotnet/archive/2015/02/03/coreclr-is-now-open-source.aspx
-[corefx]: http://github.com/dotnet/corefx
-[coreclr]: http://github.com/dotnet/coreclr
+.NET Core (including the coreclr repo) is licensed under the [MIT license](LICENSE.TXT).
diff --git a/binclash.log b/binclash.log
new file mode 100755
index 0000000000..e69de29bb2
--- /dev/null
+++ b/binclash.log
diff --git a/build-packages.cmd b/build-packages.cmd
index 3297bfc214..f80e39fd94 100644
--- a/build-packages.cmd
+++ b/build-packages.cmd
@@ -1,4 +1,4 @@
-@if "%_echo%" neq "on" echo off
+@if not defined _echo @echo off
setlocal EnableDelayedExpansion
set "__ProjectDir=%~dp0"
@@ -7,39 +7,9 @@ set allargs=%*
if /I [%1] == [/?] goto Usage
if /I [%1] == [/help] goto Usage
-call %__ProjectDir%/run.cmd build-packages -Project=%__ProjectDir%/src/.nuget/Microsoft.NETCore.Runtime.CoreClr/Microsoft.NETCore.Runtime.CoreCLR.builds -FilterToOSGroup=Windows_NT %allargs%
+call %__ProjectDir%/run.cmd build-packages -Project=%__ProjectDir%\src\.nuget\packages.builds -FilterToOSGroup=Windows_NT %allargs%
if NOT [!ERRORLEVEL!]==[0] (
- echo ERROR: An error occurred while building CoreCLR Runtime package, see build-packages.log for more details.
- exit /b 1
-)
-
-call %__ProjectDir%/run.cmd build-packages -Project=%__ProjectDir%/src/.nuget/Microsoft.NETCore.Jit/Microsoft.NETCore.Jit.builds -FilterToOSGroup=Windows_NT %allargs%
-if NOT [!ERRORLEVEL!]==[0] (
- echo ERROR: An error occurred while building Jit package, see build-packages.log for more details.
- exit /b 1
-)
-
-call %__ProjectDir%/run.cmd build-packages -Project=%__ProjectDir%/src/.nuget/Microsoft.NETCore.ILAsm/Microsoft.NETCore.ILAsm.builds -FilterToOSGroup=Windows_NT %allargs%
-if NOT [!ERRORLEVEL!]==[0] (
- echo ERROR: An error occurred while building ILAsm package, see build-packages.log for more details.
- exit /b 1
-)
-
-call %__ProjectDir%/run.cmd build-packages -Project=%__ProjectDir%/src/.nuget/Microsoft.NETCore.ILDAsm/Microsoft.NETCore.ILDAsm.builds -FilterToOSGroup=Windows_NT %allargs%
-if NOT [!ERRORLEVEL!]==[0] (
- echo ERROR: An error occurred while building ILDAsm package, see build-packages.log for more details.
- exit /b 1
-)
-
-call %__ProjectDir%/run.cmd build-packages -Project=%__ProjectDir%/src/.nuget/Microsoft.TargetingPack.Private.CoreCLR/Microsoft.TargetingPack.Private.CoreCLR.pkgproj -FilterToOSGroup=Windows_NT %allargs%
-if NOT [!ERRORLEVEL!]==[0] (
- echo ERROR: An error occurred while building CoreCLR TargetingPack package, see build-packages.log for more details.
- exit /b 1
-)
-
-call %__ProjectDir%/run.cmd build-packages -Project=%__ProjectDir%\src\.nuget\Microsoft.NETCore.TestHost\Microsoft.NETCore.TestHost.builds -FilterToOSGroup=Windows_NT %allargs%
-if NOT [!ERRORLEVEL!]==[0] (
- echo ERROR: An error occurred while building packages, see %packagesLog% for more details.
+ echo ERROR: An error occurred while building packages, see build-packages.log for more details.
exit /b 1
)
diff --git a/build-packages.sh b/build-packages.sh
index 5e03ac294b..0dd1035f6d 100755
--- a/build-packages.sh
+++ b/build-packages.sh
@@ -3,14 +3,56 @@
usage()
{
echo "Builds the NuGet packages from the binaries that were built in the Build product binaries step."
- echo "Usage: build-packages -BuildArch -BuildType"
- echo "arch can be x64, x86, arm, arm64 (default is x64)"
- echo "configuration can be release, checked, debug (default is debug)"
+ echo "Usage: build-packages -BuildArch -BuildType [portableLinux]"
+ echo "BuildArch can be x64, x86, arm, arm64 (default is x64)"
+ echo "BuildType can be release, checked, debug (default is debug)"
+ echo "portableLinux - build for Portable Linux Distribution"
echo
exit 1
}
__ProjectRoot="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+__PortableLinux=0
+
+# Use uname to determine what the OS is.
+OSName=$(uname -s)
+case $OSName in
+ Linux)
+ __BuildOS=Linux
+ __HostOS=Linux
+ ;;
+
+ Darwin)
+ __BuildOS=OSX
+ __HostOS=OSX
+ ;;
+
+ FreeBSD)
+ __BuildOS=FreeBSD
+ __HostOS=FreeBSD
+ ;;
+
+ OpenBSD)
+ __BuildOS=OpenBSD
+ __HostOS=OpenBSD
+ ;;
+
+ NetBSD)
+ __BuildOS=NetBSD
+ __HostOS=NetBSD
+ ;;
+
+ SunOS)
+ __BuildOS=SunOS
+ __HostOS=SunOS
+ ;;
+
+ *)
+ echo "Unsupported OS $OSName detected, configuring as if for Linux"
+ __BuildOS=Linux
+ __HostOS=Linux
+ ;;
+esac
unprocessedBuildArgs=
@@ -28,46 +70,34 @@ while :; do
unprocessedBuildArgs="$unprocessedBuildArgs $1"
__Arch=$(echo $1| cut -d'=' -f 2)
;;
+
+ portableLinux)
+ if [ "$__BuildOS" == "Linux" ]; then
+ __PortableLinux=1
+ else
+ echo "ERROR: portableLinux not supported for non-Linux platforms."
+ exit 1
+ fi
+ ;;
*)
unprocessedBuildArgs="$unprocessedBuildArgs $1"
esac
shift
done
-$__ProjectRoot/run.sh build-packages -Project=$__ProjectRoot/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/Microsoft.NETCore.Runtime.CoreCLR.builds -DistroRid=\${OSRid}-$__Arch -UseSharedCompilation=false -BuildNugetPackage=false $unprocessedBuildArgs
-if [ $? -ne 0 ]
-then
- echo "ERROR: An error occurred while building packages; See build-packages.log for more details."
- exit 1
-fi
-
-$__ProjectRoot/run.sh build-packages -Project=$__ProjectRoot/src/.nuget/Microsoft.NETCore.Jit/Microsoft.NETCore.Jit.builds -DistroRid=\${OSRid}-$__Arch -UseSharedCompilation=false -BuildNugetPackage=false $unprocessedBuildArgs
-if [ $? -ne 0 ]
-then
- echo "ERROR: An error occurred while building packages; See build-packages.log for more details."
- exit 1
+# Portable builds target the base RID only for Linux based platforms
+if [ $__PortableLinux == 1 ]; then
+ export __DistroRid="linux-$__Arch"
+else
+ export __DistroRid="\${OSRid}-$__Arch"
fi
-$__ProjectRoot/run.sh build-packages -Project=$__ProjectRoot/src/.nuget/Microsoft.NETCore.ILAsm/Microsoft.NETCore.ILAsm.builds -DistroRid=\${OSRid}-$__Arch -UseSharedCompilation=false -BuildNugetPackage=false $unprocessedBuildArgs
+$__ProjectRoot/run.sh build-packages -Project=$__ProjectRoot/src/.nuget/packages.builds -DistroRid=$__DistroRid -UseSharedCompilation=false -BuildNugetPackage=false $unprocessedBuildArgs
if [ $? -ne 0 ]
then
echo "ERROR: An error occurred while building packages; See build-packages.log for more details."
exit 1
fi
-$__ProjectRoot/run.sh build-packages -Project=$__ProjectRoot/src/.nuget/Microsoft.NETCore.ILDAsm/Microsoft.NETCore.ILDAsm.builds -DistroRid=\${OSRid}-$__Arch -UseSharedCompilation=false -BuildNugetPackage=false $unprocessedBuildArgs
-if [ $? -ne 0 ]
-then
- echo "ERROR: An error occurred while building packages; See build-packages.log for more details."
- exit 1
-fi
-
-# Build the TestHost package
-$__ProjectRoot/run.sh build-packages -Project=$__ProjectRoot/src/.nuget/Microsoft.NETCore.TestHost/Microsoft.NETCore.TestHost.builds -DistroRid=\${OSRid}-$__Arch -UseSharedCompilation=false -BuildNugetPackage=false $unprocessedBuildArgs
-if [ $? -ne 0 ]; then
- echo "ERROR: An error occurred while building packages, see $build_packages_log for more details."
- exit 1
-fi
-
echo "Done building packages."
exit 0
diff --git a/build-test.cmd b/build-test.cmd
index d22b489bd4..215fb53034 100644
--- a/build-test.cmd
+++ b/build-test.cmd
@@ -1,4 +1,4 @@
-@if not defined __echo @echo off
+@if not defined _echo @echo off
setlocal EnableDelayedExpansion
:: Set the default arguments for build
@@ -28,6 +28,9 @@ set "__args= %*"
set processedArgs=
set __unprocessedBuildArgs=
set __RunArgs=
+set __BuildAgainstPackages=
+set __BuildAgainstPackagesArg=
+set __RuntimeId=
:Arg_Loop
if "%1" == "" goto ArgsDone
@@ -48,6 +51,8 @@ if /i "%1" == "checked" (set __BuildType=Checked&set processedArgs
if /i "%1" == "skipmanaged" (set __SkipManaged=1&set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
if /i "%1" == "updateinvalidpackages" (set __UpdateInvalidPackagesArg=1&set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
if /i "%1" == "toolset_dir" (set __ToolsetDir=%2&set __PassThroughArgs=%__PassThroughArgs% %2&set processedArgs=!processedArgs! %1 %2&shift&shift&goto Arg_Loop)
+if /i "%1" == "buildagainstpackages" (set __BuildAgainstPackages=1&set __BuildAgainstPackagesArg=-BuildTestsAgainstPackages&shift&goto Arg_Loop)
+if /i "%1" == "runtimeid" (set __RuntimeId=%2&set processedArgs=!processedArgs! %1 %2&shift&shift&goto Arg_Loop)
if [!processedArgs!]==[] (
call set __UnprocessedBuildArgs=!__args!
@@ -93,7 +98,7 @@ if not exist "%__LogsDir%" md "%__LogsDir%"
echo %__MsgPrefix%Checking prerequisites
:: Eval the output from probe-win1.ps1
-for /f "delims=" %%a in ('powershell -NoProfile -ExecutionPolicy RemoteSigned "& ""%__SourceDir%\pal\tools\probe-win.ps1"""') do %%a
+for /f "delims=" %%a in ('powershell -NoProfile -ExecutionPolicy ByPass "& ""%__SourceDir%\pal\tools\probe-win.ps1"""') do %%a
REM =========================================================================================
REM ===
@@ -129,7 +134,7 @@ if defined __ToolsetDir (
:: Set the environment for the native build
echo %__MsgPrefix%Using environment: "%__VSToolsRoot%\..\..\VC\vcvarsall.bat" %__VCBuildArch%
call "%__VSToolsRoot%\..\..\VC\vcvarsall.bat" %__VCBuildArch%
-@if defined __echo @echo on
+@if defined _echo @echo on
if not defined VSINSTALLDIR (
echo %__MsgPrefix%Error: VSINSTALLDIR variable not defined.
@@ -141,7 +146,7 @@ if not exist "%VSINSTALLDIR%DIA SDK" goto NoDIA
pushd "%__NativeTestIntermediatesDir%"
call "%__SourceDir%\pal\tools\gen-buildsys-win.bat" ""%__ProjectFilesDir%"" %__VSVersion% %__BuildArch%
-@if defined __echo @echo on
+@if defined _echo @echo on
popd
if not exist "%__NativeTestIntermediatesDir%\install.vcxproj" (
@@ -176,21 +181,56 @@ if errorlevel 1 (
:skipnative
-if defined __SkipManaged exit /b 0
+set __BuildLogRootName=Restore_Product
+set __BuildLog=%__LogsDir%\%__BuildLogRootName%_%__BuildOS%__%__BuildArch%__%__BuildType%.log
+set __BuildWrn=%__LogsDir%\%__BuildLogRootName%_%__BuildOS%__%__BuildArch%__%__BuildType%.wrn
+set __BuildErr=%__LogsDir%\%__BuildLogRootName%_%__BuildOS%__%__BuildArch%__%__BuildType%.err
+set __msbuildLog=/flp:Verbosity=normal;LogFile="%__BuildLog%"
+set __msbuildWrn=/flp1:WarningsOnly;LogFile="%__BuildWrn%"
+set __msbuildErr=/flp2:ErrorsOnly;LogFile="%__BuildErr%"
+if not defined __BuildAgainstPackages goto SkipRestoreProduct
REM =========================================================================================
REM ===
-REM === Managed test build section
+REM === Restore product binaries from packages
REM ===
REM =========================================================================================
-echo %__MsgPrefix%Starting the Managed Tests Build
+set "__TestWorkingDir=%__RootBinDir%\tests\%__BuildOS%.%__BuildArch%.%__BuildType%"
+if not defined XunitTestBinBase set XunitTestBinBase=%__TestWorkingDir%
+set "CORE_ROOT=%XunitTestBinBase%\Tests\Core_Root"
+set "CORE_OVERLAY=%XunitTestBinBase%\Tests\coreoverlay"
-if not defined VSINSTALLDIR (
- echo %__MsgPrefix%Error: buildtest.cmd should be run from a Visual Studio Command Prompt. Please see https://github.com/dotnet/coreclr/blob/master/Documentation/project-docs/developer-guide.md for build instructions.
+call %__ProjectDir%\run.cmd build -Project=%__ProjectDir%\tests\build.proj -UpdateDependencies -BatchRestorePackages -MsBuildLog=!__msbuildLog! -MsBuildWrn=!__msbuildWrn! -MsBuildErr=!__msbuildErr! %__RunArgs% %__BuildAgainstPackagesArg% %__unprocessedBuildArgs%
+
+set __BuildLogRootName=Tests_GenerateRuntimeLayout
+
+call %__ProjectDir%\run.cmd build -Project=%__ProjectDir%\tests\runtest.proj -BinPlaceRef -BinPlaceProduct -CopyCrossgenToProduct -MsBuildLog=!__msbuildLog! -MsBuildWrn=!__msbuildWrn! -MsBuildErr=!__msbuildErr! %__RunArgs% %__BuildAgainstPackagesArg% %__unprocessedBuildArgs%
+if errorlevel 1 (
+ echo BinPlace of mscorlib.dll failed
exit /b 1
)
+if defined __RuntimeId (
+
+ if not exist %__PackagesDir%\TestNativeBins (
+ echo %__MsgPrefix%Error: Ensure you have run sync.cmd -ab before building a non-Windows test overlay against packages
+ exit /b 1
+ )
+
+ call %__ProjectDir%\run.cmd build -Project=%__ProjectDir%\tests\runtest.proj -CreateNonWindowsTestOverlay -RuntimeId="%__RuntimeId%" -MsBuildLog=!__msbuildLog! -MsBuildWrn=!__msbuildWrn! -MsBuildErr=!__msbuildErr! %__RunArgs% %__BuildAgainstPackagesArg% %__unprocessedBuildArgs%
+ for /R %__PackagesDir%\TestNativeBins\%__RuntimeId% %%f in (*.so) do copy %%f %Core_Overlay%
+ for /R %__PackagesDir%\TestNativeBins\%__RuntimeId% %%f in (*.dylib) do copy %%f %Core_Overlay%
+
+ echo %__MsgPrefix% Created the runtime layout for %__RuntimeId% in %CORE_OVERLAY%
+)
+
+echo %__MsgPrefix% Created the runtime layout with all dependencies in %CORE_ROOT%
+
+:SkipRestoreProduct
+
+if defined __SkipManaged exit /b 0
+
set __BuildLogRootName=Tests_Managed
set __BuildLog=%__LogsDir%\%__BuildLogRootName%_%__BuildOS%__%__BuildArch%__%__BuildType%.log
set __BuildWrn=%__LogsDir%\%__BuildLogRootName%_%__BuildOS%__%__BuildArch%__%__BuildType%.wrn
@@ -199,6 +239,19 @@ set __msbuildLog=/flp:Verbosity=normal;LogFile="%__BuildLog%"
set __msbuildWrn=/flp1:WarningsOnly;LogFile="%__BuildWrn%"
set __msbuildErr=/flp2:ErrorsOnly;LogFile="%__BuildErr%"
+REM =========================================================================================
+REM ===
+REM === Managed test build section
+REM ===
+REM =========================================================================================
+
+echo %__MsgPrefix%Starting the Managed Tests Build
+
+if not defined VSINSTALLDIR (
+ echo %__MsgPrefix%Error: buildtest.cmd should be run from a Visual Studio Command Prompt. Please see https://github.com/dotnet/coreclr/blob/master/Documentation/project-docs/developer-guide.md for build instructions.
+ exit /b 1
+)
+
if defined __UpdateInvalidPackagesArg (
set __up=-updateinvalidpackageversions
)
@@ -253,6 +306,17 @@ echo. -? -h -help: view this message.
echo Build architecture: -buildArch: only x64 is currently allowed ^(default: x64^).
echo Build type: -buildType: one of Debug, Checked, Release ^(default: Debug^).
echo updateinvalidpackageversions: Runs the target to update package versions.
+echo buildagainstpackages: builds tests against restored packages, instead of against a built product.
+echo runtimeid ^<ID^>: Builds a test overlay for the specified OS (Only supported when building against packages). Supported IDs are:
+echo debian.8-x64: Builds overlay for Debian 8
+echo fedora.23-x64: Builds overlay for Fedora 23
+echo opensuse.13.2-x64: Builds overlay for OpenSUSE 13.2
+echo opensuse.42.1-x64: Builds overlay for OpenSUSE 42.1
+echo osx.10.10-x64: Builds overlay for OSX 10.10
+echo rhel.7-x64: Builds overlay for RHEL 7 or CentOS
+echo ubuntu.14.04-x64: Builds overlay for Ubuntu 14.04
+echo ubuntu.16.04-x64: Builds overlay for Ubuntu 16.04
+echo ubuntu.16.10-x64: Builds overlay for Ubuntu 16.10
echo -- ... : all arguments following this tag will be passed directly to msbuild.
echo -priority=^<N^> : specify a set of test that will be built and run, with priority N.
echo 0: Build only priority 0 cases as essential testcases (default)
diff --git a/build.cmd b/build.cmd
index 2dc479c2c3..f8c49e397a 100644
--- a/build.cmd
+++ b/build.cmd
@@ -1,6 +1,7 @@
-@if not defined __echo @echo off
+@if not defined _echo @echo off
setlocal EnableDelayedExpansion EnableExtensions
+echo Starting Build at %TIME%
set __ThisScriptFull="%~f0"
set __VSToolsRoot=%VS140COMNTOOLS%
:: Note that the msbuild project files (specifically, dir.proj) will use the following variables, if set:
@@ -51,6 +52,7 @@ set __BuildTypeDebug=0
set __BuildTypeChecked=0
set __BuildTypeRelease=0
set __BuildJit32="-DBUILD_JIT32=0"
+set __BuildStandaloneGC="-DFEATURE_STANDALONE_GC=0"
set __PgoInstrument=0
@@ -107,6 +109,12 @@ if /i "%1" == "usenmakemakefiles" (set __NMakeMakefiles=1&set __ConfigureOnly=
if /i "%1" == "buildjit32" (set __BuildJit32="-DBUILD_JIT32=1"&set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
if /i "%1" == "pgoinstrument" (set __PgoInstrument=1&set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
if /i "%1" == "toolset_dir" (set __ToolsetDir=%2&set __PassThroughArgs=%__PassThroughArgs% %2&set processedArgs=!processedArgs! %1 %2&shift&shift&goto Arg_Loop)
+if /i "%1" == "compatjitcrossgen" (set __CompatJitCrossgen=1&set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
+if /i "%1" == "legacyjitcrossgen" (set __LegacyJitCrossgen=1&set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
+if /i "%1" == "buildstandalonegc" (set __BuildStandaloneGC="-DFEATURE_STANDALONE_GC=1"&set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
+
+@REM The following can be deleted once the CI system that passes it is updated to not pass it.
+if /i "%1" == "altjitcrossgen" (set processedArgs=!processedArgs! %1&shift&goto Arg_Loop)
if [!processedArgs!]==[] (
call set __UnprocessedBuildArgs=!__args!
@@ -170,13 +178,18 @@ if not exist "%__BinDir%" md "%__BinDir%"
if not exist "%__IntermediatesDir%" md "%__IntermediatesDir%"
if not exist "%__LogsDir%" md "%__LogsDir%"
+REM It is convinient to have your Nuget search path include the location where the build
+REM will plass packages. However nuget used during the build will fail if that directory
+REM does not exist. Avoid this in at least one case by agressively creating the directory.
+if not exist "%__BinDir%\.nuget\pkg" md "%__BinDir%\.nuget\pkg"
+
echo %__MsgPrefix%Commencing CoreCLR Repo build
:: Set the remaining variables based upon the determined build configuration
echo %__MsgPrefix%Checking prerequisites
:: Eval the output from probe-win1.ps1
-for /f "delims=" %%a in ('powershell -NoProfile -ExecutionPolicy RemoteSigned "& ""%__SourceDir%\pal\tools\probe-win.ps1"""') do %%a
+for /f "delims=" %%a in ('powershell -NoProfile -ExecutionPolicy ByPass "& ""%__SourceDir%\pal\tools\probe-win.ps1"""') do %%a
REM =========================================================================================
REM ===
@@ -191,15 +204,6 @@ call "%__VSToolsRoot%\VsDevCmd.bat"
REM =========================================================================================
REM ===
-REM === Restore optimization profile data
-REM ===
-REM =========================================================================================
-
-echo %__MsgPrefix%Restoring the OptimizationData Package
-@call %__ProjectDir%\run.cmd sync -optdata
-
-REM =========================================================================================
-REM ===
REM === Build the CLR VM
REM ===
REM =========================================================================================
@@ -224,25 +228,32 @@ if %__BuildNative% EQU 1 (
:: Set the environment for the native build
set __VCBuildArch=x86_amd64
if /i "%__BuildArch%" == "x86" ( set __VCBuildArch=x86 )
- if /i "%__BuildArch%" == "arm" (set __VCBuildArch=x86_arm)
+ if /i "%__BuildArch%" == "arm" (
+ set __VCBuildArch=x86_arm
+
+ REM Make CMake pick the highest installed version in the 10.0.* range
+ set ___SDKVersion="-DCMAKE_SYSTEM_VERSION=10.0"
+ )
+
echo %__MsgPrefix%Using environment: "%__VSToolsRoot%\..\..\VC\vcvarsall.bat" !__VCBuildArch!
call "%__VSToolsRoot%\..\..\VC\vcvarsall.bat" !__VCBuildArch!
- @if defined __echo @echo on
+ @if defined _echo @echo on
if not defined VSINSTALLDIR (
echo %__MsgPrefix%Error: VSINSTALLDIR variable not defined.
exit /b 1
)
if not exist "!VSINSTALLDIR!DIA SDK" goto NoDIA
+
:GenVSSolution
if defined __SkipConfigure goto SkipConfigure
echo %__MsgPrefix%Regenerating the Visual Studio solution
pushd "%__IntermediatesDir%"
- set __ExtraCmakeArgs="-DCLR_CMAKE_TARGET_OS=%__BuildOs%" "-DCLR_CMAKE_PACKAGES_DIR=%__PackagesDir%" "-DCLR_CMAKE_PGO_INSTRUMENT=%__PgoInstrument%"
- call "%__SourceDir%\pal\tools\gen-buildsys-win.bat" "%__ProjectDir%" %__VSVersion% %__BuildArch% %__BuildJit32% !__ExtraCmakeArgs!
- @if defined __echo @echo on
+ set __ExtraCmakeArgs=!___SDKVersion! "-DCLR_CMAKE_TARGET_OS=%__BuildOs%" "-DCLR_CMAKE_PACKAGES_DIR=%__PackagesDir%" "-DCLR_CMAKE_PGO_INSTRUMENT=%__PgoInstrument%"
+ call "%__SourceDir%\pal\tools\gen-buildsys-win.bat" "%__ProjectDir%" %__VSVersion% %__BuildArch% %__BuildJit32% %__BuildStandaloneGC% !__ExtraCmakeArgs!
+ @if defined _echo @echo on
popd
:SkipConfigure
if defined __ConfigureOnly goto SkipNativeBuild
@@ -286,7 +297,7 @@ if /i "%__DoCrossArchBuild%"=="1" (
set __VCBuildArch=x86_amd64
if /i "%__CrossArch%" == "x86" ( set __VCBuildArch=x86 )
@call "%__VSToolsRoot%\..\..\VC\vcvarsall.bat" !__VCBuildArch!
- @if defined __echo @echo on
+ @if defined _echo @echo on
if not exist "%__CrossCompIntermediatesDir%" md "%__CrossCompIntermediatesDir%"
if defined __SkipConfigure goto SkipConfigureCrossBuild
@@ -296,7 +307,7 @@ if /i "%__DoCrossArchBuild%"=="1" (
set "__CMakeBinDir=!__CMakeBinDir:\=/!"
set __ExtraCmakeArgs="-DCLR_CROSS_COMPONENTS_BUILD=1" "-DCLR_CMAKE_TARGET_ARCH=%__BuildArch%" "-DCLR_CMAKE_TARGET_OS=%__BuildOs%" "-DCLR_CMAKE_PACKAGES_DIR=%__PackagesDir%" "-DCLR_CMAKE_PGO_INSTRUMENT=%__PgoInstrument%"
call "%__SourceDir%\pal\tools\gen-buildsys-win.bat" "%__ProjectDir%" %__VSVersion% %__CrossArch% !__ExtraCmakeArgs!
- @if defined __echo @echo on
+ @if defined _echo @echo on
popd
:SkipConfigureCrossBuild
if not exist "%__CrossCompIntermediatesDir%\install.vcxproj" (
@@ -357,13 +368,32 @@ if %__BuildCoreLib% EQU 1 (
)
)
+REM Need diasymreader.dll on your path for /CreatePdb
+set PATH=%PATH%;%WinDir%\Microsoft.Net\Framework64\V4.0.30319;%WinDir%\Microsoft.Net\Framework\V4.0.30319
+
if %__BuildNativeCoreLib% EQU 1 (
echo %__MsgPrefix%Generating native image of System.Private.CoreLib for %__BuildOS%.%__BuildArch%.%__BuildType%
-
+
+ if "%__CompatJitCrossgen%"=="1" (
+ set COMPlus_UseWindowsX86CoreLegacyJit=1
+ )
+
+ if "%__LegacyJitCrossgen%"=="1" (
+ set COMPlus_AltJit=*
+ set COMPlus_AltJitNgen=*
+ set COMPlus_AltJitName=legacyjit.dll
+ )
+
echo "%__CrossgenExe%" /Platform_Assemblies_Paths "%__BinDir%" /out "%__BinDir%\System.Private.CoreLib.ni.dll" "%__BinDir%\System.Private.CoreLib.dll"
"%__CrossgenExe%" /Platform_Assemblies_Paths "%__BinDir%" /out "%__BinDir%\System.Private.CoreLib.ni.dll" "%__BinDir%\System.Private.CoreLib.dll" > "%__CrossGenCoreLibLog%" 2>&1
if NOT !errorlevel! == 0 (
- echo %__MsgPrefix%Error: CrossGen System.Private.CoreLib build failed. Refer to the build log file for details:
+ echo %__MsgPrefix%Error: CrossGen System.Private.CoreLib build failed. Refer to %__CrossGenCoreLibLog%
+ echo %__CrossGenCoreLibLog%
+ exit /b 1
+ )
+ "%__CrossgenExe%" /Platform_Assemblies_Paths "%__BinDir%" /CreatePdb "%__BinDir%\PDB" "%__BinDir%\System.Private.CoreLib.ni.dll" >> "%__CrossGenCoreLibLog%" 2>&1
+ if NOT !errorlevel! == 0 (
+ echo %__MsgPrefix%Error: CrossGen /CreatePdb System.Private.CoreLib build failed. Refer to %__CrossGenCoreLibLog%
echo %__CrossGenCoreLibLog%
exit /b 1
)
@@ -372,8 +402,21 @@ if %__BuildNativeCoreLib% EQU 1 (
set "__CrossGenCoreLibLog=%__LogsDir%\CrossgenMSCoreLib_%__BuildOS%__%__BuildArch%__%__BuildType%.log"
set "__CrossgenExe=%__CrossComponentBinDir%\crossgen.exe"
+
"!__CrossgenExe!" /Platform_Assemblies_Paths "%__BinDir%" /out "%__BinDir%\mscorlib.ni.dll" "%__BinDir%\mscorlib.dll" > "!__CrossGenCoreLibLog!" 2>&1
- if NOT !errorlevel! == 0 (
+ set err=!errorlevel!
+
+ if "%__CompatJitCrossgen%"=="1" (
+ set COMPlus_UseWindowsX86CoreLegacyJit=
+ )
+
+ if "%__LegacyJitCrossgen%"=="1" (
+ set COMPlus_AltJit=
+ set COMPlus_AltJitNgen=
+ set COMPlus_AltJitName=
+ )
+
+ if NOT !err! == 0 (
echo %__MsgPrefix%Error: CrossGen mscorlib facade build failed. Refer to the build log file for details:
echo !__CrossGenCoreLibLog!
exit /b 1
@@ -381,6 +424,8 @@ if %__BuildNativeCoreLib% EQU 1 (
)
if %__BuildPackages% EQU 1 (
+ echo %__MsgPrefix%Building Packages for %__BuildOS%.%__BuildArch%.%__BuildType%
+
set __MsbuildLog=/flp:Verbosity=normal;LogFile="%__LogsDir%\Nuget_%__BuildOS%__%__BuildArch%__%__BuildType%.log"
set __MsbuildWrn=/flp1:WarningsOnly;LogFile="%__LogsDir%\Nuget_%__BuildOS%__%__BuildArch%__%__BuildType%.wrn"
set __MsbuildErr=/flp2:ErrorsOnly;LogFile="%__LogsDir%\Nuget_%__BuildOS%__%__BuildArch%__%__BuildType%.err"
@@ -427,7 +472,7 @@ REM === All builds complete!
REM ===
REM =========================================================================================
-echo %__MsgPrefix%Repo successfully built.
+echo %__MsgPrefix%Repo successfully built. Finished at %TIME%
echo %__MsgPrefix%Product binaries are available at !__BinDir!
if %__BuildTests% EQU 1 (
echo %__MsgPrefix%Test binaries are available at !__TestBinDir!
diff --git a/build.proj b/build.proj
index c8d7a5d76b..7df2904e36 100644
--- a/build.proj
+++ b/build.proj
@@ -24,10 +24,6 @@
<Delete Files="$(BinDir)System.Private.CoreLib.*" />
</Target>
- <Target Name="RestoreOptData">
- <Exec Command="$(DnuRestoreCommand) &quot;$(SourceDir).nuget/optdata/project.json&quot; --source https://dotnet.myget.org/F/dotnet-core-optimization-data/api/v3/index.json" />
- </Target>
-
<Target Name="RestoreNETCorePlatforms" AfterTargets="Build" Condition="'$(RestoreDuringBuild)'=='true'">
<Exec Command="$(DnuRestoreCommand) &quot;$(SourceDir).nuget/init/project.json&quot; --source https://dotnet.myget.org/F/dotnet-core/api/v3/index.json" />
</Target>
diff --git a/build.sh b/build.sh
index e639ca0197..ca27844933 100755
--- a/build.sh
+++ b/build.sh
@@ -42,6 +42,7 @@ usage()
echo "skipmscorlib - do not build mscorlib.dll."
echo "skiptests - skip the tests in the 'tests' subdirectory."
echo "skipnuget - skip building nuget packages."
+ echo "portableLinux - build for Portable Linux Distribution"
echo "verbose - optional argument to enable verbose build output."
echo "-skiprestore: skip restoring packages ^(default: packages are restored during build^)."
echo "-disableoss: Disable Open Source Signing for System.Private.CoreLib."
@@ -56,19 +57,41 @@ usage()
exit 1
}
-initDistroRid()
+initHostDistroRid()
{
- if [ "$__BuildOS" == "Linux" ]; then
+ if [ "$__HostOS" == "Linux" ]; then
if [ ! -e /etc/os-release ]; then
echo "WARNING: Can not determine runtime id for current distro."
- export __DistroRid=""
+ __HostDistroRid=""
else
source /etc/os-release
- export __DistroRid="$ID.$VERSION_ID-$__HostArch"
+ __HostDistroRid="$ID.$VERSION_ID-$__HostArch"
fi
fi
}
+initTargetDistroRid()
+{
+ if [ $__CrossBuild == 1 ]; then
+ if [ "$__BuildOS" == "Linux" ]; then
+ if [ ! -e $ROOTFS_DIR/etc/os-release ]; then
+ echo "WARNING: Can not determine runtime id for current distro."
+ export __DistroRid=""
+ else
+ source $ROOTFS_DIR/etc/os-release
+ export __DistroRid="$ID.$VERSION_ID-$__BuildArch"
+ fi
+ fi
+ else
+ export __DistroRid="$__HostDistroRid"
+ fi
+
+ # Portable builds target the base RID only for Linux based platforms
+ if [ $__PortableLinux == 1 ]; then
+ export __DistroRid="linux-$__BuildArch"
+ fi
+}
+
setup_dirs()
{
echo Setting up directories for build
@@ -77,6 +100,11 @@ setup_dirs()
mkdir -p "$__BinDir"
mkdir -p "$__LogsDir"
mkdir -p "$__IntermediatesDir"
+
+ if [ $__CrossBuild == 1 ]; then
+ mkdir -p "$__CrossComponentBinDir"
+ mkdir -p "$__CrossCompIntermediatesDir"
+ fi
}
# Check the system to ensure the right prereqs are in place
@@ -93,11 +121,10 @@ check_prereqs()
}
-build_coreclr()
-{
+generate_event_logging_sources()
+{
if [ $__SkipCoreCLR == 1 ]; then
- echo "Skipping CoreCLR build."
return
fi
@@ -143,10 +170,23 @@ build_coreclr()
fi
rm -rf "$__GeneratedIntermediateEventProvider"
+}
- # All set to commence the build
+build_native()
+{
+ skipCondition=$1
+ platformArch="$2"
+ intermediatesForBuild="$3"
+ extraCmakeArguments="$4"
+ message="$5"
+
+ if [ $skipCondition == 1 ]; then
+ echo "Skipping $message build."
+ return
+ fi
- echo "Commencing build of native components for $__BuildOS.$__BuildArch.$__BuildType in $__IntermediatesDir"
+ # All set to commence the build
+ echo "Commencing build of $message for $__BuildOS.$__BuildArch.$__BuildType in $intermediatesForBuild"
generator=""
buildFile="Makefile"
@@ -167,34 +207,34 @@ build_coreclr()
if [ $__SkipConfigure == 0 ]; then
# if msbuild is not supported, then set __SkipGenerateVersion to 1
if [ $__isMSBuildOnNETCoreSupported == 0 ]; then __SkipGenerateVersion=1; fi
- # Drop version.c file
- __versionSourceFile=$__IntermediatesDir/version.cpp
+ # Drop version.cpp file
+ __versionSourceFile="$intermediatesForBuild/version.cpp"
if [ $__SkipGenerateVersion == 0 ]; then
+ pwd
"$__ProjectRoot/run.sh" build -Project=$__ProjectDir/build.proj -generateHeaderUnix -NativeVersionSourceFile=$__versionSourceFile $__RunArgs $__UnprocessedBuildArgs
else
+ # Generate the dummy version.cpp, but only if it didn't exist to make sure we don't trigger unnecessary rebuild
__versionSourceLine="static char sccsid[] __attribute__((used)) = \"@(#)No version information produced\";"
- echo $__versionSourceLine > $__versionSourceFile
+ if [ -e $__versionSourceFile ]; then
+ read existingVersionSourceLine < $__versionSourceFile
+ fi
+ if [ "$__versionSourceLine" != "$existingVersionSourceLine" ]; then
+ echo $__versionSourceLine > $__versionSourceFile
+ fi
fi
- echo "Restoring the OptimizationData package"
- "$__ProjectRoot/run.sh" sync -optdata
-
- pushd "$__IntermediatesDir"
+ pushd "$intermediatesForBuild"
# Regenerate the CMake solution
- __ExtraCmakeArgs="-DCLR_CMAKE_TARGET_OS=$__BuildOS -DCLR_CMAKE_PACKAGES_DIR=$__PackagesDir -DCLR_CMAKE_PGO_INSTRUMENT=$__PgoInstrument"
- echo "Invoking \"$__ProjectRoot/src/pal/tools/gen-buildsys-clang.sh\" \"$__ProjectRoot\" $__ClangMajorVersion $__ClangMinorVersion $__BuildArch $__BuildType $__CodeCoverage $__IncludeTests $generator $__ExtraCmakeArgs $__cmakeargs"
- "$__ProjectRoot/src/pal/tools/gen-buildsys-clang.sh" "$__ProjectRoot" $__ClangMajorVersion $__ClangMinorVersion $__BuildArch $__BuildType $__CodeCoverage $__IncludeTests $generator "$__ExtraCmakeArgs" "$__cmakeargs"
+ echo "Invoking \"$__ProjectRoot/src/pal/tools/gen-buildsys-clang.sh\" \"$__ProjectRoot\" $__ClangMajorVersion $__ClangMinorVersion $platformArch $__BuildType $__CodeCoverage $__IncludeTests $generator $extraCmakeArguments $__cmakeargs"
+ "$__ProjectRoot/src/pal/tools/gen-buildsys-clang.sh" "$__ProjectRoot" $__ClangMajorVersion $__ClangMinorVersion $platformArch $__BuildType $__CodeCoverage $__IncludeTests $generator "$extraCmakeArguments" "$__cmakeargs"
popd
fi
- # Check that the makefiles were created.
- pushd "$__IntermediatesDir"
-
- if [ ! -f "$__IntermediatesDir/$buildFile" ]; then
- echo "Failed to generate native component build project!"
+ if [ ! -f "$intermediatesForBuild/$buildFile" ]; then
+ echo "Failed to generate $message build project!"
exit 1
fi
-
+
# Get the number of processors available to the scheduler
# Other techniques such as `nproc` only get the number of
# processors available to a single process.
@@ -206,21 +246,24 @@ build_coreclr()
NumProc=$(($(getconf _NPROCESSORS_ONLN)+1))
fi
- # Build CoreCLR
-
+ # Build
if [ $__ConfigureOnly == 1 ]; then
- echo "Skipping CoreCLR build."
+ echo "Finish configuration & skipping $message build."
return
fi
+ # Check that the makefiles were created.
+ pushd "$intermediatesForBuild"
+
echo "Executing $buildTool install -j $NumProc"
$buildTool install -j $NumProc
if [ $? != 0 ]; then
- echo "Failed to build coreclr components."
+ echo "Failed to build $message."
exit 1
fi
- popd
+
+ popd
}
isMSBuildOnNETCoreSupported()
@@ -230,7 +273,7 @@ isMSBuildOnNETCoreSupported()
if [ "$__HostArch" == "x64" ]; then
if [ "$__HostOS" == "Linux" ]; then
- case "$__DistroRid" in
+ case "$__HostDistroRid" in
"centos.7-x64")
__isMSBuildOnNETCoreSupported=1
;;
@@ -261,6 +304,9 @@ isMSBuildOnNETCoreSupported()
"ubuntu.16.10-x64")
__isMSBuildOnNETCoreSupported=1
;;
+ "alpine.3.4.3-x64")
+ __isMSBuildOnNETCoreSupported=1
+ ;;
*)
esac
elif [ "$__HostOS" == "OSX" ]; then
@@ -475,9 +521,12 @@ __CrossBuild=0
__ClangMajorVersion=0
__ClangMinorVersion=0
__NuGetPath="$__PackagesDir/NuGet.exe"
+__HostDistroRid=""
__DistroRid=""
__cmakeargs=""
__SkipGenerateVersion=0
+__DoCrossArchBuild=0
+__PortableLinux=0
while :; do
if [ $# -le 0 ]; then
@@ -530,8 +579,17 @@ while :; do
cross)
__CrossBuild=1
;;
-
- verbose)
+
+ portablelinux)
+ if [ "$__BuildOS" == "Linux" ]; then
+ __PortableLinux=1
+ else
+ echo "ERROR: portableLinux not supported for non-Linux platforms."
+ exit 1
+ fi
+ ;;
+
+ verbose)
__VerboseBuild=1
;;
@@ -572,7 +630,6 @@ while :; do
__ConfigureOnly=1
__SkipMSCorLib=1
__SkipNuget=1
- __IncludeTests=
;;
skipconfigure)
@@ -589,6 +646,10 @@ while :; do
__SkipCoreCLR=1
;;
+ crosscomponent)
+ __DoCrossArchBuild=1
+ ;;
+
skipmscorlib)
__SkipMSCorLib=1
;;
@@ -664,8 +725,8 @@ fi
# Set dependent variables
__LogsDir="$__RootBinDir/Logs"
-# init the distro name
-initDistroRid
+# init the host distro name
+initHostDistroRid
# Set the remaining variables based upon the determined build configuration
__BinDir="$__RootBinDir/Product/$__BuildOS.$__BuildArch.$__BuildType"
@@ -675,6 +736,18 @@ __TestWorkingDir="$__RootBinDir/tests/$__BuildOS.$__BuildArch.$__BuildType"
export __IntermediatesDir="$__RootBinDir/obj/$__BuildOS.$__BuildArch.$__BuildType"
__TestIntermediatesDir="$__RootBinDir/tests/obj/$__BuildOS.$__BuildArch.$__BuildType"
__isMSBuildOnNETCoreSupported=0
+__CrossComponentBinDir="$__BinDir"
+__CrossCompIntermediatesDir="$__IntermediatesDir/crossgen"
+
+__CrossArch="$__HostArch"
+if [[ "$__HostArch" == "x64" && "$__BuildArch" == "arm" ]]; then
+ __CrossArch="x86"
+fi
+if [ $__CrossBuild == 1 ]; then
+ __CrossComponentBinDir="$__CrossComponentBinDir/$__CrossArch"
+fi
+__CrossgenCoreLibLog="$__LogsDir/CrossgenCoreLib_$__BuildOS.$BuildArch.$__BuildType.log"
+__CrossgenExe="$__CrossComponentBinDir/crossgen"
# Init if MSBuild for .NET Core is supported for this platform
isMSBuildOnNETCoreSupported
@@ -701,17 +774,37 @@ if [ $__CrossBuild == 1 ]; then
fi
fi
-# Make the directories necessary for build if they don't exist
+# init the target distro name
+initTargetDistroRid
+# Make the directories necessary for build if they don't exist
setup_dirs
# Check prereqs.
-
check_prereqs
+# Generate event logging infrastructure sources
+generate_event_logging_sources
+
# Build the coreclr (native) components.
+__ExtraCmakeArgs="-DCLR_CMAKE_TARGET_OS=$__BuildOS -DCLR_CMAKE_PACKAGES_DIR=$__PackagesDir -DCLR_CMAKE_PGO_INSTRUMENT=$__PgoInstrument"
+build_native $__SkipCoreCLR "$__BuildArch" "$__IntermediatesDir" "$__ExtraCmakeArgs" "CoreCLR component"
-build_coreclr
+# Build cross-architecture components
+if [ $__CrossBuild == 1 ]; then
+ __SkipCrossArchBuild=1
+ if [ $__DoCrossArchBuild == 1 ]; then
+ # build cross-architecture components for x86-host/arm-target
+ if [[ "$__BuildArch" == "arm" && "$__CrossArch" == "x86" ]]; then
+ __SkipCrossArchBuild=0
+ fi
+ fi
+
+ export __CMakeBinDir="$__CrossComponentBinDir"
+ export CROSSCOMPONENT=1
+ __ExtraCmakeArgs="-DCLR_CMAKE_TARGET_ARCH=$__BuildArch -DCLR_CMAKE_TARGET_OS=$__BuildOS -DCLR_CMAKE_PACKAGES_DIR=$__PackagesDir -DCLR_CMAKE_PGO_INSTRUMENT=$__PgoInstrument"
+ build_native $__SkipCrossArchBuild "$__CrossArch" "$__CrossCompIntermediatesDir" "$__ExtraCmakeArgs" "cross-architecture component"
+fi
# Build System.Private.CoreLib.
diff --git a/clean.cmd b/clean.cmd
index 50e709e3cb..42b9e59991 100644
--- a/clean.cmd
+++ b/clean.cmd
@@ -1,4 +1,4 @@
-@if not defined __echo @echo off
+@if not defined _echo @echo off
setlocal EnableDelayedExpansion
echo Running clean.cmd
diff --git a/clr.coreclr.props b/clr.coreclr.props
index 50b3b4fb30..447b302ef2 100644
--- a/clr.coreclr.props
+++ b/clr.coreclr.props
@@ -21,6 +21,7 @@
<FeatureDbiOopDebugging_HostOneCoreamd64 Condition="'$(TargetArch)' == 'amd64'">true</FeatureDbiOopDebugging_HostOneCoreamd64>
<FeatureEventTrace>true</FeatureEventTrace>
<FeatureExceptionDispatchInfo>true</FeatureExceptionDispatchInfo>
+ <FeatureExceptionNotifications>true</FeatureExceptionNotifications>
<FeatureFrameworkInternal>true</FeatureFrameworkInternal>
<FeatureHijack>true</FeatureHijack>
<FeatureInteropDebugging Condition="('$(TargetArch)' == 'i386') or ('$(TargetArch)' == 'amd64')">true</FeatureInteropDebugging>
@@ -33,6 +34,7 @@
<FeatureMergeJitAndEngine>true</FeatureMergeJitAndEngine>
<FeatureMulticoreJIT>true</FeatureMulticoreJIT>
<FeaturePrejit>true</FeaturePrejit>
+ <FeatureSpanOfT Condition="'$(UseLegacyCompiler)'!='true'">true</FeatureSpanOfT>
<FeatureStandaloneSn>true</FeatureStandaloneSn>
<FeatureStrongnameDelaySigningAllowed>true</FeatureStrongnameDelaySigningAllowed>
<FeatureStrongnameMigration>true</FeatureStrongnameMigration>
@@ -49,6 +51,7 @@
<FeatureUseAsmGCWriteBarriers>true</FeatureUseAsmGCWriteBarriers>
<!-- Setting this to "false" works only for workstation GC, not server. -->
<FeatureSymDiff>true</FeatureSymDiff>
+ <FeatureSynchronizationContextWait>true</FeatureSynchronizationContextWait>
<FeatureReadyToRun Condition="'$(TargetArch)'!='arm64'">true</FeatureReadyToRun>
<FeatureCoreSystem>true</FeatureCoreSystem>
diff --git a/clr.defines.targets b/clr.defines.targets
index 9667a773f5..a45d0dd9de 100644
--- a/clr.defines.targets
+++ b/clr.defines.targets
@@ -92,11 +92,13 @@
<CDefines Condition="'$(FeatureRwlock)' == 'true'">$(CDefines);FEATURE_RWLOCK</CDefines>
<CDefines Condition="'$(FeatureSerialization)' == 'true'">$(CDefines);FEATURE_SERIALIZATION</CDefines>
<CDefines Condition="'$(FeatureSortTables)' == 'true'">$(CDefines);FEATURE_SORT_TABLES</CDefines>
+ <CDefines Condition="'$(FeatureSpanOfT)' == 'true'">$(CDefines);FEATURE_SPAN_OF_T</CDefines>
<CDefines Condition="'$(FeatureStackProbe)' == 'true'">$(CDefines);FEATURE_STACK_PROBE</CDefines>
<CDefines Condition="'$(FeatureStandaloneSn)' == 'true'">$(CDefines);FEATURE_STANDALONE_SN</CDefines>
<CDefines Condition="'$(FeatureStrongnameDelaySigningAllowed)' == 'true'">$(CDefines);FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED</CDefines>
<CDefines Condition="'$(FeatureStrongnameMigration)' == 'true'">$(CDefines);FEATURE_STRONGNAME_MIGRATION</CDefines>
<CDefines Condition="'$(FeatureSvrGc)' == 'true'">$(CDefines);FEATURE_SVR_GC</CDefines>
+ <CDefines Condition="'$(FeatureSynchronizationContextWait)' == 'true'">$(CDefines);FEATURE_SYNCHRONIZATIONCONTEXT_WAIT</CDefines>
<CDefines Condition="'$(FeaturePerfMap)' == 'true'">$(CDefines);FEATURE_PERFMAP</CDefines>
<CDefines Condition="'$(FeatureSynchronizationcontextWait)' == 'true'">$(CDefines);FEATURE_SYNCHRONIZATIONCONTEXT_WAIT</CDefines>
<CDefines Condition="'$(FeatureSyntheticCultures)' == 'true'">$(CDefines);FEATURE_SYNTHETIC_CULTURES</CDefines>
@@ -187,6 +189,7 @@
<DefineConstants Condition="'$(FeatureRwlock)' == 'true'">$(DefineConstants);FEATURE_RWLOCK</DefineConstants>
<DefineConstants Condition="'$(FeatureSerialization)' == 'true'">$(DefineConstants);FEATURE_SERIALIZATION</DefineConstants>
<DefineConstants Condition="'$(FeatureSortTables)' == 'true'">$(DefineConstants);FEATURE_SORT_TABLES</DefineConstants>
+ <DefineConstants Condition="'$(FeatureSpanOfT)' == 'true'">$(DefineConstants);FEATURE_SPAN_OF_T</DefineConstants>
<DefineConstants Condition="'$(FeatureStrongnameMigration)' == 'true'">$(DefineConstants);FEATURE_STRONGNAME_MIGRATION</DefineConstants>
<DefineConstants Condition="'$(FeatureSynchronizationcontextWait)' == 'true'">$(DefineConstants);FEATURE_SYNCHRONIZATIONCONTEXT_WAIT</DefineConstants>
<DefineConstants Condition="'$(FeatureSyntheticCultures)' == 'true'">$(DefineConstants);FEATURE_SYNTHETIC_CULTURES</DefineConstants>
diff --git a/clrdefinitions.cmake b/clrdefinitions.cmake
index b61ab8fbc2..91346eceef 100644
--- a/clrdefinitions.cmake
+++ b/clrdefinitions.cmake
@@ -61,6 +61,12 @@ if (CLR_CMAKE_PLATFORM_UNIX)
endif(CLR_CMAKE_PLATFORM_UNIX)
+if(CLR_CMAKE_PLATFORM_ALPINE_LINUX)
+ # Alpine Linux doesn't have fixed stack limit, this define disables some stack pointer
+ # sanity checks in debug / checked build that rely on a fixed stack limit
+ add_definitions(-DNO_FIXED_STACK_LIMIT)
+endif(CLR_CMAKE_PLATFORM_ALPINE_LINUX)
+
add_definitions(-D_BLD_CLR)
add_definitions(-DDEBUGGING_SUPPORTED)
add_definitions(-DPROFILING_SUPPORTED)
@@ -118,12 +124,16 @@ if(CLR_CMAKE_PLATFORM_UNIX)
add_definitions(-DFEATURE_EVENTSOURCE_XPLAT=1)
endif(CLR_CMAKE_PLATFORM_UNIX)
add_definitions(-DFEATURE_EXCEPTIONDISPATCHINFO)
+add_definitions(-DFEATURE_EXCEPTION_NOTIFICATIONS)
# NetBSD doesn't implement this feature
if(NOT CMAKE_SYSTEM_NAME STREQUAL NetBSD)
add_definitions(-DFEATURE_HIJACK)
endif(NOT CMAKE_SYSTEM_NAME STREQUAL NetBSD)
add_definitions(-DFEATURE_HOST_ASSEMBLY_RESOLVER)
add_definitions(-DFEATURE_ICASTABLE)
+if (WIN32 AND (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386))
+add_definitions(-DFEATURE_INTEROP_DEBUGGING)
+endif (WIN32 AND (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386))
if (CLR_CMAKE_PLATFORM_UNIX OR CLR_CMAKE_TARGET_ARCH_ARM64)
add_definitions(-DFEATURE_IMPLICIT_TLS)
set(FEATURE_IMPLICIT_TLS 1)
@@ -157,6 +167,10 @@ add_definitions(-DFEATURE_RANDOMIZED_STRING_HASHING)
add_definitions(-DFEATURE_READYTORUN)
set(FEATURE_READYTORUN 1)
+if (FEATURE_STANDALONE_GC)
+ add_definitions(-DFEATURE_STANDALONE_GC)
+endif(FEATURE_STANDALONE_GC)
+
if (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386)
add_definitions(-DFEATURE_REJIT)
endif(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386)
@@ -169,6 +183,7 @@ if (CLR_CMAKE_PLATFORM_UNIX OR CLR_CMAKE_TARGET_ARCH_ARM64)
endif ()
add_definitions(-DFEATURE_SVR_GC)
add_definitions(-DFEATURE_SYMDIFF)
+add_definitions(-DFEATURE_SYNCHRONIZATIONCONTEXT_WAIT)
add_definitions(-DFEATURE_SYNTHETIC_CULTURES)
if(CLR_CMAKE_PLATFORM_UNIX_AMD64)
add_definitions(-DFEATURE_MULTIREG_RETURN)
@@ -192,3 +207,5 @@ add_definitions(-DFEATURE_WINMD_RESILIENT)
add_definitions(-D_SECURE_SCL=0)
add_definitions(-DUNICODE)
add_definitions(-D_UNICODE)
+
+add_definitions(-DFEATURE_SPAN_OF_T)
diff --git a/config.json b/config.json
index d25fdba043..1849272be1 100644
--- a/config.json
+++ b/config.json
@@ -24,6 +24,12 @@
"values": [],
"defaultValue": ""
},
+ "__Container": {
+ "description": "Container name for Azure upload.",
+ "valueType": "property",
+ "values": [],
+ "defaultValue": ""
+ },
"MsBuildFileLogging": {
"description": "MsBuild logging options.",
"valueType": "passThrough",
@@ -48,12 +54,6 @@
"values": [],
"defaultValue": ""
},
- "RestoreOptData": {
- "description": "MsBuild target that restores optimization profile data.",
- "valueType": "target",
- "values": [],
- "defaultValue": ""
- },
"RestoreDuringBuild": {
"description": "Enables/disables package restore.",
"valueType": "property",
@@ -246,6 +246,12 @@
"values": [],
"defaultValue": ""
},
+ "CreateNonWindowsTestOverlay": {
+ "description": "Runs CreateNonWindowsTestOverlay target.",
+ "valueType": "target",
+ "values": [],
+ "defaultValue": ""
+ },
"Verbosity": {
"description": "Sets build verbosity.",
"valueType": "passThrough",
@@ -270,6 +276,60 @@
"values": [],
"defaultValue": ""
},
+ "GenerateRuntimeLayout": {
+ "description": "Generates Core_Root folder",
+ "valueType": "property",
+ "values": [ true, false ],
+ "defaultValue": true
+ },
+ "BuildTestsAgainstPackages": {
+ "description": "Sets the property specifying if we're building tests against packages",
+ "valueType": "property",
+ "values": [ true, false ],
+ "defaultValue": true
+ },
+ "PublishTestNativeBins": {
+ "description": "Publishes test native binaries to Azure on non-windows",
+ "valueType": "property",
+ "values": [ true, false ],
+ "defaultValue": true
+ },
+ "RuntimeId": {
+ "description": "Specifies the OS to build Core_Root for",
+ "valueType": "property",
+ "values": [ "debian.8-x64", "fedora.23-x64", "opensuse.13.2-x64", "opensuse.42.1-x64", "osx.10.10-x64", "rhel.7-x64", "ubuntu.14.04-x64", "ubuntu.16.04-x64", "ubuntu.16.10-x64" ],
+ "defaultValue": "${__RuntimeId}"
+ },
+ "UpdateDependencies": {
+ "description": "MsBuild target that updates project.json dependencies.",
+ "valueType": "target",
+ "values": [],
+ "defaultValue": ""
+ },
+ "BatchRestorePackages": {
+ "description": "MsBuild target that restores the packages.",
+ "valueType": "target",
+ "values": [],
+ "defaultValue": ""
+ },
+ "BinPlaceRef": {
+ "description": "Place mscorlib.dll in bin/Product ref folder for building tests against",
+ "valueType": "target",
+ "values": [],
+ "defaultValue": ""
+ },
+ "BinPlaceProduct": {
+ "description": "Place test dependencies in bin/Product folder for building tests against",
+ "valueType": "target",
+ "values": [],
+ "defaultValue": ""
+ },
+ "CopyCrossgenToProduct": {
+ "description": "Place crossgen.exe in bin/Product folder for building tests against",
+ "valueType": "target",
+ "values": [],
+ "defaultValue": ""
+ },
"ExtraParameters": {
"description": "Extra parameters will be passed to the selected command.",
"valueType": "passThrough",
@@ -354,7 +414,8 @@
"settings": {
"MsBuildLog": "default",
"MsBuildWrn": "default",
- "MsBuildErr": "default"
+ "MsBuildErr": "default",
+ "MsBuildEventLogging": "default"
}
}
},
@@ -368,14 +429,6 @@
"RestoreNETCorePlatforms": "default"
}
},
- "optdata": {
- "description": "Restores optimization profile data for the repository.",
- "settings": {
- "Project": "./build.proj",
- "RestoreDuringBuild": true,
- "RestoreOptData": "default"
- }
- },
"ab": {
"description": "Downloads the latests product packages from Azure. The values for '-AzureAccount' and '-AzureToken' are required",
"settings": {
@@ -394,6 +447,12 @@
"CloudDropAccountName": "default"
}
},
+ "container": {
+ "description": "Container name to download from in Azure Blob storage.",
+ "settings": {
+ "__Container": "default"
+ }
+ },
"verbose": {
"description": "Passes /flp:v=diag to the msbuild command or the value passed by the user.",
"settings": {
@@ -411,6 +470,12 @@
"settings": {
"BuildNumberMinor": "default"
}
+ },
+ "PublishTestNativeBins": {
+ "description": "Downloads Published test native binaries.",
+ "settings": {
+ "PublishTestNativeBins": "default"
+ }
}
},
"defaultValues": {
@@ -434,6 +499,12 @@
"CloudDropAccountName": "default"
}
},
+ "container": {
+ "description": "Container name to upload into in Azure Blob storage.",
+ "settings": {
+ "__Container": "default"
+ }
+ },
"buildArch": {
"description": "Specifies architecture to publish, can be x64, x86, arm or arm64",
"settings": {
@@ -451,6 +522,18 @@
"settings": {
"__BuildOS": "default"
}
+ },
+ "distroRid": {
+ "description": "Specifies distro rid for Unix OS.",
+ "settings": {
+ "__DistroRid": "default"
+ }
+ },
+ "PublishTestNativeBins": {
+ "description": "Publishes test native binaries.",
+ "settings": {
+ "PublishTestNativeBins": "default"
+ }
}
},
"defaultValues": {
diff --git a/cross/arm/sources.list.jessie b/cross/arm/sources.list.jessie
new file mode 100644
index 0000000000..4d142ac9b1
--- /dev/null
+++ b/cross/arm/sources.list.jessie
@@ -0,0 +1,3 @@
+# Debian (sid) # UNSTABLE
+deb http://ftp.debian.org/debian/ sid main contrib non-free
+deb-src http://ftp.debian.org/debian/ sid main contrib non-free
diff --git a/cross/arm/sources.list.xenial b/cross/arm/sources.list.xenial
new file mode 100644
index 0000000000..eacd86b7df
--- /dev/null
+++ b/cross/arm/sources.list.xenial
@@ -0,0 +1,11 @@
+deb http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted universe
+deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted universe
+
+deb http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted universe
+deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted universe
+
+deb http://ports.ubuntu.com/ubuntu-ports/ xenial-backports main restricted
+deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-backports main restricted
+
+deb http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse
+deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse \ No newline at end of file
diff --git a/cross/arm64/sources.list.xenial b/cross/arm64/sources.list.xenial
new file mode 100644
index 0000000000..eacd86b7df
--- /dev/null
+++ b/cross/arm64/sources.list.xenial
@@ -0,0 +1,11 @@
+deb http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted universe
+deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted universe
+
+deb http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted universe
+deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted universe
+
+deb http://ports.ubuntu.com/ubuntu-ports/ xenial-backports main restricted
+deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-backports main restricted
+
+deb http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse
+deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted universe multiverse \ No newline at end of file
diff --git a/cross/build-rootfs.sh b/cross/build-rootfs.sh
index b786420405..cfa1a66f4a 100755
--- a/cross/build-rootfs.sh
+++ b/cross/build-rootfs.sh
@@ -2,9 +2,10 @@
usage()
{
- echo "Usage: $0 [BuildArch] [UbuntuCodeName]"
- echo "BuildArch can be: arm, arm-softfp, arm64"
- echo "UbuntuCodeName - optional, Code name for Ubuntu, can be: trusty(default), vivid, wily. If BuildArch is arm-softfp, UbuntuCodeName is ignored."
+ echo "Usage: $0 [BuildArch] [UbuntuCodeName] [lldbx.y]"
+ echo "BuildArch can be: arm(default), arm-softfp, arm64, x86"
+ echo "UbuntuCodeName - optional, Code name for Ubuntu, can be: trusty(default), vivid, wily, xenial. If BuildArch is arm-softfp, UbuntuCodeName is ignored."
+ echo "lldbx.y - optional, LLDB version, can be: lldb3.6(default), lldb3.8"
exit 1
}
@@ -17,64 +18,79 @@ __BuildArch=arm
__UbuntuArch=armhf
__UbuntuRepo="http://ports.ubuntu.com/"
__UbuntuPackagesBase="build-essential libunwind8-dev gettext symlinks liblttng-ust-dev libicu-dev"
-__UbuntuPackages="$__UbuntuPackagesBase"
-if [ -z "$LLVM_ARM_HOME" ]; then
- __LLDB_Package="lldb-3.6-dev"
-fi
-__MachineTriple=arm-linux-gnueabihf
+__LLDB_Package="lldb-3.6-dev"
__UnprocessedBuildArgs=
+
for i in "$@"
do
lowerI="$(echo $i | awk '{print tolower($0)}')"
case $lowerI in
-?|-h|--help)
- usage
- exit 1
- ;;
+ usage
+ exit 1
+ ;;
arm)
- __BuildArch=arm
- __UbuntuArch=armhf
- __UbuntuPackages="$__UbuntuPackagesBase $__LLDB_Package"
- __MachineTriple=arm-linux-gnueabihf
- ;;
+ __BuildArch=arm
+ __UbuntuArch=armhf
+ ;;
arm64)
- __BuildArch=arm64
- __UbuntuArch=arm64
- __UbuntuPackages="$__UbuntuPackagesBase"
- __MachineTriple=aarch64-linux-gnu
- ;;
+ __BuildArch=arm64
+ __UbuntuArch=arm64
+ ;;
arm-softfp)
- __BuildArch=arm-softfp
- __UbuntuArch=armel
- __UbuntuRepo="http://ftp.debian.org/debian/"
- __UbuntuPackages="$__UbuntuPackagesBase $__LLDB_Package"
- __MachineTriple=arm-linux-gnueabi
- __UbuntuCodeName=jessie
- ;;
+ __BuildArch=arm-softfp
+ __UbuntuArch=armel
+ __UbuntuRepo="http://ftp.debian.org/debian/"
+ __UbuntuCodeName=jessie
+ ;;
+ x86)
+ __BuildArch=x86
+ __UbuntuArch=i386
+ __UbuntuRepo="http://archive.ubuntu.com/ubuntu/"
+ ;;
+ lldb3.6)
+ __LLDB_Package="lldb-3.6-dev"
+ ;;
+ lldb3.8)
+ __LLDB_Package="lldb-3.8-dev"
+ ;;
vivid)
- if [ "$__UbuntuCodeName" != "jessie" ]; then
- __UbuntuCodeName=vivid
- fi
- ;;
+ if [ "$__UbuntuCodeName" != "jessie" ]; then
+ __UbuntuCodeName=vivid
+ fi
+ ;;
wily)
- if [ "$__UbuntuCodeName" != "jessie" ]; then
- __UbuntuCodeName=wily
- fi
- ;;
+ if [ "$__UbuntuCodeName" != "jessie" ]; then
+ __UbuntuCodeName=wily
+ fi
+ ;;
+ xenial)
+ if [ "$__UbuntuCodeName" != "jessie" ]; then
+ __UbuntuCodeName=xenial
+ fi
+ ;;
+ jessie)
+ __UbuntuCodeName=jessie
+ __UbuntuRepo="http://ftp.debian.org/debian/"
+ ;;
*)
- __UnprocessedBuildArgs="$__UnprocessedBuildArgs $i"
- ;;
+ __UnprocessedBuildArgs="$__UnprocessedBuildArgs $i"
+ ;;
esac
done
__RootfsDir="$__CrossDir/rootfs/$__BuildArch"
+__UbuntuPackages="$__UbuntuPackagesBase $__LLDB_Package"
if [[ -n "$ROOTFS_DIR" ]]; then
__RootfsDir=$ROOTFS_DIR
fi
-umount $__RootfsDir/*
-rm -rf $__RootfsDir
+if [ -d "$__RootfsDir" ]; then
+ umount $__RootfsDir/*
+ rm -rf $__RootfsDir
+fi
+
qemu-debootstrap --arch $__UbuntuArch $__UbuntuCodeName $__RootfsDir $__UbuntuRepo
cp $__CrossDir/$__BuildArch/sources.list.$__UbuntuCodeName $__RootfsDir/etc/apt/sources.list
chroot $__RootfsDir apt-get update
diff --git a/cross/x86/sources.list.trusty b/cross/x86/sources.list.trusty
new file mode 100644
index 0000000000..9b3085436e
--- /dev/null
+++ b/cross/x86/sources.list.trusty
@@ -0,0 +1,11 @@
+deb http://archive.ubuntu.com/ubuntu/ trusty main restricted universe
+deb-src http://archive.ubuntu.com/ubuntu/ trusty main restricted universe
+
+deb http://archive.ubuntu.com/ubuntu/ trusty-updates main restricted universe
+deb-src http://archive.ubuntu.com/ubuntu/ trusty-updates main restricted universe
+
+deb http://archive.ubuntu.com/ubuntu/ trusty-backports main restricted
+deb-src http://archive.ubuntu.com/ubuntu/ trusty-backports main restricted
+
+deb http://archive.ubuntu.com/ubuntu/ trusty-security main restricted universe multiverse
+deb-src http://archive.ubuntu.com/ubuntu/ trusty-security main restricted universe multiverse
diff --git a/cross/x86/sources.list.vivid b/cross/x86/sources.list.vivid
new file mode 100644
index 0000000000..26d37b20fc
--- /dev/null
+++ b/cross/x86/sources.list.vivid
@@ -0,0 +1,11 @@
+deb http://archive.ubuntu.com/ubuntu/ vivid main restricted universe
+deb-src http://archive.ubuntu.com/ubuntu/ vivid main restricted universe
+
+deb http://archive.ubuntu.com/ubuntu/ vivid-updates main restricted universe
+deb-src http://archive.ubuntu.com/ubuntu/ vivid-updates main restricted universe
+
+deb http://archive.ubuntu.com/ubuntu/ vivid-backports main restricted
+deb-src http://archive.ubuntu.com/ubuntu/ vivid-backports main restricted
+
+deb http://archive.ubuntu.com/ubuntu/ vivid-security main restricted universe multiverse
+deb-src http://archive.ubuntu.com/ubuntu/ vivid-security main restricted universe multiverse
diff --git a/cross/x86/sources.list.wily b/cross/x86/sources.list.wily
new file mode 100644
index 0000000000..c4b0b442ab
--- /dev/null
+++ b/cross/x86/sources.list.wily
@@ -0,0 +1,11 @@
+deb http://archive.ubuntu.com/ubuntu/ wily main restricted universe
+deb-src http://archive.ubuntu.com/ubuntu/ wily main restricted universe
+
+deb http://archive.ubuntu.com/ubuntu/ wily-updates main restricted universe
+deb-src http://archive.ubuntu.com/ubuntu/ wily-updates main restricted universe
+
+deb http://archive.ubuntu.com/ubuntu/ wily-backports main restricted
+deb-src http://archive.ubuntu.com/ubuntu/ wily-backports main restricted
+
+deb http://archive.ubuntu.com/ubuntu/ wily-security main restricted universe multiverse
+deb-src http://archive.ubuntu.com/ubuntu/ wily-security main restricted universe multiverse
diff --git a/cross/x86/sources.list.xenial b/cross/x86/sources.list.xenial
new file mode 100644
index 0000000000..ad9c5a0144
--- /dev/null
+++ b/cross/x86/sources.list.xenial
@@ -0,0 +1,11 @@
+deb http://archive.ubuntu.com/ubuntu/ xenial main restricted universe
+deb-src http://archive.ubuntu.com/ubuntu/ xenial main restricted universe
+
+deb http://archive.ubuntu.com/ubuntu/ xenial-updates main restricted universe
+deb-src http://archive.ubuntu.com/ubuntu/ xenial-updates main restricted universe
+
+deb http://archive.ubuntu.com/ubuntu/ xenial-backports main restricted
+deb-src http://archive.ubuntu.com/ubuntu/ xenial-backports main restricted
+
+deb http://archive.ubuntu.com/ubuntu/ xenial-security main restricted universe multiverse
+deb-src http://archive.ubuntu.com/ubuntu/ xenial-security main restricted universe multiverse
diff --git a/cross/x86/toolchain.cmake b/cross/x86/toolchain.cmake
new file mode 100644
index 0000000000..63c64875fa
--- /dev/null
+++ b/cross/x86/toolchain.cmake
@@ -0,0 +1,40 @@
+
+set(CROSS_ROOTFS $ENV{ROOTFS_DIR})
+
+set(CMAKE_SYSTEM_NAME Linux)
+set(CMAKE_SYSTEM_PROCESSOR i686)
+
+add_compile_options("-m32")
+add_compile_options("--sysroot=${CROSS_ROOTFS}")
+add_compile_options("-Wno-error=unused-command-line-argument")
+
+set(CROSS_LINK_FLAGS "${CROSS_LINK_FLAGS} --sysroot=${CROSS_ROOTFS}")
+set(CROSS_LINK_FLAGS "${CROSS_LINK_FLAGS} -B ${CROSS_ROOTFS}/usr/lib/gcc/i686-linux-gnu")
+set(CROSS_LINK_FLAGS "${CROSS_LINK_FLAGS} -L${CROSS_ROOTFS}/lib/i386-linux-gnu")
+set(CROSS_LINK_FLAGS "${CROSS_LINK_FLAGS} -m32")
+
+set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CROSS_LINK_FLAGS}" CACHE STRING "" FORCE)
+set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${CROSS_LINK_FLAGS}" CACHE STRING "" FORCE)
+set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${CROSS_LINK_FLAGS}" CACHE STRING "" FORCE)
+
+set(CMAKE_FIND_ROOT_PATH "${CROSS_ROOTFS}")
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+
+set(LLVM_CROSS_DIR "$ENV{LLVM_CROSS_HOME}")
+if(LLVM_CROSS_DIR)
+ set(WITH_LLDB_LIBS "${LLVM_CROSS_DIR}/lib/" CACHE STRING "")
+ set(WITH_LLDB_INCLUDES "${LLVM_CROSS_DIR}/include" CACHE STRING "")
+ set(LLDB_H "${WITH_LLDB_INCLUDES}" CACHE STRING "")
+ set(LLDB "${LLVM_CROSS_DIR}/lib/liblldb.so" CACHE STRING "")
+else()
+ set(WITH_LLDB_LIBS "${CROSS_ROOTFS}/usr/lib/i386-linux-gnu" CACHE STRING "")
+ set(CHECK_LLVM_DIR "${CROSS_ROOTFS}/usr/lib/llvm-3.8/include")
+ if(EXISTS "${CHECK_LLVM_DIR}" AND IS_DIRECTORY "${CHECK_LLVM_DIR}")
+ set(WITH_LLDB_INCLUDES "${CHECK_LLVM_DIR}")
+ else()
+ set(WITH_LLDB_INCLUDES "${CROSS_ROOTFS}/usr/lib/llvm-3.6/include")
+ endif()
+endif()
diff --git a/cross/x86/tryrun.cmake b/cross/x86/tryrun.cmake
new file mode 100644
index 0000000000..cfc52087c2
--- /dev/null
+++ b/cross/x86/tryrun.cmake
@@ -0,0 +1,127 @@
+SET( REALPATH_SUPPORTS_NONEXISTENT_FILES_EXITCODE
+ 1
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( SSCANF_SUPPORT_ll_EXITCODE
+ 0
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( SSCANF_CANNOT_HANDLE_MISSING_EXPONENT_EXITCODE
+ 1
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( HAVE_LARGE_SNPRINTF_SUPPORT_EXITCODE
+ 0
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( HAVE_SCHED_GET_PRIORITY_EXITCODE
+ 0
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( HAVE_WORKING_GETTIMEOFDAY_EXITCODE
+ 0
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( HAVE_WORKING_CLOCK_GETTIME_EXITCODE
+ 0
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( HAVE_CLOCK_MONOTONIC_EXITCODE
+ 0
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( HAVE_MMAP_DEV_ZERO_EXITCODE
+ 0
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( ONE_SHARED_MAPPING_PER_FILEREGION_PER_PROCESS_EXITCODE
+ 1
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( PTHREAD_CREATE_MODIFIES_ERRNO_EXITCODE
+ 1
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( SEM_INIT_MODIFIES_ERRNO_EXITCODE
+ 1
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( HAVE_COMPATIBLE_ACOS_EXITCODE
+ 0
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( HAVE_COMPATIBLE_ASIN_EXITCODE
+ 0
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( HAVE_COMPATIBLE_POW_EXITCODE
+ 1
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( HAVE_VALID_NEGATIVE_INF_POW_EXITCODE
+ 0
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( HAVE_VALID_POSITIVE_INF_POW_EXITCODE
+ 0
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( HAVE_COMPATIBLE_ATAN2_EXITCODE
+ 0
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( HAVE_COMPATIBLE_LOG_EXITCODE
+ 0
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( HAVE_COMPATIBLE_LOG10_EXITCODE
+ 0
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( UNGETC_NOT_RETURN_EOF_EXITCODE
+ 0
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( HAS_POSIX_SEMAPHORES_EXITCODE
+ 0
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( GETPWUID_R_SETS_ERRNO_EXITCODE
+ 0
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( FILE_OPS_CHECK_FERROR_OF_PREVIOUS_CALL_EXITCODE
+ 1
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( HAVE_CLOCK_THREAD_CPUTIME_EXITCODE
+ 0
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( HAVE_SCHED_GETCPU_EXITCODE
+ 0
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( HAVE_CLOCK_MONOTONIC_COARSE_EXITCODE
+ 0
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( HAVE_PROCFS_CTL_EXITCODE
+ 1
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( HAVE_PROCFS_MAPS_EXITCODE
+ 0
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( HAVE_PROCFS_STAT_EXITCODE
+ 0
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( HAVE_PROCFS_STATUS_EXITCODE
+ 0
+ CACHE STRING "Result from TRY_RUN" FORCE)
+
+SET( HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES
+ 0
+ CACHE STRING "Result from TRY_RUN" FORCE)
diff --git a/crosscomponents.cmake b/crosscomponents.cmake
index e0d5c1a939..7575570b36 100644
--- a/crosscomponents.cmake
+++ b/crosscomponents.cmake
@@ -6,4 +6,5 @@ set (CLR_CROSS_COMPONENTS_LIST
mscordbi
sos
clrjit
+ protojit
)
diff --git a/dependencies.props b/dependencies.props
index 52b4a877b5..3094a3d493 100644
--- a/dependencies.props
+++ b/dependencies.props
@@ -1,30 +1,25 @@
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Source of truth for dependency tooling: the commit hash of the dotnet/versions master branch as of the last auto-upgrade. -->
<PropertyGroup>
- <CoreFxCurrentRef>35258a932ae9971cbc8df1d83b4eb893947a1724</CoreFxCurrentRef>
- <CoreClrCurrentRef>35258a932ae9971cbc8df1d83b4eb893947a1724</CoreClrCurrentRef>
+ <CoreFxCurrentRef>014ac653f680703f5b9a7bf3ebc99b1a5b912c7b</CoreFxCurrentRef>
+ <CoreClrCurrentRef>014ac653f680703f5b9a7bf3ebc99b1a5b912c7b</CoreClrCurrentRef>
</PropertyGroup>
<!-- Auto-upgraded properties for each build info dependency. -->
<PropertyGroup>
- <CoreFxExpectedPrerelease>preview1-24628-02</CoreFxExpectedPrerelease>
+ <CoreFxExpectedPrerelease>beta-24820-02</CoreFxExpectedPrerelease>
</PropertyGroup>
<!-- Full package version strings that are used in other parts of the build. -->
<PropertyGroup>
- <CoreClrPackageVersion>1.1.0</CoreClrPackageVersion>
- <XunitPackageVersion>2.1.0</XunitPackageVersion>
-
- <!-- Runtime package versions from projectk-tfs/release/1.0.0 -->
- <RuntimeWin7ArmMicrosoftNETCoreTestHostPackageVersion>1.0.0</RuntimeWin7ArmMicrosoftNETCoreTestHostPackageVersion>
- <RuntimeWin8ArmMicrosoftNETCoreRuntimeCoreCLRPackageVersion>1.0.4</RuntimeWin8ArmMicrosoftNETCoreRuntimeCoreCLRPackageVersion>
- <MicrosoftNETCoreWindowsApiSetsPackageVersion>1.0.1</MicrosoftNETCoreWindowsApiSetsPackageVersion>
+ <CoreClrPackageVersion>1.2.0-beta-24820-02</CoreClrPackageVersion>
+ <XunitPackageVersion>2.2.0-beta2-build3300</XunitPackageVersion>
</PropertyGroup>
<!-- Package dependency verification/auto-upgrade configuration. -->
<PropertyGroup>
<BaseDotNetBuildInfo>build-info/dotnet/</BaseDotNetBuildInfo>
- <DependencyBranch>release/1.1.0</DependencyBranch>
+ <DependencyBranch>master</DependencyBranch>
<CurrentRefXmlPath>$(MSBuildThisFileFullPath)</CurrentRefXmlPath>
</PropertyGroup>
@@ -37,7 +32,7 @@
<BuildInfoPath>$(BaseDotNetBuildInfo)coreclr/$(DependencyBranch)</BuildInfoPath>
<CurrentRef>$(CoreClrCurrentRef)</CurrentRef>
</RemoteDependencyBuildInfo>
-
+
<DependencyBuildInfo Include="@(RemoteDependencyBuildInfo)">
<RawVersionsBaseUrl>https://raw.githubusercontent.com/dotnet/versions</RawVersionsBaseUrl>
</DependencyBuildInfo>
@@ -66,6 +61,7 @@
<Version>$(XunitPackageVersion)</Version>
</StaticDependency>
+ <XunitPerformanceDependency Include="Microsoft.DotNet.xunit.performance" />
<XunitPerformanceDependency Include="Microsoft.DotNet.xunit.performance.analysis" />
<XunitPerformanceDependency Include="Microsoft.DotNet.xunit.performance.analysis.cli" />
<XunitPerformanceDependency Include="Microsoft.DotNet.xunit.performance.metrics" />
@@ -73,11 +69,11 @@
<XunitPerformanceDependency Include="Microsoft.DotNet.xunit.performance.runner.cli" />
<XunitPerformanceDependency Include="Microsoft.DotNet.xunit.performance.runner.Windows" />
<StaticDependency Include="@(XunitPerformanceDependency)">
- <Version>1.0.0-alpha-build0035</Version>
+ <Version>1.0.0-alpha-build0040</Version>
</StaticDependency>
<StaticDependency Include="xunit.console.netcore">
- <Version>1.0.2-prerelease-00101</Version>
+ <Version>1.0.2-prerelease-00177</Version>
</StaticDependency>
<DependencyBuildInfo Include="@(StaticDependency)">
diff --git a/dir.props b/dir.props
index 5b96cd1f1c..b9bf0816e4 100644
--- a/dir.props
+++ b/dir.props
@@ -139,7 +139,7 @@
<!-- Packaging properties -->
<PropertyGroup>
- <PreReleaseLabel>servicing</PreReleaseLabel>
+ <PreReleaseLabel>beta</PreReleaseLabel>
<PackageDescriptionFile>$(SourceDir).nuget/descriptions.json</PackageDescriptionFile>
<PackageLicenseFile>$(SourceDir).nuget/dotnet_library_license.txt</PackageLicenseFile>
<PackageThirdPartyNoticesFile>$(SourceDir).nuget/ThirdPartyNotices.txt</PackageThirdPartyNoticesFile>
@@ -153,12 +153,12 @@
<ProjectUrl>https://dot.net</ProjectUrl>
<!-- Central place to set the versions of all nuget packages produced in the repo -->
- <Version Condition="'$(MSBuildProjectExtension)' == '.pkgproj' and '$(Version)' == ''">1.1.1</Version>
+ <PackageVersion Condition="'$(PackageVersion)' == ''">1.2.0</PackageVersion>
<!-- Set the boolean below to true to generate packages with stabilized versions -->
<StabilizePackageVersion Condition="'$(StabilizePackageVersion)' == ''">false</StabilizePackageVersion>
- <StableVersion Condition="'$(MSBuildProjectExtension)' == '.pkgproj' and '$(StabilizePackageVersion)' == 'true' and '$(StableVersion)' == ''">$(Version)</StableVersion>
-
+ <StableVersion Condition="'$(StabilizePackageVersion)' == 'true' and '$(StableVersion)' == ''">$(PackageVersion)</StableVersion>
+
<!-- On Windows, MSbuild still runs against Desktop FX while it runs on .NET Core on non-Windows. this requires
pulling in different packaging dependencies.
-->
diff --git a/extract-from-json.py b/extract-from-json.py
deleted file mode 100755
index e432b2b067..0000000000
--- a/extract-from-json.py
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/bin/python
-
-import argparse
-import json
-import sys
-
-def parse_args():
- parser = argparse.ArgumentParser(
- description="""Extracts information from a json file by navigating the JSON object using a
- sequence of property accessors and returning the JSON subtree, or the raw data, found
- at that location."""
- )
-
- parser.add_argument(
- '-f', '--file',
- metavar='<project.json>',
- help="Path to project.json file to parse",
- required=True,
- )
-
- parser.add_argument(
- 'property',
- metavar='property_name',
- help="""Name of property to extract using object notation.
- Pass multiple values to drill down into nested objects (in order).""",
- nargs='*',
- )
-
- parser.add_argument(
- '-r', '--raw',
- help="""Dumps the raw object found at the requested location.
- If omitted, returns a JSON formatted object instead.""",
- action='store_true',
- default=False
- )
-
- return parser.parse_args()
-
-def main():
- args = parse_args()
-
- with open(args.file) as json_file:
- selected_property = json.load(json_file)
-
- for prop in args.property:
- selected_property = selected_property[prop]
-
- if args.raw:
- print(selected_property)
- else:
- print(json.dumps(selected_property))
-
- return 0
-
-if __name__ == "__main__":
- sys.exit(main())
diff --git a/functions.cmake b/functions.cmake
index f8a2eeae04..e1a9abb469 100644
--- a/functions.cmake
+++ b/functions.cmake
@@ -1,6 +1,8 @@
function(clr_unknown_arch)
if (WIN32)
message(FATAL_ERROR "Only AMD64, ARM64, ARM and I386 are supported")
+ elseif(CLR_CROSS_COMPONENTS_BUILD)
+ message(FATAL_ERROR "Only AMD64, I386 are supported for cross-architecture component")
else()
message(FATAL_ERROR "Only AMD64, ARM64 and ARM are supported")
endif()
@@ -216,3 +218,19 @@ function(_install)
install(${ARGV})
endif()
endfunction()
+
+function(verify_dependencies targetName errorMessage)
+ # We don't need to verify dependencies on OSX, since missing dependencies
+ # result in link error over there.
+ if (NOT CLR_CMAKE_PLATFORM_DARWIN)
+ add_custom_command(
+ TARGET ${targetName}
+ POST_BUILD
+ VERBATIM
+ COMMAND ${CMAKE_SOURCE_DIR}/verify-so.sh
+ $<TARGET_FILE:${targetName}>
+ ${errorMessage}
+ COMMENT "Verifying ${targetName} dependencies"
+ )
+ endif()
+endfunction()
diff --git a/init-tools.cmd b/init-tools.cmd
index 1bdf2a89a5..cb1aad4f9e 100644
--- a/init-tools.cmd
+++ b/init-tools.cmd
@@ -1,4 +1,4 @@
-@echo off
+@if not defined _echo @echo off
setlocal
set INIT_TOOLS_LOG=%~dp0init-tools.log
@@ -6,13 +6,13 @@ set PACKAGES_DIR=%~dp0packages\
set TOOLRUNTIME_DIR=%~dp0Tools
set DOTNET_PATH=%TOOLRUNTIME_DIR%\dotnetcli\
set DOTNET_CMD=%DOTNET_PATH%dotnet.exe
-if [%BUILDTOOLS_SOURCE%]==[] set BUILDTOOLS_SOURCE=https://www.myget.org/F/dotnet-buildtools/
+if [%BUILDTOOLS_SOURCE%]==[] set BUILDTOOLS_SOURCE=https://dotnet.myget.org/F/dotnet-buildtools/api/v3/index.json
set /P BUILDTOOLS_VERSION=< "%~dp0BuildToolsVersion.txt"
set BUILD_TOOLS_PATH=%PACKAGES_DIR%Microsoft.DotNet.BuildTools\%BUILDTOOLS_VERSION%\lib\
set PROJECT_JSON_PATH=%TOOLRUNTIME_DIR%\%BUILDTOOLS_VERSION%
set PROJECT_JSON_FILE=%PROJECT_JSON_PATH%\project.json
set PROJECT_JSON_CONTENTS={ "dependencies": { "Microsoft.DotNet.BuildTools": "%BUILDTOOLS_VERSION%" , "Microsoft.DotNet.BuildTools.Coreclr": "1.0.4-prerelease"}, "frameworks": { "dnxcore50": { } } }
-set BUILD_TOOLS_SEMAPHORE=%PROJECT_JSON_PATH%\init-tools.completed
+set BUILD_TOOLS_SEMAPHORE=%PROJECT_JSON_PATH%\init-tools.completed0
set TOOLS_INIT_RETURN_CODE=0
:: if force option is specified then clean the tool runtime and build tools package directory to force it to get recreated
@@ -39,13 +39,13 @@ if NOT exist "%PROJECT_JSON_PATH%" mkdir "%PROJECT_JSON_PATH%"
echo %PROJECT_JSON_CONTENTS% > "%PROJECT_JSON_FILE%"
echo Running %0 > "%INIT_TOOLS_LOG%"
+set /p DOTNET_VERSION=< "%~dp0DotnetCLIVersion.txt"
if exist "%DOTNET_CMD%" goto :afterdotnetrestore
echo Installing dotnet cli...
if NOT exist "%DOTNET_PATH%" mkdir "%DOTNET_PATH%"
-set /p DOTNET_VERSION=< "%~dp0DotnetCLIVersion.txt"
if [%PROCESSOR_ARCHITECTURE%]==[x86] (set DOTNET_ZIP_NAME=dotnet-dev-win-x86.%DOTNET_VERSION%.zip) else (set DOTNET_ZIP_NAME=dotnet-dev-win-x64.%DOTNET_VERSION%.zip)
-set DOTNET_REMOTE_PATH=https://dotnetcli.blob.core.windows.net/dotnet/preview/Binaries/%DOTNET_VERSION%/%DOTNET_ZIP_NAME%
+set DOTNET_REMOTE_PATH=https://dotnetcli.blob.core.windows.net/dotnet/Sdk/%DOTNET_VERSION%/%DOTNET_ZIP_NAME%
set DOTNET_LOCAL_PATH=%DOTNET_PATH%%DOTNET_ZIP_NAME%
echo Installing '%DOTNET_REMOTE_PATH%' to '%DOTNET_LOCAL_PATH%' >> "%INIT_TOOLS_LOG%"
powershell -NoProfile -ExecutionPolicy unrestricted -Command "$retryCount = 0; $success = $false; do { try { (New-Object Net.WebClient).DownloadFile('%DOTNET_REMOTE_PATH%', '%DOTNET_LOCAL_PATH%'); $success = $true; } catch { if ($retryCount -ge 6) { throw; } else { $retryCount++; Start-Sleep -Seconds (5 * $retryCount); } } } while ($success -eq $false); Add-Type -Assembly 'System.IO.Compression.FileSystem' -ErrorVariable AddTypeErrors; if ($AddTypeErrors.Count -eq 0) { [System.IO.Compression.ZipFile]::ExtractToDirectory('%DOTNET_LOCAL_PATH%', '%DOTNET_PATH%') } else { (New-Object -com shell.application).namespace('%DOTNET_PATH%').CopyHere((new-object -com shell.application).namespace('%DOTNET_LOCAL_PATH%').Items(),16) }" >> "%INIT_TOOLS_LOG%"
@@ -73,6 +73,14 @@ echo Initializing BuildTools ...
echo Running: "%BUILD_TOOLS_PATH%init-tools.cmd" "%~dp0" "%DOTNET_CMD%" "%TOOLRUNTIME_DIR%" >> "%INIT_TOOLS_LOG%"
call "%BUILD_TOOLS_PATH%init-tools.cmd" "%~dp0" "%DOTNET_CMD%" "%TOOLRUNTIME_DIR%" >> "%INIT_TOOLS_LOG%"
+echo Updating CLI NuGet Frameworks map...
+robocopy "%TOOLRUNTIME_DIR%" "%TOOLRUNTIME_DIR%\dotnetcli\sdk\%DOTNET_VERSION%" NuGet.Frameworks.dll /XO >> "%INIT_TOOLS_LOG%"
+set UPDATE_CLI_ERRORLEVEL=%ERRORLEVEL%
+if %UPDATE_CLI_ERRORLEVEL% GTR 1 (
+ echo ERROR: Failed to update Nuget for CLI {Error level %UPDATE_CLI_ERRORLEVEL%}. Please check '%INIT_TOOLS_LOG%' for more details. 1>&2
+ exit /b %UPDATE_CLI_ERRORLEVEL%
+)
+
:: Create sempahore file
echo Done initializing tools.
echo Init-Tools.cmd completed for BuildTools Version: %BUILDTOOLS_VERSION% > "%BUILD_TOOLS_SEMAPHORE%"
diff --git a/init-tools.log b/init-tools.log
new file mode 100644
index 0000000000..7a96daa413
--- /dev/null
+++ b/init-tools.log
@@ -0,0 +1,539 @@
+Running: /home/jyoung/git/dotnet/coreclr-1.0.0/init-tools.sh
+Installing 'https://dotnetcli.blob.core.windows.net/dotnet/Sdk/1.0.0-preview3-003223/dotnet-dev-ubuntu-x64.1.0.0-preview3-003223.tar.gz' to '/home/jyoung/git/dotnet/coreclr-1.0.0/Tools/dotnetcli/dotnet.tar'
+Running: /home/jyoung/git/dotnet/coreclr-1.0.0/Tools/dotnetcli/dotnet restore "/home/jyoung/git/dotnet/coreclr-1.0.0/Tools/1.0.27-prerelease-01008-01/project.json" --no-cache --packages /home/jyoung/git/dotnet/coreclr-1.0.0/packages --source https://dotnet.myget.org/F/dotnet-buildtools/api/v3/index.json
+log : Restoring packages for /home/jyoung/git/dotnet/coreclr-1.0.0/Tools/1.0.27-prerelease-01008-01/project.json...
+log : Installing Microsoft.DotNet.BuildTools 1.0.27-prerelease-01008-01.
+log : Writing lock file to disk. Path: /home/jyoung/git/dotnet/coreclr-1.0.0/Tools/1.0.27-prerelease-01008-01/project.lock.json
+log : /home/jyoung/git/dotnet/coreclr-1.0.0/Tools/1.0.27-prerelease-01008-01/project.json
+log : Restore completed in 4349ms.
+Running: /home/jyoung/git/dotnet/coreclr-1.0.0/packages/Microsoft.DotNet.BuildTools/1.0.27-prerelease-01008-01/lib/init-tools.sh /home/jyoung/git/dotnet/coreclr-1.0.0 /home/jyoung/git/dotnet/coreclr-1.0.0/Tools/dotnetcli/dotnet /home/jyoung/git/dotnet/coreclr-1.0.0/Tools
+Running: /home/jyoung/git/dotnet/coreclr-1.0.0/Tools/dotnetcli/dotnet restore "/home/jyoung/git/dotnet/coreclr-1.0.0/packages/Microsoft.DotNet.BuildTools/1.0.27-prerelease-01008-01/lib/tool-runtime/project.json" --source https://dotnet.myget.org/F/dotnet-core/api/v3/index.json --source https://dotnet.myget.org/F/dotnet-buildtools/api/v3/index.json --source https://api.nuget.org/v3/index.json
+log : Restoring packages for /home/jyoung/git/dotnet/coreclr-1.0.0/packages/Microsoft.DotNet.BuildTools/1.0.27-prerelease-01008-01/lib/tool-runtime/project.json...
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: MSBuild from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> MSBuild
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: MSBuild from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> MSBuild
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: MSBuild from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> MSBuild
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: MSBuild from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> MSBuild
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: MSBuild from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> MSBuild
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: MSBuild from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> MSBuild
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: MSBuild from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> MSBuild
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: MSBuild from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> MSBuild
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: MSBuild from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> MSBuild
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: MSBuild from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> MSBuild
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: MSBuild from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> MSBuild
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: MSBuild from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> MSBuild
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: MSBuild from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> MSBuild
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Utilities.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Utilities.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Utilities.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Tasks.Core from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Tasks.Core
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Tasks.Core (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: MSBuild from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Targets (>= 0.1.0-preview-00024-160610) -> MSBuild
+warn : tool-runtime (>= 1.0.0) -> MSBuild (>= 0.1.0-preview-00024-160610)
+warn : Detected package downgrade: Microsoft.Build.Framework from 0.0.0 to 0.1.0-preview-00024-160610
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build (>= 0.1.0-preview-00024-160610) -> Microsoft.Build.Framework
+warn : tool-runtime (>= 1.0.0) -> Microsoft.Build.Framework (>= 0.1.0-preview-00024-160610)
+log : Writing lock file to disk. Path: /home/jyoung/git/dotnet/coreclr-1.0.0/packages/Microsoft.DotNet.BuildTools/1.0.27-prerelease-01008-01/lib/tool-runtime/project.lock.json
+log : /home/jyoung/git/dotnet/coreclr-1.0.0/packages/Microsoft.DotNet.BuildTools/1.0.27-prerelease-01008-01/lib/tool-runtime/project.json
+log : Restore completed in 3868ms.
+Running: /home/jyoung/git/dotnet/coreclr-1.0.0/Tools/dotnetcli/dotnet publish "/home/jyoung/git/dotnet/coreclr-1.0.0/packages/Microsoft.DotNet.BuildTools/1.0.27-prerelease-01008-01/lib/tool-runtime/project.json" -f netcoreapp1.0 -r ubuntu.14.04-x64 -o /home/jyoung/git/dotnet/coreclr-1.0.0/Tools
+Publishing tool-runtime for .NETCoreApp,Version=v1.0/ubuntu.14.04-x64
+Project tool-runtime (.NETCoreApp,Version=v1.0) will be compiled because expected outputs are missing
+Compiling tool-runtime for .NETCoreApp,Version=v1.0
+
+Compilation succeeded.
+ 0 Warning(s)
+ 0 Error(s)
+
+Time elapsed 00:00:00.8157822
+
+
+publish: Published to /home/jyoung/git/dotnet/coreclr-1.0.0/Tools
+Published 1/1 projects successfully
+Running: "/home/jyoung/git/dotnet/coreclr-1.0.0/Tools/dotnetcli/dotnet" restore "/home/jyoung/git/dotnet/coreclr-1.0.0/Tools/generated/project.json" --source https://dotnet.myget.org/F/dotnet-buildtools/api/v3/index.json --source https://api.nuget.org/v3/index.json --packages "/home/jyoung/git/dotnet/coreclr-1.0.0/Tools/."
+log : Restoring packages for /home/jyoung/git/dotnet/coreclr-1.0.0/Tools/generated/project.json...
+log : Installing Microsoft.Portable.Targets 0.1.1-dev.
+log : Installing MicroBuild.Core 0.2.0.
+log : Writing lock file to disk. Path: /home/jyoung/git/dotnet/coreclr-1.0.0/Tools/generated/project.lock.json
+log : /home/jyoung/git/dotnet/coreclr-1.0.0/Tools/generated/project.json
+log : Restore completed in 1274ms.
diff --git a/init-tools.sh b/init-tools.sh
index e6966cc2f0..cc8a5d8600 100755
--- a/init-tools.sh
+++ b/init-tools.sh
@@ -1,121 +1,169 @@
#!/usr/bin/env bash
-initDistroName()
-{
- if [ "$1" == "Linux" ]; then
- if [ ! -e /etc/os-release ]; then
- echo "WARNING: Can not determine runtime id for current distro."
- export __DistroRid=""
- else
- source /etc/os-release
- export __DistroRid="$ID.$VERSION_ID-x64"
- fi
- fi
-}
-
__scriptpath=$(cd "$(dirname "$0")"; pwd -P)
-
-# CI_SPECIFIC - On CI machines, $HOME may not be set. In such a case, create a subfolder and set the variable to set.
-# This is needed by CLI to function.
-if [ -z "$HOME" ]; then
- if [ ! -d "$__scriptpath/temp_home" ]; then
- mkdir temp_home
- fi
- export HOME=$__scriptpath/temp_home
- echo "HOME not defined; setting it to $HOME"
-fi
-
+__init_tools_log=$__scriptpath/init-tools.log
__PACKAGES_DIR=$__scriptpath/packages
__TOOLRUNTIME_DIR=$__scriptpath/Tools
__DOTNET_PATH=$__TOOLRUNTIME_DIR/dotnetcli
__DOTNET_CMD=$__DOTNET_PATH/dotnet
-if [ -z "$__BUILDTOOLS_SOURCE" ]; then __BUILDTOOLS_SOURCE=https://www.myget.org/F/dotnet-buildtools/; fi
+if [ -z "$__BUILDTOOLS_SOURCE" ]; then __BUILDTOOLS_SOURCE=https://dotnet.myget.org/F/dotnet-buildtools/api/v3/index.json; fi
__BUILD_TOOLS_PACKAGE_VERSION=$(cat $__scriptpath/BuildToolsVersion.txt)
__DOTNET_TOOLS_VERSION=$(cat $__scriptpath/DotnetCLIVersion.txt)
__BUILD_TOOLS_PATH=$__PACKAGES_DIR/Microsoft.DotNet.BuildTools/$__BUILD_TOOLS_PACKAGE_VERSION/lib
__PROJECT_JSON_PATH=$__TOOLRUNTIME_DIR/$__BUILD_TOOLS_PACKAGE_VERSION
__PROJECT_JSON_FILE=$__PROJECT_JSON_PATH/project.json
-__PROJECT_JSON_CONTENTS="{ \"dependencies\": { \"Microsoft.DotNet.BuildTools\": \"$__BUILD_TOOLS_PACKAGE_VERSION\" }, \"frameworks\": { \"dnxcore50\": { } } }"
-__DistroRid=""
-
-OSName=$(uname -s)
-case $OSName in
- Darwin)
- OS=OSX
- __DOTNET_PKG=dotnet-dev-osx-x64
- ;;
-
- Linux)
- OS=Linux
-
- if [ ! -e /etc/os-release ]; then
- echo "Cannot determine Linux distribution, asuming Ubuntu 14.04."
- __DOTNET_PKG=dotnet-dev-ubuntu.14.04-x64
- else
- source /etc/os-release
- __DOTNET_PKG="dotnet-dev-$ID.$VERSION_ID-x64"
+__PROJECT_JSON_CONTENTS="{ \"dependencies\": { \"Microsoft.DotNet.BuildTools\": \"$__BUILD_TOOLS_PACKAGE_VERSION\" }, \"frameworks\": { \"netcoreapp1.0\": { } } }"
+__INIT_TOOLS_DONE_MARKER=$__PROJECT_JSON_PATH/done
+
+# Extended version of platform detection logic from dotnet/cli/scripts/obtain/dotnet-install.sh 16692fc
+get_current_linux_name() {
+ # Detect Distro
+ if [ "$(cat /etc/*-release | grep -cim1 ubuntu)" -eq 1 ]; then
+ if [ "$(cat /etc/*-release | grep -cim1 16.04)" -eq 1 ]; then
+ echo "ubuntu.16.04"
+ return 0
+ fi
+ if [ "$(cat /etc/*-release | grep -cim1 16.10)" -eq 1 ]; then
+ echo "ubuntu.16.10"
+ return 0
fi
- ;;
-
- *)
- echo "Unsupported OS $OSName detected. Downloading ubuntu-x64 tools"
- OS=Linux
- __DOTNET_PKG=dotnet-dev-ubuntu.14.04-x64
- ;;
-esac
-# Initialize Linux Distribution name and .NET CLI package name.
+ echo "ubuntu"
+ return 0
+ elif [ "$(cat /etc/*-release | grep -cim1 centos)" -eq 1 ]; then
+ echo "centos"
+ return 0
+ elif [ "$(cat /etc/*-release | grep -cim1 rhel)" -eq 1 ]; then
+ echo "rhel"
+ return 0
+ elif [ "$(cat /etc/*-release | grep -cim1 debian)" -eq 1 ]; then
+ echo "debian"
+ return 0
+ elif [ "$(cat /etc/*-release | grep -cim1 alpine)" -eq 1 ]; then
+ echo "alpine"
+ return 0
+ elif [ "$(cat /etc/*-release | grep -cim1 fedora)" -eq 1 ]; then
+ if [ "$(cat /etc/*-release | grep -cim1 23)" -eq 1 ]; then
+ echo "fedora.23"
+ return 0
+ fi
+ if [ "$(cat /etc/*-release | grep -cim1 24)" -eq 1 ]; then
+ echo "fedora.24"
+ return 0
+ fi
+ elif [ "$(cat /etc/*-release | grep -cim1 opensuse)" -eq 1 ]; then
+ if [ "$(cat /etc/*-release | grep -cim1 13.2)" -eq 1 ]; then
+ echo "opensuse.13.2"
+ return 0
+ fi
+ if [ "$(cat /etc/*-release | grep -cim1 42.1)" -eq 1 ]; then
+ echo "opensuse.42.1"
+ return 0
+ fi
+ fi
-initDistroName $OS
+ # Cannot determine Linux distribution, assuming Ubuntu 14.04.
+ echo "ubuntu"
+ return 0
+}
-# Work around mac build issue
-if [ "$OS" == "OSX" ]; then
- echo Raising file open limit - otherwise Mac build may fail
- echo ulimit -n 2048
- ulimit -n 2048
+if [ -z "$__DOTNET_PKG" ]; then
+OSName=$(uname -s)
+ case $OSName in
+ Darwin)
+ OS=OSX
+ __DOTNET_PKG=dotnet-dev-osx-x64
+ ulimit -n 2048
+ ;;
+
+ Linux)
+ __DOTNET_PKG="dotnet-dev-$(get_current_linux_name)-x64"
+ OS=Linux
+ ;;
+
+ *)
+ echo "Unsupported OS '$OSName' detected. Downloading ubuntu-x64 tools."
+ OS=Linux
+ __DOTNET_PKG=dotnet-dev-ubuntu-x64
+ ;;
+ esac
fi
-__CLIDownloadURL=https://dotnetcli.blob.core.windows.net/dotnet/preview/Binaries/${__DOTNET_TOOLS_VERSION}/${__DOTNET_PKG}.${__DOTNET_TOOLS_VERSION}.tar.gz
-echo ".NET CLI will be downloaded from $__CLIDownloadURL"
-echo "Locating $__PROJECT_JSON_FILE to see if we already downloaded .NET CLI tools..."
+if [ ! -e $__INIT_TOOLS_DONE_MARKER ]; then
+ __PATCH_CLI_NUGET_FRAMEWORKS=0
-if [ ! -e $__PROJECT_JSON_FILE ]; then
- echo "$__PROJECT_JSON_FILE not found. Proceeding to download .NET CLI tools. "
if [ -e $__TOOLRUNTIME_DIR ]; then rm -rf -- $__TOOLRUNTIME_DIR; fi
+ echo "Running: $__scriptpath/init-tools.sh" > $__init_tools_log
if [ ! -e $__DOTNET_PATH ]; then
- # curl has HTTPS CA trust-issues less often than wget, so lets try that first.
- which curl > /dev/null 2> /dev/null
- if [ $? -ne 0 ]; then
- mkdir -p "$__DOTNET_PATH"
- wget -q -O $__DOTNET_PATH/dotnet.tar $__CLIDownloadURL
- echo "wget -q -O $__DOTNET_PATH/dotnet.tar $__CLIDownloadURL"
+
+ mkdir -p "$__DOTNET_PATH"
+
+ if [ -n "$DOTNET_TOOLSET_DIR" ] && [ -d "$DOTNET_TOOLSET_DIR/$__DOTNET_TOOLS_VERSION" ]; then
+ echo "Copying $DOTNET_TOOLSET_DIR/$__DOTNET_TOOLS_VERSION to $__DOTNET_PATH" >> $__init_tools_log
+ cp -r $DOTNET_TOOLSET_DIR/$__DOTNET_TOOLS_VERSION/* $__DOTNET_PATH
+ elif [ -n "$DOTNET_TOOL_DIR" ] && [ -d "$DOTNET_TOOL_DIR" ]; then
+ echo "Copying $DOTNET_TOOL_DIR to $__DOTNET_PATH" >> $__init_tools_log
+ cp -r $DOTNET_TOOL_DIR/* $__DOTNET_PATH
else
- curl --retry 10 -sSL --create-dirs -o $__DOTNET_PATH/dotnet.tar $__CLIDownloadURL
- echo "curl --retry 10 -sSL --create-dirs -o $__DOTNET_PATH/dotnet.tar $__CLIDownloadURL"
+ echo "Installing dotnet cli..."
+ __DOTNET_LOCATION="https://dotnetcli.blob.core.windows.net/dotnet/Sdk/${__DOTNET_TOOLS_VERSION}/${__DOTNET_PKG}.${__DOTNET_TOOLS_VERSION}.tar.gz"
+ # curl has HTTPS CA trust-issues less often than wget, so lets try that first.
+ echo "Installing '${__DOTNET_LOCATION}' to '$__DOTNET_PATH/dotnet.tar'" >> $__init_tools_log
+ which curl > /dev/null 2> /dev/null
+ if [ $? -ne 0 ]; then
+ wget -q -O $__DOTNET_PATH/dotnet.tar ${__DOTNET_LOCATION}
+ else
+ curl --retry 10 -sSL --create-dirs -o $__DOTNET_PATH/dotnet.tar ${__DOTNET_LOCATION}
+ fi
+ cd $__DOTNET_PATH
+ tar -xf $__DOTNET_PATH/dotnet.tar
+
+ cd $__scriptpath
+
+ __PATCH_CLI_NUGET_FRAMEWORKS=1
fi
- cd $__DOTNET_PATH
- tar -xf $__DOTNET_PATH/dotnet.tar
- if [ -n "$BUILDTOOLS_OVERRIDE_RUNTIME" ]; then
- find $__DOTNET_PATH -name *.ni.* | xargs rm 2>/dev/null
- cp -R $BUILDTOOLS_OVERRIDE_RUNTIME/* $__DOTNET_PATH/bin
- cp -R $BUILDTOOLS_OVERRIDE_RUNTIME/* $__DOTNET_PATH/bin/dnx
- cp -R $BUILDTOOLS_OVERRIDE_RUNTIME/* $__DOTNET_PATH/runtime/coreclr
+ fi
+
+
+ if [ -n "$BUILD_TOOLS_TOOLSET_DIR" ] && [ -d "$BUILD_TOOLS_TOOLSET_DIR/$__BUILD_TOOLS_PACKAGE_VERSION" ]; then
+ echo "Copying $BUILD_TOOLS_TOOLSET_DIR/$__BUILD_TOOLS_PACKAGE_VERSION to $__TOOLRUNTIME_DIR" >> $__init_tools_log
+ cp -r $BUILD_TOOLS_TOOLSET_DIR/$__BUILD_TOOLS_PACKAGE_VERSION/* $__TOOLRUNTIME_DIR
+ elif [ -n "$BUILD_TOOLS_TOOL_DIR" ] && [ -d "$BUILD_TOOLS_TOOL_DIR" ]; then
+ echo "Copying $BUILD_TOOLS_TOOL_DIR to $__TOOLRUNTIME_DIR" >> $__init_tools_log
+ cp -r $BUILD_TOOLS_TOOL_DIR/* $__TOOLRUNTIME_DIR
+ else
+ if [ ! -d "$__PROJECT_JSON_PATH" ]; then mkdir "$__PROJECT_JSON_PATH"; fi
+ echo $__PROJECT_JSON_CONTENTS > "$__PROJECT_JSON_FILE"
+
+ if [ ! -e $__BUILD_TOOLS_PATH ]; then
+ echo "Restoring BuildTools version $__BUILD_TOOLS_PACKAGE_VERSION..."
+ echo "Running: $__DOTNET_CMD restore \"$__PROJECT_JSON_FILE\" --no-cache --packages $__PACKAGES_DIR --source $__BUILDTOOLS_SOURCE" >> $__init_tools_log
+ $__DOTNET_CMD restore "$__PROJECT_JSON_FILE" --no-cache --packages $__PACKAGES_DIR --source $__BUILDTOOLS_SOURCE >> $__init_tools_log
+ if [ ! -e "$__BUILD_TOOLS_PATH/init-tools.sh" ]; then echo "ERROR: Could not restore build tools correctly. See '$__init_tools_log' for more details."1>&2; fi
fi
- cd $__scriptpath
+ echo "Initializing BuildTools..."
+ echo "Running: $__BUILD_TOOLS_PATH/init-tools.sh $__scriptpath $__DOTNET_CMD $__TOOLRUNTIME_DIR" >> $__init_tools_log
+ $__BUILD_TOOLS_PATH/init-tools.sh $__scriptpath $__DOTNET_CMD $__TOOLRUNTIME_DIR >> $__init_tools_log
+ if [ "$?" != "0" ]; then
+ echo "ERROR: An error occured when trying to initialize the tools. Please check '$__init_tools_log' for more details."1>&2
+ exit 1
+ fi
fi
- mkdir "$__PROJECT_JSON_PATH"
- echo $__PROJECT_JSON_CONTENTS > "$__PROJECT_JSON_FILE"
-
- if [ ! -e $__BUILD_TOOLS_PATH ]; then
- $__DOTNET_CMD restore "$__PROJECT_JSON_FILE" --packages $__PACKAGES_DIR --source $__BUILDTOOLS_SOURCE
+ if [ $__PATCH_CLI_NUGET_FRAMEWORKS -eq 1 ]; then
+ echo "Updating CLI NuGet Frameworks map..."
+ cp $__TOOLRUNTIME_DIR/NuGet.Frameworks.dll $__TOOLRUNTIME_DIR/dotnetcli/sdk/$__DOTNET_TOOLS_VERSION >> $__init_tools_log
+ if [ "$?" != "0" ]; then
+ echo "ERROR: An error occured when updating Nuget for CLI . Please check '$__init_tools_log' for more details."1>&2
+ exit 1
+ fi
fi
- # On ubuntu 14.04, /bin/sh (symbolic link) calls /bin/dash by default.
- $__BUILD_TOOLS_PATH/init-tools.sh $__scriptpath $__DOTNET_CMD $__TOOLRUNTIME_DIR
+ touch $__INIT_TOOLS_DONE_MARKER
+ echo "Done initializing tools."
else
- echo "$__PROJECT_JSON_FILE found. Skipping .NET CLI installation."
+ echo "Tools are already initialized"
fi
diff --git a/netci.groovy b/netci.groovy
index 8527b2c506..b1ffaf8084 100755
--- a/netci.groovy
+++ b/netci.groovy
@@ -15,6 +15,7 @@ def static getOSGroup(def os) {
def osGroupMap = ['Ubuntu':'Linux',
'RHEL7.2': 'Linux',
'Ubuntu16.04': 'Linux',
+ 'Ubuntu16.10': 'Linux',
'Debian8.4':'Linux',
'Fedora23':'Linux',
'OSX':'OSX',
@@ -31,20 +32,43 @@ def static getOSGroup(def os) {
// We use this class (vs variables) so that the static functions can access data here.
class Constants {
+
// Innerloop build OS's
// The Windows_NT_BuildOnly OS is a way to speed up the Non-NT builds temporarily by avoiding
// test execution in the build flow runs. It generates the exact same build
// as Windows_NT but without the tests.
- def static osList = ['Ubuntu', 'Debian8.4', 'OSX', 'Windows_NT', 'Windows_NT_BuildOnly', 'FreeBSD', 'CentOS7.1', 'OpenSUSE13.2', 'OpenSUSE42.1', 'RHEL7.2', 'LinuxARMEmulator', 'Ubuntu16.04', 'Fedora23']
+ def static osList = [
+ 'Ubuntu',
+ 'Debian8.4',
+ 'OSX',
+ 'Windows_NT',
+ 'Windows_NT_BuildOnly',
+ 'FreeBSD',
+ 'CentOS7.1',
+ 'OpenSUSE13.2',
+ 'OpenSUSE42.1',
+ 'RHEL7.2',
+ 'LinuxARMEmulator',
+ 'Ubuntu16.04',
+ 'Ubuntu16.10',
+ 'Fedora23']
+
def static crossList = ['Ubuntu', 'OSX', 'CentOS7.1', 'RHEL7.2', 'Debian8.4', 'OpenSUSE13.2']
+
// This is a set of JIT stress modes combined with the set of variables that
// need to be set to actually enable that stress mode. The key of the map is the stress mode and
// the values are the environment variables
- def static jitStressModeScenarios = ['minopts' : ['COMPlus_JITMinOpts' : '1'], 'forcerelocs' : ['COMPlus_ForceRelocs' : '1'],
- 'jitstress1' : ['COMPlus_JitStress' : '1'], 'jitstress2' : ['COMPlus_JitStress' : '2'],
- 'jitstressregs1' : ['COMPlus_JitStressRegs' : '1'], 'jitstressregs2' : ['COMPlus_JitStressRegs' : '2'],
- 'jitstressregs3' : ['COMPlus_JitStressRegs' : '3'], 'jitstressregs4' : ['COMPlus_JitStressRegs' : '4'],
- 'jitstressregs8' : ['COMPlus_JitStressRegs' : '8'], 'jitstressregs0x10' : ['COMPlus_JitStressRegs' : '0x10'],
+ def static jitStressModeScenarios = [
+ 'minopts' : ['COMPlus_JITMinOpts' : '1'],
+ 'forcerelocs' : ['COMPlus_ForceRelocs' : '1'],
+ 'jitstress1' : ['COMPlus_JitStress' : '1'],
+ 'jitstress2' : ['COMPlus_JitStress' : '2'],
+ 'jitstressregs1' : ['COMPlus_JitStressRegs' : '1'],
+ 'jitstressregs2' : ['COMPlus_JitStressRegs' : '2'],
+ 'jitstressregs3' : ['COMPlus_JitStressRegs' : '3'],
+ 'jitstressregs4' : ['COMPlus_JitStressRegs' : '4'],
+ 'jitstressregs8' : ['COMPlus_JitStressRegs' : '8'],
+ 'jitstressregs0x10' : ['COMPlus_JitStressRegs' : '0x10'],
'jitstressregs0x80' : ['COMPlus_JitStressRegs' : '0x80'],
'jitstress2_jitstressregs1' : ['COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '1'],
'jitstress2_jitstressregs2' : ['COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '2'],
@@ -53,33 +77,62 @@ class Constants {
'jitstress2_jitstressregs8' : ['COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '8'],
'jitstress2_jitstressregs0x10' : ['COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '0x10'],
'jitstress2_jitstressregs0x80' : ['COMPlus_JitStress' : '2', 'COMPlus_JitStressRegs' : '0x80'],
- 'corefx_baseline' : [ : ], // corefx baseline
- 'corefx_minopts' : ['COMPlus_JITMinOpts' : '1'],
+ 'corefx_baseline' : [ : ], // corefx baseline
+ 'corefx_minopts' : ['COMPlus_JITMinOpts' : '1'],
'corefx_jitstress1' : ['COMPlus_JitStress' : '1'],
'corefx_jitstress2' : ['COMPlus_JitStress' : '2'],
- 'corefx_jitstressregs1' : ['COMPlus_JitStressRegs' : '1'], 'corefx_jitstressregs2' : ['COMPlus_JitStressRegs' : '2'],
- 'corefx_jitstressregs3' : ['COMPlus_JitStressRegs' : '3'], 'corefx_jitstressregs4' : ['COMPlus_JitStressRegs' : '4'],
- 'corefx_jitstressregs8' : ['COMPlus_JitStressRegs' : '8'], 'corefx_jitstressregs0x10' : ['COMPlus_JitStressRegs' : '0x10'],
+ 'corefx_jitstressregs1' : ['COMPlus_JitStressRegs' : '1'],
+ 'corefx_jitstressregs2' : ['COMPlus_JitStressRegs' : '2'],
+ 'corefx_jitstressregs3' : ['COMPlus_JitStressRegs' : '3'],
+ 'corefx_jitstressregs4' : ['COMPlus_JitStressRegs' : '4'],
+ 'corefx_jitstressregs8' : ['COMPlus_JitStressRegs' : '8'],
+ 'corefx_jitstressregs0x10' : ['COMPlus_JitStressRegs' : '0x10'],
'corefx_jitstressregs0x80' : ['COMPlus_JitStressRegs' : '0x80'],
- 'gcstress0x3' : ['COMPlus_GCStress' : '0x3'], 'gcstress0xc' : ['COMPlus_GCStress' : '0xC'],
- 'zapdisable' : ['COMPlus_ZapDisable' : '0xC'],
- 'heapverify1' : ['COMPlus_HeapVerify' : '1'],
- 'gcstress0xc_zapdisable' : ['COMPlus_GCStress' : '0xC', 'COMPlus_ZapDisable' : '1'],
- 'gcstress0xc_zapdisable_jitstress2' : ['COMPlus_GCStress' : '0xC', 'COMPlus_ZapDisable' : '1', 'COMPlus_JitStress' : '2'],
- 'gcstress0xc_zapdisable_heapverify1' : ['COMPlus_GCStress' : '0xC', 'COMPlus_ZapDisable' : '1', 'COMPlus_HeapVerify' : '1'],
- 'gcstress0xc_jitstress1' : ['COMPlus_GCStress' : '0xC', 'COMPlus_JitStress' : '1'],
- 'gcstress0xc_jitstress2' : ['COMPlus_GCStress' : '0xC', 'COMPlus_JitStress' : '2'],
- 'gcstress0xc_minopts_heapverify1' : ['COMPlus_GCStress' : '0xC', 'COMPlus_JITMinOpts' : '1', 'COMPlus_HeapVerify' : '1']
+ 'gcstress0x3' : ['COMPlus_GCStress' : '0x3'],
+ 'gcstress0xc' : ['COMPlus_GCStress' : '0xC'],
+ 'zapdisable' : ['COMPlus_ZapDisable' : '1'],
+ 'heapverify1' : ['COMPlus_HeapVerify' : '1'],
+ 'gcstress0xc_zapdisable' : ['COMPlus_GCStress' : '0xC', 'COMPlus_ZapDisable' : '1'],
+ 'gcstress0xc_zapdisable_jitstress2' : ['COMPlus_GCStress' : '0xC', 'COMPlus_ZapDisable' : '1', 'COMPlus_JitStress' : '2'],
+ 'gcstress0xc_zapdisable_heapverify1' : ['COMPlus_GCStress' : '0xC', 'COMPlus_ZapDisable' : '1', 'COMPlus_HeapVerify' : '1'],
+ 'gcstress0xc_jitstress1' : ['COMPlus_GCStress' : '0xC', 'COMPlus_JitStress' : '1'],
+ 'gcstress0xc_jitstress2' : ['COMPlus_GCStress' : '0xC', 'COMPlus_JitStress' : '2'],
+ 'gcstress0xc_minopts_heapverify1' : ['COMPlus_GCStress' : '0xC', 'COMPlus_JITMinOpts' : '1', 'COMPlus_HeapVerify' : '1']
]
+
// This is a set of r2r jit stress scenarios
- def static r2rJitStressScenarios = ['r2r_jitstress1', 'r2r_jitstress2', 'r2r_jitstressregs1', 'r2r_jitstressregs2', 'r2r_jitstressregs3',
- 'r2r_jitstressregs4', 'r2r_jitstressregs8', 'r2r_jitstressregsx10', 'r2r_jitstressregsx80',
- 'r2r_jitminopts', 'r2r_jitforcerelocs']
+ def static r2rJitStressScenarios = [
+ 'r2r_jitstress1',
+ 'r2r_jitstress2',
+ 'r2r_jitstressregs1',
+ 'r2r_jitstressregs2',
+ 'r2r_jitstressregs3',
+ 'r2r_jitstressregs4',
+ 'r2r_jitstressregs8',
+ 'r2r_jitstressregsx10',
+ 'r2r_jitstressregsx80',
+ 'r2r_jitminopts',
+ 'r2r_jitforcerelocs']
+
// This is the basic set of scenarios
- def static basicScenarios = ['default', 'pri1', 'ilrt', 'r2r', 'pri1r2r', 'gcstress15_pri1r2r', 'longgc', 'coverage', 'formatting', 'gcsimulator'] + r2rJitStressScenarios
+ def static basicScenarios = [
+ 'default',
+ 'pri1',
+ 'ilrt',
+ 'r2r',
+ 'pri1r2r',
+ 'gcstress15_pri1r2r',
+ 'longgc',
+ 'coverage',
+ 'formatting',
+ 'gcsimulator',
+ 'jitdiff',
+ 'standalone_gc'] + r2rJitStressScenarios
+
def static configurationList = ['Debug', 'Checked', 'Release']
+
// This is the set of architectures
- def static architectureList = ['arm', 'arm64', 'x64', 'x86ryujit', 'x86lb']
+ def static architectureList = ['arm', 'arm64', 'x64', 'x86', 'x86compatjit', 'x86lb']
}
def static setMachineAffinity(def job, def os, def architecture) {
@@ -139,6 +192,10 @@ def static isLongGc(def scenario) {
return (scenario == 'longgc' || scenario == 'gcsimulator')
}
+def static isJitDiff(def scenario) {
+ return (scenario == 'jitdiff')
+}
+
def static setTestJobTimeOut(newJob, scenario) {
if (isGCStressRelatedTesting(scenario)) {
Utilities.setJobTimeout(newJob, 4320)
@@ -158,6 +215,9 @@ def static setTestJobTimeOut(newJob, scenario) {
else if (isLongGc(scenario)) {
Utilities.setJobTimeout(newJob, 1440)
}
+ else if (isJitDiff(scenario)) {
+ Utilities.setJobTimeout(newJob, 240)
+ }
// Non-test jobs use the default timeout value.
}
@@ -267,8 +327,11 @@ def static getJobName(def configuration, def architecture, def os, def scenario,
baseName = architecture.toLowerCase() + '_emulator_cross_' + configuration.toLowerCase() + '_' + os.toLowerCase()
}
break
- case 'x86ryujit':
- baseName = 'x86_ryujit_' + configuration.toLowerCase() + '_' + os.toLowerCase()
+ case 'x86':
+ baseName = architecture.toLowerCase() + '_' + configuration.toLowerCase() + '_' + os.toLowerCase()
+ break
+ case 'x86compatjit':
+ baseName = 'x86_compatjit_' + configuration.toLowerCase() + '_' + os.toLowerCase()
break
case 'x86lb':
baseName = 'x86_lb_' + configuration.toLowerCase() + '_' + os.toLowerCase()
@@ -305,7 +368,8 @@ def static addTriggers(def job, def branch, def isPR, def architecture, def os,
case 'default':
switch (architecture) {
case 'x64':
- case 'x86ryujit':
+ case 'x86':
+ case 'x86compatjit':
case 'x86lb':
if (isFlowJob || os == 'Windows_NT' || !(os in Constants.crossList)) {
Utilities.addGithubPushTrigger(job)
@@ -366,7 +430,7 @@ def static addTriggers(def job, def branch, def isPR, def architecture, def os,
}
}
// For x86, only add per-commit jobs for Windows
- else if (architecture == 'x86ryujit' || architecture == 'x86lb') {
+ else if (architecture == 'x86' || architecture == 'x86compatjit' || architecture == 'x86lb') {
if (os == 'Windows_NT') {
Utilities.addGithubPushTrigger(job)
}
@@ -411,7 +475,7 @@ def static addTriggers(def job, def branch, def isPR, def architecture, def os,
}
}
// For x86, only add per-commit jobs for Windows
- else if (architecture == 'x86ryujit' || architecture == 'x86lb') {
+ else if (architecture == 'x86' || architecture == 'x86compatjit' || architecture == 'x86lb') {
if (os == 'Windows_NT') {
Utilities.addPeriodicTrigger(job, 'H H * * 3,6') // some time every Wednesday and Saturday
}
@@ -434,6 +498,13 @@ def static addTriggers(def job, def branch, def isPR, def architecture, def os,
// TODO: Add once external email sending is available again
// addEmailPublisher(job, 'dotnetgctests@microsoft.com')
break
+ case 'standalone_gc':
+ assert (os == 'Windows_NT')
+ assert (configuration == 'Release' || configuration == 'Checked')
+ // TODO: Add once external email sending is available again
+ // addEmailPublisher(job, 'dotnetgctests@microsoft.com')
+ Utilities.addPeriodicTrigger(job, '@weekly')
+ break
case 'ilrt':
assert !(os in bidailyCrossList)
// ILASM/ILDASM roundtrip one gets a daily build, and only for release
@@ -445,6 +516,12 @@ def static addTriggers(def job, def branch, def isPR, def architecture, def os,
}
}
break
+ case 'jitdiff':
+ assert (os == 'Ubuntu' || os == 'Windows_NT' || os == 'OSX')
+ assert configuration == 'Checked'
+ assert (architecture == 'x64' || architecture == 'x86')
+ Utilities.addGithubPushTrigger(job)
+ break
case 'coverage':
assert (os == 'Ubuntu' || os == 'Windows_NT')
assert configuration == 'Release'
@@ -539,7 +616,7 @@ def static addTriggers(def job, def branch, def isPR, def architecture, def os,
// We generally only have a distinct set of default triggers but a bunch of on-demand ones.
def osGroup = getOSGroup(os)
switch (architecture) {
- case 'x64':
+ case 'x64': // editor brace matching: {
if (scenario == 'coverage') {
assert configuration == 'Release'
if (os == 'Ubuntu') {
@@ -551,7 +628,7 @@ def static addTriggers(def job, def branch, def isPR, def architecture, def os,
if (scenario == 'formatting') {
assert configuration == 'Checked'
if (os == 'Windows_NT' || os == 'Ubuntu') {
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} Formatting", "(?i).*test\\W+${os}\\W+formatting.*")
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} Formatting")
}
break
}
@@ -572,6 +649,7 @@ def static addTriggers(def job, def branch, def isPR, def architecture, def os,
break
case 'Fedora23':
case 'Ubuntu16.04':
+ case 'Ubuntu16.10':
case 'OpenSUSE42.1':
assert !isFlowJob
assert scenario == 'default'
@@ -597,6 +675,11 @@ def static addTriggers(def job, def branch, def isPR, def architecture, def os,
Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Priority 1 Build and Test", "(?i).*test\\W+${os}\\W+${scenario}.*")
}
break
+ case 'jitdiff':
+ if (configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Jit Diff Build and Test", "(?i).*test\\W+${os}\\W+${scenario}.*")
+ }
+ break
case 'ilrt':
if (configuration == 'Release') {
Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} IL RoundTrip Build and Test", "(?i).*test\\W+${os}\\W+${scenario}.*")
@@ -874,6 +957,11 @@ def static addTriggers(def job, def branch, def isPR, def architecture, def os,
Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Priority 1 Build and Test")
}
break
+ case 'jitdiff':
+ if (configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Jit Diff Build and Test", "(?i).*test\\W+${os}\\W+${scenario}.*")
+ }
+ break
case 'ilrt':
if (configuration == 'Release') {
Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} IL RoundTrip Build and Test", "(?i).*test\\W+${os}\\W+${scenario}.*")
@@ -959,6 +1047,11 @@ def static addTriggers(def job, def branch, def isPR, def architecture, def os,
Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} GC Simulator", "(?i).*test\\W+${os}\\W+${configuration}\\W+${scenario}.*")
}
break
+ case 'standalone_gc':
+ if (configuration == 'Release' || configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Standalone GC", "(?i).*test\\W+${os}\\W+${configuration}\\W+${scenario}.*")
+ }
+ break
case 'minopts':
assert (os == 'Windows_NT') || (os in Constants.crossList)
Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build and Test (Jit - MinOpts)",
@@ -1070,7 +1163,8 @@ def static addTriggers(def job, def branch, def isPR, def architecture, def os,
break
}
break
- case 'arm':
+ // editor brace matching: }
+ case 'arm': // editor brace matching: {
assert scenario == 'default'
switch (os) {
case 'Ubuntu':
@@ -1082,13 +1176,20 @@ def static addTriggers(def job, def branch, def isPR, def architecture, def os,
Utilities.addGithubPRTriggerForBranch(job, branch, "Linux ARM Emulator Cross ${configuration} Build")
}
break
+ case 'Windows_NT':
+ if (configuration == 'Debug' || configuration == 'Release')
+ {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} Cross ${configuration} Build")
+ }
+ break
default:
println("NYI os: ${os}");
assert false
break
}
break
- case 'arm64':
+ // editor brace matching: }
+ case 'arm64': // editor brace matching: {
assert (scenario == 'default') || (scenario == 'pri1r2r') || (scenario == 'gcstress0x3') || (scenario == 'gcstress0xc')
// Set up a private trigger
@@ -1123,165 +1224,360 @@ def static addTriggers(def job, def branch, def isPR, def architecture, def os,
break
}
break
- case 'x86ryujit':
- def arch = 'x86'
- def jit = 'ryujit'
+ // editor brace matching: }
+ case 'x86': // editor brace matching: {
+ assert (os == 'Windows_NT')
switch (scenario) {
case 'default':
- // Default trigger
- if (os == 'Windows_NT') {
- if (configuration == 'Checked') {
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} Build and Test")
- }
+ if (configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build and Test")
}
- else {
- // default trigger
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} Build", "(?i).*test\\W+${arch}\\W+${osGroup}.\\W+${jit}.*")
+ break
+ case 'pri1':
+ if (configuration == 'Release') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Priority 1 Build and Test")
+ }
+ break
+ case 'ilrt':
+ if (configuration == 'Release') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} IL RoundTrip Build and Test",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ }
+ break
+ case 'r2r':
+ if (configuration == 'Checked' || configuration == 'Release') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} R2R pri0 Build & Test",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ }
+ break
+ case 'pri1r2r':
+ if (configuration == 'Checked' || configuration == 'Release') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} R2R pri1 Build & Test",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ }
+ break
+ case 'gcstress15_pri1r2r':
+ if (configuration == 'Release' || configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} GCStress 15 R2R pri1 Build & Test",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ }
+ break
+ case 'r2r_jitstress1':
+ if (configuration == 'Release' || configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} jitstress1 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ }
+ break
+ case 'r2r_jitstress2':
+ if (configuration == 'Release' || configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} jitstress2 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ }
+ break
+ case 'r2r_jitstressregs1':
+ if (configuration == 'Release' || configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} jitstressregs1 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ }
+ break
+ case 'r2r_jitstressregs2':
+ if (configuration == 'Release' || configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} jitstressregs2 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ }
+ break
+ case 'r2r_jitstressregs3':
+ if (configuration == 'Release' || configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} jitstressregs3 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ }
+ break
+ case 'r2r_jitstressregs4':
+ if (configuration == 'Release' || configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} jitstressregs4 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ }
+ break
+ case 'r2r_jitstressregs8':
+ if (configuration == 'Release' || configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} jitstressregs8 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ }
+ break
+ case 'r2r_jitstressregsx10':
+ if (configuration == 'Release' || configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} jitstressregsx10 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ }
+ break
+ case 'r2r_jitstressregsx80':
+ if (configuration == 'Release' || configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} jitstressregsx80 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ }
+ break
+ case 'r2r_jitminopts':
+ if (configuration == 'Release' || configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} JITMinOpts R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ }
+ break
+ case 'r2r_jitforcerelocs':
+ if (configuration == 'Release' || configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} ForceRelocs R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ }
+ break
+ case 'longgc':
+ if (configuration == 'Release') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Long-Running GC Build & Test",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ }
+ break
+ case 'gcsimulator':
+ if (configuration == 'Release') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} GC Simulator",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ }
+ break
+ case 'standalone_gc':
+ if (configuration == 'Release' || configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Standalone GC",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ }
+ break
+ case 'minopts':
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build and Test (Jit - MinOpts)",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ break
+ case 'forcerelocs':
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build and Test (Jit - ForceRelocs)",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ break
+ case 'jitstress1':
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStress=1)",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ break
+ case 'jitstress2':
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStress=2)",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ break
+ case 'jitstressregs1':
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStressRegs=1)",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ break
+ case 'jitstressregs2':
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStressRegs=2)",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ break
+ case 'jitstressregs3':
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStressRegs=3)",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ break
+ case 'jitstressregs4':
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStressRegs=4)",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ break
+ case 'jitstressregs8':
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStressRegs=8)",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ break
+ case 'jitstressregs0x10':
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStressRegs=0x10)",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ break
+ case 'jitstressregs0x80':
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build and Test (Jit - JitStressRegs=0x80)",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ break
+ case 'jitstress2_jitstressregs1':
+ case 'jitstress2_jitstressregs2':
+ case 'jitstress2_jitstressregs3':
+ case 'jitstress2_jitstressregs4':
+ case 'jitstress2_jitstressregs8':
+ case 'jitstress2_jitstressregs0x10':
+ case 'jitstress2_jitstressregs0x80':
+ case 'gcstress0x3':
+ case 'gcstress0xc':
+ case 'zapdisable':
+ case 'heapverify1':
+ case 'gcstress0xc_zapdisable':
+ case 'gcstress0xc_zapdisable_jitstress2':
+ case 'gcstress0xc_zapdisable_heapverify1':
+ case 'gcstress0xc_jitstress1':
+ case 'gcstress0xc_jitstress2':
+ case 'gcstress0xc_minopts_heapverify1':
+ def displayStr = getStressModeDisplayName(scenario)
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build and Test (Jit - ${displayStr})",
+ "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}\\W+${scenario}.*")
+ break
+ default:
+ println("Unknown scenario: ${os} ${architecture} ${scenario}");
+ assert false
+ break
+ }
+ break
+ // editor brace matching: }
+ case 'x86compatjit': // editor brace matching: {
+ assert (os == 'Windows_NT')
+ def arch = 'x86'
+ def jit = 'compatjit'
+ switch (scenario) {
+ case 'default':
+ if (configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} Build and Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}.*")
}
break
case 'pri1':
- // Default trigger
if (configuration == 'Release') {
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} Priority 1 Build and Test")
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} Priority 1 Build and Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+Priority 1 Build and Test.*")
}
break
case 'ilrt':
if (configuration == 'Release') {
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} IL RoundTrip Build and Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} IL RoundTrip Build and Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
break
case 'r2r':
if (configuration == 'Checked' || configuration == 'Release') {
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} R2R pri0 Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} R2R pri0 Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
break
case 'pri1r2r':
if (configuration == 'Checked' || configuration == 'Release') {
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} R2R pri1 Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} R2R pri1 Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
break
case 'gcstress15_pri1r2r':
if (configuration == 'Release' || configuration == 'Checked') {
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} GCStress 15 R2R pri1 Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} GCStress 15 R2R pri1 Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
break
case 'r2r_jitstress1':
if (configuration == 'Release' || configuration == 'Checked') {
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstress1 R2R Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstress1 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
break
case 'r2r_jitstress2':
if (configuration == 'Release' || configuration == 'Checked') {
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstress2 R2R Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstress2 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
break
case 'r2r_jitstressregs1':
if (configuration == 'Release' || configuration == 'Checked') {
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregs1 R2R Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregs1 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
break
case 'r2r_jitstressregs2':
if (configuration == 'Release' || configuration == 'Checked') {
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregs2 R2R Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregs2 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
break
case 'r2r_jitstressregs3':
if (configuration == 'Release' || configuration == 'Checked') {
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregs3 R2R Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregs3 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
break
case 'r2r_jitstressregs4':
if (configuration == 'Release' || configuration == 'Checked') {
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregs4 R2R Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregs4 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
break
case 'r2r_jitstressregs8':
if (configuration == 'Release' || configuration == 'Checked') {
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregs8 R2R Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregs8 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
break
case 'r2r_jitstressregsx10':
if (configuration == 'Release' || configuration == 'Checked') {
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregsx10 R2R Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregsx10 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
break
case 'r2r_jitstressregsx80':
if (configuration == 'Release' || configuration == 'Checked') {
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregsx80 R2R Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregsx80 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
break
case 'r2r_jitminopts':
if (configuration == 'Release' || configuration == 'Checked') {
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} JITMinOpts R2R Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} JITMinOpts R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
break
case 'r2r_jitforcerelocs':
if (configuration == 'Release' || configuration == 'Checked') {
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} ForceRelocs R2R Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} ForceRelocs R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
break
case 'longgc':
if (configuration == 'Release') {
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} Long-Running GC Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} Long-Running GC Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
break
case 'gcsimulator':
if (configuration == 'Release') {
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} GC Simulator", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} GC Simulator",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
break
case 'minopts':
- assert (os == 'Windows_NT')
Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} Build and Test (Jit - MinOpts)",
"(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
break
case 'forcerelocs':
- assert (os == 'Windows_NT')
Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} Build and Test (Jit - ForceRelocs)",
"(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
break
case 'jitstress1':
- assert (os == 'Windows_NT')
Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} Build and Test (Jit - JitStress=1)",
"(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
break
case 'jitstress2':
- assert (os == 'Windows_NT')
Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} Build and Test (Jit - JitStress=2)",
"(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
break
case 'jitstressregs1':
- assert (os == 'Windows_NT')
Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} Build and Test (Jit - JitStressRegs=1)",
"(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
break
case 'jitstressregs2':
- assert (os == 'Windows_NT')
Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} Build and Test (Jit - JitStressRegs=2)",
"(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
break
case 'jitstressregs3':
- assert (os == 'Windows_NT')
Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} Build and Test (Jit - JitStressRegs=3)",
"(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
break
case 'jitstressregs4':
- assert (os == 'Windows_NT')
Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} Build and Test (Jit - JitStressRegs=4)",
"(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
break
case 'jitstressregs8':
- assert (os == 'Windows_NT')
Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} Build and Test (Jit - JitStressRegs=8)",
"(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
break
case 'jitstressregs0x10':
- assert (os == 'Windows_NT')
Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} Build and Test (Jit - JitStressRegs=0x10)",
"(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
break
case 'jitstressregs0x80':
- assert (os == 'Windows_NT')
Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} Build and Test (Jit - JitStressRegs=0x80)",
"(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
break
@@ -1303,150 +1599,138 @@ def static addTriggers(def job, def branch, def isPR, def architecture, def os,
case 'gcstress0xc_jitstress2':
case 'gcstress0xc_minopts_heapverify1':
def displayStr = getStressModeDisplayName(scenario)
- assert (os == 'Windows_NT')
Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} Build and Test (Jit - ${displayStr})",
"(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
break
default:
- println("Unknown scenario: ${arch} ${jit} ${scenario}");
+ println("Unknown scenario: ${os} ${arch} ${jit} ${scenario}");
assert false
break
}
break
- case 'x86lb':
- assert (scenario == 'default' || scenario == 'r2r' || scenario == 'pri1r2r' || scenario == 'gcstress15_pri1r2r' || scenario == 'longgc' || scenario == 'gcsimulator' ||
+ // editor brace matching: }
+ case 'x86lb': // editor brace matching: {
+ assert (os == 'Windows_NT')
+ assert (scenario == 'default' ||
+ scenario == 'r2r' ||
+ scenario == 'pri1r2r' ||
+ scenario == 'gcstress15_pri1r2r' ||
+ scenario == 'longgc' ||
+ scenario == 'gcsimulator' ||
Constants.r2rJitStressScenarios.indexOf(scenario) != -1)
- // For windows, x86 runs by default
+
def arch = 'x86'
- def jit = 'ryujit'
- if (architecture == 'x86lb') {
- jit = 'legacy_backend'
- }
-
- if (scenario == 'default') {
- if (os == 'Windows_NT') {
+ def jit = 'legacy_backend'
+ switch (scenario) {
+ case 'default':
if (configuration == 'Checked') {
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} Build and Test")
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} Build and Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}.*")
}
- }
- else {
- // default trigger
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} Build", "(?i).*test\\W+${arch}\\W+${osGroup}.\\W+${jit}.*")
- }
- }
- else if (scenario == 'r2r') {
- if (os == 'Windows_NT') {
+ break
+ case 'r2r':
if (configuration == 'Release') {
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} R2R pri0 Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} R2R pri0 Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
- }
- }
- else if (scenario == 'pri1r2r') {
- if (os == 'Windows_NT') {
+ break
+ case 'pri1r2r':
if (configuration == 'Release') {
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} R2R pri1 Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} R2R pri1 Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
- }
- }
- else if (scenario == 'gcstress15_pri1r2r'){
- if (os == 'Windows_NT'){
- if (configuration == 'Release'){
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} GCStress 15 R2R pri1 Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ break
+ case 'gcstress15_pri1r2r':
+ if (configuration == 'Release') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} GCStress 15 R2R pri1 Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
- }
- }
- else if (scenario == 'r2r_jitstress1'){
- if (configuration == 'Release' || configuration == 'Checked') {
- if (os == 'Windows_NT'){
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstress1 R2R Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ break
+ case 'r2r_jitstress1':
+ if (configuration == 'Release' || configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstress1 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
- }
- }
- else if (scenario == 'r2r_jitstress2'){
- if (configuration == 'Release' || configuration == 'Checked') {
- if (os == 'Windows_NT'){
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstress2 R2R Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ break
+ case 'r2r_jitstress2':
+ if (configuration == 'Release' || configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstress2 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
- }
- }
- else if (scenario == 'r2r_jitstressregs1'){
- if (configuration == 'Release' || configuration == 'Checked') {
- if (os == 'Windows_NT'){
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregs1 R2R Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ break
+ case 'r2r_jitstressregs1':
+ if (configuration == 'Release' || configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregs1 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
- }
- }
- else if (scenario == 'r2r_jitstressregs2'){
- if (configuration == 'Release' || configuration == 'Checked') {
- if (os == 'Windows_NT'){
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregs2 R2R Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ break
+ case 'r2r_jitstressregs2':
+ if (configuration == 'Release' || configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregs2 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
- }
- }
- else if (scenario == 'r2r_jitstressregs3'){
- if (configuration == 'Release' || configuration == 'Checked') {
- if (os == 'Windows_NT'){
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregs3 R2R Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ break
+ case 'r2r_jitstressregs3':
+ if (configuration == 'Release' || configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregs3 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
- }
- }
- else if (scenario == 'r2r_jitstressregs4'){
- if (configuration == 'Release' || configuration == 'Checked') {
- if (os == 'Windows_NT'){
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregs4 R2R Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ break
+ case 'r2r_jitstressregs4':
+ if (configuration == 'Release' || configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregs4 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
- }
- }
- else if (scenario == 'r2r_jitstressregs8'){
- if (configuration == 'Release' || configuration == 'Checked') {
- if (os == 'Windows_NT'){
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregs8 R2R Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ break
+ case 'r2r_jitstressregs8':
+ if (configuration == 'Release' || configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregs8 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
- }
- }
- else if (scenario == 'r2r_jitstressregsx10'){
- if (configuration == 'Release' || configuration == 'Checked') {
- if (os == 'Windows_NT'){
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregsx10 R2R Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ break
+ case 'r2r_jitstressregsx10':
+ if (configuration == 'Release' || configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregsx10 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
- }
- }
- else if (scenario == 'r2r_jitstressregsx80'){
- if (configuration == 'Release' || configuration == 'Checked') {
- if (os == 'Windows_NT'){
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregsx80 R2R Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ break
+ case 'r2r_jitstressregsx80':
+ if (configuration == 'Release' || configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitstressregsx80 R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
- }
- }
- else if (scenario == 'r2r_jitminopts'){
- if (configuration == 'Release' || configuration == 'Checked') {
- if (os == 'Windows_NT'){
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitminopts R2R Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ break
+ case 'r2r_jitminopts':
+ if (configuration == 'Release' || configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitminopts R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
- }
- }
- else if (scenario == 'r2r_jitforcerelocs'){
- if (configuration == 'Release' || configuration == 'Checked') {
- if (os == 'Windows_NT'){
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitforcerelocs R2R Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ break
+ case 'r2r_jitforcerelocs':
+ if (configuration == 'Release' || configuration == 'Checked') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} jitforcerelocs R2R Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
- }
- }
- else if (scenario == 'longgc') {
- if (os == 'Windows_NT'){
- if (configuration == 'Release'){
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} Long-Running GC Build & Test", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ break
+ case 'longgc':
+ if (configuration == 'Release') {
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} Long-Running GC Build & Test",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
- }
- }
- else if (scenario == 'gcsimulator') {
- if (os == 'Windows_NT') {
+ break
+ case 'gcsimulator':
if (configuration == 'Release') {
- Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} GC Simulator", "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
+ Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${arch} ${jit} ${configuration} GC Simulator",
+ "(?i).*test\\W+${os}\\W+${arch}\\W+${jit}\\W+${configuration}\\W+${scenario}.*")
}
- }
+ break
+ default:
+ println("Unknown scenario: ${os} ${arch} ${jit} ${scenario}");
+ assert false
+ break
}
break
+ // editor brace matching: }
default:
println("Unknown architecture: ${architecture}");
assert false
@@ -1470,6 +1754,14 @@ combinedScenarios.each { scenario ->
os = 'Windows_NT'
}
+ // WinArm32 is only built for Debug and Release
+ if (os == 'Windows_NT' && architecture == 'arm')
+ {
+ if (configuration == 'Checked')
+ {
+ return
+ }
+ }
// If the OS is LinuxARMEmulator and arch is arm, set the isLinuxEmulatorBuild
// flag to true and reset the os to Ubuntu
// The isLinuxEmulatorBuild flag will be used at a later time to execute the right
@@ -1497,12 +1789,12 @@ combinedScenarios.each { scenario ->
}
break
case 'arm':
- // Only Ubuntu cross implemented
- if (os != 'Ubuntu') {
+ if ((os != 'Ubuntu') && (os != 'Windows_NT')) {
return
}
break
- case 'x86ryujit':
+ case 'x86':
+ case 'x86compatjit':
case 'x86lb':
// Skip non-windows
if (os != 'Windows_NT') {
@@ -1517,6 +1809,7 @@ combinedScenarios.each { scenario ->
assert false
break
}
+
// Skip scenarios (blanket skipping for jit stress modes, which are good most everywhere
// with checked builds
def enableCorefxTesting = false
@@ -1529,7 +1822,7 @@ combinedScenarios.each { scenario ->
// Since these are just execution time differences,
// skip platforms that don't execute the tests here (Windows_NT only)
- def isEnabledOS = os == 'Windows_NT' || (os == 'Ubuntu' && enableCorefxTesting)
+ def isEnabledOS = (os == 'Windows_NT') || (os == 'Ubuntu' && enableCorefxTesting)
if (!isEnabledOS || isBuildOnly) {
return
}
@@ -1543,17 +1836,22 @@ combinedScenarios.each { scenario ->
case 'x64':
// Everything implemented
break
- case 'x86ryujit':
+ case 'x86':
if (enableCorefxTesting) {
return
}
break
+ case 'x86compatjit':
+ case 'x86lb':
+ // No stress modes for compatjit.dll, legacyjit.dll.
+ // (There's no technical reason we couldn't allow these.)
+ return
default:
return
}
}
else {
- // If this is a r2r jitstress, jitstressregs, jitminopts or forcerelocs scenario
+ // If this is a r2r jitstress, jitstressregs, jitminopts, or forcerelocs scenario
// and configuration is not Checked, bail out.
if (configuration != 'Checked' && Constants.r2rJitStressScenarios.indexOf(scenario) != -1) {
return;
@@ -1587,6 +1885,17 @@ combinedScenarios.each { scenario ->
return
}
break
+ case 'jitdiff':
+ if (os != 'Windows_NT' && os != 'Ubuntu' && os != 'OSX') {
+ return
+ }
+ if (architecture != 'x64') {
+ return
+ }
+ if (configuration != 'Checked') {
+ return
+ }
+ break
case 'r2r':
// The r2r build isn't necessary except for Windows_NT. Non-Windows NT uses
// the default scenario build
@@ -1642,6 +1951,19 @@ combinedScenarios.each { scenario ->
return
}
break
+ case 'standalone_gc':
+ if (os != 'Windows_NT') {
+ return
+ }
+
+ if (architecture != 'x64') {
+ return
+ }
+
+ if (configuration != 'Release' && configuration != 'Checked') {
+ return
+ }
+ break
// We need Windows x64 Release bits for the code coverage build
case 'coverage':
if (os != 'Windows_NT') {
@@ -1698,21 +2020,29 @@ combinedScenarios.each { scenario ->
// Calculate the build steps, archival, and xunit results
switch (os) {
- case 'Windows_NT':
+ case 'Windows_NT': // editor brace matching: {
switch (architecture) {
case 'x64':
- case 'x86ryujit':
+ case 'x86':
+ case 'x86compatjit':
case 'x86lb':
def arch = architecture
- if (architecture == 'x86ryujit' || architecture == 'x86lb') {
+ def buildOpts = ''
+ if (architecture == 'x86compatjit') {
arch = 'x86'
+ buildOpts = 'compatjitcrossgen'
+ }
+ else if (architecture == 'x86lb') {
+ arch = 'x86'
+ buildOpts = 'legacyjitcrossgen'
}
if (Constants.jitStressModeScenarios.containsKey(scenario) ||
scenario == 'default' ||
scenario == 'r2r' ||
+ scenario == 'jitdiff' ||
Constants.r2rJitStressScenarios.indexOf(scenario) != -1) {
- buildOpts = enableCorefxTesting ? 'skiptests' : ''
+ buildOpts += enableCorefxTesting ? ' skiptests' : ''
buildCommands += "set __TestIntermediateDir=int&&build.cmd ${lowerConfiguration} ${arch} ${buildOpts}"
}
@@ -1723,19 +2053,23 @@ combinedScenarios.each { scenario ->
// 35 characters long.
else if (scenario == 'pri1' || scenario == 'pri1r2r' || scenario == 'gcstress15_pri1r2r'|| scenario == 'coverage') {
- buildCommands += "set __TestIntermediateDir=int&&build.cmd ${lowerConfiguration} ${arch} -priority=1"
+ buildCommands += "set __TestIntermediateDir=int&&build.cmd ${lowerConfiguration} ${arch} ${buildOpts} -priority=1"
}
else if (scenario == 'ilrt') {
// First do the build with skiptests and then build the tests with ilasm roundtrip
- buildCommands += "build.cmd ${lowerConfiguration} ${arch} skiptests"
+ buildCommands += "build.cmd ${lowerConfiguration} ${arch} ${buildOpts} skiptests"
buildCommands += "set __TestIntermediateDir=int&&build-test.cmd ${lowerConfiguration} ${arch} -ilasmroundtrip"
}
else if (isLongGc(scenario)) {
- buildCommands += "build.cmd ${lowerConfiguration} ${arch} skiptests"
+ buildCommands += "build.cmd ${lowerConfiguration} ${arch} ${buildOpts} skiptests"
buildCommands += "set __TestIntermediateDir=int&&build-test.cmd ${lowerConfiguration} ${arch}"
}
+ else if (scenario == 'standalone_gc') {
+ buildCommands += "build.cmd ${lowerConfiguration} ${arch} ${buildOpts} buildstandalonegc"
+ }
else if (scenario == 'formatting') {
buildCommands += "python -u tests\\scripts\\format.py -c %WORKSPACE% -o Windows_NT -a ${arch}"
+ Utilities.addArchival(newJob, "format.patch", "", true, false)
break
}
else {
@@ -1754,6 +2088,7 @@ combinedScenarios.each { scenario ->
def runjitstressregsStr = ''
def runjitmioptsStr = ''
def runjitforcerelocsStr = ''
+ def runjitdisasmStr = ''
def gcstressStr = ''
def runtestArguments = ''
def gcTestArguments = ''
@@ -1804,11 +2139,17 @@ combinedScenarios.each { scenario ->
gcstressStr = 'gcstresslevel 0xF'
}
+ if (scenario == 'jitdiff')
+ {
+ runjitdisasmStr = 'jitdisasm crossgen'
+ }
+
if (isLongGc(scenario)) {
gcTestArguments = "${scenario} sequential"
}
- runtestArguments = "${lowerConfiguration} ${arch} ${gcstressStr} ${crossgenStr} ${runcrossgentestsStr} ${runjitstressStr} ${runjitstressregsStr} ${runjitmioptsStr} ${runjitforcerelocsStr} ${gcTestArguments}"
+ runtestArguments = "${lowerConfiguration} ${arch} ${gcstressStr} ${crossgenStr} ${runcrossgentestsStr} ${runjitstressStr} ${runjitstressregsStr} ${runjitmioptsStr} ${runjitforcerelocsStr} ${runjitdisasmStr} ${gcTestArguments}"
+
if (Constants.jitStressModeScenarios.containsKey(scenario)) {
if (enableCorefxTesting) {
// Sync to corefx repo
@@ -1825,29 +2166,21 @@ combinedScenarios.each { scenario ->
}
else {
def stepScriptLocation = "%WORKSPACE%\\bin\\tests\\SetStressModes.bat"
-
- if (architecture == 'x86ryujit'){
- def x86Vars = ['COMPLUS_AltJit' : '*', 'COMPLUS_AltJitName' : 'protojit.dll', 'COMPLUS_NoGuiOnAssert' : '1']
- buildCommands += genStressModeScriptStep(os, scenario, Constants.jitStressModeScenarios[scenario] + x86Vars, stepScriptLocation)
- }
- else {
- buildCommands += genStressModeScriptStep(os, scenario, Constants.jitStressModeScenarios[scenario], stepScriptLocation)
- }
-
+ buildCommands += genStressModeScriptStep(os, scenario, Constants.jitStressModeScenarios[scenario], stepScriptLocation)
// Run tests with the
buildCommands += "tests\\runtest.cmd ${runtestArguments} TestEnv ${stepScriptLocation}"
}
}
- else if (architecture == 'x64') {
+ else if (architecture == 'x64' || architecture == 'x86') {
buildCommands += "tests\\runtest.cmd ${runtestArguments}"
}
- else if (architecture == 'x86ryujit') {
- def testEnvLocation = "%WORKSPACE%\\tests\\x86\\ryujit_x86_testenv.cmd"
-
- buildCommands += "tests\\runtest.cmd ${runtestArguments} TestEnv ${testEnvLocation}"
+ else if (architecture == 'x86compatjit') {
+ def testEnvLocation = "%WORKSPACE%\\tests\\x86\\compatjit_x86_testenv.cmd"
+ buildCommands += "tests\\runtest.cmd ${runtestArguments} Exclude0 x86_legacy_backend_issues.targets TestEnv ${testEnvLocation}"
}
else if (architecture == 'x86lb') {
- buildCommands += "tests\\runtest.cmd ${runtestArguments} Exclude0 x86_legacy_backend_issues.targets"
+ def testEnvLocation = "%WORKSPACE%\\tests\\x86\\legacyjit_x86_testenv.cmd"
+ buildCommands += "tests\\runtest.cmd ${runtestArguments} Exclude0 x86_legacy_backend_issues.targets TestEnv ${testEnvLocation}"
}
}
@@ -1857,16 +2190,24 @@ combinedScenarios.each { scenario ->
buildCommands += "build.cmd ${lowerConfiguration} ${arch} linuxmscorlib"
buildCommands += "build.cmd ${lowerConfiguration} ${arch} freebsdmscorlib"
buildCommands += "build.cmd ${lowerConfiguration} ${arch} osxmscorlib"
-
+
// Zip up the tests directory so that we don't use so much space/time copying
// 10s of thousands of files around.
buildCommands += "powershell -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('.\\bin\\tests\\${osGroup}.${arch}.${configuration}', '.\\bin\\tests\\tests.zip')\"";
-
- if (!Constants.jitStressModeScenarios.containsKey(scenario)) {
+
+ if (!Constants.jitStressModeScenarios.containsKey(scenario) && scenario != 'jitdiff') {
// For windows, pull full test results and test drops for x86/x64.
// No need to pull for stress mode scenarios (downstream builds use the default scenario)
Utilities.addArchival(newJob, "bin/Product/**,bin/tests/tests.zip")
}
+
+ if (scenario == 'jitdiff') {
+ // retrive jit-dasm output for base commit, and run jit-diff
+ if (!isBuildOnly) {
+ // if this is a build only job, we want to keep the default (build) artifacts for the flow job
+ Utilities.addArchival(newJob, "bin/tests/${osGroup}.${arch}.${configuration}/dasm/**")
+ }
+ }
if (!isBuildOnly) {
if (architecture == 'x64' || !isPR) {
@@ -1889,6 +2230,22 @@ combinedScenarios.each { scenario ->
}
break
+ case 'arm':
+ assert (scenario == 'default')
+
+ // Set time out
+ setTestJobTimeOut(newJob, scenario)
+
+ if ( lowerConfiguration == "debug" ) {
+ // For Debug builds, we will do a P1 test build
+ buildCommands += "set __TestIntermediateDir=int&&build.cmd ${lowerConfiguration} ${architecture} -priority=1"
+ }
+ else {
+ buildCommands += "set __TestIntermediateDir=int&&build.cmd ${lowerConfiguration} ${architecture}"
+ }
+ // Add archival.
+ Utilities.addArchival(newJob, "bin/Product/**")
+ break
case 'arm64':
assert (scenario == 'default') || (scenario == 'pri1r2r') || (scenario == 'gcstress0x3') || (scenario == 'gcstress0xc')
// Set time out
@@ -1901,8 +2258,8 @@ combinedScenarios.each { scenario ->
else {
buildCommands += "set __TestIntermediateDir=int&&build.cmd skiptests ${lowerConfiguration} ${architecture} toolset_dir C:\\ats2"
// Test build and run are launched together.
- buildCommands += "Z:\\arm64\\common\\scripts\\arm64PostLauncher.cmd %WORKSPACE% ${architecture} ${lowerConfiguration} ${scenario}"
- Utilities.addXUnitDotNETResults(newJob, 'bin/tests/testResults.xml')
+ buildCommands += "python tests\\scripts\\arm64_post_build.py -repo_root %WORKSPACE% -arch ${architecture} -build_type ${lowerConfiguration} -scenario ${scenario} -key_location C:\\tools\\key.txt"
+ //Utilities.addXUnitDotNETResults(newJob, 'bin/tests/testResults.xml')
}
// Add archival.
@@ -1914,8 +2271,10 @@ combinedScenarios.each { scenario ->
break
}
break
+ // editor brace matching: }
case 'Ubuntu':
case 'Ubuntu16.04':
+ case 'Ubuntu16.10':
case 'Debian8.4':
case 'OSX':
case 'FreeBSD':
@@ -1923,18 +2282,20 @@ combinedScenarios.each { scenario ->
case 'RHEL7.2':
case 'OpenSUSE13.2':
case 'OpenSUSE42.1':
- case 'Fedora23':
+ case 'Fedora23': // editor brace matching: {
switch (architecture) {
case 'x64':
- case 'x86ryujit':
+ case 'x86':
+ case 'x86compatjit':
case 'x86lb':
def arch = architecture
- if (architecture == 'x86ryujit' || architecture == 'x86lb') {
+ if (architecture == 'x86compatjit' || architecture == 'x86lb') {
arch = 'x86'
}
if (scenario == 'formatting') {
buildCommands += "python tests/scripts/format.py -c \${WORKSPACE} -o Linux -a ${arch}"
+ Utilities.addArchival(newJob, "format.patch", "", true, false)
break
}
@@ -2043,12 +2404,13 @@ combinedScenarios.each { scenario ->
break
}
break
+ // editor brace matching: }
default:
println("Unknown os: ${os}");
assert false
break
- }
-
+ } // os
+
newJob.with {
steps {
if (os == 'Windows_NT') {
@@ -2078,7 +2440,7 @@ combinedScenarios.each { scenario ->
latestSuccessful(true)
}
}
- copyArtifacts("${corefxFolder}/linuxarmemulator_cross_${lowerConfiguration}") {
+ copyArtifacts("${corefxFolder}/linuxarmemulator_softfp_cross_${lowerConfiguration}") {
includePatterns('bin/build.tar.gz')
buildSelector {
latestSuccessful(true)
@@ -2091,7 +2453,7 @@ combinedScenarios.each { scenario ->
}
}
}
- }
+ } // newJob.with
} // os
} // configuration
@@ -2160,6 +2522,10 @@ combinedScenarios.each { scenario ->
return
}
break
+ case 'jitdiff':
+ if (configuration != 'Checked') {
+ return;
+ }
case 'r2r':
//Skip configs that aren't Checked or Release (so just Debug, for now)
if (configuration != 'Checked' && configuration != 'Release') {
@@ -2196,6 +2562,10 @@ combinedScenarios.each { scenario ->
return
}
break
+ case 'standalone_gc':
+ if (configuration != 'Release' && configuration != 'Checked') {
+ return
+ }
case 'coverage':
//We only want Ubuntu Release for coverage
if (os != 'Ubuntu') {
@@ -2273,6 +2643,7 @@ combinedScenarios.each { scenario ->
def runjitstressregsStr = ''
def runjitmioptsStr = ''
def runjitforcerelocsStr = ''
+ def runjitdisasmStr = ''
def gcstressStr = ''
if (scenario == 'r2r' ||
@@ -2321,6 +2692,11 @@ combinedScenarios.each { scenario ->
gcstressStr = '--gcstresslevel=0xF'
}
+ if (scenario == 'jitdiff')
+ {
+ runjitdisasmStr = '--jitdisasm --crossgen'
+ }
+
if (isLongGc(scenario)) {
// Long GC tests behave very poorly when they are not
// the only test running (many of them allocate until OOM).
@@ -2486,7 +2862,7 @@ combinedScenarios.each { scenario ->
--coreFxBinDir=\"\${WORKSPACE}/bin/${osGroup}.AnyCPU.Release;\${WORKSPACE}/bin/Unix.AnyCPU.Release;\${WORKSPACE}/bin/AnyOS.AnyCPU.Release\" \\
--coreFxNativeBinDir=\"\${WORKSPACE}/bin/${osGroup}.${architecture}.Release\" \\
--limitedDumpGeneration \\
- ${testEnvOpt} ${serverGCString} ${gcstressStr} ${crossgenStr} ${runcrossgentestsStr} ${runjitstressStr} ${runjitstressregsStr} ${runjitmioptsStr} ${runjitforcerelocsStr} ${sequentialString} ${playlistString}""")
+ ${testEnvOpt} ${serverGCString} ${gcstressStr} ${crossgenStr} ${runcrossgentestsStr} ${runjitstressStr} ${runjitstressregsStr} ${runjitmioptsStr} ${runjitforcerelocsStr} ${runjitdisasmStr} ${sequentialString} ${playlistString}""")
}
}
}
@@ -2498,6 +2874,10 @@ combinedScenarios.each { scenario ->
// addEmailPublisher(newJob, 'clrcoverage@microsoft.com')
}
+ if (scenario == 'jitdiff') {
+ Utilities.addArchival(newJob, "bin/tests/${osGroup}.${architecture}.${configuration}/dasm/**")
+ }
+
// Experimental: If on Ubuntu 14.04, then attempt to pull in crash dump links
if (os in ['Ubuntu']) {
SummaryBuilder summaries = new SummaryBuilder()
@@ -2566,4 +2946,4 @@ JobReport.Report.generateJobReport(out)
// Make the call to generate the help job
Utilities.createHelperJob(this, project, branch,
"Welcome to the ${project} Repository", // This is prepended to the help message
- "Have a nice day!") // This is appended to the help message. You might put known issues here. \ No newline at end of file
+ "Have a nice day!") // This is appended to the help message. You might put known issues here.
diff --git a/perf.groovy b/perf.groovy
index a95b68142c..d7eb783cb9 100644
--- a/perf.groovy
+++ b/perf.groovy
@@ -4,10 +4,11 @@ import jobs.generation.*;
def project = GithubProject
def branch = GithubBranchName
-def projectFolder = Utilities.getFolderName(project) + '/' + Utilities.getFolderName(branch)
+def projectName = Utilities.getFolderName(project)
+def projectFolder = projectName + '/' + Utilities.getFolderName(branch)
def static getOSGroup(def os) {
- def osGroupMap = ['Ubuntu':'Linux',
+ def osGroupMap = ['Ubuntu14.04':'Linux',
'RHEL7.2': 'Linux',
'Ubuntu16.04': 'Linux',
'Debian8.4':'Linux',
@@ -19,7 +20,7 @@ def static getOSGroup(def os) {
'OpenSUSE13.2': 'Linux',
'OpenSUSE42.1': 'Linux',
'LinuxARMEmulator': 'Linux']
- def osGroup = osGroupMap.get(os, null)
+ def osGroup = osGroupMap.get(os, null)
assert osGroup != null : "Could not find os group for ${os}"
return osGroupMap[os]
}
@@ -27,9 +28,6 @@ def static getOSGroup(def os) {
[true, false].each { isPR ->
['Windows_NT'].each { os ->
['x64'].each { architecture ->
- def configuration = 'Release'
- def runType = isPR ? 'private' : 'rolling'
- def benchViewName = isPR ? 'coreclr private %ghprbPullTitle%' : 'coreclr rolling %GIT_BRANCH_WITHOUT_ORIGIN% %GIT_COMMIT%'
def newJob = job(Utilities.getFullJobName(project, "perf_perflab_${os}", isPR)) {
// Set the label.
label('windows_clr_perf')
@@ -39,20 +37,32 @@ def static getOSGroup(def os) {
}
}
+ if (isPR)
+ {
+ parameters
+ {
+ stringParam('BenchviewCommitName', '%ghprbPullTitle%', 'The name that you will be used to build the full title of a run in Benchview. The final name will be of the form <branch> private BenchviewCommitName')
+ }
+ }
+ def configuration = 'Release'
+ def runType = isPR ? 'private' : 'rolling'
+ def benchViewName = isPR ? 'coreclr private %BenchviewCommitName%' : 'coreclr rolling %GIT_BRANCH_WITHOUT_ORIGIN% %GIT_COMMIT%'
+
steps {
// Batch
-
- batchFile("C:\\Tools\\nuget.exe install Microsoft.BenchView.JSONFormat -Source http://benchviewtestfeed.azurewebsites.net/nuget -OutputDirectory C:\\tools -Prerelease -ExcludeVersion")
+
+ batchFile("if exist \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\" rmdir /s /q \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\"")
+ batchFile("C:\\Tools\\nuget.exe install Microsoft.BenchView.JSONFormat -Source http://benchviewtestfeed.azurewebsites.net/nuget -OutputDirectory \"%WORKSPACE%\" -Prerelease -ExcludeVersion")
//Do this here to remove the origin but at the front of the branch name as this is a problem for BenchView
//we have to do it all as one statement because cmd is called each time and we lose the set environment variable
batchFile("if [%GIT_BRANCH:~0,7%] == [origin/] (set GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH:origin/=%) else (set GIT_BRANCH_WITHOUT_ORIGIN=%GIT_BRANCH%)\n" +
- "py C:\\tools\\Microsoft.BenchView.JSONFormat\\tools\\submission-metadata.py --name " + "\"" + benchViewName + "\"" + " --user " + "\"dotnet-bot@microsoft.com\"\n" +
- "py C:\\tools\\Microsoft.BenchView.JSONFormat\\tools\\build.py git --branch %GIT_BRANCH_WITHOUT_ORIGIN% --type " + runType)
- batchFile("py C:\\tools\\Microsoft.BenchView.JSONFormat\\tools\\machinedata.py")
+ "py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\submission-metadata.py\" --name " + "\"" + benchViewName + "\"" + " --user " + "\"dotnet-bot@microsoft.com\"\n" +
+ "py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\build.py\" git --branch %GIT_BRANCH_WITHOUT_ORIGIN% --type " + runType)
+ batchFile("py \"%WORKSPACE%\\Microsoft.BenchView.JSONFormat\\tools\\machinedata.py\"")
batchFile("set __TestIntermediateDir=int&&build.cmd release ${architecture}")
batchFile("tests\\runtest.cmd release ${architecture} GenerateLayoutOnly")
- batchFile("tests\\scripts\\run-xunit-perf.cmd -arch ${architecture} -configuration ${configuration} -testBinLoc bin\\tests\\Windows_NT.${architecture}.Release\\performance\\perflab\\Perflab -library -uploadToBenchview C:\\Tools\\Microsoft.Benchview.JSONFormat\\tools -runtype " + runType)
- batchFile("tests\\scripts\\run-xunit-perf.cmd -arch ${architecture} -configuration ${configuration} -testBinLoc bin\\tests\\Windows_NT.${architecture}.Release\\Jit\\Performance\\CodeQuality -uploadToBenchview C:\\Tools\\Microsoft.Benchview.JSONFormat\\tools -runtype " + runType)
+ batchFile("tests\\scripts\\run-xunit-perf.cmd -arch ${architecture} -configuration ${configuration} -testBinLoc bin\\tests\\Windows_NT.${architecture}.Release\\performance\\perflab\\Perflab -library -uploadToBenchview \"%WORKSPACE%\\Microsoft.Benchview.JSONFormat\\tools\" -runtype " + runType)
+ batchFile("tests\\scripts\\run-xunit-perf.cmd -arch ${architecture} -configuration ${configuration} -testBinLoc bin\\tests\\Windows_NT.${architecture}.Release\\Jit\\Performance\\CodeQuality -uploadToBenchview \"%WORKSPACE%\\Microsoft.Benchview.JSONFormat\\tools\" -runtype " + runType)
}
}
@@ -63,7 +73,7 @@ def static getOSGroup(def os) {
Utilities.addArchival(newJob, archiveSettings)
Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
-
+
if (isPR) {
TriggerBuilder builder = TriggerBuilder.triggerOnPullRequest()
builder.setGithubContext("${os} CoreCLR Perf Tests")
@@ -83,72 +93,67 @@ def static getOSGroup(def os) {
// Create the Linux/OSX/CentOS coreclr test leg for debug and release and each scenario
[true, false].each { isPR ->
- ['Ubuntu'].each { os ->
- def osGroup = getOSGroup(os)
- def architecture = 'x64'
- def configuration = 'Checked'
- def newJob = job(Utilities.getFullJobName(project, "perf_${osGroup}", isPR)) {
- parameters {
- stringParam('CORECLR_WINDOWS_BUILD', '', 'Build number to copy CoreCLR windows test binaries from')
- stringParam('CORECLR_BUILD', '', "Build number to copy CoreCLR ${osGroup} binaries from")
- }
-
+ ['Ubuntu14.04'].each { os ->
+ def newJob = job(Utilities.getFullJobName(project, "perf_${os}", isPR)) {
+
+ label('linux_clr_perf')
+ wrappers {
+ credentialsBinding {
+ string('BV_UPLOAD_SAS_TOKEN', 'CoreCLR Perf BenchView Sas')
+ }
+ }
+
+ if (isPR)
+ {
+ parameters
+ {
+ stringParam('BenchviewCommitName', '\$ghprbPullTitle', 'The name that you will be used to build the full title of a run in Benchview. The final name will be of the form <branch> private BenchviewCommitName')
+ }
+ }
+ def osGroup = getOSGroup(os)
+ def architecture = 'x64'
+ def configuration = 'Release'
+ def runType = isPR ? 'private' : 'rolling'
+ def benchViewName = isPR ? 'coreclr private \$BenchviewCommitName' : 'coreclr rolling \$GIT_BRANCH_WITHOUT_ORIGIN \$GIT_COMMIT'
+
steps {
- // Set up the copies
- // Coreclr build containing the tests and mscorlib
- copyArtifacts("dotnet_coreclr/master/x64_checked_windows_nt_pri1_bld") {
- excludePatterns('**/testResults.xml', '**/*.ni.dll')
- buildSelector {
- buildNumber('${CORECLR_WINDOWS_BUILD}')
- }
- }
-
- // Coreclr build we are trying to test
- copyArtifacts("dotnet_coreclr/master/checked_ubuntu") {
- excludePatterns('**/testResults.xml', '**/*.ni.dll')
- buildSelector {
- buildNumber('${CORECLR_BUILD}')
- }
- }
-
- def corefxFolder = Utilities.getFolderName('dotnet/corefx') + '/' + 'master'
-
- // Corefx components. We now have full stack builds on all distros we test here, so we can copy straight from CoreFX jobs.
- def osJobName = (os == 'Ubuntu') ? 'ubuntu14.04' : os.toLowerCase()
- copyArtifacts("${corefxFolder}/${osJobName}_release") {
- includePatterns('bin/build.tar.gz')
- buildSelector {
- latestSuccessful(true)
- }
- }
-
- // Unpack the corefx binaries
- shell("tar -xf ./bin/build.tar.gz")
-
- // Unzip the tests first. Exit with 0
- shell("unzip -q -o ./bin/tests/tests.zip -d ./bin/tests/Windows_NT.${architecture}.${configuration} || exit 0")
-
- // Execute the tests
- shell('./init-tools.sh')
-
- shell("""sudo bash ./tests/scripts/run-xunit-perf.sh \\
+ shell("bash ./tests/scripts/perf-prep.sh")
+ shell("./init-tools.sh")
+ shell("./build.sh ${architecture} ${configuration}")
+ shell("GIT_BRANCH_WITHOUT_ORIGIN=\$(echo \$GIT_BRANCH | sed \"s/[^/]*\\/\\(.*\\)/\\1 /\")\n" +
+ "python3.5 \"\${WORKSPACE}/tests/scripts/Microsoft.BenchView.JSONFormat/tools/submission-metadata.py\" --name " + "\"" + benchViewName + "\"" + " --user " + "\"dotnet-bot@microsoft.com\"\n" +
+ "python3.5 \"\${WORKSPACE}/tests/scripts/Microsoft.BenchView.JSONFormat/tools/build.py\" git --branch \$GIT_BRANCH_WITHOUT_ORIGIN --type " + runType)
+ shell("""sudo -E bash ./tests/scripts/run-xunit-perf.sh \\
--testRootDir=\"\${WORKSPACE}/bin/tests/Windows_NT.${architecture}.${configuration}\" \\
--testNativeBinDir=\"\${WORKSPACE}/bin/obj/${osGroup}.${architecture}.${configuration}/tests\" \\
--coreClrBinDir=\"\${WORKSPACE}/bin/Product/${osGroup}.${architecture}.${configuration}\" \\
--mscorlibDir=\"\${WORKSPACE}/bin/Product/${osGroup}.${architecture}.${configuration}\" \\
- --coreFxBinDir=\"\${WORKSPACE}/bin/${osGroup}.AnyCPU.Release;\${WORKSPACE}/bin/Unix.AnyCPU.Release;\${WORKSPACE}/bin/AnyOS.AnyCPU.Release\" \\
- --coreFxNativeBinDir=\"\${WORKSPACE}/bin/${osGroup}.${architecture}.Release\"""")
+ --coreFxBinDir=\"\${WORKSPACE}/corefx/bin/${osGroup}.AnyCPU.${configuration};\${WORKSPACE}/corefx/bin/Unix.AnyCPU.${configuration};\${WORKSPACE}/corefx/bin/AnyOS.AnyCPU.${configuration}\" \\
+ --coreFxNativeBinDir=\"\${WORKSPACE}/corefx/bin/${osGroup}.${architecture}.${configuration}\" \\
+ --runType=\"${runType}\" \\
+ --benchViewOS=\"${os}\" \\
+ --uploadToBenchview""")
}
}
- Utilities.setMachineAffinity(newJob, os, 'latest-or-auto') // Just run against Linux VM's for now.
-
// Save machinedata.json to /artifact/bin/ Jenkins dir
def archiveSettings = new ArchivalSettings()
- archiveSettings.addFiles('perf-*.xml')
+ archiveSettings.addFiles('sandbox/perf-*.xml')
+ archiveSettings.addFiles('machinedata.json')
Utilities.addArchival(newJob, archiveSettings)
Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
+
+ // For perf, we need to keep the run results longer
+ newJob.with {
+ // Enable the log rotator
+ logRotator {
+ artifactDaysToKeep(7)
+ daysToKeep(300)
+ artifactNumToKeep(25)
+ numToKeep(1000)
+ }
+ }
if (isPR) {
TriggerBuilder builder = TriggerBuilder.triggerOnPullRequest()
builder.setGithubContext("${os} Perf Tests")
@@ -163,4 +168,4 @@ def static getOSGroup(def os) {
builder.emitTrigger(newJob)
}
} // os
-} // isPR \ No newline at end of file
+} // isPR
diff --git a/pgosupport.cmake b/pgosupport.cmake
index 27fe13df6d..015eed6a0f 100644
--- a/pgosupport.cmake
+++ b/pgosupport.cmake
@@ -13,7 +13,7 @@ function(add_pgo TargetName)
endif(WIN32)
file(TO_NATIVE_PATH
- "${CLR_CMAKE_PACKAGES_DIR}/${CLR_CMAKE_OPTDATA_PACKAGEWITHRID}/${CLR_CMAKE_OPTDATA_VERSION}/data/${ProfileFileName}"
+ "${CLR_CMAKE_PACKAGES_DIR}/Microsoft.DotNet.OptimizationData.Coreclr/${CLR_CMAKE_TARGET_OS}.${CLR_CMAKE_TARGET_ARCH}/${ProfileFileName}"
ProfilePath
)
@@ -37,18 +37,6 @@ function(add_pgo TargetName)
endforeach(ConfigType)
endfunction(add_pgo)
-set(CLR_CMAKE_OPTDATA_PACKAGEID "optimization.PGO.CoreCLR")
-set(CLR_CMAKE_OPTDATA_PACKAGEWITHRID "optimization.${CLR_CMAKE_TARGET_OS}-${CLR_CMAKE_TARGET_ARCH}.PGO.CoreCLR")
-
-# Parse optdata package version from project.json
-file(TO_NATIVE_PATH "${CMAKE_SOURCE_DIR}/extract-from-json.py" ExtractFromJsonScript)
-file(TO_NATIVE_PATH "${CMAKE_SOURCE_DIR}/src/.nuget/optdata/project.json" OptDataProjectJsonPath)
-execute_process(
- COMMAND python "${ExtractFromJsonScript}" -rf "${OptDataProjectJsonPath}" dependencies "${CLR_CMAKE_OPTDATA_PACKAGEID}"
- OUTPUT_VARIABLE CLR_CMAKE_OPTDATA_VERSION
- OUTPUT_STRIP_TRAILING_WHITESPACE
-)
-
if(WIN32)
if(CLR_CMAKE_PGO_INSTRUMENT)
# Instrumented PGO binaries on Windows introduce an additional runtime dependency, pgort<ver>.dll.
diff --git a/publish-packages.cmd b/publish-packages.cmd
index 5831d29cc2..d23ff2373f 100644
--- a/publish-packages.cmd
+++ b/publish-packages.cmd
@@ -1,4 +1,4 @@
-@if "%_echo%" neq "on" echo off
+@if not defined _echo @echo off
setlocal EnableDelayedExpansion
if /I [%1] == [-?] goto Usage
@@ -18,6 +18,8 @@ echo -AzureAccount="account name"
echo -AzureToken="access token"
echo -BuildType="Configuration"
echo -BuildArch="Architecture"
+echo To specify the name of the container to publish into, use the following property:
+echo -Container="container name"
echo Architecture can be x64, x86, arm, or arm64
echo Configuration can be Release, Debug, or Checked
exit /b \ No newline at end of file
diff --git a/publish-packages.sh b/publish-packages.sh
index 8170419fb5..d5d4caa524 100755
--- a/publish-packages.sh
+++ b/publish-packages.sh
@@ -8,6 +8,8 @@ usage()
echo " -AzureToken=\"access token\""
echo " -BuildType=\"Configuration\""
echo " -BuildArch=\"Architecture\""
+ echo "To specify the name of the container to publish into, use the following property:"
+ echo " -Container=\"container name\""
echo "Configuration can be Release, Checked, or Debug"
echo "Architecture can be x64, x86, arm, or arm64"
exit 1
@@ -16,6 +18,7 @@ usage()
working_tree_root="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
$working_tree_root/run.sh publish-packages -BuildOS $*
+$working_tree_root/run.sh publish-packages -BuildOS -distroRid -PublishTestNativeBins $*
if [ $? -ne 0 ]
then
echo "ERROR: An error occurred while publishing packages; see $working_tree_root/publish-packages.log for more details. There may have been networking problems, so please try again in a few minutes."
diff --git a/run.cmd b/run.cmd
index 3647198d3d..6c761b6b82 100644
--- a/run.cmd
+++ b/run.cmd
@@ -1,4 +1,4 @@
-@if "%_echo%" neq "on" echo off
+@if not defined _echo @echo off
setlocal
if not defined VisualStudioVersion (
@@ -30,10 +30,10 @@ if NOT [%ERRORLEVEL%]==[0] (
set _toolRuntime=%~dp0Tools
set _dotnet=%_toolRuntime%\dotnetcli\dotnet.exe
-echo Running: %_dotnet% %_toolRuntime%\run.exe %*
-call %_dotnet% %_toolRuntime%\run.exe %*
+echo Running: %_dotnet% %_toolRuntime%\run.exe %~dp0config.json %*
+call %_dotnet% %_toolRuntime%\run.exe %~dp0config.json %*
if NOT [%ERRORLEVEL%]==[0] (
exit /b 1
)
-exit /b 0 \ No newline at end of file
+exit /b 0
diff --git a/run.sh b/run.sh
index 1c9299ae17..bd6a68f2bb 100755
--- a/run.sh
+++ b/run.sh
@@ -8,8 +8,8 @@ $working_tree_root/init-tools.sh
toolRuntime=$working_tree_root/Tools
dotnet=$toolRuntime/dotnetcli/dotnet
-echo "Running: $dotnet $toolRuntime/run.exe $*"
-$dotnet $toolRuntime/run.exe $*
+echo "Running: $dotnet $toolRuntime/run.exe $working_tree_root/config.json $*"
+$dotnet $toolRuntime/run.exe $working_tree_root/config.json $*
if [ $? -ne 0 ]
then
echo "ERROR: An error occured in $dotnet $toolRuntime/run $#. Check $# logs under $working_tree_root."
diff --git a/src/.gitmirrorselective b/src/.gitmirrorselective
new file mode 100644
index 0000000000..94b143d83a
--- /dev/null
+++ b/src/.gitmirrorselective
@@ -0,0 +1,2 @@
+jit
+ToolBox \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.ILAsm/Microsoft.NETCore.ILAsm.builds b/src/.nuget/Microsoft.NETCore.ILAsm/Microsoft.NETCore.ILAsm.builds
index 4cc7e101dd..e568ca57f5 100644
--- a/src/.nuget/Microsoft.NETCore.ILAsm/Microsoft.NETCore.ILAsm.builds
+++ b/src/.nuget/Microsoft.NETCore.ILAsm/Microsoft.NETCore.ILAsm.builds
@@ -27,6 +27,10 @@
<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>
@@ -55,14 +59,26 @@
<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="'$(TargetsOSX)' == 'true'" Include="osx/Microsoft.NETCore.ILAsm.pkgproj">
<OSGroup>OSX</OSGroup>
<Platform>amd64</Platform>
diff --git a/src/.nuget/Microsoft.NETCore.ILAsm/Microsoft.NETCore.ILAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILAsm/Microsoft.NETCore.ILAsm.pkgproj
index d2cc6d3a96..c0b2134610 100644
--- a/src/.nuget/Microsoft.NETCore.ILAsm/Microsoft.NETCore.ILAsm.pkgproj
+++ b/src/.nuget/Microsoft.NETCore.ILAsm/Microsoft.NETCore.ILAsm.pkgproj
@@ -22,6 +22,9 @@
<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>
@@ -43,15 +46,24 @@
<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="osx\Microsoft.NETCore.ILAsm.pkgproj">
<Platform>amd64</Platform>
</ProjectReference>
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
+</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
new file mode 100644
index 0000000000..41a5b4c301
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.ILAsm/alpine/3.4.3/Microsoft.NETCore.ILAsm.pkgproj
@@ -0,0 +1,29 @@
+<?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/linux/Microsoft.NETCore.ILAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILAsm/linux/Microsoft.NETCore.ILAsm.pkgproj
new file mode 100644
index 0000000000..ce3bf6320e
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.ILAsm/linux/Microsoft.NETCore.ILAsm.pkgproj
@@ -0,0 +1,29 @@
+<?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/ubuntu/14.04/Microsoft.NETCore.ILAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILAsm/ubuntu/14.04/Microsoft.NETCore.ILAsm.pkgproj
index 0864a65790..cacadc78b1 100644
--- 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
@@ -4,8 +4,8 @@
<PropertyGroup>
<SkipPackageFileCheck>true</SkipPackageFileCheck>
<PackageTargetRuntime>ubuntu.14.04-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
+ <!-- build for x64, arm -->
+ <PackagePlatforms>x64;arm;</PackagePlatforms>
</PropertyGroup>
<ItemGroup>
<NativeSplittableBinary Include="$(BinDir)ilasm" />
@@ -26,4 +26,4 @@
</File>
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
+</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
index b48290bed1..818495e6e2 100644
--- 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
@@ -4,8 +4,8 @@
<PropertyGroup>
<SkipPackageFileCheck>true</SkipPackageFileCheck>
<PackageTargetRuntime>ubuntu.16.04-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
+ <!-- build for x64, arm -->
+ <PackagePlatforms>x64;arm;</PackagePlatforms>
</PropertyGroup>
<ItemGroup>
<NativeSplittableBinary Include="$(BinDir)ilasm" />
@@ -26,4 +26,4 @@
</File>
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.ILDAsm/Microsoft.NETCore.ILDAsm.builds b/src/.nuget/Microsoft.NETCore.ILDAsm/Microsoft.NETCore.ILDAsm.builds
index e7ae8e2ebc..5939fdaf6e 100644
--- a/src/.nuget/Microsoft.NETCore.ILDAsm/Microsoft.NETCore.ILDAsm.builds
+++ b/src/.nuget/Microsoft.NETCore.ILDAsm/Microsoft.NETCore.ILDAsm.builds
@@ -27,6 +27,10 @@
<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>
@@ -55,14 +59,26 @@
<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="'$(TargetsOSX)' == 'true'" Include="osx/Microsoft.NETCore.ILDAsm.pkgproj">
<OSGroup>OSX</OSGroup>
<Platform>amd64</Platform>
diff --git a/src/.nuget/Microsoft.NETCore.ILDAsm/Microsoft.NETCore.ILDAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILDAsm/Microsoft.NETCore.ILDAsm.pkgproj
index 945bef972f..47683ef0a3 100644
--- a/src/.nuget/Microsoft.NETCore.ILDAsm/Microsoft.NETCore.ILDAsm.pkgproj
+++ b/src/.nuget/Microsoft.NETCore.ILDAsm/Microsoft.NETCore.ILDAsm.pkgproj
@@ -22,6 +22,9 @@
<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>
@@ -43,15 +46,24 @@
<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="osx\Microsoft.NETCore.ILDAsm.pkgproj">
<Platform>amd64</Platform>
</ProjectReference>
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
+</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
new file mode 100644
index 0000000000..b27fe08767
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.ILDAsm/alpine/3.4.3/Microsoft.NETCore.ILDAsm.pkgproj
@@ -0,0 +1,29 @@
+<?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/linux/Microsoft.NETCore.ILDAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILDAsm/linux/Microsoft.NETCore.ILDAsm.pkgproj
new file mode 100644
index 0000000000..7a7f82ddd5
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.ILDAsm/linux/Microsoft.NETCore.ILDAsm.pkgproj
@@ -0,0 +1,29 @@
+<?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/ubuntu/14.04/Microsoft.NETCore.ILDAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILDAsm/ubuntu/14.04/Microsoft.NETCore.ILDAsm.pkgproj
index e5bdb5122d..e087645962 100644
--- 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
@@ -4,8 +4,8 @@
<PropertyGroup>
<SkipPackageFileCheck>true</SkipPackageFileCheck>
<PackageTargetRuntime>ubuntu.14.04-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
+ <!-- build for x64, arm -->
+ <PackagePlatforms>x64;arm;</PackagePlatforms>
</PropertyGroup>
<ItemGroup>
<NativeSplittableBinary Include="$(BinDir)ildasm" />
@@ -26,4 +26,4 @@
</File>
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
+</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
index b20c9c9969..776e59ba16 100644
--- 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
@@ -4,8 +4,8 @@
<PropertyGroup>
<SkipPackageFileCheck>true</SkipPackageFileCheck>
<PackageTargetRuntime>ubuntu.16.04-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
+ <!-- build for x64, arm -->
+ <PackagePlatforms>x64;arm;</PackagePlatforms>
</PropertyGroup>
<ItemGroup>
<NativeSplittableBinary Include="$(BinDir)ildasm" />
@@ -26,4 +26,4 @@
</File>
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Jit/Microsoft.NETCore.Jit.builds b/src/.nuget/Microsoft.NETCore.Jit/Microsoft.NETCore.Jit.builds
index 9095196d78..61c690ebb1 100644
--- a/src/.nuget/Microsoft.NETCore.Jit/Microsoft.NETCore.Jit.builds
+++ b/src/.nuget/Microsoft.NETCore.Jit/Microsoft.NETCore.Jit.builds
@@ -27,6 +27,10 @@
<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>
@@ -55,14 +59,26 @@
<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="'$(TargetsOSX)' == 'true'" Include="osx/Microsoft.NETCore.Jit.pkgproj">
<OSGroup>OSX</OSGroup>
<Platform>amd64</Platform>
diff --git a/src/.nuget/Microsoft.NETCore.Jit/Microsoft.NETCore.Jit.pkgproj b/src/.nuget/Microsoft.NETCore.Jit/Microsoft.NETCore.Jit.pkgproj
index a6a2c194a0..bcd4e4232f 100644
--- a/src/.nuget/Microsoft.NETCore.Jit/Microsoft.NETCore.Jit.pkgproj
+++ b/src/.nuget/Microsoft.NETCore.Jit/Microsoft.NETCore.Jit.pkgproj
@@ -21,6 +21,9 @@
<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>
@@ -42,15 +45,24 @@
<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="osx\Microsoft.NETCore.Jit.pkgproj">
<Platform>amd64</Platform>
</ProjectReference>
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
+</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
new file mode 100644
index 0000000000..96851ff3ac
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.Jit/alpine/3.4.3/Microsoft.NETCore.Jit.pkgproj
@@ -0,0 +1,29 @@
+<?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/linux/Microsoft.NETCore.Jit.pkgproj b/src/.nuget/Microsoft.NETCore.Jit/linux/Microsoft.NETCore.Jit.pkgproj
new file mode 100644
index 0000000000..541b81e4ab
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.Jit/linux/Microsoft.NETCore.Jit.pkgproj
@@ -0,0 +1,29 @@
+<?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/ubuntu/14.04/Microsoft.NETCore.Jit.pkgproj b/src/.nuget/Microsoft.NETCore.Jit/ubuntu/14.04/Microsoft.NETCore.Jit.pkgproj
index e6775dabff..50d343f977 100644
--- 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
@@ -4,8 +4,8 @@
<PropertyGroup>
<SkipPackageFileCheck>true</SkipPackageFileCheck>
<PackageTargetRuntime>ubuntu.14.04-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
+ <!-- build for x64, arm -->
+ <PackagePlatforms>x64;arm;</PackagePlatforms>
</PropertyGroup>
<ItemGroup>
<NativeSplittableBinary Include="$(BinDir)libclrjit.so" />
@@ -26,4 +26,4 @@
</File>
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
+</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
index dc59c2a8ad..e57b7c51d5 100644
--- 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
@@ -4,8 +4,8 @@
<PropertyGroup>
<SkipPackageFileCheck>true</SkipPackageFileCheck>
<PackageTargetRuntime>ubuntu.16.04-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
+ <!-- build for x64, arm -->
+ <PackagePlatforms>x64;arm;</PackagePlatforms>
</PropertyGroup>
<ItemGroup>
<NativeSplittableBinary Include="$(BinDir)libclrjit.so" />
@@ -26,4 +26,4 @@
</File>
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Jit/win/Microsoft.NETCore.Jit.pkgproj b/src/.nuget/Microsoft.NETCore.Jit/win/Microsoft.NETCore.Jit.pkgproj
index 0a43ac4ceb..66106c30dc 100644
--- a/src/.nuget/Microsoft.NETCore.Jit/win/Microsoft.NETCore.Jit.pkgproj
+++ b/src/.nuget/Microsoft.NETCore.Jit/win/Microsoft.NETCore.Jit.pkgproj
@@ -8,6 +8,7 @@
</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>
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 341ec28d3f..c7bfdc3b04 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
@@ -6,7 +6,6 @@
<!-- 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">
@@ -27,6 +26,10 @@
<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>
@@ -55,14 +58,26 @@
<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="'$(TargetsOSX)' == 'true'" Include="osx/Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
<OSGroup>OSX</OSGroup>
<Platform>amd64</Platform>
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 65adcfe52c..a1405d5fff 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
@@ -9,18 +9,6 @@
<IncludeRuntimeJson>true</IncludeRuntimeJson>
</PropertyGroup>
<ItemGroup>
- <!-- ARM32_TODO: Clean this up.
- Declare a runtime dependency on the win8-arm CoreCLR built using the TFS builds
- -->
- <RuntimeDependency Include="runtime.win8-arm.Microsoft.NETCore.Runtime.CoreCLR">
- <TargetRuntime>win8-arm</TargetRuntime>
- <Version>$(RuntimeWin8ArmMicrosoftNETCoreRuntimeCoreCLRPackageVersion)</Version>
- </RuntimeDependency>
- <!-- ApiSets are only applicable for Windows.
- Despite the unconditioned package dependency it is constrained by runtime IDs within it's own package -->
- <Dependency Include="Microsoft.NETCore.Windows.ApiSets">
- <Version>$(MicrosoftNETCoreWindowsApiSetsPackageVersion)</Version>
- </Dependency>
<ProjectReference Include="..\Microsoft.NETCore.Jit\Microsoft.NETCore.Jit.pkgproj" />
<ProjectReference Include="win\Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
<Platform>amd64</Platform>
@@ -31,6 +19,12 @@
<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>
@@ -52,15 +46,24 @@
<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="osx\Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
<Platform>amd64</Platform>
</ProjectReference>
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
+</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
new file mode 100644
index 0000000000..c779349b7c
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/alpine/3.4.3/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
@@ -0,0 +1,56 @@
+<?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/linux/Microsoft.NETCore.Runtime.CoreCLR.pkgproj b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/linux/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
new file mode 100644
index 0000000000..31e719601d
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/linux/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
@@ -0,0 +1,56 @@
+<?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/ubuntu/14.04/Microsoft.NETCore.Runtime.CoreCLR.pkgproj b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/ubuntu/14.04/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
index 4b1f151f1d..86cb61a264 100644
--- 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
@@ -4,12 +4,12 @@
<PropertyGroup>
<SkipPackageFileCheck>true</SkipPackageFileCheck>
<PackageTargetRuntime>ubuntu.14.04-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
+ <!-- build for x64, arm -->
+ <PackagePlatforms>x64;arm;</PackagePlatforms>
</PropertyGroup>
<ItemGroup>
<NativeSplittableBinary Include="$(BinDir)libcoreclr.so" />
- <NativeSplittableBinary Include="$(BinDir)libcoreclrtraceptprovider.so" />
+ <NativeSplittableBinary Condition="'$(PackagePlatform)' != 'arm'" Include="$(BinDir)libcoreclrtraceptprovider.so" />
<NativeSplittableBinary Include="$(BinDir)libdbgshim.so" />
<NativeSplittableBinary Include="$(BinDir)libmscordaccore.so" />
<NativeSplittableBinary Include="$(BinDir)libmscordbi.so" />
@@ -17,8 +17,8 @@
<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" />
+ <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" />
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
index 7163623d37..72c48ee459 100644
--- 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
@@ -4,12 +4,12 @@
<PropertyGroup>
<SkipPackageFileCheck>true</SkipPackageFileCheck>
<PackageTargetRuntime>ubuntu.16.04-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
+ <!-- build for x64, arm -->
+ <PackagePlatforms>x64;arm;</PackagePlatforms>
</PropertyGroup>
<ItemGroup>
<NativeSplittableBinary Include="$(BinDir)libcoreclr.so" />
- <NativeSplittableBinary Include="$(BinDir)libcoreclrtraceptprovider.so" />
+ <NativeSplittableBinary Condition="'$(PackagePlatform)' != 'arm'" Include="$(BinDir)libcoreclrtraceptprovider.so" />
<NativeSplittableBinary Include="$(BinDir)libdbgshim.so" />
<NativeSplittableBinary Include="$(BinDir)libmscordaccore.so" />
<NativeSplittableBinary Include="$(BinDir)libmscordbi.so" />
@@ -17,8 +17,8 @@
<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" />
+ <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" />
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
index f77ac726f6..844fb0b10f 100644
--- 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
@@ -39,7 +39,7 @@
<ArchitectureSpecificNativeFileAndSymbol Include="$(BinDir)mscorrc.dll" />
<ArchitectureSpecificNativeFileAndSymbol Include="$(BinDir)sos.dll" />
<ArchitectureSpecificNativeFile Include="$(BinDir)mscorlib.ni.dll" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)System.Private.CoreLib.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" />
@@ -84,13 +84,13 @@
<CrossArchitectureSpecificNativeSymbol Condition="'$(HasCrossTargetComponents)' == 'true'"
Include="@(LongNameFiles -> '$(BinDir)$(CrossTargetComponentFolder)\%(FileName)$(CrossTargetLongNameSuffix)%(Extension)')" />
<AdditionalLibPackageExcludes Condition="'$(HasCrossTargetComponents)' == 'true'"
- Include="@(LongNameFiles -> 'runtimes\$(PackageTargetRuntime)\native\%(FileName)$(CrossTargetLongNameSuffix)%(Extension)')" />
+ 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>
+ <TargetPath>tools\$(CrossTargetComponentFolder)_$(PackagePlatform)</TargetPath>
<IsSymbolFile>true</IsSymbolFile>
</File>
</ItemGroup>
diff --git a/src/.nuget/Microsoft.NETCore.TestHost/Microsoft.NETCore.TestHost.builds b/src/.nuget/Microsoft.NETCore.TestHost/Microsoft.NETCore.TestHost.builds
index 2ae0292ea9..c1d076fb0e 100644
--- a/src/.nuget/Microsoft.NETCore.TestHost/Microsoft.NETCore.TestHost.builds
+++ b/src/.nuget/Microsoft.NETCore.TestHost/Microsoft.NETCore.TestHost.builds
@@ -27,6 +27,10 @@
<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>
@@ -55,14 +59,26 @@
<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="'$(TargetsOSX)' == 'true'" Include="osx/Microsoft.NETCore.TestHost.pkgproj">
<OSGroup>OSX</OSGroup>
<Platform>amd64</Platform>
diff --git a/src/.nuget/Microsoft.NETCore.TestHost/Microsoft.NETCore.TestHost.pkgproj b/src/.nuget/Microsoft.NETCore.TestHost/Microsoft.NETCore.TestHost.pkgproj
index fd6f7aae0b..325461d3ac 100644
--- a/src/.nuget/Microsoft.NETCore.TestHost/Microsoft.NETCore.TestHost.pkgproj
+++ b/src/.nuget/Microsoft.NETCore.TestHost/Microsoft.NETCore.TestHost.pkgproj
@@ -9,11 +9,6 @@
<IncludeRuntimeJson>true</IncludeRuntimeJson>
</PropertyGroup>
<ItemGroup>
- <!-- Declare a runtime dependency on the win8-arm CoreCLR built using the TFS builds -->
- <RuntimeDependency Include="runtime.win7-arm.Microsoft.NETCore.TestHost">
- <TargetRuntime>win7-arm</TargetRuntime>
- <Version>$(RuntimeWin7ArmMicrosoftNETCoreTestHostPackageVersion)</Version>
- </RuntimeDependency>
<ProjectReference Include="win\Microsoft.NETCore.TestHost.pkgproj">
<Platform>amd64</Platform>
</ProjectReference>
@@ -26,6 +21,9 @@
<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>
@@ -47,15 +45,24 @@
<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="osx\Microsoft.NETCore.TestHost.pkgproj">
<Platform>amd64</Platform>
</ProjectReference>
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
+</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
new file mode 100644
index 0000000000..dd142f6711
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.TestHost/alpine/3.4.3/Microsoft.NETCore.TestHost.pkgproj
@@ -0,0 +1,29 @@
+<?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/linux/Microsoft.NETCore.TestHost.pkgproj b/src/.nuget/Microsoft.NETCore.TestHost/linux/Microsoft.NETCore.TestHost.pkgproj
new file mode 100644
index 0000000000..06a6f4ce10
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.TestHost/linux/Microsoft.NETCore.TestHost.pkgproj
@@ -0,0 +1,29 @@
+<?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/ubuntu/14.04/Microsoft.NETCore.TestHost.pkgproj b/src/.nuget/Microsoft.NETCore.TestHost/ubuntu/14.04/Microsoft.NETCore.TestHost.pkgproj
index a73159ab00..8750e16817 100644
--- 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
@@ -4,8 +4,8 @@
<PropertyGroup>
<SkipPackageFileCheck>true</SkipPackageFileCheck>
<PackageTargetRuntime>ubuntu.14.04-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
+ <!-- build for x64, arm -->
+ <PackagePlatforms>x64;arm;</PackagePlatforms>
</PropertyGroup>
<ItemGroup>
<NativeSplittableBinary Include="$(BinDir)corerun" />
@@ -26,4 +26,4 @@
</File>
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
+</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
index 061319408b..3f1397f92f 100644
--- 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
@@ -4,8 +4,8 @@
<PropertyGroup>
<SkipPackageFileCheck>true</SkipPackageFileCheck>
<PackageTargetRuntime>ubuntu.16.04-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
+ <!-- build for x64, arm -->
+ <PackagePlatforms>x64;arm;</PackagePlatforms>
</PropertyGroup>
<ItemGroup>
<NativeSplittableBinary Include="$(BinDir)corerun" />
@@ -26,4 +26,4 @@
</File>
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
+</Project>
diff --git a/src/.nuget/optdata/project.json b/src/.nuget/optdata/project.json
deleted file mode 100644
index e8b45c85c0..0000000000
--- a/src/.nuget/optdata/project.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "dependencies": {
- "optimization.PGO.CoreCLR": "1.1.0-release-20161025"
- },
- "frameworks": {
- "netstandard": {}
- },
- "runtimes": {
- "win7-x64": {}
- }
-}
diff --git a/src/.nuget/packages.builds b/src/.nuget/packages.builds
index 89952ce6b0..7458c8e56f 100644
--- a/src/.nuget/packages.builds
+++ b/src/.nuget/packages.builds
@@ -9,6 +9,9 @@
<ItemGroup Condition="'$(__SkipCoreLibBuild)'==''">
<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" />
</ItemGroup>
diff --git a/src/ToolBox/.gitmirror b/src/ToolBox/.gitmirror
deleted file mode 100644
index f507630f94..0000000000
--- a/src/ToolBox/.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/ToolBox/.gitmirrorselective b/src/ToolBox/.gitmirrorselective
new file mode 100644
index 0000000000..817429603a
--- /dev/null
+++ b/src/ToolBox/.gitmirrorselective
@@ -0,0 +1 @@
+superpmi \ No newline at end of file
diff --git a/src/ToolBox/SOS/NETCore/SymbolReader.cs b/src/ToolBox/SOS/NETCore/SymbolReader.cs
index f4a3ce30d8..492f7cbd1f 100644
--- a/src/ToolBox/SOS/NETCore/SymbolReader.cs
+++ b/src/ToolBox/SOS/NETCore/SymbolReader.cs
@@ -28,13 +28,16 @@ namespace SOS
{
public IntPtr points;
public int size;
+ public IntPtr locals;
+ public int localsSize;
+
}
/// <summary>
/// Read memory callback
/// </summary>
/// <returns>number of bytes read or 0 for error</returns>
- internal unsafe delegate int ReadMemoryDelegate(IntPtr address, byte* buffer, int count);
+ internal unsafe delegate int ReadMemoryDelegate(ulong address, byte* buffer, int count);
private sealed class OpenedReader : IDisposable
{
@@ -58,7 +61,7 @@ namespace SOS
/// </summary>
private class TargetStream : Stream
{
- readonly IntPtr _address;
+ readonly ulong _address;
readonly ReadMemoryDelegate _readMemory;
public override long Position { get; set; }
@@ -67,7 +70,7 @@ namespace SOS
public override bool CanRead { get { return true; } }
public override bool CanWrite { get { return false; } }
- public TargetStream(IntPtr address, int size, ReadMemoryDelegate readMemory)
+ public TargetStream(ulong address, int size, ReadMemoryDelegate readMemory)
: base()
{
_address = address;
@@ -86,7 +89,7 @@ namespace SOS
{
fixed (byte* p = &buffer[offset])
{
- int read = _readMemory(new IntPtr(_address.ToInt64() + Position), p, count);
+ int read = _readMemory(_address + (ulong)Position, p, count);
Position += read;
return read;
}
@@ -126,6 +129,19 @@ namespace SOS
}
/// <summary>
+ /// Quick fix for Path.GetFileName which incorrectly handles Windows-style paths on Linux
+ /// </summary>
+ /// <param name="pathName"> File path to be processed </param>
+ /// <returns>Last component of path</returns>
+ private static string GetFileName(string pathName)
+ {
+ int pos = pathName.LastIndexOfAny(new char[] { '/', '\\'});
+ if (pos < 0)
+ return pathName;
+ return pathName.Substring(pos + 1);
+ }
+
+ /// <summary>
/// Checks availability of debugging information for given assembly.
/// </summary>
/// <param name="assemblyPath">
@@ -141,18 +157,18 @@ namespace SOS
/// <param name="inMemoryPdbAddress">in memory PDB address or zero</param>
/// <param name="inMemoryPdbSize">in memory PDB size</param>
/// <returns>Symbol reader handle or zero if error</returns>
- internal static IntPtr LoadSymbolsForModule(string assemblyPath, bool isFileLayout, IntPtr loadedPeAddress, int loadedPeSize,
- IntPtr inMemoryPdbAddress, int inMemoryPdbSize, ReadMemoryDelegate readMemory)
+ internal static IntPtr LoadSymbolsForModule(string assemblyPath, bool isFileLayout, ulong loadedPeAddress, int loadedPeSize,
+ ulong inMemoryPdbAddress, int inMemoryPdbSize, ReadMemoryDelegate readMemory)
{
try
{
TargetStream peStream = null;
- if (assemblyPath == null && loadedPeAddress != IntPtr.Zero)
+ if (assemblyPath == null && loadedPeAddress != 0)
{
peStream = new TargetStream(loadedPeAddress, loadedPeSize, readMemory);
}
TargetStream pdbStream = null;
- if (inMemoryPdbAddress != IntPtr.Zero)
+ if (inMemoryPdbAddress != 0)
{
pdbStream = new TargetStream(inMemoryPdbAddress, inMemoryPdbSize, readMemory);
}
@@ -207,7 +223,7 @@ namespace SOS
try
{
- string fileName = Path.GetFileName(filePath);
+ string fileName = GetFileName(filePath);
foreach (MethodDebugInformationHandle methodDebugInformationHandle in reader.MethodDebugInformation)
{
MethodDebugInformation methodDebugInfo = reader.GetMethodDebugInformation(methodDebugInformationHandle);
@@ -215,7 +231,7 @@ namespace SOS
foreach (SequencePoint point in sequencePoints)
{
string sourceName = reader.GetString(reader.GetDocument(point.Document).Name);
- if (point.StartLine == lineNumber && Path.GetFileName(sourceName) == fileName)
+ if (point.StartLine == lineNumber && GetFileName(sourceName) == fileName)
{
methodToken = MetadataTokens.GetToken(methodDebugInformationHandle.ToDefinitionHandle());
ilOffset = point.Offset;
@@ -378,7 +394,48 @@ namespace SOS
}
return false;
}
+ internal static bool GetLocalsInfoForMethod(string assemblyPath, int methodToken, out List<string> locals)
+ {
+ locals = null;
+
+ OpenedReader openedReader = GetReader(assemblyPath, isFileLayout: true, peStream: null, pdbStream: null);
+ if (openedReader == null)
+ return false;
+
+ using (openedReader)
+ {
+ try
+ {
+ Handle handle = MetadataTokens.Handle(methodToken);
+ if (handle.Kind != HandleKind.MethodDefinition)
+ return false;
+
+ locals = new List<string>();
+ MethodDebugInformationHandle methodDebugHandle =
+ ((MethodDefinitionHandle)handle).ToDebugInformationHandle();
+ LocalScopeHandleCollection localScopes = openedReader.Reader.GetLocalScopes(methodDebugHandle);
+ foreach (LocalScopeHandle scopeHandle in localScopes)
+ {
+ LocalScope scope = openedReader.Reader.GetLocalScope(scopeHandle);
+ LocalVariableHandleCollection localVars = scope.GetLocalVariables();
+ foreach (LocalVariableHandle varHandle in localVars)
+ {
+ LocalVariable localVar = openedReader.Reader.GetLocalVariable(varHandle);
+ if (localVar.Attributes == LocalVariableAttributes.DebuggerHidden)
+ continue;
+ locals.Add(openedReader.Reader.GetString(localVar.Name));
+ }
+ }
+ }
+ catch
+ {
+ return false;
+ }
+ }
+ return true;
+
+ }
/// <summary>
/// Returns source name, line numbers and IL offsets for given method token.
/// </summary>
@@ -392,11 +449,17 @@ namespace SOS
try
{
List<DebugInfo> points = null;
+ List<string> locals = null;
if (!GetDebugInfoForMethod(assemblyPath, methodToken, out points))
{
return false;
}
+
+ if (!GetLocalsInfoForMethod(assemblyPath, methodToken, out locals))
+ {
+ return false;
+ }
var structSize = Marshal.SizeOf<DebugInfo>();
debugInfo.size = points.Count;
@@ -407,6 +470,14 @@ namespace SOS
Marshal.StructureToPtr(info, ptr, false);
ptr = (IntPtr)(ptr.ToInt64() + structSize);
}
+ debugInfo.localsSize = locals.Count;
+ debugInfo.locals = Marshal.AllocHGlobal(debugInfo.localsSize * Marshal.SizeOf<IntPtr>());
+ IntPtr ptrLocals = debugInfo.locals;
+ foreach (string s in locals)
+ {
+ Marshal.WriteIntPtr(ptrLocals, Marshal.StringToHGlobalUni(s));
+ ptrLocals += Marshal.SizeOf<IntPtr>();
+ }
return true;
}
catch
@@ -446,12 +517,10 @@ namespace SOS
foreach (SequencePoint point in sequencePoints)
{
- if (point.StartLine == 0 || point.StartLine == SequencePoint.HiddenLine)
- continue;
DebugInfo debugInfo = new DebugInfo();
debugInfo.lineNumber = point.StartLine;
- debugInfo.fileName = openedReader.Reader.GetString(openedReader.Reader.GetDocument(point.Document).Name);
+ debugInfo.fileName = GetFileName(openedReader.Reader.GetString(openedReader.Reader.GetDocument(point.Document).Name));
debugInfo.ilOffset = point.Offset;
points.Add(debugInfo);
}
@@ -609,7 +678,7 @@ namespace SOS
{
try
{
- pdbPath = Path.Combine(Path.GetDirectoryName(assemblyPath), Path.GetFileName(pdbPath));
+ pdbPath = Path.Combine(Path.GetDirectoryName(assemblyPath), GetFileName(pdbPath));
}
catch
{
diff --git a/src/ToolBox/SOS/NETCore/project.json b/src/ToolBox/SOS/NETCore/project.json
index e9e4f0999f..7a3cf4fe1d 100644
--- a/src/ToolBox/SOS/NETCore/project.json
+++ b/src/ToolBox/SOS/NETCore/project.json
@@ -3,7 +3,7 @@
"Microsoft.NETCore.Platforms": "1.0.1",
"System.IO.FileSystem": "4.0.1",
"System.Runtime.InteropServices": "4.1.0",
- "System.Reflection.Metadata": "1.4.1-beta-24417-02"
+ "System.Reflection.Metadata": "1.4.1"
},
"frameworks": {
"netcoreapp1.0": {}
diff --git a/src/ToolBox/SOS/Strike/CMakeLists.txt b/src/ToolBox/SOS/Strike/CMakeLists.txt
index 5d25865780..8ba0ade1d8 100644
--- a/src/ToolBox/SOS/Strike/CMakeLists.txt
+++ b/src/ToolBox/SOS/Strike/CMakeLists.txt
@@ -24,7 +24,9 @@ elseif(CLR_CMAKE_PLATFORM_ARCH_I386)
add_definitions(-DSOS_TARGET_X86=1)
add_definitions(-D_TARGET_X86_=1)
add_definitions(-DDBG_TARGET_32BIT)
- add_definitions(-DSOS_TARGET_ARM=1)
+ if(WIN32)
+ add_definitions(-DSOS_TARGET_ARM=1)
+ endif(WIN32)
elseif(CLR_CMAKE_PLATFORM_ARCH_ARM)
add_definitions(-DSOS_TARGET_ARM=1)
add_definitions(-D_TARGET_WIN32_=1)
@@ -155,8 +157,13 @@ if(CLR_CMAKE_PLATFORM_ARCH_AMD64)
elseif(CLR_CMAKE_PLATFORM_ARCH_I386)
set(SOS_SOURCES_ARCH
disasmX86.cpp
- disasmARM.cpp
)
+ if(WIN32)
+ list(APPEND
+ SOS_SOURCES_ARCH
+ disasmARM.cpp
+ )
+ endif(WIN32)
elseif(CLR_CMAKE_PLATFORM_ARCH_ARM)
set(SOS_SOURCES_ARCH
disasmARM.cpp
diff --git a/src/ToolBox/SOS/Strike/ExpressionNode.cpp b/src/ToolBox/SOS/Strike/ExpressionNode.cpp
index 6516823aaa..920afbaedc 100644
--- a/src/ToolBox/SOS/Strike/ExpressionNode.cpp
+++ b/src/ToolBox/SOS/Strike/ExpressionNode.cpp
@@ -129,7 +129,7 @@ VOID ExpressionNode::DFSVisit(ExpressionNodeVisitorCallback pFunc, VOID* pUserDa
// Creates a new expression with a given debuggee value and frame
-ExpressionNode::ExpressionNode(__in_z WCHAR* pExpression, ICorDebugValue* pValue, ICorDebugILFrame* pFrame)
+ExpressionNode::ExpressionNode(__in_z const WCHAR* pExpression, ICorDebugValue* pValue, ICorDebugILFrame* pFrame)
{
Init(pValue, NULL, pFrame);
_snwprintf_s(pAbsoluteExpression, MAX_EXPRESSION, _TRUNCATE, L"%s", pExpression);
@@ -137,7 +137,7 @@ ExpressionNode::ExpressionNode(__in_z WCHAR* pExpression, ICorDebugValue* pValue
}
// Creates a new expression that has an error and no value
-ExpressionNode::ExpressionNode(__in_z WCHAR* pExpression, __in_z WCHAR* pErrorMessage)
+ExpressionNode::ExpressionNode(__in_z const WCHAR* pExpression, __in_z const WCHAR* pErrorMessage)
{
Init(NULL, NULL, NULL);
_snwprintf_s(pAbsoluteExpression, MAX_EXPRESSION, _TRUNCATE, L"%s", pExpression);
@@ -146,7 +146,7 @@ ExpressionNode::ExpressionNode(__in_z WCHAR* pExpression, __in_z WCHAR* pErrorMe
}
// Creates a new child expression
-ExpressionNode::ExpressionNode(__in_z WCHAR* pParentExpression, ChildKind ck, __in_z WCHAR* pRelativeExpression, ICorDebugValue* pValue, ICorDebugType* pType, ICorDebugILFrame* pFrame, UVCP_CONSTANT pDefaultValue, ULONG cchDefaultValue)
+ExpressionNode::ExpressionNode(__in_z const WCHAR* pParentExpression, ChildKind ck, __in_z const WCHAR* pRelativeExpression, ICorDebugValue* pValue, ICorDebugType* pType, ICorDebugILFrame* pFrame, UVCP_CONSTANT pDefaultValue, ULONG cchDefaultValue)
{
Init(pValue, pType, pFrame);
if(ck == ChildKind_BaseClass)
@@ -1979,7 +1979,7 @@ HRESULT ExpressionNode::GetCanonicalElementTypeForTypeName(__in_z WCHAR* pTypeNa
// Searches the debuggee for any ICorDebugType that matches the given fully qualified name
// This will search across all AppDomains and Assemblies
-HRESULT ExpressionNode::FindTypeByName(__in_z WCHAR* pTypeName, ICorDebugType** ppType)
+HRESULT ExpressionNode::FindTypeByName(__in_z const WCHAR* pTypeName, ICorDebugType** ppType)
{
HRESULT Status = S_OK;
ToRelease<ICorDebugAppDomainEnum> pAppDomainEnum;
@@ -2001,7 +2001,7 @@ HRESULT ExpressionNode::FindTypeByName(__in_z WCHAR* pTypeName, ICorDebugType**
// Searches the debuggee for any ICorDebugType that matches the given fully qualified name
// This will search across all Assemblies in the given AppDomain
-HRESULT ExpressionNode::FindTypeByName(ICorDebugAppDomain* pAppDomain, __in_z WCHAR* pTypeName, ICorDebugType** ppType)
+HRESULT ExpressionNode::FindTypeByName(ICorDebugAppDomain* pAppDomain, __in_z const WCHAR* pTypeName, ICorDebugType** ppType)
{
HRESULT Status = S_OK;
ToRelease<ICorDebugAssemblyEnum> pAssemblyEnum;
@@ -2022,7 +2022,7 @@ HRESULT ExpressionNode::FindTypeByName(ICorDebugAppDomain* pAppDomain, __in_z WC
}
// Searches the assembly for any ICorDebugType that matches the given fully qualified name
-HRESULT ExpressionNode::FindTypeByName(ICorDebugAssembly* pAssembly, __in_z WCHAR* pTypeName, ICorDebugType** ppType)
+HRESULT ExpressionNode::FindTypeByName(ICorDebugAssembly* pAssembly, __in_z const WCHAR* pTypeName, ICorDebugType** ppType)
{
HRESULT Status = S_OK;
ToRelease<ICorDebugModuleEnum> pModuleEnum;
@@ -2043,7 +2043,7 @@ HRESULT ExpressionNode::FindTypeByName(ICorDebugAssembly* pAssembly, __in_z WCHA
}
// Searches a given module for any ICorDebugType that matches the given fully qualified type name
-HRESULT ExpressionNode::FindTypeByName(ICorDebugModule* pModule, __in_z WCHAR* pTypeName, ICorDebugType** ppType)
+HRESULT ExpressionNode::FindTypeByName(ICorDebugModule* pModule, __in_z const WCHAR* pTypeName, ICorDebugType** ppType)
{
HRESULT Status = S_OK;
ToRelease<IUnknown> pMDUnknown;
@@ -2054,7 +2054,7 @@ HRESULT ExpressionNode::FindTypeByName(ICorDebugModule* pModule, __in_z WCHAR* p
// If the name contains a generic argument list, extract the type name from
// before the list
WCHAR rootName[mdNameLen];
- WCHAR* pRootName = NULL;
+ const WCHAR* pRootName = NULL;
int typeNameLen = (int) _wcslen(pTypeName);
int genericParamListStart = (int) _wcscspn(pTypeName, L"<");
if(genericParamListStart != typeNameLen)
@@ -2107,11 +2107,11 @@ HRESULT ExpressionNode::FindTypeByName(ICorDebugModule* pModule, __in_z WCHAR* p
}
typeParams = new ToRelease<ICorDebugType>[countTypeParams];
- WCHAR* pCurName = pTypeName + genericParamListStart+1;
+ const WCHAR* pCurName = pTypeName + genericParamListStart+1;
for(int i = 0; i < countTypeParams; i++)
{
WCHAR typeParamName[mdNameLen];
- WCHAR* pNextComma = _wcschr(pCurName, L',');
+ const WCHAR* pNextComma = _wcschr(pCurName, L',');
int len = (pNextComma != NULL) ? (int)(pNextComma - pCurName) : (int)_wcslen(pCurName)-1;
if(len > mdNameLen)
return E_FAIL;
diff --git a/src/ToolBox/SOS/Strike/ExpressionNode.h b/src/ToolBox/SOS/Strike/ExpressionNode.h
index 507a8a53d3..48cc036729 100644
--- a/src/ToolBox/SOS/Strike/ExpressionNode.h
+++ b/src/ToolBox/SOS/Strike/ExpressionNode.h
@@ -134,13 +134,13 @@ private:
};
// Creates a new expression with a given debuggee value and frame
- ExpressionNode(__in_z WCHAR* pExpression, ICorDebugValue* pValue, ICorDebugILFrame* pFrame);
+ ExpressionNode(__in_z const WCHAR* pExpression, ICorDebugValue* pValue, ICorDebugILFrame* pFrame);
// Creates a new expression that has an error and no value
- ExpressionNode(__in_z WCHAR* pExpression, __in_z WCHAR* pErrorMessage);
+ ExpressionNode(__in_z const WCHAR* pExpression, __in_z const WCHAR* pErrorMessage);
// Creates a new child expression
- ExpressionNode(__in_z WCHAR* pParentExpression, ChildKind ck, __in_z WCHAR* pRelativeExpression, ICorDebugValue* pValue, ICorDebugType* pType, ICorDebugILFrame* pFrame, UVCP_CONSTANT pDefaultValue = NULL, ULONG cchDefaultValue = 0);
+ ExpressionNode(__in_z const WCHAR* pParentExpression, ChildKind ck, __in_z const WCHAR* pRelativeExpression, ICorDebugValue* pValue, ICorDebugType* pType, ICorDebugILFrame* pFrame, UVCP_CONSTANT pDefaultValue = NULL, ULONG cchDefaultValue = 0);
// Common member initialization for the constructors
VOID Init(ICorDebugValue* pValue, ICorDebugType* pTypeCast, ICorDebugILFrame* pFrame);
@@ -288,17 +288,17 @@ private:
// Searches the debuggee for any ICorDebugType that matches the given fully qualified name
// This will search across all AppDomains and Assemblies
- static HRESULT FindTypeByName(__in_z WCHAR* pTypeName, ICorDebugType** ppType);
+ static HRESULT FindTypeByName(__in_z const WCHAR* pTypeName, ICorDebugType** ppType);
// Searches the debuggee for any ICorDebugType that matches the given fully qualified name
// This will search across all Assemblies in the given AppDomain
- static HRESULT FindTypeByName(ICorDebugAppDomain* pAppDomain, __in_z WCHAR* pTypeName, ICorDebugType** ppType);
+ static HRESULT FindTypeByName(ICorDebugAppDomain* pAppDomain, __in_z const WCHAR* pTypeName, ICorDebugType** ppType);
// Searches the assembly for any ICorDebugType that matches the given fully qualified name
- static HRESULT FindTypeByName(ICorDebugAssembly* pAssembly, __in_z WCHAR* pTypeName, ICorDebugType** ppType);
+ static HRESULT FindTypeByName(ICorDebugAssembly* pAssembly, __in_z const WCHAR* pTypeName, ICorDebugType** ppType);
// Searches a given module for any ICorDebugType that matches the given fully qualified type name
- static HRESULT FindTypeByName(ICorDebugModule* pModule, __in_z WCHAR* pTypeName, ICorDebugType** ppType);
+ static HRESULT FindTypeByName(ICorDebugModule* pModule, __in_z const WCHAR* pTypeName, ICorDebugType** ppType);
// Checks whether the given token is or refers to type System.ValueType or System.Enum
static HRESULT IsTokenValueTypeOrEnum(mdToken token, IMetaDataImport* pMetadata, BOOL* pResult);
diff --git a/src/ToolBox/SOS/Strike/datatarget.cpp b/src/ToolBox/SOS/Strike/datatarget.cpp
index 8f24b7d841..fe90f0e825 100644
--- a/src/ToolBox/SOS/Strike/datatarget.cpp
+++ b/src/ToolBox/SOS/Strike/datatarget.cpp
@@ -83,9 +83,9 @@ DataTarget::GetPointerSize(
{
#if defined(SOS_TARGET_AMD64) || defined(SOS_TARGET_ARM64)
*size = 8;
-#elif defined(SOS_TARGET_ARM)
+#elif defined(SOS_TARGET_ARM) || defined(SOS_TARGET_X86)
*size = 4;
-#elif
+#else
#error Unsupported architecture
#endif
diff --git a/src/ToolBox/SOS/Strike/sildasm.cpp b/src/ToolBox/SOS/Strike/sildasm.cpp
index 6bd3bb4801..911ff091e5 100644
--- a/src/ToolBox/SOS/Strike/sildasm.cpp
+++ b/src/ToolBox/SOS/Strike/sildasm.cpp
@@ -789,7 +789,7 @@ PCCOR_SIGNATURE PrettyPrintType(
{
//if (sizes[i] != 0 || lowerBounds[i] != 0)
{
- if (lowerBounds[i] == 0 && i < numSizes)
+ if (i < numSizes && lowerBounds[i] == 0)
appendStrNum(out, sizes[i]);
else
{
diff --git a/src/ToolBox/SOS/Strike/sos_stacktrace.h b/src/ToolBox/SOS/Strike/sos_stacktrace.h
index 4aba4ea52c..0af241ca3b 100644
--- a/src/ToolBox/SOS/Strike/sos_stacktrace.h
+++ b/src/ToolBox/SOS/Strike/sos_stacktrace.h
@@ -119,7 +119,7 @@ HRESULT CALLBACK _EFN_StackTrace(
// cbString - number of characters available in the string buffer.
//
// The output will be truncated of cbString is not long enough for the full stack trace.
-HRESULT _EFN_GetManagedExcepStack(
+HRESULT CALLBACK _EFN_GetManagedExcepStack(
PDEBUG_CLIENT client,
ULONG64 StackObjAddr,
__out_ecount(cbString) PSTR szStackString,
@@ -128,7 +128,7 @@ HRESULT _EFN_GetManagedExcepStack(
// _EFN_GetManagedExcepStackW - same as _EFN_GetManagedExcepStack, but returns
// the stack as a wide string.
-HRESULT _EFN_GetManagedExcepStackW(
+HRESULT CALLBACK _EFN_GetManagedExcepStackW(
PDEBUG_CLIENT client,
ULONG64 StackObjAddr,
__out_ecount(cchString) PWSTR wszStackString,
@@ -141,7 +141,7 @@ HRESULT _EFN_GetManagedExcepStackW(
// szName - a buffer to be filled with the full type name
// cbName - the number of characters available in the buffer
//
-HRESULT _EFN_GetManagedObjectName(
+HRESULT CALLBACK _EFN_GetManagedObjectName(
PDEBUG_CLIENT client,
ULONG64 objAddr,
__out_ecount(cbName) PSTR szName,
@@ -158,7 +158,7 @@ HRESULT _EFN_GetManagedObjectName(
// pOffset - the offset from objAddr to the field. This parameter can be NULL.
//
// At least one of pValue and pOffset must be non-NULL.
-HRESULT _EFN_GetManagedObjectFieldInfo(
+HRESULT CALLBACK _EFN_GetManagedObjectFieldInfo(
PDEBUG_CLIENT client,
ULONG64 objAddr,
__out_ecount (mdNameLen) PSTR szFieldName,
diff --git a/src/ToolBox/SOS/Strike/sosdocsunix.txt b/src/ToolBox/SOS/Strike/sosdocsunix.txt
index 52ec86dc4e..5ab2b311cc 100644
--- a/src/ToolBox/SOS/Strike/sosdocsunix.txt
+++ b/src/ToolBox/SOS/Strike/sosdocsunix.txt
@@ -844,6 +844,7 @@ corruption bug caused by invalid GCEncoding for a particular method.
COMMAND: bpmd.
bpmd [-nofuturemodule] <module name> <method name> [<il offset>]
+bpmd <source file name>:<line number>
bpmd -md <MethodDesc>
bpmd -list
bpmd -clear <pending breakpoint number>
diff --git a/src/ToolBox/SOS/Strike/stressLogDump.cpp b/src/ToolBox/SOS/Strike/stressLogDump.cpp
index f277f92434..9dfbe1ed5e 100644
--- a/src/ToolBox/SOS/Strike/stressLogDump.cpp
+++ b/src/ToolBox/SOS/Strike/stressLogDump.cpp
@@ -34,7 +34,7 @@ static const WCHAR* getTime(const FILETIME* time, __out_ecount (buffLen) WCHAR*
return badTime;
#ifdef FEATURE_PAL
- int length = _snwprintf(buff, buffLen, W("%02d:%02d:%02d"), systemTime.wHour, systemTime.wMinute, systemTime.wSecond);
+ int length = _snwprintf_s(buff, buffLen, _TRUNCATE, W("%02d:%02d:%02d"), systemTime.wHour, systemTime.wMinute, systemTime.wSecond);
if (length <= 0)
return badTime;
#else // FEATURE_PAL
diff --git a/src/ToolBox/SOS/Strike/strike.cpp b/src/ToolBox/SOS/Strike/strike.cpp
index 731e2f505d..3bb3f50200 100644
--- a/src/ToolBox/SOS/Strike/strike.cpp
+++ b/src/ToolBox/SOS/Strike/strike.cpp
@@ -4361,8 +4361,10 @@ DECLARE_API(VerifyObj)
ExtOut("Unable to build snapshot of the garbage collector state\n");
goto Exit;
}
- DacpGcHeapDetails *pheapDetails = g_snapshot.GetHeap(taddrObj);
- bValid = VerifyObject(*pheapDetails, taddrObj, taddrMT, objSize, TRUE);
+ {
+ DacpGcHeapDetails *pheapDetails = g_snapshot.GetHeap(taddrObj);
+ bValid = VerifyObject(*pheapDetails, taddrObj, taddrMT, objSize, TRUE);
+ }
Exit:
if (bValid)
@@ -5888,6 +5890,56 @@ HRESULT PrintSpecialThreads()
}
#endif //FEATURE_PAL
+HRESULT SwitchToExceptionThread()
+{
+ HRESULT Status;
+
+ DacpThreadStoreData ThreadStore;
+ if ((Status = ThreadStore.Request(g_sos)) != S_OK)
+ {
+ Print("Failed to request ThreadStore\n");
+ return Status;
+ }
+
+ DacpThreadData Thread;
+ CLRDATA_ADDRESS CurThread = ThreadStore.firstThread;
+ while (CurThread)
+ {
+ if (IsInterrupt())
+ break;
+
+ if ((Status = Thread.Request(g_sos, CurThread)) != S_OK)
+ {
+ PrintLn("Failed to request Thread at ", Pointer(CurThread));
+ return Status;
+ }
+
+ TADDR taLTOH;
+ if (Thread.lastThrownObjectHandle != NULL)
+ {
+ if (SafeReadMemory(TO_TADDR(Thread.lastThrownObjectHandle), &taLTOH, sizeof(taLTOH), NULL))
+ {
+ if (taLTOH != NULL)
+ {
+ ULONG id;
+ if (g_ExtSystem->GetThreadIdBySystemId(Thread.osThreadId, &id) == S_OK)
+ {
+ if (g_ExtSystem->SetCurrentThreadId(id) == S_OK)
+ {
+ PrintLn("Found managed exception on thread ", ThreadID(Thread.osThreadId));
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ CurThread = Thread.nextThread;
+ }
+
+ return Status;
+}
+
struct ThreadStateTable
{
unsigned int State;
@@ -5961,12 +6013,14 @@ DECLARE_API(Threads)
BOOL bPrintSpecialThreads = FALSE;
BOOL bPrintLiveThreadsOnly = FALSE;
+ BOOL bSwitchToManagedExceptionThread = FALSE;
BOOL dml = FALSE;
CMDOption option[] =
{ // name, vptr, type, hasValue
{"-special", &bPrintSpecialThreads, COBOOL, FALSE},
{"-live", &bPrintLiveThreadsOnly, COBOOL, FALSE},
+ {"-managedexception", &bSwitchToManagedExceptionThread, COBOOL, FALSE},
#ifndef FEATURE_PAL
{"/d", &dml, COBOOL, FALSE},
#endif
@@ -5975,6 +6029,11 @@ DECLARE_API(Threads)
{
return Status;
}
+
+ if (bSwitchToManagedExceptionThread)
+ {
+ return SwitchToExceptionThread();
+ }
// We need to support minidumps for this command.
BOOL bMiniDump = IsMiniDumpFile();
@@ -9119,7 +9178,7 @@ DECLARE_API (ProcInfo)
if (pFntGetProcessTimes && pFntGetProcessTimes (hProcess,&CreationTime,&ExitTime,&KernelTime,&UserTime)) {
ExtOut("---------------------------------------\n");
ExtOut("Process Times\n");
- static char *Month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
+ static const char *Month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
"Oct", "Nov", "Dec"};
SYSTEMTIME SystemTime;
FILETIME LocalFileTime;
diff --git a/src/ToolBox/SOS/Strike/util.cpp b/src/ToolBox/SOS/Strike/util.cpp
index 9eec76e42c..b6336fb143 100644
--- a/src/ToolBox/SOS/Strike/util.cpp
+++ b/src/ToolBox/SOS/Strike/util.cpp
@@ -254,47 +254,49 @@ HRESULT CreateInstanceCustomImpl(
typedef HRESULT (__stdcall IDebugSymbols3::*GetPathFunc)(LPWSTR , ULONG, ULONG*);
- // Handle both the image path and the symbol path
- GetPathFunc rgGetPathFuncs[] =
- { &IDebugSymbols3::GetImagePathWide, &IDebugSymbols3::GetSymbolPathWide };
-
- for (int i = 0; i < _countof(rgGetPathFuncs); ++i)
{
- ULONG pathSize = 0;
+ // Handle both the image path and the symbol path
+ GetPathFunc rgGetPathFuncs[] =
+ { &IDebugSymbols3::GetImagePathWide, &IDebugSymbols3::GetSymbolPathWide };
- // get the path buffer size
- if ((spSym3.GetPtr()->*rgGetPathFuncs[i])(NULL, 0, &pathSize) != S_OK)
+ for (int i = 0; i < _countof(rgGetPathFuncs); ++i)
{
- continue;
- }
+ ULONG pathSize = 0;
- ArrayHolder<WCHAR> imgPath = new WCHAR[pathSize+MAX_LONGPATH+1];
- if (imgPath == NULL)
- {
- continue;
- }
+ // get the path buffer size
+ if ((spSym3.GetPtr()->*rgGetPathFuncs[i])(NULL, 0, &pathSize) != S_OK)
+ {
+ continue;
+ }
- // actually get the path
- if ((spSym3.GetPtr()->*rgGetPathFuncs[i])(imgPath, pathSize, NULL) != S_OK)
- {
- continue;
- }
+ ArrayHolder<WCHAR> imgPath = new WCHAR[pathSize+MAX_LONGPATH+1];
+ if (imgPath == NULL)
+ {
+ continue;
+ }
- LPWSTR ctx;
- LPCWSTR pathElem = wcstok_s(imgPath, W(";"), &ctx);
- while (pathElem != NULL)
- {
- WCHAR fullName[MAX_LONGPATH];
- wcscpy_s(fullName, _countof(fullName), pathElem);
- if (wcscat_s(fullName, W("\\")) == 0 && wcscat_s(fullName, dllName) == 0)
+ // actually get the path
+ if ((spSym3.GetPtr()->*rgGetPathFuncs[i])(imgPath, pathSize, NULL) != S_OK)
+ {
+ continue;
+ }
+
+ LPWSTR ctx;
+ LPCWSTR pathElem = wcstok_s(imgPath, W(";"), &ctx);
+ while (pathElem != NULL)
{
- if (SUCCEEDED(CreateInstanceFromPath(clsid, iid, fullName, ppItf)))
+ WCHAR fullName[MAX_LONGPATH];
+ wcscpy_s(fullName, _countof(fullName), pathElem);
+ if (wcscat_s(fullName, W("\\")) == 0 && wcscat_s(fullName, dllName) == 0)
{
- return S_OK;
+ if (SUCCEEDED(CreateInstanceFromPath(clsid, iid, fullName, ppItf)))
+ {
+ return S_OK;
+ }
}
- }
- pathElem = wcstok_s(NULL, W(";"), &ctx);
+ pathElem = wcstok_s(NULL, W(";"), &ctx);
+ }
}
}
@@ -6132,7 +6134,7 @@ HRESULT SymbolReader::LoadSymbolsForWindowsPDB(___in IMetaDataImport* pMD, ___in
int ReadMemoryForSymbols(ULONG64 address, char *buffer, int cb)
{
ULONG read;
- if (SafeReadMemory(address, (PVOID)buffer, cb, &read))
+ if (SafeReadMemory(TO_TADDR(address), (PVOID)buffer, cb, &read))
{
return read;
}
diff --git a/src/ToolBox/SOS/Strike/util.h b/src/ToolBox/SOS/Strike/util.h
index f444c9fcb2..4612acc299 100644
--- a/src/ToolBox/SOS/Strike/util.h
+++ b/src/ToolBox/SOS/Strike/util.h
@@ -2258,13 +2258,9 @@ void GetMethodName(mdMethodDef methodDef, IMetaDataImport * pImport, CQuickBytes
#ifndef _TARGET_WIN64_
#define itoa_s_ptr _itoa_s
#define itow_s_ptr _itow_s
-#define itoa_ptr _itoa
-#define itow_ptr _itow
#else
#define itoa_s_ptr _i64toa_s
#define itow_s_ptr _i64tow_s
-#define itoa_ptr _i64toa
-#define itow_ptr _i64tow
#endif
#ifdef FEATURE_PAL
@@ -2359,11 +2355,11 @@ static const char *SymbolReaderDllName = "SOS.NETCore";
static const char *SymbolReaderClassName = "SOS.SymbolReader";
typedef int (*ReadMemoryDelegate)(ULONG64, char *, int);
-typedef ULONG64 (*LoadSymbolsForModuleDelegate)(const char*, BOOL, ULONG64, int, ULONG64, int, ReadMemoryDelegate);
-typedef void (*DisposeDelegate)(ULONG64);
-typedef BOOL (*ResolveSequencePointDelegate)(ULONG64, const char*, unsigned int, unsigned int*, unsigned int*);
-typedef BOOL (*GetLocalVariableName)(ULONG64, int, int, BSTR*);
-typedef BOOL (*GetLineByILOffsetDelegate)(ULONG64, mdMethodDef, ULONG64, ULONG *, BSTR*);
+typedef PVOID (*LoadSymbolsForModuleDelegate)(const char*, BOOL, ULONG64, int, ULONG64, int, ReadMemoryDelegate);
+typedef void (*DisposeDelegate)(PVOID);
+typedef BOOL (*ResolveSequencePointDelegate)(PVOID, const char*, unsigned int, unsigned int*, unsigned int*);
+typedef BOOL (*GetLocalVariableName)(PVOID, int, int, BSTR*);
+typedef BOOL (*GetLineByILOffsetDelegate)(PVOID, mdMethodDef, ULONG64, ULONG *, BSTR*);
class SymbolReader
{
@@ -2371,7 +2367,7 @@ private:
#ifndef FEATURE_PAL
ISymUnmanagedReader* m_pSymReader;
#endif
- ULONG64 m_symbolReaderHandle;
+ PVOID m_symbolReaderHandle;
static LoadSymbolsForModuleDelegate loadSymbolsForModuleDelegate;
static DisposeDelegate disposeDelegate;
diff --git a/src/ToolBox/SOS/Strike/vm.cpp b/src/ToolBox/SOS/Strike/vm.cpp
index e7e5701fc6..70e9210dbd 100644
--- a/src/ToolBox/SOS/Strike/vm.cpp
+++ b/src/ToolBox/SOS/Strike/vm.cpp
@@ -82,7 +82,7 @@ typedef struct _VM_STATS
typedef struct PROTECT_MASK
{
DWORD Bit;
- PSTR Name;
+ PCSTR Name;
} PROTECT_MASK, *PPROTECT_MASK;
@@ -324,7 +324,7 @@ PrintVmStatsHeader(
VOID
PrintIndividualStat(
- ___in __in_z IN PSTR Name,
+ ___in __in_z IN PCSTR Name,
IN PINDIVIDUAL_STAT Stat
)
{
@@ -379,7 +379,7 @@ PrintIndividualStat(
VOID
PrintVmStats(
- ___in __in_z IN PSTR Name,
+ ___in __in_z IN PCSTR Name,
IN PVM_STATS Stats
)
{
@@ -443,7 +443,7 @@ VmStateToString(
size_t capacity_Buffer
)
{
- PSTR result;
+ PCSTR result;
CHAR invalidStr[sizeof("12345678")];
switch( State )
@@ -478,7 +478,7 @@ VmTypeToString(
size_t capacity_Buffer
)
{
- PSTR result;
+ PCSTR result;
CHAR invalidStr[sizeof("12345678")];
switch( Type )
diff --git a/src/ToolBox/SOS/lldbplugin/CMakeLists.txt b/src/ToolBox/SOS/lldbplugin/CMakeLists.txt
index 9f90a54056..7f1fa7704f 100644
--- a/src/ToolBox/SOS/lldbplugin/CMakeLists.txt
+++ b/src/ToolBox/SOS/lldbplugin/CMakeLists.txt
@@ -21,6 +21,10 @@ if(CLR_CMAKE_PLATFORM_ARCH_AMD64)
add_definitions(-DDBG_TARGET_AMD64=1)
add_definitions(-DDBG_TARGET_WIN64=1)
add_definitions(-DBIT64)
+elseif(CLR_CMAKE_PLATFORM_ARCH_I386)
+ add_definitions(-D_TARGET_X86_=1)
+ add_definitions(-DDBG_TARGET_32BIT=1)
+ add_definitions(-DDBG_TARGET_X86=1)
elseif(CLR_CMAKE_PLATFORM_ARCH_ARM)
add_definitions(-D_TARGET_ARM_=1)
add_definitions(-DDBG_TARGET_32BIT=1)
@@ -33,6 +37,9 @@ 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/SOS/lldbplugin/services.cpp b/src/ToolBox/SOS/lldbplugin/services.cpp
index f6b42139c4..d2d2cf9f8e 100644
--- a/src/ToolBox/SOS/lldbplugin/services.cpp
+++ b/src/ToolBox/SOS/lldbplugin/services.cpp
@@ -167,6 +167,8 @@ LLDBServices::VirtualUnwind(
#ifdef DBG_TARGET_AMD64
DWORD64 spToFind = dtcontext->Rsp;
+#elif DBG_TARGET_X86
+ DWORD spToFind = dtcontext->Esp;
#elif DBG_TARGET_ARM
DWORD spToFind = dtcontext->Sp;
#endif
diff --git a/src/ToolBox/SOS/tests/OnCrash.do b/src/ToolBox/SOS/tests/OnCrash.do
deleted file mode 100644
index b1da86154a..0000000000
--- a/src/ToolBox/SOS/tests/OnCrash.do
+++ /dev/null
@@ -1,2 +0,0 @@
-script open("/tmp/flag_fail", "a").close()
-q
diff --git a/src/ToolBox/SOS/tests/README.md b/src/ToolBox/SOS/tests/README.md
index ed4c8d062c..1b9c1eac29 100644
--- a/src/ToolBox/SOS/tests/README.md
+++ b/src/ToolBox/SOS/tests/README.md
@@ -1,18 +1,28 @@
Testing libsosplugin
=====================================
-**Test assembly**
-The test asembly file must follow two rules:
-1. the test class must be named `Program` and
-2. it must have a static `Main` method.
-
-**Running tests**
-Make sure that python's lldb module is accessible. To run the tests, use the following command:
-`python test_libsosplugin.py --clr-args="/path/to/corerun [corerun_options] /path/to/test_assembly.exe"`
-`--clr-args` is a command that would normally be used to launch `corerun`
-This will run the test suite on the specified assembly.
-
-**Writing tests**
+**Test assembly**
+Compile test assembly file using any C# compiler you have, for example:
+- `gmcs test.cs`
+- `corerun csc.exe /nologo /r:System.Private.CoreLib.dll test.cs`
+
+
+**Running tests**
+Make sure that python's lldb module is accessible. To run the tests, use the following command:
+`python2 test_libsosplugin.py --corerun=corerun --sosplugin=sosplugin --assembly=assembly --timeout=timeout`
+- `lldb` is a path to `lldb` to run
+- `clrdir` is a directory with `corerun` and sosplugin
+- `assembly` is a compiled test assembly (e.g. Test.exe)
+- `timeout` is a deadline for a single test (in seconds)
+- `regex` is a regular expression matching tests to run
+- `repeat` is a number of passes for each test
+
+
+
+Log files for both failed and passed tests are `*.log` and `*.log.2` for standard output and error correspondingly.
+
+
+**Writing tests**
Tests start with the `TestSosCommands` class defined in `test_libsosplugin.py`. To add a test to the suite, start with implementing a new method inside this class whose name begins with `test_`. Most new commands will require only one line of code in this method: `self.do_test("scenarioname")`. This command will launch a new `lldb` instance, which in turn will call the `runScenario` method from `scenarioname` module. `scenarioname` is the name of the python module that will be running the scenario inside `lldb` (found in `tests` folder alongside with `test_libsosplugin.py` and named `scenarioname.py`).
An example of a scenario looks like this:
@@ -25,9 +35,10 @@ An example of a scenario looks like this:
process.Continue()
return True
- `runScenario` method does all the work related to running the scenario: setting breakpoints, running SOS commands and examining their output. It should return a boolean value indicating a success or a failure.
+ `runScenario` method does all the work related to running the scenario: setting breakpoints, running SOS commands and examining their output. It should return a boolean value indicating a success or a failure.
***Note:*** `testutils.py` defines some useful commands that can be reused in many scenarios.
-**Useful links**
-[Python scripting in LLDB](http://lldb.llvm.org/python-reference.html)
-[Python unittest framework](https://docs.python.org/2.7/library/unittest.html) \ No newline at end of file
+
+**Useful links**
+[Python scripting in LLDB](http://lldb.llvm.org/python-reference.html)
+[Python unittest framework](https://docs.python.org/2.7/library/unittest.html)
diff --git a/src/ToolBox/SOS/tests/Test.cs b/src/ToolBox/SOS/tests/Test.cs
new file mode 100644
index 0000000000..e4ef76b30a
--- /dev/null
+++ b/src/ToolBox/SOS/tests/Test.cs
@@ -0,0 +1,94 @@
+using System;
+
+class Test
+{
+ static void LikelyInlined()
+ {
+ Console.WriteLine("I would like to be inlined");
+ }
+
+ static void UnlikelyInlined()
+ {
+ Console.Write("I");
+ Console.Write(" ");
+ Console.Write("w");
+ Console.Write("o");
+ Console.Write("u");
+ Console.Write("l");
+ Console.Write("d");
+ Console.Write(" ");
+ Console.Write("n");
+ Console.Write("o");
+ Console.Write("t");
+ Console.Write(" ");
+ Console.Write("l");
+ Console.Write("i");
+ Console.Write("k");
+ Console.Write("e");
+ Console.Write(" ");
+ Console.Write("t");
+ Console.Write("o");
+ Console.Write(" ");
+ Console.Write("b");
+ Console.Write("e");
+ Console.Write(" ");
+ Console.Write("i");
+ Console.Write("n");
+ Console.Write("l");
+ Console.Write("i");
+ Console.Write("n");
+ Console.Write("e");
+ Console.Write("d");
+ Console.Write("\n");
+ }
+
+ static void ClrU()
+ {
+ Console.WriteLine("test dumpclass");
+ }
+
+ static void DumpClass()
+ {
+ Console.WriteLine("test dumpclass");
+ }
+
+ static void DumpIL()
+ {
+ Console.WriteLine("test dumpil");
+ }
+
+ static void DumpMD()
+ {
+ Console.WriteLine("test dumpmd");
+ }
+
+ static void DumpModule()
+ {
+ Console.WriteLine("test dumpmodule");
+ }
+
+ static void DumpObject()
+ {
+ Console.WriteLine("test dumpobject");
+ }
+
+ static void DumpStackObjects()
+ {
+ Console.WriteLine("test dso");
+ }
+
+ static void Name2EE()
+ {
+ Console.WriteLine("test name2ee");
+ }
+
+
+ static int Main()
+ {
+ DumpIL();
+ LikelyInlined();
+ UnlikelyInlined();
+
+ return 0;
+ }
+}
diff --git a/src/ToolBox/SOS/tests/dumpil.py b/src/ToolBox/SOS/tests/dumpil.py
deleted file mode 100644
index 9539b618bb..0000000000
--- a/src/ToolBox/SOS/tests/dumpil.py
+++ /dev/null
@@ -1,26 +0,0 @@
-import lldb
-import lldbutil
-import re
-import os
-import testutils
-
-def runScenario(assemblyName, debugger, target):
- process = target.GetProcess()
- res = lldb.SBCommandReturnObject()
- ci = debugger.GetCommandInterpreter()
-
- testutils.stop_in_main(ci, process, assemblyName)
- addr = testutils.exec_and_find(ci, "name2ee " + assemblyName + " Program.Main", "MethodDesc:\s+([0-9a-fA-F]+)")
-
- result = False
- if addr is not None:
- ci.HandleCommand("dumpil " + addr, res)
- if res.Succeeded():
- result = True
- else:
- print("DumpIL failed:")
- print(res.GetOutput())
- print(res.GetError())
-
- process.Continue()
- return result
diff --git a/src/ToolBox/SOS/tests/dumpmodule.py b/src/ToolBox/SOS/tests/dumpmodule.py
deleted file mode 100644
index 04a5764752..0000000000
--- a/src/ToolBox/SOS/tests/dumpmodule.py
+++ /dev/null
@@ -1,26 +0,0 @@
-import lldb
-import lldbutil
-import re
-import os
-import testutils
-
-def runScenario(assemblyName, debugger, target):
- process = target.GetProcess()
- res = lldb.SBCommandReturnObject()
- ci = debugger.GetCommandInterpreter()
-
- testutils.stop_in_main(ci, process, assemblyName)
- addr = testutils.exec_and_find(ci, "name2ee " + assemblyName + " Program.Main", "Module:\s+([0-9a-fA-F]+)")
-
- result = False
- if addr is not None:
- ci.HandleCommand("dumpmodule " + addr, res)
- if res.Succeeded():
- result = True
- else:
- print("DumpModule failed:")
- print(res.GetOutput())
- print(res.GetError())
-
- process.Continue()
- return result \ No newline at end of file
diff --git a/src/ToolBox/SOS/tests/runprocess.py b/src/ToolBox/SOS/tests/runprocess.py
deleted file mode 100644
index d9367b3e6c..0000000000
--- a/src/ToolBox/SOS/tests/runprocess.py
+++ /dev/null
@@ -1,34 +0,0 @@
-import os
-import lldb
-import sys
-import importlib
-from test_libsosplugin import fail_flag
-
-def run(assemblyName, moduleName):
- global fail_flag
-
- print(fail_flag)
- # set the flag, if it is not set
- if not os.access(fail_flag, os.R_OK):
- open(fail_flag, "a").close()
-
-
- debugger = lldb.debugger
-
- debugger.SetAsync(False)
- target = lldb.target
-
- debugger.HandleCommand("process launch -s")
- debugger.HandleCommand("breakpoint set -n LoadLibraryExW")
-
- target.GetProcess().Continue()
-
- debugger.HandleCommand("breakpoint delete 1")
- #run the scenario
- print("starting scenario...")
- i = importlib.import_module(moduleName)
- scenarioResult = i.runScenario(os.path.basename(assemblyName), debugger, target)
-
- # clear the failed flag if the exit status is OK
- if scenarioResult is True and target.GetProcess().GetExitStatus() == 0:
- os.unlink(fail_flag)
diff --git a/src/ToolBox/SOS/tests/t_cmd_bpmd_clear.py b/src/ToolBox/SOS/tests/t_cmd_bpmd_clear.py
new file mode 100644
index 0000000000..814d114d16
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_bpmd_clear.py
@@ -0,0 +1,62 @@
+import lldb
+import re
+import testutils as test
+
+# bpmd -clearall
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ # Set breakpoint
+
+ ci.HandleCommand("bpmd " + assembly + " Test.UnlikelyInlined", res)
+ out_msg = res.GetOutput()
+ err_msg = res.GetError()
+ print(out_msg)
+ print(err_msg)
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ # Output is not empty
+ # Should be at least 'Adding pending breakpoints...'
+ test.assertTrue(len(out_msg) > 0)
+
+ # Error message is empty
+ test.assertTrue(len(err_msg) == 0)
+
+ # Delete the first breakpoint
+
+ ci.HandleCommand("bpmd -clear 1", res)
+ out_msg = res.GetOutput()
+ err_msg = res.GetError()
+ print(out_msg)
+ print(err_msg)
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ match = re.search('Cleared', out_msg)
+ # Check for specific output
+ test.assertTrue(match)
+
+ # Error message is empty
+ test.assertEqual(err_msg, '')
+
+ process.Continue()
+ # Process must be exited
+ test.assertEqual(process.GetState(), lldb.eStateExited)
+
+ # The reason of this stop must be a breakpoint
+ test.assertEqual(process.GetSelectedThread().GetStopReason(),
+ lldb.eStopReasonNone)
+
+ #
+
+ # Delete all breakpoints, continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_bpmd_clearall.py b/src/ToolBox/SOS/tests/t_cmd_bpmd_clearall.py
new file mode 100644
index 0000000000..8da9239f57
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_bpmd_clearall.py
@@ -0,0 +1,62 @@
+import lldb
+import re
+import testutils as test
+
+# bpmd -clearall
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ # Set breakpoint
+
+ ci.HandleCommand("bpmd " + assembly + " Test.UnlikelyInlined", res)
+ out_msg = res.GetOutput()
+ err_msg = res.GetError()
+ print(out_msg)
+ print(err_msg)
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ # Output is not empty
+ # Should be at least 'Adding pending breakpoints...'
+ test.assertTrue(len(out_msg) > 0)
+
+ # Error message is empty
+ test.assertTrue(len(err_msg) == 0)
+
+ # Delete all breakpoints
+
+ ci.HandleCommand("bpmd -clearall", res)
+ out_msg = res.GetOutput()
+ err_msg = res.GetError()
+ print(out_msg)
+ print(err_msg)
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ match = re.search('All pending breakpoints cleared.', out_msg)
+ # Check for specific output
+ test.assertTrue(match)
+
+ # Error message is empty
+ test.assertEqual(err_msg, '')
+
+ process.Continue()
+ # Process must be exited
+ test.assertEqual(process.GetState(), lldb.eStateExited)
+
+ # The reason of this stop must be a breakpoint
+ test.assertEqual(process.GetSelectedThread().GetStopReason(),
+ lldb.eStopReasonNone)
+
+ #
+
+ # Delete all breakpoints, continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_bpmd_methoddesc.py b/src/ToolBox/SOS/tests/t_cmd_bpmd_methoddesc.py
new file mode 100644
index 0000000000..dfd75432f3
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_bpmd_methoddesc.py
@@ -0,0 +1,45 @@
+import lldb
+import re
+import testutils as test
+
+# bpmd -md <MethodDesc pointer>
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ md_addr = test.get_methoddesc(debugger, assembly, "Test.UnlikelyInlined")
+
+ ci.HandleCommand("bpmd -md %s" % md_addr, res)
+ out_msg = res.GetOutput()
+ err_msg = res.GetError()
+ print(out_msg)
+ print(err_msg)
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ # Output is not empty
+ # Should be at least 'Adding pending breakpoints...'
+ test.assertTrue(len(out_msg) > 0)
+
+ # Error message is empty
+ test.assertTrue(len(err_msg) == 0)
+
+ process.Continue()
+ # Process must be stopped at UnlinkelyInlined
+ test.assertEqual(process.GetState(), lldb.eStateStopped)
+
+ # The reason of this stop must be a breakpoint
+ test.assertEqual(process.GetSelectedThread().GetStopReason(),
+ lldb.eStopReasonBreakpoint)
+
+ #
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_bpmd_module_function.py b/src/ToolBox/SOS/tests/t_cmd_bpmd_module_function.py
new file mode 100644
index 0000000000..e407ab3e4e
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_bpmd_module_function.py
@@ -0,0 +1,43 @@
+import lldb
+import re
+import testutils as test
+
+# bpmd <module name> <managed function name>
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("bpmd " + assembly + " Test.UnlikelyInlined", res)
+ out_msg = res.GetOutput()
+ err_msg = res.GetError()
+ print(out_msg)
+ print(err_msg)
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ # Output is not empty
+ # Should be at least 'Adding pending breakpoints...'
+ test.assertTrue(len(out_msg) > 0)
+
+ # Error message is empty
+ test.assertTrue(len(err_msg) == 0)
+
+ process.Continue()
+ # Process must be stopped at UnlinkelyInlined
+ test.assertEqual(process.GetState(), lldb.eStateStopped)
+
+ # The reason of this stop must be a breakpoint
+ test.assertEqual(process.GetSelectedThread().GetStopReason(),
+ lldb.eStopReasonBreakpoint)
+
+ #
+
+ # Delete all breakpoints, continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_bpmd_module_function_iloffset.py b/src/ToolBox/SOS/tests/t_cmd_bpmd_module_function_iloffset.py
new file mode 100644
index 0000000000..91fb1cd125
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_bpmd_module_function_iloffset.py
@@ -0,0 +1,43 @@
+import lldb
+import re
+import testutils as test
+
+# bpmd <module name> <managed function name> [<il offset>]
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("bpmd " + assembly + " Test.UnlikelyInlined 66", res)
+ out_msg = res.GetOutput()
+ err_msg = res.GetError()
+ print(out_msg)
+ print(err_msg)
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ # Output is not empty
+ # Should be at least 'Adding pending breakpoints...'
+ test.assertTrue(len(out_msg) > 0)
+
+ # Error message is empty
+ test.assertTrue(len(err_msg) == 0)
+
+ process.Continue()
+ # Process must be stopped at UnlinkelyInlined
+ test.assertEqual(process.GetState(), lldb.eStateStopped)
+
+ # The reason of this stop must be a breakpoint
+ test.assertEqual(process.GetSelectedThread().GetStopReason(),
+ lldb.eStopReasonBreakpoint)
+
+ #
+
+ # Delete all breakpoints, continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_bpmd_nofuturemodule_module_function.py b/src/ToolBox/SOS/tests/t_cmd_bpmd_nofuturemodule_module_function.py
new file mode 100644
index 0000000000..64efad7b65
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_bpmd_nofuturemodule_module_function.py
@@ -0,0 +1,48 @@
+import lldb
+import re
+import testutils as test
+
+# bpmd -nofuturemodule <module name> <managed function name>
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Process must be stopped here while libcoreclr loading.
+ # This test usually fails on release version of coreclr
+ # since we depend on 'LoadLibraryExW' symbol present.
+ test.assertEqual(process.GetState(), lldb.eStateStopped)
+
+ # The reason of this stop must be a breakpoint
+ test.assertEqual(process.GetSelectedThread().GetStopReason(),
+ lldb.eStopReasonBreakpoint)
+
+ ci.HandleCommand("bpmd -nofuturemodule " + assembly + " Test.Main", res)
+ out_msg = res.GetOutput()
+ err_msg = res.GetError()
+ print(out_msg)
+ print(err_msg)
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ # Output is not empty
+ # Should be at least 'Adding pending breakpoints...'
+ test.assertTrue(len(out_msg) == 0)
+
+ # Error message is empty
+ test.assertTrue(len(err_msg) == 0)
+
+ process.Continue()
+ # Process must be exited because of -nofuturemodule flag
+ test.assertEqual(process.GetState(), lldb.eStateExited)
+
+ # The reason of this stop must be a breakpoint
+ test.assertEqual(process.GetSelectedThread().GetStopReason(),
+ lldb.eStopReasonNone)
+
+ #
+
+ # Delete all breakpoints, continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_clrstack.py b/src/ToolBox/SOS/tests/t_cmd_clrstack.py
new file mode 100644
index 0000000000..28a1a8b950
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_clrstack.py
@@ -0,0 +1,36 @@
+import lldb
+import re
+import testutils as test
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("clrstack", res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ match = re.search('OS Thread Id', output)
+ # Specific string must be in the output
+ test.assertTrue(match)
+
+ match = re.search('Failed to start', output)
+ # Check if a fail was reported
+ test.assertFalse(match)
+
+ # TODO: test other use cases
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_clrthreads.py b/src/ToolBox/SOS/tests/t_cmd_clrthreads.py
new file mode 100644
index 0000000000..ff731da990
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_clrthreads.py
@@ -0,0 +1,31 @@
+import lldb
+import re
+import testutils as test
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("clrthreads", res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ # Specific string must be in the output
+ test.assertNotEqual(output.find("ThreadCount:"), -1)
+
+ # TODO: test other use cases
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_clru.py b/src/ToolBox/SOS/tests/t_cmd_clru.py
new file mode 100644
index 0000000000..81a583e963
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_clru.py
@@ -0,0 +1,46 @@
+import lldb
+import re
+import testutils as test
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("name2ee " + assembly + " Test.Main", res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ match = re.search('JITTED Code Address:\s+([0-9a-fA-F]+)', output)
+ # Line matched
+ test.assertTrue(match)
+
+ groups = match.groups()
+ # Match has a single subgroup
+ test.assertEqual(len(groups), 1)
+
+ jit_addr = groups[0]
+ # Address must be a hex number
+ test.assertTrue(test.is_hexnum(jit_addr))
+
+ ci.HandleCommand("clru " + jit_addr, res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ # TODO: test other use cases
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_dso.py b/src/ToolBox/SOS/tests/t_cmd_dso.py
new file mode 100644
index 0000000000..492204da5e
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_dso.py
@@ -0,0 +1,31 @@
+import lldb
+import re
+import testutils as test
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("dso", res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ # Specific string must be in the output
+ test.assertNotEqual(output.find("SP/REG"), -1)
+
+ # TODO: test other use cases
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_dumpclass.py b/src/ToolBox/SOS/tests/t_cmd_dumpclass.py
new file mode 100644
index 0000000000..6a69070eb5
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_dumpclass.py
@@ -0,0 +1,68 @@
+import lldb
+import re
+import testutils as test
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("name2ee " + assembly + " Test.Main", res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ match = re.search('MethodDesc:\s+([0-9a-fA-F]+)', output)
+ # Line matched
+ test.assertTrue(match)
+
+ groups = match.groups()
+ # Match has a single subgroup
+ test.assertEqual(len(groups), 1)
+
+ md_addr = groups[0]
+ # Address must be a hex number
+ test.assertTrue(test.is_hexnum(md_addr))
+
+ ci.HandleCommand("dumpmd " + md_addr, res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ match = re.search('Class:\s+([0-9a-fA-F]+)', output)
+ # Line matched
+ test.assertTrue(match)
+
+ groups = match.groups()
+ # Match has a single subgroup
+ test.assertEqual(len(groups), 1)
+
+ class_addr = groups[0]
+ # Address must be a hex number
+ test.assertTrue(test.is_hexnum(class_addr))
+
+ ci.HandleCommand("dumpmd " + class_addr, res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ # TODO: test other use cases
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_dumpheap.py b/src/ToolBox/SOS/tests/t_cmd_dumpheap.py
new file mode 100644
index 0000000000..8546de79e1
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_dumpheap.py
@@ -0,0 +1,31 @@
+import lldb
+import re
+import testutils as test
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("dumpheap", res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ # Specific string must be in the output
+ test.assertNotEqual(output.find("Address"), -1)
+
+ # TODO: test other use cases
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_dumpil.py b/src/ToolBox/SOS/tests/t_cmd_dumpil.py
new file mode 100644
index 0000000000..295cf19e6f
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_dumpil.py
@@ -0,0 +1,38 @@
+import lldb
+import re
+import testutils as test
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ md_addr = test.get_methoddesc(debugger, assembly, "Test.DumpIL")
+
+ ci.HandleCommand("dumpil " + md_addr, res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ insts = res.GetOutput()
+ print(insts)
+ # Function must have some instructions
+ test.assertTrue(len(insts) > 0)
+
+ match = re.search(r'IL_\w{4}:\sldstr.*test\sdumpil.*' +
+ r'IL_\w{4}:\scall.*System\.Console::WriteLine.*' +
+ r'IL_\w{4}:\sret',
+ insts.replace('\n', ' '))
+ # Must have ldstr, call and ret instructions
+ test.assertTrue(match)
+
+ # TODO: test other use cases
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_dumplog.py b/src/ToolBox/SOS/tests/t_cmd_dumplog.py
new file mode 100644
index 0000000000..ab33b66d4b
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_dumplog.py
@@ -0,0 +1,31 @@
+import lldb
+import re
+import testutils as test
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("dumplog", res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ # Specific string must be in the output
+ test.assertNotEqual(output.find(" dump "), -1)
+
+ # TODO: test other use cases
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_dumpmd.py b/src/ToolBox/SOS/tests/t_cmd_dumpmd.py
new file mode 100644
index 0000000000..0340eb5222
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_dumpmd.py
@@ -0,0 +1,46 @@
+import lldb
+import re
+import testutils as test
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("name2ee " + assembly + " Test.Main", res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ match = re.search('MethodDesc:\s+([0-9a-fA-F]+)', output)
+ # Line matched
+ test.assertTrue(match)
+
+ groups = match.groups()
+ # Match has a single subgroup
+ test.assertEqual(len(groups), 1)
+
+ md_addr = groups[0]
+ # Address must be a hex number
+ test.assertTrue(test.is_hexnum(md_addr))
+
+ ci.HandleCommand("dumpmd " + md_addr, res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ # TODO: test other use cases
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_dumpmodule.py b/src/ToolBox/SOS/tests/t_cmd_dumpmodule.py
new file mode 100644
index 0000000000..2dd004818a
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_dumpmodule.py
@@ -0,0 +1,46 @@
+import lldb
+import re
+import testutils as test
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("name2ee " + assembly + " Test.Main", res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ match = re.search('Module:\s+([0-9a-fA-F]+)', output)
+ # Line matched
+ test.assertTrue(match)
+
+ groups = match.groups()
+ # Match has a single subgroup
+ test.assertEqual(len(groups), 1)
+
+ md_addr = groups[0]
+ # Address must be a hex number
+ test.assertTrue(test.is_hexnum(md_addr))
+
+ ci.HandleCommand("dumpmodule " + md_addr, res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ # TODO: test other use cases
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_dumpmt.py b/src/ToolBox/SOS/tests/t_cmd_dumpmt.py
new file mode 100644
index 0000000000..059060b9b4
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_dumpmt.py
@@ -0,0 +1,68 @@
+import lldb
+import re
+import testutils as test
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("name2ee " + assembly + " Test.Main", res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ match = re.search('MethodDesc:\s+([0-9a-fA-F]+)', output)
+ # Line matched
+ test.assertTrue(match)
+
+ groups = match.groups()
+ # Match has a single subgroup
+ test.assertEqual(len(groups), 1)
+
+ md_addr = groups[0]
+ # Address must be a hex number
+ test.assertTrue(test.is_hexnum(md_addr))
+
+ ci.HandleCommand("dumpmd " + md_addr, res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ match = re.search('MethodTable:\s+([0-9a-fA-F]+)', output)
+ # Line matched
+ test.assertTrue(match)
+
+ groups = match.groups()
+ # Match has a single subgroup
+ test.assertEqual(len(groups), 1)
+
+ mt_addr = groups[0]
+ # Address must be a hex number
+ test.assertTrue(test.is_hexnum(mt_addr))
+
+ ci.HandleCommand("dumpmt " + mt_addr, res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ # TODO: test other use cases
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_dumpobj.py b/src/ToolBox/SOS/tests/t_cmd_dumpobj.py
new file mode 100644
index 0000000000..93f32cd9ab
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_dumpobj.py
@@ -0,0 +1,69 @@
+import lldb
+import re
+import testutils as test
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("dso", res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ # Get all objects
+ objects = []
+ for line in output.split('\n'):
+ match = re.match('([0-9a-fA-F]+)\s+([0-9a-fA-F]+)\s', line)
+ # Not all lines list objects
+ if match:
+ groups = match.groups()
+ # Match has exactly two subgroups
+ test.assertEqual(len(groups), 2)
+
+ obj_addr = groups[1]
+ # Address must be a hex number
+ test.assertTrue(test.is_hexnum(obj_addr))
+
+ objects.append(obj_addr)
+
+ # There must be at least one object
+ test.assertTrue(len(objects) > 0)
+
+ for obj in objects:
+ ci.HandleCommand("dumpobj " + obj, res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ match = re.search('Name:\s+\S+', output)
+ test.assertTrue(match)
+ match = re.search('MethodTable:\s+[0-9a-fA-F]+', output)
+ test.assertTrue(match)
+ match = re.search('EEClass:\s+[0-9a-fA-F]+', output)
+ test.assertTrue(match)
+ match = re.search('Size:\s+[0-9a-fA-F]+', output)
+ test.assertTrue(match)
+ match = re.search('Fields:', output)
+ test.assertTrue(match)
+
+ # TODO: test other use cases
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_dumpstack.py b/src/ToolBox/SOS/tests/t_cmd_dumpstack.py
new file mode 100644
index 0000000000..3e15f8b1d9
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_dumpstack.py
@@ -0,0 +1,31 @@
+import lldb
+import re
+import testutils as test
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("dumpstack", res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ # Specific string must be in the output
+ test.assertNotEqual(output.find("Test.Main()"), -1)
+
+ # TODO: test other use cases
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_eeheap.py b/src/ToolBox/SOS/tests/t_cmd_eeheap.py
new file mode 100644
index 0000000000..50d8977422
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_eeheap.py
@@ -0,0 +1,31 @@
+import lldb
+import re
+import testutils as test
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("eeheap", res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ # Specific string must be in the output
+ test.assertNotEqual(output.find("Loader Heap"), -1)
+
+ # TODO: test other use cases
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_eestack.py b/src/ToolBox/SOS/tests/t_cmd_eestack.py
new file mode 100644
index 0000000000..bc36592f87
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_eestack.py
@@ -0,0 +1,31 @@
+import lldb
+import re
+import testutils as test
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("eestack", res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ # Specific string must be in the output
+ test.assertNotEqual(output.find("Current frame"), -1)
+
+ # TODO: test other use cases
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_gcroot.py b/src/ToolBox/SOS/tests/t_cmd_gcroot.py
new file mode 100644
index 0000000000..e6b727c9a1
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_gcroot.py
@@ -0,0 +1,61 @@
+import lldb
+import re
+import testutils as test
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("dso", res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ # Get all objects
+ objects = []
+ for line in output.split('\n'):
+ match = re.match('([0-9a-fA-F]+)\s+([0-9a-fA-F]+)\s', line)
+ # Not all lines list objects
+ if match:
+ groups = match.groups()
+ # Match has exactly two subgroups
+ test.assertEqual(len(groups), 2)
+
+ obj_addr = groups[1]
+ # Address must be a hex number
+ test.assertTrue(test.is_hexnum(obj_addr))
+
+ objects.append(obj_addr)
+
+ # There must be at least one object
+ test.assertTrue(len(objects) > 0)
+
+ for obj in objects:
+ ci.HandleCommand("gcroot " + obj, res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ match = re.search('Found', output)
+ test.assertTrue(match)
+
+ # TODO: test other use cases
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_histclear.py b/src/ToolBox/SOS/tests/t_cmd_histclear.py
new file mode 100644
index 0000000000..db29bd85f7
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_histclear.py
@@ -0,0 +1,31 @@
+import lldb
+import re
+import testutils as test
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("histclear", res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ # Specific string must be in the output
+ test.assertNotEqual(output.find("Completed successfully."), -1)
+
+ # TODO: test other use cases
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_histinit.py b/src/ToolBox/SOS/tests/t_cmd_histinit.py
new file mode 100644
index 0000000000..51191283c7
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_histinit.py
@@ -0,0 +1,31 @@
+import lldb
+import re
+import testutils as test
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("histinit", res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ # Specific string must be in the output
+ test.assertNotEqual(output.find("STRESS LOG:"), -1)
+
+ # TODO: test other use cases
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_histobj.py b/src/ToolBox/SOS/tests/t_cmd_histobj.py
new file mode 100644
index 0000000000..c88bdac16e
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_histobj.py
@@ -0,0 +1,61 @@
+import lldb
+import re
+import testutils as test
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("dso", res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ # Get all objects
+ objects = []
+ for line in output.split('\n'):
+ match = re.match('([0-9a-fA-F]+)\s+([0-9a-fA-F]+)\s', line)
+ # Not all lines list objects
+ if match:
+ groups = match.groups()
+ # Match has exactly two subgroups
+ test.assertEqual(len(groups), 2)
+
+ obj_addr = groups[1]
+ # Address must be a hex number
+ test.assertTrue(test.is_hexnum(obj_addr))
+
+ objects.append(obj_addr)
+
+ # There must be at least one object
+ test.assertTrue(len(objects) > 0)
+
+ for obj in objects:
+ ci.HandleCommand("histobj " + obj, res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ match = re.search('GCCount', output)
+ test.assertTrue(match)
+
+ # TODO: test other use cases
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_histobjfind.py b/src/ToolBox/SOS/tests/t_cmd_histobjfind.py
new file mode 100644
index 0000000000..ffe5dbf52d
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_histobjfind.py
@@ -0,0 +1,61 @@
+import lldb
+import re
+import testutils as test
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("dso", res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ # Get all objects
+ objects = []
+ for line in output.split('\n'):
+ match = re.match('([0-9a-fA-F]+)\s+([0-9a-fA-F]+)\s', line)
+ # Not all lines list objects
+ if match:
+ groups = match.groups()
+ # Match has exactly two subgroups
+ test.assertEqual(len(groups), 2)
+
+ obj_addr = groups[1]
+ # Address must be a hex number
+ test.assertTrue(test.is_hexnum(obj_addr))
+
+ objects.append(obj_addr)
+
+ # There must be at least one object
+ test.assertTrue(len(objects) > 0)
+
+ for obj in objects:
+ ci.HandleCommand("histobjfind " + obj, res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ match = re.search('GCCount', output)
+ test.assertTrue(match)
+
+ # TODO: test other use cases
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_histroot.py b/src/ToolBox/SOS/tests/t_cmd_histroot.py
new file mode 100644
index 0000000000..7b73caafda
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_histroot.py
@@ -0,0 +1,61 @@
+import lldb
+import re
+import testutils as test
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("dso", res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ # Get all objects
+ objects = []
+ for line in output.split('\n'):
+ match = re.match('([0-9a-fA-F]+)\s+([0-9a-fA-F]+)\s', line)
+ # Not all lines list objects
+ if match:
+ groups = match.groups()
+ # Match has exactly two subgroups
+ test.assertEqual(len(groups), 2)
+
+ obj_addr = groups[1]
+ # Address must be a hex number
+ test.assertTrue(test.is_hexnum(obj_addr))
+
+ objects.append(obj_addr)
+
+ # There must be at least one object
+ test.assertTrue(len(objects) > 0)
+
+ for obj in objects:
+ ci.HandleCommand("histroot " + obj, res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ match = re.search('GCCount', output)
+ test.assertTrue(match)
+
+ # TODO: test other use cases
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_ip2md.py b/src/ToolBox/SOS/tests/t_cmd_ip2md.py
new file mode 100644
index 0000000000..1384c38f0c
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_ip2md.py
@@ -0,0 +1,53 @@
+import lldb
+import re
+import testutils as test
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("name2ee " + assembly + " Test.Main", res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ match = re.search('JITTED Code Address:\s+([0-9a-fA-F]+)', output)
+ # Line matched
+ test.assertTrue(match)
+
+ groups = match.groups()
+ # Match has a single subgroup
+ test.assertEqual(len(groups), 1)
+
+ jit_addr = groups[0]
+ # Address must be a hex number
+ test.assertTrue(test.is_hexnum(jit_addr))
+
+ ci.HandleCommand("ip2md " + jit_addr, res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ # Specific string must be in the output
+ test.assertNotEqual(output.find("MethodDesc:"), -1)
+
+ # TODO: test other use cases
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_name2ee.py b/src/ToolBox/SOS/tests/t_cmd_name2ee.py
new file mode 100644
index 0000000000..b617020e36
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_name2ee.py
@@ -0,0 +1,46 @@
+import lldb
+import re
+import testutils as test
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("name2ee " + assembly + " Test.Main", res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ match = re.search('Module:\s+[0-9a-fA-F]+', output)
+ test.assertTrue(match)
+ match = re.search('Assembly:\s+\S+', output)
+ test.assertTrue(match)
+ match = re.search('Token:\s+[0-9a-fA-F]+', output)
+ test.assertTrue(match)
+ match = re.search('MethodDesc:\s+[0-9a-fA-F]+', output)
+ test.assertTrue(match)
+ match = re.search('Name:\s+\S+', output)
+ test.assertTrue(match)
+
+ process.Continue()
+ # Process must exit
+ test.assertEqual(process.GetState(), lldb.eStateExited)
+
+ # Process must exit with zero code
+ test.assertEqual(process.GetExitStatus(), 0)
+
+ # TODO: test other use cases
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_pe.py b/src/ToolBox/SOS/tests/t_cmd_pe.py
new file mode 100644
index 0000000000..0a87014934
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_pe.py
@@ -0,0 +1,28 @@
+import lldb
+import re
+import testutils as test
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("dso", res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ # TODO: test other use cases
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_sos.py b/src/ToolBox/SOS/tests/t_cmd_sos.py
new file mode 100644
index 0000000000..b407491d79
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_sos.py
@@ -0,0 +1,31 @@
+import lldb
+import re
+import testutils as test
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("sos", res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ # Specific string must be in the output
+ test.assertNotEqual(output.find("SOS"), -1)
+
+ # TODO: test other use cases
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/t_cmd_soshelp.py b/src/ToolBox/SOS/tests/t_cmd_soshelp.py
new file mode 100644
index 0000000000..8bb51dad5a
--- /dev/null
+++ b/src/ToolBox/SOS/tests/t_cmd_soshelp.py
@@ -0,0 +1,31 @@
+import lldb
+import re
+import testutils as test
+
+
+def runScenario(assembly, debugger, target):
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+ ci = debugger.GetCommandInterpreter()
+
+ # Run debugger, wait until libcoreclr is loaded,
+ # set breakpoint at Test.Main and stop there
+ test.stop_in_main(debugger, assembly)
+
+ ci.HandleCommand("soshelp", res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ test.assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ test.assertTrue(len(output) > 0)
+
+ # Specific string must be in the output
+ test.assertNotEqual(output.find("soshelp <functionname>"), -1)
+
+ # TODO: test other use cases
+
+ # Continue current process and checks its exit code
+ test.exit_lldb(debugger, assembly)
diff --git a/src/ToolBox/SOS/tests/test_libsosplugin.py b/src/ToolBox/SOS/tests/test_libsosplugin.py
index e4f59ebbcf..e5a5906264 100644
--- a/src/ToolBox/SOS/tests/test_libsosplugin.py
+++ b/src/ToolBox/SOS/tests/test_libsosplugin.py
@@ -1,3 +1,4 @@
+from __future__ import print_function
import unittest
import argparse
import re
@@ -5,80 +6,279 @@ import tempfile
import subprocess
import threading
import os
-import os.path
import sys
+import inspect
+
+lldb = ''
+clrdir = ''
+workdir = ''
+corerun = ''
+sosplugin = ''
+assembly = ''
+fail_flag = ''
+fail_flag_lldb = ''
+summary_file = ''
+timeout = 0
+regex = ''
+repeat = 0
+
+
+def runWithTimeout(cmd):
+ p = None
+
+ def run():
+ global p
+ p = subprocess.Popen(cmd, shell=True)
+ p.communicate()
+
+ thread = threading.Thread(target=run)
+ thread.start()
+
+ thread.join(timeout)
+ if thread.is_alive():
+ with open(summary_file, 'a+') as summary:
+ print('Timeout!', file=summary)
+ p.kill()
+ thread.join()
+
-assemblyName=''
-clrArgs=''
-fail_flag='/tmp/fail_flag'
-
-# helper functions
-
-def prepareScenarioFile(moduleName):
- global assemblyName
- #create a temporary scenario file
- fd, scenarioFileName = tempfile.mkstemp()
- scenarioFile = open(scenarioFileName, 'w')
- scenarioFile.write('script from runprocess import run\n')
- scenarioFile.write('script run("'+assemblyName+'", "'+moduleName+'")\n')
- scenarioFile.write('quit\n')
- scenarioFile.close()
- os.close(fd)
- return scenarioFileName
-
-def runWithTimeout(cmd, timeout):
- d = {'process': None}
- def run():
- d['process'] = subprocess.Popen(cmd, shell=True)
- d['process'].communicate()
-
- thread = threading.Thread(target=run)
- thread.start()
-
- thread.join(timeout)
- if thread.is_alive():
- d['process'].terminate()
- thread.join()
-
-# Test class
class TestSosCommands(unittest.TestCase):
- def do_test(self, command):
- global clrArgs
- global fail_flag
- filename = prepareScenarioFile(command)
- cmd = "lldb --source "+filename+" -b -K \"OnCrash.do\" -- "+clrArgs+" > "+command+".log 2>"+command+".log.2"
- runWithTimeout(cmd, 120)
- self.assertFalse(os.path.isfile(fail_flag))
- os.unlink(filename)
+ def do_test(self, command):
+ open(fail_flag, 'a').close()
+ try:
+ os.unlink(fail_flag_lldb)
+ except:
+ pass
+
+ cmd = (('%s -b ' % lldb) +
+ ("-k \"script open('%s', 'a').close()\" " % fail_flag_lldb) +
+ ("-k 'quit' ") +
+ ("--no-lldbinit ") +
+ ("-O \"plugin load %s \" " % sosplugin) +
+ ("-o \"script import testutils as test\" ") +
+ ("-o \"script test.fail_flag = '%s'\" " % fail_flag) +
+ ("-o \"script test.summary_file = '%s'\" " % summary_file) +
+ ("-o \"script test.run('%s', '%s')\" " % (assembly, command)) +
+ ("-o \"quit\" ") +
+ (" -- %s %s > %s.log 2> %s.log.2" % (corerun, assembly,
+ command, command)))
+
+ runWithTimeout(cmd)
+ self.assertFalse(os.path.isfile(fail_flag))
+ self.assertFalse(os.path.isfile(fail_flag_lldb))
+
+ try:
+ os.unlink(fail_flag)
+ except:
+ pass
+ try:
+ os.unlink(fail_flag_lldb)
+ except:
+ pass
+
+ def t_cmd_bpmd_nofuturemodule_module_function(self):
+ self.do_test('t_cmd_bpmd_nofuturemodule_module_function')
+
+ def t_cmd_bpmd_module_function(self):
+ self.do_test('t_cmd_bpmd_module_function')
+
+ def t_cmd_bpmd_module_function_iloffset(self):
+ self.do_test('t_cmd_bpmd_module_function_iloffset')
+
+ def t_cmd_bpmd_methoddesc(self):
+ self.do_test('t_cmd_bpmd_methoddesc')
+
+ def t_cmd_bpmd_clearall(self):
+ self.do_test('t_cmd_bpmd_clearall')
+
+ def t_cmd_clrstack(self):
+ self.do_test('t_cmd_clrstack')
+
+ def t_cmd_clrthreads(self):
+ self.do_test('t_cmd_clrthreads')
+
+ def t_cmd_clru(self):
+ self.do_test('t_cmd_clru')
+
+ def t_cmd_dumpclass(self):
+ self.do_test('t_cmd_dumpclass')
+
+ def t_cmd_dumpheap(self):
+ self.do_test('t_cmd_dumpheap')
+
+ def t_cmd_dumpil(self):
+ self.do_test('t_cmd_dumpil')
+
+ def t_cmd_dumplog(self):
+ self.do_test('t_cmd_dumplog')
+
+ def t_cmd_dumpmd(self):
+ self.do_test('t_cmd_dumpmd')
+
+ def t_cmd_dumpmodule(self):
+ self.do_test('t_cmd_dumpmodule')
+
+ def t_cmd_dumpmt(self):
+ self.do_test('t_cmd_dumpmt')
+
+ def t_cmd_dumpobj(self):
+ self.do_test('t_cmd_dumpobj')
+
+ def t_cmd_dumpstack(self):
+ self.do_test('t_cmd_dumpstack')
+
+ def t_cmd_dso(self):
+ self.do_test('t_cmd_dso')
+
+ def t_cmd_eeheap(self):
+ self.do_test('t_cmd_eeheap')
- def test_dumpmodule(self):
- self.do_test("dumpmodule")
+ def t_cmd_eestack(self):
+ self.do_test('t_cmd_eestack')
+
+ def t_cmd_gcroot(self):
+ self.do_test('t_cmd_gcroot')
+
+ def t_cmd_ip2md(self):
+ self.do_test('t_cmd_ip2md')
+
+ def t_cmd_name2ee(self):
+ self.do_test('t_cmd_name2ee')
+
+ def t_cmd_pe(self):
+ self.do_test('t_cmd_pe')
+
+ def t_cmd_histclear(self):
+ self.do_test('t_cmd_histclear')
+
+ def t_cmd_histinit(self):
+ self.do_test('t_cmd_histinit')
+
+ def t_cmd_histobj(self):
+ self.do_test('t_cmd_histobj')
+
+ def t_cmd_histobjfind(self):
+ self.do_test('t_cmd_histobjfind')
+
+ def t_cmd_histroot(self):
+ self.do_test('t_cmd_histroot')
+
+ def t_cmd_sos(self):
+ self.do_test('t_cmd_sos')
+
+ def t_cmd_soshelp(self):
+ self.do_test('t_cmd_soshelp')
+
+
+def generate_report():
+ report = [{'name': 'TOTAL', True: 0, False: 0, 'completed': True}]
+ fail_messages = []
+
+ if not os.path.isfile(summary_file):
+ print('No summary file to process!')
+ return
+
+ with open(summary_file, 'r') as summary:
+ for line in summary:
+ if line.startswith('new_suite: '):
+ report.append({'name': line.split()[-1], True: 0, False: 0,
+ 'completed': False, 'timeout': False})
+ elif line.startswith('True'):
+ report[-1][True] += 1
+ elif line.startswith('False'):
+ report[-1][False] += 1
+ elif line.startswith('Completed!'):
+ report[-1]['completed'] = True
+ elif line.startswith('Timeout!'):
+ report[-1]['timeout'] = True
+ elif line.startswith('!!! '):
+ fail_messages.append(line.rstrip('\n'))
+
+ for suite in report[1:]:
+ report[0][True] += suite[True]
+ report[0][False] += suite[False]
+ report[0]['completed'] &= suite['completed']
+
+ for line in fail_messages:
+ print(line)
+
+ print()
+ print('=' * 79)
+ print('{:72} {:6}'.format('Test suite', 'Result'))
+ print('-' * 79)
+ for suite in report[1:]:
+ if suite['timeout']:
+ result = 'Timeout'
+ elif suite[False]:
+ result = 'Fail'
+ elif not suite['completed']:
+ result = 'Crash'
+ elif suite[True]:
+ result = 'Success'
+ else:
+ result = 'Please, report'
+ print('{:68} {:>10}'.format(suite['name'], result))
+ print('=' * 79)
- def test_dumpil(self):
- self.do_test("dumpil")
-
if __name__ == '__main__':
- parser = argparse.ArgumentParser()
- parser.add_argument('--clr-args', default='')
- parser.add_argument('unittest_args', nargs='*')
-
- args = parser.parse_args()
-
- clrArgs = args.clr_args
- print("ClrArgs: " + clrArgs)
- # find assembly name among lldb arguments
- assembly_regexp = re.compile("([^\s]+\.exe)")
- assemblyMatch = assembly_regexp.search(clrArgs)
- if assemblyMatch is not None:
- assemblyName = assemblyMatch.group(1)
- else:
- print("Assembly not recognized")
- exit(1)
-
- print("Assembly name: "+assemblyName)
- sys.argv[1:] = args.unittest_args
- suite = unittest.TestLoader().loadTestsFromTestCase(TestSosCommands)
- unittest.TextTestRunner(verbosity=2).run(suite)
- os.unlink(fail_flag) \ No newline at end of file
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--lldb', default='lldb')
+ parser.add_argument('--clrdir', default='.')
+ parser.add_argument('--workdir', default='.')
+ parser.add_argument('--assembly', default='Test.exe')
+ parser.add_argument('--timeout', default=90)
+ parser.add_argument('--regex', default='t_cmd_')
+ parser.add_argument('--repeat', default=1)
+ parser.add_argument('unittest_args', nargs='*')
+
+ args = parser.parse_args()
+
+ lldb = args.lldb
+ clrdir = args.clrdir
+ workdir = args.workdir
+ assembly = args.assembly
+ timeout = int(args.timeout)
+ regex = args.regex
+ repeat = int(args.repeat)
+ print("lldb: %s" % lldb)
+ print("clrdir: %s" % clrdir)
+ print("workdir: %s" % workdir)
+ print("assembly: %s" % assembly)
+ print("timeout: %i" % timeout)
+ print("regex: %s" % regex)
+ print("repeat: %i" % repeat)
+
+ corerun = os.path.join(clrdir, 'corerun')
+ sosplugin = os.path.join(clrdir, 'libsosplugin.so')
+ if os.name != 'posix':
+ print('Not implemented: corerun.exe, sosplugin.dll?')
+ exit(1)
+
+ print("corerun: %s" % corerun)
+ print("sosplugin: %s" % sosplugin)
+
+ fail_flag = os.path.join(workdir, 'fail_flag')
+ fail_flag_lldb = os.path.join(workdir, 'fail_flag.lldb')
+
+ print("fail_flag: %s" % fail_flag)
+ print("fail_flag_lldb: %s" % fail_flag_lldb)
+
+ summary_file = os.path.join(workdir, 'summary')
+ print("summary_file: %s" % summary_file)
+
+ try:
+ os.unlink(summary_file)
+ except:
+ pass
+
+ sys.argv[1:] = args.unittest_args
+ suite = unittest.TestSuite()
+ all_tests = inspect.getmembers(TestSosCommands, predicate=inspect.ismethod)
+ for (test_name, test_func) in all_tests:
+ if re.match(regex, test_name):
+ suite.addTest(TestSosCommands(test_name))
+ unittest.TextTestRunner(verbosity=1).run(suite)
+
+ generate_report()
diff --git a/src/ToolBox/SOS/tests/testutils.py b/src/ToolBox/SOS/tests/testutils.py
index 1ddb6560e6..1f784b48f6 100644
--- a/src/ToolBox/SOS/tests/testutils.py
+++ b/src/ToolBox/SOS/tests/testutils.py
@@ -1,40 +1,206 @@
+from __future__ import print_function
import lldb
import re
+import inspect
+import sys
+import os
+import importlib
+
+summary_file = ''
+fail_flag = ''
+
+failed = False
+
+
+def assertCommon(passed, fatal):
+ global failed
+ with open(summary_file, 'a+') as summary:
+ print(bool(passed), file=summary)
+ if (not passed):
+ failed = True
+ print('!!! test failed:', file=summary)
+ for s in inspect.stack()[2:]:
+ print("!!! %s:%i" % (s[1], s[2]), file=summary)
+ print("!!! %s" % s[4][0], file=summary)
+ if re.match('\W*t_\w+\.py$', s[1]):
+ break
+ print('!!! ', file=summary)
+
+ if fatal:
+ exit(1)
+
+
+def assertTrue(x, fatal=True):
+ passed = bool(x)
+ assertCommon(passed, fatal)
+
+
+def assertFalse(x, fatal=True):
+ passed = not bool(x)
+ assertCommon(passed, fatal)
+
+
+def assertEqual(x, y, fatal=True):
+ passed = (x == y)
+ if not passed:
+ print(str(x), ' != ', str(y))
+ assertCommon(passed, fatal)
+
+
+def assertNotEqual(x, y, fatal=True):
+ passed = (x != y)
+ if not passed:
+ print(str(x), ' == ', str(y))
+ assertCommon(passed, fatal)
+
def checkResult(res):
- if not res.Succeeded():
- print(res.GetOutput())
- print(res.GetError())
- exit(1)
+ if not res.Succeeded():
+ print(res.GetOutput())
+ print(res.GetError())
+ exit(1)
+
+
+def is_hexnum(s):
+ try:
+ int(s, 16)
+ return True
+ except ValueError:
+ return False
+
def exec_and_find(commandInterpreter, cmd, regexp):
- res = lldb.SBCommandReturnObject()
- commandInterpreter.HandleCommand(cmd, res)
- checkResult(res)
-
- expr = re.compile(regexp)
- addr = None
-
- print(res.GetOutput())
- lines = res.GetOutput().splitlines()
- for line in lines:
- match = expr.match(line)
- if match is not None:
- addr = match.group(1)
- break
-
- print("Found addr: " + str(addr))
- return addr
-
-def stop_in_main(commandInterpreter, process, assemblyName):
- res = lldb.SBCommandReturnObject()
- commandInterpreter.HandleCommand("bpmd " + assemblyName + " Program.Main", res)
- checkResult(res)
- print(res.GetOutput())
- print(res.GetError())
- res.Clear()
-
-
- # Use Python API to continue the process. The listening thread should be
- # able to receive the state changed events.
- process.Continue() \ No newline at end of file
+ res = lldb.SBCommandReturnObject()
+ commandInterpreter.HandleCommand(cmd, res)
+ checkResult(res)
+
+ expr = re.compile(regexp)
+ addr = None
+
+ print(res.GetOutput())
+ lines = res.GetOutput().splitlines()
+ for line in lines:
+ match = expr.match(line)
+ if match:
+ addr = match.group(1)
+ break
+
+ print("Found addr: " + str(addr))
+ return addr
+
+
+def stop_in_main(debugger, assembly):
+ ci = debugger.GetCommandInterpreter()
+ target = debugger.GetSelectedTarget()
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+
+ # Process must be stopped here while libcoreclr loading.
+ # This test usually fails on release version of coreclr
+ # since we depend on 'LoadLibraryExW' symbol present.
+ assertEqual(process.GetState(), lldb.eStateStopped)
+
+ # The reason of this stop must be a breakpoint
+ assertEqual(process.GetSelectedThread().GetStopReason(),
+ lldb.eStopReasonBreakpoint)
+
+ ci.HandleCommand("bpmd " + assembly + " Test.Main", res)
+ out_msg = res.GetOutput()
+ err_msg = res.GetError()
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ assertTrue(res.Succeeded())
+
+ # Output is not empty
+ # Should be at least 'Adding pending breakpoints...'
+ assertTrue(len(out_msg) > 0)
+
+ # Error message is empty
+ assertTrue(len(err_msg) == 0)
+
+ process.Continue()
+ # Process must be stopped here if bpmd works at all
+ assertEqual(process.GetState(), lldb.eStateStopped)
+
+ # The reason of this stop must be a breakpoint
+ assertEqual(process.GetSelectedThread().GetStopReason(),
+ lldb.eStopReasonBreakpoint)
+
+
+def exit_lldb(debugger, assembly):
+ ci = debugger.GetCommandInterpreter()
+ target = debugger.GetSelectedTarget()
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+
+ ci.HandleCommand("breakpoint delete --force", res)
+ out_msg = res.GetOutput()
+ err_msg = res.GetError()
+ print(out_msg)
+ print(err_msg)
+ # Interpreter must have this command and able to run it
+ # assertTrue(res.Succeeded())
+
+ process.Continue()
+ # Process must exit
+ assertEqual(process.GetState(), lldb.eStateExited)
+
+ # Process must exit with zero code
+ assertEqual(process.GetExitStatus(), 0)
+
+
+def get_methoddesc(debugger, assembly, funcname):
+ ci = debugger.GetCommandInterpreter()
+ target = debugger.GetSelectedTarget()
+ process = target.GetProcess()
+ res = lldb.SBCommandReturnObject()
+
+ ci.HandleCommand("name2ee %s %s" % (assembly, funcname), res)
+ print(res.GetOutput())
+ print(res.GetError())
+ # Interpreter must have this command and able to run it
+ assertTrue(res.Succeeded())
+
+ output = res.GetOutput()
+ # Output is not empty
+ assertTrue(len(output) > 0)
+
+ match = re.search('MethodDesc:\s+([0-9a-fA-F]+)', output)
+ # Line matched
+ assertTrue(match)
+
+ groups = match.groups()
+ # Match has a single subgroup
+ assertEqual(len(groups), 1)
+
+ md_addr = groups[0]
+ # Address must be a hex number
+ assertTrue(is_hexnum(md_addr))
+
+ return md_addr
+
+
+def run(assembly, module):
+ with open(summary_file, 'a+') as summary:
+ print('new_suite: %s' % module, file=summary)
+
+ debugger = lldb.debugger
+
+ debugger.SetAsync(False)
+ target = lldb.target
+
+ debugger.HandleCommand("breakpoint set --one-shot --name coreclr_execute_assembly")
+ debugger.HandleCommand("process launch")
+
+ # run the scenario
+ print("starting scenario...")
+ i = importlib.import_module(module)
+ scenarioResult = i.runScenario(os.path.basename(assembly), debugger,
+ target)
+
+ if (target.GetProcess().GetExitStatus() == 0) and not failed:
+ os.unlink(fail_flag)
+
+ with open(summary_file, 'a+') as summary:
+ print('Completed!', file=summary)
diff --git a/src/ToolBox/dirs.proj b/src/ToolBox/dirs.proj
index 9ac295d8d5..e16ddd108c 100644
--- a/src/ToolBox/dirs.proj
+++ b/src/ToolBox/dirs.proj
@@ -79,7 +79,9 @@
</ProjectFile>
<ProjectFile Include="urtui\dirs.proj"/>
<ProjectFile Include="winmdexp\dirs.proj" />
+<!--
<ProjectFile Include="winverify\dirs.proj" />
+-->
<ProjectFile Include="wpf\wpf.proj" Condition="'$(BuildArchitecture)' == 'i386' or '$(BuildArchitecture)' == 'amd64'" />
<ProjectFile Include="PdbTypeMatch\PdbTypeMatch.nativeproj" Condition="'$(BuildArchitecture)' == 'i386' and '$(_BuildType)' == 'ret'" >
<ProductGroups>PK</ProductGroups>
diff --git a/src/ToolBox/superpmi/superpmi-shared/compileresult.h b/src/ToolBox/superpmi/superpmi-shared/compileresult.h
index 8fc3f7a352..87853f4cd3 100644
--- a/src/ToolBox/superpmi/superpmi-shared/compileresult.h
+++ b/src/ToolBox/superpmi/superpmi-shared/compileresult.h
@@ -203,7 +203,7 @@ public:
void recReportInliningDecision(CORINFO_METHOD_HANDLE inlinerHnd, CORINFO_METHOD_HANDLE inlineeHnd, CorInfoInline inlineResult, const char * reason);
void dmpReportInliningDecision(DWORD key, const Agnostic_ReportInliningDecision& value);
- CorInfoInline CompileResult::repReportInliningDecision(CORINFO_METHOD_HANDLE inlinerHnd, CORINFO_METHOD_HANDLE inlineeHnd);
+ CorInfoInline repReportInliningDecision(CORINFO_METHOD_HANDLE inlinerHnd, CORINFO_METHOD_HANDLE inlineeHnd);
void recSetEHcount(unsigned cEH);
void dmpSetEHcount(DWORD key, DWORD value);
diff --git a/src/ToolBox/superpmi/superpmi-shared/icorjitcompilerimpl.h b/src/ToolBox/superpmi/superpmi-shared/icorjitcompilerimpl.h
index 671b45b392..e1190d7ab6 100644
--- a/src/ToolBox/superpmi/superpmi-shared/icorjitcompilerimpl.h
+++ b/src/ToolBox/superpmi/superpmi-shared/icorjitcompilerimpl.h
@@ -57,7 +57,11 @@ 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 6eb862c8b8..b847d9bc50 100644
--- a/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h
+++ b/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h
@@ -653,7 +653,7 @@ public:
// in the code are. The native compiler will ensure that these places
// have a corresponding break point in native code.
//
- // Note that unless CORJIT_FLG_DEBUG_CODE is specified, this function will
+ // Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will
// be used only as a hint and the native compiler should not change its
// code generation.
void getBoundaries(
@@ -683,7 +683,7 @@ public:
// under debugging, the JIT needs to keep them live over their
// entire scope so that they can be inspected.
//
- // Note that unless CORJIT_FLG_DEBUG_CODE is specified, this function will
+ // Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will
// be used only as a hint and the native compiler should not change its
// code generation.
void getVars(
diff --git a/src/ToolBox/superpmi/superpmi-shared/logging.cpp b/src/ToolBox/superpmi/superpmi-shared/logging.cpp
index 5f7aa48a4f..69c321bb39 100644
--- a/src/ToolBox/superpmi/superpmi-shared/logging.cpp
+++ b/src/ToolBox/superpmi/superpmi-shared/logging.cpp
@@ -262,9 +262,9 @@ void Logger::LogVprintf(const char *function, const char *file, int line,
const char *timeStr = "";
#endif // FEATURE_PAL
- const char *logEntryFmtStr = "%s - %s [%s:%d] - %s - %s\r\n";
- size_t logEntryBuffSize = _snprintf(nullptr, 0, logEntryFmtStr,
- timeStr, function, file, line, logLevelStr, fullMsg) + 1;
+ const char logEntryFmtStr[] = "%s - %s [%s:%d] - %s - %s\r\n";
+ size_t logEntryBuffSize = sizeof(logEntryFmtStr) + strlen(timeStr) + strlen(function) +
+ strlen(file) + 10 + strlen(logLevelStr) + strlen(fullMsg);
char *logEntry = new char[logEntryBuffSize];
sprintf_s(logEntry, logEntryBuffSize, logEntryFmtStr,
diff --git a/src/ToolBox/superpmi/superpmi-shared/lwmlist.h b/src/ToolBox/superpmi/superpmi-shared/lwmlist.h
index 774e732620..de0db3a9bb 100644
--- a/src/ToolBox/superpmi/superpmi-shared/lwmlist.h
+++ b/src/ToolBox/superpmi/superpmi-shared/lwmlist.h
@@ -85,6 +85,7 @@ LWM(GetFunctionFixedEntryPoint, DWORDLONG, Agnostic_CORINFO_CONST_LOOKUP)
LWM(GetGSCookie, DWORD, DLDL)
LWM(GetHelperFtn, DWORD, DLDL)
LWM(GetHelperName, DWORD, DWORD)
+LWM(GetHFAType, DWORDLONG, DWORD)
LWM(GetInlinedCallFrameVptr, DWORD, DLDL)
LWM(GetIntConfigValue, Agnostic_ConfigIntInfo, DWORD)
LWM(GetIntrinsicID, DWORDLONG, DD)
diff --git a/src/ToolBox/superpmi/superpmi-shared/mclist.cpp b/src/ToolBox/superpmi/superpmi-shared/mclist.cpp
index 6a6f8701bf..511893fc96 100644
--- a/src/ToolBox/superpmi/superpmi-shared/mclist.cpp
+++ b/src/ToolBox/superpmi/superpmi-shared/mclist.cpp
@@ -237,7 +237,7 @@ void MCList::AddMethodToMCL(int methodIndex)
DWORD charCount = 0;
DWORD bytesWritten = 0;
- charCount = sprintf(strMethodIndex, "%d\r\n", methodIndex);
+ charCount = sprintf_s(strMethodIndex, sizeof(strMethodIndex), "%d\r\n", methodIndex);
if (!WriteFile(hMCLFile, strMethodIndex, charCount, &bytesWritten, nullptr) || bytesWritten != charCount)
{
diff --git a/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
index 2c46065b48..5768d38569 100644
--- a/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
+++ b/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
@@ -744,7 +744,7 @@ void MethodContext::recCompileMethod(CORINFO_METHOD_INFO *info, unsigned flags)
void MethodContext::dmpCompileMethod(DWORD key, const Agnostic_CompileMethod& value)
{
printf("CompiledMethod key %u, value ftn-%016llX scp-%016llX ilo-%u ils-%u ms-%u ehc-%u opt-%u rk-%u "
- "args{cc-%u rc-%016llX rts-%016llX rt-%u(%s) flg-%08X nA-%u cc-%u ci-%u mc-%u mi-%u arg-%016llX cb-%u pSig-%u scp-%016llX tok-%08X} "
+ "args{cc-%u rc-%016llX rts-%016llX rt-%u(%s) flg-%08X nA-%u cc-%u ci-%u mc-%u mi-%u arg-%016llX cb-%u pSig-%u scp-%016llX tok-%08X} "
"locals{cc-%u rc-%016llX rts-%016llX rt-%u(%s) flg-%08X nA-%u cc-%u ci-%u mc-%u mi-%u arg-%016llX cb-%u pSig-%u scp-%016llX tok-%08X} "
"flg-%08X",
key,
@@ -1098,8 +1098,8 @@ void MethodContext::recGetJitFlags(CORJIT_FLAGS *jitFlags, DWORD sizeInBytes, DW
}
void MethodContext::dmpGetJitFlags(DWORD key, DD value)
{
- CORJIT_FLAGS *flags = (CORJIT_FLAGS*)GetJitFlags->GetBuffer(value.A);
- printf("GetJitFlags key %u sizeInBytes-%u corJitFlags-%08X corJitFlags2-%08X", key, value.B, flags->corJitFlags, flags->corJitFlags2);
+ CORJIT_FLAGS *jitflags = (CORJIT_FLAGS*)GetJitFlags->GetBuffer(value.A);
+ printf("GetJitFlags key %u sizeInBytes-%u jitFlags-%016llX", key, value.B, jitflags->GetFlagsRaw());
GetJitFlags->Unlock();
}
DWORD MethodContext::repGetJitFlags(CORJIT_FLAGS *jitFlags, DWORD sizeInBytes)
@@ -2842,6 +2842,34 @@ CORINFO_CLASS_HANDLE MethodContext::repGetArgClass(CORINFO_SIG_INFO* sig, CORINF
return (CORINFO_CLASS_HANDLE)value.result;
}
+void MethodContext::recGetHFAType(CORINFO_CLASS_HANDLE clsHnd, CorInfoType result)
+{
+ if (GetHFAType == nullptr)
+ GetHFAType = new LightWeightMap<DWORDLONG, DWORD>();
+
+ GetHFAType->Add((DWORDLONG)clsHnd, (DWORD)result);
+ DEBUG_REC(dmpGetHFAType((DWORDLONG)clsHnd, (DWORD)result));
+ return;
+}
+
+void MethodContext::dmpGetHFAType(DWORDLONG key, DWORD value)
+{
+ printf("GetHFAType key %016llX, value %u ", key, value);
+ return;
+}
+
+CorInfoType MethodContext::repGetHFAType(CORINFO_CLASS_HANDLE clsHnd)
+{
+ DWORD value;
+
+ AssertCodeMsg(GetHFAType != nullptr, EXCEPTIONCODE_MC, "Didn't find anything for %016llX", (DWORDLONG)clsHnd);
+ AssertCodeMsg(GetHFAType->GetIndex((DWORDLONG)clsHnd) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX", (DWORDLONG)clsHnd);
+
+ value = GetHFAType->Get((DWORDLONG)clsHnd);
+ DEBUG_REP(dmpGetHFAType((DWORDLONG)clsHnd, value));
+ return (CorInfoType)value;
+}
+
void MethodContext::recGetMethodInfo(CORINFO_METHOD_HANDLE ftn, CORINFO_METHOD_INFO *info, bool result, DWORD exceptionCode)
{
if (GetMethodInfo == nullptr)
diff --git a/src/ToolBox/superpmi/superpmi-shared/methodcontext.h b/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
index 5869c85b45..0d49666e5c 100644
--- a/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
+++ b/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
@@ -513,9 +513,9 @@ public:
void dmpGetMethodName(DLD key, DD value);
const char *repGetMethodName(CORINFO_METHOD_HANDLE ftn, const char **moduleName);
- void MethodContext::recGetJitFlags(CORJIT_FLAGS *jitFlags, DWORD sizeInBytes, DWORD result);
- void MethodContext::dmpGetJitFlags(DWORD key, DD value);
- DWORD MethodContext::repGetJitFlags(CORJIT_FLAGS *jitFlags, DWORD sizeInBytes);
+ void recGetJitFlags(CORJIT_FLAGS *jitFlags, DWORD sizeInBytes, DWORD result);
+ void dmpGetJitFlags(DWORD key, DD value);
+ DWORD repGetJitFlags(CORJIT_FLAGS *jitFlags, DWORD sizeInBytes);
void recGetJitTimeLogFilename(LPCWSTR tempFileName);
void dmpGetJitTimeLogFilename(DWORD key, DWORD value);
@@ -674,6 +674,10 @@ public:
void dmpGetArgClass(const Agnostic_GetArgClass& key, const Agnostic_GetArgClass_Value& value);
CORINFO_CLASS_HANDLE repGetArgClass(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args, DWORD *exceptionCode);
+ void recGetHFAType(CORINFO_CLASS_HANDLE clsHnd, CorInfoType result);
+ void dmpGetHFAType(DWORDLONG key, DWORD value);
+ CorInfoType repGetHFAType(CORINFO_CLASS_HANDLE clsHnd);
+
void recGetMethodInfo(CORINFO_METHOD_HANDLE ftn, CORINFO_METHOD_INFO *info, bool result, DWORD exceptionCode);
void dmpGetMethodInfo(DWORDLONG key, const Agnostic_GetMethodInfo& value);
bool repGetMethodInfo(CORINFO_METHOD_HANDLE ftn, CORINFO_METHOD_INFO *info, DWORD *exceptionCode);
@@ -1012,7 +1016,7 @@ private:
// ********************* Please keep this up-to-date to ease adding more ***************
-// Highest packet number: 158
+// Highest packet number: 159
// *************************************************************************************
enum mcPackets
{
@@ -1055,6 +1059,7 @@ enum mcPackets
Packet_GetAddrOfCaptureThreadGlobal = 27,
Retired1 = 28,
Packet_GetArgClass = 139, //retired as 28 on 2013/07/03
+ Packet_GetHFAType = 159,
Packet_GetArgNext = 29,
Retired2 = 30,
Packet_GetArgType = 140, //retired as 30 on 2013/07/03
diff --git a/src/ToolBox/superpmi/superpmi-shim-collector/icorjitcompiler.cpp b/src/ToolBox/superpmi/superpmi-shim-collector/icorjitcompiler.cpp
index e3f5ae2764..c5f6d8aac1 100644
--- a/src/ToolBox/superpmi/superpmi-shim-collector/icorjitcompiler.cpp
+++ b/src/ToolBox/superpmi/superpmi-shim-collector/icorjitcompiler.cpp
@@ -109,7 +109,7 @@ void interceptor_ICJC::getVersionIdentifier(GUID* versionIdentifier /* OUT */)
original_ICorJitCompiler->getVersionIdentifier(versionIdentifier);
}
-unsigned interceptor_ICJC::getMaxIntrinsicSIMDVectorLength(DWORD cpuCompileFlags)
+unsigned interceptor_ICJC::getMaxIntrinsicSIMDVectorLength(CORJIT_FLAGS cpuCompileFlags)
{
return original_ICorJitCompiler->getMaxIntrinsicSIMDVectorLength(cpuCompileFlags);
}
diff --git a/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
index fb9163629d..1813ed29ff 100644
--- a/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
+++ b/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
@@ -1173,7 +1173,7 @@ bool interceptor_ICJI::isFieldStatic(CORINFO_FIELD_HANDLE fldHnd)
// in the code are. The native compiler will ensure that these places
// have a corresponding break point in native code.
//
-// Note that unless CORJIT_FLG_DEBUG_CODE is specified, this function will
+// Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will
// be used only as a hint and the native compiler should not change its
// code generation.
void interceptor_ICJI::getBoundaries(
@@ -1214,7 +1214,7 @@ void interceptor_ICJI::setBoundaries(
// under debugging, the JIT needs to keep them live over their
// entire scope so that they can be inspected.
//
-// Note that unless CORJIT_FLG_DEBUG_CODE is specified, this function will
+// Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will
// be used only as a hint and the native compiler should not change its
// code generation.
void interceptor_ICJI::getVars(
@@ -1388,7 +1388,9 @@ CorInfoType interceptor_ICJI::getHFAType (
)
{
mc->cr->AddCall("getHFAType");
- return original_ICorJitInfo->getHFAType(hClass);
+ CorInfoType temp = original_ICorJitInfo->getHFAType(hClass);
+ this->mc->recGetHFAType(hClass, temp);
+ return temp;
}
/*****************************************************************************
diff --git a/src/ToolBox/superpmi/superpmi-shim-counter/icorjitcompiler.cpp b/src/ToolBox/superpmi/superpmi-shim-counter/icorjitcompiler.cpp
index da766cc51d..2e088d438c 100644
--- a/src/ToolBox/superpmi/superpmi-shim-counter/icorjitcompiler.cpp
+++ b/src/ToolBox/superpmi/superpmi-shim-counter/icorjitcompiler.cpp
@@ -55,7 +55,7 @@ void interceptor_ICJC::getVersionIdentifier(GUID* versionIdentifier /* OUT */)
original_ICorJitCompiler->getVersionIdentifier(versionIdentifier);
}
-unsigned interceptor_ICJC::getMaxIntrinsicSIMDVectorLength(DWORD cpuCompileFlags)
+unsigned interceptor_ICJC::getMaxIntrinsicSIMDVectorLength(CORJIT_FLAGS cpuCompileFlags)
{
mcs->AddCall("getMaxIntrinsicSIMDVectorLength");
return original_ICorJitCompiler->getMaxIntrinsicSIMDVectorLength(cpuCompileFlags);
diff --git a/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
index 77519caa84..448fb1f686 100644
--- a/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
+++ b/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
@@ -961,7 +961,7 @@ bool interceptor_ICJI::isFieldStatic(CORINFO_FIELD_HANDLE fldHnd)
// in the code are. The native compiler will ensure that these places
// have a corresponding break point in native code.
//
-// Note that unless CORJIT_FLG_DEBUG_CODE is specified, this function will
+// Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will
// be used only as a hint and the native compiler should not change its
// code generation.
void interceptor_ICJI::getBoundaries(
@@ -999,7 +999,7 @@ void interceptor_ICJI::setBoundaries(
// under debugging, the JIT needs to keep them live over their
// entire scope so that they can be inspected.
//
-// Note that unless CORJIT_FLG_DEBUG_CODE is specified, this function will
+// Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will
// be used only as a hint and the native compiler should not change its
// code generation.
void interceptor_ICJI::getVars(
diff --git a/src/ToolBox/superpmi/superpmi-shim-simple/icorjitcompiler.cpp b/src/ToolBox/superpmi/superpmi-shim-simple/icorjitcompiler.cpp
index f6fceb2029..ec266e164f 100644
--- a/src/ToolBox/superpmi/superpmi-shim-simple/icorjitcompiler.cpp
+++ b/src/ToolBox/superpmi/superpmi-shim-simple/icorjitcompiler.cpp
@@ -48,7 +48,7 @@ void interceptor_ICJC::getVersionIdentifier(GUID* versionIdentifier /* OUT */)
original_ICorJitCompiler->getVersionIdentifier(versionIdentifier);
}
-unsigned interceptor_ICJC::getMaxIntrinsicSIMDVectorLength(DWORD cpuCompileFlags)
+unsigned interceptor_ICJC::getMaxIntrinsicSIMDVectorLength(CORJIT_FLAGS cpuCompileFlags)
{
return original_ICorJitCompiler->getMaxIntrinsicSIMDVectorLength(cpuCompileFlags);
}
diff --git a/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
index 89b19d8754..4d145f6a41 100644
--- a/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
+++ b/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
@@ -876,7 +876,7 @@ bool interceptor_ICJI::isFieldStatic(CORINFO_FIELD_HANDLE fldHnd)
// in the code are. The native compiler will ensure that these places
// have a corresponding break point in native code.
//
-// Note that unless CORJIT_FLG_DEBUG_CODE is specified, this function will
+// Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will
// be used only as a hint and the native compiler should not change its
// code generation.
void interceptor_ICJI::getBoundaries(
@@ -912,7 +912,7 @@ void interceptor_ICJI::setBoundaries(
// under debugging, the JIT needs to keep them live over their
// entire scope so that they can be inspected.
//
-// Note that unless CORJIT_FLG_DEBUG_CODE is specified, this function will
+// Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will
// be used only as a hint and the native compiler should not change its
// code generation.
void interceptor_ICJI::getVars(
diff --git a/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp
index 41b0195a6d..b746d3f6f7 100644
--- a/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp
+++ b/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp
@@ -1018,7 +1018,7 @@ bool MyICJI::isFieldStatic(CORINFO_FIELD_HANDLE fldHnd)
// in the code are. The native compiler will ensure that these places
// have a corresponding break point in native code.
//
-// Note that unless CORJIT_FLG_DEBUG_CODE is specified, this function will
+// Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will
// be used only as a hint and the native compiler should not change its
// code generation.
void MyICJI::getBoundaries(
@@ -1068,7 +1068,7 @@ void MyICJI::setBoundaries(
// under debugging, the JIT needs to keep them live over their
// entire scope so that they can be inspected.
//
-// Note that unless CORJIT_FLG_DEBUG_CODE is specified, this function will
+// Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will
// be used only as a hint and the native compiler should not change its
// code generation.
void MyICJI::getVars(
@@ -1192,9 +1192,8 @@ CorInfoType MyICJI::getHFAType (
)
{
jitInstance->mc->cr->AddCall("getHFAType");
- LogError("Hit unimplemented getHFAType");
- DebugBreakorAV(75);
- return (CorInfoType)0;
+ CorInfoType value = jitInstance->mc->repGetHFAType(hClass);
+ return value;
}
/*****************************************************************************
diff --git a/src/ToolBox/superpmi/superpmi/methodstatsemitter.cpp b/src/ToolBox/superpmi/superpmi/methodstatsemitter.cpp
index 0a43f02dd9..5cebc97db4 100644
--- a/src/ToolBox/superpmi/superpmi/methodstatsemitter.cpp
+++ b/src/ToolBox/superpmi/superpmi/methodstatsemitter.cpp
@@ -50,11 +50,11 @@ void MethodStatsEmitter::Emit(int methodNumber, MethodContext *mc, ULONGLONG fir
if (mc->dumpMethodMD5HashToBuffer(md5Hash, MD5_HASH_BUFFER_SIZE) != MD5_HASH_BUFFER_SIZE)
md5Hash[0] = 0;
- charCount += sprintf(rowData + charCount, "%s,", md5Hash);
+ charCount += sprintf_s(rowData + charCount, _countof(rowData) - charCount, "%s,", md5Hash);
}
if (strchr(statsTypes, '*') != NULL || strchr(statsTypes, 'n') != NULL || strchr(statsTypes, 'N') != NULL)
{
- charCount += sprintf(rowData + charCount, "%d,", methodNumber);
+ charCount += sprintf_s(rowData + charCount, _countof(rowData) - charCount, "%d,", methodNumber);
}
if (strchr(statsTypes, '*') != NULL || strchr(statsTypes, 'i') != NULL || strchr(statsTypes, 'I') != NULL)
{
@@ -63,7 +63,7 @@ void MethodStatsEmitter::Emit(int methodNumber, MethodContext *mc, ULONGLONG fir
unsigned flags = 0;
mc->repCompileMethod(&info, &flags);
- charCount += sprintf(rowData + charCount, "%d,", info.ILCodeSize);
+ charCount += sprintf_s(rowData + charCount, _countof(rowData) - charCount, "%d,", info.ILCodeSize);
}
if (strchr(statsTypes, '*') != NULL || strchr(statsTypes, 'a') != NULL || strchr(statsTypes, 'A') != NULL)
{
@@ -76,11 +76,11 @@ void MethodStatsEmitter::Emit(int methodNumber, MethodContext *mc, ULONGLONG fir
else
codeSize = 0;//this is likely a thin mc
- charCount += sprintf(rowData + charCount, "%d,", codeSize);
+ charCount += sprintf_s(rowData + charCount, _countof(rowData) - charCount, "%d,", codeSize);
}
if (strchr(statsTypes, '*') != NULL || strchr(statsTypes, 't') != NULL || strchr(statsTypes, 'T') != NULL)
{
- charCount += sprintf(rowData + charCount, "%llu,%llu,", firstTime, secondTime);
+ charCount += sprintf_s(rowData + charCount, _countof(rowData) - charCount, "%llu,%llu,", firstTime, secondTime);
}
//get rid of the final ',' and replace it with a '\n'
@@ -105,15 +105,15 @@ void MethodStatsEmitter::SetStatsTypes(char *types)
DWORD bytesWritten = 0;
if (strchr(statsTypes, '*') != NULL || strchr(statsTypes, 'h') != NULL || strchr(statsTypes, 'H') != NULL)
- charCount += sprintf(rowHeader + charCount, "HASH,");
+ charCount += sprintf_s(rowHeader + charCount, _countof(rowHeader) - charCount, "HASH,");
if (strchr(statsTypes, '*') != NULL || strchr(statsTypes, 'n') != NULL || strchr(statsTypes, 'N') != NULL)
- charCount += sprintf(rowHeader + charCount, "METHOD_NUMBER,");
+ charCount += sprintf_s(rowHeader + charCount, _countof(rowHeader) - charCount, "METHOD_NUMBER,");
if (strchr(statsTypes, '*') != NULL || strchr(statsTypes, 'i') != NULL || strchr(statsTypes, 'I') != NULL)
- charCount += sprintf(rowHeader + charCount, "IL_CODE_SIZE,");
+ charCount += sprintf_s(rowHeader + charCount, _countof(rowHeader) - charCount, "IL_CODE_SIZE,");
if (strchr(statsTypes, '*') != NULL || strchr(statsTypes, 'a') != NULL || strchr(statsTypes, 'A') != NULL)
- charCount += sprintf(rowHeader + charCount, "ASM_CODE_SIZE,");
+ charCount += sprintf_s(rowHeader + charCount, _countof(rowHeader) - charCount, "ASM_CODE_SIZE,");
if (strchr(statsTypes, '*') != NULL || strchr(statsTypes, 't') != NULL || strchr(statsTypes, 'T') != NULL)
- charCount += sprintf(rowHeader + charCount, "Time1,Time2,");
+ charCount += sprintf_s(rowHeader + charCount, _countof(rowHeader) - charCount, "Time1,Time2,");
//get rid of the final ',' and replace it with a '\n'
rowHeader[charCount - 1] = '\n';
@@ -123,4 +123,4 @@ void MethodStatsEmitter::SetStatsTypes(char *types)
LogError("Failed to write row header '%s'. GetLastError()=%u", rowHeader, GetLastError());
}
}
-} \ No newline at end of file
+}
diff --git a/src/ToolBox/superpmi/superpmi/neardiffer.cpp b/src/ToolBox/superpmi/superpmi/neardiffer.cpp
index 5b2e3b1b57..3f2c4db3b8 100644
--- a/src/ToolBox/superpmi/superpmi/neardiffer.cpp
+++ b/src/ToolBox/superpmi/superpmi/neardiffer.cpp
@@ -154,7 +154,7 @@ void NearDiffer::DumpCodeBlock(unsigned char *block, ULONG blocksize, void *orig
const size_t minInstrBytes = 7;
size_t instrBytes = max(instrSize, minInstrBytes);
- size_t buffSize = _snprintf(nullptr, 0, "%p %s\n", (void*)((size_t)originalAddr+offset), instrMnemonic) + 3 * instrBytes + 1;
+ size_t buffSize = sizeof("%p %s\n") + 10 + count + 3 * instrBytes + 1;
char *buff = new char[buffSize];
int written = 0;
written += sprintf_s(buff, buffSize, "%p ", (void*)((size_t)originalAddr+offset));
diff --git a/src/ToolBox/superpmi/superpmi/parallelsuperpmi.cpp b/src/ToolBox/superpmi/superpmi/parallelsuperpmi.cpp
index 8c5232315e..301db3cfe9 100644
--- a/src/ToolBox/superpmi/superpmi/parallelsuperpmi.cpp
+++ b/src/ToolBox/superpmi/superpmi/parallelsuperpmi.cpp
@@ -138,7 +138,7 @@ bool WriteArrayToMCL(char *mclFilename, int *arr, int count)
DWORD charCount = 0;
DWORD bytesWritten = 0;
- charCount = sprintf(strMethodIndex, "%d\r\n", arr[i]);
+ charCount = sprintf_s(strMethodIndex, sizeof(strMethodIndex), "%d\r\n", arr[i]);
if (!WriteFile(hMCLFile, strMethodIndex, charCount, &bytesWritten, nullptr) || (bytesWritten != charCount))
{
@@ -232,7 +232,7 @@ void ProcessChildStdOut(const CommandLine::Options& o, char *stdoutFilename, int
if (o.applyDiff)
{
int temp1 = 0, temp2 = 0, temp3 = 0, temp4 = 0;
- int converted = sscanf(buff, g_AsmDiffsSummaryFormatString, &temp1, &temp2, &temp3, &temp4);
+ int converted = sscanf_s(buff, g_AsmDiffsSummaryFormatString, &temp1, &temp2, &temp3, &temp4);
if (converted != 4)
{
LogError("Couldn't parse status message: \"%s\"", buff);
@@ -248,7 +248,7 @@ void ProcessChildStdOut(const CommandLine::Options& o, char *stdoutFilename, int
else
{
int temp1 = 0, temp2 = 0, temp3 = 0;
- int converted = sscanf(buff, g_SummaryFormatString, &temp1, &temp2, &temp3);
+ int converted = sscanf_s(buff, g_SummaryFormatString, &temp1, &temp2, &temp3);
if (converted != 3)
{
LogError("Couldn't parse status message: \"%s\"", buff);
diff --git a/src/ToolBox/superpmi/superpmi/superpmi.cpp b/src/ToolBox/superpmi/superpmi/superpmi.cpp
index ce352070f8..980792d4a9 100644
--- a/src/ToolBox/superpmi/superpmi/superpmi.cpp
+++ b/src/ToolBox/superpmi/superpmi/superpmi.cpp
@@ -45,6 +45,8 @@ void SetSuperPmiTargetArchitecture(const char* targetArchitecture)
}
#elif defined(_TARGET_X86_)
SpmiTargetArchitecture = SPMI_TARGET_ARCHITECTURE_X86;
+#elif defined(_TARGET_ARM_)
+ SpmiTargetArchitecture = SPMI_TARGET_ARCHITECTURE_ARM;
#endif
}
diff --git a/src/ToolBox/superpmi/superpmi/superpmi.h b/src/ToolBox/superpmi/superpmi/superpmi.h
index d5b7bdaa2b..ce535994a0 100644
--- a/src/ToolBox/superpmi/superpmi/superpmi.h
+++ b/src/ToolBox/superpmi/superpmi/superpmi.h
@@ -12,7 +12,8 @@ enum SPMI_TARGET_ARCHITECTURE
{
SPMI_TARGET_ARCHITECTURE_X86,
SPMI_TARGET_ARCHITECTURE_AMD64,
- SPMI_TARGET_ARCHITECTURE_ARM64
+ SPMI_TARGET_ARCHITECTURE_ARM64,
+ SPMI_TARGET_ARCHITECTURE_ARM
};
extern SPMI_TARGET_ARCHITECTURE SpmiTargetArchitecture;
diff --git a/src/classlibnative/bcltype/arraynative.cpp b/src/classlibnative/bcltype/arraynative.cpp
index b1aa6f8751..58fa4dd3e6 100644
--- a/src/classlibnative/bcltype/arraynative.cpp
+++ b/src/classlibnative/bcltype/arraynative.cpp
@@ -176,7 +176,6 @@ void ArrayInitializeWorker(ARRAYBASEREF * arrayRef,
#ifdef _X86_
BEGIN_CALL_TO_MANAGED();
- typedef void (__fastcall * CtorFtnType)(BYTE*, BYTE*);
for (SIZE_T i = 0; i < cElements; i++)
{
@@ -197,6 +196,7 @@ void ArrayInitializeWorker(ARRAYBASEREF * arrayRef,
nop // Mark the fact that we can call managed code
}
#else // _DEBUG
+ typedef void (__fastcall * CtorFtnType)(BYTE*, BYTE*);
(*(CtorFtnType)ctorFtn)(thisPtr, (BYTE*)pElemMT);
#endif // _DEBUG
@@ -961,7 +961,7 @@ void memmoveGCRefs(void *dest, const void *src, size_t len)
}
}
- GCHeap::GetGCHeap()->SetCardsAfterBulkCopy((Object**)dest, len);
+ GCHeapUtilities::GetGCHeap()->SetCardsAfterBulkCopy((Object**)dest, len);
}
void ArrayNative::ArrayCopyNoTypeCheck(BASEARRAYREF pSrc, unsigned int srcIndex, BASEARRAYREF pDest, unsigned int destIndex, unsigned int length)
diff --git a/src/classlibnative/bcltype/number.cpp b/src/classlibnative/bcltype/number.cpp
index 349bffb819..6ca24d8672 100644
--- a/src/classlibnative/bcltype/number.cpp
+++ b/src/classlibnative/bcltype/number.cpp
@@ -82,7 +82,7 @@ static const char* const negNumberFormats[] = {
static const char posNumberFormat[] = "#";
-#if defined(_TARGET_X86_)
+#if defined(_TARGET_X86_) && !defined(FEATURE_PAL)
extern "C" void _cdecl /*__stdcall*/ DoubleToNumber(double value, int precision, NUMBER* number);
extern "C" void _cdecl /*__stdcall*/ NumberToDouble(NUMBER* number, double* value);
@@ -132,7 +132,7 @@ unsigned int Int64DivMod1E9(unsigned __int64* value)
#pragma warning(default:4035)
-#else // !(defined(_TARGET_X86_)
+#else // _TARGET_X86_ && !FEATURE_PAL
#pragma warning(disable:4273)
extern "C" char* __cdecl _ecvt(double, int, int*, int*);
@@ -607,7 +607,7 @@ unsigned int Int64DivMod1E9(unsigned __int64* value)
-#endif // !(defined(_TARGET_X86_)
+#endif // _TARGET_X86_ && !FEATURE_PAL
#if defined(_MSC_VER) && defined(_TARGET_X86_)
#pragma optimize("y", on) // Small critical routines, don't put in EBP frame
diff --git a/src/classlibnative/bcltype/system.cpp b/src/classlibnative/bcltype/system.cpp
index e902734b23..8bb3409974 100644
--- a/src/classlibnative/bcltype/system.cpp
+++ b/src/classlibnative/bcltype/system.cpp
@@ -63,6 +63,16 @@ FCIMPLEND;
+FCIMPL0(UINT32, SystemNative::GetCurrentProcessorNumber)
+{
+ FCALL_CONTRACT;
+
+ return ::GetCurrentProcessorNumber();
+}
+FCIMPLEND;
+
+
+
FCIMPL0(UINT32, SystemNative::GetTickCount)
{
FCALL_CONTRACT;
@@ -673,7 +683,7 @@ FCIMPL0(FC_BOOL_RET, SystemNative::IsServerGC)
{
FCALL_CONTRACT;
- FC_RETURN_BOOL(GCHeap::IsServerHeap());
+ FC_RETURN_BOOL(GCHeapUtilities::IsServerHeap());
}
FCIMPLEND
diff --git a/src/classlibnative/bcltype/system.h b/src/classlibnative/bcltype/system.h
index 60355b3388..9edc595039 100644
--- a/src/classlibnative/bcltype/system.h
+++ b/src/classlibnative/bcltype/system.h
@@ -72,6 +72,7 @@ private:
public:
// Functions on the System.Environment class
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);
diff --git a/src/classlibnative/float/floatsingle.cpp b/src/classlibnative/float/floatsingle.cpp
index dd1bb43316..7e2ea0adc6 100644
--- a/src/classlibnative/float/floatsingle.cpp
+++ b/src/classlibnative/float/floatsingle.cpp
@@ -11,6 +11,22 @@
#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
+
+#endif
+
// 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
@@ -39,6 +55,218 @@ FCIMPL1(float, COMSingle::Abs, float x)
return (float)fabsf(x);
FCIMPLEND
+/*=====================================Acos=====================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Acos, float x)
+ FCALL_CONTRACT;
+
+ return (float)acosf(x);
+FCIMPLEND
+
+/*=====================================Asin=====================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Asin, float x)
+ FCALL_CONTRACT;
+
+ return (float)asinf(x);
+FCIMPLEND
+
+/*=====================================Atan=====================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Atan, float x)
+ FCALL_CONTRACT;
+
+ return (float)atanf(x);
+FCIMPLEND
+
+/*=====================================Atan2====================================
+**
+==============================================================================*/
+FCIMPL2(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)
+ FCALL_CONTRACT;
+
+ return (float)ceilf(x);
+FCIMPLEND
+
+/*=====================================Cos======================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Cos, float x)
+ FCALL_CONTRACT;
+
+ return (float)cosf(x);
+FCIMPLEND
+
+/*=====================================Cosh=====================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Cosh, float x)
+ FCALL_CONTRACT;
+
+ return (float)coshf(x);
+FCIMPLEND
+
+/*=====================================Exp======================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Exp, float x)
+ FCALL_CONTRACT;
+
+ return (float)expf(x);
+FCIMPLEND
+
+/*====================================Floor=====================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Floor, float x)
+ FCALL_CONTRACT;
+
+ return (float)floorf(x);
+FCIMPLEND
+
+/*=====================================Log======================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Log, float x)
+ FCALL_CONTRACT;
+
+ return (float)logf(x);
+FCIMPLEND
+
+/*====================================Log10=====================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Log10, float x)
+ FCALL_CONTRACT;
+
+ return (float)log10f(x);
+FCIMPLEND
+
+/*=====================================ModF=====================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::ModF, float* iptr)
+ FCALL_CONTRACT;
+
+ return (float)modff(*iptr, iptr);
+FCIMPLEND
+
+/*=====================================Pow======================================
+**
+==============================================================================*/
+FCIMPL2(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)
+ FCALL_CONTRACT;
+
+ // 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);
+FCIMPLEND
+
+/*=====================================Sin======================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Sin, float x)
+ FCALL_CONTRACT;
+
+ return (float)sinf(x);
+FCIMPLEND
+
+/*=====================================Sinh=====================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Sinh, float x)
+ FCALL_CONTRACT;
+
+ return (float)sinhf(x);
+FCIMPLEND
+
+/*=====================================Sqrt=====================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Sqrt, float x)
+ FCALL_CONTRACT;
+
+ return (float)sqrtf(x);
+FCIMPLEND
+
+/*=====================================Tan======================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Tan, float x)
+ FCALL_CONTRACT;
+
+ return (float)tanf(x);
+FCIMPLEND
+
+/*=====================================Tanh=====================================
+**
+==============================================================================*/
+FCIMPL1(float, COMSingle::Tanh, float x)
+ FCALL_CONTRACT;
+
+ return (float)tanhf(x);
+FCIMPLEND
+
#ifdef _MSC_VER
#pragma float_control(precise, on )
#endif
diff --git a/src/classlibnative/inc/floatsingle.h b/src/classlibnative/inc/floatsingle.h
index 6d123ec001..f8a1dda0fd 100644
--- a/src/classlibnative/inc/floatsingle.h
+++ b/src/classlibnative/inc/floatsingle.h
@@ -11,6 +11,25 @@
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(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);
};
#endif // _FLOATSINGLE_H_
diff --git a/src/classlibnative/inc/nlsinfo.h b/src/classlibnative/inc/nlsinfo.h
index 1c1ff01f8a..a5dc13f9a8 100644
--- a/src/classlibnative/inc/nlsinfo.h
+++ b/src/classlibnative/inc/nlsinfo.h
@@ -115,19 +115,8 @@ public:
static INT_PTR InternalInitVersionedSortHandle(LPCWSTR localeName, INT_PTR* handleOrigin);
static INT_PTR InternalInitVersionedSortHandle(LPCWSTR localeName, INT_PTR* handleOrigin, DWORD sortVersion);
static DWORD QCALLTYPE InternalGetSortVersion();
- static BOOL QCALLTYPE InternalGetNlsVersionEx(INT_PTR handle, INT_PTR handleOrigin, LPCWSTR lpLocaleName, NLSVERSIONINFOEX * lpVersionInformation);
#endif
-
-
-#ifndef FEATURE_CORECLR
- //
- // Native helper function for methods in TimeZone
- //
- static FCDECL0(LONG, nativeGetTimeZoneMinuteOffset);
- static FCDECL0(Object*, nativeGetStandardName);
- static FCDECL0(Object*, nativeGetDaylightName);
- static FCDECL1(Object*, nativeGetDaylightChanges, int year);
-#endif // FEATURE_CORECLR
+ static BOOL QCALLTYPE InternalGetNlsVersionEx(INT_PTR handle, INT_PTR handleOrigin, LPCWSTR lpLocaleName, NLSVERSIONINFOEX * lpVersionInformation);
//
// Native helper function for methods in EncodingTable
diff --git a/src/classlibnative/nls/nlsinfo.cpp b/src/classlibnative/nls/nlsinfo.cpp
index 864f998d1f..0e034c4a0c 100644
--- a/src/classlibnative/nls/nlsinfo.cpp
+++ b/src/classlibnative/nls/nlsinfo.cpp
@@ -1057,7 +1057,7 @@ FCIMPLEND
#define CULTURETYPES_FRAMEWORKCULTURES 0x0040
-const LPWSTR WHIDBEY_FRAMEWORK_CULTURE_LIST [] =
+const LPCWSTR WHIDBEY_FRAMEWORK_CULTURE_LIST [] =
{
W(""),
W("af"),
@@ -1877,127 +1877,6 @@ INT32 QCALLTYPE COMNlsInfo::InternalGetGlobalizedHashCode(INT_PTR handle, INT_PT
return(iReturnHash);
}
-#ifndef FEATURE_CORECLR // FCalls used by System.TimeZone
-
-FCIMPL0(LONG, COMNlsInfo::nativeGetTimeZoneMinuteOffset)
-{
- FCALL_CONTRACT;
-
- TIME_ZONE_INFORMATION timeZoneInfo;
-
- GetTimeZoneInformation(&timeZoneInfo);
-
- //
- // In Win32, UTC = local + offset. So for Pacific Standard Time, offset = 8.
- // In NLS+, Local time = UTC + offset. So for PST, offset = -8.
- // So we have to reverse the sign here.
- //
- return (timeZoneInfo.Bias * -1);
-}
-FCIMPLEND
-
-FCIMPL0(Object*, COMNlsInfo::nativeGetStandardName)
-{
- FCALL_CONTRACT;
-
- STRINGREF refRetVal = NULL;
- HELPER_METHOD_FRAME_BEGIN_RET_1(refRetVal);
-
- TIME_ZONE_INFORMATION timeZoneInfo;
- GetTimeZoneInformation(&timeZoneInfo);
-
- refRetVal = StringObject::NewString(timeZoneInfo.StandardName);
-
- HELPER_METHOD_FRAME_END();
- return OBJECTREFToObject(refRetVal);
-}
-FCIMPLEND
-
-FCIMPL0(Object*, COMNlsInfo::nativeGetDaylightName)
-{
- FCALL_CONTRACT;
-
- STRINGREF refRetVal = NULL;
- HELPER_METHOD_FRAME_BEGIN_RET_1(refRetVal);
-
- TIME_ZONE_INFORMATION timeZoneInfo;
- GetTimeZoneInformation(&timeZoneInfo);
- // Instead of returning null when daylight saving is not used, now we return the same result as the OS.
- //In this case, if daylight saving time is used, the standard name is returned.
-
-#if 0
- if (result == TIME_ZONE_ID_UNKNOWN || timeZoneInfo.DaylightDate.wMonth == 0) {
- // If daylight saving time is not used in this timezone, return null.
- //
- // Windows NT/2000: TIME_ZONE_ID_UNKNOWN is returned if daylight saving time is not used in
- // the current time zone, because there are no transition dates.
- //
- // For Windows 9x, a zero in the wMonth in DaylightDate means daylight saving time
- // is not specified.
- //
- // If the current timezone uses daylight saving rule, but user unchekced the
- // "Automatically adjust clock for daylight saving changes", the value
- // for DaylightBias will be 0.
- return (I2ARRAYREF)NULL;
- }
-#endif // 0
-
- refRetVal = StringObject::NewString(timeZoneInfo.DaylightName);
-
- HELPER_METHOD_FRAME_END();
- return OBJECTREFToObject(refRetVal);
-}
-FCIMPLEND
-
-FCIMPL1(Object*, COMNlsInfo::nativeGetDaylightChanges, int year)
-{
- FCALL_CONTRACT;
-
- I2ARRAYREF pResultArray = NULL;
- HELPER_METHOD_FRAME_BEGIN_RET_1(pResultArray);
-
- TIME_ZONE_INFORMATION timeZoneInfo;
- DWORD result = GetTimeZoneInformation(&timeZoneInfo);
-
- if (result == TIME_ZONE_ID_UNKNOWN || timeZoneInfo.DaylightBias == 0
- || timeZoneInfo.DaylightDate.wMonth == 0
- ) {
- // If daylight saving time is not used in this timezone, return null.
- //
- // If the current timezone uses daylight saving rule, but user unchekced the
- // "Automatically adjust clock for daylight saving changes", the value
- // for DaylightBias will be 0.
- goto lExit;
- }
-
- pResultArray = (I2ARRAYREF)AllocatePrimitiveArray(ELEMENT_TYPE_I2, 17);
-
- //
- // The content of timeZoneInfo.StandardDate is 8 words, which
- // contains year, month, day, dayOfWeek, hour, minute, second, millisecond.
- //
- memcpyNoGCRefs(pResultArray->m_Array,
- (LPVOID)&timeZoneInfo.DaylightDate,
- 8 * sizeof(INT16));
-
- //
- // The content of timeZoneInfo.DaylightDate is 8 words, which
- // contains year, month, day, dayOfWeek, hour, minute, second, millisecond.
- //
- memcpyNoGCRefs(((INT16*)pResultArray->m_Array) + 8,
- (LPVOID)&timeZoneInfo.StandardDate,
- 8 * sizeof(INT16));
-
- ((INT16*)pResultArray->m_Array)[16] = (INT16)timeZoneInfo.DaylightBias * -1;
-
-lExit: ;
- HELPER_METHOD_FRAME_END();
- return OBJECTREFToObject(pResultArray);
-}
-FCIMPLEND
-
-#endif // FEATURE_CORECLR
-
inline BOOL IsInvariantLocale(STRINGREF localeName)
{
return localeName->GetStringLength() == 0;
@@ -3411,7 +3290,6 @@ INT_PTR COMNlsInfo::InternalInitOsSortHandle(LPCWSTR localeName, __out INT_PTR*
return pSort;
}
-#ifndef FEATURE_CORECLR
BOOL QCALLTYPE COMNlsInfo::InternalGetNlsVersionEx(INT_PTR handle, INT_PTR handleOrigin, LPCWSTR lpLocaleName, NLSVERSIONINFOEX * lpVersionInformation)
{
CONTRACTL {
@@ -3421,7 +3299,7 @@ BOOL QCALLTYPE COMNlsInfo::InternalGetNlsVersionEx(INT_PTR handle, INT_PTR handl
BOOL ret = FALSE;
BEGIN_QCALL;
-
+#ifndef FEATURE_CORECLR
AppDomain* curDomain = GetAppDomain();
if(curDomain->m_bUseOsSorting)
@@ -3449,12 +3327,15 @@ BOOL QCALLTYPE COMNlsInfo::InternalGetNlsVersionEx(INT_PTR handle, INT_PTR handl
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 {
diff --git a/src/coreclr/hosts/coreconsole/coreconsole.cpp b/src/coreclr/hosts/coreconsole/coreconsole.cpp
index 1533dff88e..ea4e2e72c5 100644
--- a/src/coreclr/hosts/coreconsole/coreconsole.cpp
+++ b/src/coreclr/hosts/coreconsole/coreconsole.cpp
@@ -44,7 +44,7 @@ public:
m_capacity = m_defaultSize;
}
if (m_length + strLen + 1 > m_capacity) {
- size_t newCapacity = m_capacity * 2;
+ size_t newCapacity = (m_length + strLen + 1) * 2;
wchar_t* newBuffer = new wchar_t[newCapacity];
wcsncpy_s(newBuffer, newCapacity, m_buffer, m_length);
delete[] m_buffer;
@@ -185,7 +185,7 @@ public:
}
}
- bool TPAListContainsFile(_In_z_ wchar_t* fileNameWithoutExtension, _In_reads_(countExtensions) wchar_t** rgTPAExtensions, int countExtensions)
+ bool TPAListContainsFile(_In_z_ wchar_t* fileNameWithoutExtension, _In_reads_(countExtensions) const wchar_t** rgTPAExtensions, int countExtensions)
{
if (!m_tpaList.CStr()) return false;
@@ -225,7 +225,7 @@ public:
}
}
- void AddFilesFromDirectoryToTPAList(_In_z_ wchar_t* targetPath, _In_reads_(countExtensions) wchar_t** rgTPAExtensions, int countExtensions)
+ void AddFilesFromDirectoryToTPAList(_In_z_ wchar_t* targetPath, _In_reads_(countExtensions) const wchar_t** rgTPAExtensions, int countExtensions)
{
*m_log << W("Adding assemblies from ") << targetPath << W(" to the TPA list") << Logger::endl;
wchar_t assemblyPath[MAX_LONGPATH];
@@ -288,7 +288,7 @@ public:
// On first call, scans the coreclr directory for dlls and adds them all to the list.
const wchar_t * GetTpaList() {
if (!m_tpaList.CStr()) {
- wchar_t *rgTPAExtensions[] = {
+ const wchar_t *rgTPAExtensions[] = {
W("*.ni.dll"), // Probe for .ni.dll first so that it's preferred if ni and il coexist in the same dir
W("*.dll"),
W("*.ni.exe"),
@@ -457,7 +457,6 @@ bool TryRun(const int argc, const wchar_t* argv[], Logger &log, const bool verbo
W("APP_PATHS"),
W("APP_NI_PATHS"),
W("NATIVE_DLL_SEARCH_DIRECTORIES"),
- W("AppDomainCompatSwitch")
};
const wchar_t *property_values[] = {
// TRUSTED_PLATFORM_ASSEMBLIES
@@ -468,8 +467,6 @@ bool TryRun(const int argc, const wchar_t* argv[], Logger &log, const bool verbo
appNiPath,
// NATIVE_DLL_SEARCH_DIRECTORIES
nativeDllSearchDirs,
- // AppDomainCompatSwitch
- W("UseLatestBehaviorWhenTFMNotSpecified")
};
diff --git a/src/coreclr/hosts/corerun/corerun.cpp b/src/coreclr/hosts/corerun/corerun.cpp
index e7ddab21e9..dfbb79c0d2 100644
--- a/src/coreclr/hosts/corerun/corerun.cpp
+++ b/src/coreclr/hosts/corerun/corerun.cpp
@@ -161,7 +161,7 @@ public:
}
}
- bool TPAListContainsFile(_In_z_ wchar_t* fileNameWithoutExtension, _In_reads_(countExtensions) wchar_t** rgTPAExtensions, int countExtensions)
+ bool TPAListContainsFile(_In_z_ wchar_t* fileNameWithoutExtension, _In_reads_(countExtensions) const wchar_t** rgTPAExtensions, int countExtensions)
{
if (m_tpaList.IsEmpty()) return false;
@@ -201,7 +201,7 @@ public:
}
}
- void AddFilesFromDirectoryToTPAList(_In_z_ const wchar_t* targetPath, _In_reads_(countExtensions) wchar_t** rgTPAExtensions, int countExtensions)
+ void AddFilesFromDirectoryToTPAList(_In_z_ const wchar_t* targetPath, _In_reads_(countExtensions) const wchar_t** rgTPAExtensions, int countExtensions)
{
*m_log << W("Adding assemblies from ") << targetPath << W(" to the TPA list") << Logger::endl;
StackSString assemblyPath;
@@ -259,7 +259,7 @@ public:
// On first call, scans the coreclr directory for dlls and adds them all to the list.
const wchar_t * GetTpaList() {
if (m_tpaList.IsEmpty()) {
- wchar_t *rgTPAExtensions[] = {
+ const wchar_t *rgTPAExtensions[] = {
W("*.ni.dll"), // Probe for .ni.dll first so that it's preferred if ni and il coexist in the same dir
W("*.dll"),
W("*.ni.exe"),
@@ -495,7 +495,6 @@ bool TryRun(const int argc, const wchar_t* argv[], Logger &log, const bool verbo
W("APP_PATHS"),
W("APP_NI_PATHS"),
W("NATIVE_DLL_SEARCH_DIRECTORIES"),
- W("AppDomainCompatSwitch"),
W("APP_LOCAL_WINMETADATA")
};
const wchar_t *property_values[] = {
@@ -507,8 +506,6 @@ bool TryRun(const int argc, const wchar_t* argv[], Logger &log, const bool verbo
appNiPath,
// NATIVE_DLL_SEARCH_DIRECTORIES
nativeDllSearchDirs,
- // AppDomainCompatSwitch
- W("UseLatestBehaviorWhenTFMNotSpecified"),
// APP_LOCAL_WINMETADATA
appLocalWinmetadata
};
diff --git a/src/coreclr/hosts/unixcoreruncommon/coreruncommon.cpp b/src/coreclr/hosts/unixcoreruncommon/coreruncommon.cpp
index b3a0c07a79..d7186d7a29 100644
--- a/src/coreclr/hosts/unixcoreruncommon/coreruncommon.cpp
+++ b/src/coreclr/hosts/unixcoreruncommon/coreruncommon.cpp
@@ -379,7 +379,6 @@ int ExecuteManagedAssembly(
"APP_PATHS",
"APP_NI_PATHS",
"NATIVE_DLL_SEARCH_DIRECTORIES",
- "AppDomainCompatSwitch",
"System.GC.Server",
};
const char *propertyValues[] = {
@@ -391,8 +390,6 @@ int ExecuteManagedAssembly(
appPath.c_str(),
// NATIVE_DLL_SEARCH_DIRECTORIES
nativeDllSearchDirs.c_str(),
- // AppDomainCompatSwitch
- "UseLatestBehaviorWhenTFMNotSpecified",
// System.GC.Server
useServerGc,
};
diff --git a/src/corefx/System.Globalization.Native/CMakeLists.txt b/src/corefx/System.Globalization.Native/CMakeLists.txt
index 3d9e392132..90f50671cd 100644
--- a/src/corefx/System.Globalization.Native/CMakeLists.txt
+++ b/src/corefx/System.Globalization.Native/CMakeLists.txt
@@ -14,7 +14,7 @@ if(UTYPES_H STREQUAL UTYPES_H-NOTFOUND)
return()
endif()
-if(NOT CLR_CMAKE_PLATFORM_DARWIN)
+if (FEATURE_FIXED_ICU_VERSION AND 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,12 +26,16 @@ if(NOT CLR_CMAKE_PLATFORM_DARWIN)
message(FATAL_ERROR "Cannot find libicui18n, try installing libicu-dev (or the appropriate package for your platform)")
return()
endif()
-else()
+endif()
+
+if(CLR_CMAKE_PLATFORM_DARWIN)
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)
endif()
include(configure.cmake)
@@ -50,6 +54,12 @@ set(NATIVEGLOBALIZATION_SOURCES
timeZoneInfo.cpp
)
+if (NOT FEATURE_FIXED_ICU_VERSION)
+ list(APPEND NATIVEGLOBALIZATION_SOURCES
+ icushim.cpp
+ )
+endif()
+
include_directories(${UTYPES_H})
_add_library(System.Globalization.Native
@@ -60,11 +70,21 @@ _add_library(System.Globalization.Native
# 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)
- target_link_libraries(System.Globalization.Native
- ${ICUUC}
- ${ICUI18N}
- )
+ if (FEATURE_FIXED_ICU_VERSION)
+ target_link_libraries(System.Globalization.Native
+ ${ICUUC}
+ ${ICUI18N}
+ )
+ elseif(NOT CMAKE_SYSTEM_NAME STREQUAL FreeBSD AND NOT CMAKE_SYSTEM_NAME STREQUAL NetBSD)
+ target_link_libraries(System.Globalization.Native
+ dl
+ )
+ endif()
else()
target_link_libraries(System.Globalization.Native
${ICUCORE}
@@ -73,5 +93,11 @@ else()
add_definitions(-DU_DISABLE_RENAMING=1)
endif()
+verify_dependencies(
+ System.Globalization.Native
+ "Verification failed. System.Globalization.Native.so has undefined dependencies. These are likely ICU APIs that need to be added to icushim.h."
+)
+
# add the install targets
-install_clr(System.Globalization.Native) \ No newline at end of file
+install_clr(System.Globalization.Native)
+
diff --git a/src/corefx/System.Globalization.Native/calendarData.cpp b/src/corefx/System.Globalization.Native/calendarData.cpp
index f91cc0cb57..49436078d8 100644
--- a/src/corefx/System.Globalization.Native/calendarData.cpp
+++ b/src/corefx/System.Globalization.Native/calendarData.cpp
@@ -6,7 +6,7 @@
#include <string.h>
#include <vector>
-#include "config.h"
+#include "icushim.h"
#include "locale.hpp"
#include "holders.h"
#include "errors.h"
diff --git a/src/corefx/System.Globalization.Native/casing.cpp b/src/corefx/System.Globalization.Native/casing.cpp
index 58b47fc810..918b8fe6ed 100644
--- a/src/corefx/System.Globalization.Native/casing.cpp
+++ b/src/corefx/System.Globalization.Native/casing.cpp
@@ -5,8 +5,7 @@
#include <assert.h>
#include <stdint.h>
-#include <unicode/uchar.h>
-#include <unicode/utf16.h>
+#include "icushim.h"
/*
Function:
diff --git a/src/corefx/System.Globalization.Native/collation.cpp b/src/corefx/System.Globalization.Native/collation.cpp
index 6039a9ef39..f37211208e 100644
--- a/src/corefx/System.Globalization.Native/collation.cpp
+++ b/src/corefx/System.Globalization.Native/collation.cpp
@@ -8,12 +8,10 @@
#include <stdint.h>
#include <vector>
#include <map>
-#include <unicode/uchar.h>
-#include <unicode/ucol.h>
-#include <unicode/usearch.h>
-#include <unicode/utf16.h>
-#include "config.h"
+#include "icushim.h"
+#include "locale.hpp"
+#include "errors.h"
const int32_t CompareOptionsIgnoreCase = 0x1;
const int32_t CompareOptionsIgnoreNonSpace = 0x2;
@@ -298,7 +296,7 @@ UCollator* CloneCollatorWithOptions(const UCollator* pCollator, int32_t options,
// Returns TRUE if all the collation elements in str are completely ignorable
bool CanIgnoreAllCollationElements(const UCollator* pColl, const UChar* lpStr, int32_t length)
{
- bool result = FALSE;
+ bool result = false;
UErrorCode err = U_ZERO_ERROR;
UCollationElements* pCollElem = ucol_openElements(pColl, lpStr, length, &err);
@@ -306,20 +304,20 @@ bool CanIgnoreAllCollationElements(const UCollator* pColl, const UChar* lpStr, i
{
int32_t curCollElem = UCOL_NULLORDER;
- result = TRUE;
+ result = true;
while ((curCollElem = ucol_next(pCollElem, &err)) != UCOL_NULLORDER)
{
if (curCollElem != 0)
{
- result = FALSE;
+ result = false;
break;
}
}
if (U_FAILURE(err))
{
- result = FALSE;
+ result = false;
}
ucol_closeElements(pCollElem);
@@ -329,24 +327,36 @@ bool CanIgnoreAllCollationElements(const UCollator* pColl, const UChar* lpStr, i
}
-extern "C" SortHandle* GlobalizationNative_GetSortHandle(const char* lpLocaleName)
+extern "C" int32_t GlobalizationNative_GetSortVersion()
{
- SortHandle* pSortHandle = new SortHandle();
+ // we didn't use UCOL_TAILORINGS_VERSION because it is deprecated in ICU v5
+ return UCOL_RUNTIME_VERSION << 16 | UCOL_BUILDER_VERSION;
+}
+
+extern "C" ResultCode GlobalizationNative_GetSortHandle(const char* lpLocaleName, SortHandle** ppSortHandle)
+{
+ assert(ppSortHandle != nullptr);
+
+ *ppSortHandle = new (std::nothrow) SortHandle();
+ if ((*ppSortHandle) == nullptr)
+ {
+ return GetResultCode(U_MEMORY_ALLOCATION_ERROR);
+ }
UErrorCode err = U_ZERO_ERROR;
- pSortHandle->regular = ucol_open(lpLocaleName, &err);
+ (*ppSortHandle)->regular = ucol_open(lpLocaleName, &err);
if (U_FAILURE(err))
{
- if (pSortHandle->regular != nullptr)
- ucol_close(pSortHandle->regular);
+ if ((*ppSortHandle)->regular != nullptr)
+ ucol_close((*ppSortHandle)->regular);
- delete pSortHandle;
- pSortHandle = nullptr;
+ delete (*ppSortHandle);
+ (*ppSortHandle) = nullptr;
}
- return pSortHandle;
+ return GetResultCode(err);
}
extern "C" void GlobalizationNative_CloseSortHandle(SortHandle* pSortHandle)
diff --git a/src/corefx/System.Globalization.Native/errors.h b/src/corefx/System.Globalization.Native/errors.h
index 2bfbdb2ba1..b23a0dacd5 100644
--- a/src/corefx/System.Globalization.Native/errors.h
+++ b/src/corefx/System.Globalization.Native/errors.h
@@ -4,8 +4,6 @@
#pragma once
-#include <unicode/utypes.h>
-
/*
* These values should be kept in sync with
* Interop.GlobalizationInterop.ResultCode
@@ -15,6 +13,7 @@ enum ResultCode : int32_t
Success = 0,
UnknownError = 1,
InsufficentBuffer = 2,
+ OutOfMemory = 3
};
/*
@@ -26,6 +25,11 @@ static ResultCode GetResultCode(UErrorCode err)
{
return InsufficentBuffer;
}
+
+ if (err == U_MEMORY_ALLOCATION_ERROR)
+ {
+ return OutOfMemory;
+ }
if (U_SUCCESS(err))
{
diff --git a/src/corefx/System.Globalization.Native/holders.h b/src/corefx/System.Globalization.Native/holders.h
index 529451f77c..83e253d297 100644
--- a/src/corefx/System.Globalization.Native/holders.h
+++ b/src/corefx/System.Globalization.Native/holders.h
@@ -2,14 +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.
-#include <unicode/ucal.h>
-#include <unicode/uenum.h>
-#include <unicode/udatpg.h>
-#include <unicode/udat.h>
-#include <unicode/unum.h>
-#include <unicode/uldnames.h>
-#include <unicode/ures.h>
-
// IcuHolder is a template that can manage the lifetime of a raw pointer to ensure that it is cleaned up at the correct
// time. The general usage pattern is to aquire some ICU resource via an _open call, then construct a holder using the
// pointer and UErrorCode to manage the lifetime. When the holder goes out of scope, the coresponding close method is
diff --git a/src/corefx/System.Globalization.Native/icushim.cpp b/src/corefx/System.Globalization.Native/icushim.cpp
new file mode 100644
index 0000000000..63f111b8b1
--- /dev/null
+++ b/src/corefx/System.Globalization.Native/icushim.cpp
@@ -0,0 +1,226 @@
+// Licensed to the .NET Foundation under one or more 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 <dlfcn.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include "icushim.h"
+
+// Define pointers to all the used ICU functions
+#define PER_FUNCTION_BLOCK(fn, lib) decltype(fn)* fn##_ptr;
+FOR_ALL_ICU_FUNCTIONS
+#undef PER_FUNCTION_BLOCK
+
+static void* libicuuc = nullptr;
+static void* libicui18n = nullptr;
+
+// 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
+// plus 20 to give us enough headspace. The ICU seems to version about twice
+// a year.
+static const int MinICUVersion = U_ICU_VERSION_MAJOR_NUM;
+static const int MaxICUVersion = MinICUVersion + 20;
+static const int MinMinorICUVersion = 1;
+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
+// 2. Only majorVer and minorVer are not equal to -1 => result is baseFileName.majorver.minorVer
+// 3. All components are not equal to -1 => result is baseFileName.majorver.minorVer.subver
+void GetVersionedLibFileName(const char* baseFileName, int majorVer, int minorVer, int subVer, char* result)
+{
+ assert(majorVer != -1);
+
+ int nameLen = sprintf(result, "%s.%d", baseFileName, majorVer);
+
+ if (minorVer != -1)
+ {
+ nameLen += sprintf(result + nameLen, ".%d", minorVer);
+ if (subVer != -1)
+ {
+ sprintf(result + nameLen, ".%d", subVer);
+ }
+ }
+}
+
+// Try to open the necessary ICU libraries
+bool OpenICULibraries(int majorVer, int minorVer, int subVer)
+{
+ char libicuucName[64];
+ char libicui18nName[64];
+
+ static_assert(sizeof("libicuuc.so") + MaxICUVersionStringLength <= sizeof(libicuucName), "The libicuucName is too small");
+ GetVersionedLibFileName("libicuuc.so", majorVer, minorVer, subVer, libicuucName);
+
+ static_assert(sizeof("libicui18n.so") + MaxICUVersionStringLength <= sizeof(libicui18nName), "The libicui18nName is too small");
+ GetVersionedLibFileName("libicui18n.so", majorVer, minorVer, subVer, libicui18nName);
+
+ libicuuc = dlopen(libicuucName, RTLD_LAZY);
+ if (libicuuc != nullptr)
+ {
+ libicui18n = dlopen(libicui18nName, RTLD_LAZY);
+ if (libicui18n == nullptr)
+ {
+ dlclose(libicuuc);
+ libicuuc = nullptr;
+ }
+ }
+
+ return libicuuc != nullptr;
+}
+
+// Select libraries using the version override specified by the CLR_ICU_VERSION_OVERRIDE
+// environment variable.
+// The format of the string in this variable is majorVer[.minorVer[.subVer]] (the brackets
+// indicate optional parts).
+bool FindLibUsingOverride(int* majorVer, int* minorVer, int* subVer)
+{
+ char* versionOverride = getenv("CLR_ICU_VERSION_OVERRIDE");
+ if (versionOverride != nullptr)
+ {
+ int first = -1;
+ int second = -1;
+ int third = -1;
+
+ int matches = sscanf(versionOverride, "%d.%d.%d", &first, &second, &third);
+ if (matches > 0)
+ {
+ if (OpenICULibraries(first, second, third))
+ {
+ *majorVer = first;
+ *minorVer = second;
+ *subVer = third;
+ 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)
+{
+ for (int i = MaxICUVersion; i >= MinICUVersion; i--)
+ {
+ for (int j = MaxMinorICUVersion; j >= MinMinorICUVersion; j--)
+ {
+ if (OpenICULibraries(i, j, -1))
+ {
+ *majorVer = i;
+ *minorVer = j;
+ 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, minor and sub version.
+bool FindLibWithMajorMinorSubVersion(int* majorVer, int* minorVer, int* subVer)
+{
+ for (int i = MaxICUVersion; i >= MinICUVersion; i--)
+ {
+ for (int j = MaxMinorICUVersion; j >= MinMinorICUVersion; j--)
+ {
+ for (int k = MaxSubICUVersion; k >= MinSubICUVersion; k--)
+ {
+ if (OpenICULibraries(i, j, k))
+ {
+ *majorVer = i;
+ *minorVer = j;
+ *subVer = k;
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+// This function is ran at the end of dlopen for the current shared library
+__attribute__((constructor))
+void InitializeICUShim()
+{
+ int majorVer = -1;
+ int minorVer = -1;
+ int subVer = -1;
+
+ if (!FindLibUsingOverride(&majorVer, &minorVer, &subVer) &&
+ !FindLibWithMajorMinorVersion(&majorVer, &minorVer) &&
+ !FindLibWithMajorMinorSubVersion(&majorVer, &minorVer, &subVer))
+ {
+ // No usable ICU version found
+ fprintf(stderr, "No usable version of the ICU libraries was found\n");
+ abort();
+ }
+
+ 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)
+ {
+ // Now try just the _majorVer added
+ sprintf(symbolVersion, "_%d", majorVer);
+ sprintf(symbolName, "u_strlen%s", symbolVersion);
+ if (dlsym(libicuuc, symbolName) == nullptr)
+ {
+ // Now try the _majorVer_minorVer added
+ sprintf(symbolVersion, "_%d_%d", majorVer, minorVer);
+ sprintf(symbolName, "u_strlen%s", symbolVersion);
+ if (dlsym(libicuuc, symbolName) == nullptr)
+ {
+ // 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();
+ }
+ }
+ }
+ }
+
+ // 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); \
+ sprintf(symbolName, #fn "%s", symbolVersion); \
+ fn##_ptr = (decltype(fn)*)dlsym(lib, symbolName); \
+ if (fn##_ptr == NULL) { fprintf(stderr, "Cannot get symbol %s from " #lib "\n", symbolName); abort(); }
+
+ FOR_ALL_ICU_FUNCTIONS
+#undef PER_FUNCTION_BLOCK
+}
+
+__attribute__((destructor))
+void ShutdownICUShim()
+{
+ if (libicuuc != nullptr)
+ {
+ dlclose(libicuuc);
+ }
+
+ if (libicui18n != nullptr)
+ {
+ dlclose(libicui18n);
+ }
+}
diff --git a/src/corefx/System.Globalization.Native/icushim.h b/src/corefx/System.Globalization.Native/icushim.h
new file mode 100644
index 0000000000..8ec13d5737
--- /dev/null
+++ b/src/corefx/System.Globalization.Native/icushim.h
@@ -0,0 +1,243 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+
+// Enable calling ICU functions through shims to enable support for
+// multiple versions of ICU if the FEATURE_FIXED_ICU_VERSION is
+// not defined.
+
+#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.
+#include <unicode/locid.h>
+#include <unicode/ucurr.h>
+#include <unicode/ucal.h>
+#include <unicode/uchar.h>
+#include <unicode/ucol.h>
+#include <unicode/udat.h>
+#include <unicode/udatpg.h>
+#include <unicode/uenum.h>
+#include <unicode/uidna.h>
+#include <unicode/uldnames.h>
+#include <unicode/ulocdata.h>
+#include <unicode/unorm2.h>
+#include <unicode/unum.h>
+#include <unicode/ures.h>
+#include <unicode/usearch.h>
+#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) \
+ PER_FUNCTION_BLOCK(u_strlen, libicuuc) \
+ PER_FUNCTION_BLOCK(u_strncpy, libicuuc) \
+ PER_FUNCTION_BLOCK(u_tolower, libicuuc) \
+ PER_FUNCTION_BLOCK(u_toupper, libicuuc) \
+ PER_FUNCTION_BLOCK(ucal_add, libicui18n) \
+ PER_FUNCTION_BLOCK(ucal_close, libicui18n) \
+ PER_FUNCTION_BLOCK(ucal_get, libicui18n) \
+ PER_FUNCTION_BLOCK(ucal_getAttribute, libicui18n) \
+ PER_FUNCTION_BLOCK(ucal_getKeywordValuesForLocale, libicui18n) \
+ PER_FUNCTION_BLOCK(ucal_getLimit, libicui18n) \
+ PER_FUNCTION_BLOCK(ucal_getTimeZoneDisplayName, libicui18n) \
+ PER_FUNCTION_BLOCK(ucal_open, libicui18n) \
+ PER_FUNCTION_BLOCK(ucal_set, libicui18n) \
+ PER_FUNCTION_BLOCK(ucol_close, libicui18n) \
+ PER_FUNCTION_BLOCK(ucol_closeElements, libicui18n) \
+ PER_FUNCTION_BLOCK(ucol_getRules, libicui18n) \
+ PER_FUNCTION_BLOCK(ucol_getSortKey, libicui18n) \
+ PER_FUNCTION_BLOCK(ucol_getStrength, libicui18n) \
+ PER_FUNCTION_BLOCK(ucol_next, libicui18n) \
+ PER_FUNCTION_BLOCK(ucol_open, libicui18n) \
+ PER_FUNCTION_BLOCK(ucol_openElements, libicui18n) \
+ PER_FUNCTION_BLOCK(ucol_openRules, libicui18n) \
+ PER_FUNCTION_BLOCK(ucol_safeClone, libicui18n) \
+ PER_FUNCTION_BLOCK(ucol_setAttribute, libicui18n) \
+ PER_FUNCTION_BLOCK(ucol_strcoll, libicui18n) \
+ PER_FUNCTION_BLOCK(ucurr_forLocale, libicui18n) \
+ PER_FUNCTION_BLOCK(ucurr_getName, libicui18n) \
+ PER_FUNCTION_BLOCK(udat_close, libicui18n) \
+ PER_FUNCTION_BLOCK(udat_countSymbols, libicui18n) \
+ PER_FUNCTION_BLOCK(udat_getSymbols, libicui18n) \
+ PER_FUNCTION_BLOCK(udat_open, libicui18n) \
+ PER_FUNCTION_BLOCK(udat_setCalendar, libicui18n) \
+ PER_FUNCTION_BLOCK(udat_toPattern, libicui18n) \
+ PER_FUNCTION_BLOCK(udatpg_close, libicui18n) \
+ PER_FUNCTION_BLOCK(udatpg_getBestPattern, libicui18n) \
+ PER_FUNCTION_BLOCK(udatpg_open, libicui18n) \
+ PER_FUNCTION_BLOCK(uenum_close, libicuuc) \
+ PER_FUNCTION_BLOCK(uenum_count, libicuuc) \
+ PER_FUNCTION_BLOCK(uenum_next, libicuuc) \
+ PER_FUNCTION_BLOCK(uidna_close, libicuuc) \
+ PER_FUNCTION_BLOCK(uidna_nameToASCII, libicuuc) \
+ PER_FUNCTION_BLOCK(uidna_nameToUnicode, libicuuc) \
+ PER_FUNCTION_BLOCK(uidna_openUTS46, libicuuc) \
+ PER_FUNCTION_BLOCK(uldn_close, libicui18n) \
+ PER_FUNCTION_BLOCK(uldn_keyValueDisplayName, libicui18n) \
+ PER_FUNCTION_BLOCK(uldn_open, libicui18n) \
+ PER_FUNCTION_BLOCK(uloc_canonicalize, libicuuc) \
+ PER_FUNCTION_BLOCK(uloc_countAvailable, libicuuc) \
+ PER_FUNCTION_BLOCK(uloc_getAvailable, libicuuc) \
+ PER_FUNCTION_BLOCK(uloc_getBaseName, libicuuc) \
+ PER_FUNCTION_BLOCK(uloc_getCharacterOrientation, libicuuc) \
+ PER_FUNCTION_BLOCK(uloc_getCountry, libicuuc) \
+ PER_FUNCTION_BLOCK(uloc_getDefault, libicuuc) \
+ PER_FUNCTION_BLOCK(uloc_getDisplayCountry, libicuuc) \
+ PER_FUNCTION_BLOCK(uloc_getDisplayLanguage, libicuuc) \
+ PER_FUNCTION_BLOCK(uloc_getDisplayName, libicuuc) \
+ PER_FUNCTION_BLOCK(uloc_getISO3Country, libicuuc) \
+ PER_FUNCTION_BLOCK(uloc_getISO3Language, libicuuc) \
+ PER_FUNCTION_BLOCK(uloc_getKeywordValue, libicuuc) \
+ PER_FUNCTION_BLOCK(uloc_getLanguage, libicuuc) \
+ PER_FUNCTION_BLOCK(uloc_getLCID, libicuuc) \
+ PER_FUNCTION_BLOCK(uloc_getName, libicuuc) \
+ PER_FUNCTION_BLOCK(uloc_getParent, libicuuc) \
+ PER_FUNCTION_BLOCK(uloc_setKeywordValue, libicuuc) \
+ PER_FUNCTION_BLOCK(ulocdata_getMeasurementSystem, libicui18n) \
+ PER_FUNCTION_BLOCK(unorm2_getNFCInstance, libicuuc) \
+ PER_FUNCTION_BLOCK(unorm2_getNFDInstance, libicuuc) \
+ PER_FUNCTION_BLOCK(unorm2_getNFKCInstance, libicuuc) \
+ PER_FUNCTION_BLOCK(unorm2_getNFKDInstance, libicuuc) \
+ PER_FUNCTION_BLOCK(unorm2_isNormalized, libicuuc) \
+ PER_FUNCTION_BLOCK(unorm2_normalize, libicuuc) \
+ PER_FUNCTION_BLOCK(unum_close, libicui18n) \
+ PER_FUNCTION_BLOCK(unum_getAttribute, libicui18n) \
+ PER_FUNCTION_BLOCK(unum_getSymbol, libicui18n) \
+ PER_FUNCTION_BLOCK(unum_open, libicui18n) \
+ PER_FUNCTION_BLOCK(unum_toPattern, libicui18n) \
+ PER_FUNCTION_BLOCK(ures_close, libicuuc) \
+ PER_FUNCTION_BLOCK(ures_getByKey, libicuuc) \
+ PER_FUNCTION_BLOCK(ures_getSize, libicuuc) \
+ PER_FUNCTION_BLOCK(ures_getStringByIndex, libicuuc) \
+ PER_FUNCTION_BLOCK(ures_open, libicuuc) \
+ PER_FUNCTION_BLOCK(usearch_close, libicui18n) \
+ PER_FUNCTION_BLOCK(usearch_first, libicui18n) \
+ PER_FUNCTION_BLOCK(usearch_getMatchedLength, libicui18n) \
+ PER_FUNCTION_BLOCK(usearch_last, libicui18n) \
+ PER_FUNCTION_BLOCK(usearch_openFromCollator, libicui18n)
+
+#if HAVE_SET_MAX_VARIABLE
+#define FOR_ALL_ICU_FUNCTIONS \
+ FOR_ALL_UNCONDITIONAL_ICU_FUNCTIONS \
+ PER_FUNCTION_BLOCK(ucol_setMaxVariable, libicui18n)
+#else
+#define FOR_ALL_ICU_FUNCTIONS \
+ FOR_ALL_UNCONDITIONAL_ICU_FUNCTIONS \
+ PER_FUNCTION_BLOCK(ucol_setVariableTop, libicui18n)
+#endif
+
+// Declare pointers to all the used ICU functions
+#define PER_FUNCTION_BLOCK(fn, lib) extern decltype(fn)* fn##_ptr;
+FOR_ALL_ICU_FUNCTIONS
+#undef PER_FUNCTION_BLOCK
+
+// Redefine all calls to ICU functions as calls through pointers that are set
+// to the functions of the selected version of ICU in the initialization.
+#define u_charsToUChars(...) u_charsToUChars_ptr(__VA_ARGS__)
+#define u_strlen(...) u_strlen_ptr(__VA_ARGS__)
+#define u_strncpy(...) u_strncpy_ptr(__VA_ARGS__)
+#define u_tolower(...) u_tolower_ptr(__VA_ARGS__)
+#define u_toupper(...) u_toupper_ptr(__VA_ARGS__)
+#define ucal_add(...) ucal_add_ptr(__VA_ARGS__)
+#define ucal_close(...) ucal_close_ptr(__VA_ARGS__)
+#define ucal_get(...) ucal_get_ptr(__VA_ARGS__)
+#define ucal_getAttribute(...) ucal_getAttribute_ptr(__VA_ARGS__)
+#define ucal_getKeywordValuesForLocale(...) ucal_getKeywordValuesForLocale_ptr(__VA_ARGS__)
+#define ucal_getLimit(...) ucal_getLimit_ptr(__VA_ARGS__)
+#define ucal_getTimeZoneDisplayName(...) ucal_getTimeZoneDisplayName_ptr(__VA_ARGS__)
+#define ucal_open(...) ucal_open_ptr(__VA_ARGS__)
+#define ucal_set(...) ucal_set_ptr(__VA_ARGS__)
+#define ucol_close(...) ucol_close_ptr(__VA_ARGS__)
+#define ucol_closeElements(...) ucol_closeElements_ptr(__VA_ARGS__)
+#define ucol_getRules(...) ucol_getRules_ptr(__VA_ARGS__)
+#define ucol_getSortKey(...) ucol_getSortKey_ptr(__VA_ARGS__)
+#define ucol_getStrength(...) ucol_getStrength_ptr(__VA_ARGS__)
+#define ucol_next(...) ucol_next_ptr(__VA_ARGS__)
+#define ucol_open(...) ucol_open_ptr(__VA_ARGS__)
+#define ucol_openElements(...) ucol_openElements_ptr(__VA_ARGS__)
+#define ucol_openRules(...) ucol_openRules_ptr(__VA_ARGS__)
+#define ucol_safeClone(...) ucol_safeClone_ptr(__VA_ARGS__)
+#define ucol_setAttribute(...) ucol_setAttribute_ptr(__VA_ARGS__)
+#if HAVE_SET_MAX_VARIABLE
+#define ucol_setMaxVariable(...) ucol_setMaxVariable_ptr(__VA_ARGS__)
+#else
+#define ucol_setVariableTop(...) ucol_setVariableTop_ptr(__VA_ARGS__)
+#endif
+#define ucol_strcoll(...) ucol_strcoll_ptr(__VA_ARGS__)
+#define ucurr_forLocale(...) ucurr_forLocale_ptr(__VA_ARGS__)
+#define ucurr_getName(...) ucurr_getName_ptr(__VA_ARGS__)
+#define udat_close(...) udat_close_ptr(__VA_ARGS__)
+#define udat_countSymbols(...) udat_countSymbols_ptr(__VA_ARGS__)
+#define udat_getSymbols(...) udat_getSymbols_ptr(__VA_ARGS__)
+#define udat_open(...) udat_open_ptr(__VA_ARGS__)
+#define udat_setCalendar(...) udat_setCalendar_ptr(__VA_ARGS__)
+#define udat_toPattern(...) udat_toPattern_ptr(__VA_ARGS__)
+#define udatpg_close(...) udatpg_close_ptr(__VA_ARGS__)
+#define udatpg_getBestPattern(...) udatpg_getBestPattern_ptr(__VA_ARGS__)
+#define udatpg_open(...) udatpg_open_ptr(__VA_ARGS__)
+#define uenum_close(...) uenum_close_ptr(__VA_ARGS__)
+#define uenum_count(...) uenum_count_ptr(__VA_ARGS__)
+#define uenum_next(...) uenum_next_ptr(__VA_ARGS__)
+#define uidna_close(...) uidna_close_ptr(__VA_ARGS__)
+#define uidna_nameToASCII(...) uidna_nameToASCII_ptr(__VA_ARGS__)
+#define uidna_nameToUnicode(...) uidna_nameToUnicode_ptr(__VA_ARGS__)
+#define uidna_openUTS46(...) uidna_openUTS46_ptr(__VA_ARGS__)
+#define uldn_close(...) uldn_close_ptr(__VA_ARGS__)
+#define uldn_keyValueDisplayName(...) uldn_keyValueDisplayName_ptr(__VA_ARGS__)
+#define uldn_open(...) uldn_open_ptr(__VA_ARGS__)
+#define uloc_canonicalize(...) uloc_canonicalize_ptr(__VA_ARGS__)
+#define uloc_countAvailable(...) uloc_countAvailable_ptr(__VA_ARGS__)
+#define uloc_getAvailable(...) uloc_getAvailable_ptr(__VA_ARGS__)
+#define uloc_getBaseName(...) uloc_getBaseName_ptr(__VA_ARGS__)
+#define uloc_getCharacterOrientation(...) uloc_getCharacterOrientation_ptr(__VA_ARGS__)
+#define uloc_getCountry(...) uloc_getCountry_ptr(__VA_ARGS__)
+#define uloc_getDefault(...) uloc_getDefault_ptr(__VA_ARGS__)
+#define uloc_getDisplayCountry(...) uloc_getDisplayCountry_ptr(__VA_ARGS__)
+#define uloc_getDisplayLanguage(...) uloc_getDisplayLanguage_ptr(__VA_ARGS__)
+#define uloc_getDisplayName(...) uloc_getDisplayName_ptr(__VA_ARGS__)
+#define uloc_getISO3Country(...) uloc_getISO3Country_ptr(__VA_ARGS__)
+#define uloc_getISO3Language(...) uloc_getISO3Language_ptr(__VA_ARGS__)
+#define uloc_getKeywordValue(...) uloc_getKeywordValue_ptr(__VA_ARGS__)
+#define uloc_getLanguage(...) uloc_getLanguage_ptr(__VA_ARGS__)
+#define uloc_getLCID(...) uloc_getLCID_ptr(__VA_ARGS__)
+#define uloc_getName(...) uloc_getName_ptr(__VA_ARGS__)
+#define uloc_getParent(...) uloc_getParent_ptr(__VA_ARGS__)
+#define uloc_setKeywordValue(...) uloc_setKeywordValue_ptr(__VA_ARGS__)
+#define ulocdata_getMeasurementSystem(...) ulocdata_getMeasurementSystem_ptr(__VA_ARGS__)
+#define unorm2_getNFCInstance(...) unorm2_getNFCInstance_ptr(__VA_ARGS__)
+#define unorm2_getNFDInstance(...) unorm2_getNFDInstance_ptr(__VA_ARGS__)
+#define unorm2_getNFKCInstance(...) unorm2_getNFKCInstance_ptr(__VA_ARGS__)
+#define unorm2_getNFKDInstance(...) unorm2_getNFKDInstance_ptr(__VA_ARGS__)
+#define unorm2_isNormalized(...) unorm2_isNormalized_ptr(__VA_ARGS__)
+#define unorm2_normalize(...) unorm2_normalize_ptr(__VA_ARGS__)
+#define unum_close(...) unum_close_ptr(__VA_ARGS__)
+#define unum_getAttribute(...) unum_getAttribute_ptr(__VA_ARGS__)
+#define unum_getSymbol(...) unum_getSymbol_ptr(__VA_ARGS__)
+#define unum_open(...) unum_open_ptr(__VA_ARGS__)
+#define unum_toPattern(...) unum_toPattern_ptr(__VA_ARGS__)
+#define ures_close(...) ures_close_ptr(__VA_ARGS__)
+#define ures_getByKey(...) ures_getByKey_ptr(__VA_ARGS__)
+#define ures_getSize(...) ures_getSize_ptr(__VA_ARGS__)
+#define ures_getStringByIndex(...) ures_getStringByIndex_ptr(__VA_ARGS__)
+#define ures_open(...) ures_open_ptr(__VA_ARGS__)
+#define usearch_close(...) usearch_close_ptr(__VA_ARGS__)
+#define usearch_first(...) usearch_first_ptr(__VA_ARGS__)
+#define usearch_getMatchedLength(...) usearch_getMatchedLength_ptr(__VA_ARGS__)
+#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/corefx/System.Globalization.Native/idna.cpp b/src/corefx/System.Globalization.Native/idna.cpp
index 4820d2c3f2..23942b3a68 100644
--- a/src/corefx/System.Globalization.Native/idna.cpp
+++ b/src/corefx/System.Globalization.Native/idna.cpp
@@ -4,7 +4,7 @@
//
#include <stdint.h>
-#include <unicode/uidna.h>
+#include "icushim.h"
const uint32_t AllowUnassigned = 0x1;
const uint32_t UseStd3AsciiRules = 0x2;
diff --git a/src/corefx/System.Globalization.Native/locale.cpp b/src/corefx/System.Globalization.Native/locale.cpp
index 1cb564a45a..951179d321 100644
--- a/src/corefx/System.Globalization.Native/locale.cpp
+++ b/src/corefx/System.Globalization.Native/locale.cpp
@@ -9,6 +9,7 @@
#include <stdlib.h>
#include <locale.h>
+#include "icushim.h"
#include "locale.hpp"
int32_t UErrorCodeToBool(UErrorCode status)
@@ -147,6 +148,56 @@ const char* DetectDefaultLocaleName()
return uloc_getDefault();
}
+// GlobalizationNative_GetLocales gets all locale names and store it in the value buffer
+// in case of success, it returns the count of the characters stored in value buffer
+// in case of failure, it returns negative number.
+// if the input value buffer is null, it returns the length needed to store the
+// locale names list.
+// if the value is not null, it fills the value with locale names separated by the length
+// of each name.
+extern "C" int32_t GlobalizationNative_GetLocales(UChar *value, int32_t valueLength)
+{
+ int32_t totalLength = 0;
+ int32_t index = 0;
+ int32_t localeCount = uloc_countAvailable();
+
+ if (localeCount <= 0)
+ return -1; // failed
+
+ for (int32_t i = 0; i < localeCount; i++)
+ {
+ const char *pLocaleName = uloc_getAvailable(i);
+ if (pLocaleName[0] == 0) // unexpected empty name
+ return -2;
+
+ int32_t localeNameLength = strlen(pLocaleName);
+
+ totalLength += localeNameLength + 1; // add 1 for the name length
+
+ if (value != nullptr)
+ {
+ if (totalLength > valueLength)
+ return -3;
+
+ value[index++] = (UChar) localeNameLength;
+
+ for (int j=0; j<localeNameLength; j++)
+ {
+ if (pLocaleName[j] == '_') // fix the locale name
+ {
+ value[index++] = (UChar) '-';
+ }
+ else
+ {
+ value[index++] = (UChar) pLocaleName[j];
+ }
+ }
+ }
+ }
+
+ return totalLength;
+}
+
extern "C" int32_t GlobalizationNative_GetLocaleName(const UChar* localeName, UChar* value, int32_t valueLength)
{
UErrorCode status = U_ZERO_ERROR;
diff --git a/src/corefx/System.Globalization.Native/locale.hpp b/src/corefx/System.Globalization.Native/locale.hpp
index 4845859960..79328f3b19 100644
--- a/src/corefx/System.Globalization.Native/locale.hpp
+++ b/src/corefx/System.Globalization.Native/locale.hpp
@@ -2,8 +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.
-#include "unicode/locid.h"
-
/*
Function:
UErrorCodeToBool
diff --git a/src/corefx/System.Globalization.Native/localeNumberData.cpp b/src/corefx/System.Globalization.Native/localeNumberData.cpp
index 595cb130b2..a3586b568f 100644
--- a/src/corefx/System.Globalization.Native/localeNumberData.cpp
+++ b/src/corefx/System.Globalization.Native/localeNumberData.cpp
@@ -7,8 +7,7 @@
#include <string.h>
#include <vector>
-#include <unicode/ulocdata.h>
-
+#include "icushim.h"
#include "locale.hpp"
#include "holders.h"
diff --git a/src/corefx/System.Globalization.Native/localeStringData.cpp b/src/corefx/System.Globalization.Native/localeStringData.cpp
index 927da67095..b8eaa307c7 100644
--- a/src/corefx/System.Globalization.Native/localeStringData.cpp
+++ b/src/corefx/System.Globalization.Native/localeStringData.cpp
@@ -7,6 +7,7 @@
#include <string.h>
#include <vector>
+#include "icushim.h"
#include "locale.hpp"
#include "holders.h"
@@ -27,6 +28,8 @@ enum LocaleStringData : int32_t
ThousandSeparator = 0x0000000F,
Digits = 0x00000013,
MonetarySymbol = 0x00000014,
+ CurrencyEnglishName = 0x00001007,
+ CurrencyNativeName = 0x00001008,
Iso4217MonetarySymbol = 0x00000015,
MonetaryDecimalSeparator = 0x00000016,
MonetaryThousandSeparator = 0x00000017,
@@ -34,8 +37,10 @@ enum LocaleStringData : int32_t
PMDesignator = 0x00000029,
PositiveSign = 0x00000050,
NegativeSign = 0x00000051,
- Iso639LanguageName = 0x00000059,
+ Iso639LanguageTwoLetterName = 0x00000059,
+ Iso639LanguageThreeLetterName = 0x00000067,
Iso3166CountryName = 0x0000005A,
+ Iso3166CountryName2= 0x00000068,
NaNSymbol = 0x00000069,
PositiveInfinitySymbol = 0x0000006a,
ParentName = 0x0000006d,
@@ -111,11 +116,11 @@ UErrorCode GetLocaleInfoAmPm(const char* locale, bool am, UChar* value, int32_t
/*
Function:
-GetLocaleIso639LanguageName
+GetLocaleIso639LanguageTwoLetterName
Gets the language name for a locale (via uloc_getLanguage) and converts the result to UChars
*/
-UErrorCode GetLocaleIso639LanguageName(const char* locale, UChar* value, int32_t valueLength)
+UErrorCode GetLocaleIso639LanguageTwoLetterName(const char* locale, UChar* value, int32_t valueLength)
{
UErrorCode status = U_ZERO_ERROR;
int32_t length = uloc_getLanguage(locale, nullptr, 0, &status);
@@ -135,6 +140,23 @@ UErrorCode GetLocaleIso639LanguageName(const char* locale, UChar* value, int32_t
/*
Function:
+GetLocaleIso639LanguageThreeLetterName
+
+Gets the language name for a locale (via uloc_getISO3Language) and converts the result to UChars
+*/
+UErrorCode GetLocaleIso639LanguageThreeLetterName(const char* locale, UChar* value, int32_t valueLength)
+{
+ const char *isoLanguage = uloc_getISO3Language(locale);
+ if (isoLanguage[0] == 0)
+ {
+ return U_ILLEGAL_ARGUMENT_ERROR;
+ }
+
+ return u_charsToUChars_safe(isoLanguage, value, valueLength);
+}
+
+/*
+Function:
GetLocaleIso3166CountryName
Gets the country name for a locale (via uloc_getCountry) and converts the result to UChars
@@ -158,6 +180,66 @@ UErrorCode GetLocaleIso3166CountryName(const char* locale, UChar* value, int32_t
}
/*
+Function:
+GetLocaleIso3166CountryCode
+
+Gets the 3 letter country code for a locale (via uloc_getISO3Country) and converts the result to UChars
+*/
+UErrorCode GetLocaleIso3166CountryCode(const char* locale, UChar* value, int32_t valueLength)
+{
+ const char *pIsoCountryName = uloc_getISO3Country(locale);
+ int len = strlen(pIsoCountryName);
+
+ if (len == 0)
+ {
+ return U_ILLEGAL_ARGUMENT_ERROR;
+ }
+
+ return u_charsToUChars_safe(pIsoCountryName, value, valueLength);
+}
+
+/*
+Function:
+GetLocaleCurrencyName
+
+Gets the locale currency English or native name and convert the result to UChars
+*/
+UErrorCode GetLocaleCurrencyName(const char* locale, bool nativeName, UChar* value, int32_t valueLength)
+{
+ UErrorCode status = U_ZERO_ERROR;
+
+ UChar currencyThreeLettersName[4]; // 3 letters currency iso name + NULL
+ ucurr_forLocale(locale, currencyThreeLettersName, 4, &status);
+ if (!U_SUCCESS(status))
+ {
+ return status;
+ }
+
+ int32_t len;
+ UBool formatChoice;
+ const UChar *pCurrencyLongName = ucurr_getName(
+ currencyThreeLettersName,
+ nativeName ? locale : ULOC_US,
+ UCURR_LONG_NAME,
+ &formatChoice,
+ &len,
+ &status);
+ if (!U_SUCCESS(status))
+ {
+ return status;
+ }
+
+ if (len >= valueLength) // we need to have room for NULL too
+ {
+ return U_BUFFER_OVERFLOW_ERROR;
+ }
+ u_strncpy(value, pCurrencyLongName, len);
+ value[len] = 0;
+
+ return status;
+}
+
+/*
PAL Function:
GetLocaleInfoString
@@ -226,6 +308,12 @@ extern "C" int32_t GlobalizationNative_GetLocaleInfoString(
case Iso4217MonetarySymbol:
status = GetLocaleInfoDecimalFormatSymbol(locale, UNUM_INTL_CURRENCY_SYMBOL, value, valueLength);
break;
+ case CurrencyEnglishName:
+ status = GetLocaleCurrencyName(locale, false, value, valueLength);
+ break;
+ case CurrencyNativeName:
+ status = GetLocaleCurrencyName(locale, true, value, valueLength);
+ break;
case MonetaryDecimalSeparator:
status = GetLocaleInfoDecimalFormatSymbol(locale, UNUM_MONETARY_SEPARATOR_SYMBOL, value, valueLength);
break;
@@ -245,12 +333,18 @@ extern "C" int32_t GlobalizationNative_GetLocaleInfoString(
case NegativeSign:
status = GetLocaleInfoDecimalFormatSymbol(locale, UNUM_MINUS_SIGN_SYMBOL, value, valueLength);
break;
- case Iso639LanguageName:
- status = GetLocaleIso639LanguageName(locale, value, valueLength);
+ case Iso639LanguageTwoLetterName:
+ status = GetLocaleIso639LanguageTwoLetterName(locale, value, valueLength);
+ break;
+ case Iso639LanguageThreeLetterName:
+ status = GetLocaleIso639LanguageThreeLetterName(locale, value, valueLength);
break;
case Iso3166CountryName:
status = GetLocaleIso3166CountryName(locale, value, valueLength);
break;
+ case Iso3166CountryName2:
+ status = GetLocaleIso3166CountryCode(locale, value, valueLength);
+ break;
case NaNSymbol:
status = GetLocaleInfoDecimalFormatSymbol(locale, UNUM_NAN_SYMBOL, value, valueLength);
break;
diff --git a/src/corefx/System.Globalization.Native/normalization.cpp b/src/corefx/System.Globalization.Native/normalization.cpp
index f96f5ee315..014894a5ed 100644
--- a/src/corefx/System.Globalization.Native/normalization.cpp
+++ b/src/corefx/System.Globalization.Native/normalization.cpp
@@ -4,7 +4,7 @@
//
#include <stdint.h>
-#include <unicode/unorm2.h>
+#include "icushim.h"
/*
* These values should be kept in sync with System.Text.NormalizationForm
diff --git a/src/corefx/System.Globalization.Native/timeZoneInfo.cpp b/src/corefx/System.Globalization.Native/timeZoneInfo.cpp
index d0e01e5ce6..0dd28b4b70 100644
--- a/src/corefx/System.Globalization.Native/timeZoneInfo.cpp
+++ b/src/corefx/System.Globalization.Native/timeZoneInfo.cpp
@@ -5,8 +5,8 @@
#include <stdint.h>
#include <unistd.h>
-#include <unicode/ucal.h>
+#include "icushim.h"
#include "locale.hpp"
#include "holders.h"
#include "errors.h"
diff --git a/src/debug/daccess/daccess.cpp b/src/debug/daccess/daccess.cpp
index ba3995b1f7..69167ab07e 100644
--- a/src/debug/daccess/daccess.cpp
+++ b/src/debug/daccess/daccess.cpp
@@ -5888,14 +5888,15 @@ ClrDataAccess::RawGetMethodName(
LPCWSTR wszStubManagerName = pStubManager->GetStubManagerName(TO_TADDR(address));
_ASSERTE(wszStubManagerName != NULL);
- HRESULT hr = StringCchPrintfW(
+ int result = _snwprintf_s(
symbolBuf,
bufLen,
+ _TRUNCATE,
s_wszFormatNameWithStubManager,
wszStubManagerName, // Arg 1 = stub name
TO_TADDR(address)); // Arg 2 = stub hex address
- if (hr == S_OK)
+ if (result != -1)
{
// Printf succeeded, so we have an exact char count to return
if (symbolLen)
@@ -5951,13 +5952,14 @@ NameFromMethodDesc:
// XXX Microsoft - Should this case have a more specific name?
static WCHAR s_wszFormatNameAddressOnly[] = W("CLRStub@%I64x");
- HRESULT hr = StringCchPrintfW(
+ int result = _snwprintf_s(
symbolBuf,
bufLen,
+ _TRUNCATE,
s_wszFormatNameAddressOnly,
TO_TADDR(address));
- if (hr == S_OK)
+ if (result != -1)
{
// Printf succeeded, so we have an exact char count to return
if (symbolLen)
@@ -7352,7 +7354,7 @@ Exit:
//----------------------------------------------------------------------------
//
-// IsExceptionFromManagedCode - report if pExceptionRecord points to a exception belonging to the current runtime
+// IsExceptionFromManagedCode - report if pExceptionRecord points to an exception belonging to the current runtime
//
// Arguments:
// pExceptionRecord - the exception record
@@ -7974,7 +7976,7 @@ HRESULT DacHandleWalker::Init(ClrDataAccess *dac, UINT types[], UINT typeCount,
{
SUPPORTS_DAC;
- if (gen < 0 || gen > (int)GCHeap::GetMaxGeneration())
+ if (gen < 0 || gen > (int)GCHeapUtilities::GetMaxGeneration())
return E_INVALIDARG;
mGenerationFilter = gen;
@@ -8033,7 +8035,7 @@ bool DacHandleWalker::FetchMoreHandles(HANDLESCANPROC callback)
int max_slots = 1;
#ifdef FEATURE_SVR_GC
- if (GCHeap::IsServerHeap())
+ if (GCHeapUtilities::IsServerHeap())
max_slots = GCHeapCount();
#endif // FEATURE_SVR_GC
@@ -8089,7 +8091,7 @@ bool DacHandleWalker::FetchMoreHandles(HANDLESCANPROC callback)
HndScanHandlesForGC(hTable, callback,
(LPARAM)&param, 0,
&handleType, 1,
- mGenerationFilter, GCHeap::GetMaxGeneration(), 0);
+ mGenerationFilter, GCHeapUtilities::GetMaxGeneration(), 0);
else
HndEnumHandles(hTable, &handleType, 1, callback, (LPARAM)&param, 0, FALSE);
}
diff --git a/src/debug/daccess/daccess.targets b/src/debug/daccess/daccess.targets
index a7d9e41554..43da554f47 100644
--- a/src/debug/daccess/daccess.targets
+++ b/src/debug/daccess/daccess.targets
@@ -4,6 +4,12 @@
<!--from the original SOURCES/DIRS file by the KBC tool.-->
<!--*****************************************************-->
<!--Import the settings-->
+ <PropertyGroup>
+ <!-- Work around problems with loading System.Private.CoreLib.dll, -->
+ <!-- caused by inconsistent setting of UseLegacyCompiler and FeatureSpanOfT -->
+ <!-- between System.Private.CoreLib.dll and the runtime. -->
+ <UseLegacyCompiler>true</UseLegacyCompiler>
+ </PropertyGroup>
<Import Project="$(_NTDRIVE)$(_NTROOT)\ndp\clr\clr.props" />
<Import Project="$(_NTDRIVE)$(_NTROOT)\ndp\clr\dac.props" />
<Import Project="..\SetDebugTargetLocal.props" />
diff --git a/src/debug/daccess/dacdbiimpl.cpp b/src/debug/daccess/dacdbiimpl.cpp
index 9b17f4cd46..ae266e8a6f 100644
--- a/src/debug/daccess/dacdbiimpl.cpp
+++ b/src/debug/daccess/dacdbiimpl.cpp
@@ -90,7 +90,7 @@ IDacDbiInterface::IAllocator * g_pAllocator = NULL;
//
// Need a class to serve as a tag that we can use to overload New/Delete.
-#define forDbi (*(forDbiWorker *)NULL)
+forDbiWorker forDbi;
void * operator new(size_t lenBytes, const forDbiWorker &)
{
@@ -2364,10 +2364,12 @@ TypeHandle DacDbiInterfaceImpl::FindLoadedFnptrType(DWORD numTypeArgs, TypeHandl
// Lookup operations run the class loader in non-load mode.
ENABLE_FORBID_GC_LOADER_USE_IN_THIS_SCOPE();
- // @dbgtodo : Do we need to worry about calling convention here?
- return ClassLoader::LoadFnptrTypeThrowing(0,
- numTypeArgs,
- pInst,
+ // @dbgtodo : Do we need to worry about calling convention here?
+ // LoadFnptrTypeThrowing expects the count of arguments, not
+ // including return value, so we subtract 1 from numTypeArgs.
+ return ClassLoader::LoadFnptrTypeThrowing(0,
+ numTypeArgs - 1,
+ pInst,
ClassLoader::DontLoadTypes);
} // DacDbiInterfaceImpl::FindLoadedFnptrType
@@ -6517,7 +6519,7 @@ HRESULT DacHeapWalker::Init(CORDB_ADDRESS start, CORDB_ADDRESS end)
if (thread == NULL)
continue;
- alloc_context *ctx = thread->GetAllocContext();
+ gc_alloc_context *ctx = thread->GetAllocContext();
if (ctx == NULL)
continue;
@@ -6533,7 +6535,7 @@ HRESULT DacHeapWalker::Init(CORDB_ADDRESS start, CORDB_ADDRESS end)
}
#ifdef FEATURE_SVR_GC
- HRESULT hr = GCHeap::IsServerHeap() ? InitHeapDataSvr(mHeaps, mHeapCount) : InitHeapDataWks(mHeaps, mHeapCount);
+ HRESULT hr = GCHeapUtilities::IsServerHeap() ? InitHeapDataSvr(mHeaps, mHeapCount) : InitHeapDataWks(mHeaps, mHeapCount);
#else
HRESULT hr = InitHeapDataWks(mHeaps, mHeapCount);
#endif
@@ -6777,7 +6779,7 @@ HRESULT DacDbiInterfaceImpl::GetHeapSegments(OUT DacDbiArrayList<COR_SEGMENT> *p
HeapData *heaps = 0;
#ifdef FEATURE_SVR_GC
- HRESULT hr = GCHeap::IsServerHeap() ? DacHeapWalker::InitHeapDataSvr(heaps, heapCount) : DacHeapWalker::InitHeapDataWks(heaps, heapCount);
+ HRESULT hr = GCHeapUtilities::IsServerHeap() ? DacHeapWalker::InitHeapDataSvr(heaps, heapCount) : DacHeapWalker::InitHeapDataWks(heaps, heapCount);
#else
HRESULT hr = DacHeapWalker::InitHeapDataWks(heaps, heapCount);
#endif
@@ -6987,6 +6989,21 @@ HRESULT DacDbiInterfaceImpl::GetTypeID(CORDB_ADDRESS dbgObj, COR_TYPEID *pID)
return hr;
}
+HRESULT DacDbiInterfaceImpl::GetTypeIDForType(VMPTR_TypeHandle vmTypeHandle, COR_TYPEID *pID)
+{
+ DD_ENTER_MAY_THROW;
+
+ _ASSERTE(pID != NULL);
+ _ASSERTE(!vmTypeHandle.IsNull());
+
+ TypeHandle th = TypeHandle::FromPtr(vmTypeHandle.GetDacPtr());
+ PTR_MethodTable pMT = th.GetMethodTable();
+ pID->token1 = pMT.GetAddr();
+ _ASSERTE(pID->token1 != 0);
+ pID->token2 = 0;
+ return S_OK;
+}
+
HRESULT DacDbiInterfaceImpl::GetObjectFields(COR_TYPEID id, ULONG32 celt, COR_FIELD *layout, ULONG32 *pceltFetched)
{
if (layout == NULL || pceltFetched == NULL)
@@ -7171,7 +7188,7 @@ void DacDbiInterfaceImpl::GetGCHeapInformation(COR_HEAPINFO * pHeapInfo)
pHeapInfo->areGCStructuresValid = GCScan::GetGcRuntimeStructuresValid();
#ifdef FEATURE_SVR_GC
- if (GCHeap::IsServerHeap())
+ if (GCHeapUtilities::IsServerHeap())
{
pHeapInfo->gcType = CorDebugServerGC;
pHeapInfo->numHeaps = DacGetNumHeaps();
diff --git a/src/debug/daccess/dacdbiimpl.h b/src/debug/daccess/dacdbiimpl.h
index 56d7b0d1d7..a86072325c 100644
--- a/src/debug/daccess/dacdbiimpl.h
+++ b/src/debug/daccess/dacdbiimpl.h
@@ -138,11 +138,13 @@ public:
HRESULT WalkRefs(RefWalkHandle handle, ULONG count, OUT DacGcReference * objects, OUT ULONG *pFetched);
HRESULT GetTypeID(CORDB_ADDRESS obj, COR_TYPEID *pID);
+
+ HRESULT GetTypeIDForType(VMPTR_TypeHandle vmTypeHandle, COR_TYPEID *pID);
- HRESULT GetObjectFields(COR_TYPEID id, ULONG32 celt, COR_FIELD *layout, ULONG32 *pceltFetched);
- HRESULT GetTypeLayout(COR_TYPEID id, COR_TYPE_LAYOUT *pLayout);
- HRESULT GetArrayLayout(COR_TYPEID id, COR_ARRAY_LAYOUT *pLayout);
- void GetGCHeapInformation(COR_HEAPINFO * pHeapInfo);
+ HRESULT GetObjectFields(COR_TYPEID id, ULONG32 celt, COR_FIELD *layout, ULONG32 *pceltFetched);
+ HRESULT GetTypeLayout(COR_TYPEID id, COR_TYPE_LAYOUT *pLayout);
+ HRESULT GetArrayLayout(COR_TYPEID id, COR_ARRAY_LAYOUT *pLayout);
+ void GetGCHeapInformation(COR_HEAPINFO * pHeapInfo);
HRESULT GetPEFileMDInternalRW(VMPTR_PEFile vmPEFile, OUT TADDR* pAddrMDInternalRW);
HRESULT GetReJitInfo(VMPTR_Module vmModule, mdMethodDef methodTk, OUT VMPTR_ReJitInfo* pReJitInfo);
HRESULT GetReJitInfo(VMPTR_MethodDesc vmMethod, CORDB_ADDRESS codeStartAddress, OUT VMPTR_ReJitInfo* pReJitInfo);
diff --git a/src/debug/daccess/dacfn.cpp b/src/debug/daccess/dacfn.cpp
index 88d45993b3..d8bae7746f 100644
--- a/src/debug/daccess/dacfn.cpp
+++ b/src/debug/daccess/dacfn.cpp
@@ -217,7 +217,7 @@ DacWriteAll(TADDR addr, PVOID buffer, ULONG32 size, bool throwEx)
return S_OK;
}
-#if defined(WIN64EXCEPTIONS) && defined(FEATURE_PAL)
+#ifdef FEATURE_PAL
HRESULT
DacVirtualUnwind(DWORD threadId, PCONTEXT context, PT_KNONVOLATILE_CONTEXT_POINTERS contextPointers)
{
@@ -242,7 +242,7 @@ DacVirtualUnwind(DWORD threadId, PCONTEXT context, PT_KNONVOLATILE_CONTEXT_POINT
return hr;
}
-#endif // defined(WIN64EXCEPTIONS) && defined(FEATURE_PAL)
+#endif // FEATURE_PAL
// DacAllocVirtual - Allocate memory from the target process
// Note: this is only available to clients supporting the legacy
diff --git a/src/debug/daccess/enummem.cpp b/src/debug/daccess/enummem.cpp
index 068c2f2b13..d66af05769 100644
--- a/src/debug/daccess/enummem.cpp
+++ b/src/debug/daccess/enummem.cpp
@@ -250,9 +250,9 @@ HRESULT ClrDataAccess::EnumMemCLRStatic(IN CLRDataEnumMemoryFlags flags)
ReportMem(m_globalBase + g_dacGlobals.SharedDomain__m_pSharedDomain,
sizeof(SharedDomain));
- // We need GCHeap pointer to make EEVersion work
+ // We need IGCHeap pointer to make EEVersion work
ReportMem(m_globalBase + g_dacGlobals.dac__g_pGCHeap,
- sizeof(GCHeap *));
+ sizeof(IGCHeap *));
// see synblk.cpp, the pointer is pointed to a static byte[]
SyncBlockCache::s_pSyncBlockCache.EnumMem();
@@ -292,7 +292,9 @@ 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(); )
@@ -316,7 +318,7 @@ HRESULT ClrDataAccess::EnumMemCLRStatic(IN CLRDataEnumMemoryFlags flags)
#ifdef FEATURE_SVR_GC
CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED
(
- GCHeap::gcHeapType.EnumMem();
+ IGCHeap::gcHeapType.EnumMem();
);
#endif // FEATURE_SVR_GC
@@ -796,10 +798,9 @@ HRESULT ClrDataAccess::EnumMemWalkStackHelper(CLRDataEnumMemoryFlags flags,
currentSP = dac_cast<TADDR>(pThread->GetCachedStackLimit()) + sizeof(TADDR);
// exhaust the frames using DAC api
- bool frameHadContext;
for (; status == S_OK; )
{
- frameHadContext = false;
+ bool frameHadContext = false;
status = pStackWalk->GetFrame(&pFrame);
PCODE addr = NULL;
if (status == S_OK && pFrame != NULL)
diff --git a/src/debug/daccess/fntableaccess.cpp b/src/debug/daccess/fntableaccess.cpp
index e7b96ec3e0..6dcd5844e4 100644
--- a/src/debug/daccess/fntableaccess.cpp
+++ b/src/debug/daccess/fntableaccess.cpp
@@ -11,6 +11,7 @@
#include "stdafx.h"
+#ifndef FEATURE_PAL
#ifndef _TARGET_X86_
//
@@ -388,6 +389,7 @@ static NTSTATUS OutOfProcessFunctionTableCallback_Stub(IN ReadMemoryFunction
#endif // DEBUGSUPPORT_STUBS_HAVE_UNWIND_INFO
+
BOOL ReadMemory(PVOID pUserContext, LPCVOID lpBaseAddress, PVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead)
{
HANDLE hProcess = (HANDLE)pUserContext;
@@ -456,6 +458,5 @@ extern "C" NTSTATUS OutOfProcessFunctionTableCallbackEx()
return STATUS_UNSUCCESSFUL;
}
-
-
#endif // !_TARGET_X86_
+#endif // !FEATURE_PAL \ No newline at end of file
diff --git a/src/debug/daccess/fntableaccess.h b/src/debug/daccess/fntableaccess.h
index 0dbabdf8c9..b5ea5452f6 100644
--- a/src/debug/daccess/fntableaccess.h
+++ b/src/debug/daccess/fntableaccess.h
@@ -51,6 +51,9 @@ typedef struct _FakeHpRealCodeHdr
LPVOID phdrDebugInfo;
LPVOID phdrJitEHInfo; // changed from EE_ILEXCEPTION*
LPVOID phdrJitGCInfo; // changed from BYTE*
+#if defined (FEATURE_GDBJIT)
+ LPVOID pCalledMethods;
+#endif
LPVOID hdrMDesc; // changed from MethodDesc*
DWORD nUnwindInfos;
T_RUNTIME_FUNCTION unwindInfos[0];
diff --git a/src/debug/daccess/nidump.cpp b/src/debug/daccess/nidump.cpp
index 32eab498d3..23e76c4fe4 100644
--- a/src/debug/daccess/nidump.cpp
+++ b/src/debug/daccess/nidump.cpp
@@ -1187,12 +1187,12 @@ NativeImageDumper::DumpNativeImage()
mscorlib->fIsMscorlib = TRUE;
_ASSERTE(mscorlib->fIsHardbound);
}
+
+ _ASSERTE(mscorlib != NULL);
if( mscorlib->fIsHardbound )
{
m_isMscorlibHardBound = true;
}
-
- _ASSERTE(mscorlib != NULL);
if( m_isMscorlibHardBound )
{
//go through the module to the binder.
@@ -3120,7 +3120,7 @@ void NativeImageDumper::DumpCompleteMethod(PTR_Module module, MethodIterator& mi
#ifdef _TARGET_X86_
InfoHdr hdr;
stringOutFn( "method info Block:\n" );
- curGCInfoPtr += gcDump.DumpInfoHdr(PTR_CBYTE(gcInfoToken.Info), &hdr, &methodSize, 0);
+ curGCInfoPtr += gcDump.DumpInfoHdr(curGCInfoPtr, &hdr, &methodSize, 0);
stringOutFn( "\n" );
#endif
@@ -4088,6 +4088,7 @@ 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 );
@@ -4105,6 +4106,7 @@ void NativeImageDumper::DumpModule( PTR_Module module )
offsetof(Module, m_pCerNgenRootTable),
fieldsize(Module, m_pCerNgenRootTable) );
}
+#endif
_ASSERTE(module->m_debuggerSpecificData.m_pDynamicILCrst == NULL);
@@ -4152,6 +4154,7 @@ 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 )
@@ -4231,6 +4234,8 @@ void NativeImageDumper::DumpNgenRootTable( PTR_CerNgenRootTable table,
DisplayEndStructure( MODULE ); //CERNgenRootTable
}
+#endif // FEATURE_CER
+
void NativeImageDumper::IterateTypeDefToMTCallback( TADDR mtTarget,
TADDR flags,
PTR_LookupMapBase map,
@@ -9034,12 +9039,14 @@ 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("|"),
@@ -9439,10 +9446,12 @@ void NativeImageDumper::DumpReadyToRunMethod(PCODE pEntryPoint, PTR_RUNTIME_FUNC
g_holdStringOutData.Clear();
GCDump gcDump(GCINFO_VERSION);
gcDump.gcPrintf = stringOutFn;
-#if !defined(_TARGET_X86_) && defined(USE_GC_INFO_DECODER)
UINT32 r2rversion = m_pReadyToRunHeader->MajorVersion;
UINT32 gcInfoVersion = GCInfoToken::ReadyToRunVersionToGcInfoVersion(r2rversion);
- GcInfoDecoder gcInfoDecoder({ curGCInfoPtr, gcInfoVersion }, DECODE_CODE_LENGTH);
+ GCInfoToken gcInfoToken = { curGCInfoPtr, gcInfoVersion };
+
+#if !defined(_TARGET_X86_) && defined(USE_GC_INFO_DECODER)
+ GcInfoDecoder gcInfoDecoder(gcInfoToken, DECODE_CODE_LENGTH);
methodSize = gcInfoDecoder.GetCodeLength();
#endif
@@ -9541,8 +9550,10 @@ mdTypeRef NativeImageDumper::FindTypeRefForMT( PTR_MethodTable mt )
#undef GC_NOTRIGGER
#if defined _DEBUG && defined _TARGET_X86_
+#ifdef _MSC_VER
// disable FPO for checked build
#pragma optimize("y", off)
+#endif // _MSC_VER
#endif
#undef _ASSERTE
diff --git a/src/debug/daccess/request.cpp b/src/debug/daccess/request.cpp
index a30ec37eac..35ab5a0814 100644
--- a/src/debug/daccess/request.cpp
+++ b/src/debug/daccess/request.cpp
@@ -725,7 +725,7 @@ ClrDataAccess::GetHeapAllocData(unsigned int count, struct DacpGenerationAllocDa
SOSDacEnter();
#if defined(FEATURE_SVR_GC)
- if (GCHeap::IsServerHeap())
+ if (GCHeapUtilities::IsServerHeap())
{
hr = GetServerAllocData(count, data, pNeeded);
}
@@ -2809,7 +2809,7 @@ ClrDataAccess::GetGCHeapDetails(CLRDATA_ADDRESS heap, struct DacpGcHeapDetails *
SOSDacEnter();
// doesn't make sense to call this on WKS mode
- if (!GCHeap::IsServerHeap())
+ if (!GCHeapUtilities::IsServerHeap())
hr = E_INVALIDARG;
else
#ifdef FEATURE_SVR_GC
@@ -2884,7 +2884,7 @@ ClrDataAccess::GetHeapSegmentData(CLRDATA_ADDRESS seg, struct DacpHeapSegmentDat
SOSDacEnter();
- if (GCHeap::IsServerHeap())
+ if (GCHeapUtilities::IsServerHeap())
{
#if !defined(FEATURE_SVR_GC)
_ASSERTE(0);
@@ -2924,7 +2924,7 @@ ClrDataAccess::GetGCHeapList(unsigned int count, CLRDATA_ADDRESS heaps[], unsign
SOSDacEnter();
// make sure we called this in appropriate circumstances (i.e., we have multiple heaps)
- if (GCHeap::IsServerHeap())
+ if (GCHeapUtilities::IsServerHeap())
{
#if !defined(FEATURE_SVR_GC)
_ASSERTE(0);
@@ -2960,45 +2960,49 @@ ClrDataAccess::GetGCHeapData(struct DacpGcHeapData *gcheapData)
SOSDacEnter();
- // Now get the heap type. The first data member of the GCHeap class is the GC_HEAP_TYPE, which has
- // three possible values:
+ // for server GC-capable builds only, we need to check and see if IGCHeap::gcHeapType
+ // 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;
+
+ // 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);
- TADDR gcHeapLocation = g_pGCHeap.GetAddrRaw (); // get the starting address of the global GCHeap instance
- size_t gcHeapValue = 0; // this will hold the heap type
- ULONG32 returned = 0;
-
- // @todo Microsoft: we should probably be capturing the HRESULT from ReadVirtual. We could
- // provide a more informative error message. E_FAIL is a wretchedly vague thing to return.
- hr = m_pTarget->ReadVirtual(gcHeapLocation, (PBYTE)&gcHeapValue, sizeof(gcHeapValue), &returned);
-
- //@todo Microsoft: We have an enumerated type, we probably should use the symbolic name
// we have GC_HEAP_INVALID if gcHeapValue == 0, so we're done
- if (SUCCEEDED(hr) && ((returned != sizeof(gcHeapValue)) || (gcHeapValue == 0)))
+ if (gcHeapValue == IGCHeap::GC_HEAP_INVALID)
+ {
hr = E_FAIL;
+ goto cleanup;
+ }
+#endif
- if (SUCCEEDED(hr))
+ // Now we can get other important information about the heap
+ gcheapData->g_max_generation = GCHeapUtilities::GetMaxGeneration();
+ gcheapData->bServerMode = GCHeapUtilities::IsServerHeap();
+ gcheapData->bGcStructuresValid = GCScan::GetGcRuntimeStructuresValid();
+ if (GCHeapUtilities::IsServerHeap())
{
- // Now we can get other important information about the heap
- gcheapData->g_max_generation = GCHeap::GetMaxGeneration();
- gcheapData->bServerMode = GCHeap::IsServerHeap();
- gcheapData->bGcStructuresValid = GCScan::GetGcRuntimeStructuresValid();
- if (GCHeap::IsServerHeap())
- {
#if !defined (FEATURE_SVR_GC)
- _ASSERTE(0);
- gcheapData->HeapCount = 1;
+ _ASSERTE(0);
+ gcheapData->HeapCount = 1;
#else // !defined (FEATURE_SVR_GC)
- gcheapData->HeapCount = GCHeapCount();
+ gcheapData->HeapCount = GCHeapCount();
#endif // !defined (FEATURE_SVR_GC)
- }
- else
- {
- gcheapData->HeapCount = 1;
- }
}
+ else
+ {
+ gcheapData->HeapCount = 1;
+ }
+
+#ifdef FEATURE_SVR_GC
+cleanup:
+ ;
+#endif
SOSDacLeave();
return hr;
@@ -3014,7 +3018,7 @@ ClrDataAccess::GetOOMStaticData(struct DacpOomData *oomData)
memset(oomData, 0, sizeof(DacpOomData));
- if (!GCHeap::IsServerHeap())
+ if (!GCHeapUtilities::IsServerHeap())
{
oom_history* pOOMInfo = &(WKS::gc_heap::oom_info);
oomData->reason = pOOMInfo->reason;
@@ -3043,7 +3047,7 @@ ClrDataAccess::GetOOMData(CLRDATA_ADDRESS oomAddr, struct DacpOomData *data)
SOSDacEnter();
memset(data, 0, sizeof(DacpOomData));
- if (!GCHeap::IsServerHeap())
+ if (!GCHeapUtilities::IsServerHeap())
hr = E_FAIL; // doesn't make sense to call this on WKS mode
#ifdef FEATURE_SVR_GC
@@ -3090,7 +3094,7 @@ ClrDataAccess::GetGCInterestingInfoStaticData(struct DacpGCInterestingInfoData *
SOSDacEnter();
memset(data, 0, sizeof(DacpGCInterestingInfoData));
- if (!GCHeap::IsServerHeap())
+ if (!GCHeapUtilities::IsServerHeap())
{
for (int i = 0; i < NUM_GC_DATA_POINTS; i++)
data->interestingDataPoints[i] = WKS::interesting_data_per_heap[i];
@@ -3123,7 +3127,7 @@ ClrDataAccess::GetGCInterestingInfoData(CLRDATA_ADDRESS interestingInfoAddr, str
SOSDacEnter();
memset(data, 0, sizeof(DacpGCInterestingInfoData));
- if (!GCHeap::IsServerHeap())
+ if (!GCHeapUtilities::IsServerHeap())
hr = E_FAIL; // doesn't make sense to call this on WKS mode
#ifdef FEATURE_SVR_GC
@@ -3149,7 +3153,7 @@ ClrDataAccess::GetHeapAnalyzeData(CLRDATA_ADDRESS addr, struct DacpGcHeapAnalyz
SOSDacEnter();
- if (!GCHeap::IsServerHeap())
+ if (!GCHeapUtilities::IsServerHeap())
hr = E_FAIL; // doesn't make sense to call this on WKS mode
#ifdef FEATURE_SVR_GC
@@ -3856,7 +3860,7 @@ ClrDataAccess::EnumWksGlobalMemoryRegions(CLRDataEnumMemoryFlags flags)
// 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 = GCHeap::GetMaxGeneration(); i <= GCHeap::GetMaxGeneration()+1; i++)
+ for (ULONG i = GCHeapUtilities::GetMaxGeneration(); i <= GCHeapUtilities::GetMaxGeneration()+1; i++)
{
__DPtr<WKS::heap_segment> seg = dac_cast<TADDR>(WKS::generation_table[i].start_segment);
while (seg)
diff --git a/src/debug/daccess/request_svr.cpp b/src/debug/daccess/request_svr.cpp
index 429f30020f..1fe20e2b60 100644
--- a/src/debug/daccess/request_svr.cpp
+++ b/src/debug/daccess/request_svr.cpp
@@ -256,7 +256,7 @@ ClrDataAccess::EnumSvrGlobalMemoryRegions(CLRDataEnumMemoryFlags flags)
// 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 = GCHeap::GetMaxGeneration(); i <= GCHeap::GetMaxGeneration()+1; i++)
+ for (ULONG i = GCHeapUtilities::GetMaxGeneration(); i <= GCHeapUtilities::GetMaxGeneration()+1; i++)
{
__DPtr<SVR::heap_segment> seg = dac_cast<TADDR>(pHeap->generation_table[i].start_segment);
while (seg)
@@ -271,7 +271,7 @@ ClrDataAccess::EnumSvrGlobalMemoryRegions(CLRDataEnumMemoryFlags flags)
DWORD DacGetNumHeaps()
{
- if (GCHeap::IsServerHeap())
+ if (GCHeapUtilities::IsServerHeap())
return (DWORD)SVR::gc_heap::n_heaps;
// workstation gc
diff --git a/src/debug/di/breakpoint.cpp b/src/debug/di/breakpoint.cpp
index 1e381a5f83..e3e4fb04a5 100644
--- a/src/debug/di/breakpoint.cpp
+++ b/src/debug/di/breakpoint.cpp
@@ -15,7 +15,7 @@
CordbBreakpoint::CordbBreakpoint(CordbProcess * pProcess, CordbBreakpointType bpType)
: CordbBase(pProcess, 0, enumCordbBreakpoint),
- m_active(false), m_type(bpType)
+ m_active(false), m_pAppDomain(NULL), m_type(bpType)
{
}
diff --git a/src/debug/di/module.cpp b/src/debug/di/module.cpp
index 6717e8575f..36cc6f5f9e 100644
--- a/src/debug/di/module.cpp
+++ b/src/debug/di/module.cpp
@@ -3755,7 +3755,269 @@ HRESULT FindNativeInfoInILVariableArray(DWORD
return CORDBG_E_IL_VAR_NOT_AVAILABLE;
} // FindNativeInfoInILVariableArray
-//* ------------------------------------------------------------------------- *
+
+// * ------------------------------------------------------------------------- *
+// * Variable Enum class
+// * ------------------------------------------------------------------------- *
+//-----------------------------------------------------------------------------
+// CordbVariableHome constructor
+// Arguments:
+// Input:
+// pCode - CordbNativeCode instance containing this variable home
+// pNativeVarInfo - native location, lifetime, and index information for
+// this variable
+// isLocal - indicates whether the instance is a local variable,
+// as opposed to an argument
+// index - the argument or slot index
+// Output:
+// fields of the CordbVariableHome instance have been initialized
+//-----------------------------------------------------------------------------
+CordbVariableHome::CordbVariableHome(CordbNativeCode *pCode,
+ const ICorDebugInfo::NativeVarInfo nativeVarInfo,
+ BOOL isLocal,
+ ULONG index) :
+ CordbBase(pCode->GetModule()->GetProcess(), 0)
+{
+ _ASSERTE(pCode != NULL);
+
+ m_pCode.Assign(pCode);
+ m_nativeVarInfo = nativeVarInfo;
+ m_isLocal = isLocal;
+ m_index = index;
+}
+
+CordbVariableHome::~CordbVariableHome()
+{
+ _ASSERTE(this->IsNeutered());
+}
+
+void CordbVariableHome::Neuter()
+{
+ m_pCode.Clear();
+ CordbBase::Neuter();
+}
+
+//-----------------------------------------------------------------------------
+// Public method for IUnknown::QueryInterface.
+// Has standard QI semantics.
+//-----------------------------------------------------------------------------
+HRESULT CordbVariableHome::QueryInterface(REFIID id, void **pInterface)
+{
+ if (id == IID_ICorDebugVariableHome)
+ {
+ *pInterface = static_cast<ICorDebugVariableHome *>(this);
+ }
+ else if (id == IID_IUnknown)
+ {
+ *pInterface = static_cast<IUnknown *>(static_cast<ICorDebugVariableHome *>(this));
+ }
+ else
+ {
+ *pInterface = NULL;
+ return E_NOINTERFACE;
+ }
+
+ ExternalAddRef();
+ return S_OK;
+}
+
+//-----------------------------------------------------------------------------
+// CordbVariableHome::GetCode
+// Public method to get the Code object containing this variable home.
+//
+// Parameters:
+// ppCode - OUT: returns the Code object for this variable home.
+//
+// Returns:
+// S_OK - on success.
+//-----------------------------------------------------------------------------
+HRESULT CordbVariableHome::GetCode(ICorDebugCode **ppCode)
+{
+ PUBLIC_REENTRANT_API_ENTRY(this);
+ FAIL_IF_NEUTERED(this);
+ VALIDATE_POINTER_TO_OBJECT(ppCode, ICorDebugCode **);
+ ATT_REQUIRE_STOPPED_MAY_FAIL(m_pCode->GetProcess());
+
+ HRESULT hr = m_pCode->QueryInterface(IID_ICorDebugCode, (LPVOID*)ppCode);
+
+ return hr;
+}
+
+//-----------------------------------------------------------------------------
+// CordbVariableHome::GetSlotIndex
+// Public method to get the slot index for this variable home.
+//
+// Parameters:
+// pSlotIndex - OUT: returns the managed slot-index of this variable home.
+//
+// Returns:
+// S_OK - on success
+// E_FAIL - if the variable is not a local variable, but an argument
+//-----------------------------------------------------------------------------
+HRESULT CordbVariableHome::GetSlotIndex(ULONG32 *pSlotIndex)
+{
+ PUBLIC_REENTRANT_API_ENTRY(this);
+ FAIL_IF_NEUTERED(this);
+ VALIDATE_POINTER_TO_OBJECT(pSlotIndex, ULONG32 *);
+ ATT_REQUIRE_STOPPED_MAY_FAIL(m_pCode->GetProcess());
+
+ if (!m_isLocal)
+ {
+ return E_FAIL;
+ }
+ *pSlotIndex = m_index;
+ return S_OK;
+}
+
+//-----------------------------------------------------------------------------
+// CordbVariableHome::GetArgumentIndex
+// Public method to get the slot index for this variable home.
+//
+// Parameters:
+// pSlotIndex - OUT: returns the managed argument-index of this variable home.
+//
+// Returns:
+// S_OK - on success
+// E_FAIL - if the variable is not an argument, but a local variable
+//-----------------------------------------------------------------------------
+HRESULT CordbVariableHome::GetArgumentIndex(ULONG32 *pArgumentIndex)
+{
+ PUBLIC_REENTRANT_API_ENTRY(this);
+ FAIL_IF_NEUTERED(this);
+ VALIDATE_POINTER_TO_OBJECT(pArgumentIndex, ULONG32 *);
+ ATT_REQUIRE_STOPPED_MAY_FAIL(m_pCode->GetProcess());
+
+ if (m_isLocal)
+ {
+ return E_FAIL;
+ }
+ *pArgumentIndex = m_index;
+ return S_OK;
+}
+
+//-----------------------------------------------------------------------------
+// CordbVariableHome::GetLiveRange
+// Public method to get the native range over which this variable is live.
+//
+// Parameters:
+// pStartOffset - OUT: returns the logical offset at which the variable is
+// first live
+// pEndOffset - OUT: returns the logical offset immediately after that at
+// which the variable is last live
+//
+// Returns:
+// S_OK - on success
+//-----------------------------------------------------------------------------
+HRESULT CordbVariableHome::GetLiveRange(ULONG32 *pStartOffset,
+ ULONG32 *pEndOffset)
+{
+ PUBLIC_REENTRANT_API_ENTRY(this);
+ FAIL_IF_NEUTERED(this);
+ VALIDATE_POINTER_TO_OBJECT(pStartOffset, ULONG32 *);
+ VALIDATE_POINTER_TO_OBJECT(pEndOffset, ULONG32 *);
+ ATT_REQUIRE_STOPPED_MAY_FAIL(m_pCode->GetProcess());
+
+ *pStartOffset = m_nativeVarInfo.startOffset;
+ *pEndOffset = m_nativeVarInfo.endOffset;
+ return S_OK;
+}
+
+//-----------------------------------------------------------------------------
+// CordbVariableHome::GetLocationType
+// Public method to get the type of native location for this variable home.
+//
+// Parameters:
+// pLocationType - OUT: the type of native location
+//
+// Returns:
+// S_OK - on success
+//-----------------------------------------------------------------------------
+HRESULT CordbVariableHome::GetLocationType(VariableLocationType *pLocationType)
+{
+ PUBLIC_REENTRANT_API_ENTRY(this);
+ FAIL_IF_NEUTERED(this);
+ VALIDATE_POINTER_TO_OBJECT(pLocationType, VariableLocationType *);
+ ATT_REQUIRE_STOPPED_MAY_FAIL(m_pCode->GetProcess());
+
+ switch (m_nativeVarInfo.loc.vlType)
+ {
+ case ICorDebugInfo::VLT_REG:
+ *pLocationType = VLT_REGISTER;
+ break;
+ case ICorDebugInfo::VLT_STK:
+ *pLocationType = VLT_REGISTER_RELATIVE;
+ break;
+ default:
+ *pLocationType = VLT_INVALID;
+ }
+ return S_OK;
+}
+
+//-----------------------------------------------------------------------------
+// CordbVariableHome::GetRegister
+// Public method to get the register or base register for this variable hom.
+//
+// Parameters:
+// pRegister - OUT: for VLT_REGISTER location types, gives the register.
+// for VLT_REGISTER_RELATIVE location types, gives the base
+// register.
+//
+// Returns:
+// S_OK - on success
+// E_FAIL - for VLT_INVALID location types
+//-----------------------------------------------------------------------------
+HRESULT CordbVariableHome::GetRegister(CorDebugRegister *pRegister)
+{
+ PUBLIC_REENTRANT_API_ENTRY(this);
+ FAIL_IF_NEUTERED(this);
+ VALIDATE_POINTER_TO_OBJECT(pRegister, CorDebugRegister *);
+ ATT_REQUIRE_STOPPED_MAY_FAIL(m_pCode->GetProcess());
+
+ switch (m_nativeVarInfo.loc.vlType)
+ {
+ case ICorDebugInfo::VLT_REG:
+ *pRegister = ConvertRegNumToCorDebugRegister(m_nativeVarInfo.loc.vlReg.vlrReg);
+ break;
+ case ICorDebugInfo::VLT_STK:
+ *pRegister = ConvertRegNumToCorDebugRegister(m_nativeVarInfo.loc.vlStk.vlsBaseReg);
+ break;
+ default:
+ return E_FAIL;
+ }
+ return S_OK;
+}
+
+//-----------------------------------------------------------------------------
+// CordbVariableHome::GetOffset
+// Public method to get the offset from the base register for this variable home.
+//
+// Parameters:
+// pOffset - OUT: gives the offset from the base register
+//
+// Returns:
+// S_OK - on success
+// E_FAIL - for location types other than VLT_REGISTER_RELATIVE
+//-----------------------------------------------------------------------------
+HRESULT CordbVariableHome::GetOffset(LONG *pOffset)
+{
+ PUBLIC_REENTRANT_API_ENTRY(this);
+ FAIL_IF_NEUTERED(this);
+ VALIDATE_POINTER_TO_OBJECT(pOffset, LONG *);
+ ATT_REQUIRE_STOPPED_MAY_FAIL(m_pCode->GetProcess());
+
+ switch (m_nativeVarInfo.loc.vlType)
+ {
+ case ICorDebugInfo::VLT_STK:
+ *pOffset = m_nativeVarInfo.loc.vlStk.vlsOffset;
+ break;
+ default:
+ return E_FAIL;
+ }
+ return S_OK;
+}
+
+
+// * ------------------------------------------------------------------------- *
// * Native Code class
// * ------------------------------------------------------------------------- */
@@ -3780,7 +4042,7 @@ CordbNativeCode::CordbNativeCode(CordbFunction * pFunction,
m_fIsInstantiatedGeneric(fIsInstantiatedGeneric != FALSE)
{
_ASSERTE(GetVersion() >= CorDB_DEFAULT_ENC_FUNCTION_VERSION);
-
+
for (CodeBlobRegion region = kHot; region < MAX_REGIONS; ++region)
{
m_rgCodeRegions[region] = pJitData->m_rgCodeRegions[region];
@@ -3805,6 +4067,10 @@ HRESULT CordbNativeCode::QueryInterface(REFIID id, void ** pInterface)
{
*pInterface = static_cast<ICorDebugCode3 *>(this);
}
+ else if (id == IID_ICorDebugCode4)
+ {
+ *pInterface = static_cast<ICorDebugCode4 *>(this);
+ }
else if (id == IID_IUnknown)
{
*pInterface = static_cast<IUnknown *>(static_cast<ICorDebugCode *>(this));
@@ -4111,6 +4377,113 @@ HRESULT CordbNativeCode::GetReturnValueLiveOffset(ULONG32 ILoffset, ULONG32 buff
return hr;
}
+//-----------------------------------------------------------------------------
+// CordbNativeCode::EnumerateVariableHomes
+// Public method to get an enumeration of native variable homes. This may
+// include multiple ICorDebugVariableHomes for the same slot or argument index
+// if they have different homes at different points in the function.
+//
+// Parameters:
+// ppEnum - OUT: returns the enum of variable homes.
+//
+// Returns:
+// HRESULT for success or failure.
+//-----------------------------------------------------------------------------
+HRESULT CordbNativeCode::EnumerateVariableHomes(ICorDebugVariableHomeEnum **ppEnum)
+{
+ PUBLIC_REENTRANT_API_ENTRY(this);
+ FAIL_IF_NEUTERED(this);
+ VALIDATE_POINTER_TO_OBJECT(ppEnum, ICorDebugVariableHomeEnum **);
+ ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());
+
+ HRESULT hr = S_OK;
+
+ // Get the argument count
+ ULONG argCount = 0;
+ CordbFunction *func = GetFunction();
+ _ASSERTE(func != NULL);
+ IfFailRet(func->GetSig(NULL, &argCount, NULL));
+
+#ifdef _DEBUG
+ // Get the number of locals
+ ULONG localCount = 0;
+ EX_TRY
+ {
+ GetFunction()->GetILCode()->GetLocalVarSig(NULL, &localCount);
+ }
+ EX_CATCH_HRESULT(hr);
+ IfFailRet(hr);
+#endif
+
+ RSSmartPtr<CordbVariableHome> *rsHomes = NULL;
+
+ EX_TRY
+ {
+ CordbProcess *pProcess = GetProcess();
+ _ASSERTE(pProcess != NULL);
+
+ const DacDbiArrayList<ICorDebugInfo::NativeVarInfo> *pOffsetInfoList = m_nativeVarData.GetOffsetInfoList();
+ _ASSERTE(pOffsetInfoList != NULL);
+ DWORD countHomes = 0;
+ for (int i = 0; i < pOffsetInfoList->Count(); i++)
+ {
+ const ICorDebugInfo::NativeVarInfo *pNativeVarInfo = &((*pOffsetInfoList)[i]);
+ _ASSERTE(pNativeVarInfo != NULL);
+
+ // The variable information list can include variables
+ // with special varNumbers representing, for instance, the
+ // parameter types for generic methods. Here we are only
+ // interested in local variables and arguments.
+ if (pNativeVarInfo->varNumber < (DWORD)ICorDebugInfo::MAX_ILNUM)
+ {
+ countHomes++;
+ }
+ }
+ rsHomes = new RSSmartPtr<CordbVariableHome>[countHomes];
+
+ DWORD varHomeInd = 0;
+ for (int i = 0; i < pOffsetInfoList->Count(); i++)
+ {
+ const ICorDebugInfo::NativeVarInfo *pNativeVarInfo = &((*pOffsetInfoList)[i]);
+
+ // Again, only look for native var info representing local
+ // variables and arguments.
+ if (pNativeVarInfo->varNumber < (DWORD)ICorDebugInfo::MAX_ILNUM)
+ {
+ // determine whether this variable home represents and argument or local variable
+ BOOL isLocal = ((ULONG)pNativeVarInfo->varNumber >= argCount);
+
+ // determine the argument-index or slot-index of this variable home
+ ULONG argOrSlotIndex;
+ if (isLocal) {
+ argOrSlotIndex = pNativeVarInfo->varNumber - argCount;
+ _ASSERTE(argOrSlotIndex < localCount);
+ } else {
+ argOrSlotIndex = pNativeVarInfo->varNumber;
+ }
+
+ RSInitHolder<CordbVariableHome> pCVH(new CordbVariableHome(this,
+ (*pOffsetInfoList)[i],
+ isLocal,
+ argOrSlotIndex));
+ pProcess->GetContinueNeuterList()->Add(pProcess, pCVH);
+ _ASSERTE(varHomeInd < countHomes);
+ rsHomes[varHomeInd].Assign(pCVH);
+ pCVH.ClearAndMarkDontNeuter();
+ varHomeInd++;
+ }
+ }
+
+ RSInitHolder<CordbVariableHomeEnumerator> pCDVHE(
+ new CordbVariableHomeEnumerator(GetProcess(), &rsHomes, countHomes));
+ pProcess->GetContinueNeuterList()->Add(pProcess, pCDVHE);
+ pCDVHE.TransferOwnershipExternal(ppEnum);
+ }
+ EX_CATCH_HRESULT(hr);
+
+ return hr;
+}
+
int CordbNativeCode::GetCallInstructionLength(BYTE *ip, ULONG32 count)
{
#if defined(DBG_TARGET_ARM)
diff --git a/src/debug/di/process.cpp b/src/debug/di/process.cpp
index 44e4a0c667..a5496eee54 100644
--- a/src/debug/di/process.cpp
+++ b/src/debug/di/process.cpp
@@ -7334,6 +7334,7 @@ CordbUnmanagedThread *CordbProcess::HandleUnmanagedCreateThread(DWORD dwThreadId
if (!SUCCEEDED(hr))
{
delete ut;
+ ut = NULL;
LOG((LF_CORDB, LL_INFO10000, "Failed adding unmanaged thread to process!\n"));
CORDBSetUnrecoverableError(this, hr, 0);
@@ -8119,7 +8120,9 @@ void CordbProcess::DispatchUnmanagedInBandEvent()
break;
// Get the thread for this event
+ _ASSERTE(pUnmanagedThread == NULL);
pUnmanagedThread = pUnmanagedEvent->m_owner;
+ _ASSERTE(pUnmanagedThread != NULL);
// We better not have dispatched it yet!
_ASSERTE(!pUnmanagedEvent->IsDispatched());
@@ -8177,13 +8180,10 @@ void CordbProcess::DispatchUnmanagedInBandEvent()
m_pShim->GetWin32EventThread()->DoDbgContinue(this, pUnmanagedEvent);
// Release our reference to the unmanaged thread that we dispatched
- if (pUnmanagedThread)
- {
- // This event should have been continued long ago...
- _ASSERTE(!pUnmanagedThread->IBEvent()->IsEventWaitingForContinue());
- pUnmanagedThread->InternalRelease();
- pUnmanagedThread = NULL;
- }
+ // This event should have been continued long ago...
+ _ASSERTE(!pUnmanagedThread->IBEvent()->IsEventWaitingForContinue());
+ pUnmanagedThread->InternalRelease();
+ pUnmanagedThread = NULL;
}
m_dispatchingUnmanagedEvent = false;
diff --git a/src/debug/di/rsenumerator.hpp b/src/debug/di/rsenumerator.hpp
index eb7a225a5d..84e6194c4d 100644
--- a/src/debug/di/rsenumerator.hpp
+++ b/src/debug/di/rsenumerator.hpp
@@ -99,8 +99,8 @@ CordbEnumerator<ElemType,
ElemType **items,
DWORD countItems) :
CordbBase(pProcess, 0, enumCordbEnumerator),
-m_nextIndex(0),
-m_countItems(countItems)
+m_countItems(countItems),
+m_nextIndex(0)
{
_ASSERTE(items != NULL);
m_items = *items;
@@ -108,7 +108,7 @@ m_countItems(countItems)
}
// Destructor
-template< typename ElemType,
+template< typename ElemType,
typename ElemPublicType,
typename EnumInterfaceType,
ElemPublicType (*GetPublicType)(ElemType)>
diff --git a/src/debug/di/rsmain.cpp b/src/debug/di/rsmain.cpp
index b5685750db..0f5778789f 100644
--- a/src/debug/di/rsmain.cpp
+++ b/src/debug/di/rsmain.cpp
@@ -40,6 +40,8 @@
RSDebuggingInfo g_RSDebuggingInfo_OutOfProc = {0 }; // set to NULL
RSDebuggingInfo * g_pRSDebuggingInfo = &g_RSDebuggingInfo_OutOfProc;
+// The following instances are used for invoking overloaded new/delete
+forDbiWorker forDbi;
#ifdef _DEBUG
// For logs, we can print the string name for the debug codes.
diff --git a/src/debug/di/rspriv.h b/src/debug/di/rspriv.h
index 853767804a..18920add5d 100644
--- a/src/debug/di/rspriv.h
+++ b/src/debug/di/rspriv.h
@@ -85,6 +85,7 @@ class CordbJITILFrame;
class CordbInternalFrame;
class CordbContext;
class CordbThread;
+class CordbVariableHome;
#ifdef FEATURE_INTEROP_DEBUGGING
class CordbUnmanagedThread;
@@ -176,7 +177,7 @@ private:
USHORT m_usPort;
};
-#define forDbi (*(forDbiWorker *)NULL)
+extern forDbiWorker forDbi;
// for dbi we just default to new, but we need to have these defined for both dac and dbi
inline void * operator new(size_t lenBytes, const forDbiWorker &)
@@ -1586,7 +1587,7 @@ template< typename ElemType,
typename ElemPublicType,
typename EnumInterfaceType,
ElemPublicType (*GetPublicType)(ElemType)>
-class CordbEnumerator : public CordbBase, EnumInterfaceType
+class CordbEnumerator : public CordbBase, public EnumInterfaceType
{
private:
// the list of items being enumerated over
@@ -1680,6 +1681,11 @@ typedef CordbEnumerator<RsGuidToTypeMapping,
ICorDebugGuidToTypeEnum,
GuidToTypeMappingConvert > CordbGuidToTypeEnumerator;
+typedef CordbEnumerator<RSSmartPtr<CordbVariableHome>,
+ ICorDebugVariableHome*,
+ ICorDebugVariableHomeEnum,
+ QueryInterfaceConvert<RSSmartPtr<CordbVariableHome>, ICorDebugVariableHome> > CordbVariableHomeEnumerator;
+
// ----------------------------------------------------------------------------
// Hash table for CordbBase objects.
// - Uses Internal AddRef/Release (not external)
@@ -2920,7 +2926,7 @@ class CordbProcess :
public ICorDebugProcess4,
public ICorDebugProcess5,
public ICorDebugProcess7,
- public ICorDebugProcess8,
+ public ICorDebugProcess8,
public IDacDbiInterface::IAllocator,
public IDacDbiInterface::IMetaDataLookup,
public IProcessShimHooks
@@ -4696,7 +4702,7 @@ public:
// See definition of ICorDebugType for further invariants on types.
//
-class CordbType : public CordbBase, public ICorDebugType
+class CordbType : public CordbBase, public ICorDebugType, public ICorDebugType2
{
public:
CordbType(CordbAppDomain *appdomain, CorElementType ty, unsigned int rank);
@@ -4736,6 +4742,11 @@ public:
COM_METHOD GetRank(ULONG32 *pnRank);
//-----------------------------------------------------------
+ // ICorDebugType2
+ //-----------------------------------------------------------
+ COM_METHOD GetTypeID(COR_TYPEID *pId);
+
+ //-----------------------------------------------------------
// Non-COM members
//-----------------------------------------------------------
@@ -5812,7 +5823,10 @@ private:
* code, including an optional set of mappings from IL to offsets in the native Code.
* ------------------------------------------------------------------------- */
-class CordbNativeCode : public CordbCode, public ICorDebugCode2, public ICorDebugCode3
+class CordbNativeCode : public CordbCode,
+ public ICorDebugCode2,
+ public ICorDebugCode3,
+ public ICorDebugCode4
{
public:
CordbNativeCode(CordbFunction * pFunction,
@@ -5853,6 +5867,11 @@ public:
//-----------------------------------------------------------
+ // ICorDebugCode4
+ //-----------------------------------------------------------
+ COM_METHOD EnumerateVariableHomes(ICorDebugVariableHomeEnum **ppEnum);
+
+ //-----------------------------------------------------------
// Internal members
//-----------------------------------------------------------
@@ -8539,6 +8558,63 @@ private:
typedef enum {kUnboxed, kBoxed} BoxedValue;
#define EMPTY_BUFFER TargetBuffer(PTR_TO_CORDB_ADDRESS((void *)NULL), 0)
+/* ------------------------------------------------------------------------- *
+ * Variable Home class
+ * ------------------------------------------------------------------------- */
+class CordbVariableHome : public CordbBase, public ICorDebugVariableHome
+{
+public:
+ CordbVariableHome(CordbNativeCode *pCode,
+ const ICorDebugInfo::NativeVarInfo nativeVarInfo,
+ BOOL isLoc,
+ ULONG index);
+ ~CordbVariableHome();
+ virtual void Neuter();
+
+#ifdef _DEBUG
+ virtual const char * DbgGetName() { return "CordbVariableHome"; }
+#endif
+
+ //-----------------------------------------------------------
+ // IUnknown
+ //-----------------------------------------------------------
+ ULONG STDMETHODCALLTYPE AddRef()
+ {
+ return (BaseAddRef());
+ }
+ ULONG STDMETHODCALLTYPE Release()
+ {
+ return (BaseRelease());
+ }
+
+ COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
+
+ //-----------------------------------------------------------
+ // ICorDebugVariableHome
+ //-----------------------------------------------------------
+
+ COM_METHOD GetCode(ICorDebugCode **ppCode);
+
+ COM_METHOD GetSlotIndex(ULONG32 *pSlotIndex);
+
+ COM_METHOD GetArgumentIndex(ULONG32* pArgumentIndex);
+
+ COM_METHOD GetLiveRange(ULONG32* pStartOffset,
+ ULONG32 *pEndOffset);
+
+ COM_METHOD GetLocationType(VariableLocationType *pLocationType);
+
+ COM_METHOD GetRegister(CorDebugRegister *pRegister);
+
+ COM_METHOD GetOffset(LONG *pOffset);
+private:
+ RSSmartPtr<CordbNativeCode> m_pCode;
+ ICorDebugInfo::NativeVarInfo m_nativeVarInfo;
+ BOOL m_isLocal;
+ ULONG m_index;
+};
+
+
// for an inheritance graph of the ICDValue types, // See file:./ICorDebugValueTypes.vsd for a diagram of the types.
/* ------------------------------------------------------------------------- *
* Value class
diff --git a/src/debug/di/rspriv.inl b/src/debug/di/rspriv.inl
index 00e4c233b6..5de99c6284 100644
--- a/src/debug/di/rspriv.inl
+++ b/src/debug/di/rspriv.inl
@@ -162,7 +162,7 @@ void CordbProcess::ForceDacFlush()
{
if (m_pDacPrimitives != NULL)
{
- STRESS_LOG1(LF_CORDB, LL_INFO1000, "Flush() - old counter: %d", m_flushCounter);
+ STRESS_LOG1(LF_CORDB, LL_INFO1000, "Flush() - old counter: %d\n", m_flushCounter);
m_flushCounter++;
HRESULT hr = S_OK;
EX_TRY
diff --git a/src/debug/di/rsthread.cpp b/src/debug/di/rsthread.cpp
index ae9b43cd01..a4660be570 100644
--- a/src/debug/di/rsthread.cpp
+++ b/src/debug/di/rsthread.cpp
@@ -1493,7 +1493,7 @@ void CordbThread::Get32bitFPRegisters(CONTEXT * pContext)
for (i = 0; i <= floatStackTop; i++)
{
- long double td;
+ double td = 0.0;
__asm fstp td // copy out the double
m_floatValues[i] = td;
}
@@ -4585,7 +4585,7 @@ void CordbUnmanagedThread::SaveRaiseExceptionEntryContext()
LOG((LF_CORDB, LL_INFO1000, "CP::SREEC: failed to read exception information pointer.\n"));
return;
}
-#elif
+#else
_ASSERTE(!"Implement this for your platform");
return;
#endif
@@ -8935,8 +8935,13 @@ HRESULT CordbJITILFrame::GetReturnValueForILOffsetImpl(ULONG32 ILoffset, ICorDeb
bool found = false;
ULONG32 currentOffset = m_nativeFrame->GetIPOffset();
for (ULONG32 i = 0; i < count; ++i)
- if ((found = currentOffset == offsets[i]))
+ {
+ if (currentOffset == offsets[i])
+ {
+ found = true;
break;
+ }
+ }
if (!found)
return E_UNEXPECTED;
diff --git a/src/debug/di/rstype.cpp b/src/debug/di/rstype.cpp
index b183fdf39e..e537613412 100644
--- a/src/debug/di/rstype.cpp
+++ b/src/debug/di/rstype.cpp
@@ -276,6 +276,8 @@ HRESULT CordbType::QueryInterface(REFIID id, void **pInterface)
{
if (id == IID_ICorDebugType)
*pInterface = static_cast<ICorDebugType*>(this);
+ else if (id == IID_ICorDebugType2)
+ *pInterface = static_cast<ICorDebugType2*>(this);
else if (id == IID_IUnknown)
*pInterface = static_cast<IUnknown*>(static_cast<ICorDebugType*>(this));
else
@@ -2280,6 +2282,126 @@ HRESULT CordbType::GetBase(ICorDebugType ** ppType)
return hr;
}
+//-----------------------------------------------------------------------------
+// CordbType::GetTypeID
+// Method to get the COR_TYPEID corresponding to this CordbType.
+//
+// Parameters:
+// pId - OUT: gives the COR_TYPEID for this CordbType
+//
+// Returns:
+// S_OK if succeeded.
+// CORDBG_E_CLASS_NOT_LOADED if the type which this CordbType represents has
+// not been loaded in the runtime.
+// E_POINTER if pId is NULL
+// CORDBG_E_UNSUPPORTED for unsupported types.
+//
+HRESULT CordbType::GetTypeID(COR_TYPEID *pId)
+{
+ LOG((LF_CORDB, LL_INFO1000, "GetTypeID\n"));
+ if (pId == NULL)
+ return E_POINTER;
+
+ HRESULT hr = S_OK;
+
+ PUBLIC_API_ENTRY(this);
+ RSLockHolder stopGoLock(GetProcess()->GetStopGoLock());
+ RSLockHolder procLock(GetProcess()->GetProcessLock());
+
+ EX_TRY
+ {
+ hr = Init(FALSE);
+ IfFailThrow(hr);
+
+ VMPTR_TypeHandle vmTypeHandle;
+
+ CorElementType et = GetElementType();
+ switch (et)
+ {
+ case ELEMENT_TYPE_OBJECT:
+ case ELEMENT_TYPE_VOID:
+ case ELEMENT_TYPE_BOOLEAN:
+ case ELEMENT_TYPE_CHAR:
+ case ELEMENT_TYPE_I1:
+ case ELEMENT_TYPE_U1:
+ case ELEMENT_TYPE_I2:
+ case ELEMENT_TYPE_U2:
+ case ELEMENT_TYPE_I4:
+ case ELEMENT_TYPE_U4:
+ case ELEMENT_TYPE_I8:
+ case ELEMENT_TYPE_U8:
+ case ELEMENT_TYPE_R4:
+ case ELEMENT_TYPE_R8:
+ case ELEMENT_TYPE_STRING:
+ case ELEMENT_TYPE_TYPEDBYREF:
+ case ELEMENT_TYPE_I:
+ case ELEMENT_TYPE_U:
+ {
+ mdTypeDef mdToken;
+ VMPTR_Module vmModule = VMPTR_Module::NullPtr();
+ VMPTR_DomainFile vmDomainFile = VMPTR_DomainFile::NullPtr();
+
+ // get module and token of the simple type
+ GetProcess()->GetDAC()->GetSimpleType(GetAppDomain()->GetADToken(),
+ et,
+ &mdToken,
+ &vmModule,
+ &vmDomainFile);
+
+ vmTypeHandle = GetProcess()->GetDAC()->GetTypeHandle(vmModule, mdToken);
+ }
+ break;
+ case ELEMENT_TYPE_ARRAY:
+ case ELEMENT_TYPE_SZARRAY:
+ {
+ LOG((LF_CORDB, LL_INFO1000, "GetTypeID: parameterized type\n"));
+ if (m_typeHandleExact.IsNull())
+ {
+ hr = InitInstantiationTypeHandle(FALSE);
+ IfFailThrow(hr);
+ }
+ vmTypeHandle = m_typeHandleExact;
+ }
+ break;
+ case ELEMENT_TYPE_CLASS:
+ {
+ ICorDebugClass *pICDClass = NULL;
+ hr = GetClass(&pICDClass);
+ IfFailThrow(hr);
+ CordbClass *pClass = (CordbClass*)pICDClass;
+ _ASSERTE(pClass != NULL);
+
+ if (pClass->HasTypeParams())
+ {
+ vmTypeHandle = m_typeHandleExact;
+ }
+ else
+ {
+ mdTypeDef mdToken;
+ hr = pClass->GetToken(&mdToken);
+ IfFailThrow(hr);
+
+ VMPTR_Module vmModule = GetModule();
+ vmTypeHandle = GetProcess()->GetDAC()->GetTypeHandle(vmModule, mdToken);
+ }
+ }
+ break;
+ case ELEMENT_TYPE_PTR:
+ case ELEMENT_TYPE_BYREF:
+ case ELEMENT_TYPE_FNPTR:
+ IfFailThrow(CORDBG_E_UNSUPPORTED);
+ default:
+ _ASSERTE(!"unexpected element type!");
+ IfFailThrow(CORDBG_E_UNSUPPORTED);
+ break;
+ }
+
+ GetProcess()->GetDAC()->GetTypeIDForType(vmTypeHandle, pId);
+ }
+ EX_CATCH_HRESULT(hr);
+
+ return hr;
+}
//-----------------------------------------------------------------------------
// Get rich field information given a token.
diff --git a/src/debug/ee/controller.cpp b/src/debug/ee/controller.cpp
index 7f4d44568d..3a87fdf166 100644
--- a/src/debug/ee/controller.cpp
+++ b/src/debug/ee/controller.cpp
@@ -2824,6 +2824,8 @@ DPOSS_ACTION DebuggerController::DispatchPatchOrSingleStep(Thread *thread, CONTE
CrstHolderWithState lockController(&g_criticalSection);
+ TADDR originalAddress = 0;
+
#ifdef EnC_SUPPORTED
DebuggerControllerPatch *dcpEnCOriginal = NULL;
@@ -2878,7 +2880,7 @@ DPOSS_ACTION DebuggerController::DispatchPatchOrSingleStep(Thread *thread, CONTE
// If we setip, then that will change the address in the context.
// Remeber the old address so that we can compare it to the context's ip and see if it changed.
// If it did change, then don't dispatch our current event.
- TADDR originalAddress = (TADDR) address;
+ originalAddress = (TADDR) address;
#ifdef _DEBUG
// If we do a SetIP after this point, the value of address will be garbage. Set it to a distictive pattern now, so
@@ -4486,7 +4488,7 @@ void DebuggerPatchSkip::DebuggerDetachClean()
// THIS FIX IS INCOMPLETE!It attempts to update the IP in the cases we can easily detect.However,
// if a thread is in pre - emptive mode, and its filter context has been propagated to a VEH
// context, then the filter context we get will be NULL and this fix will not work.Our belief is
- // that this scenario is rare enough that it doesn’t justify the cost and risk associated with a
+ // that this scenario is rare enough that it doesnt justify the cost and risk associated with a
// complete fix, in which we would have to either :
// 1. Change the reference counting for DebuggerController and then change the exception handling
// logic in the debuggee so that we can handle the debugger event after detach.
diff --git a/src/debug/ee/controller.h b/src/debug/ee/controller.h
index 6611e044e5..a314874b8d 100644
--- a/src/debug/ee/controller.h
+++ b/src/debug/ee/controller.h
@@ -227,23 +227,23 @@ public:
LONG AddRef()
{
- InterlockedIncrement(&m_refCount);
- _ASSERTE(m_refCount > 0);
- return m_refCount;
+ LONG newRefCount = InterlockedIncrement(&m_refCount);
+ _ASSERTE(newRefCount > 0);
+ return newRefCount;
}
LONG Release()
{
- LONG result = InterlockedDecrement(&m_refCount);
- _ASSERTE(m_refCount >= 0);
+ LONG newRefCount = InterlockedDecrement(&m_refCount);
+ _ASSERTE(newRefCount >= 0);
- if (m_refCount == 0)
+ if (newRefCount == 0)
{
TRACE_FREE(this);
DeleteInteropSafeExecutable(this);
}
- return result;
+ return newRefCount;
}
// "PatchBypass" must be the first field of this class for alignment to be correct.
diff --git a/src/debug/ee/debugger.cpp b/src/debug/ee/debugger.cpp
index a06811c817..2aed8bd820 100644
--- a/src/debug/ee/debugger.cpp
+++ b/src/debug/ee/debugger.cpp
@@ -75,6 +75,9 @@ SVAL_IMPL_INIT(BOOL, Debugger, s_fCanChangeNgenFlags, TRUE);
bool g_EnableSIS = false;
+// The following instances are used for invoking overloaded new/delete
+InteropSafe interopsafe;
+InteropSafeExecutable interopsafeEXEC;
#ifndef DACCESS_COMPILE
@@ -594,8 +597,8 @@ void DoAssertOnType(DebuggerIPCEventType event, int count)
if (g_iDbgRuntimeCounter[event & 0x00ff] == count)
{
char tmpStr[256];
- sprintf(tmpStr, "%s == %d, break now!",
- IPCENames::GetName(event), count);
+ _snprintf_s(tmpStr, _countof(tmpStr), _TRUNCATE, "%s == %d, break now!",
+ IPCENames::GetName(event), count);
// fire the assertion
DbgAssertDialog(__FILE__, __LINE__, tmpStr);
@@ -608,8 +611,8 @@ void DoAssertOnType(DebuggerIPCEventType event, int count)
if (g_iDbgDebuggerCounter[event & 0x00ff] == count)
{
char tmpStr[256];
- sprintf(tmpStr, "%s == %d, break now!",
- IPCENames::GetName(event), count);
+ _snprintf_s(tmpStr, _countof(tmpStr), _TRUNCATE, "%s == %d, break now!",
+ IPCENames::GetName(event), count);
// fire the assertion
DbgAssertDialog(__FILE__, __LINE__, tmpStr);
@@ -11907,7 +11910,7 @@ HRESULT Debugger::GetAndSendInterceptCommand(DebuggerIPCEvent *event)
//
// Save off this breakpoint, so that if the exception gets unwound before we hit
- // the breakpoint - the exeception info can call back to remove it.
+ // the breakpoint - the exception info can call back to remove it.
//
pExState->GetDebuggerState()->SetDebuggerInterceptContext((void *)pBreakpoint);
diff --git a/src/debug/ee/debugger.h b/src/debug/ee/debugger.h
index 6368647946..9cdf546290 100644
--- a/src/debug/ee/debugger.h
+++ b/src/debug/ee/debugger.h
@@ -3512,10 +3512,10 @@ public:
* ------------------------------------------------------------------------ */
class InteropSafe {};
-#define interopsafe (*(InteropSafe*)NULL)
+extern InteropSafe interopsafe;
class InteropSafeExecutable {};
-#define interopsafeEXEC (*(InteropSafeExecutable*)NULL)
+extern InteropSafeExecutable interopsafeEXEC;
#ifndef DACCESS_COMPILE
inline void * __cdecl operator new(size_t n, const InteropSafe&)
diff --git a/src/debug/ee/functioninfo.cpp b/src/debug/ee/functioninfo.cpp
index 83c185cfc9..aa75b30407 100644
--- a/src/debug/ee/functioninfo.cpp
+++ b/src/debug/ee/functioninfo.cpp
@@ -890,7 +890,6 @@ DebuggerJitInfo::~DebuggerJitInfo()
LOG((LF_CORDB,LL_EVERYTHING, "DJI::~DJI : deleted at 0x%p\n", this));
}
-
// Lazy initialize the Debugger-Jit-Info
void DebuggerJitInfo::LazyInitBounds()
{
@@ -903,24 +902,22 @@ void DebuggerJitInfo::LazyInitBounds()
PRECONDITION(!g_pDebugger->HasDebuggerDataLock());
} CONTRACTL_END;
- //@todo: this method is not synchronized. Mei-chin's recent work should cover this one
+ LOG((LF_CORDB, LL_EVERYTHING, "DJI::LazyInitBounds: this=0x%x m_fAttemptInit %s\n", this, m_fAttemptInit == true ? "true": "false"));
+
// Only attempt lazy-init once
- // new LOG message
- LOG((LF_CORDB,LL_EVERYTHING, "DJI::LazyInitBounds: this=0x%x m_fAttemptInit %s\n", this, m_fAttemptInit == true? "true": "false"));
if (m_fAttemptInit)
{
return;
}
- m_fAttemptInit = true;
EX_TRY
{
- LOG((LF_CORDB,LL_EVERYTHING, "DJI::LazyInitBounds: this=0x%x Initing\n", this));
+ LOG((LF_CORDB, LL_EVERYTHING, "DJI::LazyInitBounds: this=0x%x Initing\n", this));
+
// Should have already been jitted
_ASSERTE(this->m_jitComplete);
MethodDesc * mdesc = this->m_fd;
-
DebugInfoRequest request;
_ASSERTE(this->m_addrOfCode != NULL); // must have address to disambguate the Enc cases.
@@ -928,7 +925,6 @@ void DebuggerJitInfo::LazyInitBounds()
// Note the MethodDesc may not yet have the jitted info, so we'll also use the starting address we got in the jit complete callback.
request.InitFromStartingAddr(mdesc, (PCODE)this->m_addrOfCode);
-
// Bounds info.
ULONG32 cMap = 0;
ICorDebugInfo::OffsetMapping *pMap = NULL;
@@ -940,12 +936,26 @@ void DebuggerJitInfo::LazyInitBounds()
InteropSafeNew, NULL, // allocator
&cMap, &pMap,
&cVars, &pVars);
+
LOG((LF_CORDB,LL_EVERYTHING, "DJI::LazyInitBounds: this=0x%x GetBoundariesAndVars success=0x%x\n", this, fSuccess));
- if (fSuccess)
+
+ Debugger::DebuggerDataLockHolder debuggerDataLockHolder(g_pDebugger);
+
+ if (!m_fAttemptInit)
{
- this->SetBoundaries(cMap, pMap);
- this->SetVars(cVars, pVars);
+ if (fSuccess)
+ {
+ this->SetBoundaries(cMap, pMap);
+ this->SetVars(cVars, pVars);
+ }
+ m_fAttemptInit = true;
}
+ else
+ {
+ DeleteInteropSafe(pMap);
+ DeleteInteropSafe(pVars);
+ }
+ // DebuggerDataLockHolder out of scope - release implied
}
EX_CATCH
{
@@ -963,10 +973,7 @@ void DebuggerJitInfo::SetVars(ULONG32 cVars, ICorDebugInfo::NativeVarInfo *pVars
{
LIMITED_METHOD_CONTRACT;
- if (m_varNativeInfo)
- {
- return;
- }
+ _ASSERTE(m_varNativeInfo == NULL);
m_varNativeInfo = pVars;
m_varNativeInfoCount = cVars;
@@ -1020,15 +1027,11 @@ void DebuggerJitInfo::SetBoundaries(ULONG32 cMap, ICorDebugInfo::OffsetMapping *
LOG((LF_CORDB,LL_EVERYTHING, "DJI::SetBoundaries: this=0x%x cMap=0x%x pMap=0x%x\n", this, cMap, pMap));
_ASSERTE((cMap == 0) == (pMap == NULL));
+ _ASSERTE(m_sequenceMap == NULL);
if (cMap == 0)
return;
- if (m_sequenceMap)
- {
- return;
- }
-
ULONG ilLast = 0;
#ifdef _DEBUG
// We assume that the map is sorted by native offset
diff --git a/src/debug/ee/i386/dbghelpers.S b/src/debug/ee/i386/dbghelpers.S
new file mode 100644
index 0000000000..d0a11011ca
--- /dev/null
+++ b/src/debug/ee/i386/dbghelpers.S
@@ -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.
+
+.intel_syntax noprefix
+#include "unixasmmacros.inc"
+
+//extern FuncEvalHijackWorker:proc
+
+// @dbgtodo- once we port Funceval, use the ExceptionHijack stub instead of this func-eval stub.
+NESTED_ENTRY FuncEvalHijack, _TEXT, UnhandledExceptionHandlerUnix
+ push eax // the ptr to the DebuggerEval
+ call C_FUNC(FuncEvalHijackWorker)
+ jmp eax // return is the patch addresss to jmp to
+
+NESTED_END FuncEvalHijack, _TEXT
+
+//
+// Flares for interop debugging.
+// Flares are exceptions (breakpoints) at well known addresses which the RS
+// listens for when interop debugging.
+//
+
+// This exception is from managed code.
+LEAF_ENTRY SignalHijackStartedFlare, _TEXT
+ int 3
+ // make sure that the basic block is unique
+ test eax,1
+ ret
+LEAF_END SignalHijackStartedFlare, _TEXT
+
+// Start the handoff
+LEAF_ENTRY ExceptionForRuntimeHandoffStartFlare, _TEXT
+ int 3
+ // make sure that the basic block is unique
+ test eax,2
+ ret
+LEAF_END ExceptionForRuntimeHandoffStartFlare, _TEXT
+
+// Finish the handoff.
+LEAF_ENTRY ExceptionForRuntimeHandoffCompleteFlare, _TEXT
+ int 3
+ // make sure that the basic block is unique
+ test eax,3
+ ret
+LEAF_END ExceptionForRuntimeHandoffCompleteFlare, _TEXT
+
+// Signal execution return to unhijacked state
+LEAF_ENTRY SignalHijackCompleteFlare, _TEXT
+ int 3
+ // make sure that the basic block is unique
+ test eax,4
+ ret
+LEAF_END SignalHijackCompleteFlare, _TEXT
+
+// This exception is from unmanaged code.
+LEAF_ENTRY ExceptionNotForRuntimeFlare, _TEXT
+ int 3
+ // make sure that the basic block is unique
+ test eax,5
+ ret
+LEAF_END ExceptionNotForRuntimeFlare, _TEXT
+
+// The Runtime is synchronized.
+LEAF_ENTRY NotifyRightSideOfSyncCompleteFlare, _TEXT
+ int 3
+ // make sure that the basic block is unique
+ test eax,6
+ ret
+LEAF_END NotifyRightSideOfSyncCompleteFlare, _TEXT
diff --git a/src/debug/ee/wks/CMakeLists.txt b/src/debug/ee/wks/CMakeLists.txt
index a096cbfca7..2b1aff57a1 100644
--- a/src/debug/ee/wks/CMakeLists.txt
+++ b/src/debug/ee/wks/CMakeLists.txt
@@ -55,9 +55,7 @@ else ()
add_compile_options(-fPIC)
-if(CLR_CMAKE_PLATFORM_ARCH_AMD64)
- add_library_clr(cordbee_wks ${CORDBEE_SOURCES_WKS} ../${ARCH_SOURCES_DIR}/dbghelpers.S)
-elseif(CLR_CMAKE_PLATFORM_ARCH_ARM)
+if(CLR_CMAKE_PLATFORM_ARCH_AMD64 OR CLR_CMAKE_PLATFORM_ARCH_ARM 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})
diff --git a/src/debug/ildbsymlib/symwrite.h b/src/debug/ildbsymlib/symwrite.h
index 055b8ec21f..54ab11a9a2 100644
--- a/src/debug/ildbsymlib/symwrite.h
+++ b/src/debug/ildbsymlib/symwrite.h
@@ -839,7 +839,8 @@ public:
{
// Help mitigate the impact of buffer overflow
// Fail fast with a null-reference AV
- return *(static_cast<T*>(0)) ;
+ volatile char* nullPointer = nullptr;
+ *nullPointer;
}
return m_array[ i ];
}
diff --git a/src/debug/inc/common.h b/src/debug/inc/common.h
index 77fe27a4b3..3bbf0a6f08 100644
--- a/src/debug/inc/common.h
+++ b/src/debug/inc/common.h
@@ -295,29 +295,7 @@ inline CORDB_ADDRESS ALIGN_ADDRESS( CORDB_ADDRESS val, CORDB_ADDRESS alignment )
return result;
}
-//
-// Whenever a structure is marshalled between different platforms, we need to ensure the
-// layout is the same in both cases. We tell GCC to use the MSVC-style packing with
-// the following attribute. The main thing this appears to control is whether
-// 8-byte values are aligned at 4-bytes (GCC default) or 8-bytes (MSVC default).
-// This attribute affects only the immediate struct it is applied to, you must also apply
-// it to any nested structs if you want their layout affected as well. You also must
-// apply this to unions embedded in other structures, since it can influence the starting
-// alignment.
-//
-// Note that there doesn't appear to be any disadvantage to applying this a little
-// more agressively than necessary, so we generally use it on all classes / structures
-// defined in a file that defines marshalled data types (eg. DacDbiStructures.h)
-// The -mms-bitfields compiler option also does this for the whole file, but we don't
-// want to go changing the layout of, for example, structures defined in OS header files
-// so we explicitly opt-in with this attribute.
-//
-#ifdef __GNUC__
-#define MSLAYOUT __attribute__((__ms_struct__))
-#else
-#define MSLAYOUT
-#endif
-
+#include "dacprivate.h" // for MSLAYOUT
#include "dumpcommon.h"
#endif //DEBUGGER_COMMON_H
diff --git a/src/debug/inc/dacdbiinterface.h b/src/debug/inc/dacdbiinterface.h
index fe58724fc5..569ccbaca7 100644
--- a/src/debug/inc/dacdbiinterface.h
+++ b/src/debug/inc/dacdbiinterface.h
@@ -32,7 +32,7 @@
template<class T> void DeleteDbiMemory(T *p);
// Need a class to serve as a tag that we can use to overload New/Delete.
class forDbiWorker {};
-#define forDbi (*(forDbiWorker *)NULL)
+extern forDbiWorker forDbi;
extern void * operator new(size_t lenBytes, const forDbiWorker &);
extern void * operator new[](size_t lenBytes, const forDbiWorker &);
extern void operator delete(void *p, const forDbiWorker &);
@@ -2508,17 +2508,20 @@ public:
virtual
HRESULT GetTypeID(CORDB_ADDRESS obj, COR_TYPEID * pType) = 0;
- virtual
- HRESULT GetObjectFields(COR_TYPEID id, ULONG32 celt, OUT COR_FIELD * layout, OUT ULONG32 * pceltFetched) = 0;
-
- virtual
- HRESULT GetTypeLayout(COR_TYPEID id, COR_TYPE_LAYOUT * pLayout) = 0;
-
- virtual
- HRESULT GetArrayLayout(COR_TYPEID id, COR_ARRAY_LAYOUT * pLayout) = 0;
-
- virtual
- void GetGCHeapInformation(OUT COR_HEAPINFO * pHeapInfo) = 0;
+ virtual
+ HRESULT GetTypeIDForType(VMPTR_TypeHandle vmTypeHandle, COR_TYPEID *pId) = 0;
+
+ virtual
+ HRESULT GetObjectFields(COR_TYPEID id, ULONG32 celt, OUT COR_FIELD * layout, OUT ULONG32 * pceltFetched) = 0;
+
+ virtual
+ HRESULT GetTypeLayout(COR_TYPEID id, COR_TYPE_LAYOUT * pLayout) = 0;
+
+ virtual
+ HRESULT GetArrayLayout(COR_TYPEID id, COR_ARRAY_LAYOUT * pLayout) = 0;
+
+ virtual
+ void GetGCHeapInformation(OUT COR_HEAPINFO * pHeapInfo) = 0;
// If a PEFile has an RW capable IMDInternalImport, this returns the address of the MDInternalRW
// object which implements it.
diff --git a/src/debug/shared/dbgtransportsession.cpp b/src/debug/shared/dbgtransportsession.cpp
index 14b509aa9c..95fdf25457 100644
--- a/src/debug/shared/dbgtransportsession.cpp
+++ b/src/debug/shared/dbgtransportsession.cpp
@@ -1140,33 +1140,6 @@ DbgTransportSession::Message * DbgTransportSession::RemoveMessageFromSendQueue(D
#ifndef RIGHT_SIDE_COMPILE
-#ifdef FEATURE_PAL
-__attribute__((noinline))
-__attribute__((optnone))
-static void
-ProbeMemory(__in_ecount(cbBuffer) volatile PBYTE pbBuffer, DWORD cbBuffer, bool fWriteAccess)
-{
- // Need an throw in this function to fool the C++ runtime into handling the
- // possible h/w exception below.
- if (pbBuffer == NULL)
- {
- throw PAL_SEHException();
- }
-
- // Simple one byte at a time probing
- while (cbBuffer > 0)
- {
- volatile BYTE read = *pbBuffer;
- if (fWriteAccess)
- {
- *pbBuffer = read;
- }
- ++pbBuffer;
- --cbBuffer;
- }
-}
-#endif // FEATURE_PAL
-
// Check read and optionally write memory access to the specified range of bytes. Used to check
// ReadProcessMemory and WriteProcessMemory requests.
HRESULT DbgTransportSession::CheckBufferAccess(__in_ecount(cbBuffer) PBYTE pbBuffer, DWORD cbBuffer, bool fWriteAccess)
@@ -1220,14 +1193,7 @@ HRESULT DbgTransportSession::CheckBufferAccess(__in_ecount(cbBuffer) PBYTE pbBuf
}
while (cbBuffer > 0);
#else
- try
- {
- // Need to explicit h/w exception holder so to catch them in ProbeMemory
- CatchHardwareExceptionHolder __catchHardwareException;
-
- ProbeMemory(pbBuffer, cbBuffer, fWriteAccess);
- }
- catch(...)
+ if (!PAL_ProbeMemory(pbBuffer, cbBuffer, fWriteAccess))
{
return HRESULT_FROM_WIN32(ERROR_INVALID_ADDRESS);
}
diff --git a/src/dlls/dbgshim/dbgshim.cpp b/src/dlls/dbgshim/dbgshim.cpp
index 4d6dc5a6e3..aeee778543 100644
--- a/src/dlls/dbgshim/dbgshim.cpp
+++ b/src/dlls/dbgshim/dbgshim.cpp
@@ -433,7 +433,7 @@ public:
DWORD arrayLength = 0;
// Wake up runtime(s)
- HRESULT hr = InternalEnumerateCLRs(&handleArray, &stringArray, &arrayLength);
+ HRESULT hr = EnumerateCLRs(m_processId, &handleArray, &stringArray, &arrayLength);
if (SUCCEEDED(hr))
{
WakeRuntimes(handleArray, arrayLength);
diff --git a/src/dlls/mscordac/CMakeLists.txt b/src/dlls/mscordac/CMakeLists.txt
index 02bba4a058..8780db904d 100644
--- a/src/dlls/mscordac/CMakeLists.txt
+++ b/src/dlls/mscordac/CMakeLists.txt
@@ -45,6 +45,10 @@ if(CLR_CMAKE_PLATFORM_LINUX OR CLR_CMAKE_PLATFORM_FREEBSD OR CLR_CMAKE_PLATFORM_
set(START_LIBRARY_GROUP -Wl,--start-group)
set(END_LIBRARY_GROUP -Wl,--end-group)
+ # These options are used to force every object to be included even if it's unused.
+ set(START_WHOLE_ARCHIVE -Wl,--whole-archive)
+ set(END_WHOLE_ARCHIVE -Wl,--no-whole-archive)
+
# Add linker exports file option
set(EXPORTS_LINKER_OPTION -Wl,--version-script=${EXPORTS_FILE})
endif(CLR_CMAKE_PLATFORM_LINUX OR CLR_CMAKE_PLATFORM_FREEBSD OR CLR_CMAKE_PLATFORM_NETBSD)
@@ -112,7 +116,9 @@ if(WIN32)
else(WIN32)
list(APPEND COREDAC_LIBRARIES
mscorrc_debug
+ ${START_WHOLE_ARCHIVE} # force all PAL objects to be included so all exports are available
coreclrpal
+ ${END_WHOLE_ARCHIVE}
palrt
)
endif(WIN32)
@@ -120,4 +126,4 @@ endif(WIN32)
target_link_libraries(mscordaccore PRIVATE ${COREDAC_LIBRARIES})
# add the install targets
-install_clr(mscordaccore) \ No newline at end of file
+install_clr(mscordaccore)
diff --git a/src/dlls/mscordac/mscordac_unixexports.src b/src/dlls/mscordac/mscordac_unixexports.src
index 466a1bf1f5..7d60c1ed4b 100644
--- a/src/dlls/mscordac/mscordac_unixexports.src
+++ b/src/dlls/mscordac/mscordac_unixexports.src
@@ -26,6 +26,7 @@ PAL_GetSymbolModuleBase
PAL_GetTransportPipeName
PAL_InitializeDLL
PAL_IsDebuggerPresent
+PAL_ProbeMemory
PAL_iswspace
PAL_memcpy
PAL_malloc
@@ -49,12 +50,15 @@ PAL_wcsstr
_wcsicmp
_stricmp
-_snprintf
-_snwprintf
-_vsnwprintf
-_itow
-_i64tow
+sprintf_s
+swprintf_s
+_snwprintf_s
+_vsnprintf_s
+_vsnwprintf_s
+_itow_s
+_i64tow_s
memcpy_s
+sscanf_s
CoCreateGuid
CopyFileW
@@ -171,4 +175,4 @@ _ZN25NativeExceptionHolderBase4PushEv
_ZN25NativeExceptionHolderBaseC2Ev
_ZN25NativeExceptionHolderBaseD2Ev
_ZN28CatchHardwareExceptionHolderC1Ev
-_ZN28CatchHardwareExceptionHolderD1Ev \ No newline at end of file
+_ZN28CatchHardwareExceptionHolderD1Ev
diff --git a/src/dlls/mscoree/coreclr/coreclr.nativeproj b/src/dlls/mscoree/coreclr/coreclr.nativeproj
index d9350bcf4c..484790ee6f 100644
--- a/src/dlls/mscoree/coreclr/coreclr.nativeproj
+++ b/src/dlls/mscoree/coreclr/coreclr.nativeproj
@@ -1,5 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="dogfood">
+ <PropertyGroup>
+ <!-- Work around problems with loading System.Private.CoreLib.dll, -->
+ <!-- caused by inconsistent setting of UseLegacyCompiler and FeatureSpanOfT -->
+ <!-- between System.Private.CoreLib.dll and the runtime. -->
+ <UseLegacyCompiler>true</UseLegacyCompiler>
+ </PropertyGroup>
<Import Project="$(_NTDRIVE)$(_NTROOT)\ndp\clr\clr.props" />
<Import Project="$(_NTDRIVE)$(_NTROOT)\ndp\clr\src\dlls\mscoree\mscoree.settings.targets" />
<PropertyGroup Label="Globals">
diff --git a/src/dlls/mscoree/mscoree.cpp b/src/dlls/mscoree/mscoree.cpp
index 3d33337c62..4c613fff6a 100644
--- a/src/dlls/mscoree/mscoree.cpp
+++ b/src/dlls/mscoree/mscoree.cpp
@@ -75,8 +75,6 @@ HINSTANCE g_hThisInst; // This library.
#include <process.h> // for __security_init_cookie()
-void* __stdcall GetCLRFunction(LPCSTR FunctionName);
-
extern "C" IExecutionEngine* __stdcall IEE();
#ifdef NO_CRT_INIT
diff --git a/src/dlls/mscoree/mscorwks_unixexports.src b/src/dlls/mscoree/mscorwks_unixexports.src
index 9c151a942c..f7862d3afe 100644
--- a/src/dlls/mscoree/mscorwks_unixexports.src
+++ b/src/dlls/mscoree/mscorwks_unixexports.src
@@ -98,6 +98,7 @@ UnlockFile
UnmapViewOfFile
VirtualAlloc
VirtualFree
+GlobalMemoryStatusEx
VirtualQuery
WideCharToMultiByte
WriteFile
diff --git a/src/dlls/mscoree/unixinterface.cpp b/src/dlls/mscoree/unixinterface.cpp
index 8d75ff2721..edd361c0c2 100644
--- a/src/dlls/mscoree/unixinterface.cpp
+++ b/src/dlls/mscoree/unixinterface.cpp
@@ -247,21 +247,23 @@ int coreclr_initialize(
host.SuppressRelease();
*hostHandle = host;
#ifdef FEATURE_GDBJIT
-
- hr = coreclr_create_delegate(*hostHandle,
- *domainId,
- "SOS.NETCore",
- "SOS.SymbolReader",
- "GetInfoForMethod",
- (void**)&getInfoForMethodDelegate);
-
- if (!SUCCEEDED(hr))
+ HRESULT createDelegateResult;
+ createDelegateResult = coreclr_create_delegate(*hostHandle,
+ *domainId,
+ "SOS.NETCore",
+ "SOS.SymbolReader",
+ "GetInfoForMethod",
+ (void**)&getInfoForMethodDelegate);
+
+#if defined(_DEBUG)
+ if (!SUCCEEDED(createDelegateResult))
{
fprintf(stderr,
- "Can't create delegate for 'System.Diagnostics.Debug.SymbolReader.SymbolReader.GetInfoForMethod' "
- "method - status: 0x%08x\n", hr);
+ "Can't create delegate for 'SOS.SymbolReader.GetInfoForMethod' "
+ "method - status: 0x%08x\n", createDelegateResult);
}
- hr = S_OK; // We don't need to fail if we can't create delegate
+#endif // _DEBUG
+
#endif
}
return hr;
diff --git a/src/dlls/mscorpe/ceefilegenwriter.cpp b/src/dlls/mscorpe/ceefilegenwriter.cpp
index cfd1ebb644..04bacd7a07 100644
--- a/src/dlls/mscorpe/ceefilegenwriter.cpp
+++ b/src/dlls/mscorpe/ceefilegenwriter.cpp
@@ -973,7 +973,7 @@ BOOL RunProcess(LPCWSTR tempResObj, LPCWSTR pszFilename, DWORD* pdwExitCode, PEW
if (FAILED(GetClrSystemDirectory(wszSystemDir)))
return FALSE;
- WCHAR* wzMachine;
+ const WCHAR* wzMachine;
if(pewriter.isIA64())
wzMachine = L"IA64";
else if(pewriter.isAMD64())
@@ -1167,6 +1167,13 @@ HRESULT CeeFileGenWriter::emitResourceSection()
const BYTE *pbStartOfMappedMem;
IMAGE_SECTION_HEADER *rsrc[2] = { NULL, NULL };
S_SIZE_T cbTotalSizeOfRawData;
+
+ char *data = NULL;
+ SIZE_T cReloc = 0;
+ IMAGE_RELOCATION *pReloc = NULL;
+ SIZE_T cSymbol = 0;
+ IMAGE_SYMBOL *pSymbolTable = NULL;
+
// create a mapped view of the .res file
pParam->hFile = WszCreateFile(pParam->szResFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (pParam->hFile == INVALID_HANDLE_VALUE)
@@ -1308,7 +1315,7 @@ HRESULT CeeFileGenWriter::emitResourceSection()
if (FAILED(pParam->hr)) goto lDone;
rsrcSection->directoryEntry(IMAGE_DIRECTORY_ENTRY_RESOURCE);
- char *data = rsrcSection->getBlock(static_cast<unsigned>(cbTotalSizeOfRawData.Value()), 8);
+ data = rsrcSection->getBlock(static_cast<unsigned>(cbTotalSizeOfRawData.Value()), 8);
if(data == NULL)
{
pParam->hr = E_OUTOFMEMORY;
@@ -1319,11 +1326,11 @@ HRESULT CeeFileGenWriter::emitResourceSection()
memcpy(data, (char *)pParam->hMod + VAL32(rsrc[0]->PointerToRawData), VAL32(rsrc[0]->SizeOfRawData));
// Map all the relocs in .rsrc$01 using the reloc and symbol tables in the COFF object.,
- SIZE_T cReloc = 0; // Total number of relocs
- IMAGE_RELOCATION *pReloc = NULL; // Reloc table start
+ cReloc = 0; // Total number of relocs
+ pReloc = NULL; // Reloc table start
- SIZE_T cSymbol = 0; // Total number of symbols
- IMAGE_SYMBOL *pSymbolTable = NULL; // Symbol table start
+ cSymbol = 0; // Total number of symbols
+ pSymbolTable = NULL; // Symbol table start
{
// Check that the relocations and symbols lie within the resource
diff --git a/src/gc/CMakeLists.txt b/src/gc/CMakeLists.txt
index 61e1ced727..d32d1c2dfb 100644
--- a/src/gc/CMakeLists.txt
+++ b/src/gc/CMakeLists.txt
@@ -38,6 +38,18 @@ set( GC_SOURCES_WKS
set( GC_SOURCES_DAC
${GC_SOURCES_DAC_AND_WKS_COMMON})
+if(FEATURE_STANDALONE_GC)
+ if(CLR_CMAKE_PLATFORM_UNIX)
+ set ( GC_SOURCES_WKS
+ ${GC_SOURCES_WKS}
+ gcenv.unix.cpp)
+ else()
+ set ( GC_SOURCES_WKS
+ ${GC_SOURCES_WKS}
+ gcenv.windows.cpp)
+ endif(CLR_CMAKE_PLATFORM_UNIX)
+endif(FEATURE_STANDALONE_GC)
+
convert_to_absolute_path(GC_SOURCES_WKS ${GC_SOURCES_WKS})
convert_to_absolute_path(GC_SOURCES_DAC ${GC_SOURCES_DAC})
diff --git a/src/gc/env/gcenv.base.h b/src/gc/env/gcenv.base.h
index a94f1a6394..94f73762f8 100644
--- a/src/gc/env/gcenv.base.h
+++ b/src/gc/env/gcenv.base.h
@@ -447,7 +447,7 @@ extern bool g_fFinalizerRunOnShutDown;
// Locks
//
-struct alloc_context;
+struct gc_alloc_context;
class Thread;
Thread * GetThread();
diff --git a/src/gc/env/gcenv.ee.h b/src/gc/env/gcenv.ee.h
index 0c1fd4988a..beb0c1a98f 100644
--- a/src/gc/env/gcenv.ee.h
+++ b/src/gc/env/gcenv.ee.h
@@ -7,35 +7,11 @@
#ifndef __GCENV_EE_H__
#define __GCENV_EE_H__
-struct ScanContext;
-class CrawlFrame;
-
-typedef void promote_func(PTR_PTR_Object, ScanContext*, uint32_t);
-
-typedef void enum_alloc_context_func(alloc_context*, void*);
-
-typedef struct
-{
- promote_func* f;
- ScanContext* sc;
- CrawlFrame * cf;
-} GCCONTEXT;
-
-// GC background thread function prototype
-typedef uint32_t (__stdcall *GCBackgroundThreadFunction)(void* param);
+#include "gcinterface.h"
class GCToEEInterface
{
public:
- //
- // Suspend/Resume callbacks
- //
- typedef enum
- {
- SUSPEND_FOR_GC = 1,
- SUSPEND_FOR_GC_PREP = 6
- } SUSPEND_REASON;
-
static void SuspendEE(SUSPEND_REASON reason);
static void RestartEE(bool bFinishedGC); //resume threads.
@@ -74,12 +50,22 @@ public:
static void EnablePreemptiveGC(Thread * pThread);
static void DisablePreemptiveGC(Thread * pThread);
- static alloc_context * GetAllocContext(Thread * pThread);
+ static gc_alloc_context * GetAllocContext(Thread * pThread);
static bool CatchAtSafePoint(Thread * pThread);
static void GcEnumAllocContexts(enum_alloc_context_func* fn, void* param);
static Thread* CreateBackgroundThread(GCBackgroundThreadFunction threadStart, void* arg);
+
+ // Diagnostics methods.
+ static void DiagGCStart(int gen, bool isInduced);
+ static void DiagUpdateGenerationBounds();
+ static void DiagGCEnd(size_t index, int gen, int reason, bool fConcurrent);
+ static void DiagWalkFReachableObjects(void* gcContext);
+ static void DiagWalkSurvivors(void* gcContext);
+ static void DiagWalkLOHSurvivors(void* gcContext);
+ static void DiagWalkBGCSurvivors(void* gcContext);
+ static void StompWriteBarrier(WriteBarrierParameters* args);
};
#endif // __GCENV_EE_H__
diff --git a/src/gc/env/gcenv.object.h b/src/gc/env/gcenv.object.h
index c999e4538e..db8995a118 100644
--- a/src/gc/env/gcenv.object.h
+++ b/src/gc/env/gcenv.object.h
@@ -31,6 +31,8 @@ public:
void ClrGCBit() { m_uSyncBlockValue &= ~BIT_SBLK_GC_RESERVE; }
};
+static_assert(sizeof(ObjHeader) == sizeof(uintptr_t), "this assumption is made by the VM!");
+
#define MTFlag_ContainsPointers 1
#define MTFlag_HasFinalizer 2
#define MTFlag_IsArray 4
diff --git a/src/gc/env/gcenv.os.h b/src/gc/env/gcenv.os.h
index bb0153f117..6a126f29ed 100644
--- a/src/gc/env/gcenv.os.h
+++ b/src/gc/env/gcenv.os.h
@@ -73,13 +73,12 @@ public:
// Reserve virtual memory range.
// Parameters:
- // address - starting virtual address, it can be NULL to let the function choose the starting address
// size - size of the virtual memory range
// alignment - requested memory alignment
// flags - flags to control special settings like write watching
// Return:
// Starting virtual address of the reserved range
- static void* VirtualReserve(void *address, size_t size, size_t alignment, uint32_t flags);
+ static void* VirtualReserve(size_t size, size_t alignment, uint32_t flags);
// Release virtual memory range previously reserved using VirtualReserve
// Parameters:
diff --git a/src/gc/gc.cpp b/src/gc/gc.cpp
index a62b02d33a..6187938ff8 100644
--- a/src/gc/gc.cpp
+++ b/src/gc/gc.cpp
@@ -21,22 +21,6 @@
#define USE_INTROSORT
-#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
-inline BOOL ShouldTrackMovementForProfilerOrEtw()
-{
-#ifdef GC_PROFILING
- if (CORProfilerTrackGC())
- return true;
-#endif
-
-#ifdef FEATURE_EVENT_TRACE
- if (ETW::GCLog::ShouldTrackMovementForEtw())
- return true;
-#endif
-
- return false;
-}
-#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
#if defined(BACKGROUND_GC) && defined(FEATURE_EVENT_TRACE)
BOOL bgc_heap_walk_for_etw_p = FALSE;
@@ -349,8 +333,8 @@ void gc_heap::add_to_history_per_heap()
#endif //BACKGROUND_GC
current_hist->fgc_lowest = lowest_address;
current_hist->fgc_highest = highest_address;
- current_hist->g_lowest = g_lowest_address;
- current_hist->g_highest = g_highest_address;
+ current_hist->g_lowest = g_gc_lowest_address;
+ current_hist->g_highest = g_gc_highest_address;
gchist_index_per_heap++;
if (gchist_index_per_heap == max_history_count)
@@ -1418,8 +1402,8 @@ int mark_time, plan_time, sweep_time, reloc_time, compact_time;
#ifndef MULTIPLE_HEAPS
-#define ephemeral_low g_ephemeral_low
-#define ephemeral_high g_ephemeral_high
+#define ephemeral_low g_gc_ephemeral_low
+#define ephemeral_high g_gc_ephemeral_high
#endif // MULTIPLE_HEAPS
@@ -1544,7 +1528,7 @@ void WaitLongerNoInstru (int i)
}
else if (g_TrapReturningThreads)
{
- GCHeap::GetGCHeap()->WaitUntilGCComplete();
+ g_theGCHeap->WaitUntilGCComplete();
}
}
@@ -1573,7 +1557,7 @@ retry:
unsigned int i = 0;
while (VolatileLoad(lock) >= 0)
{
- if ((++i & 7) && !GCHeap::IsGCInProgress())
+ if ((++i & 7) && !IsGCInProgress())
{
if (g_SystemInfo.dwNumberOfProcessors > 1)
{
@@ -1584,11 +1568,11 @@ retry:
#endif //!MULTIPLE_HEAPS
for (int j = 0; j < spin_count; j++)
{
- if (VolatileLoad(lock) < 0 || GCHeap::IsGCInProgress())
+ if (VolatileLoad(lock) < 0 || IsGCInProgress())
break;
YieldProcessor(); // indicate to the processor that we are spining
}
- if (VolatileLoad(lock) >= 0 && !GCHeap::IsGCInProgress())
+ if (VolatileLoad(lock) >= 0 && !IsGCInProgress())
{
safe_switch_to_thread();
}
@@ -2192,6 +2176,55 @@ int log2(unsigned int n)
return pos;
}
+#ifndef DACCESS_COMPILE
+
+void stomp_write_barrier_resize(bool is_runtime_suspended, bool requires_upper_bounds_check)
+{
+ WriteBarrierParameters args = {};
+ 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;
+ args.lowest_address = g_gc_lowest_address;
+ args.highest_address = g_gc_highest_address;
+ GCToEEInterface::StompWriteBarrier(&args);
+}
+
+void stomp_write_barrier_ephemeral(bool is_runtime_suspended, uint8_t* ephemeral_lo, uint8_t* ephemeral_hi)
+{
+ WriteBarrierParameters args = {};
+ args.operation = WriteBarrierOp::StompEphemeral;
+ args.is_runtime_suspended = is_runtime_suspended;
+ args.ephemeral_lo = g_gc_ephemeral_low;
+ args.ephemeral_hi = g_gc_ephemeral_high;
+#ifdef MULTIPLE_HEAPS
+ // It is not correct to update the EE's g_ephemeral_low and g_ephemeral_high
+ // to anything other than their default values when using Server GC, since
+ // there is no single ephemeral generation across all of the heaps.
+ // Server GC write barriers do not reference these two globals, but ErectWriteBarrier does.
+ //
+ // When MULTIPLE_HEAPS is defined, g_gc_ephemeral_low and g_gc_ephemeral_high should
+ // always have their default values.
+ assert(args.ephemeral_lo == (uint8_t*)1);
+ assert(args.ephemeral_hi == (uint8_t*)~0);
+#endif // MULTIPLE_HEAPS
+ GCToEEInterface::StompWriteBarrier(&args);
+}
+
+void stomp_write_barrier_initialize()
+{
+ WriteBarrierParameters args = {};
+ args.operation = WriteBarrierOp::Initialize;
+ args.is_runtime_suspended = true;
+ args.requires_upper_bounds_check = false;
+ args.card_table = g_gc_card_table;
+ args.lowest_address = g_gc_lowest_address;
+ args.highest_address = g_gc_highest_address;
+ GCToEEInterface::StompWriteBarrier(&args);
+}
+
+#endif // DACCESS_COMPILE
+
//extract the low bits [0,low[ of a uint32_t
#define lowbits(wrd, bits) ((wrd) & ((1 << (bits))-1))
//extract the high bits [high, 32] of a uint32_t
@@ -3422,7 +3455,7 @@ inline
size_t ro_seg_begin_index (heap_segment* seg)
{
size_t begin_index = (size_t)seg / gc_heap::min_segment_size;
- begin_index = max (begin_index, (size_t)g_lowest_address / gc_heap::min_segment_size);
+ begin_index = max (begin_index, (size_t)g_gc_lowest_address / gc_heap::min_segment_size);
return begin_index;
}
@@ -3430,14 +3463,14 @@ inline
size_t ro_seg_end_index (heap_segment* seg)
{
size_t end_index = (size_t)(heap_segment_reserved (seg) - 1) / gc_heap::min_segment_size;
- end_index = min (end_index, (size_t)g_highest_address / gc_heap::min_segment_size);
+ end_index = min (end_index, (size_t)g_gc_highest_address / gc_heap::min_segment_size);
return end_index;
}
void seg_mapping_table_add_ro_segment (heap_segment* seg)
{
#ifdef GROWABLE_SEG_MAPPING_TABLE
- if ((heap_segment_reserved (seg) <= g_lowest_address) || (heap_segment_mem (seg) >= g_highest_address))
+ if ((heap_segment_reserved (seg) <= g_gc_lowest_address) || (heap_segment_mem (seg) >= g_gc_highest_address))
return;
#endif //GROWABLE_SEG_MAPPING_TABLE
@@ -3621,7 +3654,7 @@ gc_heap* seg_mapping_table_heap_of_worker (uint8_t* o)
gc_heap* seg_mapping_table_heap_of (uint8_t* o)
{
#ifdef GROWABLE_SEG_MAPPING_TABLE
- if ((o < g_lowest_address) || (o >= g_highest_address))
+ if ((o < g_gc_lowest_address) || (o >= g_gc_highest_address))
return 0;
#endif //GROWABLE_SEG_MAPPING_TABLE
@@ -3631,7 +3664,7 @@ gc_heap* seg_mapping_table_heap_of (uint8_t* o)
gc_heap* seg_mapping_table_heap_of_gc (uint8_t* o)
{
#if defined(FEATURE_BASICFREEZE) && defined(GROWABLE_SEG_MAPPING_TABLE)
- if ((o < g_lowest_address) || (o >= g_highest_address))
+ if ((o < g_gc_lowest_address) || (o >= g_gc_highest_address))
return 0;
#endif //FEATURE_BASICFREEZE || GROWABLE_SEG_MAPPING_TABLE
@@ -3643,7 +3676,7 @@ gc_heap* seg_mapping_table_heap_of_gc (uint8_t* o)
heap_segment* seg_mapping_table_segment_of (uint8_t* o)
{
#if defined(FEATURE_BASICFREEZE) && defined(GROWABLE_SEG_MAPPING_TABLE)
- if ((o < g_lowest_address) || (o >= g_highest_address))
+ if ((o < g_gc_lowest_address) || (o >= g_gc_highest_address))
#ifdef FEATURE_BASICFREEZE
return ro_segment_lookup (o);
#else
@@ -3686,7 +3719,7 @@ heap_segment* seg_mapping_table_segment_of (uint8_t* o)
#ifdef FEATURE_BASICFREEZE
// TODO: This was originally written assuming that the seg_mapping_table would always contain entries for ro
- // segments whenever the ro segment falls into the [g_lowest_address,g_highest_address) range. I.e., it had an
+ // segments whenever the ro segment falls into the [g_gc_lowest_address,g_gc_highest_address) range. I.e., it had an
// extra "&& (size_t)(entry->seg1) & ro_in_entry" expression. However, at the moment, grow_brick_card_table does
// not correctly go through the ro segments and add them back to the seg_mapping_table when the [lowest,highest)
// range changes. We should probably go ahead and modify grow_brick_card_table and put back the
@@ -3743,9 +3776,9 @@ public:
BOOL fSmallObjectHeapPtr = FALSE, fLargeObjectHeapPtr = FALSE;
if (!noRangeChecks)
{
- fSmallObjectHeapPtr = GCHeap::GetGCHeap()->IsHeapPointer(this, TRUE);
+ fSmallObjectHeapPtr = g_theGCHeap->IsHeapPointer(this, TRUE);
if (!fSmallObjectHeapPtr)
- fLargeObjectHeapPtr = GCHeap::GetGCHeap()->IsHeapPointer(this);
+ fLargeObjectHeapPtr = g_theGCHeap->IsHeapPointer(this);
_ASSERTE(fSmallObjectHeapPtr || fLargeObjectHeapPtr);
}
@@ -3763,14 +3796,14 @@ public:
#ifdef VERIFY_HEAP
if (bDeep && (g_pConfig->GetHeapVerifyLevel() & EEConfig::HEAPVERIFY_GC))
- GCHeap::GetGCHeap()->ValidateObjectMember(this);
+ g_theGCHeap->ValidateObjectMember(this);
#endif
if (fSmallObjectHeapPtr)
{
#ifdef FEATURE_BASICFREEZE
- _ASSERTE(!GCHeap::GetGCHeap()->IsLargeObject(pMT) || GCHeap::GetGCHeap()->IsInFrozenSegment(this));
+ _ASSERTE(!g_theGCHeap->IsLargeObject(pMT) || g_theGCHeap->IsInFrozenSegment(this));
#else
- _ASSERTE(!GCHeap::GetGCHeap()->IsLargeObject(pMT));
+ _ASSERTE(!g_theGCHeap->IsLargeObject(pMT));
#endif
}
}
@@ -4086,8 +4119,8 @@ BOOL reserve_initial_memory (size_t normal_size, size_t large_size, size_t num_h
memory_details.current_block_normal = 0;
memory_details.current_block_large = 0;
- g_lowest_address = MAX_PTR;
- g_highest_address = 0;
+ g_gc_lowest_address = MAX_PTR;
+ g_gc_highest_address = 0;
if (((size_t)MAX_PTR - large_size) < normal_size)
{
@@ -4107,8 +4140,8 @@ BOOL reserve_initial_memory (size_t normal_size, size_t large_size, size_t num_h
uint8_t* allatonce_block = (uint8_t*)virtual_alloc (requestedMemory);
if (allatonce_block)
{
- g_lowest_address = allatonce_block;
- g_highest_address = allatonce_block + (memory_details.block_count * (large_size + normal_size));
+ g_gc_lowest_address = allatonce_block;
+ g_gc_highest_address = allatonce_block + (memory_details.block_count * (large_size + normal_size));
memory_details.allocation_pattern = initial_memory_details::ALLATONCE;
for(size_t i = 0; i < memory_details.block_count; i++)
@@ -4131,8 +4164,8 @@ BOOL reserve_initial_memory (size_t normal_size, size_t large_size, size_t num_h
if (b2)
{
memory_details.allocation_pattern = initial_memory_details::TWO_STAGE;
- g_lowest_address = min(b1,b2);
- g_highest_address = max(b1 + memory_details.block_count*normal_size,
+ g_gc_lowest_address = min(b1,b2);
+ g_gc_highest_address = max(b1 + memory_details.block_count*normal_size,
b2 + memory_details.block_count*large_size);
for(size_t i = 0; i < memory_details.block_count; i++)
{
@@ -4178,10 +4211,10 @@ BOOL reserve_initial_memory (size_t normal_size, size_t large_size, size_t num_h
}
else
{
- if (current_block->memory_base < g_lowest_address)
- g_lowest_address = current_block->memory_base;
- if (((uint8_t *) current_block->memory_base + block_size) > g_highest_address)
- g_highest_address = (current_block->memory_base + block_size);
+ if (current_block->memory_base < g_gc_lowest_address)
+ g_gc_lowest_address = current_block->memory_base;
+ if (((uint8_t *) current_block->memory_base + block_size) > g_gc_highest_address)
+ g_gc_highest_address = (current_block->memory_base + block_size);
}
reserve_success = TRUE;
}
@@ -4288,7 +4321,7 @@ void* virtual_alloc (size_t size)
flags = VirtualReserveFlags::WriteWatch;
}
#endif // !FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
- void* prgmem = GCToOSInterface::VirtualReserve (0, requested_size, card_size * card_word_width, flags);
+ void* prgmem = GCToOSInterface::VirtualReserve (requested_size, card_size * card_word_width, flags);
void *aligned_mem = prgmem;
// We don't want (prgmem + size) to be right at the end of the address space
@@ -4361,7 +4394,7 @@ static size_t get_valid_segment_size (BOOL large_seg=FALSE)
// if seg_size is small but not 0 (0 is default if config not set)
// then set the segment to the minimum size
- if (!GCHeap::IsValidSegmentSize(seg_size))
+ if (!g_theGCHeap->IsValidSegmentSize(seg_size))
{
// if requested size is between 1 byte and 4MB, use min
if ((seg_size >> 1) && !(seg_size >> 22))
@@ -4623,22 +4656,22 @@ gc_heap::get_segment (size_t size, BOOL loh_p)
{
uint8_t* start;
uint8_t* end;
- if (mem < g_lowest_address)
+ if (mem < g_gc_lowest_address)
{
start = (uint8_t*)mem;
}
else
{
- start = (uint8_t*)g_lowest_address;
+ start = (uint8_t*)g_gc_lowest_address;
}
- if (((uint8_t*)mem + size) > g_highest_address)
+ if (((uint8_t*)mem + size) > g_gc_highest_address)
{
end = (uint8_t*)mem + size;
}
else
{
- end = (uint8_t*)g_highest_address;
+ end = (uint8_t*)g_gc_highest_address;
}
if (gc_heap::grow_brick_card_tables (start, end, size, result, __this, loh_p) != 0)
@@ -4703,10 +4736,7 @@ heap_segment* gc_heap::get_segment_for_loh (size_t size
FireEtwGCCreateSegment_V1((size_t)heap_segment_mem(res), (size_t)(heap_segment_reserved (res) - heap_segment_mem(res)), ETW::GCLog::ETW_GC_INFO::LARGE_OBJECT_HEAP, GetClrInstanceId());
-#ifdef GC_PROFILING
- if (CORProfilerTrackGC())
- UpdateGenerationBounds();
-#endif // GC_PROFILING
+ GCToEEInterface::DiagUpdateGenerationBounds();
#ifdef MULTIPLE_HEAPS
hp->thread_loh_segment (res);
@@ -5231,7 +5261,7 @@ void gc_heap::gc_thread_function ()
gc_heap::ee_suspend_event.Wait(INFINITE, FALSE);
BEGIN_TIMING(suspend_ee_during_log);
- GCToEEInterface::SuspendEE(GCToEEInterface::SUSPEND_FOR_GC);
+ GCToEEInterface::SuspendEE(SUSPEND_FOR_GC);
END_TIMING(suspend_ee_during_log);
proceed_with_gc_p = TRUE;
@@ -5340,7 +5370,7 @@ heap_segment* gc_heap::segment_of (uint8_t* add, ptrdiff_t& delta, BOOL verify_p
uint8_t* sadd = add;
heap_segment* hs = 0;
heap_segment* hs1 = 0;
- if (!((add >= g_lowest_address) && (add < g_highest_address)))
+ if (!((add >= g_gc_lowest_address) && (add < g_gc_highest_address)))
{
delta = 0;
return 0;
@@ -5523,7 +5553,6 @@ public:
saved_post_plug_reloc = temp;
}
-#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
void swap_pre_plug_and_saved_for_profiler()
{
gap_reloc_pair temp;
@@ -5539,7 +5568,6 @@ public:
memcpy (saved_post_plug_info_start, &saved_post_plug, sizeof (saved_post_plug));
saved_post_plug = temp;
}
-#endif //GC_PROFILING || //FEATURE_EVENT_TRACE
// 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
@@ -5775,7 +5803,7 @@ void gc_heap::fix_allocation_context (alloc_context* acontext, BOOL for_gc_p,
//used by the heap verification for concurrent gc.
//it nulls out the words set by fix_allocation_context for heap_verification
-void repair_allocation (alloc_context* acontext, void*)
+void repair_allocation (gc_alloc_context* acontext, void*)
{
uint8_t* point = acontext->alloc_ptr;
@@ -5788,7 +5816,7 @@ void repair_allocation (alloc_context* acontext, void*)
}
}
-void void_allocation (alloc_context* acontext, void*)
+void void_allocation (gc_alloc_context* acontext, void*)
{
uint8_t* point = acontext->alloc_ptr;
@@ -5818,10 +5846,10 @@ struct fix_alloc_context_args
void* heap;
};
-void fix_alloc_context(alloc_context* acontext, void* param)
+void fix_alloc_context(gc_alloc_context* acontext, void* param)
{
fix_alloc_context_args* args = (fix_alloc_context_args*)param;
- GCHeap::GetGCHeap()->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)
@@ -6399,7 +6427,7 @@ void gc_heap::set_card (size_t card)
inline
void gset_card (size_t card)
{
- g_card_table [card_word (card)] |= (1 << card_bit (card));
+ g_gc_card_table [card_word (card)] |= (1 << card_bit (card));
}
inline
@@ -6510,7 +6538,7 @@ size_t size_card_bundle_of (uint8_t* from, uint8_t* end)
uint32_t* translate_card_bundle_table (uint32_t* cb)
{
- return (uint32_t*)((uint8_t*)cb - ((((size_t)g_lowest_address) / (card_size*card_word_width*card_bundle_size*card_bundle_word_width)) * sizeof (uint32_t)));
+ 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 ()
@@ -6722,7 +6750,7 @@ size_t size_mark_array_of (uint8_t* from, uint8_t* end)
// according to the lowest_address.
uint32_t* translate_mark_array (uint32_t* ma)
{
- return (uint32_t*)((uint8_t*)ma - size_mark_array_of (0, g_lowest_address));
+ return (uint32_t*)((uint8_t*)ma - size_mark_array_of (0, g_gc_lowest_address));
}
// from and end must be page aligned addresses.
@@ -6850,16 +6878,16 @@ void release_card_table (uint32_t* c_table)
{
destroy_card_table (c_table);
// sever the link from the parent
- if (&g_card_table[card_word (gcard_of(g_lowest_address))] == c_table)
+ if (&g_gc_card_table[card_word (gcard_of(g_gc_lowest_address))] == c_table)
{
- g_card_table = 0;
+ g_gc_card_table = 0;
#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
SoftwareWriteWatch::StaticClose();
#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
}
else
{
- uint32_t* p_table = &g_card_table[card_word (gcard_of(g_lowest_address))];
+ uint32_t* p_table = &g_gc_card_table[card_word (gcard_of(g_gc_lowest_address))];
if (p_table)
{
while (p_table && (card_table_next (p_table) != c_table))
@@ -6881,8 +6909,8 @@ void destroy_card_table (uint32_t* c_table)
uint32_t* gc_heap::make_card_table (uint8_t* start, uint8_t* end)
{
- assert (g_lowest_address == start);
- assert (g_highest_address == end);
+ assert (g_gc_lowest_address == start);
+ assert (g_gc_highest_address == end);
uint32_t virtual_reserve_flags = VirtualReserveFlags::None;
@@ -6902,7 +6930,7 @@ uint32_t* gc_heap::make_card_table (uint8_t* start, uint8_t* end)
if (can_use_write_watch_for_card_table())
{
virtual_reserve_flags |= VirtualReserveFlags::WriteWatch;
- cb = size_card_bundle_of (g_lowest_address, g_highest_address);
+ cb = size_card_bundle_of (g_gc_lowest_address, g_gc_highest_address);
}
#endif //CARD_BUNDLE
@@ -6918,7 +6946,7 @@ uint32_t* gc_heap::make_card_table (uint8_t* start, uint8_t* end)
#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
#ifdef GROWABLE_SEG_MAPPING_TABLE
- size_t st = size_seg_mapping_table_of (g_lowest_address, g_highest_address);
+ size_t st = size_seg_mapping_table_of (g_gc_lowest_address, g_gc_highest_address);
size_t st_table_offset = sizeof(card_table_info) + cs + bs + cb + wws;
size_t st_table_offset_aligned = align_for_seg_mapping_table (st_table_offset);
@@ -6932,7 +6960,7 @@ uint32_t* gc_heap::make_card_table (uint8_t* start, uint8_t* end)
size_t alloc_size = sizeof (uint8_t)*(sizeof(card_table_info) + cs + bs + cb + wws + st + ms);
size_t alloc_size_aligned = Align (alloc_size, g_SystemInfo.dwAllocationGranularity-1);
- uint8_t* mem = (uint8_t*)GCToOSInterface::VirtualReserve (0, alloc_size_aligned, 0, virtual_reserve_flags);
+ uint8_t* mem = (uint8_t*)GCToOSInterface::VirtualReserve (alloc_size_aligned, 0, virtual_reserve_flags);
if (!mem)
return 0;
@@ -6973,7 +7001,7 @@ uint32_t* gc_heap::make_card_table (uint8_t* start, uint8_t* end)
#ifdef GROWABLE_SEG_MAPPING_TABLE
seg_mapping_table = (seg_mapping*)(mem + st_table_offset_aligned);
seg_mapping_table = (seg_mapping*)((uint8_t*)seg_mapping_table -
- size_seg_mapping_table_of (0, (align_lower_segment (g_lowest_address))));
+ size_seg_mapping_table_of (0, (align_lower_segment (g_gc_lowest_address))));
#endif //GROWABLE_SEG_MAPPING_TABLE
#ifdef MARK_ARRAY
@@ -7012,10 +7040,10 @@ int gc_heap::grow_brick_card_tables (uint8_t* start,
gc_heap* hp,
BOOL loh_p)
{
- uint8_t* la = g_lowest_address;
- uint8_t* ha = g_highest_address;
- uint8_t* saved_g_lowest_address = min (start, g_lowest_address);
- uint8_t* saved_g_highest_address = max (end, g_highest_address);
+ uint8_t* la = g_gc_lowest_address;
+ uint8_t* ha = g_gc_highest_address;
+ uint8_t* saved_g_lowest_address = min (start, g_gc_lowest_address);
+ uint8_t* saved_g_highest_address = max (end, g_gc_highest_address);
#ifdef BACKGROUND_GC
// This value is only for logging purpose - it's not necessarily exactly what we
// would commit for mark array but close enough for diagnostics purpose.
@@ -7045,18 +7073,18 @@ int gc_heap::grow_brick_card_tables (uint8_t* start,
#endif // BIT64
ps *= 2;
- if (saved_g_lowest_address < g_lowest_address)
+ if (saved_g_lowest_address < g_gc_lowest_address)
{
- if (ps > (size_t)g_lowest_address)
+ if (ps > (size_t)g_gc_lowest_address)
saved_g_lowest_address = (uint8_t*)OS_PAGE_SIZE;
else
{
- assert (((size_t)g_lowest_address - ps) >= OS_PAGE_SIZE);
- saved_g_lowest_address = min (saved_g_lowest_address, (g_lowest_address - ps));
+ assert (((size_t)g_gc_lowest_address - ps) >= OS_PAGE_SIZE);
+ saved_g_lowest_address = min (saved_g_lowest_address, (g_gc_lowest_address - ps));
}
}
- if (saved_g_highest_address > g_highest_address)
+ if (saved_g_highest_address > g_gc_highest_address)
{
saved_g_highest_address = max ((saved_g_lowest_address + ps), saved_g_highest_address);
if (saved_g_highest_address > top)
@@ -7069,7 +7097,7 @@ 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_card_table;
+ uint32_t* saved_g_card_table = g_gc_card_table;
uint32_t* ct = 0;
uint32_t* translated_ct = 0;
short* bt = 0;
@@ -7125,7 +7153,7 @@ int gc_heap::grow_brick_card_tables (uint8_t* start,
dprintf (GC_TABLE_LOG, ("card table: %Id; brick table: %Id; card bundle: %Id; sw ww table: %Id; seg table: %Id; mark array: %Id",
cs, bs, cb, wws, st, ms));
- uint8_t* mem = (uint8_t*)GCToOSInterface::VirtualReserve (0, alloc_size_aligned, 0, virtual_reserve_flags);
+ uint8_t* mem = (uint8_t*)GCToOSInterface::VirtualReserve (alloc_size_aligned, 0, virtual_reserve_flags);
if (!mem)
{
@@ -7152,7 +7180,7 @@ int gc_heap::grow_brick_card_tables (uint8_t* start,
card_table_refcount (ct) = 0;
card_table_lowest_address (ct) = saved_g_lowest_address;
card_table_highest_address (ct) = saved_g_highest_address;
- card_table_next (ct) = &g_card_table[card_word (gcard_of (la))];
+ card_table_next (ct) = &g_gc_card_table[card_word (gcard_of (la))];
//clear the card table
/*
@@ -7179,9 +7207,9 @@ int gc_heap::grow_brick_card_tables (uint8_t* start,
seg_mapping* new_seg_mapping_table = (seg_mapping*)(mem + st_table_offset_aligned);
new_seg_mapping_table = (seg_mapping*)((uint8_t*)new_seg_mapping_table -
size_seg_mapping_table_of (0, (align_lower_segment (saved_g_lowest_address))));
- memcpy(&new_seg_mapping_table[seg_mapping_word_of(g_lowest_address)],
- &seg_mapping_table[seg_mapping_word_of(g_lowest_address)],
- size_seg_mapping_table_of(g_lowest_address, g_highest_address));
+ memcpy(&new_seg_mapping_table[seg_mapping_word_of(g_gc_lowest_address)],
+ &seg_mapping_table[seg_mapping_word_of(g_gc_lowest_address)],
+ size_seg_mapping_table_of(g_gc_lowest_address, g_gc_highest_address));
seg_mapping_table = new_seg_mapping_table;
}
@@ -7243,12 +7271,14 @@ int gc_heap::grow_brick_card_tables (uint8_t* start,
// Note on points where the runtime is suspended anywhere in this function. Upon an attempt to suspend the
// runtime, a different thread may suspend first, causing this thread to block at the point of the suspend call.
// So, at any suspend point, externally visible state needs to be consistent, as code that depends on that state
- // may run while this thread is blocked. This includes updates to g_card_table, g_lowest_address, and
- // g_highest_address.
+ // may run while this thread is blocked. This includes updates to g_gc_card_table, g_gc_lowest_address, and
+ // g_gc_highest_address.
suspend_EE();
}
- g_card_table = translated_ct;
+ g_gc_card_table = translated_ct;
+ g_gc_lowest_address = saved_g_lowest_address;
+ g_gc_highest_address = saved_g_highest_address;
SoftwareWriteWatch::SetResizedUntranslatedTable(
mem + sw_ww_table_offset,
@@ -7260,7 +7290,7 @@ int gc_heap::grow_brick_card_tables (uint8_t* start,
// grow version of the write barrier. This test tells us if the new
// segment was allocated at a lower address than the old, requiring
// that we start doing an upper bounds check in the write barrier.
- StompWriteBarrierResize(true, la != saved_g_lowest_address);
+ stomp_write_barrier_resize(true, la != saved_g_lowest_address);
write_barrier_updated = true;
if (!is_runtime_suspended)
@@ -7271,9 +7301,12 @@ int gc_heap::grow_brick_card_tables (uint8_t* start,
else
#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
{
- g_card_table = translated_ct;
+ g_gc_card_table = translated_ct;
}
+ g_gc_lowest_address = saved_g_lowest_address;
+ g_gc_highest_address = saved_g_highest_address;
+
if (!write_barrier_updated)
{
// This passes a bool telling whether we need to switch to the post
@@ -7284,19 +7317,9 @@ int gc_heap::grow_brick_card_tables (uint8_t* start,
// to be changed, so we are doing this after all global state has
// been updated. See the comment above suspend_EE() above for more
// info.
- StompWriteBarrierResize(!!IsGCThread(), la != saved_g_lowest_address);
+ stomp_write_barrier_resize(!!IsGCThread(), la != saved_g_lowest_address);
}
- // We need to make sure that other threads executing checked write barriers
- // will see the g_card_table update before g_lowest/highest_address updates.
- // Otherwise, the checked write barrier may AV accessing the old card table
- // with address that it does not cover. Write barriers access card table
- // without memory barriers for performance reasons, so we need to flush
- // the store buffers here.
- GCToOSInterface::FlushProcessWriteBuffers();
-
- g_lowest_address = saved_g_lowest_address;
- VolatileStore(&g_highest_address, saved_g_highest_address);
return 0;
@@ -7305,7 +7328,7 @@ fail:
if (mem)
{
- assert(g_card_table == saved_g_card_table);
+ assert(g_gc_card_table == saved_g_card_table);
//delete (uint32_t*)((uint8_t*)ct - sizeof(card_table_info));
if (!GCToOSInterface::VirtualRelease (mem, alloc_size_aligned))
@@ -7463,7 +7486,7 @@ void gc_heap::copy_brick_card_table()
assert (ha == card_table_highest_address (&old_card_table[card_word (card_of (la))]));
/* todo: Need a global lock for this */
- uint32_t* ct = &g_card_table[card_word (gcard_of (g_lowest_address))];
+ uint32_t* ct = &g_gc_card_table[card_word (gcard_of (g_gc_lowest_address))];
own_card_table (ct);
card_table = translate_card_table (ct);
/* End of global lock */
@@ -7476,8 +7499,8 @@ void gc_heap::copy_brick_card_table()
if (gc_can_use_concurrent)
{
mark_array = translate_mark_array (card_table_mark_array (ct));
- assert (mark_word_of (g_highest_address) ==
- mark_word_of (align_on_mark_word (g_highest_address)));
+ assert (mark_word_of (g_gc_highest_address) ==
+ mark_word_of (align_on_mark_word (g_gc_highest_address)));
}
else
mark_array = NULL;
@@ -7486,13 +7509,13 @@ void gc_heap::copy_brick_card_table()
#ifdef CARD_BUNDLE
#if defined(MARK_ARRAY) && defined(_DEBUG)
#ifdef GROWABLE_SEG_MAPPING_TABLE
- size_t st = size_seg_mapping_table_of (g_lowest_address, g_highest_address);
+ size_t st = size_seg_mapping_table_of (g_gc_lowest_address, g_gc_highest_address);
#else //GROWABLE_SEG_MAPPING_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));
- assert (&card_bundle_table [card_bundle_word (cardw_card_bundle (card_word (card_of (g_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));
//set the card table if we are in a heap growth scenario
@@ -9330,13 +9353,13 @@ void gc_heap::update_card_table_bundle()
bool success = GCToOSInterface::GetWriteWatch (false /* resetState */ , base_address, region_size,
(void**)g_addresses,
&bcount);
- assert (success);
+ assert (success && "GetWriteWatch failed!");
dprintf (3,("Found %d pages written", bcount));
for (unsigned i = 0; i < bcount; i++)
{
size_t bcardw = (uint32_t*)(max(g_addresses[i],base_address)) - &card_table[0];
size_t ecardw = (uint32_t*)(min(g_addresses[i]+OS_PAGE_SIZE, high_address)) - &card_table[0];
- assert (bcardw >= card_word (card_of (g_lowest_address)));
+ 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)));
@@ -9648,7 +9671,7 @@ void gc_heap::adjust_ephemeral_limits (bool is_runtime_suspended)
(size_t)ephemeral_low, (size_t)ephemeral_high))
// This updates the write barrier helpers with the new info.
- StompWriteBarrierEphemeral(is_runtime_suspended);
+ stomp_write_barrier_ephemeral(is_runtime_suspended, ephemeral_low, ephemeral_high);
}
#if defined(TRACE_GC) || defined(GC_CONFIG_DRIVEN)
@@ -9821,9 +9844,9 @@ HRESULT gc_heap::initialize_gc (size_t segment_size,
settings.first_init();
- g_card_table = make_card_table (g_lowest_address, g_highest_address);
+ g_gc_card_table = make_card_table (g_gc_lowest_address, g_gc_highest_address);
- if (!g_card_table)
+ if (!g_gc_card_table)
return E_OUTOFMEMORY;
gc_started = FALSE;
@@ -9972,8 +9995,8 @@ gc_heap::init_semi_shared()
{
goto cleanup;
}
-#endif //BACKGROUND_GC
}
+#endif //BACKGROUND_GC
memset (&current_no_gc_region_info, 0, sizeof (current_no_gc_region_info));
@@ -10306,7 +10329,7 @@ gc_heap::init_gc_heap (int h_number)
#endif //MULTIPLE_HEAPS
/* todo: Need a global lock for this */
- uint32_t* ct = &g_card_table [card_word (card_of (g_lowest_address))];
+ uint32_t* ct = &g_gc_card_table [card_word (card_of (g_gc_lowest_address))];
own_card_table (ct);
card_table = translate_card_table (ct);
/* End of global lock */
@@ -10317,13 +10340,13 @@ gc_heap::init_gc_heap (int h_number)
#ifdef CARD_BUNDLE
card_bundle_table = translate_card_bundle_table (card_table_card_bundle_table (ct));
- assert (&card_bundle_table [card_bundle_word (cardw_card_bundle (card_word (card_of (g_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
#ifdef MARK_ARRAY
if (gc_can_use_concurrent)
- mark_array = translate_mark_array (card_table_mark_array (&g_card_table[card_word (card_of (g_lowest_address))]));
+ mark_array = translate_mark_array (card_table_mark_array (&g_gc_card_table[card_word (card_of (g_gc_lowest_address))]));
else
mark_array = NULL;
#endif //MARK_ARRAY
@@ -10360,6 +10383,7 @@ gc_heap::init_gc_heap (int h_number)
(size_t)(heap_segment_reserved (lseg) - heap_segment_mem(lseg)),
ETW::GCLog::ETW_GC_INFO::LARGE_OBJECT_HEAP,
GetClrInstanceId());
+
#ifdef SEG_MAPPING_TABLE
seg_mapping_table_add_segment (lseg, __this);
#else //SEG_MAPPING_TABLE
@@ -10384,10 +10408,10 @@ gc_heap::init_gc_heap (int h_number)
heap_segment_heap (lseg) = this;
//initialize the alloc context heap
- generation_alloc_context (generation_of (0))->alloc_heap = vm_heap;
+ generation_alloc_context (generation_of (0))->set_alloc_heap(vm_heap);
//initialize the alloc context heap
- generation_alloc_context (generation_of (max_generation+1))->alloc_heap = vm_heap;
+ generation_alloc_context (generation_of (max_generation+1))->set_alloc_heap(vm_heap);
#endif //MULTIPLE_HEAPS
@@ -13043,12 +13067,12 @@ int gc_heap::try_allocate_more_space (alloc_context* acontext, size_t size,
if (can_allocate)
{
- //ETW trace for allocation tick
size_t alloc_context_bytes = acontext->alloc_limit + Align (min_obj_size, align_const) - acontext->alloc_ptr;
int etw_allocation_index = ((gen_number == 0) ? 0 : 1);
etw_allocation_running_amount[etw_allocation_index] += alloc_context_bytes;
+
if (etw_allocation_running_amount[etw_allocation_index] > etw_allocation_tick)
{
#ifdef FEATURE_REDHAWK
@@ -13080,10 +13104,10 @@ void gc_heap::balance_heaps (alloc_context* acontext)
{
if (acontext->alloc_count == 0)
{
- acontext->home_heap = GCHeap::GetHeap( heap_select::select_heap(acontext, 0) );
- gc_heap* hp = acontext->home_heap->pGenGCHeap;
+ acontext->set_home_heap(GCHeap::GetHeap( heap_select::select_heap(acontext, 0) ));
+ gc_heap* hp = acontext->get_home_heap()->pGenGCHeap;
dprintf (3, ("First allocation for context %Ix on heap %d\n", (size_t)acontext, (size_t)hp->heap_number));
- acontext->alloc_heap = acontext->home_heap;
+ acontext->set_alloc_heap(acontext->get_home_heap());
hp->alloc_context_count++;
}
}
@@ -13094,9 +13118,9 @@ void gc_heap::balance_heaps (alloc_context* acontext)
if (heap_select::can_find_heap_fast())
{
- if (acontext->home_heap != NULL)
- hint = acontext->home_heap->pGenGCHeap->heap_number;
- if (acontext->home_heap != GCHeap::GetHeap(hint = heap_select::select_heap(acontext, hint)) || ((acontext->alloc_count & 15) == 0))
+ if (acontext->get_home_heap() != NULL)
+ hint = acontext->get_home_heap()->pGenGCHeap->heap_number;
+ if (acontext->get_home_heap() != GCHeap::GetHeap(hint = heap_select::select_heap(acontext, hint)) || ((acontext->alloc_count & 15) == 0))
{
set_home_heap = TRUE;
}
@@ -13122,7 +13146,7 @@ void gc_heap::balance_heaps (alloc_context* acontext)
else
*/
{
- gc_heap* org_hp = acontext->alloc_heap->pGenGCHeap;
+ gc_heap* org_hp = acontext->get_alloc_heap()->pGenGCHeap;
dynamic_data* dd = org_hp->dynamic_data_of (0);
ptrdiff_t org_size = dd_new_allocation (dd);
@@ -13141,9 +13165,9 @@ try_again:
{
max_hp = org_hp;
max_size = org_size + delta;
- acontext->home_heap = GCHeap::GetHeap( heap_select::select_heap(acontext, hint) );
+ acontext->set_home_heap(GCHeap::GetHeap( heap_select::select_heap(acontext, hint) ));
- if (org_hp == acontext->home_heap->pGenGCHeap)
+ if (org_hp == acontext->get_home_heap()->pGenGCHeap)
max_size = max_size + delta;
org_alloc_context_count = org_hp->alloc_context_count;
@@ -13156,7 +13180,7 @@ try_again:
gc_heap* hp = GCHeap::GetHeap(i%n_heaps)->pGenGCHeap;
dd = hp->dynamic_data_of (0);
ptrdiff_t size = dd_new_allocation (dd);
- if (hp == acontext->home_heap->pGenGCHeap)
+ if (hp == acontext->get_home_heap()->pGenGCHeap)
size = size + delta;
int hp_alloc_context_count = hp->alloc_context_count;
if (hp_alloc_context_count > 0)
@@ -13183,7 +13207,7 @@ try_again:
{
org_hp->alloc_context_count--;
max_hp->alloc_context_count++;
- acontext->alloc_heap = GCHeap::GetHeap(max_hp->heap_number);
+ acontext->set_alloc_heap(GCHeap::GetHeap(max_hp->heap_number));
#if !defined(FEATURE_PAL)
if (CPUGroupInfo::CanEnableGCCPUGroups())
{ //only set ideal processor when max_hp and org_hp are in the same cpu
@@ -13221,7 +13245,7 @@ try_again:
#endif // !FEATURE_PAL
dprintf (3, ("Switching context %p (home heap %d) ",
acontext,
- acontext->home_heap->pGenGCHeap->heap_number));
+ acontext->get_home_heap()->pGenGCHeap->heap_number));
dprintf (3, (" from heap %d (%Id free bytes, %d contexts) ",
org_hp->heap_number,
org_size,
@@ -13239,7 +13263,7 @@ try_again:
gc_heap* gc_heap::balance_heaps_loh (alloc_context* acontext, size_t /*size*/)
{
- gc_heap* org_hp = acontext->alloc_heap->pGenGCHeap;
+ gc_heap* org_hp = acontext->get_alloc_heap()->pGenGCHeap;
//dprintf (1, ("LA: %Id", size));
//if (size > 128*1024)
@@ -13316,7 +13340,7 @@ BOOL gc_heap::allocate_more_space(alloc_context* acontext, size_t size,
if (alloc_generation_number == 0)
{
balance_heaps (acontext);
- status = acontext->alloc_heap->pGenGCHeap->try_allocate_more_space (acontext, size, alloc_generation_number);
+ status = acontext->get_alloc_heap()->pGenGCHeap->try_allocate_more_space (acontext, size, alloc_generation_number);
}
else
{
@@ -14785,6 +14809,9 @@ int gc_heap::generation_to_condemn (int n_initial,
dprintf (GTC_LOG, ("h%d: alloc full - BLOCK", heap_number));
n = max_generation;
*blocking_collection_p = TRUE;
+ if ((local_settings->reason == reason_oos_loh) ||
+ (local_settings->reason == reason_alloc_loh))
+ evaluate_elevation = FALSE;
local_condemn_reasons->set_condition (gen_before_oom);
}
@@ -15183,7 +15210,7 @@ void gc_heap::gc1()
vm_heap->GcCondemnedGeneration = settings.condemned_generation;
- assert (g_card_table == card_table);
+ assert (g_gc_card_table == card_table);
{
if (n == max_generation)
@@ -15472,7 +15499,15 @@ void gc_heap::gc1()
#ifdef FEATURE_EVENT_TRACE
if (bgc_heap_walk_for_etw_p && settings.concurrent)
{
- make_free_lists_for_profiler_for_bgc();
+ GCToEEInterface::DiagWalkBGCSurvivors(__this);
+
+#ifdef MULTIPLE_HEAPS
+ bgc_t_join.join(this, gc_join_after_profiler_heap_walk);
+ if (bgc_t_join.joined())
+ {
+ bgc_t_join.restart();
+ }
+#endif // MULTIPLE_HEAPS
}
#endif // FEATURE_EVENT_TRACE
#endif //BACKGROUND_GC
@@ -16382,7 +16417,7 @@ int gc_heap::garbage_collect (int n)
for (int i = 0; i < n_heaps; i++)
{
//copy the card and brick tables
- if (g_card_table != g_heaps[i]->card_table)
+ if (g_gc_card_table != g_heaps[i]->card_table)
{
g_heaps[i]->copy_brick_card_table();
}
@@ -16406,100 +16441,67 @@ int gc_heap::garbage_collect (int n)
}
#endif //BACKGROUND_GC
// check for card table growth
- if (g_card_table != card_table)
+ if (g_gc_card_table != card_table)
copy_brick_card_table();
#endif //MULTIPLE_HEAPS
- BOOL should_evaluate_elevation = FALSE;
- BOOL should_do_blocking_collection = FALSE;
+ BOOL should_evaluate_elevation = FALSE;
+ BOOL should_do_blocking_collection = FALSE;
#ifdef MULTIPLE_HEAPS
- int gen_max = condemned_generation_num;
- for (int i = 0; i < n_heaps; i++)
- {
- if (gen_max < g_heaps[i]->condemned_generation_num)
- gen_max = g_heaps[i]->condemned_generation_num;
- if ((!should_evaluate_elevation) && (g_heaps[i]->elevation_requested))
- should_evaluate_elevation = TRUE;
- if ((!should_do_blocking_collection) && (g_heaps[i]->blocking_collection))
- should_do_blocking_collection = TRUE;
- }
+ int gen_max = condemned_generation_num;
+ for (int i = 0; i < n_heaps; i++)
+ {
+ if (gen_max < g_heaps[i]->condemned_generation_num)
+ gen_max = g_heaps[i]->condemned_generation_num;
+ if ((!should_evaluate_elevation) && (g_heaps[i]->elevation_requested))
+ should_evaluate_elevation = TRUE;
+ if ((!should_do_blocking_collection) && (g_heaps[i]->blocking_collection))
+ should_do_blocking_collection = TRUE;
+ }
- settings.condemned_generation = gen_max;
-//logically continues after GC_PROFILING.
+ settings.condemned_generation = gen_max;
#else //MULTIPLE_HEAPS
- settings.condemned_generation = generation_to_condemn (n,
- &blocking_collection,
- &elevation_requested,
- FALSE);
- should_evaluate_elevation = elevation_requested;
- should_do_blocking_collection = blocking_collection;
-#endif //MULTIPLE_HEAPS
-
- settings.condemned_generation = joined_generation_to_condemn (
- should_evaluate_elevation,
- settings.condemned_generation,
- &should_do_blocking_collection
- STRESS_HEAP_ARG(n)
- );
+ settings.condemned_generation = generation_to_condemn (n,
+ &blocking_collection,
+ &elevation_requested,
+ FALSE);
+ should_evaluate_elevation = elevation_requested;
+ should_do_blocking_collection = blocking_collection;
+#endif //MULTIPLE_HEAPS
+
+ settings.condemned_generation = joined_generation_to_condemn (
+ should_evaluate_elevation,
+ settings.condemned_generation,
+ &should_do_blocking_collection
+ STRESS_HEAP_ARG(n)
+ );
- STRESS_LOG1(LF_GCROOTS|LF_GC|LF_GCALLOC, LL_INFO10,
- "condemned generation num: %d\n", settings.condemned_generation);
+ STRESS_LOG1(LF_GCROOTS|LF_GC|LF_GCALLOC, LL_INFO10,
+ "condemned generation num: %d\n", settings.condemned_generation);
- record_gcs_during_no_gc();
+ record_gcs_during_no_gc();
- if (settings.condemned_generation > 1)
- settings.promotion = TRUE;
+ if (settings.condemned_generation > 1)
+ settings.promotion = TRUE;
#ifdef HEAP_ANALYZE
- // At this point we've decided what generation is condemned
- // See if we've been requested to analyze survivors after the mark phase
- if (AnalyzeSurvivorsRequested(settings.condemned_generation))
- {
- heap_analyze_enabled = TRUE;
- }
-#endif // HEAP_ANALYZE
-
-#ifdef GC_PROFILING
-
- // If we're tracking GCs, then we need to walk the first generation
- // before collection to track how many items of each class has been
- // allocated.
- UpdateGenerationBounds();
- GarbageCollectionStartedCallback(settings.condemned_generation, settings.reason == reason_induced);
+ // At this point we've decided what generation is condemned
+ // See if we've been requested to analyze survivors after the mark phase
+ if (AnalyzeSurvivorsRequested(settings.condemned_generation))
{
- BEGIN_PIN_PROFILER(CORProfilerTrackGC());
- size_t profiling_context = 0;
-
-#ifdef MULTIPLE_HEAPS
- int hn = 0;
- for (hn = 0; hn < gc_heap::n_heaps; hn++)
- {
- gc_heap* hp = gc_heap::g_heaps [hn];
-
- // 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.
- hp->walk_heap (&AllocByClassHelper, (void *)&profiling_context, 0, FALSE);
- }
-#else
- // 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.
- gc_heap::walk_heap (&AllocByClassHelper, (void *)&profiling_context, 0, FALSE);
-#endif //MULTIPLE_HEAPS
-
- // Notify that we've reached the end of the Gen 0 scan
- g_profControlBlock.pProfInterface->EndAllocByClass(&profiling_context);
- END_PIN_PROFILER();
+ heap_analyze_enabled = TRUE;
}
+#endif // HEAP_ANALYZE
-#endif // GC_PROFILING
+ GCToEEInterface::DiagGCStart(settings.condemned_generation, settings.reason == reason_induced);
#ifdef BACKGROUND_GC
if ((settings.condemned_generation == max_generation) &&
(recursive_gc_sync::background_running_p()))
{
- //TODO BACKGROUND_GC If we just wait for the end of gc, it won't woork
+ //TODO BACKGROUND_GC If we just wait for the end of gc, it won't work
// because we have to collect 0 and 1 properly
// in particular, the allocation contexts are gone.
// For now, it is simpler to collect max_generation-1
@@ -19625,12 +19627,7 @@ void gc_heap::mark_phase (int condemned_gen_number, BOOL mark_only_p)
dprintf (3, ("Finalize marking"));
finalize_queue->ScanForFinalization (GCHeap::Promote, condemned_gen_number, mark_only_p, __this);
-#ifdef GC_PROFILING
- if (CORProfilerTrackGC())
- {
- finalize_queue->WalkFReachableObjects (__this);
- }
-#endif //GC_PROFILING
+ GCToEEInterface::DiagWalkFReachableObjects(__this);
#endif // FEATURE_PREMORTEM_FINALIZATION
// Scan dependent handles again to promote any secondaries associated with primaries that were promoted
@@ -21105,8 +21102,7 @@ void gc_heap::relocate_in_loh_compact()
generation_free_obj_space (gen)));
}
-#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
-void gc_heap::walk_relocation_loh (size_t profiling_context)
+void gc_heap::walk_relocation_for_loh (size_t profiling_context, record_surv_fn fn)
{
generation* gen = large_object_generation;
heap_segment* seg = heap_segment_rw (generation_start_segment (gen));
@@ -21136,14 +21132,7 @@ void gc_heap::walk_relocation_loh (size_t profiling_context)
STRESS_LOG_PLUG_MOVE(o, (o + size), -reloc);
- {
- ETW::GCLog::MovedReference(
- o,
- (o + size),
- reloc,
- profiling_context,
- settings.compaction);
- }
+ fn (o, (o + size), reloc, profiling_context, settings.compaction, FALSE);
o = o + size;
if (o < heap_segment_allocated (seg))
@@ -21160,7 +21149,6 @@ void gc_heap::walk_relocation_loh (size_t profiling_context)
}
}
}
-#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
BOOL gc_heap::loh_object_p (uint8_t* o)
{
@@ -22250,7 +22238,7 @@ void gc_heap::plan_phase (int condemned_gen_number)
#endif //TIME_GC
// We may update write barrier code. We assume here EE has been suspended if we are on a GC thread.
- assert(GCHeap::IsGCInProgress());
+ assert(IsGCInProgress());
BOOL should_expand = FALSE;
BOOL should_compact= FALSE;
@@ -22318,10 +22306,7 @@ void gc_heap::plan_phase (int condemned_gen_number)
if (!loh_compacted_p)
#endif //FEATURE_LOH_COMPACTION
{
-#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
- if (ShouldTrackMovementForProfilerOrEtw())
- notify_profiler_of_surviving_large_objects();
-#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+ GCToEEInterface::DiagWalkLOHSurvivors(__this);
sweep_large_objects();
}
}
@@ -22432,7 +22417,7 @@ void gc_heap::plan_phase (int condemned_gen_number)
for (i = 0; i < n_heaps; i++)
{
//copy the card and brick tables
- if (g_card_table!= g_heaps[i]->card_table)
+ if (g_gc_card_table!= g_heaps[i]->card_table)
{
g_heaps[i]->copy_brick_card_table();
}
@@ -22523,12 +22508,7 @@ void gc_heap::plan_phase (int condemned_gen_number)
assert (generation_allocation_segment (consing_gen) ==
ephemeral_heap_segment);
-#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
- if (ShouldTrackMovementForProfilerOrEtw())
- {
- record_survived_for_profiler(condemned_gen_number, first_condemned_address);
- }
-#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+ GCToEEInterface::DiagWalkSurvivors(__this);
relocate_phase (condemned_gen_number, first_condemned_address);
compact_phase (condemned_gen_number, first_condemned_address,
@@ -22738,12 +22718,7 @@ void gc_heap::plan_phase (int condemned_gen_number)
fix_older_allocation_area (older_gen);
}
-#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
- if (ShouldTrackMovementForProfilerOrEtw())
- {
- record_survived_for_profiler(condemned_gen_number, first_condemned_address);
- }
-#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+ GCToEEInterface::DiagWalkSurvivors(__this);
gen0_big_free_spaces = 0;
make_free_lists (condemned_gen_number);
@@ -23949,8 +23924,7 @@ void gc_heap::relocate_survivors (int condemned_gen_number,
}
}
-#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
-void gc_heap::walk_plug (uint8_t* plug, size_t size, BOOL check_last_object_p, walk_relocate_args* args, size_t profiling_context)
+void gc_heap::walk_plug (uint8_t* plug, size_t size, BOOL check_last_object_p, walk_relocate_args* args)
{
if (check_last_object_p)
{
@@ -23970,15 +23944,10 @@ void gc_heap::walk_plug (uint8_t* plug, size_t size, BOOL check_last_object_p, w
}
ptrdiff_t last_plug_relocation = node_relocation_distance (plug);
- ptrdiff_t reloc = settings.compaction ? last_plug_relocation : 0;
-
STRESS_LOG_PLUG_MOVE(plug, (plug + size), -last_plug_relocation);
+ ptrdiff_t reloc = settings.compaction ? last_plug_relocation : 0;
- ETW::GCLog::MovedReference(plug,
- (plug + size),
- reloc,
- profiling_context,
- settings.compaction);
+ (args->fn) (plug, (plug + size), reloc, args->profiling_context, settings.compaction, FALSE);
if (check_last_object_p)
{
@@ -23995,12 +23964,12 @@ void gc_heap::walk_plug (uint8_t* plug, size_t size, BOOL check_last_object_p, w
}
}
-void gc_heap::walk_relocation_in_brick (uint8_t* tree, walk_relocate_args* args, size_t profiling_context)
+void gc_heap::walk_relocation_in_brick (uint8_t* tree, walk_relocate_args* args)
{
assert ((tree != NULL));
if (node_left_child (tree))
{
- walk_relocation_in_brick (tree + node_left_child (tree), args, profiling_context);
+ walk_relocation_in_brick (tree + node_left_child (tree), args);
}
uint8_t* plug = tree;
@@ -24029,7 +23998,7 @@ void gc_heap::walk_relocation_in_brick (uint8_t* tree, walk_relocate_args* args,
assert (last_plug_size >= Align (min_obj_size));
}
- walk_plug (args->last_plug, last_plug_size, check_last_object_p, args, profiling_context);
+ walk_plug (args->last_plug, last_plug_size, check_last_object_p, args);
}
else
{
@@ -24042,18 +24011,14 @@ void gc_heap::walk_relocation_in_brick (uint8_t* tree, walk_relocate_args* args,
if (node_right_child (tree))
{
- walk_relocation_in_brick (tree + node_right_child (tree), args, profiling_context);
-
+ walk_relocation_in_brick (tree + node_right_child (tree), args);
}
}
-void gc_heap::walk_relocation (int condemned_gen_number,
- uint8_t* first_condemned_address,
- size_t profiling_context)
-
+void gc_heap::walk_relocation (size_t profiling_context, record_surv_fn fn)
{
- generation* condemned_gen = generation_of (condemned_gen_number);
- uint8_t* start_address = first_condemned_address;
+ generation* condemned_gen = generation_of (settings.condemned_generation);
+ uint8_t* start_address = generation_allocation_start (condemned_gen);
size_t current_brick = brick_of (start_address);
heap_segment* current_heap_segment = heap_segment_rw (generation_start_segment (condemned_gen));
@@ -24066,6 +24031,8 @@ void gc_heap::walk_relocation (int condemned_gen_number,
args.is_shortened = FALSE;
args.pinned_plug_entry = 0;
args.last_plug = 0;
+ args.profiling_context = profiling_context;
+ args.fn = fn;
while (1)
{
@@ -24075,8 +24042,8 @@ void gc_heap::walk_relocation (int condemned_gen_number,
{
walk_plug (args.last_plug,
(heap_segment_allocated (current_heap_segment) - args.last_plug),
- args.is_shortened,
- &args, profiling_context);
+ args.is_shortened,
+ &args);
args.last_plug = 0;
}
if (heap_segment_next_rw (current_heap_segment))
@@ -24097,16 +24064,29 @@ void gc_heap::walk_relocation (int condemned_gen_number,
{
walk_relocation_in_brick (brick_address (current_brick) +
brick_entry - 1,
- &args,
- profiling_context);
+ &args);
}
}
current_brick++;
}
}
+void gc_heap::walk_survivors (record_surv_fn fn, size_t context, walk_surv_type type)
+{
+ if (type == walk_for_gc)
+ walk_survivors_relocation (context, fn);
+#if defined(BACKGROUND_GC) && defined(FEATURE_EVENT_TRACE)
+ else if (type == walk_for_bgc)
+ walk_survivors_for_bgc (context, fn);
+#endif //BACKGROUND_GC && FEATURE_EVENT_TRACE
+ else if (type == walk_for_loh)
+ walk_survivors_for_loh (context, fn);
+ else
+ assert (!"unknown type!");
+}
+
#if defined(BACKGROUND_GC) && defined(FEATURE_EVENT_TRACE)
-void gc_heap::walk_relocation_for_bgc(size_t profiling_context)
+void gc_heap::walk_survivors_for_bgc (size_t profiling_context, record_surv_fn fn)
{
// This should only be called for BGCs
assert(settings.concurrent);
@@ -24140,8 +24120,7 @@ void gc_heap::walk_relocation_for_bgc(size_t profiling_context)
uint8_t* end = heap_segment_allocated (seg);
while (o < end)
- {
-
+ {
if (method_table(o) == g_pFreeObjectMethodTable)
{
o += Align (size (o), align_const);
@@ -24164,51 +24143,18 @@ void gc_heap::walk_relocation_for_bgc(size_t profiling_context)
uint8_t* plug_end = o;
- // Note on last parameter: since this is for bgc, only ETW
- // should be sending these events so that existing profapi profilers
- // don't get confused.
- ETW::GCLog::MovedReference(
- plug_start,
+ fn (plug_start,
plug_end,
0, // Reloc distance == 0 as this is non-compacting
profiling_context,
FALSE, // Non-compacting
- FALSE); // fAllowProfApiNotification
+ TRUE); // BGC
}
seg = heap_segment_next (seg);
}
}
-
-void gc_heap::make_free_lists_for_profiler_for_bgc ()
-{
- assert(settings.concurrent);
-
- size_t profiling_context = 0;
- ETW::GCLog::BeginMovedReferences(&profiling_context);
-
- // This provides the profiler with information on what blocks of
- // memory are moved during a gc.
-
- walk_relocation_for_bgc(profiling_context);
-
- // Notify the EE-side profiling code that all the references have been traced for
- // this heap, and that it needs to flush all cached data it hasn't sent to the
- // profiler and release resources it no longer needs. Since this is for bgc, only
- // ETW should be sending these events so that existing profapi profilers don't get confused.
- ETW::GCLog::EndMovedReferences(profiling_context, FALSE /* fAllowProfApiNotification */);
-
-#ifdef MULTIPLE_HEAPS
- bgc_t_join.join(this, gc_join_after_profiler_heap_walk);
- if (bgc_t_join.joined())
- {
- bgc_t_join.restart();
- }
-#endif // MULTIPLE_HEAPS
-}
-
#endif // defined(BACKGROUND_GC) && defined(FEATURE_EVENT_TRACE)
-#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
void gc_heap::relocate_phase (int condemned_gen_number,
uint8_t* first_condemned_address)
@@ -24809,7 +24755,7 @@ void gc_heap::compact_phase (int condemned_gen_number,
#pragma warning(push)
#pragma warning(disable:4702) // C4702: unreachable code: gc_thread_function may not return
#endif //_MSC_VER
-void __stdcall gc_heap::gc_thread_stub (void* arg)
+void gc_heap::gc_thread_stub (void* arg)
{
ClrFlsSetThreadType (ThreadType_GC);
STRESS_LOG_RESERVE_MEM (GC_STRESSLOG_MULTIPLY);
@@ -25177,14 +25123,14 @@ BOOL gc_heap::commit_mark_array_new_seg (gc_heap* hp,
if (new_card_table == 0)
{
- new_card_table = g_card_table;
+ new_card_table = g_gc_card_table;
}
if (hp->card_table != new_card_table)
{
if (new_lowest_address == 0)
{
- new_lowest_address = g_lowest_address;
+ new_lowest_address = g_gc_lowest_address;
}
uint32_t* ct = &new_card_table[card_word (gcard_of (new_lowest_address))];
@@ -26046,9 +25992,9 @@ gc_heap::suspend_EE ()
dprintf (2, ("suspend_EE"));
#ifdef MULTIPLE_HEAPS
gc_heap* hp = gc_heap::g_heaps[0];
- GCToEEInterface::SuspendEE(GCToEEInterface::SUSPEND_FOR_GC_PREP);
+ GCToEEInterface::SuspendEE(SUSPEND_FOR_GC_PREP);
#else
- GCToEEInterface::SuspendEE(GCToEEInterface::SUSPEND_FOR_GC_PREP);
+ GCToEEInterface::SuspendEE(SUSPEND_FOR_GC_PREP);
#endif //MULTIPLE_HEAPS
}
@@ -26062,7 +26008,7 @@ gc_heap::bgc_suspend_EE ()
}
gc_started = TRUE;
dprintf (2, ("bgc_suspend_EE"));
- GCToEEInterface::SuspendEE(GCToEEInterface::SUSPEND_FOR_GC_PREP);
+ GCToEEInterface::SuspendEE(SUSPEND_FOR_GC_PREP);
gc_started = FALSE;
for (int i = 0; i < n_heaps; i++)
@@ -26077,7 +26023,7 @@ gc_heap::bgc_suspend_EE ()
reset_gc_done();
gc_started = TRUE;
dprintf (2, ("bgc_suspend_EE"));
- GCToEEInterface::SuspendEE(GCToEEInterface::SUSPEND_FOR_GC_PREP);
+ GCToEEInterface::SuspendEE(SUSPEND_FOR_GC_PREP);
gc_started = FALSE;
set_gc_done();
}
@@ -29174,7 +29120,7 @@ generation* gc_heap::expand_heap (int condemned_generation,
return consing_gen;
//copy the card and brick tables
- if (g_card_table!= card_table)
+ if (g_gc_card_table!= card_table)
copy_brick_card_table();
BOOL new_segment_p = (heap_segment_next (new_seg) == 0);
@@ -30469,7 +30415,7 @@ CObjectHeader* gc_heap::allocate_large_object (size_t jsize, int64_t& alloc_byte
acontext.alloc_limit = 0;
acontext.alloc_bytes = 0;
#ifdef MULTIPLE_HEAPS
- acontext.alloc_heap = vm_heap;
+ acontext.set_alloc_heap(vm_heap);
#endif //MULTIPLE_HEAPS
#ifdef MARK_ARRAY
@@ -30484,14 +30430,11 @@ CObjectHeader* gc_heap::allocate_large_object (size_t jsize, int64_t& alloc_byte
#endif //BACKGROUND_GC
#endif // MARK_ARRAY
+ #if BIT64
+ size_t maxObjectSize = (INT64_MAX - 7 - Align(min_obj_size));
+ #else
size_t maxObjectSize = (INT32_MAX - 7 - Align(min_obj_size));
-
-#ifdef BIT64
- if (g_pConfig->GetGCAllowVeryLargeObjects())
- {
- maxObjectSize = (INT64_MAX - 7 - Align(min_obj_size));
- }
-#endif
+ #endif
if (jsize >= maxObjectSize)
{
@@ -30499,12 +30442,7 @@ CObjectHeader* gc_heap::allocate_large_object (size_t jsize, int64_t& alloc_byte
{
GCToOSInterface::DebugBreak();
}
-
-#ifndef FEATURE_REDHAWK
- ThrowOutOfMemoryDimensionsExceeded();
-#else
- return 0;
-#endif
+ return NULL;
}
size_t size = AlignQword (jsize);
@@ -30627,35 +30565,21 @@ BOOL gc_heap::large_object_marked (uint8_t* o, BOOL clearp)
return m;
}
-#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
-void gc_heap::record_survived_for_profiler(int condemned_gen_number, uint8_t * start_address)
+void gc_heap::walk_survivors_relocation (size_t profiling_context, record_surv_fn fn)
{
- size_t profiling_context = 0;
-
- ETW::GCLog::BeginMovedReferences(&profiling_context);
-
// Now walk the portion of memory that is actually being relocated.
- walk_relocation(condemned_gen_number, start_address, profiling_context);
+ walk_relocation (profiling_context, fn);
#ifdef FEATURE_LOH_COMPACTION
if (loh_compacted_p)
{
- walk_relocation_loh (profiling_context);
+ walk_relocation_for_loh (profiling_context, fn);
}
#endif //FEATURE_LOH_COMPACTION
-
- // Notify the EE-side profiling code that all the references have been traced for
- // this heap, and that it needs to flush all cached data it hasn't sent to the
- // profiler and release resources it no longer needs.
- ETW::GCLog::EndMovedReferences(profiling_context);
}
-void gc_heap::notify_profiler_of_surviving_large_objects ()
+void gc_heap::walk_survivors_for_loh (size_t profiling_context, record_surv_fn fn)
{
- size_t profiling_context = 0;
-
- ETW::GCLog::BeginMovedReferences(&profiling_context);
-
generation* gen = large_object_generation;
heap_segment* seg = heap_segment_rw (generation_start_segment (gen));;
@@ -30665,13 +30589,6 @@ void gc_heap::notify_profiler_of_surviving_large_objects ()
uint8_t* plug_end = o;
uint8_t* plug_start = o;
- // Generally, we can only get here if this is TRUE:
- // (CORProfilerTrackGC() || ETW::GCLog::ShouldTrackMovementForEtw())
- // But we can't always assert that, as races could theoretically cause GC profiling
- // or ETW to turn off just before we get here. This is harmless (we do checks later
- // on, under appropriate locks, before actually calling into profilers), though it's
- // a slowdown to determine these plugs for nothing.
-
while (1)
{
if (o >= heap_segment_allocated (seg))
@@ -30699,12 +30616,7 @@ void gc_heap::notify_profiler_of_surviving_large_objects ()
plug_end = o;
- ETW::GCLog::MovedReference(
- plug_start,
- plug_end,
- 0,
- profiling_context,
- FALSE);
+ fn (plug_start, plug_end, 0, profiling_context, FALSE, FALSE);
}
else
{
@@ -30714,9 +30626,7 @@ void gc_heap::notify_profiler_of_surviving_large_objects ()
}
}
}
- ETW::GCLog::EndMovedReferences(profiling_context);
}
-#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
#ifdef BACKGROUND_GC
@@ -31946,11 +31856,10 @@ void gc_heap::descr_card_table ()
#endif //TRACE_GC
}
-#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
void gc_heap::descr_generations_to_profiler (gen_walk_fn fn, void *context)
{
#ifdef MULTIPLE_HEAPS
- int n_heaps = GCHeap::GetGCHeap()->GetNumberOfHeaps ();
+ int n_heaps = g_theGCHeap->GetNumberOfHeaps ();
for (int i = 0; i < n_heaps; i++)
{
gc_heap* hp = GCHeap::GetHeap(i)->pGenGCHeap;
@@ -32027,7 +31936,6 @@ void gc_heap::descr_generations_to_profiler (gen_walk_fn fn, void *context)
}
}
}
-#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
#ifdef TRACE_GC
// Note that when logging is on it can take a long time to go through the free items.
@@ -32522,7 +32430,7 @@ void gc_heap::clear_all_mark_array()
void gc_heap::verify_mark_array_cleared (heap_segment* seg)
{
#if defined (VERIFY_HEAP) && defined (MARK_ARRAY)
- assert (card_table == g_card_table);
+ assert (card_table == g_gc_card_table);
size_t markw = mark_word_of (heap_segment_mem (seg));
size_t markw_end = mark_word_of (heap_segment_reserved (seg));
@@ -32870,8 +32778,8 @@ gc_heap::verify_heap (BOOL begin_gc_p)
#endif //BACKGROUND_GC
#ifndef MULTIPLE_HEAPS
- if ((g_ephemeral_low != generation_allocation_start (generation_of (max_generation - 1))) ||
- (g_ephemeral_high != heap_segment_reserved (ephemeral_heap_segment)))
+ if ((g_gc_ephemeral_low != generation_allocation_start (generation_of (max_generation - 1))) ||
+ (g_gc_ephemeral_high != heap_segment_reserved (ephemeral_heap_segment)))
{
FATAL_GC_ERROR();
}
@@ -32930,7 +32838,7 @@ gc_heap::verify_heap (BOOL begin_gc_p)
for (int i = 0; i < n_heaps; i++)
{
//copy the card and brick tables
- if (g_card_table != g_heaps[i]->card_table)
+ if (g_gc_card_table != g_heaps[i]->card_table)
{
g_heaps[i]->copy_brick_card_table();
}
@@ -32939,7 +32847,7 @@ gc_heap::verify_heap (BOOL begin_gc_p)
current_join->restart();
}
#else
- if (g_card_table != card_table)
+ if (g_gc_card_table != card_table)
copy_brick_card_table();
#endif //MULTIPLE_HEAPS
@@ -33306,8 +33214,12 @@ gc_heap::verify_heap (BOOL begin_gc_p)
#endif //BACKGROUND_GC
}
+#endif //VERIFY_HEAP
+
+
void GCHeap::ValidateObjectMember (Object* obj)
{
+#ifdef VERIFY_HEAP
size_t s = size (obj);
uint8_t* o = (uint8_t*)obj;
@@ -33325,9 +33237,8 @@ void GCHeap::ValidateObjectMember (Object* obj)
}
}
} );
-
+#endif // VERIFY_HEAP
}
-#endif //VERIFY_HEAP
void DestructObject (CObjectHeader* hdr)
{
@@ -33361,11 +33272,11 @@ HRESULT GCHeap::Shutdown ()
//CloseHandle (WaitForGCEvent);
//find out if the global card table hasn't been used yet
- uint32_t* ct = &g_card_table[card_word (gcard_of (g_lowest_address))];
+ uint32_t* ct = &g_gc_card_table[card_word (gcard_of (g_gc_lowest_address))];
if (card_table_refcount (ct) == 0)
{
destroy_card_table (ct);
- g_card_table = 0;
+ g_gc_card_table = 0;
#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
SoftwareWriteWatch::StaticClose();
#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
@@ -33525,7 +33436,7 @@ HRESULT GCHeap::Initialize ()
return E_FAIL;
}
- StompWriteBarrierResize(true, false);
+ stomp_write_barrier_initialize();
#ifndef FEATURE_REDHAWK // Redhawk forces relocation a different way
#if defined (STRESS_HEAP) && !defined (MULTIPLE_HEAPS)
@@ -33562,10 +33473,7 @@ HRESULT GCHeap::Initialize ()
{
GCScan::GcRuntimeStructuresValid (TRUE);
-#ifdef GC_PROFILING
- if (CORProfilerTrackGC())
- UpdateGenerationBounds();
-#endif // GC_PROFILING
+ GCToEEInterface::DiagUpdateGenerationBounds();
}
return hr;
@@ -33640,16 +33548,16 @@ BOOL GCHeap::IsEphemeral (Object* object)
return hp->ephemeral_pointer_p (o);
}
-#ifdef VERIFY_HEAP
// Return NULL if can't find next object. When EE is not suspended,
// the result is not accurate: if the input arg is in gen0, the function could
// return zeroed out memory as next object
Object * GCHeap::NextObj (Object * object)
{
+#ifdef VERIFY_HEAP
uint8_t* o = (uint8_t*)object;
#ifndef FEATURE_BASICFREEZE
- if (!((o < g_highest_address) && (o >= g_lowest_address)))
+ if (!((o < g_gc_highest_address) && (o >= g_gc_lowest_address)))
{
return NULL;
}
@@ -33687,8 +33595,13 @@ Object * GCHeap::NextObj (Object * object)
}
return (Object *)nextobj;
+#else
+ return nullptr;
+#endif // VERIFY_HEAP
}
+#ifdef VERIFY_HEAP
+
#ifdef FEATURE_BASICFREEZE
BOOL GCHeap::IsInFrozenSegment (Object * object)
{
@@ -33715,7 +33628,7 @@ BOOL GCHeap::IsHeapPointer (void* vpObject, BOOL small_heap_only)
uint8_t* object = (uint8_t*) vpObject;
#ifndef FEATURE_BASICFREEZE
- if (!((object < g_highest_address) && (object >= g_lowest_address)))
+ if (!((object < g_gc_highest_address) && (object >= g_gc_lowest_address)))
return FALSE;
#endif //!FEATURE_BASICFREEZE
@@ -33918,11 +33831,16 @@ int StressRNG(int iMaxValue)
int randValue = (((lHoldrand = lHoldrand * 214013L + 2531011L) >> 16) & 0x7fff);
return randValue % iMaxValue;
}
+#endif // STRESS_HEAP
+#endif // !FEATURE_REDHAWK
// free up object so that things will move and then do a GC
//return TRUE if GC actually happens, otherwise FALSE
-BOOL GCHeap::StressHeap(alloc_context * acontext)
+BOOL GCHeap::StressHeap(gc_alloc_context * context)
{
+#if defined(STRESS_HEAP) && !defined(FEATURE_REDHAWK)
+ alloc_context* acontext = static_cast<alloc_context*>(context);
+
// if GC stress was dynamically disabled during this run we return FALSE
if (!GCStressPolicy::IsEnabled())
return FALSE;
@@ -34102,11 +34020,12 @@ BOOL GCHeap::StressHeap(alloc_context * acontext)
}
return TRUE;
+#else
+ UNREFERENCED_PARAMETER(context);
+ return FALSE;
+#endif // defined(STRESS_HEAP) && !defined(FEATURE_REDHAWK)
}
-#endif // STRESS_HEAP
-#endif // FEATURE_REDHAWK
-
#ifdef FEATURE_PREMORTEM_FINALIZATION
#define REGISTER_FOR_FINALIZATION(_object, _size) \
@@ -34115,7 +34034,6 @@ BOOL GCHeap::StressHeap(alloc_context * acontext)
#define REGISTER_FOR_FINALIZATION(_object, _size) true
#endif // FEATURE_PREMORTEM_FINALIZATION
-#ifdef FEATURE_REDHAWK
#define CHECK_ALLOC_AND_POSSIBLY_REGISTER_FOR_FINALIZATION(_object, _size, _register) do { \
if ((_object) == NULL || ((_register) && !REGISTER_FOR_FINALIZATION(_object, _size))) \
{ \
@@ -34123,19 +34041,6 @@ BOOL GCHeap::StressHeap(alloc_context * acontext)
return NULL; \
} \
} while (false)
-#else // FEATURE_REDHAWK
-#define CHECK_ALLOC_AND_POSSIBLY_REGISTER_FOR_FINALIZATION(_object, _size, _register) do { \
- if ((_object) == NULL) \
- { \
- STRESS_LOG_OOM_STACK(_size); \
- ThrowOutOfMemory(); \
- } \
- if (_register) \
- { \
- REGISTER_FOR_FINALIZATION(_object, _size); \
- } \
-} while (false)
-#endif // FEATURE_REDHAWK
//
// Small Object Allocator
@@ -34145,27 +34050,12 @@ Object *
GCHeap::Alloc( size_t size, uint32_t flags REQD_ALIGN_DCL)
{
CONTRACTL {
-#ifdef FEATURE_REDHAWK
- // Under Redhawk NULL is returned on failure.
NOTHROW;
-#else
- THROWS;
-#endif
GC_TRIGGERS;
} CONTRACTL_END;
-#if defined(_DEBUG) && !defined(FEATURE_REDHAWK)
- if (g_pConfig->ShouldInjectFault(INJECTFAULT_GCHEAP))
- {
- char *a = new char;
- delete a;
- }
-#endif //_DEBUG && !FEATURE_REDHAWK
-
TRIGGERSGC();
- assert (!GCHeap::UseAllocationContexts());
-
Object* newAlloc = NULL;
#ifdef TRACE_GC
@@ -34237,23 +34127,16 @@ GCHeap::Alloc( size_t size, uint32_t flags REQD_ALIGN_DCL)
return newAlloc;
}
-#ifdef FEATURE_64BIT_ALIGNMENT
// 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 {
-#ifdef FEATURE_REDHAWK
- // Under Redhawk NULL is returned on failure.
NOTHROW;
-#else
- THROWS;
-#endif
GC_TRIGGERS;
} CONTRACTL_END;
- assert (!GCHeap::UseAllocationContexts());
-
Object* newAlloc = NULL;
{
@@ -34270,61 +34153,60 @@ GCHeap::AllocAlign8( size_t size, uint32_t 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.
Object*
-GCHeap::AllocAlign8(alloc_context* acontext, size_t size, uint32_t flags )
+GCHeap::AllocAlign8(gc_alloc_context* ctx, size_t size, uint32_t flags )
{
+#ifdef FEATURE_64BIT_ALIGNMENT
CONTRACTL {
-#ifdef FEATURE_REDHAWK
- // Under Redhawk NULL is returned on failure.
NOTHROW;
-#else
- THROWS;
-#endif
GC_TRIGGERS;
} CONTRACTL_END;
+ alloc_context* acontext = static_cast<alloc_context*>(ctx);
+
#ifdef MULTIPLE_HEAPS
- if (acontext->alloc_heap == 0)
+ if (acontext->get_alloc_heap() == 0)
{
AssignHeap (acontext);
- assert (acontext->alloc_heap);
+ assert (acontext->get_alloc_heap());
}
- gc_heap* hp = acontext->alloc_heap->pGenGCHeap;
+ gc_heap* hp = acontext->get_alloc_heap()->pGenGCHeap;
#else
gc_heap* hp = pGenGCHeap;
#endif //MULTIPLE_HEAPS
return AllocAlign8Common(hp, acontext, size, flags);
+#else
+ UNREFERENCED_PARAMETER(ctx);
+ UNREFERENCED_PARAMETER(size);
+ UNREFERENCED_PARAMETER(flags);
+ assert(!"should not call GCHeap::AllocAlign8 without FEATURE_64BIT_ALIGNMENT defined!");
+ return nullptr;
+#endif //FEATURE_64BIT_ALIGNMENT
}
// Common code used by both variants of AllocAlign8 above.
Object*
GCHeap::AllocAlign8Common(void* _hp, alloc_context* acontext, size_t size, uint32_t flags)
{
+#ifdef FEATURE_64BIT_ALIGNMENT
CONTRACTL {
-#ifdef FEATURE_REDHAWK
- // Under Redhawk NULL is returned on failure.
NOTHROW;
-#else
- THROWS;
-#endif
GC_TRIGGERS;
} CONTRACTL_END;
gc_heap* hp = (gc_heap*)_hp;
-#if defined(_DEBUG) && !defined(FEATURE_REDHAWK)
- if (g_pConfig->ShouldInjectFault(INJECTFAULT_GCHEAP))
- {
- char *a = new char;
- delete a;
- }
-#endif //_DEBUG && !FEATURE_REDHAWK
-
TRIGGERSGC();
Object* newAlloc = NULL;
@@ -34424,30 +34306,24 @@ GCHeap::AllocAlign8Common(void* _hp, alloc_context* acontext, size_t size, uint3
AllocCount++;
#endif //TRACE_GC
return newAlloc;
-}
+#else
+ UNREFERENCED_PARAMETER(_hp);
+ UNREFERENCED_PARAMETER(acontext);
+ UNREFERENCED_PARAMETER(size);
+ UNREFERENCED_PARAMETER(flags);
+ assert(!"Should not call GCHeap::AllocAlign8Common without FEATURE_64BIT_ALIGNMENT defined!");
+ return nullptr;
#endif // FEATURE_64BIT_ALIGNMENT
+}
Object *
GCHeap::AllocLHeap( size_t size, uint32_t flags REQD_ALIGN_DCL)
{
CONTRACTL {
-#ifdef FEATURE_REDHAWK
- // Under Redhawk NULL is returned on failure.
NOTHROW;
-#else
- THROWS;
-#endif
GC_TRIGGERS;
} CONTRACTL_END;
-#if defined(_DEBUG) && !defined(FEATURE_REDHAWK)
- if (g_pConfig->ShouldInjectFault(INJECTFAULT_GCHEAP))
- {
- char *a = new char;
- delete a;
- }
-#endif //_DEBUG && !FEATURE_REDHAWK
-
TRIGGERSGC();
Object* newAlloc = NULL;
@@ -34499,29 +34375,17 @@ GCHeap::AllocLHeap( size_t size, uint32_t flags REQD_ALIGN_DCL)
}
Object*
-GCHeap::Alloc(alloc_context* acontext, size_t size, uint32_t flags REQD_ALIGN_DCL)
+GCHeap::Alloc(gc_alloc_context* context, size_t size, uint32_t flags REQD_ALIGN_DCL)
{
CONTRACTL {
-#ifdef FEATURE_REDHAWK
- // Under Redhawk NULL is returned on failure.
NOTHROW;
-#else
- THROWS;
-#endif
GC_TRIGGERS;
} CONTRACTL_END;
-#if defined(_DEBUG) && !defined(FEATURE_REDHAWK)
- if (g_pConfig->ShouldInjectFault(INJECTFAULT_GCHEAP))
- {
- char *a = new char;
- delete a;
- }
-#endif //_DEBUG && !FEATURE_REDHAWK
-
TRIGGERSGC();
Object* newAlloc = NULL;
+ alloc_context* acontext = static_cast<alloc_context*>(context);
#ifdef TRACE_GC
#ifdef COUNT_CYCLES
@@ -34534,10 +34398,10 @@ GCHeap::Alloc(alloc_context* acontext, size_t size, uint32_t flags REQD_ALIGN_DC
#endif //TRACE_GC
#ifdef MULTIPLE_HEAPS
- if (acontext->alloc_heap == 0)
+ if (acontext->get_alloc_heap() == 0)
{
AssignHeap (acontext);
- assert (acontext->alloc_heap);
+ assert (acontext->get_alloc_heap());
}
#endif //MULTIPLE_HEAPS
@@ -34546,7 +34410,7 @@ GCHeap::Alloc(alloc_context* acontext, size_t size, uint32_t flags REQD_ALIGN_DC
#endif // FEATURE_REDHAWK
#ifdef MULTIPLE_HEAPS
- gc_heap* hp = acontext->alloc_heap->pGenGCHeap;
+ gc_heap* hp = acontext->get_alloc_heap()->pGenGCHeap;
#else
gc_heap* hp = pGenGCHeap;
#ifdef _PREFAST_
@@ -34591,8 +34455,9 @@ GCHeap::Alloc(alloc_context* acontext, size_t size, uint32_t flags REQD_ALIGN_DC
}
void
-GCHeap::FixAllocContext (alloc_context* acontext, 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
if (arg != 0)
@@ -35017,7 +34882,6 @@ void gc_heap::do_post_gc()
{
if (!settings.concurrent)
{
- GCProfileWalkHeap();
initGCShadow();
}
@@ -35037,13 +34901,10 @@ void gc_heap::do_post_gc()
GCToEEInterface::GcDone(settings.condemned_generation);
-#ifdef GC_PROFILING
- if (!settings.concurrent)
- {
- UpdateGenerationBounds();
- GarbageCollectionFinishedCallback();
- }
-#endif // GC_PROFILING
+ GCToEEInterface::DiagGCEnd(VolatileLoad(&settings.gc_index),
+ (uint32_t)settings.condemned_generation,
+ (uint32_t)settings.reason,
+ !!settings.concurrent);
//dprintf (1, (" ****end of Garbage Collection**** %d(gen0:%d)(%d)",
dprintf (1, ("*EGC* %d(gen0:%d)(%d)(%s)",
@@ -35168,7 +35029,7 @@ GCHeap::GarbageCollectGeneration (unsigned int gen, gc_reason reason)
dprintf (2, ("Suspending EE"));
BEGIN_TIMING(suspend_ee_during_log);
- GCToEEInterface::SuspendEE(GCToEEInterface::SUSPEND_FOR_GC);
+ GCToEEInterface::SuspendEE(SUSPEND_FOR_GC);
END_TIMING(suspend_ee_during_log);
gc_heap::proceed_with_gc_p = gc_heap::should_proceed_with_gc();
gc_heap::disable_preemptive (current_thread, cooperative_mode);
@@ -35383,8 +35244,8 @@ size_t GCHeap::ApproxTotalBytesInUse(BOOL small_heap_only)
void GCHeap::AssignHeap (alloc_context* acontext)
{
// Assign heap based on processor
- acontext->alloc_heap = GetHeap(heap_select::select_heap(acontext, 0));
- acontext->home_heap = acontext->alloc_heap;
+ acontext->set_alloc_heap(GetHeap(heap_select::select_heap(acontext, 0)));
+ acontext->set_home_heap(acontext->get_alloc_heap());
}
GCHeap* GCHeap::GetHeap (int n)
{
@@ -35393,11 +35254,12 @@ GCHeap* GCHeap::GetHeap (int n)
}
#endif //MULTIPLE_HEAPS
-bool GCHeap::IsThreadUsingAllocationContextHeap(alloc_context* acontext, int thread_number)
+bool GCHeap::IsThreadUsingAllocationContextHeap(gc_alloc_context* context, int thread_number)
{
+ alloc_context* acontext = static_cast<alloc_context*>(context);
#ifdef MULTIPLE_HEAPS
- return ((acontext->home_heap == GetHeap(thread_number)) ||
- ((acontext->home_heap == 0) && (thread_number == 0)));
+ return ((acontext->get_home_heap() == GetHeap(thread_number)) ||
+ ((acontext->get_home_heap() == 0) && (thread_number == 0)));
#else
UNREFERENCED_PARAMETER(acontext);
UNREFERENCED_PARAMETER(thread_number);
@@ -35427,7 +35289,8 @@ int GCHeap::GetHomeHeapNumber ()
{
if (pThread)
{
- GCHeap *hp = GCToEEInterface::GetAllocContext(pThread)->home_heap;
+ gc_alloc_context* ctx = GCToEEInterface::GetAllocContext(pThread);
+ GCHeap *hp = static_cast<alloc_context*>(ctx)->get_home_heap();
if (hp == gc_heap::g_heaps[i]->vm_heap) return i;
}
}
@@ -35639,7 +35502,7 @@ size_t GCHeap::GetValidGen0MaxSize(size_t seg_size)
{
size_t gen0size = g_pConfig->GetGCgen0size();
- if ((gen0size == 0) || !GCHeap::IsValidGen0MaxSize(gen0size))
+ if ((gen0size == 0) || !g_theGCHeap->IsValidGen0MaxSize(gen0size))
{
#ifdef SERVER_GC
// performance data seems to indicate halving the size results
@@ -35869,19 +35732,19 @@ GCHeap::SetCardsAfterBulkCopy( Object **StartPoint, size_t len )
#ifdef BACKGROUND_GC
(!gc_heap::settings.concurrent) &&
#endif //BACKGROUND_GC
- (GCHeap::GetGCHeap()->WhichGeneration( (Object*) StartPoint ) == 0))
+ (g_theGCHeap->WhichGeneration( (Object*) StartPoint ) == 0))
return;
rover = StartPoint;
end = StartPoint + (len/sizeof(Object*));
while (rover < end)
{
- if ( (((uint8_t*)*rover) >= g_ephemeral_low) && (((uint8_t*)*rover) < g_ephemeral_high) )
+ if ( (((uint8_t*)*rover) >= g_gc_ephemeral_low) && (((uint8_t*)*rover) < g_gc_ephemeral_high) )
{
// Set Bit For Card and advance to next card
size_t card = gcard_of ((uint8_t*)rover);
- Interlocked::Or (&g_card_table[card/card_word_width], (1U << (card % card_word_width)));
+ Interlocked::Or (&g_gc_card_table[card/card_word_width], (1U << (card % card_word_width)));
// Skip to next card for the object
rover = (Object**)align_on_card ((uint8_t*)(rover+1));
}
@@ -36000,12 +35863,7 @@ bool
CFinalize::RegisterForFinalization (int gen, Object* obj, size_t size)
{
CONTRACTL {
-#ifdef FEATURE_REDHAWK
- // Under Redhawk false is returned on failure.
NOTHROW;
-#else
- THROWS;
-#endif
GC_NOTRIGGER;
} CONTRACTL_END;
@@ -36043,11 +35901,7 @@ CFinalize::RegisterForFinalization (int gen, Object* obj, size_t size)
{
GCToOSInterface::DebugBreak();
}
-#ifdef FEATURE_REDHAWK
return false;
-#else
- ThrowOutOfMemory();
-#endif
}
}
Object*** end_si = &SegQueueLimit (dest);
@@ -36333,21 +36187,17 @@ CFinalize::GcScanRoots (promote_func* fn, int hn, ScanContext *pSC)
}
}
-#ifdef GC_PROFILING
-void CFinalize::WalkFReachableObjects (gc_heap* hp)
+void CFinalize::WalkFReachableObjects (fq_walk_fn fn)
{
- BEGIN_PIN_PROFILER(CORProfilerPresent());
Object** startIndex = SegQueue (CriticalFinalizerListSeg);
Object** stopCriticalIndex = SegQueueLimit (CriticalFinalizerListSeg);
Object** stopIndex = SegQueueLimit (FinalizerListSeg);
for (Object** po = startIndex; po < stopIndex; po++)
{
//report *po
- g_profControlBlock.pProfInterface->FinalizeableObjectQueued(po < stopCriticalIndex, (ObjectID)*po);
+ fn(po < stopCriticalIndex, *po);
}
- END_PIN_PROFILER();
}
-#endif //GC_PROFILING
BOOL
CFinalize::ScanForFinalization (promote_func* pfn, int gen, BOOL mark_only_p,
@@ -36374,7 +36224,7 @@ CFinalize::ScanForFinalization (promote_func* pfn, int gen, BOOL mark_only_p,
{
CObjectHeader* obj = (CObjectHeader*)*i;
dprintf (3, ("scanning: %Ix", (size_t)obj));
- if (!GCHeap::GetGCHeap()->IsPromoted (obj))
+ if (!g_theGCHeap->IsPromoted (obj))
{
dprintf (3, ("freacheable: %Ix", (size_t)obj));
@@ -36507,7 +36357,7 @@ CFinalize::UpdatePromotedGenerations (int gen, BOOL gen_0_empty_p)
for (Object** po = startIndex;
po < SegQueueLimit (gen_segment(i)); po++)
{
- int new_gen = GCHeap::GetGCHeap()->WhichGeneration (*po);
+ int new_gen = g_theGCHeap->WhichGeneration (*po);
if (new_gen != i)
{
if (new_gen > i)
@@ -36567,7 +36417,7 @@ void CFinalize::CheckFinalizerObjects()
for (Object **po = startIndex; po < stopIndex; po++)
{
- if ((int)GCHeap::GetGCHeap()->WhichGeneration (*po) < i)
+ if ((int)g_theGCHeap->WhichGeneration (*po) < i)
FATAL_GC_ERROR ();
((CObjectHeader*)*po)->Validate();
}
@@ -36583,8 +36433,7 @@ void CFinalize::CheckFinalizerObjects()
// End of VM specific support
//
//------------------------------------------------------------------------------
-
-void gc_heap::walk_heap (walk_fn fn, void* context, int gen_number, BOOL walk_large_object_heap_p)
+void gc_heap::walk_heap_per_heap (walk_fn fn, void* context, int gen_number, BOOL walk_large_object_heap_p)
{
generation* gen = gc_heap::generation_of (gen_number);
heap_segment* seg = generation_start_segment (gen);
@@ -36640,8 +36489,28 @@ void gc_heap::walk_heap (walk_fn fn, void* context, int gen_number, BOOL walk_la
}
}
-#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
-void GCHeap::WalkObject (Object* obj, walk_fn fn, void* context)
+void gc_heap::walk_finalize_queue (fq_walk_fn fn)
+{
+#ifdef FEATURE_PREMORTEM_FINALIZATION
+ finalize_queue->WalkFReachableObjects (fn);
+#endif //FEATURE_PREMORTEM_FINALIZATION
+}
+
+void gc_heap::walk_heap (walk_fn fn, void* context, int gen_number, BOOL walk_large_object_heap_p)
+{
+#ifdef MULTIPLE_HEAPS
+ for (int hn = 0; hn < gc_heap::n_heaps; hn++)
+ {
+ gc_heap* hp = gc_heap::g_heaps [hn];
+
+ hp->walk_heap_per_heap (fn, context, gen_number, walk_large_object_heap_p);
+ }
+#else
+ walk_heap_per_heap(fn, context, gen_number, walk_large_object_heap_p);
+#endif //MULTIPLE_HEAPS
+}
+
+void GCHeap::DiagWalkObject (Object* obj, walk_fn fn, void* context)
{
uint8_t* o = (uint8_t*)obj;
if (o)
@@ -36658,7 +36527,46 @@ void GCHeap::WalkObject (Object* obj, walk_fn fn, void* context)
);
}
}
-#endif //defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+
+void GCHeap::DiagWalkSurvivorsWithType (void* gc_context, record_surv_fn fn, size_t 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)
+{
+ gc_heap::walk_heap (fn, context, gen_number, walk_large_object_heap_p);
+}
+
+void GCHeap::DiagWalkFinalizeQueue (void* gc_context, fq_walk_fn fn)
+{
+ gc_heap* hp = (gc_heap*)gc_context;
+ hp->walk_finalize_queue (fn);
+}
+
+void GCHeap::DiagScanFinalizeQueue (fq_scan_fn fn, ScanContext* sc)
+{
+#ifdef MULTIPLE_HEAPS
+ for (int hn = 0; hn < gc_heap::n_heaps; hn++)
+ {
+ gc_heap* hp = gc_heap::g_heaps [hn];
+ hp->finalize_queue->GcScanRoots(fn, hn, sc);
+ }
+#else
+ pGenGCHeap->finalize_queue->GcScanRoots(fn, 0, sc);
+#endif //MULTIPLE_HEAPS
+}
+
+void GCHeap::DiagScanHandles (handle_scan_fn fn, int gen_number, ScanContext* context)
+{
+ GCScan::GcScanHandlesForProfilerAndETW (max_generation, context, fn);
+}
+
+void GCHeap::DiagScanDependentHandles (handle_scan_fn fn, int gen_number, ScanContext* context)
+{
+ GCScan::GcScanDependentHandlesForProfilerAndETW (max_generation, context, fn);
+}
// Go through and touch (read) each page straddled by a memory block.
void TouchPages(void * pStart, size_t cb)
@@ -36704,11 +36612,11 @@ void initGCShadow()
if (!(g_pConfig->GetHeapVerifyLevel() & EEConfig::HEAPVERIFY_BARRIERCHECK))
return;
- size_t len = g_highest_address - g_lowest_address;
+ size_t len = g_gc_highest_address - g_gc_lowest_address;
if (len > (size_t)(g_GCShadowEnd - g_GCShadow))
{
deleteGCShadow();
- g_GCShadowEnd = g_GCShadow = (uint8_t *)GCToOSInterface::VirtualReserve(0, len, 0, VirtualReserveFlags::None);
+ g_GCShadowEnd = g_GCShadow = (uint8_t *)GCToOSInterface::VirtualReserve(len, 0, VirtualReserveFlags::None);
if (g_GCShadow == NULL || !GCToOSInterface::VirtualCommit(g_GCShadow, len))
{
_ASSERTE(!"Not enough memory to run HeapVerify level 2");
@@ -36723,10 +36631,10 @@ void initGCShadow()
g_GCShadowEnd += len;
}
- // save the value of g_lowest_address at this time. If this value changes before
+ // save the value of g_gc_lowest_address at this time. If this value changes before
// the next call to checkGCWriteBarrier() it means we extended the heap (with a
// large object segment most probably), and the whole shadow segment is inconsistent.
- g_shadow_lowest_address = g_lowest_address;
+ g_shadow_lowest_address = g_gc_lowest_address;
//****** Copy the whole GC heap ******
//
@@ -36736,7 +36644,7 @@ void initGCShadow()
generation* gen = gc_heap::generation_of (max_generation);
heap_segment* seg = heap_segment_rw (generation_start_segment (gen));
- ptrdiff_t delta = g_GCShadow - g_lowest_address;
+ ptrdiff_t delta = g_GCShadow - g_gc_lowest_address;
BOOL small_object_segments = TRUE;
while(1)
{
@@ -36764,7 +36672,7 @@ void initGCShadow()
// test to see if 'ptr' was only updated via the write barrier.
inline void testGCShadow(Object** ptr)
{
- Object** shadow = (Object**) &g_GCShadow[((uint8_t*) ptr - g_lowest_address)];
+ Object** shadow = (Object**) &g_GCShadow[((uint8_t*) ptr - g_gc_lowest_address)];
if (*ptr != 0 && (uint8_t*) shadow < g_GCShadowEnd && *ptr != *shadow)
{
@@ -36823,9 +36731,9 @@ void testGCShadowHelper (uint8_t* x)
// Walk the whole heap, looking for pointers that were not updated with the write barrier.
void checkGCWriteBarrier()
{
- // g_shadow_lowest_address != g_lowest_address means the GC heap was extended by a segment
+ // g_shadow_lowest_address != g_gc_lowest_address means the GC heap was extended by a segment
// and the GC shadow segment did not track that change!
- if (g_GCShadowEnd <= g_GCShadow || g_shadow_lowest_address != g_lowest_address)
+ if (g_GCShadowEnd <= g_GCShadow || g_shadow_lowest_address != g_gc_lowest_address)
{
// No shadow stack, nothing to check.
return;
diff --git a/src/gc/gc.h b/src/gc/gc.h
index 14c6baee83..b7f1e956b6 100644
--- a/src/gc/gc.h
+++ b/src/gc/gc.h
@@ -14,9 +14,24 @@ Module Name:
#ifndef __GC_H
#define __GC_H
-#ifdef PROFILING_SUPPORTED
-#define GC_PROFILING //Turn on profiling
-#endif // PROFILING_SUPPORTED
+#ifdef Sleep
+// This is a funny workaround for the fact that "common.h" defines Sleep to be
+// Dont_Use_Sleep, with the hope of causing linker errors whenever someone tries to use sleep.
+//
+// However, GCToOSInterface defines a function called Sleep, which (due to this define) becomes
+// "Dont_Use_Sleep", which the GC in turn happily uses. The symbol that GCToOSInterface actually
+// exported was called "GCToOSInterface::Dont_Use_Sleep". While we progress in making the GC standalone,
+// we'll need to break the dependency on common.h (the VM header) and this problem will become moot.
+#undef Sleep
+#endif // Sleep
+
+#include "gcinterface.h"
+#include "env/gcenv.os.h"
+#include "env/gcenv.ee.h"
+
+#ifdef FEATURE_STANDALONE_GC
+#include "gcenv.ee.standalone.inl"
+#endif // FEATURE_STANDALONE_GC
/*
* Promotion Function Prototypes
@@ -26,19 +41,6 @@ typedef void enum_func (Object*);
// callback functions for heap walkers
typedef void object_callback_func(void * pvContext, void * pvDataLoc);
-// stub type to abstract a heap segment
-struct gc_heap_segment_stub;
-typedef gc_heap_segment_stub *segment_handle;
-
-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 ibReserved; // limit of reserved memory in the segment (>= commit)
-};
-
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
/* If you modify failure_get_memory and */
/* oom_reason be sure to make the corresponding */
@@ -80,6 +82,24 @@ enum oom_reason
oom_unproductive_full_gc = 6
};
+// TODO : it would be easier to make this an ORed value
+enum gc_reason
+{
+ reason_alloc_soh = 0,
+ reason_induced = 1,
+ reason_lowmemory = 2,
+ reason_empty = 3,
+ reason_alloc_loh = 4,
+ reason_oos_soh = 5,
+ reason_oos_loh = 6,
+ reason_induced_noforce = 7, // it's an induced GC and doesn't have to be blocking.
+ reason_gcstress = 8, // this turns into reason_induced & gc_mechanisms.stress_induced = true
+ reason_lowmemory_blocking = 9,
+ reason_induced_compacting = 10,
+ reason_lowmemory_host = 11,
+ reason_max
+};
+
struct oom_history
{
oom_reason reason;
@@ -97,28 +117,16 @@ struct oom_history
class CObjectHeader;
class Object;
-class GCHeap;
+class IGCHeapInternal;
/* misc defines */
#define LARGE_OBJECT_SIZE ((size_t)(85000))
-GPTR_DECL(GCHeap, g_pGCHeap);
-
#ifdef GC_CONFIG_DRIVEN
#define MAX_GLOBAL_GC_MECHANISMS_COUNT 6
GARY_DECL(size_t, gc_global_mechanisms, MAX_GLOBAL_GC_MECHANISMS_COUNT);
#endif //GC_CONFIG_DRIVEN
-#ifndef DACCESS_COMPILE
-extern "C" {
-#endif
-GPTR_DECL(uint8_t,g_lowest_address);
-GPTR_DECL(uint8_t,g_highest_address);
-GPTR_DECL(uint32_t,g_card_table);
-#ifndef DACCESS_COMPILE
-}
-#endif
-
#ifdef DACCESS_COMPILE
class DacHeapWalker;
#endif
@@ -127,137 +135,28 @@ class DacHeapWalker;
#define _LOGALLOC
#endif
-#ifdef WRITE_BARRIER_CHECK
-//always defined, but should be 0 in Server GC
-extern uint8_t* g_GCShadow;
-extern uint8_t* g_GCShadowEnd;
-// saves the g_lowest_address in between GCs to verify the consistency of the shadow segment
-extern uint8_t* g_shadow_lowest_address;
-#endif
-
#define MP_LOCKS
-extern "C" uint8_t* g_ephemeral_low;
-extern "C" uint8_t* g_ephemeral_high;
+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" uint8_t* g_gc_ephemeral_low;
+extern "C" uint8_t* g_gc_ephemeral_high;
namespace WKS {
- ::GCHeap* CreateGCHeap();
+ ::IGCHeapInternal* CreateGCHeap();
class GCHeap;
class gc_heap;
}
#if defined(FEATURE_SVR_GC)
namespace SVR {
- ::GCHeap* CreateGCHeap();
+ ::IGCHeapInternal* CreateGCHeap();
class GCHeap;
class gc_heap;
}
#endif // defined(FEATURE_SVR_GC)
-/*
- * Ephemeral Garbage Collected Heap Interface
- */
-
-
-struct alloc_context
-{
- friend class WKS::gc_heap;
-#if defined(FEATURE_SVR_GC)
- friend class SVR::gc_heap;
- friend class SVR::GCHeap;
-#endif // defined(FEATURE_SVR_GC)
- friend struct ClassDumpInfo;
-
- uint8_t* alloc_ptr;
- uint8_t* alloc_limit;
- int64_t alloc_bytes; //Number of bytes allocated on SOH by this context
- int64_t alloc_bytes_loh; //Number of bytes allocated on LOH by this context
-#if defined(FEATURE_SVR_GC)
- SVR::GCHeap* alloc_heap;
- SVR::GCHeap* home_heap;
-#endif // defined(FEATURE_SVR_GC)
- int alloc_count;
-public:
-
- void init()
- {
- LIMITED_METHOD_CONTRACT;
-
- alloc_ptr = 0;
- alloc_limit = 0;
- alloc_bytes = 0;
- alloc_bytes_loh = 0;
-#if defined(FEATURE_SVR_GC)
- alloc_heap = 0;
- home_heap = 0;
-#endif // defined(FEATURE_SVR_GC)
- alloc_count = 0;
- }
-};
-
-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
-#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
-
-#ifndef FEATURE_REDHAWK
-#if defined(GC_PROFILING) || defined (DACCESS_COMPILE)
- MethodDesc *pMD;
-#endif //GC_PROFILING || DACCESS_COMPILE
-#endif // FEATURE_REDHAWK
-#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
- EtwGCRootKind dwEtwRootKind;
-#endif // GC_PROFILING || FEATURE_EVENT_TRACE
-
- ScanContext()
- {
- LIMITED_METHOD_CONTRACT;
-
- thread_under_crawl = 0;
- thread_number = -1;
- stack_limit = 0;
- promotion = FALSE;
- concurrent = FALSE;
-#ifdef GC_PROFILING
- pMD = NULL;
-#endif //GC_PROFILING
-#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
- dwEtwRootKind = kEtwGCRootKindOther;
-#endif // GC_PROFILING || FEATURE_EVENT_TRACE
- }
-};
-
-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);
-
-#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
-struct ProfilingScanContext : ScanContext
-{
- BOOL fProfilerPinned;
- void * pvEtwContext;
- void *pHeapId;
-
- ProfilingScanContext(BOOL fProfilerPinnedParam) : ScanContext()
- {
- LIMITED_METHOD_CONTRACT;
-
- pHeapId = NULL;
- fProfilerPinned = fProfilerPinnedParam;
- pvEtwContext = NULL;
-#ifdef FEATURE_CONSERVATIVE_GC
- // To not confuse GCScan::GcScanRoots
- promotion = g_pConfig->GetGCConservative();
-#endif
- }
-};
-#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
-
#ifdef STRESS_HEAP
#define IN_STRESS_HEAP(x) x
#define STRESS_HEAP_ARG(x) ,x
@@ -266,7 +165,6 @@ struct ProfilingScanContext : ScanContext
#define STRESS_HEAP_ARG(x)
#endif // STRESS_HEAP
-
//dynamic data interface
struct gc_counters
{
@@ -275,51 +173,6 @@ struct gc_counters
size_t collection_count;
};
-// !!!!!!!!!!!!!!!!!!!!!!!
-// make sure you change the def in bcl\system\gc.cs
-// if you change this!
-enum collection_mode
-{
- collection_non_blocking = 0x00000001,
- collection_blocking = 0x00000002,
- collection_optimized = 0x00000004,
- collection_compacting = 0x00000008
-#ifdef STRESS_HEAP
- , collection_gcstress = 0x80000000
-#endif // STRESS_HEAP
-};
-
-// !!!!!!!!!!!!!!!!!!!!!!!
-// make sure you change the def in bcl\system\gc.cs
-// if you change this!
-enum wait_full_gc_status
-{
- wait_full_gc_success = 0,
- wait_full_gc_failed = 1,
- wait_full_gc_cancelled = 2,
- wait_full_gc_timeout = 3,
- wait_full_gc_na = 4
-};
-
-// !!!!!!!!!!!!!!!!!!!!!!!
-// make sure you change the def in bcl\system\gc.cs
-// if you change this!
-enum start_no_gc_region_status
-{
- start_no_gc_success = 0,
- start_no_gc_no_memory = 1,
- start_no_gc_too_large = 2,
- start_no_gc_in_progress = 3
-};
-
-enum end_no_gc_region_status
-{
- end_no_gc_success = 0,
- end_no_gc_not_in_progress = 1,
- end_no_gc_induced = 2,
- end_no_gc_alloc_exceeded = 3
-};
-
enum bgc_state
{
bgc_not_in_process = 0,
@@ -352,321 +205,82 @@ void record_changed_seg (uint8_t* start, uint8_t* end,
void record_global_mechanism (int mech_index);
#endif //GC_CONFIG_DRIVEN
-//constants for the flags parameter to the gc call back
-
-#define GC_CALL_INTERIOR 0x1
-#define GC_CALL_PINNED 0x2
-#define GC_CALL_CHECK_APP_DOMAIN 0x4
-
-//flags for GCHeap::Alloc(...)
-#define GC_ALLOC_FINALIZE 0x1
-#define GC_ALLOC_CONTAINS_REF 0x2
-#define GC_ALLOC_ALIGN8_BIAS 0x4
-#define GC_ALLOC_ALIGN8 0x8
-
-class GCHeap {
- friend struct ::_DacGlobals;
-#ifdef DACCESS_COMPILE
- friend class ClrDataAccess;
-#endif
-
-public:
-
- virtual ~GCHeap() {}
-
- static GCHeap *GetGCHeap()
+struct alloc_context : gc_alloc_context
+{
+#ifdef FEATURE_SVR_GC
+ inline SVR::GCHeap* get_alloc_heap()
{
- LIMITED_METHOD_CONTRACT;
-
- _ASSERTE(g_pGCHeap != NULL);
- return g_pGCHeap;
+ return static_cast<SVR::GCHeap*>(gc_reserved_1);
}
-#ifndef DACCESS_COMPILE
- static BOOL IsGCInProgress(BOOL bConsiderGCStart = FALSE)
+ inline void set_alloc_heap(SVR::GCHeap* heap)
{
- WRAPPER_NO_CONTRACT;
-
- return (IsGCHeapInitialized() ? GetGCHeap()->IsGCInProgressHelper(bConsiderGCStart) : false);
- }
-#endif
-
- static BOOL IsGCHeapInitialized()
- {
- LIMITED_METHOD_CONTRACT;
-
- return (g_pGCHeap != NULL);
+ gc_reserved_1 = heap;
}
- static void WaitForGCCompletion(BOOL bConsiderGCStart = FALSE)
+ inline SVR::GCHeap* get_home_heap()
{
- WRAPPER_NO_CONTRACT;
-
- if (IsGCHeapInitialized())
- GetGCHeap()->WaitUntilGCComplete(bConsiderGCStart);
- }
-
- // The runtime needs to know whether we're using workstation or server GC
- // long before the GCHeap is created. So IsServerHeap cannot be a virtual
- // method on GCHeap. Instead we make it a static method and initialize
- // gcHeapType before any of the calls to IsServerHeap. Note that this also
- // has the advantage of getting the answer without an indirection
- // (virtual call), which is important for perf critical codepaths.
-
- #ifndef DACCESS_COMPILE
- static void InitializeHeapType(bool bServerHeap)
- {
- LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_SVR_GC
- gcHeapType = bServerHeap ? GC_HEAP_SVR : GC_HEAP_WKS;
-#ifdef WRITE_BARRIER_CHECK
- if (gcHeapType == GC_HEAP_SVR)
- {
- g_GCShadow = 0;
- g_GCShadowEnd = 0;
- }
-#endif
-#else // FEATURE_SVR_GC
- UNREFERENCED_PARAMETER(bServerHeap);
- CONSISTENCY_CHECK(bServerHeap == false);
-#endif // FEATURE_SVR_GC
- }
- #endif
-
- static BOOL IsValidSegmentSize(size_t cbSize)
- {
- //Must be aligned on a Mb and greater than 4Mb
- return (((cbSize & (1024*1024-1)) ==0) && (cbSize >> 22));
+ return static_cast<SVR::GCHeap*>(gc_reserved_2);
}
- static BOOL IsValidGen0MaxSize(size_t cbSize)
+ inline void set_home_heap(SVR::GCHeap* heap)
{
- return (cbSize >= 64*1024);
+ gc_reserved_2 = heap;
}
-
- inline static bool IsServerHeap()
- {
- LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_SVR_GC
- _ASSERTE(gcHeapType != GC_HEAP_INVALID);
- return (gcHeapType == GC_HEAP_SVR);
-#else // FEATURE_SVR_GC
- return false;
#endif // FEATURE_SVR_GC
- }
+};
- 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)));
+class IGCHeapInternal : public IGCHeap {
+ friend struct ::_DacGlobals;
+#ifdef DACCESS_COMPILE
+ friend class ClrDataAccess;
#endif
-#endif
- }
-
- inline static bool MarkShouldCompeteForStatics()
- {
- WRAPPER_NO_CONTRACT;
-
- return IsServerHeap() && g_SystemInfo.dwNumberOfProcessors >= 2;
- }
-#ifndef DACCESS_COMPILE
- static GCHeap * CreateGCHeap()
- {
- WRAPPER_NO_CONTRACT;
-
- GCHeap * pGCHeap;
-
-#if defined(FEATURE_SVR_GC)
- pGCHeap = (IsServerHeap() ? SVR::CreateGCHeap() : WKS::CreateGCHeap());
-#else
- pGCHeap = WKS::CreateGCHeap();
-#endif // defined(FEATURE_SVR_GC)
-
- g_pGCHeap = pGCHeap;
- return pGCHeap;
- }
-#endif // DACCESS_COMPILE
+public:
-private:
- 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 // FEATURE_SVR_GC
+ virtual ~IGCHeapInternal() {}
-public:
- // TODO Synchronization, should be moved out
- virtual BOOL IsGCInProgressHelper (BOOL bConsiderGCStart = FALSE) = 0;
- virtual uint32_t WaitUntilGCComplete (BOOL bConsiderGCStart = FALSE) = 0;
- virtual void SetGCInProgress(BOOL fInProgress) = 0;
- virtual CLREventStatic * GetWaitForGCEvent() = 0;
-
- virtual void SetFinalizationRun (Object* obj) = 0;
- virtual Object* GetNextFinalizable() = 0;
- virtual size_t GetNumberOfFinalizable() = 0;
-
- virtual void SetFinalizeQueueForShutdown(BOOL fHasLock) = 0;
- virtual BOOL FinalizeAppDomain(AppDomain *pDomain, BOOL fRunFinalizers) = 0;
- virtual BOOL ShouldRestartFinalizerWatchDog() = 0;
-
- //wait for concurrent GC to finish
- virtual void WaitUntilConcurrentGCComplete () = 0; // Use in managed threads
-#ifndef DACCESS_COMPILE
- virtual HRESULT WaitUntilConcurrentGCCompleteAsync(int millisecondsTimeout) = 0; // Use in native threads. TRUE if succeed. FALSE if failed or timeout
-#endif
- virtual BOOL IsConcurrentGCInProgress() = 0;
-
- // Enable/disable concurrent GC
- virtual void TemporaryEnableConcurrentGC() = 0;
- virtual void TemporaryDisableConcurrentGC() = 0;
- virtual BOOL IsConcurrentGCEnabled() = 0;
-
- virtual void FixAllocContext (alloc_context* acontext, BOOL lockp, void* arg, void *heap) = 0;
- virtual Object* Alloc (alloc_context* acontext, size_t size, uint32_t flags) = 0;
-
- // This is safe to call only when EE is suspended.
- virtual Object* GetContainingObject(void *pInteriorPtr) = 0;
-
- // TODO Should be folded into constructor
- virtual HRESULT Initialize () = 0;
-
- virtual HRESULT GarbageCollect (int generation = -1, BOOL low_memory_p=FALSE, int mode = collection_blocking) = 0;
- virtual Object* Alloc (size_t size, uint32_t flags) = 0;
-#ifdef FEATURE_64BIT_ALIGNMENT
- virtual Object* AllocAlign8 (size_t size, uint32_t flags) = 0;
- virtual Object* AllocAlign8 (alloc_context* acontext, size_t size, uint32_t flags) = 0;
private:
- virtual Object* AllocAlign8Common (void* hp, alloc_context* acontext, size_t size, uint32_t flags) = 0;
+ virtual Object* AllocAlign8Common (void* hp, alloc_context* acontext, size_t size, uint32_t flags) = 0;
public:
-#endif // FEATURE_64BIT_ALIGNMENT
- virtual Object* AllocLHeap (size_t size, uint32_t flags) = 0;
- virtual void SetReservedVMLimit (size_t vmlimit) = 0;
- virtual void SetCardsAfterBulkCopy( Object**, size_t ) = 0;
-#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
- virtual void WalkObject (Object* obj, walk_fn fn, void* context) = 0;
-#endif //defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
-
- virtual bool IsThreadUsingAllocationContextHeap(alloc_context* acontext, int thread_number) = 0;
virtual int GetNumberOfHeaps () = 0;
virtual int GetHomeHeapNumber () = 0;
-
- virtual int CollectionCount (int generation, int get_bgc_fgc_count = 0) = 0;
-
- // Finalizer queue stuff (should stay)
- virtual bool RegisterForFinalization (int gen, Object* obj) = 0;
-
- // General queries to the GC
- virtual BOOL IsPromoted (Object *object) = 0;
- virtual unsigned WhichGeneration (Object* object) = 0;
- virtual BOOL IsEphemeral (Object* object) = 0;
- virtual BOOL IsHeapPointer (void* object, BOOL small_heap_only = FALSE) = 0;
-
- virtual unsigned GetCondemnedGeneration() = 0;
- virtual int GetGcLatencyMode() = 0;
- virtual int SetGcLatencyMode(int newLatencyMode) = 0;
-
- virtual int GetLOHCompactionMode() = 0;
- virtual void SetLOHCompactionMode(int newLOHCompactionyMode) = 0;
-
- virtual BOOL RegisterForFullGCNotification(uint32_t gen2Percentage,
- uint32_t lohPercentage) = 0;
- virtual BOOL CancelFullGCNotification() = 0;
- virtual int WaitForFullGCApproach(int millisecondsTimeout) = 0;
- virtual int WaitForFullGCComplete(int millisecondsTimeout) = 0;
-
- virtual int StartNoGCRegion(uint64_t totalSize, BOOL lohSizeKnown, uint64_t lohSize, BOOL disallowFullBlockingGC) = 0;
- virtual int EndNoGCRegion() = 0;
+ virtual size_t GetPromotedBytes(int heap_index) = 0;
- virtual BOOL IsObjectInFixedHeap(Object *pObj) = 0;
- virtual size_t GetTotalBytesInUse () = 0;
- virtual size_t GetCurrentObjSize() = 0;
- virtual size_t GetLastGCStartTime(int generation) = 0;
- virtual size_t GetLastGCDuration(int generation) = 0;
- virtual size_t GetNow() = 0;
- virtual unsigned GetGcCount() = 0;
- virtual void TraceGCSegments() = 0;
+ unsigned GetMaxGeneration()
+ {
+ return IGCHeap::maxGeneration;
+ }
- virtual void PublishObject(uint8_t* obj) = 0;
+ BOOL IsValidSegmentSize(size_t cbSize)
+ {
+ //Must be aligned on a Mb and greater than 4Mb
+ return (((cbSize & (1024*1024-1)) ==0) && (cbSize >> 22));
+ }
- // static if since restricting for all heaps is fine
- virtual size_t GetValidSegmentSize(BOOL large_seg = FALSE) = 0;
+ BOOL IsValidGen0MaxSize(size_t cbSize)
+ {
+ return (cbSize >= 64*1024);
+ }
- static BOOL IsLargeObject(MethodTable *mt) {
+ BOOL IsLargeObject(MethodTable *mt)
+ {
WRAPPER_NO_CONTRACT;
return mt->GetBaseSize() >= LARGE_OBJECT_SIZE;
}
- static unsigned GetMaxGeneration() {
- LIMITED_METHOD_DAC_CONTRACT;
- return max_generation;
- }
-
- virtual size_t GetPromotedBytes(int heap_index) = 0;
-
-private:
- enum {
- max_generation = 2,
- };
-
-public:
-
-#ifdef FEATURE_BASICFREEZE
- // frozen segment management functions
- virtual segment_handle RegisterFrozenSegment(segment_info *pseginfo) = 0;
- virtual void UnregisterFrozenSegment(segment_handle seg) = 0;
-#endif //FEATURE_BASICFREEZE
-
- // debug support
-#ifndef FEATURE_REDHAWK // Redhawk forces relocation a different way
-#ifdef STRESS_HEAP
- //return TRUE if GC actually happens, otherwise FALSE
- virtual BOOL StressHeap(alloc_context * acontext = 0) = 0;
-#endif
-#endif // FEATURE_REDHAWK
-#ifdef VERIFY_HEAP
- virtual void ValidateObjectMember (Object *obj) = 0;
-#endif
-
-#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
- virtual void DescrGenerationsToProfiler (gen_walk_fn fn, void *context) = 0;
-#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
-
protected:
-#ifdef VERIFY_HEAP
public:
- // Return NULL if can't find next object. When EE is not suspended,
- // the result is not accurate: if the input arg is in gen0, the function could
- // return zeroed out memory as next object
- virtual Object * NextObj (Object * object) = 0;
-#ifdef FEATURE_BASICFREEZE
+#if defined(FEATURE_BASICFREEZE) && defined(VERIFY_HEAP)
// Return TRUE if object lives in frozen segment
virtual BOOL IsInFrozenSegment (Object * object) = 0;
-#endif //FEATURE_BASICFREEZE
-#endif //VERIFY_HEAP
+#endif // defined(FEATURE_BASICFREEZE) && defined(VERIFY_HEAP)
};
-extern VOLATILE(int32_t) m_GCLock;
-
// Go through and touch (read) each page straddled by a memory block.
void TouchPages(void * pStart, size_t cb);
-// For low memory notification from host
-extern int32_t g_bLowMemoryFromHost;
-
#ifdef WRITE_BARRIER_CHECK
void updateGCShadow(Object** ptr, Object* val);
#endif
@@ -677,4 +291,27 @@ extern MethodTable *pWeakReferenceMT;
extern MethodTable *pWeakReferenceOfTCanonMT;
extern void FinalizeWeakReference(Object * obj);
+// The single GC heap instance, shared with the VM.
+extern IGCHeapInternal* g_theGCHeap;
+
+#ifndef DACCESS_COMPILE
+inline BOOL IsGCInProgress(bool bConsiderGCStart = FALSE)
+{
+ WRAPPER_NO_CONTRACT;
+
+ return g_theGCHeap != nullptr ? g_theGCHeap->IsGCInProgressHelper(bConsiderGCStart) : false;
+}
+#endif // DACCESS_COMPILE
+
+inline 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
+ return false;
+#endif // FEATURE_SVR_GC
+}
+
#endif // __GC_H
diff --git a/src/gc/gccommon.cpp b/src/gc/gccommon.cpp
index 779aac7296..d1ccddd205 100644
--- a/src/gc/gccommon.cpp
+++ b/src/gc/gccommon.cpp
@@ -15,17 +15,16 @@
#include "gc.h"
#ifdef FEATURE_SVR_GC
-SVAL_IMPL_INIT(uint32_t,GCHeap,gcHeapType,GCHeap::GC_HEAP_INVALID);
+SVAL_IMPL_INIT(uint32_t,IGCHeap,gcHeapType,IGCHeap::GC_HEAP_INVALID);
#endif // FEATURE_SVR_GC
-GPTR_IMPL(GCHeap,g_pGCHeap);
+SVAL_IMPL_INIT(uint32_t,IGCHeap,maxGeneration,2);
-/* global versions of the card table and brick table */
-GPTR_IMPL(uint32_t,g_card_table);
+IGCHeapInternal* g_theGCHeap;
-/* absolute bounds of the GC memory */
-GPTR_IMPL_INIT(uint8_t,g_lowest_address,0);
-GPTR_IMPL_INIT(uint8_t,g_highest_address,0);
+#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);
@@ -33,15 +32,18 @@ GARY_IMPL(size_t, gc_global_mechanisms, MAX_GLOBAL_GC_MECHANISMS_COUNT);
#ifndef DACCESS_COMPILE
-uint8_t* g_ephemeral_low = (uint8_t*)1;
-uint8_t* g_ephemeral_high = (uint8_t*)~0;
-
#ifdef WRITE_BARRIER_CHECK
uint8_t* g_GCShadow;
uint8_t* g_GCShadowEnd;
uint8_t* g_shadow_lowest_address = NULL;
#endif
+uint32_t* g_gc_card_table;
+uint8_t* g_gc_lowest_address = 0;
+uint8_t* g_gc_highest_address = 0;
+uint8_t* g_gc_ephemeral_low = (uint8_t*)1;
+uint8_t* g_gc_ephemeral_high = (uint8_t*)~0;
+
VOLATILE(int32_t) m_GCLock = -1;
#ifdef GC_CONFIG_DRIVEN
@@ -112,4 +114,49 @@ void record_changed_seg (uint8_t* start, uint8_t* end,
}
}
+// The runtime needs to know whether we're using workstation or server GC
+// long before the GCHeap is created.
+void InitializeHeapType(bool bServerHeap)
+{
+ LIMITED_METHOD_CONTRACT;
+#ifdef FEATURE_SVR_GC
+ IGCHeap::gcHeapType = bServerHeap ? IGCHeap::GC_HEAP_SVR : IGCHeap::GC_HEAP_WKS;
+#ifdef WRITE_BARRIER_CHECK
+ if (IGCHeap::gcHeapType == IGCHeap::GC_HEAP_SVR)
+ {
+ g_GCShadow = 0;
+ g_GCShadowEnd = 0;
+ }
+#endif // WRITE_BARRIER_CHECK
+#else // FEATURE_SVR_GC
+ UNREFERENCED_PARAMETER(bServerHeap);
+ CONSISTENCY_CHECK(bServerHeap == false);
+#endif // FEATURE_SVR_GC
+}
+
+IGCHeap* InitializeGarbageCollector(IGCToCLR* clrToGC)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ IGCHeapInternal* heap;
+#ifdef FEATURE_SVR_GC
+ assert(IGCHeap::gcHeapType != IGCHeap::GC_HEAP_INVALID);
+ heap = IGCHeap::gcHeapType == IGCHeap::GC_HEAP_SVR ? SVR::CreateGCHeap() : WKS::CreateGCHeap();
+#else
+ heap = WKS::CreateGCHeap();
+#endif
+
+ g_theGCHeap = heap;
+
+#ifdef FEATURE_STANDALONE_GC
+ assert(clrToGC != nullptr);
+ g_theGCToCLR = clrToGC;
+#else
+ UNREFERENCED_PARAMETER(clrToGC);
+ assert(clrToGC == nullptr);
+#endif
+
+ return heap;
+}
+
#endif // !DACCESS_COMPILE
diff --git a/src/gc/gcee.cpp b/src/gc/gcee.cpp
index d37eaf4de9..c93cc91b57 100644
--- a/src/gc/gcee.cpp
+++ b/src/gc/gcee.cpp
@@ -148,7 +148,7 @@ void GCHeap::UpdatePostGCCounters()
// if a max gen garbage collection was performed, resync the GC Handle counter;
// if threads are currently suspended, we do not need to obtain a lock on each handle table
if (condemned_gen == max_generation)
- total_num_gc_handles = HndCountAllHandles(!GCHeap::IsGCInProgress());
+ total_num_gc_handles = HndCountAllHandles(!IsGCInProgress());
#endif //FEATURE_REDHAWK
// per generation calculation.
@@ -381,209 +381,6 @@ size_t GCHeap::GetNow()
return GetHighPrecisionTimeStamp();
}
-void ProfScanRootsHelper(Object** ppObject, ScanContext *pSC, uint32_t dwFlags)
-{
-#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
- Object *pObj = *ppObject;
-#ifdef INTERIOR_POINTERS
- if (dwFlags & GC_CALL_INTERIOR)
- {
- uint8_t *o = (uint8_t*)pObj;
- gc_heap* hp = gc_heap::heap_of (o);
-
- if ((o < hp->gc_low) || (o >= hp->gc_high))
- {
- return;
- }
- pObj = (Object*) hp->find_object(o, hp->gc_low);
- }
-#endif //INTERIOR_POINTERS
- ScanRootsHelper(pObj, ppObject, pSC, dwFlags);
-#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
-}
-
-// TODO - at some point we would like to completely decouple profiling
-// from ETW tracing using a pattern similar to this, where the
-// ProfilingScanContext has flags about whether or not certain things
-// should be tracked, and each one of these ProfilerShouldXYZ functions
-// will check these flags and determine what to do based upon that.
-// GCProfileWalkHeapWorker can, in turn, call those methods without fear
-// of things being ifdef'd out.
-
-// Returns TRUE if GC profiling is enabled and the profiler
-// should scan dependent handles, FALSE otherwise.
-BOOL ProfilerShouldTrackConditionalWeakTableElements()
-{
-#if defined(GC_PROFILING)
- return CORProfilerTrackConditionalWeakTableElements();
-#else
- return FALSE;
-#endif // defined (GC_PROFILING)
-}
-
-// If GC profiling is enabled, informs the profiler that we are done
-// tracing dependent handles.
-void ProfilerEndConditionalWeakTableElementReferences(void* heapId)
-{
-#if defined (GC_PROFILING)
- g_profControlBlock.pProfInterface->EndConditionalWeakTableElementReferences(heapId);
-#else
- UNREFERENCED_PARAMETER(heapId);
-#endif // defined (GC_PROFILING)
-}
-
-// If GC profiling is enabled, informs the profiler that we are done
-// tracing root references.
-void ProfilerEndRootReferences2(void* heapId)
-{
-#if defined (GC_PROFILING)
- g_profControlBlock.pProfInterface->EndRootReferences2(heapId);
-#else
- UNREFERENCED_PARAMETER(heapId);
-#endif // defined (GC_PROFILING)
-}
-
-// This is called only if we've determined that either:
-// a) The Profiling API wants to do a walk of the heap, and it has pinned the
-// profiler in place (so it cannot be detached), and it's thus safe to call into the
-// profiler, OR
-// b) ETW infrastructure wants to do a walk of the heap either to log roots,
-// objects, or both.
-// This can also be called to do a single walk for BOTH a) and b) simultaneously. Since
-// ETW can ask for roots, but not objects
-#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
-
-void GCProfileWalkHeapWorker(BOOL fProfilerPinned, BOOL fShouldWalkHeapRootsForEtw, BOOL fShouldWalkHeapObjectsForEtw)
-{
- {
- ProfilingScanContext SC(fProfilerPinned);
-
- // **** Scan roots: Only scan roots if profiling API wants them or ETW wants them.
- if (fProfilerPinned || fShouldWalkHeapRootsForEtw)
- {
-#ifdef MULTIPLE_HEAPS
- int hn;
-
- // Must emulate each GC thread number so we can hit each
- // heap for enumerating the roots.
- for (hn = 0; hn < gc_heap::n_heaps; hn++)
- {
- // Ask the vm to go over all of the roots for this specific
- // heap.
- gc_heap* hp = gc_heap::g_heaps [hn];
- SC.thread_number = hn;
- GCScan::GcScanRoots(&ProfScanRootsHelper, max_generation, max_generation, &SC);
-
- // The finalizer queue is also a source of roots
- SC.dwEtwRootKind = kEtwGCRootKindFinalizer;
- hp->finalize_queue->GcScanRoots(&ProfScanRootsHelper, hn, &SC);
- }
-#else
- // Ask the vm to go over all of the roots
- GCScan::GcScanRoots(&ProfScanRootsHelper, max_generation, max_generation, &SC);
-
- // The finalizer queue is also a source of roots
- SC.dwEtwRootKind = kEtwGCRootKindFinalizer;
- pGenGCHeap->finalize_queue->GcScanRoots(&ProfScanRootsHelper, 0, &SC);
-
-#endif // MULTIPLE_HEAPS
- // Handles are kept independent of wks/svr/concurrent builds
- SC.dwEtwRootKind = kEtwGCRootKindHandle;
- GCScan::GcScanHandlesForProfilerAndETW(max_generation, &SC);
-
- // indicate that regular handle scanning is over, so we can flush the buffered roots
- // to the profiler. (This is for profapi only. ETW will flush after the
- // entire heap was is complete, via ETW::GCLog::EndHeapDump.)
- if (fProfilerPinned)
- {
- ProfilerEndRootReferences2(&SC.pHeapId);
- }
- }
-
- // **** Scan dependent handles: only if the profiler supports it or ETW wants roots
- if ((fProfilerPinned && ProfilerShouldTrackConditionalWeakTableElements()) ||
- fShouldWalkHeapRootsForEtw)
- {
- // GcScanDependentHandlesForProfiler double-checks
- // CORProfilerTrackConditionalWeakTableElements() before calling into the profiler
-
- GCScan::GcScanDependentHandlesForProfilerAndETW(max_generation, &SC);
-
- // indicate that dependent handle scanning is over, so we can flush the buffered roots
- // to the profiler. (This is for profapi only. ETW will flush after the
- // entire heap was is complete, via ETW::GCLog::EndHeapDump.)
- if (fProfilerPinned && ProfilerShouldTrackConditionalWeakTableElements())
- {
- ProfilerEndConditionalWeakTableElementReferences(&SC.pHeapId);
- }
- }
-
- ProfilerWalkHeapContext profilerWalkHeapContext(fProfilerPinned, SC.pvEtwContext);
-
- // **** Walk objects on heap: only if profiling API wants them or ETW wants them.
- if (fProfilerPinned || fShouldWalkHeapObjectsForEtw)
- {
-#ifdef MULTIPLE_HEAPS
- int hn;
-
- // Walk the heap and provide the objref to the profiler
- for (hn = 0; hn < gc_heap::n_heaps; hn++)
- {
- gc_heap* hp = gc_heap::g_heaps [hn];
- hp->walk_heap(&HeapWalkHelper, &profilerWalkHeapContext, max_generation, TRUE /* walk the large object heap */);
- }
-#else
- gc_heap::walk_heap(&HeapWalkHelper, &profilerWalkHeapContext, max_generation, TRUE);
-#endif //MULTIPLE_HEAPS
- }
-
-#ifdef FEATURE_EVENT_TRACE
- // **** Done! Indicate to ETW helpers that the heap walk is done, so any buffers
- // should be flushed into the ETW stream
- if (fShouldWalkHeapObjectsForEtw || fShouldWalkHeapRootsForEtw)
- {
- ETW::GCLog::EndHeapDump(&profilerWalkHeapContext);
- }
-#endif // FEATURE_EVENT_TRACE
- }
-}
-#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
-
-void GCProfileWalkHeap()
-{
- BOOL fWalkedHeapForProfiler = FALSE;
-
-#ifdef FEATURE_EVENT_TRACE
- if (ETW::GCLog::ShouldWalkStaticsAndCOMForEtw())
- ETW::GCLog::WalkStaticsAndCOMForETW();
-
- BOOL fShouldWalkHeapRootsForEtw = ETW::GCLog::ShouldWalkHeapRootsForEtw();
- BOOL fShouldWalkHeapObjectsForEtw = ETW::GCLog::ShouldWalkHeapObjectsForEtw();
-#else // !FEATURE_EVENT_TRACE
- BOOL fShouldWalkHeapRootsForEtw = FALSE;
- BOOL fShouldWalkHeapObjectsForEtw = FALSE;
-#endif // FEATURE_EVENT_TRACE
-
-#if defined (GC_PROFILING)
- {
- BEGIN_PIN_PROFILER(CORProfilerTrackGC());
- GCProfileWalkHeapWorker(TRUE /* fProfilerPinned */, fShouldWalkHeapRootsForEtw, fShouldWalkHeapObjectsForEtw);
- fWalkedHeapForProfiler = TRUE;
- END_PIN_PROFILER();
- }
-#endif // defined (GC_PROFILING)
-
-#if defined (GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
- // we need to walk the heap if one of GC_PROFILING or FEATURE_EVENT_TRACE
- // is defined, since both of them make use of the walk heap worker.
- if (!fWalkedHeapForProfiler &&
- (fShouldWalkHeapRootsForEtw || fShouldWalkHeapObjectsForEtw))
- {
- GCProfileWalkHeapWorker(FALSE /* fProfilerPinned */, fShouldWalkHeapRootsForEtw, fShouldWalkHeapObjectsForEtw);
- }
-#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
-}
-
BOOL GCHeap::IsGCInProgressHelper (BOOL bConsiderGCStart)
{
return GcInProgress || (bConsiderGCStart? VolatileLoad(&gc_heap::gc_started) : FALSE);
@@ -782,11 +579,11 @@ void gc_heap::background_gc_wait_lh (alloc_wait_reason awr)
/******************************************************************************/
-::GCHeap* CreateGCHeap() {
+IGCHeapInternal* CreateGCHeap() {
return new(nothrow) GCHeap(); // we return wks or svr
}
-void GCHeap::TraceGCSegments()
+void GCHeap::DiagTraceGCSegments()
{
#ifdef FEATURE_EVENT_TRACE
heap_segment* seg = 0;
@@ -823,16 +620,16 @@ void GCHeap::TraceGCSegments()
#endif // FEATURE_EVENT_TRACE
}
-#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
-void GCHeap::DescrGenerationsToProfiler (gen_walk_fn fn, void *context)
+void GCHeap::DiagDescrGenerations (gen_walk_fn fn, void *context)
{
+#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
pGenGCHeap->descr_generations_to_profiler(fn, context);
-}
#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+}
-#ifdef FEATURE_BASICFREEZE
segment_handle GCHeap::RegisterFrozenSegment(segment_info *pseginfo)
{
+#ifdef FEATURE_BASICFREEZE
heap_segment * seg = new (nothrow) heap_segment;
if (!seg)
{
@@ -863,10 +660,15 @@ segment_handle GCHeap::RegisterFrozenSegment(segment_info *pseginfo)
}
return reinterpret_cast< segment_handle >(seg);
+#else
+ assert(!"Should not call GCHeap::RegisterFrozenSegment without FEATURE_BASICFREEZE defined!");
+ return NULL;
+#endif // FEATURE_BASICFREEZE
}
void GCHeap::UnregisterFrozenSegment(segment_handle seg)
{
+#ifdef FEATURE_BASICFREEZE
#if defined (MULTIPLE_HEAPS) && !defined (ISOLATED_HEAPS)
gc_heap* heap = gc_heap::g_heaps[0];
#else
@@ -874,8 +676,10 @@ void GCHeap::UnregisterFrozenSegment(segment_handle seg)
#endif //MULTIPLE_HEAPS && !ISOLATED_HEAPS
heap->remove_ro_segment(reinterpret_cast<heap_segment*>(seg));
-}
+#else
+ assert(!"Should not call GCHeap::UnregisterFrozenSegment without FEATURE_BASICFREEZE defined!");
#endif // FEATURE_BASICFREEZE
+}
#endif // !DACCESS_COMPILE
diff --git a/src/gc/gcenv.ee.standalone.inl b/src/gc/gcenv.ee.standalone.inl
new file mode 100644
index 0000000000..3b64586d70
--- /dev/null
+++ b/src/gc/gcenv.ee.standalone.inl
@@ -0,0 +1,176 @@
+// Licensed to the .NET Foundation under one or more 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 __GCTOENV_EE_STANDALONE_INL__
+#define __GCTOENV_EE_STANDALONE_INL__
+
+#include "env/gcenv.ee.h"
+
+// The singular interface instance. All calls in GCToEEInterface
+// will be fowarded to this interface instance.
+extern IGCToCLR* g_theGCToCLR;
+
+// When we are building the GC in a standalone environment, we
+// will be dispatching virtually against g_theGCToCLR to call
+// into the EE. This class provides an identical API to the existing
+// GCToEEInterface, but only forwards the call onto the global
+// g_theGCToCLR instance.
+inline void GCToEEInterface::SuspendEE(SUSPEND_REASON reason)
+{
+ assert(g_theGCToCLR != nullptr);
+ g_theGCToCLR->SuspendEE(reason);
+}
+
+inline void GCToEEInterface::RestartEE(bool bFinishedGC)
+{
+ assert(g_theGCToCLR != nullptr);
+ g_theGCToCLR->RestartEE(bFinishedGC);
+}
+
+inline void GCToEEInterface::GcScanRoots(promote_func* fn, int condemned, int max_gen, ScanContext* sc)
+{
+ assert(g_theGCToCLR != nullptr);
+ g_theGCToCLR->GcScanRoots(fn, condemned, max_gen, sc);
+}
+
+inline void GCToEEInterface::GcStartWork(int condemned, int max_gen)
+{
+ assert(g_theGCToCLR != nullptr);
+ g_theGCToCLR->GcStartWork(condemned, max_gen);
+}
+
+inline void GCToEEInterface::AfterGcScanRoots(int condemned, int max_gen, ScanContext* sc)
+{
+ assert(g_theGCToCLR != nullptr);
+ g_theGCToCLR->AfterGcScanRoots(condemned, max_gen, sc);
+}
+
+inline void GCToEEInterface::GcBeforeBGCSweepWork()
+{
+ assert(g_theGCToCLR != nullptr);
+ g_theGCToCLR->GcBeforeBGCSweepWork();
+}
+
+inline void GCToEEInterface::GcDone(int condemned)
+{
+ assert(g_theGCToCLR != nullptr);
+ g_theGCToCLR->GcDone(condemned);
+}
+
+inline bool GCToEEInterface::RefCountedHandleCallbacks(Object * pObject)
+{
+ assert(g_theGCToCLR != nullptr);
+ return g_theGCToCLR->RefCountedHandleCallbacks(pObject);
+}
+
+inline void GCToEEInterface::SyncBlockCacheWeakPtrScan(HANDLESCANPROC scanProc, uintptr_t lp1, uintptr_t lp2)
+{
+ assert(g_theGCToCLR != nullptr);
+ g_theGCToCLR->SyncBlockCacheWeakPtrScan(scanProc, lp1, lp2);
+}
+
+inline void GCToEEInterface::SyncBlockCacheDemote(int max_gen)
+{
+ assert(g_theGCToCLR != nullptr);
+ g_theGCToCLR->SyncBlockCacheDemote(max_gen);
+}
+
+inline void GCToEEInterface::SyncBlockCachePromotionsGranted(int max_gen)
+{
+ assert(g_theGCToCLR != nullptr);
+ g_theGCToCLR->SyncBlockCachePromotionsGranted(max_gen);
+}
+
+inline bool GCToEEInterface::IsPreemptiveGCDisabled(Thread * pThread)
+{
+ assert(g_theGCToCLR != nullptr);
+ return g_theGCToCLR->IsPreemptiveGCDisabled(pThread);
+}
+
+
+inline void GCToEEInterface::EnablePreemptiveGC(Thread * pThread)
+{
+ assert(g_theGCToCLR != nullptr);
+ g_theGCToCLR->EnablePreemptiveGC(pThread);
+}
+
+inline void GCToEEInterface::DisablePreemptiveGC(Thread * pThread)
+{
+ assert(g_theGCToCLR != nullptr);
+ g_theGCToCLR->DisablePreemptiveGC(pThread);
+}
+
+inline gc_alloc_context * GCToEEInterface::GetAllocContext(Thread * pThread)
+{
+ assert(g_theGCToCLR != nullptr);
+ return g_theGCToCLR->GetAllocContext(pThread);
+}
+
+inline bool GCToEEInterface::CatchAtSafePoint(Thread * pThread)
+{
+ assert(g_theGCToCLR != nullptr);
+ return g_theGCToCLR->CatchAtSafePoint(pThread);
+}
+
+inline void GCToEEInterface::GcEnumAllocContexts(enum_alloc_context_func* fn, void* param)
+{
+ assert(g_theGCToCLR != nullptr);
+ g_theGCToCLR->GcEnumAllocContexts(fn, param);
+}
+
+inline Thread* GCToEEInterface::CreateBackgroundThread(GCBackgroundThreadFunction threadStart, void* arg)
+{
+ assert(g_theGCToCLR != nullptr);
+ return g_theGCToCLR->CreateBackgroundThread(threadStart, arg);
+}
+
+inline void GCToEEInterface::DiagGCStart(int gen, bool isInduced)
+{
+ assert(g_theGCToCLR != nullptr);
+ g_theGCToCLR->DiagGCStart(gen, isInduced);
+}
+
+inline void GCToEEInterface::DiagUpdateGenerationBounds()
+{
+ assert(g_theGCToCLR != nullptr);
+ g_theGCToCLR->DiagUpdateGenerationBounds();
+}
+
+inline void GCToEEInterface::DiagGCEnd(size_t index, int gen, int reason, bool fConcurrent)
+{
+ assert(g_theGCToCLR != nullptr);
+ g_theGCToCLR->DiagGCEnd(index, gen, reason, fConcurrent);
+}
+
+inline void GCToEEInterface::DiagWalkFReachableObjects(void* gcContext)
+{
+ assert(g_theGCToCLR != nullptr);
+ g_theGCToCLR->DiagWalkFReachableObjects(gcContext);
+}
+
+inline void GCToEEInterface::DiagWalkSurvivors(void* gcContext)
+{
+ assert(g_theGCToCLR != nullptr);
+ g_theGCToCLR->DiagWalkSurvivors(gcContext);
+}
+
+inline void GCToEEInterface::DiagWalkLOHSurvivors(void* gcContext)
+{
+ assert(g_theGCToCLR != nullptr);
+ g_theGCToCLR->DiagWalkLOHSurvivors(gcContext);
+}
+
+inline void GCToEEInterface::DiagWalkBGCSurvivors(void* gcContext)
+{
+ assert(g_theGCToCLR != nullptr);
+ return g_theGCToCLR->DiagWalkBGCSurvivors(gcContext);
+}
+
+inline void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)
+{
+ assert(g_theGCToCLR != nullptr);
+ g_theGCToCLR->StompWriteBarrier(args);
+}
+
+#endif // __GCTOENV_EE_STANDALONE_INL__
diff --git a/src/gc/gcenv.unix.cpp b/src/gc/gcenv.unix.cpp
new file mode 100644
index 0000000000..0235952e28
--- /dev/null
+++ b/src/gc/gcenv.unix.cpp
@@ -0,0 +1,308 @@
+// Licensed to the .NET Foundation under one or more 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 "env/gcenv.structs.h"
+#include "env/gcenv.base.h"
+#include "env/gcenv.os.h"
+
+// Initialize the interface implementation
+// Return:
+// true if it has succeeded, false if it has failed
+bool GCToOSInterface::Initialize()
+{
+ throw nullptr;
+}
+
+// Shutdown the interface implementation
+void GCToOSInterface::Shutdown()
+{
+ throw nullptr;
+}
+
+// Get numeric id of the current thread if possible on the
+// current platform. It is indended for logging purposes only.
+// Return:
+// Numeric id of the current thread or 0 if the
+uint64_t GCToOSInterface::GetCurrentThreadIdForLogging()
+{
+ throw nullptr;
+}
+
+// Get id of the process
+uint32_t GCToOSInterface::GetCurrentProcessId()
+{
+ throw nullptr;
+}
+
+// Set ideal affinity for the current thread
+// Parameters:
+// affinity - ideal processor affinity for the thread
+// Return:
+// true if it has succeeded, false if it has failed
+bool GCToOSInterface::SetCurrentThreadIdealAffinity(GCThreadAffinity* affinity)
+{
+ throw nullptr;
+}
+
+// Get the number of the current processor
+uint32_t GCToOSInterface::GetCurrentProcessorNumber()
+{
+ throw nullptr;
+}
+
+// Check if the OS supports getting current processor number
+bool GCToOSInterface::CanGetCurrentProcessorNumber()
+{
+ throw nullptr;
+}
+
+// Flush write buffers of processors that are executing threads of the current process
+void GCToOSInterface::FlushProcessWriteBuffers()
+{
+ throw nullptr;
+}
+
+// Break into a debugger
+void GCToOSInterface::DebugBreak()
+{
+ throw nullptr;
+}
+
+// Get number of logical processors
+uint32_t GCToOSInterface::GetLogicalCpuCount()
+{
+ throw nullptr;
+}
+
+// Causes the calling thread to sleep for the specified number of milliseconds
+// Parameters:
+// sleepMSec - time to sleep before switching to another thread
+void GCToOSInterface::Sleep(uint32_t sleepMSec)
+{
+ throw nullptr;
+}
+
+// Causes the calling thread to yield execution to another thread that is ready to run on the current processor.
+// Parameters:
+// switchCount - number of times the YieldThread was called in a loop
+void GCToOSInterface::YieldThread(uint32_t switchCount)
+{
+ throw nullptr;
+}
+
+// Reserve virtual memory range.
+// Parameters:
+// size - size of the virtual memory range
+// alignment - requested memory alignment, 0 means no specific alignment requested
+// flags - flags to control special settings like write watching
+// Return:
+// Starting virtual address of the reserved range
+void* GCToOSInterface::VirtualReserve(size_t size, size_t alignment, uint32_t flags)
+{
+ throw nullptr;
+}
+
+// Release virtual memory range previously reserved using VirtualReserve
+// Parameters:
+// address - starting virtual address
+// size - size of the virtual memory range
+// Return:
+// true if it has succeeded, false if it has failed
+bool GCToOSInterface::VirtualRelease(void* address, size_t size)
+{
+ throw nullptr;
+}
+
+// Commit virtual memory range. It must be part of a range reserved using VirtualReserve.
+// Parameters:
+// address - starting virtual address
+// size - size of the virtual memory range
+// Return:
+// true if it has succeeded, false if it has failed
+bool GCToOSInterface::VirtualCommit(void* address, size_t size)
+{
+ throw nullptr;
+}
+
+// Decomit virtual memory range.
+// Parameters:
+// address - starting virtual address
+// size - size of the virtual memory range
+// Return:
+// true if it has succeeded, false if it has failed
+bool GCToOSInterface::VirtualDecommit(void* address, size_t size)
+{
+ throw nullptr;
+}
+
+// Reset virtual memory range. Indicates that data in the memory range specified by address and size is no
+// longer of interest, but it should not be decommitted.
+// Parameters:
+// address - starting virtual address
+// size - size of the virtual memory range
+// unlock - true if the memory range should also be unlocked
+// Return:
+// true if it has succeeded, false if it has failed
+bool GCToOSInterface::VirtualReset(void * address, size_t size, bool unlock)
+{
+ throw nullptr;
+}
+
+// Check if the OS supports write watching
+bool GCToOSInterface::SupportsWriteWatch()
+{
+ throw nullptr;
+}
+
+// Reset the write tracking state for the specified virtual memory range.
+// Parameters:
+// address - starting virtual address
+// size - size of the virtual memory range
+void GCToOSInterface::ResetWriteWatch(void* address, size_t size)
+{
+ throw nullptr;
+}
+
+// Retrieve addresses of the pages that are written to in a region of virtual memory
+// Parameters:
+// resetState - true indicates to reset the write tracking state
+// address - starting virtual address
+// size - size of the virtual memory range
+// pageAddresses - buffer that receives an array of page addresses in the memory region
+// pageAddressesCount - on input, size of the lpAddresses array, in array elements
+// on output, the number of page addresses that are returned in the array.
+// Return:
+// true if it has succeeded, false if it has failed
+bool GCToOSInterface::GetWriteWatch(bool resetState, void* address, size_t size, void** pageAddresses, uintptr_t* pageAddressesCount)
+{
+ throw nullptr;
+}
+
+// Get size of the largest cache on the processor die
+// Parameters:
+// trueSize - true to return true cache size, false to return scaled up size based on
+// the processor architecture
+// Return:
+// Size of the cache
+size_t GCToOSInterface::GetLargestOnDieCacheSize(bool trueSize)
+{
+ throw nullptr;
+}
+
+// Get affinity mask of the current process
+// Parameters:
+// processMask - affinity mask for the specified process
+// systemMask - affinity mask for the system
+// Return:
+// true if it has succeeded, false if it has failed
+// Remarks:
+// A process affinity mask is a bit vector in which each bit represents the processors that
+// a process is allowed to run on. A system affinity mask is a bit vector in which each bit
+// represents the processors that are configured into a system.
+// A process affinity mask is a subset of the system affinity mask. A process is only allowed
+// to run on the processors configured into a system. Therefore, the process affinity mask cannot
+// specify a 1 bit for a processor when the system affinity mask specifies a 0 bit for that processor.
+bool GCToOSInterface::GetCurrentProcessAffinityMask(uintptr_t* processMask, uintptr_t* systemMask)
+{
+ throw nullptr;
+}
+
+// Get number of processors assigned to the current process
+// Return:
+// The number of processors
+uint32_t GCToOSInterface::GetCurrentProcessCpuCount()
+{
+ throw nullptr;
+}
+
+// Return the size of the user-mode portion of the virtual address space of this process.
+// Return:
+// non zero if it has succeeded, 0 if it has failed
+size_t GCToOSInterface::GetVirtualMemoryLimit()
+{
+ throw nullptr;
+}
+
+// Get the physical memory that this process can use.
+// Return:
+// non zero if it has succeeded, 0 if it has failed
+// Remarks:
+// If a process runs with a restricted memory limit, it returns the limit. If there's no limit
+// specified, it returns amount of actual physical memory.
+uint64_t GCToOSInterface::GetPhysicalMemoryLimit()
+{
+ throw nullptr;
+}
+
+// Get memory status
+// Parameters:
+// memory_load - A number between 0 and 100 that specifies the approximate percentage of physical memory
+// that is in use (0 indicates no memory use and 100 indicates full memory use).
+// available_physical - The amount of physical memory currently available, in bytes.
+// available_page_file - The maximum amount of memory the current process can commit, in bytes.
+void GCToOSInterface::GetMemoryStatus(uint32_t* memory_load, uint64_t* available_physical, uint64_t* available_page_file)
+{
+ throw nullptr;
+}
+
+// Get a high precision performance counter
+// Return:
+// The counter value
+int64_t GCToOSInterface::QueryPerformanceCounter()
+{
+ throw nullptr;
+}
+
+// Get a frequency of the high precision performance counter
+// Return:
+// The counter frequency
+int64_t GCToOSInterface::QueryPerformanceFrequency()
+{
+ throw nullptr;
+}
+
+// Get a time stamp with a low precision
+// Return:
+// Time stamp in milliseconds
+uint32_t GCToOSInterface::GetLowPrecisionTimeStamp()
+{
+ throw nullptr;
+}
+
+
+// Create a new thread for GC use
+// Parameters:
+// function - the function to be executed by the thread
+// param - parameters of the thread
+// affinity - processor affinity of the thread
+// Return:
+// true if it has succeeded, false if it has failed
+bool GCToOSInterface::CreateThread(GCThreadFunction function, void* param, GCThreadAffinity* affinity)
+{
+ throw nullptr;
+}
+
+// Initialize the critical section
+void CLRCriticalSection::Initialize()
+{
+ throw nullptr;
+}
+
+// Destroy the critical section
+void CLRCriticalSection::Destroy()
+{
+ throw nullptr;
+}
+
+// Enter the critical section. Blocks until the section can be entered.
+void CLRCriticalSection::Enter()
+{
+ throw nullptr;
+}
+
+// Leave the critical section
+void CLRCriticalSection::Leave()
+{
+ throw nullptr;
+} \ No newline at end of file
diff --git a/src/gc/gcenv.windows.cpp b/src/gc/gcenv.windows.cpp
new file mode 100644
index 0000000000..a636478245
--- /dev/null
+++ b/src/gc/gcenv.windows.cpp
@@ -0,0 +1,625 @@
+// Licensed to the .NET Foundation under one or more 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 <cstdint>
+#include <cassert>
+#include <cstddef>
+#include <memory>
+#include "windows.h"
+#include "psapi.h"
+#include "env/gcenv.structs.h"
+#include "env/gcenv.base.h"
+#include "env/gcenv.os.h"
+
+GCSystemInfo g_SystemInfo;
+
+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)UINTPTR_MAX;
+
+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);
+
+namespace {
+
+void GetProcessMemoryLoad(LPMEMORYSTATUSEX pMSEX)
+{
+ pMSEX->dwLength = sizeof(MEMORYSTATUSEX);
+ BOOL fRet = ::GlobalMemoryStatusEx(pMSEX);
+ assert(fRet);
+
+ // If the machine has more RAM than virtual address limit, let us cap it.
+ // Our GC can never use more than virtual address limit.
+ if (pMSEX->ullAvailPhys > pMSEX->ullTotalVirtual)
+ {
+ pMSEX->ullAvailPhys = pMSEX->ullAvailVirtual;
+ }
+}
+
+static size_t GetRestrictedPhysicalMemoryLimit()
+{
+ LIMITED_METHOD_CONTRACT;
+
+ // The limit was cached already
+ if (g_RestrictedPhysicalMemoryLimit != (size_t)UINTPTR_MAX)
+ return g_RestrictedPhysicalMemoryLimit;
+
+ size_t job_physical_memory_limit = (size_t)UINTPTR_MAX;
+ BOOL in_job_p = FALSE;
+ HINSTANCE hinstKernel32 = 0;
+
+ PIS_PROCESS_IN_JOB GCIsProcessInJob = 0;
+ PQUERY_INFORMATION_JOB_OBJECT GCQueryInformationJobObject = 0;
+
+ hinstKernel32 = LoadLibraryEx(L"kernel32.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
+ if (!hinstKernel32)
+ goto exit;
+
+ GCIsProcessInJob = (PIS_PROCESS_IN_JOB)GetProcAddress(hinstKernel32, "IsProcessInJob");
+ if (!GCIsProcessInJob)
+ goto exit;
+
+ if (!GCIsProcessInJob(GetCurrentProcess(), NULL, &in_job_p))
+ goto exit;
+
+ if (in_job_p)
+ {
+ GCGetProcessMemoryInfo = (PGET_PROCESS_MEMORY_INFO)GetProcAddress(hinstKernel32, "K32GetProcessMemoryInfo");
+
+ if (!GCGetProcessMemoryInfo)
+ goto exit;
+
+ GCQueryInformationJobObject = (PQUERY_INFORMATION_JOB_OBJECT)GetProcAddress(hinstKernel32, "QueryInformationJobObject");
+
+ if (!GCQueryInformationJobObject)
+ goto exit;
+
+ JOBOBJECT_EXTENDED_LIMIT_INFORMATION limit_info;
+ if (GCQueryInformationJobObject (NULL, JobObjectExtendedLimitInformation, &limit_info,
+ sizeof(limit_info), NULL))
+ {
+ size_t job_memory_limit = (size_t)UINTPTR_MAX;
+ size_t job_process_memory_limit = (size_t)UINTPTR_MAX;
+ size_t job_workingset_limit = (size_t)UINTPTR_MAX;
+
+ // Notes on the NT job object:
+ //
+ // You can specific a bigger process commit or working set limit than
+ // job limit which is pointless so we use the smallest of all 3 as
+ // to calculate our "physical memory load" or "available physical memory"
+ // when running inside a job object, ie, we treat this as the amount of physical memory
+ // our process is allowed to use.
+ //
+ // The commit limit is already reflected by default when you run in a
+ // job but the physical memory load is not.
+ //
+ if ((limit_info.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_JOB_MEMORY) != 0)
+ job_memory_limit = limit_info.JobMemoryLimit;
+ if ((limit_info.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_PROCESS_MEMORY) != 0)
+ job_process_memory_limit = limit_info.ProcessMemoryLimit;
+ if ((limit_info.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_WORKINGSET) != 0)
+ job_workingset_limit = limit_info.BasicLimitInformation.MaximumWorkingSetSize;
+
+ job_physical_memory_limit = min (job_memory_limit, job_process_memory_limit);
+ job_physical_memory_limit = min (job_physical_memory_limit, job_workingset_limit);
+
+ MEMORYSTATUSEX ms;
+ ::GetProcessMemoryLoad(&ms);
+
+ // A sanity check in case someone set a larger limit than there is actual physical memory.
+ job_physical_memory_limit = (size_t) min (job_physical_memory_limit, ms.ullTotalPhys);
+ }
+ }
+
+exit:
+ if (job_physical_memory_limit == (size_t)UINTPTR_MAX)
+ {
+ job_physical_memory_limit = 0;
+
+ FreeLibrary(hinstKernel32);
+ }
+
+ VolatileStore(&g_RestrictedPhysicalMemoryLimit, job_physical_memory_limit);
+ return g_RestrictedPhysicalMemoryLimit;
+}
+
+} // anonymous namespace
+
+// Initialize the interface implementation
+// Return:
+// true if it has succeeded, false if it has failed
+bool GCToOSInterface::Initialize()
+{
+ SYSTEM_INFO systemInfo;
+ GetSystemInfo(&systemInfo);
+
+ g_SystemInfo.dwNumberOfProcessors = systemInfo.dwNumberOfProcessors;
+ g_SystemInfo.dwPageSize = systemInfo.dwPageSize;
+ g_SystemInfo.dwAllocationGranularity = systemInfo.dwAllocationGranularity;
+
+ return true;
+}
+
+// Shutdown the interface implementation
+void GCToOSInterface::Shutdown()
+{
+ // nothing to do.
+}
+
+// Get numeric id of the current thread if possible on the
+// current platform. It is indended for logging purposes only.
+// Return:
+// Numeric id of the current thread or 0 if the
+uint64_t GCToOSInterface::GetCurrentThreadIdForLogging()
+{
+ return ::GetCurrentThreadId();
+}
+
+// Get id of the process
+uint32_t GCToOSInterface::GetCurrentProcessId()
+{
+ return ::GetCurrentThreadId();
+}
+
+// Set ideal affinity for the current thread
+// Parameters:
+// affinity - ideal processor affinity for the thread
+// Return:
+// true if it has succeeded, false if it has failed
+bool GCToOSInterface::SetCurrentThreadIdealAffinity(GCThreadAffinity* affinity)
+{
+ bool success = true;
+
+#if !defined(FEATURE_CORESYSTEM)
+ SetThreadIdealProcessor(GetCurrentThread(), (DWORD)affinity->Processor);
+#else
+ PROCESSOR_NUMBER proc;
+
+ if (affinity->Group != -1)
+ {
+ proc.Group = (WORD)affinity->Group;
+ proc.Number = (BYTE)affinity->Processor;
+ proc.Reserved = 0;
+
+ success = !!SetThreadIdealProcessorEx(GetCurrentThread(), &proc, NULL);
+ }
+ else
+ {
+ if (GetThreadIdealProcessorEx(GetCurrentThread(), &proc))
+ {
+ proc.Number = affinity->Processor;
+ success = !!SetThreadIdealProcessorEx(GetCurrentThread(), &proc, NULL);
+ }
+ }
+#endif
+
+ return success;
+}
+
+// Get the number of the current processor
+uint32_t GCToOSInterface::GetCurrentProcessorNumber()
+{
+ assert(GCToOSInterface::CanGetCurrentProcessorNumber());
+ return ::GetCurrentProcessorNumber();
+}
+
+// Check if the OS supports getting current processor number
+bool GCToOSInterface::CanGetCurrentProcessorNumber()
+{
+ // on all Windows platforms we support this API exists
+ return true;
+}
+
+// Flush write buffers of processors that are executing threads of the current process
+void GCToOSInterface::FlushProcessWriteBuffers()
+{
+ ::FlushProcessWriteBuffers();
+}
+
+// Break into a debugger
+void GCToOSInterface::DebugBreak()
+{
+ ::DebugBreak();
+}
+
+// Get number of logical processors
+uint32_t GCToOSInterface::GetLogicalCpuCount()
+{
+ // TODO(segilles) processor detection
+ return 1;
+}
+
+// Causes the calling thread to sleep for the specified number of milliseconds
+// Parameters:
+// sleepMSec - time to sleep before switching to another thread
+void GCToOSInterface::Sleep(uint32_t sleepMSec)
+{
+ // TODO(segilles) CLR implementation of __SwitchToThread spins for short sleep durations
+ // to avoid context switches - is that interesting or useful here?
+ if (sleepMSec > 0)
+ {
+ ::SleepEx(sleepMSec, FALSE);
+ }
+}
+
+// Causes the calling thread to yield execution to another thread that is ready to run on the current processor.
+// Parameters:
+// switchCount - number of times the YieldThread was called in a loop
+void GCToOSInterface::YieldThread(uint32_t switchCount)
+{
+ UNREFERENCED_PARAMETER(switchCount);
+ SwitchToThread();
+}
+
+// Reserve virtual memory range.
+// Parameters:
+// address - starting virtual address, it can be NULL to let the function choose the starting address
+// size - size of the virtual memory range
+// alignment - requested memory alignment, 0 means no specific alignment requested
+// flags - flags to control special settings like write watching
+// Return:
+// Starting virtual address of the reserved range
+void* GCToOSInterface::VirtualReserve(size_t size, size_t alignment, uint32_t flags)
+{
+ // Windows already ensures 64kb alignment on VirtualAlloc. The current CLR
+ // implementation ignores it on Windows, other than making some sanity checks on it.
+ UNREFERENCED_PARAMETER(alignment);
+ assert((alignment & (alignment - 1)) == 0);
+ assert(alignment <= 0x10000);
+ DWORD memFlags = (flags & VirtualReserveFlags::WriteWatch) ? (MEM_RESERVE | MEM_WRITE_WATCH) : MEM_RESERVE;
+ return ::VirtualAlloc(nullptr, size, memFlags, PAGE_READWRITE);
+}
+
+// Release virtual memory range previously reserved using VirtualReserve
+// Parameters:
+// address - starting virtual address
+// size - size of the virtual memory range
+// Return:
+// true if it has succeeded, false if it has failed
+bool GCToOSInterface::VirtualRelease(void* address, size_t size)
+{
+ return !!::VirtualFree(address, 0, MEM_RELEASE);
+}
+
+// Commit virtual memory range. It must be part of a range reserved using VirtualReserve.
+// Parameters:
+// address - starting virtual address
+// size - size of the virtual memory range
+// Return:
+// true if it has succeeded, false if it has failed
+bool GCToOSInterface::VirtualCommit(void* address, size_t size)
+{
+ return ::VirtualAlloc(address, size, MEM_COMMIT, PAGE_READWRITE) != nullptr;
+}
+
+// Decomit virtual memory range.
+// Parameters:
+// address - starting virtual address
+// size - size of the virtual memory range
+// Return:
+// true if it has succeeded, false if it has failed
+bool GCToOSInterface::VirtualDecommit(void* address, size_t size)
+{
+ return !!::VirtualFree(address, size, MEM_DECOMMIT);
+}
+
+// Reset virtual memory range. Indicates that data in the memory range specified by address and size is no
+// longer of interest, but it should not be decommitted.
+// Parameters:
+// address - starting virtual address
+// size - size of the virtual memory range
+// unlock - true if the memory range should also be unlocked
+// Return:
+// true if it has succeeded, false if it has failed. Returns false also if
+// unlocking was requested but the unlock failed.
+bool GCToOSInterface::VirtualReset(void * address, size_t size, bool unlock)
+{
+ bool success = ::VirtualAlloc(address, size, MEM_RESET, PAGE_READWRITE) != nullptr;
+ if (success && unlock)
+ {
+ ::VirtualUnlock(address, size);
+ }
+
+ return success;
+}
+
+// Check if the OS supports write watching
+bool GCToOSInterface::SupportsWriteWatch()
+{
+ void* mem = GCToOSInterface::VirtualReserve(g_SystemInfo.dwAllocationGranularity, 0, VirtualReserveFlags::WriteWatch);
+ if (mem != nullptr)
+ {
+ GCToOSInterface::VirtualRelease(mem, g_SystemInfo.dwAllocationGranularity);
+ return true;
+ }
+
+ return false;
+}
+
+// Reset the write tracking state for the specified virtual memory range.
+// Parameters:
+// address - starting virtual address
+// size - size of the virtual memory range
+void GCToOSInterface::ResetWriteWatch(void* address, size_t size)
+{
+ ::ResetWriteWatch(address, size);
+}
+
+// Retrieve addresses of the pages that are written to in a region of virtual memory
+// Parameters:
+// resetState - true indicates to reset the write tracking state
+// address - starting virtual address
+// size - size of the virtual memory range
+// pageAddresses - buffer that receives an array of page addresses in the memory region
+// pageAddressesCount - on input, size of the lpAddresses array, in array elements
+// on output, the number of page addresses that are returned in the array.
+// Return:
+// true if it has succeeded, false if it has failed
+bool GCToOSInterface::GetWriteWatch(bool resetState, void* address, size_t size, void** pageAddresses, uintptr_t* pageAddressesCount)
+{
+ uint32_t flags = resetState ? 1 : 0;
+ ULONG granularity;
+
+ bool success = ::GetWriteWatch(flags, address, size, pageAddresses, (ULONG_PTR*)pageAddressesCount, &granularity) == 0;
+ if (success)
+ {
+ assert(granularity == OS_PAGE_SIZE);
+ }
+
+ return success;
+}
+
+// Get size of the largest cache on the processor die
+// Parameters:
+// trueSize - true to return true cache size, false to return scaled up size based on
+// the processor architecture
+// Return:
+// Size of the cache
+size_t GCToOSInterface::GetLargestOnDieCacheSize(bool trueSize)
+{
+ // TODO(segilles) processor detection (see src/vm/util.cpp:1935)
+ return 0;
+}
+
+// Get affinity mask of the current process
+// Parameters:
+// processMask - affinity mask for the specified process
+// systemMask - affinity mask for the system
+// Return:
+// true if it has succeeded, false if it has failed
+// Remarks:
+// A process affinity mask is a bit vector in which each bit represents the processors that
+// a process is allowed to run on. A system affinity mask is a bit vector in which each bit
+// represents the processors that are configured into a system.
+// A process affinity mask is a subset of the system affinity mask. A process is only allowed
+// to run on the processors configured into a system. Therefore, the process affinity mask cannot
+// specify a 1 bit for a processor when the system affinity mask specifies a 0 bit for that processor.
+bool GCToOSInterface::GetCurrentProcessAffinityMask(uintptr_t* processMask, uintptr_t* systemMask)
+{
+ return !!::GetProcessAffinityMask(::GetCurrentProcess(), (PDWORD_PTR)processMask, (PDWORD_PTR)systemMask);
+}
+
+// Get number of processors assigned to the current process
+// Return:
+// The number of processors
+uint32_t GCToOSInterface::GetCurrentProcessCpuCount()
+{
+ // TODO(segilles) this does not take into account process affinity
+ return g_SystemInfo.dwNumberOfProcessors;
+}
+
+// Return the size of the user-mode portion of the virtual address space of this process.
+// Return:
+// non zero if it has succeeded, 0 if it has failed
+size_t GCToOSInterface::GetVirtualMemoryLimit()
+{
+ MEMORYSTATUSEX memStatus;
+ if (::GlobalMemoryStatusEx(&memStatus))
+ {
+ return (size_t)memStatus.ullAvailVirtual;
+ }
+
+ return 0;
+}
+
+// Get the physical memory that this process can use.
+// Return:
+// non zero if it has succeeded, 0 if it has failed
+// Remarks:
+// If a process runs with a restricted memory limit, it returns the limit. If there's no limit
+// specified, it returns amount of actual physical memory.
+uint64_t GCToOSInterface::GetPhysicalMemoryLimit()
+{
+ size_t restricted_limit = GetRestrictedPhysicalMemoryLimit();
+ if (restricted_limit != 0)
+ return restricted_limit;
+
+ MEMORYSTATUSEX memStatus;
+ if (::GlobalMemoryStatusEx(&memStatus))
+ {
+ return memStatus.ullTotalPhys;
+ }
+
+ return 0;
+}
+
+// Get memory status
+// Parameters:
+// memory_load - A number between 0 and 100 that specifies the approximate percentage of physical memory
+// that is in use (0 indicates no memory use and 100 indicates full memory use).
+// available_physical - The amount of physical memory currently available, in bytes.
+// available_page_file - The maximum amount of memory the current process can commit, in bytes.
+void GCToOSInterface::GetMemoryStatus(uint32_t* memory_load, uint64_t* available_physical, uint64_t* available_page_file)
+{
+ uint64_t restricted_limit = GetRestrictedPhysicalMemoryLimit();
+ if (restricted_limit != 0)
+ {
+ PROCESS_MEMORY_COUNTERS pmc;
+ if (GCGetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc)))
+ {
+ if (memory_load)
+ *memory_load = (uint32_t)((float)pmc.WorkingSetSize * 100.0 / (float)restricted_limit);
+ if (available_physical)
+ *available_physical = restricted_limit - pmc.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.
+ if (available_page_file)
+ *available_page_file = 0;
+
+ return;
+ }
+ }
+
+ MEMORYSTATUSEX ms;
+ ::GetProcessMemoryLoad(&ms);
+
+ if (memory_load != nullptr)
+ *memory_load = ms.dwMemoryLoad;
+ if (available_physical != nullptr)
+ *available_physical = ms.ullAvailPhys;
+ if (available_page_file != nullptr)
+ *available_page_file = ms.ullAvailPageFile;
+}
+
+// Get a high precision performance counter
+// Return:
+// The counter value
+int64_t GCToOSInterface::QueryPerformanceCounter()
+{
+ LARGE_INTEGER ts;
+ if (!::QueryPerformanceCounter(&ts))
+ {
+ assert(false && "Failed to query performance counter");
+ }
+
+ return ts.QuadPart;
+}
+
+// Get a frequency of the high precision performance counter
+// Return:
+// The counter frequency
+int64_t GCToOSInterface::QueryPerformanceFrequency()
+{
+ LARGE_INTEGER ts;
+ if (!::QueryPerformanceFrequency(&ts))
+ {
+ assert(false && "Failed to query performance counter");
+ }
+
+ return ts.QuadPart;
+}
+
+// Get a time stamp with a low precision
+// Return:
+// Time stamp in milliseconds
+uint32_t GCToOSInterface::GetLowPrecisionTimeStamp()
+{
+ return ::GetTickCount();
+}
+
+// Parameters of the GC thread stub
+struct GCThreadStubParam
+{
+ GCThreadFunction GCThreadFunction;
+ void* GCThreadParam;
+};
+
+// GC thread stub to convert GC thread function to an OS specific thread function
+static DWORD GCThreadStub(void* param)
+{
+ GCThreadStubParam *stubParam = (GCThreadStubParam*)param;
+ GCThreadFunction function = stubParam->GCThreadFunction;
+ void* threadParam = stubParam->GCThreadParam;
+
+ delete stubParam;
+
+ function(threadParam);
+
+ return 0;
+}
+
+
+// Create a new thread for GC use
+// Parameters:
+// function - the function to be executed by the thread
+// param - parameters of the thread
+// affinity - processor affinity of the thread
+// Return:
+// true if it has succeeded, false if it has failed
+bool GCToOSInterface::CreateThread(GCThreadFunction function, void* param, GCThreadAffinity* affinity)
+{
+ uint32_t thread_id;
+
+ std::unique_ptr<GCThreadStubParam> stubParam(new (std::nothrow) GCThreadStubParam());
+ if (!stubParam)
+ {
+ return false;
+ }
+
+ stubParam->GCThreadFunction = function;
+ stubParam->GCThreadParam = param;
+
+ HANDLE gc_thread = ::CreateThread(
+ nullptr,
+ 512 * 1024 /* Thread::StackSize_Medium */,
+ (LPTHREAD_START_ROUTINE)GCThreadStub,
+ stubParam.get(),
+ CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION,
+ (DWORD*)&thread_id);
+
+ if (!gc_thread)
+ {
+ return false;
+ }
+
+ stubParam.release();
+ bool result = !!::SetThreadPriority(gc_thread, /* THREAD_PRIORITY_ABOVE_NORMAL );*/ THREAD_PRIORITY_HIGHEST );
+ assert(result && "failed to set thread priority");
+
+ if (affinity->Group != GCThreadAffinity::None)
+ {
+ assert(affinity->Processor != GCThreadAffinity::None);
+ GROUP_AFFINITY ga;
+ ga.Group = (WORD)affinity->Group;
+ ga.Reserved[0] = 0; // reserve must be filled with zero
+ ga.Reserved[1] = 0; // otherwise call may fail
+ ga.Reserved[2] = 0;
+ ga.Mask = (size_t)1 << affinity->Processor;
+
+ bool result = !!::SetThreadGroupAffinity(gc_thread, &ga, nullptr);
+ assert(result && "failed to set thread affinity");
+ }
+ else if (affinity->Processor != GCThreadAffinity::None)
+ {
+ ::SetThreadAffinityMask(gc_thread, (DWORD_PTR)1 << affinity->Processor);
+ }
+
+ return true;
+}
+
+// Initialize the critical section
+void CLRCriticalSection::Initialize()
+{
+ ::InitializeCriticalSection(&m_cs);
+}
+
+// Destroy the critical section
+void CLRCriticalSection::Destroy()
+{
+ ::DeleteCriticalSection(&m_cs);
+}
+
+// Enter the critical section. Blocks until the section can be entered.
+void CLRCriticalSection::Enter()
+{
+ ::EnterCriticalSection(&m_cs);
+}
+
+// Leave the critical section
+void CLRCriticalSection::Leave()
+{
+ ::LeaveCriticalSection(&m_cs);
+}
diff --git a/src/gc/gcimpl.h b/src/gc/gcimpl.h
index 6a4ee86cd8..7e3a13a743 100644
--- a/src/gc/gcimpl.h
+++ b/src/gc/gcimpl.h
@@ -36,29 +36,10 @@ inline void checkGCWriteBarrier() {}
void GCProfileWalkHeap();
-class GCHeap;
class gc_heap;
class CFinalize;
-// TODO : it would be easier to make this an ORed value
-enum gc_reason
-{
- reason_alloc_soh = 0,
- reason_induced = 1,
- reason_lowmemory = 2,
- reason_empty = 3,
- reason_alloc_loh = 4,
- reason_oos_soh = 5,
- reason_oos_loh = 6,
- reason_induced_noforce = 7, // it's an induced GC and doesn't have to be blocking.
- reason_gcstress = 8, // this turns into reason_induced & gc_mechanisms.stress_induced = true
- reason_lowmemory_blocking = 9,
- reason_induced_compacting = 10,
- reason_lowmemory_host = 11,
- reason_max
-};
-
-class GCHeap : public ::GCHeap
+class GCHeap : public IGCHeapInternal
{
protected:
@@ -96,7 +77,7 @@ public:
size_t GetLastGCDuration(int generation);
size_t GetNow();
- void TraceGCSegments ();
+ void DiagTraceGCSegments ();
void PublishObject(uint8_t* obj);
BOOL IsGCInProgressHelper (BOOL bConsiderGCStart = FALSE);
@@ -111,17 +92,15 @@ public:
//flags can be GC_ALLOC_CONTAINS_REF GC_ALLOC_FINALIZE
Object* Alloc (size_t size, uint32_t flags);
-#ifdef FEATURE_64BIT_ALIGNMENT
Object* AllocAlign8 (size_t size, uint32_t flags);
- Object* AllocAlign8 (alloc_context* acontext, 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);
public:
-#endif // FEATURE_64BIT_ALIGNMENT
Object* AllocLHeap (size_t size, uint32_t flags);
- Object* Alloc (alloc_context* acontext, size_t size, uint32_t flags);
+ Object* Alloc (gc_alloc_context* acontext, size_t size, uint32_t flags);
- void FixAllocContext (alloc_context* acontext,
+ void FixAllocContext (gc_alloc_context* acontext,
BOOL lockp, void* arg, void *heap);
Object* GetContainingObject(void *pInteriorPtr);
@@ -132,7 +111,7 @@ public:
#endif //MULTIPLE_HEAPS
int GetHomeHeapNumber ();
- bool IsThreadUsingAllocationContextHeap(alloc_context* acontext, int thread_number);
+ bool IsThreadUsingAllocationContextHeap(gc_alloc_context* acontext, int thread_number);
int GetNumberOfHeaps ();
void HideAllocContext(alloc_context*);
void RevealAllocContext(alloc_context*);
@@ -176,9 +155,7 @@ public:
BOOL IsEphemeral (Object* object);
BOOL IsHeapPointer (void* object, BOOL small_heap_only = FALSE);
-#ifdef VERIFY_HEAP
void ValidateObjectMember (Object *obj);
-#endif //_DEBUG
PER_HEAP size_t ApproxTotalBytesInUse(BOOL small_heap_only = FALSE);
PER_HEAP size_t ApproxFreeBytes();
@@ -199,8 +176,6 @@ public:
int StartNoGCRegion(uint64_t totalSize, BOOL lohSizeKnown, uint64_t lohSize, BOOL disallowFullBlockingGC);
int EndNoGCRegion();
-
- PER_HEAP_ISOLATED unsigned GetMaxGeneration();
unsigned GetGcCount();
@@ -224,9 +199,7 @@ public:
BOOL ShouldRestartFinalizerWatchDog();
void SetCardsAfterBulkCopy( Object**, size_t);
-#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
- void WalkObject (Object* obj, walk_fn fn, void* context);
-#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+ void DiagWalkObject (Object* obj, walk_fn fn, void* context);
public: // FIX
@@ -249,11 +222,9 @@ public: // FIX
// Interface with gc_heap
size_t GarbageCollectTry (int generation, BOOL low_memory_p=FALSE, int mode=collection_blocking);
-#ifdef FEATURE_BASICFREEZE
// frozen segment management functions
virtual segment_handle RegisterFrozenSegment(segment_info *pseginfo);
virtual void UnregisterFrozenSegment(segment_handle seg);
-#endif // FEATURE_BASICFREEZE
void WaitUntilConcurrentGCComplete (); // Use in managd threads
#ifndef DACCESS_COMPILE
@@ -281,11 +252,12 @@ private:
// the condition here may have to change as well.
return g_TrapReturningThreads == 0;
}
-#ifndef FEATURE_REDHAWK // Redhawk forces relocation a different way
-#ifdef STRESS_HEAP
public:
//return TRUE if GC actually happens, otherwise FALSE
- BOOL StressHeap(alloc_context * acontext = 0);
+ BOOL StressHeap(gc_alloc_context * acontext = 0);
+
+#ifndef FEATURE_REDHAWK // Redhawk forces relocation a different way
+#ifdef STRESS_HEAP
protected:
// only used in BACKGROUND_GC, but the symbol is not defined yet...
@@ -300,17 +272,25 @@ protected:
#endif // STRESS_HEAP
#endif // FEATURE_REDHAWK
-#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
- virtual void DescrGenerationsToProfiler (gen_walk_fn fn, void *context);
-#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+ 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 DiagWalkFinalizeQueue (void* gc_context, fq_walk_fn fn);
+
+ virtual void DiagScanFinalizeQueue (fq_scan_fn fn, ScanContext* context);
+
+ virtual void DiagScanHandles (handle_scan_fn fn, int gen_number, ScanContext* context);
+
+ 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);
-#ifdef VERIFY_HEAP
public:
Object * NextObj (Object * object);
-#ifdef FEATURE_BASICFREEZE
+#if defined (FEATURE_BASICFREEZE) && defined (VERIFY_HEAP)
BOOL IsInFrozenSegment (Object * object);
-#endif //FEATURE_BASICFREEZE
-#endif //VERIFY_HEAP
+#endif // defined (FEATURE_BASICFREEZE) && defined (VERIFY_HEAP)
};
#endif // GCIMPL_H_
diff --git a/src/gc/gcinterface.ee.h b/src/gc/gcinterface.ee.h
new file mode 100644
index 0000000000..c5f87ef031
--- /dev/null
+++ b/src/gc/gcinterface.ee.h
@@ -0,0 +1,133 @@
+// Licensed to the .NET Foundation under one or more 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 _GCINTERFACE_EE_H_
+#define _GCINTERFACE_EE_H_
+
+// This interface provides the interface that the GC will use to speak to the rest
+// of the execution engine. Everything that the GC does that requires the EE
+// to be informed or that requires EE action must go through this interface.
+//
+// When FEATURE_STANDALONE_GC is defined, this class is named IGCToCLR and is
+// an abstract class. The EE will provide a class that fulfills this interface,
+// and the GC will dispatch virtually on it to call into the EE. When FEATURE_STANDALONE_GC
+// is not defined, this class is named GCToEEInterface and the GC will dispatch statically on it.
+class IGCToCLR {
+public:
+ // Suspends the EE for the given reason.
+ virtual
+ void SuspendEE(SUSPEND_REASON reason) = 0;
+
+ // Resumes all paused threads, with a boolean indicating
+ // if the EE is being restarted because a GC is complete.
+ virtual
+ void RestartEE(bool bFinishedGC) = 0;
+
+ // Performs a stack walk of all managed threads and invokes the given promote_func
+ // on all GC roots encountered on the stack. Depending on the condemned generation,
+ // this function may also enumerate all static GC refs if necessary.
+ virtual
+ void GcScanRoots(promote_func* fn, int condemned, int max_gen, ScanContext* sc) = 0;
+
+ // Callback from the GC informing the EE that it is preparing to start working.
+ virtual
+ void GcStartWork(int condemned, int max_gen) = 0;
+
+ // Callback from the GC informing the EE that it has completed the managed stack
+ // scan. User threads are still suspended at this point.
+ virtual
+ void AfterGcScanRoots(int condemned, int max_gen, ScanContext* sc) = 0;
+
+ // Callback from the GC informing the EE that the background sweep phase of a BGC is
+ // about to begin.
+ virtual
+ void GcBeforeBGCSweepWork() = 0;
+
+ // Callback from the GC informing the EE that a GC has completed.
+ virtual
+ void GcDone(int condemned) = 0;
+
+ // Predicate for the GC to query whether or not a given refcounted handle should
+ // be promoted.
+ virtual
+ bool RefCountedHandleCallbacks(Object * pObject) = 0;
+
+ // Performs a weak pointer scan of the sync block cache.
+ virtual
+ void SyncBlockCacheWeakPtrScan(HANDLESCANPROC scanProc, uintptr_t lp1, uintptr_t lp2) = 0;
+
+ // Indicates to the EE that the GC intends to demote objects in the sync block cache.
+ virtual
+ void SyncBlockCacheDemote(int max_gen) = 0;
+
+ // Indicates to the EE that the GC has granted promotion to objects in the sync block cache.
+ virtual
+ void SyncBlockCachePromotionsGranted(int max_gen) = 0;
+
+ // Queries whether or not the given thread has preemptive GC disabled.
+ virtual
+ bool IsPreemptiveGCDisabled(Thread * pThread) = 0;
+
+ // Enables preemptive GC on the given thread.
+ virtual
+ void EnablePreemptiveGC(Thread * pThread) = 0;
+
+ // Disables preemptive GC on the given thread.
+ virtual
+ void DisablePreemptiveGC(Thread * pThread) = 0;
+
+ // Retrieves the alloc context associated with a given thread.
+ virtual
+ gc_alloc_context * GetAllocContext(Thread * pThread) = 0;
+
+ // Returns true if this thread is waiting to reach a safe point.
+ virtual
+ bool CatchAtSafePoint(Thread * pThread) = 0;
+
+ // Calls the given enum_alloc_context_func with every active alloc context.
+ virtual
+ void GcEnumAllocContexts(enum_alloc_context_func* fn, void* param) = 0;
+
+ // Creates and returns a new background thread.
+ virtual
+ Thread* CreateBackgroundThread(GCBackgroundThreadFunction threadStart, void* arg) = 0;
+
+ // When a GC starts, gives the diagnostics code a chance to run.
+ virtual
+ void DiagGCStart(int gen, bool isInduced) = 0;
+
+ // When GC heap segments change, gives the diagnostics code a chance to run.
+ virtual
+ void DiagUpdateGenerationBounds() = 0;
+
+ // When a GC ends, gives the diagnostics code a chance to run.
+ virtual
+ void DiagGCEnd(size_t index, int gen, int reason, bool fConcurrent) = 0;
+
+ // During a GC after we discover what objects' finalizers should run, gives the diagnostics code a chance to run.
+ virtual
+ void DiagWalkFReachableObjects(void* gcContext) = 0;
+
+ // During a GC after we discover the survivors and the relocation info,
+ // gives the diagnostics code a chance to run. This includes LOH if we are
+ // compacting LOH.
+ virtual
+ void DiagWalkSurvivors(void* gcContext) = 0;
+
+ // During a full GC after we discover what objects to survive on LOH,
+ // gives the diagnostics code a chance to run.
+ virtual
+ void DiagWalkLOHSurvivors(void* gcContext) = 0;
+
+ // At the end of a background GC, gives the diagnostics code a chance to run.
+ virtual
+ void DiagWalkBGCSurvivors(void* gcContext) = 0;
+
+ // Informs the EE of changes to the location of the card table, potentially updating the write
+ // barrier if it needs to be updated.
+ virtual
+ void StompWriteBarrier(WriteBarrierParameters* args) = 0;
+};
+
+#endif // _GCINTERFACE_EE_H_
diff --git a/src/gc/gcinterface.h b/src/gc/gcinterface.h
new file mode 100644
index 0000000000..1457848992
--- /dev/null
+++ b/src/gc/gcinterface.h
@@ -0,0 +1,622 @@
+// Licensed to the .NET Foundation under one or more 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_H_
+#define _GC_INTERFACE_H_
+
+struct ScanContext;
+struct gc_alloc_context;
+class CrawlFrame;
+
+// Callback passed to GcScanRoots.
+typedef void promote_func(PTR_PTR_Object, ScanContext*, uint32_t);
+
+// Callback passed to GcEnumAllocContexts.
+typedef void enum_alloc_context_func(gc_alloc_context*, void*);
+
+// Callback passed to CreateBackgroundThread.
+typedef uint32_t (__stdcall *GCBackgroundThreadFunction)(void* param);
+
+// Struct often used as a parameter to callbacks.
+typedef struct
+{
+ promote_func* f;
+ ScanContext* sc;
+ CrawlFrame * cf;
+} GCCONTEXT;
+
+// SUSPEND_REASON is the reason why the GC wishes to suspend the EE,
+// used as an argument to IGCToCLR::SuspendEE.
+typedef enum
+{
+ SUSPEND_FOR_GC = 1,
+ SUSPEND_FOR_GC_PREP = 6
+} SUSPEND_REASON;
+
+typedef enum
+{
+ walk_for_gc = 1,
+ walk_for_bgc = 2,
+ walk_for_loh = 3
+} walk_surv_type;
+
+// Different operations that can be done by GCToEEInterface::StompWriteBarrier
+enum class WriteBarrierOp
+{
+ StompResize,
+ StompEphemeral,
+ Initialize
+};
+
+// Arguments to GCToEEInterface::StompWriteBarrier
+struct WriteBarrierParameters
+{
+ // The operation that StompWriteBarrier will perform.
+ WriteBarrierOp operation;
+
+ // Whether or not the runtime is currently suspended. If it is not,
+ // the EE will need to suspend it before bashing the write barrier.
+ // Used for all operations.
+ bool is_runtime_suspended;
+
+ // Whether or not the GC has moved the ephemeral generation to no longer
+ // be at the top of the heap. When the ephemeral generation is at the top
+ // of the heap, and the write barrier observes that a pointer is greater than
+ // g_ephemeral_low, it does not need to check that the pointer is less than
+ // g_ephemeral_high because there is nothing in the GC heap above the ephemeral
+ // generation. When this is not the case, however, the GC must inform the EE
+ // so that the EE can switch to a write barrier that checks that a pointer
+ // is both greater than g_ephemeral_low and less than g_ephemeral_high.
+ // Used for WriteBarrierOp::StompResize.
+ bool requires_upper_bounds_check;
+
+ // The new card table location. May or may not be the same as the previous
+ // card table. Used for WriteBarrierOp::Initialize and WriteBarrierOp::StompResize.
+ uint32_t* card_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;
+
+ // The heap's new high boundary. May or may not be the same as the previous
+ // value. Used for WriteBarrierOp::Initialize and WriteBarrierOp::StompResize.
+ uint8_t* highest_address;
+
+ // The new start of the ephemeral generation.
+ // Used for WriteBarrierOp::StompEphemeral.
+ uint8_t* ephemeral_lo;
+
+ // The new end of the ephemeral generation.
+ // Used for WriteBarrierOp::StompEphemeral.
+ uint8_t* ephemeral_hi;
+};
+
+#include "gcinterface.ee.h"
+
+// The allocation context must be known to the VM for use in the allocation
+// fast path and known to the GC for performing the allocation. Every Thread
+// has its own allocation context that it hands to the GC when allocating.
+struct gc_alloc_context
+{
+ uint8_t* alloc_ptr;
+ uint8_t* alloc_limit;
+ int64_t alloc_bytes; //Number of bytes allocated on SOH by this context
+ int64_t alloc_bytes_loh; //Number of bytes allocated on LOH by this context
+ // These two fields are deliberately not exposed past the EE-GC interface.
+ void* gc_reserved_1;
+ void* gc_reserved_2;
+ int alloc_count;
+public:
+
+ void init()
+ {
+ LIMITED_METHOD_CONTRACT;
+
+ alloc_ptr = 0;
+ alloc_limit = 0;
+ alloc_bytes = 0;
+ alloc_bytes_loh = 0;
+ gc_reserved_1 = 0;
+ gc_reserved_2 = 0;
+ alloc_count = 0;
+ }
+};
+
+// stub type to abstract a heap segment
+struct gc_heap_segment_stub;
+typedef gc_heap_segment_stub *segment_handle;
+
+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 ibReserved; // limit of reserved memory in the segment (>= commit)
+};
+
+#ifdef PROFILING_SUPPORTED
+#define GC_PROFILING //Turn on profiling
+#endif // PROFILING_SUPPORTED
+
+#define LARGE_OBJECT_SIZE ((size_t)(85000))
+
+// The minimum size of an object is three pointers wide: one for the syncblock,
+// 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
+
+class Object;
+class IGCHeap;
+
+// Initializes the garbage collector. Should only be called
+// once, during EE startup.
+IGCHeap* InitializeGarbageCollector(IGCToCLR* clrToGC);
+
+// 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
+// heap that will be created, before InitializeGarbageCollector is called
+// and the heap is actually recated.
+void InitializeHeapType(bool bServerHeap);
+
+#ifdef WRITE_BARRIER_CHECK
+//always defined, but should be 0 in Server GC
+extern uint8_t* g_GCShadow;
+extern uint8_t* g_GCShadowEnd;
+// saves the g_lowest_address in between GCs to verify the consistency of the shadow segment
+extern uint8_t* g_shadow_lowest_address;
+#endif
+
+// 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!
+enum collection_mode
+{
+ collection_non_blocking = 0x00000001,
+ collection_blocking = 0x00000002,
+ collection_optimized = 0x00000004,
+ collection_compacting = 0x00000008
+#ifdef STRESS_HEAP
+ , collection_gcstress = 0x80000000
+#endif // STRESS_HEAP
+};
+
+// !!!!!!!!!!!!!!!!!!!!!!!
+// make sure you change the def in bcl\system\gc.cs
+// if you change this!
+enum wait_full_gc_status
+{
+ wait_full_gc_success = 0,
+ wait_full_gc_failed = 1,
+ wait_full_gc_cancelled = 2,
+ wait_full_gc_timeout = 3,
+ wait_full_gc_na = 4
+};
+
+// !!!!!!!!!!!!!!!!!!!!!!!
+// make sure you change the def in bcl\system\gc.cs
+// if you change this!
+enum start_no_gc_region_status
+{
+ start_no_gc_success = 0,
+ start_no_gc_no_memory = 1,
+ start_no_gc_too_large = 2,
+ start_no_gc_in_progress = 3
+};
+
+enum end_no_gc_region_status
+{
+ end_no_gc_success = 0,
+ end_no_gc_not_in_progress = 1,
+ end_no_gc_induced = 2,
+ end_no_gc_alloc_exceeded = 3
+};
+
+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 (* 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);
+
+// IGCHeap is the interface that the VM will use when interacting with the GC.
+class IGCHeap {
+public:
+ /*
+ ===========================================================================
+ Hosting APIs. These are used by GC hosting. The code that
+ calls these methods may possibly be moved behind the interface -
+ today, the VM handles the setting of segment size and max gen 0 size.
+ (See src/vm/corehost.cpp)
+ ===========================================================================
+ */
+
+ // Returns whether or not the given size is a valid segment size.
+ 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;
+
+ // Gets a valid segment size.
+ virtual size_t GetValidSegmentSize(BOOL large_seg = FALSE) = 0;
+
+ // Sets the limit for reserved virtual memory.
+ virtual void SetReservedVMLimit(size_t vmlimit) = 0;
+
+ /*
+ ===========================================================================
+ Concurrent GC routines. These are used in various places in the VM
+ to synchronize with the GC, when the VM wants to update something that
+ the GC is potentially using, if it's doing a background GC.
+
+ Concrete examples of this are moving async pinned handles across appdomains
+ and profiling/ETW scenarios.
+ ===========================================================================
+ */
+
+ // Blocks until any running concurrent GCs complete.
+ virtual void WaitUntilConcurrentGCComplete() = 0;
+
+ // Returns true if a concurrent GC is in progress, false otherwise.
+ virtual BOOL IsConcurrentGCInProgress() = 0;
+
+ // Temporarily enables concurrent GC, used during profiling.
+ virtual void TemporaryEnableConcurrentGC() = 0;
+
+ // Temporarily disables concurrent GC, used during profiling.
+ virtual void TemporaryDisableConcurrentGC() = 0;
+
+ // Returns whether or not Concurrent GC is enabled.
+ 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
+
+
+ /*
+ ===========================================================================
+ Finalization routines. These are used by the finalizer thread to communicate
+ with the GC.
+ ===========================================================================
+ */
+
+ // Finalizes an app domain by finalizing objects within that app domain.
+ 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;
+
+ // 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;
+
+ // Gets the next finalizable object.
+ virtual Object* GetNextFinalizable() = 0;
+
+ /*
+ ===========================================================================
+ BCL routines. These are routines that are directly exposed by mscorlib
+ as a part of the `System.GC` class. These routines behave in the same
+ manner as the functions on `System.GC`.
+ ===========================================================================
+ */
+
+ // Gets the current GC latency mode.
+ virtual int GetGcLatencyMode() = 0;
+
+ // Sets the current GC latency mode. newLatencyMode has already been
+ // verified by mscorlib to be valid.
+ virtual int SetGcLatencyMode(int newLatencyMode) = 0;
+
+ // Gets the current LOH compaction mode.
+ virtual int GetLOHCompactionMode() = 0;
+
+ // Sets the current LOH compaction mode. newLOHCompactionMode has
+ // already been verified by mscorlib to be valid.
+ virtual void SetLOHCompactionMode(int newLOHCompactionMode) = 0;
+
+ // 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;
+
+ // Cancels a full GC notification that was requested by `RegisterForFullGCNotification`.
+ 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.
+ virtual int WaitForFullGCApproach(int millisecondsTimeout) = 0;
+
+ // Returns the status of a registered notification for determining whether a blocking
+ // Gen 2 collection has completed, with the given timeout.
+ virtual int WaitForFullGCComplete(int millisecondsTimeout) = 0;
+
+ // Returns the generation in which obj is found. Also used by the VM
+ // in some places, in particular syncblk code.
+ virtual unsigned WhichGeneration(Object* obj) = 0;
+
+ // Returns the number of GCs that have transpired in the given generation
+ // since the beginning of the life of the process. Also used by the VM
+ // for debug code and app domains.
+ virtual int CollectionCount(int generation, int get_bgc_fgc_coutn = 0) = 0;
+
+ // 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;
+
+ // Exits a no-GC region.
+ virtual int EndNoGCRegion() = 0;
+
+ // Gets the total number of bytes in use.
+ virtual size_t GetTotalBytesInUse() = 0;
+
+ // 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;
+
+ // Gets the largest GC generation. Also used extensively throughout the VM.
+ virtual unsigned GetMaxGeneration() = 0;
+
+ // Indicates that an object's finalizer should not be run upon the object's collection.
+ virtual void SetFinalizationRun(Object* obj) = 0;
+
+ // Indicates that an object's finalizer should be run upon the object's collection.
+ virtual bool RegisterForFinalization(int gen, Object* obj) = 0;
+
+ /*
+ ===========================================================================
+ Miscellaneous routines used by the VM.
+ ===========================================================================
+ */
+
+ // Initializes the GC heap, returning whether or not the initialization
+ // was successful.
+ virtual HRESULT Initialize() = 0;
+
+ // Returns whether nor this GC was promoted by the last GC.
+ 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;
+
+ // 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;
+
+ // Returns the number of GCs that have occured. Mainly used for
+ // sanity checks asserting that a GC has not occured.
+ virtual unsigned GetGcCount() = 0;
+
+ // Sets cards after an object has been memmoved.
+ virtual void SetCardsAfterBulkCopy(Object** obj, size_t length) = 0;
+
+ // Gets whether or not the home heap of this alloc context matches the heap
+ // associated with this thread.
+ 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;
+
+ // Blocks until a GC is complete, returning a code indicating the wait was successful.
+ 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;
+
+ // 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;
+
+ /*
+ ============================================================================
+ Add/RemoveMemoryPressure support routines. These are on the interface
+ for now, but we should move Add/RemoveMemoryPressure from the VM to the GC.
+ When that occurs, these three routines can be removed from the interface.
+ ============================================================================
+ */
+
+ // Get the timestamp corresponding to the last GC that occured for the
+ // given generation.
+ virtual size_t GetLastGCStartTime(int generation) = 0;
+
+ // Gets the duration of the last GC that occured for the given generation.
+ virtual size_t GetLastGCDuration(int generation) = 0;
+
+ // Gets a timestamp for the current moment in time.
+ virtual size_t GetNow() = 0;
+
+ /*
+ ===========================================================================
+ Allocation routines. These all call into the GC's allocator and may trigger a garbage
+ collection. All allocation routines return NULL when the allocation request
+ couldn't be serviced due to being out of memory.
+ ===========================================================================
+ */
+
+ // Allocates an object on the given allocation context with the given size and flags.
+ 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;
+
+ // 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.
+ virtual void PublishObject(uint8_t* obj) = 0;
+
+ // Gets the event that suspended threads will use to wait for the
+ // end of a GC.
+ virtual CLREventStatic* GetWaitForGCEvent() = 0;
+
+ /*
+ ===========================================================================
+ Heap verification routines. These are used during heap verification only.
+ ===========================================================================
+ */
+ // Returns whether or not this object is in the fixed heap.
+ virtual BOOL IsObjectInFixedHeap(Object* pObj) = 0;
+
+ // Walks an object and validates its members.
+ virtual void ValidateObjectMember(Object* obj) = 0;
+
+ // Retrieves the next object after the given object. When the EE
+ // is not suspended, the result is not accurate - if the input argument
+ // is in Gen0, the function could return zeroed out memory as the next object.
+ virtual Object* NextObj(Object* object) = 0;
+
+ // 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;
+
+ /*
+ ===========================================================================
+ Profiling routines. Used for event tracing and profiling to broadcast
+ information regarding the heap.
+ ===========================================================================
+ */
+
+ // Walks an object, invoking a callback on each member.
+ 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;
+
+ // 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;
+
+ // Walks the finalization queue.
+ virtual void DiagWalkFinalizeQueue(void* gc_context, fq_walk_fn fn) = 0;
+
+ // Scan roots on finalizer queue. This is a generic function.
+ virtual void DiagScanFinalizeQueue(fq_scan_fn fn, ScanContext* context) = 0;
+
+ // Scan handles for profiling or ETW.
+ virtual void DiagScanHandles(handle_scan_fn fn, int gen_number, ScanContext* context) = 0;
+
+ // Scan dependent handles for profiling or ETW.
+ virtual void DiagScanDependentHandles(handle_scan_fn fn, int gen_number, ScanContext* context) = 0;
+
+ // Describes all generations to the profiler, invoking a callback on each generation.
+ virtual void DiagDescrGenerations(gen_walk_fn fn, void* context) = 0;
+
+ // Traces all GC segments and fires ETW events with information on them.
+ virtual void DiagTraceGCSegments() = 0;
+
+ /*
+ ===========================================================================
+ GC Stress routines. Used only when running under GC Stress.
+ ===========================================================================
+ */
+
+ // Returns TRUE if GC actually happens, otherwise FALSE
+ virtual BOOL StressHeap(gc_alloc_context* acontext = 0) = 0;
+
+ /*
+ ===========================================================================
+ Routines to register read only segments for frozen objects.
+ Only valid if FEATURE_BASICFREEZE is defined.
+ ===========================================================================
+ */
+
+ // Registers a frozen segment with the GC.
+ virtual segment_handle RegisterFrozenSegment(segment_info *pseginfo) = 0;
+
+ // Unregisters a frozen segment.
+ virtual void UnregisterFrozenSegment(segment_handle seg) = 0;
+
+ 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
+void updateGCShadow(Object** ptr, Object* val);
+#endif
+
+//constants for the flags parameter to the gc call back
+
+#define GC_CALL_INTERIOR 0x1
+#define GC_CALL_PINNED 0x2
+#define GC_CALL_CHECK_APP_DOMAIN 0x4
+
+//flags for IGCHeapAlloc(...)
+#define GC_ALLOC_FINALIZE 0x1
+#define GC_ALLOC_CONTAINS_REF 0x2
+#define GC_ALLOC_ALIGN8_BIAS 0x4
+#define GC_ALLOC_ALIGN8 0x8
+
+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
+#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
+
+#ifndef FEATURE_REDHAWK
+#if defined(GC_PROFILING) || defined (DACCESS_COMPILE)
+ MethodDesc *pMD;
+#endif //GC_PROFILING || DACCESS_COMPILE
+#endif // FEATURE_REDHAWK
+#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+ EtwGCRootKind dwEtwRootKind;
+#endif // GC_PROFILING || FEATURE_EVENT_TRACE
+
+ ScanContext()
+ {
+ LIMITED_METHOD_CONTRACT;
+
+ thread_under_crawl = 0;
+ thread_number = -1;
+ stack_limit = 0;
+ promotion = FALSE;
+ concurrent = FALSE;
+#ifdef GC_PROFILING
+ pMD = NULL;
+#endif //GC_PROFILING
+#ifdef FEATURE_EVENT_TRACE
+ dwEtwRootKind = kEtwGCRootKindOther;
+#endif // FEATURE_EVENT_TRACE
+ }
+};
+
+#endif // _GC_INTERFACE_H_
diff --git a/src/gc/gcpriv.h b/src/gc/gcpriv.h
index 03a23454a0..3bed8c2cf8 100644
--- a/src/gc/gcpriv.h
+++ b/src/gc/gcpriv.h
@@ -24,7 +24,9 @@
inline void FATAL_GC_ERROR()
{
+#ifndef DACCESS_COMPILE
GCToOSInterface::DebugBreak();
+#endif // DACCESS_COMPILE
_ASSERTE(!"Fatal Error in GC.");
EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE);
}
@@ -1073,9 +1075,6 @@ enum interesting_data_point
};
//class definition of the internal class
-#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
-extern void GCProfileWalkHeapWorker(BOOL fProfilerPinned, BOOL fShouldWalkHeapRootsForEtw, BOOL fShouldWalkHeapObjectsForEtw);
-#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
class gc_heap
{
friend struct ::_DacGlobals;
@@ -1225,7 +1224,7 @@ public:
static
gc_heap* balance_heaps_loh (alloc_context* acontext, size_t size);
static
- void __stdcall gc_thread_stub (void* arg);
+ void gc_thread_stub (void* arg);
#endif //MULTIPLE_HEAPS
CObjectHeader* try_fast_alloc (size_t jsize);
@@ -1283,35 +1282,48 @@ public:
protected:
- PER_HEAP
+ PER_HEAP_ISOLATED
void walk_heap (walk_fn fn, void* context, int gen_number, BOOL walk_large_object_heap_p);
+ PER_HEAP
+ void walk_heap_per_heap (walk_fn fn, void* context, int gen_number, BOOL walk_large_object_heap_p);
+
struct walk_relocate_args
{
uint8_t* last_plug;
BOOL is_shortened;
mark* pinned_plug_entry;
+ size_t profiling_context;
+ record_surv_fn fn;
};
PER_HEAP
+ void walk_survivors (record_surv_fn fn, size_t 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, size_t profiling_context);
+ walk_relocate_args* args);
PER_HEAP
- void walk_relocation (int condemned_gen_number,
- uint8_t* first_condemned_address, size_t profiling_context);
+ void walk_relocation (size_t profiling_context, record_surv_fn fn);
PER_HEAP
- void walk_relocation_in_brick (uint8_t* tree, walk_relocate_args* args, size_t profiling_context);
+ void walk_relocation_in_brick (uint8_t* tree, walk_relocate_args* args);
-#if defined(BACKGROUND_GC) && defined(FEATURE_EVENT_TRACE)
PER_HEAP
- void walk_relocation_for_bgc(size_t profiling_context);
+ void walk_finalize_queue (fq_walk_fn fn);
+#if defined(BACKGROUND_GC) && defined(FEATURE_EVENT_TRACE)
PER_HEAP
- void make_free_lists_for_profiler_for_bgc();
+ void walk_survivors_for_bgc (size_t 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);
+ PER_HEAP
+ void walk_survivors_for_loh (size_t profiling_context, record_surv_fn fn);
+
PER_HEAP
int generation_to_condemn (int n,
BOOL* blocking_collection_p,
@@ -2148,10 +2160,8 @@ protected:
PER_HEAP
void relocate_in_loh_compact();
-#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
PER_HEAP
- void walk_relocation_loh (size_t profiling_context);
-#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+ void walk_relocation_for_loh (size_t profiling_context, record_surv_fn fn);
PER_HEAP
BOOL loh_enque_pinned_plug (uint8_t* plug, size_t len);
@@ -2547,14 +2557,8 @@ protected:
PER_HEAP
void descr_generations (BOOL begin_gc_p);
-#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
PER_HEAP_ISOLATED
void descr_generations_to_profiler (gen_walk_fn fn, void *context);
- PER_HEAP
- void record_survived_for_profiler(int condemned_gen_number, uint8_t * first_condemned_address);
- PER_HEAP
- void notify_profiler_of_surviving_large_objects ();
-#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
/*------------ Multiple non isolated heaps ----------------*/
#ifdef MULTIPLE_HEAPS
@@ -2978,7 +2982,7 @@ protected:
PER_HEAP
VOLATILE(int) alloc_context_count;
#else //MULTIPLE_HEAPS
-#define vm_heap ((GCHeap*) g_pGCHeap)
+#define vm_heap ((GCHeap*) g_theGCHeap)
#define heap_number (0)
#endif //MULTIPLE_HEAPS
@@ -3763,9 +3767,7 @@ public:
Object* GetNextFinalizableObject (BOOL only_non_critical=FALSE);
BOOL ScanForFinalization (promote_func* fn, int gen,BOOL mark_only_p, gc_heap* hp);
void RelocateFinalizationData (int gen, gc_heap* hp);
-#ifdef GC_PROFILING
- void WalkFReachableObjects (gc_heap* hp);
-#endif //GC_PROFILING
+ void WalkFReachableObjects (fq_walk_fn fn);
void GcScanRoots (promote_func* fn, int hn, ScanContext *pSC);
void UpdatePromotedGenerations (int gen, BOOL gen_0_empty_p);
size_t GetPromotedCount();
@@ -4073,8 +4075,6 @@ size_t generation_unusable_fragmentation (generation* inst)
}
#define plug_skew sizeof(ObjHeader)
-#define min_obj_size (sizeof(uint8_t*)+plug_skew+sizeof(size_t))//syncblock + vtable+ first field
-//Note that this encodes the fact that plug_skew is a multiple of uint8_t*.
// We always use USE_PADDING_TAIL when fitting so items on the free list should be
// twice the min_obj_size.
#define min_free_list (2*min_obj_size)
@@ -4319,9 +4319,6 @@ dynamic_data* gc_heap::dynamic_data_of (int gen_number)
return &dynamic_data_table [ gen_number ];
}
-extern "C" uint8_t* g_ephemeral_low;
-extern "C" uint8_t* g_ephemeral_high;
-
#define card_word_width ((size_t)32)
//
diff --git a/src/gc/gcrecord.h b/src/gc/gcrecord.h
index 8c95ad04d3..fff1fc5c8b 100644
--- a/src/gc/gcrecord.h
+++ b/src/gc/gcrecord.h
@@ -13,7 +13,7 @@ Module Name:
#ifndef __gc_record_h__
#define __gc_record_h__
-#define max_generation 2
+//#define max_generation 2
// We pack the dynamic tuning for deciding which gen to condemn in a uint32_t.
// We assume that 2 bits are enough to represent the generation.
diff --git a/src/gc/gcscan.cpp b/src/gc/gcscan.cpp
index 42989e0414..b4e6352dd6 100644
--- a/src/gc/gcscan.cpp
+++ b/src/gc/gcscan.cpp
@@ -129,7 +129,7 @@ static void CALLBACK CheckPromoted(_UNCHECKED_OBJECTREF *pObjRef, uintptr_t * /*
LOG((LF_GC, LL_INFO100000, LOG_HANDLE_OBJECT_CLASS("Checking referent of Weak-", pObjRef, "to ", *pObjRef)));
Object **pRef = (Object **)pObjRef;
- if (!GCHeap::GetGCHeap()->IsPromoted(*pRef))
+ if (!g_theGCHeap->IsPromoted(*pRef))
{
LOG((LF_GC, LL_INFO100, LOG_HANDLE_OBJECT_CLASS("Severing Weak-", pObjRef, "to unreachable ", *pObjRef)));
@@ -192,33 +192,32 @@ void GCScan::GcScanHandles (promote_func* fn, int condemned, int max_gen,
}
}
-
-#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
-
/*
* Scan all handle roots in this 'namespace' for profiling
*/
-void GCScan::GcScanHandlesForProfilerAndETW (int max_gen, ScanContext* sc)
+void GCScan::GcScanHandlesForProfilerAndETW (int max_gen, ScanContext* sc, handle_scan_fn fn)
{
LIMITED_METHOD_CONTRACT;
+#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
LOG((LF_GC|LF_GCROOTS, LL_INFO10, "Profiler Root Scan Phase, Handles\n"));
- Ref_ScanPointersForProfilerAndETW(max_gen, (uintptr_t)sc);
+ Ref_ScanHandlesForProfilerAndETW(max_gen, (uintptr_t)sc, fn);
+#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
}
/*
* Scan dependent handles in this 'namespace' for profiling
*/
-void GCScan::GcScanDependentHandlesForProfilerAndETW (int max_gen, ProfilingScanContext* sc)
+void GCScan::GcScanDependentHandlesForProfilerAndETW (int max_gen, ScanContext* sc, handle_scan_fn fn)
{
LIMITED_METHOD_CONTRACT;
+#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
LOG((LF_GC|LF_GCROOTS, LL_INFO10, "Profiler Root Scan Phase, DependentHandles\n"));
- Ref_ScanDependentHandlesForProfilerAndETW(max_gen, sc);
-}
-
+ Ref_ScanDependentHandlesForProfilerAndETW(max_gen, sc, fn);
#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+}
void GCScan::GcRuntimeStructuresValid (BOOL bValid)
{
@@ -240,14 +239,14 @@ void GCScan::GcRuntimeStructuresValid (BOOL bValid)
void GCScan::GcDemote (int condemned, int max_gen, ScanContext* sc)
{
Ref_RejuvenateHandles (condemned, max_gen, (uintptr_t)sc);
- if (!GCHeap::IsServerHeap() || sc->thread_number == 0)
+ if (!IsServerHeap() || sc->thread_number == 0)
GCToEEInterface::SyncBlockCacheDemote(max_gen);
}
void GCScan::GcPromotionsGranted (int condemned, int max_gen, ScanContext* sc)
{
Ref_AgeHandles(condemned, max_gen, (uintptr_t)sc);
- if (!GCHeap::IsServerHeap() || sc->thread_number == 0)
+ if (!IsServerHeap() || sc->thread_number == 0)
GCToEEInterface::SyncBlockCachePromotionsGranted(max_gen);
}
diff --git a/src/gc/gcscan.h b/src/gc/gcscan.h
index 3515b8e1b6..362370fa4a 100644
--- a/src/gc/gcscan.h
+++ b/src/gc/gcscan.h
@@ -52,10 +52,8 @@ class GCScan
static void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
#endif // DACCESS_COMPILE
-#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
- static void GcScanHandlesForProfilerAndETW (int max_gen, ScanContext* sc);
- static void GcScanDependentHandlesForProfilerAndETW (int max_gen, ProfilingScanContext* sc);
-#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+ static void GcScanHandlesForProfilerAndETW (int max_gen, ScanContext* sc, handle_scan_fn fn);
+ static void GcScanDependentHandlesForProfilerAndETW (int max_gen, ScanContext* sc, handle_scan_fn fn);
// scan for dead weak pointers
static void GcWeakPtrScan (promote_func* fn, int condemned, int max_gen, ScanContext*sc );
diff --git a/src/gc/handletable.cpp b/src/gc/handletable.cpp
index 43b43ffcea..29ee435b51 100644
--- a/src/gc/handletable.cpp
+++ b/src/gc/handletable.cpp
@@ -755,7 +755,7 @@ void HndLogSetEvent(OBJECTHANDLE handle, _UNCHECKED_OBJECTREF value)
uint32_t hndType = HandleFetchType(handle);
ADIndex appDomainIndex = HndGetHandleADIndex(handle);
AppDomain* pAppDomain = SystemDomain::GetAppDomainAtIndex(appDomainIndex);
- uint32_t generation = value != 0 ? GCHeap::GetGCHeap()->WhichGeneration(value) : 0;
+ uint32_t generation = value != 0 ? g_theGCHeap->WhichGeneration(value) : 0;
FireEtwSetGCHandle((void*) handle, value, hndType, generation, (int64_t) pAppDomain, GetClrInstanceId());
FireEtwPrvSetGCHandle((void*) handle, value, hndType, generation, (int64_t) pAppDomain, GetClrInstanceId());
@@ -774,14 +774,14 @@ void HndLogSetEvent(OBJECTHANDLE handle, _UNCHECKED_OBJECTREF value)
for (size_t i = 0; i < num; i ++)
{
value = ppObj[i];
- uint32_t generation = value != 0 ? GCHeap::GetGCHeap()->WhichGeneration(value) : 0;
+ uint32_t generation = value != 0 ? g_theGCHeap->WhichGeneration(value) : 0;
FireEtwSetGCHandle(overlapped, value, HNDTYPE_PINNED, generation, (int64_t) pAppDomain, GetClrInstanceId());
}
}
else
{
value = OBJECTREF_TO_UNCHECKED_OBJECTREF(overlapped->m_userObject);
- uint32_t generation = value != 0 ? GCHeap::GetGCHeap()->WhichGeneration(value) : 0;
+ uint32_t generation = value != 0 ? g_theGCHeap->WhichGeneration(value) : 0;
FireEtwSetGCHandle(overlapped, value, HNDTYPE_PINNED, generation, (int64_t) pAppDomain, GetClrInstanceId());
}
}
@@ -838,7 +838,7 @@ void HndWriteBarrier(OBJECTHANDLE handle, OBJECTREF objref)
if (*pClumpAge != 0) // Perf optimization: if clumpAge is 0, nothing more to do
{
// find out generation
- int generation = GCHeap::GetGCHeap()->WhichGeneration(value);
+ int generation = g_theGCHeap->WhichGeneration(value);
uint32_t uType = HandleFetchType(handle);
#ifndef FEATURE_REDHAWK
diff --git a/src/gc/handletablecache.cpp b/src/gc/handletablecache.cpp
index b2af40c829..aaf3370bd6 100644
--- a/src/gc/handletablecache.cpp
+++ b/src/gc/handletablecache.cpp
@@ -15,6 +15,12 @@
#include "gcenv.h"
+#ifdef Sleep // TODO(segilles)
+#undef Sleep
+#endif // Sleep
+
+#include "env/gcenv.os.h"
+
#include "handletablepriv.h"
/****************************************************************************
diff --git a/src/gc/handletablecore.cpp b/src/gc/handletablecore.cpp
index 5e077de8a2..5776c26ace 100644
--- a/src/gc/handletablecore.cpp
+++ b/src/gc/handletablecore.cpp
@@ -14,6 +14,7 @@
#include "common.h"
#include "gcenv.h"
+#include "gc.h"
#ifndef FEATURE_REDHAWK
#include "nativeoverlapped.h"
@@ -610,7 +611,7 @@ TableSegment *SegmentAlloc(HandleTable *pTable)
_ASSERTE(HANDLE_SEGMENT_ALIGNMENT >= HANDLE_SEGMENT_SIZE);
_ASSERTE(HANDLE_SEGMENT_ALIGNMENT == 0x10000);
- pSegment = (TableSegment *)GCToOSInterface::VirtualReserve(NULL, HANDLE_SEGMENT_SIZE, HANDLE_SEGMENT_ALIGNMENT, VirtualReserveFlags::None);
+ pSegment = (TableSegment *)GCToOSInterface::VirtualReserve(HANDLE_SEGMENT_SIZE, HANDLE_SEGMENT_ALIGNMENT, VirtualReserveFlags::None);
_ASSERTE(((size_t)pSegment % HANDLE_SEGMENT_ALIGNMENT) == 0);
// bail out if we couldn't get any memory
@@ -1111,13 +1112,13 @@ SLOW_PATH:
// we have the lock held but the part we care about (the async table scan) takes the table lock during
// a preparation step so we'll be able to complete our segment moves before the async scan has a
// chance to interfere with us (or vice versa).
- if (GCHeap::GetGCHeap()->IsConcurrentGCInProgress())
+ if (g_theGCHeap->IsConcurrentGCInProgress())
{
// A concurrent GC is in progress so someone might be scanning our segments asynchronously.
// Release the lock, wait for the GC to complete and try again. The order is important; if we wait
// before releasing the table lock we can deadlock with an async table scan.
ch.Release();
- GCHeap::GetGCHeap()->WaitUntilConcurrentGCComplete();
+ g_theGCHeap->WaitUntilConcurrentGCComplete();
continue;
}
diff --git a/src/gc/handletablescan.cpp b/src/gc/handletablescan.cpp
index 863b5a52b0..86ce62d5b1 100644
--- a/src/gc/handletablescan.cpp
+++ b/src/gc/handletablescan.cpp
@@ -818,7 +818,7 @@ void BlockResetAgeMapForBlocksWorker(uint32_t *pdwGen, uint32_t dwClumpMask, Sca
{
if (!HndIsNullOrDestroyedHandle(*pValue))
{
- int thisAge = GCHeap::GetGCHeap()->WhichGeneration(*pValue);
+ int thisAge = g_theGCHeap->WhichGeneration(*pValue);
if (minAge > thisAge)
minAge = thisAge;
@@ -830,7 +830,7 @@ void BlockResetAgeMapForBlocksWorker(uint32_t *pdwGen, uint32_t dwClumpMask, Sca
if (pOverlapped->m_userObject != NULL)
{
Object * pUserObject = OBJECTREFToObject(pOverlapped->m_userObject);
- thisAge = GCHeap::GetGCHeap()->WhichGeneration(pUserObject);
+ thisAge = g_theGCHeap->WhichGeneration(pUserObject);
if (minAge > thisAge)
minAge = thisAge;
if (pOverlapped->m_isArray)
@@ -840,7 +840,7 @@ void BlockResetAgeMapForBlocksWorker(uint32_t *pdwGen, uint32_t dwClumpMask, Sca
size_t num = pUserArrayObject->GetNumComponents();
for (size_t i = 0; i < num; i ++)
{
- thisAge = GCHeap::GetGCHeap()->WhichGeneration(pObj[i]);
+ thisAge = g_theGCHeap->WhichGeneration(pObj[i]);
if (minAge > thisAge)
minAge = thisAge;
}
@@ -925,10 +925,10 @@ static void VerifyObjectAndAge(_UNCHECKED_OBJECTREF *pValue, _UNCHECKED_OBJECTRE
UNREFERENCED_PARAMETER(pValue);
VerifyObject(from, obj);
- int thisAge = GCHeap::GetGCHeap()->WhichGeneration(obj);
+ int thisAge = g_theGCHeap->WhichGeneration(obj);
//debugging code
- //if (minAge > thisAge && thisAge < GCHeap::GetGCHeap()->GetMaxGeneration())
+ //if (minAge > thisAge && thisAge < g_theGCHeap->GetMaxGeneration())
//{
// if ((*pValue) == obj)
// printf("Handle (age %u) %p -> %p (age %u)", minAge, pValue, obj, thisAge);
@@ -946,7 +946,7 @@ static void VerifyObjectAndAge(_UNCHECKED_OBJECTREF *pValue, _UNCHECKED_OBJECTRE
// }
//}
- if (minAge >= GEN_MAX_AGE || (minAge > thisAge && thisAge < static_cast<int>(GCHeap::GetGCHeap()->GetMaxGeneration())))
+ if (minAge >= GEN_MAX_AGE || (minAge > thisAge && thisAge < static_cast<int>(g_theGCHeap->GetMaxGeneration())))
{
_ASSERTE(!"Fatal Error in HandleTable.");
EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE);
diff --git a/src/gc/objecthandle.cpp b/src/gc/objecthandle.cpp
index 74a8a71c5e..e8eed93006 100644
--- a/src/gc/objecthandle.cpp
+++ b/src/gc/objecthandle.cpp
@@ -95,7 +95,7 @@ void CALLBACK PromoteRefCounted(_UNCHECKED_OBJECTREF *pObjRef, uintptr_t *pExtra
Object *pOldObj = pObj;
#endif
- if (!HndIsNullOrDestroyedHandle(pObj) && !GCHeap::GetGCHeap()->IsPromoted(pObj))
+ if (!HndIsNullOrDestroyedHandle(pObj) && !g_theGCHeap->IsPromoted(pObj))
{
if (GCToEEInterface::RefCountedHandleCallbacks(pObj))
{
@@ -110,6 +110,21 @@ void CALLBACK PromoteRefCounted(_UNCHECKED_OBJECTREF *pObjRef, uintptr_t *pExtra
}
#endif // FEATURE_COMINTEROP || FEATURE_REDHAWK
+
+// Only used by profiling/ETW.
+//----------------------------------------------------------------------------
+
+/*
+ * struct DIAG_DEPSCANINFO
+ *
+ * used when tracing dependent handles for profiling/ETW.
+ */
+struct DIAG_DEPSCANINFO
+{
+ HANDLESCANPROC pfnTrace; // tracing function to use
+ uintptr_t pfnProfilingOrETW;
+};
+
void CALLBACK TraceDependentHandle(_UNCHECKED_OBJECTREF *pObjRef, uintptr_t *pExtraInfo, uintptr_t lp1, uintptr_t lp2)
{
WRAPPER_NO_CONTRACT;
@@ -122,14 +137,15 @@ void CALLBACK TraceDependentHandle(_UNCHECKED_OBJECTREF *pObjRef, uintptr_t *pEx
// object should also be non-NULL.
_ASSERTE(*pExtraInfo == NULL || *pObjRef != NULL);
- // lp2 is a HANDLESCANPROC
- HANDLESCANPROC pfnTrace = (HANDLESCANPROC) lp2;
+ struct DIAG_DEPSCANINFO *pInfo = (struct DIAG_DEPSCANINFO*)lp2;
+
+ HANDLESCANPROC pfnTrace = pInfo->pfnTrace;
// is the handle's secondary object non-NULL?
if ((*pObjRef != NULL) && (*pExtraInfo != 0))
{
// yes - call the tracing function for this handle
- pfnTrace(pObjRef, NULL, lp1, *pExtraInfo);
+ pfnTrace(pObjRef, NULL, lp1, (uintptr_t)(pInfo->pfnProfilingOrETW));
}
}
@@ -186,9 +202,9 @@ void CALLBACK PromoteDependentHandle(_UNCHECKED_OBJECTREF *pObjRef, uintptr_t *p
ScanContext *sc = (ScanContext*)lp1;
DhContext *pDhContext = Ref_GetDependentHandleContext(sc);
- if (*pObjRef && GCHeap::GetGCHeap()->IsPromoted(*pPrimaryRef))
+ if (*pObjRef && g_theGCHeap->IsPromoted(*pPrimaryRef))
{
- if (!GCHeap::GetGCHeap()->IsPromoted(*pSecondaryRef))
+ if (!g_theGCHeap->IsPromoted(*pSecondaryRef))
{
LOG((LF_GC|LF_ENC, LL_INFO10000, "\tPromoting secondary " LOG_OBJECT_CLASS(*pSecondaryRef)));
_ASSERTE(lp2);
@@ -221,7 +237,7 @@ void CALLBACK ClearDependentHandle(_UNCHECKED_OBJECTREF *pObjRef, uintptr_t *pEx
LOG((LF_GC|LF_ENC, LL_INFO1000, LOG_HANDLE_OBJECT_CLASS("\tPrimary:\t", pPrimaryRef, "to ", *pPrimaryRef)));
LOG((LF_GC|LF_ENC, LL_INFO1000, LOG_HANDLE_OBJECT_CLASS("\tSecondary\t", pSecondaryRef, "to ", *pSecondaryRef)));
- if (!GCHeap::GetGCHeap()->IsPromoted(*pPrimaryRef))
+ if (!g_theGCHeap->IsPromoted(*pPrimaryRef))
{
LOG((LF_GC|LF_ENC, LL_INFO1000, "\tunreachable ", LOG_OBJECT_CLASS(*pPrimaryRef)));
LOG((LF_GC|LF_ENC, LL_INFO1000, "\tunreachable ", LOG_OBJECT_CLASS(*pSecondaryRef)));
@@ -230,7 +246,7 @@ void CALLBACK ClearDependentHandle(_UNCHECKED_OBJECTREF *pObjRef, uintptr_t *pEx
}
else
{
- _ASSERTE(GCHeap::GetGCHeap()->IsPromoted(*pSecondaryRef));
+ _ASSERTE(g_theGCHeap->IsPromoted(*pSecondaryRef));
LOG((LF_GC|LF_ENC, LL_INFO10000, "\tPrimary is reachable " LOG_OBJECT_CLASS(*pPrimaryRef)));
LOG((LF_GC|LF_ENC, LL_INFO10000, "\tSecondary is reachable " LOG_OBJECT_CLASS(*pSecondaryRef)));
}
@@ -330,7 +346,7 @@ void CALLBACK CheckPromoted(_UNCHECKED_OBJECTREF *pObjRef, uintptr_t *pExtraInfo
LOG((LF_GC, LL_INFO100000, LOG_HANDLE_OBJECT_CLASS("Checking referent of Weak-", pObjRef, "to ", *pObjRef)));
Object **ppRef = (Object **)pObjRef;
- if (!GCHeap::GetGCHeap()->IsPromoted(*ppRef))
+ if (!g_theGCHeap->IsPromoted(*ppRef))
{
LOG((LF_GC, LL_INFO100, LOG_HANDLE_OBJECT_CLASS("Severing Weak-", pObjRef, "to unreachable ", *pObjRef)));
@@ -355,9 +371,9 @@ void CALLBACK CalculateSizedRefSize(_UNCHECKED_OBJECTREF *pObjRef, uintptr_t *pE
ScanContext* sc = (ScanContext *)lp1;
promote_func* callback = (promote_func*) lp2;
- size_t sizeBegin = GCHeap::GetGCHeap()->GetPromotedBytes(sc->thread_number);
+ size_t sizeBegin = g_theGCHeap->GetPromotedBytes(sc->thread_number);
callback(ppSizedRef, (ScanContext *)lp1, 0);
- size_t sizeEnd = GCHeap::GetGCHeap()->GetPromotedBytes(sc->thread_number);
+ size_t sizeEnd = g_theGCHeap->GetPromotedBytes(sc->thread_number);
*pSize = sizeEnd - sizeBegin;
}
@@ -414,7 +430,7 @@ void CALLBACK ScanPointerForProfilerAndETW(_UNCHECKED_OBJECTREF *pObjRef, uintpt
CONTRACTL_END;
#endif // FEATURE_REDHAWK
UNREFERENCED_PARAMETER(pExtraInfo);
- UNREFERENCED_PARAMETER(lp2);
+ handle_scan_fn fn = (handle_scan_fn)lp2;
LOG((LF_GC | LF_CORPROF, LL_INFO100000, LOG_HANDLE_OBJECT_CLASS("Notifying profiler of ", pObjRef, "to ", *pObjRef)));
@@ -422,7 +438,7 @@ void CALLBACK ScanPointerForProfilerAndETW(_UNCHECKED_OBJECTREF *pObjRef, uintpt
Object **pRef = (Object **)pObjRef;
// Get a hold of the heap ID that's tacked onto the end of the scancontext struct.
- ProfilingScanContext *pSC = (ProfilingScanContext *)lp1;
+ ScanContext *pSC = (ScanContext *)lp1;
uint32_t rootFlags = 0;
BOOL isDependent = FALSE;
@@ -487,60 +503,15 @@ void CALLBACK ScanPointerForProfilerAndETW(_UNCHECKED_OBJECTREF *pObjRef, uintpt
_UNCHECKED_OBJECTREF pSec = NULL;
-#ifdef GC_PROFILING
- // Give the profiler the objectref.
- if (pSC->fProfilerPinned)
+ if (isDependent)
{
- if (!isDependent)
- {
- BEGIN_PIN_PROFILER(CORProfilerTrackGC());
- g_profControlBlock.pProfInterface->RootReference2(
- (uint8_t *)*pRef,
- kEtwGCRootKindHandle,
- (EtwGCRootFlags)rootFlags,
- pRef,
- &pSC->pHeapId);
- END_PIN_PROFILER();
- }
- else
- {
- BEGIN_PIN_PROFILER(CORProfilerTrackConditionalWeakTableElements());
- pSec = (_UNCHECKED_OBJECTREF)HndGetHandleExtraInfo(handle);
- g_profControlBlock.pProfInterface->ConditionalWeakTableElementReference(
- (uint8_t*)*pRef,
- (uint8_t*)pSec,
- pRef,
- &pSC->pHeapId);
- END_PIN_PROFILER();
- }
+ pSec = (_UNCHECKED_OBJECTREF)HndGetHandleExtraInfo(handle);
}
-#endif // GC_PROFILING
-
-#if defined(FEATURE_EVENT_TRACE)
- // Notify ETW of the handle
- if (ETW::GCLog::ShouldWalkHeapRootsForEtw())
- {
- if (isDependent && (pSec == NULL))
- {
- pSec = (_UNCHECKED_OBJECTREF)HndGetHandleExtraInfo(handle);
- }
-
- ETW::GCLog::RootReference(
- handle,
- *pRef, // object being rooted
- pSec, // pSecondaryNodeForDependentHandle
- isDependent,
- pSC,
- 0, // dwGCFlags,
- rootFlags); // ETW handle flags
- }
-#endif // defined(FEATURE_EVENT_TRACE)
+ fn(pRef, pSec, rootFlags, pSC, isDependent);
}
#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
-
-
/*
* Scan callback for updating pointers.
*
@@ -583,10 +554,10 @@ int getNumberOfSlots()
{
WRAPPER_NO_CONTRACT;
- // when Ref_Initialize called, GCHeap::GetNumberOfHeaps() is still 0, so use #procs as a workaround
+ // when Ref_Initialize called, IGCHeap::GetNumberOfHeaps() is still 0, so use #procs as a workaround
// it is legal since even if later #heaps < #procs we create handles by thread home heap
// and just have extra unused slots in HandleTableBuckets, which does not take a lot of space
- if (!GCHeap::IsServerHeap())
+ if (!IsServerHeap())
return 1;
#ifdef FEATURE_REDHAWK
@@ -874,7 +845,7 @@ int getSlotNumber(ScanContext* sc)
{
WRAPPER_NO_CONTRACT;
- return (GCHeap::IsServerHeap() ? sc->thread_number : 0);
+ return (IsServerHeap() ? sc->thread_number : 0);
}
// <TODO> - reexpress as complete only like hndtable does now!!! -fmh</REVISIT_TODO>
@@ -1152,7 +1123,7 @@ void Ref_TraceNormalRoots(uint32_t condemned, uint32_t maxgen, ScanContext* sc,
// promote objects pointed to by strong handles
// during ephemeral GCs we also want to promote the ones pointed to by sizedref handles.
uint32_t types[2] = {HNDTYPE_STRONG, HNDTYPE_SIZEDREF};
- uint32_t uTypeCount = (((condemned >= maxgen) && !GCHeap::GetGCHeap()->IsConcurrentGCInProgress()) ? 1 : _countof(types));
+ uint32_t uTypeCount = (((condemned >= maxgen) && !g_theGCHeap->IsConcurrentGCInProgress()) ? 1 : _countof(types));
uint32_t flags = (sc->concurrent) ? HNDGCF_ASYNC : HNDGCF_NORMAL;
HandleTableMap *walk = &g_HandleTableMap;
@@ -1417,13 +1388,15 @@ void Ref_ScanDependentHandlesForRelocation(uint32_t condemned, uint32_t maxgen,
/*
loop scan version of TraceVariableHandles for single-thread-managed Ref_* functions
should be kept in sync with the code above
+ Only used by profiling/ETW.
*/
-void TraceDependentHandlesBySingleThread(HANDLESCANPROC pfnTrace, uintptr_t lp1, uint32_t condemned, uint32_t maxgen, uint32_t flags)
+void TraceDependentHandlesBySingleThread(HANDLESCANPROC pfnTrace, uintptr_t lp1, uintptr_t lp2, uint32_t condemned, uint32_t maxgen, uint32_t flags)
{
WRAPPER_NO_CONTRACT;
// set up to scan variable handles with the specified mask and trace function
uint32_t type = HNDTYPE_DEPENDENT;
+ struct DIAG_DEPSCANINFO info = { pfnTrace, lp2 };
HandleTableMap *walk = &g_HandleTableMap;
while (walk) {
@@ -1436,14 +1409,13 @@ void TraceDependentHandlesBySingleThread(HANDLESCANPROC pfnTrace, uintptr_t lp1,
HHANDLETABLE hTable = walk->pBuckets[i]->pTable[uCPUindex];
if (hTable)
HndScanHandlesForGC(hTable, TraceDependentHandle,
- lp1, (uintptr_t)pfnTrace, &type, 1, condemned, maxgen, HNDGCF_EXTRAINFO | flags);
+ lp1, (uintptr_t)&info, &type, 1, condemned, maxgen, HNDGCF_EXTRAINFO | flags);
}
}
walk = walk->pNext;
}
}
-
// We scan handle tables by their buckets (ie, AD index). We could get into the situation where
// the AD indices are not very compacted (for example if we have just unloaded ADs and their
// indices haven't been reused yet) and we could be scanning them in an unbalanced fashion.
@@ -1454,7 +1426,7 @@ void ScanSizedRefByAD(uint32_t maxgen, HANDLESCANPROC scanProc, ScanContext* sc,
HandleTableMap *walk = &g_HandleTableMap;
uint32_t type = HNDTYPE_SIZEDREF;
int uCPUindex = getSlotNumber(sc);
- int n_slots = GCHeap::GetGCHeap()->GetNumberOfHeaps();
+ int n_slots = g_theGCHeap->GetNumberOfHeaps();
while (walk)
{
@@ -1574,11 +1546,11 @@ void Ref_UpdatePointers(uint32_t condemned, uint32_t maxgen, ScanContext* sc, Re
// @TODO cwb: wait for compelling performance measurements.</REVISIT_TODO>
BOOL bDo = TRUE;
- if (GCHeap::IsServerHeap())
+ if (IsServerHeap())
{
bDo = (Interlocked::Increment(&uCount) == 1);
- Interlocked::CompareExchange (&uCount, 0, GCHeap::GetGCHeap()->GetNumberOfHeaps());
- _ASSERTE (uCount <= GCHeap::GetGCHeap()->GetNumberOfHeaps());
+ Interlocked::CompareExchange (&uCount, 0, g_theGCHeap->GetNumberOfHeaps());
+ _ASSERTE (uCount <= g_theGCHeap->GetNumberOfHeaps());
}
if (bDo)
@@ -1623,7 +1595,7 @@ void Ref_UpdatePointers(uint32_t condemned, uint32_t maxgen, ScanContext* sc, Re
#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
// Please update this if you change the Ref_UpdatePointers function above.
-void Ref_ScanPointersForProfilerAndETW(uint32_t maxgen, uintptr_t lp1)
+void Ref_ScanHandlesForProfilerAndETW(uint32_t maxgen, uintptr_t lp1, handle_scan_fn fn)
{
WRAPPER_NO_CONTRACT;
@@ -1662,16 +1634,16 @@ void Ref_ScanPointersForProfilerAndETW(uint32_t maxgen, uintptr_t lp1)
{
HHANDLETABLE hTable = walk->pBuckets[i]->pTable[uCPUindex];
if (hTable)
- HndScanHandlesForGC(hTable, &ScanPointerForProfilerAndETW, lp1, 0, types, _countof(types), maxgen, maxgen, flags);
+ HndScanHandlesForGC(hTable, &ScanPointerForProfilerAndETW, lp1, (uintptr_t)fn, types, _countof(types), maxgen, maxgen, flags);
}
walk = walk->pNext;
}
// update pointers in variable handles whose dynamic type is VHT_WEAK_SHORT, VHT_WEAK_LONG or VHT_STRONG
- TraceVariableHandlesBySingleThread(&ScanPointerForProfilerAndETW, lp1, 0, VHT_WEAK_SHORT | VHT_WEAK_LONG | VHT_STRONG, maxgen, maxgen, flags);
+ TraceVariableHandlesBySingleThread(&ScanPointerForProfilerAndETW, lp1, (uintptr_t)fn, VHT_WEAK_SHORT | VHT_WEAK_LONG | VHT_STRONG, maxgen, maxgen, flags);
}
-void Ref_ScanDependentHandlesForProfilerAndETW(uint32_t maxgen, ProfilingScanContext * SC)
+void Ref_ScanDependentHandlesForProfilerAndETW(uint32_t maxgen, ScanContext * SC, handle_scan_fn fn)
{
WRAPPER_NO_CONTRACT;
@@ -1680,12 +1652,7 @@ void Ref_ScanDependentHandlesForProfilerAndETW(uint32_t maxgen, ProfilingScanCon
uint32_t flags = HNDGCF_NORMAL;
uintptr_t lp1 = (uintptr_t)SC;
- // we'll re-use pHeapId (which was either unused (0) or freed by EndRootReferences2
- // (-1)), so reset it to NULL
- _ASSERTE((*((size_t *)(&SC->pHeapId)) == (size_t)(-1)) ||
- (*((size_t *)(&SC->pHeapId)) == (size_t)(0)));
- SC->pHeapId = NULL;
- TraceDependentHandlesBySingleThread(&ScanPointerForProfilerAndETW, lp1, maxgen, maxgen, flags);
+ TraceDependentHandlesBySingleThread(&ScanPointerForProfilerAndETW, lp1, (uintptr_t)fn, maxgen, maxgen, flags);
}
#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
@@ -1906,9 +1873,9 @@ int GetCurrentThreadHomeHeapNumber()
{
WRAPPER_NO_CONTRACT;
- if (!GCHeap::IsGCHeapInitialized())
+ if (g_theGCHeap == nullptr)
return 0;
- return GCHeap::GetGCHeap()->GetHomeHeapNumber();
+ return g_theGCHeap->GetHomeHeapNumber();
}
bool HandleTableBucket::Contains(OBJECTHANDLE handle)
@@ -1921,7 +1888,7 @@ bool HandleTableBucket::Contains(OBJECTHANDLE handle)
}
HHANDLETABLE hTable = HndGetHandleTable(handle);
- for (int uCPUindex=0; uCPUindex < GCHeap::GetGCHeap()->GetNumberOfHeaps(); uCPUindex++)
+ for (int uCPUindex=0; uCPUindex < g_theGCHeap->GetNumberOfHeaps(); uCPUindex++)
{
if (hTable == this->pTable[uCPUindex])
{
diff --git a/src/gc/objecthandle.h b/src/gc/objecthandle.h
index 89365267d6..34c2a0e321 100644
--- a/src/gc/objecthandle.h
+++ b/src/gc/objecthandle.h
@@ -652,7 +652,6 @@ BOOL Ref_ContainHandle(HandleTableBucket *pBucket, OBJECTHANDLE handle);
*/
struct ScanContext;
struct DhContext;
-struct ProfilingScanContext;
void Ref_BeginSynchronousGC (uint32_t uCondemnedGeneration, uint32_t uMaxGeneration);
void Ref_EndSynchronousGC (uint32_t uCondemnedGeneration, uint32_t uMaxGeneration);
@@ -672,10 +671,12 @@ 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_ScanPointersForProfilerAndETW(uint32_t uMaxGeneration, uintptr_t lp1);
-void Ref_ScanDependentHandlesForProfilerAndETW(uint32_t uMaxGeneration, ProfilingScanContext * SC);
+void Ref_ScanHandlesForProfilerAndETW(uint32_t uMaxGeneration, uintptr_t lp1, handle_scan_fn fn);
+void Ref_ScanDependentHandlesForProfilerAndETW(uint32_t uMaxGeneration, ScanContext * SC, handle_scan_fn fn);
void Ref_AgeHandles (uint32_t uCondemnedGeneration, uint32_t uMaxGeneration, uintptr_t lp1);
void Ref_RejuvenateHandles(uint32_t uCondemnedGeneration, uint32_t uMaxGeneration, uintptr_t lp1);
diff --git a/src/gc/sample/CMakeLists.txt b/src/gc/sample/CMakeLists.txt
index 572fba371f..9552cc51e2 100644
--- a/src/gc/sample/CMakeLists.txt
+++ b/src/gc/sample/CMakeLists.txt
@@ -22,11 +22,11 @@ set(SOURCES
if(WIN32)
list(APPEND SOURCES
- gcenv.windows.cpp)
+ ../gcenv.windows.cpp)
add_definitions(-DUNICODE=1)
else()
list(APPEND SOURCES
- gcenv.unix.cpp)
+ ../gcenv.unix.cpp)
endif()
_add_executable(gcsample
diff --git a/src/gc/sample/GCSample.cpp b/src/gc/sample/GCSample.cpp
index 7e07834ced..664dc38e94 100644
--- a/src/gc/sample/GCSample.cpp
+++ b/src/gc/sample/GCSample.cpp
@@ -68,7 +68,7 @@ Object * AllocateObject(MethodTable * pMT)
}
else
{
- pObject = GCHeap::GetGCHeap()->Alloc(acontext, size, 0);
+ pObject = g_theGCHeap->Alloc(acontext, size, 0);
if (pObject == NULL)
return NULL;
}
@@ -91,14 +91,14 @@ inline void ErectWriteBarrier(Object ** dst, Object * ref)
{
// if the dst is outside of the heap (unboxed value classes) then we
// simply exit
- if (((uint8_t*)dst < g_lowest_address) || ((uint8_t*)dst >= g_highest_address))
+ if (((uint8_t*)dst < g_gc_lowest_address) || ((uint8_t*)dst >= g_gc_highest_address))
return;
- if((uint8_t*)ref >= g_ephemeral_low && (uint8_t*)ref < g_ephemeral_high)
+ if((uint8_t*)ref >= g_gc_ephemeral_low && (uint8_t*)ref < g_gc_ephemeral_high)
{
// volatile 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.
- uint8_t* pCardByte = (uint8_t *)*(volatile uint8_t **)(&g_card_table) + card_byte((uint8_t *)dst);
+ uint8_t* pCardByte = (uint8_t *)*(volatile uint8_t **)(&g_gc_card_table) + card_byte((uint8_t *)dst);
if(*pCardByte != 0xFF)
*pCardByte = 0xFF;
}
@@ -137,7 +137,7 @@ int __cdecl main(int argc, char* argv[])
//
// Initialize GC heap
//
- GCHeap *pGCHeap = GCHeap::CreateGCHeap();
+ IGCHeap *pGCHeap = InitializeGarbageCollector(nullptr);
if (!pGCHeap)
return -1;
diff --git a/src/gc/sample/GCSample.vcxproj b/src/gc/sample/GCSample.vcxproj
index b196e1f34c..1716f462ee 100644
--- a/src/gc/sample/GCSample.vcxproj
+++ b/src/gc/sample/GCSample.vcxproj
@@ -84,10 +84,12 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="gcenv.ee.cpp" />
- <ClCompile Include="gcenv.windows.cpp" />
<ClCompile Include="GCSample.cpp" />
<ClCompile Include="..\gccommon.cpp" />
<ClCompile Include="..\gceewks.cpp" />
+ <ClCompile Include="..\gcenv.windows.cpp">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
<ClCompile Include="..\gcscan.cpp" />
<ClCompile Include="..\gcwks.cpp" />
<ClCompile Include="..\handletable.cpp" />
@@ -96,8 +98,7 @@
<ClCompile Include="..\handletablescan.cpp" />
<ClCompile Include="..\objecthandle.cpp" />
<ClCompile Include="..\env\common.cpp">
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
- <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
diff --git a/src/gc/sample/GCSample.vcxproj.filters b/src/gc/sample/GCSample.vcxproj.filters
index e46c054565..f6aacfd0c7 100644
--- a/src/gc/sample/GCSample.vcxproj.filters
+++ b/src/gc/sample/GCSample.vcxproj.filters
@@ -59,7 +59,7 @@
<ClCompile Include="gcenv.ee.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="gcenv.windows.cpp">
+ <ClCompile Include="..\gcenv.windows.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
diff --git a/src/gc/sample/gcenv.ee.cpp b/src/gc/sample/gcenv.ee.cpp
index 330564a380..ac227b4823 100644
--- a/src/gc/sample/gcenv.ee.cpp
+++ b/src/gc/sample/gcenv.ee.cpp
@@ -9,6 +9,12 @@
#include "gcenv.h"
#include "gc.h"
+MethodTable * g_pFreeObjectMethodTable;
+
+int32_t g_TrapReturningThreads;
+
+bool g_fFinalizerRunOnShutDown;
+
EEConfig * g_pConfig;
bool CLREventStatic::CreateManualEventNoThrow(bool bInitialState)
@@ -129,9 +135,9 @@ void ThreadStore::AttachCurrentThread()
g_pThreadList = pThread;
}
-void GCToEEInterface::SuspendEE(GCToEEInterface::SUSPEND_REASON reason)
+void GCToEEInterface::SuspendEE(SUSPEND_REASON reason)
{
- GCHeap::GetGCHeap()->SetGCInProgress(TRUE);
+ g_theGCHeap->SetGCInProgress(TRUE);
// TODO: Implement
}
@@ -140,7 +146,7 @@ void GCToEEInterface::RestartEE(bool bFinishedGC)
{
// TODO: Implement
- GCHeap::GetGCHeap()->SetGCInProgress(FALSE);
+ g_theGCHeap->SetGCInProgress(FALSE);
}
void GCToEEInterface::GcScanRoots(promote_func* fn, int condemned, int max_gen, ScanContext* sc)
@@ -184,7 +190,7 @@ void GCToEEInterface::DisablePreemptiveGC(Thread * pThread)
pThread->DisablePreemptiveGC();
}
-alloc_context * GCToEEInterface::GetAllocContext(Thread * pThread)
+gc_alloc_context * GCToEEInterface::GetAllocContext(Thread * pThread)
{
return pThread->GetAllocContext();
}
@@ -221,6 +227,38 @@ Thread* GCToEEInterface::CreateBackgroundThread(GCBackgroundThreadFunction threa
return NULL;
}
+void GCToEEInterface::DiagGCStart(int gen, bool isInduced)
+{
+}
+
+void GCToEEInterface::DiagUpdateGenerationBounds()
+{
+}
+
+void GCToEEInterface::DiagGCEnd(size_t index, int gen, int reason, bool fConcurrent)
+{
+}
+
+void GCToEEInterface::DiagWalkFReachableObjects(void* gcContext)
+{
+}
+
+void GCToEEInterface::DiagWalkSurvivors(void* gcContext)
+{
+}
+
+void GCToEEInterface::DiagWalkLOHSurvivors(void* gcContext)
+{
+}
+
+void GCToEEInterface::DiagWalkBGCSurvivors(void* gcContext)
+{
+}
+
+void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)
+{
+}
+
void FinalizerThread::EnableFinalization()
{
// Signal to finalizer thread that there are objects to finalize
@@ -238,14 +276,6 @@ bool IsGCSpecialThread()
return false;
}
-void StompWriteBarrierEphemeral(bool /* isRuntimeSuspended */)
-{
-}
-
-void StompWriteBarrierResize(bool /* isRuntimeSuspended */, bool /*bReqUpperBoundsCheck*/)
-{
-}
-
bool IsGCThread()
{
return false;
diff --git a/src/gc/sample/gcenv.h b/src/gc/sample/gcenv.h
index d560789751..4505f1af30 100644
--- a/src/gc/sample/gcenv.h
+++ b/src/gc/sample/gcenv.h
@@ -2,6 +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.
+// The sample is to be kept simple, so building the sample
+// in tandem with a standalone GC is currently not supported.
+#ifdef FEATURE_STANDALONE_GC
+#undef FEATURE_STANDALONE_GC
+#endif // FEATURE_STANDALONE_GC
+
#if defined(_DEBUG)
#ifndef _DEBUG_IMPL
#define _DEBUG_IMPL 1
@@ -17,12 +23,12 @@
#include "gcenv.structs.h"
#include "gcenv.base.h"
-#include "gcenv.ee.h"
#include "gcenv.os.h"
#include "gcenv.interlocked.h"
#include "gcenv.interlocked.inl"
#include "gcenv.object.h"
#include "gcenv.sync.h"
+#include "gcenv.ee.h"
#define MAX_LONGPATH 1024
@@ -64,6 +70,9 @@
#define LOG(x)
+#define SVAL_IMPL_INIT(type, cls, var, init) \
+ type cls::var = init
+
//
// Thread
//
@@ -177,8 +186,6 @@ public:
int GetGCTrimCommit() const { return 0; }
int GetGCLOHCompactionMode() const { return 0; }
- bool GetGCAllowVeryLargeObjects() const { return false; }
-
bool GetGCConservative() const { return true; }
};
diff --git a/src/gc/sample/gcenv.unix.cpp b/src/gc/sample/gcenv.unix.cpp
deleted file mode 100644
index a5e9e83ee2..0000000000
--- a/src/gc/sample/gcenv.unix.cpp
+++ /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.
-
-//
-// Implementation of the GC environment
-//
-
-#include "common.h"
-
-#include "gcenv.h"
-#include "gc.h"
-
-// TODO: Implement
diff --git a/src/gc/sample/gcenv.windows.cpp b/src/gc/sample/gcenv.windows.cpp
deleted file mode 100644
index 76187f2185..0000000000
--- a/src/gc/sample/gcenv.windows.cpp
+++ /dev/null
@@ -1,453 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-//
-// Implementation of the GC environment
-//
-
-#include "common.h"
-
-#include "windows.h"
-
-#include "gcenv.h"
-#include "gc.h"
-
-MethodTable * g_pFreeObjectMethodTable;
-
-int32_t g_TrapReturningThreads;
-
-bool g_fFinalizerRunOnShutDown;
-
-GCSystemInfo g_SystemInfo;
-
-static LARGE_INTEGER g_performanceFrequency;
-
-// Initialize the interface implementation
-// Return:
-// true if it has succeeded, false if it has failed
-bool GCToOSInterface::Initialize()
-{
- if (!::QueryPerformanceFrequency(&g_performanceFrequency))
- {
- return false;
- }
-
- SYSTEM_INFO systemInfo;
- GetSystemInfo(&systemInfo);
-
- g_SystemInfo.dwNumberOfProcessors = systemInfo.dwNumberOfProcessors;
- g_SystemInfo.dwPageSize = systemInfo.dwPageSize;
- g_SystemInfo.dwAllocationGranularity = systemInfo.dwAllocationGranularity;
-
- return true;
-}
-
-// Shutdown the interface implementation
-void GCToOSInterface::Shutdown()
-{
-}
-
-// Get numeric id of the current thread if possible on the
-// current platform. It is indended for logging purposes only.
-// Return:
-// Numeric id of the current thread or 0 if the
-uint64_t GCToOSInterface::GetCurrentThreadIdForLogging()
-{
- return ::GetCurrentThreadId();
-}
-
-// Get id of the process
-// Return:
-// Id of the current process
-uint32_t GCToOSInterface::GetCurrentProcessId()
-{
- return ::GetCurrentProcessId();
-}
-
-// Set ideal affinity for the current thread
-// Parameters:
-// affinity - ideal processor affinity for the thread
-// Return:
-// true if it has succeeded, false if it has failed
-bool GCToOSInterface::SetCurrentThreadIdealAffinity(GCThreadAffinity* affinity)
-{
- bool success = true;
-
-#if !defined(FEATURE_CORESYSTEM)
- SetThreadIdealProcessor(GetCurrentThread(), (DWORD)affinity->Processor);
-#else
- PROCESSOR_NUMBER proc;
-
- if (affinity->Group != -1)
- {
- proc.Group = (WORD)affinity->Group;
- proc.Number = (BYTE)affinity->Processor;
- proc.Reserved = 0;
-
- success = !!SetThreadIdealProcessorEx(GetCurrentThread(), &proc, NULL);
- }
- else
- {
- if (GetThreadIdealProcessorEx(GetCurrentThread(), &proc))
- {
- proc.Number = affinity->Processor;
- success = !!SetThreadIdealProcessorEx(GetCurrentThread(), &proc, NULL);
- }
- }
-#endif
-
- return success;
-}
-
-// Get the number of the current processor
-uint32_t GCToOSInterface::GetCurrentProcessorNumber()
-{
- _ASSERTE(GCToOSInterface::CanGetCurrentProcessorNumber());
- return ::GetCurrentProcessorNumber();
-}
-
-// Check if the OS supports getting current processor number
-bool GCToOSInterface::CanGetCurrentProcessorNumber()
-{
- return true;
-}
-
-// Flush write buffers of processors that are executing threads of the current process
-void GCToOSInterface::FlushProcessWriteBuffers()
-{
- ::FlushProcessWriteBuffers();
-}
-
-// Break into a debugger
-void GCToOSInterface::DebugBreak()
-{
- ::DebugBreak();
-}
-
-// Get number of logical processors
-uint32_t GCToOSInterface::GetLogicalCpuCount()
-{
- return g_SystemInfo.dwNumberOfProcessors;
-}
-
-// Causes the calling thread to sleep for the specified number of milliseconds
-// Parameters:
-// sleepMSec - time to sleep before switching to another thread
-void GCToOSInterface::Sleep(uint32_t sleepMSec)
-{
- ::Sleep(sleepMSec);
-}
-
-// Causes the calling thread to yield execution to another thread that is ready to run on the current processor.
-// Parameters:
-// switchCount - number of times the YieldThread was called in a loop
-void GCToOSInterface::YieldThread(uint32_t switchCount)
-{
- SwitchToThread();
-}
-
-// Reserve virtual memory range.
-// Parameters:
-// address - starting virtual address, it can be NULL to let the function choose the starting address
-// size - size of the virtual memory range
-// alignment - requested memory alignment
-// flags - flags to control special settings like write watching
-// Return:
-// Starting virtual address of the reserved range
-void* GCToOSInterface::VirtualReserve(void* address, size_t size, size_t alignment, uint32_t flags)
-{
- DWORD memFlags = (flags & VirtualReserveFlags::WriteWatch) ? (MEM_RESERVE | MEM_WRITE_WATCH) : MEM_RESERVE;
- return ::VirtualAlloc(0, size, memFlags, PAGE_READWRITE);
-}
-
-// Release virtual memory range previously reserved using VirtualReserve
-// Parameters:
-// address - starting virtual address
-// size - size of the virtual memory range
-// Return:
-// true if it has succeeded, false if it has failed
-bool GCToOSInterface::VirtualRelease(void* address, size_t size)
-{
- UNREFERENCED_PARAMETER(size);
- return !!::VirtualFree(address, 0, MEM_RELEASE);
-}
-
-// Commit virtual memory range. It must be part of a range reserved using VirtualReserve.
-// Parameters:
-// address - starting virtual address
-// size - size of the virtual memory range
-// Return:
-// true if it has succeeded, false if it has failed
-bool GCToOSInterface::VirtualCommit(void* address, size_t size)
-{
- return ::VirtualAlloc(address, size, MEM_COMMIT, PAGE_READWRITE) != NULL;
-}
-
-// Decomit virtual memory range.
-// Parameters:
-// address - starting virtual address
-// size - size of the virtual memory range
-// Return:
-// true if it has succeeded, false if it has failed
-bool GCToOSInterface::VirtualDecommit(void* address, size_t size)
-{
- return !!::VirtualFree(address, size, MEM_DECOMMIT);
-}
-
-// Reset virtual memory range. Indicates that data in the memory range specified by address and size is no
-// longer of interest, but it should not be decommitted.
-// Parameters:
-// address - starting virtual address
-// size - size of the virtual memory range
-// unlock - true if the memory range should also be unlocked
-// Return:
-// true if it has succeeded, false if it has failed
-bool GCToOSInterface::VirtualReset(void * address, size_t size, bool unlock)
-{
- bool success = ::VirtualAlloc(address, size, MEM_RESET, PAGE_READWRITE) != NULL;
- if (success && unlock)
- {
- // Remove the page range from the working set
- ::VirtualUnlock(address, size);
- }
-
- return success;
-}
-
-// Check if the OS supports write watching
-bool GCToOSInterface::SupportsWriteWatch()
-{
- return false;
-}
-
-// Reset the write tracking state for the specified virtual memory range.
-// Parameters:
-// address - starting virtual address
-// size - size of the virtual memory range
-void GCToOSInterface::ResetWriteWatch(void* address, size_t size)
-{
-}
-
-// Retrieve addresses of the pages that are written to in a region of virtual memory
-// Parameters:
-// resetState - true indicates to reset the write tracking state
-// address - starting virtual address
-// size - size of the virtual memory range
-// pageAddresses - buffer that receives an array of page addresses in the memory region
-// pageAddressesCount - on input, size of the lpAddresses array, in array elements
-// on output, the number of page addresses that are returned in the array.
-// Return:
-// true if it has succeeded, false if it has failed
-bool GCToOSInterface::GetWriteWatch(bool resetState, void* address, size_t size, void** pageAddresses, uintptr_t* pageAddressesCount)
-{
- return false;
-}
-
-// Get size of the largest cache on the processor die
-// Parameters:
-// trueSize - true to return true cache size, false to return scaled up size based on
-// the processor architecture
-// Return:
-// Size of the cache
-size_t GCToOSInterface::GetLargestOnDieCacheSize(bool trueSize)
-{
- // TODO: implement
- return 0;
-}
-
-// Get affinity mask of the current process
-// Parameters:
-// processMask - affinity mask for the specified process
-// systemMask - affinity mask for the system
-// Return:
-// true if it has succeeded, false if it has failed
-// Remarks:
-// A process affinity mask is a bit vector in which each bit represents the processors that
-// a process is allowed to run on. A system affinity mask is a bit vector in which each bit
-// represents the processors that are configured into a system.
-// A process affinity mask is a subset of the system affinity mask. A process is only allowed
-// to run on the processors configured into a system. Therefore, the process affinity mask cannot
-// specify a 1 bit for a processor when the system affinity mask specifies a 0 bit for that processor.
-bool GCToOSInterface::GetCurrentProcessAffinityMask(uintptr_t* processMask, uintptr_t* systemMask)
-{
- return false;
-}
-
-// Get number of processors assigned to the current process
-// Return:
-// The number of processors
-uint32_t GCToOSInterface::GetCurrentProcessCpuCount()
-{
- return g_SystemInfo.dwNumberOfProcessors;
-}
-
-// Return the size of the user-mode portion of the virtual address space of this process.
-// Return:
-// non zero if it has succeeded, 0 if it has failed
-size_t GCToOSInterface::GetVirtualMemoryLimit()
-{
- MEMORYSTATUSEX memStatus;
-
- memStatus.dwLength = sizeof(MEMORYSTATUSEX);
- BOOL fRet = GlobalMemoryStatusEx(&memStatus);
- _ASSERTE(fRet);
-
- return (size_t)memStatus.ullTotalVirtual;
-}
-
-// Get the physical memory that this process can use.
-// Return:
-// non zero if it has succeeded, 0 if it has failed
-uint64_t GCToOSInterface::GetPhysicalMemoryLimit()
-{
- MEMORYSTATUSEX memStatus;
-
- memStatus.dwLength = sizeof(MEMORYSTATUSEX);
- BOOL fRet = GlobalMemoryStatusEx(&memStatus);
- _ASSERTE(fRet);
-
- return memStatus.ullTotalPhys;
-}
-
-// Get memory status
-// Parameters:
-// memory_load - A number between 0 and 100 that specifies the approximate percentage of physical memory
-// that is in use (0 indicates no memory use and 100 indicates full memory use).
-// available_physical - The amount of physical memory currently available, in bytes.
-// available_page_file - The maximum amount of memory the current process can commit, in bytes.
-void GCToOSInterface::GetMemoryStatus(uint32_t* memory_load, uint64_t* available_physical, uint64_t* available_page_file)
-{
- MEMORYSTATUSEX memStatus;
-
- memStatus.dwLength = sizeof(MEMORYSTATUSEX);
- BOOL fRet = GlobalMemoryStatusEx(&memStatus);
- _ASSERTE (fRet);
-
- // If the machine has more RAM than virtual address limit, let us cap it.
- // The GC can never use more than virtual address limit.
- if (memStatus.ullAvailPhys > memStatus.ullTotalVirtual)
- {
- memStatus.ullAvailPhys = memStatus.ullAvailVirtual;
- }
-
- if (memory_load != NULL)
- *memory_load = memStatus.dwMemoryLoad;
- if (available_physical != NULL)
- *available_physical = memStatus.ullAvailPhys;
- if (available_page_file != NULL)
- *available_page_file = memStatus.ullAvailPageFile;
-}
-
-// Get a high precision performance counter
-// Return:
-// The counter value
-int64_t GCToOSInterface::QueryPerformanceCounter()
-{
- LARGE_INTEGER ts;
- if (!::QueryPerformanceCounter(&ts))
- {
- _ASSERTE(!"Fatal Error - cannot query performance counter.");
- abort();
- }
-
- return ts.QuadPart;
-}
-
-// Get a frequency of the high precision performance counter
-// Return:
-// The counter frequency
-int64_t GCToOSInterface::QueryPerformanceFrequency()
-{
- return g_performanceFrequency.QuadPart;
-}
-
-// Get a time stamp with a low precision
-// Return:
-// Time stamp in milliseconds
-uint32_t GCToOSInterface::GetLowPrecisionTimeStamp()
-{
- return ::GetTickCount();
-}
-
-// Parameters of the GC thread stub
-struct GCThreadStubParam
-{
- GCThreadFunction GCThreadFunction;
- void* GCThreadParam;
-};
-
-// GC thread stub to convert GC thread function to an OS specific thread function
-static DWORD __stdcall GCThreadStub(void* param)
-{
- GCThreadStubParam *stubParam = (GCThreadStubParam*)param;
- GCThreadFunction function = stubParam->GCThreadFunction;
- void* threadParam = stubParam->GCThreadParam;
-
- delete stubParam;
-
- function(threadParam);
-
- return 0;
-}
-
-// Create a new thread
-// Parameters:
-// function - the function to be executed by the thread
-// param - parameters of the thread
-// affinity - processor affinity of the thread
-// Return:
-// true if it has succeeded, false if it has failed
-bool GCToOSInterface::CreateThread(GCThreadFunction function, void* param, GCThreadAffinity* affinity)
-{
- DWORD thread_id;
-
- GCThreadStubParam* stubParam = new (nothrow) GCThreadStubParam();
- if (stubParam == NULL)
- {
- return false;
- }
-
- stubParam->GCThreadFunction = function;
- stubParam->GCThreadParam = param;
-
- HANDLE gc_thread = ::CreateThread(NULL, 0, GCThreadStub, stubParam, CREATE_SUSPENDED, &thread_id);
-
- if (!gc_thread)
- {
- delete stubParam;
- return false;
- }
-
- SetThreadPriority(gc_thread, /* THREAD_PRIORITY_ABOVE_NORMAL );*/ THREAD_PRIORITY_HIGHEST );
-
- ResumeThread(gc_thread);
-
- CloseHandle(gc_thread);
-
- return true;
-}
-
-// Initialize the critical section
-void CLRCriticalSection::Initialize()
-{
- ::InitializeCriticalSection(&m_cs);
-}
-
-// Destroy the critical section
-void CLRCriticalSection::Destroy()
-{
- ::DeleteCriticalSection(&m_cs);
-}
-
-// Enter the critical section. Blocks until the section can be entered.
-void CLRCriticalSection::Enter()
-{
- ::EnterCriticalSection(&m_cs);
-}
-
-// Leave the critical section
-void CLRCriticalSection::Leave()
-{
- ::LeaveCriticalSection(&m_cs);
-}
diff --git a/src/gc/softwarewritewatch.cpp b/src/gc/softwarewritewatch.cpp
index 519744900b..fa14a04897 100644
--- a/src/gc/softwarewritewatch.cpp
+++ b/src/gc/softwarewritewatch.cpp
@@ -6,6 +6,7 @@
#include "softwarewritewatch.h"
#include "gcenv.h"
+#include "env/gcenv.os.h"
#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
#ifndef DACCESS_COMPILE
diff --git a/src/gcdump/gcdump.cpp b/src/gcdump/gcdump.cpp
index 1c512c88e0..c89dd6ce17 100644
--- a/src/gcdump/gcdump.cpp
+++ b/src/gcdump/gcdump.cpp
@@ -11,7 +11,9 @@
* to the standard code-manager spec.
*/
+#ifndef FEATURE_PAL
#include "utilcode.h" // For _ASSERTE()
+#endif //!FEATURE_PAL
#include "gcdump.h"
/*****************************************************************************/
diff --git a/src/gcdump/gcdumpnonx86.cpp b/src/gcdump/gcdumpnonx86.cpp
index 7343ac9771..ca8cc75792 100644
--- a/src/gcdump/gcdumpnonx86.cpp
+++ b/src/gcdump/gcdumpnonx86.cpp
@@ -505,7 +505,7 @@ size_t GCDump::DumpGCTable(PTR_CBYTE gcInfoBlock,
/*****************************************************************************/
-void GCDump::DumpPtrsInFrame(PTR_CBYTE infoBlock,
+void GCDump::DumpPtrsInFrame(PTR_CBYTE gcInfoBlock,
PTR_CBYTE codeBlock,
unsigned offs,
bool verifyGCTables)
@@ -520,7 +520,7 @@ void GCDump::DumpPtrsInFrame(PTR_CBYTE infoBlock,
#define LOG(x) ((void)0)
#endif
-#define GCINFODECODER_CONTRACT(contract)
+#define GCINFODECODER_CONTRACT ((void)0)
#define GET_CALLER_SP(pREGDISPLAY) ((size_t)GetSP(pREGDISPLAY->pCallerContext))
#define VALIDATE_OBJECTREF(objref, fDeep) ((void)0)
#define VALIDATE_ROOT(isInterior, hCallBack, pObjRef) ((void)0)
diff --git a/src/gcdump/i386/gcdumpx86.cpp b/src/gcdump/i386/gcdumpx86.cpp
index 70334dee65..23e6c6834b 100644
--- a/src/gcdump/i386/gcdumpx86.cpp
+++ b/src/gcdump/i386/gcdumpx86.cpp
@@ -9,7 +9,9 @@
#ifdef _TARGET_X86_
/*****************************************************************************/
+#ifndef FEATURE_PAL
#include "utilcode.h" // For _ASSERTE()
+#endif //!FEATURE_PAL
#include "gcdump.h"
@@ -60,12 +62,13 @@ const char * CalleeSavedRegName(unsigned reg)
/*****************************************************************************/
-unsigned GCDump::DumpInfoHdr (PTR_CBYTE table,
+unsigned GCDump::DumpInfoHdr (PTR_CBYTE gcInfoBlock,
InfoHdr* header,
unsigned * methodSize,
bool verifyGCTables)
{
unsigned count;
+ PTR_CBYTE table = gcInfoBlock;
PTR_CBYTE tableStart = table;
PTR_CBYTE bp = table;
@@ -76,7 +79,7 @@ unsigned GCDump::DumpInfoHdr (PTR_CBYTE table,
table += decodeUnsigned(table, methodSize);
- table = decodeHeader(table, header);
+ table = decodeHeader(table, gcInfoVersion, header);
BOOL hasArgTabOffset = FALSE;
if (header->untrackedCnt == HAS_UNTRACKED)
@@ -107,6 +110,12 @@ unsigned GCDump::DumpInfoHdr (PTR_CBYTE table,
header->syncEndOffset = count;
}
+ if (header->revPInvokeOffset == HAS_REV_PINVOKE_FRAME_OFFSET)
+ {
+ table += decodeUnsigned(table, &count);
+ header->revPInvokeOffset = count;
+ }
+
//
// First print out all the basic information
//
@@ -931,12 +940,12 @@ DONE_REGTAB:
/*****************************************************************************/
-void GCDump::DumpPtrsInFrame(PTR_CBYTE infoBlock,
+void GCDump::DumpPtrsInFrame(PTR_CBYTE gcInfoBlock,
PTR_CBYTE codeBlock,
unsigned offs,
bool verifyGCTables)
{
- PTR_CBYTE table = infoBlock;
+ PTR_CBYTE table = gcInfoBlock;
size_t methodSize;
size_t stackSize;
@@ -963,7 +972,7 @@ void GCDump::DumpPtrsInFrame(PTR_CBYTE infoBlock,
// Typically only uses one-byte to store everything.
//
InfoHdr header;
- table = decodeHeader(table, &header);
+ table = decodeHeader(table, gcInfoVersion, &header);
if (header.untrackedCnt == HAS_UNTRACKED)
{
@@ -994,6 +1003,13 @@ void GCDump::DumpPtrsInFrame(PTR_CBYTE infoBlock,
header.syncEndOffset = offset;
_ASSERTE(offset != INVALID_SYNC_OFFSET);
}
+ if (header.revPInvokeOffset == HAS_REV_PINVOKE_FRAME_OFFSET)
+ {
+ unsigned offset;
+ table += decodeUnsigned(table, &offset);
+ header.revPInvokeOffset = offset;
+ _ASSERTE(offset != INVALID_REV_PINVOKE_OFFSET);
+ }
prologSize = header.prologSize;
epilogSize = header.epilogSize;
diff --git a/src/gcinfo/gcinfoencoder.cpp b/src/gcinfo/gcinfoencoder.cpp
index 67852220ed..15d6ed9ff9 100644
--- a/src/gcinfo/gcinfoencoder.cpp
+++ b/src/gcinfo/gcinfoencoder.cpp
@@ -343,10 +343,13 @@ GcInfoSize& GcInfoSize::operator+=(const GcInfoSize& other)
NumRanges += other.NumRanges;
NumRegs += other.NumRegs;
NumStack += other.NumStack;
- NumEh += other.NumEh;
+ NumUntracked += other.NumUntracked;
NumTransitions += other.NumTransitions;
SizeOfCode += other.SizeOfCode;
+ EncPreservedSlots += other.EncPreservedSlots;
+ UntrackedSlotSize += other.UntrackedSlotSize;
+ NumUntrackedSize += other.NumUntrackedSize;
FlagsSize += other.FlagsSize;
CodeLengthSize += other.CodeLengthSize;
ProEpilogSize += other.ProEpilogSize;
@@ -366,7 +369,6 @@ GcInfoSize& GcInfoSize::operator+=(const GcInfoSize& other)
RegSlotSize += other.RegSlotSize;
StackSlotSize += other.StackSlotSize;
CallSiteStateSize += other.CallSiteStateSize;
- NumEhSize += other.NumEhSize;
EhPosSize += other.EhPosSize;
EhStateSize += other.EhStateSize;
ChunkPtrSize += other.ChunkPtrSize;
@@ -389,12 +391,15 @@ void GcInfoSize::Log(DWORD level, const char * header)
LogSpew(LF_GCINFO, level, "NumRanges: %Iu\n", NumRanges);
LogSpew(LF_GCINFO, level, "NumRegs: %Iu\n", NumRegs);
LogSpew(LF_GCINFO, level, "NumStack: %Iu\n", NumStack);
- LogSpew(LF_GCINFO, level, "NumEh: %Iu\n", NumEh);
+ LogSpew(LF_GCINFO, level, "NumUntracked: %Iu\n", NumUntracked);
LogSpew(LF_GCINFO, level, "NumTransitions: %Iu\n", NumTransitions);
LogSpew(LF_GCINFO, level, "SizeOfCode: %Iu\n", SizeOfCode);
+ LogSpew(LF_GCINFO, level, "EncPreservedSlots: %Iu\n", EncPreservedSlots);
LogSpew(LF_GCINFO, level, "---SIZES(bits)---\n");
LogSpew(LF_GCINFO, level, "Total: %Iu\n", TotalSize);
+ LogSpew(LF_GCINFO, level, "UntrackedSlot: %Iu\n", UntrackedSlotSize);
+ LogSpew(LF_GCINFO, level, "NumUntracked: %Iu\n", NumUntrackedSize);
LogSpew(LF_GCINFO, level, "Flags: %Iu\n", FlagsSize);
LogSpew(LF_GCINFO, level, "CodeLength: %Iu\n", CodeLengthSize);
LogSpew(LF_GCINFO, level, "Prolog/Epilog: %Iu\n", ProEpilogSize);
@@ -414,7 +419,6 @@ void GcInfoSize::Log(DWORD level, const char * header)
LogSpew(LF_GCINFO, level, "RegSlots: %Iu\n", RegSlotSize);
LogSpew(LF_GCINFO, level, "StackSlots: %Iu\n", StackSlotSize);
LogSpew(LF_GCINFO, level, "CallSiteStates: %Iu\n", CallSiteStateSize);
- LogSpew(LF_GCINFO, level, "NumEh: %Iu\n", NumEhSize);
LogSpew(LF_GCINFO, level, "EhOffsets: %Iu\n", EhPosSize);
LogSpew(LF_GCINFO, level, "EhStates: %Iu\n", EhStateSize);
LogSpew(LF_GCINFO, level, "ChunkPointers: %Iu\n", ChunkPtrSize);
@@ -426,17 +430,6 @@ void GcInfoSize::Log(DWORD level, const char * header)
#endif
-#ifndef DISABLE_EH_VECTORS
-inline BOOL IsEssential(EE_ILEXCEPTION_CLAUSE *pClause)
-{
- _ASSERTE(pClause->TryEndPC >= pClause->TryStartPC);
- if(pClause->TryEndPC == pClause->TryStartPC)
- return FALSE;
-
- return TRUE;
-}
-#endif
-
GcInfoEncoder::GcInfoEncoder(
ICorJitInfo* pCorJitInfo,
CORINFO_METHOD_INFO* pMethodInfo,
@@ -1170,7 +1163,8 @@ void GcInfoEncoder::Build()
int size_tCount = (m_NumSlots + BITS_PER_SIZE_T - 1) / BITS_PER_SIZE_T;
BitArray liveState(m_pAllocator, size_tCount);
BitArray couldBeLive(m_pAllocator, size_tCount);
-
+ liveState.ClearAll();
+ couldBeLive.ClearAll();
#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED
_ASSERTE(m_NumCallSites == 0 || m_pCallSites != NULL);
@@ -1354,83 +1348,6 @@ void GcInfoEncoder::Build()
#endif
}
-
-#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED
- ///////////////////////////////////////////////////////////////////////
- // Gather EH information
- ///////////////////////////////////////////////////////////////////////
-
- couldBeLive.ClearAll();
-
-#ifndef DISABLE_EH_VECTORS
- UINT32 numEHClauses;
- EE_ILEXCEPTION *pEHInfo = (EE_ILEXCEPTION*) m_pCorJitInfo->getEHInfo();
- if (!pEHInfo)
- numEHClauses = 0;
- else
- numEHClauses = pEHInfo->EHCount();
-
- UINT32 numUsedEHClauses = numEHClauses;
- for (UINT32 clauseIndex = 0; clauseIndex < numEHClauses; clauseIndex++)
- {
- EE_ILEXCEPTION_CLAUSE * pClause;
- pClause = pEHInfo->EHClause(clauseIndex);
-
- if(!IsEssential(pClause))
- numUsedEHClauses--;
- }
-
- UINT32 ehTableBitCount = m_NumSlots * numUsedEHClauses;
- BitArray ehLiveSlots(m_pAllocator, (ehTableBitCount + BITS_PER_SIZE_T - 1) / BITS_PER_SIZE_T);
- ehLiveSlots.ClearAll();
-
- UINT32 basePos = 0;
- for (UINT32 clauseIndex = 0; clauseIndex < numEHClauses; clauseIndex++)
- {
- EE_ILEXCEPTION_CLAUSE * pClause;
- pClause = pEHInfo->EHClause(clauseIndex);
-
- _ASSERTE(pClause->TryEndPC <= m_CodeLength);
- if(!IsEssential(pClause))
- continue;
-
- liveState.ClearAll();
-
- for(pCurrent = pTransitions; pCurrent < pEndTransitions; pCurrent++)
- {
- if(pCurrent->CodeOffset > pClause->TryStartPC)
- break;
-
- UINT32 slotIndex = pCurrent->SlotId;
- BYTE becomesLive = pCurrent->BecomesLive;
- _ASSERTE(liveState.ReadBit(slotIndex) && !becomesLive
- || !liveState.ReadBit(slotIndex) && becomesLive);
- liveState.WriteBit(slotIndex, becomesLive);
- }
-
- for( ; pCurrent < pEndTransitions; pCurrent++)
- {
- if(pCurrent->CodeOffset >= pClause->TryEndPC)
- break;
-
- UINT32 slotIndex = pCurrent->SlotId;
- liveState.ClearBit(slotIndex);
- }
-
- // Copy to the EH live state table
- for(UINT32 i = 0; i < m_NumSlots; i++)
- {
- if(liveState.ReadBit(i))
- ehLiveSlots.SetBit(basePos + i);
- }
- basePos += m_NumSlots;
-
- // Keep track of which slots are used
- couldBeLive |= liveState;
- }
-#endif // DISABLE_EH_VECTORS
-#endif // PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED
-
#if CODE_OFFSETS_NEED_NORMALIZATION
// Do a pass to normalize transition offsets
for(pCurrent = pTransitions; pCurrent < pEndTransitions; pCurrent++)
@@ -1444,6 +1361,7 @@ void GcInfoEncoder::Build()
// Find out which slots are really used
///////////////////////////////////////////////////////////////////
+ couldBeLive.ClearAll();
#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED
if(m_NumCallSites)
@@ -1994,40 +1912,6 @@ void GcInfoEncoder::Build()
#endif // MUST_CALL_JITALLOCATOR_FREE
}
-
- //-----------------------------------------------------------------
- // Encode EH clauses and bit vectors
- //-----------------------------------------------------------------
-
-#ifndef DISABLE_EH_VECTORS
- GCINFO_WRITE_VARL_U(m_Info1, numUsedEHClauses, NUM_EH_CLAUSES_ENCBASE, NumEhSize);
-
- basePos = 0;
- for(UINT32 clauseIndex = 0; clauseIndex < numEHClauses; clauseIndex++)
- {
- EE_ILEXCEPTION_CLAUSE * pClause;
- pClause = pEHInfo->EHClause(clauseIndex);
-
- if(!IsEssential(pClause))
- continue;
-
- UINT32 normStartOffset = NORMALIZE_CODE_OFFSET(pClause->TryStartPC);
- UINT32 normStopOffset = NORMALIZE_CODE_OFFSET(pClause->TryEndPC);
- _ASSERTE(normStopOffset > normStartOffset);
-
- GCINFO_WRITE(m_Info1, normStartOffset, numBitsPerOffset, EhPosSize);
- GCINFO_WRITE(m_Info1, normStopOffset - 1, numBitsPerOffset, EhPosSize);
-
- for(UINT slotIndex = 0; slotIndex < m_NumSlots; slotIndex++)
- {
- if(!m_SlotTable[slotIndex].IsDeleted())
- {
- GCINFO_WRITE(m_Info1, ehLiveSlots.ReadBit(basePos + slotIndex) ? 1 : 0, 1, EhStateSize);
- }
- }
- basePos += m_NumSlots;
- }
-#endif // DISABLE_EH_VECTORS
#endif // PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED
@@ -2358,11 +2242,6 @@ lExitSuccess:;
m_CurrentMethodSize.NumMethods = 1;
#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED
m_CurrentMethodSize.NumCallSites = m_NumCallSites;
-#ifdef DISABLE_EH_VECTORS
- m_CurrentMethodSize.NumEh = 0;
-#else
- m_CurrentMethodSize.NumEh = numUsedEHClauses;
-#endif
#endif
m_CurrentMethodSize.NumRanges = numInterruptibleRanges;
m_CurrentMethodSize.NumRegs = numRegisters;
diff --git a/src/ilasm/CMakeLists.txt b/src/ilasm/CMakeLists.txt
index 34ec7997c4..9e99d02bb2 100644
--- a/src/ilasm/CMakeLists.txt
+++ b/src/ilasm/CMakeLists.txt
@@ -22,25 +22,23 @@ set(ILASM_SOURCES
asmman.cpp
main.cpp
assembler.cpp
- prebuilt/asmparse.c
+ prebuilt/asmparse.cpp
)
if(WIN32)
set(ILASM_RESOURCES Native.rc)
add_definitions(-DFX_VER_INTERNALNAME_STR=ilasm.exe)
endif(WIN32)
-set_source_files_properties( prebuilt/asmparse.c PROPERTIES LANGUAGE CXX )
if(CLR_CMAKE_PLATFORM_UNIX)
- add_compile_options(-x c++)
- # Need generate a right form of asmparse.c to avoid the following options.
+ # Need generate a right form of asmparse.cpp to avoid the following options.
# Clang also produces a bad-codegen on this prebuilt file with optimization.
# https://github.com/dotnet/coreclr/issues/2305
add_compile_options(-Wno-delete-non-virtual-dtor)
add_compile_options(-Wno-deprecated-register)
add_compile_options(-Wno-array-bounds)
add_compile_options(-Wno-unused-label)
- set_source_files_properties( prebuilt/asmparse.c PROPERTIES COMPILE_FLAGS -O0 )
+ set_source_files_properties( prebuilt/asmparse.cpp PROPERTIES COMPILE_FLAGS "-O0" )
endif(CLR_CMAKE_PLATFORM_UNIX)
_add_executable(ilasm
@@ -82,4 +80,5 @@ else()
)
endif(CLR_CMAKE_PLATFORM_UNIX)
-install_clr(ilasm) \ No newline at end of file
+install_clr(ilasm)
+
diff --git a/src/ilasm/assembler.cpp b/src/ilasm/assembler.cpp
index 690da64890..49d4ee9712 100644
--- a/src/ilasm/assembler.cpp
+++ b/src/ilasm/assembler.cpp
@@ -1725,7 +1725,7 @@ void Assembler::EmitInstrBrOffset(Instr* instr, int offset)
unsigned opc=instr->opcode;
if(m_fOptimize)
{
- if((-128 >= offset)&&(offset <= 127))
+ if((-128 <= offset)&&(offset <= 127))
{
opc = instr->opcode = ShortOf(opc);
}
diff --git a/src/ilasm/main.cpp b/src/ilasm/main.cpp
index 811c65640e..2bef40dd47 100644
--- a/src/ilasm/main.cpp
+++ b/src/ilasm/main.cpp
@@ -768,7 +768,7 @@ extern "C" int _cdecl wmain(int argc, __in WCHAR **argv)
for(iFile = 0; iFile < NumDeltaFiles; iFile++)
{
wcscpy_s(wzNewOutputFilename,MAX_FILENAME_LENGTH+16,wzOutputFilename);
- exitval = (int)StringCchPrintfW(&wzNewOutputFilename[wcslen(wzNewOutputFilename)], 32,
+ exitval = _snwprintf_s(&wzNewOutputFilename[wcslen(wzNewOutputFilename)], 32, _TRUNCATE,
W(".%d"),iFile+1);
MakeProperSourceFileName(pwzDeltaFiles[iFile], uCodePage, wzInputFilename, szInputFilename);
if(pAsm->m_fReportProgress)
diff --git a/src/ilasm/prebuilt/asmparse.c b/src/ilasm/prebuilt/asmparse.c
deleted file mode 100644
index 71b31a5ed6..0000000000
--- a/src/ilasm/prebuilt/asmparse.c
+++ /dev/null
@@ -1,4907 +0,0 @@
-/*
- * Created by Microsoft VCBU Internal YACC from "asmparse.y"
- */
-
-#line 2 "asmparse.y"
-
- // Licensed to the .NET Foundation under one or more 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 asmparse.y
-//
-#include "ilasmpch.h"
-
-#include "grammar_before.cpp"
-
-
-#line 16 "asmparse.y"
-
-#define UNION 1
-typedef union {
- CorRegTypeAttr classAttr;
- CorMethodAttr methAttr;
- CorFieldAttr fieldAttr;
- CorMethodImpl implAttr;
- CorEventAttr eventAttr;
- CorPropertyAttr propAttr;
- CorPinvokeMap pinvAttr;
- CorDeclSecurity secAct;
- CorFileFlags fileAttr;
- CorAssemblyFlags asmAttr;
- CorAssemblyFlags asmRefAttr;
- CorTypeAttr exptAttr;
- CorManifestResourceFlags manresAttr;
- double* float64;
- __int64* int64;
- __int32 int32;
- char* string;
- BinStr* binstr;
- Labels* labels;
- Instr* instr; // instruction opcode
- NVPair* pair;
- pTyParList typarlist;
- mdToken token;
- TypeDefDescr* tdd;
- CustomDescr* cad;
- unsigned short opcode;
-} YYSTYPE;
-# define ERROR_ 257
-# define BAD_COMMENT_ 258
-# define BAD_LITERAL_ 259
-# define ID 260
-# define DOTTEDNAME 261
-# define QSTRING 262
-# define SQSTRING 263
-# define INT32 264
-# define INT64 265
-# define FLOAT64 266
-# define HEXBYTE 267
-# define TYPEDEF_T 268
-# define TYPEDEF_M 269
-# define TYPEDEF_F 270
-# define TYPEDEF_TS 271
-# define TYPEDEF_MR 272
-# define TYPEDEF_CA 273
-# define DCOLON 274
-# define ELIPSIS 275
-# define VOID_ 276
-# define BOOL_ 277
-# define CHAR_ 278
-# define UNSIGNED_ 279
-# define INT_ 280
-# define INT8_ 281
-# define INT16_ 282
-# define INT32_ 283
-# define INT64_ 284
-# define FLOAT_ 285
-# define FLOAT32_ 286
-# define FLOAT64_ 287
-# define BYTEARRAY_ 288
-# define UINT_ 289
-# define UINT8_ 290
-# define UINT16_ 291
-# define UINT32_ 292
-# define UINT64_ 293
-# define FLAGS_ 294
-# define CALLCONV_ 295
-# define MDTOKEN_ 296
-# define OBJECT_ 297
-# define STRING_ 298
-# define NULLREF_ 299
-# define DEFAULT_ 300
-# define CDECL_ 301
-# define VARARG_ 302
-# define STDCALL_ 303
-# define THISCALL_ 304
-# define FASTCALL_ 305
-# define CLASS_ 306
-# define TYPEDREF_ 307
-# define UNMANAGED_ 308
-# define FINALLY_ 309
-# define HANDLER_ 310
-# define CATCH_ 311
-# define FILTER_ 312
-# define FAULT_ 313
-# define EXTENDS_ 314
-# define IMPLEMENTS_ 315
-# define TO_ 316
-# define AT_ 317
-# define TLS_ 318
-# define TRUE_ 319
-# define FALSE_ 320
-# define _INTERFACEIMPL 321
-# define VALUE_ 322
-# define VALUETYPE_ 323
-# define NATIVE_ 324
-# define INSTANCE_ 325
-# define SPECIALNAME_ 326
-# define FORWARDER_ 327
-# define STATIC_ 328
-# define PUBLIC_ 329
-# define PRIVATE_ 330
-# define FAMILY_ 331
-# define FINAL_ 332
-# define SYNCHRONIZED_ 333
-# define INTERFACE_ 334
-# define SEALED_ 335
-# define NESTED_ 336
-# define ABSTRACT_ 337
-# define AUTO_ 338
-# define SEQUENTIAL_ 339
-# define EXPLICIT_ 340
-# define ANSI_ 341
-# define UNICODE_ 342
-# define AUTOCHAR_ 343
-# define IMPORT_ 344
-# define ENUM_ 345
-# define VIRTUAL_ 346
-# define NOINLINING_ 347
-# define AGGRESSIVEINLINING_ 348
-# define NOOPTIMIZATION_ 349
-# define UNMANAGEDEXP_ 350
-# define BEFOREFIELDINIT_ 351
-# define STRICT_ 352
-# define RETARGETABLE_ 353
-# define WINDOWSRUNTIME_ 354
-# define NOPLATFORM_ 355
-# define METHOD_ 356
-# define FIELD_ 357
-# define PINNED_ 358
-# define MODREQ_ 359
-# define MODOPT_ 360
-# define SERIALIZABLE_ 361
-# define PROPERTY_ 362
-# define TYPE_ 363
-# define ASSEMBLY_ 364
-# define FAMANDASSEM_ 365
-# define FAMORASSEM_ 366
-# define PRIVATESCOPE_ 367
-# define HIDEBYSIG_ 368
-# define NEWSLOT_ 369
-# define RTSPECIALNAME_ 370
-# define PINVOKEIMPL_ 371
-# define _CTOR 372
-# define _CCTOR 373
-# define LITERAL_ 374
-# define NOTSERIALIZED_ 375
-# define INITONLY_ 376
-# define REQSECOBJ_ 377
-# define CIL_ 378
-# define OPTIL_ 379
-# define MANAGED_ 380
-# define FORWARDREF_ 381
-# define PRESERVESIG_ 382
-# define RUNTIME_ 383
-# define INTERNALCALL_ 384
-# define _IMPORT 385
-# define NOMANGLE_ 386
-# define LASTERR_ 387
-# define WINAPI_ 388
-# define AS_ 389
-# define BESTFIT_ 390
-# define ON_ 391
-# define OFF_ 392
-# define CHARMAPERROR_ 393
-# define INSTR_NONE 394
-# define INSTR_VAR 395
-# define INSTR_I 396
-# define INSTR_I8 397
-# define INSTR_R 398
-# define INSTR_BRTARGET 399
-# define INSTR_METHOD 400
-# define INSTR_FIELD 401
-# define INSTR_TYPE 402
-# define INSTR_STRING 403
-# define INSTR_SIG 404
-# define INSTR_TOK 405
-# define INSTR_SWITCH 406
-# define _CLASS 407
-# define _NAMESPACE 408
-# define _METHOD 409
-# define _FIELD 410
-# define _DATA 411
-# define _THIS 412
-# define _BASE 413
-# define _NESTER 414
-# define _EMITBYTE 415
-# define _TRY 416
-# define _MAXSTACK 417
-# define _LOCALS 418
-# define _ENTRYPOINT 419
-# define _ZEROINIT 420
-# define _EVENT 421
-# define _ADDON 422
-# define _REMOVEON 423
-# define _FIRE 424
-# define _OTHER 425
-# define _PROPERTY 426
-# define _SET 427
-# define _GET 428
-# define _PERMISSION 429
-# define _PERMISSIONSET 430
-# define REQUEST_ 431
-# define DEMAND_ 432
-# define ASSERT_ 433
-# define DENY_ 434
-# define PERMITONLY_ 435
-# define LINKCHECK_ 436
-# define INHERITCHECK_ 437
-# define REQMIN_ 438
-# define REQOPT_ 439
-# define REQREFUSE_ 440
-# define PREJITGRANT_ 441
-# define PREJITDENY_ 442
-# define NONCASDEMAND_ 443
-# define NONCASLINKDEMAND_ 444
-# define NONCASINHERITANCE_ 445
-# define _LINE 446
-# define P_LINE 447
-# define _LANGUAGE 448
-# define _CUSTOM 449
-# define INIT_ 450
-# define _SIZE 451
-# define _PACK 452
-# define _VTABLE 453
-# define _VTFIXUP 454
-# define FROMUNMANAGED_ 455
-# define CALLMOSTDERIVED_ 456
-# define _VTENTRY 457
-# define RETAINAPPDOMAIN_ 458
-# define _FILE 459
-# define NOMETADATA_ 460
-# define _HASH 461
-# define _ASSEMBLY 462
-# define _PUBLICKEY 463
-# define _PUBLICKEYTOKEN 464
-# define ALGORITHM_ 465
-# define _VER 466
-# define _LOCALE 467
-# define EXTERN_ 468
-# define _MRESOURCE 469
-# define _MODULE 470
-# define _EXPORT 471
-# define LEGACY_ 472
-# define LIBRARY_ 473
-# define X86_ 474
-# define IA64_ 475
-# define AMD64_ 476
-# define ARM_ 477
-# define MARSHAL_ 478
-# define CUSTOM_ 479
-# define SYSSTRING_ 480
-# define FIXED_ 481
-# define VARIANT_ 482
-# define CURRENCY_ 483
-# define SYSCHAR_ 484
-# define DECIMAL_ 485
-# define DATE_ 486
-# define BSTR_ 487
-# define TBSTR_ 488
-# define LPSTR_ 489
-# define LPWSTR_ 490
-# define LPTSTR_ 491
-# define OBJECTREF_ 492
-# define IUNKNOWN_ 493
-# define IDISPATCH_ 494
-# define STRUCT_ 495
-# define SAFEARRAY_ 496
-# define BYVALSTR_ 497
-# define LPVOID_ 498
-# define ANY_ 499
-# define ARRAY_ 500
-# define LPSTRUCT_ 501
-# define IIDPARAM_ 502
-# define IN_ 503
-# define OUT_ 504
-# define OPT_ 505
-# define PARAM_ 506
-# define _OVERRIDE 507
-# define WITH_ 508
-# define NULL_ 509
-# define HRESULT_ 510
-# define CARRAY_ 511
-# define USERDEFINED_ 512
-# define RECORD_ 513
-# define FILETIME_ 514
-# define BLOB_ 515
-# define STREAM_ 516
-# define STORAGE_ 517
-# define STREAMED_OBJECT_ 518
-# define STORED_OBJECT_ 519
-# define BLOB_OBJECT_ 520
-# define CF_ 521
-# define CLSID_ 522
-# define VECTOR_ 523
-# define _SUBSYSTEM 524
-# define _CORFLAGS 525
-# define ALIGNMENT_ 526
-# define _IMAGEBASE 527
-# define _STACKRESERVE 528
-# define _TYPEDEF 529
-# define _TEMPLATE 530
-# define _TYPELIST 531
-# define _MSCORLIB 532
-# define P_DEFINE 533
-# define P_UNDEF 534
-# define P_IFDEF 535
-# define P_IFNDEF 536
-# define P_ELSE 537
-# define P_ENDIF 538
-# define P_INCLUDE 539
-#define yyclearin yychar = -1
-#define yyerrok yyerrflag = 0
-#ifndef YYMAXDEPTH
-#define YYMAXDEPTH 150
-#endif
-YYSTYPE yylval, yyval;
-#ifndef YYFARDATA
-#define YYFARDATA /*nothing*/
-#endif
-#if ! defined YYSTATIC
-#define YYSTATIC /*nothing*/
-#endif
-#if ! defined YYCONST
-#define YYCONST /*nothing*/
-#endif
-#ifndef YYACT
-#define YYACT yyact
-#endif
-#ifndef YYPACT
-#define YYPACT yypact
-#endif
-#ifndef YYPGO
-#define YYPGO yypgo
-#endif
-#ifndef YYR1
-#define YYR1 yyr1
-#endif
-#ifndef YYR2
-#define YYR2 yyr2
-#endif
-#ifndef YYCHK
-#define YYCHK yychk
-#endif
-#ifndef YYDEF
-#define YYDEF yydef
-#endif
-#ifndef YYV
-#define YYV yyv
-#endif
-#ifndef YYS
-#define YYS yys
-#endif
-#ifndef YYLOCAL
-#define YYLOCAL
-#endif
-#ifndef YYR_T
-#define YYR_T int
-#endif
-typedef YYR_T yyr_t;
-#ifndef YYEXIND_T
-#define YYEXIND_T unsigned int
-#endif
-typedef YYEXIND_T yyexind_t;
-#ifndef YYOPTTIME
-#define YYOPTTIME 0
-#endif
-# define YYERRCODE 256
-
-#line 2051 "asmparse.y"
-
-
-#include "grammar_after.cpp"
-YYSTATIC YYCONST short yyexca[] = {
-#if !(YYOPTTIME)
--1, 1,
-#endif
- 0, -1,
- -2, 0,
-#if !(YYOPTTIME)
--1, 452,
-#endif
- 41, 532,
- -2, 308,
-#if !(YYOPTTIME)
--1, 621,
-#endif
- 274, 549,
- 47, 549,
- -2, 227,
-#if !(YYOPTTIME)
--1, 642,
-#endif
- 40, 307,
- 60, 307,
- -2, 549,
-#if !(YYOPTTIME)
--1, 663,
-#endif
- 41, 532,
- -2, 308,
-#if !(YYOPTTIME)
--1, 686,
-#endif
- 274, 549,
- 47, 549,
- -2, 510,
-#if !(YYOPTTIME)
--1, 803,
-#endif
- 123, 232,
- -2, 549,
-#if !(YYOPTTIME)
--1, 828,
-#endif
- 41, 532,
- -2, 308,
-#if !(YYOPTTIME)
--1, 953,
-#endif
- 41, 532,
- -2, 308,
-#if !(YYOPTTIME)
--1, 986,
-#endif
- 41, 532,
- -2, 308,
-#if !(YYOPTTIME)
--1, 987,
-#endif
- 41, 532,
- -2, 308,
-#if !(YYOPTTIME)
--1, 1308,
-#endif
- 41, 532,
- -2, 308,
-#if !(YYOPTTIME)
--1, 1309,
-#endif
- 41, 532,
- -2, 308,
-#if !(YYOPTTIME)
--1, 1315,
-#endif
- 41, 532,
- -2, 308,
-#if !(YYOPTTIME)
--1, 1322,
-#endif
- 41, 532,
- -2, 308,
-#if !(YYOPTTIME)
--1, 1447,
-#endif
- 41, 532,
- -2, 308,
-#if !(YYOPTTIME)
--1, 1479,
-#endif
- 41, 532,
- -2, 308,
-#if !(YYOPTTIME)
--1, 1545,
-#endif
- 41, 532,
- -2, 308,
-#if !(YYOPTTIME)
--1, 1562,
-#endif
- 41, 532,
- -2, 308,
-
-};
-
-# define YYNPROD 838
-#if YYOPTTIME
-YYSTATIC YYCONST yyexind_t yyexcaind[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 8, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 14, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 20, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 24, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 30, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 34, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 38, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 42, 46, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 50, 54,
- 0, 0, 0, 0, 0, 58, 0, 0, 0, 0,
- 0, 0, 62, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 66, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 70,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 74, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 78
-};
-#endif
-# define YYLAST 3904
-
-YYSTATIC YYCONST short YYFARDATA YYACT[] = {
- 699, 1398, 1121, 1466, 658, 1467, 639, 1024, 1465, 878,
- 1464, 963, 784, 753, 964, 221, 775, 26, 698, 725,
- 73, 75, 275, 414, 624, 877, 966, 1399, 535, 191,
- 477, 1503, 150, 788, 751, 756, 1134, 110, 1065, 107,
- 690, 852, 273, 153, 219, 660, 24, 44, 776, 218,
- 307, 10, 190, 176, 78, 81, 6, 86, 5, 598,
- 673, 262, 204, 515, 3, 188, 217, 983, 17, 301,
- 603, 136, 76, 1550, 1194, 1242, 214, 264, 7, 1238,
- 1057, 1239, 1113, 1111, 85, 1112, 580, 74, 715, 88,
- 87, 137, 89, 300, 115, 56, 139, 712, 672, 113,
- 1058, 98, 112, 178, 179, 180, 181, 74, 272, 696,
- 322, 519, 1015, 461, 220, 56, 18, 452, 536, 338,
- 278, 88, 87, 1021, 89, 268, 216, 269, 1240, 225,
- 56, 265, 277, 277, 1228, 1229, 106, 1226, 1227, 590,
- 277, 343, 361, 360, 359, 358, 654, 368, 345, 653,
- 68, 310, 312, 314, 316, 318, 185, 1554, 460, 1126,
- 1127, 1414, 98, 931, 932, 327, 277, 348, 339, 1027,
- 342, 778, 1026, 779, 373, 366, 154, 277, 695, 133,
- 694, 991, 379, 271, 362, 84, 258, 364, 363, 376,
- 614, 192, 387, 105, 1519, 662, 513, 930, 365, 1059,
- 369, 202, 203, 371, 370, 1487, 374, 1264, 596, 450,
- 661, 451, 763, 372, 416, 469, 186, 467, 471, 470,
- 442, 26, 74, 376, 456, 417, 418, 346, 376, 1559,
- 352, 472, 474, 599, 353, 305, 483, 388, 88, 87,
- 596, 89, 410, 1263, 1478, 500, 492, 1314, 457, 441,
- 24, 1200, 357, 491, 435, 10, 825, 797, 787, 56,
- 486, 432, 490, 428, 475, 478, 479, 773, 476, 429,
- 494, 434, 17, 192, 108, 666, 511, 511, 528, 534,
- 375, 433, 7, 351, 267, 321, 480, 481, 473, 485,
- 152, 710, 74, 484, 1234, 540, 1345, 116, 1496, 1391,
- 56, 1540, 499, 80, 79, 498, 543, 493, 1417, 571,
- 959, 268, 1351, 1544, 574, 348, 575, 154, 576, 436,
- 18, 266, 548, 1335, 1116, 578, 579, 504, 541, 46,
- 420, 544, 421, 422, 423, 933, 934, 570, 935, 88,
- 572, 947, 89, 573, 46, 594, 854, 855, 856, 1128,
- 640, 641, 600, 135, 198, 88, 87, 962, 89, 199,
- 1541, 200, 568, 1510, 192, 487, 1341, 201, 612, 154,
- 755, 482, 277, 674, 1543, 510, 510, 527, 533, 74,
- 605, 744, 745, 746, 195, 808, 182, 623, 943, 611,
- 599, 581, 582, 1141, 497, 1233, 700, 1252, 1142, 196,
- 565, 367, 375, 620, 595, 258, 610, 88, 87, 518,
- 89, 74, 606, 607, 608, 609, 747, 748, 749, 1542,
- 643, 613, 599, 537, 340, 341, 634, 1489, 348, 807,
- 459, 618, 619, 621, 780, 1130, 321, 876, 648, 649,
- 638, 88, 87, 177, 89, 1231, 88, 87, 847, 89,
- 152, 781, 702, 754, 347, 650, 664, 1502, 413, 88,
- 87, 670, 946, 1488, 651, 88, 87, 155, 89, 681,
- 642, 1518, 1126, 1127, 545, 743, 1118, 177, 993, 994,
- 995, 996, 177, 587, 505, 859, 352, 1513, 667, 988,
- 353, 678, 80, 79, 479, 177, 647, 692, 646, 1512,
- 782, 1511, 61, 62, 47, 63, 536, 1508, 357, 645,
- 685, 198, 741, 669, 480, 481, 199, 689, 200, 82,
- 63, 74, 701, 479, 201, 711, 680, 453, 72, 679,
- 88, 87, 519, 89, 512, 520, 74, 507, 508, 351,
- 686, 195, 88, 480, 481, 89, 74, 723, 71, 70,
- 354, 355, 356, 538, 691, 216, 196, 1141, 225, 1506,
- 1241, 724, 1142, 675, 676, 677, 720, 657, 721, 49,
- 50, 51, 52, 53, 54, 55, 671, 709, 74, 644,
- 479, 730, 1504, 80, 79, 714, 80, 79, 348, 49,
- 50, 51, 52, 53, 54, 55, 719, 74, 1141, 716,
- 480, 481, 726, 1142, 49, 50, 51, 52, 53, 54,
- 55, 156, 157, 158, 69, 758, 74, 542, 74, 88,
- 87, 592, 89, 600, 67, 764, 765, 155, 88, 87,
- 688, 89, 74, 783, 98, 638, 729, 1320, 1319, 1318,
- 1317, 750, 74, 697, 325, 74, 703, 1172, 1171, 1170,
- 1169, 542, 705, 348, 706, 177, 377, 1499, 324, 769,
- 770, 771, 1337, 1338, 1339, 642, 815, 789, 813, 819,
- 853, 88, 87, 816, 89, 822, 541, 1180, 801, 802,
- 80, 79, 798, 823, 88, 812, 806, 89, 74, 66,
- 818, 626, 627, 628, 74, 1117, 833, 834, 762, 1450,
- 495, 826, 216, 786, 591, 225, 1439, 800, 793, 803,
- 74, 809, 796, 636, 846, 824, 382, 383, 384, 385,
- 817, 152, 74, 857, 74, 56, 629, 630, 631, 922,
- 74, 740, 821, 49, 50, 51, 52, 53, 54, 55,
- 1437, 850, 936, 937, 860, 1490, 516, 761, 88, 87,
- 375, 89, 832, 1327, 844, 1247, 1243, 1244, 1245, 1246,
- 1179, 1435, 769, 600, 949, 192, 845, 942, 1433, 848,
- 276, 156, 157, 158, 49, 50, 51, 52, 53, 54,
- 55, 97, 74, 924, 111, 925, 926, 927, 928, 929,
- 952, 1001, 1416, 1407, 985, 152, 635, 938, 1406, 277,
- 1013, 965, 362, 1326, 1011, 74, 354, 355, 356, 442,
- 1000, 1009, 528, 605, 1404, 585, 954, 584, 583, 145,
- 1390, 1012, 948, 1388, 586, 799, 960, 955, 277, 1017,
- 958, 692, 692, 1032, 1378, 1376, 1237, 350, 441, 999,
- 1008, 817, 1022, 435, 997, 1007, 851, 1374, 1037, 1014,
- 432, 817, 428, 849, 1019, 1035, 1016, 1018, 429, 1039,
- 434, 989, 326, 323, 88, 87, 94, 89, 74, 1372,
- 433, 1033, 1034, 1045, 352, 772, 828, 277, 353, 1030,
- 80, 79, 479, 1050, 277, 56, 1370, 1368, 691, 691,
- 88, 87, 348, 89, 74, 954, 357, 337, 155, 348,
- 1366, 1364, 480, 481, 668, 1362, 817, 1359, 436, 998,
- 1006, 527, 1356, 1123, 1354, 1350, 56, 1334, 1312, 1055,
- 152, 1196, 88, 87, 718, 89, 177, 351, 1044, 1053,
- 193, 615, 1043, 194, 1051, 348, 1042, 352, 1041, 46,
- 352, 353, 1122, 1023, 768, 820, 1067, 814, 1068, 1126,
- 1127, 501, 733, 617, 616, 1124, 198, 177, 1132, 357,
- 145, 199, 357, 200, 88, 87, 577, 89, 758, 201,
- 564, 1300, 155, 1236, 308, 1119, 455, 109, 1054, 1140,
- 1129, 92, 529, 1138, 1125, 1394, 195, 1298, 1115, 1185,
- 351, 1183, 1184, 351, 88, 87, 1186, 89, 1178, 277,
- 177, 196, 1296, 1491, 1064, 1060, 1061, 1062, 1063, 1025,
- 1492, 1133, 145, 1182, 1415, 328, 329, 330, 1294, 1181,
- 956, 96, 1301, 590, 104, 103, 102, 101, 1219, 99,
- 100, 105, 56, 1, 1175, 1332, 1195, 1173, 1299, 1203,
- 332, 941, 156, 157, 158, 1167, 1187, 1188, 1189, 1190,
- 1230, 766, 1202, 1297, 1165, 1232, 1191, 1192, 1193, 80,
- 79, 479, 588, 1131, 1223, 1225, 1224, 1222, 984, 1295,
- 1235, 1197, 1400, 88, 87, 1163, 89, 1198, 1161, 1199,
- 945, 480, 481, 589, 1218, 1176, 189, 708, 1174, 88,
- 87, 1005, 89, 1003, 1004, 1159, 1168, 155, 1010, 46,
- 707, 205, 152, 1157, 704, 1166, 633, 1412, 412, 187,
- 625, 790, 61, 62, 47, 63, 156, 157, 158, 1248,
- 1177, 192, 192, 192, 192, 177, 1164, 277, 1268, 1162,
- 46, 192, 192, 192, 331, 1266, 333, 334, 335, 336,
- 1155, 625, 1251, 192, 1411, 1265, 1160, 1269, 1410, 1271,
- 1273, 1274, 1255, 1277, 1158, 1279, 1280, 1281, 1282, 1283,
- 1284, 1285, 1270, 1287, 1288, 1289, 1290, 1291, 1292, 1293,
- 1254, 1401, 1259, 56, 1302, 1303, 1153, 1305, 1304, 1151,
- 1272, 1149, 1275, 1276, 1147, 1278, 1221, 1048, 1267, 1047,
- 836, 1156, 1307, 1286, 354, 355, 356, 1145, 1143, 49,
- 50, 51, 52, 53, 54, 55, 742, 1316, 118, 119,
- 120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
- 130, 131, 132, 665, 1313, 352, 317, 1154, 454, 353,
- 1152, 315, 1150, 313, 1328, 1148, 378, 1330, 1331, 521,
- 1321, 156, 157, 158, 311, 45, 46, 357, 1146, 1144,
- 1336, 1340, 309, 1333, 817, 41, 43, 354, 355, 356,
- 354, 355, 356, 1135, 1342, 277, 277, 1140, 1552, 526,
- 590, 88, 87, 306, 89, 63, 415, 308, 351, 155,
- 1315, 1343, 308, 1257, 308, 56, 277, 503, 1452, 512,
- 590, 1451, 507, 508, 140, 308, 1380, 1381, 1382, 1383,
- 1384, 1385, 1386, 308, 944, 1347, 63, 177, 590, 1539,
- 590, 1329, 1344, 1392, 1393, 193, 531, 1346, 194, 532,
- 1397, 1396, 940, 831, 308, 138, 1379, 1402, 1403, 1031,
- 1524, 590, 923, 1408, 590, 590, 1395, 830, 811, 767,
- 760, 198, 177, 1405, 717, 566, 199, 349, 200, 258,
- 303, 792, 1564, 117, 201, 97, 1555, 1553, 1140, 49,
- 50, 51, 52, 53, 54, 55, 1546, 1523, 817, 1486,
- 1485, 195, 1484, 1454, 1449, 1446, 1443, 1442, 1438, 56,
- 524, 1436, 1434, 1432, 1419, 1413, 196, 46, 1409, 1389,
- 49, 50, 51, 52, 53, 54, 55, 134, 1445, 1387,
- 1377, 1375, 1373, 1371, 1369, 1367, 1365, 1363, 1361, 1360,
- 526, 1455, 1456, 1457, 1358, 1357, 1355, 1453, 1353, 1444,
- 1448, 1352, 63, 156, 157, 158, 1349, 1324, 1348, 1325,
- 1458, 1323, 523, 1311, 1470, 525, 1310, 1471, 1469, 1468,
- 1306, 1256, 1253, 258, 1476, 693, 1220, 88, 87, 1114,
- 89, 1052, 1481, 1038, 1480, 1036, 1029, 1028, 1020, 961,
- 951, 950, 56, 1498, 939, 1483, 1505, 1507, 1509, 858,
- 1505, 1507, 1509, 530, 841, 840, 1495, 1507, 1516, 838,
- 1520, 1517, 1515, 1514, 1522, 1521, 88, 835, 829, 89,
- 827, 56, 810, 1497, 1500, 1501, 791, 774, 738, 46,
- 737, 1538, 736, 1493, 735, 734, 49, 50, 51, 52,
- 53, 54, 55, 732, 731, 1529, 1505, 1507, 1509, 684,
- 637, 524, 569, 425, 424, 344, 258, 320, 206, 1562,
- 1547, 1525, 817, 1545, 1479, 1475, 1474, 1473, 1472, 1447,
- 1534, 1441, 1440, 1431, 1430, 354, 355, 356, 1551, 1429,
- 1549, 1428, 1427, 1548, 1535, 1536, 1537, 449, 1426, 1425,
- 1424, 1423, 1561, 63, 1422, 1421, 1560, 1563, 1420, 1418,
- 1300, 1298, 1296, 523, 1294, 1322, 525, 1175, 1173, 1557,
- 88, 1558, 1167, 89, 1556, 1526, 1527, 1528, 1530, 1531,
- 1532, 1533, 1165, 46, 1163, 96, 1161, 1159, 104, 103,
- 102, 101, 56, 99, 100, 105, 1157, 1155, 1153, 1151,
- 1149, 1309, 1308, 817, 1250, 1249, 1066, 1056, 1049, 1040,
- 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
- 255, 256, 257, 987, 986, 953, 843, 59, 842, 839,
- 837, 208, 259, 210, 228, 212, 213, 49, 50, 51,
- 52, 53, 54, 55, 728, 41, 43, 727, 713, 687,
- 683, 682, 663, 88, 632, 602, 89, 601, 593, 567,
- 547, 546, 61, 62, 47, 63, 46, 496, 419, 411,
- 874, 386, 319, 223, 304, 522, 514, 868, 517, 869,
- 870, 871, 509, 506, 56, 502, 302, 222, 36, 184,
- 93, 33, 468, 466, 465, 46, 464, 463, 244, 462,
- 227, 243, 215, 209, 245, 246, 247, 248, 249, 250,
- 251, 252, 253, 254, 255, 256, 257, 863, 864, 865,
- 95, 59, 226, 224, 207, 208, 259, 210, 228, 212,
- 213, 211, 879, 31, 56, 1002, 992, 439, 795, 41,
- 43, 431, 794, 430, 427, 539, 1046, 270, 83, 49,
- 50, 51, 52, 53, 54, 55, 61, 62, 47, 63,
- 29, 57, 862, 866, 867, 34, 872, 223, 25, 873,
- 16, 263, 15, 14, 261, 13, 260, 12, 11, 9,
- 8, 222, 1086, 4, 2, 234, 242, 245, 246, 247,
- 248, 249, 250, 251, 252, 253, 254, 255, 256, 257,
- 990, 241, 240, 239, 59, 238, 46, 237, 208, 259,
- 210, 228, 212, 213, 236, 235, 226, 224, 233, 232,
- 231, 230, 41, 43, 229, 114, 77, 42, 56, 38,
- 30, 58, 32, 59, 752, 656, 655, 1482, 299, 61,
- 62, 47, 63, 49, 50, 51, 52, 53, 54, 55,
- 223, 41, 43, 90, 183, 861, 1139, 757, 785, 1258,
- 957, 1137, 1136, 604, 222, 1461, 1460, 1459, 61, 62,
- 47, 63, 1477, 1463, 1462, 60, 35, 1201, 1120, 597,
- 659, 21, 777, 91, 37, 1069, 739, 65, 64, 197,
- 875, 39, 40, 0, 426, 0, 0, 0, 0, 226,
- 224, 0, 982, 981, 980, 0, 975, 974, 973, 972,
- 0, 970, 971, 105, 0, 979, 978, 977, 976, 0,
- 0, 0, 969, 967, 0, 0, 49, 50, 51, 52,
- 53, 54, 55, 0, 0, 0, 0, 0, 0, 0,
- 38, 30, 58, 32, 59, 0, 19, 20, 46, 22,
- 23, 48, 0, 27, 28, 49, 50, 51, 52, 53,
- 54, 55, 41, 43, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 61,
- 62, 47, 63, 0, 0, 0, 60, 35, 968, 0,
- 0, 0, 21, 0, 0, 37, 444, 1097, 0, 874,
- 0, 0, 39, 40, 0, 0, 868, 0, 869, 870,
- 871, 0, 0, 0, 0, 0, 1073, 1074, 0, 1081,
- 1095, 1075, 1076, 1077, 1078, 0, 1079, 1080, 0, 1096,
- 1082, 1083, 1084, 1085, 0, 0, 0, 0, 0, 0,
- 0, 0, 46, 0, 0, 0, 863, 864, 865, 0,
- 0, 0, 0, 0, 0, 0, 0, 19, 20, 0,
- 22, 23, 48, 0, 27, 28, 49, 50, 51, 52,
- 53, 54, 55, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 448, 0, 58, 32, 59, 0, 0, 0,
- 444, 862, 866, 867, 0, 872, 445, 0, 873, 0,
- 0, 446, 0, 0, 41, 43, 0, 146, 874, 0,
- 0, 0, 0, 0, 0, 868, 0, 869, 870, 871,
- 0, 61, 62, 47, 63, 0, 437, 438, 0, 921,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 447, 0, 0, 0,
- 0, 0, 0, 0, 0, 863, 864, 865, 49, 50,
- 51, 52, 53, 54, 55, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 448, 0, 58, 32,
- 59, 443, 440, 0, 0, 0, 0, 0, 0, 0,
- 445, 0, 0, 0, 0, 446, 0, 0, 41, 43,
- 862, 866, 867, 0, 872, 0, 0, 873, 49, 50,
- 51, 52, 53, 54, 55, 61, 62, 47, 63, 1494,
- 437, 438, 1071, 1072, 0, 1087, 1088, 1089, 0, 1090,
- 1091, 0, 0, 1092, 1093, 0, 1094, 0, 0, 0,
- 447, 0, 0, 0, 0, 0, 0, 0, 0, 1070,
- 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107,
- 1108, 1109, 1110, 893, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 443, 440, 920, 0, 0,
- 0, 0, 885, 886, 0, 894, 911, 887, 888, 889,
- 890, 0, 891, 892, 0, 912, 895, 896, 897, 898,
- 893, 0, 49, 50, 51, 52, 53, 54, 55, 0,
- 0, 0, 0, 0, 920, 146, 0, 0, 0, 885,
- 886, 0, 894, 911, 887, 888, 889, 890, 0, 891,
- 892, 0, 912, 895, 896, 897, 898, 0, 0, 0,
- 909, 0, 913, 0, 0, 175, 0, 915, 0, 151,
- 148, 163, 161, 170, 0, 164, 165, 166, 167, 0,
- 168, 169, 917, 0, 171, 172, 173, 174, 563, 0,
- 0, 142, 162, 152, 0, 0, 0, 909, 0, 913,
- 141, 147, 0, 0, 915, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 918, 143, 144, 149, 917,
- 555, 0, 549, 550, 551, 552, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 146, 0, 0, 0, 0,
- 352, 0, 0, 0, 768, 0, 0, 0, 0, 0,
- 160, 0, 918, 0, 0, 0, 0, 0, 557, 558,
- 559, 560, 357, 0, 554, 0, 0, 0, 561, 562,
- 553, 0, 0, 0, 0, 982, 981, 980, 0, 975,
- 974, 973, 972, 0, 970, 971, 105, 0, 979, 978,
- 977, 976, 0, 622, 0, 969, 967, 0, 0, 0,
- 0, 0, 0, 0, 0, 880, 0, 881, 882, 883,
- 884, 899, 900, 901, 916, 902, 903, 904, 905, 906,
- 907, 908, 910, 914, 0, 0, 0, 919, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 880, 0, 881, 882, 883, 884, 899, 900,
- 901, 916, 902, 903, 904, 905, 906, 907, 908, 910,
- 914, 968, 88, 87, 919, 89, 0, 0, 0, 0,
- 155, 0, 556, 175, 0, 0, 0, 151, 148, 163,
- 161, 170, 0, 164, 165, 166, 167, 0, 168, 169,
- 0, 0, 171, 172, 173, 174, 146, 0, 177, 142,
- 162, 352, 0, 0, 0, 353, 0, 0, 141, 147,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 357, 143, 144, 149, 0, 0, 175,
- 0, 0, 0, 0, 0, 163, 161, 170, 0, 164,
- 165, 166, 167, 0, 168, 169, 0, 0, 171, 172,
- 173, 174, 0, 0, 622, 1261, 162, 0, 160, 159,
- 0, 0, 88, 87, 0, 89, 0, 0, 0, 0,
- 155, 0, 0, 175, 0, 0, 0, 151, 148, 163,
- 161, 170, 0, 164, 165, 166, 167, 0, 168, 169,
- 0, 0, 171, 172, 173, 174, 0, 0, 177, 142,
- 162, 0, 0, 1262, 0, 0, 0, 0, 141, 147,
- 0, 0, 0, 0, 156, 157, 158, 0, 0, 0,
- 0, 1260, 0, 0, 143, 144, 149, 0, 0, 0,
- 0, 0, 0, 0, 297, 198, 146, 0, 0, 0,
- 199, 352, 200, 0, 0, 353, 0, 0, 201, 0,
- 0, 63, 0, 0, 0, 0, 0, 0, 160, 0,
- 354, 355, 356, 357, 0, 195, 284, 0, 279, 280,
- 281, 282, 283, 0, 640, 641, 0, 287, 0, 0,
- 196, 0, 0, 0, 0, 0, 285, 0, 0, 0,
- 295, 0, 286, 0, 622, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 288, 289, 290, 291, 292, 293,
- 294, 298, 0, 0, 156, 157, 158, 296, 0, 0,
- 0, 0, 0, 88, 87, 0, 89, 0, 0, 0,
- 146, 155, 0, 0, 175, 0, 0, 0, 151, 148,
- 163, 161, 170, 0, 164, 165, 166, 167, 0, 168,
- 169, 0, 0, 171, 172, 173, 174, 0, 0, 177,
- 142, 162, 0, 0, 0, 0, 0, 0, 0, 141,
- 147, 0, 0, 0, 348, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 143, 144, 149, 274, 1217,
- 1216, 1211, 0, 1210, 1209, 1208, 1207, 146, 1205, 1206,
- 105, 0, 1215, 1214, 1213, 1212, 0, 0, 0, 0,
- 0, 1204, 0, 0, 0, 0, 0, 0, 0, 160,
- 0, 354, 355, 356, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 640, 641, 982, 981, 980,
- 0, 975, 974, 973, 972, 0, 970, 971, 105, 0,
- 979, 978, 977, 976, 0, 274, 0, 969, 967, 0,
- 0, 0, 0, 88, 87, 0, 89, 0, 0, 0,
- 0, 155, 0, 0, 175, 156, 157, 158, 151, 148,
- 163, 161, 170, 0, 164, 165, 166, 167, 0, 168,
- 169, 0, 0, 171, 172, 173, 174, 146, 0, 177,
- 142, 162, 0, 0, 0, 0, 0, 0, 0, 141,
- 147, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 968, 0, 143, 144, 149, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 274, 0, 88, 87, 160,
- 89, 354, 355, 356, 146, 155, 0, 0, 175, 0,
- 0, 0, 151, 148, 163, 161, 170, 0, 164, 165,
- 166, 167, 0, 168, 169, 0, 0, 171, 172, 173,
- 174, 0, 0, 177, 142, 162, 0, 0, 0, 0,
- 0, 0, 0, 141, 147, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 156, 157, 158, 0, 143,
- 144, 149, 274, 805, 88, 87, 0, 89, 0, 0,
- 0, 0, 155, 0, 0, 175, 0, 0, 0, 151,
- 148, 163, 161, 170, 0, 164, 165, 166, 167, 0,
- 168, 169, 0, 160, 171, 172, 173, 174, 146, 0,
- 177, 142, 162, 0, 0, 0, 0, 804, 0, 0,
- 141, 147, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 143, 144, 149, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 156,
- 157, 158, 0, 0, 0, 0, 274, 0, 0, 0,
- 160, 159, 0, 0, 88, 87, 146, 89, 0, 0,
- 0, 0, 155, 0, 0, 175, 0, 0, 0, 151,
- 148, 163, 161, 170, 0, 164, 165, 166, 167, 0,
- 168, 169, 0, 0, 171, 172, 173, 174, 0, 0,
- 177, 142, 162, 0, 0, 0, 0, 0, 0, 0,
- 141, 147, 0, 0, 0, 0, 156, 157, 158, 0,
- 0, 0, 0, 0, 274, 0, 143, 144, 149, 0,
- 0, 88, 87, 0, 89, 0, 0, 0, 0, 155,
- 0, 0, 175, 0, 0, 0, 151, 148, 163, 161,
- 170, 0, 164, 165, 166, 167, 0, 168, 169, 0,
- 160, 171, 172, 173, 174, 0, 0, 177, 142, 162,
- 0, 0, 0, 0, 0, 0, 0, 759, 147, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 143, 144, 149, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 146, 0, 0, 0, 0, 156, 157, 158, 0,
- 0, 0, 0, 0, 0, 88, 87, 160, 89, 0,
- 0, 0, 0, 155, 0, 0, 175, 0, 0, 0,
- 151, 148, 163, 161, 170, 0, 164, 165, 166, 167,
- 0, 168, 169, 0, 0, 171, 172, 173, 174, 0,
- 0, 177, 142, 162, 0, 0, 146, 0, 0, 0,
- 0, 141, 147, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 156, 157, 158, 0, 143, 144, 149,
- 0, 0, 0, 88, 87, 0, 89, 0, 0, 0,
- 0, 155, 0, 0, 175, 0, 0, 0, 151, 148,
- 163, 161, 170, 0, 164, 165, 166, 167, 0, 168,
- 169, 652, 146, 171, 172, 173, 174, 0, 0, 177,
- 142, 162, 88, 87, 0, 89, 0, 0, 0, 141,
- 147, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 143, 144, 149, 0, 0,
- 0, 0, 0, 0, 0, 0, 409, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 146, 156, 157, 158,
- 988, 0, 0, 0, 0, 0, 0, 0, 0, 458,
- 0, 0, 0, 0, 391, 0, 0, 0, 407, 0,
- 0, 389, 390, 0, 0, 0, 393, 394, 405, 395,
- 396, 397, 398, 399, 400, 401, 402, 392, 0, 0,
- 0, 0, 0, 406, 0, 0, 404, 0, 0, 0,
- 146, 0, 0, 403, 722, 0, 0, 0, 0, 0,
- 0, 0, 408, 0, 0, 156, 157, 158, 488, 175,
- 489, 0, 0, 151, 148, 163, 161, 170, 0, 164,
- 165, 166, 167, 0, 168, 169, 0, 0, 171, 172,
- 173, 174, 0, 0, 177, 142, 162, 0, 0, 0,
- 0, 0, 0, 0, 141, 147, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 143, 144, 149, 380, 175, 381, 0, 0, 151, 148,
- 163, 161, 170, 0, 164, 165, 166, 167, 0, 168,
- 169, 0, 0, 171, 172, 173, 174, 0, 0, 0,
- 142, 162, 0, 0, 160, 0, 0, 0, 0, 141,
- 147, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 143, 144, 149, 0, 0,
- 175, 0, 0, 0, 151, 148, 163, 161, 170, 0,
- 164, 165, 166, 167, 0, 168, 169, 0, 0, 171,
- 172, 173, 174, 0, 0, 0, 142, 162, 0, 160,
- 0, 0, 0, 0, 0, 141, 147, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 143, 144, 149, 175, 0, 0, 0, 151, 148,
- 163, 161, 170, 0, 164, 165, 166, 167, 0, 168,
- 169, 0, 0, 171, 172, 173, 174, 0, 0, 0,
- 142, 162, 0, 0, 0, 160, 0, 0, 0, 141,
- 147, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 143, 144, 149, 175, 0,
- 0, 0, 151, 148, 163, 161, 170, 0, 164, 165,
- 166, 167, 0, 168, 169, 0, 0, 171, 172, 173,
- 174, 0, 0, 0, 142, 162, 0, 0, 0, 160,
- 0, 0, 0, 141, 147, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 143,
- 144, 149, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 160
-};
-
-YYSTATIC YYCONST short YYFARDATA YYPACT[] = {
--1000, 1543,-1000, 566, 501,-1000,-1000,-1000,-1000,-1000,
--1000,-1000, 491, 426, 425, 405,-1000,-1000,-1000, 28,
- 28, -454, 39, 39,-1000,-1000,-1000, 396,-1000, -129,
- 411,-1000, 890, 743, 7, 886, 28, -366, -369,-1000,
- -171, 777, 7, 777,-1000,-1000,-1000, 90, 2292, 411,
- 411, 411, 411,-1000,-1000, 124,-1000,-1000,-1000, -162,
- 1048,-1000,-1000, 1046, 7, 7,-1000,-1000, 1403,-1000,
--1000,-1000,-1000,-1000,-1000,-1000, 28, -139,-1000,-1000,
--1000,-1000, 359, -132, 2954, 1220,-1000,-1000,-1000,-1000,
- 2430,-1000, 28,-1000, 1317,-1000, 1308, 1644, 7, 1233,
- 1212, 1204, 1193, 1191, 1186, 1642, 1486, 18,-1000, 28,
- 600, 662,-1000,-1000, 95, 1220, 411, 2954,-1000,-1000,
--1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
--1000,-1000,-1000, 1484, 166, 1303, 448, -244, -245, -246,
- -247, 359,-1000, -118, 359, 661, 368,-1000,-1000, -76,
--1000, 3547, 186, 1189,-1000,-1000,-1000,-1000,-1000, 3383,
--1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
- 435,-1000,-1000,-1000,-1000,-1000, 1220, 1641, 326, 1220,
- 1220, 1220,-1000, 3222, 79,-1000,-1000, 1639, 1047, 2854,
--1000, 3547,-1000,-1000,-1000, 216, 216,-1000, 1638,-1000,
--1000, 29, 1483, 1482, 1779, 1432,-1000,-1000, 28,-1000,
- 28, 77,-1000,-1000,-1000,-1000, 1170,-1000,-1000,-1000,
--1000,-1000, 885, 28, 3183,-1000, 67, -94,-1000,-1000,
- 424, 28, 39, 228, 7, 424, 661, 3328, 2954, -95,
- 216, 2854, 1637,-1000, 282,-1000,-1000,-1000,-1000,-1000,
--1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
- 826, 71, 1114, 857,-1000, 87,-1000, 298, 359,-1000,
--1000, 2954,-1000,-1000, 181, 899, 216, 411,-1000,-1000,
--1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
--1000,-1000,-1000,-1000,-1000,-1000,-1000, 1631, 1630, 2084,
- 877, 275, 1301, 1629, 79, 1481, 0,-1000, 28, 0,
--1000, 39,-1000, 28,-1000, 28,-1000, 28,-1000,-1000,
--1000,-1000, 873,-1000, 28, 28,-1000, 1220,-1000,-1000,
--1000, -387,-1000,-1000,-1000,-1000,-1000, 662, 488, 94,
--1000,-1000, 1220, 1022,-1000, 1292, 581, 1628,-1000, 82,
- 411, 115,-1000,-1000,-1000, 1627, 1625, 3547, 411, 411,
- 411, 411,-1000, 359,-1000,-1000, 3547, 604,-1000, 1220,
--1000, -90,-1000, 899, 838, 861, 860, 411, 411, 2693,
--1000,-1000,-1000,-1000,-1000,-1000, 28, 1292, 1081,-1000,
--1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
--1000,-1000,-1000,-1000,-1000, 362,-1000,-1000,-1000, 1624,
- 1045,-1000, 673, 1479,-1000,-1000, 2553,-1000,-1000, 28,
--1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, 386,
- 375, 373,-1000,-1000,-1000,-1000,-1000, 28, 28, 332,
- 3115,-1000,-1000, -214, -217,-1000,-1000,-1000,-1000,-1000,
--1000,-1000, -65, 1622,-1000, 28, 1165, 1, 216, 813,
- 28,-1000, -94, 63, 63, 63, 63, 2954, 282,-1000,
--1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
- 1621, 1620, 1478,-1000,-1000,-1000, 2693,-1000,-1000,-1000,
--1000, 1292, 1619, 7, 3547,-1000, 424, 1320,-1000, -136,
- -138,-1000,-1000, -356,-1000,-1000, 7, 354, 391, 7,
--1000,-1000, 1043,-1000,-1000, 7,-1000, 7,-1000, 1039,
- 1026,-1000,-1000, 411, -177, -371, 1618,-1000,-1000,-1000,
--1000, 411, -380,-1000,-1000, -350,-1000,-1000,-1000, 1300,
--1000, 831, 411, 3547, 1220, 3493, 28, 53, 1187,-1000,
--1000,-1000,-1000,-1000,-1000,-1000, 1617,-1000,-1000,-1000,
--1000,-1000,-1000, 1614,-1000,-1000, 1317, 53, 1473,-1000,
- 1472, 859, 1464, 1463, 1461, 1459, 1457,-1000, 468, 1148,
--1000, 86, 1220,-1000,-1000,-1000, 52, 411, 53, 330,
- 108, 3021,-1000,-1000, 1296, 1220,-1000, 654,-1000,-1000,
- -63, 2954, 2954, 989, 1295, 899, 1220, 1220, 1220, 1220,
--1000, 2392,-1000, 1220,-1000, 411, 411, 411, 782, 1220,
- -7, 1220, 147, 1456,-1000, 128,-1000,-1000,-1000,-1000,
--1000,-1000, 28,-1000, 1292,-1000,-1000, 661, -16, 1051,
--1000,-1000, 1220, 1455, 1226,-1000,-1000,-1000,-1000,-1000,
--1000, -17, 216, 734, 2954, 2787, 59, 488, 1451, 1294,
--1000,-1000, 3493, -65, 854, 28, -22, 3547, 28, 1220,
- 852,-1000,-1000,-1000, 424,-1000,-1000,-1000,-1000,-1000,
--1000,-1000, 28, 39,-1000, -18, 1220, 53, 1449, 836,
- 1447, 1293, 1279,-1000, 79, 28, 28, 1446, 1132,-1000,
--1000, 1292, 1600, 1438, 1599, 1434, 1433, 1598, 1596, 1220,
- 411,-1000, 411, 28, 131, 411, 7, 2954, 411, 753,
- 902, 192, -157, 1428, 96, 1824, 120, 2016, 28,-1000,
- 1291,-1000, 883,-1000, 883, 883, 883, 883, 883, -120,
--1000, 28, 28, 411,-1000,-1000,-1000,-1000,-1000,-1000,
- 1220, 1423, 1278, 980,-1000,-1000, 263, 1260, 1019, 199,
- 78,-1000, -42, 28, 1420, 1419,-1000, 3547, 1595, 1189,
- 1189, 1189, 411, 411,-1000, 958, 270, 128,-1000,-1000,
--1000,-1000,-1000, 1418, 232, 1635, 1007, -22, 1594, 1593,
- 3439,-1000,-1000, 1685, 56, 666, 973, -22, 3547, 28,
- 1220, -337, 411, 1220,-1000,-1000, 3547,-1000,-1000, 1220,
--1000, -65, 192, 1417, -266,-1000,-1000, 1220, 2693, 850,
- 948, -144, -147, 1416, 1415, 411, 1288,-1000, -65,-1000,
- 424, 424,-1000,-1000,-1000,-1000, 354,-1000,-1000,-1000,
--1000,-1000,-1000,-1000, 1189, 1220, 1414, 28, 1220, 1412,
--1000, 411, -22, 1579, 845, 843, 839, 835,-1000, 53,
- 1715,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
--1000,-1000, 1131, 1129, 1578, 948, 79, 1410, 887, 7,
- 1577, -400, -78,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
--1000,-1000,-1000,-1000, 724,-1000,-1000,-1000,-1000,-1000,
--1000,-1000,-1000,-1000,-1000,-1000, 1576, 1576,-1000, 1576,
- 1750,-1000,-1000, -412,-1000, -402,-1000,-1000, -417,-1000,
--1000,-1000, 1408,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
- 79,-1000,-1000,-1000,-1000,-1000, 61, 432, 1220,-1000,
- 53, 630, 224,-1000, 3021, 312, 1002,-1000,-1000,-1000,
--1000,-1000, 899, -65, 1189, 1220,-1000, 411, 1219, 2954,
--1000,-1000,-1000, 200,-1000,-1000,-1000, 1158, 1157, 1144,
- 1141, 1139, 1136, 1100, 1063, 1055, 1038, 1035, 1014, 1005,
- 366, 997, 994, 7, 637, 1051, -65, -65, 28, 934,
--1000,-1000,-1000, 661, 661, 661, 661,-1000,-1000,-1000,
--1000,-1000,-1000, 661, 661, 661,-1000,-1000,-1000,-1000,
--1000, -434, 2693, 828,-1000, 661, 1220, 1187,-1000, 79,
--1000, 79, -23,-1000,-1000, 2602, 79, 28,-1000,-1000,
- 1220,-1000, 1405,-1000,-1000, 1128,-1000,-1000, -301, 1050,
- 2016,-1000,-1000,-1000,-1000, 1292,-1000, -254, -257, 28,
--1000,-1000,-1000,-1000, 352, 169, 53, 882, 745,-1000,
--1000,-1000,-1000,-1000,-1000,-1000, -423,-1000,-1000, 37,
--1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
--1000, 475,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
--1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
--1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
--1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, 28,-1000,
--1000,-1000,-1000, 1575, 1292, 1574,-1000,-1000,-1000,-1000,
--1000, 274, 1401, 1219,-1000, 128, 1400, 1239,-1000, 2348,
--1000,-1000,-1000, -56, 28, 829, 28, 2650, 28, 314,
- 28, 795, 28, 39, 28, 28, 28, 28, 28, 28,
- 28, 39, 28, 28, 28, 28, 28, 28, 28, 978,
- 962, 947, 931, 28, 28, -160, 28, 1399, 1292,-1000,
--1000, 1572, 1571, 1395, 1392, 825,-1000,-1000,-1000,-1000,
--1000,-1000,-1000,-1000, 216, -27,-1000, 1240,-1000,-1000,
- -22,-1000,-1000, 1292,-1000, 1570, 1569, 1568, 1567, 1566,
- 1557, 356, 1556, 1554, 1552, 1542, 1538, 1537,-1000,-1000,
--1000, 354,-1000, 1535, 1390, 1386,-1000,-1000,-1000,-1000,
- 1388,-1000, 710, 28,-1000, 1267, 28, 28, 974, 53,
- 824,-1000,-1000,-1000,-1000,-1000,-1000,-1000, 60, 28,
- 381, 241,-1000,-1000,-1000,-1000,-1000, 2954, 205,-1000,
--1000,-1000, 1011, 1387, 1385, 822, 49, 1380, 1377, 821,
- 1375, 819, 1374, 1373, 814, 1368, 1367, 812, 1366, 808,
- 1365, 807, 1364, 794, 1363, 793, 1362, 776, 1361, 754,
- 1360, 742, 1359, 741, 39, 28, 28, 28, 28, 28,
- 28, 28, 1358, 730, 1348, 727,-1000, 174, -65, -65,
--1000,-1000, 923, 3547, -22, -65, 1012, 1534, 1532, 1531,
- 1530, 1113, -65,-1000,-1000,-1000,-1000, 28, 721, 53,
- 705, 700, 28, 1292,-1000,-1000, 1347, 1090, 1086, 1049,
- 1344,-1000, 36,-1000, 953, 699, 45,-1000,-1000,-1000,
- 1529, 1343,-1000,-1000, 1528,-1000, 1525,-1000,-1000, 1524,
--1000,-1000, 1521,-1000, 1520,-1000, 1519,-1000, 1518,-1000,
- 1512,-1000, 1511,-1000, 1509,-1000, 1504,-1000, 1503, 1342,
- 675, 1341, 668, 1340, 647, 1337, 613,-1000, 1502,-1000,
- 1501,-1000, 1336, 1335,-1000, 2693, 1012, 1334, 1499,-1000,
- 398, 354, 1333, 606,-1000, 1247,-1000, 2053, 1332,-1000,
- 28, 28, 28,-1000,-1000, 2650,-1000,-1000,-1000,-1000,
--1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
--1000,-1000,-1000, 1498,-1000, 1497,-1000, 1496,-1000, 1495,
--1000,-1000,-1000,-1000, -30, 1494, 948, -65,-1000,-1000,
--1000, 53,-1000, 887,-1000, 1331, 1329, 1328,-1000, 164,
- 704, 2188, 257, 616, 416, 541, 518, 466, 322, 460,
- 458, 446,-1000,-1000,-1000,-1000, 430, 153, -22, -65,
--1000, 1326, 1207, 1265,-1000,-1000,-1000,-1000,-1000,-1000,
--1000,-1000, 38,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
--1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
--1000,-1000,-1000,-1000, 319, 378, 333, 272,-1000,-1000,
--1000, 1493, 1325,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
--1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, 1490, 53,
--1000,-1000,-1000,-1000,-1000, -65, -435, 28, 1227, 1316,
- -199, 1315,-1000,-1000, 216,-1000, 3547, 2693, -45, -22,
- 1012, 1489, -65, 1311,-1000
-};
-
-YYSTATIC YYCONST short YYFARDATA YYPGO[] = {
- 0, 53, 57, 6, 1900, 43, 40, 29, 1899, 0,
- 1898, 1897, 1896, 195, 50, 1895, 1893, 2, 1892, 48,
- 38, 1, 27, 30, 31, 4, 1890, 45, 22, 59,
- 1889, 136, 39, 9, 25, 7, 13, 1888, 41, 1887,
- 14, 26, 1884, 1883, 5, 3, 8, 10, 1882, 1877,
- 1876, 1875, 32, 33, 70, 1873, 1872, 1871, 1870, 12,
- 1869, 1868, 11, 1867, 35, 1866, 18, 36, 16, 24,
- 42, 23, 458, 65, 1276, 52, 127, 1864, 1863, 1848,
- 1847, 1846, 1845, 19, 34, 1844, 1353, 1837, 1836, 28,
- 784, 119, 1835, 47, 1245, 1834, 1831, 1830, 1829, 1828,
- 1825, 1824, 1817, 1815, 1813, 1812, 1811, 1796, 1795, 1033,
- 1794, 64, 62, 1793, 58, 150, 56, 76, 1790, 1789,
- 49, 1788, 1787, 1786, 1785, 1784, 1783, 61, 1782, 1781,
- 1780, 66, 114, 44, 1778, 15, 284, 1775, 1771, 1770,
- 1758, 1757, 1755, 1754, 1753, 1752, 1751, 1748, 1747, 770,
- 1746, 1745, 1743, 1742, 1741, 1734, 1713, 1712, 60, 1711,
- 1710, 113, 1709, 1708, 1707, 98, 1706, 1704, 1703, 1702,
- 1701, 1700, 1699, 69, 1696, 67, 1698, 63, 1695, 484,
- 1693, 1692, 1688, 1686, 1685, 1473
-};
-YYSTATIC YYCONST yyr_t YYFARDATA YYR1[]={
-
- 0, 109, 109, 110, 110, 110, 110, 110, 110, 110,
- 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
- 110, 110, 110, 110, 110, 110, 110, 110, 110, 136,
- 136, 36, 36, 133, 133, 133, 2, 2, 1, 1,
- 1, 9, 24, 24, 23, 23, 23, 134, 134, 134,
- 134, 134, 135, 135, 135, 135, 135, 135, 135, 135,
- 135, 93, 93, 93, 93, 94, 94, 94, 94, 10,
- 11, 73, 72, 72, 59, 61, 61, 61, 62, 62,
- 62, 65, 65, 132, 132, 132, 60, 60, 60, 60,
- 60, 60, 130, 130, 130, 119, 12, 12, 12, 12,
- 12, 12, 118, 137, 113, 138, 139, 111, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 140, 140, 141, 141, 112,
- 112, 142, 142, 56, 56, 57, 57, 69, 69, 18,
- 18, 18, 18, 18, 19, 19, 68, 68, 67, 67,
- 58, 21, 21, 22, 143, 143, 143, 143, 143, 143,
- 143, 143, 143, 143, 143, 143, 143, 143, 143, 143,
- 143, 143, 143, 116, 79, 79, 79, 79, 79, 79,
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
- 4, 4, 35, 35, 16, 16, 75, 75, 75, 75,
- 75, 75, 75, 7, 7, 7, 7, 8, 8, 8,
- 8, 8, 8, 8, 76, 74, 74, 74, 74, 74,
- 74, 144, 144, 81, 81, 81, 145, 145, 150, 150,
- 150, 150, 150, 150, 150, 150, 146, 82, 82, 82,
- 147, 147, 151, 151, 151, 151, 151, 151, 151, 152,
- 38, 38, 34, 34, 153, 114, 78, 78, 78, 78,
- 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
- 78, 78, 78, 78, 78, 78, 78, 78, 78, 83,
- 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
- 83, 83, 83, 83, 83, 3, 3, 3, 13, 13,
- 13, 13, 13, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80, 154, 115,
- 115, 155, 155, 155, 155, 155, 155, 155, 155, 155,
- 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
- 155, 155, 155, 155, 155, 158, 159, 156, 161, 161,
- 160, 160, 160, 163, 162, 162, 162, 162, 166, 166,
- 166, 169, 164, 167, 168, 165, 165, 165, 117, 170,
- 170, 172, 172, 172, 171, 171, 173, 173, 14, 14,
- 174, 174, 174, 174, 174, 174, 174, 174, 174, 174,
- 174, 174, 174, 174, 174, 41, 41, 41, 41, 41,
- 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
- 41, 41, 41, 41, 175, 31, 31, 32, 32, 39,
- 39, 39, 40, 40, 40, 40, 40, 40, 40, 40,
- 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- 40, 40, 40, 40, 40, 40, 40, 40, 42, 42,
- 42, 43, 43, 43, 47, 47, 46, 46, 45, 45,
- 44, 44, 48, 48, 49, 49, 49, 50, 50, 50,
- 50, 51, 51, 149, 95, 96, 97, 98, 99, 100,
- 101, 102, 103, 104, 105, 106, 107, 108, 157, 157,
- 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
- 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
- 157, 6, 6, 6, 6, 6, 53, 53, 54, 54,
- 55, 55, 25, 25, 26, 26, 27, 27, 27, 70,
- 70, 70, 70, 70, 70, 70, 70, 70, 70, 5,
- 5, 71, 71, 71, 71, 33, 33, 33, 33, 33,
- 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
- 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
- 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
- 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
- 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
- 20, 20, 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 28, 28, 28, 28, 28, 28, 28, 28, 28,
- 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
- 28, 28, 28, 28, 28, 52, 52, 52, 52, 52,
- 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
- 52, 52, 52, 30, 30, 29, 29, 29, 29, 29,
- 131, 131, 131, 131, 131, 131, 64, 64, 64, 63,
- 63, 87, 87, 84, 84, 85, 17, 17, 37, 37,
- 37, 37, 37, 37, 37, 37, 86, 86, 86, 86,
- 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
- 86, 176, 176, 120, 120, 120, 120, 120, 120, 120,
- 120, 120, 120, 120, 121, 121, 88, 88, 89, 89,
- 177, 122, 90, 90, 90, 90, 90, 90, 90, 90,
- 90, 90, 123, 123, 178, 178, 178, 66, 66, 179,
- 179, 179, 179, 179, 179, 180, 182, 181, 124, 124,
- 125, 125, 183, 183, 183, 183, 126, 148, 91, 91,
- 91, 91, 91, 91, 91, 91, 91, 91, 127, 127,
- 184, 184, 184, 184, 184, 184, 184, 128, 128, 92,
- 92, 92, 129, 129, 185, 185, 185, 185 };
-YYSTATIC YYCONST yyr_t YYFARDATA YYR2[]={
-
- 0, 0, 2, 4, 4, 3, 1, 1, 1, 1,
- 1, 1, 4, 4, 4, 4, 1, 1, 1, 2,
- 2, 3, 2, 2, 1, 1, 1, 4, 1, 0,
- 2, 1, 3, 2, 4, 6, 1, 1, 1, 1,
- 3, 1, 1, 1, 1, 4, 4, 4, 4, 4,
- 4, 4, 2, 3, 2, 2, 2, 1, 1, 2,
- 1, 2, 4, 6, 3, 5, 7, 9, 3, 4,
- 7, 1, 1, 1, 2, 0, 2, 2, 0, 6,
- 2, 1, 1, 1, 1, 1, 1, 1, 1, 3,
- 2, 3, 1, 2, 3, 7, 0, 2, 2, 2,
- 2, 2, 3, 3, 2, 1, 4, 3, 0, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
- 3, 2, 2, 2, 5, 0, 2, 0, 2, 0,
- 2, 3, 1, 0, 1, 1, 3, 0, 3, 1,
- 1, 1, 1, 1, 0, 2, 4, 3, 0, 2,
- 3, 0, 1, 5, 3, 4, 4, 4, 1, 1,
- 1, 1, 1, 2, 2, 4, 13, 22, 1, 1,
- 5, 3, 4, 7, 0, 2, 2, 2, 2, 2,
- 2, 2, 5, 2, 2, 2, 2, 2, 2, 5,
- 0, 2, 0, 2, 0, 3, 9, 9, 7, 7,
- 1, 1, 1, 2, 2, 1, 4, 0, 1, 1,
- 2, 2, 2, 2, 4, 2, 5, 3, 2, 2,
- 1, 4, 3, 0, 2, 2, 0, 2, 2, 2,
- 2, 2, 1, 1, 1, 1, 9, 0, 2, 2,
- 0, 2, 2, 2, 2, 1, 1, 1, 1, 1,
- 0, 4, 1, 3, 1, 13, 0, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 5, 8, 6, 5, 0,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 4, 4, 4, 4, 5, 1, 1, 1, 0, 4,
- 4, 4, 4, 0, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 5, 1, 0,
- 2, 2, 1, 2, 4, 5, 1, 1, 1, 1,
- 2, 1, 1, 1, 1, 1, 4, 6, 4, 4,
- 11, 1, 5, 3, 5, 3, 1, 2, 2, 1,
- 2, 4, 4, 1, 2, 2, 2, 2, 2, 2,
- 2, 1, 2, 1, 1, 1, 4, 4, 2, 4,
- 2, 0, 1, 1, 3, 1, 3, 1, 0, 3,
- 5, 4, 3, 5, 5, 5, 5, 5, 5, 2,
- 2, 2, 2, 2, 2, 4, 4, 4, 4, 4,
- 4, 4, 4, 5, 5, 5, 5, 4, 4, 4,
- 4, 4, 4, 3, 2, 0, 1, 1, 2, 1,
- 1, 1, 1, 4, 4, 5, 4, 4, 4, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 8,
- 8, 8, 8, 7, 7, 7, 7, 7, 0, 2,
- 2, 0, 2, 2, 0, 2, 0, 2, 0, 2,
- 0, 2, 0, 2, 0, 2, 2, 0, 2, 3,
- 2, 0, 2, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 2, 1, 2,
- 2, 2, 2, 2, 2, 3, 2, 2, 2, 5,
- 3, 2, 2, 2, 2, 2, 5, 4, 6, 2,
- 4, 0, 3, 3, 1, 1, 0, 3, 0, 1,
- 1, 3, 0, 1, 1, 3, 1, 3, 4, 4,
- 4, 4, 5, 1, 1, 1, 1, 1, 1, 1,
- 3, 1, 3, 4, 1, 0, 10, 6, 5, 6,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 2, 2, 2, 2, 1, 1, 1, 1,
- 2, 3, 4, 6, 5, 1, 1, 1, 1, 1,
- 1, 1, 2, 2, 1, 2, 2, 4, 1, 2,
- 1, 2, 1, 2, 1, 2, 1, 2, 1, 1,
- 0, 5, 0, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 2, 2, 2, 2, 1, 1,
- 1, 1, 1, 3, 2, 2, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 2, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 2, 1, 3, 2, 3, 4, 2, 2, 2,
- 5, 5, 7, 4, 3, 2, 3, 2, 1, 1,
- 2, 3, 2, 1, 2, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 2, 2, 2, 2, 1, 1,
- 1, 1, 1, 1, 3, 0, 1, 1, 3, 2,
- 6, 7, 3, 3, 3, 6, 0, 1, 3, 5,
- 6, 4, 4, 1, 3, 3, 1, 1, 1, 1,
- 4, 1, 6, 6, 6, 4, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 3, 2, 5, 4, 7, 6, 7,
- 6, 9, 8, 3, 8, 4, 0, 2, 0, 1,
- 3, 3, 0, 2, 2, 2, 3, 2, 2, 2,
- 2, 2, 0, 2, 3, 1, 1, 1, 1, 3,
- 8, 2, 3, 1, 1, 3, 3, 3, 4, 6,
- 0, 2, 3, 1, 3, 1, 4, 3, 0, 2,
- 2, 2, 3, 3, 3, 3, 3, 3, 0, 2,
- 2, 3, 3, 4, 2, 1, 1, 3, 5, 0,
- 2, 2, 0, 2, 4, 3, 1, 1 };
-YYSTATIC YYCONST short YYFARDATA YYCHK[]={
-
--1000,-109,-110,-111,-113,-114,-116,-117,-118,-119,
--120,-121,-122,-124,-126,-128,-130,-131,-132, 524,
- 525, 459, 527, 528,-133,-134,-135, 531, 532,-139,
- 408,-152, 410,-170,-137, 454,-176, 462, 407, 469,
- 470, 429, -87, 430, -93, -94, 273, 448, 529, 533,
- 534, 535, 536, 537, 538, 539, 59,-138, 409, 411,
- 453, 446, 447, 449, -10, -11, 123, 123,-115, 123,
- 123, 123, 123, -9, 264, -9, 526, -88, -24, 265,
- 264, -24, 123,-140, 314, -1, -2, 261, 260, 263,
- -78, -16, 91,-171, 123,-174, 278, 38,-175, 286,
- 287, 284, 283, 282, 281, 288, -31, -32, 267, 91,
- -9, -90, 468, 468, -92, -1, 468, -86, 431, 432,
- 433, 434, 435, 436, 437, 438, 439, 440, 441, 442,
- 443, 444, 445, -31, -86, 263, -28, -70, -74, -93,
- -94, 306, 297, 322, 323,-149, 33, 307, 276, 324,
- -52, 275, 91, -5, -76, 268, 412, 413, 414, 357,
- 356, 278, 298, 277, 281, 282, 283, 284, 286, 287,
- 279, 290, 291, 292, 293, 271, -1, 296, -1, -1,
- -1, -1, 262, -77,-172, 318, 378, 61, -73, 40,
- -75, -7, -76, 269, 272, 325, 340, -8, 295, 300,
- 302, 308, -31, -31,-112,-109, 125,-155, 415,-156,
- 417,-154, 419, 420,-117,-157, -2,-131,-120,-133,
--132,-135, 471, 457, 507,-158, 506,-160, 418, -95,
- -96, -97, -98, -99,-108,-100,-101,-102,-103,-104,
--105,-106,-107,-159,-163, 394, 395, 396, 397, 398,
- 399, 400, 401, 402, 403, 404, 405, 406, 123, 416,
--123,-125,-127,-129, -9, -1, 460,-136, -70, -76,
--141, 315, -71, -70, 91, -28,-149, 46, -7, 328,
- 329, 330, 331, 332, 326, 346, 352, 337, 364, 365,
- 366, 367, 368, 369, 370, 350, 377, 294, 371, -79,
- -9,-173,-174, 42, 40, -31, 40, -14, 91, 40,
- -14, 40, -14, 40, -14, 40, -14, 40, -14, 40,
- 41, 267, -9, 263, 58, 44, 262, -1, 353, 354,
- 355, 472, 378, 474, 475, 476, 477, -90, -91, -1,
- 329, 330, -1, -71, 41, -36, 61, 288, 262, 44,
- 389, 91, 38, 42, 358, 359, 360, 60, 389, 389,
- 389, 389, -70, 306, -70, -75, -7, 33, -9, -1,
- 280, 279, 289, -28, -1, -76, 42, 470, 47, -28,
- 270, 272, 281, 282, 283, 284, 40, -36, -1, 329,
- 330, 322, 345, 334, 335, 337, 338, 339, 340, 341,
- 342, 343, 344, 361, 354, 336, 351, 326, 370, 294,
- -2, 40, 61, -72, -71, -74, -28, -7, -7, 40,
- 301, 303, 304, 305, 41, 41, 125,-143,-114,-111,
--144,-146,-116,-117,-131,-120,-132, 451, 452,-148,
- 507,-133,-135, 506, 321, 421, 426, 471, 407, 125,
- -9, -9, 40, 450, 58, 91, -9, -71, 356, 363,
- 91,-161,-162,-164,-166,-167,-168, 311,-169, 309,
- 313, 312, -9, -2, -9, -24, 40, -23, -24, 266,
- 286, 287, -31, -9, -2, -75, -28, -76, 270, 272,
- -71, -36, 341,-175, -7, -72, 40,-115,-158, -2,
- -9, 125,-178, 461,-131,-179,-180, 466, 467,-181,
--132,-135, 463, 125,-183,-177,-179,-182, 338, 461,
- 464, 125,-184, 459, 407, 462, 296,-132,-135, 125,
--185, 459, 462,-132,-135, -89, 419, 125,-136,-142,
- -71, -1, 470, -7, -1, -13, 40, 40, -28, 328,
- 329, 330, 331, 376, 370, 326, 478, 364, 365, 366,
- 367, 374, 375, 294, 93, 125, 44, 40, -2, 41,
- -23, -9, -23, -24, -9, -9, -9, 93, -9, -9,
- 473, -1, -1, 330, 329, 327, 336, 389, 40, 61,
- 43, 123, 40, 40, 263, -1, 93, -30, -29, 275,
- -9, 40, 40, -54, -55, -28, -1, -1, -1, -1,
- -70, -28, -9, -1, 280, 93, 93, 93, -1, -1,
- -71, -1, 91, -9, -69, 60, 329, 330, 331, 364,
- 365, 366, 40, 61, -36, 123, 40, 41, -71, -3,
- 372, 373, -1, -9,-115, 123, 123, 123, -9, -9,
- 123, -71, 356, 363, 363, -81, -82, -91, -25, -26,
- -27, 275, -13, 40, -9, 58, 274, -7, 91, -1,
- -9,-161,-165,-158, 310,-165,-165,-165, -71,-158,
- -2, -9, 40, 40, 41, -71, -1, 40, -31, -28,
- -6, -2, -9, 125, 316, 316, 465, -31, -66, -9,
- 42, -36, 61, -31, 61, -31, -31, 61, 61, -1,
- 468, -9, 468, 40, -1, 468,-177, 44, 93, -1,
- -28, -28, 91, -9, -36, -83, -1, 40, 40,-173,
- -36, 41, 41, 93, 41, 41, 41, 41, 41, -12,
- 263, 44, 58, 389, 329, 330, 331, 364, 365, 366,
- -1, -84, -85, -36, 123, 262, -64, -63, -71, 306,
- 44, 93, 44, 275, -71, -71, 62, 44, 42, -5,
- -5, -5, 93, 274, 41, -68, -19, -18, 43, 45,
- 306, 323, 372, -9, -59, -61, -73, 274, -53, -22,
- 60, 41, 125,-112,-145,-147,-127, 274, -7, 91,
- -1, -71, -71, -1, 370, 326, -7, 370, 326, -1,
- 41, 44, -28, -25, 93, -9, -3, -1, -28, -9,
- 93, -2, -9, -9, -24, 274, -36, 41, 40, 41,
- 44, 44, -2, -9, -9, 41, 58, 40, 41, 40,
- 41, 41, 40, 40, -5, -1, -9, 317, -1, -31,
- -71, 93, -38, 478, 503, 504, 505, -9, 41, 389,
- -83, 41, 386, 341, 342, 343, 387, 388, 301, 303,
- 304, 305, 390, 393, 294, -4, 317, -34, -33,-153,
- 479, 481, 482, 483, 484, 276, 277, 281, 282, 283,
- 284, 286, 287, 257, 279, 290, 291, 292, 293, 485,
- 486, 487, 489, 490, 491, 492, 493, 494, 495, 334,
- 496, 280, 289, 336, 497, 341, 488, 356, 389, 501,
- 271, 123, -9, 41, -14, -14, -14, -14, -14, -14,
- 317, 283, 284, 455, 456, 458, -9, -9, -1, 41,
- 44, 61, -59, 125, 44, 61, 263, 263, -29, -9,
- 41, 41, -28, 40, -5, -1, 62, -58, -1, 40,
- -19, 41, 125, -62, -40,-135, -41, 298, 363, 297,
- 286, 287, 284, 283, 282, 281, 293, 292, 291, 290,
- 279, 278, 277,-175, 61, -3, 40, 40, 91, -54,
- 125, 125,-150, 422, 423, 424, 425,-120,-132,-133,
--135, 125,-151, 427, 428, 425,-132,-120,-133,-135,
- 125, -3, -28, -9, -93, 449, -1, -28, -27, -38,
- 41, 389, -71, 93, -35, 61, 316, 316, 41, 41,
- -1, 41, -25, -6, -6, -66, 41, -9, 41, -3,
- 40, 93, 93, 93, 93, -36, 41, 58, 58, 40,
- -35, -2, 41, 42, 91, -32, 40, 480, 500, 277,
- 281, 282, 283, 284, 280, -20, 40, -20, -20, -15,
- 509, 482, 483, 276, 277, 281, 282, 283, 284, 286,
- 287, 279, 290, 291, 292, 293, 42, 485, 486, 487,
- 489, 490, 493, 494, 496, 280, 289, 257, 510, 511,
- 512, 513, 514, 515, 516, 517, 518, 519, 520, 521,
- 522, 495, 487, 499, 41, -2, 263, 263, 44, -84,
- -37, -17, -9, 283, -36, -70, 319, 320, 125, -64,
- 123, 61, -25, -1, -67, 44, -56, -57, -71, -65,
--135, 357, 362, 40, 91, 40, 91, 40, 91, 40,
- 91, 40, 91, 40, 91, 40, 91, 40, 91, 40,
- 91, 40, 91, 40, 91, 40, 91, 40, 91, 284,
- 283, 282, 281, 40, 91, 40, 91, -31, -36, 123,
- 40, -53, -22, -25, -25, -9, 62, -75, -75, -75,
- -75, -75, -75, -75, 508, -71, 93, -1, -2, -2,
- 274, -39, -41, -36, 299, 286, 287, 284, 283, 282,
- 281, 279, 293, 292, 291, 290, 278, 277, -2, -9,
- 41, 58, -89, -69, -34, -83, 391, 392, 391, 392,
- -9, 93, -9, 43, 125, -36, 91, 91, 502, 44,
- 91, 523, 38, 281, 282, 283, 284, 280, -9, 40,
- 40, -62, 123, 41, -67, -68, 41, 44, -60, -52,
- 363, 297, 345, 299, 263, -9, 306, -70, 299, -9,
- -40, -9, -23, -9, -9, -23, -24, -9, -24, -9,
- -9, -9, -9, -9, -9, -9, -24, -9, -9, -9,
- -9, -9, -9, -9, 40, 91, 40, 91, 40, 91,
- 40, 91, -9, -9, -17, -9, 41, -59, 40, 40,
- 41, 41, 93, -7, 274, 40, -3, 284, 283, 282,
- 281, -66, 40, 41, 41, 41, 93, 43, -9, 44,
- -9, -9, 61, -36, 93, 263, -9, 281, 282, 283,
- -9, 125, -62, -71, -1, 91, 306, -70, 41, 41,
- 93, 263, 41, 41, 93, 41, 93, 41, 41, 93,
- 41, 41, 93, 41, 93, 41, 93, 41, 93, 41,
- 93, 41, 93, 41, 93, 41, 93, 41, 93, -24,
- -9, -9, -9, -9, -9, -9, -9, 41, 93, 41,
- 93, 125, -25, -25, 62, -28, -3, -25, -21, -22,
- 60, 58, -25, -9, 93, -36, 93, 93, -9, 41,
- 58, 58, 58, 41, 125, 61, 93, 263, 40, 41,
- 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- 40, 40, 41, 93, 41, 93, 41, 93, 41, 93,
- 40, 40, 41, 41, -71, -21, 41, 40, -66, 41,
- 93, 44, 41, -33, 41, -9, -9, -9, -40, -49,
- -50, -51, -42, -43, -47, -46, -45, -44, -47, -46,
- -45, -44, 40, 40, 40, 40, -45, -48, 274, 40,
- -35, -25, -80, -36, 41, 41, 41, 41, 299, 263,
- 41, 299, 306, -70, 41, -40, 41, -23, -9, 41,
- -23, -24, 41, -24, 41, -9, 41, -9, 41, -9,
- 41, 41, 41, 41, -47, -46, -45, -44, 41, 41,
- -17, -3, -25, 41, 123, 324, 378, 379, 380, 308,
- 381, 382, 383, 384, 333, 347, 348, 349, 294, 44,
- 263, 41, 41, 41, 41, 40, 41, 40, -36, -25,
- 508, -9, 41, 41, 356, 41, -7, -28, -71, 274,
- -3, -21, 40, -25, 41 };
-YYSTATIC YYCONST short YYFARDATA YYDEF[]={
-
- 1, -2, 2, 0, 0, 329, 6, 7, 8, 9,
- 10, 11, 0, 0, 0, 0, 16, 17, 18, 0,
- 0, 766, 0, 0, 24, 25, 26, 0, 28, 135,
- 0, 266, 204, 0, 425, 0, 0, 772, 105, 829,
- 92, 0, 425, 0, 83, 84, 85, 0, 0, 0,
- 0, 0, 0, 57, 58, 0, 60, 108, 259, 381,
- 0, 751, 752, 217, 425, 425, 139, 1, 0, 782,
- 800, 818, 832, 19, 41, 20, 0, 0, 22, 42,
- 43, 23, 29, 137, 0, 104, 38, 39, 36, 37,
- 217, 184, 0, 378, 0, 385, 0, 0, 425, 388,
- 388, 388, 388, 388, 388, 0, 0, 426, 427, 0,
- 754, 0, 772, 808, 0, 93, 0, 0, 736, 737,
- 738, 739, 740, 741, 742, 743, 744, 745, 746, 747,
- 748, 749, 750, 0, 0, 33, 0, 0, 0, 0,
- 0, 0, 662, 0, 0, 217, 0, 678, 679, 0,
- 683, 0, 0, 543, 230, 545, 546, 547, 548, 0,
- 483, 685, 686, 687, 688, 689, 690, 691, 692, 693,
- 0, 698, 699, 700, 701, 702, 549, 0, 52, 54,
- 55, 56, 59, 0, 380, 382, 383, 0, 61, 0,
- 71, 0, 210, 211, 212, 217, 217, 215, 0, 218,
- 219, 0, 0, 0, 0, 0, 5, 330, 0, 332,
- 0, 0, 336, 337, 338, 339, 0, 341, 342, 343,
- 344, 345, 0, 0, 0, 351, 0, 0, 328, 498,
- 0, 0, 0, 0, 425, 0, 217, 0, 0, 0,
- 217, 0, 0, 329, 0, 484, 485, 486, 487, 488,
- 489, 490, 491, 492, 493, 494, 495, 496, 356, 363,
- 0, 0, 0, 0, 21, 768, 767, 0, 29, 544,
- 107, 0, 136, 551, 0, 554, 217, 0, 308, 267,
- 268, 269, 270, 271, 272, 273, 274, 275, 276, 277,
- 278, 279, 280, 281, 282, 283, 284, 0, 0, 0,
- 0, 0, 387, 0, 0, 0, 0, 399, 0, 0,
- 400, 0, 401, 0, 402, 0, 403, 0, 404, 424,
- 102, 428, 0, 753, 0, 0, 763, 771, 773, 774,
- 775, 0, 777, 778, 779, 780, 781, 0, 0, 827,
- 830, 831, 94, 712, 713, 714, 0, 0, 31, 0,
- 0, 705, 667, 668, 669, 0, 0, 528, 0, 0,
- 0, 0, 661, 0, 664, 225, 0, 0, 675, 677,
- 680, 0, 682, 684, 0, 0, 0, 0, 0, 0,
- 228, 229, 694, 695, 696, 697, 0, 53, 147, 109,
- 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
- 120, 121, 122, 123, 124, 0, 131, 132, 133, 0,
- 0, 103, 0, 0, 72, 73, 0, 213, 214, 0,
- 220, 221, 222, 223, 64, 68, 3, 140, 329, 0,
- 0, 0, 168, 169, 170, 171, 172, 0, 0, 0,
- 0, 178, 179, 0, 0, 233, 247, 808, 105, 4,
- 331, 333, -2, 0, 340, 0, 0, 0, 217, 0,
- 0, 357, 359, 0, 0, 0, 0, 0, 0, 373,
- 374, 371, 499, 500, 501, 502, 497, 503, 504, 44,
- 0, 0, 0, 506, 507, 508, 0, 511, 512, 513,
- 514, 515, 0, 425, 0, 519, 521, 0, 360, 0,
- 0, 12, 783, 0, 785, 786, 425, 0, 0, 425,
- 793, 794, 0, 13, 801, 425, 803, 425, 805, 0,
- 0, 14, 819, 0, 0, 0, 0, 825, 826, 15,
- 833, 0, 0, 836, 837, 765, 769, 27, 30, 138,
- 142, 0, 0, 0, 40, 0, 0, 289, 0, 185,
- 186, 187, 188, 189, 190, 191, 0, 193, 194, 195,
- 196, 197, 198, 0, 205, 384, 0, 0, 0, 392,
- 0, 0, 0, 0, 0, 0, 0, 96, 756, 0,
- 776, 798, 806, 809, 810, 811, 0, 0, 0, 0,
- 0, 716, 721, 722, 34, 47, 665, 0, 703, 706,
- 707, 0, 0, 0, 529, 530, 48, 49, 50, 51,
- 663, 0, 674, 676, 681, 0, 0, 0, 0, 550,
- 0, -2, 705, 0, 106, 154, 125, 126, 127, 128,
- 129, 130, 0, 379, 62, 75, 69, 217, 0, 526,
- 305, 306, -2, 0, 0, 139, 236, 250, 173, 174,
- 818, 0, 217, 0, 0, 0, 217, 0, 0, 533,
- 534, 536, 0, -2, 0, 0, 0, 0, 0, 353,
- 0, 358, 364, 375, 0, 365, 366, 367, 372, 368,
- 369, 370, 0, 0, 505, 0, -2, 0, 0, 0,
- 0, 524, 525, 355, 0, 0, 0, 0, 0, 787,
- 788, 791, 0, 0, 0, 0, 0, 0, 0, 820,
- 0, 824, 0, 0, 0, 0, 425, 0, 552, 0,
- 0, 260, 0, 0, 289, 0, 200, 555, 0, 386,
- 0, 391, 388, 389, 388, 388, 388, 388, 388, 0,
- 755, 0, 0, 0, 812, 813, 814, 815, 816, 817,
- 828, 0, 723, 0, 75, 32, 0, 717, 0, 0,
- 0, 666, 705, 709, 0, 0, 673, 0, 668, 539,
- 540, 541, 0, 0, 224, 0, 0, 154, 149, 150,
- 151, 152, 153, 0, 0, 78, 65, 0, 0, 0,
- 528, 216, 164, 0, 0, 0, 0, 0, 0, 0,
- 181, 0, 0, -2, 234, 235, 0, 248, 249, 807,
- 334, 308, 260, 0, 346, 348, 349, 307, 0, 0,
- 202, 0, 0, 0, 0, 0, 0, 517, -2, 520,
- 521, 521, 361, 362, 784, 789, 0, 797, 792, 795,
- 802, 804, 770, 796, 821, 822, 0, 0, 835, 0,
- 141, 553, 0, 0, 0, 0, 0, 0, 285, 0,
- 0, 288, 290, 291, 292, 293, 294, 295, 296, 297,
- 298, 299, 0, 0, 0, 202, 0, 0, 262, 0,
- 0, 0, 560, 561, 562, 563, 564, 565, 566, 567,
- 568, 569, 570, 571, 0, 576, 577, 578, 579, 585,
- 586, 587, 588, 589, 590, 591, 610, 610, 594, 610,
- 612, 598, 600, 0, 602, 0, 604, 606, 0, 608,
- 609, 264, 0, 390, 393, 394, 395, 396, 397, 398,
- 0, 97, 98, 99, 100, 101, 758, 760, 799, 710,
- 0, 0, 0, 715, 716, 0, 37, 35, 704, 708,
- 670, 671, 531, -2, 542, 226, 148, 0, 158, 143,
- 155, 134, 63, 74, 76, 77, 432, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 425, 0, 526, -2, -2, 0, 0,
- 165, 166, 237, 217, 217, 217, 217, 242, 243, 244,
- 245, 167, 251, 217, 217, 217, 255, 256, 257, 258,
- 175, 0, 0, 0, 182, 217, 231, 0, 535, 537,
- 335, 0, 0, 352, 354, 0, 0, 0, 45, 46,
- 509, 516, 0, 522, 523, 0, 823, 834, 768, 147,
- 555, 309, 310, 311, 312, 289, 287, 0, 0, 0,
- 183, 201, 192, 580, 0, 0, 0, 0, 0, 605,
- 572, 573, 574, 575, 599, 592, 0, 593, 595, 596,
- 613, 614, 615, 616, 617, 618, 619, 620, 621, 622,
- 623, 0, 628, 629, 630, 631, 632, 636, 637, 638,
- 639, 640, 641, 642, 643, 644, 646, 647, 648, 649,
- 650, 651, 652, 653, 654, 655, 656, 657, 658, 659,
- 660, 601, 603, 607, 199, 95, 757, 759, 0, 724,
- 725, 728, 729, 0, 731, 0, 726, 727, 711, 718,
- 78, 0, 0, 158, 157, 154, 0, 144, 145, 0,
- 80, 81, 82, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 66, 75,
- 70, 0, 0, 0, 0, 0, 527, 238, 239, 240,
- 241, 252, 253, 254, 217, 0, 180, 0, 538, 347,
- 0, 203, 429, 430, 431, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 376, 377,
- 518, 0, 764, 0, 0, 0, 300, 301, 302, 303,
- 0, 581, 0, 0, 263, 0, 0, 0, 0, 0,
- 0, 634, 635, 624, 625, 626, 627, 645, 762, 0,
- 0, 0, 78, 672, 156, 159, 160, 0, 0, 86,
- 87, 88, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 423, 0, -2, -2,
- 208, 209, 0, 0, 0, -2, 161, 0, 0, 0,
- 0, 0, -2, 261, 286, 304, 582, 0, 0, 0,
- 0, 0, 0, 597, 633, 761, 0, 0, 0, 0,
- 0, 719, 0, 146, 0, 0, 0, 90, 433, 434,
- 0, 0, 436, 437, 0, 438, 0, 405, 407, 0,
- 406, 408, 0, 409, 0, 410, 0, 411, 0, 412,
- 0, 417, 0, 418, 0, 419, 0, 420, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 421, 0, 422,
- 0, 67, 0, 0, 163, 0, 161, 0, 0, 162,
- 0, 0, 0, 0, 584, 0, 558, 555, 0, 730,
- 0, 0, 0, 735, 720, 0, 91, 89, 474, 435,
- 477, 481, 458, 461, 464, 466, 468, 470, 464, 466,
- 468, 470, 413, 0, 414, 0, 415, 0, 416, 0,
- 468, 472, 206, 207, 0, 0, 202, -2, 790, 313,
- 583, 0, 557, 559, 611, 0, 0, 0, 79, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 464, 466, 468, 470, 0, 0, 0, -2,
- 246, 0, 0, 0, 732, 733, 734, 455, 475, 476,
- 456, 478, 0, 480, 457, 482, 439, 459, 460, 440,
- 462, 463, 441, 465, 442, 467, 443, 469, 444, 471,
- 445, 446, 447, 448, 0, 0, 0, 0, 453, 454,
- 473, 0, 0, 350, 265, 314, 315, 316, 317, 318,
- 319, 320, 321, 322, 323, 324, 325, 326, 0, 0,
- 479, 449, 450, 451, 452, -2, 0, 0, 0, 0,
- 0, 0, 556, 176, 217, 327, 0, 0, 0, 0,
- 161, 0, -2, 0, 177 };
-#ifdef YYRECOVER
-YYSTATIC YYCONST short yyrecover[] = {
--1000
-};
-#endif
-
-/* SCCSWHAT( "@(#)yypars.c 3.1 88/11/16 22:00:49 " ) */
-#line 3 "D:\\ProjectK3\\src\\tools\\devdiv\\x86\\yypars.c"
-#if ! defined(YYAPI_PACKAGE)
-/*
-** YYAPI_TOKENNAME : name used for return value of yylex
-** YYAPI_TOKENTYPE : type of the token
-** YYAPI_TOKENEME(t) : the value of the token that the parser should see
-** YYAPI_TOKENNONE : the representation when there is no token
-** YYAPI_VALUENAME : the name of the value of the token
-** YYAPI_VALUETYPE : the type of the value of the token (if null, then the value is derivable from the token itself)
-** YYAPI_VALUEOF(v) : how to get the value of the token.
-*/
-#define YYAPI_TOKENNAME yychar
-#define YYAPI_TOKENTYPE int
-#define YYAPI_TOKENEME(t) (t)
-#define YYAPI_TOKENNONE -1
-#define YYAPI_TOKENSTR(t) (sprintf(yytokbuf, "%d", t), yytokbuf)
-#define YYAPI_VALUENAME yylval
-#define YYAPI_VALUETYPE YYSTYPE
-#define YYAPI_VALUEOF(v) (v)
-#endif
-#if ! defined(YYAPI_CALLAFTERYYLEX)
-#define YYAPI_CALLAFTERYYLEX
-#endif
-
-# define YYFLAG -1000
-# define YYERROR goto yyerrlab
-# define YYACCEPT return(0)
-# define YYABORT return(1)
-
-#ifdef YYDEBUG /* RRR - 10/9/85 */
-char yytokbuf[20];
-# ifndef YYDBFLG
-# define YYDBFLG (yydebug)
-# endif
-# define yyprintf(a, b, c, d) if (YYDBFLG) YYPRINT(a, b, c, d)
-#else
-# define yyprintf(a, b, c, d)
-#endif
-
-#ifndef YYPRINT
-#define YYPRINT printf
-#endif
-
-/* parser for yacc output */
-
-#ifdef YYDUMP
-int yydump = 1; /* 1 for dumping */
-void yydumpinfo(void);
-#endif
-#ifdef YYDEBUG
-YYSTATIC int yydebug = 0; /* 1 for debugging */
-#endif
-YYSTATIC YYSTYPE yyv[YYMAXDEPTH]; /* where the values are stored */
-YYSTATIC short yys[YYMAXDEPTH]; /* the parse stack */
-
-#if ! defined(YYRECURSIVE)
-YYSTATIC YYAPI_TOKENTYPE YYAPI_TOKENNAME = YYAPI_TOKENNONE;
-#if defined(YYAPI_VALUETYPE)
-// YYSTATIC YYAPI_VALUETYPE YYAPI_VALUENAME; FIX
-#endif
-YYSTATIC int yynerrs = 0; /* number of errors */
-YYSTATIC short yyerrflag = 0; /* error recovery flag */
-#endif
-
-#ifdef YYRECOVER
-/*
-** yyscpy : copy f onto t and return a ptr to the null terminator at the
-** end of t.
-*/
-YYSTATIC char *yyscpy(register char*t, register char*f)
- {
- while(*t = *f++)
- t++;
- return(t); /* ptr to the null char */
- }
-#endif
-
-#ifndef YYNEAR
-#define YYNEAR
-#endif
-#ifndef YYPASCAL
-#define YYPASCAL
-#endif
-#ifndef YYLOCAL
-#define YYLOCAL
-#endif
-#if ! defined YYPARSER
-#define YYPARSER yyparse
-#endif
-#if ! defined YYLEX
-#define YYLEX yylex
-#endif
-
-#if defined(YYRECURSIVE)
-
- YYSTATIC YYAPI_TOKENTYPE YYAPI_TOKENNAME = YYAPI_TOKENNONE;
- #if defined(YYAPI_VALUETYPE)
- YYSTATIC YYAPI_VALUETYPE YYAPI_VALUENAME;
- #endif
- YYSTATIC int yynerrs = 0; /* number of errors */
- YYSTATIC short yyerrflag = 0; /* error recovery flag */
-
- YYSTATIC short yyn;
- YYSTATIC short yystate = 0;
- YYSTATIC short *yyps= &yys[-1];
- YYSTATIC YYSTYPE *yypv= &yyv[-1];
- YYSTATIC short yyj;
- YYSTATIC short yym;
-
-#endif
-
-#pragma warning(disable:102)
-YYLOCAL YYNEAR YYPASCAL YYPARSER()
-{
-#if ! defined(YYRECURSIVE)
-
- register short yyn;
- short yystate, *yyps;
- YYSTYPE *yypv;
- short yyj, yym;
-
- YYAPI_TOKENNAME = YYAPI_TOKENNONE;
- yystate = 0;
- yyps= &yys[-1];
- yypv= &yyv[-1];
-#endif
-
-#ifdef YYDUMP
- yydumpinfo();
-#endif
- yystack: /* put a state and value onto the stack */
-
-#ifdef YYDEBUG
- if(YYAPI_TOKENNAME == YYAPI_TOKENNONE) {
- yyprintf( "state %d, token # '%d'\n", yystate, -1, 0 );
- }
- else {
- yyprintf( "state %d, token # '%s'\n", yystate, YYAPI_TOKENSTR(YYAPI_TOKENNAME), 0 );
- }
-#endif
- if( ++yyps > &yys[YYMAXDEPTH] ) {
- yyerror( "yacc stack overflow" );
- return(1);
- }
- *yyps = yystate;
- ++yypv;
-
- *yypv = yyval;
-
-yynewstate:
-
- yyn = YYPACT[yystate];
-
- if( yyn <= YYFLAG ) { /* simple state, no lookahead */
- goto yydefault;
- }
- if( YYAPI_TOKENNAME == YYAPI_TOKENNONE ) { /* need a lookahead */
- YYAPI_TOKENNAME = YYLEX();
- YYAPI_CALLAFTERYYLEX(YYAPI_TOKENNAME);
- }
- if( ((yyn += YYAPI_TOKENEME(YYAPI_TOKENNAME)) < 0) || (yyn >= YYLAST) ) {
- goto yydefault;
- }
- if( YYCHK[ yyn = YYACT[ yyn ] ] == YYAPI_TOKENEME(YYAPI_TOKENNAME) ) { /* valid shift */
- yyval = YYAPI_VALUEOF(YYAPI_VALUENAME);
- yystate = yyn;
- yyprintf( "SHIFT: saw token '%s', now in state %4d\n", YYAPI_TOKENSTR(YYAPI_TOKENNAME), yystate, 0 );
- YYAPI_TOKENNAME = YYAPI_TOKENNONE;
- if( yyerrflag > 0 ) {
- --yyerrflag;
- }
- goto yystack;
- }
-
- yydefault:
- /* default state action */
-
- if( (yyn = YYDEF[yystate]) == -2 ) {
- register YYCONST short *yyxi;
-
- if( YYAPI_TOKENNAME == YYAPI_TOKENNONE ) {
- YYAPI_TOKENNAME = YYLEX();
- YYAPI_CALLAFTERYYLEX(YYAPI_TOKENNAME);
- yyprintf("LOOKAHEAD: token '%s'\n", YYAPI_TOKENSTR(YYAPI_TOKENNAME), 0, 0);
- }
-/*
-** search exception table, we find a -1 followed by the current state.
-** if we find one, we'll look through terminal,state pairs. if we find
-** a terminal which matches the current one, we have a match.
-** the exception table is when we have a reduce on a terminal.
-*/
-
-#if YYOPTTIME
- yyxi = yyexca + yyexcaind[yystate];
- while(( *yyxi != YYAPI_TOKENEME(YYAPI_TOKENNAME) ) && ( *yyxi >= 0 )){
- yyxi += 2;
- }
-#else
- for(yyxi = yyexca;
- (*yyxi != (-1)) || (yyxi[1] != yystate);
- yyxi += 2
- ) {
- ; /* VOID */
- }
-
- while( *(yyxi += 2) >= 0 ){
- if( *yyxi == YYAPI_TOKENEME(YYAPI_TOKENNAME) ) {
- break;
- }
- }
-#endif
- if( (yyn = yyxi[1]) < 0 ) {
- return(0); /* accept */
- }
- }
-
- if( yyn == 0 ){ /* error */
- /* error ... attempt to resume parsing */
-
- switch( yyerrflag ){
-
- case 0: /* brand new error */
-#ifdef YYRECOVER
- {
- register int i,j;
-
- for(i = 0;
- (yyrecover[i] != -1000) && (yystate > yyrecover[i]);
- i += 3
- ) {
- ;
- }
- if(yystate == yyrecover[i]) {
- yyprintf("recovered, from state %d to state %d on token # %d\n",
- yystate,yyrecover[i+2],yyrecover[i+1]
- );
- j = yyrecover[i + 1];
- if(j < 0) {
- /*
- ** here we have one of the injection set, so we're not quite
- ** sure that the next valid thing will be a shift. so we'll
- ** count it as an error and continue.
- ** actually we're not absolutely sure that the next token
- ** we were supposed to get is the one when j > 0. for example,
- ** for(+) {;} error recovery with yyerrflag always set, stops
- ** after inserting one ; before the +. at the point of the +,
- ** we're pretty sure the guy wants a 'for' loop. without
- ** setting the flag, when we're almost absolutely sure, we'll
- ** give him one, since the only thing we can shift on this
- ** error is after finding an expression followed by a +
- */
- yyerrflag++;
- j = -j;
- }
- if(yyerrflag <= 1) { /* only on first insertion */
- yyrecerr(YYAPI_TOKENNAME, j); /* what was, what should be first */
- }
- yyval = yyeval(j);
- yystate = yyrecover[i + 2];
- goto yystack;
- }
- }
-#endif
- yyerror("syntax error");
-
- yyerrlab:
- ++yynerrs;
-
- case 1:
- case 2: /* incompletely recovered error ... try again */
-
- yyerrflag = 3;
-
- /* find a state where "error" is a legal shift action */
-
- while ( yyps >= yys ) {
- yyn = YYPACT[*yyps] + YYERRCODE;
- if( yyn>= 0 && yyn < YYLAST && YYCHK[YYACT[yyn]] == YYERRCODE ){
- yystate = YYACT[yyn]; /* simulate a shift of "error" */
- yyprintf( "SHIFT 'error': now in state %4d\n", yystate, 0, 0 );
- goto yystack;
- }
- yyn = YYPACT[*yyps];
-
- /* the current yyps has no shift onn "error", pop stack */
-
- yyprintf( "error recovery pops state %4d, uncovers %4d\n", *yyps, yyps[-1], 0 );
- --yyps;
- --yypv;
- }
-
- /* there is no state on the stack with an error shift ... abort */
-
- yyabort:
- return(1);
-
-
- case 3: /* no shift yet; clobber input char */
-
- yyprintf( "error recovery discards token '%s'\n", YYAPI_TOKENSTR(YYAPI_TOKENNAME), 0, 0 );
-
- if( YYAPI_TOKENEME(YYAPI_TOKENNAME) == 0 ) goto yyabort; /* don't discard EOF, quit */
- YYAPI_TOKENNAME = YYAPI_TOKENNONE;
- goto yynewstate; /* try again in the same state */
- }
- }
-
- /* reduction by production yyn */
-yyreduce:
- {
- register YYSTYPE *yypvt;
- yypvt = yypv;
- yyps -= YYR2[yyn];
- yypv -= YYR2[yyn];
- yyval = yypv[1];
- yyprintf("REDUCE: rule %4d, popped %2d tokens, uncovered state %4d, ",yyn, YYR2[yyn], *yyps);
- yym = yyn;
- yyn = YYR1[yyn]; /* consult goto table to find next state */
- yyj = YYPGO[yyn] + *yyps + 1;
- if( (yyj >= YYLAST) || (YYCHK[ yystate = YYACT[yyj] ] != -yyn) ) {
- yystate = YYACT[YYPGO[yyn]];
- }
- yyprintf("goto state %4d\n", yystate, 0, 0);
-#ifdef YYDUMP
- yydumpinfo();
-#endif
- switch(yym){
-
-case 3:
-#line 189 "asmparse.y"
-{ PASM->EndClass(); } break;
-case 4:
-#line 190 "asmparse.y"
-{ PASM->EndNameSpace(); } break;
-case 5:
-#line 191 "asmparse.y"
-{ if(PASM->m_pCurMethod->m_ulLines[1] ==0)
- { PASM->m_pCurMethod->m_ulLines[1] = PASM->m_ulCurLine;
- PASM->m_pCurMethod->m_ulColumns[1]=PASM->m_ulCurColumn;}
- PASM->EndMethod(); } break;
-case 12:
-#line 201 "asmparse.y"
-{ PASMM->EndAssembly(); } break;
-case 13:
-#line 202 "asmparse.y"
-{ PASMM->EndAssembly(); } break;
-case 14:
-#line 203 "asmparse.y"
-{ PASMM->EndComType(); } break;
-case 15:
-#line 204 "asmparse.y"
-{ PASMM->EndManifestRes(); } break;
-case 19:
-#line 208 "asmparse.y"
-{
-#ifdef _PREFAST_
-#pragma warning(push)
-#pragma warning(disable:22011) // Suppress PREFast warning about integer overflow/underflow
-#endif
- PASM->m_dwSubsystem = yypvt[-0].int32;
-#ifdef _PREFAST_
-#pragma warning(pop)
-#endif
- } break;
-case 20:
-#line 218 "asmparse.y"
-{ PASM->m_dwComImageFlags = yypvt[-0].int32; } break;
-case 21:
-#line 219 "asmparse.y"
-{ PASM->m_dwFileAlignment = yypvt[-0].int32;
- if((yypvt[-0].int32 & (yypvt[-0].int32 - 1))||(yypvt[-0].int32 < 0x200)||(yypvt[-0].int32 > 0x10000))
- PASM->report->error("Invalid file alignment, must be power of 2 from 0x200 to 0x10000\n");} break;
-case 22:
-#line 222 "asmparse.y"
-{ PASM->m_stBaseAddress = (ULONGLONG)(*(yypvt[-0].int64)); delete yypvt[-0].int64;
- if(PASM->m_stBaseAddress & 0xFFFF)
- PASM->report->error("Invalid image base, must be 0x10000-aligned\n");} break;
-case 23:
-#line 225 "asmparse.y"
-{ PASM->m_stSizeOfStackReserve = (size_t)(*(yypvt[-0].int64)); delete yypvt[-0].int64; } break;
-case 28:
-#line 230 "asmparse.y"
-{ PASM->m_fIsMscorlib = TRUE; } break;
-case 31:
-#line 237 "asmparse.y"
-{ yyval.binstr = yypvt[-0].binstr; } break;
-case 32:
-#line 238 "asmparse.y"
-{ yyval.binstr = yypvt[-2].binstr; yyval.binstr->append(yypvt[-0].binstr); delete yypvt[-0].binstr; } break;
-case 33:
-#line 241 "asmparse.y"
-{ LPCSTRToGuid(yypvt[-0].string,&(PASM->m_guidLang)); } break;
-case 34:
-#line 242 "asmparse.y"
-{ LPCSTRToGuid(yypvt[-2].string,&(PASM->m_guidLang));
- LPCSTRToGuid(yypvt[-0].string,&(PASM->m_guidLangVendor));} break;
-case 35:
-#line 244 "asmparse.y"
-{ LPCSTRToGuid(yypvt[-4].string,&(PASM->m_guidLang));
- LPCSTRToGuid(yypvt[-2].string,&(PASM->m_guidLangVendor));
- LPCSTRToGuid(yypvt[-2].string,&(PASM->m_guidDoc));} break;
-case 36:
-#line 249 "asmparse.y"
-{ yyval.string = yypvt[-0].string; } break;
-case 37:
-#line 250 "asmparse.y"
-{ yyval.string = yypvt[-0].string; } break;
-case 38:
-#line 253 "asmparse.y"
-{ yyval.string = yypvt[-0].string; } break;
-case 39:
-#line 254 "asmparse.y"
-{ yyval.string = yypvt[-0].string; } break;
-case 40:
-#line 255 "asmparse.y"
-{ yyval.string = newStringWDel(yypvt[-2].string, '.', yypvt[-0].string); } break;
-case 41:
-#line 258 "asmparse.y"
-{ yyval.int32 = yypvt[-0].int32; } break;
-case 42:
-#line 261 "asmparse.y"
-{ yyval.int64 = yypvt[-0].int64; } break;
-case 43:
-#line 262 "asmparse.y"
-{ yyval.int64 = neg ? new __int64(yypvt[-0].int32) : new __int64((unsigned)yypvt[-0].int32); } break;
-case 44:
-#line 265 "asmparse.y"
-{ yyval.float64 = yypvt[-0].float64; } break;
-case 45:
-#line 266 "asmparse.y"
-{ float f; *((__int32*) (&f)) = yypvt[-1].int32; yyval.float64 = new double(f); } break;
-case 46:
-#line 267 "asmparse.y"
-{ yyval.float64 = (double*) yypvt[-1].int64; } break;
-case 47:
-#line 271 "asmparse.y"
-{ PASM->AddTypeDef(yypvt[-2].binstr,yypvt[-0].string); } break;
-case 48:
-#line 272 "asmparse.y"
-{ PASM->AddTypeDef(yypvt[-2].token,yypvt[-0].string); } break;
-case 49:
-#line 273 "asmparse.y"
-{ PASM->AddTypeDef(yypvt[-2].token,yypvt[-0].string); } break;
-case 50:
-#line 274 "asmparse.y"
-{ yypvt[-2].cad->tkOwner = 0; PASM->AddTypeDef(yypvt[-2].cad,yypvt[-0].string); } break;
-case 51:
-#line 275 "asmparse.y"
-{ PASM->AddTypeDef(yypvt[-2].cad,yypvt[-0].string); } break;
-case 52:
-#line 280 "asmparse.y"
-{ DefineVar(yypvt[-0].string, NULL); } break;
-case 53:
-#line 281 "asmparse.y"
-{ DefineVar(yypvt[-1].string, yypvt[-0].binstr); } break;
-case 54:
-#line 282 "asmparse.y"
-{ UndefVar(yypvt[-0].string); } break;
-case 55:
-#line 283 "asmparse.y"
-{ SkipToken = !IsVarDefined(yypvt[-0].string);
- IfEndif++;
- } break;
-case 56:
-#line 286 "asmparse.y"
-{ SkipToken = IsVarDefined(yypvt[-0].string);
- IfEndif++;
- } break;
-case 57:
-#line 289 "asmparse.y"
-{ if(IfEndif == 1) SkipToken = !SkipToken;} break;
-case 58:
-#line 290 "asmparse.y"
-{ if(IfEndif == 0)
- PASM->report->error("Unmatched #endif\n");
- else IfEndif--;
- } break;
-case 59:
-#line 294 "asmparse.y"
-{ _ASSERTE(!"yylex should have dealt with this"); } break;
-case 60:
-#line 295 "asmparse.y"
-{ } break;
-case 61:
-#line 299 "asmparse.y"
-{ yyval.cad = new CustomDescr(PASM->m_tkCurrentCVOwner, yypvt[-0].token, NULL); } break;
-case 62:
-#line 300 "asmparse.y"
-{ yyval.cad = new CustomDescr(PASM->m_tkCurrentCVOwner, yypvt[-2].token, yypvt[-0].binstr); } break;
-case 63:
-#line 301 "asmparse.y"
-{ yyval.cad = new CustomDescr(PASM->m_tkCurrentCVOwner, yypvt[-4].token, yypvt[-1].binstr); } break;
-case 64:
-#line 302 "asmparse.y"
-{ yyval.cad = new CustomDescr(PASM->m_tkCurrentCVOwner, yypvt[-2].int32, yypvt[-1].binstr); } break;
-case 65:
-#line 305 "asmparse.y"
-{ yyval.cad = new CustomDescr(yypvt[-2].token, yypvt[-0].token, NULL); } break;
-case 66:
-#line 306 "asmparse.y"
-{ yyval.cad = new CustomDescr(yypvt[-4].token, yypvt[-2].token, yypvt[-0].binstr); } break;
-case 67:
-#line 308 "asmparse.y"
-{ yyval.cad = new CustomDescr(yypvt[-6].token, yypvt[-4].token, yypvt[-1].binstr); } break;
-case 68:
-#line 309 "asmparse.y"
-{ yyval.cad = new CustomDescr(PASM->m_tkCurrentCVOwner, yypvt[-2].int32, yypvt[-1].binstr); } break;
-case 69:
-#line 312 "asmparse.y"
-{ yyval.int32 = yypvt[-2].token; bParsingByteArray = TRUE; } break;
-case 70:
-#line 316 "asmparse.y"
-{ PASM->m_pCustomDescrList = NULL;
- PASM->m_tkCurrentCVOwner = yypvt[-4].token;
- yyval.int32 = yypvt[-2].token; bParsingByteArray = TRUE; } break;
-case 71:
-#line 321 "asmparse.y"
-{ yyval.token = yypvt[-0].token; } break;
-case 72:
-#line 324 "asmparse.y"
-{ yyval.token = yypvt[-0].token; } break;
-case 73:
-#line 325 "asmparse.y"
-{ yyval.token = yypvt[-0].token; } break;
-case 74:
-#line 329 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr;
- yyval.binstr->appendInt16(nCustomBlobNVPairs);
- yyval.binstr->append(yypvt[-0].binstr);
- nCustomBlobNVPairs = 0; } break;
-case 75:
-#line 335 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt16(VAL16(0x0001)); } break;
-case 76:
-#line 336 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr;
- yyval.binstr->appendFrom(yypvt[-0].binstr, (*(yypvt[-0].binstr->ptr()) == ELEMENT_TYPE_SZARRAY) ? 2 : 1); } break;
-case 77:
-#line 338 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; } break;
-case 78:
-#line 341 "asmparse.y"
-{ yyval.binstr = new BinStr(); } break;
-case 79:
-#line 343 "asmparse.y"
-{ yyval.binstr = yypvt[-5].binstr; yyval.binstr->appendInt8(yypvt[-4].int32);
- yyval.binstr->append(yypvt[-3].binstr);
- AppendStringWithLength(yyval.binstr,yypvt[-2].string);
- yyval.binstr->appendFrom(yypvt[-0].binstr, (*(yypvt[-0].binstr->ptr()) == ELEMENT_TYPE_SZARRAY) ? 2 : 1);
- nCustomBlobNVPairs++; } break;
-case 80:
-#line 348 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; } break;
-case 81:
-#line 351 "asmparse.y"
-{ yyval.int32 = SERIALIZATION_TYPE_FIELD; } break;
-case 82:
-#line 352 "asmparse.y"
-{ yyval.int32 = SERIALIZATION_TYPE_PROPERTY; } break;
-case 83:
-#line 355 "asmparse.y"
-{ if(yypvt[-0].cad->tkOwner && !yypvt[-0].cad->tkInterfacePair)
- PASM->DefineCV(yypvt[-0].cad);
- else if(PASM->m_pCustomDescrList)
- PASM->m_pCustomDescrList->PUSH(yypvt[-0].cad); } break;
-case 84:
-#line 359 "asmparse.y"
-{ PASM->DefineCV(yypvt[-0].cad); } break;
-case 85:
-#line 360 "asmparse.y"
-{ CustomDescr* pNew = new CustomDescr(yypvt[-0].tdd->m_pCA);
- if(pNew->tkOwner == 0) pNew->tkOwner = PASM->m_tkCurrentCVOwner;
- if(pNew->tkOwner)
- PASM->DefineCV(pNew);
- else if(PASM->m_pCustomDescrList)
- PASM->m_pCustomDescrList->PUSH(pNew); } break;
-case 86:
-#line 368 "asmparse.y"
-{ yyval.binstr = yypvt[-0].binstr; } break;
-case 87:
-#line 369 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(SERIALIZATION_TYPE_TYPE); } break;
-case 88:
-#line 370 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(SERIALIZATION_TYPE_TAGGED_OBJECT); } break;
-case 89:
-#line 371 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(SERIALIZATION_TYPE_ENUM);
- AppendStringWithLength(yyval.binstr,yypvt[-0].string); } break;
-case 90:
-#line 373 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(SERIALIZATION_TYPE_ENUM);
- AppendStringWithLength(yyval.binstr,PASM->ReflectionNotation(yypvt[-0].token)); } break;
-case 91:
-#line 375 "asmparse.y"
-{ yyval.binstr = yypvt[-2].binstr; yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
-case 92:
-#line 380 "asmparse.y"
-{ PASMM->SetModuleName(NULL); PASM->m_tkCurrentCVOwner=1; } break;
-case 93:
-#line 381 "asmparse.y"
-{ PASMM->SetModuleName(yypvt[-0].string); PASM->m_tkCurrentCVOwner=1; } break;
-case 94:
-#line 382 "asmparse.y"
-{ BinStr* pbs = new BinStr();
- unsigned L = (unsigned)strlen(yypvt[-0].string);
- memcpy((char*)(pbs->getBuff(L)),yypvt[-0].string,L);
- PASM->EmitImport(pbs); delete pbs;} break;
-case 95:
-#line 389 "asmparse.y"
-{ /*PASM->SetDataSection(); PASM->EmitDataLabel($7);*/
- PASM->m_VTFList.PUSH(new VTFEntry((USHORT)yypvt[-4].int32, (USHORT)yypvt[-2].int32, yypvt[-0].string)); } break;
-case 96:
-#line 393 "asmparse.y"
-{ yyval.int32 = 0; } break;
-case 97:
-#line 394 "asmparse.y"
-{ yyval.int32 = yypvt[-1].int32 | COR_VTABLE_32BIT; } break;
-case 98:
-#line 395 "asmparse.y"
-{ yyval.int32 = yypvt[-1].int32 | COR_VTABLE_64BIT; } break;
-case 99:
-#line 396 "asmparse.y"
-{ yyval.int32 = yypvt[-1].int32 | COR_VTABLE_FROM_UNMANAGED; } break;
-case 100:
-#line 397 "asmparse.y"
-{ yyval.int32 = yypvt[-1].int32 | COR_VTABLE_CALL_MOST_DERIVED; } break;
-case 101:
-#line 398 "asmparse.y"
-{ yyval.int32 = yypvt[-1].int32 | COR_VTABLE_FROM_UNMANAGED_RETAIN_APPDOMAIN; } break;
-case 102:
-#line 401 "asmparse.y"
-{ PASM->m_pVTable = yypvt[-1].binstr; } break;
-case 103:
-#line 404 "asmparse.y"
-{ bParsingByteArray = TRUE; } break;
-case 104:
-#line 408 "asmparse.y"
-{ PASM->StartNameSpace(yypvt[-0].string); } break;
-case 105:
-#line 411 "asmparse.y"
-{ newclass = TRUE; } break;
-case 106:
-#line 414 "asmparse.y"
-{ if(yypvt[-0].typarlist) FixupConstraints();
- PASM->StartClass(yypvt[-1].string, yypvt[-2].classAttr, yypvt[-0].typarlist);
- TyParFixupList.RESET(false);
- newclass = FALSE;
- } break;
-case 107:
-#line 420 "asmparse.y"
-{ PASM->AddClass(); } break;
-case 108:
-#line 423 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) 0; } break;
-case 109:
-#line 424 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-1].classAttr & ~tdVisibilityMask) | tdPublic); } break;
-case 110:
-#line 425 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-1].classAttr & ~tdVisibilityMask) | tdNotPublic); } break;
-case 111:
-#line 426 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | 0x80000000 | tdSealed); } break;
-case 112:
-#line 427 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | 0x40000000); } break;
-case 113:
-#line 428 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | tdInterface | tdAbstract); } break;
-case 114:
-#line 429 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | tdSealed); } break;
-case 115:
-#line 430 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | tdAbstract); } break;
-case 116:
-#line 431 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-1].classAttr & ~tdLayoutMask) | tdAutoLayout); } break;
-case 117:
-#line 432 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-1].classAttr & ~tdLayoutMask) | tdSequentialLayout); } break;
-case 118:
-#line 433 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-1].classAttr & ~tdLayoutMask) | tdExplicitLayout); } break;
-case 119:
-#line 434 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-1].classAttr & ~tdStringFormatMask) | tdAnsiClass); } break;
-case 120:
-#line 435 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-1].classAttr & ~tdStringFormatMask) | tdUnicodeClass); } break;
-case 121:
-#line 436 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-1].classAttr & ~tdStringFormatMask) | tdAutoClass); } break;
-case 122:
-#line 437 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | tdImport); } break;
-case 123:
-#line 438 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | tdSerializable); } break;
-case 124:
-#line 439 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | tdWindowsRuntime); } break;
-case 125:
-#line 440 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-2].classAttr & ~tdVisibilityMask) | tdNestedPublic); } break;
-case 126:
-#line 441 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-2].classAttr & ~tdVisibilityMask) | tdNestedPrivate); } break;
-case 127:
-#line 442 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-2].classAttr & ~tdVisibilityMask) | tdNestedFamily); } break;
-case 128:
-#line 443 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-2].classAttr & ~tdVisibilityMask) | tdNestedAssembly); } break;
-case 129:
-#line 444 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-2].classAttr & ~tdVisibilityMask) | tdNestedFamANDAssem); } break;
-case 130:
-#line 445 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-2].classAttr & ~tdVisibilityMask) | tdNestedFamORAssem); } break;
-case 131:
-#line 446 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | tdBeforeFieldInit); } break;
-case 132:
-#line 447 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | tdSpecialName); } break;
-case 133:
-#line 448 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr); } break;
-case 134:
-#line 449 "asmparse.y"
-{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].int32); } break;
-case 136:
-#line 453 "asmparse.y"
-{ PASM->m_crExtends = yypvt[-0].token; } break;
-case 141:
-#line 464 "asmparse.y"
-{ PASM->AddToImplList(yypvt[-0].token); } break;
-case 142:
-#line 465 "asmparse.y"
-{ PASM->AddToImplList(yypvt[-0].token); } break;
-case 143:
-#line 469 "asmparse.y"
-{ yyval.binstr = new BinStr(); } break;
-case 144:
-#line 470 "asmparse.y"
-{ yyval.binstr = yypvt[-0].binstr; } break;
-case 145:
-#line 473 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt32(yypvt[-0].token); } break;
-case 146:
-#line 474 "asmparse.y"
-{ yyval.binstr = yypvt[-2].binstr; yyval.binstr->appendInt32(yypvt[-0].token); } break;
-case 147:
-#line 477 "asmparse.y"
-{ yyval.typarlist = NULL; PASM->m_TyParList = NULL;} break;
-case 148:
-#line 478 "asmparse.y"
-{ yyval.typarlist = yypvt[-1].typarlist; PASM->m_TyParList = yypvt[-1].typarlist;} break;
-case 149:
-#line 481 "asmparse.y"
-{ yyval.int32 = gpCovariant; } break;
-case 150:
-#line 482 "asmparse.y"
-{ yyval.int32 = gpContravariant; } break;
-case 151:
-#line 483 "asmparse.y"
-{ yyval.int32 = gpReferenceTypeConstraint; } break;
-case 152:
-#line 484 "asmparse.y"
-{ yyval.int32 = gpNotNullableValueTypeConstraint; } break;
-case 153:
-#line 485 "asmparse.y"
-{ yyval.int32 = gpDefaultConstructorConstraint; } break;
-case 154:
-#line 488 "asmparse.y"
-{ yyval.int32 = 0; } break;
-case 155:
-#line 489 "asmparse.y"
-{ yyval.int32 = yypvt[-1].int32 | yypvt[-0].int32; } break;
-case 156:
-#line 492 "asmparse.y"
-{yyval.typarlist = new TyParList(yypvt[-3].int32, yypvt[-2].binstr, yypvt[-1].string, yypvt[-0].typarlist);} break;
-case 157:
-#line 493 "asmparse.y"
-{yyval.typarlist = new TyParList(yypvt[-2].int32, NULL, yypvt[-1].string, yypvt[-0].typarlist);} break;
-case 158:
-#line 496 "asmparse.y"
-{ yyval.typarlist = NULL; } break;
-case 159:
-#line 497 "asmparse.y"
-{ yyval.typarlist = yypvt[-0].typarlist; } break;
-case 160:
-#line 500 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; } break;
-case 161:
-#line 503 "asmparse.y"
-{ yyval.int32= 0; } break;
-case 162:
-#line 504 "asmparse.y"
-{ yyval.int32 = yypvt[-0].int32; } break;
-case 163:
-#line 507 "asmparse.y"
-{ yyval.int32 = yypvt[-2].int32; } break;
-case 164:
-#line 511 "asmparse.y"
-{ if(PASM->m_pCurMethod->m_ulLines[1] ==0)
- { PASM->m_pCurMethod->m_ulLines[1] = PASM->m_ulCurLine;
- PASM->m_pCurMethod->m_ulColumns[1]=PASM->m_ulCurColumn;}
- PASM->EndMethod(); } break;
-case 165:
-#line 515 "asmparse.y"
-{ PASM->EndClass(); } break;
-case 166:
-#line 516 "asmparse.y"
-{ PASM->EndEvent(); } break;
-case 167:
-#line 517 "asmparse.y"
-{ PASM->EndProp(); } break;
-case 173:
-#line 523 "asmparse.y"
-{ PASM->m_pCurClass->m_ulSize = yypvt[-0].int32; } break;
-case 174:
-#line 524 "asmparse.y"
-{ PASM->m_pCurClass->m_ulPack = yypvt[-0].int32; } break;
-case 175:
-#line 525 "asmparse.y"
-{ PASMM->EndComType(); } break;
-case 176:
-#line 527 "asmparse.y"
-{ BinStr *sig1 = parser->MakeSig(yypvt[-7].int32, yypvt[-6].binstr, yypvt[-1].binstr);
- BinStr *sig2 = new BinStr(); sig2->append(sig1);
- PASM->AddMethodImpl(yypvt[-11].token,yypvt[-9].string,sig1,yypvt[-5].token,yypvt[-3].string,sig2);
- PASM->ResetArgNameList();
- } break;
-case 177:
-#line 533 "asmparse.y"
-{ PASM->AddMethodImpl(yypvt[-17].token,yypvt[-15].string,
- (yypvt[-14].int32==0 ? parser->MakeSig(yypvt[-19].int32,yypvt[-18].binstr,yypvt[-12].binstr) :
- parser->MakeSig(yypvt[-19].int32| IMAGE_CEE_CS_CALLCONV_GENERIC,yypvt[-18].binstr,yypvt[-12].binstr,yypvt[-14].int32)),
- yypvt[-6].token,yypvt[-4].string,
- (yypvt[-3].int32==0 ? parser->MakeSig(yypvt[-8].int32,yypvt[-7].binstr,yypvt[-1].binstr) :
- parser->MakeSig(yypvt[-8].int32| IMAGE_CEE_CS_CALLCONV_GENERIC,yypvt[-7].binstr,yypvt[-1].binstr,yypvt[-3].int32)));
- PASM->ResetArgNameList();
- } break;
-case 180:
-#line 543 "asmparse.y"
-{ if((yypvt[-1].int32 > 0) && (yypvt[-1].int32 <= (int)PASM->m_pCurClass->m_NumTyPars))
- PASM->m_pCustomDescrList = PASM->m_pCurClass->m_TyPars[yypvt[-1].int32-1].CAList();
- else
- PASM->report->error("Type parameter index out of range\n");
- } break;
-case 181:
-#line 548 "asmparse.y"
-{ int n = PASM->m_pCurClass->FindTyPar(yypvt[-0].string);
- if(n >= 0)
- PASM->m_pCustomDescrList = PASM->m_pCurClass->m_TyPars[n].CAList();
- else
- PASM->report->error("Type parameter '%s' undefined\n",yypvt[-0].string);
- } break;
-case 182:
-#line 554 "asmparse.y"
-{ yypvt[-0].cad->tkInterfacePair = yypvt[-1].token;
- if(PASM->m_pCustomDescrList)
- PASM->m_pCustomDescrList->PUSH(yypvt[-0].cad);
- } break;
-case 183:
-#line 562 "asmparse.y"
-{ yypvt[-3].binstr->insertInt8(IMAGE_CEE_CS_CALLCONV_FIELD);
- PASM->AddField(yypvt[-2].string, yypvt[-3].binstr, yypvt[-4].fieldAttr, yypvt[-1].string, yypvt[-0].binstr, yypvt[-5].int32); } break;
-case 184:
-#line 566 "asmparse.y"
-{ yyval.fieldAttr = (CorFieldAttr) 0; } break;
-case 185:
-#line 567 "asmparse.y"
-{ yyval.fieldAttr = (CorFieldAttr) (yypvt[-1].fieldAttr | fdStatic); } break;
-case 186:
-#line 568 "asmparse.y"
-{ yyval.fieldAttr = (CorFieldAttr) ((yypvt[-1].fieldAttr & ~mdMemberAccessMask) | fdPublic); } break;
-case 187:
-#line 569 "asmparse.y"
-{ yyval.fieldAttr = (CorFieldAttr) ((yypvt[-1].fieldAttr & ~mdMemberAccessMask) | fdPrivate); } break;
-case 188:
-#line 570 "asmparse.y"
-{ yyval.fieldAttr = (CorFieldAttr) ((yypvt[-1].fieldAttr & ~mdMemberAccessMask) | fdFamily); } break;
-case 189:
-#line 571 "asmparse.y"
-{ yyval.fieldAttr = (CorFieldAttr) (yypvt[-1].fieldAttr | fdInitOnly); } break;
-case 190:
-#line 572 "asmparse.y"
-{ yyval.fieldAttr = yypvt[-1].fieldAttr; } break;
-case 191:
-#line 573 "asmparse.y"
-{ yyval.fieldAttr = (CorFieldAttr) (yypvt[-1].fieldAttr | fdSpecialName); } break;
-case 192:
-#line 586 "asmparse.y"
-{ PASM->m_pMarshal = yypvt[-1].binstr; } break;
-case 193:
-#line 587 "asmparse.y"
-{ yyval.fieldAttr = (CorFieldAttr) ((yypvt[-1].fieldAttr & ~mdMemberAccessMask) | fdAssembly); } break;
-case 194:
-#line 588 "asmparse.y"
-{ yyval.fieldAttr = (CorFieldAttr) ((yypvt[-1].fieldAttr & ~mdMemberAccessMask) | fdFamANDAssem); } break;
-case 195:
-#line 589 "asmparse.y"
-{ yyval.fieldAttr = (CorFieldAttr) ((yypvt[-1].fieldAttr & ~mdMemberAccessMask) | fdFamORAssem); } break;
-case 196:
-#line 590 "asmparse.y"
-{ yyval.fieldAttr = (CorFieldAttr) ((yypvt[-1].fieldAttr & ~mdMemberAccessMask) | fdPrivateScope); } break;
-case 197:
-#line 591 "asmparse.y"
-{ yyval.fieldAttr = (CorFieldAttr) (yypvt[-1].fieldAttr | fdLiteral); } break;
-case 198:
-#line 592 "asmparse.y"
-{ yyval.fieldAttr = (CorFieldAttr) (yypvt[-1].fieldAttr | fdNotSerialized); } break;
-case 199:
-#line 593 "asmparse.y"
-{ yyval.fieldAttr = (CorFieldAttr) (yypvt[-1].int32); } break;
-case 200:
-#line 596 "asmparse.y"
-{ yyval.string = 0; } break;
-case 201:
-#line 597 "asmparse.y"
-{ yyval.string = yypvt[-0].string; } break;
-case 202:
-#line 600 "asmparse.y"
-{ yyval.binstr = NULL; } break;
-case 203:
-#line 601 "asmparse.y"
-{ yyval.binstr = yypvt[-0].binstr; } break;
-case 204:
-#line 604 "asmparse.y"
-{ yyval.int32 = 0xFFFFFFFF; } break;
-case 205:
-#line 605 "asmparse.y"
-{ yyval.int32 = yypvt[-1].int32; } break;
-case 206:
-#line 610 "asmparse.y"
-{ PASM->ResetArgNameList();
- if (yypvt[-3].binstr == NULL)
- {
- if((iCallConv)&&((yypvt[-8].int32 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n");
- yyval.token = PASM->MakeMemberRef(yypvt[-6].token, yypvt[-4].string, parser->MakeSig(yypvt[-8].int32|iCallConv, yypvt[-7].binstr, yypvt[-1].binstr));
- }
- else
- {
- mdToken mr;
- if((iCallConv)&&((yypvt[-8].int32 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n");
- mr = PASM->MakeMemberRef(yypvt[-6].token, yypvt[-4].string,
- parser->MakeSig(yypvt[-8].int32 | IMAGE_CEE_CS_CALLCONV_GENERIC|iCallConv, yypvt[-7].binstr, yypvt[-1].binstr, corCountArgs(yypvt[-3].binstr)));
- yyval.token = PASM->MakeMethodSpec(mr,
- parser->MakeSig(IMAGE_CEE_CS_CALLCONV_INSTANTIATION, 0, yypvt[-3].binstr));
- }
- } break;
-case 207:
-#line 627 "asmparse.y"
-{ PASM->ResetArgNameList();
- if((iCallConv)&&((yypvt[-8].int32 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n");
- yyval.token = PASM->MakeMemberRef(yypvt[-6].token, yypvt[-4].string,
- parser->MakeSig(yypvt[-8].int32 | IMAGE_CEE_CS_CALLCONV_GENERIC|iCallConv, yypvt[-7].binstr, yypvt[-1].binstr, yypvt[-3].int32));
- } break;
-case 208:
-#line 633 "asmparse.y"
-{ PASM->ResetArgNameList();
- if (yypvt[-3].binstr == NULL)
- {
- if((iCallConv)&&((yypvt[-6].int32 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n");
- yyval.token = PASM->MakeMemberRef(mdTokenNil, yypvt[-4].string, parser->MakeSig(yypvt[-6].int32|iCallConv, yypvt[-5].binstr, yypvt[-1].binstr));
- }
- else
- {
- mdToken mr;
- if((iCallConv)&&((yypvt[-6].int32 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n");
- mr = PASM->MakeMemberRef(mdTokenNil, yypvt[-4].string, parser->MakeSig(yypvt[-6].int32 | IMAGE_CEE_CS_CALLCONV_GENERIC|iCallConv, yypvt[-5].binstr, yypvt[-1].binstr, corCountArgs(yypvt[-3].binstr)));
- yyval.token = PASM->MakeMethodSpec(mr,
- parser->MakeSig(IMAGE_CEE_CS_CALLCONV_INSTANTIATION, 0, yypvt[-3].binstr));
- }
- } break;
-case 209:
-#line 649 "asmparse.y"
-{ PASM->ResetArgNameList();
- if((iCallConv)&&((yypvt[-6].int32 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n");
- yyval.token = PASM->MakeMemberRef(mdTokenNil, yypvt[-4].string, parser->MakeSig(yypvt[-6].int32 | IMAGE_CEE_CS_CALLCONV_GENERIC|iCallConv, yypvt[-5].binstr, yypvt[-1].binstr, yypvt[-3].int32));
- } break;
-case 210:
-#line 653 "asmparse.y"
-{ yyval.token = yypvt[-0].token; } break;
-case 211:
-#line 654 "asmparse.y"
-{ yyval.token = yypvt[-0].tdd->m_tkTypeSpec; } break;
-case 212:
-#line 655 "asmparse.y"
-{ yyval.token = yypvt[-0].tdd->m_tkTypeSpec; } break;
-case 213:
-#line 658 "asmparse.y"
-{ yyval.int32 = (yypvt[-0].int32 | IMAGE_CEE_CS_CALLCONV_HASTHIS); } break;
-case 214:
-#line 659 "asmparse.y"
-{ yyval.int32 = (yypvt[-0].int32 | IMAGE_CEE_CS_CALLCONV_EXPLICITTHIS); } break;
-case 215:
-#line 660 "asmparse.y"
-{ yyval.int32 = yypvt[-0].int32; } break;
-case 216:
-#line 661 "asmparse.y"
-{ yyval.int32 = yypvt[-1].int32; } break;
-case 217:
-#line 664 "asmparse.y"
-{ yyval.int32 = IMAGE_CEE_CS_CALLCONV_DEFAULT; } break;
-case 218:
-#line 665 "asmparse.y"
-{ yyval.int32 = IMAGE_CEE_CS_CALLCONV_DEFAULT; } break;
-case 219:
-#line 666 "asmparse.y"
-{ yyval.int32 = IMAGE_CEE_CS_CALLCONV_VARARG; } break;
-case 220:
-#line 667 "asmparse.y"
-{ yyval.int32 = IMAGE_CEE_CS_CALLCONV_C; } break;
-case 221:
-#line 668 "asmparse.y"
-{ yyval.int32 = IMAGE_CEE_CS_CALLCONV_STDCALL; } break;
-case 222:
-#line 669 "asmparse.y"
-{ yyval.int32 = IMAGE_CEE_CS_CALLCONV_THISCALL; } break;
-case 223:
-#line 670 "asmparse.y"
-{ yyval.int32 = IMAGE_CEE_CS_CALLCONV_FASTCALL; } break;
-case 224:
-#line 673 "asmparse.y"
-{ yyval.token = yypvt[-1].int32; } break;
-case 225:
-#line 676 "asmparse.y"
-{ yyval.token = yypvt[-0].token;
- PASM->delArgNameList(PASM->m_firstArgName);
- PASM->m_firstArgName = parser->m_ANSFirst.POP();
- PASM->m_lastArgName = parser->m_ANSLast.POP();
- PASM->SetMemberRefFixup(yypvt[-0].token,iOpcodeLen); } break;
-case 226:
-#line 682 "asmparse.y"
-{ yypvt[-3].binstr->insertInt8(IMAGE_CEE_CS_CALLCONV_FIELD);
- yyval.token = PASM->MakeMemberRef(yypvt[-2].token, yypvt[-0].string, yypvt[-3].binstr);
- PASM->SetMemberRefFixup(yyval.token,iOpcodeLen); } break;
-case 227:
-#line 686 "asmparse.y"
-{ yypvt[-1].binstr->insertInt8(IMAGE_CEE_CS_CALLCONV_FIELD);
- yyval.token = PASM->MakeMemberRef(NULL, yypvt[-0].string, yypvt[-1].binstr);
- PASM->SetMemberRefFixup(yyval.token,iOpcodeLen); } break;
-case 228:
-#line 689 "asmparse.y"
-{ yyval.token = yypvt[-0].tdd->m_tkTypeSpec;
- PASM->SetMemberRefFixup(yyval.token,iOpcodeLen); } break;
-case 229:
-#line 691 "asmparse.y"
-{ yyval.token = yypvt[-0].tdd->m_tkTypeSpec;
- PASM->SetMemberRefFixup(yyval.token,iOpcodeLen); } break;
-case 230:
-#line 693 "asmparse.y"
-{ yyval.token = yypvt[-0].token;
- PASM->SetMemberRefFixup(yyval.token,iOpcodeLen); } break;
-case 231:
-#line 698 "asmparse.y"
-{ PASM->ResetEvent(yypvt[-0].string, yypvt[-1].token, yypvt[-2].eventAttr); } break;
-case 232:
-#line 699 "asmparse.y"
-{ PASM->ResetEvent(yypvt[-0].string, mdTypeRefNil, yypvt[-1].eventAttr); } break;
-case 233:
-#line 703 "asmparse.y"
-{ yyval.eventAttr = (CorEventAttr) 0; } break;
-case 234:
-#line 704 "asmparse.y"
-{ yyval.eventAttr = yypvt[-1].eventAttr; } break;
-case 235:
-#line 705 "asmparse.y"
-{ yyval.eventAttr = (CorEventAttr) (yypvt[-1].eventAttr | evSpecialName); } break;
-case 238:
-#line 712 "asmparse.y"
-{ PASM->SetEventMethod(0, yypvt[-0].token); } break;
-case 239:
-#line 713 "asmparse.y"
-{ PASM->SetEventMethod(1, yypvt[-0].token); } break;
-case 240:
-#line 714 "asmparse.y"
-{ PASM->SetEventMethod(2, yypvt[-0].token); } break;
-case 241:
-#line 715 "asmparse.y"
-{ PASM->SetEventMethod(3, yypvt[-0].token); } break;
-case 246:
-#line 724 "asmparse.y"
-{ PASM->ResetProp(yypvt[-4].string,
- parser->MakeSig((IMAGE_CEE_CS_CALLCONV_PROPERTY |
- (yypvt[-6].int32 & IMAGE_CEE_CS_CALLCONV_HASTHIS)),yypvt[-5].binstr,yypvt[-2].binstr), yypvt[-7].propAttr, yypvt[-0].binstr);} break;
-case 247:
-#line 729 "asmparse.y"
-{ yyval.propAttr = (CorPropertyAttr) 0; } break;
-case 248:
-#line 730 "asmparse.y"
-{ yyval.propAttr = yypvt[-1].propAttr; } break;
-case 249:
-#line 731 "asmparse.y"
-{ yyval.propAttr = (CorPropertyAttr) (yypvt[-1].propAttr | prSpecialName); } break;
-case 252:
-#line 739 "asmparse.y"
-{ PASM->SetPropMethod(0, yypvt[-0].token); } break;
-case 253:
-#line 740 "asmparse.y"
-{ PASM->SetPropMethod(1, yypvt[-0].token); } break;
-case 254:
-#line 741 "asmparse.y"
-{ PASM->SetPropMethod(2, yypvt[-0].token); } break;
-case 259:
-#line 749 "asmparse.y"
-{ PASM->ResetForNextMethod();
- uMethodBeginLine = PASM->m_ulCurLine;
- uMethodBeginColumn=PASM->m_ulCurColumn;
- } break;
-case 260:
-#line 755 "asmparse.y"
-{ yyval.binstr = NULL; } break;
-case 261:
-#line 756 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; } break;
-case 262:
-#line 759 "asmparse.y"
-{ yyval.binstr = yypvt[-0].binstr; } break;
-case 263:
-#line 760 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; } break;
-case 264:
-#line 763 "asmparse.y"
-{ bParsingByteArray = TRUE; } break;
-case 265:
-#line 767 "asmparse.y"
-{ BinStr* sig;
- if (yypvt[-5].typarlist == NULL) sig = parser->MakeSig(yypvt[-10].int32, yypvt[-8].binstr, yypvt[-3].binstr);
- else {
- FixupTyPars(yypvt[-8].binstr);
- sig = parser->MakeSig(yypvt[-10].int32 | IMAGE_CEE_CS_CALLCONV_GENERIC, yypvt[-8].binstr, yypvt[-3].binstr, yypvt[-5].typarlist->Count());
- FixupConstraints();
- }
- PASM->StartMethod(yypvt[-6].string, sig, yypvt[-11].methAttr, yypvt[-7].binstr, yypvt[-9].int32, yypvt[-5].typarlist);
- TyParFixupList.RESET(false);
- PASM->SetImplAttr((USHORT)yypvt[-1].implAttr);
- PASM->m_pCurMethod->m_ulLines[0] = uMethodBeginLine;
- PASM->m_pCurMethod->m_ulColumns[0]=uMethodBeginColumn;
- } break;
-case 266:
-#line 782 "asmparse.y"
-{ yyval.methAttr = (CorMethodAttr) 0; } break;
-case 267:
-#line 783 "asmparse.y"
-{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdStatic); } break;
-case 268:
-#line 784 "asmparse.y"
-{ yyval.methAttr = (CorMethodAttr) ((yypvt[-1].methAttr & ~mdMemberAccessMask) | mdPublic); } break;
-case 269:
-#line 785 "asmparse.y"
-{ yyval.methAttr = (CorMethodAttr) ((yypvt[-1].methAttr & ~mdMemberAccessMask) | mdPrivate); } break;
-case 270:
-#line 786 "asmparse.y"
-{ yyval.methAttr = (CorMethodAttr) ((yypvt[-1].methAttr & ~mdMemberAccessMask) | mdFamily); } break;
-case 271:
-#line 787 "asmparse.y"
-{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdFinal); } break;
-case 272:
-#line 788 "asmparse.y"
-{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdSpecialName); } break;
-case 273:
-#line 789 "asmparse.y"
-{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdVirtual); } break;
-case 274:
-#line 790 "asmparse.y"
-{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdCheckAccessOnOverride); } break;
-case 275:
-#line 791 "asmparse.y"
-{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdAbstract); } break;
-case 276:
-#line 792 "asmparse.y"
-{ yyval.methAttr = (CorMethodAttr) ((yypvt[-1].methAttr & ~mdMemberAccessMask) | mdAssem); } break;
-case 277:
-#line 793 "asmparse.y"
-{ yyval.methAttr = (CorMethodAttr) ((yypvt[-1].methAttr & ~mdMemberAccessMask) | mdFamANDAssem); } break;
-case 278:
-#line 794 "asmparse.y"
-{ yyval.methAttr = (CorMethodAttr) ((yypvt[-1].methAttr & ~mdMemberAccessMask) | mdFamORAssem); } break;
-case 279:
-#line 795 "asmparse.y"
-{ yyval.methAttr = (CorMethodAttr) ((yypvt[-1].methAttr & ~mdMemberAccessMask) | mdPrivateScope); } break;
-case 280:
-#line 796 "asmparse.y"
-{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdHideBySig); } break;
-case 281:
-#line 797 "asmparse.y"
-{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdNewSlot); } break;
-case 282:
-#line 798 "asmparse.y"
-{ yyval.methAttr = yypvt[-1].methAttr; } break;
-case 283:
-#line 799 "asmparse.y"
-{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdUnmanagedExport); } break;
-case 284:
-#line 800 "asmparse.y"
-{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdRequireSecObject); } break;
-case 285:
-#line 801 "asmparse.y"
-{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].int32); } break;
-case 286:
-#line 803 "asmparse.y"
-{ PASM->SetPinvoke(yypvt[-4].binstr,0,yypvt[-2].binstr,yypvt[-1].pinvAttr);
- yyval.methAttr = (CorMethodAttr) (yypvt[-7].methAttr | mdPinvokeImpl); } break;
-case 287:
-#line 806 "asmparse.y"
-{ PASM->SetPinvoke(yypvt[-2].binstr,0,NULL,yypvt[-1].pinvAttr);
- yyval.methAttr = (CorMethodAttr) (yypvt[-5].methAttr | mdPinvokeImpl); } break;
-case 288:
-#line 809 "asmparse.y"
-{ PASM->SetPinvoke(new BinStr(),0,NULL,yypvt[-1].pinvAttr);
- yyval.methAttr = (CorMethodAttr) (yypvt[-4].methAttr | mdPinvokeImpl); } break;
-case 289:
-#line 813 "asmparse.y"
-{ yyval.pinvAttr = (CorPinvokeMap) 0; } break;
-case 290:
-#line 814 "asmparse.y"
-{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmNoMangle); } break;
-case 291:
-#line 815 "asmparse.y"
-{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmCharSetAnsi); } break;
-case 292:
-#line 816 "asmparse.y"
-{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmCharSetUnicode); } break;
-case 293:
-#line 817 "asmparse.y"
-{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmCharSetAuto); } break;
-case 294:
-#line 818 "asmparse.y"
-{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmSupportsLastError); } break;
-case 295:
-#line 819 "asmparse.y"
-{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmCallConvWinapi); } break;
-case 296:
-#line 820 "asmparse.y"
-{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmCallConvCdecl); } break;
-case 297:
-#line 821 "asmparse.y"
-{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmCallConvStdcall); } break;
-case 298:
-#line 822 "asmparse.y"
-{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmCallConvThiscall); } break;
-case 299:
-#line 823 "asmparse.y"
-{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmCallConvFastcall); } break;
-case 300:
-#line 824 "asmparse.y"
-{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-3].pinvAttr | pmBestFitEnabled); } break;
-case 301:
-#line 825 "asmparse.y"
-{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-3].pinvAttr | pmBestFitDisabled); } break;
-case 302:
-#line 826 "asmparse.y"
-{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-3].pinvAttr | pmThrowOnUnmappableCharEnabled); } break;
-case 303:
-#line 827 "asmparse.y"
-{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-3].pinvAttr | pmThrowOnUnmappableCharDisabled); } break;
-case 304:
-#line 828 "asmparse.y"
-{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].int32); } break;
-case 305:
-#line 831 "asmparse.y"
-{ yyval.string = newString(COR_CTOR_METHOD_NAME); } break;
-case 306:
-#line 832 "asmparse.y"
-{ yyval.string = newString(COR_CCTOR_METHOD_NAME); } break;
-case 307:
-#line 833 "asmparse.y"
-{ yyval.string = yypvt[-0].string; } break;
-case 308:
-#line 836 "asmparse.y"
-{ yyval.int32 = 0; } break;
-case 309:
-#line 837 "asmparse.y"
-{ yyval.int32 = yypvt[-3].int32 | pdIn; } break;
-case 310:
-#line 838 "asmparse.y"
-{ yyval.int32 = yypvt[-3].int32 | pdOut; } break;
-case 311:
-#line 839 "asmparse.y"
-{ yyval.int32 = yypvt[-3].int32 | pdOptional; } break;
-case 312:
-#line 840 "asmparse.y"
-{ yyval.int32 = yypvt[-1].int32 + 1; } break;
-case 313:
-#line 843 "asmparse.y"
-{ yyval.implAttr = (CorMethodImpl) (miIL | miManaged); } break;
-case 314:
-#line 844 "asmparse.y"
-{ yyval.implAttr = (CorMethodImpl) ((yypvt[-1].implAttr & 0xFFF4) | miNative); } break;
-case 315:
-#line 845 "asmparse.y"
-{ yyval.implAttr = (CorMethodImpl) ((yypvt[-1].implAttr & 0xFFF4) | miIL); } break;
-case 316:
-#line 846 "asmparse.y"
-{ yyval.implAttr = (CorMethodImpl) ((yypvt[-1].implAttr & 0xFFF4) | miOPTIL); } break;
-case 317:
-#line 847 "asmparse.y"
-{ yyval.implAttr = (CorMethodImpl) ((yypvt[-1].implAttr & 0xFFFB) | miManaged); } break;
-case 318:
-#line 848 "asmparse.y"
-{ yyval.implAttr = (CorMethodImpl) ((yypvt[-1].implAttr & 0xFFFB) | miUnmanaged); } break;
-case 319:
-#line 849 "asmparse.y"
-{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].implAttr | miForwardRef); } break;
-case 320:
-#line 850 "asmparse.y"
-{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].implAttr | miPreserveSig); } break;
-case 321:
-#line 851 "asmparse.y"
-{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].implAttr | miRuntime); } break;
-case 322:
-#line 852 "asmparse.y"
-{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].implAttr | miInternalCall); } break;
-case 323:
-#line 853 "asmparse.y"
-{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].implAttr | miSynchronized); } break;
-case 324:
-#line 854 "asmparse.y"
-{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].implAttr | miNoInlining); } break;
-case 325:
-#line 855 "asmparse.y"
-{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].implAttr | miAggressiveInlining); } break;
-case 326:
-#line 856 "asmparse.y"
-{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].implAttr | miNoOptimization); } break;
-case 327:
-#line 857 "asmparse.y"
-{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].int32); } break;
-case 328:
-#line 860 "asmparse.y"
-{ PASM->delArgNameList(PASM->m_firstArgName); PASM->m_firstArgName = NULL;PASM->m_lastArgName = NULL;
- } break;
-case 331:
-#line 868 "asmparse.y"
-{ PASM->EmitByte(yypvt[-0].int32); } break;
-case 332:
-#line 869 "asmparse.y"
-{ delete PASM->m_SEHD; PASM->m_SEHD = PASM->m_SEHDstack.POP(); } break;
-case 333:
-#line 870 "asmparse.y"
-{ PASM->EmitMaxStack(yypvt[-0].int32); } break;
-case 334:
-#line 871 "asmparse.y"
-{ PASM->EmitLocals(parser->MakeSig(IMAGE_CEE_CS_CALLCONV_LOCAL_SIG, 0, yypvt[-1].binstr));
- } break;
-case 335:
-#line 873 "asmparse.y"
-{ PASM->EmitZeroInit();
- PASM->EmitLocals(parser->MakeSig(IMAGE_CEE_CS_CALLCONV_LOCAL_SIG, 0, yypvt[-1].binstr));
- } break;
-case 336:
-#line 876 "asmparse.y"
-{ PASM->EmitEntryPoint(); } break;
-case 337:
-#line 877 "asmparse.y"
-{ PASM->EmitZeroInit(); } break;
-case 340:
-#line 880 "asmparse.y"
-{ PASM->AddLabel(PASM->m_CurPC,yypvt[-1].string); /*PASM->EmitLabel($1);*/ } break;
-case 346:
-#line 886 "asmparse.y"
-{ if(PASM->m_pCurMethod->m_dwExportOrdinal == 0xFFFFFFFF)
- {
- PASM->m_pCurMethod->m_dwExportOrdinal = yypvt[-1].int32;
- PASM->m_pCurMethod->m_szExportAlias = NULL;
- if(PASM->m_pCurMethod->m_wVTEntry == 0) PASM->m_pCurMethod->m_wVTEntry = 1;
- if(PASM->m_pCurMethod->m_wVTSlot == 0) PASM->m_pCurMethod->m_wVTSlot = yypvt[-1].int32 + 0x8000;
- }
- else
- PASM->report->warn("Duplicate .export directive, ignored\n");
- } break;
-case 347:
-#line 896 "asmparse.y"
-{ if(PASM->m_pCurMethod->m_dwExportOrdinal == 0xFFFFFFFF)
- {
- PASM->m_pCurMethod->m_dwExportOrdinal = yypvt[-3].int32;
- PASM->m_pCurMethod->m_szExportAlias = yypvt[-0].string;
- if(PASM->m_pCurMethod->m_wVTEntry == 0) PASM->m_pCurMethod->m_wVTEntry = 1;
- if(PASM->m_pCurMethod->m_wVTSlot == 0) PASM->m_pCurMethod->m_wVTSlot = yypvt[-3].int32 + 0x8000;
- }
- else
- PASM->report->warn("Duplicate .export directive, ignored\n");
- } break;
-case 348:
-#line 906 "asmparse.y"
-{ PASM->m_pCurMethod->m_wVTEntry = (WORD)yypvt[-2].int32;
- PASM->m_pCurMethod->m_wVTSlot = (WORD)yypvt[-0].int32; } break;
-case 349:
-#line 909 "asmparse.y"
-{ PASM->AddMethodImpl(yypvt[-2].token,yypvt[-0].string,NULL,NULL,NULL,NULL); } break;
-case 350:
-#line 912 "asmparse.y"
-{ PASM->AddMethodImpl(yypvt[-6].token,yypvt[-4].string,
- (yypvt[-3].int32==0 ? parser->MakeSig(yypvt[-8].int32,yypvt[-7].binstr,yypvt[-1].binstr) :
- parser->MakeSig(yypvt[-8].int32| IMAGE_CEE_CS_CALLCONV_GENERIC,yypvt[-7].binstr,yypvt[-1].binstr,yypvt[-3].int32))
- ,NULL,NULL,NULL);
- PASM->ResetArgNameList();
- } break;
-case 352:
-#line 919 "asmparse.y"
-{ if((yypvt[-1].int32 > 0) && (yypvt[-1].int32 <= (int)PASM->m_pCurMethod->m_NumTyPars))
- PASM->m_pCustomDescrList = PASM->m_pCurMethod->m_TyPars[yypvt[-1].int32-1].CAList();
- else
- PASM->report->error("Type parameter index out of range\n");
- } break;
-case 353:
-#line 924 "asmparse.y"
-{ int n = PASM->m_pCurMethod->FindTyPar(yypvt[-0].string);
- if(n >= 0)
- PASM->m_pCustomDescrList = PASM->m_pCurMethod->m_TyPars[n].CAList();
- else
- PASM->report->error("Type parameter '%s' undefined\n",yypvt[-0].string);
- } break;
-case 354:
-#line 931 "asmparse.y"
-{ if( yypvt[-2].int32 ) {
- ARG_NAME_LIST* pAN=PASM->findArg(PASM->m_pCurMethod->m_firstArgName, yypvt[-2].int32 - 1);
- if(pAN)
- {
- PASM->m_pCustomDescrList = &(pAN->CustDList);
- pAN->pValue = yypvt[-0].binstr;
- }
- else
- {
- PASM->m_pCustomDescrList = NULL;
- if(yypvt[-0].binstr) delete yypvt[-0].binstr;
- }
- } else {
- PASM->m_pCustomDescrList = &(PASM->m_pCurMethod->m_RetCustDList);
- PASM->m_pCurMethod->m_pRetValue = yypvt[-0].binstr;
- }
- PASM->m_tkCurrentCVOwner = 0;
- } break;
-case 355:
-#line 951 "asmparse.y"
-{ PASM->m_pCurMethod->CloseScope(); } break;
-case 356:
-#line 954 "asmparse.y"
-{ PASM->m_pCurMethod->OpenScope(); } break;
-case 360:
-#line 965 "asmparse.y"
-{ PASM->m_SEHD->tryTo = PASM->m_CurPC; } break;
-case 361:
-#line 966 "asmparse.y"
-{ PASM->SetTryLabels(yypvt[-2].string, yypvt[-0].string); } break;
-case 362:
-#line 967 "asmparse.y"
-{ if(PASM->m_SEHD) {PASM->m_SEHD->tryFrom = yypvt[-2].int32;
- PASM->m_SEHD->tryTo = yypvt[-0].int32;} } break;
-case 363:
-#line 971 "asmparse.y"
-{ PASM->NewSEHDescriptor();
- PASM->m_SEHD->tryFrom = PASM->m_CurPC; } break;
-case 364:
-#line 976 "asmparse.y"
-{ PASM->EmitTry(); } break;
-case 365:
-#line 977 "asmparse.y"
-{ PASM->EmitTry(); } break;
-case 366:
-#line 978 "asmparse.y"
-{ PASM->EmitTry(); } break;
-case 367:
-#line 979 "asmparse.y"
-{ PASM->EmitTry(); } break;
-case 368:
-#line 983 "asmparse.y"
-{ PASM->m_SEHD->sehHandler = PASM->m_CurPC; } break;
-case 369:
-#line 984 "asmparse.y"
-{ PASM->SetFilterLabel(yypvt[-0].string);
- PASM->m_SEHD->sehHandler = PASM->m_CurPC; } break;
-case 370:
-#line 986 "asmparse.y"
-{ PASM->m_SEHD->sehFilter = yypvt[-0].int32;
- PASM->m_SEHD->sehHandler = PASM->m_CurPC; } break;
-case 371:
-#line 990 "asmparse.y"
-{ PASM->m_SEHD->sehClause = COR_ILEXCEPTION_CLAUSE_FILTER;
- PASM->m_SEHD->sehFilter = PASM->m_CurPC; } break;
-case 372:
-#line 994 "asmparse.y"
-{ PASM->m_SEHD->sehClause = COR_ILEXCEPTION_CLAUSE_NONE;
- PASM->SetCatchClass(yypvt[-0].token);
- PASM->m_SEHD->sehHandler = PASM->m_CurPC; } break;
-case 373:
-#line 999 "asmparse.y"
-{ PASM->m_SEHD->sehClause = COR_ILEXCEPTION_CLAUSE_FINALLY;
- PASM->m_SEHD->sehHandler = PASM->m_CurPC; } break;
-case 374:
-#line 1003 "asmparse.y"
-{ PASM->m_SEHD->sehClause = COR_ILEXCEPTION_CLAUSE_FAULT;
- PASM->m_SEHD->sehHandler = PASM->m_CurPC; } break;
-case 375:
-#line 1007 "asmparse.y"
-{ PASM->m_SEHD->sehHandlerTo = PASM->m_CurPC; } break;
-case 376:
-#line 1008 "asmparse.y"
-{ PASM->SetHandlerLabels(yypvt[-2].string, yypvt[-0].string); } break;
-case 377:
-#line 1009 "asmparse.y"
-{ PASM->m_SEHD->sehHandler = yypvt[-2].int32;
- PASM->m_SEHD->sehHandlerTo = yypvt[-0].int32; } break;
-case 379:
-#line 1017 "asmparse.y"
-{ PASM->EmitDataLabel(yypvt[-1].string); } break;
-case 381:
-#line 1021 "asmparse.y"
-{ PASM->SetDataSection(); } break;
-case 382:
-#line 1022 "asmparse.y"
-{ PASM->SetTLSSection(); } break;
-case 383:
-#line 1023 "asmparse.y"
-{ PASM->SetILSection(); } break;
-case 388:
-#line 1034 "asmparse.y"
-{ yyval.int32 = 1; } break;
-case 389:
-#line 1035 "asmparse.y"
-{ yyval.int32 = yypvt[-1].int32;
- if(yypvt[-1].int32 <= 0) { PASM->report->error("Illegal item count: %d\n",yypvt[-1].int32);
- if(!PASM->OnErrGo) yyval.int32 = 1; }} break;
-case 390:
-#line 1040 "asmparse.y"
-{ PASM->EmitDataString(yypvt[-1].binstr); } break;
-case 391:
-#line 1041 "asmparse.y"
-{ PASM->EmitDD(yypvt[-1].string); } break;
-case 392:
-#line 1042 "asmparse.y"
-{ PASM->EmitData(yypvt[-1].binstr->ptr(),yypvt[-1].binstr->length()); } break;
-case 393:
-#line 1044 "asmparse.y"
-{ float f = (float) (*yypvt[-2].float64); float* p = new (nothrow) float[yypvt[-0].int32];
- if(p != NULL) {
- for(int i=0; i < yypvt[-0].int32; i++) p[i] = f;
- PASM->EmitData(p, sizeof(float)*yypvt[-0].int32); delete yypvt[-2].float64; delete [] p;
- } else PASM->report->error("Out of memory emitting data block %d bytes\n",
- sizeof(float)*yypvt[-0].int32); } break;
-case 394:
-#line 1051 "asmparse.y"
-{ double* p = new (nothrow) double[yypvt[-0].int32];
- if(p != NULL) {
- for(int i=0; i<yypvt[-0].int32; i++) p[i] = *(yypvt[-2].float64);
- PASM->EmitData(p, sizeof(double)*yypvt[-0].int32); delete yypvt[-2].float64; delete [] p;
- } else PASM->report->error("Out of memory emitting data block %d bytes\n",
- sizeof(double)*yypvt[-0].int32); } break;
-case 395:
-#line 1058 "asmparse.y"
-{ __int64* p = new (nothrow) __int64[yypvt[-0].int32];
- if(p != NULL) {
- for(int i=0; i<yypvt[-0].int32; i++) p[i] = *(yypvt[-2].int64);
- PASM->EmitData(p, sizeof(__int64)*yypvt[-0].int32); delete yypvt[-2].int64; delete [] p;
- } else PASM->report->error("Out of memory emitting data block %d bytes\n",
- sizeof(__int64)*yypvt[-0].int32); } break;
-case 396:
-#line 1065 "asmparse.y"
-{ __int32* p = new (nothrow) __int32[yypvt[-0].int32];
- if(p != NULL) {
- for(int i=0; i<yypvt[-0].int32; i++) p[i] = yypvt[-2].int32;
- PASM->EmitData(p, sizeof(__int32)*yypvt[-0].int32); delete [] p;
- } else PASM->report->error("Out of memory emitting data block %d bytes\n",
- sizeof(__int32)*yypvt[-0].int32); } break;
-case 397:
-#line 1072 "asmparse.y"
-{ __int16 i = (__int16) yypvt[-2].int32; FAIL_UNLESS(i == yypvt[-2].int32, ("Value %d too big\n", yypvt[-2].int32));
- __int16* p = new (nothrow) __int16[yypvt[-0].int32];
- if(p != NULL) {
- for(int j=0; j<yypvt[-0].int32; j++) p[j] = i;
- PASM->EmitData(p, sizeof(__int16)*yypvt[-0].int32); delete [] p;
- } else PASM->report->error("Out of memory emitting data block %d bytes\n",
- sizeof(__int16)*yypvt[-0].int32); } break;
-case 398:
-#line 1080 "asmparse.y"
-{ __int8 i = (__int8) yypvt[-2].int32; FAIL_UNLESS(i == yypvt[-2].int32, ("Value %d too big\n", yypvt[-2].int32));
- __int8* p = new (nothrow) __int8[yypvt[-0].int32];
- if(p != NULL) {
- for(int j=0; j<yypvt[-0].int32; j++) p[j] = i;
- PASM->EmitData(p, sizeof(__int8)*yypvt[-0].int32); delete [] p;
- } else PASM->report->error("Out of memory emitting data block %d bytes\n",
- sizeof(__int8)*yypvt[-0].int32); } break;
-case 399:
-#line 1087 "asmparse.y"
-{ PASM->EmitData(NULL, sizeof(float)*yypvt[-0].int32); } break;
-case 400:
-#line 1088 "asmparse.y"
-{ PASM->EmitData(NULL, sizeof(double)*yypvt[-0].int32); } break;
-case 401:
-#line 1089 "asmparse.y"
-{ PASM->EmitData(NULL, sizeof(__int64)*yypvt[-0].int32); } break;
-case 402:
-#line 1090 "asmparse.y"
-{ PASM->EmitData(NULL, sizeof(__int32)*yypvt[-0].int32); } break;
-case 403:
-#line 1091 "asmparse.y"
-{ PASM->EmitData(NULL, sizeof(__int16)*yypvt[-0].int32); } break;
-case 404:
-#line 1092 "asmparse.y"
-{ PASM->EmitData(NULL, sizeof(__int8)*yypvt[-0].int32); } break;
-case 405:
-#line 1096 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_R4);
- float f = (float)(*yypvt[-1].float64);
- yyval.binstr->appendInt32(*((__int32*)&f)); delete yypvt[-1].float64; } break;
-case 406:
-#line 1099 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_R8);
- yyval.binstr->appendInt64((__int64 *)yypvt[-1].float64); delete yypvt[-1].float64; } break;
-case 407:
-#line 1101 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_R4);
- yyval.binstr->appendInt32(yypvt[-1].int32); } break;
-case 408:
-#line 1103 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_R8);
- yyval.binstr->appendInt64((__int64 *)yypvt[-1].int64); delete yypvt[-1].int64; } break;
-case 409:
-#line 1105 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I8);
- yyval.binstr->appendInt64((__int64 *)yypvt[-1].int64); delete yypvt[-1].int64; } break;
-case 410:
-#line 1107 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I4);
- yyval.binstr->appendInt32(yypvt[-1].int32); } break;
-case 411:
-#line 1109 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I2);
- yyval.binstr->appendInt16(yypvt[-1].int32); } break;
-case 412:
-#line 1111 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I1);
- yyval.binstr->appendInt8(yypvt[-1].int32); } break;
-case 413:
-#line 1113 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U8);
- yyval.binstr->appendInt64((__int64 *)yypvt[-1].int64); delete yypvt[-1].int64; } break;
-case 414:
-#line 1115 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U4);
- yyval.binstr->appendInt32(yypvt[-1].int32); } break;
-case 415:
-#line 1117 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U2);
- yyval.binstr->appendInt16(yypvt[-1].int32); } break;
-case 416:
-#line 1119 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U1);
- yyval.binstr->appendInt8(yypvt[-1].int32); } break;
-case 417:
-#line 1121 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U8);
- yyval.binstr->appendInt64((__int64 *)yypvt[-1].int64); delete yypvt[-1].int64; } break;
-case 418:
-#line 1123 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U4);
- yyval.binstr->appendInt32(yypvt[-1].int32); } break;
-case 419:
-#line 1125 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U2);
- yyval.binstr->appendInt16(yypvt[-1].int32); } break;
-case 420:
-#line 1127 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U1);
- yyval.binstr->appendInt8(yypvt[-1].int32); } break;
-case 421:
-#line 1129 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_CHAR);
- yyval.binstr->appendInt16(yypvt[-1].int32); } break;
-case 422:
-#line 1131 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_BOOLEAN);
- yyval.binstr->appendInt8(yypvt[-1].int32);} break;
-case 423:
-#line 1133 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_STRING);
- yyval.binstr->append(yypvt[-1].binstr); delete yypvt[-1].binstr;} break;
-case 424:
-#line 1137 "asmparse.y"
-{ bParsingByteArray = TRUE; } break;
-case 425:
-#line 1140 "asmparse.y"
-{ yyval.binstr = new BinStr(); } break;
-case 426:
-#line 1141 "asmparse.y"
-{ yyval.binstr = yypvt[-0].binstr; } break;
-case 427:
-#line 1144 "asmparse.y"
-{ __int8 i = (__int8) yypvt[-0].int32; yyval.binstr = new BinStr(); yyval.binstr->appendInt8(i); } break;
-case 428:
-#line 1145 "asmparse.y"
-{ __int8 i = (__int8) yypvt[-0].int32; yyval.binstr = yypvt[-1].binstr; yyval.binstr->appendInt8(i); } break;
-case 429:
-#line 1149 "asmparse.y"
-{ yyval.binstr = yypvt[-0].binstr; } break;
-case 430:
-#line 1150 "asmparse.y"
-{ yyval.binstr = BinStrToUnicode(yypvt[-0].binstr,true); yyval.binstr->insertInt8(ELEMENT_TYPE_STRING);} break;
-case 431:
-#line 1151 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_CLASS);
- yyval.binstr->appendInt32(0); } break;
-case 432:
-#line 1156 "asmparse.y"
-{ yyval.binstr = yypvt[-0].binstr; } break;
-case 433:
-#line 1157 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_STRING); yyval.binstr->appendInt8(0xFF); } break;
-case 434:
-#line 1158 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_STRING);
- AppendStringWithLength(yyval.binstr,yypvt[-1].string); delete [] yypvt[-1].string;} break;
-case 435:
-#line 1160 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(SERIALIZATION_TYPE_TYPE);
- AppendStringWithLength(yyval.binstr,yypvt[-1].string); delete [] yypvt[-1].string;} break;
-case 436:
-#line 1162 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(SERIALIZATION_TYPE_TYPE);
- AppendStringWithLength(yyval.binstr,PASM->ReflectionNotation(yypvt[-1].token));} break;
-case 437:
-#line 1164 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(SERIALIZATION_TYPE_TYPE); yyval.binstr->appendInt8(0xFF); } break;
-case 438:
-#line 1165 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt8(SERIALIZATION_TYPE_TAGGED_OBJECT);} break;
-case 439:
-#line 1167 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
- yyval.binstr->insertInt8(ELEMENT_TYPE_R4);
- yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
-case 440:
-#line 1171 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
- yyval.binstr->insertInt8(ELEMENT_TYPE_R8);
- yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
-case 441:
-#line 1175 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
- yyval.binstr->insertInt8(ELEMENT_TYPE_I8);
- yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
-case 442:
-#line 1179 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
- yyval.binstr->insertInt8(ELEMENT_TYPE_I4);
- yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
-case 443:
-#line 1183 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
- yyval.binstr->insertInt8(ELEMENT_TYPE_I2);
- yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
-case 444:
-#line 1187 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
- yyval.binstr->insertInt8(ELEMENT_TYPE_I1);
- yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
-case 445:
-#line 1191 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
- yyval.binstr->insertInt8(ELEMENT_TYPE_U8);
- yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
-case 446:
-#line 1195 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
- yyval.binstr->insertInt8(ELEMENT_TYPE_U4);
- yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
-case 447:
-#line 1199 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
- yyval.binstr->insertInt8(ELEMENT_TYPE_U2);
- yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
-case 448:
-#line 1203 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
- yyval.binstr->insertInt8(ELEMENT_TYPE_U1);
- yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
-case 449:
-#line 1207 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
- yyval.binstr->insertInt8(ELEMENT_TYPE_U8);
- yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
-case 450:
-#line 1211 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
- yyval.binstr->insertInt8(ELEMENT_TYPE_U4);
- yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
-case 451:
-#line 1215 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
- yyval.binstr->insertInt8(ELEMENT_TYPE_U2);
- yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
-case 452:
-#line 1219 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
- yyval.binstr->insertInt8(ELEMENT_TYPE_U1);
- yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
-case 453:
-#line 1223 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
- yyval.binstr->insertInt8(ELEMENT_TYPE_CHAR);
- yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
-case 454:
-#line 1227 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
- yyval.binstr->insertInt8(ELEMENT_TYPE_BOOLEAN);
- yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
-case 455:
-#line 1231 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
- yyval.binstr->insertInt8(ELEMENT_TYPE_STRING);
- yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
-case 456:
-#line 1235 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
- yyval.binstr->insertInt8(SERIALIZATION_TYPE_TYPE);
- yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
-case 457:
-#line 1239 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
- yyval.binstr->insertInt8(SERIALIZATION_TYPE_TAGGED_OBJECT);
- yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
-case 458:
-#line 1245 "asmparse.y"
-{ yyval.binstr = new BinStr(); } break;
-case 459:
-#line 1246 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr;
- float f = (float) (*yypvt[-0].float64); yyval.binstr->appendInt32(*((__int32*)&f)); delete yypvt[-0].float64; } break;
-case 460:
-#line 1248 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr;
- yyval.binstr->appendInt32(yypvt[-0].int32); } break;
-case 461:
-#line 1252 "asmparse.y"
-{ yyval.binstr = new BinStr(); } break;
-case 462:
-#line 1253 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr;
- yyval.binstr->appendInt64((__int64 *)yypvt[-0].float64); delete yypvt[-0].float64; } break;
-case 463:
-#line 1255 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr;
- yyval.binstr->appendInt64((__int64 *)yypvt[-0].int64); delete yypvt[-0].int64; } break;
-case 464:
-#line 1259 "asmparse.y"
-{ yyval.binstr = new BinStr(); } break;
-case 465:
-#line 1260 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr;
- yyval.binstr->appendInt64((__int64 *)yypvt[-0].int64); delete yypvt[-0].int64; } break;
-case 466:
-#line 1264 "asmparse.y"
-{ yyval.binstr = new BinStr(); } break;
-case 467:
-#line 1265 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->appendInt32(yypvt[-0].int32);} break;
-case 468:
-#line 1268 "asmparse.y"
-{ yyval.binstr = new BinStr(); } break;
-case 469:
-#line 1269 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->appendInt16(yypvt[-0].int32);} break;
-case 470:
-#line 1272 "asmparse.y"
-{ yyval.binstr = new BinStr(); } break;
-case 471:
-#line 1273 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->appendInt8(yypvt[-0].int32); } break;
-case 472:
-#line 1276 "asmparse.y"
-{ yyval.binstr = new BinStr(); } break;
-case 473:
-#line 1277 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr;
- yyval.binstr->appendInt8(yypvt[-0].int32);} break;
-case 474:
-#line 1281 "asmparse.y"
-{ yyval.binstr = new BinStr(); } break;
-case 475:
-#line 1282 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->appendInt8(0xFF); } break;
-case 476:
-#line 1283 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr;
- AppendStringWithLength(yyval.binstr,yypvt[-0].string); delete [] yypvt[-0].string;} break;
-case 477:
-#line 1287 "asmparse.y"
-{ yyval.binstr = new BinStr(); } break;
-case 478:
-#line 1288 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->appendInt8(0xFF); } break;
-case 479:
-#line 1289 "asmparse.y"
-{ yyval.binstr = yypvt[-2].binstr;
- AppendStringWithLength(yyval.binstr,yypvt[-0].string); delete [] yypvt[-0].string;} break;
-case 480:
-#line 1291 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr;
- AppendStringWithLength(yyval.binstr,PASM->ReflectionNotation(yypvt[-0].token));} break;
-case 481:
-#line 1295 "asmparse.y"
-{ yyval.binstr = new BinStr(); } break;
-case 482:
-#line 1296 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->append(yypvt[-0].binstr); delete yypvt[-0].binstr; } break;
-case 483:
-#line 1300 "asmparse.y"
-{ parser->m_ANSFirst.PUSH(PASM->m_firstArgName);
- parser->m_ANSLast.PUSH(PASM->m_lastArgName);
- PASM->m_firstArgName = NULL;
- PASM->m_lastArgName = NULL; } break;
-case 484:
-#line 1306 "asmparse.y"
-{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
-case 485:
-#line 1309 "asmparse.y"
-{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
-case 486:
-#line 1312 "asmparse.y"
-{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
-case 487:
-#line 1315 "asmparse.y"
-{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
-case 488:
-#line 1318 "asmparse.y"
-{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
-case 489:
-#line 1321 "asmparse.y"
-{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
-case 490:
-#line 1324 "asmparse.y"
-{ yyval.instr = SetupInstr(yypvt[-0].opcode);
- if((!PASM->OnErrGo)&&
- ((yypvt[-0].opcode == CEE_NEWOBJ)||
- (yypvt[-0].opcode == CEE_CALLVIRT)))
- iCallConv = IMAGE_CEE_CS_CALLCONV_HASTHIS;
- } break;
-case 491:
-#line 1332 "asmparse.y"
-{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
-case 492:
-#line 1335 "asmparse.y"
-{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
-case 493:
-#line 1338 "asmparse.y"
-{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
-case 494:
-#line 1341 "asmparse.y"
-{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
-case 495:
-#line 1344 "asmparse.y"
-{ yyval.instr = SetupInstr(yypvt[-0].opcode); iOpcodeLen = PASM->OpcodeLen(yyval.instr); } break;
-case 496:
-#line 1347 "asmparse.y"
-{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
-case 497:
-#line 1350 "asmparse.y"
-{ yyval.instr = yypvt[-1].instr; bParsingByteArray = TRUE; } break;
-case 498:
-#line 1354 "asmparse.y"
-{ PASM->EmitOpcode(yypvt[-0].instr); } break;
-case 499:
-#line 1355 "asmparse.y"
-{ PASM->EmitInstrVar(yypvt[-1].instr, yypvt[-0].int32); } break;
-case 500:
-#line 1356 "asmparse.y"
-{ PASM->EmitInstrVarByName(yypvt[-1].instr, yypvt[-0].string); } break;
-case 501:
-#line 1357 "asmparse.y"
-{ PASM->EmitInstrI(yypvt[-1].instr, yypvt[-0].int32); } break;
-case 502:
-#line 1358 "asmparse.y"
-{ PASM->EmitInstrI8(yypvt[-1].instr, yypvt[-0].int64); } break;
-case 503:
-#line 1359 "asmparse.y"
-{ PASM->EmitInstrR(yypvt[-1].instr, yypvt[-0].float64); delete (yypvt[-0].float64);} break;
-case 504:
-#line 1360 "asmparse.y"
-{ double f = (double) (*yypvt[-0].int64); PASM->EmitInstrR(yypvt[-1].instr, &f); } break;
-case 505:
-#line 1361 "asmparse.y"
-{ unsigned L = yypvt[-1].binstr->length();
- FAIL_UNLESS(L >= sizeof(float), ("%d hexbytes, must be at least %d\n",
- L,sizeof(float)));
- if(L < sizeof(float)) {YYERROR; }
- else {
- double f = (L >= sizeof(double)) ? *((double *)(yypvt[-1].binstr->ptr()))
- : (double)(*(float *)(yypvt[-1].binstr->ptr()));
- PASM->EmitInstrR(yypvt[-2].instr,&f); }
- delete yypvt[-1].binstr; } break;
-case 506:
-#line 1370 "asmparse.y"
-{ PASM->EmitInstrBrOffset(yypvt[-1].instr, yypvt[-0].int32); } break;
-case 507:
-#line 1371 "asmparse.y"
-{ PASM->EmitInstrBrTarget(yypvt[-1].instr, yypvt[-0].string); } break;
-case 508:
-#line 1373 "asmparse.y"
-{ PASM->SetMemberRefFixup(yypvt[-0].token,PASM->OpcodeLen(yypvt[-1].instr));
- PASM->EmitInstrI(yypvt[-1].instr,yypvt[-0].token);
- PASM->m_tkCurrentCVOwner = yypvt[-0].token;
- PASM->m_pCustomDescrList = NULL;
- iCallConv = 0;
- } break;
-case 509:
-#line 1380 "asmparse.y"
-{ yypvt[-3].binstr->insertInt8(IMAGE_CEE_CS_CALLCONV_FIELD);
- mdToken mr = PASM->MakeMemberRef(yypvt[-2].token, yypvt[-0].string, yypvt[-3].binstr);
- PASM->SetMemberRefFixup(mr, PASM->OpcodeLen(yypvt[-4].instr));
- PASM->EmitInstrI(yypvt[-4].instr,mr);
- PASM->m_tkCurrentCVOwner = mr;
- PASM->m_pCustomDescrList = NULL;
- } break;
-case 510:
-#line 1388 "asmparse.y"
-{ yypvt[-1].binstr->insertInt8(IMAGE_CEE_CS_CALLCONV_FIELD);
- mdToken mr = PASM->MakeMemberRef(mdTokenNil, yypvt[-0].string, yypvt[-1].binstr);
- PASM->SetMemberRefFixup(mr, PASM->OpcodeLen(yypvt[-2].instr));
- PASM->EmitInstrI(yypvt[-2].instr,mr);
- PASM->m_tkCurrentCVOwner = mr;
- PASM->m_pCustomDescrList = NULL;
- } break;
-case 511:
-#line 1395 "asmparse.y"
-{ mdToken mr = yypvt[-0].token;
- PASM->SetMemberRefFixup(mr, PASM->OpcodeLen(yypvt[-1].instr));
- PASM->EmitInstrI(yypvt[-1].instr,mr);
- PASM->m_tkCurrentCVOwner = mr;
- PASM->m_pCustomDescrList = NULL;
- } break;
-case 512:
-#line 1401 "asmparse.y"
-{ mdToken mr = yypvt[-0].tdd->m_tkTypeSpec;
- PASM->SetMemberRefFixup(mr, PASM->OpcodeLen(yypvt[-1].instr));
- PASM->EmitInstrI(yypvt[-1].instr,mr);
- PASM->m_tkCurrentCVOwner = mr;
- PASM->m_pCustomDescrList = NULL;
- } break;
-case 513:
-#line 1407 "asmparse.y"
-{ mdToken mr = yypvt[-0].tdd->m_tkTypeSpec;
- PASM->SetMemberRefFixup(mr, PASM->OpcodeLen(yypvt[-1].instr));
- PASM->EmitInstrI(yypvt[-1].instr,mr);
- PASM->m_tkCurrentCVOwner = mr;
- PASM->m_pCustomDescrList = NULL;
- } break;
-case 514:
-#line 1413 "asmparse.y"
-{ PASM->EmitInstrI(yypvt[-1].instr, yypvt[-0].token);
- PASM->m_tkCurrentCVOwner = yypvt[-0].token;
- PASM->m_pCustomDescrList = NULL;
- } break;
-case 515:
-#line 1417 "asmparse.y"
-{ PASM->EmitInstrStringLiteral(yypvt[-1].instr, yypvt[-0].binstr,TRUE); } break;
-case 516:
-#line 1419 "asmparse.y"
-{ PASM->EmitInstrStringLiteral(yypvt[-4].instr, yypvt[-1].binstr,FALSE); } break;
-case 517:
-#line 1421 "asmparse.y"
-{ PASM->EmitInstrStringLiteral(yypvt[-3].instr, yypvt[-1].binstr,FALSE,TRUE); } break;
-case 518:
-#line 1423 "asmparse.y"
-{ PASM->EmitInstrSig(yypvt[-5].instr, parser->MakeSig(yypvt[-4].int32, yypvt[-3].binstr, yypvt[-1].binstr));
- PASM->ResetArgNameList();
- } break;
-case 519:
-#line 1427 "asmparse.y"
-{ PASM->EmitInstrI(yypvt[-1].instr,yypvt[-0].token);
- PASM->m_tkCurrentCVOwner = yypvt[-0].token;
- PASM->m_pCustomDescrList = NULL;
- iOpcodeLen = 0;
- } break;
-case 520:
-#line 1432 "asmparse.y"
-{ PASM->EmitInstrSwitch(yypvt[-3].instr, yypvt[-1].labels); } break;
-case 521:
-#line 1435 "asmparse.y"
-{ yyval.labels = 0; } break;
-case 522:
-#line 1436 "asmparse.y"
-{ yyval.labels = new Labels(yypvt[-2].string, yypvt[-0].labels, TRUE); } break;
-case 523:
-#line 1437 "asmparse.y"
-{ yyval.labels = new Labels((char *)(UINT_PTR)yypvt[-2].int32, yypvt[-0].labels, FALSE); } break;
-case 524:
-#line 1438 "asmparse.y"
-{ yyval.labels = new Labels(yypvt[-0].string, NULL, TRUE); } break;
-case 525:
-#line 1439 "asmparse.y"
-{ yyval.labels = new Labels((char *)(UINT_PTR)yypvt[-0].int32, NULL, FALSE); } break;
-case 526:
-#line 1443 "asmparse.y"
-{ yyval.binstr = NULL; } break;
-case 527:
-#line 1444 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; } break;
-case 528:
-#line 1447 "asmparse.y"
-{ yyval.binstr = NULL; } break;
-case 529:
-#line 1448 "asmparse.y"
-{ yyval.binstr = yypvt[-0].binstr; } break;
-case 530:
-#line 1451 "asmparse.y"
-{ yyval.binstr = yypvt[-0].binstr; } break;
-case 531:
-#line 1452 "asmparse.y"
-{ yyval.binstr = yypvt[-2].binstr; yyval.binstr->append(yypvt[-0].binstr); delete yypvt[-0].binstr; } break;
-case 532:
-#line 1456 "asmparse.y"
-{ yyval.binstr = new BinStr(); } break;
-case 533:
-#line 1457 "asmparse.y"
-{ yyval.binstr = yypvt[-0].binstr;} break;
-case 534:
-#line 1460 "asmparse.y"
-{ yyval.binstr = yypvt[-0].binstr; } break;
-case 535:
-#line 1461 "asmparse.y"
-{ yyval.binstr = yypvt[-2].binstr; yyval.binstr->append(yypvt[-0].binstr); delete yypvt[-0].binstr; } break;
-case 536:
-#line 1464 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_SENTINEL); } break;
-case 537:
-#line 1465 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->append(yypvt[-1].binstr); PASM->addArgName(NULL, yypvt[-1].binstr, yypvt[-0].binstr, yypvt[-2].int32); } break;
-case 538:
-#line 1466 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->append(yypvt[-2].binstr); PASM->addArgName(yypvt[-0].string, yypvt[-2].binstr, yypvt[-1].binstr, yypvt[-3].int32);} break;
-case 539:
-#line 1470 "asmparse.y"
-{ yyval.token = PASM->ResolveClassRef(PASM->GetAsmRef(yypvt[-2].string), yypvt[-0].string, NULL); delete[] yypvt[-2].string;} break;
-case 540:
-#line 1471 "asmparse.y"
-{ yyval.token = PASM->ResolveClassRef(yypvt[-2].token, yypvt[-0].string, NULL); } break;
-case 541:
-#line 1472 "asmparse.y"
-{ yyval.token = PASM->ResolveClassRef(mdTokenNil, yypvt[-0].string, NULL); } break;
-case 542:
-#line 1473 "asmparse.y"
-{ yyval.token = PASM->ResolveClassRef(PASM->GetModRef(yypvt[-2].string),yypvt[-0].string, NULL); delete[] yypvt[-2].string;} break;
-case 543:
-#line 1474 "asmparse.y"
-{ yyval.token = PASM->ResolveClassRef(1,yypvt[-0].string,NULL); } break;
-case 544:
-#line 1475 "asmparse.y"
-{ yyval.token = yypvt[-0].token; } break;
-case 545:
-#line 1476 "asmparse.y"
-{ yyval.token = yypvt[-0].tdd->m_tkTypeSpec; } break;
-case 546:
-#line 1477 "asmparse.y"
-{ if(PASM->m_pCurClass != NULL) yyval.token = PASM->m_pCurClass->m_cl;
- else { yyval.token = 0; PASM->report->error(".this outside class scope\n"); }
- } break;
-case 547:
-#line 1480 "asmparse.y"
-{ if(PASM->m_pCurClass != NULL) {
- yyval.token = PASM->m_pCurClass->m_crExtends;
- if(RidFromToken(yyval.token) == 0)
- PASM->report->error(".base undefined\n");
- } else { yyval.token = 0; PASM->report->error(".base outside class scope\n"); }
- } break;
-case 548:
-#line 1486 "asmparse.y"
-{ if(PASM->m_pCurClass != NULL) {
- if(PASM->m_pCurClass->m_pEncloser != NULL) yyval.token = PASM->m_pCurClass->m_pEncloser->m_cl;
- else { yyval.token = 0; PASM->report->error(".nester undefined\n"); }
- } else { yyval.token = 0; PASM->report->error(".nester outside class scope\n"); }
- } break;
-case 549:
-#line 1493 "asmparse.y"
-{ yyval.string = yypvt[-0].string; } break;
-case 550:
-#line 1494 "asmparse.y"
-{ yyval.string = newStringWDel(yypvt[-2].string, NESTING_SEP, yypvt[-0].string); } break;
-case 551:
-#line 1497 "asmparse.y"
-{ yyval.token = yypvt[-0].token;} break;
-case 552:
-#line 1498 "asmparse.y"
-{ yyval.token = PASM->GetAsmRef(yypvt[-1].string); delete[] yypvt[-1].string;} break;
-case 553:
-#line 1499 "asmparse.y"
-{ yyval.token = PASM->GetModRef(yypvt[-1].string); delete[] yypvt[-1].string;} break;
-case 554:
-#line 1500 "asmparse.y"
-{ yyval.token = PASM->ResolveTypeSpec(yypvt[-0].binstr); } break;
-case 555:
-#line 1504 "asmparse.y"
-{ yyval.binstr = new BinStr(); } break;
-case 556:
-#line 1506 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_CUSTOMMARSHALER);
- corEmitInt(yyval.binstr,yypvt[-7].binstr->length()); yyval.binstr->append(yypvt[-7].binstr);
- corEmitInt(yyval.binstr,yypvt[-5].binstr->length()); yyval.binstr->append(yypvt[-5].binstr);
- corEmitInt(yyval.binstr,yypvt[-3].binstr->length()); yyval.binstr->append(yypvt[-3].binstr);
- corEmitInt(yyval.binstr,yypvt[-1].binstr->length()); yyval.binstr->append(yypvt[-1].binstr);
- PASM->report->warn("Deprecated 4-string form of custom marshaler, first two strings ignored\n");} break;
-case 557:
-#line 1513 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_CUSTOMMARSHALER);
- corEmitInt(yyval.binstr,0);
- corEmitInt(yyval.binstr,0);
- corEmitInt(yyval.binstr,yypvt[-3].binstr->length()); yyval.binstr->append(yypvt[-3].binstr);
- corEmitInt(yyval.binstr,yypvt[-1].binstr->length()); yyval.binstr->append(yypvt[-1].binstr); } break;
-case 558:
-#line 1518 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_FIXEDSYSSTRING);
- corEmitInt(yyval.binstr,yypvt[-1].int32); } break;
-case 559:
-#line 1521 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_FIXEDARRAY);
- corEmitInt(yyval.binstr,yypvt[-2].int32); yyval.binstr->append(yypvt[-0].binstr); } break;
-case 560:
-#line 1523 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_VARIANT);
- PASM->report->warn("Deprecated native type 'variant'\n"); } break;
-case 561:
-#line 1525 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_CURRENCY); } break;
-case 562:
-#line 1526 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_SYSCHAR);
- PASM->report->warn("Deprecated native type 'syschar'\n"); } break;
-case 563:
-#line 1528 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_VOID);
- PASM->report->warn("Deprecated native type 'void'\n"); } break;
-case 564:
-#line 1530 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_BOOLEAN); } break;
-case 565:
-#line 1531 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_I1); } break;
-case 566:
-#line 1532 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_I2); } break;
-case 567:
-#line 1533 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_I4); } break;
-case 568:
-#line 1534 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_I8); } break;
-case 569:
-#line 1535 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_R4); } break;
-case 570:
-#line 1536 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_R8); } break;
-case 571:
-#line 1537 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_ERROR); } break;
-case 572:
-#line 1538 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_U1); } break;
-case 573:
-#line 1539 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_U2); } break;
-case 574:
-#line 1540 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_U4); } break;
-case 575:
-#line 1541 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_U8); } break;
-case 576:
-#line 1542 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_U1); } break;
-case 577:
-#line 1543 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_U2); } break;
-case 578:
-#line 1544 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_U4); } break;
-case 579:
-#line 1545 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_U8); } break;
-case 580:
-#line 1546 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt8(NATIVE_TYPE_PTR);
- PASM->report->warn("Deprecated native type '*'\n"); } break;
-case 581:
-#line 1548 "asmparse.y"
-{ yyval.binstr = yypvt[-2].binstr; if(yyval.binstr->length()==0) yyval.binstr->appendInt8(NATIVE_TYPE_MAX);
- yyval.binstr->insertInt8(NATIVE_TYPE_ARRAY); } break;
-case 582:
-#line 1550 "asmparse.y"
-{ yyval.binstr = yypvt[-3].binstr; if(yyval.binstr->length()==0) yyval.binstr->appendInt8(NATIVE_TYPE_MAX);
- yyval.binstr->insertInt8(NATIVE_TYPE_ARRAY);
- corEmitInt(yyval.binstr,0);
- corEmitInt(yyval.binstr,yypvt[-1].int32);
- corEmitInt(yyval.binstr,0); } break;
-case 583:
-#line 1555 "asmparse.y"
-{ yyval.binstr = yypvt[-5].binstr; if(yyval.binstr->length()==0) yyval.binstr->appendInt8(NATIVE_TYPE_MAX);
- yyval.binstr->insertInt8(NATIVE_TYPE_ARRAY);
- corEmitInt(yyval.binstr,yypvt[-1].int32);
- corEmitInt(yyval.binstr,yypvt[-3].int32);
- corEmitInt(yyval.binstr,ntaSizeParamIndexSpecified); } break;
-case 584:
-#line 1560 "asmparse.y"
-{ yyval.binstr = yypvt[-4].binstr; if(yyval.binstr->length()==0) yyval.binstr->appendInt8(NATIVE_TYPE_MAX);
- yyval.binstr->insertInt8(NATIVE_TYPE_ARRAY);
- corEmitInt(yyval.binstr,yypvt[-1].int32); } break;
-case 585:
-#line 1563 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_DECIMAL);
- PASM->report->warn("Deprecated native type 'decimal'\n"); } break;
-case 586:
-#line 1565 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_DATE);
- PASM->report->warn("Deprecated native type 'date'\n"); } break;
-case 587:
-#line 1567 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_BSTR); } break;
-case 588:
-#line 1568 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_LPSTR); } break;
-case 589:
-#line 1569 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_LPWSTR); } break;
-case 590:
-#line 1570 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_LPTSTR); } break;
-case 591:
-#line 1571 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_OBJECTREF);
- PASM->report->warn("Deprecated native type 'objectref'\n"); } break;
-case 592:
-#line 1573 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_IUNKNOWN);
- if(yypvt[-0].int32 != -1) corEmitInt(yyval.binstr,yypvt[-0].int32); } break;
-case 593:
-#line 1575 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_IDISPATCH);
- if(yypvt[-0].int32 != -1) corEmitInt(yyval.binstr,yypvt[-0].int32); } break;
-case 594:
-#line 1577 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_STRUCT); } break;
-case 595:
-#line 1578 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_INTF);
- if(yypvt[-0].int32 != -1) corEmitInt(yyval.binstr,yypvt[-0].int32); } break;
-case 596:
-#line 1580 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_SAFEARRAY);
- corEmitInt(yyval.binstr,yypvt[-0].int32);
- corEmitInt(yyval.binstr,0);} break;
-case 597:
-#line 1583 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_SAFEARRAY);
- corEmitInt(yyval.binstr,yypvt[-2].int32);
- corEmitInt(yyval.binstr,yypvt[-0].binstr->length()); yyval.binstr->append(yypvt[-0].binstr); } break;
-case 598:
-#line 1587 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_INT); } break;
-case 599:
-#line 1588 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_UINT); } break;
-case 600:
-#line 1589 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_UINT); } break;
-case 601:
-#line 1590 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_NESTEDSTRUCT);
- PASM->report->warn("Deprecated native type 'nested struct'\n"); } break;
-case 602:
-#line 1592 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_BYVALSTR); } break;
-case 603:
-#line 1593 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_ANSIBSTR); } break;
-case 604:
-#line 1594 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_TBSTR); } break;
-case 605:
-#line 1595 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_VARIANTBOOL); } break;
-case 606:
-#line 1596 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_FUNC); } break;
-case 607:
-#line 1597 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_ASANY); } break;
-case 608:
-#line 1598 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_LPSTRUCT); } break;
-case 609:
-#line 1599 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->append(yypvt[-0].tdd->m_pbsTypeSpec); } break;
-case 610:
-#line 1602 "asmparse.y"
-{ yyval.int32 = -1; } break;
-case 611:
-#line 1603 "asmparse.y"
-{ yyval.int32 = yypvt[-1].int32; } break;
-case 612:
-#line 1606 "asmparse.y"
-{ yyval.int32 = VT_EMPTY; } break;
-case 613:
-#line 1607 "asmparse.y"
-{ yyval.int32 = VT_NULL; } break;
-case 614:
-#line 1608 "asmparse.y"
-{ yyval.int32 = VT_VARIANT; } break;
-case 615:
-#line 1609 "asmparse.y"
-{ yyval.int32 = VT_CY; } break;
-case 616:
-#line 1610 "asmparse.y"
-{ yyval.int32 = VT_VOID; } break;
-case 617:
-#line 1611 "asmparse.y"
-{ yyval.int32 = VT_BOOL; } break;
-case 618:
-#line 1612 "asmparse.y"
-{ yyval.int32 = VT_I1; } break;
-case 619:
-#line 1613 "asmparse.y"
-{ yyval.int32 = VT_I2; } break;
-case 620:
-#line 1614 "asmparse.y"
-{ yyval.int32 = VT_I4; } break;
-case 621:
-#line 1615 "asmparse.y"
-{ yyval.int32 = VT_I8; } break;
-case 622:
-#line 1616 "asmparse.y"
-{ yyval.int32 = VT_R4; } break;
-case 623:
-#line 1617 "asmparse.y"
-{ yyval.int32 = VT_R8; } break;
-case 624:
-#line 1618 "asmparse.y"
-{ yyval.int32 = VT_UI1; } break;
-case 625:
-#line 1619 "asmparse.y"
-{ yyval.int32 = VT_UI2; } break;
-case 626:
-#line 1620 "asmparse.y"
-{ yyval.int32 = VT_UI4; } break;
-case 627:
-#line 1621 "asmparse.y"
-{ yyval.int32 = VT_UI8; } break;
-case 628:
-#line 1622 "asmparse.y"
-{ yyval.int32 = VT_UI1; } break;
-case 629:
-#line 1623 "asmparse.y"
-{ yyval.int32 = VT_UI2; } break;
-case 630:
-#line 1624 "asmparse.y"
-{ yyval.int32 = VT_UI4; } break;
-case 631:
-#line 1625 "asmparse.y"
-{ yyval.int32 = VT_UI8; } break;
-case 632:
-#line 1626 "asmparse.y"
-{ yyval.int32 = VT_PTR; } break;
-case 633:
-#line 1627 "asmparse.y"
-{ yyval.int32 = yypvt[-2].int32 | VT_ARRAY; } break;
-case 634:
-#line 1628 "asmparse.y"
-{ yyval.int32 = yypvt[-1].int32 | VT_VECTOR; } break;
-case 635:
-#line 1629 "asmparse.y"
-{ yyval.int32 = yypvt[-1].int32 | VT_BYREF; } break;
-case 636:
-#line 1630 "asmparse.y"
-{ yyval.int32 = VT_DECIMAL; } break;
-case 637:
-#line 1631 "asmparse.y"
-{ yyval.int32 = VT_DATE; } break;
-case 638:
-#line 1632 "asmparse.y"
-{ yyval.int32 = VT_BSTR; } break;
-case 639:
-#line 1633 "asmparse.y"
-{ yyval.int32 = VT_LPSTR; } break;
-case 640:
-#line 1634 "asmparse.y"
-{ yyval.int32 = VT_LPWSTR; } break;
-case 641:
-#line 1635 "asmparse.y"
-{ yyval.int32 = VT_UNKNOWN; } break;
-case 642:
-#line 1636 "asmparse.y"
-{ yyval.int32 = VT_DISPATCH; } break;
-case 643:
-#line 1637 "asmparse.y"
-{ yyval.int32 = VT_SAFEARRAY; } break;
-case 644:
-#line 1638 "asmparse.y"
-{ yyval.int32 = VT_INT; } break;
-case 645:
-#line 1639 "asmparse.y"
-{ yyval.int32 = VT_UINT; } break;
-case 646:
-#line 1640 "asmparse.y"
-{ yyval.int32 = VT_UINT; } break;
-case 647:
-#line 1641 "asmparse.y"
-{ yyval.int32 = VT_ERROR; } break;
-case 648:
-#line 1642 "asmparse.y"
-{ yyval.int32 = VT_HRESULT; } break;
-case 649:
-#line 1643 "asmparse.y"
-{ yyval.int32 = VT_CARRAY; } break;
-case 650:
-#line 1644 "asmparse.y"
-{ yyval.int32 = VT_USERDEFINED; } break;
-case 651:
-#line 1645 "asmparse.y"
-{ yyval.int32 = VT_RECORD; } break;
-case 652:
-#line 1646 "asmparse.y"
-{ yyval.int32 = VT_FILETIME; } break;
-case 653:
-#line 1647 "asmparse.y"
-{ yyval.int32 = VT_BLOB; } break;
-case 654:
-#line 1648 "asmparse.y"
-{ yyval.int32 = VT_STREAM; } break;
-case 655:
-#line 1649 "asmparse.y"
-{ yyval.int32 = VT_STORAGE; } break;
-case 656:
-#line 1650 "asmparse.y"
-{ yyval.int32 = VT_STREAMED_OBJECT; } break;
-case 657:
-#line 1651 "asmparse.y"
-{ yyval.int32 = VT_STORED_OBJECT; } break;
-case 658:
-#line 1652 "asmparse.y"
-{ yyval.int32 = VT_BLOB_OBJECT; } break;
-case 659:
-#line 1653 "asmparse.y"
-{ yyval.int32 = VT_CF; } break;
-case 660:
-#line 1654 "asmparse.y"
-{ yyval.int32 = VT_CLSID; } break;
-case 661:
-#line 1658 "asmparse.y"
-{ if(yypvt[-0].token == PASM->m_tkSysString)
- { yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_STRING); }
- else if(yypvt[-0].token == PASM->m_tkSysObject)
- { yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_OBJECT); }
- else
- yyval.binstr = parser->MakeTypeClass(ELEMENT_TYPE_CLASS, yypvt[-0].token); } break;
-case 662:
-#line 1664 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_OBJECT); } break;
-case 663:
-#line 1665 "asmparse.y"
-{ yyval.binstr = parser->MakeTypeClass(ELEMENT_TYPE_VALUETYPE, yypvt[-0].token); } break;
-case 664:
-#line 1666 "asmparse.y"
-{ yyval.binstr = parser->MakeTypeClass(ELEMENT_TYPE_VALUETYPE, yypvt[-0].token); } break;
-case 665:
-#line 1667 "asmparse.y"
-{ yyval.binstr = yypvt[-2].binstr; yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
-case 666:
-#line 1668 "asmparse.y"
-{ yyval.binstr = parser->MakeTypeArray(ELEMENT_TYPE_ARRAY, yypvt[-3].binstr, yypvt[-1].binstr); } break;
-case 667:
-#line 1669 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt8(ELEMENT_TYPE_BYREF); } break;
-case 668:
-#line 1670 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt8(ELEMENT_TYPE_PTR); } break;
-case 669:
-#line 1671 "asmparse.y"
-{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt8(ELEMENT_TYPE_PINNED); } break;
-case 670:
-#line 1672 "asmparse.y"
-{ yyval.binstr = parser->MakeTypeClass(ELEMENT_TYPE_CMOD_REQD, yypvt[-1].token);
- yyval.binstr->append(yypvt[-4].binstr); } break;
-case 671:
-#line 1674 "asmparse.y"
-{ yyval.binstr = parser->MakeTypeClass(ELEMENT_TYPE_CMOD_OPT, yypvt[-1].token);
- yyval.binstr->append(yypvt[-4].binstr); } break;
-case 672:
-#line 1677 "asmparse.y"
-{ yyval.binstr = parser->MakeSig(yypvt[-5].int32, yypvt[-4].binstr, yypvt[-1].binstr);
- yyval.binstr->insertInt8(ELEMENT_TYPE_FNPTR);
- PASM->delArgNameList(PASM->m_firstArgName);
- PASM->m_firstArgName = parser->m_ANSFirst.POP();
- PASM->m_lastArgName = parser->m_ANSLast.POP();
- } break;
-case 673:
-#line 1683 "asmparse.y"
-{ if(yypvt[-1].binstr == NULL) yyval.binstr = yypvt[-3].binstr;
- else {
- yyval.binstr = new BinStr();
- yyval.binstr->appendInt8(ELEMENT_TYPE_GENERICINST);
- yyval.binstr->append(yypvt[-3].binstr);
- corEmitInt(yyval.binstr, corCountArgs(yypvt[-1].binstr));
- yyval.binstr->append(yypvt[-1].binstr); delete yypvt[-3].binstr; delete yypvt[-1].binstr; }} break;
-case 674:
-#line 1690 "asmparse.y"
-{ //if(PASM->m_pCurMethod) {
- // if(($3 < 0)||((DWORD)$3 >= PASM->m_pCurMethod->m_NumTyPars))
- // PASM->report->error("Invalid method type parameter '%d'\n",$3);
- yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_MVAR); corEmitInt(yyval.binstr, yypvt[-0].int32);
- //} else PASM->report->error("Method type parameter '%d' outside method scope\n",$3);
- } break;
-case 675:
-#line 1696 "asmparse.y"
-{ //if(PASM->m_pCurClass) {
- // if(($2 < 0)||((DWORD)$2 >= PASM->m_pCurClass->m_NumTyPars))
- // PASM->report->error("Invalid type parameter '%d'\n",$2);
- yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_VAR); corEmitInt(yyval.binstr, yypvt[-0].int32);
- //} else PASM->report->error("Type parameter '%d' outside class scope\n",$2);
- } break;
-case 676:
-#line 1702 "asmparse.y"
-{ int eltype = ELEMENT_TYPE_MVAR;
- int n=-1;
- if(PASM->m_pCurMethod) n = PASM->m_pCurMethod->FindTyPar(yypvt[-0].string);
- else {
- if(PASM->m_TyParList) n = PASM->m_TyParList->IndexOf(yypvt[-0].string);
- if(n == -1)
- { n = TyParFixupList.COUNT();
- TyParFixupList.PUSH(yypvt[-0].string);
- eltype = ELEMENT_TYPE_MVARFIXUP;
- }
- }
- if(n == -1) { PASM->report->error("Invalid method type parameter '%s'\n",yypvt[-0].string);
- n = 0x1FFFFFFF; }
- yyval.binstr = new BinStr(); yyval.binstr->appendInt8(eltype); corEmitInt(yyval.binstr,n);
- } break;
-case 677:
-#line 1717 "asmparse.y"
-{ int eltype = ELEMENT_TYPE_VAR;
- int n=-1;
- if(PASM->m_pCurClass && !newclass) n = PASM->m_pCurClass->FindTyPar(yypvt[-0].string);
- else {
- if(PASM->m_TyParList) n = PASM->m_TyParList->IndexOf(yypvt[-0].string);
- if(n == -1)
- { n = TyParFixupList.COUNT();
- TyParFixupList.PUSH(yypvt[-0].string);
- eltype = ELEMENT_TYPE_VARFIXUP;
- }
- }
- if(n == -1) { PASM->report->error("Invalid type parameter '%s'\n",yypvt[-0].string);
- n = 0x1FFFFFFF; }
- yyval.binstr = new BinStr(); yyval.binstr->appendInt8(eltype); corEmitInt(yyval.binstr,n);
- } break;
-case 678:
-#line 1732 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_TYPEDBYREF); } break;
-case 679:
-#line 1733 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_VOID); } break;
-case 680:
-#line 1734 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I); } break;
-case 681:
-#line 1735 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U); } break;
-case 682:
-#line 1736 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U); } break;
-case 683:
-#line 1737 "asmparse.y"
-{ yyval.binstr = yypvt[-0].binstr; } break;
-case 684:
-#line 1738 "asmparse.y"
-{ yyval.binstr = yypvt[-0].binstr; yyval.binstr->insertInt8(ELEMENT_TYPE_SENTINEL); } break;
-case 685:
-#line 1741 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_CHAR); } break;
-case 686:
-#line 1742 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_STRING); } break;
-case 687:
-#line 1743 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_BOOLEAN); } break;
-case 688:
-#line 1744 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I1); } break;
-case 689:
-#line 1745 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I2); } break;
-case 690:
-#line 1746 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I4); } break;
-case 691:
-#line 1747 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I8); } break;
-case 692:
-#line 1748 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_R4); } break;
-case 693:
-#line 1749 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_R8); } break;
-case 694:
-#line 1750 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U1); } break;
-case 695:
-#line 1751 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U2); } break;
-case 696:
-#line 1752 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U4); } break;
-case 697:
-#line 1753 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U8); } break;
-case 698:
-#line 1754 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U1); } break;
-case 699:
-#line 1755 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U2); } break;
-case 700:
-#line 1756 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U4); } break;
-case 701:
-#line 1757 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U8); } break;
-case 702:
-#line 1758 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->append(yypvt[-0].tdd->m_pbsTypeSpec); } break;
-case 703:
-#line 1761 "asmparse.y"
-{ yyval.binstr = yypvt[-0].binstr; } break;
-case 704:
-#line 1762 "asmparse.y"
-{ yyval.binstr = yypvt[-2].binstr; yypvt[-2].binstr->append(yypvt[-0].binstr); delete yypvt[-0].binstr; } break;
-case 705:
-#line 1765 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt32(0x7FFFFFFF); yyval.binstr->appendInt32(0x7FFFFFFF); } break;
-case 706:
-#line 1766 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt32(0x7FFFFFFF); yyval.binstr->appendInt32(0x7FFFFFFF); } break;
-case 707:
-#line 1767 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt32(0); yyval.binstr->appendInt32(yypvt[-0].int32); } break;
-case 708:
-#line 1768 "asmparse.y"
-{ FAIL_UNLESS(yypvt[-2].int32 <= yypvt[-0].int32, ("lower bound %d must be <= upper bound %d\n", yypvt[-2].int32, yypvt[-0].int32));
- if (yypvt[-2].int32 > yypvt[-0].int32) { YYERROR; };
- yyval.binstr = new BinStr(); yyval.binstr->appendInt32(yypvt[-2].int32); yyval.binstr->appendInt32(yypvt[-0].int32-yypvt[-2].int32+1); } break;
-case 709:
-#line 1771 "asmparse.y"
-{ yyval.binstr = new BinStr(); yyval.binstr->appendInt32(yypvt[-1].int32); yyval.binstr->appendInt32(0x7FFFFFFF); } break;
-case 710:
-#line 1776 "asmparse.y"
-{ PASM->AddPermissionDecl(yypvt[-4].secAct, yypvt[-3].token, yypvt[-1].pair); } break;
-case 711:
-#line 1778 "asmparse.y"
-{ PASM->AddPermissionDecl(yypvt[-5].secAct, yypvt[-4].token, yypvt[-1].binstr); } break;
-case 712:
-#line 1779 "asmparse.y"
-{ PASM->AddPermissionDecl(yypvt[-1].secAct, yypvt[-0].token, (NVPair *)NULL); } break;
-case 713:
-#line 1780 "asmparse.y"
-{ PASM->AddPermissionSetDecl(yypvt[-2].secAct, yypvt[-1].binstr); } break;
-case 714:
-#line 1782 "asmparse.y"
-{ PASM->AddPermissionSetDecl(yypvt[-1].secAct,BinStrToUnicode(yypvt[-0].binstr,true));} break;
-case 715:
-#line 1784 "asmparse.y"
-{ BinStr* ret = new BinStr();
- ret->insertInt8('.');
- corEmitInt(ret, nSecAttrBlobs);
- ret->append(yypvt[-1].binstr);
- PASM->AddPermissionSetDecl(yypvt[-4].secAct,ret);
- nSecAttrBlobs = 0; } break;
-case 716:
-#line 1792 "asmparse.y"
-{ yyval.binstr = new BinStr(); nSecAttrBlobs = 0;} break;
-case 717:
-#line 1793 "asmparse.y"
-{ yyval.binstr = yypvt[-0].binstr; nSecAttrBlobs = 1; } break;
-case 718:
-#line 1794 "asmparse.y"
-{ yyval.binstr = yypvt[-2].binstr; yyval.binstr->append(yypvt[-0].binstr); nSecAttrBlobs++; } break;
-case 719:
-#line 1798 "asmparse.y"
-{ yyval.binstr = PASM->EncodeSecAttr(PASM->ReflectionNotation(yypvt[-4].token),yypvt[-1].binstr,nCustomBlobNVPairs);
- nCustomBlobNVPairs = 0; } break;
-case 720:
-#line 1801 "asmparse.y"
-{ yyval.binstr = PASM->EncodeSecAttr(yypvt[-4].string,yypvt[-1].binstr,nCustomBlobNVPairs);
- nCustomBlobNVPairs = 0; } break;
-case 721:
-#line 1805 "asmparse.y"
-{ yyval.secAct = yypvt[-2].secAct; bParsingByteArray = TRUE; } break;
-case 722:
-#line 1807 "asmparse.y"
-{ yyval.secAct = yypvt[-2].secAct; bParsingByteArray = TRUE; } break;
-case 723:
-#line 1810 "asmparse.y"
-{ yyval.pair = yypvt[-0].pair; } break;
-case 724:
-#line 1811 "asmparse.y"
-{ yyval.pair = yypvt[-2].pair->Concat(yypvt[-0].pair); } break;
-case 725:
-#line 1814 "asmparse.y"
-{ yypvt[-2].binstr->appendInt8(0); yyval.pair = new NVPair(yypvt[-2].binstr, yypvt[-0].binstr); } break;
-case 726:
-#line 1817 "asmparse.y"
-{ yyval.int32 = 1; } break;
-case 727:
-#line 1818 "asmparse.y"
-{ yyval.int32 = 0; } break;
-case 728:
-#line 1821 "asmparse.y"
-{ yyval.binstr = new BinStr();
- yyval.binstr->appendInt8(SERIALIZATION_TYPE_BOOLEAN);
- yyval.binstr->appendInt8(yypvt[-0].int32); } break;
-case 729:
-#line 1824 "asmparse.y"
-{ yyval.binstr = new BinStr();
- yyval.binstr->appendInt8(SERIALIZATION_TYPE_I4);
- yyval.binstr->appendInt32(yypvt[-0].int32); } break;
-case 730:
-#line 1827 "asmparse.y"
-{ yyval.binstr = new BinStr();
- yyval.binstr->appendInt8(SERIALIZATION_TYPE_I4);
- yyval.binstr->appendInt32(yypvt[-1].int32); } break;
-case 731:
-#line 1830 "asmparse.y"
-{ yyval.binstr = new BinStr();
- yyval.binstr->appendInt8(SERIALIZATION_TYPE_STRING);
- yyval.binstr->append(yypvt[-0].binstr); delete yypvt[-0].binstr;
- yyval.binstr->appendInt8(0); } break;
-case 732:
-#line 1834 "asmparse.y"
-{ yyval.binstr = new BinStr();
- yyval.binstr->appendInt8(SERIALIZATION_TYPE_ENUM);
- char* sz = PASM->ReflectionNotation(yypvt[-5].token);
- strcpy_s((char *)yyval.binstr->getBuff((unsigned)strlen(sz) + 1), strlen(sz) + 1,sz);
- yyval.binstr->appendInt8(1);
- yyval.binstr->appendInt32(yypvt[-1].int32); } break;
-case 733:
-#line 1840 "asmparse.y"
-{ yyval.binstr = new BinStr();
- yyval.binstr->appendInt8(SERIALIZATION_TYPE_ENUM);
- char* sz = PASM->ReflectionNotation(yypvt[-5].token);
- strcpy_s((char *)yyval.binstr->getBuff((unsigned)strlen(sz) + 1), strlen(sz) + 1,sz);
- yyval.binstr->appendInt8(2);
- yyval.binstr->appendInt32(yypvt[-1].int32); } break;
-case 734:
-#line 1846 "asmparse.y"
-{ yyval.binstr = new BinStr();
- yyval.binstr->appendInt8(SERIALIZATION_TYPE_ENUM);
- char* sz = PASM->ReflectionNotation(yypvt[-5].token);
- strcpy_s((char *)yyval.binstr->getBuff((unsigned)strlen(sz) + 1), strlen(sz) + 1,sz);
- yyval.binstr->appendInt8(4);
- yyval.binstr->appendInt32(yypvt[-1].int32); } break;
-case 735:
-#line 1852 "asmparse.y"
-{ yyval.binstr = new BinStr();
- yyval.binstr->appendInt8(SERIALIZATION_TYPE_ENUM);
- char* sz = PASM->ReflectionNotation(yypvt[-3].token);
- strcpy_s((char *)yyval.binstr->getBuff((unsigned)strlen(sz) + 1), strlen(sz) + 1,sz);
- yyval.binstr->appendInt8(4);
- yyval.binstr->appendInt32(yypvt[-1].int32); } break;
-case 736:
-#line 1860 "asmparse.y"
-{ yyval.secAct = dclRequest; } break;
-case 737:
-#line 1861 "asmparse.y"
-{ yyval.secAct = dclDemand; } break;
-case 738:
-#line 1862 "asmparse.y"
-{ yyval.secAct = dclAssert; } break;
-case 739:
-#line 1863 "asmparse.y"
-{ yyval.secAct = dclDeny; } break;
-case 740:
-#line 1864 "asmparse.y"
-{ yyval.secAct = dclPermitOnly; } break;
-case 741:
-#line 1865 "asmparse.y"
-{ yyval.secAct = dclLinktimeCheck; } break;
-case 742:
-#line 1866 "asmparse.y"
-{ yyval.secAct = dclInheritanceCheck; } break;
-case 743:
-#line 1867 "asmparse.y"
-{ yyval.secAct = dclRequestMinimum; } break;
-case 744:
-#line 1868 "asmparse.y"
-{ yyval.secAct = dclRequestOptional; } break;
-case 745:
-#line 1869 "asmparse.y"
-{ yyval.secAct = dclRequestRefuse; } break;
-case 746:
-#line 1870 "asmparse.y"
-{ yyval.secAct = dclPrejitGrant; } break;
-case 747:
-#line 1871 "asmparse.y"
-{ yyval.secAct = dclPrejitDenied; } break;
-case 748:
-#line 1872 "asmparse.y"
-{ yyval.secAct = dclNonCasDemand; } break;
-case 749:
-#line 1873 "asmparse.y"
-{ yyval.secAct = dclNonCasLinkDemand; } break;
-case 750:
-#line 1874 "asmparse.y"
-{ yyval.secAct = dclNonCasInheritance; } break;
-case 751:
-#line 1878 "asmparse.y"
-{ PASM->ResetLineNumbers(); nCurrPC = PASM->m_CurPC; PENV->bExternSource = TRUE; PENV->bExternSourceAutoincrement = FALSE; } break;
-case 752:
-#line 1879 "asmparse.y"
-{ PASM->ResetLineNumbers(); nCurrPC = PASM->m_CurPC; PENV->bExternSource = TRUE; PENV->bExternSourceAutoincrement = TRUE; } break;
-case 753:
-#line 1882 "asmparse.y"
-{ PENV->nExtLine = PENV->nExtLineEnd = yypvt[-1].int32;
- PENV->nExtCol = 0; PENV->nExtColEnd = static_cast<unsigned>(-1);
- PASM->SetSourceFileName(yypvt[-0].string);} break;
-case 754:
-#line 1885 "asmparse.y"
-{ PENV->nExtLine = PENV->nExtLineEnd = yypvt[-0].int32;
- PENV->nExtCol = 0; PENV->nExtColEnd = static_cast<unsigned>(-1); } break;
-case 755:
-#line 1887 "asmparse.y"
-{ PENV->nExtLine = PENV->nExtLineEnd = yypvt[-3].int32;
- PENV->nExtCol=yypvt[-1].int32; PENV->nExtColEnd = static_cast<unsigned>(-1);
- PASM->SetSourceFileName(yypvt[-0].string);} break;
-case 756:
-#line 1890 "asmparse.y"
-{ PENV->nExtLine = PENV->nExtLineEnd = yypvt[-2].int32;
- PENV->nExtCol=yypvt[-0].int32; PENV->nExtColEnd = static_cast<unsigned>(-1);} break;
-case 757:
-#line 1893 "asmparse.y"
-{ PENV->nExtLine = PENV->nExtLineEnd = yypvt[-5].int32;
- PENV->nExtCol=yypvt[-3].int32; PENV->nExtColEnd = yypvt[-1].int32;
- PASM->SetSourceFileName(yypvt[-0].string);} break;
-case 758:
-#line 1897 "asmparse.y"
-{ PENV->nExtLine = PENV->nExtLineEnd = yypvt[-4].int32;
- PENV->nExtCol=yypvt[-2].int32; PENV->nExtColEnd = yypvt[-0].int32; } break;
-case 759:
-#line 1900 "asmparse.y"
-{ PENV->nExtLine = yypvt[-5].int32; PENV->nExtLineEnd = yypvt[-3].int32;
- PENV->nExtCol=yypvt[-1].int32; PENV->nExtColEnd = static_cast<unsigned>(-1);
- PASM->SetSourceFileName(yypvt[-0].string);} break;
-case 760:
-#line 1904 "asmparse.y"
-{ PENV->nExtLine = yypvt[-4].int32; PENV->nExtLineEnd = yypvt[-2].int32;
- PENV->nExtCol=yypvt[-0].int32; PENV->nExtColEnd = static_cast<unsigned>(-1); } break;
-case 761:
-#line 1907 "asmparse.y"
-{ PENV->nExtLine = yypvt[-7].int32; PENV->nExtLineEnd = yypvt[-5].int32;
- PENV->nExtCol=yypvt[-3].int32; PENV->nExtColEnd = yypvt[-1].int32;
- PASM->SetSourceFileName(yypvt[-0].string);} break;
-case 762:
-#line 1911 "asmparse.y"
-{ PENV->nExtLine = yypvt[-6].int32; PENV->nExtLineEnd = yypvt[-4].int32;
- PENV->nExtCol=yypvt[-2].int32; PENV->nExtColEnd = yypvt[-0].int32; } break;
-case 763:
-#line 1913 "asmparse.y"
-{ PENV->nExtLine = PENV->nExtLineEnd = yypvt[-1].int32 - 1;
- PENV->nExtCol = 0; PENV->nExtColEnd = static_cast<unsigned>(-1);
- PASM->SetSourceFileName(yypvt[-0].binstr);} break;
-case 764:
-#line 1920 "asmparse.y"
-{ PASMM->AddFile(yypvt[-5].string, yypvt[-6].fileAttr|yypvt[-4].fileAttr|yypvt[-0].fileAttr, yypvt[-2].binstr); } break;
-case 765:
-#line 1921 "asmparse.y"
-{ PASMM->AddFile(yypvt[-1].string, yypvt[-2].fileAttr|yypvt[-0].fileAttr, NULL); } break;
-case 766:
-#line 1924 "asmparse.y"
-{ yyval.fileAttr = (CorFileFlags) 0; } break;
-case 767:
-#line 1925 "asmparse.y"
-{ yyval.fileAttr = (CorFileFlags) (yypvt[-1].fileAttr | ffContainsNoMetaData); } break;
-case 768:
-#line 1928 "asmparse.y"
-{ yyval.fileAttr = (CorFileFlags) 0; } break;
-case 769:
-#line 1929 "asmparse.y"
-{ yyval.fileAttr = (CorFileFlags) 0x80000000; } break;
-case 770:
-#line 1932 "asmparse.y"
-{ bParsingByteArray = TRUE; } break;
-case 771:
-#line 1935 "asmparse.y"
-{ PASMM->StartAssembly(yypvt[-0].string, NULL, (DWORD)yypvt[-1].asmAttr, FALSE); } break;
-case 772:
-#line 1938 "asmparse.y"
-{ yyval.asmAttr = (CorAssemblyFlags) 0; } break;
-case 773:
-#line 1939 "asmparse.y"
-{ yyval.asmAttr = (CorAssemblyFlags) (yypvt[-1].asmAttr | afRetargetable); } break;
-case 774:
-#line 1940 "asmparse.y"
-{ yyval.asmAttr = (CorAssemblyFlags) (yypvt[-1].asmAttr | afContentType_WindowsRuntime); } break;
-case 775:
-#line 1941 "asmparse.y"
-{ yyval.asmAttr = (CorAssemblyFlags) (yypvt[-1].asmAttr | afPA_NoPlatform); } break;
-case 776:
-#line 1942 "asmparse.y"
-{ yyval.asmAttr = yypvt[-2].asmAttr; } break;
-case 777:
-#line 1943 "asmparse.y"
-{ SET_PA(yyval.asmAttr,yypvt[-1].asmAttr,afPA_MSIL); } break;
-case 778:
-#line 1944 "asmparse.y"
-{ SET_PA(yyval.asmAttr,yypvt[-1].asmAttr,afPA_x86); } break;
-case 779:
-#line 1945 "asmparse.y"
-{ SET_PA(yyval.asmAttr,yypvt[-1].asmAttr,afPA_IA64); } break;
-case 780:
-#line 1946 "asmparse.y"
-{ SET_PA(yyval.asmAttr,yypvt[-1].asmAttr,afPA_AMD64); } break;
-case 781:
-#line 1947 "asmparse.y"
-{ SET_PA(yyval.asmAttr,yypvt[-1].asmAttr,afPA_ARM); } break;
-case 784:
-#line 1954 "asmparse.y"
-{ PASMM->SetAssemblyHashAlg(yypvt[-0].int32); } break;
-case 787:
-#line 1959 "asmparse.y"
-{ yyval.int32 = yypvt[-0].int32; } break;
-case 788:
-#line 1960 "asmparse.y"
-{ yyval.int32 = 0xFFFF; } break;
-case 789:
-#line 1963 "asmparse.y"
-{ PASMM->SetAssemblyPublicKey(yypvt[-1].binstr); } break;
-case 790:
-#line 1965 "asmparse.y"
-{ PASMM->SetAssemblyVer((USHORT)yypvt[-6].int32, (USHORT)yypvt[-4].int32, (USHORT)yypvt[-2].int32, (USHORT)yypvt[-0].int32); } break;
-case 791:
-#line 1966 "asmparse.y"
-{ yypvt[-0].binstr->appendInt8(0); PASMM->SetAssemblyLocale(yypvt[-0].binstr,TRUE); } break;
-case 792:
-#line 1967 "asmparse.y"
-{ PASMM->SetAssemblyLocale(yypvt[-1].binstr,FALSE); } break;
-case 795:
-#line 1972 "asmparse.y"
-{ bParsingByteArray = TRUE; } break;
-case 796:
-#line 1975 "asmparse.y"
-{ bParsingByteArray = TRUE; } break;
-case 797:
-#line 1978 "asmparse.y"
-{ bParsingByteArray = TRUE; } break;
-case 798:
-#line 1982 "asmparse.y"
-{ PASMM->StartAssembly(yypvt[-0].string, NULL, yypvt[-1].asmAttr, TRUE); } break;
-case 799:
-#line 1984 "asmparse.y"
-{ PASMM->StartAssembly(yypvt[-2].string, yypvt[-0].string, yypvt[-3].asmAttr, TRUE); } break;
-case 802:
-#line 1991 "asmparse.y"
-{ PASMM->SetAssemblyHashBlob(yypvt[-1].binstr); } break;
-case 804:
-#line 1993 "asmparse.y"
-{ PASMM->SetAssemblyPublicKeyToken(yypvt[-1].binstr); } break;
-case 805:
-#line 1994 "asmparse.y"
-{ PASMM->SetAssemblyAutodetect(); } break;
-case 806:
-#line 1997 "asmparse.y"
-{ PASMM->StartComType(yypvt[-0].string, yypvt[-1].exptAttr);} break;
-case 807:
-#line 2000 "asmparse.y"
-{ PASMM->StartComType(yypvt[-0].string, yypvt[-1].exptAttr); } break;
-case 808:
-#line 2003 "asmparse.y"
-{ yyval.exptAttr = (CorTypeAttr) 0; } break;
-case 809:
-#line 2004 "asmparse.y"
-{ yyval.exptAttr = (CorTypeAttr) (yypvt[-1].exptAttr | tdNotPublic); } break;
-case 810:
-#line 2005 "asmparse.y"
-{ yyval.exptAttr = (CorTypeAttr) (yypvt[-1].exptAttr | tdPublic); } break;
-case 811:
-#line 2006 "asmparse.y"
-{ yyval.exptAttr = (CorTypeAttr) (yypvt[-1].exptAttr | tdForwarder); } break;
-case 812:
-#line 2007 "asmparse.y"
-{ yyval.exptAttr = (CorTypeAttr) (yypvt[-2].exptAttr | tdNestedPublic); } break;
-case 813:
-#line 2008 "asmparse.y"
-{ yyval.exptAttr = (CorTypeAttr) (yypvt[-2].exptAttr | tdNestedPrivate); } break;
-case 814:
-#line 2009 "asmparse.y"
-{ yyval.exptAttr = (CorTypeAttr) (yypvt[-2].exptAttr | tdNestedFamily); } break;
-case 815:
-#line 2010 "asmparse.y"
-{ yyval.exptAttr = (CorTypeAttr) (yypvt[-2].exptAttr | tdNestedAssembly); } break;
-case 816:
-#line 2011 "asmparse.y"
-{ yyval.exptAttr = (CorTypeAttr) (yypvt[-2].exptAttr | tdNestedFamANDAssem); } break;
-case 817:
-#line 2012 "asmparse.y"
-{ yyval.exptAttr = (CorTypeAttr) (yypvt[-2].exptAttr | tdNestedFamORAssem); } break;
-case 820:
-#line 2019 "asmparse.y"
-{ PASMM->SetComTypeFile(yypvt[-0].string); } break;
-case 821:
-#line 2020 "asmparse.y"
-{ PASMM->SetComTypeComType(yypvt[-0].string); } break;
-case 822:
-#line 2021 "asmparse.y"
-{ PASMM->SetComTypeAsmRef(yypvt[-0].string); } break;
-case 823:
-#line 2022 "asmparse.y"
-{ if(!PASMM->SetComTypeImplementationTok(yypvt[-1].int32))
- PASM->report->error("Invalid implementation of exported type\n"); } break;
-case 824:
-#line 2024 "asmparse.y"
-{ if(!PASMM->SetComTypeClassTok(yypvt[-0].int32))
- PASM->report->error("Invalid TypeDefID of exported type\n"); } break;
-case 827:
-#line 2030 "asmparse.y"
-{ PASMM->StartManifestRes(yypvt[-0].string, yypvt[-0].string, yypvt[-1].manresAttr); } break;
-case 828:
-#line 2032 "asmparse.y"
-{ PASMM->StartManifestRes(yypvt[-2].string, yypvt[-0].string, yypvt[-3].manresAttr); } break;
-case 829:
-#line 2035 "asmparse.y"
-{ yyval.manresAttr = (CorManifestResourceFlags) 0; } break;
-case 830:
-#line 2036 "asmparse.y"
-{ yyval.manresAttr = (CorManifestResourceFlags) (yypvt[-1].manresAttr | mrPublic); } break;
-case 831:
-#line 2037 "asmparse.y"
-{ yyval.manresAttr = (CorManifestResourceFlags) (yypvt[-1].manresAttr | mrPrivate); } break;
-case 834:
-#line 2044 "asmparse.y"
-{ PASMM->SetManifestResFile(yypvt[-2].string, (ULONG)yypvt[-0].int32); } break;
-case 835:
-#line 2045 "asmparse.y"
-{ PASMM->SetManifestResAsmRef(yypvt[-0].string); } break;/* End of actions */
-#line 329 "D:\\ProjectK3\\src\\tools\\devdiv\\x86\\yypars.c"
- }
- }
- goto yystack; /* stack new state and value */
- }
-#pragma warning(default:102)
-
-
-#ifdef YYDUMP
-YYLOCAL void YYNEAR YYPASCAL yydumpinfo(void)
-{
- short stackindex;
- short valindex;
-
- //dump yys
- printf("short yys[%d] {\n", YYMAXDEPTH);
- for (stackindex = 0; stackindex < YYMAXDEPTH; stackindex++){
- if (stackindex)
- printf(", %s", stackindex % 10 ? "\0" : "\n");
- printf("%6d", yys[stackindex]);
- }
- printf("\n};\n");
-
- //dump yyv
- printf("YYSTYPE yyv[%d] {\n", YYMAXDEPTH);
- for (valindex = 0; valindex < YYMAXDEPTH; valindex++){
- if (valindex)
- printf(", %s", valindex % 5 ? "\0" : "\n");
- printf("%#*x", 3+sizeof(YYSTYPE), yyv[valindex]);
- }
- printf("\n};\n");
- }
-#endif
diff --git a/src/ilasm/prebuilt/asmparse.cpp b/src/ilasm/prebuilt/asmparse.cpp
new file mode 100644
index 0000000000..50c62030ff
--- /dev/null
+++ b/src/ilasm/prebuilt/asmparse.cpp
@@ -0,0 +1,4907 @@
+/*
+ * Created by Microsoft VCBU Internal YACC from "asmparse.y"
+ */
+
+#line 2 "asmparse.y"
+
+ // Licensed to the .NET Foundation under one or more 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 asmparse.y
+//
+#include "ilasmpch.h"
+
+#include "grammar_before.cpp"
+
+
+#line 16 "asmparse.y"
+
+#define UNION 1
+typedef union {
+ CorRegTypeAttr classAttr;
+ CorMethodAttr methAttr;
+ CorFieldAttr fieldAttr;
+ CorMethodImpl implAttr;
+ CorEventAttr eventAttr;
+ CorPropertyAttr propAttr;
+ CorPinvokeMap pinvAttr;
+ CorDeclSecurity secAct;
+ CorFileFlags fileAttr;
+ CorAssemblyFlags asmAttr;
+ CorAssemblyFlags asmRefAttr;
+ CorTypeAttr exptAttr;
+ CorManifestResourceFlags manresAttr;
+ double* float64;
+ __int64* int64;
+ __int32 int32;
+ char* string;
+ BinStr* binstr;
+ Labels* labels;
+ Instr* instr; // instruction opcode
+ NVPair* pair;
+ pTyParList typarlist;
+ mdToken token;
+ TypeDefDescr* tdd;
+ CustomDescr* cad;
+ unsigned short opcode;
+} YYSTYPE;
+# define ERROR_ 257
+# define BAD_COMMENT_ 258
+# define BAD_LITERAL_ 259
+# define ID 260
+# define DOTTEDNAME 261
+# define QSTRING 262
+# define SQSTRING 263
+# define INT32 264
+# define INT64 265
+# define FLOAT64 266
+# define HEXBYTE 267
+# define TYPEDEF_T 268
+# define TYPEDEF_M 269
+# define TYPEDEF_F 270
+# define TYPEDEF_TS 271
+# define TYPEDEF_MR 272
+# define TYPEDEF_CA 273
+# define DCOLON 274
+# define ELIPSIS 275
+# define VOID_ 276
+# define BOOL_ 277
+# define CHAR_ 278
+# define UNSIGNED_ 279
+# define INT_ 280
+# define INT8_ 281
+# define INT16_ 282
+# define INT32_ 283
+# define INT64_ 284
+# define FLOAT_ 285
+# define FLOAT32_ 286
+# define FLOAT64_ 287
+# define BYTEARRAY_ 288
+# define UINT_ 289
+# define UINT8_ 290
+# define UINT16_ 291
+# define UINT32_ 292
+# define UINT64_ 293
+# define FLAGS_ 294
+# define CALLCONV_ 295
+# define MDTOKEN_ 296
+# define OBJECT_ 297
+# define STRING_ 298
+# define NULLREF_ 299
+# define DEFAULT_ 300
+# define CDECL_ 301
+# define VARARG_ 302
+# define STDCALL_ 303
+# define THISCALL_ 304
+# define FASTCALL_ 305
+# define CLASS_ 306
+# define TYPEDREF_ 307
+# define UNMANAGED_ 308
+# define FINALLY_ 309
+# define HANDLER_ 310
+# define CATCH_ 311
+# define FILTER_ 312
+# define FAULT_ 313
+# define EXTENDS_ 314
+# define IMPLEMENTS_ 315
+# define TO_ 316
+# define AT_ 317
+# define TLS_ 318
+# define TRUE_ 319
+# define FALSE_ 320
+# define _INTERFACEIMPL 321
+# define VALUE_ 322
+# define VALUETYPE_ 323
+# define NATIVE_ 324
+# define INSTANCE_ 325
+# define SPECIALNAME_ 326
+# define FORWARDER_ 327
+# define STATIC_ 328
+# define PUBLIC_ 329
+# define PRIVATE_ 330
+# define FAMILY_ 331
+# define FINAL_ 332
+# define SYNCHRONIZED_ 333
+# define INTERFACE_ 334
+# define SEALED_ 335
+# define NESTED_ 336
+# define ABSTRACT_ 337
+# define AUTO_ 338
+# define SEQUENTIAL_ 339
+# define EXPLICIT_ 340
+# define ANSI_ 341
+# define UNICODE_ 342
+# define AUTOCHAR_ 343
+# define IMPORT_ 344
+# define ENUM_ 345
+# define VIRTUAL_ 346
+# define NOINLINING_ 347
+# define AGGRESSIVEINLINING_ 348
+# define NOOPTIMIZATION_ 349
+# define UNMANAGEDEXP_ 350
+# define BEFOREFIELDINIT_ 351
+# define STRICT_ 352
+# define RETARGETABLE_ 353
+# define WINDOWSRUNTIME_ 354
+# define NOPLATFORM_ 355
+# define METHOD_ 356
+# define FIELD_ 357
+# define PINNED_ 358
+# define MODREQ_ 359
+# define MODOPT_ 360
+# define SERIALIZABLE_ 361
+# define PROPERTY_ 362
+# define TYPE_ 363
+# define ASSEMBLY_ 364
+# define FAMANDASSEM_ 365
+# define FAMORASSEM_ 366
+# define PRIVATESCOPE_ 367
+# define HIDEBYSIG_ 368
+# define NEWSLOT_ 369
+# define RTSPECIALNAME_ 370
+# define PINVOKEIMPL_ 371
+# define _CTOR 372
+# define _CCTOR 373
+# define LITERAL_ 374
+# define NOTSERIALIZED_ 375
+# define INITONLY_ 376
+# define REQSECOBJ_ 377
+# define CIL_ 378
+# define OPTIL_ 379
+# define MANAGED_ 380
+# define FORWARDREF_ 381
+# define PRESERVESIG_ 382
+# define RUNTIME_ 383
+# define INTERNALCALL_ 384
+# define _IMPORT 385
+# define NOMANGLE_ 386
+# define LASTERR_ 387
+# define WINAPI_ 388
+# define AS_ 389
+# define BESTFIT_ 390
+# define ON_ 391
+# define OFF_ 392
+# define CHARMAPERROR_ 393
+# define INSTR_NONE 394
+# define INSTR_VAR 395
+# define INSTR_I 396
+# define INSTR_I8 397
+# define INSTR_R 398
+# define INSTR_BRTARGET 399
+# define INSTR_METHOD 400
+# define INSTR_FIELD 401
+# define INSTR_TYPE 402
+# define INSTR_STRING 403
+# define INSTR_SIG 404
+# define INSTR_TOK 405
+# define INSTR_SWITCH 406
+# define _CLASS 407
+# define _NAMESPACE 408
+# define _METHOD 409
+# define _FIELD 410
+# define _DATA 411
+# define _THIS 412
+# define _BASE 413
+# define _NESTER 414
+# define _EMITBYTE 415
+# define _TRY 416
+# define _MAXSTACK 417
+# define _LOCALS 418
+# define _ENTRYPOINT 419
+# define _ZEROINIT 420
+# define _EVENT 421
+# define _ADDON 422
+# define _REMOVEON 423
+# define _FIRE 424
+# define _OTHER 425
+# define _PROPERTY 426
+# define _SET 427
+# define _GET 428
+# define _PERMISSION 429
+# define _PERMISSIONSET 430
+# define REQUEST_ 431
+# define DEMAND_ 432
+# define ASSERT_ 433
+# define DENY_ 434
+# define PERMITONLY_ 435
+# define LINKCHECK_ 436
+# define INHERITCHECK_ 437
+# define REQMIN_ 438
+# define REQOPT_ 439
+# define REQREFUSE_ 440
+# define PREJITGRANT_ 441
+# define PREJITDENY_ 442
+# define NONCASDEMAND_ 443
+# define NONCASLINKDEMAND_ 444
+# define NONCASINHERITANCE_ 445
+# define _LINE 446
+# define P_LINE 447
+# define _LANGUAGE 448
+# define _CUSTOM 449
+# define INIT_ 450
+# define _SIZE 451
+# define _PACK 452
+# define _VTABLE 453
+# define _VTFIXUP 454
+# define FROMUNMANAGED_ 455
+# define CALLMOSTDERIVED_ 456
+# define _VTENTRY 457
+# define RETAINAPPDOMAIN_ 458
+# define _FILE 459
+# define NOMETADATA_ 460
+# define _HASH 461
+# define _ASSEMBLY 462
+# define _PUBLICKEY 463
+# define _PUBLICKEYTOKEN 464
+# define ALGORITHM_ 465
+# define _VER 466
+# define _LOCALE 467
+# define EXTERN_ 468
+# define _MRESOURCE 469
+# define _MODULE 470
+# define _EXPORT 471
+# define LEGACY_ 472
+# define LIBRARY_ 473
+# define X86_ 474
+# define IA64_ 475
+# define AMD64_ 476
+# define ARM_ 477
+# define MARSHAL_ 478
+# define CUSTOM_ 479
+# define SYSSTRING_ 480
+# define FIXED_ 481
+# define VARIANT_ 482
+# define CURRENCY_ 483
+# define SYSCHAR_ 484
+# define DECIMAL_ 485
+# define DATE_ 486
+# define BSTR_ 487
+# define TBSTR_ 488
+# define LPSTR_ 489
+# define LPWSTR_ 490
+# define LPTSTR_ 491
+# define OBJECTREF_ 492
+# define IUNKNOWN_ 493
+# define IDISPATCH_ 494
+# define STRUCT_ 495
+# define SAFEARRAY_ 496
+# define BYVALSTR_ 497
+# define LPVOID_ 498
+# define ANY_ 499
+# define ARRAY_ 500
+# define LPSTRUCT_ 501
+# define IIDPARAM_ 502
+# define IN_ 503
+# define OUT_ 504
+# define OPT_ 505
+# define PARAM_ 506
+# define _OVERRIDE 507
+# define WITH_ 508
+# define NULL_ 509
+# define HRESULT_ 510
+# define CARRAY_ 511
+# define USERDEFINED_ 512
+# define RECORD_ 513
+# define FILETIME_ 514
+# define BLOB_ 515
+# define STREAM_ 516
+# define STORAGE_ 517
+# define STREAMED_OBJECT_ 518
+# define STORED_OBJECT_ 519
+# define BLOB_OBJECT_ 520
+# define CF_ 521
+# define CLSID_ 522
+# define VECTOR_ 523
+# define _SUBSYSTEM 524
+# define _CORFLAGS 525
+# define ALIGNMENT_ 526
+# define _IMAGEBASE 527
+# define _STACKRESERVE 528
+# define _TYPEDEF 529
+# define _TEMPLATE 530
+# define _TYPELIST 531
+# define _MSCORLIB 532
+# define P_DEFINE 533
+# define P_UNDEF 534
+# define P_IFDEF 535
+# define P_IFNDEF 536
+# define P_ELSE 537
+# define P_ENDIF 538
+# define P_INCLUDE 539
+#define yyclearin yychar = -1
+#define yyerrok yyerrflag = 0
+#ifndef YYMAXDEPTH
+#define YYMAXDEPTH 150
+#endif
+YYSTYPE yylval, yyval;
+#ifndef YYFARDATA
+#define YYFARDATA /*nothing*/
+#endif
+#if ! defined YYSTATIC
+#define YYSTATIC /*nothing*/
+#endif
+#if ! defined YYCONST
+#define YYCONST /*nothing*/
+#endif
+#ifndef YYACT
+#define YYACT yyact
+#endif
+#ifndef YYPACT
+#define YYPACT yypact
+#endif
+#ifndef YYPGO
+#define YYPGO yypgo
+#endif
+#ifndef YYR1
+#define YYR1 yyr1
+#endif
+#ifndef YYR2
+#define YYR2 yyr2
+#endif
+#ifndef YYCHK
+#define YYCHK yychk
+#endif
+#ifndef YYDEF
+#define YYDEF yydef
+#endif
+#ifndef YYV
+#define YYV yyv
+#endif
+#ifndef YYS
+#define YYS yys
+#endif
+#ifndef YYLOCAL
+#define YYLOCAL
+#endif
+#ifndef YYR_T
+#define YYR_T int
+#endif
+typedef YYR_T yyr_t;
+#ifndef YYEXIND_T
+#define YYEXIND_T unsigned int
+#endif
+typedef YYEXIND_T yyexind_t;
+#ifndef YYOPTTIME
+#define YYOPTTIME 0
+#endif
+# define YYERRCODE 256
+
+#line 2051 "asmparse.y"
+
+
+#include "grammar_after.cpp"
+YYSTATIC YYCONST short yyexca[] = {
+#if !(YYOPTTIME)
+-1, 1,
+#endif
+ 0, -1,
+ -2, 0,
+#if !(YYOPTTIME)
+-1, 452,
+#endif
+ 41, 532,
+ -2, 308,
+#if !(YYOPTTIME)
+-1, 621,
+#endif
+ 274, 549,
+ 47, 549,
+ -2, 227,
+#if !(YYOPTTIME)
+-1, 642,
+#endif
+ 40, 307,
+ 60, 307,
+ -2, 549,
+#if !(YYOPTTIME)
+-1, 663,
+#endif
+ 41, 532,
+ -2, 308,
+#if !(YYOPTTIME)
+-1, 686,
+#endif
+ 274, 549,
+ 47, 549,
+ -2, 510,
+#if !(YYOPTTIME)
+-1, 803,
+#endif
+ 123, 232,
+ -2, 549,
+#if !(YYOPTTIME)
+-1, 828,
+#endif
+ 41, 532,
+ -2, 308,
+#if !(YYOPTTIME)
+-1, 953,
+#endif
+ 41, 532,
+ -2, 308,
+#if !(YYOPTTIME)
+-1, 986,
+#endif
+ 41, 532,
+ -2, 308,
+#if !(YYOPTTIME)
+-1, 987,
+#endif
+ 41, 532,
+ -2, 308,
+#if !(YYOPTTIME)
+-1, 1308,
+#endif
+ 41, 532,
+ -2, 308,
+#if !(YYOPTTIME)
+-1, 1309,
+#endif
+ 41, 532,
+ -2, 308,
+#if !(YYOPTTIME)
+-1, 1315,
+#endif
+ 41, 532,
+ -2, 308,
+#if !(YYOPTTIME)
+-1, 1322,
+#endif
+ 41, 532,
+ -2, 308,
+#if !(YYOPTTIME)
+-1, 1447,
+#endif
+ 41, 532,
+ -2, 308,
+#if !(YYOPTTIME)
+-1, 1479,
+#endif
+ 41, 532,
+ -2, 308,
+#if !(YYOPTTIME)
+-1, 1545,
+#endif
+ 41, 532,
+ -2, 308,
+#if !(YYOPTTIME)
+-1, 1562,
+#endif
+ 41, 532,
+ -2, 308,
+
+};
+
+# define YYNPROD 838
+#if YYOPTTIME
+YYSTATIC YYCONST yyexind_t yyexcaind[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 8, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 14, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 20, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 24, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 30, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 34, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 38, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 42, 46, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 50, 54,
+ 0, 0, 0, 0, 0, 58, 0, 0, 0, 0,
+ 0, 0, 62, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 66, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 70,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 74, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 78
+};
+#endif
+# define YYLAST 3904
+
+YYSTATIC YYCONST short YYFARDATA YYACT[] = {
+ 699, 1398, 1121, 1466, 658, 1467, 639, 1024, 1465, 878,
+ 1464, 963, 784, 753, 964, 221, 775, 26, 698, 725,
+ 73, 75, 275, 414, 624, 877, 966, 1399, 535, 191,
+ 477, 1503, 150, 788, 751, 756, 1134, 110, 1065, 107,
+ 690, 852, 273, 153, 219, 660, 24, 44, 776, 218,
+ 307, 10, 190, 176, 78, 81, 6, 86, 5, 598,
+ 673, 262, 204, 515, 3, 188, 217, 983, 17, 301,
+ 603, 136, 76, 1550, 1194, 1242, 214, 264, 7, 1238,
+ 1057, 1239, 1113, 1111, 85, 1112, 580, 74, 715, 88,
+ 87, 137, 89, 300, 115, 56, 139, 712, 672, 113,
+ 1058, 98, 112, 178, 179, 180, 181, 74, 272, 696,
+ 322, 519, 1015, 461, 220, 56, 18, 452, 536, 338,
+ 278, 88, 87, 1021, 89, 268, 216, 269, 1240, 225,
+ 56, 265, 277, 277, 1228, 1229, 106, 1226, 1227, 590,
+ 277, 343, 361, 360, 359, 358, 654, 368, 345, 653,
+ 68, 310, 312, 314, 316, 318, 185, 1554, 460, 1126,
+ 1127, 1414, 98, 931, 932, 327, 277, 348, 339, 1027,
+ 342, 778, 1026, 779, 373, 366, 154, 277, 695, 133,
+ 694, 991, 379, 271, 362, 84, 258, 364, 363, 376,
+ 614, 192, 387, 105, 1519, 662, 513, 930, 365, 1059,
+ 369, 202, 203, 371, 370, 1487, 374, 1264, 596, 450,
+ 661, 451, 763, 372, 416, 469, 186, 467, 471, 470,
+ 442, 26, 74, 376, 456, 417, 418, 346, 376, 1559,
+ 352, 472, 474, 599, 353, 305, 483, 388, 88, 87,
+ 596, 89, 410, 1263, 1478, 500, 492, 1314, 457, 441,
+ 24, 1200, 357, 491, 435, 10, 825, 797, 787, 56,
+ 486, 432, 490, 428, 475, 478, 479, 773, 476, 429,
+ 494, 434, 17, 192, 108, 666, 511, 511, 528, 534,
+ 375, 433, 7, 351, 267, 321, 480, 481, 473, 485,
+ 152, 710, 74, 484, 1234, 540, 1345, 116, 1496, 1391,
+ 56, 1540, 499, 80, 79, 498, 543, 493, 1417, 571,
+ 959, 268, 1351, 1544, 574, 348, 575, 154, 576, 436,
+ 18, 266, 548, 1335, 1116, 578, 579, 504, 541, 46,
+ 420, 544, 421, 422, 423, 933, 934, 570, 935, 88,
+ 572, 947, 89, 573, 46, 594, 854, 855, 856, 1128,
+ 640, 641, 600, 135, 198, 88, 87, 962, 89, 199,
+ 1541, 200, 568, 1510, 192, 487, 1341, 201, 612, 154,
+ 755, 482, 277, 674, 1543, 510, 510, 527, 533, 74,
+ 605, 744, 745, 746, 195, 808, 182, 623, 943, 611,
+ 599, 581, 582, 1141, 497, 1233, 700, 1252, 1142, 196,
+ 565, 367, 375, 620, 595, 258, 610, 88, 87, 518,
+ 89, 74, 606, 607, 608, 609, 747, 748, 749, 1542,
+ 643, 613, 599, 537, 340, 341, 634, 1489, 348, 807,
+ 459, 618, 619, 621, 780, 1130, 321, 876, 648, 649,
+ 638, 88, 87, 177, 89, 1231, 88, 87, 847, 89,
+ 152, 781, 702, 754, 347, 650, 664, 1502, 413, 88,
+ 87, 670, 946, 1488, 651, 88, 87, 155, 89, 681,
+ 642, 1518, 1126, 1127, 545, 743, 1118, 177, 993, 994,
+ 995, 996, 177, 587, 505, 859, 352, 1513, 667, 988,
+ 353, 678, 80, 79, 479, 177, 647, 692, 646, 1512,
+ 782, 1511, 61, 62, 47, 63, 536, 1508, 357, 645,
+ 685, 198, 741, 669, 480, 481, 199, 689, 200, 82,
+ 63, 74, 701, 479, 201, 711, 680, 453, 72, 679,
+ 88, 87, 519, 89, 512, 520, 74, 507, 508, 351,
+ 686, 195, 88, 480, 481, 89, 74, 723, 71, 70,
+ 354, 355, 356, 538, 691, 216, 196, 1141, 225, 1506,
+ 1241, 724, 1142, 675, 676, 677, 720, 657, 721, 49,
+ 50, 51, 52, 53, 54, 55, 671, 709, 74, 644,
+ 479, 730, 1504, 80, 79, 714, 80, 79, 348, 49,
+ 50, 51, 52, 53, 54, 55, 719, 74, 1141, 716,
+ 480, 481, 726, 1142, 49, 50, 51, 52, 53, 54,
+ 55, 156, 157, 158, 69, 758, 74, 542, 74, 88,
+ 87, 592, 89, 600, 67, 764, 765, 155, 88, 87,
+ 688, 89, 74, 783, 98, 638, 729, 1320, 1319, 1318,
+ 1317, 750, 74, 697, 325, 74, 703, 1172, 1171, 1170,
+ 1169, 542, 705, 348, 706, 177, 377, 1499, 324, 769,
+ 770, 771, 1337, 1338, 1339, 642, 815, 789, 813, 819,
+ 853, 88, 87, 816, 89, 822, 541, 1180, 801, 802,
+ 80, 79, 798, 823, 88, 812, 806, 89, 74, 66,
+ 818, 626, 627, 628, 74, 1117, 833, 834, 762, 1450,
+ 495, 826, 216, 786, 591, 225, 1439, 800, 793, 803,
+ 74, 809, 796, 636, 846, 824, 382, 383, 384, 385,
+ 817, 152, 74, 857, 74, 56, 629, 630, 631, 922,
+ 74, 740, 821, 49, 50, 51, 52, 53, 54, 55,
+ 1437, 850, 936, 937, 860, 1490, 516, 761, 88, 87,
+ 375, 89, 832, 1327, 844, 1247, 1243, 1244, 1245, 1246,
+ 1179, 1435, 769, 600, 949, 192, 845, 942, 1433, 848,
+ 276, 156, 157, 158, 49, 50, 51, 52, 53, 54,
+ 55, 97, 74, 924, 111, 925, 926, 927, 928, 929,
+ 952, 1001, 1416, 1407, 985, 152, 635, 938, 1406, 277,
+ 1013, 965, 362, 1326, 1011, 74, 354, 355, 356, 442,
+ 1000, 1009, 528, 605, 1404, 585, 954, 584, 583, 145,
+ 1390, 1012, 948, 1388, 586, 799, 960, 955, 277, 1017,
+ 958, 692, 692, 1032, 1378, 1376, 1237, 350, 441, 999,
+ 1008, 817, 1022, 435, 997, 1007, 851, 1374, 1037, 1014,
+ 432, 817, 428, 849, 1019, 1035, 1016, 1018, 429, 1039,
+ 434, 989, 326, 323, 88, 87, 94, 89, 74, 1372,
+ 433, 1033, 1034, 1045, 352, 772, 828, 277, 353, 1030,
+ 80, 79, 479, 1050, 277, 56, 1370, 1368, 691, 691,
+ 88, 87, 348, 89, 74, 954, 357, 337, 155, 348,
+ 1366, 1364, 480, 481, 668, 1362, 817, 1359, 436, 998,
+ 1006, 527, 1356, 1123, 1354, 1350, 56, 1334, 1312, 1055,
+ 152, 1196, 88, 87, 718, 89, 177, 351, 1044, 1053,
+ 193, 615, 1043, 194, 1051, 348, 1042, 352, 1041, 46,
+ 352, 353, 1122, 1023, 768, 820, 1067, 814, 1068, 1126,
+ 1127, 501, 733, 617, 616, 1124, 198, 177, 1132, 357,
+ 145, 199, 357, 200, 88, 87, 577, 89, 758, 201,
+ 564, 1300, 155, 1236, 308, 1119, 455, 109, 1054, 1140,
+ 1129, 92, 529, 1138, 1125, 1394, 195, 1298, 1115, 1185,
+ 351, 1183, 1184, 351, 88, 87, 1186, 89, 1178, 277,
+ 177, 196, 1296, 1491, 1064, 1060, 1061, 1062, 1063, 1025,
+ 1492, 1133, 145, 1182, 1415, 328, 329, 330, 1294, 1181,
+ 956, 96, 1301, 590, 104, 103, 102, 101, 1219, 99,
+ 100, 105, 56, 1, 1175, 1332, 1195, 1173, 1299, 1203,
+ 332, 941, 156, 157, 158, 1167, 1187, 1188, 1189, 1190,
+ 1230, 766, 1202, 1297, 1165, 1232, 1191, 1192, 1193, 80,
+ 79, 479, 588, 1131, 1223, 1225, 1224, 1222, 984, 1295,
+ 1235, 1197, 1400, 88, 87, 1163, 89, 1198, 1161, 1199,
+ 945, 480, 481, 589, 1218, 1176, 189, 708, 1174, 88,
+ 87, 1005, 89, 1003, 1004, 1159, 1168, 155, 1010, 46,
+ 707, 205, 152, 1157, 704, 1166, 633, 1412, 412, 187,
+ 625, 790, 61, 62, 47, 63, 156, 157, 158, 1248,
+ 1177, 192, 192, 192, 192, 177, 1164, 277, 1268, 1162,
+ 46, 192, 192, 192, 331, 1266, 333, 334, 335, 336,
+ 1155, 625, 1251, 192, 1411, 1265, 1160, 1269, 1410, 1271,
+ 1273, 1274, 1255, 1277, 1158, 1279, 1280, 1281, 1282, 1283,
+ 1284, 1285, 1270, 1287, 1288, 1289, 1290, 1291, 1292, 1293,
+ 1254, 1401, 1259, 56, 1302, 1303, 1153, 1305, 1304, 1151,
+ 1272, 1149, 1275, 1276, 1147, 1278, 1221, 1048, 1267, 1047,
+ 836, 1156, 1307, 1286, 354, 355, 356, 1145, 1143, 49,
+ 50, 51, 52, 53, 54, 55, 742, 1316, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
+ 130, 131, 132, 665, 1313, 352, 317, 1154, 454, 353,
+ 1152, 315, 1150, 313, 1328, 1148, 378, 1330, 1331, 521,
+ 1321, 156, 157, 158, 311, 45, 46, 357, 1146, 1144,
+ 1336, 1340, 309, 1333, 817, 41, 43, 354, 355, 356,
+ 354, 355, 356, 1135, 1342, 277, 277, 1140, 1552, 526,
+ 590, 88, 87, 306, 89, 63, 415, 308, 351, 155,
+ 1315, 1343, 308, 1257, 308, 56, 277, 503, 1452, 512,
+ 590, 1451, 507, 508, 140, 308, 1380, 1381, 1382, 1383,
+ 1384, 1385, 1386, 308, 944, 1347, 63, 177, 590, 1539,
+ 590, 1329, 1344, 1392, 1393, 193, 531, 1346, 194, 532,
+ 1397, 1396, 940, 831, 308, 138, 1379, 1402, 1403, 1031,
+ 1524, 590, 923, 1408, 590, 590, 1395, 830, 811, 767,
+ 760, 198, 177, 1405, 717, 566, 199, 349, 200, 258,
+ 303, 792, 1564, 117, 201, 97, 1555, 1553, 1140, 49,
+ 50, 51, 52, 53, 54, 55, 1546, 1523, 817, 1486,
+ 1485, 195, 1484, 1454, 1449, 1446, 1443, 1442, 1438, 56,
+ 524, 1436, 1434, 1432, 1419, 1413, 196, 46, 1409, 1389,
+ 49, 50, 51, 52, 53, 54, 55, 134, 1445, 1387,
+ 1377, 1375, 1373, 1371, 1369, 1367, 1365, 1363, 1361, 1360,
+ 526, 1455, 1456, 1457, 1358, 1357, 1355, 1453, 1353, 1444,
+ 1448, 1352, 63, 156, 157, 158, 1349, 1324, 1348, 1325,
+ 1458, 1323, 523, 1311, 1470, 525, 1310, 1471, 1469, 1468,
+ 1306, 1256, 1253, 258, 1476, 693, 1220, 88, 87, 1114,
+ 89, 1052, 1481, 1038, 1480, 1036, 1029, 1028, 1020, 961,
+ 951, 950, 56, 1498, 939, 1483, 1505, 1507, 1509, 858,
+ 1505, 1507, 1509, 530, 841, 840, 1495, 1507, 1516, 838,
+ 1520, 1517, 1515, 1514, 1522, 1521, 88, 835, 829, 89,
+ 827, 56, 810, 1497, 1500, 1501, 791, 774, 738, 46,
+ 737, 1538, 736, 1493, 735, 734, 49, 50, 51, 52,
+ 53, 54, 55, 732, 731, 1529, 1505, 1507, 1509, 684,
+ 637, 524, 569, 425, 424, 344, 258, 320, 206, 1562,
+ 1547, 1525, 817, 1545, 1479, 1475, 1474, 1473, 1472, 1447,
+ 1534, 1441, 1440, 1431, 1430, 354, 355, 356, 1551, 1429,
+ 1549, 1428, 1427, 1548, 1535, 1536, 1537, 449, 1426, 1425,
+ 1424, 1423, 1561, 63, 1422, 1421, 1560, 1563, 1420, 1418,
+ 1300, 1298, 1296, 523, 1294, 1322, 525, 1175, 1173, 1557,
+ 88, 1558, 1167, 89, 1556, 1526, 1527, 1528, 1530, 1531,
+ 1532, 1533, 1165, 46, 1163, 96, 1161, 1159, 104, 103,
+ 102, 101, 56, 99, 100, 105, 1157, 1155, 1153, 1151,
+ 1149, 1309, 1308, 817, 1250, 1249, 1066, 1056, 1049, 1040,
+ 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
+ 255, 256, 257, 987, 986, 953, 843, 59, 842, 839,
+ 837, 208, 259, 210, 228, 212, 213, 49, 50, 51,
+ 52, 53, 54, 55, 728, 41, 43, 727, 713, 687,
+ 683, 682, 663, 88, 632, 602, 89, 601, 593, 567,
+ 547, 546, 61, 62, 47, 63, 46, 496, 419, 411,
+ 874, 386, 319, 223, 304, 522, 514, 868, 517, 869,
+ 870, 871, 509, 506, 56, 502, 302, 222, 36, 184,
+ 93, 33, 468, 466, 465, 46, 464, 463, 244, 462,
+ 227, 243, 215, 209, 245, 246, 247, 248, 249, 250,
+ 251, 252, 253, 254, 255, 256, 257, 863, 864, 865,
+ 95, 59, 226, 224, 207, 208, 259, 210, 228, 212,
+ 213, 211, 879, 31, 56, 1002, 992, 439, 795, 41,
+ 43, 431, 794, 430, 427, 539, 1046, 270, 83, 49,
+ 50, 51, 52, 53, 54, 55, 61, 62, 47, 63,
+ 29, 57, 862, 866, 867, 34, 872, 223, 25, 873,
+ 16, 263, 15, 14, 261, 13, 260, 12, 11, 9,
+ 8, 222, 1086, 4, 2, 234, 242, 245, 246, 247,
+ 248, 249, 250, 251, 252, 253, 254, 255, 256, 257,
+ 990, 241, 240, 239, 59, 238, 46, 237, 208, 259,
+ 210, 228, 212, 213, 236, 235, 226, 224, 233, 232,
+ 231, 230, 41, 43, 229, 114, 77, 42, 56, 38,
+ 30, 58, 32, 59, 752, 656, 655, 1482, 299, 61,
+ 62, 47, 63, 49, 50, 51, 52, 53, 54, 55,
+ 223, 41, 43, 90, 183, 861, 1139, 757, 785, 1258,
+ 957, 1137, 1136, 604, 222, 1461, 1460, 1459, 61, 62,
+ 47, 63, 1477, 1463, 1462, 60, 35, 1201, 1120, 597,
+ 659, 21, 777, 91, 37, 1069, 739, 65, 64, 197,
+ 875, 39, 40, 0, 426, 0, 0, 0, 0, 226,
+ 224, 0, 982, 981, 980, 0, 975, 974, 973, 972,
+ 0, 970, 971, 105, 0, 979, 978, 977, 976, 0,
+ 0, 0, 969, 967, 0, 0, 49, 50, 51, 52,
+ 53, 54, 55, 0, 0, 0, 0, 0, 0, 0,
+ 38, 30, 58, 32, 59, 0, 19, 20, 46, 22,
+ 23, 48, 0, 27, 28, 49, 50, 51, 52, 53,
+ 54, 55, 41, 43, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 61,
+ 62, 47, 63, 0, 0, 0, 60, 35, 968, 0,
+ 0, 0, 21, 0, 0, 37, 444, 1097, 0, 874,
+ 0, 0, 39, 40, 0, 0, 868, 0, 869, 870,
+ 871, 0, 0, 0, 0, 0, 1073, 1074, 0, 1081,
+ 1095, 1075, 1076, 1077, 1078, 0, 1079, 1080, 0, 1096,
+ 1082, 1083, 1084, 1085, 0, 0, 0, 0, 0, 0,
+ 0, 0, 46, 0, 0, 0, 863, 864, 865, 0,
+ 0, 0, 0, 0, 0, 0, 0, 19, 20, 0,
+ 22, 23, 48, 0, 27, 28, 49, 50, 51, 52,
+ 53, 54, 55, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 448, 0, 58, 32, 59, 0, 0, 0,
+ 444, 862, 866, 867, 0, 872, 445, 0, 873, 0,
+ 0, 446, 0, 0, 41, 43, 0, 146, 874, 0,
+ 0, 0, 0, 0, 0, 868, 0, 869, 870, 871,
+ 0, 61, 62, 47, 63, 0, 437, 438, 0, 921,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 447, 0, 0, 0,
+ 0, 0, 0, 0, 0, 863, 864, 865, 49, 50,
+ 51, 52, 53, 54, 55, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 448, 0, 58, 32,
+ 59, 443, 440, 0, 0, 0, 0, 0, 0, 0,
+ 445, 0, 0, 0, 0, 446, 0, 0, 41, 43,
+ 862, 866, 867, 0, 872, 0, 0, 873, 49, 50,
+ 51, 52, 53, 54, 55, 61, 62, 47, 63, 1494,
+ 437, 438, 1071, 1072, 0, 1087, 1088, 1089, 0, 1090,
+ 1091, 0, 0, 1092, 1093, 0, 1094, 0, 0, 0,
+ 447, 0, 0, 0, 0, 0, 0, 0, 0, 1070,
+ 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107,
+ 1108, 1109, 1110, 893, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 443, 440, 920, 0, 0,
+ 0, 0, 885, 886, 0, 894, 911, 887, 888, 889,
+ 890, 0, 891, 892, 0, 912, 895, 896, 897, 898,
+ 893, 0, 49, 50, 51, 52, 53, 54, 55, 0,
+ 0, 0, 0, 0, 920, 146, 0, 0, 0, 885,
+ 886, 0, 894, 911, 887, 888, 889, 890, 0, 891,
+ 892, 0, 912, 895, 896, 897, 898, 0, 0, 0,
+ 909, 0, 913, 0, 0, 175, 0, 915, 0, 151,
+ 148, 163, 161, 170, 0, 164, 165, 166, 167, 0,
+ 168, 169, 917, 0, 171, 172, 173, 174, 563, 0,
+ 0, 142, 162, 152, 0, 0, 0, 909, 0, 913,
+ 141, 147, 0, 0, 915, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 918, 143, 144, 149, 917,
+ 555, 0, 549, 550, 551, 552, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 146, 0, 0, 0, 0,
+ 352, 0, 0, 0, 768, 0, 0, 0, 0, 0,
+ 160, 0, 918, 0, 0, 0, 0, 0, 557, 558,
+ 559, 560, 357, 0, 554, 0, 0, 0, 561, 562,
+ 553, 0, 0, 0, 0, 982, 981, 980, 0, 975,
+ 974, 973, 972, 0, 970, 971, 105, 0, 979, 978,
+ 977, 976, 0, 622, 0, 969, 967, 0, 0, 0,
+ 0, 0, 0, 0, 0, 880, 0, 881, 882, 883,
+ 884, 899, 900, 901, 916, 902, 903, 904, 905, 906,
+ 907, 908, 910, 914, 0, 0, 0, 919, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 880, 0, 881, 882, 883, 884, 899, 900,
+ 901, 916, 902, 903, 904, 905, 906, 907, 908, 910,
+ 914, 968, 88, 87, 919, 89, 0, 0, 0, 0,
+ 155, 0, 556, 175, 0, 0, 0, 151, 148, 163,
+ 161, 170, 0, 164, 165, 166, 167, 0, 168, 169,
+ 0, 0, 171, 172, 173, 174, 146, 0, 177, 142,
+ 162, 352, 0, 0, 0, 353, 0, 0, 141, 147,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 357, 143, 144, 149, 0, 0, 175,
+ 0, 0, 0, 0, 0, 163, 161, 170, 0, 164,
+ 165, 166, 167, 0, 168, 169, 0, 0, 171, 172,
+ 173, 174, 0, 0, 622, 1261, 162, 0, 160, 159,
+ 0, 0, 88, 87, 0, 89, 0, 0, 0, 0,
+ 155, 0, 0, 175, 0, 0, 0, 151, 148, 163,
+ 161, 170, 0, 164, 165, 166, 167, 0, 168, 169,
+ 0, 0, 171, 172, 173, 174, 0, 0, 177, 142,
+ 162, 0, 0, 1262, 0, 0, 0, 0, 141, 147,
+ 0, 0, 0, 0, 156, 157, 158, 0, 0, 0,
+ 0, 1260, 0, 0, 143, 144, 149, 0, 0, 0,
+ 0, 0, 0, 0, 297, 198, 146, 0, 0, 0,
+ 199, 352, 200, 0, 0, 353, 0, 0, 201, 0,
+ 0, 63, 0, 0, 0, 0, 0, 0, 160, 0,
+ 354, 355, 356, 357, 0, 195, 284, 0, 279, 280,
+ 281, 282, 283, 0, 640, 641, 0, 287, 0, 0,
+ 196, 0, 0, 0, 0, 0, 285, 0, 0, 0,
+ 295, 0, 286, 0, 622, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 288, 289, 290, 291, 292, 293,
+ 294, 298, 0, 0, 156, 157, 158, 296, 0, 0,
+ 0, 0, 0, 88, 87, 0, 89, 0, 0, 0,
+ 146, 155, 0, 0, 175, 0, 0, 0, 151, 148,
+ 163, 161, 170, 0, 164, 165, 166, 167, 0, 168,
+ 169, 0, 0, 171, 172, 173, 174, 0, 0, 177,
+ 142, 162, 0, 0, 0, 0, 0, 0, 0, 141,
+ 147, 0, 0, 0, 348, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 143, 144, 149, 274, 1217,
+ 1216, 1211, 0, 1210, 1209, 1208, 1207, 146, 1205, 1206,
+ 105, 0, 1215, 1214, 1213, 1212, 0, 0, 0, 0,
+ 0, 1204, 0, 0, 0, 0, 0, 0, 0, 160,
+ 0, 354, 355, 356, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 640, 641, 982, 981, 980,
+ 0, 975, 974, 973, 972, 0, 970, 971, 105, 0,
+ 979, 978, 977, 976, 0, 274, 0, 969, 967, 0,
+ 0, 0, 0, 88, 87, 0, 89, 0, 0, 0,
+ 0, 155, 0, 0, 175, 156, 157, 158, 151, 148,
+ 163, 161, 170, 0, 164, 165, 166, 167, 0, 168,
+ 169, 0, 0, 171, 172, 173, 174, 146, 0, 177,
+ 142, 162, 0, 0, 0, 0, 0, 0, 0, 141,
+ 147, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 968, 0, 143, 144, 149, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 274, 0, 88, 87, 160,
+ 89, 354, 355, 356, 146, 155, 0, 0, 175, 0,
+ 0, 0, 151, 148, 163, 161, 170, 0, 164, 165,
+ 166, 167, 0, 168, 169, 0, 0, 171, 172, 173,
+ 174, 0, 0, 177, 142, 162, 0, 0, 0, 0,
+ 0, 0, 0, 141, 147, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 156, 157, 158, 0, 143,
+ 144, 149, 274, 805, 88, 87, 0, 89, 0, 0,
+ 0, 0, 155, 0, 0, 175, 0, 0, 0, 151,
+ 148, 163, 161, 170, 0, 164, 165, 166, 167, 0,
+ 168, 169, 0, 160, 171, 172, 173, 174, 146, 0,
+ 177, 142, 162, 0, 0, 0, 0, 804, 0, 0,
+ 141, 147, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 143, 144, 149, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 156,
+ 157, 158, 0, 0, 0, 0, 274, 0, 0, 0,
+ 160, 159, 0, 0, 88, 87, 146, 89, 0, 0,
+ 0, 0, 155, 0, 0, 175, 0, 0, 0, 151,
+ 148, 163, 161, 170, 0, 164, 165, 166, 167, 0,
+ 168, 169, 0, 0, 171, 172, 173, 174, 0, 0,
+ 177, 142, 162, 0, 0, 0, 0, 0, 0, 0,
+ 141, 147, 0, 0, 0, 0, 156, 157, 158, 0,
+ 0, 0, 0, 0, 274, 0, 143, 144, 149, 0,
+ 0, 88, 87, 0, 89, 0, 0, 0, 0, 155,
+ 0, 0, 175, 0, 0, 0, 151, 148, 163, 161,
+ 170, 0, 164, 165, 166, 167, 0, 168, 169, 0,
+ 160, 171, 172, 173, 174, 0, 0, 177, 142, 162,
+ 0, 0, 0, 0, 0, 0, 0, 759, 147, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 143, 144, 149, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 146, 0, 0, 0, 0, 156, 157, 158, 0,
+ 0, 0, 0, 0, 0, 88, 87, 160, 89, 0,
+ 0, 0, 0, 155, 0, 0, 175, 0, 0, 0,
+ 151, 148, 163, 161, 170, 0, 164, 165, 166, 167,
+ 0, 168, 169, 0, 0, 171, 172, 173, 174, 0,
+ 0, 177, 142, 162, 0, 0, 146, 0, 0, 0,
+ 0, 141, 147, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 156, 157, 158, 0, 143, 144, 149,
+ 0, 0, 0, 88, 87, 0, 89, 0, 0, 0,
+ 0, 155, 0, 0, 175, 0, 0, 0, 151, 148,
+ 163, 161, 170, 0, 164, 165, 166, 167, 0, 168,
+ 169, 652, 146, 171, 172, 173, 174, 0, 0, 177,
+ 142, 162, 88, 87, 0, 89, 0, 0, 0, 141,
+ 147, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 143, 144, 149, 0, 0,
+ 0, 0, 0, 0, 0, 0, 409, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 146, 156, 157, 158,
+ 988, 0, 0, 0, 0, 0, 0, 0, 0, 458,
+ 0, 0, 0, 0, 391, 0, 0, 0, 407, 0,
+ 0, 389, 390, 0, 0, 0, 393, 394, 405, 395,
+ 396, 397, 398, 399, 400, 401, 402, 392, 0, 0,
+ 0, 0, 0, 406, 0, 0, 404, 0, 0, 0,
+ 146, 0, 0, 403, 722, 0, 0, 0, 0, 0,
+ 0, 0, 408, 0, 0, 156, 157, 158, 488, 175,
+ 489, 0, 0, 151, 148, 163, 161, 170, 0, 164,
+ 165, 166, 167, 0, 168, 169, 0, 0, 171, 172,
+ 173, 174, 0, 0, 177, 142, 162, 0, 0, 0,
+ 0, 0, 0, 0, 141, 147, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 143, 144, 149, 380, 175, 381, 0, 0, 151, 148,
+ 163, 161, 170, 0, 164, 165, 166, 167, 0, 168,
+ 169, 0, 0, 171, 172, 173, 174, 0, 0, 0,
+ 142, 162, 0, 0, 160, 0, 0, 0, 0, 141,
+ 147, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 143, 144, 149, 0, 0,
+ 175, 0, 0, 0, 151, 148, 163, 161, 170, 0,
+ 164, 165, 166, 167, 0, 168, 169, 0, 0, 171,
+ 172, 173, 174, 0, 0, 0, 142, 162, 0, 160,
+ 0, 0, 0, 0, 0, 141, 147, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 143, 144, 149, 175, 0, 0, 0, 151, 148,
+ 163, 161, 170, 0, 164, 165, 166, 167, 0, 168,
+ 169, 0, 0, 171, 172, 173, 174, 0, 0, 0,
+ 142, 162, 0, 0, 0, 160, 0, 0, 0, 141,
+ 147, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 143, 144, 149, 175, 0,
+ 0, 0, 151, 148, 163, 161, 170, 0, 164, 165,
+ 166, 167, 0, 168, 169, 0, 0, 171, 172, 173,
+ 174, 0, 0, 0, 142, 162, 0, 0, 0, 160,
+ 0, 0, 0, 141, 147, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 143,
+ 144, 149, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 160
+};
+
+YYSTATIC YYCONST short YYFARDATA YYPACT[] = {
+-1000, 1543,-1000, 566, 501,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000, 491, 426, 425, 405,-1000,-1000,-1000, 28,
+ 28, -454, 39, 39,-1000,-1000,-1000, 396,-1000, -129,
+ 411,-1000, 890, 743, 7, 886, 28, -366, -369,-1000,
+ -171, 777, 7, 777,-1000,-1000,-1000, 90, 2292, 411,
+ 411, 411, 411,-1000,-1000, 124,-1000,-1000,-1000, -162,
+ 1048,-1000,-1000, 1046, 7, 7,-1000,-1000, 1403,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000, 28, -139,-1000,-1000,
+-1000,-1000, 359, -132, 2954, 1220,-1000,-1000,-1000,-1000,
+ 2430,-1000, 28,-1000, 1317,-1000, 1308, 1644, 7, 1233,
+ 1212, 1204, 1193, 1191, 1186, 1642, 1486, 18,-1000, 28,
+ 600, 662,-1000,-1000, 95, 1220, 411, 2954,-1000,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000, 1484, 166, 1303, 448, -244, -245, -246,
+ -247, 359,-1000, -118, 359, 661, 368,-1000,-1000, -76,
+-1000, 3547, 186, 1189,-1000,-1000,-1000,-1000,-1000, 3383,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+ 435,-1000,-1000,-1000,-1000,-1000, 1220, 1641, 326, 1220,
+ 1220, 1220,-1000, 3222, 79,-1000,-1000, 1639, 1047, 2854,
+-1000, 3547,-1000,-1000,-1000, 216, 216,-1000, 1638,-1000,
+-1000, 29, 1483, 1482, 1779, 1432,-1000,-1000, 28,-1000,
+ 28, 77,-1000,-1000,-1000,-1000, 1170,-1000,-1000,-1000,
+-1000,-1000, 885, 28, 3183,-1000, 67, -94,-1000,-1000,
+ 424, 28, 39, 228, 7, 424, 661, 3328, 2954, -95,
+ 216, 2854, 1637,-1000, 282,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+ 826, 71, 1114, 857,-1000, 87,-1000, 298, 359,-1000,
+-1000, 2954,-1000,-1000, 181, 899, 216, 411,-1000,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000, 1631, 1630, 2084,
+ 877, 275, 1301, 1629, 79, 1481, 0,-1000, 28, 0,
+-1000, 39,-1000, 28,-1000, 28,-1000, 28,-1000,-1000,
+-1000,-1000, 873,-1000, 28, 28,-1000, 1220,-1000,-1000,
+-1000, -387,-1000,-1000,-1000,-1000,-1000, 662, 488, 94,
+-1000,-1000, 1220, 1022,-1000, 1292, 581, 1628,-1000, 82,
+ 411, 115,-1000,-1000,-1000, 1627, 1625, 3547, 411, 411,
+ 411, 411,-1000, 359,-1000,-1000, 3547, 604,-1000, 1220,
+-1000, -90,-1000, 899, 838, 861, 860, 411, 411, 2693,
+-1000,-1000,-1000,-1000,-1000,-1000, 28, 1292, 1081,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000,-1000,-1000, 362,-1000,-1000,-1000, 1624,
+ 1045,-1000, 673, 1479,-1000,-1000, 2553,-1000,-1000, 28,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, 386,
+ 375, 373,-1000,-1000,-1000,-1000,-1000, 28, 28, 332,
+ 3115,-1000,-1000, -214, -217,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000, -65, 1622,-1000, 28, 1165, 1, 216, 813,
+ 28,-1000, -94, 63, 63, 63, 63, 2954, 282,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+ 1621, 1620, 1478,-1000,-1000,-1000, 2693,-1000,-1000,-1000,
+-1000, 1292, 1619, 7, 3547,-1000, 424, 1320,-1000, -136,
+ -138,-1000,-1000, -356,-1000,-1000, 7, 354, 391, 7,
+-1000,-1000, 1043,-1000,-1000, 7,-1000, 7,-1000, 1039,
+ 1026,-1000,-1000, 411, -177, -371, 1618,-1000,-1000,-1000,
+-1000, 411, -380,-1000,-1000, -350,-1000,-1000,-1000, 1300,
+-1000, 831, 411, 3547, 1220, 3493, 28, 53, 1187,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000, 1617,-1000,-1000,-1000,
+-1000,-1000,-1000, 1614,-1000,-1000, 1317, 53, 1473,-1000,
+ 1472, 859, 1464, 1463, 1461, 1459, 1457,-1000, 468, 1148,
+-1000, 86, 1220,-1000,-1000,-1000, 52, 411, 53, 330,
+ 108, 3021,-1000,-1000, 1296, 1220,-1000, 654,-1000,-1000,
+ -63, 2954, 2954, 989, 1295, 899, 1220, 1220, 1220, 1220,
+-1000, 2392,-1000, 1220,-1000, 411, 411, 411, 782, 1220,
+ -7, 1220, 147, 1456,-1000, 128,-1000,-1000,-1000,-1000,
+-1000,-1000, 28,-1000, 1292,-1000,-1000, 661, -16, 1051,
+-1000,-1000, 1220, 1455, 1226,-1000,-1000,-1000,-1000,-1000,
+-1000, -17, 216, 734, 2954, 2787, 59, 488, 1451, 1294,
+-1000,-1000, 3493, -65, 854, 28, -22, 3547, 28, 1220,
+ 852,-1000,-1000,-1000, 424,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000, 28, 39,-1000, -18, 1220, 53, 1449, 836,
+ 1447, 1293, 1279,-1000, 79, 28, 28, 1446, 1132,-1000,
+-1000, 1292, 1600, 1438, 1599, 1434, 1433, 1598, 1596, 1220,
+ 411,-1000, 411, 28, 131, 411, 7, 2954, 411, 753,
+ 902, 192, -157, 1428, 96, 1824, 120, 2016, 28,-1000,
+ 1291,-1000, 883,-1000, 883, 883, 883, 883, 883, -120,
+-1000, 28, 28, 411,-1000,-1000,-1000,-1000,-1000,-1000,
+ 1220, 1423, 1278, 980,-1000,-1000, 263, 1260, 1019, 199,
+ 78,-1000, -42, 28, 1420, 1419,-1000, 3547, 1595, 1189,
+ 1189, 1189, 411, 411,-1000, 958, 270, 128,-1000,-1000,
+-1000,-1000,-1000, 1418, 232, 1635, 1007, -22, 1594, 1593,
+ 3439,-1000,-1000, 1685, 56, 666, 973, -22, 3547, 28,
+ 1220, -337, 411, 1220,-1000,-1000, 3547,-1000,-1000, 1220,
+-1000, -65, 192, 1417, -266,-1000,-1000, 1220, 2693, 850,
+ 948, -144, -147, 1416, 1415, 411, 1288,-1000, -65,-1000,
+ 424, 424,-1000,-1000,-1000,-1000, 354,-1000,-1000,-1000,
+-1000,-1000,-1000,-1000, 1189, 1220, 1414, 28, 1220, 1412,
+-1000, 411, -22, 1579, 845, 843, 839, 835,-1000, 53,
+ 1715,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000, 1131, 1129, 1578, 948, 79, 1410, 887, 7,
+ 1577, -400, -78,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000,-1000, 724,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000, 1576, 1576,-1000, 1576,
+ 1750,-1000,-1000, -412,-1000, -402,-1000,-1000, -417,-1000,
+-1000,-1000, 1408,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+ 79,-1000,-1000,-1000,-1000,-1000, 61, 432, 1220,-1000,
+ 53, 630, 224,-1000, 3021, 312, 1002,-1000,-1000,-1000,
+-1000,-1000, 899, -65, 1189, 1220,-1000, 411, 1219, 2954,
+-1000,-1000,-1000, 200,-1000,-1000,-1000, 1158, 1157, 1144,
+ 1141, 1139, 1136, 1100, 1063, 1055, 1038, 1035, 1014, 1005,
+ 366, 997, 994, 7, 637, 1051, -65, -65, 28, 934,
+-1000,-1000,-1000, 661, 661, 661, 661,-1000,-1000,-1000,
+-1000,-1000,-1000, 661, 661, 661,-1000,-1000,-1000,-1000,
+-1000, -434, 2693, 828,-1000, 661, 1220, 1187,-1000, 79,
+-1000, 79, -23,-1000,-1000, 2602, 79, 28,-1000,-1000,
+ 1220,-1000, 1405,-1000,-1000, 1128,-1000,-1000, -301, 1050,
+ 2016,-1000,-1000,-1000,-1000, 1292,-1000, -254, -257, 28,
+-1000,-1000,-1000,-1000, 352, 169, 53, 882, 745,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000, -423,-1000,-1000, 37,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000, 475,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, 28,-1000,
+-1000,-1000,-1000, 1575, 1292, 1574,-1000,-1000,-1000,-1000,
+-1000, 274, 1401, 1219,-1000, 128, 1400, 1239,-1000, 2348,
+-1000,-1000,-1000, -56, 28, 829, 28, 2650, 28, 314,
+ 28, 795, 28, 39, 28, 28, 28, 28, 28, 28,
+ 28, 39, 28, 28, 28, 28, 28, 28, 28, 978,
+ 962, 947, 931, 28, 28, -160, 28, 1399, 1292,-1000,
+-1000, 1572, 1571, 1395, 1392, 825,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000,-1000, 216, -27,-1000, 1240,-1000,-1000,
+ -22,-1000,-1000, 1292,-1000, 1570, 1569, 1568, 1567, 1566,
+ 1557, 356, 1556, 1554, 1552, 1542, 1538, 1537,-1000,-1000,
+-1000, 354,-1000, 1535, 1390, 1386,-1000,-1000,-1000,-1000,
+ 1388,-1000, 710, 28,-1000, 1267, 28, 28, 974, 53,
+ 824,-1000,-1000,-1000,-1000,-1000,-1000,-1000, 60, 28,
+ 381, 241,-1000,-1000,-1000,-1000,-1000, 2954, 205,-1000,
+-1000,-1000, 1011, 1387, 1385, 822, 49, 1380, 1377, 821,
+ 1375, 819, 1374, 1373, 814, 1368, 1367, 812, 1366, 808,
+ 1365, 807, 1364, 794, 1363, 793, 1362, 776, 1361, 754,
+ 1360, 742, 1359, 741, 39, 28, 28, 28, 28, 28,
+ 28, 28, 1358, 730, 1348, 727,-1000, 174, -65, -65,
+-1000,-1000, 923, 3547, -22, -65, 1012, 1534, 1532, 1531,
+ 1530, 1113, -65,-1000,-1000,-1000,-1000, 28, 721, 53,
+ 705, 700, 28, 1292,-1000,-1000, 1347, 1090, 1086, 1049,
+ 1344,-1000, 36,-1000, 953, 699, 45,-1000,-1000,-1000,
+ 1529, 1343,-1000,-1000, 1528,-1000, 1525,-1000,-1000, 1524,
+-1000,-1000, 1521,-1000, 1520,-1000, 1519,-1000, 1518,-1000,
+ 1512,-1000, 1511,-1000, 1509,-1000, 1504,-1000, 1503, 1342,
+ 675, 1341, 668, 1340, 647, 1337, 613,-1000, 1502,-1000,
+ 1501,-1000, 1336, 1335,-1000, 2693, 1012, 1334, 1499,-1000,
+ 398, 354, 1333, 606,-1000, 1247,-1000, 2053, 1332,-1000,
+ 28, 28, 28,-1000,-1000, 2650,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000, 1498,-1000, 1497,-1000, 1496,-1000, 1495,
+-1000,-1000,-1000,-1000, -30, 1494, 948, -65,-1000,-1000,
+-1000, 53,-1000, 887,-1000, 1331, 1329, 1328,-1000, 164,
+ 704, 2188, 257, 616, 416, 541, 518, 466, 322, 460,
+ 458, 446,-1000,-1000,-1000,-1000, 430, 153, -22, -65,
+-1000, 1326, 1207, 1265,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000, 38,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000,-1000, 319, 378, 333, 272,-1000,-1000,
+-1000, 1493, 1325,-1000,-1000,-1000,-1000,-1000,-1000,-1000,
+-1000,-1000,-1000,-1000,-1000,-1000,-1000,-1000, 1490, 53,
+-1000,-1000,-1000,-1000,-1000, -65, -435, 28, 1227, 1316,
+ -199, 1315,-1000,-1000, 216,-1000, 3547, 2693, -45, -22,
+ 1012, 1489, -65, 1311,-1000
+};
+
+YYSTATIC YYCONST short YYFARDATA YYPGO[] = {
+ 0, 53, 57, 6, 1900, 43, 40, 29, 1899, 0,
+ 1898, 1897, 1896, 195, 50, 1895, 1893, 2, 1892, 48,
+ 38, 1, 27, 30, 31, 4, 1890, 45, 22, 59,
+ 1889, 136, 39, 9, 25, 7, 13, 1888, 41, 1887,
+ 14, 26, 1884, 1883, 5, 3, 8, 10, 1882, 1877,
+ 1876, 1875, 32, 33, 70, 1873, 1872, 1871, 1870, 12,
+ 1869, 1868, 11, 1867, 35, 1866, 18, 36, 16, 24,
+ 42, 23, 458, 65, 1276, 52, 127, 1864, 1863, 1848,
+ 1847, 1846, 1845, 19, 34, 1844, 1353, 1837, 1836, 28,
+ 784, 119, 1835, 47, 1245, 1834, 1831, 1830, 1829, 1828,
+ 1825, 1824, 1817, 1815, 1813, 1812, 1811, 1796, 1795, 1033,
+ 1794, 64, 62, 1793, 58, 150, 56, 76, 1790, 1789,
+ 49, 1788, 1787, 1786, 1785, 1784, 1783, 61, 1782, 1781,
+ 1780, 66, 114, 44, 1778, 15, 284, 1775, 1771, 1770,
+ 1758, 1757, 1755, 1754, 1753, 1752, 1751, 1748, 1747, 770,
+ 1746, 1745, 1743, 1742, 1741, 1734, 1713, 1712, 60, 1711,
+ 1710, 113, 1709, 1708, 1707, 98, 1706, 1704, 1703, 1702,
+ 1701, 1700, 1699, 69, 1696, 67, 1698, 63, 1695, 484,
+ 1693, 1692, 1688, 1686, 1685, 1473
+};
+YYSTATIC YYCONST yyr_t YYFARDATA YYR1[]={
+
+ 0, 109, 109, 110, 110, 110, 110, 110, 110, 110,
+ 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
+ 110, 110, 110, 110, 110, 110, 110, 110, 110, 136,
+ 136, 36, 36, 133, 133, 133, 2, 2, 1, 1,
+ 1, 9, 24, 24, 23, 23, 23, 134, 134, 134,
+ 134, 134, 135, 135, 135, 135, 135, 135, 135, 135,
+ 135, 93, 93, 93, 93, 94, 94, 94, 94, 10,
+ 11, 73, 72, 72, 59, 61, 61, 61, 62, 62,
+ 62, 65, 65, 132, 132, 132, 60, 60, 60, 60,
+ 60, 60, 130, 130, 130, 119, 12, 12, 12, 12,
+ 12, 12, 118, 137, 113, 138, 139, 111, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 140, 140, 141, 141, 112,
+ 112, 142, 142, 56, 56, 57, 57, 69, 69, 18,
+ 18, 18, 18, 18, 19, 19, 68, 68, 67, 67,
+ 58, 21, 21, 22, 143, 143, 143, 143, 143, 143,
+ 143, 143, 143, 143, 143, 143, 143, 143, 143, 143,
+ 143, 143, 143, 116, 79, 79, 79, 79, 79, 79,
+ 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
+ 4, 4, 35, 35, 16, 16, 75, 75, 75, 75,
+ 75, 75, 75, 7, 7, 7, 7, 8, 8, 8,
+ 8, 8, 8, 8, 76, 74, 74, 74, 74, 74,
+ 74, 144, 144, 81, 81, 81, 145, 145, 150, 150,
+ 150, 150, 150, 150, 150, 150, 146, 82, 82, 82,
+ 147, 147, 151, 151, 151, 151, 151, 151, 151, 152,
+ 38, 38, 34, 34, 153, 114, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+ 78, 78, 78, 78, 78, 78, 78, 78, 78, 83,
+ 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
+ 83, 83, 83, 83, 83, 3, 3, 3, 13, 13,
+ 13, 13, 13, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 154, 115,
+ 115, 155, 155, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 155, 155, 155, 158, 159, 156, 161, 161,
+ 160, 160, 160, 163, 162, 162, 162, 162, 166, 166,
+ 166, 169, 164, 167, 168, 165, 165, 165, 117, 170,
+ 170, 172, 172, 172, 171, 171, 173, 173, 14, 14,
+ 174, 174, 174, 174, 174, 174, 174, 174, 174, 174,
+ 174, 174, 174, 174, 174, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 41, 41, 41, 175, 31, 31, 32, 32, 39,
+ 39, 39, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 42, 42,
+ 42, 43, 43, 43, 47, 47, 46, 46, 45, 45,
+ 44, 44, 48, 48, 49, 49, 49, 50, 50, 50,
+ 50, 51, 51, 149, 95, 96, 97, 98, 99, 100,
+ 101, 102, 103, 104, 105, 106, 107, 108, 157, 157,
+ 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
+ 157, 157, 157, 157, 157, 157, 157, 157, 157, 157,
+ 157, 6, 6, 6, 6, 6, 53, 53, 54, 54,
+ 55, 55, 25, 25, 26, 26, 27, 27, 27, 70,
+ 70, 70, 70, 70, 70, 70, 70, 70, 70, 5,
+ 5, 71, 71, 71, 71, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+ 20, 20, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 52, 52, 52, 52, 52,
+ 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+ 52, 52, 52, 30, 30, 29, 29, 29, 29, 29,
+ 131, 131, 131, 131, 131, 131, 64, 64, 64, 63,
+ 63, 87, 87, 84, 84, 85, 17, 17, 37, 37,
+ 37, 37, 37, 37, 37, 37, 86, 86, 86, 86,
+ 86, 86, 86, 86, 86, 86, 86, 86, 86, 86,
+ 86, 176, 176, 120, 120, 120, 120, 120, 120, 120,
+ 120, 120, 120, 120, 121, 121, 88, 88, 89, 89,
+ 177, 122, 90, 90, 90, 90, 90, 90, 90, 90,
+ 90, 90, 123, 123, 178, 178, 178, 66, 66, 179,
+ 179, 179, 179, 179, 179, 180, 182, 181, 124, 124,
+ 125, 125, 183, 183, 183, 183, 126, 148, 91, 91,
+ 91, 91, 91, 91, 91, 91, 91, 91, 127, 127,
+ 184, 184, 184, 184, 184, 184, 184, 128, 128, 92,
+ 92, 92, 129, 129, 185, 185, 185, 185 };
+YYSTATIC YYCONST yyr_t YYFARDATA YYR2[]={
+
+ 0, 0, 2, 4, 4, 3, 1, 1, 1, 1,
+ 1, 1, 4, 4, 4, 4, 1, 1, 1, 2,
+ 2, 3, 2, 2, 1, 1, 1, 4, 1, 0,
+ 2, 1, 3, 2, 4, 6, 1, 1, 1, 1,
+ 3, 1, 1, 1, 1, 4, 4, 4, 4, 4,
+ 4, 4, 2, 3, 2, 2, 2, 1, 1, 2,
+ 1, 2, 4, 6, 3, 5, 7, 9, 3, 4,
+ 7, 1, 1, 1, 2, 0, 2, 2, 0, 6,
+ 2, 1, 1, 1, 1, 1, 1, 1, 1, 3,
+ 2, 3, 1, 2, 3, 7, 0, 2, 2, 2,
+ 2, 2, 3, 3, 2, 1, 4, 3, 0, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
+ 3, 2, 2, 2, 5, 0, 2, 0, 2, 0,
+ 2, 3, 1, 0, 1, 1, 3, 0, 3, 1,
+ 1, 1, 1, 1, 0, 2, 4, 3, 0, 2,
+ 3, 0, 1, 5, 3, 4, 4, 4, 1, 1,
+ 1, 1, 1, 2, 2, 4, 13, 22, 1, 1,
+ 5, 3, 4, 7, 0, 2, 2, 2, 2, 2,
+ 2, 2, 5, 2, 2, 2, 2, 2, 2, 5,
+ 0, 2, 0, 2, 0, 3, 9, 9, 7, 7,
+ 1, 1, 1, 2, 2, 1, 4, 0, 1, 1,
+ 2, 2, 2, 2, 4, 2, 5, 3, 2, 2,
+ 1, 4, 3, 0, 2, 2, 0, 2, 2, 2,
+ 2, 2, 1, 1, 1, 1, 9, 0, 2, 2,
+ 0, 2, 2, 2, 2, 1, 1, 1, 1, 1,
+ 0, 4, 1, 3, 1, 13, 0, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 5, 8, 6, 5, 0,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 4, 4, 4, 4, 5, 1, 1, 1, 0, 4,
+ 4, 4, 4, 0, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 5, 1, 0,
+ 2, 2, 1, 2, 4, 5, 1, 1, 1, 1,
+ 2, 1, 1, 1, 1, 1, 4, 6, 4, 4,
+ 11, 1, 5, 3, 5, 3, 1, 2, 2, 1,
+ 2, 4, 4, 1, 2, 2, 2, 2, 2, 2,
+ 2, 1, 2, 1, 1, 1, 4, 4, 2, 4,
+ 2, 0, 1, 1, 3, 1, 3, 1, 0, 3,
+ 5, 4, 3, 5, 5, 5, 5, 5, 5, 2,
+ 2, 2, 2, 2, 2, 4, 4, 4, 4, 4,
+ 4, 4, 4, 5, 5, 5, 5, 4, 4, 4,
+ 4, 4, 4, 3, 2, 0, 1, 1, 2, 1,
+ 1, 1, 1, 4, 4, 5, 4, 4, 4, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 8,
+ 8, 8, 8, 7, 7, 7, 7, 7, 0, 2,
+ 2, 0, 2, 2, 0, 2, 0, 2, 0, 2,
+ 0, 2, 0, 2, 0, 2, 2, 0, 2, 3,
+ 2, 0, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 2, 1, 2,
+ 2, 2, 2, 2, 2, 3, 2, 2, 2, 5,
+ 3, 2, 2, 2, 2, 2, 5, 4, 6, 2,
+ 4, 0, 3, 3, 1, 1, 0, 3, 0, 1,
+ 1, 3, 0, 1, 1, 3, 1, 3, 4, 4,
+ 4, 4, 5, 1, 1, 1, 1, 1, 1, 1,
+ 3, 1, 3, 4, 1, 0, 10, 6, 5, 6,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 2, 2, 2, 2, 1, 1, 1, 1,
+ 2, 3, 4, 6, 5, 1, 1, 1, 1, 1,
+ 1, 1, 2, 2, 1, 2, 2, 4, 1, 2,
+ 1, 2, 1, 2, 1, 2, 1, 2, 1, 1,
+ 0, 5, 0, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 2, 2, 2, 2, 1, 1,
+ 1, 1, 1, 3, 2, 2, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 2, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 1, 3, 2, 3, 4, 2, 2, 2,
+ 5, 5, 7, 4, 3, 2, 3, 2, 1, 1,
+ 2, 3, 2, 1, 2, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 2, 2, 2, 2, 1, 1,
+ 1, 1, 1, 1, 3, 0, 1, 1, 3, 2,
+ 6, 7, 3, 3, 3, 6, 0, 1, 3, 5,
+ 6, 4, 4, 1, 3, 3, 1, 1, 1, 1,
+ 4, 1, 6, 6, 6, 4, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 3, 2, 5, 4, 7, 6, 7,
+ 6, 9, 8, 3, 8, 4, 0, 2, 0, 1,
+ 3, 3, 0, 2, 2, 2, 3, 2, 2, 2,
+ 2, 2, 0, 2, 3, 1, 1, 1, 1, 3,
+ 8, 2, 3, 1, 1, 3, 3, 3, 4, 6,
+ 0, 2, 3, 1, 3, 1, 4, 3, 0, 2,
+ 2, 2, 3, 3, 3, 3, 3, 3, 0, 2,
+ 2, 3, 3, 4, 2, 1, 1, 3, 5, 0,
+ 2, 2, 0, 2, 4, 3, 1, 1 };
+YYSTATIC YYCONST short YYFARDATA YYCHK[]={
+
+-1000,-109,-110,-111,-113,-114,-116,-117,-118,-119,
+-120,-121,-122,-124,-126,-128,-130,-131,-132, 524,
+ 525, 459, 527, 528,-133,-134,-135, 531, 532,-139,
+ 408,-152, 410,-170,-137, 454,-176, 462, 407, 469,
+ 470, 429, -87, 430, -93, -94, 273, 448, 529, 533,
+ 534, 535, 536, 537, 538, 539, 59,-138, 409, 411,
+ 453, 446, 447, 449, -10, -11, 123, 123,-115, 123,
+ 123, 123, 123, -9, 264, -9, 526, -88, -24, 265,
+ 264, -24, 123,-140, 314, -1, -2, 261, 260, 263,
+ -78, -16, 91,-171, 123,-174, 278, 38,-175, 286,
+ 287, 284, 283, 282, 281, 288, -31, -32, 267, 91,
+ -9, -90, 468, 468, -92, -1, 468, -86, 431, 432,
+ 433, 434, 435, 436, 437, 438, 439, 440, 441, 442,
+ 443, 444, 445, -31, -86, 263, -28, -70, -74, -93,
+ -94, 306, 297, 322, 323,-149, 33, 307, 276, 324,
+ -52, 275, 91, -5, -76, 268, 412, 413, 414, 357,
+ 356, 278, 298, 277, 281, 282, 283, 284, 286, 287,
+ 279, 290, 291, 292, 293, 271, -1, 296, -1, -1,
+ -1, -1, 262, -77,-172, 318, 378, 61, -73, 40,
+ -75, -7, -76, 269, 272, 325, 340, -8, 295, 300,
+ 302, 308, -31, -31,-112,-109, 125,-155, 415,-156,
+ 417,-154, 419, 420,-117,-157, -2,-131,-120,-133,
+-132,-135, 471, 457, 507,-158, 506,-160, 418, -95,
+ -96, -97, -98, -99,-108,-100,-101,-102,-103,-104,
+-105,-106,-107,-159,-163, 394, 395, 396, 397, 398,
+ 399, 400, 401, 402, 403, 404, 405, 406, 123, 416,
+-123,-125,-127,-129, -9, -1, 460,-136, -70, -76,
+-141, 315, -71, -70, 91, -28,-149, 46, -7, 328,
+ 329, 330, 331, 332, 326, 346, 352, 337, 364, 365,
+ 366, 367, 368, 369, 370, 350, 377, 294, 371, -79,
+ -9,-173,-174, 42, 40, -31, 40, -14, 91, 40,
+ -14, 40, -14, 40, -14, 40, -14, 40, -14, 40,
+ 41, 267, -9, 263, 58, 44, 262, -1, 353, 354,
+ 355, 472, 378, 474, 475, 476, 477, -90, -91, -1,
+ 329, 330, -1, -71, 41, -36, 61, 288, 262, 44,
+ 389, 91, 38, 42, 358, 359, 360, 60, 389, 389,
+ 389, 389, -70, 306, -70, -75, -7, 33, -9, -1,
+ 280, 279, 289, -28, -1, -76, 42, 470, 47, -28,
+ 270, 272, 281, 282, 283, 284, 40, -36, -1, 329,
+ 330, 322, 345, 334, 335, 337, 338, 339, 340, 341,
+ 342, 343, 344, 361, 354, 336, 351, 326, 370, 294,
+ -2, 40, 61, -72, -71, -74, -28, -7, -7, 40,
+ 301, 303, 304, 305, 41, 41, 125,-143,-114,-111,
+-144,-146,-116,-117,-131,-120,-132, 451, 452,-148,
+ 507,-133,-135, 506, 321, 421, 426, 471, 407, 125,
+ -9, -9, 40, 450, 58, 91, -9, -71, 356, 363,
+ 91,-161,-162,-164,-166,-167,-168, 311,-169, 309,
+ 313, 312, -9, -2, -9, -24, 40, -23, -24, 266,
+ 286, 287, -31, -9, -2, -75, -28, -76, 270, 272,
+ -71, -36, 341,-175, -7, -72, 40,-115,-158, -2,
+ -9, 125,-178, 461,-131,-179,-180, 466, 467,-181,
+-132,-135, 463, 125,-183,-177,-179,-182, 338, 461,
+ 464, 125,-184, 459, 407, 462, 296,-132,-135, 125,
+-185, 459, 462,-132,-135, -89, 419, 125,-136,-142,
+ -71, -1, 470, -7, -1, -13, 40, 40, -28, 328,
+ 329, 330, 331, 376, 370, 326, 478, 364, 365, 366,
+ 367, 374, 375, 294, 93, 125, 44, 40, -2, 41,
+ -23, -9, -23, -24, -9, -9, -9, 93, -9, -9,
+ 473, -1, -1, 330, 329, 327, 336, 389, 40, 61,
+ 43, 123, 40, 40, 263, -1, 93, -30, -29, 275,
+ -9, 40, 40, -54, -55, -28, -1, -1, -1, -1,
+ -70, -28, -9, -1, 280, 93, 93, 93, -1, -1,
+ -71, -1, 91, -9, -69, 60, 329, 330, 331, 364,
+ 365, 366, 40, 61, -36, 123, 40, 41, -71, -3,
+ 372, 373, -1, -9,-115, 123, 123, 123, -9, -9,
+ 123, -71, 356, 363, 363, -81, -82, -91, -25, -26,
+ -27, 275, -13, 40, -9, 58, 274, -7, 91, -1,
+ -9,-161,-165,-158, 310,-165,-165,-165, -71,-158,
+ -2, -9, 40, 40, 41, -71, -1, 40, -31, -28,
+ -6, -2, -9, 125, 316, 316, 465, -31, -66, -9,
+ 42, -36, 61, -31, 61, -31, -31, 61, 61, -1,
+ 468, -9, 468, 40, -1, 468,-177, 44, 93, -1,
+ -28, -28, 91, -9, -36, -83, -1, 40, 40,-173,
+ -36, 41, 41, 93, 41, 41, 41, 41, 41, -12,
+ 263, 44, 58, 389, 329, 330, 331, 364, 365, 366,
+ -1, -84, -85, -36, 123, 262, -64, -63, -71, 306,
+ 44, 93, 44, 275, -71, -71, 62, 44, 42, -5,
+ -5, -5, 93, 274, 41, -68, -19, -18, 43, 45,
+ 306, 323, 372, -9, -59, -61, -73, 274, -53, -22,
+ 60, 41, 125,-112,-145,-147,-127, 274, -7, 91,
+ -1, -71, -71, -1, 370, 326, -7, 370, 326, -1,
+ 41, 44, -28, -25, 93, -9, -3, -1, -28, -9,
+ 93, -2, -9, -9, -24, 274, -36, 41, 40, 41,
+ 44, 44, -2, -9, -9, 41, 58, 40, 41, 40,
+ 41, 41, 40, 40, -5, -1, -9, 317, -1, -31,
+ -71, 93, -38, 478, 503, 504, 505, -9, 41, 389,
+ -83, 41, 386, 341, 342, 343, 387, 388, 301, 303,
+ 304, 305, 390, 393, 294, -4, 317, -34, -33,-153,
+ 479, 481, 482, 483, 484, 276, 277, 281, 282, 283,
+ 284, 286, 287, 257, 279, 290, 291, 292, 293, 485,
+ 486, 487, 489, 490, 491, 492, 493, 494, 495, 334,
+ 496, 280, 289, 336, 497, 341, 488, 356, 389, 501,
+ 271, 123, -9, 41, -14, -14, -14, -14, -14, -14,
+ 317, 283, 284, 455, 456, 458, -9, -9, -1, 41,
+ 44, 61, -59, 125, 44, 61, 263, 263, -29, -9,
+ 41, 41, -28, 40, -5, -1, 62, -58, -1, 40,
+ -19, 41, 125, -62, -40,-135, -41, 298, 363, 297,
+ 286, 287, 284, 283, 282, 281, 293, 292, 291, 290,
+ 279, 278, 277,-175, 61, -3, 40, 40, 91, -54,
+ 125, 125,-150, 422, 423, 424, 425,-120,-132,-133,
+-135, 125,-151, 427, 428, 425,-132,-120,-133,-135,
+ 125, -3, -28, -9, -93, 449, -1, -28, -27, -38,
+ 41, 389, -71, 93, -35, 61, 316, 316, 41, 41,
+ -1, 41, -25, -6, -6, -66, 41, -9, 41, -3,
+ 40, 93, 93, 93, 93, -36, 41, 58, 58, 40,
+ -35, -2, 41, 42, 91, -32, 40, 480, 500, 277,
+ 281, 282, 283, 284, 280, -20, 40, -20, -20, -15,
+ 509, 482, 483, 276, 277, 281, 282, 283, 284, 286,
+ 287, 279, 290, 291, 292, 293, 42, 485, 486, 487,
+ 489, 490, 493, 494, 496, 280, 289, 257, 510, 511,
+ 512, 513, 514, 515, 516, 517, 518, 519, 520, 521,
+ 522, 495, 487, 499, 41, -2, 263, 263, 44, -84,
+ -37, -17, -9, 283, -36, -70, 319, 320, 125, -64,
+ 123, 61, -25, -1, -67, 44, -56, -57, -71, -65,
+-135, 357, 362, 40, 91, 40, 91, 40, 91, 40,
+ 91, 40, 91, 40, 91, 40, 91, 40, 91, 40,
+ 91, 40, 91, 40, 91, 40, 91, 40, 91, 284,
+ 283, 282, 281, 40, 91, 40, 91, -31, -36, 123,
+ 40, -53, -22, -25, -25, -9, 62, -75, -75, -75,
+ -75, -75, -75, -75, 508, -71, 93, -1, -2, -2,
+ 274, -39, -41, -36, 299, 286, 287, 284, 283, 282,
+ 281, 279, 293, 292, 291, 290, 278, 277, -2, -9,
+ 41, 58, -89, -69, -34, -83, 391, 392, 391, 392,
+ -9, 93, -9, 43, 125, -36, 91, 91, 502, 44,
+ 91, 523, 38, 281, 282, 283, 284, 280, -9, 40,
+ 40, -62, 123, 41, -67, -68, 41, 44, -60, -52,
+ 363, 297, 345, 299, 263, -9, 306, -70, 299, -9,
+ -40, -9, -23, -9, -9, -23, -24, -9, -24, -9,
+ -9, -9, -9, -9, -9, -9, -24, -9, -9, -9,
+ -9, -9, -9, -9, 40, 91, 40, 91, 40, 91,
+ 40, 91, -9, -9, -17, -9, 41, -59, 40, 40,
+ 41, 41, 93, -7, 274, 40, -3, 284, 283, 282,
+ 281, -66, 40, 41, 41, 41, 93, 43, -9, 44,
+ -9, -9, 61, -36, 93, 263, -9, 281, 282, 283,
+ -9, 125, -62, -71, -1, 91, 306, -70, 41, 41,
+ 93, 263, 41, 41, 93, 41, 93, 41, 41, 93,
+ 41, 41, 93, 41, 93, 41, 93, 41, 93, 41,
+ 93, 41, 93, 41, 93, 41, 93, 41, 93, -24,
+ -9, -9, -9, -9, -9, -9, -9, 41, 93, 41,
+ 93, 125, -25, -25, 62, -28, -3, -25, -21, -22,
+ 60, 58, -25, -9, 93, -36, 93, 93, -9, 41,
+ 58, 58, 58, 41, 125, 61, 93, 263, 40, 41,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 41, 93, 41, 93, 41, 93, 41, 93,
+ 40, 40, 41, 41, -71, -21, 41, 40, -66, 41,
+ 93, 44, 41, -33, 41, -9, -9, -9, -40, -49,
+ -50, -51, -42, -43, -47, -46, -45, -44, -47, -46,
+ -45, -44, 40, 40, 40, 40, -45, -48, 274, 40,
+ -35, -25, -80, -36, 41, 41, 41, 41, 299, 263,
+ 41, 299, 306, -70, 41, -40, 41, -23, -9, 41,
+ -23, -24, 41, -24, 41, -9, 41, -9, 41, -9,
+ 41, 41, 41, 41, -47, -46, -45, -44, 41, 41,
+ -17, -3, -25, 41, 123, 324, 378, 379, 380, 308,
+ 381, 382, 383, 384, 333, 347, 348, 349, 294, 44,
+ 263, 41, 41, 41, 41, 40, 41, 40, -36, -25,
+ 508, -9, 41, 41, 356, 41, -7, -28, -71, 274,
+ -3, -21, 40, -25, 41 };
+YYSTATIC YYCONST short YYFARDATA YYDEF[]={
+
+ 1, -2, 2, 0, 0, 329, 6, 7, 8, 9,
+ 10, 11, 0, 0, 0, 0, 16, 17, 18, 0,
+ 0, 766, 0, 0, 24, 25, 26, 0, 28, 135,
+ 0, 266, 204, 0, 425, 0, 0, 772, 105, 829,
+ 92, 0, 425, 0, 83, 84, 85, 0, 0, 0,
+ 0, 0, 0, 57, 58, 0, 60, 108, 259, 381,
+ 0, 751, 752, 217, 425, 425, 139, 1, 0, 782,
+ 800, 818, 832, 19, 41, 20, 0, 0, 22, 42,
+ 43, 23, 29, 137, 0, 104, 38, 39, 36, 37,
+ 217, 184, 0, 378, 0, 385, 0, 0, 425, 388,
+ 388, 388, 388, 388, 388, 0, 0, 426, 427, 0,
+ 754, 0, 772, 808, 0, 93, 0, 0, 736, 737,
+ 738, 739, 740, 741, 742, 743, 744, 745, 746, 747,
+ 748, 749, 750, 0, 0, 33, 0, 0, 0, 0,
+ 0, 0, 662, 0, 0, 217, 0, 678, 679, 0,
+ 683, 0, 0, 543, 230, 545, 546, 547, 548, 0,
+ 483, 685, 686, 687, 688, 689, 690, 691, 692, 693,
+ 0, 698, 699, 700, 701, 702, 549, 0, 52, 54,
+ 55, 56, 59, 0, 380, 382, 383, 0, 61, 0,
+ 71, 0, 210, 211, 212, 217, 217, 215, 0, 218,
+ 219, 0, 0, 0, 0, 0, 5, 330, 0, 332,
+ 0, 0, 336, 337, 338, 339, 0, 341, 342, 343,
+ 344, 345, 0, 0, 0, 351, 0, 0, 328, 498,
+ 0, 0, 0, 0, 425, 0, 217, 0, 0, 0,
+ 217, 0, 0, 329, 0, 484, 485, 486, 487, 488,
+ 489, 490, 491, 492, 493, 494, 495, 496, 356, 363,
+ 0, 0, 0, 0, 21, 768, 767, 0, 29, 544,
+ 107, 0, 136, 551, 0, 554, 217, 0, 308, 267,
+ 268, 269, 270, 271, 272, 273, 274, 275, 276, 277,
+ 278, 279, 280, 281, 282, 283, 284, 0, 0, 0,
+ 0, 0, 387, 0, 0, 0, 0, 399, 0, 0,
+ 400, 0, 401, 0, 402, 0, 403, 0, 404, 424,
+ 102, 428, 0, 753, 0, 0, 763, 771, 773, 774,
+ 775, 0, 777, 778, 779, 780, 781, 0, 0, 827,
+ 830, 831, 94, 712, 713, 714, 0, 0, 31, 0,
+ 0, 705, 667, 668, 669, 0, 0, 528, 0, 0,
+ 0, 0, 661, 0, 664, 225, 0, 0, 675, 677,
+ 680, 0, 682, 684, 0, 0, 0, 0, 0, 0,
+ 228, 229, 694, 695, 696, 697, 0, 53, 147, 109,
+ 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 0, 131, 132, 133, 0,
+ 0, 103, 0, 0, 72, 73, 0, 213, 214, 0,
+ 220, 221, 222, 223, 64, 68, 3, 140, 329, 0,
+ 0, 0, 168, 169, 170, 171, 172, 0, 0, 0,
+ 0, 178, 179, 0, 0, 233, 247, 808, 105, 4,
+ 331, 333, -2, 0, 340, 0, 0, 0, 217, 0,
+ 0, 357, 359, 0, 0, 0, 0, 0, 0, 373,
+ 374, 371, 499, 500, 501, 502, 497, 503, 504, 44,
+ 0, 0, 0, 506, 507, 508, 0, 511, 512, 513,
+ 514, 515, 0, 425, 0, 519, 521, 0, 360, 0,
+ 0, 12, 783, 0, 785, 786, 425, 0, 0, 425,
+ 793, 794, 0, 13, 801, 425, 803, 425, 805, 0,
+ 0, 14, 819, 0, 0, 0, 0, 825, 826, 15,
+ 833, 0, 0, 836, 837, 765, 769, 27, 30, 138,
+ 142, 0, 0, 0, 40, 0, 0, 289, 0, 185,
+ 186, 187, 188, 189, 190, 191, 0, 193, 194, 195,
+ 196, 197, 198, 0, 205, 384, 0, 0, 0, 392,
+ 0, 0, 0, 0, 0, 0, 0, 96, 756, 0,
+ 776, 798, 806, 809, 810, 811, 0, 0, 0, 0,
+ 0, 716, 721, 722, 34, 47, 665, 0, 703, 706,
+ 707, 0, 0, 0, 529, 530, 48, 49, 50, 51,
+ 663, 0, 674, 676, 681, 0, 0, 0, 0, 550,
+ 0, -2, 705, 0, 106, 154, 125, 126, 127, 128,
+ 129, 130, 0, 379, 62, 75, 69, 217, 0, 526,
+ 305, 306, -2, 0, 0, 139, 236, 250, 173, 174,
+ 818, 0, 217, 0, 0, 0, 217, 0, 0, 533,
+ 534, 536, 0, -2, 0, 0, 0, 0, 0, 353,
+ 0, 358, 364, 375, 0, 365, 366, 367, 372, 368,
+ 369, 370, 0, 0, 505, 0, -2, 0, 0, 0,
+ 0, 524, 525, 355, 0, 0, 0, 0, 0, 787,
+ 788, 791, 0, 0, 0, 0, 0, 0, 0, 820,
+ 0, 824, 0, 0, 0, 0, 425, 0, 552, 0,
+ 0, 260, 0, 0, 289, 0, 200, 555, 0, 386,
+ 0, 391, 388, 389, 388, 388, 388, 388, 388, 0,
+ 755, 0, 0, 0, 812, 813, 814, 815, 816, 817,
+ 828, 0, 723, 0, 75, 32, 0, 717, 0, 0,
+ 0, 666, 705, 709, 0, 0, 673, 0, 668, 539,
+ 540, 541, 0, 0, 224, 0, 0, 154, 149, 150,
+ 151, 152, 153, 0, 0, 78, 65, 0, 0, 0,
+ 528, 216, 164, 0, 0, 0, 0, 0, 0, 0,
+ 181, 0, 0, -2, 234, 235, 0, 248, 249, 807,
+ 334, 308, 260, 0, 346, 348, 349, 307, 0, 0,
+ 202, 0, 0, 0, 0, 0, 0, 517, -2, 520,
+ 521, 521, 361, 362, 784, 789, 0, 797, 792, 795,
+ 802, 804, 770, 796, 821, 822, 0, 0, 835, 0,
+ 141, 553, 0, 0, 0, 0, 0, 0, 285, 0,
+ 0, 288, 290, 291, 292, 293, 294, 295, 296, 297,
+ 298, 299, 0, 0, 0, 202, 0, 0, 262, 0,
+ 0, 0, 560, 561, 562, 563, 564, 565, 566, 567,
+ 568, 569, 570, 571, 0, 576, 577, 578, 579, 585,
+ 586, 587, 588, 589, 590, 591, 610, 610, 594, 610,
+ 612, 598, 600, 0, 602, 0, 604, 606, 0, 608,
+ 609, 264, 0, 390, 393, 394, 395, 396, 397, 398,
+ 0, 97, 98, 99, 100, 101, 758, 760, 799, 710,
+ 0, 0, 0, 715, 716, 0, 37, 35, 704, 708,
+ 670, 671, 531, -2, 542, 226, 148, 0, 158, 143,
+ 155, 134, 63, 74, 76, 77, 432, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 425, 0, 526, -2, -2, 0, 0,
+ 165, 166, 237, 217, 217, 217, 217, 242, 243, 244,
+ 245, 167, 251, 217, 217, 217, 255, 256, 257, 258,
+ 175, 0, 0, 0, 182, 217, 231, 0, 535, 537,
+ 335, 0, 0, 352, 354, 0, 0, 0, 45, 46,
+ 509, 516, 0, 522, 523, 0, 823, 834, 768, 147,
+ 555, 309, 310, 311, 312, 289, 287, 0, 0, 0,
+ 183, 201, 192, 580, 0, 0, 0, 0, 0, 605,
+ 572, 573, 574, 575, 599, 592, 0, 593, 595, 596,
+ 613, 614, 615, 616, 617, 618, 619, 620, 621, 622,
+ 623, 0, 628, 629, 630, 631, 632, 636, 637, 638,
+ 639, 640, 641, 642, 643, 644, 646, 647, 648, 649,
+ 650, 651, 652, 653, 654, 655, 656, 657, 658, 659,
+ 660, 601, 603, 607, 199, 95, 757, 759, 0, 724,
+ 725, 728, 729, 0, 731, 0, 726, 727, 711, 718,
+ 78, 0, 0, 158, 157, 154, 0, 144, 145, 0,
+ 80, 81, 82, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 66, 75,
+ 70, 0, 0, 0, 0, 0, 527, 238, 239, 240,
+ 241, 252, 253, 254, 217, 0, 180, 0, 538, 347,
+ 0, 203, 429, 430, 431, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 376, 377,
+ 518, 0, 764, 0, 0, 0, 300, 301, 302, 303,
+ 0, 581, 0, 0, 263, 0, 0, 0, 0, 0,
+ 0, 634, 635, 624, 625, 626, 627, 645, 762, 0,
+ 0, 0, 78, 672, 156, 159, 160, 0, 0, 86,
+ 87, 88, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 423, 0, -2, -2,
+ 208, 209, 0, 0, 0, -2, 161, 0, 0, 0,
+ 0, 0, -2, 261, 286, 304, 582, 0, 0, 0,
+ 0, 0, 0, 597, 633, 761, 0, 0, 0, 0,
+ 0, 719, 0, 146, 0, 0, 0, 90, 433, 434,
+ 0, 0, 436, 437, 0, 438, 0, 405, 407, 0,
+ 406, 408, 0, 409, 0, 410, 0, 411, 0, 412,
+ 0, 417, 0, 418, 0, 419, 0, 420, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 421, 0, 422,
+ 0, 67, 0, 0, 163, 0, 161, 0, 0, 162,
+ 0, 0, 0, 0, 584, 0, 558, 555, 0, 730,
+ 0, 0, 0, 735, 720, 0, 91, 89, 474, 435,
+ 477, 481, 458, 461, 464, 466, 468, 470, 464, 466,
+ 468, 470, 413, 0, 414, 0, 415, 0, 416, 0,
+ 468, 472, 206, 207, 0, 0, 202, -2, 790, 313,
+ 583, 0, 557, 559, 611, 0, 0, 0, 79, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 464, 466, 468, 470, 0, 0, 0, -2,
+ 246, 0, 0, 0, 732, 733, 734, 455, 475, 476,
+ 456, 478, 0, 480, 457, 482, 439, 459, 460, 440,
+ 462, 463, 441, 465, 442, 467, 443, 469, 444, 471,
+ 445, 446, 447, 448, 0, 0, 0, 0, 453, 454,
+ 473, 0, 0, 350, 265, 314, 315, 316, 317, 318,
+ 319, 320, 321, 322, 323, 324, 325, 326, 0, 0,
+ 479, 449, 450, 451, 452, -2, 0, 0, 0, 0,
+ 0, 0, 556, 176, 217, 327, 0, 0, 0, 0,
+ 161, 0, -2, 0, 177 };
+#ifdef YYRECOVER
+YYSTATIC YYCONST short yyrecover[] = {
+-1000
+};
+#endif
+
+/* SCCSWHAT( "@(#)yypars.c 3.1 88/11/16 22:00:49 " ) */
+#line 3 "D:\\ProjectK3\\src\\tools\\devdiv\\x86\\yypars.c"
+#if ! defined(YYAPI_PACKAGE)
+/*
+** YYAPI_TOKENNAME : name used for return value of yylex
+** YYAPI_TOKENTYPE : type of the token
+** YYAPI_TOKENEME(t) : the value of the token that the parser should see
+** YYAPI_TOKENNONE : the representation when there is no token
+** YYAPI_VALUENAME : the name of the value of the token
+** YYAPI_VALUETYPE : the type of the value of the token (if null, then the value is derivable from the token itself)
+** YYAPI_VALUEOF(v) : how to get the value of the token.
+*/
+#define YYAPI_TOKENNAME yychar
+#define YYAPI_TOKENTYPE int
+#define YYAPI_TOKENEME(t) (t)
+#define YYAPI_TOKENNONE -1
+#define YYAPI_TOKENSTR(t) (sprintf_s(yytokbuf, _countof(yytokbuf), "%d", t), yytokbuf)
+#define YYAPI_VALUENAME yylval
+#define YYAPI_VALUETYPE YYSTYPE
+#define YYAPI_VALUEOF(v) (v)
+#endif
+#if ! defined(YYAPI_CALLAFTERYYLEX)
+#define YYAPI_CALLAFTERYYLEX
+#endif
+
+# define YYFLAG -1000
+# define YYERROR goto yyerrlab
+# define YYACCEPT return(0)
+# define YYABORT return(1)
+
+#ifdef YYDEBUG /* RRR - 10/9/85 */
+char yytokbuf[20];
+# ifndef YYDBFLG
+# define YYDBFLG (yydebug)
+# endif
+# define yyprintf(a, b, c, d) if (YYDBFLG) YYPRINT(a, b, c, d)
+#else
+# define yyprintf(a, b, c, d)
+#endif
+
+#ifndef YYPRINT
+#define YYPRINT printf
+#endif
+
+/* parser for yacc output */
+
+#ifdef YYDUMP
+int yydump = 1; /* 1 for dumping */
+void yydumpinfo(void);
+#endif
+#ifdef YYDEBUG
+YYSTATIC int yydebug = 0; /* 1 for debugging */
+#endif
+YYSTATIC YYSTYPE yyv[YYMAXDEPTH]; /* where the values are stored */
+YYSTATIC short yys[YYMAXDEPTH]; /* the parse stack */
+
+#if ! defined(YYRECURSIVE)
+YYSTATIC YYAPI_TOKENTYPE YYAPI_TOKENNAME = YYAPI_TOKENNONE;
+#if defined(YYAPI_VALUETYPE)
+// YYSTATIC YYAPI_VALUETYPE YYAPI_VALUENAME; FIX
+#endif
+YYSTATIC int yynerrs = 0; /* number of errors */
+YYSTATIC short yyerrflag = 0; /* error recovery flag */
+#endif
+
+#ifdef YYRECOVER
+/*
+** yyscpy : copy f onto t and return a ptr to the null terminator at the
+** end of t.
+*/
+YYSTATIC char *yyscpy(register char*t, register char*f)
+ {
+ while(*t = *f++)
+ t++;
+ return(t); /* ptr to the null char */
+ }
+#endif
+
+#ifndef YYNEAR
+#define YYNEAR
+#endif
+#ifndef YYPASCAL
+#define YYPASCAL
+#endif
+#ifndef YYLOCAL
+#define YYLOCAL
+#endif
+#if ! defined YYPARSER
+#define YYPARSER yyparse
+#endif
+#if ! defined YYLEX
+#define YYLEX yylex
+#endif
+
+#if defined(YYRECURSIVE)
+
+ YYSTATIC YYAPI_TOKENTYPE YYAPI_TOKENNAME = YYAPI_TOKENNONE;
+ #if defined(YYAPI_VALUETYPE)
+ YYSTATIC YYAPI_VALUETYPE YYAPI_VALUENAME;
+ #endif
+ YYSTATIC int yynerrs = 0; /* number of errors */
+ YYSTATIC short yyerrflag = 0; /* error recovery flag */
+
+ YYSTATIC short yyn;
+ YYSTATIC short yystate = 0;
+ YYSTATIC short *yyps= &yys[-1];
+ YYSTATIC YYSTYPE *yypv= &yyv[-1];
+ YYSTATIC short yyj;
+ YYSTATIC short yym;
+
+#endif
+
+#pragma warning(disable:102)
+YYLOCAL YYNEAR YYPASCAL YYPARSER()
+{
+#if ! defined(YYRECURSIVE)
+
+ register short yyn;
+ short yystate, *yyps;
+ YYSTYPE *yypv;
+ short yyj, yym;
+
+ YYAPI_TOKENNAME = YYAPI_TOKENNONE;
+ yystate = 0;
+ yyps= &yys[-1];
+ yypv= &yyv[-1];
+#endif
+
+#ifdef YYDUMP
+ yydumpinfo();
+#endif
+ yystack: /* put a state and value onto the stack */
+
+#ifdef YYDEBUG
+ if(YYAPI_TOKENNAME == YYAPI_TOKENNONE) {
+ yyprintf( "state %d, token # '%d'\n", yystate, -1, 0 );
+ }
+ else {
+ yyprintf( "state %d, token # '%s'\n", yystate, YYAPI_TOKENSTR(YYAPI_TOKENNAME), 0 );
+ }
+#endif
+ if( ++yyps > &yys[YYMAXDEPTH] ) {
+ yyerror( "yacc stack overflow" );
+ return(1);
+ }
+ *yyps = yystate;
+ ++yypv;
+
+ *yypv = yyval;
+
+yynewstate:
+
+ yyn = YYPACT[yystate];
+
+ if( yyn <= YYFLAG ) { /* simple state, no lookahead */
+ goto yydefault;
+ }
+ if( YYAPI_TOKENNAME == YYAPI_TOKENNONE ) { /* need a lookahead */
+ YYAPI_TOKENNAME = YYLEX();
+ YYAPI_CALLAFTERYYLEX(YYAPI_TOKENNAME);
+ }
+ if( ((yyn += YYAPI_TOKENEME(YYAPI_TOKENNAME)) < 0) || (yyn >= YYLAST) ) {
+ goto yydefault;
+ }
+ if( YYCHK[ yyn = YYACT[ yyn ] ] == YYAPI_TOKENEME(YYAPI_TOKENNAME) ) { /* valid shift */
+ yyval = YYAPI_VALUEOF(YYAPI_VALUENAME);
+ yystate = yyn;
+ yyprintf( "SHIFT: saw token '%s', now in state %4d\n", YYAPI_TOKENSTR(YYAPI_TOKENNAME), yystate, 0 );
+ YYAPI_TOKENNAME = YYAPI_TOKENNONE;
+ if( yyerrflag > 0 ) {
+ --yyerrflag;
+ }
+ goto yystack;
+ }
+
+ yydefault:
+ /* default state action */
+
+ if( (yyn = YYDEF[yystate]) == -2 ) {
+ register YYCONST short *yyxi;
+
+ if( YYAPI_TOKENNAME == YYAPI_TOKENNONE ) {
+ YYAPI_TOKENNAME = YYLEX();
+ YYAPI_CALLAFTERYYLEX(YYAPI_TOKENNAME);
+ yyprintf("LOOKAHEAD: token '%s'\n", YYAPI_TOKENSTR(YYAPI_TOKENNAME), 0, 0);
+ }
+/*
+** search exception table, we find a -1 followed by the current state.
+** if we find one, we'll look through terminal,state pairs. if we find
+** a terminal which matches the current one, we have a match.
+** the exception table is when we have a reduce on a terminal.
+*/
+
+#if YYOPTTIME
+ yyxi = yyexca + yyexcaind[yystate];
+ while(( *yyxi != YYAPI_TOKENEME(YYAPI_TOKENNAME) ) && ( *yyxi >= 0 )){
+ yyxi += 2;
+ }
+#else
+ for(yyxi = yyexca;
+ (*yyxi != (-1)) || (yyxi[1] != yystate);
+ yyxi += 2
+ ) {
+ ; /* VOID */
+ }
+
+ while( *(yyxi += 2) >= 0 ){
+ if( *yyxi == YYAPI_TOKENEME(YYAPI_TOKENNAME) ) {
+ break;
+ }
+ }
+#endif
+ if( (yyn = yyxi[1]) < 0 ) {
+ return(0); /* accept */
+ }
+ }
+
+ if( yyn == 0 ){ /* error */
+ /* error ... attempt to resume parsing */
+
+ switch( yyerrflag ){
+
+ case 0: /* brand new error */
+#ifdef YYRECOVER
+ {
+ register int i,j;
+
+ for(i = 0;
+ (yyrecover[i] != -1000) && (yystate > yyrecover[i]);
+ i += 3
+ ) {
+ ;
+ }
+ if(yystate == yyrecover[i]) {
+ yyprintf("recovered, from state %d to state %d on token # %d\n",
+ yystate,yyrecover[i+2],yyrecover[i+1]
+ );
+ j = yyrecover[i + 1];
+ if(j < 0) {
+ /*
+ ** here we have one of the injection set, so we're not quite
+ ** sure that the next valid thing will be a shift. so we'll
+ ** count it as an error and continue.
+ ** actually we're not absolutely sure that the next token
+ ** we were supposed to get is the one when j > 0. for example,
+ ** for(+) {;} error recovery with yyerrflag always set, stops
+ ** after inserting one ; before the +. at the point of the +,
+ ** we're pretty sure the guy wants a 'for' loop. without
+ ** setting the flag, when we're almost absolutely sure, we'll
+ ** give him one, since the only thing we can shift on this
+ ** error is after finding an expression followed by a +
+ */
+ yyerrflag++;
+ j = -j;
+ }
+ if(yyerrflag <= 1) { /* only on first insertion */
+ yyrecerr(YYAPI_TOKENNAME, j); /* what was, what should be first */
+ }
+ yyval = yyeval(j);
+ yystate = yyrecover[i + 2];
+ goto yystack;
+ }
+ }
+#endif
+ yyerror("syntax error");
+
+ yyerrlab:
+ ++yynerrs;
+
+ case 1:
+ case 2: /* incompletely recovered error ... try again */
+
+ yyerrflag = 3;
+
+ /* find a state where "error" is a legal shift action */
+
+ while ( yyps >= yys ) {
+ yyn = YYPACT[*yyps] + YYERRCODE;
+ if( yyn>= 0 && yyn < YYLAST && YYCHK[YYACT[yyn]] == YYERRCODE ){
+ yystate = YYACT[yyn]; /* simulate a shift of "error" */
+ yyprintf( "SHIFT 'error': now in state %4d\n", yystate, 0, 0 );
+ goto yystack;
+ }
+ yyn = YYPACT[*yyps];
+
+ /* the current yyps has no shift onn "error", pop stack */
+
+ yyprintf( "error recovery pops state %4d, uncovers %4d\n", *yyps, yyps[-1], 0 );
+ --yyps;
+ --yypv;
+ }
+
+ /* there is no state on the stack with an error shift ... abort */
+
+ yyabort:
+ return(1);
+
+
+ case 3: /* no shift yet; clobber input char */
+
+ yyprintf( "error recovery discards token '%s'\n", YYAPI_TOKENSTR(YYAPI_TOKENNAME), 0, 0 );
+
+ if( YYAPI_TOKENEME(YYAPI_TOKENNAME) == 0 ) goto yyabort; /* don't discard EOF, quit */
+ YYAPI_TOKENNAME = YYAPI_TOKENNONE;
+ goto yynewstate; /* try again in the same state */
+ }
+ }
+
+ /* reduction by production yyn */
+yyreduce:
+ {
+ register YYSTYPE *yypvt;
+ yypvt = yypv;
+ yyps -= YYR2[yyn];
+ yypv -= YYR2[yyn];
+ yyval = yypv[1];
+ yyprintf("REDUCE: rule %4d, popped %2d tokens, uncovered state %4d, ",yyn, YYR2[yyn], *yyps);
+ yym = yyn;
+ yyn = YYR1[yyn]; /* consult goto table to find next state */
+ yyj = YYPGO[yyn] + *yyps + 1;
+ if( (yyj >= YYLAST) || (YYCHK[ yystate = YYACT[yyj] ] != -yyn) ) {
+ yystate = YYACT[YYPGO[yyn]];
+ }
+ yyprintf("goto state %4d\n", yystate, 0, 0);
+#ifdef YYDUMP
+ yydumpinfo();
+#endif
+ switch(yym){
+
+case 3:
+#line 189 "asmparse.y"
+{ PASM->EndClass(); } break;
+case 4:
+#line 190 "asmparse.y"
+{ PASM->EndNameSpace(); } break;
+case 5:
+#line 191 "asmparse.y"
+{ if(PASM->m_pCurMethod->m_ulLines[1] ==0)
+ { PASM->m_pCurMethod->m_ulLines[1] = PASM->m_ulCurLine;
+ PASM->m_pCurMethod->m_ulColumns[1]=PASM->m_ulCurColumn;}
+ PASM->EndMethod(); } break;
+case 12:
+#line 201 "asmparse.y"
+{ PASMM->EndAssembly(); } break;
+case 13:
+#line 202 "asmparse.y"
+{ PASMM->EndAssembly(); } break;
+case 14:
+#line 203 "asmparse.y"
+{ PASMM->EndComType(); } break;
+case 15:
+#line 204 "asmparse.y"
+{ PASMM->EndManifestRes(); } break;
+case 19:
+#line 208 "asmparse.y"
+{
+#ifdef _PREFAST_
+#pragma warning(push)
+#pragma warning(disable:22011) // Suppress PREFast warning about integer overflow/underflow
+#endif
+ PASM->m_dwSubsystem = yypvt[-0].int32;
+#ifdef _PREFAST_
+#pragma warning(pop)
+#endif
+ } break;
+case 20:
+#line 218 "asmparse.y"
+{ PASM->m_dwComImageFlags = yypvt[-0].int32; } break;
+case 21:
+#line 219 "asmparse.y"
+{ PASM->m_dwFileAlignment = yypvt[-0].int32;
+ if((yypvt[-0].int32 & (yypvt[-0].int32 - 1))||(yypvt[-0].int32 < 0x200)||(yypvt[-0].int32 > 0x10000))
+ PASM->report->error("Invalid file alignment, must be power of 2 from 0x200 to 0x10000\n");} break;
+case 22:
+#line 222 "asmparse.y"
+{ PASM->m_stBaseAddress = (ULONGLONG)(*(yypvt[-0].int64)); delete yypvt[-0].int64;
+ if(PASM->m_stBaseAddress & 0xFFFF)
+ PASM->report->error("Invalid image base, must be 0x10000-aligned\n");} break;
+case 23:
+#line 225 "asmparse.y"
+{ PASM->m_stSizeOfStackReserve = (size_t)(*(yypvt[-0].int64)); delete yypvt[-0].int64; } break;
+case 28:
+#line 230 "asmparse.y"
+{ PASM->m_fIsMscorlib = TRUE; } break;
+case 31:
+#line 237 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; } break;
+case 32:
+#line 238 "asmparse.y"
+{ yyval.binstr = yypvt[-2].binstr; yyval.binstr->append(yypvt[-0].binstr); delete yypvt[-0].binstr; } break;
+case 33:
+#line 241 "asmparse.y"
+{ LPCSTRToGuid(yypvt[-0].string,&(PASM->m_guidLang)); } break;
+case 34:
+#line 242 "asmparse.y"
+{ LPCSTRToGuid(yypvt[-2].string,&(PASM->m_guidLang));
+ LPCSTRToGuid(yypvt[-0].string,&(PASM->m_guidLangVendor));} break;
+case 35:
+#line 244 "asmparse.y"
+{ LPCSTRToGuid(yypvt[-4].string,&(PASM->m_guidLang));
+ LPCSTRToGuid(yypvt[-2].string,&(PASM->m_guidLangVendor));
+ LPCSTRToGuid(yypvt[-2].string,&(PASM->m_guidDoc));} break;
+case 36:
+#line 249 "asmparse.y"
+{ yyval.string = yypvt[-0].string; } break;
+case 37:
+#line 250 "asmparse.y"
+{ yyval.string = yypvt[-0].string; } break;
+case 38:
+#line 253 "asmparse.y"
+{ yyval.string = yypvt[-0].string; } break;
+case 39:
+#line 254 "asmparse.y"
+{ yyval.string = yypvt[-0].string; } break;
+case 40:
+#line 255 "asmparse.y"
+{ yyval.string = newStringWDel(yypvt[-2].string, '.', yypvt[-0].string); } break;
+case 41:
+#line 258 "asmparse.y"
+{ yyval.int32 = yypvt[-0].int32; } break;
+case 42:
+#line 261 "asmparse.y"
+{ yyval.int64 = yypvt[-0].int64; } break;
+case 43:
+#line 262 "asmparse.y"
+{ yyval.int64 = neg ? new __int64(yypvt[-0].int32) : new __int64((unsigned)yypvt[-0].int32); } break;
+case 44:
+#line 265 "asmparse.y"
+{ yyval.float64 = yypvt[-0].float64; } break;
+case 45:
+#line 266 "asmparse.y"
+{ float f; *((__int32*) (&f)) = yypvt[-1].int32; yyval.float64 = new double(f); } break;
+case 46:
+#line 267 "asmparse.y"
+{ yyval.float64 = (double*) yypvt[-1].int64; } break;
+case 47:
+#line 271 "asmparse.y"
+{ PASM->AddTypeDef(yypvt[-2].binstr,yypvt[-0].string); } break;
+case 48:
+#line 272 "asmparse.y"
+{ PASM->AddTypeDef(yypvt[-2].token,yypvt[-0].string); } break;
+case 49:
+#line 273 "asmparse.y"
+{ PASM->AddTypeDef(yypvt[-2].token,yypvt[-0].string); } break;
+case 50:
+#line 274 "asmparse.y"
+{ yypvt[-2].cad->tkOwner = 0; PASM->AddTypeDef(yypvt[-2].cad,yypvt[-0].string); } break;
+case 51:
+#line 275 "asmparse.y"
+{ PASM->AddTypeDef(yypvt[-2].cad,yypvt[-0].string); } break;
+case 52:
+#line 280 "asmparse.y"
+{ DefineVar(yypvt[-0].string, NULL); } break;
+case 53:
+#line 281 "asmparse.y"
+{ DefineVar(yypvt[-1].string, yypvt[-0].binstr); } break;
+case 54:
+#line 282 "asmparse.y"
+{ UndefVar(yypvt[-0].string); } break;
+case 55:
+#line 283 "asmparse.y"
+{ SkipToken = !IsVarDefined(yypvt[-0].string);
+ IfEndif++;
+ } break;
+case 56:
+#line 286 "asmparse.y"
+{ SkipToken = IsVarDefined(yypvt[-0].string);
+ IfEndif++;
+ } break;
+case 57:
+#line 289 "asmparse.y"
+{ if(IfEndif == 1) SkipToken = !SkipToken;} break;
+case 58:
+#line 290 "asmparse.y"
+{ if(IfEndif == 0)
+ PASM->report->error("Unmatched #endif\n");
+ else IfEndif--;
+ } break;
+case 59:
+#line 294 "asmparse.y"
+{ _ASSERTE(!"yylex should have dealt with this"); } break;
+case 60:
+#line 295 "asmparse.y"
+{ } break;
+case 61:
+#line 299 "asmparse.y"
+{ yyval.cad = new CustomDescr(PASM->m_tkCurrentCVOwner, yypvt[-0].token, NULL); } break;
+case 62:
+#line 300 "asmparse.y"
+{ yyval.cad = new CustomDescr(PASM->m_tkCurrentCVOwner, yypvt[-2].token, yypvt[-0].binstr); } break;
+case 63:
+#line 301 "asmparse.y"
+{ yyval.cad = new CustomDescr(PASM->m_tkCurrentCVOwner, yypvt[-4].token, yypvt[-1].binstr); } break;
+case 64:
+#line 302 "asmparse.y"
+{ yyval.cad = new CustomDescr(PASM->m_tkCurrentCVOwner, yypvt[-2].int32, yypvt[-1].binstr); } break;
+case 65:
+#line 305 "asmparse.y"
+{ yyval.cad = new CustomDescr(yypvt[-2].token, yypvt[-0].token, NULL); } break;
+case 66:
+#line 306 "asmparse.y"
+{ yyval.cad = new CustomDescr(yypvt[-4].token, yypvt[-2].token, yypvt[-0].binstr); } break;
+case 67:
+#line 308 "asmparse.y"
+{ yyval.cad = new CustomDescr(yypvt[-6].token, yypvt[-4].token, yypvt[-1].binstr); } break;
+case 68:
+#line 309 "asmparse.y"
+{ yyval.cad = new CustomDescr(PASM->m_tkCurrentCVOwner, yypvt[-2].int32, yypvt[-1].binstr); } break;
+case 69:
+#line 312 "asmparse.y"
+{ yyval.int32 = yypvt[-2].token; bParsingByteArray = TRUE; } break;
+case 70:
+#line 316 "asmparse.y"
+{ PASM->m_pCustomDescrList = NULL;
+ PASM->m_tkCurrentCVOwner = yypvt[-4].token;
+ yyval.int32 = yypvt[-2].token; bParsingByteArray = TRUE; } break;
+case 71:
+#line 321 "asmparse.y"
+{ yyval.token = yypvt[-0].token; } break;
+case 72:
+#line 324 "asmparse.y"
+{ yyval.token = yypvt[-0].token; } break;
+case 73:
+#line 325 "asmparse.y"
+{ yyval.token = yypvt[-0].token; } break;
+case 74:
+#line 329 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr;
+ yyval.binstr->appendInt16(nCustomBlobNVPairs);
+ yyval.binstr->append(yypvt[-0].binstr);
+ nCustomBlobNVPairs = 0; } break;
+case 75:
+#line 335 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt16(VAL16(0x0001)); } break;
+case 76:
+#line 336 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr;
+ yyval.binstr->appendFrom(yypvt[-0].binstr, (*(yypvt[-0].binstr->ptr()) == ELEMENT_TYPE_SZARRAY) ? 2 : 1); } break;
+case 77:
+#line 338 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; } break;
+case 78:
+#line 341 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 79:
+#line 343 "asmparse.y"
+{ yyval.binstr = yypvt[-5].binstr; yyval.binstr->appendInt8(yypvt[-4].int32);
+ yyval.binstr->append(yypvt[-3].binstr);
+ AppendStringWithLength(yyval.binstr,yypvt[-2].string);
+ yyval.binstr->appendFrom(yypvt[-0].binstr, (*(yypvt[-0].binstr->ptr()) == ELEMENT_TYPE_SZARRAY) ? 2 : 1);
+ nCustomBlobNVPairs++; } break;
+case 80:
+#line 348 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; } break;
+case 81:
+#line 351 "asmparse.y"
+{ yyval.int32 = SERIALIZATION_TYPE_FIELD; } break;
+case 82:
+#line 352 "asmparse.y"
+{ yyval.int32 = SERIALIZATION_TYPE_PROPERTY; } break;
+case 83:
+#line 355 "asmparse.y"
+{ if(yypvt[-0].cad->tkOwner && !yypvt[-0].cad->tkInterfacePair)
+ PASM->DefineCV(yypvt[-0].cad);
+ else if(PASM->m_pCustomDescrList)
+ PASM->m_pCustomDescrList->PUSH(yypvt[-0].cad); } break;
+case 84:
+#line 359 "asmparse.y"
+{ PASM->DefineCV(yypvt[-0].cad); } break;
+case 85:
+#line 360 "asmparse.y"
+{ CustomDescr* pNew = new CustomDescr(yypvt[-0].tdd->m_pCA);
+ if(pNew->tkOwner == 0) pNew->tkOwner = PASM->m_tkCurrentCVOwner;
+ if(pNew->tkOwner)
+ PASM->DefineCV(pNew);
+ else if(PASM->m_pCustomDescrList)
+ PASM->m_pCustomDescrList->PUSH(pNew); } break;
+case 86:
+#line 368 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; } break;
+case 87:
+#line 369 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(SERIALIZATION_TYPE_TYPE); } break;
+case 88:
+#line 370 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(SERIALIZATION_TYPE_TAGGED_OBJECT); } break;
+case 89:
+#line 371 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(SERIALIZATION_TYPE_ENUM);
+ AppendStringWithLength(yyval.binstr,yypvt[-0].string); } break;
+case 90:
+#line 373 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(SERIALIZATION_TYPE_ENUM);
+ AppendStringWithLength(yyval.binstr,PASM->ReflectionNotation(yypvt[-0].token)); } break;
+case 91:
+#line 375 "asmparse.y"
+{ yyval.binstr = yypvt[-2].binstr; yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 92:
+#line 380 "asmparse.y"
+{ PASMM->SetModuleName(NULL); PASM->m_tkCurrentCVOwner=1; } break;
+case 93:
+#line 381 "asmparse.y"
+{ PASMM->SetModuleName(yypvt[-0].string); PASM->m_tkCurrentCVOwner=1; } break;
+case 94:
+#line 382 "asmparse.y"
+{ BinStr* pbs = new BinStr();
+ unsigned L = (unsigned)strlen(yypvt[-0].string);
+ memcpy((char*)(pbs->getBuff(L)),yypvt[-0].string,L);
+ PASM->EmitImport(pbs); delete pbs;} break;
+case 95:
+#line 389 "asmparse.y"
+{ /*PASM->SetDataSection(); PASM->EmitDataLabel($7);*/
+ PASM->m_VTFList.PUSH(new VTFEntry((USHORT)yypvt[-4].int32, (USHORT)yypvt[-2].int32, yypvt[-0].string)); } break;
+case 96:
+#line 393 "asmparse.y"
+{ yyval.int32 = 0; } break;
+case 97:
+#line 394 "asmparse.y"
+{ yyval.int32 = yypvt[-1].int32 | COR_VTABLE_32BIT; } break;
+case 98:
+#line 395 "asmparse.y"
+{ yyval.int32 = yypvt[-1].int32 | COR_VTABLE_64BIT; } break;
+case 99:
+#line 396 "asmparse.y"
+{ yyval.int32 = yypvt[-1].int32 | COR_VTABLE_FROM_UNMANAGED; } break;
+case 100:
+#line 397 "asmparse.y"
+{ yyval.int32 = yypvt[-1].int32 | COR_VTABLE_CALL_MOST_DERIVED; } break;
+case 101:
+#line 398 "asmparse.y"
+{ yyval.int32 = yypvt[-1].int32 | COR_VTABLE_FROM_UNMANAGED_RETAIN_APPDOMAIN; } break;
+case 102:
+#line 401 "asmparse.y"
+{ PASM->m_pVTable = yypvt[-1].binstr; } break;
+case 103:
+#line 404 "asmparse.y"
+{ bParsingByteArray = TRUE; } break;
+case 104:
+#line 408 "asmparse.y"
+{ PASM->StartNameSpace(yypvt[-0].string); } break;
+case 105:
+#line 411 "asmparse.y"
+{ newclass = TRUE; } break;
+case 106:
+#line 414 "asmparse.y"
+{ if(yypvt[-0].typarlist) FixupConstraints();
+ PASM->StartClass(yypvt[-1].string, yypvt[-2].classAttr, yypvt[-0].typarlist);
+ TyParFixupList.RESET(false);
+ newclass = FALSE;
+ } break;
+case 107:
+#line 420 "asmparse.y"
+{ PASM->AddClass(); } break;
+case 108:
+#line 423 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) 0; } break;
+case 109:
+#line 424 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-1].classAttr & ~tdVisibilityMask) | tdPublic); } break;
+case 110:
+#line 425 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-1].classAttr & ~tdVisibilityMask) | tdNotPublic); } break;
+case 111:
+#line 426 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | 0x80000000 | tdSealed); } break;
+case 112:
+#line 427 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | 0x40000000); } break;
+case 113:
+#line 428 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | tdInterface | tdAbstract); } break;
+case 114:
+#line 429 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | tdSealed); } break;
+case 115:
+#line 430 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | tdAbstract); } break;
+case 116:
+#line 431 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-1].classAttr & ~tdLayoutMask) | tdAutoLayout); } break;
+case 117:
+#line 432 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-1].classAttr & ~tdLayoutMask) | tdSequentialLayout); } break;
+case 118:
+#line 433 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-1].classAttr & ~tdLayoutMask) | tdExplicitLayout); } break;
+case 119:
+#line 434 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-1].classAttr & ~tdStringFormatMask) | tdAnsiClass); } break;
+case 120:
+#line 435 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-1].classAttr & ~tdStringFormatMask) | tdUnicodeClass); } break;
+case 121:
+#line 436 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-1].classAttr & ~tdStringFormatMask) | tdAutoClass); } break;
+case 122:
+#line 437 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | tdImport); } break;
+case 123:
+#line 438 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | tdSerializable); } break;
+case 124:
+#line 439 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | tdWindowsRuntime); } break;
+case 125:
+#line 440 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-2].classAttr & ~tdVisibilityMask) | tdNestedPublic); } break;
+case 126:
+#line 441 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-2].classAttr & ~tdVisibilityMask) | tdNestedPrivate); } break;
+case 127:
+#line 442 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-2].classAttr & ~tdVisibilityMask) | tdNestedFamily); } break;
+case 128:
+#line 443 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-2].classAttr & ~tdVisibilityMask) | tdNestedAssembly); } break;
+case 129:
+#line 444 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-2].classAttr & ~tdVisibilityMask) | tdNestedFamANDAssem); } break;
+case 130:
+#line 445 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) ((yypvt[-2].classAttr & ~tdVisibilityMask) | tdNestedFamORAssem); } break;
+case 131:
+#line 446 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | tdBeforeFieldInit); } break;
+case 132:
+#line 447 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr | tdSpecialName); } break;
+case 133:
+#line 448 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].classAttr); } break;
+case 134:
+#line 449 "asmparse.y"
+{ yyval.classAttr = (CorRegTypeAttr) (yypvt[-1].int32); } break;
+case 136:
+#line 453 "asmparse.y"
+{ PASM->m_crExtends = yypvt[-0].token; } break;
+case 141:
+#line 464 "asmparse.y"
+{ PASM->AddToImplList(yypvt[-0].token); } break;
+case 142:
+#line 465 "asmparse.y"
+{ PASM->AddToImplList(yypvt[-0].token); } break;
+case 143:
+#line 469 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 144:
+#line 470 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; } break;
+case 145:
+#line 473 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt32(yypvt[-0].token); } break;
+case 146:
+#line 474 "asmparse.y"
+{ yyval.binstr = yypvt[-2].binstr; yyval.binstr->appendInt32(yypvt[-0].token); } break;
+case 147:
+#line 477 "asmparse.y"
+{ yyval.typarlist = NULL; PASM->m_TyParList = NULL;} break;
+case 148:
+#line 478 "asmparse.y"
+{ yyval.typarlist = yypvt[-1].typarlist; PASM->m_TyParList = yypvt[-1].typarlist;} break;
+case 149:
+#line 481 "asmparse.y"
+{ yyval.int32 = gpCovariant; } break;
+case 150:
+#line 482 "asmparse.y"
+{ yyval.int32 = gpContravariant; } break;
+case 151:
+#line 483 "asmparse.y"
+{ yyval.int32 = gpReferenceTypeConstraint; } break;
+case 152:
+#line 484 "asmparse.y"
+{ yyval.int32 = gpNotNullableValueTypeConstraint; } break;
+case 153:
+#line 485 "asmparse.y"
+{ yyval.int32 = gpDefaultConstructorConstraint; } break;
+case 154:
+#line 488 "asmparse.y"
+{ yyval.int32 = 0; } break;
+case 155:
+#line 489 "asmparse.y"
+{ yyval.int32 = yypvt[-1].int32 | yypvt[-0].int32; } break;
+case 156:
+#line 492 "asmparse.y"
+{yyval.typarlist = new TyParList(yypvt[-3].int32, yypvt[-2].binstr, yypvt[-1].string, yypvt[-0].typarlist);} break;
+case 157:
+#line 493 "asmparse.y"
+{yyval.typarlist = new TyParList(yypvt[-2].int32, NULL, yypvt[-1].string, yypvt[-0].typarlist);} break;
+case 158:
+#line 496 "asmparse.y"
+{ yyval.typarlist = NULL; } break;
+case 159:
+#line 497 "asmparse.y"
+{ yyval.typarlist = yypvt[-0].typarlist; } break;
+case 160:
+#line 500 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; } break;
+case 161:
+#line 503 "asmparse.y"
+{ yyval.int32= 0; } break;
+case 162:
+#line 504 "asmparse.y"
+{ yyval.int32 = yypvt[-0].int32; } break;
+case 163:
+#line 507 "asmparse.y"
+{ yyval.int32 = yypvt[-2].int32; } break;
+case 164:
+#line 511 "asmparse.y"
+{ if(PASM->m_pCurMethod->m_ulLines[1] ==0)
+ { PASM->m_pCurMethod->m_ulLines[1] = PASM->m_ulCurLine;
+ PASM->m_pCurMethod->m_ulColumns[1]=PASM->m_ulCurColumn;}
+ PASM->EndMethod(); } break;
+case 165:
+#line 515 "asmparse.y"
+{ PASM->EndClass(); } break;
+case 166:
+#line 516 "asmparse.y"
+{ PASM->EndEvent(); } break;
+case 167:
+#line 517 "asmparse.y"
+{ PASM->EndProp(); } break;
+case 173:
+#line 523 "asmparse.y"
+{ PASM->m_pCurClass->m_ulSize = yypvt[-0].int32; } break;
+case 174:
+#line 524 "asmparse.y"
+{ PASM->m_pCurClass->m_ulPack = yypvt[-0].int32; } break;
+case 175:
+#line 525 "asmparse.y"
+{ PASMM->EndComType(); } break;
+case 176:
+#line 527 "asmparse.y"
+{ BinStr *sig1 = parser->MakeSig(yypvt[-7].int32, yypvt[-6].binstr, yypvt[-1].binstr);
+ BinStr *sig2 = new BinStr(); sig2->append(sig1);
+ PASM->AddMethodImpl(yypvt[-11].token,yypvt[-9].string,sig1,yypvt[-5].token,yypvt[-3].string,sig2);
+ PASM->ResetArgNameList();
+ } break;
+case 177:
+#line 533 "asmparse.y"
+{ PASM->AddMethodImpl(yypvt[-17].token,yypvt[-15].string,
+ (yypvt[-14].int32==0 ? parser->MakeSig(yypvt[-19].int32,yypvt[-18].binstr,yypvt[-12].binstr) :
+ parser->MakeSig(yypvt[-19].int32| IMAGE_CEE_CS_CALLCONV_GENERIC,yypvt[-18].binstr,yypvt[-12].binstr,yypvt[-14].int32)),
+ yypvt[-6].token,yypvt[-4].string,
+ (yypvt[-3].int32==0 ? parser->MakeSig(yypvt[-8].int32,yypvt[-7].binstr,yypvt[-1].binstr) :
+ parser->MakeSig(yypvt[-8].int32| IMAGE_CEE_CS_CALLCONV_GENERIC,yypvt[-7].binstr,yypvt[-1].binstr,yypvt[-3].int32)));
+ PASM->ResetArgNameList();
+ } break;
+case 180:
+#line 543 "asmparse.y"
+{ if((yypvt[-1].int32 > 0) && (yypvt[-1].int32 <= (int)PASM->m_pCurClass->m_NumTyPars))
+ PASM->m_pCustomDescrList = PASM->m_pCurClass->m_TyPars[yypvt[-1].int32-1].CAList();
+ else
+ PASM->report->error("Type parameter index out of range\n");
+ } break;
+case 181:
+#line 548 "asmparse.y"
+{ int n = PASM->m_pCurClass->FindTyPar(yypvt[-0].string);
+ if(n >= 0)
+ PASM->m_pCustomDescrList = PASM->m_pCurClass->m_TyPars[n].CAList();
+ else
+ PASM->report->error("Type parameter '%s' undefined\n",yypvt[-0].string);
+ } break;
+case 182:
+#line 554 "asmparse.y"
+{ yypvt[-0].cad->tkInterfacePair = yypvt[-1].token;
+ if(PASM->m_pCustomDescrList)
+ PASM->m_pCustomDescrList->PUSH(yypvt[-0].cad);
+ } break;
+case 183:
+#line 562 "asmparse.y"
+{ yypvt[-3].binstr->insertInt8(IMAGE_CEE_CS_CALLCONV_FIELD);
+ PASM->AddField(yypvt[-2].string, yypvt[-3].binstr, yypvt[-4].fieldAttr, yypvt[-1].string, yypvt[-0].binstr, yypvt[-5].int32); } break;
+case 184:
+#line 566 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) 0; } break;
+case 185:
+#line 567 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) (yypvt[-1].fieldAttr | fdStatic); } break;
+case 186:
+#line 568 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) ((yypvt[-1].fieldAttr & ~mdMemberAccessMask) | fdPublic); } break;
+case 187:
+#line 569 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) ((yypvt[-1].fieldAttr & ~mdMemberAccessMask) | fdPrivate); } break;
+case 188:
+#line 570 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) ((yypvt[-1].fieldAttr & ~mdMemberAccessMask) | fdFamily); } break;
+case 189:
+#line 571 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) (yypvt[-1].fieldAttr | fdInitOnly); } break;
+case 190:
+#line 572 "asmparse.y"
+{ yyval.fieldAttr = yypvt[-1].fieldAttr; } break;
+case 191:
+#line 573 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) (yypvt[-1].fieldAttr | fdSpecialName); } break;
+case 192:
+#line 586 "asmparse.y"
+{ PASM->m_pMarshal = yypvt[-1].binstr; } break;
+case 193:
+#line 587 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) ((yypvt[-1].fieldAttr & ~mdMemberAccessMask) | fdAssembly); } break;
+case 194:
+#line 588 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) ((yypvt[-1].fieldAttr & ~mdMemberAccessMask) | fdFamANDAssem); } break;
+case 195:
+#line 589 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) ((yypvt[-1].fieldAttr & ~mdMemberAccessMask) | fdFamORAssem); } break;
+case 196:
+#line 590 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) ((yypvt[-1].fieldAttr & ~mdMemberAccessMask) | fdPrivateScope); } break;
+case 197:
+#line 591 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) (yypvt[-1].fieldAttr | fdLiteral); } break;
+case 198:
+#line 592 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) (yypvt[-1].fieldAttr | fdNotSerialized); } break;
+case 199:
+#line 593 "asmparse.y"
+{ yyval.fieldAttr = (CorFieldAttr) (yypvt[-1].int32); } break;
+case 200:
+#line 596 "asmparse.y"
+{ yyval.string = 0; } break;
+case 201:
+#line 597 "asmparse.y"
+{ yyval.string = yypvt[-0].string; } break;
+case 202:
+#line 600 "asmparse.y"
+{ yyval.binstr = NULL; } break;
+case 203:
+#line 601 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; } break;
+case 204:
+#line 604 "asmparse.y"
+{ yyval.int32 = 0xFFFFFFFF; } break;
+case 205:
+#line 605 "asmparse.y"
+{ yyval.int32 = yypvt[-1].int32; } break;
+case 206:
+#line 610 "asmparse.y"
+{ PASM->ResetArgNameList();
+ if (yypvt[-3].binstr == NULL)
+ {
+ if((iCallConv)&&((yypvt[-8].int32 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n");
+ yyval.token = PASM->MakeMemberRef(yypvt[-6].token, yypvt[-4].string, parser->MakeSig(yypvt[-8].int32|iCallConv, yypvt[-7].binstr, yypvt[-1].binstr));
+ }
+ else
+ {
+ mdToken mr;
+ if((iCallConv)&&((yypvt[-8].int32 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n");
+ mr = PASM->MakeMemberRef(yypvt[-6].token, yypvt[-4].string,
+ parser->MakeSig(yypvt[-8].int32 | IMAGE_CEE_CS_CALLCONV_GENERIC|iCallConv, yypvt[-7].binstr, yypvt[-1].binstr, corCountArgs(yypvt[-3].binstr)));
+ yyval.token = PASM->MakeMethodSpec(mr,
+ parser->MakeSig(IMAGE_CEE_CS_CALLCONV_INSTANTIATION, 0, yypvt[-3].binstr));
+ }
+ } break;
+case 207:
+#line 627 "asmparse.y"
+{ PASM->ResetArgNameList();
+ if((iCallConv)&&((yypvt[-8].int32 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n");
+ yyval.token = PASM->MakeMemberRef(yypvt[-6].token, yypvt[-4].string,
+ parser->MakeSig(yypvt[-8].int32 | IMAGE_CEE_CS_CALLCONV_GENERIC|iCallConv, yypvt[-7].binstr, yypvt[-1].binstr, yypvt[-3].int32));
+ } break;
+case 208:
+#line 633 "asmparse.y"
+{ PASM->ResetArgNameList();
+ if (yypvt[-3].binstr == NULL)
+ {
+ if((iCallConv)&&((yypvt[-6].int32 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n");
+ yyval.token = PASM->MakeMemberRef(mdTokenNil, yypvt[-4].string, parser->MakeSig(yypvt[-6].int32|iCallConv, yypvt[-5].binstr, yypvt[-1].binstr));
+ }
+ else
+ {
+ mdToken mr;
+ if((iCallConv)&&((yypvt[-6].int32 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n");
+ mr = PASM->MakeMemberRef(mdTokenNil, yypvt[-4].string, parser->MakeSig(yypvt[-6].int32 | IMAGE_CEE_CS_CALLCONV_GENERIC|iCallConv, yypvt[-5].binstr, yypvt[-1].binstr, corCountArgs(yypvt[-3].binstr)));
+ yyval.token = PASM->MakeMethodSpec(mr,
+ parser->MakeSig(IMAGE_CEE_CS_CALLCONV_INSTANTIATION, 0, yypvt[-3].binstr));
+ }
+ } break;
+case 209:
+#line 649 "asmparse.y"
+{ PASM->ResetArgNameList();
+ if((iCallConv)&&((yypvt[-6].int32 & iCallConv) != iCallConv)) parser->warn("'instance' added to method's calling convention\n");
+ yyval.token = PASM->MakeMemberRef(mdTokenNil, yypvt[-4].string, parser->MakeSig(yypvt[-6].int32 | IMAGE_CEE_CS_CALLCONV_GENERIC|iCallConv, yypvt[-5].binstr, yypvt[-1].binstr, yypvt[-3].int32));
+ } break;
+case 210:
+#line 653 "asmparse.y"
+{ yyval.token = yypvt[-0].token; } break;
+case 211:
+#line 654 "asmparse.y"
+{ yyval.token = yypvt[-0].tdd->m_tkTypeSpec; } break;
+case 212:
+#line 655 "asmparse.y"
+{ yyval.token = yypvt[-0].tdd->m_tkTypeSpec; } break;
+case 213:
+#line 658 "asmparse.y"
+{ yyval.int32 = (yypvt[-0].int32 | IMAGE_CEE_CS_CALLCONV_HASTHIS); } break;
+case 214:
+#line 659 "asmparse.y"
+{ yyval.int32 = (yypvt[-0].int32 | IMAGE_CEE_CS_CALLCONV_EXPLICITTHIS); } break;
+case 215:
+#line 660 "asmparse.y"
+{ yyval.int32 = yypvt[-0].int32; } break;
+case 216:
+#line 661 "asmparse.y"
+{ yyval.int32 = yypvt[-1].int32; } break;
+case 217:
+#line 664 "asmparse.y"
+{ yyval.int32 = IMAGE_CEE_CS_CALLCONV_DEFAULT; } break;
+case 218:
+#line 665 "asmparse.y"
+{ yyval.int32 = IMAGE_CEE_CS_CALLCONV_DEFAULT; } break;
+case 219:
+#line 666 "asmparse.y"
+{ yyval.int32 = IMAGE_CEE_CS_CALLCONV_VARARG; } break;
+case 220:
+#line 667 "asmparse.y"
+{ yyval.int32 = IMAGE_CEE_CS_CALLCONV_C; } break;
+case 221:
+#line 668 "asmparse.y"
+{ yyval.int32 = IMAGE_CEE_CS_CALLCONV_STDCALL; } break;
+case 222:
+#line 669 "asmparse.y"
+{ yyval.int32 = IMAGE_CEE_CS_CALLCONV_THISCALL; } break;
+case 223:
+#line 670 "asmparse.y"
+{ yyval.int32 = IMAGE_CEE_CS_CALLCONV_FASTCALL; } break;
+case 224:
+#line 673 "asmparse.y"
+{ yyval.token = yypvt[-1].int32; } break;
+case 225:
+#line 676 "asmparse.y"
+{ yyval.token = yypvt[-0].token;
+ PASM->delArgNameList(PASM->m_firstArgName);
+ PASM->m_firstArgName = parser->m_ANSFirst.POP();
+ PASM->m_lastArgName = parser->m_ANSLast.POP();
+ PASM->SetMemberRefFixup(yypvt[-0].token,iOpcodeLen); } break;
+case 226:
+#line 682 "asmparse.y"
+{ yypvt[-3].binstr->insertInt8(IMAGE_CEE_CS_CALLCONV_FIELD);
+ yyval.token = PASM->MakeMemberRef(yypvt[-2].token, yypvt[-0].string, yypvt[-3].binstr);
+ PASM->SetMemberRefFixup(yyval.token,iOpcodeLen); } break;
+case 227:
+#line 686 "asmparse.y"
+{ yypvt[-1].binstr->insertInt8(IMAGE_CEE_CS_CALLCONV_FIELD);
+ yyval.token = PASM->MakeMemberRef(NULL, yypvt[-0].string, yypvt[-1].binstr);
+ PASM->SetMemberRefFixup(yyval.token,iOpcodeLen); } break;
+case 228:
+#line 689 "asmparse.y"
+{ yyval.token = yypvt[-0].tdd->m_tkTypeSpec;
+ PASM->SetMemberRefFixup(yyval.token,iOpcodeLen); } break;
+case 229:
+#line 691 "asmparse.y"
+{ yyval.token = yypvt[-0].tdd->m_tkTypeSpec;
+ PASM->SetMemberRefFixup(yyval.token,iOpcodeLen); } break;
+case 230:
+#line 693 "asmparse.y"
+{ yyval.token = yypvt[-0].token;
+ PASM->SetMemberRefFixup(yyval.token,iOpcodeLen); } break;
+case 231:
+#line 698 "asmparse.y"
+{ PASM->ResetEvent(yypvt[-0].string, yypvt[-1].token, yypvt[-2].eventAttr); } break;
+case 232:
+#line 699 "asmparse.y"
+{ PASM->ResetEvent(yypvt[-0].string, mdTypeRefNil, yypvt[-1].eventAttr); } break;
+case 233:
+#line 703 "asmparse.y"
+{ yyval.eventAttr = (CorEventAttr) 0; } break;
+case 234:
+#line 704 "asmparse.y"
+{ yyval.eventAttr = yypvt[-1].eventAttr; } break;
+case 235:
+#line 705 "asmparse.y"
+{ yyval.eventAttr = (CorEventAttr) (yypvt[-1].eventAttr | evSpecialName); } break;
+case 238:
+#line 712 "asmparse.y"
+{ PASM->SetEventMethod(0, yypvt[-0].token); } break;
+case 239:
+#line 713 "asmparse.y"
+{ PASM->SetEventMethod(1, yypvt[-0].token); } break;
+case 240:
+#line 714 "asmparse.y"
+{ PASM->SetEventMethod(2, yypvt[-0].token); } break;
+case 241:
+#line 715 "asmparse.y"
+{ PASM->SetEventMethod(3, yypvt[-0].token); } break;
+case 246:
+#line 724 "asmparse.y"
+{ PASM->ResetProp(yypvt[-4].string,
+ parser->MakeSig((IMAGE_CEE_CS_CALLCONV_PROPERTY |
+ (yypvt[-6].int32 & IMAGE_CEE_CS_CALLCONV_HASTHIS)),yypvt[-5].binstr,yypvt[-2].binstr), yypvt[-7].propAttr, yypvt[-0].binstr);} break;
+case 247:
+#line 729 "asmparse.y"
+{ yyval.propAttr = (CorPropertyAttr) 0; } break;
+case 248:
+#line 730 "asmparse.y"
+{ yyval.propAttr = yypvt[-1].propAttr; } break;
+case 249:
+#line 731 "asmparse.y"
+{ yyval.propAttr = (CorPropertyAttr) (yypvt[-1].propAttr | prSpecialName); } break;
+case 252:
+#line 739 "asmparse.y"
+{ PASM->SetPropMethod(0, yypvt[-0].token); } break;
+case 253:
+#line 740 "asmparse.y"
+{ PASM->SetPropMethod(1, yypvt[-0].token); } break;
+case 254:
+#line 741 "asmparse.y"
+{ PASM->SetPropMethod(2, yypvt[-0].token); } break;
+case 259:
+#line 749 "asmparse.y"
+{ PASM->ResetForNextMethod();
+ uMethodBeginLine = PASM->m_ulCurLine;
+ uMethodBeginColumn=PASM->m_ulCurColumn;
+ } break;
+case 260:
+#line 755 "asmparse.y"
+{ yyval.binstr = NULL; } break;
+case 261:
+#line 756 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; } break;
+case 262:
+#line 759 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; } break;
+case 263:
+#line 760 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; } break;
+case 264:
+#line 763 "asmparse.y"
+{ bParsingByteArray = TRUE; } break;
+case 265:
+#line 767 "asmparse.y"
+{ BinStr* sig;
+ if (yypvt[-5].typarlist == NULL) sig = parser->MakeSig(yypvt[-10].int32, yypvt[-8].binstr, yypvt[-3].binstr);
+ else {
+ FixupTyPars(yypvt[-8].binstr);
+ sig = parser->MakeSig(yypvt[-10].int32 | IMAGE_CEE_CS_CALLCONV_GENERIC, yypvt[-8].binstr, yypvt[-3].binstr, yypvt[-5].typarlist->Count());
+ FixupConstraints();
+ }
+ PASM->StartMethod(yypvt[-6].string, sig, yypvt[-11].methAttr, yypvt[-7].binstr, yypvt[-9].int32, yypvt[-5].typarlist);
+ TyParFixupList.RESET(false);
+ PASM->SetImplAttr((USHORT)yypvt[-1].implAttr);
+ PASM->m_pCurMethod->m_ulLines[0] = uMethodBeginLine;
+ PASM->m_pCurMethod->m_ulColumns[0]=uMethodBeginColumn;
+ } break;
+case 266:
+#line 782 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) 0; } break;
+case 267:
+#line 783 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdStatic); } break;
+case 268:
+#line 784 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) ((yypvt[-1].methAttr & ~mdMemberAccessMask) | mdPublic); } break;
+case 269:
+#line 785 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) ((yypvt[-1].methAttr & ~mdMemberAccessMask) | mdPrivate); } break;
+case 270:
+#line 786 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) ((yypvt[-1].methAttr & ~mdMemberAccessMask) | mdFamily); } break;
+case 271:
+#line 787 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdFinal); } break;
+case 272:
+#line 788 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdSpecialName); } break;
+case 273:
+#line 789 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdVirtual); } break;
+case 274:
+#line 790 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdCheckAccessOnOverride); } break;
+case 275:
+#line 791 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdAbstract); } break;
+case 276:
+#line 792 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) ((yypvt[-1].methAttr & ~mdMemberAccessMask) | mdAssem); } break;
+case 277:
+#line 793 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) ((yypvt[-1].methAttr & ~mdMemberAccessMask) | mdFamANDAssem); } break;
+case 278:
+#line 794 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) ((yypvt[-1].methAttr & ~mdMemberAccessMask) | mdFamORAssem); } break;
+case 279:
+#line 795 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) ((yypvt[-1].methAttr & ~mdMemberAccessMask) | mdPrivateScope); } break;
+case 280:
+#line 796 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdHideBySig); } break;
+case 281:
+#line 797 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdNewSlot); } break;
+case 282:
+#line 798 "asmparse.y"
+{ yyval.methAttr = yypvt[-1].methAttr; } break;
+case 283:
+#line 799 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdUnmanagedExport); } break;
+case 284:
+#line 800 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].methAttr | mdRequireSecObject); } break;
+case 285:
+#line 801 "asmparse.y"
+{ yyval.methAttr = (CorMethodAttr) (yypvt[-1].int32); } break;
+case 286:
+#line 803 "asmparse.y"
+{ PASM->SetPinvoke(yypvt[-4].binstr,0,yypvt[-2].binstr,yypvt[-1].pinvAttr);
+ yyval.methAttr = (CorMethodAttr) (yypvt[-7].methAttr | mdPinvokeImpl); } break;
+case 287:
+#line 806 "asmparse.y"
+{ PASM->SetPinvoke(yypvt[-2].binstr,0,NULL,yypvt[-1].pinvAttr);
+ yyval.methAttr = (CorMethodAttr) (yypvt[-5].methAttr | mdPinvokeImpl); } break;
+case 288:
+#line 809 "asmparse.y"
+{ PASM->SetPinvoke(new BinStr(),0,NULL,yypvt[-1].pinvAttr);
+ yyval.methAttr = (CorMethodAttr) (yypvt[-4].methAttr | mdPinvokeImpl); } break;
+case 289:
+#line 813 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) 0; } break;
+case 290:
+#line 814 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmNoMangle); } break;
+case 291:
+#line 815 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmCharSetAnsi); } break;
+case 292:
+#line 816 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmCharSetUnicode); } break;
+case 293:
+#line 817 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmCharSetAuto); } break;
+case 294:
+#line 818 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmSupportsLastError); } break;
+case 295:
+#line 819 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmCallConvWinapi); } break;
+case 296:
+#line 820 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmCallConvCdecl); } break;
+case 297:
+#line 821 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmCallConvStdcall); } break;
+case 298:
+#line 822 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmCallConvThiscall); } break;
+case 299:
+#line 823 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].pinvAttr | pmCallConvFastcall); } break;
+case 300:
+#line 824 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-3].pinvAttr | pmBestFitEnabled); } break;
+case 301:
+#line 825 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-3].pinvAttr | pmBestFitDisabled); } break;
+case 302:
+#line 826 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-3].pinvAttr | pmThrowOnUnmappableCharEnabled); } break;
+case 303:
+#line 827 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-3].pinvAttr | pmThrowOnUnmappableCharDisabled); } break;
+case 304:
+#line 828 "asmparse.y"
+{ yyval.pinvAttr = (CorPinvokeMap) (yypvt[-1].int32); } break;
+case 305:
+#line 831 "asmparse.y"
+{ yyval.string = newString(COR_CTOR_METHOD_NAME); } break;
+case 306:
+#line 832 "asmparse.y"
+{ yyval.string = newString(COR_CCTOR_METHOD_NAME); } break;
+case 307:
+#line 833 "asmparse.y"
+{ yyval.string = yypvt[-0].string; } break;
+case 308:
+#line 836 "asmparse.y"
+{ yyval.int32 = 0; } break;
+case 309:
+#line 837 "asmparse.y"
+{ yyval.int32 = yypvt[-3].int32 | pdIn; } break;
+case 310:
+#line 838 "asmparse.y"
+{ yyval.int32 = yypvt[-3].int32 | pdOut; } break;
+case 311:
+#line 839 "asmparse.y"
+{ yyval.int32 = yypvt[-3].int32 | pdOptional; } break;
+case 312:
+#line 840 "asmparse.y"
+{ yyval.int32 = yypvt[-1].int32 + 1; } break;
+case 313:
+#line 843 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) (miIL | miManaged); } break;
+case 314:
+#line 844 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) ((yypvt[-1].implAttr & 0xFFF4) | miNative); } break;
+case 315:
+#line 845 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) ((yypvt[-1].implAttr & 0xFFF4) | miIL); } break;
+case 316:
+#line 846 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) ((yypvt[-1].implAttr & 0xFFF4) | miOPTIL); } break;
+case 317:
+#line 847 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) ((yypvt[-1].implAttr & 0xFFFB) | miManaged); } break;
+case 318:
+#line 848 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) ((yypvt[-1].implAttr & 0xFFFB) | miUnmanaged); } break;
+case 319:
+#line 849 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].implAttr | miForwardRef); } break;
+case 320:
+#line 850 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].implAttr | miPreserveSig); } break;
+case 321:
+#line 851 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].implAttr | miRuntime); } break;
+case 322:
+#line 852 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].implAttr | miInternalCall); } break;
+case 323:
+#line 853 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].implAttr | miSynchronized); } break;
+case 324:
+#line 854 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].implAttr | miNoInlining); } break;
+case 325:
+#line 855 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].implAttr | miAggressiveInlining); } break;
+case 326:
+#line 856 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].implAttr | miNoOptimization); } break;
+case 327:
+#line 857 "asmparse.y"
+{ yyval.implAttr = (CorMethodImpl) (yypvt[-1].int32); } break;
+case 328:
+#line 860 "asmparse.y"
+{ PASM->delArgNameList(PASM->m_firstArgName); PASM->m_firstArgName = NULL;PASM->m_lastArgName = NULL;
+ } break;
+case 331:
+#line 868 "asmparse.y"
+{ PASM->EmitByte(yypvt[-0].int32); } break;
+case 332:
+#line 869 "asmparse.y"
+{ delete PASM->m_SEHD; PASM->m_SEHD = PASM->m_SEHDstack.POP(); } break;
+case 333:
+#line 870 "asmparse.y"
+{ PASM->EmitMaxStack(yypvt[-0].int32); } break;
+case 334:
+#line 871 "asmparse.y"
+{ PASM->EmitLocals(parser->MakeSig(IMAGE_CEE_CS_CALLCONV_LOCAL_SIG, 0, yypvt[-1].binstr));
+ } break;
+case 335:
+#line 873 "asmparse.y"
+{ PASM->EmitZeroInit();
+ PASM->EmitLocals(parser->MakeSig(IMAGE_CEE_CS_CALLCONV_LOCAL_SIG, 0, yypvt[-1].binstr));
+ } break;
+case 336:
+#line 876 "asmparse.y"
+{ PASM->EmitEntryPoint(); } break;
+case 337:
+#line 877 "asmparse.y"
+{ PASM->EmitZeroInit(); } break;
+case 340:
+#line 880 "asmparse.y"
+{ PASM->AddLabel(PASM->m_CurPC,yypvt[-1].string); /*PASM->EmitLabel($1);*/ } break;
+case 346:
+#line 886 "asmparse.y"
+{ if(PASM->m_pCurMethod->m_dwExportOrdinal == 0xFFFFFFFF)
+ {
+ PASM->m_pCurMethod->m_dwExportOrdinal = yypvt[-1].int32;
+ PASM->m_pCurMethod->m_szExportAlias = NULL;
+ if(PASM->m_pCurMethod->m_wVTEntry == 0) PASM->m_pCurMethod->m_wVTEntry = 1;
+ if(PASM->m_pCurMethod->m_wVTSlot == 0) PASM->m_pCurMethod->m_wVTSlot = yypvt[-1].int32 + 0x8000;
+ }
+ else
+ PASM->report->warn("Duplicate .export directive, ignored\n");
+ } break;
+case 347:
+#line 896 "asmparse.y"
+{ if(PASM->m_pCurMethod->m_dwExportOrdinal == 0xFFFFFFFF)
+ {
+ PASM->m_pCurMethod->m_dwExportOrdinal = yypvt[-3].int32;
+ PASM->m_pCurMethod->m_szExportAlias = yypvt[-0].string;
+ if(PASM->m_pCurMethod->m_wVTEntry == 0) PASM->m_pCurMethod->m_wVTEntry = 1;
+ if(PASM->m_pCurMethod->m_wVTSlot == 0) PASM->m_pCurMethod->m_wVTSlot = yypvt[-3].int32 + 0x8000;
+ }
+ else
+ PASM->report->warn("Duplicate .export directive, ignored\n");
+ } break;
+case 348:
+#line 906 "asmparse.y"
+{ PASM->m_pCurMethod->m_wVTEntry = (WORD)yypvt[-2].int32;
+ PASM->m_pCurMethod->m_wVTSlot = (WORD)yypvt[-0].int32; } break;
+case 349:
+#line 909 "asmparse.y"
+{ PASM->AddMethodImpl(yypvt[-2].token,yypvt[-0].string,NULL,NULL,NULL,NULL); } break;
+case 350:
+#line 912 "asmparse.y"
+{ PASM->AddMethodImpl(yypvt[-6].token,yypvt[-4].string,
+ (yypvt[-3].int32==0 ? parser->MakeSig(yypvt[-8].int32,yypvt[-7].binstr,yypvt[-1].binstr) :
+ parser->MakeSig(yypvt[-8].int32| IMAGE_CEE_CS_CALLCONV_GENERIC,yypvt[-7].binstr,yypvt[-1].binstr,yypvt[-3].int32))
+ ,NULL,NULL,NULL);
+ PASM->ResetArgNameList();
+ } break;
+case 352:
+#line 919 "asmparse.y"
+{ if((yypvt[-1].int32 > 0) && (yypvt[-1].int32 <= (int)PASM->m_pCurMethod->m_NumTyPars))
+ PASM->m_pCustomDescrList = PASM->m_pCurMethod->m_TyPars[yypvt[-1].int32-1].CAList();
+ else
+ PASM->report->error("Type parameter index out of range\n");
+ } break;
+case 353:
+#line 924 "asmparse.y"
+{ int n = PASM->m_pCurMethod->FindTyPar(yypvt[-0].string);
+ if(n >= 0)
+ PASM->m_pCustomDescrList = PASM->m_pCurMethod->m_TyPars[n].CAList();
+ else
+ PASM->report->error("Type parameter '%s' undefined\n",yypvt[-0].string);
+ } break;
+case 354:
+#line 931 "asmparse.y"
+{ if( yypvt[-2].int32 ) {
+ ARG_NAME_LIST* pAN=PASM->findArg(PASM->m_pCurMethod->m_firstArgName, yypvt[-2].int32 - 1);
+ if(pAN)
+ {
+ PASM->m_pCustomDescrList = &(pAN->CustDList);
+ pAN->pValue = yypvt[-0].binstr;
+ }
+ else
+ {
+ PASM->m_pCustomDescrList = NULL;
+ if(yypvt[-0].binstr) delete yypvt[-0].binstr;
+ }
+ } else {
+ PASM->m_pCustomDescrList = &(PASM->m_pCurMethod->m_RetCustDList);
+ PASM->m_pCurMethod->m_pRetValue = yypvt[-0].binstr;
+ }
+ PASM->m_tkCurrentCVOwner = 0;
+ } break;
+case 355:
+#line 951 "asmparse.y"
+{ PASM->m_pCurMethod->CloseScope(); } break;
+case 356:
+#line 954 "asmparse.y"
+{ PASM->m_pCurMethod->OpenScope(); } break;
+case 360:
+#line 965 "asmparse.y"
+{ PASM->m_SEHD->tryTo = PASM->m_CurPC; } break;
+case 361:
+#line 966 "asmparse.y"
+{ PASM->SetTryLabels(yypvt[-2].string, yypvt[-0].string); } break;
+case 362:
+#line 967 "asmparse.y"
+{ if(PASM->m_SEHD) {PASM->m_SEHD->tryFrom = yypvt[-2].int32;
+ PASM->m_SEHD->tryTo = yypvt[-0].int32;} } break;
+case 363:
+#line 971 "asmparse.y"
+{ PASM->NewSEHDescriptor();
+ PASM->m_SEHD->tryFrom = PASM->m_CurPC; } break;
+case 364:
+#line 976 "asmparse.y"
+{ PASM->EmitTry(); } break;
+case 365:
+#line 977 "asmparse.y"
+{ PASM->EmitTry(); } break;
+case 366:
+#line 978 "asmparse.y"
+{ PASM->EmitTry(); } break;
+case 367:
+#line 979 "asmparse.y"
+{ PASM->EmitTry(); } break;
+case 368:
+#line 983 "asmparse.y"
+{ PASM->m_SEHD->sehHandler = PASM->m_CurPC; } break;
+case 369:
+#line 984 "asmparse.y"
+{ PASM->SetFilterLabel(yypvt[-0].string);
+ PASM->m_SEHD->sehHandler = PASM->m_CurPC; } break;
+case 370:
+#line 986 "asmparse.y"
+{ PASM->m_SEHD->sehFilter = yypvt[-0].int32;
+ PASM->m_SEHD->sehHandler = PASM->m_CurPC; } break;
+case 371:
+#line 990 "asmparse.y"
+{ PASM->m_SEHD->sehClause = COR_ILEXCEPTION_CLAUSE_FILTER;
+ PASM->m_SEHD->sehFilter = PASM->m_CurPC; } break;
+case 372:
+#line 994 "asmparse.y"
+{ PASM->m_SEHD->sehClause = COR_ILEXCEPTION_CLAUSE_NONE;
+ PASM->SetCatchClass(yypvt[-0].token);
+ PASM->m_SEHD->sehHandler = PASM->m_CurPC; } break;
+case 373:
+#line 999 "asmparse.y"
+{ PASM->m_SEHD->sehClause = COR_ILEXCEPTION_CLAUSE_FINALLY;
+ PASM->m_SEHD->sehHandler = PASM->m_CurPC; } break;
+case 374:
+#line 1003 "asmparse.y"
+{ PASM->m_SEHD->sehClause = COR_ILEXCEPTION_CLAUSE_FAULT;
+ PASM->m_SEHD->sehHandler = PASM->m_CurPC; } break;
+case 375:
+#line 1007 "asmparse.y"
+{ PASM->m_SEHD->sehHandlerTo = PASM->m_CurPC; } break;
+case 376:
+#line 1008 "asmparse.y"
+{ PASM->SetHandlerLabels(yypvt[-2].string, yypvt[-0].string); } break;
+case 377:
+#line 1009 "asmparse.y"
+{ PASM->m_SEHD->sehHandler = yypvt[-2].int32;
+ PASM->m_SEHD->sehHandlerTo = yypvt[-0].int32; } break;
+case 379:
+#line 1017 "asmparse.y"
+{ PASM->EmitDataLabel(yypvt[-1].string); } break;
+case 381:
+#line 1021 "asmparse.y"
+{ PASM->SetDataSection(); } break;
+case 382:
+#line 1022 "asmparse.y"
+{ PASM->SetTLSSection(); } break;
+case 383:
+#line 1023 "asmparse.y"
+{ PASM->SetILSection(); } break;
+case 388:
+#line 1034 "asmparse.y"
+{ yyval.int32 = 1; } break;
+case 389:
+#line 1035 "asmparse.y"
+{ yyval.int32 = yypvt[-1].int32;
+ if(yypvt[-1].int32 <= 0) { PASM->report->error("Illegal item count: %d\n",yypvt[-1].int32);
+ if(!PASM->OnErrGo) yyval.int32 = 1; }} break;
+case 390:
+#line 1040 "asmparse.y"
+{ PASM->EmitDataString(yypvt[-1].binstr); } break;
+case 391:
+#line 1041 "asmparse.y"
+{ PASM->EmitDD(yypvt[-1].string); } break;
+case 392:
+#line 1042 "asmparse.y"
+{ PASM->EmitData(yypvt[-1].binstr->ptr(),yypvt[-1].binstr->length()); } break;
+case 393:
+#line 1044 "asmparse.y"
+{ float f = (float) (*yypvt[-2].float64); float* p = new (nothrow) float[yypvt[-0].int32];
+ if(p != NULL) {
+ for(int i=0; i < yypvt[-0].int32; i++) p[i] = f;
+ PASM->EmitData(p, sizeof(float)*yypvt[-0].int32); delete yypvt[-2].float64; delete [] p;
+ } else PASM->report->error("Out of memory emitting data block %d bytes\n",
+ sizeof(float)*yypvt[-0].int32); } break;
+case 394:
+#line 1051 "asmparse.y"
+{ double* p = new (nothrow) double[yypvt[-0].int32];
+ if(p != NULL) {
+ for(int i=0; i<yypvt[-0].int32; i++) p[i] = *(yypvt[-2].float64);
+ PASM->EmitData(p, sizeof(double)*yypvt[-0].int32); delete yypvt[-2].float64; delete [] p;
+ } else PASM->report->error("Out of memory emitting data block %d bytes\n",
+ sizeof(double)*yypvt[-0].int32); } break;
+case 395:
+#line 1058 "asmparse.y"
+{ __int64* p = new (nothrow) __int64[yypvt[-0].int32];
+ if(p != NULL) {
+ for(int i=0; i<yypvt[-0].int32; i++) p[i] = *(yypvt[-2].int64);
+ PASM->EmitData(p, sizeof(__int64)*yypvt[-0].int32); delete yypvt[-2].int64; delete [] p;
+ } else PASM->report->error("Out of memory emitting data block %d bytes\n",
+ sizeof(__int64)*yypvt[-0].int32); } break;
+case 396:
+#line 1065 "asmparse.y"
+{ __int32* p = new (nothrow) __int32[yypvt[-0].int32];
+ if(p != NULL) {
+ for(int i=0; i<yypvt[-0].int32; i++) p[i] = yypvt[-2].int32;
+ PASM->EmitData(p, sizeof(__int32)*yypvt[-0].int32); delete [] p;
+ } else PASM->report->error("Out of memory emitting data block %d bytes\n",
+ sizeof(__int32)*yypvt[-0].int32); } break;
+case 397:
+#line 1072 "asmparse.y"
+{ __int16 i = (__int16) yypvt[-2].int32; FAIL_UNLESS(i == yypvt[-2].int32, ("Value %d too big\n", yypvt[-2].int32));
+ __int16* p = new (nothrow) __int16[yypvt[-0].int32];
+ if(p != NULL) {
+ for(int j=0; j<yypvt[-0].int32; j++) p[j] = i;
+ PASM->EmitData(p, sizeof(__int16)*yypvt[-0].int32); delete [] p;
+ } else PASM->report->error("Out of memory emitting data block %d bytes\n",
+ sizeof(__int16)*yypvt[-0].int32); } break;
+case 398:
+#line 1080 "asmparse.y"
+{ __int8 i = (__int8) yypvt[-2].int32; FAIL_UNLESS(i == yypvt[-2].int32, ("Value %d too big\n", yypvt[-2].int32));
+ __int8* p = new (nothrow) __int8[yypvt[-0].int32];
+ if(p != NULL) {
+ for(int j=0; j<yypvt[-0].int32; j++) p[j] = i;
+ PASM->EmitData(p, sizeof(__int8)*yypvt[-0].int32); delete [] p;
+ } else PASM->report->error("Out of memory emitting data block %d bytes\n",
+ sizeof(__int8)*yypvt[-0].int32); } break;
+case 399:
+#line 1087 "asmparse.y"
+{ PASM->EmitData(NULL, sizeof(float)*yypvt[-0].int32); } break;
+case 400:
+#line 1088 "asmparse.y"
+{ PASM->EmitData(NULL, sizeof(double)*yypvt[-0].int32); } break;
+case 401:
+#line 1089 "asmparse.y"
+{ PASM->EmitData(NULL, sizeof(__int64)*yypvt[-0].int32); } break;
+case 402:
+#line 1090 "asmparse.y"
+{ PASM->EmitData(NULL, sizeof(__int32)*yypvt[-0].int32); } break;
+case 403:
+#line 1091 "asmparse.y"
+{ PASM->EmitData(NULL, sizeof(__int16)*yypvt[-0].int32); } break;
+case 404:
+#line 1092 "asmparse.y"
+{ PASM->EmitData(NULL, sizeof(__int8)*yypvt[-0].int32); } break;
+case 405:
+#line 1096 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_R4);
+ float f = (float)(*yypvt[-1].float64);
+ yyval.binstr->appendInt32(*((__int32*)&f)); delete yypvt[-1].float64; } break;
+case 406:
+#line 1099 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_R8);
+ yyval.binstr->appendInt64((__int64 *)yypvt[-1].float64); delete yypvt[-1].float64; } break;
+case 407:
+#line 1101 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_R4);
+ yyval.binstr->appendInt32(yypvt[-1].int32); } break;
+case 408:
+#line 1103 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_R8);
+ yyval.binstr->appendInt64((__int64 *)yypvt[-1].int64); delete yypvt[-1].int64; } break;
+case 409:
+#line 1105 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I8);
+ yyval.binstr->appendInt64((__int64 *)yypvt[-1].int64); delete yypvt[-1].int64; } break;
+case 410:
+#line 1107 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I4);
+ yyval.binstr->appendInt32(yypvt[-1].int32); } break;
+case 411:
+#line 1109 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I2);
+ yyval.binstr->appendInt16(yypvt[-1].int32); } break;
+case 412:
+#line 1111 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I1);
+ yyval.binstr->appendInt8(yypvt[-1].int32); } break;
+case 413:
+#line 1113 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U8);
+ yyval.binstr->appendInt64((__int64 *)yypvt[-1].int64); delete yypvt[-1].int64; } break;
+case 414:
+#line 1115 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U4);
+ yyval.binstr->appendInt32(yypvt[-1].int32); } break;
+case 415:
+#line 1117 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U2);
+ yyval.binstr->appendInt16(yypvt[-1].int32); } break;
+case 416:
+#line 1119 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U1);
+ yyval.binstr->appendInt8(yypvt[-1].int32); } break;
+case 417:
+#line 1121 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U8);
+ yyval.binstr->appendInt64((__int64 *)yypvt[-1].int64); delete yypvt[-1].int64; } break;
+case 418:
+#line 1123 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U4);
+ yyval.binstr->appendInt32(yypvt[-1].int32); } break;
+case 419:
+#line 1125 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U2);
+ yyval.binstr->appendInt16(yypvt[-1].int32); } break;
+case 420:
+#line 1127 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U1);
+ yyval.binstr->appendInt8(yypvt[-1].int32); } break;
+case 421:
+#line 1129 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_CHAR);
+ yyval.binstr->appendInt16(yypvt[-1].int32); } break;
+case 422:
+#line 1131 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_BOOLEAN);
+ yyval.binstr->appendInt8(yypvt[-1].int32);} break;
+case 423:
+#line 1133 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_STRING);
+ yyval.binstr->append(yypvt[-1].binstr); delete yypvt[-1].binstr;} break;
+case 424:
+#line 1137 "asmparse.y"
+{ bParsingByteArray = TRUE; } break;
+case 425:
+#line 1140 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 426:
+#line 1141 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; } break;
+case 427:
+#line 1144 "asmparse.y"
+{ __int8 i = (__int8) yypvt[-0].int32; yyval.binstr = new BinStr(); yyval.binstr->appendInt8(i); } break;
+case 428:
+#line 1145 "asmparse.y"
+{ __int8 i = (__int8) yypvt[-0].int32; yyval.binstr = yypvt[-1].binstr; yyval.binstr->appendInt8(i); } break;
+case 429:
+#line 1149 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; } break;
+case 430:
+#line 1150 "asmparse.y"
+{ yyval.binstr = BinStrToUnicode(yypvt[-0].binstr,true); yyval.binstr->insertInt8(ELEMENT_TYPE_STRING);} break;
+case 431:
+#line 1151 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_CLASS);
+ yyval.binstr->appendInt32(0); } break;
+case 432:
+#line 1156 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; } break;
+case 433:
+#line 1157 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_STRING); yyval.binstr->appendInt8(0xFF); } break;
+case 434:
+#line 1158 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_STRING);
+ AppendStringWithLength(yyval.binstr,yypvt[-1].string); delete [] yypvt[-1].string;} break;
+case 435:
+#line 1160 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(SERIALIZATION_TYPE_TYPE);
+ AppendStringWithLength(yyval.binstr,yypvt[-1].string); delete [] yypvt[-1].string;} break;
+case 436:
+#line 1162 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(SERIALIZATION_TYPE_TYPE);
+ AppendStringWithLength(yyval.binstr,PASM->ReflectionNotation(yypvt[-1].token));} break;
+case 437:
+#line 1164 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(SERIALIZATION_TYPE_TYPE); yyval.binstr->appendInt8(0xFF); } break;
+case 438:
+#line 1165 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt8(SERIALIZATION_TYPE_TAGGED_OBJECT);} break;
+case 439:
+#line 1167 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_R4);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 440:
+#line 1171 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_R8);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 441:
+#line 1175 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_I8);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 442:
+#line 1179 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_I4);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 443:
+#line 1183 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_I2);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 444:
+#line 1187 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_I1);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 445:
+#line 1191 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_U8);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 446:
+#line 1195 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_U4);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 447:
+#line 1199 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_U2);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 448:
+#line 1203 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_U1);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 449:
+#line 1207 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_U8);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 450:
+#line 1211 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_U4);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 451:
+#line 1215 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_U2);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 452:
+#line 1219 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_U1);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 453:
+#line 1223 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_CHAR);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 454:
+#line 1227 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_BOOLEAN);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 455:
+#line 1231 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_STRING);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 456:
+#line 1235 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(SERIALIZATION_TYPE_TYPE);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 457:
+#line 1239 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt32(yypvt[-4].int32);
+ yyval.binstr->insertInt8(SERIALIZATION_TYPE_TAGGED_OBJECT);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 458:
+#line 1245 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 459:
+#line 1246 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr;
+ float f = (float) (*yypvt[-0].float64); yyval.binstr->appendInt32(*((__int32*)&f)); delete yypvt[-0].float64; } break;
+case 460:
+#line 1248 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr;
+ yyval.binstr->appendInt32(yypvt[-0].int32); } break;
+case 461:
+#line 1252 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 462:
+#line 1253 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr;
+ yyval.binstr->appendInt64((__int64 *)yypvt[-0].float64); delete yypvt[-0].float64; } break;
+case 463:
+#line 1255 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr;
+ yyval.binstr->appendInt64((__int64 *)yypvt[-0].int64); delete yypvt[-0].int64; } break;
+case 464:
+#line 1259 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 465:
+#line 1260 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr;
+ yyval.binstr->appendInt64((__int64 *)yypvt[-0].int64); delete yypvt[-0].int64; } break;
+case 466:
+#line 1264 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 467:
+#line 1265 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->appendInt32(yypvt[-0].int32);} break;
+case 468:
+#line 1268 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 469:
+#line 1269 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->appendInt16(yypvt[-0].int32);} break;
+case 470:
+#line 1272 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 471:
+#line 1273 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->appendInt8(yypvt[-0].int32); } break;
+case 472:
+#line 1276 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 473:
+#line 1277 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr;
+ yyval.binstr->appendInt8(yypvt[-0].int32);} break;
+case 474:
+#line 1281 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 475:
+#line 1282 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->appendInt8(0xFF); } break;
+case 476:
+#line 1283 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr;
+ AppendStringWithLength(yyval.binstr,yypvt[-0].string); delete [] yypvt[-0].string;} break;
+case 477:
+#line 1287 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 478:
+#line 1288 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->appendInt8(0xFF); } break;
+case 479:
+#line 1289 "asmparse.y"
+{ yyval.binstr = yypvt[-2].binstr;
+ AppendStringWithLength(yyval.binstr,yypvt[-0].string); delete [] yypvt[-0].string;} break;
+case 480:
+#line 1291 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr;
+ AppendStringWithLength(yyval.binstr,PASM->ReflectionNotation(yypvt[-0].token));} break;
+case 481:
+#line 1295 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 482:
+#line 1296 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->append(yypvt[-0].binstr); delete yypvt[-0].binstr; } break;
+case 483:
+#line 1300 "asmparse.y"
+{ parser->m_ANSFirst.PUSH(PASM->m_firstArgName);
+ parser->m_ANSLast.PUSH(PASM->m_lastArgName);
+ PASM->m_firstArgName = NULL;
+ PASM->m_lastArgName = NULL; } break;
+case 484:
+#line 1306 "asmparse.y"
+{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
+case 485:
+#line 1309 "asmparse.y"
+{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
+case 486:
+#line 1312 "asmparse.y"
+{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
+case 487:
+#line 1315 "asmparse.y"
+{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
+case 488:
+#line 1318 "asmparse.y"
+{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
+case 489:
+#line 1321 "asmparse.y"
+{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
+case 490:
+#line 1324 "asmparse.y"
+{ yyval.instr = SetupInstr(yypvt[-0].opcode);
+ if((!PASM->OnErrGo)&&
+ ((yypvt[-0].opcode == CEE_NEWOBJ)||
+ (yypvt[-0].opcode == CEE_CALLVIRT)))
+ iCallConv = IMAGE_CEE_CS_CALLCONV_HASTHIS;
+ } break;
+case 491:
+#line 1332 "asmparse.y"
+{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
+case 492:
+#line 1335 "asmparse.y"
+{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
+case 493:
+#line 1338 "asmparse.y"
+{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
+case 494:
+#line 1341 "asmparse.y"
+{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
+case 495:
+#line 1344 "asmparse.y"
+{ yyval.instr = SetupInstr(yypvt[-0].opcode); iOpcodeLen = PASM->OpcodeLen(yyval.instr); } break;
+case 496:
+#line 1347 "asmparse.y"
+{ yyval.instr = SetupInstr(yypvt[-0].opcode); } break;
+case 497:
+#line 1350 "asmparse.y"
+{ yyval.instr = yypvt[-1].instr; bParsingByteArray = TRUE; } break;
+case 498:
+#line 1354 "asmparse.y"
+{ PASM->EmitOpcode(yypvt[-0].instr); } break;
+case 499:
+#line 1355 "asmparse.y"
+{ PASM->EmitInstrVar(yypvt[-1].instr, yypvt[-0].int32); } break;
+case 500:
+#line 1356 "asmparse.y"
+{ PASM->EmitInstrVarByName(yypvt[-1].instr, yypvt[-0].string); } break;
+case 501:
+#line 1357 "asmparse.y"
+{ PASM->EmitInstrI(yypvt[-1].instr, yypvt[-0].int32); } break;
+case 502:
+#line 1358 "asmparse.y"
+{ PASM->EmitInstrI8(yypvt[-1].instr, yypvt[-0].int64); } break;
+case 503:
+#line 1359 "asmparse.y"
+{ PASM->EmitInstrR(yypvt[-1].instr, yypvt[-0].float64); delete (yypvt[-0].float64);} break;
+case 504:
+#line 1360 "asmparse.y"
+{ double f = (double) (*yypvt[-0].int64); PASM->EmitInstrR(yypvt[-1].instr, &f); } break;
+case 505:
+#line 1361 "asmparse.y"
+{ unsigned L = yypvt[-1].binstr->length();
+ FAIL_UNLESS(L >= sizeof(float), ("%d hexbytes, must be at least %d\n",
+ L,sizeof(float)));
+ if(L < sizeof(float)) {YYERROR; }
+ else {
+ double f = (L >= sizeof(double)) ? *((double *)(yypvt[-1].binstr->ptr()))
+ : (double)(*(float *)(yypvt[-1].binstr->ptr()));
+ PASM->EmitInstrR(yypvt[-2].instr,&f); }
+ delete yypvt[-1].binstr; } break;
+case 506:
+#line 1370 "asmparse.y"
+{ PASM->EmitInstrBrOffset(yypvt[-1].instr, yypvt[-0].int32); } break;
+case 507:
+#line 1371 "asmparse.y"
+{ PASM->EmitInstrBrTarget(yypvt[-1].instr, yypvt[-0].string); } break;
+case 508:
+#line 1373 "asmparse.y"
+{ PASM->SetMemberRefFixup(yypvt[-0].token,PASM->OpcodeLen(yypvt[-1].instr));
+ PASM->EmitInstrI(yypvt[-1].instr,yypvt[-0].token);
+ PASM->m_tkCurrentCVOwner = yypvt[-0].token;
+ PASM->m_pCustomDescrList = NULL;
+ iCallConv = 0;
+ } break;
+case 509:
+#line 1380 "asmparse.y"
+{ yypvt[-3].binstr->insertInt8(IMAGE_CEE_CS_CALLCONV_FIELD);
+ mdToken mr = PASM->MakeMemberRef(yypvt[-2].token, yypvt[-0].string, yypvt[-3].binstr);
+ PASM->SetMemberRefFixup(mr, PASM->OpcodeLen(yypvt[-4].instr));
+ PASM->EmitInstrI(yypvt[-4].instr,mr);
+ PASM->m_tkCurrentCVOwner = mr;
+ PASM->m_pCustomDescrList = NULL;
+ } break;
+case 510:
+#line 1388 "asmparse.y"
+{ yypvt[-1].binstr->insertInt8(IMAGE_CEE_CS_CALLCONV_FIELD);
+ mdToken mr = PASM->MakeMemberRef(mdTokenNil, yypvt[-0].string, yypvt[-1].binstr);
+ PASM->SetMemberRefFixup(mr, PASM->OpcodeLen(yypvt[-2].instr));
+ PASM->EmitInstrI(yypvt[-2].instr,mr);
+ PASM->m_tkCurrentCVOwner = mr;
+ PASM->m_pCustomDescrList = NULL;
+ } break;
+case 511:
+#line 1395 "asmparse.y"
+{ mdToken mr = yypvt[-0].token;
+ PASM->SetMemberRefFixup(mr, PASM->OpcodeLen(yypvt[-1].instr));
+ PASM->EmitInstrI(yypvt[-1].instr,mr);
+ PASM->m_tkCurrentCVOwner = mr;
+ PASM->m_pCustomDescrList = NULL;
+ } break;
+case 512:
+#line 1401 "asmparse.y"
+{ mdToken mr = yypvt[-0].tdd->m_tkTypeSpec;
+ PASM->SetMemberRefFixup(mr, PASM->OpcodeLen(yypvt[-1].instr));
+ PASM->EmitInstrI(yypvt[-1].instr,mr);
+ PASM->m_tkCurrentCVOwner = mr;
+ PASM->m_pCustomDescrList = NULL;
+ } break;
+case 513:
+#line 1407 "asmparse.y"
+{ mdToken mr = yypvt[-0].tdd->m_tkTypeSpec;
+ PASM->SetMemberRefFixup(mr, PASM->OpcodeLen(yypvt[-1].instr));
+ PASM->EmitInstrI(yypvt[-1].instr,mr);
+ PASM->m_tkCurrentCVOwner = mr;
+ PASM->m_pCustomDescrList = NULL;
+ } break;
+case 514:
+#line 1413 "asmparse.y"
+{ PASM->EmitInstrI(yypvt[-1].instr, yypvt[-0].token);
+ PASM->m_tkCurrentCVOwner = yypvt[-0].token;
+ PASM->m_pCustomDescrList = NULL;
+ } break;
+case 515:
+#line 1417 "asmparse.y"
+{ PASM->EmitInstrStringLiteral(yypvt[-1].instr, yypvt[-0].binstr,TRUE); } break;
+case 516:
+#line 1419 "asmparse.y"
+{ PASM->EmitInstrStringLiteral(yypvt[-4].instr, yypvt[-1].binstr,FALSE); } break;
+case 517:
+#line 1421 "asmparse.y"
+{ PASM->EmitInstrStringLiteral(yypvt[-3].instr, yypvt[-1].binstr,FALSE,TRUE); } break;
+case 518:
+#line 1423 "asmparse.y"
+{ PASM->EmitInstrSig(yypvt[-5].instr, parser->MakeSig(yypvt[-4].int32, yypvt[-3].binstr, yypvt[-1].binstr));
+ PASM->ResetArgNameList();
+ } break;
+case 519:
+#line 1427 "asmparse.y"
+{ PASM->EmitInstrI(yypvt[-1].instr,yypvt[-0].token);
+ PASM->m_tkCurrentCVOwner = yypvt[-0].token;
+ PASM->m_pCustomDescrList = NULL;
+ iOpcodeLen = 0;
+ } break;
+case 520:
+#line 1432 "asmparse.y"
+{ PASM->EmitInstrSwitch(yypvt[-3].instr, yypvt[-1].labels); } break;
+case 521:
+#line 1435 "asmparse.y"
+{ yyval.labels = 0; } break;
+case 522:
+#line 1436 "asmparse.y"
+{ yyval.labels = new Labels(yypvt[-2].string, yypvt[-0].labels, TRUE); } break;
+case 523:
+#line 1437 "asmparse.y"
+{ yyval.labels = new Labels((char *)(UINT_PTR)yypvt[-2].int32, yypvt[-0].labels, FALSE); } break;
+case 524:
+#line 1438 "asmparse.y"
+{ yyval.labels = new Labels(yypvt[-0].string, NULL, TRUE); } break;
+case 525:
+#line 1439 "asmparse.y"
+{ yyval.labels = new Labels((char *)(UINT_PTR)yypvt[-0].int32, NULL, FALSE); } break;
+case 526:
+#line 1443 "asmparse.y"
+{ yyval.binstr = NULL; } break;
+case 527:
+#line 1444 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; } break;
+case 528:
+#line 1447 "asmparse.y"
+{ yyval.binstr = NULL; } break;
+case 529:
+#line 1448 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; } break;
+case 530:
+#line 1451 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; } break;
+case 531:
+#line 1452 "asmparse.y"
+{ yyval.binstr = yypvt[-2].binstr; yyval.binstr->append(yypvt[-0].binstr); delete yypvt[-0].binstr; } break;
+case 532:
+#line 1456 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 533:
+#line 1457 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr;} break;
+case 534:
+#line 1460 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; } break;
+case 535:
+#line 1461 "asmparse.y"
+{ yyval.binstr = yypvt[-2].binstr; yyval.binstr->append(yypvt[-0].binstr); delete yypvt[-0].binstr; } break;
+case 536:
+#line 1464 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_SENTINEL); } break;
+case 537:
+#line 1465 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->append(yypvt[-1].binstr); PASM->addArgName(NULL, yypvt[-1].binstr, yypvt[-0].binstr, yypvt[-2].int32); } break;
+case 538:
+#line 1466 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->append(yypvt[-2].binstr); PASM->addArgName(yypvt[-0].string, yypvt[-2].binstr, yypvt[-1].binstr, yypvt[-3].int32);} break;
+case 539:
+#line 1470 "asmparse.y"
+{ yyval.token = PASM->ResolveClassRef(PASM->GetAsmRef(yypvt[-2].string), yypvt[-0].string, NULL); delete[] yypvt[-2].string;} break;
+case 540:
+#line 1471 "asmparse.y"
+{ yyval.token = PASM->ResolveClassRef(yypvt[-2].token, yypvt[-0].string, NULL); } break;
+case 541:
+#line 1472 "asmparse.y"
+{ yyval.token = PASM->ResolveClassRef(mdTokenNil, yypvt[-0].string, NULL); } break;
+case 542:
+#line 1473 "asmparse.y"
+{ yyval.token = PASM->ResolveClassRef(PASM->GetModRef(yypvt[-2].string),yypvt[-0].string, NULL); delete[] yypvt[-2].string;} break;
+case 543:
+#line 1474 "asmparse.y"
+{ yyval.token = PASM->ResolveClassRef(1,yypvt[-0].string,NULL); } break;
+case 544:
+#line 1475 "asmparse.y"
+{ yyval.token = yypvt[-0].token; } break;
+case 545:
+#line 1476 "asmparse.y"
+{ yyval.token = yypvt[-0].tdd->m_tkTypeSpec; } break;
+case 546:
+#line 1477 "asmparse.y"
+{ if(PASM->m_pCurClass != NULL) yyval.token = PASM->m_pCurClass->m_cl;
+ else { yyval.token = 0; PASM->report->error(".this outside class scope\n"); }
+ } break;
+case 547:
+#line 1480 "asmparse.y"
+{ if(PASM->m_pCurClass != NULL) {
+ yyval.token = PASM->m_pCurClass->m_crExtends;
+ if(RidFromToken(yyval.token) == 0)
+ PASM->report->error(".base undefined\n");
+ } else { yyval.token = 0; PASM->report->error(".base outside class scope\n"); }
+ } break;
+case 548:
+#line 1486 "asmparse.y"
+{ if(PASM->m_pCurClass != NULL) {
+ if(PASM->m_pCurClass->m_pEncloser != NULL) yyval.token = PASM->m_pCurClass->m_pEncloser->m_cl;
+ else { yyval.token = 0; PASM->report->error(".nester undefined\n"); }
+ } else { yyval.token = 0; PASM->report->error(".nester outside class scope\n"); }
+ } break;
+case 549:
+#line 1493 "asmparse.y"
+{ yyval.string = yypvt[-0].string; } break;
+case 550:
+#line 1494 "asmparse.y"
+{ yyval.string = newStringWDel(yypvt[-2].string, NESTING_SEP, yypvt[-0].string); } break;
+case 551:
+#line 1497 "asmparse.y"
+{ yyval.token = yypvt[-0].token;} break;
+case 552:
+#line 1498 "asmparse.y"
+{ yyval.token = PASM->GetAsmRef(yypvt[-1].string); delete[] yypvt[-1].string;} break;
+case 553:
+#line 1499 "asmparse.y"
+{ yyval.token = PASM->GetModRef(yypvt[-1].string); delete[] yypvt[-1].string;} break;
+case 554:
+#line 1500 "asmparse.y"
+{ yyval.token = PASM->ResolveTypeSpec(yypvt[-0].binstr); } break;
+case 555:
+#line 1504 "asmparse.y"
+{ yyval.binstr = new BinStr(); } break;
+case 556:
+#line 1506 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_CUSTOMMARSHALER);
+ corEmitInt(yyval.binstr,yypvt[-7].binstr->length()); yyval.binstr->append(yypvt[-7].binstr);
+ corEmitInt(yyval.binstr,yypvt[-5].binstr->length()); yyval.binstr->append(yypvt[-5].binstr);
+ corEmitInt(yyval.binstr,yypvt[-3].binstr->length()); yyval.binstr->append(yypvt[-3].binstr);
+ corEmitInt(yyval.binstr,yypvt[-1].binstr->length()); yyval.binstr->append(yypvt[-1].binstr);
+ PASM->report->warn("Deprecated 4-string form of custom marshaler, first two strings ignored\n");} break;
+case 557:
+#line 1513 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_CUSTOMMARSHALER);
+ corEmitInt(yyval.binstr,0);
+ corEmitInt(yyval.binstr,0);
+ corEmitInt(yyval.binstr,yypvt[-3].binstr->length()); yyval.binstr->append(yypvt[-3].binstr);
+ corEmitInt(yyval.binstr,yypvt[-1].binstr->length()); yyval.binstr->append(yypvt[-1].binstr); } break;
+case 558:
+#line 1518 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_FIXEDSYSSTRING);
+ corEmitInt(yyval.binstr,yypvt[-1].int32); } break;
+case 559:
+#line 1521 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_FIXEDARRAY);
+ corEmitInt(yyval.binstr,yypvt[-2].int32); yyval.binstr->append(yypvt[-0].binstr); } break;
+case 560:
+#line 1523 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_VARIANT);
+ PASM->report->warn("Deprecated native type 'variant'\n"); } break;
+case 561:
+#line 1525 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_CURRENCY); } break;
+case 562:
+#line 1526 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_SYSCHAR);
+ PASM->report->warn("Deprecated native type 'syschar'\n"); } break;
+case 563:
+#line 1528 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_VOID);
+ PASM->report->warn("Deprecated native type 'void'\n"); } break;
+case 564:
+#line 1530 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_BOOLEAN); } break;
+case 565:
+#line 1531 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_I1); } break;
+case 566:
+#line 1532 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_I2); } break;
+case 567:
+#line 1533 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_I4); } break;
+case 568:
+#line 1534 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_I8); } break;
+case 569:
+#line 1535 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_R4); } break;
+case 570:
+#line 1536 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_R8); } break;
+case 571:
+#line 1537 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_ERROR); } break;
+case 572:
+#line 1538 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_U1); } break;
+case 573:
+#line 1539 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_U2); } break;
+case 574:
+#line 1540 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_U4); } break;
+case 575:
+#line 1541 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_U8); } break;
+case 576:
+#line 1542 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_U1); } break;
+case 577:
+#line 1543 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_U2); } break;
+case 578:
+#line 1544 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_U4); } break;
+case 579:
+#line 1545 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_U8); } break;
+case 580:
+#line 1546 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt8(NATIVE_TYPE_PTR);
+ PASM->report->warn("Deprecated native type '*'\n"); } break;
+case 581:
+#line 1548 "asmparse.y"
+{ yyval.binstr = yypvt[-2].binstr; if(yyval.binstr->length()==0) yyval.binstr->appendInt8(NATIVE_TYPE_MAX);
+ yyval.binstr->insertInt8(NATIVE_TYPE_ARRAY); } break;
+case 582:
+#line 1550 "asmparse.y"
+{ yyval.binstr = yypvt[-3].binstr; if(yyval.binstr->length()==0) yyval.binstr->appendInt8(NATIVE_TYPE_MAX);
+ yyval.binstr->insertInt8(NATIVE_TYPE_ARRAY);
+ corEmitInt(yyval.binstr,0);
+ corEmitInt(yyval.binstr,yypvt[-1].int32);
+ corEmitInt(yyval.binstr,0); } break;
+case 583:
+#line 1555 "asmparse.y"
+{ yyval.binstr = yypvt[-5].binstr; if(yyval.binstr->length()==0) yyval.binstr->appendInt8(NATIVE_TYPE_MAX);
+ yyval.binstr->insertInt8(NATIVE_TYPE_ARRAY);
+ corEmitInt(yyval.binstr,yypvt[-1].int32);
+ corEmitInt(yyval.binstr,yypvt[-3].int32);
+ corEmitInt(yyval.binstr,ntaSizeParamIndexSpecified); } break;
+case 584:
+#line 1560 "asmparse.y"
+{ yyval.binstr = yypvt[-4].binstr; if(yyval.binstr->length()==0) yyval.binstr->appendInt8(NATIVE_TYPE_MAX);
+ yyval.binstr->insertInt8(NATIVE_TYPE_ARRAY);
+ corEmitInt(yyval.binstr,yypvt[-1].int32); } break;
+case 585:
+#line 1563 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_DECIMAL);
+ PASM->report->warn("Deprecated native type 'decimal'\n"); } break;
+case 586:
+#line 1565 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_DATE);
+ PASM->report->warn("Deprecated native type 'date'\n"); } break;
+case 587:
+#line 1567 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_BSTR); } break;
+case 588:
+#line 1568 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_LPSTR); } break;
+case 589:
+#line 1569 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_LPWSTR); } break;
+case 590:
+#line 1570 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_LPTSTR); } break;
+case 591:
+#line 1571 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_OBJECTREF);
+ PASM->report->warn("Deprecated native type 'objectref'\n"); } break;
+case 592:
+#line 1573 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_IUNKNOWN);
+ if(yypvt[-0].int32 != -1) corEmitInt(yyval.binstr,yypvt[-0].int32); } break;
+case 593:
+#line 1575 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_IDISPATCH);
+ if(yypvt[-0].int32 != -1) corEmitInt(yyval.binstr,yypvt[-0].int32); } break;
+case 594:
+#line 1577 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_STRUCT); } break;
+case 595:
+#line 1578 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_INTF);
+ if(yypvt[-0].int32 != -1) corEmitInt(yyval.binstr,yypvt[-0].int32); } break;
+case 596:
+#line 1580 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_SAFEARRAY);
+ corEmitInt(yyval.binstr,yypvt[-0].int32);
+ corEmitInt(yyval.binstr,0);} break;
+case 597:
+#line 1583 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_SAFEARRAY);
+ corEmitInt(yyval.binstr,yypvt[-2].int32);
+ corEmitInt(yyval.binstr,yypvt[-0].binstr->length()); yyval.binstr->append(yypvt[-0].binstr); } break;
+case 598:
+#line 1587 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_INT); } break;
+case 599:
+#line 1588 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_UINT); } break;
+case 600:
+#line 1589 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_UINT); } break;
+case 601:
+#line 1590 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_NESTEDSTRUCT);
+ PASM->report->warn("Deprecated native type 'nested struct'\n"); } break;
+case 602:
+#line 1592 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_BYVALSTR); } break;
+case 603:
+#line 1593 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_ANSIBSTR); } break;
+case 604:
+#line 1594 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_TBSTR); } break;
+case 605:
+#line 1595 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_VARIANTBOOL); } break;
+case 606:
+#line 1596 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_FUNC); } break;
+case 607:
+#line 1597 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_ASANY); } break;
+case 608:
+#line 1598 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(NATIVE_TYPE_LPSTRUCT); } break;
+case 609:
+#line 1599 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->append(yypvt[-0].tdd->m_pbsTypeSpec); } break;
+case 610:
+#line 1602 "asmparse.y"
+{ yyval.int32 = -1; } break;
+case 611:
+#line 1603 "asmparse.y"
+{ yyval.int32 = yypvt[-1].int32; } break;
+case 612:
+#line 1606 "asmparse.y"
+{ yyval.int32 = VT_EMPTY; } break;
+case 613:
+#line 1607 "asmparse.y"
+{ yyval.int32 = VT_NULL; } break;
+case 614:
+#line 1608 "asmparse.y"
+{ yyval.int32 = VT_VARIANT; } break;
+case 615:
+#line 1609 "asmparse.y"
+{ yyval.int32 = VT_CY; } break;
+case 616:
+#line 1610 "asmparse.y"
+{ yyval.int32 = VT_VOID; } break;
+case 617:
+#line 1611 "asmparse.y"
+{ yyval.int32 = VT_BOOL; } break;
+case 618:
+#line 1612 "asmparse.y"
+{ yyval.int32 = VT_I1; } break;
+case 619:
+#line 1613 "asmparse.y"
+{ yyval.int32 = VT_I2; } break;
+case 620:
+#line 1614 "asmparse.y"
+{ yyval.int32 = VT_I4; } break;
+case 621:
+#line 1615 "asmparse.y"
+{ yyval.int32 = VT_I8; } break;
+case 622:
+#line 1616 "asmparse.y"
+{ yyval.int32 = VT_R4; } break;
+case 623:
+#line 1617 "asmparse.y"
+{ yyval.int32 = VT_R8; } break;
+case 624:
+#line 1618 "asmparse.y"
+{ yyval.int32 = VT_UI1; } break;
+case 625:
+#line 1619 "asmparse.y"
+{ yyval.int32 = VT_UI2; } break;
+case 626:
+#line 1620 "asmparse.y"
+{ yyval.int32 = VT_UI4; } break;
+case 627:
+#line 1621 "asmparse.y"
+{ yyval.int32 = VT_UI8; } break;
+case 628:
+#line 1622 "asmparse.y"
+{ yyval.int32 = VT_UI1; } break;
+case 629:
+#line 1623 "asmparse.y"
+{ yyval.int32 = VT_UI2; } break;
+case 630:
+#line 1624 "asmparse.y"
+{ yyval.int32 = VT_UI4; } break;
+case 631:
+#line 1625 "asmparse.y"
+{ yyval.int32 = VT_UI8; } break;
+case 632:
+#line 1626 "asmparse.y"
+{ yyval.int32 = VT_PTR; } break;
+case 633:
+#line 1627 "asmparse.y"
+{ yyval.int32 = yypvt[-2].int32 | VT_ARRAY; } break;
+case 634:
+#line 1628 "asmparse.y"
+{ yyval.int32 = yypvt[-1].int32 | VT_VECTOR; } break;
+case 635:
+#line 1629 "asmparse.y"
+{ yyval.int32 = yypvt[-1].int32 | VT_BYREF; } break;
+case 636:
+#line 1630 "asmparse.y"
+{ yyval.int32 = VT_DECIMAL; } break;
+case 637:
+#line 1631 "asmparse.y"
+{ yyval.int32 = VT_DATE; } break;
+case 638:
+#line 1632 "asmparse.y"
+{ yyval.int32 = VT_BSTR; } break;
+case 639:
+#line 1633 "asmparse.y"
+{ yyval.int32 = VT_LPSTR; } break;
+case 640:
+#line 1634 "asmparse.y"
+{ yyval.int32 = VT_LPWSTR; } break;
+case 641:
+#line 1635 "asmparse.y"
+{ yyval.int32 = VT_UNKNOWN; } break;
+case 642:
+#line 1636 "asmparse.y"
+{ yyval.int32 = VT_DISPATCH; } break;
+case 643:
+#line 1637 "asmparse.y"
+{ yyval.int32 = VT_SAFEARRAY; } break;
+case 644:
+#line 1638 "asmparse.y"
+{ yyval.int32 = VT_INT; } break;
+case 645:
+#line 1639 "asmparse.y"
+{ yyval.int32 = VT_UINT; } break;
+case 646:
+#line 1640 "asmparse.y"
+{ yyval.int32 = VT_UINT; } break;
+case 647:
+#line 1641 "asmparse.y"
+{ yyval.int32 = VT_ERROR; } break;
+case 648:
+#line 1642 "asmparse.y"
+{ yyval.int32 = VT_HRESULT; } break;
+case 649:
+#line 1643 "asmparse.y"
+{ yyval.int32 = VT_CARRAY; } break;
+case 650:
+#line 1644 "asmparse.y"
+{ yyval.int32 = VT_USERDEFINED; } break;
+case 651:
+#line 1645 "asmparse.y"
+{ yyval.int32 = VT_RECORD; } break;
+case 652:
+#line 1646 "asmparse.y"
+{ yyval.int32 = VT_FILETIME; } break;
+case 653:
+#line 1647 "asmparse.y"
+{ yyval.int32 = VT_BLOB; } break;
+case 654:
+#line 1648 "asmparse.y"
+{ yyval.int32 = VT_STREAM; } break;
+case 655:
+#line 1649 "asmparse.y"
+{ yyval.int32 = VT_STORAGE; } break;
+case 656:
+#line 1650 "asmparse.y"
+{ yyval.int32 = VT_STREAMED_OBJECT; } break;
+case 657:
+#line 1651 "asmparse.y"
+{ yyval.int32 = VT_STORED_OBJECT; } break;
+case 658:
+#line 1652 "asmparse.y"
+{ yyval.int32 = VT_BLOB_OBJECT; } break;
+case 659:
+#line 1653 "asmparse.y"
+{ yyval.int32 = VT_CF; } break;
+case 660:
+#line 1654 "asmparse.y"
+{ yyval.int32 = VT_CLSID; } break;
+case 661:
+#line 1658 "asmparse.y"
+{ if(yypvt[-0].token == PASM->m_tkSysString)
+ { yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_STRING); }
+ else if(yypvt[-0].token == PASM->m_tkSysObject)
+ { yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_OBJECT); }
+ else
+ yyval.binstr = parser->MakeTypeClass(ELEMENT_TYPE_CLASS, yypvt[-0].token); } break;
+case 662:
+#line 1664 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_OBJECT); } break;
+case 663:
+#line 1665 "asmparse.y"
+{ yyval.binstr = parser->MakeTypeClass(ELEMENT_TYPE_VALUETYPE, yypvt[-0].token); } break;
+case 664:
+#line 1666 "asmparse.y"
+{ yyval.binstr = parser->MakeTypeClass(ELEMENT_TYPE_VALUETYPE, yypvt[-0].token); } break;
+case 665:
+#line 1667 "asmparse.y"
+{ yyval.binstr = yypvt[-2].binstr; yyval.binstr->insertInt8(ELEMENT_TYPE_SZARRAY); } break;
+case 666:
+#line 1668 "asmparse.y"
+{ yyval.binstr = parser->MakeTypeArray(ELEMENT_TYPE_ARRAY, yypvt[-3].binstr, yypvt[-1].binstr); } break;
+case 667:
+#line 1669 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt8(ELEMENT_TYPE_BYREF); } break;
+case 668:
+#line 1670 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt8(ELEMENT_TYPE_PTR); } break;
+case 669:
+#line 1671 "asmparse.y"
+{ yyval.binstr = yypvt[-1].binstr; yyval.binstr->insertInt8(ELEMENT_TYPE_PINNED); } break;
+case 670:
+#line 1672 "asmparse.y"
+{ yyval.binstr = parser->MakeTypeClass(ELEMENT_TYPE_CMOD_REQD, yypvt[-1].token);
+ yyval.binstr->append(yypvt[-4].binstr); } break;
+case 671:
+#line 1674 "asmparse.y"
+{ yyval.binstr = parser->MakeTypeClass(ELEMENT_TYPE_CMOD_OPT, yypvt[-1].token);
+ yyval.binstr->append(yypvt[-4].binstr); } break;
+case 672:
+#line 1677 "asmparse.y"
+{ yyval.binstr = parser->MakeSig(yypvt[-5].int32, yypvt[-4].binstr, yypvt[-1].binstr);
+ yyval.binstr->insertInt8(ELEMENT_TYPE_FNPTR);
+ PASM->delArgNameList(PASM->m_firstArgName);
+ PASM->m_firstArgName = parser->m_ANSFirst.POP();
+ PASM->m_lastArgName = parser->m_ANSLast.POP();
+ } break;
+case 673:
+#line 1683 "asmparse.y"
+{ if(yypvt[-1].binstr == NULL) yyval.binstr = yypvt[-3].binstr;
+ else {
+ yyval.binstr = new BinStr();
+ yyval.binstr->appendInt8(ELEMENT_TYPE_GENERICINST);
+ yyval.binstr->append(yypvt[-3].binstr);
+ corEmitInt(yyval.binstr, corCountArgs(yypvt[-1].binstr));
+ yyval.binstr->append(yypvt[-1].binstr); delete yypvt[-3].binstr; delete yypvt[-1].binstr; }} break;
+case 674:
+#line 1690 "asmparse.y"
+{ //if(PASM->m_pCurMethod) {
+ // if(($3 < 0)||((DWORD)$3 >= PASM->m_pCurMethod->m_NumTyPars))
+ // PASM->report->error("Invalid method type parameter '%d'\n",$3);
+ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_MVAR); corEmitInt(yyval.binstr, yypvt[-0].int32);
+ //} else PASM->report->error("Method type parameter '%d' outside method scope\n",$3);
+ } break;
+case 675:
+#line 1696 "asmparse.y"
+{ //if(PASM->m_pCurClass) {
+ // if(($2 < 0)||((DWORD)$2 >= PASM->m_pCurClass->m_NumTyPars))
+ // PASM->report->error("Invalid type parameter '%d'\n",$2);
+ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_VAR); corEmitInt(yyval.binstr, yypvt[-0].int32);
+ //} else PASM->report->error("Type parameter '%d' outside class scope\n",$2);
+ } break;
+case 676:
+#line 1702 "asmparse.y"
+{ int eltype = ELEMENT_TYPE_MVAR;
+ int n=-1;
+ if(PASM->m_pCurMethod) n = PASM->m_pCurMethod->FindTyPar(yypvt[-0].string);
+ else {
+ if(PASM->m_TyParList) n = PASM->m_TyParList->IndexOf(yypvt[-0].string);
+ if(n == -1)
+ { n = TyParFixupList.COUNT();
+ TyParFixupList.PUSH(yypvt[-0].string);
+ eltype = ELEMENT_TYPE_MVARFIXUP;
+ }
+ }
+ if(n == -1) { PASM->report->error("Invalid method type parameter '%s'\n",yypvt[-0].string);
+ n = 0x1FFFFFFF; }
+ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(eltype); corEmitInt(yyval.binstr,n);
+ } break;
+case 677:
+#line 1717 "asmparse.y"
+{ int eltype = ELEMENT_TYPE_VAR;
+ int n=-1;
+ if(PASM->m_pCurClass && !newclass) n = PASM->m_pCurClass->FindTyPar(yypvt[-0].string);
+ else {
+ if(PASM->m_TyParList) n = PASM->m_TyParList->IndexOf(yypvt[-0].string);
+ if(n == -1)
+ { n = TyParFixupList.COUNT();
+ TyParFixupList.PUSH(yypvt[-0].string);
+ eltype = ELEMENT_TYPE_VARFIXUP;
+ }
+ }
+ if(n == -1) { PASM->report->error("Invalid type parameter '%s'\n",yypvt[-0].string);
+ n = 0x1FFFFFFF; }
+ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(eltype); corEmitInt(yyval.binstr,n);
+ } break;
+case 678:
+#line 1732 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_TYPEDBYREF); } break;
+case 679:
+#line 1733 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_VOID); } break;
+case 680:
+#line 1734 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I); } break;
+case 681:
+#line 1735 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U); } break;
+case 682:
+#line 1736 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U); } break;
+case 683:
+#line 1737 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; } break;
+case 684:
+#line 1738 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; yyval.binstr->insertInt8(ELEMENT_TYPE_SENTINEL); } break;
+case 685:
+#line 1741 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_CHAR); } break;
+case 686:
+#line 1742 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_STRING); } break;
+case 687:
+#line 1743 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_BOOLEAN); } break;
+case 688:
+#line 1744 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I1); } break;
+case 689:
+#line 1745 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I2); } break;
+case 690:
+#line 1746 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I4); } break;
+case 691:
+#line 1747 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_I8); } break;
+case 692:
+#line 1748 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_R4); } break;
+case 693:
+#line 1749 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_R8); } break;
+case 694:
+#line 1750 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U1); } break;
+case 695:
+#line 1751 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U2); } break;
+case 696:
+#line 1752 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U4); } break;
+case 697:
+#line 1753 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U8); } break;
+case 698:
+#line 1754 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U1); } break;
+case 699:
+#line 1755 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U2); } break;
+case 700:
+#line 1756 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U4); } break;
+case 701:
+#line 1757 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt8(ELEMENT_TYPE_U8); } break;
+case 702:
+#line 1758 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->append(yypvt[-0].tdd->m_pbsTypeSpec); } break;
+case 703:
+#line 1761 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; } break;
+case 704:
+#line 1762 "asmparse.y"
+{ yyval.binstr = yypvt[-2].binstr; yypvt[-2].binstr->append(yypvt[-0].binstr); delete yypvt[-0].binstr; } break;
+case 705:
+#line 1765 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt32(0x7FFFFFFF); yyval.binstr->appendInt32(0x7FFFFFFF); } break;
+case 706:
+#line 1766 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt32(0x7FFFFFFF); yyval.binstr->appendInt32(0x7FFFFFFF); } break;
+case 707:
+#line 1767 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt32(0); yyval.binstr->appendInt32(yypvt[-0].int32); } break;
+case 708:
+#line 1768 "asmparse.y"
+{ FAIL_UNLESS(yypvt[-2].int32 <= yypvt[-0].int32, ("lower bound %d must be <= upper bound %d\n", yypvt[-2].int32, yypvt[-0].int32));
+ if (yypvt[-2].int32 > yypvt[-0].int32) { YYERROR; };
+ yyval.binstr = new BinStr(); yyval.binstr->appendInt32(yypvt[-2].int32); yyval.binstr->appendInt32(yypvt[-0].int32-yypvt[-2].int32+1); } break;
+case 709:
+#line 1771 "asmparse.y"
+{ yyval.binstr = new BinStr(); yyval.binstr->appendInt32(yypvt[-1].int32); yyval.binstr->appendInt32(0x7FFFFFFF); } break;
+case 710:
+#line 1776 "asmparse.y"
+{ PASM->AddPermissionDecl(yypvt[-4].secAct, yypvt[-3].token, yypvt[-1].pair); } break;
+case 711:
+#line 1778 "asmparse.y"
+{ PASM->AddPermissionDecl(yypvt[-5].secAct, yypvt[-4].token, yypvt[-1].binstr); } break;
+case 712:
+#line 1779 "asmparse.y"
+{ PASM->AddPermissionDecl(yypvt[-1].secAct, yypvt[-0].token, (NVPair *)NULL); } break;
+case 713:
+#line 1780 "asmparse.y"
+{ PASM->AddPermissionSetDecl(yypvt[-2].secAct, yypvt[-1].binstr); } break;
+case 714:
+#line 1782 "asmparse.y"
+{ PASM->AddPermissionSetDecl(yypvt[-1].secAct,BinStrToUnicode(yypvt[-0].binstr,true));} break;
+case 715:
+#line 1784 "asmparse.y"
+{ BinStr* ret = new BinStr();
+ ret->insertInt8('.');
+ corEmitInt(ret, nSecAttrBlobs);
+ ret->append(yypvt[-1].binstr);
+ PASM->AddPermissionSetDecl(yypvt[-4].secAct,ret);
+ nSecAttrBlobs = 0; } break;
+case 716:
+#line 1792 "asmparse.y"
+{ yyval.binstr = new BinStr(); nSecAttrBlobs = 0;} break;
+case 717:
+#line 1793 "asmparse.y"
+{ yyval.binstr = yypvt[-0].binstr; nSecAttrBlobs = 1; } break;
+case 718:
+#line 1794 "asmparse.y"
+{ yyval.binstr = yypvt[-2].binstr; yyval.binstr->append(yypvt[-0].binstr); nSecAttrBlobs++; } break;
+case 719:
+#line 1798 "asmparse.y"
+{ yyval.binstr = PASM->EncodeSecAttr(PASM->ReflectionNotation(yypvt[-4].token),yypvt[-1].binstr,nCustomBlobNVPairs);
+ nCustomBlobNVPairs = 0; } break;
+case 720:
+#line 1801 "asmparse.y"
+{ yyval.binstr = PASM->EncodeSecAttr(yypvt[-4].string,yypvt[-1].binstr,nCustomBlobNVPairs);
+ nCustomBlobNVPairs = 0; } break;
+case 721:
+#line 1805 "asmparse.y"
+{ yyval.secAct = yypvt[-2].secAct; bParsingByteArray = TRUE; } break;
+case 722:
+#line 1807 "asmparse.y"
+{ yyval.secAct = yypvt[-2].secAct; bParsingByteArray = TRUE; } break;
+case 723:
+#line 1810 "asmparse.y"
+{ yyval.pair = yypvt[-0].pair; } break;
+case 724:
+#line 1811 "asmparse.y"
+{ yyval.pair = yypvt[-2].pair->Concat(yypvt[-0].pair); } break;
+case 725:
+#line 1814 "asmparse.y"
+{ yypvt[-2].binstr->appendInt8(0); yyval.pair = new NVPair(yypvt[-2].binstr, yypvt[-0].binstr); } break;
+case 726:
+#line 1817 "asmparse.y"
+{ yyval.int32 = 1; } break;
+case 727:
+#line 1818 "asmparse.y"
+{ yyval.int32 = 0; } break;
+case 728:
+#line 1821 "asmparse.y"
+{ yyval.binstr = new BinStr();
+ yyval.binstr->appendInt8(SERIALIZATION_TYPE_BOOLEAN);
+ yyval.binstr->appendInt8(yypvt[-0].int32); } break;
+case 729:
+#line 1824 "asmparse.y"
+{ yyval.binstr = new BinStr();
+ yyval.binstr->appendInt8(SERIALIZATION_TYPE_I4);
+ yyval.binstr->appendInt32(yypvt[-0].int32); } break;
+case 730:
+#line 1827 "asmparse.y"
+{ yyval.binstr = new BinStr();
+ yyval.binstr->appendInt8(SERIALIZATION_TYPE_I4);
+ yyval.binstr->appendInt32(yypvt[-1].int32); } break;
+case 731:
+#line 1830 "asmparse.y"
+{ yyval.binstr = new BinStr();
+ yyval.binstr->appendInt8(SERIALIZATION_TYPE_STRING);
+ yyval.binstr->append(yypvt[-0].binstr); delete yypvt[-0].binstr;
+ yyval.binstr->appendInt8(0); } break;
+case 732:
+#line 1834 "asmparse.y"
+{ yyval.binstr = new BinStr();
+ yyval.binstr->appendInt8(SERIALIZATION_TYPE_ENUM);
+ char* sz = PASM->ReflectionNotation(yypvt[-5].token);
+ strcpy_s((char *)yyval.binstr->getBuff((unsigned)strlen(sz) + 1), strlen(sz) + 1,sz);
+ yyval.binstr->appendInt8(1);
+ yyval.binstr->appendInt32(yypvt[-1].int32); } break;
+case 733:
+#line 1840 "asmparse.y"
+{ yyval.binstr = new BinStr();
+ yyval.binstr->appendInt8(SERIALIZATION_TYPE_ENUM);
+ char* sz = PASM->ReflectionNotation(yypvt[-5].token);
+ strcpy_s((char *)yyval.binstr->getBuff((unsigned)strlen(sz) + 1), strlen(sz) + 1,sz);
+ yyval.binstr->appendInt8(2);
+ yyval.binstr->appendInt32(yypvt[-1].int32); } break;
+case 734:
+#line 1846 "asmparse.y"
+{ yyval.binstr = new BinStr();
+ yyval.binstr->appendInt8(SERIALIZATION_TYPE_ENUM);
+ char* sz = PASM->ReflectionNotation(yypvt[-5].token);
+ strcpy_s((char *)yyval.binstr->getBuff((unsigned)strlen(sz) + 1), strlen(sz) + 1,sz);
+ yyval.binstr->appendInt8(4);
+ yyval.binstr->appendInt32(yypvt[-1].int32); } break;
+case 735:
+#line 1852 "asmparse.y"
+{ yyval.binstr = new BinStr();
+ yyval.binstr->appendInt8(SERIALIZATION_TYPE_ENUM);
+ char* sz = PASM->ReflectionNotation(yypvt[-3].token);
+ strcpy_s((char *)yyval.binstr->getBuff((unsigned)strlen(sz) + 1), strlen(sz) + 1,sz);
+ yyval.binstr->appendInt8(4);
+ yyval.binstr->appendInt32(yypvt[-1].int32); } break;
+case 736:
+#line 1860 "asmparse.y"
+{ yyval.secAct = dclRequest; } break;
+case 737:
+#line 1861 "asmparse.y"
+{ yyval.secAct = dclDemand; } break;
+case 738:
+#line 1862 "asmparse.y"
+{ yyval.secAct = dclAssert; } break;
+case 739:
+#line 1863 "asmparse.y"
+{ yyval.secAct = dclDeny; } break;
+case 740:
+#line 1864 "asmparse.y"
+{ yyval.secAct = dclPermitOnly; } break;
+case 741:
+#line 1865 "asmparse.y"
+{ yyval.secAct = dclLinktimeCheck; } break;
+case 742:
+#line 1866 "asmparse.y"
+{ yyval.secAct = dclInheritanceCheck; } break;
+case 743:
+#line 1867 "asmparse.y"
+{ yyval.secAct = dclRequestMinimum; } break;
+case 744:
+#line 1868 "asmparse.y"
+{ yyval.secAct = dclRequestOptional; } break;
+case 745:
+#line 1869 "asmparse.y"
+{ yyval.secAct = dclRequestRefuse; } break;
+case 746:
+#line 1870 "asmparse.y"
+{ yyval.secAct = dclPrejitGrant; } break;
+case 747:
+#line 1871 "asmparse.y"
+{ yyval.secAct = dclPrejitDenied; } break;
+case 748:
+#line 1872 "asmparse.y"
+{ yyval.secAct = dclNonCasDemand; } break;
+case 749:
+#line 1873 "asmparse.y"
+{ yyval.secAct = dclNonCasLinkDemand; } break;
+case 750:
+#line 1874 "asmparse.y"
+{ yyval.secAct = dclNonCasInheritance; } break;
+case 751:
+#line 1878 "asmparse.y"
+{ PASM->ResetLineNumbers(); nCurrPC = PASM->m_CurPC; PENV->bExternSource = TRUE; PENV->bExternSourceAutoincrement = FALSE; } break;
+case 752:
+#line 1879 "asmparse.y"
+{ PASM->ResetLineNumbers(); nCurrPC = PASM->m_CurPC; PENV->bExternSource = TRUE; PENV->bExternSourceAutoincrement = TRUE; } break;
+case 753:
+#line 1882 "asmparse.y"
+{ PENV->nExtLine = PENV->nExtLineEnd = yypvt[-1].int32;
+ PENV->nExtCol = 0; PENV->nExtColEnd = static_cast<unsigned>(-1);
+ PASM->SetSourceFileName(yypvt[-0].string);} break;
+case 754:
+#line 1885 "asmparse.y"
+{ PENV->nExtLine = PENV->nExtLineEnd = yypvt[-0].int32;
+ PENV->nExtCol = 0; PENV->nExtColEnd = static_cast<unsigned>(-1); } break;
+case 755:
+#line 1887 "asmparse.y"
+{ PENV->nExtLine = PENV->nExtLineEnd = yypvt[-3].int32;
+ PENV->nExtCol=yypvt[-1].int32; PENV->nExtColEnd = static_cast<unsigned>(-1);
+ PASM->SetSourceFileName(yypvt[-0].string);} break;
+case 756:
+#line 1890 "asmparse.y"
+{ PENV->nExtLine = PENV->nExtLineEnd = yypvt[-2].int32;
+ PENV->nExtCol=yypvt[-0].int32; PENV->nExtColEnd = static_cast<unsigned>(-1);} break;
+case 757:
+#line 1893 "asmparse.y"
+{ PENV->nExtLine = PENV->nExtLineEnd = yypvt[-5].int32;
+ PENV->nExtCol=yypvt[-3].int32; PENV->nExtColEnd = yypvt[-1].int32;
+ PASM->SetSourceFileName(yypvt[-0].string);} break;
+case 758:
+#line 1897 "asmparse.y"
+{ PENV->nExtLine = PENV->nExtLineEnd = yypvt[-4].int32;
+ PENV->nExtCol=yypvt[-2].int32; PENV->nExtColEnd = yypvt[-0].int32; } break;
+case 759:
+#line 1900 "asmparse.y"
+{ PENV->nExtLine = yypvt[-5].int32; PENV->nExtLineEnd = yypvt[-3].int32;
+ PENV->nExtCol=yypvt[-1].int32; PENV->nExtColEnd = static_cast<unsigned>(-1);
+ PASM->SetSourceFileName(yypvt[-0].string);} break;
+case 760:
+#line 1904 "asmparse.y"
+{ PENV->nExtLine = yypvt[-4].int32; PENV->nExtLineEnd = yypvt[-2].int32;
+ PENV->nExtCol=yypvt[-0].int32; PENV->nExtColEnd = static_cast<unsigned>(-1); } break;
+case 761:
+#line 1907 "asmparse.y"
+{ PENV->nExtLine = yypvt[-7].int32; PENV->nExtLineEnd = yypvt[-5].int32;
+ PENV->nExtCol=yypvt[-3].int32; PENV->nExtColEnd = yypvt[-1].int32;
+ PASM->SetSourceFileName(yypvt[-0].string);} break;
+case 762:
+#line 1911 "asmparse.y"
+{ PENV->nExtLine = yypvt[-6].int32; PENV->nExtLineEnd = yypvt[-4].int32;
+ PENV->nExtCol=yypvt[-2].int32; PENV->nExtColEnd = yypvt[-0].int32; } break;
+case 763:
+#line 1913 "asmparse.y"
+{ PENV->nExtLine = PENV->nExtLineEnd = yypvt[-1].int32 - 1;
+ PENV->nExtCol = 0; PENV->nExtColEnd = static_cast<unsigned>(-1);
+ PASM->SetSourceFileName(yypvt[-0].binstr);} break;
+case 764:
+#line 1920 "asmparse.y"
+{ PASMM->AddFile(yypvt[-5].string, yypvt[-6].fileAttr|yypvt[-4].fileAttr|yypvt[-0].fileAttr, yypvt[-2].binstr); } break;
+case 765:
+#line 1921 "asmparse.y"
+{ PASMM->AddFile(yypvt[-1].string, yypvt[-2].fileAttr|yypvt[-0].fileAttr, NULL); } break;
+case 766:
+#line 1924 "asmparse.y"
+{ yyval.fileAttr = (CorFileFlags) 0; } break;
+case 767:
+#line 1925 "asmparse.y"
+{ yyval.fileAttr = (CorFileFlags) (yypvt[-1].fileAttr | ffContainsNoMetaData); } break;
+case 768:
+#line 1928 "asmparse.y"
+{ yyval.fileAttr = (CorFileFlags) 0; } break;
+case 769:
+#line 1929 "asmparse.y"
+{ yyval.fileAttr = (CorFileFlags) 0x80000000; } break;
+case 770:
+#line 1932 "asmparse.y"
+{ bParsingByteArray = TRUE; } break;
+case 771:
+#line 1935 "asmparse.y"
+{ PASMM->StartAssembly(yypvt[-0].string, NULL, (DWORD)yypvt[-1].asmAttr, FALSE); } break;
+case 772:
+#line 1938 "asmparse.y"
+{ yyval.asmAttr = (CorAssemblyFlags) 0; } break;
+case 773:
+#line 1939 "asmparse.y"
+{ yyval.asmAttr = (CorAssemblyFlags) (yypvt[-1].asmAttr | afRetargetable); } break;
+case 774:
+#line 1940 "asmparse.y"
+{ yyval.asmAttr = (CorAssemblyFlags) (yypvt[-1].asmAttr | afContentType_WindowsRuntime); } break;
+case 775:
+#line 1941 "asmparse.y"
+{ yyval.asmAttr = (CorAssemblyFlags) (yypvt[-1].asmAttr | afPA_NoPlatform); } break;
+case 776:
+#line 1942 "asmparse.y"
+{ yyval.asmAttr = yypvt[-2].asmAttr; } break;
+case 777:
+#line 1943 "asmparse.y"
+{ SET_PA(yyval.asmAttr,yypvt[-1].asmAttr,afPA_MSIL); } break;
+case 778:
+#line 1944 "asmparse.y"
+{ SET_PA(yyval.asmAttr,yypvt[-1].asmAttr,afPA_x86); } break;
+case 779:
+#line 1945 "asmparse.y"
+{ SET_PA(yyval.asmAttr,yypvt[-1].asmAttr,afPA_IA64); } break;
+case 780:
+#line 1946 "asmparse.y"
+{ SET_PA(yyval.asmAttr,yypvt[-1].asmAttr,afPA_AMD64); } break;
+case 781:
+#line 1947 "asmparse.y"
+{ SET_PA(yyval.asmAttr,yypvt[-1].asmAttr,afPA_ARM); } break;
+case 784:
+#line 1954 "asmparse.y"
+{ PASMM->SetAssemblyHashAlg(yypvt[-0].int32); } break;
+case 787:
+#line 1959 "asmparse.y"
+{ yyval.int32 = yypvt[-0].int32; } break;
+case 788:
+#line 1960 "asmparse.y"
+{ yyval.int32 = 0xFFFF; } break;
+case 789:
+#line 1963 "asmparse.y"
+{ PASMM->SetAssemblyPublicKey(yypvt[-1].binstr); } break;
+case 790:
+#line 1965 "asmparse.y"
+{ PASMM->SetAssemblyVer((USHORT)yypvt[-6].int32, (USHORT)yypvt[-4].int32, (USHORT)yypvt[-2].int32, (USHORT)yypvt[-0].int32); } break;
+case 791:
+#line 1966 "asmparse.y"
+{ yypvt[-0].binstr->appendInt8(0); PASMM->SetAssemblyLocale(yypvt[-0].binstr,TRUE); } break;
+case 792:
+#line 1967 "asmparse.y"
+{ PASMM->SetAssemblyLocale(yypvt[-1].binstr,FALSE); } break;
+case 795:
+#line 1972 "asmparse.y"
+{ bParsingByteArray = TRUE; } break;
+case 796:
+#line 1975 "asmparse.y"
+{ bParsingByteArray = TRUE; } break;
+case 797:
+#line 1978 "asmparse.y"
+{ bParsingByteArray = TRUE; } break;
+case 798:
+#line 1982 "asmparse.y"
+{ PASMM->StartAssembly(yypvt[-0].string, NULL, yypvt[-1].asmAttr, TRUE); } break;
+case 799:
+#line 1984 "asmparse.y"
+{ PASMM->StartAssembly(yypvt[-2].string, yypvt[-0].string, yypvt[-3].asmAttr, TRUE); } break;
+case 802:
+#line 1991 "asmparse.y"
+{ PASMM->SetAssemblyHashBlob(yypvt[-1].binstr); } break;
+case 804:
+#line 1993 "asmparse.y"
+{ PASMM->SetAssemblyPublicKeyToken(yypvt[-1].binstr); } break;
+case 805:
+#line 1994 "asmparse.y"
+{ PASMM->SetAssemblyAutodetect(); } break;
+case 806:
+#line 1997 "asmparse.y"
+{ PASMM->StartComType(yypvt[-0].string, yypvt[-1].exptAttr);} break;
+case 807:
+#line 2000 "asmparse.y"
+{ PASMM->StartComType(yypvt[-0].string, yypvt[-1].exptAttr); } break;
+case 808:
+#line 2003 "asmparse.y"
+{ yyval.exptAttr = (CorTypeAttr) 0; } break;
+case 809:
+#line 2004 "asmparse.y"
+{ yyval.exptAttr = (CorTypeAttr) (yypvt[-1].exptAttr | tdNotPublic); } break;
+case 810:
+#line 2005 "asmparse.y"
+{ yyval.exptAttr = (CorTypeAttr) (yypvt[-1].exptAttr | tdPublic); } break;
+case 811:
+#line 2006 "asmparse.y"
+{ yyval.exptAttr = (CorTypeAttr) (yypvt[-1].exptAttr | tdForwarder); } break;
+case 812:
+#line 2007 "asmparse.y"
+{ yyval.exptAttr = (CorTypeAttr) (yypvt[-2].exptAttr | tdNestedPublic); } break;
+case 813:
+#line 2008 "asmparse.y"
+{ yyval.exptAttr = (CorTypeAttr) (yypvt[-2].exptAttr | tdNestedPrivate); } break;
+case 814:
+#line 2009 "asmparse.y"
+{ yyval.exptAttr = (CorTypeAttr) (yypvt[-2].exptAttr | tdNestedFamily); } break;
+case 815:
+#line 2010 "asmparse.y"
+{ yyval.exptAttr = (CorTypeAttr) (yypvt[-2].exptAttr | tdNestedAssembly); } break;
+case 816:
+#line 2011 "asmparse.y"
+{ yyval.exptAttr = (CorTypeAttr) (yypvt[-2].exptAttr | tdNestedFamANDAssem); } break;
+case 817:
+#line 2012 "asmparse.y"
+{ yyval.exptAttr = (CorTypeAttr) (yypvt[-2].exptAttr | tdNestedFamORAssem); } break;
+case 820:
+#line 2019 "asmparse.y"
+{ PASMM->SetComTypeFile(yypvt[-0].string); } break;
+case 821:
+#line 2020 "asmparse.y"
+{ PASMM->SetComTypeComType(yypvt[-0].string); } break;
+case 822:
+#line 2021 "asmparse.y"
+{ PASMM->SetComTypeAsmRef(yypvt[-0].string); } break;
+case 823:
+#line 2022 "asmparse.y"
+{ if(!PASMM->SetComTypeImplementationTok(yypvt[-1].int32))
+ PASM->report->error("Invalid implementation of exported type\n"); } break;
+case 824:
+#line 2024 "asmparse.y"
+{ if(!PASMM->SetComTypeClassTok(yypvt[-0].int32))
+ PASM->report->error("Invalid TypeDefID of exported type\n"); } break;
+case 827:
+#line 2030 "asmparse.y"
+{ PASMM->StartManifestRes(yypvt[-0].string, yypvt[-0].string, yypvt[-1].manresAttr); } break;
+case 828:
+#line 2032 "asmparse.y"
+{ PASMM->StartManifestRes(yypvt[-2].string, yypvt[-0].string, yypvt[-3].manresAttr); } break;
+case 829:
+#line 2035 "asmparse.y"
+{ yyval.manresAttr = (CorManifestResourceFlags) 0; } break;
+case 830:
+#line 2036 "asmparse.y"
+{ yyval.manresAttr = (CorManifestResourceFlags) (yypvt[-1].manresAttr | mrPublic); } break;
+case 831:
+#line 2037 "asmparse.y"
+{ yyval.manresAttr = (CorManifestResourceFlags) (yypvt[-1].manresAttr | mrPrivate); } break;
+case 834:
+#line 2044 "asmparse.y"
+{ PASMM->SetManifestResFile(yypvt[-2].string, (ULONG)yypvt[-0].int32); } break;
+case 835:
+#line 2045 "asmparse.y"
+{ PASMM->SetManifestResAsmRef(yypvt[-0].string); } break;/* End of actions */
+#line 329 "D:\\ProjectK3\\src\\tools\\devdiv\\x86\\yypars.c"
+ }
+ }
+ goto yystack; /* stack new state and value */
+ }
+#pragma warning(default:102)
+
+
+#ifdef YYDUMP
+YYLOCAL void YYNEAR YYPASCAL yydumpinfo(void)
+{
+ short stackindex;
+ short valindex;
+
+ //dump yys
+ printf("short yys[%d] {\n", YYMAXDEPTH);
+ for (stackindex = 0; stackindex < YYMAXDEPTH; stackindex++){
+ if (stackindex)
+ printf(", %s", stackindex % 10 ? "\0" : "\n");
+ printf("%6d", yys[stackindex]);
+ }
+ printf("\n};\n");
+
+ //dump yyv
+ printf("YYSTYPE yyv[%d] {\n", YYMAXDEPTH);
+ for (valindex = 0; valindex < YYMAXDEPTH; valindex++){
+ if (valindex)
+ printf(", %s", valindex % 5 ? "\0" : "\n");
+ printf("%#*x", 3+sizeof(YYSTYPE), yyv[valindex]);
+ }
+ printf("\n};\n");
+ }
+#endif
diff --git a/src/ildasm/dis.cpp b/src/ildasm/dis.cpp
index ad5e5a7141..371466feee 100644
--- a/src/ildasm/dis.cpp
+++ b/src/ildasm/dis.cpp
@@ -475,7 +475,7 @@ void dumpOneEHInfo(DasmExceptionInfoClause* ehInfo, IMDInternalImport *pImport,
/*
if(ehInfo->GetFlags() & ERR_OUT_OF_CODE)
{
- sprintf(szString,"%s// WARNING: Boundary outside the method code",g_szAsmCodeIndent);
+ _snprintf_s(szString, _countof(szString), _TRUNCATE, "%s// WARNING: Boundary outside the method code",g_szAsmCodeIndent);
printLine(GUICookie,szString);
}
*/
@@ -863,8 +863,8 @@ BOOL SourceLinesHelper(void *GUICookie, LineCodeDescr* pLCD, __out_ecount(nSize)
/*
BOOL fHasEmbeddedSource=FALSE;
((ISymUnmanagedDocument*)(pParam->pLCD->FileToken))->HasEmbeddedSource(&fHasEmbeddedSource);
- sprintf(szString,"%s// PDB has %sembedded source",g_szAsmCodeIndent,
- fHasEmbeddedSource ? "" : "no ");
+ _snprintf_s(szString, _countof(szString), _TRUNCATE, "%s// PDB has %sembedded source",g_szAsmCodeIndent,
+ fHasEmbeddedSource ? "" : "no ");
printLine(pParam->GUICookie,szString);
*/
}
diff --git a/src/ildasm/dres.cpp b/src/ildasm/dres.cpp
index 0f23fcc036..53e1925cea 100644
--- a/src/ildasm/dres.cpp
+++ b/src/ildasm/dres.cpp
@@ -281,11 +281,11 @@ DWORD DumpResourceToFile(__in __nullterminated WCHAR* wzFileName)
void* GUICookie = (void*)wzFileName;
BYTE* pbData;
printLine(GUICookie,"");
- sprintf(szString,"// ========== Win32 Resource Entries (%d) ========",ulNumResNodes);
+ sprintf_s(szString, _countof(szString), "// ========== Win32 Resource Entries (%d) ========",ulNumResNodes);
for(i=0; i < ulNumResNodes; i++)
{
printLine(GUICookie,"");
- sprintf(szString,"// Res.# %d Type=0x%X Name=0x%X Lang=0x%X DataOffset=0x%X DataLength=%d",
+ sprintf_s(szString, _countof(szString), "// Res.# %d Type=0x%X Name=0x%X Lang=0x%X DataOffset=0x%X DataLength=%d",
i+1,
g_prResNodePtr[i]->ResHdr.dwTypeID,
g_prResNodePtr[i]->ResHdr.dwNameID,
diff --git a/src/ildasm/gui.cpp b/src/ildasm/gui.cpp
index f5f141d279..83501e66ef 100644
--- a/src/ildasm/gui.cpp
+++ b/src/ildasm/gui.cpp
@@ -2256,7 +2256,7 @@ void FindTextInListbox(HWND hwnd, FINDREPLACEW* lpfr)
if(pos >= 0)
{
//char sz[32];
- //sprintf(sz,"%d:%d",strFind.chrg.cpMin,strFind.chrg.cpMax);
+ //sprintf_s(sz, _countof(sz), "%d:%d",strFind.chrg.cpMin,strFind.chrg.cpMax);
//MessageBox(hwnd,sz,"Find",MB_OK);
SendMessage(hwndLB,EM_SETSEL,(WPARAM)pos,(LPARAM)(pos+wcslen(lpfr->lpstrFindWhat)));
}
diff --git a/src/ildasm/windasm.cpp b/src/ildasm/windasm.cpp
index d8a28812b7..57f779fd50 100644
--- a/src/ildasm/windasm.cpp
+++ b/src/ildasm/windasm.cpp
@@ -383,27 +383,29 @@ int ProcessOneArg(__in __nullterminated char* szArg, __out char** ppszObjFileNam
}
else if ((_stricmp(szOpt, "met") == 0)&&g_fTDC)
{
- if(g_fTDC)
+#ifdef FEATURE_CORECLR
+ printf("Warning: 'METADATA' option is ignored for ildasm on CoreCLR.\n");
+#else
+
+ char *pStr = EqualOrColon(szArg);
+ g_fDumpMetaInfo = TRUE;
+ if(pStr)
{
- char *pStr = EqualOrColon(szArg);
- g_fDumpMetaInfo = TRUE;
- if(pStr)
- {
- char szOptn[64];
- strncpy_s(szOptn, 64, pStr+1,10);
- szOptn[3] = 0; // recognize metainfo specifier by first 3 chars
- if (_stricmp(szOptn, "hex") == 0) g_ulMetaInfoFilter |= MDInfo::dumpMoreHex;
- else if(_stricmp(szOptn, "csv") == 0) g_ulMetaInfoFilter |= MDInfo::dumpCSV;
- else if(_stricmp(szOptn, "mdh") == 0) g_ulMetaInfoFilter |= MDInfo::dumpHeader;
- else if(_stricmp(szOptn, "raw") == 0) g_ulMetaInfoFilter |= MDInfo::dumpRaw;
- else if(_stricmp(szOptn, "hea") == 0) g_ulMetaInfoFilter |= MDInfo::dumpRawHeaps;
- else if(_stricmp(szOptn, "sch") == 0) g_ulMetaInfoFilter |= MDInfo::dumpSchema;
- else if(_stricmp(szOptn, "unr") == 0) g_ulMetaInfoFilter |= MDInfo::dumpUnsat;
- else if(_stricmp(szOptn, "val") == 0) g_ulMetaInfoFilter |= MDInfo::dumpValidate;
- else if(_stricmp(szOptn, "sta") == 0) g_ulMetaInfoFilter |= MDInfo::dumpStats;
- else return -1;
- }
+ char szOptn[64];
+ strncpy_s(szOptn, 64, pStr+1,10);
+ szOptn[3] = 0; // recognize metainfo specifier by first 3 chars
+ if (_stricmp(szOptn, "hex") == 0) g_ulMetaInfoFilter |= MDInfo::dumpMoreHex;
+ else if(_stricmp(szOptn, "csv") == 0) g_ulMetaInfoFilter |= MDInfo::dumpCSV;
+ else if(_stricmp(szOptn, "mdh") == 0) g_ulMetaInfoFilter |= MDInfo::dumpHeader;
+ else if(_stricmp(szOptn, "raw") == 0) g_ulMetaInfoFilter |= MDInfo::dumpRaw;
+ else if(_stricmp(szOptn, "hea") == 0) g_ulMetaInfoFilter |= MDInfo::dumpRawHeaps;
+ else if(_stricmp(szOptn, "sch") == 0) g_ulMetaInfoFilter |= MDInfo::dumpSchema;
+ else if(_stricmp(szOptn, "unr") == 0) g_ulMetaInfoFilter |= MDInfo::dumpUnsat;
+ else if(_stricmp(szOptn, "val") == 0) g_ulMetaInfoFilter |= MDInfo::dumpValidate;
+ else if(_stricmp(szOptn, "sta") == 0) g_ulMetaInfoFilter |= MDInfo::dumpStats;
+ else return -1;
}
+#endif // FEATURE_CORECLR
}
else if (_stricmp(szOpt, "obj") == 0)
{
diff --git a/src/inc/CMakeLists.txt b/src/inc/CMakeLists.txt
index 803ca3bcc7..d38fa40773 100644
--- a/src/inc/CMakeLists.txt
+++ b/src/inc/CMakeLists.txt
@@ -50,23 +50,22 @@ add_compile_options(/TC)
else()
-#The MIDL tool exists for Windows only, so for other systems, we have the prebuilt xxx_i.c files checked in
+#The MIDL tool exists for Windows only, so for other systems, we have the prebuilt xxx_i.cpp files checked in
# The prebuilt files contain extra '!_MIDL_USE_GUIDDEF_' after the #endif, but not in the comment.
# In order to not to have to modify these prebuilt files, we disable the extra tokens warning.
add_compile_options(-Wno-extra-tokens)
-
+add_compile_options(-D_MIDL_USE_GUIDDEF_)
foreach(IDL_SOURCE IN LISTS CORGUIDS_IDL_SOURCES)
get_filename_component(IDLNAME ${IDL_SOURCE} NAME_WE)
- set(C_SOURCE ../pal/prebuilt/idl/${IDLNAME}_i.c)
+ set(C_SOURCE ../pal/prebuilt/idl/${IDLNAME}_i.cpp)
list(APPEND CORGUIDS_SOURCES ${C_SOURCE})
endforeach(IDL_SOURCE)
add_compile_options(-fPIC)
-
endif(WIN32)
-# Compile *_i.c to lib
+# Compile *_i.cpp to lib
_add_library(corguids ${CORGUIDS_SOURCES})
# Binplace the inc files for packaging later.
diff --git a/src/inc/bitposition.h b/src/inc/bitposition.h
index 0f3831fce9..392d9a6632 100644
--- a/src/inc/bitposition.h
+++ b/src/inc/bitposition.h
@@ -25,7 +25,11 @@ inline
unsigned BitPosition(unsigned value)
{
_ASSERTE((value != 0) && ((value & (value-1)) == 0));
-#ifndef _TARGET_AMD64_
+#if defined(_TARGET_ARM_) && defined(__llvm__)
+ // use intrinsic functions for arm32
+ // this is applied for LLVM only but it may work for some compilers
+ DWORD index = __builtin_clz(__builtin_arm_rbit(value));
+#elif !defined(_TARGET_AMD64_)
const unsigned PRIME = 37;
static const char hashTable[PRIME] =
diff --git a/src/inc/clrconfigvalues.h b/src/inc/clrconfigvalues.h
index d6a362e0df..a0183d2b51 100644
--- a/src/inc/clrconfigvalues.h
+++ b/src/inc/clrconfigvalues.h
@@ -477,6 +477,12 @@ 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_)
+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
+
+RETAIL_CONFIG_DWORD_INFO(EXTERNAL_RequireLegacyJit, W("RequireLegacyJit"), 0, "Set to 1 to require the use of legacy JIT (via COMPlus_useLegacyJit=1 or COMPlus_UseWindowsX86CoreLegacyJit=1).")
+
CONFIG_STRING_INFO_EX(INTERNAL_JitValNumCSE, W("JitValNumCSE"), "Enables ValNum CSE for the specified methods", CLRConfig::REGUTIL_default)
CONFIG_STRING_INFO_EX(INTERNAL_JitLexicalCSE, W("JitLexicalCSE"), "Enables Lexical CSE for the specified methods", CLRConfig::REGUTIL_default)
CONFIG_DWORD_INFO_EX(INTERNAL_JitNoCSE, W("JitNoCSE"), 0, "", CLRConfig::REGUTIL_default)
@@ -493,7 +499,7 @@ CONFIG_DWORD_INFO_EX(INTERNAL_JitNoStructPromotion, W("JitNoStructPromotion"), 0
CONFIG_DWORD_INFO_EX(INTERNAL_JitNoUnroll, W("JitNoUnroll"), 0, "", CLRConfig::REGUTIL_default)
CONFIG_DWORD_INFO_EX(INTERNAL_JitNoMemoryBarriers, W("JitNoMemoryBarriers"), 0, "If 1, don't generate memory barriers", CLRConfig::REGUTIL_default)
#ifdef FEATURE_ENABLE_NO_RANGE_CHECKS
-RETAIL_CONFIG_DWORD_INFO(PRIVATE_JitNoRangeChks, W("JitNoRngChks"), 0, "If 1, don't generate range checks")
+RETAIL_CONFIG_DWORD_INFO_EX(PRIVATE_JitNoRangeChks, W("JitNoRngChks"), 0, "If 1, don't generate range checks", CLRConfig::REGUTIL_default)
#endif
RETAIL_CONFIG_DWORD_INFO_DIRECT_ACCESS(EXTERNAL_JitOptimizeType, W("JitOptimizeType"), "")
CONFIG_DWORD_INFO_EX(INTERNAL_JitOrder, W("JitOrder"), 0, "", CLRConfig::REGUTIL_default)
@@ -551,7 +557,7 @@ CONFIG_DWORD_INFO_EX(INTERNAL_JitSplitFunctionSize, W("JitSplitFunctionSize"), 0
RETAIL_CONFIG_DWORD_INFO_EX(EXTERNAL_JitRegisterFP, W("JitRegisterFP"), 3, "Control FP enregistration", CLRConfig::REGUTIL_default)
RETAIL_CONFIG_DWORD_INFO(INTERNAL_JitELTHookEnabled, W("JitELTHookEnabled"), 0, "On ARM, setting this will emit Enter/Leave/TailCall callbacks")
CONFIG_DWORD_INFO_EX(INTERNAL_JitComponentUnitTests, W("JitComponentUnitTests"), 0, "Run JIT component unit tests", CLRConfig::REGUTIL_default)
-CONFIG_DWORD_INFO_EX(INTERNAL_JitMemStats, W("JitMemStats"), 0, "Display JIT memory usage statistics", CLRConfig::REGUTIL_default)
+RETAIL_CONFIG_DWORD_INFO_EX(INTERNAL_JitMemStats, W("JitMemStats"), 0, "Display JIT memory usage statistics", CLRConfig::REGUTIL_default)
CONFIG_DWORD_INFO_EX(INTERNAL_JitLoopHoistStats, W("JitLoopHoistStats"), 0, "Display JIT loop hoisting statistics", CLRConfig::REGUTIL_default)
CONFIG_DWORD_INFO_EX(INTERNAL_JitDebugLogLoopCloning, W("JitDebugLogLoopCloning"), 0, "In debug builds log places where loop cloning optimizations are performed on the fast path.", CLRConfig::REGUTIL_default);
CONFIG_DWORD_INFO_EX(INTERNAL_JitVNMapSelLimit, W("JitVNMapSelLimit"), 0, "If non-zero, assert if # of VNF_MapSelect applications considered reaches this", CLRConfig::REGUTIL_default)
@@ -600,11 +606,11 @@ RETAIL_CONFIG_DWORD_INFO(INTERNAL_InterpreterDoLoopMethods, W("InterpreterDoLoop
RETAIL_CONFIG_DWORD_INFO_EX(INTERNAL_InterpreterUseCaching, W("InterpreterUseCaching"), 1, "If non-zero, use the caching mechanism.", CLRConfig::REGUTIL_default)
RETAIL_CONFIG_DWORD_INFO_EX(INTERNAL_InterpreterLooseRules, W("InterpreterLooseRules"), 1, "If non-zero, allow ECMA spec violations required by managed C++.", CLRConfig::REGUTIL_default)
RETAIL_CONFIG_DWORD_INFO(INTERNAL_InterpreterPrintPostMortem, W("InterpreterPrintPostMortem"), 0, "Prints summary information about the execution to the console")
-CONFIG_STRING_INFO_EX(INTERNAL_InterpreterLogFile, W("InterpreterLogFile"), "If non-null, append interpreter logging to this file, else use stdout", CLRConfig::REGUTIL_default)
-CONFIG_DWORD_INFO(INTERNAL_DumpInterpreterStubs, W("DumpInterpreterStubs"), 0, "Prints all interpreter stubs that are created to the console")
-CONFIG_DWORD_INFO(INTERNAL_TraceInterpreterEntries, W("TraceInterpreterEntries"), 0, "Logs entries to interpreted methods to the console")
-CONFIG_DWORD_INFO(INTERNAL_TraceInterpreterIL, W("TraceInterpreterIL"), 0, "Logs individual instructions of interpreted methods to the console")
-CONFIG_DWORD_INFO(INTERNAL_TraceInterpreterOstack, W("TraceInterpreterOstack"), 0, "Logs operand stack after each IL instruction of interpreted methods to the console")
+RETAIL_CONFIG_STRING_INFO_EX(INTERNAL_InterpreterLogFile, W("InterpreterLogFile"), "If non-null, append interpreter logging to this file, else use stdout", CLRConfig::REGUTIL_default)
+RETAIL_CONFIG_DWORD_INFO(INTERNAL_DumpInterpreterStubs, W("DumpInterpreterStubs"), 0, "Prints all interpreter stubs that are created to the console")
+RETAIL_CONFIG_DWORD_INFO(INTERNAL_TraceInterpreterEntries, W("TraceInterpreterEntries"), 0, "Logs entries to interpreted methods to the console")
+RETAIL_CONFIG_DWORD_INFO(INTERNAL_TraceInterpreterIL, W("TraceInterpreterIL"), 0, "Logs individual instructions of interpreted methods to the console")
+RETAIL_CONFIG_DWORD_INFO(INTERNAL_TraceInterpreterOstack, W("TraceInterpreterOstack"), 0, "Logs operand stack after each IL instruction of interpreted methods to the console")
CONFIG_DWORD_INFO(INTERNAL_TraceInterpreterVerbose, W("TraceInterpreterVerbose"), 0, "Logs interpreter progress with detailed messages to the console")
CONFIG_DWORD_INFO(INTERNAL_TraceInterpreterJITTransition, W("TraceInterpreterJITTransition"), 0, "Logs when the interpreter determines a method should be JITted")
#endif
@@ -1122,12 +1128,12 @@ 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)
+#if defined(CROSSGEN_COMPILE) || defined(FEATURE_CORECLR)
#define INTERNAL_NoGuiOnAssert_Default 1
#else
#define INTERNAL_NoGuiOnAssert_Default 0
#endif
-CONFIG_DWORD_INFO_EX(INTERNAL_NoGuiOnAssert, W("NoGuiOnAssert"), INTERNAL_NoGuiOnAssert_Default, "", CLRConfig::REGUTIL_default)
+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)
RETAIL_CONFIG_DWORD_INFO_DIRECT_ACCESS(EXTERNAL_NotifyBadAppCfg, W("NotifyBadAppCfg"), "Whether to show a message box for bad application config file.")
diff --git a/src/inc/clrnt.h b/src/inc/clrnt.h
index c15bd48fa8..0e082c79d5 100644
--- a/src/inc/clrnt.h
+++ b/src/inc/clrnt.h
@@ -835,17 +835,17 @@ RtlVirtualUnwind_Unsafe(
// X86
//
-#if defined(_TARGET_X86_)
-
-#pragma warning(push)
-#pragma warning (disable:4035) // disable 4035 (function must return something)
-#define PcTeb 0x18
-#pragma warning(pop)
+#ifdef _TARGET_X86_
+#ifndef FEATURE_PAL
typedef struct _DISPATCHER_CONTEXT {
_EXCEPTION_REGISTRATION_RECORD* RegistrationPointer;
} DISPATCHER_CONTEXT, *PDISPATCHER_CONTEXT;
+#endif // !FEATURE_PAL
+
+#define RUNTIME_FUNCTION__BeginAddress(prf) (prf)->BeginAddress
+
#endif // _TARGET_X86_
#ifdef _TARGET_ARM_
diff --git a/src/inc/corcompile.h b/src/inc/corcompile.h
index 70db9f162b..3b517ae212 100644
--- a/src/inc/corcompile.h
+++ b/src/inc/corcompile.h
@@ -72,6 +72,7 @@ typedef DPTR(struct CORCOMPILE_IMPORT_SECTION)
PTR_CORCOMPILE_IMPORT_SECTION;
#ifdef _TARGET_X86_
+#ifndef FEATURE_PAL
//
// x86 ABI does not define RUNTIME_FUNCTION. Define our own to allow unification between x86 and other platforms.
//
@@ -80,14 +81,15 @@ typedef struct _RUNTIME_FUNCTION {
DWORD UnwindData;
} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
+#endif // !FEATURE_PAL
+
typedef DPTR(RUNTIME_FUNCTION) PTR_RUNTIME_FUNCTION;
-#define RUNTIME_FUNCTION__BeginAddress(prf) (prf)->BeginAddress
// Chained unwind info. Used for cold methods.
#define RUNTIME_FUNCTION_INDIRECT 0x80000000
-#endif
+#endif // _TARGET_X86_
// The stride is choosen as maximum value that still gives good page locality of RUNTIME_FUNCTION table touches (only one page of
// RUNTIME_FUNCTION table is going to be touched during most IP2MD lookups).
@@ -1164,7 +1166,7 @@ enum CorCompileILRegion
class ICorCompilePreloader
{
public:
- typedef void (__stdcall *CORCOMPILE_CompileStubCallback)(LPVOID pContext, CORINFO_METHOD_HANDLE hStub, DWORD dwJitFlags);
+ typedef void (__stdcall *CORCOMPILE_CompileStubCallback)(LPVOID pContext, CORINFO_METHOD_HANDLE hStub, CORJIT_FLAGS jitFlags);
//
// Map methods are available after Serialize() is called
@@ -1849,7 +1851,7 @@ class ICorCompileInfo
// Get the compilation flags that are shared between JIT and NGen
virtual HRESULT GetBaseJitFlags(
IN CORINFO_METHOD_HANDLE hMethod,
- OUT DWORD *pFlags) = 0;
+ OUT CORJIT_FLAGS *pFlags) = 0;
// needed for stubs to obtain the number of bytes to copy into the native image
// return the beginning of the stub and the size to copy (in bytes)
@@ -1887,16 +1889,16 @@ class ICorCompileInfo
/*****************************************************************************/
// This function determines the compile flags to use for a generic intatiation
// since only the open instantiation can be verified.
-// See the comment associated with CORJIT_FLG_SKIP_VERIFICATION for details.
+// See the comment associated with CORJIT_FLAG_SKIP_VERIFICATION for details.
//
// On return:
// if *raiseVerificationException=TRUE, the caller should raise a VerificationException.
// if *unverifiableGenericCode=TRUE, the method is a generic instantiation with
// unverifiable code
-CorJitFlag GetCompileFlagsIfGenericInstantiation(
+CORJIT_FLAGS GetCompileFlagsIfGenericInstantiation(
CORINFO_METHOD_HANDLE method,
- CorJitFlag compileFlags,
+ CORJIT_FLAGS compileFlags,
ICorJitInfo * pCorJitInfo,
BOOL * raiseVerificationException,
BOOL * unverifiableGenericCode);
diff --git a/src/inc/cordebug.idl b/src/inc/cordebug.idl
index 49b8acc923..093b893dbc 100644
--- a/src/inc/cordebug.idl
+++ b/src/inc/cordebug.idl
@@ -177,6 +177,7 @@ interface ICorDebugTypeEnum;
interface ICorDebugCodeEnum;
interface ICorDebugFrameEnum;
interface ICorDebugValueEnum;
+interface ICorDebugVariableHomeEnum;
interface ICorDebugAppDomainEnum;
interface ICorDebugAssemblyEnum;
interface ICorDebugBlockingObjectEnum;
@@ -5594,6 +5595,23 @@ interface ICorDebugCode3 : IUnknown
[out, size_is(bufferSize), length_is(*pFetched)] ULONG32 pOffsets[]);
};
+[
+ object,
+ local,
+ uuid(18221fa4-20cb-40fa-b19d-9f91c4fa8c14),
+ pointer_default(unique)
+]
+interface ICorDebugCode4 : IUnknown
+{
+ /*
+ * EnumerateVariableHomes - gives an enum for local variables and arguments
+ * in the function.
+ * This may include multiple ICorDebugVariableHomes for the same slot or
+ * argument index if they have different homes at different points in the
+ * function.
+ */
+ HRESULT EnumerateVariableHomes([out] ICorDebugVariableHomeEnum **ppEnum);
+}
[
object,
@@ -6488,8 +6506,79 @@ interface ICorDebugArrayValue : ICorDebugHeapValue
[out] ICorDebugValue **ppValue);
};
+[
+ object,
+ local,
+ uuid(50847b8d-f43f-41b0-924c-6383a5f2278b),
+ pointer_default(unique)
+]
+interface ICorDebugVariableHome : IUnknown
+{
+ /*
+ * GetCode - gives the ICorDebugCode instance containing this
+ * ICorDebugVariableHome.
+ */
+ HRESULT GetCode([out] ICorDebugCode **ppCode);
+ /*
+ * GetSlotIndex - gives the managed slot-index of a local variable.
+ * The slot-index can be used to retrieve the metadata for this local.
+ * Returns E_FAIL if the variable is a function argument.
+ */
+ HRESULT GetSlotIndex([out] ULONG32 *pSlotIndex);
+
+ /*
+ * GetArgumentIndex - gives the argument index of a function argument.
+ * The argument index can be used to retrieve the metadata for this
+ * argument.
+ * Returns E_FAIL if the variable is a local variable.
+ */
+ HRESULT GetArgumentIndex([out] ULONG32* pArgumentIndex);
-/*
+ /*
+ * GetLiveRange - gives the native range over which this variable is live.
+ * pStartOffset is the logical offset at which the variable is first live.
+ * pEndOffset is the logical offset immediately after that at which the
+ * variable is last live.
+ */
+ HRESULT GetLiveRange([out] ULONG32* pStartOffset,
+ [out] ULONG32 *pEndOffset);
+
+ typedef enum VariableLocationType
+ {
+ VLT_REGISTER, // variable is in a register
+ VLT_REGISTER_RELATIVE, // variable is in a register-relative memory
+ // location
+ VLT_INVALID
+ } VariableLocationType;
+
+ /*
+ * GetLocationType - gives the type of native location. See
+ * VariableLocationType.
+ * Returns VLT_INVALID if the variable is not stored in a register or in a
+ * register-relative memory location.
+ */
+ HRESULT GetLocationType([out] VariableLocationType *pLocationType);
+
+ /*
+ * GetRegister - gives the register containing the variables with location
+ * type VLT_REGISTER, and the base register for variables with location
+ * type VLT_REGISTER_RELATIVE.
+ * Returns E_FAIL if the variable is not in a register or in a
+ * register-relative location.
+ */
+ HRESULT GetRegister([out] CorDebugRegister *pRegister);
+
+ /*
+ * GetOffset - gives the offset from the base register for a variable.
+ * Returns E_FAIL if the variable is not in a register-relative memory
+ * location.
+ */
+ HRESULT GetOffset([out] LONG *pOffset);
+}
+
+
+
+/*
* ICorDebugHandleValue represents a reference value that the debugger has
* explicitly created a GC handle to. It does not represent GC Handles in the debuggee process,
@@ -6802,6 +6891,28 @@ interface ICorDebugValueEnum : ICorDebugEnum
[
object,
local,
+ uuid(e76b7a57-4f7a-4309-85a7-5d918c3deaf7),
+ pointer_default(unique)
+]
+interface ICorDebugVariableHomeEnum : ICorDebugEnum
+{
+ /*
+ * Next - gives the specified number of ICorDebugVariableHome instances from
+ * the enumeration, starting at the current position.
+ * celt is the number of requested instances.
+ * pceltFetched is the number of instances retrieved.
+ * returns S_FALSE if the actual number of instances retrieved is smaller
+ * than the number of instances requested.
+ */
+ HRESULT Next([in] ULONG celt,
+ [out, size_is(celt), length_is(*pceltFetched)]
+ ICorDebugVariableHome *homes[],
+ [out] ULONG *pceltFetched);
+};
+
+[
+ object,
+ local,
uuid(55E96461-9645-45e4-A2FF-0367877ABCDE),
pointer_default(unique)
]
@@ -6951,6 +7062,28 @@ interface ICorDebugType : IUnknown
};
+[
+ object,
+ local,
+ uuid(e6e91d79-693d-48bc-b417-8284b4f10fb5),
+ pointer_default(unique)
+]
+interface ICorDebugType2 : IUnknown
+{
+ /*
+ * GetTypeID - gives a COR_TYPEID for the ICorDebugType. This
+ * provides a mapping from the ICorDebugType, which represents a
+ * type that may or may not have been loaded into the runtime, to
+ * a COR_TYPEID, which serves as an opaque handle identifying a
+ * type loaded into the runtime. When the type that the
+ * ICorDebugType represents has not yet been loaded, this returns
+ * CORDBG_E_CLASS_NOT_LOADED. Returns CORDBG_E_UNSUPPORTED for
+ * unsupported types.
+ */
+ HRESULT GetTypeID([out] COR_TYPEID *id);
+};
+
+
/* ------------------------------------------------------------------------- *
* DEPRECATED
*
diff --git a/src/inc/corinfo.h b/src/inc/corinfo.h
index 6e41d8e035..e899a23379 100644
--- a/src/inc/corinfo.h
+++ b/src/inc/corinfo.h
@@ -231,11 +231,11 @@ TODO: Talk about initializing strutures before use
#if COR_JIT_EE_VERSION > 460
// Update this one
-SELECTANY const GUID JITEEVersionIdentifier = { /* 0b17dfeb-1ead-4e06-b025-d60d3a493b53 */
- 0x0b17dfeb,
- 0x1ead,
- 0x4e06,
- { 0xb0, 0x25, 0xd6, 0x0d, 0x3a, 0x49, 0x3b, 0x53 }
+SELECTANY const GUID JITEEVersionIdentifier = { /* 4bd06266-8ef7-4172-bec6-d3149fde7859 */
+ 0x4bd06266,
+ 0x8ef7,
+ 0x4172,
+ {0xbe, 0xc6, 0xd3, 0x14, 0x9f, 0xde, 0x78, 0x59}
};
#else
@@ -642,6 +642,7 @@ enum CorInfoHelpFunc
#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
@@ -910,10 +911,12 @@ enum CORINFO_ACCESS_FLAGS
// These are the flags set on an CORINFO_EH_CLAUSE
enum CORINFO_EH_CLAUSE_FLAGS
{
- CORINFO_EH_CLAUSE_NONE = 0,
- CORINFO_EH_CLAUSE_FILTER = 0x0001, // If this bit is on, then this EH entry is for a filter
- CORINFO_EH_CLAUSE_FINALLY = 0x0002, // This clause is a finally clause
- CORINFO_EH_CLAUSE_FAULT = 0x0004, // This clause is a fault clause
+ CORINFO_EH_CLAUSE_NONE = 0,
+ CORINFO_EH_CLAUSE_FILTER = 0x0001, // If this bit is on, then this EH entry is for a filter
+ CORINFO_EH_CLAUSE_FINALLY = 0x0002, // This clause is a finally clause
+ CORINFO_EH_CLAUSE_FAULT = 0x0004, // This clause is a fault clause
+ CORINFO_EH_CLAUSE_DUPLICATE = 0x0008, // Duplicated clause. This clause was duplicated to a funclet which was pulled out of line
+ CORINFO_EH_CLAUSE_SAMETRY = 0x0010, // This clause covers same try block as the previous one. (Used by CoreRT ABI.)
};
// This enumeration is passed to InternalThrow
@@ -1706,6 +1709,9 @@ 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)
@@ -2631,7 +2637,7 @@ public:
// in the code are. The native compiler will ensure that these places
// have a corresponding break point in native code.
//
- // Note that unless CORJIT_FLG_DEBUG_CODE is specified, this function will
+ // Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will
// be used only as a hint and the native compiler should not change its
// code generation.
virtual void getBoundaries(
@@ -2661,7 +2667,7 @@ public:
// under debugging, the JIT needs to keep them live over their
// entire scope so that they can be inspected.
//
- // Note that unless CORJIT_FLG_DEBUG_CODE is specified, this function will
+ // Note that unless CORJIT_FLAG_DEBUG_CODE is specified, this function will
// be used only as a hint and the native compiler should not change its
// code generation.
virtual void getVars(
diff --git a/src/inc/corjit.h b/src/inc/corjit.h
index e4deabd0e1..6d01b9f9d9 100644
--- a/src/inc/corjit.h
+++ b/src/inc/corjit.h
@@ -73,6 +73,8 @@ enum CorJitResult
};
+#if COR_JIT_EE_VERSION <= 460
+
/* values for flags in compileMethod */
enum CorJitFlag
@@ -133,21 +135,11 @@ enum CorJitFlag
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
-
-#if COR_JIT_EE_VERSION > 460
- CORJIT_FLG_CALL_GETJITFLAGS = 0xffffffff, // Indicates that the JIT should retrieve flags in the form of a
- // pointer to a CORJIT_FLAGS value via ICorJitInfo::getJitFlags().
-#endif
};
enum CorJitFlag2
{
CORJIT_FLG2_SAMPLING_JIT_BACKGROUND = 0x00000001, // JIT is being invoked as a result of stack sampling for hot methods in the background
-#if COR_JIT_EE_VERSION > 460
- CORJIT_FLG2_USE_PINVOKE_HELPERS = 0x00000002, // The JIT should use the PINVOKE_{BEGIN,END} helpers instead of emitting inline transitions
- CORJIT_FLG2_REVERSE_PINVOKE = 0x00000004, // The JIT should insert REVERSE_PINVOKE_{ENTER,EXIT} helpers into method prolog/epilog
- CORJIT_FLG2_DESKTOP_QUIRKS = 0x00000008, // The JIT should generate desktop-quirk-compatible code
-#endif
};
struct CORJIT_FLAGS
@@ -156,11 +148,157 @@ struct CORJIT_FLAGS
unsigned corJitFlags2; // Values are from CorJitFlag2
};
+#endif // COR_JIT_EE_VERSION <= 460
+
+#if COR_JIT_EE_VERSION > 460
+
+class CORJIT_FLAGS
+{
+public:
+
+ enum CorJitFlag
+ {
+ CORJIT_FLAG_CALL_GETJITFLAGS = 0xffffffff, // Indicates that the JIT should retrieve flags in the form of a
+ // pointer to a CORJIT_FLAGS value via ICorJitInfo::getJitFlags().
+ CORJIT_FLAG_SPEED_OPT = 0,
+ CORJIT_FLAG_SIZE_OPT = 1,
+ CORJIT_FLAG_DEBUG_CODE = 2, // generate "debuggable" code (no code-mangling optimizations)
+ CORJIT_FLAG_DEBUG_EnC = 3, // We are in Edit-n-Continue mode
+ CORJIT_FLAG_DEBUG_INFO = 4, // generate line and local-var info
+ CORJIT_FLAG_MIN_OPT = 5, // disable all jit optimizations (not necesarily debuggable code)
+ CORJIT_FLAG_GCPOLL_CALLS = 6, // Emit calls to JIT_POLLGC for thread suspension.
+ CORJIT_FLAG_MCJIT_BACKGROUND = 7, // Calling from multicore JIT background thread, do not call JitComplete
+
+ #if defined(_TARGET_X86_)
+
+ CORJIT_FLAG_PINVOKE_RESTORE_ESP = 8, // Restore ESP after returning from inlined PInvoke
+ CORJIT_FLAG_TARGET_P4 = 9,
+ CORJIT_FLAG_USE_FCOMI = 10, // Generated code may use fcomi(p) instruction
+ CORJIT_FLAG_USE_CMOV = 11, // Generated code may use cmov instruction
+ CORJIT_FLAG_USE_SSE2 = 12, // Generated code may use SSE-2 instructions
+
+ #else // !defined(_TARGET_X86_)
+
+ CORJIT_FLAG_UNUSED1 = 8,
+ CORJIT_FLAG_UNUSED2 = 9,
+ CORJIT_FLAG_UNUSED3 = 10,
+ CORJIT_FLAG_UNUSED4 = 11,
+ CORJIT_FLAG_UNUSED5 = 12,
+
+ #endif // !defined(_TARGET_X86_)
+
+ #if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
+
+ CORJIT_FLAG_USE_SSE3_4 = 13,
+ CORJIT_FLAG_USE_AVX = 14,
+ CORJIT_FLAG_USE_AVX2 = 15,
+ CORJIT_FLAG_USE_AVX_512 = 16,
+ CORJIT_FLAG_FEATURE_SIMD = 17,
+
+ #else // !defined(_TARGET_X86_) && !defined(_TARGET_AMD64_)
+
+ CORJIT_FLAG_UNUSED6 = 13,
+ CORJIT_FLAG_UNUSED7 = 14,
+ CORJIT_FLAG_UNUSED8 = 15,
+ CORJIT_FLAG_UNUSED9 = 16,
+ CORJIT_FLAG_UNUSED10 = 17,
+
+ #endif // !defined(_TARGET_X86_) && !defined(_TARGET_AMD64_)
+
+ CORJIT_FLAG_MAKEFINALCODE = 18, // Use the final code generator, i.e., not the interpreter.
+ CORJIT_FLAG_READYTORUN = 19, // Use version-resilient code generation
+ CORJIT_FLAG_PROF_ENTERLEAVE = 20, // Instrument prologues/epilogues
+ CORJIT_FLAG_PROF_REJIT_NOPS = 21, // Insert NOPs to ensure code is re-jitable
+ CORJIT_FLAG_PROF_NO_PINVOKE_INLINE = 22, // Disables PInvoke inlining
+ CORJIT_FLAG_SKIP_VERIFICATION = 23, // (lazy) skip verification - determined without doing a full resolve. See comment below
+ CORJIT_FLAG_PREJIT = 24, // jit or prejit is the execution engine.
+ CORJIT_FLAG_RELOC = 25, // Generate relocatable code
+ CORJIT_FLAG_IMPORT_ONLY = 26, // Only import the function
+ CORJIT_FLAG_IL_STUB = 27, // method is an IL stub
+ CORJIT_FLAG_PROCSPLIT = 28, // JIT should separate code into hot and cold sections
+ CORJIT_FLAG_BBINSTR = 29, // Collect basic block profile information
+ CORJIT_FLAG_BBOPT = 30, // Optimize method based on profile information
+ CORJIT_FLAG_FRAMED = 31, // All methods have an EBP frame
+ CORJIT_FLAG_ALIGN_LOOPS = 32, // add NOPs before loops to align them at 16 byte boundaries
+ CORJIT_FLAG_PUBLISH_SECRET_PARAM = 33, // JIT must place stub secret param into local 0. (used by IL stubs)
+ CORJIT_FLAG_GCPOLL_INLINE = 34, // JIT must inline calls to GCPoll when possible
+ CORJIT_FLAG_SAMPLING_JIT_BACKGROUND = 35, // JIT is being invoked as a result of stack sampling for hot methods in the background
+ 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_FLAGS()
+ : corJitFlags(0)
+ {
+ // empty
+ }
+
+ // Convenience constructor to set exactly one flag.
+ CORJIT_FLAGS(CorJitFlag flag)
+ : corJitFlags(0)
+ {
+ Set(flag);
+ }
+
+ CORJIT_FLAGS(const CORJIT_FLAGS& other)
+ {
+ corJitFlags = other.corJitFlags;
+ }
+
+ void Reset()
+ {
+ corJitFlags = 0;
+ }
+
+ void Set(CorJitFlag flag)
+ {
+ corJitFlags |= 1ULL << (unsigned __int64)flag;
+ }
+
+ void Clear(CorJitFlag flag)
+ {
+ corJitFlags &= ~(1ULL << (unsigned __int64)flag);
+ }
+
+ bool IsSet(CorJitFlag flag) const
+ {
+ return (corJitFlags & (1ULL << (unsigned __int64)flag)) != 0;
+ }
+
+ void Add(const CORJIT_FLAGS& other)
+ {
+ corJitFlags |= other.corJitFlags;
+ }
+
+ void Remove(const CORJIT_FLAGS& other)
+ {
+ corJitFlags &= ~other.corJitFlags;
+ }
+
+ bool IsEmpty() const
+ {
+ return corJitFlags == 0;
+ }
+
+ // DO NOT USE THIS FUNCTION! (except in very restricted special cases)
+ unsigned __int64 GetFlagsRaw()
+ {
+ return corJitFlags;
+ }
+
+private:
+
+ unsigned __int64 corJitFlags;
+};
+
+#endif // COR_JIT_EE_VERSION > 460
+
/*****************************************************************************
-Here is how CORJIT_FLG_SKIP_VERIFICATION should be interepreted.
+Here is how CORJIT_FLAG_SKIP_VERIFICATION should be interepreted.
Note that even if any method is inlined, it need not be verified.
-if (CORJIT_FLG_SKIP_VERIFICATION is passed in to ICorJitCompiler::compileMethod())
+if (CORJIT_FLAG_SKIP_VERIFICATION is passed in to ICorJitCompiler::compileMethod())
{
No verification needs to be done.
Just compile the method, generating unverifiable code if necessary
@@ -245,7 +383,7 @@ else
case INSTVER_GENERIC_PASSED_VERIFICATION:
{
- This cannot ever happen because the VM would pass in CORJIT_FLG_SKIP_VERIFICATION.
+ This cannot ever happen because the VM would pass in CORJIT_FLAG_SKIP_VERIFICATION.
}
case INSTVER_GENERIC_FAILED_VERIFICATION:
@@ -260,7 +398,7 @@ else
case CORINFO_VERIFICATION_CAN_SKIP:
{
- This cannot ever happen because the CLR would pass in CORJIT_FLG_SKIP_VERIFICATION.
+ This cannot ever happen because the CLR would pass in CORJIT_FLAG_SKIP_VERIFICATION.
}
case CORINFO_VERIFICATION_RUNTIME_CHECK:
@@ -377,7 +515,11 @@ 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,
diff --git a/src/inc/corprof.idl b/src/inc/corprof.idl
index 4288897844..9af1cd97a8 100644
--- a/src/inc/corprof.idl
+++ b/src/inc/corprof.idl
@@ -60,6 +60,10 @@ cpp_quote("#endif")
typedef const BYTE *LPCBYTE;
typedef BYTE *LPBYTE;
+typedef BYTE COR_SIGNATURE;
+typedef COR_SIGNATURE* PCOR_SIGNATURE;
+typedef const COR_SIGNATURE* PCCOR_SIGNATURE;
+
#endif
@@ -2375,6 +2379,36 @@ interface ICorProfilerCallback7 : ICorProfilerCallback6
}
+[
+ object,
+ uuid(5BED9B15-C079-4D47-BFE2-215A140C07E0),
+ pointer_default(unique),
+ local
+]
+interface ICorProfilerCallback8 : ICorProfilerCallback7
+{
+ // This event is triggered whenever a dynamic method is jit compiled.
+ // These include various IL Stubs and LCG Methods.
+ // The goal is to provide profiler writers with enough information to identify
+ // it to users as beyond unknown code addresses.
+ // Note: FunctionID's provided here cannot be used to resolve to their metadata
+ // tokens since dynamic methods have no metadata.
+ //
+ // Documentation Note: pILHeader is only valid during the callback
+
+ HRESULT DynamicMethodJITCompilationStarted(
+ [in] FunctionID functionId,
+ [in] BOOL fIsSafeToBlock,
+ [in] LPCBYTE pILHeader,
+ [in] ULONG cbILHeader);
+
+ HRESULT DynamicMethodJITCompilationFinished(
+ [in] FunctionID functionId,
+ [in] HRESULT hrStatus,
+ [in] BOOL fIsSafeToBlock);
+}
+
+
/*
* COR_PRF_CODEGEN_FLAGS controls various flags and hooks for a specific
* method. A combination of COR_PRF_CODEGEN_FLAGS is provided by the
@@ -3781,6 +3815,59 @@ interface ICorProfilerInfo7 : ICorProfilerInfo6
};
+[
+ object,
+ uuid(C5AC80A6-782E-4716-8044-39598C60CFBF),
+ pointer_default(unique),
+ local
+]
+interface ICorProfilerInfo8 : ICorProfilerInfo7
+{
+ /*
+ * Determines if a function has associated metadata
+ *
+ * Certain methods like IL Stubs or LCG Methods do not have
+ * associated metadata that can be retrieved using the IMetaDataImport APIs.
+ *
+ * Such methods can be encountered by profilers through instruction pointers
+ * or by listening to ICorProfilerCallback::DynamicMethodJITCompilationStarted
+ *
+ * This API can be used to determine whether a FunctionID is dynamic.
+ */
+ HRESULT IsFunctionDynamic( [in] FunctionID functionId,
+ [out] BOOL *isDynamic);
+
+ /*
+ * Maps a managed code instruction pointer to a FunctionID.
+ *
+ * GetFunctionFromIP2 fails for dynamic methods, this method works for
+ * both dynamic and non-dynamic methods. It is a superset of GetFunctionFromIP2
+ */
+ HRESULT GetFunctionFromIP3([in] LPCBYTE ip,
+ [out] FunctionID *functionId,
+ [out] ReJITID * pReJitId);
+
+ /*
+ * Retrieves informaiton about dynamic methods
+ *
+ * Certain methods like IL Stubs or LCG do not have
+ * associated metadata that can be retrieved using the IMetaDataImport APIs.
+ *
+ * Such methods can be encountered by profilers through instruction pointers
+ * or by listening to ICorProfilerCallback::DynamicMethodJITCompilationStarted
+ *
+ * This API can be used to retrieve information about dynamic methods
+ * including a friendly name if available.
+ */
+ HRESULT GetDynamicFunctionInfo( [in] FunctionID functionId,
+ [out] ModuleID *moduleId,
+ [out] PCCOR_SIGNATURE *ppvSig,
+ [out] ULONG *pbSig,
+ [in] ULONG cchName,
+ [out] ULONG *pcchName,
+ [out] WCHAR wszName[]);
+};
+
/*
* This interface lets you iterate over methods in the runtime.
*/
diff --git a/src/inc/daccess.h b/src/inc/daccess.h
index b4c5044bd9..6d9fb3265f 100644
--- a/src/inc/daccess.h
+++ b/src/inc/daccess.h
@@ -774,18 +774,18 @@ interface IMDInternalImport* DacGetMDImport(const ReflectionModule* reflectionMo
int DacGetIlMethodSize(TADDR methAddr);
struct COR_ILMETHOD* DacGetIlMethod(TADDR methAddr);
-#if defined(WIN64EXCEPTIONS)
+#ifdef WIN64EXCEPTIONS
struct _UNWIND_INFO * DacGetUnwindInfo(TADDR taUnwindInfo);
// virtually unwind a CONTEXT out-of-process
struct _KNONVOLATILE_CONTEXT_POINTERS;
BOOL DacUnwindStackFrame(T_CONTEXT * pContext, T_KNONVOLATILE_CONTEXT_POINTERS* pContextPointers);
+#endif // WIN64EXCEPTIONS
#if defined(FEATURE_PAL)
// call back through data target to unwind out-of-process
HRESULT DacVirtualUnwind(ULONG32 threadId, PCONTEXT context, PT_KNONVOLATILE_CONTEXT_POINTERS contextPointers);
#endif // FEATURE_PAL
-#endif // _WIN64
#ifdef FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
class SString;
diff --git a/src/inc/dacprivate.h b/src/inc/dacprivate.h
index 5a09abe113..0db4affcfc 100644
--- a/src/inc/dacprivate.h
+++ b/src/inc/dacprivate.h
@@ -20,6 +20,29 @@
#include <msodw.h>
#endif // FEATURE_PAL
+//
+// Whenever a structure is marshalled between different platforms, we need to ensure the
+// layout is the same in both cases. We tell GCC to use the MSVC-style packing with
+// the following attribute. The main thing this appears to control is whether
+// 8-byte values are aligned at 4-bytes (GCC default) or 8-bytes (MSVC default).
+// This attribute affects only the immediate struct it is applied to, you must also apply
+// it to any nested structs if you want their layout affected as well. You also must
+// apply this to unions embedded in other structures, since it can influence the starting
+// alignment.
+//
+// Note that there doesn't appear to be any disadvantage to applying this a little
+// more agressively than necessary, so we generally use it on all classes / structures
+// defined in a file that defines marshalled data types (eg. DacDbiStructures.h)
+// The -mms-bitfields compiler option also does this for the whole file, but we don't
+// want to go changing the layout of, for example, structures defined in OS header files
+// so we explicitly opt-in with this attribute.
+//
+#ifdef __GNUC__
+#define MSLAYOUT __attribute__((__ms_struct__))
+#else
+#define MSLAYOUT
+#endif
+
//----------------------------------------------------------------------------
//
// Utility class to allow for zero initialization of our Dacp- structs.
@@ -58,7 +81,7 @@ enum
};
enum DacpObjectType { OBJ_STRING=0,OBJ_FREE,OBJ_OBJECT,OBJ_ARRAY,OBJ_OTHER };
-struct DacpObjectData : ZeroInit<DacpObjectData>
+struct MSLAYOUT DacpObjectData : ZeroInit<DacpObjectData>
{
CLRDATA_ADDRESS MethodTable;
DacpObjectType ObjectType;
@@ -81,7 +104,7 @@ struct DacpObjectData : ZeroInit<DacpObjectData>
}
};
-struct DacpExceptionObjectData : ZeroInit<DacpExceptionObjectData>
+struct MSLAYOUT DacpExceptionObjectData : ZeroInit<DacpExceptionObjectData>
{
CLRDATA_ADDRESS Message;
CLRDATA_ADDRESS InnerException;
@@ -105,7 +128,7 @@ struct DacpExceptionObjectData : ZeroInit<DacpExceptionObjectData>
}
};
-struct DacpUsefulGlobalsData : ZeroInit<DacpUsefulGlobalsData>
+struct MSLAYOUT DacpUsefulGlobalsData : ZeroInit<DacpUsefulGlobalsData>
{
CLRDATA_ADDRESS ArrayMethodTable;
CLRDATA_ADDRESS StringMethodTable;
@@ -114,7 +137,7 @@ struct DacpUsefulGlobalsData : ZeroInit<DacpUsefulGlobalsData>
CLRDATA_ADDRESS FreeMethodTable;
};
-struct DacpFieldDescData : ZeroInit<DacpFieldDescData>
+struct MSLAYOUT DacpFieldDescData : ZeroInit<DacpFieldDescData>
{
CorElementType Type;
CorElementType sigType; // ELEMENT_TYPE_XXX from signature. We need this to disply pretty name for String in minidump's case
@@ -137,7 +160,7 @@ struct DacpFieldDescData : ZeroInit<DacpFieldDescData>
}
};
-struct DacpMethodTableFieldData : ZeroInit<DacpMethodTableFieldData>
+struct MSLAYOUT DacpMethodTableFieldData : ZeroInit<DacpMethodTableFieldData>
{
WORD wNumInstanceFields;
WORD wNumStaticFields;
@@ -154,7 +177,7 @@ struct DacpMethodTableFieldData : ZeroInit<DacpMethodTableFieldData>
}
};
-struct DacpMethodTableTransparencyData : ZeroInit<DacpMethodTableTransparencyData>
+struct MSLAYOUT DacpMethodTableTransparencyData : ZeroInit<DacpMethodTableTransparencyData>
{
BOOL bHasCriticalTransparentInfo;
BOOL bIsCritical;
@@ -166,7 +189,7 @@ struct DacpMethodTableTransparencyData : ZeroInit<DacpMethodTableTransparencyDat
}
};
-struct DacpDomainLocalModuleData : ZeroInit<DacpDomainLocalModuleData>
+struct MSLAYOUT DacpDomainLocalModuleData : ZeroInit<DacpDomainLocalModuleData>
{
// These two parameters are used as input params when calling the
// no-argument form of Request below.
@@ -186,7 +209,7 @@ struct DacpDomainLocalModuleData : ZeroInit<DacpDomainLocalModuleData>
};
-struct DacpThreadLocalModuleData : ZeroInit<DacpThreadLocalModuleData>
+struct MSLAYOUT DacpThreadLocalModuleData : ZeroInit<DacpThreadLocalModuleData>
{
// These two parameters are used as input params when calling the
// no-argument form of Request below.
@@ -200,7 +223,7 @@ struct DacpThreadLocalModuleData : ZeroInit<DacpThreadLocalModuleData>
};
-struct DacpModuleData : ZeroInit<DacpModuleData>
+struct MSLAYOUT DacpModuleData : ZeroInit<DacpModuleData>
{
CLRDATA_ADDRESS Address;
CLRDATA_ADDRESS File; // A PEFile addr
@@ -243,7 +266,7 @@ private:
void operator=(const DacpModuleData&);
};
-struct DacpMethodTableData : ZeroInit<DacpMethodTableData>
+struct MSLAYOUT DacpMethodTableData : ZeroInit<DacpMethodTableData>
{
BOOL bIsFree; // everything else is NULL if this is true.
CLRDATA_ADDRESS Module;
@@ -260,7 +283,7 @@ struct DacpMethodTableData : ZeroInit<DacpMethodTableData>
BOOL bIsShared; // flags & enum_flag_DomainNeutral
BOOL bIsDynamic;
BOOL bContainsPointers;
-
+
HRESULT Request(ISOSDacInterface *sos, CLRDATA_ADDRESS addr)
{
return sos->GetMethodTableData(addr, this);
@@ -279,7 +302,7 @@ struct DacpMethodTableData : ZeroInit<DacpMethodTableData>
#define CLRSECURITYHOSTED 0x80
#define CLRHOSTED 0x80000000
-struct DacpThreadStoreData : ZeroInit<DacpThreadStoreData>
+struct MSLAYOUT DacpThreadStoreData : ZeroInit<DacpThreadStoreData>
{
LONG threadCount;
LONG unstartedThreadCount;
@@ -290,14 +313,14 @@ struct DacpThreadStoreData : ZeroInit<DacpThreadStoreData>
CLRDATA_ADDRESS finalizerThread;
CLRDATA_ADDRESS gcThread;
DWORD fHostConfig; // Uses hosting flags defined above
-
+
HRESULT Request(ISOSDacInterface *sos)
{
return sos->GetThreadStoreData(this);
}
};
-struct DacpAppDomainStoreData : ZeroInit<DacpAppDomainStoreData>
+struct MSLAYOUT DacpAppDomainStoreData : ZeroInit<DacpAppDomainStoreData>
{
CLRDATA_ADDRESS sharedDomain;
CLRDATA_ADDRESS systemDomain;
@@ -309,14 +332,14 @@ struct DacpAppDomainStoreData : ZeroInit<DacpAppDomainStoreData>
}
};
-struct DacpCOMInterfacePointerData : ZeroInit<DacpCOMInterfacePointerData>
+struct MSLAYOUT DacpCOMInterfacePointerData : ZeroInit<DacpCOMInterfacePointerData>
{
CLRDATA_ADDRESS methodTable;
CLRDATA_ADDRESS interfacePtr;
CLRDATA_ADDRESS comContext;
};
-struct DacpRCWData : ZeroInit<DacpRCWData>
+struct MSLAYOUT DacpRCWData : ZeroInit<DacpRCWData>
{
CLRDATA_ADDRESS identityPointer;
CLRDATA_ADDRESS unknownPointer;
@@ -355,7 +378,7 @@ struct DacpRCWData : ZeroInit<DacpRCWData>
}
};
-struct DacpCCWData : ZeroInit<DacpCCWData>
+struct MSLAYOUT DacpCCWData : ZeroInit<DacpCCWData>
{
CLRDATA_ADDRESS outerIUnknown;
CLRDATA_ADDRESS managedObject;
@@ -397,7 +420,7 @@ enum DacpAppDomainDataStage {
// Information about a BaseDomain (AppDomain, SharedDomain or SystemDomain).
// For types other than AppDomain, some fields (like dwID, DomainLocalBlock, etc.) will be 0/null.
-struct DacpAppDomainData : ZeroInit<DacpAppDomainData>
+struct MSLAYOUT DacpAppDomainData : ZeroInit<DacpAppDomainData>
{
// The pointer to the BaseDomain (not necessarily an AppDomain).
// It's useful to keep this around in the structure
@@ -420,7 +443,7 @@ struct DacpAppDomainData : ZeroInit<DacpAppDomainData>
}
};
-struct DacpAssemblyData : ZeroInit<DacpAssemblyData>
+struct MSLAYOUT DacpAssemblyData : ZeroInit<DacpAssemblyData>
{
CLRDATA_ADDRESS AssemblyPtr; //useful to have
CLRDATA_ADDRESS ClassLoader;
@@ -445,7 +468,7 @@ struct DacpAssemblyData : ZeroInit<DacpAssemblyData>
};
-struct DacpThreadData : ZeroInit<DacpThreadData>
+struct MSLAYOUT DacpThreadData : ZeroInit<DacpThreadData>
{
DWORD corThreadId;
DWORD osThreadId;
@@ -470,7 +493,7 @@ struct DacpThreadData : ZeroInit<DacpThreadData>
};
-struct DacpReJitData : ZeroInit<DacpReJitData>
+struct MSLAYOUT DacpReJitData : ZeroInit<DacpReJitData>
{
enum Flags
{
@@ -485,7 +508,7 @@ struct DacpReJitData : ZeroInit<DacpReJitData>
CLRDATA_ADDRESS NativeCodeAddr;
};
-struct DacpMethodDescData : ZeroInit<DacpMethodDescData>
+struct MSLAYOUT DacpMethodDescData : ZeroInit<DacpMethodDescData>
{
BOOL bHasNativeCode;
BOOL bIsDynamic;
@@ -529,7 +552,7 @@ struct DacpMethodDescData : ZeroInit<DacpMethodDescData>
}
};
-struct DacpMethodDescTransparencyData : ZeroInit<DacpMethodDescTransparencyData>
+struct MSLAYOUT DacpMethodDescTransparencyData : ZeroInit<DacpMethodDescTransparencyData>
{
BOOL bHasCriticalTransparentInfo;
BOOL bIsCritical;
@@ -544,7 +567,7 @@ struct DacpMethodDescTransparencyData : ZeroInit<DacpMethodDescTransparencyData>
// for JITType
enum JITTypes {TYPE_UNKNOWN=0,TYPE_JIT,TYPE_PJIT};
-struct DacpCodeHeaderData : ZeroInit<DacpCodeHeaderData>
+struct MSLAYOUT DacpCodeHeaderData : ZeroInit<DacpCodeHeaderData>
{
CLRDATA_ADDRESS GCInfo;
JITTypes JITType;
@@ -561,7 +584,7 @@ struct DacpCodeHeaderData : ZeroInit<DacpCodeHeaderData>
}
};
-struct DacpWorkRequestData : ZeroInit<DacpWorkRequestData>
+struct MSLAYOUT DacpWorkRequestData : ZeroInit<DacpWorkRequestData>
{
CLRDATA_ADDRESS Function;
CLRDATA_ADDRESS Context;
@@ -573,7 +596,7 @@ struct DacpWorkRequestData : ZeroInit<DacpWorkRequestData>
}
};
-struct DacpHillClimbingLogEntry : ZeroInit<DacpHillClimbingLogEntry>
+struct MSLAYOUT DacpHillClimbingLogEntry : ZeroInit<DacpHillClimbingLogEntry>
{
DWORD TickCount;
int Transition;
@@ -589,7 +612,7 @@ struct DacpHillClimbingLogEntry : ZeroInit<DacpHillClimbingLogEntry>
// Used for CLR versions >= 4.0
-struct DacpThreadpoolData : ZeroInit<DacpThreadpoolData>
+struct MSLAYOUT DacpThreadpoolData : ZeroInit<DacpThreadpoolData>
{
LONG cpuUtilization;
int NumIdleWorkerThreads;
@@ -623,7 +646,7 @@ struct DacpThreadpoolData : ZeroInit<DacpThreadpoolData>
}
};
-struct DacpGenerationData : ZeroInit<DacpGenerationData>
+struct MSLAYOUT DacpGenerationData : ZeroInit<DacpGenerationData>
{
CLRDATA_ADDRESS start_segment;
CLRDATA_ADDRESS allocation_start;
@@ -636,18 +659,18 @@ struct DacpGenerationData : ZeroInit<DacpGenerationData>
#define DAC_NUMBERGENERATIONS 4
-struct DacpAllocData : ZeroInit<DacpAllocData>
+struct MSLAYOUT DacpAllocData : ZeroInit<DacpAllocData>
{
CLRDATA_ADDRESS allocBytes;
CLRDATA_ADDRESS allocBytesLoh;
};
-struct DacpGenerationAllocData : ZeroInit<DacpGenerationAllocData>
+struct MSLAYOUT DacpGenerationAllocData : ZeroInit<DacpGenerationAllocData>
{
DacpAllocData allocData[DAC_NUMBERGENERATIONS];
};
-struct DacpGcHeapDetails : ZeroInit<DacpGcHeapDetails>
+struct MSLAYOUT DacpGcHeapDetails : ZeroInit<DacpGcHeapDetails>
{
CLRDATA_ADDRESS heapAddr; // Only filled in in server mode, otherwise NULL
CLRDATA_ADDRESS alloc_allocated;
@@ -681,7 +704,7 @@ struct DacpGcHeapDetails : ZeroInit<DacpGcHeapDetails>
}
};
-struct DacpGcHeapData
+struct MSLAYOUT DacpGcHeapData
: ZeroInit<DacpGcHeapData>
{
BOOL bServerMode;
@@ -695,7 +718,7 @@ struct DacpGcHeapData
}
};
-struct DacpHeapSegmentData
+struct MSLAYOUT DacpHeapSegmentData
: ZeroInit<DacpHeapSegmentData>
{
CLRDATA_ADDRESS segmentAddr;
@@ -730,7 +753,7 @@ struct DacpHeapSegmentData
}
};
-struct DacpOomData : ZeroInit<DacpOomData>
+struct MSLAYOUT DacpOomData : ZeroInit<DacpOomData>
{
int reason;
ULONG64 alloc_size;
@@ -761,7 +784,7 @@ struct DacpOomData : ZeroInit<DacpOomData>
#define MAX_GC_MECHANISM_BITS_COUNT 2
// This is from ndp\clr\src\vm\common.h
#define MAX_GLOBAL_GC_MECHANISMS_COUNT 6
-struct DacpGCInterestingInfoData : ZeroInit<DacpGCInterestingInfoData>
+struct MSLAYOUT DacpGCInterestingInfoData : ZeroInit<DacpGCInterestingInfoData>
{
size_t interestingDataPoints[NUM_GC_DATA_POINTS];
size_t compactReasons[MAX_COMPACT_REASONS_COUNT];
@@ -808,7 +831,7 @@ struct DacpGCInterestingInfoData : ZeroInit<DacpGCInterestingInfoData>
}
};
-struct DacpGcHeapAnalyzeData
+struct MSLAYOUT DacpGcHeapAnalyzeData
: ZeroInit<DacpGcHeapAnalyzeData>
{
CLRDATA_ADDRESS heapAddr; // Only filled in in server mode, otherwise NULL
@@ -836,7 +859,7 @@ struct DacpGcHeapAnalyzeData
#define SYNCBLOCKDATA_COMFLAGS_RCW 2
#define SYNCBLOCKDATA_COMFLAGS_CF 4
-struct DacpSyncBlockData : ZeroInit<DacpSyncBlockData>
+struct MSLAYOUT DacpSyncBlockData : ZeroInit<DacpSyncBlockData>
{
CLRDATA_ADDRESS Object;
BOOL bFree; // if set, no other fields are useful
@@ -863,7 +886,7 @@ struct DacpSyncBlockData : ZeroInit<DacpSyncBlockData>
}
};
-struct DacpSyncBlockCleanupData : ZeroInit<DacpSyncBlockCleanupData>
+struct MSLAYOUT DacpSyncBlockCleanupData : ZeroInit<DacpSyncBlockCleanupData>
{
CLRDATA_ADDRESS SyncBlockPointer;
@@ -883,7 +906,7 @@ struct DacpSyncBlockCleanupData : ZeroInit<DacpSyncBlockCleanupData>
enum EHClauseType {EHFault, EHFinally, EHFilter, EHTyped, EHUnknown};
-struct DACEHInfo : ZeroInit<DACEHInfo>
+struct MSLAYOUT DACEHInfo : ZeroInit<DACEHInfo>
{
EHClauseType clauseType;
CLRDATA_ADDRESS tryStartOffset;
@@ -898,7 +921,7 @@ struct DACEHInfo : ZeroInit<DACEHInfo>
mdToken tokCatch; // the type token of the TYPED clause type
};
-struct DacpGetModuleAddress : ZeroInit<DacpGetModuleAddress>
+struct MSLAYOUT DacpGetModuleAddress : ZeroInit<DacpGetModuleAddress>
{
CLRDATA_ADDRESS ModulePtr;
HRESULT Request(IXCLRDataModule* pDataModule)
@@ -907,7 +930,7 @@ struct DacpGetModuleAddress : ZeroInit<DacpGetModuleAddress>
}
};
-struct DacpGetModuleData : ZeroInit<DacpGetModuleData>
+struct MSLAYOUT DacpGetModuleData : ZeroInit<DacpGetModuleData>
{
BOOL IsDynamic;
BOOL IsInMemory;
@@ -924,7 +947,7 @@ struct DacpGetModuleData : ZeroInit<DacpGetModuleData>
}
};
-struct DacpFrameData : ZeroInit<DacpFrameData>
+struct MSLAYOUT DacpFrameData : ZeroInit<DacpFrameData>
{
CLRDATA_ADDRESS frameAddr;
@@ -937,7 +960,7 @@ struct DacpFrameData : ZeroInit<DacpFrameData>
}
};
-struct DacpJitManagerInfo : ZeroInit<DacpJitManagerInfo>
+struct MSLAYOUT DacpJitManagerInfo : ZeroInit<DacpJitManagerInfo>
{
CLRDATA_ADDRESS managerAddr;
DWORD codeType; // for union below
@@ -946,14 +969,14 @@ struct DacpJitManagerInfo : ZeroInit<DacpJitManagerInfo>
enum CodeHeapType {CODEHEAP_LOADER=0,CODEHEAP_HOST,CODEHEAP_UNKNOWN};
-struct DacpJitCodeHeapInfo : ZeroInit<DacpJitCodeHeapInfo>
+struct MSLAYOUT DacpJitCodeHeapInfo : ZeroInit<DacpJitCodeHeapInfo>
{
DWORD codeHeapType; // for union below
union
{
CLRDATA_ADDRESS LoaderHeap; // if CODEHEAP_LOADER
- struct
+ struct MSLAYOUT
{
CLRDATA_ADDRESS baseAddr; // if CODEHEAP_HOST
CLRDATA_ADDRESS currentAddr;
diff --git a/src/inc/dacvars.h b/src/inc/dacvars.h
index fb052b3f5d..0a60684ad1 100644
--- a/src/inc/dacvars.h
+++ b/src/inc/dacvars.h
@@ -125,9 +125,10 @@ 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, GCHeap__gcHeapType, GCHeap::gcHeapType)
+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)
@@ -198,7 +199,7 @@ 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, GCHeap, dac__g_pGCHeap, ::g_pGCHeap)
+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)
@@ -217,6 +218,9 @@ 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)
@@ -229,8 +233,12 @@ 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)
@@ -244,7 +252,9 @@ 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)
diff --git a/src/inc/debugreturn.h b/src/inc/debugreturn.h
index dbcbd2bb46..e5013ccabe 100644
--- a/src/inc/debugreturn.h
+++ b/src/inc/debugreturn.h
@@ -27,9 +27,11 @@
#else // !_PREFAST_
-// This is disabled in VS2015 Update 3 and earlier because only C++11 constexpr is supported,
-// which doesn't allow the use of 'if' statements within the body of a constexpr function.
-#if defined(_DEBUG) && (!defined(_MSC_FULL_VER) || _MSC_FULL_VER > 190024210)
+// This is disabled in build 190024315 (a pre-release build after VS 2015 Update 3) and
+// earlier because those builds only support C++11 constexpr, which doesn't allow the
+// use of 'if' statements within the body of a constexpr function. Later builds support
+// C++14 constexpr.
+#if defined(_DEBUG) && (!defined(_MSC_FULL_VER) || _MSC_FULL_VER > 190024315)
// Code to generate a compile-time error if return statements appear where they
// shouldn't.
@@ -110,7 +112,7 @@ typedef __SafeToReturn __ReturnOK;
#define DEBUG_OK_TO_RETURN_BEGIN(arg) { typedef __SafeToReturn __ReturnOK; if (0 && __ReturnOK::used()) { } else {
#define DEBUG_OK_TO_RETURN_END(arg) } }
-#else // defined(_DEBUG) && (!defined(_MSC_FULL_VER) || _MSC_FULL_VER > 190024210)
+#else // defined(_DEBUG) && (!defined(_MSC_FULL_VER) || _MSC_FULL_VER > 190024315)
#define DEBUG_ASSURE_SAFE_TO_RETURN TRUE
@@ -120,7 +122,7 @@ typedef __SafeToReturn __ReturnOK;
#define DEBUG_OK_TO_RETURN_BEGIN(arg) {
#define DEBUG_OK_TO_RETURN_END(arg) }
-#endif // defined(_DEBUG) && (!defined(_MSC_FULL_VER) || _MSC_FULL_VER > 190024210)
+#endif // defined(_DEBUG) && (!defined(_MSC_FULL_VER) || _MSC_FULL_VER > 190024315)
#endif // !_PREFAST_
diff --git a/src/inc/eetwain.h b/src/inc/eetwain.h
index 6e183c5546..502d181962 100644
--- a/src/inc/eetwain.h
+++ b/src/inc/eetwain.h
@@ -278,16 +278,16 @@ virtual void * GetGSCookieAddr(PREGDISPLAY pContext,
Returns true if the given IP is in the given method's prolog or an epilog.
*/
virtual bool IsInPrologOrEpilog(DWORD relPCOffset,
- PTR_VOID methodInfoPtr,
+ GCInfoToken gcInfoToken,
size_t* prologSize) = 0;
/*
Returns true if the given IP is in the synchronized region of the method (valid for synchronized methods only)
*/
virtual bool IsInSynchronizedRegion(
- DWORD relOffset,
- PTR_VOID methodInfoPtr,
- unsigned flags) = 0;
+ DWORD relOffset,
+ GCInfoToken gcInfoToken,
+ unsigned flags) = 0;
/*
Returns the size of a given function as reported in the GC info (does
@@ -297,9 +297,15 @@ virtual bool IsInSynchronizedRegion(
virtual size_t GetFunctionSize(GCInfoToken gcInfoToken) = 0;
/*
+Returns the ReturnKind of a given function as reported in the GC info.
+*/
+
+virtual ReturnKind GetReturnKind(GCInfoToken gcInfotoken) = 0;
+
+/*
Returns the size of the frame (barring localloc)
*/
-virtual unsigned int GetFrameSize(PTR_VOID methodInfoPtr) = 0;
+virtual unsigned int GetFrameSize(GCInfoToken gcInfoToken) = 0;
#ifndef DACCESS_COMPILE
@@ -307,16 +313,16 @@ virtual unsigned int GetFrameSize(PTR_VOID methodInfoPtr) = 0;
virtual const BYTE* GetFinallyReturnAddr(PREGDISPLAY pReg)=0;
-virtual BOOL IsInFilter(void *methodInfoPtr,
+virtual BOOL IsInFilter(GCInfoToken gcInfoToken,
unsigned offset,
PCONTEXT pCtx,
DWORD curNestLevel) = 0;
-virtual BOOL LeaveFinally(void *methodInfoPtr,
+virtual BOOL LeaveFinally(GCInfoToken gcInfoToken,
unsigned offset,
PCONTEXT pCtx) = 0;
-virtual void LeaveCatch(void *methodInfoPtr,
+virtual void LeaveCatch(GCInfoToken gcInfoToken,
unsigned offset,
PCONTEXT pCtx)=0;
@@ -535,18 +541,18 @@ void * GetGSCookieAddr(PREGDISPLAY pContext,
*/
virtual
bool IsInPrologOrEpilog(
- DWORD relOffset,
- PTR_VOID methodInfoPtr,
- size_t* prologSize);
+ DWORD relOffset,
+ GCInfoToken gcInfoToken,
+ size_t* prologSize);
/*
Returns true if the given IP is in the synchronized region of the method (valid for synchronized functions only)
*/
virtual
bool IsInSynchronizedRegion(
- DWORD relOffset,
- PTR_VOID methodInfoPtr,
- unsigned flags);
+ DWORD relOffset,
+ GCInfoToken gcInfoToken,
+ unsigned flags);
/*
Returns the size of a given function.
@@ -555,23 +561,27 @@ virtual
size_t GetFunctionSize(GCInfoToken gcInfoToken);
/*
+Returns the ReturnKind of a given function.
+*/
+virtual ReturnKind GetReturnKind(GCInfoToken gcInfotoken);
+
+/*
Returns the size of the frame (barring localloc)
*/
virtual
-unsigned int GetFrameSize(
- PTR_VOID methodInfoPtr);
+unsigned int GetFrameSize(GCInfoToken gcInfoToken);
#ifndef DACCESS_COMPILE
virtual const BYTE* GetFinallyReturnAddr(PREGDISPLAY pReg);
-virtual BOOL LeaveFinally(void *methodInfoPtr,
+virtual BOOL LeaveFinally(GCInfoToken gcInfoToken,
unsigned offset,
PCONTEXT pCtx);
-virtual BOOL IsInFilter(void *methodInfoPtr,
+virtual BOOL IsInFilter(GCInfoToken gcInfoToken,
unsigned offset,
PCONTEXT pCtx,
DWORD curNestLevel);
-virtual void LeaveCatch(void *methodInfoPtr,
+virtual void LeaveCatch(GCInfoToken gcInfoToken,
unsigned offset,
PCONTEXT pCtx);
@@ -646,8 +656,9 @@ struct hdrInfo
{
unsigned int methodSize; // native code bytes
unsigned int argSize; // in bytes
- unsigned int stackSize; /* including callee saved registers */
- unsigned int rawStkSize; /* excluding callee saved registers */
+ unsigned int stackSize; // including callee saved registers
+ unsigned int rawStkSize; // excluding callee saved registers
+ ReturnKind returnKind; // The ReturnKind for this method.
unsigned int prologSize;
@@ -689,6 +700,7 @@ struct hdrInfo
unsigned int syncStartOffset; // start/end code offset of the protected region in synchronized methods.
unsigned int syncEndOffset; // INVALID_SYNC_OFFSET if there not synchronized method
unsigned int syncEpilogStart; // The start of the epilog. Synchronized methods are guaranteed to have no more than one epilog.
+ unsigned int revPInvokeOffset; // INVALID_REV_PINVOKE_OFFSET if there is no Reverse PInvoke frame
enum { NOT_IN_PROLOG = -1, NOT_IN_EPILOG = -1 };
diff --git a/src/inc/eventtrace.h b/src/inc/eventtrace.h
index 67d9b7942e..765249e87f 100644
--- a/src/inc/eventtrace.h
+++ b/src/inc/eventtrace.h
@@ -34,7 +34,29 @@
#define _VMEVENTTRACE_H_
#include "eventtracebase.h"
+#include "gcinterface.h"
+#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+struct ProfilingScanContext : ScanContext
+{
+ BOOL fProfilerPinned;
+ void * pvEtwContext;
+ void *pHeapId;
+
+ ProfilingScanContext(BOOL fProfilerPinnedParam) : ScanContext()
+ {
+ LIMITED_METHOD_CONTRACT;
+
+ pHeapId = NULL;
+ fProfilerPinned = fProfilerPinnedParam;
+ pvEtwContext = NULL;
+#ifdef FEATURE_CONSERVATIVE_GC
+ // To not confuse GCScan::GcScanRoots
+ promotion = g_pConfig->GetGCConservative();
+#endif
+ }
+};
+#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
#ifndef FEATURE_REDHAWK
diff --git a/src/inc/fstring.h b/src/inc/fstring.h
index 68c9098c8f..9245885896 100644
--- a/src/inc/fstring.h
+++ b/src/inc/fstring.h
@@ -21,6 +21,9 @@
namespace FString
{
+ // Note: All "length" parameters do not count the space for the null terminator.
+ // Caller of Unicode_Utf8 and Utf8_Unicode must pass in a buffer of size at least length + 1.
+
// Scan for ASCII only string, calculate result UTF8 string length
HRESULT Unicode_Utf8_Length(__in_z LPCWSTR pString, __out bool * pAllAscii, __out DWORD * pLength);
diff --git a/src/inc/gcdecoder.cpp b/src/inc/gcdecoder.cpp
index d337faeebc..a2a2e8ccd5 100644
--- a/src/inc/gcdecoder.cpp
+++ b/src/inc/gcdecoder.cpp
@@ -86,19 +86,19 @@ size_t FASTCALL decodeSigned(PTR_CBYTE src, int* val)
#pragma optimize("tgy", on)
#endif
-PTR_CBYTE FASTCALL decodeHeader(PTR_CBYTE table, InfoHdr* header)
+PTR_CBYTE FASTCALL decodeHeader(PTR_CBYTE table, UINT32 version, InfoHdr* header)
{
LIMITED_METHOD_DAC_CONTRACT;
- BYTE byte = *table++;
- BYTE encoding = byte & 0x7f;
-
+ BYTE nextByte = *table++;
+ BYTE encoding = nextByte & 0x7f;
GetInfoHdr(encoding, header);
-
- while (byte & 0x80)
+ while (nextByte & MORE_BYTES_TO_FOLLOW)
{
- byte = *table++;
- encoding = byte & 0x7f;
+ nextByte = *table++;
+ encoding = nextByte & ADJ_ENCODING_MAX;
+ // encoding here always corresponds to codes in InfoHdrAdjust set
+
if (encoding < NEXT_FOUR_START)
{
if (encoding < SET_ARGCOUNT)
@@ -126,6 +126,7 @@ PTR_CBYTE FASTCALL decodeHeader(PTR_CBYTE table, InfoHdr* header)
else if (encoding < FIRST_FLIP)
{
header->untrackedCnt = encoding - SET_UNTRACKED;
+ _ASSERTE(header->untrackedCnt != HAS_UNTRACKED);
}
else switch (encoding)
{
@@ -145,22 +146,22 @@ PTR_CBYTE FASTCALL decodeHeader(PTR_CBYTE table, InfoHdr* header)
header->ebpSaved ^= 1;
break;
case FLIP_EBP_FRAME:
- header->ebpFrame ^= 1;
+ header->ebpFrame ^= 1;
break;
case FLIP_INTERRUPTIBLE:
- header->interruptible ^= 1;
+ header->interruptible ^= 1;
break;
case FLIP_DOUBLE_ALIGN:
- header->doubleAlign ^= 1;
+ header->doubleAlign ^= 1;
break;
case FLIP_SECURITY:
- header->security ^= 1;
+ header->security ^= 1;
break;
case FLIP_HANDLERS:
- header->handlers ^= 1;
+ header->handlers ^= 1;
break;
case FLIP_LOCALLOC:
- header->localloc ^= 1;
+ header->localloc ^= 1;
break;
case FLIP_EDITnCONTINUE:
header->editNcontinue ^= 1;
@@ -172,10 +173,10 @@ PTR_CBYTE FASTCALL decodeHeader(PTR_CBYTE table, InfoHdr* header)
header->untrackedCnt = HAS_UNTRACKED;
break;
case FLIP_VARARGS:
- header->varargs ^= 1;
+ header->varargs ^= 1;
break;
case FLIP_PROF_CALLBACKS:
- header->profCallbacks ^= 1;
+ header->profCallbacks ^= 1;
break;
case FLIP_HAS_GENERICS_CONTEXT:
header->genericsContext ^= 1;
@@ -189,6 +190,27 @@ PTR_CBYTE FASTCALL decodeHeader(PTR_CBYTE table, InfoHdr* header)
case FLIP_SYNC:
header->syncStartOffset ^= HAS_SYNC_OFFSET;
break;
+ case FLIP_REV_PINVOKE_FRAME:
+ _ASSERTE(GCInfoEncodesRevPInvokeFrame(version));
+ header->revPInvokeOffset ^= HAS_REV_PINVOKE_FRAME_OFFSET;
+ break;
+
+ case NEXT_OPCODE:
+ _ASSERTE((nextByte & MORE_BYTES_TO_FOLLOW) && "Must have another code");
+ nextByte = *table++;
+ encoding = nextByte & ADJ_ENCODING_MAX;
+ // encoding here always corresponds to codes in InfoHdrAdjust2 set
+
+ if (encoding < SET_RET_KIND_MAX)
+ {
+ _ASSERTE(GCInfoEncodesReturnKind(version));
+ header->returnKind = (ReturnKind)encoding;
+ }
+ else
+ {
+ assert(!"Unexpected encoding");
+ }
+ break;
}
}
else
@@ -202,14 +224,14 @@ PTR_CBYTE FASTCALL decodeHeader(PTR_CBYTE table, InfoHdr* header)
case 5:
assert(NEXT_FOUR_FRAMESIZE == 0x50);
lowBits = encoding & 0xf;
- header->frameSize <<= 4;
- header->frameSize += lowBits;
+ header->frameSize <<= 4;
+ header->frameSize += lowBits;
break;
case 6:
assert(NEXT_FOUR_ARGCOUNT == 0x60);
lowBits = encoding & 0xf;
- header->argCount <<= 4;
- header->argCount += lowBits;
+ header->argCount <<= 4;
+ header->argCount += lowBits;
break;
case 7:
if ((encoding & 0x8) == 0)
@@ -217,14 +239,14 @@ PTR_CBYTE FASTCALL decodeHeader(PTR_CBYTE table, InfoHdr* header)
assert(NEXT_THREE_PROLOGSIZE == 0x70);
lowBits = encoding & 0x7;
header->prologSize <<= 3;
- header->prologSize += lowBits;
+ header->prologSize += lowBits;
}
else
{
assert(NEXT_THREE_EPILOGSIZE == 0x78);
lowBits = encoding & 0x7;
header->epilogSize <<= 3;
- header->epilogSize += lowBits;
+ header->epilogSize += lowBits;
}
break;
}
@@ -293,154 +315,155 @@ const InfoHdrSmall infoHdrShortcut[128] = {
// | | | | | | | | | | | | | | | | |
// | | | | | | | | | | | | | | | | | genericsContext
// | | | | | | | | | | | | | | | | | |
-// | | | | | | | | | | | | | | | | | | genericsContextIsMethodDesc
-// | | | | | | | | | | | | | | | | | | |
-// | | | | | | | | | | | | | | | | | | | Arg count
-// | | | | | | | | | | | | | | | | | | | | Counted occurances
-// | | | | | | | | | | | | | | | | | | | | Frame size |
-// | | | | | | | | | | | | | | | | | | | | | |
-// | | | | | | | | | | | | | | | | | | | | | untrackedCnt | Header encoding
-// | | | | | | | | | | | | | | | | | | | | | | | |
-// | | | | | | | | | | | | | | | | | | | | | | varPtrTable | |
-// | | | | | | | | | | | | | | | | | | | | | | | | |
-// | | | | | | | | | | | | | | | | | | | | | | | gsCookieOffs | |
-// | | | | | | | | | | | | | | | | | | | | | | | | | |
-// | | | | | | | | | | | | | | | | | | | | | | | | syncOffs | |
-// | | | | | | | | | | | | | | | | | | | | | | | | | | | |
-// | | | | | | | | | | | | | | | | | | | | | | | | | | | |
-// | | | | | | | | | | | | | | | | | | | | | | | | | | | |
-// v v v v v v v v v v v v v v v v v v v v v v v v v v v v
- { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1139 00
- { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 128738 01
- { 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 3696 02
- { 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 402 03
- { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 4259 04
- { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, // 3379 05
- { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 2058 06
- { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0 }, // 728 07
- { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0 }, // 984 08
- { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0 }, // 606 09
- { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0 }, // 1110 0a
- { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 1, 0 }, // 414 0b
- { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 1553 0c
- { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, YES }, // 584 0d
- { 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 2182 0e
- { 1, 2, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 3445 0f
- { 1, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1369 10
- { 1, 2, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 515 11
- { 1, 2, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 21127 12
- { 1, 2, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 3517 13
- { 1, 2, 3, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 750 14
- { 1, 4, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1876 15
- { 1, 4, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, // 1665 16
- { 1, 4, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 729 17
- { 1, 4, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0 }, // 484 18
- { 1, 4, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 331 19
- { 2, 3, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 361 1a
- { 2, 3, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 964 1b
- { 2, 3, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 3713 1c
- { 2, 3, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 466 1d
- { 2, 3, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1325 1e
- { 2, 3, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 712 1f
- { 2, 3, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 588 20
- { 2, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 20542 21
- { 2, 3, 2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 3802 22
- { 2, 3, 3, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 798 23
- { 2, 5, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1900 24
- { 2, 5, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 385 25
- { 2, 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1617 26
- { 2, 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, // 1743 27
- { 2, 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 909 28
- { 2, 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0 }, // 602 29
- { 2, 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0 }, // 352 2a
- { 2, 6, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 657 2b
- { 2, 7, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, YES }, // 1283 2c
- { 2, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 1286 2d
- { 3, 4, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1495 2e
- { 3, 4, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1989 2f
- { 3, 4, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1154 30
- { 3, 4, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 9300 31
- { 3, 4, 2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 392 32
- { 3, 4, 2, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1720 33
- { 3, 6, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1246 34
- { 3, 6, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 800 35
- { 3, 6, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1179 36
- { 3, 6, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, // 1368 37
- { 3, 6, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 349 38
- { 3, 6, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0 }, // 505 39
- { 3, 6, 2, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 629 3a
- { 3, 8, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 2, YES }, // 365 3b
- { 4, 5, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 487 3c
- { 4, 5, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1752 3d
- { 4, 5, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1959 3e
- { 4, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 2436 3f
- { 4, 5, 2, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 861 40
- { 4, 7, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1459 41
- { 4, 7, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 950 42
- { 4, 7, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1491 43
- { 4, 7, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, // 879 44
- { 4, 7, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 408 45
- { 5, 4, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 4870 46
- { 5, 6, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 359 47
- { 5, 6, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // 915 48
- { 5, 6, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0 }, // 412 49
- { 5, 6, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1288 4a
- { 5, 6, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 1591 4b
- { 5, 6, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, YES }, // 361 4c
- { 5, 6, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0 }, // 623 4d
- { 5, 8, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0 }, // 1239 4e
- { 6, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 457 4f
- { 6, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 606 50
- { 6, 4, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, YES }, // 1073 51
- { 6, 4, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, YES }, // 508 52
- { 6, 6, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 330 53
- { 6, 6, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1709 54
- { 6, 7, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // 1164 55
- { 7, 4, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 556 56
- { 7, 5, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, YES }, // 529 57
- { 7, 5, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, YES }, // 1423 58
- { 7, 8, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, YES }, // 2455 59
- { 7, 8, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // 956 5a
- { 7, 8, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, YES }, // 1399 5b
- { 7, 8, 2, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, YES }, // 587 5c
- { 7, 10, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 1, YES }, // 743 5d
- { 7, 10, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0 }, // 1004 5e
- { 7, 10, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, YES }, // 487 5f
- { 7, 10, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0 }, // 337 60
- { 7, 10, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, YES }, // 361 61
- { 8, 3, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 }, // 560 62
- { 8, 6, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // 1377 63
- { 9, 4, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 }, // 877 64
- { 9, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // 3041 65
- { 9, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, YES }, // 349 66
- { 10, 5, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0 }, // 2061 67
- { 10, 5, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 }, // 577 68
- { 11, 6, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0 }, // 1195 69
- { 12, 5, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 491 6a
- { 13, 8, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, YES }, // 627 6b
- { 13, 8, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0 }, // 1099 6c
- { 13, 10, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 1, YES }, // 488 6d
- { 14, 7, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 574 6e
- { 16, 7, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, YES }, // 1281 6f
- { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, YES }, // 1881 70
- { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 339 71
- { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0 }, // 2594 72
- { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0 }, // 339 73
- { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, YES }, // 2107 74
- { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, YES }, // 2372 75
- { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, YES }, // 1078 76
- { 16, 7, 2, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, YES }, // 384 77
- { 16, 9, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 4, 1, YES }, // 1541 78
- { 16, 9, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 4, 1, YES }, // 975 79
- { 19, 7, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, YES }, // 546 7a
- { 24, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, YES }, // 675 7b
- { 45, 9, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 902 7c
- { 51, 7, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, YES }, // 432 7d
- { 51, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 361 7e
- { 51, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0 }, // 703 7f
+// | | | | | | | | | | | | | | | | | | genericsContextIsMethodDesc
+// | | | | | | | | | | | | | | | | | | |
+// | | | | | | | | | | | | | | | | | | | returnKind
+// | | | | | | | | | | | | | | | | | | | |
+// | | | | | | | | | | | | | | | | | | | | Arg count
+// | | | | | | | | | | | | | | | | | | | | | Counted occurences
+// | | | | | | | | | | | | | | | | | | | | | Frame size |
+// | | | | | | | | | | | | | | | | | | | | | | |
+// | | | | | | | | | | | | | | | | | | | | | | untrackedCnt | Header encoding
+// | | | | | | | | | | | | | | | | | | | | | | | | |
+// | | | | | | | | | | | | | | | | | | | | | | | varPtrTable | |
+// | | | | | | | | | | | | | | | | | | | | | | | | | |
+// | | | | | | | | | | | | | | | | | | | | | | | | gsCookieOffs | |
+// | | | | | | | | | | | | | | | | | | | | | | | | | | |
+// | | | | | | | | | | | | | | | | | | | | | | | | | syncOffs | |
+// | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+// | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+// | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+// v v v v v v v v v v v v v v v v v v v v v v v v v v v v v
+ { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1139 00
+ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 128738 01
+ { 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 3696 02
+ { 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 402 03
+ { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 4259 04
+ { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, // 3379 05
+ { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 2058 06
+ { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0 }, // 728 07
+ { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0 }, // 984 08
+ { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0 }, // 606 09
+ { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0 }, // 1110 0a
+ { 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 1, 0 }, // 414 0b
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 1553 0c
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, YES }, // 584 0d
+ { 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 2182 0e
+ { 1, 2, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 3445 0f
+ { 1, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1369 10
+ { 1, 2, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 515 11
+ { 1, 2, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 21127 12
+ { 1, 2, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 3517 13
+ { 1, 2, 3, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 750 14
+ { 1, 4, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1876 15
+ { 1, 4, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, // 1665 16
+ { 1, 4, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 729 17
+ { 1, 4, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0 }, // 484 18
+ { 1, 4, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 331 19
+ { 2, 3, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 361 1a
+ { 2, 3, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 964 1b
+ { 2, 3, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 3713 1c
+ { 2, 3, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 466 1d
+ { 2, 3, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1325 1e
+ { 2, 3, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 712 1f
+ { 2, 3, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 588 20
+ { 2, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 20542 21
+ { 2, 3, 2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 3802 22
+ { 2, 3, 3, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 798 23
+ { 2, 5, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1900 24
+ { 2, 5, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 385 25
+ { 2, 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1617 26
+ { 2, 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, // 1743 27
+ { 2, 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 909 28
+ { 2, 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0 }, // 602 29
+ { 2, 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0 }, // 352 2a
+ { 2, 6, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 657 2b
+ { 2, 7, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, YES }, // 1283 2c
+ { 2, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 1286 2d
+ { 3, 4, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1495 2e
+ { 3, 4, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1989 2f
+ { 3, 4, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1154 30
+ { 3, 4, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 9300 31
+ { 3, 4, 2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 392 32
+ { 3, 4, 2, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1720 33
+ { 3, 6, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1246 34
+ { 3, 6, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 800 35
+ { 3, 6, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1179 36
+ { 3, 6, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, // 1368 37
+ { 3, 6, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 349 38
+ { 3, 6, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0 }, // 505 39
+ { 3, 6, 2, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 629 3a
+ { 3, 8, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 2, YES }, // 365 3b
+ { 4, 5, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 487 3c
+ { 4, 5, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1752 3d
+ { 4, 5, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1959 3e
+ { 4, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 2436 3f
+ { 4, 5, 2, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 861 40
+ { 4, 7, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1459 41
+ { 4, 7, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 950 42
+ { 4, 7, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1491 43
+ { 4, 7, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, // 879 44
+ { 4, 7, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 408 45
+ { 5, 4, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 4870 46
+ { 5, 6, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 359 47
+ { 5, 6, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // 915 48
+ { 5, 6, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0 }, // 412 49
+ { 5, 6, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1288 4a
+ { 5, 6, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 1591 4b
+ { 5, 6, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, YES }, // 361 4c
+ { 5, 6, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0 }, // 623 4d
+ { 5, 8, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0 }, // 1239 4e
+ { 6, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 457 4f
+ { 6, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 606 50
+ { 6, 4, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, YES }, // 1073 51
+ { 6, 4, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, YES }, // 508 52
+ { 6, 6, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 330 53
+ { 6, 6, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1709 54
+ { 6, 7, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // 1164 55
+ { 7, 4, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 556 56
+ { 7, 5, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, YES }, // 529 57
+ { 7, 5, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, YES }, // 1423 58
+ { 7, 8, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, YES }, // 2455 59
+ { 7, 8, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // 956 5a
+ { 7, 8, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, YES }, // 1399 5b
+ { 7, 8, 2, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, YES }, // 587 5c
+ { 7, 10, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 1, YES }, // 743 5d
+ { 7, 10, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0 }, // 1004 5e
+ { 7, 10, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, YES }, // 487 5f
+ { 7, 10, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0 }, // 337 60
+ { 7, 10, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, YES }, // 361 61
+ { 8, 3, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 }, // 560 62
+ { 8, 6, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // 1377 63
+ { 9, 4, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 }, // 877 64
+ { 9, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // 3041 65
+ { 9, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, YES }, // 349 66
+ { 10, 5, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0 }, // 2061 67
+ { 10, 5, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 }, // 577 68
+ { 11, 6, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0 }, // 1195 69
+ { 12, 5, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 491 6a
+ { 13, 8, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, YES }, // 627 6b
+ { 13, 8, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0 }, // 1099 6c
+ { 13, 10, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 1, YES }, // 488 6d
+ { 14, 7, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 574 6e
+ { 16, 7, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, YES }, // 1281 6f
+ { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, YES }, // 1881 70
+ { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 339 71
+ { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0 }, // 2594 72
+ { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0 }, // 339 73
+ { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, YES }, // 2107 74
+ { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, YES }, // 2372 75
+ { 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, YES }, // 1078 76
+ { 16, 7, 2, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, YES }, // 384 77
+ { 16, 9, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 4, 1, YES }, // 1541 78
+ { 16, 9, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 4, 1, YES }, // 975 79
+ { 19, 7, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, YES }, // 546 7a
+ { 24, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, YES }, // 675 7b
+ { 45, 9, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 902 7c
+ { 51, 7, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, YES }, // 432 7d
+ { 51, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 361 7e
+ { 51, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0 }, // 703 7f
};
-
bool InfoHdrSmall::isHeaderMatch(const InfoHdr& target) const
{
#ifdef _ASSERTE
@@ -448,7 +471,8 @@ bool InfoHdrSmall::isHeaderMatch(const InfoHdr& target) const
_ASSERTE(target.untrackedCnt != HAS_UNTRACKED &&
target.varPtrTableSize != HAS_VARPTR &&
target.gsCookieOffset != HAS_GS_COOKIE_OFFSET &&
- target.syncStartOffset != HAS_SYNC_OFFSET);
+ target.syncStartOffset != HAS_SYNC_OFFSET &&
+ target.revPInvokeOffset != HAS_REV_PINVOKE_FRAME_OFFSET);
#endif
// compare two InfoHdr's up to but not including the untrackCnt field
@@ -470,7 +494,13 @@ bool InfoHdrSmall::isHeaderMatch(const InfoHdr& target) const
if (target.gsCookieOffset != INVALID_GS_COOKIE_OFFSET)
return false;
- return target.syncStartOffset == INVALID_SYNC_OFFSET;
+ if (target.syncStartOffset != INVALID_SYNC_OFFSET)
+ return false;
+
+ if (target.revPInvokeOffset!= INVALID_REV_PINVOKE_OFFSET)
+ return false;
+
+ return true;
}
@@ -503,7 +533,7 @@ const unsigned callCommonDelta[4] = { 6,8,10,12 };
* EDI = 0x1, ESI = 0x2, EBX = 0x4, EBP = 0x8
*
*/
-const unsigned callPatternTable[80] = { // # of occurances
+const unsigned callPatternTable[80] = { // # of occurences
0x0a000200, // 30109
0x0c000200, // 22970
0x0c000201, // 19005
diff --git a/src/inc/gcdump.h b/src/inc/gcdump.h
index cd73940ded..3271ca1d6b 100644
--- a/src/inc/gcdump.h
+++ b/src/inc/gcdump.h
@@ -45,7 +45,7 @@ public:
* Return value : Size in bytes of the header encoding
*/
- unsigned FASTCALL DumpInfoHdr (PTR_CBYTE gcInfoBlock,
+ unsigned FASTCALL DumpInfoHdr (PTR_CBYTE gcInfoBlock,
InfoHdr * header, /* OUT */
unsigned * methodSize, /* OUT */
bool verifyGCTables = false);
@@ -53,7 +53,7 @@ public:
/*-------------------------------------------------------------------------
* Dumps the GC tables to 'stdout'
- * table : The GCInfoToken
+ * gcInfoBlock : Start of the GC info block
* verifyGCTables : If the JIT has been compiled with VERIFY_GC_TABLES
* Return value : Size in bytes of the GC table encodings
*/
@@ -70,10 +70,10 @@ public:
* verifyGCTables : If the JIT has been compiled with VERIFY_GC_TABLES
*/
- void FASTCALL DumpPtrsInFrame(PTR_CBYTE infoBlock,
- PTR_CBYTE codeBlock,
- unsigned offs,
- bool verifyGCTables = false);
+ void FASTCALL DumpPtrsInFrame(PTR_CBYTE gcInfoBlock,
+ PTR_CBYTE codeBlock,
+ unsigned offs,
+ bool verifyGCTables = false);
public:
diff --git a/src/inc/gcinfo.h b/src/inc/gcinfo.h
index 8d249a38a6..e5537e0526 100644
--- a/src/inc/gcinfo.h
+++ b/src/inc/gcinfo.h
@@ -32,15 +32,21 @@ const unsigned this_OFFSET_FLAG = 0x2; // the offset is "this"
// The current GCInfo Version
//-----------------------------------------------------------------------------
-#ifdef _TARGET_X86_
-// X86 GcInfo encoding is yet to be changed.
-#define GCINFO_VERSION 1
-#else
#define GCINFO_VERSION 2
-#endif // _TARGET_X86_
#define MIN_GCINFO_VERSION_WITH_RETURN_KIND 2
#define MIN_GCINFO_VERSION_WITH_REV_PINVOKE_FRAME 2
+
+inline BOOL GCInfoEncodesReturnKind(UINT32 version=GCINFO_VERSION)
+{
+ return version >= MIN_GCINFO_VERSION_WITH_RETURN_KIND;
+}
+
+inline BOOL GCInfoEncodesRevPInvokeFrame(UINT32 version=GCINFO_VERSION)
+{
+ return version >= MIN_GCINFO_VERSION_WITH_REV_PINVOKE_FRAME;
+}
+
//-----------------------------------------------------------------------------
// GCInfoToken: A wrapper that contains the GcInfo data and version number.
//
@@ -62,11 +68,11 @@ struct GCInfoToken
BOOL IsReturnKindAvailable()
{
- return (Version >= MIN_GCINFO_VERSION_WITH_RETURN_KIND);
+ return GCInfoEncodesReturnKind(Version);
}
BOOL IsReversePInvokeFrameAvailable()
{
- return (Version >= MIN_GCINFO_VERSION_WITH_REV_PINVOKE_FRAME);
+ return GCInfoEncodesRevPInvokeFrame(Version);
}
static UINT32 ReadyToRunVersionToGcInfoVersion(UINT32 readyToRunMajorVersion)
diff --git a/src/inc/gcinfodecoder.h b/src/inc/gcinfodecoder.h
index c77c3598b0..6d4850ad67 100644
--- a/src/inc/gcinfodecoder.h
+++ b/src/inc/gcinfodecoder.h
@@ -11,16 +11,47 @@
#ifndef _GC_INFO_DECODER_
#define _GC_INFO_DECODER_
-#include "gcinfotypes.h"
-
#define _max(a, b) (((a) > (b)) ? (a) : (b))
#define _min(a, b) (((a) < (b)) ? (a) : (b))
-#ifndef GCINFODECODER_NO_EE
+#if !defined(_TARGET_X86_)
+#define USE_GC_INFO_DECODER
+#endif
+
+#if !defined(GCINFODECODER_NO_EE)
#include "eetwain.h"
-#else // GCINFODECODER_NO_EE
+#else
+
+#ifdef FEATURE_REDHAWK
+
+typedef ArrayDPTR(const uint8_t) PTR_CBYTE;
+
+#define LIMITED_METHOD_CONTRACT
+#define SUPPORTS_DAC
+
+#define LOG(x)
+#define LOG_PIPTR(pObjRef, gcFlags, hCallBack)
+#define DAC_ARG(x)
+
+#define VALIDATE_ROOT(isInterior, hCallBack, pObjRef)
+
+#define _ASSERTE(x) assert(x)
+
+#define UINT32 UInt32
+#define INT32 Int32
+#define UINT16 UInt16
+#define UINT UInt32
+#define SIZE_T UIntNative
+#define SSIZE_T IntNative
+#define LPVOID void*
+
+typedef void * OBJECTREF;
+
+#define GET_CALLER_SP(pREGDISPLAY) ((TADDR)0)
+
+#else // FEATURE_REDHAWK
// Stuff from cgencpu.h:
@@ -112,11 +143,17 @@ inline BOOL IS_ALIGNED( void* val, size_t alignment )
#ifndef _EETWAIN_H
typedef void (*GCEnumCallback)(
- LPVOID hCallback, // callback data
+ void * hCallback, // callback data
OBJECTREF* pObject, // address of obect-reference we are reporting
uint32_t flags // is this a pinned and/or interior pointer
);
+#endif // !_EETWAIN_H
+
+#include "regdisp.h"
+
+#endif // FEATURE_REDHAWK
+
#ifndef _strike_h
enum ICodeManagerFlags
@@ -135,16 +172,9 @@ enum ICodeManagerFlags
#endif // !_strike_h
-#if !defined(_TARGET_X86_)
-#define USE_GC_INFO_DECODER
-#endif
-
-#include "regdisp.h"
-
-#endif // !_EETWAIN_H
-
#endif // GCINFODECODER_NO_EE
+
#include "gcinfotypes.h"
#ifdef _DEBUG
@@ -153,10 +183,6 @@ enum ICodeManagerFlags
#define MAX_PREDECODED_SLOTS 64
#endif
-#if defined(FEATURE_PAL) && !defined(STATIC_CONTRACT_SUPPORTS_DAC_HOST_ONLY)
-#define STATIC_CONTRACT_SUPPORTS_DAC_HOST_ONLY
-#endif
-
enum GcInfoDecoderFlags
@@ -286,8 +312,6 @@ public:
__forceinline void SetCurrentPos( size_t pos )
{
- STATIC_CONTRACT_SUPPORTS_DAC_HOST_ONLY; // note: this will set only the host instance, not the target instance
-
size_t adjPos = pos + m_InitialRelPos;
m_pCurrent = m_pBuffer + adjPos / BITS_PER_SIZE_T;
m_RelPos = (int)(adjPos % BITS_PER_SIZE_T);
@@ -431,7 +455,7 @@ class GcInfoDecoder
{
public:
- // If you are not insterested in interruptibility or gc lifetime information, pass 0 as instructionOffset
+ // If you are not interested in interruptibility or gc lifetime information, pass 0 as instructionOffset
GcInfoDecoder(
GCInfoToken gcInfoToken,
GcInfoDecoderFlags flags = DECODE_EVERYTHING,
@@ -448,16 +472,16 @@ public:
// This is used for gccoverage
bool IsSafePoint(UINT32 codeOffset);
- typedef void EnumerateSafePointsCallback (UINT32 offset, LPVOID hCallback);
- void EnumerateSafePoints(EnumerateSafePointsCallback *pCallback, LPVOID hCallback);
+ typedef void EnumerateSafePointsCallback (UINT32 offset, void * hCallback);
+ void EnumerateSafePoints(EnumerateSafePointsCallback * pCallback, void * hCallback);
#endif
// Returns true to stop enumerating.
- typedef bool EnumerateInterruptibleRangesCallback (UINT32 startOffset, UINT32 stopOffset, LPVOID hCallback);
+ typedef bool EnumerateInterruptibleRangesCallback (UINT32 startOffset, UINT32 stopOffset, void * hCallback);
void EnumerateInterruptibleRanges (
EnumerateInterruptibleRangesCallback *pCallback,
- LPVOID hCallback);
+ void * hCallback);
//------------------------------------------------------------------------
// GC lifetime information
@@ -468,7 +492,7 @@ public:
bool reportScratchSlots,
unsigned flags,
GCEnumCallback pCallBack,
- LPVOID hCallBack
+ void * hCallBack
);
// Public for the gc info dumper
@@ -476,7 +500,7 @@ public:
PREGDISPLAY pRD,
unsigned flags,
GCEnumCallback pCallBack,
- LPVOID hCallBack
+ void * hCallBack
);
//------------------------------------------------------------------------
@@ -490,7 +514,7 @@ public:
UINT32 GetPrologSize();
INT32 GetPSPSymStackSlot();
INT32 GetGenericsInstContextStackSlot();
- INT32 GetReversePInvokeStackSlot();
+ INT32 GetReversePInvokeFrameStackSlot();
bool HasMethodDescGenericsInstContext();
bool HasMethodTableGenericsInstContext();
bool GetIsVarArg();
@@ -518,7 +542,7 @@ private:
bool m_WantsReportOnlyLeaf;
INT32 m_SecurityObjectStackSlot;
INT32 m_GSCookieStackSlot;
- INT32 m_ReversePInvokeStackSlot;
+ INT32 m_ReversePInvokeFrameStackSlot;
UINT32 m_ValidRangeStart;
UINT32 m_ValidRangeEnd;
INT32 m_PSPSymStackSlot;
@@ -526,7 +550,6 @@ private:
UINT32 m_CodeLength;
UINT32 m_StackBaseRegister;
UINT32 m_SizeOfEditAndContinuePreservedArea;
- INT32 m_ReversePInvokeFrameSlot;
ReturnKind m_ReturnKind;
#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED
UINT32 m_NumSafePoints;
@@ -545,7 +568,7 @@ private:
#endif
UINT32 m_Version;
- static bool SetIsInterruptibleCB (UINT32 startOffset, UINT32 stopOffset, LPVOID hCallback);
+ static bool SetIsInterruptibleCB (UINT32 startOffset, UINT32 stopOffset, void * hCallback);
OBJECTREF* GetRegisterSlot(
int regNum,
@@ -577,7 +600,7 @@ private:
PREGDISPLAY pRD,
unsigned flags,
GCEnumCallback pCallBack,
- LPVOID hCallBack
+ void * hCallBack
);
void ReportRegisterToGC(
@@ -586,7 +609,7 @@ private:
PREGDISPLAY pRD,
unsigned flags,
GCEnumCallback pCallBack,
- LPVOID hCallBack
+ void * hCallBack
);
void ReportStackSlotToGC(
@@ -596,7 +619,7 @@ private:
PREGDISPLAY pRD,
unsigned flags,
GCEnumCallback pCallBack,
- LPVOID hCallBack
+ void * hCallBack
);
@@ -607,7 +630,7 @@ private:
bool reportScratchSlots,
unsigned inputFlags,
GCEnumCallback pCallBack,
- LPVOID hCallBack
+ void * hCallBack
)
{
_ASSERTE(slotIndex < slotDecoder.GetNumSlots());
diff --git a/src/inc/gcinfoencoder.h b/src/inc/gcinfoencoder.h
index 838f1babf7..d09f43058f 100644
--- a/src/inc/gcinfoencoder.h
+++ b/src/inc/gcinfoencoder.h
@@ -100,6 +100,11 @@
#include "gcinfotypes.h"
+// As stated in issue #6008, GcInfoSize should be incorporated into debug builds.
+#ifdef _DEBUG
+#define MEASURE_GCINFO
+#endif
+
#ifdef MEASURE_GCINFO
struct GcInfoSize
{
@@ -110,10 +115,13 @@ struct GcInfoSize
size_t NumRanges;
size_t NumRegs;
size_t NumStack;
- size_t NumEh;
+ size_t NumUntracked;
size_t NumTransitions;
size_t SizeOfCode;
+ size_t EncPreservedSlots;
+ size_t UntrackedSlotSize;
+ size_t NumUntrackedSize;
size_t FlagsSize;
size_t RetKindSize;
size_t CodeLengthSize;
@@ -134,7 +142,6 @@ struct GcInfoSize
size_t RegSlotSize;
size_t StackSlotSize;
size_t CallSiteStateSize;
- size_t NumEhSize;
size_t EhPosSize;
size_t EhStateSize;
size_t ChunkPtrSize;
diff --git a/src/inc/gcinfotypes.h b/src/inc/gcinfotypes.h
index cd19759634..c802d97ec6 100644
--- a/src/inc/gcinfotypes.h
+++ b/src/inc/gcinfotypes.h
@@ -6,49 +6,15 @@
#ifndef __GCINFOTYPES_H__
#define __GCINFOTYPES_H__
+#ifndef FEATURE_REDHAWK
#include "gcinfo.h"
+#endif
-// This file is included when building an "alt jit". In that case, we are doing a cross-compile:
-// we may be building the ARM jit on x86, for example. We generally make that work by conditionalizing on
-// a _TARGET_XXX_ variable that we explicitly set in the build, rather than the _XXX_ variable implicitly
-// set by the compiler. But this file is *also* included by the runtime, and needs in that case to be
-// conditionalized by the actual platform we're compiling for. We solve this by:
-// 1) conditionalizing on _TARGET_XXX_ in this file,
-// 2) having a _TARGET_SET_ variable so we know whether we're in a compilation for JIT in which some
-// _TARGET_XXX_ has already been set, and
-// 3) if _TARGET_SET_ is not set, set the _TARGET_XXX_ variable appropriate for the current _XXX_.
-//
-#ifndef _TARGET_SET_
-
-//#ifdef _X86_
-//#define _TARGET_X86_
-//#endif
-
-//#ifdef _AMD64_
-//#define _TARGET_AMD64_
-//#endif
-
-//#ifdef _ARM_
-//#define _TARGET_ARM_
-//#endif
-
-#endif // _TARGET_SET_
-#if defined(_TARGET_AMD64_) || defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
#define PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED
-#endif
-
-#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED
-//
-// The EH vector mechanism is not completely worked out,
-// so it's temporarily disabled. We rely on fully-interruptible instead.
-//
-#define DISABLE_EH_VECTORS
-#endif
-#if defined(_TARGET_AMD64_) || defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
#define FIXED_STACK_PARAMETER_SCRATCH_AREA
-#endif
+
#define BITS_PER_SIZE_T ((int)sizeof(size_t)*8)
@@ -376,12 +342,17 @@ enum infoHdrAdjustConstants {
SET_PROLOGSIZE_MAX = 16,
SET_EPILOGSIZE_MAX = 10, // Change to 6
SET_EPILOGCNT_MAX = 4,
- SET_UNTRACKED_MAX = 3
+ SET_UNTRACKED_MAX = 3,
+ SET_RET_KIND_MAX = 4, // 2 bits for ReturnKind
+ ADJ_ENCODING_MAX = 0x7f, // Maximum valid encoding in a byte
+ // Also used to mask off next bit from each encoding byte.
+ MORE_BYTES_TO_FOLLOW = 0x80 // If the High-bit of a header or adjustment byte
+ // is set, then there are more adjustments to follow.
};
//
-// Enum to define the 128 codes that are used to incrementally adjust the InfoHdr structure
-//
+// Enum to define codes that are used to incrementally adjust the InfoHdr structure.
+// First set of opcodes
enum infoHdrAdjust {
SET_FRAMESIZE = 0, // 0x00
@@ -412,18 +383,25 @@ enum infoHdrAdjust {
FLIP_SYNC, // 0x4B
FLIP_HAS_GENERICS_CONTEXT,// 0x4C
FLIP_GENERICS_CONTEXT_IS_METHODDESC,// 0x4D
+ FLIP_REV_PINVOKE_FRAME, // 0x4E
+ NEXT_OPCODE, // 0x4F -- see next Adjustment enumeration
+ NEXT_FOUR_START = 0x50,
+ NEXT_FOUR_FRAMESIZE = 0x50,
+ NEXT_FOUR_ARGCOUNT = 0x60,
+ NEXT_THREE_PROLOGSIZE = 0x70,
+ NEXT_THREE_EPILOGSIZE = 0x78
+};
- // 0x4E .. 0x4f unused
-
- NEXT_FOUR_START = 0x50,
- NEXT_FOUR_FRAMESIZE = 0x50,
- NEXT_FOUR_ARGCOUNT = 0x60,
- NEXT_THREE_PROLOGSIZE = 0x70,
- NEXT_THREE_EPILOGSIZE = 0x78
+// Second set of opcodes, when first code is 0x4F
+enum infoHdrAdjust2 {
+ SET_RETURNKIND = 0, // 0x00-SET_RET_KIND_MAX Set ReturnKind to value
};
#define HAS_UNTRACKED ((unsigned int) -1)
#define HAS_VARPTR ((unsigned int) -1)
+
+#define INVALID_REV_PINVOKE_OFFSET 0
+#define HAS_REV_PINVOKE_FRAME_OFFSET ((unsigned int) -1)
// 0 is not a valid offset for EBP-frames as all locals are at a negative offset
// For ESP frames, the cookie is above (at a higher address than) the buffers,
// and so cannot be at offset 0.
@@ -463,6 +441,7 @@ struct InfoHdrSmall {
unsigned char profCallbacks : 1; // 4 [0]
unsigned char genericsContext : 1;//4 [1] function reports a generics context parameter is present
unsigned char genericsContextIsMethodDesc : 1;//4[2]
+ unsigned char returnKind : 2; // 4 [4] Available GcInfo v2 onwards, previously undefined
unsigned short argCount; // 5,6 in bytes
unsigned int frameSize; // 7,8,9,10 in bytes
unsigned int untrackedCnt; // 11,12,13,14
@@ -483,8 +462,8 @@ struct InfoHdr : public InfoHdrSmall {
unsigned int gsCookieOffset; // 19,20,21,22
unsigned int syncStartOffset; // 23,24,25,26
unsigned int syncEndOffset; // 27,28,29,30
-
- // 31 bytes total
+ unsigned int revPInvokeOffset; // 31,32,33,34 Available GcInfo v2 onwards, previously undefined
+ // 35 bytes total
// Checks whether "this" is compatible with "target".
// It is not an exact bit match as "this" could have some
@@ -498,7 +477,8 @@ struct InfoHdr : public InfoHdrSmall {
_ASSERTE(target.untrackedCnt != HAS_UNTRACKED &&
target.varPtrTableSize != HAS_VARPTR &&
target.gsCookieOffset != HAS_GS_COOKIE_OFFSET &&
- target.syncStartOffset != HAS_SYNC_OFFSET);
+ target.syncStartOffset != HAS_SYNC_OFFSET &&
+ target.revPInvokeOffset != HAS_REV_PINVOKE_FRAME_OFFSET);
#endif
// compare two InfoHdr's up to but not including the untrackCnt field
@@ -525,6 +505,10 @@ struct InfoHdr : public InfoHdrSmall {
(target.syncStartOffset == INVALID_SYNC_OFFSET))
return false;
+ if ((revPInvokeOffset == INVALID_REV_PINVOKE_OFFSET) !=
+ (target.revPInvokeOffset == INVALID_REV_PINVOKE_OFFSET))
+ return false;
+
return true;
}
};
@@ -551,15 +535,16 @@ inline void GetInfoHdr(int index, InfoHdr * header)
{
*((InfoHdrSmall *)header) = infoHdrShortcut[index];
- header->gsCookieOffset = 0;
- header->syncStartOffset = 0;
- header->syncEndOffset = 0;
+ header->gsCookieOffset = INVALID_GS_COOKIE_OFFSET;
+ header->syncStartOffset = INVALID_SYNC_OFFSET;
+ header->syncEndOffset = INVALID_SYNC_OFFSET;
+ header->revPInvokeOffset = INVALID_REV_PINVOKE_OFFSET;
}
-PTR_CBYTE FASTCALL decodeHeader(PTR_CBYTE table, InfoHdr* header);
+PTR_CBYTE FASTCALL decodeHeader(PTR_CBYTE table, UINT32 version, InfoHdr* header);
BYTE FASTCALL encodeHeaderFirst(const InfoHdr& header, InfoHdr* state, int* more, int *pCached);
-BYTE FASTCALL encodeHeaderNext(const InfoHdr& header, InfoHdr* state);
+BYTE FASTCALL encodeHeaderNext(const InfoHdr& header, InfoHdr* state, BYTE &codeSet);
size_t FASTCALL decodeUnsigned(PTR_CBYTE src, unsigned* value);
size_t FASTCALL decodeUDelta(PTR_CBYTE src, unsigned* value, unsigned lastValue);
diff --git a/src/inc/jithelpers.h b/src/inc/jithelpers.h
index 8a719927e5..f84db9142d 100644
--- a/src/inc/jithelpers.h
+++ b/src/inc/jithelpers.h
@@ -302,15 +302,16 @@
JITHELPER(CORINFO_HELP_VIRTUAL_FUNC_PTR, JIT_VirtualFunctionPointer, CORINFO_HELP_SIG_4_STACK)
//JITHELPER(CORINFO_HELP_VIRTUAL_FUNC_PTR_LOG,JIT_VirtualFunctionPointerLogging)
- JITHELPER(CORINFO_HELP_READYTORUN_NEW, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB)
- JITHELPER(CORINFO_HELP_READYTORUN_NEWARR_1, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB)
- JITHELPER(CORINFO_HELP_READYTORUN_ISINSTANCEOF, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB)
- 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)
+ JITHELPER(CORINFO_HELP_READYTORUN_NEW, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB)
+ JITHELPER(CORINFO_HELP_READYTORUN_NEWARR_1, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB)
+ JITHELPER(CORINFO_HELP_READYTORUN_ISINSTANCEOF, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB)
+ 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_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)
diff --git a/src/inc/livedatatarget.h b/src/inc/livedatatarget.h
index 7282dd4be1..1ffbca7d78 100644
--- a/src/inc/livedatatarget.h
+++ b/src/inc/livedatatarget.h
@@ -14,6 +14,7 @@
// Does not include IXClrData definitions.
#include <clrdata.h>
+#ifndef FEATURE_PAL
//---------------------------------------------------------------------------------------
//
@@ -100,6 +101,7 @@ private:
CLRDATA_ADDRESS m_baseAddressOfEngine;
};
+#endif // FEATURE_PAL
#endif // _LIVEPROC_DATATARGET_H_
diff --git a/src/inc/longfilepathwrappers.h b/src/inc/longfilepathwrappers.h
index a847988935..a0ffe38da5 100644
--- a/src/inc/longfilepathwrappers.h
+++ b/src/inc/longfilepathwrappers.h
@@ -124,18 +124,18 @@ GetLongPathNameWrapper(
SString& lpszLongPath
);
-UINT GetTempFileNameWrapper(
+UINT WINAPI GetTempFileNameWrapper(
_In_ LPCTSTR lpPathName,
_In_ LPCTSTR lpPrefixString,
_In_ UINT uUnique,
SString& lpTempFileName
);
-DWORD GetTempPathWrapper(
+DWORD WINAPI GetTempPathWrapper(
SString& lpBuffer
);
-DWORD GetCurrentDirectoryWrapper(
+DWORD WINAPI GetCurrentDirectoryWrapper(
SString& lpBuffer
);
@@ -145,7 +145,7 @@ GetModuleFileNameWrapper(
SString& buffer
);
-DWORD GetEnvironmentVariableWrapper(
+DWORD WINAPI GetEnvironmentVariableWrapper(
_In_opt_ LPCTSTR lpName,
_Out_opt_ SString& lpBuffer
);
diff --git a/src/inc/shash.inl b/src/inc/shash.inl
index 72affb45ba..f48899a588 100644
--- a/src/inc/shash.inl
+++ b/src/inc/shash.inl
@@ -22,8 +22,8 @@ SHash<TRAITS>::SHash()
LIMITED_METHOD_CONTRACT;
#ifndef __GNUC__ // these crash GCC
- static_assert_no_msg(s_growth_factor_numerator > s_growth_factor_denominator);
- static_assert_no_msg(s_density_factor_numerator < s_density_factor_denominator);
+ static_assert_no_msg(SHash<TRAITS>::s_growth_factor_numerator > SHash<TRAITS>::s_growth_factor_denominator);
+ static_assert_no_msg(SHash<TRAITS>::s_density_factor_numerator < SHash<TRAITS>::s_density_factor_denominator);
#endif
}
diff --git a/src/inc/sortversioning.h b/src/inc/sortversioning.h
index 7bc01c67f2..fe3e878802 100644
--- a/src/inc/sortversioning.h
+++ b/src/inc/sortversioning.h
@@ -107,7 +107,7 @@ namespace SortVersioning
PSORTHANDLE GetSortHandle(__in LPCWSTR lpLocaleName, __in_opt CONST NLSVERSIONINFO * pVersion);
- int SortCompareString(__in LPCWSTR lpLocaleName,
+ int WINAPI SortCompareString(__in LPCWSTR lpLocaleName,
__in DWORD dwCmpFlags,
__in_ecount(cchCount1) LPCWSTR lpString1,
__in int cchCount1,
@@ -137,7 +137,7 @@ namespace SortVersioning
__reserved LPVOID lpReserved,
__reserved LPARAM lParam );
- __success(return != 0) int SortDllChangeCase(
+ __success(return != 0) int WINAPI SortDllChangeCase(
__in PSORTHANDLE pSort,
__in DWORD dwFlags,
__in_ecount(cchSrc) LPCWSTR pSrc,
@@ -147,7 +147,7 @@ namespace SortVersioning
__in_opt LPVOID lpReserved,
__in_opt LPARAM lParam );
- __success(return != 0) int SortDllGetSortKey(
+ __success(return != 0) int WINAPI SortDllGetSortKey(
__in PSORTHANDLE pSort,
__in DWORD dwFlags,
__in_ecount(cchSrc) LPCWSTR pSrc,
@@ -157,7 +157,7 @@ namespace SortVersioning
__in_opt LPVOID lpReserved,
__in_opt LPARAM lParam );
- int SortFindString(__in LPCWSTR lpLocaleName,
+ int WINAPI SortFindString(__in LPCWSTR lpLocaleName,
__in DWORD dwFindNLSStringFlags,
__in_ecount(cchSource) LPCWSTR lpStringSource,
__in int cchSource,
@@ -168,7 +168,7 @@ namespace SortVersioning
__reserved LPVOID lpReserved,
__reserved LPARAM lParam);
- __success(return != 0) int SortDllFindString(
+ __success(return != 0) int WINAPI SortDllFindString(
__in PSORTHANDLE pSort,
__in DWORD dwFindNLSStringFlags,
__in_ecount(cchSource) LPCWSTR lpStringSource,
@@ -179,7 +179,7 @@ namespace SortVersioning
__in_opt LPVOID lpReserved,
__in_opt LPARAM lParam);
- BOOL SortIsDefinedString(__in NLS_FUNCTION Function,
+ BOOL WINAPI SortIsDefinedString(__in NLS_FUNCTION Function,
__in DWORD dwFlags,
__in_opt CONST NLSVERSIONINFOEX * lpVersionInfo,
__in LPCWSTR lpString,
diff --git a/src/inc/stacktrace.h b/src/inc/stacktrace.h
index 83646c85ef..49e951780c 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)
+#if defined(_TARGET_X86_) && defined(FEATURE_CORECLR) && !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
+#else // _TARGET_X86_ && FEATURE_CORECLR && !FEATURE_PAL
#define ClrCaptureContext RtlCaptureContext
-#endif // _X86 && FEATURE_CORECLR else
+#endif // _TARGET_X86_ && FEATURE_CORECLR && !FEATURE_PAL
#endif
diff --git a/src/inc/stresslog.h b/src/inc/stresslog.h
index 86dee130c4..55fb27a56d 100644
--- a/src/inc/stresslog.h
+++ b/src/inc/stresslog.h
@@ -683,7 +683,7 @@ public:
static const char* gcRootPromoteMsg()
{
STATIC_CONTRACT_LEAF;
- return " GCHeap::Promote: Promote GC Root *%p = %p MT = %pT\n";
+ return " IGCHeap::Promote: Promote GC Root *%p = %p MT = %pT\n";
}
static const char* gcPlugMoveMsg()
diff --git a/src/inc/utilcode.h b/src/inc/utilcode.h
index c519e8b872..a1a083638b 100644
--- a/src/inc/utilcode.h
+++ b/src/inc/utilcode.h
@@ -134,6 +134,17 @@ inline TADDR PCODEToPINSTR(PCODE pc)
#endif
}
+// Convert from a PINSTR to the corresponding PCODE. On many architectures this will be the identity function;
+// on ARM, this will raise the THUMB bit.
+inline PCODE PINSTRToPCODE(TADDR addr)
+{
+#ifdef _TARGET_ARM_
+ return DataPointerToThumbCode<PCODE,TADDR>(addr);
+#else
+ return dac_cast<PCODE>(addr);
+#endif
+}
+
typedef LPCSTR LPCUTF8;
typedef LPSTR LPUTF8;
@@ -3389,7 +3400,7 @@ public:
m_iSize = iBuckets + 7;
}
- ~CClosedHashBase()
+ virtual ~CClosedHashBase()
{
WRAPPER_NO_CONTRACT;
Clear();
@@ -5170,6 +5181,11 @@ template<class T> void DeleteExecutable(T *p)
INDEBUG(BOOL DbgIsExecutable(LPVOID lpMem, SIZE_T length);)
+BOOL NoGuiOnAssert();
+#ifdef _DEBUG
+VOID TerminateOnAssert();
+#endif // _DEBUG
+
class HighCharHelper {
public:
static inline BOOL IsHighChar(int c) {
@@ -5750,4 +5766,6 @@ extern SpinConstants g_SpinConstants;
// ======================================================================================
+void* __stdcall GetCLRFunction(LPCSTR FunctionName);
+
#endif // __UtilCode_h__
diff --git a/src/inc/winwrap.h b/src/inc/winwrap.h
index 91a71b700b..4a012d3726 100644
--- a/src/inc/winwrap.h
+++ b/src/inc/winwrap.h
@@ -86,8 +86,6 @@
#undef lstrcmp
#undef lstrcmpi
#undef lstrcpyn
-#undef lstrcpy
-#undef lstrcat
#undef lstrlen
#undef CreateMutex
#undef OpenMutex
@@ -222,7 +220,6 @@
// winuser.h
#undef MAKEINTRESOURCE
#undef wvsprintf
-#undef wsprintf
#undef LoadKeyboardLayout
#undef GetKeyboardLayoutName
#undef CreateDesktop
@@ -395,8 +392,6 @@
#define WszQueryRecoveryAgents QueryRecoveryAgentsW
#define Wszlstrcmp lstrcmpW
#define Wszlstrcmpi lstrcmpiW
-#define Wszlstrcpy lstrcpyW
-#define Wszlstrcat lstrcatW
#define WszCreateMutex CreateMutexW
#define WszOpenMutex OpenMutexW
#define WszCreateEvent CreateEventW
@@ -684,8 +679,6 @@
// on win98 and higher
#define Wszlstrlen lstrlenW
-#define Wszlstrcpy lstrcpyW
-#define Wszlstrcat lstrcatW
//File and Directory Functions which need special handling for LongFile Names
//Note only the functions which are currently used are defined
diff --git a/src/inc/xmlparser_i.c b/src/inc/xmlparser_i.cpp
index 33927f651f..33927f651f 100644
--- a/src/inc/xmlparser_i.c
+++ b/src/inc/xmlparser_i.cpp
diff --git a/src/inc/zapper.h b/src/inc/zapper.h
index 2fa94373fa..1018505faa 100644
--- a/src/inc/zapper.h
+++ b/src/inc/zapper.h
@@ -540,7 +540,7 @@ class ZapperOptions
bool m_fNGenLastRetry; // This is retry of the compilation
- unsigned m_compilerFlags;
+ CORJIT_FLAGS m_compilerFlags;
bool m_legacyMode; // true if the zapper was invoked using legacy mode
diff --git a/src/ipcman/ipcshared.h b/src/ipcman/ipcshared.h
index d40b0ba53e..865509dfc3 100644
--- a/src/ipcman/ipcshared.h
+++ b/src/ipcman/ipcshared.h
@@ -75,8 +75,8 @@ public:
HANDLE & pPrivateNamespace,
PSID* pSID,
BOOL bCreate);
- static HRESULT IPCShared::FreeHandles(HANDLE & hDescriptor, PSID & pSID);
- static HRESULT IPCShared::FreeHandles(HANDLE & hBoundaryDescriptor, PSID & pSID, HANDLE & hPrivateNamespace);
+ static HRESULT FreeHandles(HANDLE & hDescriptor, PSID & pSID);
+ static HRESULT FreeHandles(HANDLE & hBoundaryDescriptor, PSID & pSID, HANDLE & hPrivateNamespace);
static HRESULT CreateWinNTDescriptor(DWORD pid, BOOL bRestrictiveACL, SECURITY_ATTRIBUTES **ppSA, KernelObject whatObject);
static HRESULT CreateWinNTDescriptor(DWORD pid, BOOL bRestrictiveACL, SECURITY_ATTRIBUTES **ppSA, KernelObject whatObject, EDescriptorType descType);
static void DestroySecurityAttributes(SECURITY_ATTRIBUTES *pSA);
diff --git a/src/jit/CMakeLists.txt b/src/jit/CMakeLists.txt
index 6372e37852..96b8c496b9 100644
--- a/src/jit/CMakeLists.txt
+++ b/src/jit/CMakeLists.txt
@@ -7,9 +7,9 @@ include_directories("../inc")
# Enable the following for UNIX altjit on Windows
# add_definitions(-DALT_JIT)
-if (CLR_CMAKE_TARGET_ARCH_AMD64)
- add_definitions(-DFEATURE_SIMD)
- add_definitions(-DFEATURE_AVX_SUPPORT)
+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 ()
@@ -23,6 +23,7 @@ set( JIT_SOURCES
bitset.cpp
block.cpp
codegencommon.cpp
+ codegenlinear.cpp
compiler.cpp
copyprop.cpp
disasm.cpp
@@ -194,19 +195,17 @@ endif()
add_custom_target(jit_exports DEPENDS ${JIT_EXPORTS_FILE})
-set(JIT_BASE_NAME clrjit)
-if (CLR_BUILD_JIT32)
- set(JIT_BASE_NAME ryujit)
-endif()
-
-if(WIN32)
- add_definitions(-DFX_VER_INTERNALNAME_STR=${JIT_BASE_NAME}.dll)
-endif(WIN32)
-
add_subdirectory(dll)
add_subdirectory(crossgen)
add_subdirectory(standalone)
-if (CLR_CMAKE_PLATFORM_ARCH_I386 OR CLR_CMAKE_PLATFORM_ARCH_ARM)
+if (CLR_CMAKE_PLATFORM_ARCH_ARM)
add_subdirectory(protojit)
-endif (CLR_CMAKE_PLATFORM_ARCH_I386 OR CLR_CMAKE_PLATFORM_ARCH_ARM)
+endif (CLR_CMAKE_PLATFORM_ARCH_ARM)
+
+if (CLR_CMAKE_PLATFORM_ARCH_I386)
+ add_subdirectory(legacyjit)
+ if (NOT CLR_BUILD_JIT32)
+ add_subdirectory(compatjit)
+ endif ()
+endif (CLR_CMAKE_PLATFORM_ARCH_I386)
diff --git a/src/jit/ICorJitInfo_API_names.h b/src/jit/ICorJitInfo_API_names.h
new file mode 100644
index 0000000000..601afbdfe1
--- /dev/null
+++ b/src/jit/ICorJitInfo_API_names.h
@@ -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.
+
+DEF_CLR_API(getMethodAttribs)
+DEF_CLR_API(setMethodAttribs)
+DEF_CLR_API(getMethodSig)
+DEF_CLR_API(getMethodInfo)
+DEF_CLR_API(canInline)
+DEF_CLR_API(reportInliningDecision)
+DEF_CLR_API(canTailCall)
+DEF_CLR_API(reportTailCallDecision)
+DEF_CLR_API(getEHinfo)
+DEF_CLR_API(getMethodClass)
+DEF_CLR_API(getMethodModule)
+DEF_CLR_API(getMethodVTableOffset)
+DEF_CLR_API(getIntrinsicID)
+DEF_CLR_API(isInSIMDModule)
+DEF_CLR_API(getUnmanagedCallConv)
+DEF_CLR_API(pInvokeMarshalingRequired)
+DEF_CLR_API(satisfiesMethodConstraints)
+DEF_CLR_API(isCompatibleDelegate)
+DEF_CLR_API(isDelegateCreationAllowed)
+DEF_CLR_API(isInstantiationOfVerifiedGeneric)
+DEF_CLR_API(initConstraintsForVerification)
+DEF_CLR_API(canSkipMethodVerification)
+DEF_CLR_API(methodMustBeLoadedBeforeCodeIsRun)
+DEF_CLR_API(mapMethodDeclToMethodImpl)
+DEF_CLR_API(getGSCookie)
+DEF_CLR_API(resolveToken)
+DEF_CLR_API(tryResolveToken)
+DEF_CLR_API(findSig)
+DEF_CLR_API(findCallSiteSig)
+DEF_CLR_API(getTokenTypeAsHandle)
+DEF_CLR_API(canSkipVerification)
+DEF_CLR_API(isValidToken)
+DEF_CLR_API(isValidStringRef)
+DEF_CLR_API(shouldEnforceCallvirtRestriction)
+DEF_CLR_API(asCorInfoType)
+DEF_CLR_API(getClassName)
+DEF_CLR_API(appendClassName)
+DEF_CLR_API(isValueClass)
+DEF_CLR_API(canInlineTypeCheckWithObjectVTable)
+DEF_CLR_API(getClassAttribs)
+DEF_CLR_API(isStructRequiringStackAllocRetBuf)
+DEF_CLR_API(getClassModule)
+DEF_CLR_API(getModuleAssembly)
+DEF_CLR_API(getAssemblyName)
+DEF_CLR_API(LongLifetimeMalloc)
+DEF_CLR_API(LongLifetimeFree)
+DEF_CLR_API(getClassModuleIdForStatics)
+DEF_CLR_API(getClassSize)
+DEF_CLR_API(getClassAlignmentRequirement)
+DEF_CLR_API(getClassGClayout)
+DEF_CLR_API(getClassNumInstanceFields)
+DEF_CLR_API(getFieldInClass)
+DEF_CLR_API(checkMethodModifier)
+DEF_CLR_API(getNewHelper)
+DEF_CLR_API(getNewArrHelper)
+DEF_CLR_API(getCastingHelper)
+DEF_CLR_API(getSharedCCtorHelper)
+DEF_CLR_API(getSecurityPrologHelper)
+DEF_CLR_API(getTypeForBox)
+DEF_CLR_API(getBoxHelper)
+DEF_CLR_API(getUnBoxHelper)
+DEF_CLR_API(getReadyToRunHelper)
+DEF_CLR_API(getReadyToRunDelegateCtorHelper)
+DEF_CLR_API(getHelperName)
+DEF_CLR_API(initClass)
+DEF_CLR_API(classMustBeLoadedBeforeCodeIsRun)
+DEF_CLR_API(getBuiltinClass)
+DEF_CLR_API(getTypeForPrimitiveValueClass)
+DEF_CLR_API(canCast)
+DEF_CLR_API(areTypesEquivalent)
+DEF_CLR_API(mergeClasses)
+DEF_CLR_API(getParentType)
+DEF_CLR_API(getChildType)
+DEF_CLR_API(satisfiesClassConstraints)
+DEF_CLR_API(isSDArray)
+DEF_CLR_API(getArrayRank)
+DEF_CLR_API(getArrayInitializationData)
+DEF_CLR_API(canAccessClass)
+DEF_CLR_API(getFieldName)
+DEF_CLR_API(getFieldClass)
+DEF_CLR_API(getFieldType)
+DEF_CLR_API(getFieldOffset)
+DEF_CLR_API(isWriteBarrierHelperRequired)
+DEF_CLR_API(getFieldInfo)
+DEF_CLR_API(isFieldStatic)
+DEF_CLR_API(getBoundaries)
+DEF_CLR_API(setBoundaries)
+DEF_CLR_API(getVars)
+DEF_CLR_API(setVars)
+DEF_CLR_API(allocateArray)
+DEF_CLR_API(freeArray)
+DEF_CLR_API(getArgNext)
+DEF_CLR_API(getArgType)
+DEF_CLR_API(getArgClass)
+DEF_CLR_API(getHFAType)
+DEF_CLR_API(GetErrorHRESULT)
+DEF_CLR_API(GetErrorMessage)
+DEF_CLR_API(FilterException)
+DEF_CLR_API(HandleException)
+DEF_CLR_API(ThrowExceptionForJitResult)
+DEF_CLR_API(ThrowExceptionForHelper)
+DEF_CLR_API(getEEInfo)
+DEF_CLR_API(getJitTimeLogFilename)
+DEF_CLR_API(getMethodDefFromMethod)
+DEF_CLR_API(getMethodName)
+DEF_CLR_API(getMethodHash)
+DEF_CLR_API(findNameOfToken)
+DEF_CLR_API(getSystemVAmd64PassStructInRegisterDescriptor)
+DEF_CLR_API(getThreadTLSIndex)
+DEF_CLR_API(getInlinedCallFrameVptr)
+DEF_CLR_API(getAddrOfCaptureThreadGlobal)
+DEF_CLR_API(getAddrModuleDomainID)
+DEF_CLR_API(getHelperFtn)
+DEF_CLR_API(getFunctionEntryPoint)
+DEF_CLR_API(getFunctionFixedEntryPoint)
+DEF_CLR_API(getMethodSync)
+DEF_CLR_API(getLazyStringLiteralHelper)
+DEF_CLR_API(embedModuleHandle)
+DEF_CLR_API(embedClassHandle)
+DEF_CLR_API(embedMethodHandle)
+DEF_CLR_API(embedFieldHandle)
+DEF_CLR_API(embedGenericHandle)
+DEF_CLR_API(getLocationOfThisType)
+DEF_CLR_API(getPInvokeUnmanagedTarget)
+DEF_CLR_API(getAddressOfPInvokeFixup)
+DEF_CLR_API(getAddressOfPInvokeTarget)
+DEF_CLR_API(GetCookieForPInvokeCalliSig)
+DEF_CLR_API(canGetCookieForPInvokeCalliSig)
+DEF_CLR_API(getJustMyCodeHandle)
+DEF_CLR_API(GetProfilingHandle)
+DEF_CLR_API(getCallInfo)
+DEF_CLR_API(canAccessFamily)
+DEF_CLR_API(isRIDClassDomainID)
+DEF_CLR_API(getClassDomainID)
+DEF_CLR_API(getFieldAddress)
+DEF_CLR_API(getVarArgsHandle)
+DEF_CLR_API(canGetVarArgsHandle)
+DEF_CLR_API(constructStringLiteral)
+DEF_CLR_API(emptyStringLiteral)
+DEF_CLR_API(getFieldThreadLocalStoreID)
+DEF_CLR_API(setOverride)
+DEF_CLR_API(addActiveDependency)
+DEF_CLR_API(GetDelegateCtor)
+DEF_CLR_API(MethodCompileComplete)
+DEF_CLR_API(getTailCallCopyArgsThunk)
+DEF_CLR_API(getJitFlags)
+DEF_CLR_API(runWithErrorTrap)
+DEF_CLR_API(getMemoryManager)
+DEF_CLR_API(allocMem)
+DEF_CLR_API(reserveUnwindInfo)
+DEF_CLR_API(allocUnwindInfo)
+DEF_CLR_API(allocGCInfo)
+DEF_CLR_API(yieldExecution)
+DEF_CLR_API(setEHcount)
+DEF_CLR_API(setEHinfo)
+DEF_CLR_API(logMsg)
+DEF_CLR_API(doAssert)
+DEF_CLR_API(reportFatalError)
+DEF_CLR_API(allocBBProfileBuffer)
+DEF_CLR_API(getBBProfileData)
+DEF_CLR_API(recordCallSite)
+DEF_CLR_API(recordRelocation)
+DEF_CLR_API(getRelocTypeHint)
+DEF_CLR_API(getModuleNativeEntryPointRange)
+DEF_CLR_API(getExpectedTargetArchitecture)
+
+#undef DEF_CLR_API
diff --git a/src/jit/ICorJitInfo_API_wrapper.hpp b/src/jit/ICorJitInfo_API_wrapper.hpp
new file mode 100644
index 0000000000..4272b2755c
--- /dev/null
+++ b/src/jit/ICorJitInfo_API_wrapper.hpp
@@ -0,0 +1,1666 @@
+// Licensed to the .NET Foundation under one or more 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 API_ENTER(name) wrapComp->CLR_API_Enter(API_##name);
+#define API_LEAVE(name) wrapComp->CLR_API_Leave(API_##name);
+
+/**********************************************************************************/
+// clang-format off
+/**********************************************************************************/
+//
+// ICorMethodInfo
+//
+
+DWORD WrapICorJitInfo::getMethodAttribs(CORINFO_METHOD_HANDLE ftn /* IN */)
+{
+ API_ENTER(getMethodAttribs)
+ DWORD temp = wrapHnd->getMethodAttribs(ftn);
+ API_LEAVE(getMethodAttribs)
+ return temp;
+}
+
+void WrapICorJitInfo::setMethodAttribs(CORINFO_METHOD_HANDLE ftn,/* IN */
+ CorInfoMethodRuntimeFlags attribs/* IN */)
+{
+ API_ENTER(setMethodAttribs);
+ wrapHnd->setMethodAttribs(ftn, attribs);
+ API_LEAVE(setMethodAttribs);
+}
+
+void WrapICorJitInfo::getMethodSig(CORINFO_METHOD_HANDLE ftn, /* IN */
+ CORINFO_SIG_INFO *sig, /* OUT */
+ CORINFO_CLASS_HANDLE memberParent/* IN */)
+{
+ API_ENTER(getMethodSig);
+ wrapHnd->getMethodSig(ftn, sig, memberParent);
+ API_LEAVE(getMethodSig);
+}
+
+bool WrapICorJitInfo::getMethodInfo(
+ CORINFO_METHOD_HANDLE ftn, /* IN */
+ CORINFO_METHOD_INFO* info /* OUT */)
+{
+ API_ENTER(getMethodInfo);
+ bool temp = wrapHnd->getMethodInfo(ftn, info);
+ API_LEAVE(getMethodInfo);
+ return temp;
+}
+
+CorInfoInline WrapICorJitInfo::canInline(
+ CORINFO_METHOD_HANDLE callerHnd, /* IN */
+ CORINFO_METHOD_HANDLE calleeHnd, /* IN */
+ DWORD* pRestrictions /* OUT */)
+{
+ API_ENTER(canInline);
+ CorInfoInline temp = wrapHnd->canInline(callerHnd, calleeHnd, pRestrictions);
+ API_LEAVE(canInline);
+ return temp;
+}
+
+void WrapICorJitInfo::reportInliningDecision(CORINFO_METHOD_HANDLE inlinerHnd,
+ CORINFO_METHOD_HANDLE inlineeHnd,
+ CorInfoInline inlineResult,
+ const char * reason)
+{
+ API_ENTER(reportInliningDecision);
+ wrapHnd->reportInliningDecision(inlinerHnd, inlineeHnd, inlineResult, reason);
+ API_LEAVE(reportInliningDecision);
+}
+
+bool WrapICorJitInfo::canTailCall(
+ CORINFO_METHOD_HANDLE callerHnd, /* IN */
+ CORINFO_METHOD_HANDLE declaredCalleeHnd, /* IN */
+ CORINFO_METHOD_HANDLE exactCalleeHnd, /* IN */
+ bool fIsTailPrefix /* IN */)
+{
+ API_ENTER(canTailCall);
+ bool temp = wrapHnd->canTailCall(callerHnd, declaredCalleeHnd, exactCalleeHnd, fIsTailPrefix);
+ API_LEAVE(canTailCall);
+ return temp;
+}
+
+void WrapICorJitInfo::reportTailCallDecision(CORINFO_METHOD_HANDLE callerHnd,
+ CORINFO_METHOD_HANDLE calleeHnd,
+ bool fIsTailPrefix,
+ CorInfoTailCall tailCallResult,
+ const char * reason)
+{
+ API_ENTER(reportTailCallDecision);
+ wrapHnd->reportTailCallDecision(callerHnd, calleeHnd, fIsTailPrefix, tailCallResult, reason);
+ API_LEAVE(reportTailCallDecision);
+}
+
+void WrapICorJitInfo::getEHinfo(
+ CORINFO_METHOD_HANDLE ftn, /* IN */
+ unsigned EHnumber, /* IN */
+ CORINFO_EH_CLAUSE* clause /* OUT */)
+{
+ API_ENTER(getEHinfo);
+ wrapHnd->getEHinfo(ftn, EHnumber, clause);
+ API_LEAVE(getEHinfo);
+}
+
+CORINFO_CLASS_HANDLE WrapICorJitInfo::getMethodClass(
+ CORINFO_METHOD_HANDLE method)
+{
+ API_ENTER(getMethodClass);
+ CORINFO_CLASS_HANDLE temp = wrapHnd->getMethodClass(method);
+ API_LEAVE(getMethodClass);
+ return temp;
+}
+
+CORINFO_MODULE_HANDLE WrapICorJitInfo::getMethodModule(
+ CORINFO_METHOD_HANDLE method)
+{
+ API_ENTER(getMethodModule);
+ CORINFO_MODULE_HANDLE temp = wrapHnd->getMethodModule(method);
+ API_LEAVE(getMethodModule);
+ return temp;
+}
+
+void WrapICorJitInfo::getMethodVTableOffset(
+ CORINFO_METHOD_HANDLE method, /* IN */
+ unsigned* offsetOfIndirection, /* OUT */
+ unsigned* offsetAfterIndirection /* OUT */)
+{
+ API_ENTER(getMethodVTableOffset);
+ wrapHnd->getMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection);
+ API_LEAVE(getMethodVTableOffset);
+}
+
+#if COR_JIT_EE_VERSION > 460
+
+CorInfoIntrinsics WrapICorJitInfo::getIntrinsicID(
+ CORINFO_METHOD_HANDLE method,
+ bool* pMustExpand /* OUT */)
+{
+ API_ENTER(getIntrinsicID);
+ CorInfoIntrinsics temp = wrapHnd->getIntrinsicID(method, pMustExpand);
+ API_LEAVE(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);
+ bool temp = wrapHnd->isInSIMDModule(classHnd);
+ API_LEAVE(isInSIMDModule);
+ return temp;
+}
+
+CorInfoUnmanagedCallConv WrapICorJitInfo::getUnmanagedCallConv(
+ CORINFO_METHOD_HANDLE method)
+{
+ API_ENTER(getUnmanagedCallConv);
+ CorInfoUnmanagedCallConv temp = wrapHnd->getUnmanagedCallConv(method);
+ API_LEAVE(getUnmanagedCallConv);
+ return temp;
+}
+
+BOOL WrapICorJitInfo::pInvokeMarshalingRequired(
+ CORINFO_METHOD_HANDLE method,
+ CORINFO_SIG_INFO* callSiteSig)
+{
+ API_ENTER(pInvokeMarshalingRequired);
+ BOOL temp = wrapHnd->pInvokeMarshalingRequired(method, callSiteSig);
+ API_LEAVE(pInvokeMarshalingRequired);
+ return temp;
+}
+
+BOOL WrapICorJitInfo::satisfiesMethodConstraints(
+ CORINFO_CLASS_HANDLE parent, // the exact parent of the method
+ CORINFO_METHOD_HANDLE method)
+{
+ API_ENTER(satisfiesMethodConstraints);
+ BOOL temp = wrapHnd->satisfiesMethodConstraints(parent, method);
+ API_LEAVE(satisfiesMethodConstraints);
+ return temp;
+}
+
+BOOL WrapICorJitInfo::isCompatibleDelegate(
+ CORINFO_CLASS_HANDLE objCls,
+ CORINFO_CLASS_HANDLE methodParentCls,
+ CORINFO_METHOD_HANDLE method,
+ CORINFO_CLASS_HANDLE delegateCls,
+ BOOL *pfIsOpenDelegate)
+{
+ API_ENTER(isCompatibleDelegate);
+ BOOL temp = wrapHnd->isCompatibleDelegate(objCls, methodParentCls, method, delegateCls, pfIsOpenDelegate);
+ API_LEAVE(isCompatibleDelegate);
+ return temp;
+}
+
+BOOL WrapICorJitInfo::isDelegateCreationAllowed(
+ CORINFO_CLASS_HANDLE delegateHnd,
+ CORINFO_METHOD_HANDLE calleeHnd)
+{
+ API_ENTER(isDelegateCreationAllowed);
+ BOOL temp = wrapHnd->isDelegateCreationAllowed(delegateHnd, calleeHnd);
+ API_LEAVE(isDelegateCreationAllowed);
+ return temp;
+}
+
+
+CorInfoInstantiationVerification WrapICorJitInfo::isInstantiationOfVerifiedGeneric(
+ CORINFO_METHOD_HANDLE method /* IN */)
+{
+ API_ENTER(isInstantiationOfVerifiedGeneric);
+ CorInfoInstantiationVerification temp = wrapHnd->isInstantiationOfVerifiedGeneric(method);
+ API_LEAVE(isInstantiationOfVerifiedGeneric);
+ return temp;
+}
+
+void WrapICorJitInfo::initConstraintsForVerification(
+ CORINFO_METHOD_HANDLE method, /* IN */
+ BOOL *pfHasCircularClassConstraints, /* OUT */
+ BOOL *pfHasCircularMethodConstraint /* OUT */)
+{
+ API_ENTER(initConstraintsForVerification);
+ wrapHnd->initConstraintsForVerification(method, pfHasCircularClassConstraints, pfHasCircularMethodConstraint);
+ API_LEAVE(initConstraintsForVerification);
+}
+
+CorInfoCanSkipVerificationResult WrapICorJitInfo::canSkipMethodVerification(
+ CORINFO_METHOD_HANDLE ftnHandle)
+{
+ API_ENTER(canSkipMethodVerification);
+ CorInfoCanSkipVerificationResult temp = wrapHnd->canSkipMethodVerification(ftnHandle);
+ API_LEAVE(canSkipMethodVerification);
+ return temp;
+}
+
+void WrapICorJitInfo::methodMustBeLoadedBeforeCodeIsRun(
+ CORINFO_METHOD_HANDLE method)
+{
+ API_ENTER(methodMustBeLoadedBeforeCodeIsRun);
+ wrapHnd->methodMustBeLoadedBeforeCodeIsRun(method);
+ API_LEAVE(methodMustBeLoadedBeforeCodeIsRun);
+}
+
+CORINFO_METHOD_HANDLE WrapICorJitInfo::mapMethodDeclToMethodImpl(
+ CORINFO_METHOD_HANDLE method)
+{
+ API_ENTER(mapMethodDeclToMethodImpl);
+ CORINFO_METHOD_HANDLE temp = wrapHnd->mapMethodDeclToMethodImpl(method);
+ API_LEAVE(mapMethodDeclToMethodImpl);
+ return temp;
+}
+
+void WrapICorJitInfo::getGSCookie(
+ GSCookie * pCookieVal,
+ GSCookie ** ppCookieVal )
+{
+ API_ENTER(getGSCookie);
+ wrapHnd->getGSCookie(pCookieVal, ppCookieVal);
+ API_LEAVE(getGSCookie);
+}
+
+/**********************************************************************************/
+//
+// ICorModuleInfo
+//
+/**********************************************************************************/
+
+void WrapICorJitInfo::resolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken)
+{
+ API_ENTER(resolveToken);
+ wrapHnd->resolveToken(pResolvedToken);
+ API_LEAVE(resolveToken);
+}
+
+#if COR_JIT_EE_VERSION > 460
+
+bool WrapICorJitInfo::tryResolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken)
+{
+ API_ENTER(tryResolveToken);
+ bool success = wrapHnd->tryResolveToken(pResolvedToken);
+ API_LEAVE(tryResolveToken);
+ return success;
+}
+
+#endif
+
+void WrapICorJitInfo::findSig(
+ CORINFO_MODULE_HANDLE module,
+ unsigned sigTOK,
+ CORINFO_CONTEXT_HANDLE context,
+ CORINFO_SIG_INFO *sig )
+{
+ API_ENTER(findSig);
+ wrapHnd->findSig(module, sigTOK, context, sig);
+ API_LEAVE(findSig);
+}
+
+void WrapICorJitInfo::findCallSiteSig(
+ CORINFO_MODULE_HANDLE module, /* IN */
+ unsigned methTOK, /* IN */
+ CORINFO_CONTEXT_HANDLE context, /* IN */
+ CORINFO_SIG_INFO *sig /* OUT */)
+{
+ API_ENTER(findCallSiteSig);
+ wrapHnd->findCallSiteSig(module, methTOK, context, sig);
+ API_LEAVE(findCallSiteSig);
+}
+
+CORINFO_CLASS_HANDLE WrapICorJitInfo::getTokenTypeAsHandle(
+ CORINFO_RESOLVED_TOKEN * pResolvedToken /* IN */)
+{
+ API_ENTER(getTokenTypeAsHandle);
+ CORINFO_CLASS_HANDLE temp = wrapHnd->getTokenTypeAsHandle(pResolvedToken);
+ API_LEAVE(getTokenTypeAsHandle);
+ return temp;
+}
+
+CorInfoCanSkipVerificationResult WrapICorJitInfo::canSkipVerification(
+ CORINFO_MODULE_HANDLE module /* IN */)
+{
+ API_ENTER(canSkipVerification);
+ CorInfoCanSkipVerificationResult temp = wrapHnd->canSkipVerification(module);
+ API_LEAVE(canSkipVerification);
+ return temp;
+}
+
+BOOL WrapICorJitInfo::isValidToken(
+ CORINFO_MODULE_HANDLE module, /* IN */
+ unsigned metaTOK /* IN */)
+{
+ API_ENTER(isValidToken);
+ BOOL result = wrapHnd->isValidToken(module, metaTOK);
+ API_LEAVE(isValidToken);
+ return result;
+}
+
+BOOL WrapICorJitInfo::isValidStringRef(
+ CORINFO_MODULE_HANDLE module, /* IN */
+ unsigned metaTOK /* IN */)
+{
+ API_ENTER(isValidStringRef);
+ BOOL temp = wrapHnd->isValidStringRef(module, metaTOK);
+ API_LEAVE(isValidStringRef);
+ return temp;
+}
+
+BOOL WrapICorJitInfo::shouldEnforceCallvirtRestriction(
+ CORINFO_MODULE_HANDLE scope)
+{
+ API_ENTER(shouldEnforceCallvirtRestriction);
+ BOOL temp = wrapHnd->shouldEnforceCallvirtRestriction(scope);
+ API_LEAVE(shouldEnforceCallvirtRestriction);
+ return temp;
+}
+
+/**********************************************************************************/
+//
+// ICorClassInfo
+//
+/**********************************************************************************/
+
+CorInfoType WrapICorJitInfo::asCorInfoType(CORINFO_CLASS_HANDLE cls)
+{
+ API_ENTER(asCorInfoType);
+ CorInfoType temp = wrapHnd->asCorInfoType(cls);
+ API_LEAVE(asCorInfoType);
+ return temp;
+}
+
+const char* WrapICorJitInfo::getClassName(CORINFO_CLASS_HANDLE cls)
+{
+ API_ENTER(getClassName);
+ const char* result = wrapHnd->getClassName(cls);
+ API_LEAVE(getClassName);
+ return result;
+}
+
+int WrapICorJitInfo::appendClassName(
+ __deref_inout_ecount(*pnBufLen) WCHAR** ppBuf,
+ int* pnBufLen,
+ CORINFO_CLASS_HANDLE cls,
+ BOOL fNamespace,
+ BOOL fFullInst,
+ BOOL fAssembly)
+{
+ API_ENTER(appendClassName);
+ WCHAR* pBuf = *ppBuf;
+ int nLen = wrapHnd->appendClassName(ppBuf, pnBufLen, cls, fNamespace, fFullInst, fAssembly);
+ API_LEAVE(appendClassName);
+ return nLen;
+}
+
+BOOL WrapICorJitInfo::isValueClass(CORINFO_CLASS_HANDLE cls)
+{
+ API_ENTER(isValueClass);
+ BOOL temp = wrapHnd->isValueClass(cls);
+ API_LEAVE(isValueClass);
+ return temp;
+}
+
+BOOL WrapICorJitInfo::canInlineTypeCheckWithObjectVTable(CORINFO_CLASS_HANDLE cls)
+{
+ API_ENTER(canInlineTypeCheckWithObjectVTable);
+ BOOL temp = wrapHnd->canInlineTypeCheckWithObjectVTable(cls);
+ API_LEAVE(canInlineTypeCheckWithObjectVTable);
+ return temp;
+}
+
+DWORD WrapICorJitInfo::getClassAttribs(
+ CORINFO_CLASS_HANDLE cls)
+{
+ API_ENTER(getClassAttribs);
+ DWORD temp = wrapHnd->getClassAttribs(cls);
+ API_LEAVE(getClassAttribs);
+ return temp;
+}
+
+BOOL WrapICorJitInfo::isStructRequiringStackAllocRetBuf(CORINFO_CLASS_HANDLE cls)
+{
+ API_ENTER(isStructRequiringStackAllocRetBuf);
+ BOOL temp = wrapHnd->isStructRequiringStackAllocRetBuf(cls);
+ API_LEAVE(isStructRequiringStackAllocRetBuf);
+ return temp;
+}
+
+CORINFO_MODULE_HANDLE WrapICorJitInfo::getClassModule(
+ CORINFO_CLASS_HANDLE cls)
+{
+ API_ENTER(getClassModule);
+ CORINFO_MODULE_HANDLE result = wrapHnd->getClassModule(cls);
+ API_LEAVE(getClassModule);
+ return result;
+}
+
+CORINFO_ASSEMBLY_HANDLE WrapICorJitInfo::getModuleAssembly(
+ CORINFO_MODULE_HANDLE mod)
+{
+ API_ENTER(getModuleAssembly);
+ CORINFO_ASSEMBLY_HANDLE result = wrapHnd->getModuleAssembly(mod);
+ API_LEAVE(getModuleAssembly);
+ return result;
+}
+
+const char* WrapICorJitInfo::getAssemblyName(
+ CORINFO_ASSEMBLY_HANDLE assem)
+{
+ API_ENTER(getAssemblyName);
+ const char* result = wrapHnd->getAssemblyName(assem);
+ API_LEAVE(getAssemblyName);
+ return result;
+}
+
+void* WrapICorJitInfo::LongLifetimeMalloc(size_t sz)
+{
+ API_ENTER(LongLifetimeMalloc);
+ void* result = wrapHnd->LongLifetimeMalloc(sz);
+ API_LEAVE(LongLifetimeMalloc);
+ return result;
+}
+
+void WrapICorJitInfo::LongLifetimeFree(void* obj)
+{
+ API_ENTER(LongLifetimeFree);
+ wrapHnd->LongLifetimeFree(obj);
+ API_LEAVE(LongLifetimeFree);
+}
+
+size_t WrapICorJitInfo::getClassModuleIdForStatics(
+ CORINFO_CLASS_HANDLE cls,
+ CORINFO_MODULE_HANDLE *pModule,
+ void **ppIndirection)
+{
+ API_ENTER(getClassModuleIdForStatics);
+ size_t temp = wrapHnd->getClassModuleIdForStatics(cls, pModule, ppIndirection);
+ API_LEAVE(getClassModuleIdForStatics);
+ return temp;
+}
+
+unsigned WrapICorJitInfo::getClassSize(CORINFO_CLASS_HANDLE cls)
+{
+ API_ENTER(getClassSize);
+ unsigned temp = wrapHnd->getClassSize(cls);
+ API_LEAVE(getClassSize);
+ return temp;
+}
+
+unsigned WrapICorJitInfo::getClassAlignmentRequirement(
+ CORINFO_CLASS_HANDLE cls,
+ BOOL fDoubleAlignHint)
+{
+ API_ENTER(getClassAlignmentRequirement);
+ unsigned temp = wrapHnd->getClassAlignmentRequirement(cls, fDoubleAlignHint);
+ API_LEAVE(getClassAlignmentRequirement);
+ return temp;
+}
+
+unsigned WrapICorJitInfo::getClassGClayout(
+ CORINFO_CLASS_HANDLE cls, /* IN */
+ BYTE *gcPtrs /* OUT */)
+{
+ API_ENTER(getClassGClayout);
+ unsigned temp = wrapHnd->getClassGClayout(cls, gcPtrs);
+ API_LEAVE(getClassGClayout);
+ return temp;
+}
+
+unsigned WrapICorJitInfo::getClassNumInstanceFields(
+ CORINFO_CLASS_HANDLE cls /* IN */)
+{
+ API_ENTER(getClassNumInstanceFields);
+ unsigned temp = wrapHnd->getClassNumInstanceFields(cls);
+ API_LEAVE(getClassNumInstanceFields);
+ return temp;
+}
+
+CORINFO_FIELD_HANDLE WrapICorJitInfo::getFieldInClass(
+ CORINFO_CLASS_HANDLE clsHnd,
+ INT num)
+{
+ API_ENTER(getFieldInClass);
+ CORINFO_FIELD_HANDLE temp = wrapHnd->getFieldInClass(clsHnd, num);
+ API_LEAVE(getFieldInClass);
+ return temp;
+}
+
+BOOL WrapICorJitInfo::checkMethodModifier(
+ CORINFO_METHOD_HANDLE hMethod,
+ LPCSTR modifier,
+ BOOL fOptional)
+{
+ API_ENTER(checkMethodModifier);
+ BOOL result = wrapHnd->checkMethodModifier(hMethod, modifier, fOptional);
+ API_LEAVE(checkMethodModifier);
+ return result;
+}
+
+CorInfoHelpFunc WrapICorJitInfo::getNewHelper(
+ CORINFO_RESOLVED_TOKEN * pResolvedToken,
+ CORINFO_METHOD_HANDLE callerHandle)
+{
+ API_ENTER(getNewHelper);
+ CorInfoHelpFunc temp = wrapHnd->getNewHelper(pResolvedToken, callerHandle);
+ API_LEAVE(getNewHelper);
+ return temp;
+}
+
+CorInfoHelpFunc WrapICorJitInfo::getNewArrHelper(
+ CORINFO_CLASS_HANDLE arrayCls)
+{
+ API_ENTER(getNewArrHelper);
+ CorInfoHelpFunc temp = wrapHnd->getNewArrHelper(arrayCls);
+ API_LEAVE(getNewArrHelper);
+ return temp;
+}
+
+CorInfoHelpFunc WrapICorJitInfo::getCastingHelper(
+ CORINFO_RESOLVED_TOKEN * pResolvedToken,
+ bool fThrowing)
+{
+ API_ENTER(getCastingHelper);
+ CorInfoHelpFunc temp = wrapHnd->getCastingHelper(pResolvedToken, fThrowing);
+ API_LEAVE(getCastingHelper);
+ return temp;
+}
+
+CorInfoHelpFunc WrapICorJitInfo::getSharedCCtorHelper(
+ CORINFO_CLASS_HANDLE clsHnd)
+{
+ API_ENTER(getSharedCCtorHelper);
+ CorInfoHelpFunc temp = wrapHnd->getSharedCCtorHelper(clsHnd);
+ API_LEAVE(getSharedCCtorHelper);
+ return temp;
+}
+
+CorInfoHelpFunc WrapICorJitInfo::getSecurityPrologHelper(
+ CORINFO_METHOD_HANDLE ftn)
+{
+ API_ENTER(getSecurityPrologHelper);
+ CorInfoHelpFunc temp = wrapHnd->getSecurityPrologHelper(ftn);
+ API_LEAVE(getSecurityPrologHelper);
+ return temp;
+}
+
+CORINFO_CLASS_HANDLE WrapICorJitInfo::getTypeForBox(
+ CORINFO_CLASS_HANDLE cls)
+{
+ API_ENTER(getTypeForBox);
+ CORINFO_CLASS_HANDLE temp = wrapHnd->getTypeForBox(cls);
+ API_LEAVE(getTypeForBox);
+ return temp;
+}
+
+CorInfoHelpFunc WrapICorJitInfo::getBoxHelper(
+ CORINFO_CLASS_HANDLE cls)
+{
+ API_ENTER(getBoxHelper);
+ CorInfoHelpFunc temp = wrapHnd->getBoxHelper(cls);
+ API_LEAVE(getBoxHelper);
+ return temp;
+}
+
+CorInfoHelpFunc WrapICorJitInfo::getUnBoxHelper(
+ CORINFO_CLASS_HANDLE cls)
+{
+ API_ENTER(getUnBoxHelper);
+ CorInfoHelpFunc temp = wrapHnd->getUnBoxHelper(cls);
+ API_LEAVE(getUnBoxHelper);
+ return temp;
+}
+
+#if COR_JIT_EE_VERSION > 460
+
+bool WrapICorJitInfo::getReadyToRunHelper(
+ CORINFO_RESOLVED_TOKEN * pResolvedToken,
+ CORINFO_LOOKUP_KIND * pGenericLookupKind,
+ CorInfoHelpFunc id,
+ CORINFO_CONST_LOOKUP * pLookup)
+{
+ API_ENTER(getReadyToRunHelper);
+ bool result = wrapHnd->getReadyToRunHelper(pResolvedToken, pGenericLookupKind, id, pLookup);
+ API_LEAVE(getReadyToRunHelper);
+ return result;
+}
+
+void WrapICorJitInfo::getReadyToRunDelegateCtorHelper(
+ CORINFO_RESOLVED_TOKEN * pTargetMethod,
+ CORINFO_CLASS_HANDLE delegateType,
+ CORINFO_CONST_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)
+{
+ API_ENTER(getHelperName);
+ const char* temp = wrapHnd->getHelperName(funcNum);
+ API_LEAVE(getHelperName);
+ return temp;
+}
+
+CorInfoInitClassResult WrapICorJitInfo::initClass(
+ CORINFO_FIELD_HANDLE field,
+
+ CORINFO_METHOD_HANDLE method,
+ CORINFO_CONTEXT_HANDLE context,
+ BOOL speculative)
+{
+ API_ENTER(initClass);
+ CorInfoInitClassResult temp = wrapHnd->initClass(field, method, context, speculative);
+ API_LEAVE(initClass);
+ return temp;
+}
+
+void WrapICorJitInfo::classMustBeLoadedBeforeCodeIsRun(
+ CORINFO_CLASS_HANDLE cls)
+{
+ API_ENTER(classMustBeLoadedBeforeCodeIsRun);
+ wrapHnd->classMustBeLoadedBeforeCodeIsRun(cls);
+ API_LEAVE(classMustBeLoadedBeforeCodeIsRun);
+}
+
+CORINFO_CLASS_HANDLE WrapICorJitInfo::getBuiltinClass(
+ CorInfoClassId classId)
+{
+ API_ENTER(getBuiltinClass);
+ CORINFO_CLASS_HANDLE temp = wrapHnd->getBuiltinClass(classId);
+ API_LEAVE(getBuiltinClass);
+ return temp;
+}
+
+CorInfoType WrapICorJitInfo::getTypeForPrimitiveValueClass(
+ CORINFO_CLASS_HANDLE cls)
+{
+ API_ENTER(getTypeForPrimitiveValueClass);
+ CorInfoType temp = wrapHnd->getTypeForPrimitiveValueClass(cls);
+ API_LEAVE(getTypeForPrimitiveValueClass);
+ return temp;
+}
+
+BOOL WrapICorJitInfo::canCast(
+ CORINFO_CLASS_HANDLE child,
+ CORINFO_CLASS_HANDLE parent )
+{
+ API_ENTER(canCast);
+ BOOL temp = wrapHnd->canCast(child, parent);
+ API_LEAVE(canCast);
+ return temp;
+}
+
+BOOL WrapICorJitInfo::areTypesEquivalent(
+ CORINFO_CLASS_HANDLE cls1,
+ CORINFO_CLASS_HANDLE cls2)
+{
+ API_ENTER(areTypesEquivalent);
+ BOOL temp = wrapHnd->areTypesEquivalent(cls1, cls2);
+ API_LEAVE(areTypesEquivalent);
+ return temp;
+}
+
+CORINFO_CLASS_HANDLE WrapICorJitInfo::mergeClasses(
+ CORINFO_CLASS_HANDLE cls1,
+ CORINFO_CLASS_HANDLE cls2)
+{
+ API_ENTER(mergeClasses);
+ CORINFO_CLASS_HANDLE temp = wrapHnd->mergeClasses(cls1, cls2);
+ API_LEAVE(mergeClasses);
+ return temp;
+}
+
+CORINFO_CLASS_HANDLE WrapICorJitInfo::getParentType(
+ CORINFO_CLASS_HANDLE cls)
+{
+ API_ENTER(getParentType);
+ CORINFO_CLASS_HANDLE temp = wrapHnd->getParentType(cls);
+ API_LEAVE(getParentType);
+ return temp;
+}
+
+CorInfoType WrapICorJitInfo::getChildType(
+ CORINFO_CLASS_HANDLE clsHnd,
+ CORINFO_CLASS_HANDLE *clsRet)
+{
+ API_ENTER(getChildType);
+ CorInfoType temp = wrapHnd->getChildType(clsHnd, clsRet);
+ API_LEAVE(getChildType);
+ return temp;
+}
+
+BOOL WrapICorJitInfo::satisfiesClassConstraints(
+ CORINFO_CLASS_HANDLE cls)
+{
+ API_ENTER(satisfiesClassConstraints);
+ BOOL temp = wrapHnd->satisfiesClassConstraints(cls);
+ API_LEAVE(satisfiesClassConstraints);
+ return temp;
+
+}
+
+BOOL WrapICorJitInfo::isSDArray(
+ CORINFO_CLASS_HANDLE cls)
+{
+ API_ENTER(isSDArray);
+ BOOL temp = wrapHnd->isSDArray(cls);
+ API_LEAVE(isSDArray);
+ return temp;
+}
+
+unsigned WrapICorJitInfo::getArrayRank(
+ CORINFO_CLASS_HANDLE cls)
+{
+ API_ENTER(getArrayRank);
+ unsigned result = wrapHnd->getArrayRank(cls);
+ API_LEAVE(getArrayRank);
+ return result;
+}
+
+void * WrapICorJitInfo::getArrayInitializationData(
+ CORINFO_FIELD_HANDLE field,
+ DWORD size)
+{
+ API_ENTER(getArrayInitializationData);
+ void *temp = wrapHnd->getArrayInitializationData(field, size);
+ API_LEAVE(getArrayInitializationData);
+ return temp;
+}
+
+CorInfoIsAccessAllowedResult WrapICorJitInfo::canAccessClass(
+ CORINFO_RESOLVED_TOKEN * pResolvedToken,
+ CORINFO_METHOD_HANDLE callerHandle,
+ CORINFO_HELPER_DESC *pAccessHelper)
+{
+ API_ENTER(canAccessClass);
+ CorInfoIsAccessAllowedResult temp = wrapHnd->canAccessClass(pResolvedToken, callerHandle, pAccessHelper);
+ API_LEAVE(canAccessClass);
+ return temp;
+}
+
+/**********************************************************************************/
+//
+// ICorFieldInfo
+//
+/**********************************************************************************/
+
+const char* WrapICorJitInfo::getFieldName(
+ CORINFO_FIELD_HANDLE ftn, /* IN */
+ const char **moduleName /* OUT */)
+{
+ API_ENTER(getFieldName);
+ const char* temp = wrapHnd->getFieldName(ftn, moduleName);
+ API_LEAVE(getFieldName);
+ return temp;
+}
+
+CORINFO_CLASS_HANDLE WrapICorJitInfo::getFieldClass(
+ CORINFO_FIELD_HANDLE field)
+{
+ API_ENTER(getFieldClass);
+ CORINFO_CLASS_HANDLE temp = wrapHnd->getFieldClass(field);
+ API_LEAVE(getFieldClass);
+ return temp;
+}
+
+CorInfoType WrapICorJitInfo::getFieldType(
+ CORINFO_FIELD_HANDLE field,
+ CORINFO_CLASS_HANDLE *structType,
+ CORINFO_CLASS_HANDLE memberParent/* IN */)
+{
+ API_ENTER(getFieldType);
+ CorInfoType temp = wrapHnd->getFieldType(field, structType, memberParent);
+ API_LEAVE(getFieldType);
+ return temp;
+}
+
+unsigned WrapICorJitInfo::getFieldOffset(
+ CORINFO_FIELD_HANDLE field)
+{
+ API_ENTER(getFieldOffset);
+ unsigned temp = wrapHnd->getFieldOffset(field);
+ API_LEAVE(getFieldOffset);
+ return temp;
+}
+
+bool WrapICorJitInfo::isWriteBarrierHelperRequired(
+ CORINFO_FIELD_HANDLE field)
+{
+ API_ENTER(isWriteBarrierHelperRequired);
+ bool result = wrapHnd->isWriteBarrierHelperRequired(field);
+ API_LEAVE(isWriteBarrierHelperRequired);
+ return result;
+}
+
+void WrapICorJitInfo::getFieldInfo(CORINFO_RESOLVED_TOKEN * pResolvedToken,
+ CORINFO_METHOD_HANDLE callerHandle,
+ CORINFO_ACCESS_FLAGS flags,
+ CORINFO_FIELD_INFO *pResult)
+{
+ API_ENTER(getFieldInfo);
+ wrapHnd->getFieldInfo(pResolvedToken, callerHandle, flags, pResult);
+ API_LEAVE(getFieldInfo);
+}
+
+bool WrapICorJitInfo::isFieldStatic(CORINFO_FIELD_HANDLE fldHnd)
+{
+ API_ENTER(isFieldStatic);
+ bool result = wrapHnd->isFieldStatic(fldHnd);
+ API_LEAVE(isFieldStatic);
+ return result;
+}
+
+/*********************************************************************************/
+//
+// ICorDebugInfo
+//
+/*********************************************************************************/
+
+void WrapICorJitInfo::getBoundaries(
+ CORINFO_METHOD_HANDLE ftn,
+ unsigned int *cILOffsets,
+ DWORD **pILOffsets,
+
+ ICorDebugInfo::BoundaryTypes *implictBoundaries)
+{
+ API_ENTER(getBoundaries);
+ wrapHnd->getBoundaries(ftn, cILOffsets, pILOffsets, implictBoundaries);
+ API_LEAVE(getBoundaries);
+}
+
+void WrapICorJitInfo::setBoundaries(
+ CORINFO_METHOD_HANDLE ftn,
+ ULONG32 cMap,
+ ICorDebugInfo::OffsetMapping *pMap)
+{
+ API_ENTER(setBoundaries);
+ wrapHnd->setBoundaries(ftn, cMap, pMap);
+ API_LEAVE(setBoundaries);
+}
+
+void WrapICorJitInfo::getVars(
+ CORINFO_METHOD_HANDLE ftn,
+ ULONG32 *cVars,
+ ICorDebugInfo::ILVarInfo **vars,
+ bool *extendOthers)
+
+{
+ API_ENTER(getVars);
+ wrapHnd->getVars(ftn, cVars, vars, extendOthers);
+ API_LEAVE(getVars);
+}
+
+void WrapICorJitInfo::setVars(
+ CORINFO_METHOD_HANDLE ftn,
+ ULONG32 cVars,
+ ICorDebugInfo::NativeVarInfo *vars)
+
+{
+ API_ENTER(setVars);
+ wrapHnd->setVars(ftn, cVars, vars);
+ API_LEAVE(setVars);
+}
+
+void * WrapICorJitInfo::allocateArray(
+ ULONG cBytes)
+{
+ API_ENTER(allocateArray);
+ void *temp = wrapHnd->allocateArray(cBytes);
+ API_LEAVE(allocateArray);
+ return temp;
+}
+
+void WrapICorJitInfo::freeArray(
+ void *array)
+{
+ API_ENTER(freeArray);
+ wrapHnd->freeArray(array);
+ API_LEAVE(freeArray);
+}
+
+/*********************************************************************************/
+//
+// ICorArgInfo
+//
+/*********************************************************************************/
+
+CORINFO_ARG_LIST_HANDLE WrapICorJitInfo::getArgNext(
+ CORINFO_ARG_LIST_HANDLE args /* IN */)
+{
+ API_ENTER(getArgNext);
+ CORINFO_ARG_LIST_HANDLE temp = wrapHnd->getArgNext(args);
+ API_LEAVE(getArgNext);
+ return temp;
+}
+
+CorInfoTypeWithMod WrapICorJitInfo::getArgType(
+ CORINFO_SIG_INFO* sig, /* IN */
+ CORINFO_ARG_LIST_HANDLE args, /* IN */
+ CORINFO_CLASS_HANDLE *vcTypeRet /* OUT */)
+{
+ API_ENTER(getArgType);
+ CorInfoTypeWithMod temp = wrapHnd->getArgType(sig, args, vcTypeRet);
+ API_LEAVE(getArgType);
+ return temp;
+}
+
+CORINFO_CLASS_HANDLE WrapICorJitInfo::getArgClass(
+ CORINFO_SIG_INFO* sig, /* IN */
+ CORINFO_ARG_LIST_HANDLE args /* IN */)
+{
+ API_ENTER(getArgClass);
+ CORINFO_CLASS_HANDLE temp = wrapHnd->getArgClass(sig, args);
+ API_LEAVE(getArgClass);
+ return temp;
+}
+
+CorInfoType WrapICorJitInfo::getHFAType(
+ CORINFO_CLASS_HANDLE hClass)
+{
+ API_ENTER(getHFAType);
+ CorInfoType temp = wrapHnd->getHFAType(hClass);
+ API_LEAVE(getHFAType);
+ return temp;
+}
+
+HRESULT WrapICorJitInfo::GetErrorHRESULT(
+ struct _EXCEPTION_POINTERS *pExceptionPointers)
+{
+ API_ENTER(GetErrorHRESULT);
+ HRESULT temp = wrapHnd->GetErrorHRESULT(pExceptionPointers);
+ API_LEAVE(GetErrorHRESULT);
+ return temp;
+}
+
+ULONG WrapICorJitInfo::GetErrorMessage(
+ __inout_ecount(bufferLength) LPWSTR buffer,
+ ULONG bufferLength)
+{
+ API_ENTER(GetErrorMessage);
+ ULONG temp = wrapHnd->GetErrorMessage(buffer, bufferLength);
+ API_LEAVE(GetErrorMessage);
+ return temp;
+}
+
+int WrapICorJitInfo::FilterException(
+ struct _EXCEPTION_POINTERS *pExceptionPointers)
+{
+ API_ENTER(FilterException);
+ int temp = wrapHnd->FilterException(pExceptionPointers);
+ API_LEAVE(FilterException);
+ return temp;
+}
+
+void WrapICorJitInfo::HandleException(
+ struct _EXCEPTION_POINTERS *pExceptionPointers)
+{
+ API_ENTER(HandleException);
+ wrapHnd->HandleException(pExceptionPointers);
+ API_LEAVE(HandleException);
+}
+
+void WrapICorJitInfo::ThrowExceptionForJitResult(
+ HRESULT result)
+{
+ API_ENTER(ThrowExceptionForJitResult);
+ wrapHnd->ThrowExceptionForJitResult(result);
+ API_LEAVE(ThrowExceptionForJitResult);
+}
+
+void WrapICorJitInfo::ThrowExceptionForHelper(
+ const CORINFO_HELPER_DESC * throwHelper)
+{
+ API_ENTER(ThrowExceptionForHelper);
+ wrapHnd->ThrowExceptionForHelper(throwHelper);
+ API_LEAVE(ThrowExceptionForHelper);
+}
+
+void WrapICorJitInfo::getEEInfo(
+ CORINFO_EE_INFO *pEEInfoOut)
+{
+ API_ENTER(getEEInfo);
+ wrapHnd->getEEInfo(pEEInfoOut);
+ API_LEAVE(getEEInfo);
+}
+
+LPCWSTR WrapICorJitInfo::getJitTimeLogFilename()
+{
+ API_ENTER(getJitTimeLogFilename);
+ LPCWSTR temp = wrapHnd->getJitTimeLogFilename();
+ API_LEAVE(getJitTimeLogFilename);
+ return temp;
+}
+
+mdMethodDef WrapICorJitInfo::getMethodDefFromMethod(
+ CORINFO_METHOD_HANDLE hMethod)
+{
+ API_ENTER(getMethodDefFromMethod);
+ mdMethodDef result = wrapHnd->getMethodDefFromMethod(hMethod);
+ API_LEAVE(getMethodDefFromMethod);
+ return result;
+}
+
+const char* WrapICorJitInfo::getMethodName(
+ CORINFO_METHOD_HANDLE ftn, /* IN */
+ const char **moduleName /* OUT */)
+{
+ API_ENTER(getMethodName);
+ const char* temp = wrapHnd->getMethodName(ftn, moduleName);
+ API_LEAVE(getMethodName);
+ return temp;
+}
+
+unsigned WrapICorJitInfo::getMethodHash(
+ CORINFO_METHOD_HANDLE ftn /* IN */)
+{
+ API_ENTER(getMethodHash);
+ unsigned temp = wrapHnd->getMethodHash(ftn);
+ API_LEAVE(getMethodHash);
+ return temp;
+}
+
+size_t WrapICorJitInfo::findNameOfToken(
+ CORINFO_MODULE_HANDLE module, /* IN */
+ mdToken metaTOK, /* IN */
+ __out_ecount(FQNameCapacity) char * szFQName, /* OUT */
+ size_t FQNameCapacity /* IN */)
+{
+ API_ENTER(findNameOfToken);
+ size_t result = wrapHnd->findNameOfToken(module, metaTOK, szFQName, FQNameCapacity);
+ API_LEAVE(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)
+{
+ API_ENTER(getSystemVAmd64PassStructInRegisterDescriptor);
+ bool result = wrapHnd->getSystemVAmd64PassStructInRegisterDescriptor(structHnd, structPassInRegDescPtr);
+ API_LEAVE(getSystemVAmd64PassStructInRegisterDescriptor);
+ return result;
+}
+
+#endif
+
+DWORD WrapICorJitInfo::getThreadTLSIndex(
+ void **ppIndirection)
+{
+ API_ENTER(getThreadTLSIndex);
+ DWORD temp = wrapHnd->getThreadTLSIndex(ppIndirection);
+ API_LEAVE(getThreadTLSIndex);
+ return temp;
+}
+
+const void * WrapICorJitInfo::getInlinedCallFrameVptr(
+ void **ppIndirection)
+{
+ API_ENTER(getInlinedCallFrameVptr);
+ const void* temp = wrapHnd->getInlinedCallFrameVptr(ppIndirection);
+ API_LEAVE(getInlinedCallFrameVptr);
+ return temp;
+}
+
+LONG * WrapICorJitInfo::getAddrOfCaptureThreadGlobal(
+ void **ppIndirection)
+{
+ API_ENTER(getAddrOfCaptureThreadGlobal);
+ LONG * temp = wrapHnd->getAddrOfCaptureThreadGlobal(ppIndirection);
+ API_LEAVE(getAddrOfCaptureThreadGlobal);
+ return temp;
+}
+
+SIZE_T* WrapICorJitInfo::getAddrModuleDomainID(CORINFO_MODULE_HANDLE module)
+{
+ API_ENTER(getAddrModuleDomainID);
+ SIZE_T* result = wrapHnd->getAddrModuleDomainID(module);
+ API_LEAVE(getAddrModuleDomainID);
+ return result;
+}
+
+void* WrapICorJitInfo::getHelperFtn(
+ CorInfoHelpFunc ftnNum,
+ void **ppIndirection)
+{
+ API_ENTER(getHelperFtn);
+ void *temp = wrapHnd->getHelperFtn(ftnNum, ppIndirection);
+ API_LEAVE(getHelperFtn);
+ return temp;
+}
+
+void WrapICorJitInfo::getFunctionEntryPoint(
+ CORINFO_METHOD_HANDLE ftn, /* IN */
+ CORINFO_CONST_LOOKUP * pResult, /* OUT */
+ CORINFO_ACCESS_FLAGS accessFlags)
+{
+ API_ENTER(getFunctionEntryPoint);
+ wrapHnd->getFunctionEntryPoint(ftn, pResult, accessFlags);
+ API_LEAVE(getFunctionEntryPoint);
+}
+
+void WrapICorJitInfo::getFunctionFixedEntryPoint(
+ CORINFO_METHOD_HANDLE ftn,
+ CORINFO_CONST_LOOKUP * pResult)
+{
+ API_ENTER(getFunctionFixedEntryPoint);
+ wrapHnd->getFunctionFixedEntryPoint(ftn, pResult);
+ API_LEAVE(getFunctionFixedEntryPoint);
+}
+
+void* WrapICorJitInfo::getMethodSync(
+ CORINFO_METHOD_HANDLE ftn,
+ void **ppIndirection)
+{
+ API_ENTER(getMethodSync);
+ void *temp = wrapHnd->getMethodSync(ftn, ppIndirection);
+ API_LEAVE(getMethodSync);
+ return temp;
+}
+
+
+CorInfoHelpFunc WrapICorJitInfo::getLazyStringLiteralHelper(
+ CORINFO_MODULE_HANDLE handle)
+{
+ API_ENTER(getLazyStringLiteralHelper);
+ CorInfoHelpFunc temp = wrapHnd->getLazyStringLiteralHelper(handle);
+ API_LEAVE(getLazyStringLiteralHelper);
+ return temp;
+}
+
+CORINFO_MODULE_HANDLE WrapICorJitInfo::embedModuleHandle(
+ CORINFO_MODULE_HANDLE handle,
+ void **ppIndirection)
+{
+ API_ENTER(embedModuleHandle);
+ CORINFO_MODULE_HANDLE temp = wrapHnd->embedModuleHandle(handle, ppIndirection);
+ API_LEAVE(embedModuleHandle);
+ return temp;
+}
+
+CORINFO_CLASS_HANDLE WrapICorJitInfo::embedClassHandle(
+ CORINFO_CLASS_HANDLE handle,
+ void **ppIndirection)
+{
+ API_ENTER(embedClassHandle);
+ CORINFO_CLASS_HANDLE temp = wrapHnd->embedClassHandle(handle, ppIndirection);
+ API_LEAVE(embedClassHandle);
+ return temp;
+}
+
+CORINFO_METHOD_HANDLE WrapICorJitInfo::embedMethodHandle(
+ CORINFO_METHOD_HANDLE handle,
+ void **ppIndirection)
+{
+ API_ENTER(embedMethodHandle);
+ CORINFO_METHOD_HANDLE temp = wrapHnd->embedMethodHandle(handle, ppIndirection);
+ API_LEAVE(embedMethodHandle);
+ return temp;
+}
+
+CORINFO_FIELD_HANDLE WrapICorJitInfo::embedFieldHandle(
+ CORINFO_FIELD_HANDLE handle,
+ void **ppIndirection)
+{
+ API_ENTER(embedFieldHandle);
+ CORINFO_FIELD_HANDLE temp = wrapHnd->embedFieldHandle(handle, ppIndirection);
+ API_LEAVE(embedFieldHandle);
+ return temp;
+}
+
+void WrapICorJitInfo::embedGenericHandle(
+ CORINFO_RESOLVED_TOKEN * pResolvedToken,
+ BOOL fEmbedParent,
+ CORINFO_GENERICHANDLE_RESULT * pResult)
+{
+ API_ENTER(embedGenericHandle);
+ wrapHnd->embedGenericHandle(pResolvedToken, fEmbedParent, pResult);
+ API_LEAVE(embedGenericHandle);
+}
+
+CORINFO_LOOKUP_KIND WrapICorJitInfo::getLocationOfThisType(
+ CORINFO_METHOD_HANDLE context)
+{
+ API_ENTER(getLocationOfThisType);
+ CORINFO_LOOKUP_KIND temp = wrapHnd->getLocationOfThisType(context);
+ API_LEAVE(getLocationOfThisType);
+ return temp;
+}
+
+void* WrapICorJitInfo::getPInvokeUnmanagedTarget(
+ CORINFO_METHOD_HANDLE method,
+ void **ppIndirection)
+{
+ API_ENTER(getPInvokeUnmanagedTarget);
+ void *result = wrapHnd->getPInvokeUnmanagedTarget(method, ppIndirection);
+ API_LEAVE(getPInvokeUnmanagedTarget);
+ return result;
+}
+
+void* WrapICorJitInfo::getAddressOfPInvokeFixup(
+ CORINFO_METHOD_HANDLE method,
+ void **ppIndirection)
+{
+ API_ENTER(getAddressOfPInvokeFixup);
+ void *temp = wrapHnd->getAddressOfPInvokeFixup(method, ppIndirection);
+ API_LEAVE(getAddressOfPInvokeFixup);
+ return temp;
+}
+
+#if COR_JIT_EE_VERSION > 460
+
+void WrapICorJitInfo::getAddressOfPInvokeTarget(
+ CORINFO_METHOD_HANDLE method,
+ CORINFO_CONST_LOOKUP *pLookup)
+{
+ API_ENTER(getAddressOfPInvokeTarget);
+ wrapHnd->getAddressOfPInvokeTarget(method, pLookup);
+ API_LEAVE(getAddressOfPInvokeTarget);
+}
+
+#endif
+
+LPVOID WrapICorJitInfo::GetCookieForPInvokeCalliSig(
+ CORINFO_SIG_INFO* szMetaSig,
+ void ** ppIndirection)
+{
+ API_ENTER(GetCookieForPInvokeCalliSig);
+ LPVOID temp = wrapHnd->GetCookieForPInvokeCalliSig(szMetaSig, ppIndirection);
+ API_LEAVE(GetCookieForPInvokeCalliSig);
+ return temp;
+}
+
+bool WrapICorJitInfo::canGetCookieForPInvokeCalliSig(
+ CORINFO_SIG_INFO* szMetaSig)
+{
+ API_ENTER(canGetCookieForPInvokeCalliSig);
+ bool temp = wrapHnd->canGetCookieForPInvokeCalliSig(szMetaSig);
+ API_LEAVE(canGetCookieForPInvokeCalliSig);
+ return temp;
+}
+
+CORINFO_JUST_MY_CODE_HANDLE WrapICorJitInfo::getJustMyCodeHandle(
+ CORINFO_METHOD_HANDLE method,
+ CORINFO_JUST_MY_CODE_HANDLE**ppIndirection)
+{
+ API_ENTER(getJustMyCodeHandle);
+ CORINFO_JUST_MY_CODE_HANDLE temp = wrapHnd->getJustMyCodeHandle(method, ppIndirection);
+ API_LEAVE(getJustMyCodeHandle);
+ return temp;
+}
+
+void WrapICorJitInfo::GetProfilingHandle(
+ BOOL *pbHookFunction,
+ void **pProfilerHandle,
+ BOOL *pbIndirectedHandles)
+{
+ API_ENTER(GetProfilingHandle);
+ wrapHnd->GetProfilingHandle(pbHookFunction, pProfilerHandle, pbIndirectedHandles);
+ API_LEAVE(GetProfilingHandle);
+}
+
+void WrapICorJitInfo::getCallInfo(
+ CORINFO_RESOLVED_TOKEN * pResolvedToken,
+ CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken,
+ CORINFO_METHOD_HANDLE callerHandle,
+ CORINFO_CALLINFO_FLAGS flags,
+ CORINFO_CALL_INFO *pResult)
+{
+ API_ENTER(getCallInfo);
+ wrapHnd->getCallInfo(pResolvedToken, pConstrainedResolvedToken, callerHandle, flags, pResult);
+ API_LEAVE(getCallInfo);
+}
+
+BOOL WrapICorJitInfo::canAccessFamily(CORINFO_METHOD_HANDLE hCaller,
+ CORINFO_CLASS_HANDLE hInstanceType)
+{
+ API_ENTER(canAccessFamily);
+ BOOL temp = wrapHnd->canAccessFamily(hCaller, hInstanceType);
+ API_LEAVE(canAccessFamily);
+ return temp;
+}
+
+BOOL WrapICorJitInfo::isRIDClassDomainID(CORINFO_CLASS_HANDLE cls)
+{
+ API_ENTER(isRIDClassDomainID);
+ BOOL result = wrapHnd->isRIDClassDomainID(cls);
+ API_LEAVE(isRIDClassDomainID);
+ return result;
+}
+
+unsigned WrapICorJitInfo::getClassDomainID(
+ CORINFO_CLASS_HANDLE cls,
+ void **ppIndirection)
+{
+ API_ENTER(getClassDomainID);
+ unsigned temp = wrapHnd->getClassDomainID(cls, ppIndirection);
+ API_LEAVE(getClassDomainID);
+ return temp;
+}
+
+void* WrapICorJitInfo::getFieldAddress(
+ CORINFO_FIELD_HANDLE field,
+ void **ppIndirection)
+{
+ API_ENTER(getFieldAddress);
+ void *temp = wrapHnd->getFieldAddress(field, ppIndirection);
+ API_LEAVE(getFieldAddress);
+ return temp;
+}
+
+CORINFO_VARARGS_HANDLE WrapICorJitInfo::getVarArgsHandle(
+ CORINFO_SIG_INFO *pSig,
+ void **ppIndirection)
+{
+ API_ENTER(getVarArgsHandle);
+ CORINFO_VARARGS_HANDLE temp = wrapHnd->getVarArgsHandle(pSig, ppIndirection);
+ API_LEAVE(getVarArgsHandle);
+ return temp;
+}
+
+bool WrapICorJitInfo::canGetVarArgsHandle(
+ CORINFO_SIG_INFO *pSig)
+{
+ API_ENTER(canGetVarArgsHandle);
+ bool temp = wrapHnd->canGetVarArgsHandle(pSig);
+ API_LEAVE(canGetVarArgsHandle);
+ return temp;
+}
+
+InfoAccessType WrapICorJitInfo::constructStringLiteral(
+ CORINFO_MODULE_HANDLE module,
+ mdToken metaTok,
+ void **ppValue)
+{
+ API_ENTER(constructStringLiteral);
+ InfoAccessType temp = wrapHnd->constructStringLiteral(module, metaTok, ppValue);
+ API_LEAVE(constructStringLiteral);
+ return temp;
+}
+
+InfoAccessType WrapICorJitInfo::emptyStringLiteral(void **ppValue)
+{
+ API_ENTER(emptyStringLiteral);
+ InfoAccessType temp = wrapHnd->emptyStringLiteral(ppValue);
+ API_LEAVE(emptyStringLiteral);
+ return temp;
+}
+
+DWORD WrapICorJitInfo::getFieldThreadLocalStoreID(
+ CORINFO_FIELD_HANDLE field,
+ void **ppIndirection)
+{
+ API_ENTER(getFieldThreadLocalStoreID);
+ DWORD temp = wrapHnd->getFieldThreadLocalStoreID(field, ppIndirection);
+ API_LEAVE(getFieldThreadLocalStoreID);
+ return temp;
+}
+
+void WrapICorJitInfo::setOverride(
+ ICorDynamicInfo *pOverride,
+ CORINFO_METHOD_HANDLE currentMethod)
+{
+ API_ENTER(setOverride);
+ wrapHnd->setOverride(pOverride, currentMethod);
+ API_LEAVE(setOverride);
+}
+
+void WrapICorJitInfo::addActiveDependency(
+ CORINFO_MODULE_HANDLE moduleFrom,
+ CORINFO_MODULE_HANDLE moduleTo)
+{
+ API_ENTER(addActiveDependency);
+ wrapHnd->addActiveDependency(moduleFrom, moduleTo);
+ API_LEAVE(addActiveDependency);
+}
+
+CORINFO_METHOD_HANDLE WrapICorJitInfo::GetDelegateCtor(
+ CORINFO_METHOD_HANDLE methHnd,
+ CORINFO_CLASS_HANDLE clsHnd,
+ CORINFO_METHOD_HANDLE targetMethodHnd,
+ DelegateCtorArgs * pCtorData)
+{
+ API_ENTER(GetDelegateCtor);
+ CORINFO_METHOD_HANDLE temp = wrapHnd->GetDelegateCtor(methHnd, clsHnd, targetMethodHnd, pCtorData);
+ API_LEAVE(GetDelegateCtor);
+ return temp;
+}
+
+void WrapICorJitInfo::MethodCompileComplete(
+ CORINFO_METHOD_HANDLE methHnd)
+{
+ API_ENTER(MethodCompileComplete);
+ wrapHnd->MethodCompileComplete(methHnd);
+ API_LEAVE(MethodCompileComplete);
+}
+
+void* WrapICorJitInfo::getTailCallCopyArgsThunk(
+ CORINFO_SIG_INFO *pSig,
+ CorInfoHelperTailCallSpecialHandling flags)
+{
+ API_ENTER(getTailCallCopyArgsThunk);
+ void *result = wrapHnd->getTailCallCopyArgsThunk(pSig, flags);
+ API_LEAVE(getTailCallCopyArgsThunk);
+ return result;
+}
+
+/*********************************************************************************/
+//
+// ICorJitInfo
+//
+/*********************************************************************************/
+
+#if COR_JIT_EE_VERSION > 460
+
+DWORD WrapICorJitInfo::getJitFlags(CORJIT_FLAGS *jitFlags, DWORD sizeInBytes)
+{
+ API_ENTER(getJitFlags);
+ DWORD result = wrapHnd->getJitFlags(jitFlags, sizeInBytes);
+ API_LEAVE(getJitFlags);
+ return result;
+}
+
+bool WrapICorJitInfo::runWithErrorTrap(void(*function)(void*), void *param)
+{
+ return wrapHnd->runWithErrorTrap(function, param);
+}
+
+#endif
+
+IEEMemoryManager* WrapICorJitInfo::getMemoryManager()
+{
+ API_ENTER(getMemoryManager);
+ IEEMemoryManager * temp = wrapHnd->getMemoryManager();
+ API_LEAVE(getMemoryManager);
+ return temp;
+}
+
+void WrapICorJitInfo::allocMem(
+ ULONG hotCodeSize, /* IN */
+ ULONG coldCodeSize, /* IN */
+ ULONG roDataSize, /* IN */
+ ULONG xcptnsCount, /* IN */
+ CorJitAllocMemFlag flag, /* IN */
+ void ** hotCodeBlock, /* OUT */
+ void ** coldCodeBlock, /* OUT */
+ void ** roDataBlock /* OUT */)
+{
+ API_ENTER(allocMem);
+ wrapHnd->allocMem(hotCodeSize, coldCodeSize, roDataSize, xcptnsCount, flag, hotCodeBlock, coldCodeBlock, roDataBlock);
+ API_LEAVE(allocMem);
+}
+
+void WrapICorJitInfo::reserveUnwindInfo(
+ BOOL isFunclet, /* IN */
+ BOOL isColdCode, /* IN */
+ ULONG unwindSize /* IN */)
+{
+ API_ENTER(reserveUnwindInfo);
+ wrapHnd->reserveUnwindInfo(isFunclet, isColdCode, unwindSize);
+ API_LEAVE(reserveUnwindInfo);
+}
+
+void WrapICorJitInfo::allocUnwindInfo(
+ BYTE * pHotCode, /* IN */
+ BYTE * pColdCode, /* IN */
+ ULONG startOffset, /* IN */
+ ULONG endOffset, /* IN */
+ ULONG unwindSize, /* IN */
+ BYTE * pUnwindBlock, /* IN */
+ CorJitFuncKind funcKind /* IN */)
+{
+ API_ENTER(allocUnwindInfo);
+ wrapHnd->allocUnwindInfo(pHotCode, pColdCode, startOffset, endOffset, unwindSize, pUnwindBlock, funcKind);
+ API_LEAVE(allocUnwindInfo);
+}
+
+void *WrapICorJitInfo::allocGCInfo(size_t size /* IN */)
+{
+ API_ENTER(allocGCInfo);
+ void *temp = wrapHnd->allocGCInfo(size);
+ API_LEAVE(allocGCInfo);
+ return temp;
+}
+
+void WrapICorJitInfo::yieldExecution()
+{
+ API_ENTER(yieldExecution); //Nothing to record
+ wrapHnd->yieldExecution();
+ API_LEAVE(yieldExecution); //Nothing to recor)
+}
+
+void WrapICorJitInfo::setEHcount(unsigned cEH /* IN */)
+{
+ API_ENTER(setEHcount);
+ wrapHnd->setEHcount(cEH);
+ API_LEAVE(setEHcount);
+}
+
+void WrapICorJitInfo::setEHinfo(
+ unsigned EHnumber, /* IN */
+ const CORINFO_EH_CLAUSE *clause /* IN */)
+{
+ API_ENTER(setEHinfo);
+ wrapHnd->setEHinfo(EHnumber, clause);
+ API_LEAVE(setEHinfo);
+}
+
+BOOL WrapICorJitInfo::logMsg(unsigned level, const char* fmt, va_list args)
+{
+ API_ENTER(logMsg);
+ BOOL result = wrapHnd->logMsg(level, fmt, args);
+ API_LEAVE(logMsg);
+ return result;
+}
+
+int WrapICorJitInfo::doAssert(const char* szFile, int iLine, const char* szExpr)
+{
+ API_ENTER(doAssert);
+ int result = wrapHnd->doAssert(szFile, iLine, szExpr);
+ API_LEAVE(doAssert);
+ return result;
+}
+
+void WrapICorJitInfo::reportFatalError(CorJitResult result)
+{
+ API_ENTER(reportFatalError);
+ wrapHnd->reportFatalError(result);
+ API_LEAVE(reportFatalError);
+}
+
+HRESULT WrapICorJitInfo::allocBBProfileBuffer(
+ ULONG count,
+ ProfileBuffer **profileBuffer)
+{
+ API_ENTER(allocBBProfileBuffer);
+ HRESULT result = wrapHnd->allocBBProfileBuffer(count, profileBuffer);
+ API_LEAVE(allocBBProfileBuffer);
+ return result;
+}
+
+HRESULT WrapICorJitInfo::getBBProfileData(
+ CORINFO_METHOD_HANDLE ftnHnd,
+ ULONG *count,
+ ProfileBuffer **profileBuffer,
+ ULONG *numRuns)
+{
+ API_ENTER(getBBProfileData);
+ HRESULT temp = wrapHnd->getBBProfileData(ftnHnd, count, profileBuffer, numRuns);
+ API_LEAVE(getBBProfileData);
+ return temp;
+}
+
+void WrapICorJitInfo::recordCallSite(
+ ULONG instrOffset, /* IN */
+ CORINFO_SIG_INFO * callSig, /* IN */
+ CORINFO_METHOD_HANDLE methodHandle /* IN */)
+{
+ API_ENTER(recordCallSite);
+ wrapHnd->recordCallSite(instrOffset, callSig, methodHandle);
+ API_LEAVE(recordCallSite);
+}
+
+void WrapICorJitInfo::recordRelocation(
+ void *location, /* IN */
+ void *target, /* IN */
+ WORD fRelocType, /* IN */
+ WORD slotNum, /* IN */
+ INT32 addlDelta /* IN */)
+{
+ API_ENTER(recordRelocation);
+ wrapHnd->recordRelocation(location, target, fRelocType, slotNum, addlDelta);
+ API_LEAVE(recordRelocation);
+}
+
+WORD WrapICorJitInfo::getRelocTypeHint(void *target)
+{
+ API_ENTER(getRelocTypeHint);
+ WORD result = wrapHnd->getRelocTypeHint(target);
+ API_LEAVE(getRelocTypeHint);
+ return result;
+}
+
+void WrapICorJitInfo::getModuleNativeEntryPointRange(
+ void **pStart, /* OUT */
+ void **pEnd /* OUT */)
+{
+ API_ENTER(getModuleNativeEntryPointRange);
+ wrapHnd->getModuleNativeEntryPointRange(pStart, pEnd);
+ API_LEAVE(getModuleNativeEntryPointRange);
+}
+
+DWORD WrapICorJitInfo::getExpectedTargetArchitecture()
+{
+ API_ENTER(getExpectedTargetArchitecture);
+ DWORD result = wrapHnd->getExpectedTargetArchitecture();
+ API_LEAVE(getExpectedTargetArchitecture);
+ return result;
+}
+
+/**********************************************************************************/
+// clang-format on
+/**********************************************************************************/
diff --git a/src/jit/assertionprop.cpp b/src/jit/assertionprop.cpp
index fe35c3b780..cb0832fe47 100644
--- a/src/jit/assertionprop.cpp
+++ b/src/jit/assertionprop.cpp
@@ -1100,11 +1100,6 @@ Compiler::AssertionIndex Compiler::optCreateAssertion(GenTreePtr op1,
CNS_COMMON:
{
- // TODO-1stClassStructs: handle constant propagation to struct types.
- if (varTypeIsStruct(lclVar))
- {
- goto DONE_ASSERTION;
- }
//
// Must either be an OAK_EQUAL or an OAK_NOT_EQUAL assertion
//
@@ -2034,12 +2029,7 @@ void Compiler::optAssertionGen(GenTreePtr tree)
{
case GT_ASG:
// VN takes care of non local assertions for assignments and data flow.
- // TODO-1stClassStructs: Enable assertion prop for struct types.
- if (varTypeIsStruct(tree))
- {
- // Do nothing.
- }
- else if (optLocalAssertionProp)
+ if (optLocalAssertionProp)
{
assertionIndex = optCreateAssertion(tree->gtOp.gtOp1, tree->gtOp.gtOp2, OAK_EQUAL);
}
@@ -2052,26 +2042,15 @@ void Compiler::optAssertionGen(GenTreePtr tree)
case GT_OBJ:
case GT_BLK:
case GT_DYN_BLK:
- // TODO-1stClassStructs: These should always be considered to create a non-null
- // assertion, but previously, when these indirections were implicit due to a block
- // copy or init, they were not being considered to do so.
- break;
case GT_IND:
- // TODO-1stClassStructs: All indirections should be considered to create a non-null
- // assertion, but previously, when these indirections were implicit due to a block
- // copy or init, they were not being considered to do so.
- if (tree->gtType == TYP_STRUCT)
- {
- GenTree* parent = tree->gtGetParent(nullptr);
- if ((parent != nullptr) && (parent->gtOper == GT_ASG))
- {
- break;
- }
- }
case GT_NULLCHECK:
+ // All indirections create non-null assertions
+ assertionIndex = optCreateAssertion(tree->AsIndir()->Addr(), nullptr, OAK_NOT_EQUAL);
+ break;
+
case GT_ARR_LENGTH:
- // An array length can create a non-null assertion
- assertionIndex = optCreateAssertion(tree->gtOp.gtOp1, nullptr, OAK_NOT_EQUAL);
+ // An array length is an indirection (but doesn't derive from GenTreeIndir).
+ assertionIndex = optCreateAssertion(tree->AsArrLen()->ArrRef(), nullptr, OAK_NOT_EQUAL);
break;
case GT_ARR_BOUNDS_CHECK:
@@ -2629,9 +2608,29 @@ GenTreePtr Compiler::optConstantAssertionProp(AssertionDsc* curAssertion,
else
{
bool isArrIndex = ((tree->gtFlags & GTF_VAR_ARR_INDEX) != 0);
- newTree->ChangeOperConst(GT_CNS_INT);
- newTree->gtIntCon.gtIconVal = curAssertion->op2.u1.iconVal;
- newTree->ClearIconHandleMask();
+ // If we have done constant propagation of a struct type, it is only valid for zero-init,
+ // and we have to ensure that we have the right zero for the type.
+ if (varTypeIsStruct(tree))
+ {
+ assert(curAssertion->op2.u1.iconVal == 0);
+ }
+#ifdef FEATURE_SIMD
+ if (varTypeIsSIMD(tree))
+ {
+ var_types simdType = tree->TypeGet();
+ tree->ChangeOperConst(GT_CNS_DBL);
+ GenTree* initVal = tree;
+ initVal->gtType = TYP_FLOAT;
+ newTree =
+ gtNewSIMDNode(simdType, initVal, nullptr, SIMDIntrinsicInit, TYP_FLOAT, genTypeSize(simdType));
+ }
+ else
+#endif // FEATURE_SIMD
+ {
+ newTree->ChangeOperConst(GT_CNS_INT);
+ newTree->gtIntCon.gtIconVal = curAssertion->op2.u1.iconVal;
+ newTree->ClearIconHandleMask();
+ }
// If we're doing an array index address, assume any constant propagated contributes to the index.
if (isArrIndex)
{
@@ -3421,32 +3420,13 @@ GenTreePtr Compiler::optAssertionProp_Ind(ASSERT_VALARG_TP assertions, const Gen
{
assert(tree->OperIsIndir());
- // TODO-1stClassStructs: All indirections should be handled here, but
- // previously, when these indirections were GT_OBJ, or implicit due to a block
- // copy or init, they were not being handled.
- if (tree->TypeGet() == TYP_STRUCT)
- {
- if (tree->OperIsBlk())
- {
- return nullptr;
- }
- else
- {
- GenTree* parent = tree->gtGetParent(nullptr);
- if ((parent != nullptr) && parent->OperIsBlkOp())
- {
- return nullptr;
- }
- }
- }
-
if (!(tree->gtFlags & GTF_EXCEPT))
{
return nullptr;
}
// Check for add of a constant.
- GenTreePtr op1 = tree->gtOp.gtOp1;
+ GenTreePtr op1 = tree->AsIndir()->Addr();
if ((op1->gtOper == GT_ADD) && (op1->gtOp.gtOp2->gtOper == GT_CNS_INT))
{
op1 = op1->gtOp.gtOp1;
@@ -3700,6 +3680,21 @@ GenTreePtr Compiler::optAssertionProp_BndsChk(ASSERT_VALARG_TP assertions, const
assert(tree->gtOper == GT_ARR_BOUNDS_CHECK);
+#ifdef FEATURE_ENABLE_NO_RANGE_CHECKS
+ if (JitConfig.JitNoRangeChks())
+ {
+#ifdef DEBUG
+ if (verbose)
+ {
+ printf("\nFlagging check redundant due to JitNoRangeChks in BB%02u:\n", compCurBB->bbNum);
+ gtDispTree(tree, nullptr, nullptr, true);
+ }
+#endif // DEBUG
+ tree->gtFlags |= GTF_ARR_BOUND_INBND;
+ return nullptr;
+ }
+#endif // FEATURE_ENABLE_NO_RANGE_CHECKS
+
BitVecOps::Iter iter(apTraits, assertions);
unsigned index = 0;
while (iter.NextElem(apTraits, &index))
@@ -4688,9 +4683,8 @@ GenTreePtr Compiler::optVNConstantPropOnJTrue(BasicBlock* block, GenTreePtr stmt
newStmt = fgInsertStmtNearEnd(block, sideEffList);
sideEffList = nullptr;
}
- fgMorphBlockStmt(block, newStmt DEBUGARG(__FUNCTION__));
- gtSetStmtInfo(newStmt);
- fgSetStmtSeq(newStmt);
+
+ fgMorphBlockStmt(block, newStmt->AsStmt() DEBUGARG(__FUNCTION__));
}
// Transform the relop's operands to be both zeroes.
@@ -4748,7 +4742,6 @@ Compiler::fgWalkResult Compiler::optVNConstantPropCurStmt(BasicBlock* block, Gen
case GT_MOD:
case GT_UDIV:
case GT_UMOD:
- case GT_MULHI:
case GT_EQ:
case GT_NE:
case GT_LT:
@@ -4767,6 +4760,10 @@ Compiler::fgWalkResult Compiler::optVNConstantPropCurStmt(BasicBlock* block, Gen
case GT_INTRINSIC:
break;
+ case GT_MULHI:
+ assert(false && "Unexpected GT_MULHI node encountered before lowering");
+ break;
+
case GT_JTRUE:
break;
@@ -4911,9 +4908,7 @@ GenTreePtr Compiler::optVNAssertionPropCurStmt(BasicBlock* block, GenTreePtr stm
if (optAssertionPropagatedCurrentStmt)
{
- fgMorphBlockStmt(block, stmt DEBUGARG("optVNAssertionPropCurStmt"));
- gtSetStmtInfo(stmt);
- fgSetStmtSeq(stmt);
+ fgMorphBlockStmt(block, stmt->AsStmt() DEBUGARG("optVNAssertionPropCurStmt"));
}
// Check if propagation removed statements starting from current stmt.
@@ -5110,13 +5105,7 @@ void Compiler::optAssertionPropMain()
}
#endif
// Re-morph the statement.
- fgMorphBlockStmt(block, stmt DEBUGARG("optAssertionPropMain"));
-
- // Recalculate the gtCostSz, etc...
- gtSetStmtInfo(stmt);
-
- // Re-thread the nodes
- fgSetStmtSeq(stmt);
+ fgMorphBlockStmt(block, stmt->AsStmt() DEBUGARG("optAssertionPropMain"));
}
// Check if propagation removed statements starting from current stmt.
diff --git a/src/jit/bitsetasuint64.h b/src/jit/bitsetasuint64.h
index 150f7e9d61..243e9e33b4 100644
--- a/src/jit/bitsetasuint64.h
+++ b/src/jit/bitsetasuint64.h
@@ -167,7 +167,7 @@ public:
{
IAllocator* alloc = BitSetTraits::GetDebugOnlyAllocator(env);
const int CharsForUINT64 = sizeof(UINT64) * 2;
- char* res = NULL;
+ char* res = nullptr;
const int AllocSize = CharsForUINT64 + 4;
res = (char*)alloc->Alloc(AllocSize);
UINT64 bits = bs;
diff --git a/src/jit/block.cpp b/src/jit/block.cpp
index 2d37754ec5..47f1052cc8 100644
--- a/src/jit/block.cpp
+++ b/src/jit/block.cpp
@@ -554,7 +554,9 @@ void BasicBlock::dspBlockHeader(Compiler* compiler,
}
if (showFlags)
{
- printf(" flags=0x%08x: ", bbFlags);
+ const unsigned lowFlags = (unsigned)bbFlags;
+ const unsigned highFlags = (unsigned)(bbFlags >> 32);
+ printf(" flags=0x%08x.%08x: ", highFlags, lowFlags);
dspFlags();
}
printf("\n");
@@ -568,7 +570,25 @@ void* BasicBlock::HeapPhiArg::operator new(size_t sz, Compiler* comp)
return comp->compGetMem(sz, CMK_HeapPhiArg);
}
-void BasicBlock::CloneBlockState(Compiler* compiler, BasicBlock* to, const BasicBlock* from)
+//------------------------------------------------------------------------
+// CloneBlockState: Try to populate `to` block with a copy of `from` block's statements, replacing
+// uses of local `varNum` with IntCns `varVal`.
+//
+// Arguments:
+// compiler - Jit compiler instance
+// to - New/empty block to copy statements into
+// from - Block to copy statements from
+// varNum - lclVar uses with lclNum `varNum` will be replaced; can be ~0 to indicate no replacement.
+// varVal - If replacing uses of `varNum`, replace them with int constants with value `varVal`.
+//
+// Return Value:
+// Cloning may fail because this routine uses `gtCloneExpr` for cloning and it can't handle all
+// IR nodes. If cloning of any statement fails, `false` will be returned and block `to` may be
+// partially populated. If cloning of all statements succeeds, `true` will be returned and
+// block `to` will be fully populated.
+
+bool BasicBlock::CloneBlockState(
+ Compiler* compiler, BasicBlock* to, const BasicBlock* from, unsigned varNum, int varVal)
{
assert(to->bbTreeList == nullptr);
@@ -595,9 +615,17 @@ void BasicBlock::CloneBlockState(Compiler* compiler, BasicBlock* to, const Basic
for (GenTreePtr fromStmt = from->bbTreeList; fromStmt != nullptr; fromStmt = fromStmt->gtNext)
{
- compiler->fgInsertStmtAtEnd(to,
- compiler->fgNewStmtFromTree(compiler->gtCloneExpr(fromStmt->gtStmt.gtStmtExpr)));
+ auto newExpr = compiler->gtCloneExpr(fromStmt->gtStmt.gtStmtExpr, 0, varNum, varVal);
+ if (!newExpr)
+ {
+ // gtCloneExpr doesn't handle all opcodes, so may fail to clone a statement.
+ // When that happens, it returns nullptr; abandon the rest of this block and
+ // return `false` to the caller to indicate that cloning was unsuccessful.
+ return false;
+ }
+ compiler->fgInsertStmtAtEnd(to, compiler->fgNewStmtFromTree(newExpr));
}
+ return true;
}
// LIR helpers
@@ -667,7 +695,6 @@ GenTreeStmt* BasicBlock::lastStmt()
return result->AsStmt();
}
-
//------------------------------------------------------------------------
// BasicBlock::firstNode: Returns the first node in the block.
//
diff --git a/src/jit/block.h b/src/jit/block.h
index ecfbb620a1..99c0efc1a7 100644
--- a/src/jit/block.h
+++ b/src/jit/block.h
@@ -30,17 +30,13 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include "simplerhash.h"
/*****************************************************************************/
-
+typedef BitVec EXPSET_TP;
#if LARGE_EXPSET
-typedef unsigned __int64 EXPSET_TP;
#define EXPSET_SZ 64
#else
-typedef unsigned int EXPSET_TP;
#define EXPSET_SZ 32
#endif
-#define EXPSET_ALL ((EXPSET_TP)0 - 1)
-
typedef BitVec ASSERT_TP;
typedef BitVec_ValArg_T ASSERT_VALARG_TP;
typedef BitVec_ValRet_T ASSERT_VALRET_TP;
@@ -291,14 +287,14 @@ struct BasicBlock : private LIR::Range
}
}
+ unsigned __int64 bbFlags; // see BBF_xxxx below
+
unsigned bbNum; // the block's number
unsigned bbPostOrderNum; // the block's post order number in the graph.
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.
- unsigned bbFlags; // see BBF_xxxx below
-
#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
@@ -357,6 +353,10 @@ struct BasicBlock : private LIR::Range
// BBJ_CALLFINALLY block, as well as, on x86, the final step block out of a
// finally.
+// Flags that relate blocks to loop structure.
+
+#define BBF_LOOP_FLAGS (BBF_LOOP_PREHEADER | BBF_LOOP_HEAD | BBF_LOOP_CALL0 | BBF_LOOP_CALL1)
+
bool isRunRarely()
{
return ((bbFlags & BBF_RUN_RARELY) != 0);
@@ -860,9 +860,7 @@ struct BasicBlock : private LIR::Range
unsigned bbHeapSsaNumIn; // The SSA # of "Heap" on entry to the block.
unsigned bbHeapSsaNumOut; // The SSA # of "Heap" on exit from the block.
-#ifdef DEBUGGING_SUPPORT
VARSET_TP bbScope; // variables in scope over the block
-#endif
void InitVarSets(class Compiler* comp);
@@ -1094,9 +1092,11 @@ public:
return AllSuccs(comp, this);
}
- // Clone block state and statements from 'from' block to 'to' block.
- // Assumes that "to" is an empty block.
- static void CloneBlockState(Compiler* compiler, BasicBlock* to, const BasicBlock* from);
+ // Try to clone block state and statements from `from` block to `to` block (which must be new/empty),
+ // optionally replacing uses of local `varNum` with IntCns `varVal`. Return true if all statements
+ // in the block are cloned successfully, false (with partially-populated `to` block) if one fails.
+ static bool CloneBlockState(
+ Compiler* compiler, BasicBlock* to, const BasicBlock* from, unsigned varNum = (unsigned)-1, int varVal = 0);
void MakeLIR(GenTree* firstNode, GenTree* lastNode);
bool IsLIR();
diff --git a/src/jit/codegen.h b/src/jit/codegen.h
index 0c4a311186..c6e38ab6af 100755
--- a/src/jit/codegen.h
+++ b/src/jit/codegen.h
@@ -48,7 +48,6 @@ public:
unsigned* cnsPtr,
bool nogen = false);
-
private:
#if defined(_TARGET_XARCH_) && !FEATURE_STACK_FP_X87
// Bit masks used in negating a float or double number.
@@ -123,7 +122,7 @@ private:
void genRangeCheck(GenTree* node);
- void genLockedInstructions(GenTree* node);
+ void genLockedInstructions(GenTreeOp* node);
//-------------------------------------------------------------------------
// Register-related methods
@@ -251,6 +250,8 @@ protected:
void genAdjustSP(ssize_t delta);
+ void genAdjustStackLevel(BasicBlock* block);
+
void genExitCode(BasicBlock* block);
//-------------------------------------------------------------------------
@@ -488,15 +489,26 @@ protected:
void genAmd64EmitterUnitTests();
#endif
-//-------------------------------------------------------------------------
-//
-// End prolog/epilog generation
-//
-//-------------------------------------------------------------------------
+ //-------------------------------------------------------------------------
+ //
+ // End prolog/epilog generation
+ //
+ //-------------------------------------------------------------------------
-/*****************************************************************************/
-#ifdef DEBUGGING_SUPPORT
-/*****************************************************************************/
+ void genSinglePush();
+ void genSinglePop();
+ regMaskTP genPushRegs(regMaskTP regs, regMaskTP* byrefRegs, regMaskTP* noRefRegs);
+ void genPopRegs(regMaskTP regs, regMaskTP byrefRegs, regMaskTP noRefRegs);
+
+/*
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XX XX
+XX Debugging Support XX
+XX XX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+*/
#ifdef DEBUG
void genIPmappingDisp(unsigned mappingNum, Compiler::IPmappingDsc* ipMapping);
@@ -730,10 +742,6 @@ protected:
unsigned genTrnslLocalVarCount;
#endif
-/*****************************************************************************/
-#endif // DEBUGGING_SUPPORT
-/*****************************************************************************/
-
#ifndef LEGACY_BACKEND
#include "codegenlinear.h"
#else // LEGACY_BACKEND
diff --git a/src/jit/codegenarm.cpp b/src/jit/codegenarm.cpp
index 4ce82307f9..73e51f2ef7 100644
--- a/src/jit/codegenarm.cpp
+++ b/src/jit/codegenarm.cpp
@@ -27,102 +27,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include "gcinfoencoder.h"
#endif
-// Get the register assigned to the given node
-
-regNumber CodeGenInterface::genGetAssignedReg(GenTreePtr tree)
-{
- return tree->gtRegNum;
-}
-
-//------------------------------------------------------------------------
-// genSpillVar: Spill a local variable
-//
-// Arguments:
-// tree - the lclVar node for the variable being spilled
-//
-// Return Value:
-// None.
-//
-// Assumptions:
-// The lclVar must be a register candidate (lvRegCandidate)
-
-void CodeGen::genSpillVar(GenTreePtr tree)
-{
- regMaskTP regMask;
- unsigned varNum = tree->gtLclVarCommon.gtLclNum;
- LclVarDsc* varDsc = &(compiler->lvaTable[varNum]);
-
- // We don't actually need to spill if it is already living in memory
- bool needsSpill = ((tree->gtFlags & GTF_VAR_DEF) == 0 && varDsc->lvIsInReg());
- if (needsSpill)
- {
- bool restoreRegVar = false;
- if (tree->gtOper == GT_REG_VAR)
- {
- tree->SetOper(GT_LCL_VAR);
- restoreRegVar = true;
- }
-
- // mask off the flag to generate the right spill code, then bring it back
- tree->gtFlags &= ~GTF_REG_VAL;
-
- instruction storeIns = ins_Store(tree->TypeGet());
-
- if (varTypeIsMultiReg(tree))
- {
- assert(varDsc->lvRegNum == genRegPairLo(tree->gtRegPair));
- assert(varDsc->lvOtherReg == genRegPairHi(tree->gtRegPair));
- regNumber regLo = genRegPairLo(tree->gtRegPair);
- regNumber regHi = genRegPairHi(tree->gtRegPair);
- inst_TT_RV(storeIns, tree, regLo);
- inst_TT_RV(storeIns, tree, regHi, 4);
- }
- else
- {
- assert(varDsc->lvRegNum == tree->gtRegNum);
- inst_TT_RV(storeIns, tree, tree->gtRegNum);
- }
- tree->gtFlags |= GTF_REG_VAL;
-
- if (restoreRegVar)
- {
- tree->SetOper(GT_REG_VAR);
- }
-
- genUpdateRegLife(varDsc, /*isBorn*/ false, /*isDying*/ true DEBUGARG(tree));
- gcInfo.gcMarkRegSetNpt(varDsc->lvRegMask());
-
- if (VarSetOps::IsMember(compiler, gcInfo.gcTrkStkPtrLcls, varDsc->lvVarIndex))
- {
-#ifdef DEBUG
- if (!VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex))
- {
- JITDUMP("\t\t\t\t\t\t\tVar V%02u becoming live\n", varNum);
- }
- else
- {
- JITDUMP("\t\t\t\t\t\t\tVar V%02u continuing live\n", varNum);
- }
-#endif
- VarSetOps::AddElemD(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex);
- }
- }
-
- tree->gtFlags &= ~GTF_SPILL;
- varDsc->lvRegNum = REG_STK;
- if (varTypeIsMultiReg(tree))
- {
- varDsc->lvOtherReg = REG_STK;
- }
-}
-
-// inline
-void CodeGenInterface::genUpdateVarReg(LclVarDsc* varDsc, GenTreePtr tree)
-{
- assert(tree->OperIsScalarLocal() || (tree->gtOper == GT_COPY));
- varDsc->lvRegNum = tree->gtRegNum;
-}
-
/*****************************************************************************
*
* Generate code that will set the given register to the integer constant.
@@ -157,735 +61,22 @@ void CodeGen::genSetRegToIcon(regNumber reg, ssize_t val, var_types type, insFla
*/
void CodeGen::genEmitGSCookieCheck(bool pushReg)
{
- NYI("ARM genEmitGSCookieCheck is not yet implemented for protojit");
+ NYI("ARM genEmitGSCookieCheck");
}
-/*****************************************************************************
- *
- * Generate code for all the basic blocks in the function.
- */
-
-void CodeGen::genCodeForBBlist()
+BasicBlock* CodeGen::genCallFinally(BasicBlock* block, BasicBlock* lblk)
{
- unsigned varNum;
- LclVarDsc* varDsc;
-
- unsigned savedStkLvl;
-
-#ifdef DEBUG
- genInterruptibleUsed = true;
-
- // You have to be careful if you create basic blocks from now on
- compiler->fgSafeBasicBlockCreation = false;
-
- // This stress mode is not comptible with fully interruptible GC
- if (genInterruptible && compiler->opts.compStackCheckOnCall)
- {
- compiler->opts.compStackCheckOnCall = false;
- }
-
- // This stress mode is not comptible with fully interruptible GC
- if (genInterruptible && compiler->opts.compStackCheckOnRet)
- {
- compiler->opts.compStackCheckOnRet = false;
- }
-#endif
-
- // Prepare the blocks for exception handling codegen: mark the blocks that needs labels.
- genPrepForEHCodegen();
-
- assert(!compiler->fgFirstBBScratch ||
- compiler->fgFirstBB == compiler->fgFirstBBScratch); // compiler->fgFirstBBScratch has to be first.
-
- /* Initialize the spill tracking logic */
-
- regSet.rsSpillBeg();
-
-#ifdef DEBUGGING_SUPPORT
- /* Initialize the line# tracking logic */
-
- if (compiler->opts.compScopeInfo)
- {
- siInit();
- }
-#endif
-
- if (compiler->opts.compDbgEnC)
- {
- noway_assert(isFramePointerUsed());
- regSet.rsSetRegsModified(RBM_INT_CALLEE_SAVED & ~RBM_FPBASE);
- }
-
- /* If we have any pinvoke calls, we might potentially trash everything */
- if (compiler->info.compCallUnmanaged)
- {
- noway_assert(isFramePointerUsed()); // Setup of Pinvoke frame currently requires an EBP style frame
- regSet.rsSetRegsModified(RBM_INT_CALLEE_SAVED & ~RBM_FPBASE);
- }
-
- genPendingCallLabel = nullptr;
-
- /* Initialize the pointer tracking code */
-
- gcInfo.gcRegPtrSetInit();
- gcInfo.gcVarPtrSetInit();
-
- /* If any arguments live in registers, mark those regs as such */
-
- for (varNum = 0, varDsc = compiler->lvaTable; varNum < compiler->lvaCount; varNum++, varDsc++)
- {
- /* Is this variable a parameter assigned to a register? */
-
- if (!varDsc->lvIsParam || !varDsc->lvRegister)
- continue;
-
- /* Is the argument live on entry to the method? */
-
- if (!VarSetOps::IsMember(compiler, compiler->fgFirstBB->bbLiveIn, varDsc->lvVarIndex))
- continue;
-
- /* Is this a floating-point argument? */
-
- if (varDsc->IsFloatRegType())
- continue;
-
- noway_assert(!varTypeIsFloating(varDsc->TypeGet()));
-
- /* Mark the register as holding the variable */
-
- regTracker.rsTrackRegLclVar(varDsc->lvRegNum, varNum);
- }
-
- unsigned finallyNesting = 0;
-
- // Make sure a set is allocated for compiler->compCurLife (in the long case), so we can set it to empty without
- // allocation at the start of each basic block.
- VarSetOps::AssignNoCopy(compiler, compiler->compCurLife, VarSetOps::MakeEmpty(compiler));
-
- /*-------------------------------------------------------------------------
- *
- * Walk the basic blocks and generate code for each one
- *
- */
-
- BasicBlock* block;
- BasicBlock* lblk; /* previous block */
-
- for (lblk = NULL, block = compiler->fgFirstBB; block != NULL; lblk = block, block = block->bbNext)
- {
-#ifdef DEBUG
- if (compiler->verbose)
- {
- printf("\n=============== Generating ");
- block->dspBlockHeader(compiler, true, true);
- compiler->fgDispBBLiveness(block);
- }
-#endif // DEBUG
-
- /* Figure out which registers hold variables on entry to this block */
-
- regSet.ClearMaskVars();
- gcInfo.gcRegGCrefSetCur = RBM_NONE;
- gcInfo.gcRegByrefSetCur = RBM_NONE;
-
- compiler->m_pLinearScan->recordVarLocationsAtStartOfBB(block);
-
- genUpdateLife(block->bbLiveIn);
-
- // Even if liveness didn't change, we need to update the registers containing GC references.
- // genUpdateLife will update the registers live due to liveness changes. But what about registers that didn't
- // change? We cleared them out above. Maybe we should just not clear them out, but update the ones that change
- // here. That would require handling the changes in recordVarLocationsAtStartOfBB().
-
- regMaskTP newLiveRegSet = RBM_NONE;
- regMaskTP newRegGCrefSet = RBM_NONE;
- regMaskTP newRegByrefSet = RBM_NONE;
- VARSET_ITER_INIT(compiler, iter, block->bbLiveIn, varIndex);
- while (iter.NextElem(compiler, &varIndex))
- {
- unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
- LclVarDsc* varDsc = &(compiler->lvaTable[varNum]);
-
- if (varDsc->lvIsInReg())
- {
- newLiveRegSet |= varDsc->lvRegMask();
- if (varDsc->lvType == TYP_REF)
- {
- newRegGCrefSet |= varDsc->lvRegMask();
- }
- else if (varDsc->lvType == TYP_BYREF)
- {
- newRegByrefSet |= varDsc->lvRegMask();
- }
- }
- else if (varDsc->lvType == TYP_REF || varDsc->lvType == TYP_BYREF)
- {
- VarSetOps::AddElemD(compiler, gcInfo.gcVarPtrSetCur, varIndex);
- }
- }
-
- regSet.rsMaskVars = newLiveRegSet;
- gcInfo.gcMarkRegSetGCref(newRegGCrefSet DEBUGARG(true));
- gcInfo.gcMarkRegSetByref(newRegByrefSet DEBUGARG(true));
-
- /* Blocks with handlerGetsXcptnObj()==true use GT_CATCH_ARG to
- represent the exception object (TYP_REF).
- We mark REG_EXCEPTION_OBJECT as holding a GC object on entry
- to the block, it will be the first thing evaluated
- (thanks to GTF_ORDER_SIDEEFF).
- */
-
- if (handlerGetsXcptnObj(block->bbCatchTyp))
- {
- for (GenTree* node : LIR::AsRange(block))
- {
- if (node->OperGet() == GT_CATCH_ARG)
- {
- gcInfo.gcMarkRegSetGCref(RBM_EXCEPTION_OBJECT);
- break;
- }
- }
- }
-
- /* Start a new code output block */
- CLANG_FORMAT_COMMENT_ANCHOR;
-
-#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);
- }
-#endif // defined(_TARGET_ARM_)
-
- genUpdateCurrentFunclet(block);
-#endif // FEATURE_EH_FUNCLETS
-
-#ifdef _TARGET_XARCH_
- if (genAlignLoops && block->bbFlags & BBF_LOOP_HEAD)
- {
- getEmitter()->emitLoopAlign();
- }
-#endif
-
-#ifdef DEBUG
- if (compiler->opts.dspCode)
- printf("\n L_M%03u_BB%02u:\n", Compiler::s_compMethodsCount, block->bbNum);
-#endif
-
- block->bbEmitCookie = NULL;
-
- if (block->bbFlags & (BBF_JMP_TARGET | BBF_HAS_LABEL))
- {
- /* Mark a label and update the current set of live GC refs */
-
- block->bbEmitCookie =
- getEmitter()->emitAddLabel(gcInfo.gcVarPtrSetCur, gcInfo.gcRegGCrefSetCur, gcInfo.gcRegByrefSetCur,
- /*isFinally*/ block->bbFlags & BBF_FINALLY_TARGET);
- }
-
- if (block == compiler->fgFirstColdBlock)
- {
-#ifdef DEBUG
- if (compiler->verbose)
- {
- printf("\nThis is the start of the cold region of the method\n");
- }
-#endif
- // We should never have a block that falls through into the Cold section
- noway_assert(!lblk->bbFallsThrough());
-
- // We require the block that starts the Cold section to have a label
- noway_assert(block->bbEmitCookie);
- getEmitter()->emitSetFirstColdIGCookie(block->bbEmitCookie);
- }
-
- /* Both stacks are always empty on entry to a basic block */
-
- genStackLevel = 0;
-
-#if !FEATURE_FIXED_OUT_ARGS
- /* Check for inserted throw blocks and adjust genStackLevel */
-
- if (!isFramePointerUsed() && compiler->fgIsThrowHlpBlk(block))
- {
- noway_assert(block->bbFlags & BBF_JMP_TARGET);
-
- genStackLevel = compiler->fgThrowHlpBlkStkLevel(block) * sizeof(int);
-
- if (genStackLevel)
- {
- NYI("Need emitMarkStackLvl()");
- }
- }
-#endif // !FEATURE_FIXED_OUT_ARGS
-
- savedStkLvl = genStackLevel;
-
- /* Tell everyone which basic block we're working on */
-
- compiler->compCurBB = block;
-
-#ifdef DEBUGGING_SUPPORT
- siBeginBlock(block);
-
- // BBF_INTERNAL blocks don't correspond to any single IL instruction.
- if (compiler->opts.compDbgInfo && (block->bbFlags & BBF_INTERNAL) && block != compiler->fgFirstBB)
- genIPmappingAdd((IL_OFFSETX)ICorDebugInfo::NO_MAPPING, true);
-
- bool firstMapping = true;
-#endif // DEBUGGING_SUPPORT
-
- /*---------------------------------------------------------------------
- *
- * Generate code for each statement-tree in the block
- *
- */
- CLANG_FORMAT_COMMENT_ANCHOR;
-
-#if FEATURE_EH_FUNCLETS
- if (block->bbFlags & BBF_FUNCLET_BEG)
- {
- genReserveFuncletProlog(block);
- }
-#endif // FEATURE_EH_FUNCLETS
-
- // Clear compCurStmt and compCurLifeTree.
- compiler->compCurStmt = nullptr;
- compiler->compCurLifeTree = nullptr;
-
-#ifdef DEBUG
- bool pastProfileUpdate = false;
-#endif
-
-// Traverse the block in linear order, generating code for each node as we
-// as we encounter it.
-#ifdef DEBUGGING_SUPPORT
- IL_OFFSETX currentILOffset = BAD_IL_OFFSET;
-#endif
- for (GenTree* node : LIR::AsRange(block))
- {
-#ifdef DEBUGGING_SUPPORT
- // Do we have a new IL offset?
- if (node->OperGet() == GT_IL_OFFSET)
- {
- genEnsureCodeEmitted(currentILOffset);
-
- currentILOffset = node->gtStmt.gtStmtILoffsx;
-
- genIPmappingAdd(currentILOffset, firstMapping);
- firstMapping = false;
- }
-#endif // DEBUGGING_SUPPORT
-
-#ifdef DEBUG
- if (node->OperGet() == GT_IL_OFFSET)
- {
- noway_assert(node->gtStmt.gtStmtLastILoffs <= compiler->info.compILCodeSize ||
- node->gtStmt.gtStmtLastILoffs == BAD_IL_OFFSET);
-
- if (compiler->opts.dspCode && compiler->opts.dspInstrs &&
- node->gtStmt.gtStmtLastILoffs != BAD_IL_OFFSET)
- {
- while (genCurDispOffset <= node->gtStmt.gtStmtLastILoffs)
- {
- genCurDispOffset += dumpSingleInstr(compiler->info.compCode, genCurDispOffset, "> ");
- }
- }
- }
-#endif // DEBUG
-
- genCodeForTreeNode(node);
- if (node->gtHasReg() && node->gtLsraInfo.isLocalDefUse)
- {
- genConsumeReg(node);
- }
-
-#ifdef DEBUG
- regSet.rsSpillChk();
-
- assert((node->gtFlags & GTF_SPILL) == 0);
-
- /* Make sure we didn't bungle pointer register tracking */
-
- regMaskTP ptrRegs = (gcInfo.gcRegGCrefSetCur | gcInfo.gcRegByrefSetCur);
- regMaskTP nonVarPtrRegs = ptrRegs & ~regSet.rsMaskVars;
-
- // If return is a GC-type, clear it. Note that if a common
- // epilog is generated (genReturnBB) it has a void return
- // even though we might return a ref. We can't use the compRetType
- // as the determiner because something we are tracking as a byref
- // might be used as a return value of a int function (which is legal)
- if (node->gtOper == GT_RETURN && (varTypeIsGC(compiler->info.compRetType) ||
- (node->gtOp.gtOp1 != 0 && varTypeIsGC(node->gtOp.gtOp1->TypeGet()))))
- {
- nonVarPtrRegs &= ~RBM_INTRET;
- }
-
- // When profiling, the first few nodes in a catch block will be an update of
- // the profile count (does not interfere with the exception object).
- if (((compiler->opts.eeFlags & CORJIT_FLG_BBINSTR) != 0) && handlerGetsXcptnObj(block->bbCatchTyp))
- {
- pastProfileUpdate = pastProfileUpdate || node->OperGet() == GT_CATCH_ARG;
- if (!pastProfileUpdate)
- {
- nonVarPtrRegs &= ~RBM_EXCEPTION_OBJECT;
- }
- }
-
- if (nonVarPtrRegs)
- {
- printf("Regset after node=");
- Compiler::printTreeID(node);
- printf(" BB%02u gcr=", block->bbNum);
- printRegMaskInt(gcInfo.gcRegGCrefSetCur & ~regSet.rsMaskVars);
- compiler->getEmitter()->emitDispRegSet(gcInfo.gcRegGCrefSetCur & ~regSet.rsMaskVars);
- printf(", byr=");
- printRegMaskInt(gcInfo.gcRegByrefSetCur & ~regSet.rsMaskVars);
- compiler->getEmitter()->emitDispRegSet(gcInfo.gcRegByrefSetCur & ~regSet.rsMaskVars);
- printf(", regVars=");
- printRegMaskInt(regSet.rsMaskVars);
- compiler->getEmitter()->emitDispRegSet(regSet.rsMaskVars);
- printf("\n");
- }
-
- noway_assert(nonVarPtrRegs == 0);
-#endif // DEBUG
- }
-
-#ifdef DEBUGGING_SUPPORT
- // It is possible to reach the end of the block without generating code for the current IL offset.
- // For example, if the following IR ends the current block, no code will have been generated for
- // offset 21:
- //
- // ( 0, 0) [000040] ------------ il_offset void IL offset: 21
- //
- // N001 ( 0, 0) [000039] ------------ nop void
- //
- // This can lead to problems when debugging the generated code. To prevent these issues, make sure
- // we've generated code for the last IL offset we saw in the block.
- genEnsureCodeEmitted(currentILOffset);
-
- if (compiler->opts.compScopeInfo && (compiler->info.compVarScopesCount > 0))
- {
- siEndBlock(block);
-
- /* Is this the last block, and are there any open scopes left ? */
-
- bool isLastBlockProcessed = (block->bbNext == NULL);
- if (block->isBBCallAlwaysPair())
- {
- isLastBlockProcessed = (block->bbNext->bbNext == NULL);
- }
-
- if (isLastBlockProcessed && siOpenScopeList.scNext)
- {
- /* This assert no longer holds, because we may insert a throw
- block to demarcate the end of a try or finally region when they
- are at the end of the method. It would be nice if we could fix
- our code so that this throw block will no longer be necessary. */
-
- // noway_assert(block->bbCodeOffsEnd != compiler->info.compILCodeSize);
-
- siCloseAllOpenScopes();
- }
- }
-
-#endif // DEBUGGING_SUPPORT
-
- genStackLevel -= savedStkLvl;
-
-#ifdef DEBUG
- // compCurLife should be equal to the liveOut set, except that we don't keep
- // it up to date for vars that are not register candidates
- // (it would be nice to have a xor set function)
-
- VARSET_TP VARSET_INIT_NOCOPY(extraLiveVars, VarSetOps::Diff(compiler, block->bbLiveOut, compiler->compCurLife));
- VarSetOps::UnionD(compiler, extraLiveVars, VarSetOps::Diff(compiler, compiler->compCurLife, block->bbLiveOut));
- VARSET_ITER_INIT(compiler, extraLiveVarIter, extraLiveVars, extraLiveVarIndex);
- while (extraLiveVarIter.NextElem(compiler, &extraLiveVarIndex))
- {
- unsigned varNum = compiler->lvaTrackedToVarNum[extraLiveVarIndex];
- LclVarDsc* varDsc = compiler->lvaTable + varNum;
- assert(!varDsc->lvIsRegCandidate());
- }
-#endif
-
- /* Both stacks should always be empty on exit from a basic block */
-
- noway_assert(genStackLevel == 0);
-
-#ifdef _TARGET_AMD64_
- // On AMD64, we need to generate a NOP after a call that is the last instruction of the block, in several
- // situations, to support proper exception handling semantics. This is mostly to ensure that when the stack
- // walker computes an instruction pointer for a frame, that instruction pointer is in the correct EH region.
- // The document "X64 and ARM ABIs.docx" has more details. The situations:
- // 1. If the call instruction is in a different EH region as the instruction that follows it.
- // 2. If the call immediately precedes an OS epilog. (Note that what the JIT or VM consider an epilog might
- // be slightly different from what the OS considers an epilog, and it is the OS-reported epilog that matters
- // here.)
- // We handle case #1 here, and case #2 in the emitter.
- if (getEmitter()->emitIsLastInsCall())
- {
- // Ok, the last instruction generated is a call instruction. Do any of the other conditions hold?
- // Note: we may be generating a few too many NOPs for the case of call preceding an epilog. Technically,
- // if the next block is a BBJ_RETURN, an epilog will be generated, but there may be some instructions
- // generated before the OS epilog starts, such as a GS cookie check.
- if ((block->bbNext == nullptr) || !BasicBlock::sameEHRegion(block, block->bbNext))
- {
- // We only need the NOP if we're not going to generate any more code as part of the block end.
-
- switch (block->bbJumpKind)
- {
- case BBJ_ALWAYS:
- case BBJ_THROW:
- case BBJ_CALLFINALLY:
- case BBJ_EHCATCHRET:
- // We're going to generate more code below anyway, so no need for the NOP.
-
- case BBJ_RETURN:
- case BBJ_EHFINALLYRET:
- case BBJ_EHFILTERRET:
- // These are the "epilog follows" case, handled in the emitter.
-
- break;
-
- case BBJ_NONE:
- if (block->bbNext == nullptr)
- {
- // Call immediately before the end of the code; we should never get here .
- instGen(INS_BREAKPOINT); // This should never get executed
- }
- else
- {
- // We need the NOP
- instGen(INS_nop);
- }
- break;
-
- case BBJ_COND:
- case BBJ_SWITCH:
- // These can't have a call as the last instruction!
-
- default:
- noway_assert(!"Unexpected bbJumpKind");
- break;
- }
- }
- }
-#endif //_TARGET_AMD64_
-
- /* Do we need to generate a jump or return? */
-
- switch (block->bbJumpKind)
- {
- case BBJ_ALWAYS:
- inst_JMP(EJ_jmp, block->bbJumpDest);
- break;
-
- case BBJ_RETURN:
- genExitCode(block);
- break;
-
- case BBJ_THROW:
- // If we have a throw at the end of a function or funclet, we need to emit another instruction
- // afterwards to help the OS unwinder determine the correct context during unwind.
- // We insert an unexecuted breakpoint instruction in several situations
- // following a throw instruction:
- // 1. If the throw is the last instruction of the function or funclet. This helps
- // the OS unwinder determine the correct context during an unwind from the
- // thrown exception.
- // 2. If this is this is the last block of the hot section.
- // 3. If the subsequent block is a special throw block.
- // 4. On AMD64, if the next block is in a different EH region.
- if ((block->bbNext == NULL)
-#if FEATURE_EH_FUNCLETS
- || (block->bbNext->bbFlags & BBF_FUNCLET_BEG)
-#endif // FEATURE_EH_FUNCLETS
-#ifdef _TARGET_AMD64_
- || !BasicBlock::sameEHRegion(block, block->bbNext)
-#endif // _TARGET_AMD64_
- || (!isFramePointerUsed() && compiler->fgIsThrowHlpBlk(block->bbNext)) ||
- block->bbNext == compiler->fgFirstColdBlock)
- {
- instGen(INS_BREAKPOINT); // This should never get executed
- }
-
- break;
-
- case BBJ_CALLFINALLY:
-
- // Now set REG_LR to the address of where the finally funclet should
- // return to directly.
-
- BasicBlock* bbFinallyRet;
- bbFinallyRet = NULL;
-
- // 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;
-
-#if 0
- // TODO-ARM-CQ:
- // We don't know the address of finally funclet yet. But adr requires the offset
- // to finally funclet from current IP is within 4095 bytes. So this code is disabled
- // for now.
- getEmitter()->emitIns_J_R (INS_adr,
- EA_4BYTE,
- bbFinallyRet,
- REG_LR);
-#else // !0
- // 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);
-#endif // !0
-
- // 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.
- if (!(block->bbFlags & BBF_RETLESS_CALL))
- {
- assert(block->isBBCallAlwaysPair());
-
- lblk = block;
- block = block->bbNext;
- }
- break;
-
-#ifdef _TARGET_ARM_
-
- case BBJ_EHCATCHRET:
- // set r0 to the address the VM should return to after the catch
- getEmitter()->emitIns_R_L(INS_movw, EA_4BYTE_DSP_RELOC, block->bbJumpDest, REG_R0);
- getEmitter()->emitIns_R_L(INS_movt, EA_4BYTE_DSP_RELOC, block->bbJumpDest, REG_R0);
-
- __fallthrough;
-
- case BBJ_EHFINALLYRET:
- case BBJ_EHFILTERRET:
- genReserveFuncletEpilog(block);
- break;
-
-#elif defined(_TARGET_AMD64_)
-
- case BBJ_EHCATCHRET:
- // Set EAX to the address the VM should return to after the catch.
- // Generate a RIP-relative
- // lea reg, [rip + disp32] ; the RIP is implicit
- // which will be position-indepenent.
- // TODO-ARM-Bug?: For ngen, we need to generate a reloc for the displacement (maybe EA_PTR_DSP_RELOC).
- getEmitter()->emitIns_R_L(INS_lea, EA_PTRSIZE, block->bbJumpDest, REG_INTRET);
- __fallthrough;
-
- case BBJ_EHFINALLYRET:
- case BBJ_EHFILTERRET:
- genReserveFuncletEpilog(block);
- break;
-
-#endif // _TARGET_AMD64_
-
- case BBJ_NONE:
- case BBJ_COND:
- case BBJ_SWITCH:
- break;
-
- default:
- noway_assert(!"Unexpected bbJumpKind");
- break;
- }
-
-#ifdef DEBUG
- compiler->compCurBB = 0;
-#endif
-
- } //------------------ END-FOR each block of the method -------------------
-
- /* Nothing is live at this point */
- genUpdateLife(VarSetOps::MakeEmpty(compiler));
-
- /* Finalize the spill tracking logic */
-
- regSet.rsSpillEnd();
-
- /* Finalize the temp tracking logic */
-
- compiler->tmpEnd();
-
-#ifdef DEBUG
- if (compiler->verbose)
- {
- printf("\n# ");
- printf("compCycleEstimate = %6d, compSizeEstimate = %5d ", compiler->compCycleEstimate, compiler->compSizeEstimate);
- printf("%s\n", compiler->info.compFullName);
- }
-#endif
+ NYI("ARM genCallFinally");
+ return block;
}
-// return the child that has the same reg as the dst (if any)
-// other child returned (out param) in 'other'
-GenTree* sameRegAsDst(GenTree* tree, GenTree*& other /*out*/)
-{
- if (tree->gtRegNum == REG_NA)
- {
- other = nullptr;
- return NULL;
- }
+// move an immediate value into an integer register
- GenTreePtr op1 = tree->gtOp.gtOp1->gtEffectiveVal();
- GenTreePtr op2 = tree->gtOp.gtOp2->gtEffectiveVal();
- if (op1->gtRegNum == tree->gtRegNum)
- {
- other = op2;
- return op1;
- }
- if (op2->gtRegNum == tree->gtRegNum)
- {
- other = op1;
- return op2;
- }
- else
- {
- other = nullptr;
- return NULL;
- }
+void CodeGen::genEHCatchRet(BasicBlock* block)
+{
+ NYI("ARM genEHCatchRet");
}
-// move an immediate value into an integer register
-
void CodeGen::instGen_Set_Reg_To_Imm(emitAttr size, regNumber reg, ssize_t imm, insFlags flags)
{
// reg cannot be a FP register
@@ -902,16 +93,7 @@ void CodeGen::instGen_Set_Reg_To_Imm(emitAttr size, regNumber reg, ssize_t imm,
}
else
{
-#ifdef _TARGET_AMD64_
- if (AddrShouldUsePCRel(imm))
- {
- getEmitter()->emitIns_R_AI(INS_lea, EA_PTR_DSP_RELOC, reg, imm);
- }
- else
-#endif // _TARGET_AMD64_
- {
- getEmitter()->emitIns_R_I(INS_mov, size, reg, imm);
- }
+ getEmitter()->emitIns_R_I(INS_mov, size, reg, imm);
}
regTracker.rsTrackRegIntCns(reg, imm);
}
@@ -1423,6 +605,7 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
break;
case GT_LIST:
+ case GT_FIELD_LIST:
case GT_ARGPLACE:
// Nothing to do
break;
@@ -1479,7 +662,7 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
case GT_LOCKADD:
case GT_XCHG:
case GT_XADD:
- genLockedInstructions(treeNode);
+ genLockedInstructions(treeNode->AsOp());
break;
case GT_CMPXCHG:
@@ -1554,7 +737,8 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
{
#ifdef DEBUG
char message[256];
- sprintf(message, "NYI: Unimplemented node type %s\n", GenTree::NodeName(treeNode->OperGet()));
+ _snprintf_s(message, _countof(message), _TRUNCATE, "NYI: Unimplemented node type %s\n",
+ GenTree::NodeName(treeNode->OperGet()));
notYetImplemented(message, __FILE__, __LINE__);
#else
NYI("unimplemented node");
@@ -1566,7 +750,7 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
// generate code for the locked operations:
// GT_LOCKADD, GT_XCHG, GT_XADD
-void CodeGen::genLockedInstructions(GenTree* treeNode)
+void CodeGen::genLockedInstructions(GenTreeOp* treeNode)
{
NYI("genLockedInstructions");
}
@@ -1697,188 +881,9 @@ void CodeGen::genCodeForShift(GenTreePtr tree)
NYI("genCodeForShift");
}
-void CodeGen::genUnspillRegIfNeeded(GenTree* tree)
-{
- regNumber dstReg = tree->gtRegNum;
-
- GenTree* unspillTree = tree;
- if (tree->gtOper == GT_RELOAD)
- {
- unspillTree = tree->gtOp.gtOp1;
- }
- if (unspillTree->gtFlags & GTF_SPILLED)
- {
- if (genIsRegCandidateLocal(unspillTree))
- {
- // Reset spilled flag, since we are going to load a local variable from its home location.
- unspillTree->gtFlags &= ~GTF_SPILLED;
-
- // Load local variable from its home location.
- inst_RV_TT(ins_Load(unspillTree->gtType), dstReg, unspillTree);
-
- unspillTree->SetInReg();
-
- GenTreeLclVarCommon* lcl = unspillTree->AsLclVarCommon();
- LclVarDsc* varDsc = &compiler->lvaTable[lcl->gtLclNum];
-
- // TODO-Review: We would like to call:
- // genUpdateRegLife(varDsc, /*isBorn*/ true, /*isDying*/ false DEBUGARG(tree));
- // instead of the following code, but this ends up hitting this assert:
- // assert((regSet.rsMaskVars & regMask) == 0);
- // due to issues with LSRA resolution moves.
- // So, just force it for now. This probably indicates a condition that creates a GC hole!
- //
- // Extra note: I think we really want to call something like gcInfo.gcUpdateForRegVarMove,
- // because the variable is not really going live or dead, but that method is somewhat poorly
- // factored because it, in turn, updates rsMaskVars which is part of RegSet not GCInfo.
- // TODO-Cleanup: This code exists in other CodeGen*.cpp files, and should be moved to CodeGenCommon.cpp.
-
- genUpdateVarReg(varDsc, tree);
-#ifdef DEBUG
- if (VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex))
- {
- JITDUMP("\t\t\t\t\t\t\tRemoving V%02u from gcVarPtrSetCur\n", lcl->gtLclNum);
- }
-#endif // DEBUG
- VarSetOps::RemoveElemD(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex);
-
-#ifdef DEBUG
- if (compiler->verbose)
- {
- printf("\t\t\t\t\t\t\tV%02u in reg ", lcl->gtLclNum);
- varDsc->PrintVarReg();
- printf(" is becoming live ");
- Compiler::printTreeID(unspillTree);
- printf("\n");
- }
-#endif // DEBUG
-
- regSet.AddMaskVars(genGetRegMask(varDsc));
- }
- else
- {
- TempDsc* t = regSet.rsUnspillInPlace(unspillTree, unspillTree->gtRegNum);
- compiler->tmpRlsTemp(t);
- getEmitter()->emitIns_R_S(ins_Load(unspillTree->gtType), emitActualTypeSize(unspillTree->gtType), dstReg,
- t->tdTempNum(), 0);
-
- unspillTree->SetInReg();
- }
-
- gcInfo.gcMarkRegPtrVal(dstReg, unspillTree->TypeGet());
- }
-}
-
-// do liveness update for a subnode that is being consumed by codegen
-regNumber CodeGen::genConsumeReg(GenTree* tree)
-{
- genUnspillRegIfNeeded(tree);
-
- // genUpdateLife() will also spill local var if marked as GTF_SPILL by calling CodeGen::genSpillVar
- genUpdateLife(tree);
- assert(tree->gtRegNum != REG_NA);
-
- // there are three cases where consuming a reg means clearing the bit in the live mask
- // 1. it was not produced by a local
- // 2. it was produced by a local that is going dead
- // 3. it was produced by a local that does not live in that reg (like one allocated on the stack)
-
- if (genIsRegCandidateLocal(tree))
- {
- GenTreeLclVarCommon* lcl = tree->AsLclVarCommon();
- LclVarDsc* varDsc = &compiler->lvaTable[lcl->GetLclNum()];
-
- if (varDsc->lvRegNum == tree->gtRegNum && ((tree->gtFlags & GTF_VAR_DEATH) != 0))
- {
- gcInfo.gcMarkRegSetNpt(genRegMask(tree->gtRegNum));
- }
- else if (!varDsc->lvLRACandidate)
- {
- gcInfo.gcMarkRegSetNpt(genRegMask(tree->gtRegNum));
- }
- }
- else
- {
- gcInfo.gcMarkRegSetNpt(genRegMask(tree->gtRegNum));
- }
-
- return tree->gtRegNum;
-}
-
-// Do liveness update for an address tree: one of GT_LEA, GT_LCL_VAR, or GT_CNS_INT (for call indirect).
-void CodeGen::genConsumeAddress(GenTree* addr)
-{
- if (addr->OperGet() == GT_LEA)
- {
- genConsumeAddrMode(addr->AsAddrMode());
- }
- else
- {
- assert(!addr->isContained());
- genConsumeReg(addr);
- }
-}
-
-// do liveness update for a subnode that is being consumed by codegen
-void CodeGen::genConsumeAddrMode(GenTreeAddrMode* addr)
+void CodeGen::genRegCopy(GenTree* treeNode)
{
- if (addr->Base())
- genConsumeReg(addr->Base());
- if (addr->Index())
- genConsumeReg(addr->Index());
-}
-
-// do liveness update for register produced by the current node in codegen
-void CodeGen::genProduceReg(GenTree* tree)
-{
- if (tree->gtFlags & GTF_SPILL)
- {
- if (genIsRegCandidateLocal(tree))
- {
- // Store local variable to its home location.
- tree->gtFlags &= ~GTF_REG_VAL;
- inst_TT_RV(ins_Store(tree->gtType), tree, tree->gtRegNum);
- }
- else
- {
- tree->SetInReg();
- regSet.rsSpillTree(tree->gtRegNum, tree);
- tree->gtFlags |= GTF_SPILLED;
- tree->gtFlags &= ~GTF_SPILL;
- gcInfo.gcMarkRegSetNpt(genRegMask(tree->gtRegNum));
- return;
- }
- }
-
- genUpdateLife(tree);
-
- // If we've produced a register, mark it as a pointer, as needed.
- // Except in the case of a dead definition of a lclVar.
- if (tree->gtHasReg() && (!tree->IsLocal() || (tree->gtFlags & GTF_VAR_DEATH) == 0))
- {
- gcInfo.gcMarkRegPtrVal(tree->gtRegNum, tree->TypeGet());
- }
- tree->SetInReg();
-}
-
-// transfer gc/byref status of src reg to dst reg
-void CodeGen::genTransferRegGCState(regNumber dst, regNumber src)
-{
- regMaskTP srcMask = genRegMask(src);
- regMaskTP dstMask = genRegMask(dst);
-
- if (gcInfo.gcRegGCrefSetCur & srcMask)
- {
- gcInfo.gcMarkRegSetGCref(dstMask);
- }
- else if (gcInfo.gcRegByrefSetCur & srcMask)
- {
- gcInfo.gcMarkRegSetByref(dstMask);
- }
- else
- {
- gcInfo.gcMarkRegSetNpt(dstMask);
- }
+ NYI("genRegCopy");
}
// Produce code for a GT_CALL node
@@ -2050,57 +1055,6 @@ void CodeGen::genEmitHelperCall(unsigned helper,
NYI("Helper call");
}
-/*****************************************************************************/
-#ifdef DEBUGGING_SUPPORT
-/*****************************************************************************
- * genSetScopeInfo
- *
- * Called for every scope info piece to record by the main genSetScopeInfo()
- */
-
-void CodeGen::genSetScopeInfo(unsigned which,
- UNATIVE_OFFSET startOffs,
- UNATIVE_OFFSET length,
- unsigned varNum,
- unsigned LVnum,
- bool avail,
- Compiler::siVarLoc& varLoc)
-{
- /* We need to do some mapping while reporting back these variables */
-
- unsigned ilVarNum = compiler->compMap2ILvarNum(varNum);
- noway_assert((int)ilVarNum != ICorDebugInfo::UNKNOWN_ILNUM);
-
- VarName name = nullptr;
-
-#ifdef DEBUG
-
- for (unsigned scopeNum = 0; scopeNum < compiler->info.compVarScopesCount; scopeNum++)
- {
- if (LVnum == compiler->info.compVarScopes[scopeNum].vsdLVnum)
- {
- name = compiler->info.compVarScopes[scopeNum].vsdName;
- }
- }
-
- // Hang on to this compiler->info.
-
- TrnslLocalVarInfo& tlvi = genTrnslLocalVarInfo[which];
-
- tlvi.tlviVarNum = ilVarNum;
- tlvi.tlviLVnum = LVnum;
- tlvi.tlviName = name;
- tlvi.tlviStartPC = startOffs;
- tlvi.tlviLength = length;
- tlvi.tlviAvailable = avail;
- tlvi.tlviVarLoc = varLoc;
-
-#endif // DEBUG
-
- compiler->eeSetLVinfo(which, startOffs, length, ilVarNum, LVnum, name, avail, varLoc);
-}
-#endif // DEBUGGING_SUPPORT
-
#endif // _TARGET_ARM_
#endif // !LEGACY_BACKEND
diff --git a/src/jit/codegenarm64.cpp b/src/jit/codegenarm64.cpp
index ca0df53a34..cc7c5dc524 100644
--- a/src/jit/codegenarm64.cpp
+++ b/src/jit/codegenarm64.cpp
@@ -747,7 +747,7 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in
* +=======================+ <---- Caller's SP
* |Callee saved registers | // multiple of 8 bytes
* |-----------------------|
- * | PSP slot | // 8 bytes
+ * | PSP slot | // 8 bytes (omitted in CoreRT ABI)
* |-----------------------|
* ~ alignment padding ~ // To make the whole frame 16 byte aligned.
* |-----------------------|
@@ -773,7 +773,7 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in
* +=======================+ <---- Caller's SP
* |Callee saved registers | // multiple of 8 bytes
* |-----------------------|
- * | PSP slot | // 8 bytes
+ * | PSP slot | // 8 bytes (omitted in CoreRT ABI)
* |-----------------------|
* ~ alignment padding ~ // To make the whole frame 16 byte aligned.
* |-----------------------|
@@ -801,7 +801,7 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in
* +=======================+ <---- Caller's SP
* |Callee saved registers | // multiple of 8 bytes
* |-----------------------|
- * | PSP slot | // 8 bytes
+ * | PSP slot | // 8 bytes (omitted in CoreRT ABI)
* |-----------------------|
* ~ alignment padding ~ // To make the first SP subtraction 16 byte aligned
* |-----------------------|
@@ -883,7 +883,7 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in
* +=======================+ <---- Caller's SP
* |Callee saved registers | // multiple of 8 bytes
* |-----------------------|
- * | PSP slot | // 8 bytes
+ * | PSP slot | // 8 bytes (omitted in CoreRT ABI)
* |-----------------------|
* | Saved FP, LR | // 16 bytes
* |-----------------------|
@@ -988,6 +988,12 @@ void CodeGen::genFuncletProlog(BasicBlock* block)
// This is the end of the OS-reported prolog for purposes of unwinding
compiler->unwindEndProlog();
+ // If there is no PSPSym (CoreRT ABI), we are done.
+ if (compiler->lvaPSPSym == BAD_VAR_NUM)
+ {
+ return;
+ }
+
if (isFilter)
{
// This is the first block of a filter
@@ -1134,8 +1140,10 @@ void CodeGen::genCaptureFuncletPrologEpilogInfo()
assert((rsMaskSaveRegs & RBM_LR) != 0);
assert((rsMaskSaveRegs & RBM_FP) != 0);
+ unsigned PSPSize = (compiler->lvaPSPSym != BAD_VAR_NUM) ? REGSIZE_BYTES : 0;
+
unsigned saveRegsCount = genCountBits(rsMaskSaveRegs);
- unsigned saveRegsPlusPSPSize = saveRegsCount * REGSIZE_BYTES + /* PSPSym */ REGSIZE_BYTES;
+ unsigned saveRegsPlusPSPSize = saveRegsCount * REGSIZE_BYTES + PSPSize;
if (compiler->info.compIsVarArgs)
{
// For varargs we always save all of the integer register arguments
@@ -1222,22 +1230,29 @@ void CodeGen::genCaptureFuncletPrologEpilogInfo()
printf(" SP delta 1: %d\n", genFuncletInfo.fiSpDelta1);
printf(" SP delta 2: %d\n", genFuncletInfo.fiSpDelta2);
- if (CallerSP_to_PSP_slot_delta != compiler->lvaGetCallerSPRelativeOffset(compiler->lvaPSPSym)) // for debugging
+ if (compiler->lvaPSPSym != BAD_VAR_NUM)
{
- printf("lvaGetCallerSPRelativeOffset(lvaPSPSym): %d\n",
- compiler->lvaGetCallerSPRelativeOffset(compiler->lvaPSPSym));
+ if (CallerSP_to_PSP_slot_delta !=
+ compiler->lvaGetCallerSPRelativeOffset(compiler->lvaPSPSym)) // for debugging
+ {
+ printf("lvaGetCallerSPRelativeOffset(lvaPSPSym): %d\n",
+ compiler->lvaGetCallerSPRelativeOffset(compiler->lvaPSPSym));
+ }
}
}
-#endif // DEBUG
assert(genFuncletInfo.fiSP_to_FPLR_save_delta >= 0);
assert(genFuncletInfo.fiSP_to_PSP_slot_delta >= 0);
assert(genFuncletInfo.fiSP_to_CalleeSave_delta >= 0);
assert(genFuncletInfo.fiCallerSP_to_PSP_slot_delta <= 0);
- assert(compiler->lvaPSPSym != BAD_VAR_NUM);
- assert(genFuncletInfo.fiCallerSP_to_PSP_slot_delta ==
- compiler->lvaGetCallerSPRelativeOffset(compiler->lvaPSPSym)); // same offset used in main function and
- // funclet!
+
+ if (compiler->lvaPSPSym != BAD_VAR_NUM)
+ {
+ assert(genFuncletInfo.fiCallerSP_to_PSP_slot_delta ==
+ compiler->lvaGetCallerSPRelativeOffset(compiler->lvaPSPSym)); // same offset used in main function and
+ // funclet!
+ }
+#endif // DEBUG
}
/*
@@ -1250,100 +1265,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
*/
-// Get the register assigned to the given node
-
-regNumber CodeGenInterface::genGetAssignedReg(GenTreePtr tree)
-{
- return tree->gtRegNum;
-}
-
-//------------------------------------------------------------------------
-// genSpillVar: Spill a local variable
-//
-// Arguments:
-// tree - the lclVar node for the variable being spilled
-//
-// Return Value:
-// None.
-//
-// Assumptions:
-// The lclVar must be a register candidate (lvRegCandidate)
-
-void CodeGen::genSpillVar(GenTreePtr tree)
-{
- unsigned varNum = tree->gtLclVarCommon.gtLclNum;
- LclVarDsc* varDsc = &(compiler->lvaTable[varNum]);
-
- assert(varDsc->lvIsRegCandidate());
-
- // We don't actually need to spill if it is already living in memory
- bool needsSpill = ((tree->gtFlags & GTF_VAR_DEF) == 0 && varDsc->lvIsInReg());
- if (needsSpill)
- {
- var_types lclTyp = varDsc->TypeGet();
- if (varDsc->lvNormalizeOnStore())
- lclTyp = genActualType(lclTyp);
- emitAttr size = emitTypeSize(lclTyp);
-
- bool restoreRegVar = false;
- if (tree->gtOper == GT_REG_VAR)
- {
- tree->SetOper(GT_LCL_VAR);
- restoreRegVar = true;
- }
-
- // mask off the flag to generate the right spill code, then bring it back
- tree->gtFlags &= ~GTF_REG_VAL;
-
- instruction storeIns = ins_Store(tree->TypeGet(), compiler->isSIMDTypeLocalAligned(varNum));
-
- assert(varDsc->lvRegNum == tree->gtRegNum);
- inst_TT_RV(storeIns, tree, tree->gtRegNum, 0, size);
-
- tree->gtFlags |= GTF_REG_VAL;
-
- if (restoreRegVar)
- {
- tree->SetOper(GT_REG_VAR);
- }
-
- genUpdateRegLife(varDsc, /*isBorn*/ false, /*isDying*/ true DEBUGARG(tree));
- gcInfo.gcMarkRegSetNpt(varDsc->lvRegMask());
-
- if (VarSetOps::IsMember(compiler, gcInfo.gcTrkStkPtrLcls, varDsc->lvVarIndex))
- {
-#ifdef DEBUG
- if (!VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex))
- {
- JITDUMP("\t\t\t\t\t\t\tVar V%02u becoming live\n", varNum);
- }
- else
- {
- JITDUMP("\t\t\t\t\t\t\tVar V%02u continuing live\n", varNum);
- }
-#endif
- VarSetOps::AddElemD(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex);
- }
- }
-
- tree->gtFlags &= ~GTF_SPILL;
- varDsc->lvRegNum = REG_STK;
- if (varTypeIsMultiReg(tree))
- {
- varDsc->lvOtherReg = REG_STK;
- }
-}
-
-// inline
-void CodeGenInterface::genUpdateVarReg(LclVarDsc* varDsc, GenTreePtr tree)
-{
- assert(tree->OperIsScalarLocal() || (tree->gtOper == GT_COPY));
- varDsc->lvRegNum = tree->gtRegNum;
-}
-
-/*****************************************************************************/
-/*****************************************************************************/
-
/*****************************************************************************
*
* Generate code that will set the given register to the integer constant.
@@ -1405,702 +1326,79 @@ void CodeGen::genEmitGSCookieCheck(bool pushReg)
genDefineTempLabel(gsCheckBlk);
}
-/*****************************************************************************
- *
- * Generate code for all the basic blocks in the function.
- */
-
-void CodeGen::genCodeForBBlist()
+BasicBlock* CodeGen::genCallFinally(BasicBlock* block, BasicBlock* lblk)
{
- unsigned varNum;
- LclVarDsc* varDsc;
-
- unsigned savedStkLvl;
-
-#ifdef DEBUG
- genInterruptibleUsed = true;
-
- // You have to be careful if you create basic blocks from now on
- compiler->fgSafeBasicBlockCreation = false;
-
- // This stress mode is not comptible with fully interruptible GC
- if (genInterruptible && compiler->opts.compStackCheckOnCall)
- {
- compiler->opts.compStackCheckOnCall = false;
- }
-
- // This stress mode is not comptible with fully interruptible GC
- if (genInterruptible && compiler->opts.compStackCheckOnRet)
- {
- compiler->opts.compStackCheckOnRet = false;
- }
-#endif // DEBUG
-
- // Prepare the blocks for exception handling codegen: mark the blocks that needs labels.
- genPrepForEHCodegen();
-
- assert(!compiler->fgFirstBBScratch ||
- compiler->fgFirstBB == compiler->fgFirstBBScratch); // compiler->fgFirstBBScratch has to be first.
-
- /* Initialize the spill tracking logic */
-
- regSet.rsSpillBeg();
+ // Generate a call to the finally, like this:
+ // mov x0,qword ptr [fp + 10H] / sp // Load x0 with PSPSym, or sp if PSPSym is not used
+ // bl finally-funclet
+ // b finally-return // Only for non-retless finally calls
+ // The 'b' can be a NOP if we're going to the next block.
-#ifdef DEBUGGING_SUPPORT
- /* Initialize the line# tracking logic */
-
- if (compiler->opts.compScopeInfo)
- {
- siInit();
- }
-#endif
-
- // The current implementation of switch tables requires the first block to have a label so it
- // can generate offsets to the switch label targets.
- // TODO-ARM64-CQ: remove this when switches have been re-implemented to not use this.
- if (compiler->fgHasSwitch)
+ if (compiler->lvaPSPSym != BAD_VAR_NUM)
{
- compiler->fgFirstBB->bbFlags |= BBF_JMP_TARGET;
+ getEmitter()->emitIns_R_S(ins_Load(TYP_I_IMPL), EA_PTRSIZE, REG_R0, compiler->lvaPSPSym, 0);
}
-
- genPendingCallLabel = nullptr;
-
- /* Initialize the pointer tracking code */
-
- gcInfo.gcRegPtrSetInit();
- gcInfo.gcVarPtrSetInit();
-
- /* If any arguments live in registers, mark those regs as such */
-
- for (varNum = 0, varDsc = compiler->lvaTable; varNum < compiler->lvaCount; varNum++, varDsc++)
+ else
{
- /* Is this variable a parameter assigned to a register? */
-
- if (!varDsc->lvIsParam || !varDsc->lvRegister)
- continue;
-
- /* Is the argument live on entry to the method? */
-
- if (!VarSetOps::IsMember(compiler, compiler->fgFirstBB->bbLiveIn, varDsc->lvVarIndex))
- continue;
-
- /* Is this a floating-point argument? */
-
- if (varDsc->IsFloatRegType())
- continue;
-
- noway_assert(!varTypeIsFloating(varDsc->TypeGet()));
-
- /* Mark the register as holding the variable */
-
- regTracker.rsTrackRegLclVar(varDsc->lvRegNum, varNum);
+ getEmitter()->emitIns_R_R(INS_mov, EA_PTRSIZE, REG_R0, REG_SPBASE);
}
+ getEmitter()->emitIns_J(INS_bl_local, block->bbJumpDest);
- unsigned finallyNesting = 0;
-
- // Make sure a set is allocated for compiler->compCurLife (in the long case), so we can set it to empty without
- // allocation at the start of each basic block.
- VarSetOps::AssignNoCopy(compiler, compiler->compCurLife, VarSetOps::MakeEmpty(compiler));
-
- /*-------------------------------------------------------------------------
- *
- * Walk the basic blocks and generate code for each one
- *
- */
-
- BasicBlock* block;
- BasicBlock* lblk; /* previous block */
-
- for (lblk = NULL, block = compiler->fgFirstBB; block != NULL; lblk = block, block = block->bbNext)
+ if (block->bbFlags & BBF_RETLESS_CALL)
{
-#ifdef DEBUG
- if (compiler->verbose)
- {
- printf("\n=============== Generating ");
- block->dspBlockHeader(compiler, true, true);
- compiler->fgDispBBLiveness(block);
- }
-#endif // DEBUG
-
- /* Figure out which registers hold variables on entry to this block */
-
- regSet.ClearMaskVars();
- gcInfo.gcRegGCrefSetCur = RBM_NONE;
- gcInfo.gcRegByrefSetCur = RBM_NONE;
-
- compiler->m_pLinearScan->recordVarLocationsAtStartOfBB(block);
-
- genUpdateLife(block->bbLiveIn);
-
- // Even if liveness didn't change, we need to update the registers containing GC references.
- // genUpdateLife will update the registers live due to liveness changes. But what about registers that didn't
- // change? We cleared them out above. Maybe we should just not clear them out, but update the ones that change
- // here. That would require handling the changes in recordVarLocationsAtStartOfBB().
-
- regMaskTP newLiveRegSet = RBM_NONE;
- regMaskTP newRegGCrefSet = RBM_NONE;
- regMaskTP newRegByrefSet = RBM_NONE;
-#ifdef DEBUG
- VARSET_TP VARSET_INIT_NOCOPY(removedGCVars, VarSetOps::MakeEmpty(compiler));
- VARSET_TP VARSET_INIT_NOCOPY(addedGCVars, VarSetOps::MakeEmpty(compiler));
-#endif
- VARSET_ITER_INIT(compiler, iter, block->bbLiveIn, varIndex);
- while (iter.NextElem(compiler, &varIndex))
- {
- unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
- LclVarDsc* varDsc = &(compiler->lvaTable[varNum]);
-
- if (varDsc->lvIsInReg())
- {
- newLiveRegSet |= varDsc->lvRegMask();
- if (varDsc->lvType == TYP_REF)
- {
- newRegGCrefSet |= varDsc->lvRegMask();
- }
- else if (varDsc->lvType == TYP_BYREF)
- {
- newRegByrefSet |= varDsc->lvRegMask();
- }
-#ifdef DEBUG
- if (verbose && VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varIndex))
- {
- VarSetOps::AddElemD(compiler, removedGCVars, varIndex);
- }
-#endif // DEBUG
- VarSetOps::RemoveElemD(compiler, gcInfo.gcVarPtrSetCur, varIndex);
- }
- else if (compiler->lvaIsGCTracked(varDsc))
- {
-#ifdef DEBUG
- if (verbose && !VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varIndex))
- {
- VarSetOps::AddElemD(compiler, addedGCVars, varIndex);
- }
-#endif // DEBUG
- VarSetOps::AddElemD(compiler, gcInfo.gcVarPtrSetCur, varIndex);
- }
- }
-
- regSet.rsMaskVars = newLiveRegSet;
-
-#ifdef DEBUG
- if (compiler->verbose)
- {
- if (!VarSetOps::IsEmpty(compiler, addedGCVars))
- {
- printf("\t\t\t\t\t\t\tAdded GCVars: ");
- dumpConvertedVarSet(compiler, addedGCVars);
- printf("\n");
- }
- if (!VarSetOps::IsEmpty(compiler, removedGCVars))
- {
- printf("\t\t\t\t\t\t\tRemoved GCVars: ");
- dumpConvertedVarSet(compiler, removedGCVars);
- printf("\n");
- }
- }
-#endif // DEBUG
-
- gcInfo.gcMarkRegSetGCref(newRegGCrefSet DEBUGARG(true));
- gcInfo.gcMarkRegSetByref(newRegByrefSet DEBUGARG(true));
-
- /* Blocks with handlerGetsXcptnObj()==true use GT_CATCH_ARG to
- represent the exception object (TYP_REF).
- We mark REG_EXCEPTION_OBJECT as holding a GC object on entry
- to the block, it will be the first thing evaluated
- (thanks to GTF_ORDER_SIDEEFF).
- */
-
- if (handlerGetsXcptnObj(block->bbCatchTyp))
- {
- for (GenTree* node : LIR::AsRange(block))
- {
- if (node->OperGet() == GT_CATCH_ARG)
- {
- gcInfo.gcMarkRegSetGCref(RBM_EXCEPTION_OBJECT);
- break;
- }
- }
- }
-
- /* Start a new code output block */
-
- genUpdateCurrentFunclet(block);
-
-#ifdef _TARGET_XARCH_
- if (genAlignLoops && block->bbFlags & BBF_LOOP_HEAD)
- {
- getEmitter()->emitLoopAlign();
- }
-#endif
-
-#ifdef DEBUG
- if (compiler->opts.dspCode)
- printf("\n L_M%03u_BB%02u:\n", Compiler::s_compMethodsCount, block->bbNum);
-#endif
-
- block->bbEmitCookie = NULL;
-
- if (block->bbFlags & (BBF_JMP_TARGET | BBF_HAS_LABEL))
- {
- /* Mark a label and update the current set of live GC refs */
-
- block->bbEmitCookie = getEmitter()->emitAddLabel(gcInfo.gcVarPtrSetCur, gcInfo.gcRegGCrefSetCur,
- gcInfo.gcRegByrefSetCur, FALSE);
- }
-
- if (block == compiler->fgFirstColdBlock)
- {
-#ifdef DEBUG
- if (compiler->verbose)
- {
- printf("\nThis is the start of the cold region of the method\n");
- }
-#endif
- // We should never have a block that falls through into the Cold section
- noway_assert(!lblk->bbFallsThrough());
-
- // We require the block that starts the Cold section to have a label
- noway_assert(block->bbEmitCookie);
- getEmitter()->emitSetFirstColdIGCookie(block->bbEmitCookie);
- }
-
- /* Both stacks are always empty on entry to a basic block */
-
- genStackLevel = 0;
-
- savedStkLvl = genStackLevel;
-
- /* Tell everyone which basic block we're working on */
-
- compiler->compCurBB = block;
-
-#ifdef DEBUGGING_SUPPORT
- siBeginBlock(block);
-
- // BBF_INTERNAL blocks don't correspond to any single IL instruction.
- if (compiler->opts.compDbgInfo && (block->bbFlags & BBF_INTERNAL) &&
- !compiler->fgBBisScratch(block)) // If the block is the distinguished first scratch block, then no need to
- // emit a NO_MAPPING entry, immediately after the prolog.
- {
- genIPmappingAdd((IL_OFFSETX)ICorDebugInfo::NO_MAPPING, true);
- }
-
- bool firstMapping = true;
-#endif // DEBUGGING_SUPPORT
-
- /*---------------------------------------------------------------------
- *
- * Generate code for each statement-tree in the block
- *
- */
-
- if (block->bbFlags & BBF_FUNCLET_BEG)
- {
- genReserveFuncletProlog(block);
- }
-
- // Clear compCurStmt and compCurLifeTree.
- compiler->compCurStmt = nullptr;
- compiler->compCurLifeTree = nullptr;
-
- // Traverse the block in linear order, generating code for each node as we
- // as we encounter it.
- CLANG_FORMAT_COMMENT_ANCHOR;
-
-#ifdef DEBUGGING_SUPPORT
- IL_OFFSETX currentILOffset = BAD_IL_OFFSET;
-#endif
- for (GenTree* node : LIR::AsRange(block).NonPhiNodes())
- {
-#ifdef DEBUGGING_SUPPORT
- // Do we have a new IL offset?
- if (node->OperGet() == GT_IL_OFFSET)
- {
- genEnsureCodeEmitted(currentILOffset);
- currentILOffset = node->gtStmt.gtStmtILoffsx;
- genIPmappingAdd(currentILOffset, firstMapping);
- firstMapping = false;
- }
-#endif // DEBUGGING_SUPPORT
-
-#ifdef DEBUG
- if (node->OperGet() == GT_IL_OFFSET)
- {
- noway_assert(node->gtStmt.gtStmtLastILoffs <= compiler->info.compILCodeSize ||
- node->gtStmt.gtStmtLastILoffs == BAD_IL_OFFSET);
-
- if (compiler->opts.dspCode && compiler->opts.dspInstrs &&
- node->gtStmt.gtStmtLastILoffs != BAD_IL_OFFSET)
- {
- while (genCurDispOffset <= node->gtStmt.gtStmtLastILoffs)
- {
- genCurDispOffset += dumpSingleInstr(compiler->info.compCode, genCurDispOffset, "> ");
- }
- }
- }
-#endif // DEBUG
-
- genCodeForTreeNode(node);
- if (node->gtHasReg() && node->gtLsraInfo.isLocalDefUse)
- {
- genConsumeReg(node);
- }
- } // end for each node in block
-
-#ifdef DEBUG
- // The following set of register spill checks and GC pointer tracking checks used to be
- // performed at statement boundaries. Now, with LIR, there are no statements, so they are
- // performed at the end of each block.
- // TODO: could these checks be performed more frequently? E.g., at each location where
- // the register allocator says there are no live non-variable registers. Perhaps this could
- // be done by (a) keeping a running count of live non-variable registers by using
- // gtLsraInfo.srcCount and gtLsraInfo.dstCount to decrement and increment the count, respectively,
- // and running the checks when the count is zero. Or, (b) use the map maintained by LSRA
- // (operandToLocationInfoMap) to mark a node somehow when, after the execution of that node,
- // there will be no live non-variable registers.
-
- regSet.rsSpillChk();
-
- /* Make sure we didn't bungle pointer register tracking */
-
- regMaskTP ptrRegs = gcInfo.gcRegGCrefSetCur | gcInfo.gcRegByrefSetCur;
- regMaskTP nonVarPtrRegs = ptrRegs & ~regSet.rsMaskVars;
-
- // If return is a GC-type, clear it. Note that if a common
- // epilog is generated (genReturnBB) it has a void return
- // even though we might return a ref. We can't use the compRetType
- // as the determiner because something we are tracking as a byref
- // might be used as a return value of a int function (which is legal)
- GenTree* blockLastNode = block->lastNode();
- if ((blockLastNode != nullptr) && (blockLastNode->gtOper == GT_RETURN) &&
- (varTypeIsGC(compiler->info.compRetType) ||
- (blockLastNode->gtOp.gtOp1 != nullptr && varTypeIsGC(blockLastNode->gtOp.gtOp1->TypeGet()))))
- {
- nonVarPtrRegs &= ~RBM_INTRET;
- }
-
- if (nonVarPtrRegs)
- {
- printf("Regset after BB%02u gcr=", block->bbNum);
- printRegMaskInt(gcInfo.gcRegGCrefSetCur & ~regSet.rsMaskVars);
- compiler->getEmitter()->emitDispRegSet(gcInfo.gcRegGCrefSetCur & ~regSet.rsMaskVars);
- printf(", byr=");
- printRegMaskInt(gcInfo.gcRegByrefSetCur & ~regSet.rsMaskVars);
- compiler->getEmitter()->emitDispRegSet(gcInfo.gcRegByrefSetCur & ~regSet.rsMaskVars);
- printf(", regVars=");
- printRegMaskInt(regSet.rsMaskVars);
- compiler->getEmitter()->emitDispRegSet(regSet.rsMaskVars);
- printf("\n");
- }
-
- noway_assert(nonVarPtrRegs == RBM_NONE);
-#endif // DEBUG
-
-#if defined(DEBUG) && defined(_TARGET_ARM64_)
- if (block->bbNext == nullptr)
- {
- // Unit testing of the ARM64 emitter: generate a bunch of instructions into the last block
- // (it's as good as any, but better than the prolog, which can only be a single instruction
- // group) then use COMPlus_JitLateDisasm=* to see if the late disassembler
- // thinks the instructions are the same as we do.
- genArm64EmitterUnitTests();
- }
-#endif // defined(DEBUG) && defined(_TARGET_ARM64_)
-
-#ifdef DEBUGGING_SUPPORT
- // It is possible to reach the end of the block without generating code for the current IL offset.
- // For example, if the following IR ends the current block, no code will have been generated for
- // offset 21:
- //
- // ( 0, 0) [000040] ------------ il_offset void IL offset: 21
- //
- // N001 ( 0, 0) [000039] ------------ nop void
- //
- // This can lead to problems when debugging the generated code. To prevent these issues, make sure
- // we've generated code for the last IL offset we saw in the block.
- genEnsureCodeEmitted(currentILOffset);
-
- if (compiler->opts.compScopeInfo && (compiler->info.compVarScopesCount > 0))
- {
- siEndBlock(block);
-
- /* Is this the last block, and are there any open scopes left ? */
+ // We have a retless call, and the last instruction generated was a call.
+ // If the next block is in a different EH region (or is the end of the code
+ // block), then we need to generate a breakpoint here (since it will never
+ // get executed) to get proper unwind behavior.
- bool isLastBlockProcessed = (block->bbNext == NULL);
- if (block->isBBCallAlwaysPair())
- {
- isLastBlockProcessed = (block->bbNext->bbNext == NULL);
- }
-
- if (isLastBlockProcessed && siOpenScopeList.scNext)
- {
- /* This assert no longer holds, because we may insert a throw
- block to demarcate the end of a try or finally region when they
- are at the end of the method. It would be nice if we could fix
- our code so that this throw block will no longer be necessary. */
-
- // noway_assert(block->bbCodeOffsEnd != compiler->info.compILCodeSize);
-
- siCloseAllOpenScopes();
- }
- }
-
-#endif // DEBUGGING_SUPPORT
-
- genStackLevel -= savedStkLvl;
-
-#ifdef DEBUG
- // compCurLife should be equal to the liveOut set, except that we don't keep
- // it up to date for vars that are not register candidates
- // (it would be nice to have a xor set function)
-
- VARSET_TP VARSET_INIT_NOCOPY(extraLiveVars, VarSetOps::Diff(compiler, block->bbLiveOut, compiler->compCurLife));
- VarSetOps::UnionD(compiler, extraLiveVars, VarSetOps::Diff(compiler, compiler->compCurLife, block->bbLiveOut));
- VARSET_ITER_INIT(compiler, extraLiveVarIter, extraLiveVars, extraLiveVarIndex);
- while (extraLiveVarIter.NextElem(compiler, &extraLiveVarIndex))
+ if ((block->bbNext == nullptr) || !BasicBlock::sameEHRegion(block, block->bbNext))
{
- unsigned varNum = compiler->lvaTrackedToVarNum[extraLiveVarIndex];
- LclVarDsc* varDsc = compiler->lvaTable + varNum;
- assert(!varDsc->lvIsRegCandidate());
+ instGen(INS_BREAKPOINT); // This should never get executed
}
-#endif
-
- /* Both stacks should always be empty on exit from a basic block */
-
- noway_assert(genStackLevel == 0);
+ }
+ else
+ {
+ // Because of the way the flowgraph is connected, the liveness info for this one instruction
+ // after the call is not (can not be) correct in cases where a variable has a last use in the
+ // handler. So turn off GC reporting for this single instruction.
+ getEmitter()->emitDisableGC();
-#if 0
- // On AMD64, we need to generate a NOP after a call that is the last instruction of the block, in several
- // situations, to support proper exception handling semantics. This is mostly to ensure that when the stack
- // walker computes an instruction pointer for a frame, that instruction pointer is in the correct EH region.
- // The document "X64 and ARM ABIs.docx" has more details. The situations:
- // 1. If the call instruction is in a different EH region as the instruction that follows it.
- // 2. If the call immediately precedes an OS epilog. (Note that what the JIT or VM consider an epilog might
- // be slightly different from what the OS considers an epilog, and it is the OS-reported epilog that matters here.)
- // We handle case #1 here, and case #2 in the emitter.
- if (getEmitter()->emitIsLastInsCall())
+ // Now go to where the finally funclet needs to return to.
+ if (block->bbNext->bbJumpDest == block->bbNext->bbNext)
{
- // Ok, the last instruction generated is a call instruction. Do any of the other conditions hold?
- // Note: we may be generating a few too many NOPs for the case of call preceding an epilog. Technically,
- // if the next block is a BBJ_RETURN, an epilog will be generated, but there may be some instructions
- // generated before the OS epilog starts, such as a GS cookie check.
- if ((block->bbNext == nullptr) ||
- !BasicBlock::sameEHRegion(block, block->bbNext))
- {
- // We only need the NOP if we're not going to generate any more code as part of the block end.
-
- switch (block->bbJumpKind)
- {
- case BBJ_ALWAYS:
- case BBJ_THROW:
- case BBJ_CALLFINALLY:
- case BBJ_EHCATCHRET:
- // We're going to generate more code below anyway, so no need for the NOP.
-
- case BBJ_RETURN:
- case BBJ_EHFINALLYRET:
- case BBJ_EHFILTERRET:
- // These are the "epilog follows" case, handled in the emitter.
-
- break;
-
- case BBJ_NONE:
- if (block->bbNext == nullptr)
- {
- // Call immediately before the end of the code; we should never get here .
- instGen(INS_BREAKPOINT); // This should never get executed
- }
- else
- {
- // We need the NOP
- instGen(INS_nop);
- }
- break;
-
- case BBJ_COND:
- case BBJ_SWITCH:
- // These can't have a call as the last instruction!
-
- default:
- noway_assert(!"Unexpected bbJumpKind");
- break;
- }
- }
+ // Fall-through.
+ // TODO-ARM64-CQ: Can we get rid of this instruction, and just have the call return directly
+ // to the next instruction? This would depend on stack walking from within the finally
+ // handler working without this instruction being in this special EH region.
+ instGen(INS_nop);
}
-#endif // 0
-
- /* Do we need to generate a jump or return? */
-
- switch (block->bbJumpKind)
+ else
{
- case BBJ_ALWAYS:
- inst_JMP(EJ_jmp, block->bbJumpDest);
- break;
-
- case BBJ_RETURN:
- genExitCode(block);
- break;
-
- case BBJ_THROW:
- // If we have a throw at the end of a function or funclet, we need to emit another instruction
- // afterwards to help the OS unwinder determine the correct context during unwind.
- // We insert an unexecuted breakpoint instruction in several situations
- // following a throw instruction:
- // 1. If the throw is the last instruction of the function or funclet. This helps
- // the OS unwinder determine the correct context during an unwind from the
- // thrown exception.
- // 2. If this is this is the last block of the hot section.
- // 3. If the subsequent block is a special throw block.
- // 4. On AMD64, if the next block is in a different EH region.
- if ((block->bbNext == NULL) || (block->bbNext->bbFlags & BBF_FUNCLET_BEG) ||
- !BasicBlock::sameEHRegion(block, block->bbNext) ||
- (!isFramePointerUsed() && compiler->fgIsThrowHlpBlk(block->bbNext)) ||
- block->bbNext == compiler->fgFirstColdBlock)
- {
- instGen(INS_BREAKPOINT); // This should never get executed
- }
-
- break;
-
- case BBJ_CALLFINALLY:
-
- // Generate a call to the finally, like this:
- // mov x0,qword ptr [fp + 10H] // Load x0 with PSPSym
- // bl finally-funclet
- // b finally-return // Only for non-retless finally calls
- // The 'b' can be a NOP if we're going to the next block.
-
- getEmitter()->emitIns_R_S(ins_Load(TYP_I_IMPL), EA_PTRSIZE, REG_R0, compiler->lvaPSPSym, 0);
- getEmitter()->emitIns_J(INS_bl_local, block->bbJumpDest);
-
- if (block->bbFlags & BBF_RETLESS_CALL)
- {
- // We have a retless call, and the last instruction generated was a call.
- // If the next block is in a different EH region (or is the end of the code
- // block), then we need to generate a breakpoint here (since it will never
- // get executed) to get proper unwind behavior.
-
- if ((block->bbNext == nullptr) || !BasicBlock::sameEHRegion(block, block->bbNext))
- {
- instGen(INS_BREAKPOINT); // This should never get executed
- }
- }
- else
- {
- // Because of the way the flowgraph is connected, the liveness info for this one instruction
- // after the call is not (can not be) correct in cases where a variable has a last use in the
- // handler. So turn off GC reporting for this single instruction.
- getEmitter()->emitDisableGC();
-
- // Now go to where the finally funclet needs to return to.
- if (block->bbNext->bbJumpDest == block->bbNext->bbNext)
- {
- // Fall-through.
- // TODO-ARM64-CQ: Can we get rid of this instruction, and just have the call return directly
- // to the next instruction? This would depend on stack walking from within the finally
- // handler working without this instruction being in this special EH region.
- instGen(INS_nop);
- }
- else
- {
- inst_JMP(EJ_jmp, block->bbNext->bbJumpDest);
- }
-
- getEmitter()->emitEnableGC();
- }
-
- // 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.
- if (!(block->bbFlags & BBF_RETLESS_CALL))
- {
- assert(block->isBBCallAlwaysPair());
-
- lblk = block;
- block = block->bbNext;
- }
- break;
-
- case BBJ_EHCATCHRET:
- // For long address (default): `adrp + add` will be emitted.
- // For short address (proven later): `adr` will be emitted.
- getEmitter()->emitIns_R_L(INS_adr, EA_PTRSIZE, block->bbJumpDest, REG_INTRET);
-
- __fallthrough;
-
- case BBJ_EHFINALLYRET:
- case BBJ_EHFILTERRET:
- genReserveFuncletEpilog(block);
- break;
-
- case BBJ_NONE:
- case BBJ_COND:
- case BBJ_SWITCH:
- break;
-
- default:
- noway_assert(!"Unexpected bbJumpKind");
- break;
+ inst_JMP(EJ_jmp, block->bbNext->bbJumpDest);
}
-#ifdef DEBUG
- compiler->compCurBB = 0;
-#endif
-
- } //------------------ END-FOR each block of the method -------------------
-
- /* Nothing is live at this point */
- genUpdateLife(VarSetOps::MakeEmpty(compiler));
-
- /* Finalize the spill tracking logic */
-
- regSet.rsSpillEnd();
-
- /* Finalize the temp tracking logic */
-
- compiler->tmpEnd();
+ getEmitter()->emitEnableGC();
+ }
-#ifdef DEBUG
- if (compiler->verbose)
+ // 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.
+ if (!(block->bbFlags & BBF_RETLESS_CALL))
{
- printf("\n# ");
- printf("compCycleEstimate = %6d, compSizeEstimate = %5d ", compiler->compCycleEstimate,
- compiler->compSizeEstimate);
- printf("%s\n", compiler->info.compFullName);
+ assert(block->isBBCallAlwaysPair());
+
+ lblk = block;
+ block = block->bbNext;
}
-#endif
+ return block;
}
-// return the child that has the same reg as the dst (if any)
-// other child returned (out param) in 'other'
-// TODO-Cleanup: move to CodeGenCommon.cpp
-GenTree* sameRegAsDst(GenTree* tree, GenTree*& other /*out*/)
+void CodeGen::genEHCatchRet(BasicBlock* block)
{
- if (tree->gtRegNum == REG_NA)
- {
- other = nullptr;
- return NULL;
- }
-
- GenTreePtr op1 = tree->gtOp.gtOp1;
- GenTreePtr op2 = tree->gtOp.gtOp2;
- if (op1->gtRegNum == tree->gtRegNum)
- {
- other = op2;
- return op1;
- }
- if (op2->gtRegNum == tree->gtRegNum)
- {
- other = op1;
- return op2;
- }
- else
- {
- other = nullptr;
- return NULL;
- }
+ // For long address (default): `adrp + add` will be emitted.
+ // For short address (proven later): `adr` will be emitted.
+ getEmitter()->emitIns_R_L(INS_adr, EA_PTRSIZE, block->bbJumpDest, REG_INTRET);
}
// move an immediate value into an integer register
@@ -3397,12 +2695,13 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
break;
case GT_LIST:
+ case GT_FIELD_LIST:
case GT_ARGPLACE:
// Nothing to do
break;
case GT_PUTARG_STK:
- genPutArgStk(treeNode);
+ genPutArgStk(treeNode->AsPutArgStk());
break;
case GT_PUTARG_REG:
@@ -3432,7 +2731,7 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
case GT_LOCKADD:
case GT_XCHG:
case GT_XADD:
- genLockedInstructions(treeNode);
+ genLockedInstructions(treeNode->AsOp());
break;
case GT_MEMORYBARRIER:
@@ -3597,7 +2896,8 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
{
#ifdef DEBUG
char message[256];
- sprintf(message, "Unimplemented node type %s\n", GenTree::NodeName(treeNode->OperGet()));
+ _snprintf_s(message, _countof(message), _TRUNCATE, "Unimplemented node type %s\n",
+ GenTree::NodeName(treeNode->OperGet()));
#endif
assert(!"Unknown node in codegen");
}
@@ -3998,9 +3298,11 @@ BAILOUT:
if (endLabel != nullptr)
genDefineTempLabel(endLabel);
- // Write the lvaShadowSPfirst stack frame slot
- noway_assert(compiler->lvaLocAllocSPvar != BAD_VAR_NUM);
- getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, targetReg, compiler->lvaLocAllocSPvar, 0);
+ // Write the lvaLocAllocSPvar stack frame slot
+ if (compiler->lvaLocAllocSPvar != BAD_VAR_NUM)
+ {
+ getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, targetReg, compiler->lvaLocAllocSPvar, 0);
+ }
#if STACK_PROBES
if (compiler->opts.compNeedStackProbes)
@@ -4034,6 +3336,10 @@ void CodeGen::genCodeForInitBlkUnroll(GenTreeBlk* initBlkNode)
unsigned size = initBlkNode->Size();
GenTreePtr dstAddr = initBlkNode->Addr();
GenTreePtr initVal = initBlkNode->Data();
+ if (initVal->OperIsInitVal())
+ {
+ initVal = initVal->gtGetOp1();
+ }
assert(!dstAddr->isContained());
assert(!initVal->isContained());
@@ -4043,8 +3349,7 @@ void CodeGen::genCodeForInitBlkUnroll(GenTreeBlk* initBlkNode)
emitter *emit = getEmitter();
- genConsumeReg(initVal);
- genConsumeReg(dstAddr);
+ 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,
@@ -4066,27 +3371,25 @@ void CodeGen::genCodeForInitBlk(GenTreeBlk* initBlkNode)
unsigned size = initBlkNode->Size();
GenTreePtr dstAddr = initBlkNode->Addr();
GenTreePtr initVal = initBlkNode->Data();
+ if (initVal->OperIsInitVal())
+ {
+ initVal = initVal->gtGetOp1();
+ }
assert(!dstAddr->isContained());
assert(!initVal->isContained());
assert(initBlkNode->gtRsvdRegs == RBM_ARG_2);
- if (size == 0)
- {
- noway_assert(initBlkNode->gtOper == GT_DYN_BLK);
- genConsumeRegAndCopy(initBlkNode->AsDynBlk()->gtDynamicSize, REG_ARG_2);
- }
- else
- {
// TODO-ARM64-CQ: When initblk loop unrolling is implemented
// put this assert back on.
#if 0
- assert(size >= INITBLK_UNROLL_LIMIT);
-#endif // 0
- genSetRegToIcon(REG_ARG_2, size);
+ if (size != 0)
+ {
+ assert(blockSize >= INITBLK_UNROLL_LIMIT);
}
- genConsumeRegAndCopy(initVal, REG_ARG_1);
- genConsumeRegAndCopy(dstAddr, REG_ARG_0);
+#endif // 0
+
+ genConsumeBlockOp(initBlkNode, REG_ARG_0, REG_ARG_1, REG_ARG_2);
genEmitHelperCall(CORINFO_HELP_MEMSET, 0, EA_UNKNOWN);
}
@@ -4238,29 +3541,38 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* cpBlkNode)
// str tempReg, [R14, #8]
void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)
{
- // Make sure we got the arguments of the cpobj operation in the right registers
- GenTreePtr dstAddr = cpObjNode->Addr();
- GenTreePtr source = cpObjNode->Data();
- noway_assert(source->gtOper == GT_IND);
- GenTreePtr srcAddr = source->gtGetOp1();
+ GenTreePtr dstAddr = cpObjNode->Addr();
+ GenTreePtr source = cpObjNode->Data();
+ var_types srcAddrType = TYP_BYREF;
+ bool sourceIsLocal = false;
+
+ assert(source->isContained());
+ if (source->gtOper == GT_IND)
+ {
+ GenTree* srcAddr = source->gtGetOp1();
+ assert(!srcAddr->isContained());
+ srcAddrType = srcAddr->TypeGet();
+ }
+ else
+ {
+ noway_assert(source->IsLocal());
+ sourceIsLocal = true;
+ }
bool dstOnStack = dstAddr->OperIsLocalAddr();
#ifdef DEBUG
assert(!dstAddr->isContained());
- assert(!srcAddr->isContained());
// This GenTree node has data about GC pointers, this means we're dealing
// with CpObj.
assert(cpObjNode->gtGcPtrCount > 0);
#endif // DEBUG
- // Consume these registers.
+ // Consume the operands and get them into the right registers.
// They may now contain gc pointers (depending on their type; gcMarkRegPtrVal will "do the right thing").
- genConsumeRegAndCopy(srcAddr, REG_WRITE_BARRIER_SRC_BYREF);
- gcInfo.gcMarkRegPtrVal(REG_WRITE_BARRIER_SRC_BYREF, srcAddr->TypeGet());
-
- genConsumeRegAndCopy(dstAddr, REG_WRITE_BARRIER_DST_BYREF);
+ genConsumeBlockOp(cpObjNode, REG_WRITE_BARRIER_DST_BYREF, REG_WRITE_BARRIER_SRC_BYREF, REG_NA);
+ gcInfo.gcMarkRegPtrVal(REG_WRITE_BARRIER_SRC_BYREF, srcAddrType);
gcInfo.gcMarkRegPtrVal(REG_WRITE_BARRIER_DST_BYREF, dstAddr->TypeGet());
// Temp register used to perform the sequence of loads and stores.
@@ -4332,31 +3644,17 @@ 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();
- GenTreePtr source = cpBlkNode->Data();
- noway_assert(source->gtOper == GT_IND);
- GenTreePtr srcAddr = source->gtGetOp1();
-
assert(!dstAddr->isContained());
- assert(!srcAddr->isContained());
- assert(cpBlkNode->gtRsvdRegs == RBM_ARG_2);
- if (blockSize != 0)
- {
+ genConsumeBlockOp(cpBlkNode, REG_ARG_0, REG_ARG_1, REG_ARG_2);
+
#if 0
// Enable this when we support cpblk loop unrolling.
-
- assert(blockSize->gtIntCon.gtIconVal >= CPBLK_UNROLL_LIMIT);
-
-#endif // 0
- genSetRegToIcon(REG_ARG_2, blockSize);
- }
- else
+ if (blockSize != 0)
{
- noway_assert(cpBlkNode->gtOper == GT_DYN_BLK);
- genConsumeRegAndCopy(cpBlkNode->AsDynBlk()->gtDynamicSize, REG_ARG_2);
+ assert(blockSize->gtIntCon.gtIconVal >= CPBLK_UNROLL_LIMIT);
}
- genConsumeRegAndCopy(srcAddr, REG_ARG_1);
- genConsumeRegAndCopy(dstAddr, REG_ARG_0);
+#endif // 0
genEmitHelperCall(CORINFO_HELP_MEMCPY, 0, EA_UNKNOWN);
}
@@ -4421,7 +3719,7 @@ void CodeGen::genJumpTable(GenTree* treeNode)
// generate code for the locked operations:
// GT_LOCKADD, GT_XCHG, GT_XADD
-void CodeGen::genLockedInstructions(GenTree* treeNode)
+void CodeGen::genLockedInstructions(GenTreeOp* treeNode)
{
#if 0
GenTree* data = treeNode->gtOp.gtOp2;
@@ -4839,154 +4137,6 @@ void CodeGen::genCodeForShift(GenTreePtr tree)
genProduceReg(tree);
}
-// TODO-Cleanup: move to CodeGenCommon.cpp
-void CodeGen::genUnspillRegIfNeeded(GenTree* tree)
-{
- regNumber dstReg = tree->gtRegNum;
-
- GenTree* unspillTree = tree;
- if (tree->gtOper == GT_RELOAD)
- {
- unspillTree = tree->gtOp.gtOp1;
- }
-
- if (unspillTree->gtFlags & GTF_SPILLED)
- {
- if (genIsRegCandidateLocal(unspillTree))
- {
- // Reset spilled flag, since we are going to load a local variable from its home location.
- unspillTree->gtFlags &= ~GTF_SPILLED;
-
- GenTreeLclVarCommon* lcl = unspillTree->AsLclVarCommon();
- LclVarDsc* varDsc = &compiler->lvaTable[lcl->gtLclNum];
-
- var_types targetType = unspillTree->gtType;
- instruction ins = ins_Load(targetType, compiler->isSIMDTypeLocalAligned(lcl->gtLclNum));
- emitAttr attr = emitTypeSize(targetType);
- emitter* emit = getEmitter();
-
- // Fixes Issue #3326
- attr = emit->emitInsAdjustLoadStoreAttr(ins, attr);
-
- // Load local variable from its home location.
- inst_RV_TT(ins, dstReg, unspillTree, 0, attr);
-
- unspillTree->SetInReg();
-
- // TODO-Review: We would like to call:
- // genUpdateRegLife(varDsc, /*isBorn*/ true, /*isDying*/ false DEBUGARG(tree));
- // instead of the following code, but this ends up hitting this assert:
- // assert((regSet.rsMaskVars & regMask) == 0);
- // due to issues with LSRA resolution moves.
- // So, just force it for now. This probably indicates a condition that creates a GC hole!
- //
- // Extra note: I think we really want to call something like gcInfo.gcUpdateForRegVarMove,
- // because the variable is not really going live or dead, but that method is somewhat poorly
- // factored because it, in turn, updates rsMaskVars which is part of RegSet not GCInfo.
- // This code exists in other CodeGen*.cpp files.
-
- // Don't update the variable's location if we are just re-spilling it again.
-
- if ((unspillTree->gtFlags & GTF_SPILL) == 0)
- {
- genUpdateVarReg(varDsc, tree);
-#ifdef DEBUG
- if (VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex))
- {
- JITDUMP("\t\t\t\t\t\t\tRemoving V%02u from gcVarPtrSetCur\n", lcl->gtLclNum);
- }
-#endif // DEBUG
- VarSetOps::RemoveElemD(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex);
-
-#ifdef DEBUG
- if (compiler->verbose)
- {
- printf("\t\t\t\t\t\t\tV%02u in reg ", lcl->gtLclNum);
- varDsc->PrintVarReg();
- printf(" is becoming live ");
- compiler->printTreeID(unspillTree);
- printf("\n");
- }
-#endif // DEBUG
-
- regSet.AddMaskVars(genGetRegMask(varDsc));
- }
-
- gcInfo.gcMarkRegPtrVal(dstReg, unspillTree->TypeGet());
- }
- else if (unspillTree->IsMultiRegCall())
- {
- GenTreeCall* call = unspillTree->AsCall();
- ReturnTypeDesc* pRetTypeDesc = call->GetReturnTypeDesc();
- unsigned regCount = pRetTypeDesc->GetReturnRegCount();
- GenTreeCopyOrReload* reloadTree = nullptr;
- if (tree->OperGet() == GT_RELOAD)
- {
- reloadTree = tree->AsCopyOrReload();
- }
-
- // In case of multi-reg call node, GTF_SPILLED flag on it indicates that
- // one or more of its result regs are spilled. Call node needs to be
- // queried to know which specific result regs to be unspilled.
- for (unsigned i = 0; i < regCount; ++i)
- {
- unsigned flags = call->GetRegSpillFlagByIdx(i);
- if ((flags & GTF_SPILLED) != 0)
- {
- var_types dstType = pRetTypeDesc->GetReturnRegType(i);
- regNumber unspillTreeReg = call->GetRegNumByIdx(i);
-
- if (reloadTree != nullptr)
- {
- dstReg = reloadTree->GetRegNumByIdx(i);
- if (dstReg == REG_NA)
- {
- dstReg = unspillTreeReg;
- }
- }
- else
- {
- dstReg = unspillTreeReg;
- }
-
- TempDsc* t = regSet.rsUnspillInPlace(call, unspillTreeReg, i);
- getEmitter()->emitIns_R_S(ins_Load(dstType), emitActualTypeSize(dstType), dstReg, t->tdTempNum(),
- 0);
- compiler->tmpRlsTemp(t);
- gcInfo.gcMarkRegPtrVal(dstReg, dstType);
- }
- }
-
- unspillTree->gtFlags &= ~GTF_SPILLED;
- unspillTree->SetInReg();
- }
- else
- {
- TempDsc* t = regSet.rsUnspillInPlace(unspillTree, unspillTree->gtRegNum);
- getEmitter()->emitIns_R_S(ins_Load(unspillTree->gtType), emitActualTypeSize(unspillTree->TypeGet()), dstReg,
- t->tdTempNum(), 0);
- compiler->tmpRlsTemp(t);
-
- unspillTree->gtFlags &= ~GTF_SPILLED;
- unspillTree->SetInReg();
- gcInfo.gcMarkRegPtrVal(dstReg, unspillTree->TypeGet());
- }
- }
-}
-
-// Do Liveness update for a subnodes that is being consumed by codegen
-// including the logic for reload in case is needed and also takes care
-// of locating the value on the desired register.
-void CodeGen::genConsumeRegAndCopy(GenTree* tree, regNumber needReg)
-{
- regNumber treeReg = genConsumeReg(tree);
- if (treeReg != needReg)
- {
- var_types targetType = tree->TypeGet();
- inst_RV_RV(ins_Copy(targetType), needReg, treeReg, targetType);
- }
-}
-
void CodeGen::genRegCopy(GenTree* treeNode)
{
assert(treeNode->OperGet() == GT_COPY);
@@ -5049,261 +4199,6 @@ void CodeGen::genRegCopy(GenTree* treeNode)
genProduceReg(treeNode);
}
-// Do liveness update for a subnode that is being consumed by codegen.
-// TODO-Cleanup: move to CodeGenCommon.cpp
-regNumber CodeGen::genConsumeReg(GenTree* tree)
-{
- if (tree->OperGet() == GT_COPY)
- {
- genRegCopy(tree);
- }
- // Handle the case where we have a lclVar that needs to be copied before use (i.e. because it
- // interferes with one of the other sources (or the target, if it's a "delayed use" register)).
- // TODO-Cleanup: This is a special copyReg case in LSRA - consider eliminating these and
- // always using GT_COPY to make the lclVar location explicit.
- // Note that we have to do this before calling genUpdateLife because otherwise if we spill it
- // the lvRegNum will be set to REG_STK and we will lose track of what register currently holds
- // the lclVar (normally when a lclVar is spilled it is then used from its former register
- // location, which matches the gtRegNum on the node).
- // (Note that it doesn't matter if we call this before or after genUnspillRegIfNeeded
- // because if it's on the stack it will always get reloaded into tree->gtRegNum).
- if (genIsRegCandidateLocal(tree))
- {
- GenTreeLclVarCommon* lcl = tree->AsLclVarCommon();
- LclVarDsc* varDsc = &compiler->lvaTable[lcl->GetLclNum()];
- if ((varDsc->lvRegNum != REG_STK) && (varDsc->lvRegNum != tree->gtRegNum))
- {
- inst_RV_RV(ins_Copy(tree->TypeGet()), tree->gtRegNum, varDsc->lvRegNum);
- }
- }
-
- genUnspillRegIfNeeded(tree);
-
- // genUpdateLife() will also spill local var if marked as GTF_SPILL by calling CodeGen::genSpillVar
- genUpdateLife(tree);
- assert(tree->gtRegNum != REG_NA);
-
- // there are three cases where consuming a reg means clearing the bit in the live mask
- // 1. it was not produced by a local
- // 2. it was produced by a local that is going dead
- // 3. it was produced by a local that does not live in that reg (like one allocated on the stack)
-
- if (genIsRegCandidateLocal(tree))
- {
- GenTreeLclVarCommon* lcl = tree->AsLclVarCommon();
- LclVarDsc* varDsc = &compiler->lvaTable[lcl->GetLclNum()];
- assert(varDsc->lvLRACandidate);
-
- if ((tree->gtFlags & GTF_VAR_DEATH) != 0)
- {
- gcInfo.gcMarkRegSetNpt(genRegMask(varDsc->lvRegNum));
- }
- else if (varDsc->lvRegNum == REG_STK)
- {
- // We have loaded this into a register only temporarily
- gcInfo.gcMarkRegSetNpt(genRegMask(tree->gtRegNum));
- }
- }
- else
- {
- gcInfo.gcMarkRegSetNpt(genRegMask(tree->gtRegNum));
- }
-
- return tree->gtRegNum;
-}
-
-// Do liveness update for an address tree: one of GT_LEA, GT_LCL_VAR, or GT_CNS_INT (for call indirect).
-// TODO-Cleanup: move to CodeGenCommon.cpp
-void CodeGen::genConsumeAddress(GenTree* addr)
-{
- if (addr->OperGet() == GT_LEA)
- {
- genConsumeAddrMode(addr->AsAddrMode());
- }
- else if (!addr->isContained())
- {
- genConsumeReg(addr);
- }
-}
-
-// do liveness update for a subnode that is being consumed by codegen
-// TODO-Cleanup: move to CodeGenCommon.cpp
-void CodeGen::genConsumeAddrMode(GenTreeAddrMode* addr)
-{
- if (addr->Base())
- genConsumeReg(addr->Base());
- if (addr->Index())
- genConsumeReg(addr->Index());
-}
-
-// TODO-Cleanup: move to CodeGenCommon.cpp
-void CodeGen::genConsumeRegs(GenTree* tree)
-{
- if (tree->isContained())
- {
- if (tree->isIndir())
- {
- genConsumeAddress(tree->AsIndir()->Addr());
- }
- else if (tree->OperGet() == GT_AND)
- {
- // This is the special contained GT_AND that we created in Lowering::LowerCmp()
- // Now we need to consume the operands of the GT_AND node.
- genConsumeOperands(tree->AsOp());
- }
- else
- {
- assert(tree->OperIsLeaf());
- }
- }
- else
- {
- genConsumeReg(tree);
- }
-}
-
-//------------------------------------------------------------------------
-// genConsumeOperands: Do liveness update for the operands of a unary or binary tree
-//
-// Arguments:
-// tree - the GenTreeOp whose operands will have their liveness updated.
-//
-// Return Value:
-// None.
-//
-// Notes:
-// Note that this logic is localized here because we must do the liveness update in
-// the correct execution order. This is important because we may have two operands
-// that involve the same lclVar, and if one is marked "lastUse" we must handle it
-// after the first.
-// TODO-Cleanup: move to CodeGenCommon.cpp
-
-void CodeGen::genConsumeOperands(GenTreeOp* tree)
-{
- GenTree* firstOp = tree->gtOp1;
- GenTree* secondOp = tree->gtOp2;
- if ((tree->gtFlags & GTF_REVERSE_OPS) != 0)
- {
- assert(secondOp != nullptr);
- firstOp = secondOp;
- secondOp = tree->gtOp1;
- }
- if (firstOp != nullptr)
- {
- genConsumeRegs(firstOp);
- }
- if (secondOp != nullptr)
- {
- genConsumeRegs(secondOp);
- }
-}
-
-// do liveness update for register produced by the current node in codegen
-// TODO-Cleanup: move to CodeGenCommon.cpp
-void CodeGen::genProduceReg(GenTree* tree)
-{
- if (tree->gtFlags & GTF_SPILL)
- {
- if (genIsRegCandidateLocal(tree))
- {
- // Store local variable to its home location.
- tree->gtFlags &= ~GTF_REG_VAL;
- inst_TT_RV(ins_Store(tree->gtType, compiler->isSIMDTypeLocalAligned(tree->gtLclVarCommon.gtLclNum)), tree,
- tree->gtRegNum);
- }
- else
- {
- tree->SetInReg();
- regSet.rsSpillTree(tree->gtRegNum, tree);
- tree->gtFlags |= GTF_SPILLED;
- tree->gtFlags &= ~GTF_SPILL;
- gcInfo.gcMarkRegSetNpt(genRegMask(tree->gtRegNum));
- return;
- }
- }
-
- genUpdateLife(tree);
-
- // If we've produced a register, mark it as a pointer, as needed.
- if (tree->gtHasReg())
- {
- // We only mark the register in the following cases:
- // 1. It is not a register candidate local. In this case, we're producing a
- // register from a local, but the local is not a register candidate. Thus,
- // we must be loading it as a temp register, and any "last use" flag on
- // the register wouldn't be relevant.
- // 2. The register candidate local is going dead. There's no point to mark
- // the register as live, with a GC pointer, if the variable is dead.
- if (!genIsRegCandidateLocal(tree) || ((tree->gtFlags & GTF_VAR_DEATH) == 0))
- {
- gcInfo.gcMarkRegPtrVal(tree->gtRegNum, tree->TypeGet());
- }
- }
- tree->SetInReg();
-}
-
-// transfer gc/byref status of src reg to dst reg
-// TODO-Cleanup: move to CodeGenCommon.cpp
-void CodeGen::genTransferRegGCState(regNumber dst, regNumber src)
-{
- regMaskTP srcMask = genRegMask(src);
- regMaskTP dstMask = genRegMask(dst);
-
- if (gcInfo.gcRegGCrefSetCur & srcMask)
- {
- gcInfo.gcMarkRegSetGCref(dstMask);
- }
- else if (gcInfo.gcRegByrefSetCur & srcMask)
- {
- gcInfo.gcMarkRegSetByref(dstMask);
- }
- else
- {
- gcInfo.gcMarkRegSetNpt(dstMask);
- }
-}
-
-// generates an ip-relative call or indirect call via reg ('call reg')
-// 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)
-// TODO-Cleanup: move to CodeGenCommon.cpp
-void CodeGen::genEmitCall(int callType,
- CORINFO_METHOD_HANDLE methHnd,
- INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo) void* addr,
- emitAttr retSize,
- emitAttr secondRetSize,
- IL_OFFSETX ilOffset,
- regNumber base,
- bool isJump,
- bool isNoGC)
-{
-
- getEmitter()->emitIns_Call(emitter::EmitCallType(callType), methHnd, INDEBUG_LDISASM_COMMA(sigInfo) addr, 0,
- retSize, secondRetSize, gcInfo.gcVarPtrSetCur, gcInfo.gcRegGCrefSetCur,
- gcInfo.gcRegByrefSetCur, ilOffset, base, REG_NA, 0, 0, isJump,
- emitter::emitNoGChelper(compiler->eeGetHelperNum(methHnd)));
-}
-
-// 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)
-// TODO-Cleanup: move to CodeGenCommon.cpp
-void CodeGen::genEmitCall(int callType,
- CORINFO_METHOD_HANDLE methHnd,
- INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo) GenTreeIndir* indir,
- emitAttr retSize,
- emitAttr secondRetSize,
- IL_OFFSETX ilOffset)
-{
- genConsumeAddress(indir->Addr());
-
- getEmitter()->emitIns_Call(emitter::EmitCallType(callType), methHnd, INDEBUG_LDISASM_COMMA(sigInfo) nullptr, 0,
- retSize, 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());
-}
-
// Produce code for a GT_CALL node
void CodeGen::genCallInstruction(GenTreePtr node)
{
@@ -5321,7 +4216,7 @@ void CodeGen::genCallInstruction(GenTreePtr node)
// Consume all the arg regs
for (GenTreePtr list = call->gtCallLateArgs; list; list = list->MoveNext())
{
- assert(list->IsList());
+ assert(list->OperIsList());
GenTreePtr argNode = list->Current();
@@ -5332,7 +4227,7 @@ void CodeGen::genCallInstruction(GenTreePtr node)
continue;
// Deal with multi register passed struct args.
- if (argNode->OperGet() == GT_LIST)
+ if (argNode->OperGet() == GT_FIELD_LIST)
{
GenTreeArgList* argListPtr = argNode->AsArgList();
unsigned iterationNum = 0;
@@ -5457,7 +4352,6 @@ void CodeGen::genCallInstruction(GenTreePtr node)
}
}
-#ifdef DEBUGGING_SUPPORT
// 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,
@@ -5466,7 +4360,6 @@ void CodeGen::genCallInstruction(GenTreePtr node)
{
(void)compiler->genCallSite2ILOffsetMap->Lookup(call, &ilOffset);
}
-#endif // DEBUGGING_SUPPORT
if (target != nullptr)
{
@@ -6703,7 +5596,7 @@ void CodeGen::genIntrinsic(GenTreePtr treeNode)
// Return value:
// None
//
-void CodeGen::genPutArgStk(GenTreePtr treeNode)
+void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode)
{
assert(treeNode->OperGet() == GT_PUTARG_STK);
var_types targetType = treeNode->TypeGet();
@@ -6759,7 +5652,7 @@ void CodeGen::genPutArgStk(GenTreePtr treeNode)
varNumOut = compiler->lvaOutgoingArgSpaceVar;
argOffsetMax = compiler->lvaOutgoingArgSpaceSize;
}
- bool isStruct = (targetType == TYP_STRUCT) || (source->OperGet() == GT_LIST);
+ bool isStruct = (targetType == TYP_STRUCT) || (source->OperGet() == GT_FIELD_LIST);
if (!isStruct) // a normal non-Struct argument
{
@@ -6785,24 +5678,24 @@ void CodeGen::genPutArgStk(GenTreePtr treeNode)
{
assert(source->isContained()); // We expect that this node was marked as contained in LowerArm64
- if (source->OperGet() == GT_LIST)
+ if (source->OperGet() == GT_FIELD_LIST)
{
// Deal with the multi register passed struct args.
- GenTreeArgList* argListPtr = source->AsArgList();
+ GenTreeFieldList* fieldListPtr = source->AsFieldList();
- // Evaluate each of the GT_LIST items into their register
+ // Evaluate each of the GT_FIELD_LIST items into their register
// and store their register into the outgoing argument area
- for (; argListPtr != nullptr; argListPtr = argListPtr->Rest())
+ for (; fieldListPtr != nullptr; fieldListPtr = fieldListPtr->Rest())
{
- GenTreePtr nextArgNode = argListPtr->gtOp.gtOp1;
+ 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_LIST into the outgoing argument
- // area
+ // 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
@@ -7159,7 +6052,6 @@ void CodeGen::genCreateAndStoreGCInfoX64(unsigned codeSize, unsigned prologSize
// 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 defined(DEBUGGING_SUPPORT)
if (compiler->opts.compDbgEnC)
{
// what we have to preserve is called the "frame header" (see comments in VM\eetwain.cpp)
@@ -7183,7 +6075,6 @@ void CodeGen::genCreateAndStoreGCInfoX64(unsigned codeSize, unsigned prologSize
// frame
gcInfoEncoder->SetSizeOfEditAndContinuePreservedArea(preservedAreaSize);
}
-#endif
gcInfoEncoder->Build();
@@ -7249,58 +6140,6 @@ void CodeGen::genEmitHelperCall(unsigned helper, int argSize, emitAttr retSize,
regTracker.rsTrashRegsForGCInterruptability();
}
-/*****************************************************************************/
-#ifdef DEBUGGING_SUPPORT
-/*****************************************************************************
- * genSetScopeInfo
- *
- * Called for every scope info piece to record by the main genSetScopeInfo()
- */
-
-// TODO-Cleanup: move to CodeGenCommon.cpp
-void CodeGen::genSetScopeInfo(unsigned which,
- UNATIVE_OFFSET startOffs,
- UNATIVE_OFFSET length,
- unsigned varNum,
- unsigned LVnum,
- bool avail,
- Compiler::siVarLoc& varLoc)
-{
- /* We need to do some mapping while reporting back these variables */
-
- unsigned ilVarNum = compiler->compMap2ILvarNum(varNum);
- noway_assert((int)ilVarNum != ICorDebugInfo::UNKNOWN_ILNUM);
-
- VarName name = nullptr;
-
-#ifdef DEBUG
-
- for (unsigned scopeNum = 0; scopeNum < compiler->info.compVarScopesCount; scopeNum++)
- {
- if (LVnum == compiler->info.compVarScopes[scopeNum].vsdLVnum)
- {
- name = compiler->info.compVarScopes[scopeNum].vsdName;
- }
- }
-
- // Hang on to this compiler->info.
-
- TrnslLocalVarInfo& tlvi = genTrnslLocalVarInfo[which];
-
- tlvi.tlviVarNum = ilVarNum;
- tlvi.tlviLVnum = LVnum;
- tlvi.tlviName = name;
- tlvi.tlviStartPC = startOffs;
- tlvi.tlviLength = length;
- tlvi.tlviAvailable = avail;
- tlvi.tlviVarLoc = varLoc;
-
-#endif // DEBUG
-
- compiler->eeSetLVinfo(which, startOffs, length, ilVarNum, LVnum, name, avail, varLoc);
-}
-#endif // DEBUGGING_SUPPORT
-
/*****************************************************************************
* Unit testing of the ARM64 emitter: generate a bunch of instructions into the prolog
* (it's as good a place as any), then use COMPlus_JitLateDisasm=* to see if the late
diff --git a/src/jit/codegenclassic.h b/src/jit/codegenclassic.h
index 81b7b34194..3a88c83915 100644
--- a/src/jit/codegenclassic.h
+++ b/src/jit/codegenclassic.h
@@ -63,10 +63,6 @@ void genPInvokeCallEpilog(LclVarDsc* varDsc, regMaskTP retVal);
regNumber genLclHeap(GenTreePtr size);
-void genSinglePush();
-
-void genSinglePop();
-
void genDyingVars(VARSET_VALARG_TP beforeSet, VARSET_VALARG_TP afterSet);
bool genContainsVarDeath(GenTreePtr from, GenTreePtr to, unsigned varNum);
@@ -287,9 +283,6 @@ void genCodeForJumpTable(GenTreePtr tree);
void genCodeForSwitchTable(GenTreePtr tree);
void genCodeForSwitch(GenTreePtr tree);
-regMaskTP genPushRegs(regMaskTP regs, regMaskTP* byrefRegs, regMaskTP* noRefRegs);
-void genPopRegs(regMaskTP regs, regMaskTP byrefRegs, regMaskTP noRefRegs);
-
size_t genPushArgList(GenTreePtr call);
#ifdef _TARGET_ARM_
diff --git a/src/jit/codegencommon.cpp b/src/jit/codegencommon.cpp
index 2710447ade..240911523f 100755..100644
--- a/src/jit/codegencommon.cpp
+++ b/src/jit/codegencommon.cpp
@@ -103,6 +103,10 @@ CodeGen::CodeGen(Compiler* theCompiler) : CodeGenInterface(theCompiler)
u8ToDblBitmask = nullptr;
#endif // defined(_TARGET_XARCH_) && !FEATURE_STACK_FP_X87
+#if defined(FEATURE_PUT_STRUCT_ARG_STK) && !defined(_TARGET_X86_)
+ m_stkArgVarNum = BAD_VAR_NUM;
+#endif
+
regTracker.rsTrackInit(compiler, &regSet);
gcInfo.regSet = &regSet;
m_cgEmitter = new (compiler->getAllocator()) emitter();
@@ -163,12 +167,10 @@ CodeGen::CodeGen(Compiler* theCompiler) : CodeGenInterface(theCompiler)
genFlagsEqualToNone();
#endif // LEGACY_BACKEND
-#ifdef DEBUGGING_SUPPORT
// Initialize the IP-mapping logic.
compiler->genIPmappingList = nullptr;
compiler->genIPmappingLast = nullptr;
compiler->genCallSite2ILOffsetMap = nullptr;
-#endif
/* Assume that we not fully interruptible */
@@ -359,7 +361,7 @@ void CodeGen::genPrepForCompiler()
{
VarSetOps::AddElemD(compiler, compiler->raRegVarsMask, varDsc->lvVarIndex);
}
- else if (compiler->lvaIsGCTracked(varDsc) && (!varDsc->lvIsParam || varDsc->lvIsRegArg))
+ else if (compiler->lvaIsGCTracked(varDsc))
{
VarSetOps::AddElemD(compiler, gcInfo.gcTrkStkPtrLcls, varDsc->lvVarIndex);
}
@@ -646,23 +648,32 @@ regMaskTP Compiler::compHelperCallKillSet(CorInfoHelpFunc helper)
return RBM_RSI | RBM_RDI | RBM_CALLEE_TRASH;
#elif defined(_TARGET_ARM64_)
return RBM_CALLEE_TRASH_NOGC;
+#elif defined(_TARGET_X86_)
+ return RBM_ESI | RBM_EDI | RBM_ECX;
#else
NYI("Model kill set for CORINFO_HELP_ASSIGN_BYREF on target arch");
return RBM_CALLEE_TRASH;
#endif
case CORINFO_HELP_PROF_FCN_ENTER:
-#ifdef _TARGET_AMD64_
+#ifdef RBM_PROFILER_ENTER_TRASH
return RBM_PROFILER_ENTER_TRASH;
#else
- unreached();
+ NYI("Model kill set for CORINFO_HELP_PROF_FCN_ENTER on target arch");
#endif
+
case CORINFO_HELP_PROF_FCN_LEAVE:
- case CORINFO_HELP_PROF_FCN_TAILCALL:
-#ifdef _TARGET_AMD64_
+#ifdef RBM_PROFILER_LEAVE_TRASH
return RBM_PROFILER_LEAVE_TRASH;
#else
- unreached();
+ NYI("Model kill set for CORINFO_HELP_PROF_FCN_LEAVE on target arch");
+#endif
+
+ case CORINFO_HELP_PROF_FCN_TAILCALL:
+#ifdef RBM_PROFILER_TAILCALL_TRASH
+ return RBM_PROFILER_TAILCALL_TRASH;
+#else
+ NYI("Model kill set for CORINFO_HELP_PROF_FCN_TAILCALL on target arch");
#endif
case CORINFO_HELP_STOP_FOR_GC:
@@ -685,26 +696,34 @@ regMaskTP Compiler::compHelperCallKillSet(CorInfoHelpFunc helper)
regMaskTP Compiler::compNoGCHelperCallKillSet(CorInfoHelpFunc helper)
{
assert(emitter::emitNoGChelper(helper));
-#ifdef _TARGET_AMD64_
+
switch (helper)
{
+#if defined(_TARGET_AMD64_) || defined(_TARGET_X86_)
case CORINFO_HELP_PROF_FCN_ENTER:
return RBM_PROFILER_ENTER_TRASH;
case CORINFO_HELP_PROF_FCN_LEAVE:
- case CORINFO_HELP_PROF_FCN_TAILCALL:
return RBM_PROFILER_LEAVE_TRASH;
+ case CORINFO_HELP_PROF_FCN_TAILCALL:
+ return RBM_PROFILER_TAILCALL_TRASH;
+#endif // defined(_TARGET_AMD64_) || defined(_TARGET_X86_)
+
case CORINFO_HELP_ASSIGN_BYREF:
+#if defined(_TARGET_AMD64_)
// this helper doesn't trash RSI and RDI
return RBM_CALLEE_TRASH_NOGC & ~(RBM_RSI | RBM_RDI);
+#elif defined(_TARGET_X86_)
+ // This helper only trashes ECX.
+ return RBM_ECX;
+#else
+ return RBM_CALLEE_TRASH_NOGC;
+#endif // defined(_TARGET_AMD64_)
default:
return RBM_CALLEE_TRASH_NOGC;
}
-#else
- return RBM_CALLEE_TRASH_NOGC;
-#endif
}
// Update liveness (always var liveness, i.e., compCurLife, and also, if "ForCodeGen" is true, reg liveness, i.e.,
@@ -1004,9 +1023,7 @@ void Compiler::compUpdateLifeVar(GenTreePtr tree, VARSET_TP* pLastUseVars)
#endif // LEGACY_BACKEND
-#ifdef DEBUGGING_SUPPORT
codeGen->siUpdate();
-#endif
}
}
@@ -1172,9 +1189,7 @@ void Compiler::compChangeLife(VARSET_VALARG_TP newLife DEBUGARG(GenTreePtr tree)
#endif // !LEGACY_BACKEND
}
-#ifdef DEBUGGING_SUPPORT
codeGen->siUpdate();
-#endif
}
// Need an explicit instantiation.
@@ -1626,6 +1641,44 @@ void CodeGen::genAdjustSP(ssize_t delta)
inst_RV_IV(INS_add, REG_SPBASE, delta, EA_PTRSIZE);
}
+//------------------------------------------------------------------------
+// genAdjustStackLevel: Adjust the stack level, if required, for a throw helper block
+//
+// Arguments:
+// block - The BasicBlock for which we are about to generate code.
+//
+// Assumptions:
+// Must be called just prior to generating code for 'block'.
+//
+// Notes:
+// This only makes an adjustment if !FEATURE_FIXED_OUT_ARGS, if there is no frame pointer,
+// and if 'block' is a throw helper block with a non-zero stack level.
+
+void CodeGen::genAdjustStackLevel(BasicBlock* block)
+{
+#if !FEATURE_FIXED_OUT_ARGS
+ // Check for inserted throw blocks and adjust genStackLevel.
+
+ if (!isFramePointerUsed() && compiler->fgIsThrowHlpBlk(block))
+ {
+ noway_assert(block->bbFlags & BBF_JMP_TARGET);
+
+ genStackLevel = 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;
+#else // _TARGET_X86_
+ NYI("Need emitMarkStackLvl()");
+#endif // _TARGET_X86_
+ }
+ }
+#endif // !FEATURE_FIXED_OUT_ARGS
+}
+
#ifdef _TARGET_ARM_
// return size
// alignmentWB is out param
@@ -2539,14 +2592,12 @@ emitJumpKind CodeGen::genJumpKindForOper(genTreeOps cmp, CompareKind compareKind
void CodeGen::genExitCode(BasicBlock* block)
{
-#ifdef DEBUGGING_SUPPORT
/* Just wrote the first instruction of the epilog - inform debugger
Note that this may result in a duplicate IPmapping entry, and
that this is ok */
// For non-optimized debuggable code, there is only one epilog.
genIPmappingAdd((IL_OFFSETX)ICorDebugInfo::EPILOG, true);
-#endif // DEBUGGING_SUPPORT
bool jmpEpilog = ((block->bbFlags & BBF_HAS_JMP) != 0);
if (compiler->getNeedsGSSecurityCookie())
@@ -2968,7 +3019,7 @@ void CodeGen::genGenerateCode(void** codePtr, ULONG* nativeSizeOfCode)
#if defined(DEBUG)
,
(compiler->compCodeOpt() != Compiler::SMALL_CODE) &&
- !(compiler->opts.eeFlags & CORJIT_FLG_PREJIT)
+ !compiler->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT)
#endif
#ifdef LEGACY_BACKEND
,
@@ -3095,7 +3146,8 @@ void CodeGen::genGenerateCode(void** codePtr, ULONG* nativeSizeOfCode)
We need to relax the assert as our estimation won't include code-gen
stack changes (which we know don't affect fgAddCodeRef()) */
noway_assert(getEmitter()->emitMaxStackDepth <=
- (compiler->fgPtrArgCntMax + compiler->compHndBBtabCount + // Return address for locally-called finallys
+ (compiler->fgPtrArgCntMax + // Max number of pointer-sized stack arguments.
+ compiler->compHndBBtabCount + // Return address for locally-called finallys
genTypeStSz(TYP_LONG) + // longs/doubles may be transferred via stack, etc
(compiler->compTailCallUsed ? 4 : 0))); // CORINFO_HELP_TAILCALL args
#endif
@@ -3116,8 +3168,6 @@ void CodeGen::genGenerateCode(void** codePtr, ULONG* nativeSizeOfCode)
compiler->unwindEmit(*codePtr, coldCodePtr);
-#ifdef DEBUGGING_SUPPORT
-
/* Finalize the line # tracking logic after we know the exact block sizes/offsets */
genIPmappingGen();
@@ -3126,8 +3176,6 @@ void CodeGen::genGenerateCode(void** codePtr, ULONG* nativeSizeOfCode)
genSetScopeInfo();
-#endif // DEBUGGING_SUPPORT
-
#ifdef LATE_DISASM
unsigned finalHotCodeSize;
unsigned finalColdCodeSize;
@@ -3272,6 +3320,8 @@ void CodeGen::genReportEH()
EHblkDsc* HBtab;
EHblkDsc* HBtabEnd;
+ bool isCoreRTABI = compiler->IsTargetAbi(CORINFO_CORERT_ABI);
+
unsigned EHCount = compiler->compHndBBtabCount;
#if FEATURE_EH_FUNCLETS
@@ -3279,46 +3329,55 @@ void CodeGen::genReportEH()
// VM.
unsigned duplicateClauseCount = 0;
unsigned enclosingTryIndex;
- for (XTnum = 0; XTnum < compiler->compHndBBtabCount; XTnum++)
+
+ // Duplicate clauses are not used by CoreRT ABI
+ if (!isCoreRTABI)
{
- for (enclosingTryIndex = compiler->ehTrueEnclosingTryIndexIL(XTnum); // find the true enclosing try index,
- // ignoring 'mutual protect' trys
- enclosingTryIndex != EHblkDsc::NO_ENCLOSING_INDEX;
- enclosingTryIndex = compiler->ehGetEnclosingTryIndex(enclosingTryIndex))
+ for (XTnum = 0; XTnum < compiler->compHndBBtabCount; XTnum++)
{
- ++duplicateClauseCount;
+ for (enclosingTryIndex = compiler->ehTrueEnclosingTryIndexIL(XTnum); // find the true enclosing try index,
+ // ignoring 'mutual protect' trys
+ enclosingTryIndex != EHblkDsc::NO_ENCLOSING_INDEX;
+ enclosingTryIndex = compiler->ehGetEnclosingTryIndex(enclosingTryIndex))
+ {
+ ++duplicateClauseCount;
+ }
}
+ EHCount += duplicateClauseCount;
}
- EHCount += duplicateClauseCount;
#if FEATURE_EH_CALLFINALLY_THUNKS
unsigned clonedFinallyCount = 0;
- // We don't keep track of how many cloned finally there are. So, go through and count.
- // We do a quick pass first through the EH table to see if there are any try/finally
- // clauses. If there aren't, we don't need to look for BBJ_CALLFINALLY.
-
- bool anyFinallys = false;
- for (HBtab = compiler->compHndBBtab, HBtabEnd = compiler->compHndBBtab + compiler->compHndBBtabCount;
- HBtab < HBtabEnd; HBtab++)
+ // Duplicate clauses are not used by CoreRT ABI
+ if (!isCoreRTABI)
{
- if (HBtab->HasFinallyHandler())
+ // We don't keep track of how many cloned finally there are. So, go through and count.
+ // We do a quick pass first through the EH table to see if there are any try/finally
+ // clauses. If there aren't, we don't need to look for BBJ_CALLFINALLY.
+
+ bool anyFinallys = false;
+ for (HBtab = compiler->compHndBBtab, HBtabEnd = compiler->compHndBBtab + compiler->compHndBBtabCount;
+ HBtab < HBtabEnd; HBtab++)
{
- anyFinallys = true;
- break;
+ if (HBtab->HasFinallyHandler())
+ {
+ anyFinallys = true;
+ break;
+ }
}
- }
- if (anyFinallys)
- {
- for (BasicBlock* block = compiler->fgFirstBB; block != nullptr; block = block->bbNext)
+ if (anyFinallys)
{
- if (block->bbJumpKind == BBJ_CALLFINALLY)
+ for (BasicBlock* block = compiler->fgFirstBB; block != nullptr; block = block->bbNext)
{
- ++clonedFinallyCount;
+ if (block->bbJumpKind == BBJ_CALLFINALLY)
+ {
+ ++clonedFinallyCount;
+ }
}
- }
- EHCount += clonedFinallyCount;
+ EHCount += clonedFinallyCount;
+ }
}
#endif // FEATURE_EH_CALLFINALLY_THUNKS
@@ -3373,6 +3432,23 @@ void CodeGen::genReportEH()
CORINFO_EH_CLAUSE_FLAGS flags = ToCORINFO_EH_CLAUSE_FLAGS(HBtab->ebdHandlerType);
+ if (isCoreRTABI && (XTnum > 0))
+ {
+ // For CoreRT, CORINFO_EH_CLAUSE_SAMETRY flag means that the current clause covers same
+ // try block as the previous one. The runtime cannot reliably infer this information from
+ // native code offsets because of different try blocks can have same offsets. Alternative
+ // solution to this problem would be inserting extra nops to ensure that different try
+ // blocks have different offsets.
+ if (EHblkDsc::ebdIsSameTry(HBtab, HBtab - 1))
+ {
+ // The SAMETRY bit should only be set on catch clauses. This is ensured in IL, where only 'catch' is
+ // allowed to be mutually-protect. E.g., the C# "try {} catch {} catch {} finally {}" actually exists in
+ // IL as "try { try {} catch {} catch {} } finally {}".
+ assert(HBtab->HasCatchHandler());
+ flags = (CORINFO_EH_CLAUSE_FLAGS)(flags | CORINFO_EH_CLAUSE_SAMETRY);
+ }
+ }
+
// Note that we reuse the CORINFO_EH_CLAUSE type, even though the names of
// the fields aren't accurate.
@@ -3578,9 +3654,7 @@ void CodeGen::genReportEH()
CORINFO_EH_CLAUSE_FLAGS flags = ToCORINFO_EH_CLAUSE_FLAGS(encTab->ebdHandlerType);
// Tell the VM this is an extra clause caused by moving funclets out of line.
- // It seems weird this is from the CorExceptionFlag enum in corhdr.h,
- // not the CORINFO_EH_CLAUSE_FLAGS enum in corinfo.h.
- flags = (CORINFO_EH_CLAUSE_FLAGS)(flags | COR_ILEXCEPTION_CLAUSE_DUPLICATED);
+ flags = (CORINFO_EH_CLAUSE_FLAGS)(flags | CORINFO_EH_CLAUSE_DUPLICATE);
// Note that the JIT-EE interface reuses the CORINFO_EH_CLAUSE type, even though the names of
// the fields aren't really accurate. For example, we set "TryLength" to the offset of the
@@ -3617,7 +3691,7 @@ void CodeGen::genReportEH()
} // if (duplicateClauseCount > 0)
#if FEATURE_EH_CALLFINALLY_THUNKS
- if (anyFinallys)
+ if (clonedFinallyCount > 0)
{
unsigned reportedClonedFinallyCount = 0;
for (BasicBlock* block = compiler->fgFirstBB; block != nullptr; block = block->bbNext)
@@ -3647,9 +3721,9 @@ void CodeGen::genReportEH()
CORINFO_EH_CLAUSE clause;
clause.ClassToken = 0; // unused
- clause.Flags = (CORINFO_EH_CLAUSE_FLAGS)(CORINFO_EH_CLAUSE_FINALLY | COR_ILEXCEPTION_CLAUSE_DUPLICATED);
- clause.TryOffset = hndBeg;
- clause.TryLength = hndBeg;
+ clause.Flags = (CORINFO_EH_CLAUSE_FLAGS)(CORINFO_EH_CLAUSE_FINALLY | CORINFO_EH_CLAUSE_DUPLICATE);
+ clause.TryOffset = hndBeg;
+ clause.TryLength = hndBeg;
clause.HandlerOffset = hndBeg;
clause.HandlerLength = hndEnd;
@@ -3671,7 +3745,7 @@ void CodeGen::genReportEH()
} // for each block
assert(clonedFinallyCount == reportedClonedFinallyCount);
- } // if (anyFinallys)
+ } // if (clonedFinallyCount > 0)
#endif // FEATURE_EH_CALLFINALLY_THUNKS
#endif // FEATURE_EH_FUNCLETS
@@ -6995,12 +7069,12 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg,
noway_assert(varTypeIsGC(varDsc->TypeGet()) || (varDsc->TypeGet() == TYP_STRUCT) ||
compiler->info.compInitMem || compiler->opts.compDbgCode);
-#ifdef _TARGET_64BIT_
+#ifndef LEGACY_BACKEND
if (!varDsc->lvOnFrame)
{
continue;
}
-#else // !_TARGET_64BIT_
+#else // LEGACY_BACKEND
if (varDsc->lvRegister)
{
if (varDsc->lvOnFrame)
@@ -7016,7 +7090,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg,
}
continue;
}
-#endif // !_TARGET_64BIT_
+#endif // LEGACY_BACKEND
if ((varDsc->TypeGet() == TYP_STRUCT) && !compiler->info.compInitMem &&
(varDsc->lvExactSize >= TARGET_POINTER_SIZE))
@@ -7221,11 +7295,31 @@ void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegZeroed)
#ifdef PROFILING_SUPPORTED
-/*-----------------------------------------------------------------------------
- *
- * Generate the profiling function enter callback.
- */
-
+//-----------------------------------------------------------------------------------
+// genProfilingEnterCallback: Generate the profiling function enter callback.
+//
+// Arguments:
+// initReg - register to use as scratch register
+// pInitRegZeroed - OUT parameter. *pInitRegZeroed set to 'false' if 'initReg' is
+// not zero after this call.
+//
+// Return Value:
+// None
+//
+// Notes:
+// The x86 profile enter helper has the following requirements (see ProfileEnterNaked in
+// VM\i386\asmhelpers.asm for details):
+// 1. The calling sequence for calling the helper is:
+// push FunctionIDOrClientID
+// call ProfileEnterHelper
+// 2. The calling function has an EBP frame.
+// 3. EBP points to the saved ESP which is the first thing saved in the function. Thus,
+// the following prolog is assumed:
+// push ESP
+// mov EBP, ESP
+// 4. All registers are preserved.
+// 5. The helper pops the FunctionIDOrClientID argument from the stack.
+//
void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
{
assert(compiler->compGeneratingProlog);
@@ -7236,7 +7330,6 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
return;
}
-#ifndef LEGACY_BACKEND
#if defined(_TARGET_AMD64_) && !defined(UNIX_AMD64_ABI) // No profiling for System V systems yet.
unsigned varNum;
LclVarDsc* varDsc;
@@ -7280,7 +7373,7 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
else
{
// No need to record relocations, if we are generating ELT hooks under the influence
- // of complus_JitELtHookEnabled=1
+ // of COMPlus_JitELTHookEnabled=1
if (compiler->opts.compJitELTHookEnabled)
{
genSetRegToIcon(REG_ARG_0, (ssize_t)compiler->compProfilerMethHnd, TYP_I_IMPL);
@@ -7346,11 +7439,7 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
*pInitRegZeroed = false;
}
-#else //!_TARGET_AMD64_
- NYI("RyuJIT: Emit Profiler Enter callback");
-#endif
-
-#else // LEGACY_BACKEND
+#elif defined(_TARGET_X86_) || (defined(_TARGET_ARM_) && defined(LEGACY_BACKEND))
unsigned saveStackLvl2 = genStackLevel;
@@ -7423,17 +7512,41 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
/* Restore the stack level */
genStackLevel = saveStackLvl2;
-#endif // LEGACY_BACKEND
-}
-/*****************************************************************************
- *
- * Generates Leave profiler hook.
- * Technically, this is not part of the epilog; it is called when we are generating code for a GT_RETURN node.
- */
+#else // target
+ NYI("Emit Profiler Enter callback");
+#endif // target
+}
+//-----------------------------------------------------------------------------------
+// genProfilingLeaveCallback: Generate the profiling function leave or tailcall callback.
+// Technically, this is not part of the epilog; it is called when we are generating code for a GT_RETURN node.
+//
+// Arguments:
+// helper - which helper to call. Either CORINFO_HELP_PROF_FCN_LEAVE or CORINFO_HELP_PROF_FCN_TAILCALL
+//
+// Return Value:
+// None
+//
+// Notes:
+// The x86 profile leave/tailcall helper has the following requirements (see ProfileLeaveNaked and
+// ProfileTailcallNaked in VM\i386\asmhelpers.asm for details):
+// 1. The calling sequence for calling the helper is:
+// push FunctionIDOrClientID
+// call ProfileLeaveHelper or ProfileTailcallHelper
+// 2. The calling function has an EBP frame.
+// 3. EBP points to the saved ESP which is the first thing saved in the function. Thus,
+// the following prolog is assumed:
+// push ESP
+// mov EBP, ESP
+// 4. helper == CORINFO_HELP_PROF_FCN_LEAVE: All registers are preserved.
+// helper == CORINFO_HELP_PROF_FCN_TAILCALL: Only argument registers are preserved.
+// 5. The helper pops the FunctionIDOrClientID argument from the stack.
+//
void CodeGen::genProfilingLeaveCallback(unsigned helper /*= CORINFO_HELP_PROF_FCN_LEAVE*/)
{
+ assert((helper == CORINFO_HELP_PROF_FCN_LEAVE) || (helper == CORINFO_HELP_PROF_FCN_TAILCALL));
+
// Only hook if profiler says it's okay.
if (!compiler->compIsProfilerHookNeeded())
{
@@ -7442,12 +7555,11 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper /*= CORINFO_HELP_PROF_FC
compiler->info.compProfilerCallback = true;
- // Need to save on to the stack level, since the callee will pop the argument
+ // Need to save on to the stack level, since the helper call will pop the argument
unsigned saveStackLvl2 = genStackLevel;
-#ifndef LEGACY_BACKEND
-
#if defined(_TARGET_AMD64_) && !defined(UNIX_AMD64_ABI) // No profiling for System V systems yet.
+
// Since the method needs to make a profiler callback, it should have out-going arg space allocated.
noway_assert(compiler->lvaOutgoingArgSpaceVar != BAD_VAR_NUM);
noway_assert(compiler->lvaOutgoingArgSpaceSize >= (4 * REGSIZE_BYTES));
@@ -7477,7 +7589,7 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper /*= CORINFO_HELP_PROF_FC
else
{
// Don't record relocations, if we are generating ELT hooks under the influence
- // of complus_JitELtHookEnabled=1
+ // of COMPlus_JitELTHookEnabled=1
if (compiler->opts.compJitELTHookEnabled)
{
genSetRegToIcon(REG_ARG_0, (ssize_t)compiler->compProfilerMethHnd, TYP_I_IMPL);
@@ -7517,13 +7629,8 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper /*= CORINFO_HELP_PROF_FC
// "mov r8, helper addr; call r8"
genEmitHelperCall(helper, 0, EA_UNKNOWN, REG_ARG_2);
-#else //!_TARGET_AMD64_
- NYI("RyuJIT: Emit Profiler Leave callback");
-#endif // _TARGET_*
-
-#else // LEGACY_BACKEND
+#elif defined(_TARGET_X86_)
-#if defined(_TARGET_X86_)
//
// Push the profilerHandle
//
@@ -7538,7 +7645,7 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper /*= CORINFO_HELP_PROF_FC
}
genSinglePush();
- genEmitHelperCall(CORINFO_HELP_PROF_FCN_LEAVE,
+ genEmitHelperCall(helper,
sizeof(int) * 1, // argSize
EA_UNKNOWN); // retSize
@@ -7549,7 +7656,9 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper /*= CORINFO_HELP_PROF_FC
{
compiler->fgPtrArgCntMax = 1;
}
-#elif defined(_TARGET_ARM_)
+
+#elif defined(LEGACY_BACKEND) && defined(_TARGET_ARM_)
+
//
// Push the profilerHandle
//
@@ -7571,9 +7680,9 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper /*= CORINFO_HELP_PROF_FC
bool r0Trashed;
emitAttr attr = EA_UNKNOWN;
- if (compiler->info.compRetType == TYP_VOID ||
- (!compiler->info.compIsVarArgs && !compiler->opts.compUseSoftFP && (varTypeIsFloating(compiler->info.compRetType) ||
- compiler->IsHfa(compiler->info.compMethodInfo->args.retTypeClass))))
+ if (compiler->info.compRetType == TYP_VOID || (!compiler->info.compIsVarArgs && !compiler->opts.compUseSoftFP &&
+ (varTypeIsFloating(compiler->info.compRetType) ||
+ compiler->IsHfa(compiler->info.compMethodInfo->args.retTypeClass))))
{
r0Trashed = false;
}
@@ -7625,11 +7734,10 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper /*= CORINFO_HELP_PROF_FC
}
regSet.rsUnlockReg(RBM_PROFILER_RET_USED);
-#else // _TARGET_*
- NYI("Pushing the profilerHandle & caller's sp for the profiler callout and locking them");
-#endif // _TARGET_*
-#endif // LEGACY_BACKEND
+#else // target
+ NYI("Emit Profiler Leave callback");
+#endif // target
/* Restore the stack level */
genStackLevel = saveStackLvl2;
@@ -7741,7 +7849,7 @@ void CodeGen::genPrologPadForReJit()
assert(compiler->compGeneratingProlog);
#ifdef _TARGET_XARCH_
- if (!(compiler->opts.eeFlags & CORJIT_FLG_PROF_REJIT_NOPS))
+ if (!compiler->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PROF_REJIT_NOPS))
{
return;
}
@@ -8165,11 +8273,9 @@ void CodeGen::genFnProlog()
getEmitter()->emitBegProlog();
compiler->unwindBegProlog();
-#ifdef DEBUGGING_SUPPORT
// Do this so we can put the prolog instruction group ahead of
// other instruction groups
genIPmappingAddToFront((IL_OFFSETX)ICorDebugInfo::PROLOG);
-#endif // DEBUGGING_SUPPORT
#ifdef DEBUG
if (compiler->opts.dspCode)
@@ -8178,13 +8284,11 @@ void CodeGen::genFnProlog()
}
#endif
-#ifdef DEBUGGING_SUPPORT
if (compiler->opts.compScopeInfo && (compiler->info.compVarScopesCount > 0))
{
// Create new scopes for the method-parameters for the prolog-block.
psiBegProlog();
}
-#endif
#ifdef DEBUG
@@ -8664,12 +8768,6 @@ void CodeGen::genFnProlog()
// when compInitMem is true the genZeroInitFrame will zero out the shadow SP slots
if (compiler->ehNeedsShadowSPslots() && !compiler->info.compInitMem)
{
- /*
- // size/speed option?
- getEmitter()->emitIns_I_ARR(INS_mov, EA_PTRSIZE, 0,
- REG_EBP, REG_NA, -compiler->lvaShadowSPfirstOffs);
- */
-
// The last slot is reserved for ICodeManager::FixContext(ppEndRegion)
unsigned filterEndOffsetSlotOffs = compiler->lvaLclSize(compiler->lvaShadowSPslotsVar) - (sizeof(void*));
@@ -8707,9 +8805,8 @@ void CodeGen::genFnProlog()
// Initialize any "hidden" slots/locals
- if (compiler->compLocallocUsed)
+ if (compiler->lvaLocAllocSPvar != BAD_VAR_NUM)
{
- noway_assert(compiler->lvaLocAllocSPvar != BAD_VAR_NUM);
#ifdef _TARGET_ARM64_
getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, REG_FPBASE, compiler->lvaLocAllocSPvar, 0);
#else
@@ -8870,12 +8967,10 @@ void CodeGen::genFnProlog()
getEmitter()->emitMarkPrologEnd();
}
-#ifdef DEBUGGING_SUPPORT
if (compiler->opts.compScopeInfo && (compiler->info.compVarScopesCount > 0))
{
psiEndProlog();
}
-#endif
if (hasGCRef)
{
@@ -8927,7 +9022,7 @@ void CodeGen::genFnProlog()
// LEA EAX, &<VARARGS HANDLE> + EAX
getEmitter()->emitIns_R_ARR(INS_lea, EA_PTRSIZE, REG_EAX, genFramePointerReg(), REG_EAX, offset);
- if (varDsc->lvRegister)
+ if (varDsc->lvIsInReg())
{
if (varDsc->lvRegNum != REG_EAX)
{
@@ -9637,7 +9732,7 @@ void CodeGen::genFnEpilog(BasicBlock* block)
* |Pre-spill regs space | // This is only necessary to keep the PSP slot at the same offset
* | | // in function and funclet
* |-----------------------|
- * | PSP slot |
+ * | PSP slot | // Omitted in CoreRT ABI
* |-----------------------|
* ~ possible 4 byte pad ~
* ~ for alignment ~
@@ -9936,7 +10031,7 @@ void CodeGen::genCaptureFuncletPrologEpilogInfo()
* ~ possible 8 byte pad ~
* ~ for alignment ~
* |-----------------------|
- * | PSP slot |
+ * | PSP slot | // Omitted in CoreRT ABI
* |-----------------------|
* | Outgoing arg space | // this only exists if the function makes a call
* |-----------------------| <---- Initial SP
@@ -10007,6 +10102,12 @@ void CodeGen::genFuncletProlog(BasicBlock* block)
// This is the end of the OS-reported prolog for purposes of unwinding
compiler->unwindEndProlog();
+ // If there is no PSPSym (CoreRT ABI), we are done.
+ if (compiler->lvaPSPSym == BAD_VAR_NUM)
+ {
+ return;
+ }
+
getEmitter()->emitIns_R_AR(INS_mov, EA_PTRSIZE, REG_FPBASE, REG_ARG_0, genFuncletInfo.fiPSP_slot_InitialSP_offset);
regTracker.rsTrackRegTrash(REG_FPBASE);
@@ -10100,10 +10201,12 @@ void CodeGen::genCaptureFuncletPrologEpilogInfo()
unsigned calleeFPRegsSavedSize = genCountBits(compiler->compCalleeFPRegsSavedMask) * XMM_REGSIZE_BYTES;
unsigned FPRegsPad = (calleeFPRegsSavedSize > 0) ? AlignmentPad(totalFrameSize, XMM_REGSIZE_BYTES) : 0;
+ unsigned PSPSymSize = (compiler->lvaPSPSym != BAD_VAR_NUM) ? REGSIZE_BYTES : 0;
+
totalFrameSize += FPRegsPad // Padding before pushing entire xmm regs
+ calleeFPRegsSavedSize // pushed callee-saved float regs
// below calculated 'pad' will go here
- + REGSIZE_BYTES // PSPSym
+ + PSPSymSize // PSPSym
+ compiler->lvaOutgoingArgSpaceSize // outgoing arg space
;
@@ -10111,7 +10214,7 @@ void CodeGen::genCaptureFuncletPrologEpilogInfo()
genFuncletInfo.fiSpDelta = FPRegsPad // Padding to align SP on XMM_REGSIZE_BYTES boundary
+ calleeFPRegsSavedSize // Callee saved xmm regs
- + pad + REGSIZE_BYTES // PSPSym
+ + pad + PSPSymSize // PSPSym
+ compiler->lvaOutgoingArgSpaceSize // outgoing arg space
;
@@ -10124,12 +10227,14 @@ void CodeGen::genCaptureFuncletPrologEpilogInfo()
printf(" SP delta: %d\n", genFuncletInfo.fiSpDelta);
printf(" PSP slot Initial SP offset: %d\n", genFuncletInfo.fiPSP_slot_InitialSP_offset);
}
-#endif // DEBUG
- assert(compiler->lvaPSPSym != BAD_VAR_NUM);
- assert(genFuncletInfo.fiPSP_slot_InitialSP_offset ==
- compiler->lvaGetInitialSPRelativeOffset(compiler->lvaPSPSym)); // same offset used in main function and
- // funclet!
+ if (compiler->lvaPSPSym != BAD_VAR_NUM)
+ {
+ assert(genFuncletInfo.fiPSP_slot_InitialSP_offset ==
+ compiler->lvaGetInitialSPRelativeOffset(compiler->lvaPSPSym)); // same offset used in main function and
+ // funclet!
+ }
+#endif // DEBUG
}
#elif defined(_TARGET_ARM64_)
@@ -10249,13 +10354,12 @@ void CodeGen::genSetPSPSym(regNumber initReg, bool* pInitRegZeroed)
{
assert(compiler->compGeneratingProlog);
- if (!compiler->ehNeedsPSPSym())
+ if (compiler->lvaPSPSym == BAD_VAR_NUM)
{
return;
}
- noway_assert(isFramePointerUsed()); // We need an explicit frame pointer
- assert(compiler->lvaPSPSym != BAD_VAR_NUM); // We should have created the PSPSym variable
+ noway_assert(isFramePointerUsed()); // We need an explicit frame pointer
#if defined(_TARGET_ARM_)
@@ -10851,8 +10955,162 @@ unsigned CodeGen::getFirstArgWithStackSlot()
#endif // !LEGACY_BACKEND && (_TARGET_XARCH_ || _TARGET_ARM64_)
-/*****************************************************************************/
-#ifdef DEBUGGING_SUPPORT
+//------------------------------------------------------------------------
+// genSinglePush: Report a change in stack level caused by a single word-sized push instruction
+//
+void CodeGen::genSinglePush()
+{
+ genStackLevel += sizeof(void*);
+}
+
+//------------------------------------------------------------------------
+// genSinglePop: Report a change in stack level caused by a single word-sized pop instruction
+//
+void CodeGen::genSinglePop()
+{
+ genStackLevel -= sizeof(void*);
+}
+
+//------------------------------------------------------------------------
+// genPushRegs: Push the given registers.
+//
+// Arguments:
+// regs - mask or registers to push
+// byrefRegs - OUT arg. Set to byref registers that were pushed.
+// noRefRegs - OUT arg. Set to non-GC ref registers that were pushed.
+//
+// Return Value:
+// Mask of registers pushed.
+//
+// Notes:
+// This function does not check if the register is marked as used, etc.
+//
+regMaskTP CodeGen::genPushRegs(regMaskTP regs, regMaskTP* byrefRegs, regMaskTP* noRefRegs)
+{
+ *byrefRegs = RBM_NONE;
+ *noRefRegs = RBM_NONE;
+
+ if (regs == RBM_NONE)
+ {
+ return RBM_NONE;
+ }
+
+#if FEATURE_FIXED_OUT_ARGS
+
+ NYI("Don't call genPushRegs with real regs!");
+ return RBM_NONE;
+
+#else // FEATURE_FIXED_OUT_ARGS
+
+ noway_assert(genTypeStSz(TYP_REF) == genTypeStSz(TYP_I_IMPL));
+ noway_assert(genTypeStSz(TYP_BYREF) == genTypeStSz(TYP_I_IMPL));
+
+ regMaskTP pushedRegs = regs;
+
+ for (regNumber reg = REG_INT_FIRST; regs != RBM_NONE; reg = REG_NEXT(reg))
+ {
+ regMaskTP regBit = regMaskTP(1) << reg;
+
+ if ((regBit & regs) == RBM_NONE)
+ continue;
+
+ var_types type;
+ if (regBit & gcInfo.gcRegGCrefSetCur)
+ {
+ type = TYP_REF;
+ }
+ else if (regBit & gcInfo.gcRegByrefSetCur)
+ {
+ *byrefRegs |= regBit;
+ type = TYP_BYREF;
+ }
+ else if (noRefRegs != NULL)
+ {
+ *noRefRegs |= regBit;
+ type = TYP_I_IMPL;
+ }
+ else
+ {
+ continue;
+ }
+
+ inst_RV(INS_push, reg, type);
+
+ genSinglePush();
+ gcInfo.gcMarkRegSetNpt(regBit);
+
+ regs &= ~regBit;
+ }
+
+ return pushedRegs;
+
+#endif // FEATURE_FIXED_OUT_ARGS
+}
+
+//------------------------------------------------------------------------
+// genPopRegs: Pop the registers that were pushed by genPushRegs().
+//
+// Arguments:
+// regs - mask of registers to pop
+// byrefRegs - The byref registers that were pushed by genPushRegs().
+// noRefRegs - The non-GC ref registers that were pushed by genPushRegs().
+//
+// Return Value:
+// None
+//
+void CodeGen::genPopRegs(regMaskTP regs, regMaskTP byrefRegs, regMaskTP noRefRegs)
+{
+ if (regs == RBM_NONE)
+ {
+ return;
+ }
+
+#if FEATURE_FIXED_OUT_ARGS
+
+ NYI("Don't call genPopRegs with real regs!");
+
+#else // FEATURE_FIXED_OUT_ARGS
+
+ noway_assert((regs & byrefRegs) == byrefRegs);
+ noway_assert((regs & noRefRegs) == noRefRegs);
+ noway_assert((regs & (gcInfo.gcRegGCrefSetCur | gcInfo.gcRegByrefSetCur)) == RBM_NONE);
+
+ noway_assert(genTypeStSz(TYP_REF) == genTypeStSz(TYP_INT));
+ noway_assert(genTypeStSz(TYP_BYREF) == genTypeStSz(TYP_INT));
+
+ // Walk the registers in the reverse order as genPushRegs()
+ for (regNumber reg = REG_INT_LAST; regs != RBM_NONE; reg = REG_PREV(reg))
+ {
+ regMaskTP regBit = regMaskTP(1) << reg;
+
+ if ((regBit & regs) == RBM_NONE)
+ continue;
+
+ var_types type;
+ if (regBit & byrefRegs)
+ {
+ type = TYP_BYREF;
+ }
+ else if (regBit & noRefRegs)
+ {
+ type = TYP_INT;
+ }
+ else
+ {
+ type = TYP_REF;
+ }
+
+ inst_RV(INS_pop, reg, type);
+ genSinglePop();
+
+ if (type != TYP_INT)
+ gcInfo.gcMarkRegPtrVal(reg, type);
+
+ regs &= ~regBit;
+ }
+
+#endif // FEATURE_FIXED_OUT_ARGS
+}
/*****************************************************************************
* genSetScopeInfo
@@ -11151,6 +11409,103 @@ void CodeGen::genSetScopeInfo()
compiler->eeSetLVdone();
}
+//------------------------------------------------------------------------
+// genSetScopeInfo: Record scope information for debug info
+//
+// Arguments:
+// which
+// startOffs - the starting offset for this scope
+// length - the length of this scope
+// varNum - the lclVar for this scope info
+// LVnum
+// avail
+// varLoc
+//
+// Notes:
+// Called for every scope info piece to record by the main genSetScopeInfo()
+
+void CodeGen::genSetScopeInfo(unsigned which,
+ UNATIVE_OFFSET startOffs,
+ UNATIVE_OFFSET length,
+ unsigned varNum,
+ unsigned LVnum,
+ bool avail,
+ Compiler::siVarLoc& varLoc)
+{
+ // We need to do some mapping while reporting back these variables.
+
+ unsigned ilVarNum = compiler->compMap2ILvarNum(varNum);
+ noway_assert((int)ilVarNum != ICorDebugInfo::UNKNOWN_ILNUM);
+
+#ifdef _TARGET_X86_
+ // Non-x86 platforms are allowed to access all arguments directly
+ // so we don't need this code.
+
+ // Is this a varargs function?
+
+ if (compiler->info.compIsVarArgs && varNum != compiler->lvaVarargsHandleArg &&
+ varNum < compiler->info.compArgsCount && !compiler->lvaTable[varNum].lvIsRegArg)
+ {
+ noway_assert(varLoc.vlType == Compiler::VLT_STK || varLoc.vlType == Compiler::VLT_STK2);
+
+ // All stack arguments (except the varargs handle) have to be
+ // accessed via the varargs cookie. Discard generated info,
+ // and just find its position relative to the varargs handle
+
+ PREFIX_ASSUME(compiler->lvaVarargsHandleArg < compiler->info.compArgsCount);
+ if (!compiler->lvaTable[compiler->lvaVarargsHandleArg].lvOnFrame)
+ {
+ noway_assert(!compiler->opts.compDbgCode);
+ return;
+ }
+
+ // Can't check compiler->lvaTable[varNum].lvOnFrame as we don't set it for
+ // arguments of vararg functions to avoid reporting them to GC.
+ noway_assert(!compiler->lvaTable[varNum].lvRegister);
+ unsigned cookieOffset = compiler->lvaTable[compiler->lvaVarargsHandleArg].lvStkOffs;
+ unsigned varOffset = compiler->lvaTable[varNum].lvStkOffs;
+
+ noway_assert(cookieOffset < varOffset);
+ unsigned offset = varOffset - cookieOffset;
+ unsigned stkArgSize = compiler->compArgSize - intRegState.rsCalleeRegArgCount * sizeof(void*);
+ noway_assert(offset < stkArgSize);
+ offset = stkArgSize - offset;
+
+ varLoc.vlType = Compiler::VLT_FIXED_VA;
+ varLoc.vlFixedVarArg.vlfvOffset = offset;
+ }
+
+#endif // _TARGET_X86_
+
+ VarName name = nullptr;
+
+#ifdef DEBUG
+
+ for (unsigned scopeNum = 0; scopeNum < compiler->info.compVarScopesCount; scopeNum++)
+ {
+ if (LVnum == compiler->info.compVarScopes[scopeNum].vsdLVnum)
+ {
+ name = compiler->info.compVarScopes[scopeNum].vsdName;
+ }
+ }
+
+ // Hang on to this compiler->info.
+
+ TrnslLocalVarInfo& tlvi = genTrnslLocalVarInfo[which];
+
+ tlvi.tlviVarNum = ilVarNum;
+ tlvi.tlviLVnum = LVnum;
+ tlvi.tlviName = name;
+ tlvi.tlviStartPC = startOffs;
+ tlvi.tlviLength = length;
+ tlvi.tlviAvailable = avail;
+ tlvi.tlviVarLoc = varLoc;
+
+#endif // DEBUG
+
+ compiler->eeSetLVinfo(which, startOffs, length, ilVarNum, LVnum, name, avail, varLoc);
+}
+
/*****************************************************************************/
#ifdef LATE_DISASM
#if defined(DEBUG)
@@ -11747,19 +12102,16 @@ void CodeGen::genIPmappingGen()
compiler->eeSetLIdone();
}
-#endif // DEBUGGING_SUPPORT
-
/*============================================================================
*
* These are empty stubs to help the late dis-assembler to compile
- * if DEBUGGING_SUPPORT is not enabled, or the late disassembler is being
- * built into a non-DEBUG build.
+ * if the late disassembler is being built into a non-DEBUG build.
*
*============================================================================
*/
#if defined(LATE_DISASM)
-#if !defined(DEBUGGING_SUPPORT) || !defined(DEBUG)
+#if !defined(DEBUG)
/* virtual */
const char* CodeGen::siRegVarName(size_t offs, size_t size, unsigned reg)
@@ -11774,6 +12126,6 @@ const char* CodeGen::siStackVarName(size_t offs, size_t size, unsigned reg, unsi
}
/*****************************************************************************/
-#endif // !defined(DEBUGGING_SUPPORT) || !defined(DEBUG)
+#endif // !defined(DEBUG)
#endif // defined(LATE_DISASM)
/*****************************************************************************/
diff --git a/src/jit/codegeninterface.h b/src/jit/codegeninterface.h
index e9abbe6b3c..3950673e3a 100644
--- a/src/jit/codegeninterface.h
+++ b/src/jit/codegeninterface.h
@@ -253,12 +253,14 @@ public:
private:
bool m_cgDoubleAlign;
-#else // !DOUBLE_ALIGN
+#else // !DOUBLE_ALIGN
+
public:
bool doubleAlignOrFramePointerUsed() const
{
return isFramePointerUsed();
}
+
#endif // !DOUBLE_ALIGN
#ifdef DEBUG
@@ -424,10 +426,8 @@ public:
private:
bool m_cgFullPtrRegMap;
-#ifdef DEBUGGING_SUPPORT
public:
virtual void siUpdate() = 0;
-#endif // DEBUGGING_SUPPORT
#ifdef LATE_DISASM
public:
diff --git a/src/jit/codegenlegacy.cpp b/src/jit/codegenlegacy.cpp
index ea40eb2aff..667b9d4af8 100644
--- a/src/jit/codegenlegacy.cpp
+++ b/src/jit/codegenlegacy.cpp
@@ -243,18 +243,6 @@ GenTreePtr CodeGen::genGetAddrModeBase(GenTreePtr tree)
return NULL;
}
-// inline
-void CodeGen::genSinglePush()
-{
- genStackLevel += sizeof(void*);
-}
-
-// inline
-void CodeGen::genSinglePop()
-{
- genStackLevel -= sizeof(void*);
-}
-
#if FEATURE_STACK_FP_X87
// inline
void CodeGenInterface::genResetFPstkLevel(unsigned newValue /* = 0 */)
@@ -497,9 +485,10 @@ void CodeGen::genIncRegBy(regNumber reg, ssize_t ival, GenTreePtr tree, var_type
}
}
#endif
-
- insFlags flags = setFlags ? INS_FLAGS_SET : INS_FLAGS_DONT_CARE;
- inst_RV_IV(INS_add, reg, ival, emitActualTypeSize(dstType), flags);
+ {
+ insFlags flags = setFlags ? INS_FLAGS_SET : INS_FLAGS_DONT_CARE;
+ inst_RV_IV(INS_add, reg, ival, emitActualTypeSize(dstType), flags);
+ }
#ifdef _TARGET_XARCH_
UPDATE_LIVENESS:
@@ -4328,8 +4317,6 @@ emitJumpKind CodeGen::genCondSetFlags(GenTreePtr cond)
addrReg1 = genMakeRvalueAddressable(op1, RBM_NONE, RegSet::KEEP_REG, false, smallOk);
}
- // #if defined(DEBUGGING_SUPPORT)
-
/* Special case: comparison of two constants */
// Needed if Importer doesn't call gtFoldExpr()
@@ -4347,8 +4334,6 @@ emitJumpKind CodeGen::genCondSetFlags(GenTreePtr cond)
addrReg1 = genRegMask(op1->gtRegNum);
}
- // #endif
-
/* Compare the operand against the constant */
if (op2->IsIconHandle())
@@ -7087,84 +7072,87 @@ void CodeGen::genCodeForTreeSmpBinArithLogOp(GenTreePtr tree, regMaskTP destReg,
regTracker.rsTrackRegTrash(reg);
- bool op2Released = false;
+ {
+ bool op2Released = false;
- // For overflow instructions, tree->gtType is the accurate type,
- // and gives us the size for the operands.
+ // For overflow instructions, tree->gtType is the accurate type,
+ // and gives us the size for the operands.
- emitAttr opSize = emitTypeSize(treeType);
+ emitAttr opSize = emitTypeSize(treeType);
- /* Compute the new value */
+ /* Compute the new value */
- if (isArith && !op2->InReg() && (op2->OperKind() & GTK_CONST)
+ if (isArith && !op2->InReg() && (op2->OperKind() & GTK_CONST)
#if !CPU_HAS_FP_SUPPORT
- && (treeType == TYP_INT || treeType == TYP_I_IMPL)
+ && (treeType == TYP_INT || treeType == TYP_I_IMPL)
#endif
- )
- {
- ssize_t ival = op2->gtIntCon.gtIconVal;
-
- if (oper == GT_ADD)
- {
- genIncRegBy(reg, ival, tree, treeType, ovfl);
- }
- else if (oper == GT_SUB)
- {
- if (ovfl && ((tree->gtFlags & GTF_UNSIGNED) ||
- (ival == ((treeType == TYP_INT) ? INT32_MIN : SSIZE_T_MIN))) // -0x80000000 == 0x80000000.
- // Therefore we can't use -ival.
)
- {
- /* For unsigned overflow, we have to use INS_sub to set
- the flags correctly */
+ {
+ ssize_t ival = op2->gtIntCon.gtIconVal;
- genDecRegBy(reg, ival, tree);
+ if (oper == GT_ADD)
+ {
+ genIncRegBy(reg, ival, tree, treeType, ovfl);
}
- else
+ else if (oper == GT_SUB)
{
- /* Else, we simply add the negative of the value */
+ if (ovfl && ((tree->gtFlags & GTF_UNSIGNED) ||
+ (ival == ((treeType == TYP_INT) ? INT32_MIN : SSIZE_T_MIN))) // -0x80000000 == 0x80000000.
+ // Therefore we can't use -ival.
+ )
+ {
+ /* For unsigned overflow, we have to use INS_sub to set
+ the flags correctly */
- genIncRegBy(reg, -ival, tree, treeType, ovfl);
+ genDecRegBy(reg, ival, tree);
+ }
+ else
+ {
+ /* Else, we simply add the negative of the value */
+
+ genIncRegBy(reg, -ival, tree, treeType, ovfl);
+ }
+ }
+ else if (oper == GT_MUL)
+ {
+ genMulRegBy(reg, ival, tree, treeType, ovfl);
}
}
- else if (oper == GT_MUL)
- {
- genMulRegBy(reg, ival, tree, treeType, ovfl);
- }
- }
- else
- {
- // op2 could be a GT_COMMA (i.e. an assignment for a CSE def)
- op2 = op2->gtEffectiveVal();
- if (varTypeIsByte(treeType) && op2->InReg())
+ else
{
- noway_assert(genRegMask(reg) & RBM_BYTE_REGS);
+ // op2 could be a GT_COMMA (i.e. an assignment for a CSE def)
+ op2 = op2->gtEffectiveVal();
+ if (varTypeIsByte(treeType) && op2->InReg())
+ {
+ noway_assert(genRegMask(reg) & RBM_BYTE_REGS);
- regNumber op2reg = op2->gtRegNum;
- regMaskTP op2regMask = genRegMask(op2reg);
+ regNumber op2reg = op2->gtRegNum;
+ regMaskTP op2regMask = genRegMask(op2reg);
- if (!(op2regMask & RBM_BYTE_REGS))
- {
- regNumber byteReg = regSet.rsGrabReg(RBM_BYTE_REGS);
+ if (!(op2regMask & RBM_BYTE_REGS))
+ {
+ regNumber byteReg = regSet.rsGrabReg(RBM_BYTE_REGS);
- inst_RV_RV(INS_mov, byteReg, op2reg);
- regTracker.rsTrackRegTrash(byteReg);
+ inst_RV_RV(INS_mov, byteReg, op2reg);
+ regTracker.rsTrackRegTrash(byteReg);
- genDoneAddressable(op2, addrReg, RegSet::KEEP_REG);
- op2Released = true;
+ genDoneAddressable(op2, addrReg, RegSet::KEEP_REG);
+ op2Released = true;
- op2->gtRegNum = byteReg;
+ op2->gtRegNum = byteReg;
+ }
}
- }
- inst_RV_TT(ins, reg, op2, 0, opSize, flags);
- }
+ inst_RV_TT(ins, reg, op2, 0, opSize, flags);
+ }
- /* Free up anything that was tied up by the operand */
-
- if (!op2Released)
- genDoneAddressable(op2, addrReg, RegSet::KEEP_REG);
+ /* Free up anything that was tied up by the operand */
+ if (!op2Released)
+ {
+ genDoneAddressable(op2, addrReg, RegSet::KEEP_REG);
+ }
+ }
/* The result will be where the first operand is sitting */
/* We must use RegSet::KEEP_REG since op1 can have a GC pointer here */
@@ -9721,7 +9709,7 @@ void CodeGen::genCodeForTreeSmpOp(GenTreePtr tree, regMaskTP destReg, regMaskTP
switch (oper)
{
case GT_ASG:
- if (tree->OperIsBlkOp())
+ if (tree->OperIsBlkOp() && op1->gtOper != GT_LCL_VAR)
{
genCodeForBlkOp(tree, destReg);
}
@@ -10184,6 +10172,9 @@ void CodeGen::genCodeForTreeSmpOp(GenTreePtr tree, regMaskTP destReg, regMaskTP
if (op1 == NULL)
return;
#endif
+ __fallthrough;
+
+ case GT_INIT_VAL:
/* Generate the operand into some register */
@@ -11293,10 +11284,8 @@ void CodeGen::genCodeForTreeSmpOpAsg(GenTreePtr tree)
bool volat = false; // Is this a volatile store
regMaskTP regGC;
instruction ins;
-#ifdef DEBUGGING_SUPPORT
- unsigned lclVarNum = compiler->lvaCount;
- unsigned lclILoffs = DUMMY_INIT(0);
-#endif
+ unsigned lclVarNum = compiler->lvaCount;
+ unsigned lclILoffs = DUMMY_INIT(0);
#ifdef _TARGET_ARM_
if (tree->gtType == TYP_STRUCT)
@@ -11335,7 +11324,6 @@ void CodeGen::genCodeForTreeSmpOpAsg(GenTreePtr tree)
noway_assert(varNum < compiler->lvaCount);
varDsc = compiler->lvaTable + varNum;
-#ifdef DEBUGGING_SUPPORT
/* For non-debuggable code, every definition of a lcl-var has
* to be checked to see if we need to open a new scope for it.
* Remember the local var info to call siCheckVarScope
@@ -11346,7 +11334,6 @@ void CodeGen::genCodeForTreeSmpOpAsg(GenTreePtr tree)
lclVarNum = varNum;
lclILoffs = op1->gtLclVar.gtLclILoffs;
}
-#endif
/* Check against dead store ? (with min opts we may have dead stores) */
@@ -11999,13 +11986,11 @@ void CodeGen::genCodeForTreeSmpOpAsg(GenTreePtr tree)
genCodeForTreeSmpOpAsg_DONE_ASSG(tree, addrReg, REG_NA, ovfl);
LExit:
-#ifdef DEBUGGING_SUPPORT
/* For non-debuggable code, every definition of a lcl-var has
* to be checked to see if we need to open a new scope for it.
*/
if (lclVarNum < compiler->lvaCount)
siCheckVarScope(lclVarNum, lclILoffs);
-#endif
}
#ifdef _PREFAST_
#pragma warning(pop)
@@ -12436,14 +12421,12 @@ void CodeGen::genCodeForBBlist()
regSet.rsSpillBeg();
-#ifdef DEBUGGING_SUPPORT
/* Initialize the line# tracking logic */
if (compiler->opts.compScopeInfo)
{
siInit();
}
-#endif
#ifdef _TARGET_X86_
if (compiler->compTailCallUsed)
@@ -12774,27 +12757,7 @@ void CodeGen::genCodeForBBlist()
genResetFPstkLevel();
#endif // FEATURE_STACK_FP_X87
-#if !FEATURE_FIXED_OUT_ARGS
- /* Check for inserted throw blocks and adjust genStackLevel */
-
- if (!isFramePointerUsed() && compiler->fgIsThrowHlpBlk(block))
- {
- noway_assert(block->bbFlags & BBF_JMP_TARGET);
-
- genStackLevel = compiler->fgThrowHlpBlkStkLevel(block) * sizeof(int);
-
- if (genStackLevel)
- {
-#ifdef _TARGET_X86_
- getEmitter()->emitMarkStackLvl(genStackLevel);
- inst_RV_IV(INS_add, REG_SPBASE, genStackLevel, EA_PTRSIZE);
- genStackLevel = 0;
-#else // _TARGET_X86_
- NYI("Need emitMarkStackLvl()");
-#endif // _TARGET_X86_
- }
- }
-#endif // !FEATURE_FIXED_OUT_ARGS
+ genAdjustStackLevel(block);
savedStkLvl = genStackLevel;
@@ -12802,7 +12765,6 @@ void CodeGen::genCodeForBBlist()
compiler->compCurBB = block;
-#ifdef DEBUGGING_SUPPORT
siBeginBlock(block);
// BBF_INTERNAL blocks don't correspond to any single IL instruction.
@@ -12810,7 +12772,6 @@ void CodeGen::genCodeForBBlist()
genIPmappingAdd((IL_OFFSETX)ICorDebugInfo::NO_MAPPING, true);
bool firstMapping = true;
-#endif // DEBUGGING_SUPPORT
/*---------------------------------------------------------------------
*
@@ -12830,8 +12791,6 @@ void CodeGen::genCodeForBBlist()
{
noway_assert(stmt->gtOper == GT_STMT);
-#if defined(DEBUGGING_SUPPORT)
-
/* Do we have a new IL-offset ? */
if (stmt->gtStmt.gtStmtILoffsx != BAD_IL_OFFSET)
@@ -12841,8 +12800,6 @@ void CodeGen::genCodeForBBlist()
firstMapping = false;
}
-#endif // DEBUGGING_SUPPORT
-
#ifdef DEBUG
if (stmt->gtStmt.gtStmtLastILoffs != BAD_IL_OFFSET)
{
@@ -12945,7 +12902,7 @@ void CodeGen::genCodeForBBlist()
// harmless "inc" instruction (does not interfere with the exception
// object).
- if ((compiler->opts.eeFlags & CORJIT_FLG_BBINSTR) && (stmt == block->bbTreeList) &&
+ if (compiler->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_BBINSTR) && (stmt == block->bbTreeList) &&
(block->bbCatchTyp && handlerGetsXcptnObj(block->bbCatchTyp)))
{
nonVarPtrRegs &= ~RBM_EXCEPTION_OBJECT;
@@ -12972,14 +12929,10 @@ void CodeGen::genCodeForBBlist()
noway_assert(stmt->gtOper == GT_STMT);
-#ifdef DEBUGGING_SUPPORT
genEnsureCodeEmitted(stmt->gtStmt.gtStmtILoffsx);
-#endif
} //-------- END-FOR each statement-tree of the current block ---------
-#ifdef DEBUGGING_SUPPORT
-
if (compiler->opts.compScopeInfo && (compiler->info.compVarScopesCount > 0))
{
siEndBlock(block);
@@ -13005,8 +12958,6 @@ void CodeGen::genCodeForBBlist()
}
}
-#endif // DEBUGGING_SUPPORT
-
genStackLevel -= savedStkLvl;
gcInfo.gcMarkRegSetNpt(gcrefRegs | byrefRegs);
@@ -13449,10 +13400,8 @@ void CodeGen::genCodeForTreeLng(GenTreePtr tree, regMaskTP needReg, regMaskTP av
{
case GT_ASG:
{
-#ifdef DEBUGGING_SUPPORT
unsigned lclVarNum = compiler->lvaCount;
unsigned lclVarILoffs = DUMMY_INIT(0);
-#endif
/* Is the target a local ? */
@@ -13467,7 +13416,6 @@ void CodeGen::genCodeForTreeLng(GenTreePtr tree, regMaskTP needReg, regMaskTP av
// No dead stores, (with min opts we may have dead stores)
noway_assert(!varDsc->lvTracked || compiler->opts.MinOpts() || !(op1->gtFlags & GTF_VAR_DEATH));
-#ifdef DEBUGGING_SUPPORT
/* For non-debuggable code, every definition of a lcl-var has
* to be checked to see if we need to open a new scope for it.
* Remember the local var info to call siCheckVarScope
@@ -13479,7 +13427,6 @@ void CodeGen::genCodeForTreeLng(GenTreePtr tree, regMaskTP needReg, regMaskTP av
lclVarNum = varNum;
lclVarILoffs = op1->gtLclVar.gtLclILoffs;
}
-#endif
/* Has the variable been assigned to a register (pair) ? */
@@ -13767,13 +13714,11 @@ void CodeGen::genCodeForTreeLng(GenTreePtr tree, regMaskTP needReg, regMaskTP av
genUpdateLife(op1);
genUpdateLife(tree);
-#ifdef DEBUGGING_SUPPORT
/* For non-debuggable code, every definition of a lcl-var has
* to be checked to see if we need to open a new scope for it.
*/
if (lclVarNum < compiler->lvaCount)
siCheckVarScope(lclVarNum, lclVarILoffs);
-#endif
}
return;
@@ -15792,132 +15737,6 @@ void CodeGen::genEmitHelperCall(unsigned helper, int argSize, emitAttr retSize)
/*****************************************************************************
*
- * Push the given registers.
- * This function does not check if the register is marked as used, etc.
- */
-
-regMaskTP CodeGen::genPushRegs(regMaskTP regs, regMaskTP* byrefRegs, regMaskTP* noRefRegs)
-{
- *byrefRegs = RBM_NONE;
- *noRefRegs = RBM_NONE;
-
- // noway_assert((regs & regSet.rsRegMaskFree()) == regs); // Don't care. Caller is responsible for all this
-
- if (regs == RBM_NONE)
- return RBM_NONE;
-
-#if FEATURE_FIXED_OUT_ARGS
-
- NYI("Don't call genPushRegs with real regs!");
- return RBM_NONE;
-
-#else // FEATURE_FIXED_OUT_ARGS
-
- noway_assert(genTypeStSz(TYP_REF) == genTypeStSz(TYP_I_IMPL));
- noway_assert(genTypeStSz(TYP_BYREF) == genTypeStSz(TYP_I_IMPL));
-
- regMaskTP pushedRegs = regs;
-
- for (regNumber reg = REG_INT_FIRST; regs != RBM_NONE; reg = REG_NEXT(reg))
- {
- regMaskTP regBit = regMaskTP(1) << reg;
-
- if ((regBit & regs) == RBM_NONE)
- continue;
-
- var_types type;
- if (regBit & gcInfo.gcRegGCrefSetCur)
- {
- type = TYP_REF;
- }
- else if (regBit & gcInfo.gcRegByrefSetCur)
- {
- *byrefRegs |= regBit;
- type = TYP_BYREF;
- }
- else if (noRefRegs != NULL)
- {
- *noRefRegs |= regBit;
- type = TYP_I_IMPL;
- }
- else
- {
- continue;
- }
-
- inst_RV(INS_push, reg, type);
-
- genSinglePush();
- gcInfo.gcMarkRegSetNpt(regBit);
-
- regs &= ~regBit;
- }
-
- return pushedRegs;
-
-#endif // FEATURE_FIXED_OUT_ARGS
-}
-
-/*****************************************************************************
- *
- * Pop the registers pushed by genPushRegs()
- */
-
-void CodeGen::genPopRegs(regMaskTP regs, regMaskTP byrefRegs, regMaskTP noRefRegs)
-{
- if (regs == RBM_NONE)
- return;
-
-#if FEATURE_FIXED_OUT_ARGS
-
- NYI("Don't call genPopRegs with real regs!");
-
-#else // FEATURE_FIXED_OUT_ARGS
-
- noway_assert((regs & byrefRegs) == byrefRegs);
- noway_assert((regs & noRefRegs) == noRefRegs);
- // noway_assert((regs & regSet.rsRegMaskFree()) == regs); // Don't care. Caller is responsible for all this
- noway_assert((regs & (gcInfo.gcRegGCrefSetCur | gcInfo.gcRegByrefSetCur)) == RBM_NONE);
-
- noway_assert(genTypeStSz(TYP_REF) == genTypeStSz(TYP_INT));
- noway_assert(genTypeStSz(TYP_BYREF) == genTypeStSz(TYP_INT));
-
- // Walk the registers in the reverse order as genPushRegs()
- for (regNumber reg = REG_INT_LAST; regs != RBM_NONE; reg = REG_PREV(reg))
- {
- regMaskTP regBit = regMaskTP(1) << reg;
-
- if ((regBit & regs) == RBM_NONE)
- continue;
-
- var_types type;
- if (regBit & byrefRegs)
- {
- type = TYP_BYREF;
- }
- else if (regBit & noRefRegs)
- {
- type = TYP_INT;
- }
- else
- {
- type = TYP_REF;
- }
-
- inst_RV(INS_pop, reg, type);
- genSinglePop();
-
- if (type != TYP_INT)
- gcInfo.gcMarkRegPtrVal(reg, type);
-
- regs &= ~regBit;
- }
-
-#endif // FEATURE_FIXED_OUT_ARGS
-}
-
-/*****************************************************************************
- *
* Push the given argument list, right to left; returns the total amount of
* stuff pushed.
*/
@@ -18519,12 +18338,10 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
CORINFO_SIG_INFO* sigInfo = nullptr;
-#ifdef DEBUGGING_SUPPORT
if (compiler->opts.compDbgInfo && compiler->genCallSite2ILOffsetMap != NULL)
{
(void)compiler->genCallSite2ILOffsetMap->Lookup(call, &ilOffset);
}
-#endif
/* Make some sanity checks on the call node */
@@ -19600,6 +19417,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
regNumber indCallReg;
case IAT_VALUE:
+ {
//------------------------------------------------------
// Non-virtual direct calls to known addressess
//
@@ -19607,7 +19425,24 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
// it be nice if they all did!
CLANG_FORMAT_COMMENT_ANCHOR;
#ifdef _TARGET_ARM_
- if (!arm_Valid_Imm_For_BL((ssize_t)addr))
+ // We may use direct call for some of recursive calls
+ // as we can safely estimate the distance from the call site to the top of the method
+ const int codeOffset = MAX_PROLOG_SIZE_BYTES + // prolog size
+ getEmitter()->emitCurCodeOffset + // offset of the current IG
+ 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)
+ {
+ getEmitter()->emitIns_Call(emitter::EC_FUNC_TOKEN, methHnd,
+ INDEBUG_LDISASM_COMMA(sigInfo) NULL, // addr
+ args, retSize, gcInfo.gcVarPtrSetCur,
+ gcInfo.gcRegGCrefSetCur, gcInfo.gcRegByrefSetCur, ilOffset,
+ REG_NA, REG_NA, 0, 0, // ireg, xreg, xmul, disp
+ false, // isJump
+ emitter::emitNoGChelper(helperNum));
+ }
+ else if (!arm_Valid_Imm_For_BL((ssize_t)addr))
{
// Load the address into a register and call through a register
indCallReg = regSet.rsGrabReg(RBM_ALLINT); // Grab an available register to use for the
@@ -19634,7 +19469,8 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
false, /* isJump */
emitter::emitNoGChelper(helperNum));
}
- break;
+ }
+ break;
case IAT_PVALUE:
//------------------------------------------------------
@@ -20046,7 +19882,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
#if defined(_TARGET_X86_)
if (call->gtFlags & GTF_CALL_UNMANAGED)
{
- if ((compiler->opts.eeFlags & CORJIT_FLG_PINVOKE_RESTORE_ESP) ||
+ if (compiler->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PINVOKE_RESTORE_ESP) ||
compiler->compStressCompile(Compiler::STRESS_PINVOKE_RESTORE_ESP, 50))
{
// P/Invoke signature mismatch resilience - restore ESP to pre-call value. We would ideally
@@ -20756,9 +20592,11 @@ DONE:
}
#endif
- /* Write the lvaShadowSPfirst stack frame slot */
- noway_assert(compiler->lvaLocAllocSPvar != BAD_VAR_NUM);
- getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, REG_SPBASE, compiler->lvaLocAllocSPvar, 0);
+ /* Write the lvaLocAllocSPvar stack frame slot */
+ if (compiler->lvaLocAllocSPvar != BAD_VAR_NUM)
+ {
+ getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, REG_SPBASE, compiler->lvaLocAllocSPvar, 0);
+ }
#if STACK_PROBES
// Don't think it is worth it the codegen complexity to embed this
@@ -20783,98 +20621,6 @@ DONE:
return regCnt;
}
-/*****************************************************************************/
-#ifdef DEBUGGING_SUPPORT
-/*****************************************************************************
- * genSetScopeInfo
- *
- * Called for every scope info piece to record by the main genSetScopeInfo()
- */
-
-void CodeGen::genSetScopeInfo(unsigned which,
- UNATIVE_OFFSET startOffs,
- UNATIVE_OFFSET length,
- unsigned varNum,
- unsigned LVnum,
- bool avail,
- Compiler::siVarLoc& varLoc)
-{
- /* We need to do some mapping while reporting back these variables */
-
- unsigned ilVarNum = compiler->compMap2ILvarNum(varNum);
- noway_assert((int)ilVarNum != ICorDebugInfo::UNKNOWN_ILNUM);
-
-#ifdef _TARGET_X86_
- // Non-x86 platforms are allowed to access all arguments directly
- // so we don't need this code.
-
- // Is this a varargs function?
-
- if (compiler->info.compIsVarArgs && varNum != compiler->lvaVarargsHandleArg &&
- varNum < compiler->info.compArgsCount && !compiler->lvaTable[varNum].lvIsRegArg)
- {
- noway_assert(varLoc.vlType == Compiler::VLT_STK || varLoc.vlType == Compiler::VLT_STK2);
-
- // All stack arguments (except the varargs handle) have to be
- // accessed via the varargs cookie. Discard generated info,
- // and just find its position relative to the varargs handle
-
- PREFIX_ASSUME(compiler->lvaVarargsHandleArg < compiler->info.compArgsCount);
- if (!compiler->lvaTable[compiler->lvaVarargsHandleArg].lvOnFrame)
- {
- noway_assert(!compiler->opts.compDbgCode);
- return;
- }
-
- // Can't check compiler->lvaTable[varNum].lvOnFrame as we don't set it for
- // arguments of vararg functions to avoid reporting them to GC.
- noway_assert(!compiler->lvaTable[varNum].lvRegister);
- unsigned cookieOffset = compiler->lvaTable[compiler->lvaVarargsHandleArg].lvStkOffs;
- unsigned varOffset = compiler->lvaTable[varNum].lvStkOffs;
-
- noway_assert(cookieOffset < varOffset);
- unsigned offset = varOffset - cookieOffset;
- unsigned stkArgSize = compiler->compArgSize - intRegState.rsCalleeRegArgCount * sizeof(void*);
- noway_assert(offset < stkArgSize);
- offset = stkArgSize - offset;
-
- varLoc.vlType = Compiler::VLT_FIXED_VA;
- varLoc.vlFixedVarArg.vlfvOffset = offset;
- }
-
-#endif // _TARGET_X86_
-
- VarName name = NULL;
-
-#ifdef DEBUG
-
- for (unsigned scopeNum = 0; scopeNum < compiler->info.compVarScopesCount; scopeNum++)
- {
- if (LVnum == compiler->info.compVarScopes[scopeNum].vsdLVnum)
- {
- name = compiler->info.compVarScopes[scopeNum].vsdName;
- }
- }
-
- // Hang on to this compiler->info.
-
- TrnslLocalVarInfo& tlvi = genTrnslLocalVarInfo[which];
-
- tlvi.tlviVarNum = ilVarNum;
- tlvi.tlviLVnum = LVnum;
- tlvi.tlviName = name;
- tlvi.tlviStartPC = startOffs;
- tlvi.tlviLength = length;
- tlvi.tlviAvailable = avail;
- tlvi.tlviVarLoc = varLoc;
-
-#endif // DEBUG
-
- compiler->eeSetLVinfo(which, startOffs, length, ilVarNum, LVnum, name, avail, varLoc);
-}
-
-#endif // DEBUGGING_SUPPORT
-
/*****************************************************************************
*
* Return non-zero if the given register is free after the given tree is
diff --git a/src/jit/codegenlinear.cpp b/src/jit/codegenlinear.cpp
new file mode 100644
index 0000000000..9713288e08
--- /dev/null
+++ b/src/jit/codegenlinear.cpp
@@ -0,0 +1,1773 @@
+// Licensed to the .NET Foundation under one or more 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 Code Generation Support Methods for Linear Codegen 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.
+#include "emit.h"
+#include "codegen.h"
+
+//------------------------------------------------------------------------
+// genCodeForBBlist: Generate code for all the blocks in a method
+//
+// Arguments:
+// None
+//
+// Notes:
+// This is the main method for linear codegen. It calls genCodeForTreeNode
+// to generate the code for each node in each BasicBlock, and handles BasicBlock
+// boundaries and branches.
+//
+void CodeGen::genCodeForBBlist()
+{
+ unsigned varNum;
+ LclVarDsc* varDsc;
+
+ unsigned savedStkLvl;
+
+#ifdef DEBUG
+ genInterruptibleUsed = true;
+
+ // You have to be careful if you create basic blocks from now on
+ compiler->fgSafeBasicBlockCreation = false;
+
+ // This stress mode is not comptible with fully interruptible GC
+ if (genInterruptible && compiler->opts.compStackCheckOnCall)
+ {
+ compiler->opts.compStackCheckOnCall = false;
+ }
+
+ // This stress mode is not comptible with fully interruptible GC
+ if (genInterruptible && compiler->opts.compStackCheckOnRet)
+ {
+ compiler->opts.compStackCheckOnRet = false;
+ }
+#endif // DEBUG
+
+ // Prepare the blocks for exception handling codegen: mark the blocks that needs labels.
+ genPrepForEHCodegen();
+
+ assert(!compiler->fgFirstBBScratch ||
+ compiler->fgFirstBB == compiler->fgFirstBBScratch); // compiler->fgFirstBBScratch has to be first.
+
+ /* Initialize the spill tracking logic */
+
+ regSet.rsSpillBeg();
+
+ /* Initialize the line# tracking logic */
+
+ if (compiler->opts.compScopeInfo)
+ {
+ siInit();
+ }
+
+ // The current implementation of switch tables requires the first block to have a label so it
+ // can generate offsets to the switch label targets.
+ // TODO-CQ: remove this when switches have been re-implemented to not use this.
+ if (compiler->fgHasSwitch)
+ {
+ compiler->fgFirstBB->bbFlags |= BBF_JMP_TARGET;
+ }
+
+ genPendingCallLabel = nullptr;
+
+ /* Initialize the pointer tracking code */
+
+ gcInfo.gcRegPtrSetInit();
+ gcInfo.gcVarPtrSetInit();
+
+ /* If any arguments live in registers, mark those regs as such */
+
+ for (varNum = 0, varDsc = compiler->lvaTable; varNum < compiler->lvaCount; varNum++, varDsc++)
+ {
+ /* Is this variable a parameter assigned to a register? */
+
+ if (!varDsc->lvIsParam || !varDsc->lvRegister)
+ {
+ continue;
+ }
+
+ /* Is the argument live on entry to the method? */
+
+ if (!VarSetOps::IsMember(compiler, compiler->fgFirstBB->bbLiveIn, varDsc->lvVarIndex))
+ {
+ continue;
+ }
+
+ /* Is this a floating-point argument? */
+
+ if (varDsc->IsFloatRegType())
+ {
+ continue;
+ }
+
+ noway_assert(!varTypeIsFloating(varDsc->TypeGet()));
+
+ /* Mark the register as holding the variable */
+
+ regTracker.rsTrackRegLclVar(varDsc->lvRegNum, varNum);
+ }
+
+ unsigned finallyNesting = 0;
+
+ // Make sure a set is allocated for compiler->compCurLife (in the long case), so we can set it to empty without
+ // allocation at the start of each basic block.
+ VarSetOps::AssignNoCopy(compiler, compiler->compCurLife, VarSetOps::MakeEmpty(compiler));
+
+ /*-------------------------------------------------------------------------
+ *
+ * Walk the basic blocks and generate code for each one
+ *
+ */
+
+ BasicBlock* block;
+ BasicBlock* lblk; /* previous block */
+
+ for (lblk = nullptr, block = compiler->fgFirstBB; block != nullptr; lblk = block, block = block->bbNext)
+ {
+#ifdef DEBUG
+ if (compiler->verbose)
+ {
+ printf("\n=============== Generating ");
+ block->dspBlockHeader(compiler, true, true);
+ compiler->fgDispBBLiveness(block);
+ }
+#endif // DEBUG
+
+ // Figure out which registers hold variables on entry to this block
+
+ regSet.ClearMaskVars();
+ gcInfo.gcRegGCrefSetCur = RBM_NONE;
+ gcInfo.gcRegByrefSetCur = RBM_NONE;
+
+ compiler->m_pLinearScan->recordVarLocationsAtStartOfBB(block);
+
+ genUpdateLife(block->bbLiveIn);
+
+ // Even if liveness didn't change, we need to update the registers containing GC references.
+ // genUpdateLife will update the registers live due to liveness changes. But what about registers that didn't
+ // change? We cleared them out above. Maybe we should just not clear them out, but update the ones that change
+ // here. That would require handling the changes in recordVarLocationsAtStartOfBB().
+
+ regMaskTP newLiveRegSet = RBM_NONE;
+ regMaskTP newRegGCrefSet = RBM_NONE;
+ regMaskTP newRegByrefSet = RBM_NONE;
+#ifdef DEBUG
+ VARSET_TP VARSET_INIT_NOCOPY(removedGCVars, VarSetOps::MakeEmpty(compiler));
+ VARSET_TP VARSET_INIT_NOCOPY(addedGCVars, VarSetOps::MakeEmpty(compiler));
+#endif
+ VARSET_ITER_INIT(compiler, iter, block->bbLiveIn, varIndex);
+ while (iter.NextElem(compiler, &varIndex))
+ {
+ unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
+ LclVarDsc* varDsc = &(compiler->lvaTable[varNum]);
+
+ if (varDsc->lvIsInReg())
+ {
+ newLiveRegSet |= varDsc->lvRegMask();
+ if (varDsc->lvType == TYP_REF)
+ {
+ newRegGCrefSet |= varDsc->lvRegMask();
+ }
+ else if (varDsc->lvType == TYP_BYREF)
+ {
+ newRegByrefSet |= varDsc->lvRegMask();
+ }
+#ifdef DEBUG
+ if (verbose && VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varIndex))
+ {
+ VarSetOps::AddElemD(compiler, removedGCVars, varIndex);
+ }
+#endif // DEBUG
+ VarSetOps::RemoveElemD(compiler, gcInfo.gcVarPtrSetCur, varIndex);
+ }
+ else if (compiler->lvaIsGCTracked(varDsc))
+ {
+#ifdef DEBUG
+ if (verbose && !VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varIndex))
+ {
+ VarSetOps::AddElemD(compiler, addedGCVars, varIndex);
+ }
+#endif // DEBUG
+ VarSetOps::AddElemD(compiler, gcInfo.gcVarPtrSetCur, varIndex);
+ }
+ }
+
+ regSet.rsMaskVars = newLiveRegSet;
+
+#ifdef DEBUG
+ if (compiler->verbose)
+ {
+ if (!VarSetOps::IsEmpty(compiler, addedGCVars))
+ {
+ printf("\t\t\t\t\t\t\tAdded GCVars: ");
+ dumpConvertedVarSet(compiler, addedGCVars);
+ printf("\n");
+ }
+ if (!VarSetOps::IsEmpty(compiler, removedGCVars))
+ {
+ printf("\t\t\t\t\t\t\tRemoved GCVars: ");
+ dumpConvertedVarSet(compiler, removedGCVars);
+ printf("\n");
+ }
+ }
+#endif // DEBUG
+
+ gcInfo.gcMarkRegSetGCref(newRegGCrefSet DEBUGARG(true));
+ gcInfo.gcMarkRegSetByref(newRegByrefSet DEBUGARG(true));
+
+ /* Blocks with handlerGetsXcptnObj()==true use GT_CATCH_ARG to
+ represent the exception object (TYP_REF).
+ We mark REG_EXCEPTION_OBJECT as holding a GC object on entry
+ to the block, it will be the first thing evaluated
+ (thanks to GTF_ORDER_SIDEEFF).
+ */
+
+ if (handlerGetsXcptnObj(block->bbCatchTyp))
+ {
+ for (GenTree* node : LIR::AsRange(block))
+ {
+ if (node->OperGet() == GT_CATCH_ARG)
+ {
+ gcInfo.gcMarkRegSetGCref(RBM_EXCEPTION_OBJECT);
+ break;
+ }
+ }
+ }
+
+ /* Start a new code output block */
+
+ genUpdateCurrentFunclet(block);
+
+#ifdef _TARGET_XARCH_
+ if (genAlignLoops && block->bbFlags & BBF_LOOP_HEAD)
+ {
+ getEmitter()->emitLoopAlign();
+ }
+#endif
+
+#ifdef DEBUG
+ if (compiler->opts.dspCode)
+ {
+ printf("\n L_M%03u_BB%02u:\n", Compiler::s_compMethodsCount, block->bbNum);
+ }
+#endif
+
+ block->bbEmitCookie = nullptr;
+
+ if (block->bbFlags & (BBF_JMP_TARGET | BBF_HAS_LABEL))
+ {
+ /* Mark a label and update the current set of live GC refs */
+
+ block->bbEmitCookie = getEmitter()->emitAddLabel(gcInfo.gcVarPtrSetCur, gcInfo.gcRegGCrefSetCur,
+ gcInfo.gcRegByrefSetCur, FALSE);
+ }
+
+ if (block == compiler->fgFirstColdBlock)
+ {
+#ifdef DEBUG
+ if (compiler->verbose)
+ {
+ printf("\nThis is the start of the cold region of the method\n");
+ }
+#endif
+ // We should never have a block that falls through into the Cold section
+ noway_assert(!lblk->bbFallsThrough());
+
+ // We require the block that starts the Cold section to have a label
+ noway_assert(block->bbEmitCookie);
+ getEmitter()->emitSetFirstColdIGCookie(block->bbEmitCookie);
+ }
+
+ /* Both stacks are always empty on entry to a basic block */
+
+ genStackLevel = 0;
+ genAdjustStackLevel(block);
+ savedStkLvl = genStackLevel;
+
+ /* Tell everyone which basic block we're working on */
+
+ compiler->compCurBB = block;
+
+ siBeginBlock(block);
+
+ // BBF_INTERNAL blocks don't correspond to any single IL instruction.
+ if (compiler->opts.compDbgInfo && (block->bbFlags & BBF_INTERNAL) &&
+ !compiler->fgBBisScratch(block)) // If the block is the distinguished first scratch block, then no need to
+ // emit a NO_MAPPING entry, immediately after the prolog.
+ {
+ genIPmappingAdd((IL_OFFSETX)ICorDebugInfo::NO_MAPPING, true);
+ }
+
+ bool firstMapping = true;
+
+#if FEATURE_EH_FUNCLETS
+ if (block->bbFlags & BBF_FUNCLET_BEG)
+ {
+ genReserveFuncletProlog(block);
+ }
+#endif // FEATURE_EH_FUNCLETS
+
+ // Clear compCurStmt and compCurLifeTree.
+ compiler->compCurStmt = nullptr;
+ compiler->compCurLifeTree = nullptr;
+
+ // Traverse the block in linear order, generating code for each node as we
+ // as we encounter it.
+ CLANG_FORMAT_COMMENT_ANCHOR;
+
+#ifdef DEBUG
+ // Set the use-order numbers for each node.
+ {
+ int useNum = 0;
+ for (GenTree* node : LIR::AsRange(block).NonPhiNodes())
+ {
+ assert((node->gtDebugFlags & GTF_DEBUG_NODE_CG_CONSUMED) == 0);
+
+ node->gtUseNum = -1;
+ if (node->isContained() || node->IsCopyOrReload())
+ {
+ continue;
+ }
+
+ for (GenTree* operand : node->Operands())
+ {
+ genNumberOperandUse(operand, useNum);
+ }
+ }
+ }
+#endif // DEBUG
+
+ IL_OFFSETX currentILOffset = BAD_IL_OFFSET;
+ for (GenTree* node : LIR::AsRange(block).NonPhiNodes())
+ {
+ // Do we have a new IL offset?
+ if (node->OperGet() == GT_IL_OFFSET)
+ {
+ genEnsureCodeEmitted(currentILOffset);
+ currentILOffset = node->gtStmt.gtStmtILoffsx;
+ genIPmappingAdd(currentILOffset, firstMapping);
+ firstMapping = false;
+ }
+
+#ifdef DEBUG
+ if (node->OperGet() == GT_IL_OFFSET)
+ {
+ noway_assert(node->gtStmt.gtStmtLastILoffs <= compiler->info.compILCodeSize ||
+ node->gtStmt.gtStmtLastILoffs == BAD_IL_OFFSET);
+
+ if (compiler->opts.dspCode && compiler->opts.dspInstrs &&
+ node->gtStmt.gtStmtLastILoffs != BAD_IL_OFFSET)
+ {
+ while (genCurDispOffset <= node->gtStmt.gtStmtLastILoffs)
+ {
+ genCurDispOffset += dumpSingleInstr(compiler->info.compCode, genCurDispOffset, "> ");
+ }
+ }
+ }
+#endif // DEBUG
+
+ genCodeForTreeNode(node);
+ if (node->gtHasReg() && node->gtLsraInfo.isLocalDefUse)
+ {
+ genConsumeReg(node);
+ }
+ } // end for each node in block
+
+#ifdef DEBUG
+ // The following set of register spill checks and GC pointer tracking checks used to be
+ // performed at statement boundaries. Now, with LIR, there are no statements, so they are
+ // performed at the end of each block.
+ // TODO: could these checks be performed more frequently? E.g., at each location where
+ // the register allocator says there are no live non-variable registers. Perhaps this could
+ // be done by (a) keeping a running count of live non-variable registers by using
+ // gtLsraInfo.srcCount and gtLsraInfo.dstCount to decrement and increment the count, respectively,
+ // and running the checks when the count is zero. Or, (b) use the map maintained by LSRA
+ // (operandToLocationInfoMap) to mark a node somehow when, after the execution of that node,
+ // there will be no live non-variable registers.
+
+ regSet.rsSpillChk();
+
+ /* Make sure we didn't bungle pointer register tracking */
+
+ regMaskTP ptrRegs = gcInfo.gcRegGCrefSetCur | gcInfo.gcRegByrefSetCur;
+ regMaskTP nonVarPtrRegs = ptrRegs & ~regSet.rsMaskVars;
+
+ // If return is a GC-type, clear it. Note that if a common
+ // epilog is generated (genReturnBB) it has a void return
+ // even though we might return a ref. We can't use the compRetType
+ // as the determiner because something we are tracking as a byref
+ // might be used as a return value of a int function (which is legal)
+ GenTree* blockLastNode = block->lastNode();
+ if ((blockLastNode != nullptr) && (blockLastNode->gtOper == GT_RETURN) &&
+ (varTypeIsGC(compiler->info.compRetType) ||
+ (blockLastNode->gtOp.gtOp1 != nullptr && varTypeIsGC(blockLastNode->gtOp.gtOp1->TypeGet()))))
+ {
+ nonVarPtrRegs &= ~RBM_INTRET;
+ }
+
+ if (nonVarPtrRegs)
+ {
+ printf("Regset after BB%02u gcr=", block->bbNum);
+ printRegMaskInt(gcInfo.gcRegGCrefSetCur & ~regSet.rsMaskVars);
+ compiler->getEmitter()->emitDispRegSet(gcInfo.gcRegGCrefSetCur & ~regSet.rsMaskVars);
+ printf(", byr=");
+ printRegMaskInt(gcInfo.gcRegByrefSetCur & ~regSet.rsMaskVars);
+ compiler->getEmitter()->emitDispRegSet(gcInfo.gcRegByrefSetCur & ~regSet.rsMaskVars);
+ printf(", regVars=");
+ printRegMaskInt(regSet.rsMaskVars);
+ compiler->getEmitter()->emitDispRegSet(regSet.rsMaskVars);
+ printf("\n");
+ }
+
+ noway_assert(nonVarPtrRegs == RBM_NONE);
+#endif // DEBUG
+
+#if defined(DEBUG)
+ if (block->bbNext == nullptr)
+ {
+// Unit testing of the emitter: generate a bunch of instructions into the last block
+// (it's as good as any, but better than the prolog, which can only be a single instruction
+// group) then use COMPlus_JitLateDisasm=* to see if the late disassembler
+// thinks the instructions are the same as we do.
+#if defined(_TARGET_AMD64_) && defined(LATE_DISASM)
+ genAmd64EmitterUnitTests();
+#elif defined(_TARGET_ARM64_)
+ genArm64EmitterUnitTests();
+#endif // _TARGET_ARM64_
+ }
+#endif // defined(DEBUG)
+
+ // It is possible to reach the end of the block without generating code for the current IL offset.
+ // For example, if the following IR ends the current block, no code will have been generated for
+ // offset 21:
+ //
+ // ( 0, 0) [000040] ------------ il_offset void IL offset: 21
+ //
+ // N001 ( 0, 0) [000039] ------------ nop void
+ //
+ // This can lead to problems when debugging the generated code. To prevent these issues, make sure
+ // we've generated code for the last IL offset we saw in the block.
+ genEnsureCodeEmitted(currentILOffset);
+
+ if (compiler->opts.compScopeInfo && (compiler->info.compVarScopesCount > 0))
+ {
+ siEndBlock(block);
+
+ /* Is this the last block, and are there any open scopes left ? */
+
+ bool isLastBlockProcessed = (block->bbNext == nullptr);
+ if (block->isBBCallAlwaysPair())
+ {
+ isLastBlockProcessed = (block->bbNext->bbNext == nullptr);
+ }
+
+ if (isLastBlockProcessed && siOpenScopeList.scNext)
+ {
+ /* This assert no longer holds, because we may insert a throw
+ block to demarcate the end of a try or finally region when they
+ are at the end of the method. It would be nice if we could fix
+ our code so that this throw block will no longer be necessary. */
+
+ // noway_assert(block->bbCodeOffsEnd != compiler->info.compILCodeSize);
+
+ siCloseAllOpenScopes();
+ }
+ }
+
+ genStackLevel -= savedStkLvl;
+
+#ifdef DEBUG
+ // compCurLife should be equal to the liveOut set, except that we don't keep
+ // it up to date for vars that are not register candidates
+ // (it would be nice to have a xor set function)
+
+ VARSET_TP VARSET_INIT_NOCOPY(extraLiveVars, VarSetOps::Diff(compiler, block->bbLiveOut, compiler->compCurLife));
+ VarSetOps::UnionD(compiler, extraLiveVars, VarSetOps::Diff(compiler, compiler->compCurLife, block->bbLiveOut));
+ VARSET_ITER_INIT(compiler, extraLiveVarIter, extraLiveVars, extraLiveVarIndex);
+ while (extraLiveVarIter.NextElem(compiler, &extraLiveVarIndex))
+ {
+ unsigned varNum = compiler->lvaTrackedToVarNum[extraLiveVarIndex];
+ LclVarDsc* varDsc = compiler->lvaTable + varNum;
+ assert(!varDsc->lvIsRegCandidate());
+ }
+#endif
+
+ /* Both stacks should always be empty on exit from a basic block */
+ noway_assert(genStackLevel == 0);
+
+#ifdef _TARGET_AMD64_
+ // On AMD64, we need to generate a NOP after a call that is the last instruction of the block, in several
+ // situations, to support proper exception handling semantics. This is mostly to ensure that when the stack
+ // walker computes an instruction pointer for a frame, that instruction pointer is in the correct EH region.
+ // The document "X64 and ARM ABIs.docx" has more details. The situations:
+ // 1. If the call instruction is in a different EH region as the instruction that follows it.
+ // 2. If the call immediately precedes an OS epilog. (Note that what the JIT or VM consider an epilog might
+ // be slightly different from what the OS considers an epilog, and it is the OS-reported epilog that matters
+ // here.)
+ // We handle case #1 here, and case #2 in the emitter.
+ if (getEmitter()->emitIsLastInsCall())
+ {
+ // Ok, the last instruction generated is a call instruction. Do any of the other conditions hold?
+ // Note: we may be generating a few too many NOPs for the case of call preceding an epilog. Technically,
+ // if the next block is a BBJ_RETURN, an epilog will be generated, but there may be some instructions
+ // generated before the OS epilog starts, such as a GS cookie check.
+ if ((block->bbNext == nullptr) || !BasicBlock::sameEHRegion(block, block->bbNext))
+ {
+ // We only need the NOP if we're not going to generate any more code as part of the block end.
+
+ switch (block->bbJumpKind)
+ {
+ case BBJ_ALWAYS:
+ case BBJ_THROW:
+ case BBJ_CALLFINALLY:
+ case BBJ_EHCATCHRET:
+ // We're going to generate more code below anyway, so no need for the NOP.
+
+ case BBJ_RETURN:
+ case BBJ_EHFINALLYRET:
+ case BBJ_EHFILTERRET:
+ // These are the "epilog follows" case, handled in the emitter.
+
+ break;
+
+ case BBJ_NONE:
+ if (block->bbNext == nullptr)
+ {
+ // Call immediately before the end of the code; we should never get here .
+ instGen(INS_BREAKPOINT); // This should never get executed
+ }
+ else
+ {
+ // We need the NOP
+ instGen(INS_nop);
+ }
+ break;
+
+ case BBJ_COND:
+ case BBJ_SWITCH:
+ // These can't have a call as the last instruction!
+
+ default:
+ noway_assert(!"Unexpected bbJumpKind");
+ break;
+ }
+ }
+ }
+#endif // _TARGET_AMD64_
+
+ /* Do we need to generate a jump or return? */
+
+ switch (block->bbJumpKind)
+ {
+ case BBJ_ALWAYS:
+ inst_JMP(EJ_jmp, block->bbJumpDest);
+ break;
+
+ case BBJ_RETURN:
+ genExitCode(block);
+ break;
+
+ case BBJ_THROW:
+ // If we have a throw at the end of a function or funclet, we need to emit another instruction
+ // afterwards to help the OS unwinder determine the correct context during unwind.
+ // We insert an unexecuted breakpoint instruction in several situations
+ // following a throw instruction:
+ // 1. If the throw is the last instruction of the function or funclet. This helps
+ // the OS unwinder determine the correct context during an unwind from the
+ // thrown exception.
+ // 2. If this is this is the last block of the hot section.
+ // 3. If the subsequent block is a special throw block.
+ // 4. On AMD64, if the next block is in a different EH region.
+ if ((block->bbNext == nullptr) || (block->bbNext->bbFlags & BBF_FUNCLET_BEG) ||
+ !BasicBlock::sameEHRegion(block, block->bbNext) ||
+ (!isFramePointerUsed() && compiler->fgIsThrowHlpBlk(block->bbNext)) ||
+ block->bbNext == compiler->fgFirstColdBlock)
+ {
+ instGen(INS_BREAKPOINT); // This should never get executed
+ }
+
+ break;
+
+ case BBJ_CALLFINALLY:
+ block = genCallFinally(block, lblk);
+ break;
+
+#if FEATURE_EH_FUNCLETS
+
+ case BBJ_EHCATCHRET:
+ genEHCatchRet(block);
+ __fallthrough;
+
+ case BBJ_EHFINALLYRET:
+ case BBJ_EHFILTERRET:
+ genReserveFuncletEpilog(block);
+ break;
+
+#else // !FEATURE_EH_FUNCLETS
+
+ case BBJ_EHCATCHRET:
+ noway_assert(!"Unexpected BBJ_EHCATCHRET"); // not used on x86
+
+ case BBJ_EHFINALLYRET:
+ case BBJ_EHFILTERRET:
+ genEHFinallyOrFilterRet(block);
+ break;
+
+#endif // !FEATURE_EH_FUNCLETS
+
+ case BBJ_NONE:
+ case BBJ_COND:
+ case BBJ_SWITCH:
+ break;
+
+ default:
+ noway_assert(!"Unexpected bbJumpKind");
+ break;
+ }
+
+#ifdef DEBUG
+ compiler->compCurBB = nullptr;
+#endif
+
+ } //------------------ END-FOR each block of the method -------------------
+
+ /* Nothing is live at this point */
+ genUpdateLife(VarSetOps::MakeEmpty(compiler));
+
+ /* Finalize the spill tracking logic */
+
+ regSet.rsSpillEnd();
+
+ /* Finalize the temp tracking logic */
+
+ compiler->tmpEnd();
+
+#ifdef DEBUG
+ if (compiler->verbose)
+ {
+ printf("\n# ");
+ printf("compCycleEstimate = %6d, compSizeEstimate = %5d ", compiler->compCycleEstimate,
+ compiler->compSizeEstimate);
+ printf("%s\n", compiler->info.compFullName);
+ }
+#endif
+}
+
+/*
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XX XX
+XX Register Management XX
+XX XX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+*/
+//
+
+//------------------------------------------------------------------------
+// genGetAssignedReg: Get the register assigned to the given node
+//
+// Arguments:
+// tree - the lclVar node whose assigned register we want
+//
+// Return Value:
+// The assigned regNumber
+//
+regNumber CodeGenInterface::genGetAssignedReg(GenTreePtr tree)
+{
+ return tree->gtRegNum;
+}
+
+//------------------------------------------------------------------------
+// genSpillVar: Spill a local variable
+//
+// Arguments:
+// tree - the lclVar node for the variable being spilled
+//
+// Return Value:
+// None.
+//
+// Assumptions:
+// The lclVar must be a register candidate (lvRegCandidate)
+
+void CodeGen::genSpillVar(GenTreePtr tree)
+{
+ unsigned varNum = tree->gtLclVarCommon.gtLclNum;
+ LclVarDsc* varDsc = &(compiler->lvaTable[varNum]);
+
+ assert(varDsc->lvIsRegCandidate());
+
+ // We don't actually need to spill if it is already living in memory
+ bool needsSpill = ((tree->gtFlags & GTF_VAR_DEF) == 0 && varDsc->lvIsInReg());
+ if (needsSpill)
+ {
+ // In order for a lclVar to have been allocated to a register, it must not have been aliasable, and can
+ // therefore be store-normalized (rather than load-normalized). In fact, not performing store normalization
+ // can lead to problems on architectures where a lclVar may be allocated to a register that is not
+ // addressable at the granularity of the lclVar's defined type (e.g. x86).
+ var_types lclTyp = genActualType(varDsc->TypeGet());
+ emitAttr size = emitTypeSize(lclTyp);
+
+ bool restoreRegVar = false;
+ if (tree->gtOper == GT_REG_VAR)
+ {
+ tree->SetOper(GT_LCL_VAR);
+ restoreRegVar = true;
+ }
+
+ // mask off the flag to generate the right spill code, then bring it back
+ tree->gtFlags &= ~GTF_REG_VAL;
+
+ instruction storeIns = ins_Store(tree->TypeGet(), compiler->isSIMDTypeLocalAligned(varNum));
+#if CPU_LONG_USES_REGPAIR
+ if (varTypeIsMultiReg(tree))
+ {
+ assert(varDsc->lvRegNum == genRegPairLo(tree->gtRegPair));
+ assert(varDsc->lvOtherReg == genRegPairHi(tree->gtRegPair));
+ regNumber regLo = genRegPairLo(tree->gtRegPair);
+ regNumber regHi = genRegPairHi(tree->gtRegPair);
+ inst_TT_RV(storeIns, tree, regLo);
+ inst_TT_RV(storeIns, tree, regHi, 4);
+ }
+ else
+#endif
+ {
+ assert(varDsc->lvRegNum == tree->gtRegNum);
+ inst_TT_RV(storeIns, tree, tree->gtRegNum, 0, size);
+ }
+ tree->gtFlags |= GTF_REG_VAL;
+
+ if (restoreRegVar)
+ {
+ tree->SetOper(GT_REG_VAR);
+ }
+
+ genUpdateRegLife(varDsc, /*isBorn*/ false, /*isDying*/ true DEBUGARG(tree));
+ gcInfo.gcMarkRegSetNpt(varDsc->lvRegMask());
+
+ if (VarSetOps::IsMember(compiler, gcInfo.gcTrkStkPtrLcls, varDsc->lvVarIndex))
+ {
+#ifdef DEBUG
+ if (!VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex))
+ {
+ JITDUMP("\t\t\t\t\t\t\tVar V%02u becoming live\n", varNum);
+ }
+ else
+ {
+ JITDUMP("\t\t\t\t\t\t\tVar V%02u continuing live\n", varNum);
+ }
+#endif
+ VarSetOps::AddElemD(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex);
+ }
+ }
+
+ tree->gtFlags &= ~GTF_SPILL;
+ varDsc->lvRegNum = REG_STK;
+ if (varTypeIsMultiReg(tree))
+ {
+ varDsc->lvOtherReg = REG_STK;
+ }
+}
+
+//------------------------------------------------------------------------
+// genUpdateVarReg: Update the current register location for a lclVar
+//
+// Arguments:
+// varDsc - the LclVarDsc for the lclVar
+// tree - the lclVar node
+//
+// inline
+void CodeGenInterface::genUpdateVarReg(LclVarDsc* varDsc, GenTreePtr tree)
+{
+ assert(tree->OperIsScalarLocal() || (tree->gtOper == GT_COPY));
+ varDsc->lvRegNum = tree->gtRegNum;
+}
+
+//------------------------------------------------------------------------
+// sameRegAsDst: Return the child that has the same reg as the dst (if any)
+//
+// Arguments:
+// tree - the node of interest
+// other - an out parameter to return the other child
+//
+// Notes:
+// If 'tree' has a child with the same assigned register as its target reg,
+// that child will be returned, and 'other' will contain the non-matching child.
+// Otherwise, both other and the return value will be nullptr.
+//
+GenTree* sameRegAsDst(GenTree* tree, GenTree*& other /*out*/)
+{
+ if (tree->gtRegNum == REG_NA)
+ {
+ other = nullptr;
+ return nullptr;
+ }
+
+ GenTreePtr op1 = tree->gtOp.gtOp1;
+ GenTreePtr op2 = tree->gtOp.gtOp2;
+ if (op1->gtRegNum == tree->gtRegNum)
+ {
+ other = op2;
+ return op1;
+ }
+ if (op2->gtRegNum == tree->gtRegNum)
+ {
+ other = op1;
+ return op2;
+ }
+ else
+ {
+ other = nullptr;
+ return nullptr;
+ }
+}
+
+//------------------------------------------------------------------------
+// genUnspillRegIfNeeded: Reload the value into a register, if needed
+//
+// Arguments:
+// tree - the node of interest.
+//
+// Notes:
+// In the normal case, the value will be reloaded into the register it
+// was originally computed into. However, if that register is not available,
+// the register allocator will have allocated a different register, and
+// inserted a GT_RELOAD to indicate the register into which it should be
+// reloaded.
+//
+void CodeGen::genUnspillRegIfNeeded(GenTree* tree)
+{
+ regNumber dstReg = tree->gtRegNum;
+ GenTree* unspillTree = tree;
+
+ if (tree->gtOper == GT_RELOAD)
+ {
+ unspillTree = tree->gtOp.gtOp1;
+ }
+
+ if ((unspillTree->gtFlags & GTF_SPILLED) != 0)
+ {
+ if (genIsRegCandidateLocal(unspillTree))
+ {
+ // Reset spilled flag, since we are going to load a local variable from its home location.
+ unspillTree->gtFlags &= ~GTF_SPILLED;
+
+ GenTreeLclVarCommon* lcl = unspillTree->AsLclVarCommon();
+ LclVarDsc* varDsc = &compiler->lvaTable[lcl->gtLclNum];
+
+// TODO-Cleanup: The following code could probably be further merged and cleaned up.
+#ifdef _TARGET_XARCH_
+ // Load local variable from its home location.
+ // In most cases the tree type will indicate the correct type to use for the load.
+ // However, if it is NOT a normalizeOnLoad lclVar (i.e. NOT a small int that always gets
+ // widened when loaded into a register), and its size is not the same as genActualType of
+ // the type of the lclVar, then we need to change the type of the tree node when loading.
+ // This situation happens due to "optimizations" that avoid a cast and
+ // simply retype the node when using long type lclVar as an int.
+ // While loading the int in that case would work for this use of the lclVar, if it is
+ // later used as a long, we will have incorrectly truncated the long.
+ // In the normalizeOnLoad case ins_Load will return an appropriate sign- or zero-
+ // extending load.
+
+ var_types treeType = unspillTree->TypeGet();
+ if (treeType != genActualType(varDsc->lvType) && !varTypeIsGC(treeType) && !varDsc->lvNormalizeOnLoad())
+ {
+ assert(!varTypeIsGC(varDsc));
+ var_types spillType = genActualType(varDsc->lvType);
+ unspillTree->gtType = spillType;
+ inst_RV_TT(ins_Load(spillType, compiler->isSIMDTypeLocalAligned(lcl->gtLclNum)), dstReg, unspillTree);
+ unspillTree->gtType = treeType;
+ }
+ else
+ {
+ inst_RV_TT(ins_Load(treeType, compiler->isSIMDTypeLocalAligned(lcl->gtLclNum)), dstReg, unspillTree);
+ }
+#elif defined(_TARGET_ARM64_)
+ var_types targetType = unspillTree->gtType;
+ instruction ins = ins_Load(targetType, compiler->isSIMDTypeLocalAligned(lcl->gtLclNum));
+ emitAttr attr = emitTypeSize(targetType);
+ emitter* emit = getEmitter();
+
+ // Fixes Issue #3326
+ attr = emit->emitInsAdjustLoadStoreAttr(ins, attr);
+
+ // Load local variable from its home location.
+ inst_RV_TT(ins, dstReg, unspillTree, 0, attr);
+#else
+ NYI("Unspilling not implemented for this target architecture.");
+#endif
+ unspillTree->SetInReg();
+
+ // TODO-Review: We would like to call:
+ // genUpdateRegLife(varDsc, /*isBorn*/ true, /*isDying*/ false DEBUGARG(tree));
+ // instead of the following code, but this ends up hitting this assert:
+ // assert((regSet.rsMaskVars & regMask) == 0);
+ // due to issues with LSRA resolution moves.
+ // So, just force it for now. This probably indicates a condition that creates a GC hole!
+ //
+ // Extra note: I think we really want to call something like gcInfo.gcUpdateForRegVarMove,
+ // because the variable is not really going live or dead, but that method is somewhat poorly
+ // factored because it, in turn, updates rsMaskVars which is part of RegSet not GCInfo.
+ // TODO-Cleanup: This code exists in other CodeGen*.cpp files, and should be moved to CodeGenCommon.cpp.
+
+ // Don't update the variable's location if we are just re-spilling it again.
+
+ if ((unspillTree->gtFlags & GTF_SPILL) == 0)
+ {
+ genUpdateVarReg(varDsc, tree);
+#ifdef DEBUG
+ if (VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex))
+ {
+ JITDUMP("\t\t\t\t\t\t\tRemoving V%02u from gcVarPtrSetCur\n", lcl->gtLclNum);
+ }
+#endif // DEBUG
+ VarSetOps::RemoveElemD(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex);
+
+#ifdef DEBUG
+ if (compiler->verbose)
+ {
+ printf("\t\t\t\t\t\t\tV%02u in reg ", lcl->gtLclNum);
+ varDsc->PrintVarReg();
+ printf(" is becoming live ");
+ compiler->printTreeID(unspillTree);
+ printf("\n");
+ }
+#endif // DEBUG
+
+ regSet.AddMaskVars(genGetRegMask(varDsc));
+ }
+
+ gcInfo.gcMarkRegPtrVal(dstReg, unspillTree->TypeGet());
+ }
+ else if (unspillTree->IsMultiRegCall())
+ {
+ GenTreeCall* call = unspillTree->AsCall();
+ ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc();
+ unsigned regCount = retTypeDesc->GetReturnRegCount();
+ GenTreeCopyOrReload* reloadTree = nullptr;
+ if (tree->OperGet() == GT_RELOAD)
+ {
+ reloadTree = tree->AsCopyOrReload();
+ }
+
+ // In case of multi-reg call node, GTF_SPILLED flag on it indicates that
+ // one or more of its result regs are spilled. Call node needs to be
+ // queried to know which specific result regs to be unspilled.
+ for (unsigned i = 0; i < regCount; ++i)
+ {
+ unsigned flags = call->GetRegSpillFlagByIdx(i);
+ if ((flags & GTF_SPILLED) != 0)
+ {
+ var_types dstType = retTypeDesc->GetReturnRegType(i);
+ regNumber unspillTreeReg = call->GetRegNumByIdx(i);
+
+ if (reloadTree != nullptr)
+ {
+ dstReg = reloadTree->GetRegNumByIdx(i);
+ if (dstReg == REG_NA)
+ {
+ dstReg = unspillTreeReg;
+ }
+ }
+ else
+ {
+ dstReg = unspillTreeReg;
+ }
+
+ TempDsc* t = regSet.rsUnspillInPlace(call, unspillTreeReg, i);
+ getEmitter()->emitIns_R_S(ins_Load(dstType), emitActualTypeSize(dstType), dstReg, t->tdTempNum(),
+ 0);
+ compiler->tmpRlsTemp(t);
+ gcInfo.gcMarkRegPtrVal(dstReg, dstType);
+ }
+ }
+
+ unspillTree->gtFlags &= ~GTF_SPILLED;
+ unspillTree->SetInReg();
+ }
+ else
+ {
+ TempDsc* t = regSet.rsUnspillInPlace(unspillTree, unspillTree->gtRegNum);
+ getEmitter()->emitIns_R_S(ins_Load(unspillTree->gtType), emitActualTypeSize(unspillTree->TypeGet()), dstReg,
+ t->tdTempNum(), 0);
+ compiler->tmpRlsTemp(t);
+
+ unspillTree->gtFlags &= ~GTF_SPILLED;
+ unspillTree->SetInReg();
+ gcInfo.gcMarkRegPtrVal(dstReg, unspillTree->TypeGet());
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+// genCopyRegIfNeeded: Copy the given node into the specified register
+//
+// Arguments:
+// node - The node that has been evaluated (consumed).
+// needReg - The register in which its value is needed.
+//
+// Notes:
+// This must be a node that has a register.
+//
+void CodeGen::genCopyRegIfNeeded(GenTree* node, regNumber needReg)
+{
+ assert((node->gtRegNum != REG_NA) && (needReg != REG_NA));
+ if (node->gtRegNum != needReg)
+ {
+ inst_RV_RV(INS_mov, needReg, node->gtRegNum, node->TypeGet());
+ }
+}
+
+// Do Liveness update for a subnodes that is being consumed by codegen
+// including the logic for reload in case is needed and also takes care
+// of locating the value on the desired register.
+void CodeGen::genConsumeRegAndCopy(GenTree* node, regNumber needReg)
+{
+ if (needReg == REG_NA)
+ {
+ return;
+ }
+ regNumber treeReg = genConsumeReg(node);
+ genCopyRegIfNeeded(node, needReg);
+}
+
+// Check that registers are consumed in the right order for the current node being generated.
+#ifdef DEBUG
+void CodeGen::genNumberOperandUse(GenTree* const operand, int& useNum) const
+{
+ assert(operand != nullptr);
+ assert(operand->gtUseNum == -1);
+
+ // Ignore argument placeholders.
+ if (operand->OperGet() == GT_ARGPLACE)
+ {
+ return;
+ }
+
+ if (!operand->isContained() && !operand->IsCopyOrReload())
+ {
+ operand->gtUseNum = useNum;
+ useNum++;
+ }
+ else
+ {
+ for (GenTree* operand : operand->Operands())
+ {
+ genNumberOperandUse(operand, useNum);
+ }
+ }
+}
+
+void CodeGen::genCheckConsumeNode(GenTree* const node)
+{
+ assert(node != nullptr);
+
+ if (verbose)
+ {
+ if ((node->gtDebugFlags & GTF_DEBUG_NODE_CG_CONSUMED) != 0)
+ {
+ printf("Node was consumed twice:\n");
+ compiler->gtDispTree(node, nullptr, nullptr, true);
+ }
+ else if ((lastConsumedNode != nullptr) && (node->gtUseNum < lastConsumedNode->gtUseNum))
+ {
+ printf("Nodes were consumed out-of-order:\n");
+ compiler->gtDispTree(lastConsumedNode, nullptr, nullptr, true);
+ compiler->gtDispTree(node, nullptr, nullptr, true);
+ }
+ }
+
+ assert((node->OperGet() == GT_CATCH_ARG) || ((node->gtDebugFlags & GTF_DEBUG_NODE_CG_CONSUMED) == 0));
+ assert((lastConsumedNode == nullptr) || (node->gtUseNum == -1) || (node->gtUseNum > lastConsumedNode->gtUseNum));
+
+ node->gtDebugFlags |= GTF_DEBUG_NODE_CG_CONSUMED;
+ lastConsumedNode = node;
+}
+#endif // DEBUG
+
+//--------------------------------------------------------------------
+// genConsumeReg: Do liveness update for a subnode that is being
+// consumed by codegen.
+//
+// Arguments:
+// tree - GenTree node
+//
+// Return Value:
+// Returns the reg number of tree.
+// In case of multi-reg call node returns the first reg number
+// of the multi-reg return.
+regNumber CodeGen::genConsumeReg(GenTree* tree)
+{
+ if (tree->OperGet() == GT_COPY)
+ {
+ genRegCopy(tree);
+ }
+
+ // Handle the case where we have a lclVar that needs to be copied before use (i.e. because it
+ // interferes with one of the other sources (or the target, if it's a "delayed use" register)).
+ // TODO-Cleanup: This is a special copyReg case in LSRA - consider eliminating these and
+ // always using GT_COPY to make the lclVar location explicit.
+ // Note that we have to do this before calling genUpdateLife because otherwise if we spill it
+ // the lvRegNum will be set to REG_STK and we will lose track of what register currently holds
+ // the lclVar (normally when a lclVar is spilled it is then used from its former register
+ // location, which matches the gtRegNum on the node).
+ // (Note that it doesn't matter if we call this before or after genUnspillRegIfNeeded
+ // because if it's on the stack it will always get reloaded into tree->gtRegNum).
+ if (genIsRegCandidateLocal(tree))
+ {
+ GenTreeLclVarCommon* lcl = tree->AsLclVarCommon();
+ LclVarDsc* varDsc = &compiler->lvaTable[lcl->GetLclNum()];
+ if (varDsc->lvRegNum != REG_STK && varDsc->lvRegNum != tree->gtRegNum)
+ {
+ inst_RV_RV(ins_Copy(tree->TypeGet()), tree->gtRegNum, varDsc->lvRegNum);
+ }
+ }
+
+ genUnspillRegIfNeeded(tree);
+
+ // genUpdateLife() will also spill local var if marked as GTF_SPILL by calling CodeGen::genSpillVar
+ genUpdateLife(tree);
+
+ assert(tree->gtHasReg());
+
+ // there are three cases where consuming a reg means clearing the bit in the live mask
+ // 1. it was not produced by a local
+ // 2. it was produced by a local that is going dead
+ // 3. it was produced by a local that does not live in that reg (like one allocated on the stack)
+
+ if (genIsRegCandidateLocal(tree))
+ {
+ GenTreeLclVarCommon* lcl = tree->AsLclVarCommon();
+ LclVarDsc* varDsc = &compiler->lvaTable[lcl->GetLclNum()];
+ assert(varDsc->lvLRACandidate);
+
+ if ((tree->gtFlags & GTF_VAR_DEATH) != 0)
+ {
+ gcInfo.gcMarkRegSetNpt(genRegMask(varDsc->lvRegNum));
+ }
+ else if (varDsc->lvRegNum == REG_STK)
+ {
+ // We have loaded this into a register only temporarily
+ gcInfo.gcMarkRegSetNpt(genRegMask(tree->gtRegNum));
+ }
+ }
+ else
+ {
+ gcInfo.gcMarkRegSetNpt(tree->gtGetRegMask());
+ }
+
+ genCheckConsumeNode(tree);
+ return tree->gtRegNum;
+}
+
+// Do liveness update for an address tree: one of GT_LEA, GT_LCL_VAR, or GT_CNS_INT (for call indirect).
+void CodeGen::genConsumeAddress(GenTree* addr)
+{
+ if (!addr->isContained())
+ {
+ genConsumeReg(addr);
+ }
+ else if (addr->OperGet() == GT_LEA)
+ {
+ genConsumeAddrMode(addr->AsAddrMode());
+ }
+}
+
+// do liveness update for a subnode that is being consumed by codegen
+void CodeGen::genConsumeAddrMode(GenTreeAddrMode* addr)
+{
+ genConsumeOperands(addr);
+}
+
+void CodeGen::genConsumeRegs(GenTree* tree)
+{
+#if !defined(_TARGET_64BIT_)
+ if (tree->OperGet() == GT_LONG)
+ {
+ genConsumeRegs(tree->gtGetOp1());
+ genConsumeRegs(tree->gtGetOp2());
+ return;
+ }
+#endif // !defined(_TARGET_64BIT_)
+
+ if (tree->isContained())
+ {
+ if (tree->isContainedSpillTemp())
+ {
+ // spill temps are un-tracked and hence no need to update life
+ }
+ else if (tree->isIndir())
+ {
+ genConsumeAddress(tree->AsIndir()->Addr());
+ }
+ else if (tree->OperGet() == GT_AND)
+ {
+ // This is the special contained GT_AND that we created in Lowering::TreeNodeInfoInitCmp()
+ // Now we need to consume the operands of the GT_AND node.
+ genConsumeOperands(tree->AsOp());
+ }
+#ifdef _TARGET_XARCH_
+ else if (tree->OperGet() == GT_LCL_VAR)
+ {
+ // A contained lcl var must be living on stack and marked as reg optional, or not be a
+ // register candidate.
+ unsigned varNum = tree->AsLclVarCommon()->GetLclNum();
+ LclVarDsc* varDsc = compiler->lvaTable + varNum;
+
+ noway_assert(varDsc->lvRegNum == REG_STK);
+ noway_assert(tree->IsRegOptional() || !varDsc->lvLRACandidate);
+
+ // Update the life of the lcl var.
+ genUpdateLife(tree);
+ }
+#endif // _TARGET_XARCH_
+ else if (tree->OperIsInitVal())
+ {
+ genConsumeReg(tree->gtGetOp1());
+ }
+ else
+ {
+#ifdef FEATURE_SIMD
+ // (In)Equality operation that produces bool result, when compared
+ // against Vector zero, marks its Vector Zero operand as contained.
+ assert(tree->OperIsLeaf() || tree->IsIntegralConstVector(0));
+#else
+ assert(tree->OperIsLeaf());
+#endif
+ }
+ }
+ else
+ {
+ genConsumeReg(tree);
+ }
+}
+
+//------------------------------------------------------------------------
+// genConsumeOperands: Do liveness update for the operands of a unary or binary tree
+//
+// Arguments:
+// tree - the GenTreeOp whose operands will have their liveness updated.
+//
+// Return Value:
+// None.
+//
+// Notes:
+// Note that this logic is localized here because we must do the liveness update in
+// the correct execution order. This is important because we may have two operands
+// that involve the same lclVar, and if one is marked "lastUse" we must handle it
+// after the first.
+
+void CodeGen::genConsumeOperands(GenTreeOp* tree)
+{
+ GenTree* firstOp = tree->gtOp1;
+ GenTree* secondOp = tree->gtOp2;
+ if ((tree->gtFlags & GTF_REVERSE_OPS) != 0)
+ {
+ assert(secondOp != nullptr);
+ firstOp = secondOp;
+ secondOp = tree->gtOp1;
+ }
+ if (firstOp != nullptr)
+ {
+ genConsumeRegs(firstOp);
+ }
+ if (secondOp != nullptr)
+ {
+ genConsumeRegs(secondOp);
+ }
+}
+
+#if FEATURE_PUT_STRUCT_ARG_STK
+//------------------------------------------------------------------------
+// genConsumePutStructArgStk: Do liveness update for the operands of a PutArgStk node.
+// Also loads in the right register the addresses of the
+// src/dst for rep mov operation.
+//
+// Arguments:
+// putArgNode - the PUTARG_STK tree.
+// dstReg - the dstReg for the rep move operation.
+// srcReg - the srcReg for the rep move operation.
+// sizeReg - the sizeReg for the rep move operation.
+//
+// Return Value:
+// None.
+//
+// Notes:
+// sizeReg can be REG_NA when this function is used to consume the dstReg and srcReg
+// for copying on the stack a struct with references.
+// The source address/offset is determined from the address on the GT_OBJ node, while
+// the destination address is the address contained in 'm_stkArgVarNum' plus the offset
+// provided in the 'putArgNode'.
+// m_stkArgVarNum must be set to the varnum for the local used for placing the "by-value" args on the stack.
+
+void CodeGen::genConsumePutStructArgStk(GenTreePutArgStk* putArgNode,
+ regNumber dstReg,
+ regNumber srcReg,
+ regNumber sizeReg)
+{
+ assert(varTypeIsStruct(putArgNode));
+
+ // The putArgNode children are always contained. We should not consume any registers.
+ assert(putArgNode->gtGetOp1()->isContained());
+
+ GenTree* dstAddr = putArgNode;
+
+ // Get the source address.
+ GenTree* src = putArgNode->gtGetOp1();
+ assert((src->gtOper == GT_OBJ) || ((src->gtOper == GT_IND && varTypeIsSIMD(src))));
+ GenTree* srcAddr = src->gtGetOp1();
+
+ size_t size = putArgNode->getArgSize();
+
+ assert(dstReg != REG_NA);
+ assert(srcReg != REG_NA);
+
+ // Consume the registers only if they are not contained or set to REG_NA.
+ if (srcAddr->gtRegNum != REG_NA)
+ {
+ genConsumeReg(srcAddr);
+ }
+
+ // If the op1 is already in the dstReg - nothing to do.
+ // Otherwise load the op1 (GT_ADDR) into the dstReg to copy the struct on the stack by value.
+ CLANG_FORMAT_COMMENT_ANCHOR;
+
+#ifdef _TARGET_X86_
+ assert(dstReg != REG_SPBASE);
+ inst_RV_RV(INS_mov, dstReg, REG_SPBASE);
+#else // !_TARGET_X86_
+ if (dstAddr->gtRegNum != dstReg)
+ {
+ // Generate LEA instruction to load the stack of the outgoing var + SlotNum offset (or the incoming arg area
+ // for tail calls) in RDI.
+ // Destination is always local (on the stack) - use EA_PTRSIZE.
+ assert(m_stkArgVarNum != BAD_VAR_NUM);
+ getEmitter()->emitIns_R_S(INS_lea, EA_PTRSIZE, dstReg, m_stkArgVarNum, putArgNode->getArgOffset());
+ }
+#endif // !_TARGET_X86_
+
+ if (srcAddr->gtRegNum != srcReg)
+ {
+ if (srcAddr->OperIsLocalAddr())
+ {
+ // The OperLocalAddr is always contained.
+ assert(srcAddr->isContained());
+ GenTreeLclVarCommon* lclNode = srcAddr->AsLclVarCommon();
+
+ // Generate LEA instruction to load the LclVar address in RSI.
+ // Source is known to be on the stack. Use EA_PTRSIZE.
+ unsigned int offset = 0;
+ if (srcAddr->OperGet() == GT_LCL_FLD_ADDR)
+ {
+ offset = srcAddr->AsLclFld()->gtLclOffs;
+ }
+ getEmitter()->emitIns_R_S(INS_lea, EA_PTRSIZE, srcReg, lclNode->gtLclNum, offset);
+ }
+ else
+ {
+ assert(srcAddr->gtRegNum != REG_NA);
+ // Source is not known to be on the stack. Use EA_BYREF.
+ getEmitter()->emitIns_R_R(INS_mov, EA_BYREF, srcReg, srcAddr->gtRegNum);
+ }
+ }
+
+ if (sizeReg != REG_NA)
+ {
+ inst_RV_IV(INS_mov, sizeReg, size, EA_PTRSIZE);
+ }
+}
+#endif // FEATURE_PUT_STRUCT_ARG_STK
+
+//------------------------------------------------------------------------
+// genSetBlockSize: Ensure that the block size is in the given register
+//
+// Arguments:
+// blkNode - The block node
+// sizeReg - The register into which the block's size should go
+//
+
+void CodeGen::genSetBlockSize(GenTreeBlk* blkNode, regNumber sizeReg)
+{
+ if (sizeReg != REG_NA)
+ {
+ unsigned blockSize = blkNode->Size();
+ if (blockSize != 0)
+ {
+ assert((blkNode->gtRsvdRegs & genRegMask(sizeReg)) != 0);
+ genSetRegToIcon(sizeReg, blockSize);
+ }
+ else
+ {
+ noway_assert(blkNode->gtOper == GT_STORE_DYN_BLK);
+ GenTree* sizeNode = blkNode->AsDynBlk()->gtDynamicSize;
+ if (sizeNode->gtRegNum != sizeReg)
+ {
+ inst_RV_RV(INS_mov, sizeReg, sizeNode->gtRegNum, sizeNode->TypeGet());
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+// genConsumeBlockSrc: Consume the source address register of a block node, if any.
+//
+// Arguments:
+// blkNode - The block node
+
+void CodeGen::genConsumeBlockSrc(GenTreeBlk* blkNode)
+{
+ GenTree* src = blkNode->Data();
+ if (blkNode->OperIsCopyBlkOp())
+ {
+ // For a CopyBlk we need the address of the source.
+ if (src->OperGet() == GT_IND)
+ {
+ src = src->gtOp.gtOp1;
+ }
+ else
+ {
+ // This must be a local.
+ // For this case, there is no source address register, as it is a
+ // stack-based address.
+ assert(src->OperIsLocal());
+ return;
+ }
+ }
+ else
+ {
+ if (src->OperIsInitVal())
+ {
+ src = src->gtGetOp1();
+ }
+ }
+ genConsumeReg(src);
+}
+
+//------------------------------------------------------------------------
+// genSetBlockSrc: Ensure that the block source is in its allocated register.
+//
+// Arguments:
+// blkNode - The block node
+// srcReg - The register in which to set the source (address or init val).
+//
+void CodeGen::genSetBlockSrc(GenTreeBlk* blkNode, regNumber srcReg)
+{
+ GenTree* src = blkNode->Data();
+ if (blkNode->OperIsCopyBlkOp())
+ {
+ // For a CopyBlk we need the address of the source.
+ if (src->OperGet() == GT_IND)
+ {
+ src = src->gtOp.gtOp1;
+ }
+ else
+ {
+ // This must be a local struct.
+ // Load its address into srcReg.
+ inst_RV_TT(INS_lea, srcReg, src, 0, EA_BYREF);
+ return;
+ }
+ }
+ else
+ {
+ if (src->OperIsInitVal())
+ {
+ src = src->gtGetOp1();
+ }
+ }
+ genCopyRegIfNeeded(src, srcReg);
+}
+
+//------------------------------------------------------------------------
+// genConsumeBlockOp: Ensure that the block's operands are enregistered
+// as needed.
+// Arguments:
+// blkNode - The block node
+//
+// Notes:
+// This ensures that the operands are consumed in the proper order to
+// obey liveness modeling.
+
+void CodeGen::genConsumeBlockOp(GenTreeBlk* blkNode, regNumber dstReg, regNumber srcReg, regNumber sizeReg)
+{
+ // We have to consume the registers, and perform any copies, in the actual execution order.
+ // The nominal order is: dst, src, size. However this may have been changed
+ // with reverse flags on the blkNode and the setting of gtEvalSizeFirst in the case of a dynamic
+ // block size.
+ // Note that the register allocator ensures that the registers ON THE NODES will not interfere
+ // with one another if consumed (i.e. reloaded or moved to their ASSIGNED reg) in execution order.
+ // Further, it ensures that they will not interfere with one another if they are then copied
+ // to the REQUIRED register (if a fixed register requirement) in execution order. This requires,
+ // then, that we first consume all the operands, then do any necessary moves.
+
+ GenTree* dstAddr = blkNode->Addr();
+ GenTree* src = nullptr;
+ unsigned blockSize = blkNode->Size();
+ GenTree* size = nullptr;
+ bool evalSizeFirst = true;
+
+ // First, consume all the sources in order
+ if (blkNode->OperGet() == GT_STORE_DYN_BLK)
+ {
+ size = blkNode->AsDynBlk()->gtDynamicSize;
+ if (blkNode->AsDynBlk()->gtEvalSizeFirst)
+ {
+ genConsumeReg(size);
+ }
+ else
+ {
+ evalSizeFirst = false;
+ }
+ }
+ if (blkNode->IsReverseOp())
+ {
+
+ genConsumeBlockSrc(blkNode);
+ genConsumeReg(dstAddr);
+ }
+ else
+ {
+ genConsumeReg(dstAddr);
+ genConsumeBlockSrc(blkNode);
+ }
+ if (!evalSizeFirst)
+ {
+ noway_assert(size != nullptr);
+ genConsumeReg(size);
+ }
+
+ // Next, perform any necessary moves.
+ if (evalSizeFirst)
+ {
+ genSetBlockSize(blkNode, sizeReg);
+ }
+ if (blkNode->IsReverseOp())
+ {
+ genSetBlockSrc(blkNode, srcReg);
+ genCopyRegIfNeeded(dstAddr, dstReg);
+ }
+ else
+ {
+ genCopyRegIfNeeded(dstAddr, dstReg);
+ genSetBlockSrc(blkNode, srcReg);
+ }
+ if (!evalSizeFirst)
+ {
+ genSetBlockSize(blkNode, sizeReg);
+ }
+}
+
+//-------------------------------------------------------------------------
+// genProduceReg: do liveness update for register produced by the current
+// node in codegen.
+//
+// Arguments:
+// tree - Gentree node
+//
+// Return Value:
+// None.
+void CodeGen::genProduceReg(GenTree* tree)
+{
+#ifdef DEBUG
+ assert((tree->gtDebugFlags & GTF_DEBUG_NODE_CG_PRODUCED) == 0);
+ tree->gtDebugFlags |= GTF_DEBUG_NODE_CG_PRODUCED;
+#endif
+
+ if (tree->gtFlags & GTF_SPILL)
+ {
+ // Code for GT_COPY node gets generated as part of consuming regs by its parent.
+ // A GT_COPY node in turn produces reg result and it should never be marked to
+ // spill.
+ //
+ // Similarly GT_RELOAD node gets generated as part of consuming regs by its
+ // parent and should never be marked for spilling.
+ noway_assert(!tree->IsCopyOrReload());
+
+ if (genIsRegCandidateLocal(tree))
+ {
+ // Store local variable to its home location.
+ tree->gtFlags &= ~GTF_REG_VAL;
+ // Ensure that lclVar stores are typed correctly.
+ unsigned varNum = tree->gtLclVarCommon.gtLclNum;
+ assert(!compiler->lvaTable[varNum].lvNormalizeOnStore() ||
+ (tree->TypeGet() == genActualType(compiler->lvaTable[varNum].TypeGet())));
+ inst_TT_RV(ins_Store(tree->gtType, compiler->isSIMDTypeLocalAligned(varNum)), tree, tree->gtRegNum);
+ }
+ else
+ {
+ // In case of multi-reg call node, spill flag on call node
+ // indicates that one or more of its allocated regs need to
+ // be spilled. Call node needs to be further queried to
+ // know which of its result regs needs to be spilled.
+ if (tree->IsMultiRegCall())
+ {
+ GenTreeCall* call = tree->AsCall();
+ ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc();
+ unsigned regCount = retTypeDesc->GetReturnRegCount();
+
+ for (unsigned i = 0; i < regCount; ++i)
+ {
+ unsigned flags = call->GetRegSpillFlagByIdx(i);
+ if ((flags & GTF_SPILL) != 0)
+ {
+ regNumber reg = call->GetRegNumByIdx(i);
+ call->SetInReg();
+ regSet.rsSpillTree(reg, call, i);
+ gcInfo.gcMarkRegSetNpt(genRegMask(reg));
+ }
+ }
+ }
+ else
+ {
+ tree->SetInReg();
+ regSet.rsSpillTree(tree->gtRegNum, tree);
+ gcInfo.gcMarkRegSetNpt(genRegMask(tree->gtRegNum));
+ }
+
+ tree->gtFlags |= GTF_SPILLED;
+ tree->gtFlags &= ~GTF_SPILL;
+
+ return;
+ }
+ }
+
+ genUpdateLife(tree);
+
+ // If we've produced a register, mark it as a pointer, as needed.
+ if (tree->gtHasReg())
+ {
+ // We only mark the register in the following cases:
+ // 1. It is not a register candidate local. In this case, we're producing a
+ // register from a local, but the local is not a register candidate. Thus,
+ // we must be loading it as a temp register, and any "last use" flag on
+ // the register wouldn't be relevant.
+ // 2. The register candidate local is going dead. There's no point to mark
+ // the register as live, with a GC pointer, if the variable is dead.
+ if (!genIsRegCandidateLocal(tree) || ((tree->gtFlags & GTF_VAR_DEATH) == 0))
+ {
+ // Multi-reg call node will produce more than one register result.
+ // Mark all the regs produced by call node.
+ if (tree->IsMultiRegCall())
+ {
+ GenTreeCall* call = tree->AsCall();
+ ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc();
+ unsigned regCount = retTypeDesc->GetReturnRegCount();
+
+ for (unsigned i = 0; i < regCount; ++i)
+ {
+ regNumber reg = call->GetRegNumByIdx(i);
+ var_types type = retTypeDesc->GetReturnRegType(i);
+ gcInfo.gcMarkRegPtrVal(reg, type);
+ }
+ }
+ else if (tree->IsCopyOrReloadOfMultiRegCall())
+ {
+ // we should never see reload of multi-reg call here
+ // because GT_RELOAD gets generated in reg consuming path.
+ noway_assert(tree->OperGet() == GT_COPY);
+
+ // A multi-reg GT_COPY node produces those regs to which
+ // copy has taken place.
+ GenTreeCopyOrReload* copy = tree->AsCopyOrReload();
+ GenTreeCall* call = copy->gtGetOp1()->AsCall();
+ ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc();
+ unsigned regCount = retTypeDesc->GetReturnRegCount();
+
+ for (unsigned i = 0; i < regCount; ++i)
+ {
+ var_types type = retTypeDesc->GetReturnRegType(i);
+ regNumber fromReg = call->GetRegNumByIdx(i);
+ regNumber toReg = copy->GetRegNumByIdx(i);
+
+ if (toReg != REG_NA)
+ {
+ gcInfo.gcMarkRegPtrVal(toReg, type);
+ }
+ }
+ }
+ else
+ {
+ gcInfo.gcMarkRegPtrVal(tree->gtRegNum, tree->TypeGet());
+ }
+ }
+ }
+ tree->SetInReg();
+}
+
+// transfer gc/byref status of src reg to dst reg
+void CodeGen::genTransferRegGCState(regNumber dst, regNumber src)
+{
+ regMaskTP srcMask = genRegMask(src);
+ regMaskTP dstMask = genRegMask(dst);
+
+ if (gcInfo.gcRegGCrefSetCur & srcMask)
+ {
+ gcInfo.gcMarkRegSetGCref(dstMask);
+ }
+ else if (gcInfo.gcRegByrefSetCur & srcMask)
+ {
+ gcInfo.gcMarkRegSetByref(dstMask);
+ }
+ else
+ {
+ gcInfo.gcMarkRegSetNpt(dstMask);
+ }
+}
+
+// generates an ip-relative call or indirect call via reg ('call reg')
+// 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)
+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)
+{
+#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,
+ emitter::emitNoGChelper(compiler->eeGetHelperNum(methHnd)));
+}
+
+// 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)
+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)
+{
+#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());
+}
+
+#endif // !LEGACY_BACKEND
diff --git a/src/jit/codegenlinear.h b/src/jit/codegenlinear.h
index fb0d6ea165..406ab779f1 100644
--- a/src/jit/codegenlinear.h
+++ b/src/jit/codegenlinear.h
@@ -16,6 +16,10 @@ void genCodeForTreeNode(GenTreePtr treeNode);
void genCodeForBinary(GenTreePtr treeNode);
+#if defined(_TARGET_X86_)
+void genCodeForLongUMod(GenTreeOp* node);
+#endif // _TARGET_X86_
+
void genCodeForDivMod(GenTreeOp* treeNode);
void genCodeForMulHi(GenTreeOp* treeNode);
@@ -24,6 +28,10 @@ void genLeaInstruction(GenTreeAddrMode* lea);
void genSetRegToCond(regNumber dstReg, GenTreePtr tree);
+#if !defined(_TARGET_64BIT_)
+void genLongToIntCast(GenTreePtr treeNode);
+#endif
+
void genIntToIntCast(GenTreePtr treeNode);
void genFloatToFloatCast(GenTreePtr treeNode);
@@ -36,7 +44,7 @@ void genCkfinite(GenTreePtr treeNode);
void genIntrinsic(GenTreePtr treeNode);
-void genPutArgStk(GenTreePtr treeNode);
+void genPutArgStk(GenTreePutArgStk* treeNode);
unsigned getBaseVarForPutArgStk(GenTreePtr treeNode);
#if defined(_TARGET_XARCH_) || defined(_TARGET_ARM64_)
@@ -49,7 +57,6 @@ void genCompareInt(GenTreePtr treeNode);
#if !defined(_TARGET_64BIT_)
void genCompareLong(GenTreePtr treeNode);
-void genJTrueLong(GenTreePtr treeNode);
#endif
#ifdef FEATURE_SIMD
@@ -61,7 +68,8 @@ enum SIMDScalarMoveType
};
instruction getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_types baseType, unsigned* ival = nullptr);
-void genSIMDScalarMove(var_types type, regNumber target, regNumber src, SIMDScalarMoveType moveType);
+void genSIMDScalarMove(
+ var_types targetType, var_types type, regNumber target, regNumber src, SIMDScalarMoveType moveType);
void genSIMDZero(var_types targetType, var_types baseType, regNumber targetReg);
void genSIMDIntrinsicInit(GenTreeSIMD* simdNode);
void genSIMDIntrinsicInitN(GenTreeSIMD* simdNode);
@@ -87,7 +95,10 @@ void genSIMDCheck(GenTree* treeNode);
void genStoreIndTypeSIMD12(GenTree* treeNode);
void genStoreLclFldTypeSIMD12(GenTree* treeNode);
void genLoadIndTypeSIMD12(GenTree* treeNode);
-void genLoadLclFldTypeSIMD12(GenTree* treeNode);
+void genLoadLclTypeSIMD12(GenTree* treeNode);
+#ifdef _TARGET_X86_
+void genPutArgStkSIMD12(GenTree* treeNode);
+#endif // _TARGET_X86_
#endif // FEATURE_SIMD
#if !defined(_TARGET_64BIT_)
@@ -104,6 +115,7 @@ void genUnspillRegIfNeeded(GenTree* tree);
regNumber genConsumeReg(GenTree* tree);
+void genCopyRegIfNeeded(GenTree* tree, regNumber needReg);
void genConsumeRegAndCopy(GenTree* tree, regNumber needReg);
void genConsumeIfReg(GenTreePtr tree)
@@ -122,15 +134,14 @@ void genConsumeAddress(GenTree* addr);
void genConsumeAddrMode(GenTreeAddrMode* mode);
-void genConsumeBlockSize(GenTreeBlk* blkNode, regNumber sizeReg);
-void genConsumeBlockDst(GenTreeBlk* blkNode);
-GenTree* genConsumeBlockSrc(GenTreeBlk* blkNode);
+void genSetBlockSize(GenTreeBlk* blkNode, regNumber sizeReg);
+void genConsumeBlockSrc(GenTreeBlk* blkNode);
+void genSetBlockSrc(GenTreeBlk* blkNode, regNumber srcReg);
void genConsumeBlockOp(GenTreeBlk* blkNode, regNumber dstReg, regNumber srcReg, regNumber sizeReg);
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
-void genConsumePutStructArgStk(
- GenTreePutArgStk* putArgStkNode, regNumber dstReg, regNumber srcReg, regNumber sizeReg, unsigned baseVarNum);
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+#ifdef FEATURE_PUT_STRUCT_ARG_STK
+void genConsumePutStructArgStk(GenTreePutArgStk* putArgStkNode, regNumber dstReg, regNumber srcReg, regNumber sizeReg);
+#endif // FEATURE_PUT_STRUCT_ARG_STK
void genConsumeRegs(GenTree* tree);
@@ -142,6 +153,10 @@ void genSetRegToIcon(regNumber reg, ssize_t val, var_types type = TYP_INT, insFl
void genCodeForShift(GenTreePtr tree);
+#if defined(_TARGET_X86_)
+void genCodeForShiftLong(GenTreePtr tree);
+#endif
+
#ifdef _TARGET_XARCH_
void genCodeForShiftRMW(GenTreeStoreInd* storeInd);
#endif // _TARGET_XARCH_
@@ -154,12 +169,23 @@ void genCodeForCpBlkRepMovs(GenTreeBlk* cpBlkNode);
void genCodeForCpBlkUnroll(GenTreeBlk* cpBlkNode);
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
-void genPutStructArgStk(GenTreePtr treeNode, unsigned baseVarNum);
+#ifdef FEATURE_PUT_STRUCT_ARG_STK
+#ifdef _TARGET_X86_
+bool genAdjustStackForPutArgStk(GenTreePutArgStk* putArgStk);
+void genPushReg(var_types type, regNumber srcReg);
+void genPutArgStkFieldList(GenTreePutArgStk* putArgStk);
+#endif // _TARGET_X86_
+
+void genPutStructArgStk(GenTreePutArgStk* treeNode);
-void genStructPutArgRepMovs(GenTreePutArgStk* putArgStkNode, unsigned baseVarNum);
-void genStructPutArgUnroll(GenTreePutArgStk* putArgStkNode, unsigned baseVarNum);
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+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);
+void genStructPutArgRepMovs(GenTreePutArgStk* putArgStkNode);
+void genStructPutArgUnroll(GenTreePutArgStk* putArgStkNode);
+void genStoreRegToStackArg(var_types type, regNumber reg, int offset);
+#endif // FEATURE_PUT_STRUCT_ARG_STK
void genCodeForLoadOffset(instruction ins, emitAttr size, regNumber dst, GenTree* base, unsigned offset);
@@ -191,6 +217,14 @@ void genCallInstruction(GenTreePtr call);
void genJmpMethod(GenTreePtr jmp);
+BasicBlock* genCallFinally(BasicBlock* block, BasicBlock* lblk);
+
+#if FEATURE_EH_FUNCLETS
+void genEHCatchRet(BasicBlock* block);
+#else // !FEATURE_EH_FUNCLETS
+void genEHFinallyOrFilterRet(BasicBlock* block);
+#endif // !FEATURE_EH_FUNCLETS
+
void genMultiRegCallStoreToLocal(GenTreePtr treeNode);
// Deals with codegen for muti-register struct returns.
@@ -212,9 +246,19 @@ bool genIsRegCandidateLocal(GenTreePtr tree)
return (varDsc->lvIsRegCandidate());
}
+#ifdef FEATURE_PUT_STRUCT_ARG_STK
+#ifdef _TARGET_X86_
+bool m_pushStkArg;
+#else // !_TARGET_X86_
+unsigned m_stkArgVarNum;
+unsigned m_stkArgOffset;
+#endif // !_TARGET_X86_
+#endif // !FEATURE_PUT_STRUCT_ARG_STK
+
#ifdef DEBUG
GenTree* lastConsumedNode;
-void genCheckConsumeNode(GenTree* treeNode);
+void genNumberOperandUse(GenTree* const operand, int& useNum) const;
+void genCheckConsumeNode(GenTree* const node);
#else // !DEBUG
inline void genCheckConsumeNode(GenTree* treeNode)
{
diff --git a/src/jit/codegenxarch.cpp b/src/jit/codegenxarch.cpp
index a41c28695b..8e0af48799 100644
--- a/src/jit/codegenxarch.cpp
+++ b/src/jit/codegenxarch.cpp
@@ -24,114 +24,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include "gcinfo.h"
#include "gcinfoencoder.h"
-// Get the register assigned to the given node
-
-regNumber CodeGenInterface::genGetAssignedReg(GenTreePtr tree)
-{
- return tree->gtRegNum;
-}
-
-//------------------------------------------------------------------------
-// genSpillVar: Spill a local variable
-//
-// Arguments:
-// tree - the lclVar node for the variable being spilled
-//
-// Return Value:
-// None.
-//
-// Assumptions:
-// The lclVar must be a register candidate (lvRegCandidate)
-
-void CodeGen::genSpillVar(GenTreePtr tree)
-{
- unsigned varNum = tree->gtLclVarCommon.gtLclNum;
- LclVarDsc* varDsc = &(compiler->lvaTable[varNum]);
-
- assert(varDsc->lvIsRegCandidate());
-
- // We don't actually need to spill if it is already living in memory
- bool needsSpill = ((tree->gtFlags & GTF_VAR_DEF) == 0 && varDsc->lvIsInReg());
- if (needsSpill)
- {
- var_types lclTyp = varDsc->TypeGet();
- if (varDsc->lvNormalizeOnStore())
- {
- lclTyp = genActualType(lclTyp);
- }
- emitAttr size = emitTypeSize(lclTyp);
-
- bool restoreRegVar = false;
- if (tree->gtOper == GT_REG_VAR)
- {
- tree->SetOper(GT_LCL_VAR);
- restoreRegVar = true;
- }
-
- // mask off the flag to generate the right spill code, then bring it back
- tree->gtFlags &= ~GTF_REG_VAL;
-
- instruction storeIns = ins_Store(tree->TypeGet(), compiler->isSIMDTypeLocalAligned(varNum));
-#if CPU_LONG_USES_REGPAIR
- if (varTypeIsMultiReg(tree))
- {
- assert(varDsc->lvRegNum == genRegPairLo(tree->gtRegPair));
- assert(varDsc->lvOtherReg == genRegPairHi(tree->gtRegPair));
- regNumber regLo = genRegPairLo(tree->gtRegPair);
- regNumber regHi = genRegPairHi(tree->gtRegPair);
- inst_TT_RV(storeIns, tree, regLo);
- inst_TT_RV(storeIns, tree, regHi, 4);
- }
- else
-#endif
- {
- assert(varDsc->lvRegNum == tree->gtRegNum);
- inst_TT_RV(storeIns, tree, tree->gtRegNum, 0, size);
- }
- tree->gtFlags |= GTF_REG_VAL;
-
- if (restoreRegVar)
- {
- tree->SetOper(GT_REG_VAR);
- }
-
- genUpdateRegLife(varDsc, /*isBorn*/ false, /*isDying*/ true DEBUGARG(tree));
- gcInfo.gcMarkRegSetNpt(varDsc->lvRegMask());
-
- if (VarSetOps::IsMember(compiler, gcInfo.gcTrkStkPtrLcls, varDsc->lvVarIndex))
- {
-#ifdef DEBUG
- if (!VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex))
- {
- JITDUMP("\t\t\t\t\t\t\tVar V%02u becoming live\n", varNum);
- }
- else
- {
- JITDUMP("\t\t\t\t\t\t\tVar V%02u continuing live\n", varNum);
- }
-#endif
- VarSetOps::AddElemD(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex);
- }
- }
-
- tree->gtFlags &= ~GTF_SPILL;
- varDsc->lvRegNum = REG_STK;
- if (varTypeIsMultiReg(tree))
- {
- varDsc->lvOtherReg = REG_STK;
- }
-}
-
-// inline
-void CodeGenInterface::genUpdateVarReg(LclVarDsc* varDsc, GenTreePtr tree)
-{
- assert(tree->OperIsScalarLocal() || (tree->gtOper == GT_COPY));
- varDsc->lvRegNum = tree->gtRegNum;
-}
-
-/*****************************************************************************/
-/*****************************************************************************/
-
/*****************************************************************************
*
* Generate code that will set the given register to the integer constant.
@@ -231,6 +123,8 @@ void CodeGen::genEmitGSCookieCheck(bool pushReg)
}
regNumber regGSCheck;
+ regMaskTP regMaskGSCheck = RBM_NONE;
+
if (!pushReg)
{
// Non-tail call: we can use any callee trash register that is not
@@ -251,8 +145,11 @@ void CodeGen::genEmitGSCookieCheck(bool pushReg)
else
{
#ifdef _TARGET_X86_
- NYI_X86("Tail calls from methods that need GS check");
- regGSCheck = REG_NA;
+ // It doesn't matter which register we pick, since we're going to save and restore it
+ // around the check.
+ // TODO-CQ: Can we optimize the choice of register to avoid doing the push/pop sometimes?
+ regGSCheck = REG_EAX;
+ regMaskGSCheck = RBM_EAX;
#else // !_TARGET_X86_
// Tail calls from methods that need GS check: We need to preserve registers while
// emitting GS cookie check for a tail prefixed call or a jmp. To emit GS cookie
@@ -287,8 +184,13 @@ void CodeGen::genEmitGSCookieCheck(bool pushReg)
#endif // !_TARGET_X86_
}
+ regMaskTP byrefPushedRegs = RBM_NONE;
+ regMaskTP norefPushedRegs = RBM_NONE;
+ regMaskTP pushedRegs = RBM_NONE;
+
if (compiler->gsGlobalSecurityCookieAddr == nullptr)
{
+#if defined(_TARGET_AMD64_)
// If GS cookie value fits within 32-bits we can use 'cmp mem64, imm32'.
// Otherwise, load the value into a reg and use 'cmp mem64, reg64'.
if ((int)compiler->gsGlobalSecurityCookieVal != (ssize_t)compiler->gsGlobalSecurityCookieVal)
@@ -297,7 +199,9 @@ void CodeGen::genEmitGSCookieCheck(bool pushReg)
getEmitter()->emitIns_S_R(INS_cmp, EA_PTRSIZE, regGSCheck, compiler->lvaGSSecurityCookie, 0);
}
else
+#endif // defined(_TARGET_AMD64_)
{
+ assert((int)compiler->gsGlobalSecurityCookieVal == (ssize_t)compiler->gsGlobalSecurityCookieVal);
getEmitter()->emitIns_S_I(INS_cmp, EA_PTRSIZE, compiler->lvaGSSecurityCookie, 0,
(int)compiler->gsGlobalSecurityCookieVal);
}
@@ -305,6 +209,9 @@ void CodeGen::genEmitGSCookieCheck(bool pushReg)
else
{
// Ngen case - GS cookie value needs to be accessed through an indirection.
+
+ pushedRegs = genPushRegs(regMaskGSCheck, &byrefPushedRegs, &norefPushedRegs);
+
instGen_Set_Reg_To_Imm(EA_HANDLE_CNS_RELOC, regGSCheck, (ssize_t)compiler->gsGlobalSecurityCookieAddr);
getEmitter()->emitIns_R_AR(ins_Load(TYP_I_IMPL), EA_PTRSIZE, regGSCheck, regGSCheck, 0);
getEmitter()->emitIns_S_R(INS_cmp, EA_PTRSIZE, regGSCheck, compiler->lvaGSSecurityCookie, 0);
@@ -315,821 +222,180 @@ void CodeGen::genEmitGSCookieCheck(bool pushReg)
inst_JMP(jmpEqual, gsCheckBlk);
genEmitHelperCall(CORINFO_HELP_FAIL_FAST, 0, EA_UNKNOWN);
genDefineTempLabel(gsCheckBlk);
-}
-/*****************************************************************************
- *
- * Generate code for all the basic blocks in the function.
- */
+ genPopRegs(pushedRegs, byrefPushedRegs, norefPushedRegs);
+}
-void CodeGen::genCodeForBBlist()
+BasicBlock* CodeGen::genCallFinally(BasicBlock* block, BasicBlock* lblk)
{
- unsigned varNum;
- LclVarDsc* varDsc;
-
- unsigned savedStkLvl;
-
-#ifdef DEBUG
- genInterruptibleUsed = true;
-
- // You have to be careful if you create basic blocks from now on
- compiler->fgSafeBasicBlockCreation = false;
-
- // This stress mode is not comptible with fully interruptible GC
- if (genInterruptible && compiler->opts.compStackCheckOnCall)
- {
- compiler->opts.compStackCheckOnCall = false;
- }
-
- // This stress mode is not comptible with fully interruptible GC
- if (genInterruptible && compiler->opts.compStackCheckOnRet)
- {
- compiler->opts.compStackCheckOnRet = false;
- }
-#endif // DEBUG
-
- // Prepare the blocks for exception handling codegen: mark the blocks that needs labels.
- genPrepForEHCodegen();
-
- assert(!compiler->fgFirstBBScratch ||
- compiler->fgFirstBB == compiler->fgFirstBBScratch); // compiler->fgFirstBBScratch has to be first.
-
- /* Initialize the spill tracking logic */
-
- regSet.rsSpillBeg();
-
-#ifdef DEBUGGING_SUPPORT
- /* Initialize the line# tracking logic */
+#if FEATURE_EH_FUNCLETS
+ // Generate a call to the finally, like this:
+ // mov rcx,qword ptr [rbp + 20H] // Load rcx with PSPSym
+ // call finally-funclet
+ // jmp finally-return // Only for non-retless finally calls
+ // The jmp can be a NOP if we're going to the next block.
+ // If we're generating code for the main function (not a funclet), and there is no localloc,
+ // then RSP at this point is the same value as that stored in the PSPSym. So just copy RSP
+ // instead of loading the PSPSym in this case, or if PSPSym is not used (CoreRT ABI).
- if (compiler->opts.compScopeInfo)
+ if ((compiler->lvaPSPSym == BAD_VAR_NUM) ||
+ (!compiler->compLocallocUsed && (compiler->funCurrentFunc()->funKind == FUNC_ROOT)))
{
- siInit();
+ inst_RV_RV(INS_mov, REG_ARG_0, REG_SPBASE, TYP_I_IMPL);
}
-#endif
-
- // The current implementation of switch tables requires the first block to have a label so it
- // can generate offsets to the switch label targets.
- // TODO-XArch-CQ: remove this when switches have been re-implemented to not use this.
- if (compiler->fgHasSwitch)
+ else
{
- compiler->fgFirstBB->bbFlags |= BBF_JMP_TARGET;
+ getEmitter()->emitIns_R_S(ins_Load(TYP_I_IMPL), EA_PTRSIZE, REG_ARG_0, compiler->lvaPSPSym, 0);
}
+ getEmitter()->emitIns_J(INS_call, block->bbJumpDest);
- genPendingCallLabel = nullptr;
-
- /* Initialize the pointer tracking code */
-
- gcInfo.gcRegPtrSetInit();
- gcInfo.gcVarPtrSetInit();
-
- /* If any arguments live in registers, mark those regs as such */
-
- for (varNum = 0, varDsc = compiler->lvaTable; varNum < compiler->lvaCount; varNum++, varDsc++)
+ if (block->bbFlags & BBF_RETLESS_CALL)
{
- /* Is this variable a parameter assigned to a register? */
-
- if (!varDsc->lvIsParam || !varDsc->lvRegister)
- {
- continue;
- }
+ // We have a retless call, and the last instruction generated was a call.
+ // If the next block is in a different EH region (or is the end of the code
+ // block), then we need to generate a breakpoint here (since it will never
+ // get executed) to get proper unwind behavior.
- /* Is the argument live on entry to the method? */
-
- if (!VarSetOps::IsMember(compiler, compiler->fgFirstBB->bbLiveIn, varDsc->lvVarIndex))
+ if ((block->bbNext == nullptr) || !BasicBlock::sameEHRegion(block, block->bbNext))
{
- continue;
- }
-
- /* Is this a floating-point argument? */
-
- if (varDsc->IsFloatRegType())
- {
- continue;
+ instGen(INS_BREAKPOINT); // This should never get executed
}
-
- noway_assert(!varTypeIsFloating(varDsc->TypeGet()));
-
- /* Mark the register as holding the variable */
-
- regTracker.rsTrackRegLclVar(varDsc->lvRegNum, varNum);
}
-
- unsigned finallyNesting = 0;
-
- // Make sure a set is allocated for compiler->compCurLife (in the long case), so we can set it to empty without
- // allocation at the start of each basic block.
- VarSetOps::AssignNoCopy(compiler, compiler->compCurLife, VarSetOps::MakeEmpty(compiler));
-
- /*-------------------------------------------------------------------------
- *
- * Walk the basic blocks and generate code for each one
- *
- */
-
- BasicBlock* block;
- BasicBlock* lblk; /* previous block */
-
- for (lblk = nullptr, block = compiler->fgFirstBB; block != nullptr; lblk = block, block = block->bbNext)
+ else
{
-#ifdef DEBUG
- if (compiler->verbose)
- {
- printf("\n=============== Generating ");
- block->dspBlockHeader(compiler, true, true);
- compiler->fgDispBBLiveness(block);
- }
-#endif // DEBUG
-
- // Figure out which registers hold variables on entry to this block
-
- regSet.ClearMaskVars();
- gcInfo.gcRegGCrefSetCur = RBM_NONE;
- gcInfo.gcRegByrefSetCur = RBM_NONE;
-
- compiler->m_pLinearScan->recordVarLocationsAtStartOfBB(block);
-
- genUpdateLife(block->bbLiveIn);
-
- // Even if liveness didn't change, we need to update the registers containing GC references.
- // genUpdateLife will update the registers live due to liveness changes. But what about registers that didn't
- // change? We cleared them out above. Maybe we should just not clear them out, but update the ones that change
- // here. That would require handling the changes in recordVarLocationsAtStartOfBB().
-
- regMaskTP newLiveRegSet = RBM_NONE;
- regMaskTP newRegGCrefSet = RBM_NONE;
- regMaskTP newRegByrefSet = RBM_NONE;
-#ifdef DEBUG
- VARSET_TP VARSET_INIT_NOCOPY(removedGCVars, VarSetOps::MakeEmpty(compiler));
- VARSET_TP VARSET_INIT_NOCOPY(addedGCVars, VarSetOps::MakeEmpty(compiler));
-#endif
- VARSET_ITER_INIT(compiler, iter, block->bbLiveIn, varIndex);
- while (iter.NextElem(compiler, &varIndex))
- {
- unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
- LclVarDsc* varDsc = &(compiler->lvaTable[varNum]);
-
- if (varDsc->lvIsInReg())
- {
- newLiveRegSet |= varDsc->lvRegMask();
- if (varDsc->lvType == TYP_REF)
- {
- newRegGCrefSet |= varDsc->lvRegMask();
- }
- else if (varDsc->lvType == TYP_BYREF)
- {
- newRegByrefSet |= varDsc->lvRegMask();
- }
-#ifdef DEBUG
- if (verbose && VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varIndex))
- {
- VarSetOps::AddElemD(compiler, removedGCVars, varIndex);
- }
-#endif // DEBUG
- VarSetOps::RemoveElemD(compiler, gcInfo.gcVarPtrSetCur, varIndex);
- }
- else if (compiler->lvaIsGCTracked(varDsc))
- {
-#ifdef DEBUG
- if (verbose && !VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varIndex))
- {
- VarSetOps::AddElemD(compiler, addedGCVars, varIndex);
- }
-#endif // DEBUG
- VarSetOps::AddElemD(compiler, gcInfo.gcVarPtrSetCur, varIndex);
- }
- }
-
- regSet.rsMaskVars = newLiveRegSet;
-
-#ifdef DEBUG
- if (compiler->verbose)
- {
- if (!VarSetOps::IsEmpty(compiler, addedGCVars))
- {
- printf("\t\t\t\t\t\t\tAdded GCVars: ");
- dumpConvertedVarSet(compiler, addedGCVars);
- printf("\n");
- }
- if (!VarSetOps::IsEmpty(compiler, removedGCVars))
- {
- printf("\t\t\t\t\t\t\tRemoved GCVars: ");
- dumpConvertedVarSet(compiler, removedGCVars);
- printf("\n");
- }
- }
-#endif // DEBUG
-
- gcInfo.gcMarkRegSetGCref(newRegGCrefSet DEBUGARG(true));
- gcInfo.gcMarkRegSetByref(newRegByrefSet DEBUGARG(true));
-
- /* Blocks with handlerGetsXcptnObj()==true use GT_CATCH_ARG to
- represent the exception object (TYP_REF).
- We mark REG_EXCEPTION_OBJECT as holding a GC object on entry
- to the block, it will be the first thing evaluated
- (thanks to GTF_ORDER_SIDEEFF).
- */
-
- if (handlerGetsXcptnObj(block->bbCatchTyp))
- {
- for (GenTree* node : LIR::AsRange(block))
- {
- if (node->OperGet() == GT_CATCH_ARG)
- {
- gcInfo.gcMarkRegSetGCref(RBM_EXCEPTION_OBJECT);
- break;
- }
- }
- }
-
- /* Start a new code output block */
-
- genUpdateCurrentFunclet(block);
-
- if (genAlignLoops && block->bbFlags & BBF_LOOP_HEAD)
- {
- getEmitter()->emitLoopAlign();
- }
-
-#ifdef DEBUG
- if (compiler->opts.dspCode)
- {
- printf("\n L_M%03u_BB%02u:\n", Compiler::s_compMethodsCount, block->bbNum);
- }
-#endif
-
- block->bbEmitCookie = nullptr;
-
- if (block->bbFlags & (BBF_JMP_TARGET | BBF_HAS_LABEL))
- {
- /* Mark a label and update the current set of live GC refs */
-
- block->bbEmitCookie = getEmitter()->emitAddLabel(gcInfo.gcVarPtrSetCur, gcInfo.gcRegGCrefSetCur,
- gcInfo.gcRegByrefSetCur, FALSE);
- }
-
- if (block == compiler->fgFirstColdBlock)
- {
-#ifdef DEBUG
- if (compiler->verbose)
- {
- printf("\nThis is the start of the cold region of the method\n");
- }
-#endif
- // We should never have a block that falls through into the Cold section
- noway_assert(!lblk->bbFallsThrough());
-
- // We require the block that starts the Cold section to have a label
- noway_assert(block->bbEmitCookie);
- getEmitter()->emitSetFirstColdIGCookie(block->bbEmitCookie);
- }
-
- /* Both stacks are always empty on entry to a basic block */
-
- genStackLevel = 0;
-
- savedStkLvl = genStackLevel;
-
- /* Tell everyone which basic block we're working on */
-
- compiler->compCurBB = block;
-
-#ifdef DEBUGGING_SUPPORT
- siBeginBlock(block);
-
- // BBF_INTERNAL blocks don't correspond to any single IL instruction.
- if (compiler->opts.compDbgInfo && (block->bbFlags & BBF_INTERNAL) &&
- !compiler->fgBBisScratch(block)) // If the block is the distinguished first scratch block, then no need to
- // emit a NO_MAPPING entry, immediately after the prolog.
- {
- genIPmappingAdd((IL_OFFSETX)ICorDebugInfo::NO_MAPPING, true);
- }
-
- bool firstMapping = true;
-#endif // DEBUGGING_SUPPORT
-
- /*---------------------------------------------------------------------
- *
- * Generate code for each statement-tree in the block
- *
- */
- CLANG_FORMAT_COMMENT_ANCHOR;
-
-#if FEATURE_EH_FUNCLETS
- if (block->bbFlags & BBF_FUNCLET_BEG)
- {
- genReserveFuncletProlog(block);
- }
-#endif // FEATURE_EH_FUNCLETS
-
- // Clear compCurStmt and compCurLifeTree.
- compiler->compCurStmt = nullptr;
- compiler->compCurLifeTree = nullptr;
-
- // Traverse the block in linear order, generating code for each node as we
- // as we encounter it.
- CLANG_FORMAT_COMMENT_ANCHOR;
-
-#ifdef DEBUGGING_SUPPORT
- IL_OFFSETX currentILOffset = BAD_IL_OFFSET;
-#endif
- for (GenTree* node : LIR::AsRange(block).NonPhiNodes())
- {
-#ifdef DEBUGGING_SUPPORT
- // Do we have a new IL offset?
- if (node->OperGet() == GT_IL_OFFSET)
- {
- genEnsureCodeEmitted(currentILOffset);
- currentILOffset = node->gtStmt.gtStmtILoffsx;
- genIPmappingAdd(currentILOffset, firstMapping);
- firstMapping = false;
- }
-#endif // DEBUGGING_SUPPORT
-
-#ifdef DEBUG
- if (node->OperGet() == GT_IL_OFFSET)
- {
- noway_assert(node->gtStmt.gtStmtLastILoffs <= compiler->info.compILCodeSize ||
- node->gtStmt.gtStmtLastILoffs == BAD_IL_OFFSET);
-
- if (compiler->opts.dspCode && compiler->opts.dspInstrs &&
- node->gtStmt.gtStmtLastILoffs != BAD_IL_OFFSET)
- {
- while (genCurDispOffset <= node->gtStmt.gtStmtLastILoffs)
- {
- genCurDispOffset += dumpSingleInstr(compiler->info.compCode, genCurDispOffset, "> ");
- }
- }
- }
-#endif // DEBUG
-
- genCodeForTreeNode(node);
- if (node->gtHasReg() && node->gtLsraInfo.isLocalDefUse)
- {
- genConsumeReg(node);
- }
- } // end for each node in block
-
-#ifdef DEBUG
- // The following set of register spill checks and GC pointer tracking checks used to be
- // performed at statement boundaries. Now, with LIR, there are no statements, so they are
- // performed at the end of each block.
- // TODO: could these checks be performed more frequently? E.g., at each location where
- // the register allocator says there are no live non-variable registers. Perhaps this could
- // be done by (a) keeping a running count of live non-variable registers by using
- // gtLsraInfo.srcCount and gtLsraInfo.dstCount to decrement and increment the count, respectively,
- // and running the checks when the count is zero. Or, (b) use the map maintained by LSRA
- // (operandToLocationInfoMap) to mark a node somehow when, after the execution of that node,
- // there will be no live non-variable registers.
-
- regSet.rsSpillChk();
-
- /* Make sure we didn't bungle pointer register tracking */
-
- regMaskTP ptrRegs = gcInfo.gcRegGCrefSetCur | gcInfo.gcRegByrefSetCur;
- regMaskTP nonVarPtrRegs = ptrRegs & ~regSet.rsMaskVars;
-
- // If return is a GC-type, clear it. Note that if a common
- // epilog is generated (genReturnBB) it has a void return
- // even though we might return a ref. We can't use the compRetType
- // as the determiner because something we are tracking as a byref
- // might be used as a return value of a int function (which is legal)
- GenTree* blockLastNode = block->lastNode();
- if ((blockLastNode != nullptr) && (blockLastNode->gtOper == GT_RETURN) &&
- (varTypeIsGC(compiler->info.compRetType) ||
- (blockLastNode->gtOp.gtOp1 != nullptr && varTypeIsGC(blockLastNode->gtOp.gtOp1->TypeGet()))))
- {
- nonVarPtrRegs &= ~RBM_INTRET;
- }
-
- if (nonVarPtrRegs)
- {
- printf("Regset after BB%02u gcr=", block->bbNum);
- printRegMaskInt(gcInfo.gcRegGCrefSetCur & ~regSet.rsMaskVars);
- compiler->getEmitter()->emitDispRegSet(gcInfo.gcRegGCrefSetCur & ~regSet.rsMaskVars);
- printf(", byr=");
- printRegMaskInt(gcInfo.gcRegByrefSetCur & ~regSet.rsMaskVars);
- compiler->getEmitter()->emitDispRegSet(gcInfo.gcRegByrefSetCur & ~regSet.rsMaskVars);
- printf(", regVars=");
- printRegMaskInt(regSet.rsMaskVars);
- compiler->getEmitter()->emitDispRegSet(regSet.rsMaskVars);
- printf("\n");
- }
-
- noway_assert(nonVarPtrRegs == RBM_NONE);
-#endif // DEBUG
-
-#if defined(DEBUG) && defined(LATE_DISASM) && defined(_TARGET_AMD64_)
- if (block->bbNext == nullptr)
- {
- // Unit testing of the AMD64 emitter: generate a bunch of instructions into the last block
- // (it's as good as any, but better than the prolog, which can only be a single instruction
- // group) then use COMPlus_JitLateDisasm=* to see if the late disassembler
- // thinks the instructions are the same as we do.
- genAmd64EmitterUnitTests();
- }
-#endif // defined(DEBUG) && defined(LATE_DISASM) && defined(_TARGET_ARM64_)
-
-#ifdef DEBUGGING_SUPPORT
- // It is possible to reach the end of the block without generating code for the current IL offset.
- // For example, if the following IR ends the current block, no code will have been generated for
- // offset 21:
- //
- // ( 0, 0) [000040] ------------ il_offset void IL offset: 21
- //
- // N001 ( 0, 0) [000039] ------------ nop void
- //
- // This can lead to problems when debugging the generated code. To prevent these issues, make sure
- // we've generated code for the last IL offset we saw in the block.
- genEnsureCodeEmitted(currentILOffset);
+ // Because of the way the flowgraph is connected, the liveness info for this one instruction
+ // after the call is not (can not be) correct in cases where a variable has a last use in the
+ // handler. So turn off GC reporting for this single instruction.
+ getEmitter()->emitDisableGC();
- if (compiler->opts.compScopeInfo && (compiler->info.compVarScopesCount > 0))
+ // Now go to where the finally funclet needs to return to.
+ if (block->bbNext->bbJumpDest == block->bbNext->bbNext)
{
- siEndBlock(block);
-
- /* Is this the last block, and are there any open scopes left ? */
-
- bool isLastBlockProcessed = (block->bbNext == nullptr);
- if (block->isBBCallAlwaysPair())
- {
- isLastBlockProcessed = (block->bbNext->bbNext == nullptr);
- }
-
- if (isLastBlockProcessed && siOpenScopeList.scNext)
- {
- /* This assert no longer holds, because we may insert a throw
- block to demarcate the end of a try or finally region when they
- are at the end of the method. It would be nice if we could fix
- our code so that this throw block will no longer be necessary. */
-
- // noway_assert(block->bbCodeOffsEnd != compiler->info.compILCodeSize);
-
- siCloseAllOpenScopes();
- }
+ // Fall-through.
+ // TODO-XArch-CQ: Can we get rid of this instruction, and just have the call return directly
+ // to the next instruction? This would depend on stack walking from within the finally
+ // handler working without this instruction being in this special EH region.
+ instGen(INS_nop);
}
-
-#endif // DEBUGGING_SUPPORT
-
- genStackLevel -= savedStkLvl;
-
-#ifdef DEBUG
- // compCurLife should be equal to the liveOut set, except that we don't keep
- // it up to date for vars that are not register candidates
- // (it would be nice to have a xor set function)
-
- VARSET_TP VARSET_INIT_NOCOPY(extraLiveVars, VarSetOps::Diff(compiler, block->bbLiveOut, compiler->compCurLife));
- VarSetOps::UnionD(compiler, extraLiveVars, VarSetOps::Diff(compiler, compiler->compCurLife, block->bbLiveOut));
- VARSET_ITER_INIT(compiler, extraLiveVarIter, extraLiveVars, extraLiveVarIndex);
- while (extraLiveVarIter.NextElem(compiler, &extraLiveVarIndex))
+ else
{
- unsigned varNum = compiler->lvaTrackedToVarNum[extraLiveVarIndex];
- LclVarDsc* varDsc = compiler->lvaTable + varNum;
- assert(!varDsc->lvIsRegCandidate());
+ inst_JMP(EJ_jmp, block->bbNext->bbJumpDest);
}
-#endif
-
- /* Both stacks should always be empty on exit from a basic block */
- noway_assert(genStackLevel == 0);
-
-#ifdef _TARGET_AMD64_
- // On AMD64, we need to generate a NOP after a call that is the last instruction of the block, in several
- // situations, to support proper exception handling semantics. This is mostly to ensure that when the stack
- // walker computes an instruction pointer for a frame, that instruction pointer is in the correct EH region.
- // The document "X64 and ARM ABIs.docx" has more details. The situations:
- // 1. If the call instruction is in a different EH region as the instruction that follows it.
- // 2. If the call immediately precedes an OS epilog. (Note that what the JIT or VM consider an epilog might
- // be slightly different from what the OS considers an epilog, and it is the OS-reported epilog that matters
- // here.)
- // We handle case #1 here, and case #2 in the emitter.
- if (getEmitter()->emitIsLastInsCall())
- {
- // Ok, the last instruction generated is a call instruction. Do any of the other conditions hold?
- // Note: we may be generating a few too many NOPs for the case of call preceding an epilog. Technically,
- // if the next block is a BBJ_RETURN, an epilog will be generated, but there may be some instructions
- // generated before the OS epilog starts, such as a GS cookie check.
- if ((block->bbNext == nullptr) || !BasicBlock::sameEHRegion(block, block->bbNext))
- {
- // We only need the NOP if we're not going to generate any more code as part of the block end.
-
- switch (block->bbJumpKind)
- {
- case BBJ_ALWAYS:
- case BBJ_THROW:
- case BBJ_CALLFINALLY:
- case BBJ_EHCATCHRET:
- // We're going to generate more code below anyway, so no need for the NOP.
-
- case BBJ_RETURN:
- case BBJ_EHFINALLYRET:
- case BBJ_EHFILTERRET:
- // These are the "epilog follows" case, handled in the emitter.
-
- break;
-
- case BBJ_NONE:
- if (block->bbNext == nullptr)
- {
- // Call immediately before the end of the code; we should never get here .
- instGen(INS_BREAKPOINT); // This should never get executed
- }
- else
- {
- // We need the NOP
- instGen(INS_nop);
- }
- break;
-
- case BBJ_COND:
- case BBJ_SWITCH:
- // These can't have a call as the last instruction!
-
- default:
- noway_assert(!"Unexpected bbJumpKind");
- break;
- }
- }
- }
-#endif // _TARGET_AMD64_
-
- /* Do we need to generate a jump or return? */
-
- switch (block->bbJumpKind)
- {
- case BBJ_ALWAYS:
- inst_JMP(EJ_jmp, block->bbJumpDest);
- break;
-
- case BBJ_RETURN:
- genExitCode(block);
- break;
-
- case BBJ_THROW:
- // If we have a throw at the end of a function or funclet, we need to emit another instruction
- // afterwards to help the OS unwinder determine the correct context during unwind.
- // We insert an unexecuted breakpoint instruction in several situations
- // following a throw instruction:
- // 1. If the throw is the last instruction of the function or funclet. This helps
- // the OS unwinder determine the correct context during an unwind from the
- // thrown exception.
- // 2. If this is this is the last block of the hot section.
- // 3. If the subsequent block is a special throw block.
- // 4. On AMD64, if the next block is in a different EH region.
- if ((block->bbNext == nullptr) || (block->bbNext->bbFlags & BBF_FUNCLET_BEG) ||
- !BasicBlock::sameEHRegion(block, block->bbNext) ||
- (!isFramePointerUsed() && compiler->fgIsThrowHlpBlk(block->bbNext)) ||
- block->bbNext == compiler->fgFirstColdBlock)
- {
- instGen(INS_BREAKPOINT); // This should never get executed
- }
-
- break;
-
- case BBJ_CALLFINALLY:
-
-#if FEATURE_EH_FUNCLETS
-
- // Generate a call to the finally, like this:
- // mov rcx,qword ptr [rbp + 20H] // Load rcx with PSPSym
- // call finally-funclet
- // jmp finally-return // Only for non-retless finally calls
- // The jmp can be a NOP if we're going to the next block.
- // If we're generating code for the main function (not a funclet), and there is no localloc,
- // then RSP at this point is the same value as that stored in the PSPsym. So just copy RSP
- // instead of loading the PSPSym in this case.
- if (!compiler->compLocallocUsed && (compiler->funCurrentFunc()->funKind == FUNC_ROOT))
- {
- inst_RV_RV(INS_mov, REG_ARG_0, REG_SPBASE, TYP_I_IMPL);
- }
- else
- {
- getEmitter()->emitIns_R_S(ins_Load(TYP_I_IMPL), EA_PTRSIZE, REG_ARG_0, compiler->lvaPSPSym, 0);
- }
- getEmitter()->emitIns_J(INS_call, block->bbJumpDest);
+ getEmitter()->emitEnableGC();
+ }
- if (block->bbFlags & BBF_RETLESS_CALL)
- {
- // We have a retless call, and the last instruction generated was a call.
- // If the next block is in a different EH region (or is the end of the code
- // block), then we need to generate a breakpoint here (since it will never
- // get executed) to get proper unwind behavior.
+#else // !FEATURE_EH_FUNCLETS
- if ((block->bbNext == nullptr) || !BasicBlock::sameEHRegion(block, block->bbNext))
- {
- instGen(INS_BREAKPOINT); // This should never get executed
- }
- }
- else
- {
- // Because of the way the flowgraph is connected, the liveness info for this one instruction
- // after the call is not (can not be) correct in cases where a variable has a last use in the
- // handler. So turn off GC reporting for this single instruction.
- getEmitter()->emitDisableGC();
+ // If we are about to invoke a finally locally from a try block, we have to set the ShadowSP slot
+ // corresponding to the finally's nesting level. When invoked in response to an exception, the
+ // EE does this.
+ //
+ // We have a BBJ_CALLFINALLY followed by a BBJ_ALWAYS.
+ //
+ // We will emit :
+ // mov [ebp - (n + 1)], 0
+ // mov [ebp - n ], 0xFC
+ // push &step
+ // jmp finallyBlock
+ // ...
+ // step:
+ // mov [ebp - n ], 0
+ // jmp leaveTarget
+ // ...
+ // leaveTarget:
+
+ noway_assert(isFramePointerUsed());
+
+ // Get the nesting level which contains the finally
+ unsigned finallyNesting = 0;
+ compiler->fgGetNestingLevel(block, &finallyNesting);
- // Now go to where the finally funclet needs to return to.
- if (block->bbNext->bbJumpDest == block->bbNext->bbNext)
- {
- // Fall-through.
- // TODO-XArch-CQ: Can we get rid of this instruction, and just have the call return directly
- // to the next instruction? This would depend on stack walking from within the finally
- // handler working without this instruction being in this special EH region.
- instGen(INS_nop);
- }
- else
- {
- inst_JMP(EJ_jmp, block->bbNext->bbJumpDest);
- }
+ // The last slot is reserved for ICodeManager::FixContext(ppEndRegion)
+ unsigned filterEndOffsetSlotOffs;
+ filterEndOffsetSlotOffs = (unsigned)(compiler->lvaLclSize(compiler->lvaShadowSPslotsVar) - TARGET_POINTER_SIZE);
- getEmitter()->emitEnableGC();
- }
+ unsigned curNestingSlotOffs;
+ curNestingSlotOffs = (unsigned)(filterEndOffsetSlotOffs - ((finallyNesting + 1) * TARGET_POINTER_SIZE));
-#else // !FEATURE_EH_FUNCLETS
+ // Zero out the slot for the next nesting level
+ instGen_Store_Imm_Into_Lcl(TYP_I_IMPL, EA_PTRSIZE, 0, compiler->lvaShadowSPslotsVar,
+ curNestingSlotOffs - TARGET_POINTER_SIZE);
+ instGen_Store_Imm_Into_Lcl(TYP_I_IMPL, EA_PTRSIZE, LCL_FINALLY_MARK, compiler->lvaShadowSPslotsVar,
+ curNestingSlotOffs);
- // If we are about to invoke a finally locally from a try block, we have to set the ShadowSP slot
- // corresponding to the finally's nesting level. When invoked in response to an exception, the
- // EE does this.
- //
- // We have a BBJ_CALLFINALLY followed by a BBJ_ALWAYS.
- //
- // We will emit :
- // mov [ebp - (n + 1)], 0
- // mov [ebp - n ], 0xFC
- // push &step
- // jmp finallyBlock
- // ...
- // step:
- // mov [ebp - n ], 0
- // jmp leaveTarget
- // ...
- // leaveTarget:
-
- noway_assert(isFramePointerUsed());
-
- // Get the nesting level which contains the finally
- compiler->fgGetNestingLevel(block, &finallyNesting);
-
- // The last slot is reserved for ICodeManager::FixContext(ppEndRegion)
- unsigned filterEndOffsetSlotOffs;
- filterEndOffsetSlotOffs =
- (unsigned)(compiler->lvaLclSize(compiler->lvaShadowSPslotsVar) - TARGET_POINTER_SIZE);
-
- unsigned curNestingSlotOffs;
- curNestingSlotOffs = (unsigned)(filterEndOffsetSlotOffs - ((finallyNesting + 1) * TARGET_POINTER_SIZE));
-
- // Zero out the slot for the next nesting level
- instGen_Store_Imm_Into_Lcl(TYP_I_IMPL, EA_PTRSIZE, 0, compiler->lvaShadowSPslotsVar,
- curNestingSlotOffs - TARGET_POINTER_SIZE);
- instGen_Store_Imm_Into_Lcl(TYP_I_IMPL, EA_PTRSIZE, LCL_FINALLY_MARK, compiler->lvaShadowSPslotsVar,
- curNestingSlotOffs);
-
- // Now push the address where the finally funclet should return to directly.
- if (!(block->bbFlags & BBF_RETLESS_CALL))
- {
- assert(block->isBBCallAlwaysPair());
- getEmitter()->emitIns_J(INS_push_hide, block->bbNext->bbJumpDest);
- }
- else
- {
- // EE expects a DWORD, so we give him 0
- inst_IV(INS_push_hide, 0);
- }
+ // Now push the address where the finally funclet should return to directly.
+ if (!(block->bbFlags & BBF_RETLESS_CALL))
+ {
+ assert(block->isBBCallAlwaysPair());
+ getEmitter()->emitIns_J(INS_push_hide, block->bbNext->bbJumpDest);
+ }
+ else
+ {
+ // EE expects a DWORD, so we give him 0
+ inst_IV(INS_push_hide, 0);
+ }
- // Jump to the finally BB
- inst_JMP(EJ_jmp, block->bbJumpDest);
+ // Jump to the finally BB
+ inst_JMP(EJ_jmp, block->bbJumpDest);
#endif // !FEATURE_EH_FUNCLETS
- // 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.
- if (!(block->bbFlags & BBF_RETLESS_CALL))
- {
- assert(block->isBBCallAlwaysPair());
-
- lblk = block;
- block = block->bbNext;
- }
+ // 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.
+ if (!(block->bbFlags & BBF_RETLESS_CALL))
+ {
+ assert(block->isBBCallAlwaysPair());
- break;
+ lblk = block;
+ block = block->bbNext;
+ }
+ return block;
+}
#if FEATURE_EH_FUNCLETS
-
- case BBJ_EHCATCHRET:
- // Set RAX to the address the VM should return to after the catch.
- // Generate a RIP-relative
- // lea reg, [rip + disp32] ; the RIP is implicit
- // which will be position-indepenent.
- getEmitter()->emitIns_R_L(INS_lea, EA_PTR_DSP_RELOC, block->bbJumpDest, REG_INTRET);
- __fallthrough;
-
- case BBJ_EHFINALLYRET:
- case BBJ_EHFILTERRET:
- genReserveFuncletEpilog(block);
- break;
+void CodeGen::genEHCatchRet(BasicBlock* block)
+{
+ // Set RAX to the address the VM should return to after the catch.
+ // Generate a RIP-relative
+ // lea reg, [rip + disp32] ; the RIP is implicit
+ // which will be position-indepenent.
+ getEmitter()->emitIns_R_L(INS_lea, EA_PTR_DSP_RELOC, block->bbJumpDest, REG_INTRET);
+}
#else // !FEATURE_EH_FUNCLETS
- case BBJ_EHCATCHRET:
- noway_assert(!"Unexpected BBJ_EHCATCHRET"); // not used on x86
-
- case BBJ_EHFINALLYRET:
- case BBJ_EHFILTERRET:
- {
- // The last statement of the block must be a GT_RETFILT, which has already been generated.
- assert(block->lastNode() != nullptr);
- assert(block->lastNode()->OperGet() == GT_RETFILT);
-
- if (block->bbJumpKind == BBJ_EHFINALLYRET)
- {
- assert(block->lastNode()->gtOp.gtOp1 == nullptr); // op1 == nullptr means endfinally
-
- // Return using a pop-jmp sequence. As the "try" block calls
- // the finally with a jmp, this leaves the x86 call-ret stack
- // balanced in the normal flow of path.
-
- noway_assert(isFramePointerRequired());
- inst_RV(INS_pop_hide, REG_EAX, TYP_I_IMPL);
- inst_RV(INS_i_jmp, REG_EAX, TYP_I_IMPL);
- }
- else
- {
- assert(block->bbJumpKind == BBJ_EHFILTERRET);
-
- // The return value has already been computed.
- instGen_Return(0);
- }
- }
- break;
-
-#endif // !FEATURE_EH_FUNCLETS
-
- case BBJ_NONE:
- case BBJ_COND:
- case BBJ_SWITCH:
- break;
-
- default:
- noway_assert(!"Unexpected bbJumpKind");
- break;
- }
-
-#ifdef DEBUG
- compiler->compCurBB = nullptr;
-#endif
-
- } //------------------ END-FOR each block of the method -------------------
-
- /* Nothing is live at this point */
- genUpdateLife(VarSetOps::MakeEmpty(compiler));
-
- /* Finalize the spill tracking logic */
-
- regSet.rsSpillEnd();
-
- /* Finalize the temp tracking logic */
-
- compiler->tmpEnd();
+void CodeGen::genEHFinallyOrFilterRet(BasicBlock* block)
+{
+ // The last statement of the block must be a GT_RETFILT, which has already been generated.
+ assert(block->lastNode() != nullptr);
+ assert(block->lastNode()->OperGet() == GT_RETFILT);
-#ifdef DEBUG
- if (compiler->verbose)
+ if (block->bbJumpKind == BBJ_EHFINALLYRET)
{
- printf("\n# ");
- printf("compCycleEstimate = %6d, compSizeEstimate = %5d ", compiler->compCycleEstimate,
- compiler->compSizeEstimate);
- printf("%s\n", compiler->info.compFullName);
- }
-#endif
-}
+ assert(block->lastNode()->gtOp.gtOp1 == nullptr); // op1 == nullptr means endfinally
-// return the child that has the same reg as the dst (if any)
-// other child returned (out param) in 'other'
-GenTree* sameRegAsDst(GenTree* tree, GenTree*& other /*out*/)
-{
- if (tree->gtRegNum == REG_NA)
- {
- other = nullptr;
- return nullptr;
- }
+ // Return using a pop-jmp sequence. As the "try" block calls
+ // the finally with a jmp, this leaves the x86 call-ret stack
+ // balanced in the normal flow of path.
- GenTreePtr op1 = tree->gtOp.gtOp1;
- GenTreePtr op2 = tree->gtOp.gtOp2;
- if (op1->gtRegNum == tree->gtRegNum)
- {
- other = op2;
- return op1;
- }
- if (op2->gtRegNum == tree->gtRegNum)
- {
- other = op1;
- return op2;
+ noway_assert(isFramePointerRequired());
+ inst_RV(INS_pop_hide, REG_EAX, TYP_I_IMPL);
+ inst_RV(INS_i_jmp, REG_EAX, TYP_I_IMPL);
}
else
{
- other = nullptr;
- return nullptr;
+ assert(block->bbJumpKind == BBJ_EHFILTERRET);
+
+ // The return value has already been computed.
+ instGen_Return(0);
}
}
+#endif // !FEATURE_EH_FUNCLETS
+
// Move an immediate value into an integer register
void CodeGen::instGen_Set_Reg_To_Imm(emitAttr size, regNumber reg, ssize_t imm, insFlags flags)
@@ -1227,7 +493,10 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre
// Generate code to get the high N bits of a N*N=2N bit multiplication result
void CodeGen::genCodeForMulHi(GenTreeOp* treeNode)
{
- assert(!(treeNode->gtFlags & GTF_UNSIGNED));
+ if (treeNode->OperGet() == GT_MULHI)
+ {
+ assert(!(treeNode->gtFlags & GTF_UNSIGNED));
+ }
assert(!treeNode->gtOverflowEx());
regNumber targetReg = treeNode->gtRegNum;
@@ -1247,8 +516,7 @@ void CodeGen::genCodeForMulHi(GenTreeOp* treeNode)
GenTree* rmOp = op2;
// Set rmOp to the contained memory operand (if any)
- //
- if (op1->isContained() || (!op2->isContained() && (op2->gtRegNum == targetReg)))
+ if (op1->isContained() || (!op2->isContained() && (op2->gtRegNum == REG_RAX)))
{
regOp = op2;
rmOp = op1;
@@ -1256,25 +524,131 @@ void CodeGen::genCodeForMulHi(GenTreeOp* treeNode)
assert(!regOp->isContained());
// Setup targetReg when neither of the source operands was a matching register
- if (regOp->gtRegNum != targetReg)
+ if (regOp->gtRegNum != REG_RAX)
{
- inst_RV_RV(ins_Copy(targetType), targetReg, regOp->gtRegNum, targetType);
+ inst_RV_RV(ins_Copy(targetType), REG_RAX, regOp->gtRegNum, targetType);
}
- emit->emitInsBinary(INS_imulEAX, size, treeNode, rmOp);
+ instruction ins;
+ if ((treeNode->gtFlags & GTF_UNSIGNED) == 0)
+ {
+ ins = INS_imulEAX;
+ }
+ else
+ {
+ ins = INS_mulEAX;
+ }
+ emit->emitInsBinary(ins, size, treeNode, rmOp);
// Move the result to the desired register, if necessary
- if (targetReg != REG_RDX)
+ if (treeNode->OperGet() == GT_MULHI && targetReg != REG_RDX)
{
inst_RV_RV(INS_mov, targetReg, REG_RDX, targetType);
}
}
-// generate code for a DIV or MOD operation
+#ifdef _TARGET_X86_
+//------------------------------------------------------------------------
+// genCodeForLongUMod: Generate code for a tree of the form
+// `(umod (gt_long x y) (const int))`
+//
+// Arguments:
+// node - the node for which to generate code
+//
+void CodeGen::genCodeForLongUMod(GenTreeOp* node)
+{
+ assert(node != nullptr);
+ assert(node->OperGet() == GT_UMOD);
+ assert(node->TypeGet() == TYP_INT);
+
+ GenTreeOp* const dividend = node->gtOp1->AsOp();
+ assert(dividend->OperGet() == GT_LONG);
+ assert(varTypeIsLong(dividend));
+
+ genConsumeOperands(node);
+
+ GenTree* const dividendLo = dividend->gtOp1;
+ GenTree* const dividendHi = dividend->gtOp2;
+ assert(!dividendLo->isContained());
+ assert(!dividendHi->isContained());
+
+ GenTree* const divisor = node->gtOp2;
+ assert(divisor->gtSkipReloadOrCopy()->OperGet() == GT_CNS_INT);
+ assert(!divisor->gtSkipReloadOrCopy()->isContained());
+ assert(divisor->gtSkipReloadOrCopy()->AsIntCon()->gtIconVal >= 2);
+ assert(divisor->gtSkipReloadOrCopy()->AsIntCon()->gtIconVal <= 0x3fffffff);
+
+ // dividendLo must be in RAX; dividendHi must be in RDX
+ genCopyRegIfNeeded(dividendLo, REG_EAX);
+ genCopyRegIfNeeded(dividendHi, REG_EDX);
+
+ // At this point, EAX:EDX contains the 64bit dividend and op2->gtRegNum
+ // contains the 32bit divisor. We want to generate the following code:
+ //
+ // cmp edx, divisor->gtRegNum
+ // jb noOverflow
+ //
+ // mov temp, eax
+ // mov eax, edx
+ // xor edx, edx
+ // div divisor->gtRegNum
+ // mov eax, temp
+ //
+ // noOverflow:
+ // div divisor->gtRegNum
+ //
+ // This works because (a * 2^32 + b) % c = ((a % c) * 2^32 + b) % c.
+
+ BasicBlock* const noOverflow = genCreateTempLabel();
+
+ // cmp edx, divisor->gtRegNum
+ // jb noOverflow
+ inst_RV_RV(INS_cmp, REG_EDX, divisor->gtRegNum);
+ inst_JMP(EJ_jb, noOverflow);
+
+ // mov temp, eax
+ // mov eax, edx
+ // xor edx, edx
+ // div divisor->gtRegNum
+ // mov eax, temp
+ const regNumber tempReg = genRegNumFromMask(node->gtRsvdRegs);
+ inst_RV_RV(INS_mov, tempReg, REG_EAX, TYP_INT);
+ inst_RV_RV(INS_mov, REG_EAX, REG_EDX, TYP_INT);
+ instGen_Set_Reg_To_Zero(EA_PTRSIZE, REG_EDX);
+ inst_RV(INS_div, divisor->gtRegNum, TYP_INT);
+ inst_RV_RV(INS_mov, REG_EAX, tempReg, TYP_INT);
+
+ // noOverflow:
+ // div divisor->gtRegNum
+ genDefineTempLabel(noOverflow);
+ inst_RV(INS_div, divisor->gtRegNum, TYP_INT);
+
+ const regNumber targetReg = node->gtRegNum;
+ if (targetReg != REG_EDX)
+ {
+ inst_RV_RV(INS_mov, targetReg, REG_RDX, TYP_INT);
+ }
+ genProduceReg(node);
+}
+#endif // _TARGET_X86_
+
+//------------------------------------------------------------------------
+// genCodeForDivMod: Generate code for a DIV or MOD operation.
+//
+// Arguments:
+// treeNode - the node to generate the code for
//
void CodeGen::genCodeForDivMod(GenTreeOp* treeNode)
{
- GenTree* dividend = treeNode->gtOp1;
+ GenTree* dividend = treeNode->gtOp1;
+#ifdef _TARGET_X86_
+ if (varTypeIsLong(dividend->TypeGet()))
+ {
+ genCodeForLongUMod(treeNode);
+ return;
+ }
+#endif // _TARGET_X86_
+
GenTree* divisor = treeNode->gtOp2;
genTreeOps oper = treeNode->OperGet();
emitAttr size = emitTypeSize(treeNode);
@@ -1319,10 +693,7 @@ void CodeGen::genCodeForDivMod(GenTreeOp* treeNode)
else
{
// dividend must be in RAX
- if (dividend->gtRegNum != REG_RAX)
- {
- inst_RV_RV(INS_mov, REG_RAX, dividend->gtRegNum, targetType);
- }
+ genCopyRegIfNeeded(dividend, REG_RAX);
// zero or sign extend rax to rdx
if (oper == GT_UMOD || oper == GT_UDIV)
@@ -1395,7 +766,7 @@ void CodeGen::genCodeForBinary(GenTree* treeNode)
assert(oper == GT_OR || oper == GT_XOR || oper == GT_AND || oper == GT_ADD || oper == GT_SUB);
#else // !defined(_TARGET_64BIT_)
assert(oper == GT_OR || oper == GT_XOR || oper == GT_AND || oper == GT_ADD_LO || oper == GT_ADD_HI ||
- oper == GT_SUB_LO || oper == GT_SUB_HI || oper == GT_MUL_HI || oper == GT_DIV_HI || oper == GT_MOD_HI ||
+ oper == GT_SUB_LO || oper == GT_SUB_HI || oper == GT_MUL_LONG || oper == GT_DIV_HI || oper == GT_MOD_HI ||
oper == GT_ADD || oper == GT_SUB);
#endif // !defined(_TARGET_64BIT_)
@@ -1443,7 +814,7 @@ void CodeGen::genCodeForBinary(GenTree* treeNode)
}
// now we know there are 3 different operands so attempt to use LEA
else if (oper == GT_ADD && !varTypeIsFloating(treeNode) && !treeNode->gtOverflowEx() // LEA does not set flags
- && (op2->isContainedIntOrIImmed() || !op2->isContained()))
+ && (op2->isContainedIntOrIImmed() || !op2->isContained()) && !treeNode->gtSetFlags())
{
if (op2->isContainedIntOrIImmed())
{
@@ -1833,7 +1204,7 @@ void CodeGen::genReturn(GenTreePtr treeNode)
//
// Reason for not materializing Leave callback as a GT_PROF_HOOK node after GT_RETURN:
// In flowgraph and other places assert that the last node of a block marked as
- // GT_RETURN is either a GT_RETURN or GT_JMP or a tail call. It would be nice to
+ // BBJ_RETURN is either a GT_RETURN or GT_JMP or a tail call. It would be nice to
// maintain such an invariant irrespective of whether profiler hook needed or not.
// Also, there is not much to be gained by materializing it as an explicit node.
if (compiler->compCurBB == compiler->genReturnBB)
@@ -1913,9 +1284,11 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
switch (treeNode->gtOper)
{
+#ifndef JIT32_GCENCODER
case GT_START_NONGC:
getEmitter()->emitDisableGC();
break;
+#endif // !defined(JIT32_GCENCODER)
case GT_PROF_HOOK:
#ifdef PROFILING_SUPPORTED
@@ -1996,14 +1369,18 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
// genCodeForShift() calls genProduceReg()
break;
- case GT_CAST:
#if !defined(_TARGET_64BIT_)
- // We will NYI in DecomposeNode() if we are cast TO a long type, but we do not
- // yet support casting FROM a long type either, and that's simpler to catch
- // here.
- NYI_IF(varTypeIsLong(treeNode->gtOp.gtOp1), "Casts from TYP_LONG");
-#endif // !defined(_TARGET_64BIT_)
+ case GT_LSH_HI:
+ case GT_RSH_LO:
+ // TODO-X86-CQ: This only handles the case where the operand being shifted is in a register. We don't
+ // need sourceHi to be always in reg in case of GT_LSH_HI (because it could be moved from memory to
+ // targetReg if sourceHi is a contained mem-op). Similarly for GT_RSH_LO, sourceLo could be marked as
+ // contained memory-op. Even if not a memory-op, we could mark it as reg-optional.
+ genCodeForShiftLong(treeNode);
+ break;
+#endif
+ case GT_CAST:
if (varTypeIsFloating(targetType) && varTypeIsFloating(treeNode->gtOp.gtOp1))
{
// Casts float/double <--> double/float
@@ -2037,7 +1414,7 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
if (isRegCandidate && !(treeNode->gtFlags & GTF_VAR_DEATH))
{
- assert((treeNode->InReg()) || (treeNode->gtFlags & GTF_SPILLED));
+ assert(treeNode->InReg() || (treeNode->gtFlags & GTF_SPILLED));
}
// If this is a register candidate that has been spilled, genConsumeReg() will
@@ -2047,6 +1424,15 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
{
assert(!isRegCandidate);
+#if defined(FEATURE_SIMD) && defined(_TARGET_X86_)
+ // Loading of TYP_SIMD12 (i.e. Vector3) variable
+ if (treeNode->TypeGet() == TYP_SIMD12)
+ {
+ genLoadLclTypeSIMD12(treeNode);
+ break;
+ }
+#endif // defined(FEATURE_SIMD) && defined(_TARGET_X86_)
+
emit->emitIns_R_S(ins_Load(treeNode->TypeGet(), compiler->isSIMDTypeLocalAligned(lcl->gtLclNum)),
emitTypeSize(treeNode), treeNode->gtRegNum, lcl->gtLclNum, 0);
genProduceReg(treeNode);
@@ -2075,7 +1461,7 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
// Loading of TYP_SIMD12 (i.e. Vector3) field
if (treeNode->TypeGet() == TYP_SIMD12)
{
- genLoadLclFldTypeSIMD12(treeNode);
+ genLoadLclTypeSIMD12(treeNode);
break;
}
#endif
@@ -2243,6 +1629,9 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
break;
case GT_MULHI:
+#ifdef _TARGET_X86_
+ case GT_MUL_LONG:
+#endif
genCodeForMulHi(treeNode->AsOp());
genProduceReg(treeNode);
break;
@@ -2408,18 +1797,18 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
// X86 Long comparison
else if (varTypeIsLong(op1Type))
{
- // When not materializing the result in a register, the compare logic is generated
- // when we generate the GT_JTRUE.
- if (treeNode->gtRegNum != REG_NA)
- {
- genCompareLong(treeNode);
- }
- else
- {
- // We generate the compare when we generate the GT_JTRUE, but we need to consume
- // the operands now.
- genConsumeOperands(treeNode->AsOp());
- }
+#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);
}
#endif // !defined(_TARGET_64BIT_)
else
@@ -2437,52 +1826,60 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
assert(compiler->compCurBB->bbJumpKind == BBJ_COND);
#if !defined(_TARGET_64BIT_)
- // For long compares, we emit special logic
- if (varTypeIsLong(cmp->gtGetOp1()))
- {
- genJTrueLong(cmp);
- }
- else
+ // Long-typed compares should have been handled by Lowering::LowerCompare.
+ assert(!varTypeIsLong(cmp->gtGetOp1()));
#endif
- {
- // Get the "kind" and type of the comparison. Note that whether it is an unsigned cmp
- // is governed by a flag NOT by the inherent type of the node
- // TODO-XArch-CQ: Check if we can use the currently set flags.
- emitJumpKind jumpKind[2];
- bool branchToTrueLabel[2];
- genJumpKindsForTree(cmp, jumpKind, branchToTrueLabel);
- BasicBlock* skipLabel = nullptr;
- if (jumpKind[0] != EJ_NONE)
- {
- BasicBlock* jmpTarget;
- if (branchToTrueLabel[0])
- {
- jmpTarget = compiler->compCurBB->bbJumpDest;
- }
- else
- {
- // This case arises only for ordered GT_EQ right now
- assert((cmp->gtOper == GT_EQ) && ((cmp->gtFlags & GTF_RELOP_NAN_UN) == 0));
- skipLabel = genCreateTempLabel();
- jmpTarget = skipLabel;
- }
-
- inst_JMP(jumpKind[0], jmpTarget);
- }
+ // Get the "kind" and type of the comparison. Note that whether it is an unsigned cmp
+ // is governed by a flag NOT by the inherent type of the node
+ // TODO-XArch-CQ: Check if we can use the currently set flags.
+ emitJumpKind jumpKind[2];
+ bool branchToTrueLabel[2];
+ genJumpKindsForTree(cmp, jumpKind, branchToTrueLabel);
- if (jumpKind[1] != EJ_NONE)
+ BasicBlock* skipLabel = nullptr;
+ if (jumpKind[0] != EJ_NONE)
+ {
+ BasicBlock* jmpTarget;
+ if (branchToTrueLabel[0])
{
- // the second conditional branch always has to be to the true label
- assert(branchToTrueLabel[1]);
- inst_JMP(jumpKind[1], compiler->compCurBB->bbJumpDest);
+ jmpTarget = compiler->compCurBB->bbJumpDest;
}
-
- if (skipLabel != nullptr)
+ else
{
- genDefineTempLabel(skipLabel);
+ // This case arises only for ordered GT_EQ right now
+ assert((cmp->gtOper == GT_EQ) && ((cmp->gtFlags & GTF_RELOP_NAN_UN) == 0));
+ skipLabel = genCreateTempLabel();
+ jmpTarget = skipLabel;
}
+
+ inst_JMP(jumpKind[0], jmpTarget);
+ }
+
+ if (jumpKind[1] != EJ_NONE)
+ {
+ // the second conditional branch always has to be to the true label
+ assert(branchToTrueLabel[1]);
+ inst_JMP(jumpKind[1], compiler->compCurBB->bbJumpDest);
}
+
+ if (skipLabel != nullptr)
+ {
+ genDefineTempLabel(skipLabel);
+ }
+ }
+ 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;
@@ -2572,12 +1969,13 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
break;
case GT_LIST:
+ case GT_FIELD_LIST:
case GT_ARGPLACE:
// Nothing to do
break;
case GT_PUTARG_STK:
- genPutArgStk(treeNode);
+ genPutArgStk(treeNode->AsPutArgStk());
break;
case GT_PUTARG_REG:
@@ -2608,7 +2006,7 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
case GT_LOCKADD:
case GT_XCHG:
case GT_XADD:
- genLockedInstructions(treeNode);
+ genLockedInstructions(treeNode->AsOp());
break;
case GT_MEMORYBARRIER:
@@ -2795,7 +2193,8 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
{
#ifdef DEBUG
char message[256];
- sprintf(message, "Unimplemented node type %s\n", GenTree::NodeName(treeNode->OperGet()));
+ _snprintf_s(message, _countof(message), _TRUNCATE, "Unimplemented node type %s\n",
+ GenTree::NodeName(treeNode->OperGet()));
#endif
assert(!"Unknown node in codegen");
}
@@ -3330,8 +2729,10 @@ ALLOC_DONE:
BAILOUT:
// Write the lvaLocAllocSPvar stack frame slot
- noway_assert(compiler->lvaLocAllocSPvar != BAD_VAR_NUM);
- getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, REG_SPBASE, compiler->lvaLocAllocSPvar, 0);
+ if (compiler->lvaLocAllocSPvar != BAD_VAR_NUM)
+ {
+ getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, REG_SPBASE, compiler->lvaLocAllocSPvar, 0);
+ }
#if STACK_PROBES
if (compiler->opts.compNeedStackProbes)
@@ -3356,10 +2757,15 @@ BAILOUT:
void CodeGen::genCodeForStoreBlk(GenTreeBlk* storeBlkNode)
{
+#ifdef JIT32_GCENCODER
+ assert(!storeBlkNode->gtBlkOpGcUnsafe);
+#else
if (storeBlkNode->gtBlkOpGcUnsafe)
{
getEmitter()->emitDisableGC();
}
+#endif // JIT32_GCENCODER
+
bool isCopyBlk = storeBlkNode->OperIsCopyBlkOp();
switch (storeBlkNode->gtBlkOpKind)
@@ -3399,23 +2805,40 @@ void CodeGen::genCodeForStoreBlk(GenTreeBlk* storeBlkNode)
default:
unreached();
}
+
+#ifndef JIT32_GCENCODER
if (storeBlkNode->gtBlkOpGcUnsafe)
{
getEmitter()->emitEnableGC();
}
+#endif // !defined(JIT32_GCENCODER)
}
-// Generate code for InitBlk using rep stos.
+//
+//------------------------------------------------------------------------
+// genCodeForInitBlkRepStos: Generate code for InitBlk using rep stos.
+//
+// Arguments:
+// initBlkNode - The Block store for which we are generating code.
+//
// Preconditions:
-// The size of the buffers must be a constant and also less than INITBLK_STOS_LIMIT bytes.
-// Any value larger than that, we'll use the helper even if both the
-// fill byte and the size are integer constants.
+// On x64:
+// The size of the buffers must be a constant and also less than INITBLK_STOS_LIMIT bytes.
+// Any value larger than that, we'll use the helper even if both the fill byte and the
+// size are integer constants.
+// On x86:
+// The size must either be a non-constant or less than INITBLK_STOS_LIMIT bytes.
+//
void CodeGen::genCodeForInitBlkRepStos(GenTreeBlk* initBlkNode)
{
- // Make sure we got the arguments of the initblk/initobj operation in the right registers
+ // Make sure we got the arguments of the initblk/initobj operation in the right registers.
unsigned size = initBlkNode->Size();
GenTreePtr dstAddr = initBlkNode->Addr();
GenTreePtr initVal = initBlkNode->Data();
+ if (initVal->OperIsInitVal())
+ {
+ initVal = initVal->gtGetOp1();
+ }
#ifdef DEBUG
assert(!dstAddr->isContained());
@@ -3428,7 +2851,8 @@ void CodeGen::genCodeForInitBlkRepStos(GenTreeBlk* initBlkNode)
#ifdef _TARGET_AMD64_
assert(size > CPBLK_UNROLL_LIMIT && size < CPBLK_MOVS_LIMIT);
#else
- assert(size > CPBLK_UNROLL_LIMIT);
+ // Note that a size of zero means a non-constant size.
+ assert((size == 0) || (size > CPBLK_UNROLL_LIMIT));
#endif
}
@@ -3449,9 +2873,13 @@ void CodeGen::genCodeForInitBlkUnroll(GenTreeBlk* initBlkNode)
unsigned size = initBlkNode->Size();
GenTreePtr dstAddr = initBlkNode->Addr();
GenTreePtr initVal = initBlkNode->Data();
+ if (initVal->OperIsInitVal())
+ {
+ initVal = initVal->gtGetOp1();
+ }
assert(!dstAddr->isContained());
- assert(!initVal->isContained());
+ assert(!initVal->isContained() || (initVal->IsIntegralConst(0) && ((size & 0xf) == 0)));
assert(size != 0);
assert(size <= INITBLK_UNROLL_LIMIT);
assert(initVal->gtSkipReloadOrCopy()->IsCnsIntOrI());
@@ -3512,9 +2940,11 @@ void CodeGen::genCodeForInitBlkUnroll(GenTreeBlk* initBlkNode)
offset += 4;
emit->emitIns_AR_R(INS_mov, EA_4BYTE, valReg, dstAddr->gtRegNum, offset);
offset += 4;
-#else // !_TARGET_X86_
+#else // !_TARGET_X86_
+
emit->emitIns_AR_R(INS_mov, EA_8BYTE, valReg, dstAddr->gtRegNum, offset);
offset += 8;
+
#endif // !_TARGET_X86_
}
if ((size & 4) != 0)
@@ -3544,6 +2974,10 @@ void CodeGen::genCodeForInitBlk(GenTreeBlk* initBlkNode)
unsigned blockSize = initBlkNode->Size();
GenTreePtr dstAddr = initBlkNode->Addr();
GenTreePtr initVal = initBlkNode->Data();
+ if (initVal->OperIsInitVal())
+ {
+ initVal = initVal->gtGetOp1();
+ }
assert(!dstAddr->isContained());
assert(!initVal->isContained());
@@ -3760,21 +3194,145 @@ void CodeGen::genCodeForCpBlkRepMovs(GenTreeBlk* cpBlkNode)
instGen(INS_r_movsb);
}
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
+#ifdef FEATURE_PUT_STRUCT_ARG_STK
+//------------------------------------------------------------------------
+// CodeGen::genMove8IfNeeded: Conditionally move 8 bytes of a struct to the argument area
+//
+// Arguments:
+// size - The size of bytes remaining to be moved
+// longTmpReg - The tmp register to be used for the long value
+// srcAddr - The address of the source struct
+// offset - The current offset being copied
+//
+// Return Value:
+// Returns the number of bytes moved (8 or 0).
+//
+// Notes:
+// This is used in the PutArgStkKindUnroll case, to move any bytes that are
+// not an even multiple of 16.
+// 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)
+{
+#ifdef _TARGET_X86_
+ instruction longMovIns = INS_movq;
+#else // !_TARGET_X86_
+ instruction longMovIns = INS_mov;
+#endif // !_TARGET_X86_
+ if ((size & 8) != 0)
+ {
+ genCodeForLoadOffset(longMovIns, EA_8BYTE, longTmpReg, srcAddr, offset);
+ genStoreRegToStackArg(TYP_LONG, longTmpReg, offset);
+ return 8;
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------------
+// CodeGen::genMove4IfNeeded: Conditionally move 4 bytes of a struct to the argument area
+//
+// Arguments:
+// size - The size of bytes remaining to be moved
+// intTmpReg - The tmp register to be used for the long value
+// srcAddr - The address of the source struct
+// offset - The current offset being copied
+//
+// Return Value:
+// Returns the number of bytes moved (4 or 0).
+//
+// Notes:
+// This is used in the PutArgStkKindUnroll case, to move any bytes that are
+// not an even multiple of 16.
+// intTmpReg must be an integer register.
+// This is checked by genStoreRegToStackArg.
+//
+int CodeGen::genMove4IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAddr, unsigned offset)
+{
+ if ((size & 4) != 0)
+ {
+ genCodeForLoadOffset(INS_mov, EA_4BYTE, intTmpReg, srcAddr, offset);
+ genStoreRegToStackArg(TYP_INT, intTmpReg, offset);
+ return 4;
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------------
+// CodeGen::genMove2IfNeeded: Conditionally move 2 bytes of a struct to the argument area
+//
+// Arguments:
+// size - The size of bytes remaining to be moved
+// intTmpReg - The tmp register to be used for the long value
+// srcAddr - The address of the source struct
+// offset - The current offset being copied
+//
+// Return Value:
+// Returns the number of bytes moved (2 or 0).
+//
+// Notes:
+// This is used in the PutArgStkKindUnroll case, to move any bytes that are
+// not an even multiple of 16.
+// intTmpReg must be an integer register.
+// This is checked by genStoreRegToStackArg.
+//
+int CodeGen::genMove2IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAddr, unsigned offset)
+{
+ if ((size & 2) != 0)
+ {
+ genCodeForLoadOffset(INS_mov, EA_2BYTE, intTmpReg, srcAddr, offset);
+ genStoreRegToStackArg(TYP_SHORT, intTmpReg, offset);
+ return 2;
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------------
+// CodeGen::genMove1IfNeeded: Conditionally move 1 byte of a struct to the argument area
+//
+// Arguments:
+// size - The size of bytes remaining to be moved
+// intTmpReg - The tmp register to be used for the long value
+// srcAddr - The address of the source struct
+// offset - The current offset being copied
+//
+// Return Value:
+// Returns the number of bytes moved (1 or 0).
+//
+// Notes:
+// This is used in the PutArgStkKindUnroll case, to move any bytes that are
+// not an even multiple of 16.
+// intTmpReg must be an integer register.
+// This is checked by genStoreRegToStackArg.
+//
+int CodeGen::genMove1IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAddr, unsigned offset)
+{
+
+ if ((size & 1) != 0)
+ {
+ genCodeForLoadOffset(INS_mov, EA_1BYTE, intTmpReg, srcAddr, offset);
+ genStoreRegToStackArg(TYP_BYTE, intTmpReg, offset);
+ return 1;
+ }
+ return 0;
+}
//---------------------------------------------------------------------------------------------------------------//
// genStructPutArgUnroll: Generates code for passing a struct arg on stack by value using loop unrolling.
//
// Arguments:
// putArgNode - the PutArgStk tree.
-// baseVarNum - the base var number, relative to which the by-val struct will be copied on the stack.
+//
+// Notes:
+// m_stkArgVarNum must be set to the base var number, relative to which the by-val struct will be copied to the
+// stack.
//
// TODO-Amd64-Unix: Try to share code with copyblk.
// Need refactoring of copyblk before it could be used for putarg_stk.
// The difference for now is that a putarg_stk contains its children, while cpyblk does not.
// This creates differences in code. After some significant refactoring it could be reused.
//
-void CodeGen::genStructPutArgUnroll(GenTreePutArgStk* putArgNode, unsigned baseVarNum)
+void CodeGen::genStructPutArgUnroll(GenTreePutArgStk* putArgNode)
{
// We will never call this method for SIMD types, which are stored directly
// in genPutStructArgStk().
@@ -3801,14 +3359,43 @@ void CodeGen::genStructPutArgUnroll(GenTreePutArgStk* putArgNode, unsigned baseV
unsigned offset = 0;
+ regNumber xmmTmpReg = REG_NA;
+ regNumber intTmpReg = REG_NA;
+ regNumber longTmpReg = REG_NA;
+#ifdef _TARGET_X86_
+ // On x86 we use an XMM register for both 16 and 8-byte chunks, but if it's
+ // less than 16 bytes, we will just be using pushes
+ if (size >= 8)
+ {
+ xmmTmpReg = genRegNumFromMask(putArgNode->gtRsvdRegs & RBM_ALLFLOAT);
+ longTmpReg = xmmTmpReg;
+ }
+ if ((size & 0x7) != 0)
+ {
+ intTmpReg = genRegNumFromMask(putArgNode->gtRsvdRegs & RBM_ALLINT);
+ }
+#else // !_TARGET_X86_
+ // On x64 we use an XMM register only for 16-byte chunks.
+ if (size >= XMM_REGSIZE_BYTES)
+ {
+ xmmTmpReg = genRegNumFromMask(putArgNode->gtRsvdRegs & RBM_ALLFLOAT);
+ }
+ if ((size & 0xf) != 0)
+ {
+ intTmpReg = genRegNumFromMask(putArgNode->gtRsvdRegs & RBM_ALLINT);
+ longTmpReg = intTmpReg;
+ }
+#endif // !_TARGET_X86_
+
// 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)
{
+#ifdef _TARGET_X86_
+ assert(!m_pushStkArg);
+#endif // _TARGET_X86_
assert(putArgNode->gtRsvdRegs != RBM_NONE);
- regNumber xmmReg = genRegNumFromMask(putArgNode->gtRsvdRegs & RBM_ALLFLOAT);
- assert(genIsValidFloatReg(xmmReg));
size_t slots = size / XMM_REGSIZE_BYTES;
assert(putArgNode->gtGetOp1()->isContained());
@@ -3820,11 +3407,10 @@ void CodeGen::genStructPutArgUnroll(GenTreePutArgStk* putArgNode, unsigned baseV
while (slots-- > 0)
{
// Load
- genCodeForLoadOffset(INS_movdqu, EA_8BYTE, xmmReg, src->gtGetOp1(),
- offset); // Load the address of the child of the Obj node.
+ genCodeForLoadOffset(INS_movdqu, EA_8BYTE, xmmTmpReg, src->gtGetOp1(), offset);
// Store
- emit->emitIns_S_R(INS_movdqu, EA_8BYTE, xmmReg, baseVarNum, putArgOffset + offset);
+ genStoreRegToStackArg(TYP_STRUCT, xmmTmpReg, offset);
offset += XMM_REGSIZE_BYTES;
}
@@ -3833,41 +3419,29 @@ void CodeGen::genStructPutArgUnroll(GenTreePutArgStk* putArgNode, unsigned baseV
// 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(putArgNode->gtRsvdRegs & RBM_ALLINT);
- assert(genIsValidIntReg(tmpReg));
-
- if ((size & 8) != 0)
- {
- genCodeForLoadOffset(INS_mov, EA_8BYTE, tmpReg, src->gtOp.gtOp1, offset);
-
- emit->emitIns_S_R(INS_mov, EA_8BYTE, tmpReg, baseVarNum, putArgOffset + offset);
-
- offset += 8;
- }
-
- if ((size & 4) != 0)
- {
- genCodeForLoadOffset(INS_mov, EA_4BYTE, tmpReg, src->gtOp.gtOp1, offset);
-
- emit->emitIns_S_R(INS_mov, EA_4BYTE, tmpReg, baseVarNum, putArgOffset + offset);
-
- offset += 4;
- }
-
- if ((size & 2) != 0)
- {
- genCodeForLoadOffset(INS_mov, EA_2BYTE, tmpReg, src->gtOp.gtOp1, offset);
-
- emit->emitIns_S_R(INS_mov, EA_2BYTE, tmpReg, baseVarNum, putArgOffset + offset);
-
- offset += 2;
+#ifdef _TARGET_X86_
+ if (m_pushStkArg)
+ {
+ // This case is currently supported only for the case where the total size is
+ // less than XMM_REGSIZE_BYTES. We need to push the remaining chunks in reverse
+ // order. However, morph has ensured that we have a struct that is an even
+ // multiple of TARGET_POINTER_SIZE, so we don't need to worry about alignment.
+ assert(((size & 0xc) == size) && (offset == 0));
+ // If we have a 4 byte chunk, load it from either offset 0 or 8, depending on
+ // whether we've got an 8 byte chunk, and then push it on the stack.
+ unsigned pushedBytes = genMove4IfNeeded(size, intTmpReg, src->gtOp.gtOp1, size & 0x8);
+ // Now if we have an 8 byte chunk, load it from offset 0 (it's the first chunk)
+ // and push it on the stack.
+ pushedBytes += genMove8IfNeeded(size, longTmpReg, src->gtOp.gtOp1, 0);
}
-
- if ((size & 1) != 0)
+ else
+#endif // _TARGET_X86_
{
- genCodeForLoadOffset(INS_mov, EA_1BYTE, tmpReg, src->gtOp.gtOp1, offset);
- emit->emitIns_S_R(INS_mov, EA_1BYTE, tmpReg, baseVarNum, putArgOffset + offset);
+ offset += genMove8IfNeeded(size, longTmpReg, src->gtOp.gtOp1, offset);
+ offset += genMove4IfNeeded(size, intTmpReg, src->gtOp.gtOp1, offset);
+ offset += genMove2IfNeeded(size, intTmpReg, src->gtOp.gtOp1, offset);
+ offset += genMove1IfNeeded(size, intTmpReg, src->gtOp.gtOp1, offset);
+ assert(offset == size);
}
}
}
@@ -3877,17 +3451,16 @@ void CodeGen::genStructPutArgUnroll(GenTreePutArgStk* putArgNode, unsigned baseV
//
// Arguments:
// putArgNode - the PutArgStk tree.
-// baseVarNum - the base var number, relative to which the by-val struct bits will go.
//
// Preconditions:
// The size argument of the PutArgStk (for structs) is a constant and is between
// CPBLK_UNROLL_LIMIT and CPBLK_MOVS_LIMIT bytes.
+// m_stkArgVarNum must be set to the base var number, relative to which the by-val struct bits will go.
//
-void CodeGen::genStructPutArgRepMovs(GenTreePutArgStk* putArgNode, unsigned baseVarNum)
+void CodeGen::genStructPutArgRepMovs(GenTreePutArgStk* putArgNode)
{
assert(putArgNode->TypeGet() == TYP_STRUCT);
assert(putArgNode->getArgSize() > CPBLK_UNROLL_LIMIT);
- assert(baseVarNum != BAD_VAR_NUM);
// Make sure we got the arguments of the cpblk operation in the right registers
GenTreePtr dstAddr = putArgNode;
@@ -3897,7 +3470,7 @@ void CodeGen::genStructPutArgRepMovs(GenTreePutArgStk* putArgNode, unsigned base
assert(putArgNode->gtRsvdRegs == (RBM_RDI | RBM_RCX | RBM_RSI));
assert(srcAddr->isContained());
- genConsumePutStructArgStk(putArgNode, REG_RDI, REG_RSI, REG_RCX, baseVarNum);
+ genConsumePutStructArgStk(putArgNode, REG_RDI, REG_RSI, REG_RCX);
instGen(INS_r_movsb);
}
@@ -3906,12 +3479,14 @@ void CodeGen::genStructPutArgRepMovs(GenTreePutArgStk* putArgNode, unsigned base
// must be cleared to zeroes. The native compiler doesn't clear the upper bits
// and there is no way to know if the caller is native or not. So, the upper
// 32 bits of Vector argument on stack are always cleared to zero.
-#ifdef FEATURE_SIMD
+#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING) && defined(FEATURE_SIMD)
void CodeGen::genClearStackVec3ArgUpperBits()
{
#ifdef DEBUG
if (verbose)
+ {
printf("*************** In genClearStackVec3ArgUpperBits()\n");
+ }
#endif
assert(compiler->compGeneratingProlog);
@@ -3948,12 +3523,13 @@ void CodeGen::genClearStackVec3ArgUpperBits()
}
}
}
-#endif // FEATURE_SIMD
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+#endif // defined(FEATURE_UNIX_AMD64_STRUCT_PASSING) && defined(FEATURE_SIMD)
+#endif // FEATURE_PUT_STRUCT_ARG_STK
// Generate code for CpObj nodes wich copy structs that have interleaved
// GC pointers.
-// This will generate a sequence of movsq instructions for the cases of non-gc members
+// This will generate a sequence of movsp instructions for the cases of non-gc members.
+// Note that movsp is an alias for movsd on x86 and movsq on x64.
// and calls to the BY_REF_ASSIGN helper otherwise.
void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)
{
@@ -3961,6 +3537,7 @@ void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)
GenTreePtr dstAddr = cpObjNode->Addr();
GenTreePtr source = cpObjNode->Data();
GenTreePtr srcAddr = nullptr;
+ var_types srcAddrType = TYP_BYREF;
bool sourceIsLocal = false;
assert(source->isContained());
@@ -3973,24 +3550,12 @@ void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)
{
noway_assert(source->IsLocal());
sourceIsLocal = true;
- // TODO: 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;
}
bool dstOnStack = dstAddr->OperIsLocalAddr();
#ifdef DEBUG
- bool isRepMovsqUsed = false;
+ bool isRepMovspUsed = false;
assert(!dstAddr->isContained());
@@ -3998,44 +3563,40 @@ void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)
// with CpObj, so this requires special logic.
assert(cpObjNode->gtGcPtrCount > 0);
- // MovSq instruction is used for copying non-gcref fields and it needs
- // src = RSI and dst = RDI.
+ // MovSp (alias for movsq on x64 and movsd on x86) instruction is used for copying non-gcref fields
+ // and it needs src = RSI and dst = RDI.
// Either these registers must not contain lclVars, or they must be dying or marked for spill.
// This is because these registers are incremented as we go through the struct.
- GenTree* actualSrcAddr = srcAddr->gtSkipReloadOrCopy();
- GenTree* actualDstAddr = dstAddr->gtSkipReloadOrCopy();
- unsigned srcLclVarNum = BAD_VAR_NUM;
- unsigned dstLclVarNum = BAD_VAR_NUM;
- bool isSrcAddrLiveOut = false;
- bool isDstAddrLiveOut = false;
- if (genIsRegCandidateLocal(actualSrcAddr))
- {
- srcLclVarNum = actualSrcAddr->AsLclVarCommon()->gtLclNum;
- isSrcAddrLiveOut = ((actualSrcAddr->gtFlags & (GTF_VAR_DEATH | GTF_SPILL)) == 0);
- }
- if (genIsRegCandidateLocal(actualDstAddr))
- {
- dstLclVarNum = actualDstAddr->AsLclVarCommon()->gtLclNum;
- isDstAddrLiveOut = ((actualDstAddr->gtFlags & (GTF_VAR_DEATH | GTF_SPILL)) == 0);
- }
- assert((actualSrcAddr->gtRegNum != REG_RSI) || !isSrcAddrLiveOut ||
- ((srcLclVarNum == dstLclVarNum) && !isDstAddrLiveOut));
- assert((actualDstAddr->gtRegNum != REG_RDI) || !isDstAddrLiveOut ||
- ((srcLclVarNum == dstLclVarNum) && !isSrcAddrLiveOut));
+ if (!sourceIsLocal)
+ {
+ GenTree* actualSrcAddr = srcAddr->gtSkipReloadOrCopy();
+ GenTree* actualDstAddr = dstAddr->gtSkipReloadOrCopy();
+ unsigned srcLclVarNum = BAD_VAR_NUM;
+ unsigned dstLclVarNum = BAD_VAR_NUM;
+ bool isSrcAddrLiveOut = false;
+ bool isDstAddrLiveOut = false;
+ if (genIsRegCandidateLocal(actualSrcAddr))
+ {
+ srcLclVarNum = actualSrcAddr->AsLclVarCommon()->gtLclNum;
+ isSrcAddrLiveOut = ((actualSrcAddr->gtFlags & (GTF_VAR_DEATH | GTF_SPILL)) == 0);
+ }
+ if (genIsRegCandidateLocal(actualDstAddr))
+ {
+ dstLclVarNum = actualDstAddr->AsLclVarCommon()->gtLclNum;
+ isDstAddrLiveOut = ((actualDstAddr->gtFlags & (GTF_VAR_DEATH | GTF_SPILL)) == 0);
+ }
+ assert((actualSrcAddr->gtRegNum != REG_RSI) || !isSrcAddrLiveOut ||
+ ((srcLclVarNum == dstLclVarNum) && !isDstAddrLiveOut));
+ assert((actualDstAddr->gtRegNum != REG_RDI) || !isDstAddrLiveOut ||
+ ((srcLclVarNum == dstLclVarNum) && !isSrcAddrLiveOut));
+ srcAddrType = srcAddr->TypeGet();
+ }
#endif // DEBUG
- // Consume these registers.
+ // Consume the operands and get them into the right registers.
// They may now contain gc pointers (depending on their type; gcMarkRegPtrVal will "do the right thing").
- if (sourceIsLocal)
- {
- inst_RV_TT(INS_lea, REG_RSI, source, 0, EA_BYREF);
- genConsumeBlockOp(cpObjNode, REG_RDI, REG_NA, REG_NA);
- }
- else
- {
- genConsumeBlockOp(cpObjNode, REG_RDI, REG_RSI, REG_NA);
- }
- gcInfo.gcMarkRegPtrVal(REG_RSI, srcAddr->TypeGet());
+ genConsumeBlockOp(cpObjNode, REG_RDI, REG_RSI, REG_NA);
+ gcInfo.gcMarkRegPtrVal(REG_RSI, srcAddrType);
gcInfo.gcMarkRegPtrVal(REG_RDI, dstAddr->TypeGet());
unsigned slots = cpObjNode->gtSlots;
@@ -4046,23 +3607,23 @@ void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)
if (slots >= CPOBJ_NONGC_SLOTS_LIMIT)
{
#ifdef DEBUG
- // If the destination of the CpObj is on the stack
- // make sure we allocated RCX to emit rep movsq.
- regNumber tmpReg = genRegNumFromMask(cpObjNode->gtRsvdRegs & RBM_ALLINT);
- assert(tmpReg == REG_RCX);
- isRepMovsqUsed = true;
+ // If the destination of the CpObj is on the stack, make sure we allocated
+ // RCX to emit the movsp (alias for movsd or movsq for 32 and 64 bits respectively).
+ assert((cpObjNode->gtRsvdRegs & RBM_RCX) != 0);
+ regNumber tmpReg = REG_RCX;
+ isRepMovspUsed = true;
#endif // DEBUG
getEmitter()->emitIns_R_I(INS_mov, EA_4BYTE, REG_RCX, slots);
- instGen(INS_r_movsq);
+ instGen(INS_r_movsp);
}
else
{
- // For small structs, it's better to emit a sequence of movsq than to
- // emit a rep movsq instruction.
+ // For small structs, it's better to emit a sequence of movsp than to
+ // emit a rep movsp instruction.
while (slots > 0)
{
- instGen(INS_movsq);
+ instGen(INS_movsp);
slots--;
}
}
@@ -4078,7 +3639,7 @@ void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)
switch (gcPtrs[i])
{
case TYPE_GC_NONE:
- // Let's see if we can use rep movsq instead of a sequence of movsq instructions
+ // Let's see if we can use rep movsp instead of a sequence of movsp instructions
// to save cycles and code size.
{
unsigned nonGcSlotCount = 0;
@@ -4090,12 +3651,12 @@ void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)
} while (i < slots && gcPtrs[i] == TYPE_GC_NONE);
// If we have a very small contiguous non-gc region, it's better just to
- // emit a sequence of movsq instructions
+ // emit a sequence of movsp instructions
if (nonGcSlotCount < CPOBJ_NONGC_SLOTS_LIMIT)
{
while (nonGcSlotCount > 0)
{
- instGen(INS_movsq);
+ instGen(INS_movsp);
nonGcSlotCount--;
}
}
@@ -4103,13 +3664,13 @@ void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)
{
#ifdef DEBUG
// Otherwise, we can save code-size and improve CQ by emitting
- // rep movsq
- regNumber tmpReg = genRegNumFromMask(cpObjNode->gtRsvdRegs & RBM_ALLINT);
- assert(tmpReg == REG_RCX);
- isRepMovsqUsed = true;
+ // rep movsp (alias for movsd/movsq for x86/x64)
+ assert((cpObjNode->gtRsvdRegs & RBM_RCX) != 0);
+ regNumber tmpReg = REG_RCX;
+ isRepMovspUsed = true;
#endif // DEBUG
getEmitter()->emitIns_R_I(INS_mov, EA_4BYTE, REG_RCX, nonGcSlotCount);
- instGen(INS_r_movsq);
+ instGen(INS_r_movsp);
}
}
break;
@@ -4235,7 +3796,7 @@ void CodeGen::genJumpTable(GenTree* treeNode)
// generate code for the locked operations:
// GT_LOCKADD, GT_XCHG, GT_XADD
-void CodeGen::genLockedInstructions(GenTree* treeNode)
+void CodeGen::genLockedInstructions(GenTreeOp* treeNode)
{
GenTree* data = treeNode->gtOp.gtOp2;
GenTree* addr = treeNode->gtOp.gtOp1;
@@ -4244,11 +3805,6 @@ void CodeGen::genLockedInstructions(GenTree* treeNode)
regNumber addrReg = addr->gtRegNum;
instruction ins;
- // 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);
- genConsumeReg(addr);
-
// The register allocator should have extended the lifetime of the address
// so that it is not used as the target.
noway_assert(addrReg != targetReg);
@@ -4258,7 +3814,7 @@ void CodeGen::genLockedInstructions(GenTree* treeNode)
assert(targetReg != REG_NA || treeNode->OperGet() == GT_LOCKADD || !genIsRegCandidateLocal(data) ||
(data->gtFlags & GTF_VAR_DEATH) != 0);
- genConsumeIfReg(data);
+ genConsumeOperands(treeNode);
if (targetReg != REG_NA && dataReg != REG_NA && dataReg != targetReg)
{
inst_RV_RV(ins_Copy(data->TypeGet()), targetReg, dataReg);
@@ -4284,6 +3840,10 @@ void CodeGen::genLockedInstructions(GenTree* treeNode)
default:
unreached();
}
+
+ // 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);
if (treeNode->gtRegNum != REG_NA)
@@ -4459,22 +4019,22 @@ void CodeGen::genCodeForArrOffset(GenTreeArrOffs* arrOffset)
GenTreePtr arrObj = arrOffset->gtArrObj;
regNumber tgtReg = arrOffset->gtRegNum;
-
- noway_assert(tgtReg != REG_NA);
+ assert(tgtReg != REG_NA);
unsigned dim = arrOffset->gtCurrDim;
unsigned rank = arrOffset->gtArrRank;
var_types elemType = arrOffset->gtArrElemType;
- // We will use a temp register for the offset*scale+effectiveIndex computation.
- regMaskTP tmpRegMask = arrOffset->gtRsvdRegs;
- regNumber tmpReg = genRegNumFromMask(tmpRegMask);
-
// First, consume the operands in the correct order.
regNumber offsetReg = REG_NA;
+ regNumber tmpReg = REG_NA;
if (!offsetNode->IsIntegralConst(0))
{
offsetReg = genConsumeReg(offsetNode);
+
+ // We will use a temp register for the offset*scale+effectiveIndex computation.
+ regMaskTP tmpRegMask = arrOffset->gtRsvdRegs;
+ tmpReg = genRegNumFromMask(tmpRegMask);
}
else
{
@@ -4495,6 +4055,9 @@ void CodeGen::genCodeForArrOffset(GenTreeArrOffs* arrOffset)
if (!offsetNode->IsIntegralConst(0))
{
+ assert(tmpReg != REG_NA);
+ assert(arrReg != REG_NA);
+
// Evaluate tgtReg = offsetReg*dim_size + indexReg.
// tmpReg is used to load dim_size and the result of the multiplication.
// Note that dim_size will never be negative.
@@ -4617,6 +4180,12 @@ instruction CodeGen::genGetInsForOper(genTreeOps oper, var_types type)
case GT_SUB_HI:
ins = INS_sbb;
break;
+ case GT_LSH_HI:
+ ins = INS_shld;
+ break;
+ case GT_RSH_LO:
+ ins = INS_shrd;
+ break;
#endif // !defined(_TARGET_64BIT_)
default:
unreached();
@@ -4654,6 +4223,7 @@ void CodeGen::genCodeForShift(GenTreePtr tree)
regNumber operandReg = operand->gtRegNum;
GenTreePtr shiftBy = tree->gtGetOp2();
+
if (shiftBy->isContainedIntOrIImmed())
{
// First, move the operand to the destination register and
@@ -4672,12 +4242,7 @@ void CodeGen::genCodeForShift(GenTreePtr tree)
// We must have the number of bits to shift stored in ECX, since we constrained this node to
// sit in ECX. In case this didn't happen, LSRA expects the code generator to move it since it's a single
// register destination requirement.
- regNumber shiftReg = shiftBy->gtRegNum;
- if (shiftReg != REG_RCX)
- {
- // Issue the mov to RCX:
- inst_RV_RV(INS_mov, REG_RCX, shiftReg, shiftBy->TypeGet());
- }
+ genCopyRegIfNeeded(shiftBy, REG_RCX);
// The operand to be shifted must not be in ECX
noway_assert(operandReg != REG_RCX);
@@ -4692,6 +4257,67 @@ void CodeGen::genCodeForShift(GenTreePtr tree)
genProduceReg(tree);
}
+#ifdef _TARGET_X86_
+//------------------------------------------------------------------------
+// genCodeForShiftLong: Generates the code sequence for a GenTree node that
+// represents a three operand bit shift or rotate operation (<<Hi, >>Lo).
+//
+// 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::genCodeForShiftLong(GenTreePtr tree)
+{
+ // Only the non-RMW case here.
+ genTreeOps oper = tree->OperGet();
+ assert(oper == GT_LSH_HI || oper == GT_RSH_LO);
+
+ GenTree* operand = tree->gtOp.gtOp1;
+ assert(operand->OperGet() == GT_LONG);
+ assert(!operand->gtOp.gtOp1->isContained());
+ assert(!operand->gtOp.gtOp2->isContained());
+
+ GenTree* operandLo = operand->gtGetOp1();
+ GenTree* operandHi = operand->gtGetOp2();
+
+ regNumber regLo = operandLo->gtRegNum;
+ regNumber regHi = operandHi->gtRegNum;
+
+ genConsumeOperands(tree->AsOp());
+
+ var_types targetType = tree->TypeGet();
+ instruction ins = genGetInsForOper(oper, targetType);
+
+ GenTreePtr shiftBy = tree->gtGetOp2();
+
+ assert(shiftBy->isContainedIntOrIImmed());
+
+ unsigned int count = shiftBy->AsIntConCommon()->IconValue();
+
+ regNumber regResult = (oper == GT_LSH_HI) ? regHi : regLo;
+
+ if (regResult != tree->gtRegNum)
+ {
+ inst_RV_RV(INS_mov, tree->gtRegNum, regResult, targetType);
+ }
+
+ if (oper == GT_LSH_HI)
+ {
+ inst_RV_RV_IV(ins, emitTypeSize(targetType), tree->gtRegNum, regLo, count);
+ }
+ else
+ {
+ assert(oper == GT_RSH_LO);
+ inst_RV_RV_IV(ins, emitTypeSize(targetType), tree->gtRegNum, regHi, count);
+ }
+
+ genProduceReg(tree);
+}
+#endif
+
//------------------------------------------------------------------------
// genCodeForShiftRMW: Generates the code sequence for a GT_STOREIND GenTree node that
// represents a RMW bit shift or rotate operation (<<, >>, >>>, rol, ror), for example:
@@ -4739,182 +4365,13 @@ void CodeGen::genCodeForShiftRMW(GenTreeStoreInd* storeInd)
// sit in ECX. In case this didn't happen, LSRA expects the code generator to move it since it's a single
// register destination requirement.
regNumber shiftReg = shiftBy->gtRegNum;
- if (shiftReg != REG_RCX)
- {
- // Issue the mov to RCX:
- inst_RV_RV(INS_mov, REG_RCX, shiftReg, shiftBy->TypeGet());
- }
+ genCopyRegIfNeeded(shiftBy, REG_RCX);
// The shiftBy operand is implicit, so call the unary version of emitInsRMW.
getEmitter()->emitInsRMW(ins, attr, storeInd);
}
}
-void CodeGen::genUnspillRegIfNeeded(GenTree* tree)
-{
- regNumber dstReg = tree->gtRegNum;
- GenTree* unspillTree = tree;
-
- if (tree->gtOper == GT_RELOAD)
- {
- unspillTree = tree->gtOp.gtOp1;
- }
-
- if ((unspillTree->gtFlags & GTF_SPILLED) != 0)
- {
- if (genIsRegCandidateLocal(unspillTree))
- {
- // Reset spilled flag, since we are going to load a local variable from its home location.
- unspillTree->gtFlags &= ~GTF_SPILLED;
-
- GenTreeLclVarCommon* lcl = unspillTree->AsLclVarCommon();
- LclVarDsc* varDsc = &compiler->lvaTable[lcl->gtLclNum];
-
- // Load local variable from its home location.
- // In most cases the tree type will indicate the correct type to use for the load.
- // However, if it is NOT a normalizeOnLoad lclVar (i.e. NOT a small int that always gets
- // widened when loaded into a register), and its size is not the same as genActualType of
- // the type of the lclVar, then we need to change the type of the tree node when loading.
- // This situation happens due to "optimizations" that avoid a cast and
- // simply retype the node when using long type lclVar as an int.
- // While loading the int in that case would work for this use of the lclVar, if it is
- // later used as a long, we will have incorrectly truncated the long.
- // In the normalizeOnLoad case ins_Load will return an appropriate sign- or zero-
- // extending load.
-
- var_types treeType = unspillTree->TypeGet();
- if (treeType != genActualType(varDsc->lvType) && !varTypeIsGC(treeType) && !varDsc->lvNormalizeOnLoad())
- {
- assert(!varTypeIsGC(varDsc));
- var_types spillType = genActualType(varDsc->lvType);
- unspillTree->gtType = spillType;
- inst_RV_TT(ins_Load(spillType, compiler->isSIMDTypeLocalAligned(lcl->gtLclNum)), dstReg, unspillTree);
- unspillTree->gtType = treeType;
- }
- else
- {
- inst_RV_TT(ins_Load(treeType, compiler->isSIMDTypeLocalAligned(lcl->gtLclNum)), dstReg, unspillTree);
- }
-
- unspillTree->SetInReg();
-
- // TODO-Review: We would like to call:
- // genUpdateRegLife(varDsc, /*isBorn*/ true, /*isDying*/ false DEBUGARG(tree));
- // instead of the following code, but this ends up hitting this assert:
- // assert((regSet.rsMaskVars & regMask) == 0);
- // due to issues with LSRA resolution moves.
- // So, just force it for now. This probably indicates a condition that creates a GC hole!
- //
- // Extra note: I think we really want to call something like gcInfo.gcUpdateForRegVarMove,
- // because the variable is not really going live or dead, but that method is somewhat poorly
- // factored because it, in turn, updates rsMaskVars which is part of RegSet not GCInfo.
- // TODO-Cleanup: This code exists in other CodeGen*.cpp files, and should be moved to CodeGenCommon.cpp.
-
- // Don't update the variable's location if we are just re-spilling it again.
-
- if ((unspillTree->gtFlags & GTF_SPILL) == 0)
- {
- genUpdateVarReg(varDsc, tree);
-#ifdef DEBUG
- if (VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex))
- {
- JITDUMP("\t\t\t\t\t\t\tRemoving V%02u from gcVarPtrSetCur\n", lcl->gtLclNum);
- }
-#endif // DEBUG
- VarSetOps::RemoveElemD(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex);
-
-#ifdef DEBUG
- if (compiler->verbose)
- {
- printf("\t\t\t\t\t\t\tV%02u in reg ", lcl->gtLclNum);
- varDsc->PrintVarReg();
- printf(" is becoming live ");
- compiler->printTreeID(unspillTree);
- printf("\n");
- }
-#endif // DEBUG
-
- regSet.AddMaskVars(genGetRegMask(varDsc));
- }
-
- gcInfo.gcMarkRegPtrVal(dstReg, unspillTree->TypeGet());
- }
- else if (unspillTree->IsMultiRegCall())
- {
- GenTreeCall* call = unspillTree->AsCall();
- ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc();
- unsigned regCount = retTypeDesc->GetReturnRegCount();
- GenTreeCopyOrReload* reloadTree = nullptr;
- if (tree->OperGet() == GT_RELOAD)
- {
- reloadTree = tree->AsCopyOrReload();
- }
-
- // In case of multi-reg call node, GTF_SPILLED flag on it indicates that
- // one or more of its result regs are spilled. Call node needs to be
- // queried to know which specific result regs to be unspilled.
- for (unsigned i = 0; i < regCount; ++i)
- {
- unsigned flags = call->GetRegSpillFlagByIdx(i);
- if ((flags & GTF_SPILLED) != 0)
- {
- var_types dstType = retTypeDesc->GetReturnRegType(i);
- regNumber unspillTreeReg = call->GetRegNumByIdx(i);
-
- if (reloadTree != nullptr)
- {
- dstReg = reloadTree->GetRegNumByIdx(i);
- if (dstReg == REG_NA)
- {
- dstReg = unspillTreeReg;
- }
- }
- else
- {
- dstReg = unspillTreeReg;
- }
-
- TempDsc* t = regSet.rsUnspillInPlace(call, unspillTreeReg, i);
- getEmitter()->emitIns_R_S(ins_Load(dstType), emitActualTypeSize(dstType), dstReg, t->tdTempNum(),
- 0);
- compiler->tmpRlsTemp(t);
- gcInfo.gcMarkRegPtrVal(dstReg, dstType);
- }
- }
-
- unspillTree->gtFlags &= ~GTF_SPILLED;
- unspillTree->SetInReg();
- }
- else
- {
- TempDsc* t = regSet.rsUnspillInPlace(unspillTree, unspillTree->gtRegNum);
- getEmitter()->emitIns_R_S(ins_Load(unspillTree->gtType), emitActualTypeSize(unspillTree->TypeGet()), dstReg,
- t->tdTempNum(), 0);
- compiler->tmpRlsTemp(t);
-
- unspillTree->gtFlags &= ~GTF_SPILLED;
- unspillTree->SetInReg();
- gcInfo.gcMarkRegPtrVal(dstReg, unspillTree->TypeGet());
- }
- }
-}
-
-// Do Liveness update for a subnodes that is being consumed by codegen
-// including the logic for reload in case is needed and also takes care
-// of locating the value on the desired register.
-void CodeGen::genConsumeRegAndCopy(GenTree* tree, regNumber needReg)
-{
- if (needReg == REG_NA)
- {
- return;
- }
- regNumber treeReg = genConsumeReg(tree);
- if (treeReg != needReg)
- {
- inst_RV_RV(INS_mov, needReg, treeReg, tree->TypeGet());
- }
-}
-
void CodeGen::genRegCopy(GenTree* treeNode)
{
assert(treeNode->OperGet() == GT_COPY);
@@ -5022,662 +4479,6 @@ void CodeGen::genRegCopy(GenTree* treeNode)
genProduceReg(treeNode);
}
-// Check that registers are consumed in the right order for the current node being generated.
-#ifdef DEBUG
-void CodeGen::genCheckConsumeNode(GenTree* treeNode)
-{
- // GT_PUTARG_REG is consumed out of order.
- if (treeNode->gtSeqNum != 0 && treeNode->OperGet() != GT_PUTARG_REG)
- {
- if (lastConsumedNode != nullptr)
- {
- if (treeNode == lastConsumedNode)
- {
- if (verbose)
- {
- printf("Node was consumed twice:\n ");
- compiler->gtDispTree(treeNode, nullptr, nullptr, true);
- }
- }
- else
- {
- if (verbose && (lastConsumedNode->gtSeqNum > treeNode->gtSeqNum))
- {
- printf("Nodes were consumed out-of-order:\n");
- compiler->gtDispTree(lastConsumedNode, nullptr, nullptr, true);
- compiler->gtDispTree(treeNode, nullptr, nullptr, true);
- }
- // assert(lastConsumedNode->gtSeqNum < treeNode->gtSeqNum);
- }
- }
- lastConsumedNode = treeNode;
- }
-}
-#endif // DEBUG
-
-//--------------------------------------------------------------------
-// genConsumeReg: Do liveness update for a subnode that is being
-// consumed by codegen.
-//
-// Arguments:
-// tree - GenTree node
-//
-// Return Value:
-// Returns the reg number of tree.
-// In case of multi-reg call node returns the first reg number
-// of the multi-reg return.
-regNumber CodeGen::genConsumeReg(GenTree* tree)
-{
- if (tree->OperGet() == GT_COPY)
- {
- genRegCopy(tree);
- }
-
- // Handle the case where we have a lclVar that needs to be copied before use (i.e. because it
- // interferes with one of the other sources (or the target, if it's a "delayed use" register)).
- // TODO-Cleanup: This is a special copyReg case in LSRA - consider eliminating these and
- // always using GT_COPY to make the lclVar location explicit.
- // Note that we have to do this before calling genUpdateLife because otherwise if we spill it
- // the lvRegNum will be set to REG_STK and we will lose track of what register currently holds
- // the lclVar (normally when a lclVar is spilled it is then used from its former register
- // location, which matches the gtRegNum on the node).
- // (Note that it doesn't matter if we call this before or after genUnspillRegIfNeeded
- // because if it's on the stack it will always get reloaded into tree->gtRegNum).
- if (genIsRegCandidateLocal(tree))
- {
- GenTreeLclVarCommon* lcl = tree->AsLclVarCommon();
- LclVarDsc* varDsc = &compiler->lvaTable[lcl->GetLclNum()];
- if (varDsc->lvRegNum != REG_STK && varDsc->lvRegNum != tree->gtRegNum)
- {
- inst_RV_RV(INS_mov, tree->gtRegNum, varDsc->lvRegNum);
- }
- }
-
- genUnspillRegIfNeeded(tree);
-
- // genUpdateLife() will also spill local var if marked as GTF_SPILL by calling CodeGen::genSpillVar
- genUpdateLife(tree);
-
- assert(tree->gtHasReg());
-
- // there are three cases where consuming a reg means clearing the bit in the live mask
- // 1. it was not produced by a local
- // 2. it was produced by a local that is going dead
- // 3. it was produced by a local that does not live in that reg (like one allocated on the stack)
-
- if (genIsRegCandidateLocal(tree))
- {
- GenTreeLclVarCommon* lcl = tree->AsLclVarCommon();
- LclVarDsc* varDsc = &compiler->lvaTable[lcl->GetLclNum()];
- assert(varDsc->lvLRACandidate);
-
- if ((tree->gtFlags & GTF_VAR_DEATH) != 0)
- {
- gcInfo.gcMarkRegSetNpt(genRegMask(varDsc->lvRegNum));
- }
- else if (varDsc->lvRegNum == REG_STK)
- {
- // We have loaded this into a register only temporarily
- gcInfo.gcMarkRegSetNpt(genRegMask(tree->gtRegNum));
- }
- }
- else
- {
- gcInfo.gcMarkRegSetNpt(tree->gtGetRegMask());
- }
-
- genCheckConsumeNode(tree);
- return tree->gtRegNum;
-}
-
-// Do liveness update for an address tree: one of GT_LEA, GT_LCL_VAR, or GT_CNS_INT (for call indirect).
-void CodeGen::genConsumeAddress(GenTree* addr)
-{
- if (!addr->isContained())
- {
- genConsumeReg(addr);
- }
- else if (addr->OperGet() == GT_LEA)
- {
- genConsumeAddrMode(addr->AsAddrMode());
- }
-}
-
-// do liveness update for a subnode that is being consumed by codegen
-void CodeGen::genConsumeAddrMode(GenTreeAddrMode* addr)
-{
- genConsumeOperands(addr);
-}
-
-void CodeGen::genConsumeRegs(GenTree* tree)
-{
-#if !defined(_TARGET_64BIT_)
- if (tree->OperGet() == GT_LONG)
- {
- genConsumeRegs(tree->gtGetOp1());
- genConsumeRegs(tree->gtGetOp2());
- return;
- }
-#endif // !defined(_TARGET_64BIT_)
-
- if (tree->isContained())
- {
- if (tree->isContainedSpillTemp())
- {
- // spill temps are un-tracked and hence no need to update life
- }
- else if (tree->isIndir())
- {
- genConsumeAddress(tree->AsIndir()->Addr());
- }
- else if (tree->OperGet() == GT_AND)
- {
- // This is the special contained GT_AND that we created in Lowering::LowerCmp()
- // Now we need to consume the operands of the GT_AND node.
- genConsumeOperands(tree->AsOp());
- }
- else if (tree->OperGet() == GT_LCL_VAR)
- {
- // A contained lcl var must be living on stack and marked as reg optional.
- unsigned varNum = tree->AsLclVarCommon()->GetLclNum();
- LclVarDsc* varDsc = compiler->lvaTable + varNum;
-
- noway_assert(varDsc->lvRegNum == REG_STK);
- noway_assert(tree->IsRegOptional());
-
- // Update the life of reg optional lcl var.
- genUpdateLife(tree);
- }
- else
- {
- assert(tree->OperIsLeaf());
- }
- }
- else
- {
- genConsumeReg(tree);
- }
-}
-
-//------------------------------------------------------------------------
-// genConsumeOperands: Do liveness update for the operands of a unary or binary tree
-//
-// Arguments:
-// tree - the GenTreeOp whose operands will have their liveness updated.
-//
-// Return Value:
-// None.
-//
-// Notes:
-// Note that this logic is localized here because we must do the liveness update in
-// the correct execution order. This is important because we may have two operands
-// that involve the same lclVar, and if one is marked "lastUse" we must handle it
-// after the first.
-
-void CodeGen::genConsumeOperands(GenTreeOp* tree)
-{
- GenTree* firstOp = tree->gtOp1;
- GenTree* secondOp = tree->gtOp2;
- if ((tree->gtFlags & GTF_REVERSE_OPS) != 0)
- {
- assert(secondOp != nullptr);
- firstOp = secondOp;
- secondOp = tree->gtOp1;
- }
- if (firstOp != nullptr)
- {
- genConsumeRegs(firstOp);
- }
- if (secondOp != nullptr)
- {
- genConsumeRegs(secondOp);
- }
-}
-
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
-//------------------------------------------------------------------------
-// genConsumePutStructArgStk: Do liveness update for the operands of a PutArgStk node.
-// Also loads in the right register the addresses of the
-// src/dst for rep mov operation.
-//
-// Arguments:
-// putArgNode - the PUTARG_STK tree.
-// dstReg - the dstReg for the rep move operation.
-// srcReg - the srcReg for the rep move operation.
-// sizeReg - the sizeReg for the rep move operation.
-// baseVarNum - the varnum for the local used for placing the "by-value" args on the stack.
-//
-// Return Value:
-// None.
-//
-// Note: sizeReg can be REG_NA when this function is used to consume the dstReg and srcReg
-// for copying on the stack a struct with references.
-// The source address/offset is determined from the address on the GT_OBJ node, while
-// the destination address is the address contained in 'baseVarNum' plus the offset
-// provided in the 'putArgNode'.
-
-void CodeGen::genConsumePutStructArgStk(
- GenTreePutArgStk* putArgNode, regNumber dstReg, regNumber srcReg, regNumber sizeReg, unsigned baseVarNum)
-{
- assert(varTypeIsStruct(putArgNode));
- assert(baseVarNum != BAD_VAR_NUM);
-
- // The putArgNode children are always contained. We should not consume any registers.
- assert(putArgNode->gtGetOp1()->isContained());
-
- GenTree* dstAddr = putArgNode;
-
- // Get the source address.
- GenTree* src = putArgNode->gtGetOp1();
- assert((src->gtOper == GT_OBJ) || ((src->gtOper == GT_IND && varTypeIsSIMD(src))));
- GenTree* srcAddr = src->gtGetOp1();
-
- size_t size = putArgNode->getArgSize();
-
- assert(dstReg != REG_NA);
- assert(srcReg != REG_NA);
-
- // Consume the registers only if they are not contained or set to REG_NA.
- if (srcAddr->gtRegNum != REG_NA)
- {
- genConsumeReg(srcAddr);
- }
-
- // If the op1 is already in the dstReg - nothing to do.
- // Otherwise load the op1 (GT_ADDR) into the dstReg to copy the struct on the stack by value.
- if (dstAddr->gtRegNum != dstReg)
- {
- // Generate LEA instruction to load the stack of the outgoing var + SlotNum offset (or the incoming arg area
- // for tail calls) in RDI.
- // Destination is always local (on the stack) - use EA_PTRSIZE.
- getEmitter()->emitIns_R_S(INS_lea, EA_PTRSIZE, dstReg, baseVarNum, putArgNode->getArgOffset());
- }
-
- if (srcAddr->gtRegNum != srcReg)
- {
- if (srcAddr->OperIsLocalAddr())
- {
- // The OperLocalAddr is always contained.
- assert(srcAddr->isContained());
- GenTreeLclVarCommon* lclNode = srcAddr->AsLclVarCommon();
-
- // Generate LEA instruction to load the LclVar address in RSI.
- // Source is known to be on the stack. Use EA_PTRSIZE.
- unsigned int offset = 0;
- if (srcAddr->OperGet() == GT_LCL_FLD_ADDR)
- {
- offset = srcAddr->AsLclFld()->gtLclOffs;
- }
- getEmitter()->emitIns_R_S(INS_lea, EA_PTRSIZE, srcReg, lclNode->gtLclNum, offset);
- }
- else
- {
- assert(srcAddr->gtRegNum != REG_NA);
- // Source is not known to be on the stack. Use EA_BYREF.
- getEmitter()->emitIns_R_R(INS_mov, EA_BYREF, srcReg, srcAddr->gtRegNum);
- }
- }
-
- if (sizeReg != REG_NA)
- {
- inst_RV_IV(INS_mov, sizeReg, size, EA_8BYTE);
- }
-}
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
-
-//------------------------------------------------------------------------
-// genConsumeBlockSize: Ensure that the block size is in the given register
-//
-// Arguments:
-// blkNode - The block node
-// sizeReg - The register into which the block's size should go
-//
-
-void CodeGen::genConsumeBlockSize(GenTreeBlk* blkNode, regNumber sizeReg)
-{
- if (sizeReg != REG_NA)
- {
- unsigned blockSize = blkNode->Size();
- if (blockSize != 0)
- {
- assert(blkNode->gtRsvdRegs == genRegMask(sizeReg));
- genSetRegToIcon(sizeReg, blockSize);
- }
- else
- {
- noway_assert(blkNode->gtOper == GT_STORE_DYN_BLK);
- genConsumeReg(blkNode->AsDynBlk()->gtDynamicSize);
- }
- }
-}
-
-//------------------------------------------------------------------------
-// genConsumeBlockDst: Ensure that the block destination address is in its
-// allocated register.
-// Arguments:
-// blkNode - The block node
-//
-
-void CodeGen::genConsumeBlockDst(GenTreeBlk* blkNode)
-{
- GenTree* dstAddr = blkNode->Addr();
- genConsumeReg(dstAddr);
-}
-
-//------------------------------------------------------------------------
-// genConsumeBlockSrc: Ensure that the block source address is in its
-// allocated register if it is non-local.
-// Arguments:
-// blkNode - The block node
-//
-// Return Value:
-// Returns the source address node, if it is non-local,
-// and nullptr otherwise.
-
-GenTree* CodeGen::genConsumeBlockSrc(GenTreeBlk* blkNode)
-{
- GenTree* src = blkNode->Data();
- if (blkNode->OperIsCopyBlkOp())
- {
- // For a CopyBlk we need the address of the source.
- if (src->OperGet() == GT_IND)
- {
- src = src->gtOp.gtOp1;
- }
- else
- {
- // This must be a local.
- // For this case, there is no source address register, as it is a
- // stack-based address.
- assert(src->OperIsLocal());
- return nullptr;
- }
- }
- genConsumeReg(src);
- return src;
-}
-
-//------------------------------------------------------------------------
-// genConsumeBlockOp: Ensure that the block's operands are enregistered
-// as needed.
-// Arguments:
-// blkNode - The block node
-//
-// Notes:
-// This ensures that the operands are consumed in the proper order to
-// obey liveness modeling.
-
-void CodeGen::genConsumeBlockOp(GenTreeBlk* blkNode, regNumber dstReg, regNumber srcReg, regNumber sizeReg)
-{
- // We have to consume the registers, and perform any copies, in the actual execution order.
- // The nominal order is: dst, src, size. However this may have been changed
- // with reverse flags on the blkNode and the setting of gtEvalSizeFirst in the case of a dynamic
- // block size.
- // Note that the register allocator ensures that the registers ON THE NODES will not interfere
- // with one another if consumed (i.e. reloaded or moved to their ASSIGNED reg) in execution order.
- // Further, it ensures that they will not interfere with one another if they are then copied
- // to the REQUIRED register (if a fixed register requirement) in execution order. This requires,
- // then, that we first consume all the operands, then do any necessary moves.
-
- GenTree* dstAddr = blkNode->Addr();
- GenTree* src = nullptr;
- unsigned blockSize = blkNode->Size();
- GenTree* size = nullptr;
- bool evalSizeFirst = true;
-
- if (blkNode->OperGet() == GT_STORE_DYN_BLK)
- {
- evalSizeFirst = blkNode->AsDynBlk()->gtEvalSizeFirst;
- size = blkNode->AsDynBlk()->gtDynamicSize;
- }
-
- // First, consusme all the sources in order
- if (evalSizeFirst)
- {
- genConsumeBlockSize(blkNode, sizeReg);
- }
- if (blkNode->IsReverseOp())
- {
- src = genConsumeBlockSrc(blkNode);
- genConsumeBlockDst(blkNode);
- }
- else
- {
- genConsumeBlockDst(blkNode);
- src = genConsumeBlockSrc(blkNode);
- }
- if (!evalSizeFirst)
- {
- genConsumeBlockSize(blkNode, sizeReg);
- }
- // Next, perform any necessary moves.
- if (evalSizeFirst && (size != nullptr) && (size->gtRegNum != sizeReg))
- {
- inst_RV_RV(INS_mov, sizeReg, size->gtRegNum, size->TypeGet());
- }
- if (blkNode->IsReverseOp())
- {
- if ((src != nullptr) && (src->gtRegNum != srcReg))
- {
- inst_RV_RV(INS_mov, srcReg, src->gtRegNum, src->TypeGet());
- }
- if (dstAddr->gtRegNum != dstReg)
- {
- inst_RV_RV(INS_mov, dstReg, dstAddr->gtRegNum, dstAddr->TypeGet());
- }
- }
- else
- {
- if (dstAddr->gtRegNum != dstReg)
- {
- inst_RV_RV(INS_mov, dstReg, dstAddr->gtRegNum, dstAddr->TypeGet());
- }
- if ((src != nullptr) && (src->gtRegNum != srcReg))
- {
- inst_RV_RV(INS_mov, srcReg, src->gtRegNum, src->TypeGet());
- }
- }
- if (!evalSizeFirst && size != nullptr && (size->gtRegNum != sizeReg))
- {
- inst_RV_RV(INS_mov, sizeReg, size->gtRegNum, size->TypeGet());
- }
-}
-
-//-------------------------------------------------------------------------
-// genProduceReg: do liveness update for register produced by the current
-// node in codegen.
-//
-// Arguments:
-// tree - Gentree node
-//
-// Return Value:
-// None.
-void CodeGen::genProduceReg(GenTree* tree)
-{
- if (tree->gtFlags & GTF_SPILL)
- {
- // Code for GT_COPY node gets generated as part of consuming regs by its parent.
- // A GT_COPY node in turn produces reg result and it should never be marked to
- // spill.
- //
- // Similarly GT_RELOAD node gets generated as part of consuming regs by its
- // parent and should never be marked for spilling.
- noway_assert(!tree->IsCopyOrReload());
-
- if (genIsRegCandidateLocal(tree))
- {
- // Store local variable to its home location.
- tree->gtFlags &= ~GTF_REG_VAL;
- // Ensure that lclVar stores are typed correctly.
- unsigned varNum = tree->gtLclVarCommon.gtLclNum;
- assert(!compiler->lvaTable[varNum].lvNormalizeOnStore() ||
- (tree->TypeGet() == genActualType(compiler->lvaTable[varNum].TypeGet())));
- inst_TT_RV(ins_Store(tree->gtType, compiler->isSIMDTypeLocalAligned(varNum)), tree, tree->gtRegNum);
- }
- else
- {
- // In case of multi-reg call node, spill flag on call node
- // indicates that one or more of its allocated regs need to
- // be spilled. Call node needs to be further queried to
- // know which of its result regs needs to be spilled.
- if (tree->IsMultiRegCall())
- {
- GenTreeCall* call = tree->AsCall();
- ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc();
- unsigned regCount = retTypeDesc->GetReturnRegCount();
-
- for (unsigned i = 0; i < regCount; ++i)
- {
- unsigned flags = call->GetRegSpillFlagByIdx(i);
- if ((flags & GTF_SPILL) != 0)
- {
- regNumber reg = call->GetRegNumByIdx(i);
- call->SetInReg();
- regSet.rsSpillTree(reg, call, i);
- gcInfo.gcMarkRegSetNpt(genRegMask(reg));
- }
- }
- }
- else
- {
- tree->SetInReg();
- regSet.rsSpillTree(tree->gtRegNum, tree);
- gcInfo.gcMarkRegSetNpt(genRegMask(tree->gtRegNum));
- }
-
- tree->gtFlags |= GTF_SPILLED;
- tree->gtFlags &= ~GTF_SPILL;
-
- return;
- }
- }
-
- genUpdateLife(tree);
-
- // If we've produced a register, mark it as a pointer, as needed.
- if (tree->gtHasReg())
- {
- // We only mark the register in the following cases:
- // 1. It is not a register candidate local. In this case, we're producing a
- // register from a local, but the local is not a register candidate. Thus,
- // we must be loading it as a temp register, and any "last use" flag on
- // the register wouldn't be relevant.
- // 2. The register candidate local is going dead. There's no point to mark
- // the register as live, with a GC pointer, if the variable is dead.
- if (!genIsRegCandidateLocal(tree) || ((tree->gtFlags & GTF_VAR_DEATH) == 0))
- {
- // Multi-reg call node will produce more than one register result.
- // Mark all the regs produced by call node.
- if (tree->IsMultiRegCall())
- {
- GenTreeCall* call = tree->AsCall();
- ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc();
- unsigned regCount = retTypeDesc->GetReturnRegCount();
-
- for (unsigned i = 0; i < regCount; ++i)
- {
- regNumber reg = call->GetRegNumByIdx(i);
- var_types type = retTypeDesc->GetReturnRegType(i);
- gcInfo.gcMarkRegPtrVal(reg, type);
- }
- }
- else if (tree->IsCopyOrReloadOfMultiRegCall())
- {
- // we should never see reload of multi-reg call here
- // because GT_RELOAD gets generated in reg consuming path.
- noway_assert(tree->OperGet() == GT_COPY);
-
- // A multi-reg GT_COPY node produces those regs to which
- // copy has taken place.
- GenTreeCopyOrReload* copy = tree->AsCopyOrReload();
- GenTreeCall* call = copy->gtGetOp1()->AsCall();
- ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc();
- unsigned regCount = retTypeDesc->GetReturnRegCount();
-
- for (unsigned i = 0; i < regCount; ++i)
- {
- var_types type = retTypeDesc->GetReturnRegType(i);
- regNumber fromReg = call->GetRegNumByIdx(i);
- regNumber toReg = copy->GetRegNumByIdx(i);
-
- if (toReg != REG_NA)
- {
- gcInfo.gcMarkRegPtrVal(toReg, type);
- }
- }
- }
- else
- {
- gcInfo.gcMarkRegPtrVal(tree->gtRegNum, tree->TypeGet());
- }
- }
- }
- tree->SetInReg();
-}
-
-// transfer gc/byref status of src reg to dst reg
-void CodeGen::genTransferRegGCState(regNumber dst, regNumber src)
-{
- regMaskTP srcMask = genRegMask(src);
- regMaskTP dstMask = genRegMask(dst);
-
- if (gcInfo.gcRegGCrefSetCur & srcMask)
- {
- gcInfo.gcMarkRegSetGCref(dstMask);
- }
- else if (gcInfo.gcRegByrefSetCur & srcMask)
- {
- gcInfo.gcMarkRegSetByref(dstMask);
- }
- else
- {
- gcInfo.gcMarkRegSetNpt(dstMask);
- }
-}
-
-// generates an ip-relative call or indirect call via reg ('call reg')
-// 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)
-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)
-{
-#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,
- emitter::emitNoGChelper(compiler->eeGetHelperNum(methHnd)));
-}
-
-// 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)
-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)
-{
-#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());
-}
-
//------------------------------------------------------------------------
// genStoreInd: Generate code for a GT_STOREIND node.
//
@@ -5724,16 +4525,10 @@ void CodeGen::genStoreInd(GenTreePtr node)
noway_assert(data->gtRegNum != REG_ARG_0);
// addr goes in REG_ARG_0
- if (addr->gtRegNum != REG_ARG_0)
- {
- inst_RV_RV(INS_mov, REG_ARG_0, addr->gtRegNum, addr->TypeGet());
- }
+ genCopyRegIfNeeded(addr, REG_ARG_0);
// data goes in REG_ARG_1
- if (data->gtRegNum != REG_ARG_1)
- {
- inst_RV_RV(INS_mov, REG_ARG_1, data->gtRegNum, data->TypeGet());
- }
+ genCopyRegIfNeeded(data, REG_ARG_1);
genGCWriteBarrier(storeInd, writeBarrierForm);
}
@@ -5821,6 +4616,23 @@ void CodeGen::genStoreInd(GenTreePtr node)
assert(rmwSrc == data->gtGetOp2());
genCodeForShiftRMW(storeInd);
}
+ else if (!compiler->opts.compDbgCode && data->OperGet() == GT_ADD &&
+ (rmwSrc->IsIntegralConst(1) || rmwSrc->IsIntegralConst(-1)))
+ {
+ // Generate "inc/dec [mem]" instead of "add/sub [mem], 1".
+ //
+ // Notes:
+ // 1) Global morph transforms GT_SUB(x, +/-1) into GT_ADD(x, -/+1).
+ // 2) TODO-AMD64: Debugger routine NativeWalker::Decode() runs into
+ // an assert while decoding ModR/M byte of "inc dword ptr [rax]".
+ // It is not clear whether Decode() can handle all possible
+ // addr modes with inc/dec. For this reason, inc/dec [mem]
+ // is not generated while generating debuggable code. Update
+ // the above if condition once Decode() routine is fixed.
+ assert(rmwSrc->isContainedIntOrIImmed());
+ instruction ins = rmwSrc->IsIntegralConst(1) ? INS_inc : INS_dec;
+ getEmitter()->emitInsRMW(ins, emitTypeSize(storeInd), storeInd);
+ }
else
{
// generate code for remaining binary RMW memory ops like add/sub/and/or/xor
@@ -5905,10 +4717,7 @@ bool CodeGen::genEmitOptimizedGCWriteBarrier(GCInfo::WriteBarrierForm writeBarri
// call write_barrier_helper_reg
// addr goes in REG_ARG_0
- if (addr->gtRegNum != REG_WRITE_BARRIER) // REVIEW: can it ever not already by in this register?
- {
- inst_RV_RV(INS_mov, REG_WRITE_BARRIER, addr->gtRegNum, addr->TypeGet());
- }
+ genCopyRegIfNeeded(addr, REG_WRITE_BARRIER);
unsigned tgtAnywhere = 0;
if (writeBarrierForm != GCInfo::WBF_BarrierUnchecked)
@@ -5943,10 +4752,28 @@ void CodeGen::genCallInstruction(GenTreePtr node)
// all virtuals should have been expanded into a control expression
assert(!call->IsVirtual() || call->gtControlExpr || call->gtCallAddr);
+ // Insert a GS check if necessary
+ if (call->IsTailCallViaHelper())
+ {
+ if (compiler->getNeedsGSSecurityCookie())
+ {
+#if FEATURE_FIXED_OUT_ARGS
+ // If either of the conditions below is true, we will need a temporary register in order to perform the GS
+ // cookie check. When FEATURE_FIXED_OUT_ARGS is disabled, we save and restore the temporary register using
+ // push/pop. When FEATURE_FIXED_OUT_ARGS is enabled, however, we need an alternative solution. For now,
+ // though, the tail prefix is ignored on all platforms that use fixed out args, so we should never hit this
+ // case.
+ assert(compiler->gsGlobalSecurityCookieAddr == nullptr);
+ assert((int)compiler->gsGlobalSecurityCookieVal == (ssize_t)compiler->gsGlobalSecurityCookieVal);
+#endif
+ genEmitGSCookieCheck(true);
+ }
+ }
+
// Consume all the arg regs
for (GenTreePtr list = call->gtCallLateArgs; list; list = list->MoveNext())
{
- assert(list->IsList());
+ assert(list->OperIsList());
GenTreePtr argNode = list->Current();
@@ -5960,13 +4787,13 @@ void CodeGen::genCallInstruction(GenTreePtr node)
#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
// Deal with multi register passed struct args.
- if (argNode->OperGet() == GT_LIST)
+ if (argNode->OperGet() == GT_FIELD_LIST)
{
- GenTreeArgList* argListPtr = argNode->AsArgList();
- unsigned iterationNum = 0;
- for (; argListPtr != nullptr; argListPtr = argListPtr->Rest(), iterationNum++)
+ GenTreeFieldList* fieldListPtr = argNode->AsFieldList();
+ unsigned iterationNum = 0;
+ for (; fieldListPtr != nullptr; fieldListPtr = fieldListPtr->Rest(), iterationNum++)
{
- GenTreePtr putArgRegNode = argListPtr->gtOp.gtOp1;
+ GenTreePtr putArgRegNode = fieldListPtr->gtOp.gtOp1;
assert(putArgRegNode->gtOper == GT_PUTARG_REG);
regNumber argReg = REG_NA;
@@ -6036,20 +4863,34 @@ void CodeGen::genCallInstruction(GenTreePtr node)
{
assert((arg->gtGetOp1()->OperGet() == GT_PUTARG_STK) && (arg->gtGetOp2()->OperGet() == GT_PUTARG_STK));
}
+ if ((arg->OperGet() == GT_PUTARG_STK) && (arg->gtGetOp1()->OperGet() == GT_FIELD_LIST))
+ {
+ fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(call, arg);
+ assert(curArgTabEntry);
+ stackArgBytes += curArgTabEntry->numSlots * TARGET_POINTER_SIZE;
+ }
+ else
#endif // defined(_TARGET_X86_)
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
- if (genActualType(arg->TypeGet()) == TYP_STRUCT)
+#ifdef FEATURE_PUT_STRUCT_ARG_STK
+ if (genActualType(arg->TypeGet()) == TYP_STRUCT)
{
assert(arg->OperGet() == GT_PUTARG_STK);
- GenTreeObj* obj = arg->gtGetOp1()->AsObj();
- stackArgBytes = compiler->info.compCompHnd->getClassSize(obj->gtClass);
+ GenTreeObj* obj = arg->gtGetOp1()->AsObj();
+ unsigned argBytes = (unsigned)roundUp(obj->gtBlkSize, TARGET_POINTER_SIZE);
+#ifdef DEBUG
+ fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(call, arg);
+ assert((curArgTabEntry->numSlots * TARGET_POINTER_SIZE) == argBytes);
+#endif // DEBUG
+ stackArgBytes += argBytes;
}
else
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+ {
+#endif // FEATURE_PUT_STRUCT_ARG_STK
stackArgBytes += genTypeSize(genActualType(arg->TypeGet()));
+ }
}
args = args->gtOp.gtOp2;
}
@@ -6098,10 +4939,7 @@ void CodeGen::genCallInstruction(GenTreePtr node)
assert(target != nullptr);
genConsumeReg(target);
- if (target->gtRegNum != REG_RAX)
- {
- inst_RV_RV(INS_mov, REG_RAX, target->gtRegNum);
- }
+ genCopyRegIfNeeded(target, REG_RAX);
return;
}
@@ -6141,7 +4979,6 @@ void CodeGen::genCallInstruction(GenTreePtr node)
bool fPossibleSyncHelperCall = false;
CorInfoHelpFunc helperNum = CORINFO_HELP_UNDEF;
-#ifdef DEBUGGING_SUPPORT
// 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,
@@ -6150,7 +4987,6 @@ void CodeGen::genCallInstruction(GenTreePtr node)
{
(void)compiler->genCallSite2ILOffsetMap->Lookup(call, &ilOffset);
}
-#endif // DEBUGGING_SUPPORT
#if defined(_TARGET_X86_)
// If the callee pops the arguments, we pass a positive value as the argSize, and the emitter will
@@ -6167,7 +5003,38 @@ void CodeGen::genCallInstruction(GenTreePtr node)
if (target != nullptr)
{
- if (target->isContainedIndir())
+#ifdef _TARGET_X86_
+ if (call->IsVirtualStub() && (call->gtCallType == CT_INDIRECT))
+ {
+ // On x86, we need to generate a very specific pattern for indirect VSD calls:
+ //
+ // 3-byte nop
+ // call dword ptr [eax]
+ //
+ // Where EAX is also used as an argument to the stub dispatch helper. Make
+ // sure that the call target address is computed into EAX in this case.
+
+ assert(REG_VIRTUAL_STUB_PARAM == REG_VIRTUAL_STUB_TARGET);
+
+ assert(target->isContainedIndir());
+ assert(target->OperGet() == GT_IND);
+
+ GenTree* addr = target->AsIndir()->Addr();
+ assert(!addr->isContained());
+
+ genConsumeReg(addr);
+ 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,
+ ilOffset, REG_VIRTUAL_STUB_TARGET, REG_NA, 1, 0);
+ }
+ else
+#endif
+ if (target->isContainedIndir())
{
if (target->AsIndir()->HasBase() && target->AsIndir()->Base()->isContainedIntOrIImmed())
{
@@ -6977,8 +5844,6 @@ void CodeGen::genCompareLong(GenTreePtr treeNode)
genConsumeOperands(tree);
- assert(targetReg != REG_NA);
-
GenTreePtr loOp1 = op1->gtGetOp1();
GenTreePtr hiOp1 = op1->gtGetOp2();
GenTreePtr loOp2 = op2->gtGetOp1();
@@ -6992,6 +5857,12 @@ void CodeGen::genCompareLong(GenTreePtr treeNode)
// Emit the compare instruction
getEmitter()->emitInsBinary(ins, cmpAttr, hiOp1, hiOp2);
+ // If the result is not being materialized in a register, we're done.
+ if (targetReg == REG_NA)
+ {
+ return;
+ }
+
// Generate the first jump for the high compare
CompareKind compareKind = ((tree->gtFlags & GTF_UNSIGNED) != 0) ? CK_UNSIGNED : CK_SIGNED;
@@ -7015,10 +5886,6 @@ void CodeGen::genCompareLong(GenTreePtr treeNode)
emitJumpKind jumpKindLo = genJumpKindForOper(tree->gtOper, CK_UNSIGNED);
inst_SET(jumpKindLo, targetReg);
- // Set the higher bytes to 0
- inst_RV_RV(ins_Move_Extend(TYP_UBYTE, true), targetReg, targetReg, TYP_UBYTE, emitTypeSize(TYP_UBYTE));
- genProduceReg(tree);
-
inst_JMP(EJ_jmp, labelFinal);
// Define the label for hi jump target here. If we have jumped here, we want to set
@@ -7027,11 +5894,10 @@ void CodeGen::genCompareLong(GenTreePtr treeNode)
genDefineTempLabel(labelHi);
inst_SET(genJumpKindForOper(tree->gtOper, compareKind), targetReg);
+ genDefineTempLabel(labelFinal);
// Set the higher bytes to 0
inst_RV_RV(ins_Move_Extend(TYP_UBYTE, true), targetReg, targetReg, TYP_UBYTE, emitTypeSize(TYP_UBYTE));
genProduceReg(tree);
-
- genDefineTempLabel(labelFinal);
}
else
{
@@ -7062,152 +5928,6 @@ void CodeGen::genCompareLong(GenTreePtr treeNode)
genProduceReg(tree);
}
}
-
-//------------------------------------------------------------------------
-// genJTrueLong: Generate code for comparing two longs on x86 for the case where the result
-// is not 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.
-// We only have to do the low compare if the high parts of the operands are equal.
-//
-// In the case where the result of a rel-op is not realized in a register, we generate:
-//
-// Opcode x86 equivalent Comment
-// ------ -------------- -------
-//
-// GT_LT; unsigned cmp hiOp1,hiOp2
-// jb trueLabel
-// ja falseLabel
-// cmp loOp1,loOp2
-// jb trueLabel
-// falseLabel:
-//
-// GT_LE; unsigned cmp hiOp1,hiOp2
-// jb trueLabel
-// ja falseLabel
-// cmp loOp1,loOp2
-// jbe trueLabel
-// falseLabel:
-//
-// GT_GT; unsigned cmp hiOp1,hiOp2
-// ja trueLabel
-// jb falseLabel
-// cmp loOp1,loOp2
-// ja trueLabel
-// falseLabel:
-//
-// GT_GE; unsigned cmp hiOp1,hiOp2
-// ja trueLabel
-// jb falseLabel
-// cmp loOp1,loOp2
-// jae trueLabel
-// falseLabel:
-//
-// GT_LT; signed cmp hiOp1,hiOp2
-// jl trueLabel
-// jg falseLabel
-// cmp loOp1,loOp2
-// jb trueLabel
-// falseLabel:
-//
-// GT_LE; signed cmp hiOp1,hiOp2
-// jl trueLabel
-// jg falseLabel
-// cmp loOp1,loOp2
-// jbe trueLabel
-// falseLabel:
-//
-// GT_GT; signed cmp hiOp1,hiOp2
-// jg trueLabel
-// jl falseLabel
-// cmp loOp1,loOp2
-// ja trueLabel
-// falseLabel:
-//
-// GT_GE; signed cmp hiOp1,hiOp2
-// jg trueLabel
-// jl falseLabel
-// cmp loOp1,loOp2
-// jae trueLabel
-// falseLabel:
-//
-// GT_EQ; cmp hiOp1,hiOp2
-// jne falseLabel
-// cmp loOp1,loOp2
-// je trueLabel
-// falseLabel:
-//
-// GT_NE; cmp hiOp1,hiOp2
-// jne labelTrue
-// cmp loOp1,loOp2
-// jne trueLabel
-// falseLabel:
-//
-// TODO-X86-CQ: Check if hi or lo parts of op2 are 0 and change the compare to a test.
-void CodeGen::genJTrueLong(GenTreePtr treeNode)
-{
- assert(treeNode->OperIsCompare());
-
- GenTreeOp* tree = treeNode->AsOp();
- GenTreePtr op1 = tree->gtOp1;
- GenTreePtr op2 = tree->gtOp2;
-
- assert(varTypeIsLong(op1->TypeGet()));
- assert(varTypeIsLong(op2->TypeGet()));
-
- regNumber targetReg = treeNode->gtRegNum;
-
- assert(targetReg == REG_NA);
-
- GenTreePtr loOp1 = op1->gtGetOp1();
- GenTreePtr hiOp1 = op1->gtGetOp2();
- GenTreePtr loOp2 = op2->gtGetOp1();
- GenTreePtr hiOp2 = op2->gtGetOp2();
-
- // Emit the compare instruction
- getEmitter()->emitInsBinary(INS_cmp, EA_4BYTE, hiOp1, hiOp2);
-
- // Generate the first jump for the high compare
- CompareKind compareKind = ((tree->gtFlags & GTF_UNSIGNED) != 0) ? CK_UNSIGNED : CK_SIGNED;
-
- // TODO-X86-CQ: If the next block is a BBJ_ALWAYS, we can set falseLabel = compiler->compCurBB->bbNext->bbJumpDest.
- BasicBlock* falseLabel = genCreateTempLabel();
-
- emitJumpKind jumpKindHi[2];
-
- // Generate the jumps for the high compare
- genJumpKindsForTreeLongHi(tree, jumpKindHi);
-
- BasicBlock* trueLabel = compiler->compCurBB->bbJumpDest;
-
- if (jumpKindHi[0] != EJ_NONE)
- {
- inst_JMP(jumpKindHi[0], trueLabel);
- }
-
- if (jumpKindHi[1] != EJ_NONE)
- {
- inst_JMP(jumpKindHi[1], falseLabel);
- }
-
- // The low jump must be unsigned
- emitJumpKind jumpKindLo = genJumpKindForOper(tree->gtOper, CK_UNSIGNED);
-
- // Emit the comparison and the jump to the trueLabel
- getEmitter()->emitInsBinary(INS_cmp, EA_4BYTE, loOp1, loOp2);
-
- inst_JMP(jumpKindLo, trueLabel);
-
- // Generate falseLabel, which is the false path. We will jump here if the high compare is false
- // or fall through if the low compare is false.
- genDefineTempLabel(falseLabel);
-}
#endif //! defined(_TARGET_64BIT_)
//------------------------------------------------------------------------
@@ -7339,19 +6059,77 @@ void CodeGen::genCompareInt(GenTreePtr treeNode)
{
assert(treeNode->OperIsCompare());
- GenTreeOp* tree = treeNode->AsOp();
- GenTreePtr op1 = tree->gtOp1;
- GenTreePtr op2 = tree->gtOp2;
- var_types op1Type = op1->TypeGet();
- var_types op2Type = op2->TypeGet();
+ GenTreeOp* tree = treeNode->AsOp();
+ GenTreePtr op1 = tree->gtOp1;
+ GenTreePtr op2 = tree->gtOp2;
+ var_types op1Type = op1->TypeGet();
+ var_types op2Type = op2->TypeGet();
+ regNumber targetReg = treeNode->gtRegNum;
+
+ // Case of op1 == 0 or op1 != 0:
+ // Optimize generation of 'test' instruction if op1 sets flags.
+ //
+ // Note that if LSRA has inserted any GT_RELOAD/GT_COPY before
+ // op1, it will not modify the flags set by codegen of op1.
+ // Similarly op1 could also be reg-optional at its use and
+ // it was spilled after producing its result in a register.
+ // Spill code too will not modify the flags set by op1.
+ GenTree* realOp1 = op1->gtSkipReloadOrCopy();
+ if (realOp1->gtSetFlags())
+ {
+ // op1 must set ZF and SF flags
+ assert(realOp1->gtSetZSFlags());
+
+ // Must be (in)equality against zero.
+ assert(tree->OperGet() == GT_EQ || tree->OperGet() == GT_NE);
+ assert(op2->IsIntegralConst(0));
+ assert(op2->isContained());
+
+ // Just consume the operands
+ genConsumeOperands(tree);
+
+ // No need to generate test instruction since
+ // op1 sets flags
+
+ // Are we evaluating this into a register?
+ if (targetReg != REG_NA)
+ {
+ genSetRegToCond(targetReg, tree);
+ genProduceReg(tree);
+ }
+
+ return;
+ }
+
+#ifdef FEATURE_SIMD
+ // If we have GT_JTRUE(GT_EQ/NE(GT_SIMD((in)Equality, v1, v2), true/false)),
+ // then we don't need to generate code for GT_EQ/GT_NE, since SIMD (in)Equality intrinsic
+ // would set or clear Zero flag.
+ if ((targetReg == REG_NA) && (tree->OperGet() == GT_EQ || tree->OperGet() == GT_NE))
+ {
+ // Is it a SIMD (in)Equality that doesn't need to materialize result into a register?
+ if ((op1->gtRegNum == REG_NA) && op1->IsSIMDEqualityOrInequality())
+ {
+ // Must be comparing against true or false.
+ assert(op2->IsIntegralConst(0) || op2->IsIntegralConst(1));
+ assert(op2->isContainedIntOrIImmed());
+
+ // In this case SIMD (in)Equality will set or clear
+ // Zero flag, based on which GT_JTRUE would generate
+ // the right conditional jump.
+ return;
+ }
+ }
+#endif // FEATURE_SIMD
genConsumeOperands(tree);
instruction ins;
emitAttr cmpAttr;
- regNumber targetReg = treeNode->gtRegNum;
- assert(!op1->isContainedIntOrIImmed()); // We no longer support swapping op1 and op2 to generate cmp reg, imm
+ // TODO-CQ: We should be able to support swapping op1 and op2 to generate cmp reg, imm.
+ // https://github.com/dotnet/coreclr/issues/7270
+ assert(!op1->isContainedIntOrIImmed()); // We no longer support
assert(!varTypeIsFloating(op2Type));
#ifdef _TARGET_X86_
@@ -7387,7 +6165,7 @@ void CodeGen::genCompareInt(GenTreePtr treeNode)
{
// Do we have a short compare against a constant in op2?
//
- // We checked for this case in LowerCmp() and if we can perform a small
+ // We checked for this case in TreeNodeInfoInitCmp() and if we can perform a small
// compare immediate we labeled this compare with a GTF_RELOP_SMALL
// and for unsigned small non-equality compares the GTF_UNSIGNED flag.
//
@@ -7442,12 +6220,11 @@ void CodeGen::genCompareInt(GenTreePtr treeNode)
if (op1->isContained())
{
// op1 can be a contained memory op
- // or the special contained GT_AND that we created in Lowering::LowerCmp()
+ // or the special contained GT_AND that we created in Lowering::TreeNodeInfoInitCmp()
//
- if ((op1->OperGet() == GT_AND))
+ if ((op1->OperGet() == GT_AND) && op1->gtGetOp2()->isContainedIntOrIImmed() &&
+ ((tree->OperGet() == GT_EQ) || (tree->OperGet() == GT_NE)))
{
- noway_assert(op1->gtOp.gtOp2->isContainedIntOrIImmed());
-
ins = INS_test; // we will generate "test andOp1, andOp2CnsVal"
op2 = op1->gtOp.gtOp2; // must assign op2 before we overwrite op1
op1 = op1->gtOp.gtOp1; // overwrite op1
@@ -7561,6 +6338,93 @@ void CodeGen::genSetRegToCond(regNumber dstReg, GenTreePtr tree)
}
}
+#if !defined(_TARGET_64BIT_)
+//------------------------------------------------------------------------
+// genIntToIntCast: Generate code for long to int casts on x86.
+//
+// Arguments:
+// cast - The GT_CAST node
+//
+// Return Value:
+// None.
+//
+// Assumptions:
+// 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::genLongToIntCast(GenTree* cast)
+{
+ assert(cast->OperGet() == GT_CAST);
+
+ GenTree* src = cast->gtGetOp1();
+ noway_assert(src->OperGet() == GT_LONG);
+
+ genConsumeRegs(src);
+
+ 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;
+
+ assert((dstType == TYP_INT) || (dstType == TYP_UINT));
+ assert(genIsValidIntReg(loSrcReg));
+ assert(genIsValidIntReg(hiSrcReg));
+ assert(genIsValidIntReg(dstReg));
+
+ if (cast->gtOverflow())
+ {
+ //
+ // 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))
+ {
+ BasicBlock* allOne = genCreateTempLabel();
+ BasicBlock* success = genCreateTempLabel();
+
+ inst_RV_RV(INS_test, loSrcReg, loSrcReg, TYP_INT, EA_4BYTE);
+ inst_JMP(EJ_js, allOne);
+
+ inst_RV_RV(INS_test, hiSrcReg, hiSrcReg, TYP_INT, EA_4BYTE);
+ genJumpToThrowHlpBlk(EJ_jne, SCK_OVERFLOW);
+ inst_JMP(EJ_jmp, success);
+
+ genDefineTempLabel(allOne);
+ inst_RV_IV(INS_cmp, hiSrcReg, -1, EA_4BYTE);
+ genJumpToThrowHlpBlk(EJ_jne, SCK_OVERFLOW);
+
+ genDefineTempLabel(success);
+ }
+ else
+ {
+ if ((srcType == TYP_ULONG) && (dstType == TYP_INT))
+ {
+ inst_RV_RV(INS_test, loSrcReg, loSrcReg, TYP_INT, EA_4BYTE);
+ genJumpToThrowHlpBlk(EJ_js, SCK_OVERFLOW);
+ }
+
+ inst_RV_RV(INS_test, hiSrcReg, hiSrcReg, TYP_INT, EA_4BYTE);
+ genJumpToThrowHlpBlk(EJ_jne, SCK_OVERFLOW);
+ }
+ }
+
+ if (dstReg != loSrcReg)
+ {
+ inst_RV_RV(INS_mov, dstReg, loSrcReg, TYP_INT, EA_4BYTE);
+ }
+
+ genProduceReg(cast);
+}
+#endif
+
//------------------------------------------------------------------------
// genIntToIntCast: Generate code for an integer cast
// This method handles integer overflow checking casts
@@ -7584,13 +6448,22 @@ void CodeGen::genIntToIntCast(GenTreePtr treeNode)
{
assert(treeNode->OperGet() == GT_CAST);
- GenTreePtr castOp = treeNode->gtCast.CastOp();
- regNumber targetReg = treeNode->gtRegNum;
- regNumber sourceReg = castOp->gtRegNum;
- var_types dstType = treeNode->CastToType();
- bool isUnsignedDst = varTypeIsUnsigned(dstType);
- var_types srcType = genActualType(castOp->TypeGet());
- bool isUnsignedSrc = varTypeIsUnsigned(srcType);
+ GenTreePtr castOp = treeNode->gtCast.CastOp();
+ var_types srcType = genActualType(castOp->TypeGet());
+
+#if !defined(_TARGET_64BIT_)
+ if (varTypeIsLong(srcType))
+ {
+ genLongToIntCast(treeNode);
+ return;
+ }
+#endif // !defined(_TARGET_64BIT_)
+
+ regNumber targetReg = treeNode->gtRegNum;
+ regNumber sourceReg = castOp->gtRegNum;
+ var_types dstType = treeNode->CastToType();
+ bool isUnsignedDst = varTypeIsUnsigned(dstType);
+ bool isUnsignedSrc = varTypeIsUnsigned(srcType);
// if necessary, force the srcType to unsigned when the GT_UNSIGNED flag is set
if (!isUnsignedSrc && (treeNode->gtFlags & GTF_UNSIGNED) != 0)
@@ -7948,7 +6821,7 @@ void CodeGen::genFloatToFloatCast(GenTreePtr treeNode)
assert(varTypeIsFloating(srcType) && varTypeIsFloating(dstType));
genConsumeOperands(treeNode->AsOp());
- if (srcType == dstType && targetReg == op1->gtRegNum)
+ if (srcType == dstType && (!op1->isContained() && (targetReg == op1->gtRegNum)))
{
// source and destinations types are the same and also reside in the same register.
// we just need to consume and produce the reg in this case.
@@ -7999,7 +6872,8 @@ void CodeGen::genIntToFloatCast(GenTreePtr treeNode)
assert(!varTypeIsFloating(srcType) && varTypeIsFloating(dstType));
#if !defined(_TARGET_64BIT_)
- NYI_IF(varTypeIsLong(srcType), "Conversion from long to float");
+ // We expect morph to replace long to float/double casts with helper calls
+ noway_assert(!varTypeIsLong(srcType));
#endif // !defined(_TARGET_64BIT_)
// Since xarch emitter doesn't handle reporting gc-info correctly while casting away gc-ness we
@@ -8225,27 +7099,27 @@ void CodeGen::genCkfinite(GenTreePtr treeNode)
//
// For TYP_DOUBLE, we'll generate (for targetReg != op1->gtRegNum):
// movaps targetReg, op1->gtRegNum
- // shufps targetReg, targetReg, 0xB1 // WZYX => ZWXY
- // mov_xmm2i tmpReg, targetReg // tmpReg <= Y
+ // shufps targetReg, targetReg, 0xB1 // WZYX => ZWXY
+ // mov_xmm2i tmpReg, targetReg // tmpReg <= Y
// and tmpReg, <mask>
// cmp tmpReg, <mask>
// je <throw block>
// movaps targetReg, op1->gtRegNum // copy the value again, instead of un-shuffling it
//
// For TYP_DOUBLE with (targetReg == op1->gtRegNum):
- // shufps targetReg, targetReg, 0xB1 // WZYX => ZWXY
- // mov_xmm2i tmpReg, targetReg // tmpReg <= Y
+ // shufps targetReg, targetReg, 0xB1 // WZYX => ZWXY
+ // mov_xmm2i tmpReg, targetReg // tmpReg <= Y
// and tmpReg, <mask>
// cmp tmpReg, <mask>
// je <throw block>
- // shufps targetReg, targetReg, 0xB1 // ZWXY => WZYX
+ // shufps targetReg, targetReg, 0xB1 // ZWXY => WZYX
//
// For TYP_FLOAT, it's the same as _TARGET_64BIT_:
- // mov_xmm2i tmpReg, targetReg // tmpReg <= low 32 bits
+ // mov_xmm2i tmpReg, targetReg // tmpReg <= low 32 bits
// and tmpReg, <mask>
// cmp tmpReg, <mask>
// je <throw block>
- // movaps targetReg, op1->gtRegNum // only if targetReg != op1->gtRegNum
+ // movaps targetReg, op1->gtRegNum // only if targetReg != op1->gtRegNum
regNumber copyToTmpSrcReg; // The register we'll copy to the integer temp.
@@ -8613,7 +7487,7 @@ unsigned CodeGen::getBaseVarForPutArgStk(GenTreePtr treeNode)
#if FEATURE_FIXED_OUT_ARGS
baseVarNum = compiler->lvaOutgoingArgSpaceVar;
#else // !FEATURE_FIXED_OUT_ARGS
- NYI_X86("Stack args for x86/RyuJIT");
+ assert(!"No BaseVarForPutArgStk on x86");
baseVarNum = BAD_VAR_NUM;
#endif // !FEATURE_FIXED_OUT_ARGS
}
@@ -8621,8 +7495,74 @@ unsigned CodeGen::getBaseVarForPutArgStk(GenTreePtr treeNode)
return baseVarNum;
}
-//--------------------------------------------------------------------- //
-// genPutStructArgStk - generate code for passing an arg on the stack.
+#ifdef _TARGET_X86_
+//---------------------------------------------------------------------
+// adjustStackForPutArgStk:
+// adjust the stack pointer for a putArgStk node if necessary.
+//
+// Arguments:
+// putArgStk - the putArgStk node.
+//
+// Returns: true if the stack pointer was adjusted; false otherwise.
+//
+bool CodeGen::genAdjustStackForPutArgStk(GenTreePutArgStk* putArgStk)
+{
+#ifdef FEATURE_SIMD
+ if (varTypeIsSIMD(putArgStk))
+ {
+ const unsigned argSize = genTypeSize(putArgStk);
+ inst_RV_IV(INS_sub, REG_SPBASE, argSize, EA_PTRSIZE);
+ genStackLevel += argSize;
+ m_pushStkArg = false;
+ return true;
+ }
+#endif // FEATURE_SIMD
+
+ const unsigned argSize = putArgStk->getArgSize();
+
+ // If the gtPutArgStkKind is one of the push types, we do not pre-adjust the stack.
+ // This is set in Lowering, and is true if and only if:
+ // - This argument contains any GC pointers OR
+ // - It is a GT_FIELD_LIST OR
+ // - It is less than 16 bytes in size.
+ CLANG_FORMAT_COMMENT_ANCHOR;
+
+#ifdef DEBUG
+ switch (putArgStk->gtPutArgStkKind)
+ {
+ case GenTreePutArgStk::Kind::RepInstr:
+ case GenTreePutArgStk::Kind::Unroll:
+ assert((putArgStk->gtNumberReferenceSlots == 0) && (putArgStk->gtGetOp1()->OperGet() != GT_FIELD_LIST) &&
+ (argSize >= 16));
+ break;
+ case GenTreePutArgStk::Kind::Push:
+ case GenTreePutArgStk::Kind::PushAllSlots:
+ assert((putArgStk->gtNumberReferenceSlots != 0) || (putArgStk->gtGetOp1()->OperGet() == GT_FIELD_LIST) ||
+ (argSize < 16));
+ break;
+ case GenTreePutArgStk::Kind::Invalid:
+ default:
+ assert(!"Uninitialized GenTreePutArgStk::Kind");
+ break;
+ }
+#endif // DEBUG
+
+ if (putArgStk->isPushKind())
+ {
+ m_pushStkArg = true;
+ return false;
+ }
+ else
+ {
+ m_pushStkArg = false;
+ inst_RV_IV(INS_sub, REG_SPBASE, argSize, EA_PTRSIZE);
+ genStackLevel += argSize;
+ return true;
+ }
+}
+
+//---------------------------------------------------------------------
+// genPutArgStkFieldList - generate code for passing an arg on the stack.
//
// Arguments
// treeNode - the GT_PUTARG_STK node
@@ -8631,25 +7571,224 @@ unsigned CodeGen::getBaseVarForPutArgStk(GenTreePtr treeNode)
// Return value:
// None
//
-void CodeGen::genPutArgStk(GenTreePtr treeNode)
+void CodeGen::genPutArgStkFieldList(GenTreePutArgStk* putArgStk)
{
- var_types targetType = treeNode->TypeGet();
+ GenTreeFieldList* const fieldList = putArgStk->gtOp1->AsFieldList();
+ assert(fieldList != nullptr);
+
+ // Set m_pushStkArg and pre-adjust the stack if necessary.
+ const bool preAdjustedStack = genAdjustStackForPutArgStk(putArgStk);
+ // For now, we only support the "push" case; we will push a full slot for the first field of each slot
+ // within the struct.
+ assert((putArgStk->isPushKind()) && !preAdjustedStack && m_pushStkArg);
+
+ // If we have pre-adjusted the stack and are simply storing the fields in order) set the offset to 0.
+ // (Note that this mode is not currently being used.)
+ // If we are pushing the arguments (i.e. we have not pre-adjusted the stack), then we are pushing them
+ // in reverse order, so we start with the current field offset at the size of the struct arg (which must be
+ // a multiple of the target pointer size).
+ unsigned currentOffset = (preAdjustedStack) ? 0 : putArgStk->getArgSize();
+ unsigned prevFieldOffset = currentOffset;
+ regNumber tmpReg = REG_NA;
+ if (putArgStk->gtRsvdRegs != RBM_NONE)
+ {
+ assert(genCountBits(putArgStk->gtRsvdRegs) == 1);
+ tmpReg = genRegNumFromMask(putArgStk->gtRsvdRegs);
+ assert(genIsValidIntReg(tmpReg));
+ }
+ for (GenTreeFieldList* current = fieldList; current != nullptr; current = current->Rest())
+ {
+ GenTree* const fieldNode = current->Current();
+ const unsigned fieldOffset = current->gtFieldOffset;
+ var_types fieldType = current->gtFieldType;
+
+ // Long-typed nodes should have been handled by the decomposition pass, and lowering should have sorted the
+ // field list in descending order by offset.
+ assert(!varTypeIsLong(fieldType));
+ assert(fieldOffset <= prevFieldOffset);
+
+ // Consume the register, if any, for this field. Note that genConsumeRegs() will appropriately
+ // update the liveness info for a lclVar that has been marked RegOptional, which hasn't been
+ // assigned a register, and which is therefore contained.
+ // Unlike genConsumeReg(), it handles the case where no registers are being consumed.
+ genConsumeRegs(fieldNode);
+ regNumber argReg = fieldNode->isContainedSpillTemp() ? REG_NA : fieldNode->gtRegNum;
+
+ // If the field is slot-like, we can use a push instruction to store the entire register no matter the type.
+ //
+ // The GC encoder requires that the stack remain 4-byte aligned at all times. Round the adjustment up
+ // to the next multiple of 4. If we are going to generate a `push` instruction, the adjustment must
+ // not require rounding.
+ // NOTE: if the field is of GC type, we must use a push instruction, since the emitter is not otherwise
+ // able to detect stores into the outgoing argument area of the stack on x86.
+ const bool fieldIsSlot = ((fieldOffset % 4) == 0) && ((prevFieldOffset - fieldOffset) >= 4);
+ int adjustment = roundUp(currentOffset - fieldOffset, 4);
+ if (fieldIsSlot)
+ {
+ fieldType = genActualType(fieldType);
+ unsigned pushSize = genTypeSize(fieldType);
+ assert((pushSize % 4) == 0);
+ adjustment -= pushSize;
+ while (adjustment != 0)
+ {
+ inst_IV(INS_push, 0);
+ currentOffset -= pushSize;
+ genStackLevel += pushSize;
+ adjustment -= pushSize;
+ }
+ m_pushStkArg = true;
+ }
+ else
+ {
+ m_pushStkArg = false;
+ // We always "push" floating point fields (i.e. they are full slot values that don't
+ // require special handling).
+ assert(varTypeIsIntegralOrI(fieldNode));
+ // If we can't push this field, it needs to be in a register so that we can store
+ // it to the stack location.
+ assert(tmpReg != REG_NA);
+ if (adjustment != 0)
+ {
+ // This moves the stack pointer to fieldOffset.
+ // For this case, we must adjust the stack and generate stack-relative stores rather than pushes.
+ // Adjust the stack pointer to the next slot boundary.
+ inst_RV_IV(INS_sub, REG_SPBASE, adjustment, EA_PTRSIZE);
+ currentOffset -= adjustment;
+ genStackLevel += adjustment;
+ }
+
+ // Does it need to be in a byte register?
+ // If so, we'll use tmpReg, which must have been allocated as a byte register.
+ // If it's already in a register, but not a byteable one, then move it.
+ if (varTypeIsByte(fieldType) && ((argReg == REG_NA) || ((genRegMask(argReg) & RBM_BYTE_REGS) == 0)))
+ {
+ noway_assert((genRegMask(tmpReg) & RBM_BYTE_REGS) != 0);
+ if (argReg != REG_NA)
+ {
+ inst_RV_RV(INS_mov, tmpReg, argReg, fieldType);
+ argReg = tmpReg;
+ }
+ }
+ }
+
+ if (argReg == REG_NA)
+ {
+ if (m_pushStkArg)
+ {
+ if (fieldNode->isContainedSpillTemp())
+ {
+ assert(fieldNode->IsRegOptional());
+ TempDsc* tmp = getSpillTempDsc(fieldNode);
+ getEmitter()->emitIns_S(INS_push, emitActualTypeSize(fieldNode->TypeGet()), tmp->tdTempNum(), 0);
+ compiler->tmpRlsTemp(tmp);
+ }
+ else
+ {
+ assert(varTypeIsIntegralOrI(fieldNode));
+ switch (fieldNode->OperGet())
+ {
+ case GT_LCL_VAR:
+ inst_TT(INS_push, fieldNode, 0, 0, emitActualTypeSize(fieldNode->TypeGet()));
+ break;
+ case GT_CNS_INT:
+ if (fieldNode->IsIconHandle())
+ {
+ inst_IV_handle(INS_push, fieldNode->gtIntCon.gtIconVal);
+ }
+ else
+ {
+ inst_IV(INS_push, fieldNode->gtIntCon.gtIconVal);
+ }
+ break;
+ default:
+ unreached();
+ }
+ }
+ currentOffset -= TARGET_POINTER_SIZE;
+ genStackLevel += TARGET_POINTER_SIZE;
+ }
+ else
+ {
+ // The stack has been adjusted and we will load the field to tmpReg and then store it on the stack.
+ assert(varTypeIsIntegralOrI(fieldNode));
+ switch (fieldNode->OperGet())
+ {
+ case GT_LCL_VAR:
+ inst_RV_TT(INS_mov, tmpReg, fieldNode);
+ break;
+ case GT_CNS_INT:
+ genSetRegToConst(tmpReg, fieldNode->TypeGet(), fieldNode);
+ break;
+ default:
+ unreached();
+ }
+ genStoreRegToStackArg(fieldType, tmpReg, fieldOffset - currentOffset);
+ }
+ }
+ else
+ {
+ genStoreRegToStackArg(fieldType, argReg, fieldOffset - currentOffset);
+ if (m_pushStkArg)
+ {
+ // We always push a slot-rounded size
+ currentOffset -= genTypeSize(fieldType);
+ }
+ }
+
+ prevFieldOffset = fieldOffset;
+ }
+ if (currentOffset != 0)
+ {
+ // 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;
+ }
+}
+#endif // _TARGET_X86_
+
+//---------------------------------------------------------------------
+// genPutArgStk - generate code for passing an arg on the stack.
+//
+// Arguments
+// treeNode - the GT_PUTARG_STK node
+// targetType - the type of the treeNode
+//
+// Return value:
+// None
+//
+void CodeGen::genPutArgStk(GenTreePutArgStk* putArgStk)
+{
+ var_types targetType = putArgStk->TypeGet();
+
#ifdef _TARGET_X86_
- noway_assert(targetType != TYP_STRUCT);
+
+#ifdef FEATURE_SIMD
+ if (targetType == TYP_SIMD12)
+ {
+ genPutArgStkSIMD12(putArgStk);
+ return;
+ }
+#endif // FEATURE_SIMD
+
+ if (varTypeIsStruct(targetType))
+ {
+ (void)genAdjustStackForPutArgStk(putArgStk);
+ genPutStructArgStk(putArgStk);
+ return;
+ }
// The following logic is applicable for x86 arch.
- assert(!varTypeIsFloating(targetType) || (targetType == treeNode->gtGetOp1()->TypeGet()));
+ assert(!varTypeIsFloating(targetType) || (targetType == putArgStk->gtOp1->TypeGet()));
- GenTreePtr data = treeNode->gtOp.gtOp1;
+ GenTreePtr data = putArgStk->gtOp1;
// On a 32-bit target, all of the long arguments have been decomposed into
// a separate putarg_stk for each of the upper and lower halves.
noway_assert(targetType != TYP_LONG);
- int argSize = genTypeSize(genActualType(targetType));
- genStackLevel += argSize;
+ const unsigned argSize = putArgStk->getArgSize();
+ assert((argSize % TARGET_POINTER_SIZE) == 0);
- // TODO-Cleanup: Handle this in emitInsMov() in emitXArch.cpp?
if (data->isContainedIntOrIImmed())
{
if (data->IsIconHandle())
@@ -8660,53 +7799,50 @@ void CodeGen::genPutArgStk(GenTreePtr treeNode)
{
inst_IV(INS_push, data->gtIntCon.gtIconVal);
}
+ genStackLevel += argSize;
}
- else if (data->isContained())
+ else if (data->OperGet() == GT_FIELD_LIST)
{
- NYI_X86("Contained putarg_stk of non-constant");
+ genPutArgStkFieldList(putArgStk);
}
else
{
+ // We should not see any contained nodes that are not immediates.
+ assert(!data->isContained());
genConsumeReg(data);
- if (varTypeIsIntegralOrI(targetType))
- {
- inst_RV(INS_push, data->gtRegNum, targetType);
- }
- else
- {
- // Decrement SP.
- inst_RV_IV(INS_sub, REG_SPBASE, argSize, emitActualTypeSize(TYP_I_IMPL));
- getEmitter()->emitIns_AR_R(ins_Store(targetType), emitTypeSize(targetType), data->gtRegNum, REG_SPBASE, 0);
- }
+ genPushReg(targetType, data->gtRegNum);
}
#else // !_TARGET_X86_
{
- unsigned baseVarNum = getBaseVarForPutArgStk(treeNode);
+ unsigned baseVarNum = getBaseVarForPutArgStk(putArgStk);
#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
if (varTypeIsStruct(targetType))
{
- genPutStructArgStk(treeNode, baseVarNum);
+ m_stkArgVarNum = baseVarNum;
+ m_stkArgOffset = putArgStk->getArgOffset();
+ genPutStructArgStk(putArgStk);
+ m_stkArgVarNum = BAD_VAR_NUM;
return;
}
#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
noway_assert(targetType != TYP_STRUCT);
- assert(!varTypeIsFloating(targetType) || (targetType == treeNode->gtGetOp1()->TypeGet()));
+ assert(!varTypeIsFloating(targetType) || (targetType == putArgStk->gtOp1->TypeGet()));
// 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()->getArgOffset();
+ int argOffset = putArgStk->getArgOffset();
#ifdef DEBUG
- fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(treeNode->AsPutArgStk()->gtCall, treeNode);
+ fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(putArgStk->gtCall, putArgStk);
assert(curArgTabEntry);
assert(argOffset == (int)curArgTabEntry->slotNum * TARGET_POINTER_SIZE);
#endif
- GenTreePtr data = treeNode->gtGetOp1();
+ GenTreePtr data = putArgStk->gtOp1;
if (data->isContained())
{
@@ -8723,7 +7859,125 @@ void CodeGen::genPutArgStk(GenTreePtr treeNode)
#endif // !_TARGET_X86_
}
-#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
+#ifdef _TARGET_X86_
+// genPushReg: Push a register value onto the stack and adjust the stack level
+//
+// Arguments:
+// type - the type of value to be stored
+// reg - the register containing the value
+//
+// Notes:
+// For TYP_LONG, the srcReg must be a floating point register.
+// Otherwise, the register type must be consistent with the given type.
+//
+void CodeGen::genPushReg(var_types type, regNumber srcReg)
+{
+ unsigned size = genTypeSize(type);
+ if (varTypeIsIntegralOrI(type) && type != TYP_LONG)
+ {
+ assert(genIsValidIntReg(srcReg));
+ inst_RV(INS_push, srcReg, type);
+ }
+ else
+ {
+ instruction ins;
+ emitAttr attr = emitTypeSize(type);
+ if (type == TYP_LONG)
+ {
+ // On x86, the only way we can push a TYP_LONG from a register is if it is in an xmm reg.
+ // This is only used when we are pushing a struct from memory to memory, and basically is
+ // handling an 8-byte "chunk", as opposed to strictly a long type.
+ ins = INS_movq;
+ }
+ else
+ {
+ ins = ins_Store(type);
+ }
+ assert(genIsValidFloatReg(srcReg));
+ inst_RV_IV(INS_sub, REG_SPBASE, size, EA_PTRSIZE);
+ getEmitter()->emitIns_AR_R(ins, attr, srcReg, REG_SPBASE, 0);
+ }
+ genStackLevel += size;
+}
+#endif // _TARGET_X86_
+
+#if defined(FEATURE_PUT_STRUCT_ARG_STK)
+// genStoreRegToStackArg: Store a register value into the stack argument area
+//
+// Arguments:
+// type - the type of value to be stored
+// reg - the register containing the value
+// offset - the offset from the base (see Assumptions below)
+//
+// Notes:
+// A type of TYP_STRUCT instructs this method to store a 16-byte chunk
+// at the given offset (i.e. not the full struct).
+//
+// Assumptions:
+// The caller must set the context appropriately before calling this method:
+// - On x64, m_stkArgVarNum must be set according to whether this is a regular or tail call.
+// - On x86, the caller must set m_pushStkArg if this method should push the argument.
+// Otherwise, the argument is stored at the given offset from sp.
+//
+// TODO: In the below code the load and store instructions are for 16 bytes, but the
+// type is EA_8BYTE. The movdqa/u are 16 byte instructions, so it works, but
+// this probably needs to be changed.
+//
+void CodeGen::genStoreRegToStackArg(var_types type, regNumber srcReg, int offset)
+{
+ assert(srcReg != REG_NA);
+ instruction ins;
+ emitAttr attr;
+ unsigned size;
+
+ if (type == TYP_STRUCT)
+ {
+ ins = INS_movdqu;
+ // This should be changed!
+ attr = EA_8BYTE;
+ size = 16;
+ }
+ else
+ {
+#ifdef FEATURE_SIMD
+ if (varTypeIsSIMD(type))
+ {
+ assert(genIsValidFloatReg(srcReg));
+ ins = ins_Store(type); // TODO-CQ: pass 'aligned' correctly
+ }
+ else
+#endif // FEATURE_SIMD
+#ifdef _TARGET_X86_
+ if (type == TYP_LONG)
+ {
+ assert(genIsValidFloatReg(srcReg));
+ ins = INS_movq;
+ }
+ else
+#endif // _TARGET_X86_
+ {
+ assert((varTypeIsFloating(type) && genIsValidFloatReg(srcReg)) ||
+ (varTypeIsIntegralOrI(type) && genIsValidIntReg(srcReg)));
+ ins = ins_Store(type);
+ }
+ attr = emitTypeSize(type);
+ size = genTypeSize(type);
+ }
+
+#ifdef _TARGET_X86_
+ if (m_pushStkArg)
+ {
+ genPushReg(type, srcReg);
+ }
+ else
+ {
+ getEmitter()->emitIns_AR_R(ins, attr, srcReg, REG_SPBASE, offset);
+ }
+#else // !_TARGET_X86_
+ assert(m_stkArgVarNum != BAD_VAR_NUM);
+ getEmitter()->emitIns_S_R(ins, attr, srcReg, m_stkArgVarNum, m_stkArgOffset + offset);
+#endif // !_TARGET_X86_
+}
//---------------------------------------------------------------------
// genPutStructArgStk - generate code for copying a struct arg on the stack by value.
@@ -8731,42 +7985,39 @@ void CodeGen::genPutArgStk(GenTreePtr treeNode)
// it generates the gcinfo as well.
//
// Arguments
-// treeNode - the GT_PUTARG_STK node
-// baseVarNum - the variable number relative to which to put the argument on the stack.
-// For tail calls this is the baseVarNum = 0.
-// For non tail calls this is the outgoingArgSpace.
-//
-// Return value:
-// None
+// putArgStk - the GT_PUTARG_STK node
//
-void CodeGen::genPutStructArgStk(GenTreePtr treeNode, unsigned baseVarNum)
+// Notes:
+// In the case of fixed out args, the caller must have set m_stkArgVarNum to the variable number
+// corresponding to the argument area (where we will put the argument on the stack).
+// For tail calls this is the baseVarNum = 0.
+// For non tail calls this is the outgoingArgSpace.
+void CodeGen::genPutStructArgStk(GenTreePutArgStk* putArgStk)
{
- assert(treeNode->OperGet() == GT_PUTARG_STK);
- assert(baseVarNum != BAD_VAR_NUM);
-
- var_types targetType = treeNode->TypeGet();
+ var_types targetType = putArgStk->TypeGet();
if (varTypeIsSIMD(targetType))
{
- regNumber srcReg = genConsumeReg(treeNode->gtGetOp1());
+ regNumber srcReg = genConsumeReg(putArgStk->gtGetOp1());
assert((srcReg != REG_NA) && (genIsValidFloatReg(srcReg)));
- getEmitter()->emitIns_S_R(ins_Store(targetType), emitTypeSize(targetType), srcReg, baseVarNum,
- treeNode->AsPutArgStk()->getArgOffset());
+ genStoreRegToStackArg(targetType, srcReg, 0);
return;
}
assert(targetType == TYP_STRUCT);
- GenTreePutArgStk* putArgStk = treeNode->AsPutArgStk();
if (putArgStk->gtNumberReferenceSlots == 0)
{
switch (putArgStk->gtPutArgStkKind)
{
- case GenTreePutArgStk::PutArgStkKindRepInstr:
- genStructPutArgRepMovs(putArgStk, baseVarNum);
+ case GenTreePutArgStk::Kind::RepInstr:
+ genStructPutArgRepMovs(putArgStk);
break;
- case GenTreePutArgStk::PutArgStkKindUnroll:
- genStructPutArgUnroll(putArgStk, baseVarNum);
+ case GenTreePutArgStk::Kind::Unroll:
+ genStructPutArgUnroll(putArgStk);
+ break;
+ case GenTreePutArgStk::Kind::Push:
+ genStructPutArgUnroll(putArgStk);
break;
default:
unreached();
@@ -8775,108 +8026,150 @@ void CodeGen::genPutStructArgStk(GenTreePtr treeNode, unsigned baseVarNum)
else
{
// No need to disable GC the way COPYOBJ does. Here the refs are copied in atomic operations always.
+ CLANG_FORMAT_COMMENT_ANCHOR;
- // Consume these registers.
- // They may now contain gc pointers (depending on their type; gcMarkRegPtrVal will "do the right thing").
- genConsumePutStructArgStk(putArgStk, REG_RDI, REG_RSI, REG_NA, baseVarNum);
- GenTreePtr dstAddr = putArgStk;
- GenTreePtr src = putArgStk->gtOp.gtOp1;
- assert(src->OperGet() == GT_OBJ);
- GenTreePtr srcAddr = src->gtGetOp1();
+#ifdef _TARGET_X86_
+ // On x86, any struct that has contains GC references must be stored to the stack using `push` instructions so
+ // that the emitter properly detects the need to update the method's GC information.
+ //
+ // Strictly speaking, it is only necessary to use `push` to store the GC references themselves, so for structs
+ // with large numbers of consecutive non-GC-ref-typed fields, we may be able to improve the code size in the
+ // future.
+ assert(m_pushStkArg);
- unsigned slots = putArgStk->gtNumSlots;
+ GenTree* srcAddr = putArgStk->gtGetOp1()->gtGetOp1();
+ BYTE* gcPtrs = putArgStk->gtGcPtrs;
+ const unsigned numSlots = putArgStk->gtNumSlots;
- // We are always on the stack we don't need to use the write barrier.
- BYTE* gcPtrs = putArgStk->gtGcPtrs;
- unsigned gcPtrCount = putArgStk->gtNumberReferenceSlots;
+ regNumber srcRegNum = srcAddr->gtRegNum;
+ const bool srcAddrInReg = srcRegNum != REG_NA;
- unsigned i = 0;
- unsigned copiedSlots = 0;
- while (i < slots)
+ unsigned srcLclNum = 0;
+ unsigned srcLclOffset = 0;
+ if (srcAddrInReg)
{
- switch (gcPtrs[i])
+ genConsumeReg(srcAddr);
+ }
+ else
+ {
+ assert(srcAddr->OperIsLocalAddr());
+
+ srcLclNum = srcAddr->AsLclVarCommon()->gtLclNum;
+ if (srcAddr->OperGet() == GT_LCL_FLD_ADDR)
{
- case TYPE_GC_NONE:
- // Let's see if we can use rep movsq instead of a sequence of movsq instructions
- // to save cycles and code size.
- {
- unsigned nonGcSlotCount = 0;
+ srcLclOffset = srcAddr->AsLclFld()->gtLclOffs;
+ }
+ }
- do
- {
- nonGcSlotCount++;
- i++;
- } while (i < slots && gcPtrs[i] == TYPE_GC_NONE);
+ for (int i = numSlots - 1; i >= 0; --i)
+ {
+ emitAttr slotAttr;
+ if (gcPtrs[i] == TYPE_GC_NONE)
+ {
+ slotAttr = EA_4BYTE;
+ }
+ else if (gcPtrs[i] == TYPE_GC_REF)
+ {
+ slotAttr = EA_GCREF;
+ }
+ else
+ {
+ assert(gcPtrs[i] == TYPE_GC_BYREF);
+ slotAttr = EA_BYREF;
+ }
- // If we have a very small contiguous non-gc region, it's better just to
- // emit a sequence of movsq instructions
- if (nonGcSlotCount < CPOBJ_NONGC_SLOTS_LIMIT)
- {
- copiedSlots += nonGcSlotCount;
- while (nonGcSlotCount > 0)
- {
- instGen(INS_movsq);
- nonGcSlotCount--;
- }
- }
- else
- {
- getEmitter()->emitIns_R_I(INS_mov, EA_4BYTE, REG_RCX, nonGcSlotCount);
- copiedSlots += nonGcSlotCount;
- instGen(INS_r_movsq);
- }
- }
- break;
+ const unsigned offset = i * 4;
+ if (srcAddrInReg)
+ {
+ getEmitter()->emitIns_AR_R(INS_push, slotAttr, REG_NA, srcRegNum, offset);
+ }
+ else
+ {
+ getEmitter()->emitIns_S(INS_push, slotAttr, srcLclNum, srcLclOffset + offset);
+ }
+ genStackLevel += 4;
+ }
+#else // !defined(_TARGET_X86_)
+
+ // Consume these registers.
+ // They may now contain gc pointers (depending on their type; gcMarkRegPtrVal will "do the right thing").
+ genConsumePutStructArgStk(putArgStk, REG_RDI, REG_RSI, REG_NA);
+
+ const bool srcIsLocal = putArgStk->gtOp1->AsObj()->gtOp1->OperIsLocalAddr();
+ const emitAttr srcAddrAttr = srcIsLocal ? EA_PTRSIZE : EA_BYREF;
+
+#if DEBUG
+ unsigned numGCSlotsCopied = 0;
+#endif // DEBUG
+
+ BYTE* gcPtrs = putArgStk->gtGcPtrs;
+ const unsigned numSlots = putArgStk->gtNumSlots;
+ for (unsigned i = 0; i < numSlots;)
+ {
+ if (gcPtrs[i] == TYPE_GC_NONE)
+ {
+ // Let's see if we can use rep movsp (alias for movsd or movsq for 32 and 64 bits respectively)
+ // instead of a sequence of movsp instructions to save cycles and code size.
+ unsigned adjacentNonGCSlotCount = 0;
+ do
+ {
+ adjacentNonGCSlotCount++;
+ i++;
+ } while ((i < numSlots) && (gcPtrs[i] == TYPE_GC_NONE));
- case TYPE_GC_REF: // Is an object ref
- case TYPE_GC_BYREF: // Is an interior pointer - promote it but don't scan it
+ // If we have a very small contiguous non-ref region, it's better just to
+ // emit a sequence of movsp instructions
+ if (adjacentNonGCSlotCount < CPOBJ_NONGC_SLOTS_LIMIT)
{
- // We have a GC (byref or ref) pointer
- // TODO-Amd64-Unix: Here a better solution (for code size and CQ) would be to use movsq instruction,
- // but the logic for emitting a GC info record is not available (it is internal for the emitter
- // only.) See emitGCVarLiveUpd function. If we could call it separately, we could do
- // instGen(INS_movsq); and emission of gc info.
-
- var_types memType;
- if (gcPtrs[i] == TYPE_GC_REF)
- {
- memType = TYP_REF;
- }
- else
+ for (; adjacentNonGCSlotCount > 0; adjacentNonGCSlotCount--)
{
- assert(gcPtrs[i] == TYPE_GC_BYREF);
- memType = TYP_BYREF;
+ instGen(INS_movsp);
}
+ }
+ else
+ {
+ getEmitter()->emitIns_R_I(INS_mov, EA_4BYTE, REG_RCX, adjacentNonGCSlotCount);
+ instGen(INS_r_movsp);
+ }
+ }
+ else
+ {
+ assert((gcPtrs[i] == TYPE_GC_REF) || (gcPtrs[i] == TYPE_GC_BYREF));
+
+ // We have a GC (byref or ref) pointer
+ // TODO-Amd64-Unix: Here a better solution (for code size and CQ) would be to use movsp instruction,
+ // but the logic for emitting a GC info record is not available (it is internal for the emitter
+ // only.) See emitGCVarLiveUpd function. If we could call it separately, we could do
+ // instGen(INS_movsp); and emission of gc info.
- getEmitter()->emitIns_R_AR(ins_Load(memType), emitTypeSize(memType), REG_RCX, REG_RSI, 0);
- getEmitter()->emitIns_S_R(ins_Store(memType), emitTypeSize(memType), REG_RCX, baseVarNum,
- ((copiedSlots + putArgStk->gtSlotNum) * TARGET_POINTER_SIZE));
+ var_types memType = (gcPtrs[i] == TYPE_GC_REF) ? TYP_REF : TYP_BYREF;
+ getEmitter()->emitIns_R_AR(ins_Load(memType), emitTypeSize(memType), REG_RCX, REG_RSI, 0);
+ genStoreRegToStackArg(memType, REG_RCX, i * TARGET_POINTER_SIZE);
+
+#ifdef DEBUG
+ numGCSlotsCopied++;
+#endif // DEBUG
+ i++;
+ if (i < numSlots)
+ {
// Source for the copy operation.
// If a LocalAddr, use EA_PTRSIZE - copy from stack.
// If not a LocalAddr, use EA_BYREF - the source location is not on the stack.
- getEmitter()->emitIns_R_I(INS_add, ((src->OperIsLocalAddr()) ? EA_PTRSIZE : EA_BYREF), REG_RSI,
- TARGET_POINTER_SIZE);
+ getEmitter()->emitIns_R_I(INS_add, srcAddrAttr, REG_RSI, TARGET_POINTER_SIZE);
// Always copying to the stack - outgoing arg area
// (or the outgoing arg area of the caller for a tail call) - use EA_PTRSIZE.
getEmitter()->emitIns_R_I(INS_add, EA_PTRSIZE, REG_RDI, TARGET_POINTER_SIZE);
- copiedSlots++;
- gcPtrCount--;
- i++;
}
- break;
-
- default:
- unreached();
- break;
}
}
- assert(gcPtrCount == 0);
+ assert(numGCSlotsCopied == putArgStk->gtNumberReferenceSlots);
+#endif // _TARGET_X86_
}
}
-#endif // defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
+#endif // defined(FEATURE_PUT_STRUCT_ARG_STK)
/*****************************************************************************
*
@@ -9043,7 +8336,7 @@ void* CodeGen::genCreateAndStoreGCInfoJIT32(unsigned codeSize,
return infoPtr;
}
-#else // !JIT32_GCENCODER
+#else // !JIT32_GCENCODER
void CodeGen::genCreateAndStoreGCInfoX64(unsigned codeSize, unsigned prologSize DEBUGARG(void* codePtr))
{
IAllocator* allowZeroAlloc = new (compiler, CMK_GC) AllowZeroAllocator(compiler->getAllocatorGC());
@@ -9061,7 +8354,6 @@ void CodeGen::genCreateAndStoreGCInfoX64(unsigned codeSize, unsigned prologSize
// 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 defined(DEBUGGING_SUPPORT)
if (compiler->opts.compDbgEnC)
{
// what we have to preserve is called the "frame header" (see comments in VM\eetwain.cpp)
@@ -9088,7 +8380,6 @@ void CodeGen::genCreateAndStoreGCInfoX64(unsigned codeSize, unsigned prologSize
// frame
gcInfoEncoder->SetSizeOfEditAndContinuePreservedArea(preservedAreaSize);
}
-#endif
gcInfoEncoder->Build();
@@ -9203,18 +8494,33 @@ void CodeGen::genStoreLongLclVar(GenTree* treeNode)
assert(varDsc->TypeGet() == TYP_LONG);
assert(!varDsc->lvPromoted);
GenTreePtr op1 = treeNode->gtOp.gtOp1;
- noway_assert(op1->OperGet() == GT_LONG);
+ noway_assert(op1->OperGet() == GT_LONG || op1->OperGet() == GT_MUL_LONG);
genConsumeRegs(op1);
- // Definitions of register candidates will have been lowered to 2 int lclVars.
- assert(!treeNode->InReg());
+ 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);
- 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_R_S(ins_Store(TYP_INT), EA_4BYTE, loVal->gtRegNum, lclNum, 0);
- emit->emitIns_R_S(ins_Store(TYP_INT), EA_4BYTE, hiVal->gtRegNum, lclNum, genTypeSize(TYP_INT));
+ // 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 // !defined(_TARGET_64BIT_)
@@ -9332,57 +8638,6 @@ void CodeGen::genAmd64EmitterUnitTests()
#endif // defined(DEBUG) && defined(LATE_DISASM) && defined(_TARGET_AMD64_)
-/*****************************************************************************/
-#ifdef DEBUGGING_SUPPORT
-/*****************************************************************************
- * genSetScopeInfo
- *
- * Called for every scope info piece to record by the main genSetScopeInfo()
- */
-
-void CodeGen::genSetScopeInfo(unsigned which,
- UNATIVE_OFFSET startOffs,
- UNATIVE_OFFSET length,
- unsigned varNum,
- unsigned LVnum,
- bool avail,
- Compiler::siVarLoc& varLoc)
-{
- /* We need to do some mapping while reporting back these variables */
-
- unsigned ilVarNum = compiler->compMap2ILvarNum(varNum);
- noway_assert((int)ilVarNum != ICorDebugInfo::UNKNOWN_ILNUM);
-
- VarName name = nullptr;
-
-#ifdef DEBUG
-
- for (unsigned scopeNum = 0; scopeNum < compiler->info.compVarScopesCount; scopeNum++)
- {
- if (LVnum == compiler->info.compVarScopes[scopeNum].vsdLVnum)
- {
- name = compiler->info.compVarScopes[scopeNum].vsdName;
- }
- }
-
- // Hang on to this compiler->info.
-
- TrnslLocalVarInfo& tlvi = genTrnslLocalVarInfo[which];
-
- tlvi.tlviVarNum = ilVarNum;
- tlvi.tlviLVnum = LVnum;
- tlvi.tlviName = name;
- tlvi.tlviStartPC = startOffs;
- tlvi.tlviLength = length;
- tlvi.tlviAvailable = avail;
- tlvi.tlviVarLoc = varLoc;
-
-#endif // DEBUG
-
- compiler->eeSetLVinfo(which, startOffs, length, ilVarNum, LVnum, name, avail, varLoc);
-}
-#endif // DEBUGGING_SUPPORT
-
#endif // _TARGET_AMD64_
#endif // !LEGACY_BACKEND
diff --git a/.gitmirror b/src/jit/compatjit/.gitmirror
index f507630f94..f507630f94 100644
--- a/.gitmirror
+++ b/src/jit/compatjit/.gitmirror
diff --git a/src/jit/compatjit/CMakeLists.txt b/src/jit/compatjit/CMakeLists.txt
new file mode 100644
index 0000000000..1e0615e431
--- /dev/null
+++ b/src/jit/compatjit/CMakeLists.txt
@@ -0,0 +1,66 @@
+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 afbecdfc60..114847c0d0 100644
--- a/src/jit/compiler.cpp
+++ b/src/jit/compiler.cpp
@@ -48,6 +48,60 @@ bool Compiler::s_pAltJitExcludeAssembliesListInitialized = false;
AssemblyNamesList2* Compiler::s_pAltJitExcludeAssembliesList = nullptr;
#endif // ALT_JIT
+/*****************************************************************************
+ *
+ * Little helpers to grab the current cycle counter value; this is done
+ * differently based on target architecture, host toolchain, etc. The
+ * main thing is to keep the overhead absolutely minimal; in fact, on
+ * x86/x64 we use RDTSC even though it's not thread-safe; GetThreadCycles
+ * (which is monotonous) is just too expensive.
+ */
+#ifdef FEATURE_JIT_METHOD_PERF
+
+#if defined(_HOST_X86_) || defined(_HOST_AMD64_)
+
+#if defined(_MSC_VER)
+
+#include <intrin.h>
+inline bool _our_GetThreadCycles(unsigned __int64* cycleOut)
+{
+ *cycleOut = __rdtsc();
+ return true;
+}
+
+#elif defined(__clang__)
+
+inline bool _our_GetThreadCycles(unsigned __int64* cycleOut)
+{
+ uint64_t cycles;
+ asm volatile("rdtsc" : "=A"(cycles));
+ *cycleOut = cycles;
+ return true;
+}
+
+#else // neither _MSC_VER nor __clang__
+
+// The following *might* work - might as well try.
+#define _our_GetThreadCycles(cp) GetThreadCycles(cp)
+
+#endif
+
+#elif defined(_HOST_ARM_) || defined(_HOST_ARM64_)
+
+// If this doesn't work please see ../gc/gc.cpp for additional ARM
+// info (and possible solutions).
+#define _our_GetThreadCycles(cp) GetThreadCycles(cp)
+
+#else // not x86/x64 and not ARM
+
+// Don't know what this target is, but let's give it a try; if
+// someone really wants to make this work, please add the right
+// code here.
+#define _our_GetThreadCycles(cp) GetThreadCycles(cp)
+
+#endif // which host OS
+
+#endif // FEATURE_JIT_METHOD_PERF
/*****************************************************************************/
inline unsigned getCurTime()
{
@@ -147,8 +201,6 @@ void Compiler::compDspSrcLinesByLineNum(unsigned line, bool seek)
void Compiler::compDspSrcLinesByNativeIP(UNATIVE_OFFSET curIP)
{
-#ifdef DEBUGGING_SUPPORT
-
static IPmappingDsc* nextMappingDsc;
static unsigned lastLine;
@@ -203,8 +255,6 @@ void Compiler::compDspSrcLinesByNativeIP(UNATIVE_OFFSET curIP)
nextMappingDsc = nextMappingDsc->ipmdNext;
}
}
-
-#endif
}
/*****************************************************************************/
@@ -232,6 +282,15 @@ unsigned genTreeNsizHistBuckets[] = {1000, 5000, 10000, 50000, 100000, 500000,
Histogram genTreeNsizHist(HostAllocator::getHostAllocator(), genTreeNsizHistBuckets);
#endif // MEASURE_NODE_SIZE
+/*****************************************************************************/
+#if MEASURE_MEM_ALLOC
+
+unsigned memSizeHistBuckets[] = {20, 50, 75, 100, 150, 250, 500, 1000, 5000, 0};
+Histogram memAllocHist(HostAllocator::getHostAllocator(), memSizeHistBuckets);
+Histogram memUsedHist(HostAllocator::getHostAllocator(), memSizeHistBuckets);
+
+#endif // MEASURE_MEM_ALLOC
+
/*****************************************************************************
*
* Variables to keep track of total code amounts.
@@ -475,7 +534,7 @@ bool Compiler::isSingleFloat32Struct(CORINFO_CLASS_HANDLE clsHnd)
for (;;)
{
// all of class chain must be of value type and must have only one field
- if (!info.compCompHnd->isValueClass(clsHnd) && info.compCompHnd->getClassNumInstanceFields(clsHnd) != 1)
+ if (!info.compCompHnd->isValueClass(clsHnd) || info.compCompHnd->getClassNumInstanceFields(clsHnd) != 1)
{
return false;
}
@@ -1101,14 +1160,11 @@ size_t genFlowNodeCnt;
#ifdef DEBUG
/* static */
unsigned Compiler::s_compMethodsCount = 0; // to produce unique label names
-
-/* static */
-bool Compiler::s_dspMemStats = false;
#endif
-#ifndef DEBUGGING_SUPPORT
+#if MEASURE_MEM_ALLOC
/* static */
-const bool Compiler::Options::compDbgCode = false;
+bool Compiler::s_dspMemStats = false;
#endif
#ifndef PROFILING_SUPPORTED
@@ -1184,18 +1240,22 @@ void Compiler::compShutdown()
}
#endif
+#if NODEBASH_STATS
+ GenTree::ReportOperBashing(jitstdout);
+#endif
+
// Where should we write our statistics output?
FILE* fout = jitstdout;
#ifdef FEATURE_JIT_METHOD_PERF
- if (compJitTimeLogFilename != NULL)
+ if (compJitTimeLogFilename != nullptr)
{
- // I assume that this will return NULL if it fails for some reason, and
- // that...
FILE* jitTimeLogFile = _wfopen(compJitTimeLogFilename, W("a"));
- // ...Print will return silently with a NULL argument.
- CompTimeSummaryInfo::s_compTimeSummary.Print(jitTimeLogFile);
- fclose(jitTimeLogFile);
+ if (jitTimeLogFile != nullptr)
+ {
+ CompTimeSummaryInfo::s_compTimeSummary.Print(jitTimeLogFile);
+ fclose(jitTimeLogFile);
+ }
}
#endif // FEATURE_JIT_METHOD_PERF
@@ -1214,6 +1274,63 @@ void Compiler::compShutdown()
}
#endif // COUNT_RANGECHECKS
+#if COUNT_AST_OPERS
+
+ // Add up all the counts so that we can show percentages of total
+ unsigned gtc = 0;
+ for (unsigned op = 0; op < GT_COUNT; op++)
+ gtc += GenTree::s_gtNodeCounts[op];
+
+ if (gtc > 0)
+ {
+ unsigned rem_total = gtc;
+ unsigned rem_large = 0;
+ unsigned rem_small = 0;
+
+ unsigned tot_large = 0;
+ unsigned tot_small = 0;
+
+ fprintf(fout, "\nGenTree operator counts (approximate):\n\n");
+
+ for (unsigned op = 0; op < GT_COUNT; op++)
+ {
+ unsigned siz = GenTree::s_gtTrueSizes[op];
+ unsigned cnt = GenTree::s_gtNodeCounts[op];
+ double pct = 100.0 * cnt / gtc;
+
+ if (siz > TREE_NODE_SZ_SMALL)
+ tot_large += cnt;
+ else
+ tot_small += cnt;
+
+ // Let's not show anything below a threshold
+ if (pct >= 0.5)
+ {
+ fprintf(fout, " GT_%-17s %7u (%4.1lf%%) %3u bytes each\n", GenTree::OpName((genTreeOps)op), cnt,
+ pct, siz);
+ rem_total -= cnt;
+ }
+ else
+ {
+ if (siz > TREE_NODE_SZ_SMALL)
+ rem_large += cnt;
+ else
+ rem_small += cnt;
+ }
+ }
+ if (rem_total > 0)
+ {
+ fprintf(fout, " All other GT_xxx ... %7u (%4.1lf%%) ... %4.1lf%% small + %4.1lf%% large\n", rem_total,
+ 100.0 * rem_total / gtc, 100.0 * rem_small / gtc, 100.0 * rem_large / gtc);
+ }
+ fprintf(fout, " -----------------------------------------------------\n");
+ fprintf(fout, " Total ....... %11u --ALL-- ... %4.1lf%% small + %4.1lf%% large\n", gtc,
+ 100.0 * tot_small / gtc, 100.0 * tot_large / gtc);
+ fprintf(fout, "\n");
+ }
+
+#endif // COUNT_AST_OPERS
+
#if DISPLAY_SIZES
if (grossVMsize && grossNCsize)
@@ -1367,17 +1484,23 @@ void Compiler::compShutdown()
#if MEASURE_MEM_ALLOC
-#ifdef DEBUG
- // Under debug, we only dump memory stats when the COMPlus_* variable is defined.
- // Under non-debug, we don't have the COMPlus_* variable, and we always dump it.
if (s_dspMemStats)
-#endif
{
fprintf(fout, "\nAll allocations:\n");
s_aggMemStats.Print(jitstdout);
fprintf(fout, "\nLargest method:\n");
s_maxCompMemStats.Print(jitstdout);
+
+ fprintf(fout, "\n");
+ fprintf(fout, "---------------------------------------------------\n");
+ fprintf(fout, "Distribution of total memory allocated per method (in KB):\n");
+ memAllocHist.dump(fout);
+
+ fprintf(fout, "\n");
+ fprintf(fout, "---------------------------------------------------\n");
+ fprintf(fout, "Distribution of total memory used per method (in KB):\n");
+ memUsedHist.dump(fout);
}
#endif // MEASURE_MEM_ALLOC
@@ -1452,100 +1575,8 @@ void Compiler::compDisplayStaticSizes(FILE* fout)
{
#if MEASURE_NODE_SIZE
- /*
- IMPORTANT: Use the following code to check the alignment of
- GenTree members (in a retail build, of course).
- */
-
- GenTree* gtDummy = nullptr;
-
- fprintf(fout, "\n");
- fprintf(fout, "Offset / size of gtOper = %2u / %2u\n", offsetof(GenTree, gtOper), sizeof(gtDummy->gtOper));
- fprintf(fout, "Offset / size of gtType = %2u / %2u\n", offsetof(GenTree, gtType), sizeof(gtDummy->gtType));
-#if FEATURE_ANYCSE
- fprintf(fout, "Offset / size of gtCSEnum = %2u / %2u\n", offsetof(GenTree, gtCSEnum),
- sizeof(gtDummy->gtCSEnum));
-#endif // FEATURE_ANYCSE
-#if ASSERTION_PROP
- fprintf(fout, "Offset / size of gtAssertionNum = %2u / %2u\n", offsetof(GenTree, gtAssertionNum),
- sizeof(gtDummy->gtAssertionNum));
-#endif // ASSERTION_PROP
-#if FEATURE_STACK_FP_X87
- fprintf(fout, "Offset / size of gtFPlvl = %2u / %2u\n", offsetof(GenTree, gtFPlvl),
- sizeof(gtDummy->gtFPlvl));
-#endif // FEATURE_STACK_FP_X87
- // TODO: The section that report GenTree sizes should be made into a public static member function of the GenTree
- // class (see https://github.com/dotnet/coreclr/pull/493)
- // fprintf(fout, "Offset / size of gtCostEx = %2u / %2u\n", offsetof(GenTree, _gtCostEx ),
- // sizeof(gtDummy->_gtCostEx ));
- // fprintf(fout, "Offset / size of gtCostSz = %2u / %2u\n", offsetof(GenTree, _gtCostSz ),
- // sizeof(gtDummy->_gtCostSz ));
- fprintf(fout, "Offset / size of gtFlags = %2u / %2u\n", offsetof(GenTree, gtFlags),
- sizeof(gtDummy->gtFlags));
- fprintf(fout, "Offset / size of gtVNPair = %2u / %2u\n", offsetof(GenTree, gtVNPair),
- sizeof(gtDummy->gtVNPair));
- fprintf(fout, "Offset / size of gtRsvdRegs = %2u / %2u\n", offsetof(GenTree, gtRsvdRegs),
- sizeof(gtDummy->gtRsvdRegs));
-#ifdef LEGACY_BACKEND
- fprintf(fout, "Offset / size of gtUsedRegs = %2u / %2u\n", offsetof(GenTree, gtUsedRegs),
- sizeof(gtDummy->gtUsedRegs));
-#endif // LEGACY_BACKEND
-#ifndef LEGACY_BACKEND
- fprintf(fout, "Offset / size of gtLsraInfo = %2u / %2u\n", offsetof(GenTree, gtLsraInfo),
- sizeof(gtDummy->gtLsraInfo));
-#endif // !LEGACY_BACKEND
- fprintf(fout, "Offset / size of gtNext = %2u / %2u\n", offsetof(GenTree, gtNext), sizeof(gtDummy->gtNext));
- fprintf(fout, "Offset / size of gtPrev = %2u / %2u\n", offsetof(GenTree, gtPrev), sizeof(gtDummy->gtPrev));
- fprintf(fout, "\n");
-
-#if SMALL_TREE_NODES
- fprintf(fout, "Small tree node size = %3u\n", TREE_NODE_SZ_SMALL);
-#endif // SMALL_TREE_NODES
- fprintf(fout, "Large tree node size = %3u\n", TREE_NODE_SZ_LARGE);
- fprintf(fout, "Size of GenTree = %3u\n", sizeof(GenTree));
- fprintf(fout, "Size of GenTreeUnOp = %3u\n", sizeof(GenTreeUnOp));
- fprintf(fout, "Size of GenTreeOp = %3u\n", sizeof(GenTreeOp));
- fprintf(fout, "Size of GenTreeVal = %3u\n", sizeof(GenTreeVal));
- fprintf(fout, "Size of GenTreeIntConCommon = %3u\n", sizeof(GenTreeIntConCommon));
- fprintf(fout, "Size of GenTreePhysReg = %3u\n", sizeof(GenTreePhysReg));
-#ifndef LEGACY_BACKEND
- fprintf(fout, "Size of GenTreeJumpTable = %3u\n", sizeof(GenTreeJumpTable));
-#endif // !LEGACY_BACKEND
- fprintf(fout, "Size of GenTreeIntCon = %3u\n", sizeof(GenTreeIntCon));
- fprintf(fout, "Size of GenTreeLngCon = %3u\n", sizeof(GenTreeLngCon));
- fprintf(fout, "Size of GenTreeDblCon = %3u\n", sizeof(GenTreeDblCon));
- fprintf(fout, "Size of GenTreeStrCon = %3u\n", sizeof(GenTreeStrCon));
- fprintf(fout, "Size of GenTreeLclVarCommon = %3u\n", sizeof(GenTreeLclVarCommon));
- fprintf(fout, "Size of GenTreeLclVar = %3u\n", sizeof(GenTreeLclVar));
- fprintf(fout, "Size of GenTreeLclFld = %3u\n", sizeof(GenTreeLclFld));
- fprintf(fout, "Size of GenTreeRegVar = %3u\n", sizeof(GenTreeRegVar));
- fprintf(fout, "Size of GenTreeCast = %3u\n", sizeof(GenTreeCast));
- fprintf(fout, "Size of GenTreeBox = %3u\n", sizeof(GenTreeBox));
- fprintf(fout, "Size of GenTreeField = %3u\n", sizeof(GenTreeField));
- fprintf(fout, "Size of GenTreeArgList = %3u\n", sizeof(GenTreeArgList));
- fprintf(fout, "Size of GenTreeColon = %3u\n", sizeof(GenTreeColon));
- fprintf(fout, "Size of GenTreeCall = %3u\n", sizeof(GenTreeCall));
- fprintf(fout, "Size of GenTreeCmpXchg = %3u\n", sizeof(GenTreeCmpXchg));
- fprintf(fout, "Size of GenTreeFptrVal = %3u\n", sizeof(GenTreeFptrVal));
- fprintf(fout, "Size of GenTreeQmark = %3u\n", sizeof(GenTreeQmark));
- fprintf(fout, "Size of GenTreeIntrinsic = %3u\n", sizeof(GenTreeIntrinsic));
- fprintf(fout, "Size of GenTreeIndex = %3u\n", sizeof(GenTreeIndex));
- fprintf(fout, "Size of GenTreeArrLen = %3u\n", sizeof(GenTreeArrLen));
- fprintf(fout, "Size of GenTreeBoundsChk = %3u\n", sizeof(GenTreeBoundsChk));
- fprintf(fout, "Size of GenTreeArrElem = %3u\n", sizeof(GenTreeArrElem));
- fprintf(fout, "Size of GenTreeAddrMode = %3u\n", sizeof(GenTreeAddrMode));
- fprintf(fout, "Size of GenTreeIndir = %3u\n", sizeof(GenTreeIndir));
- fprintf(fout, "Size of GenTreeStoreInd = %3u\n", sizeof(GenTreeStoreInd));
- fprintf(fout, "Size of GenTreeRetExpr = %3u\n", sizeof(GenTreeRetExpr));
- fprintf(fout, "Size of GenTreeStmt = %3u\n", sizeof(GenTreeStmt));
- fprintf(fout, "Size of GenTreeObj = %3u\n", sizeof(GenTreeObj));
- fprintf(fout, "Size of GenTreeClsVar = %3u\n", sizeof(GenTreeClsVar));
- fprintf(fout, "Size of GenTreeArgPlace = %3u\n", sizeof(GenTreeArgPlace));
- fprintf(fout, "Size of GenTreeLabel = %3u\n", sizeof(GenTreeLabel));
- fprintf(fout, "Size of GenTreePhiArg = %3u\n", sizeof(GenTreePhiArg));
- fprintf(fout, "Size of GenTreePutArgStk = %3u\n", sizeof(GenTreePutArgStk));
- fprintf(fout, "\n");
-#endif // MEASURE_NODE_SIZE
+ GenTree::DumpNodeSizes(fout);
+#endif
#if MEASURE_BLOCK_SIZE
@@ -1572,8 +1603,6 @@ void Compiler::compDisplayStaticSizes(FILE* fout)
sizeof(bbDummy->bbJumpDest));
fprintf(fout, "Offset / size of bbJumpSwt = %3u / %3u\n", offsetof(BasicBlock, bbJumpSwt),
sizeof(bbDummy->bbJumpSwt));
- fprintf(fout, "Offset / size of bbTreeList = %3u / %3u\n", offsetof(BasicBlock, bbTreeList),
- sizeof(bbDummy->bbTreeList));
fprintf(fout, "Offset / size of bbEntryState = %3u / %3u\n", offsetof(BasicBlock, bbEntryState),
sizeof(bbDummy->bbEntryState));
fprintf(fout, "Offset / size of bbStkTempsIn = %3u / %3u\n", offsetof(BasicBlock, bbStkTempsIn),
@@ -1618,12 +1647,8 @@ void Compiler::compDisplayStaticSizes(FILE* fout)
sizeof(bbDummy->bbHeapSsaNumIn));
fprintf(fout, "Offset / size of bbHeapSsaNumOut = %3u / %3u\n", offsetof(BasicBlock, bbHeapSsaNumOut),
sizeof(bbDummy->bbHeapSsaNumOut));
-
-#ifdef DEBUGGING_SUPPORT
fprintf(fout, "Offset / size of bbScope = %3u / %3u\n", offsetof(BasicBlock, bbScope),
sizeof(bbDummy->bbScope));
-#endif // DEBUGGING_SUPPORT
-
fprintf(fout, "Offset / size of bbCseGen = %3u / %3u\n", offsetof(BasicBlock, bbCseGen),
sizeof(bbDummy->bbCseGen));
fprintf(fout, "Offset / size of bbCseIn = %3u / %3u\n", offsetof(BasicBlock, bbCseIn),
@@ -1888,10 +1913,6 @@ void Compiler::compInit(ArenaAllocator* pAlloc, InlineInfo* inlineInfo)
SIMDVectorHandle = nullptr;
#endif
-#ifdef DEBUG
- inlRNG = nullptr;
-#endif
-
compUsesThrowHelper = false;
}
@@ -2244,14 +2265,14 @@ const char* Compiler::compLocalVarName(unsigned varNum, unsigned offs)
void Compiler::compSetProcessor()
{
- unsigned compileFlags = opts.eeFlags;
+ const JitFlags& jitFlags = *opts.jitFlags;
#if defined(_TARGET_ARM_)
info.genCPU = CPU_ARM;
#elif defined(_TARGET_AMD64_)
- info.genCPU = CPU_X64;
+ info.genCPU = CPU_X64;
#elif defined(_TARGET_X86_)
- if (compileFlags & CORJIT_FLG_TARGET_P4)
+ if (jitFlags.IsSet(JitFlags::JIT_FLAG_TARGET_P4))
info.genCPU = CPU_X86_PENTIUM_4;
else
info.genCPU = CPU_X86;
@@ -2262,33 +2283,66 @@ void Compiler::compSetProcessor()
//
CLANG_FORMAT_COMMENT_ANCHOR;
-#ifdef _TARGET_AMD64_
- opts.compUseFCOMI = false;
- opts.compUseCMOV = true;
- opts.compCanUseSSE2 = true;
+#ifdef _TARGET_XARCH_
+ opts.compCanUseSSE3_4 = false;
+ if (!jitFlags.IsSet(JitFlags::JIT_FLAG_PREJIT) && jitFlags.IsSet(JitFlags::JIT_FLAG_USE_SSE3_4))
+ {
+ if (JitConfig.EnableSSE3_4() != 0)
+ {
+ opts.compCanUseSSE3_4 = true;
+ }
+ }
#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 (((compileFlags & CORJIT_FLG_PREJIT) == 0) && ((compileFlags & CORJIT_FLG_USE_AVX2) != 0))
+ if (!jitFlags.IsSet(JitFlags::JIT_FLAG_PREJIT) && jitFlags.IsSet(JitFlags::JIT_FLAG_USE_AVX2))
{
if (JitConfig.EnableAVX() != 0)
{
opts.compCanUseAVX = true;
- if (!compIsForInlining())
- {
- codeGen->getEmitter()->SetUseAVX(true);
- }
}
}
-#endif
-#endif //_TARGET_AMD64_
+#endif // FEATURE_AVX_SUPPORT
-#ifdef _TARGET_X86_
- opts.compUseFCOMI = ((opts.eeFlags & CORJIT_FLG_USE_FCOMI) != 0);
- opts.compUseCMOV = ((opts.eeFlags & CORJIT_FLG_USE_CMOV) != 0);
- opts.compCanUseSSE2 = ((opts.eeFlags & CORJIT_FLG_USE_SSE2) != 0);
+ if (!compIsForInlining())
+ {
+#ifdef FEATURE_AVX_SUPPORT
+ if (opts.compCanUseAVX)
+ {
+ codeGen->getEmitter()->SetUseAVX(true);
+ }
+ else
+#endif // FEATURE_AVX_SUPPORT
+ if (opts.compCanUseSSE3_4)
+ {
+ codeGen->getEmitter()->SetUseSSE3_4(true);
+ }
+ }
+#endif // _TARGET_XARCH_
+
+#ifdef _TARGET_AMD64_
+ opts.compUseFCOMI = false;
+ opts.compUseCMOV = true;
+ opts.compCanUseSSE2 = true;
+#elif defined(_TARGET_X86_)
+ opts.compUseFCOMI = jitFlags.IsSet(JitFlags::JIT_FLAG_USE_FCOMI);
+ opts.compUseCMOV = jitFlags.IsSet(JitFlags::JIT_FLAG_USE_CMOV);
+ opts.compCanUseSSE2 = jitFlags.IsSet(JitFlags::JIT_FLAG_USE_SSE2);
+
+#if !defined(LEGACY_BACKEND) && !defined(FEATURE_CORECLR)
+ // RyuJIT/x86 requires SSE2 to be available: there is no support for generating floating-point
+ // code with x87 instructions. On .NET Core, the VM always tells us that SSE2 is available.
+ // However, on desktop, under ngen, (and presumably in the unlikely case you're actually
+ // running on a machine without SSE2), the VM does not set the SSE2 flag. We ignore this and
+ // go ahead and generate SSE2 code anyway.
+ if (!opts.compCanUseSSE2)
+ {
+ JITDUMP("VM didn't set CORJIT_FLG_USE_SSE2! Ignoring, and generating SSE2 code anyway.\n");
+ opts.compCanUseSSE2 = true;
+ }
+#endif // !defined(LEGACY_BACKEND) && !defined(FEATURE_CORECLR)
#ifdef DEBUG
if (opts.compUseFCOMI)
@@ -2296,7 +2350,9 @@ void Compiler::compSetProcessor()
if (opts.compUseCMOV)
opts.compUseCMOV = !compStressCompile(STRESS_USE_CMOV, 50);
- // Should we override the SSE2 setting
+#ifdef LEGACY_BACKEND
+
+ // Should we override the SSE2 setting?
enum
{
SSE2_FORCE_DISABLE = 0,
@@ -2310,7 +2366,17 @@ void Compiler::compSetProcessor()
opts.compCanUseSSE2 = true;
else if (opts.compCanUseSSE2)
opts.compCanUseSSE2 = !compStressCompile(STRESS_GENERIC_VARN, 50);
+
+#else // !LEGACY_BACKEND
+
+ // RyuJIT/x86 requires SSE2 to be available and hence
+ // don't turn off compCanUseSSE2 under stress.
+ assert(opts.compCanUseSSE2);
+
+#endif // !LEGACY_BACKEND
+
#endif // DEBUG
+
#endif // _TARGET_X86_
}
@@ -2378,31 +2444,36 @@ unsigned ReinterpretHexAsDecimal(unsigned in)
return result;
}
-void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags)
+void Compiler::compInitOptions(JitFlags* jitFlags)
{
#ifdef UNIX_AMD64_ABI
opts.compNeedToAlignFrame = false;
#endif // UNIX_AMD64_ABI
memset(&opts, 0, sizeof(opts));
- unsigned compileFlags = jitFlags->corJitFlags;
-
if (compIsForInlining())
{
- assert((compileFlags & CORJIT_FLG_LOST_WHEN_INLINING) == 0);
- assert(compileFlags & CORJIT_FLG_SKIP_VERIFICATION);
+ // The following flags are lost when inlining. (They are removed in
+ // Compiler::fgInvokeInlineeCompiler().)
+ assert(!jitFlags->IsSet(JitFlags::JIT_FLAG_BBOPT));
+ assert(!jitFlags->IsSet(JitFlags::JIT_FLAG_BBINSTR));
+ assert(!jitFlags->IsSet(JitFlags::JIT_FLAG_PROF_ENTERLEAVE));
+ assert(!jitFlags->IsSet(JitFlags::JIT_FLAG_DEBUG_EnC));
+ assert(!jitFlags->IsSet(JitFlags::JIT_FLAG_DEBUG_INFO));
+
+ assert(jitFlags->IsSet(JitFlags::JIT_FLAG_SKIP_VERIFICATION));
}
opts.jitFlags = jitFlags;
- opts.eeFlags = compileFlags;
opts.compFlags = CLFLG_MAXOPT; // Default value is for full optimization
- if (opts.eeFlags & (CORJIT_FLG_DEBUG_CODE | CORJIT_FLG_MIN_OPT))
+ if (jitFlags->IsSet(JitFlags::JIT_FLAG_DEBUG_CODE) || jitFlags->IsSet(JitFlags::JIT_FLAG_MIN_OPT))
{
opts.compFlags = CLFLG_MINOPT;
}
// Don't optimize .cctors (except prejit) or if we're an inlinee
- else if (!(opts.eeFlags & CORJIT_FLG_PREJIT) && ((info.compFlags & FLG_CCTOR) == FLG_CCTOR) && !compIsForInlining())
+ else if (!jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT) && ((info.compFlags & FLG_CCTOR) == FLG_CCTOR) &&
+ !compIsForInlining())
{
opts.compFlags = CLFLG_MINOPT;
}
@@ -2414,32 +2485,31 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags)
// If the EE sets SIZE_OPT or if we are compiling a Class constructor
// we will optimize for code size at the expense of speed
//
- if ((opts.eeFlags & CORJIT_FLG_SIZE_OPT) || ((info.compFlags & FLG_CCTOR) == FLG_CCTOR))
+ if (jitFlags->IsSet(JitFlags::JIT_FLAG_SIZE_OPT) || ((info.compFlags & FLG_CCTOR) == FLG_CCTOR))
{
opts.compCodeOpt = SMALL_CODE;
}
//
// If the EE sets SPEED_OPT we will optimize for speed at the expense of code size
//
- else if (opts.eeFlags & CORJIT_FLG_SPEED_OPT)
+ else if (jitFlags->IsSet(JitFlags::JIT_FLAG_SPEED_OPT))
{
opts.compCodeOpt = FAST_CODE;
- assert((opts.eeFlags & CORJIT_FLG_SIZE_OPT) == 0);
+ assert(!jitFlags->IsSet(JitFlags::JIT_FLAG_SIZE_OPT));
}
-//-------------------------------------------------------------------------
+ //-------------------------------------------------------------------------
+
+ opts.compDbgCode = jitFlags->IsSet(JitFlags::JIT_FLAG_DEBUG_CODE);
+ opts.compDbgInfo = jitFlags->IsSet(JitFlags::JIT_FLAG_DEBUG_INFO);
+ opts.compDbgEnC = jitFlags->IsSet(JitFlags::JIT_FLAG_DEBUG_EnC);
-#ifdef DEBUGGING_SUPPORT
- opts.compDbgCode = (opts.eeFlags & CORJIT_FLG_DEBUG_CODE) != 0;
- opts.compDbgInfo = (opts.eeFlags & CORJIT_FLG_DEBUG_INFO) != 0;
- opts.compDbgEnC = (opts.eeFlags & CORJIT_FLG_DEBUG_EnC) != 0;
#if REGEN_SHORTCUTS || REGEN_CALLPAT
// We never want to have debugging enabled when regenerating GC encoding patterns
opts.compDbgCode = false;
opts.compDbgInfo = false;
opts.compDbgEnC = false;
#endif
-#endif
compSetProcessor();
@@ -2473,7 +2543,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags)
#ifdef DEBUG
const JitConfigValues::MethodSet* pfAltJit;
- if (opts.eeFlags & CORJIT_FLG_PREJIT)
+ if (jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT))
{
pfAltJit = &JitConfig.AltJitNgen();
}
@@ -2498,7 +2568,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags)
#else // !DEBUG
const char* altJitVal;
- if (opts.eeFlags & CORJIT_FLG_PREJIT)
+ if (jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT))
{
altJitVal = JitConfig.AltJitNgen().list();
}
@@ -2602,7 +2672,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags)
//
if (!compIsForInlining())
{
- if (opts.eeFlags & CORJIT_FLG_PREJIT)
+ if (jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT))
{
if (JitConfig.NgenDump().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args))
{
@@ -2952,10 +3022,8 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags)
#endif // DEBUG
#ifdef FEATURE_SIMD
-#ifdef _TARGET_AMD64_
- // Minimum bar for availing SIMD benefits is SSE2 on AMD64.
- featureSIMD = ((opts.eeFlags & CORJIT_FLG_FEATURE_SIMD) != 0);
-#endif // _TARGET_AMD64_
+ // Minimum bar for availing SIMD benefits is SSE2 on AMD64/x86.
+ featureSIMD = jitFlags->IsSet(JitFlags::JIT_FLAG_FEATURE_SIMD);
#endif // FEATURE_SIMD
if (compIsForInlining() || compIsForImportOnly())
@@ -2978,23 +3046,26 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags)
opts.compTailCallLoopOpt = true;
#endif
-#ifdef DEBUG
- opts.dspInstrs = false;
- opts.dspEmit = false;
- opts.dspLines = false;
- opts.varNames = false;
- opts.dmpHex = false;
- opts.disAsm = false;
- opts.disAsmSpilled = false;
- opts.disDiffable = false;
- opts.dspCode = false;
- opts.dspEHTable = false;
- opts.dspGCtbls = false;
- opts.disAsm2 = false;
- opts.dspUnwind = false;
- s_dspMemStats = false;
- opts.compLongAddress = false;
+#ifdef PROFILING_SUPPORTED
opts.compJitELTHookEnabled = false;
+#endif // PROFILING_SUPPORTED
+
+#ifdef DEBUG
+ opts.dspInstrs = false;
+ opts.dspEmit = false;
+ opts.dspLines = false;
+ opts.varNames = false;
+ opts.dmpHex = false;
+ opts.disAsm = false;
+ opts.disAsmSpilled = false;
+ opts.disDiffable = false;
+ opts.dspCode = false;
+ opts.dspEHTable = false;
+ opts.dspGCtbls = false;
+ opts.disAsm2 = false;
+ opts.dspUnwind = false;
+ opts.compLongAddress = false;
+ opts.optRepeat = false;
#ifdef LATE_DISASM
opts.doLateDisasm = false;
@@ -3007,7 +3078,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags)
//
if (!altJitConfig || opts.altJit)
{
- if (opts.eeFlags & CORJIT_FLG_PREJIT)
+ if (jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT))
{
if ((JitConfig.NgenOrder() & 1) == 1)
{
@@ -3084,14 +3155,14 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags)
opts.dspDiffable = true;
}
- if (JitConfig.DisplayMemStats() != 0)
+ if (JitConfig.JitLongAddress() != 0)
{
- s_dspMemStats = true;
+ opts.compLongAddress = true;
}
- if (JitConfig.JitLongAddress() != 0)
+ if (JitConfig.JitOptRepeat().contains(info.compMethodName, info.compClassName, &info.compMethodInfo->args))
{
- opts.compLongAddress = true;
+ opts.optRepeat = true;
}
}
@@ -3152,7 +3223,6 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags)
//-------------------------------------------------------------------------
-#ifdef DEBUGGING_SUPPORT
#ifdef DEBUG
assert(!codeGen->isGCTypeFixed());
opts.compGcChecks = (JitConfig.JitGCChecks() != 0) || compStressCompile(STRESS_GENERIC_VARN, 5);
@@ -3173,11 +3243,15 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags)
opts.compStackCheckOnCall = (dwJitStackChecks & DWORD(STACK_CHECK_ON_CALL)) != 0;
#endif
+#if MEASURE_MEM_ALLOC
+ s_dspMemStats = (JitConfig.DisplayMemStats() != 0);
+#endif
+
#ifdef PROFILING_SUPPORTED
- opts.compNoPInvokeInlineCB = (opts.eeFlags & CORJIT_FLG_PROF_NO_PINVOKE_INLINE) ? true : false;
+ opts.compNoPInvokeInlineCB = jitFlags->IsSet(JitFlags::JIT_FLAG_PROF_NO_PINVOKE_INLINE);
// Cache the profiler handle
- if (opts.eeFlags & CORJIT_FLG_PROF_ENTERLEAVE)
+ if (jitFlags->IsSet(JitFlags::JIT_FLAG_PROF_ENTERLEAVE))
{
BOOL hookNeeded;
BOOL indirected;
@@ -3192,11 +3266,8 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags)
compProfilerMethHndIndirected = false;
}
-#if defined(_TARGET_ARM_) || defined(_TARGET_AMD64_)
- // Right now this ELT hook option is enabled only for arm and amd64
-
- // Honour complus_JitELTHookEnabled only if VM has not asked us to generate profiler
- // hooks in the first place. That is, Override VM only if it hasn't asked for a
+ // Honour COMPlus_JitELTHookEnabled only if VM has not asked us to generate profiler
+ // hooks in the first place. That is, override VM only if it hasn't asked for a
// profiler callback for this method.
if (!compProfilerHookNeeded && (JitConfig.JitELTHookEnabled() != 0))
{
@@ -3209,7 +3280,6 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags)
compProfilerMethHnd = (void*)DummyProfilerELTStub;
compProfilerMethHndIndirected = false;
}
-#endif // _TARGET_ARM_ || _TARGET_AMD64_
#endif // PROFILING_SUPPORTED
@@ -3226,10 +3296,9 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags)
}
#endif
- opts.compMustInlinePInvokeCalli = (opts.eeFlags & CORJIT_FLG_IL_STUB) ? true : false;
+ opts.compMustInlinePInvokeCalli = jitFlags->IsSet(JitFlags::JIT_FLAG_IL_STUB);
opts.compScopeInfo = opts.compDbgInfo;
-#endif // DEBUGGING_SUPPORT
#ifdef LATE_DISASM
codeGen->getDisAssembler().disOpenForLateDisAsm(info.compMethodName, info.compClassName,
@@ -3239,7 +3308,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags)
//-------------------------------------------------------------------------
#if RELOC_SUPPORT
- opts.compReloc = (opts.eeFlags & CORJIT_FLG_RELOC) ? true : false;
+ opts.compReloc = jitFlags->IsSet(JitFlags::JIT_FLAG_RELOC);
#endif
#ifdef DEBUG
@@ -3249,7 +3318,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags)
#endif
#endif // DEBUG
- opts.compProcedureSplitting = (opts.eeFlags & CORJIT_FLG_PROCSPLIT) ? true : false;
+ opts.compProcedureSplitting = jitFlags->IsSet(JitFlags::JIT_FLAG_PROCSPLIT);
#ifdef _TARGET_ARM64_
// TODO-ARM64-NYI: enable hot/cold splitting
@@ -3294,7 +3363,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags)
fgProfileBuffer = nullptr;
fgProfileData_ILSizeMismatch = false;
fgNumProfileRuns = 0;
- if (opts.eeFlags & CORJIT_FLG_BBOPT)
+ if (jitFlags->IsSet(JitFlags::JIT_FLAG_BBOPT))
{
assert(!compIsForInlining());
HRESULT hr;
@@ -3365,7 +3434,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags)
printf("OPTIONS: compProcedureSplitting = %s\n", dspBool(opts.compProcedureSplitting));
printf("OPTIONS: compProcedureSplittingEH = %s\n", dspBool(opts.compProcedureSplittingEH));
- if ((opts.eeFlags & CORJIT_FLG_BBOPT) && fgHaveProfileData())
+ if (jitFlags->IsSet(JitFlags::JIT_FLAG_BBOPT) && fgHaveProfileData())
{
printf("OPTIONS: using real profile data\n");
}
@@ -3375,7 +3444,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags)
printf("OPTIONS: discarded IBC profile data due to mismatch in ILSize\n");
}
- if (opts.eeFlags & CORJIT_FLG_PREJIT)
+ if (jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT))
{
printf("OPTIONS: Jit invoked for ngen\n");
}
@@ -3384,11 +3453,11 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags)
#endif
opts.compGCPollType = GCPOLL_NONE;
- if (opts.eeFlags & CORJIT_FLG_GCPOLL_CALLS)
+ if (jitFlags->IsSet(JitFlags::JIT_FLAG_GCPOLL_CALLS))
{
opts.compGCPollType = GCPOLL_CALL;
}
- else if (opts.eeFlags & CORJIT_FLG_GCPOLL_INLINE)
+ else if (jitFlags->IsSet(JitFlags::JIT_FLAG_GCPOLL_INLINE))
{
// make sure that the EE didn't set both flags.
assert(opts.compGCPollType == GCPOLL_NONE);
@@ -3568,14 +3637,11 @@ void Compiler::compInitDebuggingInfo()
info.compVarScopesCount = 0;
-#ifdef DEBUGGING_SUPPORT
if (opts.compScopeInfo)
-#endif
{
eeGetVars();
}
-#ifdef DEBUGGING_SUPPORT
compInitVarScopeMap();
if (opts.compScopeInfo || opts.compDbgCode)
@@ -3598,7 +3664,6 @@ void Compiler::compInitDebuggingInfo()
JITDUMP("Debuggable code - Add new BB%02u to perform initialization of variables [%08X]\n", fgFirstBB->bbNum,
dspPtr(fgFirstBB));
}
-#endif // DEBUGGING_SUPPORT
/*-------------------------------------------------------------------------
*
@@ -3617,9 +3682,7 @@ void Compiler::compInitDebuggingInfo()
info.compStmtOffsetsCount = 0;
-#ifdef DEBUGGING_SUPPORT
if (opts.compDbgInfo)
-#endif
{
/* Get hold of the line# records, if there are any */
@@ -3661,12 +3724,9 @@ void Compiler::compInitDebuggingInfo()
void Compiler::compSetOptimizationLevel()
{
- unsigned compileFlags;
bool theMinOptsValue;
unsigned jitMinOpts;
- compileFlags = opts.eeFlags;
-
if (compIsForInlining())
{
theMinOptsValue = impInlineInfo->InlinerCompiler->opts.MinOpts();
@@ -3757,13 +3817,40 @@ void Compiler::compSetOptimizationLevel()
}
}
+#if 0
+ // The code in this #if can be used to debug optimization issues according to method hash.
+ // To use, uncomment, rebuild and set environment variables minoptshashlo and minoptshashhi.
+#ifdef DEBUG
+ unsigned methHash = info.compMethodHash();
+ char* lostr = getenv("minoptshashlo");
+ unsigned methHashLo = 0;
+ if (lostr != nullptr)
+ {
+ sscanf_s(lostr, "%x", &methHashLo);
+ char* histr = getenv("minoptshashhi");
+ unsigned methHashHi = UINT32_MAX;
+ if (histr != nullptr)
+ {
+ sscanf_s(histr, "%x", &methHashHi);
+ if (methHash >= methHashLo && methHash <= methHashHi)
+ {
+ printf("MinOpts for method %s, hash = 0x%x.\n",
+ info.compFullName, info.compMethodHash());
+ printf(""); // in our logic this causes a flush
+ theMinOptsValue = true;
+ }
+ }
+ }
+#endif
+#endif
+
if (compStressCompile(STRESS_MIN_OPTS, 5))
{
theMinOptsValue = true;
}
// For PREJIT we never drop down to MinOpts
// unless unless CLFLG_MINOPT is set
- else if (!(compileFlags & CORJIT_FLG_PREJIT))
+ else if (!opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT))
{
if ((unsigned)JitConfig.JitMinOptsCodeSize() < info.compILCodeSize)
{
@@ -3805,7 +3892,7 @@ void Compiler::compSetOptimizationLevel()
// Retail check if we should force Minopts due to the complexity of the method
// For PREJIT we never drop down to MinOpts
// unless unless CLFLG_MINOPT is set
- if (!theMinOptsValue && !(compileFlags & CORJIT_FLG_PREJIT) &&
+ if (!theMinOptsValue && !opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT) &&
((DEFAULT_MIN_OPTS_CODE_SIZE < info.compILCodeSize) || (DEFAULT_MIN_OPTS_INSTR_COUNT < opts.instrCount) ||
(DEFAULT_MIN_OPTS_BB_COUNT < fgBBcount) || (DEFAULT_MIN_OPTS_LV_NUM_COUNT < lvaCount) ||
(DEFAULT_MIN_OPTS_LV_REF_COUNT < opts.lvRefCount)))
@@ -3828,14 +3915,14 @@ void Compiler::compSetOptimizationLevel()
unsigned methHash = info.compMethodHash();
char* lostr = getenv("opthashlo");
unsigned methHashLo = 0;
- if (lostr != NULL)
+ if (lostr != NULL)
{
sscanf_s(lostr, "%x", &methHashLo);
// methHashLo = (unsigned(atoi(lostr)) << 2); // So we don't have to use negative numbers.
}
char* histr = getenv("opthashhi");
unsigned methHashHi = UINT32_MAX;
- if (histr != NULL)
+ if (histr != NULL)
{
sscanf_s(histr, "%x", &methHashHi);
// methHashHi = (unsigned(atoi(histr)) << 2); // So we don't have to use negative numbers.
@@ -3883,27 +3970,27 @@ _SetMinOpts:
}
#if !defined(_TARGET_AMD64_)
- // The VM sets CORJIT_FLG_FRAMED for two reasons: (1) the COMPlus_JitFramed variable is set, or
+ // The VM sets JitFlags::JIT_FLAG_FRAMED for two reasons: (1) the COMPlus_JitFramed variable is set, or
// (2) the function is marked "noinline". The reason for #2 is that people mark functions
// noinline to ensure the show up on in a stack walk. But for AMD64, we don't need a frame
// pointer for the frame to show up in stack walk.
- if (compileFlags & CORJIT_FLG_FRAMED)
+ if (opts.jitFlags->IsSet(JitFlags::JIT_FLAG_FRAMED))
codeGen->setFrameRequired(true);
#endif
- if (compileFlags & CORJIT_FLG_RELOC)
+ if (opts.jitFlags->IsSet(JitFlags::JIT_FLAG_RELOC))
{
codeGen->genAlignLoops = false; // loop alignment not supported for prejitted code
- // The zapper doesn't set CORJIT_FLG_ALIGN_LOOPS, and there is
+ // The zapper doesn't set JitFlags::JIT_FLAG_ALIGN_LOOPS, and there is
// no reason for it to set it as the JIT doesn't currently support loop alignment
// for prejitted images. (The JIT doesn't know the final address of the code, hence
// it can't align code based on unknown addresses.)
- assert((compileFlags & CORJIT_FLG_ALIGN_LOOPS) == 0);
+ assert(!opts.jitFlags->IsSet(JitFlags::JIT_FLAG_ALIGN_LOOPS));
}
else
{
- codeGen->genAlignLoops = (compileFlags & CORJIT_FLG_ALIGN_LOOPS) != 0;
+ codeGen->genAlignLoops = opts.jitFlags->IsSet(JitFlags::JIT_FLAG_ALIGN_LOOPS);
}
}
@@ -4075,7 +4162,7 @@ void Compiler::compFunctionTraceEnd(void* methodCodePtr, ULONG methodCodeSize, b
// For an overview of the structure of the JIT, see:
// https://github.com/dotnet/coreclr/blob/master/Documentation/botr/ryujit-overview.md
//
-void Compiler::compCompile(void** methodCodePtr, ULONG* methodCodeSize, CORJIT_FLAGS* compileFlags)
+void Compiler::compCompile(void** methodCodePtr, ULONG* methodCodeSize, JitFlags* compileFlags)
{
if (compIsForInlining())
{
@@ -4112,26 +4199,36 @@ void Compiler::compCompile(void** methodCodePtr, ULONG* methodCodeSize, CORJIT_F
fgRemovePreds();
}
+ EndPhase(PHASE_IMPORTATION);
+
if (compIsForInlining())
{
/* Quit inlining if fgImport() failed for any reason. */
- if (compDonotInline())
+ if (!compDonotInline())
{
- return;
+ /* Filter out unimported BBs */
+
+ fgRemoveEmptyBlocks();
}
- /* Filter out unimported BBs */
+ EndPhase(PHASE_POST_IMPORT);
- fgRemoveEmptyBlocks();
+#ifdef FEATURE_JIT_METHOD_PERF
+ if (pCompJitTimer != nullptr)
+ {
+#if MEASURE_CLRAPI_CALLS
+ EndPhase(PHASE_CLR_API);
+#endif
+ pCompJitTimer->Terminate(this, CompTimeSummaryInfo::s_compTimeSummary, false);
+ }
+#endif
return;
}
assert(!compDonotInline());
- EndPhase(PHASE_IMPORTATION);
-
// Maybe the caller was not interested in generating code
if (compIsForImportOnly())
{
@@ -4145,7 +4242,7 @@ void Compiler::compCompile(void** methodCodePtr, ULONG* methodCodeSize, CORJIT_F
fgRemoveEH();
#endif // !FEATURE_EH
- if (compileFlags->corJitFlags & CORJIT_FLG_BBINSTR)
+ if (compileFlags->IsSet(JitFlags::JIT_FLAG_BBINSTR))
{
fgInstrumentMethod();
}
@@ -4180,7 +4277,7 @@ void Compiler::compCompile(void** methodCodePtr, ULONG* methodCodeSize, CORJIT_F
/* Massage the trees so that we can generate code out of them */
fgMorph();
- EndPhase(PHASE_MORPH);
+ EndPhase(PHASE_MORPH_END);
/* GS security checks for unsafe buffers */
if (getNeedsGSSecurityCookie())
@@ -4336,6 +4433,7 @@ void Compiler::compCompile(void** methodCodePtr, ULONG* methodCodeSize, CORJIT_F
bool doCopyProp = true;
bool doAssertionProp = true;
bool doRangeAnalysis = true;
+ int iterations = 1;
#ifdef DEBUG
doSsa = (JitConfig.JitDoSsa() != 0);
@@ -4345,72 +4443,88 @@ void Compiler::compCompile(void** methodCodePtr, ULONG* methodCodeSize, CORJIT_F
doCopyProp = doValueNum && (JitConfig.JitDoCopyProp() != 0);
doAssertionProp = doValueNum && (JitConfig.JitDoAssertionProp() != 0);
doRangeAnalysis = doAssertionProp && (JitConfig.JitDoRangeAnalysis() != 0);
-#endif
- if (doSsa)
+ if (opts.optRepeat)
{
- fgSsaBuild();
- EndPhase(PHASE_BUILD_SSA);
+ iterations = JitConfig.JitOptRepeatCount();
}
+#endif
- if (doEarlyProp)
+ while (iterations > 0)
{
- /* Propagate array length and rewrite getType() method call */
- optEarlyProp();
- EndPhase(PHASE_EARLY_PROP);
- }
+ if (doSsa)
+ {
+ fgSsaBuild();
+ EndPhase(PHASE_BUILD_SSA);
+ }
- if (doValueNum)
- {
- fgValueNumber();
- EndPhase(PHASE_VALUE_NUMBER);
- }
+ if (doEarlyProp)
+ {
+ /* Propagate array length and rewrite getType() method call */
+ optEarlyProp();
+ EndPhase(PHASE_EARLY_PROP);
+ }
- if (doLoopHoisting)
- {
- /* Hoist invariant code out of loops */
- optHoistLoopCode();
- EndPhase(PHASE_HOIST_LOOP_CODE);
- }
+ if (doValueNum)
+ {
+ fgValueNumber();
+ EndPhase(PHASE_VALUE_NUMBER);
+ }
- if (doCopyProp)
- {
- /* Perform VN based copy propagation */
- optVnCopyProp();
- EndPhase(PHASE_VN_COPY_PROP);
- }
+ if (doLoopHoisting)
+ {
+ /* Hoist invariant code out of loops */
+ optHoistLoopCode();
+ EndPhase(PHASE_HOIST_LOOP_CODE);
+ }
+
+ if (doCopyProp)
+ {
+ /* Perform VN based copy propagation */
+ optVnCopyProp();
+ EndPhase(PHASE_VN_COPY_PROP);
+ }
#if FEATURE_ANYCSE
- /* Remove common sub-expressions */
- optOptimizeCSEs();
+ /* Remove common sub-expressions */
+ optOptimizeCSEs();
#endif // FEATURE_ANYCSE
#if ASSERTION_PROP
- if (doAssertionProp)
- {
- /* Assertion propagation */
- optAssertionPropMain();
- EndPhase(PHASE_ASSERTION_PROP_MAIN);
- }
+ if (doAssertionProp)
+ {
+ /* Assertion propagation */
+ optAssertionPropMain();
+ EndPhase(PHASE_ASSERTION_PROP_MAIN);
+ }
- if (doRangeAnalysis)
- {
- /* Optimize array index range checks */
- RangeCheck rc(this);
- rc.OptimizeRangeChecks();
- EndPhase(PHASE_OPTIMIZE_INDEX_CHECKS);
- }
+ if (doRangeAnalysis)
+ {
+ /* Optimize array index range checks */
+ RangeCheck rc(this);
+ rc.OptimizeRangeChecks();
+ EndPhase(PHASE_OPTIMIZE_INDEX_CHECKS);
+ }
#endif // ASSERTION_PROP
- /* update the flowgraph if we modified it during the optimization phase*/
- if (fgModified)
- {
- fgUpdateFlowGraph();
- EndPhase(PHASE_UPDATE_FLOW_GRAPH);
+ /* update the flowgraph if we modified it during the optimization phase*/
+ if (fgModified)
+ {
+ fgUpdateFlowGraph();
+ EndPhase(PHASE_UPDATE_FLOW_GRAPH);
+
+ // Recompute the edge weight if we have modified the flow graph
+ fgComputeEdgeWeights();
+ EndPhase(PHASE_COMPUTE_EDGE_WEIGHTS2);
+ }
- // Recompute the edge weight if we have modified the flow graph
- fgComputeEdgeWeights();
- EndPhase(PHASE_COMPUTE_EDGE_WEIGHTS2);
+ // Iterate if requested, resetting annotations first.
+ if (--iterations == 0)
+ {
+ break;
+ }
+ ResetOptAnnotations();
+ RecomputeLoopInfo();
}
}
@@ -4540,7 +4654,12 @@ void Compiler::compCompile(void** methodCodePtr, ULONG* methodCodeSize, CORJIT_F
#ifdef FEATURE_JIT_METHOD_PERF
if (pCompJitTimer)
- pCompJitTimer->Terminate(this, CompTimeSummaryInfo::s_compTimeSummary);
+ {
+#if MEASURE_CLRAPI_CALLS
+ EndPhase(PHASE_CLR_API);
+#endif
+ pCompJitTimer->Terminate(this, CompTimeSummaryInfo::s_compTimeSummary, true);
+ }
#endif
RecordStateAtEndOfCompilation();
@@ -4569,6 +4688,82 @@ void Compiler::compCompile(void** methodCodePtr, ULONG* methodCodeSize, CORJIT_F
#endif // FUNC_INFO_LOGGING
}
+//------------------------------------------------------------------------
+// ResetOptAnnotations: Clear annotations produced during global optimizations.
+//
+// Notes:
+// The intent of this method is to clear any information typically assumed
+// to be set only once; it is used between iterations when JitOptRepeat is
+// in effect.
+
+void Compiler::ResetOptAnnotations()
+{
+ assert(opts.optRepeat);
+ assert(JitConfig.JitOptRepeatCount() > 0);
+ fgResetForSsa();
+ vnStore = nullptr;
+ m_opAsgnVarDefSsaNums = nullptr;
+ m_blockToEHPreds = nullptr;
+ fgSsaPassesCompleted = 0;
+ fgVNPassesCompleted = 0;
+
+ for (BasicBlock* block = fgFirstBB; block != nullptr; block = block->bbNext)
+ {
+ for (GenTreeStmt* stmt = block->firstStmt(); stmt != nullptr; stmt = stmt->getNextStmt())
+ {
+ stmt->gtFlags &= ~GTF_STMT_HAS_CSE;
+
+ for (GenTreePtr tree = stmt->gtStmt.gtStmtList; tree != nullptr; tree = tree->gtNext)
+ {
+ tree->ClearVN();
+ tree->ClearAssertion();
+ tree->gtCSEnum = NO_CSE;
+
+ // Clear any *_ASG_LHS flags -- these are set during SSA construction,
+ // and the heap live-in calculation depends on them being unset coming
+ // into SSA construction (without clearing them, a block that has a
+ // heap def via one of these before any heap use is treated as not having
+ // an upwards-exposed heap use, even though subsequent heap uses may not
+ // be killed by the store; this seems to be a bug, worked around here).
+ if (tree->OperIsIndir())
+ {
+ tree->gtFlags &= ~GTF_IND_ASG_LHS;
+ }
+ else if (tree->OperGet() == GT_CLS_VAR)
+ {
+ tree->gtFlags &= ~GTF_CLS_VAR_ASG_LHS;
+ }
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+// RecomputeLoopInfo: Recompute loop annotations between opt-repeat iterations.
+//
+// Notes:
+// The intent of this method is to update loop structure annotations, and those
+// they depend on; these annotations may have become stale during optimization,
+// and need to be up-to-date before running another iteration of optimizations.
+
+void Compiler::RecomputeLoopInfo()
+{
+ assert(opts.optRepeat);
+ assert(JitConfig.JitOptRepeatCount() > 0);
+ // Recompute reachability sets, dominators, and loops.
+ optLoopCount = 0;
+ fgDomsComputed = false;
+ for (BasicBlock* block = fgFirstBB; block != nullptr; block = block->bbNext)
+ {
+ block->bbFlags &= ~BBF_LOOP_FLAGS;
+ }
+ fgComputeReachability();
+ // Rebuild the loop tree annotations themselves. Since this is performed as
+ // part of 'optOptimizeLoops', this will also re-perform loop rotation, but
+ // not other optimizations, as the others are not part of 'optOptimizeLoops'.
+ optOptimizeLoops();
+}
+
/*****************************************************************************/
void Compiler::ProcessShutdownWork(ICorStaticInfo* statInfo)
{
@@ -4696,11 +4891,13 @@ int Compiler::compCompile(CORINFO_METHOD_HANDLE methodHnd,
CORINFO_METHOD_INFO* methodInfo,
void** methodCodePtr,
ULONG* methodCodeSize,
- CORJIT_FLAGS* compileFlags)
+ JitFlags* compileFlags)
{
#ifdef FEATURE_JIT_METHOD_PERF
static bool checkedForJitTimeLog = false;
+ pCompJitTimer = nullptr;
+
if (!checkedForJitTimeLog)
{
// Call into VM to get the config strings. FEATURE_JIT_METHOD_PERF is enabled for
@@ -4713,14 +4910,10 @@ int Compiler::compCompile(CORINFO_METHOD_HANDLE methodHnd,
checkedForJitTimeLog = true;
}
- if ((Compiler::compJitTimeLogFilename != NULL) || (JitTimeLogCsv() != NULL))
+ if ((Compiler::compJitTimeLogFilename != nullptr) || (JitTimeLogCsv() != nullptr))
{
pCompJitTimer = JitTimer::Create(this, methodInfo->ILCodeSize);
}
- else
- {
- pCompJitTimer = NULL;
- }
#endif // FEATURE_JIT_METHOD_PERF
#ifdef DEBUG
@@ -4862,7 +5055,7 @@ int Compiler::compCompile(CORINFO_METHOD_HANDLE methodHnd,
// Set this before the first 'BADCODE'
// Skip verification where possible
- tiVerificationNeeded = (compileFlags->corJitFlags & CORJIT_FLG_SKIP_VERIFICATION) == 0;
+ tiVerificationNeeded = !compileFlags->IsSet(JitFlags::JIT_FLAG_SKIP_VERIFICATION);
assert(!compIsForInlining() || !tiVerificationNeeded); // Inlinees must have been verified.
@@ -4893,8 +5086,8 @@ int Compiler::compCompile(CORINFO_METHOD_HANDLE methodHnd,
case CORINFO_VERIFICATION_CAN_SKIP:
// The VM should first verify the open instantiation. If unverifiable code
- // is detected, it should pass in CORJIT_FLG_SKIP_VERIFICATION.
- assert(!"The VM should have used CORJIT_FLG_SKIP_VERIFICATION");
+ // is detected, it should pass in JitFlags::JIT_FLAG_SKIP_VERIFICATION.
+ assert(!"The VM should have used JitFlags::JIT_FLAG_SKIP_VERIFICATION");
tiVerificationNeeded = false;
break;
@@ -4933,7 +5126,7 @@ int Compiler::compCompile(CORINFO_METHOD_HANDLE methodHnd,
CORINFO_METHOD_INFO* methodInfo;
void** methodCodePtr;
ULONG* methodCodeSize;
- CORJIT_FLAGS* compileFlags;
+ JitFlags* compileFlags;
CorInfoInstantiationVerification instVerInfo;
int result;
@@ -5000,6 +5193,8 @@ void Compiler::compCompileFinish()
// Make the updates.
genMemStats.nraTotalSizeAlloc = compGetAllocator()->getTotalBytesAllocated();
genMemStats.nraTotalSizeUsed = compGetAllocator()->getTotalBytesUsed();
+ memAllocHist.record((unsigned)((genMemStats.nraTotalSizeAlloc + 1023) / 1024));
+ memUsedHist.record((unsigned)((genMemStats.nraTotalSizeUsed + 1023) / 1024));
s_aggMemStats.Add(genMemStats);
if (genMemStats.allocSz > s_maxCompMemStats.allocSz)
{
@@ -5038,6 +5233,7 @@ void Compiler::compCompileFinish()
// the prolog which requires memory
(info.compLocalsCount <= 32) && (!opts.MinOpts()) && // We may have too many local variables, etc
(getJitStressLevel() == 0) && // We need extra memory for stress
+ !opts.optRepeat && // We need extra memory to repeat opts
!compAllocator->bypassHostAllocator() && // ArenaAllocator::getDefaultPageSize() is artificially low for
// DirectAlloc
(compAllocator->getTotalBytesAllocated() > (2 * ArenaAllocator::getDefaultPageSize())) &&
@@ -5071,7 +5267,7 @@ void Compiler::compCompileFinish()
mdMethodDef currentMethodToken = info.compCompHnd->getMethodDefFromMethod(info.compMethodHnd);
unsigned profCallCount = 0;
- if (((opts.eeFlags & CORJIT_FLG_BBOPT) != 0) && fgHaveProfileData())
+ if (opts.jitFlags->IsSet(JitFlags::JIT_FLAG_BBOPT) && fgHaveProfileData())
{
assert(fgProfileBuffer[0].ILOffset == 0);
profCallCount = fgProfileBuffer[0].ExecutionCount;
@@ -5208,7 +5404,7 @@ void Compiler::compCompileFinish()
// For ngen the int3 or breakpoint instruction will be right at the
// start of the ngen method and we will stop when we execute it.
//
- if ((opts.eeFlags & CORJIT_FLG_PREJIT) == 0)
+ if (!opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT))
{
if (compJitHaltMethod())
{
@@ -5296,7 +5492,7 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr,
CORINFO_METHOD_INFO* methodInfo,
void** methodCodePtr,
ULONG* methodCodeSize,
- CORJIT_FLAGS* compileFlags,
+ JitFlags* compileFlags,
CorInfoInstantiationVerification instVerInfo)
{
CORINFO_METHOD_HANDLE methodHnd = info.compMethodHnd;
@@ -5438,7 +5634,7 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr,
info.compIsContextful = (info.compClassAttr & CORINFO_FLG_CONTEXTFUL) != 0;
- info.compPublishStubParam = (opts.eeFlags & CORJIT_FLG_PUBLISH_SECRET_PARAM) != 0;
+ info.compPublishStubParam = opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PUBLISH_SECRET_PARAM);
switch (methodInfo->args.getCallConv())
{
@@ -5476,7 +5672,7 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr,
const bool forceInline = !!(info.compFlags & CORINFO_FLG_FORCEINLINE);
- if (!compIsForInlining() && (opts.eeFlags & CORJIT_FLG_PREJIT))
+ if (!compIsForInlining() && opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT))
{
// We're prejitting the root method. We also will analyze it as
// a potential inline candidate.
@@ -5644,10 +5840,6 @@ _Next:
return CORJIT_OK;
}
-/*****************************************************************************/
-#ifdef DEBUGGING_SUPPORT
-/*****************************************************************************/
-
//------------------------------------------------------------------------
// compFindLocalVarLinear: Linear search for variable's scope containing offset.
//
@@ -5992,11 +6184,7 @@ void Compiler::compProcessScopesUntil(unsigned offset,
} while (foundExit || foundEnter);
}
-/*****************************************************************************/
-#endif // DEBUGGING_SUPPORT
-/*****************************************************************************/
-
-#if defined(DEBUGGING_SUPPORT) && defined(DEBUG)
+#if defined(DEBUG)
void Compiler::compDispScopeLists()
{
@@ -6044,10 +6232,6 @@ void Compiler::compDispScopeLists()
}
}
-#endif
-
-#if defined(DEBUG)
-
void Compiler::compDispLocalVars()
{
printf("info.compVarScopesCount = %d\n", info.compVarScopesCount);
@@ -6066,7 +6250,66 @@ void Compiler::compDispLocalVars()
}
}
-#endif
+#endif // DEBUG
+
+/*****************************************************************************/
+
+#if MEASURE_CLRAPI_CALLS
+
+struct WrapICorJitInfo : public ICorJitInfo
+{
+ //------------------------------------------------------------------------
+ // WrapICorJitInfo::makeOne: allocate an instance of WrapICorJitInfo
+ //
+ // Arguments:
+ // alloc - the allocator to get memory from for the instance
+ // compile - the compiler instance
+ // compHndRef - the ICorJitInfo handle from the EE; the caller's
+ // copy may be replaced with a "wrapper" instance
+ //
+ // Return Value:
+ // If the config flags indicate that ICorJitInfo should be wrapped,
+ // we return the "wrapper" instance; otherwise we return "nullptr".
+
+ static WrapICorJitInfo* makeOne(ArenaAllocator* alloc, Compiler* compiler, COMP_HANDLE& compHndRef /* INOUT */)
+ {
+ WrapICorJitInfo* wrap = nullptr;
+
+ if (JitConfig.JitEECallTimingInfo() != 0)
+ {
+ // It's too early to use the default allocator, so we do this
+ // in two steps to be safe (the constructor doesn't need to do
+ // anything except fill in the vtable pointer, so we let the
+ // compiler do it).
+ void* inst = alloc->allocateMemory(roundUp(sizeof(WrapICorJitInfo)));
+ if (inst != nullptr)
+ {
+ // If you get a build error here due to 'WrapICorJitInfo' being
+ // an abstract class, it's very likely that the wrapper bodies
+ // in ICorJitInfo_API_wrapper.hpp are no longer in sync with
+ // the EE interface; please be kind and update the header file.
+ wrap = new (inst, jitstd::placement_t()) WrapICorJitInfo();
+
+ wrap->wrapComp = compiler;
+
+ // Save the real handle and replace it with our wrapped version.
+ wrap->wrapHnd = compHndRef;
+ compHndRef = wrap;
+ }
+ }
+
+ return wrap;
+ }
+
+private:
+ Compiler* wrapComp;
+ COMP_HANDLE wrapHnd; // the "real thing"
+
+public:
+#include "ICorJitInfo_API_wrapper.hpp"
+};
+
+#endif // MEASURE_CLRAPI_CALLS
/*****************************************************************************/
@@ -6078,7 +6321,7 @@ int jitNativeCode(CORINFO_METHOD_HANDLE methodHnd,
CORINFO_METHOD_INFO* methodInfo,
void** methodCodePtr,
ULONG* methodCodeSize,
- CORJIT_FLAGS* compileFlags,
+ JitFlags* compileFlags,
void* inlineInfoPtr)
{
//
@@ -6093,6 +6336,10 @@ START:
ArenaAllocator* pAlloc = nullptr;
ArenaAllocator alloc;
+#if MEASURE_CLRAPI_CALLS
+ WrapICorJitInfo* wrapCLR = nullptr;
+#endif
+
if (inlineInfo)
{
// Use inliner's memory allocator when compiling the inlinee.
@@ -6128,8 +6375,11 @@ START:
CORINFO_METHOD_INFO* methodInfo;
void** methodCodePtr;
ULONG* methodCodeSize;
- CORJIT_FLAGS* compileFlags;
+ JitFlags* compileFlags;
InlineInfo* inlineInfo;
+#if MEASURE_CLRAPI_CALLS
+ WrapICorJitInfo* wrapCLR;
+#endif
int result;
} param;
@@ -6145,7 +6395,10 @@ START:
param.methodCodeSize = methodCodeSize;
param.compileFlags = compileFlags;
param.inlineInfo = inlineInfo;
- param.result = result;
+#if MEASURE_CLRAPI_CALLS
+ param.wrapCLR = nullptr;
+#endif
+ param.result = result;
setErrorTrap(compHnd, Param*, pParamOuter, &param)
{
@@ -6172,6 +6425,10 @@ START:
pParam->pComp = (Compiler*)pParam->pAlloc->allocateMemory(roundUp(sizeof(*pParam->pComp)));
}
+#if MEASURE_CLRAPI_CALLS
+ pParam->wrapCLR = WrapICorJitInfo::makeOne(pParam->pAlloc, pParam->pComp, pParam->compHnd);
+#endif
+
// push this compiler on the stack (TLS)
pParam->pComp->prevCompiler = JitTls::GetCompiler();
JitTls::SetCompiler(pParam->pComp);
@@ -6238,8 +6495,9 @@ START:
jitFallbackCompile = true;
// Update the flags for 'safer' code generation.
- compileFlags->corJitFlags |= CORJIT_FLG_MIN_OPT;
- compileFlags->corJitFlags &= ~(CORJIT_FLG_SIZE_OPT | CORJIT_FLG_SPEED_OPT);
+ compileFlags->Set(JitFlags::JIT_FLAG_MIN_OPT);
+ compileFlags->Clear(JitFlags::JIT_FLAG_SIZE_OPT);
+ compileFlags->Clear(JitFlags::JIT_FLAG_SPEED_OPT);
goto START;
}
@@ -6952,9 +7210,12 @@ void Compiler::compDispCallArgStats(FILE* fout)
// Static variables
CritSecObject CompTimeSummaryInfo::s_compTimeSummaryLock;
CompTimeSummaryInfo CompTimeSummaryInfo::s_compTimeSummary;
+#if MEASURE_CLRAPI_CALLS
+double JitTimer::s_cyclesPerSec = CycleTimer::CyclesPerSecond();
+#endif
#endif // FEATURE_JIT_METHOD_PERF
-#if defined(FEATURE_JIT_METHOD_PERF) || DUMP_FLOWGRAPHS
+#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,
#include "compphases.h"
@@ -6983,13 +7244,36 @@ int PhaseParent[] = {
};
CompTimeInfo::CompTimeInfo(unsigned byteCodeBytes)
- : m_byteCodeBytes(byteCodeBytes), m_totalCycles(0), m_parentPhaseEndSlop(0), m_timerFailure(false)
+ : m_byteCodeBytes(byteCodeBytes)
+ , m_totalCycles(0)
+ , m_parentPhaseEndSlop(0)
+ , m_timerFailure(false)
+#if MEASURE_CLRAPI_CALLS
+ , m_allClrAPIcalls(0)
+ , m_allClrAPIcycles(0)
+#endif
{
for (int i = 0; i < PHASE_NUMBER_OF; i++)
{
m_invokesByPhase[i] = 0;
m_cyclesByPhase[i] = 0;
+#if MEASURE_CLRAPI_CALLS
+ m_CLRinvokesByPhase[i] = 0;
+ m_CLRcyclesByPhase[i] = 0;
+#endif
}
+
+#if MEASURE_CLRAPI_CALLS
+ assert(ARRAYSIZE(m_perClrAPIcalls) == API_ICorJitInfo_Names::API_COUNT);
+ assert(ARRAYSIZE(m_perClrAPIcycles) == API_ICorJitInfo_Names::API_COUNT);
+ assert(ARRAYSIZE(m_maxClrAPIcycles) == API_ICorJitInfo_Names::API_COUNT);
+ for (int i = 0; i < API_ICorJitInfo_Names::API_COUNT; i++)
+ {
+ m_perClrAPIcalls[i] = 0;
+ m_perClrAPIcycles[i] = 0;
+ m_maxClrAPIcycles[i] = 0;
+ }
+#endif
}
bool CompTimeSummaryInfo::IncludedInFilteredData(CompTimeInfo& info)
@@ -6997,52 +7281,125 @@ bool CompTimeSummaryInfo::IncludedInFilteredData(CompTimeInfo& info)
return false; // info.m_byteCodeBytes < 10;
}
-void CompTimeSummaryInfo::AddInfo(CompTimeInfo& info)
+//------------------------------------------------------------------------
+// CompTimeSummaryInfo::AddInfo: Record timing info from one compile.
+//
+// Arguments:
+// info - The timing information to record.
+// includePhases - If "true", the per-phase info in "info" is valid,
+// which means that a "normal" compile has ended; if
+// the value is "false" we are recording the results
+// of a partial compile (typically an import-only run
+// on behalf of the inliner) in which case the phase
+// info is not valid and so we only record EE call
+// overhead.
+void CompTimeSummaryInfo::AddInfo(CompTimeInfo& info, bool includePhases)
{
if (info.m_timerFailure)
+ {
return; // Don't update if there was a failure.
+ }
CritSecHolder timeLock(s_compTimeSummaryLock);
- m_numMethods++;
- bool includeInFiltered = IncludedInFilteredData(info);
+ if (includePhases)
+ {
+ bool includeInFiltered = IncludedInFilteredData(info);
- // Update the totals and maxima.
- m_total.m_byteCodeBytes += info.m_byteCodeBytes;
- m_maximum.m_byteCodeBytes = max(m_maximum.m_byteCodeBytes, info.m_byteCodeBytes);
- m_total.m_totalCycles += info.m_totalCycles;
- m_maximum.m_totalCycles = max(m_maximum.m_totalCycles, info.m_totalCycles);
+ m_numMethods++;
- if (includeInFiltered)
- {
- m_numFilteredMethods++;
- m_filtered.m_byteCodeBytes += info.m_byteCodeBytes;
- m_filtered.m_totalCycles += info.m_totalCycles;
- m_filtered.m_parentPhaseEndSlop += info.m_parentPhaseEndSlop;
- }
+ // Update the totals and maxima.
+ m_total.m_byteCodeBytes += info.m_byteCodeBytes;
+ m_maximum.m_byteCodeBytes = max(m_maximum.m_byteCodeBytes, info.m_byteCodeBytes);
+ m_total.m_totalCycles += info.m_totalCycles;
+ m_maximum.m_totalCycles = max(m_maximum.m_totalCycles, info.m_totalCycles);
+
+#if MEASURE_CLRAPI_CALLS
+ // Update the CLR-API values.
+ m_total.m_allClrAPIcalls += info.m_allClrAPIcalls;
+ m_maximum.m_allClrAPIcalls = max(m_maximum.m_allClrAPIcalls, info.m_allClrAPIcalls);
+ m_total.m_allClrAPIcycles += info.m_allClrAPIcycles;
+ m_maximum.m_allClrAPIcycles = max(m_maximum.m_allClrAPIcycles, info.m_allClrAPIcycles);
+#endif
- for (int i = 0; i < PHASE_NUMBER_OF; i++)
- {
- m_total.m_invokesByPhase[i] += info.m_invokesByPhase[i];
- m_total.m_cyclesByPhase[i] += info.m_cyclesByPhase[i];
if (includeInFiltered)
{
- m_filtered.m_invokesByPhase[i] += info.m_invokesByPhase[i];
- m_filtered.m_cyclesByPhase[i] += info.m_cyclesByPhase[i];
+ m_numFilteredMethods++;
+ m_filtered.m_byteCodeBytes += info.m_byteCodeBytes;
+ m_filtered.m_totalCycles += info.m_totalCycles;
+ m_filtered.m_parentPhaseEndSlop += info.m_parentPhaseEndSlop;
+ }
+
+ for (int i = 0; i < PHASE_NUMBER_OF; i++)
+ {
+ m_total.m_invokesByPhase[i] += info.m_invokesByPhase[i];
+ m_total.m_cyclesByPhase[i] += info.m_cyclesByPhase[i];
+
+#if MEASURE_CLRAPI_CALLS
+ m_total.m_CLRinvokesByPhase[i] += info.m_CLRinvokesByPhase[i];
+ m_total.m_CLRcyclesByPhase[i] += info.m_CLRcyclesByPhase[i];
+#endif
+
+ if (includeInFiltered)
+ {
+ m_filtered.m_invokesByPhase[i] += info.m_invokesByPhase[i];
+ m_filtered.m_cyclesByPhase[i] += info.m_cyclesByPhase[i];
+#if MEASURE_CLRAPI_CALLS
+ m_filtered.m_CLRinvokesByPhase[i] += info.m_CLRinvokesByPhase[i];
+ m_filtered.m_CLRcyclesByPhase[i] += info.m_CLRcyclesByPhase[i];
+#endif
+ }
+ m_maximum.m_cyclesByPhase[i] = max(m_maximum.m_cyclesByPhase[i], info.m_cyclesByPhase[i]);
+
+#if MEASURE_CLRAPI_CALLS
+ m_maximum.m_CLRcyclesByPhase[i] = max(m_maximum.m_CLRcyclesByPhase[i], info.m_CLRcyclesByPhase[i]);
+#endif
}
- m_maximum.m_cyclesByPhase[i] = max(m_maximum.m_cyclesByPhase[i], info.m_cyclesByPhase[i]);
+ m_total.m_parentPhaseEndSlop += info.m_parentPhaseEndSlop;
+ m_maximum.m_parentPhaseEndSlop = max(m_maximum.m_parentPhaseEndSlop, info.m_parentPhaseEndSlop);
+ }
+#if MEASURE_CLRAPI_CALLS
+ else
+ {
+ m_totMethods++;
+
+ // Update the "global" CLR-API values.
+ m_total.m_allClrAPIcalls += info.m_allClrAPIcalls;
+ m_maximum.m_allClrAPIcalls = max(m_maximum.m_allClrAPIcalls, info.m_allClrAPIcalls);
+ m_total.m_allClrAPIcycles += info.m_allClrAPIcycles;
+ m_maximum.m_allClrAPIcycles = max(m_maximum.m_allClrAPIcycles, info.m_allClrAPIcycles);
+
+ // Update the per-phase CLR-API values.
+ m_total.m_invokesByPhase[PHASE_CLR_API] += info.m_allClrAPIcalls;
+ m_maximum.m_invokesByPhase[PHASE_CLR_API] =
+ max(m_maximum.m_perClrAPIcalls[PHASE_CLR_API], info.m_allClrAPIcalls);
+ m_total.m_cyclesByPhase[PHASE_CLR_API] += info.m_allClrAPIcycles;
+ m_maximum.m_cyclesByPhase[PHASE_CLR_API] =
+ max(m_maximum.m_cyclesByPhase[PHASE_CLR_API], info.m_allClrAPIcycles);
+ }
+
+ for (int i = 0; i < API_ICorJitInfo_Names::API_COUNT; i++)
+ {
+ m_total.m_perClrAPIcalls[i] += info.m_perClrAPIcalls[i];
+ m_maximum.m_perClrAPIcalls[i] = max(m_maximum.m_perClrAPIcalls[i], info.m_perClrAPIcalls[i]);
+
+ m_total.m_perClrAPIcycles[i] += info.m_perClrAPIcycles[i];
+ m_maximum.m_perClrAPIcycles[i] = max(m_maximum.m_perClrAPIcycles[i], info.m_perClrAPIcycles[i]);
+
+ m_maximum.m_maxClrAPIcycles[i] = max(m_maximum.m_maxClrAPIcycles[i], info.m_maxClrAPIcycles[i]);
}
- m_total.m_parentPhaseEndSlop += info.m_parentPhaseEndSlop;
- m_maximum.m_parentPhaseEndSlop = max(m_maximum.m_parentPhaseEndSlop, info.m_parentPhaseEndSlop);
+#endif
}
// Static
-LPCWSTR Compiler::compJitTimeLogFilename = NULL;
+LPCWSTR Compiler::compJitTimeLogFilename = nullptr;
void CompTimeSummaryInfo::Print(FILE* f)
{
- if (f == NULL)
+ if (f == nullptr)
+ {
return;
+ }
// Otherwise...
double countsPerSec = CycleTimer::CyclesPerSecond();
if (countsPerSec == 0.0)
@@ -7051,13 +7408,16 @@ void CompTimeSummaryInfo::Print(FILE* f)
return;
}
+ bool extraInfo = (JitConfig.JitEECallTimingInfo() != 0);
+ double totTime_ms = 0.0;
+
fprintf(f, "JIT Compilation time report:\n");
fprintf(f, " Compiled %d methods.\n", m_numMethods);
if (m_numMethods != 0)
{
fprintf(f, " Compiled %d bytecodes total (%d max, %8.2f avg).\n", m_total.m_byteCodeBytes,
m_maximum.m_byteCodeBytes, (double)m_total.m_byteCodeBytes / (double)m_numMethods);
- double totTime_ms = ((double)m_total.m_totalCycles / countsPerSec) * 1000.0;
+ totTime_ms = ((double)m_total.m_totalCycles / countsPerSec) * 1000.0;
fprintf(f, " Time: total: %10.3f Mcycles/%10.3f ms\n", ((double)m_total.m_totalCycles / 1000000.0),
totTime_ms);
fprintf(f, " max: %10.3f Mcycles/%10.3f ms\n", ((double)m_maximum.m_totalCycles) / 1000000.0,
@@ -7065,15 +7425,36 @@ void CompTimeSummaryInfo::Print(FILE* f)
fprintf(f, " avg: %10.3f Mcycles/%10.3f ms\n",
((double)m_total.m_totalCycles) / 1000000.0 / (double)m_numMethods, totTime_ms / (double)m_numMethods);
- fprintf(f, " Total time by phases:\n");
- fprintf(f, " PHASE inv/meth Mcycles time (ms) %% of total max (ms)\n");
- fprintf(f, " --------------------------------------------------------------------------------------\n");
+ const char* extraHdr1 = "";
+ const char* extraHdr2 = "";
+#if MEASURE_CLRAPI_CALLS
+ if (extraInfo)
+ {
+ extraHdr1 = " CLRs/meth % in CLR";
+ extraHdr2 = "-----------------------";
+ }
+#endif
+
+ fprintf(f, "\n Total time by phases:\n");
+ fprintf(f, " PHASE inv/meth Mcycles time (ms) %% of total max (ms)%s\n",
+ extraHdr1);
+ fprintf(f, " ---------------------------------------------------------------------------------------%s\n",
+ extraHdr2);
+
// Ensure that at least the names array and the Phases enum have the same number of entries:
assert(sizeof(PhaseNames) / sizeof(const char*) == PHASE_NUMBER_OF);
for (int i = 0; i < PHASE_NUMBER_OF; i++)
{
- double phase_tot_ms = (((double)m_total.m_cyclesByPhase[i]) / countsPerSec) * 1000.0;
- double phase_max_ms = (((double)m_maximum.m_cyclesByPhase[i]) / countsPerSec) * 1000.0;
+ double phase_tot_ms = (((double)m_total.m_cyclesByPhase[i]) / countsPerSec) * 1000.0;
+ double phase_max_ms = (((double)m_maximum.m_cyclesByPhase[i]) / countsPerSec) * 1000.0;
+ double phase_tot_pct = 100.0 * phase_tot_ms / totTime_ms;
+
+#if MEASURE_CLRAPI_CALLS
+ // Skip showing CLR API call info if we didn't collect any
+ if (i == PHASE_CLR_API && !extraInfo)
+ continue;
+#endif
+
// Indent nested phases, according to depth.
int ancPhase = PhaseParent[i];
while (ancPhase != -1)
@@ -7081,13 +7462,33 @@ void CompTimeSummaryInfo::Print(FILE* f)
fprintf(f, " ");
ancPhase = PhaseParent[ancPhase];
}
- fprintf(f, " %-30s %5.2f %10.2f %9.3f %8.2f%% %8.3f\n", PhaseNames[i],
+ fprintf(f, " %-30s %6.2f %10.2f %9.3f %8.2f%% %8.3f", PhaseNames[i],
((double)m_total.m_invokesByPhase[i]) / ((double)m_numMethods),
((double)m_total.m_cyclesByPhase[i]) / 1000000.0, phase_tot_ms, (phase_tot_ms * 100.0 / totTime_ms),
phase_max_ms);
+
+#if MEASURE_CLRAPI_CALLS
+ if (extraInfo && i != PHASE_CLR_API)
+ {
+ double nest_tot_ms = (((double)m_total.m_CLRcyclesByPhase[i]) / countsPerSec) * 1000.0;
+ double nest_percent = nest_tot_ms * 100.0 / totTime_ms;
+ double calls_per_fn = ((double)m_total.m_CLRinvokesByPhase[i]) / ((double)m_numMethods);
+
+ if (nest_percent > 0.1 || calls_per_fn > 10)
+ fprintf(f, " %5.1f %8.2f%%", calls_per_fn, nest_percent);
+ }
+#endif
+ fprintf(f, "\n");
+ }
+
+ // Show slop if it's over a certain percentage of the total
+ double pslop_pct = 100.0 * m_total.m_parentPhaseEndSlop * 1000.0 / countsPerSec / totTime_ms;
+ if (pslop_pct >= 1.0)
+ {
+ fprintf(f, "\n 'End phase slop' should be very small (if not, there's unattributed time): %9.3f Mcycles = "
+ "%3.1f%% of total.\n\n",
+ m_total.m_parentPhaseEndSlop / 1000000.0, pslop_pct);
}
- fprintf(f, "\n 'End phase slop' should be very small (if not, there's unattributed time): %9.3f Mcycles.\n",
- m_total.m_parentPhaseEndSlop);
}
if (m_numFilteredMethods > 0)
{
@@ -7121,19 +7522,125 @@ void CompTimeSummaryInfo::Print(FILE* f)
((double)m_filtered.m_cyclesByPhase[i]) / 1000000.0, phase_tot_ms,
(phase_tot_ms * 100.0 / totTime_ms));
}
- fprintf(f, "\n 'End phase slop' should be very small (if not, there's unattributed time): %9.3f Mcycles.\n",
- m_filtered.m_parentPhaseEndSlop);
+
+ double fslop_ms = m_filtered.m_parentPhaseEndSlop * 1000.0 / countsPerSec;
+ if (fslop_ms > 1.0)
+ {
+ fprintf(f,
+ "\n 'End phase slop' should be very small (if not, there's unattributed time): %9.3f Mcycles.\n",
+ m_filtered.m_parentPhaseEndSlop);
+ }
}
+
+#if MEASURE_CLRAPI_CALLS
+ if (m_total.m_allClrAPIcalls > 0 && m_total.m_allClrAPIcycles > 0)
+ {
+ fprintf(f, "\n");
+ if (m_totMethods > 0)
+ fprintf(f, " Imported %u methods.\n\n", m_numMethods + m_totMethods);
+
+ fprintf(f, " CLR API # calls total time max time avg time %% "
+ "of total\n");
+ fprintf(f, " -------------------------------------------------------------------------------");
+ fprintf(f, "---------------------\n");
+
+ static const char* APInames[] = {
+#define DEF_CLR_API(name) #name,
+#include "ICorJitInfo_API_names.h"
+ };
+
+ unsigned shownCalls = 0;
+ double shownMillis = 0.0;
+#ifdef DEBUG
+ unsigned checkedCalls = 0;
+ double checkedMillis = 0.0;
+#endif
+
+ for (unsigned pass = 0; pass < 2; pass++)
+ {
+ for (unsigned i = 0; i < API_ICorJitInfo_Names::API_COUNT; i++)
+ {
+ unsigned calls = m_total.m_perClrAPIcalls[i];
+ if (calls == 0)
+ continue;
+
+ unsigned __int64 cycles = m_total.m_perClrAPIcycles[i];
+ double millis = 1000.0 * cycles / countsPerSec;
+
+ // Don't show the small fry to keep the results manageable
+ if (millis < 0.5)
+ {
+ // We always show the following API because it is always called
+ // exactly once for each method and its body is the simplest one
+ // possible (it just returns an integer constant), and therefore
+ // it can be used to measure the overhead of adding the CLR API
+ // timing code. Roughly speaking, on a 3GHz x64 box the overhead
+ // per call should be around 40 ns when using RDTSC, compared to
+ // about 140 ns when using GetThreadCycles() under Windows.
+ if (i != API_ICorJitInfo_Names::API_getExpectedTargetArchitecture)
+ continue;
+ }
+
+ // In the first pass we just compute the totals.
+ if (pass == 0)
+ {
+ shownCalls += m_total.m_perClrAPIcalls[i];
+ shownMillis += millis;
+ continue;
+ }
+
+ unsigned __int32 maxcyc = m_maximum.m_maxClrAPIcycles[i];
+ double max_ms = 1000.0 * maxcyc / countsPerSec;
+
+ fprintf(f, " %-40s", APInames[i]); // API name
+ fprintf(f, " %8u %9.1f ms", calls, millis); // #calls, total time
+ fprintf(f, " %8.1f ms %8.1f ns", max_ms, 1000000.0 * millis / calls); // max, avg time
+ fprintf(f, " %5.1f%%\n", 100.0 * millis / shownMillis); // % of total
+
+#ifdef DEBUG
+ checkedCalls += m_total.m_perClrAPIcalls[i];
+ checkedMillis += millis;
+#endif
+ }
+ }
+
+#ifdef DEBUG
+ assert(checkedCalls == shownCalls);
+ assert(checkedMillis == shownMillis);
+#endif
+
+ if (shownCalls > 0 || shownMillis > 0)
+ {
+ fprintf(f, " -------------------------");
+ fprintf(f, "---------------------------------------------------------------------------\n");
+ fprintf(f, " Total for calls shown above %8u %10.1f ms", shownCalls, shownMillis);
+ if (totTime_ms > 0.0)
+ fprintf(f, " (%4.1lf%% of overall JIT time)", shownMillis * 100.0 / totTime_ms);
+ fprintf(f, "\n");
+ }
+ fprintf(f, "\n");
+ }
+#endif
+
+ fprintf(f, "\n");
}
JitTimer::JitTimer(unsigned byteCodeSize) : m_info(byteCodeSize)
{
+#if MEASURE_CLRAPI_CALLS
+ m_CLRcallInvokes = 0;
+ m_CLRcallCycles = 0;
+#endif
+
#ifdef DEBUG
m_lastPhase = (Phases)-1;
+#if MEASURE_CLRAPI_CALLS
+ m_CLRcallAPInum = -1;
+#endif
#endif
unsigned __int64 threadCurCycles;
- if (GetThreadCycles(&threadCurCycles))
+ if (_our_GetThreadCycles(&threadCurCycles))
{
m_start = threadCurCycles;
m_curPhaseStart = threadCurCycles;
@@ -7147,9 +7654,10 @@ void JitTimer::EndPhase(Phases phase)
// assert((int)phase > (int)m_lastPhase); // We should end phases in increasing order.
unsigned __int64 threadCurCycles;
- if (GetThreadCycles(&threadCurCycles))
+ if (_our_GetThreadCycles(&threadCurCycles))
{
unsigned __int64 phaseCycles = (threadCurCycles - m_curPhaseStart);
+
// If this is not a leaf phase, the assumption is that the last subphase must have just recently ended.
// Credit the duration to "slop", the total of which should be very small.
if (PhaseHasChildren[phase])
@@ -7161,6 +7669,13 @@ void JitTimer::EndPhase(Phases phase)
// It is a leaf phase. Credit duration to it.
m_info.m_invokesByPhase[phase]++;
m_info.m_cyclesByPhase[phase] += phaseCycles;
+
+#if MEASURE_CLRAPI_CALLS
+ // Record the CLR API timing info as well.
+ m_info.m_CLRinvokesByPhase[phase] += m_CLRcallInvokes;
+ m_info.m_CLRcyclesByPhase[phase] += m_CLRcallCycles;
+#endif
+
// Credit the phase's ancestors, if any.
int ancPhase = PhaseParent[phase];
while (ancPhase != -1)
@@ -7168,8 +7683,13 @@ void JitTimer::EndPhase(Phases phase)
m_info.m_cyclesByPhase[ancPhase] += phaseCycles;
ancPhase = PhaseParent[ancPhase];
}
- // Did we just end the last phase?
- if (phase + 1 == PHASE_NUMBER_OF)
+
+#if MEASURE_CLRAPI_CALLS
+ const Phases lastPhase = PHASE_CLR_API;
+#else
+ const Phases lastPhase = PHASE_NUMBER_OF;
+#endif
+ if (phase + 1 == lastPhase)
{
m_info.m_totalCycles = (threadCurCycles - m_start);
}
@@ -7179,11 +7699,92 @@ void JitTimer::EndPhase(Phases phase)
}
}
}
+
#ifdef DEBUG
m_lastPhase = phase;
#endif
+#if MEASURE_CLRAPI_CALLS
+ m_CLRcallInvokes = 0;
+ m_CLRcallCycles = 0;
+#endif
+}
+
+#if MEASURE_CLRAPI_CALLS
+
+//------------------------------------------------------------------------
+// JitTimer::CLRApiCallEnter: Start the stopwatch for an EE call.
+//
+// Arguments:
+// apix - The API index - an "enum API_ICorJitInfo_Names" value.
+//
+
+void JitTimer::CLRApiCallEnter(unsigned apix)
+{
+ assert(m_CLRcallAPInum == -1); // Nested calls not allowed
+ m_CLRcallAPInum = apix;
+
+ // If we can't get the cycles, we'll just ignore this call
+ if (!_our_GetThreadCycles(&m_CLRcallStart))
+ m_CLRcallStart = 0;
+}
+
+//------------------------------------------------------------------------
+// JitTimer::CLRApiCallLeave: compute / record time spent in an EE call.
+//
+// Arguments:
+// apix - The API's "enum API_ICorJitInfo_Names" value; this value
+// should match the value passed to the most recent call to
+// "CLRApiCallEnter" (i.e. these must come as matched pairs),
+// and they also may not nest.
+//
+
+void JitTimer::CLRApiCallLeave(unsigned apix)
+{
+ // Make sure we're actually inside a measured CLR call.
+ assert(m_CLRcallAPInum != -1);
+ m_CLRcallAPInum = -1;
+
+ // Ignore this one if we don't have a valid starting counter.
+ if (m_CLRcallStart != 0)
+ {
+ if (JitConfig.JitEECallTimingInfo() != 0)
+ {
+ unsigned __int64 threadCurCycles;
+ if (_our_GetThreadCycles(&threadCurCycles))
+ {
+ // Compute the cycles spent in the call.
+ threadCurCycles -= m_CLRcallStart;
+
+ // Add the cycles to the 'phase' and bump its use count.
+ m_info.m_cyclesByPhase[PHASE_CLR_API] += threadCurCycles;
+ m_info.m_invokesByPhase[PHASE_CLR_API] += 1;
+
+ // Add the values to the "per API" info.
+ m_info.m_allClrAPIcycles += threadCurCycles;
+ m_info.m_allClrAPIcalls += 1;
+
+ m_info.m_perClrAPIcalls[apix] += 1;
+ m_info.m_perClrAPIcycles[apix] += threadCurCycles;
+ m_info.m_maxClrAPIcycles[apix] = max(m_info.m_maxClrAPIcycles[apix], (unsigned __int32)threadCurCycles);
+
+ // Subtract the cycles from the enclosing phase by bumping its start time
+ m_curPhaseStart += threadCurCycles;
+
+ // Update the running totals.
+ m_CLRcallInvokes += 1;
+ m_CLRcallCycles += threadCurCycles;
+ }
+ }
+
+ m_CLRcallStart = 0;
+ }
+
+ assert(m_CLRcallAPInum != -1); // No longer in this API call.
+ m_CLRcallAPInum = -1;
}
+#endif // MEASURE_CLRAPI_CALLS
+
CritSecObject JitTimer::s_csvLock;
LPCWSTR Compiler::JitTimeLogCsv()
@@ -7195,39 +7796,38 @@ LPCWSTR Compiler::JitTimeLogCsv()
void JitTimer::PrintCsvHeader()
{
LPCWSTR jitTimeLogCsv = Compiler::JitTimeLogCsv();
- if (jitTimeLogCsv == NULL)
+ if (jitTimeLogCsv == nullptr)
{
return;
}
CritSecHolder csvLock(s_csvLock);
- FILE* fp = _wfopen(jitTimeLogCsv, W("r"));
- if (fp == nullptr)
+ FILE* fp = _wfopen(jitTimeLogCsv, W("a"));
+ if (fp != nullptr)
{
- // File doesn't exist, so create it and write the header
-
- // Use write mode, so we rewrite the file, and retain only the last compiled process/dll.
- // Ex: ngen install mscorlib won't print stats for "ngen" but for "mscorsvw"
- FILE* fp = _wfopen(jitTimeLogCsv, W("w"));
- fprintf(fp, "\"Method Name\",");
- fprintf(fp, "\"Method Index\",");
- fprintf(fp, "\"IL Bytes\",");
- fprintf(fp, "\"Basic Blocks\",");
- fprintf(fp, "\"Opt Level\",");
- fprintf(fp, "\"Loops Cloned\",");
-
- for (int i = 0; i < PHASE_NUMBER_OF; i++)
+ // Write the header if the file is empty
+ if (ftell(fp) == 0)
{
- fprintf(fp, "\"%s\",", PhaseNames[i]);
- }
+ fprintf(fp, "\"Method Name\",");
+ fprintf(fp, "\"Method Index\",");
+ fprintf(fp, "\"IL Bytes\",");
+ fprintf(fp, "\"Basic Blocks\",");
+ fprintf(fp, "\"Opt Level\",");
+ fprintf(fp, "\"Loops Cloned\",");
- InlineStrategy::DumpCsvHeader(fp);
+ for (int i = 0; i < PHASE_NUMBER_OF; i++)
+ {
+ fprintf(fp, "\"%s\",", PhaseNames[i]);
+ }
- fprintf(fp, "\"Total Cycles\",");
- fprintf(fp, "\"CPS\"\n");
+ InlineStrategy::DumpCsvHeader(fp);
+
+ fprintf(fp, "\"Total Cycles\",");
+ fprintf(fp, "\"CPS\"\n");
+ }
+ fclose(fp);
}
- fclose(fp);
}
extern ICorJitHost* g_jitHost;
@@ -7235,7 +7835,7 @@ extern ICorJitHost* g_jitHost;
void JitTimer::PrintCsvMethodStats(Compiler* comp)
{
LPCWSTR jitTimeLogCsv = Compiler::JitTimeLogCsv();
- if (jitTimeLogCsv == NULL)
+ if (jitTimeLogCsv == nullptr)
{
return;
}
@@ -7265,7 +7865,9 @@ void JitTimer::PrintCsvMethodStats(Compiler* comp)
for (int i = 0; i < PHASE_NUMBER_OF; i++)
{
if (!PhaseHasChildren[i])
+ {
totCycles += m_info.m_cyclesByPhase[i];
+ }
fprintf(fp, "%I64u,", m_info.m_cyclesByPhase[i]);
}
@@ -7277,23 +7879,14 @@ void JitTimer::PrintCsvMethodStats(Compiler* comp)
}
// Completes the timing of the current method, and adds it to "sum".
-void JitTimer::Terminate(Compiler* comp, CompTimeSummaryInfo& sum)
+void JitTimer::Terminate(Compiler* comp, CompTimeSummaryInfo& sum, bool includePhases)
{
-#ifdef DEBUG
- unsigned __int64 totCycles2 = 0;
- for (int i = 0; i < PHASE_NUMBER_OF; i++)
+ if (includePhases)
{
- if (!PhaseHasChildren[i])
- totCycles2 += m_info.m_cyclesByPhase[i];
+ PrintCsvMethodStats(comp);
}
- // We include m_parentPhaseEndSlop in the next phase's time also (we probably shouldn't)
- // totCycles2 += m_info.m_parentPhaseEndSlop;
- assert(totCycles2 == m_info.m_totalCycles);
-#endif
-
- PrintCsvMethodStats(comp);
- sum.AddInfo(m_info);
+ sum.AddInfo(m_info, includePhases);
}
#endif // FEATURE_JIT_METHOD_PERF
@@ -7331,6 +7924,10 @@ void Compiler::MemStats::PrintByKind(FILE* f)
void Compiler::AggregateMemStats::Print(FILE* f)
{
fprintf(f, "For %9u methods:\n", nMethods);
+ if (nMethods == 0)
+ {
+ return;
+ }
fprintf(f, " count: %12u (avg %7u per method)\n", allocCnt, allocCnt / nMethods);
fprintf(f, " alloc size : %12llu (avg %7llu per method)\n", allocSz, allocSz / nMethods);
fprintf(f, " max alloc : %12llu\n", allocSzMax);
@@ -8520,6 +9117,9 @@ int cTreeFlagsIR(Compiler* comp, GenTree* tree)
break;
case GT_MUL:
+#if defined(_TARGET_X86_) && !defined(LEGACY_BACKEND)
+ case GT_MUL_LONG:
+#endif
if (tree->gtFlags & GTF_MUL_64RSLT)
{
@@ -10124,11 +10724,6 @@ void cNodeIR(Compiler* comp, GenTree* tree)
}
break;
- case GT_STORE_CLS_VAR:
-
- chars += printf(" ???");
- break;
-
case GT_LEA:
GenTreeAddrMode* lea = tree->AsAddrMode();
diff --git a/src/jit/compiler.h b/src/jit/compiler.h
index 05047c5ecb..d8cd491063 100644
--- a/src/jit/compiler.h
+++ b/src/jit/compiler.h
@@ -691,12 +691,21 @@ public:
// is now TYP_INT in the local variable table. It's not really unused, because it's in the tree.
assert(varTypeIsStruct(lvType) || (lvType == TYP_BLK) || (lvPromoted && lvUnusedStruct));
+
+#if defined(FEATURE_SIMD) && !defined(_TARGET_64BIT_)
+ // For 32-bit architectures, we make local variable SIMD12 types 16 bytes instead of just 12. We can't do
+ // this for arguments, which must be passed according the defined ABI.
+ if ((lvType == TYP_SIMD12) && !lvIsParam)
+ {
+ assert(lvExactSize == 12);
+ return 16;
+ }
+#endif // defined(FEATURE_SIMD) && !defined(_TARGET_64BIT_)
+
return (unsigned)(roundUp(lvExactSize, TARGET_POINTER_SIZE));
}
-#if defined(DEBUGGING_SUPPORT) || defined(DEBUG)
unsigned lvSlotNum; // original slot # (if remapped)
-#endif
typeInfo lvVerTypeInfo; // type info needed for verification
@@ -926,6 +935,14 @@ extern const char* PhaseNames[];
extern const char* PhaseEnums[];
extern const LPCWSTR PhaseShortNames[];
+// The following enum provides a simple 1:1 mapping to CLR API's
+enum API_ICorJitInfo_Names
+{
+#define DEF_CLR_API(name) API_##name,
+#include "ICorJitInfo_API_names.h"
+ API_COUNT
+};
+
//---------------------------------------------------------------
// Compilation time.
//
@@ -949,6 +966,10 @@ struct CompTimeInfo
unsigned __int64 m_totalCycles;
unsigned __int64 m_invokesByPhase[PHASE_NUMBER_OF];
unsigned __int64 m_cyclesByPhase[PHASE_NUMBER_OF];
+#if MEASURE_CLRAPI_CALLS
+ unsigned __int64 m_CLRinvokesByPhase[PHASE_NUMBER_OF];
+ unsigned __int64 m_CLRcyclesByPhase[PHASE_NUMBER_OF];
+#endif
// 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
@@ -960,12 +981,25 @@ struct CompTimeInfo
unsigned __int64 m_parentPhaseEndSlop;
bool m_timerFailure;
+#if MEASURE_CLRAPI_CALLS
+ // The following measures the time spent inside each individual CLR API call.
+ unsigned m_allClrAPIcalls;
+ unsigned m_perClrAPIcalls[API_ICorJitInfo_Names::API_COUNT];
+ unsigned __int64 m_allClrAPIcycles;
+ unsigned __int64 m_perClrAPIcycles[API_ICorJitInfo_Names::API_COUNT];
+ unsigned __int32 m_maxClrAPIcycles[API_ICorJitInfo_Names::API_COUNT];
+#endif // MEASURE_CLRAPI_CALLS
+
CompTimeInfo(unsigned byteCodeBytes);
#endif
};
#ifdef FEATURE_JIT_METHOD_PERF
+#if MEASURE_CLRAPI_CALLS
+struct WrapICorJitInfo;
+#endif
+
// This class summarizes the JIT time information over the course of a run: the number of methods compiled,
// and the total and maximum timings. (These are instances of the "CompTimeInfo" type described above).
// The operation of adding a single method's timing to the summary may be performed concurrently by several
@@ -977,6 +1011,7 @@ class CompTimeSummaryInfo
static CritSecObject s_compTimeSummaryLock;
int m_numMethods;
+ int m_totMethods;
CompTimeInfo m_total;
CompTimeInfo m_maximum;
@@ -996,13 +1031,14 @@ public:
// This is the unique CompTimeSummaryInfo object for this instance of the runtime.
static CompTimeSummaryInfo s_compTimeSummary;
- CompTimeSummaryInfo() : m_numMethods(0), m_total(0), m_maximum(0), m_numFilteredMethods(0), m_filtered(0)
+ CompTimeSummaryInfo()
+ : m_numMethods(0), m_totMethods(0), m_total(0), m_maximum(0), m_numFilteredMethods(0), m_filtered(0)
{
}
// Assumes that "info" is a completed CompTimeInfo for a compilation; adds it to the summary.
// This is thread safe.
- void AddInfo(CompTimeInfo& info);
+ void AddInfo(CompTimeInfo& info, bool includePhases);
// Print the summary information to "f".
// This is not thread-safe; assumed to be called by only one thread.
@@ -1017,6 +1053,13 @@ class JitTimer
{
unsigned __int64 m_start; // Start of the compilation.
unsigned __int64 m_curPhaseStart; // Start of the current phase.
+#if MEASURE_CLRAPI_CALLS
+ unsigned __int64 m_CLRcallStart; // Start of the current CLR API call (if any).
+ unsigned __int64 m_CLRcallInvokes; // CLR API invokes under current outer so far
+ unsigned __int64 m_CLRcallCycles; // CLR API cycles under current outer so far.
+ int m_CLRcallAPInum; // The enum/index of the current CLR API call (or -1).
+ static double s_cyclesPerSec; // Cached for speedier measurements
+#endif
#ifdef DEBUG
Phases m_lastPhase; // The last phase that was completed (or (Phases)-1 to start).
#endif
@@ -1045,9 +1088,15 @@ public:
// Ends the current phase (argument is for a redundant check).
void EndPhase(Phases phase);
+#if MEASURE_CLRAPI_CALLS
+ // Start and end a timed CLR API call.
+ void CLRApiCallEnter(unsigned apix);
+ void CLRApiCallLeave(unsigned apix);
+#endif // MEASURE_CLRAPI_CALLS
+
// Completes the timing of the current method, which is assumed to have "byteCodeBytes" bytes of bytecode,
// and adds it to "sum".
- void Terminate(Compiler* comp, CompTimeSummaryInfo& sum);
+ void Terminate(Compiler* comp, CompTimeSummaryInfo& sum, bool includePhases);
// Attempts to query the cycle counter of the current thread. If successful, returns "true" and sets
// *cycles to the cycle counter value. Otherwise, returns false and sets the "m_timerFailure" flag of
@@ -1164,7 +1213,13 @@ struct fgArgTabEntry
regNumber otherRegNum; // The (second) register to use when passing this argument.
SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR structDesc;
-#endif // defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
+#elif defined(_TARGET_X86_)
+ __declspec(property(get = getIsStruct)) bool isStruct;
+ bool getIsStruct()
+ {
+ return varTypeIsStruct(node);
+ }
+#endif // _TARGET_X86_
#ifdef _TARGET_ARM_
void SetIsHfaRegArg(bool hfaRegArg)
@@ -1293,6 +1348,10 @@ public:
{
return hasStackArgs;
}
+ bool AreArgsComplete() const
+ {
+ return argsComplete;
+ }
};
#ifdef DEBUG
@@ -1939,8 +1998,6 @@ public:
GenTreeArgList* gtNewArgList(GenTreePtr op1, GenTreePtr op2);
GenTreeArgList* gtNewArgList(GenTreePtr op1, GenTreePtr op2, GenTreePtr op3);
- GenTreeArgList* gtNewAggregate(GenTree* element);
-
static fgArgTabEntryPtr gtArgEntryByArgNum(GenTreePtr call, unsigned argNum);
static fgArgTabEntryPtr gtArgEntryByNode(GenTreePtr call, GenTreePtr node);
fgArgTabEntryPtr gtArgEntryByLateArgIndex(GenTreePtr call, unsigned lateArgInx);
@@ -1975,7 +2032,18 @@ public:
GenTreePtr gtClone(GenTree* tree, bool complexOK = false);
- GenTreePtr gtCloneExpr(GenTree* tree, unsigned addFlags = 0, unsigned varNum = (unsigned)-1, int varVal = 0);
+ // If `tree` is a lclVar with lclNum `varNum`, return an IntCns with value `varVal`; otherwise,
+ // create a copy of `tree`, adding specified flags, replacing uses of lclVar `deepVarNum` with
+ // IntCnses with value `deepVarVal`.
+ GenTreePtr gtCloneExpr(
+ GenTree* tree, unsigned addFlags, unsigned varNum, int varVal, unsigned deepVarNum, int deepVarVal);
+
+ // Create a copy of `tree`, optionally adding specifed flags, and optionally mapping uses of local
+ // `varNum` to int constants with value `varVal`.
+ GenTreePtr gtCloneExpr(GenTree* tree, unsigned addFlags = 0, unsigned varNum = (unsigned)-1, int varVal = 0)
+ {
+ return gtCloneExpr(tree, addFlags, varNum, varVal, varNum, varVal);
+ }
GenTreePtr gtReplaceTree(GenTreePtr stmt, GenTreePtr tree, GenTreePtr replacementTree);
@@ -1997,7 +2065,7 @@ public:
unsigned gtHashValue(GenTree* tree);
- unsigned gtSetListOrder(GenTree* list, bool regs);
+ unsigned gtSetListOrder(GenTree* list, bool regs, bool isListCallArgs);
void gtWalkOp(GenTree** op1, GenTree** op2, GenTree* adr, bool constOnly);
@@ -2277,7 +2345,8 @@ public:
DNER_VMNeedsStackAddr,
DNER_LiveInOutOfHandler,
DNER_LiveAcrossUnmanagedCall,
- DNER_BlockOp, // Is read or written via a block operation that explicitly takes the address.
+ DNER_BlockOp, // Is read or written via a block operation that explicitly takes the address.
+ DNER_IsStructArg, // Is a struct passed as an argument in a way that requires a stack location.
#ifdef JIT32_GCENCODER
DNER_PinningRef,
#endif
@@ -2439,7 +2508,6 @@ public:
void lvaInit();
- unsigned lvaArgSize(const void* argTok);
unsigned lvaLclSize(unsigned varNum);
unsigned lvaLclExactSize(unsigned varNum);
@@ -2712,9 +2780,10 @@ protected:
void impImportNewObjArray(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_CALL_INFO* pCallInfo);
- bool impCanPInvokeInline(var_types callRetTyp);
- bool impCanPInvokeInlineCallSite(var_types callRetTyp);
- void impCheckForPInvokeCall(GenTreePtr call, CORINFO_METHOD_HANDLE methHnd, CORINFO_SIG_INFO* sig, unsigned mflags);
+ bool impCanPInvokeInline(BasicBlock* block);
+ 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);
void impPopArgsForUnmanagedCall(GenTreePtr call, CORINFO_SIG_INFO* sig);
@@ -2739,8 +2808,6 @@ protected:
GenTreePtr impFixupCallStructReturn(GenTreePtr call, CORINFO_CLASS_HANDLE retClsHnd);
- GenTreePtr impInitCallLongReturn(GenTreePtr call);
-
GenTreePtr impFixupStructReturnType(GenTreePtr op, CORINFO_CLASS_HANDLE retClsHnd);
#ifdef DEBUG
@@ -2764,7 +2831,6 @@ protected:
void impImportLeave(BasicBlock* block);
void impResetLeaveBlock(BasicBlock* block, unsigned jmpAddr);
- BOOL impLocAllocOnStack();
GenTreePtr impIntrinsic(CORINFO_CLASS_HANDLE clsHnd,
CORINFO_METHOD_HANDLE method,
CORINFO_SIG_INFO* sig,
@@ -2868,6 +2934,8 @@ public:
unsigned flags,
void* compileTimeHandle);
+ GenTreePtr getRuntimeContextTree(CORINFO_RUNTIME_LOOKUP_KIND kind);
+
GenTreePtr impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken,
CORINFO_LOOKUP* pLookup,
void* compileTimeHandle);
@@ -3148,8 +3216,6 @@ private:
static LONG jitNestingLevel;
#endif // DEBUG
- bool seenConditionalJump;
-
static BOOL impIsAddressInLocal(GenTreePtr tree, GenTreePtr* lclVarTreeOut);
void impMakeDiscretionaryInlineObservations(InlineInfo* pInlineInfo, InlineResult* inlineResult);
@@ -3455,8 +3521,9 @@ public:
void fgMorphStmts(BasicBlock* block, bool* mult, bool* lnot, bool* loadw);
void fgMorphBlocks();
- bool fgMorphBlockStmt(BasicBlock* block, GenTreePtr stmt DEBUGARG(const char* msg));
+ bool fgMorphBlockStmt(BasicBlock* block, GenTreeStmt* stmt DEBUGARG(const char* msg));
+ void fgCheckArgCnt();
void fgSetOptions();
#ifdef DEBUG
@@ -3845,7 +3912,7 @@ public:
//
var_types getReturnTypeForStruct(CORINFO_CLASS_HANDLE clsHnd,
structPassingKind* wbPassStruct = nullptr,
- unsigned structSize = 0);
+ unsigned structSize = 0);
#ifdef DEBUG
// Print a representation of "vnp" or "vn" on standard output.
@@ -4072,7 +4139,7 @@ public:
void fgUnreachableBlock(BasicBlock* block);
- void fgRemoveJTrue(BasicBlock* block);
+ void fgRemoveConditionalJump(BasicBlock* block);
BasicBlock* fgLastBBInMainFunction();
@@ -4204,6 +4271,7 @@ public:
void fgDebugCheckLinks(bool morphTrees = false);
void fgDebugCheckNodeLinks(BasicBlock* block, GenTreePtr stmt);
void fgDebugCheckFlags(GenTreePtr tree);
+ void fgDebugCheckFlagsHelper(GenTreePtr tree, unsigned treeFlags, unsigned chkFlags);
#endif
#ifdef LEGACY_BACKEND
@@ -4305,7 +4373,7 @@ protected:
void fgLinkBasicBlocks();
- void fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, BYTE* jumpTarget);
+ unsigned fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, BYTE* jumpTarget);
void fgCheckBasicBlockControlFlow();
@@ -4380,13 +4448,6 @@ private:
GenTree* fgInsertCommaFormTemp(GenTree** ppTree, CORINFO_CLASS_HANDLE structType = nullptr);
GenTree* fgMakeMultiUse(GenTree** ppTree);
- // After replacing oldChild with newChild, fixup the fgArgTabEntryPtr
- // if it happens to be an argument to a call.
- void fgFixupIfCallArg(ArrayStack<GenTree*>* parentStack, GenTree* oldChild, GenTree* newChild);
-
-public:
- void fgFixupArgTabEntryPtr(GenTreePtr parentCall, GenTreePtr oldArg, GenTreePtr newArg);
-
private:
// Recognize a bitwise rotation pattern and convert into a GT_ROL or a GT_ROR node.
GenTreePtr fgRecognizeAndMorphBitwiseRotation(GenTreePtr tree);
@@ -4440,16 +4501,11 @@ private:
// for sufficiently small offsets, we can rely on OS page protection to implicitly null-check addresses that we
// know will be dereferenced. To know that reliance on implicit null checking is sound, we must further know that
// all offsets between the top-level indirection and the bottom are constant, and that their sum is sufficiently
- // small; hence the other fields of MorphAddrContext. Finally, the odd structure of GT_COPYBLK, in which the second
- // argument is a GT_LIST, requires us to "tell" that List node that its parent is a GT_COPYBLK, so it "knows" that
- // each of its arguments should be evaluated in MACK_Ind contexts. (This would not be true for GT_LIST nodes
- // representing method call argument lists.)
+ // small; hence the other fields of MorphAddrContext.
enum MorphAddrContextKind
{
MACK_Ind,
MACK_Addr,
- MACK_CopyBlock, // This is necessary so we know we have to start a new "Ind" context for each of the
- // addresses in the arg list.
};
struct MorphAddrContext
{
@@ -4513,7 +4569,7 @@ private:
void fgMorphCallInline(GenTreeCall* call, InlineResult* result);
void fgMorphCallInlineHelper(GenTreeCall* call, InlineResult* result);
#if DEBUG
- void fgNoteNonInlineCandidate(GenTreePtr tree, GenTreeCall* call);
+ void fgNoteNonInlineCandidate(GenTreeStmt* stmt, GenTreeCall* call);
static fgWalkPreFn fgFindNonInlineCandidate;
#endif
GenTreePtr fgOptimizeDelegateConstructor(GenTreePtr call, CORINFO_CONTEXT_HANDLE* ExactContextHnd);
@@ -4525,16 +4581,14 @@ private:
GenTreePtr fgMorphGetStructAddr(GenTreePtr* pTree, CORINFO_CLASS_HANDLE clsHnd, bool isRValue = false);
GenTreePtr fgMorphBlkNode(GenTreePtr tree, bool isDest);
GenTreePtr fgMorphBlockOperand(GenTreePtr tree, var_types asgType, unsigned blockWidth, bool isDest);
+ void fgMorphUnsafeBlk(GenTreeObj* obj);
GenTreePtr fgMorphCopyBlock(GenTreePtr tree);
GenTreePtr fgMorphForRegisterFP(GenTreePtr tree);
GenTreePtr fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac = nullptr);
GenTreePtr fgMorphSmpOpPre(GenTreePtr tree);
- GenTreePtr fgMorphDivByConst(GenTreeOp* tree);
- GenTreePtr fgMorphModByConst(GenTreeOp* tree);
GenTreePtr fgMorphModToSubMulDiv(GenTreeOp* tree);
GenTreePtr fgMorphSmpOpOptional(GenTreeOp* tree);
GenTreePtr fgMorphRecognizeBoxNullable(GenTree* compare);
- bool fgShouldUseMagicNumberDivide(GenTreeOp* tree);
GenTreePtr fgMorphToEmulatedFP(GenTreePtr tree);
GenTreePtr fgMorphConst(GenTreePtr tree);
@@ -4544,11 +4598,12 @@ public:
private:
#if LOCAL_ASSERTION_PROP
+ void fgKillDependentAssertionsSingle(unsigned lclNum DEBUGARG(GenTreePtr tree));
void fgKillDependentAssertions(unsigned lclNum DEBUGARG(GenTreePtr tree));
#endif
void fgMorphTreeDone(GenTreePtr tree, GenTreePtr oldTree = nullptr DEBUGARG(int morphNum = 0));
- GenTreePtr fgMorphStmt;
+ GenTreeStmt* fgMorphStmt;
unsigned fgGetBigOffsetMorphingTemp(var_types type); // We cache one temp per type to be
// used when morphing big offset.
@@ -4564,7 +4619,6 @@ private:
void fgMarkUseDef(GenTreeLclVarCommon* tree, GenTree* asgdLclVar = nullptr);
-#ifdef DEBUGGING_SUPPORT
void fgBeginScopeLife(VARSET_TP* inScope, VarScopeDsc* var);
void fgEndScopeLife(VARSET_TP* inScope, VarScopeDsc* var);
@@ -4578,8 +4632,6 @@ private:
void fgDispDebugScopes();
#endif // DEBUG
-#endif // DEBUGGING_SUPPORT
-
//-------------------------------------------------------------------------
//
// The following keeps track of any code we've added for things like array
@@ -4622,6 +4674,7 @@ private:
void fgInvokeInlineeCompiler(GenTreeCall* call, InlineResult* result);
void fgInsertInlineeBlocks(InlineInfo* pInlineInfo);
GenTreePtr fgInlinePrependStatements(InlineInfo* inlineInfo);
+ void fgInlineAppendStatements(InlineInfo* inlineInfo, BasicBlock* block, GenTreePtr stmt);
#if FEATURE_MULTIREG_RET
GenTreePtr fgGetStructAsStructPtr(GenTreePtr tree);
@@ -4905,6 +4958,7 @@ public:
#define LPFLG_VAR_LIMIT 0x0100 // iterator is compared with a local var (var # found in lpVarLimit)
#define LPFLG_CONST_LIMIT 0x0200 // iterator is compared with a constant (found in lpConstLimit)
#define LPFLG_ARRLEN_LIMIT 0x0400 // iterator is compared with a.len or a[i].len (found in lpArrLenLimit)
+#define LPFLG_SIMD_LIMIT 0x0080 // iterator is compared with Vector<T>.Count (found in lpConstLimit)
#define LPFLG_HAS_PREHEAD 0x0800 // lpHead is known to be a preHead for this loop
#define LPFLG_REMOVED 0x1000 // has been removed from the loop table (unrolled or optimized away)
@@ -5205,6 +5259,11 @@ protected:
static const int MIN_CSE_COST = 2;
+ // Keeps tracked cse indices
+ BitVecTraits* cseTraits;
+ EXPSET_TP cseFull;
+ EXPSET_TP cseEmpty;
+
/* Generic list of nodes - used by the CSE logic */
struct treeLst
@@ -6237,7 +6296,7 @@ public:
BOOL eeIsValueClass(CORINFO_CLASS_HANDLE clsHnd);
-#if defined(DEBUG) || defined(FEATURE_JIT_METHOD_PERF) || defined(FEATURE_SIMD)
+#if defined(DEBUG) || defined(FEATURE_JIT_METHOD_PERF) || defined(FEATURE_SIMD) || defined(TRACK_LSRA_STATS)
bool IsSuperPMIException(unsigned code)
{
@@ -6334,10 +6393,19 @@ public:
#endif
}
+ 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()
{
-#if COR_JIT_EE_VERSION > 460 && defined(UNIX_AMD64_ABI)
- return eeGetEEInfo()->targetAbi == CORINFO_CORERT_ABI;
+#ifdef UNIX_AMD64_ABI
+ return IsTargetAbi(CORINFO_CORERT_ABI);
#else
return false;
#endif
@@ -6522,8 +6590,6 @@ private:
public:
CodeGenInterface* codeGen;
-#ifdef DEBUGGING_SUPPORT
-
// The following holds information about instr offsets in terms of generated code.
struct IPmappingDsc
@@ -6553,7 +6619,6 @@ public:
typedef SimplerHashTable<GenTreePtr, PtrKeyFuncs<GenTree>, IL_OFFSETX, JitSimplerHashBehavior>
CallSiteILOffsetTable;
CallSiteILOffsetTable* genCallSite2ILOffsetMap;
-#endif // DEBUGGING_SUPPORT
unsigned genReturnLocal; // Local number for the return value when applicable.
BasicBlock* genReturnBB; // jumped to when not optimizing for speed.
@@ -6588,8 +6653,14 @@ public:
{
return codeGen->doDoubleAlign();
}
- DWORD getCanDoubleAlign(); // Defined & used only by RegAlloc
-#endif // DOUBLE_ALIGN
+ DWORD getCanDoubleAlign();
+ bool shouldDoubleAlign(unsigned refCntStk,
+ unsigned refCntReg,
+ unsigned refCntWtdReg,
+ unsigned refCntStkParam,
+ unsigned refCntWtdStkDbl);
+#endif // DOUBLE_ALIGN
+
__declspec(property(get = getFullPtrRegMap, put = setFullPtrRegMap)) bool genFullPtrRegMap;
bool getFullPtrRegMap()
{
@@ -6829,6 +6900,11 @@ private:
return InstructionSet_AVX;
}
+ if (CanUseSSE3_4())
+ {
+ return InstructionSet_SSE3_4;
+ }
+
// min bar is SSE2
assert(canUseSSE2());
return InstructionSet_SSE2;
@@ -7072,7 +7148,7 @@ private:
// and small int base type vectors.
SIMDIntrinsicID impSIMDIntegralRelOpGreaterThanOrEqual(
CORINFO_CLASS_HANDLE typeHnd, unsigned simdVectorSize, var_types baseType, GenTree** op1, GenTree** op2);
-#endif // defined(_TARGET_AMD64_) && !defined(LEGACY_BACKEND)
+#endif // defined(_TARGET_XARCH_) && !defined(LEGACY_BACKEND)
void setLclRelatedToSIMDIntrinsic(GenTreePtr tree);
bool areFieldsContiguous(GenTreePtr op1, GenTreePtr op2);
@@ -7261,6 +7337,16 @@ private:
// Returns true if the TYP_SIMD locals on stack are aligned at their
// preferred byte boundary specified by getSIMDTypeAlignment().
+ //
+ // As per the Intel manual, the preferred alignment for AVX vectors is 32-bytes. On Amd64,
+ // RSP/EBP is aligned at 16-bytes, therefore to align SIMD types at 32-bytes we need even
+ // RSP/EBP to be 32-byte aligned. It is not clear whether additional stack space used in
+ // aligning stack is worth the benefit and for now will use 16-byte alignment for AVX
+ // 256-bit vectors with unaligned load/stores to/from memory. On x86, the stack frame
+ // is aligned to 4 bytes. We need to extend existing support for double (8-byte) alignment
+ // to 16 or 32 byte alignment for frames with local SIMD vars, if that is determined to be
+ // profitable.
+ //
bool isSIMDTypeLocalAligned(unsigned varNum)
{
#if defined(FEATURE_SIMD) && ALIGN_SIMD_TYPES
@@ -7270,8 +7356,7 @@ private:
int off = lvaFrameAddress(varNum, &ebpBased);
// TODO-Cleanup: Can't this use the lvExactSize on the varDsc?
int alignment = getSIMDTypeAlignment(lvaTable[varNum].lvType);
- bool isAligned = ((off % alignment) == 0);
- noway_assert(isAligned || lvaTable[varNum].lvIsParam);
+ bool isAligned = (alignment <= STACK_ALIGN) && ((off % alignment) == 0);
return isAligned;
}
#endif // FEATURE_SIMD
@@ -7289,6 +7374,16 @@ private:
#endif
}
+ // Whether SSE3, SSE3, SSE4.1 and SSE4.2 is available
+ bool CanUseSSE3_4() const
+ {
+#ifdef _TARGET_XARCH_
+ return opts.compCanUseSSE3_4;
+#else
+ return false;
+#endif
+ }
+
bool canUseAVX() const
{
#ifdef FEATURE_AVX_SUPPORT
@@ -7393,21 +7488,21 @@ public:
struct Options
{
- CORJIT_FLAGS* jitFlags; // all flags passed from the EE
- unsigned eeFlags; // CorJitFlag flags passed from the EE
- unsigned compFlags; // method attributes
+ JitFlags* jitFlags; // all flags passed from the EE
+ unsigned compFlags; // method attributes
codeOptimize compCodeOpt; // what type of code optimizations
bool compUseFCOMI;
bool compUseCMOV;
#ifdef _TARGET_XARCH_
- bool compCanUseSSE2; // Allow CodeGen to use "movq XMM" instructions
+ bool compCanUseSSE2; // Allow CodeGen to use "movq XMM" instructions
+ bool compCanUseSSE3_4; // Allow CodeGen to use SSE3, SSSE3, SSE4.1 and SSE4.2 instructions
#ifdef FEATURE_AVX_SUPPORT
bool compCanUseAVX; // Allow CodeGen to use AVX 256-bit vectors for SIMD operations
-#endif
-#endif
+#endif // FEATURE_AVX_SUPPORT
+#endif // _TARGET_XARCH_
// optimize maximally and/or favor speed over size?
@@ -7464,7 +7559,7 @@ public:
#ifdef FEATURE_READYTORUN_COMPILER
inline bool IsReadyToRun()
{
- return (eeFlags & CORJIT_FLG_READYTORUN) != 0;
+ return jitFlags->IsSet(JitFlags::JIT_FLAG_READYTORUN);
}
#else
inline bool IsReadyToRun()
@@ -7478,7 +7573,7 @@ public:
inline bool ShouldUsePInvokeHelpers()
{
#if COR_JIT_EE_VERSION > 460
- return (jitFlags->corJitFlags2 & CORJIT_FLG2_USE_PINVOKE_HELPERS) != 0;
+ return jitFlags->IsSet(JitFlags::JIT_FLAG_USE_PINVOKE_HELPERS);
#else
return false;
#endif
@@ -7489,7 +7584,7 @@ public:
inline bool IsReversePInvoke()
{
#if COR_JIT_EE_VERSION > 460
- return (jitFlags->corJitFlags2 & CORJIT_FLG2_REVERSE_PINVOKE) != 0;
+ return jitFlags->IsSet(JitFlags::JIT_FLAG_REVERSE_PINVOKE);
#else
return false;
#endif
@@ -7499,7 +7594,7 @@ public:
inline bool IsJit32Compat()
{
#if defined(_TARGET_X86_) && COR_JIT_EE_VERSION > 460
- return (jitFlags->corJitFlags2 & CORJIT_FLG2_DESKTOP_QUIRKS) != 0;
+ return jitFlags->IsSet(JitFlags::JIT_FLAG_DESKTOP_QUIRKS);
#else
return false;
#endif
@@ -7509,7 +7604,7 @@ public:
inline bool IsJit64Compat()
{
#if defined(_TARGET_AMD64_) && COR_JIT_EE_VERSION > 460
- return (jitFlags->corJitFlags2 & CORJIT_FLG2_DESKTOP_QUIRKS) != 0;
+ return jitFlags->IsSet(JitFlags::JIT_FLAG_DESKTOP_QUIRKS);
#elif defined(_TARGET_AMD64_) && !defined(FEATURE_CORECLR)
return true;
#else
@@ -7517,14 +7612,10 @@ public:
#endif
}
-#ifdef DEBUGGING_SUPPORT
bool compScopeInfo; // Generate the LocalVar info ?
bool compDbgCode; // Generate debugger-friendly code?
bool compDbgInfo; // Gather debugging info?
bool compDbgEnC;
-#else
- static const bool compDbgCode;
-#endif
#ifdef PROFILING_SUPPORTED
bool compNoPInvokeInlineCB;
@@ -7584,6 +7675,7 @@ public:
bool altJit; // True if we are an altjit and are compiling this method
#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
@@ -7623,9 +7715,11 @@ public:
// for any call. We have a plan for not needing for stubs though
bool compNeedStackProbes;
- // Whether to emit Enter/Leave/TailCall hooks using a dummy stub (DummyProfilerELTStub())
- // This options helps one to make JIT behave as if it is under profiler.
+#ifdef PROFILING_SUPPORTED
+ // Whether to emit Enter/Leave/TailCall hooks using a dummy stub (DummyProfilerELTStub()).
+ // This option helps make the JIT behave as if it is running under a profiler.
bool compJitELTHookEnabled;
+#endif // PROFILING_SUPPORTED
#if FEATURE_TAILCALL_OPT
// Whether opportunistic or implicit tail call optimization is enabled.
@@ -7650,8 +7744,6 @@ public:
#ifdef DEBUG
- static bool s_dspMemStats; // Display per-phase memory statistics for every function
-
template <typename T>
T dspPtr(T p)
{
@@ -7759,8 +7851,8 @@ public:
codeOptimize compCodeOpt()
{
#if 0
- // Switching between size & speed has measurable throughput impact
- // (3.5% on NGen mscorlib when measured). It used to be enabled for
+ // Switching between size & speed has measurable throughput impact
+ // (3.5% on NGen mscorlib when measured). It used to be enabled for
// DEBUG, but should generate identical code between CHK & RET builds,
// so that's not acceptable.
// TODO-Throughput: Figure out what to do about size vs. speed & throughput.
@@ -7772,10 +7864,6 @@ public:
#endif
}
-#ifdef DEBUG
- CLRRandom* inlRNG;
-#endif
-
//--------------------- Info about the procedure --------------------------
struct Info
@@ -7855,8 +7943,6 @@ public:
// and the VM expects that, or the JIT is a "self-host" compiler
// (e.g., x86 hosted targeting x86) and the VM expects that.
-#if defined(DEBUGGING_SUPPORT) || defined(DEBUG)
-
/* The following holds IL scope information about local variables.
*/
@@ -7871,8 +7957,6 @@ public:
unsigned compStmtOffsetsCount;
ICorDebugInfo::BoundaryTypes compStmtOffsetsImplicit;
-#endif // DEBUGGING_SUPPORT || DEBUG
-
#define CPU_X86 0x0100 // The generic X86 CPU
#define CPU_X86_PENTIUM_4 0x0110
@@ -7937,9 +8021,12 @@ public:
// Such method's compRetNativeType is TYP_STRUCT without a hidden RetBufArg
return varTypeIsStruct(info.compRetNativeType) && (info.compRetBuffArg == BAD_VAR_NUM);
#endif // TARGET_XXX
+
#else // not FEATURE_MULTIREG_RET
+
// For this architecture there are no multireg returns
return false;
+
#endif // FEATURE_MULTIREG_RET
}
@@ -7960,7 +8047,7 @@ public:
void compDispLocalVars();
-#endif // DEBUGGING_SUPPORT || DEBUG
+#endif // DEBUG
//-------------------------- Global Compiler Data ------------------------------------
@@ -8059,19 +8146,22 @@ public:
CORINFO_METHOD_INFO* methodInfo,
void** methodCodePtr,
ULONG* methodCodeSize,
- CORJIT_FLAGS* compileFlags);
+ JitFlags* compileFlags);
void compCompileFinish();
int compCompileHelper(CORINFO_MODULE_HANDLE classPtr,
COMP_HANDLE compHnd,
CORINFO_METHOD_INFO* methodInfo,
void** methodCodePtr,
ULONG* methodCodeSize,
- CORJIT_FLAGS* compileFlags,
+ JitFlags* compileFlags,
CorInfoInstantiationVerification instVerInfo);
ArenaAllocator* compGetAllocator();
#if MEASURE_MEM_ALLOC
+
+ static bool s_dspMemStats; // Display per-phase memory statistics for every function
+
struct MemStats
{
unsigned allocCnt; // # of allocs
@@ -8195,9 +8285,8 @@ public:
void compDspSrcLinesByLineNum(unsigned line, bool seek = false);
#endif // DEBUG
-//-------------------------------------------------------------------------
+ //-------------------------------------------------------------------------
-#ifdef DEBUGGING_SUPPORT
typedef ListNode<VarScopeDsc*> VarScopeListNode;
struct VarScopeMapInfo
@@ -8255,8 +8344,6 @@ public:
void compDispScopeLists();
#endif // DEBUG
-#endif // DEBUGGING_SUPPORT
-
bool compIsProfilerHookNeeded();
//-------------------------------------------------------------------------
@@ -8299,7 +8386,7 @@ public:
protected:
size_t compMaxUncheckedOffsetForNullObject;
- void compInitOptions(CORJIT_FLAGS* compileFlags);
+ void compInitOptions(JitFlags* compileFlags);
void compSetProcessor();
void compInitDebuggingInfo();
@@ -8307,16 +8394,22 @@ protected:
#ifdef _TARGET_ARMARCH_
bool compRsvdRegCheck(FrameLayoutState curState);
#endif
- void compCompile(void** methodCodePtr, ULONG* methodCodeSize, CORJIT_FLAGS* compileFlags);
+ void compCompile(void** methodCodePtr, ULONG* methodCodeSize, JitFlags* compileFlags);
- // Data required for generating profiler Enter/Leave/TailCall hooks
- CLANG_FORMAT_COMMENT_ANCHOR;
+ // Clear annotations produced during optimizations; to be used between iterations when repeating opts.
+ void ResetOptAnnotations();
+
+ // Regenerate loop descriptors; to be used between iterations when repeating opts.
+ void RecomputeLoopInfo();
#ifdef PROFILING_SUPPORTED
+ // Data required for generating profiler Enter/Leave/TailCall hooks
+
bool compProfilerHookNeeded; // Whether profiler Enter/Leave/TailCall hook needs to be generated for the method
void* compProfilerMethHnd; // Profiler handle of the method being compiled. Passed as param to ELT callbacks
bool compProfilerMethHndIndirected; // Whether compProfilerHandle is pointer to the handle or is an actual handle
#endif
+
#ifdef _TARGET_AMD64_
bool compQuirkForPPP(); // Check if this method should be Quirked for the PPP issue
#endif
@@ -8692,6 +8785,18 @@ private:
#endif
inline void EndPhase(Phases phase); // Indicate the end of the given phase.
+#if MEASURE_CLRAPI_CALLS
+ // Thin wrappers that call into JitTimer (if present).
+ inline void CLRApiCallEnter(unsigned apix);
+ inline void CLRApiCallLeave(unsigned apix);
+
+public:
+ inline void CLR_API_Enter(API_ICorJitInfo_Names ename);
+ inline void CLR_API_Leave(API_ICorJitInfo_Names ename);
+
+private:
+#endif
+
#if defined(DEBUG) || defined(INLINE_DATA) || defined(FEATURE_CLRSQM)
// These variables are associated with maintaining SQM data about compile time.
unsigned __int64 m_compCyclesAtEndOfInlining; // The thread-virtualized cycle count at the end of the inlining phase
diff --git a/src/jit/compiler.hpp b/src/jit/compiler.hpp
index eb8eb19c68..e8358fd2ab 100644
--- a/src/jit/compiler.hpp
+++ b/src/jit/compiler.hpp
@@ -473,10 +473,17 @@ inline unsigned Compiler::funGetFuncIdx(BasicBlock* block)
#endif // !FEATURE_EH_FUNCLETS
-/*****************************************************************************
- *
- * Map a register mask to a register number
- */
+//------------------------------------------------------------------------------
+// genRegNumFromMask : Maps a single register mask to a register number.
+//
+// Arguments:
+// mask - the register mask
+//
+// Return Value:
+// The number of the register contained in the mask.
+//
+// Assumptions:
+// The mask contains one and only one register.
inline regNumber genRegNumFromMask(regMaskTP mask)
{
@@ -768,7 +775,8 @@ inline double getR8LittleEndian(const BYTE* ptr)
/*****************************************************************************
*
- * Return the bitmask to use in the EXPSET_TP for the CSE with the given CSE index.
+ * Return the normalized index to use in the EXPSET_TP for the CSE with
+ * the given CSE index.
* Each GenTree has the following field:
* signed char gtCSEnum; // 0 or the CSE index (negated if def)
* So zero is reserved to mean this node is not a CSE
@@ -777,15 +785,15 @@ inline double getR8LittleEndian(const BYTE* ptr)
* This precondition is checked by the assert on the first line of this method.
*/
-inline EXPSET_TP genCSEnum2bit(unsigned index)
+inline unsigned int genCSEnum2bit(unsigned index)
{
assert((index > 0) && (index <= EXPSET_SZ));
- return ((EXPSET_TP)1 << (index - 1));
+ return (index - 1);
}
#ifdef DEBUG
-const char* genES2str(EXPSET_TP set);
+const char* genES2str(BitVecTraits* traits, EXPSET_TP set);
const char* refCntWtd2str(unsigned refCntWtd);
#endif
@@ -870,6 +878,10 @@ inline GenTree::GenTree(genTreeOps oper, var_types type DEBUGARG(bool largeNode)
#endif
#endif
+#if COUNT_AST_OPERS
+ InterlockedIncrement(&s_gtNodeCounts[oper]);
+#endif
+
#ifdef DEBUG
gtSeqNum = 0;
gtTreeID = JitTls::GetCompiler()->compGenTreeID++;
@@ -1285,11 +1297,11 @@ inline void GenTree::SetOper(genTreeOps oper, ValueNumberUpdate vnUpdate)
assert(GenTree::s_gtNodeSizes[gtOper] == TREE_NODE_SZ_SMALL ||
GenTree::s_gtNodeSizes[gtOper] == TREE_NODE_SZ_LARGE);
- assert(GenTree::s_gtNodeSizes[oper] == TREE_NODE_SZ_SMALL || GenTree::s_gtNodeSizes[oper] == TREE_NODE_SZ_LARGE);
+ assert(GenTree::s_gtNodeSizes[oper] == TREE_NODE_SZ_SMALL || GenTree::s_gtNodeSizes[oper] == TREE_NODE_SZ_LARGE);
assert(GenTree::s_gtNodeSizes[oper] == TREE_NODE_SZ_SMALL || (gtDebugFlags & GTF_DEBUG_NODE_LARGE));
- gtOper = oper;
+ SetOperRaw(oper);
#ifdef DEBUG
// Maintain the invariant that unary operators always have NULL gtOp2.
@@ -1327,6 +1339,9 @@ inline void GenTree::CopyFrom(const GenTree* src, Compiler* comp)
assert((gtDebugFlags & GTF_DEBUG_NODE_LARGE) || GenTree::s_gtNodeSizes[src->gtOper] == TREE_NODE_SZ_SMALL);
GenTreePtr prev = gtPrev;
GenTreePtr next = gtNext;
+
+ RecordOperBashing(OperGet(), src->OperGet()); // nop unless NODEBASH_STATS is enabled
+
// The VTable pointer is copied intentionally here
memcpy((void*)this, (void*)src, src->GetNodeSize());
this->gtPrev = prev;
@@ -1373,7 +1388,7 @@ inline void GenTree::InitNodeSize()
inline void GenTree::SetOper(genTreeOps oper, ValueNumberUpdate vnUpdate)
{
- gtOper = oper;
+ SetOperRaw(oper);
if (vnUpdate == CLEAR_VN)
{
@@ -1384,6 +1399,7 @@ inline void GenTree::SetOper(genTreeOps oper, ValueNumberUpdate vnUpdate)
inline void GenTree::CopyFrom(GenTreePtr src)
{
+ RecordOperBashing(OperGet(), src->OperGet()); // nop unless NODEBASH_STATS is enabled
*this = *src;
#ifdef DEBUG
gtSeqNum = 0;
@@ -1405,6 +1421,16 @@ inline GenTreePtr Compiler::gtNewCastNodeL(var_types typ, GenTreePtr op1, var_ty
#endif // SMALL_TREE_NODES
/*****************************************************************************/
+/*****************************************************************************/
+
+inline void GenTree::SetOperRaw(genTreeOps oper)
+{
+ // Please do not do anything here other than assign to gtOper (debug-only
+ // code is OK, but should be kept to a minimum).
+ RecordOperBashing(OperGet(), oper); // nop unless NODEBASH_STATS is enabled
+ gtOper = oper;
+}
+
inline void GenTree::SetOperResetFlags(genTreeOps oper)
{
SetOper(oper);
@@ -1446,7 +1472,7 @@ inline void GenTree::ChangeOper(genTreeOps oper, ValueNumberUpdate vnUpdate)
inline void GenTree::ChangeOperUnchecked(genTreeOps oper)
{
- gtOper = oper; // Trust the caller and don't use SetOper()
+ SetOperRaw(oper); // Trust the caller and don't use SetOper()
gtFlags &= GTF_COMMON_MASK;
}
@@ -1579,7 +1605,7 @@ inline unsigned Compiler::lvaGrabTemp(bool shortLifetime DEBUGARG(const char* re
#if 0
// TODO-Cleanup: Enable this and test.
-#ifdef DEBUG
+#ifdef DEBUG
// Fill the old table with junks. So to detect the un-intended use.
memset(lvaTable, fDefaultFill2.val_DontUse_(CLRConfig::INTERNAL_JitDefaultFill, 0xFF), lvaCount * sizeof(*lvaTable));
#endif
@@ -1655,7 +1681,7 @@ inline unsigned Compiler::lvaGrabTemps(unsigned cnt DEBUGARG(const char* reason)
}
#if 0
-#ifdef DEBUG
+#ifdef DEBUG
// TODO-Cleanup: Enable this and test.
// Fill the old table with junks. So to detect the un-intended use.
memset(lvaTable, fDefaultFill2.val_DontUse_(CLRConfig::INTERNAL_JitDefaultFill, 0xFF), lvaCount * sizeof(*lvaTable));
@@ -3909,7 +3935,7 @@ inline bool Compiler::IsSharedStaticHelper(GenTreePtr tree)
helper == CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_DYNAMICCLASS ||
helper == CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_DYNAMICCLASS ||
#ifdef FEATURE_READYTORUN_COMPILER
- helper == CORINFO_HELP_READYTORUN_STATIC_BASE ||
+ helper == CORINFO_HELP_READYTORUN_STATIC_BASE || helper == CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE ||
#endif
helper == CORINFO_HELP_CLASSINIT_SHARED_DYNAMICCLASS;
#if 0
@@ -3944,7 +3970,7 @@ inline bool jitStaticFldIsGlobAddr(CORINFO_FIELD_HANDLE fldHnd)
return (fldHnd == FLD_GLOBAL_DS || fldHnd == FLD_GLOBAL_FS);
}
-#if defined(DEBUG) || defined(FEATURE_JIT_METHOD_PERF) || defined(FEATURE_SIMD)
+#if defined(DEBUG) || defined(FEATURE_JIT_METHOD_PERF) || defined(FEATURE_SIMD) || defined(FEATURE_TRACELOGGING)
inline bool Compiler::eeIsNativeMethod(CORINFO_METHOD_HANDLE method)
{
@@ -4087,16 +4113,12 @@ inline bool Compiler::compIsProfilerHookNeeded()
{
#ifdef PROFILING_SUPPORTED
return compProfilerHookNeeded
-
-#if defined(_TARGET_ARM_) || defined(_TARGET_AMD64_)
// IL stubs are excluded by VM and we need to do the same even running
// under a complus env hook to generate profiler hooks
- || (opts.compJitELTHookEnabled && !(opts.eeFlags & CORJIT_FLG_IL_STUB))
-#endif
- ;
-#else // PROFILING_SUPPORTED
+ || (opts.compJitELTHookEnabled && !opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IL_STUB));
+#else // !PROFILING_SUPPORTED
return false;
-#endif
+#endif // !PROFILING_SUPPORTED
}
/*****************************************************************************
@@ -4185,7 +4207,7 @@ inline bool Compiler::impIsDUP_LDVIRTFTN_TOKEN(const BYTE* delegateCreateStart,
inline bool Compiler::compIsForImportOnly()
{
- return ((opts.eeFlags & CORJIT_FLG_IMPORT_ONLY) != 0);
+ return opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IMPORT_ONLY);
}
/*****************************************************************************
@@ -4352,10 +4374,12 @@ inline bool Compiler::lvaIsGCTracked(const LclVarDsc* varDsc)
{
if (varDsc->lvTracked && (varDsc->lvType == TYP_REF || varDsc->lvType == TYP_BYREF))
{
+ // Stack parameters are always untracked w.r.t. GC reportings
+ const bool isStackParam = varDsc->lvIsParam && !varDsc->lvIsRegArg;
#ifdef _TARGET_AMD64_
- return !lvaIsFieldOfDependentlyPromotedStruct(varDsc);
+ return !isStackParam && !lvaIsFieldOfDependentlyPromotedStruct(varDsc);
#else // !_TARGET_AMD64_
- return true;
+ return !isStackParam;
#endif // !_TARGET_AMD64_
}
else
@@ -4367,8 +4391,10 @@ inline bool Compiler::lvaIsGCTracked(const LclVarDsc* varDsc)
inline void Compiler::EndPhase(Phases phase)
{
#if defined(FEATURE_JIT_METHOD_PERF)
- if (pCompJitTimer != NULL)
+ if (pCompJitTimer != nullptr)
+ {
pCompJitTimer->EndPhase(phase);
+ }
#endif
#if DUMP_FLOWGRAPHS
fgDumpFlowGraph(phase);
@@ -4405,6 +4431,36 @@ inline void Compiler::EndPhase(Phases phase)
}
/*****************************************************************************/
+#if MEASURE_CLRAPI_CALLS
+
+inline void Compiler::CLRApiCallEnter(unsigned apix)
+{
+ if (pCompJitTimer != nullptr)
+ {
+ pCompJitTimer->CLRApiCallEnter(apix);
+ }
+}
+inline void Compiler::CLRApiCallLeave(unsigned apix)
+{
+ if (pCompJitTimer != nullptr)
+ {
+ pCompJitTimer->CLRApiCallLeave(apix);
+ }
+}
+
+inline void Compiler::CLR_API_Enter(API_ICorJitInfo_Names ename)
+{
+ CLRApiCallEnter(ename);
+}
+
+inline void Compiler::CLR_API_Leave(API_ICorJitInfo_Names ename)
+{
+ CLRApiCallLeave(ename);
+}
+
+#endif // MEASURE_CLRAPI_CALLS
+
+/*****************************************************************************/
bool Compiler::fgExcludeFromSsa(unsigned lclNum)
{
if (opts.MinOpts())
diff --git a/src/jit/compphases.h b/src/jit/compphases.h
index f193d04647..ac1bb636ff 100644
--- a/src/jit/compphases.h
+++ b/src/jit/compphases.h
@@ -22,7 +22,12 @@
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, "Morph", "MORPH", 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_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)
@@ -55,7 +60,7 @@ CompPhaseNameMacro(PHASE_OPTIMIZE_INDEX_CHECKS, "Optimize index checks",
#if FEATURE_VALNUM_CSE
CompPhaseNameMacro(PHASE_OPTIMIZE_VALNUM_CSES, "Optimize Valnum CSEs", "OPT-CSE", false, -1)
-#endif
+#endif
CompPhaseNameMacro(PHASE_VN_COPY_PROP, "VN based copy prop", "CP-PROP", false, -1)
#if ASSERTION_PROP
@@ -86,6 +91,12 @@ CompPhaseNameMacro(PHASE_LINEAR_SCAN_RESOLVE, "LSRA resolve",
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)
+
+#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)
+#endif
// clang-format on
#undef CompPhaseNameMacro
diff --git a/src/jit/crossgen/CMakeLists.txt b/src/jit/crossgen/CMakeLists.txt
index f79d9e72ce..6440e91a04 100644
--- a/src/jit/crossgen/CMakeLists.txt
+++ b/src/jit/crossgen/CMakeLists.txt
@@ -1,7 +1,7 @@
include(${CLR_DIR}/crossgen.cmake)
-if(CLR_CMAKE_TARGET_ARCH_I386 OR CLR_CMAKE_TARGET_ARCH_ARM)
+if(CLR_CMAKE_TARGET_ARCH_ARM)
add_definitions(-DLEGACY_BACKEND)
endif()
-add_library_clr(${JIT_BASE_NAME}_crossgen ${SOURCES})
+add_library_clr(clrjit_crossgen ${SOURCES})
diff --git a/src/jit/decomposelongs.cpp b/src/jit/decomposelongs.cpp
index cf66487367..98b8b081fc 100644
--- a/src/jit/decomposelongs.cpp
+++ b/src/jit/decomposelongs.cpp
@@ -65,7 +65,7 @@ void DecomposeLongs::DecomposeBlock(BasicBlock* block)
assert(block->isEmpty() || block->IsLIR());
m_blockWeight = block->getBBWeight(m_compiler);
- m_range = &LIR::AsRange(block);
+ m_range = &LIR::AsRange(block);
DecomposeRangeHelper();
}
@@ -90,7 +90,7 @@ void DecomposeLongs::DecomposeRange(Compiler* compiler, unsigned blockWeight, LI
DecomposeLongs decomposer(compiler);
decomposer.m_blockWeight = blockWeight;
- decomposer.m_range = &range;
+ decomposer.m_range = &range;
decomposer.DecomposeRangeHelper();
}
@@ -111,13 +111,7 @@ void DecomposeLongs::DecomposeRangeHelper()
GenTree* node = Range().FirstNonPhiNode();
while (node != nullptr)
{
- LIR::Use use;
- if (!Range().TryGetUse(node, &use))
- {
- use = LIR::Use::GetDummyUse(Range(), node);
- }
-
- node = DecomposeNode(use);
+ node = DecomposeNode(node);
}
assert(Range().CheckLIR(m_compiler));
@@ -132,10 +126,8 @@ void DecomposeLongs::DecomposeRangeHelper()
// Return Value:
// The next node to process.
//
-GenTree* DecomposeLongs::DecomposeNode(LIR::Use& use)
+GenTree* DecomposeLongs::DecomposeNode(GenTree* tree)
{
- GenTree* tree = use.Def();
-
// Handle the case where we are implicitly using the lower half of a long lclVar.
if ((tree->TypeGet() == TYP_INT) && tree->OperIsLocal())
{
@@ -171,14 +163,15 @@ GenTree* DecomposeLongs::DecomposeNode(LIR::Use& use)
}
#endif // DEBUG
+ LIR::Use use;
+ if (!Range().TryGetUse(tree, &use))
+ {
+ use = LIR::Use::GetDummyUse(Range(), tree);
+ }
+
GenTree* nextNode = nullptr;
switch (tree->OperGet())
{
- case GT_PHI:
- case GT_PHI_ARG:
- nextNode = tree->gtNext;
- break;
-
case GT_LCL_VAR:
nextNode = DecomposeLclVar(use);
break;
@@ -212,8 +205,7 @@ GenTree* DecomposeLongs::DecomposeNode(LIR::Use& use)
break;
case GT_STORE_LCL_FLD:
- assert(tree->gtOp.gtOp1->OperGet() == GT_LONG);
- NYI("st.lclFld of of TYP_LONG");
+ nextNode = DecomposeStoreLclFld(use);
break;
case GT_IND:
@@ -239,23 +231,11 @@ GenTree* DecomposeLongs::DecomposeNode(LIR::Use& use)
break;
case GT_MUL:
- NYI("Arithmetic binary operators on TYP_LONG - GT_MUL");
- break;
-
- case GT_DIV:
- NYI("Arithmetic binary operators on TYP_LONG - GT_DIV");
- break;
-
- case GT_MOD:
- NYI("Arithmetic binary operators on TYP_LONG - GT_MOD");
- break;
-
- case GT_UDIV:
- NYI("Arithmetic binary operators on TYP_LONG - GT_UDIV");
+ nextNode = DecomposeMul(use);
break;
case GT_UMOD:
- NYI("Arithmetic binary operators on TYP_LONG - GT_UMOD");
+ nextNode = DecomposeUMod(use);
break;
case GT_LSH:
@@ -266,11 +246,7 @@ GenTree* DecomposeLongs::DecomposeNode(LIR::Use& use)
case GT_ROL:
case GT_ROR:
- NYI("Arithmetic binary operators on TYP_LONG - ROTATE");
- break;
-
- case GT_MULHI:
- NYI("Arithmetic binary operators on TYP_LONG - MULHI");
+ nextNode = DecomposeRotate(use);
break;
case GT_LOCKADD:
@@ -288,6 +264,37 @@ GenTree* DecomposeLongs::DecomposeNode(LIR::Use& use)
}
}
+ // If we replaced the argument to a GT_FIELD_LIST element with a GT_LONG node, split that field list
+ // element into two elements: one for each half of the GT_LONG.
+ if ((use.Def()->OperGet() == GT_LONG) && !use.IsDummyUse() && (use.User()->OperGet() == GT_FIELD_LIST))
+ {
+ GenTreeOp* value = use.Def()->AsOp();
+ Range().Remove(value);
+
+ // The node returned by `use.User()` is the head of the field list. We need to find the actual node that uses
+ // the `GT_LONG` so that we can split it.
+ GenTreeFieldList* listNode = use.User()->AsFieldList();
+ for (; listNode != nullptr; listNode = listNode->Rest())
+ {
+ if (listNode->Current() == value)
+ {
+ break;
+ }
+ }
+
+ assert(listNode != nullptr);
+ GenTree* rest = listNode->gtOp2;
+
+ GenTreeFieldList* loNode = listNode;
+ loNode->gtOp1 = value->gtOp1;
+ loNode->gtFieldType = TYP_INT;
+
+ GenTreeFieldList* hiNode =
+ new (m_compiler, GT_FIELD_LIST) GenTreeFieldList(value->gtOp2, loNode->gtFieldOffset + 4, TYP_INT, loNode);
+
+ hiNode->gtOp2 = rest;
+ }
+
#ifdef DEBUG
if (m_compiler->verbose)
{
@@ -308,23 +315,25 @@ GenTree* DecomposeLongs::DecomposeNode(LIR::Use& use)
// Arguments:
// use - the LIR::Use object for the def that needs to be decomposed.
// loResult - the decomposed low part
-// hiResult - the decomposed high part. This must follow loResult in the linear order,
-// as the new GT_LONG node will be inserted immediately after it.
+// hiResult - the decomposed high part
+// insertResultAfter - the node that the GT_LONG should be inserted after
//
// Return Value:
// The next node to process.
//
-GenTree* DecomposeLongs::FinalizeDecomposition(LIR::Use& use, GenTree* loResult, GenTree* hiResult)
+GenTree* DecomposeLongs::FinalizeDecomposition(LIR::Use& use,
+ GenTree* loResult,
+ GenTree* hiResult,
+ GenTree* insertResultAfter)
{
assert(use.IsInitialized());
assert(loResult != nullptr);
assert(hiResult != nullptr);
assert(Range().Contains(loResult));
assert(Range().Contains(hiResult));
- assert(loResult->Precedes(hiResult));
GenTree* gtLong = new (m_compiler, GT_LONG) GenTreeOp(GT_LONG, TYP_LONG, loResult, hiResult);
- Range().InsertAfter(hiResult, gtLong);
+ Range().InsertAfter(insertResultAfter, gtLong);
use.ReplaceWith(m_compiler, gtLong);
@@ -366,8 +375,6 @@ GenTree* DecomposeLongs::DecomposeLclVar(LIR::Use& use)
}
else
{
- noway_assert(varDsc->lvLRACandidate == false);
-
loResult->SetOper(GT_LCL_FLD);
loResult->AsLclFld()->gtLclOffs = 0;
loResult->AsLclFld()->gtFieldSeq = FieldSeqStore::NotAField();
@@ -380,7 +387,7 @@ GenTree* DecomposeLongs::DecomposeLclVar(LIR::Use& use)
m_compiler->lvaIncRefCnts(loResult);
m_compiler->lvaIncRefCnts(hiResult);
- return FinalizeDecomposition(use, loResult, hiResult);
+ return FinalizeDecomposition(use, loResult, hiResult, hiResult);
}
//------------------------------------------------------------------------
@@ -404,7 +411,7 @@ GenTree* DecomposeLongs::DecomposeLclFld(LIR::Use& use)
GenTree* hiResult = m_compiler->gtNewLclFldNode(loResult->gtLclNum, TYP_INT, loResult->gtLclOffs + 4);
Range().InsertAfter(loResult, hiResult);
- return FinalizeDecomposition(use, loResult, hiResult);
+ return FinalizeDecomposition(use, loResult, hiResult, hiResult);
}
//------------------------------------------------------------------------
@@ -423,59 +430,118 @@ GenTree* DecomposeLongs::DecomposeStoreLclVar(LIR::Use& use)
GenTree* tree = use.Def();
GenTree* rhs = tree->gtGetOp1();
- if ((rhs->OperGet() == GT_PHI) || (rhs->OperGet() == GT_CALL))
+ if ((rhs->OperGet() == GT_PHI) || (rhs->OperGet() == GT_CALL) ||
+ ((rhs->OperGet() == GT_MUL_LONG) && (rhs->gtFlags & GTF_MUL_64RSLT) != 0))
{
// GT_CALLs are not decomposed, so will not be converted to GT_LONG
// GT_STORE_LCL_VAR = GT_CALL are handled in genMultiRegCallStoreToLocal
+ // GT_MULs are not decomposed, so will not be converted to GT_LONG
return tree->gtNext;
}
noway_assert(rhs->OperGet() == GT_LONG);
+
unsigned varNum = tree->AsLclVarCommon()->gtLclNum;
LclVarDsc* varDsc = m_compiler->lvaTable + varNum;
+ if (!varDsc->lvPromoted)
+ {
+ // We cannot decompose a st.lclVar that is not promoted because doing so
+ // changes its liveness semantics. For example, consider the following
+ // decomposition of a st.lclVar into two st.lclFlds:
+ //
+ // Before:
+ //
+ // /--* t0 int
+ // +--* t1 int
+ // t2 = * gt_long long
+ //
+ // /--* t2 long
+ // * st.lclVar long V0
+ //
+ // After:
+ // /--* t0 int
+ // * st.lclFld int V0 [+0]
+ //
+ // /--* t1 int
+ // * st.lclFld int V0 [+4]
+ //
+ // Before decomposition, the `st.lclVar` is a simple def of `V0`. After
+ // decomposition, each `st.lclFld` is a partial def of `V0`. This partial
+ // def is treated as both a use and a def of the appropriate lclVar. This
+ // difference will affect any situation in which the liveness of a variable
+ // at a def matters (e.g. dead store elimination, live-in sets, etc.). As
+ // a result, we leave these stores as-is and generate the decomposed store
+ // in the code generator.
+ //
+ // NOTE: this does extend the lifetime of the low half of the `GT_LONG`
+ // node as compared to the decomposed form. If we start doing more code
+ // motion in the backend, this may cause some CQ issues and some sort of
+ // decomposition could be beneficial.
+ return tree->gtNext;
+ }
+
+ assert(varDsc->lvFieldCnt == 2);
m_compiler->lvaDecRefCnts(tree);
- GenTree* loRhs = rhs->gtGetOp1();
- GenTree* hiRhs = rhs->gtGetOp2();
- GenTree* hiStore = m_compiler->gtNewLclLNode(varNum, TYP_INT);
+ GenTreeOp* value = rhs->AsOp();
+ Range().Remove(value);
- if (varDsc->lvPromoted)
- {
- assert(varDsc->lvFieldCnt == 2);
+ const unsigned loVarNum = varDsc->lvFieldLclStart;
+ GenTree* loStore = tree;
+ loStore->AsLclVarCommon()->SetLclNum(loVarNum);
+ loStore->gtOp.gtOp1 = value->gtOp1;
+ loStore->gtType = TYP_INT;
- unsigned loVarNum = varDsc->lvFieldLclStart;
- unsigned hiVarNum = loVarNum + 1;
- tree->AsLclVarCommon()->SetLclNum(loVarNum);
- hiStore->SetOper(GT_STORE_LCL_VAR);
- hiStore->AsLclVarCommon()->SetLclNum(hiVarNum);
- }
- else
- {
- noway_assert(varDsc->lvLRACandidate == false);
+ const unsigned hiVarNum = loVarNum + 1;
+ GenTree* hiStore = m_compiler->gtNewLclLNode(hiVarNum, TYP_INT);
+ hiStore->SetOper(GT_STORE_LCL_VAR);
+ hiStore->gtOp.gtOp1 = value->gtOp2;
+ hiStore->gtFlags |= GTF_VAR_DEF;
- tree->SetOper(GT_STORE_LCL_FLD);
- tree->AsLclFld()->gtLclOffs = 0;
- tree->AsLclFld()->gtFieldSeq = FieldSeqStore::NotAField();
+ m_compiler->lvaIncRefCnts(loStore);
+ m_compiler->lvaIncRefCnts(hiStore);
- hiStore->SetOper(GT_STORE_LCL_FLD);
- hiStore->AsLclFld()->gtLclOffs = 4;
- hiStore->AsLclFld()->gtFieldSeq = FieldSeqStore::NotAField();
- }
+ Range().InsertAfter(tree, hiStore);
- // 'tree' is going to steal the loRhs node for itself, so we need to remove the
- // GT_LONG node from the threading.
- Range().Remove(rhs);
+ return hiStore->gtNext;
+}
- tree->gtOp.gtOp1 = loRhs;
- tree->gtType = TYP_INT;
+//------------------------------------------------------------------------
+// DecomposeStoreLclFld: Decompose GT_STORE_LCL_FLD.
+//
+// Arguments:
+// use - the LIR::Use object for the def that needs to be decomposed.
+//
+// Return Value:
+// The next node to process.
+//
+GenTree* DecomposeLongs::DecomposeStoreLclFld(LIR::Use& use)
+{
+ assert(use.IsInitialized());
+ assert(use.Def()->OperGet() == GT_STORE_LCL_FLD);
- hiStore->gtOp.gtOp1 = hiRhs;
- hiStore->gtFlags |= GTF_VAR_DEF;
+ GenTreeLclFld* store = use.Def()->AsLclFld();
+
+ GenTreeOp* value = store->gtOp1->AsOp();
+ assert(value->OperGet() == GT_LONG);
+ Range().Remove(value);
+
+ // The original store node will be repurposed to store the low half of the GT_LONG.
+ GenTreeLclFld* loStore = store;
+ loStore->gtOp1 = value->gtOp1;
+ loStore->gtType = TYP_INT;
+ loStore->gtFlags |= GTF_VAR_USEASG;
- m_compiler->lvaIncRefCnts(tree);
+ // Create the store for the upper half of the GT_LONG and insert it after the low store.
+ GenTreeLclFld* hiStore = m_compiler->gtNewLclFldNode(loStore->gtLclNum, TYP_INT, loStore->gtLclOffs + 4);
+ hiStore->SetOper(GT_STORE_LCL_FLD);
+ hiStore->gtOp1 = value->gtOp2;
+ hiStore->gtFlags |= (GTF_VAR_DEF | GTF_VAR_USEASG);
+
+ // Bump the ref count for the destination.
m_compiler->lvaIncRefCnts(hiStore);
- Range().InsertAfter(tree, hiStore);
+ Range().InsertAfter(loStore, hiStore);
return hiStore->gtNext;
}
@@ -494,35 +560,103 @@ GenTree* DecomposeLongs::DecomposeCast(LIR::Use& use)
assert(use.IsInitialized());
assert(use.Def()->OperGet() == GT_CAST);
- GenTree* tree = use.Def();
+ GenTree* cast = use.Def()->AsCast();
GenTree* loResult = nullptr;
GenTree* hiResult = nullptr;
- assert(tree->gtPrev == tree->gtGetOp1());
- NYI_IF(tree->gtOverflow(), "TYP_LONG cast with overflow");
- switch (tree->AsCast()->CastFromType())
+ var_types srcType = cast->CastFromType();
+ var_types dstType = cast->CastToType();
+
+ if ((cast->gtFlags & GTF_UNSIGNED) != 0)
+ {
+ srcType = genUnsignedType(srcType);
+ }
+
+ if (varTypeIsLong(srcType))
+ {
+ if (cast->gtOverflow() && (varTypeIsUnsigned(srcType) != varTypeIsUnsigned(dstType)))
+ {
+ GenTree* srcOp = cast->gtGetOp1();
+ noway_assert(srcOp->OperGet() == GT_LONG);
+ GenTree* loSrcOp = srcOp->gtGetOp1();
+ GenTree* hiSrcOp = srcOp->gtGetOp2();
+
+ //
+ // When casting between long types an overflow check is needed only if the types
+ // have different signedness. In both cases (long->ulong and ulong->long) we only
+ // need to check if the high part is negative or not. Use the existing cast node
+ // to perform a int->uint cast of the high part to take advantage of the overflow
+ // check provided by codegen.
+ //
+
+ loResult = loSrcOp;
+
+ hiResult = cast;
+ hiResult->gtType = TYP_INT;
+ hiResult->AsCast()->gtCastType = TYP_UINT;
+ hiResult->gtFlags &= ~GTF_UNSIGNED;
+ hiResult->gtOp.gtOp1 = hiSrcOp;
+
+ Range().Remove(cast);
+ Range().Remove(srcOp);
+ Range().InsertAfter(hiSrcOp, hiResult);
+ }
+ else
+ {
+ NYI("Unimplemented long->long no-op cast decomposition");
+ }
+ }
+ else if (varTypeIsIntegralOrI(srcType))
{
- case TYP_INT:
- if (tree->gtFlags & GTF_UNSIGNED)
+ if (cast->gtOverflow() && !varTypeIsUnsigned(srcType) && varTypeIsUnsigned(dstType))
+ {
+ //
+ // An overflow check is needed only when casting from a signed type to ulong.
+ // Change the cast type to uint to take advantage of the overflow check provided
+ // by codegen and then zero extend the resulting uint to ulong.
+ //
+
+ loResult = cast;
+ loResult->AsCast()->gtCastType = TYP_UINT;
+ loResult->gtType = TYP_INT;
+
+ hiResult = m_compiler->gtNewZeroConNode(TYP_INT);
+
+ Range().InsertAfter(loResult, hiResult);
+ }
+ else
+ {
+ if (varTypeIsUnsigned(srcType))
{
- loResult = tree->gtGetOp1();
- Range().Remove(tree);
+ loResult = cast->gtGetOp1();
+ hiResult = m_compiler->gtNewZeroConNode(TYP_INT);
- hiResult = new (m_compiler, GT_CNS_INT) GenTreeIntCon(TYP_INT, 0);
+ Range().Remove(cast);
Range().InsertAfter(loResult, hiResult);
}
else
{
- NYI("Lowering of signed cast TYP_INT->TYP_LONG");
- }
- break;
+ LIR::Use src(Range(), &(cast->gtOp.gtOp1), cast);
+ unsigned lclNum = src.ReplaceWithLclVar(m_compiler, m_blockWeight);
- default:
- NYI("Unimplemented type for Lowering of cast to TYP_LONG");
- break;
+ loResult = src.Def();
+
+ GenTree* loCopy = m_compiler->gtNewLclvNode(lclNum, TYP_INT);
+ 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);
+ m_compiler->lvaIncRefCnts(loCopy);
+ }
+ }
+ }
+ else
+ {
+ NYI("Unimplemented cast decomposition");
}
- return FinalizeDecomposition(use, loResult, hiResult);
+ return FinalizeDecomposition(use, loResult, hiResult, hiResult);
}
//------------------------------------------------------------------------
@@ -549,7 +683,7 @@ GenTree* DecomposeLongs::DecomposeCnsLng(LIR::Use& use)
GenTree* hiResult = new (m_compiler, GT_CNS_INT) GenTreeIntCon(TYP_INT, hiVal);
Range().InsertAfter(loResult, hiResult);
- return FinalizeDecomposition(use, loResult, hiResult);
+ return FinalizeDecomposition(use, loResult, hiResult, hiResult);
}
//------------------------------------------------------------------------
@@ -567,35 +701,7 @@ GenTree* DecomposeLongs::DecomposeCall(LIR::Use& use)
assert(use.Def()->OperGet() == GT_CALL);
// We only need to force var = call() if the call's result is used.
- if (use.IsDummyUse())
- return use.Def()->gtNext;
-
- GenTree* user = use.User();
- if (user->OperGet() == GT_STORE_LCL_VAR)
- {
- // If parent is already a STORE_LCL_VAR, we can skip it if
- // it is already marked as lvIsMultiRegRet.
- unsigned varNum = user->AsLclVarCommon()->gtLclNum;
- if (m_compiler->lvaTable[varNum].lvIsMultiRegRet)
- {
- return use.Def()->gtNext;
- }
- else if (!m_compiler->lvaTable[varNum].lvPromoted)
- {
- // If var wasn't promoted, we can just set lvIsMultiRegRet.
- m_compiler->lvaTable[varNum].lvIsMultiRegRet = true;
- return use.Def()->gtNext;
- }
- }
-
- GenTree* originalNode = use.Def();
-
- // Otherwise, we need to force var = call()
- unsigned varNum = use.ReplaceWithLclVar(m_compiler, m_blockWeight);
- m_compiler->lvaTable[varNum].lvIsMultiRegRet = true;
-
- // Decompose the new LclVar use
- return DecomposeLclVar(use);
+ return StoreNodeToVar(use);
}
//------------------------------------------------------------------------
@@ -627,7 +733,7 @@ GenTree* DecomposeLongs::DecomposeStoreInd(LIR::Use& use)
// + --* t155 long
// * storeIndir long
- GenTree* gtLong = tree->gtOp.gtOp2;
+ GenTree* gtLong = tree->gtOp.gtOp2;
// Save address to a temp. It is used in storeIndLow and storeIndHigh trees.
LIR::Use address(Range(), &tree->gtOp.gtOp1, tree);
@@ -721,12 +827,13 @@ GenTree* DecomposeLongs::DecomposeInd(LIR::Use& use)
GenTreePtr addrHigh =
new (m_compiler, GT_LEA) GenTreeAddrMode(TYP_REF, addrBaseHigh, nullptr, 0, genTypeSize(TYP_INT));
GenTreePtr indHigh = new (m_compiler, GT_IND) GenTreeIndir(GT_IND, TYP_INT, addrHigh, nullptr);
+ indHigh->gtFlags |= (indLow->gtFlags & (GTF_GLOB_REF | GTF_EXCEPT | GTF_IND_FLAGS));
m_compiler->lvaIncRefCnts(addrBaseHigh);
Range().InsertAfter(indLow, addrBaseHigh, addrHigh, indHigh);
- return FinalizeDecomposition(use, indLow, indHigh);
+ return FinalizeDecomposition(use, indLow, indHigh, indHigh);
}
//------------------------------------------------------------------------
@@ -758,7 +865,7 @@ GenTree* DecomposeLongs::DecomposeNot(LIR::Use& use)
GenTree* hiResult = new (m_compiler, GT_NOT) GenTreeOp(GT_NOT, TYP_INT, hiOp1, nullptr);
Range().InsertAfter(loResult, hiResult);
- return FinalizeDecomposition(use, loResult, hiResult);
+ return FinalizeDecomposition(use, loResult, hiResult, hiResult);
}
//------------------------------------------------------------------------
@@ -779,14 +886,6 @@ GenTree* DecomposeLongs::DecomposeNeg(LIR::Use& use)
GenTree* gtLong = tree->gtGetOp1();
noway_assert(gtLong->OperGet() == GT_LONG);
- LIR::Use op1(Range(), &gtLong->gtOp.gtOp1, gtLong);
- op1.ReplaceWithLclVar(m_compiler, m_blockWeight);
-
- LIR::Use op2(Range(), &gtLong->gtOp.gtOp2, gtLong);
- op2.ReplaceWithLclVar(m_compiler, m_blockWeight);
-
- // Neither GT_NEG nor the introduced temporaries have side effects.
- tree->gtFlags &= ~GTF_ALL_EFFECT;
GenTree* loOp1 = gtLong->gtGetOp1();
GenTree* hiOp1 = gtLong->gtGetOp2();
@@ -799,11 +898,10 @@ GenTree* DecomposeLongs::DecomposeNeg(LIR::Use& use)
GenTree* zero = m_compiler->gtNewZeroConNode(TYP_INT);
GenTree* hiAdjust = m_compiler->gtNewOperNode(GT_ADD_HI, TYP_INT, hiOp1, zero);
GenTree* hiResult = m_compiler->gtNewOperNode(GT_NEG, TYP_INT, hiAdjust);
- hiResult->gtFlags = tree->gtFlags;
Range().InsertAfter(loResult, zero, hiAdjust, hiResult);
- return FinalizeDecomposition(use, loResult, hiResult);
+ return FinalizeDecomposition(use, loResult, hiResult, hiResult);
}
//------------------------------------------------------------------------
@@ -864,14 +962,19 @@ GenTree* DecomposeLongs::DecomposeArith(LIR::Use& use)
}
}
- return FinalizeDecomposition(use, loResult, hiResult);
+ return FinalizeDecomposition(use, loResult, hiResult, hiResult);
}
//------------------------------------------------------------------------
-// DecomposeShift: Decompose GT_LSH, GT_RSH, GT_RSZ. For shift nodes, we need to use
-// the shift helper functions, so we here convert the shift into a helper call by
-// pulling its arguments out of linear order and making them the args to a call, then
-// replacing the original node with the new call.
+// DecomposeShift: Decompose GT_LSH, GT_RSH, GT_RSZ. For shift nodes being shifted
+// by a constant int, we can inspect the shift amount and decompose to the appropriate
+// node types, generating a shl/shld pattern for GT_LSH, a shrd/shr pattern for GT_RSZ,
+// and a shrd/sar pattern for GT_SHR for most shift amounts. Shifting by 0, >= 32 and
+// >= 64 are special cased to produce better code patterns.
+//
+// For all other shift nodes, we need to use the shift helper functions, so we here convert
+// the shift into a helper call by pulling its arguments out of linear order and making
+// them the args to a call, then replacing the original node with the new call.
//
// Arguments:
// use - the LIR::Use object for the def that needs to be decomposed.
@@ -883,66 +986,646 @@ GenTree* DecomposeLongs::DecomposeShift(LIR::Use& use)
{
assert(use.IsInitialized());
- GenTree* tree = use.Def();
- GenTree* gtLong = tree->gtGetOp1();
- genTreeOps oper = tree->OperGet();
+ GenTree* tree = use.Def();
+ GenTree* gtLong = tree->gtGetOp1();
+ GenTree* loOp1 = gtLong->gtGetOp1();
+ GenTree* hiOp1 = gtLong->gtGetOp2();
+ GenTree* shiftByOp = tree->gtGetOp2();
+
+ genTreeOps oper = tree->OperGet();
+ genTreeOps shiftByOper = shiftByOp->OperGet();
assert((oper == GT_LSH) || (oper == GT_RSH) || (oper == GT_RSZ));
- LIR::Use loOp1Use(Range(), &gtLong->gtOp.gtOp1, gtLong);
- loOp1Use.ReplaceWithLclVar(m_compiler, m_blockWeight);
+ // If we are shifting by a constant int, we do not want to use a helper, instead, we decompose.
+ if (shiftByOper == GT_CNS_INT)
+ {
+ unsigned int count = shiftByOp->gtIntCon.gtIconVal;
+ Range().Remove(shiftByOp);
- LIR::Use hiOp1Use(Range(), &gtLong->gtOp.gtOp2, gtLong);
- hiOp1Use.ReplaceWithLclVar(m_compiler, m_blockWeight);
+ if (count == 0)
+ {
+ GenTree* next = tree->gtNext;
+ // Remove tree and don't do anything else.
+ Range().Remove(tree);
+ use.ReplaceWith(m_compiler, gtLong);
+ return next;
+ }
- LIR::Use shiftWidthUse(Range(), &tree->gtOp.gtOp2, tree);
- shiftWidthUse.ReplaceWithLclVar(m_compiler, m_blockWeight);
+ GenTree* loResult;
+ GenTree* hiResult;
- GenTree* loOp1 = gtLong->gtGetOp1();
- GenTree* hiOp1 = gtLong->gtGetOp2();
+ GenTree* insertAfter;
- GenTree* shiftWidthOp = tree->gtGetOp2();
+ switch (oper)
+ {
+ 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
+
+ Range().Remove(gtLong);
+ loOp1 = RepresentOpAsLocalVar(loOp1, gtLong, &gtLong->gtOp.gtOp1);
+ unsigned loOp1LclNum = loOp1->AsLclVarCommon()->gtLclNum;
+ Range().Remove(loOp1);
+
+ GenTree* shiftByHi = m_compiler->gtNewIconNode(count, TYP_INT);
+ GenTree* shiftByLo = m_compiler->gtNewIconNode(count, TYP_INT);
+
+ loResult = m_compiler->gtNewOperNode(GT_LSH, TYP_INT, loOp1, shiftByLo);
+
+ // Create a GT_LONG that contains loCopy and hiOp1. This will be used in codegen to
+ // generate the shld instruction
+ GenTree* loCopy = m_compiler->gtNewLclvNode(loOp1LclNum, TYP_INT);
+ GenTree* hiOp = new (m_compiler, GT_LONG) GenTreeOp(GT_LONG, TYP_LONG, loCopy, hiOp1);
+ hiResult = m_compiler->gtNewOperNode(GT_LSH_HI, TYP_INT, hiOp, shiftByHi);
+
+ m_compiler->lvaIncRefCnts(loCopy);
+
+ Range().InsertBefore(tree, loCopy, hiOp1, hiOp);
+ Range().InsertBefore(tree, shiftByHi, hiResult);
+ Range().InsertBefore(tree, loOp1, shiftByLo, loResult);
+
+ insertAfter = loResult;
+ }
+ else
+ {
+ assert(count >= 32);
+
+ if (count < 64)
+ {
+ if (count == 32)
+ {
+ // Move loOp1 into hiResult (shift of 32 bits is just a mov of lo to hi)
+ // We need to make sure that we save lo to a temp variable so that we don't overwrite lo
+ // before saving it to hi in the case that we are doing an inplace shift. I.e.:
+ // x = x << 32
+
+ LIR::Use loOp1Use(Range(), &gtLong->gtOp.gtOp1, gtLong);
+ loOp1Use.ReplaceWithLclVar(m_compiler, m_blockWeight);
+
+ hiResult = loOp1Use.Def();
+ Range().Remove(gtLong);
+ }
+ else
+ {
+ Range().Remove(gtLong);
+ Range().Remove(loOp1);
+ assert(count > 32 && count < 64);
+
+ // Move loOp1 into hiResult, do a GT_LSH with count - 32.
+ // We will compute hiResult before loResult in this case, so we don't need to store lo to a
+ // 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);
+ }
+ }
+ else
+ {
+ Range().Remove(gtLong);
+ Range().Remove(loOp1);
+ assert(count >= 64);
+
+ // 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);
+ }
+
+ // Zero out loResult (shift of >= 32 bits shifts all lo bits to hiResult)
+ loResult = m_compiler->gtNewZeroConNode(TYP_INT);
+ Range().InsertBefore(tree, loResult);
+
+ insertAfter = loResult;
+ }
+ }
+ break;
+ case GT_RSZ:
+ {
+ Range().Remove(gtLong);
+
+ if (count < 32)
+ {
+ // Hi is a GT_RSZ, lo is a GT_RSH_LO. Will produce:
+ // reg1 = hi
+ // shrd lo, reg1, shift
+ // shr hi, shift
+
+ hiOp1 = RepresentOpAsLocalVar(hiOp1, gtLong, &gtLong->gtOp.gtOp2);
+ unsigned hiOp1LclNum = hiOp1->AsLclVarCommon()->gtLclNum;
+ GenTree* hiCopy = m_compiler->gtNewLclvNode(hiOp1LclNum, TYP_INT);
+
+ GenTree* shiftByHi = m_compiler->gtNewIconNode(count, TYP_INT);
+ GenTree* shiftByLo = m_compiler->gtNewIconNode(count, TYP_INT);
+
+ m_compiler->lvaIncRefCnts(hiCopy);
+
+ hiResult = m_compiler->gtNewOperNode(GT_RSZ, TYP_INT, hiOp1, shiftByHi);
+
+ // Create a GT_LONG that contains loOp1 and hiCopy. This will be used in codegen to
+ // generate the shrd instruction
+ 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);
+ }
+ else
+ {
+ Range().Remove(loOp1);
+ Range().Remove(hiOp1);
+ assert(count >= 32);
+ if (count < 64)
+ {
+ if (count == 32)
+ {
+ // Move hiOp1 into loResult.
+ loResult = hiOp1;
+ Range().InsertBefore(tree, loResult);
+ }
+ else
+ {
+ assert(count > 32 && count < 64);
+
+ // 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);
+ }
+ }
+ else
+ {
+ assert(count >= 64);
+
+ // Zero out lo
+ loResult = m_compiler->gtNewZeroConNode(TYP_INT);
+ Range().InsertBefore(tree, loResult);
+ }
+
+ // Zero out hi
+ hiResult = m_compiler->gtNewZeroConNode(TYP_INT);
+ Range().InsertBefore(tree, hiResult);
+ }
+
+ insertAfter = hiResult;
+ }
+ break;
+ case GT_RSH:
+ {
+ Range().Remove(gtLong);
+ Range().Remove(loOp1);
+
+ hiOp1 = RepresentOpAsLocalVar(hiOp1, gtLong, &gtLong->gtOp.gtOp2);
+ unsigned hiOp1LclNum = hiOp1->AsLclVarCommon()->gtLclNum;
+ GenTree* hiCopy = m_compiler->gtNewLclvNode(hiOp1LclNum, TYP_INT);
+ Range().Remove(hiOp1);
+
+ if (count < 32)
+ {
+ // Hi is a GT_RSH, lo is a GT_RSH_LO. Will produce:
+ // reg1 = hi
+ // shrd lo, reg1, shift
+ // sar hi, shift
+
+ GenTree* shiftByHi = m_compiler->gtNewIconNode(count, TYP_INT);
+ GenTree* shiftByLo = m_compiler->gtNewIconNode(count, TYP_INT);
+ m_compiler->lvaIncRefCnts(hiCopy);
+
+ hiResult = m_compiler->gtNewOperNode(GT_RSH, TYP_INT, hiOp1, shiftByHi);
+
+ // Create a GT_LONG that contains loOp1 and hiCopy. This will be used in codegen to
+ // generate the shrd instruction
+ 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);
+ }
+ else
+ {
+ assert(count >= 32);
+ if (count < 64)
+ {
+ if (count == 32)
+ {
+ // Move hiOp1 into loResult.
+ loResult = hiOp1;
+ Range().InsertBefore(tree, loResult);
+ }
+ else
+ {
+ assert(count > 32 && count < 64);
+
+ // 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);
+ }
+
+ // 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);
+
+ m_compiler->lvaIncRefCnts(hiCopy);
+ }
+ else
+ {
+ assert(count >= 64);
+
+ // 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);
+
+ // 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);
+
+ m_compiler->lvaIncRefCnts(hiCopy);
+ }
+ }
+
+ insertAfter = hiResult;
+ }
+ break;
+ default:
+ unreached();
+ }
- Range().Remove(gtLong);
- Range().Remove(loOp1);
- Range().Remove(hiOp1);
+ // Remove tree from Range
+ Range().Remove(tree);
- Range().Remove(shiftWidthOp);
+ 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);
+ loOp1 = RepresentOpAsLocalVar(loOp1, gtLong, &gtLong->gtOp.gtOp1);
+ hiOp1 = RepresentOpAsLocalVar(hiOp1, gtLong, &gtLong->gtOp.gtOp2);
- // TODO-X86-CQ: If the shift operand is a GT_CNS_INT, we should pipe the instructions through to codegen
- // and generate the shift instructions ourselves there, rather than replacing it with a helper call.
+ Range().Remove(shiftByOp);
+ Range().Remove(gtLong);
+ Range().Remove(loOp1);
+ Range().Remove(hiOp1);
- unsigned helper;
+ unsigned helper;
- switch (oper)
+ switch (oper)
+ {
+ case GT_LSH:
+ helper = CORINFO_HELP_LLSH;
+ break;
+ case GT_RSH:
+ helper = CORINFO_HELP_LRSH;
+ break;
+ case GT_RSZ:
+ helper = CORINFO_HELP_LRSZ;
+ break;
+ default:
+ unreached();
+ }
+
+ 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;
+
+ 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().Remove(tree);
+ use.ReplaceWith(m_compiler, call);
+ return call;
+ }
+}
+
+//------------------------------------------------------------------------
+// DecomposeRotate: Decompose GT_ROL and GT_ROR with constant shift amounts. We can
+// inspect the rotate amount and decompose to the appropriate node types, generating
+// a shld/shld pattern for GT_ROL, a shrd/shrd pattern for GT_ROR, for most rotate
+// amounts.
+//
+// Arguments:
+// use - the LIR::Use object for the def that needs to be decomposed.
+//
+// Return Value:
+// The next node to process.
+//
+GenTree* DecomposeLongs::DecomposeRotate(LIR::Use& use)
+{
+ GenTree* tree = use.Def();
+ GenTree* gtLong = tree->gtGetOp1();
+ GenTree* rotateByOp = tree->gtGetOp2();
+
+ genTreeOps oper = tree->OperGet();
+
+ assert((oper == GT_ROL) || (oper == GT_ROR));
+ assert(rotateByOp->IsCnsIntOrI());
+
+ // For longs, we need to change rols into two GT_LSH_HIs and rors into two GT_RSH_LOs
+ // so we will get:
+ //
+ // shld lo, hi, rotateAmount
+ // shld hi, loCopy, rotateAmount
+ //
+ // or:
+ //
+ // shrd lo, hi, rotateAmount
+ // shrd hi, loCopy, rotateAmount
+
+ if (oper == GT_ROL)
{
- case GT_LSH:
- helper = CORINFO_HELP_LLSH;
- break;
- case GT_RSH:
- helper = CORINFO_HELP_LRSH;
- break;
- case GT_RSZ:
- helper = CORINFO_HELP_LRSZ;
- break;
- default:
- unreached();
+ oper = GT_LSH_HI;
+ }
+ else
+ {
+ oper = GT_RSH_LO;
}
- GenTreeArgList* argList = m_compiler->gtNewArgList(loOp1, hiOp1, shiftWidthOp);
+ unsigned int count = rotateByOp->gtIntCon.gtIconVal;
+ Range().Remove(rotateByOp);
+
+ // Make sure the rotate amount is between 0 and 63.
+ assert((count < 64) && (count != 0));
+
+ GenTree* loResult;
+ GenTree* hiResult;
+
+ if (count == 32)
+ {
+ // If the rotate amount is 32, then swap hi and lo
+ LIR::Use loOp1Use(Range(), &gtLong->gtOp.gtOp1, gtLong);
+ loOp1Use.ReplaceWithLclVar(m_compiler, m_blockWeight);
+
+ LIR::Use hiOp1Use(Range(), &gtLong->gtOp.gtOp2, gtLong);
+ hiOp1Use.ReplaceWithLclVar(m_compiler, m_blockWeight);
+
+ hiResult = loOp1Use.Def();
+ loResult = hiOp1Use.Def();
+ gtLong->gtOp.gtOp1 = loResult;
+ gtLong->gtOp.gtOp2 = hiResult;
+
+ GenTree* next = tree->gtNext;
+ // Remove tree and don't do anything else.
+ Range().Remove(tree);
+ use.ReplaceWith(m_compiler, gtLong);
+ return next;
+ }
+ else
+ {
+ GenTree* loOp1;
+ GenTree* hiOp1;
+
+ if (count > 32)
+ {
+ // If count > 32, we swap hi and lo, and subtract 32 from count
+ hiOp1 = gtLong->gtGetOp1();
+ loOp1 = gtLong->gtGetOp2();
+
+ Range().Remove(gtLong);
+ loOp1 = RepresentOpAsLocalVar(loOp1, gtLong, &gtLong->gtOp.gtOp2);
+ hiOp1 = RepresentOpAsLocalVar(hiOp1, gtLong, &gtLong->gtOp.gtOp1);
+
+ count -= 32;
+ }
+ else
+ {
+ loOp1 = gtLong->gtGetOp1();
+ hiOp1 = gtLong->gtGetOp2();
+
+ Range().Remove(gtLong);
+ loOp1 = RepresentOpAsLocalVar(loOp1, gtLong, &gtLong->gtOp.gtOp1);
+ hiOp1 = RepresentOpAsLocalVar(hiOp1, gtLong, &gtLong->gtOp.gtOp2);
+ }
+
+ unsigned loOp1LclNum = loOp1->AsLclVarCommon()->gtLclNum;
+ unsigned hiOp1LclNum = hiOp1->AsLclVarCommon()->gtLclNum;
+
+ Range().Remove(loOp1);
+ Range().Remove(hiOp1);
+
+ GenTree* rotateByHi = m_compiler->gtNewIconNode(count, TYP_INT);
+ GenTree* rotateByLo = m_compiler->gtNewIconNode(count, TYP_INT);
+
+ // Create a GT_LONG that contains loOp1 and hiCopy. This will be used in codegen to
+ // generate the shld instruction
+ GenTree* hiCopy = m_compiler->gtNewLclvNode(hiOp1LclNum, TYP_INT);
+ GenTree* loOp = new (m_compiler, GT_LONG) GenTreeOp(GT_LONG, TYP_LONG, hiCopy, loOp1);
+ loResult = m_compiler->gtNewOperNode(oper, TYP_INT, loOp, rotateByLo);
+
+ // Create a GT_LONG that contains loCopy and hiOp1. This will be used in codegen to
+ // generate the shld instruction
+ GenTree* loCopy = m_compiler->gtNewLclvNode(loOp1LclNum, TYP_INT);
+ GenTree* hiOp = new (m_compiler, GT_LONG) GenTreeOp(GT_LONG, TYP_LONG, loCopy, hiOp1);
+ hiResult = m_compiler->gtNewOperNode(oper, TYP_INT, hiOp, rotateByHi);
+
+ m_compiler->lvaIncRefCnts(loCopy);
+ m_compiler->lvaIncRefCnts(hiCopy);
+
+ Range().InsertBefore(tree, hiCopy, loOp1, loOp);
+ Range().InsertBefore(tree, rotateByLo, loResult);
+ Range().InsertBefore(tree, loCopy, hiOp1, hiOp);
+ Range().InsertBefore(tree, rotateByHi, hiResult);
+
+ Range().Remove(tree);
+
+ return FinalizeDecomposition(use, loResult, hiResult, hiResult);
+ }
+}
+
+//------------------------------------------------------------------------
+// DecomposeMul: Decompose GT_MUL. The only GT_MULs that make it to decompose are
+// those with the GTF_MUL_64RSLT flag set. These muls result in a mul instruction that
+// returns its result in two registers like GT_CALLs do. Additionally, these muls are
+// guaranteed to be in the form long = (long)int * (long)int. Therefore, to decompose
+// these nodes, we convert them into GT_MUL_LONGs, undo the cast from int to long by
+// stripping out the lo ops, and force them into the form var = mul, as we do for
+// GT_CALLs. In codegen, we then produce a mul instruction that produces the result
+// in edx:eax, and store those registers on the stack in genStoreLongLclVar.
+//
+// All other GT_MULs have been converted to helper calls in morph.cpp
+//
+// Arguments:
+// use - the LIR::Use object for the def that needs to be decomposed.
+//
+// Return Value:
+// The next node to process.
+//
+GenTree* DecomposeLongs::DecomposeMul(LIR::Use& use)
+{
+ assert(use.IsInitialized());
+
+ GenTree* tree = use.Def();
+ genTreeOps oper = tree->OperGet();
+
+ assert(oper == GT_MUL);
+ assert((tree->gtFlags & GTF_MUL_64RSLT) != 0);
+
+ GenTree* op1 = tree->gtGetOp1();
+ GenTree* op2 = tree->gtGetOp2();
+
+ GenTree* loOp1 = op1->gtGetOp1();
+ GenTree* hiOp1 = op1->gtGetOp2();
+ GenTree* loOp2 = op2->gtGetOp1();
+ GenTree* hiOp2 = op2->gtGetOp2();
+
+ 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->SetOperRaw(GT_MUL_LONG);
+
+ return StoreNodeToVar(use);
+}
+
+//------------------------------------------------------------------------
+// DecomposeUMod: Decompose GT_UMOD. The only GT_UMODs that make it to decompose
+// are guaranteed to be an unsigned long mod with op2 which is a cast to long from
+// a constant int whose value is between 2 and 0x3fffffff. All other GT_UMODs are
+// morphed into helper calls. These GT_UMODs will actually return an int value in
+// RDX. In decompose, we make the lo operation a TYP_INT GT_UMOD, with op2 as the
+// original lo half and op1 as a GT_LONG. We make the hi part 0, so we end up with:
+//
+// GT_UMOD[TYP_INT] ( GT_LONG [TYP_LONG] (loOp1, hiOp1), loOp2 [TYP_INT] )
+//
+// With the expectation that we will generate:
+//
+// EDX = hiOp1
+// EAX = loOp1
+// reg = loOp2
+// idiv reg
+// EDX is the remainder, and result of GT_UMOD
+// mov hiReg = 0
+//
+// Arguments:
+// use - the LIR::Use object for the def that needs to be decomposed.
+//
+// Return Value:
+// The next node to process.
+//
+GenTree* DecomposeLongs::DecomposeUMod(LIR::Use& use)
+{
+ assert(use.IsInitialized());
+
+ GenTree* tree = use.Def();
+ genTreeOps oper = tree->OperGet();
+
+ assert(oper == GT_UMOD);
+
+ GenTree* op1 = tree->gtGetOp1();
+ GenTree* op2 = tree->gtGetOp2();
+ assert(op1->OperGet() == GT_LONG);
+ assert(op2->OperGet() == GT_LONG);
+
+ GenTree* loOp2 = op2->gtGetOp1();
+ GenTree* hiOp2 = op2->gtGetOp2();
+
+ assert(loOp2->OperGet() == GT_CNS_INT);
+ assert(hiOp2->OperGet() == GT_CNS_INT);
+ assert((loOp2->gtIntCon.gtIconVal >= 2) && (loOp2->gtIntCon.gtIconVal <= 0x3fffffff));
+ assert(hiOp2->gtIntCon.gtIconVal == 0);
+
+ // Get rid of op2's hi part. We don't need it.
+ Range().Remove(hiOp2);
+ Range().Remove(op2);
+
+ // Lo part is the GT_UMOD
+ GenTree* loResult = tree;
+ loResult->gtOp.gtOp2 = loOp2;
+ loResult->gtType = TYP_INT;
- GenTree* call = m_compiler->gtNewHelperCallNode(helper, TYP_LONG, 0, argList);
+ // Set the high part to 0
+ GenTree* hiResult = m_compiler->gtNewZeroConNode(TYP_INT);
- GenTreeCall* callNode = call->AsCall();
- ReturnTypeDesc* retTypeDesc = callNode->GetReturnTypeDesc();
- retTypeDesc->InitializeLongReturnType(m_compiler);
+ Range().InsertAfter(loResult, hiResult);
- call = m_compiler->fgMorphArgs(callNode);
- Range().InsertAfter(tree, LIR::SeqTree(m_compiler, call));
-
- Range().Remove(tree);
- use.ReplaceWith(m_compiler, call);
- return call;
+ return FinalizeDecomposition(use, loResult, hiResult, hiResult);
+}
+
+//------------------------------------------------------------------------
+// StoreNodeToVar: Check if the user is a STORE_LCL_VAR, and if it isn't,
+// store the node to a var. Then decompose the new LclVar.
+//
+// Arguments:
+// use - the LIR::Use object for the def that needs to be decomposed.
+//
+// Return Value:
+// The next node to process.
+//
+GenTree* DecomposeLongs::StoreNodeToVar(LIR::Use& use)
+{
+ if (use.IsDummyUse())
+ return use.Def()->gtNext;
+
+ GenTree* tree = use.Def();
+ GenTree* user = use.User();
+
+ if (user->OperGet() == GT_STORE_LCL_VAR)
+ {
+ // If parent is already a STORE_LCL_VAR, we can skip it if
+ // it is already marked as lvIsMultiRegRet.
+ unsigned varNum = user->AsLclVarCommon()->gtLclNum;
+ if (m_compiler->lvaTable[varNum].lvIsMultiRegRet)
+ {
+ return tree->gtNext;
+ }
+ else if (!m_compiler->lvaTable[varNum].lvPromoted)
+ {
+ // If var wasn't promoted, we can just set lvIsMultiRegRet.
+ m_compiler->lvaTable[varNum].lvIsMultiRegRet = true;
+ return tree->gtNext;
+ }
+ }
+
+ // Otherwise, we need to force var = call()
+ unsigned varNum = use.ReplaceWithLclVar(m_compiler, m_blockWeight);
+ m_compiler->lvaTable[varNum].lvIsMultiRegRet = true;
+
+ // Decompose the new LclVar use
+ return DecomposeLclVar(use);
+}
+
+//------------------------------------------------------------------------
+// Check is op already local var, if not store it to local.
+//
+// Arguments:
+// op - GenTree* to represent as local variable
+// user - user of op
+// edge - edge from user to op
+//
+// Return Value:
+// op represented as local var
+//
+GenTree* DecomposeLongs::RepresentOpAsLocalVar(GenTree* op, GenTree* user, GenTree** edge)
+{
+ if (op->OperGet() == GT_LCL_VAR)
+ {
+ return op;
+ }
+ else
+ {
+ LIR::Use opUse(Range(), edge, user);
+ opUse.ReplaceWithLclVar(m_compiler, m_blockWeight);
+ return *edge;
+ }
}
//------------------------------------------------------------------------
@@ -965,9 +1648,6 @@ genTreeOps DecomposeLongs::GetHiOper(genTreeOps oper)
case GT_SUB:
return GT_SUB_HI;
break;
- case GT_MUL:
- return GT_MUL_HI;
- break;
case GT_DIV:
return GT_DIV_HI;
break;
diff --git a/src/jit/decomposelongs.h b/src/jit/decomposelongs.h
index af9b342fb2..8965a0b330 100644
--- a/src/jit/decomposelongs.h
+++ b/src/jit/decomposelongs.h
@@ -35,13 +35,14 @@ private:
}
// Driver functions
- void DecomposeRangeHelper();
- GenTree* DecomposeNode(LIR::Use& use);
+ void DecomposeRangeHelper();
+ GenTree* DecomposeNode(GenTree* tree);
// Per-node type decompose cases
GenTree* DecomposeLclVar(LIR::Use& use);
GenTree* DecomposeLclFld(LIR::Use& use);
GenTree* DecomposeStoreLclVar(LIR::Use& use);
+ GenTree* DecomposeStoreLclFld(LIR::Use& use);
GenTree* DecomposeCast(LIR::Use& use);
GenTree* DecomposeCnsLng(LIR::Use& use);
GenTree* DecomposeCall(LIR::Use& use);
@@ -51,10 +52,15 @@ private:
GenTree* DecomposeNeg(LIR::Use& use);
GenTree* DecomposeArith(LIR::Use& use);
GenTree* DecomposeShift(LIR::Use& use);
+ GenTree* DecomposeRotate(LIR::Use& use);
+ GenTree* DecomposeMul(LIR::Use& use);
+ GenTree* DecomposeUMod(LIR::Use& use);
// Helper functions
- GenTree* FinalizeDecomposition(LIR::Use& use, GenTree* loResult, GenTree* hiResult);
+ GenTree* FinalizeDecomposition(LIR::Use& use, GenTree* loResult, GenTree* hiResult, GenTree* insertResultAfter);
+ GenTree* RepresentOpAsLocalVar(GenTree* op, GenTree* user, GenTree** edge);
+ GenTree* StoreNodeToVar(LIR::Use& use);
static genTreeOps GetHiOper(genTreeOps oper);
static genTreeOps GetLoOper(genTreeOps oper);
diff --git a/src/jit/dll/CMakeLists.txt b/src/jit/dll/CMakeLists.txt
index 01e58dbbb8..43ed07eae5 100644
--- a/src/jit/dll/CMakeLists.txt
+++ b/src/jit/dll/CMakeLists.txt
@@ -1,20 +1,20 @@
project(ClrJit)
-if(CLR_CMAKE_PLATFORM_ARCH_I386 OR CLR_CMAKE_PLATFORM_ARCH_ARM)
+if(CLR_CMAKE_TARGET_ARCH_ARM)
add_definitions(-DLEGACY_BACKEND)
-endif(CLR_CMAKE_PLATFORM_ARCH_I386 OR CLR_CMAKE_PLATFORM_ARCH_ARM)
+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(${JIT_BASE_NAME}_static
+ add_library_clr(clrjit_static
STATIC
${SHARED_LIB_SOURCES}
)
- add_dependencies(${JIT_BASE_NAME}_static coreclrpal gcinfo)
+ add_dependencies(clrjit_static coreclrpal gcinfo)
else()
- add_library_clr(${JIT_BASE_NAME}_static
+ add_library_clr(clrjit_static
${SOURCES}
)
# Disable up to here (see above) the following for UNIX altjit on Windows
diff --git a/src/jit/dll/jit.nativeproj b/src/jit/dll/jit.nativeproj
index 97981e7eff..7505f5e8ef 100644
--- a/src/jit/dll/jit.nativeproj
+++ b/src/jit/dll/jit.nativeproj
@@ -37,9 +37,9 @@
<!-- Profile-guided optimization -->
- <PogoOptimize Condition="('$(BuildArchitecture)' == 'arm')">false</PogoOptimize>
- <PogoInstrument Condition="('$(BuildArchitecture)' == 'arm') and ('$(_BuildType)' == 'ret') and ('$(BuildProjectName)' == '')">true</PogoInstrument>
- <PogoUpdate Condition="('$(BuildArchitecture)' == 'arm') and ('$(_BuildType)' == 'ret') and ('$(BuildProjectName)' == '')">true</PogoUpdate>
+ <PogoOptimize Condition="('$(BuildArchitecture)' == 'amd64' or '$(BuildArchitecture)' == 'arm')">false</PogoOptimize>
+ <PogoInstrument Condition="('$(BuildArchitecture)' == 'amd64' or '$(BuildArchitecture)' == 'arm') and ('$(_BuildType)' == 'ret') and ('$(BuildProjectName)' == '')">true</PogoInstrument>
+ <PogoUpdate Condition="('$(BuildArchitecture)' == 'amd64' or '$(BuildArchitecture)' == 'arm') and ('$(_BuildType)' == 'ret') and ('$(BuildProjectName)' == '')">true</PogoUpdate>
<Win32DllLibs Condition="'$(PogoInstrument)' == 'true' and '$(BuildArchitecture)' == 'amd64'">$(Win32DllLibs);$(CrtLibPath)\pgort.lib</Win32DllLibs>
<Win32DllLibs Condition="'$(PogoInstrument)' == 'true' and '$(BuildArchitecture)' == 'arm'">$(Win32DllLibs);$(CrtLibPath)\pgort.lib;$(SdkLibPath)\ntdll.lib</Win32DllLibs>
<OptimizationDataRelativeDir>$(_BuildArch)\CLR\Base</OptimizationDataRelativeDir>
diff --git a/src/jit/earlyprop.cpp b/src/jit/earlyprop.cpp
index 70d1012aa0..51de631d19 100644
--- a/src/jit/earlyprop.cpp
+++ b/src/jit/earlyprop.cpp
@@ -189,8 +189,7 @@ void Compiler::optEarlyProp()
// Walk the stmt tree in linear order to rewrite any array length reference with a
// constant array length.
- bool isRewritten = false;
- bool bbHasNullCheck = (block->bbFlags & BBF_HAS_NULLCHECK) != 0;
+ bool isRewritten = false;
for (GenTreePtr tree = stmt->gtStmt.gtStmtList; tree != nullptr; tree = tree->gtNext)
{
if (optEarlyPropRewriteTree(tree))
@@ -238,12 +237,8 @@ bool Compiler::optEarlyPropRewriteTree(GenTreePtr tree)
objectRefPtr = tree->gtOp.gtOp1;
propKind = optPropKind::OPK_ARRAYLEN;
}
- else if ((tree->OperGet() == GT_IND) && !varTypeIsStruct(tree))
+ else if (tree->OperIsIndir())
{
- // TODO-1stClassStructs: The above condition should apply equally to all indirections,
- // but previously the implicit indirections due to a struct assignment were not
- // considered, so we are currently limiting it to non-structs to preserve existing
- // behavior.
// optFoldNullCheck takes care of updating statement info if a null check is removed.
optFoldNullCheck(tree);
@@ -259,7 +254,7 @@ bool Compiler::optEarlyPropRewriteTree(GenTreePtr tree)
return false;
}
- objectRefPtr = tree->gtOp.gtOp1;
+ objectRefPtr = tree->AsIndir()->Addr();
propKind = optPropKind::OPK_OBJ_GETTYPE;
}
else
@@ -511,15 +506,23 @@ void Compiler::optFoldNullCheck(GenTreePtr tree)
// |
// x
- assert(tree->OperGet() == GT_IND);
- if (tree->gtGetOp1()->OperGet() == GT_LCL_VAR)
+ if ((compCurBB->bbFlags & BBF_HAS_NULLCHECK) == 0)
+ {
+ return;
+ }
+
+ assert(tree->OperIsIndir());
+
+ GenTree* const addr = tree->AsIndir()->Addr();
+ if (addr->OperGet() == GT_LCL_VAR)
{
// Check if we have the pattern above and find the nullcheck node if we do.
// Find the definition of the indirected local (x in the picture)
- GenTreePtr indLocalTree = tree->gtGetOp1();
- unsigned lclNum = indLocalTree->AsLclVarCommon()->GetLclNum();
- unsigned ssaNum = indLocalTree->AsLclVarCommon()->GetSsaNum();
+ GenTreeLclVarCommon* const lclVarNode = addr->AsLclVarCommon();
+
+ const unsigned lclNum = lclVarNode->GetLclNum();
+ const unsigned ssaNum = lclVarNode->GetSsaNum();
if (ssaNum != SsaConfig::RESERVED_SSA_NUM)
{
@@ -557,7 +560,7 @@ void Compiler::optFoldNullCheck(GenTreePtr tree)
{
// Walk from the use to the def in reverse execution order to see
// if any nodes have unsafe side effects.
- GenTreePtr currentTree = indLocalTree->gtPrev;
+ GenTreePtr currentTree = lclVarNode->gtPrev;
bool isInsideTry = compCurBB->hasTryIndex();
bool canRemoveNullCheck = true;
const unsigned maxNodesWalked = 25;
@@ -612,13 +615,8 @@ void Compiler::optFoldNullCheck(GenTreePtr tree)
additionNode->gtFlags & (GTF_EXCEPT | GTF_DONT_CSE);
// Re-morph the statement.
- fgMorphBlockStmt(compCurBB, curStmt DEBUGARG("optFoldNullCheck"));
-
- // Recalculate the gtCostSz, etc...
- gtSetStmtInfo(curStmt);
-
- // Re-thread the nodes
- fgSetStmtSeq(curStmt);
+ fgMorphBlockStmt(compCurBB,
+ curStmt->AsStmt() DEBUGARG("optFoldNullCheck"));
}
}
}
@@ -668,4 +666,4 @@ bool Compiler::optCanMoveNullCheckPastTree(GenTreePtr tree, bool isInsideTry)
}
}
return result;
-} \ No newline at end of file
+}
diff --git a/src/jit/ee_il_dll.cpp b/src/jit/ee_il_dll.cpp
index 527244221e..dcadaa9453 100755..100644
--- a/src/jit/ee_il_dll.cpp
+++ b/src/jit/ee_il_dll.cpp
@@ -284,21 +284,17 @@ CorJitResult CILJit::compileMethod(
return g_realJitCompiler->compileMethod(compHnd, methodInfo, flags, entryAddress, nativeSizeOfCode);
}
- CORJIT_FLAGS jitFlags = {0};
+ JitFlags jitFlags;
- DWORD jitFlagsSize = 0;
#if COR_JIT_EE_VERSION > 460
- if (flags == CORJIT_FLG_CALL_GETJITFLAGS)
- {
- jitFlagsSize = compHnd->getJitFlags(&jitFlags, sizeof(jitFlags));
- }
-#endif
-
- assert(jitFlagsSize <= sizeof(jitFlags));
- if (jitFlagsSize == 0)
- {
- jitFlags.corJitFlags = flags;
- }
+ 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;
@@ -385,17 +381,31 @@ 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)
{
return g_realJitCompiler->getMaxIntrinsicSIMDVectorLength(cpuCompileFlags);
}
-#ifdef _TARGET_AMD64_
+ 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_
#ifdef FEATURE_AVX_SUPPORT
- if (((cpuCompileFlags & CORJIT_FLG_PREJIT) == 0) && ((cpuCompileFlags & CORJIT_FLG_FEATURE_SIMD) != 0) &&
- ((cpuCompileFlags & CORJIT_FLG_USE_AVX2) != 0))
+ if (!jitFlags.IsSet(JitFlags::JIT_FLAG_PREJIT) && jitFlags.IsSet(JitFlags::JIT_FLAG_FEATURE_SIMD) &&
+ jitFlags.IsSet(JitFlags::JIT_FLAG_USE_AVX2))
{
if (JitConfig.EnableAVX() != 0)
{
@@ -404,9 +414,10 @@ unsigned CILJit::getMaxIntrinsicSIMDVectorLength(DWORD cpuCompileFlags)
}
#endif // FEATURE_AVX_SUPPORT
return 16;
-#else // !_TARGET_AMD64_
+#endif // _TARGET_XARCH_
+#else // !FEATURE_SIMD
return 0;
-#endif // !_TARGET_AMD64_
+#endif // !FEATURE_SIMD
}
void CILJit::setRealJit(ICorJitCompiler* realJitCompiler)
@@ -1378,7 +1389,7 @@ bool Compiler::eeRunWithErrorTrapImp(void (*function)(void*), void* param)
* Utility functions
*/
-#if defined(DEBUG) || defined(FEATURE_JIT_METHOD_PERF) || defined(FEATURE_SIMD)
+#if defined(DEBUG) || defined(FEATURE_JIT_METHOD_PERF) || defined(FEATURE_SIMD) || defined(FEATURE_TRACELOGGING)
/*****************************************************************************/
@@ -1526,6 +1537,9 @@ const char* Compiler::eeGetClassName(CORINFO_CLASS_HANDLE clsHnd)
const wchar_t* Compiler::eeGetCPString(size_t strHandle)
{
+#ifdef FEATURE_PAL
+ return nullptr;
+#else
char buff[512 + sizeof(CORINFO_String)];
// make this bulletproof, so it works even if we are wrong.
@@ -1547,6 +1561,7 @@ const wchar_t* Compiler::eeGetCPString(size_t strHandle)
}
return (asString->chars);
+#endif // FEATURE_PAL
}
#endif // DEBUG
diff --git a/src/jit/ee_il_dll.hpp b/src/jit/ee_il_dll.hpp
index d9bf95fde8..3899d92192 100644
--- a/src/jit/ee_il_dll.hpp
+++ b/src/jit/ee_il_dll.hpp
@@ -21,7 +21,11 @@ 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 5c991ddf1b..0929b7392e 100644
--- a/src/jit/emit.cpp
+++ b/src/jit/emit.cpp
@@ -1264,9 +1264,9 @@ void* emitter::emitAllocInstr(size_t sz, emitAttr opsz)
// ARM - This is currently broken on _TARGET_ARM_
// When nopSize is odd we misalign emitCurIGsize
//
- if (!(emitComp->opts.eeFlags & CORJIT_FLG_PREJIT) && !emitInInstrumentation &&
- !emitIGisInProlog(emitCurIG) // don't do this in prolog or epilog
- && !emitIGisInEpilog(emitCurIG) &&
+ if (!emitComp->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT) && !emitInInstrumentation &&
+ !emitIGisInProlog(emitCurIG) && // don't do this in prolog or epilog
+ !emitIGisInEpilog(emitCurIG) &&
emitRandomNops // sometimes we turn off where exact codegen is needed (pinvoke inline)
)
{
@@ -1670,13 +1670,9 @@ void emitter::emitCreatePlaceholderIG(insGroupPlaceholderType igType,
emitCurIGsize += MAX_PLACEHOLDER_IG_SIZE;
emitCurCodeOffset += emitCurIGsize;
-#ifdef DEBUGGING_SUPPORT
-
#if FEATURE_EH_FUNCLETS
// Add the appropriate IP mapping debugging record for this placeholder
- // group.
-
- // genExitCode() adds the mapping for main function epilogs
+ // group. genExitCode() adds the mapping for main function epilogs.
if (emitComp->opts.compDbgInfo)
{
if (igType == IGPT_FUNCLET_PROLOG)
@@ -1690,8 +1686,6 @@ void emitter::emitCreatePlaceholderIG(insGroupPlaceholderType igType,
}
#endif // FEATURE_EH_FUNCLETS
-#endif // DEBUGGING_SUPPORT
-
/* Start a new IG if more code follows */
if (last)
@@ -2320,7 +2314,7 @@ bool emitter::emitNoGChelper(unsigned IHX)
case CORINFO_HELP_PROF_FCN_LEAVE:
case CORINFO_HELP_PROF_FCN_ENTER:
-#ifdef _TARGET_AMD64_
+#if defined(_TARGET_AMD64_) || (defined(_TARGET_X86_) && !defined(LEGACY_BACKEND))
case CORINFO_HELP_PROF_FCN_TAILCALL:
#endif
case CORINFO_HELP_LLSH:
@@ -3414,8 +3408,6 @@ size_t emitter::emitIssue1Instr(insGroup* ig, instrDesc* id, BYTE** dp)
#endif
-#if defined(DEBUGGING_SUPPORT) || defined(DEBUG)
-
/* Did the size of the instruction match our expectations? */
UNATIVE_OFFSET csz = (UNATIVE_OFFSET)(*dp - curInsAdr);
@@ -3447,8 +3439,6 @@ size_t emitter::emitIssue1Instr(insGroup* ig, instrDesc* id, BYTE** dp)
#endif
}
-#endif
-
#ifdef DEBUG
/* Make sure the instruction descriptor size also matches our expectations */
if (is != emitSizeOfInsDsc(id))
@@ -6048,7 +6038,7 @@ unsigned char emitter::emitOutputLong(BYTE* dst, ssize_t val)
#ifdef DEBUG
if (emitComp->opts.dspEmit)
{
- printf("; emit_long 0%08XH\n", val);
+ printf("; emit_long 0%08XH\n", (int)val);
}
#ifdef _TARGET_AMD64_
// if we're emitting code bytes, ensure that we've already emitted the rex prefix!
@@ -6072,9 +6062,9 @@ unsigned char emitter::emitOutputSizeT(BYTE* dst, ssize_t val)
if (emitComp->opts.dspEmit)
{
#ifdef _TARGET_AMD64_
- printf("; emit_size_t 0%016llXH\n", (size_t)val);
+ printf("; emit_size_t 0%016llXH\n", val);
#else // _TARGET_AMD64_
- printf("; emit_size_t 0%08XH\n", (size_t)val);
+ printf("; emit_size_t 0%08XH\n", val);
#endif // _TARGET_AMD64_
}
#endif // DEBUG
@@ -6082,6 +6072,60 @@ unsigned char emitter::emitOutputSizeT(BYTE* dst, ssize_t val)
return sizeof(size_t);
}
+//------------------------------------------------------------------------
+// Wrappers to emitOutputByte, emitOutputWord, emitOutputLong, emitOutputSizeT
+// that take unsigned __int64 or size_t type instead of ssize_t. Used on RyuJIT/x86.
+//
+// Arguments:
+// dst - passed through
+// val - passed through
+//
+// Return Value:
+// Same as wrapped function.
+//
+
+#if !defined(LEGACY_BACKEND) && defined(_TARGET_X86_)
+unsigned char emitter::emitOutputByte(BYTE* dst, size_t val)
+{
+ return emitOutputByte(dst, (ssize_t)val);
+}
+
+unsigned char emitter::emitOutputWord(BYTE* dst, size_t val)
+{
+ return emitOutputWord(dst, (ssize_t)val);
+}
+
+unsigned char emitter::emitOutputLong(BYTE* dst, size_t val)
+{
+ return emitOutputLong(dst, (ssize_t)val);
+}
+
+unsigned char emitter::emitOutputSizeT(BYTE* dst, size_t val)
+{
+ return emitOutputSizeT(dst, (ssize_t)val);
+}
+
+unsigned char emitter::emitOutputByte(BYTE* dst, unsigned __int64 val)
+{
+ return emitOutputByte(dst, (ssize_t)val);
+}
+
+unsigned char emitter::emitOutputWord(BYTE* dst, unsigned __int64 val)
+{
+ return emitOutputWord(dst, (ssize_t)val);
+}
+
+unsigned char emitter::emitOutputLong(BYTE* dst, unsigned __int64 val)
+{
+ return emitOutputLong(dst, (ssize_t)val);
+}
+
+unsigned char emitter::emitOutputSizeT(BYTE* dst, unsigned __int64 val)
+{
+ return emitOutputSizeT(dst, (ssize_t)val);
+}
+#endif // !defined(LEGACY_BACKEND) && defined(_TARGET_X86_)
+
/*****************************************************************************
*
* Given a block cookie and a code position, return the actual code offset;
diff --git a/src/jit/emit.h b/src/jit/emit.h
index 8fb24bcd60..5b1a395379 100644
--- a/src/jit/emit.h
+++ b/src/jit/emit.h
@@ -427,6 +427,11 @@ public:
// There seem to be some cases where this is used without being initialized via CodeGen::inst_set_SV_var().
emitVarRefOffs = 0;
#endif // DEBUG
+
+#ifdef _TARGET_XARCH_
+ SetUseSSE3_4(false);
+#endif // _TARGET_XARCH_
+
#ifdef FEATURE_AVX_SUPPORT
SetUseAVX(false);
#endif // FEATURE_AVX_SUPPORT
@@ -1659,6 +1664,18 @@ private:
unsigned char emitOutputLong(BYTE* dst, ssize_t val);
unsigned char emitOutputSizeT(BYTE* dst, ssize_t val);
+#if !defined(LEGACY_BACKEND) && defined(_TARGET_X86_)
+ unsigned char emitOutputByte(BYTE* dst, size_t val);
+ unsigned char emitOutputWord(BYTE* dst, size_t val);
+ unsigned char emitOutputLong(BYTE* dst, size_t val);
+ unsigned char emitOutputSizeT(BYTE* dst, size_t val);
+
+ unsigned char emitOutputByte(BYTE* dst, unsigned __int64 val);
+ unsigned char emitOutputWord(BYTE* dst, unsigned __int64 val);
+ unsigned char emitOutputLong(BYTE* dst, unsigned __int64 val);
+ unsigned char emitOutputSizeT(BYTE* dst, unsigned __int64 val);
+#endif // !defined(LEGACY_BACKEND) && defined(_TARGET_X86_)
+
size_t emitIssue1Instr(insGroup* ig, instrDesc* id, BYTE** dp);
size_t emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp);
@@ -1742,8 +1759,8 @@ private:
BYTE* emitCurIGfreeEndp; // one byte past the last available byte in buffer
BYTE* emitCurIGfreeBase; // first byte address
- unsigned emitCurIGinsCnt; // # of collected instr's in buffer
- unsigned emitCurIGsize; // estimated code size of current group in bytes
+ unsigned emitCurIGinsCnt; // # of collected instr's in buffer
+ unsigned emitCurIGsize; // estimated code size of current group in bytes
UNATIVE_OFFSET emitCurCodeOffset; // current code offset within group
UNATIVE_OFFSET emitTotalCodeSize; // bytes of code in entire method
@@ -1822,8 +1839,12 @@ private:
void emitInsertIGAfter(insGroup* insertAfterIG, insGroup* ig);
void emitNewIG();
+
+#if !defined(JIT32_GCENCODER)
void emitDisableGC();
void emitEnableGC();
+#endif // !defined(JIT32_GCENCODER)
+
void emitGenIG(insGroup* ig);
insGroup* emitSavIG(bool emitAdd = false);
void emitNxtIG(bool emitAdd = false);
@@ -2707,6 +2728,7 @@ inline void emitter::emitNewIG()
emitGenIG(ig);
}
+#if !defined(JIT32_GCENCODER)
// Start a new instruction group that is not interruptable
inline void emitter::emitDisableGC()
{
@@ -2736,6 +2758,7 @@ inline void emitter::emitEnableGC()
// instruction groups.
emitForceNewIG = true;
}
+#endif // !defined(JIT32_GCENCODER)
/*****************************************************************************/
#endif // _EMIT_H_
diff --git a/src/jit/emitarm.cpp b/src/jit/emitarm.cpp
index 1f57048a80..45928ca2d2 100644
--- a/src/jit/emitarm.cpp
+++ b/src/jit/emitarm.cpp
@@ -4368,6 +4368,7 @@ void emitter::emitIns_J_R(instruction ins, emitAttr attr, BasicBlock* dst, regNu
*
* EC_FUNC_TOKEN : addr is the method address
* EC_FUNC_ADDR : addr is the absolute address of the function
+ * if addr is NULL, it is a recursive call
*
* If callType is one of these emitCallTypes, addr has to be NULL.
* EC_INDIR_R : "call ireg".
@@ -4463,13 +4464,11 @@ void emitter::emitIns_Call(EmitCallType callType,
assert(argSize % (int)sizeof(void*) == 0);
argCnt = argSize / (int)sizeof(void*);
-#ifdef DEBUGGING_SUPPORT
/* Managed RetVal: emit sequence point for the call */
if (emitComp->opts.compDbgInfo && ilOffset != BAD_IL_OFFSET)
{
codeGen->genIPmappingAdd(ilOffset, false);
}
-#endif
/*
We need to allocate the appropriate instruction descriptor based
@@ -4555,8 +4554,8 @@ void emitter::emitIns_Call(EmitCallType callType,
assert(callType == EC_FUNC_TOKEN || callType == EC_FUNC_ADDR);
- assert(addr != NULL);
- assert(codeGen->validImmForBL((ssize_t)addr));
+ // if addr is nullptr then this call is treated as a recursive call.
+ assert(addr == nullptr || codeGen->arm_Valid_Imm_For_BL((ssize_t)addr));
if (isJump)
{
@@ -5266,8 +5265,8 @@ BYTE* emitter::emitOutputLJ(insGroup* ig, BYTE* dst, instrDesc* i)
else
#endif
{
- assert(distVal >= -16777216);
- assert(distVal <= 16777214);
+ assert(distVal >= CALL_DIST_MAX_NEG);
+ assert(distVal <= CALL_DIST_MAX_POS);
if (distVal < 0)
code |= 1 << 26;
@@ -6211,7 +6210,14 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
sz = sizeof(instrDesc);
}
- addr = id->idAddr()->iiaAddr;
+ if (id->idAddr()->iiaAddr == NULL) /* a recursive call */
+ {
+ addr = emitCodeBlock;
+ }
+ else
+ {
+ addr = id->idAddr()->iiaAddr;
+ }
code = emitInsCode(ins, fmt);
#ifdef RELOC_SUPPORT
diff --git a/src/jit/emitarm64.cpp b/src/jit/emitarm64.cpp
index a632ec12c8..12c4087115 100644
--- a/src/jit/emitarm64.cpp
+++ b/src/jit/emitarm64.cpp
@@ -6738,13 +6738,11 @@ void emitter::emitIns_Call(EmitCallType callType,
assert(argSize % REGSIZE_BYTES == 0);
argCnt = (int)(argSize / (int)sizeof(void*));
-#ifdef DEBUGGING_SUPPORT
/* Managed RetVal: emit sequence point for the call */
if (emitComp->opts.compDbgInfo && ilOffset != BAD_IL_OFFSET)
{
codeGen->genIPmappingAdd(ilOffset, false);
}
-#endif
/*
We need to allocate the appropriate instruction descriptor based
diff --git a/src/jit/emitxarch.cpp b/src/jit/emitxarch.cpp
index d43f766ee8..b6bacfa520 100644
--- a/src/jit/emitxarch.cpp
+++ b/src/jit/emitxarch.cpp
@@ -30,6 +30,15 @@ bool IsSSE2Instruction(instruction ins)
return (ins >= INS_FIRST_SSE2_INSTRUCTION && ins <= INS_LAST_SSE2_INSTRUCTION);
}
+bool IsSSE4Instruction(instruction ins)
+{
+#ifdef LEGACY_BACKEND
+ return false;
+#else
+ return (ins >= INS_FIRST_SSE4_INSTRUCTION && ins <= INS_LAST_SSE4_INSTRUCTION);
+#endif
+}
+
bool IsSSEOrAVXInstruction(instruction ins)
{
#ifdef FEATURE_AVX_SUPPORT
@@ -48,7 +57,9 @@ bool emitter::IsAVXInstruction(instruction ins)
#endif
}
+#ifdef _TARGET_AMD64_
#define REX_PREFIX_MASK 0xFF00000000LL
+#endif // _TARGET_AMD64_
#ifdef FEATURE_AVX_SUPPORT
// Returns true if the AVX instruction is a binary operator that requires 3 operands.
@@ -75,10 +86,8 @@ bool emitter::IsThreeOperandBinaryAVXInstruction(instruction ins)
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_pminub || ins == INS_pmaxsw || ins == INS_pminsw || ins == INS_insertps ||
+ ins == INS_vinsertf128 || ins == INS_punpckldq || ins == INS_phaddd);
}
// Returns true if the AVX instruction is a move operator that requires 3 operands.
@@ -92,22 +101,45 @@ bool emitter::IsThreeOperandMoveAVXInstruction(instruction ins)
return IsAVXInstruction(ins) &&
(ins == INS_movlpd || ins == INS_movlps || ins == INS_movhpd || ins == INS_movhps || ins == INS_movss);
}
-#endif // FEATURE_AVX_SUPPORT
-// Returns true if the AVX instruction is a 4-byte opcode.
+// ------------------------------------------------------------------------------
+// Is4ByteAVXInstruction: Returns true if the AVX instruction is a 4-byte opcode.
+//
+// Arguments:
+// ins - instructions
+//
// 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 Is4ByteAVXInstruction(instruction ins)
+bool emitter::Is4ByteAVXInstruction(instruction ins)
{
-#ifdef FEATURE_AVX_SUPPORT
- return (ins == INS_dpps || ins == INS_dppd || ins == INS_insertps || ins == INS_pcmpeqq || ins == INS_pcmpgtq ||
+ 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);
-#else
+ ins == INS_pmulld || ins == INS_ptest || ins == INS_phaddd);
+}
+#endif // FEATURE_AVX_SUPPORT
+
+// -------------------------------------------------------------------
+// Is4ByteSSE4Instruction: Returns true if the SSE4 instruction
+// is a 4-byte opcode.
+//
+// Arguments:
+// ins - instruction
+//
+// Note that this should be true for any of the instructions in instrsXArch.h
+// that use the SSE38 or SSE3A macro.
+bool emitter::Is4ByteSSE4Instruction(instruction ins)
+{
+#ifdef LEGACY_BACKEND
+ // 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);
#endif
}
@@ -150,8 +182,9 @@ bool emitter::TakesVexPrefix(instruction ins)
// prefix. Based on 'attr' param we could add 2-byte VEX prefix in case of scalar
// and AVX-128 bit operations.
#define DEFAULT_3BYTE_VEX_PREFIX 0xC4E07800000000ULL
-#define LBIT_IN_3BYTE_VEX_PREFIX 0X00000400000000ULL
-size_t emitter::AddVexPrefix(instruction ins, size_t code, emitAttr attr)
+#define DEFAULT_3BYTE_VEX_PREFIX_MASK 0xFFFFFF00000000ULL
+#define LBIT_IN_3BYTE_VEX_PREFIX 0x00000400000000ULL
+emitter::code_t emitter::AddVexPrefix(instruction ins, code_t code, emitAttr attr)
{
// Only AVX instructions require VEX prefix
assert(IsAVXInstruction(ins));
@@ -160,6 +193,7 @@ size_t emitter::AddVexPrefix(instruction ins, size_t code, emitAttr attr)
assert(!hasVexPrefix(code));
// Set L bit to 1 in case of instructions that operate on 256-bits.
+ assert((code & DEFAULT_3BYTE_VEX_PREFIX_MASK) == 0);
code |= DEFAULT_3BYTE_VEX_PREFIX;
if (attr == EA_32BYTE)
{
@@ -296,25 +330,25 @@ bool IsXMMReg(regNumber reg)
}
// Returns bits to be encoded in instruction for the given register.
-regNumber RegEncoding(regNumber reg)
+unsigned RegEncoding(regNumber reg)
{
#ifndef LEGACY_BACKEND
// XMM registers do not share the same reg numbers as integer registers.
// But register encoding of integer and XMM registers is the same.
// Therefore, subtract XMMBASE from regNumber to get the register encoding
// in case of XMM registers.
- return (regNumber)((IsXMMReg(reg) ? reg - XMMBASE : reg) & 0x7);
+ return (unsigned)((IsXMMReg(reg) ? reg - XMMBASE : reg) & 0x7);
#else // LEGACY_BACKEND
// Legacy X86: XMM registers share the same reg numbers as integer registers and
// hence nothing to do to get reg encoding.
- return (regNumber)(reg & 0x7);
+ return (unsigned)(reg & 0x7);
#endif // LEGACY_BACKEND
}
// Utility routines that abstract the logic of adding REX.W, REX.R, REX.X, REX.B and REX prefixes
// SSE2: separate 1-byte prefix gets added before opcode.
// AVX: specific bits within VEX prefix need to be set in bit-inverted form.
-size_t emitter::AddRexWPrefix(instruction ins, size_t code)
+emitter::code_t emitter::AddRexWPrefix(instruction ins, code_t code)
{
#ifdef _TARGET_AMD64_
if (UseAVX() && IsAVXInstruction(ins))
@@ -335,7 +369,7 @@ size_t emitter::AddRexWPrefix(instruction ins, size_t code)
#ifdef _TARGET_AMD64_
-size_t emitter::AddRexRPrefix(instruction ins, size_t code)
+emitter::code_t emitter::AddRexRPrefix(instruction ins, code_t code)
{
if (UseAVX() && IsAVXInstruction(ins))
{
@@ -349,7 +383,7 @@ size_t emitter::AddRexRPrefix(instruction ins, size_t code)
return code | 0x4400000000ULL;
}
-size_t emitter::AddRexXPrefix(instruction ins, size_t code)
+emitter::code_t emitter::AddRexXPrefix(instruction ins, code_t code)
{
if (UseAVX() && IsAVXInstruction(ins))
{
@@ -363,7 +397,7 @@ size_t emitter::AddRexXPrefix(instruction ins, size_t code)
return code | 0x4200000000ULL;
}
-size_t emitter::AddRexBPrefix(instruction ins, size_t code)
+emitter::code_t emitter::AddRexBPrefix(instruction ins, code_t code)
{
if (UseAVX() && IsAVXInstruction(ins))
{
@@ -378,12 +412,14 @@ size_t emitter::AddRexBPrefix(instruction ins, size_t code)
}
// Adds REX prefix (0x40) without W, R, X or B bits set
-size_t emitter::AddRexPrefix(instruction ins, size_t code)
+emitter::code_t emitter::AddRexPrefix(instruction ins, code_t code)
{
assert(!UseAVX() || !IsAVXInstruction(ins));
return code | 0x4000000000ULL;
}
+#endif //_TARGET_AMD64_
+
bool isPrefix(BYTE b)
{
assert(b != 0); // Caller should check this
@@ -401,17 +437,15 @@ bool isPrefix(BYTE b)
return ((b == 0xF2) || (b == 0xF3) || (b == 0x66));
}
-#endif //_TARGET_AMD64_
-
// Outputs VEX prefix (in case of AVX instructions) and REX.R/X/W/B otherwise.
-unsigned emitter::emitOutputRexOrVexPrefixIfNeeded(instruction ins, BYTE* dst, size_t& code)
+unsigned emitter::emitOutputRexOrVexPrefixIfNeeded(instruction ins, BYTE* dst, code_t& code)
{
-#ifdef _TARGET_AMD64_ // TODO-x86: This needs to be enabled for AVX support on x86.
+#ifdef FEATURE_AVX_SUPPORT
if (hasVexPrefix(code))
{
// Only AVX instructions should have a VEX prefix
assert(UseAVX() && IsAVXInstruction(ins));
- size_t vexPrefix = (code >> 32) & 0x00FFFFFF;
+ code_t vexPrefix = (code >> 32) & 0x00FFFFFF;
code &= 0x00000000FFFFFFFFLL;
WORD leadingBytes = 0;
@@ -504,7 +538,10 @@ unsigned emitter::emitOutputRexOrVexPrefixIfNeeded(instruction ins, BYTE* dst, s
emitOutputByte(dst + 2, vexPrefix & 0xFF);
return 3;
}
- else if (code > 0x00FFFFFFFFLL)
+#endif // FEATURE_AVX_SUPPORT
+
+#ifdef _TARGET_AMD64_
+ if (code > 0x00FFFFFFFFLL)
{
BYTE prefix = (code >> 32) & 0xFF;
noway_assert(prefix >= 0x40 && prefix <= 0x4F);
@@ -543,13 +580,13 @@ unsigned emitter::emitOutputRexOrVexPrefixIfNeeded(instruction ins, BYTE* dst, s
{
// 3 prefixes were rex = rr, check = c1, check2 = c2 encoded as 0xrrc1c2XXXX
// Change to c2rrc1XXXX, and emit check2 now
- code = (((size_t)prefix << 24) | ((size_t)check << 16) | (code & 0x0000FFFFLL));
+ code = (((code_t)prefix << 24) | ((code_t)check << 16) | (code & 0x0000FFFFLL));
}
else
{
// 2 prefixes were rex = rr, check2 = c2 encoded as 0xrrXXc2XXXX, (check is part of the opcode)
// Change to c2XXrrXXXX, and emit check2 now
- code = (((size_t)check << 24) | ((size_t)prefix << 16) | (code & 0x0000FFFFLL));
+ code = (((code_t)check << 24) | ((code_t)prefix << 16) | (code & 0x0000FFFFLL));
}
return emitOutputByte(dst, check2);
}
@@ -593,7 +630,6 @@ void emitter::emitOutputPreEpilogNOP()
// Size of rex prefix in bytes
unsigned emitter::emitGetRexPrefixSize(instruction ins)
{
-
// In case of AVX instructions, REX prefixes are part of VEX prefix.
// And hence requires no additional byte to encode REX prefixes.
if (IsAVXInstruction(ins))
@@ -630,7 +666,7 @@ unsigned emitter::emitGetVexPrefixSize(instruction ins, emitAttr attr)
//=(opcodeSize - ExtrabytesSize) + vexPrefixSize
//=opcodeSize + (vexPrefixSize - ExtrabytesSize)
//=opcodeSize + vexPrefixAdjustedSize
-unsigned emitter::emitGetVexPrefixAdjustedSize(instruction ins, emitAttr attr, size_t code)
+unsigned emitter::emitGetVexPrefixAdjustedSize(instruction ins, emitAttr attr, code_t code)
{
#ifdef FEATURE_AVX_SUPPORT
if (IsAVXInstruction(ins))
@@ -674,19 +710,19 @@ unsigned emitter::emitGetVexPrefixAdjustedSize(instruction ins, emitAttr attr, s
}
// Get size of rex or vex prefix emitted in code
-unsigned emitter::emitGetPrefixSize(size_t code)
+unsigned emitter::emitGetPrefixSize(code_t code)
{
-#ifdef FEATURE_AVX_SUPPORT
- if (code & VEX_PREFIX_MASK_3BYTE)
+ if (hasVexPrefix(code))
{
return 3;
}
- else
-#endif
- if (code & REX_PREFIX_MASK)
+
+#ifdef _TARGET_AMD64_
+ if (code & REX_PREFIX_MASK)
{
return 1;
}
+#endif // _TARGET_AMD64_
return 0;
}
@@ -1058,7 +1094,7 @@ size_t insCodesMR[] =
// clang-format on
// Returns true iff the give CPU instruction has an MR encoding.
-inline size_t hasCodeMR(instruction ins)
+inline bool hasCodeMR(instruction ins)
{
assert((unsigned)ins < sizeof(insCodesMR) / sizeof(insCodesMR[0]));
return ((insCodesMR[ins] != BAD_CODE));
@@ -1083,7 +1119,7 @@ inline size_t insCodeMR(instruction ins)
* part of an opcode.
*/
-inline unsigned emitter::insEncodeReg012(instruction ins, regNumber reg, emitAttr size, size_t* code)
+inline unsigned emitter::insEncodeReg012(instruction ins, regNumber reg, emitAttr size, code_t* code)
{
assert(reg < REG_STK);
@@ -1106,16 +1142,16 @@ inline unsigned emitter::insEncodeReg012(instruction ins, regNumber reg, emitAtt
}
#endif // _TARGET_AMD64_
- reg = RegEncoding(reg);
- assert(reg < 8);
- return reg;
+ unsigned regBits = RegEncoding(reg);
#else // LEGACY_BACKEND
- assert(reg < 8);
- return reg;
+ unsigned regBits = reg;
#endif // LEGACY_BACKEND
+
+ assert(regBits < 8);
+ return regBits;
}
/*****************************************************************************
@@ -1124,7 +1160,7 @@ inline unsigned emitter::insEncodeReg012(instruction ins, regNumber reg, emitAtt
* part of an opcode.
*/
-inline unsigned emitter::insEncodeReg345(instruction ins, regNumber reg, emitAttr size, size_t* code)
+inline unsigned emitter::insEncodeReg345(instruction ins, regNumber reg, emitAttr size, code_t* code)
{
assert(reg < REG_STK);
@@ -1147,14 +1183,16 @@ inline unsigned emitter::insEncodeReg345(instruction ins, regNumber reg, emitAtt
}
#endif // _TARGET_AMD64_
- reg = RegEncoding(reg);
- assert(reg < 8);
- return (reg << 3);
+ unsigned regBits = RegEncoding(reg);
+
+#else // LEGACY_BACKEND
+
+ unsigned regBits = reg;
-#else // LEGACY_BACKEND
- assert(reg < 8);
- return (reg << 3);
#endif // LEGACY_BACKEND
+
+ assert(regBits < 8);
+ return (regBits << 3);
}
/***********************************************************************************
@@ -1162,7 +1200,7 @@ inline unsigned emitter::insEncodeReg345(instruction ins, regNumber reg, emitAtt
* Returns modified AVX opcode with the specified register encoded in bits 3-6 of
* byte 2 of VEX prefix.
*/
-inline size_t emitter::insEncodeReg3456(instruction ins, regNumber reg, emitAttr size, size_t code)
+inline emitter::code_t emitter::insEncodeReg3456(instruction ins, regNumber reg, emitAttr size, code_t code)
{
#ifdef FEATURE_AVX_SUPPORT
assert(reg < REG_STK);
@@ -1172,7 +1210,7 @@ inline size_t emitter::insEncodeReg3456(instruction ins, regNumber reg, emitAttr
// Get 4-bit register encoding
// RegEncoding() gives lower 3 bits
// IsExtendedReg() gives MSB.
- size_t regBits = RegEncoding(reg);
+ code_t regBits = RegEncoding(reg);
if (IsExtendedReg(reg))
{
regBits |= 0x08;
@@ -1196,7 +1234,7 @@ inline size_t emitter::insEncodeReg3456(instruction ins, regNumber reg, emitAttr
* Used exclusively to generate the REX.X bit and truncate the register.
*/
-inline unsigned emitter::insEncodeRegSIB(instruction ins, regNumber reg, size_t* code)
+inline unsigned emitter::insEncodeRegSIB(instruction ins, regNumber reg, code_t* code)
{
assert(reg < REG_STK);
@@ -1210,11 +1248,13 @@ inline unsigned emitter::insEncodeRegSIB(instruction ins, regNumber reg, size_t*
{
*code = AddRexXPrefix(ins, *code); // REX.X
}
- reg = RegEncoding(reg);
-#endif
+ unsigned regBits = RegEncoding(reg);
+#else // !_TARGET_AMD64_
+ unsigned regBits = reg;
+#endif // !_TARGET_AMD64_
- assert(reg < 8);
- return reg;
+ assert(regBits < 8);
+ return regBits;
}
/*****************************************************************************
@@ -1222,7 +1262,7 @@ inline unsigned emitter::insEncodeRegSIB(instruction ins, regNumber reg, size_t*
* Returns the "[r/m]" opcode with the mod/RM field set to register.
*/
-inline size_t emitter::insEncodeMRreg(instruction ins, size_t code)
+inline emitter::code_t emitter::insEncodeMRreg(instruction ins, code_t code)
{
// If Byte 4 (which is 0xFF00) is 0, that's where the RM encoding goes.
// Otherwise, it will be placed after the 4 byte encoding.
@@ -1237,22 +1277,10 @@ inline size_t emitter::insEncodeMRreg(instruction ins, size_t code)
/*****************************************************************************
*
- * Returns the "[r/m], icon" opcode with the mod/RM field set to register.
- */
-
-inline size_t insEncodeMIreg(instruction ins, size_t code)
-{
- assert((code & 0xC000) == 0);
- code |= 0xC000;
- return code;
-}
-
-/*****************************************************************************
- *
* Returns the given "[r/m]" opcode with the mod/RM field set to register.
*/
-inline size_t insEncodeRMreg(instruction ins, size_t code)
+inline emitter::code_t emitter::insEncodeRMreg(instruction ins, code_t code)
{
// If Byte 4 (which is 0xFF00) is 0, that's where the RM encoding goes.
// Otherwise, it will be placed after the 4 byte encoding.
@@ -1270,7 +1298,7 @@ inline size_t insEncodeRMreg(instruction ins, size_t code)
* the given register.
*/
-inline size_t emitter::insEncodeMRreg(instruction ins, regNumber reg, emitAttr size, size_t code)
+inline emitter::code_t emitter::insEncodeMRreg(instruction ins, regNumber reg, emitAttr size, code_t code)
{
assert((code & 0xC000) == 0);
code |= 0xC000;
@@ -1285,7 +1313,7 @@ inline size_t emitter::insEncodeMRreg(instruction ins, regNumber reg, emitAttr s
* the given register.
*/
-inline size_t emitter::insEncodeMIreg(instruction ins, regNumber reg, emitAttr size, size_t code)
+inline emitter::code_t emitter::insEncodeMIreg(instruction ins, regNumber reg, emitAttr size, code_t code)
{
assert((code & 0xC000) == 0);
code |= 0xC000;
@@ -1310,12 +1338,12 @@ inline bool insNeedsRRIb(instruction ins)
* Returns the "reg,reg,imm8" opcode with both the reg's set to the
* the given register.
*/
-inline size_t emitter::insEncodeRRIb(instruction ins, regNumber reg, emitAttr size)
+inline emitter::code_t emitter::insEncodeRRIb(instruction ins, regNumber reg, emitAttr size)
{
assert(size == EA_4BYTE); // All we handle for now.
assert(insNeedsRRIb(ins));
// If this list gets longer, use a switch, or a table lookup.
- size_t code = 0x69c0;
+ code_t code = 0x69c0;
unsigned regcode = insEncodeReg012(ins, reg, size, &code);
// We use the same register as source and destination. (Could have another version that does both regs...)
code |= regcode;
@@ -1329,9 +1357,9 @@ inline size_t emitter::insEncodeRRIb(instruction ins, regNumber reg, emitAttr si
* nibble of the opcode
*/
-inline size_t emitter::insEncodeOpreg(instruction ins, regNumber reg, emitAttr size)
+inline emitter::code_t emitter::insEncodeOpreg(instruction ins, regNumber reg, emitAttr size)
{
- size_t code = insCodeRR(ins);
+ code_t code = insCodeRR(ins);
unsigned regcode = insEncodeReg012(ins, reg, size, &code);
code |= regcode;
return code;
@@ -1342,7 +1370,7 @@ inline size_t emitter::insEncodeOpreg(instruction ins, regNumber reg, emitAttr s
* Return the 'SS' field value for the given index scale factor.
*/
-inline unsigned insSSval(unsigned scale)
+inline unsigned emitter::insSSval(unsigned scale)
{
assert(scale == 1 || scale == 2 || scale == 4 || scale == 8);
@@ -1447,7 +1475,7 @@ bool emitter::emitVerifyEncodable(instruction ins, emitAttr size, regNumber reg1
* Estimate the size (in bytes of generated code) of the given instruction.
*/
-inline UNATIVE_OFFSET emitter::emitInsSize(size_t code)
+inline UNATIVE_OFFSET emitter::emitInsSize(code_t code)
{
UNATIVE_OFFSET size = (code & 0xFF000000) ? 4 : (code & 0x00FF0000) ? 3 : 2;
#ifdef _TARGET_AMD64_
@@ -1466,18 +1494,17 @@ inline UNATIVE_OFFSET emitter::emitInsSizeRR(instruction ins, regNumber reg1, re
emitAttr size = EA_SIZE(attr);
UNATIVE_OFFSET sz;
-#ifdef _TARGET_AMD64_
- // If Byte 4 (which is 0xFF00) is non-zero, that's where the RM encoding goes.
+
+ // If Byte 4 (which is 0xFF00) is zero, that's where the RM encoding goes.
// Otherwise, it will be placed after the 4 byte encoding, making the total 5 bytes.
// This would probably be better expressed as a different format or something?
- if (insCodeRM(ins) & 0xFF00)
+ if ((insCodeRM(ins) & 0xFF00) != 0)
{
sz = 5;
}
else
-#endif // _TARGET_AMD64_
{
- size_t code = insCodeRM(ins);
+ code_t code = insCodeRM(ins);
sz = emitInsSize(insEncodeRMreg(ins, code));
}
@@ -1502,7 +1529,7 @@ inline UNATIVE_OFFSET emitter::emitInsSizeRR(instruction ins, regNumber reg1, re
/*****************************************************************************/
-inline UNATIVE_OFFSET emitter::emitInsSizeSV(size_t code, int var, int dsp)
+inline UNATIVE_OFFSET emitter::emitInsSizeSV(code_t code, int var, int dsp)
{
UNATIVE_OFFSET size = emitInsSize(code);
UNATIVE_OFFSET offs;
@@ -1777,7 +1804,7 @@ static bool baseRegisterRequiresDisplacement(regNumber base)
#endif
}
-UNATIVE_OFFSET emitter::emitInsSizeAM(instrDesc* id, size_t code)
+UNATIVE_OFFSET emitter::emitInsSizeAM(instrDesc* id, code_t code)
{
emitAttr attrSize = id->idOpSize();
instruction ins = id->idIns();
@@ -1994,7 +2021,7 @@ UNATIVE_OFFSET emitter::emitInsSizeAM(instrDesc* id, size_t code)
return size;
}
-inline UNATIVE_OFFSET emitter::emitInsSizeAM(instrDesc* id, size_t code, int val)
+inline UNATIVE_OFFSET emitter::emitInsSizeAM(instrDesc* id, code_t code, int val)
{
instruction ins = id->idIns();
UNATIVE_OFFSET valSize = EA_SIZE_IN_BYTES(id->idOpSize());
@@ -2027,7 +2054,7 @@ inline UNATIVE_OFFSET emitter::emitInsSizeAM(instrDesc* id, size_t code, int val
return valSize + emitInsSizeAM(id, code);
}
-inline UNATIVE_OFFSET emitter::emitInsSizeCV(instrDesc* id, size_t code)
+inline UNATIVE_OFFSET emitter::emitInsSizeCV(instrDesc* id, code_t code)
{
instruction ins = id->idIns();
@@ -2047,7 +2074,7 @@ inline UNATIVE_OFFSET emitter::emitInsSizeCV(instrDesc* id, size_t code)
return size + emitInsSize(code);
}
-inline UNATIVE_OFFSET emitter::emitInsSizeCV(instrDesc* id, size_t code, int val)
+inline UNATIVE_OFFSET emitter::emitInsSizeCV(instrDesc* id, code_t code, int val)
{
instruction ins = id->idIns();
UNATIVE_OFFSET valSize = EA_SIZE_IN_BYTES(id->idOpSize());
@@ -2252,7 +2279,7 @@ void emitter::emitIns(instruction ins)
{
UNATIVE_OFFSET sz;
instrDesc* id = emitNewInstr();
- size_t code = insCodeMR(ins);
+ code_t code = insCodeMR(ins);
#ifdef DEBUG
#if FEATURE_STACK_FP_X87
@@ -2328,7 +2355,7 @@ void emitter::emitIns(instruction ins, emitAttr attr)
{
UNATIVE_OFFSET sz;
instrDesc* id = emitNewInstr(attr);
- size_t code = insCodeMR(ins);
+ code_t code = insCodeMR(ins);
assert(ins == INS_cdq);
assert((code & 0xFFFFFF00) == 0);
sz = 1;
@@ -2499,8 +2526,9 @@ void emitter::emitHandleMemOp(GenTreeIndir* indir, instrDesc* id, insFormat fmt,
// Absolute addresses marked as contained should fit within the base of addr mode.
assert(memBase->AsIntConCommon()->FitsInAddrBase(emitComp));
- // Either not generating relocatable code or addr must be an icon handle
- assert(!emitComp->opts.compReloc || memBase->IsIconHandle());
+ // Either not generating relocatable code, or addr must be an icon handle, or the
+ // constant is zero (which we won't generate a relocation for).
+ assert(!emitComp->opts.compReloc || memBase->IsIconHandle() || memBase->IsIntegralConst(0));
if (memBase->AsIntConCommon()->AddrNeedsReloc(emitComp))
{
@@ -2904,6 +2932,19 @@ regNumber emitter::emitInsBinary(instruction ins, emitAttr attr, GenTree* dst, G
varNum = tmpDsc->tdTempNum();
offset = 0;
}
+ else
+ {
+ // At this point we must have a memory operand that is a contained indir: if we do not, we should have handled
+ // this instruction above in the reg/imm or reg/reg case.
+ assert(mem != nullptr);
+ assert(memBase != nullptr);
+
+ if (memBase->OperGet() == GT_LCL_VAR_ADDR)
+ {
+ varNum = memBase->AsLclVarCommon()->GetLclNum();
+ offset = 0;
+ }
+ }
// Spill temp numbers are negative and start with -1
// which also happens to be BAD_VAR_NUM. For this reason
@@ -2911,7 +2952,7 @@ regNumber emitter::emitInsBinary(instruction ins, emitAttr attr, GenTree* dst, G
if (varNum != BAD_VAR_NUM || tmpDsc != nullptr)
{
// Is the memory op in the source position?
- if (src->isContainedLclField() || src->isContainedLclVar() || src->isContainedSpillTemp())
+ if (src->isContainedMemoryOp())
{
if (instrHasImplicitRegPairDest(ins))
{
@@ -3351,22 +3392,7 @@ void emitter::emitIns_R(instruction ins, emitAttr attr, regNumber reg)
dispIns(id);
emitCurIGsize += sz;
-#if !FEATURE_FIXED_OUT_ARGS
-
- if (ins == INS_push)
- {
- emitCurStackLvl += emitCntStackDepth;
-
- if (emitMaxStackDepth < emitCurStackLvl)
- emitMaxStackDepth = emitCurStackLvl;
- }
- else if (ins == INS_pop)
- {
- emitCurStackLvl -= emitCntStackDepth;
- assert((int)emitCurStackLvl >= 0);
- }
-
-#endif // !FEATURE_FIXED_OUT_ARGS
+ emitAdjustStackDepthPushPop(ins);
}
/*****************************************************************************
@@ -3484,7 +3510,7 @@ void emitter::emitIns_R_I(instruction ins, emitAttr attr, regNumber reg, ssize_t
sz += emitGetRexPrefixSize(ins);
}
-#ifdef _TARGET_X86_
+#if defined(_TARGET_X86_) && defined(LEGACY_BACKEND)
assert(reg < 8);
#endif
@@ -3504,34 +3530,10 @@ void emitter::emitIns_R_I(instruction ins, emitAttr attr, regNumber reg, ssize_t
dispIns(id);
emitCurIGsize += sz;
-#if !FEATURE_FIXED_OUT_ARGS
-
if (reg == REG_ESP)
{
- if (emitCntStackDepth)
- {
- if (ins == INS_sub)
- {
- S_UINT32 newStackLvl(emitCurStackLvl);
- newStackLvl += S_UINT32(val);
- noway_assert(!newStackLvl.IsOverflow());
-
- emitCurStackLvl = newStackLvl.Value();
-
- if (emitMaxStackDepth < emitCurStackLvl)
- emitMaxStackDepth = emitCurStackLvl;
- }
- else if (ins == INS_add)
- {
- S_UINT32 newStackLvl = S_UINT32(emitCurStackLvl) - S_UINT32(val);
- noway_assert(!newStackLvl.IsOverflow());
-
- emitCurStackLvl = newStackLvl.Value();
- }
- }
+ emitAdjustStackDepth(ins, val);
}
-
-#endif // !FEATURE_FIXED_OUT_ARGS
}
/*****************************************************************************
@@ -3584,17 +3586,7 @@ void emitter::emitIns_I(instruction ins, emitAttr attr, int val)
dispIns(id);
emitCurIGsize += sz;
-#if !FEATURE_FIXED_OUT_ARGS
-
- if (ins == INS_push)
- {
- emitCurStackLvl += emitCntStackDepth;
-
- if (emitMaxStackDepth < emitCurStackLvl)
- emitMaxStackDepth = emitCurStackLvl;
- }
-
-#endif // !FEATURE_FIXED_OUT_ARGS
+ emitAdjustStackDepthPushPop(ins);
}
/*****************************************************************************
@@ -3693,22 +3685,7 @@ void emitter::emitIns_C(instruction ins, emitAttr attr, CORINFO_FIELD_HANDLE fld
dispIns(id);
emitCurIGsize += sz;
-#if !FEATURE_FIXED_OUT_ARGS
-
- if (ins == INS_push)
- {
- emitCurStackLvl += emitCntStackDepth;
-
- if (emitMaxStackDepth < emitCurStackLvl)
- emitMaxStackDepth = emitCurStackLvl;
- }
- else if (ins == INS_pop)
- {
- emitCurStackLvl -= emitCntStackDepth;
- assert((int)emitCurStackLvl >= 0);
- }
-
-#endif // !FEATURE_FIXED_OUT_ARGS
+ emitAdjustStackDepthPushPop(ins);
}
/*****************************************************************************
@@ -3757,11 +3734,14 @@ void emitter::emitIns_R_R(instruction ins, emitAttr attr, regNumber reg1, regNum
void emitter::emitIns_R_R_I(instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, int ival)
{
- // SSE2 version requires 5 bytes and AVX version 6 bytes
+ // SSE2 version requires 5 bytes and SSE4/AVX version 6 bytes
UNATIVE_OFFSET sz = 4;
if (IsSSEOrAVXInstruction(ins))
{
- sz = UseAVX() ? 6 : 5;
+ // AVX: 3 byte VEX prefix + 1 byte opcode + 1 byte ModR/M + 1 byte immediate
+ // SSE4: 4 byte opcode + 1 byte ModR/M + 1 byte immediate
+ // SSE2: 3 byte opcode + 1 byte ModR/M + 1 byte immediate
+ sz = (UseAVX() || UseSSE3_4()) ? 6 : 5;
}
#ifdef _TARGET_AMD64_
@@ -4014,7 +3994,7 @@ void emitter::emitIns_C_I(instruction ins, emitAttr attr, CORINFO_FIELD_HANDLE f
id->idIns(ins);
id->idInsFmt(fmt);
- size_t code = insCodeMI(ins);
+ code_t code = insCodeMI(ins);
UNATIVE_OFFSET sz = emitInsSizeCV(id, code, val);
#ifdef _TARGET_AMD64_
@@ -4387,22 +4367,7 @@ void emitter::emitIns_AR_R(
dispIns(id);
emitCurIGsize += sz;
-#if !FEATURE_FIXED_OUT_ARGS
-
- if (ins == INS_push)
- {
- emitCurStackLvl += emitCntStackDepth;
-
- if (emitMaxStackDepth < emitCurStackLvl)
- emitMaxStackDepth = emitCurStackLvl;
- }
- else if (ins == INS_pop)
- {
- emitCurStackLvl -= emitCntStackDepth;
- assert((int)emitCurStackLvl >= 0);
- }
-
-#endif // !FEATURE_FIXED_OUT_ARGS
+ emitAdjustStackDepthPushPop(ins);
}
void emitter::emitIns_AI_R(instruction ins, emitAttr attr, regNumber ireg, ssize_t disp)
@@ -4443,22 +4408,7 @@ void emitter::emitIns_AI_R(instruction ins, emitAttr attr, regNumber ireg, ssize
dispIns(id);
emitCurIGsize += sz;
-#if !FEATURE_FIXED_OUT_ARGS
-
- if (ins == INS_push)
- {
- emitCurStackLvl += emitCntStackDepth;
-
- if (emitMaxStackDepth < emitCurStackLvl)
- emitMaxStackDepth = emitCurStackLvl;
- }
- else if (ins == INS_pop)
- {
- emitCurStackLvl -= emitCntStackDepth;
- assert((int)emitCurStackLvl >= 0);
- }
-
-#endif // !FEATURE_FIXED_OUT_ARGS
+ emitAdjustStackDepthPushPop(ins);
}
void emitter::emitIns_I_ARR(instruction ins, emitAttr attr, int val, regNumber reg, regNumber rg2, int disp)
@@ -4575,22 +4525,7 @@ void emitter::emitIns_ARR_R(instruction ins, emitAttr attr, regNumber ireg, regN
dispIns(id);
emitCurIGsize += sz;
-#if !FEATURE_FIXED_OUT_ARGS
-
- if (ins == INS_push)
- {
- emitCurStackLvl += emitCntStackDepth;
-
- if (emitMaxStackDepth < emitCurStackLvl)
- emitMaxStackDepth = emitCurStackLvl;
- }
- else if (ins == INS_pop)
- {
- emitCurStackLvl -= emitCntStackDepth;
- assert((int)emitCurStackLvl >= 0);
- }
-
-#endif // !FEATURE_FIXED_OUT_ARGS
+ emitAdjustStackDepthPushPop(ins);
}
void emitter::emitIns_I_ARX(
@@ -4711,22 +4646,7 @@ void emitter::emitIns_ARX_R(
dispIns(id);
emitCurIGsize += sz;
-#if !FEATURE_FIXED_OUT_ARGS
-
- if (ins == INS_push)
- {
- emitCurStackLvl += emitCntStackDepth;
-
- if (emitMaxStackDepth < emitCurStackLvl)
- emitMaxStackDepth = emitCurStackLvl;
- }
- else if (ins == INS_pop)
- {
- emitCurStackLvl -= emitCntStackDepth;
- assert((int)emitCurStackLvl >= 0);
- }
-
-#endif // !FEATURE_FIXED_OUT_ARGS
+ emitAdjustStackDepthPushPop(ins);
}
void emitter::emitIns_I_AX(instruction ins, emitAttr attr, int val, regNumber reg, unsigned mul, int disp)
@@ -4842,22 +4762,7 @@ void emitter::emitIns_AX_R(instruction ins, emitAttr attr, regNumber ireg, regNu
dispIns(id);
emitCurIGsize += sz;
-#if !FEATURE_FIXED_OUT_ARGS
-
- if (ins == INS_push)
- {
- emitCurStackLvl += emitCntStackDepth;
-
- if (emitMaxStackDepth < emitCurStackLvl)
- emitMaxStackDepth = emitCurStackLvl;
- }
- else if (ins == INS_pop)
- {
- emitCurStackLvl -= emitCntStackDepth;
- assert((int)emitCurStackLvl >= 0);
- }
-
-#endif // !FEATURE_FIXED_OUT_ARGS
+ emitAdjustStackDepthPushPop(ins);
}
/*****************************************************************************
@@ -4901,22 +4806,7 @@ void emitter::emitIns_S(instruction ins, emitAttr attr, int varx, int offs)
dispIns(id);
emitCurIGsize += sz;
-#if !FEATURE_FIXED_OUT_ARGS
-
- if (ins == INS_push)
- {
- emitCurStackLvl += emitCntStackDepth;
-
- if (emitMaxStackDepth < emitCurStackLvl)
- emitMaxStackDepth = emitCurStackLvl;
- }
- else if (ins == INS_pop)
- {
- emitCurStackLvl -= emitCntStackDepth;
- assert((int)emitCurStackLvl >= 0);
- }
-
-#endif // !FEATURE_FIXED_OUT_ARGS
+ emitAdjustStackDepthPushPop(ins);
}
void emitter::emitIns_S_R(instruction ins, emitAttr attr, regNumber ireg, int varx, int offs)
@@ -5197,8 +5087,23 @@ void emitter::emitIns_J(instruction ins, BasicBlock* dst, int instrCount /* = 0
dispIns(id);
emitCurIGsize += sz;
+ emitAdjustStackDepthPushPop(ins);
+}
+
#if !FEATURE_FIXED_OUT_ARGS
+//------------------------------------------------------------------------
+// emitAdjustStackDepthPushPop: Adjust the current and maximum stack depth.
+//
+// Arguments:
+// ins - the instruction. Only INS_push and INS_pop adjust the stack depth.
+//
+// Notes:
+// 1. Alters emitCurStackLvl and possibly emitMaxStackDepth.
+// 2. emitCntStackDepth must be set (0 in prolog/epilog, one DWORD elsewhere)
+//
+void emitter::emitAdjustStackDepthPushPop(instruction ins)
+{
if (ins == INS_push)
{
emitCurStackLvl += emitCntStackDepth;
@@ -5206,10 +5111,53 @@ void emitter::emitIns_J(instruction ins, BasicBlock* dst, int instrCount /* = 0
if (emitMaxStackDepth < emitCurStackLvl)
emitMaxStackDepth = emitCurStackLvl;
}
+ else if (ins == INS_pop)
+ {
+ emitCurStackLvl -= emitCntStackDepth;
+ assert((int)emitCurStackLvl >= 0);
+ }
+}
-#endif // !FEATURE_FIXED_OUT_ARGS
+//------------------------------------------------------------------------
+// emitAdjustStackDepth: Adjust the current and maximum stack depth.
+//
+// Arguments:
+// ins - the instruction. Only INS_add and INS_sub adjust the stack depth.
+// It is assumed that the add/sub is on the stack pointer.
+// val - the number of bytes to add to or subtract from the stack pointer.
+//
+// Notes:
+// 1. Alters emitCurStackLvl and possibly emitMaxStackDepth.
+// 2. emitCntStackDepth must be set (0 in prolog/epilog, one DWORD elsewhere)
+//
+void emitter::emitAdjustStackDepth(instruction ins, ssize_t val)
+{
+ // If we're in the prolog or epilog, or otherwise not tracking the stack depth, just return.
+ if (emitCntStackDepth == 0)
+ return;
+
+ if (ins == INS_sub)
+ {
+ S_UINT32 newStackLvl(emitCurStackLvl);
+ newStackLvl += S_UINT32(val);
+ noway_assert(!newStackLvl.IsOverflow());
+
+ emitCurStackLvl = newStackLvl.Value();
+
+ if (emitMaxStackDepth < emitCurStackLvl)
+ emitMaxStackDepth = emitCurStackLvl;
+ }
+ else if (ins == INS_add)
+ {
+ S_UINT32 newStackLvl = S_UINT32(emitCurStackLvl) - S_UINT32(val);
+ noway_assert(!newStackLvl.IsOverflow());
+
+ emitCurStackLvl = newStackLvl.Value();
+ }
}
+#endif // EMIT_TRACK_STACK_DEPTH
+
/*****************************************************************************
*
* Add a call instruction (direct or indirect).
@@ -5393,13 +5341,11 @@ void emitter::emitIns_Call(EmitCallType callType,
assert(argSize % sizeof(void*) == 0);
argCnt = (int)(argSize / (ssize_t)sizeof(void*)); // we need a signed-divide
-#ifdef DEBUGGING_SUPPORT
/* Managed RetVal: emit sequence point for the call */
if (emitComp->opts.compDbgInfo && ilOffset != BAD_IL_OFFSET)
{
codeGen->genIPmappingAdd(ilOffset, false);
}
-#endif
/*
We need to allocate the appropriate instruction descriptor based
@@ -5793,9 +5739,18 @@ const char* emitter::emitRegName(regNumber reg, emitAttr attr, bool varName)
return emitXMMregName(reg);
case EA_8BYTE:
+ if ((REG_XMM0 <= reg) && (reg <= REG_XMM15))
+ {
+ return emitXMMregName(reg);
+ }
break;
case EA_4BYTE:
+ if ((REG_XMM0 <= reg) && (reg <= REG_XMM15))
+ {
+ return emitXMMregName(reg);
+ }
+
if (reg > REG_R15)
{
break;
@@ -5880,10 +5835,24 @@ const char* emitter::emitRegName(regNumber reg, emitAttr attr, bool varName)
case EA_16BYTE:
return emitXMMregName(reg);
-#endif // LEGACY_BACKEND
+ case EA_8BYTE:
+ if ((REG_XMM0 <= reg) && (reg <= REG_XMM7))
+ {
+ return emitXMMregName(reg);
+ }
+ break;
+
+ case EA_4BYTE:
+ if ((REG_XMM0 <= reg) && (reg <= REG_XMM7))
+ {
+ return emitXMMregName(reg);
+ }
+ break;
+#else // LEGACY_BACKEND
case EA_4BYTE:
break;
+#endif // LEGACY_BACKEND
case EA_2BYTE:
rn++;
@@ -6661,9 +6630,9 @@ void emitter::emitDispIns(
printf(" %-9s", sstr);
}
#ifndef FEATURE_PAL
- if (strnlen_s(sstr, 10) > 8)
+ if (strnlen_s(sstr, 10) >= 8)
#else // FEATURE_PAL
- if (strnlen(sstr, 10) > 8)
+ if (strnlen(sstr, 10) >= 8)
#endif // FEATURE_PAL
{
printf(" ");
@@ -6808,17 +6777,8 @@ void emitter::emitDispIns(
case IF_RRD_ARD:
case IF_RWR_ARD:
case IF_RRW_ARD:
- if (IsAVXInstruction(ins))
- {
- printf("%s, %s", emitYMMregName((unsigned)id->idReg1()), sstr);
- }
- else if (IsSSE2Instruction(ins))
- {
- printf("%s, %s", emitXMMregName((unsigned)id->idReg1()), sstr);
- }
- else
#ifdef _TARGET_AMD64_
- if (ins == INS_movsxd)
+ if (ins == INS_movsxd)
{
printf("%s, %s", emitRegName(id->idReg1(), EA_8BYTE), sstr);
}
@@ -6841,18 +6801,7 @@ void emitter::emitDispIns(
printf("%s", sstr);
emitDispAddrMode(id);
- if (IsAVXInstruction(ins))
- {
- printf(", %s", emitYMMregName((unsigned)id->idReg1()));
- }
- else if (IsSSE2Instruction(ins))
- {
- printf(", %s", emitXMMregName((unsigned)id->idReg1()));
- }
- else
- {
- printf(", %s", emitRegName(id->idReg1(), attr));
- }
+ printf(", %s", emitRegName(id->idReg1(), attr));
break;
case IF_ARD_CNS:
@@ -6930,18 +6879,7 @@ void emitter::emitDispIns(
emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(),
id->idDebugOnlyInfo()->idVarRefOffs, asmfm);
- if (IsAVXInstruction(ins))
- {
- printf(", %s", emitYMMregName((unsigned)id->idReg1()));
- }
- else if (IsSSE2Instruction(ins))
- {
- printf(", %s", emitXMMregName((unsigned)id->idReg1()));
- }
- else
- {
- printf(", %s", emitRegName(id->idReg1(), attr));
- }
+ printf(", %s", emitRegName(id->idReg1(), attr));
break;
case IF_SRD_CNS:
@@ -6983,17 +6921,8 @@ void emitter::emitDispIns(
case IF_RRD_SRD:
case IF_RWR_SRD:
case IF_RRW_SRD:
- if (IsAVXInstruction(ins))
- {
- printf("%s, %s", emitYMMregName((unsigned)id->idReg1()), sstr);
- }
- else if (IsSSE2Instruction(ins))
- {
- printf("%s, %s", emitXMMregName((unsigned)id->idReg1()), sstr);
- }
- else
#ifdef _TARGET_AMD64_
- if (ins == INS_movsxd)
+ if (ins == INS_movsxd)
{
printf("%s, %s", emitRegName(id->idReg1(), EA_8BYTE), sstr);
}
@@ -7016,36 +6945,31 @@ void emitter::emitDispIns(
case IF_RRD_RRD:
case IF_RWR_RRD:
case IF_RRW_RRD:
-
if (ins == INS_mov_i2xmm)
{
- printf("%s, %s", emitXMMregName((unsigned)id->idReg1()), emitRegName(id->idReg2(), attr));
+ printf("%s, %s", emitRegName(id->idReg1(), EA_16BYTE), emitRegName(id->idReg2(), attr));
}
else if (ins == INS_mov_xmm2i)
{
- printf("%s, %s", emitRegName(id->idReg2(), attr), emitXMMregName((unsigned)id->idReg1()));
+ printf("%s, %s", emitRegName(id->idReg2(), attr), emitRegName(id->idReg1(), EA_16BYTE));
+ }
+ else if (ins == INS_pmovmskb)
+ {
+ printf("%s, %s", emitRegName(id->idReg1(), EA_4BYTE), emitRegName(id->idReg2(), attr));
}
#ifndef LEGACY_BACKEND
else if ((ins == INS_cvtsi2ss) || (ins == INS_cvtsi2sd))
{
- printf(" %s, %s", emitXMMregName((unsigned)id->idReg1()), emitRegName(id->idReg2(), attr));
+ printf(" %s, %s", emitRegName(id->idReg1(), EA_16BYTE), emitRegName(id->idReg2(), attr));
}
#endif
else if ((ins == INS_cvttsd2si)
#ifndef LEGACY_BACKEND
|| (ins == INS_cvtss2si) || (ins == INS_cvtsd2si) || (ins == INS_cvttss2si)
#endif
- )
- {
- printf(" %s, %s", emitRegName(id->idReg1(), attr), emitXMMregName((unsigned)id->idReg2()));
- }
- else if (IsAVXInstruction(ins))
- {
- printf("%s, %s", emitYMMregName((unsigned)id->idReg1()), emitYMMregName((unsigned)id->idReg2()));
- }
- else if (IsSSE2Instruction(ins))
+ || 0)
{
- printf("%s, %s", emitXMMregName((unsigned)id->idReg1()), emitXMMregName((unsigned)id->idReg2()));
+ printf(" %s, %s", emitRegName(id->idReg1(), attr), emitRegName(id->idReg2(), EA_16BYTE));
}
#ifdef _TARGET_AMD64_
else if (ins == INS_movsxd)
@@ -7079,16 +7003,8 @@ void emitter::emitDispIns(
break;
#endif
case IF_RRW_RRW_CNS:
- if (IsAVXInstruction(ins))
- {
- printf("%s,", emitYMMregName((unsigned)id->idReg1()), attr);
- printf(" %s", emitYMMregName((unsigned)id->idReg2()), attr);
- }
- else
- {
- printf("%s,", emitRegName(id->idReg1(), attr));
- printf(" %s", emitRegName(id->idReg2(), attr));
- }
+ printf("%s,", emitRegName(id->idReg1(), attr));
+ printf(" %s", emitRegName(id->idReg2(), attr));
val = emitGetInsSC(id);
#ifdef _TARGET_AMD64_
// no 8-byte immediates allowed here!
@@ -7133,18 +7049,7 @@ void emitter::emitDispIns(
attr = EA_PTRSIZE;
}
#endif
- if (IsAVXInstruction(ins))
- {
- printf("%s, %s", emitYMMregName((unsigned)id->idReg1()), sstr);
- }
- else if (IsSSE2Instruction(ins))
- {
- printf("%s, %s", emitXMMregName((unsigned)id->idReg1()), sstr);
- }
- else
- {
- printf("%s, %s", emitRegName(id->idReg1(), attr), sstr);
- }
+ printf("%s, %s", emitRegName(id->idReg1(), attr), sstr);
offs = emitGetInsDsp(id);
emitDispClsVar(id->idAddr()->iiaFieldHnd, offs, ID_INFO_DSP_RELOC);
break;
@@ -7521,7 +7426,7 @@ static BYTE* emitOutputNOP(BYTE* dst, size_t nBytes)
* Output an instruction involving an address mode.
*/
-BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, size_t code, CnsVal* addc)
+BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc)
{
regNumber reg;
regNumber rgx;
@@ -7543,7 +7448,7 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, size_t code, CnsVal* addc)
// Special case: call via a register
if (id->idIsCallRegPtr())
{
- size_t opcode = insEncodeMRreg(INS_call, reg, EA_PTRSIZE, insCodeMR(INS_call));
+ code_t opcode = insEncodeMRreg(INS_call, reg, EA_PTRSIZE, insCodeMR(INS_call));
dst += emitOutputRexOrVexPrefixIfNeeded(ins, dst, opcode);
dst += emitOutputWord(dst, opcode);
@@ -7559,13 +7464,15 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, size_t code, CnsVal* addc)
if (IsExtendedReg(reg, EA_PTRSIZE))
{
insEncodeReg012(ins, reg, EA_PTRSIZE, &code);
- reg = RegEncoding(reg);
+ // TODO-Cleanup: stop casting RegEncoding() back to a regNumber.
+ reg = (regNumber)RegEncoding(reg);
}
if (IsExtendedReg(rgx, EA_PTRSIZE))
{
insEncodeRegSIB(ins, rgx, &code);
- rgx = RegEncoding(rgx);
+ // TODO-Cleanup: stop casting RegEncoding() back to a regNumber.
+ rgx = (regNumber)RegEncoding(rgx);
}
// And emit the REX prefix
@@ -7605,7 +7512,7 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, size_t code, CnsVal* addc)
// For this format, moves do not support a third operand, so we only need to handle the binary ops.
if (IsThreeOperandBinaryAVXInstruction(ins))
{
- // Encode source operand reg in 'vvvv' bits in 1's compliement form
+ // Encode source operand reg in 'vvvv' bits in 1's complement form
// The order of operands are reversed, therefore use reg2 as the source.
code = insEncodeReg3456(ins, id->idReg1(), size, code);
}
@@ -7619,13 +7526,15 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, size_t code, CnsVal* addc)
if (IsExtendedReg(reg, EA_PTRSIZE))
{
insEncodeReg012(ins, reg, EA_PTRSIZE, &code);
- reg = RegEncoding(reg);
+ // TODO-Cleanup: stop casting RegEncoding() back to a regNumber.
+ reg = (regNumber)RegEncoding(reg);
}
if (IsExtendedReg(rgx, EA_PTRSIZE))
{
insEncodeRegSIB(ins, rgx, &code);
- rgx = RegEncoding(rgx);
+ // TODO-Cleanup: stop casting RegEncoding() back to a regNumber.
+ rgx = (regNumber)RegEncoding(rgx);
}
// Is this a 'big' opcode?
@@ -8185,7 +8094,7 @@ DONE:
* Output an instruction involving a stack frame value.
*/
-BYTE* emitter::emitOutputSV(BYTE* dst, instrDesc* id, size_t code, CnsVal* addc)
+BYTE* emitter::emitOutputSV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc)
{
int adr;
int dsp;
@@ -8234,7 +8143,7 @@ BYTE* emitter::emitOutputSV(BYTE* dst, instrDesc* id, size_t code, CnsVal* addc)
// Special case emitting AVX instructions
if (Is4ByteAVXInstruction(ins))
{
- size_t regcode = insEncodeReg345(ins, id->idReg1(), size, &code);
+ unsigned regcode = insEncodeReg345(ins, id->idReg1(), size, &code);
dst += emitOutputRexOrVexPrefixIfNeeded(ins, dst, code);
// Emit last opcode byte
@@ -8581,7 +8490,7 @@ BYTE* emitter::emitOutputSV(BYTE* dst, instrDesc* id, size_t code, CnsVal* addc)
* Output an instruction with a static data member (class variable).
*/
-BYTE* emitter::emitOutputCV(BYTE* dst, instrDesc* id, size_t code, CnsVal* addc)
+BYTE* emitter::emitOutputCV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc)
{
BYTE* addr;
CORINFO_FIELD_HANDLE fldh;
@@ -8646,20 +8555,18 @@ BYTE* emitter::emitOutputCV(BYTE* dst, instrDesc* id, size_t code, CnsVal* addc)
{
case IF_RWR_MRD:
- assert((unsigned)code ==
- (insCodeRM(ins) | (insEncodeReg345(ins, REG_EAX, EA_PTRSIZE, NULL) << 8) | 0x0500));
+ assert(code == (insCodeRM(ins) | (insEncodeReg345(ins, REG_EAX, EA_PTRSIZE, NULL) << 8) | 0x0500));
- code &= ~((size_t)0xFFFFFFFF);
+ code &= ~((code_t)0xFFFFFFFF);
code |= 0xA0;
isMoffset = true;
break;
case IF_MWR_RRD:
- assert((unsigned)code ==
- (insCodeMR(ins) | (insEncodeReg345(ins, REG_EAX, EA_PTRSIZE, NULL) << 8) | 0x0500));
+ assert(code == (insCodeMR(ins) | (insEncodeReg345(ins, REG_EAX, EA_PTRSIZE, NULL) << 8) | 0x0500));
- code &= ~((size_t)0xFFFFFFFF);
+ code &= ~((code_t)0xFFFFFFFF);
code |= 0xA2;
isMoffset = true;
break;
@@ -8674,7 +8581,7 @@ BYTE* emitter::emitOutputCV(BYTE* dst, instrDesc* id, size_t code, CnsVal* addc)
// Special case emitting AVX instructions
if (Is4ByteAVXInstruction(ins))
{
- size_t regcode = insEncodeReg345(ins, id->idReg1(), size, &code);
+ unsigned regcode = insEncodeReg345(ins, id->idReg1(), size, &code);
dst += emitOutputRexOrVexPrefixIfNeeded(ins, dst, code);
// Emit last opcode byte
@@ -9017,7 +8924,7 @@ BYTE* emitter::emitOutputCV(BYTE* dst, instrDesc* id, size_t code, CnsVal* addc)
BYTE* emitter::emitOutputR(BYTE* dst, instrDesc* id)
{
- size_t code;
+ code_t code;
instruction ins = id->idIns();
regNumber reg = id->idReg1();
@@ -9228,7 +9135,7 @@ BYTE* emitter::emitOutputR(BYTE* dst, instrDesc* id)
BYTE* emitter::emitOutputRR(BYTE* dst, instrDesc* id)
{
- size_t code;
+ code_t code;
instruction ins = id->idIns();
regNumber reg1 = id->idReg1();
@@ -9238,7 +9145,7 @@ BYTE* emitter::emitOutputRR(BYTE* dst, instrDesc* id)
// Get the 'base' opcode
code = insCodeRM(ins);
code = AddVexPrefixIfNeeded(ins, code, size);
- if (IsSSE2Instruction(ins) || IsAVXInstruction(ins))
+ if (IsSSEOrAVXInstruction(ins))
{
code = insEncodeRMreg(ins, code);
@@ -9322,12 +9229,12 @@ BYTE* emitter::emitOutputRR(BYTE* dst, instrDesc* id)
// now we use the single source as source1 and source2.
if (IsThreeOperandBinaryAVXInstruction(ins))
{
- // encode source/dest operand reg in 'vvvv' bits in 1's compliement form
+ // encode source/dest operand reg in 'vvvv' bits in 1's complement form
code = insEncodeReg3456(ins, reg1, size, code);
}
else if (IsThreeOperandMoveAVXInstruction(ins))
{
- // encode source operand reg in 'vvvv' bits in 1's compliement form
+ // encode source operand reg in 'vvvv' bits in 1's complement form
code = insEncodeReg3456(ins, reg2, size, code);
}
@@ -9340,6 +9247,13 @@ BYTE* emitter::emitOutputRR(BYTE* dst, instrDesc* id)
// Output the highest word of the opcode
dst += emitOutputWord(dst, code >> 16);
code &= 0x0000FFFF;
+
+ if (Is4ByteSSE4Instruction(ins))
+ {
+ // Output 3rd byte of the opcode
+ dst += emitOutputByte(dst, code);
+ code &= 0xFF00;
+ }
}
else if (code & 0x00FF0000)
{
@@ -9349,13 +9263,13 @@ BYTE* emitter::emitOutputRR(BYTE* dst, instrDesc* id)
// If byte 4 is 0xC0, then it contains the Mod/RM encoding for a 3-byte
// encoding. Otherwise, this is an instruction with a 4-byte encoding,
- // and the MOd/RM encoding needs to go in the 5th byte.
+ // and the Mod/RM encoding needs to go in the 5th byte.
// TODO-XArch-CQ: Currently, this will only support registers in the 5th byte.
// We probably need a different mechanism to identify the 4-byte encodings.
if ((code & 0xFF) == 0x00)
{
- // This case happens for AVX instructions only
- assert(IsAVXInstruction(ins));
+ // This case happens for SSE4/AVX instructions only
+ assert(IsAVXInstruction(ins) || IsSSE4Instruction(ins));
if ((code & 0xFF00) == 0xC000)
{
dst += emitOutputByte(dst, (0xC0 | regCode));
@@ -9560,7 +9474,7 @@ BYTE* emitter::emitOutputRR(BYTE* dst, instrDesc* id)
#ifdef FEATURE_AVX_SUPPORT
BYTE* emitter::emitOutputRRR(BYTE* dst, instrDesc* id)
{
- size_t code;
+ code_t code;
instruction ins = id->idIns();
assert(IsAVXInstruction(ins));
@@ -9642,7 +9556,7 @@ BYTE* emitter::emitOutputRRR(BYTE* dst, instrDesc* id)
BYTE* emitter::emitOutputRI(BYTE* dst, instrDesc* id)
{
- size_t code;
+ code_t code;
emitAttr size = id->idOpSize();
instruction ins = id->idIns();
regNumber reg = id->idReg1();
@@ -10004,7 +9918,7 @@ DONE:
BYTE* emitter::emitOutputIV(BYTE* dst, instrDesc* id)
{
- size_t code;
+ code_t code;
instruction ins = id->idIns();
emitAttr size = id->idOpSize();
ssize_t val = emitGetInsSC(id);
@@ -10286,27 +10200,29 @@ BYTE* emitter::emitOutputLJ(BYTE* dst, instrDesc* i)
}
else
{
- size_t code;
+ code_t code;
// Long jump
if (jmp)
{
+ // clang-format off
assert(INS_jmp + (INS_l_jmp - INS_jmp) == INS_l_jmp);
- assert(INS_jo + (INS_l_jmp - INS_jmp) == INS_l_jo);
- assert(INS_jb + (INS_l_jmp - INS_jmp) == INS_l_jb);
+ assert(INS_jo + (INS_l_jmp - INS_jmp) == INS_l_jo);
+ assert(INS_jb + (INS_l_jmp - INS_jmp) == INS_l_jb);
assert(INS_jae + (INS_l_jmp - INS_jmp) == INS_l_jae);
- assert(INS_je + (INS_l_jmp - INS_jmp) == INS_l_je);
+ assert(INS_je + (INS_l_jmp - INS_jmp) == INS_l_je);
assert(INS_jne + (INS_l_jmp - INS_jmp) == INS_l_jne);
assert(INS_jbe + (INS_l_jmp - INS_jmp) == INS_l_jbe);
- assert(INS_ja + (INS_l_jmp - INS_jmp) == INS_l_ja);
- assert(INS_js + (INS_l_jmp - INS_jmp) == INS_l_js);
+ assert(INS_ja + (INS_l_jmp - INS_jmp) == INS_l_ja);
+ assert(INS_js + (INS_l_jmp - INS_jmp) == INS_l_js);
assert(INS_jns + (INS_l_jmp - INS_jmp) == INS_l_jns);
assert(INS_jpe + (INS_l_jmp - INS_jmp) == INS_l_jpe);
assert(INS_jpo + (INS_l_jmp - INS_jmp) == INS_l_jpo);
- assert(INS_jl + (INS_l_jmp - INS_jmp) == INS_l_jl);
+ assert(INS_jl + (INS_l_jmp - INS_jmp) == INS_l_jl);
assert(INS_jge + (INS_l_jmp - INS_jmp) == INS_l_jge);
assert(INS_jle + (INS_l_jmp - INS_jmp) == INS_l_jle);
- assert(INS_jg + (INS_l_jmp - INS_jmp) == INS_l_jg);
+ assert(INS_jg + (INS_l_jmp - INS_jmp) == INS_l_jg);
+ // clang-format on
code = insCode((instruction)(ins + (INS_l_jmp - INS_jmp)));
}
@@ -10452,10 +10368,10 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
// What instruction format have we got?
switch (id->idInsFmt())
{
- size_t code;
- size_t regcode;
- int args;
- CnsVal cnsVal;
+ code_t code;
+ unsigned regcode;
+ int args;
+ CnsVal cnsVal;
BYTE* addr;
bool recCall;
@@ -10792,6 +10708,10 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
dst += emitOutputWord(dst, code);
dst += emitOutputByte(dst, emitGetInsSC(id));
sz = emitSizeOfInsDsc(id);
+
+ // Update GC info.
+ assert(!id->idGCref());
+ emitGCregDeadUpd(id->idReg1(), dst);
break;
case IF_RRD_RRD:
@@ -10871,7 +10791,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
// Output the REX prefix
dst += emitOutputRexOrVexPrefixIfNeeded(ins, dst, code);
- if (UseAVX() && Is4ByteAVXInstruction(ins))
+ if (Is4ByteAVXInstruction(ins))
{
// We just need to output the last byte of the opcode.
assert((code & 0xFF) == 0);
@@ -10883,6 +10803,12 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
{
dst += emitOutputWord(dst, code >> 16);
code &= 0x0000FFFF;
+
+ if (Is4ByteSSE4Instruction(ins))
+ {
+ dst += emitOutputWord(dst, code);
+ code = 0;
+ }
}
else if (code & 0x00FF0000)
{
@@ -10898,9 +10824,9 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
}
else
{
- // This case occurs for AVX instructions.
+ // This case occurs for SSE4/AVX instructions.
// Note that regcode is left shifted by 8-bits.
- assert(Is4ByteAVXInstruction(ins));
+ assert(Is4ByteAVXInstruction(ins) || Is4ByteSSE4Instruction(ins));
dst += emitOutputByte(dst, 0xC0 | (regcode >> 8));
}
diff --git a/src/jit/emitxarch.h b/src/jit/emitxarch.h
index dfd7e6ec50..98256cdaa7 100644
--- a/src/jit/emitxarch.h
+++ b/src/jit/emitxarch.h
@@ -28,6 +28,15 @@ inline static bool isDoubleReg(regNumber reg)
/* Routines that compute the size of / encode instructions */
/************************************************************************/
+// code_t is a type used to accumulate bits of opcode + prefixes. On amd64, it must be 64 bits
+// to support the REX prefixes. On both x86 and amd64, it must be 64 bits to support AVX, with
+// its 3-byte VEX prefix. For legacy backend (which doesn't support AVX), leave it as size_t.
+#if defined(LEGACY_BACKEND)
+typedef size_t code_t;
+#else // !defined(LEGACY_BACKEND)
+typedef unsigned __int64 code_t;
+#endif // !defined(LEGACY_BACKEND)
+
struct CnsVal
{
ssize_t cnsVal;
@@ -36,19 +45,19 @@ struct CnsVal
#endif
};
-UNATIVE_OFFSET emitInsSize(size_t code);
+UNATIVE_OFFSET emitInsSize(code_t code);
UNATIVE_OFFSET emitInsSizeRM(instruction ins);
-UNATIVE_OFFSET emitInsSizeSV(size_t code, int var, int dsp);
+UNATIVE_OFFSET emitInsSizeSV(code_t code, int var, int dsp);
UNATIVE_OFFSET emitInsSizeSV(instrDesc* id, int var, int dsp, int val);
UNATIVE_OFFSET emitInsSizeRR(instruction ins, regNumber reg1, regNumber reg2, emitAttr attr);
-UNATIVE_OFFSET emitInsSizeAM(instrDesc* id, size_t code);
-UNATIVE_OFFSET emitInsSizeAM(instrDesc* id, size_t code, int val);
-UNATIVE_OFFSET emitInsSizeCV(instrDesc* id, size_t code);
-UNATIVE_OFFSET emitInsSizeCV(instrDesc* id, size_t code, int val);
+UNATIVE_OFFSET emitInsSizeAM(instrDesc* id, code_t code);
+UNATIVE_OFFSET emitInsSizeAM(instrDesc* id, code_t code, int val);
+UNATIVE_OFFSET emitInsSizeCV(instrDesc* id, code_t code);
+UNATIVE_OFFSET emitInsSizeCV(instrDesc* id, code_t code, int val);
-BYTE* emitOutputAM(BYTE* dst, instrDesc* id, size_t code, CnsVal* addc = nullptr);
-BYTE* emitOutputSV(BYTE* dst, instrDesc* id, size_t code, CnsVal* addc = nullptr);
-BYTE* emitOutputCV(BYTE* dst, instrDesc* id, size_t code, CnsVal* addc = nullptr);
+BYTE* emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc = nullptr);
+BYTE* emitOutputSV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc = nullptr);
+BYTE* emitOutputCV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc = nullptr);
BYTE* emitOutputR(BYTE* dst, instrDesc* id);
BYTE* emitOutputRI(BYTE* dst, instrDesc* id);
@@ -61,42 +70,60 @@ BYTE* emitOutputRRR(BYTE* dst, instrDesc* id);
BYTE* emitOutputLJ(BYTE* dst, instrDesc* id);
-unsigned emitOutputRexOrVexPrefixIfNeeded(instruction ins, BYTE* dst, size_t& code);
+unsigned emitOutputRexOrVexPrefixIfNeeded(instruction ins, BYTE* dst, code_t& code);
unsigned emitGetRexPrefixSize(instruction ins);
unsigned emitGetVexPrefixSize(instruction ins, emitAttr attr);
-unsigned emitGetPrefixSize(size_t code);
-unsigned emitGetVexPrefixAdjustedSize(instruction ins, emitAttr attr, size_t code);
+unsigned emitGetPrefixSize(code_t code);
+unsigned emitGetVexPrefixAdjustedSize(instruction ins, emitAttr attr, code_t code);
+
+unsigned insEncodeReg012(instruction ins, regNumber reg, emitAttr size, code_t* code);
+unsigned insEncodeReg345(instruction ins, regNumber reg, emitAttr size, code_t* code);
+code_t insEncodeReg3456(instruction ins, regNumber reg, emitAttr size, code_t code);
+unsigned insEncodeRegSIB(instruction ins, regNumber reg, code_t* code);
-unsigned insEncodeReg345(instruction ins, regNumber reg, emitAttr size, size_t* code);
-unsigned insEncodeReg012(instruction ins, regNumber reg, emitAttr size, size_t* code);
-size_t insEncodeReg3456(instruction ins, regNumber reg, emitAttr size, size_t code);
-unsigned insEncodeRegSIB(instruction ins, regNumber reg, size_t* code);
+code_t insEncodeMRreg(instruction ins, code_t code);
+code_t insEncodeRMreg(instruction ins, code_t code);
+code_t insEncodeMRreg(instruction ins, regNumber reg, emitAttr size, code_t code);
+code_t insEncodeRRIb(instruction ins, regNumber reg, emitAttr size);
+code_t insEncodeOpreg(instruction ins, regNumber reg, emitAttr size);
-size_t insEncodeMRreg(instruction ins, size_t code);
-size_t insEncodeMRreg(instruction ins, regNumber reg, emitAttr size, size_t code);
-size_t insEncodeRRIb(instruction ins, regNumber reg, emitAttr size);
-size_t insEncodeOpreg(instruction ins, regNumber reg, emitAttr size);
+unsigned insSSval(unsigned scale);
bool IsAVXInstruction(instruction ins);
-size_t insEncodeMIreg(instruction ins, regNumber reg, emitAttr size, size_t code);
+code_t insEncodeMIreg(instruction ins, regNumber reg, emitAttr size, code_t code);
-size_t AddRexWPrefix(instruction ins, size_t code);
-size_t AddRexRPrefix(instruction ins, size_t code);
-size_t AddRexXPrefix(instruction ins, size_t code);
-size_t AddRexBPrefix(instruction ins, size_t code);
-size_t AddRexPrefix(instruction ins, size_t code);
+code_t AddRexWPrefix(instruction ins, code_t code);
+code_t AddRexRPrefix(instruction ins, code_t code);
+code_t AddRexXPrefix(instruction ins, code_t code);
+code_t AddRexBPrefix(instruction ins, code_t code);
+code_t AddRexPrefix(instruction ins, code_t code);
+
+bool useSSE3_4Encodings;
+bool UseSSE3_4()
+{
+ return useSSE3_4Encodings;
+}
+void SetUseSSE3_4(bool value)
+{
+ useSSE3_4Encodings = value;
+}
+bool Is4ByteSSE4Instruction(instruction ins);
#ifdef FEATURE_AVX_SUPPORT
+
// 3-byte VEX prefix starts with byte 0xC4
-#define VEX_PREFIX_MASK_3BYTE 0xC4000000000000LL
+#define VEX_PREFIX_MASK_3BYTE 0xFF000000000000ULL
+#define VEX_PREFIX_CODE_3BYTE 0xC4000000000000ULL
+
bool TakesVexPrefix(instruction ins);
+
// Returns true if the instruction encoding already contains VEX prefix
-bool hasVexPrefix(size_t code)
+bool hasVexPrefix(code_t code)
{
- return (code & VEX_PREFIX_MASK_3BYTE) != 0;
+ return (code & VEX_PREFIX_MASK_3BYTE) == VEX_PREFIX_CODE_3BYTE;
}
-size_t AddVexPrefix(instruction ins, size_t code, emitAttr attr);
-size_t AddVexPrefixIfNeeded(instruction ins, size_t code, emitAttr size)
+code_t AddVexPrefix(instruction ins, code_t code, emitAttr attr);
+code_t AddVexPrefixIfNeeded(instruction ins, code_t code, emitAttr size)
{
if (TakesVexPrefix(ins))
{
@@ -104,7 +131,7 @@ size_t AddVexPrefixIfNeeded(instruction ins, size_t code, emitAttr size)
}
return code;
}
-size_t AddVexPrefixIfNeededAndNotPresent(instruction ins, size_t code, emitAttr size)
+code_t AddVexPrefixIfNeededAndNotPresent(instruction ins, code_t code, emitAttr size)
{
if (TakesVexPrefix(ins) && !hasVexPrefix(code))
{
@@ -112,6 +139,7 @@ size_t AddVexPrefixIfNeededAndNotPresent(instruction ins, size_t code, emitAttr
}
return code;
}
+
bool useAVXEncodings;
bool UseAVX()
{
@@ -121,18 +149,20 @@ void SetUseAVX(bool value)
{
useAVXEncodings = value;
}
+
bool IsThreeOperandBinaryAVXInstruction(instruction ins);
bool IsThreeOperandMoveAVXInstruction(instruction ins);
bool IsThreeOperandAVXInstruction(instruction ins)
{
return (IsThreeOperandBinaryAVXInstruction(ins) || IsThreeOperandMoveAVXInstruction(ins));
}
+bool Is4ByteAVXInstruction(instruction ins);
#else // !FEATURE_AVX_SUPPORT
-bool UseAVX()
+bool UseAVX()
{
return false;
}
-bool hasVexPrefix(size_t code)
+bool hasVexPrefix(code_t code)
{
return false;
}
@@ -148,15 +178,19 @@ bool IsThreeOperandAVXInstruction(instruction ins)
{
return false;
}
+bool Is4ByteAVXInstruction(instruction ins)
+{
+ return false;
+}
bool TakesVexPrefix(instruction ins)
{
return false;
}
-size_t AddVexPrefixIfNeeded(instruction ins, size_t code, emitAttr attr)
+code_t AddVexPrefixIfNeeded(instruction ins, code_t code, emitAttr attr)
{
return code;
}
-size_t AddVexPrefixIfNeededAndNotPresent(instruction ins, size_t code, emitAttr size)
+code_t AddVexPrefixIfNeededAndNotPresent(instruction ins, code_t code, emitAttr size)
{
return code;
}
@@ -226,6 +260,18 @@ bool emitVerifyEncodable(instruction ins, emitAttr size, regNumber reg1, regNumb
bool emitInsCanOnlyWriteSSE2OrAVXReg(instrDesc* id);
+#if FEATURE_FIXED_OUT_ARGS
+void emitAdjustStackDepthPushPop(instruction ins)
+{
+}
+void emitAdjustStackDepth(instruction ins, ssize_t val)
+{
+}
+#else // !FEATURE_FIXED_OUT_ARGS
+void emitAdjustStackDepthPushPop(instruction ins);
+void emitAdjustStackDepth(instruction ins, ssize_t val);
+#endif // !FEATURE_FIXED_OUT_ARGS
+
/*****************************************************************************
*
* Convert between an index scale in bytes to a smaller encoding used for
diff --git a/src/jit/error.cpp b/src/jit/error.cpp
index 71c3301045..f42dcef5c6 100644
--- a/src/jit/error.cpp
+++ b/src/jit/error.cpp
@@ -129,7 +129,7 @@ void noWayAssertBodyConditional(
}
}
-#if !defined(_TARGET_X86_) || !defined(LEGACY_BACKEND)
+#if defined(ALT_JIT) && (!defined(_TARGET_X86_) || !defined(LEGACY_BACKEND))
/*****************************************************************************/
void notYetImplemented(const char* msg, const char* filename, unsigned line)
@@ -193,7 +193,7 @@ void notYetImplemented(const char* msg, const char* filename, unsigned line)
}
}
-#endif // #if !defined(_TARGET_X86_) || !defined(LEGACY_BACKEND)
+#endif // #if defined(ALT_JIT) && (!defined(_TARGET_X86_) || !defined(LEGACY_BACKEND))
/*****************************************************************************/
LONG __JITfilter(PEXCEPTION_POINTERS pExceptionPointers, LPVOID lpvParam)
diff --git a/src/jit/error.h b/src/jit/error.h
index c56971aaf7..0535601055 100644
--- a/src/jit/error.h
+++ b/src/jit/error.h
@@ -58,10 +58,11 @@ extern LONG __JITfilter(PEXCEPTION_POINTERS pExceptionPointers, LPVOID lpvParam)
/*****************************************************************************/
+// clang-format off
+
extern void debugError(const char* msg, const char* file, unsigned line);
extern void DECLSPEC_NORETURN badCode();
-extern void DECLSPEC_NORETURN
-badCode3(const char* msg, const char* msg2, int arg, __in_z const char* file, unsigned line);
+extern void DECLSPEC_NORETURN badCode3(const char* msg, const char* msg2, int arg, __in_z const char* file, unsigned line);
extern void DECLSPEC_NORETURN noWay();
extern void DECLSPEC_NORETURN NOMEM();
extern void DECLSPEC_NORETURN fatal(int errCode);
@@ -79,120 +80,6 @@ extern void noWayAssertBodyConditional(
);
extern void noWayAssertBodyConditional(const char* cond, const char* file, unsigned line);
-#if !defined(_TARGET_X86_) || !defined(LEGACY_BACKEND)
-
-// This guy can return based on Config flag/Debugger
-extern void notYetImplemented(const char* msg, const char* file, unsigned line);
-#define NYI(msg) notYetImplemented("NYI: " #msg, __FILE__, __LINE__)
-#define NYI_IF(cond, msg) \
- if (cond) \
- notYetImplemented("NYI: " #msg, __FILE__, __LINE__)
-
-#ifdef _TARGET_AMD64_
-
-#define NYI_AMD64(msg) notYetImplemented("NYI_AMD64: " #msg, __FILE__, __LINE__)
-#define NYI_X86(msg) \
- do \
- { \
- } while (0)
-#define NYI_ARM(msg) \
- do \
- { \
- } while (0)
-#define NYI_ARM64(msg) \
- do \
- { \
- } while (0)
-
-#elif defined(_TARGET_X86_)
-
-#define NYI_AMD64(msg) \
- do \
- { \
- } while (0)
-#define NYI_X86(msg) notYetImplemented("NYI_X86: " #msg, __FILE__, __LINE__)
-#define NYI_ARM(msg) \
- do \
- { \
- } while (0)
-#define NYI_ARM64(msg) \
- do \
- { \
- } while (0)
-
-#elif defined(_TARGET_ARM_)
-
-#define NYI_AMD64(msg) \
- do \
- { \
- } while (0)
-#define NYI_X86(msg) \
- do \
- { \
- } while (0)
-#define NYI_ARM(msg) notYetImplemented("NYI_ARM: " #msg, __FILE__, __LINE__)
-#define NYI_ARM64(msg) \
- do \
- { \
- } while (0)
-
-#elif defined(_TARGET_ARM64_)
-
-#define NYI_AMD64(msg) \
- do \
- { \
- } while (0)
-#define NYI_X86(msg) \
- do \
- { \
- } while (0)
-#define NYI_ARM(msg) \
- do \
- { \
- } while (0)
-#define NYI_ARM64(msg) notYetImplemented("NYI_ARM64: " #msg, __FILE__, __LINE__)
-
-#else
-
-#error "Unknown platform, not x86, ARM, or AMD64?"
-
-#endif
-
-#else // defined(_TARGET_X86_) && defined(LEGACY_BACKEND)
-
-#define NYI(msg) assert(!msg)
-#define NYI_AMD64(msg) \
- do \
- { \
- } while (0)
-#define NYI_ARM(msg) \
- do \
- { \
- } while (0)
-#define NYI_ARM64(msg) \
- do \
- { \
- } while (0)
-
-#endif // _TARGET_X86_
-
-#if !defined(_TARGET_X86_) && !defined(FEATURE_STACK_FP_X87)
-#define NYI_FLAT_FP_X87(msg) notYetImplemented("NYI: " #msg, __FILE__, __LINE__)
-#define NYI_FLAT_FP_X87_NC(msg) notYetImplemented("NYI: " #msg, __FILE__, __LINE__)
-
-#else
-
-#define NYI_FLAT_FP_X87(msg) \
- do \
- { \
- } while (0)
-#define NYI_FLAT_FP_X87_NC(msg) \
- do \
- { \
- } while (0)
-
-#endif // !_TARGET_X86_ && !FEATURE_STACK_FP_X87
-
#ifdef DEBUG
#define NO_WAY(msg) (debugError(msg, __FILE__, __LINE__), noWay())
// Used for fallback stress mode
@@ -210,6 +97,8 @@ extern void notYetImplemented(const char* msg, const char* file, unsigned line);
} while (0)
#define unreached() noWayAssertBody("unreached", __FILE__, __LINE__)
+#define NOWAY_MSG(msg) noWayAssertBodyConditional(msg, __FILE__, __LINE__)
+
#else
#define NO_WAY(msg) noWay()
@@ -232,6 +121,8 @@ extern void notYetImplemented(const char* msg, const char* file, unsigned line);
} while (0)
#define unreached() noWayAssertBody()
+#define NOWAY_MSG(msg) noWayAssertBodyConditional(NOWAY_ASSERT_BODY_ARGUMENTS)
+
#endif
// IMPL_LIMITATION is called when we encounter valid IL that is not
@@ -239,7 +130,81 @@ extern void notYetImplemented(const char* msg, const char* file, unsigned line);
// limitations (that could be removed in the future)
#define IMPL_LIMITATION(msg) NO_WAY(msg)
-#if defined(_HOST_X86_)
+#if !defined(_TARGET_X86_) || !defined(LEGACY_BACKEND)
+
+#if defined(ALT_JIT)
+
+// This guy can return based on Config flag/Debugger
+extern void notYetImplemented(const char* msg, const char* file, unsigned line);
+#define NYIRAW(msg) notYetImplemented(msg, __FILE__, __LINE__)
+
+#else // !defined(ALT_JIT)
+
+#define NYIRAW(msg) NOWAY_MSG(msg)
+
+#endif // !defined(ALT_JIT)
+
+#define NYI(msg) NYIRAW("NYI: " msg)
+#define NYI_IF(cond, msg) if (cond) NYIRAW("NYI: " msg)
+
+#ifdef _TARGET_AMD64_
+
+#define NYI_AMD64(msg) NYIRAW("NYI_AMD64: " msg)
+#define NYI_X86(msg) do { } while (0)
+#define NYI_ARM(msg) do { } while (0)
+#define NYI_ARM64(msg) do { } while (0)
+
+#elif defined(_TARGET_X86_)
+
+#define NYI_AMD64(msg) do { } while (0)
+#define NYI_X86(msg) NYIRAW("NYI_X86: " msg)
+#define NYI_ARM(msg) do { } while (0)
+#define NYI_ARM64(msg) do { } while (0)
+
+#elif defined(_TARGET_ARM_)
+
+#define NYI_AMD64(msg) do { } while (0)
+#define NYI_X86(msg) do { } while (0)
+#define NYI_ARM(msg) NYIRAW("NYI_ARM: " msg)
+#define NYI_ARM64(msg) do { } while (0)
+
+#elif defined(_TARGET_ARM64_)
+
+#define NYI_AMD64(msg) do { } while (0)
+#define NYI_X86(msg) do { } while (0)
+#define NYI_ARM(msg) do { } while (0)
+#define NYI_ARM64(msg) NYIRAW("NYI_ARM64: " msg)
+
+#else
+
+#error "Unknown platform, not x86, ARM, or AMD64?"
+
+#endif
+
+#else // NYI not available; make it an assert.
+
+#define NYI(msg) assert(!msg)
+#define NYI_AMD64(msg) do { } while (0)
+#define NYI_ARM(msg) do { } while (0)
+#define NYI_ARM64(msg) do { } while (0)
+
+#endif // NYI not available
+
+#if !defined(_TARGET_X86_) && !defined(FEATURE_STACK_FP_X87)
+
+#define NYI_FLAT_FP_X87(msg) NYI(msg)
+#define NYI_FLAT_FP_X87_NC(msg) NYI(msg)
+
+#else
+
+#define NYI_FLAT_FP_X87(msg) do { } while (0)
+#define NYI_FLAT_FP_X87_NC(msg) do { } while (0)
+
+#endif // !_TARGET_X86_ && !FEATURE_STACK_FP_X87
+
+// clang-format on
+
+#if defined(_HOST_X86_) && !defined(FEATURE_PAL)
// While debugging in an Debugger, the "int 3" will cause the program to break
// Outside, the exception handler will just filter out the "int 3".
diff --git a/src/jit/flowgraph.cpp b/src/jit/flowgraph.cpp
index 1c68bfd96a..441569c339 100644
--- a/src/jit/flowgraph.cpp
+++ b/src/jit/flowgraph.cpp
@@ -2985,8 +2985,8 @@ void Compiler::fgRemovePreds()
{
C_ASSERT(offsetof(BasicBlock, bbPreds) ==
offsetof(BasicBlock, bbCheapPreds)); // bbPreds and bbCheapPreds are at the same place in a union,
- C_ASSERT(sizeof(((BasicBlock*)0)->bbPreds) ==
- sizeof(((BasicBlock*)0)->bbCheapPreds)); // and are the same size. So, this function removes both.
+ C_ASSERT(sizeof(((BasicBlock*)nullptr)->bbPreds) ==
+ sizeof(((BasicBlock*)nullptr)->bbCheapPreds)); // and are the same size. So, this function removes both.
for (BasicBlock* block = fgFirstBB; block != nullptr; block = block->bbNext)
{
@@ -3890,8 +3890,7 @@ bool Compiler::fgCreateGCPoll(GCPollType pollType, BasicBlock* block)
BBjumpKinds oldJumpKind = top->bbJumpKind;
// Update block flags
- unsigned originalFlags;
- originalFlags = top->bbFlags | BBF_GC_SAFE_POINT;
+ const unsigned __int64 originalFlags = top->bbFlags | BBF_GC_SAFE_POINT;
// Unlike Fei's inliner from puclr, I'm allowed to split loops.
// And we keep a few other flags...
@@ -4269,6 +4268,7 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, BYTE*
const bool isForceInline = (info.compFlags & CORINFO_FLG_FORCEINLINE) != 0;
const bool makeInlineObservations = (compInlineResult != nullptr);
const bool isInlining = compIsForInlining();
+ unsigned retBlocks = 0;
if (makeInlineObservations)
{
@@ -4638,6 +4638,7 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, BYTE*
break;
case CEE_JMP:
+ retBlocks++;
#if !defined(_TARGET_X86_) && !defined(_TARGET_ARM_)
if (!isInlining)
@@ -4730,6 +4731,8 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, BYTE*
fgObserveInlineConstants(opcode, pushedStack, isInlining);
}
break;
+ case CEE_RET:
+ retBlocks++;
default:
break;
@@ -4758,6 +4761,27 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, BYTE*
{
compInlineResult->Note(InlineObservation::CALLEE_END_OPCODE_SCAN);
+ if (!compInlineResult->UsesLegacyPolicy())
+ {
+ // If there are no return blocks we know it does not return, however if there
+ // return blocks we don't know it returns as it may be counting unreachable code.
+ // However we will still make the CALLEE_DOES_NOT_RETURN observation.
+
+ compInlineResult->NoteBool(InlineObservation::CALLEE_DOES_NOT_RETURN, retBlocks == 0);
+
+ if (retBlocks == 0 && isInlining)
+ {
+ // Mark the call node as "no return" as it can impact caller's code quality.
+ impInlineInfo->iciCall->gtCallMoreFlags |= GTF_CALL_M_DOES_NOT_RETURN;
+ }
+ }
+
+ // Determine if call site is within a try.
+ if (isInlining && impInlineInfo->iciBlock->hasTryIndex())
+ {
+ compInlineResult->Note(InlineObservation::CALLSITE_IN_TRY_REGION);
+ }
+
// If the inline is viable and discretionary, do the
// profitability screening.
if (compInlineResult->IsDiscretionaryCandidate())
@@ -5062,22 +5086,23 @@ void Compiler::fgLinkBasicBlocks()
/*****************************************************************************
*
- * Walk the instrs to create the basic blocks.
+ * Walk the instrs to create the basic blocks. Returns the number of BBJ_RETURN in method
*/
-void Compiler::fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, BYTE* jumpTarget)
+unsigned Compiler::fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, BYTE* jumpTarget)
{
+ unsigned retBlocks;
const BYTE* codeBegp = codeAddr;
const BYTE* codeEndp = codeAddr + codeSize;
bool tailCall = false;
unsigned curBBoffs;
BasicBlock* curBBdesc;
+ retBlocks = 0;
/* Clear the beginning offset for the first BB */
curBBoffs = 0;
-#ifdef DEBUGGING_SUPPORT
if (opts.compDbgCode && (info.compVarScopesCount > 0))
{
compResetScopeLists();
@@ -5090,7 +5115,6 @@ void Compiler::fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, BYTE*
{ /* do nothing */
}
}
-#endif
BBjumpKinds jmpKind;
@@ -5280,7 +5304,8 @@ void Compiler::fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, BYTE*
// TODO-CQ: We can inline some callees with explicit tail calls if we can guarantee that the calls
// can be dispatched as tail calls from the caller.
compInlineResult->NoteFatal(InlineObservation::CALLEE_EXPLICIT_TAIL_PREFIX);
- return;
+ retBlocks++;
+ return retBlocks;
}
__fallthrough;
@@ -5391,6 +5416,7 @@ void Compiler::fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, BYTE*
But instead of directly returning to the caller we jump and
execute something else in between */
case CEE_RET:
+ retBlocks++;
jmpKind = BBJ_RETURN;
break;
@@ -5473,8 +5499,6 @@ void Compiler::fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, BYTE*
nxtBBoffs = (IL_OFFSET)(codeAddr - codeBegp);
-#ifdef DEBUGGING_SUPPORT
-
bool foundScope = false;
if (opts.compDbgCode && (info.compVarScopesCount > 0))
@@ -5488,7 +5512,6 @@ void Compiler::fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, BYTE*
foundScope = true;
}
}
-#endif
/* Do we have a jump? */
@@ -5505,7 +5528,6 @@ void Compiler::fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, BYTE*
bool makeBlock = (jumpTarget[nxtBBoffs] != JT_NONE);
-#ifdef DEBUGGING_SUPPORT
if (!makeBlock && foundScope)
{
makeBlock = true;
@@ -5516,7 +5538,6 @@ void Compiler::fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, BYTE*
}
#endif // DEBUG
}
-#endif // DEBUGGING_SUPPORT
if (!makeBlock)
{
@@ -5581,6 +5602,8 @@ void Compiler::fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, BYTE*
/* Finally link up the bbJumpDest of the blocks together */
fgLinkBasicBlocks();
+
+ return retBlocks;
}
/*****************************************************************************
@@ -5726,44 +5749,23 @@ void Compiler::fgFindBasicBlocks()
/* Now create the basic blocks */
- fgMakeBasicBlocks(info.compCode, info.compILCodeSize, jumpTarget);
+ unsigned retBlocks = fgMakeBasicBlocks(info.compCode, info.compILCodeSize, jumpTarget);
if (compIsForInlining())
{
- if (compInlineResult->IsFailure())
- {
- return;
- }
-
- bool hasReturnBlocks = false;
- bool hasMoreThanOneReturnBlock = false;
- for (BasicBlock* block = fgFirstBB; block != nullptr; block = block->bbNext)
- {
- if (block->bbJumpKind == BBJ_RETURN)
- {
- if (hasReturnBlocks)
- {
- hasMoreThanOneReturnBlock = true;
- break;
- }
-
- hasReturnBlocks = true;
- }
- }
-
- if (!hasReturnBlocks && !compInlineResult->UsesLegacyPolicy())
+#ifdef DEBUG
+ // If fgFindJumpTargets marked the call as "no return" there
+ // really should be no BBJ_RETURN blocks in the method.
+ //
+ // Note LegacyPolicy does not mark calls as no return, so if
+ // it's active, skip the check.
+ if (!compInlineResult->UsesLegacyPolicy())
{
- //
- // Mark the call node as "no return". The inliner might ignore CALLEE_DOES_NOT_RETURN and
- // fail inline for a different reasons. In that case we still want to make the "no return"
- // information available to the caller as it can impact caller's code quality.
- //
-
- impInlineInfo->iciCall->gtCallMoreFlags |= GTF_CALL_M_DOES_NOT_RETURN;
+ bool markedNoReturn = (impInlineInfo->iciCall->gtCallMoreFlags & GTF_CALL_M_DOES_NOT_RETURN) != 0;
+ assert((markedNoReturn && (retBlocks == 0)) || (!markedNoReturn && (retBlocks >= 1)));
}
-
- compInlineResult->NoteBool(InlineObservation::CALLEE_DOES_NOT_RETURN, !hasReturnBlocks);
+#endif // DEBUG
if (compInlineResult->IsFailure())
{
@@ -5777,12 +5779,14 @@ void Compiler::fgFindBasicBlocks()
compHndBBtabCount = impInlineInfo->InlinerCompiler->compHndBBtabCount;
info.compXcptnsCount = impInlineInfo->InlinerCompiler->info.compXcptnsCount;
- if (info.compRetNativeType != TYP_VOID && hasMoreThanOneReturnBlock)
+ // Use a spill temp for the return value if there are multiple return blocks.
+ if ((info.compRetNativeType != TYP_VOID) && (retBlocks > 1))
{
// 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"));
lvaTable[lvaInlineeReturnSpillTemp].lvType = info.compRetNativeType;
}
+
return;
}
@@ -6666,7 +6670,7 @@ void Compiler::fgImport()
impImport(fgFirstBB);
- if (!(opts.eeFlags & CORJIT_FLG_SKIP_VERIFICATION))
+ if (!opts.jitFlags->IsSet(JitFlags::JIT_FLAG_SKIP_VERIFICATION))
{
CorInfoMethodRuntimeFlags verFlag;
verFlag = tiIsVerifiableCode ? CORINFO_FLG_VERIFIABLE : CORINFO_FLG_UNVERIFIABLE;
@@ -6936,7 +6940,7 @@ GenTreePtr Compiler::fgGetSharedCCtor(CORINFO_CLASS_HANDLE cls)
if (opts.IsReadyToRun())
{
CORINFO_RESOLVED_TOKEN resolvedToken;
- ZeroMemory(&resolvedToken, sizeof(resolvedToken));
+ memset(&resolvedToken, 0, sizeof(resolvedToken));
resolvedToken.hClass = cls;
return impReadyToRunHelperToTree(&resolvedToken, CORINFO_HELP_READYTORUN_STATIC_BASE, TYP_BYREF);
@@ -8248,8 +8252,8 @@ void Compiler::fgAddInternal()
if (!varTypeIsFloating(info.compRetType))
{
lvaTable[genReturnLocal].setPrefReg(REG_INTRET, this);
-#ifdef REG_FLOATRET
}
+#ifdef REG_FLOATRET
else
{
lvaTable[genReturnLocal].setPrefReg(REG_FLOATRET, this);
@@ -8301,7 +8305,7 @@ void Compiler::fgAddInternal()
CORINFO_JUST_MY_CODE_HANDLE* pDbgHandle = nullptr;
CORINFO_JUST_MY_CODE_HANDLE dbgHandle = nullptr;
- if (opts.compDbgCode && !(opts.eeFlags & CORJIT_FLG_IL_STUB))
+ if (opts.compDbgCode && !opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IL_STUB))
{
dbgHandle = info.compCompHnd->getJustMyCodeHandle(info.compMethodHnd, &pDbgHandle);
}
@@ -8589,17 +8593,12 @@ GenTreeStmt* Compiler::fgNewStmtFromTree(GenTreePtr tree, IL_OFFSETX offs)
// The first good IL offset of a statement in the block, or BAD_IL_OFFSET if such an IL offset
// cannot be found.
//
-// If we are not built with DEBUGGING_SUPPORT or DEBUG, then always report BAD_IL_OFFSET,
-// since in that case statements don't contain an IL offset. The effect will be that split
-// blocks will lose their IL offset information.
-
IL_OFFSET Compiler::fgFindBlockILOffset(BasicBlock* block)
{
// This function searches for IL offsets in statement nodes, so it can't be used in LIR. We
// could have a similar function for LIR that searches for GT_IL_OFFSET nodes.
assert(!block->IsLIR());
-#if defined(DEBUGGING_SUPPORT) || defined(DEBUG)
for (GenTree* stmt = block->bbTreeList; stmt != nullptr; stmt = stmt->gtNext)
{
assert(stmt->IsStatement());
@@ -8608,7 +8607,6 @@ IL_OFFSET Compiler::fgFindBlockILOffset(BasicBlock* block)
return jitGetILoffs(stmt->gtStmt.gtStmtILoffsx);
}
}
-#endif // defined(DEBUGGING_SUPPORT) || defined(DEBUG)
return BAD_IL_OFFSET;
}
@@ -8949,10 +8947,10 @@ void Compiler::fgSimpleLowering()
for (GenTreePtr tree = stmt->gtStmtList; tree; tree = tree->gtNext)
{
#else
- LIR::Range& range = LIR::AsRange(block);
- for (GenTree* tree : range)
+ LIR::Range& range = LIR::AsRange(block);
+ for (GenTree* tree : range)
+ {
{
- {
#endif
if (tree->gtOper == GT_ARR_LENGTH)
{
@@ -9000,7 +8998,7 @@ void Compiler::fgSimpleLowering()
add->gtNext = tree;
tree->gtPrev = add;
#else
- range.InsertAfter(arr, con, add);
+ range.InsertAfter(arr, con, add);
#endif
}
@@ -9339,6 +9337,7 @@ inline bool OperIsControlFlow(genTreeOps oper)
switch (oper)
{
case GT_JTRUE:
+ case GT_JCC:
case GT_SWITCH:
case GT_LABEL:
@@ -10019,10 +10018,10 @@ void Compiler::fgUnreachableBlock(BasicBlock* block)
/*****************************************************************************************************
*
- * Function called to remove or morph a GT_JTRUE statement when we jump to the same
+ * Function called to remove or morph a jump when we jump to the same
* block when both the condition is true or false.
*/
-void Compiler::fgRemoveJTrue(BasicBlock* block)
+void Compiler::fgRemoveConditionalJump(BasicBlock* block)
{
noway_assert(block->bbJumpKind == BBJ_COND && block->bbJumpDest == block->bbNext);
assert(compRationalIRForm == block->IsLIR());
@@ -10053,7 +10052,7 @@ void Compiler::fgRemoveJTrue(BasicBlock* block)
LIR::Range& blockRange = LIR::AsRange(block);
GenTree* test = blockRange.LastNode();
- assert(test->OperGet() == GT_JTRUE);
+ assert(test->OperIsConditionalJump());
bool isClosed;
unsigned sideEffects;
@@ -10109,7 +10108,7 @@ void Compiler::fgRemoveJTrue(BasicBlock* block)
{
test->gtStmtExpr = sideEffList;
- fgMorphBlockStmt(block, test DEBUGARG("fgRemoveJTrue"));
+ fgMorphBlockStmt(block, test DEBUGARG("fgRemoveConditionalJump"));
}
}
}
@@ -10545,7 +10544,7 @@ void Compiler::fgRemoveBlock(BasicBlock* block, bool unreachable)
// Make sure we are replacing "block" with "succBlock" in predBlock->bbJumpDest.
noway_assert(predBlock->bbJumpDest == block);
predBlock->bbJumpDest = succBlock;
- fgRemoveJTrue(predBlock);
+ fgRemoveConditionalJump(predBlock);
break;
}
@@ -10605,7 +10604,7 @@ void Compiler::fgRemoveBlock(BasicBlock* block, bool unreachable)
/* Check for branch to next block */
if (bPrev->bbJumpDest == bPrev->bbNext)
{
- fgRemoveJTrue(bPrev);
+ fgRemoveConditionalJump(bPrev);
}
break;
@@ -11031,10 +11030,10 @@ bool Compiler::fgExpandRarelyRunBlocks()
noway_assert(tmpbb->isBBCallAlwaysPair());
bPrevPrev = tmpbb;
#else
- if (tmpbb->bbJumpKind == BBJ_CALLFINALLY)
- {
- bPrevPrev = tmpbb;
- }
+ if (tmpbb->bbJumpKind == BBJ_CALLFINALLY)
+ {
+ bPrevPrev = tmpbb;
+ }
#endif
}
@@ -11566,60 +11565,60 @@ BasicBlock* Compiler::fgRelocateEHRange(unsigned regionIndex, FG_RELOCATE_TYPE r
#else // FEATURE_EH_FUNCLETS
- for (XTnum = 0, HBtab = compHndBBtab; XTnum < compHndBBtabCount; XTnum++, HBtab++)
+ for (XTnum = 0, HBtab = compHndBBtab; XTnum < compHndBBtabCount; XTnum++, HBtab++)
+ {
+ if (XTnum == regionIndex)
{
- if (XTnum == regionIndex)
- {
- // Don't update our handler's Last info
- continue;
- }
+ // Don't update our handler's Last info
+ continue;
+ }
- if (HBtab->ebdTryLast == bLast)
+ if (HBtab->ebdTryLast == bLast)
+ {
+ // If we moved a set of blocks that were at the end of
+ // a different try region then we may need to update ebdTryLast
+ for (block = HBtab->ebdTryBeg; block != NULL; block = block->bbNext)
{
- // If we moved a set of blocks that were at the end of
- // a different try region then we may need to update ebdTryLast
- for (block = HBtab->ebdTryBeg; block != NULL; block = block->bbNext)
+ if (block == bPrev)
{
- if (block == bPrev)
- {
- fgSetTryEnd(HBtab, bPrev);
- break;
- }
- else if (block == HBtab->ebdTryLast->bbNext)
- {
- // bPrev does not come after the TryBeg
- break;
- }
+ fgSetTryEnd(HBtab, bPrev);
+ break;
+ }
+ else if (block == HBtab->ebdTryLast->bbNext)
+ {
+ // bPrev does not come after the TryBeg
+ break;
}
}
- if (HBtab->ebdHndLast == bLast)
+ }
+ if (HBtab->ebdHndLast == bLast)
+ {
+ // If we moved a set of blocks that were at the end of
+ // a different handler region then we must update ebdHndLast
+ for (block = HBtab->ebdHndBeg; block != NULL; block = block->bbNext)
{
- // If we moved a set of blocks that were at the end of
- // a different handler region then we must update ebdHndLast
- for (block = HBtab->ebdHndBeg; block != NULL; block = block->bbNext)
+ if (block == bPrev)
{
- if (block == bPrev)
- {
- fgSetHndEnd(HBtab, bPrev);
- break;
- }
- else if (block == HBtab->ebdHndLast->bbNext)
- {
- // bPrev does not come after the HndBeg
- break;
- }
+ fgSetHndEnd(HBtab, bPrev);
+ break;
+ }
+ else if (block == HBtab->ebdHndLast->bbNext)
+ {
+ // bPrev does not come after the HndBeg
+ break;
}
}
- } // end exception table iteration
+ }
+ } // end exception table iteration
- // We have decided to insert the block(s) after fgLastBlock
- fgMoveBlocksAfter(bStart, bLast, insertAfterBlk);
+ // We have decided to insert the block(s) after fgLastBlock
+ fgMoveBlocksAfter(bStart, bLast, insertAfterBlk);
- // If bPrev falls through, we will insert a jump to block
- fgConnectFallThrough(bPrev, bStart);
+ // If bPrev falls through, we will insert a jump to block
+ fgConnectFallThrough(bPrev, bStart);
- // If bLast falls through, we will insert a jump to bNext
- fgConnectFallThrough(bLast, bNext);
+ // If bLast falls through, we will insert a jump to bNext
+ fgConnectFallThrough(bLast, bNext);
#endif // FEATURE_EH_FUNCLETS
@@ -12060,70 +12059,70 @@ void Compiler::fgCreateFunclets()
#else // !FEATURE_EH_FUNCLETS
- /*****************************************************************************
- *
- * Function called to relocate any and all EH regions.
- * Only entire consecutive EH regions will be moved and they will be kept together.
- * Except for the first block, the range can not have any blocks that jump into or out of the region.
- */
+/*****************************************************************************
+ *
+ * Function called to relocate any and all EH regions.
+ * Only entire consecutive EH regions will be moved and they will be kept together.
+ * Except for the first block, the range can not have any blocks that jump into or out of the region.
+ */
- bool Compiler::fgRelocateEHRegions()
- {
- bool result = false; // Our return value
+bool Compiler::fgRelocateEHRegions()
+{
+ bool result = false; // Our return value
#ifdef DEBUG
- if (verbose)
- printf("*************** In fgRelocateEHRegions()\n");
+ if (verbose)
+ printf("*************** In fgRelocateEHRegions()\n");
#endif
- if (fgCanRelocateEHRegions)
- {
- unsigned XTnum;
- EHblkDsc* HBtab;
+ if (fgCanRelocateEHRegions)
+ {
+ unsigned XTnum;
+ EHblkDsc* HBtab;
- for (XTnum = 0, HBtab = compHndBBtab; XTnum < compHndBBtabCount; XTnum++, HBtab++)
+ for (XTnum = 0, HBtab = compHndBBtab; XTnum < compHndBBtabCount; XTnum++, HBtab++)
+ {
+ // Nested EH regions cannot be moved.
+ // Also we don't want to relocate an EH region that has a filter
+ if ((HBtab->ebdHandlerNestingLevel == 0) && !HBtab->HasFilter())
{
- // Nested EH regions cannot be moved.
- // Also we don't want to relocate an EH region that has a filter
- if ((HBtab->ebdHandlerNestingLevel == 0) && !HBtab->HasFilter())
- {
- bool movedTry = false;
+ bool movedTry = false;
#if DEBUG
- bool movedHnd = false;
+ bool movedHnd = false;
#endif // DEBUG
- // Only try to move the outermost try region
- if (HBtab->ebdEnclosingTryIndex == EHblkDsc::NO_ENCLOSING_INDEX)
+ // Only try to move the outermost try region
+ if (HBtab->ebdEnclosingTryIndex == EHblkDsc::NO_ENCLOSING_INDEX)
+ {
+ // Move the entire try region if it can be moved
+ if (HBtab->ebdTryBeg->isRunRarely())
{
- // Move the entire try region if it can be moved
- if (HBtab->ebdTryBeg->isRunRarely())
+ BasicBlock* bTryLastBB = fgRelocateEHRange(XTnum, FG_RELOCATE_TRY);
+ if (bTryLastBB != NULL)
{
- BasicBlock* bTryLastBB = fgRelocateEHRange(XTnum, FG_RELOCATE_TRY);
- if (bTryLastBB != NULL)
- {
- result = true;
- movedTry = true;
- }
+ result = true;
+ movedTry = true;
}
+ }
#if DEBUG
- if (verbose && movedTry)
- {
- printf("\nAfter relocating an EH try region");
- fgDispBasicBlocks();
- fgDispHandlerTab();
+ if (verbose && movedTry)
+ {
+ printf("\nAfter relocating an EH try region");
+ fgDispBasicBlocks();
+ fgDispHandlerTab();
- // Make sure that the predecessor lists are accurate
- if (expensiveDebugCheckLevel >= 2)
- {
- fgDebugCheckBBlist();
- }
+ // Make sure that the predecessor lists are accurate
+ if (expensiveDebugCheckLevel >= 2)
+ {
+ fgDebugCheckBBlist();
}
-#endif // DEBUG
}
+#endif // DEBUG
+ }
- // 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.
- CLANG_FORMAT_COMMENT_ANCHOR;
+ // 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.
+ CLANG_FORMAT_COMMENT_ANCHOR;
#if 0
// Now try to move the entire handler region if it can be moved.
@@ -12142,38 +12141,38 @@ void Compiler::fgCreateFunclets()
#endif // 0
#if DEBUG
- if (verbose && movedHnd)
- {
- printf("\nAfter relocating an EH handler region");
- fgDispBasicBlocks();
- fgDispHandlerTab();
+ if (verbose && movedHnd)
+ {
+ printf("\nAfter relocating an EH handler region");
+ fgDispBasicBlocks();
+ fgDispHandlerTab();
- // Make sure that the predecessor lists are accurate
- if (expensiveDebugCheckLevel >= 2)
- {
- fgDebugCheckBBlist();
- }
+ // Make sure that the predecessor lists are accurate
+ if (expensiveDebugCheckLevel >= 2)
+ {
+ fgDebugCheckBBlist();
}
-#endif // DEBUG
}
+#endif // DEBUG
}
}
+ }
#if DEBUG
- fgVerifyHandlerTab();
+ fgVerifyHandlerTab();
- if (verbose && result)
- {
- printf("\nAfter fgRelocateEHRegions()");
- fgDispBasicBlocks();
- fgDispHandlerTab();
- // Make sure that the predecessor lists are accurate
- fgDebugCheckBBlist();
- }
+ if (verbose && result)
+ {
+ printf("\nAfter fgRelocateEHRegions()");
+ fgDispBasicBlocks();
+ fgDispHandlerTab();
+ // Make sure that the predecessor lists are accurate
+ fgDebugCheckBBlist();
+ }
#endif // DEBUG
- return result;
- }
+ return result;
+}
#endif // !FEATURE_EH_FUNCLETS
@@ -13489,6 +13488,7 @@ bool Compiler::fgOptimizeSwitchBranches(BasicBlock* block)
GenTree* switchVal = switchTree->gtOp.gtOp1;
noway_assert(genActualTypeIsIntOrI(switchVal->TypeGet()));
+#ifndef LEGACY_BACKEND
// If we are in LIR, remove the jump table from the block.
if (block->IsLIR())
{
@@ -13496,6 +13496,7 @@ bool Compiler::fgOptimizeSwitchBranches(BasicBlock* block)
assert(jumpTable->OperGet() == GT_JMPTABLE);
blockRange->Remove(jumpTable);
}
+#endif
// Change the GT_SWITCH(switchVal) into GT_JTRUE(GT_EQ(switchVal==0)).
// Also mark the node as GTF_DONT_CSE as further down JIT is not capable of handling it.
@@ -13793,7 +13794,7 @@ bool Compiler::fgOptimizeBranchToNext(BasicBlock* block, BasicBlock* bNext, Basi
{
LIR::Range& blockRange = LIR::AsRange(block);
GenTree* jmp = blockRange.LastNode();
- assert(jmp->OperGet() == GT_JTRUE);
+ assert(jmp->OperIsConditionalJump());
bool isClosed;
unsigned sideEffects;
@@ -14034,7 +14035,7 @@ bool Compiler::fgOptimizeBranch(BasicBlock* bJump)
// we are willing to have more code expansion since we
// won't be running code from this page
//
- if (opts.eeFlags & CORJIT_FLG_PREJIT)
+ if (opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT))
{
if (rareJump)
{
@@ -14169,16 +14170,16 @@ bool Compiler::fgOptimizeBranch(BasicBlock* bJump)
//
gtReverseCond(condTree);
+ // We need to update the following flags of the bJump block if they were set in the bDest block
+ bJump->bbFlags |=
+ (bDest->bbFlags & (BBF_HAS_NEWOBJ | BBF_HAS_NEWARRAY | BBF_HAS_NULLCHECK | BBF_HAS_IDX_LEN | BBF_HAS_VTABREF));
+
bJump->bbJumpKind = BBJ_COND;
bJump->bbJumpDest = bDest->bbNext;
/* Mark the jump dest block as being a jump target */
bJump->bbJumpDest->bbFlags |= BBF_JMP_TARGET | BBF_HAS_LABEL;
- // We need to update the following flags of the bJump block if they were set in the bbJumpDest block
- bJump->bbFlags |= (bJump->bbJumpDest->bbFlags &
- (BBF_HAS_NEWOBJ | BBF_HAS_NEWARRAY | BBF_HAS_NULLCHECK | BBF_HAS_IDX_LEN | BBF_HAS_VTABREF));
-
/* Update bbRefs and bbPreds */
// bJump now falls through into the next block
@@ -15879,11 +15880,18 @@ bool Compiler::fgUpdateFlowGraph(bool doTailDuplication)
/* Reverse the jump condition */
GenTree* test = block->lastNode();
- noway_assert(test->gtOper == GT_JTRUE);
+ noway_assert(test->OperIsConditionalJump());
- GenTree* cond = gtReverseCond(test->gtOp.gtOp1);
- assert(cond == test->gtOp.gtOp1); // Ensure `gtReverseCond` did not create a new node.
- test->gtOp.gtOp1 = cond;
+ if (test->OperGet() == GT_JTRUE)
+ {
+ GenTree* cond = gtReverseCond(test->gtOp.gtOp1);
+ assert(cond == test->gtOp.gtOp1); // Ensure `gtReverseCond` did not create a new node.
+ test->gtOp.gtOp1 = cond;
+ }
+ else
+ {
+ gtReverseCond(test);
+ }
// Optimize the Conditional JUMP to go to the new target
block->bbJumpDest = bNext->bbJumpDest;
@@ -18020,9 +18028,13 @@ void Compiler::fgSetTreeSeqFinish(GenTreePtr tree, bool isLIR)
{
// If we are sequencing a node that does not appear in LIR,
// do not add it to the list.
- if (isLIR && (((tree->OperGet() == GT_LIST) && !tree->AsArgList()->IsAggregate()) || tree->OperGet() == GT_ARGPLACE))
+ if (isLIR)
{
- return;
+ if ((tree->OperGet() == GT_LIST) || (tree->OperGet() == GT_ARGPLACE) ||
+ (tree->OperGet() == GT_FIELD_LIST && !tree->AsFieldList()->IsFieldListHead()))
+ {
+ return;
+ }
}
/* Append to the node list */
@@ -18359,7 +18371,7 @@ void Compiler::fgSetBlockOrder(BasicBlock* block)
//
// For the (usual) case of GT_BLK or GT_OBJ, the size is always "evaluated" (i.e.
// instantiated into a register) last. In those cases, the GTF_REVERSE_OPS flag
-// on the assignment works as usual.
+// on the assignment works as usual.
// In order to preserve previous possible orderings, the order for evaluating
// the size of a GT_DYN_BLK node is controlled by its gtEvalSizeFirst flag. If
// that is set, the size is evaluated first, and then the src and dst are evaluated
@@ -18549,20 +18561,20 @@ static escapeMapping_t s_EscapeMapping[] =
{'"', "&quot;"},
{0, nullptr}
};
-// clang-formt on
+// clang-format on
-const char* Compiler::fgProcessEscapes(const char* nameIn, escapeMapping_t* map)
+const char* Compiler::fgProcessEscapes(const char* nameIn, escapeMapping_t* map)
{
- const char* nameOut = nameIn;
- unsigned lengthOut;
- unsigned index;
- bool match;
- bool subsitutionRequired;
- const char* pChar;
-
- lengthOut = 1;
+ const char* nameOut = nameIn;
+ unsigned lengthOut;
+ unsigned index;
+ bool match;
+ bool subsitutionRequired;
+ const char* pChar;
+
+ lengthOut = 1;
subsitutionRequired = false;
- pChar = nameIn;
+ pChar = nameIn;
while (*pChar != '\0')
{
match = false;
@@ -18590,8 +18602,8 @@ const char* Compiler::fgProcessEscapes(const char* nameIn, escapeMapping_t* ma
if (subsitutionRequired)
{
- char* newName = (char*) compGetMemA(lengthOut, CMK_DebugOnly);
- char* pDest;
+ char* newName = (char*)compGetMemA(lengthOut, CMK_DebugOnly);
+ char* pDest;
pDest = newName;
pChar = nameIn;
while (*pChar != '\0')
@@ -18619,7 +18631,7 @@ const char* Compiler::fgProcessEscapes(const char* nameIn, escapeMapping_t* ma
pChar++;
}
*pDest++ = '\0';
- nameOut = (const char*) newName;
+ nameOut = (const char*)newName;
}
return nameOut;
@@ -18655,44 +18667,47 @@ static void fprintfDouble(FILE* fgxFile, double value)
// Opens a file to which a flowgraph can be dumped, whose name is based on the current
// config vales.
-FILE* Compiler::fgOpenFlowGraphFile(bool* wbDontClose, Phases phase, LPCWSTR type)
+FILE* Compiler::fgOpenFlowGraphFile(bool* wbDontClose, Phases phase, LPCWSTR type)
{
- FILE* fgxFile;
- LPCWSTR pattern = nullptr;
- LPCWSTR filename = nullptr;
- LPCWSTR pathname = nullptr;
- const char* escapedString;
- bool createDuplicateFgxFiles = true;
+ FILE* fgxFile;
+ LPCWSTR pattern = nullptr;
+ LPCWSTR filename = nullptr;
+ LPCWSTR pathname = nullptr;
+ const char* escapedString;
+ bool createDuplicateFgxFiles = true;
#ifdef DEBUG
- if (opts.eeFlags & CORJIT_FLG_PREJIT)
+ if (opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT))
{
- pattern = JitConfig.NgenDumpFg();
+ pattern = JitConfig.NgenDumpFg();
filename = JitConfig.NgenDumpFgFile();
pathname = JitConfig.NgenDumpFgDir();
}
else
{
- pattern = JitConfig.JitDumpFg();
+ pattern = JitConfig.JitDumpFg();
filename = JitConfig.JitDumpFgFile();
pathname = JitConfig.JitDumpFgDir();
}
#endif // DEBUG
- if (fgBBcount <= 1) {
+ if (fgBBcount <= 1)
+ {
return nullptr;
-}
+ }
- if (pattern == nullptr) {
+ if (pattern == nullptr)
+ {
return nullptr;
-}
+ }
- if (wcslen(pattern) == 0) {
+ if (wcslen(pattern) == 0)
+ {
return nullptr;
-}
+ }
LPCWSTR phasePattern = JitConfig.JitDumpFgPhase();
- LPCWSTR phaseName = PhaseShortNames[phase];
+ LPCWSTR phaseName = PhaseShortNames[phase];
if (phasePattern == nullptr)
{
if (phase != PHASE_DETERMINE_FIRST_COLD_BLOCK)
@@ -18723,9 +18738,10 @@ FILE* Compiler::fgOpenFlowGraphFile(bool* wbDontClose, Phases phas
{
while ((*pattern != W(':')) && (*pattern != W('*')))
{
- if (*pattern != *className) {
+ if (*pattern != *className)
+ {
return nullptr;
-}
+ }
pattern++;
className++;
@@ -18736,12 +18752,14 @@ FILE* Compiler::fgOpenFlowGraphFile(bool* wbDontClose, Phases phas
}
else
{
- if (*className != 0) {
+ if (*className != 0)
+ {
return nullptr;
-}
- }
+ }
}
- if (*pattern != W(':')) {
+ }
+ if (*pattern != W(':'))
+ {
return nullptr;
}
@@ -18757,9 +18775,10 @@ FILE* Compiler::fgOpenFlowGraphFile(bool* wbDontClose, Phases phas
{
while ((*pattern != 0) && (*pattern != W('*')))
{
- if (*pattern != *methodName) {
+ if (*pattern != *methodName)
+ {
return nullptr;
-}
+ }
pattern++;
methodName++;
@@ -18770,12 +18789,14 @@ FILE* Compiler::fgOpenFlowGraphFile(bool* wbDontClose, Phases phas
}
else
{
- if (*methodName != 0) {
+ if (*methodName != 0)
+ {
return nullptr;
-}
- }
+ }
}
- if (*pattern != 0) {
+ }
+ if (*pattern != 0)
+ {
return nullptr;
}
}
@@ -18838,15 +18859,15 @@ FILE* Compiler::fgOpenFlowGraphFile(bool* wbDontClose, Phases phas
{
createDuplicateFgxFiles = true;
-ONE_FILE_PER_METHOD:;
+ ONE_FILE_PER_METHOD:;
- escapedString = fgProcessEscapes(info.compFullName, s_EscapeFileMapping);
+ escapedString = fgProcessEscapes(info.compFullName, s_EscapeFileMapping);
size_t wCharCount = strlen(escapedString) + wcslen(phaseName) + 1 + strlen("~999") + wcslen(type) + 1;
if (pathname != nullptr)
{
wCharCount += wcslen(pathname) + 1;
}
- filename = (LPCWSTR) alloca(wCharCount * sizeof(WCHAR));
+ filename = (LPCWSTR)alloca(wCharCount * sizeof(WCHAR));
if (pathname != nullptr)
{
swprintf_s((LPWSTR)filename, wCharCount, W("%s\\%S-%s.%s"), pathname, escapedString, phaseName, type);
@@ -18855,7 +18876,7 @@ ONE_FILE_PER_METHOD:;
{
swprintf_s((LPWSTR)filename, wCharCount, W("%S.%s"), escapedString, type);
}
- fgxFile = _wfopen(filename, W("r")); // Check if this file already exists
+ fgxFile = _wfopen(filename, W("r")); // Check if this file already exists
if (fgxFile != nullptr)
{
// For Generic methods we will have both hot and cold versions
@@ -18876,10 +18897,11 @@ ONE_FILE_PER_METHOD:;
{
swprintf_s((LPWSTR)filename, wCharCount, W("%S~%d.%s"), escapedString, i, type);
}
- fgxFile = _wfopen(filename, W("r")); // Check if this file exists
- if (fgxFile == nullptr) {
+ fgxFile = _wfopen(filename, W("r")); // Check if this file exists
+ if (fgxFile == nullptr)
+ {
break;
- }
+ }
}
// If we have already created 1000 files with this name then just fail
if (fgxFile != nullptr)
@@ -18888,28 +18910,28 @@ ONE_FILE_PER_METHOD:;
return nullptr;
}
}
- fgxFile = _wfopen(filename, W("a+"));
+ fgxFile = _wfopen(filename, W("a+"));
*wbDontClose = false;
}
else if (wcscmp(filename, W("stdout")) == 0)
{
- fgxFile = jitstdout;
+ fgxFile = jitstdout;
*wbDontClose = true;
}
else if (wcscmp(filename, W("stderr")) == 0)
{
- fgxFile = stderr;
+ fgxFile = stderr;
*wbDontClose = true;
}
else
{
LPCWSTR origFilename = filename;
- size_t wCharCount = wcslen(origFilename) + wcslen(type) + 2;
+ size_t wCharCount = wcslen(origFilename) + wcslen(type) + 2;
if (pathname != nullptr)
{
wCharCount += wcslen(pathname) + 1;
}
- filename = (LPCWSTR) alloca(wCharCount * sizeof(WCHAR));
+ filename = (LPCWSTR)alloca(wCharCount * sizeof(WCHAR));
if (pathname != nullptr)
{
swprintf_s((LPWSTR)filename, wCharCount, W("%s\\%s.%s"), pathname, origFilename, type);
@@ -18918,7 +18940,7 @@ ONE_FILE_PER_METHOD:;
{
swprintf_s((LPWSTR)filename, wCharCount, W("%s.%s"), origFilename, type);
}
- fgxFile = _wfopen(filename, W("a+"));
+ fgxFile = _wfopen(filename, W("a+"));
*wbDontClose = false;
}
@@ -18959,39 +18981,39 @@ ONE_FILE_PER_METHOD:;
// phases.
// COMPlus_JitDumpFgDot Set to non-zero to emit Dot instead of Xml Flowgraph dump. (Default is xml format.)
-bool Compiler::fgDumpFlowGraph(Phases phase)
+bool Compiler::fgDumpFlowGraph(Phases phase)
{
- bool result = false;
- bool dontClose = false;
- bool createDotFile = false;
+ bool result = false;
+ bool dontClose = false;
+ bool createDotFile = false;
if (JitConfig.JitDumpFgDot())
{
createDotFile = true;
}
-
- FILE* fgxFile = fgOpenFlowGraphFile(&dontClose, phase, createDotFile ? W("dot") : W("fgx"));
+
+ FILE* fgxFile = fgOpenFlowGraphFile(&dontClose, phase, createDotFile ? W("dot") : W("fgx"));
if (fgxFile == nullptr)
{
return false;
}
- bool validWeights = fgHaveValidEdgeWeights;
- unsigned calledCount = max(fgCalledWeight, BB_UNITY_WEIGHT) / BB_UNITY_WEIGHT;
- double weightDivisor = (double) (calledCount * BB_UNITY_WEIGHT);
- const char* escapedString;
- const char* regionString = "NONE";
+ bool validWeights = fgHaveValidEdgeWeights;
+ unsigned calledCount = max(fgCalledWeight, BB_UNITY_WEIGHT) / BB_UNITY_WEIGHT;
+ double weightDivisor = (double)(calledCount * BB_UNITY_WEIGHT);
+ const char* escapedString;
+ const char* regionString = "NONE";
- if (info.compMethodInfo->regionKind == CORINFO_REGION_HOT)
+ if (info.compMethodInfo->regionKind == CORINFO_REGION_HOT)
{
- regionString="HOT";
+ regionString = "HOT";
}
else if (info.compMethodInfo->regionKind == CORINFO_REGION_COLD)
{
- regionString="COLD";
+ regionString = "COLD";
}
else if (info.compMethodInfo->regionKind == CORINFO_REGION_JIT)
{
- regionString="JIT";
+ regionString = "JIT";
}
if (createDotFile)
@@ -19001,7 +19023,7 @@ bool Compiler::fgDumpFlowGraph(Phases phase)
}
else
{
- fprintf(fgxFile, "<method");
+ fprintf(fgxFile, "<method");
escapedString = fgProcessEscapes(info.compFullName, s_EscapeMapping);
fprintf(fgxFile, "\n name=\"%s\"", escapedString);
@@ -19042,77 +19064,74 @@ bool Compiler::fgDumpFlowGraph(Phases phase)
fprintf(fgxFile, "\n firstColdBlock=\"%d\"", fgFirstColdBlock->bbNum);
}
- fprintf(fgxFile, ">");
+ fprintf(fgxFile, ">");
fprintf(fgxFile, "\n <blocks");
fprintf(fgxFile, "\n blockCount=\"%d\"", fgBBcount);
- fprintf(fgxFile, ">");
+ fprintf(fgxFile, ">");
}
- static const char* kindImage[] = { "EHFINALLYRET", "EHFILTERRET", "EHCATCHRET",
- "THROW", "RETURN", "NONE", "ALWAYS", "LEAVE",
- "CALLFINALLY", "COND", "SWITCH" };
+ static const char* kindImage[] = {"EHFINALLYRET", "EHFILTERRET", "EHCATCHRET", "THROW", "RETURN", "NONE",
+ "ALWAYS", "LEAVE", "CALLFINALLY", "COND", "SWITCH"};
BasicBlock* block;
unsigned blockOrdinal;
- for (block = fgFirstBB , blockOrdinal = 1;
- block != nullptr;
- block = block->bbNext, blockOrdinal++)
+ for (block = fgFirstBB, blockOrdinal = 1; block != nullptr; block = block->bbNext, blockOrdinal++)
{
if (createDotFile)
{
// Add constraint edges to try to keep nodes ordered.
// It seems to work best if these edges are all created first.
- switch(block->bbJumpKind)
+ switch (block->bbJumpKind)
{
- case BBJ_COND:
- case BBJ_NONE:
- assert(block->bbNext != nullptr);
- fprintf(fgxFile, " BB%02u -> BB%02u\n", block->bbNum, block->bbNext->bbNum);
- break;
- default:
- // These may or may not have an edge to the next block.
- // Add a transparent edge to keep nodes ordered.
- if (block->bbNext != nullptr)
- {
- fprintf(fgxFile, " BB%02u -> BB%02u [arrowtail=none,color=transparent]\n", block->bbNum, block->bbNext->bbNum);
- }
+ case BBJ_COND:
+ case BBJ_NONE:
+ assert(block->bbNext != nullptr);
+ fprintf(fgxFile, " BB%02u -> BB%02u\n", block->bbNum, block->bbNext->bbNum);
+ break;
+ default:
+ // These may or may not have an edge to the next block.
+ // Add a transparent edge to keep nodes ordered.
+ if (block->bbNext != nullptr)
+ {
+ fprintf(fgxFile, " BB%02u -> BB%02u [arrowtail=none,color=transparent]\n", block->bbNum,
+ block->bbNext->bbNum);
+ }
}
}
else
{
- fprintf(fgxFile,"\n <block");
- fprintf(fgxFile,"\n id=\"%d\"", block->bbNum);
- fprintf(fgxFile,"\n ordinal=\"%d\"", blockOrdinal);
- fprintf(fgxFile,"\n jumpKind=\"%s\"", kindImage[block->bbJumpKind]);
+ fprintf(fgxFile, "\n <block");
+ fprintf(fgxFile, "\n id=\"%d\"", block->bbNum);
+ fprintf(fgxFile, "\n ordinal=\"%d\"", blockOrdinal);
+ fprintf(fgxFile, "\n jumpKind=\"%s\"", kindImage[block->bbJumpKind]);
if (block->hasTryIndex())
{
- fprintf(fgxFile,"\n inTry=\"%s\"", "true");
+ fprintf(fgxFile, "\n inTry=\"%s\"", "true");
}
if (block->hasHndIndex())
{
- fprintf(fgxFile,"\n inHandler=\"%s\"", "true");
+ fprintf(fgxFile, "\n inHandler=\"%s\"", "true");
}
- if (((fgFirstBB->bbFlags & BBF_PROF_WEIGHT) != 0) &&
- ((block->bbFlags & BBF_COLD) == 0) )
+ if (((fgFirstBB->bbFlags & BBF_PROF_WEIGHT) != 0) && ((block->bbFlags & BBF_COLD) == 0))
{
- fprintf(fgxFile,"\n hot=\"true\"");
+ fprintf(fgxFile, "\n hot=\"true\"");
}
if (block->bbFlags & (BBF_HAS_NEWOBJ | BBF_HAS_NEWARRAY))
{
- fprintf(fgxFile,"\n callsNew=\"true\"");
+ fprintf(fgxFile, "\n callsNew=\"true\"");
}
if (block->bbFlags & BBF_LOOP_HEAD)
{
- fprintf(fgxFile,"\n loopHead=\"true\"");
+ fprintf(fgxFile, "\n loopHead=\"true\"");
}
- fprintf(fgxFile,"\n weight=");
- fprintfDouble(fgxFile, ((double) block->bbWeight) / weightDivisor);
- fprintf(fgxFile,"\n codeEstimate=\"%d\"", fgGetCodeEstimate(block));
- fprintf(fgxFile,"\n startOffset=\"%d\"", block->bbCodeOffs);
- fprintf(fgxFile,"\n endOffset=\"%d\"", block->bbCodeOffsEnd);
- fprintf(fgxFile, ">");
- fprintf(fgxFile,"\n </block>");
+ fprintf(fgxFile, "\n weight=");
+ fprintfDouble(fgxFile, ((double)block->bbWeight) / weightDivisor);
+ fprintf(fgxFile, "\n codeEstimate=\"%d\"", fgGetCodeEstimate(block));
+ fprintf(fgxFile, "\n startOffset=\"%d\"", block->bbCodeOffs);
+ fprintf(fgxFile, "\n endOffset=\"%d\"", block->bbCodeOffsEnd);
+ fprintf(fgxFile, ">");
+ fprintf(fgxFile, "\n </block>");
}
}
@@ -19122,10 +19141,10 @@ bool Compiler::fgDumpFlowGraph(Phases phase)
fprintf(fgxFile, "\n <edges");
fprintf(fgxFile, "\n edgeCount=\"%d\"", fgEdgeCount);
- fprintf(fgxFile, ">");
+ fprintf(fgxFile, ">");
}
- unsigned edgeNum = 1;
+ unsigned edgeNum = 1;
BasicBlock* bTarget;
for (bTarget = fgFirstBB; bTarget != nullptr; bTarget = bTarget->bbNext)
{
@@ -19136,21 +19155,21 @@ bool Compiler::fgDumpFlowGraph(Phases phase)
}
else
{
- targetWeightDivisor = (double) bTarget->bbWeight;
+ targetWeightDivisor = (double)bTarget->bbWeight;
}
flowList* edge;
for (edge = bTarget->bbPreds; edge != nullptr; edge = edge->flNext, edgeNum++)
{
- BasicBlock* bSource = edge->flBlock;
- double sourceWeightDivisor;
+ BasicBlock* bSource = edge->flBlock;
+ double sourceWeightDivisor;
if (bSource->bbWeight == BB_ZERO_WEIGHT)
{
sourceWeightDivisor = 1.0;
}
else
{
- sourceWeightDivisor = (double) bSource->bbWeight;
+ sourceWeightDivisor = (double)bSource->bbWeight;
}
if (createDotFile)
{
@@ -19172,54 +19191,54 @@ bool Compiler::fgDumpFlowGraph(Phases phase)
}
else
{
- fprintf(fgxFile,"\n <edge");
- fprintf(fgxFile,"\n id=\"%d\"", edgeNum);
- fprintf(fgxFile,"\n source=\"%d\"", bSource->bbNum);
- fprintf(fgxFile,"\n target=\"%d\"", bTarget->bbNum);
+ fprintf(fgxFile, "\n <edge");
+ fprintf(fgxFile, "\n id=\"%d\"", edgeNum);
+ fprintf(fgxFile, "\n source=\"%d\"", bSource->bbNum);
+ fprintf(fgxFile, "\n target=\"%d\"", bTarget->bbNum);
if (bSource->bbJumpKind == BBJ_SWITCH)
{
if (edge->flDupCount >= 2)
{
- fprintf(fgxFile,"\n switchCases=\"%d\"", edge->flDupCount);
+ fprintf(fgxFile, "\n switchCases=\"%d\"", edge->flDupCount);
}
if (bSource->bbJumpSwt->getDefault() == bTarget)
{
- fprintf(fgxFile,"\n switchDefault=\"true\"");
+ fprintf(fgxFile, "\n switchDefault=\"true\"");
}
}
if (validWeights)
{
unsigned edgeWeight = (edge->flEdgeWeightMin + edge->flEdgeWeightMax) / 2;
- fprintf(fgxFile,"\n weight=");
- fprintfDouble(fgxFile, ((double) edgeWeight) / weightDivisor);
+ fprintf(fgxFile, "\n weight=");
+ fprintfDouble(fgxFile, ((double)edgeWeight) / weightDivisor);
if (edge->flEdgeWeightMin != edge->flEdgeWeightMax)
{
- fprintf(fgxFile,"\n minWeight=");
- fprintfDouble(fgxFile, ((double) edge->flEdgeWeightMin) / weightDivisor);
- fprintf(fgxFile,"\n maxWeight=");
- fprintfDouble(fgxFile, ((double) edge->flEdgeWeightMax) / weightDivisor);
+ fprintf(fgxFile, "\n minWeight=");
+ fprintfDouble(fgxFile, ((double)edge->flEdgeWeightMin) / weightDivisor);
+ fprintf(fgxFile, "\n maxWeight=");
+ fprintfDouble(fgxFile, ((double)edge->flEdgeWeightMax) / weightDivisor);
}
if (edgeWeight > 0)
{
if (edgeWeight < bSource->bbWeight)
{
- fprintf(fgxFile,"\n out=");
- fprintfDouble(fgxFile, ((double) edgeWeight) / sourceWeightDivisor );
+ fprintf(fgxFile, "\n out=");
+ fprintfDouble(fgxFile, ((double)edgeWeight) / sourceWeightDivisor);
}
if (edgeWeight < bTarget->bbWeight)
{
- fprintf(fgxFile,"\n in=");
- fprintfDouble(fgxFile, ((double) edgeWeight) / targetWeightDivisor);
+ fprintf(fgxFile, "\n in=");
+ fprintfDouble(fgxFile, ((double)edgeWeight) / targetWeightDivisor);
}
}
}
}
if (!createDotFile)
{
- fprintf(fgxFile, ">");
- fprintf(fgxFile,"\n </edge>");
+ fprintf(fgxFile, ">");
+ fprintf(fgxFile, "\n </edge>");
}
}
}
@@ -19251,7 +19270,7 @@ bool Compiler::fgDumpFlowGraph(Phases phase)
/*****************************************************************************/
#ifdef DEBUG
-void Compiler::fgDispReach()
+void Compiler::fgDispReach()
{
printf("------------------------------------------------\n");
printf("BBnum Reachable by \n");
@@ -19269,7 +19288,7 @@ void Compiler::fgDispReach()
}
}
-void Compiler::fgDispDoms()
+void Compiler::fgDispDoms()
{
// Don't bother printing this when we have a large number of BasicBlocks in the method
if (fgBBcount > 256)
@@ -19296,23 +19315,17 @@ void Compiler::fgDispDoms()
/*****************************************************************************/
-void Compiler::fgTableDispBasicBlock(BasicBlock* block,
- int ibcColWidth /* = 0 */)
+void Compiler::fgTableDispBasicBlock(BasicBlock* block, int ibcColWidth /* = 0 */)
{
- unsigned flags = block->bbFlags;
+ const unsigned __int64 flags = block->bbFlags;
+ unsigned bbNumMax = compIsForInlining() ? impInlineInfo->InlinerCompiler->fgBBNumMax : fgBBNumMax;
+ int maxBlockNumWidth = CountDigits(bbNumMax);
+ maxBlockNumWidth = max(maxBlockNumWidth, 2);
+ int blockNumWidth = CountDigits(block->bbNum);
+ blockNumWidth = max(blockNumWidth, 2);
+ int blockNumPadding = maxBlockNumWidth - blockNumWidth;
- unsigned bbNumMax = compIsForInlining() ? impInlineInfo->InlinerCompiler->fgBBNumMax : fgBBNumMax;
- int maxBlockNumWidth = CountDigits(bbNumMax);
- maxBlockNumWidth = max(maxBlockNumWidth, 2);
- int blockNumWidth = CountDigits(block->bbNum);
- blockNumWidth = max(blockNumWidth, 2);
- int blockNumPadding = maxBlockNumWidth - blockNumWidth;
-
- printf("BB%02u%*s [%08p] %2u",
- block->bbNum,
- blockNumPadding, "",
- dspPtr(block),
- block->bbRefs);
+ printf("BB%02u%*s [%08p] %2u", block->bbNum, blockNumPadding, "", dspPtr(block), block->bbRefs);
//
// Display EH 'try' region index
@@ -19406,86 +19419,89 @@ void Compiler::fgTableDispBasicBlock(BasicBlock* block,
// Display block branch target
//
- if (flags & BBF_REMOVED)
+ if (flags & BBF_REMOVED)
{
- printf( "[removed] ");
+ printf("[removed] ");
}
else
{
switch (block->bbJumpKind)
{
- case BBJ_COND:
- printf("-> BB%02u%*s ( cond )", block->bbJumpDest->bbNum, maxBlockNumWidth - max(CountDigits(block->bbJumpDest->bbNum), 2), "");
- break;
+ case BBJ_COND:
+ printf("-> BB%02u%*s ( cond )", block->bbJumpDest->bbNum,
+ maxBlockNumWidth - max(CountDigits(block->bbJumpDest->bbNum), 2), "");
+ break;
- case BBJ_CALLFINALLY:
- printf("-> BB%02u%*s (callf )", block->bbJumpDest->bbNum, maxBlockNumWidth - max(CountDigits(block->bbJumpDest->bbNum), 2), "");
- break;
+ case BBJ_CALLFINALLY:
+ printf("-> BB%02u%*s (callf )", block->bbJumpDest->bbNum,
+ maxBlockNumWidth - max(CountDigits(block->bbJumpDest->bbNum), 2), "");
+ break;
- case BBJ_ALWAYS:
- if (flags & BBF_KEEP_BBJ_ALWAYS)
- {
- printf("-> BB%02u%*s (ALWAYS)", block->bbJumpDest->bbNum, maxBlockNumWidth - max(CountDigits(block->bbJumpDest->bbNum), 2), "");
- }
- else
- {
- printf("-> BB%02u%*s (always)", block->bbJumpDest->bbNum, maxBlockNumWidth - max(CountDigits(block->bbJumpDest->bbNum), 2), "");
- }
- break;
+ case BBJ_ALWAYS:
+ if (flags & BBF_KEEP_BBJ_ALWAYS)
+ {
+ printf("-> BB%02u%*s (ALWAYS)", block->bbJumpDest->bbNum,
+ maxBlockNumWidth - max(CountDigits(block->bbJumpDest->bbNum), 2), "");
+ }
+ else
+ {
+ printf("-> BB%02u%*s (always)", block->bbJumpDest->bbNum,
+ maxBlockNumWidth - max(CountDigits(block->bbJumpDest->bbNum), 2), "");
+ }
+ break;
- case BBJ_LEAVE:
- printf("-> BB%02u%*s (leave )", block->bbJumpDest->bbNum, maxBlockNumWidth - max(CountDigits(block->bbJumpDest->bbNum), 2), "");
- break;
+ case BBJ_LEAVE:
+ printf("-> BB%02u%*s (leave )", block->bbJumpDest->bbNum,
+ maxBlockNumWidth - max(CountDigits(block->bbJumpDest->bbNum), 2), "");
+ break;
- case BBJ_EHFINALLYRET:
- printf( "%*s (finret)", maxBlockNumWidth - 2, "");
- break;
+ case BBJ_EHFINALLYRET:
+ printf("%*s (finret)", maxBlockNumWidth - 2, "");
+ break;
- case BBJ_EHFILTERRET:
- printf( "%*s (fltret)", maxBlockNumWidth - 2, "");
- break;
+ case BBJ_EHFILTERRET:
+ printf("%*s (fltret)", maxBlockNumWidth - 2, "");
+ break;
- case BBJ_EHCATCHRET:
- printf("-> BB%02u%*s ( cret )", block->bbJumpDest->bbNum, maxBlockNumWidth - max(CountDigits(block->bbJumpDest->bbNum), 2), "");
- break;
+ case BBJ_EHCATCHRET:
+ printf("-> BB%02u%*s ( cret )", block->bbJumpDest->bbNum,
+ maxBlockNumWidth - max(CountDigits(block->bbJumpDest->bbNum), 2), "");
+ break;
- case BBJ_THROW:
- printf( "%*s (throw )", maxBlockNumWidth - 2, "");
- break;
+ case BBJ_THROW:
+ printf("%*s (throw )", maxBlockNumWidth - 2, "");
+ break;
- case BBJ_RETURN:
- printf( "%*s (return)", maxBlockNumWidth - 2, "");
- break;
+ case BBJ_RETURN:
+ printf("%*s (return)", maxBlockNumWidth - 2, "");
+ break;
- default:
- printf( "%*s ", maxBlockNumWidth - 2, "");
- break;
+ default:
+ printf("%*s ", maxBlockNumWidth - 2, "");
+ break;
- case BBJ_SWITCH:
- printf("->");
-
- unsigned jumpCnt;
- jumpCnt = block->bbJumpSwt->bbsCount;
- BasicBlock** jumpTab;
- jumpTab = block->bbJumpSwt->bbsDstTab;
- int switchWidth;
- switchWidth = 0;
- do
- {
- printf("%cBB%02u",
- (jumpTab == block->bbJumpSwt->bbsDstTab) ? ' ' : ',',
- (*jumpTab)->bbNum);
- switchWidth += 1 /* space/comma */ + 2 /* BB */ + max(CountDigits((*jumpTab)->bbNum), 2);
- }
- while (++jumpTab, --jumpCnt);
+ case BBJ_SWITCH:
+ printf("->");
- if (switchWidth < 7)
- {
- printf("%*s", 8 - switchWidth, "");
- }
+ unsigned jumpCnt;
+ jumpCnt = block->bbJumpSwt->bbsCount;
+ BasicBlock** jumpTab;
+ jumpTab = block->bbJumpSwt->bbsDstTab;
+ int switchWidth;
+ switchWidth = 0;
+ do
+ {
+ printf("%cBB%02u", (jumpTab == block->bbJumpSwt->bbsDstTab) ? ' ' : ',', (*jumpTab)->bbNum);
+ switchWidth += 1 /* space/comma */ + 2 /* BB */ + max(CountDigits((*jumpTab)->bbNum), 2);
+ } while (++jumpTab, --jumpCnt);
- printf(" (switch)");
- break;
+ if (switchWidth < 7)
+ {
+ printf("%*s", 8 - switchWidth, "");
+ }
+
+ printf(" (switch)");
+ break;
}
}
@@ -19526,12 +19542,28 @@ void Compiler::fgTableDispBasicBlock(BasicBlock* block,
switch (block->bbCatchTyp)
{
- case BBCT_NONE: break;
- case BBCT_FAULT: printf("fault "); cnt += 6; break;
- case BBCT_FINALLY: printf("finally "); cnt += 8; break;
- case BBCT_FILTER: printf("filter "); cnt += 7; break;
- case BBCT_FILTER_HANDLER: printf("filtHnd "); cnt += 8; break;
- default: printf("catch "); cnt += 6; break;
+ case BBCT_NONE:
+ break;
+ case BBCT_FAULT:
+ printf("fault ");
+ cnt += 6;
+ break;
+ case BBCT_FINALLY:
+ printf("finally ");
+ cnt += 8;
+ break;
+ case BBCT_FILTER:
+ printf("filter ");
+ cnt += 7;
+ break;
+ case BBCT_FILTER_HANDLER:
+ printf("filtHnd ");
+ cnt += 8;
+ break;
+ default:
+ printf("catch ");
+ cnt += 6;
+ break;
}
if (block->bbCatchTyp != BBCT_NONE)
@@ -19548,9 +19580,7 @@ void Compiler::fgTableDispBasicBlock(BasicBlock* block,
EHblkDsc* HBtab;
EHblkDsc* HBtabEnd;
- for (HBtab = compHndBBtab, HBtabEnd = compHndBBtab + compHndBBtabCount;
- HBtab < HBtabEnd;
- HBtab++)
+ for (HBtab = compHndBBtab, HBtabEnd = compHndBBtab + compHndBBtabCount; HBtab < HBtabEnd; HBtab++)
{
if (HBtab->ebdTryBeg == block)
{
@@ -19564,9 +19594,7 @@ void Compiler::fgTableDispBasicBlock(BasicBlock* block,
EHblkDsc* HBtab;
EHblkDsc* HBtabEnd;
- for (HBtab = compHndBBtab, HBtabEnd = compHndBBtab + compHndBBtabCount;
- HBtab < HBtabEnd;
- HBtab++)
+ for (HBtab = compHndBBtab, HBtabEnd = compHndBBtab + compHndBBtabCount; HBtab < HBtabEnd; HBtab++)
{
if (HBtab->ebdTryLast == block)
{
@@ -19607,9 +19635,7 @@ void Compiler::fgTableDispBasicBlock(BasicBlock* block,
Dump blocks from firstBlock to lastBlock.
*/
-void Compiler::fgDispBasicBlocks(BasicBlock* firstBlock,
- BasicBlock* lastBlock,
- bool dumpTrees)
+void Compiler::fgDispBasicBlocks(BasicBlock* firstBlock, BasicBlock* lastBlock, bool dumpTrees)
{
BasicBlock* block;
@@ -19627,24 +19653,27 @@ void Compiler::fgDispBasicBlocks(BasicBlock* firstBlock,
if (block->bbFlags & BBF_PROF_WEIGHT)
{
int thisIbcWidth = CountDigits(block->bbWeight);
- ibcColWidth = max(ibcColWidth, thisIbcWidth);
+ ibcColWidth = max(ibcColWidth, thisIbcWidth);
}
- if (block == lastBlock) {
+ if (block == lastBlock)
+ {
break;
- }
+ }
}
if (ibcColWidth > 0)
{
ibcColWidth = max(ibcColWidth, 3) + 1; // + 1 for the leading space
}
- unsigned bbNumMax = compIsForInlining() ? impInlineInfo->InlinerCompiler->fgBBNumMax : fgBBNumMax;
- int maxBlockNumWidth = CountDigits(bbNumMax);
- maxBlockNumWidth = max(maxBlockNumWidth, 2);
+ unsigned bbNumMax = compIsForInlining() ? impInlineInfo->InlinerCompiler->fgBBNumMax : fgBBNumMax;
+ int maxBlockNumWidth = CountDigits(bbNumMax);
+ maxBlockNumWidth = max(maxBlockNumWidth, 2);
padWidth += maxBlockNumWidth - 2; // Account for functions with a large number of blocks.
+ // clang-format off
+
printf("\n");
printf("------%*s------------------------------------%*s-----------------------%*s----------------------------------------\n",
padWidth, "------------",
@@ -19665,9 +19694,9 @@ void Compiler::fgDispBasicBlocks(BasicBlock* firstBlock,
ibcColWidth, "------------",
maxBlockNumWidth, "----");
- for (block = firstBlock;
- block;
- block = block->bbNext)
+ // clang-format on
+
+ for (block = firstBlock; block; block = block->bbNext)
{
// First, do some checking on the bbPrev links
if (block->bbPrev)
@@ -19681,36 +19710,34 @@ void Compiler::fgDispBasicBlocks(BasicBlock* firstBlock,
{
printf("bad prev link!\n");
}
-
+
if (block == fgFirstColdBlock)
{
- printf("~~~~~~%*s~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%*s~~~~~~~~~~~~~~~~~~~~~~~%*s~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
- padWidth, "~~~~~~~~~~~~",
- ibcColWidth, "~~~~~~~~~~~~",
- maxBlockNumWidth, "~~~~");
+ printf("~~~~~~%*s~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%*s~~~~~~~~~~~~~~~~~~~~~~~%*s~~~~~~~~~~~~~~~~~~~~~~~~~"
+ "~~~~~~~~~~~~~~~\n",
+ padWidth, "~~~~~~~~~~~~", ibcColWidth, "~~~~~~~~~~~~", maxBlockNumWidth, "~~~~");
}
#if FEATURE_EH_FUNCLETS
if (block == fgFirstFuncletBB)
{
- printf("++++++%*s++++++++++++++++++++++++++++++++++++%*s+++++++++++++++++++++++%*s++++++++++++++++++++++++++++++++++++++++ funclets follow\n",
- padWidth, "++++++++++++",
- ibcColWidth, "++++++++++++",
- maxBlockNumWidth, "++++");
+ printf("++++++%*s++++++++++++++++++++++++++++++++++++%*s+++++++++++++++++++++++%*s+++++++++++++++++++++++++"
+ "+++++++++++++++ funclets follow\n",
+ padWidth, "++++++++++++", ibcColWidth, "++++++++++++", maxBlockNumWidth, "++++");
}
#endif // FEATURE_EH_FUNCLETS
fgTableDispBasicBlock(block, ibcColWidth);
- if (block == lastBlock) {
+ if (block == lastBlock)
+ {
break;
- }
+ }
}
- printf("------%*s------------------------------------%*s-----------------------%*s----------------------------------------\n",
- padWidth, "------------",
- ibcColWidth, "------------",
- maxBlockNumWidth, "----");
+ printf("------%*s------------------------------------%*s-----------------------%*s---------------------------------"
+ "-------\n",
+ padWidth, "------------", ibcColWidth, "------------", maxBlockNumWidth, "----");
if (dumpTrees)
{
@@ -19720,7 +19747,7 @@ void Compiler::fgDispBasicBlocks(BasicBlock* firstBlock,
/*****************************************************************************/
-void Compiler::fgDispBasicBlocks(bool dumpTrees)
+void Compiler::fgDispBasicBlocks(bool dumpTrees)
{
fgDispBasicBlocks(fgFirstBB, nullptr, dumpTrees);
}
@@ -19728,9 +19755,9 @@ void Compiler::fgDispBasicBlocks(bool dumpTrees)
/*****************************************************************************/
// Increment the stmtNum and dump the tree using gtDispTree
//
-void Compiler::fgDumpStmtTree(GenTreePtr stmt, unsigned blkNum)
+void Compiler::fgDumpStmtTree(GenTreePtr stmt, unsigned blkNum)
{
- compCurStmtNum++; // Increment the current stmtNum
+ compCurStmtNum++; // Increment the current stmtNum
printf("\n***** BB%02u, stmt %d\n", blkNum, compCurStmtNum);
@@ -19750,7 +19777,7 @@ void Compiler::fgDumpStmtTree(GenTreePtr stmt, unsigned blkNum)
// Arguments:
// block - The block to dump.
//
-void Compiler::fgDumpBlock(BasicBlock* block)
+void Compiler::fgDumpBlock(BasicBlock* block)
{
printf("\n------------ ");
block->dspBlockHeader(this);
@@ -19762,7 +19789,7 @@ void Compiler::fgDumpBlock(BasicBlock* block)
fgDumpStmtTree(stmt, block->bbNum);
if (stmt == block->bbTreeList)
{
- block->bbStmtNum = compCurStmtNum; // Set the block->bbStmtNum
+ block->bbStmtNum = compCurStmtNum; // Set the block->bbStmtNum
}
}
}
@@ -19775,63 +19802,81 @@ void Compiler::fgDumpBlock(BasicBlock* block)
/*****************************************************************************/
// Walk the BasicBlock list calling fgDumpTree once per Stmt
//
-void Compiler::fgDumpTrees(BasicBlock* firstBlock,
- BasicBlock* lastBlock)
+void Compiler::fgDumpTrees(BasicBlock* firstBlock, BasicBlock* lastBlock)
{
- compCurStmtNum = 0; // Reset the current stmtNum
+ compCurStmtNum = 0; // Reset the current stmtNum
/* Walk the basic blocks */
- // Note that typically we have already called fgDispBasicBlocks()
+ // Note that typically we have already called fgDispBasicBlocks()
// so we don't need to print the preds and succs again here
//
for (BasicBlock* block = firstBlock; block; block = block->bbNext)
{
fgDumpBlock(block);
- if (block == lastBlock) {
+ if (block == lastBlock)
+ {
break;
+ }
}
- }
- printf("\n-------------------------------------------------------------------------------------------------------------------\n");
+ printf("\n---------------------------------------------------------------------------------------------------------"
+ "----------\n");
}
-
/*****************************************************************************
* Try to create as many candidates for GTF_MUL_64RSLT as possible.
* We convert 'intOp1*intOp2' into 'int(long(nop(intOp1))*long(intOp2))'.
*/
/* static */
-Compiler::fgWalkResult Compiler::fgStress64RsltMulCB(GenTreePtr* pTree, fgWalkData* data)
+Compiler::fgWalkResult Compiler::fgStress64RsltMulCB(GenTreePtr* pTree, fgWalkData* data)
{
- GenTreePtr tree = *pTree;
+ GenTreePtr tree = *pTree;
Compiler* pComp = data->compiler;
-
- if (tree->gtOper != GT_MUL || tree->gtType != TYP_INT || (tree->gtOverflow())) {
+
+ if (tree->gtOper != GT_MUL || tree->gtType != TYP_INT || (tree->gtOverflow()))
+ {
return WALK_CONTINUE;
-}
+ }
+
+#ifdef DEBUG
+ if (pComp->verbose)
+ {
+ printf("STRESS_64RSLT_MUL before:\n");
+ pComp->gtDispTree(tree);
+ }
+#endif // DEBUG
// To ensure optNarrowTree() doesn't fold back to the original tree.
- tree->gtOp.gtOp1 = pComp->gtNewOperNode(GT_NOP, TYP_LONG, tree->gtOp.gtOp1);
tree->gtOp.gtOp1 = pComp->gtNewCastNode(TYP_LONG, tree->gtOp.gtOp1, TYP_LONG);
- tree->gtOp.gtOp2 = pComp->gtNewCastNode(TYP_LONG, tree->gtOp.gtOp2, TYP_LONG);
- tree->gtType = TYP_LONG;
- *pTree = pComp->gtNewCastNode(TYP_INT, tree, TYP_INT);
+ tree->gtOp.gtOp1 = pComp->gtNewOperNode(GT_NOP, TYP_LONG, tree->gtOp.gtOp1);
+ tree->gtOp.gtOp1 = pComp->gtNewCastNode(TYP_LONG, tree->gtOp.gtOp1, TYP_LONG);
+ tree->gtOp.gtOp2 = pComp->gtNewCastNode(TYP_LONG, tree->gtOp.gtOp2, TYP_LONG);
+ tree->gtType = TYP_LONG;
+ *pTree = pComp->gtNewCastNode(TYP_INT, tree, TYP_INT);
+
+#ifdef DEBUG
+ if (pComp->verbose)
+ {
+ printf("STRESS_64RSLT_MUL after:\n");
+ pComp->gtDispTree(*pTree);
+ }
+#endif // DEBUG
return WALK_SKIP_SUBTREES;
}
-void Compiler::fgStress64RsltMul()
+void Compiler::fgStress64RsltMul()
{
- if (!compStressCompile(STRESS_64RSLT_MUL, 20)) {
+ if (!compStressCompile(STRESS_64RSLT_MUL, 20))
+ {
return;
-}
+ }
fgWalkAllTreesPre(fgStress64RsltMulCB, (void*)this);
}
-
// This variable is used to generate "traversal labels": one-time constants with which
// we label basic blocks that are members of the basic block list, in order to have a
// fast, high-probability test for membership in that list. Type is "volatile" because
@@ -19847,8 +19892,7 @@ static volatile int bbTraverseLabel = 1;
*
*****************************************************************************/
-void Compiler::fgDebugCheckBBlist(bool checkBBNum /* = false */,
- bool checkBBRefs /* = true */)
+void Compiler::fgDebugCheckBBlist(bool checkBBNum /* = false */, bool checkBBRefs /* = true */)
{
#ifdef DEBUG
if (verbose)
@@ -19858,7 +19902,7 @@ void Compiler::fgDebugCheckBBlist(bool checkBBNum /* = false */,
#endif // DEBUG
fgDebugCheckBlockLinks();
-
+
if (fgBBcount > 10000 && expensiveDebugCheckLevel < 1)
{
// The basic block checks are too expensive if there are too many blocks,
@@ -19875,7 +19919,7 @@ void Compiler::fgDebugCheckBBlist(bool checkBBNum /* = false */,
unsigned blockRefs;
#if FEATURE_EH_FUNCLETS
- bool reachedFirstFunclet = false;
+ bool reachedFirstFunclet = false;
if (fgFuncletsCreated)
{
//
@@ -19898,15 +19942,13 @@ void Compiler::fgDebugCheckBBlist(bool checkBBNum /* = false */,
block->bbTraversalStamp = curTraversalStamp;
}
- for (prevBlock = nullptr, block = fgFirstBB;
- block;
- prevBlock = block, block = block->bbNext)
+ for (prevBlock = nullptr, block = fgFirstBB; block; prevBlock = block, block = block->bbNext)
{
blockRefs = 0;
/* First basic block has countOfInEdges() >= 1 */
- if (block == fgFirstBB)
+ if (block == fgFirstBB)
{
noway_assert(block->countOfInEdges() >= 1);
blockRefs = 1;
@@ -19920,27 +19962,24 @@ void Compiler::fgDebugCheckBBlist(bool checkBBNum /* = false */,
// If the block is a BBJ_COND, a BBJ_SWITCH or a
// lowered GT_SWITCH_TABLE node then make sure it
- // ends with a GT_JTRUE or a GT_SWITCH
+ // ends with a conditional jump or a GT_SWITCH
if (block->bbJumpKind == BBJ_COND)
{
- noway_assert(block->lastNode()->gtNext == nullptr && block->lastNode()->gtOper == GT_JTRUE);
+ noway_assert(block->lastNode()->gtNext == nullptr && block->lastNode()->OperIsConditionalJump());
}
else if (block->bbJumpKind == BBJ_SWITCH)
{
#ifndef LEGACY_BACKEND
noway_assert(block->lastNode()->gtNext == nullptr &&
- (block->lastNode()->gtOper == GT_SWITCH ||
- block->lastNode()->gtOper == GT_SWITCH_TABLE));
-#else // LEGACY_BACKEND
- noway_assert(block->lastStmt()->gtNext == NULL &&
- block->lastStmt()->gtStmtExpr->gtOper == GT_SWITCH);
+ (block->lastNode()->gtOper == GT_SWITCH || block->lastNode()->gtOper == GT_SWITCH_TABLE));
+#else // LEGACY_BACKEND
+ noway_assert(block->lastStmt()->gtNext == NULL && block->lastStmt()->gtStmtExpr->gtOper == GT_SWITCH);
#endif // LEGACY_BACKEND
}
- else if (!( block->bbJumpKind == BBJ_ALWAYS
- || block->bbJumpKind == BBJ_RETURN))
+ else if (!(block->bbJumpKind == BBJ_ALWAYS || block->bbJumpKind == BBJ_RETURN))
{
- //this block cannot have a poll
+ // this block cannot have a poll
noway_assert(!(block->bbFlags & BBF_NEEDS_GCPOLL));
}
@@ -19981,7 +20020,8 @@ void Compiler::fgDebugCheckBBlist(bool checkBBNum /* = false */,
#endif // FEATURE_EH_FUNCLETS
// Don't check cheap preds.
- for (pred = (fgCheapPredsValid ? nullptr : block->bbPreds); pred != nullptr; blockRefs += pred->flDupCount, pred = pred->flNext)
+ for (pred = (fgCheapPredsValid ? nullptr : block->bbPreds); pred != nullptr;
+ blockRefs += pred->flDupCount, pred = pred->flNext)
{
assert(fgComputePredsDone); // If this isn't set, why do we have a preds list?
@@ -19994,95 +20034,101 @@ void Compiler::fgDebugCheckBBlist(bool checkBBNum /* = false */,
if (ehTryDsc != nullptr)
{
// You can jump to the start of a try
- if (ehTryDsc->ebdTryBeg == block) {
+ if (ehTryDsc->ebdTryBeg == block)
+ {
goto CHECK_HND;
-}
+ }
// You can jump within the same try region
- if (bbInTryRegions(block->getTryIndex(), blockPred)) {
+ if (bbInTryRegions(block->getTryIndex(), blockPred))
+ {
goto CHECK_HND;
-}
+ }
// The catch block can jump back into the middle of the try
- if (bbInCatchHandlerRegions(block, blockPred)) {
+ if (bbInCatchHandlerRegions(block, blockPred))
+ {
goto CHECK_HND;
-}
+ }
// The end of a finally region is a BBJ_EHFINALLYRET block (during importing, BBJ_LEAVE) which
// is marked as "returning" to the BBJ_ALWAYS block following the BBJ_CALLFINALLY
// block that does a local call to the finally. This BBJ_ALWAYS is within
// the try region protected by the finally (for x86, ARM), but that's ok.
- if (prevBlock->bbJumpKind == BBJ_CALLFINALLY &&
- block->bbJumpKind == BBJ_ALWAYS &&
- blockPred->bbJumpKind == BBJ_EHFINALLYRET) {
+ if (prevBlock->bbJumpKind == BBJ_CALLFINALLY && block->bbJumpKind == BBJ_ALWAYS &&
+ blockPred->bbJumpKind == BBJ_EHFINALLYRET)
+ {
goto CHECK_HND;
-}
+ }
- printf("Jump into the middle of try region: BB%02u branches to BB%02u\n", blockPred->bbNum, block->bbNum);
+ printf("Jump into the middle of try region: BB%02u branches to BB%02u\n", blockPred->bbNum,
+ block->bbNum);
noway_assert(!"Jump into middle of try region");
}
-CHECK_HND:;
+ CHECK_HND:;
EHblkDsc* ehHndDsc = ehGetBlockHndDsc(block);
if (ehHndDsc != nullptr)
{
// You can do a BBJ_EHFINALLYRET or BBJ_EHFILTERRET into a handler region
- if ( (blockPred->bbJumpKind == BBJ_EHFINALLYRET)
- || (blockPred->bbJumpKind == BBJ_EHFILTERRET)) {
+ if ((blockPred->bbJumpKind == BBJ_EHFINALLYRET) || (blockPred->bbJumpKind == BBJ_EHFILTERRET))
+ {
goto CHECK_JUMP;
-}
+ }
// Our try block can call our finally block
- if ((block->bbCatchTyp == BBCT_FINALLY) &&
- (blockPred->bbJumpKind == BBJ_CALLFINALLY) &&
+ if ((block->bbCatchTyp == BBCT_FINALLY) && (blockPred->bbJumpKind == BBJ_CALLFINALLY) &&
ehCallFinallyInCorrectRegion(blockPred, block->getHndIndex()))
{
goto CHECK_JUMP;
}
// You can jump within the same handler region
- if (bbInHandlerRegions(block->getHndIndex(), blockPred)) {
+ if (bbInHandlerRegions(block->getHndIndex(), blockPred))
+ {
goto CHECK_JUMP;
-}
+ }
// A filter can jump to the start of the filter handler
- if (ehHndDsc->HasFilter()) {
+ if (ehHndDsc->HasFilter())
+ {
goto CHECK_JUMP;
-}
+ }
- printf("Jump into the middle of handler region: BB%02u branches to BB%02u\n", blockPred->bbNum, block->bbNum);
+ printf("Jump into the middle of handler region: BB%02u branches to BB%02u\n", blockPred->bbNum,
+ block->bbNum);
noway_assert(!"Jump into the middle of handler region");
}
-CHECK_JUMP:;
+ CHECK_JUMP:;
switch (blockPred->bbJumpKind)
{
- case BBJ_COND:
- noway_assert(blockPred->bbNext == block || blockPred->bbJumpDest == block);
- break;
+ case BBJ_COND:
+ noway_assert(blockPred->bbNext == block || blockPred->bbJumpDest == block);
+ break;
- case BBJ_NONE:
- noway_assert(blockPred->bbNext == block);
- break;
+ case BBJ_NONE:
+ noway_assert(blockPred->bbNext == block);
+ break;
- case BBJ_CALLFINALLY:
- case BBJ_ALWAYS:
- case BBJ_EHCATCHRET:
- case BBJ_EHFILTERRET:
- noway_assert(blockPred->bbJumpDest == block);
- break;
+ case BBJ_CALLFINALLY:
+ case BBJ_ALWAYS:
+ case BBJ_EHCATCHRET:
+ case BBJ_EHFILTERRET:
+ noway_assert(blockPred->bbJumpDest == block);
+ break;
- case BBJ_EHFINALLYRET:
+ case BBJ_EHFINALLYRET:
{
// If the current block is a successor to a BBJ_EHFINALLYRET (return from finally),
// then the lexically previous block should be a call to the same finally.
// Verify all of that.
- unsigned hndIndex = blockPred->getHndIndex();
- EHblkDsc* ehDsc = ehGetDsc(hndIndex);
- BasicBlock* finBeg = ehDsc->ebdHndBeg;
+ unsigned hndIndex = blockPred->getHndIndex();
+ EHblkDsc* ehDsc = ehGetDsc(hndIndex);
+ BasicBlock* finBeg = ehDsc->ebdHndBeg;
// Because there is no bbPrev, we have to search for the lexically previous
// block. We can shorten the search by only looking in places where it is legal
@@ -20094,13 +20140,15 @@ CHECK_JUMP:;
for (BasicBlock* bcall = begBlk; bcall != endBlk; bcall = bcall->bbNext)
{
- if (bcall->bbJumpKind != BBJ_CALLFINALLY || bcall->bbJumpDest != finBeg) {
+ if (bcall->bbJumpKind != BBJ_CALLFINALLY || bcall->bbJumpDest != finBeg)
+ {
continue;
-}
+ }
- if (block == bcall->bbNext) {
+ if (block == bcall->bbNext)
+ {
goto PRED_OK;
- }
+ }
}
#if FEATURE_EH_FUNCLETS
@@ -20114,19 +20162,22 @@ CHECK_JUMP:;
for (BasicBlock* bcall = fgFirstFuncletBB; bcall; bcall = bcall->bbNext)
{
- if (bcall->bbJumpKind != BBJ_CALLFINALLY || bcall->bbJumpDest != finBeg) {
+ if (bcall->bbJumpKind != BBJ_CALLFINALLY || bcall->bbJumpDest != finBeg)
+ {
continue;
-}
+ }
- if (block != bcall->bbNext) {
+ if (block != bcall->bbNext)
+ {
continue;
-}
+ }
- if (ehCallFinallyInCorrectRegion(bcall, hndIndex)) {
+ if (ehCallFinallyInCorrectRegion(bcall, hndIndex))
+ {
goto PRED_OK;
+ }
}
}
- }
#endif // FEATURE_EH_FUNCLETS
@@ -20134,34 +20185,34 @@ CHECK_JUMP:;
}
break;
- case BBJ_THROW:
- case BBJ_RETURN:
- noway_assert(!"THROW and RETURN block cannot be in the predecessor list!");
- break;
+ case BBJ_THROW:
+ case BBJ_RETURN:
+ noway_assert(!"THROW and RETURN block cannot be in the predecessor list!");
+ break;
- case BBJ_SWITCH:
- unsigned jumpCnt; jumpCnt = blockPred->bbJumpSwt->bbsCount;
- BasicBlock** jumpTab; jumpTab = blockPred->bbJumpSwt->bbsDstTab;
+ case BBJ_SWITCH:
+ unsigned jumpCnt;
+ jumpCnt = blockPred->bbJumpSwt->bbsCount;
+ BasicBlock** jumpTab;
+ jumpTab = blockPred->bbJumpSwt->bbsDstTab;
- do
- {
- if (block == *jumpTab)
+ do
{
- goto PRED_OK;
- }
- }
- while (++jumpTab, --jumpCnt);
+ if (block == *jumpTab)
+ {
+ goto PRED_OK;
+ }
+ } while (++jumpTab, --jumpCnt);
- noway_assert(!"SWITCH in the predecessor list with no jump label to BLOCK!");
- break;
+ noway_assert(!"SWITCH in the predecessor list with no jump label to BLOCK!");
+ break;
- default:
- noway_assert(!"Unexpected bbJumpKind");
- break;
+ default:
+ noway_assert(!"Unexpected bbJumpKind");
+ break;
}
-PRED_OK:;
-
+ PRED_OK:;
}
/* Check the bbRefs */
@@ -20200,7 +20251,7 @@ PRED_OK:;
copiedForGenericsCtxt = ((info.compMethodInfo->options & CORINFO_GENERICS_CTXT_FROM_THIS) != 0);
#else // JIT32_GCENCODER
copiedForGenericsCtxt = FALSE;
-#endif // JIT32_GCENCODER
+#endif // JIT32_GCENCODER
// This if only in support of the noway_asserts it contains.
if (info.compIsStatic)
@@ -20213,16 +20264,18 @@ PRED_OK:;
// For instance method:
assert(info.compThisArg != BAD_VAR_NUM);
bool compThisArgAddrExposedOK = !lvaTable[info.compThisArg].lvAddrExposed;
+
#ifndef JIT32_GCENCODER
compThisArgAddrExposedOK = compThisArgAddrExposedOK || copiedForGenericsCtxt;
-#endif // !JIT32_GCENCODER
- noway_assert(compThisArgAddrExposedOK && // should never expose the address of arg 0 or
- !lvaTable[info.compThisArg].lvArgWrite && // write to arg 0.
- ( // In addition,
- lvaArg0Var == info.compThisArg || // lvArg0Var should remain 0 if arg0 is not written to or address-exposed.
- lvaArg0Var != info.compThisArg &&
- (lvaTable[lvaArg0Var].lvAddrExposed || lvaTable[lvaArg0Var].lvArgWrite || copiedForGenericsCtxt)
- ));
+#endif // !JIT32_GCENCODER
+
+ // 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)));
}
}
@@ -20232,40 +20285,40 @@ PRED_OK:;
*
****************************************************************************/
-void Compiler::fgDebugCheckFlags(GenTreePtr tree)
+void Compiler::fgDebugCheckFlags(GenTreePtr tree)
{
noway_assert(tree->gtOper != GT_STMT);
- genTreeOps oper = tree->OperGet();
- unsigned kind = tree->OperKind();
- unsigned treeFlags = tree->gtFlags & GTF_ALL_EFFECT;
- unsigned chkFlags = 0;
+ genTreeOps oper = tree->OperGet();
+ unsigned kind = tree->OperKind();
+ unsigned treeFlags = tree->gtFlags & GTF_ALL_EFFECT;
+ unsigned chkFlags = 0;
/* Is this a leaf node? */
- if (kind & GTK_LEAF)
+ if (kind & GTK_LEAF)
{
switch (oper)
{
- case GT_CLS_VAR:
- chkFlags |= GTF_GLOB_REF;
- break;
+ case GT_CLS_VAR:
+ chkFlags |= GTF_GLOB_REF;
+ break;
- case GT_CATCH_ARG:
- chkFlags |= GTF_ORDER_SIDEEFF;
- break;
+ case GT_CATCH_ARG:
+ chkFlags |= GTF_ORDER_SIDEEFF;
+ break;
- default:
- break;
+ default:
+ break;
}
}
/* Is it a 'simple' unary/binary operator? */
- else if (kind & GTK_SMPOP)
+ else if (kind & GTK_SMPOP)
{
- GenTreePtr op1 = tree->gtOp.gtOp1;
- GenTreePtr op2 = tree->gtGetOp2();
+ GenTreePtr op1 = tree->gtOp.gtOp1;
+ GenTreePtr op2 = tree->gtGetOp2();
// During GS work, we make shadow copies for params.
// In gsParamsToShadows(), we create a shadow var of TYP_INT for every small type param.
@@ -20275,48 +20328,88 @@ void Compiler::fgDebugCheckFlags(GenTreePtr tree)
// TYP_INT up to the GT_ASG tree is only correct if we don't need to propagate the TYP_INT back up.
// The following checks will ensure this.
- // Is the left child of "tree" a GT_ASG?,
+ // Is the left child of "tree" a GT_ASG?
+ //
+ // If parent is a TYP_VOID, we don't no need to propagate TYP_INT up. We are fine.
+ // (or) If GT_ASG is the left child of a GT_COMMA, the type of the GT_COMMA node will
+ // be determined by its right child. So we don't need to propagate TYP_INT up either. We are fine.
if (op1 && op1->gtOper == GT_ASG)
{
- assert(tree->gtType == TYP_VOID || // If parent is a TYP_VOID, we don't no need to propagate TYP_INT up. We are fine.
- tree->gtOper == GT_COMMA); // (or) If GT_ASG is the left child of a GT_COMMA, the type of the GT_COMMA node will
- } // be determined by its right child. So we don't need to propagate TYP_INT up either. We are fine.
+ assert(tree->gtType == TYP_VOID || tree->gtOper == GT_COMMA);
+ }
- // Is the right child of "tree" a GT_ASG?,
+ // Is the right child of "tree" a GT_ASG?
+ //
+ // If parent is a TYP_VOID, we don't no need to propagate TYP_INT up. We are fine.
if (op2 && op2->gtOper == GT_ASG)
{
- assert(tree->gtType == TYP_VOID); // If parent is a TYP_VOID, we don't no need to propagate TYP_INT up. We are fine.
+ assert(tree->gtType == TYP_VOID);
}
switch (oper)
{
- case GT_QMARK:
- if (op1->OperIsCompare())
- {
- noway_assert(op1->gtFlags & GTF_DONT_CSE);
- }
- else
- {
- noway_assert( (op1->gtOper == GT_CNS_INT) &&
- ((op1->gtIntCon.gtIconVal == 0) || (op1->gtIntCon.gtIconVal == 1)) );
- }
- break;
+ case GT_QMARK:
+ if (op1->OperIsCompare())
+ {
+ noway_assert(op1->gtFlags & GTF_DONT_CSE);
+ }
+ else
+ {
+ noway_assert((op1->gtOper == GT_CNS_INT) &&
+ ((op1->gtIntCon.gtIconVal == 0) || (op1->gtIntCon.gtIconVal == 1)));
+ }
+ break;
- default:
- break;
+ case GT_LIST:
+ case GT_FIELD_LIST:
+ if ((op2 != nullptr) && op2->OperIsAnyList())
+ {
+ ArrayStack<GenTree*> stack(this);
+ while ((tree->gtGetOp2() != nullptr) && tree->gtGetOp2()->OperIsAnyList())
+ {
+ stack.Push(tree);
+ tree = tree->gtGetOp2();
+ }
+
+ fgDebugCheckFlags(tree);
+
+ while (stack.Height() > 0)
+ {
+ tree = stack.Pop();
+ assert((tree->gtFlags & GTF_REVERSE_OPS) == 0);
+ fgDebugCheckFlags(tree->gtOp.gtOp1);
+ chkFlags |= (tree->gtOp.gtOp1->gtFlags & GTF_ALL_EFFECT);
+ chkFlags |= (tree->gtGetOp2()->gtFlags & GTF_ALL_EFFECT);
+ fgDebugCheckFlagsHelper(tree, (tree->gtFlags & GTF_ALL_EFFECT), chkFlags);
+ }
+
+ return;
+ }
+ break;
+
+ default:
+ break;
}
/* Recursively check the subtrees */
- if (op1) { fgDebugCheckFlags(op1);
-}
- if (op2) { fgDebugCheckFlags(op2);
-}
+ if (op1)
+ {
+ fgDebugCheckFlags(op1);
+ }
+ if (op2)
+ {
+ fgDebugCheckFlags(op2);
+ }
- if (op1) { chkFlags |= (op1->gtFlags & GTF_ALL_EFFECT);
-}
- if (op2) { chkFlags |= (op2->gtFlags & GTF_ALL_EFFECT);
-}
+ if (op1)
+ {
+ chkFlags |= (op1->gtFlags & GTF_ALL_EFFECT);
+ }
+ if (op2)
+ {
+ chkFlags |= (op2->gtFlags & GTF_ALL_EFFECT);
+ }
// We reuse the value of GTF_REVERSE_OPS for a GT_IND-specific flag,
// so exempt that (unary) operator.
@@ -20331,7 +20424,7 @@ void Compiler::fgDebugCheckFlags(GenTreePtr tree)
was set and thus GTF_ASG cannot be considered here. */
/* For a GT_ASG(GT_IND(x), y) we are interested in the side effects of x */
- GenTreePtr op1p;
+ GenTreePtr op1p;
if ((kind & GTK_ASGOP) && (op1->gtOper == GT_IND))
{
op1p = op1->gtOp.gtOp1;
@@ -20355,20 +20448,18 @@ void Compiler::fgDebugCheckFlags(GenTreePtr tree)
if (kind & GTK_ASGOP)
{
- chkFlags |= GTF_ASG;
+ chkFlags |= GTF_ASG;
}
/* Note that it is OK for treeFlags not to have a GTF_EXCEPT,
AssertionProp's non-Null may have cleared it */
if (tree->OperMayThrow())
{
- chkFlags |= (treeFlags & GTF_EXCEPT);
+ chkFlags |= (treeFlags & GTF_EXCEPT);
}
- if (oper == GT_ADDR &&
- (op1->OperIsLocal() ||
- op1->gtOper == GT_CLS_VAR ||
- (op1->gtOper == GT_IND && op1->gtOp.gtOp1->gtOper == GT_CLS_VAR_ADDR)))
+ if (oper == GT_ADDR && (op1->OperIsLocal() || op1->gtOper == GT_CLS_VAR ||
+ (op1->gtOper == GT_IND && op1->gtOp.gtOp1->gtOper == GT_CLS_VAR_ADDR)))
{
/* &aliasedVar doesn't need GTF_GLOB_REF, though alisasedVar does.
Similarly for clsVar */
@@ -20378,131 +20469,149 @@ void Compiler::fgDebugCheckFlags(GenTreePtr tree)
/* See what kind of a special operator we have here */
- else { switch (tree->OperGet())
+ else
{
- case GT_CALL:
+ switch (tree->OperGet())
+ {
+ case GT_CALL:
- GenTreePtr args;
- GenTreePtr argx;
- GenTreeCall* call;
-
- call = tree->AsCall();
+ GenTreePtr args;
+ GenTreePtr argx;
+ GenTreeCall* call;
- chkFlags |= GTF_CALL;
+ call = tree->AsCall();
- if ((treeFlags & GTF_EXCEPT) && !(chkFlags & GTF_EXCEPT))
- {
- switch (eeGetHelperNum(tree->gtCall.gtCallMethHnd))
- {
- // Is this a helper call that can throw an exception ?
- case CORINFO_HELP_LDIV:
- case CORINFO_HELP_LMOD:
- case CORINFO_HELP_METHOD_ACCESS_CHECK:
- case CORINFO_HELP_FIELD_ACCESS_CHECK:
- case CORINFO_HELP_CLASS_ACCESS_CHECK:
- case CORINFO_HELP_DELEGATE_SECURITY_CHECK:
- chkFlags |= GTF_EXCEPT;
- break;
- default:
- break;
- }
- }
+ chkFlags |= GTF_CALL;
- if (call->gtCallObjp)
- {
- fgDebugCheckFlags(call->gtCallObjp);
- chkFlags |= (call->gtCallObjp->gtFlags & GTF_SIDE_EFFECT);
+ if ((treeFlags & GTF_EXCEPT) && !(chkFlags & GTF_EXCEPT))
+ {
+ switch (eeGetHelperNum(tree->gtCall.gtCallMethHnd))
+ {
+ // Is this a helper call that can throw an exception ?
+ case CORINFO_HELP_LDIV:
+ case CORINFO_HELP_LMOD:
+ case CORINFO_HELP_METHOD_ACCESS_CHECK:
+ case CORINFO_HELP_FIELD_ACCESS_CHECK:
+ case CORINFO_HELP_CLASS_ACCESS_CHECK:
+ case CORINFO_HELP_DELEGATE_SECURITY_CHECK:
+ chkFlags |= GTF_EXCEPT;
+ break;
+ default:
+ break;
+ }
+ }
- if (call->gtCallObjp->gtFlags & GTF_ASG)
- {
- treeFlags |= GTF_ASG;
- }
- }
+ if (call->gtCallObjp)
+ {
+ fgDebugCheckFlags(call->gtCallObjp);
+ chkFlags |= (call->gtCallObjp->gtFlags & GTF_SIDE_EFFECT);
- for (args = call->gtCallArgs; args; args = args->gtOp.gtOp2)
- {
- argx = args->gtOp.gtOp1;
- fgDebugCheckFlags(argx);
+ if (call->gtCallObjp->gtFlags & GTF_ASG)
+ {
+ treeFlags |= GTF_ASG;
+ }
+ }
- chkFlags |= (argx->gtFlags & GTF_SIDE_EFFECT);
+ for (args = call->gtCallArgs; args; args = args->gtOp.gtOp2)
+ {
+ argx = args->gtOp.gtOp1;
+ fgDebugCheckFlags(argx);
- if (argx->gtFlags & GTF_ASG)
- {
- treeFlags |= GTF_ASG;
- }
- }
+ chkFlags |= (argx->gtFlags & GTF_SIDE_EFFECT);
- for (args = call->gtCallLateArgs; args; args = args->gtOp.gtOp2)
- {
- argx = args->gtOp.gtOp1;
- fgDebugCheckFlags(argx);
+ if (argx->gtFlags & GTF_ASG)
+ {
+ treeFlags |= GTF_ASG;
+ }
+ }
- chkFlags |= (argx->gtFlags & GTF_SIDE_EFFECT);
+ for (args = call->gtCallLateArgs; args; args = args->gtOp.gtOp2)
+ {
+ argx = args->gtOp.gtOp1;
+ fgDebugCheckFlags(argx);
- if (argx->gtFlags & GTF_ASG)
- {
- treeFlags |= GTF_ASG;
- }
- }
+ chkFlags |= (argx->gtFlags & GTF_SIDE_EFFECT);
- if ((call->gtCallType == CT_INDIRECT) && (call->gtCallCookie != nullptr))
- {
- fgDebugCheckFlags(call->gtCallCookie);
- chkFlags |= (call->gtCallCookie->gtFlags & GTF_SIDE_EFFECT);
- }
+ if (argx->gtFlags & GTF_ASG)
+ {
+ treeFlags |= GTF_ASG;
+ }
+ }
- if (call->gtCallType == CT_INDIRECT)
- {
- fgDebugCheckFlags(call->gtCallAddr);
- chkFlags |= (call->gtCallAddr->gtFlags & GTF_SIDE_EFFECT);
- }
+ if ((call->gtCallType == CT_INDIRECT) && (call->gtCallCookie != nullptr))
+ {
+ fgDebugCheckFlags(call->gtCallCookie);
+ chkFlags |= (call->gtCallCookie->gtFlags & GTF_SIDE_EFFECT);
+ }
- if (call->IsUnmanaged() &&
- (call->gtCallMoreFlags & GTF_CALL_M_UNMGD_THISCALL))
- {
- if (call->gtCallArgs->gtOp.gtOp1->OperGet() == GT_NOP)
- {
- noway_assert(call->gtCallLateArgs->gtOp.gtOp1->TypeGet() == TYP_I_IMPL ||
- call->gtCallLateArgs->gtOp.gtOp1->TypeGet() == TYP_BYREF);
- }
- else
- {
- noway_assert(call->gtCallArgs->gtOp.gtOp1->TypeGet() == TYP_I_IMPL ||
- call->gtCallArgs->gtOp.gtOp1->TypeGet() == TYP_BYREF);
- }
- }
- break;
+ if (call->gtCallType == CT_INDIRECT)
+ {
+ fgDebugCheckFlags(call->gtCallAddr);
+ chkFlags |= (call->gtCallAddr->gtFlags & GTF_SIDE_EFFECT);
+ }
- case GT_ARR_ELEM:
+ if (call->IsUnmanaged() && (call->gtCallMoreFlags & GTF_CALL_M_UNMGD_THISCALL))
+ {
+ if (call->gtCallArgs->gtOp.gtOp1->OperGet() == GT_NOP)
+ {
+ noway_assert(call->gtCallLateArgs->gtOp.gtOp1->TypeGet() == TYP_I_IMPL ||
+ call->gtCallLateArgs->gtOp.gtOp1->TypeGet() == TYP_BYREF);
+ }
+ else
+ {
+ noway_assert(call->gtCallArgs->gtOp.gtOp1->TypeGet() == TYP_I_IMPL ||
+ call->gtCallArgs->gtOp.gtOp1->TypeGet() == TYP_BYREF);
+ }
+ }
+ break;
- GenTreePtr arrObj;
- unsigned dim;
+ case GT_ARR_ELEM:
- arrObj = tree->gtArrElem.gtArrObj;
- fgDebugCheckFlags(arrObj);
- chkFlags |= (arrObj->gtFlags & GTF_ALL_EFFECT);
+ GenTreePtr arrObj;
+ unsigned dim;
- for (dim = 0; dim < tree->gtArrElem.gtArrRank; dim++)
- {
- fgDebugCheckFlags(tree->gtArrElem.gtArrInds[dim]);
- chkFlags |= tree->gtArrElem.gtArrInds[dim]->gtFlags & GTF_ALL_EFFECT;
- }
- break;
+ arrObj = tree->gtArrElem.gtArrObj;
+ fgDebugCheckFlags(arrObj);
+ chkFlags |= (arrObj->gtFlags & GTF_ALL_EFFECT);
- case GT_ARR_OFFSET:
- fgDebugCheckFlags(tree->gtArrOffs.gtOffset);
- chkFlags |= (tree->gtArrOffs.gtOffset->gtFlags & GTF_ALL_EFFECT);
- fgDebugCheckFlags(tree->gtArrOffs.gtIndex);
- chkFlags |= (tree->gtArrOffs.gtIndex->gtFlags & GTF_ALL_EFFECT);
- fgDebugCheckFlags(tree->gtArrOffs.gtArrObj);
- chkFlags |= (tree->gtArrOffs.gtArrObj->gtFlags & GTF_ALL_EFFECT);
- break;
+ for (dim = 0; dim < tree->gtArrElem.gtArrRank; dim++)
+ {
+ fgDebugCheckFlags(tree->gtArrElem.gtArrInds[dim]);
+ chkFlags |= tree->gtArrElem.gtArrInds[dim]->gtFlags & GTF_ALL_EFFECT;
+ }
+ break;
- default:
- break;
+ case GT_ARR_OFFSET:
+ fgDebugCheckFlags(tree->gtArrOffs.gtOffset);
+ chkFlags |= (tree->gtArrOffs.gtOffset->gtFlags & GTF_ALL_EFFECT);
+ fgDebugCheckFlags(tree->gtArrOffs.gtIndex);
+ chkFlags |= (tree->gtArrOffs.gtIndex->gtFlags & GTF_ALL_EFFECT);
+ fgDebugCheckFlags(tree->gtArrOffs.gtArrObj);
+ chkFlags |= (tree->gtArrOffs.gtArrObj->gtFlags & GTF_ALL_EFFECT);
+ break;
+
+ default:
+ break;
+ }
}
+
+ fgDebugCheckFlagsHelper(tree, treeFlags, chkFlags);
}
+//------------------------------------------------------------------------------
+// fgDebugCheckFlagsHelper : Check if all bits that are set in chkFlags are also set in treeFlags.
+//
+//
+// Arguments:
+// tree - Tree whose flags are being checked
+// treeFlags - Actual flags on the tree
+// chkFlags - Expected flags
+//
+// Note:
+// Checking that all bits that are set in treeFlags are also set in chkFlags is currently disabled.
+
+void Compiler::fgDebugCheckFlagsHelper(GenTreePtr tree, unsigned treeFlags, unsigned chkFlags)
+{
if (chkFlags & ~treeFlags)
{
// Print the tree so we can see it in the log.
@@ -20524,12 +20633,12 @@ void Compiler::fgDebugCheckFlags(GenTreePtr tree)
#if 0
// TODO-Cleanup:
/* The tree has extra flags set. However, this will happen if we
- replace a subtree with something, but don't clear the flags up
- the tree. Can't flag this unless we start clearing flags above.
+ replace a subtree with something, but don't clear the flags up
+ the tree. Can't flag this unless we start clearing flags above.
- Note: we need this working for GTF_CALL and CSEs, so I'm enabling
- it for calls.
- */
+ Note: we need this working for GTF_CALL and CSEs, so I'm enabling
+ it for calls.
+ */
if (tree->OperGet() != GT_CALL && (treeFlags & GTF_CALL) && !(chkFlags & GTF_CALL))
{
// Print the tree so we can see it in the log.
@@ -20545,7 +20654,7 @@ void Compiler::fgDebugCheckFlags(GenTreePtr tree)
GenTree::gtDispFlags(treeFlags & ~chkFlags, GTF_DEBUG_NONE);
printf("\n");
gtDispTree(tree);
- }
+ }
#endif // 0
}
}
@@ -20569,14 +20678,13 @@ void Compiler::fgDebugCheckNodeLinks(BasicBlock* block, GenTree* node)
noway_assert(stmt->gtStmtList);
// The first node's gtPrev must be nullptr (the gtPrev list is not circular).
- // The last node's gtNext must be nullptr (the gtNext list is not circular). This is tested if the loop below terminates.
+ // The last node's gtNext must be nullptr (the gtNext list is not circular). This is tested if the loop below
+ // terminates.
assert(stmt->gtStmtList->gtPrev == nullptr);
- for (GenTreePtr tree = stmt->gtStmtList;
- tree != nullptr;
- tree = tree->gtNext)
+ for (GenTreePtr tree = stmt->gtStmtList; tree != nullptr; tree = tree->gtNext)
{
- if (tree->gtPrev)
+ if (tree->gtPrev)
{
noway_assert(tree->gtPrev->gtNext == tree);
}
@@ -20585,7 +20693,7 @@ void Compiler::fgDebugCheckNodeLinks(BasicBlock* block, GenTree* node)
noway_assert(tree == stmt->gtStmtList);
}
- if (tree->gtNext)
+ if (tree->gtNext)
{
noway_assert(tree->gtNext->gtPrev == tree);
}
@@ -20621,40 +20729,40 @@ void Compiler::fgDebugCheckNodeLinks(BasicBlock* block, GenTree* node)
{
switch (tree->gtOper)
{
- case GT_QMARK:
- expectedPrevTree = tree->gtOp.gtOp2->AsColon()->ThenNode(); // "then" operand of the GT_COLON (generated second).
- break;
+ case GT_QMARK:
+ expectedPrevTree =
+ tree->gtOp.gtOp2->AsColon()->ThenNode(); // "then" operand of the GT_COLON (generated second).
+ break;
- case GT_COLON:
- expectedPrevTree = tree->AsColon()->ElseNode(); // "else" branch result (generated first).
- break;
+ case GT_COLON:
+ expectedPrevTree = tree->AsColon()->ElseNode(); // "else" branch result (generated first).
+ break;
- default:
- if (tree->gtOp.gtOp2)
- {
- if (tree->gtFlags & GTF_REVERSE_OPS)
+ default:
+ if (tree->gtOp.gtOp2)
{
- expectedPrevTree = tree->gtOp.gtOp1;
+ if (tree->gtFlags & GTF_REVERSE_OPS)
+ {
+ expectedPrevTree = tree->gtOp.gtOp1;
+ }
+ else
+ {
+ expectedPrevTree = tree->gtOp.gtOp2;
+ }
}
else
{
- expectedPrevTree = tree->gtOp.gtOp2;
+ expectedPrevTree = tree->gtOp.gtOp1;
}
- }
- else
- {
- expectedPrevTree = tree->gtOp.gtOp1;
- }
- break;
+ break;
}
}
- noway_assert(expectedPrevTree == nullptr || // No expectations about the prev node
- tree->gtPrev == expectedPrevTree); // The "normal" case
+ noway_assert(expectedPrevTree == nullptr || // No expectations about the prev node
+ tree->gtPrev == expectedPrevTree); // The "normal" case
}
}
-
/*****************************************************************************
*
* A DEBUG routine to check the correctness of the links between GT_STMT nodes
@@ -20662,15 +20770,14 @@ void Compiler::fgDebugCheckNodeLinks(BasicBlock* block, GenTree* node)
*
****************************************************************************/
-void Compiler::fgDebugCheckLinks(bool morphTrees)
+void Compiler::fgDebugCheckLinks(bool morphTrees)
{
// This used to be only on for stress, and there was a comment stating that
// it was "quite an expensive operation" but I did not find that to be true.
// Set DO_SANITY_DEBUG_CHECKS to false to revert to that behavior.
const bool DO_SANITY_DEBUG_CHECKS = true;
- if (!DO_SANITY_DEBUG_CHECKS &&
- !compStressCompile(STRESS_CHK_FLOW_UPDATE, 30))
+ if (!DO_SANITY_DEBUG_CHECKS && !compStressCompile(STRESS_CHK_FLOW_UPDATE, 30))
{
return;
}
@@ -20680,7 +20787,7 @@ void Compiler::fgDebugCheckLinks(bool morphTrees)
/* For each basic block check the bbTreeList links */
for (BasicBlock* block = fgFirstBB; block; block = block->bbNext)
{
-PROCESS_BLOCK_AGAIN:;
+ PROCESS_BLOCK_AGAIN:;
if (block->IsLIR())
{
LIR::AsRange(block).CheckLIR(this);
@@ -20690,11 +20797,12 @@ PROCESS_BLOCK_AGAIN:;
for (GenTreeStmt* stmt = block->firstStmt(); stmt; stmt = stmt->gtNextStmt)
{
/* Verify that bbTreeList is threaded correctly */
- /* Note that for the GT_STMT list, the gtPrev list is circular. The gtNext list is not: gtNext of the last GT_STMT in a block is nullptr. */
+ /* Note that for the GT_STMT list, the gtPrev list is circular. The gtNext list is not: gtNext of the
+ * last GT_STMT in a block is nullptr. */
noway_assert(stmt->gtPrev);
- if (stmt == block->bbTreeList)
+ if (stmt == block->bbTreeList)
{
noway_assert(stmt->gtPrev->gtNext == nullptr);
}
@@ -20703,7 +20811,7 @@ PROCESS_BLOCK_AGAIN:;
noway_assert(stmt->gtPrev->gtNext == stmt);
}
- if (stmt->gtNext)
+ if (stmt->gtNext)
{
noway_assert(stmt->gtNext->gtPrev == stmt);
}
@@ -20782,9 +20890,9 @@ void Compiler::fgDebugCheckBlockLinks()
// Create a set with all the successors. Don't use BlockSet, so we don't need to worry
// about the BlockSet epoch.
BitVecTraits bitVecTraits(fgBBNumMax + 1, this);
- BitVec BITVEC_INIT_NOCOPY(succBlocks, BitVecOps::MakeEmpty(&bitVecTraits));
+ BitVec BITVEC_INIT_NOCOPY(succBlocks, BitVecOps::MakeEmpty(&bitVecTraits));
BasicBlock** jumpTable = block->bbJumpSwt->bbsDstTab;
- unsigned jumpCount = block->bbJumpSwt->bbsCount;
+ unsigned jumpCount = block->bbJumpSwt->bbsCount;
for (unsigned i = 0; i < jumpCount; i++)
{
BitVecOps::AddElemD(&bitVecTraits, succBlocks, jumpTable[i]->bbNum);
@@ -20822,10 +20930,10 @@ void Compiler::fgDebugCheckBlockLinks()
// Likewise the depth limit is a policy consideration, and serves mostly
// as a safeguard to prevent runaway inlining of small methods.
-unsigned Compiler::fgCheckInlineDepthAndRecursion(InlineInfo* inlineInfo)
+unsigned Compiler::fgCheckInlineDepthAndRecursion(InlineInfo* inlineInfo)
{
BYTE* candidateCode = inlineInfo->inlineCandidateInfo->methInfo.ILCode;
- InlineContext* inlineContext = inlineInfo->iciStmt->gtStmt.gtInlineContext;
+ InlineContext* inlineContext = inlineInfo->iciStmt->gtInlineContext;
InlineResult* inlineResult = inlineInfo->inlineResult;
// There should be a context for all candidates.
@@ -20860,17 +20968,18 @@ unsigned Compiler::fgCheckInlineDepthAndRecursion(InlineInfo* inlineInfo)
* Inlining phase
*/
-
-void Compiler::fgInline()
+void Compiler::fgInline()
{
- if (!opts.OptEnabled(CLFLG_INLINING)) {
+ if (!opts.OptEnabled(CLFLG_INLINING))
+ {
return;
-}
+ }
#ifdef DEBUG
- if (verbose) {
+ if (verbose)
+ {
printf("*************** In fgInline()\n");
-}
+ }
#endif // DEBUG
BasicBlock* block = fgFirstBB;
@@ -20881,9 +20990,7 @@ void Compiler::fgInline()
for (; block != nullptr; block = block->bbNext)
{
- for (GenTreeStmt* stmt = block->firstStmt();
- stmt;
- stmt = stmt->gtNextStmt)
+ for (GenTreeStmt* stmt = block->firstStmt(); stmt; stmt = stmt->gtNextStmt)
{
stmt->gtInlineContext = rootContext;
}
@@ -20901,9 +21008,7 @@ void Compiler::fgInline()
GenTreeStmt* stmt;
GenTreePtr expr;
- for (stmt = block->firstStmt();
- stmt != nullptr;
- stmt = stmt->gtNextStmt)
+ for (stmt = block->firstStmt(); stmt != nullptr; stmt = stmt->gtNextStmt)
{
expr = stmt->gtStmtExpr;
@@ -20932,14 +21037,11 @@ void Compiler::fgInline()
}
// See if we need to replace the return value place holder.
- fgWalkTreePre(&stmt->gtStmtExpr,
- fgUpdateInlineReturnExpressionPlaceHolder,
- (void *) this);
+ fgWalkTreePre(&stmt->gtStmtExpr, fgUpdateInlineReturnExpressionPlaceHolder, (void*)this);
// See if stmt is of the form GT_COMMA(call, nop)
- // If yes, we can get rid of GT_COMMA.
- if (expr->OperGet() == GT_COMMA &&
- expr->gtOp.gtOp1->OperGet() == GT_CALL &&
+ // If yes, we can get rid of GT_COMMA.
+ if (expr->OperGet() == GT_COMMA && expr->gtOp.gtOp1->OperGet() == GT_CALL &&
expr->gtOp.gtOp2->OperGet() == GT_NOP)
{
stmt->gtStmtExpr = expr->gtOp.gtOp1;
@@ -20961,9 +21063,7 @@ void Compiler::fgInline()
{
GenTreeStmt* stmt;
- for (stmt = block->firstStmt();
- stmt;
- stmt = stmt->gtNextStmt)
+ for (stmt = block->firstStmt(); stmt; stmt = stmt->gtNextStmt)
{
// Call Compiler::fgDebugCheckInlineCandidates on each node
fgWalkTreePre(&stmt->gtStmtExpr, fgDebugCheckInlineCandidates);
@@ -20975,17 +21075,17 @@ void Compiler::fgInline()
fgVerifyHandlerTab();
- if (verbose)
+ if (verbose)
{
printf("*************** After fgInline()\n");
fgDispBasicBlocks(true);
fgDispHandlerTab();
}
- if (verbose || fgPrintInlinedMethods)
+ if (verbose || fgPrintInlinedMethods)
{
- printf("**************** Inline Tree\n");
- m_inlineStrategy->Dump();
+ printf("**************** Inline Tree\n");
+ m_inlineStrategy->Dump();
}
#endif // DEBUG
@@ -21007,14 +21107,13 @@ void Compiler::fgInline()
// Note:
// Invokes fgNoteNonInlineCandidate on the nodes it finds.
-Compiler::fgWalkResult Compiler::fgFindNonInlineCandidate(GenTreePtr* pTree,
- fgWalkData* data)
+Compiler::fgWalkResult Compiler::fgFindNonInlineCandidate(GenTreePtr* pTree, fgWalkData* data)
{
GenTreePtr tree = *pTree;
if (tree->gtOper == GT_CALL)
{
Compiler* compiler = data->compiler;
- GenTreePtr stmt = (GenTreePtr) data->pCallbackData;
+ GenTreeStmt* stmt = (GenTreeStmt*)data->pCallbackData;
GenTreeCall* call = tree->AsCall();
compiler->fgNoteNonInlineCandidate(stmt, call);
@@ -21027,17 +21126,16 @@ Compiler::fgWalkResult Compiler::fgFindNonInlineCandidate(GenTreePtr* pTree
// not marked as inline candidates.
//
// Arguments:
-// tree - statement containing the call
+// stmt - statement containing the call
// call - the call itself
//
// Notes:
// Used in debug only to try and place descriptions of inline failures
// into the proper context in the inline tree.
-void Compiler::fgNoteNonInlineCandidate(GenTreePtr tree,
- GenTreeCall* call)
+void Compiler::fgNoteNonInlineCandidate(GenTreeStmt* stmt, GenTreeCall* call)
{
- InlineResult inlineResult(this, call, nullptr, "fgNotInlineCandidate");
+ InlineResult inlineResult(this, call, nullptr, "fgNotInlineCandidate");
InlineObservation currentObservation = InlineObservation::CALLSITE_NOT_CANDIDATE;
// Try and recover the reason left behind when the jit decided
@@ -21070,7 +21168,7 @@ void Compiler::fgNoteNonInlineCandidate(GenTreePtr tree,
if (call->gtCallType == CT_USER_FUNC)
{
// Create InlineContext for the failure
- m_inlineStrategy->NewFailure(tree, &inlineResult);
+ m_inlineStrategy->NewFailure(stmt, &inlineResult);
}
}
@@ -21088,12 +21186,8 @@ void Compiler::fgNoteNonInlineCandidate(GenTreePtr tree,
*/
GenTreePtr Compiler::fgGetStructAsStructPtr(GenTreePtr tree)
{
- noway_assert((tree->gtOper == GT_LCL_VAR) ||
- (tree->gtOper == GT_FIELD) ||
- (tree->gtOper == GT_IND) ||
- (tree->gtOper == GT_BLK) ||
- (tree->gtOper == GT_OBJ) ||
- tree->OperIsSIMD() ||
+ noway_assert((tree->gtOper == GT_LCL_VAR) || (tree->gtOper == GT_FIELD) || (tree->gtOper == GT_IND) ||
+ (tree->gtOper == GT_BLK) || (tree->gtOper == GT_OBJ) || tree->OperIsSIMD() ||
// tree->gtOper == GT_CALL || cannot get address of call.
// tree->gtOper == GT_MKREFANY || inlining should've been aborted due to mkrefany opcode.
// tree->gtOper == GT_RET_EXPR || cannot happen after fgUpdateInlineReturnExpressionPlaceHolder
@@ -21101,18 +21195,18 @@ GenTreePtr Compiler::fgGetStructAsStructPtr(GenTreePtr tree)
switch (tree->OperGet())
{
- case GT_BLK:
- case GT_OBJ:
- case GT_IND:
- return tree->gtOp.gtOp1;
+ case GT_BLK:
+ case GT_OBJ:
+ case GT_IND:
+ return tree->gtOp.gtOp1;
- case GT_COMMA:
- tree->gtOp.gtOp2 = fgGetStructAsStructPtr(tree->gtOp.gtOp2);
- tree->gtType = TYP_BYREF;
- return tree;
+ case GT_COMMA:
+ tree->gtOp.gtOp2 = fgGetStructAsStructPtr(tree->gtOp.gtOp2);
+ tree->gtType = TYP_BYREF;
+ return tree;
- default:
- return gtNewOperNode(GT_ADDR, TYP_BYREF, tree);
+ default:
+ return gtNewOperNode(GT_ADDR, TYP_BYREF, tree);
}
}
@@ -21137,15 +21231,15 @@ GenTreePtr Compiler::fgAssignStructInlineeToVar(GenTreePtr child, CORINFO_CLASS_
// we have a ", , , call()" -- this is very defensive as we may never get
// an inlinee that is made of commas. If the inlinee is not a call, then
// we use a copy block to do the assignment.
- GenTreePtr src = child;
- GenTreePtr lastComma = NULL;
+ GenTreePtr src = child;
+ GenTreePtr lastComma = nullptr;
while (src->gtOper == GT_COMMA)
{
lastComma = src;
- src = src->gtOp.gtOp2;
+ src = src->gtOp.gtOp2;
}
- GenTreePtr newInlinee = NULL;
+ GenTreePtr newInlinee = nullptr;
if (src->gtOper == GT_CALL)
{
// If inlinee was just a call, new inlinee is v05 = call()
@@ -21162,16 +21256,16 @@ GenTreePtr Compiler::fgAssignStructInlineeToVar(GenTreePtr child, CORINFO_CLASS_
if (child->gtOper == GT_COMMA)
{
lastComma->gtOp.gtOp2 = newInlinee;
- newInlinee = child;
+ newInlinee = child;
}
}
else
{
// Inlinee is not a call, so just create a copy block to the tmp.
- src = child;
+ src = child;
GenTreePtr dstAddr = fgGetStructAsStructPtr(dst);
GenTreePtr srcAddr = fgGetStructAsStructPtr(src);
- newInlinee = gtNewCpObjNode(dstAddr, srcAddr, retClsHnd, false);
+ newInlinee = gtNewCpObjNode(dstAddr, srcAddr, retClsHnd, false);
}
GenTreePtr production = gtNewLclvNode(tmpNum, structType);
@@ -21197,15 +21291,17 @@ void Compiler::fgAttachStructInlineeToAsg(GenTreePtr tree, GenTreePtr child, COR
assert(tree->gtOper == GT_ASG);
// We have an assignment, we codegen only V05 = call().
- if (child->gtOper == GT_CALL && tree->gtOp.gtOp1->gtOper == GT_LCL_VAR)
+ // However, if it is a multireg return on x64/ux we want to assign it to a temp.
+ if (child->gtOper == GT_CALL && tree->gtOp.gtOp1->gtOper == GT_LCL_VAR && !child->AsCall()->HasMultiRegRetVal())
{
return;
}
GenTreePtr dstAddr = fgGetStructAsStructPtr(tree->gtOp.gtOp1);
- GenTreePtr srcAddr = fgGetStructAsStructPtr((child->gtOper == GT_CALL)
- ? fgAssignStructInlineeToVar(child, retClsHnd) // Assign to a variable if it is a call.
- : child); // Just get the address, if not a call.
+ GenTreePtr srcAddr = fgGetStructAsStructPtr(
+ (child->gtOper == GT_CALL)
+ ? fgAssignStructInlineeToVar(child, retClsHnd) // Assign to a variable if it is a call.
+ : child); // Just get the address, if not a call.
tree->CopyFrom(gtNewCpObjNode(dstAddr, srcAddr, retClsHnd, false), this);
}
@@ -21217,16 +21313,15 @@ void Compiler::fgAttachStructInlineeToAsg(GenTreePtr tree, GenTreePtr child, COR
*/
/* static */
-Compiler::fgWalkResult Compiler::fgUpdateInlineReturnExpressionPlaceHolder(GenTreePtr* pTree,
- fgWalkData* data)
+Compiler::fgWalkResult Compiler::fgUpdateInlineReturnExpressionPlaceHolder(GenTreePtr* pTree, fgWalkData* data)
{
- GenTreePtr tree = *pTree;
- Compiler* comp = data->compiler;
+ GenTreePtr tree = *pTree;
+ Compiler* comp = data->compiler;
CORINFO_CLASS_HANDLE retClsHnd = NO_CLASS_HANDLE;
if (tree->gtOper == GT_RET_EXPR)
{
- // We are going to copy the tree from the inlinee,
+ // We are going to copy the tree from the inlinee,
// so record the handle now.
//
if (varTypeIsStruct(tree))
@@ -21242,7 +21337,7 @@ Compiler::fgWalkResult Compiler::fgUpdateInlineReturnExpressionPlaceHolder(
#ifdef DEBUG
if (comp->verbose)
{
- printf("\nReplacing the return expression placeholder ");
+ printf("\nReplacing the return expression placeholder ");
printTreeID(tree);
printf(" with ");
printTreeID(inlineCandidate);
@@ -21252,7 +21347,7 @@ Compiler::fgWalkResult Compiler::fgUpdateInlineReturnExpressionPlaceHolder(
}
#endif // DEBUG
- tree->CopyFrom(inlineCandidate, comp);
+ tree->CopyFrom(inlineCandidate, comp);
#ifdef DEBUG
if (comp->verbose)
@@ -21262,8 +21357,7 @@ Compiler::fgWalkResult Compiler::fgUpdateInlineReturnExpressionPlaceHolder(
printf("\n");
}
#endif // DEBUG
- }
- while (tree->gtOper == GT_RET_EXPR);
+ } while (tree->gtOper == GT_RET_EXPR);
}
#if FEATURE_MULTIREG_RET
@@ -21305,15 +21399,12 @@ Compiler::fgWalkResult Compiler::fgUpdateInlineReturnExpressionPlaceHolder(
if ((tree->gtOper == GT_ASG) && (tree->gtOp.gtOp2->gtOper == GT_COMMA))
{
GenTreePtr comma;
- for (comma = tree->gtOp.gtOp2;
- comma->gtOper == GT_COMMA;
- comma = comma->gtOp.gtOp2)
+ for (comma = tree->gtOp.gtOp2; comma->gtOper == GT_COMMA; comma = comma->gtOp.gtOp2)
{
// empty
}
- noway_assert(!varTypeIsStruct(comma) ||
- comma->gtOper != GT_RET_EXPR ||
+ noway_assert(!varTypeIsStruct(comma) || comma->gtOper != GT_RET_EXPR ||
!comp->IsMultiRegReturnedType(comma->gtRetExpr.gtRetClsHnd));
}
@@ -21330,8 +21421,7 @@ Compiler::fgWalkResult Compiler::fgUpdateInlineReturnExpressionPlaceHolder(
*/
/* static */
-Compiler::fgWalkResult Compiler::fgDebugCheckInlineCandidates(GenTreePtr* pTree,
- fgWalkData* data)
+Compiler::fgWalkResult Compiler::fgDebugCheckInlineCandidates(GenTreePtr* pTree, fgWalkData* data)
{
GenTreePtr tree = *pTree;
if (tree->gtOper == GT_CALL)
@@ -21348,9 +21438,7 @@ Compiler::fgWalkResult Compiler::fgDebugCheckInlineCandidates(GenTreePtr* p
#endif // DEBUG
-
-void Compiler::fgInvokeInlineeCompiler(GenTreeCall* call,
- InlineResult* inlineResult)
+void Compiler::fgInvokeInlineeCompiler(GenTreeCall* call, InlineResult* inlineResult)
{
noway_assert(call->gtOper == GT_CALL);
noway_assert((call->gtFlags & GTF_CALL_INLINE_CANDIDATE) != 0);
@@ -21393,92 +21481,95 @@ void Compiler::fgInvokeInlineeCompiler(GenTreeCall* call,
// Set the trap to catch all errors (including recoverable ones from the EE)
struct Param
{
- Compiler* pThis;
- GenTree* call;
+ Compiler* pThis;
+ GenTree* call;
CORINFO_METHOD_HANDLE fncHandle;
- InlineCandidateInfo* inlineCandidateInfo;
- InlineInfo* inlineInfo;
+ InlineCandidateInfo* inlineCandidateInfo;
+ InlineInfo* inlineInfo;
} param = {nullptr};
- param.pThis = this;
- param.call = call;
- param.fncHandle = fncHandle;
+ param.pThis = this;
+ param.call = call;
+ param.fncHandle = fncHandle;
param.inlineCandidateInfo = inlineCandidateInfo;
- param.inlineInfo = &inlineInfo;
- bool success = eeRunWithErrorTrap<Param>([](Param* pParam)
- {
- // Init the local var info of the inlinee
- pParam->pThis->impInlineInitVars(pParam->inlineInfo);
+ param.inlineInfo = &inlineInfo;
+ bool success = eeRunWithErrorTrap<Param>(
+ [](Param* pParam) {
+ // Init the local var info of the inlinee
+ pParam->pThis->impInlineInitVars(pParam->inlineInfo);
- if (pParam->inlineInfo->inlineResult->IsCandidate())
- {
- /* Clear the temp table */
- memset(pParam->inlineInfo->lclTmpNum, -1, sizeof(pParam->inlineInfo->lclTmpNum));
+ if (pParam->inlineInfo->inlineResult->IsCandidate())
+ {
+ /* Clear the temp table */
+ memset(pParam->inlineInfo->lclTmpNum, -1, sizeof(pParam->inlineInfo->lclTmpNum));
- //
- // Prepare the call to jitNativeCode
- //
+ //
+ // Prepare the call to jitNativeCode
+ //
- pParam->inlineInfo->InlinerCompiler = pParam->pThis;
- if (pParam->pThis->impInlineInfo == nullptr)
- {
- pParam->inlineInfo->InlineRoot = pParam->pThis;
- }
- else
- {
- pParam->inlineInfo->InlineRoot = pParam->pThis->impInlineInfo->InlineRoot;
- }
- pParam->inlineInfo->argCnt = pParam->inlineCandidateInfo->methInfo.args.totalILArgs();
- pParam->inlineInfo->tokenLookupContextHandle = pParam->inlineCandidateInfo->exactContextHnd;
+ pParam->inlineInfo->InlinerCompiler = pParam->pThis;
+ if (pParam->pThis->impInlineInfo == nullptr)
+ {
+ pParam->inlineInfo->InlineRoot = pParam->pThis;
+ }
+ else
+ {
+ pParam->inlineInfo->InlineRoot = pParam->pThis->impInlineInfo->InlineRoot;
+ }
+ pParam->inlineInfo->argCnt = pParam->inlineCandidateInfo->methInfo.args.totalILArgs();
+ pParam->inlineInfo->tokenLookupContextHandle = pParam->inlineCandidateInfo->exactContextHnd;
- JITLOG_THIS(pParam->pThis,
- (LL_INFO100000,
- "INLINER: inlineInfo.tokenLookupContextHandle for %s set to 0x%p:\n",
- pParam->pThis->eeGetMethodFullName(pParam->fncHandle),
- pParam->pThis->dspPtr(pParam->inlineInfo->tokenLookupContextHandle)));
+ JITLOG_THIS(pParam->pThis,
+ (LL_INFO100000, "INLINER: inlineInfo.tokenLookupContextHandle for %s set to 0x%p:\n",
+ pParam->pThis->eeGetMethodFullName(pParam->fncHandle),
+ pParam->pThis->dspPtr(pParam->inlineInfo->tokenLookupContextHandle)));
- CORJIT_FLAGS compileFlagsForInlinee;
- memcpy(&compileFlagsForInlinee, pParam->pThis->opts.jitFlags, sizeof(compileFlagsForInlinee));
- compileFlagsForInlinee.corJitFlags &= ~CORJIT_FLG_LOST_WHEN_INLINING;
- compileFlagsForInlinee.corJitFlags |= CORJIT_FLG_SKIP_VERIFICATION;
+ JitFlags compileFlagsForInlinee = *pParam->pThis->opts.jitFlags;
+
+ // The following flags are lost when inlining.
+ // (This is checked in Compiler::compInitOptions().)
+ compileFlagsForInlinee.Clear(JitFlags::JIT_FLAG_BBOPT);
+ compileFlagsForInlinee.Clear(JitFlags::JIT_FLAG_BBINSTR);
+ compileFlagsForInlinee.Clear(JitFlags::JIT_FLAG_PROF_ENTERLEAVE);
+ compileFlagsForInlinee.Clear(JitFlags::JIT_FLAG_DEBUG_EnC);
+ compileFlagsForInlinee.Clear(JitFlags::JIT_FLAG_DEBUG_INFO);
+
+ compileFlagsForInlinee.Set(JitFlags::JIT_FLAG_SKIP_VERIFICATION);
#ifdef DEBUG
- if (pParam->pThis->verbose)
- {
- printf("\nInvoking compiler for the inlinee method %s :\n",
- pParam->pThis->eeGetMethodFullName(pParam->fncHandle));
- }
+ if (pParam->pThis->verbose)
+ {
+ printf("\nInvoking compiler for the inlinee method %s :\n",
+ pParam->pThis->eeGetMethodFullName(pParam->fncHandle));
+ }
#endif // DEBUG
- int result = jitNativeCode(pParam->fncHandle,
- pParam->inlineCandidateInfo->methInfo.scope,
- pParam->pThis->info.compCompHnd,
- &pParam->inlineCandidateInfo->methInfo,
- (void**)pParam->inlineInfo,
- nullptr,
- &compileFlagsForInlinee,
- pParam->inlineInfo);
-
- if (result != CORJIT_OK)
- {
- // If we haven't yet determined why this inline fails, use
- // a catch-all something bad happened observation.
- InlineResult* innerInlineResult = pParam->inlineInfo->inlineResult;
+ int result =
+ jitNativeCode(pParam->fncHandle, pParam->inlineCandidateInfo->methInfo.scope,
+ pParam->pThis->info.compCompHnd, &pParam->inlineCandidateInfo->methInfo,
+ (void**)pParam->inlineInfo, nullptr, &compileFlagsForInlinee, pParam->inlineInfo);
- if (!innerInlineResult->IsFailure())
+ if (result != CORJIT_OK)
{
- innerInlineResult->NoteFatal(InlineObservation::CALLSITE_COMPILATION_FAILURE);
+ // If we haven't yet determined why this inline fails, use
+ // a catch-all something bad happened observation.
+ InlineResult* innerInlineResult = pParam->inlineInfo->inlineResult;
+
+ if (!innerInlineResult->IsFailure())
+ {
+ innerInlineResult->NoteFatal(InlineObservation::CALLSITE_COMPILATION_FAILURE);
+ }
}
}
- }
- }, &param);
+ },
+ &param);
if (!success)
{
#ifdef DEBUG
if (verbose)
{
- printf("\nInlining failed due to an exception during invoking the compiler for the inlinee method %s.\n",
- eeGetMethodFullName(fncHandle));
+ printf("\nInlining failed due to an exception during invoking the compiler for the inlinee method %s.\n",
+ eeGetMethodFullName(fncHandle));
}
#endif // DEBUG
@@ -21498,8 +21589,7 @@ void Compiler::fgInvokeInlineeCompiler(GenTreeCall* call,
#ifdef DEBUG
if (0 && verbose)
{
- printf("\nDone invoking compiler for the inlinee method %s\n",
- eeGetMethodFullName(fncHandle));
+ printf("\nDone invoking compiler for the inlinee method %s\n", eeGetMethodFullName(fncHandle));
}
#endif // DEBUG
@@ -21514,7 +21604,7 @@ void Compiler::fgInvokeInlineeCompiler(GenTreeCall* call,
if (verbose)
{
printf("\nInlining failed because pInlineInfo->retExpr is not set in the inlinee method %s.\n",
- eeGetMethodFullName(fncHandle));
+ eeGetMethodFullName(fncHandle));
}
#endif // DEBUG
inlineResult->NoteFatal(InlineObservation::CALLEE_LACKS_RETURN);
@@ -21526,7 +21616,8 @@ void Compiler::fgInvokeInlineeCompiler(GenTreeCall* call,
// we defer the call to initClass() until inlining is completed in case it fails. If inlining succeeds,
// we will call initClass().
if (!(info.compCompHnd->initClass(nullptr /* field */, fncHandle /* method */,
- inlineCandidateInfo->exactContextHnd /* context */) & CORINFO_INITCLASS_INITIALIZED))
+ inlineCandidateInfo->exactContextHnd /* context */) &
+ CORINFO_INITCLASS_INITIALIZED))
{
inlineResult->NoteFatal(InlineObservation::CALLEE_CLASS_INIT_FAILURE);
return;
@@ -21545,11 +21636,8 @@ void Compiler::fgInvokeInlineeCompiler(GenTreeCall* call,
if (verbose || fgPrintInlinedMethods)
{
- printf("Successfully inlined %s (%d IL bytes) (depth %d) [%s]\n",
- eeGetMethodFullName(fncHandle),
- inlineCandidateInfo->methInfo.ILCodeSize,
- inlineDepth,
- inlineResult->ReasonString());
+ printf("Successfully inlined %s (%d IL bytes) (depth %d) [%s]\n", eeGetMethodFullName(fncHandle),
+ inlineCandidateInfo->methInfo.ILCodeSize, inlineDepth, inlineResult->ReasonString());
}
if (verbose)
@@ -21566,20 +21654,39 @@ void Compiler::fgInvokeInlineeCompiler(GenTreeCall* call,
inlineResult->NoteSuccess();
}
-// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-// The inlining attempt cannot be failed starting from this point.
-// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+//------------------------------------------------------------------------
+// fgInsertInlineeBlocks: incorporate statements for an inline into the
+// root method.
+//
+// Arguments:
+// inlineInfo -- info for the inline
+//
+// Notes:
+// The inlining attempt cannot be failed once this method is called.
+//
+// Adds all inlinee statements, plus any glue statements needed
+// either before or after the inlined call.
+//
+// Updates flow graph and assigns weights to inlinee
+// blocks. Currently does not attempt to read IBC data for the
+// inlinee.
+//
+// Updates relevant root method status flags (eg optMethodFlags) to
+// include information from the inlinee.
+//
+// Marks newly added statements with an appropriate inline context.
+
void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo)
{
- GenTreePtr iciCall = pInlineInfo->iciCall;
- GenTreePtr iciStmt = pInlineInfo->iciStmt;
- BasicBlock* iciBlock = pInlineInfo->iciBlock;
+ GenTreeCall* iciCall = pInlineInfo->iciCall;
+ GenTreeStmt* iciStmt = pInlineInfo->iciStmt;
+ BasicBlock* iciBlock = pInlineInfo->iciBlock;
BasicBlock* block;
// We can write better assert here. For example, we can check that
// iciBlock contains iciStmt, which in turn contains iciCall.
noway_assert(iciBlock->bbTreeList != nullptr);
- noway_assert(iciStmt->gtStmt.gtStmtExpr != nullptr);
+ noway_assert(iciStmt->gtStmtExpr != nullptr);
noway_assert(iciCall->gtOper == GT_CALL);
#ifdef DEBUG
@@ -21591,33 +21698,23 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo)
printf("\n\n----------- Statements (and blocks) added due to the inlining of call ");
printTreeID(iciCall);
printf(" -----------\n");
- // gtDispTree(iciStmt);
}
#endif // DEBUG
- //
// Create a new inline context and mark the inlined statements with it
- //
InlineContext* calleeContext = m_inlineStrategy->NewSuccess(pInlineInfo);
- for (block = InlineeCompiler->fgFirstBB;
- block != nullptr;
- block = block->bbNext)
+ for (block = InlineeCompiler->fgFirstBB; block != nullptr; block = block->bbNext)
{
- for (GenTreeStmt* stmt = block->firstStmt();
- stmt;
- stmt = stmt->gtNextStmt)
+ for (GenTreeStmt* stmt = block->firstStmt(); stmt; stmt = stmt->gtNextStmt)
{
stmt->gtInlineContext = calleeContext;
}
}
- //
- // Prepend statements.
- //
- GenTreePtr stmtAfter;
- stmtAfter = fgInlinePrependStatements(pInlineInfo);
+ // Prepend statements
+ GenTreePtr stmtAfter = fgInlinePrependStatements(pInlineInfo);
#ifdef DEBUG
if (verbose)
@@ -21627,6 +21724,9 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo)
}
#endif // DEBUG
+ BasicBlock* topBlock = iciBlock;
+ BasicBlock* bottomBlock = nullptr;
+
if (InlineeCompiler->fgBBcount == 1)
{
// When fgBBCount is 1 we will always have a non-NULL fgFirstBB
@@ -21641,22 +21741,21 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo)
// Inlinee contains just one BB. So just insert its statement list to topBlock.
if (InlineeCompiler->fgFirstBB->bbTreeList)
{
- stmtAfter = fgInsertStmtListAfter(iciBlock,
- stmtAfter,
- InlineeCompiler->fgFirstBB->bbTreeList);
+ stmtAfter = fgInsertStmtListAfter(iciBlock, stmtAfter, InlineeCompiler->fgFirstBB->bbTreeList);
// Copy inlinee bbFlags to caller bbFlags.
- const unsigned int inlineeBlockFlags = InlineeCompiler->fgFirstBB->bbFlags;
+ const unsigned __int64 inlineeBlockFlags = InlineeCompiler->fgFirstBB->bbFlags;
noway_assert((inlineeBlockFlags & BBF_HAS_JMP) == 0);
noway_assert((inlineeBlockFlags & BBF_KEEP_BBJ_ALWAYS) == 0);
iciBlock->bbFlags |= inlineeBlockFlags;
}
+
#ifdef DEBUG
if (verbose)
{
noway_assert(currentDumpStmt);
- if (currentDumpStmt != stmtAfter)
+ if (currentDumpStmt != stmtAfter)
{
do
{
@@ -21669,10 +21768,14 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo)
gtDispTree(currentDumpStmt);
printf("\n");
- } while (currentDumpStmt != stmtAfter);
+ } while (currentDumpStmt != stmtAfter);
}
}
#endif // DEBUG
+
+ // Append statements to unpin, if necessary.
+ fgInlineAppendStatements(pInlineInfo, iciBlock, stmtAfter);
+
goto _Done;
}
}
@@ -21681,24 +21784,20 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo)
// ======= Inserting inlinee's basic blocks ===============
//
- BasicBlock* topBlock;
- BasicBlock* bottomBlock;
-
- topBlock = iciBlock;
-
- bottomBlock = fgNewBBafter(topBlock->bbJumpKind, topBlock, true);
- bottomBlock->bbRefs = 1;
+ bottomBlock = fgNewBBafter(topBlock->bbJumpKind, topBlock, true);
+ bottomBlock->bbRefs = 1;
bottomBlock->bbJumpDest = topBlock->bbJumpDest;
bottomBlock->inheritWeight(topBlock);
topBlock->bbJumpKind = BBJ_NONE;
// Update block flags
- unsigned originalFlags;
- originalFlags = topBlock->bbFlags;
- noway_assert((originalFlags & BBF_SPLIT_NONEXIST) == 0);
- topBlock->bbFlags &= ~(BBF_SPLIT_LOST);
- bottomBlock->bbFlags |= originalFlags & BBF_SPLIT_GAINED;
+ {
+ const unsigned __int64 originalFlags = topBlock->bbFlags;
+ noway_assert((originalFlags & BBF_SPLIT_NONEXIST) == 0);
+ topBlock->bbFlags &= ~(BBF_SPLIT_LOST);
+ bottomBlock->bbFlags |= originalFlags & BBF_SPLIT_GAINED;
+ }
//
// Split statements between topBlock and bottomBlock
@@ -21708,10 +21807,10 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo)
GenTreePtr bottomBlock_Begin;
GenTreePtr bottomBlock_End;
- topBlock_Begin = nullptr;
- topBlock_End = nullptr;
+ topBlock_Begin = nullptr;
+ topBlock_End = nullptr;
bottomBlock_Begin = nullptr;
- bottomBlock_End = nullptr;
+ bottomBlock_End = nullptr;
//
// First figure out bottomBlock_Begin
@@ -21724,7 +21823,7 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo)
// topBlock is empty before the split.
// In this case, both topBlock and bottomBlock should be empty
noway_assert(bottomBlock_Begin == nullptr);
- topBlock->bbTreeList = nullptr;
+ topBlock->bbTreeList = nullptr;
bottomBlock->bbTreeList = nullptr;
}
else if (topBlock->bbTreeList == bottomBlock_Begin)
@@ -21735,7 +21834,7 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo)
// And the split is before the first statement.
// In this case, topBlock should be empty, and everything else should be moved to the bottonBlock.
bottomBlock->bbTreeList = topBlock->bbTreeList;
- topBlock->bbTreeList = nullptr;
+ topBlock->bbTreeList = nullptr;
}
else if (bottomBlock_Begin == nullptr)
{
@@ -21753,9 +21852,9 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo)
noway_assert(bottomBlock_Begin);
// This is the normal case where both blocks should contain at least one statement.
- topBlock_Begin = topBlock->bbTreeList;
+ topBlock_Begin = topBlock->bbTreeList;
noway_assert(topBlock_Begin);
- topBlock_End = bottomBlock_Begin->gtPrev;
+ topBlock_End = bottomBlock_Begin->gtPrev;
noway_assert(topBlock_End);
bottomBlock_End = topBlock->lastStmt();
noway_assert(bottomBlock_End);
@@ -21778,25 +21877,23 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo)
bool inheritWeight;
inheritWeight = true; // The firstBB does inherit the weight from the iciBlock
- for (block = InlineeCompiler->fgFirstBB;
- block != nullptr;
- block = block->bbNext)
+ for (block = InlineeCompiler->fgFirstBB; block != nullptr; block = block->bbNext)
{
noway_assert(!block->hasTryIndex());
noway_assert(!block->hasHndIndex());
block->copyEHRegion(iciBlock);
- block->bbFlags |= iciBlock->bbFlags & BBF_BACKWARD_JUMP;
+ block->bbFlags |= iciBlock->bbFlags & BBF_BACKWARD_JUMP;
- if (iciStmt->gtStmt.gtStmtILoffsx != BAD_IL_OFFSET)
+ if (iciStmt->gtStmtILoffsx != BAD_IL_OFFSET)
{
- block->bbCodeOffs = jitGetILoffs(iciStmt->gtStmt.gtStmtILoffsx);
- block->bbCodeOffsEnd = block->bbCodeOffs + 1; // TODO: is code size of 1 some magic number for inlining?
+ block->bbCodeOffs = jitGetILoffs(iciStmt->gtStmtILoffsx);
+ block->bbCodeOffsEnd = block->bbCodeOffs + 1; // TODO: is code size of 1 some magic number for inlining?
}
else
{
- block->bbCodeOffs = 0; // TODO: why not BAD_IL_OFFSET?
- block->bbCodeOffsEnd = 0;
- block->bbFlags |= BBF_INTERNAL;
+ block->bbCodeOffs = 0; // TODO: why not BAD_IL_OFFSET?
+ block->bbCodeOffsEnd = 0;
+ block->bbFlags |= BBF_INTERNAL;
}
if (block->bbJumpKind == BBJ_RETURN)
@@ -21810,8 +21907,8 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo)
#ifdef DEBUG
if (verbose)
{
- printf("\nConvert bbJumpKind of BB%02u to BBJ_ALWAYS to bottomBlock BB%02u\n",
- block->bbNum, bottomBlock->bbNum);
+ printf("\nConvert bbJumpKind of BB%02u to BBJ_ALWAYS to bottomBlock BB%02u\n", block->bbNum,
+ bottomBlock->bbNum);
}
#endif // DEBUG
}
@@ -21846,6 +21943,9 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo)
//
fgBBcount += InlineeCompiler->fgBBcount;
+ // Append statements to unpin if necessary.
+ fgInlineAppendStatements(pInlineInfo, bottomBlock, nullptr);
+
#ifdef DEBUG
if (verbose)
{
@@ -21862,15 +21962,18 @@ _Done:
//
// Copy out some flags
//
- compLongUsed |= InlineeCompiler->compLongUsed;
- compFloatingPointUsed |= InlineeCompiler->compFloatingPointUsed;
- compLocallocUsed |= InlineeCompiler->compLocallocUsed;
- compQmarkUsed |= InlineeCompiler->compQmarkUsed;
- compUnsafeCastUsed |= InlineeCompiler->compUnsafeCastUsed;
+ compLongUsed |= InlineeCompiler->compLongUsed;
+ compFloatingPointUsed |= InlineeCompiler->compFloatingPointUsed;
+ compLocallocUsed |= InlineeCompiler->compLocallocUsed;
+ compQmarkUsed |= InlineeCompiler->compQmarkUsed;
+ compUnsafeCastUsed |= InlineeCompiler->compUnsafeCastUsed;
compNeedsGSSecurityCookie |= InlineeCompiler->compNeedsGSSecurityCookie;
- compGSReorderStackLayout |= InlineeCompiler->compGSReorderStackLayout;
+ compGSReorderStackLayout |= InlineeCompiler->compGSReorderStackLayout;
+
+ // Update unmanaged call count
+ info.compCallUnmanaged += InlineeCompiler->info.compCallUnmanaged;
- // Update optMethodFlags
+// Update optMethodFlags
#ifdef DEBUG
unsigned optMethodFlagsBefore = optMethodFlags;
@@ -21881,8 +21984,8 @@ _Done:
#ifdef DEBUG
if (optMethodFlags != optMethodFlagsBefore)
{
- JITDUMP("INLINER: Updating optMethodFlags -- root:%0x callee:%0x new:%0x\n",
- optMethodFlagsBefore, InlineeCompiler->optMethodFlags, optMethodFlags);
+ JITDUMP("INLINER: Updating optMethodFlags -- root:%0x callee:%0x new:%0x\n", optMethodFlagsBefore,
+ InlineeCompiler->optMethodFlags, optMethodFlags);
}
#endif
@@ -21908,24 +22011,41 @@ _Done:
// Detach the GT_CALL node from the original statement by hanging a "nothing" node under it,
// so that fgMorphStmts can remove the statement once we return from here.
//
- iciStmt->gtStmt.gtStmtExpr = gtNewNothingNode();
+ iciStmt->gtStmtExpr = gtNewNothingNode();
}
-// Prepend the statements that are needed before the inlined call.
-// Return the last statement that is prepended.
+//------------------------------------------------------------------------
+// fgInlinePrependStatements: prepend statements needed to match up
+// caller and inlined callee
+//
+// Arguments:
+// inlineInfo -- info for the inline
+//
+// Return Value:
+// The last statement that was added, or the original call if no
+// statements were added.
+//
+// Notes:
+// Statements prepended may include the following:
+// * This pointer null check
+// * Class initialization
+// * Zeroing of must-init locals in the callee
+// * Passing of call arguments via temps
+//
+// Newly added statements are placed just after the original call
+// and are are given the same inline context as the call any calls
+// added here will appear to have been part of the immediate caller.
-GenTreePtr Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo)
+GenTreePtr Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo)
{
- BasicBlock* block = inlineInfo->iciBlock;
+ BasicBlock* block = inlineInfo->iciBlock;
+ GenTreeStmt* callStmt = inlineInfo->iciStmt;
+ IL_OFFSETX callILOffset = callStmt->gtStmtILoffsx;
+ 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;
- GenTreePtr callStmt = inlineInfo->iciStmt;
- noway_assert(callStmt->gtOper == GT_STMT);
- IL_OFFSETX callILOffset = callStmt->gtStmt.gtStmtILoffsx;
-
- GenTreePtr afterStmt = callStmt; // afterStmt is the place where the new statements should be inserted after.
- GenTreePtr newStmt;
-
- GenTreePtr call = inlineInfo->iciCall;
noway_assert(call->gtOper == GT_CALL);
#ifdef DEBUG
@@ -21939,12 +22059,13 @@ GenTreePtr Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo)
// Prepend statements for any initialization / side effects
- InlArgInfo* inlArgInfo = inlineInfo->inlArgInfo;
- InlLclVarInfo* lclVarInfo = inlineInfo->lclVarInfo;
+ InlArgInfo* inlArgInfo = inlineInfo->inlArgInfo;
+ InlLclVarInfo* lclVarInfo = inlineInfo->lclVarInfo;
GenTreePtr tree;
- // Create the null check statement (but not appending it to the statement list yet) for the 'this' pointer if necessary.
+ // Create the null check statement (but not appending it to the statement list yet) for the 'this' pointer if
+ // necessary.
// The NULL check should be done after "argument setup statements".
// The only reason we move it here is for calling "impInlineFetchArg(0,..." to reserve a temp
// for the "this" pointer.
@@ -21956,8 +22077,7 @@ GenTreePtr Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo)
if (call->gtFlags & GTF_CALL_NULLCHECK && !inlineInfo->thisDereferencedFirst)
{
// Call impInlineFetchArg to "reserve" a temp for the "this" pointer.
- nullcheck = gtNewOperNode(GT_IND, TYP_INT,
- impInlineFetchArg(0, inlArgInfo, lclVarInfo));
+ nullcheck = gtNewOperNode(GT_IND, TYP_INT, impInlineFetchArg(0, inlArgInfo, lclVarInfo));
nullcheck->gtFlags |= GTF_EXCEPT;
// The NULL-check statement will be inserted to the statement list after those statements
@@ -21995,10 +22115,8 @@ GenTreePtr Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo)
GenTreePtr argSingleUseNode = inlArgInfo[argNum].argBashTmpNode;
- if (argSingleUseNode &&
- !(argSingleUseNode->gtFlags & GTF_VAR_CLONED) &&
- !inlArgInfo[argNum].argHasLdargaOp &&
- !inlArgInfo[argNum].argHasStargOp)
+ if (argSingleUseNode && !(argSingleUseNode->gtFlags & GTF_VAR_CLONED) &&
+ !inlArgInfo[argNum].argHasLdargaOp && !inlArgInfo[argNum].argHasStargOp)
{
// 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.
@@ -22019,15 +22137,12 @@ GenTreePtr Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo)
noway_assert(structHnd != NO_CLASS_HANDLE);
}
- // Unsafe value cls check is not needed for 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);
+ // Unsafe value cls check is not needed for
+ // 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);
#ifdef DEBUG
if (verbose)
@@ -22035,7 +22150,6 @@ GenTreePtr Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo)
gtDispTree(afterStmt);
}
#endif // DEBUG
-
}
}
else if (inlArgInfo[argNum].argIsByRefToStructLocal)
@@ -22046,19 +22160,18 @@ GenTreePtr Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo)
{
/* 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(!inlArgInfo[argNum].argIsUsed || inlArgInfo[argNum].argIsInvariant ||
+ inlArgInfo[argNum].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)
{
- assert(inlArgInfo[argNum].argNode->OperIsConst() ||
- inlArgInfo[argNum].argNode->gtOper == GT_ADDR);
+ assert(inlArgInfo[argNum].argNode->OperIsConst() || inlArgInfo[argNum].argNode->gtOper == GT_ADDR);
}
noway_assert((inlArgInfo[argNum].argIsLclVar == 0) ==
- (inlArgInfo[argNum].argNode->gtOper != GT_LCL_VAR || (inlArgInfo[argNum].argNode->gtFlags & GTF_GLOB_REF)));
+ (inlArgInfo[argNum].argNode->gtOper != GT_LCL_VAR ||
+ (inlArgInfo[argNum].argNode->gtFlags & GTF_GLOB_REF)));
/* If the argument has side effects, append it */
@@ -22086,7 +22199,6 @@ GenTreePtr Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo)
gtDispTree(afterStmt);
}
#endif // DEBUG
-
}
}
}
@@ -22101,7 +22213,7 @@ GenTreePtr Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo)
if (inlineInfo->inlineCandidateInfo->initClassResult & CORINFO_INITCLASS_USE_HELPER)
{
CORINFO_CONTEXT_HANDLE exactContext = inlineInfo->inlineCandidateInfo->exactContextHnd;
- CORINFO_CLASS_HANDLE exactClass;
+ CORINFO_CLASS_HANDLE exactClass;
if (((SIZE_T)exactContext & CORINFO_CONTEXTFLAGS_MASK) == CORINFO_CONTEXTFLAGS_CLASS)
{
@@ -22109,18 +22221,19 @@ GenTreePtr Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo)
}
else
{
- exactClass = info.compCompHnd->getMethodClass(CORINFO_METHOD_HANDLE((SIZE_T)exactContext & ~CORINFO_CONTEXTFLAGS_MASK));
+ exactClass = info.compCompHnd->getMethodClass(
+ CORINFO_METHOD_HANDLE((SIZE_T)exactContext & ~CORINFO_CONTEXTFLAGS_MASK));
}
- tree = fgGetSharedCCtor(exactClass);
- newStmt = gtNewStmt(tree, callILOffset);
+ tree = fgGetSharedCCtor(exactClass);
+ newStmt = gtNewStmt(tree, callILOffset);
afterStmt = fgInsertStmtAfter(block, afterStmt, newStmt);
}
// Insert the nullcheck statement now.
if (nullcheck)
{
- newStmt = gtNewStmt(nullcheck, callILOffset);
+ newStmt = gtNewStmt(nullcheck, callILOffset);
afterStmt = fgInsertStmtAfter(block, afterStmt, newStmt);
}
@@ -22133,8 +22246,7 @@ GenTreePtr Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo)
unsigned lclCnt = InlineeMethodInfo->locals.numArgs;
// Does callee contain any zero-init local?
- if ((lclCnt != 0) &&
- (InlineeMethodInfo->options & CORINFO_OPT_INIT_LOCALS) != 0)
+ if ((lclCnt != 0) && (InlineeMethodInfo->options & CORINFO_OPT_INIT_LOCALS) != 0)
{
#ifdef DEBUG
@@ -22146,7 +22258,7 @@ GenTreePtr Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo)
for (unsigned lclNum = 0; lclNum < lclCnt; lclNum++)
{
- unsigned tmpNum = inlineInfo->lclTmpNum[lclNum];
+ unsigned tmpNum = inlineInfo->lclTmpNum[lclNum];
// Is the local used at all?
if (tmpNum != BAD_VAR_NUM)
@@ -22158,25 +22270,21 @@ GenTreePtr Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo)
{
// Unsafe value cls check is not needed here since in-linee compiler instance would have
// iterated over locals and marked accordingly.
- impAssignTempGen(tmpNum,
- gtNewZeroConNode(genActualType(lclTyp)),
- NO_CLASS_HANDLE,
- (unsigned)CHECK_SPILL_NONE,
- & afterStmt,
- callILOffset,
- block);
+ impAssignTempGen(tmpNum, gtNewZeroConNode(genActualType(lclTyp)), NO_CLASS_HANDLE,
+ (unsigned)CHECK_SPILL_NONE, &afterStmt, callILOffset, block);
}
else
{
- CORINFO_CLASS_HANDLE structType = lclVarInfo[lclNum + inlineInfo->argCnt].lclVerTypeInfo.GetClassHandle();
+ CORINFO_CLASS_HANDLE structType =
+ lclVarInfo[lclNum + inlineInfo->argCnt].lclVerTypeInfo.GetClassHandle();
- tree = gtNewBlkOpNode(gtNewLclvNode(tmpNum, lclTyp), // Dest
- gtNewIconNode(0), // Value
+ tree = gtNewBlkOpNode(gtNewLclvNode(tmpNum, lclTyp), // Dest
+ gtNewIconNode(0), // Value
info.compCompHnd->getClassSize(structType), // Size
- false, // isVolatile
- false); // not copyBlock
+ false, // isVolatile
+ false); // not copyBlock
- newStmt = gtNewStmt(tree, callILOffset);
+ newStmt = gtNewStmt(tree, callILOffset);
afterStmt = fgInsertStmtAfter(block, afterStmt, newStmt);
}
@@ -22190,14 +22298,102 @@ GenTreePtr Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo)
}
}
+ // Update any newly added statements with the appropriate context.
+ InlineContext* context = callStmt->gtInlineContext;
+ assert(context != nullptr);
+ for (GenTreeStmt* addedStmt = callStmt->gtNextStmt; addedStmt != postStmt; addedStmt = addedStmt->gtNextStmt)
+ {
+ assert(addedStmt->gtInlineContext == nullptr);
+ addedStmt->gtInlineContext = context;
+ }
+
return afterStmt;
}
+//------------------------------------------------------------------------
+// fgInlineAppendStatements: Append statements that are needed
+// after the inlined call.
+//
+// Arguments:
+// inlineInfo - information about the inline
+// block - basic block for the new statements
+// stmtAfter - (optional) insertion point for mid-block cases
+
+void Compiler::fgInlineAppendStatements(InlineInfo* inlineInfo, BasicBlock* block, GenTreePtr stmtAfter)
+{
+ // Null out any inline pinned locals
+ if (!inlineInfo->hasPinnedLocals)
+ {
+ // No pins, nothing to do
+ return;
+ }
+
+ JITDUMP("Unpin 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;
+ InlLclVarInfo* lclVarInfo = inlineInfo->lclVarInfo;
+
+ noway_assert(callStmt->gtOper == GT_STMT);
+
+ for (unsigned lclNum = 0; lclNum < lclCnt; lclNum++)
+ {
+ unsigned tmpNum = inlineInfo->lclTmpNum[lclNum];
+
+ // Is the local used at all?
+ if (tmpNum == BAD_VAR_NUM)
+ {
+ // Nope, nothing to unpin.
+ continue;
+ }
+
+ // Is the local pinned?
+ if (!lvaTable[tmpNum].lvPinned)
+ {
+ // Nope, nothing to unpin.
+ continue;
+ }
+
+ // Does the local we're about to unpin 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;
+ if (retExpr != nullptr)
+ {
+ const bool interferesWithReturn = gtHasRef(inlineInfo->retExpr, tmpNum, false);
+ 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);
+
+ if (stmtAfter == nullptr)
+ {
+ stmtAfter = fgInsertStmtAtBeg(block, unpinStmt);
+ }
+ else
+ {
+ stmtAfter = fgInsertStmtAfter(block, stmtAfter, unpinStmt);
+ }
+
+#ifdef DEBUG
+ if (verbose)
+ {
+ gtDispTree(unpinStmt);
+ }
+#endif // DEBUG
+ }
+}
/*****************************************************************************/
/*static*/
-Compiler::fgWalkResult Compiler::fgChkThrowCB(GenTreePtr* pTree,
- fgWalkData* data)
+Compiler::fgWalkResult Compiler::fgChkThrowCB(GenTreePtr* pTree, fgWalkData* data)
{
GenTreePtr tree = *pTree;
@@ -22210,28 +22406,30 @@ Compiler::fgWalkResult Compiler::fgChkThrowCB(GenTreePtr* pTree,
switch (tree->gtOper)
{
- case GT_MUL:
- case GT_ADD:
- case GT_SUB:
- case GT_ASG_ADD:
- case GT_ASG_SUB:
- case GT_CAST:
- if (tree->gtOverflow()) {
- return Compiler::WALK_ABORT;
-}
- break;
+ case GT_MUL:
+ case GT_ADD:
+ case GT_SUB:
+ case GT_ASG_ADD:
+ case GT_ASG_SUB:
+ case GT_CAST:
+ if (tree->gtOverflow())
+ {
+ return Compiler::WALK_ABORT;
+ }
+ break;
- case GT_INDEX:
- if (tree->gtFlags & GTF_INX_RNGCHK) {
- return Compiler::WALK_ABORT;
-}
- break;
+ case GT_INDEX:
+ if (tree->gtFlags & GTF_INX_RNGCHK)
+ {
+ return Compiler::WALK_ABORT;
+ }
+ break;
- case GT_ARR_BOUNDS_CHECK:
- return Compiler::WALK_ABORT;
+ case GT_ARR_BOUNDS_CHECK:
+ return Compiler::WALK_ABORT;
- default:
- break;
+ default:
+ break;
}
return Compiler::WALK_CONTINUE;
@@ -22239,33 +22437,32 @@ Compiler::fgWalkResult Compiler::fgChkThrowCB(GenTreePtr* pTree,
/*****************************************************************************/
/*static*/
-Compiler::fgWalkResult Compiler::fgChkLocAllocCB(GenTreePtr* pTree,
- fgWalkData* data)
+Compiler::fgWalkResult Compiler::fgChkLocAllocCB(GenTreePtr* pTree, fgWalkData* data)
{
GenTreePtr tree = *pTree;
- if (tree->gtOper == GT_LCLHEAP) {
+ if (tree->gtOper == GT_LCLHEAP)
+ {
return Compiler::WALK_ABORT;
-}
+ }
return Compiler::WALK_CONTINUE;
}
/*****************************************************************************/
/*static*/
-Compiler::fgWalkResult Compiler::fgChkQmarkCB(GenTreePtr* pTree,
- fgWalkData* data)
+Compiler::fgWalkResult Compiler::fgChkQmarkCB(GenTreePtr* pTree, fgWalkData* data)
{
GenTreePtr tree = *pTree;
- if (tree->gtOper == GT_QMARK) {
+ if (tree->gtOper == GT_QMARK)
+ {
return Compiler::WALK_ABORT;
-}
+ }
return Compiler::WALK_CONTINUE;
}
-
void Compiler::fgLclFldAssign(unsigned lclNum)
{
assert(varTypeIsStruct(lvaTable[lclNum].lvType));
diff --git a/src/jit/gcencode.cpp b/src/jit/gcencode.cpp
index f20183b25a..128fc4addb 100644
--- a/src/jit/gcencode.cpp
+++ b/src/jit/gcencode.cpp
@@ -23,6 +23,89 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include "gcinfotypes.h"
+ReturnKind GCTypeToReturnKind(CorInfoGCType gcType)
+{
+ switch (gcType)
+ {
+ case TYPE_GC_NONE:
+ return RT_Scalar;
+ case TYPE_GC_REF:
+ return RT_Object;
+ case TYPE_GC_BYREF:
+ return RT_ByRef;
+ default:
+ _ASSERTE(!"TYP_GC_OTHER is unexpected");
+ return RT_Illegal;
+ }
+}
+
+ReturnKind GCInfo::getReturnKind()
+{
+ switch (compiler->info.compRetType)
+ {
+ case TYP_REF:
+ case TYP_ARRAY:
+ return RT_Object;
+ case TYP_BYREF:
+ return RT_ByRef;
+ case TYP_STRUCT:
+ {
+ CORINFO_CLASS_HANDLE structType = compiler->info.compMethodInfo->args.retTypeClass;
+ var_types retType = compiler->getReturnTypeForStruct(structType);
+
+ switch (retType)
+ {
+ case TYP_ARRAY:
+ _ASSERTE(false && "TYP_ARRAY unexpected from getReturnTypeForStruct()");
+ // fall through
+ case TYP_REF:
+ return RT_Object;
+
+ case TYP_BYREF:
+ return RT_ByRef;
+
+ case TYP_STRUCT:
+ if (compiler->IsHfa(structType))
+ {
+#ifdef _TARGET_X86_
+ _ASSERTE(false && "HFAs not expected for X86");
+#endif // _TARGET_X86_
+
+ return RT_Scalar;
+ }
+ else
+ {
+ // Multi-reg return
+ BYTE gcPtrs[2] = {TYPE_GC_NONE, TYPE_GC_NONE};
+ compiler->info.compCompHnd->getClassGClayout(structType, gcPtrs);
+
+ ReturnKind first = GCTypeToReturnKind((CorInfoGCType)gcPtrs[0]);
+ ReturnKind second = GCTypeToReturnKind((CorInfoGCType)gcPtrs[1]);
+
+ return GetStructReturnKind(first, second);
+ }
+
+#ifdef _TARGET_X86_
+ case TYP_FLOAT:
+ case TYP_DOUBLE:
+ return RT_Float;
+#endif // _TARGET_X86_
+ default:
+ return RT_Scalar;
+ }
+ }
+
+#ifdef _TARGET_X86_
+ case TYP_FLOAT:
+ case TYP_DOUBLE:
+ return RT_Float;
+#endif // _TARGET_X86_
+
+ default:
+ return RT_Scalar;
+ }
+}
+
#ifdef JIT32_GCENCODER
#include "emit.h"
@@ -104,18 +187,21 @@ static void regenLog(unsigned encoding, InfoHdr* header, InfoHdr* state)
fprintf(logFile, "InfoHdr( %2d, %2d, %1d, %1d, %1d,"
" %1d, %1d, %1d, %1d, %1d,"
- " %1d, %1d, %1d, %1d, %1d,"
- " %1d, %2d, %2d, %2d, %2d,"
- " %2d, %2d), \n",
+ " %1d, %1d, %1d, %1d, %1d, %1d,"
+ " %1d, %1d, %1d,"
+ " %1d, %2d, %2d,"
+ " %2d, %2d, %2d, %2d, %2d, %2d), \n",
state->prologSize, state->epilogSize, state->epilogCount, state->epilogAtEnd, state->ediSaved,
state->esiSaved, state->ebxSaved, state->ebpSaved, state->ebpFrame, state->interruptible,
state->doubleAlign, state->security, state->handlers, state->localloc, state->editNcontinue, state->varargs,
- state->profCallbacks, state->argCount, state->frameSize,
+ state->profCallbacks, state->genericsContext, state->genericsContextIsMethodDesc, state->returnKind,
+ state->argCount, state->frameSize,
(state->untrackedCnt <= SET_UNTRACKED_MAX) ? state->untrackedCnt : HAS_UNTRACKED,
(state->varPtrTableSize == 0) ? 0 : HAS_VARPTR,
(state->gsCookieOffset == INVALID_GS_COOKIE_OFFSET) ? 0 : HAS_GS_COOKIE_OFFSET,
(state->syncStartOffset == INVALID_SYNC_OFFSET) ? 0 : HAS_SYNC_OFFSET,
- (state->syncStartOffset == INVALID_SYNC_OFFSET) ? 0 : HAS_SYNC_OFFSET);
+ (state->syncStartOffset == INVALID_SYNC_OFFSET) ? 0 : HAS_SYNC_OFFSET,
+ (state->revPInvokeOffset == INVALID_REV_PINVOKE_OFFSET) ? 0 : HAS_REV_PINVOKE_FRAME_OFFSET);
fflush(logFile);
@@ -265,9 +351,11 @@ static int bigEncoding4(unsigned cur, unsigned tgt, unsigned max)
return cnt;
}
-BYTE FASTCALL encodeHeaderNext(const InfoHdr& header, InfoHdr* state)
+BYTE FASTCALL encodeHeaderNext(const InfoHdr& header, InfoHdr* state, BYTE& codeSet)
{
BYTE encoding = 0xff;
+ codeSet = 1; // codeSet is 1 or 2, depending on whether the returned encoding
+ // corresponds to InfoHdrAdjust, or InfoHdrAdjust2 enumerations.
if (state->argCount != header.argCount)
{
@@ -547,6 +635,15 @@ BYTE FASTCALL encodeHeaderNext(const InfoHdr& header, InfoHdr* state)
goto DO_RETURN;
}
+ if (GCInfoEncodesReturnKind() && (state->returnKind != header.returnKind))
+ {
+ state->returnKind = header.returnKind;
+ codeSet = 2; // Two byte encoding
+ encoding = header.returnKind;
+ _ASSERTE(encoding < SET_RET_KIND_MAX);
+ goto DO_RETURN;
+ }
+
if (state->gsCookieOffset != header.gsCookieOffset)
{
assert(state->gsCookieOffset == INVALID_GS_COOKIE_OFFSET || state->gsCookieOffset == HAS_GS_COOKIE_OFFSET);
@@ -587,10 +684,31 @@ BYTE FASTCALL encodeHeaderNext(const InfoHdr& header, InfoHdr* state)
}
}
+ if (GCInfoEncodesRevPInvokeFrame() && (state->revPInvokeOffset != header.revPInvokeOffset))
+ {
+ assert(state->revPInvokeOffset == INVALID_REV_PINVOKE_OFFSET ||
+ state->revPInvokeOffset == HAS_REV_PINVOKE_FRAME_OFFSET);
+
+ if (state->revPInvokeOffset == INVALID_REV_PINVOKE_OFFSET)
+ {
+ // header.revPInvokeOffset is non-zero.
+ state->revPInvokeOffset = HAS_REV_PINVOKE_FRAME_OFFSET;
+ encoding = FLIP_REV_PINVOKE_FRAME;
+ goto DO_RETURN;
+ }
+ else if (header.revPInvokeOffset == INVALID_REV_PINVOKE_OFFSET)
+ {
+ state->revPInvokeOffset = INVALID_REV_PINVOKE_OFFSET;
+ encoding = FLIP_REV_PINVOKE_FRAME;
+ goto DO_RETURN;
+ }
+ }
+
DO_RETURN:
- assert(encoding < 0x80);
+ _ASSERTE(encoding < MORE_BYTES_TO_FOLLOW);
if (!state->isHeaderMatch(header))
- encoding |= 0x80;
+ encoding |= MORE_BYTES_TO_FOLLOW;
+
return encoding;
}
@@ -806,6 +924,14 @@ static int measureDistance(const InfoHdr& header, const InfoHdrSmall* p, int clo
return distance;
}
+ if (p->returnKind != header.returnKind)
+ {
+ // Setting the ReturnKind requires two bytes of encoding.
+ distance += 2;
+ if (distance >= closeness)
+ return distance;
+ }
+
if (header.gsCookieOffset != INVALID_GS_COOKIE_OFFSET)
{
distance += 1;
@@ -820,6 +946,13 @@ static int measureDistance(const InfoHdr& header, const InfoHdrSmall* p, int clo
return distance;
}
+ if (header.revPInvokeOffset != INVALID_REV_PINVOKE_OFFSET)
+ {
+ distance += 1;
+ if (distance >= closeness)
+ return distance;
+ }
+
return distance;
}
@@ -1164,6 +1297,16 @@ size_t GCInfo::gcInfoBlockHdrSave(
header->genericsContext = compiler->lvaReportParamTypeArg();
header->genericsContextIsMethodDesc =
header->genericsContext && (compiler->info.compMethodInfo->options & (CORINFO_GENERICS_CTXT_FROM_METHODDESC));
+
+ if (GCInfoEncodesReturnKind())
+ {
+ ReturnKind returnKind = getReturnKind();
+ _ASSERTE(IsValidReturnKind(returnKind) && "Return Kind must be valid");
+ _ASSERTE(!IsStructReturnKind(returnKind) && "Struct Return Kinds Unexpected for JIT32");
+ _ASSERTE(((int)returnKind < (int)SET_RET_KIND_MAX) && "ReturnKind has no legal encoding");
+ header->returnKind = returnKind;
+ }
+
header->gsCookieOffset = INVALID_GS_COOKIE_OFFSET;
if (compiler->getNeedsGSSecurityCookie())
{
@@ -1190,6 +1333,8 @@ size_t GCInfo::gcInfoBlockHdrSave(
assert(header->epilogCount <= 1);
}
+ header->revPInvokeOffset = INVALID_REV_PINVOKE_OFFSET;
+
assert((compiler->compArgSize & 0x3) == 0);
size_t argCount =
@@ -1224,12 +1369,21 @@ size_t GCInfo::gcInfoBlockHdrSave(
*dest++ = headerEncoding;
BYTE encoding = headerEncoding;
- while (encoding & 0x80)
+ BYTE codeSet = 1;
+ while (encoding & MORE_BYTES_TO_FOLLOW)
{
- encoding = encodeHeaderNext(*header, &state);
+ encoding = encodeHeaderNext(*header, &state, codeSet);
+
#if REGEN_SHORTCUTS
regenLog(headerEncoding, header, &state);
#endif
+ _ASSERTE(codeSet == 1 || codeSet == 2 && "Encoding must correspond to InfoHdrAdjust or InfoHdrAdjust2");
+ if (codeSet == 2)
+ {
+ *dest++ = NEXT_OPCODE | MORE_BYTES_TO_FOLLOW;
+ ++size;
+ }
+
*dest++ = encoding;
++size;
}
@@ -1771,12 +1925,12 @@ size_t GCInfo::gcMakeRegPtrTable(BYTE* dest, int mask, const InfoHdr& header, un
}
else
{
- /* Stack-passed arguments which are not enregistered
- * are always reported in this "untracked stack
- * pointers" section of the GC info even if lvTracked==true
- */
+/* Stack-passed arguments which are not enregistered
+ * are always reported in this "untracked stack
+ * pointers" section of the GC info even if lvTracked==true
+ */
- /* Has this argument been enregistered? */
+/* Has this argument been enregistered? */
#ifndef LEGACY_BACKEND
if (!varDsc->lvOnFrame)
#else // LEGACY_BACKEND
@@ -3277,7 +3431,7 @@ void GCInfo::gcFindPtrsInFrame(const void* infoBlock, const void* codeBlock, uns
GCDump gcDump(GCINFO_VERSION);
gcDump.gcPrintf = gcDump_logf; // use my printf (which logs to VM)
- gcDump.DumpPtrsInFrame((const BYTE*)infoBlock, (const BYTE*)codeBlock, offs, verifyGCTables);
+ gcDump.DumpPtrsInFrame((PTR_CBYTE)infoBlock, (const BYTE*)codeBlock, offs, verifyGCTables);
}
#endif // DUMP_GC_TABLES
@@ -3504,23 +3658,6 @@ public:
#endif // DEBUG
-ReturnKind GCTypeToReturnKind(CorInfoGCType gcType)
-{
-
- switch (gcType)
- {
- case TYPE_GC_NONE:
- return RT_Scalar;
- case TYPE_GC_REF:
- return RT_Object;
- case TYPE_GC_BYREF:
- return RT_ByRef;
- default:
- _ASSERTE(!"TYP_GC_OTHER is unexpected");
- return RT_Illegal;
- }
-}
-
void GCInfo::gcInfoBlockHdrSave(GcInfoEncoder* gcInfoEncoder, unsigned methodSize, unsigned prologSize)
{
#ifdef DEBUG
@@ -3536,65 +3673,7 @@ void GCInfo::gcInfoBlockHdrSave(GcInfoEncoder* gcInfoEncoder, unsigned methodSiz
gcInfoEncoderWithLog->SetCodeLength(methodSize);
- ReturnKind returnKind = RT_Illegal;
-
- switch (compiler->info.compRetType)
- {
- case TYP_REF:
- case TYP_ARRAY:
- returnKind = RT_Object;
- break;
- case TYP_BYREF:
- returnKind = RT_ByRef;
- break;
- case TYP_STRUCT:
- {
- CORINFO_CLASS_HANDLE structType = compiler->info.compMethodInfo->args.retTypeClass;
- var_types retType = compiler->getReturnTypeForStruct(structType);
-
- switch (retType)
- {
- case TYP_ARRAY:
- _ASSERTE(false && "TYP_ARRAY unexpected from getReturnTypeForStruct()");
-
- case TYP_REF:
- returnKind = RT_Object;
- break;
-
- case TYP_BYREF:
- returnKind = RT_ByRef;
- break;
-
- case TYP_STRUCT:
- if (compiler->IsHfa(structType))
- {
- returnKind = RT_Scalar;
- }
- else
- {
- // Multi-reg return
- BYTE gcPtrs[2] = { TYPE_GC_NONE, TYPE_GC_NONE };
- compiler->info.compCompHnd->getClassGClayout(structType, gcPtrs);
-
- ReturnKind first = GCTypeToReturnKind((CorInfoGCType)gcPtrs[0]);
- ReturnKind second = GCTypeToReturnKind((CorInfoGCType)gcPtrs[1]);
-
- returnKind = GetStructReturnKind(first, second);
- }
- break;
-
- default:
- returnKind = RT_Scalar;
- break;
- }
- break;
- }
- default:
- returnKind = RT_Scalar;
- }
-
- _ASSERTE(returnKind != RT_Illegal);
- gcInfoEncoderWithLog->SetReturnKind(returnKind);
+ gcInfoEncoderWithLog->SetReturnKind(getReturnKind());
if (compiler->isFramePointerUsed())
{
@@ -3682,10 +3761,8 @@ void GCInfo::gcInfoBlockHdrSave(GcInfoEncoder* gcInfoEncoder, unsigned methodSiz
}
#if FEATURE_EH_FUNCLETS
- if (compiler->ehNeedsPSPSym())
+ if (compiler->lvaPSPSym != BAD_VAR_NUM)
{
- assert(compiler->lvaPSPSym != BAD_VAR_NUM);
-
#ifdef _TARGET_AMD64_
// The PSPSym is relative to InitialSP on X64 and CallerSP on other platforms.
gcInfoEncoderWithLog->SetPSPSymStackSlot(compiler->lvaGetInitialSPRelativeOffset(compiler->lvaPSPSym));
diff --git a/src/jit/gentree.cpp b/src/jit/gentree.cpp
index 67474e11ec..4a6cc740c6 100644
--- a/src/jit/gentree.cpp
+++ b/src/jit/gentree.cpp
@@ -21,7 +21,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
/*****************************************************************************/
const unsigned short GenTree::gtOperKindTable[] = {
-#define GTNODE(en, sn, cm, ok) ok + GTK_COMMUTE *cm,
+#define GTNODE(en, sn, st, cm, ok) ok + GTK_COMMUTE *cm,
#include "gtlist.h"
};
@@ -209,7 +209,7 @@ static void printIndent(IndentStack* indentStack)
}
static const char* nodeNames[] = {
-#define GTNODE(en, sn, cm, ok) sn,
+#define GTNODE(en, sn, st, cm, ok) sn,
#include "gtlist.h"
};
@@ -220,8 +220,12 @@ const char* GenTree::NodeName(genTreeOps op)
return nodeNames[op];
}
+#endif
+
+#if defined(DEBUG) || NODEBASH_STATS || MEASURE_NODE_SIZE || COUNT_AST_OPERS
+
static const char* opNames[] = {
-#define GTNODE(en, sn, cm, ok) #en,
+#define GTNODE(en, sn, st, cm, ok) #en,
#include "gtlist.h"
};
@@ -234,12 +238,27 @@ const char* GenTree::OpName(genTreeOps op)
#endif
+#if MEASURE_NODE_SIZE && SMALL_TREE_NODES
+
+static const char* opStructNames[] = {
+#define GTNODE(en, sn, st, cm, ok) #st,
+#include "gtlist.h"
+};
+
+const char* GenTree::OpStructName(genTreeOps op)
+{
+ assert((unsigned)op < sizeof(opStructNames) / sizeof(opStructNames[0]));
+
+ return opStructNames[op];
+}
+
+#endif
+
/*****************************************************************************
*
* When 'SMALL_TREE_NODES' is enabled, we allocate tree nodes in 2 different
- * sizes: 'GTF_DEBUG_NODE_SMALL' for most nodes and 'GTF_DEBUG_NODE_LARGE' for
- * the few nodes (such as calls and statement list nodes) that have more fields
- * and take up a lot more space.
+ * sizes: 'TREE_NODE_SZ_SMALL' for most nodes and 'TREE_NODE_SZ_LARGE' for the
+ * few nodes (such as calls) that have more fields and take up a lot more space.
*/
#if SMALL_TREE_NODES
@@ -248,6 +267,19 @@ const char* GenTree::OpName(genTreeOps op)
/* static */
unsigned char GenTree::s_gtNodeSizes[GT_COUNT + 1];
+#if NODEBASH_STATS || MEASURE_NODE_SIZE || COUNT_AST_OPERS
+
+unsigned char GenTree::s_gtTrueSizes[GT_COUNT + 1]{
+#define GTNODE(en, sn, st, cm, ok) sizeof(st),
+#include "gtlist.h"
+};
+
+#endif // NODEBASH_STATS || MEASURE_NODE_SIZE || COUNT_AST_OPERS
+
+#if COUNT_AST_OPERS
+LONG GenTree::s_gtNodeCounts[GT_COUNT + 1] = {0};
+#endif // COUNT_AST_OPERS
+
/* static */
void GenTree::InitNodeSize()
{
@@ -265,12 +297,13 @@ void GenTree::InitNodeSize()
// Now set all of the appropriate entries to 'large'
CLANG_FORMAT_COMMENT_ANCHOR;
+// clang-format off
#if defined(FEATURE_HFA) || defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
// On ARM32, ARM64 and System V for struct returning
// there is code that does GT_ASG-tree.CopyObj call.
// CopyObj is a large node and the GT_ASG is small, which triggers an exception.
- GenTree::s_gtNodeSizes[GT_ASG] = TREE_NODE_SZ_LARGE;
- GenTree::s_gtNodeSizes[GT_RETURN] = TREE_NODE_SZ_LARGE;
+ GenTree::s_gtNodeSizes[GT_ASG] = TREE_NODE_SZ_LARGE;
+ GenTree::s_gtNodeSizes[GT_RETURN] = TREE_NODE_SZ_LARGE;
#endif // defined(FEATURE_HFA) || defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
GenTree::s_gtNodeSizes[GT_CALL] = TREE_NODE_SZ_LARGE;
@@ -282,30 +315,32 @@ void GenTree::InitNodeSize()
#ifdef FEATURE_SIMD
GenTree::s_gtNodeSizes[GT_SIMD_CHK] = TREE_NODE_SZ_LARGE;
#endif // FEATURE_SIMD
- GenTree::s_gtNodeSizes[GT_ARR_ELEM] = TREE_NODE_SZ_LARGE;
- GenTree::s_gtNodeSizes[GT_ARR_INDEX] = TREE_NODE_SZ_LARGE;
- GenTree::s_gtNodeSizes[GT_ARR_OFFSET] = TREE_NODE_SZ_LARGE;
- GenTree::s_gtNodeSizes[GT_RET_EXPR] = TREE_NODE_SZ_LARGE;
- GenTree::s_gtNodeSizes[GT_OBJ] = TREE_NODE_SZ_LARGE;
- GenTree::s_gtNodeSizes[GT_FIELD] = TREE_NODE_SZ_LARGE;
- GenTree::s_gtNodeSizes[GT_STMT] = TREE_NODE_SZ_LARGE;
- GenTree::s_gtNodeSizes[GT_CMPXCHG] = TREE_NODE_SZ_LARGE;
- GenTree::s_gtNodeSizes[GT_QMARK] = TREE_NODE_SZ_LARGE;
- GenTree::s_gtNodeSizes[GT_LEA] = TREE_NODE_SZ_LARGE;
- GenTree::s_gtNodeSizes[GT_STORE_OBJ] = TREE_NODE_SZ_LARGE;
- GenTree::s_gtNodeSizes[GT_DYN_BLK] = TREE_NODE_SZ_LARGE;
- GenTree::s_gtNodeSizes[GT_STORE_DYN_BLK] = TREE_NODE_SZ_LARGE;
- GenTree::s_gtNodeSizes[GT_INTRINSIC] = TREE_NODE_SZ_LARGE;
- GenTree::s_gtNodeSizes[GT_ALLOCOBJ] = TREE_NODE_SZ_LARGE;
+ GenTree::s_gtNodeSizes[GT_ARR_ELEM] = TREE_NODE_SZ_LARGE;
+ GenTree::s_gtNodeSizes[GT_ARR_INDEX] = TREE_NODE_SZ_LARGE;
+ GenTree::s_gtNodeSizes[GT_ARR_OFFSET] = TREE_NODE_SZ_LARGE;
+ GenTree::s_gtNodeSizes[GT_RET_EXPR] = TREE_NODE_SZ_LARGE;
+ GenTree::s_gtNodeSizes[GT_OBJ] = TREE_NODE_SZ_LARGE;
+ GenTree::s_gtNodeSizes[GT_FIELD] = TREE_NODE_SZ_LARGE;
+ GenTree::s_gtNodeSizes[GT_STMT] = TREE_NODE_SZ_LARGE;
+ GenTree::s_gtNodeSizes[GT_CMPXCHG] = TREE_NODE_SZ_LARGE;
+ GenTree::s_gtNodeSizes[GT_QMARK] = TREE_NODE_SZ_LARGE;
+ GenTree::s_gtNodeSizes[GT_LEA] = TREE_NODE_SZ_LARGE;
+ GenTree::s_gtNodeSizes[GT_STORE_OBJ] = TREE_NODE_SZ_LARGE;
+ GenTree::s_gtNodeSizes[GT_DYN_BLK] = TREE_NODE_SZ_LARGE;
+ GenTree::s_gtNodeSizes[GT_STORE_DYN_BLK] = TREE_NODE_SZ_LARGE;
+ GenTree::s_gtNodeSizes[GT_INTRINSIC] = TREE_NODE_SZ_LARGE;
+ GenTree::s_gtNodeSizes[GT_ALLOCOBJ] = TREE_NODE_SZ_LARGE;
#if USE_HELPERS_FOR_INT_DIV
- GenTree::s_gtNodeSizes[GT_DIV] = TREE_NODE_SZ_LARGE;
- GenTree::s_gtNodeSizes[GT_UDIV] = TREE_NODE_SZ_LARGE;
- GenTree::s_gtNodeSizes[GT_MOD] = TREE_NODE_SZ_LARGE;
- GenTree::s_gtNodeSizes[GT_UMOD] = TREE_NODE_SZ_LARGE;
+ GenTree::s_gtNodeSizes[GT_DIV] = TREE_NODE_SZ_LARGE;
+ GenTree::s_gtNodeSizes[GT_UDIV] = TREE_NODE_SZ_LARGE;
+ GenTree::s_gtNodeSizes[GT_MOD] = TREE_NODE_SZ_LARGE;
+ GenTree::s_gtNodeSizes[GT_UMOD] = TREE_NODE_SZ_LARGE;
#endif
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
- GenTree::s_gtNodeSizes[GT_PUTARG_STK] = TREE_NODE_SZ_LARGE;
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+#ifdef FEATURE_PUT_STRUCT_ARG_STK
+ // TODO-Throughput: This should not need to be a large node. The object info should be
+ // obtained from the child node.
+ GenTree::s_gtNodeSizes[GT_PUTARG_STK] = TREE_NODE_SZ_LARGE;
+#endif // FEATURE_PUT_STRUCT_ARG_STK
assert(GenTree::s_gtNodeSizes[GT_RETURN] == GenTree::s_gtNodeSizes[GT_ASG]);
@@ -314,60 +349,65 @@ void GenTree::InitNodeSize()
assert(sizeof(GenTreeLclFld) <= GenTree::s_gtNodeSizes[GT_LCL_FLD]);
assert(sizeof(GenTreeLclVar) <= GenTree::s_gtNodeSizes[GT_LCL_VAR]);
- static_assert_no_msg(sizeof(GenTree) <= TREE_NODE_SZ_SMALL);
- static_assert_no_msg(sizeof(GenTreeUnOp) <= TREE_NODE_SZ_SMALL);
- static_assert_no_msg(sizeof(GenTreeOp) <= TREE_NODE_SZ_SMALL);
- static_assert_no_msg(sizeof(GenTreeVal) <= TREE_NODE_SZ_SMALL);
+ static_assert_no_msg(sizeof(GenTree) <= TREE_NODE_SZ_SMALL);
+ static_assert_no_msg(sizeof(GenTreeUnOp) <= TREE_NODE_SZ_SMALL);
+ static_assert_no_msg(sizeof(GenTreeOp) <= TREE_NODE_SZ_SMALL);
+ static_assert_no_msg(sizeof(GenTreeVal) <= TREE_NODE_SZ_SMALL);
static_assert_no_msg(sizeof(GenTreeIntConCommon) <= TREE_NODE_SZ_SMALL);
- static_assert_no_msg(sizeof(GenTreePhysReg) <= TREE_NODE_SZ_SMALL);
+ static_assert_no_msg(sizeof(GenTreePhysReg) <= TREE_NODE_SZ_SMALL);
#ifndef LEGACY_BACKEND
- static_assert_no_msg(sizeof(GenTreeJumpTable) <= TREE_NODE_SZ_SMALL);
+ static_assert_no_msg(sizeof(GenTreeJumpTable) <= TREE_NODE_SZ_SMALL);
#endif // !LEGACY_BACKEND
- static_assert_no_msg(sizeof(GenTreeIntCon) <= TREE_NODE_SZ_SMALL);
- static_assert_no_msg(sizeof(GenTreeLngCon) <= TREE_NODE_SZ_SMALL);
- static_assert_no_msg(sizeof(GenTreeDblCon) <= TREE_NODE_SZ_SMALL);
- static_assert_no_msg(sizeof(GenTreeStrCon) <= TREE_NODE_SZ_SMALL);
+ static_assert_no_msg(sizeof(GenTreeIntCon) <= TREE_NODE_SZ_SMALL);
+ static_assert_no_msg(sizeof(GenTreeLngCon) <= TREE_NODE_SZ_SMALL);
+ static_assert_no_msg(sizeof(GenTreeDblCon) <= TREE_NODE_SZ_SMALL);
+ static_assert_no_msg(sizeof(GenTreeStrCon) <= TREE_NODE_SZ_SMALL);
static_assert_no_msg(sizeof(GenTreeLclVarCommon) <= TREE_NODE_SZ_SMALL);
- static_assert_no_msg(sizeof(GenTreeLclVar) <= TREE_NODE_SZ_SMALL);
- static_assert_no_msg(sizeof(GenTreeLclFld) <= TREE_NODE_SZ_SMALL);
- static_assert_no_msg(sizeof(GenTreeRegVar) <= TREE_NODE_SZ_SMALL);
- static_assert_no_msg(sizeof(GenTreeCast) <= TREE_NODE_SZ_LARGE); // *** large node
- static_assert_no_msg(sizeof(GenTreeBox) <= TREE_NODE_SZ_LARGE); // *** large node
- static_assert_no_msg(sizeof(GenTreeField) <= TREE_NODE_SZ_LARGE); // *** large node
- static_assert_no_msg(sizeof(GenTreeArgList) <= TREE_NODE_SZ_SMALL);
- static_assert_no_msg(sizeof(GenTreeColon) <= TREE_NODE_SZ_SMALL);
- static_assert_no_msg(sizeof(GenTreeCall) <= TREE_NODE_SZ_LARGE); // *** large node
- static_assert_no_msg(sizeof(GenTreeCmpXchg) <= TREE_NODE_SZ_LARGE); // *** large node
- static_assert_no_msg(sizeof(GenTreeFptrVal) <= TREE_NODE_SZ_LARGE); // *** large node
- static_assert_no_msg(sizeof(GenTreeQmark) <= TREE_NODE_SZ_LARGE); // *** large node
- static_assert_no_msg(sizeof(GenTreeIntrinsic) <= TREE_NODE_SZ_LARGE); // *** large node
- static_assert_no_msg(sizeof(GenTreeIndex) <= TREE_NODE_SZ_LARGE); // *** large node
- static_assert_no_msg(sizeof(GenTreeArrLen) <= TREE_NODE_SZ_LARGE); // *** large node
- static_assert_no_msg(sizeof(GenTreeBoundsChk) <= TREE_NODE_SZ_LARGE); // *** large node
- static_assert_no_msg(sizeof(GenTreeArrElem) <= TREE_NODE_SZ_LARGE); // *** large node
- static_assert_no_msg(sizeof(GenTreeArrIndex) <= TREE_NODE_SZ_LARGE); // *** large node
- static_assert_no_msg(sizeof(GenTreeArrOffs) <= TREE_NODE_SZ_LARGE); // *** large node
- static_assert_no_msg(sizeof(GenTreeIndir) <= TREE_NODE_SZ_SMALL);
- static_assert_no_msg(sizeof(GenTreeStoreInd) <= TREE_NODE_SZ_SMALL);
- static_assert_no_msg(sizeof(GenTreeAddrMode) <= TREE_NODE_SZ_SMALL);
- static_assert_no_msg(sizeof(GenTreeObj) <= TREE_NODE_SZ_LARGE); // *** large node
- static_assert_no_msg(sizeof(GenTreeBlk) <= TREE_NODE_SZ_SMALL);
- static_assert_no_msg(sizeof(GenTreeRetExpr) <= TREE_NODE_SZ_LARGE); // *** large node
- static_assert_no_msg(sizeof(GenTreeStmt) <= TREE_NODE_SZ_LARGE); // *** large node
- static_assert_no_msg(sizeof(GenTreeClsVar) <= TREE_NODE_SZ_SMALL);
- static_assert_no_msg(sizeof(GenTreeArgPlace) <= TREE_NODE_SZ_SMALL);
- static_assert_no_msg(sizeof(GenTreeLabel) <= TREE_NODE_SZ_SMALL);
- static_assert_no_msg(sizeof(GenTreePhiArg) <= TREE_NODE_SZ_SMALL);
- static_assert_no_msg(sizeof(GenTreeAllocObj) <= TREE_NODE_SZ_LARGE); // *** large node
-#ifndef FEATURE_UNIX_AMD64_STRUCT_PASSING
- static_assert_no_msg(sizeof(GenTreePutArgStk) <= TREE_NODE_SZ_SMALL);
-#else // FEATURE_UNIX_AMD64_STRUCT_PASSING
- static_assert_no_msg(sizeof(GenTreePutArgStk) <= TREE_NODE_SZ_LARGE);
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+ static_assert_no_msg(sizeof(GenTreeLclVar) <= TREE_NODE_SZ_SMALL);
+ static_assert_no_msg(sizeof(GenTreeLclFld) <= TREE_NODE_SZ_SMALL);
+ static_assert_no_msg(sizeof(GenTreeRegVar) <= TREE_NODE_SZ_SMALL);
+ static_assert_no_msg(sizeof(GenTreeJumpCC) <= TREE_NODE_SZ_SMALL);
+ static_assert_no_msg(sizeof(GenTreeCast) <= TREE_NODE_SZ_LARGE); // *** large node
+ static_assert_no_msg(sizeof(GenTreeBox) <= TREE_NODE_SZ_LARGE); // *** large node
+ static_assert_no_msg(sizeof(GenTreeField) <= TREE_NODE_SZ_LARGE); // *** large node
+ static_assert_no_msg(sizeof(GenTreeArgList) <= TREE_NODE_SZ_SMALL);
+ static_assert_no_msg(sizeof(GenTreeFieldList) <= TREE_NODE_SZ_SMALL);
+ static_assert_no_msg(sizeof(GenTreeColon) <= TREE_NODE_SZ_SMALL);
+ static_assert_no_msg(sizeof(GenTreeCall) <= TREE_NODE_SZ_LARGE); // *** large node
+ static_assert_no_msg(sizeof(GenTreeCmpXchg) <= TREE_NODE_SZ_LARGE); // *** large node
+ static_assert_no_msg(sizeof(GenTreeFptrVal) <= TREE_NODE_SZ_LARGE); // *** large node
+ static_assert_no_msg(sizeof(GenTreeQmark) <= TREE_NODE_SZ_LARGE); // *** large node
+ static_assert_no_msg(sizeof(GenTreeIntrinsic) <= TREE_NODE_SZ_LARGE); // *** large node
+ static_assert_no_msg(sizeof(GenTreeIndex) <= TREE_NODE_SZ_LARGE); // *** large node
+ static_assert_no_msg(sizeof(GenTreeArrLen) <= TREE_NODE_SZ_LARGE); // *** large node
+ static_assert_no_msg(sizeof(GenTreeBoundsChk) <= TREE_NODE_SZ_LARGE); // *** large node
+ static_assert_no_msg(sizeof(GenTreeArrElem) <= TREE_NODE_SZ_LARGE); // *** large node
+ static_assert_no_msg(sizeof(GenTreeArrIndex) <= TREE_NODE_SZ_LARGE); // *** large node
+ static_assert_no_msg(sizeof(GenTreeArrOffs) <= TREE_NODE_SZ_LARGE); // *** large node
+ static_assert_no_msg(sizeof(GenTreeIndir) <= TREE_NODE_SZ_SMALL);
+ static_assert_no_msg(sizeof(GenTreeStoreInd) <= TREE_NODE_SZ_SMALL);
+ static_assert_no_msg(sizeof(GenTreeAddrMode) <= TREE_NODE_SZ_SMALL);
+ static_assert_no_msg(sizeof(GenTreeObj) <= TREE_NODE_SZ_LARGE); // *** large node
+ static_assert_no_msg(sizeof(GenTreeBlk) <= TREE_NODE_SZ_SMALL);
+ static_assert_no_msg(sizeof(GenTreeRetExpr) <= TREE_NODE_SZ_LARGE); // *** large node
+ static_assert_no_msg(sizeof(GenTreeStmt) <= TREE_NODE_SZ_LARGE); // *** large node
+ static_assert_no_msg(sizeof(GenTreeClsVar) <= TREE_NODE_SZ_SMALL);
+ static_assert_no_msg(sizeof(GenTreeArgPlace) <= TREE_NODE_SZ_SMALL);
+ static_assert_no_msg(sizeof(GenTreeLabel) <= TREE_NODE_SZ_SMALL);
+ static_assert_no_msg(sizeof(GenTreePhiArg) <= TREE_NODE_SZ_SMALL);
+ static_assert_no_msg(sizeof(GenTreeAllocObj) <= TREE_NODE_SZ_LARGE); // *** large node
+#ifndef FEATURE_PUT_STRUCT_ARG_STK
+ static_assert_no_msg(sizeof(GenTreePutArgStk) <= TREE_NODE_SZ_SMALL);
+#else // FEATURE_PUT_STRUCT_ARG_STK
+ // TODO-Throughput: This should not need to be a large node. The object info should be
+ // obtained from the child node.
+ static_assert_no_msg(sizeof(GenTreePutArgStk) <= TREE_NODE_SZ_LARGE);
+#endif // FEATURE_PUT_STRUCT_ARG_STK
#ifdef FEATURE_SIMD
- static_assert_no_msg(sizeof(GenTreeSIMD) <= TREE_NODE_SZ_SMALL);
+ static_assert_no_msg(sizeof(GenTreeSIMD) <= TREE_NODE_SZ_SMALL);
#endif // FEATURE_SIMD
+ // clang-format on
}
size_t GenTree::GetNodeSize() const
@@ -394,6 +434,88 @@ bool GenTree::IsNodeProperlySized() const
}
#endif
+/*****************************************************************************
+ *
+ * When 'NODEBASH_STATS' is enabled in "jit.h" we record all instances of
+ * an existing GenTree node having its operator changed. This can be useful
+ * for two (related) things - to see what is being bashed (and what isn't),
+ * and to verify that the existing choices for what nodes are marked 'large'
+ * are reasonable (to minimize "wasted" space).
+ *
+ * And yes, the hash function / logic is simplistic, but it is conflict-free
+ * and transparent for what we need.
+ */
+
+#if NODEBASH_STATS
+
+#define BASH_HASH_SIZE 211
+
+inline hashme(genTreeOps op1, genTreeOps op2)
+{
+ return ((op1 * 104729) ^ (op2 * 56569)) % BASH_HASH_SIZE;
+}
+
+struct BashHashDsc
+{
+ unsigned __int32 bhFullHash; // the hash value (unique for all old->new pairs)
+ unsigned __int32 bhCount; // the same old->new bashings seen so far
+ unsigned __int8 bhOperOld; // original gtOper
+ unsigned __int8 bhOperNew; // new gtOper
+};
+
+static BashHashDsc BashHash[BASH_HASH_SIZE];
+
+void GenTree::RecordOperBashing(genTreeOps operOld, genTreeOps operNew)
+{
+ unsigned hash = hashme(operOld, operNew);
+ BashHashDsc* desc = BashHash + hash;
+
+ if (desc->bhFullHash != hash)
+ {
+ noway_assert(desc->bhCount == 0); // if this ever fires, need fix the hash fn
+ desc->bhFullHash = hash;
+ }
+
+ desc->bhCount += 1;
+ desc->bhOperOld = operOld;
+ desc->bhOperNew = operNew;
+}
+
+void GenTree::ReportOperBashing(FILE* f)
+{
+ unsigned total = 0;
+
+ fflush(f);
+
+ fprintf(f, "\n");
+ fprintf(f, "Bashed gtOper stats:\n");
+ fprintf(f, "\n");
+ fprintf(f, " Old operator New operator #bytes old->new Count\n");
+ fprintf(f, " ---------------------------------------------------------------\n");
+
+ for (unsigned h = 0; h < BASH_HASH_SIZE; h++)
+ {
+ unsigned count = BashHash[h].bhCount;
+ if (count == 0)
+ continue;
+
+ unsigned opOld = BashHash[h].bhOperOld;
+ unsigned opNew = BashHash[h].bhOperNew;
+
+ fprintf(f, " GT_%-13s -> GT_%-13s [size: %3u->%3u] %c %7u\n", OpName((genTreeOps)opOld),
+ OpName((genTreeOps)opNew), s_gtTrueSizes[opOld], s_gtTrueSizes[opNew],
+ (s_gtTrueSizes[opOld] < s_gtTrueSizes[opNew]) ? 'X' : ' ', count);
+ total += count;
+ }
+ fprintf(f, "\n");
+ fprintf(f, "Total bashings: %u\n", total);
+ fprintf(f, "\n");
+
+ fflush(f);
+}
+
+#endif // NODEBASH_STATS
+
#else // SMALL_TREE_NODES
#ifdef DEBUG
@@ -407,6 +529,71 @@ bool GenTree::IsNodeProperlySized() const
/*****************************************************************************/
+#if MEASURE_NODE_SIZE
+
+void GenTree::DumpNodeSizes(FILE* fp)
+{
+// Dump the sizes of the various GenTree flavors
+
+#if SMALL_TREE_NODES
+ fprintf(fp, "Small tree node size = %3u bytes\n", TREE_NODE_SZ_SMALL);
+#endif
+ fprintf(fp, "Large tree node size = %3u bytes\n", TREE_NODE_SZ_LARGE);
+ fprintf(fp, "\n");
+
+#if SMALL_TREE_NODES
+
+ // Verify that node sizes are set kosherly and dump sizes
+ for (unsigned op = GT_NONE + 1; op < GT_COUNT; op++)
+ {
+ unsigned needSize = s_gtTrueSizes[op];
+ unsigned nodeSize = s_gtNodeSizes[op];
+
+ const char* structNm = OpStructName((genTreeOps)op);
+ const char* operName = OpName((genTreeOps)op);
+
+ bool repeated = false;
+
+ // Have we seen this struct flavor before?
+ for (unsigned mop = GT_NONE + 1; mop < op; mop++)
+ {
+ if (strcmp(structNm, OpStructName((genTreeOps)mop)) == 0)
+ {
+ repeated = true;
+ break;
+ }
+ }
+
+ // Don't repeat the same GenTree flavor unless we have an error
+ if (!repeated || needSize > nodeSize)
+ {
+ unsigned sizeChar = '?';
+
+ if (nodeSize == TREE_NODE_SZ_SMALL)
+ sizeChar = 'S';
+ else if (nodeSize == TREE_NODE_SZ_LARGE)
+ sizeChar = 'L';
+
+ fprintf(fp, "GT_%-16s ... %-19s = %3u bytes (%c)", operName, structNm, needSize, sizeChar);
+ if (needSize > nodeSize)
+ {
+ fprintf(fp, " -- ERROR -- allocation is only %u bytes!", nodeSize);
+ }
+ else if (needSize <= TREE_NODE_SZ_SMALL && nodeSize == TREE_NODE_SZ_LARGE)
+ {
+ fprintf(fp, " ... could be small");
+ }
+
+ fprintf(fp, "\n");
+ }
+ }
+
+#endif
+}
+
+#endif // MEASURE_NODE_SIZE
+/*****************************************************************************/
+
// make sure these get instantiated, because it's not in a header file
// (emulating the c++ 'export' keyword here)
// VC appears to be somewhat unpredictable about whether they end up in the .obj file without this
@@ -965,11 +1152,12 @@ Compiler::fgWalkResult Compiler::fgWalkTreePostRec(GenTreePtr* pTree, fgWalkData
}
break;
- case GT_LIST:
+ case GT_FIELD_LIST:
{
- GenTreeArgList* list = tree->AsArgList();
- if (list->IsAggregate())
+ GenTreeFieldList* list = tree->AsFieldList();
+ if (list->IsFieldListHead())
{
+ GenTreeFieldList* list = tree->AsFieldList();
for (; list != nullptr; list = list->Rest())
{
result = fgWalkTreePostRec<computeStack>(&list->gtOp1, fgWalkData);
@@ -978,12 +1166,8 @@ Compiler::fgWalkResult Compiler::fgWalkTreePostRec(GenTreePtr* pTree, fgWalkData
return result;
}
}
- break;
}
-
- // GT_LIST nodes that do not represent aggregate arguments intentionally fall through to the
- // default node processing below.
- __fallthrough;
+ break;
}
default:
@@ -1765,6 +1949,66 @@ bool GenTreeCall::IsHelperCall(Compiler* compiler, unsigned helper) const
return IsHelperCall(compiler->eeFindHelper(helper));
}
+//------------------------------------------------------------------------
+// GenTreeCall::ReplaceCallOperand:
+// Replaces a given operand to a call node and updates the call
+// argument table if necessary.
+//
+// Arguments:
+// useEdge - the use edge that points to the operand to be replaced.
+// replacement - the replacement node.
+//
+void GenTreeCall::ReplaceCallOperand(GenTree** useEdge, GenTree* replacement)
+{
+ assert(useEdge != nullptr);
+ assert(replacement != nullptr);
+ assert(TryGetUse(*useEdge, &useEdge));
+
+ GenTree* originalOperand = *useEdge;
+ *useEdge = replacement;
+
+ const bool isArgument =
+ (replacement != gtControlExpr) &&
+ ((gtCallType != CT_INDIRECT) || ((replacement != gtCallCookie) && (replacement != gtCallAddr)));
+
+ if (isArgument)
+ {
+ if ((originalOperand->gtFlags & GTF_LATE_ARG) != 0)
+ {
+ replacement->gtFlags |= GTF_LATE_ARG;
+ }
+ else
+ {
+ assert((replacement->gtFlags & GTF_LATE_ARG) == 0);
+
+ fgArgTabEntryPtr fp = Compiler::gtArgEntryByNode(this, originalOperand);
+ assert(fp->node == originalOperand);
+ fp->node = replacement;
+ }
+ }
+}
+
+//-------------------------------------------------------------------------
+// AreArgsComplete: Determine if this GT_CALL node's arguments have been processed.
+//
+// Return Value:
+// Returns true if fgMorphArgs has processed the arguments.
+//
+bool GenTreeCall::AreArgsComplete() const
+{
+ if (fgArgInfo == nullptr)
+ {
+ return false;
+ }
+ if (fgArgInfo->AreArgsComplete())
+ {
+ assert((gtCallLateArgs != nullptr) || !fgArgInfo->HasRegArgs());
+ return true;
+ }
+ assert(gtCallArgs == nullptr);
+ return false;
+}
+
/*****************************************************************************
*
* Returns non-zero if the two trees are identical.
@@ -2071,7 +2315,9 @@ AGAIN:
#ifdef FEATURE_READYTORUN_COMPILER
if (op1->gtCall.gtEntryPoint.addr != op2->gtCall.gtEntryPoint.addr)
+ {
return false;
+ }
#endif
}
else
@@ -2560,8 +2806,8 @@ AGAIN:
hash = genTreeHashAdd(hash, tree->gtAllocObj.gtNewHelper);
break;
case GT_OBJ:
- hash = genTreeHashAdd(hash, static_cast<unsigned>(
- reinterpret_cast<uintptr_t>(tree->gtObj.gtClass)));
+ hash =
+ genTreeHashAdd(hash, static_cast<unsigned>(reinterpret_cast<uintptr_t>(tree->gtObj.gtClass)));
break;
// For the ones below no extra argument matters for comparison.
@@ -3196,6 +3442,11 @@ GenTreePtr Compiler::gtReverseCond(GenTree* tree)
tree->gtFlags ^= GTF_RELOP_NAN_UN;
}
}
+ else if (tree->OperGet() == GT_JCC)
+ {
+ GenTreeJumpCC* jcc = tree->AsJumpCC();
+ jcc->gtCondition = GenTree::ReverseRelop(jcc->gtCondition);
+ }
else
{
tree = gtNewOperNode(GT_NOT, TYP_INT, tree);
@@ -3257,77 +3508,136 @@ bool GenTree::gtIsValid64RsltMul()
#endif // DEBUG
-/*****************************************************************************
- *
- * Figure out the evaluation order for a list of values.
- */
+//------------------------------------------------------------------------------
+// gtSetListOrder : Figure out the evaluation order for a list of values.
+//
+//
+// Arguments:
+// list - List to figure out the evaluation order for
+// isListCallArgs - True iff the list is a list of call arguments
+// callArgsInRegs - True iff the list is a list of call arguments and they are passed in registers
+//
+// Return Value:
+// True if the operation can be a root of a bitwise rotation tree; false otherwise.
-unsigned Compiler::gtSetListOrder(GenTree* list, bool regs)
+unsigned Compiler::gtSetListOrder(GenTree* list, bool isListCallArgs, bool callArgsInRegs)
{
- assert(list && list->IsList());
+ assert((list != nullptr) && list->OperIsAnyList());
+ assert(!callArgsInRegs || isListCallArgs);
- unsigned level = 0;
- unsigned ftreg = 0;
- unsigned costSz = 0;
- unsigned costEx = 0;
+ ArrayStack<GenTree*> listNodes(this);
+ do
+ {
+ listNodes.Push(list);
+ list = list->gtOp.gtOp2;
+ } while ((list != nullptr) && (list->OperIsAnyList()));
+
+ unsigned nxtlvl = (list == nullptr) ? 0 : gtSetEvalOrder(list);
+ while (listNodes.Height() > 0)
+ {
#if FEATURE_STACK_FP_X87
- /* Save the current FP stack level since an argument list
- * will implicitly pop the FP stack when pushing the argument */
- unsigned FPlvlSave = codeGen->genGetFPstkLevel();
+ /* Save the current FP stack level since an argument list
+ * will implicitly pop the FP stack when pushing the argument */
+ unsigned FPlvlSave = codeGen->genGetFPstkLevel();
#endif // FEATURE_STACK_FP_X87
- GenTreePtr next = list->gtOp.gtOp2;
+ list = listNodes.Pop();
+ assert(list && list->OperIsAnyList());
+ GenTreePtr next = list->gtOp.gtOp2;
- if (next)
- {
- unsigned nxtlvl = gtSetListOrder(next, regs);
+ unsigned level = 0;
+ unsigned ftreg = 0;
- ftreg |= next->gtRsvdRegs;
+ // TODO: Do we have to compute costs differently for argument lists and
+ // all other lists?
+ // https://github.com/dotnet/coreclr/issues/7095
+ unsigned costSz = (isListCallArgs || (next == nullptr)) ? 0 : 1;
+ unsigned costEx = (isListCallArgs || (next == nullptr)) ? 0 : 1;
- if (level < nxtlvl)
+ if (next != nullptr)
{
- level = nxtlvl;
+ ftreg |= next->gtRsvdRegs;
+ if (isListCallArgs)
+ {
+ if (level < nxtlvl)
+ {
+ level = nxtlvl;
+ }
+ }
+ costEx += next->gtCostEx;
+ costSz += next->gtCostSz;
}
- costEx += next->gtCostEx;
- costSz += next->gtCostSz;
- }
- GenTreePtr op1 = list->gtOp.gtOp1;
- unsigned lvl = gtSetEvalOrder(op1);
+ GenTreePtr op1 = list->gtOp.gtOp1;
+ unsigned lvl = gtSetEvalOrder(op1);
#if FEATURE_STACK_FP_X87
- /* restore the FP level */
- codeGen->genResetFPstkLevel(FPlvlSave);
+ // restore the FP level
+ codeGen->genResetFPstkLevel(FPlvlSave);
#endif // FEATURE_STACK_FP_X87
- list->gtRsvdRegs = (regMaskSmall)(ftreg | op1->gtRsvdRegs);
+ list->gtRsvdRegs = (regMaskSmall)(ftreg | op1->gtRsvdRegs);
- if (level < lvl)
- {
- level = lvl;
- }
+ // Swap the level counts
+ if (list->gtFlags & GTF_REVERSE_OPS)
+ {
+ unsigned tmpl;
- if (op1->gtCostEx != 0)
- {
- costEx += op1->gtCostEx;
- costEx += regs ? 0 : IND_COST_EX;
- }
+ tmpl = lvl;
+ lvl = nxtlvl;
+ nxtlvl = tmpl;
+ }
- if (op1->gtCostSz != 0)
- {
- costSz += op1->gtCostSz;
+ // TODO: Do we have to compute levels differently for argument lists and
+ // all other lists?
+ // https://github.com/dotnet/coreclr/issues/7095
+ if (isListCallArgs)
+ {
+ if (level < lvl)
+ {
+ level = lvl;
+ }
+ }
+ else
+ {
+ if (lvl < 1)
+ {
+ level = nxtlvl;
+ }
+ else if (lvl == nxtlvl)
+ {
+ level = lvl + 1;
+ }
+ else
+ {
+ level = lvl;
+ }
+ }
+
+ if (op1->gtCostEx != 0)
+ {
+ costEx += op1->gtCostEx;
+ costEx += (callArgsInRegs || !isListCallArgs) ? 0 : IND_COST_EX;
+ }
+
+ if (op1->gtCostSz != 0)
+ {
+ costSz += op1->gtCostSz;
#ifdef _TARGET_XARCH_
- if (regs) // push is smaller than mov to reg
+ if (callArgsInRegs) // push is smaller than mov to reg
#endif
- {
- costSz += 1;
+ {
+ costSz += 1;
+ }
}
- }
- list->SetCosts(costEx, costSz);
+ list->SetCosts(costEx, costSz);
- return level;
+ nxtlvl = level;
+ }
+
+ return nxtlvl;
}
/*****************************************************************************
@@ -3363,17 +3673,8 @@ void Compiler::gtWalkOp(GenTree** op1WB, GenTree** op2WB, GenTree* adr, bool con
{
GenTreePtr op1 = *op1WB;
GenTreePtr op2 = *op2WB;
- GenTreePtr op1EffectiveVal;
- if (op1->gtOper == GT_COMMA)
- {
- op1EffectiveVal = op1->gtEffectiveVal();
- if ((op1EffectiveVal->gtOper == GT_ADD) && (!op1EffectiveVal->gtOverflow()) &&
- (!constOnly || (op1EffectiveVal->gtOp.gtOp2->IsCnsIntOrI())))
- {
- op1 = op1EffectiveVal;
- }
- }
+ op1 = op1->gtEffectiveVal();
// Now we look for op1's with non-overflow GT_ADDs [of constants]
while ((op1->gtOper == GT_ADD) && (!op1->gtOverflow()) && (!constOnly || (op1->gtOp.gtOp2->IsCnsIntOrI())))
@@ -3398,20 +3699,12 @@ void Compiler::gtWalkOp(GenTree** op1WB, GenTree** op2WB, GenTree* adr, bool con
op2 = tmp;
}
- if (op1->gtOper == GT_COMMA)
- {
- op1EffectiveVal = op1->gtEffectiveVal();
- if ((op1EffectiveVal->gtOper == GT_ADD) && (!op1EffectiveVal->gtOverflow()) &&
- (!constOnly || (op1EffectiveVal->gtOp.gtOp2->IsCnsIntOrI())))
- {
- op1 = op1EffectiveVal;
- }
- }
-
if (!constOnly && ((op2 == adr) || (!op2->IsCnsIntOrI())))
{
break;
}
+
+ op1 = op1->gtEffectiveVal();
}
*op1WB = op1;
@@ -3445,15 +3738,7 @@ GenTreePtr Compiler::gtWalkOpEffectiveVal(GenTreePtr op)
{
for (;;)
{
- if (op->gtOper == GT_COMMA)
- {
- GenTreePtr opEffectiveVal = op->gtEffectiveVal();
- if ((opEffectiveVal->gtOper == GT_ADD) && (!opEffectiveVal->gtOverflow()) &&
- (opEffectiveVal->gtOp.gtOp2->IsCnsIntOrI()))
- {
- op = opEffectiveVal;
- }
- }
+ op = op->gtEffectiveVal();
if ((op->gtOper != GT_ADD) || op->gtOverflow() || !op->gtOp.gtOp2->IsCnsIntOrI())
{
@@ -3980,6 +4265,7 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree)
break;
case GT_LIST:
+ case GT_FIELD_LIST:
case GT_NOP:
costEx = 0;
costSz = 0;
@@ -4671,6 +4957,14 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree)
goto DONE;
+ case GT_LIST:
+ case GT_FIELD_LIST:
+ {
+ const bool isListCallArgs = false;
+ const bool callArgsInRegs = false;
+ return gtSetListOrder(tree, isListCallArgs, callArgsInRegs);
+ }
+
default:
break;
}
@@ -5025,6 +5319,7 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree)
break;
case GT_LIST:
+ case GT_FIELD_LIST:
break;
case GT_SUB:
@@ -5123,7 +5418,9 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree)
#if FEATURE_STACK_FP_X87
FPlvlSave = codeGen->genGetFPstkLevel();
#endif // FEATURE_STACK_FP_X87
- lvl2 = gtSetListOrder(tree->gtCall.gtCallArgs, false);
+ const bool isListCallArgs = true;
+ const bool callArgsInRegs = false;
+ lvl2 = gtSetListOrder(tree->gtCall.gtCallArgs, isListCallArgs, callArgsInRegs);
if (level < lvl2)
{
level = lvl2;
@@ -5145,7 +5442,9 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree)
#if FEATURE_STACK_FP_X87
FPlvlSave = codeGen->genGetFPstkLevel();
#endif // FEATURE_STACK_FP_X87
- lvl2 = gtSetListOrder(tree->gtCall.gtCallLateArgs, true);
+ const bool isListCallArgs = true;
+ const bool callArgsInRegs = true;
+ lvl2 = gtSetListOrder(tree->gtCall.gtCallLateArgs, isListCallArgs, callArgsInRegs);
if (level < lvl2)
{
level = lvl2;
@@ -5189,7 +5488,7 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree)
costSz += 2;
}
}
- else if ((opts.eeFlags & CORJIT_FLG_PREJIT) == 0)
+ else if (!opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT))
{
costEx += 2;
costSz += 6;
@@ -5789,11 +6088,11 @@ bool GenTree::IsAddWithI32Const(GenTreePtr* addr, int* offset)
// 'parent' must be non-null
//
// Notes:
-// When FEATURE_MULTIREG_ARGS is defined we can get here with GT_LDOBJ tree.
+// When FEATURE_MULTIREG_ARGS is defined we can get here with GT_OBJ tree.
// This happens when we have a struct that is passed in multiple registers.
//
// Also note that when FEATURE_UNIX_AMD64_STRUCT_PASSING is defined the GT_LDOBJ
-// later gets converted to a GT_LIST with two GT_LCL_FLDs in Lower/LowerXArch.
+// later gets converted to a GT_FIELD_LIST with two GT_LCL_FLDs in Lower/LowerXArch.
//
GenTreePtr* GenTree::gtGetChildPointer(GenTreePtr parent)
@@ -5952,6 +6251,9 @@ GenTreePtr* GenTree::gtGetChildPointer(GenTreePtr parent)
bool GenTree::TryGetUse(GenTree* def, GenTree*** use)
{
+ assert(def != nullptr);
+ assert(use != nullptr);
+
for (GenTree** useEdge : UseEdges())
{
if (*useEdge == def)
@@ -5965,6 +6267,32 @@ bool GenTree::TryGetUse(GenTree* def, GenTree*** use)
}
//------------------------------------------------------------------------
+// GenTree::ReplaceOperand:
+// Replace a given operand to this node with a new operand. If the
+// current node is a call node, this will also udpate the call
+// argument table if necessary.
+//
+// Arguments:
+// useEdge - the use edge that points to the operand to be replaced.
+// replacement - the replacement node.
+//
+void GenTree::ReplaceOperand(GenTree** useEdge, GenTree* replacement)
+{
+ assert(useEdge != nullptr);
+ assert(replacement != nullptr);
+ assert(TryGetUse(*useEdge, &useEdge));
+
+ if (OperGet() == GT_CALL)
+ {
+ AsCall()->ReplaceCallOperand(useEdge, replacement);
+ }
+ else
+ {
+ *useEdge = replacement;
+ }
+}
+
+//------------------------------------------------------------------------
// gtGetParent: Get the parent of this node, and optionally capture the
// pointer to the child so that it can be modified.
//
@@ -6500,16 +6828,15 @@ GenTreeCall* Compiler::gtNewCallNode(
#endif // LEGACY_BACKEND
#ifdef FEATURE_READYTORUN_COMPILER
- node->gtCall.gtEntryPoint.addr = nullptr;
+ node->gtEntryPoint.addr = nullptr;
#endif
#if defined(DEBUG) || defined(INLINE_DATA)
// These get updated after call node is built.
- node->gtCall.gtInlineObservation = InlineObservation::CALLEE_UNUSED_INITIAL;
- node->gtCall.gtRawILOffset = BAD_IL_OFFSET;
+ node->gtInlineObservation = InlineObservation::CALLEE_UNUSED_INITIAL;
+ node->gtRawILOffset = BAD_IL_OFFSET;
#endif
-#ifdef DEBUGGING_SUPPORT
// Spec: Managed Retval sequence points needs to be generated while generating debug info for debuggable code.
//
// Implementation note: if not generating MRV info genCallSite2ILOffsetMap will be NULL and
@@ -6537,7 +6864,6 @@ GenTreeCall* Compiler::gtNewCallNode(
assert(!genCallSite2ILOffsetMap->Lookup(node, &value));
genCallSite2ILOffsetMap->Set(node, ilOffset);
}
-#endif
// Initialize gtOtherRegs
node->ClearOtherRegs();
@@ -6545,6 +6871,22 @@ GenTreeCall* Compiler::gtNewCallNode(
// Initialize spill flags of gtOtherRegs
node->ClearOtherRegFlags();
+#if defined(_TARGET_X86_) && !defined(LEGACY_BACKEND)
+ // Initialize the multi-reg long return info if necessary
+ if (varTypeIsLong(node))
+ {
+ // The return type will remain as the incoming long type
+ node->gtReturnType = node->gtType;
+
+ // Initialize Return type descriptor of call node
+ ReturnTypeDesc* retTypeDesc = node->GetReturnTypeDesc();
+ retTypeDesc->InitializeLongReturnType(this);
+
+ // must be a long returned in two registers
+ assert(retTypeDesc->GetReturnRegCount() == 2);
+ }
+#endif // defined(_TARGET_X86_) && !defined(_LEGACY_BACKEND_)
+
return node;
}
@@ -6648,29 +6990,6 @@ GenTreeArgList* Compiler::gtNewArgList(GenTreePtr arg1, GenTreePtr arg2)
return new (this, GT_LIST) GenTreeArgList(arg1, gtNewArgList(arg2));
}
-//------------------------------------------------------------------------
-// Compiler::gtNewAggregate:
-// Creates a new aggregate argument node. These nodes are used to
-// represent arguments that are composed of multiple values (e.g.
-// the lclVars that represent the fields of a promoted struct).
-//
-// Note that aggregate arguments are currently represented by GT_LIST
-// nodes that are marked with the GTF_LIST_AGGREGATE flag. This
-// representation may be changed in the future to instead use its own
-// node type (e.g. GT_AGGREGATE).
-//
-// Arguments:
-// firstElement - The first element in the aggregate's list of values.
-//
-// Returns:
-// The newly-created aggregate node.
-GenTreeArgList* Compiler::gtNewAggregate(GenTree* firstElement)
-{
- GenTreeArgList* agg = gtNewArgList(firstElement);
- agg->gtFlags |= GTF_LIST_AGGREGATE;
- return agg;
-}
-
/*****************************************************************************
*
* Create a list out of the three values.
@@ -6741,7 +7060,7 @@ fgArgTabEntryPtr Compiler::gtArgEntryByNode(GenTreePtr call, GenTreePtr node)
#endif // PROTO_JIT
else if (curArgTabEntry->parent != nullptr)
{
- assert(curArgTabEntry->parent->IsList());
+ assert(curArgTabEntry->parent->OperIsList());
if (curArgTabEntry->parent->Current() == node)
{
return curArgTabEntry;
@@ -6956,17 +7275,32 @@ GenTree* Compiler::gtNewBlockVal(GenTreePtr addr, unsigned size)
{
// By default we treat this as an opaque struct type with known size.
var_types blkType = TYP_STRUCT;
-#if FEATURE_SIMD
if ((addr->gtOper == GT_ADDR) && (addr->gtGetOp1()->OperGet() == GT_LCL_VAR))
{
GenTree* val = addr->gtGetOp1();
- if (varTypeIsSIMD(val) && (genTypeSize(val->TypeGet()) == size))
+#if FEATURE_SIMD
+ if (varTypeIsSIMD(val))
{
- blkType = val->TypeGet();
- return addr->gtGetOp1();
+ if (genTypeSize(val->TypeGet()) == size)
+ {
+ blkType = val->TypeGet();
+ return addr->gtGetOp1();
+ }
}
- }
+ else
#endif // FEATURE_SIMD
+#ifndef LEGACY_BACKEND
+ if (val->TypeGet() == TYP_STRUCT)
+ {
+ GenTreeLclVarCommon* lcl = addr->gtGetOp1()->AsLclVarCommon();
+ LclVarDsc* varDsc = &(lvaTable[lcl->gtLclNum]);
+ if ((varDsc->TypeGet() == TYP_STRUCT) && (varDsc->lvExactSize == size))
+ {
+ return addr->gtGetOp1();
+ }
+ }
+#endif // !LEGACY_BACKEND
+ }
return new (this, GT_BLK) GenTreeBlk(GT_BLK, blkType, addr, size);
}
@@ -6979,7 +7313,10 @@ GenTree* Compiler::gtNewBlockVal(GenTreePtr addr, unsigned size)
// if FEATURE_SIMD is enabled and the source has a SIMD type.
// isVolatile - Is this marked as volatile memory?
-GenTree* Compiler::gtNewCpObjNode(GenTreePtr dstAddr, GenTreePtr srcAddr, CORINFO_CLASS_HANDLE structHnd, bool isVolatile)
+GenTree* Compiler::gtNewCpObjNode(GenTreePtr dstAddr,
+ GenTreePtr srcAddr,
+ CORINFO_CLASS_HANDLE structHnd,
+ bool isVolatile)
{
GenTreePtr lhs = gtNewStructVal(structHnd, dstAddr);
GenTree* src = nullptr;
@@ -7046,10 +7383,10 @@ void GenTreeIntCon::FixupInitBlkValue(var_types asgType)
}
#endif // _TARGET_64BIT_
- // Make the type used in the GT_IND node match for evaluation types.
+ // Make the type match for evaluation types.
gtType = asgType;
- // if we are using an GT_INITBLK on a GC type the value being assigned has to be zero (null).
+ // if we are initializing a GC type the value being assigned must be zero (null).
assert(!varTypeIsGC(asgType) || (cns == 0));
}
@@ -7057,7 +7394,7 @@ void GenTreeIntCon::FixupInitBlkValue(var_types asgType)
}
}
-//
+//
//------------------------------------------------------------------------
// gtBlockOpInit: Initializes a BlkOp GenTree
//
@@ -7066,7 +7403,7 @@ void GenTreeIntCon::FixupInitBlkValue(var_types asgType)
// dst - the target (destination) we want to either initialize or copy to.
// src - the init value for InitBlk or the source struct for CpBlk/CpObj.
// isVolatile - specifies whether this node is a volatile memory operation.
-//
+//
// Assumptions:
// 'result' is an assignment that is newly constructed.
// If 'dst' is TYP_STRUCT, then it must be a block node or lclVar.
@@ -7156,9 +7493,6 @@ void Compiler::gtBlockOpInit(GenTreePtr result, GenTreePtr dst, GenTreePtr srcOr
result->gtFlags |= dst->gtFlags & GTF_ALL_EFFECT;
result->gtFlags |= result->gtOp.gtOp2->gtFlags & GTF_ALL_EFFECT;
- // TODO-1stClassStructs: This should be done only if the destination is non-local.
- result->gtFlags |= (GTF_GLOB_REF | GTF_ASG);
-
// REVERSE_OPS is necessary because the use must occur before the def
result->gtFlags |= GTF_REVERSE_OPS;
@@ -7229,12 +7563,20 @@ GenTree* Compiler::gtNewBlkOpNode(
srcOrFillVal = srcOrFillVal->gtGetOp1()->gtGetOp1();
}
}
-
- GenTree* result = gtNewAssignNode(dst, srcOrFillVal);
- if (!isCopyBlock)
+ else
{
- result->gtFlags |= GTF_BLK_INIT;
+ // InitBlk
+ assert(varTypeIsIntegral(srcOrFillVal));
+ if (varTypeIsStruct(dst))
+ {
+ if (!srcOrFillVal->IsIntegralConst(0))
+ {
+ srcOrFillVal = gtNewOperNode(GT_INIT_VAL, TYP_INT, srcOrFillVal);
+ }
+ }
}
+
+ GenTree* result = gtNewAssignNode(dst, srcOrFillVal);
gtBlockOpInit(result, dst, srcOrFillVal, isVolatile);
return result;
}
@@ -7376,17 +7718,30 @@ GenTreePtr Compiler::gtClone(GenTree* tree, bool complexOK)
return copy;
}
-/*****************************************************************************
- *
- * Clones the given tree value and returns a copy of the given tree. Any
- * references to local variable varNum will be replaced with the integer
- * constant varVal.
- */
+//------------------------------------------------------------------------
+// gtCloneExpr: Create a copy of `tree`, adding flags `addFlags`, mapping
+// local `varNum` to int constant `varVal` if it appears at
+// the root, and mapping uses of local `deepVarNum` to constant
+// `deepVarVal` if they occur beyond the root.
+//
+// Arguments:
+// tree - GenTree to create a copy of
+// addFlags - GTF_* flags to add to the copied tree nodes
+// varNum - lclNum to replace at the root, or ~0 for no root replacement
+// varVal - If replacing at root, replace local `varNum` with IntCns `varVal`
+// deepVarNum - lclNum to replace uses of beyond the root, or ~0 for no replacement
+// deepVarVal - If replacing beyond root, replace `deepVarNum` with IntCns `deepVarVal`
+//
+// Return Value:
+// A copy of the given tree with the replacements and added flags specified.
+//
+// Notes:
+// Top-level callers should generally call the overload that doesn't have
+// the explicit `deepVarNum` and `deepVarVal` parameters; those are used in
+// recursive invocations to avoid replacing defs.
-GenTreePtr Compiler::gtCloneExpr(GenTree* tree,
- unsigned addFlags,
- unsigned varNum, // = (unsigned)-1
- int varVal)
+GenTreePtr Compiler::gtCloneExpr(
+ GenTree* tree, unsigned addFlags, unsigned varNum, int varVal, unsigned deepVarNum, int deepVarVal)
{
if (tree == nullptr)
{
@@ -7442,6 +7797,10 @@ GenTreePtr Compiler::gtCloneExpr(GenTree* tree,
if (tree->gtLclVarCommon.gtLclNum == varNum)
{
copy = gtNewIconNode(varVal, tree->gtType);
+ if (tree->gtFlags & GTF_VAR_ARR_INDEX)
+ {
+ copy->LabelIndex(this);
+ }
}
else
{
@@ -7572,16 +7931,16 @@ GenTreePtr Compiler::gtCloneExpr(GenTree* tree,
// The nodes below this are not bashed, so they can be allocated at their individual sizes.
case GT_LIST:
- // This is ridiculous, but would go away if we made a stronger distinction between argument lists, whose
- // second argument *must* be an arglist*, and the uses of LIST in copyblk and initblk.
- if (tree->gtOp.gtOp2 != nullptr && tree->gtOp.gtOp2->OperGet() == GT_LIST)
- {
- copy = new (this, GT_LIST) GenTreeArgList(tree->gtOp.gtOp1, tree->gtOp.gtOp2->AsArgList());
- }
- else
- {
- copy = new (this, GT_LIST) GenTreeOp(GT_LIST, TYP_VOID, tree->gtOp.gtOp1, tree->gtOp.gtOp2);
- }
+ assert((tree->gtOp.gtOp2 == nullptr) || tree->gtOp.gtOp2->OperIsList());
+ copy = new (this, GT_LIST) GenTreeArgList(tree->gtOp.gtOp1);
+ copy->gtOp.gtOp2 = tree->gtOp.gtOp2;
+ break;
+
+ case GT_FIELD_LIST:
+ copy = new (this, GT_FIELD_LIST) GenTreeFieldList(tree->gtOp.gtOp1, tree->AsFieldList()->gtFieldOffset,
+ tree->AsFieldList()->gtFieldType, nullptr);
+ copy->gtOp.gtOp2 = tree->gtOp.gtOp2;
+ copy->gtFlags = (copy->gtFlags & ~GTF_FIELD_LIST_HEAD) | (tree->gtFlags & GTF_FIELD_LIST_HEAD);
break;
case GT_INDEX:
@@ -7608,8 +7967,9 @@ GenTreePtr Compiler::gtCloneExpr(GenTree* tree,
case GT_ARR_INDEX:
copy = new (this, GT_ARR_INDEX)
- GenTreeArrIndex(tree->TypeGet(), gtCloneExpr(tree->gtArrIndex.ArrObj(), addFlags, varNum, varVal),
- gtCloneExpr(tree->gtArrIndex.IndexExpr(), addFlags, varNum, varVal),
+ GenTreeArrIndex(tree->TypeGet(),
+ gtCloneExpr(tree->gtArrIndex.ArrObj(), addFlags, deepVarNum, deepVarVal),
+ gtCloneExpr(tree->gtArrIndex.IndexExpr(), addFlags, deepVarNum, deepVarVal),
tree->gtArrIndex.gtCurrDim, tree->gtArrIndex.gtArrRank,
tree->gtArrIndex.gtArrElemType);
break;
@@ -7708,12 +8068,20 @@ GenTreePtr Compiler::gtCloneExpr(GenTree* tree,
if (tree->gtOp.gtOp1)
{
- copy->gtOp.gtOp1 = gtCloneExpr(tree->gtOp.gtOp1, addFlags, varNum, varVal);
+ if (tree->gtOper == GT_ASG)
+ {
+ // Don't replace varNum if it appears as the LHS of an assign.
+ copy->gtOp.gtOp1 = gtCloneExpr(tree->gtOp.gtOp1, addFlags, -1, 0, deepVarNum, deepVarVal);
+ }
+ else
+ {
+ copy->gtOp.gtOp1 = gtCloneExpr(tree->gtOp.gtOp1, addFlags, deepVarNum, deepVarVal);
+ }
}
if (tree->gtGetOp2())
{
- copy->gtOp.gtOp2 = gtCloneExpr(tree->gtOp.gtOp2, addFlags, varNum, varVal);
+ copy->gtOp.gtOp2 = gtCloneExpr(tree->gtOp.gtOp2, addFlags, deepVarNum, deepVarVal);
}
/* Flags */
@@ -7775,18 +8143,6 @@ GenTreePtr Compiler::gtCloneExpr(GenTree* tree,
copy->CopyReg(tree);
}
- // We can call gtCloneExpr() before we have called fgMorph when we expand a GT_INDEX node in fgMorphArrayIndex()
- // The method gtFoldExpr() expects to be run after fgMorph so it will set the GTF_DEBUG_NODE_MORPHED
- // flag on nodes that it adds/modifies. Then when we call fgMorph we will assert.
- // We really only will need to fold when this method is used to replace references to
- // local variable with an integer.
- //
- if (varNum != (unsigned)-1)
- {
- /* Try to do some folding */
- copy = gtFoldExpr(copy);
- }
-
goto DONE;
}
@@ -7795,7 +8151,7 @@ GenTreePtr Compiler::gtCloneExpr(GenTree* tree,
switch (oper)
{
case GT_STMT:
- copy = gtCloneExpr(tree->gtStmt.gtStmtExpr, addFlags, varNum, varVal);
+ copy = gtCloneExpr(tree->gtStmt.gtStmtExpr, addFlags, deepVarNum, deepVarVal);
copy = gtNewStmt(copy, tree->gtStmt.gtStmtILoffsx);
goto DONE;
@@ -7803,15 +8159,17 @@ GenTreePtr Compiler::gtCloneExpr(GenTree* tree,
copy = new (this, GT_CALL) GenTreeCall(tree->TypeGet());
- copy->gtCall.gtCallObjp =
- tree->gtCall.gtCallObjp ? gtCloneExpr(tree->gtCall.gtCallObjp, addFlags, varNum, varVal) : nullptr;
- copy->gtCall.gtCallArgs = tree->gtCall.gtCallArgs
- ? gtCloneExpr(tree->gtCall.gtCallArgs, addFlags, varNum, varVal)->AsArgList()
+ copy->gtCall.gtCallObjp = tree->gtCall.gtCallObjp
+ ? gtCloneExpr(tree->gtCall.gtCallObjp, addFlags, deepVarNum, deepVarVal)
: nullptr;
+ copy->gtCall.gtCallArgs =
+ tree->gtCall.gtCallArgs
+ ? gtCloneExpr(tree->gtCall.gtCallArgs, addFlags, deepVarNum, deepVarVal)->AsArgList()
+ : nullptr;
copy->gtCall.gtCallMoreFlags = tree->gtCall.gtCallMoreFlags;
copy->gtCall.gtCallLateArgs =
tree->gtCall.gtCallLateArgs
- ? gtCloneExpr(tree->gtCall.gtCallLateArgs, addFlags, varNum, varVal)->AsArgList()
+ ? gtCloneExpr(tree->gtCall.gtCallLateArgs, addFlags, deepVarNum, deepVarVal)->AsArgList()
: nullptr;
#if !FEATURE_FIXED_OUT_ARGS
@@ -7832,11 +8190,12 @@ GenTreePtr Compiler::gtCloneExpr(GenTree* tree,
/* Copy the union */
if (tree->gtCall.gtCallType == CT_INDIRECT)
{
- copy->gtCall.gtCallCookie = tree->gtCall.gtCallCookie
- ? gtCloneExpr(tree->gtCall.gtCallCookie, addFlags, varNum, varVal)
- : nullptr;
- copy->gtCall.gtCallAddr =
- tree->gtCall.gtCallAddr ? gtCloneExpr(tree->gtCall.gtCallAddr, addFlags, varNum, varVal) : nullptr;
+ copy->gtCall.gtCallCookie =
+ tree->gtCall.gtCallCookie ? gtCloneExpr(tree->gtCall.gtCallCookie, addFlags, deepVarNum, deepVarVal)
+ : nullptr;
+ copy->gtCall.gtCallAddr = tree->gtCall.gtCallAddr
+ ? gtCloneExpr(tree->gtCall.gtCallAddr, addFlags, deepVarNum, deepVarVal)
+ : nullptr;
}
else if (tree->gtFlags & GTF_CALL_VIRT_STUB)
{
@@ -7883,8 +8242,9 @@ GenTreePtr Compiler::gtCloneExpr(GenTree* tree,
copy = gtNewFieldRef(tree->TypeGet(), tree->gtField.gtFldHnd, nullptr, tree->gtField.gtFldOffset);
- copy->gtField.gtFldObj =
- tree->gtField.gtFldObj ? gtCloneExpr(tree->gtField.gtFldObj, addFlags, varNum, varVal) : nullptr;
+ copy->gtField.gtFldObj = tree->gtField.gtFldObj
+ ? gtCloneExpr(tree->gtField.gtFldObj, addFlags, deepVarNum, deepVarVal)
+ : nullptr;
copy->gtField.gtFldMayOverlap = tree->gtField.gtFldMayOverlap;
#ifdef FEATURE_READYTORUN_COMPILER
copy->gtField.gtFieldLookup = tree->gtField.gtFieldLookup;
@@ -7897,10 +8257,10 @@ GenTreePtr Compiler::gtCloneExpr(GenTree* tree,
GenTreePtr inds[GT_ARR_MAX_RANK];
for (unsigned dim = 0; dim < tree->gtArrElem.gtArrRank; dim++)
{
- inds[dim] = gtCloneExpr(tree->gtArrElem.gtArrInds[dim], addFlags, varNum, varVal);
+ inds[dim] = gtCloneExpr(tree->gtArrElem.gtArrInds[dim], addFlags, deepVarNum, deepVarVal);
}
copy = new (this, GT_ARR_ELEM)
- GenTreeArrElem(tree->TypeGet(), gtCloneExpr(tree->gtArrElem.gtArrObj, addFlags, varNum, varVal),
+ GenTreeArrElem(tree->TypeGet(), gtCloneExpr(tree->gtArrElem.gtArrObj, addFlags, deepVarNum, deepVarVal),
tree->gtArrElem.gtArrRank, tree->gtArrElem.gtArrElemSize, tree->gtArrElem.gtArrElemType,
&inds[0]);
}
@@ -7909,34 +8269,37 @@ GenTreePtr Compiler::gtCloneExpr(GenTree* tree,
case GT_ARR_OFFSET:
{
copy = new (this, GT_ARR_OFFSET)
- GenTreeArrOffs(tree->TypeGet(), gtCloneExpr(tree->gtArrOffs.gtOffset, addFlags, varNum, varVal),
- gtCloneExpr(tree->gtArrOffs.gtIndex, addFlags, varNum, varVal),
- gtCloneExpr(tree->gtArrOffs.gtArrObj, addFlags, varNum, varVal),
+ GenTreeArrOffs(tree->TypeGet(), gtCloneExpr(tree->gtArrOffs.gtOffset, addFlags, deepVarNum, deepVarVal),
+ gtCloneExpr(tree->gtArrOffs.gtIndex, addFlags, deepVarNum, deepVarVal),
+ gtCloneExpr(tree->gtArrOffs.gtArrObj, addFlags, deepVarNum, deepVarVal),
tree->gtArrOffs.gtCurrDim, tree->gtArrOffs.gtArrRank, tree->gtArrOffs.gtArrElemType);
}
break;
case GT_CMPXCHG:
copy = new (this, GT_CMPXCHG)
- GenTreeCmpXchg(tree->TypeGet(), gtCloneExpr(tree->gtCmpXchg.gtOpLocation, addFlags, varNum, varVal),
- gtCloneExpr(tree->gtCmpXchg.gtOpValue, addFlags, varNum, varVal),
- gtCloneExpr(tree->gtCmpXchg.gtOpComparand, addFlags, varNum, varVal));
+ GenTreeCmpXchg(tree->TypeGet(),
+ gtCloneExpr(tree->gtCmpXchg.gtOpLocation, addFlags, deepVarNum, deepVarVal),
+ gtCloneExpr(tree->gtCmpXchg.gtOpValue, addFlags, deepVarNum, deepVarVal),
+ gtCloneExpr(tree->gtCmpXchg.gtOpComparand, addFlags, deepVarNum, deepVarVal));
break;
case GT_ARR_BOUNDS_CHECK:
#ifdef FEATURE_SIMD
case GT_SIMD_CHK:
#endif // FEATURE_SIMD
- copy = new (this, oper) GenTreeBoundsChk(oper, tree->TypeGet(),
- gtCloneExpr(tree->gtBoundsChk.gtArrLen, addFlags, varNum, varVal),
- gtCloneExpr(tree->gtBoundsChk.gtIndex, addFlags, varNum, varVal),
- tree->gtBoundsChk.gtThrowKind);
+ copy = new (this, oper)
+ GenTreeBoundsChk(oper, tree->TypeGet(),
+ gtCloneExpr(tree->gtBoundsChk.gtArrLen, addFlags, deepVarNum, deepVarVal),
+ gtCloneExpr(tree->gtBoundsChk.gtIndex, addFlags, deepVarNum, deepVarVal),
+ tree->gtBoundsChk.gtThrowKind);
break;
case GT_STORE_DYN_BLK:
case GT_DYN_BLK:
- copy = new (this, oper) GenTreeDynBlk(gtCloneExpr(tree->gtDynBlk.Addr(), addFlags, varNum, varVal),
- gtCloneExpr(tree->gtDynBlk.gtDynamicSize, addFlags, varNum, varVal));
+ copy = new (this, oper)
+ GenTreeDynBlk(gtCloneExpr(tree->gtDynBlk.Addr(), addFlags, deepVarNum, deepVarVal),
+ gtCloneExpr(tree->gtDynBlk.gtDynamicSize, addFlags, deepVarNum, deepVarVal));
break;
default:
@@ -8050,12 +8413,31 @@ GenTreePtr Compiler::gtReplaceTree(GenTreePtr stmt, GenTreePtr tree, GenTreePtr
{
assert(treeParent != nullptr);
+ // Check to see if the node to be replaced is a call argument and if so,
+ // set `treeParent` to the call node.
+ GenTree* cursor = treeParent;
+ while ((cursor != nullptr) && (cursor->OperGet() == GT_LIST))
+ {
+ cursor = cursor->gtNext;
+ }
+
+ if ((cursor != nullptr) && (cursor->OperGet() == GT_CALL))
+ {
+ treeParent = cursor;
+ }
+
+#ifdef DEBUG
+ GenTree** useEdge;
+ assert(treeParent->TryGetUse(tree, &useEdge));
+ assert(useEdge == treePtr);
+#endif // DEBUG
+
GenTreePtr treeFirstNode = fgGetFirstNode(tree);
GenTreePtr treeLastNode = tree;
GenTreePtr treePrevNode = treeFirstNode->gtPrev;
GenTreePtr treeNextNode = treeLastNode->gtNext;
- *treePtr = replacementTree;
+ treeParent->ReplaceOperand(treePtr, replacementTree);
// Build the linear order for "replacementTree".
fgSetTreeSeq(replacementTree, treePrevNode);
@@ -8082,48 +8464,6 @@ GenTreePtr Compiler::gtReplaceTree(GenTreePtr stmt, GenTreePtr tree, GenTreePtr
treeNextNode->gtPrev = treeLastNode;
}
- bool needFixupCallArg = false;
- GenTreePtr node = treeParent;
-
- // If we have replaced an arg, then update pointers in argtable.
- do
- {
- // Look for the first enclosing callsite
- switch (node->OperGet())
- {
- case GT_LIST:
- case GT_ARGPLACE:
- // "tree" is likely an argument of a call.
- needFixupCallArg = true;
- break;
-
- case GT_CALL:
- if (needFixupCallArg)
- {
- // We have replaced an arg, so update pointers in argtable.
- fgFixupArgTabEntryPtr(node, tree, replacementTree);
- needFixupCallArg = false;
- }
- break;
-
- default:
- // "tree" is unlikely an argument of a call.
- needFixupCallArg = false;
- break;
- }
-
- if (needFixupCallArg)
- {
- // Keep tracking to update the first enclosing call.
- node = node->gtGetParent(nullptr);
- }
- else
- {
- // Stop tracking.
- node = nullptr;
- }
- } while (node != nullptr);
-
// Propagate side-effect flags of "replacementTree" to its parents if needed.
gtUpdateSideEffects(treeParent, tree->gtFlags, replacementTree->gtFlags);
}
@@ -8304,14 +8644,13 @@ bool GenTree::gtSetFlags() const
//
// Precondition we have a GTK_SMPOP
//
- assert(OperIsSimple());
-
if (!varTypeIsIntegralOrI(TypeGet()))
{
return false;
}
#if FEATURE_SET_FLAGS
+ assert(OperIsSimple());
if ((gtFlags & GTF_SET_FLAGS) && gtOper != GT_IND)
{
@@ -8325,6 +8664,7 @@ bool GenTree::gtSetFlags() const
#else // !FEATURE_SET_FLAGS
+#ifdef LEGACY_BACKEND
#ifdef _TARGET_XARCH_
// Return true if/when the codegen for this node will set the flags
//
@@ -8346,6 +8686,22 @@ bool GenTree::gtSetFlags() const
return false;
#endif
+#else // !LEGACY_BACKEND
+#ifdef _TARGET_XARCH_
+ if (((gtFlags & GTF_SET_FLAGS) != 0) && (gtOper != GT_IND))
+ {
+ // GTF_SET_FLAGS is not valid on GT_IND and is overlaid with GTF_NONFAULTING_IND
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+#else
+ unreached();
+#endif
+#endif // !LEGACY_BACKEND
+
#endif // !FEATURE_SET_FLAGS
}
@@ -8399,7 +8755,8 @@ bool GenTree::gtRequestSetFlags()
/*****************************************************************************/
void GenTree::CopyTo(class Compiler* comp, const GenTree& gt)
{
- gtOper = gt.gtOper;
+ SetOperRaw(gt.OperGet());
+
gtType = gt.gtType;
gtAssertionNum = gt.gtAssertionNum;
@@ -8772,19 +9129,12 @@ GenTreePtr GenTree::GetChild(unsigned childNum)
}
}
-GenTreeUseEdgeIterator::GenTreeUseEdgeIterator()
- : m_node(nullptr)
- , m_edge(nullptr)
- , m_argList(nullptr)
- , m_state(-1)
+GenTreeUseEdgeIterator::GenTreeUseEdgeIterator() : 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_node(node), m_edge(nullptr), m_argList(nullptr), m_state(0)
{
assert(m_node != nullptr);
@@ -8894,30 +9244,53 @@ GenTree** GenTreeUseEdgeIterator::GetNextUseEdge() const
}
case GT_DYN_BLK:
+ {
+ GenTreeDynBlk* const dynBlock = m_node->AsDynBlk();
switch (m_state)
{
case 0:
- return &(m_node->AsDynBlk()->gtOp1);
+ return dynBlock->gtEvalSizeFirst ? &dynBlock->gtDynamicSize : &dynBlock->gtOp1;
case 1:
- return &(m_node->AsDynBlk()->gtDynamicSize);
+ return dynBlock->gtEvalSizeFirst ? &dynBlock->gtOp1 : &dynBlock->gtDynamicSize;
default:
return nullptr;
}
- break;
+ }
+ break;
case GT_STORE_DYN_BLK:
- switch (m_state)
+ {
+ GenTreeDynBlk* const dynBlock = m_node->AsDynBlk();
+ if (dynBlock->gtEvalSizeFirst)
{
- case 0:
- return &(m_node->AsDynBlk()->gtOp1);
- case 1:
- return &(m_node->AsDynBlk()->gtOp2);
- case 2:
- return &(m_node->AsDynBlk()->gtDynamicSize);
- default:
- return nullptr;
+ 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;
+ }
}
- break;
+ 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:
{
@@ -8942,13 +9315,9 @@ GenTree** GenTreeUseEdgeIterator::GetNextUseEdge() const
}
break;
- case GT_LIST:
- if (m_node->AsArgList()->IsAggregate())
- {
- // List nodes that represent aggregates are handled by MoveNextAggregateUseEdge.
- break;
- }
- __fallthrough;
+ case GT_FIELD_LIST:
+ // Field List nodes are handled by MoveToNextFieldUseEdge.
+ break;
default:
if (m_node->OperIsConst() || m_node->OperIsLeaf())
@@ -8988,13 +9357,13 @@ void GenTreeUseEdgeIterator::MoveToNextCallUseEdge()
{
enum
{
- CALL_INSTANCE = 0,
- CALL_ARGS = 1,
- CALL_LATE_ARGS = 2,
+ CALL_INSTANCE = 0,
+ CALL_ARGS = 1,
+ CALL_LATE_ARGS = 2,
CALL_CONTROL_EXPR = 3,
- CALL_COOKIE = 4,
- CALL_ADDRESS = 5,
- CALL_TERMINAL = 6,
+ CALL_COOKIE = 4,
+ CALL_ADDRESS = 5,
+ CALL_TERMINAL = 6,
};
GenTreeCall* call = m_node->AsCall();
@@ -9197,10 +9566,9 @@ void GenTreeUseEdgeIterator::MoveToNextSIMDUseEdge()
}
#endif // FEATURE_SIMD
-void GenTreeUseEdgeIterator::MoveToNextAggregateUseEdge()
+void GenTreeUseEdgeIterator::MoveToNextFieldUseEdge()
{
- assert(m_node->OperGet() == GT_LIST);
- assert(m_node->AsArgList()->IsAggregate());
+ assert(m_node->OperGet() == GT_FIELD_LIST);
for (;;)
{
@@ -9218,9 +9586,9 @@ void GenTreeUseEdgeIterator::MoveToNextAggregateUseEdge()
}
else
{
- GenTreeArgList* aggNode = m_argList->AsArgList();
- m_edge = &aggNode->gtOp1;
- m_argList = aggNode->Rest();
+ GenTreeArgList* listNode = m_argList->AsArgList();
+ m_edge = &listNode->gtOp1;
+ m_argList = listNode->Rest();
return;
}
break;
@@ -9266,9 +9634,9 @@ GenTreeUseEdgeIterator& GenTreeUseEdgeIterator::operator++()
MoveToNextSIMDUseEdge();
}
#endif
- else if ((op == GT_LIST) && (m_node->AsArgList()->IsAggregate()))
+ else if (op == GT_FIELD_LIST)
{
- MoveToNextAggregateUseEdge();
+ MoveToNextFieldUseEdge();
}
else
{
@@ -9529,7 +9897,7 @@ void Compiler::gtDispNodeName(GenTree* tree)
{
sprintf_s(bufp, sizeof(buf), " %s_ovfl%c", name, 0);
}
- else if (tree->OperIsBlk() && (tree->AsBlk()->gtBlkSize != 0))
+ else if (tree->OperIsBlk() && !tree->OperIsDynBlk())
{
sprintf_s(bufp, sizeof(buf), " %s(%d)", name, tree->AsBlk()->gtBlkSize);
}
@@ -9775,6 +10143,9 @@ void Compiler::gtDispNode(GenTreePtr tree, IndentStack* indentStack, __in __in_z
goto DASH;
case GT_MUL:
+#if defined(_TARGET_X86_) && !defined(LEGACY_BACKEND)
+ case GT_MUL_LONG:
+#endif
if (tree->gtFlags & GTF_MUL_64RSLT)
{
printf("L");
@@ -10409,6 +10780,13 @@ void Compiler::gtDispConst(GenTree* tree)
printf(" field offset");
}
+#ifdef FEATURE_SIMD
+ if ((tree->gtFlags & GTF_ICON_SIMD_COUNT) != 0)
+ {
+ printf(" Vector<T>.Count");
+ }
+#endif
+
if ((tree->IsReuseRegVal()) != 0)
{
printf(" reuse reg val");
@@ -10714,6 +11092,10 @@ void Compiler::gtDispLeaf(GenTree* tree, IndentStack* indentStack)
}
break;
+ case GT_JCC:
+ printf(" cond=%s", GenTree::NodeName(tree->AsJumpCC()->gtCondition));
+ break;
+
default:
assert(!"don't know how to display tree leaf node");
}
@@ -10928,14 +11310,62 @@ void Compiler::gtDispTree(GenTreePtr tree,
{
printf(" (last use)");
}
- if (tree->OperIsCopyBlkOp())
+ if (tree->OperIsBlkOp())
+ {
+ if (tree->OperIsCopyBlkOp())
+ {
+ printf(" (copy)");
+ }
+ else if (tree->OperIsInitBlkOp())
+ {
+ printf(" (init)");
+ }
+ if (tree->OperIsStoreBlk() && (tree->AsBlk()->gtBlkOpKind != GenTreeBlk::BlkOpKindInvalid))
+ {
+ switch (tree->AsBlk()->gtBlkOpKind)
+ {
+ case GenTreeBlk::BlkOpKindRepInstr:
+ printf(" (RepInstr)");
+ break;
+ case GenTreeBlk::BlkOpKindUnroll:
+ printf(" (Unroll)");
+ break;
+ case GenTreeBlk::BlkOpKindHelper:
+ printf(" (Helper)");
+ break;
+ default:
+ unreached();
+ }
+ }
+ }
+ else if (tree->OperIsFieldList())
{
- printf(" (copy)");
+ printf(" %s at offset %d", varTypeName(tree->AsFieldList()->gtFieldType),
+ tree->AsFieldList()->gtFieldOffset);
}
- else if (tree->OperIsInitBlkOp())
+#if FEATURE_PUT_STRUCT_ARG_STK
+ else if ((tree->OperGet() == GT_PUTARG_STK) &&
+ (tree->AsPutArgStk()->gtPutArgStkKind != GenTreePutArgStk::Kind::Invalid))
{
- printf(" (init)");
+ switch (tree->AsPutArgStk()->gtPutArgStkKind)
+ {
+ case GenTreePutArgStk::Kind::RepInstr:
+ printf(" (RepInstr)");
+ break;
+ case GenTreePutArgStk::Kind::Unroll:
+ printf(" (Unroll)");
+ break;
+ case GenTreePutArgStk::Kind::Push:
+ printf(" (Push)");
+ break;
+ case GenTreePutArgStk::Kind::PushAllSlots:
+ printf(" (PushAllSlots)");
+ break;
+ default:
+ unreached();
+ }
}
+#endif // FEATURE_PUT_STRUCT_ARG_STK
IndirectAssignmentAnnotation* pIndirAnnote;
if (tree->gtOper == GT_ASG && GetIndirAssignMap()->Lookup(tree, &pIndirAnnote))
@@ -11282,7 +11712,7 @@ void Compiler::gtDispTree(GenTreePtr tree,
// call - The call for which 'arg' is an argument
// arg - The argument for which a message should be constructed
// argNum - The ordinal number of the arg in the argument list
-// listCount - When printing in LIR form this is the count for a multireg GT_LIST
+// listCount - When printing in LIR form this is the count for a GT_FIELD_LIST
// or -1 if we are not printing in LIR form
// bufp - A pointer to the buffer into which the message is written
// bufLength - The length of the buffer pointed to by bufp
@@ -11338,7 +11768,7 @@ void Compiler::gtGetArgMsg(
// call - The call for which 'arg' is an argument
// argx - The argument for which a message should be constructed
// lateArgIndex - The ordinal number of the arg in the lastArg list
-// listCount - When printing in LIR form this is the count for a multireg GT_LIST
+// listCount - When printing in LIR form this is the count for a multireg GT_FIELD_LIST
// or -1 if we are not printing in LIR form
// bufp - A pointer to the buffer into which the message is written
// bufLength - The length of the buffer pointed to by bufp
@@ -11542,22 +11972,8 @@ void Compiler::gtDispLIRNode(GenTree* node)
const bool nodeIsCall = node->IsCall();
- int numCallEarlyArgs = 0;
- if (nodeIsCall)
- {
- GenTreeCall* call = node->AsCall();
- for (GenTreeArgList* args = call->gtCallArgs; args != nullptr; args = args->Rest())
- {
- if (!args->Current()->IsArgPlaceHolderNode() && args->Current()->IsValue())
- {
- numCallEarlyArgs++;
- }
- }
- }
-
// Visit operands
- IndentInfo operandArc = IIArcTop;
- int callArgNumber = 0;
+ IndentInfo operandArc = IIArcTop;
for (GenTree* operand : node->Operands())
{
if (operand->IsArgPlaceHolderNode() || !operand->IsValue())
@@ -11588,20 +12004,22 @@ void Compiler::gtDispLIRNode(GenTree* node)
}
else
{
- int callLateArgNumber = callArgNumber - numCallEarlyArgs;
+ fgArgTabEntryPtr curArgTabEntry = gtArgEntryByNode(call, operand);
+ assert(curArgTabEntry);
+
if (operand->OperGet() == GT_LIST)
{
int listIndex = 0;
for (GenTreeArgList* element = operand->AsArgList(); element != nullptr; element = element->Rest())
{
operand = element->Current();
- if (callLateArgNumber < 0)
+ if (curArgTabEntry->lateArgInx == (unsigned)-1)
{
- gtGetArgMsg(call, operand, callArgNumber, listIndex, buf, sizeof(buf));
+ gtGetArgMsg(call, operand, curArgTabEntry->argNum, listIndex, buf, sizeof(buf));
}
else
{
- gtGetLateArgMsg(call, operand, callLateArgNumber, listIndex, buf, sizeof(buf));
+ gtGetLateArgMsg(call, operand, curArgTabEntry->lateArgInx, listIndex, buf, sizeof(buf));
}
displayOperand(operand, buf, operandArc, indentStack);
@@ -11610,19 +12028,17 @@ void Compiler::gtDispLIRNode(GenTree* node)
}
else
{
- if (callLateArgNumber < 0)
+ if (curArgTabEntry->lateArgInx == (unsigned)-1)
{
- gtGetArgMsg(call, operand, callArgNumber, -1, buf, sizeof(buf));
+ gtGetArgMsg(call, operand, curArgTabEntry->argNum, -1, buf, sizeof(buf));
}
else
{
- gtGetLateArgMsg(call, operand, callLateArgNumber, -1, buf, sizeof(buf));
+ gtGetLateArgMsg(call, operand, curArgTabEntry->lateArgInx, -1, buf, sizeof(buf));
}
displayOperand(operand, buf, operandArc, indentStack);
}
-
- callArgNumber++;
}
}
else if (node->OperIsDynBlkOp())
@@ -12315,9 +12731,6 @@ GenTreePtr Compiler::gtFoldExprConst(GenTreePtr tree)
case TYP_ULONG:
if (!(tree->gtFlags & GTF_UNSIGNED) && tree->gtOverflow() && i1 < 0)
{
- op1->ChangeOperConst(GT_CNS_NATIVELONG); // need type of oper to be same as tree
- op1->gtType = TYP_LONG;
- // We don't care about the value as we are throwing an exception
goto LNG_OVF;
}
lval1 = UINT64(UINT32(i1));
@@ -12516,47 +12929,19 @@ GenTreePtr Compiler::gtFoldExprConst(GenTreePtr tree)
// constants in a target-specific function.
CLANG_FORMAT_COMMENT_ANCHOR;
-#ifdef _TARGET_XARCH_
- // Don't fold conversions of +inf/-inf to integral value as the value returned by JIT helper
- // doesn't match with the C compiler's cast result.
+ // Don't fold conversions of +inf/-inf to integral value on all platforms
+ // as the value returned by JIT helper doesn't match with the C compiler's cast result.
+ // We want the behavior to be same with or without folding.
return tree;
-#else //!_TARGET_XARCH_
+ }
- switch (tree->CastToType())
- {
- case TYP_BYTE:
- i1 = ssize_t(INT8(d1));
- goto CNS_INT;
- case TYP_UBYTE:
- i1 = ssize_t(UINT8(d1));
- goto CNS_INT;
- case TYP_SHORT:
- i1 = ssize_t(INT16(d1));
- goto CNS_INT;
- case TYP_CHAR:
- i1 = ssize_t(UINT16(d1));
- goto CNS_INT;
- case TYP_INT:
- i1 = ssize_t(INT32(d1));
- goto CNS_INT;
- case TYP_UINT:
- i1 = ssize_t(UINT32(d1));
- goto CNS_INT;
- case TYP_LONG:
- lval1 = INT64(d1);
- goto CNS_LONG;
- case TYP_ULONG:
- lval1 = UINT64(d1);
- goto CNS_LONG;
- case TYP_FLOAT:
- case TYP_DOUBLE:
- if (op1->gtType == TYP_FLOAT)
- d1 = forceCastToFloat(d1); // it's only !_finite() after this conversion
- goto CNS_DOUBLE;
- default:
- unreached();
- }
-#endif //!_TARGET_XARCH_
+ if (d1 <= -1.0 && varTypeIsUnsigned(tree->CastToType()))
+ {
+ // Don't fold conversions of these cases becasue the result is unspecified per ECMA spec
+ // and the native math doing the fold doesn't match the run-time computation on all
+ // platforms.
+ // We want the behavior to be same with or without folding.
+ return tree;
}
switch (tree->CastToType())
@@ -12633,7 +13018,7 @@ GenTreePtr Compiler::gtFoldExprConst(GenTreePtr tree)
return op2;
}
- if (tree->gtOper == GT_LIST)
+ if (tree->OperIsAnyList())
{
return tree;
}
@@ -13621,8 +14006,8 @@ GenTreePtr Compiler::gtNewTempAssign(unsigned tmp, GenTreePtr val)
var_types valTyp = val->TypeGet();
if (val->OperGet() == GT_LCL_VAR && lvaTable[val->gtLclVar.gtLclNum].lvNormalizeOnLoad())
{
- valTyp = lvaGetRealType(val->gtLclVar.gtLclNum);
- val = gtNewLclvNode(val->gtLclVar.gtLclNum, valTyp, val->gtLclVar.gtLclILoffs);
+ valTyp = lvaGetRealType(val->gtLclVar.gtLclNum);
+ val->gtType = valTyp;
}
var_types dstTyp = varDsc->TypeGet();
@@ -14108,7 +14493,7 @@ void Compiler::gtExtractSideEffList(GenTreePtr expr,
// effect of this instruction, change it into a GT_LOCKADD node (the add only)
if (oper == GT_XADD)
{
- expr->gtOper = GT_LOCKADD;
+ expr->SetOperRaw(GT_LOCKADD);
expr->gtType = TYP_VOID;
}
@@ -14188,12 +14573,12 @@ void Compiler::gtExtractSideEffList(GenTreePtr expr,
GenTreePtr args;
for (args = expr->gtCall.gtCallArgs; args; args = args->gtOp.gtOp2)
{
- assert(args->IsList());
+ assert(args->OperIsList());
gtExtractSideEffList(args->Current(), pList, flags);
}
for (args = expr->gtCall.gtCallLateArgs; args; args = args->gtOp.gtOp2)
{
- assert(args->IsList());
+ assert(args->OperIsList());
gtExtractSideEffList(args->Current(), pList, flags);
}
}
@@ -15356,11 +15741,18 @@ bool GenTree::isContained() const
return false;
}
+ // these either produce a result in register or set flags reg.
+ if (IsSIMDEqualityOrInequality())
+ {
+ return false;
+ }
+
// TODO-Cleanup : this is not clean, would be nice to have some way of marking this.
switch (OperGet())
{
case GT_STOREIND:
case GT_JTRUE:
+ case GT_JCC:
case GT_RETURN:
case GT_RETFILT:
case GT_STORE_LCL_FLD:
@@ -15381,7 +15773,9 @@ bool GenTree::isContained() const
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:
@@ -15928,6 +16322,17 @@ void GenTree::ParseArrayAddress(
// TODO-Review: A NotAField here indicates a failure to properly maintain the field sequence
// See test case self_host_tests_x86\jit\regression\CLR-x86-JIT\v1-m12-beta2\ b70992\ b70992.exe
// Safest thing to do here is to drop back to MinOpts
+ CLANG_FORMAT_COMMENT_ANCHOR;
+
+#ifdef DEBUG
+ if (comp->opts.optRepeat)
+ {
+ // We don't guarantee preserving these annotations through the entire optimizer, so
+ // just conservatively return null if under optRepeat.
+ *pArr = nullptr;
+ return;
+ }
+#endif // DEBUG
noway_assert(!"fldSeqIter is NotAField() in ParseArrayAddress");
}
@@ -16446,24 +16851,6 @@ bool GenTree::isCommutativeSIMDIntrinsic()
#endif // FEATURE_SIMD
//---------------------------------------------------------------------------------------
-// GenTreeArgList::Prepend:
-// Prepends an element to a GT_LIST.
-//
-// Arguments:
-// compiler - The compiler context.
-// element - The element to prepend.
-//
-// Returns:
-// The new head of the list.
-GenTreeArgList* GenTreeArgList::Prepend(Compiler* compiler, GenTree* element)
-{
- GenTreeArgList* head = compiler->gtNewListNode(element, this);
- head->gtFlags |= (gtFlags & GTF_LIST_AGGREGATE);
- gtFlags &= ~GTF_LIST_AGGREGATE;
- return head;
-}
-
-//---------------------------------------------------------------------------------------
// InitializeStructReturnType:
// Initialize the Return Type Descriptor for a method that returns a struct type
//
diff --git a/src/jit/gentree.h b/src/jit/gentree.h
index 4efeeae620..4611d35465 100644
--- a/src/jit/gentree.h
+++ b/src/jit/gentree.h
@@ -68,7 +68,7 @@ enum SpecialCodeKind
DECLARE_TYPED_ENUM(genTreeOps, BYTE)
{
-#define GTNODE(en, sn, cm, ok) GT_##en,
+#define GTNODE(en, sn, st, cm, ok) GT_##en,
#include "gtlist.h"
GT_COUNT,
@@ -429,13 +429,15 @@ struct GenTree
noway_assert(FitsIn<unsigned char>(level));
gtFPlvl = (unsigned char)level;
}
-#else // FEATURE_STACK_FP_X87
+#else // FEATURE_STACK_FP_X87
+
void gtCopyFPlvl(GenTree* other)
{
}
void gtSetFPlvl(unsigned level)
{
}
+
#endif // FEATURE_STACK_FP_X87
//
@@ -564,7 +566,7 @@ public:
bool isContainedIntOrIImmed() const
{
- return isContained() && IsCnsIntOrI();
+ return isContained() && IsCnsIntOrI() && !isContainedSpillTemp();
}
bool isContainedFltOrDblImmed() const
@@ -766,15 +768,15 @@ public:
#ifdef LEGACY_BACKEND
#define GTF_SPILLED_OPER 0x00000100 // op1 has been spilled
#define GTF_SPILLED_OP2 0x00000200 // op2 has been spilled
-#else
+#else // !LEGACY_BACKEND
#define GTF_NOREG_AT_USE 0x00000100 // tree node is in memory at the point of use
-#endif // LEGACY_BACKEND
+#endif // !LEGACY_BACKEND
#define GTF_ZSF_SET 0x00000400 // the zero(ZF) and sign(SF) flags set to the operand
-#if FEATURE_SET_FLAGS
+
#define GTF_SET_FLAGS 0x00000800 // Requires that codegen for this node set the flags
// Use gtSetFlags() to check this flags
-#endif
+
#define GTF_IND_NONFAULTING 0x00000800 // An indir that cannot fault. GTF_SET_FLAGS is not used on indirs
#define GTF_MAKE_CSE 0x00002000 // Hoisted Expression: try hard to make this into CSE (see optPerformHoistExpr)
@@ -865,12 +867,18 @@ public:
#define GTF_IND_TLS_REF 0x08000000 // GT_IND -- the target is accessed via TLS
#define GTF_IND_ASG_LHS 0x04000000 // GT_IND -- this GT_IND node is (the effective val) of the LHS of an
// assignment; don't evaluate it independently.
-#define GTF_IND_UNALIGNED 0x02000000 // GT_IND -- the load or store is unaligned (we assume worst case
- // alignment of 1 byte)
-#define GTF_IND_INVARIANT 0x01000000 // GT_IND -- the target is invariant (a prejit indirection)
-#define GTF_IND_ARR_LEN 0x80000000 // GT_IND -- the indirection represents an array length (of the REF
- // contribution to its argument).
-#define GTF_IND_ARR_INDEX 0x00800000 // GT_IND -- the indirection represents an (SZ) array index
+#define GTF_IND_REQ_ADDR_IN_REG GTF_IND_ASG_LHS // GT_IND -- requires its addr operand to be evaluated
+ // into a register. This flag is useful in cases where it
+ // is required to generate register indirect addressing mode.
+ // One such case is virtual stub calls on xarch. This is only
+ // valid in the backend, where GTF_IND_ASG_LHS is not necessary
+ // (all such indirections will be lowered to GT_STOREIND).
+#define GTF_IND_UNALIGNED 0x02000000 // GT_IND -- the load or store is unaligned (we assume worst case
+ // alignment of 1 byte)
+#define GTF_IND_INVARIANT 0x01000000 // GT_IND -- the target is invariant (a prejit indirection)
+#define GTF_IND_ARR_LEN 0x80000000 // GT_IND -- the indirection represents an array length (of the REF
+ // contribution to its argument).
+#define GTF_IND_ARR_INDEX 0x00800000 // GT_IND -- the indirection represents an (SZ) array index
#define GTF_IND_FLAGS \
(GTF_IND_VOLATILE | GTF_IND_REFARR_LAYOUT | GTF_IND_TGTANYWHERE | GTF_IND_NONFAULTING | GTF_IND_TLS_REF | \
@@ -925,11 +933,12 @@ public:
#define GTF_ICON_FIELD_OFF 0x08000000 // GT_CNS_INT -- constant is a field offset
+#define GTF_ICON_SIMD_COUNT 0x04000000 // GT_CNS_INT -- constant is Vector<T>.Count
+
#define GTF_BLK_VOLATILE 0x40000000 // GT_ASG, GT_STORE_BLK, GT_STORE_OBJ, GT_STORE_DYNBLK
// -- is a volatile block operation
#define GTF_BLK_UNALIGNED 0x02000000 // GT_ASG, GT_STORE_BLK, GT_STORE_OBJ, GT_STORE_DYNBLK
// -- is an unaligned block operation
-#define GTF_BLK_INIT 0x01000000 // GT_ASG, GT_STORE_BLK, GT_STORE_OBJ, GT_STORE_DYNBLK -- is an init block operation
#define GTF_OVERFLOW 0x10000000 // GT_ADD, GT_SUB, GT_MUL, - Need overflow check
// GT_ASG_ADD, GT_ASG_SUB,
@@ -942,10 +951,13 @@ public:
#define GTF_ARRLEN_ARR_IDX 0x80000000 // GT_ARR_LENGTH -- Length which feeds into an array index expression
-#define GTF_LIST_AGGREGATE 0x80000000 // GT_LIST -- Indicates that this list should be treated as an
- // anonymous aggregate value (e.g. a multi-value argument).
+#define GTF_FIELD_LIST_HEAD 0x80000000 // GT_FIELD_LIST -- Indicates that this is the first field in a list of
+ // struct fields constituting a single call argument.
//----------------------------------------------------------------
+#define GTF_SIMD12_OP 0x80000000 // GT_SIMD -- Indicates that the operands need to be handled as SIMD12
+ // even if they have been retyped as SIMD16.
+//----------------------------------------------------------------
#define GTF_STMT_CMPADD 0x80000000 // GT_STMT -- added by compiler
#define GTF_STMT_HAS_CSE 0x40000000 // GT_STMT -- CSE def or use was subsituted
@@ -958,8 +970,10 @@ public:
#define GTF_DEBUG_NODE_MORPHED 0x00000001 // the node has been morphed (in the global morphing phase)
#define GTF_DEBUG_NODE_SMALL 0x00000002
#define GTF_DEBUG_NODE_LARGE 0x00000004
+#define GTF_DEBUG_NODE_CG_PRODUCED 0x00000008 // genProduceReg has been called on this node
+#define GTF_DEBUG_NODE_CG_CONSUMED 0x00000010 // genConsumeReg has been called on this node
-#define GTF_DEBUG_NODE_MASK 0x00000007 // These flags are all node (rather than operation) properties.
+#define GTF_DEBUG_NODE_MASK 0x0000001F // These flags are all node (rather than operation) properties.
#define GTF_DEBUG_VAR_CSE_REF 0x00800000 // GT_LCL_VAR -- This is a CSE LCL_VAR node
#endif // defined(DEBUG)
@@ -970,6 +984,8 @@ public:
#ifdef DEBUG
unsigned gtTreeID;
unsigned gtSeqNum; // liveness traversal order within the current statement
+
+ int gtUseNum; // use-ordered traversal within the function
#endif
static const unsigned short gtOperKindTable[];
@@ -1011,9 +1027,9 @@ public:
return gtType != TYP_VOID;
}
- if (gtOper == GT_LIST)
+ if (gtOper == GT_FIELD_LIST)
{
- return (gtFlags & GTF_LIST_AGGREGATE) != 0;
+ return (gtFlags & GTF_FIELD_LIST_HEAD) != 0;
}
return true;
@@ -1033,14 +1049,14 @@ public:
return IsNothingNode();
case GT_ARGPLACE:
- // ARGPLACE nodes may not be present in a block's LIR sequence, but they may
+ case GT_LIST:
+ // ARGPLACE and LIST nodes may not be present in a block's LIR sequence, but they may
// be present as children of an LIR node.
return (gtNext == nullptr) && (gtPrev == nullptr);
- case GT_LIST:
- // LIST nodes may only be present in an LIR sequence if they represent aggregates.
- // They are always allowed, however, as children of an LIR node.
- return ((gtFlags & GTF_LIST_AGGREGATE) != 0) || ((gtNext == nullptr) && (gtPrev == nullptr));
+ case GT_FIELD_LIST:
+ // Only the head of the FIELD_LIST is present in the block's LIR sequence.
+ return (((gtFlags & GTF_FIELD_LIST_HEAD) != 0) || ((gtNext == nullptr) && (gtPrev == nullptr)));
case GT_ADDR:
{
@@ -1130,6 +1146,21 @@ public:
return (gtOper == GT_LEA);
}
+ static bool OperIsInitVal(genTreeOps gtOper)
+ {
+ return (gtOper == GT_INIT_VAL);
+ }
+
+ bool OperIsInitVal() const
+ {
+ return OperIsInitVal(OperGet());
+ }
+
+ bool IsConstInitVal()
+ {
+ return (gtOper == GT_CNS_INT) || (OperIsInitVal() && (gtGetOp1()->gtOper == GT_CNS_INT));
+ }
+
bool OperIsBlkOp();
bool OperIsCopyBlkOp();
bool OperIsInitBlkOp();
@@ -1146,6 +1177,16 @@ public:
return OperIsBlk(OperGet());
}
+ static bool OperIsDynBlk(genTreeOps gtOper)
+ {
+ return ((gtOper == GT_DYN_BLK) || (gtOper == GT_STORE_DYN_BLK));
+ }
+
+ bool OperIsDynBlk() const
+ {
+ return OperIsDynBlk(OperGet());
+ }
+
static bool OperIsStoreBlk(genTreeOps gtOper)
{
return ((gtOper == GT_STORE_BLK) || (gtOper == GT_STORE_OBJ) || (gtOper == GT_STORE_DYN_BLK));
@@ -1206,7 +1247,7 @@ public:
return OperIsLocalRead(OperGet());
}
- bool OperIsCompare()
+ bool OperIsCompare() const
{
return (OperKind(gtOper) & GTK_RELOP) != 0;
}
@@ -1270,7 +1311,6 @@ public:
{
case GT_ADD_HI:
case GT_SUB_HI:
- case GT_MUL_HI:
case GT_DIV_HI:
case GT_MOD_HI:
return true;
@@ -1396,8 +1436,7 @@ public:
static bool OperIsStore(genTreeOps gtOper)
{
return (gtOper == GT_STOREIND || gtOper == GT_STORE_LCL_VAR || gtOper == GT_STORE_LCL_FLD ||
- gtOper == GT_STORE_CLS_VAR || gtOper == GT_STORE_BLK || gtOper == GT_STORE_OBJ ||
- gtOper == GT_STORE_DYN_BLK);
+ gtOper == GT_STORE_BLK || gtOper == GT_STORE_OBJ || gtOper == GT_STORE_DYN_BLK);
}
static bool OperIsAtomicOp(genTreeOps gtOper)
@@ -1425,9 +1464,34 @@ public:
return OperIsSIMD(gtOper);
}
- bool OperIsAggregate()
+ bool OperIsFieldListHead()
+ {
+ return (gtOper == GT_FIELD_LIST) && ((gtFlags & GTF_FIELD_LIST_HEAD) != 0);
+ }
+
+ bool OperIsConditionalJump() const
+ {
+ return (gtOper == GT_JTRUE) || (gtOper == GT_JCC);
+ }
+
+ static bool OperIsBoundsCheck(genTreeOps op)
+ {
+ if (op == GT_ARR_BOUNDS_CHECK)
+ {
+ return true;
+ }
+#ifdef FEATURE_SIMD
+ if (op == GT_SIMD_CHK)
+ {
+ return true;
+ }
+#endif // FEATURE_SIMD
+ return false;
+ }
+
+ bool OperIsBoundsCheck() const
{
- return (gtOper == GT_LIST) && ((gtFlags & GTF_LIST_AGGREGATE) != 0);
+ return OperIsBoundsCheck(OperGet());
}
// Requires that "op" is an op= operator. Returns
@@ -1462,6 +1526,7 @@ public:
switch (gtOper)
{
case GT_LIST:
+ case GT_FIELD_LIST:
case GT_INTRINSIC:
case GT_LEA:
#ifdef FEATURE_SIMD
@@ -1474,19 +1539,47 @@ public:
}
static inline bool RequiresNonNullOp2(genTreeOps oper);
- bool IsListForMultiRegArg();
+ bool IsValidCallArgument();
#endif // DEBUG
inline bool IsFPZero();
inline bool IsIntegralConst(ssize_t constVal);
+ inline bool IsIntegralConstVector(ssize_t constVal);
inline bool IsBoxedValue();
- bool IsList() const
+ inline bool IsSIMDEqualityOrInequality() const;
+
+ static bool OperIsList(genTreeOps gtOper)
{
return gtOper == GT_LIST;
}
+ bool OperIsList() const
+ {
+ return OperIsList(gtOper);
+ }
+
+ static bool OperIsFieldList(genTreeOps gtOper)
+ {
+ return gtOper == GT_FIELD_LIST;
+ }
+
+ bool OperIsFieldList() const
+ {
+ return OperIsFieldList(gtOper);
+ }
+
+ static bool OperIsAnyList(genTreeOps gtOper)
+ {
+ return OperIsList(gtOper) || OperIsFieldList(gtOper);
+ }
+
+ bool OperIsAnyList() const
+ {
+ return OperIsAnyList(gtOper);
+ }
+
inline GenTreePtr MoveNext();
inline GenTreePtr Current();
@@ -1508,6 +1601,8 @@ public:
// Get the parent of this node, and optionally capture the pointer to the child so that it can be modified.
GenTreePtr gtGetParent(GenTreePtr** parentChildPtrPtr);
+ void ReplaceOperand(GenTree** useEdge, GenTree* replacement);
+
inline GenTreePtr gtEffectiveVal(bool commaOnly = false);
// Return the child of this node if it is a GT_RELOAD or GT_COPY; otherwise simply return the node itself
@@ -1536,7 +1631,13 @@ public:
public:
#if SMALL_TREE_NODES
static unsigned char s_gtNodeSizes[];
+#if NODEBASH_STATS || MEASURE_NODE_SIZE || COUNT_AST_OPERS
+ static unsigned char s_gtTrueSizes[];
+#endif
+#if COUNT_AST_OPERS
+ static LONG s_gtNodeCounts[];
#endif
+#endif // SMALL_TREE_NODES
static void InitNodeSize();
@@ -1555,15 +1656,19 @@ public:
static bool Compare(GenTreePtr op1, GenTreePtr op2, bool swapOK = false);
//---------------------------------------------------------------------
-#ifdef DEBUG
- //---------------------------------------------------------------------
+#if defined(DEBUG)
static const char* NodeName(genTreeOps op);
+#endif
+#if defined(DEBUG) || NODEBASH_STATS || MEASURE_NODE_SIZE || COUNT_AST_OPERS
static const char* OpName(genTreeOps op);
+#endif
-//---------------------------------------------------------------------
+#if MEASURE_NODE_SIZE && SMALL_TREE_NODES
+ static const char* OpStructName(genTreeOps op);
#endif
+
//---------------------------------------------------------------------
bool IsNothingNode() const;
@@ -1583,6 +1688,7 @@ public:
// set gtOper and only keep GTF_COMMON_MASK flags
void ChangeOper(genTreeOps oper, ValueNumberUpdate vnUpdate = CLEAR_VN);
void ChangeOperUnchecked(genTreeOps oper);
+ void SetOperRaw(genTreeOps oper);
void ChangeType(var_types newType)
{
@@ -1597,6 +1703,20 @@ public:
}
}
+#if SMALL_TREE_NODES
+#if NODEBASH_STATS
+ static void RecordOperBashing(genTreeOps operOld, genTreeOps operNew);
+ static void ReportOperBashing(FILE* fp);
+#else
+ static void RecordOperBashing(genTreeOps operOld, genTreeOps operNew)
+ { /* do nothing */
+ }
+ static void ReportOperBashing(FILE* fp)
+ { /* do nothing */
+ }
+#endif
+#endif
+
bool IsLocal() const
{
return OperIsLocal(OperGet());
@@ -1777,6 +1897,14 @@ public:
bool gtOverflowEx() const;
bool gtSetFlags() const;
bool gtRequestSetFlags();
+
+ // Returns true if the codegen of this tree node
+ // sets ZF and SF flags.
+ bool gtSetZSFlags() const
+ {
+ return (gtFlags & GTF_ZSF_SET) != 0;
+ }
+
#ifdef DEBUG
bool gtIsValid64RsltMul();
static int gtDispFlags(unsigned flags, unsigned debugFlags);
@@ -1827,10 +1955,10 @@ public:
// Returns an iterator that will produce the use edge to each operand of this node. Differs
// from the sequence of nodes produced by a loop over `GetChild` in its handling of call, phi,
// and block op nodes.
- GenTreeUseEdgeIterator GenTree::UseEdgesBegin();
- GenTreeUseEdgeIterator GenTree::UseEdgesEnd();
+ GenTreeUseEdgeIterator UseEdgesBegin();
+ GenTreeUseEdgeIterator UseEdgesEnd();
- IteratorPair<GenTreeUseEdgeIterator> GenTree::UseEdges();
+ IteratorPair<GenTreeUseEdgeIterator> UseEdges();
// Returns an iterator that will produce each operand of this node. Differs from the sequence
// of nodes produced by a loop over `GetChild` in its handling of call, phi, and block op
@@ -1866,6 +1994,10 @@ public:
gtFlags &= ~GTF_REUSE_REG_VAL;
}
+#if MEASURE_NODE_SIZE
+ static void DumpNodeSizes(FILE* fp);
+#endif
+
#ifdef DEBUG
private:
@@ -1931,7 +2063,7 @@ class GenTreeUseEdgeIterator final
#ifdef FEATURE_SIMD
void MoveToNextSIMDUseEdge();
#endif
- void MoveToNextAggregateUseEdge();
+ void MoveToNextFieldUseEdge();
public:
GenTreeUseEdgeIterator();
@@ -2128,7 +2260,7 @@ struct GenTreeIntConCommon : public GenTree
}
bool ImmedValNeedsReloc(Compiler* comp);
- bool GenTreeIntConCommon::ImmedValCanBeFolded(Compiler* comp, genTreeOps op);
+ bool ImmedValCanBeFolded(Compiler* comp, genTreeOps op);
#ifdef _TARGET_XARCH_
bool FitsInAddrBase(Compiler* comp);
@@ -2629,18 +2761,13 @@ struct GenTreeField : public GenTree
// method names for the arguments.
struct GenTreeArgList : public GenTreeOp
{
- bool IsAggregate() const
- {
- return (gtFlags & GTF_LIST_AGGREGATE) != 0;
- }
-
GenTreePtr& Current()
{
return gtOp1;
}
GenTreeArgList*& Rest()
{
- assert(gtOp2 == nullptr || gtOp2->OperGet() == GT_LIST);
+ assert(gtOp2 == nullptr || gtOp2->OperIsAnyList());
return *reinterpret_cast<GenTreeArgList**>(&gtOp2);
}
@@ -2654,20 +2781,68 @@ struct GenTreeArgList : public GenTreeOp
{
}
- GenTreeArgList(GenTreePtr arg, GenTreeArgList* rest) : GenTreeOp(GT_LIST, TYP_VOID, arg, rest)
+ GenTreeArgList(GenTreePtr arg, GenTreeArgList* rest) : GenTreeArgList(GT_LIST, arg, rest)
{
- // With structs passed in multiple args we could have an arg
- // GT_LIST containing a list of LCL_FLDs, see IsListForMultiRegArg()
- //
- assert((arg != nullptr) && ((!arg->IsList()) || (arg->IsListForMultiRegArg())));
+ }
+
+ GenTreeArgList(genTreeOps oper, GenTreePtr arg, GenTreeArgList* rest) : GenTreeOp(oper, TYP_VOID, arg, rest)
+ {
+ assert(OperIsAnyList(oper));
+ assert((arg != nullptr) && arg->IsValidCallArgument());
gtFlags |= arg->gtFlags & GTF_ALL_EFFECT;
if (rest != nullptr)
{
gtFlags |= rest->gtFlags & GTF_ALL_EFFECT;
}
}
+};
+
+// Represents a list of fields constituting a struct, when it is passed as an argument.
+// The first field of the struct is marked with the GTF_FIELD_LIST_HEAD flag, and
+// in LIR form it is the only member of the list that is threaded into the execution
+// order.
+// It differs from the GenTreeArgList in a couple of ways:
+// - The entire list represents a single argument.
+// - It contains additional fields to provide the offset and type of the field.
+//
+struct GenTreeFieldList : public GenTreeArgList
+{
+ unsigned gtFieldOffset;
+ var_types gtFieldType;
+
+ bool IsFieldListHead() const
+ {
+ return (gtFlags & GTF_FIELD_LIST_HEAD) != 0;
+ }
- GenTreeArgList* Prepend(Compiler* compiler, GenTree* element);
+#if DEBUGGABLE_GENTREE
+ GenTreeFieldList() : GenTreeArgList()
+ {
+ }
+#endif
+
+ GenTreeFieldList*& Rest()
+ {
+ assert(gtOp2 == nullptr || gtOp2->OperGet() == GT_FIELD_LIST);
+ return *reinterpret_cast<GenTreeFieldList**>(&gtOp2);
+ }
+
+ GenTreeFieldList(GenTreePtr arg, unsigned fieldOffset, var_types fieldType, GenTreeFieldList* prevList)
+ : GenTreeArgList(GT_FIELD_LIST, arg, nullptr)
+ {
+ // While GT_FIELD_LIST can be in a GT_LIST, GT_FIELD_LISTs cannot be nested or have GT_LISTs.
+ assert(!arg->OperIsAnyList());
+ gtFieldOffset = fieldOffset;
+ gtFieldType = fieldType;
+ if (prevList == nullptr)
+ {
+ gtFlags |= GTF_FIELD_LIST_HEAD;
+ }
+ else
+ {
+ prevList->gtOp2 = this;
+ }
+ }
};
// There was quite a bit of confusion in the code base about which of gtOp1 and gtOp2 was the
@@ -3360,8 +3535,13 @@ struct GenTreeCall final : public GenTree
bool IsHelperCall(Compiler* compiler, unsigned helper) const;
+ void ReplaceCallOperand(GenTree** operandUseEdge, GenTree* replacement);
+
+ bool AreArgsComplete() const;
+
GenTreeCall(var_types type) : GenTree(GT_CALL, type)
{
+ fgArgInfo = nullptr;
}
#if DEBUGGABLE_GENTREE
GenTreeCall() : GenTree()
@@ -4017,6 +4197,19 @@ struct GenTreeObj : public GenTreeBlk
// Let's assert it just to be safe.
noway_assert(roundUp(gtBlkSize, REGSIZE_BYTES) == gtBlkSize);
}
+ else
+ {
+ genTreeOps newOper = GT_BLK;
+ if (gtOper == GT_STORE_OBJ)
+ {
+ newOper = GT_STORE_BLK;
+ }
+ else
+ {
+ assert(gtOper == GT_OBJ);
+ }
+ SetOper(newOper);
+ }
}
void CopyGCInfo(GenTreeObj* srcObj)
@@ -4068,6 +4261,8 @@ public:
GenTreeDynBlk(GenTreePtr addr, GenTreePtr dynamicSize)
: GenTreeBlk(GT_DYN_BLK, TYP_STRUCT, addr, 0), gtDynamicSize(dynamicSize), gtEvalSizeFirst(false)
{
+ // Conservatively the 'addr' could be null or point into the global heap.
+ gtFlags |= GTF_EXCEPT | GTF_GLOB_REF;
gtFlags |= (dynamicSize->gtFlags & GTF_ALL_EFFECT);
}
@@ -4198,10 +4393,7 @@ struct GenTreeStmt : public GenTree
GenTreePtr gtStmtExpr; // root of the expression tree
GenTreePtr gtStmtList; // first node (for forward walks)
InlineContext* gtInlineContext; // The inline context for this statement.
-
-#if defined(DEBUGGING_SUPPORT) || defined(DEBUG)
- IL_OFFSETX gtStmtILoffsx; // instr offset (if available)
-#endif
+ IL_OFFSETX gtStmtILoffsx; // instr offset (if available)
#ifdef DEBUG
IL_OFFSET gtStmtLastILoffs; // instr offset at end of stmt
@@ -4240,9 +4432,7 @@ struct GenTreeStmt : public GenTree
, gtStmtExpr(expr)
, gtStmtList(nullptr)
, gtInlineContext(nullptr)
-#if defined(DEBUGGING_SUPPORT) || defined(DEBUG)
, gtStmtILoffsx(offset)
-#endif
#ifdef DEBUG
, gtStmtLastILoffs(BAD_IL_OFFSET)
#endif
@@ -4350,20 +4540,19 @@ struct GenTreePutArgStk : public GenTreeUnOp
GenTreePutArgStk(genTreeOps oper,
var_types type,
- unsigned slotNum FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(unsigned numSlots)
- FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(bool isStruct),
+ 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))
, gtSlotNum(slotNum)
, putInIncomingArgArea(_putInIncomingArgArea)
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
- , gtPutArgStkKind(PutArgStkKindInvalid)
+#ifdef FEATURE_PUT_STRUCT_ARG_STK
+ , gtPutArgStkKind(Kind::Invalid)
, gtNumSlots(numSlots)
- , gtIsStruct(isStruct)
, gtNumberReferenceSlots(0)
, gtGcPtrs(nullptr)
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+#endif // FEATURE_PUT_STRUCT_ARG_STK
{
#ifdef DEBUG
gtCall = callNode;
@@ -4373,20 +4562,18 @@ struct GenTreePutArgStk : public GenTreeUnOp
GenTreePutArgStk(genTreeOps oper,
var_types type,
GenTreePtr op1,
- unsigned slotNum FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(unsigned numSlots)
- FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(bool isStruct),
+ 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)
, putInIncomingArgArea(_putInIncomingArgArea)
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
- , gtPutArgStkKind(PutArgStkKindInvalid)
+#ifdef FEATURE_PUT_STRUCT_ARG_STK
+ , gtPutArgStkKind(Kind::Invalid)
, gtNumSlots(numSlots)
- , gtIsStruct(isStruct)
, gtNumberReferenceSlots(0)
, gtGcPtrs(nullptr)
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+#endif // FEATURE_PUT_STRUCT_ARG_STK
{
#ifdef DEBUG
gtCall = callNode;
@@ -4397,18 +4584,16 @@ struct GenTreePutArgStk : public GenTreeUnOp
GenTreePutArgStk(genTreeOps oper,
var_types type,
- unsigned slotNum FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(unsigned numSlots)
- FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(bool isStruct) DEBUGARG(GenTreePtr callNode = NULL)
- DEBUGARG(bool largeNode = false))
+ 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)
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
- , gtPutArgStkKind(PutArgStkKindInvalid)
+#ifdef FEATURE_PUT_STRUCT_ARG_STK
+ , gtPutArgStkKind(Kind::Invalid)
, gtNumSlots(numSlots)
- , gtIsStruct(isStruct)
, gtNumberReferenceSlots(0)
, gtGcPtrs(nullptr)
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+#endif // FEATURE_PUT_STRUCT_ARG_STK
{
#ifdef DEBUG
gtCall = callNode;
@@ -4418,18 +4603,16 @@ struct GenTreePutArgStk : public GenTreeUnOp
GenTreePutArgStk(genTreeOps oper,
var_types type,
GenTreePtr op1,
- unsigned slotNum FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(unsigned numSlots)
- FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(bool isStruct) DEBUGARG(GenTreePtr callNode = NULL)
- DEBUGARG(bool largeNode = false))
+ 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)
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
- , gtPutArgStkKind(PutArgStkKindInvalid)
+#ifdef FEATURE_PUT_STRUCT_ARG_STK
+ , gtPutArgStkKind(Kind::Invalid)
, gtNumSlots(numSlots)
- , gtIsStruct(isStruct)
, gtNumberReferenceSlots(0)
, gtGcPtrs(nullptr)
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+#endif // FEATURE_PUT_STRUCT_ARG_STK
{
#ifdef DEBUG
gtCall = callNode;
@@ -4442,14 +4625,14 @@ struct GenTreePutArgStk : public GenTreeUnOp
return gtSlotNum * TARGET_POINTER_SIZE;
}
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
+#ifdef FEATURE_PUT_STRUCT_ARG_STK
unsigned getArgSize()
{
return gtNumSlots * TARGET_POINTER_SIZE;
}
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+#endif // FEATURE_PUT_STRUCT_ARG_STK
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
+#ifdef FEATURE_PUT_STRUCT_ARG_STK
//------------------------------------------------------------------------
// setGcPointers: Sets the number of references and the layout of the struct object returned by the VM.
//
@@ -4471,27 +4654,32 @@ struct GenTreePutArgStk : public GenTreeUnOp
gtNumberReferenceSlots = numPointers;
gtGcPtrs = pointers;
}
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+#endif // FEATURE_PUT_STRUCT_ARG_STK
#ifdef DEBUG
GenTreePtr gtCall; // the call node to which this argument belongs
#endif
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
+#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
+ // block node.
- enum PutArgStkKind : __int8{
- PutArgStkKindInvalid, PutArgStkKindRepInstr, PutArgStkKindUnroll,
+ enum class Kind : __int8{
+ Invalid, RepInstr, Unroll, Push, PushAllSlots,
};
- PutArgStkKind gtPutArgStkKind;
+ Kind gtPutArgStkKind;
+ bool isPushKind()
+ {
+ return (gtPutArgStkKind == Kind::Push) || (gtPutArgStkKind == Kind::PushAllSlots);
+ }
unsigned gtNumSlots; // Number of slots for the argument to be passed on stack
- bool gtIsStruct; // This stack arg is a struct.
unsigned gtNumberReferenceSlots; // Number of reference slots.
BYTE* gtGcPtrs; // gcPointers
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+#endif // FEATURE_PUT_STRUCT_ARG_STK
#if DEBUGGABLE_GENTREE
GenTreePutArgStk() : GenTreeUnOp()
@@ -4644,6 +4832,23 @@ struct GenTreeAllocObj final : public GenTreeUnOp
#endif
};
+struct GenTreeJumpCC final : public GenTree
+{
+ genTreeOps gtCondition; // any relop
+
+ GenTreeJumpCC(genTreeOps condition)
+ : GenTree(GT_JCC, TYP_VOID DEBUGARG(/*largeNode*/ FALSE)), gtCondition(condition)
+ {
+ assert(OperIsCompare(condition));
+ }
+
+#if DEBUGGABLE_GENTREE
+ GenTreeJumpCC() : GenTree()
+ {
+ }
+#endif // DEBUGGABLE_GENTREE
+};
+
//------------------------------------------------------------------------
// Deferred inline functions of GenTree -- these need the subtypes above to
// be defined already.
@@ -4673,34 +4878,31 @@ inline bool GenTree::OperIsDynBlkOp()
return false;
}
-inline bool GenTree::OperIsCopyBlkOp()
+inline bool GenTree::OperIsInitBlkOp()
{
- if (gtOper == GT_ASG)
+ if (!OperIsBlkOp())
{
- return (varTypeIsStruct(gtGetOp1()) && ((gtFlags & GTF_BLK_INIT) == 0));
+ return false;
}
#ifndef LEGACY_BACKEND
- else if (OperIsStoreBlk())
- {
- return ((gtFlags & GTF_BLK_INIT) == 0);
- }
-#endif
- return false;
-}
-
-inline bool GenTree::OperIsInitBlkOp()
-{
+ GenTree* src;
if (gtOper == GT_ASG)
{
- return (varTypeIsStruct(gtGetOp1()) && ((gtFlags & GTF_BLK_INIT) != 0));
+ src = gtGetOp2();
}
-#ifndef LEGACY_BACKEND
- else if (OperIsStoreBlk())
+ else
{
- return ((gtFlags & GTF_BLK_INIT) != 0);
+ src = AsBlk()->Data()->gtSkipReloadOrCopy();
}
-#endif
- return false;
+#else // LEGACY_BACKEND
+ GenTree* src = gtGetOp2();
+#endif // LEGACY_BACKEND
+ return src->OperIsInitVal() || src->OperIsConst();
+}
+
+inline bool GenTree::OperIsCopyBlkOp()
+{
+ return OperIsBlkOp() && !OperIsInitBlkOp();
}
//------------------------------------------------------------------------
@@ -4748,34 +4950,63 @@ inline bool GenTree::IsIntegralConst(ssize_t constVal)
return false;
}
+//-------------------------------------------------------------------
+// IsIntegralConstVector: returns true if this this is a SIMD vector
+// with all its elements equal to an integral constant.
+//
+// Arguments:
+// constVal - const value of vector element
+//
+// Returns:
+// True if this represents an integral const SIMD vector.
+//
+inline bool GenTree::IsIntegralConstVector(ssize_t constVal)
+{
+#ifdef FEATURE_SIMD
+ // SIMDIntrinsicInit intrinsic with a const value as initializer
+ // represents a const vector.
+ if ((gtOper == GT_SIMD) && (gtSIMD.gtSIMDIntrinsicID == SIMDIntrinsicInit) && gtGetOp1()->IsIntegralConst(constVal))
+ {
+ assert(varTypeIsIntegral(gtSIMD.gtSIMDBaseType));
+ assert(gtGetOp2() == nullptr);
+ return true;
+ }
+#endif
+
+ return false;
+}
+
inline bool GenTree::IsBoxedValue()
{
assert(gtOper != GT_BOX || gtBox.BoxOp() != nullptr);
return (gtOper == GT_BOX) && (gtFlags & GTF_BOX_VALUE);
}
+inline bool GenTree::IsSIMDEqualityOrInequality() const
+{
+#ifdef FEATURE_SIMD
+ if (gtOper == GT_SIMD)
+ {
+ // Has to cast away const-ness since AsSIMD() method is non-const.
+ GenTreeSIMD* simdNode = const_cast<GenTree*>(this)->AsSIMD();
+ return (simdNode->gtSIMDIntrinsicID == SIMDIntrinsicOpEquality ||
+ simdNode->gtSIMDIntrinsicID == SIMDIntrinsicOpInEquality);
+ }
+#endif
+
+ return false;
+}
+
inline GenTreePtr GenTree::MoveNext()
{
- assert(IsList());
+ assert(OperIsAnyList());
return gtOp.gtOp2;
}
#ifdef DEBUG
//------------------------------------------------------------------------
-// IsListForMultiRegArg: Given an GenTree node that represents an argument
-// enforce (or don't enforce) the following invariant.
-//
-// For LEGACY_BACKEND or architectures that don't support MultiReg args
-// we don't allow a GT_LIST at all.
-//
-// Currently for AMD64 UNIX we allow a limited case where a GT_LIST is
-// allowed but every element must be a GT_LCL_FLD.
-//
-// For the future targets that allow for Multireg args (and this includes
-// the current ARM64 target) we allow a GT_LIST of arbitrary nodes, these
-// would typically start out as GT_LCL_VARs or GT_LCL_FLDS or GT_INDs,
-// but could be changed into constants or GT_COMMA trees by the later
-// optimization phases.
+// IsValidCallArgument: Given an GenTree node that represents an argument
+// enforce (or don't enforce) the following invariant.
//
// Arguments:
// instance method for a GenTree node
@@ -4784,33 +5015,46 @@ inline GenTreePtr GenTree::MoveNext()
// true: the GenTree node is accepted as a valid argument
// false: the GenTree node is not accepted as a valid argumeny
//
-inline bool GenTree::IsListForMultiRegArg()
+// Notes:
+// For targets that don't support arguments as a list of fields, we do not support GT_FIELD_LIST.
+//
+// Currently for AMD64 UNIX we allow a limited case where a GT_FIELD_LIST is
+// allowed but every element must be a GT_LCL_FLD.
+//
+// For the future targets that allow for Multireg args (and this includes the current ARM64 target),
+// or that allow for passing promoted structs, we allow a GT_FIELD_LIST of arbitrary nodes.
+// These would typically start out as GT_LCL_VARs or GT_LCL_FLDS or GT_INDs,
+// but could be changed into constants or GT_COMMA trees by the later
+// optimization phases.
+
+inline bool GenTree::IsValidCallArgument()
{
- if (!IsList())
+ if (OperIsList())
{
- // We don't have a GT_LIST, so just return true.
- return true;
+ // GT_FIELD_LIST is the only list allowed.
+ return false;
}
- else // We do have a GT_LIST
+ if (OperIsFieldList())
{
-#if defined(LEGACY_BACKEND) || !FEATURE_MULTIREG_ARGS
-
- // Not allowed to have a GT_LIST for an argument
- // unless we have a RyuJIT backend and FEATURE_MULTIREG_ARGS
+#if defined(LEGACY_BACKEND) || (!FEATURE_MULTIREG_ARGS && !FEATURE_PUT_STRUCT_ARG_STK)
+ // Not allowed to have a GT_FIELD_LIST for an argument
+ // unless we have a RyuJIT backend and FEATURE_MULTIREG_ARGS or FEATURE_PUT_STRUCT_ARG_STK
return false;
-#else // we have RyuJIT backend and FEATURE_MULTIREG_ARGS
+#else // we have RyuJIT backend and FEATURE_MULTIREG_ARGS or FEATURE_PUT_STRUCT_ARG_STK
#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
- // For UNIX ABI we currently only allow a GT_LIST of GT_LCL_FLDs nodes
+ // For UNIX ABI we currently only allow a GT_FIELD_LIST of GT_LCL_FLDs nodes
GenTree* gtListPtr = this;
while (gtListPtr != nullptr)
{
// ToDo: fix UNIX_AMD64 so that we do not generate this kind of a List
// Note the list as currently created is malformed, as the last entry is a nullptr
if (gtListPtr->Current() == nullptr)
+ {
break;
+ }
// Only a list of GT_LCL_FLDs is allowed
if (gtListPtr->Current()->OperGet() != GT_LCL_FLD)
@@ -4821,25 +5065,27 @@ inline bool GenTree::IsListForMultiRegArg()
}
#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
- // Note that for non-UNIX ABI the GT_LIST may contain any node
+ // Note that for non-UNIX ABI the GT_FIELD_LIST may contain any node
//
- // We allow this GT_LIST as an argument
+ // We allow this GT_FIELD_LIST as an argument
return true;
-#endif // RyuJIT backend and FEATURE_MULTIREG_ARGS
+#endif // FEATURE_MULTIREG_ARGS
}
+ // We don't have either kind of list, so it satisfies the invariant.
+ return true;
}
#endif // DEBUG
inline GenTreePtr GenTree::Current()
{
- assert(IsList());
+ assert(OperIsAnyList());
return gtOp.gtOp1;
}
inline GenTreePtr* GenTree::pCurrent()
{
- assert(IsList());
+ assert(OperIsAnyList());
return &(gtOp.gtOp1);
}
@@ -4917,23 +5163,22 @@ inline GenTreePtr GenTree::gtGetOp2()
inline GenTreePtr GenTree::gtEffectiveVal(bool commaOnly)
{
- switch (gtOper)
+ GenTree* effectiveVal = this;
+ for (;;)
{
- case GT_COMMA:
- return gtOp.gtOp2->gtEffectiveVal(commaOnly);
-
- case GT_NOP:
- if (!commaOnly && gtOp.gtOp1 != nullptr)
- {
- return gtOp.gtOp1->gtEffectiveVal();
- }
- break;
-
- default:
- break;
+ if (effectiveVal->gtOper == GT_COMMA)
+ {
+ effectiveVal = effectiveVal->gtOp.gtOp2;
+ }
+ else if (!commaOnly && (effectiveVal->gtOper == GT_NOP) && (effectiveVal->gtOp.gtOp1 != nullptr))
+ {
+ effectiveVal = effectiveVal->gtOp.gtOp1;
+ }
+ else
+ {
+ return effectiveVal;
+ }
}
-
- return this;
}
inline GenTree* GenTree::gtSkipReloadOrCopy()
diff --git a/src/jit/gschecks.cpp b/src/jit/gschecks.cpp
index 43cbb892e9..9255d8fd36 100644
--- a/src/jit/gschecks.cpp
+++ b/src/jit/gschecks.cpp
@@ -40,9 +40,9 @@ const unsigned NO_SHADOW_COPY = UINT_MAX;
* The current function has an unsafe buffer on the stack. Search for vulnerable
* parameters which could be used to modify a code address and take over the process
* in the case of a buffer overrun. Create a safe local copy for each vulnerable parameter,
- * which will be allocated bellow the unsafe buffer. Change uses of the param to the
+ * which will be allocated bellow the unsafe buffer. Change uses of the param to the
* shadow copy.
- *
+ *
* A pointer under indirection is considered vulnerable. A malicious user could read from
* protected memory or write to it. If a parameter is assigned/computed into another variable,
* and is a pointer (i.e., under indirection), then we consider the variable to be part of the
@@ -58,7 +58,7 @@ void Compiler::gsCopyShadowParams()
// Allocate array for shadow param info
gsShadowVarInfo = new (this, CMK_Unknown) ShadowParamVarInfo[lvaCount]();
- // Find groups of variables assigned to each other, and also
+ // Find groups of variables assigned to each other, and also
// tracks variables which are dereferenced and marks them as ptrs.
// Look for assignments to *p, and ptrs passed to functions
if (gsFindVulnerableParams())
@@ -83,7 +83,7 @@ struct MarkPtrsInfo
{
printf(
"[MarkPtrsInfo] = {comp = %p, lvAssignDef = %d, isAssignSrc = %d, isUnderIndir = %d, skipNextNode = %d}\n",
- comp, lvAssignDef, isAssignSrc, isUnderIndir, skipNextNode);
+ comp, lvAssignDef, isAssignSrc, isUnderIndir, skipNextNode);
}
#endif
};
@@ -129,7 +129,7 @@ Compiler::fgWalkResult Compiler::gsMarkPtrsAndAssignGroups(GenTreePtr* pTree, fg
newState.isUnderIndir = true;
{
newState.skipNextNode = true; // Don't have to worry about which kind of node we're dealing with
- comp->fgWalkTreePre(&tree, comp->gsMarkPtrsAndAssignGroups, (void *)&newState);
+ comp->fgWalkTreePre(&tree, comp->gsMarkPtrsAndAssignGroups, (void*)&newState);
}
return WALK_SKIP_SUBTREES;
@@ -160,50 +160,50 @@ Compiler::fgWalkResult Compiler::gsMarkPtrsAndAssignGroups(GenTreePtr* pTree, fg
{
shadowVarInfo[pState->lvAssignDef].assignGroup->bitVectSet(lclNum);
}
-
+
// Point both to the same bit vector
shadowVarInfo[lclNum].assignGroup = shadowVarInfo[pState->lvAssignDef].assignGroup;
}
else if (shadowVarInfo[lclNum].assignGroup)
{
shadowVarInfo[lclNum].assignGroup->bitVectSet(pState->lvAssignDef);
-
+
// Point both to the same bit vector
shadowVarInfo[pState->lvAssignDef].assignGroup = shadowVarInfo[lclNum].assignGroup;
}
else
{
- FixedBitVect* bv = FixedBitVect::bitVectInit(pState->comp->lvaCount, pState->comp);
+ FixedBitVect* bv = FixedBitVect::bitVectInit(pState->comp->lvaCount, pState->comp);
// (shadowVarInfo[pState->lvAssignDef] == NULL && shadowVarInfo[lclNew] == NULL);
// Neither of them has an assign group yet. Make a new one.
shadowVarInfo[pState->lvAssignDef].assignGroup = bv;
- shadowVarInfo[lclNum].assignGroup = bv;
+ shadowVarInfo[lclNum].assignGroup = bv;
bv->bitVectSet(pState->lvAssignDef);
bv->bitVectSet(lclNum);
}
}
return WALK_CONTINUE;
-
+
// Calls - Mark arg variables
case GT_CALL:
newState.isUnderIndir = false;
- newState.isAssignSrc = false;
+ newState.isAssignSrc = false;
{
if (tree->gtCall.gtCallObjp)
{
newState.isUnderIndir = true;
- comp->fgWalkTreePre(&tree->gtCall.gtCallObjp, gsMarkPtrsAndAssignGroups, (void*)&newState);
+ comp->fgWalkTreePre(&tree->gtCall.gtCallObjp, gsMarkPtrsAndAssignGroups, (void*)&newState);
}
for (GenTreeArgList* args = tree->gtCall.gtCallArgs; args; args = args->Rest())
{
- comp->fgWalkTreePre(&args->Current(), gsMarkPtrsAndAssignGroups, (void*)&newState);
+ comp->fgWalkTreePre(&args->Current(), gsMarkPtrsAndAssignGroups, (void*)&newState);
}
for (GenTreeArgList* args = tree->gtCall.gtCallLateArgs; args; args = args->Rest())
{
- comp->fgWalkTreePre(&args->Current(), gsMarkPtrsAndAssignGroups, (void*)&newState);
+ comp->fgWalkTreePre(&args->Current(), gsMarkPtrsAndAssignGroups, (void*)&newState);
}
if (tree->gtCall.gtCallType == CT_INDIRECT)
@@ -213,7 +213,7 @@ Compiler::fgWalkResult Compiler::gsMarkPtrsAndAssignGroups(GenTreePtr* pTree, fg
// A function pointer is treated like a write-through pointer since
// it controls what code gets executed, and so indirectly can cause
// a write to memory.
- comp->fgWalkTreePre(&tree->gtCall.gtCallAddr, gsMarkPtrsAndAssignGroups, (void*)&newState);
+ comp->fgWalkTreePre(&tree->gtCall.gtCallAddr, gsMarkPtrsAndAssignGroups, (void*)&newState);
}
}
return WALK_SKIP_SUBTREES;
@@ -223,7 +223,7 @@ Compiler::fgWalkResult Compiler::gsMarkPtrsAndAssignGroups(GenTreePtr* pTree, fg
// We'll assume p in "**p = " can be vulnerable because by changing 'p', someone
// could control where **p stores to.
{
- comp->fgWalkTreePre(&tree->gtOp.gtOp1, comp->gsMarkPtrsAndAssignGroups, (void*)&newState);
+ comp->fgWalkTreePre(&tree->gtOp.gtOp1, comp->gsMarkPtrsAndAssignGroups, (void*)&newState);
}
return WALK_SKIP_SUBTREES;
@@ -251,7 +251,7 @@ Compiler::fgWalkResult Compiler::gsMarkPtrsAndAssignGroups(GenTreePtr* pTree, fg
{
// Walk dst side
comp->fgWalkTreePre(&tree->gtOp.gtOp1, comp->gsMarkPtrsAndAssignGroups, (void*)&newState);
-
+
// Now handle src side
isLocVar = tree->gtOp.gtOp1->OperGet() == GT_LCL_VAR;
isLocFld = tree->gtOp.gtOp1->OperGet() == GT_LCL_FLD;
@@ -262,7 +262,7 @@ Compiler::fgWalkResult Compiler::gsMarkPtrsAndAssignGroups(GenTreePtr* pTree, fg
newState.lvAssignDef = lclNum;
newState.isAssignSrc = true;
}
-
+
comp->fgWalkTreePre(&tree->gtOp.gtOp2, comp->gsMarkPtrsAndAssignGroups, (void*)&newState);
}
@@ -377,7 +377,7 @@ bool Compiler::gsFindVulnerableParams()
*/
void Compiler::gsParamsToShadows()
{
- // Cache old count since we'll add new variables, and
+ // Cache old count since we'll add new variables, and
// gsShadowVarInfo will not grow to accomodate the new ones.
UINT lvaOldCount = lvaCount;
@@ -513,7 +513,7 @@ void Compiler::gsParamsToShadows()
GenTreePtr src = gtNewLclvNode(shadowVar, lvaTable[shadowVar].TypeGet());
GenTreePtr dst = gtNewLclvNode(lclNum, varDsc->TypeGet());
-
+
src->gtFlags |= GTF_DONT_CSE;
dst->gtFlags |= GTF_DONT_CSE;
@@ -530,7 +530,7 @@ void Compiler::gsParamsToShadows()
{
opAssign = gtNewAssignNode(dst, src);
}
-
+
(void)fgInsertStmtNearEnd(block, fgMorphTree(opAssign));
}
}
@@ -552,8 +552,8 @@ Compiler::fgWalkResult Compiler::gsReplaceShadowParams(GenTreePtr* pTree, fgWalk
{
asg = tree; // "asg" is the assignment tree.
tree = tree->gtOp.gtOp1; // "tree" is the local var tree at the left-hand size of the assignment.
- }
-
+ }
+
if (tree->gtOper == GT_LCL_VAR || tree->gtOper == GT_LCL_FLD)
{
UINT paramNum = tree->gtLclVarCommon.gtLclNum;
@@ -571,7 +571,7 @@ Compiler::fgWalkResult Compiler::gsReplaceShadowParams(GenTreePtr* pTree, fgWalk
if (varTypeIsSmall(comp->lvaTable[paramNum].TypeGet()))
{
tree->gtType = TYP_INT;
- if (asg)
+ if (asg)
{
// If this is an assignment tree, propagate the type to it as well.
asg->gtType = TYP_INT;
diff --git a/src/jit/gtlist.h b/src/jit/gtlist.h
index a03bcfe4b0..92265a7359 100644
--- a/src/jit/gtlist.h
+++ b/src/jit/gtlist.h
@@ -9,245 +9,270 @@
#endif
/*****************************************************************************/
//
-// Node enum
-// , "Node name"
-// ,commutative
-// ,operKind
+// Node enum
+// ,"Node name"
+// ,GenTree struct flavor
+// ,commutative
+// ,operKind
-GTNODE(NONE , "<none>" ,0,GTK_SPECIAL)
+GTNODE(NONE , "<none>" ,char ,0,GTK_SPECIAL)
//-----------------------------------------------------------------------------
// Leaf nodes (i.e. these nodes have no sub-operands):
//-----------------------------------------------------------------------------
-GTNODE(LCL_VAR , "lclVar" ,0,GTK_LEAF|GTK_LOCAL) // local variable
-GTNODE(LCL_FLD , "lclFld" ,0,GTK_LEAF|GTK_LOCAL) // field in a non-primitive variable
-GTNODE(LCL_VAR_ADDR , "&lclVar" ,0,GTK_LEAF) // address of local variable
-GTNODE(LCL_FLD_ADDR , "&lclFld" ,0,GTK_LEAF) // address of field in a non-primitive variable
-GTNODE(STORE_LCL_VAR , "st.lclVar" ,0,GTK_UNOP|GTK_LOCAL|GTK_NOVALUE) // store to local variable
-GTNODE(STORE_LCL_FLD , "st.lclFld" ,0,GTK_UNOP|GTK_LOCAL|GTK_NOVALUE) // store to field in a non-primitive variable
-GTNODE(CATCH_ARG , "catchArg" ,0,GTK_LEAF) // Exception object in a catch block
-GTNODE(LABEL , "codeLabel" ,0,GTK_LEAF) // Jump-target
-GTNODE(FTN_ADDR , "ftnAddr" ,0,GTK_LEAF) // Address of a function
-GTNODE(RET_EXPR , "retExpr" ,0,GTK_LEAF) // Place holder for the return expression from an inline candidate
+GTNODE(LCL_VAR , "lclVar" ,GenTreeLclVar ,0,GTK_LEAF|GTK_LOCAL) // local variable
+GTNODE(LCL_FLD , "lclFld" ,GenTreeLclFld ,0,GTK_LEAF|GTK_LOCAL) // field in a non-primitive variable
+GTNODE(LCL_VAR_ADDR , "&lclVar" ,GenTreeLclVar ,0,GTK_LEAF) // address of local variable
+GTNODE(LCL_FLD_ADDR , "&lclFld" ,GenTreeLclFld ,0,GTK_LEAF) // address of field in a non-primitive variable
+GTNODE(STORE_LCL_VAR , "st.lclVar" ,GenTreeLclVar ,0,GTK_UNOP|GTK_LOCAL|GTK_NOVALUE) // store to local variable
+GTNODE(STORE_LCL_FLD , "st.lclFld" ,GenTreeLclFld ,0,GTK_UNOP|GTK_LOCAL|GTK_NOVALUE) // store to field in a non-primitive variable
+GTNODE(CATCH_ARG , "catchArg" ,GenTree ,0,GTK_LEAF) // Exception object in a catch block
+GTNODE(LABEL , "codeLabel" ,GenTreeLabel ,0,GTK_LEAF) // Jump-target
+GTNODE(FTN_ADDR , "ftnAddr" ,GenTreeFptrVal ,0,GTK_LEAF) // Address of a function
+GTNODE(RET_EXPR , "retExpr" ,GenTreeRetExpr ,0,GTK_LEAF) // Place holder for the return expression from an inline candidate
//-----------------------------------------------------------------------------
// Constant nodes:
//-----------------------------------------------------------------------------
-GTNODE(CNS_INT , "const" ,0,GTK_LEAF|GTK_CONST)
-GTNODE(CNS_LNG , "lconst" ,0,GTK_LEAF|GTK_CONST)
-GTNODE(CNS_DBL , "dconst" ,0,GTK_LEAF|GTK_CONST)
-GTNODE(CNS_STR , "sconst" ,0,GTK_LEAF|GTK_CONST)
+GTNODE(CNS_INT , "const" ,GenTreeIntCon ,0,GTK_LEAF|GTK_CONST)
+GTNODE(CNS_LNG , "lconst" ,GenTreeLngCon ,0,GTK_LEAF|GTK_CONST)
+GTNODE(CNS_DBL , "dconst" ,GenTreeDblCon ,0,GTK_LEAF|GTK_CONST)
+GTNODE(CNS_STR , "sconst" ,GenTreeStrCon ,0,GTK_LEAF|GTK_CONST)
//-----------------------------------------------------------------------------
// Unary operators (1 operand):
//-----------------------------------------------------------------------------
-GTNODE(NOT , "~" ,0,GTK_UNOP)
-GTNODE(NOP , "nop" ,0,GTK_UNOP)
-GTNODE(NEG , "unary -" ,0,GTK_UNOP)
-GTNODE(COPY , "copy" ,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.
-GTNODE(RELOAD , "reload" ,0,GTK_UNOP)
-GTNODE(CHS , "flipsign" ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR) // GT_CHS is actually unary -- op2 is ignored.
- // Changing to unary presently causes problems, though -- take a little work to fix.
-
-GTNODE(ARR_LENGTH , "arrLen" ,0,GTK_UNOP|GTK_EXOP) // array-length
-
-GTNODE(INTRINSIC , "intrinsic" ,0,GTK_BINOP|GTK_EXOP) // intrinsics
-
-GTNODE(LOCKADD , "lockAdd" ,0,GTK_BINOP|GTK_NOVALUE)
-GTNODE(XADD , "XAdd" ,0,GTK_BINOP)
-GTNODE(XCHG , "Xchg" ,0,GTK_BINOP)
-GTNODE(CMPXCHG , "cmpxchg" ,0,GTK_SPECIAL)
-GTNODE(MEMORYBARRIER , "memoryBarrier" ,0,GTK_LEAF|GTK_NOVALUE)
-
-GTNODE(CAST , "cast" ,0,GTK_UNOP|GTK_EXOP) // conversion to another type
-GTNODE(CKFINITE , "ckfinite" ,0,GTK_UNOP) // Check for NaN
-GTNODE(LCLHEAP , "lclHeap" ,0,GTK_UNOP) // alloca()
-GTNODE(JMP , "jump" ,0,GTK_LEAF|GTK_NOVALUE) // Jump to another function
-
-
-GTNODE(ADDR , "addr" ,0,GTK_UNOP) // address of
-GTNODE(IND , "indir" ,0,GTK_UNOP) // load indirection
-GTNODE(STOREIND , "storeIndir" ,0,GTK_BINOP|GTK_NOVALUE) // store indirection
-
- // TODO-Cleanup: GT_ARR_BOUNDS_CHECK should be made a GTK_BINOP now that it has only two child nodes
-GTNODE(ARR_BOUNDS_CHECK , "arrBndsChk" ,0,GTK_SPECIAL|GTK_NOVALUE) // array bounds check
-GTNODE(OBJ , "obj" ,0,GTK_UNOP|GTK_EXOP) // Object that MAY have gc pointers, and thus includes the relevant gc layout info.
-GTNODE(STORE_OBJ , "storeObj" ,0,GTK_BINOP|GTK_EXOP|GTK_NOVALUE) // Object that MAY have gc pointers, and thus includes the relevant gc layout info.
-GTNODE(BLK , "blk" ,0,GTK_UNOP) // Block/object with no gc pointers, and with a known size (e.g. a struct with no gc fields)
-GTNODE(STORE_BLK , "storeBlk" ,0,GTK_BINOP|GTK_NOVALUE) // Block/object with no gc pointers, and with a known size (e.g. a struct with no gc fields)
-GTNODE(DYN_BLK , "DynBlk" ,0,GTK_SPECIAL) // Dynamically sized block object
-GTNODE(STORE_DYN_BLK , "storeDynBlk" ,0,GTK_SPECIAL|GTK_NOVALUE) // Dynamically sized block object
-GTNODE(BOX , "box" ,0,GTK_UNOP|GTK_EXOP|GTK_NOTLIR)
+GTNODE(NOT , "~" ,GenTreeOp ,0,GTK_UNOP)
+GTNODE(NOP , "nop" ,GenTree ,0,GTK_UNOP)
+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.
+GTNODE(RELOAD , "reload" ,GenTreeCopyOrReload,0,GTK_UNOP)
+GTNODE(CHS , "flipsign" ,GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR) // GT_CHS is actually unary -- op2 is ignored.
+ // Changing to unary presently causes problems, though -- take a little work to fix.
+
+GTNODE(ARR_LENGTH , "arrLen" ,GenTreeArrLen ,0,GTK_UNOP|GTK_EXOP) // array-length
+
+GTNODE(INTRINSIC , "intrinsic" ,GenTreeIntrinsic ,0,GTK_BINOP|GTK_EXOP) // intrinsics
+
+GTNODE(LOCKADD , "lockAdd" ,GenTreeOp ,0,GTK_BINOP|GTK_NOVALUE)
+GTNODE(XADD , "XAdd" ,GenTreeOp ,0,GTK_BINOP)
+GTNODE(XCHG , "Xchg" ,GenTreeOp ,0,GTK_BINOP)
+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(JMP , "jump" ,GenTreeVal ,0,GTK_LEAF|GTK_NOVALUE) // Jump to another function
+
+GTNODE(ADDR , "addr" ,GenTreeOp ,0,GTK_UNOP) // address of
+GTNODE(IND , "indir" ,GenTreeOp ,0,GTK_UNOP) // load indirection
+GTNODE(STOREIND , "storeIndir" ,GenTreeStoreInd ,0,GTK_BINOP|GTK_NOVALUE) // store indirection
+
+ // TODO-Cleanup: GT_ARR_BOUNDS_CHECK should be made a GTK_BINOP now that it has only two child nodes
+GTNODE(ARR_BOUNDS_CHECK , "arrBndsChk" ,GenTreeBoundsChk ,0,GTK_SPECIAL|GTK_NOVALUE)// array bounds check
+GTNODE(OBJ , "obj" ,GenTreeObj ,0,GTK_UNOP|GTK_EXOP) // Object that MAY have gc pointers, and thus includes the relevant gc layout info.
+GTNODE(STORE_OBJ , "storeObj" ,GenTreeBlk ,0,GTK_BINOP|GTK_EXOP|GTK_NOVALUE) // Object that MAY have gc pointers, and thus includes the relevant gc layout info.
+GTNODE(BLK , "blk" ,GenTreeBlk ,0,GTK_UNOP) // Block/object with no gc pointers, and with a known size (e.g. a struct with no gc fields)
+GTNODE(STORE_BLK , "storeBlk" ,GenTreeBlk ,0,GTK_BINOP|GTK_NOVALUE) // Block/object with no gc pointers, and with a known size (e.g. a struct with no gc fields)
+GTNODE(DYN_BLK , "DynBlk" ,GenTreeBlk ,0,GTK_SPECIAL) // Dynamically sized block object
+GTNODE(STORE_DYN_BLK , "storeDynBlk" ,GenTreeBlk ,0,GTK_SPECIAL|GTK_NOVALUE)// Dynamically sized block object
+GTNODE(BOX , "box" ,GenTreeBox ,0,GTK_UNOP|GTK_EXOP|GTK_NOTLIR)
#ifdef FEATURE_SIMD
-GTNODE(SIMD_CHK , "simdChk" ,0,GTK_SPECIAL|GTK_NOVALUE) // Compare whether an index is less than the given SIMD vector length, and call CORINFO_HELP_RNGCHKFAIL if not.
- // TODO-CQ: In future may want to add a field that specifies different exceptions but we'll
- // need VM assistance for that.
- // TODO-CQ: It would actually be very nice to make this an unconditional throw, and expose the control flow that
- // does the compare, so that it can be more easily optimized. But that involves generating qmarks at import time...
+GTNODE(SIMD_CHK , "simdChk" ,GenTreeBoundsChk ,0,GTK_SPECIAL|GTK_NOVALUE)// Compare whether an index is less than the given SIMD vector length, and call CORINFO_HELP_RNGCHKFAIL if not.
+ // TODO-CQ: In future may want to add a field that specifies different exceptions but we'll
+ // need VM assistance for that.
+ // TODO-CQ: It would actually be very nice to make this an unconditional throw, and expose the control flow that
+ // does the compare, so that it can be more easily optimized. But that involves generating qmarks at import time...
#endif // FEATURE_SIMD
-GTNODE(ALLOCOBJ , "allocObj" ,0,GTK_UNOP|GTK_EXOP) // object allocator
+GTNODE(ALLOCOBJ , "allocObj" ,GenTreeAllocObj ,0,GTK_UNOP|GTK_EXOP) // object allocator
+
+GTNODE(INIT_VAL , "initVal" ,GenTreeOp ,0,GTK_UNOP) // Initialization value for an initBlk
//-----------------------------------------------------------------------------
// Binary operators (2 operands):
//-----------------------------------------------------------------------------
-GTNODE(ADD , "+" ,1,GTK_BINOP)
-GTNODE(SUB , "-" ,0,GTK_BINOP)
-GTNODE(MUL , "*" ,1,GTK_BINOP)
-GTNODE(DIV , "/" ,0,GTK_BINOP)
-GTNODE(MOD , "%" ,0,GTK_BINOP)
+GTNODE(ADD , "+" ,GenTreeOp ,1,GTK_BINOP)
+GTNODE(SUB , "-" ,GenTreeOp ,0,GTK_BINOP)
+GTNODE(MUL , "*" ,GenTreeOp ,1,GTK_BINOP)
+GTNODE(DIV , "/" ,GenTreeOp ,0,GTK_BINOP)
+GTNODE(MOD , "%" ,GenTreeOp ,0,GTK_BINOP)
-GTNODE(UDIV , "un-/" ,0,GTK_BINOP)
-GTNODE(UMOD , "un-%" ,0,GTK_BINOP)
+GTNODE(UDIV , "un-/" ,GenTreeOp ,0,GTK_BINOP)
+GTNODE(UMOD , "un-%" ,GenTreeOp ,0,GTK_BINOP)
-GTNODE(OR , "|" ,1,GTK_BINOP|GTK_LOGOP)
-GTNODE(XOR , "^" ,1,GTK_BINOP|GTK_LOGOP)
-GTNODE(AND , "&" ,1,GTK_BINOP|GTK_LOGOP)
+GTNODE(OR , "|" ,GenTreeOp ,1,GTK_BINOP|GTK_LOGOP)
+GTNODE(XOR , "^" ,GenTreeOp ,1,GTK_BINOP|GTK_LOGOP)
+GTNODE(AND , "&" ,GenTreeOp ,1,GTK_BINOP|GTK_LOGOP)
-GTNODE(LSH , "<<" ,0,GTK_BINOP)
-GTNODE(RSH , ">>" ,0,GTK_BINOP)
-GTNODE(RSZ , ">>>" ,0,GTK_BINOP)
-GTNODE(ROL , "rol" ,0,GTK_BINOP)
-GTNODE(ROR , "ror" ,0,GTK_BINOP)
-GTNODE(MULHI , "mulhi" ,1,GTK_BINOP) // returns high bits (top N bits of the 2N bit result of an NxN multiply)
+GTNODE(LSH , "<<" ,GenTreeOp ,0,GTK_BINOP)
+GTNODE(RSH , ">>" ,GenTreeOp ,0,GTK_BINOP)
+GTNODE(RSZ , ">>>" ,GenTreeOp ,0,GTK_BINOP)
+GTNODE(ROL , "rol" ,GenTreeOp ,0,GTK_BINOP)
+GTNODE(ROR , "ror" ,GenTreeOp ,0,GTK_BINOP)
+GTNODE(MULHI , "mulhi" ,GenTreeOp ,1,GTK_BINOP) // returns high bits (top N bits of the 2N bit result of an NxN multiply)
+ // GT_MULHI is used in division by a constant (fgMorphDivByConst). We turn
+ // the div into a MULHI + some adjustments. In codegen, we only use the
+ // results of the high register, and we drop the low results.
-GTNODE(ASG , "=" ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
-GTNODE(ASG_ADD , "+=" ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
-GTNODE(ASG_SUB , "-=" ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
-GTNODE(ASG_MUL , "*=" ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
-GTNODE(ASG_DIV , "/=" ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
-GTNODE(ASG_MOD , "%=" ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
+GTNODE(ASG , "=" ,GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
+GTNODE(ASG_ADD , "+=" ,GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
+GTNODE(ASG_SUB , "-=" ,GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
+GTNODE(ASG_MUL , "*=" ,GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
+GTNODE(ASG_DIV , "/=" ,GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
+GTNODE(ASG_MOD , "%=" ,GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
-GTNODE(ASG_UDIV , "/=" ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
-GTNODE(ASG_UMOD , "%=" ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
+GTNODE(ASG_UDIV , "/=" ,GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
+GTNODE(ASG_UMOD , "%=" ,GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
-GTNODE(ASG_OR , "|=" ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
-GTNODE(ASG_XOR , "^=" ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
-GTNODE(ASG_AND , "&=" ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
-GTNODE(ASG_LSH , "<<=" ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
-GTNODE(ASG_RSH , ">>=" ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
-GTNODE(ASG_RSZ , ">>>=" ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
+GTNODE(ASG_OR , "|=" ,GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
+GTNODE(ASG_XOR , "^=" ,GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
+GTNODE(ASG_AND , "&=" ,GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
+GTNODE(ASG_LSH , "<<=" ,GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
+GTNODE(ASG_RSH , ">>=" ,GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
+GTNODE(ASG_RSZ , ">>>=" ,GenTreeOp ,0,GTK_BINOP|GTK_ASGOP|GTK_NOTLIR)
-GTNODE(EQ , "==" ,0,GTK_BINOP|GTK_RELOP)
-GTNODE(NE , "!=" ,0,GTK_BINOP|GTK_RELOP)
-GTNODE(LT , "<" ,0,GTK_BINOP|GTK_RELOP)
-GTNODE(LE , "<=" ,0,GTK_BINOP|GTK_RELOP)
-GTNODE(GE , ">=" ,0,GTK_BINOP|GTK_RELOP)
-GTNODE(GT , ">" ,0,GTK_BINOP|GTK_RELOP)
+GTNODE(EQ , "==" ,GenTreeOp ,0,GTK_BINOP|GTK_RELOP)
+GTNODE(NE , "!=" ,GenTreeOp ,0,GTK_BINOP|GTK_RELOP)
+GTNODE(LT , "<" ,GenTreeOp ,0,GTK_BINOP|GTK_RELOP)
+GTNODE(LE , "<=" ,GenTreeOp ,0,GTK_BINOP|GTK_RELOP)
+GTNODE(GE , ">=" ,GenTreeOp ,0,GTK_BINOP|GTK_RELOP)
+GTNODE(GT , ">" ,GenTreeOp ,0,GTK_BINOP|GTK_RELOP)
-GTNODE(COMMA , "comma" ,0,GTK_BINOP|GTK_NOTLIR)
+GTNODE(COMMA , "comma" ,GenTreeOp ,0,GTK_BINOP|GTK_NOTLIR)
-GTNODE(QMARK , "qmark" ,0,GTK_BINOP|GTK_EXOP|GTK_NOTLIR)
-GTNODE(COLON , "colon" ,0,GTK_BINOP|GTK_NOTLIR)
+GTNODE(QMARK , "qmark" ,GenTreeQmark ,0,GTK_BINOP|GTK_EXOP|GTK_NOTLIR)
+GTNODE(COLON , "colon" ,GenTreeColon ,0,GTK_BINOP|GTK_NOTLIR)
-GTNODE(INDEX , "[]" ,0,GTK_BINOP|GTK_EXOP|GTK_NOTLIR) // SZ-array-element
+GTNODE(INDEX , "[]" ,GenTreeIndex ,0,GTK_BINOP|GTK_EXOP|GTK_NOTLIR) // SZ-array-element
-GTNODE(MKREFANY , "mkrefany" ,0,GTK_BINOP)
+GTNODE(MKREFANY , "mkrefany" ,GenTreeOp ,0,GTK_BINOP)
-GTNODE(LEA , "lea" ,0,GTK_BINOP|GTK_EXOP)
+GTNODE(LEA , "lea" ,GenTreeAddrMode ,0,GTK_BINOP|GTK_EXOP)
#if !defined(LEGACY_BACKEND) && !defined(_TARGET_64BIT_)
// A GT_LONG node simply represents the long value produced by the concatenation
// of its two (lower and upper half) operands. Some GT_LONG nodes are transient,
// during the decomposing of longs; others are handled by codegen as operands of
// nodes such as calls, returns and stores of long lclVars.
-GTNODE(LONG , "gt_long" ,0,GTK_BINOP)
-
-// The following are nodes representing the upper half of a 64-bit operation
-// that requires a carry/borrow. However, they are all named GT_XXX_HI for
-// consistency.
-GTNODE(ADD_LO , "+Lo" ,1,GTK_BINOP)
-GTNODE(ADD_HI , "+Hi" ,1,GTK_BINOP)
-GTNODE(SUB_LO , "-Lo" ,0,GTK_BINOP)
-GTNODE(SUB_HI , "-Hi" ,0,GTK_BINOP)
-GTNODE(MUL_HI , "*Hi" ,1,GTK_BINOP)
-GTNODE(DIV_HI , "/Hi" ,0,GTK_BINOP)
-GTNODE(MOD_HI , "%Hi" ,0,GTK_BINOP)
+GTNODE(LONG , "gt_long" ,GenTreeOp ,0,GTK_BINOP)
+
+// The following are nodes representing x86 specific long operators, including
+// high operators of a 64-bit operations that requires a carry/borrow, which are
+// named GT_XXX_HI for consistency, low operators of 64-bit operations that need
+// to not be modified in phases post-decompose, and operators that return 64-bit
+// results in one instruction.
+GTNODE(ADD_LO , "+Lo" ,GenTreeOp ,1,GTK_BINOP)
+GTNODE(ADD_HI , "+Hi" ,GenTreeOp ,1,GTK_BINOP)
+GTNODE(SUB_LO , "-Lo" ,GenTreeOp ,0,GTK_BINOP)
+GTNODE(SUB_HI , "-Hi" ,GenTreeOp ,0,GTK_BINOP)
+GTNODE(DIV_HI , "/Hi" ,GenTreeOp ,0,GTK_BINOP)
+GTNODE(MOD_HI , "%Hi" ,GenTreeOp ,0,GTK_BINOP)
+GTNODE(MUL_LONG , "*long" ,GenTreeOp ,1,GTK_BINOP) // A mul that returns the 2N bit result of an NxN multiply. This op
+ // is used for x86 multiplies that take two ints and return a long
+ // result. All other multiplies with long results are morphed into
+ // helper calls. It is similar to GT_MULHI, the difference being that
+ // GT_MULHI drops the lo part of the result, whereas GT_MUL_LONG keeps
+ // both parts of the result.
+
+// The following are nodes that specify shifts that take a GT_LONG op1. The GT_LONG
+// contains the hi and lo parts of three operand shift form where one op will be
+// shifted into the other op as part of the operation (LSH_HI will shift
+// the high bits of the lo operand into the high operand as it shifts left. RSH_LO
+// will shift the lo bits of the high operand into the lo operand). LSH_HI
+// represents the high operation of a 64-bit left shift by a constant int, and
+// RSH_LO represents the lo operation of a 64-bit right shift by a constant int.
+GTNODE(LSH_HI , "<<Hi" ,GenTreeOp ,0,GTK_BINOP)
+GTNODE(RSH_LO , ">>Lo" ,GenTreeOp ,0,GTK_BINOP)
#endif // !defined(LEGACY_BACKEND) && !defined(_TARGET_64BIT_)
#ifdef FEATURE_SIMD
-GTNODE(SIMD , "simd" ,0,GTK_BINOP|GTK_EXOP) // SIMD functions/operators/intrinsics
+GTNODE(SIMD , "simd" ,GenTreeSIMD ,0,GTK_BINOP|GTK_EXOP) // SIMD functions/operators/intrinsics
#endif // FEATURE_SIMD
//-----------------------------------------------------------------------------
// Other nodes that look like unary/binary operators:
//-----------------------------------------------------------------------------
-GTNODE(JTRUE , "jmpTrue" ,0,GTK_UNOP|GTK_NOVALUE)
+GTNODE(JTRUE , "jmpTrue" ,GenTreeOp ,0,GTK_UNOP|GTK_NOVALUE)
+GTNODE(JCC , "jcc" ,GenTreeJumpCC ,0,GTK_LEAF|GTK_NOVALUE)
-GTNODE(LIST , "<list>" ,0,GTK_BINOP)
+GTNODE(LIST , "<list>" ,GenTreeArgList ,0,GTK_BINOP|GTK_NOVALUE)
+GTNODE(FIELD_LIST , "<fldList>" ,GenTreeFieldList ,0,GTK_BINOP) // List of fields of a struct, when passed as an argument
//-----------------------------------------------------------------------------
// Other nodes that have special structure:
//-----------------------------------------------------------------------------
-GTNODE(FIELD , "field" ,0,GTK_SPECIAL) // Member-field
-GTNODE(ARR_ELEM , "arrMD&" ,0,GTK_SPECIAL) // Multi-dimensional array-element address
-GTNODE(ARR_INDEX , "arrMDIdx" ,0,GTK_BINOP|GTK_EXOP) // Effective, bounds-checked index for one dimension of a multi-dimensional array element
-GTNODE(ARR_OFFSET , "arrMDOffs" ,0,GTK_SPECIAL) // Flattened offset of multi-dimensional array element
-GTNODE(CALL , "call()" ,0,GTK_SPECIAL)
+GTNODE(FIELD , "field" ,GenTreeField ,0,GTK_SPECIAL) // Member-field
+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)
//-----------------------------------------------------------------------------
// Statement operator nodes:
//-----------------------------------------------------------------------------
-GTNODE(BEG_STMTS , "begStmts" ,0,GTK_SPECIAL|GTK_NOVALUE) // used only temporarily in importer by impBegin/EndTreeList()
-GTNODE(STMT , "stmtExpr" ,0,GTK_SPECIAL|GTK_NOVALUE) // top-level list nodes in bbTreeList
+GTNODE(BEG_STMTS , "begStmts" ,GenTree ,0,GTK_SPECIAL|GTK_NOVALUE)// used only temporarily in importer by impBegin/EndTreeList()
+GTNODE(STMT , "stmtExpr" ,GenTreeStmt ,0,GTK_SPECIAL|GTK_NOVALUE)// top-level list nodes in bbTreeList
-GTNODE(RETURN , "return" ,0,GTK_UNOP|GTK_NOVALUE) // return from current function
-GTNODE(SWITCH , "switch" ,0,GTK_UNOP|GTK_NOVALUE) // switch
+GTNODE(RETURN , "return" ,GenTreeOp ,0,GTK_UNOP|GTK_NOVALUE) // return from current function
+GTNODE(SWITCH , "switch" ,GenTreeOp ,0,GTK_UNOP|GTK_NOVALUE) // switch
-GTNODE(NO_OP , "no_op" ,0,GTK_LEAF|GTK_NOVALUE) // nop!
+GTNODE(NO_OP , "no_op" ,GenTree ,0,GTK_LEAF|GTK_NOVALUE) // nop!
-GTNODE(START_NONGC, "start_nongc",0,GTK_LEAF|GTK_NOVALUE) // starts a new instruction group that will be non-gc interruptible
+GTNODE(START_NONGC , "start_nongc" ,GenTree ,0,GTK_LEAF|GTK_NOVALUE) // starts a new instruction group that will be non-gc interruptible
-GTNODE(PROF_HOOK , "prof_hook" ,0,GTK_LEAF|GTK_NOVALUE) // profiler Enter/Leave/TailCall hook
+GTNODE(PROF_HOOK , "prof_hook" ,GenTree ,0,GTK_LEAF|GTK_NOVALUE) // profiler Enter/Leave/TailCall hook
-GTNODE(RETFILT , "retfilt", 0,GTK_UNOP|GTK_NOVALUE) // end filter with TYP_I_IMPL return value
+GTNODE(RETFILT , "retfilt" ,GenTreeOp ,0,GTK_UNOP|GTK_NOVALUE) // end filter with TYP_I_IMPL return value
#if !FEATURE_EH_FUNCLETS
-GTNODE(END_LFIN , "endLFin" ,0,GTK_LEAF|GTK_NOVALUE) // end locally-invoked finally
+GTNODE(END_LFIN , "endLFin" ,GenTreeVal ,0,GTK_LEAF|GTK_NOVALUE) // end locally-invoked finally
#endif // !FEATURE_EH_FUNCLETS
//-----------------------------------------------------------------------------
// Nodes used for optimizations.
//-----------------------------------------------------------------------------
-GTNODE(PHI , "phi" ,0,GTK_UNOP) // phi node for ssa.
-GTNODE(PHI_ARG , "phiArg" ,0,GTK_LEAF|GTK_LOCAL) // phi(phiarg, phiarg, phiarg)
+GTNODE(PHI , "phi" ,GenTreeOp ,0,GTK_UNOP) // phi node for ssa.
+GTNODE(PHI_ARG , "phiArg" ,GenTreePhiArg ,0,GTK_LEAF|GTK_LOCAL) // phi(phiarg, phiarg, phiarg)
//-----------------------------------------------------------------------------
// Nodes used by Lower to generate a closer CPU representation of other nodes
//-----------------------------------------------------------------------------
-GTNODE(JMPTABLE , "jumpTable" , 0, GTK_LEAF) // Generates the jump table for switches
-GTNODE(SWITCH_TABLE, "tableSwitch", 0, GTK_BINOP|GTK_NOVALUE) // Jump Table based switch construct
+#ifndef LEGACY_BACKEND
+GTNODE(JMPTABLE , "jumpTable" ,GenTreeJumpTable ,0, GTK_LEAF) // Generates the jump table for switches
+#endif
+GTNODE(SWITCH_TABLE , "tableSwitch" ,GenTreeOp ,0, GTK_BINOP|GTK_NOVALUE) // Jump Table based switch construct
//-----------------------------------------------------------------------------
// Nodes used only within the code generator:
//-----------------------------------------------------------------------------
-GTNODE(REG_VAR , "regVar" ,0,GTK_LEAF|GTK_LOCAL) // register variable
-GTNODE(CLS_VAR , "clsVar" ,0,GTK_LEAF) // static data member
-GTNODE(CLS_VAR_ADDR , "&clsVar" ,0,GTK_LEAF) // static data member address
-GTNODE(STORE_CLS_VAR, "st.clsVar" ,0,GTK_LEAF|GTK_NOVALUE) // store to static data member
-GTNODE(ARGPLACE , "argPlace" ,0,GTK_LEAF) // placeholder for a register arg
-GTNODE(NULLCHECK , "nullcheck" ,0,GTK_UNOP|GTK_NOVALUE) // null checks the source
-GTNODE(PHYSREG , "physregSrc" ,0,GTK_LEAF) // read from a physical register
-GTNODE(PHYSREGDST , "physregDst" ,0,GTK_UNOP|GTK_NOVALUE) // write to a physical register
-GTNODE(EMITNOP , "emitnop" ,0,GTK_LEAF|GTK_NOVALUE) // emitter-placed nop
-GTNODE(PINVOKE_PROLOG,"pinvoke_prolog",0,GTK_LEAF|GTK_NOVALUE) // pinvoke prolog seq
-GTNODE(PINVOKE_EPILOG,"pinvoke_epilog",0,GTK_LEAF|GTK_NOVALUE) // pinvoke epilog seq
-GTNODE(PUTARG_REG , "putarg_reg" ,0,GTK_UNOP) // operator that places outgoing arg in register
-GTNODE(PUTARG_STK , "putarg_stk" ,0,GTK_UNOP) // operator that places outgoing arg in stack
-GTNODE(RETURNTRAP , "returnTrap" ,0,GTK_UNOP|GTK_NOVALUE) // a conditional call to wait on gc
-GTNODE(SWAP , "swap" ,0,GTK_BINOP|GTK_NOVALUE) // op1 and op2 swap (registers)
-GTNODE(IL_OFFSET , "il_offset" ,0,GTK_LEAF|GTK_NOVALUE) // marks an IL offset for debugging purposes
+GTNODE(REG_VAR , "regVar" ,GenTreeLclVar ,0,GTK_LEAF|GTK_LOCAL) // register variable
+GTNODE(CLS_VAR , "clsVar" ,GenTreeClsVar ,0,GTK_LEAF) // static data member
+GTNODE(CLS_VAR_ADDR , "&clsVar" ,GenTreeClsVar ,0,GTK_LEAF) // static data member address
+GTNODE(ARGPLACE , "argPlace" ,GenTreeArgPlace ,0,GTK_LEAF) // placeholder for a register arg
+GTNODE(NULLCHECK , "nullcheck" ,GenTreeOp ,0,GTK_UNOP|GTK_NOVALUE) // null checks the source
+GTNODE(PHYSREG , "physregSrc" ,GenTreePhysReg ,0,GTK_LEAF) // read from a physical register
+GTNODE(PHYSREGDST , "physregDst" ,GenTreeOp ,0,GTK_UNOP|GTK_NOVALUE) // write to a physical register
+GTNODE(EMITNOP , "emitnop" ,GenTree ,0,GTK_LEAF|GTK_NOVALUE) // emitter-placed nop
+GTNODE(PINVOKE_PROLOG ,"pinvoke_prolog",GenTree ,0,GTK_LEAF|GTK_NOVALUE) // pinvoke prolog seq
+GTNODE(PINVOKE_EPILOG ,"pinvoke_epilog",GenTree ,0,GTK_LEAF|GTK_NOVALUE) // pinvoke epilog seq
+GTNODE(PUTARG_REG , "putarg_reg" ,GenTreeOp ,0,GTK_UNOP) // operator that places outgoing arg in register
+GTNODE(PUTARG_STK , "putarg_stk" ,GenTreePutArgStk ,0,GTK_UNOP) // operator that places outgoing arg in stack
+GTNODE(RETURNTRAP , "returnTrap" ,GenTreeOp ,0,GTK_UNOP|GTK_NOVALUE) // a conditional call to wait on gc
+GTNODE(SWAP , "swap" ,GenTreeOp ,0,GTK_BINOP|GTK_NOVALUE) // op1 and op2 swap (registers)
+GTNODE(IL_OFFSET , "il_offset" ,GenTreeStmt ,0,GTK_LEAF|GTK_NOVALUE) // marks an IL offset for debugging purposes
/*****************************************************************************/
#undef GTNODE
diff --git a/src/jit/gtstructs.h b/src/jit/gtstructs.h
index 895d3b6598..ac912407be 100644
--- a/src/jit/gtstructs.h
+++ b/src/jit/gtstructs.h
@@ -65,7 +65,8 @@ GTSTRUCT_1(Cast , GT_CAST)
GTSTRUCT_1(Box , GT_BOX)
GTSTRUCT_1(Field , GT_FIELD)
GTSTRUCT_1(Call , GT_CALL)
-GTSTRUCT_1(ArgList , GT_LIST)
+GTSTRUCT_2(ArgList , GT_LIST, GT_FIELD_LIST)
+GTSTRUCT_1(FieldList , GT_FIELD_LIST)
GTSTRUCT_1(Colon , GT_COLON)
GTSTRUCT_1(FptrVal , GT_FTN_ADDR)
GTSTRUCT_1(Intrinsic , GT_INTRINSIC)
@@ -100,6 +101,7 @@ GTSTRUCT_1(PhysReg , GT_PHYSREG)
GTSTRUCT_1(SIMD , GT_SIMD)
#endif // FEATURE_SIMD
GTSTRUCT_1(AllocObj , GT_ALLOCOBJ)
+GTSTRUCT_1(JumpCC , GT_JCC)
/*****************************************************************************/
#undef GTSTRUCT_0
#undef GTSTRUCT_1
diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp
index d04ded78fa..cb09ff8b8c 100644
--- a/src/jit/importer.cpp
+++ b/src/jit/importer.cpp
@@ -63,15 +63,12 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
void Compiler::impInit()
{
-#ifdef DEBUG
- impTreeList = impTreeLast = nullptr;
-#endif
-#if defined(DEBUG)
+#ifdef DEBUG
+ impTreeList = nullptr;
+ impTreeLast = nullptr;
impInlinedCodeSize = 0;
#endif
-
- seenConditionalJump = false;
}
/*****************************************************************************
@@ -600,13 +597,9 @@ inline void Compiler::impAppendStmt(GenTreePtr stmt, unsigned chkLevel)
// Assignment to (unaliased) locals don't count as a side-effect as
// we handle them specially using impSpillLclRefs(). Temp locals should
// be fine too.
- // TODO-1stClassStructs: The check below should apply equally to struct assignments,
- // but previously the block ops were always being marked GTF_GLOB_REF, even if
- // the operands could not be global refs.
if ((expr->gtOper == GT_ASG) && (expr->gtOp.gtOp1->gtOper == GT_LCL_VAR) &&
- !(expr->gtOp.gtOp1->gtFlags & GTF_GLOB_REF) && !gtHasLocalsWithAddrOp(expr->gtOp.gtOp2) &&
- !varTypeIsStruct(expr->gtOp.gtOp1))
+ !(expr->gtOp.gtOp1->gtFlags & GTF_GLOB_REF) && !gtHasLocalsWithAddrOp(expr->gtOp.gtOp2))
{
unsigned op2Flags = expr->gtOp.gtOp2->gtFlags & GTF_GLOB_EFFECT;
assert(flags == (op2Flags | GTF_ASG));
@@ -673,8 +666,6 @@ inline void Compiler::impAppendStmt(GenTreePtr stmt, unsigned chkLevel)
impMarkContiguousSIMDFieldAssignments(stmt);
#endif
-#ifdef DEBUGGING_SUPPORT
-
/* Once we set impCurStmtOffs in an appended tree, we are ready to
report the following offsets. So reset impCurStmtOffs */
@@ -683,8 +674,6 @@ inline void Compiler::impAppendStmt(GenTreePtr stmt, unsigned chkLevel)
impCurStmtOffsSet(BAD_IL_OFFSET);
}
-#endif
-
#ifdef DEBUG
if (impLastILoffsStmt == nullptr)
{
@@ -1143,9 +1132,13 @@ GenTreePtr Compiler::impAssignStructPtr(GenTreePtr destAddr,
if (destAddr->OperGet() == GT_ADDR)
{
GenTree* destNode = destAddr->gtGetOp1();
- // If the actual destination is already a block node, or is a node that
+ // If the actual destination is a local (for non-LEGACY_BACKEND), or already a block node, or is a node that
// will be morphed, don't insert an OBJ(ADDR).
- if (destNode->gtOper == GT_INDEX || destNode->OperIsBlk())
+ if (destNode->gtOper == GT_INDEX || destNode->OperIsBlk()
+#ifndef LEGACY_BACKEND
+ || ((destNode->OperGet() == GT_LCL_VAR) && (destNode->TypeGet() == src->TypeGet()))
+#endif // !LEGACY_BACKEND
+ )
{
dest = destNode;
}
@@ -1194,6 +1187,9 @@ GenTreePtr Compiler::impAssignStructPtr(GenTreePtr destAddr,
{
// Mark the struct LclVar as used in a MultiReg return context
// which currently makes it non promotable.
+ // TODO-1stClassStructs: Eliminate this pessimization when we can more generally
+ // handle multireg returns.
+ lcl->gtFlags |= GTF_DONT_CSE;
lvaTable[lcl->gtLclVarCommon.gtLclNum].lvIsMultiRegRet = true;
}
else // The call result is not a multireg return
@@ -1208,12 +1204,20 @@ GenTreePtr Compiler::impAssignStructPtr(GenTreePtr destAddr,
dest = lcl;
#if defined(_TARGET_ARM_)
+ // TODO-Cleanup: This should have been taken care of in the above HasMultiRegRetVal() case,
+ // but that method has not been updadted to include ARM.
impMarkLclDstNotPromotable(lcl->gtLclVarCommon.gtLclNum, src, structHnd);
+ lcl->gtFlags |= GTF_DONT_CSE;
#elif defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
// Not allowed for FEATURE_CORCLR which is the only SKU available for System V OSs.
assert(!src->gtCall.IsVarargs() && "varargs not allowed for System V OSs.");
// Make the struct non promotable. The eightbytes could contain multiple fields.
+ // TODO-1stClassStructs: Eliminate this pessimization when we can more generally
+ // handle multireg returns.
+ // TODO-Cleanup: Why is this needed here? This seems that it will set this even for
+ // non-multireg returns.
+ lcl->gtFlags |= GTF_DONT_CSE;
lvaTable[lcl->gtLclVarCommon.gtLclNum].lvIsMultiRegRet = true;
#endif
}
@@ -1255,10 +1259,11 @@ GenTreePtr Compiler::impAssignStructPtr(GenTreePtr destAddr,
src->gtType = genActualType(returnType);
call->gtType = src->gtType;
- // 1stClassStructToDo: We shouldn't necessarily need this.
- if (dest != nullptr)
+ // If we've changed the type, and it no longer matches a local destination,
+ // we must use an indirection.
+ if ((dest != nullptr) && (dest->OperGet() == GT_LCL_VAR) && (dest->TypeGet() != asgType))
{
- dest = gtNewOperNode(GT_IND, returnType, gtNewOperNode(GT_ADDR, TYP_BYREF, dest));
+ dest = nullptr;
}
// !!! The destination could be on stack. !!!
@@ -1329,21 +1334,19 @@ GenTreePtr Compiler::impAssignStructPtr(GenTreePtr destAddr,
}
else if (src->IsLocal())
{
- // TODO-1stClassStructs: Eliminate this; it is only here to minimize diffs in the
- // initial implementation. Previously the source would have been under a GT_ADDR, which
- // would cause it to be marked GTF_DONT_CSE.
asgType = src->TypeGet();
- src->gtFlags |= GTF_DONT_CSE;
- if (asgType == TYP_STRUCT)
- {
- GenTree* srcAddr = gtNewOperNode(GT_ADDR, TYP_BYREF, src);
- src = gtNewOperNode(GT_IND, TYP_STRUCT, srcAddr);
- }
}
else if (asgType == TYP_STRUCT)
{
asgType = impNormStructType(structHnd);
src->gtType = asgType;
+#ifdef LEGACY_BACKEND
+ if (asgType == TYP_STRUCT)
+ {
+ GenTree* srcAddr = gtNewOperNode(GT_ADDR, TYP_BYREF, src);
+ src = gtNewOperNode(GT_IND, TYP_STRUCT, srcAddr);
+ }
+#endif
}
if (dest == nullptr)
{
@@ -1459,6 +1462,8 @@ GenTreePtr Compiler::impGetStructAddr(GenTreePtr structVal,
// into which the gcLayout will be written.
// pNumGCVars - (optional, default nullptr) - if non-null, a pointer to an unsigned,
// which will be set to the number of GC fields in the struct.
+// pSimdBaseType - (optional, default nullptr) - if non-null, and the struct is a SIMD
+// type, set to the SIMD base type
//
// Return Value:
// The JIT type for the struct (e.g. TYP_STRUCT, or TYP_SIMD*).
@@ -1480,53 +1485,69 @@ var_types Compiler::impNormStructType(CORINFO_CLASS_HANDLE structHnd,
var_types* pSimdBaseType)
{
assert(structHnd != NO_CLASS_HANDLE);
- unsigned originalSize = info.compCompHnd->getClassSize(structHnd);
- unsigned numGCVars = 0;
- var_types structType = TYP_STRUCT;
- var_types simdBaseType = TYP_UNKNOWN;
- bool definitelyHasGCPtrs = false;
-#ifdef FEATURE_SIMD
- // We don't want to consider this as a possible SIMD type if it has GC pointers.
- // (Saves querying about the SIMD assembly.)
- BYTE gcBytes[maxPossibleSIMDStructBytes / TARGET_POINTER_SIZE];
- if ((gcLayout == nullptr) && (originalSize >= minSIMDStructBytes()) && (originalSize <= maxSIMDStructBytes()))
- {
- gcLayout = gcBytes;
- }
-#endif // FEATURE_SIMD
+ const DWORD structFlags = info.compCompHnd->getClassAttribs(structHnd);
+ var_types structType = TYP_STRUCT;
+
+#ifdef FEATURE_CORECLR
+ const bool hasGCPtrs = (structFlags & CORINFO_FLG_CONTAINS_GC_PTR) != 0;
+#else
+ // Desktop CLR won't report FLG_CONTAINS_GC_PTR for RefAnyClass - need to check explicitly.
+ const bool isRefAny = (structHnd == impGetRefAnyClass());
+ const bool hasGCPtrs = isRefAny || ((structFlags & CORINFO_FLG_CONTAINS_GC_PTR) != 0);
+#endif
- if (gcLayout != nullptr)
- {
- numGCVars = info.compCompHnd->getClassGClayout(structHnd, gcLayout);
- definitelyHasGCPtrs = (numGCVars != 0);
- }
#ifdef FEATURE_SIMD
// Check to see if this is a SIMD type.
- if (featureSIMD && (originalSize <= getSIMDVectorRegisterByteLength()) && (originalSize >= TARGET_POINTER_SIZE) &&
- !definitelyHasGCPtrs)
+ if (featureSIMD && !hasGCPtrs)
{
- unsigned int sizeBytes;
- simdBaseType = getBaseTypeAndSizeOfSIMDType(structHnd, &sizeBytes);
- if (simdBaseType != TYP_UNKNOWN)
+ unsigned originalSize = info.compCompHnd->getClassSize(structHnd);
+
+ if ((originalSize >= minSIMDStructBytes()) && (originalSize <= maxSIMDStructBytes()))
{
- assert(sizeBytes == originalSize);
- structType = getSIMDTypeForSize(sizeBytes);
- if (pSimdBaseType != nullptr)
+ unsigned int sizeBytes;
+ var_types simdBaseType = getBaseTypeAndSizeOfSIMDType(structHnd, &sizeBytes);
+ if (simdBaseType != TYP_UNKNOWN)
{
- *pSimdBaseType = simdBaseType;
- }
+ assert(sizeBytes == originalSize);
+ structType = getSIMDTypeForSize(sizeBytes);
+ if (pSimdBaseType != nullptr)
+ {
+ *pSimdBaseType = simdBaseType;
+ }
#ifdef _TARGET_AMD64_
- // Amd64: also indicate that we use floating point registers
- compFloatingPointUsed = true;
+ // Amd64: also indicate that we use floating point registers
+ compFloatingPointUsed = true;
#endif
+ }
}
}
#endif // FEATURE_SIMD
- if (pNumGCVars != nullptr)
+
+ // Fetch GC layout info if requested
+ if (gcLayout != nullptr)
+ {
+ unsigned numGCVars = info.compCompHnd->getClassGClayout(structHnd, gcLayout);
+
+ // Verify that the quick test up above via the class attributes gave a
+ // safe view of the type's GCness.
+ //
+ // Note there are cases where hasGCPtrs is true but getClassGClayout
+ // does not report any gc fields.
+ assert(hasGCPtrs || (numGCVars == 0));
+
+ if (pNumGCVars != nullptr)
+ {
+ *pNumGCVars = numGCVars;
+ }
+ }
+ else
{
- *pNumGCVars = numGCVars;
+ // Can't safely ask for number of GC pointers without also
+ // asking for layout.
+ assert(pNumGCVars == nullptr);
}
+
return structType;
}
@@ -1777,15 +1798,19 @@ GenTreePtr Compiler::impReadyToRunLookupToTree(CORINFO_CONST_LOOKUP* pLookup,
unsigned handleFlags,
void* compileTimeHandle)
{
- CORINFO_GENERIC_HANDLE handle = 0;
- void* pIndirection = 0;
+ CORINFO_GENERIC_HANDLE handle = nullptr;
+ void* pIndirection = nullptr;
assert(pLookup->accessType != IAT_PPVALUE);
if (pLookup->accessType == IAT_VALUE)
+ {
handle = pLookup->handle;
+ }
else if (pLookup->accessType == IAT_PVALUE)
+ {
pIndirection = pLookup->addr;
- return gtNewIconEmbHndNode(handle, pIndirection, handleFlags, 0, 0, compileTimeHandle);
+ }
+ return gtNewIconEmbHndNode(handle, pIndirection, handleFlags, 0, nullptr, compileTimeHandle);
}
GenTreePtr Compiler::impReadyToRunHelperToTree(
@@ -1798,7 +1823,9 @@ GenTreePtr Compiler::impReadyToRunHelperToTree(
CORINFO_CONST_LOOKUP lookup;
#if COR_JIT_EE_VERSION > 460
if (!info.compCompHnd->getReadyToRunHelper(pResolvedToken, pGenericLookupKind, helper, &lookup))
- return NULL;
+ {
+ return nullptr;
+ }
#else
info.compCompHnd->getReadyToRunHelper(pResolvedToken, helper, &lookup);
#endif
@@ -1828,7 +1855,9 @@ GenTreePtr Compiler::impMethodPointer(CORINFO_RESOLVED_TOKEN* pResolvedToken, CO
*op1->gtFptrVal.gtLdftnResolvedToken = *pResolvedToken;
}
else
+ {
op1->gtFptrVal.gtEntryPoint.addr = nullptr;
+ }
#endif
break;
@@ -1852,6 +1881,46 @@ GenTreePtr Compiler::impMethodPointer(CORINFO_RESOLVED_TOKEN* pResolvedToken, CO
return op1;
}
+//------------------------------------------------------------------------
+// getRuntimeContextTree: find pointer to context for runtime lookup.
+//
+// Arguments:
+// kind - lookup kind.
+//
+// Return Value:
+// Return GenTree pointer to generic shared context.
+//
+// Notes:
+// Reports about generic context using.
+
+GenTreePtr Compiler::getRuntimeContextTree(CORINFO_RUNTIME_LOOKUP_KIND kind)
+{
+ GenTreePtr ctxTree = nullptr;
+
+ // 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;
+
+ if (kind == CORINFO_LOOKUP_THISOBJ)
+ {
+ // this Object
+ ctxTree = gtNewLclvNode(info.compThisArg, TYP_REF);
+
+ // Vtable pointer of this object
+ ctxTree = gtNewOperNode(GT_IND, TYP_I_IMPL, ctxTree);
+ ctxTree->gtFlags |= GTF_EXCEPT; // Null-pointer exception
+ ctxTree->gtFlags |= GTF_IND_INVARIANT;
+ }
+ else
+ {
+ assert(kind == CORINFO_LOOKUP_METHODPARAM || kind == CORINFO_LOOKUP_CLASSPARAM);
+
+ ctxTree = gtNewLclvNode(info.compTypeCtxtArg, TYP_I_IMPL); // Exact method descriptor as passed in as last arg
+ }
+ return ctxTree;
+}
+
/*****************************************************************************/
/* Import a dictionary lookup to access a handle in code shared between
generic instantiations.
@@ -1874,36 +1943,12 @@ GenTreePtr Compiler::impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedTok
CORINFO_LOOKUP* pLookup,
void* compileTimeHandle)
{
- CORINFO_RUNTIME_LOOKUP_KIND kind = pLookup->lookupKind.runtimeLookupKind;
- CORINFO_RUNTIME_LOOKUP* pRuntimeLookup = &pLookup->runtimeLookup;
// This method can only be called from the importer instance of the Compiler.
// In other word, it cannot be called by the instance of the Compiler for the inlinee.
assert(!compIsForInlining());
- GenTreePtr ctxTree;
-
- // 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;
-
- if (kind == CORINFO_LOOKUP_THISOBJ)
- {
- // this Object
- ctxTree = gtNewLclvNode(info.compThisArg, TYP_REF);
-
- // Vtable pointer of this object
- ctxTree = gtNewOperNode(GT_IND, TYP_I_IMPL, ctxTree);
- ctxTree->gtFlags |= GTF_EXCEPT; // Null-pointer exception
- ctxTree->gtFlags |= GTF_IND_INVARIANT;
- }
- else
- {
- assert(kind == CORINFO_LOOKUP_METHODPARAM || kind == CORINFO_LOOKUP_CLASSPARAM);
-
- ctxTree = gtNewLclvNode(info.compTypeCtxtArg, TYP_I_IMPL); // Exact method descriptor as passed in as last arg
- }
+ GenTreePtr ctxTree = getRuntimeContextTree(pLookup->lookupKind.runtimeLookupKind);
#ifdef FEATURE_READYTORUN_COMPILER
if (opts.IsReadyToRun())
@@ -1913,6 +1958,7 @@ GenTreePtr Compiler::impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedTok
}
#endif
+ CORINFO_RUNTIME_LOOKUP* pRuntimeLookup = &pLookup->runtimeLookup;
// It's available only via the run-time helper function
if (pRuntimeLookup->indirections == CORINFO_USEHELPER)
{
@@ -2083,8 +2129,6 @@ bool Compiler::impSpillStackEntry(unsigned level,
guard.Init(&impNestedStackSpill, bAssertOnRecursion);
#endif
- assert(!fgGlobalMorph); // use impInlineSpillStackEntry() during inlining
-
GenTreePtr tree = verCurrentState.esStack[level].val;
/* Allocate a temp if we haven't been asked to use a particular one */
@@ -2179,8 +2223,6 @@ void Compiler::impSpillStackEnsure(bool spillLeaves)
void Compiler::impSpillEvalStack()
{
- assert(!fgGlobalMorph); // use impInlineSpillEvalStack() during inlining
-
for (unsigned level = 0; level < verCurrentState.esStackDepth; level++)
{
impSpillStackEntry(level, BAD_VAR_NUM DEBUGARG(false) DEBUGARG("impSpillEvalStack"));
@@ -2318,8 +2360,6 @@ Compiler::fgWalkResult Compiler::impFindValueClasses(GenTreePtr* pTree, fgWalkDa
void Compiler::impSpillLclRefs(ssize_t lclNum)
{
- assert(!fgGlobalMorph); // use impInlineSpillLclRefs() during inlining
-
/* Before we make any appends to the tree list we must spill the
* "special" side effects (GTF_ORDER_SIDEEFF) - GT_CATCH_ARG */
@@ -2676,7 +2716,6 @@ static inline bool impOpcodeIsCallOpcode(OPCODE opcode)
}
/*****************************************************************************/
-#ifdef DEBUGGING_SUPPORT
static inline bool impOpcodeIsCallSiteBoundary(OPCODE opcode)
{
@@ -2695,8 +2734,6 @@ static inline bool impOpcodeIsCallSiteBoundary(OPCODE opcode)
}
}
-#endif // DEBUGGING_SUPPORT
-
/*****************************************************************************/
// One might think it is worth caching these values, but results indicate
@@ -2816,27 +2853,6 @@ GenTreePtr Compiler::impImplicitR4orR8Cast(GenTreePtr tree, var_types dstTyp)
return tree;
}
-/*****************************************************************************/
-BOOL Compiler::impLocAllocOnStack()
-{
- if (!compLocallocUsed)
- {
- return (FALSE);
- }
-
- // Returns true if a GT_LCLHEAP node is encountered in any of the trees
- // that have been pushed on the importer evaluatuion stack.
- //
- for (unsigned i = 0; i < verCurrentState.esStackDepth; i++)
- {
- if (fgWalkTreePre(&verCurrentState.esStack[i].val, Compiler::fgChkLocAllocCB) == WALK_ABORT)
- {
- return (TRUE);
- }
- }
- return (FALSE);
-}
-
//------------------------------------------------------------------------
// impInitializeArrayIntrinsic: Attempts to replace a call to InitializeArray
// with a GT_COPYBLK node.
@@ -3236,7 +3252,7 @@ GenTreePtr Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd,
#if COR_JIT_EE_VERSION > 460
CorInfoIntrinsics intrinsicID = info.compCompHnd->getIntrinsicID(method, &mustExpand);
#else
- CorInfoIntrinsics intrinsicID = info.compCompHnd->getIntrinsicID(method);
+ CorInfoIntrinsics intrinsicID = info.compCompHnd->getIntrinsicID(method);
#endif
*pIntrinsicID = intrinsicID;
@@ -3307,9 +3323,9 @@ GenTreePtr Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd,
op1 = nullptr;
-#ifdef LEGACY_BACKEND
+#if defined(LEGACY_BACKEND)
if (IsTargetIntrinsic(intrinsicID))
-#else
+#elif !defined(_TARGET_X86_)
// Intrinsics that are not implemented directly by target instructions will
// be re-materialized as users calls in rationalizer. For prefixed tail calls,
// don't do this optimization, because
@@ -3317,6 +3333,11 @@ GenTreePtr Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd,
// b) It will be non-trivial task or too late to re-materialize a surviving
// tail prefixed GT_INTRINSIC as tail call in rationalizer.
if (!IsIntrinsicImplementedByUserCall(intrinsicID) || !tailCall)
+#else
+ // On x86 RyuJIT, importing intrinsics that are implemented as user calls can cause incorrect calculation
+ // of the depth of the stack if these intrinsics are used as arguments to another call. This causes bad
+ // code generation for certain EH constructs.
+ if (!IsIntrinsicImplementedByUserCall(intrinsicID))
#endif
{
switch (sig->numArgs)
@@ -3534,7 +3555,7 @@ GenTreePtr Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd,
// Get native TypeHandle argument to old helper
op1 = op1->gtCall.gtCallArgs;
- assert(op1->IsList());
+ assert(op1->OperIsList());
assert(op1->gtOp.gtOp2 == nullptr);
op1 = op1->gtOp.gtOp1;
retNode = op1;
@@ -3886,7 +3907,7 @@ void Compiler::verHandleVerificationFailure(BasicBlock* block DEBUGARG(bool logM
#endif // DEBUG
// Add the non verifiable flag to the compiler
- if ((opts.eeFlags & CORJIT_FLG_IMPORT_ONLY) != 0)
+ if (opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IMPORT_ONLY))
{
tiIsVerifiableCode = FALSE;
}
@@ -4913,14 +4934,26 @@ GenTreePtr Compiler::impImportLdvirtftn(GenTreePtr thisPtr,
}
#ifdef FEATURE_READYTORUN_COMPILER
- if (opts.IsReadyToRun() && !pCallInfo->exactContextNeedsRuntimeLookup)
+ if (opts.IsReadyToRun())
{
- GenTreeCall* call = gtNewHelperCallNode(CORINFO_HELP_READYTORUN_VIRTUAL_FUNC_PTR, TYP_I_IMPL, GTF_EXCEPT,
- gtNewArgList(thisPtr));
+ if (!pCallInfo->exactContextNeedsRuntimeLookup)
+ {
+ GenTreeCall* call = gtNewHelperCallNode(CORINFO_HELP_READYTORUN_VIRTUAL_FUNC_PTR, TYP_I_IMPL, GTF_EXCEPT,
+ gtNewArgList(thisPtr));
- call->setEntryPoint(pCallInfo->codePointerLookup.constLookup);
+ call->setEntryPoint(pCallInfo->codePointerLookup.constLookup);
- return call;
+ return call;
+ }
+
+ // We need a runtime lookup. CoreRT has a ReadyToRun helper for that too.
+ if (IsTargetAbi(CORINFO_CORERT_ABI))
+ {
+ GenTreePtr ctxTree = getRuntimeContextTree(pCallInfo->codePointerLookup.lookupKind.runtimeLookupKind);
+
+ return impReadyToRunHelperToTree(pResolvedToken, CORINFO_HELP_READYTORUN_GENERIC_HANDLE, TYP_I_IMPL,
+ gtNewArgList(ctxTree), &pCallInfo->codePointerLookup.lookupKind);
+ }
}
#endif
@@ -5001,7 +5034,7 @@ void Compiler::impImportAndPushBox(CORINFO_RESOLVED_TOKEN* pResolvedToken)
if (opts.IsReadyToRun())
{
op1 = impReadyToRunHelperToTree(pResolvedToken, CORINFO_HELP_READYTORUN_NEW, TYP_REF);
- usingReadyToRunHelper = (op1 != NULL);
+ usingReadyToRunHelper = (op1 != nullptr);
}
if (!usingReadyToRunHelper)
@@ -5150,7 +5183,7 @@ void Compiler::impImportNewObjArray(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORI
CLANG_FORMAT_COMMENT_ANCHOR;
#if COR_JIT_EE_VERSION > 460
- if (!opts.IsReadyToRun() || (eeGetEEInfo()->targetAbi == CORINFO_CORERT_ABI))
+ if (!opts.IsReadyToRun() || IsTargetAbi(CORINFO_CORERT_ABI))
{
LclVarDsc* newObjArrayArgsVar;
@@ -5325,61 +5358,110 @@ GenTreePtr Compiler::impTransformThis(GenTreePtr thisPtr,
}
}
-bool Compiler::impCanPInvokeInline(var_types callRetTyp)
+//------------------------------------------------------------------------
+// impCanPInvokeInline: examine information from a call to see if the call
+// qualifies as an inline pinvoke.
+//
+// Arguments:
+// block - block contaning the call, or for inlinees, block
+// containing the call being inlined
+//
+// Return Value:
+// true if this call qualifies as an inline pinvoke, false otherwise
+//
+// Notes:
+// Checks basic legality and then a number of ambient conditions
+// where we could pinvoke but choose not to
+
+bool Compiler::impCanPInvokeInline(BasicBlock* block)
{
- return impCanPInvokeInlineCallSite(callRetTyp) && getInlinePInvokeEnabled() && (!opts.compDbgCode) &&
+ return impCanPInvokeInlineCallSite(block) && getInlinePInvokeEnabled() && (!opts.compDbgCode) &&
(compCodeOpt() != SMALL_CODE) && (!opts.compNoPInvokeInlineCB) // profiler is preventing inline pinvoke
;
}
-// Returns false only if the callsite really cannot be inlined. Ignores global variables
-// like debugger, profiler etc.
-bool Compiler::impCanPInvokeInlineCallSite(var_types callRetTyp)
+//------------------------------------------------------------------------
+// impCanPInvokeInlineSallSite: basic legality checks using information
+// from a call to see if the call qualifies as an inline pinvoke.
+//
+// Arguments:
+// block - block contaning the call, or for inlinees, block
+// containing the call being inlined
+//
+// Return Value:
+// true if this call can legally qualify as an inline pinvoke, false otherwise
+//
+// Notes:
+// For runtimes that support exception handling interop there are
+// restrictions on using inline pinvoke in handler regions.
+//
+// * We have to disable pinvoke inlining inside of filters because
+// in case the main execution (i.e. in the try block) is inside
+// unmanaged code, we cannot reuse the inlined stub (we still need
+// the original state until we are in the catch handler)
+//
+// * We disable pinvoke inlining inside handlers since the GSCookie
+// is in the inlined Frame (see
+// CORINFO_EE_INFO::InlinedCallFrameInfo::offsetOfGSCookie), but
+// this would not protect framelets/return-address of handlers.
+//
+// These restrictions are currently also in place for CoreCLR but
+// can be relaxed when coreclr/#8459 is addressed.
+
+bool Compiler::impCanPInvokeInlineCallSite(BasicBlock* block)
{
- return
- // We have to disable pinvoke inlining inside of filters
- // because in case the main execution (i.e. in the try block) is inside
- // unmanaged code, we cannot reuse the inlined stub (we still need the
- // original state until we are in the catch handler)
- (!bbInFilterILRange(compCurBB)) &&
- // We disable pinvoke inlining inside handlers since the GSCookie is
- // in the inlined Frame (see CORINFO_EE_INFO::InlinedCallFrameInfo::offsetOfGSCookie),
- // but this would not protect framelets/return-address of handlers.
- !compCurBB->hasHndIndex() &&
#ifdef _TARGET_AMD64_
- // Turns out JIT64 doesn't perform PInvoke inlining inside try regions, here's an excerpt of
- // the comment from JIT64 explaining why:
- //
- //// [VSWhidbey: 611015] - because the jitted code links in the Frame (instead
- //// of the stub) we rely on the Frame not being 'active' until inside the
- //// stub. This normally happens by the stub setting the return address
- //// pointer in the Frame object inside the stub. On a normal return, the
- //// return address pointer is zeroed out so the Frame can be safely re-used,
- //// but if an exception occurs, nobody zeros out the return address pointer.
- //// Thus if we re-used the Frame object, it would go 'active' as soon as we
- //// link it into the Frame chain.
- ////
- //// Technically we only need to disable PInvoke inlining if we're in a
- //// handler or if we're
- //// in a try body with a catch or filter/except where other non-handler code
- //// in this method might run and try to re-use the dirty Frame object.
- //
- // Now, because of this, the VM actually assumes that in 64 bit we never PInvoke
- // inline calls on any EH construct, you can verify that on VM\ExceptionHandling.cpp:203
- // The method responsible for resuming execution is UpdateObjectRefInResumeContextCallback
- // you can see how it aligns with JIT64 policy of not inlining PInvoke calls almost right
- // at the beginning of the body of the method.
- !compCurBB->hasTryIndex() &&
-#endif
- (!impLocAllocOnStack()) && (callRetTyp != TYP_STRUCT);
+ // On x64, we disable pinvoke inlining inside of try regions.
+ // Here is the comment from JIT64 explaining why:
+ //
+ // [VSWhidbey: 611015] - because the jitted code links in the
+ // Frame (instead of the stub) we rely on the Frame not being
+ // 'active' until inside the stub. This normally happens by the
+ // stub setting the return address pointer in the Frame object
+ // inside the stub. On a normal return, the return address
+ // pointer is zeroed out so the Frame can be safely re-used, but
+ // if an exception occurs, nobody zeros out the return address
+ // pointer. Thus if we re-used the Frame object, it would go
+ // 'active' as soon as we link it into the Frame chain.
+ //
+ // Technically we only need to disable PInvoke inlining if we're
+ // in a handler or if we're in a try body with a catch or
+ // filter/except where other non-handler code in this method
+ // might run and try to re-use the dirty Frame object.
+ //
+ // A desktop test case where this seems to matter is
+ // jit\jit64\ebvts\mcpp\sources2\ijw\__clrcall\vector_ctor_dtor.02\deldtor_clr.exe
+ const bool inX64Try = block->hasTryIndex();
+#else
+ const bool inX64Try = false;
+#endif // _TARGET_AMD64_
+
+ return !inX64Try && !block->hasHndIndex();
}
-void Compiler::impCheckForPInvokeCall(GenTreePtr call,
- CORINFO_METHOD_HANDLE methHnd,
- CORINFO_SIG_INFO* sig,
- unsigned mflags)
+//------------------------------------------------------------------------
+// impCheckForPInvokeCall examine call to see if it is a pinvoke and if so
+// if it can be expressed as an inline pinvoke.
+//
+// Arguments:
+// call - tree for the call
+// methHnd - handle for the method being called (may be null)
+// sig - signature of the method being called
+// mflags - method flags for the method being called
+// block - block contaning the call, or for inlinees, block
+// containing the call being inlined
+//
+// Notes:
+// Sets GTF_CALL_M_PINVOKE on the call for pinvokes.
+//
+// Also sets GTF_CALL_UNMANAGED on call for inline pinvokes if the
+// call passes a combination of legality and profitabilty checks.
+//
+// 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)
{
- var_types callRetTyp = JITtype2varType(sig->retType);
CorInfoUnmanagedCallConv unmanagedCallConv;
// If VM flagged it as Pinvoke, flag the call node accordingly
@@ -5422,15 +5504,12 @@ void Compiler::impCheckForPInvokeCall(GenTreePtr call,
if (opts.compMustInlinePInvokeCalli && methHnd == nullptr)
{
-#ifdef _TARGET_X86_
- // CALLI in IL stubs must be inlined
- assert(impCanPInvokeInlineCallSite(callRetTyp));
- assert(!info.compCompHnd->pInvokeMarshalingRequired(methHnd, sig));
-#endif // _TARGET_X86_
+ // Always inline pinvoke.
}
else
{
- if (!impCanPInvokeInline(callRetTyp))
+ // Check legality and profitability.
+ if (!impCanPInvokeInline(block))
{
return;
}
@@ -5439,6 +5518,14 @@ void Compiler::impCheckForPInvokeCall(GenTreePtr call,
{
return;
}
+
+ // Size-speed tradeoff: don't use inline pinvoke at rarely
+ // executed call sites. The non-inline version is more
+ // compact.
+ if (block->isRunRarely())
+ {
+ return;
+ }
}
JITLOG((LL_INFO1000000, "\nInline a CALLI PINVOKE call from method %s", info.compFullName));
@@ -5446,8 +5533,6 @@ void Compiler::impCheckForPInvokeCall(GenTreePtr call,
call->gtFlags |= GTF_CALL_UNMANAGED;
info.compCallUnmanaged++;
- assert(!compIsForInlining());
-
// AMD64 convention is same for native and managed
if (unmanagedCallConv == CORINFO_UNMANAGED_CALLCONV_C)
{
@@ -5736,6 +5821,7 @@ GenTreePtr Compiler::impImportStaticFieldAccess(CORINFO_RESOLVED_TOKEN* pResolve
break;
case CORINFO_FIELD_STATIC_SHARED_STATIC_HELPER:
+ {
#ifdef FEATURE_READYTORUN_COMPILER
if (opts.IsReadyToRun())
{
@@ -5762,8 +5848,39 @@ GenTreePtr Compiler::impImportStaticFieldAccess(CORINFO_RESOLVED_TOKEN* pResolve
new (this, GT_CNS_INT) GenTreeIntCon(TYP_INT, pFieldInfo->offset, fs));
}
break;
+ }
+#if COR_JIT_EE_VERSION > 460
+ case CORINFO_FIELD_STATIC_READYTORUN_HELPER:
+ {
+#ifdef FEATURE_READYTORUN_COMPILER
+ noway_assert(opts.IsReadyToRun());
+ CORINFO_LOOKUP_KIND kind = info.compCompHnd->getLocationOfThisType(info.compMethodHnd);
+ assert(kind.needsRuntimeLookup);
+
+ GenTreePtr ctxTree = getRuntimeContextTree(kind.runtimeLookupKind);
+ GenTreeArgList* args = gtNewArgList(ctxTree);
+
+ unsigned callFlags = 0;
+
+ if (info.compCompHnd->getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_BEFOREFIELDINIT)
+ {
+ callFlags |= GTF_CALL_HOISTABLE;
+ }
+ var_types type = TYP_BYREF;
+ op1 = gtNewHelperCallNode(CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE, type, callFlags, args);
+ op1->gtCall.setEntryPoint(pFieldInfo->fieldLookup);
+ FieldSeqNode* fs = GetFieldSeqStore()->CreateSingleton(pResolvedToken->hField);
+ op1 = gtNewOperNode(GT_ADD, type, op1,
+ new (this, GT_CNS_INT) GenTreeIntCon(TYP_I_IMPL, pFieldInfo->offset, fs));
+#else
+ unreached();
+#endif // FEATURE_READYTORUN_COMPILER
+ }
+ break;
+#endif // COR_JIT_EE_VERSION > 460
default:
+ {
if (!(access & CORINFO_ACCESS_ADDRESS))
{
// In future, it may be better to just create the right tree here instead of folding it later.
@@ -5820,6 +5937,7 @@ GenTreePtr Compiler::impImportStaticFieldAccess(CORINFO_RESOLVED_TOKEN* pResolve
}
}
break;
+ }
}
if (pFieldInfo->fieldFlags & CORINFO_FLG_FIELD_STATIC_IN_HEAP)
@@ -6071,7 +6189,7 @@ bool Compiler::impIsTailCallILPattern(bool tailPrefixed,
((nextOpcode == CEE_NOP) || ((nextOpcode == CEE_POP) && (++cntPop == 1)))); // Next opcode = nop or exactly
// one pop seen so far.
#else
- nextOpcode = (OPCODE)getU1LittleEndian(codeAddrOfNextOpcode);
+ nextOpcode = (OPCODE)getU1LittleEndian(codeAddrOfNextOpcode);
#endif
if (isCallPopAndRet)
@@ -6845,9 +6963,15 @@ var_types Compiler::impImportCall(OPCODE opcode,
//--------------------------- Inline NDirect ------------------------------
- if (!compIsForInlining())
+ // For inline cases we technically should look at both the current
+ // block and the call site block (or just the latter if we've
+ // fused the EH trees). However the block-related checks pertain to
+ // EH and we currently won't inline a method with EH. So for
+ // inlinees, just checking the call site block is sufficient.
{
- impCheckForPInvokeCall(call, methHnd, sig, mflags);
+ // New lexical block here to avoid compilation errors because of GOTOs.
+ BasicBlock* block = compIsForInlining() ? impInlineInfo->iciBlock : compCurBB;
+ impCheckForPInvokeCall(call, methHnd, sig, mflags, block);
}
if (call->gtFlags & GTF_CALL_UNMANAGED)
@@ -7035,7 +7159,7 @@ var_types Compiler::impImportCall(OPCODE opcode,
{
instParam =
impReadyToRunLookupToTree(&callInfo->instParamLookup, GTF_ICON_CLASS_HDL, exactClassHandle);
- if (instParam == NULL)
+ if (instParam == nullptr)
{
return callRetTyp;
}
@@ -7452,10 +7576,6 @@ DONE_CALL:
{
call = impFixupCallStructReturn(call, sig->retTypeClass);
}
- else if (varTypeIsLong(callRetTyp))
- {
- call = impInitCallLongReturn(call);
- }
if ((call->gtFlags & GTF_CALL_INLINE_CANDIDATE) != 0)
{
@@ -7467,6 +7587,13 @@ DONE_CALL:
// TODO: Still using the widened type.
call = gtNewInlineCandidateReturnExpr(call, genActualType(callRetTyp));
}
+ else
+ {
+ // 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"));
+ }
}
if (!bIntrinsicImported)
@@ -7738,42 +7865,6 @@ GenTreePtr Compiler::impFixupCallStructReturn(GenTreePtr call, CORINFO_CLASS_HAN
return call;
}
-//-------------------------------------------------------------------------------------
-// impInitCallLongReturn:
-// Initialize the ReturnTypDesc for a call that returns a TYP_LONG
-//
-// Arguments:
-// call - GT_CALL GenTree node
-//
-// Return Value:
-// Returns new GenTree node after initializing the ReturnTypeDesc of call node
-//
-GenTreePtr Compiler::impInitCallLongReturn(GenTreePtr call)
-{
- assert(call->gtOper == GT_CALL);
-
-#if defined(_TARGET_X86_) && !defined(LEGACY_BACKEND)
- // LEGACY_BACKEND does not use multi reg returns for calls with long return types
-
- if (varTypeIsLong(call))
- {
- GenTreeCall* callNode = call->AsCall();
-
- // The return type will remain as the incoming long type
- callNode->gtReturnType = call->gtType;
-
- // Initialize Return type descriptor of call node
- ReturnTypeDesc* retTypeDesc = callNode->GetReturnTypeDesc();
- retTypeDesc->InitializeLongReturnType(this);
-
- // must be a long returned in two registers
- assert(retTypeDesc->GetReturnRegCount() == 2);
- }
-#endif // _TARGET_X86_ && !LEGACY_BACKEND
-
- return call;
-}
-
/*****************************************************************************
For struct return values, re-type the operand in the case where the ABI
does not use a struct return buffer
@@ -7804,6 +7895,9 @@ GenTreePtr Compiler::impFixupStructReturnType(GenTreePtr op, CORINFO_CLASS_HANDL
unsigned lclNum = op->gtLclVarCommon.gtLclNum;
lvaTable[lclNum].lvIsMultiRegRet = true;
+ // TODO-1stClassStructs: Handle constant propagation and CSE-ing of multireg returns.
+ op->gtFlags |= GTF_DONT_CSE;
+
return op;
}
@@ -7828,6 +7922,10 @@ GenTreePtr Compiler::impFixupStructReturnType(GenTreePtr op, CORINFO_CLASS_HANDL
unsigned lclNum = op->gtLclVarCommon.gtLclNum;
// Make sure this struct type stays as struct so that we can return it as an HFA
lvaTable[lclNum].lvIsMultiRegRet = true;
+
+ // TODO-1stClassStructs: Handle constant propagation and CSE-ing of multireg returns.
+ op->gtFlags |= GTF_DONT_CSE;
+
return op;
}
@@ -7860,6 +7958,10 @@ GenTreePtr Compiler::impFixupStructReturnType(GenTreePtr op, CORINFO_CLASS_HANDL
// Make sure this struct type is not struct promoted
lvaTable[lclNum].lvIsMultiRegRet = true;
+
+ // TODO-1stClassStructs: Handle constant propagation and CSE-ing of multireg returns.
+ op->gtFlags |= GTF_DONT_CSE;
+
return op;
}
@@ -9311,8 +9413,6 @@ void Compiler::impImportBlockCode(BasicBlock* block)
opcodeOffs = (IL_OFFSET)(codeAddr - info.compCode);
-#if defined(DEBUGGING_SUPPORT) || defined(DEBUG)
-
#ifndef DEBUG
if (opts.compDbgInfo)
#endif
@@ -9424,8 +9524,6 @@ void Compiler::impImportBlockCode(BasicBlock* block)
}
}
-#endif // defined(DEBUGGING_SUPPORT) || defined(DEBUG)
-
CORINFO_CLASS_HANDLE clsHnd = DUMMY_INIT(NULL);
CORINFO_CLASS_HANDLE ldelemClsHnd = DUMMY_INIT(NULL);
CORINFO_CLASS_HANDLE stelemClsHnd = DUMMY_INIT(NULL);
@@ -9515,6 +9613,14 @@ void Compiler::impImportBlockCode(BasicBlock* block)
SPILL_APPEND:
+ // We need to call impSpillLclRefs() for a struct type lclVar.
+ // This is done for non-block assignments in the handling of stloc.
+ if ((op1->OperGet() == GT_ASG) && varTypeIsStruct(op1->gtOp.gtOp1) &&
+ (op1->gtOp.gtOp1->gtOper == GT_LCL_VAR))
+ {
+ impSpillLclRefs(op1->gtOp.gtOp1->AsLclVarCommon()->gtLclNum);
+ }
+
/* Append 'op1' to the list of statements */
impAppendTree(op1, (unsigned)CHECK_SPILL_ALL, impCurStmtOffs);
goto DONE_APPEND;
@@ -11087,8 +11193,6 @@ void Compiler::impImportBlockCode(BasicBlock* block)
COND_JUMP:
- seenConditionalJump = true;
-
/* Fold comparison if we can */
op1 = gtFoldExpr(op1);
@@ -12328,14 +12432,12 @@ void Compiler::impImportBlockCode(BasicBlock* block)
// At present this can only be String
else if (clsFlags & CORINFO_FLG_VAROBJSIZE)
{
-#if COR_JIT_EE_VERSION > 460
- if (eeGetEEInfo()->targetAbi == CORINFO_CORERT_ABI)
+ if (IsTargetAbi(CORINFO_CORERT_ABI))
{
// The dummy argument does not exist in CoreRT
newObjThisPtr = nullptr;
}
else
-#endif
{
// This is the case for variable-sized objects that are not
// arrays. In this case, call the constructor with a null 'this'
@@ -12368,6 +12470,33 @@ void Compiler::impImportBlockCode(BasicBlock* block)
// The lookup of the code pointer will be handled by CALL in this case
if (clsFlags & CORINFO_FLG_VALUECLASS)
{
+ if (compIsForInlining())
+ {
+ // If value class has GC fields, inform the inliner. It may choose to
+ // bail out on the inline.
+ DWORD typeFlags = info.compCompHnd->getClassAttribs(resolvedToken.hClass);
+ if ((typeFlags & CORINFO_FLG_CONTAINS_GC_PTR) != 0)
+ {
+ compInlineResult->Note(InlineObservation::CALLEE_HAS_GC_STRUCT);
+ if (compInlineResult->IsFailure())
+ {
+ return;
+ }
+
+ // Do further notification in the case where the call site is rare;
+ // some policies do not track the relative hotness of call sites for
+ // "always" inline cases.
+ if (impInlineInfo->iciBlock->isRunRarely())
+ {
+ compInlineResult->Note(InlineObservation::CALLSITE_RARE_GC_STRUCT);
+ if (compInlineResult->IsFailure())
+ {
+ return;
+ }
+ }
+ }
+ }
+
CorInfoType jitTyp = info.compCompHnd->asCorInfoType(resolvedToken.hClass);
unsigned size = info.compCompHnd->getClassSize(resolvedToken.hClass);
@@ -12403,7 +12532,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
if (opts.IsReadyToRun())
{
op1 = impReadyToRunHelperToTree(&resolvedToken, CORINFO_HELP_READYTORUN_NEW, TYP_REF);
- usingReadyToRunHelper = (op1 != NULL);
+ usingReadyToRunHelper = (op1 != nullptr);
}
if (!usingReadyToRunHelper)
@@ -12503,6 +12632,10 @@ void Compiler::impImportBlockCode(BasicBlock* block)
if (compIsForInlining())
{
+ if (compDonotInline())
+ {
+ return;
+ }
// We rule out inlinees with explicit tail calls in fgMakeBasicBlocks.
assert((prefixFlags & PREFIX_TAILCALL_EXPLICIT) == 0);
}
@@ -12696,7 +12829,9 @@ 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);
@@ -12828,7 +12963,9 @@ void Compiler::impImportBlockCode(BasicBlock* block)
#ifdef FEATURE_READYTORUN_COMPILER
if (fieldInfo.fieldAccessor == CORINFO_FIELD_INSTANCE_WITH_BASE)
+ {
op1->gtField.gtFieldLookup = fieldInfo.fieldLookup;
+ }
#endif
op1->gtFlags |= (obj->gtFlags & GTF_GLOB_EFFECT);
@@ -12925,6 +13062,9 @@ 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;
@@ -13068,6 +13208,9 @@ 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 */
@@ -13134,7 +13277,9 @@ void Compiler::impImportBlockCode(BasicBlock* block)
#ifdef FEATURE_READYTORUN_COMPILER
if (fieldInfo.fieldAccessor == CORINFO_FIELD_INSTANCE_WITH_BASE)
+ {
op1->gtField.gtFieldLookup = fieldInfo.fieldLookup;
+ }
#endif
op1->gtFlags |= (obj->gtFlags & GTF_GLOB_EFFECT);
@@ -13185,6 +13330,9 @@ 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;
@@ -13376,7 +13524,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
{
op1 = impReadyToRunHelperToTree(&resolvedToken, CORINFO_HELP_READYTORUN_NEWARR_1, TYP_REF,
gtNewArgList(op2));
- usingReadyToRunHelper = (op1 != NULL);
+ usingReadyToRunHelper = (op1 != nullptr);
if (!usingReadyToRunHelper)
{
@@ -13388,9 +13536,11 @@ void Compiler::impImportBlockCode(BasicBlock* block)
// Reason: performance (today, we'll always use the slow helper for the R2R generics case)
// Need to restore array classes before creating array objects on the heap
- op1 = impTokenToHandle(&resolvedToken, NULL, TRUE /*mustRestoreHandle*/);
- if (op1 == NULL) // compDonotInline()
+ op1 = impTokenToHandle(&resolvedToken, nullptr, TRUE /*mustRestoreHandle*/);
+ if (op1 == nullptr)
+ { // compDonotInline()
return;
+ }
}
}
@@ -13498,7 +13648,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
GenTreePtr opLookup =
impReadyToRunHelperToTree(&resolvedToken, CORINFO_HELP_READYTORUN_ISINSTANCEOF, TYP_REF,
gtNewArgList(op1));
- usingReadyToRunHelper = (opLookup != NULL);
+ usingReadyToRunHelper = (opLookup != nullptr);
op1 = (usingReadyToRunHelper ? opLookup : op1);
if (!usingReadyToRunHelper)
@@ -13510,9 +13660,11 @@ void Compiler::impImportBlockCode(BasicBlock* block)
// 3) Perform the 'is instance' check on the input object
// Reason: performance (today, we'll always use the slow helper for the R2R generics case)
- op2 = impTokenToHandle(&resolvedToken, NULL, FALSE);
- if (op2 == NULL) // compDonotInline()
+ op2 = impTokenToHandle(&resolvedToken, nullptr, FALSE);
+ if (op2 == nullptr)
+ { // compDonotInline()
return;
+ }
}
}
@@ -14026,7 +14178,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
{
GenTreePtr opLookup = impReadyToRunHelperToTree(&resolvedToken, CORINFO_HELP_READYTORUN_CHKCAST,
TYP_REF, gtNewArgList(op1));
- usingReadyToRunHelper = (opLookup != NULL);
+ usingReadyToRunHelper = (opLookup != nullptr);
op1 = (usingReadyToRunHelper ? opLookup : op1);
if (!usingReadyToRunHelper)
@@ -14038,9 +14190,11 @@ void Compiler::impImportBlockCode(BasicBlock* block)
// 3) Check the object on the stack for the type-cast
// Reason: performance (today, we'll always use the slow helper for the R2R generics case)
- op2 = impTokenToHandle(&resolvedToken, NULL, FALSE);
- if (op2 == NULL) // compDonotInline()
+ op2 = impTokenToHandle(&resolvedToken, nullptr, FALSE);
+ if (op2 == nullptr)
+ { // compDonotInline()
return;
+ }
}
}
@@ -14075,20 +14229,6 @@ void Compiler::impImportBlockCode(BasicBlock* block)
compInlineResult->NoteFatal(InlineObservation::CALLEE_THROW_WITH_INVALID_STACK);
return;
}
-
- /* Don't inline non-void conditionals that have a throw in one of the branches */
-
- /* NOTE: If we do allow this, note that we can't simply do a
- checkLiveness() to match the liveness at the end of the "then"
- and "else" branches of the GT_COLON. The branch with the throw
- will keep nothing live, so we should use the liveness at the
- end of the non-throw branch. */
-
- if (seenConditionalJump && (impInlineInfo->inlineCandidateInfo->fncRetType != TYP_VOID))
- {
- compInlineResult->NoteFatal(InlineObservation::CALLSITE_CONDITIONAL_THROW);
- return;
- }
}
if (tiVerificationNeeded)
@@ -14714,6 +14854,10 @@ GenTreePtr Compiler::impAssignMultiRegTypeToVar(GenTreePtr op, CORINFO_CLASS_HAN
unsigned tmpNum = lvaGrabTemp(true DEBUGARG("Return value temp for multireg return."));
impAssignTempGen(tmpNum, op, hClass, (unsigned)CHECK_SPILL_NONE);
GenTreePtr ret = gtNewLclvNode(tmpNum, op->gtType);
+
+ // TODO-1stClassStructs: Handle constant propagation and CSE-ing of multireg returns.
+ ret->gtFlags |= GTF_DONT_CSE;
+
assert(IsMultiRegReturnedType(hClass));
// Mark the var so that fields are not promoted and stay together.
@@ -14852,7 +14996,8 @@ bool Compiler::impReturnInstruction(BasicBlock* block, int prefixFlags, OPCODE&
if (lvaInlineeReturnSpillTemp != BAD_VAR_NUM)
{
- assert(info.compRetNativeType != TYP_VOID && fgMoreThanOneReturnBlock());
+ assert(info.compRetNativeType != TYP_VOID &&
+ (fgMoreThanOneReturnBlock() || impInlineInfo->hasPinnedLocals));
// This is a bit of a workaround...
// If we are inlining a call that returns a struct, where the actual "native" return type is
@@ -14943,7 +15088,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());
+ assert(fgMoreThanOneReturnBlock() || impInlineInfo->hasPinnedLocals);
impAssignTempGen(lvaInlineeReturnSpillTemp, op2, se.seTypeInfo.GetClassHandle(),
(unsigned)CHECK_SPILL_ALL);
@@ -16469,7 +16614,7 @@ void Compiler::impImport(BasicBlock* method)
// coupled with the JIT64 IL Verification logic. Look inside verHandleVerificationFailure
// method for further explanation on why we raise this exception instead of making the jitted
// code throw the verification exception during execution.
- if (tiVerificationNeeded && (opts.eeFlags & CORJIT_FLG_IMPORT_ONLY) != 0)
+ if (tiVerificationNeeded && opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IMPORT_ONLY))
{
BADCODE("Basic block marked as not verifiable");
}
@@ -16989,18 +17134,10 @@ void Compiler::impInlineRecordArgInfo(InlineInfo* pInlineInfo,
#endif // FEATURE_SIMD
}
- if (curArgVal->gtFlags & GTF_ORDER_SIDEEFF)
- {
- // Right now impInlineSpillLclRefs and impInlineSpillGlobEffects don't take
- // into account special side effects, so we disallow them during inlining.
- inlineResult->NoteFatal(InlineObservation::CALLSITE_ARG_HAS_SIDE_EFFECT);
- return;
- }
-
- if (curArgVal->gtFlags & GTF_GLOB_EFFECT)
+ if (curArgVal->gtFlags & GTF_ALL_EFFECT)
{
inlCurArgInfo->argHasGlobRef = (curArgVal->gtFlags & GTF_GLOB_REF) != 0;
- inlCurArgInfo->argHasSideEff = (curArgVal->gtFlags & GTF_SIDE_EFFECT) != 0;
+ inlCurArgInfo->argHasSideEff = (curArgVal->gtFlags & (GTF_ALL_EFFECT & ~GTF_GLOB_REF)) != 0;
}
if (curArgVal->gtOper == GT_LCL_VAR)
@@ -17251,6 +17388,7 @@ void Compiler::impInlineInitVars(InlineInfo* pInlineInfo)
var_types sigType = (var_types)eeGetArgType(argLst, &methInfo->args);
lclVarInfo[i].lclVerTypeInfo = verParseArgSigToTypeInfo(&methInfo->args, argLst);
+
#ifdef FEATURE_SIMD
if ((!foundSIMDType || (sigType == TYP_STRUCT)) && isSIMDClass(&(lclVarInfo[i].lclVerTypeInfo)))
{
@@ -17377,16 +17515,49 @@ void Compiler::impInlineInitVars(InlineInfo* pInlineInfo)
var_types type = (var_types)eeGetArgType(localsSig, &methInfo->locals, &isPinned);
lclVarInfo[i + argCnt].lclHasLdlocaOp = false;
+ lclVarInfo[i + argCnt].lclIsPinned = isPinned;
lclVarInfo[i + argCnt].lclTypeInfo = type;
if (isPinned)
{
- inlineResult->NoteFatal(InlineObservation::CALLEE_HAS_PINNED_LOCALS);
- return;
+ // Pinned locals may cause inlines to fail.
+ inlineResult->Note(InlineObservation::CALLEE_HAS_PINNED_LOCALS);
+ if (inlineResult->IsFailure())
+ {
+ return;
+ }
}
lclVarInfo[i + argCnt].lclVerTypeInfo = verParseArgSigToTypeInfo(&methInfo->locals, localsSig);
+ // If this local is a struct type with GC fields, inform the inliner. It may choose to bail
+ // out on the inline.
+ if (type == TYP_STRUCT)
+ {
+ CORINFO_CLASS_HANDLE lclHandle = lclVarInfo[i + argCnt].lclVerTypeInfo.GetClassHandle();
+ DWORD typeFlags = info.compCompHnd->getClassAttribs(lclHandle);
+ if ((typeFlags & CORINFO_FLG_CONTAINS_GC_PTR) != 0)
+ {
+ inlineResult->Note(InlineObservation::CALLEE_HAS_GC_STRUCT);
+ if (inlineResult->IsFailure())
+ {
+ return;
+ }
+
+ // Do further notification in the case where the call site is rare; some policies do
+ // not track the relative hotness of call sites for "always" inline cases.
+ if (pInlineInfo->iciBlock->isRunRarely())
+ {
+ inlineResult->Note(InlineObservation::CALLSITE_RARE_GC_STRUCT);
+ if (inlineResult->IsFailure())
+ {
+
+ return;
+ }
+ }
+ }
+ }
+
localsSig = info.compCompHnd->getArgNext(localsSig);
#ifdef FEATURE_SIMD
@@ -17431,6 +17602,28 @@ unsigned Compiler::impInlineFetchLocal(unsigned lclNum DEBUGARG(const char* reas
lvaTable[tmpNum].lvHasLdAddrOp = 1;
}
+ if (impInlineInfo->lclVarInfo[lclNum + impInlineInfo->argCnt].lclIsPinned)
+ {
+ 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;
+ }
+
if (impInlineInfo->lclVarInfo[lclNum + impInlineInfo->argCnt].lclVerTypeInfo.IsStruct())
{
if (varTypeIsStruct(lclTyp))
@@ -17895,10 +18088,17 @@ void Compiler::impMarkInlineCandidate(GenTreePtr callNode,
bool Compiler::IsTargetIntrinsic(CorInfoIntrinsics intrinsicId)
{
-#if defined(_TARGET_AMD64_)
+#if defined(_TARGET_AMD64_) || (defined(_TARGET_X86_) && !defined(LEGACY_BACKEND))
switch (intrinsicId)
{
// Amd64 only has SSE2 instruction to directly compute sqrt/abs.
+ //
+ // TODO: Because the x86 backend only targets SSE for floating-point code,
+ // it does not treat Sine, Cosine, or Round as intrinsics (JIT32
+ // implemented those intrinsics as x87 instructions). If this poses
+ // a CQ problem, it may be necessary to change the implementation of
+ // the helper calls to decrease call overhead or switch back to the
+ // x87 instructions. This is tracked by #7097.
case CORINFO_INTRINSIC_Sqrt:
case CORINFO_INTRINSIC_Abs:
return true;
diff --git a/src/jit/inline.cpp b/src/jit/inline.cpp
index deccc0e84b..05fcf1c6b9 100644
--- a/src/jit/inline.cpp
+++ b/src/jit/inline.cpp
@@ -447,7 +447,7 @@ void InlineContext::DumpData(unsigned indent)
else if (m_Success)
{
const char* inlineReason = InlGetObservationString(m_Observation);
- printf("%*s%u,\"%s\",\"%s\"", indent, "", m_Ordinal, inlineReason, calleeName);
+ printf("%*s%u,\"%s\",\"%s\",", indent, "", m_Ordinal, inlineReason, calleeName);
m_Policy->DumpData(jitstdout);
printf("\n");
}
@@ -500,14 +500,25 @@ void InlineContext::DumpXml(FILE* file, unsigned indent)
fprintf(file, "%*s<Offset>%u</Offset>\n", indent + 2, "", offset);
fprintf(file, "%*s<Reason>%s</Reason>\n", indent + 2, "", inlineReason);
- // Optionally, dump data about the last inline
- if ((JitConfig.JitInlineDumpData() != 0) && (this == m_InlineStrategy->GetLastContext()))
+ // Optionally, dump data about the inline
+ const int dumpDataSetting = JitConfig.JitInlineDumpData();
+
+ // JitInlineDumpData=1 -- dump data plus deltas for last inline only
+ if ((dumpDataSetting == 1) && (this == m_InlineStrategy->GetLastContext()))
{
fprintf(file, "%*s<Data>", indent + 2, "");
m_InlineStrategy->DumpDataContents(file);
fprintf(file, "</Data>\n");
}
+ // JitInlineDumpData=2 -- dump data for all inlines, no deltas
+ if ((dumpDataSetting == 2) && (m_Policy != nullptr))
+ {
+ fprintf(file, "%*s<Data>", indent + 2, "");
+ m_Policy->DumpData(file);
+ fprintf(file, "</Data>\n");
+ }
+
newIndent = indent + 2;
}
@@ -646,10 +657,11 @@ void InlineResult::Report()
m_Reported = true;
#ifdef DEBUG
- const char* callee = nullptr;
+ const char* callee = nullptr;
+ const bool showInlines = (JitConfig.JitPrintInlinedMethods() == 1);
// Optionally dump the result
- if (VERBOSE)
+ if (VERBOSE || showInlines)
{
const char* format = "INLINER: during '%s' result '%s' reason '%s' for '%s' calling '%s'\n";
const char* caller = (m_Caller == nullptr) ? "n/a" : m_RootCompiler->eeGetMethodFullName(m_Caller);
@@ -689,12 +701,18 @@ void InlineResult::Report()
#ifdef DEBUG
+ const char* obsString = InlGetObservationString(obs);
+
if (VERBOSE)
{
- const char* obsString = InlGetObservationString(obs);
JITDUMP("\nINLINER: Marking %s as NOINLINE because of %s\n", callee, obsString);
}
+ if (showInlines)
+ {
+ printf("Marking %s as NOINLINE because of %s\n", callee, obsString);
+ }
+
#endif // DEBUG
COMP_HANDLE comp = m_RootCompiler->info.compCompHnd;
@@ -740,6 +758,7 @@ InlineStrategy::InlineStrategy(Compiler* compiler)
, m_HasForceViaDiscretionary(false)
#if defined(DEBUG) || defined(INLINE_DATA)
, m_MethodXmlFilePosition(0)
+ , m_Random(nullptr)
#endif // defined(DEBUG) || defined(INLINE_DATA)
{
@@ -1155,10 +1174,10 @@ InlineContext* InlineStrategy::NewRoot()
InlineContext* InlineStrategy::NewSuccess(InlineInfo* inlineInfo)
{
InlineContext* calleeContext = new (m_Compiler, CMK_Inlining) InlineContext(this);
- GenTree* stmt = inlineInfo->iciStmt;
+ GenTreeStmt* stmt = inlineInfo->iciStmt;
BYTE* calleeIL = inlineInfo->inlineCandidateInfo->methInfo.ILCode;
unsigned calleeILSize = inlineInfo->inlineCandidateInfo->methInfo.ILCodeSize;
- InlineContext* parentContext = stmt->gtStmt.gtInlineContext;
+ InlineContext* parentContext = stmt->gtInlineContext;
noway_assert(parentContext != nullptr);
@@ -1213,35 +1232,22 @@ InlineContext* InlineStrategy::NewSuccess(InlineInfo* inlineInfo)
// A new InlineContext for diagnostic purposes, or nullptr if
// the desired context could not be created.
-InlineContext* InlineStrategy::NewFailure(GenTree* stmt, InlineResult* inlineResult)
+InlineContext* InlineStrategy::NewFailure(GenTreeStmt* stmt, InlineResult* inlineResult)
{
- // Check for a parent context first. We may insert new statements
- // between the caller and callee that do not pick up either's
- // context, and these statements may have calls that we later
- // examine and fail to inline.
- //
- // See fgInlinePrependStatements for examples.
-
- InlineContext* parentContext = stmt->gtStmt.gtInlineContext;
-
- if (parentContext == nullptr)
- {
- // Assume for now this is a failure to inline a call in a
- // statement inserted between caller and callee. Just ignore
- // it for the time being.
-
- return nullptr;
- }
-
+ // Check for a parent context first. We should now have a parent
+ // context for all statements.
+ InlineContext* parentContext = stmt->gtInlineContext;
+ assert(parentContext != nullptr);
InlineContext* failedContext = new (m_Compiler, CMK_Inlining) InlineContext(this);
- failedContext->m_Parent = parentContext;
- // Push on front here will put siblings in reverse lexical
- // order which we undo in the dumper
+ // Pushing the new context on the front of the parent child list
+ // will put siblings in reverse lexical order which we undo in the
+ // dumper.
+ failedContext->m_Parent = parentContext;
failedContext->m_Sibling = parentContext->m_Child;
parentContext->m_Child = failedContext;
failedContext->m_Child = nullptr;
- failedContext->m_Offset = stmt->AsStmt()->gtStmtILoffsx;
+ failedContext->m_Offset = stmt->gtStmtILoffsx;
failedContext->m_Observation = inlineResult->GetObservation();
failedContext->m_Callee = inlineResult->GetCallee();
failedContext->m_Success = false;
@@ -1354,7 +1360,7 @@ void InlineStrategy::DumpDataEnsurePolicyIsSet()
// successful policy, so fake one up.
if (m_LastSuccessfulPolicy == nullptr)
{
- const bool isPrejitRoot = (opts.eeFlags & CORJIT_FLG_PREJIT) != 0;
+ const bool isPrejitRoot = opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT);
m_LastSuccessfulPolicy = InlinePolicy::GetPolicy(m_Compiler, isPrejitRoot);
// Add in a bit of data....
@@ -1388,7 +1394,7 @@ void InlineStrategy::DumpDataHeader(FILE* file)
void InlineStrategy::DumpDataSchema(FILE* file)
{
DumpDataEnsurePolicyIsSet();
- fprintf(file, "Method,Version,HotSize,ColdSize,JitTime,SizeEstimate,TimeEstimate");
+ fprintf(file, "Method,Version,HotSize,ColdSize,JitTime,SizeEstimate,TimeEstimate,");
m_LastSuccessfulPolicy->DumpSchema(file);
}
@@ -1424,7 +1430,7 @@ void InlineStrategy::DumpDataContents(FILE* file)
microsecondsSpentJitting = (unsigned)((counts / countsPerSec) * 1000 * 1000);
}
- fprintf(file, "%08X,%u,%u,%u,%u,%d,%d", currentMethodToken, m_InlineCount, info.compTotalHotCodeSize,
+ fprintf(file, "%08X,%u,%u,%u,%u,%d,%d,", currentMethodToken, m_InlineCount, info.compTotalHotCodeSize,
info.compTotalColdCodeSize, microsecondsSpentJitting, m_CurrentSizeEstimate / 10, m_CurrentTimeEstimate);
m_LastSuccessfulPolicy->DumpData(file);
}
@@ -1461,10 +1467,22 @@ void InlineStrategy::DumpXml(FILE* file, unsigned indent)
fprintf(file, "<InlineForest>\n");
fprintf(file, "<Policy>%s</Policy>\n", m_LastSuccessfulPolicy->GetName());
- if (JitConfig.JitInlineDumpData() != 0)
+ const int dumpDataSetting = JitConfig.JitInlineDumpData();
+ if (dumpDataSetting != 0)
{
fprintf(file, "<DataSchema>");
- DumpDataSchema(file);
+
+ if (dumpDataSetting == 1)
+ {
+ // JitInlineDumpData=1 -- dump schema for data plus deltas
+ DumpDataSchema(file);
+ }
+ else if (dumpDataSetting == 2)
+ {
+ // JitInlineDumpData=2 -- dump schema for data only
+ m_LastSuccessfulPolicy->DumpSchema(file);
+ }
+
fprintf(file, "</DataSchema>\n");
}
@@ -1484,7 +1502,7 @@ void InlineStrategy::DumpXml(FILE* file, unsigned indent)
const Compiler::Info& info = m_Compiler->info;
const Compiler::Options& opts = m_Compiler->opts;
- const bool isPrejitRoot = (opts.eeFlags & CORJIT_FLG_PREJIT) != 0;
+ const bool isPrejitRoot = opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT);
const bool isForceInline = (info.compFlags & CORINFO_FLG_FORCEINLINE) != 0;
// We'd really like the method identifier to be unique and
@@ -1589,6 +1607,52 @@ void InlineStrategy::FinalizeXml(FILE* file)
ReplayPolicy::FinalizeXml();
}
+//------------------------------------------------------------------------
+// GetRandom: setup or access random state
+//
+// Return Value:
+// New or pre-existing random state.
+//
+// Notes:
+// Random state is kept per jit compilation request. Seed is partially
+// specified externally (via stress or policy setting) and partially
+// specified internally via method hash.
+
+CLRRandom* InlineStrategy::GetRandom()
+{
+ if (m_Random == nullptr)
+ {
+ int externalSeed = 0;
+
+#ifdef DEBUG
+
+ if (m_Compiler->compRandomInlineStress())
+ {
+ externalSeed = getJitStressLevel();
+ }
+
+#endif // DEBUG
+
+ int randomPolicyFlag = JitConfig.JitInlinePolicyRandom();
+ if (randomPolicyFlag != 0)
+ {
+ externalSeed = randomPolicyFlag;
+ }
+
+ int internalSeed = m_Compiler->info.compMethodHash();
+
+ assert(externalSeed != 0);
+ assert(internalSeed != 0);
+
+ int seed = externalSeed ^ internalSeed;
+
+ m_Random = new (m_Compiler, CMK_Inlining) CLRRandom();
+ m_Random->Init(seed);
+ }
+
+ return m_Random;
+}
+
#endif // defined(DEBUG) || defined(INLINE_DATA)
//------------------------------------------------------------------------
diff --git a/src/jit/inline.def b/src/jit/inline.def
index 2c933fb8a9..ff0b21100e 100644
--- a/src/jit/inline.def
+++ b/src/jit/inline.def
@@ -40,7 +40,6 @@ INLINE_OBSERVATION(HAS_MANAGED_VARARGS, bool, "managed varargs",
INLINE_OBSERVATION(HAS_NATIVE_VARARGS, bool, "native varargs", FATAL, CALLEE)
INLINE_OBSERVATION(HAS_NO_BODY, bool, "has no body", FATAL, CALLEE)
INLINE_OBSERVATION(HAS_NULL_FOR_LDELEM, bool, "has null pointer for ldelem", FATAL, CALLEE)
-INLINE_OBSERVATION(HAS_PINNED_LOCALS, bool, "has pinned locals", FATAL, CALLEE)
INLINE_OBSERVATION(IS_ARRAY_METHOD, bool, "is array method", FATAL, CALLEE)
INLINE_OBSERVATION(IS_GENERIC_VIRTUAL, bool, "generic virtual", FATAL, CALLEE)
INLINE_OBSERVATION(IS_JIT_NOINLINE, bool, "noinline per JitNoinline", FATAL, CALLEE)
@@ -78,6 +77,8 @@ INLINE_OBSERVATION(BELOW_ALWAYS_INLINE_SIZE, bool, "below ALWAYS_INLINE size"
INLINE_OBSERVATION(CLASS_PROMOTABLE, bool, "promotable value class", INFORMATION, CALLEE)
INLINE_OBSERVATION(DOES_NOT_RETURN, bool, "does not return", INFORMATION, CALLEE)
INLINE_OBSERVATION(END_OPCODE_SCAN, bool, "done looking at opcodes", INFORMATION, CALLEE)
+INLINE_OBSERVATION(HAS_GC_STRUCT, bool, "has gc field in struct local", INFORMATION, CALLEE)
+INLINE_OBSERVATION(HAS_PINNED_LOCALS, bool, "has pinned locals", INFORMATION, CALLEE)
INLINE_OBSERVATION(HAS_SIMD, bool, "has SIMD arg, local, or ret", INFORMATION, CALLEE)
INLINE_OBSERVATION(HAS_SWITCH, bool, "has switch", INFORMATION, CALLEE)
INLINE_OBSERVATION(IL_CODE_SIZE, int, "number of bytes of IL", INFORMATION, CALLEE)
@@ -112,7 +113,6 @@ INLINE_OBSERVATION(HAS_NEWOBJ, bool, "has newobj",
// ------ Call Site Correctness -------
INLINE_OBSERVATION(ARG_HAS_NULL_THIS, bool, "this pointer argument is null", FATAL, CALLSITE)
-INLINE_OBSERVATION(ARG_HAS_SIDE_EFFECT, bool, "argument has side effect", FATAL, CALLSITE)
INLINE_OBSERVATION(ARG_IS_MKREFANY, bool, "argument is mkrefany", FATAL, CALLSITE)
INLINE_OBSERVATION(ARG_NO_BASH_TO_INT, bool, "argument can't bash to int", FATAL, CALLSITE)
INLINE_OBSERVATION(ARG_NO_BASH_TO_REF, bool, "argument can't bash to ref", FATAL, CALLSITE)
@@ -122,7 +122,6 @@ INLINE_OBSERVATION(CANT_EMBED_VARARGS_COOKIE, bool, "can't embed varargs cooki
INLINE_OBSERVATION(CLASS_INIT_FAILURE_SPEC, bool, "speculative class init failed", FATAL, CALLSITE)
INLINE_OBSERVATION(COMPILATION_ERROR, bool, "compilation error", FATAL, CALLSITE)
INLINE_OBSERVATION(COMPILATION_FAILURE, bool, "failed to compile", FATAL, CALLSITE)
-INLINE_OBSERVATION(CONDITIONAL_THROW, bool, "conditional throw", FATAL, CALLSITE)
INLINE_OBSERVATION(CROSS_BOUNDARY_CALLI, bool, "cross-boundary calli", FATAL, CALLSITE)
INLINE_OBSERVATION(CROSS_BOUNDARY_SECURITY, bool, "cross-boundary security check", FATAL, CALLSITE)
INLINE_OBSERVATION(EXCEEDS_THRESHOLD, bool, "exceeds profit threshold", FATAL, CALLSITE)
@@ -140,7 +139,7 @@ INLINE_OBSERVATION(IS_TOO_DEEP, bool, "too deep",
INLINE_OBSERVATION(IS_VIRTUAL, bool, "virtual", FATAL, CALLSITE)
INLINE_OBSERVATION(IS_VM_NOINLINE, bool, "noinline per VM", FATAL, CALLSITE)
INLINE_OBSERVATION(IS_WITHIN_CATCH, bool, "within catch region", FATAL, CALLSITE)
-INLINE_OBSERVATION(IS_WITHIN_FILTER, bool, "within filterregion", FATAL, CALLSITE)
+INLINE_OBSERVATION(IS_WITHIN_FILTER, bool, "within filter region", FATAL, CALLSITE)
INLINE_OBSERVATION(LDARGA_NOT_LOCAL_VAR, bool, "ldarga not on local var", FATAL, CALLSITE)
INLINE_OBSERVATION(LDFLD_NEEDS_HELPER, bool, "ldfld needs helper", FATAL, CALLSITE)
INLINE_OBSERVATION(LDVIRTFN_ON_NON_VIRTUAL, bool, "ldvirtfn on non-virtual", FATAL, CALLSITE)
@@ -149,6 +148,7 @@ INLINE_OBSERVATION(NOT_CANDIDATE, bool, "not inline candidate",
INLINE_OBSERVATION(NOT_PROFITABLE_INLINE, bool, "unprofitable inline", FATAL, CALLSITE)
INLINE_OBSERVATION(OVER_BUDGET, bool, "inline exceeds budget", FATAL, CALLSITE)
INLINE_OBSERVATION(OVER_INLINE_LIMIT, bool, "limited by JitInlineLimit", FATAL, CALLSITE)
+INLINE_OBSERVATION(PIN_IN_TRY_REGION, bool, "within try region, pinned", FATAL, CALLSITE)
INLINE_OBSERVATION(RANDOM_REJECT, bool, "random reject", FATAL, CALLSITE)
INLINE_OBSERVATION(REQUIRES_SAME_THIS, bool, "requires same this", FATAL, CALLSITE)
INLINE_OBSERVATION(RETURN_TYPE_MISMATCH, bool, "return type mismatch", FATAL, CALLSITE)
@@ -157,12 +157,14 @@ INLINE_OBSERVATION(TOO_MANY_LOCALS, bool, "too many locals",
// ------ Call Site Performance -------
+INLINE_OBSERVATION(RARE_GC_STRUCT, bool, "rarely called, has gc struct", INFORMATION, CALLSITE)
// ------ Call Site Information -------
INLINE_OBSERVATION(CONSTANT_ARG_FEEDS_TEST, bool, "constant argument feeds test", INFORMATION, CALLSITE)
INLINE_OBSERVATION(DEPTH, int, "depth", INFORMATION, CALLSITE)
INLINE_OBSERVATION(FREQUENCY, int, "rough call site frequency", INFORMATION, CALLSITE)
+INLINE_OBSERVATION(IN_TRY_REGION, bool, "call site in try region", INFORMATION, CALLSITE)
INLINE_OBSERVATION(IS_PROFITABLE_INLINE, bool, "profitable inline", INFORMATION, CALLSITE)
INLINE_OBSERVATION(IS_SAME_THIS, bool, "same this as root caller", INFORMATION, CALLSITE)
INLINE_OBSERVATION(IS_SIZE_DECREASING_INLINE, bool, "size decreasing inline", INFORMATION, CALLSITE)
diff --git a/src/jit/inline.h b/src/jit/inline.h
index e3d5750754..2634ebe6fa 100644
--- a/src/jit/inline.h
+++ b/src/jit/inline.h
@@ -85,11 +85,6 @@ const unsigned int MAX_INL_ARGS = 10; // does not include obj pointer
const unsigned int MAX_INL_LCLS = 8;
#endif // LEGACY_BACKEND
-// Flags lost during inlining.
-
-#define CORJIT_FLG_LOST_WHEN_INLINING \
- (CORJIT_FLG_BBOPT | CORJIT_FLG_BBINSTR | CORJIT_FLG_PROF_ENTERLEAVE | CORJIT_FLG_DEBUG_EnC | CORJIT_FLG_DEBUG_INFO)
-
// Forward declarations
class InlineStrategy;
@@ -542,6 +537,7 @@ struct InlLclVarInfo
var_types lclTypeInfo;
typeInfo lclVerTypeInfo;
bool lclHasLdlocaOp; // Is there LDLOCA(s) operation on this argument?
+ bool lclIsPinned;
};
// InlineInfo provides detailed information about a particular inline candidate.
@@ -568,12 +564,13 @@ struct InlineInfo
InlLclVarInfo lclVarInfo[MAX_INL_LCLS + MAX_INL_ARGS + 1]; // type information from local sig
bool thisDereferencedFirst;
+ bool hasPinnedLocals;
#ifdef FEATURE_SIMD
bool hasSIMDTypeArgLocalOrReturn;
#endif // FEATURE_SIMD
GenTreeCall* iciCall; // The GT_CALL node to be inlined.
- GenTree* iciStmt; // The statement iciCall is in.
+ GenTreeStmt* iciStmt; // The statement iciCall is in.
BasicBlock* iciBlock; // The basic block iciStmt is in.
};
@@ -706,7 +703,7 @@ public:
InlineContext* NewSuccess(InlineInfo* inlineInfo);
// Create context for a failing inline.
- InlineContext* NewFailure(GenTree* stmt, InlineResult* inlineResult);
+ InlineContext* NewFailure(GenTreeStmt* stmt, InlineResult* inlineResult);
// Compiler associated with this strategy
Compiler* GetCompiler() const
@@ -823,6 +820,9 @@ public:
m_MethodXmlFilePosition = val;
}
+ // Set up or access random state (for use by RandomPolicy)
+ CLRRandom* GetRandom();
+
#endif // defined(DEBUG) || defined(INLINE_DATA)
// Some inline limit values
@@ -887,7 +887,8 @@ private:
bool m_HasForceViaDiscretionary;
#if defined(DEBUG) || defined(INLINE_DATA)
- long m_MethodXmlFilePosition;
+ long m_MethodXmlFilePosition;
+ CLRRandom* m_Random;
#endif // defined(DEBUG) || defined(INLINE_DATA)
};
diff --git a/src/jit/inlinepolicy.cpp b/src/jit/inlinepolicy.cpp
index f80f3a5ec0..61e70c3ed4 100644
--- a/src/jit/inlinepolicy.cpp
+++ b/src/jit/inlinepolicy.cpp
@@ -27,22 +27,22 @@
InlinePolicy* InlinePolicy::GetPolicy(Compiler* compiler, bool isPrejitRoot)
{
-#ifdef DEBUG
+#if defined(DEBUG) || defined(INLINE_DATA)
- // Optionally install the RandomPolicy.
- bool useRandomPolicy = compiler->compRandomInlineStress();
+#if defined(DEBUG)
+ const bool useRandomPolicyForStress = compiler->compRandomInlineStress();
+#else
+ const bool useRandomPolicyForStress = false;
+#endif // defined(DEBUG)
+
+ const bool useRandomPolicy = (JitConfig.JitInlinePolicyRandom() != 0);
- if (useRandomPolicy)
+ // Optionally install the RandomPolicy.
+ if (useRandomPolicyForStress || useRandomPolicy)
{
- unsigned seed = getJitStressLevel();
- assert(seed != 0);
- return new (compiler, CMK_Inlining) RandomPolicy(compiler, isPrejitRoot, seed);
+ return new (compiler, CMK_Inlining) RandomPolicy(compiler, isPrejitRoot);
}
-#endif // DEBUG
-
-#if defined(DEBUG) || defined(INLINE_DATA)
-
// Optionally install the ReplayPolicy.
bool useReplayPolicy = JitConfig.JitInlinePolicyReplay() != 0;
@@ -106,7 +106,7 @@ InlinePolicy* InlinePolicy::GetPolicy(Compiler* compiler, bool isPrejitRoot)
void LegalPolicy::NoteFatal(InlineObservation obs)
{
// As a safeguard, all fatal impact must be
- // reported via noteFatal.
+ // reported via NoteFatal.
assert(InlGetImpact(obs) == InlineImpact::FATAL);
NoteInternal(obs);
assert(InlDecisionIsFailure(m_Decision));
@@ -243,7 +243,7 @@ void LegacyPolicy::NoteBool(InlineObservation obs, bool value)
InlineImpact impact = InlGetImpact(obs);
// As a safeguard, all fatal impact must be
- // reported via noteFatal.
+ // reported via NoteFatal.
assert(impact != InlineImpact::FATAL);
// Handle most information here
@@ -383,6 +383,12 @@ void LegacyPolicy::NoteBool(InlineObservation obs, bool value)
break;
}
+ case InlineObservation::CALLEE_HAS_PINNED_LOCALS:
+ // The legacy policy is to never inline methods with
+ // pinned locals.
+ SetNever(obs);
+ break;
+
default:
// Ignore the remainder for now
break;
@@ -443,16 +449,16 @@ void LegacyPolicy::NoteInt(InlineObservation obs, int value)
// Now that we know size and forceinline state,
// update candidacy.
- if (m_CodeSize <= InlineStrategy::ALWAYS_INLINE_SIZE)
- {
- // Candidate based on small size
- SetCandidate(InlineObservation::CALLEE_BELOW_ALWAYS_INLINE_SIZE);
- }
- else if (m_IsForceInline)
+ if (m_IsForceInline)
{
// Candidate based on force inline
SetCandidate(InlineObservation::CALLEE_IS_FORCE_INLINE);
}
+ else if (m_CodeSize <= InlineStrategy::ALWAYS_INLINE_SIZE)
+ {
+ // Candidate based on small size
+ SetCandidate(InlineObservation::CALLEE_BELOW_ALWAYS_INLINE_SIZE);
+ }
else if (m_CodeSize <= m_RootCompiler->m_inlineStrategy->GetMaxInlineILSize())
{
// Candidate, pending profitability evaluation
@@ -842,11 +848,21 @@ int LegacyPolicy::CodeSizeEstimate()
// NoteBool: handle a boolean observation with non-fatal impact
//
// Arguments:
-// obs - the current obsevation
+// obs - the current observation
// value - the value of the observation
void EnhancedLegacyPolicy::NoteBool(InlineObservation obs, bool value)
{
+
+#ifdef DEBUG
+ // Check the impact
+ InlineImpact impact = InlGetImpact(obs);
+
+ // As a safeguard, all fatal impact must be
+ // reported via NoteFatal.
+ assert(impact != InlineImpact::FATAL);
+#endif // DEBUG
+
switch (obs)
{
case InlineObservation::CALLEE_DOES_NOT_RETURN:
@@ -854,6 +870,36 @@ void EnhancedLegacyPolicy::NoteBool(InlineObservation obs, bool value)
m_IsNoReturnKnown = true;
break;
+ case InlineObservation::CALLSITE_RARE_GC_STRUCT:
+ // If this is a discretionary or always inline candidate
+ // with a gc struct, we may change our mind about inlining
+ // if the call site is rare, to avoid costs associated with
+ // zeroing the GC struct up in the root prolog.
+ if (m_Observation == InlineObservation::CALLEE_BELOW_ALWAYS_INLINE_SIZE)
+ {
+ assert(m_CallsiteFrequency == InlineCallsiteFrequency::UNUSED);
+ SetFailure(obs);
+ return;
+ }
+ else if (m_Observation == InlineObservation::CALLEE_IS_DISCRETIONARY_INLINE)
+ {
+ assert(m_CallsiteFrequency == InlineCallsiteFrequency::RARE);
+ SetFailure(obs);
+ return;
+ }
+ break;
+
+ case InlineObservation::CALLEE_HAS_PINNED_LOCALS:
+ if (m_CallsiteIsInTryRegion)
+ {
+ // Inlining a method with pinned locals in a try
+ // region requires wrapping the inline body in a
+ // try/finally to ensure unpinning. Bail instead.
+ SetFailure(InlineObservation::CALLSITE_PIN_IN_TRY_REGION);
+ return;
+ }
+ break;
+
default:
// Pass all other information to the legacy policy
LegacyPolicy::NoteBool(obs, value);
@@ -928,7 +974,7 @@ bool EnhancedLegacyPolicy::PropagateNeverToRuntime() const
return propagate;
}
-#ifdef DEBUG
+#if defined(DEBUG) || defined(INLINE_DATA)
//------------------------------------------------------------------------
// RandomPolicy: construct a new RandomPolicy
@@ -936,89 +982,10 @@ bool EnhancedLegacyPolicy::PropagateNeverToRuntime() const
// Arguments:
// compiler -- compiler instance doing the inlining (root compiler)
// isPrejitRoot -- true if this compiler is prejitting the root method
-// seed -- seed value for the random number generator
-
-RandomPolicy::RandomPolicy(Compiler* compiler, bool isPrejitRoot, unsigned seed)
- : LegalPolicy(isPrejitRoot)
- , m_RootCompiler(compiler)
- , m_Random(nullptr)
- , m_CodeSize(0)
- , m_IsForceInline(false)
- , m_IsForceInlineKnown(false)
-{
- // If necessary, setup and seed the random state.
- if (compiler->inlRNG == nullptr)
- {
- compiler->inlRNG = new (compiler, CMK_Inlining) CLRRandom();
- unsigned hash = m_RootCompiler->info.compMethodHash();
- assert(hash != 0);
- assert(seed != 0);
- int hashSeed = static_cast<int>(hash ^ seed);
- compiler->inlRNG->Init(hashSeed);
- }
-
- m_Random = compiler->inlRNG;
-}
-
-//------------------------------------------------------------------------
-// NoteSuccess: handle finishing all the inlining checks successfully
-
-void RandomPolicy::NoteSuccess()
+RandomPolicy::RandomPolicy(Compiler* compiler, bool isPrejitRoot) : DiscretionaryPolicy(compiler, isPrejitRoot)
{
- assert(InlDecisionIsCandidate(m_Decision));
- m_Decision = InlineDecision::SUCCESS;
-}
-
-//------------------------------------------------------------------------
-// NoteBool: handle a boolean observation with non-fatal impact
-//
-// Arguments:
-// obs - the current obsevation
-// value - the value of the observation
-void RandomPolicy::NoteBool(InlineObservation obs, bool value)
-{
- // Check the impact
- InlineImpact impact = InlGetImpact(obs);
-
- // As a safeguard, all fatal impact must be
- // reported via noteFatal.
- assert(impact != InlineImpact::FATAL);
-
- // Handle most information here
- bool isInformation = (impact == InlineImpact::INFORMATION);
- bool propagate = !isInformation;
-
- if (isInformation)
- {
- switch (obs)
- {
- case InlineObservation::CALLEE_IS_FORCE_INLINE:
- // The RandomPolicy still honors force inlines.
- //
- // We may make the force-inline observation more than
- // once. All observations should agree.
- assert(!m_IsForceInlineKnown || (m_IsForceInline == value));
- m_IsForceInline = value;
- m_IsForceInlineKnown = true;
- break;
-
- case InlineObservation::CALLEE_HAS_SWITCH:
- case InlineObservation::CALLEE_UNSUPPORTED_OPCODE:
- // Pass these on, they should cause inlining to fail.
- propagate = true;
- break;
-
- default:
- // Ignore the remainder for now
- break;
- }
- }
-
- if (propagate)
- {
- NoteInternal(obs);
- }
+ m_Random = compiler->m_inlineStrategy->GetRandom();
}
//------------------------------------------------------------------------
@@ -1032,7 +999,6 @@ void RandomPolicy::NoteInt(InlineObservation obs, int value)
{
switch (obs)
{
-
case InlineObservation::CALLEE_IL_CODE_SIZE:
{
assert(m_IsForceInlineKnown);
@@ -1054,7 +1020,8 @@ void RandomPolicy::NoteInt(InlineObservation obs, int value)
}
default:
- // Ignore all other information
+ // Defer to superclass for all other information
+ DiscretionaryPolicy::NoteInt(obs, value);
break;
}
}
@@ -1087,6 +1054,16 @@ void RandomPolicy::DetermineProfitability(CORINFO_METHOD_INFO* methodInfo)
}
}
+ // If we're also dumping inline data, make additional observations
+ // based on the method info, and estimate code size and perf
+ // impact, so that the reports have the necessary data.
+ if (JitConfig.JitInlineDumpData() != 0)
+ {
+ MethodInfoObservations(methodInfo);
+ EstimateCodeSize();
+ EstimatePerformanceImpact();
+ }
+
// Use a probability curve that roughly matches the observed
// behavior of the LegacyPolicy. That way we're inlining
// differently but not creating enormous methods.
@@ -1165,7 +1142,7 @@ void RandomPolicy::DetermineProfitability(CORINFO_METHOD_INFO* methodInfo)
}
}
-#endif // DEBUG
+#endif // defined(DEBUG) || defined(INLINE_DATA)
#ifdef _MSC_VER
// Disable warning about new array member initialization behavior
@@ -1181,7 +1158,7 @@ void RandomPolicy::DetermineProfitability(CORINFO_METHOD_INFO* methodInfo)
// clang-format off
DiscretionaryPolicy::DiscretionaryPolicy(Compiler* compiler, bool isPrejitRoot)
- : LegacyPolicy(compiler, isPrejitRoot)
+ : EnhancedLegacyPolicy(compiler, isPrejitRoot)
, m_Depth(0)
, m_BlockCount(0)
, m_Maxstack(0)
@@ -1227,6 +1204,7 @@ DiscretionaryPolicy::DiscretionaryPolicy(Compiler* compiler, bool isPrejitRoot)
, m_IsSameThis(false)
, m_CallerHasNewArray(false)
, m_CallerHasNewObj(false)
+ , m_CalleeHasGCStruct(false)
{
// Empty
}
@@ -1278,8 +1256,17 @@ void DiscretionaryPolicy::NoteBool(InlineObservation obs, bool value)
m_CallerHasNewObj = value;
break;
+ case InlineObservation::CALLEE_HAS_GC_STRUCT:
+ m_CalleeHasGCStruct = value;
+ break;
+
+ case InlineObservation::CALLSITE_RARE_GC_STRUCT:
+ // This is redundant since this policy tracks call site
+ // hotness for all candidates. So ignore.
+ break;
+
default:
- LegacyPolicy::NoteBool(obs, value);
+ EnhancedLegacyPolicy::NoteBool(obs, value);
break;
}
}
@@ -1295,7 +1282,6 @@ void DiscretionaryPolicy::NoteInt(InlineObservation obs, int value)
{
switch (obs)
{
-
case InlineObservation::CALLEE_IL_CODE_SIZE:
// Override how code size is handled
{
@@ -1323,7 +1309,7 @@ void DiscretionaryPolicy::NoteInt(InlineObservation obs, int value)
// on similarity of impact on codegen.
OPCODE opcode = static_cast<OPCODE>(value);
ComputeOpcodeBin(opcode);
- LegacyPolicy::NoteInt(obs, value);
+ EnhancedLegacyPolicy::NoteInt(obs, value);
break;
}
@@ -1344,8 +1330,8 @@ void DiscretionaryPolicy::NoteInt(InlineObservation obs, int value)
break;
default:
- // Delegate remainder to the LegacyPolicy.
- LegacyPolicy::NoteInt(obs, value);
+ // Delegate remainder to the super class.
+ EnhancedLegacyPolicy::NoteInt(obs, value);
break;
}
}
@@ -1660,8 +1646,8 @@ void DiscretionaryPolicy::DetermineProfitability(CORINFO_METHOD_INFO* methodInfo
// model for actual inlining.
EstimatePerformanceImpact();
- // Delegate to LegacyPolicy for the rest
- LegacyPolicy::DetermineProfitability(methodInfo);
+ // Delegate to super class for the rest
+ EnhancedLegacyPolicy::DetermineProfitability(methodInfo);
}
//------------------------------------------------------------------------
@@ -1869,7 +1855,7 @@ int DiscretionaryPolicy::CodeSizeEstimate()
void DiscretionaryPolicy::DumpSchema(FILE* file) const
{
- fprintf(file, ",ILSize");
+ fprintf(file, "ILSize");
fprintf(file, ",CallsiteFrequency");
fprintf(file, ",InstructionCount");
fprintf(file, ",LoadStoreCount");
@@ -1938,6 +1924,8 @@ void DiscretionaryPolicy::DumpSchema(FILE* file) const
fprintf(file, ",IsSameThis");
fprintf(file, ",CallerHasNewArray");
fprintf(file, ",CallerHasNewObj");
+ fprintf(file, ",CalleeDoesNotReturn");
+ fprintf(file, ",CalleeHasGCStruct");
}
//------------------------------------------------------------------------
@@ -1949,7 +1937,7 @@ void DiscretionaryPolicy::DumpSchema(FILE* file) const
void DiscretionaryPolicy::DumpData(FILE* file) const
{
- fprintf(file, ",%u", m_CodeSize);
+ fprintf(file, "%u", m_CodeSize);
fprintf(file, ",%u", m_CallsiteFrequency);
fprintf(file, ",%u", m_InstructionCount);
fprintf(file, ",%u", m_LoadStoreCount);
@@ -2018,6 +2006,8 @@ void DiscretionaryPolicy::DumpData(FILE* file) const
fprintf(file, ",%u", m_IsSameThis ? 1 : 0);
fprintf(file, ",%u", m_CallerHasNewArray ? 1 : 0);
fprintf(file, ",%u", m_CallerHasNewObj ? 1 : 0);
+ fprintf(file, ",%u", m_IsNoReturn ? 1 : 0);
+ fprintf(file, ",%u", m_CalleeHasGCStruct ? 1 : 0);
}
#endif // defined(DEBUG) || defined(INLINE_DATA)
@@ -2473,7 +2463,7 @@ bool ReplayPolicy::FindMethod()
// See if token matches
unsigned token = 0;
- int count = sscanf(buffer, " <Token>%u</Token> ", &token);
+ int count = sscanf_s(buffer, " <Token>%u</Token> ", &token);
if ((count != 1) || (token != methodToken))
{
continue;
@@ -2487,7 +2477,7 @@ bool ReplayPolicy::FindMethod()
// See if hash matches
unsigned hash = 0;
- count = sscanf(buffer, " <Hash>%u</Hash> ", &hash);
+ count = sscanf_s(buffer, " <Hash>%u</Hash> ", &hash);
if ((count != 1) || (hash != methodHash))
{
continue;
@@ -2646,7 +2636,7 @@ bool ReplayPolicy::FindInline(unsigned token, unsigned hash, unsigned offset)
// Match token
unsigned inlineToken = 0;
- int count = sscanf(buffer, " <Token>%u</Token> ", &inlineToken);
+ int count = sscanf_s(buffer, " <Token>%u</Token> ", &inlineToken);
if ((count != 1) || (inlineToken != token))
{
@@ -2661,7 +2651,7 @@ bool ReplayPolicy::FindInline(unsigned token, unsigned hash, unsigned offset)
// Match hash
unsigned inlineHash = 0;
- count = sscanf(buffer, " <Hash>%u</Hash> ", &inlineHash);
+ count = sscanf_s(buffer, " <Hash>%u</Hash> ", &inlineHash);
if ((count != 1) || (inlineHash != hash))
{
@@ -2676,7 +2666,7 @@ bool ReplayPolicy::FindInline(unsigned token, unsigned hash, unsigned offset)
// Match offset
unsigned inlineOffset = 0;
- count = sscanf(buffer, " <Offset>%u</Offset> ", &inlineOffset);
+ count = sscanf_s(buffer, " <Offset>%u</Offset> ", &inlineOffset);
if ((count != 1) || (inlineOffset != offset))
{
continue;
@@ -2695,7 +2685,7 @@ bool ReplayPolicy::FindInline(unsigned token, unsigned hash, unsigned offset)
if (fgets(buffer, sizeof(buffer), s_ReplayFile) != nullptr)
{
unsigned collectData = 0;
- count = sscanf(buffer, " <CollectData>%u</CollectData> ", &collectData);
+ count = sscanf_s(buffer, " <CollectData>%u</CollectData> ", &collectData);
if (count == 1)
{
diff --git a/src/jit/inlinepolicy.h b/src/jit/inlinepolicy.h
index 62031c86a0..3239dcbe89 100644
--- a/src/jit/inlinepolicy.h
+++ b/src/jit/inlinepolicy.h
@@ -98,6 +98,7 @@ public:
, m_HasSimd(false)
, m_LooksLikeWrapperMethod(false)
, m_MethodIsMostlyLoadStore(false)
+ , m_CallsiteIsInTryRegion(false)
{
// empty
}
@@ -165,6 +166,7 @@ protected:
bool m_HasSimd : 1;
bool m_LooksLikeWrapperMethod : 1;
bool m_MethodIsMostlyLoadStore : 1;
+ bool m_CallsiteIsInTryRegion : 1;
};
// EnhancedLegacyPolicy extends the legacy policy by rejecting
@@ -196,65 +198,15 @@ protected:
bool m_IsNoReturnKnown : 1;
};
-#ifdef DEBUG
-
-// RandomPolicy implements a policy that inlines at random.
-// It is mostly useful for stress testing.
-
-class RandomPolicy : public LegalPolicy
-{
-public:
- // Construct a RandomPolicy
- RandomPolicy(Compiler* compiler, bool isPrejitRoot, unsigned seed);
-
- // Policy observations
- void NoteSuccess() override;
- void NoteBool(InlineObservation obs, bool value) override;
- void NoteInt(InlineObservation obs, int value) override;
-
- // Policy determinations
- void DetermineProfitability(CORINFO_METHOD_INFO* methodInfo) override;
-
- // Policy policies
- bool PropagateNeverToRuntime() const override
- {
- return true;
- }
- bool IsLegacyPolicy() const override
- {
- return false;
- }
-
- // Policy estimates
- int CodeSizeEstimate() override
- {
- return 0;
- }
-
- const char* GetName() const override
- {
- return "RandomPolicy";
- }
-
-private:
- // Data members
- Compiler* m_RootCompiler;
- CLRRandom* m_Random;
- unsigned m_CodeSize;
- bool m_IsForceInline : 1;
- bool m_IsForceInlineKnown : 1;
-};
-
-#endif // DEBUG
-
-// DiscretionaryPolicy is a variant of the legacy policy. It differs
-// in that there is no ALWAYS_INLINE class, there is no IL size limit,
-// it does not try and maintain legacy compatabilty, and in prejit mode,
-// discretionary failures do not set the "NEVER" inline bit.
+// DiscretionaryPolicy is a variant of the enhanced legacy policy. It
+// differs in that there is no ALWAYS_INLINE class, there is no IL
+// size limit, it does not try and maintain legacy compatabilty, and
+// in prejit mode, discretionary failures do not set the "NEVER"
+// inline bit.
//
// It is useful for gathering data about inline costs.
-class DiscretionaryPolicy : public LegacyPolicy
+class DiscretionaryPolicy : public EnhancedLegacyPolicy
{
public:
// Construct a DiscretionaryPolicy
@@ -266,10 +218,6 @@ public:
// Policy policies
bool PropagateNeverToRuntime() const override;
- bool IsLegacyPolicy() const override
- {
- return false;
- }
// Policy determinations
void DetermineProfitability(CORINFO_METHOD_INFO* methodInfo) override;
@@ -346,6 +294,7 @@ protected:
bool m_IsSameThis;
bool m_CallerHasNewArray;
bool m_CallerHasNewObj;
+ bool m_CalleeHasGCStruct;
};
// ModelPolicy is an experimental policy that uses the results
@@ -382,6 +331,35 @@ public:
#if defined(DEBUG) || defined(INLINE_DATA)
+// RandomPolicy implements a policy that inlines at random.
+// It is mostly useful for stress testing.
+
+class RandomPolicy : public DiscretionaryPolicy
+{
+public:
+ // Construct a RandomPolicy
+ RandomPolicy(Compiler* compiler, bool isPrejitRoot);
+
+ // Policy observations
+ void NoteInt(InlineObservation obs, int value) override;
+
+ // Policy determinations
+ void DetermineProfitability(CORINFO_METHOD_INFO* methodInfo) override;
+
+ const char* GetName() const override
+ {
+ return "RandomPolicy";
+ }
+
+private:
+ // Data members
+ CLRRandom* m_Random;
+};
+
+#endif // defined(DEBUG) || defined(INLINE_DATA)
+
+#if defined(DEBUG) || defined(INLINE_DATA)
+
// FullPolicy is an experimental policy that will always inline if
// possible, subject to externally settable depth and size limits.
//
diff --git a/src/jit/instr.cpp b/src/jit/instr.cpp
index d516e0dea4..edc4483c6b 100644
--- a/src/jit/instr.cpp
+++ b/src/jit/instr.cpp
@@ -149,8 +149,6 @@ const char* CodeGen::genSizeStr(emitAttr attr)
nullptr,
"xmmword ptr ",
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
- nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
- nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
"ymmword ptr"
};
@@ -3054,7 +3052,7 @@ bool CodeGenInterface::validImmForBL(ssize_t addr)
return
// If we are running the altjit for NGEN, then assume we can use the "BL" instruction.
// This matches the usual behavior for NGEN, since we normally do generate "BL".
- (!compiler->info.compMatchedVM && (compiler->opts.eeFlags & CORJIT_FLG_PREJIT)) ||
+ (!compiler->info.compMatchedVM && compiler->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT)) ||
(compiler->eeGetRelocTypeHint((void*)addr) == IMAGE_REL_BASED_THUMB_BRANCH24);
}
bool CodeGen::arm_Valid_Imm_For_BL(ssize_t addr)
@@ -3240,7 +3238,7 @@ instruction CodeGen::ins_Move_Extend(var_types srcType, bool srcInReg)
*
* Parameters
* srcType - source type
- * aligned - whether source is 16-byte aligned if srcType is a SIMD type
+ * aligned - whether source is properly aligned if srcType is a SIMD type
*/
instruction CodeGenInterface::ins_Load(var_types srcType, bool aligned /*=false*/)
{
@@ -3258,8 +3256,7 @@ instruction CodeGenInterface::ins_Load(var_types srcType, bool aligned /*=false*
#endif // FEATURE_SIMD
if (compiler->canUseAVX())
{
- // TODO-CQ: consider alignment of AVX vectors.
- return INS_movupd;
+ return (aligned) ? INS_movapd : INS_movupd;
}
else
{
@@ -3404,7 +3401,7 @@ instruction CodeGen::ins_Copy(var_types dstType)
*
* Parameters
* dstType - destination type
- * aligned - whether destination is 16-byte aligned if dstType is a SIMD type
+ * aligned - whether destination is properly aligned if dstType is a SIMD type
*/
instruction CodeGenInterface::ins_Store(var_types dstType, bool aligned /*=false*/)
{
@@ -3422,8 +3419,7 @@ instruction CodeGenInterface::ins_Store(var_types dstType, bool aligned /*=false
#endif // FEATURE_SIMD
if (compiler->canUseAVX())
{
- // TODO-CQ: consider alignment of AVX vectors.
- return INS_movupd;
+ return (aligned) ? INS_movapd : INS_movupd;
}
else
{
diff --git a/src/jit/instr.h b/src/jit/instr.h
index c38f8d2073..2d50234fdc 100644
--- a/src/jit/instr.h
+++ b/src/jit/instr.h
@@ -284,15 +284,19 @@ END_DECLARE_TYPED_ENUM(emitAttr,unsigned)
#define EmitSize(x) (EA_ATTR(genTypeSize(TypeGet(x))))
// Enum specifying the instruction set for generating floating point or SIMD code.
+// These enums are ordered such that each one is inclusive of previous instruction sets
+// and the VM ensures this as well when setting the CONFIG flags.
enum InstructionSet
{
#ifdef _TARGET_XARCH_
- InstructionSet_SSE2,
- InstructionSet_AVX,
+ InstructionSet_SSE2, // SSE2 Instruction set
+ InstructionSet_SSE3_4, // SSE3, SSSE3, SSE4.1 and SSE4.2 instruction set
+ InstructionSet_AVX, // AVX2 instruction set
+ // TODO-Cleaup - This should be named as InstructionSet_AVX2
#elif defined(_TARGET_ARM_)
InstructionSet_NEON,
#endif
- InstructionSet_NONE
+ InstructionSet_NONE // No instruction set is available indicating an invalid value
};
// clang-format on
diff --git a/src/jit/instrsxarch.h b/src/jit/instrsxarch.h
index 436563babf..4317334bf2 100644
--- a/src/jit/instrsxarch.h
+++ b/src/jit/instrsxarch.h
@@ -178,6 +178,7 @@ INST3(FIRST_SSE2_INSTRUCTION, "FIRST_SSE2_INSTRUCTION", 0, IUM_WR, 0, 0, BAD_CO
// These are the SSE instructions used on x86
INST3( mov_i2xmm, "movd" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, PCKDBL(0x6E)) // Move int reg to a xmm reg. reg1=xmm reg, reg2=int reg
INST3( mov_xmm2i, "movd" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, PCKDBL(0x7E)) // Move xmm reg to an int reg. reg1=xmm reg, reg2=int reg
+INST3( pmovmskb, "pmovmskb" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, PCKDBL(0xD7)) // Move the MSB bits of all bytes in a xmm reg to an int reg
INST3( movq, "movq" , 0, IUM_WR, 0, 0, PCKDBL(0xD6), BAD_CODE, SSEFLT(0x7E))
INST3( movsdsse2, "movsd" , 0, IUM_WR, 0, 0, SSEDBL(0x11), BAD_CODE, SSEDBL(0x10))
@@ -317,6 +318,8 @@ INST3( insertps, "insertps" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SS
INST3( pcmpeqq, "pcmpeqq" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE38(0x29)) // Packed compare 64-bit integers for equality
INST3( pcmpgtq, "pcmpgtq" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE38(0x37)) // Packed compare 64-bit integers for equality
INST3( pmulld, "pmulld" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE38(0x40)) // Packed multiply 32 bit unsigned integers and store lower 32 bits of each result
+INST3( ptest, "ptest" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE38(0x17)) // Packed logical compare
+INST3( phaddd, "phaddd" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE38(0x02)) // Packed horizontal add
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)
@@ -367,25 +370,25 @@ INST2(sar_N , "sar" , 0, IUM_RW, 0, 1, 0x0038C0, 0x0038C0)
INST1(r_movsb, "rep movsb" , 0, IUM_RD, 0, 0, 0x00A4F3)
INST1(r_movsd, "rep movsd" , 0, IUM_RD, 0, 0, 0x00A5F3)
-#ifndef LEGACY_BACKEND
+#if !defined(LEGACY_BACKEND) && defined(_TARGET_AMD64_)
INST1(r_movsq, "rep movsq" , 0, IUM_RD, 0, 0, 0xF3A548)
-#endif // !LEGACY_BACKEND
+#endif // !LEGACY_BACKEND || !defined(_TARGET_AMD64_)
INST1(movsb , "movsb" , 0, IUM_RD, 0, 0, 0x0000A4)
INST1(movsd , "movsd" , 0, IUM_RD, 0, 0, 0x0000A5)
-#ifndef LEGACY_BACKEND
+#if !defined(LEGACY_BACKEND) && defined(_TARGET_AMD64_)
INST1(movsq, "movsq" , 0, IUM_RD, 0, 0, 0x00A548)
-#endif // !LEGACY_BACKEND
+#endif // !LEGACY_BACKEND || !defined(_TARGET_AMD64_)
INST1(r_stosb, "rep stosb" , 0, IUM_RD, 0, 0, 0x00AAF3)
INST1(r_stosd, "rep stosd" , 0, IUM_RD, 0, 0, 0x00ABF3)
-#ifndef LEGACY_BACKEND
+#if !defined(LEGACY_BACKEND) && defined(_TARGET_AMD64_)
INST1(r_stosq, "rep stosq" , 0, IUM_RD, 0, 0, 0xF3AB48)
-#endif // !LEGACY_BACKEND
+#endif // !LEGACY_BACKEND || !defined(_TARGET_AMD64_)
INST1(stosb, "stosb" , 0, IUM_RD, 0, 0, 0x0000AA)
INST1(stosd, "stosd" , 0, IUM_RD, 0, 0, 0x0000AB)
-#ifndef LEGACY_BACKEND
+#if !defined(LEGACY_BACKEND) && defined(_TARGET_AMD64_)
INST1(stosq, "stosq" , 0, IUM_RD, 0, 0, 0x00AB48)
-#endif // !LEGACY_BACKEND
+#endif // !LEGACY_BACKEND || !defined(_TARGET_AMD64_)
INST1(int3 , "int3" , 0, IUM_RD, 0, 0, 0x0000CC)
INST1(nop , "nop" , 0, IUM_RD, 0, 0, 0x000090)
diff --git a/src/jit/jit.h b/src/jit/jit.h
index 7bf5cd4051..220294f825 100644
--- a/src/jit/jit.h
+++ b/src/jit/jit.h
@@ -28,6 +28,7 @@
#ifdef _MSC_VER
// These don't seem useful, so turning them off is no big deal
+#pragma warning(disable : 4065) // "switch statement contains 'default' but no 'case' labels" (happens due to #ifdefs)
#pragma warning(disable : 4510) // can't generate default constructor
#pragma warning(disable : 4511) // can't generate copy constructor
#pragma warning(disable : 4512) // can't generate assignment constructor
@@ -209,6 +210,7 @@
#include "corhdr.h"
#include "corjit.h"
+#include "jitee.h"
#define __OPERATOR_NEW_INLINE 1 // indicate that I will define these
#define __PLACEMENT_NEW_INLINE // don't bring in the global placement new, it is easy to make a mistake
@@ -259,6 +261,15 @@ struct CLRConfig
#define FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY(x)
#endif // defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
+#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING) || (defined(_TARGET_X86_) && !defined(LEGACY_BACKEND))
+#define FEATURE_PUT_STRUCT_ARG_STK 1
+#define PUT_STRUCT_ARG_STK_ONLY_ARG(x) , x
+#define PUT_STRUCT_ARG_STK_ONLY(x) x
+#else // !(defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)|| (defined(_TARGET_X86_) && !defined(LEGACY_BACKEND)))
+#define PUT_STRUCT_ARG_STK_ONLY_ARG(x)
+#define PUT_STRUCT_ARG_STK_ONLY(x)
+#endif // !(defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)|| (defined(_TARGET_X86_) && !defined(LEGACY_BACKEND)))
+
#if defined(UNIX_AMD64_ABI)
#define UNIX_AMD64_ABI_ONLY_ARG(x) , x
#define UNIX_AMD64_ABI_ONLY(x) x
@@ -377,17 +388,6 @@ typedef ptrdiff_t ssize_t;
/*****************************************************************************/
-// Debugging support is ON by default. Can be turned OFF by
-// adding /DDEBUGGING_SUPPORT=0 on the command line.
-
-#ifndef DEBUGGING_SUPPORT
-#define DEBUGGING_SUPPORT
-#elif !DEBUGGING_SUPPORT
-#undef DEBUGGING_SUPPORT
-#endif
-
-/*****************************************************************************/
-
// Late disassembly is OFF by default. Can be turned ON by
// adding /DLATE_DISASM=1 on the command line.
// Always OFF in the non-debug version
@@ -465,6 +465,8 @@ typedef ptrdiff_t ssize_t;
#define MEASURE_NODE_SIZE 0 // Collect stats about GenTree node allocations.
#define MEASURE_PTRTAB_SIZE 0 // Collect stats about GC pointer table allocations.
#define EMITTER_STATS 0 // Collect stats on the emitter.
+#define NODEBASH_STATS 0 // Collect stats on changed gtOper values in GenTree's.
+#define COUNT_AST_OPERS 0 // Display use counts for GenTree operators.
#define VERBOSE_SIZES 0 // Always display GC info sizes. If set, DISPLAY_SIZES must also be set.
#define VERBOSE_VERIFY 0 // Dump additional information when verifying code. Useful to debug verification bugs.
@@ -472,9 +474,30 @@ typedef ptrdiff_t ssize_t;
#ifdef DEBUG
#define MEASURE_MEM_ALLOC 1 // Collect memory allocation stats.
#define LOOP_HOIST_STATS 1 // Collect loop hoisting stats.
+#define TRACK_LSRA_STATS 1 // Collect LSRA stats
#else
#define MEASURE_MEM_ALLOC 0 // You can set this to 1 to get memory stats in retail, as well
#define LOOP_HOIST_STATS 0 // You can set this to 1 to get loop hoist stats in retail, as well
+#define TRACK_LSRA_STATS 0 // You can set this to 1 to get LSRA stats in retail, as well
+#endif
+
+// Timing calls to clr.dll is only available under certain conditions.
+#ifndef FEATURE_JIT_METHOD_PERF
+#define MEASURE_CLRAPI_CALLS 0 // Can't time these calls without METHOD_PERF.
+#endif
+#ifdef DEBUG
+#define MEASURE_CLRAPI_CALLS 0 // No point in measuring DEBUG code.
+#endif
+#if !defined(_HOST_X86_) && !defined(_HOST_AMD64_)
+#define MEASURE_CLRAPI_CALLS 0 // Cycle counters only hooked up on x86/x64.
+#endif
+#if !defined(_MSC_VER) && !defined(__clang__)
+#define MEASURE_CLRAPI_CALLS 0 // Only know how to do this with VC and Clang.
+#endif
+
+// If none of the above set the flag to 0, it's available.
+#ifndef MEASURE_CLRAPI_CALLS
+#define MEASURE_CLRAPI_CALLS 0 // Set to 1 to measure time in ICorJitInfo calls.
#endif
/*****************************************************************************/
@@ -686,7 +709,7 @@ inline size_t unsigned_abs(ssize_t x)
/*****************************************************************************/
-#if CALL_ARG_STATS || COUNT_BASIC_BLOCKS || COUNT_LOOPS || EMITTER_STATS || MEASURE_NODE_SIZE
+#if CALL_ARG_STATS || COUNT_BASIC_BLOCKS || COUNT_LOOPS || EMITTER_STATS || MEASURE_NODE_SIZE || MEASURE_MEM_ALLOC
class Histogram
{
@@ -807,7 +830,7 @@ extern int jitNativeCode(CORINFO_METHOD_HANDLE methodHnd,
CORINFO_METHOD_INFO* methodInfo,
void** methodCodePtr,
ULONG* methodCodeSize,
- CORJIT_FLAGS* compileFlags,
+ JitFlags* compileFlags,
void* inlineInfoPtr);
#ifdef _HOST_64BIT_
diff --git a/src/jit/jit.settings.targets b/src/jit/jit.settings.targets
index 9dbc225843..6c0474a00c 100644
--- a/src/jit/jit.settings.targets
+++ b/src/jit/jit.settings.targets
@@ -86,10 +86,11 @@
<CppCompile Include="..\jitconfig.cpp" />
<CppCompile Include="..\hostallocator.cpp" />
<CppCompile Include="..\objectalloc.cpp" />
- <CppCompile Inlcude="..\sideeffects.cpp" />
+ <CppCompile Include="..\sideeffects.cpp" />
<CppCompile Condition="'$(ClDefines.Contains(`LEGACY_BACKEND`))'=='True'" Include="..\CodeGenLegacy.cpp" />
<CppCompile Condition="'$(ClDefines.Contains(`LEGACY_BACKEND`))'=='False'" Include="..\Lower.cpp" />
<CppCompile Condition="'$(ClDefines.Contains(`LEGACY_BACKEND`))'=='False'" Include="..\LSRA.cpp" />
+ <CppCompile Condition="'$(ClDefines.Contains(`LEGACY_BACKEND`))'=='False'" Include="..\codegenlinear.cpp" />
</ItemGroup>
<ItemGroup Condition="'$(TargetArch)'=='i386'">
<CppCompile Include="..\emitXArch.cpp" />
diff --git a/src/jit/jitconfig.h b/src/jit/jitconfig.h
index d5b4e30796..9186e12982 100644
--- a/src/jit/jitconfig.h
+++ b/src/jit/jitconfig.h
@@ -5,6 +5,8 @@
#ifndef _JITCONFIG_H_
#define _JITCONFIG_H_
+#include "switches.h"
+
struct CORINFO_SIG_INFO;
class ICorJitHost;
diff --git a/src/jit/jitconfigvalues.h b/src/jit/jitconfigvalues.h
index 6579817249..39a2505246 100644
--- a/src/jit/jitconfigvalues.h
+++ b/src/jit/jitconfigvalues.h
@@ -17,10 +17,10 @@ CONFIG_INTEGER(DebugBreakOnVerificationFailure, W("DebugBreakOnVerificationFailu
// verification failure
CONFIG_INTEGER(DiffableDasm, W("JitDiffableDasm"), 0) // Make the disassembly diff-able
CONFIG_INTEGER(DisplayLoopHoistStats, W("JitLoopHoistStats"), 0) // Display JIT loop hoisting statistics
-CONFIG_INTEGER(DisplayMemStats, W("JitMemStats"), 0) // Display JIT memory usage statistics
-CONFIG_INTEGER(DumpJittedMethods, W("DumpJittedMethods"), 0) // Prints all jitted methods to the console
-CONFIG_INTEGER(EnablePCRelAddr, W("JitEnablePCRelAddr"), 1) // Whether absolute addr be encoded as PC-rel offset by
- // RyuJIT where possible
+CONFIG_INTEGER(DisplayLsraStats, W("JitLsraStats"), 0) // Display JIT Linear Scan Register Allocator statistics
+CONFIG_INTEGER(DumpJittedMethods, W("DumpJittedMethods"), 0) // Prints all jitted methods to the console
+CONFIG_INTEGER(EnablePCRelAddr, W("JitEnablePCRelAddr"), 1) // Whether absolute addr be encoded as PC-rel offset by
+ // RyuJIT where possible
CONFIG_INTEGER(InterpreterFallback, W("InterpreterFallback"), 0) // Fallback to the interpreter when the JIT compiler
// fails
CONFIG_INTEGER(JitAssertOnMaxRAPasses, W("JitAssertOnMaxRAPasses"), 0)
@@ -154,10 +154,12 @@ 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(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(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(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
@@ -186,6 +188,10 @@ CONFIG_STRING(NgenDumpIRFormat, W("NgenDumpIRFormat")) // Same as JitD
CONFIG_STRING(NgenDumpIRPhase, W("NgenDumpIRPhase")) // Same as JitDumpIRPhase, but for ngen
#endif // defined(DEBUG)
+#ifdef FEATURE_ENABLE_NO_RANGE_CHECKS
+CONFIG_INTEGER(JitNoRangeChks, W("JitNoRngChks"), 0) // If 1, don't generate range checks
+#endif
+
// AltJitAssertOnNYI should be 0 on targets where JIT is under developement or bring up stage, so as to facilitate
// fallback to main JIT on hitting a NYI.
#if defined(_TARGET_ARM64_) || defined(_TARGET_X86_)
@@ -194,11 +200,17 @@ CONFIG_INTEGER(AltJitAssertOnNYI, W("AltJitAssertOnNYI"), 0) // Controls the Alt
CONFIG_INTEGER(AltJitAssertOnNYI, W("AltJitAssertOnNYI"), 1) // Controls the AltJit behavior of NYI stuff
#endif // defined(_TARGET_ARM64_) || defined(_TARGET_X86_)
+#if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
+CONFIG_INTEGER(EnableSSE3_4, W("EnableSSE3_4"), 1) // Enable SSE3, SSSE3, SSE 4.1 and 4.2 instruction set as default
+#endif
+
#if defined(_TARGET_AMD64_)
-CONFIG_INTEGER(EnableAVX, W("EnableAVX"), 1) // Enable AVX instruction set for wide operations as default
-#else // !defined(_TARGET_AMD64_)
+CONFIG_INTEGER(EnableAVX, W("EnableAVX"), 1) // Enable AVX instruction set for wide operations as default.
+// When both AVX and SSE3_4 are set, we will use the most capable instruction set available
+// which will prefer AVX over SSE3/4.
+#else // !defined(_TARGET_AMD64_)
CONFIG_INTEGER(EnableAVX, W("EnableAVX"), 0) // Enable AVX instruction set for wide operations as default
-#endif // defined(_TARGET_AMD64_)
+#endif // defined(_TARGET_AMD64_)
#if !defined(DEBUG) && !defined(_DEBUG)
CONFIG_INTEGER(JitEnableNoWayAssert, W("JitEnableNoWayAssert"), 0)
@@ -206,9 +218,17 @@ CONFIG_INTEGER(JitEnableNoWayAssert, W("JitEnableNoWayAssert"), 0)
CONFIG_INTEGER(JitEnableNoWayAssert, W("JitEnableNoWayAssert"), 1)
#endif // !defined(DEBUG) && !defined(_DEBUG)
+// 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
+// we take the easy way out and always include the flag, even in release builds
+// (normally MEASURE_MEM_ALLOC is off for release builds but if it's toggled on
+// for release in "jit.h" the flag would be missing for some includers).
+// TODO-Cleanup: need to make 'MEASURE_MEM_ALLOC' well-defined here at all times.
+CONFIG_INTEGER(DisplayMemStats, W("JitMemStats"), 0) // Display JIT memory usage statistics
+
CONFIG_INTEGER(JitAggressiveInlining, W("JitAggressiveInlining"), 0) // Aggressive inlining of all methods
-CONFIG_INTEGER(JitELTHookEnabled, W("JitELTHookEnabled"), 0) // On ARM, setting this will emit Enter/Leave/TailCall
- // callbacks
+CONFIG_INTEGER(JitELTHookEnabled, W("JitELTHookEnabled"), 0) // If 1, emit Enter/Leave/TailCall callbacks
CONFIG_INTEGER(JitInlineSIMDMultiplier, W("JitInlineSIMDMultiplier"), 3)
#if defined(FEATURE_ENABLE_NO_RANGE_CHECKS)
@@ -242,6 +262,8 @@ CONFIG_INTEGER(JitInlineLimit, W("JitInlineLimit"), -1)
CONFIG_INTEGER(JitInlinePolicyDiscretionary, W("JitInlinePolicyDiscretionary"), 0)
CONFIG_INTEGER(JitInlinePolicyFull, W("JitInlinePolicyFull"), 0)
CONFIG_INTEGER(JitInlinePolicySize, W("JitInlinePolicySize"), 0)
+CONFIG_INTEGER(JitInlinePolicyRandom, W("JitInlinePolicyRandom"), 0) // nozero enables; value is the external random
+ // seed
CONFIG_INTEGER(JitInlinePolicyReplay, W("JitInlinePolicyReplay"), 0)
CONFIG_STRING(JitNoInlineRange, W("JitNoInlineRange"))
CONFIG_STRING(JitInlineReplayFile, W("JitInlineReplayFile"))
@@ -250,6 +272,8 @@ CONFIG_STRING(JitInlineReplayFile, W("JitInlineReplayFile"))
CONFIG_INTEGER(JitInlinePolicyLegacy, W("JitInlinePolicyLegacy"), 0)
CONFIG_INTEGER(JitInlinePolicyModel, W("JitInlinePolicyModel"), 0)
+CONFIG_INTEGER(JitEECallTimingInfo, W("JitEECallTimingInfo"), 0)
+
#undef CONFIG_INTEGER
#undef CONFIG_STRING
#undef CONFIG_METHODSET
diff --git a/src/jit/jitee.h b/src/jit/jitee.h
new file mode 100644
index 0000000000..f9bd83f5bb
--- /dev/null
+++ b/src/jit/jitee.h
@@ -0,0 +1,264 @@
+// Licensed to the .NET Foundation under one or more 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 wraps the CORJIT_FLAGS type in the JIT-EE interface (in corjit.h) such that the JIT can
+// build with either the old flags (COR_JIT_EE_VERSION <= 460) or the new flags (COR_JIT_EE_VERSION > 460).
+// It actually is exactly the same as the new definition, and must be kept up-to-date with the new definition.
+// When built against an old JIT-EE interface, the old flags are converted into this structure.
+class JitFlags
+{
+public:
+ // clang-format off
+ enum JitFlag
+ {
+ JIT_FLAG_SPEED_OPT = 0,
+ JIT_FLAG_SIZE_OPT = 1,
+ JIT_FLAG_DEBUG_CODE = 2, // generate "debuggable" code (no code-mangling optimizations)
+ JIT_FLAG_DEBUG_EnC = 3, // We are in Edit-n-Continue mode
+ JIT_FLAG_DEBUG_INFO = 4, // generate line and local-var info
+ JIT_FLAG_MIN_OPT = 5, // disable all jit optimizations (not necesarily debuggable code)
+ JIT_FLAG_GCPOLL_CALLS = 6, // Emit calls to JIT_POLLGC for thread suspension.
+ JIT_FLAG_MCJIT_BACKGROUND = 7, // Calling from multicore JIT background thread, do not call JitComplete
+
+ #if defined(_TARGET_X86_)
+
+ JIT_FLAG_PINVOKE_RESTORE_ESP = 8, // Restore ESP after returning from inlined PInvoke
+ JIT_FLAG_TARGET_P4 = 9,
+ JIT_FLAG_USE_FCOMI = 10, // Generated code may use fcomi(p) instruction
+ JIT_FLAG_USE_CMOV = 11, // Generated code may use cmov instruction
+ JIT_FLAG_USE_SSE2 = 12, // Generated code may use SSE-2 instructions
+
+ #else // !defined(_TARGET_X86_)
+
+ JIT_FLAG_UNUSED1 = 8,
+ JIT_FLAG_UNUSED2 = 9,
+ JIT_FLAG_UNUSED3 = 10,
+ JIT_FLAG_UNUSED4 = 11,
+ JIT_FLAG_UNUSED5 = 12,
+
+ #endif // !defined(_TARGET_X86_)
+
+ #if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
+
+ JIT_FLAG_USE_SSE3_4 = 13,
+ JIT_FLAG_USE_AVX = 14,
+ JIT_FLAG_USE_AVX2 = 15,
+ JIT_FLAG_USE_AVX_512 = 16,
+ JIT_FLAG_FEATURE_SIMD = 17,
+
+ #else // !defined(_TARGET_X86_) && !defined(_TARGET_AMD64_)
+
+ JIT_FLAG_UNUSED6 = 13,
+ JIT_FLAG_UNUSED7 = 14,
+ JIT_FLAG_UNUSED8 = 15,
+ JIT_FLAG_UNUSED9 = 16,
+ JIT_FLAG_UNUSED10 = 17,
+
+ #endif // !defined(_TARGET_X86_) && !defined(_TARGET_AMD64_)
+
+ JIT_FLAG_MAKEFINALCODE = 18, // Use the final code generator, i.e., not the interpreter.
+ JIT_FLAG_READYTORUN = 19, // Use version-resilient code generation
+ JIT_FLAG_PROF_ENTERLEAVE = 20, // Instrument prologues/epilogues
+ JIT_FLAG_PROF_REJIT_NOPS = 21, // Insert NOPs to ensure code is re-jitable
+ JIT_FLAG_PROF_NO_PINVOKE_INLINE = 22, // Disables PInvoke inlining
+ JIT_FLAG_SKIP_VERIFICATION = 23, // (lazy) skip verification - determined without doing a full resolve. See comment below
+ JIT_FLAG_PREJIT = 24, // jit or prejit is the execution engine.
+ JIT_FLAG_RELOC = 25, // Generate relocatable code
+ JIT_FLAG_IMPORT_ONLY = 26, // Only import the function
+ JIT_FLAG_IL_STUB = 27, // method is an IL stub
+ JIT_FLAG_PROCSPLIT = 28, // JIT should separate code into hot and cold sections
+ JIT_FLAG_BBINSTR = 29, // Collect basic block profile information
+ JIT_FLAG_BBOPT = 30, // Optimize method based on profile information
+ JIT_FLAG_FRAMED = 31, // All methods have an EBP frame
+ JIT_FLAG_ALIGN_LOOPS = 32, // add NOPs before loops to align them at 16 byte boundaries
+ JIT_FLAG_PUBLISH_SECRET_PARAM = 33, // JIT must place stub secret param into local 0. (used by IL stubs)
+ JIT_FLAG_GCPOLL_INLINE = 34, // JIT must inline calls to GCPoll when possible
+ JIT_FLAG_SAMPLING_JIT_BACKGROUND = 35, // JIT is being invoked as a result of stack sampling for hot methods in the background
+ 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
+ };
+ // clang-format on
+
+ JitFlags() : m_jitFlags(0)
+ {
+ // empty
+ }
+
+ // Convenience constructor to set exactly one flags.
+ JitFlags(JitFlag flag) : m_jitFlags(0)
+ {
+ Set(flag);
+ }
+
+ void Reset()
+ {
+ m_jitFlags = 0;
+ }
+
+ void Set(JitFlag flag)
+ {
+ m_jitFlags |= 1ULL << (unsigned __int64)flag;
+ }
+
+ void Clear(JitFlag flag)
+ {
+ m_jitFlags &= ~(1ULL << (unsigned __int64)flag);
+ }
+
+ bool IsSet(JitFlag flag) const
+ {
+ return (m_jitFlags & (1ULL << (unsigned __int64)flag)) != 0;
+ }
+
+ void Add(const JitFlags& other)
+ {
+ m_jitFlags |= other.m_jitFlags;
+ }
+
+ void Remove(const JitFlags& other)
+ {
+ m_jitFlags &= ~other.m_jitFlags;
+ }
+
+ bool IsEmpty() const
+ {
+ 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
+ // values defined in this type.
+ m_jitFlags = flags.GetFlagsRaw();
+
+ C_ASSERT(sizeof(m_jitFlags) == sizeof(CORJIT_FLAGS));
+
+#define FLAGS_EQUAL(a, b) C_ASSERT((unsigned)(a) == (unsigned)(b))
+
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_SPEED_OPT, JIT_FLAG_SPEED_OPT);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_SIZE_OPT, JIT_FLAG_SIZE_OPT);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE, JIT_FLAG_DEBUG_CODE);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_EnC, JIT_FLAG_DEBUG_EnC);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_INFO, JIT_FLAG_DEBUG_INFO);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_MIN_OPT, JIT_FLAG_MIN_OPT);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_GCPOLL_CALLS, JIT_FLAG_GCPOLL_CALLS);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_MCJIT_BACKGROUND, JIT_FLAG_MCJIT_BACKGROUND);
+
+#if defined(_TARGET_X86_)
+
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_PINVOKE_RESTORE_ESP, JIT_FLAG_PINVOKE_RESTORE_ESP);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_TARGET_P4, JIT_FLAG_TARGET_P4);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_FCOMI, JIT_FLAG_USE_FCOMI);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_CMOV, JIT_FLAG_USE_CMOV);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE2, JIT_FLAG_USE_SSE2);
+
+#endif
+
+#if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
+
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE3_4, JIT_FLAG_USE_SSE3_4);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_AVX, JIT_FLAG_USE_AVX);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_AVX2, JIT_FLAG_USE_AVX2);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_AVX_512, JIT_FLAG_USE_AVX_512);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_FEATURE_SIMD, JIT_FLAG_FEATURE_SIMD);
+
+#endif
+
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_MAKEFINALCODE, JIT_FLAG_MAKEFINALCODE);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_READYTORUN, JIT_FLAG_READYTORUN);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_PROF_ENTERLEAVE, JIT_FLAG_PROF_ENTERLEAVE);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_PROF_REJIT_NOPS, JIT_FLAG_PROF_REJIT_NOPS);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_PROF_NO_PINVOKE_INLINE, JIT_FLAG_PROF_NO_PINVOKE_INLINE);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION, JIT_FLAG_SKIP_VERIFICATION);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_PREJIT, JIT_FLAG_PREJIT);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_RELOC, JIT_FLAG_RELOC);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY, JIT_FLAG_IMPORT_ONLY);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB, JIT_FLAG_IL_STUB);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_PROCSPLIT, JIT_FLAG_PROCSPLIT);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_BBINSTR, JIT_FLAG_BBINSTR);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_BBOPT, JIT_FLAG_BBOPT);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_FRAMED, JIT_FLAG_FRAMED);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_ALIGN_LOOPS, JIT_FLAG_ALIGN_LOOPS);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_PUBLISH_SECRET_PARAM, JIT_FLAG_PUBLISH_SECRET_PARAM);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_GCPOLL_INLINE, JIT_FLAG_GCPOLL_INLINE);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_SAMPLING_JIT_BACKGROUND, JIT_FLAG_SAMPLING_JIT_BACKGROUND);
+ 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);
+
+#undef FLAGS_EQUAL
+ }
+
+#endif // COR_JIT_EE_VERSION > 460
+
+private:
+ unsigned __int64 m_jitFlags;
+};
diff --git a/src/jit/jiteh.cpp b/src/jit/jiteh.cpp
index b20c2f8a9a..4b3ceaecf6 100644
--- a/src/jit/jiteh.cpp
+++ b/src/jit/jiteh.cpp
@@ -2979,7 +2979,7 @@ void Compiler::dispOutgoingEHClause(unsigned num, const CORINFO_EH_CLAUSE& claus
// Note: the flags field is kind of weird. It should be compared for equality
// to determine the type of clause, even though it looks like a bitfield. In
// Particular, CORINFO_EH_CLAUSE_NONE is zero, so you can "&" to check it.
- // You do need to mask off the bits, though, because COR_ILEXCEPTION_CLAUSE_DUPLICATED
+ // You do need to mask off the bits, though, because CORINFO_EH_CLAUSE_DUPLICATE
// is and'ed in.
const DWORD CORINFO_EH_CLAUSE_TYPE_MASK = 0x7;
switch (clause.Flags & CORINFO_EH_CLAUSE_TYPE_MASK)
@@ -3013,15 +3013,19 @@ void Compiler::dispOutgoingEHClause(unsigned num, const CORINFO_EH_CLAUSE& claus
}
if ((clause.TryOffset == clause.TryLength) && (clause.TryOffset == clause.HandlerOffset) &&
- ((clause.Flags & (COR_ILEXCEPTION_CLAUSE_DUPLICATED | COR_ILEXCEPTION_CLAUSE_FINALLY)) ==
- (COR_ILEXCEPTION_CLAUSE_DUPLICATED | COR_ILEXCEPTION_CLAUSE_FINALLY)))
+ ((clause.Flags & (CORINFO_EH_CLAUSE_DUPLICATE | CORINFO_EH_CLAUSE_FINALLY)) ==
+ (CORINFO_EH_CLAUSE_DUPLICATE | CORINFO_EH_CLAUSE_FINALLY)))
{
printf(" cloned finally");
}
- else if (clause.Flags & COR_ILEXCEPTION_CLAUSE_DUPLICATED)
+ else if (clause.Flags & CORINFO_EH_CLAUSE_DUPLICATE)
{
printf(" duplicated");
}
+ else if (clause.Flags & CORINFO_EH_CLAUSE_SAMETRY)
+ {
+ printf(" same try");
+ }
printf("\n");
}
diff --git a/src/jit/jitgcinfo.h b/src/jit/jitgcinfo.h
index b93ac3376c..3f8d8afe88 100644
--- a/src/jit/jitgcinfo.h
+++ b/src/jit/jitgcinfo.h
@@ -380,6 +380,9 @@ private:
public:
void gcUpdateForRegVarMove(regMaskTP srcMask, regMaskTP dstMask, LclVarDsc* varDsc);
#endif // !LEGACY_BACKEND
+
+private:
+ ReturnKind getReturnKind();
};
inline unsigned char encodeUnsigned(BYTE* dest, unsigned value)
diff --git a/src/jit/lclvars.cpp b/src/jit/lclvars.cpp
index 369c96322d..ea9c573a02 100644
--- a/src/jit/lclvars.cpp
+++ b/src/jit/lclvars.cpp
@@ -385,8 +385,9 @@ void Compiler::lvaInitThisPtr(InitVarDscInfo* varDscInfo)
if (simdBaseType != TYP_UNKNOWN)
{
assert(varTypeIsSIMD(type));
- varDsc->lvSIMDType = true;
- varDsc->lvBaseType = simdBaseType;
+ varDsc->lvSIMDType = true;
+ varDsc->lvBaseType = simdBaseType;
+ varDsc->lvExactSize = genTypeSize(type);
}
}
#endif // FEATURE_SIMD
@@ -1448,12 +1449,16 @@ void Compiler::lvaCanPromoteStructType(CORINFO_CLASS_HANDLE typeHnd,
#if 1 // TODO-Cleanup: Consider removing this entire #if block in the future
- // This method has two callers. The one in Importer.cpp passes sortFields == false
- // and the other passes sortFields == true.
- // This is a workaround that leave the inlining behavior the same and before while still
- // performing extra struct promotions when compiling the method.
- //
+// This method has two callers. The one in Importer.cpp passes sortFields == false
+// and the other passes sortFields == true.
+// This is a workaround that leaves the inlining behavior the same as before while still
+// performing extra struct promotions when compiling the method.
+//
+// The x86 legacy back-end can't handle the more general RyuJIT struct promotion (notably structs
+// with holes), in genPushArgList(), so in that case always check for custom layout.
+#if FEATURE_FIXED_OUT_ARGS || !defined(LEGACY_BACKEND)
if (!sortFields) // the condition "!sortFields" really means "we are inlining"
+#endif
{
treatAsOverlapping = StructHasCustomLayout(typeFlags);
}
@@ -1736,7 +1741,7 @@ void Compiler::lvaPromoteStructVar(unsigned lclNum, lvaStructPromotionInfo* Stru
}
}
-#if !defined(_TARGET_64BIT_)
+#if !defined(LEGACY_BACKEND) && !defined(_TARGET_64BIT_)
//------------------------------------------------------------------------
// lvaPromoteLongVars: "Struct promote" all register candidate longs as if they are structs of two ints.
//
@@ -1752,29 +1757,18 @@ void Compiler::lvaPromoteLongVars()
{
return;
}
+
// The lvaTable might grow as we grab temps. Make a local copy here.
unsigned startLvaCount = lvaCount;
for (unsigned lclNum = 0; lclNum < startLvaCount; lclNum++)
{
LclVarDsc* varDsc = &lvaTable[lclNum];
if (!varTypeIsLong(varDsc) || varDsc->lvDoNotEnregister || varDsc->lvIsMultiRegArgOrRet() ||
- (varDsc->lvRefCnt == 0))
+ (varDsc->lvRefCnt == 0) || varDsc->lvIsStructField || (fgNoStructPromotion && varDsc->lvIsParam))
{
continue;
}
- // Will this work ???
- // We can't have nested promoted structs.
- if (varDsc->lvIsStructField)
- {
- if (lvaGetPromotionType(varDsc->lvParentLcl) != PROMOTION_TYPE_INDEPENDENT)
- {
- continue;
- }
- varDsc->lvIsStructField = false;
- varDsc->lvTracked = false;
- }
-
varDsc->lvFieldCnt = 2;
varDsc->lvFieldLclStart = lvaCount;
varDsc->lvPromoted = true;
@@ -1823,7 +1817,7 @@ void Compiler::lvaPromoteLongVars()
}
#endif // DEBUG
}
-#endif // !_TARGET_64BIT_
+#endif // !defined(LEGACY_BACKEND) && !defined(_TARGET_64BIT_)
/*****************************************************************************
* Given a fldOffset in a promoted struct var, return the index of the local
@@ -1904,6 +1898,10 @@ void Compiler::lvaSetVarDoNotEnregister(unsigned varNum DEBUGARG(DoNotEnregister
JITDUMP("it is a struct\n");
assert(varTypeIsStruct(varDsc));
break;
+ case DNER_IsStructArg:
+ JITDUMP("it is a struct arg\n");
+ assert(varTypeIsStruct(varDsc));
+ break;
case DNER_BlockOp:
JITDUMP("written in a block op\n");
varDsc->lvLclBlockOpAddr = 1;
@@ -2038,7 +2036,7 @@ void Compiler::lvaSetStruct(unsigned varNum, CORINFO_CLASS_HANDLE typeHnd, bool
}
#ifndef _TARGET_64BIT_
- bool fDoubleAlignHint = FALSE;
+ BOOL fDoubleAlignHint = FALSE;
#ifdef _TARGET_X86_
fDoubleAlignHint = TRUE;
#endif
@@ -2697,6 +2695,10 @@ void Compiler::lvaSortByRefCount()
lvaTrackedCount = 0;
lvaTrackedCountInSizeTUnits = 0;
+#ifdef DEBUG
+ VarSetOps::AssignNoCopy(this, lvaTrackedVars, VarSetOps::MakeEmpty(this));
+#endif
+
if (lvaCount == 0)
{
return;
@@ -3386,26 +3388,30 @@ void Compiler::lvaMarkLocalVars()
#endif // !FEATURE_EH_FUNCLETS
-#if FEATURE_EH_FUNCLETS
- if (ehNeedsPSPSym())
+ // PSPSym and LocAllocSPvar are not used by the CoreRT ABI
+ if (!IsTargetAbi(CORINFO_CORERT_ABI))
{
- lvaPSPSym = lvaGrabTempWithImplicitUse(false DEBUGARG("PSPSym"));
- LclVarDsc* lclPSPSym = &lvaTable[lvaPSPSym];
- lclPSPSym->lvType = TYP_I_IMPL;
- }
+#if FEATURE_EH_FUNCLETS
+ if (ehNeedsPSPSym())
+ {
+ lvaPSPSym = lvaGrabTempWithImplicitUse(false DEBUGARG("PSPSym"));
+ LclVarDsc* lclPSPSym = &lvaTable[lvaPSPSym];
+ lclPSPSym->lvType = TYP_I_IMPL;
+ }
#endif // FEATURE_EH_FUNCLETS
- if (compLocallocUsed)
- {
- lvaLocAllocSPvar = lvaGrabTempWithImplicitUse(false DEBUGARG("LocAllocSPvar"));
- LclVarDsc* locAllocSPvar = &lvaTable[lvaLocAllocSPvar];
- locAllocSPvar->lvType = TYP_I_IMPL;
+ // TODO: LocAllocSPvar should be only required by the implicit frame layout expected by the VM on x86.
+ // It should be removed on other platforms once we check there are no other implicit dependencies.
+ if (compLocallocUsed)
+ {
+ lvaLocAllocSPvar = lvaGrabTempWithImplicitUse(false DEBUGARG("LocAllocSPvar"));
+ LclVarDsc* locAllocSPvar = &lvaTable[lvaLocAllocSPvar];
+ locAllocSPvar->lvType = TYP_I_IMPL;
+ }
}
BasicBlock* block;
-#if defined(DEBUGGING_SUPPORT) || defined(DEBUG)
-
#ifndef DEBUG
// Assign slot numbers to all variables.
// If compiler generated local variables, slot numbers will be
@@ -3428,8 +3434,6 @@ void Compiler::lvaMarkLocalVars()
}
}
-#endif // defined(DEBUGGING_SUPPORT) || defined(DEBUG)
-
/* Mark all local variable references */
lvaRefCountingStarted = true;
@@ -4062,12 +4066,11 @@ void Compiler::lvaFixVirtualFrameOffsets()
LclVarDsc* varDsc;
#if FEATURE_EH_FUNCLETS && defined(_TARGET_AMD64_)
- if (ehNeedsPSPSym())
+ if (lvaPSPSym != BAD_VAR_NUM)
{
// We need to fix the offset of the PSPSym so there is no padding between it and the outgoing argument space.
// Without this code, lvaAlignFrame might have put the padding lower than the PSPSym, which would be between
// the PSPSym and the outgoing argument space.
- assert(lvaPSPSym != BAD_VAR_NUM);
varDsc = &lvaTable[lvaPSPSym];
assert(varDsc->lvFramePointerBased); // We always access it RBP-relative.
assert(!varDsc->lvMustInit); // It is never "must init".
@@ -4453,7 +4456,9 @@ int Compiler::lvaAssignVirtualFrameOffsetToArg(unsigned lclNum,
noway_assert(argSize);
if (Target::g_tgtArgOrder == Target::ARG_ORDER_L2R)
+ {
argOffs -= argSize;
+ }
unsigned fieldVarNum = BAD_VAR_NUM;
@@ -4543,7 +4548,9 @@ int Compiler::lvaAssignVirtualFrameOffsetToArg(unsigned lclNum,
}
if (Target::g_tgtArgOrder == Target::ARG_ORDER_R2L && !varDsc->lvIsRegArg)
+ {
argOffs += argSize;
+ }
return argOffs;
}
@@ -4973,13 +4980,12 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
#endif //_TARGET_AMD64_
#if FEATURE_EH_FUNCLETS && defined(_TARGET_ARMARCH_)
- if (ehNeedsPSPSym())
+ if (lvaPSPSym != BAD_VAR_NUM)
{
// On ARM/ARM64, if we need a PSPSym, allocate it first, before anything else, including
// padding (so we can avoid computing the same padding in the funclet
// frame). Note that there is no special padding requirement for the PSPSym.
noway_assert(codeGen->isFramePointerUsed()); // We need an explicit frame pointer
- assert(lvaPSPSym != BAD_VAR_NUM); // We should have created the PSPSym variable
stkOffs = lvaAllocLocalAndSetVirtualOffset(lvaPSPSym, TARGET_POINTER_SIZE, stkOffs);
}
#endif // FEATURE_EH_FUNCLETS && defined(_TARGET_ARMARCH_)
@@ -5033,7 +5039,7 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
stkOffs = lvaAllocLocalAndSetVirtualOffset(lvaSecurityObject, TARGET_POINTER_SIZE, stkOffs);
}
- if (compLocallocUsed)
+ if (lvaLocAllocSPvar != BAD_VAR_NUM)
{
#ifdef JIT32_GCENCODER
noway_assert(codeGen->isFramePointerUsed()); // else offsets of locals of frameless methods will be incorrect
@@ -5278,7 +5284,9 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
// a local variable which will need stack frame space.
//
if (!varDsc->lvIsRegArg)
+ {
continue;
+ }
#ifdef _TARGET_ARM64_
if (info.compIsVarArgs)
@@ -5477,13 +5485,12 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
}
#if FEATURE_EH_FUNCLETS && defined(_TARGET_AMD64_)
- if (ehNeedsPSPSym())
+ if (lvaPSPSym != BAD_VAR_NUM)
{
// On AMD64, if we need a PSPSym, allocate it last, immediately above the outgoing argument
// space. Any padding will be higher on the stack than this
// (including the padding added by lvaAlignFrame()).
noway_assert(codeGen->isFramePointerUsed()); // We need an explicit frame pointer
- assert(lvaPSPSym != BAD_VAR_NUM); // We should have created the PSPSym variable
stkOffs = lvaAllocLocalAndSetVirtualOffset(lvaPSPSym, TARGET_POINTER_SIZE, stkOffs);
}
#endif // FEATURE_EH_FUNCLETS && defined(_TARGET_AMD64_)
diff --git a/src/.gitmirror b/src/jit/legacyjit/.gitmirror
index f507630f94..f507630f94 100644
--- a/src/.gitmirror
+++ b/src/jit/legacyjit/.gitmirror
diff --git a/src/jit/legacyjit/CMakeLists.txt b/src/jit/legacyjit/CMakeLists.txt
new file mode 100644
index 0000000000..73a4600a66
--- /dev/null
+++ b/src/jit/legacyjit/CMakeLists.txt
@@ -0,0 +1,62 @@
+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/jit/lir.cpp b/src/jit/lir.cpp
index 94206def1c..35dd1815ef 100644
--- a/src/jit/lir.cpp
+++ b/src/jit/lir.cpp
@@ -190,12 +190,13 @@ void LIR::Use::ReplaceWith(Compiler* compiler, GenTree* replacement)
assert(IsDummyUse() || m_range->Contains(m_user));
assert(m_range->Contains(replacement));
- GenTree* replacedNode = *m_edge;
-
- *m_edge = replacement;
- if (!IsDummyUse() && m_user->IsCall())
+ if (!IsDummyUse())
+ {
+ m_user->ReplaceOperand(m_edge, replacement);
+ }
+ else
{
- compiler->fgFixupArgTabEntryPtr(m_user, replacedNode, replacement);
+ *m_edge = replacement;
}
}
@@ -256,7 +257,7 @@ unsigned LIR::Use::ReplaceWithLclVar(Compiler* compiler, unsigned blockWeight, u
assert(m_range->Contains(m_user));
assert(m_range->Contains(*m_edge));
- GenTree* node = *m_edge;
+ GenTree* const node = *m_edge;
if (lclNum == BAD_VAR_NUM)
{
@@ -267,9 +268,11 @@ unsigned LIR::Use::ReplaceWithLclVar(Compiler* compiler, unsigned blockWeight, u
compiler->lvaTable[lclNum].incRefCnts(blockWeight, compiler);
compiler->lvaTable[lclNum].incRefCnts(blockWeight, compiler);
- GenTreeLclVar* store = compiler->gtNewTempAssign(lclNum, node)->AsLclVar();
+ GenTreeLclVar* const store = compiler->gtNewTempAssign(lclNum, node)->AsLclVar();
+ assert(store != nullptr);
+ assert(store->gtOp1 == node);
- GenTree* load =
+ GenTree* const load =
new (compiler, GT_LCL_VAR) GenTreeLclVar(store->TypeGet(), store->AsLclVarCommon()->GetLclNum(), BAD_IL_OFFSET);
m_range->InsertAfter(node, store, load);
@@ -678,7 +681,7 @@ void LIR::Range::FinishInsertBefore(GenTree* insertionPoint, GenTree* first, Gen
assert(m_lastNode != nullptr);
assert(m_lastNode->gtNext == nullptr);
m_lastNode->gtNext = first;
- first->gtPrev = m_lastNode;
+ first->gtPrev = m_lastNode;
}
m_lastNode = last;
}
@@ -866,7 +869,7 @@ void LIR::Range::FinishInsertAfter(GenTree* insertionPoint, GenTree* first, GenT
assert(m_firstNode != nullptr);
assert(m_firstNode->gtPrev == nullptr);
m_firstNode->gtPrev = last;
- last->gtNext = m_firstNode;
+ last->gtNext = m_firstNode;
}
m_firstNode = first;
}
@@ -1157,7 +1160,6 @@ void LIR::Range::Delete(Compiler* compiler, BasicBlock* block, ReadOnlyRange&& r
Delete(compiler, block, range.m_firstNode, range.m_lastNode);
}
-
//------------------------------------------------------------------------
// LIR::Range::TryGetUse: Try to find the use for a given node.
//
@@ -1616,22 +1618,21 @@ void LIR::InsertBeforeTerminator(BasicBlock* block, LIR::Range&& range)
#if DEBUG
switch (block->bbJumpKind)
{
- case BBJ_COND:
- assert(insertionPoint->OperGet() == GT_JTRUE);
- break;
+ case BBJ_COND:
+ assert(insertionPoint->OperIsConditionalJump());
+ break;
- case BBJ_SWITCH:
- assert((insertionPoint->OperGet() == GT_SWITCH) || (insertionPoint->OperGet() == GT_SWITCH_TABLE));
- break;
+ case BBJ_SWITCH:
+ assert((insertionPoint->OperGet() == GT_SWITCH) || (insertionPoint->OperGet() == GT_SWITCH_TABLE));
+ break;
- case BBJ_RETURN:
- assert((insertionPoint->OperGet() == GT_RETURN) ||
- (insertionPoint->OperGet() == GT_JMP) ||
- (insertionPoint->OperGet() == GT_CALL));
- break;
+ case BBJ_RETURN:
+ assert((insertionPoint->OperGet() == GT_RETURN) || (insertionPoint->OperGet() == GT_JMP) ||
+ (insertionPoint->OperGet() == GT_CALL));
+ break;
- default:
- unreached();
+ default:
+ unreached();
}
#endif
}
diff --git a/src/jit/liveness.cpp b/src/jit/liveness.cpp
index 19d326303e..423d72b9b2 100644
--- a/src/jit/liveness.cpp
+++ b/src/jit/liveness.cpp
@@ -76,7 +76,6 @@ void Compiler::fgMarkUseDef(GenTreeLclVarCommon* tree, GenTree* asgdLclVar)
if ((lhsLclNum == lclNum) && ((tree->gtFlags & GTF_VAR_DEF) == 0) && (tree != asgdLclVar))
{
/* bingo - we have an x = f(x) case */
- noway_assert(lvaTable[lhsLclNum].lvType != TYP_STRUCT);
asgdLclVar->gtFlags |= GTF_VAR_USEDEF;
rhsUSEDEF = true;
}
@@ -699,10 +698,6 @@ void Compiler::fgPerBlockLocalVarLiveness()
}
}
-/*****************************************************************************/
-#ifdef DEBUGGING_SUPPORT
-/*****************************************************************************/
-
// Helper functions to mark variables live over their entire scope
void Compiler::fgBeginScopeLife(VARSET_TP* inScope, VarScopeDsc* var)
@@ -1113,7 +1108,7 @@ void Compiler::fgExtendDbgLifetimes()
// Create initialization node
if (!block->IsLIR())
{
- GenTree* varNode = gtNewLclvNode(varNum, type);
+ GenTree* varNode = gtNewLclvNode(varNum, type);
GenTree* initNode = gtNewAssignNode(varNode, zero);
// Create a statement for the initializer, sequence it, and append it to the current BB.
@@ -1124,7 +1119,8 @@ void Compiler::fgExtendDbgLifetimes()
}
else
{
- GenTree* store = new (this, GT_STORE_LCL_VAR) GenTreeLclVar(GT_STORE_LCL_VAR, type, varNum, BAD_IL_OFFSET);
+ GenTree* store =
+ new (this, GT_STORE_LCL_VAR) GenTreeLclVar(GT_STORE_LCL_VAR, type, varNum, BAD_IL_OFFSET);
store->gtOp.gtOp1 = zero;
store->gtFlags |= (GTF_VAR_DEF | GTF_ASG);
@@ -1133,7 +1129,7 @@ void Compiler::fgExtendDbgLifetimes()
#if !defined(_TARGET_64BIT_) && !defined(LEGACY_BACKEND)
DecomposeLongs::DecomposeRange(this, blockWeight, initRange);
-#endif
+#endif // !defined(_TARGET_64BIT_) && !defined(LEGACY_BACKEND)
// Naively inserting the initializer at the end of the block may add code after the block's
// terminator, in which case the inserted code will never be executed (and the IR for the
@@ -1184,10 +1180,6 @@ void Compiler::fgExtendDbgLifetimes()
#endif // DEBUG
}
-/*****************************************************************************/
-#endif // DEBUGGING_SUPPORT
-/*****************************************************************************/
-
VARSET_VALRET_TP Compiler::fgGetHandlerLiveVars(BasicBlock* block)
{
noway_assert(block);
@@ -1905,9 +1897,7 @@ VARSET_VALRET_TP Compiler::fgComputeLife(VARSET_VALARG_TP lifeArg,
VARSET_TP VARSET_INIT(this, life, lifeArg); // lifeArg is const ref; copy to allow modification.
VARSET_TP VARSET_INIT(this, keepAliveVars, volatileVars);
-#ifdef DEBUGGING_SUPPORT
VarSetOps::UnionD(this, keepAliveVars, compCurBB->bbScope); // Don't kill vars in scope
-#endif
noway_assert(VarSetOps::Equal(this, VarSetOps::Intersection(this, keepAliveVars, life), keepAliveVars));
noway_assert(compCurStmt->gtOper == GT_STMT);
@@ -1955,9 +1945,7 @@ VARSET_VALRET_TP Compiler::fgComputeLifeLIR(VARSET_VALARG_TP lifeArg, BasicBlock
VARSET_TP VARSET_INIT(this, life, lifeArg); // lifeArg is const ref; copy to allow modification.
VARSET_TP VARSET_INIT(this, keepAliveVars, volatileVars);
-#ifdef DEBUGGING_SUPPORT
VarSetOps::UnionD(this, keepAliveVars, block->bbScope); // Don't kill vars in scope
-#endif
noway_assert(VarSetOps::Equal(this, VarSetOps::Intersection(this, keepAliveVars, life), keepAliveVars));
@@ -1980,9 +1968,9 @@ VARSET_VALRET_TP Compiler::fgComputeLifeLIR(VARSET_VALARG_TP lifeArg, BasicBlock
else if (node->OperIsNonPhiLocal() || node->OperIsLocalAddr())
{
bool isDeadStore = fgComputeLifeLocal(life, keepAliveVars, node, node);
- if (isDeadStore)
+ if (isDeadStore && fgTryRemoveDeadLIRStore(blockRange, node, &next))
{
- fgTryRemoveDeadLIRStore(blockRange, node, &next);
+ fgStmtRemoved = true;
}
}
}
@@ -2018,9 +2006,8 @@ VARSET_VALRET_TP Compiler::fgComputeLife(VARSET_VALARG_TP lifeArg,
GenTreePtr gtColon = NULL;
VARSET_TP VARSET_INIT(this, keepAliveVars, volatileVars);
-#ifdef DEBUGGING_SUPPORT
VarSetOps::UnionD(this, keepAliveVars, compCurBB->bbScope); /* Dont kill vars in scope */
-#endif
+
noway_assert(VarSetOps::Equal(this, VarSetOps::Intersection(this, keepAliveVars, life), keepAliveVars));
noway_assert(compCurStmt->gtOper == GT_STMT);
noway_assert(endNode || (startNode == compCurStmt->gtStmt.gtStmtExpr));
@@ -2548,10 +2535,10 @@ bool Compiler::fgRemoveDeadStore(
switch (asgNode->gtOper)
{
case GT_ASG_ADD:
- asgNode->gtOper = GT_ADD;
+ asgNode->SetOperRaw(GT_ADD);
break;
case GT_ASG_SUB:
- asgNode->gtOper = GT_SUB;
+ asgNode->SetOperRaw(GT_SUB);
break;
default:
// Only add and sub allowed, we don't have ASG_MUL and ASG_DIV for ints, and
@@ -2854,10 +2841,6 @@ void Compiler::fgInterBlockLocalVarLiveness()
fgLiveVarAnalysis();
-//-------------------------------------------------------------------------
-
-#ifdef DEBUGGING_SUPPORT
-
/* For debuggable code, we mark vars as live over their entire
* reported scope, so that it will be visible over the entire scope
*/
@@ -2867,8 +2850,6 @@ void Compiler::fgInterBlockLocalVarLiveness()
fgExtendDbgLifetimes();
}
-#endif // DEBUGGING_SUPPORT
-
/*-------------------------------------------------------------------------
* Variables involved in exception-handlers and finally blocks need
* to be specially marked
diff --git a/src/jit/loopcloning.cpp b/src/jit/loopcloning.cpp
index 8ce015e607..a1ba14292a 100644
--- a/src/jit/loopcloning.cpp
+++ b/src/jit/loopcloning.cpp
@@ -698,7 +698,7 @@ void LoopCloneContext::CondToStmtInBlock(Compiler* comp,
comp->fgInsertStmtAtEnd(block, stmt);
// Remorph.
- comp->fgMorphBlockStmt(block, stmt DEBUGARG("Loop cloning condition"));
+ comp->fgMorphBlockStmt(block, stmt->AsStmt() DEBUGARG("Loop cloning condition"));
}
//--------------------------------------------------------------------------------------------------
diff --git a/src/jit/lower.cpp b/src/jit/lower.cpp
index 09eb9146ac..a6e50b304c 100644
--- a/src/jit/lower.cpp
+++ b/src/jit/lower.cpp
@@ -135,6 +135,15 @@ GenTree* Lowering::LowerNode(GenTree* node)
LowerCall(node);
break;
+ case GT_LT:
+ case GT_LE:
+ case GT_GT:
+ case GT_GE:
+ case GT_EQ:
+ case GT_NE:
+ LowerCompare(node);
+ break;
+
case GT_JMP:
LowerJmpMethod(node);
break;
@@ -169,13 +178,33 @@ GenTree* Lowering::LowerNode(GenTree* node)
// produces a TYP_SIMD16 result
node->gtType = TYP_SIMD16;
}
+
+#ifdef _TARGET_XARCH_
+ if ((node->AsSIMD()->gtSIMDIntrinsicID == SIMDIntrinsicGetItem) && (node->gtGetOp1()->OperGet() == GT_IND))
+ {
+ // If SIMD vector is already in memory, we force its
+ // addr to be evaluated into a reg. This would allow
+ // us to generate [regBase] or [regBase+offset] or
+ // [regBase+sizeOf(SIMD vector baseType)*regIndex]
+ // to access the required SIMD vector element directly
+ // from memory.
+ //
+ // TODO-CQ-XARCH: If addr of GT_IND is GT_LEA, we
+ // might be able update GT_LEA to fold the regIndex
+ // or offset in some cases. Instead with this
+ // approach we always evaluate GT_LEA into a reg.
+ // Ideally, we should be able to lower GetItem intrinsic
+ // into GT_IND(newAddr) where newAddr combines
+ // the addr of SIMD vector with the given index.
+ node->gtOp.gtOp1->gtFlags |= GTF_IND_REQ_ADDR_IN_REG;
+ }
+#endif
break;
case GT_LCL_VAR:
case GT_STORE_LCL_VAR:
if (node->TypeGet() == TYP_SIMD12)
{
-#ifdef _TARGET_64BIT_
// Assumption 1:
// RyuJit backend depends on the assumption that on 64-Bit targets Vector3 size is rounded off
// to TARGET_POINTER_SIZE and hence Vector3 locals on stack can be treated as TYP_SIMD16 for
@@ -198,10 +227,29 @@ GenTree* Lowering::LowerNode(GenTree* node)
// Vector3 return values are returned two return registers and Caller assembles them into a
// single xmm reg. Hence RyuJIT explicitly generates code to clears upper 4-bytes of Vector3
// type args in prolog and Vector3 type return value of a call
+ //
+ // RyuJIT x86 Windows: all non-param Vector3 local vars are allocated as 16 bytes. Vector3 arguments
+ // are pushed as 12 bytes. For return values, a 16-byte local is allocated and the address passed
+ // as a return buffer pointer. The callee doesn't write the high 4 bytes, and we don't need to clear
+ // it either.
+
+ unsigned varNum = node->AsLclVarCommon()->GetLclNum();
+ LclVarDsc* varDsc = &comp->lvaTable[varNum];
+
+#if defined(_TARGET_64BIT_)
+ assert(varDsc->lvSize() == 16);
node->gtType = TYP_SIMD16;
-#else
- NYI("Lowering of TYP_SIMD12 locals");
-#endif // _TARGET_64BIT_
+#else // !_TARGET_64BIT_
+ if (varDsc->lvSize() == 16)
+ {
+ node->gtType = TYP_SIMD16;
+ }
+ else
+ {
+ // The following assert is guaranteed by lvSize().
+ assert(varDsc->lvIsParam);
+ }
+#endif // !_TARGET_64BIT_
}
#endif // FEATURE_SIMD
__fallthrough;
@@ -215,7 +263,7 @@ GenTree* Lowering::LowerNode(GenTree* node)
#if FEATURE_MULTIREG_RET
GenTree* src = node->gtGetOp1();
assert((src->OperGet() == GT_CALL) && src->AsCall()->HasMultiRegRetVal());
-#else // !FEATURE_MULTIREG_RET
+#else // !FEATURE_MULTIREG_RET
assert(!"Unexpected struct local store in Lowering");
#endif // !FEATURE_MULTIREG_RET
}
@@ -680,7 +728,7 @@ void Lowering::ReplaceArgWithPutArgOrCopy(GenTree** argSlot, GenTree* putArgOrCo
// Arguments:
// call - the call whose arg is being rewritten.
// arg - the arg being rewritten.
-// info - the ArgTabEntry information for the argument.
+// info - the fgArgTabEntry information for the argument.
// type - the type of the argument.
//
// Return Value:
@@ -692,11 +740,11 @@ void Lowering::ReplaceArgWithPutArgOrCopy(GenTree** argSlot, GenTree* putArgOrCo
//
// Notes:
// For System V systems with native struct passing (i.e. FEATURE_UNIX_AMD64_STRUCT_PASSING defined)
-// this method allocates a single GT_PUTARG_REG for 1 eightbyte structs and a GT_LIST of two GT_PUTARG_REGs
+// this method allocates a single GT_PUTARG_REG for 1 eightbyte structs and a GT_FIELD_LIST of two GT_PUTARG_REGs
// for two eightbyte structs.
//
// For STK passed structs the method generates GT_PUTARG_STK tree. For System V systems with native struct passing
-// (i.e. FEATURE_UNIX_AMD64_STRUCT_PASSING defined) this method also sets the GP pointers count and the pointers
+// (i.e. FEATURE_UNIX_AMD64_STRUCT_PASSING defined) this method also sets the GC pointers count and the pointers
// layout object, so the codegen of the GT_PUTARG_STK could use this for optimizing copying to the stack by value.
// (using block copy primitives for non GC pointers and a single TARGET_POINTER_SIZE copy with recording GC info.)
//
@@ -753,8 +801,8 @@ GenTreePtr Lowering::NewPutArg(GenTreeCall* call, GenTreePtr arg, fgArgTabEntryP
// In this case a new tree is created that is GT_PUTARG_REG
// with a op1 the original argument.
// 2. The struct is contained in 2 eightbytes:
- // in this case the arg comes as a GT_LIST of two GT_LCL_FLDs - the two eightbytes of the struct.
- // The code creates a GT_PUTARG_REG node for each GT_LCL_FLD in the GT_LIST
+ // in this case the arg comes as a GT_FIELD_LIST of two GT_LCL_FLDs - the two eightbytes of the struct.
+ // The code creates a GT_PUTARG_REG node for each GT_LCL_FLD in the GT_FIELD_LIST
// and splices it in the list with the corresponding original GT_LCL_FLD tree as op1.
assert(info->structDesc.eightByteCount != 0);
@@ -826,25 +874,25 @@ GenTreePtr Lowering::NewPutArg(GenTreeCall* call, GenTreePtr arg, fgArgTabEntryP
//
// clang-format on
- assert(arg->OperGet() == GT_LIST);
+ assert(arg->OperGet() == GT_FIELD_LIST);
- GenTreeArgList* argListPtr = arg->AsArgList();
- assert(argListPtr->IsAggregate());
+ GenTreeFieldList* fieldListPtr = arg->AsFieldList();
+ assert(fieldListPtr->IsFieldListHead());
- for (unsigned ctr = 0; argListPtr != nullptr; argListPtr = argListPtr->Rest(), ctr++)
+ for (unsigned ctr = 0; fieldListPtr != nullptr; fieldListPtr = fieldListPtr->Rest(), ctr++)
{
// Create a new GT_PUTARG_REG node with op1 the original GT_LCL_FLD.
GenTreePtr newOper = comp->gtNewOperNode(
GT_PUTARG_REG,
comp->GetTypeFromClassificationAndSizes(info->structDesc.eightByteClassifications[ctr],
info->structDesc.eightByteSizes[ctr]),
- argListPtr->gtOp.gtOp1);
+ fieldListPtr->gtOp.gtOp1);
- // Splice in the new GT_PUTARG_REG node in the GT_LIST
- ReplaceArgWithPutArgOrCopy(&argListPtr->gtOp.gtOp1, newOper);
+ // Splice in the new GT_PUTARG_REG node in the GT_FIELD_LIST
+ ReplaceArgWithPutArgOrCopy(&fieldListPtr->gtOp.gtOp1, newOper);
}
- // Just return arg. The GT_LIST is not replaced.
+ // Just return arg. The GT_FIELD_LIST is not replaced.
// Nothing more to do.
return arg;
}
@@ -857,26 +905,26 @@ GenTreePtr Lowering::NewPutArg(GenTreeCall* call, GenTreePtr arg, fgArgTabEntryP
else
#else // not defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
#if FEATURE_MULTIREG_ARGS
- if ((info->numRegs > 1) && (arg->OperGet() == GT_LIST))
+ if ((info->numRegs > 1) && (arg->OperGet() == GT_FIELD_LIST))
{
- assert(arg->OperGet() == GT_LIST);
+ assert(arg->OperGet() == GT_FIELD_LIST);
- GenTreeArgList* argListPtr = arg->AsArgList();
- assert(argListPtr->IsAggregate());
+ GenTreeFieldList* fieldListPtr = arg->AsFieldList();
+ assert(fieldListPtr->IsFieldListHead());
- for (unsigned ctr = 0; argListPtr != nullptr; argListPtr = argListPtr->Rest(), ctr++)
+ for (unsigned ctr = 0; fieldListPtr != nullptr; fieldListPtr = fieldListPtr->Rest(), ctr++)
{
- GenTreePtr curOp = argListPtr->gtOp.gtOp1;
+ GenTreePtr curOp = fieldListPtr->gtOp.gtOp1;
var_types curTyp = curOp->TypeGet();
// Create a new GT_PUTARG_REG node with op1
GenTreePtr newOper = comp->gtNewOperNode(GT_PUTARG_REG, curTyp, curOp);
- // Splice in the new GT_PUTARG_REG node in the GT_LIST
- ReplaceArgWithPutArgOrCopy(&argListPtr->gtOp.gtOp1, newOper);
+ // Splice in the new GT_PUTARG_REG node in the GT_FIELD_LIST
+ ReplaceArgWithPutArgOrCopy(&fieldListPtr->gtOp.gtOp1, newOper);
}
- // Just return arg. The GT_LIST is not replaced.
+ // Just return arg. The GT_FIELD_LIST is not replaced.
// Nothing more to do.
return arg;
}
@@ -893,23 +941,20 @@ 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.
- FEATURE_UNIX_AMD64_STRUCT_PASSING_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 FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(info->numSlots)
- FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(info->isStruct),
+ 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 FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(info->numSlots)
- FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(info->isStruct) DEBUGARG(call));
+ info->slotNum PUT_STRUCT_ARG_STK_ONLY_ARG(info->numSlots) DEBUGARG(call));
#endif
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
+#ifdef FEATURE_PUT_STRUCT_ARG_STK
// If the ArgTabEntry indicates that this arg is a struct
// get and store the number of slots that are references.
// This is later used in the codegen for PUT_ARG_STK implementation
@@ -919,8 +964,6 @@ GenTreePtr Lowering::NewPutArg(GenTreeCall* call, GenTreePtr arg, fgArgTabEntryP
// pair copying using XMM registers or rep mov instructions.
if (info->isStruct)
{
- unsigned numRefs = 0;
- BYTE* gcLayout = new (comp, CMK_Codegen) BYTE[info->numSlots];
// We use GT_OBJ for non-SIMD struct arguments. However, for
// SIMD arguments the GT_OBJ has already been transformed.
if (arg->gtOper != GT_OBJ)
@@ -929,13 +972,14 @@ GenTreePtr Lowering::NewPutArg(GenTreeCall* call, GenTreePtr arg, fgArgTabEntryP
}
else
{
+ unsigned numRefs = 0;
+ BYTE* gcLayout = new (comp, CMK_Codegen) BYTE[info->numSlots];
assert(!varTypeIsSIMD(arg));
numRefs = comp->info.compCompHnd->getClassGClayout(arg->gtObj.gtClass, gcLayout);
+ putArg->AsPutArgStk()->setGcPointers(numRefs, gcLayout);
}
-
- putArg->AsPutArgStk()->setGcPointers(numRefs, gcLayout);
}
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+#endif // FEATURE_PUT_STRUCT_ARG_STK
}
if (arg->InReg())
@@ -1011,6 +1055,22 @@ void Lowering::LowerArg(GenTreeCall* call, GenTreePtr* ppArg)
type = TYP_INT;
}
+#if defined(FEATURE_SIMD) && defined(_TARGET_X86_)
+ // Non-param TYP_SIMD12 local var nodes are massaged in Lower to TYP_SIMD16 to match their
+ // allocated size (see lvSize()). However, when passing the variables as arguments, and
+ // storing the variables to the outgoing argument area on the stack, we must use their
+ // actual TYP_SIMD12 type, so exactly 12 bytes is allocated and written.
+ if (type == TYP_SIMD16)
+ {
+ if ((arg->OperGet() == GT_LCL_VAR) || (arg->OperGet() == GT_STORE_LCL_VAR))
+ {
+ unsigned varNum = arg->AsLclVarCommon()->GetLclNum();
+ LclVarDsc* varDsc = &comp->lvaTable[varNum];
+ type = varDsc->lvType;
+ }
+ }
+#endif // defined(FEATURE_SIMD) && defined(_TARGET_X86_)
+
GenTreePtr putArg;
// If we hit this we are probably double-lowering.
@@ -1068,7 +1128,7 @@ void Lowering::LowerArg(GenTreeCall* call, GenTreePtr* ppArg)
putArg = NewPutArg(call, arg, info, type);
// In the case of register passable struct (in one or two registers)
- // the NewPutArg returns a new node (GT_PUTARG_REG or a GT_LIST with two GT_PUTARG_REGs.)
+ // the NewPutArg returns a new node (GT_PUTARG_REG or a GT_FIELD_LIST with two GT_PUTARG_REGs.)
// If an extra node is returned, splice it in the right place in the tree.
if (arg != putArg)
{
@@ -1367,6 +1427,7 @@ void Lowering::CheckVSQuirkStackPaddingNeeded(GenTreeCall* call)
// Inserts profiler hook, GT_PROF_HOOK for a tail call node.
//
+// AMD64:
// We need to insert this after all nested calls, but before all the arguments to this call have been set up.
// To do this, we look for the first GT_PUTARG_STK or GT_PUTARG_REG, and insert the hook immediately before
// that. If there are no args, then it should be inserted before the call node.
@@ -1391,16 +1452,30 @@ void Lowering::CheckVSQuirkStackPaddingNeeded(GenTreeCall* call)
// In this case, the GT_PUTARG_REG src is a nested call. We need to put the instructions after that call
// (as shown). We assume that of all the GT_PUTARG_*, only the first one can have a nested call.
//
+// X86:
+// Insert the profiler hook immediately before the call. The profiler hook will preserve
+// all argument registers (ECX, EDX), but nothing else.
+//
// Params:
// callNode - tail call node
-// insertionPoint - if caller has an insertion point; If null
-// profiler hook is inserted before args are setup
+// insertionPoint - if non-null, insert the profiler hook before this point.
+// If null, insert the profiler hook before args are setup
// but after all arg side effects are computed.
+//
void Lowering::InsertProfTailCallHook(GenTreeCall* call, GenTree* insertionPoint)
{
assert(call->IsTailCall());
assert(comp->compIsProfilerHookNeeded());
+#if defined(_TARGET_X86_)
+
+ if (insertionPoint == nullptr)
+ {
+ insertionPoint = call;
+ }
+
+#else // !defined(_TARGET_X86_)
+
if (insertionPoint == nullptr)
{
GenTreePtr tmp = nullptr;
@@ -1437,6 +1512,8 @@ void Lowering::InsertProfTailCallHook(GenTreeCall* call, GenTree* insertionPoint
}
}
+#endif // !defined(_TARGET_X86_)
+
assert(insertionPoint != nullptr);
GenTreePtr profHookNode = new (comp, GT_PROF_HOOK) GenTree(GT_PROF_HOOK, TYP_VOID);
BlockRange().InsertBefore(insertionPoint, profHookNode);
@@ -1705,7 +1782,10 @@ GenTree* Lowering::LowerTailCallViaHelper(GenTreeCall* call, GenTree* callTarget
assert(!comp->opts.compNeedSecurityCheck); // tail call from methods that need security check
assert(!call->IsUnmanaged()); // tail calls to unamanaged methods
assert(!comp->compLocallocUsed); // tail call from methods that also do localloc
- assert(!comp->getNeedsGSSecurityCookie()); // jit64 compat: tail calls from methods that need GS check
+
+#ifdef _TARGET_AMD64_
+ assert(!comp->getNeedsGSSecurityCookie()); // jit64 compat: tail calls from methods that need GS check
+#endif // _TARGET_AMD64_
// We expect to see a call that meets the following conditions
assert(call->IsTailCallViaHelper());
@@ -1713,8 +1793,9 @@ GenTree* Lowering::LowerTailCallViaHelper(GenTreeCall* call, GenTree* callTarget
// The TailCall helper call never returns to the caller and is not GC interruptible.
// Therefore the block containing the tail call should be a GC safe point to avoid
- // GC starvation.
- assert(comp->compCurBB->bbFlags & BBF_GC_SAFE_POINT);
+ // GC starvation. It is legal for the block to be unmarked iff the entry block is a
+ // GC safe point, as the entry block trivially dominates every reachable block.
+ assert((comp->compCurBB->bbFlags & BBF_GC_SAFE_POINT) || (comp->fgFirstBB->bbFlags & BBF_GC_SAFE_POINT));
// If PInvokes are in-lined, we have to remember to execute PInvoke method epilog anywhere that
// a method returns. This is a case of caller method has both PInvokes and tail calls.
@@ -1839,16 +1920,268 @@ GenTree* Lowering::LowerTailCallViaHelper(GenTreeCall* call, GenTree* callTarget
// Now add back tail call flags for identifying this node as tail call dispatched via helper.
call->gtCallMoreFlags |= GTF_CALL_M_TAILCALL | GTF_CALL_M_TAILCALL_VIA_HELPER;
+#ifdef PROFILING_SUPPORTED
// Insert profiler tail call hook if needed.
// Since we don't know the insertion point, pass null for second param.
if (comp->compIsProfilerHookNeeded())
{
InsertProfTailCallHook(call, nullptr);
}
+#endif // PROFILING_SUPPORTED
+
+ assert(call->IsTailCallViaHelper());
return result;
}
+//------------------------------------------------------------------------
+// Lowering::LowerCompare: lowers a compare node.
+//
+// For 64-bit targets, this doesn't do much of anything: all comparisons
+// that we support can be handled in code generation on such targets.
+//
+// For 32-bit targets, however, any comparison that feeds a `GT_JTRUE`
+// node must be lowered such that the liveness of the operands to the
+// comparison is properly visible to the rest of the backend. As such,
+// a 64-bit comparison is lowered from something like this:
+//
+// ------------ BB02 [004..014) -> BB02 (cond), preds={BB02,BB01} succs={BB03,BB02}
+// N001 ( 1, 1) [000006] ------------ t6 = lclVar int V02 loc0 u:5 $148
+//
+// /--* t6 int
+// N002 ( 2, 3) [000007] ---------U-- t7 = * cast long <- ulong <- uint $3c0
+//
+// N003 ( 3, 10) [000009] ------------ t9 = lconst long 0x0000000000000003 $101
+//
+// /--* t7 long
+// +--* t9 long
+// N004 ( 9, 17) [000010] N------N-U-- t10 = * < int $149
+//
+// /--* t10 int
+// N005 ( 11, 19) [000011] ------------ * jmpTrue void
+//
+// To something like this:
+//
+// ------------ BB02 [004..014) -> BB03 (cond), preds={BB06,BB07,BB01} succs={BB06,BB03}
+// [000099] ------------ t99 = const int 0
+//
+// [000101] ------------ t101 = const int 0
+//
+// /--* t99 int
+// +--* t101 int
+// N004 ( 9, 17) [000010] N------N-U-- t10 = * > int $149
+//
+// /--* t10 int
+// N005 ( 11, 19) [000011] ------------ * jmpTrue void
+//
+//
+// ------------ BB06 [???..???) -> BB02 (cond), preds={BB02} succs={BB07,BB02}
+// [000105] -------N-U-- jcc void cond=<
+//
+//
+// ------------ BB07 [???..???) -> BB02 (cond), preds={BB06} succs={BB03,BB02}
+// N001 ( 1, 1) [000006] ------------ t6 = lclVar int V02 loc0 u:5 $148
+//
+// N003 ( 3, 10) [000009] ------------ t9 = const int 3
+//
+// /--* t6 int
+// +--* t9 int
+// [000106] N------N-U-- t106 = * < int
+//
+// /--* t106 int
+// [000107] ------------ * jmpTrue void
+//
+// Which will eventually generate code similar to the following:
+//
+// 33DB xor ebx, ebx
+// 85DB test ebx, ebx
+// 7707 ja SHORT G_M50523_IG04
+// 72E7 jb SHORT G_M50523_IG03
+// 83F803 cmp eax, 3
+// 72E2 jb SHORT G_M50523_IG03
+//
+void Lowering::LowerCompare(GenTree* cmp)
+{
+#ifndef _TARGET_64BIT_
+ if (cmp->gtGetOp1()->TypeGet() != TYP_LONG)
+ {
+ return;
+ }
+
+ LIR::Use cmpUse;
+
+ if (!BlockRange().TryGetUse(cmp, &cmpUse) || cmpUse.User()->OperGet() != GT_JTRUE)
+ {
+ return;
+ }
+
+ GenTree* src1 = cmp->gtGetOp1();
+ GenTree* src2 = cmp->gtGetOp2();
+ unsigned weight = m_block->getBBWeight(comp);
+
+ LIR::Use loSrc1(BlockRange(), &(src1->gtOp.gtOp1), src1);
+ LIR::Use loSrc2(BlockRange(), &(src2->gtOp.gtOp1), src2);
+
+ if (loSrc1.Def()->OperGet() != GT_CNS_INT && loSrc1.Def()->OperGet() != GT_LCL_VAR)
+ {
+ loSrc1.ReplaceWithLclVar(comp, weight);
+ }
+
+ if (loSrc2.Def()->OperGet() != GT_CNS_INT && loSrc2.Def()->OperGet() != GT_LCL_VAR)
+ {
+ loSrc2.ReplaceWithLclVar(comp, weight);
+ }
+
+ BasicBlock* jumpDest = m_block->bbJumpDest;
+ BasicBlock* nextDest = m_block->bbNext;
+ BasicBlock* newBlock = comp->fgSplitBlockAtEnd(m_block);
+
+ cmp->gtType = TYP_INT;
+ cmp->gtOp.gtOp1 = src1->gtOp.gtOp2;
+ cmp->gtOp.gtOp2 = src2->gtOp.gtOp2;
+
+ if (cmp->OperGet() == GT_EQ || cmp->OperGet() == GT_NE)
+ {
+ // 64-bit equality comparisons (no matter the polarity) require two 32-bit comparisons: one for the upper 32
+ // bits and one for the lower 32 bits. As such, we update the flow graph like so:
+ //
+ // Before:
+ // BB0: cond
+ // / \
+ // false true
+ // | |
+ // BB1 BB2
+ //
+ // After:
+ // BB0: cond(hi)
+ // / \
+ // false true
+ // | |
+ // | BB3: cond(lo)
+ // | / \
+ // | false true
+ // \ / |
+ // BB1 BB2
+ //
+
+ BlockRange().Remove(loSrc1.Def());
+ BlockRange().Remove(loSrc2.Def());
+ GenTree* loCmp = comp->gtNewOperNode(cmp->OperGet(), TYP_INT, loSrc1.Def(), loSrc2.Def());
+ loCmp->gtFlags = cmp->gtFlags;
+ GenTree* loJtrue = comp->gtNewOperNode(GT_JTRUE, TYP_VOID, loCmp);
+ LIR::AsRange(newBlock).InsertAfter(nullptr, loSrc1.Def(), loSrc2.Def(), loCmp, loJtrue);
+
+ m_block->bbJumpKind = BBJ_COND;
+
+ if (cmp->OperGet() == GT_EQ)
+ {
+ cmp->gtOper = GT_NE;
+ m_block->bbJumpDest = nextDest;
+ nextDest->bbFlags |= BBF_JMP_TARGET;
+ comp->fgAddRefPred(nextDest, m_block);
+ }
+ else
+ {
+ m_block->bbJumpDest = jumpDest;
+ comp->fgAddRefPred(jumpDest, m_block);
+ }
+
+ assert(newBlock->bbJumpKind == BBJ_COND);
+ assert(newBlock->bbJumpDest == jumpDest);
+ }
+ else
+ {
+ // 64-bit ordinal comparisons are more complicated: they require two comparisons for the upper 32 bits and one
+ // comparison for the lower 32 bits. We update the flowgraph as such:
+ //
+ // Before:
+ // BB0: cond
+ // / \
+ // false true
+ // | |
+ // BB1 BB2
+ //
+ // After:
+ // BB0: (!cond(hi) && !eq(hi))
+ // / \
+ // true false
+ // | |
+ // | BB3: (cond(hi) && !eq(hi))
+ // | / \
+ // | false true
+ // | | |
+ // | BB4: cond(lo) |
+ // | / \ |
+ // | false true |
+ // \ / \ /
+ // BB1 BB2
+ //
+ //
+ // Note that the actual comparisons used to implement "(!cond(hi) && !eq(hi))" and "(cond(hi) && !eq(hi))"
+ // differ based on the original condition, and all consist of a single node. The switch statement below
+ // performs the necessary mapping.
+ //
+
+ genTreeOps hiCmpOper;
+ genTreeOps loCmpOper;
+
+ switch (cmp->OperGet())
+ {
+ case GT_LT:
+ cmp->gtOper = GT_GT;
+ hiCmpOper = GT_LT;
+ loCmpOper = GT_LT;
+ break;
+ case GT_LE:
+ cmp->gtOper = GT_GT;
+ hiCmpOper = GT_LT;
+ loCmpOper = GT_LE;
+ break;
+ case GT_GT:
+ cmp->gtOper = GT_LT;
+ hiCmpOper = GT_GT;
+ loCmpOper = GT_GT;
+ break;
+ case GT_GE:
+ cmp->gtOper = GT_LT;
+ hiCmpOper = GT_GT;
+ loCmpOper = GT_GE;
+ break;
+ default:
+ unreached();
+ }
+
+ BasicBlock* newBlock2 = comp->fgSplitBlockAtEnd(newBlock);
+
+ GenTree* hiJcc = new (comp, GT_JCC) GenTreeJumpCC(hiCmpOper);
+ hiJcc->gtFlags = cmp->gtFlags;
+ LIR::AsRange(newBlock).InsertAfter(nullptr, hiJcc);
+
+ BlockRange().Remove(loSrc1.Def());
+ BlockRange().Remove(loSrc2.Def());
+ GenTree* loCmp = comp->gtNewOperNode(loCmpOper, TYP_INT, loSrc1.Def(), loSrc2.Def());
+ loCmp->gtFlags = cmp->gtFlags | GTF_UNSIGNED;
+ GenTree* loJtrue = comp->gtNewOperNode(GT_JTRUE, TYP_VOID, loCmp);
+ LIR::AsRange(newBlock2).InsertAfter(nullptr, loSrc1.Def(), loSrc2.Def(), loCmp, loJtrue);
+
+ m_block->bbJumpKind = BBJ_COND;
+ m_block->bbJumpDest = nextDest;
+ nextDest->bbFlags |= BBF_JMP_TARGET;
+ comp->fgAddRefPred(nextDest, m_block);
+
+ newBlock->bbJumpKind = BBJ_COND;
+ newBlock->bbJumpDest = jumpDest;
+ comp->fgAddRefPred(jumpDest, newBlock);
+
+ assert(newBlock2->bbJumpKind == BBJ_COND);
+ assert(newBlock2->bbJumpDest == jumpDest);
+ }
+
+ BlockRange().Remove(src1);
+ BlockRange().Remove(src2);
+#endif
+}
+
// Lower "jmp <method>" tail call to insert PInvoke method epilog if required.
void Lowering::LowerJmpMethod(GenTree* jmp)
{
@@ -2334,8 +2667,12 @@ void Lowering::InsertPInvokeMethodProlog()
DISPTREERANGE(firstBlockRange, storeFP);
// --------------------------------------------------------
+ // On 32-bit targets, CORINFO_HELP_INIT_PINVOKE_FRAME initializes the PInvoke frame and then pushes it onto
+ // the current thread's Frame stack. On 64-bit targets, it only initializes the PInvoke frame.
+ CLANG_FORMAT_COMMENT_ANCHOR;
- if (comp->opts.eeFlags & CORJIT_FLG_IL_STUB)
+#ifdef _TARGET_64BIT_
+ if (comp->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IL_STUB))
{
// 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
@@ -2343,6 +2680,7 @@ void Lowering::InsertPInvokeMethodProlog()
firstBlockRange.InsertBefore(insertionPoint, LIR::SeqTree(comp, frameUpd));
DISPTREERANGE(firstBlockRange, frameUpd);
}
+#endif // _TARGET_64BIT_
}
//------------------------------------------------------------------------
@@ -2405,9 +2743,14 @@ void Lowering::InsertPInvokeMethodEpilog(BasicBlock* returnBB DEBUGARG(GenTreePt
GenTree* storeGCState = SetGCState(1);
returnBlockRange.InsertBefore(insertionPoint, LIR::SeqTree(comp, storeGCState));
- if (comp->opts.eeFlags & CORJIT_FLG_IL_STUB)
+ // Pop the frame if necessary. This always happens in the epilog on 32-bit targets. For 64-bit targets, we only do
+ // this in the epilog for IL stubs; for non-IL stubs the frame is popped after every PInvoke call.
+ CLANG_FORMAT_COMMENT_ANCHOR;
+
+#ifdef _TARGET_64BIT_
+ if (comp->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IL_STUB))
+#endif // _TARGET_64BIT_
{
- // Pop the frame, in non-stubs we do this around each PInvoke call
GenTree* frameUpd = CreateFrameLinkUpdate(PopFrame);
returnBlockRange.InsertBefore(insertionPoint, LIR::SeqTree(comp, frameUpd));
}
@@ -2454,6 +2797,7 @@ void Lowering::InsertPInvokeCallProlog(GenTreeCall* call)
comp->fgMorphTree(helperCall);
BlockRange().InsertBefore(insertBefore, LIR::SeqTree(comp, helperCall));
+ LowerNode(helperCall); // helper call is inserted before current node and should be lowered here.
return;
}
#endif
@@ -2464,7 +2808,7 @@ void Lowering::InsertPInvokeCallProlog(GenTreeCall* call)
// InlinedCallFrame.m_pCallSiteSP = SP // x86 only
// InlinedCallFrame.m_pCallerReturnAddress = return address
// Thread.gcState = 0
- // (non-stub) - update top Frame on TCB
+ // (non-stub) - update top Frame on TCB // 64-bit targets only
// ----------------------------------------------------------------------------------
// Setup InlinedCallFrame.callSiteTarget (which is how the JIT refers to it).
@@ -2474,11 +2818,19 @@ void Lowering::InsertPInvokeCallProlog(GenTreeCall* call)
if (callType == CT_INDIRECT)
{
+#if !defined(_TARGET_64BIT_)
+ // On 32-bit targets, indirect calls need the size of the stack args in InlinedCallFrame.m_Datum.
+ const unsigned numStkArgBytes = call->fgArgInfo->GetNextSlotNum() * TARGET_POINTER_SIZE;
+
+ src = comp->gtNewIconNode(numStkArgBytes, TYP_INT);
+#else
+ // On 64-bit targets, indirect calls may need the stub parameter value in InlinedCallFrame.m_Datum.
+ // If the stub parameter value is not needed, m_Datum will be initialized by the VM.
if (comp->info.compPublishStubParam)
{
- src = new (comp, GT_LCL_VAR) GenTreeLclVar(TYP_I_IMPL, comp->lvaStubArgumentVar, BAD_IL_OFFSET);
+ src = comp->gtNewLclvNode(comp->lvaStubArgumentVar, TYP_I_IMPL);
}
- // else { If we don't have secret parameter, m_Datum will be initialized by VM code }
+#endif // !defined(_TARGET_64BIT_)
}
else
{
@@ -2542,7 +2894,12 @@ void Lowering::InsertPInvokeCallProlog(GenTreeCall* call)
BlockRange().InsertBefore(insertBefore, LIR::SeqTree(comp, storeLab));
- if (!(comp->opts.eeFlags & CORJIT_FLG_IL_STUB))
+ // Push the PInvoke frame if necessary. On 32-bit targets this only happens in the method prolog if a method
+ // contains PInvokes; on 64-bit targets this is necessary in non-stubs.
+ CLANG_FORMAT_COMMENT_ANCHOR;
+
+#ifdef _TARGET_64BIT_
+ if (!comp->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IL_STUB))
{
// Set the TCB's frame to be the one we just created.
// Note the init routine for the InlinedCallFrame (CORINFO_HELP_INIT_PINVOKE_FRAME)
@@ -2552,6 +2909,7 @@ void Lowering::InsertPInvokeCallProlog(GenTreeCall* call)
GenTree* frameUpd = CreateFrameLinkUpdate(PushFrame);
BlockRange().InsertBefore(insertBefore, LIR::SeqTree(comp, frameUpd));
}
+#endif // _TARGET_64BIT_
// IMPORTANT **** This instruction must come last!!! ****
// It changes the thread's state to Preemptive mode
@@ -2583,7 +2941,7 @@ void Lowering::InsertPInvokeCallEpilog(GenTreeCall* call)
// First argument is the address of the frame variable.
GenTree* frameAddr =
new (comp, GT_LCL_VAR) GenTreeLclVar(GT_LCL_VAR, TYP_BYREF, comp->lvaInlinedPInvokeFrameVar, BAD_IL_OFFSET);
- frameAddr->gtOper = GT_LCL_VAR_ADDR;
+ frameAddr->SetOperRaw(GT_LCL_VAR_ADDR);
// Insert call to CORINFO_HELP_JIT_PINVOKE_END
GenTree* helperCall =
@@ -2604,12 +2962,32 @@ void Lowering::InsertPInvokeCallEpilog(GenTreeCall* call)
tree = CreateReturnTrapSeq();
BlockRange().InsertBefore(insertionPoint, LIR::SeqTree(comp, tree));
- // Pop the frame if necessasry
- if (!(comp->opts.eeFlags & CORJIT_FLG_IL_STUB))
+ // Pop the frame if necessary. On 32-bit targets this only happens in the method epilog; on 64-bit targets thi
+ // happens after every PInvoke call in non-stubs. 32-bit targets instead mark the frame as inactive.
+ CLANG_FORMAT_COMMENT_ANCHOR;
+
+#ifdef _TARGET_64BIT_
+ if (!comp->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IL_STUB))
{
tree = CreateFrameLinkUpdate(PopFrame);
BlockRange().InsertBefore(insertionPoint, LIR::SeqTree(comp, tree));
}
+#else
+ const CORINFO_EE_INFO::InlinedCallFrameInfo& callFrameInfo = comp->eeGetEEInfo()->inlinedCallFrameInfo;
+
+ // ----------------------------------------------------------------------------------
+ // InlinedCallFrame.m_pCallerReturnAddress = nullptr
+
+ GenTreeLclFld* const storeCallSiteTracker =
+ new (comp, GT_STORE_LCL_FLD) GenTreeLclFld(GT_STORE_LCL_FLD, TYP_I_IMPL, comp->lvaInlinedPInvokeFrameVar,
+ callFrameInfo.offsetOfReturnAddress);
+
+ GenTreeIntCon* const constantZero = new (comp, GT_CNS_INT) GenTreeIntCon(TYP_I_IMPL, 0);
+
+ storeCallSiteTracker->gtOp1 = constantZero;
+
+ BlockRange().InsertBefore(insertionPoint, constantZero, storeCallSiteTracker);
+#endif // _TARGET_64BIT_
}
//------------------------------------------------------------------------
@@ -2624,7 +3002,7 @@ void Lowering::InsertPInvokeCallEpilog(GenTreeCall* call)
GenTree* Lowering::LowerNonvirtPinvokeCall(GenTreeCall* call)
{
// PInvoke lowering varies depending on the flags passed in by the EE. By default,
- // GC transitions are generated inline; if CORJIT_FLG2_USE_PINVOKE_HELPERS is specified,
+ // GC transitions are generated inline; if CORJIT_FLAG_USE_PINVOKE_HELPERS is specified,
// GC transitions are instead performed using helper calls. Examples of each case are given
// below. Note that the data structure that is used to store information about a call frame
// containing any P/Invoke calls is initialized in the method prolog (see
@@ -2697,7 +3075,7 @@ GenTree* Lowering::LowerNonvirtPinvokeCall(GenTreeCall* call)
#if COR_JIT_EE_VERSION > 460
comp->info.compCompHnd->getAddressOfPInvokeTarget(methHnd, &lookup);
#else
- void* pIndirection;
+ void* pIndirection;
lookup.accessType = IAT_PVALUE;
lookup.addr = comp->info.compCompHnd->getAddressOfPInvokeFixup(methHnd, &pIndirection);
if (lookup.addr == nullptr)
@@ -2866,14 +3244,10 @@ GenTree* Lowering::LowerVirtualStubCall(GenTreeCall* call)
}
#endif
- // TODO-Cleanup: Disable emitting random NOPs
-
// This is code to set up an indirect call to a stub address computed
// via dictionary lookup.
if (call->gtCallType == CT_INDIRECT)
{
- NYI_X86("Virtual Stub dispatched call lowering via dictionary lookup");
-
// The importer decided we needed a stub call via a computed
// stub dispatch address, i.e. an address which came from a dictionary lookup.
// - The dictionary lookup produces an indirected address, suitable for call
@@ -2886,6 +3260,8 @@ GenTree* Lowering::LowerVirtualStubCall(GenTreeCall* call)
// All we have to do here is add an indirection to generate the actual call target.
GenTree* ind = Ind(call->gtCallAddr);
+ ind->gtFlags |= GTF_IND_REQ_ADDR_IN_REG;
+
BlockRange().InsertAfter(call->gtCallAddr, ind);
call->gtCallAddr = ind;
}
@@ -2923,8 +3299,10 @@ GenTree* Lowering::LowerVirtualStubCall(GenTreeCall* call)
// So we don't use a register.
#ifndef _TARGET_X86_
// on x64 we must materialize the target using specific registers.
- addr->gtRegNum = REG_VIRTUAL_STUB_PARAM;
+ addr->gtRegNum = REG_VIRTUAL_STUB_PARAM;
+
indir->gtRegNum = REG_JUMP_THUNK_PARAM;
+ indir->gtFlags |= GTF_IND_REQ_ADDR_IN_REG;
#endif
result = indir;
}
@@ -3042,8 +3420,6 @@ bool Lowering::AreSourcesPossiblyModifiedLocals(GenTree* addr, GenTree* base, Ge
return true;
}
}
-
- unreached();
}
//------------------------------------------------------------------------
@@ -3082,9 +3458,9 @@ GenTree* Lowering::TryCreateAddrMode(LIR::Use&& use, bool isIndir)
{
// We can have an indirection on the rhs of a block copy (it is the source
// object). This is not a "regular" indirection.
- // (Note that the parent check could be costly.)
- GenTree* parent = indir->gtGetParent(nullptr);
- if ((parent != nullptr) && parent->OperIsIndir())
+ // (Note that the user check could be costly.)
+ LIR::Use indirUse;
+ if (BlockRange().TryGetUse(indir, &indirUse) && indirUse.User()->OperIsIndir())
{
isIndir = false;
}
@@ -3248,9 +3624,14 @@ void Lowering::LowerUnsignedDivOrMod(GenTree* node)
{
assert((node->OperGet() == GT_UDIV) || (node->OperGet() == GT_UMOD));
- GenTree* divisor = node->gtGetOp2();
+ GenTree* divisor = node->gtGetOp2();
+ GenTree* dividend = node->gtGetOp1();
- if (divisor->IsCnsIntOrI())
+ if (divisor->IsCnsIntOrI()
+#ifdef _TARGET_X86_
+ && (dividend->OperGet() != GT_LONG)
+#endif
+ )
{
size_t divisorValue = static_cast<size_t>(divisor->gtIntCon.IconValue());
@@ -3276,6 +3657,91 @@ void Lowering::LowerUnsignedDivOrMod(GenTree* node)
}
//------------------------------------------------------------------------
+// GetSignedMagicNumberForDivide: Generates a magic number and shift amount for
+// the magic number division optimization.
+//
+// Arguments:
+// denom - The denominator
+// shift - Pointer to the shift value to be returned
+//
+// Returns:
+// The magic number.
+//
+// Notes:
+// This code is previously from UTC where it notes it was taken from
+// _The_PowerPC_Compiler_Writer's_Guide_, pages 57-58. The paper is is based on
+// is "Division by invariant integers using multiplication" by Torbjorn Granlund
+// and Peter L. Montgomery in PLDI 94
+
+template <typename T>
+T GetSignedMagicNumberForDivide(T denom, int* shift /*out*/)
+{
+ // static SMAG smag;
+ const int bits = sizeof(T) * 8;
+ const int bits_minus_1 = bits - 1;
+
+ typedef typename jitstd::make_unsigned<T>::type UT;
+
+ const UT two_nminus1 = UT(1) << bits_minus_1;
+
+ int p;
+ UT absDenom;
+ UT absNc;
+ UT delta;
+ UT q1;
+ UT r1;
+ UT r2;
+ UT q2;
+ UT t;
+ T result_magic;
+ int result_shift;
+ int iters = 0;
+
+ absDenom = abs(denom);
+ t = two_nminus1 + ((unsigned int)denom >> 31);
+ absNc = t - 1 - (t % absDenom); // absolute value of nc
+ p = bits_minus_1; // initialize p
+ q1 = two_nminus1 / absNc; // initialize q1 = 2^p / abs(nc)
+ r1 = two_nminus1 - (q1 * absNc); // initialize r1 = rem(2^p, abs(nc))
+ q2 = two_nminus1 / absDenom; // initialize q1 = 2^p / abs(denom)
+ r2 = two_nminus1 - (q2 * absDenom); // initialize r1 = rem(2^p, abs(denom))
+
+ do
+ {
+ iters++;
+ p++;
+ q1 *= 2; // update q1 = 2^p / abs(nc)
+ r1 *= 2; // update r1 = rem(2^p / abs(nc))
+
+ if (r1 >= absNc)
+ { // must be unsigned comparison
+ q1++;
+ r1 -= absNc;
+ }
+
+ q2 *= 2; // update q2 = 2^p / abs(denom)
+ r2 *= 2; // update r2 = rem(2^p / abs(denom))
+
+ if (r2 >= absDenom)
+ { // must be unsigned comparison
+ q2++;
+ r2 -= absDenom;
+ }
+
+ delta = absDenom - r2;
+ } while (q1 < delta || (q1 == delta && r1 == 0));
+
+ result_magic = q2 + 1; // resulting magic number
+ if (denom < 0)
+ {
+ result_magic = -result_magic;
+ }
+ *shift = p - bits; // resulting shift
+
+ return result_magic;
+}
+
+//------------------------------------------------------------------------
// LowerSignedDivOrMod: transform integer GT_DIV/GT_MOD nodes with a power of 2
// const divisor into equivalent but faster sequences.
//
@@ -3313,8 +3779,10 @@ GenTree* Lowering::LowerSignedDivOrMod(GenTreePtr node)
ssize_t divisorValue = divisor->gtIntCon.IconValue();
- if (divisorValue == -1)
+ if (divisorValue == -1 || divisorValue == 0)
{
+ // x / 0 and x % 0 can't be optimized because they are required to throw an exception.
+
// x / -1 can't be optimized because INT_MIN / -1 is required to throw an exception.
// x % -1 is always 0 and the IL spec says that the rem instruction "can" throw an exception if x is
@@ -3343,14 +3811,122 @@ GenTree* Lowering::LowerSignedDivOrMod(GenTreePtr node)
if (!isPow2(absDivisorValue))
{
+#ifdef _TARGET_XARCH_
+ ssize_t magic;
+ int shift;
+
+ if (type == TYP_INT)
+ {
+ magic = GetSignedMagicNumberForDivide<int32_t>(static_cast<int32_t>(divisorValue), &shift);
+ }
+ else
+ {
+#ifdef _TARGET_64BIT_
+ magic = GetSignedMagicNumberForDivide<int64_t>(static_cast<int64_t>(divisorValue), &shift);
+#else
+ unreached();
+#endif
+ }
+
+ divisor->gtIntConCommon.SetIconValue(magic);
+
+ // Insert a new GT_MULHI node in front of the existing GT_DIV/GT_MOD node.
+ // The existing node will later be transformed into a GT_ADD/GT_SUB that
+ // computes the final result. This way don't need to find and change the
+ // use of the existing node.
+ GenTree* mulhi = comp->gtNewOperNode(GT_MULHI, type, divisor, dividend);
+ BlockRange().InsertBefore(divMod, mulhi);
+
+ // mulhi was the easy part. Now we need to generate different code depending
+ // on the divisor value:
+ // For 3 we need:
+ // div = signbit(mulhi) + mulhi
+ // For 5 we need:
+ // div = signbit(mulhi) + sar(mulhi, 1) ; requires shift adjust
+ // For 7 we need:
+ // mulhi += dividend ; requires add adjust
+ // div = signbit(mulhi) + sar(mulhi, 2) ; requires shift adjust
+ // For -3 we need:
+ // mulhi -= dividend ; requires sub adjust
+ // div = signbit(mulhi) + sar(mulhi, 1) ; requires shift adjust
+ bool requiresAddSubAdjust = signum(divisorValue) != signum(magic);
+ bool requiresShiftAdjust = shift != 0;
+ bool requiresDividendMultiuse = requiresAddSubAdjust || !isDiv;
+ unsigned curBBWeight = comp->compCurBB->getBBWeight(comp);
+ unsigned dividendLclNum = BAD_VAR_NUM;
+
+ if (requiresDividendMultiuse)
+ {
+ LIR::Use dividendUse(BlockRange(), &mulhi->gtOp.gtOp2, mulhi);
+ dividendLclNum = dividendUse.ReplaceWithLclVar(comp, curBBWeight);
+ }
+
+ GenTree* adjusted;
+
+ if (requiresAddSubAdjust)
+ {
+ dividend = comp->gtNewLclvNode(dividendLclNum, type);
+ comp->lvaTable[dividendLclNum].incRefCnts(curBBWeight, comp);
+
+ adjusted = comp->gtNewOperNode(divisorValue > 0 ? GT_ADD : GT_SUB, type, mulhi, dividend);
+ BlockRange().InsertBefore(divMod, dividend, adjusted);
+ }
+ else
+ {
+ adjusted = mulhi;
+ }
+
+ GenTree* shiftBy = comp->gtNewIconNode(genTypeSize(type) * 8 - 1, type);
+ GenTree* signBit = comp->gtNewOperNode(GT_RSZ, type, adjusted, shiftBy);
+ BlockRange().InsertBefore(divMod, shiftBy, signBit);
+
+ LIR::Use adjustedUse(BlockRange(), &signBit->gtOp.gtOp1, signBit);
+ unsigned adjustedLclNum = adjustedUse.ReplaceWithLclVar(comp, curBBWeight);
+ adjusted = comp->gtNewLclvNode(adjustedLclNum, type);
+ comp->lvaTable[adjustedLclNum].incRefCnts(curBBWeight, comp);
+ BlockRange().InsertBefore(divMod, adjusted);
+
+ if (requiresShiftAdjust)
+ {
+ shiftBy = comp->gtNewIconNode(shift, TYP_INT);
+ adjusted = comp->gtNewOperNode(GT_RSH, type, adjusted, shiftBy);
+ BlockRange().InsertBefore(divMod, shiftBy, adjusted);
+ }
+
+ if (isDiv)
+ {
+ divMod->SetOperRaw(GT_ADD);
+ divMod->gtOp.gtOp1 = adjusted;
+ divMod->gtOp.gtOp2 = signBit;
+ }
+ else
+ {
+ GenTree* div = comp->gtNewOperNode(GT_ADD, type, adjusted, signBit);
+
+ dividend = comp->gtNewLclvNode(dividendLclNum, type);
+ comp->lvaTable[dividendLclNum].incRefCnts(curBBWeight, comp);
+
+ // divisor % dividend = dividend - divisor x div
+ GenTree* divisor = comp->gtNewIconNode(divisorValue, type);
+ GenTree* mul = comp->gtNewOperNode(GT_MUL, type, div, divisor);
+ BlockRange().InsertBefore(divMod, dividend, div, divisor, mul);
+
+ divMod->SetOperRaw(GT_SUB);
+ divMod->gtOp.gtOp1 = dividend;
+ divMod->gtOp.gtOp2 = mul;
+ }
+
+ return mulhi;
+#else
+ // Currently there's no GT_MULHI for ARM32/64
return next;
+#endif
}
- // We're committed to the conversion now. Go find the use.
+ // We're committed to the conversion now. Go find the use if any.
LIR::Use use;
if (!BlockRange().TryGetUse(node, &use))
{
- assert(!"signed DIV/MOD node is unused");
return next;
}
@@ -3450,8 +4026,6 @@ void Lowering::LowerStoreInd(GenTree* node)
void Lowering::LowerBlockStore(GenTreeBlk* blkNode)
{
GenTree* src = blkNode->Data();
- // TODO-1stClassStructs: Don't require this.
- assert(blkNode->OperIsInitBlkOp() || !src->OperIsLocal());
TryCreateAddrMode(LIR::Use(BlockRange(), &blkNode->Addr(), blkNode), false);
}
@@ -3817,17 +4391,17 @@ void Lowering::CheckCallArg(GenTree* arg)
break;
#endif
- case GT_LIST:
- {
- GenTreeArgList* list = arg->AsArgList();
- assert(list->IsAggregate());
+ case GT_FIELD_LIST:
+ {
+ GenTreeFieldList* list = arg->AsFieldList();
+ assert(list->IsFieldListHead());
- for (; list != nullptr; list = list->Rest())
- {
- assert(list->Current()->OperIsPutArg());
- }
+ for (; list != nullptr; list = list->Rest())
+ {
+ assert(list->Current()->OperIsPutArg());
}
- break;
+ }
+ break;
default:
assert(arg->OperIsPutArg());
diff --git a/src/jit/lower.h b/src/jit/lower.h
index 620636d8bd..c1cafb4ee8 100644
--- a/src/jit/lower.h
+++ b/src/jit/lower.h
@@ -65,6 +65,7 @@ private:
// Call Lowering
// ------------------------------
void LowerCall(GenTree* call);
+ void LowerCompare(GenTree* tree);
void LowerJmpMethod(GenTree* jmp);
void LowerRet(GenTree* ret);
GenTree* LowerDelegateInvoke(GenTreeCall* call);
@@ -127,8 +128,14 @@ private:
// return true if this call target is within range of a pc-rel call on the machine
bool IsCallTargetInRange(void* addr);
+#ifdef _TARGET_X86_
+ bool ExcludeNonByteableRegisters(GenTree* tree);
+#endif
+
void TreeNodeInfoInit(GenTree* stmt);
+ void TreeNodeInfoInitCheckByteable(GenTree* tree);
+
#if defined(_TARGET_XARCH_)
void TreeNodeInfoInitSimple(GenTree* tree);
@@ -190,6 +197,7 @@ private:
void TreeNodeInfoInitReturn(GenTree* tree);
void TreeNodeInfoInitShiftRotate(GenTree* tree);
void TreeNodeInfoInitCall(GenTreeCall* call);
+ void TreeNodeInfoInitCmp(GenTreePtr tree);
void TreeNodeInfoInitStructArg(GenTreePtr structArg);
void TreeNodeInfoInitBlockStore(GenTreeBlk* blkNode);
void TreeNodeInfoInitLogicalOp(GenTree* tree);
@@ -200,11 +208,11 @@ private:
#endif // FEATURE_SIMD
void TreeNodeInfoInitCast(GenTree* tree);
#ifdef _TARGET_ARM64_
- void TreeNodeInfoInitPutArgStk(GenTree* argNode, fgArgTabEntryPtr info);
+ void TreeNodeInfoInitPutArgStk(GenTreePutArgStk* argNode, fgArgTabEntryPtr info);
#endif // _TARGET_ARM64_
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
- void TreeNodeInfoInitPutArgStk(GenTree* tree);
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+#ifdef FEATURE_PUT_STRUCT_ARG_STK
+ void TreeNodeInfoInitPutArgStk(GenTreePutArgStk* tree);
+#endif // FEATURE_PUT_STRUCT_ARG_STK
void TreeNodeInfoInitLclHeap(GenTree* tree);
void DumpNodeInfoMap();
@@ -226,8 +234,6 @@ private:
void SetMulOpCounts(GenTreePtr tree);
#endif // defined(_TARGET_XARCH_)
- void LowerCmp(GenTreePtr tree);
-
#if !CPU_LOAD_STORE_ARCH
bool IsRMWIndirCandidate(GenTree* operand, GenTree* storeInd);
bool IsBinOpInRMWStoreInd(GenTreePtr tree);
diff --git a/src/jit/lowerarm.cpp b/src/jit/lowerarm.cpp
index 67cea2ff4e..5bf23c4199 100644
--- a/src/jit/lowerarm.cpp
+++ b/src/jit/lowerarm.cpp
@@ -32,10 +32,76 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include "lower.h"
#include "lsra.h"
-/* Lowering of GT_CAST nodes */
+//------------------------------------------------------------------------
+// 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)
{
- NYI_ARM("ARM Lowering for cast");
+ 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;
+
+ // TODO-ARM-Cleanup: Remove following NYI assertions.
+ if (varTypeIsFloating(srcType))
+ {
+ NYI_ARM("Lowering for cast from float"); // Not tested yet.
+ 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);
+ }
}
void Lowering::LowerRotate(GenTreePtr tree)
@@ -62,7 +128,73 @@ bool Lowering::IsCallTargetInRange(void* addr)
// return true if the immediate can be folded into an instruction, for example small enough and non-relocatable
bool Lowering::IsContainableImmed(GenTree* parentNode, GenTree* childNode)
{
- NYI_ARM("ARM IsContainableImmed");
+ if (varTypeIsFloating(parentNode->TypeGet()))
+ {
+ // TODO-ARM-Cleanup: not tested yet.
+ NYI_ARM("ARM IsContainableImmed for floating point type");
+
+ // We can contain a floating point 0.0 constant in a compare instruction
+ switch (parentNode->OperGet())
+ {
+ default:
+ return false;
+
+ case GT_EQ:
+ case GT_NE:
+ case GT_LT:
+ case GT_LE:
+ case GT_GE:
+ case GT_GT:
+ if (childNode->IsIntegralConst(0))
+ return true;
+ break;
+ }
+ }
+ else
+ {
+ // Make sure we have an actual immediate
+ if (!childNode->IsCnsIntOrI())
+ return false;
+ if (childNode->IsIconHandle() && comp->opts.compReloc)
+ return false;
+
+ ssize_t immVal = childNode->gtIntCon.gtIconVal;
+ emitAttr attr = emitActualTypeSize(childNode->TypeGet());
+ emitAttr size = EA_SIZE(attr);
+
+ switch (parentNode->OperGet())
+ {
+ default:
+ return false;
+
+ case GT_ADD:
+ case GT_SUB:
+ if (emitter::emitIns_valid_imm_for_add(immVal, INS_FLAGS_DONT_CARE))
+ return true;
+ break;
+
+ case GT_EQ:
+ case GT_NE:
+ case GT_LT:
+ case GT_LE:
+ case GT_GE:
+ case GT_GT:
+ case GT_AND:
+ case GT_OR:
+ case GT_XOR:
+ if (emitter::emitIns_valid_imm_for_alu(immVal))
+ return true;
+ break;
+
+ case GT_STORE_LCL_VAR:
+ // TODO-ARM-Cleanup: not tested yet
+ NYI_ARM("ARM IsContainableImmed for GT_STORE_LCL_VAR");
+ if (immVal == 0)
+ return true;
+ break;
+ }
+ }
+
return false;
}
diff --git a/src/jit/lowerarm64.cpp b/src/jit/lowerarm64.cpp
index 1720c62acb..cc9e2266d2 100644
--- a/src/jit/lowerarm64.cpp
+++ b/src/jit/lowerarm64.cpp
@@ -126,6 +126,10 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
TreeNodeInfo* info = &(tree->gtLsraInfo);
RegisterType registerType = TypeGet(tree);
+ JITDUMP("TreeNodeInfoInit for: ");
+ DISPNODE(tree);
+ JITDUMP("\n");
+
switch (tree->OperGet())
{
GenTree* op1;
@@ -202,6 +206,7 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
__fallthrough;
case GT_LIST:
+ case GT_FIELD_LIST:
case GT_ARGPLACE:
case GT_NO_OP:
case GT_START_NONGC:
@@ -485,7 +490,7 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
case GT_LE:
case GT_GE:
case GT_GT:
- LowerCmp(tree);
+ TreeNodeInfoInitCmp(tree);
break;
case GT_CKFINITE:
@@ -524,12 +529,12 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
break;
case GT_BLK:
- case GT_OBJ:
case GT_DYN_BLK:
// These should all be eliminated prior to Lowering.
assert(!"Non-store block node in Lowering");
info->srcCount = 0;
info->dstCount = 0;
+ break;
case GT_STORE_BLK:
case GT_STORE_OBJ:
@@ -537,6 +542,12 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
TreeNodeInfoInitBlockStore(tree->AsBlk());
break;
+ case GT_INIT_VAL:
+ // Always a passthrough of its child's value.
+ info->srcCount = 0;
+ info->dstCount = 0;
+ break;
+
case GT_LCLHEAP:
{
info->srcCount = 1;
@@ -977,7 +988,7 @@ void Lowering::TreeNodeInfoInitCall(GenTreeCall* call)
for (GenTreePtr list = call->gtCallLateArgs; list; list = list->MoveNext())
{
- assert(list->IsList());
+ assert(list->OperIsList());
GenTreePtr argNode = list->Current();
@@ -989,7 +1000,7 @@ void Lowering::TreeNodeInfoInitCall(GenTreeCall* call)
// late arg that is not passed in a register
assert(argNode->gtOper == GT_PUTARG_STK);
- TreeNodeInfoInitPutArgStk(argNode, curArgTabEntry);
+ TreeNodeInfoInitPutArgStk(argNode->AsPutArgStk(), curArgTabEntry);
continue;
}
@@ -1003,16 +1014,16 @@ void Lowering::TreeNodeInfoInitCall(GenTreeCall* call)
argNode = argNode->gtEffectiveVal();
- // A GT_LIST has a TYP_VOID, but is used to represent a multireg struct
- if (varTypeIsStruct(argNode) || (argNode->gtOper == GT_LIST))
+ // 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_LIST)
+ 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)
- GenTreeArgList* argListPtr = argNode->AsArgList();
+ GenTreeFieldList* fieldListPtr = argNode->AsFieldList();
// Initailize the first register and the first regmask in our list
regNumber targetReg = argReg;
@@ -1020,9 +1031,9 @@ void Lowering::TreeNodeInfoInitCall(GenTreeCall* call)
unsigned iterationNum = 0;
originalSize = 0;
- for (; argListPtr; argListPtr = argListPtr->Rest())
+ for (; fieldListPtr; fieldListPtr = fieldListPtr->Rest())
{
- GenTreePtr putArgRegNode = argListPtr->gtOp.gtOp1;
+ GenTreePtr putArgRegNode = fieldListPtr->Current();
assert(putArgRegNode->gtOper == GT_PUTARG_REG);
GenTreePtr putArgChild = putArgRegNode->gtOp.gtOp1;
@@ -1115,7 +1126,7 @@ void Lowering::TreeNodeInfoInitCall(GenTreeCall* call)
assert(curArgTabEntry->regNum == REG_STK);
- TreeNodeInfoInitPutArgStk(arg, curArgTabEntry);
+ TreeNodeInfoInitPutArgStk(arg->AsPutArgStk(), curArgTabEntry);
}
else
{
@@ -1154,7 +1165,7 @@ void Lowering::TreeNodeInfoInitCall(GenTreeCall* call)
// Notes:
// Set the child node(s) to be contained when we have a multireg arg
//
-void Lowering::TreeNodeInfoInitPutArgStk(GenTree* argNode, fgArgTabEntryPtr info)
+void Lowering::TreeNodeInfoInitPutArgStk(GenTreePutArgStk* argNode, fgArgTabEntryPtr info)
{
assert(argNode->gtOper == GT_PUTARG_STK);
@@ -1166,14 +1177,14 @@ void Lowering::TreeNodeInfoInitPutArgStk(GenTree* argNode, fgArgTabEntryPtr info
argNode->gtLsraInfo.srcCount = 1;
argNode->gtLsraInfo.dstCount = 0;
- // Do we have a TYP_STRUCT argument (or a GT_LIST), if so it must be a multireg pass-by-value struct
- if ((putArgChild->TypeGet() == TYP_STRUCT) || (putArgChild->OperGet() == GT_LIST))
+ // 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_LIST)
+ if (putArgChild->OperGet() == GT_FIELD_LIST)
{
- // We consume all of the items in the GT_LIST
+ // We consume all of the items in the GT_FIELD_LIST
argNode->gtLsraInfo.srcCount = info->numSlots;
}
else
@@ -1219,8 +1230,9 @@ void Lowering::TreeNodeInfoInitPutArgStk(GenTree* argNode, fgArgTabEntryPtr info
void Lowering::TreeNodeInfoInitBlockStore(GenTreeBlk* blkNode)
{
- GenTree* dstAddr = blkNode->Addr();
- unsigned size;
+ GenTree* dstAddr = blkNode->Addr();
+ unsigned size = blkNode->gtBlkSize;
+ GenTree* source = blkNode->Data();
LinearScan* l = m_lsra;
Compiler* compiler = comp;
@@ -1228,16 +1240,44 @@ void Lowering::TreeNodeInfoInitBlockStore(GenTreeBlk* blkNode)
// 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 ((blkNode->OperGet() == GT_STORE_OBJ) && (blkNode->AsObj()->gtGcPtrCount == 0))
+ if (!isInitBlk)
{
- blkNode->SetOper(GT_STORE_BLK);
+ // 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();
+ // 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 (blkNode->OperIsInitBlkOp())
+ if (isInitBlk)
{
- unsigned size = blkNode->gtBlkSize;
- GenTreePtr initVal = blkNode->Data();
+ GenTreePtr initVal = source;
+ if (initVal->OperIsInitVal())
+ {
+ initVal = initVal->gtGetOp1();
+ }
+ srcAddrOrFill = initVal;
#if 0
// TODO-ARM64-CQ: Currently we generate a helper call for every
@@ -1264,8 +1304,6 @@ void Lowering::TreeNodeInfoInitBlockStore(GenTreeBlk* blkNode)
initVal->gtType = TYP_LONG;
}
- MakeSrcContained(tree, blockSize);
-
// In case we have a buffer >= 16 bytes
// we can use SSE2 to do a 128-bit store in a single
// instruction.
@@ -1282,7 +1320,7 @@ void Lowering::TreeNodeInfoInitBlockStore(GenTreeBlk* blkNode)
else
#endif // 0
{
- // The helper follows the regular AMD64 ABI.
+ // The helper follows the regular ABI.
dstAddr->gtLsraInfo.setSrcCandidates(l, RBM_ARG_0);
initVal->gtLsraInfo.setSrcCandidates(l, RBM_ARG_1);
blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindHelper;
@@ -1306,34 +1344,12 @@ void Lowering::TreeNodeInfoInitBlockStore(GenTreeBlk* blkNode)
{
// CopyObj or CopyBlk
// Sources are src and dest and size if not constant.
- unsigned size = blkNode->gtBlkSize;
- GenTreePtr source = blkNode->Data();
- GenTree* srcAddr = nullptr;
- if (source->gtOper == GT_IND)
- {
- srcAddr = 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 (srcAddr->gtLsraInfo.getDstCount() == 0)
- {
- srcAddr->gtLsraInfo.setDstCount(1);
- srcAddr->gtLsraInfo.setSrcCount(source->gtLsraInfo.srcCount);
- }
- m_lsra->clearOperandCounts(source);
- }
- else
- {
- assert(source->IsLocal());
- MakeSrcContained(blkNode, source);
- }
if (blkNode->OperGet() == GT_STORE_OBJ)
{
// CopyObj
GenTreeObj* objNode = blkNode->AsObj();
- GenTreePtr source = objNode->Data();
unsigned slots = objNode->gtSlots;
@@ -1362,16 +1378,19 @@ void Lowering::TreeNodeInfoInitBlockStore(GenTreeBlk* blkNode)
blkNode->gtLsraInfo.internalIntCount = 1;
dstAddr->gtLsraInfo.setSrcCandidates(l, RBM_WRITE_BARRIER_DST_BYREF);
- srcAddr->gtLsraInfo.setSrcCandidates(l, RBM_WRITE_BARRIER_SRC_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
- unsigned size = blkNode->gtBlkSize;
- GenTreePtr dstAddr = blkNode->Addr();
- GenTreePtr srcAddr = blkNode->Data();
- short internalIntCount = 0;
- regMaskTP internalIntCandidates = RBM_NONE;
+ 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
@@ -1379,11 +1398,8 @@ void Lowering::TreeNodeInfoInitBlockStore(GenTreeBlk* blkNode)
// TODO-ARM64-CQ: cpblk loop unrolling is currently not implemented.
- if (blockSize->IsCnsIntOrI() && blockSize->gtIntCon.gtIconVal <= CPBLK_UNROLL_LIMIT)
+ if ((size != 0) && (size <= INITBLK_UNROLL_LIMIT))
{
- assert(!blockSize->IsIconHandle());
- ssize_t size = blockSize->gtIntCon.gtIconVal;
-
// If we have a buffer between XMM_REGSIZE_BYTES and CPBLK_UNROLL_LIMIT bytes, we'll use SSE2.
// Structs and buffer with sizes <= CPBLK_UNROLL_LIMIT bytes are occurring in more than 95% of
// our framework assemblies, so this is the main code generation scheme we'll use.
@@ -1404,9 +1420,9 @@ void Lowering::TreeNodeInfoInitBlockStore(GenTreeBlk* blkNode)
// If src or dst are on stack, we don't have to generate the address into a register
// because it's just some constant+SP
- if (srcAddr->OperIsLocalAddr())
+ if (srcAddr != nullptr && srcAddrOrFill->OperIsLocalAddr())
{
- MakeSrcContained(blkNode, srcAddr);
+ MakeSrcContained(blkNode, srcAddrOrFill);
}
if (dstAddr->OperIsLocalAddr())
@@ -1425,15 +1441,9 @@ void Lowering::TreeNodeInfoInitBlockStore(GenTreeBlk* blkNode)
dstAddr->gtLsraInfo.setSrcCandidates(l, RBM_ARG_0);
// The srcAddr goes in arg1.
- if (srcAddr != nullptr)
+ if (srcAddrOrFill != nullptr)
{
- srcAddr->gtLsraInfo.setSrcCandidates(l, RBM_ARG_1);
- }
- else
- {
- // This is a local; we'll use a temp register for its address.
- internalIntCandidates |= RBM_ARG_1;
- internalIntCount++;
+ srcAddrOrFill->gtLsraInfo.setSrcCandidates(l, RBM_ARG_1);
}
if (size != 0)
{
@@ -1447,7 +1457,6 @@ void Lowering::TreeNodeInfoInitBlockStore(GenTreeBlk* blkNode)
noway_assert(blkNode->gtOper == GT_STORE_DYN_BLK);
blkNode->gtLsraInfo.setSrcCount(3);
GenTree* blockSize = blkNode->AsDynBlk()->gtDynamicSize;
- assert(!blockSize->IsIconHandle());
blockSize->gtLsraInfo.setSrcCandidates(l, RBM_ARG_2);
}
blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindHelper;
@@ -1860,7 +1869,7 @@ void Lowering::SetIndirAddrOpCounts(GenTreePtr indirTree)
}
}
-void Lowering::LowerCmp(GenTreePtr tree)
+void Lowering::TreeNodeInfoInitCmp(GenTreePtr tree)
{
TreeNodeInfo* info = &(tree->gtLsraInfo);
diff --git a/src/jit/lowerxarch.cpp b/src/jit/lowerxarch.cpp
index 6f98eb6661..589cef482e 100644
--- a/src/jit/lowerxarch.cpp
+++ b/src/jit/lowerxarch.cpp
@@ -77,7 +77,7 @@ void Lowering::LowerStoreLoc(GenTreeLclVarCommon* storeLoc)
// InitBlk
MakeSrcContained(storeLoc, op1);
}
- else if (storeLoc->TypeGet() == TYP_SIMD12)
+ else if ((storeLoc->TypeGet() == TYP_SIMD12) && (storeLoc->OperGet() == GT_STORE_LCL_FLD))
{
// Need an additional register to extract upper 4 bytes of Vector3.
info->internalFloatCount = 1;
@@ -177,6 +177,7 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
break;
case GT_LCL_FLD:
+ case GT_LCL_VAR:
info->srcCount = 0;
info->dstCount = 1;
@@ -185,9 +186,9 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
if (tree->TypeGet() == TYP_SIMD12)
{
// We need an internal register different from targetReg in which 'tree' produces its result
- // because both targetReg and internal reg will be in use at the same time. This is achieved
- // by asking for two internal registers.
- info->internalFloatCount = 2;
+ // because both targetReg and internal reg will be in use at the same time.
+ info->internalFloatCount = 1;
+ info->isInternalRegDelayFree = true;
info->setInternalCandidates(m_lsra, m_lsra->allSIMDRegs());
}
#endif
@@ -195,7 +196,16 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
case GT_STORE_LCL_FLD:
case GT_STORE_LCL_VAR:
- info->srcCount = 1;
+#ifdef _TARGET_X86_
+ if (tree->gtGetOp1()->OperGet() == GT_LONG)
+ {
+ info->srcCount = 2;
+ }
+ else
+#endif // _TARGET_X86_
+ {
+ info->srcCount = 1;
+ }
info->dstCount = 0;
LowerStoreLoc(tree->AsLclVarCommon());
break;
@@ -242,6 +252,7 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
break;
case GT_LIST:
+ case GT_FIELD_LIST:
case GT_ARGPLACE:
case GT_NO_OP:
case GT_START_NONGC:
@@ -319,9 +330,87 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
break;
case GT_JTRUE:
+ {
+ info->srcCount = 0;
+ info->dstCount = 0;
+
+ GenTree* cmp = tree->gtGetOp1();
+ l->clearDstCount(cmp);
+
+#ifdef FEATURE_SIMD
+ // Say we have the following IR
+ // simdCompareResult = GT_SIMD((In)Equality, v1, v2)
+ // integerCompareResult = GT_EQ/NE(simdCompareResult, true/false)
+ // GT_JTRUE(integerCompareResult)
+ //
+ // In this case we don't need to generate code for GT_EQ_/NE, since SIMD (In)Equality
+ // intrinsic would set or clear Zero flag.
+
+ genTreeOps cmpOper = cmp->OperGet();
+ if (cmpOper == GT_EQ || cmpOper == GT_NE)
+ {
+ GenTree* cmpOp1 = cmp->gtGetOp1();
+ GenTree* cmpOp2 = cmp->gtGetOp2();
+
+ if (cmpOp1->IsSIMDEqualityOrInequality() && (cmpOp2->IsIntegralConst(0) || cmpOp2->IsIntegralConst(1)))
+ {
+ // clear dstCount on SIMD node to indicate that
+ // result doesn't need to be materialized into a register.
+ l->clearOperandCounts(cmp);
+ l->clearDstCount(cmpOp1);
+ l->clearOperandCounts(cmpOp2);
+
+ // Codegen of SIMD (in)Equality uses target integer reg
+ // only for setting flags. Target reg is not needed on AVX
+ // when comparing against Vector Zero. In all other cases
+ // we need to reserve an int type internal register, since we
+ // have cleared dstCount.
+ if (compiler->canUseAVX() && cmpOp1->gtGetOp2()->IsIntegralConstVector(0))
+ {
+ // We don't need an internal register,since we use vptest
+ // for setting flags.
+ }
+ else
+ {
+ ++(cmpOp1->gtLsraInfo.internalIntCount);
+ regMaskTP internalCandidates = cmpOp1->gtLsraInfo.getInternalCandidates(l);
+ internalCandidates |= l->allRegs(TYP_INT);
+ cmpOp1->gtLsraInfo.setInternalCandidates(l, internalCandidates);
+ }
+
+ // We would have to reverse compare oper in the following cases:
+ // 1) SIMD Equality: Sets Zero flag on equal otherwise clears it.
+ // Therefore, if compare oper is == or != against false(0), we will
+ // be checking opposite of what is required.
+ //
+ // 2) SIMD inEquality: Clears Zero flag on true otherwise sets it.
+ // Therefore, if compare oper is == or != against true(1), we will
+ // be checking opposite of what is required.
+ GenTreeSIMD* simdNode = cmpOp1->AsSIMD();
+ if (simdNode->gtSIMDIntrinsicID == SIMDIntrinsicOpEquality)
+ {
+ if (cmpOp2->IsIntegralConst(0))
+ {
+ cmp->SetOper(GenTree::ReverseRelop(cmpOper));
+ }
+ }
+ else
+ {
+ assert(simdNode->gtSIMDIntrinsicID == SIMDIntrinsicOpInEquality);
+ if (cmpOp2->IsIntegralConst(1))
+ {
+ cmp->SetOper(GenTree::ReverseRelop(cmpOper));
+ }
+ }
+ }
+ }
+#endif // FEATURE_SIMD
+ }
+ break;
+
+ case GT_JCC:
info->srcCount = 0;
info->dstCount = 0;
- l->clearDstCount(tree->gtOp.gtOp1);
break;
case GT_JMP:
@@ -436,6 +525,9 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
case GT_MUL:
case GT_MULHI:
+#if defined(_TARGET_X86_) && !defined(LEGACY_BACKEND)
+ case GT_MUL_LONG:
+#endif
SetMulOpCounts(tree);
break;
@@ -478,6 +570,11 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
info->internalFloatCount = 1;
info->setInternalCandidates(l, l->internalFloatRegCandidates());
}
+ else
+ {
+ // Codegen of this tree node sets ZF and SF flags.
+ tree->gtFlags |= GTF_ZSF_SET;
+ }
break;
case GT_NOT:
@@ -490,6 +587,10 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
case GT_RSZ:
case GT_ROL:
case GT_ROR:
+#ifdef _TARGET_X86_
+ case GT_LSH_HI:
+ case GT_RSH_LO:
+#endif
TreeNodeInfoInitShiftRotate(tree);
break;
@@ -499,7 +600,7 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
case GT_LE:
case GT_GE:
case GT_GT:
- LowerCmp(tree);
+ TreeNodeInfoInitCmp(tree);
break;
case GT_CKFINITE:
@@ -542,10 +643,7 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
}
break;
-#ifdef _TARGET_X86_
- case GT_OBJ:
- NYI_X86("GT_OBJ");
-#elif !defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
+#if !defined(FEATURE_PUT_STRUCT_ARG_STK)
case GT_OBJ:
#endif
case GT_BLK:
@@ -556,11 +654,11 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
info->dstCount = 0;
break;
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
+#ifdef FEATURE_PUT_STRUCT_ARG_STK
case GT_PUTARG_STK:
- TreeNodeInfoInitPutArgStk(tree);
+ TreeNodeInfoInitPutArgStk(tree->AsPutArgStk());
break;
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+#endif // FEATURE_PUT_STRUCT_ARG_STK
case GT_STORE_BLK:
case GT_STORE_OBJ:
@@ -568,6 +666,12 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
TreeNodeInfoInitBlockStore(tree->AsBlk());
break;
+ case GT_INIT_VAL:
+ // Always a passthrough of its child's value.
+ info->srcCount = 0;
+ info->dstCount = 0;
+ break;
+
case GT_LCLHEAP:
TreeNodeInfoInitLclHeap(tree);
break;
@@ -634,14 +738,20 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
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;
+ info->srcCount = 3;
+ info->dstCount = 1;
+
// we don't want to generate code for this
if (tree->gtArrOffs.gtOffset->IsIntegralConst(0))
{
MakeSrcContained(tree, tree->gtArrOffs.gtOffset);
}
+ else
+ {
+ // Here we simply need an internal register, which must be different
+ // from any of the operand's registers, but may be the same as targetReg.
+ info->internalIntCount = 1;
+ }
break;
case GT_LEA:
@@ -725,15 +835,9 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
#endif
case GT_CLS_VAR:
- info->srcCount = 0;
- // GT_CLS_VAR, by the time we reach the backend, must always
- // be a pure use.
- // It will produce a result of the type of the
- // node, and use an internal register for the address.
-
- info->dstCount = 1;
- assert((tree->gtFlags & (GTF_VAR_DEF | GTF_VAR_USEASG | GTF_VAR_USEDEF)) == 0);
- info->internalIntCount = 1;
+ // These nodes are eliminated by rationalizer.
+ JITDUMP("Unexpected node %s in Lower.\n", GenTree::NodeName(tree->OperGet()));
+ unreached();
break;
} // end switch (tree->OperGet())
@@ -813,27 +917,36 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
}
}
+ TreeNodeInfoInitCheckByteable(tree);
+
+ // We need to be sure that we've set info->srcCount and info->dstCount appropriately
+ assert((info->dstCount < 2) || (tree->IsMultiRegCall() && info->dstCount == MAX_RET_REG_COUNT));
+}
+
+//------------------------------------------------------------------------
+// TreeNodeInfoInitCheckByteable: Check the tree to see if "byte-able" registers are
+// required, and set the tree node info accordingly.
+//
+// Arguments:
+// tree - The node of interest
+//
+// Return Value:
+// None.
+//
+void Lowering::TreeNodeInfoInitCheckByteable(GenTree* tree)
+{
#ifdef _TARGET_X86_
+ LinearScan* l = m_lsra;
+ TreeNodeInfo* info = &(tree->gtLsraInfo);
+
// Exclude RBM_NON_BYTE_REGS from dst candidates of tree node and src candidates of operands
// if the tree node is a byte type.
//
- // Example1: GT_STOREIND(byte, addr, op2) - storeind of byte sized value from op2 into mem 'addr'
- // Storeind itself will not produce any value and hence dstCount=0. But op2 could be TYP_INT
- // value. In this case we need to exclude esi/edi from the src candidates of op2.
- //
- // Example2: GT_CAST(int <- bool <- int) - here type of GT_CAST node is int and castToType is bool.
- //
- // Example3: GT_EQ(int, op1 of type ubyte, op2 of type ubyte) - in this case codegen uses
- // ubyte as the result of comparison and if the result needs to be materialized into a reg
- // simply zero extend it to TYP_INT size. Here is an example of generated code:
- // cmp dl, byte ptr[addr mode]
- // movzx edx, dl
- //
// Though this looks conservative in theory, in practice we could not think of a case where
// the below logic leads to conservative register specification. In future when or if we find
// one such case, this logic needs to be fine tuned for that case(s).
- if (varTypeIsByte(tree) || ((tree->OperGet() == GT_CAST) && varTypeIsByte(tree->CastToType())) ||
- (tree->OperIsCompare() && varTypeIsByte(tree->gtGetOp1()) && varTypeIsByte(tree->gtGetOp2())))
+
+ if (ExcludeNonByteableRegisters(tree))
{
regMaskTP regMask;
if (info->dstCount > 0)
@@ -870,9 +983,6 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
}
}
#endif //_TARGET_X86_
-
- // We need to be sure that we've set info->srcCount and info->dstCount appropriately
- assert((info->dstCount < 2) || (tree->IsMultiRegCall() && info->dstCount == MAX_RET_REG_COUNT));
}
//------------------------------------------------------------------------
@@ -1028,6 +1138,31 @@ void Lowering::TreeNodeInfoInitShiftRotate(GenTree* tree)
GenTreePtr shiftBy = tree->gtOp.gtOp2;
GenTreePtr source = tree->gtOp.gtOp1;
+#ifdef _TARGET_X86_
+ // 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
+
// x64 can encode 8 bits of shift and it will use 5 or 6. (the others are masked off)
// We will allow whatever can be encoded - hope you know what you are doing.
if (!IsContainableImmed(tree, shiftBy) || (shiftBy->gtIntConCommon.IconValue() > 255) ||
@@ -1040,6 +1175,17 @@ void Lowering::TreeNodeInfoInitShiftRotate(GenTree* tree)
else
{
MakeSrcContained(tree, shiftBy);
+
+ // Note that Rotate Left/Right instructions don't set ZF and SF flags.
+ //
+ // If the operand being shifted is 32-bits then upper three bits are masked
+ // by hardware to get actual shift count. Similarly for 64-bit operands
+ // shift count is narrowed to [0..63]. If the resulting shift count is zero,
+ // then shift operation won't modify flags.
+ //
+ // TODO-CQ-XARCH: We can optimize generating 'test' instruction for GT_EQ/NE(shift, 0)
+ // if the shift count is known to be non-zero and in the range depending on the
+ // operand size.
}
}
@@ -1088,6 +1234,12 @@ void Lowering::TreeNodeInfoInitCall(GenTreeCall* call)
assert(ctrlExpr == nullptr);
assert(call->gtCallAddr != nullptr);
ctrlExpr = call->gtCallAddr;
+
+#ifdef _TARGET_X86_
+ // Fast tail calls aren't currently supported on x86, but if they ever are, the code
+ // below that handles indirect VSD calls will need to be fixed.
+ assert(!call->IsFastTailCall() || !call->IsVirtualStub());
+#endif // _TARGET_X86_
}
// set reg requirements on call target represented as control sequence.
@@ -1103,7 +1255,24 @@ void Lowering::TreeNodeInfoInitCall(GenTreeCall* call)
// computed into a register.
if (!call->IsFastTailCall())
{
- if (ctrlExpr->isIndir())
+#ifdef _TARGET_X86_
+ // On x86, we need to generate a very specific pattern for indirect VSD calls:
+ //
+ // 3-byte nop
+ // call dword ptr [eax]
+ //
+ // Where EAX is also used as an argument to the stub dispatch helper. Make
+ // sure that the call target address is computed into EAX in this case.
+ if (call->IsVirtualStub() && (call->gtCallType == CT_INDIRECT))
+ {
+ assert(ctrlExpr->isIndir());
+
+ ctrlExpr->gtGetOp1()->gtLsraInfo.setSrcCandidates(l, RBM_VIRTUAL_STUB_TARGET);
+ MakeSrcContained(call, ctrlExpr);
+ }
+ else
+#endif // _TARGET_X86_
+ if (ctrlExpr->isIndir())
{
MakeSrcContained(call, ctrlExpr);
}
@@ -1191,7 +1360,7 @@ void Lowering::TreeNodeInfoInitCall(GenTreeCall* call)
// First, count reg args
for (GenTreePtr list = call->gtCallLateArgs; list; list = list->MoveNext())
{
- assert(list->IsList());
+ assert(list->OperIsList());
GenTreePtr argNode = list->Current();
@@ -1206,7 +1375,7 @@ void Lowering::TreeNodeInfoInitCall(GenTreeCall* call)
argNode->gtLsraInfo.srcCount = 1;
argNode->gtLsraInfo.dstCount = 0;
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
+#ifdef FEATURE_PUT_STRUCT_ARG_STK
// If the node is TYP_STRUCT and it is put on stack with
// putarg_stk operation, we consume and produce no registers.
// In this case the embedded Obj node should not produce
@@ -1218,7 +1387,7 @@ void Lowering::TreeNodeInfoInitCall(GenTreeCall* call)
argNode->gtOp.gtOp1->gtLsraInfo.dstCount = 0;
argNode->gtLsraInfo.srcCount = 0;
}
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+#endif // FEATURE_PUT_STRUCT_ARG_STK
continue;
}
@@ -1248,7 +1417,7 @@ void Lowering::TreeNodeInfoInitCall(GenTreeCall* call)
// 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) FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY(|| curArgTabEntry->isStruct))
+ if (varTypeIsStruct(argNode) PUT_STRUCT_ARG_STK_ONLY(|| curArgTabEntry->isStruct))
{
unsigned originalSize = 0;
LclVarDsc* varDsc = nullptr;
@@ -1270,16 +1439,16 @@ void Lowering::TreeNodeInfoInitCall(GenTreeCall* call)
{
originalSize = genTypeSize(argNode->gtType);
}
- else if (argNode->gtOper == GT_LIST)
+ else if (argNode->gtOper == GT_FIELD_LIST)
{
originalSize = 0;
// There could be up to 2 PUTARG_REGs in the list
- GenTreeArgList* argListPtr = argNode->AsArgList();
- unsigned iterationNum = 0;
- for (; argListPtr; argListPtr = argListPtr->Rest())
+ GenTreeFieldList* fieldListPtr = argNode->AsFieldList();
+ unsigned iterationNum = 0;
+ for (; fieldListPtr; fieldListPtr = fieldListPtr->Rest())
{
- GenTreePtr putArgRegNode = argListPtr->gtOp.gtOp1;
+ GenTreePtr putArgRegNode = fieldListPtr->Current();
assert(putArgRegNode->gtOper == GT_PUTARG_REG);
if (iterationNum == 0)
@@ -1509,7 +1678,7 @@ void Lowering::TreeNodeInfoInitBlockStore(GenTreeBlk* blkNode)
}
m_lsra->clearOperandCounts(source);
}
- else if (!source->OperIsSIMD())
+ else if (!source->IsMultiRegCall() && !source->OperIsSIMD())
{
assert(source->IsLocal());
MakeSrcContained(blkNode, source);
@@ -1519,7 +1688,11 @@ void Lowering::TreeNodeInfoInitBlockStore(GenTreeBlk* blkNode)
if (isInitBlk)
{
GenTree* initVal = source;
- srcAddrOrFill = source;
+ if (initVal->OperIsInitVal())
+ {
+ initVal = initVal->gtGetOp1();
+ }
+ srcAddrOrFill = initVal;
// If we have an InitBlk with constant block size we can optimize several ways:
// a) If the size is smaller than a small memory page but larger than INITBLK_UNROLL_LIMIT bytes
// we use rep stosb since this reduces the register pressure in LSRA and we have
@@ -1571,8 +1744,23 @@ void Lowering::TreeNodeInfoInitBlockStore(GenTreeBlk* blkNode)
// a pack of 16 init value constants.
blkNode->gtLsraInfo.internalFloatCount = 1;
blkNode->gtLsraInfo.setInternalCandidates(l, l->internalFloatRegCandidates());
+ if ((fill == 0) && ((size & 0xf) == 0))
+ {
+ MakeSrcContained(blkNode, source);
+ }
}
blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindUnroll;
+
+#ifdef _TARGET_X86_
+ if ((size & 1) != 0)
+ {
+ // On x86, you can't address the lower byte of ESI, EDI, ESP, or EBP when doing
+ // a "mov byte ptr [dest], val". If the fill size is odd, we will try to do this
+ // when unrolling, so only allow byteable registers as the source value. (We could
+ // consider just using BlkOpKindRepInstr instead.)
+ sourceRegMask = RBM_BYTE_REGS;
+ }
+#endif // _TARGET_X86_
}
else
{
@@ -1825,7 +2013,7 @@ void Lowering::TreeNodeInfoInitBlockStore(GenTreeBlk* blkNode)
}
}
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
+#ifdef FEATURE_PUT_STRUCT_ARG_STK
//------------------------------------------------------------------------
// TreeNodeInfoInitPutArgStk: Set the NodeInfo for a GT_PUTARG_STK.
//
@@ -1835,44 +2023,219 @@ void Lowering::TreeNodeInfoInitBlockStore(GenTreeBlk* blkNode)
// Return Value:
// None.
//
-void Lowering::TreeNodeInfoInitPutArgStk(GenTree* tree)
+void Lowering::TreeNodeInfoInitPutArgStk(GenTreePutArgStk* putArgStk)
{
- TreeNodeInfo* info = &(tree->gtLsraInfo);
+ TreeNodeInfo* info = &(putArgStk->gtLsraInfo);
LinearScan* l = m_lsra;
- if (tree->TypeGet() != TYP_STRUCT)
+#ifdef _TARGET_X86_
+ if (putArgStk->gtOp1->gtOper == GT_FIELD_LIST)
+ {
+ putArgStk->gtNumberReferenceSlots = 0;
+ putArgStk->gtPutArgStkKind = GenTreePutArgStk::Kind::Invalid;
+
+ GenTreeFieldList* fieldList = putArgStk->gtOp1->AsFieldList();
+
+ // The code generator will push these fields in reverse order by offset. Reorder the list here s.t. the order
+ // of uses is visible to LSRA.
+ unsigned fieldCount = 0;
+ GenTreeFieldList* head = nullptr;
+ for (GenTreeFieldList *current = fieldList, *next; current != nullptr; current = next)
+ {
+ next = current->Rest();
+
+ // First, insert the field node into the sorted list.
+ GenTreeFieldList* prev = nullptr;
+ for (GenTreeFieldList* cursor = head;; cursor = cursor->Rest())
+ {
+ // If the offset of the current list node is greater than the offset of the cursor or if we have
+ // reached the end of the list, insert the current node before the cursor and terminate.
+ if ((cursor == nullptr) || (current->gtFieldOffset > cursor->gtFieldOffset))
+ {
+ if (prev == nullptr)
+ {
+ assert(cursor == head);
+ head = current;
+ }
+ else
+ {
+ prev->Rest() = current;
+ }
+
+ current->Rest() = cursor;
+ break;
+ }
+ }
+
+ fieldCount++;
+ }
+
+ info->srcCount = fieldCount;
+ info->dstCount = 0;
+
+ // In theory, the upper bound for the size of a field list is 8: these constructs only appear when passing the
+ // collection of lclVars that represent the fields of a promoted struct lclVar, and we do not promote struct
+ // lclVars with more than 4 fields. If each of these lclVars is of type long, decomposition will split the
+ // corresponding field list nodes in two, giving an upper bound of 8.
+ //
+ // The reason that this is important is that the algorithm we use above to sort the field list is O(N^2): if
+ // the maximum size of a field list grows significantly, we will need to reevaluate it.
+ assert(fieldCount <= 8);
+
+ // The sort above may have changed which node is at the head of the list. Update the PUTARG_STK node if
+ // necessary.
+ if (head != fieldList)
+ {
+ head->gtFlags |= GTF_FIELD_LIST_HEAD;
+ fieldList->gtFlags &= ~GTF_FIELD_LIST_HEAD;
+
+#ifdef DEBUG
+ head->gtSeqNum = fieldList->gtSeqNum;
+#endif // DEBUG
+
+ head->gtLsraInfo = fieldList->gtLsraInfo;
+ head->gtClearReg(comp);
+
+ BlockRange().InsertAfter(fieldList, head);
+ BlockRange().Remove(fieldList);
+
+ fieldList = head;
+ putArgStk->gtOp1 = fieldList;
+ }
+
+ // Now that the fields have been sorted, initialize the LSRA info.
+ bool allFieldsAreSlots = true;
+ bool needsByteTemp = false;
+ unsigned prevOffset = putArgStk->getArgSize();
+ for (GenTreeFieldList* current = fieldList; current != nullptr; current = current->Rest())
+ {
+ GenTree* const fieldNode = current->Current();
+ const var_types fieldType = fieldNode->TypeGet();
+ const unsigned fieldOffset = current->gtFieldOffset;
+ assert(fieldType != TYP_LONG);
+
+ // For x86 we must mark all integral fields as contained or reg-optional, and handle them
+ // accordingly in code generation, since we may have up to 8 fields, which cannot all be in
+ // registers to be consumed atomically by the call.
+ if (varTypeIsIntegralOrI(fieldNode))
+ {
+ if (fieldNode->OperGet() == GT_LCL_VAR)
+ {
+ LclVarDsc* varDsc = &(comp->lvaTable[fieldNode->AsLclVarCommon()->gtLclNum]);
+ if (varDsc->lvTracked && !varDsc->lvDoNotEnregister)
+ {
+ SetRegOptional(fieldNode);
+ }
+ else
+ {
+ MakeSrcContained(putArgStk, fieldNode);
+ }
+ }
+ else if (fieldNode->IsIntCnsFitsInI32())
+ {
+ MakeSrcContained(putArgStk, fieldNode);
+ }
+ else
+ {
+ // For the case where we cannot directly push the value, if we run out of registers,
+ // it would be better to defer computation until we are pushing the arguments rather
+ // than spilling, but this situation is not all that common, as most cases of promoted
+ // structs do not have a large number of fields, and of those most are lclVars or
+ // copy-propagated constants.
+ SetRegOptional(fieldNode);
+ }
+ }
+ else
+ {
+ assert(varTypeIsFloating(fieldNode));
+ }
+
+ // We can treat as a slot any field that is stored at a slot boundary, where the previous
+ // field is not in the same slot. (Note that we store the fields in reverse order.)
+ const bool fieldIsSlot = ((fieldOffset % 4) == 0) && ((prevOffset - fieldOffset) >= 4);
+ if (!fieldIsSlot)
+ {
+ allFieldsAreSlots = false;
+ if (varTypeIsByte(fieldType))
+ {
+ // If this field is a slot--i.e. it is an integer field that is 4-byte aligned and takes up 4 bytes
+ // (including padding)--we can store the whole value rather than just the byte. Otherwise, we will
+ // need a byte-addressable register for the store. We will enforce this requirement on an internal
+ // register, which we can use to copy multiple byte values.
+ needsByteTemp = true;
+ }
+ }
+
+ if (varTypeIsGC(fieldType))
+ {
+ putArgStk->gtNumberReferenceSlots++;
+ }
+
+ prevOffset = fieldOffset;
+ }
+
+ // Set the copy kind.
+ // TODO-X86-CQ: Even if we are using push, if there are contiguous floating point fields, we should
+ // adjust the stack once for those fields. The latter is really best done in code generation, but
+ // this tuning should probably be undertaken as a whole.
+ // Also, if there are floating point fields, it may be better to use the "Unroll" mode
+ // of copying the struct as a whole, if the fields are not register candidates.
+ if (allFieldsAreSlots)
+ {
+ putArgStk->gtPutArgStkKind = GenTreePutArgStk::Kind::PushAllSlots;
+ }
+ else
+ {
+ putArgStk->gtPutArgStkKind = GenTreePutArgStk::Kind::Push;
+ // If any of the fields cannot be stored with an actual push, we may need a temporary
+ // register to load the value before storing it to the stack location.
+ info->internalIntCount = 1;
+ regMaskTP regMask = l->allRegs(TYP_INT);
+ if (needsByteTemp)
+ {
+ regMask &= ~RBM_NON_BYTE_REGS;
+ }
+ info->setInternalCandidates(l, regMask);
+ }
+ return;
+ }
+#endif // _TARGET_X86_
+
+#if defined(FEATURE_SIMD) && defined(_TARGET_X86_)
+ // For PutArgStk of a TYP_SIMD12, we need an extra register.
+ if (putArgStk->TypeGet() == TYP_SIMD12)
{
- TreeNodeInfoInitSimple(tree);
+ info->srcCount = putArgStk->gtOp1->gtLsraInfo.dstCount;
+ info->dstCount = 0;
+ info->internalFloatCount = 1;
+ info->setInternalCandidates(l, l->allSIMDRegs());
return;
}
+#endif // defined(FEATURE_SIMD) && defined(_TARGET_X86_)
- GenTreePutArgStk* putArgStkTree = tree->AsPutArgStk();
+ if (putArgStk->TypeGet() != TYP_STRUCT)
+ {
+ TreeNodeInfoInitSimple(putArgStk);
+ return;
+ }
- GenTreePtr dst = tree;
- GenTreePtr src = tree->gtOp.gtOp1;
+ GenTreePtr dst = putArgStk;
+ GenTreePtr src = putArgStk->gtOp1;
GenTreePtr srcAddr = nullptr;
+ bool haveLocalAddr = false;
if ((src->OperGet() == GT_OBJ) || (src->OperGet() == GT_IND))
{
srcAddr = src->gtOp.gtOp1;
+ assert(srcAddr != nullptr);
+ haveLocalAddr = srcAddr->OperIsLocalAddr();
}
else
{
- assert(varTypeIsSIMD(tree));
- }
- info->srcCount = src->gtLsraInfo.dstCount;
-
- // If this is a stack variable address,
- // make the op1 contained, so this way
- // there is no unnecessary copying between registers.
- // To avoid assertion, increment the parent's source.
- // It is recovered below.
- bool haveLocalAddr = ((srcAddr != nullptr) && (srcAddr->OperIsLocalAddr()));
- if (haveLocalAddr)
- {
- info->srcCount += 1;
+ assert(varTypeIsSIMD(putArgStk));
}
+ info->srcCount = src->gtLsraInfo.dstCount;
info->dstCount = 0;
// In case of a CpBlk we could use a helper call. In case of putarg_stk we
@@ -1884,7 +2247,7 @@ void Lowering::TreeNodeInfoInitPutArgStk(GenTree* tree)
// This threshold will decide from using the helper or let the JIT decide to inline
// a code sequence of its choice.
ssize_t helperThreshold = max(CPBLK_MOVS_LIMIT, CPBLK_UNROLL_LIMIT);
- ssize_t size = putArgStkTree->gtNumSlots * TARGET_POINTER_SIZE;
+ ssize_t size = putArgStk->gtNumSlots * TARGET_POINTER_SIZE;
// TODO-X86-CQ: The helper call either is not supported on x86 or required more work
// (I don't know which).
@@ -1892,7 +2255,7 @@ void Lowering::TreeNodeInfoInitPutArgStk(GenTree* tree)
// If we have a buffer between XMM_REGSIZE_BYTES and CPBLK_UNROLL_LIMIT bytes, we'll use SSE2.
// Structs and buffer with sizes <= CPBLK_UNROLL_LIMIT bytes are occurring in more than 95% of
// our framework assemblies, so this is the main code generation scheme we'll use.
- if (size <= CPBLK_UNROLL_LIMIT && putArgStkTree->gtNumberReferenceSlots == 0)
+ if (size <= CPBLK_UNROLL_LIMIT && putArgStk->gtNumberReferenceSlots == 0)
{
// If we have a remainder smaller than XMM_REGSIZE_BYTES, we need an integer temp reg.
//
@@ -1913,46 +2276,62 @@ void Lowering::TreeNodeInfoInitPutArgStk(GenTree* tree)
info->setInternalCandidates(l, regMask);
}
+#ifdef _TARGET_X86_
+ if (size >= 8)
+#else // !_TARGET_X86_
if (size >= XMM_REGSIZE_BYTES)
+#endif // !_TARGET_X86_
{
- // If we have a buffer larger than XMM_REGSIZE_BYTES,
- // reserve an XMM register to use it for a
+ // If we have a buffer larger than or equal to XMM_REGSIZE_BYTES on x64/ux,
+ // or larger than or equal to 8 bytes on x86, reserve an XMM register to use it for a
// series of 16-byte loads and stores.
info->internalFloatCount = 1;
info->addInternalCandidates(l, l->internalFloatRegCandidates());
}
- if (haveLocalAddr)
+#ifdef _TARGET_X86_
+ if (size < XMM_REGSIZE_BYTES)
{
- MakeSrcContained(putArgStkTree, srcAddr);
+ putArgStk->gtPutArgStkKind = GenTreePutArgStk::Kind::Push;
}
-
- // If src or dst are on stack, we don't have to generate the address into a register
- // because it's just some constant+SP
- putArgStkTree->gtPutArgStkKind = GenTreePutArgStk::PutArgStkKindUnroll;
+ else
+#endif // _TARGET_X86_
+ {
+ putArgStk->gtPutArgStkKind = GenTreePutArgStk::Kind::Unroll;
+ }
+ }
+#ifdef _TARGET_X86_
+ else if (putArgStk->gtNumberReferenceSlots != 0)
+ {
+ // On x86, we must use `push` to store GC references to the stack in order for the emitter to properly update
+ // the function's GC info. These `putargstk` nodes will generate a sequence of `push` instructions.
+ putArgStk->gtPutArgStkKind = GenTreePutArgStk::Kind::Push;
}
+#endif // _TARGET_X86_
else
{
info->internalIntCount += 3;
info->setInternalCandidates(l, (RBM_RDI | RBM_RCX | RBM_RSI));
- if (haveLocalAddr)
- {
- MakeSrcContained(putArgStkTree, srcAddr);
- }
- putArgStkTree->gtPutArgStkKind = GenTreePutArgStk::PutArgStkKindRepInstr;
+ putArgStk->gtPutArgStkKind = GenTreePutArgStk::Kind::RepInstr;
}
// Always mark the OBJ and ADDR as contained trees by the putarg_stk. The codegen will deal with this tree.
- MakeSrcContained(putArgStkTree, src);
+ MakeSrcContained(putArgStk, src);
- // Balance up the inc above.
if (haveLocalAddr)
{
- info->srcCount -= 1;
+ // If the source address is the address of a lclVar, make the source address contained to avoid unnecessary
+ // copies.
+ //
+ // To avoid an assertion in MakeSrcContained, increment the parent's source count beforehand and decrement it
+ // afterwards.
+ info->srcCount++;
+ MakeSrcContained(putArgStk, srcAddr);
+ info->srcCount--;
}
}
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+#endif // FEATURE_PUT_STRUCT_ARG_STK
//------------------------------------------------------------------------
// TreeNodeInfoInitLclHeap: Set the NodeInfo for a GT_LCLHEAP.
@@ -1976,13 +2355,17 @@ void Lowering::TreeNodeInfoInitLclHeap(GenTree* tree)
// Here '-' means don't care.
//
// Size? Init Memory? # temp regs
- // 0 - 0
- // const and <=6 reg words - 0
- // const and >6 reg words Yes 0
+ // 0 - 0 (returns 0)
+ // const and <=6 reg words - 0 (pushes '0')
+ // const and >6 reg words Yes 0 (pushes '0')
// const and <PageSize No 0 (amd64) 1 (x86)
- // const and >=PageSize No 2
- // Non-const Yes 0
- // Non-const No 2
+ // (x86:tmpReg for sutracting from esp)
+ // const and >=PageSize No 2 (regCnt and tmpReg for subtracing from sp)
+ // Non-const Yes 0 (regCnt=targetReg and pushes '0')
+ // Non-const No 2 (regCnt and tmpReg for subtracting from sp)
+ //
+ // Note: Here we don't need internal register to be different from targetReg.
+ // Rather, require it to be different from operand's reg.
GenTreePtr size = tree->gtOp.gtOp1;
if (size->IsCnsIntOrI())
@@ -2121,6 +2504,9 @@ void Lowering::TreeNodeInfoInitLogicalOp(GenTree* tree)
// as reg optional.
SetRegOptionalForBinOp(tree);
}
+
+ // Codegen of this tree node sets ZF and SF flags.
+ tree->gtFlags |= GTF_ZSF_SET;
}
//------------------------------------------------------------------------
@@ -2189,15 +2575,40 @@ void Lowering::TreeNodeInfoInitModDiv(GenTree* tree)
info->setDstCandidates(l, RBM_RAX);
}
- // If possible would like to have op1 in RAX to avoid a register move
- op1->gtLsraInfo.setSrcCandidates(l, RBM_RAX);
+ bool op2CanBeRegOptional = true;
+#ifdef _TARGET_X86_
+ if (op1->OperGet() == GT_LONG)
+ {
+ // To avoid reg move would like to have op1's low part in RAX and high part in RDX.
+ GenTree* loVal = op1->gtGetOp1();
+ GenTree* hiVal = op1->gtGetOp2();
+
+ // Src count is actually 3, so increment.
+ assert(op2->IsCnsIntOrI());
+ assert(tree->OperGet() == GT_UMOD);
+ info->srcCount++;
+ op2CanBeRegOptional = false;
+
+ // This situation also requires an internal register.
+ info->internalIntCount = 1;
+ info->setInternalCandidates(l, l->allRegs(TYP_INT));
+
+ loVal->gtLsraInfo.setSrcCandidates(l, RBM_EAX);
+ hiVal->gtLsraInfo.setSrcCandidates(l, RBM_EDX);
+ }
+ else
+#endif
+ {
+ // If possible would like to have op1 in RAX to avoid a register move
+ op1->gtLsraInfo.setSrcCandidates(l, RBM_RAX);
+ }
// divisor can be an r/m, but the memory indirection must be of the same size as the divide
if (op2->isMemoryOp() && (op2->TypeGet() == tree->TypeGet()))
{
MakeSrcContained(tree, op2);
}
- else
+ else if (op2CanBeRegOptional)
{
op2->gtLsraInfo.setSrcCandidates(l, l->allRegs(TYP_INT) & ~(RBM_RAX | RBM_RDX));
@@ -2298,12 +2709,13 @@ void Lowering::TreeNodeInfoInitSIMD(GenTree* tree)
info->dstCount = 1;
switch (simdTree->gtSIMDIntrinsicID)
{
+ GenTree* op1;
GenTree* op2;
case SIMDIntrinsicInit:
{
info->srcCount = 1;
- GenTree* op1 = tree->gtOp.gtOp1;
+ op1 = tree->gtOp.gtOp1;
// This sets all fields of a SIMD struct to the given value.
// Mark op1 as contained if it is either zero or int constant of all 1's,
@@ -2377,7 +2789,8 @@ void Lowering::TreeNodeInfoInitSIMD(GenTree* tree)
info->srcCount = 2;
// SSE2 32-bit integer multiplication requires two temp regs
- if (simdTree->gtSIMDIntrinsicID == SIMDIntrinsicMul && simdTree->gtSIMDBaseType == TYP_INT)
+ if (simdTree->gtSIMDIntrinsicID == SIMDIntrinsicMul && simdTree->gtSIMDBaseType == TYP_INT &&
+ comp->getSIMDInstructionSet() == InstructionSet_SSE2)
{
info->internalFloatCount = 2;
info->setInternalCandidates(lsra, lsra->allSIMDRegs());
@@ -2406,38 +2819,78 @@ void Lowering::TreeNodeInfoInitSIMD(GenTree* tree)
case SIMDIntrinsicOpEquality:
case SIMDIntrinsicOpInEquality:
- // Need two SIMD registers as scratch.
- // See genSIMDIntrinsicRelOp() for details on code sequence generate and
- // the need for two scratch registers.
- info->srcCount = 2;
- info->internalFloatCount = 2;
- info->setInternalCandidates(lsra, lsra->allSIMDRegs());
+ info->srcCount = 2;
+
+ // On SSE4/AVX, we can generate optimal code for (in)equality
+ // against zero using ptest. We can safely do the this optimization
+ // for integral vectors but not for floating-point for the reason
+ // that we have +0.0 and -0.0 and +0.0 == -0.0
+ op2 = tree->gtGetOp2();
+ if ((comp->getSIMDInstructionSet() >= InstructionSet_SSE3_4) && op2->IsIntegralConstVector(0))
+ {
+ MakeSrcContained(tree, op2);
+ }
+ else
+ {
+
+ // Need one SIMD register as scratch.
+ // See genSIMDIntrinsicRelOp() for details on code sequence generated and
+ // the need for one scratch register.
+ //
+ // Note these intrinsics produce a BOOL result, hence internal float
+ // registers reserved are guaranteed to be different from target
+ // integer register without explicitly specifying.
+ info->internalFloatCount = 1;
+ info->setInternalCandidates(lsra, lsra->allSIMDRegs());
+ }
break;
case SIMDIntrinsicDotProduct:
- if ((comp->getSIMDInstructionSet() == InstructionSet_SSE2) ||
- (simdTree->gtOp.gtOp1->TypeGet() == TYP_SIMD32))
+ // Float/Double vectors:
+ // For SSE, or AVX with 32-byte vectors, we also need an internal register
+ // as scratch. Further we need the targetReg and internal reg to be distinct
+ // registers. Note that if this is a TYP_SIMD16 or smaller on AVX, then we
+ // don't need a tmpReg.
+ //
+ // 32-byte integer vector on SSE4/AVX:
+ // will take advantage of phaddd, which operates only on 128-bit xmm reg.
+ // This will need 1 (in case of SSE4) or 2 (in case of AVX) internal
+ // registers since targetReg is an int type register.
+ //
+ // See genSIMDIntrinsicDotProduct() for details on code sequence generated
+ // and the need for scratch registers.
+ if (varTypeIsFloating(simdTree->gtSIMDBaseType))
{
- // For SSE, or AVX with 32-byte vectors, we also need an internal register as scratch.
- // Further we need the targetReg and internal reg to be distinct registers.
- // This is achieved by requesting two internal registers; thus one of them
- // will be different from targetReg.
- // Note that if this is a TYP_SIMD16 or smaller on AVX, then we don't need a tmpReg.
- //
- // See genSIMDIntrinsicDotProduct() for details on code sequence generated and
- // the need for scratch registers.
- info->internalFloatCount = 2;
+ if ((comp->getSIMDInstructionSet() == InstructionSet_SSE2) ||
+ (simdTree->gtOp.gtOp1->TypeGet() == TYP_SIMD32))
+ {
+ info->internalFloatCount = 1;
+ info->isInternalRegDelayFree = true;
+ info->setInternalCandidates(lsra, lsra->allSIMDRegs());
+ }
+ // else don't need scratch reg(s).
+ }
+ else
+ {
+ assert(simdTree->gtSIMDBaseType == TYP_INT && comp->getSIMDInstructionSet() >= InstructionSet_SSE3_4);
+
+ // No need to set isInternalRegDelayFree since targetReg is a
+ // an int type reg and guaranteed to be different from xmm/ymm
+ // regs.
+ info->internalFloatCount = comp->canUseAVX() ? 2 : 1;
info->setInternalCandidates(lsra, lsra->allSIMDRegs());
}
info->srcCount = 2;
break;
case SIMDIntrinsicGetItem:
+ {
// This implements get_Item method. The sources are:
// - the source SIMD struct
// - index (which element to get)
// The result is baseType of SIMD struct.
info->srcCount = 2;
+ op1 = tree->gtOp.gtOp1;
op2 = tree->gtOp.gtOp2;
// If the index is a constant, mark it as contained.
@@ -2446,48 +2899,69 @@ void Lowering::TreeNodeInfoInitSIMD(GenTree* tree)
info->srcCount = 1;
}
- // If the index is not a constant, we will use the SIMD temp location to store the vector.
- // Otherwise, if the baseType is floating point, the targetReg will be a xmm reg and we
- // can use that in the process of extracting the element.
- //
- // If the index is a constant and base type is a small int we can use pextrw, but on AVX
- // we will need a temp if are indexing into the upper half of the AVX register.
- // In all other cases with constant index, we need a temp xmm register to extract the
- // element if index is other than zero.
-
- if (!op2->IsCnsIntOrI())
+ if (op1->isMemoryOp())
{
- (void)comp->getSIMDInitTempVarNum();
+ MakeSrcContained(tree, op1);
+
+ // Although GT_IND of TYP_SIMD12 reserves an internal float
+ // register for reading 4 and 8 bytes from memory and
+ // assembling them into target XMM reg, it is not required
+ // in this case.
+ op1->gtLsraInfo.internalIntCount = 0;
+ op1->gtLsraInfo.internalFloatCount = 0;
}
- else if (!varTypeIsFloating(simdTree->gtSIMDBaseType))
+ else
{
- bool needFloatTemp;
- if (varTypeIsSmallInt(simdTree->gtSIMDBaseType) &&
- (comp->getSIMDInstructionSet() == InstructionSet_AVX))
- {
- int byteShiftCnt = (int)op2->AsIntCon()->gtIconVal * genTypeSize(simdTree->gtSIMDBaseType);
- needFloatTemp = (byteShiftCnt >= 16);
- }
- else
+ // If the index is not a constant, we will use the SIMD temp location to store the vector.
+ // Otherwise, if the baseType is floating point, the targetReg will be a xmm reg and we
+ // can use that in the process of extracting the element.
+ //
+ // If the index is a constant and base type is a small int we can use pextrw, but on AVX
+ // we will need a temp if are indexing into the upper half of the AVX register.
+ // In all other cases with constant index, we need a temp xmm register to extract the
+ // element if index is other than zero.
+
+ if (!op2->IsCnsIntOrI())
{
- needFloatTemp = !op2->IsIntegralConst(0);
+ (void)comp->getSIMDInitTempVarNum();
}
- if (needFloatTemp)
+ else if (!varTypeIsFloating(simdTree->gtSIMDBaseType))
{
- info->internalFloatCount = 1;
- info->setInternalCandidates(lsra, lsra->allSIMDRegs());
+ bool needFloatTemp;
+ if (varTypeIsSmallInt(simdTree->gtSIMDBaseType) &&
+ (comp->getSIMDInstructionSet() == InstructionSet_AVX))
+ {
+ int byteShiftCnt = (int)op2->AsIntCon()->gtIconVal * genTypeSize(simdTree->gtSIMDBaseType);
+ needFloatTemp = (byteShiftCnt >= 16);
+ }
+ else
+ {
+ needFloatTemp = !op2->IsIntegralConst(0);
+ }
+
+ if (needFloatTemp)
+ {
+ info->internalFloatCount = 1;
+ info->setInternalCandidates(lsra, lsra->allSIMDRegs());
+ }
}
}
- break;
+ }
+ break;
case SIMDIntrinsicSetX:
case SIMDIntrinsicSetY:
case SIMDIntrinsicSetZ:
case SIMDIntrinsicSetW:
- // We need an internal integer register
- info->srcCount = 2;
- info->internalIntCount = 1;
- info->setInternalCandidates(lsra, lsra->allRegs(TYP_INT));
+ info->srcCount = 2;
+
+ // We need an internal integer register for SSE2 codegen
+ if (comp->getSIMDInstructionSet() == InstructionSet_SSE2)
+ {
+ info->internalIntCount = 1;
+ info->setInternalCandidates(lsra, lsra->allRegs(TYP_INT));
+ }
+
break;
case SIMDIntrinsicCast:
@@ -2592,6 +3066,8 @@ void Lowering::TreeNodeInfoInitCast(GenTree* tree)
{
if (genTypeSize(castOpType) == 8)
{
+ // Here we don't need internal register to be different from targetReg,
+ // rather require it to be different from operand's reg.
info->internalIntCount = 1;
}
}
@@ -2693,7 +3169,6 @@ void Lowering::SetIndirAddrOpCounts(GenTreePtr indirTree)
GenTreePtr index = nullptr;
unsigned mul, cns;
bool rev;
- bool modifiedSources = false;
#ifdef FEATURE_SIMD
// If indirTree is of TYP_SIMD12, don't mark addr as contained
@@ -2711,11 +3186,10 @@ void Lowering::SetIndirAddrOpCounts(GenTreePtr indirTree)
info->internalFloatCount = 1;
// In case of GT_IND we need an internal register different from targetReg and
- // both of the registers are used at the same time. This achieved by reserving
- // two internal registers
+ // both of the registers are used at the same time.
if (indirTree->OperGet() == GT_IND)
{
- (info->internalFloatCount)++;
+ info->isInternalRegDelayFree = true;
}
info->setInternalCandidates(m_lsra, m_lsra->allSIMDRegs());
@@ -2724,16 +3198,21 @@ void Lowering::SetIndirAddrOpCounts(GenTreePtr indirTree)
}
#endif // FEATURE_SIMD
- // These nodes go into an addr mode:
- // - GT_CLS_VAR_ADDR turns into a constant.
- // - GT_LCL_VAR_ADDR is a stack addr mode.
- if ((addr->OperGet() == GT_CLS_VAR_ADDR) || (addr->OperGet() == GT_LCL_VAR_ADDR))
+ if ((indirTree->gtFlags & GTF_IND_REQ_ADDR_IN_REG) != 0)
{
+ // The address of an indirection that requires its address in a reg.
+ // Skip any further processing that might otherwise make it contained.
+ }
+ else if ((addr->OperGet() == GT_CLS_VAR_ADDR) || (addr->OperGet() == GT_LCL_VAR_ADDR))
+ {
+ // These nodes go into an addr mode:
+ // - GT_CLS_VAR_ADDR turns into a constant.
+ // - GT_LCL_VAR_ADDR is a stack addr mode.
+
// make this contained, it turns into a constant that goes into an addr mode
MakeSrcContained(indirTree, addr);
}
- else if (addr->IsCnsIntOrI() && addr->AsIntConCommon()->FitsInAddrBase(comp) &&
- addr->gtLsraInfo.getDstCandidates(m_lsra) != RBM_VIRTUAL_STUB_PARAM)
+ else if (addr->IsCnsIntOrI() && addr->AsIntConCommon()->FitsInAddrBase(comp))
{
// Amd64:
// We can mark any pc-relative 32-bit addr as containable, except for a direct VSD call address.
@@ -2755,17 +3234,10 @@ void Lowering::SetIndirAddrOpCounts(GenTreePtr indirTree)
}
else if ((addr->OperGet() == GT_LEA) && IsSafeToContainMem(indirTree, addr))
{
- GenTreeAddrMode* lea = addr->AsAddrMode();
- base = lea->Base();
- index = lea->Index();
-
- 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--;
+ MakeSrcContained(indirTree, addr);
}
else if (comp->codeGen->genCreateAddrMode(addr, -1, true, 0, &rev, &base, &index, &mul, &cns, true /*nogen*/) &&
- !(modifiedSources = AreSourcesPossiblyModifiedLocals(indirTree, base, index)))
+ !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
@@ -2774,7 +3246,16 @@ void Lowering::SetIndirAddrOpCounts(GenTreePtr indirTree)
assert(base != addr);
m_lsra->clearOperandCounts(addr);
- GenTreePtr arrLength = nullptr;
+ const bool hasBase = base != nullptr;
+ const bool hasIndex = index != nullptr;
+ assert(hasBase || hasIndex); // At least one of a base or an index must be present.
+
+ // If the addressing mode has both a base and an index, bump its source count by one. If it only has one or the
+ // other, its source count is already correct (due to the source for the address itself).
+ if (hasBase && hasIndex)
+ {
+ info->srcCount++;
+ }
// Traverse the computation below GT_IND to find the operands
// for the addressing mode, marking the various constants and
@@ -2784,14 +3265,13 @@ void Lowering::SetIndirAddrOpCounts(GenTreePtr indirTree)
// 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)
+ bool foundBase = !hasBase;
+ bool foundIndex = !hasIndex;
+ for (GenTree *child = addr, *nextChild = nullptr; child != nullptr && !child->OperIsLeaf(); child = nextChild)
{
- nextChild = nullptr;
- GenTreePtr op1 = child->gtOp.gtOp1;
- GenTreePtr op2 = (child->OperIsBinary()) ? child->gtOp.gtOp2 : nullptr;
+ nextChild = nullptr;
+ GenTree* op1 = child->gtOp.gtOp1;
+ GenTree* op2 = (child->OperIsBinary()) ? child->gtOp.gtOp2 : nullptr;
if (op1 == base)
{
@@ -2832,7 +3312,6 @@ void Lowering::SetIndirAddrOpCounts(GenTreePtr indirTree)
}
}
assert(foundBase && foundIndex);
- info->srcCount--; // it gets incremented below.
}
else if (addr->gtOper == GT_ARR_ELEM)
{
@@ -2845,32 +3324,23 @@ void Lowering::SetIndirAddrOpCounts(GenTreePtr indirTree)
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++;
- }
}
-void Lowering::LowerCmp(GenTreePtr tree)
+void Lowering::TreeNodeInfoInitCmp(GenTreePtr tree)
{
+ assert(tree->OperIsCompare());
+
TreeNodeInfo* info = &(tree->gtLsraInfo);
info->srcCount = 2;
info->dstCount = 1;
#ifdef _TARGET_X86_
+ // If the compare is used by a jump, we just need to set the condition codes. If not, then we need
+ // to store the result into the low byte of a register, which requires the dst be a byteable register.
+ // We always set the dst candidates, though, because if this is compare is consumed by a jump, they
+ // won't be used. We might be able to use GTF_RELOP_JMP_USED to determine this case, but it's not clear
+ // that flag is maintained until this location (especially for decomposed long compares).
info->setDstCandidates(m_lsra, RBM_BYTE_REGS);
#endif // _TARGET_X86_
@@ -2894,9 +3364,9 @@ void Lowering::LowerCmp(GenTreePtr tree)
#endif // !defined(_TARGET_64BIT_)
// If either of op1 or op2 is floating point values, then we need to use
- // ucomiss or ucomisd to compare, both of which support the following form
- // ucomis[s|d] xmm, xmm/mem. That is only the second operand can be a memory
- // op.
+ // ucomiss or ucomisd to compare, both of which support the following form:
+ // ucomis[s|d] xmm, xmm/mem
+ // That is only the second operand can be a memory op.
//
// Second operand is a memory Op: Note that depending on comparison operator,
// the operands of ucomis[s|d] need to be reversed. Therefore, either op1 or
@@ -2952,16 +3422,9 @@ void Lowering::LowerCmp(GenTreePtr tree)
bool hasShortCast = false;
if (CheckImmedAndMakeContained(tree, op2))
{
- bool op1CanBeContained = (op1Type == op2Type);
- if (!op1CanBeContained)
- {
- if (genTypeSize(op1Type) == genTypeSize(op2Type))
- {
- // The constant is of the correct size, but we don't have an exact type match
- // We can treat the isMemoryOp as "contained"
- op1CanBeContained = true;
- }
- }
+ // If the types are the same, or if the constant is of the correct size,
+ // we can treat the isMemoryOp as contained.
+ bool op1CanBeContained = (genTypeSize(op1Type) == genTypeSize(op2Type));
// Do we have a short compare against a constant in op2
//
@@ -3031,13 +3494,13 @@ void Lowering::LowerCmp(GenTreePtr tree)
bool op1IsMadeContained = false;
// When op1 is a GT_AND we can often generate a single "test" instruction
- // instead of two instructions (an "and" instruction followed by a "cmp"/"test")
+ // instead of two instructions (an "and" instruction followed by a "cmp"/"test").
//
- // This instruction can only be used for equality or inequality comparions.
+ // This instruction can only be used for equality or inequality comparisons.
// and we must have a compare against zero.
//
// If we have a postive test for a single bit we can reverse the condition and
- // make the compare be against zero
+ // make the compare be against zero.
//
// Example:
// GT_EQ GT_NE
@@ -3046,8 +3509,8 @@ void Lowering::LowerCmp(GenTreePtr tree)
// / \ / \
// andOp1 GT_CNS (0x100) andOp1 GT_CNS (0x100)
//
- // We will mark the GT_AND node as contained if the tree is a equality compare with zero
- // Additionally when we do this we also allow for a contained memory operand for "andOp1".
+ // We will mark the GT_AND node as contained if the tree is an equality compare with zero.
+ // Additionally, when we do this we also allow for a contained memory operand for "andOp1".
//
bool isEqualityCompare = (tree->gtOper == GT_EQ || tree->gtOper == GT_NE);
@@ -3066,7 +3529,7 @@ void Lowering::LowerCmp(GenTreePtr tree)
// so that we can generate a test instruction.
// Reverse the equality comparison
- tree->gtOper = (tree->gtOper == GT_EQ) ? GT_NE : GT_EQ;
+ tree->SetOperRaw((tree->gtOper == GT_EQ) ? GT_NE : GT_EQ);
// Change the relOp2CnsVal to zero
relOp2CnsVal = 0;
@@ -3171,7 +3634,7 @@ void Lowering::LowerCmp(GenTreePtr tree)
genTreeOps castOp1Oper = castOp1->OperGet();
bool safeOper = false;
- // It is not always safe to change the gtType of 'castOp1' to TYP_UBYTE
+ // It is not always safe to change the gtType of 'castOp1' to TYP_UBYTE.
// For example when 'castOp1Oper' is a GT_RSZ or GT_RSH then we are shifting
// bits from the left into the lower bits. If we change the type to a TYP_UBYTE
// we will instead generate a byte sized shift operation: shr al, 24
@@ -3196,22 +3659,24 @@ void Lowering::LowerCmp(GenTreePtr tree)
//
assert(!castOp1->gtOverflowEx()); // Must not be an overflow checking operation
- GenTreePtr removeTreeNode = op1;
- tree->gtOp.gtOp1 = castOp1;
- op1 = castOp1;
- castOp1->gtType = TYP_UBYTE;
-
- // trim down the value if castOp1 is an int constant since its type changed to UBYTE.
- if (castOp1Oper == GT_CNS_INT)
- {
- castOp1->gtIntCon.gtIconVal = (UINT8)castOp1->gtIntCon.gtIconVal;
- }
-
+ // TODO-Cleanup: we're within "if (CheckImmedAndMakeContained(tree, op2))", so isn't
+ // the following condition always true?
if (op2->isContainedIntOrIImmed())
{
ssize_t val = (ssize_t)op2->AsIntConCommon()->IconValue();
if (val >= 0 && val <= 255)
{
+ GenTreePtr removeTreeNode = op1;
+ tree->gtOp.gtOp1 = castOp1;
+ op1 = castOp1;
+ castOp1->gtType = TYP_UBYTE;
+
+ // trim down the value if castOp1 is an int constant since its type changed to UBYTE.
+ if (castOp1Oper == GT_CNS_INT)
+ {
+ castOp1->gtIntCon.gtIconVal = (UINT8)castOp1->gtIntCon.gtIconVal;
+ }
+
op2->gtType = TYP_UBYTE;
tree->gtFlags |= GTF_UNSIGNED;
@@ -3222,18 +3687,26 @@ void Lowering::LowerCmp(GenTreePtr tree)
MakeSrcContained(tree, op1);
op1IsMadeContained = true;
}
- }
- }
- BlockRange().Remove(removeTreeNode);
+ BlockRange().Remove(removeTreeNode);
+
+ // We've changed the type on op1 to TYP_UBYTE, but we already processed that node.
+ // We need to go back and mark it byteable.
+ // TODO-Cleanup: it might be better to move this out of the TreeNodeInfoInit pass to
+ // the earlier "lower" pass, in which case the byteable check would just fall out.
+ // But that is quite complex!
+ TreeNodeInfoInitCheckByteable(op1);
+
#ifdef DEBUG
- if (comp->verbose)
- {
- printf("LowerCmp: Removing a GT_CAST to TYP_UBYTE and changing castOp1->gtType to "
- "TYP_UBYTE\n");
- comp->gtDispTreeRange(BlockRange(), tree);
- }
+ if (comp->verbose)
+ {
+ printf("TreeNodeInfoInitCmp: Removing a GT_CAST to TYP_UBYTE and changing "
+ "castOp1->gtType to TYP_UBYTE\n");
+ comp->gtDispTreeRange(BlockRange(), tree);
+ }
#endif
+ }
+ }
}
}
@@ -3241,6 +3714,41 @@ void Lowering::LowerCmp(GenTreePtr tree)
if (!op1IsMadeContained)
{
SetRegOptional(op1);
+
+ // If op1 codegen sets ZF and SF flags and ==/!= against
+ // zero, we don't need to generate test instruction,
+ // provided we don't have another GenTree node between op1
+ // and tree that could potentially modify flags.
+ //
+ // TODO-CQ: right now the below peep is inexpensive and
+ // gets the benefit in most of cases because in majority
+ // of cases op1, op2 and tree would be in that order in
+ // execution. In general we should be able to check that all
+ // the nodes that come after op1 in execution order do not
+ // modify the flags so that it is safe to avoid generating a
+ // test instruction. Such a check requires that on each
+ // GenTree node we need to set the info whether its codegen
+ // will modify flags.
+ //
+ // TODO-CQ: We can optimize compare against zero in the
+ // following cases by generating the branch as indicated
+ // against each case.
+ // 1) unsigned compare
+ // < 0 - always FALSE
+ // <= 0 - ZF=1 and jne
+ // > 0 - ZF=0 and je
+ // >= 0 - always TRUE
+ //
+ // 2) signed compare
+ // < 0 - SF=1 and js
+ // >= 0 - SF=0 and jns
+ if (isEqualityCompare && op1->gtSetZSFlags() && op2->IsIntegralConst(0) && (op1->gtNext == op2) &&
+ (op2->gtNext == tree))
+ {
+ // Require codegen of op1 to set the flags.
+ assert(!op1->gtSetFlags());
+ op1->gtFlags |= GTF_SET_FLAGS;
+ }
}
}
}
@@ -3255,10 +3763,17 @@ void Lowering::LowerCmp(GenTreePtr tree)
{
MakeSrcContained(tree, op1);
}
+ else if (op1->IsCnsIntOrI())
+ {
+ // TODO-CQ: We should be able to support swapping op1 and op2 to generate cmp reg, imm,
+ // but there is currently an assert in CodeGen::genCompareInt().
+ // https://github.com/dotnet/coreclr/issues/7270
+ SetRegOptional(op2);
+ }
else
{
// One of op1 or op2 could be marked as reg optional
- // to indicate that codgen can still generate code
+ // to indicate that codegen can still generate code
// if one of them is on stack.
SetRegOptional(PreferredRegOptionalOperand(tree));
}
@@ -3318,7 +3833,6 @@ void Lowering::LowerCast(GenTree* tree)
var_types dstType = tree->CastToType();
var_types srcType = op1->TypeGet();
var_types tmpType = TYP_UNDEF;
- bool srcUns = false;
// force the srcType to unsigned if GT_UNSIGNED flag is set
if (tree->gtFlags & GTF_UNSIGNED)
@@ -3849,6 +4363,20 @@ bool Lowering::SetStoreIndOpCountsIfRMWMemOp(GenTreePtr storeInd)
}
m_lsra->clearOperandCounts(indirCandidateChild);
+#ifdef _TARGET_X86_
+ if (varTypeIsByte(storeInd))
+ {
+ // If storeInd is of TYP_BYTE, set indirOpSources to byteable registers.
+ bool containedNode = indirOpSource->gtLsraInfo.dstCount == 0;
+ if (!containedNode)
+ {
+ regMaskTP regMask = indirOpSource->gtLsraInfo.getSrcCandidates(m_lsra);
+ assert(regMask != RBM_NONE);
+ indirOpSource->gtLsraInfo.setSrcCandidates(m_lsra, regMask & ~RBM_NON_BYTE_REGS);
+ }
+ }
+#endif
+
return true;
}
@@ -3858,8 +4386,11 @@ bool Lowering::SetStoreIndOpCountsIfRMWMemOp(GenTreePtr storeInd)
*/
void Lowering::SetMulOpCounts(GenTreePtr tree)
{
+#if defined(_TARGET_X86_)
+ assert(tree->OperGet() == GT_MUL || tree->OperGet() == GT_MULHI || tree->OperGet() == GT_MUL_LONG);
+#else
assert(tree->OperGet() == GT_MUL || tree->OperGet() == GT_MULHI);
-
+#endif
TreeNodeInfo* info = &(tree->gtLsraInfo);
info->srcCount = 2;
@@ -3900,13 +4431,18 @@ void Lowering::SetMulOpCounts(GenTreePtr tree)
GenTreeIntConCommon* imm = nullptr;
GenTreePtr other = nullptr;
- // There are three forms of x86 multiply:
- // one-op form: RDX:RAX = RAX * r/m
- // two-op form: reg *= r/m
- // three-op form: reg = r/m * imm
+// There are three forms of x86 multiply:
+// one-op form: RDX:RAX = RAX * r/m
+// two-op form: reg *= r/m
+// three-op form: reg = r/m * imm
- // This special widening 32x32->64 MUL is not used on x64
- assert((tree->gtFlags & GTF_MUL_64RSLT) == 0);
+// This special widening 32x32->64 MUL is not used on x64
+#if defined(_TARGET_X86_)
+ if (tree->OperGet() != GT_MUL_LONG)
+#endif
+ {
+ assert((tree->gtFlags & GTF_MUL_64RSLT) == 0);
+ }
// Multiply should never be using small types
assert(!varTypeIsSmall(tree->TypeGet()));
@@ -3924,12 +4460,21 @@ void Lowering::SetMulOpCounts(GenTreePtr tree)
info->setDstCandidates(m_lsra, RBM_RAX);
hasImpliedFirstOperand = true;
}
- else if (tree->gtOper == GT_MULHI)
+ else if (tree->OperGet() == GT_MULHI)
+ {
+ // Have to use the encoding:RDX:RAX = RAX * rm. Since we only care about the
+ // upper 32 bits of the result set the destination candidate to REG_RDX.
+ info->setDstCandidates(m_lsra, RBM_RDX);
+ hasImpliedFirstOperand = true;
+ }
+#if defined(_TARGET_X86_)
+ else if (tree->OperGet() == GT_MUL_LONG)
{
// have to use the encoding:RDX:RAX = RAX * rm
info->setDstCandidates(m_lsra, RBM_RAX);
hasImpliedFirstOperand = true;
}
+#endif
else if (IsContainableImmed(tree, op2) || IsContainableImmed(tree, op1))
{
if (IsContainableImmed(tree, op2))
@@ -4187,6 +4732,71 @@ GenTree* Lowering::PreferredRegOptionalOperand(GenTree* tree)
return preferredOp;
}
+#ifdef _TARGET_X86_
+//------------------------------------------------------------------------
+// ExcludeNonByteableRegisters: Determines if we need to exclude non-byteable registers for
+// various reasons
+//
+// Arguments:
+// tree - The node of interest
+//
+// Return Value:
+// If we need to exclude non-byteable registers
+//
+bool Lowering::ExcludeNonByteableRegisters(GenTree* tree)
+{
+ // Example1: GT_STOREIND(byte, addr, op2) - storeind of byte sized value from op2 into mem 'addr'
+ // Storeind itself will not produce any value and hence dstCount=0. But op2 could be TYP_INT
+ // value. In this case we need to exclude esi/edi from the src candidates of op2.
+ if (varTypeIsByte(tree))
+ {
+ return true;
+ }
+ // Example2: GT_CAST(int <- bool <- int) - here type of GT_CAST node is int and castToType is bool.
+ else if ((tree->OperGet() == GT_CAST) && varTypeIsByte(tree->CastToType()))
+ {
+ return true;
+ }
+ else if (tree->OperIsCompare())
+ {
+ GenTree* op1 = tree->gtGetOp1();
+ GenTree* op2 = tree->gtGetOp2();
+
+ // Example3: GT_EQ(int, op1 of type ubyte, op2 of type ubyte) - in this case codegen uses
+ // ubyte as the result of comparison and if the result needs to be materialized into a reg
+ // simply zero extend it to TYP_INT size. Here is an example of generated code:
+ // cmp dl, byte ptr[addr mode]
+ // movzx edx, dl
+ if (varTypeIsByte(op1) && varTypeIsByte(op2))
+ {
+ return true;
+ }
+ // Example4: GT_EQ(int, op1 of type ubyte, op2 is GT_CNS_INT) - in this case codegen uses
+ // ubyte as the result of the comparison and if the result needs to be materialized into a reg
+ // simply zero extend it to TYP_INT size.
+ else if (varTypeIsByte(op1) && op2->IsCnsIntOrI())
+ {
+ return true;
+ }
+ // Example4: GT_EQ(int, op1 is GT_CNS_INT, op2 of type ubyte) - in this case codegen uses
+ // ubyte as the result of the comparison and if the result needs to be materialized into a reg
+ // simply zero extend it to TYP_INT size.
+ else if (op1->IsCnsIntOrI() && varTypeIsByte(op2))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+}
+#endif // _TARGET_X86_
+
#endif // _TARGET_XARCH_
#endif // !LEGACY_BACKEND
diff --git a/src/jit/lsra.cpp b/src/jit/lsra.cpp
index 317b976e42..accfd6ee78 100644
--- a/src/jit/lsra.cpp
+++ b/src/jit/lsra.cpp
@@ -355,6 +355,33 @@ RegRecord* LinearScan::getRegisterRecord(regNumber regNum)
}
#ifdef DEBUG
+
+//----------------------------------------------------------------------------
+// getConstrainedRegMask: Returns new regMask which is the intersection of
+// regMaskActual and regMaskConstraint if the new regMask has at least
+// minRegCount registers, otherwise returns regMaskActual.
+//
+// Arguments:
+// regMaskActual - regMask that needs to be constrained
+// regMaskConstraint - regMask constraint that needs to be
+// applied to regMaskActual
+// minRegCount - Minimum number of regs that should be
+// be present in new regMask.
+//
+// Return Value:
+// New regMask that has minRegCount registers after instersection.
+// Otherwise returns regMaskActual.
+regMaskTP LinearScan::getConstrainedRegMask(regMaskTP regMaskActual, regMaskTP regMaskConstraint, unsigned minRegCount)
+{
+ regMaskTP newMask = regMaskActual & regMaskConstraint;
+ if (genCountBits(newMask) >= minRegCount)
+ {
+ return newMask;
+ }
+
+ return regMaskActual;
+}
+
//------------------------------------------------------------------------
// stressLimitRegs: Given a set of registers, expressed as a register mask, reduce
// them based on the current stress options.
@@ -373,38 +400,46 @@ regMaskTP LinearScan::stressLimitRegs(RefPosition* refPosition, regMaskTP mask)
{
if (getStressLimitRegs() != LSRA_LIMIT_NONE)
{
+ // The refPosition could be null, for example when called
+ // by getTempRegForResolution().
+ int minRegCount = (refPosition != nullptr) ? refPosition->minRegCandidateCount : 1;
+
switch (getStressLimitRegs())
{
case LSRA_LIMIT_CALLEE:
- if (!compiler->opts.compDbgEnC && (mask & RBM_CALLEE_SAVED) != RBM_NONE)
+ if (!compiler->opts.compDbgEnC)
{
- mask &= RBM_CALLEE_SAVED;
+ mask = getConstrainedRegMask(mask, RBM_CALLEE_SAVED, minRegCount);
}
break;
+
case LSRA_LIMIT_CALLER:
- if ((mask & RBM_CALLEE_TRASH) != RBM_NONE)
- {
- mask &= RBM_CALLEE_TRASH;
- }
- break;
+ {
+ mask = getConstrainedRegMask(mask, RBM_CALLEE_TRASH, minRegCount);
+ }
+ break;
+
case LSRA_LIMIT_SMALL_SET:
if ((mask & LsraLimitSmallIntSet) != RBM_NONE)
{
- mask &= LsraLimitSmallIntSet;
+ mask = getConstrainedRegMask(mask, LsraLimitSmallIntSet, minRegCount);
}
else if ((mask & LsraLimitSmallFPSet) != RBM_NONE)
{
- mask &= LsraLimitSmallFPSet;
+ mask = getConstrainedRegMask(mask, LsraLimitSmallFPSet, minRegCount);
}
break;
+
default:
unreached();
}
+
if (refPosition != nullptr && refPosition->isFixedRegRef)
{
mask |= refPosition->registerAssignment;
}
}
+
return mask;
}
#endif // DEBUG
@@ -658,16 +693,13 @@ void LinearScan::applyCalleeSaveHeuristics(RefPosition* rp)
#endif // _TARGET_AMD64_
Interval* theInterval = rp->getInterval();
+
#ifdef DEBUG
regMaskTP calleeSaveMask = calleeSaveRegs(getRegisterType(theInterval, rp));
if (doReverseCallerCallee())
{
- regMaskTP newAssignment = rp->registerAssignment;
- newAssignment &= calleeSaveMask;
- if (newAssignment != RBM_NONE)
- {
- rp->registerAssignment = newAssignment;
- }
+ rp->registerAssignment =
+ getConstrainedRegMask(rp->registerAssignment, calleeSaveMask, rp->minRegCandidateCount);
}
else
#endif // DEBUG
@@ -777,6 +809,9 @@ RefPosition* LinearScan::newRefPosition(
// mask - Set of valid registers for this RefPosition
// multiRegIdx - register position if this RefPosition corresponds to a
// multi-reg call node.
+// minRegCount - Minimum number registers that needs to be ensured while
+// constraining candidates for this ref position under
+// LSRA stress. This is a DEBUG only arg.
//
// Return Value:
// a new RefPosition
@@ -786,7 +821,8 @@ RefPosition* LinearScan::newRefPosition(Interval* theInterval,
RefType theRefType,
GenTree* theTreeNode,
regMaskTP mask,
- unsigned multiRegIdx /* = 0 */)
+ unsigned multiRegIdx /* = 0 */
+ DEBUGARG(unsigned minRegCandidateCount /* = 1 */))
{
#ifdef DEBUG
if (theInterval != nullptr && regType(theInterval->registerType) == FloatRegisterType)
@@ -843,6 +879,10 @@ RefPosition* LinearScan::newRefPosition(Interval* theInterval,
newRP->setMultiRegIdx(multiRegIdx);
newRP->setAllocateIfProfitable(0);
+#ifdef DEBUG
+ newRP->minRegCandidateCount = minRegCandidateCount;
+#endif // DEBUG
+
associateRefPosWithInterval(newRP);
DBEXEC(VERBOSE, newRP->dump());
@@ -1071,12 +1111,14 @@ LinearScan::LinearScan(Compiler* theCompiler)
#endif
dumpTerse = (JitConfig.JitDumpTerseLsra() != 0);
-
#endif // DEBUG
+
availableIntRegs = (RBM_ALLINT & ~compiler->codeGen->regSet.rsMaskResvd);
+
#if ETW_EBP_FRAMED
availableIntRegs &= ~RBM_FPBASE;
#endif // ETW_EBP_FRAMED
+
availableFloatRegs = RBM_ALLFLOAT;
availableDoubleRegs = RBM_ALLDOUBLE;
@@ -1272,6 +1314,7 @@ void LinearScan::setBlockSequence()
bool addedInternalBlocks = false;
verifiedAllBBs = false;
+ hasCriticalEdges = false;
BasicBlock* nextBlock;
for (BasicBlock* block = compiler->fgFirstBB; block != nullptr; block = nextBlock)
{
@@ -1288,6 +1331,13 @@ void LinearScan::setBlockSequence()
blockInfo[block->bbNum].hasCriticalOutEdge = false;
blockInfo[block->bbNum].weight = block->bbWeight;
+#if TRACK_LSRA_STATS
+ blockInfo[block->bbNum].spillCount = 0;
+ blockInfo[block->bbNum].copyRegCount = 0;
+ blockInfo[block->bbNum].resolutionMovCount = 0;
+ blockInfo[block->bbNum].splitEdgeCount = 0;
+#endif // TRACK_LSRA_STATS
+
if (block->GetUniquePred(compiler) == nullptr)
{
for (flowList* pred = block->bbPreds; pred != nullptr; pred = pred->flNext)
@@ -1296,6 +1346,7 @@ void LinearScan::setBlockSequence()
if (predBlock->NumSucc(compiler) > 1)
{
blockInfo[block->bbNum].hasCriticalInEdge = true;
+ hasCriticalEdges = true;
break;
}
else if (predBlock->bbJumpKind == BBJ_SWITCH)
@@ -1321,6 +1372,7 @@ void LinearScan::setBlockSequence()
if (checkForCriticalOutEdge && succ->GetUniquePred(compiler) == nullptr)
{
blockInfo[block->bbNum].hasCriticalOutEdge = true;
+ hasCriticalEdges = true;
// We can stop checking now.
checkForCriticalOutEdge = false;
}
@@ -1666,11 +1718,6 @@ void LinearScan::doLinearScan()
compiler->codeGen->regSet.rsClearRegsModified();
- // Figure out if we're going to use an RSP frame or an RBP frame. We need to do this
- // before building the intervals and ref positions, because those objects will embed
- // RBP in various register masks (like preferences) if RBP is allowed to be allocated.
- setFrameType();
-
initMaxSpill();
buildIntervals();
DBEXEC(VERBOSE, TupleStyleDump(LSRA_DUMP_REFPOS));
@@ -1685,6 +1732,17 @@ void LinearScan::doLinearScan()
resolveRegisters();
compiler->EndPhase(PHASE_LINEAR_SCAN_RESOLVE);
+#if TRACK_LSRA_STATS
+ if ((JitConfig.DisplayLsraStats() != 0)
+#ifdef DEBUG
+ || VERBOSE
+#endif
+ )
+ {
+ dumpLsraStats(jitstdout);
+ }
+#endif // TRACK_LSRA_STATS
+
DBEXEC(VERBOSE, TupleStyleDump(LSRA_DUMP_POST));
compiler->compLSRADone = true;
@@ -1892,6 +1950,8 @@ void LinearScan::identifyCandidates()
// for vectors on Arm64, though the actual value may differ.
VarSetOps::AssignNoCopy(compiler, fpCalleeSaveCandidateVars, VarSetOps::MakeEmpty(compiler));
+ VarSetOps::AssignNoCopy(compiler, resolutionCandidateVars, VarSetOps::MakeEmpty(compiler));
+ VarSetOps::AssignNoCopy(compiler, splitOrSpilledVars, VarSetOps::MakeEmpty(compiler));
VARSET_TP VARSET_INIT_NOCOPY(fpMaybeCandidateVars, VarSetOps::MakeEmpty(compiler));
unsigned int floatVarCount = 0;
unsigned int thresholdFPRefCntWtd = 4 * BB_UNITY_WEIGHT;
@@ -1902,6 +1962,37 @@ void LinearScan::identifyCandidates()
unsigned int largeVectorVarCount = 0;
unsigned int thresholdLargeVectorRefCntWtd = 4 * BB_UNITY_WEIGHT;
#endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
+#if DOUBLE_ALIGN
+ unsigned refCntStk = 0;
+ unsigned refCntReg = 0;
+ unsigned refCntWtdReg = 0;
+ unsigned refCntStkParam = 0; // sum of ref counts for all stack based parameters
+ unsigned refCntWtdStkDbl = 0; // sum of wtd ref counts for stack based doubles
+ doDoubleAlign = false;
+ bool checkDoubleAlign = true;
+ if (compiler->codeGen->isFramePointerRequired() || compiler->opts.MinOpts())
+ {
+ checkDoubleAlign = false;
+ }
+ else
+ {
+ switch (compiler->getCanDoubleAlign())
+ {
+ case MUST_DOUBLE_ALIGN:
+ doDoubleAlign = true;
+ checkDoubleAlign = false;
+ break;
+ case CAN_DOUBLE_ALIGN:
+ break;
+ case CANT_DOUBLE_ALIGN:
+ doDoubleAlign = false;
+ checkDoubleAlign = false;
+ break;
+ default:
+ unreached();
+ }
+ }
+#endif // DOUBLE_ALIGN
for (lclNum = 0, varDsc = compiler->lvaTable; lclNum < compiler->lvaCount; lclNum++, varDsc++)
{
@@ -1911,6 +2002,32 @@ void LinearScan::identifyCandidates()
Interval* newInt = newInterval(intervalType);
newInt->setLocalNumber(lclNum, this);
+
+#if DOUBLE_ALIGN
+ if (checkDoubleAlign)
+ {
+ if (varDsc->lvIsParam && !varDsc->lvIsRegArg)
+ {
+ refCntStkParam += varDsc->lvRefCnt;
+ }
+ else if (!isRegCandidate(varDsc) || varDsc->lvDoNotEnregister)
+ {
+ refCntStk += varDsc->lvRefCnt;
+ if ((varDsc->lvType == TYP_DOUBLE) ||
+ ((varTypeIsStruct(varDsc) && varDsc->lvStructDoubleAlign &&
+ (compiler->lvaGetPromotionType(varDsc) != Compiler::PROMOTION_TYPE_INDEPENDENT))))
+ {
+ refCntWtdStkDbl += varDsc->lvRefCntWtd;
+ }
+ }
+ else
+ {
+ refCntReg += varDsc->lvRefCnt;
+ refCntWtdReg += varDsc->lvRefCntWtd;
+ }
+ }
+#endif // DOUBLE_ALIGN
+
if (varDsc->lvIsStructField)
{
newInt->isStructField = true;
@@ -2095,6 +2212,24 @@ void LinearScan::identifyCandidates()
}
}
+#if DOUBLE_ALIGN
+ if (checkDoubleAlign)
+ {
+ // TODO-CQ: Fine-tune this:
+ // In the legacy reg predictor, this runs after allocation, and then demotes any lclVars
+ // allocated to the frame pointer, which is probably the wrong order.
+ // However, because it runs after allocation, it can determine the impact of demoting
+ // the lclVars allocated to the frame pointer.
+ // => Here, estimate of the EBP refCnt and weighted refCnt is a wild guess.
+ //
+ unsigned refCntEBP = refCntReg / 8;
+ unsigned refCntWtdEBP = refCntWtdReg / 8;
+
+ doDoubleAlign =
+ compiler->shouldDoubleAlign(refCntStk, refCntEBP, refCntWtdEBP, refCntStkParam, refCntWtdStkDbl);
+ }
+#endif // DOUBLE_ALIGN
+
// The factors we consider to determine which set of fp vars to use as candidates for callee save
// registers current include the number of fp vars, whether there are loops, and whether there are
// multiple exits. These have been selected somewhat empirically, but there is probably room for
@@ -2510,6 +2645,9 @@ regMaskTP LinearScan::getKillSetForNode(GenTree* tree)
break;
case GT_MULHI:
+#if defined(_TARGET_X86_) && !defined(LEGACY_BACKEND)
+ case GT_MUL_LONG:
+#endif
killMask = RBM_RAX | RBM_RDX;
break;
@@ -2644,7 +2782,7 @@ regMaskTP LinearScan::getKillSetForNode(GenTree* tree)
}
break;
-#if defined(PROFILING_SUPPORTED) && defined(_TARGET_AMD64_)
+#if defined(PROFILING_SUPPORTED)
// If this method requires profiler ELT hook then mark these nodes as killing
// callee trash registers (excluding RAX and XMM0). The reason for this is that
// profiler callback would trash these registers. See vm\amd64\asmhelpers.asm for
@@ -2660,10 +2798,9 @@ regMaskTP LinearScan::getKillSetForNode(GenTree* tree)
if (compiler->compIsProfilerHookNeeded())
{
killMask = compiler->compHelperCallKillSet(CORINFO_HELP_PROF_FCN_TAILCALL);
- ;
}
break;
-#endif // PROFILING_SUPPORTED && _TARGET_AMD64_
+#endif // PROFILING_SUPPORTED
default:
// for all other 'tree->OperGet()' kinds, leave 'killMask' = RBM_NONE
@@ -2769,19 +2906,46 @@ bool LinearScan::buildKillPositionsForNode(GenTree* tree, LsraLocation currentLo
return false;
}
+//----------------------------------------------------------------------------
+// defineNewInternalTemp: Defines a ref position for an internal temp.
+//
+// Arguments:
+// tree - Gentree node requiring an internal register
+// regType - Register type
+// currentLoc - Location of the temp Def position
+// regMask - register mask of candidates for temp
+// minRegCandidateCount - Minimum registers to be ensured in candidate
+// set under LSRA stress mode. This is a
+// DEBUG only arg.
RefPosition* LinearScan::defineNewInternalTemp(GenTree* tree,
RegisterType regType,
LsraLocation currentLoc,
- regMaskTP regMask)
+ regMaskTP regMask DEBUGARG(unsigned minRegCandidateCount))
{
Interval* current = newInterval(regType);
current->isInternal = true;
- return newRefPosition(current, currentLoc, RefTypeDef, tree, regMask);
+ return newRefPosition(current, currentLoc, RefTypeDef, tree, regMask, 0 DEBUG_ARG(minRegCandidateCount));
}
+//------------------------------------------------------------------------
+// buildInternalRegisterDefsForNode - build Def positions for internal
+// registers required for tree node.
+//
+// Arguments:
+// tree - Gentree node that needs internal registers
+// currentLoc - Location at which Def positions need to be defined
+// temps - in-out array which is populated with ref positions
+// created for Def of internal registers
+// minRegCandidateCount - Minimum registers to be ensured in candidate
+// set of ref positions under LSRA stress. This is
+// a DEBUG only arg.
+//
+// Returns:
+// The total number of Def positions created for internal registers of tree node.
int LinearScan::buildInternalRegisterDefsForNode(GenTree* tree,
LsraLocation currentLoc,
- RefPosition* temps[]) // populates
+ RefPosition* temps[] // populates
+ DEBUGARG(unsigned minRegCandidateCount))
{
int count;
int internalIntCount = tree->gtLsraInfo.internalIntCount;
@@ -2805,14 +2969,16 @@ int LinearScan::buildInternalRegisterDefsForNode(GenTree* tree,
internalIntCands = genFindLowestBit(internalIntCands);
internalCands &= ~internalIntCands;
}
- temps[count] = defineNewInternalTemp(tree, IntRegisterType, currentLoc, internalIntCands);
+ temps[count] =
+ defineNewInternalTemp(tree, IntRegisterType, currentLoc, internalIntCands DEBUG_ARG(minRegCandidateCount));
}
int internalFloatCount = tree->gtLsraInfo.internalFloatCount;
for (int i = 0; i < internalFloatCount; i++)
{
regMaskTP internalFPCands = (internalCands & internalFloatRegCandidates());
- temps[count++] = defineNewInternalTemp(tree, FloatRegisterType, currentLoc, internalFPCands);
+ temps[count++] =
+ defineNewInternalTemp(tree, FloatRegisterType, currentLoc, internalFPCands DEBUG_ARG(minRegCandidateCount));
}
noway_assert(count < MaxInternalRegisters);
@@ -2820,10 +2986,26 @@ int LinearScan::buildInternalRegisterDefsForNode(GenTree* tree,
return count;
}
+//------------------------------------------------------------------------
+// buildInternalRegisterUsesForNode - adds Use positions for internal
+// registers required for tree node.
+//
+// Arguments:
+// tree - Gentree node that needs internal registers
+// currentLoc - Location at which Use positions need to be defined
+// defs - int array containing Def positions of internal
+// registers.
+// total - Total number of Def positions in 'defs' array.
+// minRegCandidateCount - Minimum registers to be ensured in candidate
+// set of ref positions under LSRA stress. This is
+// a DEBUG only arg.
+//
+// Returns:
+// Void.
void LinearScan::buildInternalRegisterUsesForNode(GenTree* tree,
LsraLocation currentLoc,
RefPosition* defs[],
- int total)
+ int total DEBUGARG(unsigned minRegCandidateCount))
{
assert(total < MaxInternalRegisters);
@@ -2840,8 +3022,14 @@ void LinearScan::buildInternalRegisterUsesForNode(GenTree* tree,
}
else
{
- RefPosition* newest = newRefPosition(defs[i]->getInterval(), currentLoc, RefTypeUse, tree, mask);
- newest->lastUse = true;
+ RefPosition* newest = newRefPosition(defs[i]->getInterval(), currentLoc, RefTypeUse, tree, mask,
+ 0 DEBUG_ARG(minRegCandidateCount));
+ newest->lastUse = true;
+
+ if (tree->gtLsraInfo.isInternalRegDelayFree)
+ {
+ newest->delayRegFree = true;
+ }
}
}
}
@@ -3196,10 +3384,10 @@ static int ComputeOperandDstCount(GenTree* operand)
// If an operand has no destination registers but does have source registers, it must be a store
// or a compare.
assert(operand->OperIsStore() || operand->OperIsBlkOp() || operand->OperIsPutArgStk() ||
- operand->OperIsCompare());
+ operand->OperIsCompare() || operand->IsSIMDEqualityOrInequality());
return 0;
}
- else if (!operand->OperIsAggregate() && (operand->OperIsStore() || operand->TypeGet() == TYP_VOID))
+ else if (!operand->OperIsFieldListHead() && (operand->OperIsStore() || operand->TypeGet() == TYP_VOID))
{
// Stores and void-typed operands may be encountered when processing call nodes, which contain
// pointers to argument setup stores.
@@ -3207,7 +3395,7 @@ static int ComputeOperandDstCount(GenTree* operand)
}
else
{
- // If an aggregate or non-void-typed operand is not an unsued value and does not have source registers,
+ // If a field list or non-void-typed operand is not an unused value and does not have source registers,
// that argument is contained within its parent and produces `sum(operand_dst_count)` registers.
int dstCount = 0;
for (GenTree* op : operand->Operands())
@@ -3254,16 +3442,14 @@ void LinearScan::buildRefPositionsForNode(GenTree* tree,
assert(!isRegPairType(tree->TypeGet()));
#endif // _TARGET_ARM_
- // The LIR traversal doesn't visit non-aggregate GT_LIST or GT_ARGPLACE nodes
+ // The LIR traversal doesn't visit GT_LIST or GT_ARGPLACE nodes.
+ // GT_CLS_VAR nodes should have been eliminated by rationalizer.
assert(tree->OperGet() != GT_ARGPLACE);
- assert((tree->OperGet() != GT_LIST) || tree->AsArgList()->IsAggregate());
+ assert(tree->OperGet() != GT_LIST);
+ assert(tree->OperGet() != GT_CLS_VAR);
- // These nodes are eliminated by the Rationalizer.
- if (tree->OperGet() == GT_CLS_VAR)
- {
- JITDUMP("Unexpected node %s in LSRA.\n", GenTree::NodeName(tree->OperGet()));
- assert(!"Unexpected node in LSRA.");
- }
+ // The LIR traversal visits only the first node in a GT_FIELD_LIST.
+ assert((tree->OperGet() != GT_FIELD_LIST) || tree->AsFieldList()->IsFieldListHead());
// The set of internal temporary registers used by this node are stored in the
// gtRsvdRegs register mask. Clear it out.
@@ -3409,7 +3595,7 @@ void LinearScan::buildRefPositionsForNode(GenTree* tree,
{
// Get the location info for the register defined by the first operand.
LocationInfoList operandDefs;
- bool found = operandToLocationInfoMap.TryGetValue(*(tree->OperandsBegin()), &operandDefs);
+ bool found = operandToLocationInfoMap.TryGetValue(*(tree->OperandsBegin()), &operandDefs);
assert(found);
// Since we only expect to consume one register, we should only have a single register to
@@ -3503,7 +3689,51 @@ void LinearScan::buildRefPositionsForNode(GenTree* tree,
// (i.e. the target is read-modify-write), preference the dst to op1.
bool hasDelayFreeSrc = tree->gtLsraInfo.hasDelayFreeSrc;
- if (tree->OperGet() == GT_PUTARG_REG && isCandidateLocalRef(tree->gtGetOp1()) &&
+
+#if defined(DEBUG) && defined(_TARGET_X86_)
+ // On x86, `LSRA_LIMIT_CALLER` is too restrictive to allow the use of special put args: this stress mode
+ // leaves only three registers allocatable--eax, ecx, and edx--of which the latter two are also used for the
+ // first two integral arguments to a call. This can leave us with too few registers to succesfully allocate in
+ // situations like the following:
+ //
+ // t1026 = lclVar ref V52 tmp35 u:3 REG NA <l:$3a1, c:$98d>
+ //
+ // /--* t1026 ref
+ // t1352 = * putarg_reg ref REG NA
+ //
+ // t342 = lclVar int V14 loc6 u:4 REG NA $50c
+ //
+ // t343 = const int 1 REG NA $41
+ //
+ // /--* t342 int
+ // +--* t343 int
+ // t344 = * + int REG NA $495
+ //
+ // t345 = lclVar int V04 arg4 u:2 REG NA $100
+ //
+ // /--* t344 int
+ // +--* t345 int
+ // t346 = * % int REG NA $496
+ //
+ // /--* t346 int
+ // t1353 = * putarg_reg int REG NA
+ //
+ // t1354 = lclVar ref V52 tmp35 (last use) REG NA
+ //
+ // /--* t1354 ref
+ // t1355 = * lea(b+0) byref REG NA
+ //
+ // Here, the first `putarg_reg` would normally be considered a special put arg, which would remove `ecx` from the
+ // set of allocatable registers, leaving only `eax` and `edx`. The allocator will then fail to allocate a register
+ // for the def of `t345` if arg4 is not a register candidate: the corresponding ref position will be constrained to
+ // { `ecx`, `ebx`, `esi`, `edi` }, which `LSRA_LIMIT_CALLER` will further constrain to `ecx`, which will not be
+ // available due to the special put arg.
+ const bool supportsSpecialPutArg = getStressLimitRegs() != LSRA_LIMIT_CALLER;
+#else
+ const bool supportsSpecialPutArg = true;
+#endif
+
+ if (supportsSpecialPutArg && tree->OperGet() == GT_PUTARG_REG && isCandidateLocalRef(tree->gtGetOp1()) &&
(tree->gtGetOp1()->gtFlags & GTF_VAR_DEATH) == 0)
{
// This is the case for a "pass-through" copy of a lclVar. In the case where it is a non-last-use,
@@ -3525,9 +3755,17 @@ void LinearScan::buildRefPositionsForNode(GenTree* tree,
RefPosition* internalRefs[MaxInternalRegisters];
+#ifdef DEBUG
+ // Number of registers required for tree node is the sum of
+ // consume + produce + internalCount. This is the minimum
+ // set of registers that needs to be ensured in candidate
+ // set of ref positions created.
+ unsigned minRegCount = consume + produce + info.internalIntCount + info.internalFloatCount;
+#endif // DEBUG
+
// make intervals for all the 'internal' register requirements for this node
// where internal means additional registers required temporarily
- int internalCount = buildInternalRegisterDefsForNode(tree, currentLoc, internalRefs);
+ int internalCount = buildInternalRegisterDefsForNode(tree, currentLoc, internalRefs DEBUG_ARG(minRegCount));
// pop all ref'd tree temps
GenTreeOperandIterator iterator = tree->OperandsBegin();
@@ -3632,6 +3870,37 @@ void LinearScan::buildRefPositionsForNode(GenTree* tree,
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
+ // consuming node to minRegCount.
+ //
+ // For example consider the following IR on x86, where v01 and v02
+ // are method args coming in ecx and edx respectively.
+ // GT_DIV(v01, v02)
+ //
+ // For GT_DIV minRegCount will be 3 without adding kill set
+ // of GT_DIV node.
+ //
+ // Assume further JitStressRegs=2, which would constrain
+ // candidates to callee trashable regs { eax, ecx, edx } on
+ // use positions of v01 and v02. LSRA allocates ecx for v01.
+ // Use position of v02 cannot be allocated a regs since it
+ // is marked delay-reg free and {eax,edx} are getting killed
+ // before the def of GT_DIV. For this reason, minRegCount
+ // for Use position of v02 also needs to take into account
+ // of kill set of its consuming node.
+ unsigned minRegCountForUsePos = minRegCount;
+ if (delayRegFree)
+ {
+ regMaskTP killMask = getKillSetForNode(tree);
+ if (killMask != RBM_NONE)
+ {
+ minRegCountForUsePos += genCountBits(killMask);
+ }
+ }
+#endif // DEBUG
+
RefPosition* pos;
if ((candidates & allRegs(i->registerType)) == 0)
{
@@ -3645,13 +3914,16 @@ void LinearScan::buildRefPositionsForNode(GenTree* tree,
regNumber physicalReg = genRegNumFromMask(fixedAssignment);
RefPosition* pos = newRefPosition(physicalReg, currentLoc, RefTypeFixedReg, nullptr, fixedAssignment);
}
- pos = newRefPosition(i, currentLoc, RefTypeUse, useNode, allRegs(i->registerType), multiRegIdx);
+ pos = newRefPosition(i, currentLoc, RefTypeUse, useNode, allRegs(i->registerType),
+ multiRegIdx DEBUG_ARG(minRegCountForUsePos));
pos->registerAssignment = candidates;
}
else
{
- pos = newRefPosition(i, currentLoc, RefTypeUse, useNode, candidates, multiRegIdx);
+ pos = newRefPosition(i, currentLoc, RefTypeUse, useNode, candidates,
+ multiRegIdx DEBUG_ARG(minRegCountForUsePos));
}
+
if (delayRegFree)
{
hasDelayFreeSrc = true;
@@ -3675,7 +3947,7 @@ void LinearScan::buildRefPositionsForNode(GenTree* tree,
listNodePool.ReturnNodes(operandDefs);
}
- buildInternalRegisterUsesForNode(tree, currentLoc, internalRefs, internalCount);
+ buildInternalRegisterUsesForNode(tree, currentLoc, internalRefs, internalCount DEBUG_ARG(minRegCount));
RegisterType registerType = getDefType(tree);
regMaskTP candidates = getDefCandidates(tree);
@@ -3708,7 +3980,7 @@ void LinearScan::buildRefPositionsForNode(GenTree* tree,
{
// Build RefPositions for saving any live large vectors.
// This must be done after the kills, so that we know which large vectors are still live.
- VarSetOps::AssignNoCopy(compiler, liveLargeVectors, buildUpperVectorSaveRefPositions(tree, currentLoc));
+ VarSetOps::AssignNoCopy(compiler, liveLargeVectors, buildUpperVectorSaveRefPositions(tree, currentLoc + 1));
}
#endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
@@ -3779,7 +4051,8 @@ void LinearScan::buildRefPositionsForNode(GenTree* tree,
locationInfoList.Append(listNodePool.GetNode(defLocation, interval, tree, (unsigned)i));
}
- RefPosition* pos = newRefPosition(interval, defLocation, defRefType, defNode, currCandidates, (unsigned)i);
+ RefPosition* pos = newRefPosition(interval, defLocation, defRefType, defNode, currCandidates,
+ (unsigned)i DEBUG_ARG(minRegCount));
if (info.isLocalDefUse)
{
pos->isLocalDefUse = true;
@@ -3791,11 +4064,12 @@ void LinearScan::buildRefPositionsForNode(GenTree* tree,
}
#if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
- buildUpperVectorRestoreRefPositions(tree, currentLoc, liveLargeVectors);
+ // SaveDef position must be at the same location as Def position of call node.
+ buildUpperVectorRestoreRefPositions(tree, defLocation, liveLargeVectors);
#endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
- bool isContainedNode =
- !noAdd && consume == 0 && produce == 0 && (tree->OperIsAggregate() || (tree->TypeGet() != TYP_VOID && !tree->OperIsStore()));
+ 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.
@@ -3852,6 +4126,22 @@ BasicBlock* getNonEmptyBlock(BasicBlock* block)
return block;
}
+//------------------------------------------------------------------------
+// insertZeroInitRefPositions: Handle lclVars that are live-in to the first block
+//
+// Notes:
+// For each lclVar that is live-in to the first block:
+// - If it is a GC ref, or if compInitMem is set, a ZeroInit RefPosition will be created.
+// - Otherwise, it will be marked as spilled, since it will not be assigned a register
+// on entry and will be loaded from memory on the undefined path.
+// Note that, when the compInitMem option is not set, we may encounter these on
+// paths that are protected by the same condition as an earlier def. However, since
+// we don't do the analysis to determine this - and couldn't rely on always identifying
+// such cases even if we tried - we must conservatively treat the undefined path as
+// being possible. This is a relatively rare case, so the introduced conservatism is
+// not expected to warrant the analysis required to determine the best placement of
+// an initialization.
+//
void LinearScan::insertZeroInitRefPositions()
{
// insert defs for this, then a block boundary
@@ -3861,15 +4151,23 @@ void LinearScan::insertZeroInitRefPositions()
{
unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
LclVarDsc* varDsc = compiler->lvaTable + varNum;
- if (!varDsc->lvIsParam && isCandidateVar(varDsc) &&
- (compiler->info.compInitMem || varTypeIsGC(varDsc->TypeGet())))
+ if (!varDsc->lvIsParam && isCandidateVar(varDsc))
{
- GenTree* firstNode = getNonEmptyBlock(compiler->fgFirstBB)->firstNode();
- JITDUMP("V%02u was live in\n", varNum);
- Interval* interval = getIntervalForLocalVar(varNum);
- RefPosition* pos =
- newRefPosition(interval, MinLocation, RefTypeZeroInit, firstNode, allRegs(interval->registerType));
- varDsc->lvMustInit = true;
+ JITDUMP("V%02u was live in to first block:", varNum);
+ Interval* interval = getIntervalForLocalVar(varNum);
+ if (compiler->info.compInitMem || varTypeIsGC(varDsc->TypeGet()))
+ {
+ JITDUMP(" creating ZeroInit\n");
+ GenTree* firstNode = getNonEmptyBlock(compiler->fgFirstBB)->firstNode();
+ RefPosition* pos =
+ newRefPosition(interval, MinLocation, RefTypeZeroInit, firstNode, allRegs(interval->registerType));
+ varDsc->lvMustInit = true;
+ }
+ else
+ {
+ setIntervalAsSpilled(interval);
+ JITDUMP(" marking as spilled\n");
+ }
}
}
}
@@ -4131,8 +4429,20 @@ void LinearScan::buildIntervals()
}
#endif // DEBUG
+#if DOUBLE_ALIGN
+ // We will determine whether we should double align the frame during
+ // identifyCandidates(), but we initially assume that we will not.
+ doDoubleAlign = false;
+#endif
+
identifyCandidates();
+ // Figure out if we're going to use a frame pointer. We need to do this before building
+ // the ref positions, because those objects will embed the frame register in various register masks
+ // if the frame pointer is not reserved. If we decide to have a frame pointer, setFrameType() will
+ // remove the frame pointer from the masks.
+ setFrameType();
+
DBEXEC(VERBOSE, TupleStyleDump(LSRA_DUMP_PRE));
// second part:
@@ -4263,6 +4573,9 @@ void LinearScan::buildIntervals()
insertZeroInitRefPositions();
}
+ // Any lclVars live-in to a block are resolution candidates.
+ VarSetOps::UnionD(compiler, resolutionCandidateVars, block->bbLiveIn);
+
// Determine if we need any DummyDefs.
// We need DummyDefs for cases where "predBlock" isn't really a predecessor.
// Note that it's possible to have uses of unitialized variables, in which case even the first
@@ -4274,8 +4587,8 @@ void LinearScan::buildIntervals()
VARSET_TP VARSET_INIT(compiler, newLiveIn, block->bbLiveIn);
if (predBlock)
{
- JITDUMP("\n\nSetting incoming variable registers of BB%02u to outVarToRegMap of BB%02u\n", block->bbNum,
- predBlock->bbNum);
+ JITDUMP("\n\nSetting BB%02u as the predecessor for determining incoming variable registers of BB%02u\n",
+ block->bbNum, predBlock->bbNum);
assert(predBlock->bbNum <= bbNumMaxBeforeResolution);
blockInfo[block->bbNum].predBBNum = predBlock->bbNum;
// Compute set difference: newLiveIn = block->bbLiveIn - predBlock->bbLiveOut
@@ -4534,7 +4847,16 @@ void LinearScan::validateIntervals()
void LinearScan::setFrameType()
{
FrameType frameType = FT_NOT_SET;
- if (compiler->codeGen->isFramePointerRequired())
+#if DOUBLE_ALIGN
+ compiler->codeGen->setDoubleAlign(false);
+ if (doDoubleAlign)
+ {
+ frameType = FT_DOUBLE_ALIGN_FRAME;
+ compiler->codeGen->setDoubleAlign(true);
+ }
+ else
+#endif // DOUBLE_ALIGN
+ if (compiler->codeGen->isFramePointerRequired())
{
frameType = FT_EBP_FRAME;
}
@@ -4563,22 +4885,6 @@ void LinearScan::setFrameType()
}
}
-#if DOUBLE_ALIGN
- // The DOUBLE_ALIGN feature indicates whether the JIT will attempt to double-align the
- // frame if needed. Note that this feature isn't on for amd64, because the stack is
- // always double-aligned by default.
- compiler->codeGen->setDoubleAlign(false);
-
- // TODO-CQ: Tune this (see regalloc.cpp, in which raCntWtdStkDblStackFP is used to
- // determine whether to double-align). Note, though that there is at least one test
- // (jit\opt\Perf\DoubleAlign\Locals.exe) that depends on double-alignment being set
- // in certain situations.
- if (!compiler->opts.MinOpts() && !compiler->codeGen->isFramePointerRequired() && compiler->compFloatingPointUsed)
- {
- frameType = FT_DOUBLE_ALIGN_FRAME;
- }
-#endif // DOUBLE_ALIGN
-
switch (frameType)
{
case FT_ESP_FRAME:
@@ -4593,7 +4899,6 @@ void LinearScan::setFrameType()
case FT_DOUBLE_ALIGN_FRAME:
noway_assert(!compiler->codeGen->isFramePointerRequired());
compiler->codeGen->setFramePointerUsed(false);
- compiler->codeGen->setDoubleAlign(true);
break;
#endif // DOUBLE_ALIGN
default:
@@ -4625,11 +4930,11 @@ void LinearScan::setFrameType()
compiler->rpFrameType = frameType;
}
-// Is the copyReg given by this RefPosition still busy at the
+// Is the copyReg/moveReg given by this RefPosition still busy at the
// given location?
-bool copyRegInUse(RefPosition* ref, LsraLocation loc)
+bool copyOrMoveRegInUse(RefPosition* ref, LsraLocation loc)
{
- assert(ref->copyReg);
+ assert(ref->copyReg || ref->moveReg);
if (ref->getRefEndLocation() >= loc)
{
return true;
@@ -4689,14 +4994,15 @@ bool LinearScan::registerIsAvailable(RegRecord* physRegRecord,
return false;
}
- // Is this a copyReg? It is if the register assignment doesn't match.
- // (the recentReference may not be a copyReg, because we could have seen another
- // reference since the copyReg)
+ // Is this a copyReg/moveReg? It is if the register assignment doesn't match.
+ // (the recentReference may not be a copyReg/moveReg, because we could have seen another
+ // reference since the copyReg/moveReg)
if (!assignedInterval->isAssignedTo(physRegRecord->regNum))
{
// Don't reassign it if it's still in use
- if (recentReference->copyReg && copyRegInUse(recentReference, currentLoc))
+ if ((recentReference->copyReg || recentReference->moveReg) &&
+ copyOrMoveRegInUse(recentReference, currentLoc))
{
return false;
}
@@ -5393,8 +5699,17 @@ regNumber LinearScan::allocateBusyReg(Interval* current, RefPosition* refPositio
// to remain live until the use, we should set the candidates to allRegs(regType)
// to avoid a spill - codegen can then insert the copy.
assert(candidates == candidateBit);
- physRegNextLocation = MaxLocation;
- farthestRefPosWeight = BB_MAX_WEIGHT;
+
+ // If a refPosition has a fixed reg as its candidate and is also marked
+ // as allocateIfProfitable, we should allocate fixed reg only if the
+ // weight of this ref position is greater than the weight of the ref
+ // position to which fixed reg is assigned. Such a case would arise
+ // on x86 under LSRA stress.
+ if (!allocateIfProfitable)
+ {
+ physRegNextLocation = MaxLocation;
+ farthestRefPosWeight = BB_MAX_WEIGHT;
+ }
}
else
{
@@ -5487,13 +5802,14 @@ regNumber LinearScan::allocateBusyReg(Interval* current, RefPosition* refPositio
}
}
- LsraLocation nextLocation = assignedInterval->getNextRefLocation();
+ RefPosition* nextRefPosition = assignedInterval->getNextRefPosition();
+ LsraLocation nextLocation = assignedInterval->getNextRefLocation();
// We should never spill a register that's occupied by an Interval with its next use at the current location.
// Normally this won't occur (unless we actually had more uses in a single node than there are registers),
// because we'll always find something with a later nextLocation, but it can happen in stress when
// we have LSRA_SELECT_NEAREST.
- if ((nextLocation == refLocation) && !refPosition->isFixedRegRef)
+ if ((nextLocation == refLocation) && !refPosition->isFixedRegRef && nextRefPosition->RequiresRegister())
{
continue;
}
@@ -5578,7 +5894,17 @@ regNumber LinearScan::allocateBusyReg(Interval* current, RefPosition* refPositio
else
{
// Must have found a spill candidate.
- assert((farthestRefPhysRegRecord != nullptr) && (farthestLocation > refLocation || refPosition->isFixedRegRef));
+ assert(farthestRefPhysRegRecord != nullptr);
+ if ((farthestLocation == refLocation) && !refPosition->isFixedRegRef)
+ {
+ Interval* assignedInterval = farthestRefPhysRegRecord->assignedInterval;
+ RefPosition* nextRefPosition = assignedInterval->getNextRefPosition();
+ assert(!nextRefPosition->RequiresRegister());
+ }
+ else
+ {
+ assert(farthestLocation > refLocation || refPosition->isFixedRegRef);
+ }
}
#endif
@@ -5699,6 +6025,70 @@ void LinearScan::assignPhysReg(RegRecord* regRec, Interval* interval)
}
//------------------------------------------------------------------------
+// setIntervalAsSplit: Set this Interval as being split
+//
+// Arguments:
+// interval - The Interval which is being split
+//
+// Return Value:
+// None.
+//
+// Notes:
+// The given Interval will be marked as split, and it will be added to the
+// set of splitOrSpilledVars.
+//
+// Assumptions:
+// "interval" must be a lclVar interval, as tree temps are never split.
+// This is asserted in the call to getVarIndex().
+//
+void LinearScan::setIntervalAsSplit(Interval* interval)
+{
+ if (interval->isLocalVar)
+ {
+ unsigned varIndex = interval->getVarIndex(compiler);
+ if (!interval->isSplit)
+ {
+ VarSetOps::AddElemD(compiler, splitOrSpilledVars, varIndex);
+ }
+ else
+ {
+ assert(VarSetOps::IsMember(compiler, splitOrSpilledVars, varIndex));
+ }
+ }
+ interval->isSplit = true;
+}
+
+//------------------------------------------------------------------------
+// setIntervalAsSpilled: Set this Interval as being spilled
+//
+// Arguments:
+// interval - The Interval which is being spilled
+//
+// Return Value:
+// None.
+//
+// Notes:
+// The given Interval will be marked as spilled, and it will be added
+// to the set of splitOrSpilledVars.
+//
+void LinearScan::setIntervalAsSpilled(Interval* interval)
+{
+ if (interval->isLocalVar)
+ {
+ unsigned varIndex = interval->getVarIndex(compiler);
+ if (!interval->isSpilled)
+ {
+ VarSetOps::AddElemD(compiler, splitOrSpilledVars, varIndex);
+ }
+ else
+ {
+ assert(VarSetOps::IsMember(compiler, splitOrSpilledVars, varIndex));
+ }
+ }
+ interval->isSpilled = true;
+}
+
+//------------------------------------------------------------------------
// spill: Spill this Interval between "fromRefPosition" and "toRefPosition"
//
// Arguments:
@@ -5739,8 +6129,10 @@ void LinearScan::spillInterval(Interval* interval, RefPosition* fromRefPosition,
}
#endif // DEBUG
- interval->isActive = false;
- interval->isSpilled = true;
+ INTRACK_STATS(updateLsraStat(LSRA_STAT_SPILL, fromRefPosition->bbNum));
+
+ interval->isActive = false;
+ setIntervalAsSpilled(interval);
// If fromRefPosition occurs before the beginning of this block, mark this as living in the stack
// on entry to this block.
@@ -5923,7 +6315,7 @@ void LinearScan::unassignPhysReg(RegRecord* regRec, RefPosition* spillRefPositio
setInVarRegForBB(curBBNum, assignedInterval->varNum, REG_STK);
if (spillRefPosition->nextRefPosition != nullptr)
{
- assignedInterval->isSpilled = true;
+ setIntervalAsSpilled(assignedInterval);
}
}
else
@@ -5945,7 +6337,8 @@ void LinearScan::unassignPhysReg(RegRecord* regRec, RefPosition* spillRefPositio
{
assignedInterval->assignedReg = regRec;
}
- else if (regRec->previousInterval != nullptr && regRec->previousInterval->assignedReg == regRec &&
+ else if (regRec->previousInterval != nullptr && regRec->previousInterval != assignedInterval &&
+ regRec->previousInterval->assignedReg == regRec &&
regRec->previousInterval->getNextRefPosition() != nullptr)
{
regRec->assignedInterval = regRec->previousInterval;
@@ -6128,7 +6521,14 @@ void LinearScan::processBlockStartLocations(BasicBlock* currentBlock, bool alloc
if (allocationPass)
{
targetReg = predVarToRegMap[varIndex];
- INDEBUG(targetReg = rotateBlockStartLocation(interval, targetReg, (~liveRegs | inactiveRegs)));
+#ifdef DEBUG
+ regNumber newTargetReg = rotateBlockStartLocation(interval, targetReg, (~liveRegs | inactiveRegs));
+ if (newTargetReg != targetReg)
+ {
+ targetReg = newTargetReg;
+ setIntervalAsSplit(interval);
+ }
+#endif // DEBUG
inVarToRegMap[varIndex] = targetReg;
}
else // !allocationPass (i.e. resolution/write-back pass)
@@ -6686,6 +7086,7 @@ void LinearScan::allocateRegisters()
INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_NO_ENTRY_REG_ALLOCATED, currentInterval));
didDump = true;
allocate = false;
+ setIntervalAsSpilled(currentInterval);
}
// If it has no actual references, mark it as "lastUse"; since they're not actually part
// of any flow they won't have been marked during dataflow. Otherwise, if we allocate a
@@ -6912,6 +7313,7 @@ void LinearScan::allocateRegisters()
}
currentRefPosition->moveReg = true;
assignedRegister = REG_NA;
+ setIntervalAsSplit(currentInterval);
INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_MOVE_REG, currentInterval, assignedRegister));
}
else if ((genRegMask(assignedRegister) & currentRefPosition->registerAssignment) != 0)
@@ -6936,65 +7338,47 @@ void LinearScan::allocateRegisters()
}
else
{
- // This must be a localVar or a single-reg fixed use or a tree temp with conflicting def & use.
-
- assert(currentInterval && (currentInterval->isLocalVar || currentRefPosition->isFixedRegRef ||
- currentInterval->hasConflictingDefUse));
+ assert(currentInterval != nullptr);
// It's already in a register, but not one we need.
- // If it is a fixed use that is not marked "delayRegFree", there is already a FixedReg to ensure that
- // the needed reg is not otherwise in use, so we can simply ignore it and codegen will do the copy.
- // The reason we need special handling for the "delayRegFree" case is that we need to mark the
- // fixed-reg as in-use and delayed (the FixedReg RefPosition doesn't handle the delay requirement).
- // Otherwise, if this is a pure use localVar or tree temp, we assign a copyReg, but must free both regs
- // if it is a last use.
- if (!currentRefPosition->isFixedRegRef || currentRefPosition->delayRegFree)
- {
- if (!RefTypeIsDef(currentRefPosition->refType))
+ if (!RefTypeIsDef(currentRefPosition->refType))
+ {
+ regNumber copyReg = assignCopyReg(currentRefPosition);
+ assert(copyReg != REG_NA);
+ INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_COPY_REG, currentInterval, copyReg));
+ lastAllocatedRefPosition = currentRefPosition;
+ if (currentRefPosition->lastUse)
{
- regNumber copyReg = assignCopyReg(currentRefPosition);
- assert(copyReg != REG_NA);
- INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_COPY_REG, currentInterval, copyReg));
- lastAllocatedRefPosition = currentRefPosition;
- if (currentRefPosition->lastUse)
+ if (currentRefPosition->delayRegFree)
{
- if (currentRefPosition->delayRegFree)
- {
- INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_LAST_USE_DELAYED, currentInterval,
- assignedRegister));
- delayRegsToFree |=
- (genRegMask(assignedRegister) | currentRefPosition->registerAssignment);
- }
- else
- {
- INDEBUG(
- dumpLsraAllocationEvent(LSRA_EVENT_LAST_USE, currentInterval, assignedRegister));
- regsToFree |= (genRegMask(assignedRegister) | currentRefPosition->registerAssignment);
- }
+ INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_LAST_USE_DELAYED, currentInterval,
+ assignedRegister));
+ delayRegsToFree |= (genRegMask(assignedRegister) | currentRefPosition->registerAssignment);
}
- // If this is a tree temp (non-localVar) interval, we will need an explicit move.
- if (!currentInterval->isLocalVar)
+ else
{
- currentRefPosition->moveReg = true;
- currentRefPosition->copyReg = false;
+ INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_LAST_USE, currentInterval, assignedRegister));
+ regsToFree |= (genRegMask(assignedRegister) | currentRefPosition->registerAssignment);
}
- continue;
}
- else
+ // If this is a tree temp (non-localVar) interval, we will need an explicit move.
+ if (!currentInterval->isLocalVar)
{
- INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_NEEDS_NEW_REG, nullptr, assignedRegister));
- regsToFree |= genRegMask(assignedRegister);
- // We want a new register, but we don't want this to be considered a spill.
- assignedRegister = REG_NA;
- if (physRegRecord->assignedInterval == currentInterval)
- {
- unassignPhysRegNoSpill(physRegRecord);
- }
+ currentRefPosition->moveReg = true;
+ currentRefPosition->copyReg = false;
}
+ continue;
}
else
{
- INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_KEPT_ALLOCATION, nullptr, assignedRegister));
+ INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_NEEDS_NEW_REG, nullptr, assignedRegister));
+ regsToFree |= genRegMask(assignedRegister);
+ // We want a new register, but we don't want this to be considered a spill.
+ assignedRegister = REG_NA;
+ if (physRegRecord->assignedInterval == currentInterval)
+ {
+ unassignPhysRegNoSpill(physRegRecord);
+ }
}
}
}
@@ -7031,23 +7415,39 @@ void LinearScan::allocateRegisters()
// then find a register to spill
if (assignedRegister == REG_NA)
{
-#ifdef FEATURE_SIMD
+#if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
if (refType == RefTypeUpperVectorSaveDef)
{
// TODO-CQ: Determine whether copying to two integer callee-save registers would be profitable.
- currentRefPosition->registerAssignment = (allRegs(TYP_FLOAT) & RBM_FLT_CALLEE_TRASH);
- assignedRegister = tryAllocateFreeReg(currentInterval, currentRefPosition);
+
+ // SaveDef position occurs after the Use of args and at the same location as Kill/Def
+ // positions of a call node. But SaveDef position cannot use any of the arg regs as
+ // they are needed for call node.
+ currentRefPosition->registerAssignment =
+ (allRegs(TYP_FLOAT) & RBM_FLT_CALLEE_TRASH & ~RBM_FLTARG_REGS);
+ assignedRegister = tryAllocateFreeReg(currentInterval, currentRefPosition);
+
// There MUST be caller-save registers available, because they have all just been killed.
+ // Amd64 Windows: xmm4-xmm5 are guaranteed to be available as xmm0-xmm3 are used for passing args.
+ // Amd64 Unix: xmm8-xmm15 are guaranteed to be avilable as xmm0-xmm7 are used for passing args.
+ // X86 RyuJIT Windows: xmm4-xmm7 are guanrateed to be available.
assert(assignedRegister != REG_NA);
+
// Now, spill it.
- // (These will look a bit backward in the dump, but it's a pain to dump the alloc before the spill).
+ // Note:
+ // i) The reason we have to spill is that SaveDef position is allocated after the Kill positions
+ // of the call node are processed. Since callee-trash registers are killed by call node
+ // we explicity spill and unassign the register.
+ // ii) These will look a bit backward in the dump, but it's a pain to dump the alloc before the
+ // spill).
unassignPhysReg(getRegisterRecord(assignedRegister), currentRefPosition);
INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_ALLOC_REG, currentInterval, assignedRegister));
+
// Now set assignedRegister to REG_NA again so that we don't re-activate it.
assignedRegister = REG_NA;
}
else
-#endif // FEATURE_SIMD
+#endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
if (currentRefPosition->RequiresRegister() || currentRefPosition->AllocateIfProfitable())
{
if (allocateReg)
@@ -7069,6 +7469,7 @@ void LinearScan::allocateRegisters()
currentRefPosition->registerAssignment = RBM_NONE;
currentRefPosition->reload = false;
+ setIntervalAsSpilled(currentInterval);
INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_NO_REG_ALLOCATED, currentInterval));
}
@@ -7078,6 +7479,7 @@ void LinearScan::allocateRegisters()
INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_NO_REG_ALLOCATED, currentInterval));
currentRefPosition->registerAssignment = RBM_NONE;
currentInterval->isActive = false;
+ setIntervalAsSpilled(currentInterval);
}
}
#ifdef DEBUG
@@ -7224,7 +7626,7 @@ void LinearScan::allocateRegisters()
// - interval->physReg is set to the assigned register
// (i.e. at the code location which is currently being handled by resolveRegisters())
// - interval->isActive is true iff the interval is live and occupying a register
-// - interval->isSpilled is set to true if the interval is EVER spilled
+// - interval->isSpilled should have already been set to true if the interval is EVER spilled
// - interval->isSplit is set to true if the interval does not occupy the same
// register throughout the method
// - RegRecord->assignedInterval points to the interval which currently occupies
@@ -7264,9 +7666,9 @@ void LinearScan::resolveLocalRef(BasicBlock* block, GenTreePtr treeNode, RefPosi
if (currentRefPosition->registerAssignment == RBM_NONE)
{
assert(!currentRefPosition->RequiresRegister());
+ assert(interval->isSpilled);
- interval->isSpilled = true;
- varDsc->lvRegNum = REG_STK;
+ varDsc->lvRegNum = REG_STK;
if (interval->assignedReg != nullptr && interval->assignedReg->assignedInterval == interval)
{
interval->assignedReg->assignedInterval = nullptr;
@@ -7314,8 +7716,10 @@ void LinearScan::resolveLocalRef(BasicBlock* block, GenTreePtr treeNode, RefPosi
// In the reload case we simply do not set GTF_REG_VAL, and it gets
// referenced from the variable's home location.
// This is also true for a pure def which is spilled.
- if (reload && currentRefPosition->refType != RefTypeDef)
+ if (reload)
{
+ assert(currentRefPosition->refType != RefTypeDef);
+ assert(interval->isSpilled);
varDsc->lvRegNum = REG_STK;
if (!spillAfter)
{
@@ -7353,31 +7757,15 @@ void LinearScan::resolveLocalRef(BasicBlock* block, GenTreePtr treeNode, RefPosi
{
assert(currentRefPosition->refType == RefTypeExpUse);
}
-
- // If we have an undefined use set it as non-reg
- if (!interval->isSpilled)
- {
- if (varDsc->lvIsParam && !varDsc->lvIsRegArg && currentRefPosition == interval->firstRefPosition)
- {
- // Parameters are the only thing that can be used before defined
- }
- else
- {
- // if we see a use before def of something else, the zero init flag better not be set.
- noway_assert(!compiler->info.compInitMem);
- // if it is not set, then the behavior is undefined but we don't want to crash or assert
- interval->isSpilled = true;
- }
- }
}
else if (spillAfter && !RefTypeIsUse(currentRefPosition->refType))
{
// In the case of a pure def, don't bother spilling - just assign it to the
// stack. However, we need to remember that it was spilled.
- interval->isSpilled = true;
- varDsc->lvRegNum = REG_STK;
- interval->physReg = REG_NA;
+ assert(interval->isSpilled);
+ varDsc->lvRegNum = REG_STK;
+ interval->physReg = REG_NA;
if (treeNode != nullptr)
{
treeNode->gtRegNum = REG_NA;
@@ -7409,6 +7797,7 @@ void LinearScan::resolveLocalRef(BasicBlock* block, GenTreePtr treeNode, RefPosi
}
else
{
+ assert(interval->isSplit);
interval->physReg = assignedReg;
}
@@ -7426,13 +7815,11 @@ void LinearScan::resolveLocalRef(BasicBlock* block, GenTreePtr treeNode, RefPosi
{
if (varDsc->lvRegNum != REG_STK)
{
- // If the register assignments don't match, then this interval is spilt,
- // but not spilled (yet)
- // However, we don't have a single register assignment now
+ // If the register assignments don't match, then this interval is split.
if (varDsc->lvRegNum != assignedReg)
{
- interval->isSplit = TRUE;
- varDsc->lvRegNum = REG_STK;
+ setIntervalAsSplit(interval);
+ varDsc->lvRegNum = REG_STK;
}
}
else
@@ -7447,9 +7834,9 @@ void LinearScan::resolveLocalRef(BasicBlock* block, GenTreePtr treeNode, RefPosi
{
treeNode->gtFlags |= GTF_SPILL;
}
- interval->isSpilled = true;
- interval->physReg = REG_NA;
- varDsc->lvRegNum = REG_STK;
+ assert(interval->isSpilled);
+ interval->physReg = REG_NA;
+ varDsc->lvRegNum = REG_STK;
}
// This value is in a register, UNLESS we already saw this treeNode
@@ -7489,6 +7876,7 @@ void LinearScan::writeRegisters(RefPosition* currentRefPosition, GenTree* tree)
// than the one it was spilled from (GT_RELOAD).
//
// Arguments:
+// block - basic block in which GT_COPY/GT_RELOAD is inserted.
// tree - This is the node to copy or reload.
// Insert copy or reload node between this node and its parent.
// multiRegIdx - register position of tree node for which copy or reload is needed.
@@ -7557,6 +7945,10 @@ void LinearScan::insertCopyOrReload(BasicBlock* block, GenTreePtr tree, unsigned
else
{
oper = GT_COPY;
+
+#if TRACK_LSRA_STATS
+ updateLsraStat(LSRA_STAT_COPY_REG, block->bbNum);
+#endif
}
// If the parent is a reload/copy node, then tree must be a multi-reg call node
@@ -8100,7 +8492,7 @@ void LinearScan::resolveRegisters()
{
JITDUMP(" internal");
GenTreePtr indNode = nullptr;
- if (treeNode->OperIsIndir())
+ if (treeNode->OperGet() == GT_IND)
{
indNode = treeNode;
JITDUMP(" allocated at GT_IND");
@@ -8223,6 +8615,11 @@ void LinearScan::resolveRegisters()
printf("RESOLVING BB BOUNDARIES\n");
printf("-----------------------\n");
+ printf("Resolution Candidates: ");
+ dumpConvertedVarSet(compiler, resolutionCandidateVars);
+ printf("\n");
+ printf("Has %sCritical Edges\n\n", hasCriticalEdges ? "" : "No");
+
printf("Prior to Resolution\n");
foreach_block(compiler, block)
{
@@ -8282,23 +8679,10 @@ void LinearScan::resolveRegisters()
varDsc->lvArgInitReg = initialReg;
JITDUMP(" Set V%02u argument initial register to %s\n", lclNum, getRegName(initialReg));
}
- if (!varDsc->lvIsRegArg)
- {
- // stack arg
- if (compiler->lvaIsFieldOfDependentlyPromotedStruct(varDsc))
- {
- if (sourceReg != initialReg)
- {
- // The code generator won't initialize struct
- // fields, so we have to do that if it's not already
- // where it belongs.
- assert(interval->isStructField);
- JITDUMP(" Move struct field param V%02u from %s to %s\n", lclNum, getRegName(sourceReg),
- getRegName(initialReg));
- insertMove(insertionBlock, insertionPoint, lclNum, sourceReg, initialReg);
- }
- }
- }
+
+ // Stack args that are part of dependently-promoted structs should never be register candidates (see
+ // LinearScan::isRegCandidate).
+ assert(varDsc->lvIsRegArg || !compiler->lvaIsFieldOfDependentlyPromotedStruct(varDsc));
}
// If lvRegNum is REG_STK, that means that either no register
@@ -8347,8 +8731,8 @@ void LinearScan::resolveRegisters()
}
if (firstRefPosition->registerAssignment == RBM_NONE || firstRefPosition->spillAfter)
{
- // Either this RefPosition is spilled, or it is not a "real" def or use
- assert(firstRefPosition->spillAfter ||
+ // Either this RefPosition is spilled, or regOptional or it is not a "real" def or use
+ assert(firstRefPosition->spillAfter || firstRefPosition->AllocateIfProfitable() ||
(firstRefPosition->refType != RefTypeDef && firstRefPosition->refType != RefTypeUse));
varDsc->lvRegNum = REG_STK;
}
@@ -8432,6 +8816,8 @@ void LinearScan::insertMove(
BasicBlock* block, GenTreePtr insertionPoint, unsigned lclNum, regNumber fromReg, regNumber toReg)
{
LclVarDsc* varDsc = compiler->lvaTable + lclNum;
+ // the lclVar must be a register candidate
+ assert(isRegCandidate(varDsc));
// One or both MUST be a register
assert(fromReg != REG_STK || toReg != REG_STK);
// They must not be the same register.
@@ -8440,20 +8826,22 @@ void LinearScan::insertMove(
// This var can't be marked lvRegister now
varDsc->lvRegNum = REG_STK;
- var_types lclTyp = varDsc->TypeGet();
- if (varDsc->lvNormalizeOnStore())
- {
- lclTyp = genActualType(lclTyp);
- }
- GenTreePtr src = compiler->gtNewLclvNode(lclNum, lclTyp);
+ GenTreePtr src = compiler->gtNewLclvNode(lclNum, varDsc->TypeGet());
src->gtLsraInfo.isLsraAdded = true;
- GenTreePtr top;
- // If we are moving from STK to reg, mark the lclVar nodes with GTF_SPILLED
- // Otherwise, if we are moving from reg to stack, mark it as GTF_SPILL
- // Finally, for a reg-to-reg move, generate a GT_COPY
+ // There are three cases we need to handle:
+ // - We are loading a lclVar from the stack.
+ // - We are storing a lclVar to the stack.
+ // - We are copying a lclVar between registers.
+ //
+ // In the first and second cases, the lclVar node will be marked with GTF_SPILLED and GTF_SPILL, respectively.
+ // It is up to the code generator to ensure that any necessary normalization is done when loading or storing the
+ // lclVar's value.
+ //
+ // In the third case, we generate GT_COPY(GT_LCL_VAR) and type each node with the normalized type of the lclVar.
+ // This is safe because a lclVar is always normalized once it is in a register.
- top = src;
+ GenTree* dst = src;
if (fromReg == REG_STK)
{
src->gtFlags |= GTF_SPILLED;
@@ -8467,21 +8855,22 @@ void LinearScan::insertMove(
}
else
{
- top = new (compiler, GT_COPY) GenTreeCopyOrReload(GT_COPY, varDsc->TypeGet(), src);
+ var_types movType = genActualType(varDsc->TypeGet());
+ src->gtType = movType;
+
+ dst = new (compiler, GT_COPY) GenTreeCopyOrReload(GT_COPY, movType, src);
// This is the new home of the lclVar - indicate that by clearing the GTF_VAR_DEATH flag.
// Note that if src is itself a lastUse, this will have no effect.
- top->gtFlags &= ~(GTF_VAR_DEATH);
+ dst->gtFlags &= ~(GTF_VAR_DEATH);
src->gtRegNum = fromReg;
src->SetInReg();
- top->gtRegNum = toReg;
- src->gtNext = top;
- top->gtPrev = src;
+ dst->gtRegNum = toReg;
src->gtLsraInfo.isLocalDefUse = false;
- top->gtLsraInfo.isLsraAdded = true;
+ dst->gtLsraInfo.isLsraAdded = true;
}
- top->gtLsraInfo.isLocalDefUse = true;
+ dst->gtLsraInfo.isLocalDefUse = true;
- LIR::Range treeRange = LIR::SeqTree(compiler, top);
+ LIR::Range treeRange = LIR::SeqTree(compiler, dst);
LIR::Range& blockRange = LIR::AsRange(block);
if (insertionPoint != nullptr)
@@ -8497,7 +8886,7 @@ void LinearScan::insertMove(
noway_assert(!blockRange.IsEmpty());
GenTree* branch = blockRange.LastNode();
- assert(branch->OperGet() == GT_JTRUE || branch->OperGet() == GT_SWITCH_TABLE ||
+ assert(branch->OperIsConditionalJump() || branch->OperGet() == GT_SWITCH_TABLE ||
branch->OperGet() == GT_SWITCH);
blockRange.InsertBefore(branch, std::move(treeRange));
@@ -8568,7 +8957,7 @@ void LinearScan::insertSwap(
noway_assert(!blockRange.IsEmpty());
GenTree* branch = blockRange.LastNode();
- assert(branch->OperGet() == GT_JTRUE || branch->OperGet() == GT_SWITCH_TABLE ||
+ assert(branch->OperIsConditionalJump() || branch->OperGet() == GT_SWITCH_TABLE ||
branch->OperGet() == GT_SWITCH);
blockRange.InsertBefore(branch, std::move(swapRange));
@@ -8682,12 +9071,15 @@ void LinearScan::addResolution(
insertMove(block, insertionPoint, interval->varNum, fromReg, toReg);
if (fromReg == REG_STK || toReg == REG_STK)
{
- interval->isSpilled = true;
+ assert(interval->isSpilled);
}
else
{
- interval->isSplit = true;
+ // We should have already marked this as spilled or split.
+ assert((interval->isSpilled) || (interval->isSplit));
}
+
+ INTRACK_STATS(updateLsraStat(LSRA_STAT_RESOLUTION_MOV, block->bbNum));
}
//------------------------------------------------------------------------
@@ -8706,6 +9098,12 @@ void LinearScan::addResolution(
void LinearScan::handleOutgoingCriticalEdges(BasicBlock* block)
{
+ VARSET_TP VARSET_INIT_NOCOPY(outResolutionSet,
+ VarSetOps::Intersection(compiler, block->bbLiveOut, resolutionCandidateVars));
+ if (VarSetOps::IsEmpty(compiler, outResolutionSet))
+ {
+ return;
+ }
VARSET_TP VARSET_INIT_NOCOPY(sameResolutionSet, VarSetOps::MakeEmpty(compiler));
VARSET_TP VARSET_INIT_NOCOPY(sameLivePathsSet, VarSetOps::MakeEmpty(compiler));
VARSET_TP VARSET_INIT_NOCOPY(singleTargetSet, VarSetOps::MakeEmpty(compiler));
@@ -8720,6 +9118,8 @@ void LinearScan::handleOutgoingCriticalEdges(BasicBlock* block)
// First, determine the live regs at the end of this block so that we know what regs are
// available to copy into.
+ // Note that for this purpose we use the full live-out set, because we must ensure that
+ // even the registers that remain the same across the edge are preserved correctly.
regMaskTP liveOutRegs = RBM_NONE;
VARSET_ITER_INIT(compiler, iter1, block->bbLiveOut, varIndex1);
while (iter1.NextElem(compiler, &varIndex1))
@@ -8755,7 +9155,7 @@ void LinearScan::handleOutgoingCriticalEdges(BasicBlock* block)
regMaskTP sameWriteRegs = RBM_NONE;
regMaskTP diffReadRegs = RBM_NONE;
- // For each var, classify them as:
+ // For each var that may require resolution, classify them as:
// - in the same register at the end of this block and at each target (no resolution needed)
// - in different registers at different targets (resolve separately):
// diffResolutionSet
@@ -8764,7 +9164,7 @@ void LinearScan::handleOutgoingCriticalEdges(BasicBlock* block)
// write to any registers that are read by those in the diffResolutionSet:
// sameResolutionSet
- VARSET_ITER_INIT(compiler, iter, block->bbLiveOut, varIndex);
+ VARSET_ITER_INIT(compiler, iter, outResolutionSet, varIndex);
while (iter.NextElem(compiler, &varIndex))
{
unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
@@ -8936,6 +9336,16 @@ void LinearScan::resolveEdges()
{
JITDUMP("RESOLVING EDGES\n");
+ // The resolutionCandidateVars set was initialized with all the lclVars that are live-in to
+ // any block. We now intersect that set with any lclVars that ever spilled or split.
+ // If there are no candidates for resoultion, simply return.
+
+ VarSetOps::IntersectionD(compiler, resolutionCandidateVars, splitOrSpilledVars);
+ if (VarSetOps::IsEmpty(compiler, resolutionCandidateVars))
+ {
+ return;
+ }
+
BasicBlock *block, *prevBlock = nullptr;
// Handle all the critical edges first.
@@ -8944,18 +9354,21 @@ void LinearScan::resolveEdges()
// remaining mismatches. We visit the out-edges, as that allows us to share the moves that are
// common among allt he targets.
- foreach_block(compiler, block)
+ if (hasCriticalEdges)
{
- if (block->bbNum > bbNumMaxBeforeResolution)
- {
- // This is a new block added during resolution - we don't need to visit these now.
- continue;
- }
- if (blockInfo[block->bbNum].hasCriticalOutEdge)
+ foreach_block(compiler, block)
{
- handleOutgoingCriticalEdges(block);
+ if (block->bbNum > bbNumMaxBeforeResolution)
+ {
+ // This is a new block added during resolution - we don't need to visit these now.
+ continue;
+ }
+ if (blockInfo[block->bbNum].hasCriticalOutEdge)
+ {
+ handleOutgoingCriticalEdges(block);
+ }
+ prevBlock = block;
}
- prevBlock = block;
}
prevBlock = nullptr;
@@ -8975,7 +9388,9 @@ void LinearScan::resolveEdges()
// we may need resolution at the beginning of this block.
// This may be true even if it's the block we used for starting locations,
// if a variable was spilled.
- if (!VarSetOps::IsEmpty(compiler, block->bbLiveIn))
+ VARSET_TP VARSET_INIT_NOCOPY(inResolutionSet,
+ VarSetOps::Intersection(compiler, block->bbLiveIn, resolutionCandidateVars));
+ if (!VarSetOps::IsEmpty(compiler, inResolutionSet))
{
if (uniquePredBlock != nullptr)
{
@@ -8988,7 +9403,7 @@ void LinearScan::resolveEdges()
uniquePredBlock = uniquePredBlock->GetUniquePred(compiler);
noway_assert(uniquePredBlock != nullptr);
}
- resolveEdge(uniquePredBlock, block, ResolveSplit, block->bbLiveIn);
+ resolveEdge(uniquePredBlock, block, ResolveSplit, inResolutionSet);
}
}
@@ -9003,7 +9418,12 @@ void LinearScan::resolveEdges()
BasicBlock* succBlock = block->GetSucc(0, compiler);
if (succBlock->GetUniquePred(compiler) == nullptr)
{
- resolveEdge(block, succBlock, ResolveJoin, succBlock->bbLiveIn);
+ VARSET_TP VARSET_INIT_NOCOPY(outResolutionSet, VarSetOps::Intersection(compiler, succBlock->bbLiveIn,
+ resolutionCandidateVars));
+ if (!VarSetOps::IsEmpty(compiler, outResolutionSet))
+ {
+ resolveEdge(block, succBlock, ResolveJoin, outResolutionSet);
+ }
}
}
}
@@ -9161,6 +9581,9 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
// in resolveEdges(), after all the edge resolution has been done (by calling this
// method for each edge).
block = compiler->fgSplitEdge(fromBlock, toBlock);
+
+ // Split edges are counted against fromBlock.
+ INTRACK_STATS(updateLsraStat(LSRA_STAT_SPLIT_EDGE, fromBlock->bbNum));
break;
default:
unreached();
@@ -9347,11 +9770,13 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
{
useSwap = true;
}
-#else // !_TARGET_XARCH_
+#else // !_TARGET_XARCH_
+
else
{
tempReg = tempRegInt;
}
+
#endif // !_TARGET_XARCH_
if (useSwap || tempReg == REG_NA)
{
@@ -9396,6 +9821,8 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
sourceIntervals[sourceReg]->varNum, fromReg);
location[sourceReg] = REG_NA;
location[source[otherTargetReg]] = (regNumberSmall)fromReg;
+
+ INTRACK_STATS(updateLsraStat(LSRA_STAT_RESOLUTION_MOV, block->bbNum));
}
else
{
@@ -9406,6 +9833,7 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
// First, spill "otherInterval" from targetReg to the stack.
Interval* otherInterval = sourceIntervals[source[otherTargetReg]];
+ setIntervalAsSpilled(otherInterval);
addResolution(block, insertionPoint, otherInterval, REG_STK, targetReg);
JITDUMP(" (%s)\n", resolveTypeName[resolveType]);
location[source[otherTargetReg]] = REG_STK;
@@ -9527,6 +9955,126 @@ void TreeNodeInfo::addInternalCandidates(LinearScan* lsra, regMaskTP mask)
internalCandsIndex = (unsigned char)i;
}
+#if TRACK_LSRA_STATS
+// ----------------------------------------------------------
+// updateLsraStat: Increment LSRA stat counter.
+//
+// Arguments:
+// stat - LSRA stat enum
+// bbNum - Basic block to which LSRA stat needs to be
+// associated with.
+//
+void LinearScan::updateLsraStat(LsraStat stat, unsigned bbNum)
+{
+ if (bbNum > bbNumMaxBeforeResolution)
+ {
+ // This is a newly created basic block as part of resolution.
+ // These blocks contain resolution moves that are already accounted.
+ return;
+ }
+
+ switch (stat)
+ {
+ case LSRA_STAT_SPILL:
+ ++(blockInfo[bbNum].spillCount);
+ break;
+
+ case LSRA_STAT_COPY_REG:
+ ++(blockInfo[bbNum].copyRegCount);
+ break;
+
+ case LSRA_STAT_RESOLUTION_MOV:
+ ++(blockInfo[bbNum].resolutionMovCount);
+ break;
+
+ case LSRA_STAT_SPLIT_EDGE:
+ ++(blockInfo[bbNum].splitEdgeCount);
+ break;
+
+ default:
+ break;
+ }
+}
+
+// -----------------------------------------------------------
+// dumpLsraStats - dumps Lsra stats to given file.
+//
+// Arguments:
+// file - file to which stats are to be written.
+//
+void LinearScan::dumpLsraStats(FILE* file)
+{
+ unsigned sumSpillCount = 0;
+ unsigned sumCopyRegCount = 0;
+ unsigned sumResolutionMovCount = 0;
+ unsigned sumSplitEdgeCount = 0;
+ UINT64 wtdSpillCount = 0;
+ UINT64 wtdCopyRegCount = 0;
+ UINT64 wtdResolutionMovCount = 0;
+
+ fprintf(file, "----------\n");
+ fprintf(file, "LSRA Stats");
+#ifdef DEBUG
+ if (!VERBOSE)
+ {
+ fprintf(file, " : %s\n", compiler->info.compFullName);
+ }
+ else
+ {
+ // In verbose mode no need to print full name
+ // while printing lsra stats.
+ fprintf(file, "\n");
+ }
+#else
+ fprintf(file, " : %s\n", compiler->eeGetMethodFullName(compiler->info.compCompHnd));
+#endif
+
+ fprintf(file, "----------\n");
+
+ for (BasicBlock* block = compiler->fgFirstBB; block != nullptr; block = block->bbNext)
+ {
+ if (block->bbNum > bbNumMaxBeforeResolution)
+ {
+ continue;
+ }
+
+ unsigned spillCount = blockInfo[block->bbNum].spillCount;
+ unsigned copyRegCount = blockInfo[block->bbNum].copyRegCount;
+ unsigned resolutionMovCount = blockInfo[block->bbNum].resolutionMovCount;
+ unsigned splitEdgeCount = blockInfo[block->bbNum].splitEdgeCount;
+
+ if (spillCount != 0 || copyRegCount != 0 || resolutionMovCount != 0 || splitEdgeCount != 0)
+ {
+ fprintf(file, "BB%02u [%8d]: ", block->bbNum, block->bbWeight);
+ fprintf(file, "SpillCount = %d, ResolutionMovs = %d, SplitEdges = %d, CopyReg = %d\n", spillCount,
+ resolutionMovCount, splitEdgeCount, copyRegCount);
+ }
+
+ sumSpillCount += spillCount;
+ sumCopyRegCount += copyRegCount;
+ sumResolutionMovCount += resolutionMovCount;
+ sumSplitEdgeCount += splitEdgeCount;
+
+ wtdSpillCount += (UINT64)spillCount * block->bbWeight;
+ wtdCopyRegCount += (UINT64)copyRegCount * block->bbWeight;
+ wtdResolutionMovCount += (UINT64)resolutionMovCount * block->bbWeight;
+ }
+
+ fprintf(file, "Total Spill Count: %d Weighted: %I64u\n", sumSpillCount, wtdSpillCount);
+ fprintf(file, "Total CopyReg Count: %d Weighted: %I64u\n", sumCopyRegCount, wtdCopyRegCount);
+ fprintf(file, "Total ResolutionMov Count: %d Weighted: %I64u\n", sumResolutionMovCount, wtdResolutionMovCount);
+ fprintf(file, "Total number of split edges: %d\n", sumSplitEdgeCount);
+
+ // compute total number of spill temps created
+ unsigned numSpillTemps = 0;
+ for (int i = 0; i < TYP_COUNT; i++)
+ {
+ numSpillTemps += maxSpill[i];
+ }
+ fprintf(file, "Total Number of spill temps created: %d\n\n", numSpillTemps);
+}
+#endif // TRACK_LSRA_STATS
+
#ifdef DEBUG
void dumpRegMask(regMaskTP regs)
{
@@ -9645,6 +10193,11 @@ void RefPosition::dump()
{
printf(" outOfOrder");
}
+
+ if (this->AllocateIfProfitable())
+ {
+ printf(" regOptional");
+ }
printf(">\n");
}
@@ -11329,9 +11882,18 @@ void LinearScan::verifyFinalAllocation()
{
if (VERBOSE)
{
+ // If refPos is marked as copyReg, then the reg that is spilled
+ // is the homeReg of the interval not the reg currently assigned
+ // to refPos.
+ regNumber spillReg = regNum;
+ if (currentRefPosition->copyReg)
+ {
+ assert(interval != nullptr);
+ spillReg = interval->physReg;
+ }
dumpRegRecords();
dumpEmptyRefPosition();
- printf("Spill %-4s ", getRegName(regNum));
+ printf("Spill %-4s ", getRegName(spillReg));
}
}
else if (currentRefPosition->copyReg)
@@ -11392,15 +11954,14 @@ void LinearScan::verifyFinalAllocation()
interval->physReg = REG_NA;
interval->assignedReg = nullptr;
- // regRegcord could be null if RefPosition is to be allocated a
- // reg only if profitable.
+ // regRegcord could be null if the RefPosition does not require a register.
if (regRecord != nullptr)
{
regRecord->assignedInterval = nullptr;
}
else
{
- assert(currentRefPosition->AllocateIfProfitable());
+ assert(!currentRefPosition->RequiresRegister());
}
}
}
@@ -11506,6 +12067,8 @@ void LinearScan::verifyResolutionMove(GenTree* resolutionMove, LsraLocation curr
assert(leftInterval->physReg == leftRegNum && rightInterval->physReg == rightRegNum);
leftInterval->physReg = rightRegNum;
rightInterval->physReg = leftRegNum;
+ leftInterval->assignedReg = &physRegs[rightRegNum];
+ rightInterval->assignedReg = &physRegs[leftRegNum];
physRegs[rightRegNum].assignedInterval = leftInterval;
physRegs[leftRegNum].assignedInterval = rightInterval;
if (VERBOSE)
diff --git a/src/jit/lsra.h b/src/jit/lsra.h
index a3c41fe1e3..c8a3fb4e24 100644
--- a/src/jit/lsra.h
+++ b/src/jit/lsra.h
@@ -73,6 +73,25 @@ struct LsraBlockInfo
unsigned int predBBNum;
bool hasCriticalInEdge;
bool hasCriticalOutEdge;
+
+#if TRACK_LSRA_STATS
+ // Per block maintained LSRA statistics.
+
+ // Number of spills of local vars or tree temps in this basic block.
+ unsigned spillCount;
+
+ // Number of GT_COPY nodes inserted in this basic block while allocating regs.
+ // Note that GT_COPY nodes are also inserted as part of basic block boundary
+ // resolution, which are accounted against resolutionMovCount but not
+ // against copyRegCount.
+ unsigned copyRegCount;
+
+ // Number of resolution moves inserted in this basic block.
+ unsigned resolutionMovCount;
+
+ // Number of critical edges from this block that are split.
+ unsigned splitEdgeCount;
+#endif // TRACK_LSRA_STATS
};
// This is sort of a bit mask
@@ -504,6 +523,8 @@ private:
{
return (LsraStressLimitRegs)(lsraStressMask & LSRA_LIMIT_MASK);
}
+
+ regMaskTP getConstrainedRegMask(regMaskTP regMaskActual, regMaskTP regMaskConstrain, unsigned minRegCount);
regMaskTP stressLimitRegs(RefPosition* refPosition, regMaskTP mask);
// This controls the heuristics used to select registers
@@ -572,7 +593,7 @@ private:
regNumber rotateBlockStartLocation(Interval* interval, regNumber targetReg, regMaskTP availableRegs);
// This controls whether we always insert a GT_RELOAD instruction after a spill
- // Note that this can be combined with LsraSpillAlways (or not)
+ // Note that this can be combined with LSRA_SPILL_ALWAYS (or not)
enum LsraReload{LSRA_NO_RELOAD_IF_SAME = 0, LSRA_ALWAYS_INSERT_RELOAD = 0x400, LSRA_RELOAD_MASK = 0x400};
LsraReload getLsraReload()
{
@@ -769,11 +790,19 @@ private:
regMaskTP getDefCandidates(GenTree* tree);
var_types getDefType(GenTree* tree);
- RefPosition* defineNewInternalTemp(GenTree* tree, RegisterType regType, LsraLocation currentLoc, regMaskTP regMask);
+ RefPosition* defineNewInternalTemp(GenTree* tree,
+ RegisterType regType,
+ LsraLocation currentLoc,
+ regMaskTP regMask DEBUGARG(unsigned minRegCandidateCount));
- int buildInternalRegisterDefsForNode(GenTree* tree, LsraLocation currentLoc, RefPosition* defs[]);
+ int buildInternalRegisterDefsForNode(GenTree* tree,
+ LsraLocation currentLoc,
+ RefPosition* defs[] DEBUGARG(unsigned minRegCandidateCount));
- void buildInternalRegisterUsesForNode(GenTree* tree, LsraLocation currentLoc, RefPosition* defs[], int total);
+ void buildInternalRegisterUsesForNode(GenTree* tree,
+ LsraLocation currentLoc,
+ RefPosition* defs[],
+ int total DEBUGARG(unsigned minRegCandidateCount));
void resolveLocalRef(BasicBlock* block, GenTreePtr treeNode, RefPosition* currentRefPosition);
@@ -824,7 +853,7 @@ private:
RefType theRefType,
GenTree* theTreeNode,
regMaskTP mask,
- unsigned multiRegIdx = 0);
+ unsigned multiRegIdx = 0 DEBUGARG(unsigned minRegCandidateCount = 1));
RefPosition* newRefPosition(
regNumber reg, LsraLocation theLocation, RefType theRefType, GenTree* theTreeNode, regMaskTP mask);
@@ -864,6 +893,8 @@ private:
unassignPhysReg(getRegisterRecord(reg), nullptr);
}
+ void setIntervalAsSpilled(Interval* interval);
+ void setIntervalAsSplit(Interval* interval);
void spillInterval(Interval* interval, RefPosition* fromRefPosition, RefPosition* toRefPosition);
void spillGCRefs(RefPosition* killRefPosition);
@@ -936,11 +967,8 @@ private:
char* operandString,
unsigned operandStringLength);
void lsraDispNode(GenTreePtr tree, LsraTupleDumpMode mode, bool hasDest);
- void DumpOperandDefs(GenTree* operand,
- bool& first,
- LsraTupleDumpMode mode,
- char* operandString,
- const unsigned operandStringLength);
+ void DumpOperandDefs(
+ GenTree* operand, bool& first, LsraTupleDumpMode mode, char* operandString, const unsigned operandStringLength);
void TupleStyleDump(LsraTupleDumpMode mode);
bool dumpTerse;
@@ -1020,6 +1048,20 @@ private:
void validateIntervals();
#endif // DEBUG
+#if TRACK_LSRA_STATS
+ enum LsraStat{
+ LSRA_STAT_SPILL, LSRA_STAT_COPY_REG, LSRA_STAT_RESOLUTION_MOV, LSRA_STAT_SPLIT_EDGE,
+ };
+
+ void updateLsraStat(LsraStat stat, unsigned currentBBNum);
+
+ void dumpLsraStats(FILE* file);
+
+#define INTRACK_STATS(x) x
+#else // !TRACK_LSRA_STATS
+#define INTRACK_STATS(x)
+#endif // !TRACK_LSRA_STATS
+
Compiler* compiler;
private:
@@ -1066,6 +1108,10 @@ private:
return BlockSetOps::IsMember(compiler, bbVisitedSet, block->bbNum);
}
+#if DOUBLE_ALIGN
+ bool doDoubleAlign;
+#endif
+
// A map from bbNum to the block information used during register allocation.
LsraBlockInfo* blockInfo;
BasicBlock* findPredBlockForLiveIn(BasicBlock* block, BasicBlock* prevBlock DEBUGARG(bool* pPredBlockIsAllocated));
@@ -1092,6 +1138,8 @@ private:
unsigned int bbSeqCount;
// The Location of the start of the current block.
LsraLocation curBBStartLocation;
+ // True if the method contains any critical edges.
+ bool hasCriticalEdges;
// Ordered list of RefPositions
RefPositionList refPositions;
@@ -1111,6 +1159,12 @@ private:
// Current set of live tracked vars, used during building of RefPositions to determine whether
// to preference to callee-save
VARSET_TP currentLiveVars;
+ // Set of variables that may require resolution across an edge.
+ // This is first constructed during interval building, to contain all the lclVars that are live at BB edges.
+ // Then, any lclVar that is always in the same register is removed from the set.
+ VARSET_TP resolutionCandidateVars;
+ // This set contains all the lclVars that are ever spilled or split.
+ VARSET_TP splitOrSpilledVars;
// Set of floating point variables to consider for callee-save registers.
VARSET_TP fpCalleeSaveCandidateVars;
#if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
@@ -1382,6 +1436,7 @@ public:
, delayRegFree(false)
, outOfOrder(false)
#ifdef DEBUG
+ , minRegCandidateCount(1)
, rpNum(0)
#endif
{
@@ -1555,9 +1610,15 @@ public:
}
#ifdef DEBUG
- unsigned rpNum; // The unique RefPosition number, equal to its index in the refPositions list. Only used for
- // debugging dumps.
-#endif // DEBUG
+ // Minimum number registers that needs to be ensured while
+ // constraining candidates for this ref position under
+ // LSRA stress.
+ unsigned minRegCandidateCount;
+
+ // The unique RefPosition number, equal to its index in the
+ // refPositions list. Only used for debugging dumps.
+ unsigned rpNum;
+#endif // DEBUG
bool isIntervalRef()
{
diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp
index 00df17baa0..678bb34c54 100644
--- a/src/jit/morph.cpp
+++ b/src/jit/morph.cpp
@@ -204,6 +204,9 @@ GenTreePtr Compiler::fgMorphCast(GenTreePtr tree)
{
case TYP_INT:
#ifdef _TARGET_X86_ // there is no rounding convert to integer instruction on ARM or x64 so skip this
+#ifdef LEGACY_BACKEND
+ // the RyuJIT backend does not use the x87 FPU and therefore
+ // does not support folding the cast conv.i4(round.d(d))
if ((oper->gtOper == GT_INTRINSIC) &&
(oper->gtIntrinsic.gtIntrinsicId == CORINFO_INTRINSIC_Round))
{
@@ -212,7 +215,9 @@ GenTreePtr Compiler::fgMorphCast(GenTreePtr tree)
return fgMorphTree(oper);
}
// if SSE2 is not enabled, we need the helper
- else if (!opts.compCanUseSSE2)
+ else
+#endif // LEGACY_BACKEND
+ if (!opts.compCanUseSSE2)
{
return fgMorphCastIntoHelper(tree, CORINFO_HELP_DBL2INT, oper);
}
@@ -360,8 +365,17 @@ GenTreePtr Compiler::fgMorphCast(GenTreePtr tree)
oper = gtNewCastNode(TYP_LONG, oper, TYP_LONG);
oper->gtFlags |= (tree->gtFlags & (GTF_OVERFLOW | GTF_EXCEPT | GTF_UNSIGNED));
tree->gtFlags &= ~GTF_UNSIGNED;
+#ifndef LEGACY_BACKEND
+ return fgMorphCastIntoHelper(tree, CORINFO_HELP_LNG2DBL, oper);
+#endif
}
}
+#ifndef LEGACY_BACKEND
+ else if (((tree->gtFlags & GTF_UNSIGNED) == 0) && (srcType == TYP_LONG) && varTypeIsFloating(dstType))
+ {
+ return fgMorphCastIntoHelper(tree, CORINFO_HELP_LNG2DBL, oper);
+ }
+#endif
#endif //_TARGET_XARCH_
else if (varTypeIsGC(srcType) != varTypeIsGC(dstType))
{
@@ -1010,12 +1024,12 @@ fgArgInfo::fgArgInfo(GenTreePtr newCall, GenTreePtr oldCall)
{
/* Get hold of the next argument values for the oldCall and newCall */
- assert(newArgs->IsList());
+ assert(newArgs->OperIsList());
newCurr = newArgs->Current();
newArgs = newArgs->Rest();
- assert(oldArgs->IsList());
+ assert(oldArgs->OperIsList());
oldCurr = oldArgs->Current();
oldArgs = oldArgs->Rest();
@@ -1047,6 +1061,8 @@ fgArgInfo::fgArgInfo(GenTreePtr newCall, GenTreePtr oldCall)
argCount = oldArgInfo->argCount;
nextSlotNum = oldArgInfo->nextSlotNum;
+ hasRegArgs = oldArgInfo->hasRegArgs;
+ hasStackArgs = oldArgInfo->hasStackArgs;
argsComplete = true;
argsSorted = true;
}
@@ -1188,7 +1204,7 @@ fgArgTabEntry* fgArgInfo::RemorphRegArg(
GenTreePtr argx;
if (curArgTabEntry->parent != nullptr)
{
- assert(curArgTabEntry->parent->IsList());
+ assert(curArgTabEntry->parent->OperIsList());
argx = curArgTabEntry->parent->Current();
isRegArg = (argx->gtFlags & GTF_LATE_ARG) != 0;
}
@@ -1255,7 +1271,7 @@ void fgArgInfo::RemorphStkArg(
if (curArgTabEntry->parent != nullptr)
{
- assert(curArgTabEntry->parent->IsList());
+ assert(curArgTabEntry->parent->OperIsList());
argx = curArgTabEntry->parent->Current();
isRegArg = (argx->gtFlags & GTF_LATE_ARG) != 0;
}
@@ -1283,7 +1299,7 @@ void fgArgInfo::RemorphStkArg(
assert(curArgTabEntry->numSlots == numSlots);
assert(curArgTabEntry->alignment == alignment);
assert(curArgTabEntry->parent == parent);
- assert(parent->IsList());
+ assert(parent->OperIsList());
#if FEATURE_FIXED_OUT_ARGS
if (curArgTabEntry->node != node)
@@ -1512,7 +1528,7 @@ void fgArgInfo::ArgsComplete()
#ifndef LEGACY_BACKEND
#if FEATURE_MULTIREG_ARGS
- // For RyuJIT backend we will expand a Multireg arg into a GT_LIST
+ // For RyuJIT backend we will expand a Multireg arg into a GT_FIELD_LIST
// with multiple indirections, so here we consider spilling it into a tmp LclVar.
//
// Note that Arm32 is a LEGACY_BACKEND and it defines FEATURE_MULTIREG_ARGS
@@ -2364,7 +2380,7 @@ void fgArgInfo::EvalArgsToTemps()
{
GenTreePtr parent = curArgTabEntry->parent;
/* a normal argument from the list */
- noway_assert(parent->IsList());
+ noway_assert(parent->OperIsList());
noway_assert(parent->gtOp.gtOp1 == argx);
parent->gtOp.gtOp1 = setupArg;
@@ -2387,7 +2403,7 @@ void fgArgInfo::EvalArgsToTemps()
}
else
{
- noway_assert(tmpRegArgNext->IsList());
+ noway_assert(tmpRegArgNext->OperIsList());
noway_assert(tmpRegArgNext->Current());
tmpRegArgNext->gtOp.gtOp2 = compiler->gtNewArgList(defArg);
tmpRegArgNext = tmpRegArgNext->Rest();
@@ -2603,7 +2619,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
unsigned argSlots = 0;
unsigned nonRegPassedStructSlots = 0;
- bool lateArgsComputed = (call->gtCallLateArgs != nullptr);
+ bool reMorphing = call->AreArgsComplete();
bool callHasRetBuffArg = call->HasRetBufArg();
#ifndef _TARGET_X86_ // i.e. _TARGET_AMD64_ or _TARGET_ARM_
@@ -2731,7 +2747,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
// Process the late arguments (which were determined by a previous caller).
// Do this before resetting fgPtrArgCntCur as fgMorphTree(call->gtCallLateArgs)
// may need to refer to it.
- if (lateArgsComputed)
+ if (reMorphing)
{
// We need to reMorph the gtCallLateArgs early since that is what triggers
// the expression folding and we need to have the final folded gtCallLateArgs
@@ -2745,14 +2761,17 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
//
// Since the late arguments are evaluated last we have pushed all of the
// other arguments on the stack before we evaluate these late arguments,
- // so we record the stack depth on the first morph call when lateArgsComputed
+ // 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();
- fgPtrArgCntCur += callStkLevel;
- call->gtCallLateArgs = fgMorphTree(call->gtCallLateArgs)->AsArgList();
- flagsSummary |= call->gtCallLateArgs->gtFlags;
- fgPtrArgCntCur -= callStkLevel;
+ if (call->gtCallLateArgs != nullptr)
+ {
+ fgPtrArgCntCur += callStkLevel;
+ call->gtCallLateArgs = fgMorphTree(call->gtCallLateArgs)->AsArgList();
+ flagsSummary |= call->gtCallLateArgs->gtFlags;
+ fgPtrArgCntCur -= callStkLevel;
+ }
assert(call->fgArgInfo != nullptr);
call->fgArgInfo->RemorphReset();
@@ -2780,7 +2799,8 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
// *********** END NOTE *********
CLANG_FORMAT_COMMENT_ANCHOR;
-#if !defined(LEGACY_BACKEND) && defined(_TARGET_X86_)
+#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 (call->IsHelperCall(this, CORINFO_HELP_INIT_PINVOKE_FRAME))
@@ -2792,21 +2812,20 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
}
// 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) || call->IsHelperCall(this, CORINFO_HELP_LRSZ))
+ else if (call->IsHelperCall(this, CORINFO_HELP_LLSH) || call->IsHelperCall(this, CORINFO_HELP_LRSH) ||
+ call->IsHelperCall(this, CORINFO_HELP_LRSZ))
{
GenTreeArgList* args = call->gtCallArgs;
- GenTree* arg1 = args->Current();
+ GenTree* arg1 = args->Current();
assert(arg1 != nullptr);
nonStandardArgs.Add(arg1, REG_LNGARG_LO);
- args = args->Rest();
+ args = args->Rest();
GenTree* arg2 = args->Current();
assert(arg2 != nullptr);
nonStandardArgs.Add(arg2, REG_LNGARG_HI);
}
-#endif // !defined(LEGACY_BACKEND) && defined(_TARGET_X86_)
-
-#if !defined(LEGACY_BACKEND) && !defined(_TARGET_X86_)
+#else // !defined(_TARGET_X86_)
// TODO-X86-CQ: Currently RyuJIT/x86 passes args on the stack, so this is not needed.
// If/when we change that, the following code needs to be changed to correctly support the (TBD) managed calling
// convention for x86/SSE.
@@ -2817,7 +2836,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
{
args = call->gtCallArgs;
assert(args != nullptr);
- assert(args->IsList());
+ assert(args->OperIsList());
argx = call->gtCallArgs->Current();
@@ -2871,21 +2890,32 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
nonStandardArgs.Add(arg, REG_VIRTUAL_STUB_PARAM);
}
- else if (call->gtCallType == CT_INDIRECT && call->gtCallCookie)
+ else
+#endif // defined(_TARGET_X86_)
+ if (call->gtCallType == CT_INDIRECT && (call->gtCallCookie != nullptr))
{
assert(!call->IsUnmanaged());
- // put cookie into R11
GenTree* arg = call->gtCallCookie;
noway_assert(arg != nullptr);
call->gtCallCookie = nullptr;
+#if defined(_TARGET_X86_)
+ // x86 passes the cookie on the stack as the final argument to the call.
+ GenTreeArgList** insertionPoint = &call->gtCallArgs;
+ for (; *insertionPoint != nullptr; insertionPoint = &(*insertionPoint)->Rest())
+ {
+ }
+ *insertionPoint = gtNewListNode(arg, nullptr);
+#else // !defined(_TARGET_X86_)
+ // All other architectures pass the cookie in a register.
call->gtCallArgs = gtNewListNode(arg, call->gtCallArgs);
- numArgs++;
+#endif // defined(_TARGET_X86_)
nonStandardArgs.Add(arg, REG_PINVOKE_COOKIE_PARAM);
+ numArgs++;
- // put destination into R10
+ // put destination into R10/EAX
arg = gtClone(call->gtCallAddr, true);
call->gtCallArgs = gtNewListNode(arg, call->gtCallArgs);
numArgs++;
@@ -2896,7 +2926,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
call->gtCallType = CT_HELPER;
call->gtCallMethHnd = eeFindHelper(CORINFO_HELP_PINVOKE_CALLI);
}
-#endif // !defined(LEGACY_BACKEND) && !defined(_TARGET_X86_)
+#endif // !defined(LEGACY_BACKEND)
// Allocate the fgArgInfo for the call node;
//
@@ -2929,7 +2959,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
/* We must fill in or update the argInfo table */
- if (lateArgsComputed)
+ if (reMorphing)
{
/* this is a register argument - possibly update it in the table */
call->fgArgInfo->RemorphRegArg(argIndex, argx, nullptr, genMapIntRegArgNumToRegNum(intArgRegNum), 1, 1);
@@ -3075,7 +3105,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
*parentArgx = argx;
flagsSummary |= argx->gtFlags;
- assert(args->IsList());
+ assert(args->OperIsList());
assert(argx == args->Current());
#ifndef LEGACY_BACKEND
@@ -3114,13 +3144,15 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
compFloatingPointUsed = true;
}
- unsigned size = 0;
- CORINFO_CLASS_HANDLE copyBlkClass = nullptr;
- bool isRegArg = false;
+ unsigned size = 0;
+ CORINFO_CLASS_HANDLE copyBlkClass = nullptr;
+ bool isRegArg = false;
+ bool isNonStandard = false;
+ regNumber nonStdRegNum = REG_NA;
fgArgTabEntryPtr argEntry = nullptr;
- if (lateArgsComputed)
+ if (reMorphing)
{
argEntry = gtArgEntryByArgNum(call, argIndex);
}
@@ -3128,7 +3160,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
#ifdef _TARGET_ARM_
bool passUsingIntRegs;
- if (lateArgsComputed)
+ if (reMorphing)
{
passUsingFloatRegs = isValidFloatArgReg(argEntry->regNum);
passUsingIntRegs = isValidIntArgReg(argEntry->regNum);
@@ -3179,7 +3211,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
#elif defined(_TARGET_ARM64_)
- if (lateArgsComputed)
+ if (reMorphing)
{
passUsingFloatRegs = isValidFloatArgReg(argEntry->regNum);
}
@@ -3189,8 +3221,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
}
#elif defined(_TARGET_AMD64_)
-#if defined(UNIX_AMD64_ABI)
- if (lateArgsComputed)
+ if (reMorphing)
{
passUsingFloatRegs = isValidFloatArgReg(argEntry->regNum);
}
@@ -3198,9 +3229,6 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
{
passUsingFloatRegs = varTypeIsFloating(argx);
}
-#else // WINDOWS_AMD64_ABI
- passUsingFloatRegs = varTypeIsFloating(argx);
-#endif // !UNIX_AMD64_ABI
#elif defined(_TARGET_X86_)
passUsingFloatRegs = false;
@@ -3216,7 +3244,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
bool isStructArg = varTypeIsStruct(argx);
- if (lateArgsComputed)
+ if (reMorphing)
{
#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
// Get the struct description for the already completed struct argument.
@@ -3260,7 +3288,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
// This size has now been computed
assert(size != 0);
}
- else // !lateArgsComputed
+ else // !reMorphing
{
//
// Figure out the size of the argument. This is either in number of registers, or number of
@@ -3287,7 +3315,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
}
}
#else // !FEATURE_UNIX_AMD64_STRUCT_PASSING
- size = 1; // On AMD64, all primitives fit in a single (64-bit) 'slot'
+ size = 1; // On AMD64, all primitives fit in a single (64-bit) 'slot'
#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
#elif defined(_TARGET_ARM64_)
if (isStructArg)
@@ -3379,7 +3407,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
GenTreePtr argObj = argx;
GenTreePtr* parentOfArgObj = parentArgx;
- assert(args->IsList());
+ assert(args->OperIsList());
assert(argx == args->Current());
/* The GT_OBJ may be be a child of a GT_COMMA */
@@ -3686,11 +3714,6 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
// the obj reading memory past the end of the valuetype
CLANG_FORMAT_COMMENT_ANCHOR;
-#if defined(_TARGET_X86_) && !defined(LEGACY_BACKEND)
- // TODO-X86-CQ: [1091733] Revisit for small structs, we should use push instruction
- copyBlkClass = objClass;
- size = roundupSize / TARGET_POINTER_SIZE; // Normalize size to number of pointer sized items
-#else // !defined(_TARGET_X86_) || defined(LEGACY_BACKEND)
if (roundupSize > originalSize)
{
copyBlkClass = objClass;
@@ -3705,7 +3728,6 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
}
size = roundupSize / TARGET_POINTER_SIZE; // Normalize size to number of pointer sized items
-#endif // !defined(_TARGET_X86_) || defined(LEGACY_BACKEND)
}
}
}
@@ -3841,7 +3863,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
}
}
#else // !defined(UNIX_AMD64_ABI)
- isRegArg = (intArgRegNum + (size - 1)) < maxRegArgs;
+ isRegArg = (intArgRegNum + (size - 1)) < maxRegArgs;
#endif // !defined(UNIX_AMD64_ABI)
#endif // _TARGET_ARM_
}
@@ -3850,8 +3872,19 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
isRegArg = false;
}
-#if defined(_TARGET_X86_) && !defined(LEGACY_BACKEND)
- if (call->IsTailCallViaHelper())
+#ifndef LEGACY_BACKEND
+ // If there are nonstandard args (outside the calling convention) they were inserted above
+ // and noted them in a table so we can recognize them here and build their argInfo.
+ //
+ // They should not affect the placement of any other args or stack space required.
+ // Example: on AMD64 R10 and R11 are used for indirect VSD (generic interface) and cookie calls.
+ isNonStandard = nonStandardArgs.FindReg(argx, &nonStdRegNum);
+ if (isNonStandard && (nonStdRegNum == REG_STK))
+ {
+ isRegArg = false;
+ }
+#if defined(_TARGET_X86_)
+ else if (call->IsTailCallViaHelper())
{
// We have already (before calling fgMorphArgs()) appended the 4 special args
// required by the x86 tailcall helper. These args are required to go on the
@@ -3862,9 +3895,9 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
isRegArg = false;
}
}
-#endif // defined(_TARGET_X86_) && !defined(LEGACY_BACKEND)
-
- } // end !lateArgsComputed
+#endif // defined(_TARGET_X86_)
+#endif // !LEGACY_BACKEND
+ } // end !reMorphing
//
// Now we know if the argument goes in registers or not and how big it is,
@@ -3943,23 +3976,17 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
#endif
fgArgTabEntryPtr newArgEntry;
- if (lateArgsComputed)
+ if (reMorphing)
{
// This is a register argument - possibly update it in the table
newArgEntry = call->fgArgInfo->RemorphRegArg(argIndex, argx, args, nextRegNum, size, argAlign);
}
else
{
- bool isNonStandard = false;
-
-#ifndef LEGACY_BACKEND
- // If there are nonstandard args (outside the calling convention) they were inserted above
- // and noted them in a table so we can recognize them here and build their argInfo.
- //
- // They should not affect the placement of any other args or stack space required.
- // Example: on AMD64 R10 and R11 are used for indirect VSD (generic interface) and cookie calls.
- isNonStandard = nonStandardArgs.FindReg(argx, &nextRegNum);
-#endif // !LEGACY_BACKEND
+ if (isNonStandard)
+ {
+ nextRegNum = nonStdRegNum;
+ }
// This is a register argument - put it in the table
newArgEntry = call->fgArgInfo->AddRegArg(argIndex, argx, args, nextRegNum, size, argAlign
@@ -4053,7 +4080,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
// If the register arguments have not been determined then we must fill in the argInfo
- if (lateArgsComputed)
+ if (reMorphing)
{
// This is a stack argument - possibly update it in the table
call->fgArgInfo->RemorphStkArg(argIndex, argx, args, size, argAlign);
@@ -4068,14 +4095,14 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
if (copyBlkClass != NO_CLASS_HANDLE)
{
- noway_assert(!lateArgsComputed);
+ noway_assert(!reMorphing);
fgMakeOutgoingStructArgCopy(call, args, argIndex,
copyBlkClass FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(&structDesc));
// This can cause a GTF_EXCEPT flag to be set.
// TODO-CQ: Fix the cases where this happens. We shouldn't be adding any new flags.
// This currently occurs in the case where we are re-morphing the args on x86/RyuJIT, and
- // there are no register arguments. Then lateArgsComputed is never true, so we keep re-copying
+ // there are no register arguments. Then reMorphing is never true, so we keep re-copying
// any struct arguments.
// i.e. assert(((call->gtFlags & GTF_EXCEPT) != 0) || ((args->Current()->gtFlags & GTF_EXCEPT) == 0)
flagsSummary |= (args->Current()->gtFlags & GTF_EXCEPT);
@@ -4088,10 +4115,21 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
#ifndef LEGACY_BACKEND
if (argx->gtOper == GT_MKREFANY)
{
- NYI_X86("MKREFANY");
-
// 'Lower' the MKREFANY tree and insert it.
- noway_assert(!lateArgsComputed);
+ noway_assert(!reMorphing);
+
+#ifdef _TARGET_X86_
+
+ // Build the mkrefany as a GT_FIELD_LIST
+ GenTreeFieldList* fieldList = new (this, GT_FIELD_LIST)
+ GenTreeFieldList(argx->gtOp.gtOp1, offsetof(CORINFO_RefAny, dataPtr), TYP_BYREF, nullptr);
+ (void)new (this, GT_FIELD_LIST)
+ GenTreeFieldList(argx->gtOp.gtOp2, offsetof(CORINFO_RefAny, type), TYP_I_IMPL, fieldList);
+ fgArgTabEntryPtr fp = Compiler::gtArgEntryByNode(call, argx);
+ fp->node = fieldList;
+ args->gtOp.gtOp1 = fieldList;
+
+#else // !_TARGET_X86_
// Get a new temp
// Here we don't need unsafe value cls check since the addr of temp is used only in mkrefany
@@ -4117,9 +4155,47 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
// EvalArgsToTemps will cause tmp to actually get loaded as the argument
call->fgArgInfo->EvalToTmp(argIndex, tmp, asg);
lvaSetVarAddrExposed(tmp);
+#endif // !_TARGET_X86_
}
#endif // !LEGACY_BACKEND
+#if defined(_TARGET_X86_) && !defined(LEGACY_BACKEND)
+ if (isStructArg)
+ {
+ GenTree* lclNode = fgIsIndirOfAddrOfLocal(argx);
+ if ((lclNode != nullptr) &&
+ (lvaGetPromotionType(lclNode->AsLclVarCommon()->gtLclNum) == Compiler::PROMOTION_TYPE_INDEPENDENT))
+ {
+ // Make a GT_FIELD_LIST of the field lclVars.
+ GenTreeLclVarCommon* lcl = lclNode->AsLclVarCommon();
+ LclVarDsc* varDsc = &(lvaTable[lcl->gtLclNum]);
+ GenTreeFieldList* fieldList = nullptr;
+ for (unsigned fieldLclNum = varDsc->lvFieldLclStart;
+ fieldLclNum < varDsc->lvFieldLclStart + varDsc->lvFieldCnt; ++fieldLclNum)
+ {
+ LclVarDsc* fieldVarDsc = &lvaTable[fieldLclNum];
+ if (fieldList == nullptr)
+ {
+ lcl->SetLclNum(fieldLclNum);
+ lcl->ChangeOper(GT_LCL_VAR);
+ lcl->gtType = fieldVarDsc->lvType;
+ fieldList = new (this, GT_FIELD_LIST)
+ GenTreeFieldList(lcl, fieldVarDsc->lvFldOffset, fieldVarDsc->lvType, nullptr);
+ fgArgTabEntryPtr fp = Compiler::gtArgEntryByNode(call, argx);
+ fp->node = fieldList;
+ args->gtOp.gtOp1 = fieldList;
+ }
+ else
+ {
+ GenTree* fieldLcl = gtNewLclvNode(fieldLclNum, fieldVarDsc->lvType);
+ fieldList = new (this, GT_FIELD_LIST)
+ GenTreeFieldList(fieldLcl, fieldVarDsc->lvFldOffset, fieldVarDsc->lvType, fieldList);
+ }
+ }
+ }
+ }
+#endif // defined (_TARGET_X86_) && !defined(LEGACY_BACKEND)
+
#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
if (isStructArg && !isRegArg)
{
@@ -4132,7 +4208,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
}
} // end foreach argument loop
- if (!lateArgsComputed)
+ if (!reMorphing)
{
call->fgArgInfo->ArgsComplete();
#ifdef LEGACY_BACKEND
@@ -4240,11 +4316,11 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
// For UNIX_AMD64, the condition without hasStackArgCopy cannot catch
// all cases of fgMakeOutgoingStructArgCopy() being called. hasStackArgCopy
// is added to make sure to call EvalArgsToTemp.
- if (!lateArgsComputed && (call->fgArgInfo->HasRegArgs()
+ if (!reMorphing && (call->fgArgInfo->HasRegArgs()
#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
- || hasStackArgCopy
+ || hasStackArgCopy
#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
- ))
+ ))
{
// This is the first time that we morph this call AND it has register arguments.
// Follow into the code below and do the 'defer or eval to temp' analysis.
@@ -4271,7 +4347,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
// In the future we can migrate UNIX_AMD64 to use this
// method instead of fgMorphSystemVStructArgs
- // We only build GT_LISTs for MultiReg structs for the RyuJIT backend
+ // We only build GT_FIELD_LISTs for MultiReg structs for the RyuJIT backend
if (hasMultiregStructArgs)
{
fgMorphMultiregStructArgs(call);
@@ -4334,7 +4410,7 @@ void Compiler::fgMorphSystemVStructArgs(GenTreeCall* call, bool hasStructArgumen
{
for (GenTreePtr list = call->gtCallLateArgs; list; list = list->MoveNext())
{
- assert(list->IsList());
+ assert(list->OperIsList());
GenTreePtr argNode = list->Current();
if (argx == argNode)
@@ -4355,7 +4431,7 @@ void Compiler::fgMorphSystemVStructArgs(GenTreeCall* call, bool hasStructArgumen
{
var_types originalType = type;
// If we have already processed the arg...
- if (arg->OperGet() == GT_LIST && varTypeIsStruct(arg))
+ if (arg->OperGet() == GT_FIELD_LIST && varTypeIsStruct(arg))
{
continue;
}
@@ -4386,6 +4462,16 @@ void Compiler::fgMorphSystemVStructArgs(GenTreeCall* call, bool hasStructArgumen
// Create LCL_FLD for each eightbyte.
argListCreated = true;
+ // First eightbyte.
+ arg->AsLclFld()->gtFieldSeq = FieldSeqStore::NotAField();
+ arg->gtType =
+ GetTypeFromClassificationAndSizes(fgEntryPtr->structDesc.eightByteClassifications[0],
+ fgEntryPtr->structDesc.eightByteSizes[0]);
+ GenTreeFieldList* fieldList =
+ new (this, GT_FIELD_LIST) GenTreeFieldList(arg, 0, originalType, nullptr);
+ fieldList->gtType = originalType; // Preserve the type. It is a special case.
+ arg = fieldList;
+
// Second eightbyte.
GenTreeLclFld* newLclField = new (this, GT_LCL_FLD)
GenTreeLclFld(GetTypeFromClassificationAndSizes(fgEntryPtr->structDesc
@@ -4393,17 +4479,9 @@ void Compiler::fgMorphSystemVStructArgs(GenTreeCall* call, bool hasStructArgumen
fgEntryPtr->structDesc.eightByteSizes[1]),
lclCommon->gtLclNum, fgEntryPtr->structDesc.eightByteOffsets[1]);
- GenTreeArgList* aggregate = gtNewAggregate(newLclField);
- aggregate->gtType = originalType; // Preserve the type. It is a special case.
- newLclField->gtFieldSeq = FieldSeqStore::NotAField();
-
- // First field
- arg->AsLclFld()->gtFieldSeq = FieldSeqStore::NotAField();
- arg->gtType =
- GetTypeFromClassificationAndSizes(fgEntryPtr->structDesc.eightByteClassifications[0],
- fgEntryPtr->structDesc.eightByteSizes[0]);
- arg = aggregate->Prepend(this, arg);
- arg->gtType = type; // Preserve the type. It is a special case.
+ fieldList = new (this, GT_FIELD_LIST) GenTreeFieldList(newLclField, 0, originalType, fieldList);
+ fieldList->gtType = originalType; // Preserve the type. It is a special case.
+ newLclField->gtFieldSeq = FieldSeqStore::NotAField();
}
else
{
@@ -4450,7 +4528,7 @@ void Compiler::fgMorphSystemVStructArgs(GenTreeCall* call, bool hasStructArgumen
{
for (GenTreePtr list = call->gtCallLateArgs; list; list = list->MoveNext())
{
- assert(list->IsList());
+ assert(list->OperIsList());
GenTreePtr argNode = list->Current();
if (argx == argNode)
@@ -4490,8 +4568,8 @@ void Compiler::fgMorphSystemVStructArgs(GenTreeCall* call, bool hasStructArgumen
//
// Notes:
// We only call fgMorphMultiregStructArg for the register passed TYP_STRUCT arguments.
-// The call to fgMorphMultiregStructArg will mutate the argument into the GT_LIST form
-// whicj is only used for register arguments.
+// The call to fgMorphMultiregStructArg will mutate the argument into the GT_FIELD_LIST form
+// which is only used for struct arguments.
// If this method fails to find any TYP_STRUCT arguments it will assert.
//
void Compiler::fgMorphMultiregStructArgs(GenTreeCall* call)
@@ -4540,7 +4618,7 @@ void Compiler::fgMorphMultiregStructArgs(GenTreeCall* call)
{
for (GenTreePtr list = call->gtCallLateArgs; list; list = list->MoveNext())
{
- assert(list->IsList());
+ assert(list->OperIsList());
GenTreePtr argNode = list->Current();
if (argx == argNode)
@@ -4588,7 +4666,7 @@ void Compiler::fgMorphMultiregStructArgs(GenTreeCall* call)
//-----------------------------------------------------------------------------
// fgMorphMultiregStructArg: Given a multireg TYP_STRUCT arg from a call argument list
-// Morph the argument into a set of GT_LIST nodes.
+// Morph the argument into a set of GT_FIELD_LIST nodes.
//
// Arguments:
// arg - A GenTree node containing a TYP_STRUCT arg that
@@ -4600,7 +4678,7 @@ void Compiler::fgMorphMultiregStructArgs(GenTreeCall* call)
// for passing in multiple registers.
// If arg is a LclVar we check if it is struct promoted and has the right number of fields
// and if they are at the appropriate offsets we will use the struct promted fields
-// in the GT_LIST nodes that we create.
+// in the GT_FIELD_LIST nodes that we create.
// If we have a GT_LCL_VAR that isn't struct promoted or doesn't meet the requirements
// we will use a set of GT_LCL_FLDs nodes to access the various portions of the struct
// this also forces the struct to be stack allocated into the local frame.
@@ -4715,7 +4793,7 @@ GenTreePtr Compiler::fgMorphMultiregStructArg(GenTreePtr arg, fgArgTabEntryPtr f
// We should still have a TYP_STRUCT
assert(argValue->TypeGet() == TYP_STRUCT);
- GenTreeArgList* newArg = nullptr;
+ GenTreeFieldList* newArg = nullptr;
// Are we passing a struct LclVar?
//
@@ -4817,9 +4895,10 @@ GenTreePtr Compiler::fgMorphMultiregStructArg(GenTreePtr arg, fgArgTabEntryPtr f
// Create a new tree for 'arg'
// replace the existing LDOBJ(ADDR(LCLVAR))
- // with a LIST(LCLVAR-LO, LIST(LCLVAR-HI, nullptr))
+ // with a FIELD_LIST(LCLVAR-LO, FIELD_LIST(LCLVAR-HI, nullptr))
//
- newArg = gtNewAggregate(hiLclVar)->Prepend(this, loLclVar);
+ newArg = new (this, GT_FIELD_LIST) GenTreeFieldList(loLclVar, 0, loType, nullptr);
+ (void)new (this, GT_FIELD_LIST) GenTreeFieldList(hiLclVar, TARGET_POINTER_SIZE, hiType, newArg);
}
}
}
@@ -4885,27 +4964,22 @@ GenTreePtr Compiler::fgMorphMultiregStructArg(GenTreePtr arg, fgArgTabEntryPtr f
//
lvaSetVarDoNotEnregister(varNum DEBUG_ARG(DNER_LocalField));
- // Start building our list from the last element
- unsigned offset = lastOffset;
- unsigned inx = elemCount;
-
// Create a new tree for 'arg'
// replace the existing LDOBJ(ADDR(LCLVAR))
- // with a LIST(LCLFLD-LO, LIST(LCLFLD-HI, nullptr) ...)
+ // with a FIELD_LIST(LCLFLD-LO, FIELD_LIST(LCLFLD-HI, nullptr) ...)
//
- while (inx > 0)
+ unsigned offset = 0;
+ GenTreeFieldList* listEntry = nullptr;
+ for (unsigned inx = 0; inx < elemCount; inx++)
{
- inx--;
- offset -= elemSize;
+ elemSize = genTypeSize(type[inx]);
GenTreePtr nextLclFld = gtNewLclFldNode(varNum, type[inx], offset);
+ listEntry = new (this, GT_FIELD_LIST) GenTreeFieldList(nextLclFld, offset, type[inx], listEntry);
if (newArg == nullptr)
{
- newArg = gtNewAggregate(nextLclFld);
- }
- else
- {
- newArg = newArg->Prepend(this, nextLclFld);
+ newArg = listEntry;
}
+ offset += elemSize;
}
}
// Are we passing a GT_OBJ struct?
@@ -4918,17 +4992,14 @@ GenTreePtr Compiler::fgMorphMultiregStructArg(GenTreePtr arg, fgArgTabEntryPtr f
// Create a new tree for 'arg'
// replace the existing LDOBJ(EXPR)
- // with a LIST(IND(EXPR), LIST(IND(EXPR+8), nullptr) ...)
+ // with a FIELD_LIST(IND(EXPR), FIELD_LIST(IND(EXPR+8), nullptr) ...)
//
- // Start building our list from the last element
- unsigned offset = structSize;
- unsigned inx = elemCount;
- while (inx > 0)
+ unsigned offset = 0;
+ GenTreeFieldList* listEntry = nullptr;
+ for (unsigned inx = 0; inx < elemCount; inx++)
{
- inx--;
- elemSize = genTypeSize(type[inx]);
- offset -= elemSize;
+ elemSize = genTypeSize(type[inx]);
GenTreePtr curAddr = baseAddr;
if (offset != 0)
{
@@ -4941,14 +5012,21 @@ GenTreePtr Compiler::fgMorphMultiregStructArg(GenTreePtr arg, fgArgTabEntryPtr f
curAddr = baseAddr;
}
GenTreePtr curItem = gtNewOperNode(GT_IND, type[inx], curAddr);
- if (newArg == nullptr)
+
+ // For safety all GT_IND should have at least GT_GLOB_REF set.
+ curItem->gtFlags |= GTF_GLOB_REF;
+ if (fgAddrCouldBeNull(curItem))
{
- newArg = gtNewAggregate(curItem);
+ // This indirection can cause a GPF if the address could be null.
+ curItem->gtFlags |= GTF_EXCEPT;
}
- else
+
+ listEntry = new (this, GT_FIELD_LIST) GenTreeFieldList(curItem, offset, type[inx], listEntry);
+ if (newArg == nullptr)
{
- newArg = newArg->Prepend(this, curItem);
+ newArg = listEntry;
}
+ offset += elemSize;
}
}
}
@@ -5674,7 +5752,7 @@ GenTreePtr Compiler::fgMorphArrayIndex(GenTreePtr tree)
addr = gtNewOperNode(GT_ADD, TYP_BYREF, addr, cns);
#if SMALL_TREE_NODES
- assert(tree->gtDebugFlags & GTF_DEBUG_NODE_LARGE);
+ assert((tree->gtDebugFlags & GTF_DEBUG_NODE_LARGE) || GenTree::s_gtNodeSizes[GT_IND] == TREE_NODE_SZ_SMALL);
#endif
// Change the orginal GT_INDEX node into a GT_IND node
@@ -5847,7 +5925,15 @@ GenTreePtr Compiler::fgMorphStackArgForVarArgs(unsigned lclNum, var_types varTyp
lclOffs));
// Access the argument through the local
- GenTreePtr tree = gtNewOperNode(GT_IND, varType, ptrArg);
+ GenTreePtr tree;
+ if (varType == TYP_STRUCT)
+ {
+ tree = gtNewBlockVal(ptrArg, varDsc->lvExactSize);
+ }
+ else
+ {
+ tree = gtNewOperNode(GT_IND, varType, ptrArg);
+ }
tree->gtFlags |= GTF_IND_TGTANYWHERE;
if (varDsc->lvAddrExposed)
@@ -5884,8 +5970,14 @@ GenTreePtr Compiler::fgMorphLocalVar(GenTreePtr tree)
if (info.compIsVarArgs)
{
GenTreePtr newTree = fgMorphStackArgForVarArgs(lclNum, varType, 0);
- if (newTree != NULL)
+ if (newTree != nullptr)
+ {
+ if (newTree->OperIsBlk() && ((tree->gtFlags & GTF_VAR_DEF) == 0))
+ {
+ fgMorphBlkToInd(newTree->AsBlk(), newTree->gtType);
+ }
return newTree;
+ }
}
#endif // _TARGET_X86_
@@ -6205,7 +6297,9 @@ GenTreePtr Compiler::fgMorphField(GenTreePtr tree, MorphAddrContext* mac)
GenTreePtr baseOffset = gtNewIconEmbHndNode(tree->gtField.gtFieldLookup.addr, nullptr, GTF_ICON_FIELD_HDL);
if (tree->gtField.gtFieldLookup.accessType == IAT_PVALUE)
+ {
baseOffset = gtNewOperNode(GT_IND, TYP_I_IMPL, baseOffset);
+ }
addr =
gtNewOperNode(GT_ADD, (var_types)(objRefType == TYP_I_IMPL ? TYP_I_IMPL : TYP_BYREF), addr, baseOffset);
@@ -6483,8 +6577,8 @@ void Compiler::fgMorphCallInline(GenTreeCall* call, InlineResult* inlineResult)
// hanging a "nothing" node to it. Later the "nothing" node will be removed
// and the original GT_CALL tree will be picked up by the GT_RET_EXPR node.
- noway_assert(fgMorphStmt->gtStmt.gtStmtExpr == call);
- fgMorphStmt->gtStmt.gtStmtExpr = gtNewNothingNode();
+ noway_assert(fgMorphStmt->gtStmtExpr == call);
+ fgMorphStmt->gtStmtExpr = gtNewNothingNode();
}
// Clear the Inline Candidate flag so we can ensure later we tried
@@ -6662,7 +6756,7 @@ bool Compiler::fgCanFastTailCall(GenTreeCall* callee)
{
nCalleeArgs++;
- assert(args->IsList());
+ assert(args->OperIsList());
GenTreePtr argx = args->gtOp.gtOp1;
if (varTypeIsStruct(argx))
@@ -6980,7 +7074,14 @@ void Compiler::fgMorphTailCall(GenTreeCall* call)
}
#endif // _TARGET_X86_
+#if defined(_TARGET_X86_)
+ // When targeting x86, the runtime requires that we perforrm a null check on the `this` argument before tail
+ // calling to a virtual dispatch stub. This requirement is a consequence of limitations in the runtime's
+ // ability to map an AV to a NullReferenceException if the AV occurs in a dispatch stub.
+ if (call->NeedsNullCheck() || call->IsVirtualStub())
+#else
if (call->NeedsNullCheck())
+#endif // defined(_TARGET_X86_)
{
// clone "this" if "this" has no side effects.
if ((thisPtr == nullptr) && !(objp->gtFlags & GTF_SIDE_EFFECT))
@@ -7668,17 +7769,39 @@ GenTreePtr Compiler::fgMorphCall(GenTreeCall* call)
}
#endif
- GenTreePtr stmtExpr = fgMorphStmt->gtStmt.gtStmtExpr;
+ GenTreePtr stmtExpr = fgMorphStmt->gtStmtExpr;
#ifdef DEBUG
// Tail call needs to be in one of the following IR forms
// Either a call stmt or
- // GT_RETURN(GT_CALL(..)) or
- // var = call
- noway_assert((stmtExpr->gtOper == GT_CALL && stmtExpr == call) ||
- (stmtExpr->gtOper == GT_RETURN &&
- (stmtExpr->gtOp.gtOp1 == call || stmtExpr->gtOp.gtOp1->gtOp.gtOp1 == call)) ||
- (stmtExpr->gtOper == GT_ASG && stmtExpr->gtOp.gtOp2 == call));
+ // GT_RETURN(GT_CALL(..)) or GT_RETURN(GT_CAST(GT_CALL(..)))
+ // var = GT_CALL(..) or var = (GT_CAST(GT_CALL(..)))
+ genTreeOps stmtOper = stmtExpr->gtOper;
+ if (stmtOper == GT_CALL)
+ {
+ noway_assert(stmtExpr == call);
+ }
+ else
+ {
+ noway_assert(stmtOper == GT_RETURN || stmtOper == GT_ASG);
+ GenTreePtr treeWithCall;
+ if (stmtOper == GT_RETURN)
+ {
+ treeWithCall = stmtExpr->gtGetOp1();
+ }
+ else
+ {
+ treeWithCall = stmtExpr->gtGetOp2();
+ }
+ if (treeWithCall->gtOper == GT_CAST)
+ {
+ noway_assert(treeWithCall->gtGetOp1() == call && !treeWithCall->gtOverflow());
+ }
+ else
+ {
+ noway_assert(treeWithCall == call);
+ }
+ }
#endif
// For void calls, we would have created a GT_CALL in the stmt list.
@@ -7687,7 +7810,7 @@ GenTreePtr Compiler::fgMorphCall(GenTreeCall* call)
// For debuggable code, it would be an assignment of the call to a temp
// We want to get rid of any of this extra trees, and just leave
// the call.
- GenTreePtr nextMorphStmt = fgMorphStmt->gtNext;
+ GenTreeStmt* nextMorphStmt = fgMorphStmt->gtNextStmt;
#ifdef _TARGET_AMD64_
// Legacy Jit64 Compat:
@@ -7703,46 +7826,46 @@ GenTreePtr Compiler::fgMorphCall(GenTreeCall* call)
if ((stmtExpr->gtOper == GT_CALL) || (stmtExpr->gtOper == GT_ASG))
{
// First delete all GT_NOPs after the call
- GenTreePtr morphStmtToRemove = nullptr;
+ GenTreeStmt* morphStmtToRemove = nullptr;
while (nextMorphStmt != nullptr)
{
- GenTreePtr nextStmtExpr = nextMorphStmt->gtStmt.gtStmtExpr;
+ GenTreePtr nextStmtExpr = nextMorphStmt->gtStmtExpr;
if (!nextStmtExpr->IsNothingNode())
{
break;
}
morphStmtToRemove = nextMorphStmt;
- nextMorphStmt = morphStmtToRemove->gtNext;
+ nextMorphStmt = morphStmtToRemove->gtNextStmt;
fgRemoveStmt(compCurBB, morphStmtToRemove);
}
// Check to see if there is a pop.
// Since tail call is honored, we can get rid of the stmt corresponding to pop.
- if (nextMorphStmt != nullptr && nextMorphStmt->gtStmt.gtStmtExpr->gtOper != GT_RETURN)
+ if (nextMorphStmt != nullptr && nextMorphStmt->gtStmtExpr->gtOper != GT_RETURN)
{
// Note that pop opcode may or may not result in a new stmt (for details see
// impImportBlockCode()). Hence, it is not possible to assert about the IR
// form generated by pop but pop tree must be side-effect free so that we can
// delete it safely.
- GenTreePtr popStmt = nextMorphStmt;
- nextMorphStmt = nextMorphStmt->gtNext;
+ GenTreeStmt* popStmt = nextMorphStmt;
+ nextMorphStmt = nextMorphStmt->gtNextStmt;
- noway_assert((popStmt->gtStmt.gtStmtExpr->gtFlags & GTF_ALL_EFFECT) == 0);
+ noway_assert((popStmt->gtStmtExpr->gtFlags & GTF_ALL_EFFECT) == 0);
fgRemoveStmt(compCurBB, popStmt);
}
// Next delete any GT_NOP nodes after pop
while (nextMorphStmt != nullptr)
{
- GenTreePtr nextStmtExpr = nextMorphStmt->gtStmt.gtStmtExpr;
+ GenTreePtr nextStmtExpr = nextMorphStmt->gtStmtExpr;
if (!nextStmtExpr->IsNothingNode())
{
break;
}
morphStmtToRemove = nextMorphStmt;
- nextMorphStmt = morphStmtToRemove->gtNext;
+ nextMorphStmt = morphStmtToRemove->gtNextStmt;
fgRemoveStmt(compCurBB, morphStmtToRemove);
}
}
@@ -7751,7 +7874,7 @@ GenTreePtr Compiler::fgMorphCall(GenTreeCall* call)
// Delete GT_RETURN if any
if (nextMorphStmt != nullptr)
{
- GenTreePtr retExpr = nextMorphStmt->gtStmt.gtStmtExpr;
+ GenTreePtr retExpr = nextMorphStmt->gtStmtExpr;
noway_assert(retExpr->gtOper == GT_RETURN);
// If var=call, then the next stmt must be a GT_RETURN(TYP_VOID) or GT_RETURN(var).
@@ -7766,7 +7889,7 @@ GenTreePtr Compiler::fgMorphCall(GenTreeCall* call)
fgRemoveStmt(compCurBB, nextMorphStmt);
}
- fgMorphStmt->gtStmt.gtStmtExpr = call;
+ fgMorphStmt->gtStmtExpr = call;
// Tail call via helper: The VM can't use return address hijacking if we're
// not going to return and the helper doesn't have enough info to safely poll,
@@ -7855,7 +7978,7 @@ NO_TAIL_CALL:
|| call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_READYTORUN_VIRTUAL_FUNC_PTR)
#endif
) &&
- (call == fgMorphStmt->gtStmt.gtStmtExpr))
+ (call == fgMorphStmt->gtStmtExpr))
{
// This is call to CORINFO_HELP_VIRTUAL_FUNC_PTR with ignored result.
// Transform it into a null check.
@@ -8008,31 +8131,72 @@ NO_TAIL_CALL:
// This needs to be done after the arguments are morphed to ensure constant propagation has already taken place.
if ((call->gtCallType == CT_HELPER) && (call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_ARRADDR_ST)))
{
- GenTreePtr value = gtArgEntryByArgNum(call, 2)->node;
-
+ GenTree* value = gtArgEntryByArgNum(call, 2)->node;
if (value->IsIntegralConst(0))
{
assert(value->OperGet() == GT_CNS_INT);
- GenTreePtr arr = gtArgEntryByArgNum(call, 0)->node;
- GenTreePtr index = gtArgEntryByArgNum(call, 1)->node;
- arr = gtClone(arr, true);
- if (arr != nullptr)
+ GenTree* arr = gtArgEntryByArgNum(call, 0)->node;
+ GenTree* index = gtArgEntryByArgNum(call, 1)->node;
+
+ // Either or both of the array and index arguments may have been spilled to temps by `fgMorphArgs`. Copy
+ // the spill trees as well if necessary.
+ GenTreeOp* argSetup = nullptr;
+ for (GenTreeArgList* earlyArgs = call->gtCallArgs; earlyArgs != nullptr; earlyArgs = earlyArgs->Rest())
{
- index = gtClone(index, true);
- if (index != nullptr)
+ GenTree* const arg = earlyArgs->Current();
+ if (arg->OperGet() != GT_ASG)
{
- value = gtClone(value);
- noway_assert(value != nullptr);
+ continue;
+ }
+
+ assert(arg != arr);
+ assert(arg != index);
- GenTreePtr nullCheckedArr = impCheckForNullPointer(arr);
- GenTreePtr arrIndexNode = gtNewIndexRef(TYP_REF, nullCheckedArr, index);
- GenTreePtr arrStore = gtNewAssignNode(arrIndexNode, value);
- arrStore->gtFlags |= GTF_ASG;
+ arg->gtFlags &= ~GTF_LATE_ARG;
- return fgMorphTree(arrStore);
+ GenTree* op1 = argSetup;
+ if (op1 == nullptr)
+ {
+ op1 = gtNewNothingNode();
+#if DEBUG
+ op1->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED;
+#endif // DEBUG
}
+
+ argSetup = new (this, GT_COMMA) GenTreeOp(GT_COMMA, TYP_VOID, op1, arg);
+
+#if DEBUG
+ argSetup->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED;
+#endif // DEBUG
}
+
+#ifdef DEBUG
+ auto resetMorphedFlag = [](GenTree** slot, fgWalkData* data) -> fgWalkResult {
+ (*slot)->gtDebugFlags &= ~GTF_DEBUG_NODE_MORPHED;
+ return WALK_CONTINUE;
+ };
+
+ fgWalkTreePost(&arr, resetMorphedFlag);
+ fgWalkTreePost(&index, resetMorphedFlag);
+ fgWalkTreePost(&value, resetMorphedFlag);
+#endif // DEBUG
+
+ GenTree* const nullCheckedArr = impCheckForNullPointer(arr);
+ GenTree* const arrIndexNode = gtNewIndexRef(TYP_REF, nullCheckedArr, index);
+ GenTree* const arrStore = gtNewAssignNode(arrIndexNode, value);
+ arrStore->gtFlags |= GTF_ASG;
+
+ GenTree* result = fgMorphTree(arrStore);
+ if (argSetup != nullptr)
+ {
+ result = new (this, GT_COMMA) GenTreeOp(GT_COMMA, TYP_VOID, argSetup, result);
+#if DEBUG
+ result->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED;
+#endif // DEBUG
+ }
+
+ return result;
}
}
@@ -8187,8 +8351,14 @@ GenTreePtr Compiler::fgMorphLeaf(GenTreePtr tree)
{
GenTreePtr newTree =
fgMorphStackArgForVarArgs(tree->gtLclFld.gtLclNum, tree->gtType, tree->gtLclFld.gtLclOffs);
- if (newTree != NULL)
+ if (newTree != nullptr)
+ {
+ if (newTree->OperIsBlk() && ((tree->gtFlags & GTF_VAR_DEF) == 0))
+ {
+ fgMorphBlkToInd(newTree->AsBlk(), newTree->gtType);
+ }
return newTree;
+ }
}
}
#endif // _TARGET_X86_
@@ -8390,7 +8560,7 @@ GenTreePtr Compiler::fgMorphOneAsgBlockOp(GenTreePtr tree)
// with the bits to create a single assigment.
noway_assert(size <= REGSIZE_BYTES);
- if (isInitBlock && (src->gtOper != GT_CNS_INT))
+ if (isInitBlock && !src->IsConstInitVal())
{
return nullptr;
}
@@ -8563,8 +8733,12 @@ GenTreePtr Compiler::fgMorphOneAsgBlockOp(GenTreePtr tree)
}
else
#endif
- if (src->IsCnsIntOrI())
{
+ if (src->OperIsInitVal())
+ {
+ src = src->gtGetOp1();
+ }
+ assert(src->IsCnsIntOrI());
// This will mutate the integer constant, in place, to be the correct
// value for the type we are using in the assignment.
src->AsIntCon()->FixupInitBlkValue(asgType);
@@ -8632,7 +8806,8 @@ GenTreePtr Compiler::fgMorphOneAsgBlockOp(GenTreePtr tree)
GenTreePtr Compiler::fgMorphInitBlock(GenTreePtr tree)
{
- noway_assert(tree->gtOper == GT_ASG && varTypeIsStruct(tree));
+ // We must have the GT_ASG form of InitBlkOp.
+ noway_assert((tree->OperGet() == GT_ASG) && tree->OperIsInitBlkOp());
#ifdef DEBUG
bool morphed = false;
#endif // DEBUG
@@ -8647,6 +8822,12 @@ GenTreePtr Compiler::fgMorphInitBlock(GenTreePtr tree)
tree->gtOp.gtOp1 = dest;
}
tree->gtType = dest->TypeGet();
+ // (Constant propagation may cause a TYP_STRUCT lclVar to be changed to GT_CNS_INT, and its
+ // type will be the type of the original lclVar, in which case we will change it to TYP_INT).
+ if ((src->OperGet() == GT_CNS_INT) && varTypeIsStruct(src))
+ {
+ src->gtType = TYP_INT;
+ }
JITDUMP("\nfgMorphInitBlock:");
GenTreePtr oneAsgTree = fgMorphOneAsgBlockOp(tree);
@@ -8658,7 +8839,7 @@ GenTreePtr Compiler::fgMorphInitBlock(GenTreePtr tree)
else
{
GenTree* destAddr = nullptr;
- GenTree* initVal = src;
+ GenTree* initVal = src->OperIsInitVal() ? src->gtGetOp1() : src;
GenTree* blockSize = nullptr;
unsigned blockWidth = 0;
FieldSeqNode* destFldSeq = nullptr;
@@ -8727,6 +8908,7 @@ GenTreePtr Compiler::fgMorphInitBlock(GenTreePtr tree)
if (destLclVar->lvPromoted && blockWidthIsConst)
{
+ assert(initVal->OperGet() == GT_CNS_INT);
noway_assert(varTypeIsStruct(destLclVar));
noway_assert(!opts.MinOpts());
if (destLclVar->lvAddrExposed & destLclVar->lvContainsHoles)
@@ -8786,25 +8968,9 @@ GenTreePtr Compiler::fgMorphInitBlock(GenTreePtr tree)
#if CPU_USES_BLOCK_MOVE
compBlkOpUsed = true;
#endif
- if (!dest->OperIsBlk())
- {
- GenTree* destAddr = gtNewOperNode(GT_ADDR, TYP_BYREF, dest);
- CORINFO_CLASS_HANDLE clsHnd = gtGetStructHandleIfPresent(dest);
- if (clsHnd == NO_CLASS_HANDLE)
- {
- dest = new (this, GT_BLK) GenTreeBlk(GT_BLK, dest->TypeGet(), destAddr, blockWidth);
- }
- else
- {
- GenTree* newDest = gtNewObjNode(clsHnd, destAddr);
- if (newDest->OperGet() == GT_OBJ)
- {
- gtSetObjGcInfo(newDest->AsObj());
- }
- dest = newDest;
- }
- tree->gtOp.gtOp1 = dest;
- }
+ dest = fgMorphBlockOperand(dest, dest->TypeGet(), blockWidth, true);
+ tree->gtOp.gtOp1 = dest;
+ tree->gtFlags |= (dest->gtFlags & GTF_ALL_EFFECT);
}
else
{
@@ -9068,9 +9234,18 @@ GenTree* Compiler::fgMorphBlkNode(GenTreePtr tree, bool isDest)
if (blkNode->AsDynBlk()->gtDynamicSize->IsCnsIntOrI())
{
unsigned size = (unsigned)blkNode->AsDynBlk()->gtDynamicSize->AsIntConCommon()->IconValue();
- blkNode->AsDynBlk()->gtDynamicSize = nullptr;
- blkNode->ChangeOper(GT_BLK);
- blkNode->gtBlkSize = size;
+ // A GT_BLK with size of zero is not supported,
+ // so if we encounter such a thing we just leave it as a GT_DYN_BLK
+ if (size != 0)
+ {
+ blkNode->AsDynBlk()->gtDynamicSize = nullptr;
+ blkNode->ChangeOper(GT_BLK);
+ blkNode->gtBlkSize = size;
+ }
+ else
+ {
+ return tree;
+ }
}
else
{
@@ -9104,7 +9279,7 @@ GenTree* Compiler::fgMorphBlkNode(GenTreePtr tree, bool isDest)
//
// Notes:
// This does the following:
-// - Ensures that a struct operand is a block node.
+// - Ensures that a struct operand is a block node or (for non-LEGACY_BACKEND) lclVar.
// - Ensures that any COMMAs are above ADDR nodes.
// Although 'tree' WAS an operand of a block assignment, the assignment
// may have been retyped to be a scalar assignment.
@@ -9113,10 +9288,6 @@ GenTree* Compiler::fgMorphBlockOperand(GenTree* tree, var_types asgType, unsigne
{
GenTree* effectiveVal = tree->gtEffectiveVal();
- // TODO-1stClassStucts: We would like to transform non-TYP_STRUCT nodes to
- // either plain lclVars or GT_INDs. However, for now we want to preserve most
- // of the block nodes until the Rationalizer.
-
if (!varTypeIsStruct(asgType))
{
if (effectiveVal->OperIsIndir())
@@ -9143,69 +9314,141 @@ GenTree* Compiler::fgMorphBlockOperand(GenTree* tree, var_types asgType, unsigne
}
else
{
+ GenTreeIndir* indirTree = nullptr;
+ GenTreeLclVarCommon* lclNode = nullptr;
+ bool needsIndirection = true;
+
+ if (effectiveVal->OperIsIndir())
+ {
+ indirTree = effectiveVal->AsIndir();
+ GenTree* addr = effectiveVal->AsIndir()->Addr();
+ if ((addr->OperGet() == GT_ADDR) && (addr->gtGetOp1()->OperGet() == GT_LCL_VAR))
+ {
+ lclNode = addr->gtGetOp1()->AsLclVarCommon();
+ }
+ }
+ else if (effectiveVal->OperGet() == GT_LCL_VAR)
+ {
+ lclNode = effectiveVal->AsLclVarCommon();
+ }
#ifdef FEATURE_SIMD
if (varTypeIsSIMD(asgType))
{
- if (effectiveVal->OperIsIndir())
+ if ((indirTree != nullptr) && (lclNode == nullptr) && (indirTree->Addr()->OperGet() == GT_ADDR) &&
+ (indirTree->Addr()->gtGetOp1()->gtOper == GT_SIMD))
{
- GenTree* addr = effectiveVal->AsIndir()->Addr();
- if (!isDest && (addr->OperGet() == GT_ADDR))
- {
- if ((addr->gtGetOp1()->gtOper == GT_SIMD) || (addr->gtGetOp1()->OperGet() == GT_LCL_VAR))
- {
- effectiveVal = addr->gtGetOp1();
- }
- }
- else if (isDest && !effectiveVal->OperIsBlk())
- {
- effectiveVal = new (this, GT_BLK) GenTreeBlk(GT_BLK, asgType, addr, blockWidth);
- }
+ assert(!isDest);
+ needsIndirection = false;
+ effectiveVal = indirTree->Addr()->gtGetOp1();
}
- else if (!effectiveVal->OperIsSIMD() && (!effectiveVal->IsLocal() || isDest) && !effectiveVal->OperIsBlk())
+ if (effectiveVal->OperIsSIMD())
{
- GenTree* addr = gtNewOperNode(GT_ADDR, TYP_BYREF, effectiveVal);
- effectiveVal = new (this, GT_BLK) GenTreeBlk(GT_BLK, asgType, addr, blockWidth);
+ needsIndirection = false;
}
}
- else
#endif // FEATURE_SIMD
- if (!effectiveVal->OperIsBlk())
+ if (lclNode != nullptr)
+ {
+ LclVarDsc* varDsc = &(lvaTable[lclNode->gtLclNum]);
+ if (varTypeIsStruct(varDsc) && (varDsc->lvExactSize == blockWidth))
+ {
+#ifndef LEGACY_BACKEND
+ effectiveVal = lclNode;
+ needsIndirection = false;
+#endif // !LEGACY_BACKEND
+ }
+ else
+ {
+ // This may be a lclVar that was determined to be address-exposed.
+ effectiveVal->gtFlags |= (lclNode->gtFlags & GTF_ALL_EFFECT);
+ }
+ }
+ if (needsIndirection)
{
- GenTree* addr = gtNewOperNode(GT_ADDR, TYP_BYREF, effectiveVal);
- CORINFO_CLASS_HANDLE clsHnd = gtGetStructHandleIfPresent(effectiveVal);
- GenTree* newTree;
- if (clsHnd == NO_CLASS_HANDLE)
+ if (indirTree != nullptr)
{
- newTree = new (this, GT_BLK) GenTreeBlk(GT_BLK, TYP_STRUCT, addr, blockWidth);
+ // We should never find a struct indirection on the lhs of an assignment.
+ assert(!isDest || indirTree->OperIsBlk());
+ if (!isDest && indirTree->OperIsBlk())
+ {
+ (void)fgMorphBlkToInd(effectiveVal->AsBlk(), asgType);
+ }
}
else
{
- newTree = gtNewObjNode(clsHnd, addr);
- if (isDest && (newTree->OperGet() == GT_OBJ))
+ GenTree* newTree;
+ GenTree* addr = gtNewOperNode(GT_ADDR, TYP_BYREF, effectiveVal);
+ if (isDest)
{
- gtSetObjGcInfo(newTree->AsObj());
+ CORINFO_CLASS_HANDLE clsHnd = gtGetStructHandleIfPresent(effectiveVal);
+ if (clsHnd == NO_CLASS_HANDLE)
+ {
+ newTree = new (this, GT_BLK) GenTreeBlk(GT_BLK, TYP_STRUCT, addr, blockWidth);
+ }
+ else
+ {
+ newTree = gtNewObjNode(clsHnd, addr);
+ if (isDest && (newTree->OperGet() == GT_OBJ))
+ {
+ gtSetObjGcInfo(newTree->AsObj());
+ }
+ if (effectiveVal->IsLocal() && ((effectiveVal->gtFlags & GTF_GLOB_EFFECT) == 0))
+ {
+ // This is not necessarily a global reference, though gtNewObjNode always assumes it is.
+ // TODO-1stClassStructs: This check should be done in the GenTreeObj constructor,
+ // where it currently sets GTF_GLOB_EFFECT unconditionally, but it is handled
+ // separately now to avoid excess diffs.
+ newTree->gtFlags &= ~(GTF_GLOB_EFFECT);
+ }
+ }
}
- if (effectiveVal->IsLocal() && ((effectiveVal->gtFlags & GTF_GLOB_EFFECT) == 0))
+ else
{
- // This is not necessarily a global reference, though gtNewObjNode always assumes it is.
- // TODO-1stClassStructs: This check should be done in the GenTreeObj constructor,
- // where it currently sets GTF_GLOB_EFFECT unconditionally, but it is handled
- // separately now to avoid excess diffs.
- newTree->gtFlags &= ~(GTF_GLOB_EFFECT);
+ newTree = new (this, GT_IND) GenTreeIndir(GT_IND, asgType, addr, nullptr);
}
+ effectiveVal = newTree;
}
- effectiveVal = newTree;
}
}
- if (!isDest && effectiveVal->OperIsBlk())
- {
- (void)fgMorphBlkToInd(effectiveVal->AsBlk(), asgType);
- }
tree = effectiveVal;
return tree;
}
//------------------------------------------------------------------------
+// fgMorphUnsafeBlk: Convert a CopyObj with a dest on the stack to a GC Unsafe CopyBlk
+//
+// Arguments:
+// dest - the GT_OBJ or GT_STORE_OBJ
+//
+// Assumptions:
+// The destination must be known (by the caller) to be on the stack.
+//
+// Notes:
+// If we have a CopyObj with a dest on the stack, and its size is small enouch
+// to be completely unrolled (i.e. between [16..64] bytes), we will convert it into a
+// GC Unsafe CopyBlk that is non-interruptible.
+// This is not supported for the JIT32_GCENCODER, in which case this method is a no-op.
+//
+void Compiler::fgMorphUnsafeBlk(GenTreeObj* dest)
+{
+#if defined(CPBLK_UNROLL_LIMIT) && !defined(JIT32_GCENCODER)
+ assert(dest->gtGcPtrCount != 0);
+ unsigned blockWidth = dest->AsBlk()->gtBlkSize;
+#ifdef DEBUG
+ bool destOnStack = false;
+ GenTree* destAddr = dest->Addr();
+ assert(destAddr->IsLocalAddrExpr() != nullptr);
+#endif
+ if ((blockWidth >= (2 * TARGET_POINTER_SIZE)) && (blockWidth <= CPBLK_UNROLL_LIMIT))
+ {
+ genTreeOps newOper = (dest->gtOper == GT_OBJ) ? GT_BLK : GT_STORE_BLK;
+ dest->SetOper(newOper);
+ dest->AsBlk()->gtBlkOpGcUnsafe = true; // Mark as a GC unsafe copy block
+ }
+#endif // defined(CPBLK_UNROLL_LIMIT) && !defined(JIT32_GCENCODER)
+}
+
+//------------------------------------------------------------------------
// fgMorphCopyBlock: Perform the Morphing of block copy
//
// Arguments:
@@ -9444,6 +9687,14 @@ GenTreePtr Compiler::fgMorphCopyBlock(GenTreePtr tree)
bool requiresCopyBlock = false;
bool srcSingleLclVarAsg = false;
+ if ((destLclVar != nullptr) && (srcLclVar == destLclVar))
+ {
+ // Beyond perf reasons, it is not prudent to have a copy of a struct to itself.
+ GenTree* nop = gtNewNothingNode();
+ INDEBUG(nop->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED);
+ return nop;
+ }
+
// If either src or dest is a reg-sized non-field-addressed struct, keep the copyBlock.
if ((destLclVar != nullptr && destLclVar->lvRegStruct) || (srcLclVar != nullptr && srcLclVar->lvRegStruct))
{
@@ -9485,12 +9736,19 @@ GenTreePtr Compiler::fgMorphCopyBlock(GenTreePtr tree)
// Are both dest and src promoted structs?
if (destDoFldAsg && srcDoFldAsg)
{
- // Both structs should be of the same type, if not we will use a copy block
+ // Both structs should be of the same type, or each have a single field of the same type.
+ // If not we will use a copy block.
if (lvaTable[destLclNum].lvVerTypeInfo.GetClassHandle() !=
lvaTable[srcLclNum].lvVerTypeInfo.GetClassHandle())
{
- requiresCopyBlock = true; // Mismatched types, leave as a CopyBlock
- JITDUMP(" with mismatched types");
+ unsigned destFieldNum = lvaTable[destLclNum].lvFieldLclStart;
+ unsigned srcFieldNum = lvaTable[srcLclNum].lvFieldLclStart;
+ if ((lvaTable[destLclNum].lvFieldCnt != 1) || (lvaTable[srcLclNum].lvFieldCnt != 1) ||
+ (lvaTable[destFieldNum].lvType != lvaTable[srcFieldNum].lvType))
+ {
+ requiresCopyBlock = true; // Mismatched types, leave as a CopyBlock
+ JITDUMP(" with mismatched types");
+ }
}
}
// Are neither dest or src promoted structs?
@@ -9584,34 +9842,24 @@ GenTreePtr Compiler::fgMorphCopyBlock(GenTreePtr tree)
var_types asgType = dest->TypeGet();
dest = fgMorphBlockOperand(dest, asgType, blockWidth, true /*isDest*/);
asg->gtOp.gtOp1 = dest;
- hasGCPtrs = ((dest->OperGet() == GT_OBJ) && (dest->AsObj()->gtGcPtrCount != 0));
+ asg->gtFlags |= (dest->gtFlags & GTF_ALL_EFFECT);
-#ifdef CPBLK_UNROLL_LIMIT
// Note that the unrolling of CopyBlk is only implemented on some platforms.
- // Currently that includes x64 and Arm64 but not x64 or Arm32.
+ // Currently that includes x64 and ARM but not x86: the code generation for this
+ // construct requires the ability to mark certain regions of the generated code
+ // as non-interruptible, and the GC encoding for the latter platform does not
+ // have this capability.
// If we have a CopyObj with a dest on the stack
// we will convert it into an GC Unsafe CopyBlk that is non-interruptible
- // when its size is small enouch to be completely unrolled (i.e. between [16..64] bytes)
+ // when its size is small enouch to be completely unrolled (i.e. between [16..64] bytes).
+ // (This is not supported for the JIT32_GCENCODER, for which fgMorphUnsafeBlk is a no-op.)
//
- if (hasGCPtrs && destOnStack && blockWidthIsConst && (blockWidth >= (2 * TARGET_POINTER_SIZE)) &&
- (blockWidth <= CPBLK_UNROLL_LIMIT))
+ if (destOnStack && (dest->OperGet() == GT_OBJ))
{
- if (dest->OperGet() == GT_OBJ)
- {
- dest->SetOper(GT_BLK);
- dest->AsBlk()->gtBlkOpGcUnsafe = true; // Mark as a GC unsafe copy block
- }
- else
- {
- assert(dest->OperIsLocal());
- GenTree* destAddr = gtNewOperNode(GT_ADDR, TYP_BYREF, dest);
- dest = new (this, GT_BLK) GenTreeBlk(GT_BLK, dest->TypeGet(), destAddr, blockWidth);
- dest->AsBlk()->gtBlkOpGcUnsafe = true; // Mark as a GC unsafe copy block
- tree->gtOp.gtOp1 = dest;
- }
+ fgMorphUnsafeBlk(dest->AsObj());
}
-#endif
+
// Eliminate the "OBJ or BLK" node on the rhs.
rhs = fgMorphBlockOperand(rhs, asgType, blockWidth, false /*!isDest*/);
asg->gtOp.gtOp2 = rhs;
@@ -9659,8 +9907,6 @@ GenTreePtr Compiler::fgMorphCopyBlock(GenTreePtr tree)
// To do fieldwise assignments for both sides, they'd better be the same struct type!
// All of these conditions were checked above...
assert(destLclNum != BAD_VAR_NUM && srcLclNum != BAD_VAR_NUM);
- assert(lvaTable[destLclNum].lvVerTypeInfo.GetClassHandle() ==
- lvaTable[srcLclNum].lvVerTypeInfo.GetClassHandle());
assert(destLclVar != nullptr && srcLclVar != nullptr && destLclVar->lvFieldCnt == srcLclVar->lvFieldCnt);
fieldCnt = destLclVar->lvFieldCnt;
@@ -10354,23 +10600,12 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
/* fgDoNormalizeOnStore can change op2 */
noway_assert(op1 == tree->gtOp.gtOp1);
op2 = tree->gtOp.gtOp2;
- // TODO-1stClassStructs: this is here to match previous behavior, but results in some
- // unnecessary pessimization in the handling of addresses in fgMorphCopyBlock().
- if (tree->OperIsBlkOp())
- {
- op1->gtFlags |= GTF_DONT_CSE;
- if (tree->OperIsCopyBlkOp() &&
- (op2->IsLocal() || (op2->OperIsIndir() && (op2->AsIndir()->Addr()->OperGet() == GT_ADDR))))
- {
- op2->gtFlags |= GTF_DONT_CSE;
- }
- }
#ifdef FEATURE_SIMD
{
// We should check whether op2 should be assigned to a SIMD field or not.
// If it is, we should tranlate the tree to simd intrinsic.
- assert((tree->gtDebugFlags & GTF_DEBUG_NODE_MORPHED) == 0);
+ assert(!fgGlobalMorph || ((tree->gtDebugFlags & GTF_DEBUG_NODE_MORPHED) == 0));
GenTreePtr newTree = fgMorphFieldAssignToSIMDIntrinsicSet(tree);
typ = tree->TypeGet();
op1 = tree->gtGetOp1();
@@ -10451,8 +10686,8 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
case GT_COLON:
#if LOCAL_ASSERTION_PROP
if (optLocalAssertionProp)
- {
#endif
+ {
isQmarkColon = true;
}
break;
@@ -10608,13 +10843,6 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
{
op2 = gtFoldExprConst(op2);
}
-
- if (fgShouldUseMagicNumberDivide(tree->AsOp()))
- {
- tree = fgMorphDivByConst(tree->AsOp());
- op1 = tree->gtOp.gtOp1;
- op2 = tree->gtOp.gtOp2;
- }
#endif // !LEGACY_BACKEND
break;
@@ -10673,44 +10901,44 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
// Note for _TARGET_ARMARCH_ we don't have a remainder instruction, so we don't do this optimization
//
#else // _TARGET_XARCH
- /* If this is an unsigned long mod with op2 which is a cast to long from a
- constant int, then don't morph to a call to the helper. This can be done
- faster inline using idiv.
- */
+ /* If this is an unsigned long mod with op2 which is a cast to long from a
+ constant int, then don't morph to a call to the helper. This can be done
+ faster inline using idiv.
+ */
- noway_assert(op2);
- if ((typ == TYP_LONG) && opts.OptEnabled(CLFLG_CONSTANTFOLD) &&
- ((tree->gtFlags & GTF_UNSIGNED) == (op1->gtFlags & GTF_UNSIGNED)) &&
- ((tree->gtFlags & GTF_UNSIGNED) == (op2->gtFlags & GTF_UNSIGNED)))
- {
- if (op2->gtOper == GT_CAST && op2->gtCast.CastOp()->gtOper == GT_CNS_INT &&
- op2->gtCast.CastOp()->gtIntCon.gtIconVal >= 2 &&
- op2->gtCast.CastOp()->gtIntCon.gtIconVal <= 0x3fffffff &&
- (tree->gtFlags & GTF_UNSIGNED) == (op2->gtCast.CastOp()->gtFlags & GTF_UNSIGNED))
- {
- tree->gtOp.gtOp2 = op2 = fgMorphCast(op2);
- noway_assert(op2->gtOper == GT_CNS_NATIVELONG);
- }
+ noway_assert(op2);
+ if ((typ == TYP_LONG) && opts.OptEnabled(CLFLG_CONSTANTFOLD) &&
+ ((tree->gtFlags & GTF_UNSIGNED) == (op1->gtFlags & GTF_UNSIGNED)) &&
+ ((tree->gtFlags & GTF_UNSIGNED) == (op2->gtFlags & GTF_UNSIGNED)))
+ {
+ if (op2->gtOper == GT_CAST && op2->gtCast.CastOp()->gtOper == GT_CNS_INT &&
+ op2->gtCast.CastOp()->gtIntCon.gtIconVal >= 2 &&
+ op2->gtCast.CastOp()->gtIntCon.gtIconVal <= 0x3fffffff &&
+ (tree->gtFlags & GTF_UNSIGNED) == (op2->gtCast.CastOp()->gtFlags & GTF_UNSIGNED))
+ {
+ tree->gtOp.gtOp2 = op2 = fgMorphCast(op2);
+ noway_assert(op2->gtOper == GT_CNS_NATIVELONG);
+ }
- if (op2->gtOper == GT_CNS_NATIVELONG && op2->gtIntConCommon.LngValue() >= 2 &&
- op2->gtIntConCommon.LngValue() <= 0x3fffffff)
- {
- tree->gtOp.gtOp1 = op1 = fgMorphTree(op1);
- noway_assert(op1->TypeGet() == TYP_LONG);
+ if (op2->gtOper == GT_CNS_NATIVELONG && op2->gtIntConCommon.LngValue() >= 2 &&
+ op2->gtIntConCommon.LngValue() <= 0x3fffffff)
+ {
+ tree->gtOp.gtOp1 = op1 = fgMorphTree(op1);
+ noway_assert(op1->TypeGet() == TYP_LONG);
- // Update flags for op1 morph
- tree->gtFlags &= ~GTF_ALL_EFFECT;
+ // Update flags for op1 morph
+ tree->gtFlags &= ~GTF_ALL_EFFECT;
- tree->gtFlags |= (op1->gtFlags & GTF_ALL_EFFECT); // Only update with op1 as op2 is a constant
+ tree->gtFlags |= (op1->gtFlags & GTF_ALL_EFFECT); // Only update with op1 as op2 is a constant
- // If op1 is a constant, then do constant folding of the division operator
- if (op1->gtOper == GT_CNS_NATIVELONG)
- {
- tree = gtFoldExpr(tree);
+ // If op1 is a constant, then do constant folding of the division operator
+ if (op1->gtOper == GT_CNS_NATIVELONG)
+ {
+ tree = gtFoldExpr(tree);
+ }
+ return tree;
}
- return tree;
}
- }
#endif // _TARGET_XARCH
ASSIGN_HELPER_FOR_MOD:
@@ -10773,16 +11001,28 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
tree = fgMorphModToSubMulDiv(tree->AsOp());
op1 = tree->gtOp.gtOp1;
op2 = tree->gtOp.gtOp2;
-
-#else // !_TARGET_ARM64_
-
- if (oper != GT_UMOD && fgShouldUseMagicNumberDivide(tree->AsOp()))
- {
- tree = fgMorphModByConst(tree->AsOp());
- op1 = tree->gtOp.gtOp1;
- op2 = tree->gtOp.gtOp2;
+#else //_TARGET_ARM64_
+ // If b is not a power of 2 constant then lowering replaces a % b
+ // with a - (a / b) * b and applies magic division optimization to
+ // a / b. The code may already contain an a / b expression (e.g.
+ // x = a / 10; y = a % 10;) and then we end up with redundant code.
+ // If we convert % to / here we give CSE the opportunity to eliminate
+ // the redundant division. If there's no redundant division then
+ // nothing is lost, lowering would have done this transform anyway.
+
+ if ((tree->OperGet() == GT_MOD) && op2->IsIntegralConst())
+ {
+ ssize_t divisorValue = op2->AsIntCon()->IconValue();
+ size_t absDivisorValue = (divisorValue == SSIZE_T_MIN) ? static_cast<size_t>(divisorValue)
+ : static_cast<size_t>(abs(divisorValue));
+
+ if (!isPow2(absDivisorValue))
+ {
+ tree = fgMorphModToSubMulDiv(tree->AsOp());
+ op1 = tree->gtOp.gtOp1;
+ op2 = tree->gtOp.gtOp2;
+ }
}
-
#endif //_TARGET_ARM64_
#endif // !LEGACY_BACKEND
break;
@@ -10857,12 +11097,12 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
((op2->gtCall.gtCallMoreFlags & GTF_CALL_M_SPECIAL_INTRINSIC) ||
(op2->gtCall.gtCallType == CT_HELPER)))
#else
- if ((((op1->gtOper == GT_INTRINSIC) &&
- (op1->gtIntrinsic.gtIntrinsicId == CORINFO_INTRINSIC_Object_GetType)) ||
- ((op1->gtOper == GT_CALL) && (op1->gtCall.gtCallType == CT_HELPER))) &&
- (((op2->gtOper == GT_INTRINSIC) &&
- (op2->gtIntrinsic.gtIntrinsicId == CORINFO_INTRINSIC_Object_GetType)) ||
- ((op2->gtOper == GT_CALL) && (op2->gtCall.gtCallType == CT_HELPER))))
+ if ((((op1->gtOper == GT_INTRINSIC) &&
+ (op1->gtIntrinsic.gtIntrinsicId == CORINFO_INTRINSIC_Object_GetType)) ||
+ ((op1->gtOper == GT_CALL) && (op1->gtCall.gtCallType == CT_HELPER))) &&
+ (((op2->gtOper == GT_INTRINSIC) &&
+ (op2->gtIntrinsic.gtIntrinsicId == CORINFO_INTRINSIC_Object_GetType)) ||
+ ((op2->gtOper == GT_CALL) && (op2->gtCall.gtCallType == CT_HELPER))))
#endif
{
GenTreePtr pGetClassFromHandle;
@@ -10872,8 +11112,8 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
bool bOp1ClassFromHandle = gtIsTypeHandleToRuntimeTypeHelper(op1);
bool bOp2ClassFromHandle = gtIsTypeHandleToRuntimeTypeHelper(op2);
#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) : false;
+ bool bOp2ClassFromHandle = op2->gtOper == GT_CALL ? gtIsTypeHandleToRuntimeTypeHelper(op2) : false;
#endif
// Optimize typeof(...) == typeof(...)
@@ -10929,8 +11169,8 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
info.compCompHnd->getIntrinsicID(pGetType->gtCall.gtCallMethHnd) ==
CORINFO_INTRINSIC_Object_GetType &&
#else
- if ((pGetType->gtOper == GT_INTRINSIC) &&
- (pGetType->gtIntrinsic.gtIntrinsicId == CORINFO_INTRINSIC_Object_GetType) &&
+ if ((pGetType->gtOper == GT_INTRINSIC) &&
+ (pGetType->gtIntrinsic.gtIntrinsicId == CORINFO_INTRINSIC_Object_GetType) &&
#endif
pConstLiteral->gtOper == GT_CNS_INT && pConstLiteral->gtType == TYP_I_IMPL)
{
@@ -10944,7 +11184,7 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
#ifdef LEGACY_BACKEND
GenTreePtr objMT = gtNewOperNode(GT_IND, TYP_I_IMPL, pGetType->gtCall.gtCallObjp);
#else
- GenTreePtr objMT = gtNewOperNode(GT_IND, TYP_I_IMPL, pGetType->gtUnOp.gtOp1);
+ GenTreePtr objMT = gtNewOperNode(GT_IND, TYP_I_IMPL, pGetType->gtUnOp.gtOp1);
#endif
objMT->gtFlags |= GTF_EXCEPT; // Null ref exception if object is null
compCurBB->bbFlags |= BBF_HAS_VTABREF;
@@ -11041,7 +11281,7 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
// Assume it's an Ind context to start.
MorphAddrContext subIndMac1(MACK_Ind);
MorphAddrContext* subMac1 = mac;
- if (subMac1 == nullptr || subMac1->m_kind == MACK_Ind || subMac1->m_kind == MACK_CopyBlock)
+ if (subMac1 == nullptr || subMac1->m_kind == MACK_Ind)
{
switch (tree->gtOper)
{
@@ -11532,7 +11772,7 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
//
// EQ/NE
// / \
- // op1 CNS 0/1
+ // op1 CNS 0/1
//
ival2 = INT_MAX; // The value of INT_MAX for ival2 just means that the constant value is not 0 or 1
@@ -11557,11 +11797,11 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
//
// EQ/NE Possible REVERSE(RELOP)
// / \ / \
- // COMMA CNS 0/1 -> COMMA relop_op2
+ // COMMA CNS 0/1 -> COMMA relop_op2
// / \ / \
- // x RELOP x relop_op1
+ // x RELOP x relop_op1
// / \
- // relop_op1 relop_op2
+ // relop_op1 relop_op2
//
//
//
@@ -11600,13 +11840,13 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
//
// EQ/NE EQ/NE
// / \ / \
- // COMMA CNS 0/1 -> RELOP CNS 0/1
+ // COMMA CNS 0/1 -> RELOP CNS 0/1
// / \ / \
- // ASG LCL_VAR
+ // ASG LCL_VAR
// / \
- // LCL_VAR RELOP
+ // LCL_VAR RELOP
// / \
- //
+ //
GenTreePtr asg = op1->gtOp.gtOp1;
GenTreePtr lcl = op1->gtOp.gtOp2;
@@ -11689,9 +11929,9 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
//
// EQ/NE -> RELOP/!RELOP
// / \ / \
- // RELOP CNS 0/1
+ // RELOP CNS 0/1
// / \
- //
+ //
// Note that we will remove/destroy the EQ/NE node and move
// the RELOP up into it's location.
@@ -11721,11 +11961,11 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
//
// EQ/NE EQ/NE
// / \ / \
- // AND CNS 0/1 -> AND CNS 0
+ // AND CNS 0/1 -> AND CNS 0
// / \ / \
- // RSZ/RSH CNS 1 x CNS (1 << y)
+ // RSZ/RSH CNS 1 x CNS (1 << y)
// / \
- // x CNS_INT +y
+ // x CNS_INT +y
if (op1->gtOper == GT_AND)
{
@@ -12121,38 +12361,42 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
goto CM_OVF_OP;
}
- /* Check for "op1 - cns2" , we change it to "op1 + (-cns2)" */
-
- noway_assert(op2);
- if (op2->IsCnsIntOrI())
+ // TODO #4104: there are a lot of other places where
+ // this condition is not checked before transformations.
+ if (fgGlobalMorph)
{
- /* Negate the constant and change the node to be "+" */
+ /* Check for "op1 - cns2" , we change it to "op1 + (-cns2)" */
- op2->gtIntConCommon.SetIconValue(-op2->gtIntConCommon.IconValue());
- oper = GT_ADD;
- tree->ChangeOper(oper);
- goto CM_ADD_OP;
- }
+ noway_assert(op2);
+ if (op2->IsCnsIntOrI())
+ {
+ /* Negate the constant and change the node to be "+" */
- /* Check for "cns1 - op2" , we change it to "(cns1 + (-op2))" */
+ op2->gtIntConCommon.SetIconValue(-op2->gtIntConCommon.IconValue());
+ oper = GT_ADD;
+ tree->ChangeOper(oper);
+ goto CM_ADD_OP;
+ }
- noway_assert(op1);
- if (op1->IsCnsIntOrI())
- {
- noway_assert(varTypeIsIntOrI(tree));
+ /* Check for "cns1 - op2" , we change it to "(cns1 + (-op2))" */
- tree->gtOp.gtOp2 = op2 =
- gtNewOperNode(GT_NEG, tree->gtType, op2); // The type of the new GT_NEG node should be the same
- // as the type of the tree, i.e. tree->gtType.
- fgMorphTreeDone(op2);
+ noway_assert(op1);
+ if (op1->IsCnsIntOrI())
+ {
+ noway_assert(varTypeIsIntOrI(tree));
- oper = GT_ADD;
- tree->ChangeOper(oper);
- goto CM_ADD_OP;
- }
+ tree->gtOp.gtOp2 = op2 = gtNewOperNode(GT_NEG, tree->gtType, op2); // The type of the new GT_NEG
+ // node should be the same
+ // as the type of the tree, i.e. tree->gtType.
+ fgMorphTreeDone(op2);
- /* No match - exit */
+ oper = GT_ADD;
+ tree->ChangeOper(oper);
+ goto CM_ADD_OP;
+ }
+ /* No match - exit */
+ }
break;
#ifdef _TARGET_ARM64_
@@ -12281,7 +12525,8 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
// Dereferencing the pointer in either case will have the
// same effect.
- if (!gtIsActiveCSE_Candidate(op1) && varTypeIsGC(op2->TypeGet()))
+ if (!optValnumCSE_phase && varTypeIsGC(op2->TypeGet()) &&
+ ((op1->gtFlags & GTF_ALL_EFFECT) == 0))
{
op2->gtType = tree->gtType;
DEBUG_DESTROY_NODE(op1);
@@ -12520,7 +12765,7 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
// Also make sure that the tree type matches the fieldVarType and that it's lvFldOffset
// is zero
- if (fieldVarDsc->TypeGet() == tree->TypeGet() && (fieldVarDsc->lvFldOffset == 0))
+ if (fieldVarDsc->TypeGet() == typ && (fieldVarDsc->lvFldOffset == 0))
{
// We can just use the existing promoted field LclNum
temp->gtLclVarCommon.SetLclNum(lclNumFld);
@@ -12538,8 +12783,8 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
else if (varTypeIsSmall(typ) && (genTypeSize(lvaTable[lclNum].lvType) == genTypeSize(typ)) &&
!lvaTable[lclNum].lvNormalizeOnLoad())
{
- tree->gtType = temp->gtType;
- foldAndReturnTemp = true;
+ tree->gtType = typ = temp->TypeGet();
+ foldAndReturnTemp = true;
}
else
{
@@ -12554,7 +12799,7 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
// Append the field sequence, change the type.
temp->AsLclFld()->gtFieldSeq =
GetFieldSeqStore()->Append(temp->AsLclFld()->gtFieldSeq, fieldSeq);
- temp->gtType = tree->TypeGet();
+ temp->gtType = typ;
foldAndReturnTemp = true;
}
@@ -12623,9 +12868,9 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
#ifdef _TARGET_ARM_
// Check for a LclVar TYP_STRUCT with misalignment on a Floating Point field
//
- if (varTypeIsFloating(tree->TypeGet()))
+ if (varTypeIsFloating(typ))
{
- if ((ival1 % emitTypeSize(tree->TypeGet())) != 0)
+ if ((ival1 % emitTypeSize(typ)) != 0)
{
tree->gtFlags |= GTF_IND_UNALIGNED;
break;
@@ -12638,24 +12883,35 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
}
}
-#ifdef DEBUG
- // If we have decided to fold, then temp cannot be nullptr
- if (foldAndReturnTemp)
- {
- assert(temp != nullptr);
- }
-#endif
-
- if (temp != nullptr)
- {
- noway_assert(op1->gtOper == GT_ADD || op1->gtOper == GT_ADDR);
-
- // If we haven't already decided to fold this expression
- //
- if (!foldAndReturnTemp)
+ // At this point we may have a lclVar or lclFld that might be foldable with a bit of extra massaging:
+ // - We may have a load of a local where the load has a different type than the local
+ // - We may have a load of a local plus an offset
+ //
+ // In these cases, we will change the lclVar or lclFld into a lclFld of the appropriate type and
+ // offset if doing so is legal. The only cases in which this transformation is illegal are if the load
+ // begins before the local or if the load extends beyond the end of the local (i.e. if the load is
+ // out-of-bounds w.r.t. the local).
+ if ((temp != nullptr) && !foldAndReturnTemp)
+ {
+ assert(temp->OperIsLocal());
+
+ const unsigned lclNum = temp->AsLclVarCommon()->gtLclNum;
+ LclVarDsc* const varDsc = &lvaTable[lclNum];
+
+ const var_types tempTyp = temp->TypeGet();
+ const bool useExactSize =
+ varTypeIsStruct(tempTyp) || (tempTyp == TYP_BLK) || (tempTyp == TYP_LCLBLK);
+ const unsigned varSize = useExactSize ? varDsc->lvExactSize : genTypeSize(temp);
+
+ // If the size of the load is greater than the size of the lclVar, we cannot fold this access into
+ // a lclFld: the access represented by an lclFld node must begin at or after the start of the
+ // lclVar and must not extend beyond the end of the lclVar.
+ if ((ival1 < 0) || ((ival1 + genTypeSize(typ)) > varSize))
+ {
+ lvaSetVarDoNotEnregister(lclNum DEBUGARG(DNER_LocalField));
+ }
+ else
{
- noway_assert(temp->OperIsLocal());
- LclVarDsc* varDsc = &(lvaTable[temp->AsLclVarCommon()->gtLclNum]);
// Make sure we don't separately promote the fields of this struct.
if (varDsc->lvRegStruct)
{
@@ -12664,7 +12920,7 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
}
else
{
- lvaSetVarDoNotEnregister(temp->gtLclVarCommon.gtLclNum DEBUGARG(DNER_LocalField));
+ lvaSetVarDoNotEnregister(lclNum DEBUGARG(DNER_LocalField));
}
// We will turn a GT_LCL_VAR into a GT_LCL_FLD with an gtLclOffs of 'ival'
@@ -12689,19 +12945,19 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
temp->gtType = tree->gtType;
foldAndReturnTemp = true;
}
+ }
- assert(foldAndReturnTemp == true);
+ if (foldAndReturnTemp)
+ {
+ assert(temp != nullptr);
+ assert(temp->TypeGet() == typ);
+ assert((op1->OperGet() == GT_ADD) || (op1->OperGet() == GT_ADDR));
- // Keep the DONT_CSE flag in sync
- // (i.e keep the original value of this flag from tree)
- // as it can be set for 'temp' because a GT_ADDR always marks it for it's op1
- //
+ // Copy the value of GTF_DONT_CSE from the original tree to `temp`: it can be set for
+ // 'temp' because a GT_ADDR always marks it for its operand.
temp->gtFlags &= ~GTF_DONT_CSE;
temp->gtFlags |= (tree->gtFlags & GTF_DONT_CSE);
- noway_assert(op1->gtOper == GT_ADD || op1->gtOper == GT_ADDR);
- noway_assert(temp->gtType == tree->gtType);
-
if (op1->OperGet() == GT_ADD)
{
DEBUG_DESTROY_NODE(op1->gtOp.gtOp1); // GT_ADDR
@@ -12984,7 +13240,7 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
// If we are in the Valuenum CSE phase then don't morph away anything as these
// nodes may have CSE defs/uses in them.
//
- if (!optValnumCSE_phase && (oper != GT_ASG) && (oper != GT_COLON) && !tree->IsList())
+ if (!optValnumCSE_phase && (oper != GT_ASG) && (oper != GT_COLON) && !tree->OperIsAnyList())
{
/* Check for op1 as a GT_COMMA with a unconditional throw node */
if (op1 && fgIsCommaThrow(op1, true))
@@ -13530,6 +13786,7 @@ GenTree* Compiler::fgMorphSmpOpOptional(GenTreeOp* tree)
/* The target is used as well as being defined */
if (op1->OperIsLocal())
{
+ op1->gtFlags &= ~GTF_VAR_USEDEF;
op1->gtFlags |= GTF_VAR_USEASG;
}
@@ -13666,7 +13923,7 @@ GenTree* Compiler::fgMorphSmpOpOptional(GenTreeOp* tree)
/* Check for the case "(val + icon) << icon" */
- if (op2->IsCnsIntOrI() && op1->gtOper == GT_ADD && !op1->gtOverflow())
+ if (!optValnumCSE_phase && op2->IsCnsIntOrI() && op1->gtOper == GT_ADD && !op1->gtOverflow())
{
GenTreePtr cns = op1->gtOp.gtOp2;
@@ -13731,192 +13988,45 @@ GenTree* Compiler::fgMorphSmpOpOptional(GenTreeOp* tree)
break;
+ case GT_INIT_VAL:
+ // Initialization values for initBlk have special semantics - their lower
+ // byte is used to fill the struct. However, we allow 0 as a "bare" value,
+ // which enables them to get a VNForZero, and be propagated.
+ if (op1->IsIntegralConst(0))
+ {
+ return op1;
+ }
+ break;
+
default:
break;
}
return tree;
}
-// code to generate a magic number and shift amount for the magic number division
-// optimization. This code is previously from UTC where it notes it was taken from
-// _The_PowerPC_Compiler_Writer's_Guide_, pages 57-58.
-// The paper it is based on is "Division by invariant integers using multiplication"
-// by Torbjorn Granlund and Peter L. Montgomery in PLDI 94
-
-template <typename T>
-T GetSignedMagicNumberForDivide(T denom, int* shift /*out*/)
-{
- // static SMAG smag;
- const int bits = sizeof(T) * 8;
- const int bits_minus_1 = bits - 1;
-
- typedef typename jitstd::make_unsigned<T>::type UT;
-
- const UT two_nminus1 = UT(1) << bits_minus_1;
-
- int p;
- UT absDenom;
- UT absNc;
- UT delta;
- UT q1;
- UT r1;
- UT r2;
- UT q2;
- UT t;
- T result_magic;
- int result_shift;
- int iters = 0;
-
- absDenom = abs(denom);
- t = two_nminus1 + ((unsigned int)denom >> 31);
- absNc = t - 1 - (t % absDenom); // absolute value of nc
- p = bits_minus_1; // initialize p
- q1 = two_nminus1 / absNc; // initialize q1 = 2^p / abs(nc)
- r1 = two_nminus1 - (q1 * absNc); // initialize r1 = rem(2^p, abs(nc))
- q2 = two_nminus1 / absDenom; // initialize q1 = 2^p / abs(denom)
- r2 = two_nminus1 - (q2 * absDenom); // initialize r1 = rem(2^p, abs(denom))
-
- do
- {
- iters++;
- p++;
- q1 *= 2; // update q1 = 2^p / abs(nc)
- r1 *= 2; // update r1 = rem(2^p / abs(nc))
-
- if (r1 >= absNc)
- { // must be unsigned comparison
- q1++;
- r1 -= absNc;
- }
-
- q2 *= 2; // update q2 = 2^p / abs(denom)
- r2 *= 2; // update r2 = rem(2^p / abs(denom))
-
- if (r2 >= absDenom)
- { // must be unsigned comparison
- q2++;
- r2 -= absDenom;
- }
-
- delta = absDenom - r2;
- } while (q1 < delta || (q1 == delta && r1 == 0));
-
- result_magic = q2 + 1; // resulting magic number
- if (denom < 0)
- {
- result_magic = -result_magic;
- }
- *shift = p - bits; // resulting shift
-
- return result_magic;
-}
-
-bool Compiler::fgShouldUseMagicNumberDivide(GenTreeOp* tree)
-{
-#ifdef _TARGET_ARM64_
- // TODO-ARM64-NYI: We don't have a 'mulHi' implementation yet for ARM64
- return false;
-#else
-
- // During the optOptimizeValnumCSEs phase we can call fgMorph and when we do,
- // if this method returns true we will introduce a new LclVar and
- // a couple of new GenTree nodes, including an assignment to the new LclVar.
- // None of these new GenTree nodes will have valid ValueNumbers.
- // That is an invalid state for a GenTree node during the optOptimizeValnumCSEs phase.
- //
- // Also during optAssertionProp when extracting side effects we can assert
- // during gtBuildCommaList if we have one tree that has Value Numbers
- // and another one that does not.
- //
- if (!fgGlobalMorph)
- {
- // We only perform the Magic Number Divide optimization during
- // the initial global morph phase
- return false;
- }
-
- if (tree->gtFlags & GTF_OVERFLOW)
- {
- return false;
- }
-
- if (tree->gtOp2->gtOper != GT_CNS_INT && tree->gtOp2->gtOper != GT_CNS_LNG)
- {
- return false;
- }
-
- ssize_t cons = tree->gtOp2->gtIntConCommon.IconValue();
-
- if (cons == 0 || cons == -1 || cons == 1)
- {
- return false;
- }
-
- // codegen will expand these
- if (cons == SSIZE_T_MIN || isPow2(abs(cons)))
- {
- return false;
- }
-
- // someone else will fold this away, so don't make it complicated for them
- if (tree->gtOp1->IsCnsIntOrI())
- {
- return false;
- }
-
- // There is no technical barrier to handling unsigned, however it is quite rare
- // and more work to support and test
- if (tree->gtFlags & GTF_UNSIGNED)
- {
- return false;
- }
-
- return true;
-#endif
-}
-
-// transform x%c -> x-((x/c)*c)
-
-GenTree* Compiler::fgMorphModByConst(GenTreeOp* tree)
-{
- assert(fgShouldUseMagicNumberDivide(tree));
-
- var_types type = tree->gtType;
-
- GenTree* cns = tree->gtOp2;
-
- GenTree* numerator = fgMakeMultiUse(&tree->gtOp1);
-
- tree->SetOper(GT_DIV);
-
- GenTree* mul = gtNewOperNode(GT_MUL, type, tree, gtCloneExpr(cns));
-
- GenTree* sub = gtNewOperNode(GT_SUB, type, numerator, mul);
-
-#ifdef DEBUG
- sub->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED;
-#endif
-
- return sub;
-}
-
-// For ARM64 we don't have a remainder instruction,
-// The architecture manual suggests the following transformation to
-// generate code for such operator:
+//------------------------------------------------------------------------
+// fgMorphModToSubMulDiv: Transform a % b into the equivalent a - (a / b) * b
+// (see ECMA III 3.55 and III.3.56).
//
-// a % b = a - (a / b) * b;
+// Arguments:
+// tree - The GT_MOD/GT_UMOD tree to morph
//
-// This method will produce the above expression in 'a' and 'b' are
-// leaf nodes, otherwise, if any of them is not a leaf it will spill
-// its value into a temporary variable, an example:
-// (x * 2 - 1) % (y + 1) -> t1 - (t2 * ( comma(t1 = x * 2 - 1, t1) / comma(t2 = y + 1, t2) ) )
+// Returns:
+// The morphed tree
+//
+// Notes:
+// For ARM64 we don't have a remainder instruction so this transform is
+// always done. For XARCH this transform is done if we know that magic
+// division will be used, in that case this transform allows CSE to
+// eliminate the redundant div from code like "x = a / 3; y = a % 3;".
+//
+// This method will produce the above expression in 'a' and 'b' are
+// leaf nodes, otherwise, if any of them is not a leaf it will spill
+// its value into a temporary variable, an example:
+// (x * 2 - 1) % (y + 1) -> t1 - (t2 * ( comma(t1 = x * 2 - 1, t1) / comma(t2 = y + 1, t2) ) )
//
GenTree* Compiler::fgMorphModToSubMulDiv(GenTreeOp* tree)
{
-#ifndef _TARGET_ARM64_
- assert(!"This should only be called for ARM64");
-#endif
-
if (tree->OperGet() == GT_MOD)
{
tree->SetOper(GT_DIV);
@@ -13944,8 +14054,16 @@ GenTree* Compiler::fgMorphModToSubMulDiv(GenTreeOp* tree)
denominator = fgMakeMultiUse(&tree->gtOp2);
}
+ // The numerator and denominator may have been assigned to temps, in which case
+ // their defining assignments are in the current tree. Therefore, we need to
+ // set the execuction order accordingly on the nodes we create.
+ // That is, the "mul" will be evaluated in "normal" order, and the "sub" must
+ // be set to be evaluated in reverse order.
+ //
GenTree* mul = gtNewOperNode(GT_MUL, type, tree, gtCloneExpr(denominator));
+ assert(!mul->IsReverseOp());
GenTree* sub = gtNewOperNode(GT_SUB, type, gtCloneExpr(numerator), mul);
+ sub->gtFlags |= GTF_REVERSE_OPS;
#ifdef DEBUG
sub->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED;
@@ -13954,95 +14072,6 @@ GenTree* Compiler::fgMorphModToSubMulDiv(GenTreeOp* tree)
return sub;
}
-// Turn a division by a constant into a multiplication by constant + some adjustments
-// see comments on GetSignedMagicNumberForDivide for source of this algorithm.
-// returns: the transformed tree
-
-GenTree* Compiler::fgMorphDivByConst(GenTreeOp* tree)
-{
- assert(fgShouldUseMagicNumberDivide(tree));
-
- JITDUMP("doing magic number divide optimization\n");
-
- int64_t denominator = tree->gtOp2->gtIntConCommon.IconValue();
- int64_t magic;
- int shift;
- var_types type = tree->gtType;
-
- if (tree->gtType == TYP_INT)
- {
- magic = GetSignedMagicNumberForDivide<int32_t>((int32_t)denominator, &shift);
- }
- else
- {
- magic = GetSignedMagicNumberForDivide<int64_t>((int64_t)denominator, &shift);
- }
-
- GenTree* numerator = nullptr;
-
- // If signs of the denominator and magic number don't match,
- // we will need to use the numerator again.
- if (signum(denominator) != signum(magic))
- {
- numerator = fgMakeMultiUse(&tree->gtOp1);
- tree->gtFlags |= GTF_ASG;
- }
-
- if (type == TYP_LONG)
- {
- tree->gtOp2->gtIntConCommon.SetLngValue(magic);
- }
- else
- {
- tree->gtOp2->gtIntConCommon.SetIconValue((ssize_t)magic);
- }
-
- tree->SetOper(GT_MULHI);
-
- GenTree* t = tree;
- GenTree* mulresult = tree;
-
- JITDUMP("Multiply Result:\n");
- DISPTREE(mulresult);
-
- GenTree* adjusted = mulresult;
-
- if (denominator > 0 && magic < 0)
- {
- // add the numerator back in
- adjusted = gtNewOperNode(GT_ADD, type, mulresult, numerator);
- }
- else if (denominator < 0 && magic > 0)
- {
- // subtract the numerator off
- adjusted = gtNewOperNode(GT_SUB, type, mulresult, numerator);
- }
- else
- {
- adjusted = mulresult;
- }
-
- GenTree* result1 = adjusted;
- if (shift != 0)
- {
- result1 = gtNewOperNode(GT_RSH, type, adjusted, gtNewIconNode(shift, TYP_INT));
- }
-
- GenTree* secondClone = fgMakeMultiUse(&result1);
-
- GenTree* result2 = gtNewOperNode(GT_RSZ, type, secondClone, gtNewIconNode(genTypeSize(type) * 8 - 1, type));
-
- GenTree* result = gtNewOperNode(GT_ADD, type, result1, result2);
- JITDUMP("Final Magic Number divide:\n");
- DISPTREE(result);
-
-#ifdef DEBUG
- result->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED;
-#endif
-
- return result;
-}
-
//------------------------------------------------------------------------------
// fgOperIsBitwiseRotationRoot : Check if the operation can be a root of a bitwise rotation tree.
//
@@ -14238,10 +14267,10 @@ GenTreePtr Compiler::fgRecognizeAndMorphBitwiseRotation(GenTreePtr tree)
#ifndef _TARGET_64BIT_
if (!shiftIndexWithoutAdd->IsCnsIntOrI() && (rotatedValueBitSize == 64))
{
- // TODO: we need to handle variable-sized long shifts specially on x86.
+ // TODO-X86-CQ: we need to handle variable-sized long shifts specially on x86.
// GT_LSH, GT_RSH, and GT_RSZ have helpers for this case. We may need
// to add helpers for GT_ROL and GT_ROR.
- NYI("Rotation of a long value by variable amount");
+ return tree;
}
#endif
@@ -14276,7 +14305,15 @@ GenTreePtr Compiler::fgRecognizeAndMorphBitwiseRotation(GenTreePtr tree)
tree->gtOp.gtOp1 = rotatedValue;
tree->gtOp.gtOp2 = rotateIndex;
tree->ChangeOper(rotateOp);
- noway_assert(inputTreeEffects == ((rotatedValue->gtFlags | rotateIndex->gtFlags) & GTF_ALL_EFFECT));
+
+ unsigned childFlags = 0;
+ for (GenTree* op : tree->Operands())
+ {
+ childFlags |= (op->gtFlags & GTF_ALL_EFFECT);
+ }
+
+ // The parent's flags should be a superset of its operands' flags
+ noway_assert((inputTreeEffects & childFlags) == childFlags);
}
else
{
@@ -14719,29 +14756,15 @@ DONE:
}
#if LOCAL_ASSERTION_PROP
-/*****************************************************************************
- *
- * Kill all dependent assertions with regard to lclNum.
- *
- */
-
-void Compiler::fgKillDependentAssertions(unsigned lclNum DEBUGARG(GenTreePtr tree))
+//------------------------------------------------------------------------
+// fgKillDependentAssertionsSingle: Kill all assertions specific to lclNum
+//
+// Arguments:
+// lclNum - The varNum of the lclVar for which we're killing assertions.
+// tree - (DEBUG only) the tree responsible for killing its assertions.
+//
+void Compiler::fgKillDependentAssertionsSingle(unsigned lclNum DEBUGARG(GenTreePtr tree))
{
- LclVarDsc* varDsc = &lvaTable[lclNum];
-
- if (varDsc->lvPromoted)
- {
- noway_assert(varTypeIsStruct(varDsc));
-
- // Kill the field locals.
- for (unsigned i = varDsc->lvFieldLclStart; i < varDsc->lvFieldLclStart + varDsc->lvFieldCnt; ++i)
- {
- fgKillDependentAssertions(i DEBUGARG(tree));
- }
-
- // Fall through to kill the struct local itself.
- }
-
/* All dependent assertions are killed here */
ASSERT_TP killed = BitVecOps::MakeCopy(apTraits, GetAssertionDep(lclNum));
@@ -14778,6 +14801,48 @@ void Compiler::fgKillDependentAssertions(unsigned lclNum DEBUGARG(GenTreePtr tre
noway_assert(BitVecOps::IsEmpty(apTraits, killed));
}
}
+//------------------------------------------------------------------------
+// fgKillDependentAssertions: Kill all dependent assertions with regard to lclNum.
+//
+// Arguments:
+// lclNum - The varNum of the lclVar for which we're killing assertions.
+// tree - (DEBUG only) the tree responsible for killing its assertions.
+//
+// Notes:
+// For structs and struct fields, it will invalidate the children and parent
+// respectively.
+// Calls fgKillDependentAssertionsSingle to kill the assertions for a single lclVar.
+//
+void Compiler::fgKillDependentAssertions(unsigned lclNum DEBUGARG(GenTreePtr tree))
+{
+ LclVarDsc* varDsc = &lvaTable[lclNum];
+
+ if (varDsc->lvPromoted)
+ {
+ noway_assert(varTypeIsStruct(varDsc));
+
+ // Kill the field locals.
+ for (unsigned i = varDsc->lvFieldLclStart; i < varDsc->lvFieldLclStart + varDsc->lvFieldCnt; ++i)
+ {
+ fgKillDependentAssertionsSingle(i DEBUGARG(tree));
+ }
+
+ // Kill the struct local itself.
+ fgKillDependentAssertionsSingle(lclNum DEBUGARG(tree));
+ }
+ else if (varDsc->lvIsStructField)
+ {
+ // Kill the field local.
+ fgKillDependentAssertionsSingle(lclNum DEBUGARG(tree));
+
+ // Kill the parent struct.
+ fgKillDependentAssertionsSingle(varDsc->lvParentLcl DEBUGARG(tree));
+ }
+ else
+ {
+ fgKillDependentAssertionsSingle(lclNum DEBUGARG(tree));
+ }
+}
#endif // LOCAL_ASSERTION_PROP
/*****************************************************************************
@@ -14841,13 +14906,12 @@ void Compiler::fgMorphTreeDone(GenTreePtr tree,
if (optAssertionCount > 0)
{
/* Is this an assignment to a local variable */
-
- if ((tree->OperKind() & GTK_ASGOP) &&
- (tree->gtOp.gtOp1->gtOper == GT_LCL_VAR || tree->gtOp.gtOp1->gtOper == GT_LCL_FLD))
+ GenTreeLclVarCommon* lclVarTree = nullptr;
+ if (tree->DefinesLocal(this, &lclVarTree))
{
- unsigned op1LclNum = tree->gtOp.gtOp1->gtLclVarCommon.gtLclNum;
- noway_assert(op1LclNum < lvaCount);
- fgKillDependentAssertions(op1LclNum DEBUGARG(tree));
+ unsigned lclNum = lclVarTree->gtLclNum;
+ noway_assert(lclNum < lvaCount);
+ fgKillDependentAssertions(lclNum DEBUGARG(tree));
}
}
@@ -15223,14 +15287,15 @@ bool Compiler::fgFoldConditional(BasicBlock* block)
// Returns false if 'stmt' is still in the block (even if other statements were removed).
//
-bool Compiler::fgMorphBlockStmt(BasicBlock* block, GenTreePtr stmt DEBUGARG(const char* msg))
+bool Compiler::fgMorphBlockStmt(BasicBlock* block, GenTreeStmt* stmt DEBUGARG(const char* msg))
{
- noway_assert(stmt->gtOper == GT_STMT);
+ assert(block != nullptr);
+ assert(stmt != nullptr);
compCurBB = block;
compCurStmt = stmt;
- GenTreePtr morph = fgMorphTree(stmt->gtStmt.gtStmtExpr);
+ GenTree* morph = fgMorphTree(stmt->gtStmtExpr);
// Bug 1106830 - During the CSE phase we can't just remove
// morph->gtOp.gtOp2 as it could contain CSE expressions.
@@ -15239,7 +15304,7 @@ bool Compiler::fgMorphBlockStmt(BasicBlock* block, GenTreePtr stmt DEBUGARG(cons
//
if (!optValnumCSE_phase)
{
- /* Check for morph as a GT_COMMA with an unconditional throw */
+ // Check for morph as a GT_COMMA with an unconditional throw
if (fgIsCommaThrow(morph, true))
{
#ifdef DEBUG
@@ -15251,12 +15316,12 @@ bool Compiler::fgMorphBlockStmt(BasicBlock* block, GenTreePtr stmt DEBUGARG(cons
printf("\n");
}
#endif
- /* Use the call as the new stmt */
+ // Use the call as the new stmt
morph = morph->gtOp.gtOp1;
noway_assert(morph->gtOper == GT_CALL);
}
- /* we can get a throw as a statement root*/
+ // we can get a throw as a statement root
if (fgIsThrow(morph))
{
#ifdef DEBUG
@@ -15271,15 +15336,19 @@ bool Compiler::fgMorphBlockStmt(BasicBlock* block, GenTreePtr stmt DEBUGARG(cons
}
}
- stmt->gtStmt.gtStmtExpr = morph;
+ stmt->gtStmtExpr = morph;
- /* Can the entire tree be removed ? */
+ if (lvaLocalVarRefCounted)
+ {
+ // fgMorphTree may have introduced new lclVar references. Bump the ref counts if requested.
+ lvaRecursiveIncRefCounts(stmt->gtStmtExpr);
+ }
+ // Can the entire tree be removed?
bool removedStmt = fgCheckRemoveStmt(block, stmt);
- /* Or this is the last statement of a conditional branch that was just folded */
-
- if ((!removedStmt) && (stmt->gtNext == nullptr) && !fgRemoveRestOfBlock)
+ // Or this is the last statement of a conditional branch that was just folded?
+ if (!removedStmt && (stmt->getNextStmt() == nullptr) && !fgRemoveRestOfBlock)
{
if (fgFoldConditional(block))
{
@@ -15292,11 +15361,10 @@ bool Compiler::fgMorphBlockStmt(BasicBlock* block, GenTreePtr stmt DEBUGARG(cons
if (!removedStmt)
{
- /* Have to re-do the evaluation order since for example
- * some later code does not expect constants as op1 */
+ // Have to re-do the evaluation order since for example some later code does not expect constants as op1
gtSetStmtInfo(stmt);
- /* Have to re-link the nodes for this statement */
+ // Have to re-link the nodes for this statement
fgSetStmtSeq(stmt);
}
@@ -15311,18 +15379,13 @@ bool Compiler::fgMorphBlockStmt(BasicBlock* block, GenTreePtr stmt DEBUGARG(cons
if (fgRemoveRestOfBlock)
{
- /* Remove the rest of the stmts in the block */
-
- while (stmt->gtNext)
+ // Remove the rest of the stmts in the block
+ for (stmt = stmt->getNextStmt(); stmt != nullptr; stmt = stmt->getNextStmt())
{
- stmt = stmt->gtNext;
- noway_assert(stmt->gtOper == GT_STMT);
-
fgRemoveStmt(block, stmt);
}
- // The rest of block has been removed
- // and we will always throw an exception
+ // The rest of block has been removed and we will always throw an exception.
// Update succesors of block
fgRemoveBlockAsPred(block);
@@ -15368,8 +15431,9 @@ void Compiler::fgMorphStmts(BasicBlock* block, bool* mult, bool* lnot, bool* loa
fgCurrentlyInUseArgTemps = hashBv::Create(this);
- GenTreePtr stmt, prev;
- for (stmt = block->bbTreeList, prev = nullptr; stmt; prev = stmt->gtStmt.gtStmtExpr, stmt = stmt->gtNext)
+ GenTreeStmt* stmt = block->firstStmt();
+ GenTreePtr prev = nullptr;
+ for (; stmt != nullptr; prev = stmt->gtStmtExpr, stmt = stmt->gtNextStmt)
{
noway_assert(stmt->gtOper == GT_STMT);
@@ -15379,8 +15443,7 @@ void Compiler::fgMorphStmts(BasicBlock* block, bool* mult, bool* lnot, bool* loa
continue;
}
#ifdef FEATURE_SIMD
- if (!opts.MinOpts() && stmt->gtStmt.gtStmtExpr->TypeGet() == TYP_FLOAT &&
- stmt->gtStmt.gtStmtExpr->OperGet() == GT_ASG)
+ if (!opts.MinOpts() && stmt->gtStmtExpr->TypeGet() == TYP_FLOAT && stmt->gtStmtExpr->OperGet() == GT_ASG)
{
fgMorphCombineSIMDFieldAssignments(block, stmt);
}
@@ -15388,7 +15451,7 @@ void Compiler::fgMorphStmts(BasicBlock* block, bool* mult, bool* lnot, bool* loa
fgMorphStmt = stmt;
compCurStmt = stmt;
- GenTreePtr tree = stmt->gtStmt.gtStmtExpr;
+ GenTreePtr tree = stmt->gtStmtExpr;
#ifdef DEBUG
compCurStmtNum++;
@@ -15416,15 +15479,15 @@ void Compiler::fgMorphStmts(BasicBlock* block, bool* mult, bool* lnot, bool* loa
// Has fgMorphStmt been sneakily changed ?
- if (stmt->gtStmt.gtStmtExpr != tree)
+ if (stmt->gtStmtExpr != tree)
{
/* This must be tailcall. Ignore 'morph' and carry on with
the tail-call node */
- morph = stmt->gtStmt.gtStmtExpr;
+ morph = stmt->gtStmtExpr;
noway_assert(compTailCallUsed);
noway_assert((morph->gtOper == GT_CALL) && morph->AsCall()->IsTailCall());
- noway_assert(stmt->gtNext == nullptr);
+ noway_assert(stmt->gtNextStmt == nullptr);
GenTreeCall* call = morph->AsCall();
// Could either be
@@ -15448,7 +15511,7 @@ void Compiler::fgMorphStmts(BasicBlock* block, bool* mult, bool* lnot, bool* loa
noway_assert(compTailCallUsed);
noway_assert((tree->gtOper == GT_CALL) && tree->AsCall()->IsTailCall());
- noway_assert(stmt->gtNext == nullptr);
+ noway_assert(stmt->gtNextStmt == nullptr);
GenTreeCall* call = morph->AsCall();
@@ -15505,7 +15568,7 @@ void Compiler::fgMorphStmts(BasicBlock* block, bool* mult, bool* lnot, bool* loa
fgRemoveRestOfBlock = true;
}
- stmt->gtStmt.gtStmtExpr = tree = morph;
+ stmt->gtStmtExpr = tree = morph;
noway_assert(fgPtrArgCntCur == 0);
@@ -15958,6 +16021,45 @@ void Compiler::fgMorphBlocks()
#endif
}
+//------------------------------------------------------------------------
+// fgCheckArgCnt: Check whether the maximum arg size will change codegen requirements
+//
+// Notes:
+// fpPtrArgCntMax records the maximum number of pushed arguments.
+// Depending upon this value of the maximum number of pushed arguments
+// we may need to use an EBP frame or be partially interuptible.
+// This functionality has been factored out of fgSetOptions() because
+// the Rationalizer can create new calls.
+//
+// Assumptions:
+// This must be called before isFramePointerRequired() is called, because it is a
+// phased variable (can only be written before it has been read).
+//
+void Compiler::fgCheckArgCnt()
+{
+ if (!compCanEncodePtrArgCntMax())
+ {
+#ifdef DEBUG
+ if (verbose)
+ {
+ printf("Too many pushed arguments for fully interruptible encoding, marking method as partially "
+ "interruptible\n");
+ }
+#endif
+ genInterruptible = false;
+ }
+ if (fgPtrArgCntMax >= sizeof(unsigned))
+ {
+#ifdef DEBUG
+ if (verbose)
+ {
+ printf("Too many pushed arguments for an ESP based encoding, forcing an EBP frame\n");
+ }
+#endif
+ codeGen->setFramePointerRequired(true);
+ }
+}
+
/*****************************************************************************
*
* Make some decisions about the kind of code to generate.
@@ -15974,13 +16076,11 @@ void Compiler::fgSetOptions()
}
#endif
-#ifdef DEBUGGING_SUPPORT
if (opts.compDbgCode)
{
assert(!codeGen->isGCTypeFixed());
genInterruptible = true; // debugging is easier this way ...
}
-#endif
/* Assume we won't need an explicit stack frame if this is allowed */
@@ -16035,32 +16135,7 @@ void Compiler::fgSetOptions()
#endif // _TARGET_X86_
- // fpPtrArgCntMax records the maximum number of pushed arguments
- // Depending upon this value of the maximum number of pushed arguments
- // we may need to use an EBP frame or be partially interuptible
- //
-
- if (!compCanEncodePtrArgCntMax())
- {
-#ifdef DEBUG
- if (verbose)
- {
- printf("Too many pushed arguments for fully interruptible encoding, marking method as partially "
- "interruptible\n");
- }
-#endif
- genInterruptible = false;
- }
- if (fgPtrArgCntMax >= sizeof(unsigned))
- {
-#ifdef DEBUG
- if (verbose)
- {
- printf("Too many pushed arguments for an ESP based encoding, forcing an EBP frame\n");
- }
-#endif
- codeGen->setFramePointerRequiredGCInfo(true);
- }
+ fgCheckArgCnt();
if (info.compCallUnmanaged)
{
@@ -16121,6 +16196,23 @@ GenTreePtr Compiler::fgInitThisClass()
}
else
{
+#ifdef FEATURE_READYTORUN_COMPILER
+ // Only CoreRT understands CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE. Don't do this on CoreCLR.
+ if (opts.IsReadyToRun() && IsTargetAbi(CORINFO_CORERT_ABI))
+ {
+ CORINFO_RESOLVED_TOKEN resolvedToken;
+ memset(&resolvedToken, 0, sizeof(resolvedToken));
+
+ GenTreePtr ctxTree = getRuntimeContextTree(kind.runtimeLookupKind);
+
+ // CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE with a zeroed out resolvedToken means "get the static
+ // base of the class that owns the method being compiled". If we're in this method, it means we're not
+ // inlining and there's no ambiguity.
+ return impReadyToRunHelperToTree(&resolvedToken, CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE, TYP_BYREF,
+ gtNewArgList(ctxTree), &kind);
+ }
+#endif
+
// 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.)
@@ -16774,19 +16866,13 @@ void Compiler::fgMorph()
fgRemoveEmptyBlocks();
- /* Add any internal blocks/trees we may need */
-
- fgAddInternal();
-
-#if OPT_BOOL_OPS
- fgMultipleNots = false;
-#endif
-
#ifdef DEBUG
/* Inliner could add basic blocks. Check that the flowgraph data is up-to-date */
fgDebugCheckBBlist(false, false);
#endif // DEBUG
+ EndPhase(PHASE_MORPH_INIT);
+
/* Inline */
fgInline();
#if 0
@@ -16796,6 +16882,16 @@ void Compiler::fgMorph()
RecordStateAtEndOfInlining(); // Record "start" values for post-inlining cycles and elapsed time.
+ EndPhase(PHASE_MORPH_INLINE);
+
+ /* Add any internal blocks/trees we may need */
+
+ fgAddInternal();
+
+#if OPT_BOOL_OPS
+ fgMultipleNots = false;
+#endif
+
#ifdef DEBUG
/* Inliner could add basic blocks. Check that the flowgraph data is up-to-date */
fgDebugCheckBBlist(false, false);
@@ -16804,6 +16900,8 @@ void Compiler::fgMorph()
/* For x64 and ARM64 we need to mark irregular parameters early so that they don't get promoted */
fgMarkImplicitByRefArgs();
+ EndPhase(PHASE_MORPH_IMPBYREF);
+
/* Promote struct locals if necessary */
fgPromoteStructs();
@@ -16816,10 +16914,14 @@ void Compiler::fgMorph()
fgStress64RsltMul();
#endif // DEBUG
+ EndPhase(PHASE_STR_ADRLCL);
+
/* Morph the trees in all the blocks of the method */
fgMorphBlocks();
+ EndPhase(PHASE_MORPH_GLOBAL);
+
#if 0
JITDUMP("trees after fgMorphBlocks\n");
DBEXEC(VERBOSE, fgDispBasicBlocks(true));
@@ -17454,9 +17556,6 @@ enum AddrExposedContext
AXC_AddrWide, // The address being computed will be dereferenced by a block operation that operates
// on more bytes than the width of the storage location addressed. If this is a
// field of a promoted struct local, declare the entire struct local address-taken.
- AXC_InitBlk, // An GT_INITBLK is the immediate parent. The first argument is in an IND context.
- AXC_CopyBlk, // An GT_COPYBLK is the immediate parent. The first argument is in a GT_LIST, whose
- // args should be evaluated in an IND context.
AXC_IndAdd, // A GT_ADD is the immediate parent, and it was evaluated in an IND contxt.
// If one arg is a constant int, evaluate the other in an IND context. Otherwise, none.
};
@@ -17572,14 +17671,8 @@ Compiler::fgWalkResult Compiler::fgMarkAddrTakenLocalsPreCB(GenTreePtr* pTree, f
return WALK_CONTINUE;
case GT_LIST:
- if (axc == AXC_InitBlk || axc == AXC_CopyBlk)
- {
- axcStack->Push(axc);
- }
- else
- {
- axcStack->Push(AXC_None);
- }
+ case GT_FIELD_LIST:
+ axcStack->Push(AXC_None);
return WALK_CONTINUE;
case GT_INDEX:
@@ -18083,9 +18176,6 @@ bool Compiler::fgShouldCreateAssignOp(GenTreePtr tree, bool* bReverse)
#endif // defined(LEGACY_BACKEND)
}
-// Static variables.
-Compiler::MorphAddrContext Compiler::s_CopyBlockMAC(Compiler::MACK_CopyBlock);
-
#ifdef FEATURE_SIMD
//-----------------------------------------------------------------------------------
diff --git a/src/jit/nodeinfo.h b/src/jit/nodeinfo.h
index a73033a91f..1937cc4377 100644
--- a/src/jit/nodeinfo.h
+++ b/src/jit/nodeinfo.h
@@ -21,17 +21,18 @@ public:
_internalIntCount = 0;
_internalFloatCount = 0;
- srcCandsIndex = 0;
- dstCandsIndex = 0;
- internalCandsIndex = 0;
- isLocalDefUse = false;
- isHelperCallWithKills = false;
- isLsraAdded = false;
- isDelayFree = false;
- hasDelayFreeSrc = false;
- isTgtPref = false;
- regOptional = false;
- definesAnyRegisters = false;
+ srcCandsIndex = 0;
+ dstCandsIndex = 0;
+ internalCandsIndex = 0;
+ isLocalDefUse = false;
+ isHelperCallWithKills = false;
+ isLsraAdded = false;
+ isDelayFree = false;
+ hasDelayFreeSrc = false;
+ isTgtPref = false;
+ regOptional = false;
+ definesAnyRegisters = false;
+ isInternalRegDelayFree = false;
#ifdef DEBUG
isInitialized = false;
#endif
@@ -99,42 +100,54 @@ public:
LsraLocation loc;
-private:
- unsigned char _dstCount;
- unsigned char _srcCount;
- unsigned char _internalIntCount;
- unsigned char _internalFloatCount;
-
public:
unsigned char srcCandsIndex;
unsigned char dstCandsIndex;
unsigned char internalCandsIndex;
+private:
+ unsigned char _srcCount : 5;
+ unsigned char _dstCount : 3;
+ unsigned char _internalIntCount : 3;
+ unsigned char _internalFloatCount : 3;
+
+public:
// isLocalDefUse identifies trees that produce a value that is not consumed elsewhere.
// Examples include stack arguments to a call (they are immediately stored), lhs of comma
// nodes, or top-level nodes that are non-void.
unsigned char isLocalDefUse : 1;
+
// isHelperCallWithKills is set when this is a helper call that kills more than just its in/out regs.
unsigned char isHelperCallWithKills : 1;
+
// Is this node added by LSRA, e.g. as a resolution or copy/reload move.
unsigned char isLsraAdded : 1;
+
// isDelayFree is set when the register defined by this node will interfere with the destination
// of the consuming node, and therefore it must not be freed immediately after use.
unsigned char isDelayFree : 1;
+
// hasDelayFreeSrc is set when this node has sources that are marked "isDelayFree". This is because,
// we may eventually "contain" this node, in which case we don't want it's children (which have
// already been marked "isDelayFree" to be handled that way when allocating.
unsigned char hasDelayFreeSrc : 1;
+
// isTgtPref is set to true when we have a rmw op, where we would like the result to be allocated
// in the same register as op1.
unsigned char isTgtPref : 1;
+
// Whether a spilled second src can be treated as a contained operand
unsigned char regOptional : 1;
+
// Whether or not a node defines any registers, whether directly (for nodes where dstCout is non-zero)
// or indirectly (for contained nodes, which propagate the transitive closure of the registers
// defined by their inputs). Used during buildRefPositionsForNode in order to avoid unnecessary work.
unsigned char definesAnyRegisters : 1;
+ // Whether internal register needs to be different from targetReg
+ // in which result is produced.
+ unsigned char isInternalRegDelayFree : 1;
+
#ifdef DEBUG
// isInitialized is set when the tree node is handled.
unsigned char isInitialized : 1;
diff --git a/src/jit/optcse.cpp b/src/jit/optcse.cpp
index d23b4cd198..3ff4cea385 100644
--- a/src/jit/optcse.cpp
+++ b/src/jit/optcse.cpp
@@ -301,15 +301,15 @@ Compiler::fgWalkResult Compiler::optCSE_MaskHelper(GenTreePtr* pTree, fgWalkData
if (IS_CSE_INDEX(tree->gtCSEnum))
{
- unsigned cseIndex = GET_CSE_INDEX(tree->gtCSEnum);
- EXPSET_TP cseBit = genCSEnum2bit(cseIndex);
+ unsigned cseIndex = GET_CSE_INDEX(tree->gtCSEnum);
+ unsigned cseBit = genCSEnum2bit(cseIndex);
if (IS_CSE_DEF(tree->gtCSEnum))
{
- pUserData->CSE_defMask |= cseBit;
+ BitVecOps::AddElemD(comp->cseTraits, pUserData->CSE_defMask, cseBit);
}
else
{
- pUserData->CSE_useMask |= cseBit;
+ BitVecOps::AddElemD(comp->cseTraits, pUserData->CSE_useMask, cseBit);
}
}
@@ -321,8 +321,8 @@ Compiler::fgWalkResult Compiler::optCSE_MaskHelper(GenTreePtr* pTree, fgWalkData
//
void Compiler::optCSE_GetMaskData(GenTreePtr tree, optCSE_MaskData* pMaskData)
{
- pMaskData->CSE_defMask = 0;
- pMaskData->CSE_useMask = 0;
+ pMaskData->CSE_defMask = BitVecOps::MakeCopy(cseTraits, cseEmpty);
+ pMaskData->CSE_useMask = BitVecOps::MakeCopy(cseTraits, cseEmpty);
fgWalkTreePre(&tree, optCSE_MaskHelper, (void*)pMaskData);
}
@@ -355,14 +355,14 @@ bool Compiler::optCSE_canSwap(GenTree* op1, GenTree* op2)
optCSE_GetMaskData(op2, &op2MaskData);
// We cannot swap if op1 contains a CSE def that is used by op2
- if ((op1MaskData.CSE_defMask & op2MaskData.CSE_useMask) != 0)
+ if (!BitVecOps::IsEmptyIntersection(cseTraits, op1MaskData.CSE_defMask, op2MaskData.CSE_useMask))
{
canSwap = false;
}
else
{
// We also cannot swap if op2 contains a CSE def that is used by op1.
- if ((op2MaskData.CSE_defMask & op1MaskData.CSE_useMask) != 0)
+ if (!BitVecOps::IsEmptyIntersection(cseTraits, op2MaskData.CSE_defMask, op1MaskData.CSE_useMask))
{
canSwap = false;
}
@@ -495,6 +495,14 @@ void Compiler::optValnumCSE_Init()
optCSEtab = nullptr;
#endif
+ // 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));
+
/* Allocate and clear the hash bucket table */
optCSEhash = new (this, CMK_CSE) CSEdsc*[s_optCSEhashSize]();
@@ -631,8 +639,8 @@ unsigned Compiler::optValnumCSE_Index(GenTreePtr tree, GenTreePtr stmt)
C_ASSERT((signed char)MAX_CSE_CNT == MAX_CSE_CNT);
- unsigned CSEindex = ++optCSECandidateCount;
- EXPSET_TP CSEmask = genCSEnum2bit(CSEindex);
+ unsigned CSEindex = ++optCSECandidateCount;
+ // EXPSET_TP CSEmask = genCSEnum2bit(CSEindex);
/* Record the new CSE index in the hashDsc */
hashDsc->csdIndex = CSEindex;
@@ -649,10 +657,11 @@ unsigned Compiler::optValnumCSE_Index(GenTreePtr tree, GenTreePtr stmt)
#ifdef DEBUG
if (verbose)
{
+ EXPSET_TP tempMask = BitVecOps::MakeSingleton(cseTraits, genCSEnum2bit(CSEindex));
printf("\nCSE candidate #%02u, vn=", CSEindex);
vnPrint(vnlib, 0);
- printf(" cseMask=%s in BB%02u, [cost=%2u, size=%2u]: \n", genES2str(genCSEnum2bit(CSEindex)),
- compCurBB->bbNum, tree->gtCostEx, tree->gtCostSz);
+ printf(" cseMask=%s in BB%02u, [cost=%2u, size=%2u]: \n", genES2str(cseTraits, tempMask), compCurBB->bbNum,
+ tree->gtCostEx, tree->gtCostSz);
gtDispTree(tree);
}
#endif // DEBUG
@@ -773,19 +782,18 @@ void Compiler::optValnumCSE_InitDataFlow()
if (init_to_zero)
{
/* Initialize to {ZERO} prior to dataflow */
-
- block->bbCseIn = 0;
+ block->bbCseIn = BitVecOps::MakeCopy(cseTraits, cseEmpty);
}
else
{
/* Initialize to {ALL} prior to dataflow */
-
- block->bbCseIn = EXPSET_ALL;
+ block->bbCseIn = BitVecOps::MakeCopy(cseTraits, cseFull);
}
- block->bbCseOut = EXPSET_ALL;
+
+ block->bbCseOut = BitVecOps::MakeCopy(cseTraits, cseFull);
/* Initialize to {ZERO} prior to locating the CSE candidates */
- block->bbCseGen = 0;
+ block->bbCseGen = BitVecOps::MakeCopy(cseTraits, cseEmpty);
}
// We walk the set of CSE candidates and set the bit corresponsing to the CSEindex
@@ -801,7 +809,7 @@ void Compiler::optValnumCSE_InitDataFlow()
while (lst != nullptr)
{
BasicBlock* block = lst->tslBlock;
- block->bbCseGen |= genCSEnum2bit(CSEindex);
+ BitVecOps::AddElemD(cseTraits, block->bbCseGen, genCSEnum2bit(CSEindex));
lst = lst->tslNext;
}
}
@@ -814,7 +822,7 @@ void Compiler::optValnumCSE_InitDataFlow()
bool headerPrinted = false;
for (BasicBlock* block = fgFirstBB; block; block = block->bbNext)
{
- if (block->bbCseGen != 0)
+ if (block->bbCseGen != nullptr)
{
if (!headerPrinted)
{
@@ -822,7 +830,7 @@ void Compiler::optValnumCSE_InitDataFlow()
headerPrinted = true;
}
printf("BB%02u", block->bbNum);
- printf(" cseGen = %s\n", genES2str(block->bbCseGen));
+ printf(" cseGen = %s\n", genES2str(cseTraits, block->bbCseGen));
}
}
}
@@ -857,21 +865,24 @@ public:
// At the start of the merge function of the dataflow equations, initialize premerge state (to detect changes.)
void StartMerge(BasicBlock* block)
{
- m_preMergeOut = block->bbCseOut;
+ m_preMergeOut = BitVecOps::MakeCopy(m_pCompiler->cseTraits, 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)
{
- block->bbCseIn &= predBlock->bbCseOut;
+ BitVecOps::IntersectionD(m_pCompiler->cseTraits, block->bbCseIn, predBlock->bbCseOut);
}
// At the end of the merge store results of the dataflow equations, in a postmerge state.
bool EndMerge(BasicBlock* block)
{
- EXPSET_TP mergeOut = block->bbCseOut & (block->bbCseIn | block->bbCseGen);
- block->bbCseOut = mergeOut;
- return (mergeOut != m_preMergeOut);
+ 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));
}
};
@@ -905,8 +916,8 @@ void Compiler::optValnumCSE_DataFlow()
for (BasicBlock* block = fgFirstBB; block; block = block->bbNext)
{
printf("BB%02u", block->bbNum);
- printf(" cseIn = %s", genES2str(block->bbCseIn));
- printf(" cseOut = %s", genES2str(block->bbCseOut));
+ printf(" cseIn = %s", genES2str(cseTraits, block->bbCseIn));
+ printf(" cseOut = %s", genES2str(cseTraits, block->bbCseOut));
printf("\n");
}
@@ -946,7 +957,7 @@ void Compiler::optValnumCSE_Availablity()
compCurBB = block;
- EXPSET_TP available_cses = block->bbCseIn;
+ EXPSET_TP available_cses = BitVecOps::MakeCopy(cseTraits, block->bbCseIn);
optCSEweight = block->getBBWeight(this);
@@ -961,13 +972,13 @@ void Compiler::optValnumCSE_Availablity()
{
if (IS_CSE_INDEX(tree->gtCSEnum))
{
- EXPSET_TP mask = genCSEnum2bit(tree->gtCSEnum);
- CSEdsc* desc = optCSEfindDsc(tree->gtCSEnum);
- unsigned stmw = block->getBBWeight(this);
+ unsigned int cseBit = genCSEnum2bit(tree->gtCSEnum);
+ CSEdsc* desc = optCSEfindDsc(tree->gtCSEnum);
+ unsigned stmw = block->getBBWeight(this);
/* Is this expression available here? */
- if (available_cses & mask)
+ if (BitVecOps::IsMember(cseTraits, available_cses, cseBit))
{
/* This is a CSE use */
@@ -993,8 +1004,7 @@ void Compiler::optValnumCSE_Availablity()
tree->gtCSEnum = TO_CSE_DEF(tree->gtCSEnum);
/* This CSE will be available after this def */
-
- available_cses |= mask;
+ BitVecOps::AddElemD(cseTraits, available_cses, cseBit);
}
#ifdef DEBUG
if (verbose && IS_CSE_INDEX(tree->gtCSEnum))
@@ -1236,6 +1246,7 @@ public:
{
printf("\nSorted CSE candidates:\n");
/* Print out the CSE candidates */
+ EXPSET_TP tempMask;
for (unsigned cnt = 0; cnt < m_pCompiler->optCSECandidateCount; cnt++)
{
Compiler::CSEdsc* dsc = sortTab[cnt];
@@ -1255,8 +1266,9 @@ public:
use = dsc->csdUseWtCnt; // weighted use count (excluding the implicit uses at defs)
}
+ tempMask = BitVecOps::MakeSingleton(m_pCompiler->cseTraits, genCSEnum2bit(dsc->csdIndex));
printf("CSE #%02u,cseMask=%s,useCnt=%d: [def=%3u, use=%3u", dsc->csdIndex,
- genES2str(genCSEnum2bit(dsc->csdIndex)), dsc->csdUseCount, def, use);
+ genES2str(m_pCompiler->cseTraits, tempMask), dsc->csdUseCount, def, use);
printf("] :: ");
m_pCompiler->gtDispTree(expr, nullptr, nullptr, true);
}
@@ -2038,7 +2050,7 @@ public:
assert(m_pCompiler->fgRemoveRestOfBlock == false);
/* re-morph the statement */
- m_pCompiler->fgMorphBlockStmt(blk, stm DEBUGARG("optValnumCSE"));
+ m_pCompiler->fgMorphBlockStmt(blk, stm->AsStmt() DEBUGARG("optValnumCSE"));
} while (lst != nullptr);
}
@@ -2516,8 +2528,6 @@ void Compiler::optCleanupCSEs()
//
for (BasicBlock* block = fgFirstBB; block; block = block->bbNext)
{
- unsigned blkFlags = block->bbFlags;
-
// And clear all the "visited" bits on the block
//
block->bbFlags &= ~(BBF_VISITED | BBF_MARKED);
diff --git a/src/jit/optimizer.cpp b/src/jit/optimizer.cpp
index 0fbdb27770..bd82f6a6f3 100644
--- a/src/jit/optimizer.cpp
+++ b/src/jit/optimizer.cpp
@@ -822,6 +822,10 @@ bool Compiler::optCheckIterInLoopTest(
if (limitOp->gtOper == GT_CNS_INT)
{
optLoopTable[loopInd].lpFlags |= LPFLG_CONST_LIMIT;
+ if ((limitOp->gtFlags & GTF_ICON_SIMD_COUNT) != 0)
+ {
+ optLoopTable[loopInd].lpFlags |= LPFLG_SIMD_LIMIT;
+ }
}
else if (limitOp->gtOper == GT_LCL_VAR && !optIsVarAssigned(from, to, nullptr, limitOp->gtLclVarCommon.gtLclNum))
{
@@ -1081,9 +1085,24 @@ bool Compiler::optExtractInitTestIncr(
// If it is a duplicated loop condition, skip it.
if (init->gtFlags & GTF_STMT_CMPADD)
{
- // Must be a duplicated loop condition.
- noway_assert(init->gtStmt.gtStmtExpr->gtOper == GT_JTRUE);
- init = init->gtPrev;
+ bool doGetPrev = true;
+#ifdef DEBUG
+ if (opts.optRepeat)
+ {
+ // Previous optimization passes may have inserted compiler-generated
+ // statements other than duplicated loop conditions.
+ doGetPrev = (init->gtPrev != nullptr);
+ }
+ else
+ {
+ // Must be a duplicated loop condition.
+ noway_assert(init->gtStmt.gtStmtExpr->gtOper == GT_JTRUE);
+ }
+#endif // DEBUG
+ if (doGetPrev)
+ {
+ init = init->gtPrev;
+ }
noway_assert(init != nullptr);
}
@@ -1217,10 +1236,14 @@ void Compiler::optRecordLoop(BasicBlock* head,
}
// Make sure the "iterVar" initialization is never skipped,
- // i.e. HEAD dominates the ENTRY.
- if (!fgDominate(head, entry))
+ // i.e. every pred of ENTRY other than HEAD is in the loop.
+ for (flowList* predEdge = entry->bbPreds; predEdge; predEdge = predEdge->flNext)
{
- goto DONE_LOOP;
+ BasicBlock* predBlock = predEdge->flBlock;
+ if ((predBlock != head) && !optLoopTable[loopInd].lpContains(predBlock))
+ {
+ goto DONE_LOOP;
+ }
}
if (!optPopulateInitInfo(loopInd, init, iterVar))
@@ -2798,11 +2821,6 @@ void Compiler::optUnrollLoops()
}
#endif
- if (optCanCloneLoops())
- {
- return;
- }
-
#ifdef DEBUG
if (verbose)
{
@@ -2811,276 +2829,266 @@ void Compiler::optUnrollLoops()
#endif
/* Look for loop unrolling candidates */
- /* Double loop so that after unrolling an inner loop we set change to true
- * and we then go back over all of the loop candidates and try to unroll
- * the next outer loop, until we don't unroll any loops,
- * then change will be false and we are done.
- */
- for (;;)
- {
- bool change = false;
+ bool change = false;
+
+ // Visit loops from highest to lowest number to vist them in innermost
+ // to outermost order
+ for (unsigned lnum = optLoopCount - 1; lnum != ~0U; --lnum)
+ {
+ BasicBlock* block;
+ BasicBlock* head;
+ BasicBlock* bottom;
+
+ GenTree* loop;
+ GenTree* test;
+ GenTree* incr;
+ GenTree* phdr;
+ GenTree* init;
+
+ bool dupCond;
+ int lval;
+ int lbeg; // initial value for iterator
+ int llim; // limit value for iterator
+ unsigned lvar; // iterator lclVar #
+ int iterInc; // value to increment the iterator
+ genTreeOps iterOper; // type of iterator increment (i.e. ADD, SUB, etc.)
+ var_types iterOperType; // type result of the oper (for overflow instrs)
+ genTreeOps testOper; // type of loop test (i.e. GT_LE, GT_GE, etc.)
+ bool unsTest; // Is the comparison u/int
+
+ unsigned loopRetCount; // number of BBJ_RETURN blocks in loop
+ unsigned totalIter; // total number of iterations in the constant loop
+ unsigned loopFlags; // actual lpFlags
+ unsigned requiredFlags; // required lpFlags
+
+ static const int ITER_LIMIT[COUNT_OPT_CODE + 1] = {
+ 10, // BLENDED_CODE
+ 0, // SMALL_CODE
+ 20, // FAST_CODE
+ 0 // COUNT_OPT_CODE
+ };
+
+ noway_assert(ITER_LIMIT[SMALL_CODE] == 0);
+ noway_assert(ITER_LIMIT[COUNT_OPT_CODE] == 0);
+
+ unsigned iterLimit = (unsigned)ITER_LIMIT[compCodeOpt()];
- for (unsigned lnum = 0; lnum < optLoopCount; lnum++)
+#ifdef DEBUG
+ if (compStressCompile(STRESS_UNROLL_LOOPS, 50))
{
- BasicBlock* block;
- BasicBlock* head;
- BasicBlock* bottom;
-
- GenTree* loop;
- GenTree* test;
- GenTree* incr;
- GenTree* phdr;
- GenTree* init;
-
- bool dupCond;
- int lval;
- int lbeg; // initial value for iterator
- int llim; // limit value for iterator
- unsigned lvar; // iterator lclVar #
- int iterInc; // value to increment the iterator
- genTreeOps iterOper; // type of iterator increment (i.e. ASG_ADD, ASG_SUB, etc.)
- var_types iterOperType; // type result of the oper (for overflow instrs)
- genTreeOps testOper; // type of loop test (i.e. GT_LE, GT_GE, etc.)
- bool unsTest; // Is the comparison u/int
-
- unsigned totalIter; // total number of iterations in the constant loop
- unsigned loopCostSz; // Cost is size of one iteration
- unsigned loopFlags; // actual lpFlags
- unsigned requiredFlags; // required lpFlags
+ iterLimit *= 10;
+ }
+#endif
- GenTree* loopList; // new stmt list of the unrolled loop
- GenTree* loopLast;
+ static const int UNROLL_LIMIT_SZ[COUNT_OPT_CODE + 1] = {
+ 300, // BLENDED_CODE
+ 0, // SMALL_CODE
+ 600, // FAST_CODE
+ 0 // COUNT_OPT_CODE
+ };
- static const int ITER_LIMIT[COUNT_OPT_CODE + 1] = {
- 10, // BLENDED_CODE
- 0, // SMALL_CODE
- 20, // FAST_CODE
- 0 // COUNT_OPT_CODE
- };
+ noway_assert(UNROLL_LIMIT_SZ[SMALL_CODE] == 0);
+ noway_assert(UNROLL_LIMIT_SZ[COUNT_OPT_CODE] == 0);
- noway_assert(ITER_LIMIT[SMALL_CODE] == 0);
- noway_assert(ITER_LIMIT[COUNT_OPT_CODE] == 0);
+ int unrollLimitSz = (unsigned)UNROLL_LIMIT_SZ[compCodeOpt()];
- unsigned iterLimit = (unsigned)ITER_LIMIT[compCodeOpt()];
+ loopFlags = optLoopTable[lnum].lpFlags;
+ // Check for required flags:
+ // LPFLG_DO_WHILE - required because this transform only handles loops of this form
+ // LPFLG_CONST - required because this transform only handles full unrolls
+ // LPFLG_SIMD_LIMIT - included here as a heuristic, not for correctness/structural reasons
+ requiredFlags = LPFLG_DO_WHILE | LPFLG_CONST | LPFLG_SIMD_LIMIT;
#ifdef DEBUG
- if (compStressCompile(STRESS_UNROLL_LOOPS, 50))
- {
- iterLimit *= 10;
- }
-#endif
-
- static const int UNROLL_LIMIT_SZ[COUNT_OPT_CODE + 1] = {
- 30, // BLENDED_CODE
- 0, // SMALL_CODE
- 60, // FAST_CODE
- 0 // COUNT_OPT_CODE
- };
-
- noway_assert(UNROLL_LIMIT_SZ[SMALL_CODE] == 0);
- noway_assert(UNROLL_LIMIT_SZ[COUNT_OPT_CODE] == 0);
-
- int unrollLimitSz = (unsigned)UNROLL_LIMIT_SZ[compCodeOpt()];
+ if (compStressCompile(STRESS_UNROLL_LOOPS, 50))
+ {
+ // In stress mode, quadruple the size limit, and drop
+ // the restriction that loop limit must be Vector<T>.Count.
-#ifdef DEBUG
- if (compStressCompile(STRESS_UNROLL_LOOPS, 50))
- {
- unrollLimitSz *= 10;
- }
+ unrollLimitSz *= 4;
+ requiredFlags &= ~LPFLG_SIMD_LIMIT;
+ }
#endif
- loopFlags = optLoopTable[lnum].lpFlags;
- requiredFlags = LPFLG_DO_WHILE | LPFLG_ONE_EXIT | LPFLG_CONST;
+ /* Ignore the loop if we don't have a do-while
+ that has a constant number of iterations */
- /* Ignore the loop if we don't have a do-while with a single exit
- that has a constant number of iterations */
-
- if ((loopFlags & requiredFlags) != requiredFlags)
- {
- continue;
- }
+ if ((loopFlags & requiredFlags) != requiredFlags)
+ {
+ continue;
+ }
- /* ignore if removed or marked as not unrollable */
+ /* ignore if removed or marked as not unrollable */
- if (optLoopTable[lnum].lpFlags & (LPFLG_DONT_UNROLL | LPFLG_REMOVED))
- {
- continue;
- }
+ if (loopFlags & (LPFLG_DONT_UNROLL | LPFLG_REMOVED))
+ {
+ continue;
+ }
- head = optLoopTable[lnum].lpHead;
- noway_assert(head);
- bottom = optLoopTable[lnum].lpBottom;
- noway_assert(bottom);
+ head = optLoopTable[lnum].lpHead;
+ noway_assert(head);
+ bottom = optLoopTable[lnum].lpBottom;
+ noway_assert(bottom);
- /* The single exit must be at the bottom of the loop */
- noway_assert(optLoopTable[lnum].lpExit);
- if (optLoopTable[lnum].lpExit != bottom)
- {
- continue;
- }
+ /* Get the loop data:
+ - initial constant
+ - limit constant
+ - iterator
+ - iterator increment
+ - increment operation type (i.e. ADD, SUB, etc...)
+ - loop test type (i.e. GT_GE, GT_LT, etc...)
+ */
- /* Unrolling loops with jumps in them is not worth the headache
- * Later we might consider unrolling loops after un-switching */
+ lbeg = optLoopTable[lnum].lpConstInit;
+ llim = optLoopTable[lnum].lpConstLimit();
+ testOper = optLoopTable[lnum].lpTestOper();
- block = head;
- do
- {
- block = block->bbNext;
- noway_assert(block);
+ lvar = optLoopTable[lnum].lpIterVar();
+ iterInc = optLoopTable[lnum].lpIterConst();
+ iterOper = optLoopTable[lnum].lpIterOper();
- if (block->bbJumpKind != BBJ_NONE)
- {
- if (block != bottom)
- {
- goto DONE_LOOP;
- }
- }
- } while (block != bottom);
+ iterOperType = optLoopTable[lnum].lpIterOperType();
+ unsTest = (optLoopTable[lnum].lpTestTree->gtFlags & GTF_UNSIGNED) != 0;
- /* Get the loop data:
- - initial constant
- - limit constant
- - iterator
- - iterator increment
- - increment operation type (i.e. ASG_ADD, ASG_SUB, etc...)
- - loop test type (i.e. GT_GE, GT_LT, etc...)
- */
+ if (lvaTable[lvar].lvAddrExposed)
+ { // If the loop iteration variable is address-exposed then bail
+ continue;
+ }
+ if (lvaTable[lvar].lvIsStructField)
+ { // If the loop iteration variable is a promoted field from a struct then
+ // bail
+ continue;
+ }
- lbeg = optLoopTable[lnum].lpConstInit;
- llim = optLoopTable[lnum].lpConstLimit();
- testOper = optLoopTable[lnum].lpTestOper();
+ /* Locate the pre-header and initialization and increment/test statements */
- lvar = optLoopTable[lnum].lpIterVar();
- iterInc = optLoopTable[lnum].lpIterConst();
- iterOper = optLoopTable[lnum].lpIterOper();
+ phdr = head->bbTreeList;
+ noway_assert(phdr);
+ loop = bottom->bbTreeList;
+ noway_assert(loop);
- iterOperType = optLoopTable[lnum].lpIterOperType();
- unsTest = (optLoopTable[lnum].lpTestTree->gtFlags & GTF_UNSIGNED) != 0;
+ init = head->lastStmt();
+ noway_assert(init && (init->gtNext == nullptr));
+ test = bottom->lastStmt();
+ noway_assert(test && (test->gtNext == nullptr));
+ incr = test->gtPrev;
+ noway_assert(incr);
- if (lvaTable[lvar].lvAddrExposed)
- { // If the loop iteration variable is address-exposed then bail
- continue;
- }
- if (lvaTable[lvar].lvIsStructField)
- { // If the loop iteration variable is a promoted field from a struct then
- // bail
- continue;
- }
+ if (init->gtFlags & GTF_STMT_CMPADD)
+ {
+ /* Must be a duplicated loop condition */
+ noway_assert(init->gtStmt.gtStmtExpr->gtOper == GT_JTRUE);
- /* Locate the pre-header and initialization and increment/test statements */
+ dupCond = true;
+ init = init->gtPrev;
+ noway_assert(init);
+ }
+ else
+ {
+ dupCond = false;
+ }
- phdr = head->bbTreeList;
- noway_assert(phdr);
- loop = bottom->bbTreeList;
- noway_assert(loop);
+ /* Find the number of iterations - the function returns false if not a constant number */
- init = head->lastStmt();
- noway_assert(init && (init->gtNext == nullptr));
- test = bottom->lastStmt();
- noway_assert(test && (test->gtNext == nullptr));
- incr = test->gtPrev;
- noway_assert(incr);
+ if (!optComputeLoopRep(lbeg, llim, iterInc, iterOper, iterOperType, testOper, unsTest, dupCond, &totalIter))
+ {
+ continue;
+ }
- if (init->gtFlags & GTF_STMT_CMPADD)
- {
- /* Must be a duplicated loop condition */
- noway_assert(init->gtStmt.gtStmtExpr->gtOper == GT_JTRUE);
+ /* Forget it if there are too many repetitions or not a constant loop */
- dupCond = true;
- init = init->gtPrev;
- noway_assert(init);
- }
- else
- {
- dupCond = false;
- }
+ if (totalIter > iterLimit)
+ {
+ continue;
+ }
- /* Find the number of iterations - the function returns false if not a constant number */
+ noway_assert(init->gtOper == GT_STMT);
+ init = init->gtStmt.gtStmtExpr;
+ noway_assert(test->gtOper == GT_STMT);
+ test = test->gtStmt.gtStmtExpr;
+ noway_assert(incr->gtOper == GT_STMT);
+ incr = incr->gtStmt.gtStmtExpr;
- if (!optComputeLoopRep(lbeg, llim, iterInc, iterOper, iterOperType, testOper, unsTest, dupCond, &totalIter))
- {
- continue;
- }
+ // Don't unroll loops we don't understand.
+ if (incr->gtOper != GT_ASG)
+ {
+ continue;
+ }
+ incr = incr->gtOp.gtOp2;
- /* Forget it if there are too many repetitions or not a constant loop */
+ /* Make sure everything looks ok */
+ if ((init->gtOper != GT_ASG) || (init->gtOp.gtOp1->gtOper != GT_LCL_VAR) ||
+ (init->gtOp.gtOp1->gtLclVarCommon.gtLclNum != lvar) || (init->gtOp.gtOp2->gtOper != GT_CNS_INT) ||
+ (init->gtOp.gtOp2->gtIntCon.gtIconVal != lbeg) ||
- if (totalIter > iterLimit)
- {
- continue;
- }
+ !((incr->gtOper == GT_ADD) || (incr->gtOper == GT_SUB)) || (incr->gtOp.gtOp1->gtOper != GT_LCL_VAR) ||
+ (incr->gtOp.gtOp1->gtLclVarCommon.gtLclNum != lvar) || (incr->gtOp.gtOp2->gtOper != GT_CNS_INT) ||
+ (incr->gtOp.gtOp2->gtIntCon.gtIconVal != iterInc) ||
- noway_assert(init->gtOper == GT_STMT);
- init = init->gtStmt.gtStmtExpr;
- noway_assert(test->gtOper == GT_STMT);
- test = test->gtStmt.gtStmtExpr;
- noway_assert(incr->gtOper == GT_STMT);
- incr = incr->gtStmt.gtStmtExpr;
+ (test->gtOper != GT_JTRUE))
+ {
+ noway_assert(!"Bad precondition in Compiler::optUnrollLoops()");
+ continue;
+ }
- // Don't unroll loops we don't understand.
- if (incr->gtOper == GT_ASG)
- {
- continue;
- }
+ /* heuristic - Estimated cost in code size of the unrolled loop */
- /* Make sure everything looks ok */
- if ((init->gtOper != GT_ASG) || (init->gtOp.gtOp1->gtOper != GT_LCL_VAR) ||
- (init->gtOp.gtOp1->gtLclVarCommon.gtLclNum != lvar) || (init->gtOp.gtOp2->gtOper != GT_CNS_INT) ||
- (init->gtOp.gtOp2->gtIntCon.gtIconVal != lbeg) ||
+ {
+ ClrSafeInt<unsigned> loopCostSz; // Cost is size of one iteration
- !((incr->gtOper == GT_ASG_ADD) || (incr->gtOper == GT_ASG_SUB)) ||
- (incr->gtOp.gtOp1->gtOper != GT_LCL_VAR) || (incr->gtOp.gtOp1->gtLclVarCommon.gtLclNum != lvar) ||
- (incr->gtOp.gtOp2->gtOper != GT_CNS_INT) || (incr->gtOp.gtOp2->gtIntCon.gtIconVal != iterInc) ||
+ block = head->bbNext;
+ auto tryIndex = block->bbTryIndex;
- (test->gtOper != GT_JTRUE))
+ loopRetCount = 0;
+ for (;; block = block->bbNext)
{
- noway_assert(!"Bad precondition in Compiler::optUnrollLoops()");
- continue;
- }
-
- /* heuristic - Estimated cost in code size of the unrolled loop */
-
- loopCostSz = 0;
-
- block = head;
+ if (block->bbTryIndex != tryIndex)
+ {
+ // Unrolling would require cloning EH regions
+ goto DONE_LOOP;
+ }
- do
- {
- block = block->bbNext;
+ if (block->bbJumpKind == BBJ_RETURN)
+ {
+ ++loopRetCount;
+ }
/* Visit all the statements in the block */
for (GenTreeStmt* stmt = block->firstStmt(); stmt; stmt = stmt->gtNextStmt)
{
- /* Get the expression and stop if end reached */
-
- GenTreePtr expr = stmt->gtStmtExpr;
- if (expr == incr)
- {
- break;
- }
-
/* Calculate gtCostSz */
gtSetStmtInfo(stmt);
/* Update loopCostSz */
loopCostSz += stmt->gtCostSz;
}
- } while (block != bottom);
+
+ if (block == bottom)
+ {
+ break;
+ }
+ }
+
+#ifdef JIT32_GCENCODER
+ if (fgReturnCount + loopRetCount * (totalIter - 1) > SET_EPILOGCNT_MAX)
+ {
+ // Jit32 GC encoder can't report more than SET_EPILOGCNT_MAX epilogs.
+ goto DONE_LOOP;
+ }
+#endif // !JIT32_GCENCODER
/* Compute the estimated increase in code size for the unrolled loop */
- unsigned int fixedLoopCostSz;
- fixedLoopCostSz = 8;
+ ClrSafeInt<unsigned> fixedLoopCostSz(8);
- int unrollCostSz;
- unrollCostSz = (loopCostSz * totalIter) - (loopCostSz + fixedLoopCostSz);
+ ClrSafeInt<int> unrollCostSz = ClrSafeInt<int>(loopCostSz * ClrSafeInt<unsigned>(totalIter)) -
+ ClrSafeInt<int>(loopCostSz + fixedLoopCostSz);
/* Don't unroll if too much code duplication would result. */
- if (unrollCostSz > unrollLimitSz)
+ if (unrollCostSz.IsOverflow() || (unrollCostSz.Value() > unrollLimitSz))
{
- /* prevent this loop from being revisited */
- optLoopTable[lnum].lpFlags |= LPFLG_DONT_UNROLL;
goto DONE_LOOP;
}
@@ -3100,76 +3108,81 @@ void Compiler::optUnrollLoops()
printf("\n");
}
#endif
+ }
- /* Create the unrolled loop statement list */
-
- loopList = loopLast = nullptr;
+ /* Create the unrolled loop statement list */
+ {
+ BlockToBlockMap blockMap(getAllocator());
+ BasicBlock* insertAfter = bottom;
for (lval = lbeg; totalIter; totalIter--)
{
- block = head;
-
- do
+ for (block = head->bbNext;; block = block->bbNext)
{
- GenTreeStmt* stmt;
- GenTree* expr;
-
- block = block->bbNext;
- noway_assert(block);
+ BasicBlock* newBlock = insertAfter =
+ fgNewBBafter(block->bbJumpKind, insertAfter, /*extendRegion*/ true);
+ blockMap.Set(block, newBlock);
- /* Visit all the statements in the block */
-
- for (stmt = block->firstStmt(); stmt; stmt = stmt->gtNextStmt)
+ if (!BasicBlock::CloneBlockState(this, newBlock, block, lvar, lval))
{
- /* Stop if we've reached the end of the loop */
-
- if (stmt->gtStmtExpr == incr)
- {
- break;
- }
-
- /* Clone/substitute the expression */
-
- expr = gtCloneExpr(stmt, 0, lvar, lval);
-
// cloneExpr doesn't handle everything
+ BasicBlock* oldBottomNext = insertAfter->bbNext;
+ bottom->bbNext = oldBottomNext;
+ oldBottomNext->bbPrev = bottom;
+ optLoopTable[lnum].lpFlags |= LPFLG_DONT_UNROLL;
+ goto DONE_LOOP;
+ }
+ // Block weight should no longer have the loop multiplier
+ newBlock->modifyBBWeight(newBlock->bbWeight / BB_LOOP_WEIGHT);
+ // Jump dests are set in a post-pass; make sure CloneBlockState hasn't tried to set them.
+ assert(newBlock->bbJumpDest == nullptr);
- if (!expr)
- {
- optLoopTable[lnum].lpFlags |= LPFLG_DONT_UNROLL;
- goto DONE_LOOP;
- }
-
- /* Append the expression to our list */
-
- if (loopList)
+ if (block == bottom)
+ {
+ // Remove the test; we're doing a full unroll.
+
+ GenTreeStmt* testCopyStmt = newBlock->lastStmt();
+ GenTreePtr testCopyExpr = testCopyStmt->gtStmt.gtStmtExpr;
+ assert(testCopyExpr->gtOper == GT_JTRUE);
+ GenTreePtr sideEffList = nullptr;
+ gtExtractSideEffList(testCopyExpr, &sideEffList, GTF_SIDE_EFFECT | GTF_ORDER_SIDEEFF);
+ if (sideEffList == nullptr)
{
- loopLast->gtNext = expr;
+ fgRemoveStmt(newBlock, testCopyStmt);
}
else
{
- loopList = expr;
+ testCopyStmt->gtStmt.gtStmtExpr = sideEffList;
}
+ newBlock->bbJumpKind = BBJ_NONE;
- expr->gtPrev = loopLast;
- loopLast = expr;
+ // Exit this loop; we've walked all the blocks.
+ break;
}
- } while (block != bottom);
+ }
+
+ // Now redirect any branches within the newly-cloned iteration
+ for (block = head->bbNext; block != bottom; block = block->bbNext)
+ {
+ BasicBlock* newBlock = blockMap[block];
+ optCopyBlkDest(block, newBlock);
+ optRedirectBlock(newBlock, &blockMap);
+ }
/* update the new value for the unrolled iterator */
switch (iterOper)
{
- case GT_ASG_ADD:
+ case GT_ADD:
lval += iterInc;
break;
- case GT_ASG_SUB:
+ case GT_SUB:
lval -= iterInc;
break;
- case GT_ASG_RSH:
- case GT_ASG_LSH:
+ case GT_RSH:
+ case GT_LSH:
noway_assert(!"Unrolling not implemented for this loop iterator");
goto DONE_LOOP;
@@ -3179,46 +3192,22 @@ void Compiler::optUnrollLoops()
}
}
- /* Finish the linked list */
-
- if (loopList)
+ // Gut the old loop body
+ for (block = head->bbNext;; block = block->bbNext)
{
- loopList->gtPrev = loopLast;
- loopLast->gtNext = nullptr;
- }
-
- /* Replace the body with the unrolled one */
-
- block = head;
-
- do
- {
- block = block->bbNext;
- noway_assert(block);
block->bbTreeList = nullptr;
block->bbJumpKind = BBJ_NONE;
- block->bbFlags &= ~BBF_NEEDS_GCPOLL;
- } while (block != bottom);
-
- bottom->bbJumpKind = BBJ_NONE;
- bottom->bbTreeList = loopList;
- bottom->bbFlags &= ~BBF_NEEDS_GCPOLL;
- bottom->modifyBBWeight(bottom->bbWeight / BB_LOOP_WEIGHT);
-
- bool dummy;
-
- fgMorphStmts(bottom, &dummy, &dummy, &dummy);
-
- /* Update bbRefs and bbPreds */
- /* Here head->bbNext is bottom !!! - Replace it */
-
- fgRemoveRefPred(head->bbNext, bottom);
-
- /* Now change the initialization statement in the HEAD to "lvar = lval;"
- * (the last value of the iterator in the loop)
- * and drop the jump condition since the unrolled loop will always execute */
+ block->bbFlags &= ~(BBF_NEEDS_GCPOLL | BBF_LOOP_HEAD);
+ if (block->bbJumpDest != nullptr)
+ {
+ block->bbJumpDest = nullptr;
+ }
- init->gtOp.gtOp2->gtIntCon.gtIconVal = lval;
+ if (block == bottom)
+ {
+ break;
+ }
+ }
/* if the HEAD is a BBJ_COND drop the condition (and make HEAD a BBJ_NONE block) */
@@ -3240,10 +3229,6 @@ void Compiler::optUnrollLoops()
phdr->gtPrev = init;
head->bbJumpKind = BBJ_NONE;
head->bbFlags &= ~BBF_NEEDS_GCPOLL;
-
- /* Update bbRefs and bbPreds */
-
- fgRemoveRefPred(head->bbJumpDest, head);
}
else
{
@@ -3256,18 +3241,9 @@ void Compiler::optUnrollLoops()
{
printf("Whole unrolled loop:\n");
- GenTreePtr s = loopList;
-
- while (s)
- {
- noway_assert(s->gtOper == GT_STMT);
- gtDispTree(s);
- s = s->gtNext;
- }
- printf("\n");
-
gtDispTree(init);
printf("\n");
+ fgDumpTrees(head->bbNext, insertAfter);
}
#endif
@@ -3278,22 +3254,25 @@ void Compiler::optUnrollLoops()
/* Make sure to update loop table */
/* Use the LPFLG_REMOVED flag and update the bbLoopMask acordingly
- * (also make head and bottom NULL - to hit an assert or GPF) */
+ * (also make head and bottom NULL - to hit an assert or GPF) */
optLoopTable[lnum].lpFlags |= LPFLG_REMOVED;
optLoopTable[lnum].lpHead = optLoopTable[lnum].lpBottom = nullptr;
- DONE_LOOP:;
+ // Note if we created new BBJ_RETURNs
+ fgReturnCount += loopRetCount * (totalIter - 1);
}
- if (!change)
- {
- break;
- }
+ DONE_LOOP:;
+ }
+
+ if (change)
+ {
+ fgUpdateChangedFlowGraph();
}
#ifdef DEBUG
- fgDebugCheckBBlist();
+ fgDebugCheckBBlist(true);
#endif
}
#ifdef _PREFAST_
@@ -3639,12 +3618,10 @@ void Compiler::fgOptWhileLoop(BasicBlock* block)
copyOfCondStmt->gtFlags |= GTF_STMT_CMPADD;
-#ifdef DEBUGGING_SUPPORT
if (opts.compDbgInfo)
{
copyOfCondStmt->gtStmt.gtStmtILoffsx = condStmt->gtStmt.gtStmtILoffsx;
}
-#endif
// Flag the block that received the copy as potentially having an array/vtable
// reference if the block copied from did; this is a conservative guess.
@@ -4265,7 +4242,7 @@ void Compiler::optDebugLogLoopCloning(BasicBlock* block, GenTreePtr insertBefore
GenTreePtr logCall = gtNewHelperCallNode(CORINFO_HELP_DEBUG_LOG_LOOP_CLONING, TYP_VOID);
GenTreePtr stmt = fgNewStmtFromTree(logCall);
fgInsertStmtBefore(block, insertBefore, stmt);
- fgMorphBlockStmt(block, stmt DEBUGARG("Debug log loop cloning"));
+ fgMorphBlockStmt(block, stmt->AsStmt() DEBUGARG("Debug log loop cloning"));
}
#endif
@@ -4394,14 +4371,18 @@ bool Compiler::optIsLoopClonable(unsigned loopInd)
}
// We've previously made a decision whether to have separate return epilogs, or branch to one.
- // There's a GCInfo limitation in the x86 case, so that there can be no more than 4 separate epilogs.
- // (I thought this was x86-specific, but it's not if-d. On other architectures, the decision should be made as a
- // heuristic tradeoff; perhaps we're just choosing to live with 4 as the limit.)
- if (fgReturnCount + loopRetCount > 4)
+ // There's a GCInfo limitation in the x86 case, so that there can be no more than SET_EPILOGCNT_MAX separate
+ // epilogs. Other architectures have a limit of 4 here for "historical reasons", but this should be revisited
+ // (or return blocks should not be considered part of the loop, rendering this issue moot).
+ unsigned epilogLimit = 4;
+#ifdef JIT32_GCENCODER
+ epilogLimit = SET_EPILOGCNT_MAX;
+#endif // JIT32_GCENCODER
+ if (fgReturnCount + loopRetCount > epilogLimit)
{
JITDUMP("Loop cloning: rejecting loop because it has %d returns; if added to previously-existing %d returns, "
- "would exceed the limit of 4.\n",
- loopRetCount, fgReturnCount);
+ "would exceed the limit of %d.\n",
+ loopRetCount, fgReturnCount, epilogLimit);
return false;
}
@@ -4642,7 +4623,11 @@ void Compiler::optCloneLoop(unsigned loopInd, LoopCloneContext* context)
BasicBlock* newBlk = fgNewBBafter(blk->bbJumpKind, newPred,
/*extendRegion*/ true);
- BasicBlock::CloneBlockState(this, newBlk, blk);
+ // Call CloneBlockState to make a copy of the block's statements (and attributes), and assert that it
+ // has a return value indicating success, because optCanOptimizeByLoopCloningVisitor has already
+ // checked them to guarantee they are clonable.
+ bool cloneOk = BasicBlock::CloneBlockState(this, newBlk, blk);
+ noway_assert(cloneOk);
// TODO-Cleanup: The above clones the bbNatLoopNum, which is incorrect. Eventually, we should probably insert
// the cloned loop in the loop table. For now, however, we'll just make these blocks be part of the surrounding
// loop, if one exists -- the parent of the loop we're cloning.
@@ -4716,6 +4701,12 @@ void Compiler::optCloneLoop(unsigned loopInd, LoopCloneContext* context)
}
assert(foundIt && e2 != nullptr);
+ // Don't unroll loops that we've cloned -- the unroller expects any loop it should unroll to
+ // initialize the loop counter immediately before entering the loop, but we've left a shared
+ // initialization of the loop counter up above the test that determines which version of the
+ // loop to take.
+ optLoopTable[loopInd].lpFlags |= LPFLG_DONT_UNROLL;
+
fgUpdateChangedFlowGraph();
}
@@ -6226,9 +6217,28 @@ bool Compiler::optHoistLoopExprsForTree(
// be hoisted so that they are evaluated in the same order as they would have been in the loop,
// and therefore throw exceptions in the same order. (So we don't use GTF_GLOBALLY_VISIBLE_SIDE_EFFECTS
// here, since that includes exceptions.)
- if (tree->gtFlags & GTF_CALL)
+ if (tree->IsCall())
{
- *pFirstBlockAndBeforeSideEffect = false;
+ // If it's a call, it must be a helper call that does not mutate the heap.
+ // Further, if it may run a cctor, it must be labeled as "Hoistable"
+ // (meaning it won't run a cctor because the class is not precise-init).
+ GenTreeCall* call = tree->AsCall();
+ if (call->gtCallType != CT_HELPER)
+ {
+ *pFirstBlockAndBeforeSideEffect = false;
+ }
+ else
+ {
+ CorInfoHelpFunc helpFunc = eeGetHelperNum(call->gtCallMethHnd);
+ if (s_helperCallProperties.MutatesHeap(helpFunc))
+ {
+ *pFirstBlockAndBeforeSideEffect = false;
+ }
+ else if (s_helperCallProperties.MayRunCctor(helpFunc) && (call->gtFlags & GTF_CALL_HOISTABLE) == 0)
+ {
+ *pFirstBlockAndBeforeSideEffect = false;
+ }
+ }
}
else if (tree->OperIsAssignment())
{
@@ -6748,15 +6758,17 @@ void Compiler::fgCreateLoopPreHeader(unsigned lnum)
bool Compiler::optBlockIsLoopEntry(BasicBlock* blk, unsigned* pLnum)
{
- unsigned lnum = blk->bbNatLoopNum;
- while (lnum != BasicBlock::NOT_IN_LOOP)
+ for (unsigned lnum = blk->bbNatLoopNum; lnum != BasicBlock::NOT_IN_LOOP; lnum = optLoopTable[lnum].lpParent)
{
+ if (optLoopTable[lnum].lpFlags & LPFLG_REMOVED)
+ {
+ continue;
+ }
if (optLoopTable[lnum].lpEntry == blk)
{
*pLnum = lnum;
return true;
}
- lnum = optLoopTable[lnum].lpParent;
}
return false;
}
@@ -7239,7 +7251,7 @@ void Compiler::optRemoveRangeCheck(
noway_assert(stmt->gtOper == GT_STMT);
noway_assert(tree->gtOper == GT_COMMA);
- noway_assert(tree->gtOp.gtOp1->gtOper == GT_ARR_BOUNDS_CHECK);
+ noway_assert(tree->gtOp.gtOp1->OperIsBoundsCheck());
noway_assert(forceRemove || optIsRangeCheckRemovable(tree->gtOp.gtOp1));
GenTreeBoundsChk* bndsChk = tree->gtOp.gtOp1->AsBoundsChk();
diff --git a/src/jit/protojit/CMakeLists.txt b/src/jit/protojit/CMakeLists.txt
index e3cc769ba0..91c69e9a83 100644
--- a/src/jit/protojit/CMakeLists.txt
+++ b/src/jit/protojit/CMakeLists.txt
@@ -3,8 +3,13 @@ project(protojit)
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(WIN32)
+ add_definitions(-DFX_VER_INTERNALNAME_STR=protojit.dll)
+endif(WIN32)
+
add_library_clr(protojit
SHARED
${SHARED_LIB_SOURCES}
@@ -28,7 +33,8 @@ if(CLR_CMAKE_PLATFORM_UNIX)
)
else()
list(APPEND RYUJIT_LINK_LIBRARIES
- msvcrt.lib
+ ${STATIC_MT_CRT_LIB}
+ ${STATIC_MT_VCRT_LIB}
kernel32.lib
advapi32.lib
ole32.lib
diff --git a/src/jit/rangecheck.cpp b/src/jit/rangecheck.cpp
index ae0c792f11..8d16cce31a 100644
--- a/src/jit/rangecheck.cpp
+++ b/src/jit/rangecheck.cpp
@@ -208,7 +208,7 @@ void RangeCheck::OptimizeRangeCheck(BasicBlock* block, GenTreePtr stmt, GenTreeP
// If we are not looking at array bounds check, bail.
GenTreePtr tree = treeParent->gtOp.gtOp1;
- if (tree->gtOper != GT_ARR_BOUNDS_CHECK)
+ if (!tree->OperIsBoundsCheck())
{
return;
}
@@ -233,6 +233,9 @@ void RangeCheck::OptimizeRangeCheck(BasicBlock* block, GenTreePtr stmt, GenTreeP
}
}
else
+#ifdef FEATURE_SIMD
+ if (tree->gtOper != GT_SIMD_CHK)
+#endif // FEATURE_SIMD
{
arrSize = GetArrLength(arrLenVn);
}
diff --git a/src/jit/rationalize.cpp b/src/jit/rationalize.cpp
index 03e0c9a27e..7f5a26fa1f 100644
--- a/src/jit/rationalize.cpp
+++ b/src/jit/rationalize.cpp
@@ -16,44 +16,6 @@ struct SplitData
Rationalizer* thisPhase;
};
-//------------------------------------------------------------------------------
-// isNodeCallArg - given a context (stack of parent nodes), determine if the TOS is an arg to a call
-//------------------------------------------------------------------------------
-
-GenTree* isNodeCallArg(ArrayStack<GenTree*>* parentStack)
-{
- for (int i = 1; // 0 is current node, so start at 1
- i < parentStack->Height(); i++)
- {
- GenTree* node = parentStack->Index(i);
- switch (node->OperGet())
- {
- case GT_LIST:
- case GT_ARGPLACE:
- break;
- case GT_NOP:
- // Currently there's an issue when the rationalizer performs
- // the fixup of a call argument: the case is when we remove an
- // inserted NOP as a parent of a call introduced by fgMorph;
- // when then the rationalizer removes it, the tree stack in the
- // walk is not consistent with the node it was just deleted, so the
- // solution is just to go 1 level deeper.
- // TODO-Cleanup: This has to be fixed in a proper way: make the rationalizer
- // correctly modify the evaluation stack when removing treenodes.
- if (node->gtOp.gtOp1->gtOper == GT_CALL)
- {
- return node->gtOp.gtOp1;
- }
- break;
- case GT_CALL:
- return node;
- default:
- return nullptr;
- }
- }
- return nullptr;
-}
-
// return op that is the store equivalent of the given load opcode
genTreeOps storeForm(genTreeOps loadForm)
{
@@ -109,54 +71,6 @@ void copyFlags(GenTree* dst, GenTree* src, unsigned mask)
dst->gtFlags |= (src->gtFlags & mask);
}
-// call args have other pointers to them which must be fixed up if
-// they are replaced
-void Compiler::fgFixupIfCallArg(ArrayStack<GenTree*>* parentStack, GenTree* oldChild, GenTree* newChild)
-{
- GenTree* parentCall = isNodeCallArg(parentStack);
- if (!parentCall)
- {
- return;
- }
-
- // we have replaced an arg, so update pointers in argtable
- fgFixupArgTabEntryPtr(parentCall, oldChild, newChild);
-}
-
-//------------------------------------------------------------------------
-// fgFixupArgTabEntryPtr: Fixup the fgArgTabEntryPtr of parentCall after
-// replacing oldArg with newArg
-//
-// Arguments:
-// parentCall - a pointer to the parent call node
-// oldArg - the original argument node
-// newArg - the replacement argument node
-//
-
-void Compiler::fgFixupArgTabEntryPtr(GenTreePtr parentCall, GenTreePtr oldArg, GenTreePtr newArg)
-{
- assert(parentCall != nullptr);
- assert(oldArg != nullptr);
- assert(newArg != nullptr);
-
- JITDUMP("parent call was :\n");
- DISPNODE(parentCall);
-
- JITDUMP("old child was :\n");
- DISPNODE(oldArg);
-
- if (oldArg->gtFlags & GTF_LATE_ARG)
- {
- newArg->gtFlags |= GTF_LATE_ARG;
- }
- else
- {
- fgArgTabEntryPtr fp = Compiler::gtArgEntryByNode(parentCall, oldArg);
- assert(fp->node == oldArg);
- fp->node = newArg;
- }
-}
-
// Rewrite a SIMD indirection as GT_IND(GT_LEA(obj.op1)), or as a simple
// lclVar if possible.
//
@@ -191,8 +105,8 @@ void Rationalizer::RewriteSIMDOperand(LIR::Use& use, bool keepBlk)
return;
}
- // If the operand of is a GT_ADDR(GT_LCL_VAR) and LclVar is known to be of simdType,
- // replace obj by GT_LCL_VAR.
+ // If we have GT_IND(GT_LCL_VAR_ADDR) and the GT_LCL_VAR_ADDR is TYP_BYREF/TYP_I_IMPL,
+ // and the var is a SIMD type, replace the expression by GT_LCL_VAR.
GenTree* addr = tree->AsIndir()->Addr();
if (addr->OperIsLocalAddr() && comp->isAddrOfSIMDType(addr))
{
@@ -202,6 +116,17 @@ void Rationalizer::RewriteSIMDOperand(LIR::Use& use, bool keepBlk)
addr->gtType = simdType;
use.ReplaceWith(comp, addr);
}
+#if defined(_TARGET_X86_)
+ // For x86, if we have GT_IND(GT_ADDR(GT_SIMD)), remove the GT_IND(GT_ADDR()), leaving just
+ // the GT_SIMD.
+ else if ((addr->OperGet() == GT_ADDR) && (addr->gtGetOp1()->OperGet() == GT_SIMD))
+ {
+ BlockRange().Remove(tree);
+ BlockRange().Remove(addr);
+
+ use.ReplaceWith(comp, addr->gtGetOp1());
+ }
+#endif // defined(_TARGET_X86_)
else if (!keepBlk)
{
tree->SetOper(GT_IND);
@@ -242,13 +167,32 @@ void Rationalizer::RewriteNodeAsCall(GenTree** use,
// Create the call node
GenTreeCall* call = comp->gtNewCallNode(CT_USER_FUNC, callHnd, tree->gtType, args);
- call = comp->fgMorphArgs(call);
+
+#if DEBUG
+ CORINFO_SIG_INFO sig;
+ comp->eeGetMethodSig(callHnd, &sig);
+ assert(JITtype2varType(sig.retType) == tree->gtType);
+#endif // DEBUG
+
+ call = comp->fgMorphArgs(call);
+ // Determine if this call has changed any codegen requirements.
+ comp->fgCheckArgCnt();
+
#ifdef FEATURE_READYTORUN_COMPILER
call->gtCall.setEntryPoint(entryPoint);
#endif
// Replace "tree" with "call"
- *use = call;
+ if (data->parentStack->Height() > 1)
+ {
+ data->parentStack->Index(1)->ReplaceOperand(use, call);
+ }
+ else
+ {
+ // If there's no parent, the tree being replaced is the root of the
+ // statement (and no special handling is necessary).
+ *use = call;
+ }
// Rebuild the evaluation order.
comp->gtSetStmtInfo(root);
@@ -278,8 +222,6 @@ void Rationalizer::RewriteNodeAsCall(GenTree** use,
treeNextNode->gtPrev = treeLastNode;
}
- comp->fgFixupIfCallArg(data->parentStack, tree, call);
-
// Propagate flags of "call" to its parents.
// 0 is current node, so start at 1
for (int i = 1; i < data->parentStack->Height(); i++)
@@ -510,33 +452,77 @@ void Rationalizer::RewriteAssignment(LIR::Use& use)
genTreeOps locationOp = location->OperGet();
-#ifdef FEATURE_SIMD
- if (varTypeIsSIMD(location) && assignment->OperIsInitBlkOp())
+ if (assignment->OperIsBlkOp())
{
- if (location->OperGet() == GT_LCL_VAR)
+#ifdef FEATURE_SIMD
+ if (varTypeIsSIMD(location) && assignment->OperIsInitBlkOp())
{
- var_types simdType = location->TypeGet();
- GenTree* initVal = assignment->gtOp.gtOp2;
- var_types baseType = comp->getBaseTypeOfSIMDLocal(location);
- if (baseType != TYP_UNKNOWN)
+ if (location->OperGet() == GT_LCL_VAR)
{
- GenTreeSIMD* simdTree = new (comp, GT_SIMD)
- GenTreeSIMD(simdType, initVal, SIMDIntrinsicInit, baseType, genTypeSize(simdType));
- assignment->gtOp.gtOp2 = simdTree;
- value = simdTree;
- initVal->gtNext = simdTree;
- simdTree->gtPrev = initVal;
-
- simdTree->gtNext = location;
- location->gtPrev = simdTree;
+ var_types simdType = location->TypeGet();
+ GenTree* initVal = assignment->gtOp.gtOp2;
+ var_types baseType = comp->getBaseTypeOfSIMDLocal(location);
+ if (baseType != TYP_UNKNOWN)
+ {
+ GenTreeSIMD* simdTree = new (comp, GT_SIMD)
+ GenTreeSIMD(simdType, initVal, SIMDIntrinsicInit, baseType, genTypeSize(simdType));
+ assignment->gtOp.gtOp2 = simdTree;
+ value = simdTree;
+ initVal->gtNext = simdTree;
+ simdTree->gtPrev = initVal;
+
+ simdTree->gtNext = location;
+ location->gtPrev = simdTree;
+ }
}
}
- else
+#endif // FEATURE_SIMD
+ if ((location->TypeGet() == TYP_STRUCT) && !assignment->IsPhiDefn() && !value->IsMultiRegCall())
{
- assert(location->OperIsBlk());
+ if ((location->OperGet() == GT_LCL_VAR))
+ {
+ // We need to construct a block node for the location.
+ // Modify lcl to be the address form.
+ location->SetOper(addrForm(locationOp));
+ LclVarDsc* varDsc = &(comp->lvaTable[location->AsLclVarCommon()->gtLclNum]);
+ location->gtType = TYP_BYREF;
+ GenTreeBlk* storeBlk = nullptr;
+ unsigned int size = varDsc->lvExactSize;
+
+ if (varDsc->lvStructGcCount != 0)
+ {
+ CORINFO_CLASS_HANDLE structHnd = varDsc->lvVerTypeInfo.GetClassHandle();
+ GenTreeObj* objNode = comp->gtNewObjNode(structHnd, location)->AsObj();
+ unsigned int slots = (unsigned)(roundUp(size, TARGET_POINTER_SIZE) / TARGET_POINTER_SIZE);
+
+ objNode->SetGCInfo(varDsc->lvGcLayout, varDsc->lvStructGcCount, slots);
+ objNode->ChangeOper(GT_STORE_OBJ);
+ objNode->SetData(value);
+ comp->fgMorphUnsafeBlk(objNode);
+ storeBlk = objNode;
+ }
+ else
+ {
+ storeBlk = new (comp, GT_STORE_BLK) GenTreeBlk(GT_STORE_BLK, TYP_STRUCT, location, value, size);
+ }
+ storeBlk->gtFlags |= (GTF_REVERSE_OPS | GTF_ASG);
+ storeBlk->gtFlags |= ((location->gtFlags | value->gtFlags) & GTF_ALL_EFFECT);
+
+ GenTree* insertionPoint = location->gtNext;
+ BlockRange().InsertBefore(insertionPoint, storeBlk);
+ use.ReplaceWith(comp, storeBlk);
+ BlockRange().Remove(assignment);
+ JITDUMP("After transforming local struct assignment into a block op:\n");
+ DISPTREERANGE(BlockRange(), use.Def());
+ JITDUMP("\n");
+ return;
+ }
+ else
+ {
+ assert(location->OperIsBlk());
+ }
}
}
-#endif // FEATURE_SIMD
switch (locationOp)
{
@@ -605,10 +591,10 @@ void Rationalizer::RewriteAssignment(LIR::Use& use)
}
JITDUMP("Rewriting GT_ASG(%s(X), Y) to %s(X,Y):\n", GenTree::NodeName(location->gtOper),
GenTree::NodeName(storeOper));
- storeBlk->gtOper = storeOper;
+ storeBlk->SetOperRaw(storeOper);
storeBlk->gtFlags &= ~GTF_DONT_CSE;
storeBlk->gtFlags |= (assignment->gtFlags & (GTF_ALL_EFFECT | GTF_REVERSE_OPS | GTF_BLK_VOLATILE |
- GTF_BLK_UNALIGNED | GTF_BLK_INIT | GTF_DONT_CSE));
+ GTF_BLK_UNALIGNED | GTF_DONT_CSE));
storeBlk->gtBlk.Data() = value;
// Replace the assignment node with the store
@@ -693,21 +679,20 @@ Compiler::fgWalkResult Rationalizer::RewriteNode(GenTree** useEdge, ArrayStack<G
const bool isLateArg = (node->gtFlags & GTF_LATE_ARG) != 0;
#endif
- // First, remove any preceeding GT_LIST nodes, which are not otherwise visited by the tree walk.
+ // First, remove any preceeding list nodes, which are not otherwise visited by the tree walk.
//
- // NOTE: GT_LIST nodes that are used as aggregates, by block ops, and by phi nodes will in fact be visited.
- for (GenTree* prev = node->gtPrev;
- prev != nullptr && prev->OperGet() == GT_LIST && !(prev->AsArgList()->IsAggregate());
- prev = node->gtPrev)
+ // NOTE: GT_FIELD_LIST head nodes, and GT_LIST nodes used by phi nodes will in fact be visited.
+ for (GenTree* prev = node->gtPrev; prev != nullptr && prev->OperIsAnyList() && !(prev->OperIsFieldListHead());
+ prev = node->gtPrev)
{
BlockRange().Remove(prev);
}
// In addition, remove the current node if it is a GT_LIST node that is not an aggregate.
- if (node->OperGet() == GT_LIST)
+ if (node->OperIsAnyList())
{
GenTreeArgList* list = node->AsArgList();
- if (!list->IsAggregate())
+ if (!list->OperIsFieldListHead())
{
BlockRange().Remove(list);
}
@@ -741,6 +726,11 @@ Compiler::fgWalkResult Rationalizer::RewriteNode(GenTree** useEdge, ArrayStack<G
RewriteAddress(use);
break;
+ case GT_IND:
+ // Clear the `GTF_IND_ASG_LHS` flag, which overlaps with `GTF_IND_REQ_ADDR_IN_REG`.
+ node->gtFlags &= ~GTF_IND_ASG_LHS;
+ break;
+
case GT_NOP:
// fgMorph sometimes inserts NOP nodes between defs and uses
// supposedly 'to prevent constant folding'. In this case, remove the
@@ -931,19 +921,27 @@ Compiler::fgWalkResult Rationalizer::RewriteNode(GenTree** useEdge, ArrayStack<G
#endif // FEATURE_SIMD
default:
+ // JCC nodes should not be present in HIR.
+ assert(node->OperGet() != GT_JCC);
break;
}
// Do some extra processing on top-level nodes to remove unused local reads.
- if (use.IsDummyUse() && node->OperIsLocalRead())
+ if (node->OperIsLocalRead())
{
- assert((node->gtFlags & GTF_ALL_EFFECT) == 0);
-
- comp->lvaDecRefCnts(node);
- BlockRange().Remove(node);
+ if (use.IsDummyUse())
+ {
+ comp->lvaDecRefCnts(node);
+ BlockRange().Remove(node);
+ }
+ else
+ {
+ // Local reads are side-effect-free; clear any flags leftover from frontend transformations.
+ node->gtFlags &= ~GTF_ALL_EFFECT;
+ }
}
- assert(isLateArg == ((node->gtFlags & GTF_LATE_ARG) != 0));
+ assert(isLateArg == ((use.Def()->gtFlags & GTF_LATE_ARG) != 0));
return Compiler::WALK_CONTINUE;
}
diff --git a/src/jit/regalloc.cpp b/src/jit/regalloc.cpp
index 9dd7299906..8a7ad5a163 100644
--- a/src/jit/regalloc.cpp
+++ b/src/jit/regalloc.cpp
@@ -53,8 +53,6 @@ regMaskTP Compiler::raConfigRestrictMaskFP()
return result;
}
-#ifdef LEGACY_BACKEND // We don't use any of the old register allocator functions when LSRA is used instead.
-
#if DOUBLE_ALIGN
DWORD Compiler::getCanDoubleAlign()
{
@@ -67,8 +65,84 @@ DWORD Compiler::getCanDoubleAlign()
return DEFAULT_DOUBLE_ALIGN;
#endif
}
+
+//------------------------------------------------------------------------
+// shouldDoubleAlign: Determine whether to double-align the frame
+//
+// Arguments:
+// refCntStk - sum of ref counts for all stack based variables
+// refCntEBP - sum of ref counts for EBP enregistered variables
+// refCntWtdEBP - sum of wtd ref counts for EBP enregistered variables
+// refCntStkParam - sum of ref counts for all stack based parameters
+// refCntWtdStkDbl - sum of wtd ref counts for stack based doubles (including structs
+// with double fields).
+//
+// Return Value:
+// Returns true if this method estimates that a double-aligned frame would be beneficial
+//
+// Notes:
+// The impact of a double-aligned frame is computed as follows:
+// - We save a byte of code for each parameter reference (they are frame-pointer relative)
+// - We pay a byte of code for each non-parameter stack reference.
+// - We save the misalignment penalty and possible cache-line crossing penalty.
+// This is estimated as 0 for SMALL_CODE, 16 for FAST_CODE and 4 otherwise.
+// - We pay 7 extra bytes for:
+// MOV EBP,ESP,
+// LEA ESP,[EBP-offset]
+// AND ESP,-8 to double align ESP
+// - We pay one extra memory reference for each variable that could have been enregistered in EBP (refCntWtdEBP).
+//
+// If the misalignment penalty is estimated to be less than the bytes used, we don't double align.
+// Otherwise, we compare the weighted ref count of ebp-enregistered variables aginst double the
+// ref count for double-aligned values.
+//
+bool Compiler::shouldDoubleAlign(
+ unsigned refCntStk, unsigned refCntEBP, unsigned refCntWtdEBP, unsigned refCntStkParam, unsigned refCntWtdStkDbl)
+{
+ bool doDoubleAlign = false;
+ const unsigned DBL_ALIGN_SETUP_SIZE = 7;
+
+ unsigned bytesUsed = refCntStk + refCntEBP - refCntStkParam + DBL_ALIGN_SETUP_SIZE;
+ unsigned misaligned_weight = 4;
+
+ if (compCodeOpt() == Compiler::SMALL_CODE)
+ misaligned_weight = 0;
+
+ if (compCodeOpt() == Compiler::FAST_CODE)
+ misaligned_weight *= 4;
+
+ JITDUMP("\nDouble alignment:\n");
+ JITDUMP(" Bytes that could be saved by not using EBP frame: %i\n", bytesUsed);
+ JITDUMP(" Sum of weighted ref counts for EBP enregistered variables: %i\n", refCntWtdEBP);
+ JITDUMP(" Sum of weighted ref counts for weighted stack based doubles: %i\n", refCntWtdStkDbl);
+
+ if (bytesUsed > ((refCntWtdStkDbl * misaligned_weight) / BB_UNITY_WEIGHT))
+ {
+ JITDUMP(" Predicting not to double-align ESP to save %d bytes of code.\n", bytesUsed);
+ }
+ else if (refCntWtdEBP > refCntWtdStkDbl * 2)
+ {
+ // TODO-CQ: On P4 2 Proc XEON's, SciMark.FFT degrades if SciMark.FFT.transform_internal is
+ // not double aligned.
+ // Here are the numbers that make this not double-aligned.
+ // refCntWtdStkDbl = 0x164
+ // refCntWtdEBP = 0x1a4
+ // We think we do need to change the heuristic to be in favor of double-align.
+
+ JITDUMP(" Predicting not to double-align ESP to allow EBP to be used to enregister variables.\n");
+ }
+ else
+ {
+ // OK we passed all of the benefit tests, so we'll predict a double aligned frame.
+ JITDUMP(" Predicting to create a double-aligned frame\n");
+ doDoubleAlign = true;
+ }
+ return doDoubleAlign;
+}
#endif // DOUBLE_ALIGN
+#ifdef LEGACY_BACKEND // We don't use any of the old register allocator functions when LSRA is used instead.
+
void Compiler::raInit()
{
#if FEATURE_STACK_FP_X87
@@ -2415,12 +2489,6 @@ regMaskTP Compiler::rpPredictTreeRegUse(GenTreePtr tree,
{
case GT_ASG:
- if (tree->OperIsBlkOp())
- {
- interferingRegs |= rpPredictBlkAsgRegUse(tree, predictReg, lockedRegs, rsvdRegs);
- regMask = 0;
- goto RETURN_CHECK;
- }
/* Is the value being assigned into a LCL_VAR? */
if (op1->gtOper == GT_LCL_VAR)
{
@@ -2486,6 +2554,12 @@ regMaskTP Compiler::rpPredictTreeRegUse(GenTreePtr tree,
}
}
}
+ else if (tree->OperIsBlkOp())
+ {
+ interferingRegs |= rpPredictBlkAsgRegUse(tree, predictReg, lockedRegs, rsvdRegs);
+ regMask = 0;
+ goto RETURN_CHECK;
+ }
__fallthrough;
case GT_CHS:
@@ -4384,6 +4458,13 @@ regMaskTP Compiler::rpPredictTreeRegUse(GenTreePtr tree,
case GT_ARR_LENGTH:
goto GENERIC_UNARY;
+ case GT_INIT_VAL:
+ // This unary operator simply passes through the value from its child (much like GT_NOP)
+ // and thus won't need a scratch register.
+ regMask = rpPredictTreeRegUse(op1, predictReg, lockedRegs, rsvdRegs);
+ tree->gtUsedRegs = op1->gtUsedRegs;
+ goto RETURN_CHECK;
+
default:
#ifdef DEBUG
gtDispTree(tree);
@@ -4525,7 +4606,7 @@ regMaskTP Compiler::rpPredictTreeRegUse(GenTreePtr tree,
curArgMask = RBM_NONE; // Set of argument registers that are going to be setup by this arg
tmpMask = RBM_NONE; // Set of additional temp registers that are need only to setup the current arg
- assert(list->IsList());
+ assert(list->OperIsList());
args = list->Current();
list = list->Rest();
@@ -5840,114 +5921,14 @@ regMaskTP Compiler::rpPredictAssignRegVars(regMaskTP regAvail)
if (getCanDoubleAlign() == CAN_DOUBLE_ALIGN && (refCntWtdStkDbl > 0))
{
- /* OK, there may be some benefit to double-aligning the frame */
- /* But let us compare the benefits vs. the costs of this */
-
- /*
- One cost to consider is the benefit of smaller code
- when using EBP as a frame pointer register
-
- Each stack variable reference is an extra byte of code
- if we use a double-aligned frame, parameters are
- accessed via EBP for a double-aligned frame so they
- don't use an extra byte of code.
-
- We pay one byte of code for each refCntStk and we pay
- one byte or more for each refCntEBP but we save one
- byte for each refCntStkParam.
-
- Our savings are the elimination of a possible misaligned
- access and a possible DCU spilt when an access crossed
- a cache-line boundry.
-
- We use the loop weighted value of
- refCntWtdStkDbl * misaligned_weight (0, 4, 16)
- to represent this savings.
- */
-
- // We also pay 7 extra bytes for the MOV EBP,ESP,
- // LEA ESP,[EBP-0x10] and the AND ESP,-8 to double align ESP
- const unsigned DBL_ALIGN_SETUP_SIZE = 7;
-
- unsigned bytesUsed = refCntStk + refCntEBP - refCntStkParam + DBL_ALIGN_SETUP_SIZE;
- unsigned misaligned_weight = 4;
-
- if (compCodeOpt() == SMALL_CODE)
- misaligned_weight = 0;
-
- if (compCodeOpt() == FAST_CODE)
- misaligned_weight *= 4;
-
-#ifdef DEBUG
- if (verbose)
- {
- printf("; Double alignment:\n");
- printf("; Bytes that could be save by not using EBP frame: %i\n", bytesUsed);
- printf("; Sum of weighted ref counts for EBP enregistered variables: %i\n", refCntWtdEBP);
- printf("; Sum of weighted ref counts for weighted stack based doubles: %i\n", refCntWtdStkDbl);
- }
-#endif
-
- if (bytesUsed > ((refCntWtdStkDbl * misaligned_weight) / BB_UNITY_WEIGHT))
- {
- /* It's probably better to use EBP as a frame pointer */
- CLANG_FORMAT_COMMENT_ANCHOR;
-
-#ifdef DEBUG
- if (verbose)
- printf("; Predicting not to double-align ESP to save %d bytes of code.\n", bytesUsed);
-#endif
- goto NO_DOUBLE_ALIGN;
- }
-
- /*
- Another cost to consider is the benefit of using EBP to enregister
- one or more integer variables
-
- We pay one extra memory reference for each refCntWtdEBP
-
- Our savings are the elimination of a possible misaligned
- access and a possible DCU spilt when an access crossed
- a cache-line boundry.
-
- */
-
- // <BUGNUM>
- // VSW 346717: On P4 2 Proc XEON's, SciMark.FFT degrades if SciMark.FFT.transform_internal is
- // not double aligned.
- // Here are the numbers that make this not double-aligned.
- // refCntWtdStkDbl = 0x164
- // refCntWtdEBP = 0x1a4
- // We think we do need to change the heuristic to be in favor of double-align.
- // </BUGNUM>
-
- if (refCntWtdEBP > refCntWtdStkDbl * 2)
+ if (shouldDoubleAlign(refCntStk, refCntEBP, refCntWtdEBP, refCntStkParam, refCntWtdStkDbl))
{
- /* It's probably better to use EBP to enregister integer variables */
- CLANG_FORMAT_COMMENT_ANCHOR;
-
-#ifdef DEBUG
- if (verbose)
- printf("; Predicting not to double-align ESP to allow EBP to be used to enregister variables\n");
-#endif
- goto NO_DOUBLE_ALIGN;
+ rpFrameType = FT_DOUBLE_ALIGN_FRAME;
+ goto REVERSE_EBP_ENREG;
}
-
-#ifdef DEBUG
- if (verbose)
- printf("; Predicting to create a double-aligned frame\n");
-#endif
- /*
- OK we passed all of the benefit tests
- so we'll predict a double aligned frame
- */
-
- rpFrameType = FT_DOUBLE_ALIGN_FRAME;
- goto REVERSE_EBP_ENREG;
}
}
-NO_DOUBLE_ALIGN:
#endif // DOUBLE_ALIGN
if (!codeGen->isFramePointerRequired() && !codeGen->isFrameRequired())
@@ -6673,8 +6654,6 @@ void Compiler::raMarkStkVars()
#endif // FEATURE_FIXED_OUT_ARGS
-#ifdef DEBUGGING_SUPPORT
-
#ifdef DEBUG
/* For debugging, note that we have to reserve space even for
unused variables if they are ever in scope. However, this is not
@@ -6709,7 +6688,6 @@ void Compiler::raMarkStkVars()
varDsc->lvMustInit = true;
}
}
-#endif // DEBUGGING_SUPPORT
#ifndef LEGACY_BACKEND
varDsc->lvOnFrame = needSlot;
diff --git a/src/jit/regalloc.h b/src/jit/regalloc.h
index 7e2d7c7eb1..5054b4568e 100644
--- a/src/jit/regalloc.h
+++ b/src/jit/regalloc.h
@@ -17,6 +17,18 @@ enum FrameType
#endif
};
+#if DOUBLE_ALIGN
+enum CanDoubleAlign
+{
+ CANT_DOUBLE_ALIGN,
+ CAN_DOUBLE_ALIGN,
+ MUST_DOUBLE_ALIGN,
+ COUNT_DOUBLE_ALIGN,
+
+ DEFAULT_DOUBLE_ALIGN = CAN_DOUBLE_ALIGN
+};
+#endif
+
#ifdef LEGACY_BACKEND
#include "varset.h"
@@ -94,18 +106,6 @@ enum rpPredictReg
#endif // _TARGET_
};
-#if DOUBLE_ALIGN
-enum CanDoubleAlign
-{
- CANT_DOUBLE_ALIGN,
- CAN_DOUBLE_ALIGN,
- MUST_DOUBLE_ALIGN,
- COUNT_DOUBLE_ALIGN,
-
- DEFAULT_DOUBLE_ALIGN = CAN_DOUBLE_ALIGN
-};
-#endif
-
#endif // LEGACY_BACKEND
#endif // REGALLOC_H_
diff --git a/src/jit/registerfp.cpp b/src/jit/registerfp.cpp
index 997c223ed4..3a3143e629 100644
--- a/src/jit/registerfp.cpp
+++ b/src/jit/registerfp.cpp
@@ -326,10 +326,8 @@ void CodeGen::genFloatAssign(GenTree* tree)
bool unaligned = false; // Is this an unaligned store
regNumber op2reg = REG_NA;
-#ifdef DEBUGGING_SUPPORT
unsigned lclVarNum = compiler->lvaCount;
unsigned lclILoffs = DUMMY_INIT(0);
-#endif
noway_assert(tree->OperGet() == GT_ASG);
@@ -358,7 +356,6 @@ void CodeGen::genFloatAssign(GenTree* tree)
noway_assert(varNum < compiler->lvaCount);
varDsc = compiler->lvaTable + varNum;
-#ifdef DEBUGGING_SUPPORT
// For non-debuggable code, every definition of a lcl-var has
// to be checked to see if we need to open a new scope for it.
// Remember the local var info to call siCheckVarScope
@@ -369,7 +366,6 @@ void CodeGen::genFloatAssign(GenTree* tree)
lclVarNum = varNum;
lclILoffs = op1->gtLclVar.gtLclILoffs;
}
-#endif
// Dead Store assert (with min opts we may have dead stores)
//
@@ -607,13 +603,11 @@ DONE_ASG:
genUpdateLife(tree);
-#ifdef DEBUGGING_SUPPORT
/* For non-debuggable code, every definition of a lcl-var has
* to be checked to see if we need to open a new scope for it.
*/
if (lclVarNum < compiler->lvaCount)
siCheckVarScope(lclVarNum, lclILoffs);
-#endif
}
void CodeGen::genCodeForTreeFloat(GenTreePtr tree, RegSet::RegisterPreference* pref)
diff --git a/src/jit/regset.cpp b/src/jit/regset.cpp
index 2980f96813..0d0ac3e0ce 100644
--- a/src/jit/regset.cpp
+++ b/src/jit/regset.cpp
@@ -3175,6 +3175,16 @@ var_types Compiler::tmpNormalizeType(var_types type)
type = genActualType(type);
+#if defined(FEATURE_SIMD) && !defined(_TARGET_64BIT_)
+ // For SIMD on 32-bit platforms, we always spill SIMD12 to a 16-byte SIMD16 temp.
+ // This is because we don't have a single instruction to store 12 bytes. We also
+ // allocate non-argument locals as 16 bytes; see lvSize().
+ if (type == TYP_SIMD12)
+ {
+ type = TYP_SIMD16;
+ }
+#endif // defined(FEATURE_SIMD) && !defined(_TARGET_64BIT_)
+
#else // LEGACY_BACKEND
if (!varTypeIsGC(type))
{
diff --git a/src/jit/scopeinfo.cpp b/src/jit/scopeinfo.cpp
index f2a7902317..29c18f941c 100644
--- a/src/jit/scopeinfo.cpp
+++ b/src/jit/scopeinfo.cpp
@@ -58,10 +58,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include "emit.h"
#include "codegen.h"
-/*****************************************************************************/
-#ifdef DEBUGGING_SUPPORT
-/*****************************************************************************/
-
bool Compiler::siVarLoc::vlIsInReg(regNumber reg)
{
switch (vlType)
@@ -1050,7 +1046,6 @@ void CodeGen::psiBegProlog()
void CodeGen::psiAdjustStackLevel(unsigned size)
{
-#ifdef DEBUGGING_SUPPORT
if (!compiler->opts.compScopeInfo || (compiler->info.compVarScopesCount == 0))
{
return;
@@ -1082,7 +1077,6 @@ void CodeGen::psiAdjustStackLevel(unsigned size)
}
#endif // ACCURATE_PROLOG_DEBUG_INFO
-#endif // DEBUGGING_SUPPORT
}
/*****************************************************************************
@@ -1094,7 +1088,6 @@ void CodeGen::psiAdjustStackLevel(unsigned size)
void CodeGen::psiMoveESPtoEBP()
{
-#ifdef DEBUGGING_SUPPORT
if (!compiler->opts.compScopeInfo || (compiler->info.compVarScopesCount == 0))
{
return;
@@ -1127,7 +1120,6 @@ void CodeGen::psiMoveESPtoEBP()
}
#endif // ACCURATE_PROLOG_DEBUG_INFO
-#endif // DEBUGGING_SUPPORT
}
/*****************************************************************************
@@ -1141,7 +1133,6 @@ void CodeGen::psiMoveESPtoEBP()
void CodeGen::psiMoveToReg(unsigned varNum, regNumber reg, regNumber otherReg)
{
-#ifdef DEBUGGING_SUPPORT
assert(compiler->compGeneratingProlog);
if (!compiler->opts.compScopeInfo)
@@ -1195,7 +1186,6 @@ void CodeGen::psiMoveToReg(unsigned varNum, regNumber reg, regNumber otherReg)
!"Parameter scope not found (Assert doesnt always indicate error)");
#endif // ACCURATE_PROLOG_DEBUG_INFO
-#endif // DEBUGGING_SUPPORT
}
/*****************************************************************************
@@ -1207,7 +1197,6 @@ void CodeGen::psiMoveToReg(unsigned varNum, regNumber reg, regNumber otherReg)
void CodeGen::psiMoveToStack(unsigned varNum)
{
-#ifdef DEBUGGING_SUPPORT
if (!compiler->opts.compScopeInfo || (compiler->info.compVarScopesCount == 0))
{
return;
@@ -1248,7 +1237,6 @@ void CodeGen::psiMoveToStack(unsigned varNum)
!"Parameter scope not found (Assert doesnt always indicate error)");
#endif // ACCURATE_PROLOG_DEBUG_INFO
-#endif // DEBUGGING_SUPPORT
}
/*****************************************************************************
@@ -1264,8 +1252,4 @@ void CodeGen::psiEndProlog()
{
psiEndPrologScope(scope);
}
-}
-
-/*****************************************************************************/
-#endif // DEBUGGING_SUPPORT
-/*****************************************************************************/
+} \ No newline at end of file
diff --git a/src/jit/sideeffects.h b/src/jit/sideeffects.h
index 33fac16f05..e14b2925ed 100644
--- a/src/jit/sideeffects.h
+++ b/src/jit/sideeffects.h
@@ -136,6 +136,12 @@ public:
// SideEffectSet:
// Represents a set of side effects for the purposes of analyzing code
// motion.
+// Note that for non-fixed-size frames without a frame pointer (currently
+// x86-only), we don't track the modification of the stack level that occurs
+// with a GT_PUTARG_STK as a side-effect. If we ever support general code
+// reordering, that would have to be taken into account. As it happens,
+// we currently do not reorder any other side-effecting nodes relative to
+// these.
//
class SideEffectSet final
{
diff --git a/src/jit/simd.cpp b/src/jit/simd.cpp
index 1f0c867b55..39664c47bf 100644
--- a/src/jit/simd.cpp
+++ b/src/jit/simd.cpp
@@ -77,10 +77,10 @@ int Compiler::getSIMDVectorLength(CORINFO_CLASS_HANDLE typeHnd)
//
int Compiler::getSIMDTypeAlignment(var_types simdType)
{
-#ifdef _TARGET_AMD64_
+#ifdef _TARGET_XARCH_
// Fixed length vectors have the following alignment preference
- // Vector2/3 = 8 byte alignment
- // Vector4 = 16-byte alignment
+ // Vector2 = 8 byte alignment
+ // Vector3/4 = 16-byte alignment
unsigned size = genTypeSize(simdType);
// preferred alignment for SSE2 128-bit vectors is 16-bytes
@@ -88,13 +88,16 @@ int Compiler::getSIMDTypeAlignment(var_types simdType)
{
return 8;
}
-
- // As per Intel manual, AVX vectors preferred alignment is 32-bytes but on Amd64
- // RSP/EBP is aligned at 16-bytes, therefore to align SIMD types at 32-bytes we need even
- // RSP/EBP to be 32-byte aligned. It is not clear whether additional stack space used in
- // aligning stack is worth the benefit and for now will use 16-byte alignment for AVX
- // 256-bit vectors with unaligned load/stores to/from memory.
- return 16;
+ else if (size <= 16)
+ {
+ assert((size == 12) || (size == 16));
+ return 16;
+ }
+ else
+ {
+ assert(size == 32);
+ return 32;
+ }
#else
assert(!"getSIMDTypeAlignment() unimplemented on target arch");
unreached();
@@ -391,7 +394,6 @@ const SIMDIntrinsicInfo* Compiler::getSIMDIntrinsicInfo(CORINFO_CLASS_HANDLE* in
CORINFO_CLASS_HANDLE typeHnd = *inOutTypeHnd;
*baseType = getBaseTypeAndSizeOfSIMDType(typeHnd, sizeBytes);
- bool isHWAcceleratedIntrinsic = false;
if (typeHnd == SIMDVectorHandle)
{
// All of the supported intrinsics on this static class take a first argument that's a vector,
@@ -424,6 +426,16 @@ const SIMDIntrinsicInfo* Compiler::getSIMDIntrinsicInfo(CORINFO_CLASS_HANDLE* in
return nullptr;
}
+#ifdef _TARGET_X86_
+ // NYI: support LONG type SIMD intrinsics. Need support in long decomposition.
+ // (Don't use NYI fallback mechanism; just call the function.)
+ if ((*baseType == TYP_LONG) || (*baseType == TYP_ULONG))
+ {
+ JITDUMP("NYI: x86 long base type SIMD intrinsics\n");
+ return nullptr;
+ }
+#endif // _TARGET_X86_
+
// account for implicit "this" arg
*argCount = sig->numArgs;
if (sig->hasThis())
@@ -525,7 +537,8 @@ const SIMDIntrinsicInfo* Compiler::getSIMDIntrinsicInfo(CORINFO_CLASS_HANDLE* in
// We don't check anything in that case.
if (!isThisPtr || !isNewObj)
{
- GenTreePtr arg = impStackTop(stackIndex).val;
+ GenTreePtr arg = impStackTop(stackIndex).val;
+ var_types argType = arg->TypeGet();
var_types expectedArgType;
if (argIndex < fixedArgCnt)
@@ -540,6 +553,7 @@ const SIMDIntrinsicInfo* Compiler::getSIMDIntrinsicInfo(CORINFO_CLASS_HANDLE* in
{
// The type of the argument will be genActualType(*baseType).
expectedArgType = genActualType(*baseType);
+ argType = genActualType(argType);
}
}
else
@@ -547,7 +561,6 @@ const SIMDIntrinsicInfo* Compiler::getSIMDIntrinsicInfo(CORINFO_CLASS_HANDLE* in
expectedArgType = *baseType;
}
- var_types argType = arg->TypeGet();
if (!isThisPtr && argType == TYP_I_IMPL)
{
// The reference implementation has a constructor that takes a pointer.
@@ -715,7 +728,7 @@ GenTreeSIMD* Compiler::impSIMDGetFixed(var_types simdType, var_types baseType, u
return simdTree;
}
-#ifdef _TARGET_AMD64_
+#ifdef _TARGET_XARCH_
// impSIMDLongRelOpEqual: transforms operands and returns the SIMD intrinsic to be applied on
// transformed operands to obtain == comparison result.
//
@@ -741,7 +754,7 @@ SIMDIntrinsicID Compiler::impSIMDLongRelOpEqual(CORINFO_CLASS_HANDLE typeHnd,
//
// Equality(v1, v2):
// tmp = (v1 == v2) i.e. compare for equality as if v1 and v2 are vector<int>
- // result = BitwiseAnd(t, shuffle(t, (2, 3, 1 0)))
+ // result = BitwiseAnd(t, shuffle(t, (2, 3, 0, 1)))
// Shuffle is meant to swap the comparison results of low-32-bits and high 32-bits of respective long elements.
// Compare vector<long> as if they were vector<int> and assign the result to a temp
@@ -755,7 +768,7 @@ SIMDIntrinsicID Compiler::impSIMDLongRelOpEqual(CORINFO_CLASS_HANDLE typeHnd,
// op2 = Shuffle(tmp, 0xB1)
// IntrinsicId = BitwiseAnd
*pOp1 = gtNewOperNode(GT_COMMA, simdType, asg, tmp);
- *pOp2 = gtNewSIMDNode(simdType, gtNewLclvNode(lclNum, simdType), gtNewIconNode(SHUFFLE_ZWYX, TYP_INT),
+ *pOp2 = gtNewSIMDNode(simdType, gtNewLclvNode(lclNum, simdType), gtNewIconNode(SHUFFLE_ZWXY, TYP_INT),
SIMDIntrinsicShuffleSSE2, TYP_INT, size);
return SIMDIntrinsicBitwiseAnd;
}
@@ -971,7 +984,7 @@ SIMDIntrinsicID Compiler::impSIMDIntegralRelOpGreaterThanOrEqual(
return SIMDIntrinsicBitwiseOr;
}
-#endif //_TARGET_AMD64_
+#endif // _TARGET_XARCH_
// Transforms operands and returns the SIMD intrinsic to be applied on
// transformed operands to obtain given relop result.
@@ -999,7 +1012,7 @@ SIMDIntrinsicID Compiler::impSIMDRelOp(SIMDIntrinsicID relOpIntrinsicId,
assert(isRelOpSIMDIntrinsic(relOpIntrinsicId));
-#ifdef _TARGET_AMD64_
+#ifdef _TARGET_XARCH_
SIMDIntrinsicID intrinsicID = relOpIntrinsicId;
var_types baseType = *inOutBaseType;
@@ -1076,7 +1089,7 @@ SIMDIntrinsicID Compiler::impSIMDRelOp(SIMDIntrinsicID relOpIntrinsicId,
//
// We need to treat op1 and op2 as signed for comparison purpose after
// the transformation.
- ssize_t constVal = 0;
+ __int64 constVal = 0;
switch (baseType)
{
case TYP_UBYTE:
@@ -1105,9 +1118,19 @@ SIMDIntrinsicID Compiler::impSIMDRelOp(SIMDIntrinsicID relOpIntrinsicId,
if (intrinsicID != SIMDIntrinsicEqual)
{
// For constructing const vector use either long or int base type.
- var_types tempBaseType = (baseType == TYP_ULONG) ? TYP_LONG : TYP_INT;
- GenTree* initVal = gtNewIconNode(constVal);
- initVal->gtType = tempBaseType;
+ var_types tempBaseType;
+ GenTree* initVal;
+ if (baseType == TYP_ULONG)
+ {
+ tempBaseType = TYP_LONG;
+ initVal = gtNewLconNode(constVal);
+ }
+ else
+ {
+ tempBaseType = TYP_INT;
+ initVal = gtNewIconNode((ssize_t)constVal);
+ }
+ initVal->gtType = tempBaseType;
GenTree* constVector = gtNewSIMDNode(simdType, initVal, nullptr, SIMDIntrinsicInit, tempBaseType, size);
// Assign constVector to a temp, since we intend to use it more than once
@@ -1127,10 +1150,10 @@ SIMDIntrinsicID Compiler::impSIMDRelOp(SIMDIntrinsicID relOpIntrinsicId,
}
return intrinsicID;
-#else
+#else // !_TARGET_XARCH_
assert(!"impSIMDRelOp() unimplemented on target arch");
unreached();
-#endif //_TARGET_AMD64_
+#endif // !_TARGET_XARCH_
}
// Creates a GT_SIMD tree for Select operation
@@ -1210,7 +1233,7 @@ GenTreePtr Compiler::impSIMDMinMax(SIMDIntrinsicID intrinsicId,
var_types simdType = op1->TypeGet();
assert(op2->TypeGet() == simdType);
-#ifdef _TARGET_AMD64_
+#ifdef _TARGET_XARCH_
// SSE2 has direct support for float/double/signed word/unsigned byte.
// For other integer types we compute min/max as follows
//
@@ -1347,10 +1370,10 @@ GenTreePtr Compiler::impSIMDMinMax(SIMDIntrinsicID intrinsicId,
assert(simdTree != nullptr);
return simdTree;
-#else
+#else // !_TARGET_XARCH_
assert(!"impSIMDMinMax() unimplemented on target arch");
unreached();
-#endif //_TARGET_AMD64_
+#endif // !_TARGET_XARCH_
}
//------------------------------------------------------------------------
@@ -1791,6 +1814,8 @@ GenTreePtr Compiler::impSIMDIntrinsic(OPCODE opcode,
int length = getSIMDVectorLength(clsHnd);
GenTreeIntCon* intConstTree = new (this, GT_CNS_INT) GenTreeIntCon(TYP_INT, length);
retVal = intConstTree;
+
+ intConstTree->gtFlags |= GTF_ICON_SIMD_COUNT;
}
break;
@@ -2223,7 +2248,11 @@ GenTreePtr Compiler::impSIMDIntrinsic(OPCODE opcode,
assert(op2->TypeGet() == simdType);
simdTree = gtNewSIMDNode(genActualType(callType), op1, op2, SIMDIntrinsicOpEquality, baseType, size);
- retVal = simdTree;
+ if (simdType == TYP_SIMD12)
+ {
+ simdTree->gtFlags |= GTF_SIMD12_OP;
+ }
+ retVal = simdTree;
}
break;
@@ -2234,7 +2263,11 @@ GenTreePtr Compiler::impSIMDIntrinsic(OPCODE opcode,
op2 = impSIMDPopStack(simdType);
op1 = impSIMDPopStack(simdType, instMethod);
simdTree = gtNewSIMDNode(genActualType(callType), op1, op2, SIMDIntrinsicOpInEquality, baseType, size);
- retVal = simdTree;
+ if (simdType == TYP_SIMD12)
+ {
+ simdTree->gtFlags |= GTF_SIMD12_OP;
+ }
+ retVal = simdTree;
}
break;
@@ -2262,7 +2295,7 @@ GenTreePtr Compiler::impSIMDIntrinsic(OPCODE opcode,
case SIMDIntrinsicBitwiseOr:
case SIMDIntrinsicBitwiseXor:
{
-#if defined(_TARGET_AMD64_) && defined(DEBUG)
+#if defined(_TARGET_XARCH_) && defined(DEBUG)
// check for the cases where we don't support intrinsics.
// This check should be done before we make modifications to type stack.
// Note that this is more of a double safety check for robustness since
@@ -2290,7 +2323,7 @@ GenTreePtr Compiler::impSIMDIntrinsic(OPCODE opcode,
return nullptr;
}
}
-#endif //_TARGET_AMD64_ && DEBUG
+#endif // _TARGET_XARCH_ && DEBUG
// op1 is the first operand; if instance method, op1 is "this" arg
// op2 is the second operand
@@ -2331,9 +2364,9 @@ GenTreePtr Compiler::impSIMDIntrinsic(OPCODE opcode,
{
// op1 is a SIMD variable that is "this" arg
// op2 is an index of TYP_INT
- op2 = impSIMDPopStack(TYP_INT);
- op1 = impSIMDPopStack(simdType, instMethod);
- unsigned int vectorLength = getSIMDVectorLength(size, baseType);
+ op2 = impSIMDPopStack(TYP_INT);
+ op1 = impSIMDPopStack(simdType, instMethod);
+ int vectorLength = getSIMDVectorLength(size, baseType);
if (!op2->IsCnsIntOrI() || op2->AsIntCon()->gtIconVal >= vectorLength)
{
// We need to bounds-check the length of the vector.
@@ -2366,15 +2399,15 @@ GenTreePtr Compiler::impSIMDIntrinsic(OPCODE opcode,
case SIMDIntrinsicDotProduct:
{
-#if defined(_TARGET_AMD64_) && defined(DEBUG)
- // Right now dot product is supported only for float vectors.
- // See SIMDIntrinsicList.h for supported base types for this intrinsic.
- if (!varTypeIsFloating(baseType))
+#if defined(_TARGET_XARCH_)
+ // Right now dot product is supported only for float/double vectors and
+ // int vectors on SSE4/AVX.
+ if (!varTypeIsFloating(baseType) &&
+ !(baseType == TYP_INT && getSIMDInstructionSet() >= InstructionSet_SSE3_4))
{
- assert(!"Dot product on integer type vectors not supported");
return nullptr;
}
-#endif //_TARGET_AMD64_ && DEBUG
+#endif // _TARGET_XARCH_
// op1 is a SIMD variable that is the first source and also "this" arg.
// op2 is a SIMD variable which is the second source.
@@ -2382,13 +2415,17 @@ GenTreePtr Compiler::impSIMDIntrinsic(OPCODE opcode,
op1 = impSIMDPopStack(simdType, instMethod);
simdTree = gtNewSIMDNode(baseType, op1, op2, simdIntrinsicID, baseType, size);
- retVal = simdTree;
+ if (simdType == TYP_SIMD12)
+ {
+ simdTree->gtFlags |= GTF_SIMD12_OP;
+ }
+ retVal = simdTree;
}
break;
case SIMDIntrinsicSqrt:
{
-#if defined(_TARGET_AMD64_) && defined(DEBUG)
+#if defined(_TARGET_XARCH_) && defined(DEBUG)
// SSE/AVX doesn't support sqrt on integer type vectors and hence
// should never be seen as an intrinsic here. See SIMDIntrinsicList.h
// for supported base types for this intrinsic.
@@ -2397,7 +2434,7 @@ GenTreePtr Compiler::impSIMDIntrinsic(OPCODE opcode,
assert(!"Sqrt not supported on integer vectors\n");
return nullptr;
}
-#endif // _TARGET_AMD64_ && DEBUG
+#endif // _TARGET_XARCH_ && DEBUG
op1 = impSIMDPopStack(simdType);
@@ -2409,7 +2446,7 @@ GenTreePtr Compiler::impSIMDIntrinsic(OPCODE opcode,
{
op1 = impSIMDPopStack(simdType);
-#ifdef _TARGET_AMD64_
+#ifdef _TARGET_XARCH_
if (varTypeIsFloating(baseType))
{
// Abs(vf) = vf & new SIMDVector<float>(0x7fffffff);
@@ -2448,10 +2485,10 @@ GenTreePtr Compiler::impSIMDIntrinsic(OPCODE opcode,
unreached();
}
-#else //!_TARGET_AMD64_
- assert(!"Abs intrinsic on non-Amd64 target not implemented");
+#else // !_TARGET_XARCH_
+ assert(!"Abs intrinsic on non-xarch target not implemented");
unreached();
-#endif //!_TARGET_AMD64_
+#endif // !_TARGET_XARCH_
}
break;
@@ -2524,15 +2561,15 @@ GenTreePtr Compiler::impSIMDIntrinsic(OPCODE opcode,
return nullptr;
}
-#ifdef _TARGET_AMD64_
- // Amd64: also indicate that we use floating point registers.
+#ifdef _TARGET_XARCH_
+ // XArch: also indicate that we use floating point registers.
// The need for setting this here is that a method may not have SIMD
// type lclvars, but might be exercising SIMD intrinsics on fields of
// SIMD type.
//
// e.g. public Vector<float> ComplexVecFloat::sqabs() { return this.r * this.r + this.i * this.i; }
compFloatingPointUsed = true;
-#endif
+#endif // _TARGET_XARCH_
// At this point, we have a tree that we are going to store into a destination.
// TODO-1stClassStructs: This should be a simple store or assignment, and should not require
diff --git a/src/jit/simd.h b/src/jit/simd.h
index c68899e412..c4a8866b07 100644
--- a/src/jit/simd.h
+++ b/src/jit/simd.h
@@ -29,13 +29,18 @@ struct SIMDIntrinsicInfo
var_types supportedBaseTypes[SIMD_INTRINSIC_MAX_BASETYPE_COUNT];
};
-#ifdef _TARGET_AMD64_
+#ifdef _TARGET_XARCH_
// SSE2 Shuffle control byte to shuffle vector <W, Z, Y, X>
// These correspond to shuffle immediate byte in shufps SSE2 instruction.
-#define SHUFFLE_XXXX 0x00
-#define SHUFFLE_ZWYX 0xB1
-#define SHUFFLE_WWYY 0xF5
-#define SHUFFLE_ZZXX 0xA0
+#define SHUFFLE_XXXX 0x00 // 00 00 00 00
+#define SHUFFLE_XXWW 0x0F // 00 00 11 11
+#define SHUFFLE_XYZW 0x1B // 00 01 10 11
+#define SHUFFLE_YXYX 0x44 // 01 00 01 00
+#define SHUFFLE_YYZZ 0x5A // 01 01 10 10
+#define SHUFFLE_ZXXY 0x81 // 10 00 00 01
+#define SHUFFLE_ZWXY 0xB1 // 10 11 00 01
+#define SHUFFLE_WWYY 0xF5 // 11 11 01 01
+#define SHUFFLE_ZZXX 0xA0 // 10 10 00 00
#endif
#endif // FEATURE_SIMD
diff --git a/src/jit/simdcodegenxarch.cpp b/src/jit/simdcodegenxarch.cpp
index 702f967aad..ec933fd5d7 100644
--- a/src/jit/simdcodegenxarch.cpp
+++ b/src/jit/simdcodegenxarch.cpp
@@ -17,7 +17,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#ifndef LEGACY_BACKEND // This file is ONLY used for the RyuJIT backend that uses the linear scan register allocator.
-#ifdef _TARGET_AMD64_
+#ifdef _TARGET_XARCH_
#include "emit.h"
#include "codegen.h"
#include "sideeffects.h"
@@ -62,7 +62,7 @@ instruction CodeGen::getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_type
// AVX supports broadcast instructions to populate YMM reg with a single float/double value from memory.
// AVX2 supports broadcast instructions to populate YMM reg with a single value from memory or mm reg.
// If we decide to use AVX2 only, we can remove this assert.
- if ((compiler->opts.eeFlags & CORJIT_FLG_USE_AVX2) == 0)
+ if (!compiler->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_USE_AVX2))
{
assert(baseType == TYP_FLOAT || baseType == TYP_DOUBLE);
}
@@ -205,12 +205,9 @@ instruction CodeGen::getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_type
{
result = INS_pmullw;
}
- else if (compiler->canUseAVX())
+ else if ((baseType == TYP_INT) && (compiler->getSIMDInstructionSet() >= InstructionSet_SSE3_4))
{
- if (baseType == TYP_INT)
- {
- result = INS_pmulld;
- }
+ result = INS_pmulld;
}
break;
@@ -300,7 +297,8 @@ instruction CodeGen::getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_type
{
result = INS_pcmpeqb;
}
- else if (compiler->canUseAVX() && (baseType == TYP_ULONG || baseType == TYP_LONG))
+ else if ((baseType == TYP_ULONG || baseType == TYP_LONG) &&
+ (compiler->getSIMDInstructionSet() >= InstructionSet_SSE3_4))
{
result = INS_pcmpeqq;
}
@@ -359,7 +357,7 @@ instruction CodeGen::getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_type
{
result = INS_pcmpgtb;
}
- else if (compiler->canUseAVX() && (baseType == TYP_LONG))
+ else if ((baseType == TYP_LONG) && (compiler->getSIMDInstructionSet() >= InstructionSet_SSE3_4))
{
result = INS_pcmpgtq;
}
@@ -464,7 +462,8 @@ instruction CodeGen::getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_type
// to target mm reg, zeroing out the upper bits if and only if specified.
//
// Arguments:
-// type the type of value to be moved
+// targetType the target type
+// baseType the base type of value to be moved
// targetReg the target reg
// srcReg the src reg
// moveType action to be performed on target upper bits
@@ -475,10 +474,10 @@ instruction CodeGen::getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_type
// Notes:
// This is currently only supported for floating point types.
//
-void CodeGen::genSIMDScalarMove(var_types type, regNumber targetReg, regNumber srcReg, SIMDScalarMoveType moveType)
+void CodeGen::genSIMDScalarMove(
+ var_types targetType, var_types baseType, regNumber targetReg, regNumber srcReg, SIMDScalarMoveType moveType)
{
- var_types targetType = compiler->getSIMDVectorType();
- assert(varTypeIsFloating(type));
+ assert(varTypeIsFloating(baseType));
#ifdef FEATURE_AVX_SUPPORT
if (compiler->getSIMDInstructionSet() == InstructionSet_AVX)
{
@@ -487,17 +486,17 @@ void CodeGen::genSIMDScalarMove(var_types type, regNumber targetReg, regNumber s
case SMT_PreserveUpper:
if (srcReg != targetReg)
{
- instruction ins = ins_Store(type);
+ instruction ins = ins_Store(baseType);
if (getEmitter()->IsThreeOperandMoveAVXInstruction(ins))
{
// In general, when we use a three-operands move instruction, we want to merge the src with
// itself. This is an exception in that we actually want the "merge" behavior, so we must
// specify it with all 3 operands.
- inst_RV_RV_RV(ins, targetReg, targetReg, srcReg, emitTypeSize(targetType));
+ inst_RV_RV_RV(ins, targetReg, targetReg, srcReg, emitTypeSize(baseType));
}
else
{
- inst_RV_RV(ins, targetReg, srcReg, targetType, emitTypeSize(targetType));
+ inst_RV_RV(ins, targetReg, srcReg, baseType, emitTypeSize(baseType));
}
}
break;
@@ -516,9 +515,9 @@ void CodeGen::genSIMDScalarMove(var_types type, regNumber targetReg, regNumber s
case SMT_ZeroInitUpper_SrcHasUpperZeros:
if (srcReg != targetReg)
{
- instruction ins = ins_Copy(type);
+ instruction ins = ins_Copy(baseType);
assert(!getEmitter()->IsThreeOperandMoveAVXInstruction(ins));
- inst_RV_RV(ins, targetReg, srcReg, targetType, emitTypeSize(targetType));
+ inst_RV_RV(ins, targetReg, srcReg, baseType, emitTypeSize(baseType));
}
break;
@@ -536,7 +535,7 @@ void CodeGen::genSIMDScalarMove(var_types type, regNumber targetReg, regNumber s
case SMT_PreserveUpper:
if (srcReg != targetReg)
{
- inst_RV_RV(ins_Store(type), targetReg, srcReg, targetType, emitTypeSize(targetType));
+ inst_RV_RV(ins_Store(baseType), targetReg, srcReg, baseType, emitTypeSize(baseType));
}
break;
@@ -545,22 +544,22 @@ void CodeGen::genSIMDScalarMove(var_types type, regNumber targetReg, regNumber s
{
// There is no guarantee that upper bits of op1Reg are zero.
// We achieve this by using left logical shift 12-bytes and right logical shift 12 bytes.
- instruction ins = getOpForSIMDIntrinsic(SIMDIntrinsicShiftLeftInternal, type);
+ instruction ins = getOpForSIMDIntrinsic(SIMDIntrinsicShiftLeftInternal, baseType);
getEmitter()->emitIns_R_I(ins, EA_16BYTE, srcReg, 12);
- ins = getOpForSIMDIntrinsic(SIMDIntrinsicShiftRightInternal, type);
+ ins = getOpForSIMDIntrinsic(SIMDIntrinsicShiftRightInternal, baseType);
getEmitter()->emitIns_R_I(ins, EA_16BYTE, srcReg, 12);
}
else
{
genSIMDZero(targetType, TYP_FLOAT, targetReg);
- inst_RV_RV(ins_Store(type), targetReg, srcReg);
+ inst_RV_RV(ins_Store(baseType), targetReg, srcReg);
}
break;
case SMT_ZeroInitUpper_SrcHasUpperZeros:
if (srcReg != targetReg)
{
- inst_RV_RV(ins_Copy(type), targetReg, srcReg, targetType, emitTypeSize(targetType));
+ inst_RV_RV(ins_Copy(baseType), targetReg, srcReg, baseType, emitTypeSize(baseType));
}
break;
@@ -676,7 +675,7 @@ void CodeGen::genSIMDIntrinsicInit(GenTreeSIMD* simdNode)
SIMDScalarMoveType moveType =
op1->IsCnsFltOrDbl() || op1->isMemoryOp() ? SMT_ZeroInitUpper_SrcHasUpperZeros : SMT_ZeroInitUpper;
- genSIMDScalarMove(TYP_FLOAT, targetReg, op1Reg, moveType);
+ genSIMDScalarMove(targetType, TYP_FLOAT, targetReg, op1Reg, moveType);
if (size == 8)
{
@@ -786,7 +785,7 @@ void CodeGen::genSIMDIntrinsicInitN(GenTreeSIMD* simdNode)
{
getEmitter()->emitIns_R_I(insLeftShift, EA_16BYTE, vectorReg, baseTypeSize);
}
- genSIMDScalarMove(baseType, vectorReg, operandReg, SMT_PreserveUpper);
+ genSIMDScalarMove(targetType, baseType, vectorReg, operandReg, SMT_PreserveUpper);
offset += baseTypeSize;
}
@@ -1033,11 +1032,10 @@ void CodeGen::genSIMDIntrinsicBinOp(GenTreeSIMD* simdNode)
//
void CodeGen::genSIMDIntrinsicRelOp(GenTreeSIMD* simdNode)
{
- GenTree* op1 = simdNode->gtGetOp1();
- GenTree* op2 = simdNode->gtGetOp2();
- var_types baseType = simdNode->gtSIMDBaseType;
- regNumber targetReg = simdNode->gtRegNum;
- assert(targetReg != REG_NA);
+ GenTree* op1 = simdNode->gtGetOp1();
+ GenTree* op2 = simdNode->gtGetOp2();
+ var_types baseType = simdNode->gtSIMDBaseType;
+ regNumber targetReg = simdNode->gtRegNum;
var_types targetType = simdNode->TypeGet();
InstructionSet iset = compiler->getSIMDInstructionSet();
@@ -1051,8 +1049,16 @@ void CodeGen::genSIMDIntrinsicRelOp(GenTreeSIMD* simdNode)
case SIMDIntrinsicEqual:
case SIMDIntrinsicGreaterThan:
{
- // SSE2: vector<(u)long> relation op should be implemented in terms of TYP_INT comparison operations
- assert(((iset == InstructionSet_AVX) || (baseType != TYP_LONG)) && (baseType != TYP_ULONG));
+ assert(targetReg != REG_NA);
+
+#ifdef DEBUG
+ // SSE2: vector<(u)long> relational op should be implemented in terms of
+ // TYP_INT comparison operations
+ if (baseType == TYP_LONG || baseType == TYP_ULONG)
+ {
+ assert(iset >= InstructionSet_SSE3_4);
+ }
+#endif
// Greater-than: Floating point vectors use "<" with swapped operands
if (simdNode->gtSIMDIntrinsicID == SIMDIntrinsicGreaterThan)
@@ -1093,6 +1099,8 @@ void CodeGen::genSIMDIntrinsicRelOp(GenTreeSIMD* simdNode)
case SIMDIntrinsicLessThan:
case SIMDIntrinsicLessThanOrEqual:
{
+ assert(targetReg != REG_NA);
+
// Int vectors use ">" and ">=" with swapped operands
assert(varTypeIsFloating(baseType));
@@ -1115,17 +1123,6 @@ void CodeGen::genSIMDIntrinsicRelOp(GenTreeSIMD* simdNode)
case SIMDIntrinsicOpEquality:
case SIMDIntrinsicOpInEquality:
{
- assert(genIsValidIntReg(targetReg));
-
- // We need two additional XMM register as scratch
- assert(simdNode->gtRsvdRegs != RBM_NONE);
- assert(genCountBits(simdNode->gtRsvdRegs) == 2);
-
- regMaskTP tmpRegsMask = simdNode->gtRsvdRegs;
- regMaskTP tmpReg1Mask = genFindLowestBit(tmpRegsMask);
- tmpRegsMask &= ~tmpReg1Mask;
- regNumber tmpReg1 = genRegNumFromMask(tmpReg1Mask);
- regNumber tmpReg2 = genRegNumFromMask(tmpRegsMask);
var_types simdType = op1->TypeGet();
// TODO-1stClassStructs: Temporary to minimize asmDiffs
if (simdType == TYP_DOUBLE)
@@ -1140,96 +1137,111 @@ void CodeGen::genSIMDIntrinsicRelOp(GenTreeSIMD* simdNode)
simdType = TYP_SIMD16;
}
- // tmpReg1 = (op1Reg == op2Reg)
- // Call this value of tmpReg1 as 'compResult' for further reference below.
- regNumber otherReg = op2Reg;
- if (tmpReg1 != op2Reg)
+ // On SSE4/AVX, we can generate optimal code for (in)equality against zero using ptest.
+ if ((compiler->getSIMDInstructionSet() >= InstructionSet_SSE3_4) && op2->IsIntegralConstVector(0))
{
- if (tmpReg1 != op1Reg)
- {
- inst_RV_RV(ins_Copy(simdType), tmpReg1, op1Reg, simdType, emitActualTypeSize(simdType));
- }
+ assert(op2->isContained());
+ inst_RV_RV(INS_ptest, op1->gtRegNum, op1->gtRegNum, simdType, emitActualTypeSize(simdType));
}
else
{
- otherReg = op1Reg;
- }
+ // We need one additional SIMD register to store the result of the SIMD compare.
+ regNumber tmpReg1 = genRegNumFromMask(simdNode->gtRsvdRegs & RBM_ALLFLOAT);
- // For all integer types we can use TYP_INT comparison.
- unsigned ival = 0;
- instruction ins =
- getOpForSIMDIntrinsic(SIMDIntrinsicEqual, varTypeIsFloating(baseType) ? baseType : TYP_INT, &ival);
+ // tmpReg1 = (op1Reg == op2Reg)
+ // Call this value of tmpReg1 as 'compResult' for further reference below.
+ regNumber otherReg = op2Reg;
+ if (tmpReg1 != op2Reg)
+ {
+ if (tmpReg1 != op1Reg)
+ {
+ inst_RV_RV(ins_Copy(simdType), tmpReg1, op1Reg, simdType, emitActualTypeSize(simdType));
+ }
+ }
+ else
+ {
+ otherReg = op1Reg;
+ }
- if (varTypeIsFloating(baseType))
- {
- getEmitter()->emitIns_R_R_I(ins, emitActualTypeSize(simdType), tmpReg1, otherReg, ival);
- }
- else
- {
- inst_RV_RV(ins, tmpReg1, otherReg, simdType, emitActualTypeSize(simdType));
+ // For all integer types we can use TYP_INT comparison.
+ unsigned ival = 0;
+ instruction ins =
+ getOpForSIMDIntrinsic(SIMDIntrinsicEqual, varTypeIsFloating(baseType) ? baseType : TYP_INT, &ival);
+
+ if (varTypeIsFloating(baseType))
+ {
+ getEmitter()->emitIns_R_R_I(ins, emitActualTypeSize(simdType), tmpReg1, otherReg, ival);
+ }
+ else
+ {
+ inst_RV_RV(ins, tmpReg1, otherReg, simdType, emitActualTypeSize(simdType));
+ }
+
+ regNumber intReg;
+ if (targetReg == REG_NA)
+ {
+ // If we are not materializing result into a register,
+ // we would have reserved an int type internal register.
+ intReg = genRegNumFromMask(simdNode->gtRsvdRegs & RBM_ALLINT);
+ }
+ else
+ {
+ // We can use targetReg for setting flags.
+ intReg = targetReg;
+
+ // Must have not reserved any int type internal registers.
+ assert(genCountBits(simdNode->gtRsvdRegs & RBM_ALLINT) == 0);
+ }
+
+ inst_RV_RV(INS_pmovmskb, intReg, tmpReg1, simdType, emitActualTypeSize(simdType));
+ // There's no pmovmskw/pmovmskd/pmovmskq but they're not needed anyway. Vector compare
+ // instructions produce "all ones"/"all zeroes" components and pmovmskb extracts a
+ // subset of each component's ones/zeroes. In the end we need to know if the result is
+ // "all ones" where the number of ones is given by the vector byte size, not by the
+ // vector component count. So, for AVX registers we need to compare to 0xFFFFFFFF and
+ // for SSE registers we need to compare to 0x0000FFFF.
+ // The SIMD12 case is handled specially, because we can't rely on the upper bytes being
+ // zero, so we must compare only the lower 3 floats (hence the byte mask of 0xFFF).
+ // Note that -1 is used instead of 0xFFFFFFFF, on x64 emit doesn't correctly recognize
+ // that 0xFFFFFFFF can be encoded in a single byte and emits the longer 3DFFFFFFFF
+ // encoding instead of 83F8FF.
+ ssize_t mask;
+ if ((simdNode->gtFlags & GTF_SIMD12_OP) != 0)
+ {
+ mask = 0x00000FFF;
+ getEmitter()->emitIns_R_I(INS_and, EA_4BYTE, intReg, mask);
+ }
+ else if (emitActualTypeSize(simdType) == 32)
+ {
+ mask = -1;
+ }
+ else
+ {
+ mask = 0x0000FFFF;
+ }
+ getEmitter()->emitIns_R_I(INS_cmp, EA_4BYTE, intReg, mask);
}
- // If we have 32 bytes, start by anding the two 16-byte halves to get a 16-byte result.
- if (compiler->canUseAVX() && (simdType == TYP_SIMD32))
+ if (targetReg != REG_NA)
{
- // Reduce tmpReg1 from 256-bits to 128-bits bitwise-Anding the lower and uppper 128-bits
+ // If we need to materialize result into a register, targetReg needs to
+ // be set to 1 on true and zero on false.
+ // Equality:
+ // cmp targetReg, 0xFFFFFFFF or 0xFFFF
+ // sete targetReg
+ // movzx targetReg, targetReg
//
- // Generated code sequence
- // - vextractf128 tmpReg2, tmpReg1, 0x01
- // tmpReg2[128..255] <- 0
- // tmpReg2[0..127] <- tmpReg1[128..255]
- // - vandps tmpReg1, tempReg2
- // This will zero-out upper portion of tmpReg1 and
- // lower portion of tmpReg1 is and of upper and lower 128-bit comparison result.
- getEmitter()->emitIns_R_R_I(INS_vextractf128, EA_32BYTE, tmpReg2, tmpReg1, 0x01);
- inst_RV_RV(INS_andps, tmpReg1, tmpReg2, simdType, emitActualTypeSize(simdType));
- }
- // Next, if we have more than 8 bytes, and the two 8-byte halves to get a 8-byte result.
- if (simdType != TYP_SIMD8)
- {
- // tmpReg2 = Shuffle(tmpReg1, (1,0,3,2))
- // Note: vpshufd is a 128-bit only instruction. Therefore, explicitly pass EA_16BYTE
- getEmitter()->emitIns_R_R_I(INS_pshufd, EA_16BYTE, tmpReg2, tmpReg1, 0x4E);
-
- // tmpReg1 = BitwiseAnd(tmpReg1, tmpReg2)
+ // InEquality:
+ // cmp targetReg, 0xFFFFFFFF or 0xFFFF
+ // setne targetReg
+ // movzx targetReg, targetReg
//
- // Note that what we have computed is as follows at this point:
- // tmpReg1[0] = compResult[0] & compResult[2]
- // tmpReg1[1] = compResult[1] & compResult[3]
- inst_RV_RV(INS_andps, tmpReg1, tmpReg2, simdType, emitActualTypeSize(simdType));
+ assert(simdNode->TypeGet() == TYP_INT);
+ inst_RV((simdNode->gtSIMDIntrinsicID == SIMDIntrinsicOpEquality) ? INS_sete : INS_setne, targetReg,
+ TYP_INT, EA_1BYTE);
+ // Set the higher bytes to 0
+ inst_RV_RV(ins_Move_Extend(TYP_UBYTE, true), targetReg, targetReg, TYP_UBYTE, emitTypeSize(TYP_UBYTE));
}
- // At this point, we have either reduced the result to 8 bytes: tmpReg1[0] and tmpReg1[1],
- // OR we have a Vector2 (TYP_SIMD8) in tmpReg1, which has only those two fields.
-
- // tmpReg2 = Shuffle(tmpReg1, (0,0,0,1))
- // tmpReg2[0] = compResult[1] & compResult[3]
- getEmitter()->emitIns_R_R_I(INS_pshufd, EA_16BYTE, tmpReg2, tmpReg1, 0x1);
-
- // tmpReg1 = BitwiseAnd(tmpReg1, tmpReg2)
- // That is tmpReg1[0] = compResult[0] & compResult[1] & compResult[2] & compResult[3]
- inst_RV_RV(INS_pand, tmpReg1, tmpReg2, simdType, emitActualTypeSize(simdType)); // ??? INS_andps??
-
- // targetReg = lower 32-bits of tmpReg1 = compResult[0] & compResult[1] & compResult[2] & compResult[3]
- // (Note that for mov_xmm2i, the int register is always in the reg2 position.
- inst_RV_RV(INS_mov_xmm2i, tmpReg1, targetReg, TYP_INT);
-
- // Since we need to compute a bool result, targetReg needs to be set to 1 on true and zero on false.
- // Equality:
- // cmp targetReg, 0xFFFFFFFF
- // sete targetReg
- // movzx targetReg, targetReg
- //
- // InEquality:
- // cmp targetReg, 0xFFFFFFFF
- // setne targetReg
- // movzx targetReg, targetReg
- //
- getEmitter()->emitIns_R_I(INS_cmp, EA_4BYTE, targetReg, 0xFFFFFFFF);
- inst_RV((simdNode->gtSIMDIntrinsicID == SIMDIntrinsicOpEquality) ? INS_sete : INS_setne, targetReg, TYP_INT,
- EA_1BYTE);
- assert(simdNode->TypeGet() == TYP_INT);
- // Set the higher bytes to 0
- inst_RV_RV(ins_Move_Extend(TYP_UBYTE, true), targetReg, targetReg, TYP_UBYTE, emitTypeSize(TYP_UBYTE));
}
break;
@@ -1267,45 +1279,68 @@ void CodeGen::genSIMDIntrinsicDotProduct(GenTreeSIMD* simdNode)
regNumber targetReg = simdNode->gtRegNum;
assert(targetReg != REG_NA);
- // DotProduct is only supported on floating point types.
var_types targetType = simdNode->TypeGet();
assert(targetType == baseType);
- assert(varTypeIsFloating(baseType));
genConsumeOperands(simdNode);
- regNumber op1Reg = op1->gtRegNum;
- regNumber op2Reg = op2->gtRegNum;
+ regNumber op1Reg = op1->gtRegNum;
+ regNumber op2Reg = op2->gtRegNum;
+ regNumber tmpReg1 = REG_NA;
+ regNumber tmpReg2 = REG_NA;
- regNumber tmpReg = REG_NA;
- // For SSE, or AVX with 32-byte vectors, we need an additional Xmm register as scratch.
- // However, it must be distinct from targetReg, so we request two from the register allocator.
- // Note that if this is a TYP_SIMD16 or smaller on AVX, then we don't need a tmpReg.
- if ((compiler->getSIMDInstructionSet() == InstructionSet_SSE2) || (simdEvalType == TYP_SIMD32))
+ InstructionSet iset = compiler->getSIMDInstructionSet();
+
+ // Dot product intrinsic is supported only on float/double vectors
+ // and 32-byte int vectors on AVX.
+ //
+ // Float/Double Vectors:
+ // For SSE, or AVX with 32-byte vectors, we need one additional Xmm register
+ // different from targetReg as scratch. Note that if this is a TYP_SIMD16 or
+ // smaller on AVX, then we don't need a tmpReg.
+ //
+ // 32-byte integer vector on AVX: we need two additional Xmm registers
+ // different from targetReg as scratch.
+ //
+ // 16-byte integer vector on SSE4: we need one additional Xmm register
+ // different from targetReg as scratch.
+ if (varTypeIsFloating(baseType))
{
- assert(simdNode->gtRsvdRegs != RBM_NONE);
- assert(genCountBits(simdNode->gtRsvdRegs) == 2);
+ if ((compiler->getSIMDInstructionSet() == InstructionSet_SSE2) || (simdEvalType == TYP_SIMD32))
+ {
+ assert(simdNode->gtRsvdRegs != RBM_NONE);
+ assert(genCountBits(simdNode->gtRsvdRegs) == 1);
- regMaskTP tmpRegsMask = simdNode->gtRsvdRegs;
- regMaskTP tmpReg1Mask = genFindLowestBit(tmpRegsMask);
- tmpRegsMask &= ~tmpReg1Mask;
- regNumber tmpReg1 = genRegNumFromMask(tmpReg1Mask);
- regNumber tmpReg2 = genRegNumFromMask(tmpRegsMask);
+ tmpReg1 = genRegNumFromMask(simdNode->gtRsvdRegs);
+ assert(tmpReg1 != REG_NA);
+ assert(tmpReg1 != targetReg);
+ }
+ else
+ {
+ assert(simdNode->gtRsvdRegs == RBM_NONE);
+ }
+ }
+ else
+ {
+ assert(baseType == TYP_INT);
+ assert(iset >= InstructionSet_SSE3_4);
- // Choose any register different from targetReg as tmpReg
- if (tmpReg1 != targetReg)
+ if (iset == InstructionSet_SSE3_4)
{
- tmpReg = tmpReg1;
+ // Must have reserved 1 scratch register.
+ assert(genCountBits(simdNode->gtRsvdRegs) == 1);
+ tmpReg1 = genRegNumFromMask(simdNode->gtRsvdRegs);
}
else
{
- assert(targetReg != tmpReg2);
- tmpReg = tmpReg2;
+ // Must have reserved 2 scratch registers.
+ assert(genCountBits(simdNode->gtRsvdRegs) == 2);
+ regMaskTP tmpRegMask = genFindLowestBit(simdNode->gtRsvdRegs);
+ tmpReg1 = genRegNumFromMask(tmpRegMask);
+ tmpReg2 = genRegNumFromMask(simdNode->gtRsvdRegs & ~tmpRegMask);
}
- assert(tmpReg != REG_NA);
- assert(tmpReg != targetReg);
}
- if (compiler->getSIMDInstructionSet() == InstructionSet_SSE2)
+ if (iset == InstructionSet_SSE2)
{
// We avoid reg move if either op1Reg == targetReg or op2Reg == targetReg
if (op1Reg == targetReg)
@@ -1323,96 +1358,187 @@ void CodeGen::genSIMDIntrinsicDotProduct(GenTreeSIMD* simdNode)
}
// DotProduct(v1, v2)
- // Here v0 = targetReg, v1 = op1Reg, v2 = op2Reg and tmp = tmpReg
- if (baseType == TYP_FLOAT)
+ // Here v0 = targetReg, v1 = op1Reg, v2 = op2Reg and tmp = tmpReg1
+ if ((simdNode->gtFlags & GTF_SIMD12_OP) != 0)
+ {
+ assert(baseType == TYP_FLOAT);
+ // v0 = v1 * v2
+ // tmp = v0 // v0 = (3, 2, 1, 0) - each element is given by its
+ // // position
+ // tmp = shuffle(tmp, tmp, SHUFFLE_ZXXY) // tmp = (2, 0, 0, 1) - don't really care what's in upper
+ // // bits
+ // v0 = v0 + tmp // v0 = (3+2, 0+2, 1+0, 0+1)
+ // tmp = shuffle(tmp, tmp, SHUFFLE_XXWW) // tmp = ( 1, 1, 2, 2)
+ // v0 = v0 + tmp // v0 = (1+2+3, 0+1+2, 0+1+2, 0+1+2)
+ //
+ inst_RV_RV(INS_mulps, targetReg, op2Reg);
+ inst_RV_RV(INS_movaps, tmpReg1, targetReg);
+ inst_RV_RV_IV(INS_shufps, EA_16BYTE, tmpReg1, tmpReg1, SHUFFLE_ZXXY);
+ inst_RV_RV(INS_addps, targetReg, tmpReg1);
+ inst_RV_RV_IV(INS_shufps, EA_16BYTE, tmpReg1, tmpReg1, SHUFFLE_XXWW);
+ inst_RV_RV(INS_addps, targetReg, tmpReg1);
+ }
+ else if (baseType == TYP_FLOAT)
{
// v0 = v1 * v2
// tmp = v0 // v0 = (3, 2, 1, 0) - each element is given by its
// // position
- // tmp = shuffle(tmp, tmp, Shuffle(2,3,0,1)) // tmp = (2, 3, 0, 1)
+ // tmp = shuffle(tmp, tmp, SHUFFLE_ZWXY) // tmp = (2, 3, 0, 1)
// v0 = v0 + tmp // v0 = (3+2, 2+3, 1+0, 0+1)
// tmp = v0
- // tmp = shuffle(tmp, tmp, Shuffle(0,1,2,3)) // tmp = (0+1, 1+0, 2+3, 3+2)
+ // tmp = shuffle(tmp, tmp, SHUFFLE_XYZW) // tmp = (0+1, 1+0, 2+3, 3+2)
// v0 = v0 + tmp // v0 = (0+1+2+3, 0+1+2+3, 0+1+2+3, 0+1+2+3)
// // Essentially horizontal addtion of all elements.
// // We could achieve the same using SSEv3 instruction
// // HADDPS.
//
inst_RV_RV(INS_mulps, targetReg, op2Reg);
- inst_RV_RV(INS_movaps, tmpReg, targetReg);
- inst_RV_RV_IV(INS_shufps, EA_16BYTE, tmpReg, tmpReg, 0xb1);
- inst_RV_RV(INS_addps, targetReg, tmpReg);
- inst_RV_RV(INS_movaps, tmpReg, targetReg);
- inst_RV_RV_IV(INS_shufps, EA_16BYTE, tmpReg, tmpReg, 0x1b);
- inst_RV_RV(INS_addps, targetReg, tmpReg);
+ inst_RV_RV(INS_movaps, tmpReg1, targetReg);
+ inst_RV_RV_IV(INS_shufps, EA_16BYTE, tmpReg1, tmpReg1, SHUFFLE_ZWXY);
+ inst_RV_RV(INS_addps, targetReg, tmpReg1);
+ inst_RV_RV(INS_movaps, tmpReg1, targetReg);
+ inst_RV_RV_IV(INS_shufps, EA_16BYTE, tmpReg1, tmpReg1, SHUFFLE_XYZW);
+ inst_RV_RV(INS_addps, targetReg, tmpReg1);
}
- else if (baseType == TYP_DOUBLE)
+ else
{
+ assert(baseType == TYP_DOUBLE);
+
// v0 = v1 * v2
// tmp = v0 // v0 = (1, 0) - each element is given by its position
// tmp = shuffle(tmp, tmp, Shuffle(0,1)) // tmp = (0, 1)
// v0 = v0 + tmp // v0 = (1+0, 0+1)
inst_RV_RV(INS_mulpd, targetReg, op2Reg);
- inst_RV_RV(INS_movaps, tmpReg, targetReg);
- inst_RV_RV_IV(INS_shufpd, EA_16BYTE, tmpReg, tmpReg, 0x01);
- inst_RV_RV(INS_addpd, targetReg, tmpReg);
- }
- else
- {
- unreached();
+ inst_RV_RV(INS_movaps, tmpReg1, targetReg);
+ inst_RV_RV_IV(INS_shufpd, EA_16BYTE, tmpReg1, tmpReg1, 0x01);
+ inst_RV_RV(INS_addpd, targetReg, tmpReg1);
}
}
else
{
- // We avoid reg move if either op1Reg == targetReg or op2Reg == targetReg.
- // Note that this is a duplicate of the code above for SSE, but in the AVX case we can eventually
- // use the 3-op form, so that we can avoid these copies.
- // TODO-CQ: Add inst_RV_RV_RV_IV().
- if (op1Reg == targetReg)
- {
- // Best case
- // nothing to do, we have registers in the right place
- }
- else if (op2Reg == targetReg)
+ assert(iset >= InstructionSet_SSE3_4);
+
+ if (varTypeIsFloating(baseType))
{
- op2Reg = op1Reg;
+ // We avoid reg move if either op1Reg == targetReg or op2Reg == targetReg.
+ // Note that this is a duplicate of the code above for SSE, but in the AVX case we can eventually
+ // use the 3-op form, so that we can avoid these copies.
+ // TODO-CQ: Add inst_RV_RV_RV_IV().
+ if (op1Reg == targetReg)
+ {
+ // Best case
+ // nothing to do, we have registers in the right place
+ }
+ else if (op2Reg == targetReg)
+ {
+ op2Reg = op1Reg;
+ }
+ else
+ {
+ inst_RV_RV(ins_Copy(simdType), targetReg, op1Reg, simdEvalType, emitActualTypeSize(simdType));
+ }
+
+ emitAttr emitSize = emitActualTypeSize(simdEvalType);
+ if (baseType == TYP_FLOAT)
+ {
+ // dpps computes the dot product of the upper & lower halves of the 32-byte register.
+ // Notice that if this is a TYP_SIMD16 or smaller on AVX, then we don't need a tmpReg.
+ unsigned mask = ((simdNode->gtFlags & GTF_SIMD12_OP) != 0) ? 0x71 : 0xf1;
+ inst_RV_RV_IV(INS_dpps, emitSize, targetReg, op2Reg, mask);
+ // dpps computes the dot product of the upper & lower halves of the 32-byte register.
+ // Notice that if this is a TYP_SIMD16 or smaller on AVX, then we don't need a tmpReg.
+ // If this is TYP_SIMD32, we need to combine the lower & upper results.
+ if (simdEvalType == TYP_SIMD32)
+ {
+ getEmitter()->emitIns_R_R_I(INS_vextractf128, EA_32BYTE, tmpReg1, targetReg, 0x01);
+ inst_RV_RV(INS_addps, targetReg, tmpReg1, targetType, emitTypeSize(targetType));
+ }
+ }
+ else if (baseType == TYP_DOUBLE)
+ {
+ if (simdEvalType == TYP_SIMD32)
+ {
+ // targetReg = targetReg * op2Reg
+ // targetReg = vhaddpd(targetReg, targetReg) ; horizontal sum of lower & upper halves
+ // tmpReg = vextractf128(targetReg, 1) ; Moves the upper sum into tempReg
+ // targetReg = targetReg + tmpReg1
+ inst_RV_RV(INS_mulpd, targetReg, op2Reg, simdEvalType, emitActualTypeSize(simdType));
+ inst_RV_RV(INS_haddpd, targetReg, targetReg, simdEvalType, emitActualTypeSize(simdType));
+ getEmitter()->emitIns_R_R_I(INS_vextractf128, EA_32BYTE, tmpReg1, targetReg, 0x01);
+ inst_RV_RV(INS_addpd, targetReg, tmpReg1, targetType, emitTypeSize(targetType));
+ }
+ else
+ {
+ // On AVX, we have no 16-byte vectors of double. Note that, if we did, we could use
+ // dppd directly.
+ assert(iset == InstructionSet_SSE3_4);
+ inst_RV_RV_IV(INS_dppd, emitSize, targetReg, op2Reg, 0x31);
+ }
+ }
}
else
{
- inst_RV_RV(ins_Copy(simdType), targetReg, op1Reg, simdEvalType, emitActualTypeSize(simdType));
- }
+ // Dot product of 32-byte int vector on SSE4/AVX.
+ assert(baseType == TYP_INT);
+ assert(simdEvalType == TYP_SIMD16 || simdEvalType == TYP_SIMD32);
+
+#ifdef DEBUG
+ // SSE4: We need 1 scratch register.
+ // AVX2: We need 2 scratch registers.
+ if (simdEvalType == TYP_SIMD16)
+ {
+ assert(tmpReg1 != REG_NA);
+ }
+ else
+ {
+ assert(tmpReg1 != REG_NA);
+ assert(tmpReg2 != REG_NA);
+ }
+#endif
+
+ // tmpReg1 = op1 * op2
+ if (iset == InstructionSet_AVX)
+ {
+ // On AVX take advantage 3 operand form of pmulld
+ inst_RV_RV_RV(INS_pmulld, tmpReg1, op1Reg, op2Reg, emitTypeSize(simdEvalType));
+ }
+ else
+ {
+ inst_RV_RV(ins_Copy(simdEvalType), tmpReg1, op1Reg, simdEvalType);
+ inst_RV_RV(INS_pmulld, tmpReg1, op2Reg, simdEvalType);
+ }
- emitAttr emitSize = emitActualTypeSize(simdEvalType);
- if (baseType == TYP_FLOAT)
- {
- // dpps computes the dot product of the upper & lower halves of the 32-byte register.
- // Notice that if this is a TYP_SIMD16 or smaller on AVX, then we don't need a tmpReg.
- inst_RV_RV_IV(INS_dpps, emitSize, targetReg, op2Reg, 0xf1);
- // If this is TYP_SIMD32, we need to combine the lower & upper results.
if (simdEvalType == TYP_SIMD32)
{
- getEmitter()->emitIns_R_R_I(INS_vextractf128, EA_32BYTE, tmpReg, targetReg, 0x01);
- inst_RV_RV(INS_addps, targetReg, tmpReg, targetType, emitTypeSize(targetType));
+ // tmpReg2[127..0] = Upper 128-bits of tmpReg1
+ getEmitter()->emitIns_R_R_I(INS_vextractf128, EA_32BYTE, tmpReg2, tmpReg1, 0x01);
+
+ // tmpReg1[127..0] = tmpReg1[127..0] + tmpReg2[127..0]
+ // This will compute
+ // tmpReg1[0] = op1[0]*op2[0] + op1[4]*op2[4]
+ // tmpReg1[1] = op1[1]*op2[1] + op1[5]*op2[5]
+ // tmpReg1[2] = op1[2]*op2[2] + op1[6]*op2[6]
+ // tmpReg1[4] = op1[4]*op2[4] + op1[7]*op2[7]
+ inst_RV_RV(INS_paddd, tmpReg1, tmpReg2, TYP_SIMD16, EA_16BYTE);
}
- }
- else if (baseType == TYP_DOUBLE)
- {
- // On AVX, we have no 16-byte vectors of double. Note that, if we did, we could use
- // dppd directly.
- assert(simdType == TYP_SIMD32);
-
- // targetReg = targetReg * op2Reg
- // targetReg = vhaddpd(targetReg, targetReg) ; horizontal sum of lower & upper halves
- // tmpReg = vextractf128(targetReg, 1) ; Moves the upper sum into tempReg
- // targetReg = targetReg + tmpReg
- inst_RV_RV(INS_mulpd, targetReg, op2Reg, simdEvalType, emitActualTypeSize(simdType));
- inst_RV_RV(INS_haddpd, targetReg, targetReg, simdEvalType, emitActualTypeSize(simdType));
- getEmitter()->emitIns_R_R_I(INS_vextractf128, EA_32BYTE, tmpReg, targetReg, 0x01);
- inst_RV_RV(INS_addpd, targetReg, tmpReg, targetType, emitTypeSize(targetType));
- }
- else
- {
- unreached();
+
+ // This horizontal add will compute
+ //
+ // TYP_SIMD16:
+ // tmpReg1[0] = tmpReg1[2] = op1[0]*op2[0] + op1[1]*op2[1]
+ // tmpReg1[1] = tmpReg1[3] = op1[2]*op2[2] + op1[4]*op2[4]
+ //
+ // TYP_SIMD32:
+ // tmpReg1[0] = tmpReg1[2] = op1[0]*op2[0] + op1[4]*op2[4] + op1[1]*op2[1] + op1[5]*op2[5]
+ // tmpReg1[1] = tmpReg1[3] = op1[2]*op2[2] + op1[6]*op2[6] + op1[4]*op2[4] + op1[7]*op2[7]
+ inst_RV_RV(INS_phaddd, tmpReg1, tmpReg1, TYP_SIMD16, EA_16BYTE);
+
+ // DotProduct(op1, op2) = tmpReg1[0] = tmpReg1[0] + tmpReg1[1]
+ inst_RV_RV(INS_phaddd, tmpReg1, tmpReg1, TYP_SIMD16, EA_16BYTE);
+
+ // TargetReg = integer result from tmpReg1
+ // (Note that for mov_xmm2i, the int register is always in the reg2 position)
+ inst_RV_RV(INS_mov_xmm2i, tmpReg1, targetReg, TYP_INT);
}
}
@@ -1456,6 +1582,59 @@ void CodeGen::genSIMDIntrinsicGetItem(GenTreeSIMD* simdNode)
genConsumeOperands(simdNode);
regNumber srcReg = op1->gtRegNum;
+ // Optimize the case of op1 is in memory and trying to access ith element.
+ if (op1->isMemoryOp())
+ {
+ assert(op1->isContained());
+
+ regNumber baseReg;
+ regNumber indexReg;
+ int offset = 0;
+
+ if (op1->OperGet() == GT_LCL_FLD)
+ {
+ // There are three parts to the total offset here:
+ // {offset of local} + {offset of SIMD Vector field} + {offset of element within SIMD vector}.
+ bool isEBPbased;
+ unsigned varNum = op1->gtLclVarCommon.gtLclNum;
+ offset += compiler->lvaFrameAddress(varNum, &isEBPbased);
+ offset += op1->gtLclFld.gtLclOffs;
+
+ baseReg = (isEBPbased) ? REG_EBP : REG_ESP;
+ }
+ else
+ {
+ // Require GT_IND addr to be not contained.
+ assert(op1->OperGet() == GT_IND);
+
+ GenTree* addr = op1->AsIndir()->Addr();
+ assert(!addr->isContained());
+ baseReg = addr->gtRegNum;
+ }
+
+ if (op2->isContainedIntOrIImmed())
+ {
+ indexReg = REG_NA;
+ offset += (int)op2->AsIntConCommon()->IconValue() * genTypeSize(baseType);
+ }
+ else
+ {
+ indexReg = op2->gtRegNum;
+ assert(genIsValidIntReg(indexReg));
+ }
+
+ // Now, load the desired element.
+ getEmitter()->emitIns_R_ARX(ins_Move_Extend(baseType, false), // Load
+ emitTypeSize(baseType), // Of the vector baseType
+ targetReg, // To targetReg
+ baseReg, // Base Reg
+ indexReg, // Indexed
+ genTypeSize(baseType), // by the size of the baseType
+ offset);
+ genProduceReg(simdNode);
+ return;
+ }
+
// SSE2 doesn't have an instruction to implement this intrinsic if the index is not a constant.
// For the non-constant case, we will use the SIMD temp location to store the vector, and
// the load the desired element.
@@ -1839,26 +2018,9 @@ void CodeGen::genLoadIndTypeSIMD12(GenTree* treeNode)
// Need an addtional Xmm register to read upper 4 bytes, which is different from targetReg
assert(treeNode->gtRsvdRegs != RBM_NONE);
- assert(genCountBits(treeNode->gtRsvdRegs) == 2);
-
- regNumber tmpReg = REG_NA;
- regMaskTP tmpRegsMask = treeNode->gtRsvdRegs;
- regMaskTP tmpReg1Mask = genFindLowestBit(tmpRegsMask);
- tmpRegsMask &= ~tmpReg1Mask;
- regNumber tmpReg1 = genRegNumFromMask(tmpReg1Mask);
- regNumber tmpReg2 = genRegNumFromMask(tmpRegsMask);
+ assert(genCountBits(treeNode->gtRsvdRegs) == 1);
- // Choose any register different from targetReg as tmpReg
- if (tmpReg1 != targetReg)
- {
- tmpReg = tmpReg1;
- }
- else
- {
- assert(targetReg != tmpReg2);
- tmpReg = tmpReg2;
- }
- assert(tmpReg != REG_NA);
+ regNumber tmpReg = genRegNumFromMask(treeNode->gtRsvdRegs);
assert(tmpReg != targetReg);
// Load upper 4 bytes in tmpReg
@@ -1868,7 +2030,7 @@ void CodeGen::genLoadIndTypeSIMD12(GenTree* treeNode)
getEmitter()->emitIns_R_AR(ins_Load(TYP_DOUBLE), EA_8BYTE, targetReg, operandReg, 0);
// combine upper 4 bytes and lower 8 bytes in targetReg
- getEmitter()->emitIns_R_R_I(INS_shufps, emitActualTypeSize(TYP_SIMD16), targetReg, tmpReg, 0x44);
+ getEmitter()->emitIns_R_R_I(INS_shufps, emitActualTypeSize(TYP_SIMD16), targetReg, tmpReg, SHUFFLE_YXYX);
genProduceReg(treeNode);
}
@@ -1912,9 +2074,9 @@ void CodeGen::genStoreLclFldTypeSIMD12(GenTree* treeNode)
}
//-----------------------------------------------------------------------------
-// genLoadLclFldTypeSIMD12: load a TYP_SIMD12 (i.e. Vector3) type field.
-// Since Vector3 is not a hardware supported write size, it is performed
-// as two reads: 8 byte followed by 4-byte.
+// genLoadLclTypeSIMD12: load a TYP_SIMD12 (i.e. Vector3) type field.
+// Since Vector3 is not a hardware supported read size, it is performed
+// as two reads: 4 byte followed by 8 byte.
//
// Arguments:
// treeNode - tree node that is attempting to load TYP_SIMD12 field
@@ -1922,37 +2084,26 @@ void CodeGen::genStoreLclFldTypeSIMD12(GenTree* treeNode)
// Return Value:
// None.
//
-void CodeGen::genLoadLclFldTypeSIMD12(GenTree* treeNode)
+void CodeGen::genLoadLclTypeSIMD12(GenTree* treeNode)
{
- assert(treeNode->OperGet() == GT_LCL_FLD);
+ assert((treeNode->OperGet() == GT_LCL_FLD) || (treeNode->OperGet() == GT_LCL_VAR));
regNumber targetReg = treeNode->gtRegNum;
- unsigned offs = treeNode->gtLclFld.gtLclOffs;
+ unsigned offs = 0;
unsigned varNum = treeNode->gtLclVarCommon.gtLclNum;
assert(varNum < compiler->lvaCount);
- // Need an addtional Xmm register to read upper 4 bytes
- assert(treeNode->gtRsvdRegs != RBM_NONE);
- assert(genCountBits(treeNode->gtRsvdRegs) == 2);
-
- regNumber tmpReg = REG_NA;
- regMaskTP tmpRegsMask = treeNode->gtRsvdRegs;
- regMaskTP tmpReg1Mask = genFindLowestBit(tmpRegsMask);
- tmpRegsMask &= ~tmpReg1Mask;
- regNumber tmpReg1 = genRegNumFromMask(tmpReg1Mask);
- regNumber tmpReg2 = genRegNumFromMask(tmpRegsMask);
-
- // Choose any register different from targetReg as tmpReg
- if (tmpReg1 != targetReg)
+ if (treeNode->OperGet() == GT_LCL_FLD)
{
- tmpReg = tmpReg1;
+ offs = treeNode->gtLclFld.gtLclOffs;
}
- else
- {
- assert(targetReg != tmpReg2);
- tmpReg = tmpReg2;
- }
- assert(tmpReg != REG_NA);
+
+ // Need an additional Xmm register that is different from
+ // targetReg to read upper 4 bytes.
+ assert(treeNode->gtRsvdRegs != RBM_NONE);
+ assert(genCountBits(treeNode->gtRsvdRegs) == 1);
+
+ regNumber tmpReg = genRegNumFromMask(treeNode->gtRsvdRegs);
assert(tmpReg != targetReg);
// Read upper 4 bytes to tmpReg
@@ -1962,11 +2113,54 @@ void CodeGen::genLoadLclFldTypeSIMD12(GenTree* treeNode)
getEmitter()->emitIns_R_S(ins_Move_Extend(TYP_DOUBLE, false), EA_8BYTE, targetReg, varNum, offs);
// combine upper 4 bytes and lower 8 bytes in targetReg
- getEmitter()->emitIns_R_R_I(INS_shufps, emitActualTypeSize(TYP_SIMD16), targetReg, tmpReg, 0x44);
+ getEmitter()->emitIns_R_R_I(INS_shufps, emitActualTypeSize(TYP_SIMD16), targetReg, tmpReg, SHUFFLE_YXYX);
genProduceReg(treeNode);
}
+#ifdef _TARGET_X86_
+
+//-----------------------------------------------------------------------------
+// genPutArgStkSIMD12: store a TYP_SIMD12 (i.e. Vector3) type field.
+// Since Vector3 is not a hardware supported write size, it is performed
+// as two stores: 8 byte followed by 4-byte.
+//
+// Arguments:
+// treeNode - tree node that is attempting to store TYP_SIMD12 field
+//
+// Return Value:
+// None.
+//
+void CodeGen::genPutArgStkSIMD12(GenTree* treeNode)
+{
+ assert(treeNode->OperGet() == GT_PUTARG_STK);
+
+ GenTreePtr op1 = treeNode->gtOp.gtOp1;
+ assert(!op1->isContained());
+ regNumber operandReg = genConsumeReg(op1);
+
+ // Need an addtional Xmm register to extract upper 4 bytes from data.
+ assert(treeNode->gtRsvdRegs != RBM_NONE);
+ assert(genCountBits(treeNode->gtRsvdRegs) == 1);
+ regNumber tmpReg = genRegNumFromMask(treeNode->gtRsvdRegs);
+
+ // Subtract from ESP; create space for argument.
+ // TODO-CQ: use 'push' instead?
+ inst_RV_IV(INS_sub, REG_SPBASE, 12, EA_PTRSIZE);
+ genStackLevel += 12;
+
+ // 8-byte write
+ getEmitter()->emitIns_AR_R(ins_Store(TYP_DOUBLE), EA_8BYTE, operandReg, REG_SPBASE, 0);
+
+ // Extract upper 4-bytes from data
+ getEmitter()->emitIns_R_R_I(INS_pshufd, emitActualTypeSize(TYP_SIMD16), tmpReg, operandReg, 0x02);
+
+ // 4-byte write
+ getEmitter()->emitIns_AR_R(ins_Store(TYP_FLOAT), EA_4BYTE, tmpReg, REG_SPBASE, 8);
+}
+
+#endif // _TARGET_X86_
+
//-----------------------------------------------------------------------------
// genSIMDIntrinsicUpperSave: save the upper half of a TYP_SIMD32 vector to
// the given register, if any, or to memory.
@@ -2139,5 +2333,5 @@ void CodeGen::genSIMDIntrinsic(GenTreeSIMD* simdNode)
}
#endif // FEATURE_SIMD
-#endif //_TARGET_AMD64_
+#endif //_TARGET_XARCH_
#endif // !LEGACY_BACKEND
diff --git a/src/jit/simdintrinsiclist.h b/src/jit/simdintrinsiclist.h
index a44fb9d0a1..c81f7b4bf0 100644
--- a/src/jit/simdintrinsiclist.h
+++ b/src/jit/simdintrinsiclist.h
@@ -20,7 +20,7 @@
e) TODO-Cleanup: when we plumb TYP_SIMD through front-end, replace TYP_STRUCT with TYP_SIMD.
*/
-#ifdef _TARGET_AMD64_
+#ifdef _TARGET_XARCH_
// Max number of parameters that we model in the table for SIMD intrinsic methods.
#define SIMD_INTRINSIC_MAX_MODELED_PARAM_COUNT 3
@@ -111,7 +111,8 @@ SIMD_INTRINSIC("op_BitwiseOr", false, BitwiseOr,
SIMD_INTRINSIC("op_ExclusiveOr", false, BitwiseXor, "^", TYP_STRUCT, 2, {TYP_STRUCT, TYP_STRUCT, TYP_UNDEF}, {TYP_INT, TYP_FLOAT, TYP_DOUBLE, TYP_LONG, TYP_CHAR, TYP_UBYTE, TYP_BYTE, TYP_SHORT, TYP_UINT, TYP_ULONG})
// Dot Product
-SIMD_INTRINSIC("Dot", false, DotProduct, "Dot", TYP_UNKNOWN, 2, {TYP_STRUCT, TYP_STRUCT, TYP_UNDEF}, {TYP_FLOAT, TYP_DOUBLE, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF})
+// Is supported only on Vector<int> on AVX.
+SIMD_INTRINSIC("Dot", false, DotProduct, "Dot", TYP_UNKNOWN, 2, {TYP_STRUCT, TYP_STRUCT, TYP_UNDEF}, {TYP_INT, TYP_FLOAT, TYP_DOUBLE, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF})
// Select
SIMD_INTRINSIC("ConditionalSelect", false, Select, "Select", TYP_STRUCT, 3, {TYP_STRUCT, TYP_STRUCT, TYP_STRUCT}, {TYP_INT, TYP_FLOAT, TYP_DOUBLE, TYP_LONG, TYP_CHAR, TYP_UBYTE, TYP_BYTE, TYP_SHORT, TYP_UINT, TYP_ULONG})
@@ -137,9 +138,9 @@ SIMD_INTRINSIC("UpperRestore", false, UpperRestore,
SIMD_INTRINSIC(nullptr, false, Invalid, "Invalid", TYP_UNDEF, 0, {TYP_UNDEF, TYP_UNDEF, TYP_UNDEF}, {TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF, TYP_UNDEF})
#undef SIMD_INTRINSIC
-#else //_TARGET_AMD64_
+#else //_TARGET_XARCH_
#error SIMD intrinsics not defined for target arch
-#endif //!_TARGET_AMD64_
+#endif //!_TARGET_XARCH_
#endif //FEATURE_SIMD
// clang-format on
diff --git a/src/jit/ssabuilder.cpp b/src/jit/ssabuilder.cpp
index 2da6902464..f0ee461c45 100644
--- a/src/jit/ssabuilder.cpp
+++ b/src/jit/ssabuilder.cpp
@@ -27,87 +27,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
namespace
{
/**
- * Visits basic blocks in the depth first order and arranges them in the order of
- * their DFS finish time.
- *
- * @param block The fgFirstBB or entry block.
- * @param comp A pointer to compiler.
- * @param visited In pointer initialized to false and of size at least fgMaxBBNum.
- * @param count Out pointer for count of all nodes reachable by DFS.
- * @param postOrder Out poitner to arrange the blocks and of size at least fgMaxBBNum.
- */
-static void TopologicalSortHelper(BasicBlock* block, Compiler* comp, bool* visited, int* count, BasicBlock** postOrder)
-{
- visited[block->bbNum] = true;
-
- ArrayStack<BasicBlock*> blocks(comp);
- ArrayStack<AllSuccessorIter> iterators(comp);
- ArrayStack<AllSuccessorIter> ends(comp);
-
- // there are three stacks used here and all should be same height
- // the first is for blocks
- // the second is the iterator to keep track of what succ of the block we are looking at
- // and the third is the end marker iterator
- blocks.Push(block);
- iterators.Push(block->GetAllSuccs(comp).begin());
- ends.Push(block->GetAllSuccs(comp).end());
-
- while (blocks.Height() > 0)
- {
- block = blocks.Top();
-
-#ifdef DEBUG
- if (comp->verboseSsa)
- {
- printf("[SsaBuilder::TopologicalSortHelper] Visiting BB%02u: ", block->bbNum);
- printf("[");
- unsigned numSucc = block->NumSucc(comp);
- for (unsigned i = 0; i < numSucc; ++i)
- {
- printf("BB%02u, ", block->GetSucc(i, comp)->bbNum);
- }
- EHSuccessorIter end = block->GetEHSuccs(comp).end();
- for (EHSuccessorIter ehsi = block->GetEHSuccs(comp).begin(); ehsi != end; ++ehsi)
- {
- printf("[EH]BB%02u, ", (*ehsi)->bbNum);
- }
- printf("]\n");
- }
-#endif
-
- if (iterators.TopRef() != ends.TopRef())
- {
- // if the block on TOS still has unreached successors, visit them
- AllSuccessorIter& iter = iterators.TopRef();
- BasicBlock* succ = *iter;
- ++iter;
- // push the child
-
- if (!visited[succ->bbNum])
- {
- blocks.Push(succ);
- iterators.Push(succ->GetAllSuccs(comp).begin());
- ends.Push(succ->GetAllSuccs(comp).end());
- visited[succ->bbNum] = true;
- }
- }
- else
- {
- // all successors have been visited
- blocks.Pop();
- iterators.Pop();
- ends.Pop();
-
- postOrder[*count] = block;
- block->bbPostOrderNum = *count;
- *count += 1;
-
- DBG_SSA_JITDUMP("postOrder[%d] = [%p] and BB%02u\n", *count, dspPtr(block), block->bbNum);
- }
- }
-}
-
-/**
* Method that finds a common IDom parent, much like least common ancestor.
*
* @param finger1 A basic block that might share IDom ancestor with finger2.
@@ -184,6 +103,8 @@ void Compiler::fgResetForSsa()
{
lvaTable[i].lvPerSsaData.Reset();
}
+ lvHeapPerSsaData.Reset();
+ m_heapSsaMap = nullptr;
for (BasicBlock* blk = fgFirstBB; blk != nullptr; blk = blk->bbNext)
{
// Eliminate phis.
@@ -197,6 +118,32 @@ void Compiler::fgResetForSsa()
blk->bbTreeList->gtPrev = last;
}
}
+
+ // Clear post-order numbers and SSA numbers; SSA construction will overwrite these,
+ // but only for reachable code, so clear them to avoid analysis getting confused
+ // by stale annotations in unreachable code.
+ blk->bbPostOrderNum = 0;
+ for (GenTreeStmt* stmt = blk->firstStmt(); stmt != nullptr; stmt = stmt->getNextStmt())
+ {
+ for (GenTreePtr tree = stmt->gtStmt.gtStmtList; tree != nullptr; tree = tree->gtNext)
+ {
+ if (tree->IsLocal())
+ {
+ tree->gtLclVarCommon.SetSsaNum(SsaConfig::RESERVED_SSA_NUM);
+ continue;
+ }
+
+ Compiler::IndirectAssignmentAnnotation* pIndirAssign = nullptr;
+ if ((tree->OperGet() != GT_ASG) || !GetIndirAssignMap()->Lookup(tree, &pIndirAssign) ||
+ (pIndirAssign == nullptr))
+ {
+ continue;
+ }
+
+ pIndirAssign->m_defSsaNum = SsaConfig::RESERVED_SSA_NUM;
+ pIndirAssign->m_useSsaNum = SsaConfig::RESERVED_SSA_NUM;
+ }
+ }
}
}
@@ -222,27 +169,97 @@ SsaBuilder::SsaBuilder(Compiler* pCompiler, IAllocator* pIAllocator)
{
}
-/**
- * Topologically sort the graph and return the number of nodes visited.
- *
- * @param postOrder The array in which the arranged basic blocks have to be returned.
- * @param count The size of the postOrder array.
- *
- * @return The number of nodes visited while performing DFS on the graph.
- */
+//------------------------------------------------------------------------
+// TopologicalSort: Topologically sort the graph and return the number of nodes visited.
+//
+// Arguments:
+// postOrder - The array in which the arranged basic blocks have to be returned.
+// count - The size of the postOrder array.
+//
+// Return Value:
+// The number of nodes visited while performing DFS on the graph.
+
int SsaBuilder::TopologicalSort(BasicBlock** postOrder, int count)
{
- // Allocate and initialize visited flags.
- bool* visited = (bool*)alloca(count * sizeof(bool));
- memset(visited, 0, count * sizeof(bool));
+ Compiler* comp = m_pCompiler;
+
+ BitVecTraits traits(comp->fgBBNumMax + 1, comp);
+ BitVec BITVEC_INIT_NOCOPY(visited, BitVecOps::MakeEmpty(&traits));
// Display basic blocks.
- DBEXEC(VERBOSE, m_pCompiler->fgDispBasicBlocks());
- DBEXEC(VERBOSE, m_pCompiler->fgDispHandlerTab());
+ DBEXEC(VERBOSE, comp->fgDispBasicBlocks());
+ DBEXEC(VERBOSE, comp->fgDispHandlerTab());
- // Call the recursive helper.
- int postIndex = 0;
- TopologicalSortHelper(m_pCompiler->fgFirstBB, m_pCompiler, visited, &postIndex, postOrder);
+ // Compute order.
+ int postIndex = 0;
+ BasicBlock* block = comp->fgFirstBB;
+ BitVecOps::AddElemD(&traits, visited, block->bbNum);
+
+ ArrayStack<BasicBlock*> blocks(comp);
+ ArrayStack<AllSuccessorIter> iterators(comp);
+ ArrayStack<AllSuccessorIter> ends(comp);
+
+ // there are three stacks used here and all should be same height
+ // the first is for blocks
+ // the second is the iterator to keep track of what succ of the block we are looking at
+ // and the third is the end marker iterator
+ blocks.Push(block);
+ iterators.Push(block->GetAllSuccs(comp).begin());
+ ends.Push(block->GetAllSuccs(comp).end());
+
+ while (blocks.Height() > 0)
+ {
+ block = blocks.Top();
+
+#ifdef DEBUG
+ if (comp->verboseSsa)
+ {
+ printf("[SsaBuilder::TopologicalSort] Visiting BB%02u: ", block->bbNum);
+ printf("[");
+ unsigned numSucc = block->NumSucc(comp);
+ for (unsigned i = 0; i < numSucc; ++i)
+ {
+ printf("BB%02u, ", block->GetSucc(i, comp)->bbNum);
+ }
+ EHSuccessorIter end = block->GetEHSuccs(comp).end();
+ for (EHSuccessorIter ehsi = block->GetEHSuccs(comp).begin(); ehsi != end; ++ehsi)
+ {
+ printf("[EH]BB%02u, ", (*ehsi)->bbNum);
+ }
+ printf("]\n");
+ }
+#endif
+
+ if (iterators.TopRef() != ends.TopRef())
+ {
+ // if the block on TOS still has unreached successors, visit them
+ AllSuccessorIter& iter = iterators.TopRef();
+ BasicBlock* succ = *iter;
+ ++iter;
+
+ // push the children
+ if (!BitVecOps::IsMember(&traits, visited, succ->bbNum))
+ {
+ blocks.Push(succ);
+ iterators.Push(succ->GetAllSuccs(comp).begin());
+ ends.Push(succ->GetAllSuccs(comp).end());
+ BitVecOps::AddElemD(&traits, visited, succ->bbNum);
+ }
+ }
+ else
+ {
+ // all successors have been visited
+ blocks.Pop();
+ iterators.Pop();
+ ends.Pop();
+
+ postOrder[postIndex] = block;
+ block->bbPostOrderNum = postIndex;
+ postIndex += 1;
+
+ DBG_SSA_JITDUMP("postOrder[%d] = [%p] and BB%02u\n", postIndex, dspPtr(block), block->bbNum);
+ }
+ }
// In the absence of EH (because catch/finally have no preds), this should be valid.
// assert(postIndex == (count - 1));
@@ -1686,7 +1703,17 @@ void SsaBuilder::Build()
JITDUMP("[SsaBuilder] Max block count is %d.\n", blockCount);
// Allocate the postOrder array for the graph.
- BasicBlock** postOrder = (BasicBlock**)alloca(blockCount * sizeof(BasicBlock*));
+
+ BasicBlock** postOrder;
+
+ if (blockCount > DEFAULT_MIN_OPTS_BB_COUNT)
+ {
+ postOrder = new (m_pCompiler->getAllocator()) BasicBlock*[blockCount];
+ }
+ else
+ {
+ postOrder = (BasicBlock**)alloca(blockCount * sizeof(BasicBlock*));
+ }
// Topologically sort the graph.
int count = TopologicalSort(postOrder, blockCount);
diff --git a/src/jit/stackfp.cpp b/src/jit/stackfp.cpp
index f975822740..43c463039e 100644
--- a/src/jit/stackfp.cpp
+++ b/src/jit/stackfp.cpp
@@ -1406,8 +1406,6 @@ void CodeGen::genCodeForTreeStackFP_Asg(GenTreePtr tree)
assert(!varDsc->lvTracked || compiler->opts.MinOpts() || !(op1NonCom->gtFlags & GTF_VAR_DEATH));
#endif
-#ifdef DEBUGGING_SUPPORT
-
/* For non-debuggable code, every definition of a lcl-var has
* to be checked to see if we need to open a new scope for it.
*/
@@ -1416,7 +1414,6 @@ void CodeGen::genCodeForTreeStackFP_Asg(GenTreePtr tree)
{
siCheckVarScope(op1NonCom->gtLclVarCommon.gtLclNum, op1NonCom->gtLclVar.gtLclILoffs);
}
-#endif
}
assert(op2);
@@ -2827,7 +2824,7 @@ void CodeGen::genCondJumpFltStackFP(GenTreePtr cond, BasicBlock* jumpTrue, Basic
BasicBlock* CodeGen::genTransitionBlockStackFP(FlatFPStateX87* pState, BasicBlock* pFrom, BasicBlock* pTarget)
{
// Fast paths where a transition block is not necessary
- if (pTarget->bbFPStateX87 && FlatFPStateX87::AreEqual(pState, pTarget->bbFPStateX87) || pState->IsEmpty())
+ if ((pTarget->bbFPStateX87 && FlatFPStateX87::AreEqual(pState, pTarget->bbFPStateX87)) || pState->IsEmpty())
{
return pTarget;
}
@@ -4143,8 +4140,26 @@ void Compiler::raEnregisterVarsPostPassStackFP()
{
raSetRegLclBirthDeath(tree, lastlife, false);
}
+
+ // Model implicit use (& hence last use) of frame list root at pinvokes.
+ if (tree->gtOper == GT_CALL)
+ {
+ GenTreeCall* call = tree->AsCall();
+ if (call->IsUnmanaged() && !opts.ShouldUsePInvokeHelpers())
+ {
+ LclVarDsc* frameVarDsc = &lvaTable[info.compLvFrameListRoot];
+
+ if (frameVarDsc->lvTracked && ((call->gtCallMoreFlags & GTF_CALL_M_FRAME_VAR_DEATH) != 0))
+ {
+ // Frame var dies here
+ unsigned varIndex = frameVarDsc->lvVarIndex;
+ VarSetOps::RemoveElemD(this, lastlife, varIndex);
+ }
+ }
+ }
}
}
+
assert(VarSetOps::Equal(this, lastlife, block->bbLiveOut));
}
compCurBB = NULL;
diff --git a/src/jit/standalone/CMakeLists.txt b/src/jit/standalone/CMakeLists.txt
index 2e6317098e..f20d3790c7 100644
--- a/src/jit/standalone/CMakeLists.txt
+++ b/src/jit/standalone/CMakeLists.txt
@@ -1,22 +1,27 @@
project(ryujit)
+
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_TARGET_ARCH_I386 OR CLR_CMAKE_TARGET_ARCH_ARM)
+if(CLR_CMAKE_TARGET_ARCH_ARM)
add_definitions(-DLEGACY_BACKEND)
endif()
-add_library_clr(${JIT_BASE_NAME}
+if(WIN32)
+ add_definitions(-DFX_VER_INTERNALNAME_STR=clrjit.dll)
+endif(WIN32)
+
+add_library_clr(clrjit
SHARED
${SHARED_LIB_SOURCES}
)
-add_dependencies(${JIT_BASE_NAME} jit_exports)
+add_dependencies(clrjit jit_exports)
-set_property(TARGET ${JIT_BASE_NAME} APPEND_STRING PROPERTY LINK_FLAGS ${JIT_EXPORTS_LINKER_OPTION})
-set_property(TARGET ${JIT_BASE_NAME} APPEND_STRING PROPERTY LINK_DEPENDS ${JIT_EXPORTS_FILE})
+set_property(TARGET clrjit APPEND_STRING PROPERTY LINK_FLAGS ${JIT_EXPORTS_LINKER_OPTION})
+set_property(TARGET clrjit APPEND_STRING PROPERTY LINK_DEPENDS ${JIT_EXPORTS_FILE})
set(RYUJIT_LINK_LIBRARIES
utilcodestaticnohost
@@ -47,12 +52,12 @@ else()
)
endif(CLR_CMAKE_PLATFORM_UNIX)
-target_link_libraries(${JIT_BASE_NAME}
+target_link_libraries(clrjit
${RYUJIT_LINK_LIBRARIES}
)
# add the install targets
-install_clr(${JIT_BASE_NAME})
+install_clr(clrjit)
# Enable profile guided optimization
-add_pgo(${JIT_BASE_NAME})
+add_pgo(clrjit)
diff --git a/src/jit/target.h b/src/jit/target.h
index fa0b18af3e..a726525488 100644
--- a/src/jit/target.h
+++ b/src/jit/target.h
@@ -6,11 +6,6 @@
#ifndef _TARGET_H_
#define _TARGET_H_
-// Inform includers that we're in a context in which a target has been set.
-#if defined(_TARGET_X86_) || defined(_TARGET_AMD64_) || defined(_TARGET_ARM_)
-#define _TARGET_SET_
-#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_)
@@ -365,6 +360,9 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#endif // !LEGACY_BACKEND
+#ifdef FEATURE_SIMD
+ #define ALIGN_SIMD_TYPES 1 // whether SIMD type locals are to be aligned
+#endif // FEATURE_SIMD
#define FEATURE_WRITE_BARRIER 1 // Generate the proper WriteBarrier calls for GC
#define FEATURE_FIXED_OUT_ARGS 0 // X86 uses push instructions to pass args
@@ -585,7 +583,14 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define RBM_CALLEE_TRASH_NOGC RBM_EDX
#endif // NOGC_WRITE_BARRIERS
- // IL stub's secret parameter (CORJIT_FLG_PUBLISH_SECRET_PARAM)
+ // GenericPInvokeCalliHelper unmanaged target parameter
+ #define REG_PINVOKE_TARGET_PARAM REG_EAX
+ #define RBM_PINVOKE_TARGET_PARAM RBM_EAX
+
+ // GenericPInvokeCalliHelper cookie parameter
+ #define REG_PINVOKE_COOKIE_PARAM REG_STK
+
+ // IL stub's secret parameter (JitFlags::JIT_FLAG_PUBLISH_SECRET_PARAM)
#define REG_SECRET_STUB_PARAM REG_EAX
#define RBM_SECRET_STUB_PARAM RBM_EAX
@@ -594,6 +599,10 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define RBM_VIRTUAL_STUB_PARAM RBM_EAX
#define PREDICT_REG_VIRTUAL_STUB_PARAM PREDICT_REG_EAX
+ // VSD target address register
+ #define REG_VIRTUAL_STUB_TARGET REG_EAX
+ #define RBM_VIRTUAL_STUB_TARGET RBM_EAX
+
// Registers used by PInvoke frame setup
#define REG_PINVOKE_FRAME REG_EDI // EDI is p/invoke "Frame" pointer argument to CORINFO_HELP_INIT_PINVOKE_FRAME helper
#define RBM_PINVOKE_FRAME RBM_EDI
@@ -670,6 +679,12 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define RBM_ARG_REGS (RBM_ARG_0|RBM_ARG_1)
+ // The registers trashed by profiler enter/leave/tailcall hook
+ // See vm\i386\asmhelpers.asm for more details.
+ #define RBM_PROFILER_ENTER_TRASH RBM_NONE
+ #define RBM_PROFILER_LEAVE_TRASH RBM_NONE
+ #define RBM_PROFILER_TAILCALL_TRASH (RBM_ALLINT & ~RBM_ARG_REGS)
+
// What sort of reloc do we use for [disp32] address mode
#define IMAGE_REL_BASED_DISP32 IMAGE_REL_BASED_HIGHLOW
@@ -968,7 +983,7 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define RBM_PINVOKE_TARGET_PARAM RBM_R10
#define PREDICT_REG_PINVOKE_TARGET_PARAM PREDICT_REG_R10
- // IL stub's secret MethodDesc parameter (CORJIT_FLG_PUBLISH_SECRET_PARAM)
+ // IL stub's secret MethodDesc parameter (JitFlags::JIT_FLAG_PUBLISH_SECRET_PARAM)
#define REG_SECRET_STUB_PARAM REG_R10
#define RBM_SECRET_STUB_PARAM RBM_R10
@@ -1111,9 +1126,10 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#endif // !UNIX_AMD64_ABI
// The registers trashed by profiler enter/leave/tailcall hook
- // See vm\amd64\amshelpers.asm for more details.
- #define RBM_PROFILER_ENTER_TRASH RBM_CALLEE_TRASH
- #define RBM_PROFILER_LEAVE_TRASH (RBM_CALLEE_TRASH & ~(RBM_FLOATRET | RBM_INTRET))
+ // See vm\amd64\asmhelpers.asm for more details.
+ #define RBM_PROFILER_ENTER_TRASH RBM_CALLEE_TRASH
+ #define RBM_PROFILER_LEAVE_TRASH (RBM_CALLEE_TRASH & ~(RBM_FLOATRET | RBM_INTRET))
+ #define RBM_PROFILER_TAILCALL_TRASH RBM_PROFILER_LEAVE_TRASH
// The registers trashed by the CORINFO_HELP_STOP_FOR_GC helper.
#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
@@ -1339,7 +1355,7 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define RBM_PINVOKE_TARGET_PARAM RBM_R12
#define PREDICT_REG_PINVOKE_TARGET_PARAM PREDICT_REG_R12
- // IL stub's secret MethodDesc parameter (CORJIT_FLG_PUBLISH_SECRET_PARAM)
+ // IL stub's secret MethodDesc parameter (JitFlags::JIT_FLAG_PUBLISH_SECRET_PARAM)
#define REG_SECRET_STUB_PARAM REG_R12
#define RBM_SECRET_STUB_PARAM RBM_R12
@@ -1447,6 +1463,9 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define JMP_DIST_SMALL_MAX_NEG (-2048)
#define JMP_DIST_SMALL_MAX_POS (+2046)
+ #define CALL_DIST_MAX_NEG (-16777216)
+ #define CALL_DIST_MAX_POS (+16777214)
+
#define JCC_DIST_SMALL_MAX_NEG (-256)
#define JCC_DIST_SMALL_MAX_POS (+254)
@@ -1617,7 +1636,7 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define RBM_PINVOKE_TARGET_PARAM RBM_R14
#define PREDICT_REG_PINVOKE_TARGET_PARAM PREDICT_REG_R14
- // IL stub's secret MethodDesc parameter (CORJIT_FLG_PUBLISH_SECRET_PARAM)
+ // IL stub's secret MethodDesc parameter (JitFlags::JIT_FLAG_PUBLISH_SECRET_PARAM)
#define REG_SECRET_STUB_PARAM REG_R12
#define RBM_SECRET_STUB_PARAM RBM_R12
@@ -2277,6 +2296,9 @@ inline regNumber regNextOfType(regNumber reg, var_types type)
inline bool isRegPairType(int /* s/b "var_types" */ type)
{
+#if !CPU_LONG_USES_REGPAIR
+ return false;
+#else
#ifdef _TARGET_64BIT_
return false;
#elif CPU_HAS_FP_SUPPORT
@@ -2284,6 +2306,7 @@ inline bool isRegPairType(int /* s/b "var_types" */ type)
#else
return type == TYP_LONG || type == TYP_DOUBLE;
#endif
+#endif // CPU_LONG_USES_REGPAIR
}
inline bool isFloatRegType(int /* s/b "var_types" */ type)
diff --git a/src/jit/tinyarray.h b/src/jit/tinyarray.h
index 17d7e044b2..bee59bdb59 100644
--- a/src/jit/tinyarray.h
+++ b/src/jit/tinyarray.h
@@ -71,7 +71,7 @@ public:
// only use this for clearing it
void operator=(void* rhs)
{
- assert(rhs == NULL);
+ assert(rhs == nullptr);
data = 0;
}
};
diff --git a/src/jit/unwindamd64.cpp b/src/jit/unwindamd64.cpp
index 89abdff2b3..14eba8cb50 100644
--- a/src/jit/unwindamd64.cpp
+++ b/src/jit/unwindamd64.cpp
@@ -481,6 +481,13 @@ void Compiler::unwindSetFrameRegWindows(regNumber reg, unsigned offset)
}
#ifdef UNIX_AMD64_ABI
+//------------------------------------------------------------------------
+// Compiler::unwindSetFrameRegCFI: Record a cfi info for a frame register set.
+//
+// Arguments:
+// reg - The register being set as the frame register.
+// offset - The offset from the current stack pointer that the frame pointer will point at.
+//
void Compiler::unwindSetFrameRegCFI(regNumber reg, unsigned offset)
{
assert(compGeneratingProlog);
@@ -492,7 +499,13 @@ void Compiler::unwindSetFrameRegCFI(regNumber reg, unsigned offset)
createCfiCode(func, cbProlog, CFI_DEF_CFA_REGISTER, mapRegNumToDwarfReg(reg));
if (offset != 0)
{
- createCfiCode(func, cbProlog, CFI_ADJUST_CFA_OFFSET, DWARF_REG_ILLEGAL, offset);
+ // before: cfa = rsp + old_cfa_offset;
+ // rbp = rsp + offset;
+ // after: cfa should be based on rbp, but points to the old address:
+ // rsp + old_cfa_offset == rbp + old_cfa_offset + adjust;
+ // adjust = -offset;
+ int adjust = -(int)offset;
+ createCfiCode(func, cbProlog, CFI_ADJUST_CFA_OFFSET, DWARF_REG_ILLEGAL, adjust);
}
}
#endif // UNIX_AMD64_ABI
diff --git a/src/jit/utils.cpp b/src/jit/utils.cpp
index 9934416412..3a45039aa7 100644
--- a/src/jit/utils.cpp
+++ b/src/jit/utils.cpp
@@ -657,7 +657,7 @@ void dumpILRange(const BYTE* const codeAddr, unsigned codeSize) // in bytes
for (IL_OFFSET offs = 0; offs < codeSize;)
{
char prefix[100];
- sprintf(prefix, "IL_%04x ", offs);
+ sprintf_s(prefix, _countof(prefix), "IL_%04x ", offs);
unsigned codeBytesDumped = dumpSingleInstr(codeAddr, offs, prefix);
offs += codeBytesDumped;
}
@@ -665,11 +665,9 @@ void dumpILRange(const BYTE* const codeAddr, unsigned codeSize) // in bytes
/*****************************************************************************
*
- * Display a variable set (which may be a 32-bit or 64-bit number); only
- * one or two of these can be used at once.
+ * Display a variable set.
*/
-
-const char* genES2str(EXPSET_TP set)
+const char* genES2str(BitVecTraits* traits, EXPSET_TP set)
{
const int bufSize = 17;
static char num1[bufSize];
@@ -682,11 +680,7 @@ const char* genES2str(EXPSET_TP set)
nump = (nump == num1) ? num2 : num1;
-#if EXPSET_SZ == 32
- sprintf_s(temp, bufSize, "%08X", set);
-#else
- sprintf_s(temp, bufSize, "%08X%08X", (int)(set >> 32), (int)set);
-#endif
+ sprintf_s(temp, bufSize, "%s", BitVecOps::ToString(traits, set));
return temp;
}
@@ -876,7 +870,7 @@ void ConfigMethodRange::InitRanges(const wchar_t* rangeStr, unsigned capacity)
#endif // defined(DEBUG) || defined(INLINE_DATA)
-#if CALL_ARG_STATS || COUNT_BASIC_BLOCKS || COUNT_LOOPS || EMITTER_STATS || MEASURE_NODE_SIZE
+#if CALL_ARG_STATS || COUNT_BASIC_BLOCKS || COUNT_LOOPS || EMITTER_STATS || MEASURE_NODE_SIZE || MEASURE_MEM_ALLOC
/*****************************************************************************
* Histogram class.
@@ -896,7 +890,10 @@ Histogram::Histogram(IAllocator* allocator, const unsigned* const sizeTable)
Histogram::~Histogram()
{
- m_allocator->Free(m_counts);
+ if (m_counts != nullptr)
+ {
+ m_allocator->Free(m_counts);
+ }
}
// We need to lazy allocate the histogram data so static `Histogram` variables don't try to
@@ -1414,6 +1411,9 @@ 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
diff --git a/src/jit/valuenum.cpp b/src/jit/valuenum.cpp
index 5bc96ed4a9..f7cc0c9a23 100644
--- a/src/jit/valuenum.cpp
+++ b/src/jit/valuenum.cpp
@@ -76,7 +76,6 @@ ValueNumStore::ValueNumStore(Compiler* comp, IAllocator* alloc)
, m_VNFunc2Map(nullptr)
, m_VNFunc3Map(nullptr)
, m_VNFunc4Map(nullptr)
- , m_uPtrToLocNotAFieldCount(1)
{
// We have no current allocation chunks.
for (unsigned i = 0; i < TYP_COUNT; i++)
@@ -604,6 +603,7 @@ ValueNumStore::Chunk::Chunk(
switch (attribs)
{
case CEA_None:
+ case CEA_NotAField:
break; // Nothing to do.
case CEA_Const:
switch (typ)
@@ -911,6 +911,7 @@ class Object* ValueNumStore::s_specialRefConsts[] = {nullptr, nullptr, nullptr};
ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func)
{
assert(VNFuncArity(func) == 0);
+ assert(func != VNF_NotAField);
ValueNum res;
@@ -1029,9 +1030,9 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
{
if (typ != TYP_BYREF) // We don't want/need to optimize a zero byref
{
- genTreeOps oper = genTreeOps(func);
- ValueNum ZeroVN, OneVN; // We may need to create one of these in the switch below.
- switch (oper)
+ ValueNum resultVN = NoVN;
+ ValueNum ZeroVN, OneVN; // We may need to create one of these in the switch below.
+ switch (genTreeOps(func))
{
case GT_ADD:
// This identity does not apply for floating point (when x == -0.0)
@@ -1041,11 +1042,11 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
ZeroVN = VNZeroForType(typ);
if (arg0VN == ZeroVN)
{
- return arg1VN;
+ resultVN = arg1VN;
}
else if (arg1VN == ZeroVN)
{
- return arg0VN;
+ resultVN = arg0VN;
}
}
break;
@@ -1055,7 +1056,7 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
ZeroVN = VNZeroForType(typ);
if (arg1VN == ZeroVN)
{
- return arg0VN;
+ resultVN = arg0VN;
}
break;
@@ -1066,11 +1067,11 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
{
if (arg0VN == OneVN)
{
- return arg1VN;
+ resultVN = arg1VN;
}
else if (arg1VN == OneVN)
{
- return arg0VN;
+ resultVN = arg0VN;
}
}
@@ -1080,11 +1081,11 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
ZeroVN = VNZeroForType(typ);
if (arg0VN == ZeroVN)
{
- return ZeroVN;
+ resultVN = ZeroVN;
}
else if (arg1VN == ZeroVN)
{
- return ZeroVN;
+ resultVN = ZeroVN;
}
}
break;
@@ -1097,7 +1098,7 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
{
if (arg1VN == OneVN)
{
- return arg0VN;
+ resultVN = arg0VN;
}
}
break;
@@ -1109,11 +1110,11 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
ZeroVN = VNZeroForType(typ);
if (arg0VN == ZeroVN)
{
- return arg1VN;
+ resultVN = arg1VN;
}
else if (arg1VN == ZeroVN)
{
- return arg0VN;
+ resultVN = arg0VN;
}
break;
@@ -1122,11 +1123,11 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
ZeroVN = VNZeroForType(typ);
if (arg0VN == ZeroVN)
{
- return ZeroVN;
+ resultVN = ZeroVN;
}
else if (arg1VN == ZeroVN)
{
- return ZeroVN;
+ resultVN = ZeroVN;
}
break;
@@ -1142,7 +1143,7 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
ZeroVN = VNZeroForType(typ);
if (arg1VN == ZeroVN)
{
- return arg0VN;
+ resultVN = arg0VN;
}
break;
@@ -1150,30 +1151,35 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
// (x == x) => true (unless x is NaN)
if (!varTypeIsFloating(TypeOfVN(arg0VN)) && (arg0VN != NoVN) && (arg0VN == arg1VN))
{
- return VNOneForType(typ);
+ resultVN = VNOneForType(typ);
}
if ((arg0VN == VNForNull() && IsKnownNonNull(arg1VN)) ||
(arg1VN == VNForNull() && IsKnownNonNull(arg0VN)))
{
- return VNZeroForType(typ);
+ resultVN = VNZeroForType(typ);
}
break;
case GT_NE:
// (x != x) => false (unless x is NaN)
if (!varTypeIsFloating(TypeOfVN(arg0VN)) && (arg0VN != NoVN) && (arg0VN == arg1VN))
{
- return VNZeroForType(typ);
+ resultVN = VNZeroForType(typ);
}
if ((arg0VN == VNForNull() && IsKnownNonNull(arg1VN)) ||
(arg1VN == VNForNull() && IsKnownNonNull(arg0VN)))
{
- return VNOneForType(typ);
+ resultVN = VNOneForType(typ);
}
break;
default:
break;
}
+
+ if ((resultVN != NoVN) && (TypeOfVN(resultVN) == typ))
+ {
+ return resultVN;
+ }
}
}
else // must be a VNF_ function
@@ -2072,10 +2078,11 @@ bool ValueNumStore::CanEvalForConstantArgs(VNFunc vnf)
case GT_MKREFANY: // We can't evaluate these.
case GT_RETFILT:
case GT_LIST:
+ case GT_FIELD_LIST:
case GT_ARR_LENGTH:
return false;
case GT_MULHI:
- // should be rare, not worth the complexity and risk of getting it wrong
+ assert(false && "Unexpected GT_MULHI node encountered before lowering");
return false;
default:
return true;
@@ -2545,6 +2552,11 @@ ValueNumPair ValueNumStore::VNPairApplySelectors(ValueNumPair map, FieldSeqNode*
return ValueNumPair(liberalVN, conservVN);
}
+bool ValueNumStore::IsVNNotAField(ValueNum vn)
+{
+ return m_chunks.GetNoExpand(GetChunkNum(vn))->m_attribs == CEA_NotAField;
+}
+
ValueNum ValueNumStore::VNForFieldSeq(FieldSeqNode* fieldSeq)
{
if (fieldSeq == nullptr)
@@ -2553,7 +2565,11 @@ ValueNum ValueNumStore::VNForFieldSeq(FieldSeqNode* fieldSeq)
}
else if (fieldSeq == FieldSeqStore::NotAField())
{
- return VNForNotAField();
+ // We always allocate a new, unique VN in this call.
+ Chunk* c = GetAllocChunk(TYP_REF, CEA_NotAField);
+ unsigned offsetWithinChunk = c->AllocVN();
+ ValueNum result = c->m_baseVN + offsetWithinChunk;
+ return result;
}
else
{
@@ -2585,22 +2601,22 @@ FieldSeqNode* ValueNumStore::FieldSeqVNToFieldSeq(ValueNum vn)
{
return nullptr;
}
- else if (vn == VNForNotAField())
+
+ assert(IsVNFunc(vn));
+
+ VNFuncApp funcApp;
+ GetVNFunc(vn, &funcApp);
+ if (funcApp.m_func == VNF_NotAField)
{
return FieldSeqStore::NotAField();
}
- else
- {
- assert(IsVNFunc(vn));
- VNFuncApp funcApp;
- GetVNFunc(vn, &funcApp);
- assert(funcApp.m_func == VNF_FieldSeq);
- ssize_t fieldHndVal = ConstantValue<ssize_t>(funcApp.m_args[0]);
- FieldSeqNode* head =
- m_pComp->GetFieldSeqStore()->CreateSingleton(reinterpret_cast<CORINFO_FIELD_HANDLE>(fieldHndVal));
- FieldSeqNode* tail = FieldSeqVNToFieldSeq(funcApp.m_args[1]);
- return m_pComp->GetFieldSeqStore()->Append(head, tail);
- }
+
+ assert(funcApp.m_func == VNF_FieldSeq);
+ const ssize_t fieldHndVal = ConstantValue<ssize_t>(funcApp.m_args[0]);
+ FieldSeqNode* head =
+ m_pComp->GetFieldSeqStore()->CreateSingleton(reinterpret_cast<CORINFO_FIELD_HANDLE>(fieldHndVal));
+ FieldSeqNode* tail = FieldSeqVNToFieldSeq(funcApp.m_args[1]);
+ return m_pComp->GetFieldSeqStore()->Append(head, tail);
}
ValueNum ValueNumStore::FieldSeqVNAppend(ValueNum fsVN1, ValueNum fsVN2)
@@ -2609,40 +2625,31 @@ ValueNum ValueNumStore::FieldSeqVNAppend(ValueNum fsVN1, ValueNum fsVN2)
{
return fsVN2;
}
- else if (fsVN1 == VNForNotAField() || fsVN2 == VNForNotAField())
- {
- return VNForNotAField();
- }
- else
- {
- assert(IsVNFunc(fsVN1));
- VNFuncApp funcApp1;
- GetVNFunc(fsVN1, &funcApp1);
- assert(funcApp1.m_func == VNF_FieldSeq);
- ValueNum tailRes = FieldSeqVNAppend(funcApp1.m_args[1], fsVN2);
- ValueNum fieldSeqVN = VNForFunc(TYP_REF, VNF_FieldSeq, funcApp1.m_args[0], tailRes);
-#ifdef DEBUG
- if (m_pComp->verbose)
- {
- printf(" fieldSeq " STR_VN "%x is ", fieldSeqVN);
- vnDump(m_pComp, fieldSeqVN);
- printf("\n");
- }
-#endif
+ assert(IsVNFunc(fsVN1));
- return fieldSeqVN;
+ VNFuncApp funcApp1;
+ GetVNFunc(fsVN1, &funcApp1);
+
+ if ((funcApp1.m_func == VNF_NotAField) || IsVNNotAField(fsVN2))
+ {
+ return VNForFieldSeq(FieldSeqStore::NotAField());
}
-}
-ValueNum ValueNumStore::VNForPtrToLoc(var_types typ, ValueNum lclVarVN, ValueNum fieldSeqVN)
-{
- if (fieldSeqVN == VNForNotAField())
+ assert(funcApp1.m_func == VNF_FieldSeq);
+ ValueNum tailRes = FieldSeqVNAppend(funcApp1.m_args[1], fsVN2);
+ ValueNum fieldSeqVN = VNForFunc(TYP_REF, VNF_FieldSeq, funcApp1.m_args[0], tailRes);
+
+#ifdef DEBUG
+ if (m_pComp->verbose)
{
- // To distinguish two different not a fields, append a unique value.
- return VNForFunc(typ, VNF_PtrToLoc, lclVarVN, fieldSeqVN, VNForIntCon(++m_uPtrToLocNotAFieldCount));
+ printf(" fieldSeq " STR_VN "%x is ", fieldSeqVN);
+ vnDump(m_pComp, fieldSeqVN);
+ printf("\n");
}
- return VNForFunc(typ, VNF_PtrToLoc, lclVarVN, fieldSeqVN, VNForIntCon(0));
+#endif
+
+ return fieldSeqVN;
}
ValueNum ValueNumStore::ExtendPtrVN(GenTreePtr opA, GenTreePtr opB)
@@ -2650,7 +2657,7 @@ ValueNum ValueNumStore::ExtendPtrVN(GenTreePtr opA, GenTreePtr opB)
if (opB->OperGet() == GT_CNS_INT)
{
FieldSeqNode* fldSeq = opB->gtIntCon.gtFieldSeq;
- if ((fldSeq != nullptr) && (fldSeq != FieldSeqStore::NotAField()))
+ if (fldSeq != nullptr)
{
return ExtendPtrVN(opA, opB->gtIntCon.gtFieldSeq);
}
@@ -2660,8 +2667,9 @@ ValueNum ValueNumStore::ExtendPtrVN(GenTreePtr opA, GenTreePtr opB)
ValueNum ValueNumStore::ExtendPtrVN(GenTreePtr opA, FieldSeqNode* fldSeq)
{
+ assert(fldSeq != nullptr);
+
ValueNum res = NoVN;
- assert(fldSeq != FieldSeqStore::NotAField());
ValueNum opAvnWx = opA->gtVNPair.GetLiberal();
assert(VNIsValid(opAvnWx));
@@ -2684,7 +2692,7 @@ ValueNum ValueNumStore::ExtendPtrVN(GenTreePtr opA, FieldSeqNode* fldSeq)
assert(GetVNFunc(VNNormVal(opA->GetVN(VNK_Conservative)), &consFuncApp) && consFuncApp.Equals(funcApp));
#endif
ValueNum fldSeqVN = VNForFieldSeq(fldSeq);
- res = VNForPtrToLoc(TYP_BYREF, funcApp.m_args[0], FieldSeqVNAppend(funcApp.m_args[1], fldSeqVN));
+ res = VNForFunc(TYP_BYREF, VNF_PtrToLoc, funcApp.m_args[0], FieldSeqVNAppend(funcApp.m_args[1], fldSeqVN));
}
else if (funcApp.m_func == VNF_PtrToStatic)
{
@@ -2917,6 +2925,11 @@ ValueNum Compiler::fgValueNumberArrIndexVal(GenTreePtr tree,
var_types ValueNumStore::TypeOfVN(ValueNum vn)
{
+ if (vn == NoVN)
+ {
+ return TYP_UNDEF;
+ }
+
Chunk* c = m_chunks.GetNoExpand(GetChunkNum(vn));
return c->m_typ;
}
@@ -2936,6 +2949,11 @@ var_types ValueNumStore::TypeOfVN(ValueNum vn)
BasicBlock::loopNumber ValueNumStore::LoopOfVN(ValueNum vn)
{
+ if (vn == NoVN)
+ {
+ return MAX_LOOP_NUM;
+ }
+
Chunk* c = m_chunks.GetNoExpand(GetChunkNum(vn));
return c->m_loopNum;
}
@@ -3388,6 +3406,7 @@ bool ValueNumStore::IsVNFunc(ValueNum vn)
Chunk* c = m_chunks.GetNoExpand(GetChunkNum(vn));
switch (c->m_attribs)
{
+ case CEA_NotAField:
case CEA_Func0:
case CEA_Func1:
case CEA_Func2:
@@ -3401,6 +3420,11 @@ bool ValueNumStore::IsVNFunc(ValueNum vn)
bool ValueNumStore::GetVNFunc(ValueNum vn, VNFuncApp* funcApp)
{
+ if (vn == NoVN)
+ {
+ return false;
+ }
+
Chunk* c = m_chunks.GetNoExpand(GetChunkNum(vn));
unsigned offset = ChunkOffset(vn);
assert(offset < c->m_numUsed);
@@ -3415,8 +3439,8 @@ bool ValueNumStore::GetVNFunc(ValueNum vn, VNFuncApp* funcApp)
funcApp->m_args[1] = farg4->m_arg1;
funcApp->m_args[2] = farg4->m_arg2;
funcApp->m_args[3] = farg4->m_arg3;
- }
return true;
+ }
case CEA_Func3:
{
VNDefFunc3Arg* farg3 = &reinterpret_cast<VNDefFunc3Arg*>(c->m_defs)[offset];
@@ -3425,8 +3449,8 @@ bool ValueNumStore::GetVNFunc(ValueNum vn, VNFuncApp* funcApp)
funcApp->m_args[0] = farg3->m_arg0;
funcApp->m_args[1] = farg3->m_arg1;
funcApp->m_args[2] = farg3->m_arg2;
- }
return true;
+ }
case CEA_Func2:
{
VNDefFunc2Arg* farg2 = &reinterpret_cast<VNDefFunc2Arg*>(c->m_defs)[offset];
@@ -3434,23 +3458,29 @@ bool ValueNumStore::GetVNFunc(ValueNum vn, VNFuncApp* funcApp)
funcApp->m_arity = 2;
funcApp->m_args[0] = farg2->m_arg0;
funcApp->m_args[1] = farg2->m_arg1;
- }
return true;
+ }
case CEA_Func1:
{
VNDefFunc1Arg* farg1 = &reinterpret_cast<VNDefFunc1Arg*>(c->m_defs)[offset];
funcApp->m_func = farg1->m_func;
funcApp->m_arity = 1;
funcApp->m_args[0] = farg1->m_arg0;
- }
return true;
+ }
case CEA_Func0:
{
VNDefFunc0Arg* farg0 = &reinterpret_cast<VNDefFunc0Arg*>(c->m_defs)[offset];
funcApp->m_func = farg0->m_func;
funcApp->m_arity = 0;
+ return true;
}
+ case CEA_NotAField:
+ {
+ funcApp->m_func = VNF_NotAField;
+ funcApp->m_arity = 0;
return true;
+ }
default:
return false;
}
@@ -3751,8 +3781,9 @@ static genTreeOps genTreeOpsIllegalAsVNFunc[] = {GT_IND, // When we do heap memo
// These need special semantics:
GT_COMMA, // == second argument (but with exception(s) from first).
GT_ADDR, GT_ARR_BOUNDS_CHECK,
- GT_OBJ, // May reference heap memory.
- GT_BLK, // May reference heap memory.
+ GT_OBJ, // May reference heap memory.
+ GT_BLK, // May reference heap memory.
+ GT_INIT_VAL, // Not strictly a pass-through.
// These control-flow operations need no values.
GT_JTRUE, GT_RETURN, GT_SWITCH, GT_RETFILT, GT_CKFINITE};
@@ -3842,10 +3873,9 @@ static const char* s_reservedNameArr[] = {
"$VN.No", // -1 NoVN
"$VN.Null", // 0 VNForNull()
"$VN.ZeroMap", // 1 VNForZeroMap()
- "$VN.NotAField", // 2 VNForNotAField()
- "$VN.ReadOnlyHeap", // 3 VNForROH()
- "$VN.Void", // 4 VNForVoid()
- "$VN.EmptyExcSet" // 5 VNForEmptyExcSet()
+ "$VN.ReadOnlyHeap", // 2 VNForROH()
+ "$VN.Void", // 3 VNForVoid()
+ "$VN.EmptyExcSet" // 4 VNForEmptyExcSet()
};
// Returns the string name of "vn" when it is a reserved value number, nullptr otherwise
@@ -4804,8 +4834,16 @@ void Compiler::fgValueNumberTreeConst(GenTreePtr tree)
tree->gtVNPair.SetBoth(vnStore->VNForDoubleCon(tree->gtDblCon.gtDconVal));
break;
case TYP_REF:
- // Null is the only constant. (Except maybe for String?)
- tree->gtVNPair.SetBoth(ValueNumStore::VNForNull());
+ if (tree->gtIntConCommon.IconValue() == 0)
+ {
+ tree->gtVNPair.SetBoth(ValueNumStore::VNForNull());
+ }
+ else
+ {
+ assert(tree->gtFlags == GTF_ICON_STR_HDL); // Constant object can be only frozen string.
+ tree->gtVNPair.SetBoth(
+ vnStore->VNForHandle(ssize_t(tree->gtIntConCommon.IconValue()), tree->GetIconHandleFlag()));
+ }
break;
case TYP_BYREF:
@@ -4903,9 +4941,6 @@ void Compiler::fgValueNumberBlockAssignment(GenTreePtr tree, bool evalAsgLhsInd)
}
#endif // DEBUG
}
- // Initblock's are of type void. Give them the void "value" -- they may occur in argument lists, which we
- // want to be able to give VN's to.
- tree->gtVNPair.SetBoth(ValueNumStore::VNForVoid());
}
else
{
@@ -4913,6 +4948,9 @@ void Compiler::fgValueNumberBlockAssignment(GenTreePtr tree, bool evalAsgLhsInd)
// TODO-CQ: Why not be complete, and get this case right?
fgMutateHeap(tree DEBUGARG("INITBLK - non local"));
}
+ // Initblock's are of type void. Give them the void "value" -- they may occur in argument lists, which we
+ // want to be able to give VN's to.
+ tree->gtVNPair.SetBoth(ValueNumStore::VNForVoid());
}
else
{
@@ -4953,17 +4991,21 @@ void Compiler::fgValueNumberBlockAssignment(GenTreePtr tree, bool evalAsgLhsInd)
assert(lhs->OperGet() == GT_IND);
lhsAddr = lhs->gtOp.gtOp1;
}
+
// For addr-of-local expressions, lib/cons shouldn't matter.
assert(lhsAddr->gtVNPair.BothEqual());
ValueNum lhsAddrVN = lhsAddr->GetVN(VNK_Liberal);
// Unpack the PtrToLoc value number of the address.
assert(vnStore->IsVNFunc(lhsAddrVN));
+
VNFuncApp lhsAddrFuncApp;
vnStore->GetVNFunc(lhsAddrVN, &lhsAddrFuncApp);
+
assert(lhsAddrFuncApp.m_func == VNF_PtrToLoc);
assert(vnStore->IsVNConstant(lhsAddrFuncApp.m_args[0]) &&
vnStore->ConstantValue<unsigned>(lhsAddrFuncApp.m_args[0]) == lhsLclNum);
+
lhsFldSeq = vnStore->FieldSeqVNToFieldSeq(lhsAddrFuncApp.m_args[1]);
}
@@ -5598,10 +5640,9 @@ void Compiler::fgValueNumberTree(GenTreePtr tree, bool evalAsgLhsInd)
// (we looked in a side table above for its "def" identity). Look up that value.
ValueNumPair oldLhsVNPair =
lvaTable[lclFld->GetLclNum()].GetPerSsaData(lclFld->GetSsaNum())->m_vnPair;
- newLhsVNPair =
- vnStore->VNPairApplySelectorsAssign(oldLhsVNPair, lclFld->gtFieldSeq,
- rhsVNPair, // Pre-value.
- lvaGetActualType(lclFld->gtLclNum), compCurBB);
+ newLhsVNPair = vnStore->VNPairApplySelectorsAssign(oldLhsVNPair, lclFld->gtFieldSeq,
+ rhsVNPair, // Pre-value.
+ lclFld->TypeGet(), compCurBB);
}
}
lvaTable[lclFld->GetLclNum()].GetPerSsaData(lclDefSsaNum)->m_vnPair = newLhsVNPair;
@@ -6034,8 +6075,9 @@ void Compiler::fgValueNumberTree(GenTreePtr tree, bool evalAsgLhsInd)
if (newVN == ValueNumStore::NoVN)
{
assert(arg->gtLclVarCommon.GetSsaNum() != ValueNumStore::NoVN);
- newVN = vnStore->VNForPtrToLoc(TYP_BYREF, vnStore->VNForIntCon(arg->gtLclVarCommon.GetLclNum()),
- vnStore->VNForFieldSeq(fieldSeq));
+ newVN = vnStore->VNForFunc(TYP_BYREF, VNF_PtrToLoc,
+ vnStore->VNForIntCon(arg->gtLclVarCommon.GetLclNum()),
+ vnStore->VNForFieldSeq(fieldSeq));
}
tree->gtVNPair.SetBoth(newVN);
}
@@ -6240,17 +6282,12 @@ void Compiler::fgValueNumberTree(GenTreePtr tree, bool evalAsgLhsInd)
}
tree->gtVNPair = vnStore->VNPWithExc(tree->gtVNPair, addrXvnp);
}
- else if (!varTypeIsStruct(tree) && vnStore->GetVNFunc(addrNvnp.GetLiberal(), &funcApp) &&
- (funcApp.m_func == VNF_PtrToArrElem))
+ else if (vnStore->GetVNFunc(addrNvnp.GetLiberal(), &funcApp) && (funcApp.m_func == VNF_PtrToArrElem))
{
- // TODO-1stClassStructs: The above condition need not exclude struct types, but it is
- // excluded for now to minimize diffs.
fgValueNumberArrIndexVal(tree, &funcApp, addrXvnp.GetLiberal());
}
- else if (!varTypeIsStruct(tree) && addr->IsFieldAddr(this, &obj, &staticOffset, &fldSeq2))
+ else if (addr->IsFieldAddr(this, &obj, &staticOffset, &fldSeq2))
{
- // TODO-1stClassStructs: The above condition need not exclude struct types, but it is
- // excluded for now to minimize diffs.
if (fldSeq2 == FieldSeqStore::NotAField())
{
tree->gtVNPair.SetBoth(vnStore->VNForExpr(compCurBB, tree->TypeGet()));
@@ -6522,6 +6559,9 @@ void Compiler::fgValueNumberTree(GenTreePtr tree, bool evalAsgLhsInd)
case GT_JTRUE:
case GT_LIST:
+#ifndef LEGACY_BACKEND
+ case GT_FIELD_LIST:
+#endif // !LEGACY_BACKEND
// These nodes never need to have a ValueNumber
tree->gtVNPair.SetBoth(ValueNumStore::NoVN);
break;
@@ -6667,7 +6707,7 @@ void Compiler::fgValueNumberCastTree(GenTreePtr tree)
bool srcIsUnsigned = ((tree->gtFlags & GTF_UNSIGNED) != 0);
bool hasOverflowCheck = tree->gtOverflowEx();
- assert(genActualType(castToType) == tree->TypeGet()); // Insure that the resultType is correct
+ assert(genActualType(castToType) == genActualType(tree->TypeGet())); // Insure that the resultType is correct
tree->gtVNPair = vnStore->VNPairForCast(srcVNPair, castToType, castFromType, srcIsUnsigned, hasOverflowCheck);
}
@@ -6816,6 +6856,7 @@ void Compiler::fgValueNumberHelperCallFunc(GenTreeCall* call, VNFunc vnf, ValueN
break;
case VNF_ReadyToRunStaticBase:
+ case VNF_ReadyToRunGenericStaticBase:
case VNF_ReadyToRunIsInstanceOf:
case VNF_ReadyToRunCastClass:
{
@@ -7061,11 +7102,11 @@ VNFunc Compiler::fgValueNumberHelperMethVNFunc(CorInfoHelpFunc helpFunc)
vnf = VNFunc(GT_MOD);
break;
case CORINFO_HELP_ULDIV:
- vnf = VNFunc(GT_DIV);
- break; // Is this the right thing?
+ vnf = VNFunc(GT_UDIV);
+ break;
case CORINFO_HELP_ULMOD:
- vnf = VNFunc(GT_MOD);
- break; // Is this the right thing?
+ vnf = VNFunc(GT_UMOD);
+ break;
case CORINFO_HELP_LNG2DBL:
vnf = VNF_Lng2Dbl;
@@ -7155,6 +7196,11 @@ 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;
diff --git a/src/jit/valuenum.h b/src/jit/valuenum.h
index 17dacfbb54..c8a57ff210 100644
--- a/src/jit/valuenum.h
+++ b/src/jit/valuenum.h
@@ -297,13 +297,6 @@ public:
return ValueNum(SRC_ZeroMap);
}
- // The value number for the special "NotAField" field sequence.
- static ValueNum VNForNotAField()
- {
- // We reserve Chunk 0 for "special" VNs. Let SRC_NotAField (== 2) be the "not a field seq".
- return ValueNum(SRC_NotAField);
- }
-
// The ROH map is the map for the "read-only heap". We assume that this is never mutated, and always
// has the same value number.
static ValueNum VNForROH()
@@ -450,7 +443,7 @@ public:
// Get a new, unique value number for an expression that we're not equating to some function,
// which is the value of a tree in the given block.
- ValueNum VNForExpr(BasicBlock *block, var_types typ = TYP_UNKNOWN);
+ ValueNum VNForExpr(BasicBlock* block, var_types typ = TYP_UNKNOWN);
// This controls extra tracing of the "evaluation" of "VNF_MapSelect" functions.
#define FEATURE_VN_TRACE_APPLY_SELECTORS 1
@@ -485,13 +478,11 @@ public:
ValueNumPair VNPairApplySelectors(ValueNumPair map, FieldSeqNode* fieldSeq, var_types indType);
- ValueNumPair VNPairApplySelectorsAssign(ValueNumPair map,
- FieldSeqNode* fieldSeq,
- ValueNumPair rhs,
- var_types indType,
- BasicBlock* block)
+ ValueNumPair VNPairApplySelectorsAssign(
+ ValueNumPair map, FieldSeqNode* fieldSeq, ValueNumPair rhs, var_types indType, BasicBlock* block)
{
- return ValueNumPair(VNApplySelectorsAssign(VNK_Liberal, map.GetLiberal(), fieldSeq, rhs.GetLiberal(), indType, block),
+ return ValueNumPair(VNApplySelectorsAssign(VNK_Liberal, map.GetLiberal(), fieldSeq, rhs.GetLiberal(), indType,
+ block),
VNApplySelectorsAssign(VNK_Conservative, map.GetConservative(), fieldSeq,
rhs.GetConservative(), indType, block));
}
@@ -506,6 +497,9 @@ public:
bool srcIsUnsigned = false,
bool hasOverflowCheck = false);
+ // Returns true iff the VN represents an application of VNF_NotAField.
+ bool IsVNNotAField(ValueNum vn);
+
// PtrToLoc values need to express a field sequence as one of their arguments. VN for null represents
// empty sequence, otherwise, "FieldSeq(VN(FieldHandle), restOfSeq)".
ValueNum VNForFieldSeq(FieldSeqNode* fieldSeq);
@@ -518,12 +512,6 @@ public:
// concatenation "fsVN1 || fsVN2".
ValueNum FieldSeqVNAppend(ValueNum fsVN1, ValueNum fsVN2);
- // Requires "lclVarVN" be a value number for a GT_LCL_VAR pointer tree.
- // Requires "fieldSeqVN" be a field sequence value number.
- // Requires "typ" to be a TYP_REF/TYP_BYREF used for VNF_PtrToLoc.
- // When "fieldSeqVN" is VNForNotAField, a unique VN is generated using m_uPtrToLocNotAFieldCount.
- ValueNum VNForPtrToLoc(var_types typ, ValueNum lclVarVN, ValueNum fieldSeqVN);
-
// If "opA" has a PtrToLoc, PtrToArrElem, or PtrToStatic application as its value numbers, and "opB" is an integer
// with a "fieldSeq", returns the VN for the pointer form extended with the field sequence; or else NoVN.
ValueNum ExtendPtrVN(GenTreePtr opA, GenTreePtr opB);
@@ -853,14 +841,15 @@ private:
DECLARE_TYPED_ENUM(ChunkExtraAttribs, BYTE)
{
- CEA_None, // No extra attributes.
- CEA_Const, // This chunk contains constant values.
- CEA_Handle, // This chunk contains handle constants.
- CEA_Func0, // Represents functions of arity 0.
- CEA_Func1, // ...arity 1.
- CEA_Func2, // ...arity 2.
- CEA_Func3, // ...arity 3.
- CEA_Func4, // ...arity 4.
+ CEA_None, // No extra attributes.
+ CEA_Const, // This chunk contains constant values.
+ CEA_Handle, // This chunk contains handle constants.
+ CEA_NotAField, // This chunk contains "not a field" values.
+ CEA_Func0, // Represents functions of arity 0.
+ CEA_Func1, // ...arity 1.
+ CEA_Func2, // ...arity 2.
+ CEA_Func3, // ...arity 3.
+ CEA_Func4, // ...arity 4.
CEA_Count
}
END_DECLARE_TYPED_ENUM(ChunkExtraAttribs, BYTE);
@@ -883,9 +872,14 @@ private:
ChunkExtraAttribs m_attribs;
BasicBlock::loopNumber m_loopNum;
- // Initialize a chunk, starting at "*baseVN", for the given "typ", "attribs", and "loopNum" (using "alloc" for allocations).
+ // Initialize a chunk, starting at "*baseVN", for the given "typ", "attribs", and "loopNum" (using "alloc" for
+ // allocations).
// (Increments "*baseVN" by ChunkSize.)
- Chunk(IAllocator* alloc, ValueNum* baseVN, var_types typ, ChunkExtraAttribs attribs, BasicBlock::loopNumber loopNum);
+ Chunk(IAllocator* alloc,
+ ValueNum* baseVN,
+ var_types typ,
+ ChunkExtraAttribs attribs,
+ BasicBlock::loopNumber loopNum);
// Requires that "m_numUsed < ChunkSize." Returns the offset of the allocated VN within the chunk; the
// actual VN is this added to the "m_baseVN" of the chunk.
@@ -1257,7 +1251,6 @@ private:
{
SRC_Null,
SRC_ZeroMap,
- SRC_NotAField,
SRC_ReadOnlyHeap,
SRC_Void,
SRC_EmptyExcSet,
@@ -1265,10 +1258,6 @@ private:
SRC_NumSpecialRefConsts
};
- // Counter to keep track of all the unique not a field sequences that have been assigned to
- // PtrToLoc, because the ptr was added to an offset that was not a field.
- unsigned m_uPtrToLocNotAFieldCount;
-
// The "values" of special ref consts will be all be "null" -- their differing meanings will
// be carried by the distinct value numbers.
static class Object* s_specialRefConsts[SRC_NumSpecialRefConsts];
diff --git a/src/jit/valuenumfuncs.h b/src/jit/valuenumfuncs.h
index 064a33707b..eb17aedf28 100644
--- a/src/jit/valuenumfuncs.h
+++ b/src/jit/valuenumfuncs.h
@@ -11,9 +11,10 @@ ValueNumFuncDef(MapStore, 3, false, false, false)
ValueNumFuncDef(MapSelect, 2, false, false, false)
ValueNumFuncDef(FieldSeq, 2, false, false, false) // Sequence (VN of null == empty) of (VN's of) field handles.
+ValueNumFuncDef(NotAField, 0, false, false, false) // Value number function for FieldSeqStore::NotAField.
ValueNumFuncDef(ZeroMap, 0, false, false, false) // The "ZeroMap": indexing at any index yields "zero of the desired type".
-ValueNumFuncDef(PtrToLoc, 3, false, false, false) // Pointer (byref) to a local variable. Args: VN's of: 0: var num, 1: FieldSeq, 2: Unique value for this PtrToLoc.
+ValueNumFuncDef(PtrToLoc, 2, false, false, false) // Pointer (byref) to a local variable. Args: VN's of: 0: var num, 1: FieldSeq.
ValueNumFuncDef(PtrToArrElem, 4, false, false, false) // Pointer (byref) to an array element. Args: 0: array elem type eq class var_types value, VN's of: 1: array, 2: index, 3: FieldSeq.
ValueNumFuncDef(PtrToStatic, 1, false, false, false) // Pointer (byref) to a static variable (or possibly a field thereof, if the static variable is a struct). Args: 0: FieldSeq, first element
// of which is the static var.
@@ -99,6 +100,7 @@ ValueNumFuncDef(GetsharedNongcstaticBase, 2, false, true, true)
ValueNumFuncDef(GetsharedGcstaticBaseNoctor, 1, false, true, true)
ValueNumFuncDef(GetsharedNongcstaticBaseNoctor, 1, false, true, true)
ValueNumFuncDef(ReadyToRunStaticBase, 1, false, true, true)
+ValueNumFuncDef(ReadyToRunGenericStaticBase, 2, false, true, true)
ValueNumFuncDef(GetsharedGcstaticBaseDynamicclass, 2, false, true, true)
ValueNumFuncDef(GetsharedNongcstaticBaseDynamicclass, 2, false, true, true)
ValueNumFuncDef(GetgenericsGcthreadstaticBase, 1, false, true, true)
diff --git a/src/md/ceefilegen/cceegen.cpp b/src/md/ceefilegen/cceegen.cpp
index 268093cd6b..0cf0780d15 100644
--- a/src/md/ceefilegen/cceegen.cpp
+++ b/src/md/ceefilegen/cceegen.cpp
@@ -572,18 +572,20 @@ HRESULT CCeeGen::emitMetaData(IMetaDataEmit *emitter, CeeSection* section, DWORD
_ASSERTE(metaDataLen <= buffLen);
#ifdef ENC_DELTA_HACK
- extern int __cdecl fclose(FILE *);
- WCHAR szFileName[256];
- DWORD len = GetEnvironmentVariable(W("COMP_ENC_EMIT"), szFileName, ARRAYSIZE(szFileName));
- _ASSERTE(len < (ARRAYSIZE(szFileName) + 6)); // +6 for the .dmeta
- if (len > 0 && len < (ARRAYSIZE(szFileName) + 6))
{
- wcscat_s(szFileName, ARRAYSIZE(szFileName), W(".dmeta"));
- FILE *pDelta;
- int ec = _wfopen_s(&pDelta, szFileName, W("wb"));
- if (FAILED(ec)) { return HRESULT_FROM_WIN32(ERROR_OPEN_FAILED); }
- fwrite(buffer, 1, metaDataLen, pDelta);
- fclose(pDelta);
+ extern int __cdecl fclose(FILE *);
+ WCHAR szFileName[256];
+ DWORD len = GetEnvironmentVariable(W("COMP_ENC_EMIT"), szFileName, ARRAYSIZE(szFileName));
+ _ASSERTE(len < (ARRAYSIZE(szFileName) + 6)); // +6 for the .dmeta
+ if (len > 0 && len < (ARRAYSIZE(szFileName) + 6))
+ {
+ wcscat_s(szFileName, ARRAYSIZE(szFileName), W(".dmeta"));
+ FILE *pDelta;
+ int ec = _wfopen_s(&pDelta, szFileName, W("wb"));
+ if (FAILED(ec)) { return HRESULT_FROM_WIN32(ERROR_OPEN_FAILED); }
+ fwrite(buffer, 1, metaDataLen, pDelta);
+ fclose(pDelta);
+ }
}
#endif
diff --git a/src/md/winmd/adapter.cpp b/src/md/winmd/adapter.cpp
index 5b4d95cc7c..2c9dd1b9fd 100644
--- a/src/md/winmd/adapter.cpp
+++ b/src/md/winmd/adapter.cpp
@@ -88,6 +88,8 @@ HRESULT CheckIfWinMDAdapterNeeded(IMDCommon *pRawMDCommon)
HRESULT hr;
LPWSTR wszCorVersion = NULL;
WinMDAdapter* pNewAdapter = NULL;
+ ULONG numAssemblyRefs = 0;
+ const char *szClrPortion = NULL;
*ppAdapter = NULL;
@@ -102,7 +104,7 @@ HRESULT CheckIfWinMDAdapterNeeded(IMDCommon *pRawMDCommon)
//------------------------------------------------------------------------------------------------
LPCSTR szVersion;
IfFailGo(pRawMDCommon->GetVersionString(&szVersion));
- const char *szClrPortion = strchr(szVersion, ';');
+ szClrPortion = strchr(szVersion, ';');
if (szClrPortion)
{
pNewAdapter->m_scenario = kWinMDExp;
@@ -148,7 +150,7 @@ HRESULT CheckIfWinMDAdapterNeeded(IMDCommon *pRawMDCommon)
//------------------------------------------------------------------------------------------------
// Find an assemblyRef to mscorlib (required to exist in .winmd files precisely to make the adapter's job easier.
//------------------------------------------------------------------------------------------------
- ULONG numAssemblyRefs = pNewAdapter->m_pRawMetaModelCommonRO->CommonGetRowCount(mdtAssemblyRef);
+ numAssemblyRefs = pNewAdapter->m_pRawMetaModelCommonRO->CommonGetRowCount(mdtAssemblyRef);
pNewAdapter->m_assemblyRefMscorlib = 0;
pNewAdapter->m_fReferencesMscorlibV4 = FALSE;
for (ULONG rid = 1; rid <= numAssemblyRefs; rid++)
@@ -860,10 +862,11 @@ WinMDAdapter::GetTypeRefProps(
HRESULT hr;
ULONG treatment;
+ ULONG treatmentClass;
IfFailGo(GetTypeRefTreatment(tkTypeRef, &treatment));
_ASSERTE(treatment != kTrNotYetInitialized);
- ULONG treatmentClass = treatment & kTrClassMask;
+ treatmentClass = treatment & kTrClassMask;
if (treatmentClass == kTrClassWellKnownRedirected)
{
ULONG nRewritePairIndex = treatment & ~kTrClassMask;
@@ -998,9 +1001,10 @@ WinMDAdapter::GetTypeRefRedirectedInfo(
HRESULT hr;
ULONG treatment;
+ ULONG treatmentClass;
IfFailGo(GetTypeRefTreatment(tkTypeRef, &treatment));
- ULONG treatmentClass = treatment & kTrClassMask;
+ treatmentClass = treatment & kTrClassMask;
if (treatmentClass == kTrClassWellKnownRedirected)
{
*pIndex = (RedirectedTypeIndex)(treatment & ~kTrClassMask);
@@ -1278,11 +1282,14 @@ HRESULT WinMDAdapter::ModifyMethodProps(mdMethodDef tkMethodDef, /*[in, out]*/ D
_ASSERTE(TypeFromToken(tkMethodDef) == mdtMethodDef);
ULONG mdTreatment;
+ DWORD dwAttr;
+ DWORD dwImplFlags;
+ ULONG ulRVA;
IfFailGo(GetMethodDefTreatment(tkMethodDef, &mdTreatment));
- DWORD dwAttr = pdwAttr ? *pdwAttr: 0;
- DWORD dwImplFlags = pdwImplFlags ? *pdwImplFlags : 0;
- ULONG ulRVA = pulRVA ? *pulRVA : 0;
+ dwAttr = pdwAttr ? *pdwAttr: 0;
+ dwImplFlags = pdwImplFlags ? *pdwImplFlags : 0;
+ ulRVA = pulRVA ? *pulRVA : 0;
switch (mdTreatment & kMdTreatmentMask)
{
@@ -2400,9 +2407,12 @@ HRESULT WinMDAdapter::TranslateWinMDAttributeUsageAttribute(mdTypeDef tkTypeDefO
{
IfFailGo(COR_E_BADIMAGEFORMAT);
}
- DWORD wfTargetValue = *(DWORD*)(pbWFUsageBlob + 2);
- *pClrTargetValue = ConvertToClrAttributeTarget(wfTargetValue);
+ {
+ DWORD wfTargetValue = *(DWORD*)(pbWFUsageBlob + 2);
+ *pClrTargetValue = ConvertToClrAttributeTarget(wfTargetValue);
+ }
+
// add AttributeTargets.Method, AttributeTargets.Constructor , AttributeTargets.Property, and AttributeTargets.Event if this is the VersionAttribute
LPCSTR szNamespace;
LPCSTR szName;
diff --git a/src/md/winmd/inc/adapter.h b/src/md/winmd/inc/adapter.h
index e69b620938..e42992f81f 100644
--- a/src/md/winmd/inc/adapter.h
+++ b/src/md/winmd/inc/adapter.h
@@ -136,7 +136,7 @@ public:
static BOOL ConvertWellKnownTypeNameFromClrToWinRT(LPCSTR *pszFullName);
// Map a well-known CLR typename to WinRT typename
- static BOOL WinMDAdapter::ConvertWellKnownTypeNameFromClrToWinRT(LPCSTR *pszNamespace, LPCSTR *pszName);
+ static BOOL ConvertWellKnownTypeNameFromClrToWinRT(LPCSTR *pszNamespace, LPCSTR *pszName);
// Returns names of redirected type 'index'.
static void GetRedirectedTypeInfo(
diff --git a/src/md/winmd/winmdimport.cpp b/src/md/winmd/winmdimport.cpp
index fe80bf0b04..cc983d2bfc 100644
--- a/src/md/winmd/winmdimport.cpp
+++ b/src/md/winmd/winmdimport.cpp
@@ -588,13 +588,15 @@ class WinMDImport : public IMetaDataImport2
*pmb = mdMethodDefNil;
- // check to see if this is a vararg signature
- PCCOR_SIGNATURE pvSigTemp = pvSigBlob;
- if (isCallConv(CorSigUncompressCallingConv(pvSigTemp), IMAGE_CEE_CS_CALLCONV_VARARG))
{
- // Get the fixed part of VARARG signature
- IfFailGo(_GetFixedSigOfVarArg(pvSigBlob, cbSigBlob, &qbSig, &cbSigBlob));
- pvSigBlob = (PCCOR_SIGNATURE) qbSig.Ptr();
+ // check to see if this is a vararg signature
+ PCCOR_SIGNATURE pvSigTemp = pvSigBlob;
+ if (isCallConv(CorSigUncompressCallingConv(pvSigTemp), IMAGE_CEE_CS_CALLCONV_VARARG))
+ {
+ // Get the fixed part of VARARG signature
+ IfFailGo(_GetFixedSigOfVarArg(pvSigBlob, cbSigBlob, &qbSig, &cbSigBlob));
+ pvSigBlob = (PCCOR_SIGNATURE) qbSig.Ptr();
+ }
}
// now iterate all methods in td and compare name and signature
@@ -1654,15 +1656,17 @@ class WinMDImport : public IMetaDataImport2
// Step 1: Call EnumAssemblyRefs with an empty buffer to create the HENUMInternal
IfFailGo(m_pRawAssemblyImport->EnumAssemblyRefs(phEnum, NULL, 0, NULL));
- // Step 2: Increment the cound to include the extra assembly refs
- HENUMInternal *phInternalEnum = static_cast<HENUMInternal*>(*phEnum);
+ {
+ // Step 2: Increment the count to include the extra assembly refs
+ HENUMInternal *phInternalEnum = static_cast<HENUMInternal*>(*phEnum);
- _ASSERTE(phInternalEnum->m_EnumType == MDSimpleEnum);
+ _ASSERTE(phInternalEnum->m_EnumType == MDSimpleEnum);
- _ASSERTE( phInternalEnum->m_ulCount == m_pWinMDAdapter->GetRawAssemblyRefCount());
- int n = m_pWinMDAdapter->GetExtraAssemblyRefCount();
- phInternalEnum->m_ulCount += n;
- phInternalEnum->u.m_ulEnd += n;
+ _ASSERTE( phInternalEnum->m_ulCount == m_pWinMDAdapter->GetRawAssemblyRefCount());
+ int n = m_pWinMDAdapter->GetExtraAssemblyRefCount();
+ phInternalEnum->m_ulCount += n;
+ phInternalEnum->u.m_ulEnd += n;
+ }
// Step 3: Call EnumAssemblyRefs again and pass in the modifed HENUMInternal and the real buffer
IfFailGo(m_pRawAssemblyImport->EnumAssemblyRefs(phEnum, rAssemblyRefs, cMax, pcTokens));
diff --git a/src/mscorlib/Common/PinnableBufferCache.cs b/src/mscorlib/Common/PinnableBufferCache.cs
index fee3e46f46..fc6e13a899 100644
--- a/src/mscorlib/Common/PinnableBufferCache.cs
+++ b/src/mscorlib/Common/PinnableBufferCache.cs
@@ -4,9 +4,6 @@
#define ENABLE
#define MINBUFFERS
using System;
-#if !FEATURE_CORECLR
-using System.Diagnostics.Tracing;
-#endif
using System.Runtime.InteropServices;
using System.Runtime.ConstrainedExecution;
using System.Collections.Generic;
@@ -45,12 +42,6 @@ namespace System
/// Create a PinnableBufferCache that works on any object (it is intended for OverlappedData)
/// This is only used in mscorlib.
/// </summary>
-#if (ENABLE || MINBUFFERS)
-#pragma warning disable 618
- [EnvironmentPermission(SecurityAction.Assert, Unrestricted = true)]
-#pragma warning restore 618
- [System.Security.SecuritySafeCritical]
-#endif
internal PinnableBufferCache(string cacheName, Func<object> factory)
{
m_NotGen2 = new List<object>(DefaultNumberOfBuffers);
@@ -103,7 +94,6 @@ namespace System
/// <summary>
/// Get a object from the buffer manager. If no buffers exist, allocate a new one.
/// </summary>
- [System.Security.SecuritySafeCritical]
internal object Allocate()
{
#if ENABLE
@@ -149,7 +139,6 @@ namespace System
/// <summary>
/// Return a buffer back to the buffer manager.
/// </summary>
- [System.Security.SecuritySafeCritical]
internal void Free(object buffer)
{
#if ENABLE
@@ -188,7 +177,6 @@ namespace System
/// Called when we don't have any buffers in our free list to give out.
/// </summary>
/// <returns></returns>
- [System.Security.SecuritySafeCritical]
private void Restock(out object returnBuffer)
{
lock (this)
@@ -241,7 +229,6 @@ namespace System
/// <summary>
/// See if we can promote the buffers to the free list. Returns true if sucessful.
/// </summary>
- [System.Security.SecuritySafeCritical]
private bool AgePendingBuffers()
{
if (m_gen1CountAtLastRestock < GC.CollectionCount(GC.MaxGeneration - 1))
@@ -317,7 +304,6 @@ namespace System
/// otherwise, we root the cache to the Gen2GcCallback object, and leak the cache even when
/// the application no longer needs it.
/// </summary>
- [System.Security.SecuritySafeCritical]
private static bool Gen2GcCallbackFunc(object targetObj)
{
return ((PinnableBufferCache)(targetObj)).TrimFreeListIfNeeded();
@@ -328,7 +314,6 @@ namespace System
/// NOTE: DO NOT CALL THIS DIRECTLY FROM THE GEN2GCCALLBACK. INSTEAD CALL IT VIA A STATIC FUNCTION (SEE ABOVE).
/// If you register a non-static function as a callback, then this object will be leaked.
/// </summary>
- [System.Security.SecuritySafeCritical]
private bool TrimFreeListIfNeeded()
{
int curMSec = Environment.TickCount;
@@ -481,7 +466,6 @@ namespace System
/// </summary>
internal sealed class Gen2GcCallback : CriticalFinalizerObject
{
- [System.Security.SecuritySafeCritical]
public Gen2GcCallback()
: base()
{
@@ -506,14 +490,12 @@ namespace System
private Func<object, bool> m_callback;
private GCHandle m_weakTargetObj;
- [System.Security.SecuritySafeCritical]
private void Setup(Func<object, bool> callback, object targetObj)
{
m_callback = callback;
m_weakTargetObj = GCHandle.Alloc(targetObj, GCHandleType.Weak);
}
- [System.Security.SecuritySafeCritical]
~Gen2GcCallback()
{
// Check to see if the target object is still alive.
@@ -549,8 +531,6 @@ namespace System
#endregion
}
-
-#if FEATURE_CORECLR
internal sealed class PinnableBufferCacheEventSource
{
public static readonly PinnableBufferCacheEventSource Log = new PinnableBufferCacheEventSource();
@@ -581,86 +561,9 @@ namespace System
return 0;
}
- [System.Security.SecuritySafeCritical]
static internal unsafe long AddressOfObject(byte[] array)
{
return 0;
}
}
-#else
- /// <summary>
- /// PinnableBufferCacheEventSource is a private eventSource that we are using to
- /// debug and monitor the effectiveness of PinnableBufferCache
- /// </summary>
-#if PINNABLEBUFFERCACHE_MSCORLIB
- [EventSource(Name = "Microsoft-DotNETRuntime-PinnableBufferCache")]
-#else
- [EventSource(Name = "Microsoft-DotNETRuntime-PinnableBufferCache-System")]
-#endif
- internal sealed class PinnableBufferCacheEventSource : EventSource
- {
- public static readonly PinnableBufferCacheEventSource Log = new PinnableBufferCacheEventSource();
-
- [Event(1, Level = EventLevel.Verbose)]
- public void DebugMessage(string message) { if (IsEnabled()) WriteEvent(1, message); }
- [Event(2, Level = EventLevel.Verbose)]
- public void DebugMessage1(string message, long value) { if (IsEnabled()) WriteEvent(2, message, value); }
- [Event(3, Level = EventLevel.Verbose)]
- public void DebugMessage2(string message, long value1, long value2) { if (IsEnabled()) WriteEvent(3, message, value1, value2); }
- [Event(18, Level = EventLevel.Verbose)]
- public void DebugMessage3(string message, long value1, long value2, long value3) { if (IsEnabled()) WriteEvent(18, message, value1, value2, value3); }
-
- [Event(4)]
- public void Create(string cacheName) { if (IsEnabled()) WriteEvent(4, cacheName); }
-
- [Event(5, Level = EventLevel.Verbose)]
- public void AllocateBuffer(string cacheName, ulong objectId, int objectHash, int objectGen, int freeCountAfter) { if (IsEnabled()) WriteEvent(5, cacheName, objectId, objectHash, objectGen, freeCountAfter); }
- [Event(6)]
- public void AllocateBufferFromNotGen2(string cacheName, int notGen2CountAfter) { if (IsEnabled()) WriteEvent(6, cacheName, notGen2CountAfter); }
- [Event(7)]
- public void AllocateBufferCreatingNewBuffers(string cacheName, int totalBuffsBefore, int objectCount) { if (IsEnabled()) WriteEvent(7, cacheName, totalBuffsBefore, objectCount); }
- [Event(8)]
- public void AllocateBufferAged(string cacheName, int agedCount) { if (IsEnabled()) WriteEvent(8, cacheName, agedCount); }
- [Event(9)]
- public void AllocateBufferFreeListEmpty(string cacheName, int notGen2CountBefore) { if (IsEnabled()) WriteEvent(9, cacheName, notGen2CountBefore); }
-
- [Event(10, Level = EventLevel.Verbose)]
- public void FreeBuffer(string cacheName, ulong objectId, int objectHash, int freeCountBefore) { if (IsEnabled()) WriteEvent(10, cacheName, objectId, objectHash, freeCountBefore); }
- [Event(11)]
- public void FreeBufferStillTooYoung(string cacheName, int notGen2CountBefore) { if (IsEnabled()) WriteEvent(11, cacheName, notGen2CountBefore); }
-
- [Event(13)]
- public void TrimCheck(string cacheName, int totalBuffs, bool neededMoreThanFreeList, int deltaMSec) { if (IsEnabled()) WriteEvent(13, cacheName, totalBuffs, neededMoreThanFreeList, deltaMSec); }
- [Event(14)]
- public void TrimFree(string cacheName, int totalBuffs, int freeListCount, int toBeFreed) { if (IsEnabled()) WriteEvent(14, cacheName, totalBuffs, freeListCount, toBeFreed); }
- [Event(15)]
- public void TrimExperiment(string cacheName, int totalBuffs, int freeListCount, int numTrimTrial) { if (IsEnabled()) WriteEvent(15, cacheName, totalBuffs, freeListCount, numTrimTrial); }
- [Event(16)]
- public void TrimFreeSizeOK(string cacheName, int totalBuffs, int freeListCount) { if (IsEnabled()) WriteEvent(16, cacheName, totalBuffs, freeListCount); }
- [Event(17)]
- public void TrimFlush(string cacheName, int totalBuffs, int freeListCount, int notGen2CountBefore) { if (IsEnabled()) WriteEvent(17, cacheName, totalBuffs, freeListCount, notGen2CountBefore); }
- [Event(20)]
- public void AgePendingBuffersResults(string cacheName, int promotedToFreeListCount, int heldBackCount) { if (IsEnabled()) WriteEvent(20, cacheName, promotedToFreeListCount, heldBackCount); }
- [Event(21)]
- public void WalkFreeListResult(string cacheName, int freeListCount, int gen0BuffersInFreeList) { if (IsEnabled()) WriteEvent(21, cacheName, freeListCount, gen0BuffersInFreeList); }
-
-
- static internal ulong AddressOf(object obj)
- {
- var asByteArray = obj as byte[];
- if (asByteArray != null)
- return (ulong)AddressOfByteArray(asByteArray);
- return 0;
- }
-
- [System.Security.SecuritySafeCritical]
- static internal unsafe long AddressOfByteArray(byte[] array)
- {
- if (array == null)
- return 0;
- fixed (byte* ptr = array)
- return (long)(ptr - 2 * sizeof(void*));
- }
- }
-#endif
}
diff --git a/src/mscorlib/System.Private.CoreLib.csproj b/src/mscorlib/System.Private.CoreLib.csproj
index c14ce422fb..f1f944a6f6 100644
--- a/src/mscorlib/System.Private.CoreLib.csproj
+++ b/src/mscorlib/System.Private.CoreLib.csproj
@@ -1,5 +1,9 @@
<?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' and '$(UseLegacyCompiler)'!='true'" />
+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<!-- Include common build properties -->
diff --git a/src/mscorlib/System.Private.CoreLib.sln b/src/mscorlib/System.Private.CoreLib.sln
index 4ab28af2d9..60a2316957 100644
--- a/src/mscorlib/System.Private.CoreLib.sln
+++ b/src/mscorlib/System.Private.CoreLib.sln
@@ -5,6 +5,11 @@ VisualStudioVersion = 14.0.25420.1
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("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E16B1C86-C275-495B-80D6-7CE8196A18B4}"
+ ProjectSection(SolutionItems) = preProject
+ model.xml = model.xml
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Checked|amd64 = Checked|amd64
diff --git a/src/mscorlib/corefx/Debug.cs b/src/mscorlib/corefx/Debug.cs
new file mode 100644
index 0000000000..3398c0e31e
--- /dev/null
+++ b/src/mscorlib/corefx/Debug.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;
+
+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.Errors.cs b/src/mscorlib/corefx/Interop/Unix/Interop.Errors.cs
new file mode 100644
index 0000000000..4248434db3
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Unix/Interop.Errors.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.
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ /// <summary>Common Unix errno error codes.</summary>
+ internal enum Error
+ {
+ // These values were defined in src/Native/System.Native/fxerrno.h
+ //
+ // They compare against values obtained via Interop.Sys.GetLastError() not Marshal.GetLastWin32Error()
+ // which obtains the raw errno that varies between unixes. The strong typing as an enum is meant to
+ // prevent confusing the two. Casting to or from int is suspect. Use GetLastErrorInfo() if you need to
+ // correlate these to the underlying platform values or obtain the corresponding error message.
+ //
+
+ SUCCESS = 0,
+
+ E2BIG = 0x10001, // Argument list too long.
+ EACCES = 0x10002, // Permission denied.
+ EADDRINUSE = 0x10003, // Address in use.
+ EADDRNOTAVAIL = 0x10004, // Address not available.
+ EAFNOSUPPORT = 0x10005, // Address family not supported.
+ EAGAIN = 0x10006, // Resource unavailable, try again (same value as EWOULDBLOCK),
+ EALREADY = 0x10007, // Connection already in progress.
+ EBADF = 0x10008, // Bad file descriptor.
+ EBADMSG = 0x10009, // Bad message.
+ EBUSY = 0x1000A, // Device or resource busy.
+ ECANCELED = 0x1000B, // Operation canceled.
+ ECHILD = 0x1000C, // No child processes.
+ ECONNABORTED = 0x1000D, // Connection aborted.
+ ECONNREFUSED = 0x1000E, // Connection refused.
+ ECONNRESET = 0x1000F, // Connection reset.
+ EDEADLK = 0x10010, // Resource deadlock would occur.
+ EDESTADDRREQ = 0x10011, // Destination address required.
+ EDOM = 0x10012, // Mathematics argument out of domain of function.
+ EDQUOT = 0x10013, // Reserved.
+ EEXIST = 0x10014, // File exists.
+ EFAULT = 0x10015, // Bad address.
+ EFBIG = 0x10016, // File too large.
+ EHOSTUNREACH = 0x10017, // Host is unreachable.
+ EIDRM = 0x10018, // Identifier removed.
+ EILSEQ = 0x10019, // Illegal byte sequence.
+ EINPROGRESS = 0x1001A, // Operation in progress.
+ EINTR = 0x1001B, // Interrupted function.
+ EINVAL = 0x1001C, // Invalid argument.
+ EIO = 0x1001D, // I/O error.
+ EISCONN = 0x1001E, // Socket is connected.
+ EISDIR = 0x1001F, // Is a directory.
+ ELOOP = 0x10020, // Too many levels of symbolic links.
+ EMFILE = 0x10021, // File descriptor value too large.
+ EMLINK = 0x10022, // Too many links.
+ EMSGSIZE = 0x10023, // Message too large.
+ EMULTIHOP = 0x10024, // Reserved.
+ ENAMETOOLONG = 0x10025, // Filename too long.
+ ENETDOWN = 0x10026, // Network is down.
+ ENETRESET = 0x10027, // Connection aborted by network.
+ ENETUNREACH = 0x10028, // Network unreachable.
+ ENFILE = 0x10029, // Too many files open in system.
+ ENOBUFS = 0x1002A, // No buffer space available.
+ ENODEV = 0x1002C, // No such device.
+ ENOENT = 0x1002D, // No such file or directory.
+ ENOEXEC = 0x1002E, // Executable file format error.
+ ENOLCK = 0x1002F, // No locks available.
+ ENOLINK = 0x10030, // Reserved.
+ ENOMEM = 0x10031, // Not enough space.
+ ENOMSG = 0x10032, // No message of the desired type.
+ ENOPROTOOPT = 0x10033, // Protocol not available.
+ ENOSPC = 0x10034, // No space left on device.
+ ENOSYS = 0x10037, // Function not supported.
+ ENOTCONN = 0x10038, // The socket is not connected.
+ ENOTDIR = 0x10039, // Not a directory or a symbolic link to a directory.
+ ENOTEMPTY = 0x1003A, // Directory not empty.
+ ENOTSOCK = 0x1003C, // Not a socket.
+ ENOTSUP = 0x1003D, // Not supported (same value as EOPNOTSUP).
+ ENOTTY = 0x1003E, // Inappropriate I/O control operation.
+ ENXIO = 0x1003F, // No such device or address.
+ EOVERFLOW = 0x10040, // Value too large to be stored in data type.
+ EPERM = 0x10042, // Operation not permitted.
+ EPIPE = 0x10043, // Broken pipe.
+ EPROTO = 0x10044, // Protocol error.
+ EPROTONOSUPPORT = 0x10045, // Protocol not supported.
+ EPROTOTYPE = 0x10046, // Protocol wrong type for socket.
+ ERANGE = 0x10047, // Result too large.
+ EROFS = 0x10048, // Read-only file system.
+ ESPIPE = 0x10049, // Invalid seek.
+ ESRCH = 0x1004A, // No such process.
+ ESTALE = 0x1004B, // Reserved.
+ ETIMEDOUT = 0x1004D, // Connection timed out.
+ ETXTBSY = 0x1004E, // Text file busy.
+ EXDEV = 0x1004F, // Cross-device link.
+ ESOCKTNOSUPPORT = 0x1005E, // Socket type not supported.
+ EPFNOSUPPORT = 0x10060, // Protocol family not supported.
+ ESHUTDOWN = 0x1006C, // Socket shutdown.
+ EHOSTDOWN = 0x10070, // Host is down.
+ ENODATA = 0x10071, // No data available.
+
+ // POSIX permits these to have the same value and we make them always equal so
+ // that CoreFX cannot introduce a dependency on distinguishing between them that
+ // would not work on all platforms.
+ EOPNOTSUPP = ENOTSUP, // Operation not supported on socket.
+ EWOULDBLOCK = EAGAIN, // Operation would block.
+ }
+
+
+ // Represents a platform-agnostic Error and underlying platform-specific errno
+ internal struct ErrorInfo
+ {
+ private Error _error;
+ private int _rawErrno;
+
+ internal ErrorInfo(int errno)
+ {
+ _error = Interop.Sys.ConvertErrorPlatformToPal(errno);
+ _rawErrno = errno;
+ }
+
+ internal ErrorInfo(Error error)
+ {
+ _error = error;
+ _rawErrno = -1;
+ }
+
+ internal Error Error
+ {
+ get { return _error; }
+ }
+
+ internal int RawErrno
+ {
+ get { return _rawErrno == -1 ? (_rawErrno = Interop.Sys.ConvertErrorPalToPlatform(_error)) : _rawErrno; }
+ }
+
+ internal string GetErrorMessage()
+ {
+ return Interop.Sys.StrError(RawErrno);
+ }
+
+ public override string ToString()
+ {
+ return string.Format(
+ "RawErrno: {0} Error: {1} GetErrorMessage: {2}", // No localization required; text is member names used for debugging purposes
+ RawErrno, Error, GetErrorMessage());
+ }
+ }
+
+ internal partial class Sys
+ {
+ internal static Error GetLastError()
+ {
+ return ConvertErrorPlatformToPal(Marshal.GetLastWin32Error());
+ }
+
+ internal static ErrorInfo GetLastErrorInfo()
+ {
+ return new ErrorInfo(Marshal.GetLastWin32Error());
+ }
+
+ internal static unsafe string StrError(int platformErrno)
+ {
+ int maxBufferLength = 1024; // should be long enough for most any UNIX error
+ byte* buffer = stackalloc byte[maxBufferLength];
+ byte* message = StrErrorR(platformErrno, buffer, maxBufferLength);
+
+ if (message == null)
+ {
+ // This means the buffer was not large enough, but still contains
+ // as much of the error message as possible and is guaranteed to
+ // be null-terminated. We're not currently resizing/retrying because
+ // maxBufferLength is large enough in practice, but we could do
+ // so here in the future if necessary.
+ message = buffer;
+ }
+
+ return Marshal.PtrToStringAnsi((IntPtr)message);
+ }
+
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_ConvertErrorPlatformToPal")]
+ internal static extern Error ConvertErrorPlatformToPal(int platformErrno);
+
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_ConvertErrorPalToPlatform")]
+ internal static extern int ConvertErrorPalToPlatform(Error error);
+
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_StrErrorR")]
+ private static unsafe extern byte* StrErrorR(int platformErrno, byte* buffer, int bufferSize);
+ }
+}
+
+// NOTE: extension method can't be nested inside Interop class.
+internal static class InteropErrorExtensions
+{
+ // Intended usage is e.g. Interop.Error.EFAIL.Info() for brevity
+ // vs. new Interop.ErrorInfo(Interop.Error.EFAIL) for synthesizing
+ // errors. Errors originated from the system should be obtained
+ // via GetLastErrorInfo(), not GetLastError().Info() as that will
+ // convert twice, which is not only inefficient but also lossy if
+ // we ever encounter a raw errno that no equivalent in the Error
+ // enum.
+ public static Interop.ErrorInfo Info(this Interop.Error error)
+ {
+ return new Interop.ErrorInfo(error);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Unix/Interop.IOErrors.cs b/src/mscorlib/corefx/Interop/Unix/Interop.IOErrors.cs
new file mode 100644
index 0000000000..e9d6ce61d6
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Unix/Interop.IOErrors.cs
@@ -0,0 +1,170 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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.IO;
+using System.Runtime.InteropServices;
+using Microsoft.Win32.SafeHandles;
+
+internal static partial class Interop
+{
+ private static void ThrowExceptionForIoErrno(ErrorInfo errorInfo, string path, bool isDirectory, Func<ErrorInfo, ErrorInfo> errorRewriter)
+ {
+ Debug.Assert(errorInfo.Error != Error.SUCCESS);
+ Debug.Assert(errorInfo.Error != Error.EINTR, "EINTR errors should be handled by the native shim and never bubble up to managed code");
+
+ if (errorRewriter != null)
+ {
+ errorInfo = errorRewriter(errorInfo);
+ }
+
+ throw Interop.GetExceptionForIoErrno(errorInfo, path, isDirectory);
+ }
+
+ internal static void CheckIo(Error error, string path = null, bool isDirectory = false, Func<ErrorInfo, ErrorInfo> errorRewriter = null)
+ {
+ if (error != Interop.Error.SUCCESS)
+ {
+ ThrowExceptionForIoErrno(error.Info(), path, isDirectory, errorRewriter);
+ }
+ }
+
+ /// <summary>
+ /// Validates the result of system call that returns greater than or equal to 0 on success
+ /// and less than 0 on failure, with errno set to the error code.
+ /// If the system call failed for any reason, an exception is thrown. Otherwise, the system call succeeded.
+ /// </summary>
+ /// <param name="result">The result of the system call.</param>
+ /// <param name="path">The path with which this error is associated. This may be null.</param>
+ /// <param name="isDirectory">true if the <paramref name="path"/> is known to be a directory; otherwise, false.</param>
+ /// <param name="errorRewriter">Optional function to change an error code prior to processing it.</param>
+ /// <returns>
+ /// On success, returns the non-negative result long that was validated.
+ /// </returns>
+ internal static long CheckIo(long result, string path = null, bool isDirectory = false, Func<ErrorInfo, ErrorInfo> errorRewriter = null)
+ {
+ if (result < 0)
+ {
+ ThrowExceptionForIoErrno(Sys.GetLastErrorInfo(), path, isDirectory, errorRewriter);
+ }
+
+ return result;
+ }
+
+ /// <summary>
+ /// Validates the result of system call that returns greater than or equal to 0 on success
+ /// and less than 0 on failure, with errno set to the error code.
+ /// If the system call failed for any reason, an exception is thrown. Otherwise, the system call succeeded.
+ /// </summary>
+ /// <returns>
+ /// On success, returns the non-negative result int that was validated.
+ /// </returns>
+ internal static int CheckIo(int result, string path = null, bool isDirectory = false, Func<ErrorInfo, ErrorInfo> errorRewriter = null)
+ {
+ CheckIo((long)result, path, isDirectory, errorRewriter);
+
+ return result;
+ }
+
+ /// <summary>
+ /// Validates the result of system call that returns greater than or equal to 0 on success
+ /// and less than 0 on failure, with errno set to the error code.
+ /// If the system call failed for any reason, an exception is thrown. Otherwise, the system call succeeded.
+ /// </summary>
+ /// <returns>
+ /// On success, returns the non-negative result IntPtr that was validated.
+ /// </returns>
+ internal static IntPtr CheckIo(IntPtr result, string path = null, bool isDirectory = false, Func<ErrorInfo, ErrorInfo> errorRewriter = null)
+ {
+ CheckIo((long)result, path, isDirectory, errorRewriter);
+
+ return result;
+ }
+
+ /// <summary>
+ /// Validates the result of system call that returns greater than or equal to 0 on success
+ /// and less than 0 on failure, with errno set to the error code.
+ /// If the system call failed for any reason, an exception is thrown. Otherwise, the system call succeeded.
+ /// </summary>
+ /// <returns>
+ /// On success, returns the valid SafeFileHandle that was validated.
+ /// </returns>
+ internal static TSafeHandle CheckIo<TSafeHandle>(TSafeHandle handle, string path = null, bool isDirectory = false, Func<ErrorInfo, ErrorInfo> errorRewriter = null)
+ where TSafeHandle : SafeHandle
+ {
+ if (handle.IsInvalid)
+ {
+ ThrowExceptionForIoErrno(Sys.GetLastErrorInfo(), path, isDirectory, errorRewriter);
+ }
+
+ return handle;
+ }
+
+ /// <summary>
+ /// Gets an Exception to represent the supplied error info.
+ /// </summary>
+ /// <param name="error">The error info</param>
+ /// <param name="path">The path with which this error is associated. This may be null.</param>
+ /// <param name="isDirectory">true if the <paramref name="path"/> is known to be a directory; otherwise, false.</param>
+ /// <returns></returns>
+ internal static Exception GetExceptionForIoErrno(ErrorInfo errorInfo, string path = null, bool isDirectory = false)
+ {
+ // Translate the errno into a known set of exception types. For cases where multiple errnos map
+ // to the same exception type, include an inner exception with the details.
+ switch (errorInfo.Error)
+ {
+ case Error.ENOENT:
+ if (isDirectory)
+ {
+ return !string.IsNullOrEmpty(path) ?
+ new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, path)) :
+ new DirectoryNotFoundException(SR.IO_PathNotFound_NoPathName);
+ }
+ else
+ {
+ return !string.IsNullOrEmpty(path) ?
+ new FileNotFoundException(SR.Format(SR.IO_FileNotFound_FileName, path), path) :
+ new FileNotFoundException(SR.IO_FileNotFound);
+ }
+
+ case Error.EACCES:
+ case Error.EBADF:
+ case Error.EPERM:
+ Exception inner = GetIOException(errorInfo);
+ return !string.IsNullOrEmpty(path) ?
+ new UnauthorizedAccessException(SR.Format(SR.UnauthorizedAccess_IODenied_Path, path), inner) :
+ new UnauthorizedAccessException(SR.UnauthorizedAccess_IODenied_NoPathName, inner);
+
+ case Error.ENAMETOOLONG:
+ return new PathTooLongException(SR.IO_PathTooLong);
+
+ case Error.EWOULDBLOCK:
+ return !string.IsNullOrEmpty(path) ?
+ new IOException(SR.Format(SR.IO_SharingViolation_File, path), errorInfo.RawErrno) :
+ new IOException(SR.IO_SharingViolation_NoFileName, errorInfo.RawErrno);
+
+ case Error.ECANCELED:
+ return new OperationCanceledException();
+
+ case Error.EFBIG:
+ return new ArgumentOutOfRangeException("value", SR.ArgumentOutOfRange_FileLengthTooBig);
+
+ case Error.EEXIST:
+ if (!string.IsNullOrEmpty(path))
+ {
+ return new IOException(SR.Format(SR.IO_FileExists_Name, path), errorInfo.RawErrno);
+ }
+ goto default;
+
+ default:
+ return GetIOException(errorInfo);
+ }
+ }
+
+ internal static Exception GetIOException(Interop.ErrorInfo errorInfo)
+ {
+ return new IOException(errorInfo.GetErrorMessage(), errorInfo.RawErrno);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Unix/Interop.Libraries.cs b/src/mscorlib/corefx/Interop/Unix/Interop.Libraries.cs
index f8c5b26e44..a11a23ce8c 100644
--- a/src/mscorlib/corefx/Interop/Unix/Interop.Libraries.cs
+++ b/src/mscorlib/corefx/Interop/Unix/Interop.Libraries.cs
@@ -7,5 +7,12 @@ internal static partial class Interop
private static partial class Libraries
{
internal const string GlobalizationInterop = "System.Globalization.Native"; // CoreFX wrappers for ICU
+ // Shims
+ internal const string SystemNative = "System.Native";
+ internal const string HttpNative = "System.Net.Http.Native";
+ internal const string NetSecurityNative = "System.Net.Security.Native";
+ internal const string CryptoNative = "System.Security.Cryptography.Native.OpenSsl";
+ internal const string GlobalizationNative = "System.Globalization.Native";
+ internal const string CompressionNative = "System.IO.Compression.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
index 6acf55e17b..eb9e0743bc 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Collation.cs
+++ b/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Collation.cs
@@ -13,7 +13,7 @@ internal static partial class Interop
{
[SecurityCritical]
[DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetSortHandle")]
- internal unsafe static extern SafeSortHandle GetSortHandle(byte[] localeName);
+ internal unsafe static extern ResultCode GetSortHandle(byte[] localeName, out SafeSortHandle sortHandle);
[SecurityCritical]
[DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_CloseSortHandle")]
@@ -53,6 +53,9 @@ internal static partial class Interop
[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();
+
[SecurityCritical]
internal class SafeSortHandle : SafeHandle
{
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Idna.cs b/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Idna.cs
new file mode 100644
index 0000000000..43c72281ae
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Idna.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.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class GlobalizationInterop
+ {
+ internal const int AllowUnassigned = 0x1;
+ internal const int UseStd3AsciiRules = 0x2;
+
+ [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_ToAscii")]
+ internal static unsafe extern int ToAscii(uint flags, char* src, int srcLen, char* dstBuffer, int dstBufferCapacity);
+
+ [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_ToUnicode")]
+ internal static unsafe extern int ToUnicode(uint flags, char* src, int srcLen, char* dstBuffer, int dstBufferCapacity);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Locale.cs b/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Locale.cs
index 3912581c73..fcea708ee8 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Locale.cs
+++ b/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Locale.cs
@@ -33,5 +33,8 @@ internal static partial class Interop
[DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetLocaleInfoGroupingSizes")]
[return: MarshalAs(UnmanagedType.Bool)]
internal unsafe static extern bool GetLocaleInfoGroupingSizes(string localeName, uint localeGroupingData, ref int primaryGroupSize, ref int secondaryGroupSize);
+
+ [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetLocales")]
+ internal unsafe static extern int GetLocales([Out] Char[] value, int valueLength);
}
}
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Normalization.cs b/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Normalization.cs
new file mode 100644
index 0000000000..c4cb9fb851
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Normalization.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.Text;
+
+internal static partial class Interop
+{
+ internal static partial class GlobalizationInterop
+ {
+ [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_IsNormalized")]
+ internal static extern int IsNormalized(NormalizationForm normalizationForm, string src, int srcLen);
+
+ [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_NormalizeString")]
+ internal static extern int NormalizeString(NormalizationForm normalizationForm, string src, int srcLen, [Out] char[] dstBuffer, int dstBufferCapacity);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.ResultCode.cs b/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.ResultCode.cs
index 4621580063..cca6ae4dcb 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.ResultCode.cs
+++ b/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.ResultCode.cs
@@ -12,6 +12,7 @@ internal static partial class Interop
Success = 0,
UnknownError = 1,
InsufficentBuffer = 2,
+ OutOfMemory = 3
}
}
}
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Close.cs b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Close.cs
new file mode 100644
index 0000000000..8d192398a0
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Close.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 static partial class Interop
+{
+ internal static partial class Sys
+ {
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_Close", SetLastError = true)]
+ internal static extern int Close(IntPtr fd);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.FLock.cs b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.FLock.cs
new file mode 100644
index 0000000000..22934a3e77
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.FLock.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;
+using System.Runtime.InteropServices;
+using Microsoft.Win32.SafeHandles;
+
+internal static partial class Interop
+{
+ internal static partial class Sys
+ {
+ internal enum LockOperations : int
+ {
+ LOCK_SH = 1, /* shared lock */
+ LOCK_EX = 2, /* exclusive lock */
+ LOCK_NB = 4, /* don't block when locking*/
+ LOCK_UN = 8, /* unlock */
+ }
+
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_FLock", SetLastError = true)]
+ internal static extern int FLock(SafeFileHandle fd, LockOperations operation);
+
+ /// <summary>
+ /// Exposing this for SafeFileHandle.ReleaseHandle() to call.
+ /// Normal callers should use FLock(SafeFileHandle fd).
+ /// </summary>
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_FLock", SetLastError = true)]
+ internal static extern int FLock(IntPtr fd, LockOperations operation);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.FSync.cs b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.FSync.cs
new file mode 100644
index 0000000000..e3ab970931
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.FSync.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.Runtime.InteropServices;
+using Microsoft.Win32.SafeHandles;
+
+internal static partial class Interop
+{
+ internal static partial class Sys
+ {
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_FSync", SetLastError = true)]
+ internal static extern int FSync(SafeFileHandle fd);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.FTruncate.cs b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.FTruncate.cs
new file mode 100644
index 0000000000..5dad650362
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.FTruncate.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.Runtime.InteropServices;
+using Microsoft.Win32.SafeHandles;
+
+internal static partial class Interop
+{
+ internal static partial class Sys
+ {
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_FTruncate", SetLastError = true)]
+ internal static extern int FTruncate(SafeFileHandle fd, long length);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Fcntl.cs b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Fcntl.cs
new file mode 100644
index 0000000000..23b48a4f5d
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Fcntl.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.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Sys
+ {
+ internal enum LockType : short
+ {
+ F_WRLCK = 1, // exclusive or write lock
+ F_UNLCK = 2 // unlock
+ }
+
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_LockFileRegion", SetLastError=true)]
+ internal static extern int LockFileRegion(SafeHandle fd, long offset, long length, LockType lockType);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.GetCwd.cs b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.GetCwd.cs
new file mode 100644
index 0000000000..724e342342
--- /dev/null
+++ b/src/mscorlib/corefx/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)
+ {
+ 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
new file mode 100644
index 0000000000..33664c4d39
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.GetUnixName.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.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/Unix/System.Native/Interop.LSeek.cs b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.LSeek.cs
new file mode 100644
index 0000000000..7f8df7c6bf
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.LSeek.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.Runtime.InteropServices;
+using Microsoft.Win32.SafeHandles;
+
+internal static partial class Interop
+{
+ internal static partial class Sys
+ {
+ internal enum SeekWhence
+ {
+ SEEK_SET = 0,
+ SEEK_CUR = 1,
+ SEEK_END = 2
+ }
+
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_LSeek", SetLastError = true)]
+ internal static extern long LSeek(SafeFileHandle fd, long offset, SeekWhence whence);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.MksTemps.cs b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.MksTemps.cs
new file mode 100644
index 0000000000..b8694d9007
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.MksTemps.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;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Sys
+ {
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_MksTemps", SetLastError = true)]
+ internal static extern IntPtr MksTemps(
+ byte[] template,
+ int suffixlen);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Open.cs b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Open.cs
new file mode 100644
index 0000000000..a9a994c78c
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Open.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.Runtime.InteropServices;
+using Microsoft.Win32.SafeHandles;
+
+internal static partial class Interop
+{
+ internal static partial class Sys
+ {
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_Open", SetLastError = true)]
+ internal static extern SafeFileHandle Open(string filename, OpenFlags flags, int mode);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.OpenFlags.cs b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.OpenFlags.cs
new file mode 100644
index 0000000000..f9e54c3cbc
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.OpenFlags.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;
+
+internal static partial class Interop
+{
+ internal static partial class Sys
+ {
+ [Flags]
+ internal enum OpenFlags
+ {
+ // Access modes (mutually exclusive)
+ O_RDONLY = 0x0000,
+ O_WRONLY = 0x0001,
+ O_RDWR = 0x0002,
+
+ // Flags (combinable)
+ O_CLOEXEC = 0x0010,
+ O_CREAT = 0x0020,
+ O_EXCL = 0x0040,
+ O_TRUNC = 0x0080,
+ O_SYNC = 0x0100,
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.PathConf.cs b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.PathConf.cs
new file mode 100644
index 0000000000..4a1fcf67d0
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.PathConf.cs
@@ -0,0 +1,73 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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
+ {
+ internal static int DEFAULT_PC_NAME_MAX = 255;
+
+ internal enum PathConfName : int
+ {
+ PC_LINK_MAX = 1,
+ PC_MAX_CANON = 2,
+ PC_MAX_INPUT = 3,
+ PC_NAME_MAX = 4,
+ PC_PATH_MAX = 5,
+ PC_PIPE_BUF = 6,
+ PC_CHOWN_RESTRICTED = 7,
+ PC_NO_TRUNC = 8,
+ PC_VDISABLE = 9,
+ }
+
+ /// <summary>The maximum path length for the system. -1 if it hasn't yet been initialized.</summary>
+ private static int s_maxPath = -1;
+
+ /// <summary>The maximum name length for the system. -1 if it hasn't yet been initialized.</summary>
+ private static int s_maxName = -1;
+
+ internal static int MaxPath
+ {
+ get
+ {
+ // Benign race condition on cached value
+ if (s_maxPath < 0)
+ {
+ // GetMaximumPath returns a long from PathConf
+ // but our callers expect an int so we need to convert.
+ long temp = GetMaximumPath();
+ if (temp > int.MaxValue)
+ s_maxPath = int.MaxValue;
+ else
+ s_maxPath = Convert.ToInt32(temp);
+ }
+ return s_maxPath;
+ }
+ }
+
+ internal static int MaxName
+ {
+ get
+ {
+ // Benign race condition on cached value
+ if (s_maxName < 0)
+ {
+ int result = PathConf("/", PathConfName.PC_NAME_MAX);
+ s_maxName = result >= 0 ? result : DEFAULT_PC_NAME_MAX;
+ }
+
+ return s_maxName;
+ }
+ }
+
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_PathConf", SetLastError = true)]
+ private static extern int PathConf(string path, PathConfName name);
+
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetMaximumPath")]
+ private static extern long GetMaximumPath();
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Permissions.cs b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Permissions.cs
new file mode 100644
index 0000000000..f1d13787d2
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Permissions.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.
+
+using System;
+
+internal static partial class Interop
+{
+ internal static partial class Sys
+ {
+ [Flags]
+ internal enum Permissions
+ {
+ Mask = S_IRWXU | S_IRWXG | S_IRWXO,
+
+ S_IRWXU = S_IRUSR | S_IWUSR | S_IXUSR,
+ S_IRUSR = 0x100,
+ S_IWUSR = 0x80,
+ S_IXUSR = 0x40,
+
+ S_IRWXG = S_IRGRP | S_IWGRP | S_IXGRP,
+ S_IRGRP = 0x20,
+ S_IWGRP = 0x10,
+ S_IXGRP = 0x8,
+
+ S_IRWXO = S_IROTH | S_IWOTH | S_IXOTH,
+ S_IROTH = 0x4,
+ S_IWOTH = 0x2,
+ S_IXOTH = 0x1,
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.PosixFAdvise.cs b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.PosixFAdvise.cs
new file mode 100644
index 0000000000..69e39b30d2
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.PosixFAdvise.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.Runtime.InteropServices;
+using Microsoft.Win32.SafeHandles;
+
+internal static partial class Interop
+{
+ internal static partial class Sys
+ {
+ internal enum FileAdvice : int
+ {
+ POSIX_FADV_NORMAL = 0, /* no special advice, the default value */
+ POSIX_FADV_RANDOM = 1, /* random I/O access */
+ POSIX_FADV_SEQUENTIAL = 2, /* sequential I/O access */
+ POSIX_FADV_WILLNEED = 3, /* will need specified pages */
+ POSIX_FADV_DONTNEED = 4, /* don't need the specified pages */
+ POSIX_FADV_NOREUSE = 5, /* data will only be acessed once */
+ }
+
+ /// <summary>
+ /// Notifies the OS kernel that the specified file will be accessed in a particular way soon; this allows the kernel to
+ /// potentially optimize the access pattern of the file.
+ /// </summary>
+ /// <param name="fd">The file descriptor of the file</param>
+ /// <param name="offset">The start of the region to advise about</param>
+ /// <param name="length">The number of bytes of the region (until the end of the file if 0)</param>
+ /// <param name="advice">The type of advice to give the kernel about the specified region</param>
+ /// <returns>
+ /// Returns 0 on success; otherwise, the error code is returned
+ /// </returns>
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_PosixFAdvise", SetLastError = false /* this is explicitly called out in the man page */)]
+ internal static extern int PosixFAdvise(SafeFileHandle fd, long offset, long length, FileAdvice advice);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Read.cs b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Read.cs
new file mode 100644
index 0000000000..812ae348dc
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Read.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.Runtime.InteropServices;
+using Microsoft.Win32.SafeHandles;
+
+internal static partial class Interop
+{
+ internal static partial class Sys
+ {
+ /// <summary>
+ /// Reads a number of bytes from an open file descriptor into a specified buffer.
+ /// </summary>
+ /// <param name="fd">The open file descriptor to try to read from</param>
+ /// <param name="buffer">The buffer to read info into</param>
+ /// <param name="count">The size of the buffer</param>
+ /// <returns>
+ /// Returns the number of bytes read on success; otherwise, -1 is returned
+ /// Note - on fail. the position of the stream may change depending on the platform; consult man 2 read for more info
+ /// </returns>
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_Read", SetLastError = true)]
+ internal static unsafe extern int Read(SafeFileHandle fd, byte* buffer, int count);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Stat.cs b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Stat.cs
new file mode 100644
index 0000000000..a8bc2ec7d1
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Stat.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.
+
+using System;
+using System.Runtime.InteropServices;
+using Microsoft.Win32.SafeHandles;
+
+internal static partial class Interop
+{
+ internal static partial class Sys
+ {
+ // Even though csc will by default use a sequential layout, a CS0649 warning as error
+ // is produced for un-assigned fields when no StructLayout is specified.
+ //
+ // Explicitly saying Sequential disables that warning/error for consumers which only
+ // use Stat in debug builds.
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct FileStatus
+ {
+ internal FileStatusFlags Flags;
+ internal int Mode;
+ internal uint Uid;
+ internal uint Gid;
+ internal long Size;
+ internal long ATime;
+ internal long MTime;
+ internal long CTime;
+ internal long BirthTime;
+ }
+
+ internal static class FileTypes
+ {
+ internal const int S_IFMT = 0xF000;
+ internal const int S_IFIFO = 0x1000;
+ internal const int S_IFCHR = 0x2000;
+ internal const int S_IFDIR = 0x4000;
+ internal const int S_IFREG = 0x8000;
+ internal const int S_IFLNK = 0xA000;
+ internal const int S_IFSOCK = 0xC000;
+ }
+
+ [Flags]
+ internal enum FileStatusFlags
+ {
+ None = 0,
+ HasBirthTime = 1,
+ }
+
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_FStat", SetLastError = true)]
+ internal static extern int FStat(SafeFileHandle fd, out FileStatus output);
+
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_Stat", SetLastError = true)]
+ internal static extern int Stat(string path, out FileStatus output);
+
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_LStat", SetLastError = true)]
+ internal static extern int LStat(string path, out FileStatus output);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Unlink.cs b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Unlink.cs
new file mode 100644
index 0000000000..829210fa7e
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Unlink.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 static partial class Interop
+{
+ internal static partial class Sys
+ {
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_Unlink", SetLastError = true)]
+ internal static extern int Unlink(string pathname);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Write.cs b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Write.cs
new file mode 100644
index 0000000000..c14fc26263
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Write.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.Runtime.InteropServices;
+using Microsoft.Win32.SafeHandles;
+
+internal static partial class Interop
+{
+ internal static partial class Sys
+ {
+ /// <summary>
+ /// Writes the specified buffer to the provided open file descriptor
+ /// </summary>
+ /// <param name="fd">The file descriptor to try and write to</param>
+ /// <param name="buffer">The data to attempt to write</param>
+ /// <param name="bufferSize">The amount of data to write, in bytes</param>
+ /// <returns>
+ /// Returns the number of bytes written on success; otherwise, returns -1 and sets errno
+ /// </returns>
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_Write", SetLastError = true)]
+ internal static unsafe extern int Write(SafeFileHandle fd, byte* buffer, int bufferSize);
+
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_Write", SetLastError = true)]
+ internal static unsafe extern int Write(int fd, byte* buffer, int bufferSize);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/BCrypt/Interop.BCryptGenRandom.cs b/src/mscorlib/corefx/Interop/Windows/BCrypt/Interop.BCryptGenRandom.cs
new file mode 100644
index 0000000000..d2ce4131b0
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/BCrypt/Interop.BCryptGenRandom.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.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
new file mode 100644
index 0000000000..49d674f399
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/BCrypt/Interop.NTSTATUS.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;
+
+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/Crypt32/Interop.CryptProtectMemory.cs b/src/mscorlib/corefx/Interop/Windows/Crypt32/Interop.CryptProtectMemory.cs
new file mode 100644
index 0000000000..b10cb6a041
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/Crypt32/Interop.CryptProtectMemory.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;
+using System.Security;
+
+internal partial class Interop
+{
+ internal partial class Crypt32
+ {
+ internal const uint CRYPTPROTECTMEMORY_BLOCK_SIZE = 16;
+ internal const uint CRYPTPROTECTMEMORY_SAME_PROCESS = 0;
+
+ [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
+ internal static extern bool CryptProtectMemory(SafeBSTRHandle pData, uint cbData, uint dwFlags);
+
+ [DllImport(Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
+ internal static extern bool CryptUnprotectMemory(SafeBSTRHandle pData, uint cbData, uint dwFlags);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/Interop.BOOL.cs b/src/mscorlib/corefx/Interop/Windows/Interop.BOOL.cs
new file mode 100644
index 0000000000..9f4dab8935
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/Interop.BOOL.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.
+
+internal partial class Interop
+{
+ /// <summary>
+ /// Blittable version of Windows BOOL type. It is convenient in situations where
+ /// manual marshalling is required, or to avoid overhead of regular bool marshalling.
+ /// </summary>
+ /// <remarks>
+ /// Some Windows APIs return arbitrary integer values although the return type is defined
+ /// as BOOL. It is best to never compare BOOL to TRUE. Always use bResult != BOOL.FALSE
+ /// or bResult == BOOL.FALSE .
+ /// </remarks>
+ internal enum BOOL : int
+ {
+ FALSE = 0,
+ TRUE = 1,
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/Interop.Libraries.cs b/src/mscorlib/corefx/Interop/Windows/Interop.Libraries.cs
new file mode 100644
index 0000000000..1165a2da95
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/Interop.Libraries.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.
+
+internal static partial class Interop
+{
+ internal static class Libraries
+ {
+ internal const string Advapi32 = "advapi32.dll";
+ internal const string BCrypt = "BCrypt.dll";
+ internal const string Combase = "combase.dll";
+ internal const string Console_L1 = "api-ms-win-core-console-l1-1-0.dll";
+ internal const string Console_L2 = "api-ms-win-core-console-l2-1-0.dll";
+ internal const string CoreFile_L1 = "api-ms-win-core-file-l1-1-0.dll";
+ internal const string CoreFile_L1_2 = "api-ms-win-core-file-l1-2-0.dll";
+ internal const string CoreFile_L2 = "api-ms-win-core-file-l2-1-0.dll";
+ internal const string Crypt32 = "crypt32.dll";
+ internal const string Debug = "api-ms-win-core-debug-l1-1-0.dll";
+ internal const string Error_L1 = "api-ms-win-core-winrt-error-l1-1-0.dll";
+ internal const string ErrorHandling = "api-ms-win-core-errorhandling-l1-1-0.dll";
+ internal const string Eventing = "api-ms-win-eventing-provider-l1-1-0.dll";
+ internal const string Handle = "api-ms-win-core-handle-l1-1-0.dll";
+ internal const string Heap = "api-ms-win-core-heap-obsolete-l1-1-0.dll";
+ internal const string Heap_L1 = "api-ms-win-core-heap-l1-1-0.dll";
+ internal const string IO = "api-ms-win-core-io-l1-1-0.dll";
+ internal const string IpHlpApi = "iphlpapi.dll";
+ internal const string Kernel32 = "kernel32.dll";
+ internal const string Kernel32_L1 = "api-ms-win-core-kernel32-legacy-l1-1-1.dll";
+ internal const string Kernel32_L2 = "api-ms-win-core-kernel32-legacy-l1-1-0.dll";
+ internal const string Keyboard = "ext-ms-win-ntuser-keyboard-l1-2-1.dll";
+ internal const string LibraryLoader = "api-ms-win-core-libraryloader-l1-1-0.dll";
+ internal const string Localization = "api-ms-win-core-localization-l1-2-0.dll";
+ internal const string Memory_L1_0 = "api-ms-win-core-memory-l1-1-0.dll";
+ internal const string Memory_L1_1 = "api-ms-win-core-memory-l1-1-1.dll";
+ internal const string Memory_L1_2 = "api-ms-win-core-memory-l1-1-2.dll";
+ internal const string Memory_L1_3 = "api-ms-win-core-memory-l1-1-3.dll";
+ internal const string NCrypt = "ncrypt.dll";
+ internal const string NtDll = "ntdll.dll";
+ internal const string OleAut32 = "oleaut32.dll";
+ internal const string Pipe = "api-ms-win-core-namedpipe-l1-1-0.dll";
+ internal const string Pipe_L2 = "api-ms-win-core-namedpipe-l1-2-1.dll";
+ internal const string ProcessEnvironment = "api-ms-win-core-processenvironment-l1-1-0.dll";
+ internal const string ProcessThread_L1 = "api-ms-win-core-processthreads-l1-1-0.dll";
+ internal const string ProcessThread_L1_1 = "api-ms-win-core-processthreads-l1-1-1.dll";
+ internal const string ProcessThread_L1_2 = "api-ms-win-core-processthreads-l1-1-2.dll";
+ internal const string ProcessTopology = "api-ms-win-core-processtopology-obsolete-l1-1-0.dll";
+ internal const string Profile = "api-ms-win-core-profile-l1-1-0.dll";
+ internal const string Psapi = "api-ms-win-core-psapi-l1-1-0.dll";
+ internal const string Psapi_Obsolete = "api-ms-win-core-psapi-obsolete-l1-1-0.dll";
+ internal const string Registry_L1 = "api-ms-win-core-registry-l1-1-0.dll";
+ internal const string Registry_L2 = "api-ms-win-core-registry-l2-1-0.dll";
+ internal const string RoBuffer = "api-ms-win-core-winrt-robuffer-l1-1-0.dll";
+ internal const string SecurityBase = "api-ms-win-security-base-l1-1-0.dll";
+ internal const string SecurityCpwl = "api-ms-win-security-cpwl-l1-1-0.dll";
+ internal const string SecurityCryptoApi = "api-ms-win-security-cryptoapi-l1-1-0.dll";
+ internal const string SecurityLsa = "api-ms-win-security-lsalookup-l2-1-0.dll";
+ internal const string SecurityLsaPolicy = "api-ms-win-security-lsapolicy-l1-1-0.dll";
+ internal const string SecurityProvider = "api-ms-win-security-provider-l1-1-0.dll";
+ internal const string SecuritySddl = "api-ms-win-security-sddl-l1-1-0.dll";
+ internal const string ServiceCore = "api-ms-win-service-core-l1-1-1.dll";
+ internal const string ServiceMgmt_L1 = "api-ms-win-service-management-l1-1-0.dll";
+ internal const string ServiceMgmt_L2 = "api-ms-win-service-management-l2-1-0.dll";
+ internal const string ServiceWinSvc = "api-ms-win-service-winsvc-l1-1-0.dll";
+ internal const string Shell = "shell32.dll";
+ internal const string ShellFolders = "ext-ms-win-shell32-shellfolders-l1-1-0.dll";
+ internal const string Sspi = "sspicli.dll";
+ internal const string String_L1 = "api-ms-win-core-string-l1-1-0.dll";
+ internal const string Synch = "api-ms-win-core-synch-l1-1-0.dll";
+ internal const string SystemInfo_L1_1 = "api-ms-win-core-sysinfo-l1-1-0.dll";
+ internal const string SystemInfo_L1_2 = "api-ms-win-core-sysinfo-l1-2-0.dll";
+ internal const string SystemInfo_L2_1 = "api-ms-win-core-sysinfo-l2-1-0.dll";
+ internal const string ThreadPool = "api-ms-win-core-threadpool-l1-2-0.dll";
+ internal const string User32 = "user32.dll";
+ internal const string Util = "api-ms-win-core-util-l1-1-0.dll";
+ internal const string Version = "api-ms-win-core-version-l1-1-0.dll";
+ internal const string WinHttp = "winhttp.dll";
+ internal const string Winsock = "Ws2_32.dll";
+ internal const string Wow64 = "api-ms-win-core-wow64-l1-1-0.dll";
+ internal const string Ws2_32 = "ws2_32.dll";
+ internal const string Zlib = "clrcompression.dll";
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/NtDll/Interop.ZeroMemory.cs b/src/mscorlib/corefx/Interop/Windows/NtDll/Interop.ZeroMemory.cs
new file mode 100644
index 0000000000..caa0329bd0
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/NtDll/Interop.ZeroMemory.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 NtDll
+ {
+ [DllImport(Libraries.NtDll, CharSet = CharSet.Unicode, EntryPoint = "RtlZeroMemory")]
+ internal static extern void ZeroMemory(SafeBSTRHandle address, uint length);
+
+ [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/mincore/Interop.CancelIoEx.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.CancelIoEx.cs
new file mode 100644
index 0000000000..868d409321
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.CancelIoEx.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 Microsoft.Win32.SafeHandles;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+internal partial class Interop
+{
+ internal partial class mincore
+ {
+ [DllImport(Libraries.IO, SetLastError = true)]
+ internal static unsafe extern bool CancelIoEx(SafeHandle handle, NativeOverlapped* lpOverlapped);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/mincore/Interop.CloseHandle.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.CloseHandle.cs
new file mode 100644
index 0000000000..029937b6d5
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.CloseHandle.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;
+
+internal partial class Interop
+{
+ internal partial class mincore
+ {
+ [DllImport(Libraries.Handle, SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ internal static extern bool CloseHandle(IntPtr handle);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/mincore/Interop.CreateFile.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.CreateFile.cs
new file mode 100644
index 0000000000..670037d52e
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/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 mincore
+ {
+ /// <summary>
+ /// WARNING: This method does not implicitly handle long paths. Use CreateFile.
+ /// </summary>
+ [DllImport(Libraries.CoreFile_L1, 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/mincore/Interop.Errors.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.Errors.cs
new file mode 100644
index 0000000000..05b2250830
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.Errors.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.
+
+internal partial class Interop
+{
+ internal partial class mincore
+ {
+ 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/mincore/Interop.FileOperations.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.FileOperations.cs
new file mode 100644
index 0000000000..4369760042
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.FileOperations.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.
+
+internal partial class Interop
+{
+ internal partial class mincore
+ {
+ internal partial class IOReparseOptions
+ {
+ internal const uint IO_REPARSE_TAG_FILE_PLACEHOLDER = 0x80000015;
+ internal const uint IO_REPARSE_TAG_MOUNT_POINT = 0xA0000003;
+ }
+
+ internal partial class FileOperations
+ {
+ internal const int OPEN_EXISTING = 3;
+ internal const int COPY_FILE_FAIL_IF_EXISTS = 0x00000001;
+
+ internal const int FILE_ACTION_ADDED = 1;
+ internal const int FILE_ACTION_REMOVED = 2;
+ internal const int FILE_ACTION_MODIFIED = 3;
+ internal const int FILE_ACTION_RENAMED_OLD_NAME = 4;
+ internal const int FILE_ACTION_RENAMED_NEW_NAME = 5;
+
+ internal const int FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;
+ internal const int FILE_FLAG_FIRST_PIPE_INSTANCE = 0x00080000;
+ internal const int FILE_FLAG_OVERLAPPED = 0x40000000;
+
+ internal const int FILE_LIST_DIRECTORY = 0x0001;
+ }
+
+ internal const uint SEM_FAILCRITICALERRORS = 1;
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/mincore/Interop.FileTypes.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.FileTypes.cs
new file mode 100644
index 0000000000..a24813e8d6
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.FileTypes.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.
+
+internal partial class Interop
+{
+ internal partial class mincore
+ {
+ internal partial class FileTypes
+ {
+ internal const int FILE_TYPE_DISK = 0x0001;
+ internal const int FILE_TYPE_CHAR = 0x0002;
+ internal const int FILE_TYPE_PIPE = 0x0003;
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/mincore/Interop.FlushFileBuffers.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.FlushFileBuffers.cs
new file mode 100644
index 0000000000..69f4fe07ce
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.FlushFileBuffers.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 Microsoft.Win32.SafeHandles;
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class mincore
+ {
+ [DllImport(Libraries.CoreFile_L1, SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ internal static extern bool FlushFileBuffers(SafeHandle hHandle);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/mincore/Interop.FormatMessage.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.FormatMessage.cs
new file mode 100644
index 0000000000..02ecbb8a63
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.FormatMessage.cs
@@ -0,0 +1,112 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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 mincore
+ {
+ private const int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
+ private const int FORMAT_MESSAGE_FROM_HMODULE = 0x00000800;
+ private const int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
+ private const int FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000;
+
+
+ private const int ERROR_INSUFFICIENT_BUFFER = 0x7A;
+
+ [DllImport(Libraries.Localization, CharSet = CharSet.Unicode, EntryPoint = "FormatMessageW", SetLastError = true, BestFitMapping = true)]
+ private static extern int FormatMessage(
+ int dwFlags,
+ IntPtr lpSource,
+ uint dwMessageId,
+ int dwLanguageId,
+ [Out] StringBuilder lpBuffer,
+ int nSize,
+ IntPtr[] arguments);
+
+ /// <summary>
+ /// Returns a string message for the specified Win32 error code.
+ /// </summary>
+ internal static string GetMessage(int errorCode)
+ {
+ return GetMessage(IntPtr.Zero, errorCode);
+ }
+
+ internal static string GetMessage(IntPtr moduleHandle, int errorCode)
+ {
+ var sb = new StringBuilder(InitialBufferSize);
+ do
+ {
+ string errorMsg;
+ if (TryGetErrorMessage(moduleHandle, errorCode, sb, out errorMsg))
+ {
+ return errorMsg;
+ }
+ else
+ {
+ // increase the capacity of the StringBuilder.
+ sb.Capacity *= BufferSizeIncreaseFactor;
+ }
+ }
+ while (sb.Capacity < MaxAllowedBufferSize);
+
+ // If you come here then a size as large as 65K is also not sufficient and so we give the generic errorMsg.
+ return string.Format("Unknown error (0x{0:x})", errorCode);
+ }
+
+ private static bool TryGetErrorMessage(IntPtr moduleHandle, int errorCode, StringBuilder sb, out string errorMsg)
+ {
+ errorMsg = "";
+
+ int flags = FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY;
+ if (moduleHandle != IntPtr.Zero)
+ {
+ flags |= FORMAT_MESSAGE_FROM_HMODULE;
+ }
+
+ int result = FormatMessage(flags, moduleHandle, (uint)errorCode, 0, sb, sb.Capacity, null);
+ if (result != 0)
+ {
+ int i = sb.Length;
+ while (i > 0)
+ {
+ char ch = sb[i - 1];
+ if (ch > 32 && ch != '.') break;
+ i--;
+ }
+ errorMsg = sb.ToString(0, i);
+ }
+ else if (Marshal.GetLastWin32Error() == ERROR_INSUFFICIENT_BUFFER)
+ {
+ return false;
+ }
+ else
+ {
+ errorMsg = string.Format("Unknown error (0x{0:x})", errorCode);
+ }
+
+ return true;
+ }
+
+ // Windows API FormatMessage lets you format a message string given an errorcode.
+ // Unlike other APIs this API does not support a way to query it for the total message size.
+ //
+ // So the API can only be used in one of these two ways.
+ // a. You pass a buffer of appropriate size and get the resource.
+ // b. Windows creates a buffer and passes the address back and the onus of releasing the buffer lies on the caller.
+ //
+ // Since the error code is coming from the user, it is not possible to know the size in advance.
+ // Unfortunately we can't use option b. since the buffer can only be freed using LocalFree and it is a private API on onecore.
+ // Also, using option b is ugly for the managed code and could cause memory leak in situations where freeing is unsuccessful.
+ //
+ // As a result we use the following approach.
+ // We initially call the API with a buffer size of 256 and then gradually increase the size in case of failure until we reach the maximum allowed limit of 65K.
+ private const int InitialBufferSize = 256;
+ private const int BufferSizeIncreaseFactor = 4;
+ private const int MaxAllowedBufferSize = 65 * 1024;
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/mincore/Interop.GetFileInformationByHandleEx.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.GetFileInformationByHandleEx.cs
new file mode 100644
index 0000000000..c4739a5ddc
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.GetFileInformationByHandleEx.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 Microsoft.Win32.SafeHandles;
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class mincore
+ {
+ [DllImport(Libraries.CoreFile_L2, 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/mincore/Interop.GetFileType_SafeHandle.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.GetFileType_SafeHandle.cs
new file mode 100644
index 0000000000..3e2567b6bf
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.GetFileType_SafeHandle.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 Microsoft.Win32.SafeHandles;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class mincore
+ {
+ [DllImport(Libraries.CoreFile_L1, SetLastError = true)]
+ internal extern static int GetFileType(SafeHandle hFile);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/mincore/Interop.GetFullPathNameW.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.GetFullPathNameW.cs
new file mode 100644
index 0000000000..a34cc33db3
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.GetFullPathNameW.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 mincore
+ {
+ /// <summary>
+ /// WARNING: This method does not implicitly handle long paths. Use GetFullPathName or PathHelper.
+ /// </summary>
+ [DllImport(Libraries.CoreFile_L1, SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)]
+ unsafe internal static extern uint GetFullPathNameW(char* path, uint numBufferChars, SafeHandle buffer, IntPtr mustBeZero);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/mincore/Interop.GetLongPathNameW.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.GetLongPathNameW.cs
new file mode 100644
index 0000000000..d50db6650b
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/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;
+
+partial class Interop
+{
+ partial class mincore
+ {
+ /// <summary>
+ /// WARNING: This method does not implicitly handle long paths. Use GetFullPath/PathHelper.
+ /// </summary>
+ [DllImport(Libraries.CoreFile_L1, SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)]
+ internal static extern uint GetLongPathNameW(SafeHandle lpszShortPath, SafeHandle lpszLongPath, uint cchBuffer);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/mincore/Interop.GetTempFileNameW.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.GetTempFileNameW.cs
new file mode 100644
index 0000000000..f06d11be52
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/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;
+
+partial class Interop
+{
+ partial class mincore
+ {
+ [DllImport(Libraries.CoreFile_L1, 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/mincore/Interop.GetTempPathW.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.GetTempPathW.cs
new file mode 100644
index 0000000000..0ccc27c9ec
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/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;
+
+partial class Interop
+{
+ partial class mincore
+ {
+ [DllImport(Libraries.CoreFile_L1_2, CharSet = CharSet.Unicode, BestFitMapping = false)]
+ internal static extern uint GetTempPathW(int bufferLen, [Out]StringBuilder buffer);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/mincore/Interop.Idna.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.Idna.cs
new file mode 100644
index 0000000000..e14f16b048
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.Idna.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.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class mincore
+ {
+ //
+ // Idn APIs
+ //
+
+ [DllImport("api-ms-win-core-localization-l1-2-0.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("api-ms-win-core-localization-l1-2-0.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;
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/mincore/Interop.LockFile.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.LockFile.cs
new file mode 100644
index 0000000000..ee9a98ecce
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.LockFile.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 Microsoft.Win32.SafeHandles;
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class mincore
+ {
+ [DllImport(Libraries.CoreFile_L1, SetLastError = true)]
+ internal static extern bool LockFile(SafeFileHandle handle, int offsetLow, int offsetHigh, int countLow, int countHigh);
+
+ [DllImport(Libraries.CoreFile_L1, SetLastError = true)]
+ internal static extern bool UnlockFile(SafeFileHandle handle, int offsetLow, int offsetHigh, int countLow, int countHigh);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/mincore/Interop.ReadFile_SafeHandle_IntPtr.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.ReadFile_SafeHandle_IntPtr.cs
new file mode 100644
index 0000000000..093a993c10
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.ReadFile_SafeHandle_IntPtr.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 Microsoft.Win32.SafeHandles;
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class mincore
+ {
+ [DllImport(Libraries.CoreFile_L1, SetLastError = true)]
+ unsafe internal static extern int ReadFile(
+ SafeHandle handle,
+ byte* bytes,
+ int numBytesToRead,
+ out int numBytesRead,
+ IntPtr mustBeZero);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/mincore/Interop.ReadFile_SafeHandle_NativeOverlapped.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.ReadFile_SafeHandle_NativeOverlapped.cs
new file mode 100644
index 0000000000..ac238cb802
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.ReadFile_SafeHandle_NativeOverlapped.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 Microsoft.Win32.SafeHandles;
+using System;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+internal partial class Interop
+{
+ internal partial class mincore
+ {
+ [DllImport(Libraries.CoreFile_L1, SetLastError = true)]
+ unsafe internal static extern int ReadFile(
+ SafeHandle handle,
+ byte* bytes,
+ int numBytesToRead,
+ IntPtr numBytesRead_mustBeZero,
+ NativeOverlapped* overlapped);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/mincore/Interop.SECURITY_ATTRIBUTES.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.SECURITY_ATTRIBUTES.cs
new file mode 100644
index 0000000000..0f5c224022
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.SECURITY_ATTRIBUTES.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 Microsoft.Win32.SafeHandles;
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class mincore
+ {
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct SECURITY_ATTRIBUTES
+ {
+ internal uint nLength;
+ internal IntPtr lpSecurityDescriptor;
+ internal BOOL bInheritHandle;
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/mincore/Interop.SafeCreateFile.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.SafeCreateFile.cs
new file mode 100644
index 0000000000..edfc66d2c9
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.SafeCreateFile.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;
+using System.IO;
+using System.Runtime.InteropServices;
+using Microsoft.Win32.SafeHandles;
+
+internal partial class Interop
+{
+ internal partial class mincore
+ {
+ 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.mincore.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.mincore.GetFileType(handle);
+ if (fileType != Interop.mincore.FileTypes.FILE_TYPE_DISK)
+ {
+ handle.Dispose();
+ throw new NotSupportedException(SR.NotSupported_FileStreamOnNonFiles);
+ }
+ }
+
+ return handle;
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/mincore/Interop.SecurityOptions.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.SecurityOptions.cs
new file mode 100644
index 0000000000..767d7f528f
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.SecurityOptions.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.
+
+internal partial class Interop
+{
+ internal partial class mincore
+ {
+ internal partial class SecurityOptions
+ {
+ internal const int SECURITY_SQOS_PRESENT = 0x00100000;
+ internal const int SECURITY_ANONYMOUS = 0 << 16;
+ internal const int SECURITY_IDENTIFICATION = 1 << 16;
+ internal const int SECURITY_IMPERSONATION = 2 << 16;
+ internal const int SECURITY_DELEGATION = 3 << 16;
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/mincore/Interop.SetEndOfFile.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.SetEndOfFile.cs
new file mode 100644
index 0000000000..ee0d3b4bc8
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.SetEndOfFile.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 Microsoft.Win32.SafeHandles;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class mincore
+ {
+ [DllImport(Libraries.CoreFile_L1, SetLastError = true)]
+ internal static extern bool SetEndOfFile(SafeFileHandle hFile);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/mincore/Interop.SetErrorMode.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.SetErrorMode.cs
new file mode 100644
index 0000000000..a845990ded
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.SetErrorMode.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 mincore
+ {
+ [DllImport(Libraries.ErrorHandling, SetLastError = false, EntryPoint = "SetErrorMode", ExactSpelling = true)]
+ internal static extern uint SetErrorMode(uint newMode);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/mincore/Interop.SetFileInformationByHandle.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.SetFileInformationByHandle.cs
new file mode 100644
index 0000000000..0519219132
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.SetFileInformationByHandle.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 Microsoft.Win32.SafeHandles;
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class mincore
+ {
+ [DllImport(Libraries.CoreFile_L1, SetLastError = true)]
+ internal static extern bool SetFileInformationByHandle(SafeFileHandle hFile, FILE_INFO_BY_HANDLE_CLASS FileInformationClass, ref FILE_BASIC_INFO lpFileInformation, uint dwBufferSize);
+
+ // Default values indicate "no change". Use defaults so that we don't force callsites to be aware of the default values
+ internal unsafe static bool SetFileTime(
+ SafeFileHandle hFile,
+ long creationTime = -1,
+ long lastAccessTime = -1,
+ long lastWriteTime = -1,
+ long changeTime = -1,
+ uint fileAttributes = 0)
+ {
+ FILE_BASIC_INFO basicInfo = new FILE_BASIC_INFO()
+ {
+ CreationTime = creationTime,
+ LastAccessTime = lastAccessTime,
+ LastWriteTime = lastWriteTime,
+ ChangeTime = changeTime,
+ FileAttributes = fileAttributes
+ };
+
+ return SetFileInformationByHandle(hFile, FILE_INFO_BY_HANDLE_CLASS.FileBasicInfo, ref basicInfo, (uint)Marshal.SizeOf<FILE_BASIC_INFO>());
+ }
+
+ internal struct FILE_BASIC_INFO
+ {
+ internal long CreationTime;
+ internal long LastAccessTime;
+ internal long LastWriteTime;
+ internal long ChangeTime;
+ internal uint FileAttributes;
+ }
+
+ internal enum FILE_INFO_BY_HANDLE_CLASS : uint
+ {
+ FileBasicInfo = 0x0u,
+ FileStandardInfo = 0x1u,
+ FileNameInfo = 0x2u,
+ FileRenameInfo = 0x3u,
+ FileDispositionInfo = 0x4u,
+ FileAllocationInfo = 0x5u,
+ FileEndOfFileInfo = 0x6u,
+ FileStreamInfo = 0x7u,
+ FileCompressionInfo = 0x8u,
+ FileAttributeTagInfo = 0x9u,
+ FileIdBothDirectoryInfo = 0xAu,
+ FileIdBothDirectoryRestartInfo = 0xBu,
+ FileIoPriorityHintInfo = 0xCu,
+ FileRemoteProtocolInfo = 0xDu,
+ FileFullDirectoryInfo = 0xEu,
+ FileFullDirectoryRestartInfo = 0xFu,
+ FileStorageInfo = 0x10u,
+ FileAlignmentInfo = 0x11u,
+ FileIdInfo = 0x12u,
+ FileIdExtdDirectoryInfo = 0x13u,
+ FileIdExtdDirectoryRestartInfo = 0x14u,
+ MaximumFileInfoByHandleClass = 0x15u,
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/mincore/Interop.SetFilePointerEx.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.SetFilePointerEx.cs
new file mode 100644
index 0000000000..09f8e1feb3
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.SetFilePointerEx.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 Microsoft.Win32.SafeHandles;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class mincore
+ {
+ [DllImport(Libraries.CoreFile_L1, SetLastError = true)]
+ internal static extern bool SetFilePointerEx(SafeFileHandle hFile, long liDistanceToMove, out long lpNewFilePointer, uint dwMoveMethod);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/mincore/Interop.ThreadPoolIO.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.ThreadPoolIO.cs
new file mode 100644
index 0000000000..a0afed5d1a
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.ThreadPoolIO.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;
+using System.Runtime.InteropServices;
+using Microsoft.Win32.SafeHandles;
+
+internal static partial class Interop
+{
+ internal static partial class mincore
+ {
+ [DllImport(Libraries.ThreadPool, SetLastError = true)]
+ internal static unsafe extern SafeThreadPoolIOHandle CreateThreadpoolIo(SafeHandle fl, [MarshalAs(UnmanagedType.FunctionPtr)] NativeIoCompletionCallback pfnio, IntPtr context, IntPtr pcbe);
+
+ [DllImport(Libraries.ThreadPool)]
+ internal static unsafe extern void CloseThreadpoolIo(IntPtr pio);
+
+ [DllImport(Libraries.ThreadPool)]
+ internal static unsafe extern void StartThreadpoolIo(SafeThreadPoolIOHandle pio);
+
+ [DllImport(Libraries.ThreadPool)]
+ internal static unsafe extern void CancelThreadpoolIo(SafeThreadPoolIOHandle pio);
+ }
+
+ internal delegate void NativeIoCompletionCallback(IntPtr instance, IntPtr context, IntPtr overlapped, uint ioResult, UIntPtr numberOfBytesTransferred, IntPtr io);
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/mincore/Interop.UnsafeCreateFile.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.UnsafeCreateFile.cs
new file mode 100644
index 0000000000..e7e4f0513a
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.UnsafeCreateFile.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;
+using System.IO;
+using Microsoft.Win32.SafeHandles;
+
+internal partial class Interop
+{
+ internal partial class mincore
+ {
+ internal static SafeFileHandle UnsafeCreateFile(
+ string lpFileName,
+ int dwDesiredAccess,
+ FileShare dwShareMode,
+ ref Interop.mincore.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/mincore/Interop.WideCharToMultiByte.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.WideCharToMultiByte.cs
new file mode 100644
index 0000000000..b1a2975696
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/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 mincore
+ {
+ [DllImport(Libraries.String_L1)]
+ 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/mincore/Interop.WriteFile_SafeHandle_IntPtr.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.WriteFile_SafeHandle_IntPtr.cs
new file mode 100644
index 0000000000..052ba3ce7d
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.WriteFile_SafeHandle_IntPtr.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 Microsoft.Win32.SafeHandles;
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class mincore
+ {
+ // 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.CoreFile_L1, SetLastError = true)]
+ internal static unsafe extern int WriteFile(SafeHandle handle, byte* bytes, int numBytesToWrite, out int numBytesWritten, IntPtr mustBeZero);
+
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/mincore/Interop.WriteFile_SafeHandle_NativeOverlapped.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.WriteFile_SafeHandle_NativeOverlapped.cs
new file mode 100644
index 0000000000..e9d2953045
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.WriteFile_SafeHandle_NativeOverlapped.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 Microsoft.Win32.SafeHandles;
+using System;
+using System.Runtime.InteropServices;
+using System.Threading;
+internal partial class Interop
+{
+ internal partial class mincore
+ {
+ // 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.CoreFile_L1, SetLastError = true)]
+ internal static unsafe extern int WriteFile(SafeHandle handle, byte* bytes, int numBytesToWrite, IntPtr numBytesWritten_mustBeZero, NativeOverlapped* lpOverlapped);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/oleaut32/Interop.SysAllocStringLen.cs b/src/mscorlib/corefx/Interop/Windows/oleaut32/Interop.SysAllocStringLen.cs
new file mode 100644
index 0000000000..65da4eaaea
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/oleaut32/Interop.SysAllocStringLen.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 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
new file mode 100644
index 0000000000..027d8eece9
--- /dev/null
+++ b/src/mscorlib/corefx/Interop/Windows/oleaut32/Interop.SysStringLen.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;
+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/SafeFileHandle.Unix.cs b/src/mscorlib/corefx/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs
new file mode 100644
index 0000000000..5ddb31ad36
--- /dev/null
+++ b/src/mscorlib/corefx/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs
@@ -0,0 +1,122 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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;
+
+namespace Microsoft.Win32.SafeHandles
+{
+ [System.Security.SecurityCritical]
+ public sealed class SafeFileHandle : SafeHandleZeroOrMinusOneIsInvalid
+ {
+ /// <summary>A handle value of -1.</summary>
+ private static readonly IntPtr s_invalidHandle = new IntPtr(-1);
+
+ private SafeFileHandle() : this(ownsHandle: true)
+ {
+ }
+
+ private SafeFileHandle(bool ownsHandle)
+ : base(ownsHandle)
+ {
+ SetHandle(s_invalidHandle);
+ }
+
+ public SafeFileHandle(IntPtr preexistingHandle, bool ownsHandle) : this(ownsHandle)
+ {
+ SetHandle(preexistingHandle);
+ }
+
+ internal bool? IsAsync { get; set; }
+
+ /// <summary>Opens the specified file with the requested flags and mode.</summary>
+ /// <param name="path">The path to the file.</param>
+ /// <param name="flags">The flags with which to open the file.</param>
+ /// <param name="mode">The mode for opening the file.</param>
+ /// <returns>A SafeFileHandle for the opened file.</returns>
+ internal static SafeFileHandle Open(string path, Interop.Sys.OpenFlags flags, int mode)
+ {
+ Debug.Assert(path != null);
+
+ // If we fail to open the file due to a path not existing, we need to know whether to blame
+ // the file itself or its directory. If we're creating the file, then we blame the directory,
+ // otherwise we blame the file.
+ bool enoentDueToDirectory = (flags & Interop.Sys.OpenFlags.O_CREAT) != 0;
+
+ // Open the file.
+ SafeFileHandle handle = Interop.CheckIo(
+ Interop.Sys.Open(path, flags, mode),
+ path,
+ isDirectory: enoentDueToDirectory,
+ errorRewriter: e => (e.Error == Interop.Error.EISDIR) ? Interop.Error.EACCES.Info() : e);
+
+ // Make sure it's not a directory; we do this after opening it once we have a file descriptor
+ // to avoid race conditions.
+ Interop.Sys.FileStatus status;
+ if (Interop.Sys.FStat(handle, out status) != 0)
+ {
+ handle.Dispose();
+ throw Interop.GetExceptionForIoErrno(Interop.Sys.GetLastErrorInfo(), path);
+ }
+ if ((status.Mode & Interop.Sys.FileTypes.S_IFMT) == Interop.Sys.FileTypes.S_IFDIR)
+ {
+ handle.Dispose();
+ throw Interop.GetExceptionForIoErrno(Interop.Error.EACCES.Info(), path, isDirectory: true);
+ }
+
+ return handle;
+ }
+
+ /// <summary>Opens a SafeFileHandle for a file descriptor created by a provided delegate.</summary>
+ /// <param name="fdFunc">
+ /// The function that creates the file descriptor. Returns the file descriptor on success, or an invalid
+ /// file descriptor on error with Marshal.GetLastWin32Error() set to the error code.
+ /// </param>
+ /// <returns>The created SafeFileHandle.</returns>
+ internal static SafeFileHandle Open(Func<SafeFileHandle> fdFunc)
+ {
+ SafeFileHandle handle = Interop.CheckIo(fdFunc());
+
+ Debug.Assert(!handle.IsInvalid, "File descriptor is invalid");
+ return handle;
+ }
+
+ [System.Security.SecurityCritical]
+ protected override bool ReleaseHandle()
+ {
+ // When the SafeFileHandle was opened, we likely issued an flock on the created descriptor in order to add
+ // an advisory lock. This lock should be removed via closing the file descriptor, but close can be
+ // interrupted, and we don't retry closes. As such, we could end up leaving the file locked,
+ // which could prevent subsequent usage of the file until this process dies. To avoid that, we proactively
+ // try to release the lock before we close the handle. (If it's not locked, there's no behavioral
+ // problem trying to unlock it.)
+ Interop.Sys.FLock(handle, Interop.Sys.LockOperations.LOCK_UN); // ignore any errors
+
+ // Close the descriptor. Although close is documented to potentially fail with EINTR, we never want
+ // to retry, as the descriptor could actually have been closed, been subsequently reassigned, and
+ // be in use elsewhere in the process. Instead, we simply check whether the call was successful.
+ int result = Interop.Sys.Close(handle);
+#if DEBUG
+ if (result != 0)
+ {
+ Debug.Fail(string.Format(
+ "Close failed with result {0} and error {1}",
+ result, Interop.Sys.GetLastErrorInfo()));
+ }
+#endif
+ return result == 0;
+ }
+
+ public override bool IsInvalid
+ {
+ [System.Security.SecurityCritical]
+ get
+ {
+ long h = (long)handle;
+ return h < 0 || h > int.MaxValue;
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/Microsoft/Win32/SafeHandles/SafeFileHandle.Windows.cs b/src/mscorlib/corefx/Microsoft/Win32/SafeHandles/SafeFileHandle.Windows.cs
new file mode 100644
index 0000000000..7d4dd444c7
--- /dev/null
+++ b/src/mscorlib/corefx/Microsoft/Win32/SafeHandles/SafeFileHandle.Windows.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.
+
+using System;
+using System.Security;
+using System.Runtime.InteropServices;
+using System.Threading;
+using Microsoft.Win32;
+
+namespace Microsoft.Win32.SafeHandles
+{
+ public sealed class SafeFileHandle : SafeHandleZeroOrMinusOneIsInvalid
+ {
+ private bool? _isAsync;
+
+ private SafeFileHandle() : base(true)
+ {
+ _isAsync = null;
+ }
+
+ public SafeFileHandle(IntPtr preexistingHandle, bool ownsHandle) : base(ownsHandle)
+ {
+ SetHandle(preexistingHandle);
+
+ _isAsync = null;
+ }
+
+ internal bool? IsAsync
+ {
+ get
+ {
+ return _isAsync;
+ }
+
+ set
+ {
+ _isAsync = value;
+ }
+ }
+
+ internal ThreadPoolBoundHandle ThreadPoolBinding { get; set; }
+
+ override protected bool ReleaseHandle()
+ {
+ return Interop.mincore.CloseHandle(handle);
+ }
+ }
+}
+
diff --git a/src/mscorlib/corefx/Microsoft/Win32/SafeHandles/SafeThreadPoolIOHandle.cs b/src/mscorlib/corefx/Microsoft/Win32/SafeHandles/SafeThreadPoolIOHandle.cs
new file mode 100644
index 0000000000..3dbc2bb620
--- /dev/null
+++ b/src/mscorlib/corefx/Microsoft/Win32/SafeHandles/SafeThreadPoolIOHandle.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.
+
+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
index 513bd9d94d..d820613f7e 100644
--- a/src/mscorlib/corefx/SR.cs
+++ b/src/mscorlib/corefx/SR.cs
@@ -1,247 +1,588 @@
using System;
+using System.Globalization;
-namespace 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
{
- internal static class SR
- {
- 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_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 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_CultureInvalidIdentifier
- {
- get { return Environment.GetResourceString("Argument_CultureInvalidIdentifier"); }
- }
-
- public static string Argument_CultureNotSupported
- {
- get { return Environment.GetResourceString("Argument_CultureNotSupported"); }
- }
+ 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_InvalidArrayLength
- {
- get { return Environment.GetResourceString("Argument_InvalidArrayLength"); }
- }
-
- public static string Argument_InvalidCalendar
- {
- get { return Environment.GetResourceString("Argument_InvalidCalendar"); }
- }
-
- 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_InvalidFlag
- {
- get { return Environment.GetResourceString("Argument_InvalidFlag"); }
- }
-
- public static string Argument_InvalidGroupSize
- {
- get { return Environment.GetResourceString("Argument_InvalidGroupSize"); }
- }
-
- 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_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 Format(string formatString, params object[] args)
- {
- return string.Format(CultureInfo.CurrentCulture, formatString, args);
- }
+ 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);
}
}
diff --git a/src/mscorlib/corefx/System/Buffers/ArrayPool.cs b/src/mscorlib/corefx/System/Buffers/ArrayPool.cs
new file mode 100644
index 0000000000..441e48dab4
--- /dev/null
+++ b/src/mscorlib/corefx/System/Buffers/ArrayPool.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.
+
+namespace System.Buffers
+{
+ /// <summary>
+ /// Provides a resource pool that enables reusing instances of type <see cref="T:T[]"/>.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// Renting and returning buffers with an <see cref="ArrayPool{T}"/> can increase performance
+ /// in situations where arrays are created and destroyed frequently, resulting in significant
+ /// memory pressure on the garbage collector.
+ /// </para>
+ /// <para>
+ /// This class is thread-safe. All members may be used by multiple threads concurrently.
+ /// </para>
+ /// </remarks>
+ public abstract class ArrayPool<T>
+ {
+ /// <summary>
+ /// Retrieves a shared <see cref="ArrayPool{T}"/> instance.
+ /// </summary>
+ /// <remarks>
+ /// The shared pool provides a default implementation of <see cref="ArrayPool{T}"/>
+ /// that's intended for general applicability. It maintains arrays of multiple sizes, and
+ /// may hand back a larger array than was actually requested, but will never hand back a smaller
+ /// array than was requested. Renting a buffer from it with <see cref="Rent"/> will result in an
+ /// existing buffer being taken from the pool if an appropriate buffer is available or in a new
+ /// buffer being allocated if one is not available.
+ /// </remarks>
+ public static ArrayPool<T> Shared => SharedPool.Value;
+
+ /// <summary>Stores a cached pool instance for T[].</summary>
+ /// <remarks>
+ /// Separated out into a nested class to enable lazy-initialization of the pool provided by
+ /// the runtime, only forced when Shared is used (and not when Create is called or when
+ /// other non-Shared accesses happen).
+ /// </remarks>
+ private static class SharedPool
+ {
+ /// <summary>Per-type cached pool.</summary>
+ /// <remarks>
+ /// byte[] and char[] are the most commonly pooled array types. For these we use a special pool type
+ /// optimized for very fast access speeds, at the expense of more memory consumption.
+ /// </remarks>
+ internal readonly static ArrayPool<T> Value =
+ typeof(T) == typeof(byte) || typeof(T) == typeof(char) ? new TlsOverPerCoreLockedStacksArrayPool<T>() :
+ Create();
+ }
+
+ /// <summary>
+ /// Creates a new <see cref="ArrayPool{T}"/> instance using default configuration options.
+ /// </summary>
+ /// <returns>A new <see cref="ArrayPool{T}"/> instance.</returns>
+ public static ArrayPool<T> Create() => new ConfigurableArrayPool<T>();
+
+ /// <summary>
+ /// Creates a new <see cref="ArrayPool{T}"/> instance using custom configuration options.
+ /// </summary>
+ /// <param name="maxArrayLength">The maximum length of array instances that may be stored in the pool.</param>
+ /// <param name="maxArraysPerBucket">
+ /// The maximum number of array instances that may be stored in each bucket in the pool. The pool
+ /// groups arrays of similar lengths into buckets for faster access.
+ /// </param>
+ /// <returns>A new <see cref="ArrayPool{T}"/> instance with the specified configuration options.</returns>
+ /// <remarks>
+ /// The created pool will group arrays into buckets, with no more than <paramref name="maxArraysPerBucket"/>
+ /// in each bucket and with those arrays not exceeding <paramref name="maxArrayLength"/> in length.
+ /// </remarks>
+ public static ArrayPool<T> Create(int maxArrayLength, int maxArraysPerBucket) =>
+ new ConfigurableArrayPool<T>(maxArrayLength, maxArraysPerBucket);
+
+ /// <summary>
+ /// Retrieves a buffer that is at least the requested length.
+ /// </summary>
+ /// <param name="minimumLength">The minimum length of the array needed.</param>
+ /// <returns>
+ /// An <see cref="T:T[]"/> that is at least <paramref name="minimumLength"/> in length.
+ /// </returns>
+ /// <remarks>
+ /// This buffer is loaned to the caller and should be returned to the same pool via
+ /// <see cref="Return"/> so that it may be reused in subsequent usage of <see cref="Rent"/>.
+ /// It is not a fatal error to not return a rented buffer, but failure to do so may lead to
+ /// decreased application performance, as the pool may need to create a new buffer to replace
+ /// the one lost.
+ /// </remarks>
+ public abstract T[] Rent(int minimumLength);
+
+ /// <summary>
+ /// Returns to the pool an array that was previously obtained via <see cref="Rent"/> on the same
+ /// <see cref="ArrayPool{T}"/> instance.
+ /// </summary>
+ /// <param name="array">
+ /// The buffer previously obtained from <see cref="Rent"/> to return to the pool.
+ /// </param>
+ /// <param name="clearArray">
+ /// If <c>true</c> and if the pool will store the buffer to enable subsequent reuse, <see cref="Return"/>
+ /// will clear <paramref name="array"/> of its contents so that a subsequent consumer via <see cref="Rent"/>
+ /// will not see the previous consumer's content. If <c>false</c> or if the pool will release the buffer,
+ /// the array's contents are left unchanged.
+ /// </param>
+ /// <remarks>
+ /// Once a buffer has been returned to the pool, the caller gives up all ownership of the buffer
+ /// and must not use it. The reference returned from a given call to <see cref="Rent"/> must only be
+ /// returned via <see cref="Return"/> once. The default <see cref="ArrayPool{T}"/>
+ /// may hold onto the returned buffer in order to rent it again, or it may release the returned buffer
+ /// if it's determined that the pool already has enough buffers stored.
+ /// </remarks>
+ public abstract void Return(T[] array, bool clearArray = false);
+ }
+}
diff --git a/src/mscorlib/corefx/System/Buffers/ArrayPoolEventSource.cs b/src/mscorlib/corefx/System/Buffers/ArrayPoolEventSource.cs
new file mode 100644
index 0000000000..9482744144
--- /dev/null
+++ b/src/mscorlib/corefx/System/Buffers/ArrayPoolEventSource.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 System.Diagnostics.Tracing;
+
+namespace System.Buffers
+{
+ [EventSource(Name = "System.Buffers.ArrayPoolEventSource")]
+ internal sealed class ArrayPoolEventSource : EventSource
+ {
+ internal readonly static ArrayPoolEventSource Log = new ArrayPoolEventSource();
+
+ /// <summary>The reason for a BufferAllocated event.</summary>
+ internal enum BufferAllocatedReason : int
+ {
+ /// <summary>The pool is allocating a buffer to be pooled in a bucket.</summary>
+ Pooled,
+ /// <summary>The requested buffer size was too large to be pooled.</summary>
+ OverMaximumSize,
+ /// <summary>The pool has already allocated for pooling as many buffers of a particular size as it's allowed.</summary>
+ PoolExhausted
+ }
+
+ /// <summary>
+ /// Event for when a buffer is rented. This is invoked once for every successful call to Rent,
+ /// regardless of whether a buffer is allocated or a buffer is taken from the pool. In a
+ /// perfect situation where all rented buffers are returned, we expect to see the number
+ /// of BufferRented events exactly match the number of BuferReturned events, with the number
+ /// of BufferAllocated events being less than or equal to those numbers (ideally significantly
+ /// less than).
+ /// </summary>
+ [Event(1, Level = EventLevel.Verbose)]
+ internal unsafe void BufferRented(int bufferId, int bufferSize, int poolId, int bucketId)
+ {
+ EventData* payload = stackalloc EventData[4];
+ payload[0].Size = sizeof(int);
+ payload[0].DataPointer = ((IntPtr)(&bufferId));
+ payload[1].Size = sizeof(int);
+ payload[1].DataPointer = ((IntPtr)(&bufferSize));
+ payload[2].Size = sizeof(int);
+ payload[2].DataPointer = ((IntPtr)(&poolId));
+ payload[3].Size = sizeof(int);
+ payload[3].DataPointer = ((IntPtr)(&bucketId));
+ WriteEventCore(1, 4, payload);
+ }
+
+ /// <summary>
+ /// Event for when a buffer is allocated by the pool. In an ideal situation, the number
+ /// of BufferAllocated events is significantly smaller than the number of BufferRented and
+ /// BufferReturned events.
+ /// </summary>
+ [Event(2, Level = EventLevel.Informational)]
+ internal unsafe void BufferAllocated(int bufferId, int bufferSize, int poolId, int bucketId, BufferAllocatedReason reason)
+ {
+ EventData* payload = stackalloc EventData[5];
+ payload[0].Size = sizeof(int);
+ payload[0].DataPointer = ((IntPtr)(&bufferId));
+ payload[1].Size = sizeof(int);
+ payload[1].DataPointer = ((IntPtr)(&bufferSize));
+ payload[2].Size = sizeof(int);
+ payload[2].DataPointer = ((IntPtr)(&poolId));
+ payload[3].Size = sizeof(int);
+ payload[3].DataPointer = ((IntPtr)(&bucketId));
+ payload[4].Size = sizeof(BufferAllocatedReason);
+ payload[4].DataPointer = ((IntPtr)(&reason));
+ WriteEventCore(2, 5, payload);
+ }
+
+ /// <summary>
+ /// Event raised when a buffer is returned to the pool. This event is raised regardless of whether
+ /// the returned buffer is stored or dropped. In an ideal situation, the number of BufferReturned
+ /// events exactly matches the number of BufferRented events.
+ /// </summary>
+ [Event(3, Level = EventLevel.Verbose)]
+ internal void BufferReturned(int bufferId, int bufferSize, int poolId) => WriteEvent(3, bufferId, bufferSize, poolId);
+ }
+}
diff --git a/src/mscorlib/corefx/System/Buffers/ConfigurableArrayPool.cs b/src/mscorlib/corefx/System/Buffers/ConfigurableArrayPool.cs
new file mode 100644
index 0000000000..1e0e769530
--- /dev/null
+++ b/src/mscorlib/corefx/System/Buffers/ConfigurableArrayPool.cs
@@ -0,0 +1,265 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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.Buffers
+{
+ internal sealed partial class ConfigurableArrayPool<T> : ArrayPool<T>
+ {
+ /// <summary>The default maximum length of each array in the pool (2^20).</summary>
+ private const int DefaultMaxArrayLength = 1024 * 1024;
+ /// <summary>The default maximum number of arrays per bucket that are available for rent.</summary>
+ private const int DefaultMaxNumberOfArraysPerBucket = 50;
+
+ private readonly Bucket[] _buckets;
+
+ internal ConfigurableArrayPool() : this(DefaultMaxArrayLength, DefaultMaxNumberOfArraysPerBucket)
+ {
+ }
+
+ internal ConfigurableArrayPool(int maxArrayLength, int maxArraysPerBucket)
+ {
+ if (maxArrayLength <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(maxArrayLength));
+ }
+ if (maxArraysPerBucket <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(maxArraysPerBucket));
+ }
+
+ // Our bucketing algorithm has a min length of 2^4 and a max length of 2^30.
+ // Constrain the actual max used to those values.
+ const int MinimumArrayLength = 0x10, MaximumArrayLength = 0x40000000;
+ if (maxArrayLength > MaximumArrayLength)
+ {
+ maxArrayLength = MaximumArrayLength;
+ }
+ else if (maxArrayLength < MinimumArrayLength)
+ {
+ maxArrayLength = MinimumArrayLength;
+ }
+
+ // Create the buckets.
+ int poolId = Id;
+ int maxBuckets = Utilities.SelectBucketIndex(maxArrayLength);
+ var buckets = new Bucket[maxBuckets + 1];
+ for (int i = 0; i < buckets.Length; i++)
+ {
+ buckets[i] = new Bucket(Utilities.GetMaxSizeForBucket(i), maxArraysPerBucket, poolId);
+ }
+ _buckets = buckets;
+ }
+
+ /// <summary>Gets an ID for the pool to use with events.</summary>
+ private int Id => GetHashCode();
+
+ public override T[] Rent(int minimumLength)
+ {
+ // Arrays can't be smaller than zero. We allow requesting zero-length arrays (even though
+ // pooling such an array isn't valuable) as it's a valid length array, and we want the pool
+ // to be usable in general instead of using `new`, even for computed lengths.
+ if (minimumLength < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(minimumLength));
+ }
+ else if (minimumLength == 0)
+ {
+ // No need for events with the empty array. Our pool is effectively infinite
+ // and we'll never allocate for rents and never store for returns.
+ return EmptyArray<T>.Value;
+ }
+
+ var log = ArrayPoolEventSource.Log;
+ T[] buffer = null;
+
+ int index = Utilities.SelectBucketIndex(minimumLength);
+ if (index < _buckets.Length)
+ {
+ // Search for an array starting at the 'index' bucket. If the bucket is empty, bump up to the
+ // next higher bucket and try that one, but only try at most a few buckets.
+ const int MaxBucketsToTry = 2;
+ int i = index;
+ do
+ {
+ // Attempt to rent from the bucket. If we get a buffer from it, return it.
+ buffer = _buckets[i].Rent();
+ if (buffer != null)
+ {
+ if (log.IsEnabled())
+ {
+ log.BufferRented(buffer.GetHashCode(), buffer.Length, Id, _buckets[i].Id);
+ }
+ return buffer;
+ }
+ }
+ while (++i < _buckets.Length && i != index + MaxBucketsToTry);
+
+ // The pool was exhausted for this buffer size. Allocate a new buffer with a size corresponding
+ // to the appropriate bucket.
+ buffer = new T[_buckets[index]._bufferLength];
+ }
+ else
+ {
+ // The request was for a size too large for the pool. Allocate an array of exactly the requested length.
+ // When it's returned to the pool, we'll simply throw it away.
+ buffer = new T[minimumLength];
+ }
+
+ if (log.IsEnabled())
+ {
+ int bufferId = buffer.GetHashCode(), bucketId = -1; // no bucket for an on-demand allocated buffer
+ log.BufferRented(bufferId, buffer.Length, Id, bucketId);
+ log.BufferAllocated(bufferId, buffer.Length, Id, bucketId, index >= _buckets.Length ?
+ ArrayPoolEventSource.BufferAllocatedReason.OverMaximumSize : ArrayPoolEventSource.BufferAllocatedReason.PoolExhausted);
+ }
+
+ return buffer;
+ }
+
+ public override void Return(T[] array, bool clearArray = false)
+ {
+ if (array == null)
+ {
+ throw new ArgumentNullException(nameof(array));
+ }
+ else if (array.Length == 0)
+ {
+ // Ignore empty arrays. When a zero-length array is rented, we return a singleton
+ // rather than actually taking a buffer out of the lowest bucket.
+ return;
+ }
+
+ // Determine with what bucket this array length is associated
+ int bucket = Utilities.SelectBucketIndex(array.Length);
+
+ // If we can tell that the buffer was allocated, drop it. Otherwise, check if we have space in the pool
+ if (bucket < _buckets.Length)
+ {
+ // Clear the array if the user requests
+ if (clearArray)
+ {
+ Array.Clear(array, 0, array.Length);
+ }
+
+ // Return the buffer to its bucket. In the future, we might consider having Return return false
+ // instead of dropping a bucket, in which case we could try to return to a lower-sized bucket,
+ // just as how in Rent we allow renting from a higher-sized bucket.
+ _buckets[bucket].Return(array);
+ }
+
+ // Log that the buffer was returned
+ var log = ArrayPoolEventSource.Log;
+ if (log.IsEnabled())
+ {
+ log.BufferReturned(array.GetHashCode(), array.Length, Id);
+ }
+ }
+
+ /// <summary>Provides a thread-safe bucket containing buffers that can be Rent'd and Return'd.</summary>
+ private sealed class Bucket
+ {
+ internal readonly int _bufferLength;
+ private readonly T[][] _buffers;
+ private readonly int _poolId;
+
+ private SpinLock _lock; // do not make this readonly; it's a mutable struct
+ private int _index;
+
+ /// <summary>
+ /// Creates the pool with numberOfBuffers arrays where each buffer is of bufferLength length.
+ /// </summary>
+ internal Bucket(int bufferLength, int numberOfBuffers, int poolId)
+ {
+ _lock = new SpinLock(Debugger.IsAttached); // only enable thread tracking if debugger is attached; it adds non-trivial overheads to Enter/Exit
+ _buffers = new T[numberOfBuffers][];
+ _bufferLength = bufferLength;
+ _poolId = poolId;
+ }
+
+ /// <summary>Gets an ID for the bucket to use with events.</summary>
+ internal int Id => GetHashCode();
+
+ /// <summary>Takes an array from the bucket. If the bucket is empty, returns null.</summary>
+ internal T[] Rent()
+ {
+ T[][] buffers = _buffers;
+ T[] buffer = null;
+
+ // While holding the lock, grab whatever is at the next available index and
+ // update the index. We do as little work as possible while holding the spin
+ // lock to minimize contention with other threads. The try/finally is
+ // necessary to properly handle thread aborts on platforms which have them.
+ bool lockTaken = false, allocateBuffer = false;
+ try
+ {
+ _lock.Enter(ref lockTaken);
+
+ if (_index < buffers.Length)
+ {
+ buffer = buffers[_index];
+ buffers[_index++] = null;
+ allocateBuffer = buffer == null;
+ }
+ }
+ finally
+ {
+ if (lockTaken) _lock.Exit(false);
+ }
+
+ // While we were holding the lock, we grabbed whatever was at the next available index, if
+ // there was one. If we tried and if we got back null, that means we hadn't yet allocated
+ // for that slot, in which case we should do so now.
+ if (allocateBuffer)
+ {
+ buffer = new T[_bufferLength];
+
+ var log = ArrayPoolEventSource.Log;
+ if (log.IsEnabled())
+ {
+ log.BufferAllocated(buffer.GetHashCode(), _bufferLength, _poolId, Id,
+ ArrayPoolEventSource.BufferAllocatedReason.Pooled);
+ }
+ }
+
+ return buffer;
+ }
+
+ /// <summary>
+ /// Attempts to return the buffer to the bucket. If successful, the buffer will be stored
+ /// in the bucket and true will be returned; otherwise, the buffer won't be stored, and false
+ /// will be returned.
+ /// </summary>
+ internal void Return(T[] array)
+ {
+ // Check to see if the buffer is the correct size for this bucket
+ if (array.Length != _bufferLength)
+ {
+ throw new ArgumentException(SR.ArgumentException_BufferNotFromPool, nameof(array));
+ }
+
+ // While holding the spin lock, if there's room available in the bucket,
+ // put the buffer into the next available slot. Otherwise, we just drop it.
+ // The try/finally is necessary to properly handle thread aborts on platforms
+ // which have them.
+ bool lockTaken = false;
+ try
+ {
+ _lock.Enter(ref lockTaken);
+
+ if (_index != 0)
+ {
+ _buffers[--_index] = array;
+ }
+ }
+ finally
+ {
+ if (lockTaken) _lock.Exit(false);
+ }
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.Unix.cs b/src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.Unix.cs
new file mode 100644
index 0000000000..8a1d006b12
--- /dev/null
+++ b/src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.Unix.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.
+
+using Microsoft.Win32;
+using System.Runtime.CompilerServices;
+
+namespace System.Buffers
+{
+ internal sealed partial class TlsOverPerCoreLockedStacksArrayPool<T>
+ {
+ /// <summary>Get an identifier for the current thread to use to index into the stacks.</summary>
+ private static int ExecutionId
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get
+ {
+ // On Unix, CurrentProcessorNumber is implemented in terms of sched_getcpu, which
+ // doesn't exist on all platforms. On those it doesn't exist on, GetCurrentProcessorNumber
+ // returns -1. As a fallback in that case and to spread the threads across the buckets
+ // by default, we use the current managed thread ID as a proxy.
+ int id = CurrentProcessorNumber;
+ if (id < 0) id = Environment.CurrentManagedThreadId;
+ return id;
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.Windows.cs b/src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.Windows.cs
new file mode 100644
index 0000000000..d42242c910
--- /dev/null
+++ b/src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.Windows.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 Microsoft.Win32;
+using System.Runtime.CompilerServices;
+using System.Threading;
+
+namespace System.Buffers
+{
+ internal sealed partial class TlsOverPerCoreLockedStacksArrayPool<T> : ArrayPool<T>
+ {
+ /// <summary>Get an identifier for the current thread to use to index into the stacks.</summary>
+ private static int ExecutionId
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get { return CurrentProcessorNumber; }
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs b/src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs
new file mode 100644
index 0000000000..debc33615f
--- /dev/null
+++ b/src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs
@@ -0,0 +1,328 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// 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.Runtime.CompilerServices;
+using System.Threading;
+
+namespace System.Buffers
+{
+ /// <summary>
+ /// Provides an ArrayPool implementation meant to be used as the singleton returned from ArrayPool.Shared.
+ /// </summary>
+ /// <remarks>
+ /// The implementation uses a tiered caching scheme, with a small per-thread cache for each array size, followed
+ /// by a cache per array size shared by all threads, split into per-core stacks meant to be used by threads
+ /// running on that core. Locks are used to protect each per-core stack, because a thread can migrate after
+ /// checking its processor number, because multiple threads could interleave on the same core, and because
+ /// a thread is allowed to check other core's buckets if its core's bucket is empty/full.
+ /// </remarks>
+ internal sealed partial class TlsOverPerCoreLockedStacksArrayPool<T> : ArrayPool<T>
+ {
+ // TODO: #7747: "Investigate optimizing ArrayPool heuristics"
+ // - Explore caching in TLS more than one array per size per thread, and moving stale buffers to the global queue.
+ // - Explore dumping stale buffers from the global queue, similar to PinnableBufferCache (maybe merging them).
+ // - Explore changing the size of each per-core bucket, potentially dynamically or based on other factors like array size.
+ // - Explore changing number of buckets and what sizes of arrays are cached.
+ // - Investigate whether false sharing is causing any issues, in particular on LockedStack's count and the contents of its array.
+ // ...
+
+ /// <summary>The number of buckets (array sizes) in the pool, one for each array length, starting from length 16.</summary>
+ private const int NumBuckets = 17; // Utilities.SelectBucketIndex(2*1024*1024)
+ /// <summary>Maximum number of per-core stacks to use per array size.</summary>
+ private const int MaxPerCorePerArraySizeStacks = 64; // selected to avoid needing to worry about processor groups
+ /// <summary>The maximum number of buffers to store in a bucket's global queue.</summary>
+ private const int MaxBuffersPerArraySizePerCore = 8;
+
+ /// <summary>The length of arrays stored in the corresponding indices in <see cref="_buckets"/> and <see cref="t_tlsBuckets"/>.</summary>
+ private readonly int[] _bucketArraySizes;
+ /// <summary>
+ /// An array of per-core array stacks. The slots are lazily initialized to avoid creating
+ /// lots of overhead for unused array sizes.
+ /// </summary>
+ private readonly PerCoreLockedStacks[] _buckets = new PerCoreLockedStacks[NumBuckets];
+ /// <summary>A per-thread array of arrays, to cache one array per array size per thread.</summary>
+ [ThreadStatic]
+ private static T[][] t_tlsBuckets;
+ /// <summary>
+ /// Cached processor number used as a hint for which per-core stack to access.
+ /// </summary>
+ [ThreadStatic]
+ private static int? t_cachedProcessorNumber;
+
+ /// <summary>Initialize the pool.</summary>
+ public TlsOverPerCoreLockedStacksArrayPool()
+ {
+ var sizes = new int[NumBuckets];
+ for (int i = 0; i < sizes.Length; i++)
+ {
+ sizes[i] = Utilities.GetMaxSizeForBucket(i);
+ }
+ _bucketArraySizes = sizes;
+ }
+
+ /// <summary>Allocate a new PerCoreLockedStacks and try to store it into the <see cref="_buckets"/> array.</summary>
+ private PerCoreLockedStacks CreatePerCoreLockedStacks(int bucketIndex)
+ {
+ var inst = new PerCoreLockedStacks();
+ return Interlocked.CompareExchange(ref _buckets[bucketIndex], inst, null) ?? inst;
+ }
+
+ /// <summary>Gets an ID for the pool to use with events.</summary>
+ private int Id => GetHashCode();
+
+ /// <summary>Gets the processor number associated with the current thread.</summary>
+ /// <remarks>Uses a cached value if one exists on the current thread.</remarks>
+ private static int CurrentProcessorNumber
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get
+ {
+ int? num = t_cachedProcessorNumber;
+ if (!num.HasValue)
+ {
+ t_cachedProcessorNumber = num = Environment.CurrentProcessorNumber;
+ }
+ return num.GetValueOrDefault();
+ }
+ }
+
+ public override T[] Rent(int minimumLength)
+ {
+ // Arrays can't be smaller than zero. We allow requesting zero-length arrays (even though
+ // pooling such an array isn't valuable) as it's a valid length array, and we want the pool
+ // to be usable in general instead of using `new`, even for computed lengths.
+ if (minimumLength < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(minimumLength));
+ }
+ else if (minimumLength == 0)
+ {
+ // No need to log the empty array. Our pool is effectively infinite
+ // and we'll never allocate for rents and never store for returns.
+ return EmptyArray<T>.Value;
+ }
+
+ ArrayPoolEventSource log = ArrayPoolEventSource.Log;
+ T[] buffer;
+
+ // Get the bucket number for the array length
+ int bucketIndex = Utilities.SelectBucketIndex(minimumLength);
+
+ // If the array could come from a bucket...
+ if (bucketIndex < _buckets.Length)
+ {
+ // First try to get it from TLS if possible.
+ T[][] tlsBuckets = t_tlsBuckets;
+ if (tlsBuckets != null)
+ {
+ buffer = tlsBuckets[bucketIndex];
+ if (buffer != null)
+ {
+ tlsBuckets[bucketIndex] = null;
+ if (log.IsEnabled())
+ {
+ log.BufferRented(buffer.GetHashCode(), buffer.Length, Id, bucketIndex);
+ }
+ return buffer;
+ }
+ }
+
+ // We couldn't get a buffer from TLS, so try the global stack.
+ PerCoreLockedStacks b = _buckets[bucketIndex];
+ if (b != null)
+ {
+ buffer = b.TryPop();
+ if (buffer != null)
+ {
+ if (log.IsEnabled())
+ {
+ log.BufferRented(buffer.GetHashCode(), buffer.Length, Id, bucketIndex);
+ }
+ return buffer;
+ }
+ }
+
+ // No buffer available. Allocate a new buffer with a size corresponding to the appropriate bucket.
+ buffer = new T[_bucketArraySizes[bucketIndex]];
+ }
+ else
+ {
+ // The request was for a size too large for the pool. Allocate an array of exactly the requested length.
+ // When it's returned to the pool, we'll simply throw it away.
+ buffer = new T[minimumLength];
+ }
+
+ if (log.IsEnabled())
+ {
+ int bufferId = buffer.GetHashCode(), bucketId = -1; // no bucket for an on-demand allocated buffer
+ log.BufferRented(bufferId, buffer.Length, Id, bucketId);
+ log.BufferAllocated(bufferId, buffer.Length, Id, bucketId, bucketIndex >= _buckets.Length ?
+ ArrayPoolEventSource.BufferAllocatedReason.OverMaximumSize :
+ ArrayPoolEventSource.BufferAllocatedReason.PoolExhausted);
+ }
+
+ return buffer;
+ }
+
+ public override void Return(T[] array, bool clearArray = false)
+ {
+ if (array == null)
+ {
+ throw new ArgumentNullException(nameof(array));
+ }
+
+ // Determine with what bucket this array length is associated
+ int bucketIndex = Utilities.SelectBucketIndex(array.Length);
+
+ // If we can tell that the buffer was allocated (or empty), drop it. Otherwise, check if we have space in the pool.
+ if (bucketIndex < _buckets.Length)
+ {
+ // Clear the array if the user requests.
+ if (clearArray)
+ {
+ Array.Clear(array, 0, array.Length);
+ }
+
+ // Check to see if the buffer is the correct size for this bucket
+ if (array.Length != _bucketArraySizes[bucketIndex])
+ {
+ throw new ArgumentException(SR.ArgumentException_BufferNotFromPool, nameof(array));
+ }
+
+ // Write through the TLS bucket. If there weren't any buckets, create them
+ // and store this array into it. If there were, store this into it, and
+ // if there was a previous one there, push that to the global stack. This
+ // helps to keep LIFO access such that the most recently pushed stack will
+ // be in TLS and the first to be popped next.
+ T[][] tlsBuckets = t_tlsBuckets;
+ if (tlsBuckets == null)
+ {
+ t_tlsBuckets = tlsBuckets = new T[NumBuckets][];
+ tlsBuckets[bucketIndex] = array;
+ }
+ else
+ {
+ T[] prev = tlsBuckets[bucketIndex];
+ tlsBuckets[bucketIndex] = array;
+ if (prev != null)
+ {
+ PerCoreLockedStacks bucket = _buckets[bucketIndex] ?? CreatePerCoreLockedStacks(bucketIndex);
+ bucket.TryPush(prev);
+ }
+ }
+ }
+
+ // Log that the buffer was returned
+ ArrayPoolEventSource log = ArrayPoolEventSource.Log;
+ if (log.IsEnabled())
+ {
+ log.BufferReturned(array.GetHashCode(), array.Length, Id);
+ }
+ }
+
+ /// <summary>
+ /// Stores a set of stacks of arrays, with one stack per core.
+ /// </summary>
+ private sealed class PerCoreLockedStacks
+ {
+ /// <summary>The stacks.</summary>
+ private readonly LockedStack[] _perCoreStacks;
+
+ /// <summary>Initializes the stacks.</summary>
+ public PerCoreLockedStacks()
+ {
+ // Create the stacks. We create as many as there are processors, limited by our max.
+ var stacks = new LockedStack[Math.Min(Environment.ProcessorCount, MaxPerCorePerArraySizeStacks)];
+ for (int i = 0; i < stacks.Length; i++)
+ {
+ stacks[i] = new LockedStack();
+ }
+ _perCoreStacks = stacks;
+ }
+
+ /// <summary>Try to push the array into the stacks. If each is full when it's tested, the array will be dropped.</summary>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void TryPush(T[] array)
+ {
+ // Try to push on to the associated stack first. If that fails,
+ // round-robin through the other stacks.
+ LockedStack[] stacks = _perCoreStacks;
+ int index = ExecutionId % stacks.Length;
+ for (int i = 0; i < stacks.Length; i++)
+ {
+ if (stacks[index].TryPush(array)) return;
+ if (++index == stacks.Length) index = 0;
+ }
+ }
+
+ /// <summary>Try to get an array from the stacks. If each is empty when it's tested, null will be returned.</summary>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public T[] TryPop()
+ {
+ // Try to pop from the associated stack first. If that fails,
+ // round-robin through the other stacks.
+ T[] arr;
+ LockedStack[] stacks = _perCoreStacks;
+ int index = ExecutionId % stacks.Length;
+ for (int i = 0; i < stacks.Length; i++)
+ {
+ if ((arr = stacks[index].TryPop()) != null) return arr;
+ if (++index == stacks.Length) index = 0;
+ }
+ return null;
+ }
+ }
+
+ /// <summary>Provides a simple stack of arrays, protected by a lock.</summary>
+ private sealed class LockedStack
+ {
+ private readonly T[][] _arrays = new T[MaxBuffersPerArraySizePerCore][];
+ private int _count;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public bool TryPush(T[] array)
+ {
+ bool enqueued = false;
+ MonitorEnterWithProcNumberFlush(this);
+ if (_count < MaxBuffersPerArraySizePerCore)
+ {
+ _arrays[_count++] = array;
+ enqueued = true;
+ }
+ Monitor.Exit(this);
+ return enqueued;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public T[] TryPop()
+ {
+ T[] arr = null;
+ MonitorEnterWithProcNumberFlush(this);
+ if (_count > 0)
+ {
+ arr = _arrays[--_count];
+ _arrays[_count] = null;
+ }
+ Monitor.Exit(this);
+ return arr;
+ }
+
+ /// <summary>
+ /// Enters the monitor on the object. If there is any contention while trying
+ /// to acquire the monitor, it flushes the cached processor number so that subsequent
+ /// attempts to access the per-core stacks will use an updated processor number.
+ /// </summary>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static void MonitorEnterWithProcNumberFlush(object obj)
+ {
+ if (!Monitor.TryEnter(obj))
+ {
+ t_cachedProcessorNumber = null;
+ Monitor.Enter(obj);
+ }
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/Buffers/Utilities.cs b/src/mscorlib/corefx/System/Buffers/Utilities.cs
new file mode 100644
index 0000000000..823299f5fc
--- /dev/null
+++ b/src/mscorlib/corefx/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/corefx/System/Globalization/Calendar.cs b/src/mscorlib/corefx/System/Globalization/Calendar.cs
index 343682d156..78e9f00d08 100644
--- a/src/mscorlib/corefx/System/Globalization/Calendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/Calendar.cs
@@ -2,9 +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.Runtime.CompilerServices;
-using System.Globalization;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.Serialization;
@@ -99,8 +97,14 @@ namespace System.Globalization
}
}
-
-
+ [System.Runtime.InteropServices.ComVisible(false)]
+ public virtual CalendarAlgorithmType AlgorithmType
+ {
+ get
+ {
+ return CalendarAlgorithmType.Unknown;
+ }
+ }
protected Calendar()
{
@@ -164,9 +168,9 @@ namespace System.Globalization
//
////////////////////////////////////////////////////////////////////////
[System.Runtime.InteropServices.ComVisible(false)]
- internal static Calendar ReadOnly(Calendar calendar)
+ public static Calendar ReadOnly(Calendar calendar)
{
- if (calendar == null) { throw new ArgumentNullException("calendar"); }
+ if (calendar == null) { throw new ArgumentNullException(nameof(calendar)); }
Contract.EndContractBlock();
if (calendar.IsReadOnly) { return (calendar); }
@@ -206,7 +210,7 @@ namespace System.Globalization
// The following code assumes that the current era value can not be -1.
if (_currentEraValue == -1)
{
- Contract.Assert(BaseCalendarID != CalendarId.UNINITIALIZED_VALUE, "[Calendar.CurrentEraValue] Expected a real calendar ID");
+ Debug.Assert(BaseCalendarID != CalendarId.UNINITIALIZED_VALUE, "[Calendar.CurrentEraValue] Expected a real calendar ID");
_currentEraValue = CalendarData.GetCalendarData(BaseCalendarID).iCurrentEra;
}
return (_currentEraValue);
@@ -242,7 +246,7 @@ namespace System.Globalization
double tempMillis = (value * scale + (value >= 0 ? 0.5 : -0.5));
if (!((tempMillis > -(double)MaxMillis) && (tempMillis < (double)MaxMillis)))
{
- throw new ArgumentOutOfRangeException("value", SR.ArgumentOutOfRange_AddValue);
+ throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_AddValue);
}
long millis = (long)tempMillis;
@@ -521,7 +525,7 @@ namespace System.Globalization
// 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;
- Contract.Assert(offset >= 0, "Calendar.GetFirstDayWeekOfYear(): offset >= 0");
+ Debug.Assert(offset >= 0, "Calendar.GetFirstDayWeekOfYear(): offset >= 0");
return ((dayOfYear + offset) / 7 + 1);
}
@@ -646,7 +650,7 @@ namespace System.Globalization
if ((int)firstDayOfWeek < 0 || (int)firstDayOfWeek > 6)
{
throw new ArgumentOutOfRangeException(
- "firstDayOfWeek", SR.Format(SR.ArgumentOutOfRange_Range,
+ nameof(firstDayOfWeek), SR.Format(SR.ArgumentOutOfRange_Range,
DayOfWeek.Sunday, DayOfWeek.Saturday));
}
Contract.EndContractBlock();
@@ -660,7 +664,7 @@ namespace System.Globalization
return (GetWeekOfYearFullDays(time, (int)firstDayOfWeek, 4));
}
throw new ArgumentOutOfRangeException(
- "rule", SR.Format(SR.ArgumentOutOfRange_Range,
+ nameof(rule), SR.Format(SR.ArgumentOutOfRange_Range,
CalendarWeekRule.FirstDay, CalendarWeekRule.FirstFourDayWeek));
}
@@ -700,6 +704,16 @@ namespace System.Globalization
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.
+ //
+
+ [System.Runtime.InteropServices.ComVisible(false)]
+ 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.
//
@@ -808,7 +822,7 @@ namespace System.Globalization
{
if (year < 0)
{
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
SR.ArgumentOutOfRange_NeedNonNegNum);
}
Contract.EndContractBlock();
@@ -830,7 +844,7 @@ namespace System.Globalization
if (millisecond < 0 || millisecond >= MillisPerSecond)
{
throw new ArgumentOutOfRangeException(
- "millisecond",
+ nameof(millisecond),
String.Format(
CultureInfo.InvariantCulture,
SR.Format(SR.ArgumentOutOfRange_Range, 0, MillisPerSecond - 1)));
diff --git a/src/mscorlib/corefx/System/Globalization/CalendarAlgorithmType.cs b/src/mscorlib/corefx/System/Globalization/CalendarAlgorithmType.cs
new file mode 100644
index 0000000000..159b0e6f77
--- /dev/null
+++ b/src/mscorlib/corefx/System/Globalization/CalendarAlgorithmType.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.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
index 6c6a18ec37..270d62f143 100644
--- a/src/mscorlib/corefx/System/Globalization/CalendarData.Unix.cs
+++ b/src/mscorlib/corefx/System/Globalization/CalendarData.Unix.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.Diagnostics.Contracts;
using System.Runtime.InteropServices;
using System.Security;
@@ -200,7 +201,7 @@ namespace System.Globalization
break;
default:
const string unsupportedDateFieldSymbols = "YuUrQqwWDFg";
- Contract.Assert(unsupportedDateFieldSymbols.IndexOf(input[index]) == -1,
+ 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]));
diff --git a/src/mscorlib/corefx/System/Globalization/CalendarData.cs b/src/mscorlib/corefx/System/Globalization/CalendarData.cs
index 2dbd1b8069..d22bd67ac1 100644
--- a/src/mscorlib/corefx/System/Globalization/CalendarData.cs
+++ b/src/mscorlib/corefx/System/Globalization/CalendarData.cs
@@ -2,11 +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.Runtime.InteropServices;
-using System.Runtime.CompilerServices;
-using System.Diagnostics.Contracts;
-using System.Collections.Generic;
+using System.Diagnostics;
namespace System.Globalization
{
@@ -108,7 +104,7 @@ namespace System.Globalization
if (!LoadCalendarDataFromSystem(localeName, calendarId))
{
- Contract.Assert(false, "[CalendarData] LoadCalendarDataFromSystem 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.
diff --git a/src/mscorlib/corefx/System/Globalization/CalendricalCalculationsHelper.cs b/src/mscorlib/corefx/System/Globalization/CalendricalCalculationsHelper.cs
index ba7601b420..149e63c689 100644
--- a/src/mscorlib/corefx/System/Globalization/CalendricalCalculationsHelper.cs
+++ b/src/mscorlib/corefx/System/Globalization/CalendricalCalculationsHelper.cs
@@ -2,8 +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.Diagnostics.Contracts;
+using System.Diagnostics;
namespace System.Globalization
{
@@ -126,7 +125,7 @@ namespace System.Globalization
return longitude;
}
- static public double AsDayFraction(double longitude)
+ public static double AsDayFraction(double longitude)
{
return longitude / FullCircleOfArc;
}
@@ -153,7 +152,7 @@ namespace System.Globalization
// the following formulas defines a polynomial function which gives us the amount that the earth is slowing down for specific year ranges
private static double DefaultEphemerisCorrection(int gregorianYear)
{
- Contract.Assert(gregorianYear < 1620 || 2020 <= gregorianYear);
+ Debug.Assert(gregorianYear < 1620 || 2020 <= gregorianYear);
long january1stOfYear = GetNumberOfDays(new DateTime(gregorianYear, 1, 1));
double daysSinceStartOf1810 = january1stOfYear - StartOf1810;
double x = TwelveHours + daysSinceStartOf1810;
@@ -162,34 +161,34 @@ namespace System.Globalization
private static double EphemerisCorrection1988to2019(int gregorianYear)
{
- Contract.Assert(1988 <= gregorianYear && gregorianYear <= 2019);
+ Debug.Assert(1988 <= gregorianYear && gregorianYear <= 2019);
return (double)(gregorianYear - 1933) / SecondsPerDay;
}
private static double EphemerisCorrection1900to1987(int gregorianYear)
{
- Contract.Assert(1900 <= gregorianYear && gregorianYear <= 1987);
+ Debug.Assert(1900 <= gregorianYear && gregorianYear <= 1987);
double centuriesFrom1900 = CenturiesFrom1900(gregorianYear);
return PolynomialSum(s_coefficients1900to1987, centuriesFrom1900);
}
private static double EphemerisCorrection1800to1899(int gregorianYear)
{
- Contract.Assert(1800 <= gregorianYear && gregorianYear <= 1899);
+ Debug.Assert(1800 <= gregorianYear && gregorianYear <= 1899);
double centuriesFrom1900 = CenturiesFrom1900(gregorianYear);
return PolynomialSum(s_coefficients1800to1899, centuriesFrom1900);
}
private static double EphemerisCorrection1700to1799(int gregorianYear)
{
- Contract.Assert(1700 <= gregorianYear && gregorianYear <= 1799);
+ Debug.Assert(1700 <= gregorianYear && gregorianYear <= 1799);
double yearsSince1700 = gregorianYear - 1700;
return PolynomialSum(s_coefficients1700to1799, yearsSince1700) / SecondsPerDay;
}
private static double EphemerisCorrection1620to1699(int gregorianYear)
{
- Contract.Assert(1620 <= gregorianYear && gregorianYear <= 1699);
+ Debug.Assert(1620 <= gregorianYear && gregorianYear <= 1699);
double yearsSince1600 = gregorianYear - 1600;
return PolynomialSum(s_coefficients1620to1699, yearsSince1600) / SecondsPerDay;
}
@@ -216,11 +215,11 @@ namespace System.Globalization
}
}
- Contract.Assert(false, "Not expected to come here");
+ Debug.Assert(false, "Not expected to come here");
return DefaultEphemerisCorrection(year);
}
- static public double JulianCenturies(double moment)
+ public static double JulianCenturies(double moment)
{
double dynamicalMoment = moment + EphemerisCorrection(moment);
return (dynamicalMoment - Noon2000Jan01) / DaysInUniformLengthCentury;
@@ -274,7 +273,7 @@ namespace System.Globalization
}
// midday
- static public double Midday(double date, double longitude)
+ public static double Midday(double date, double longitude)
{
return AsLocalTime(date + TwelveHours, longitude) - AsDayFraction(longitude);
}
@@ -285,7 +284,7 @@ namespace System.Globalization
}
// midday-in-tehran
- static public double MiddayAtPersianObservationSite(double date)
+ public static double MiddayAtPersianObservationSite(double date)
{
return Midday(date, InitLongitude(52.5)); // 52.5 degrees east - longitude of UTC+3:30 which defines Iranian Standard Time
}
@@ -362,7 +361,7 @@ namespace System.Globalization
return (-0.004778 * SinOfDegree(a)) - (0.0003667 * SinOfDegree(b));
}
- static public double Compute(double time)
+ public static double Compute(double time)
{
double julianCenturies = JulianCenturies(time);
double lambda = 282.7771834
@@ -373,7 +372,7 @@ namespace System.Globalization
return InitLongitude(longitude);
}
- static public double AsSeason(double longitude)
+ public static double AsSeason(double longitude)
{
return (longitude < 0) ? (longitude + FullCircleOfArc) : longitude;
}
@@ -405,7 +404,7 @@ namespace System.Globalization
break;
}
}
- Contract.Assert(day != upperBoundNewYearDay);
+ Debug.Assert(day != upperBoundNewYearDay);
return day - 1;
}
diff --git a/src/mscorlib/corefx/System/Globalization/CharUnicodeInfo.cs b/src/mscorlib/corefx/System/Globalization/CharUnicodeInfo.cs
index 4cb95fb8f1..dc38ca405b 100644
--- a/src/mscorlib/corefx/System/Globalization/CharUnicodeInfo.cs
+++ b/src/mscorlib/corefx/System/Globalization/CharUnicodeInfo.cs
@@ -12,12 +12,7 @@
//
////////////////////////////////////////////////////////////////////////////
-using System;
-using System.Threading;
-using System.Runtime.InteropServices;
-using System.Runtime.CompilerServices;
-using System.Reflection;
-using System.Security;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
namespace System.Globalization
@@ -59,8 +54,8 @@ namespace System.Globalization
internal static int InternalConvertToUtf32(String s, int index)
{
- Contract.Assert(s != null, "s != null");
- Contract.Assert(index >= 0 && index < s.Length, "index < s.Length");
+ 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;
@@ -100,9 +95,9 @@ namespace System.Globalization
internal static int InternalConvertToUtf32(String s, int index, out int charLength)
{
- Contract.Assert(s != null, "s != null");
- Contract.Assert(s.Length > 0, "s.Length > 0");
- Contract.Assert(index >= 0 && index < s.Length, "index >= 0 && index < s.Length");
+ 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)
{
@@ -131,8 +126,8 @@ namespace System.Globalization
internal static bool IsWhiteSpace(String s, int index)
{
- Contract.Assert(s != null, "s!=null");
- Contract.Assert(index >= 0 && index < s.Length, "index >= 0 && index < s.Length");
+ 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".
@@ -170,9 +165,9 @@ namespace System.Globalization
//
// 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)
{
- Contract.Assert(ch >= 0 && ch <= 0x10ffff, "ch is not in valid Unicode range.");
+ 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.
@@ -191,6 +186,21 @@ namespace System.Globalization
}
}
+ 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)]];
+ }
+ }
////////////////////////////////////////////////////////////////////////
//
@@ -218,16 +228,58 @@ namespace System.Globalization
{
if (s == null)
{
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
}
if (index < 0 || index >= s.Length)
{
- throw new ArgumentOutOfRangeException("index", SR.ArgumentOutOfRange_Index);
+ 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));
@@ -236,16 +288,16 @@ namespace System.Globalization
public static UnicodeCategory GetUnicodeCategory(String s, int index)
{
if (s == null)
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
if (((uint)index) >= ((uint)s.Length))
{
- throw new ArgumentOutOfRangeException("index");
+ 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));
}
@@ -265,9 +317,9 @@ namespace System.Globalization
//
////////////////////////////////////////////////////////////////////////
- internal unsafe static byte InternalGetCategoryValue(int ch, int offset)
+ internal static unsafe byte InternalGetCategoryValue(int ch, int offset)
{
- Contract.Assert(ch >= 0 && ch <= 0x10ffff, "ch is not in valid Unicode range.");
+ 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.
@@ -284,7 +336,7 @@ namespace System.Globalization
// Make sure that OtherNotAssigned is the last category in UnicodeCategory.
// If that changes, change the following assertion as well.
//
- //Contract.Assert(uc >= 0 && uc <= UnicodeCategory.OtherNotAssigned, "Table returns incorrect Unicode category");
+ //Debug.Assert(uc >= 0 && uc <= UnicodeCategory.OtherNotAssigned, "Table returns incorrect Unicode category");
return (uc);
}
}
@@ -304,8 +356,8 @@ namespace System.Globalization
internal static UnicodeCategory InternalGetUnicodeCategory(String value, int index)
{
- Contract.Assert(value != null, "value can not be null");
- Contract.Assert(index < value.Length, "index < value.Length");
+ Debug.Assert(value != null, "value can not be null");
+ Debug.Assert(index < value.Length, "index < value.Length");
return (InternalGetUnicodeCategory(InternalConvertToUtf32(value, index)));
}
@@ -319,16 +371,16 @@ namespace System.Globalization
internal static UnicodeCategory InternalGetUnicodeCategory(String str, int index, out int charLength)
{
- Contract.Assert(str != null, "str can not be null");
- Contract.Assert(str.Length > 0, "str.Length > 0"); ;
- Contract.Assert(index >= 0 && index < str.Length, "index >= 0 && index < str.Length");
+ 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)
{
- Contract.Assert(uc >= 0, "uc >= 0");
+ Debug.Assert(uc >= 0, "uc >= 0");
return (
uc == UnicodeCategory.NonSpacingMark ||
uc == UnicodeCategory.SpacingCombiningMark ||
diff --git a/src/mscorlib/corefx/System/Globalization/CharUnicodeInfoData.cs b/src/mscorlib/corefx/System/Globalization/CharUnicodeInfoData.cs
index 7284cfd3bc..b1bef8146e 100644
--- a/src/mscorlib/corefx/System/Globalization/CharUnicodeInfoData.cs
+++ b/src/mscorlib/corefx/System/Globalization/CharUnicodeInfoData.cs
@@ -1218,5 +1218,30 @@ namespace System.Globalization
0x00, 0x00, 0x00, 0x00, 0x80, 0x84, 0x2e, 0x41, 0x00, 0x00, 0x00, 0x00, 0x84, 0xd7, 0x97, 0x41,
0x00, 0x00, 0x00, 0x20, 0x5f, 0xa0, 0x02, 0x42, 0x00, 0x00, 0x00, 0xa2, 0x94, 0x1a, 0x6d, 0x42
};
+
+ private static ushort[] s_pDigitValues = new ushort []
+ {
+ 0xffff, 0x0000, 0x0101, 0x0202, 0x0303, 0x0404, 0x0505, 0x0606,
+ 0x0707, 0x0808, 0x0909, 0xff02, 0xff03, 0xff01, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xff04, 0xff05, 0xff06,
+ 0xff07, 0xff08, 0xff09, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xff00, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0x0000
+ };
+
}
}
diff --git a/src/mscorlib/corefx/System/Globalization/ChineseLunisolarCalendar.cs b/src/mscorlib/corefx/System/Globalization/ChineseLunisolarCalendar.cs
index 48f62019d7..271d9802ce 100644
--- a/src/mscorlib/corefx/System/Globalization/ChineseLunisolarCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/ChineseLunisolarCalendar.cs
@@ -342,13 +342,13 @@ namespace System.Globalization
{
if (era != CurrentEra && era != ChineseEra)
{
- throw new ArgumentOutOfRangeException("era", SR.ArgumentOutOfRange_InvalidEraValue);
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
if (year < MIN_LUNISOLAR_YEAR || year > MAX_LUNISOLAR_YEAR)
{
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range, MIN_LUNISOLAR_YEAR, MAX_LUNISOLAR_YEAR));
diff --git a/src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs b/src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs
index 2aaf5a22fa..21c3c9f7e4 100644
--- a/src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs
+++ b/src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs
@@ -2,6 +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.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -17,7 +18,6 @@ namespace System.Globalization
[NonSerialized]
private bool _isAsciiEqualityOrdinal;
- [SecuritySafeCritical]
internal CompareInfo(CultureInfo culture)
{
_name = culture.m_name;
@@ -27,14 +27,23 @@ namespace System.Globalization
private void InitSort(CultureInfo culture)
{
_sortName = culture.SortName;
- _sortHandle = Interop.GlobalizationInterop.GetSortHandle(GetNullTerminatedUtf8String(_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)
{
- Contract.Assert(source != null);
- Contract.Assert(value != null);
+ Debug.Assert(source != null);
+ Debug.Assert(value != null);
if (value.Length == 0)
{
@@ -77,8 +86,8 @@ namespace System.Globalization
internal static unsafe int LastIndexOfOrdinal(string source, string value, int startIndex, int count, bool ignoreCase)
{
- Contract.Assert(source != null);
- Contract.Assert(value != null);
+ Debug.Assert(source != null);
+ Debug.Assert(value != null);
if (value.Length == 0)
{
@@ -124,8 +133,8 @@ namespace System.Globalization
private int GetHashCodeOfStringCore(string source, CompareOptions options)
{
- Contract.Assert(source != null);
- Contract.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
+ Debug.Assert(source != null);
+ Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
return GetHashCodeOfStringCore(source, options, forceRandomizedHashing: false, additionalEntropy: 0);
}
@@ -137,9 +146,9 @@ namespace System.Globalization
private unsafe int CompareString(string string1, int offset1, int length1, string string2, int offset2, int length2, CompareOptions options)
{
- Contract.Assert(string1 != null);
- Contract.Assert(string2 != null);
- Contract.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
+ Debug.Assert(string1 != null);
+ Debug.Assert(string2 != null);
+ Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
fixed (char* pString1 = string1)
{
@@ -152,9 +161,9 @@ namespace System.Globalization
private unsafe int IndexOfCore(string source, string target, int startIndex, int count, CompareOptions options)
{
- Contract.Assert(!string.IsNullOrEmpty(source));
- Contract.Assert(target != null);
- Contract.Assert((options & CompareOptions.OrdinalIgnoreCase) == 0);
+ Debug.Assert(!string.IsNullOrEmpty(source));
+ Debug.Assert(target != null);
+ Debug.Assert((options & CompareOptions.OrdinalIgnoreCase) == 0);
if (target.Length == 0)
{
@@ -181,9 +190,9 @@ namespace System.Globalization
private unsafe int LastIndexOfCore(string source, string target, int startIndex, int count, CompareOptions options)
{
- Contract.Assert(!string.IsNullOrEmpty(source));
- Contract.Assert(target != null);
- Contract.Assert((options & CompareOptions.OrdinalIgnoreCase) == 0);
+ Debug.Assert(!string.IsNullOrEmpty(source));
+ Debug.Assert(target != null);
+ Debug.Assert((options & CompareOptions.OrdinalIgnoreCase) == 0);
if (target.Length == 0)
{
@@ -212,12 +221,11 @@ namespace System.Globalization
}
}
- [SecuritySafeCritical]
private bool StartsWith(string source, string prefix, CompareOptions options)
{
- Contract.Assert(!string.IsNullOrEmpty(source));
- Contract.Assert(!string.IsNullOrEmpty(prefix));
- Contract.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
+ 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())
{
@@ -227,12 +235,11 @@ namespace System.Globalization
return Interop.GlobalizationInterop.StartsWith(_sortHandle, prefix, prefix.Length, source, source.Length, options);
}
- [SecuritySafeCritical]
private bool EndsWith(string source, string suffix, CompareOptions options)
{
- Contract.Assert(!string.IsNullOrEmpty(source));
- Contract.Assert(!string.IsNullOrEmpty(suffix));
- Contract.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
+ 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())
{
@@ -241,16 +248,81 @@ namespace System.Globalization
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 ----
// -----------------------------
- [SecuritySafeCritical]
internal unsafe int GetHashCodeOfStringCore(string source, CompareOptions options, bool forceRandomizedHashing, long additionalEntropy)
{
- Contract.Assert(source != null);
- Contract.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
+ Debug.Assert(source != null);
+ Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
if (source.Length == 0)
{
@@ -307,9 +379,19 @@ namespace System.Globalization
int bytesWritten = System.Text.Encoding.UTF8.GetBytes(s, 0, s.Length, buffer, 0);
- Contract.Assert(bytesWritten == byteLen);
+ 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
index 744a48b107..4ebaf9cb10 100644
--- a/src/mscorlib/corefx/System/Globalization/CompareInfo.Windows.cs
+++ b/src/mscorlib/corefx/System/Globalization/CompareInfo.Windows.cs
@@ -2,6 +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.Diagnostics;
using System.Diagnostics.Contracts;
namespace System.Globalization
@@ -53,24 +54,24 @@ namespace System.Globalization
internal static int IndexOfOrdinal(string source, string value, int startIndex, int count, bool ignoreCase)
{
- Contract.Assert(source != null);
- Contract.Assert(value != null);
+ 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)
{
- Contract.Assert(source != null);
- Contract.Assert(value != null);
+ 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)
{
- Contract.Assert(source != null);
- Contract.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
+ Debug.Assert(source != null);
+ Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
if (source.Length == 0)
{
@@ -102,9 +103,9 @@ namespace System.Globalization
private unsafe int CompareString(string string1, int offset1, int length1, string string2, int offset2, int length2, CompareOptions options)
{
- Contract.Assert(string1 != null);
- Contract.Assert(string2 != null);
- Contract.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
+ Debug.Assert(string1 != null);
+ Debug.Assert(string2 != null);
+ Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
string localeName = _sortHandle != IntPtr.Zero ? null : _sortName;
@@ -167,9 +168,9 @@ namespace System.Globalization
private int IndexOfCore(string source, string target, int startIndex, int count, CompareOptions options)
{
- Contract.Assert(!string.IsNullOrEmpty(source));
- Contract.Assert(target != null);
- Contract.Assert((options & CompareOptions.OrdinalIgnoreCase) == 0);
+ 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.
@@ -200,9 +201,9 @@ namespace System.Globalization
private int LastIndexOfCore(string source, string target, int startIndex, int count, CompareOptions options)
{
- Contract.Assert(!string.IsNullOrEmpty(source));
- Contract.Assert(target != null);
- Contract.Assert((options & CompareOptions.OrdinalIgnoreCase) == 0);
+ 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.
@@ -234,9 +235,9 @@ namespace System.Globalization
private bool StartsWith(string source, string prefix, CompareOptions options)
{
- Contract.Assert(!string.IsNullOrEmpty(source));
- Contract.Assert(!string.IsNullOrEmpty(prefix));
- Contract.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
+ 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,
@@ -249,9 +250,9 @@ namespace System.Globalization
private bool EndsWith(string source, string suffix, CompareOptions options)
{
- Contract.Assert(!string.IsNullOrEmpty(source));
- Contract.Assert(!string.IsNullOrEmpty(suffix));
- Contract.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
+ 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,
@@ -280,14 +281,10 @@ namespace System.Globalization
int sourceStartIndex = findLastIndex ? startIndex - sourceCount + 1 : startIndex;
-#if !TEST_CODEGEN_OPTIMIZATION
fixed (char* pSource = source, spTarget = target)
{
char* spSubSource = pSource + sourceStartIndex;
-#else
- String.StringPointer spSubSource = source.GetStringPointer(sourceStartIndex);
- String.StringPointer spTarget = target.GetStringPointer();
-#endif
+
if (findLastIndex)
{
int startPattern = (sourceCount - 1) - targetCount + 1;
@@ -347,11 +344,29 @@ namespace System.Globalization
retValue += startIndex;
}
}
-#if !TEST_CODEGEN_OPTIMIZATION
}
return retValue;
-#endif // TEST_CODEGEN_OPTIMIZATION
+ }
+
+ 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
@@ -381,7 +396,7 @@ namespace System.Globalization
// Suffix & Prefix shouldn't use this, make sure to turn off the NORM_LINGUISTIC_CASING flag
if (options == CompareOptions.Ordinal) { nativeCompareFlags = COMPARE_OPTIONS_ORDINAL; }
- Contract.Assert(((options & ~(CompareOptions.IgnoreCase |
+ Debug.Assert(((options & ~(CompareOptions.IgnoreCase |
CompareOptions.IgnoreKanaType |
CompareOptions.IgnoreNonSpace |
CompareOptions.IgnoreSymbols |
@@ -391,5 +406,10 @@ namespace System.Globalization
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
index 77778af23c..64dbfe84f7 100644
--- a/src/mscorlib/corefx/System/Globalization/CompareInfo.cs
+++ b/src/mscorlib/corefx/System/Globalization/CompareInfo.cs
@@ -12,20 +12,15 @@
//
////////////////////////////////////////////////////////////////////////////
-using System;
-using System.Collections;
-using System.Collections.Generic;
+using System.Reflection;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
using System.Runtime.Serialization;
-using System.Threading;
namespace System.Globalization
{
[Flags]
[Serializable]
- [System.Runtime.InteropServices.ComVisible(true)]
public enum CompareOptions
{
None = 0x00000000,
@@ -40,7 +35,6 @@ namespace System.Globalization
}
[Serializable]
- [System.Runtime.InteropServices.ComVisible(true)]
public partial class CompareInfo : IDeserializationCallback
{
// Mask used to check if IndexOf()/LastIndexOf()/IsPrefix()/IsPostfix() has the right flags.
@@ -58,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.
@@ -69,6 +68,86 @@ namespace System.Globalization
[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.
@@ -82,13 +161,40 @@ namespace System.Globalization
{
if (name == null)
{
- throw new ArgumentNullException("name");
+ 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)
{
@@ -130,12 +236,11 @@ namespace System.Globalization
//
////////////////////////////////////////////////////////////////////////
- [System.Runtime.InteropServices.ComVisible(false)]
public virtual String Name
{
get
{
- Contract.Assert(_name != null, "CompareInfo.Name Expected _name to be set");
+ Debug.Assert(_name != null, "CompareInfo.Name Expected _name to be set");
if (_name == "zh-CHT" || _name == "zh-CHS")
{
return _name;
@@ -173,14 +278,14 @@ namespace System.Globalization
{
if (options != CompareOptions.Ordinal)
{
- throw new ArgumentException(SR.Argument_CompareOptionOrdinal, "options");
+ throw new ArgumentException(SR.Argument_CompareOptionOrdinal, nameof(options));
}
return String.CompareOrdinal(string1, string2);
}
if ((options & ValidCompareMaskOffFlags) != 0)
{
- throw new ArgumentException(SR.Argument_InvalidFlag, "options");
+ throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
}
//Our paradigm is that null sorts less than any other string and
@@ -247,31 +352,31 @@ namespace System.Globalization
// Verify inputs
if (length1 < 0 || length2 < 0)
{
- throw new ArgumentOutOfRangeException((length1 < 0) ? "length1" : "length2", SR.ArgumentOutOfRange_NeedPosNum);
+ throw new ArgumentOutOfRangeException((length1 < 0) ? nameof(length1) : nameof(length2), SR.ArgumentOutOfRange_NeedPosNum);
}
if (offset1 < 0 || offset2 < 0)
{
- throw new ArgumentOutOfRangeException((offset1 < 0) ? "offset1" : "offset2", SR.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("string1", SR.ArgumentOutOfRange_OffsetLength);
+ throw new ArgumentOutOfRangeException(nameof(string1), SR.ArgumentOutOfRange_OffsetLength);
}
if (offset2 > (string2 == null ? 0 : string2.Length) - length2)
{
- throw new ArgumentOutOfRangeException("string2", SR.ArgumentOutOfRange_OffsetLength);
+ throw new ArgumentOutOfRangeException(nameof(string2), SR.ArgumentOutOfRange_OffsetLength);
}
if ((options & CompareOptions.Ordinal) != 0)
{
if (options != CompareOptions.Ordinal)
{
throw new ArgumentException(SR.Argument_CompareOptionOrdinal,
- "options");
+ nameof(options));
}
}
else if ((options & ValidCompareMaskOffFlags) != 0)
{
- throw new ArgumentException(SR.Argument_InvalidFlag, "options");
+ throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
}
//
@@ -318,8 +423,8 @@ namespace System.Globalization
//
internal static unsafe int CompareOrdinalIgnoreCase(string strA, int indexA, int lengthA, string strB, int indexB, int lengthB)
{
- Contract.Assert(indexA + lengthA <= strA.Length);
- Contract.Assert(indexB + lengthB <= strB.Length);
+ Debug.Assert(indexA + lengthA <= strA.Length);
+ Debug.Assert(indexB + lengthB <= strB.Length);
int length = Math.Min(lengthA, lengthB);
int range = length;
@@ -375,7 +480,7 @@ namespace System.Globalization
{
if (source == null || prefix == null)
{
- throw new ArgumentNullException((source == null ? "source" : "prefix"),
+ throw new ArgumentNullException((source == null ? nameof(source) : nameof(prefix)),
SR.ArgumentNull_String);
}
Contract.EndContractBlock();
@@ -402,7 +507,7 @@ namespace System.Globalization
if ((options & ValidIndexMaskOffFlags) != 0)
{
- throw new ArgumentException(SR.Argument_InvalidFlag, "options");
+ throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
}
return StartsWith(source, prefix, options);
@@ -425,7 +530,7 @@ namespace System.Globalization
{
if (source == null || suffix == null)
{
- throw new ArgumentNullException((source == null ? "source" : "suffix"),
+ throw new ArgumentNullException((source == null ? nameof(source) : nameof(suffix)),
SR.ArgumentNull_String);
}
Contract.EndContractBlock();
@@ -452,7 +557,7 @@ namespace System.Globalization
if ((options & ValidIndexMaskOffFlags) != 0)
{
- throw new ArgumentException(SR.Argument_InvalidFlag, "options");
+ throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
}
return EndsWith(source, suffix, options);
@@ -481,7 +586,7 @@ namespace System.Globalization
public unsafe virtual int IndexOf(String source, char value)
{
if (source == null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
return IndexOf(source, value, 0, source.Length, CompareOptions.None);
@@ -491,7 +596,7 @@ namespace System.Globalization
public unsafe virtual int IndexOf(String source, String value)
{
if (source == null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
return IndexOf(source, value, 0, source.Length, CompareOptions.None);
@@ -501,7 +606,7 @@ namespace System.Globalization
public unsafe virtual int IndexOf(String source, char value, CompareOptions options)
{
if (source == null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
return IndexOf(source, value, 0, source.Length, options);
@@ -511,17 +616,34 @@ namespace System.Globalization
public unsafe virtual int IndexOf(String source, String value, CompareOptions options)
{
if (source == null)
- throw new ArgumentNullException("source");
+ 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("source");
+ throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
return IndexOf(source, value, startIndex, source.Length - startIndex, options);
@@ -531,7 +653,7 @@ namespace System.Globalization
public unsafe virtual int IndexOf(String source, String value, int startIndex, CompareOptions options)
{
if (source == null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
return IndexOf(source, value, startIndex, source.Length - startIndex, options);
@@ -553,13 +675,13 @@ namespace System.Globalization
{
// Validate inputs
if (source == null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
if (startIndex < 0 || startIndex > source.Length)
- throw new ArgumentOutOfRangeException("startIndex", SR.ArgumentOutOfRange_Index);
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
if (count < 0 || startIndex > source.Length - count)
- throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_Count);
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count);
Contract.EndContractBlock();
if (options == CompareOptions.OrdinalIgnoreCase)
@@ -570,7 +692,7 @@ namespace System.Globalization
// Validate CompareOptions
// Ordinal can't be selected with other flags
if ((options & ValidIndexMaskOffFlags) != 0 && (options != CompareOptions.Ordinal))
- throw new ArgumentException(SR.Argument_InvalidFlag, "options");
+ throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
return IndexOfCore(source, new string(value, 1), startIndex, count, options);
}
@@ -580,13 +702,13 @@ namespace System.Globalization
{
// Validate inputs
if (source == null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
if (value == null)
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
if (startIndex > source.Length)
{
- throw new ArgumentOutOfRangeException("startIndex", SR.ArgumentOutOfRange_Index);
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
}
Contract.EndContractBlock();
@@ -603,11 +725,11 @@ namespace System.Globalization
if (startIndex < 0)
{
- throw new ArgumentOutOfRangeException("startIndex", SR.ArgumentOutOfRange_Index);
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
}
if (count < 0 || startIndex > source.Length - count)
- throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_Count);
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count);
if (options == CompareOptions.OrdinalIgnoreCase)
{
@@ -617,7 +739,7 @@ namespace System.Globalization
// Validate CompareOptions
// Ordinal can't be selected with other flags
if ((options & ValidIndexMaskOffFlags) != 0 && (options != CompareOptions.Ordinal))
- throw new ArgumentException(SR.Argument_InvalidFlag, "options");
+ throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
return IndexOfCore(source, value, startIndex, count, options);
}
@@ -639,7 +761,7 @@ namespace System.Globalization
public unsafe virtual int LastIndexOf(String source, char value)
{
if (source == null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
// Can't start at negative index, so make sure we check for the length == 0 case.
@@ -651,7 +773,7 @@ namespace System.Globalization
public virtual int LastIndexOf(String source, String value)
{
if (source == null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
// Can't start at negative index, so make sure we check for the length == 0 case.
@@ -663,7 +785,7 @@ namespace System.Globalization
public virtual int LastIndexOf(String source, char value, CompareOptions options)
{
if (source == null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
// Can't start at negative index, so make sure we check for the length == 0 case.
@@ -674,7 +796,7 @@ namespace System.Globalization
public unsafe virtual int LastIndexOf(String source, String value, CompareOptions options)
{
if (source == null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
// Can't start at negative index, so make sure we check for the length == 0 case.
@@ -682,6 +804,16 @@ namespace System.Globalization
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)
{
@@ -711,7 +843,7 @@ namespace System.Globalization
{
// Verify Arguments
if (source == null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
// Validate CompareOptions
@@ -719,7 +851,7 @@ namespace System.Globalization
if ((options & ValidIndexMaskOffFlags) != 0 &&
(options != CompareOptions.Ordinal) &&
(options != CompareOptions.OrdinalIgnoreCase))
- throw new ArgumentException(SR.Argument_InvalidFlag, "options");
+ throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
// Special case for 0 length input strings
if (source.Length == 0 && (startIndex == -1 || startIndex == 0))
@@ -727,7 +859,7 @@ namespace System.Globalization
// Make sure we're not out of range
if (startIndex < 0 || startIndex > source.Length)
- throw new ArgumentOutOfRangeException("startIndex", SR.ArgumentOutOfRange_Index);
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
// Make sure that we allow startIndex == source.Length
if (startIndex == source.Length)
@@ -739,7 +871,7 @@ 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("count", SR.ArgumentOutOfRange_Count);
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count);
if (options == CompareOptions.OrdinalIgnoreCase)
{
@@ -754,9 +886,9 @@ namespace System.Globalization
{
// Verify Arguments
if (source == null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
if (value == null)
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
Contract.EndContractBlock();
// Validate CompareOptions
@@ -764,7 +896,7 @@ namespace System.Globalization
if ((options & ValidIndexMaskOffFlags) != 0 &&
(options != CompareOptions.Ordinal) &&
(options != CompareOptions.OrdinalIgnoreCase))
- throw new ArgumentException(SR.Argument_InvalidFlag, "options");
+ throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
// Special case for 0 length input strings
if (source.Length == 0 && (startIndex == -1 || startIndex == 0))
@@ -772,7 +904,7 @@ namespace System.Globalization
// Make sure we're not out of range
if (startIndex < 0 || startIndex > source.Length)
- throw new ArgumentOutOfRangeException("startIndex", SR.ArgumentOutOfRange_Index);
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
// Make sure that we allow startIndex == source.Length
if (startIndex == source.Length)
@@ -788,7 +920,7 @@ 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("count", SR.ArgumentOutOfRange_Count);
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count);
if (options == CompareOptions.OrdinalIgnoreCase)
{
@@ -798,8 +930,24 @@ namespace System.Globalization
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
@@ -872,12 +1020,12 @@ namespace System.Globalization
//
if (null == source)
{
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
}
if ((options & ValidHashCodeOfStringMaskOffFlags) != 0)
{
- throw new ArgumentException(SR.Argument_InvalidFlag, "options");
+ throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
}
Contract.EndContractBlock();
@@ -888,7 +1036,7 @@ namespace System.Globalization
{
if (source == null)
{
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
}
if (options == CompareOptions.Ordinal)
@@ -921,5 +1069,26 @@ namespace System.Globalization
{
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
index 58aae2f40b..7f2f17d9f5 100644
--- a/src/mscorlib/corefx/System/Globalization/CultureData.Unix.cs
+++ b/src/mscorlib/corefx/System/Globalization/CultureData.Unix.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
using System.Security;
@@ -17,7 +18,8 @@ namespace System.Globalization
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.
@@ -25,8 +27,8 @@ namespace System.Globalization
[SecuritySafeCritical]
private unsafe bool InitCultureData()
{
- Contract.Assert(_sRealName != null);
-
+ Debug.Assert(_sRealName != null);
+
string alternateSortName = string.Empty;
string realNameBuffer = _sRealName;
@@ -66,23 +68,21 @@ namespace System.Globalization
_sName = _sWindowsName;
}
_sRealName = _sName;
- _sSpecificCulture = _sRealName; // we don't attempt to find a non-neutral locale if a neutral is passed in (unlike win32)
_iLanguage = this.ILANGUAGE;
if (_iLanguage == 0)
{
- _iLanguage = LOCALE_CUSTOM_UNSPECIFIED;
+ _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 (!_bNeutral)
+ if (index>0 && !_bNeutral && !IsCustomCultureId(_iLanguage))
{
- if (!IsCustomCultureId(_iLanguage))
- {
- _sName = _sWindowsName.Substring(0, index);
- }
+ _sName = _sWindowsName.Substring(0, index);
}
return true;
}
@@ -120,10 +120,10 @@ namespace System.Globalization
windowsName = StringBuilderCache.GetStringAndRelease(sb); // the name passed to subsequent ICU calls
return true;
}
-
+
private string GetLocaleInfo(LocaleStringData type)
{
- Contract.Assert(_sWindowsName != null, "[CultureData.GetLocaleInfo] Expected _sWindowsName to be populated already");
+ Debug.Assert(_sWindowsName != null, "[CultureData.GetLocaleInfo] Expected _sWindowsName to be populated already");
return GetLocaleInfo(_sWindowsName, type);
}
@@ -132,7 +132,7 @@ namespace System.Globalization
[SecuritySafeCritical]
private string GetLocaleInfo(string localeName, LocaleStringData type)
{
- Contract.Assert(localeName != null, "[CultureData.GetLocaleInfo] Expected localeName to be not be null");
+ Debug.Assert(localeName != null, "[CultureData.GetLocaleInfo] Expected localeName to be not be null");
switch (type)
{
@@ -149,7 +149,7 @@ namespace System.Globalization
{
// Failed, just use empty string
StringBuilderCache.Release(sb);
- Contract.Assert(false, "[CultureData.GetLocaleInfo(LocaleStringData)] Failed");
+ Debug.Assert(false, "[CultureData.GetLocaleInfo(LocaleStringData)] Failed");
return String.Empty;
}
return StringBuilderCache.GetStringAndRelease(sb);
@@ -158,7 +158,7 @@ namespace System.Globalization
[SecuritySafeCritical]
private int GetLocaleInfo(LocaleNumberData type)
{
- Contract.Assert(_sWindowsName != null, "[CultureData.GetLocaleInfo(LocaleNumberData)] Expected _sWindowsName to be populated already");
+ Debug.Assert(_sWindowsName != null, "[CultureData.GetLocaleInfo(LocaleNumberData)] Expected _sWindowsName to be populated already");
switch (type)
{
@@ -173,7 +173,7 @@ namespace System.Globalization
if (!result)
{
// Failed, just use 0
- Contract.Assert(false, "[CultureData.GetLocaleInfo(LocaleNumberData)] failed");
+ Debug.Assert(false, "[CultureData.GetLocaleInfo(LocaleNumberData)] failed");
}
return value;
@@ -182,14 +182,14 @@ namespace System.Globalization
[SecuritySafeCritical]
private int[] GetLocaleInfo(LocaleGroupingData type)
{
- Contract.Assert(_sWindowsName != null, "[CultureData.GetLocaleInfo(LocaleGroupingData)] Expected _sWindowsName to be populated already");
+ 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)
{
- Contract.Assert(false, "[CultureData.GetLocaleInfo(LocaleGroupingData type)] failed");
+ Debug.Assert(false, "[CultureData.GetLocaleInfo(LocaleGroupingData type)] failed");
}
if (secondaryGroupingSize == 0)
@@ -208,7 +208,7 @@ namespace System.Globalization
[SecuritySafeCritical]
private string GetTimeFormatString(bool shortFormat)
{
- Contract.Assert(_sWindowsName != null, "[CultureData.GetTimeFormatString(bool shortFormat)] Expected _sWindowsName to be populated already");
+ Debug.Assert(_sWindowsName != null, "[CultureData.GetTimeFormatString(bool shortFormat)] Expected _sWindowsName to be populated already");
StringBuilder sb = StringBuilderCache.Acquire(ICU_ULOC_KEYWORD_AND_VALUES_CAPACITY);
@@ -217,7 +217,7 @@ namespace System.Globalization
{
// Failed, just use empty string
StringBuilderCache.Release(sb);
- Contract.Assert(false, "[CultureData.GetTimeFormatString(bool shortFormat)] Failed");
+ Debug.Assert(false, "[CultureData.GetTimeFormatString(bool shortFormat)] Failed");
return String.Empty;
}
@@ -300,5 +300,127 @@ namespace System.Globalization
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
index 9969ecbd81..d1c99da607 100644
--- a/src/mscorlib/corefx/System/Globalization/CultureData.Windows.cs
+++ b/src/mscorlib/corefx/System/Globalization/CultureData.Windows.cs
@@ -3,10 +3,13 @@
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
-using System.Diagnostics.Contracts;
+using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
+
+#if ENABLE_WINRT
using Internal.Runtime.Augments;
+#endif
namespace System.Globalization
{
@@ -158,7 +161,7 @@ namespace System.Globalization
private string GetLocaleInfo(LocaleStringData type)
{
- Contract.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfo] Expected _sWindowsName to be populated by already");
+ Debug.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfo] Expected _sWindowsName to be populated by already");
return GetLocaleInfo(_sWindowsName, type);
}
@@ -183,7 +186,7 @@ namespace System.Globalization
// Ask OS for data, note that we presume it returns success, so we have to know that
// sWindowsName is valid before calling.
- Contract.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfoInt] Expected _sWindowsName to be populated by already");
+ Debug.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfoInt] Expected _sWindowsName to be populated by already");
int result = Interop.mincore.GetLocaleInfoExInt(_sWindowsName, lctype);
return result;
@@ -203,7 +206,7 @@ namespace System.Globalization
private int GetFirstDayOfWeek()
{
- Contract.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfoInt] Expected _sWindowsName to be populated by already");
+ Debug.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfoInt] Expected _sWindowsName to be populated by already");
const uint LOCALE_IFIRSTDAYOFWEEK = 0x0000100C;
@@ -216,7 +219,7 @@ namespace System.Globalization
private String[] GetTimeFormats()
{
// Note that this gets overrides for us all the time
- Contract.Assert(_sWindowsName != null, "[CultureData.DoEnumTimeFormats] Expected _sWindowsName to be populated by already");
+ Debug.Assert(_sWindowsName != null, "[CultureData.DoEnumTimeFormats] Expected _sWindowsName to be populated by already");
String[] result = ReescapeWin32Strings(nativeEnumTimeFormats(_sWindowsName, 0, UseUserOverride));
return result;
@@ -225,7 +228,7 @@ namespace System.Globalization
private String[] GetShortTimeFormats()
{
// Note that this gets overrides for us all the time
- Contract.Assert(_sWindowsName != null, "[CultureData.DoEnumShortTimeFormats] Expected _sWindowsName to be populated by already");
+ Debug.Assert(_sWindowsName != null, "[CultureData.DoEnumShortTimeFormats] Expected _sWindowsName to be populated by already");
String[] result = ReescapeWin32Strings(nativeEnumTimeFormats(_sWindowsName, TIME_NOSECONDS, UseUserOverride));
return result;
@@ -235,7 +238,7 @@ namespace System.Globalization
// region name match the requested region name
private static CultureData GetCultureDataFromRegionName(String regionName)
{
- Contract.Assert(regionName != null);
+ Debug.Assert(regionName != null);
const uint LOCALE_SUPPLEMENTAL = 0x00000002;
const uint LOCALE_SPECIFICDATA = 0x00000020;
@@ -264,26 +267,64 @@ namespace System.Globalization
return null;
}
- private static string GetLanguageDisplayName(string cultureName)
+ 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 static string GetRegionDisplayName(string isoCountryCode)
+ 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)
{
- Contract.Assert(localeName != null, "[CultureData.GetLocaleInfoFromLCType] Expected localeName to be not be null");
+ Debug.Assert(localeName != null, "[CultureData.GetLocaleInfoFromLCType] Expected localeName to be not be null");
// Fix lctype if we don't want overrides
if (!useUserOveride)
@@ -557,5 +598,76 @@ namespace System.Globalization
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
index eb71318fdb..c15a77cf45 100644
--- a/src/mscorlib/corefx/System/Globalization/CultureData.cs
+++ b/src/mscorlib/corefx/System/Globalization/CultureData.cs
@@ -2,25 +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;
-using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Text;
using System.Threading;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Diagnostics.Contracts;
namespace System.Globalization
{
#if INSIDE_CLR
using StringStringDictionary = Dictionary<string, string>;
- using StringCultureDataDictionary = Dictionary<String, CultureData>;
+ 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
//
@@ -57,8 +55,6 @@ namespace System.Globalization
internal partial class CultureData
{
private const int undef = -1;
- private const int LOCALE_CUSTOM_UNSPECIFIED = 0x1000;
- private const int LOCALE_CUSTOM_DEFAULT = 0x0c00;
// Override flag
private String _sRealName; // Name you passed in (ie: en-US, en, or de-DE_phoneb)
@@ -74,9 +70,13 @@ namespace System.Globalization
// 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)
@@ -84,11 +84,12 @@ namespace System.Globalization
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
// (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
@@ -108,6 +109,8 @@ namespace System.Globalization
// 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
@@ -145,6 +148,11 @@ namespace System.Globalization
// 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)
@@ -391,6 +399,42 @@ namespace System.Globalization
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
@@ -422,20 +466,25 @@ namespace System.Globalization
// 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._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._saNativeDigits = new String[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }; // native characters for digits 0-9
invariant._iDigits = 2; // number of fractional digits
invariant._iNegativeNumber = 1; // negative number format
invariant._waGrouping = new int[] { 3 }; // grouping of digits
@@ -454,6 +503,8 @@ namespace System.Globalization
// 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
@@ -487,7 +538,11 @@ namespace System.Globalization
// These are desktop only, not coreclr
- invariant._iLanguage = 0x007f; // locale ID (0409) - NO sort information
+ 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;
}
@@ -605,6 +660,33 @@ namespace System.Globalization
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
@@ -622,7 +704,7 @@ namespace System.Globalization
{
get
{
- Contract.Assert(_sRealName != null, "[CultureData.CultureName] Expected _sRealName to be populated by 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.
@@ -834,6 +916,17 @@ namespace System.Globalization
}
}
+ // 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 //
/////////////
@@ -845,12 +938,38 @@ namespace System.Globalization
{
if (_sISO639Language == null)
{
- _sISO639Language = GetLocaleInfo(LocaleStringData.Iso639LanguageName);
+ _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
@@ -922,6 +1041,17 @@ namespace System.Globalization
}
}
+ internal int IGEOID
+ {
+ get
+ {
+ if (_iGeoId == undef)
+ {
+ _iGeoId = GetGeoId(_sRealName);
+ }
+ return _iGeoId;
+ }
+ }
// localized name for the country
internal string SLOCALIZEDCOUNTRY
@@ -987,17 +1117,51 @@ namespace System.Globalization
}
}
- /////////////
- // Numbers //
- ////////////
-
- // internal String sPositiveSign ; // (user can override) positive sign
- // internal String sNegativeSign ; // (user can override) negative sign
- // internal String[] saNativeDigits ; // (user can override) native characters for digits 0-9
- // internal int iDigits ; // (user can override) number of fractional digits
- // internal int iNegativeNumber ; // (user can override) negative number format
+ // 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
@@ -1144,6 +1308,32 @@ namespace System.Globalization
}
}
+ // 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
@@ -1522,7 +1712,7 @@ namespace System.Globalization
// 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];
- Contract.Assert(_sWindowsName != null, "[CultureData.CalendarIds] Expected _sWindowsName to be populated by already");
+ 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.
@@ -1585,9 +1775,16 @@ namespace System.Globalization
}
}
+ // 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)
{
- Contract.Assert(calendarId > 0 && calendarId <= CalendarId.LAST_CALENDAR,
+ 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
@@ -1606,7 +1803,7 @@ namespace System.Globalization
// Make sure that calendar has data
if (calendarData == null)
{
- Contract.Assert(_sWindowsName != null, "[CultureData.GetCalendar] Expected _sWindowsName to be populated by already");
+ Debug.Assert(_sWindowsName != null, "[CultureData.GetCalendar] Expected _sWindowsName to be populated by already");
calendarData = new CalendarData(_sWindowsName, calendarId, this.UseUserOverride);
_calendars[calendarIndex] = calendarData;
}
@@ -1646,7 +1843,7 @@ namespace System.Globalization
{
if (_iReadingLayout == undef)
{
- Contract.Assert(_sRealName != null, "[CultureData.IsRightToLeft] Expected _sRealName to be populated by already");
+ Debug.Assert(_sRealName != null, "[CultureData.IsRightToLeft] Expected _sRealName to be populated by already");
_iReadingLayout = GetLocaleInfo(LocaleNumberData.ReadingLayout);
}
@@ -1667,8 +1864,8 @@ namespace System.Globalization
{
// 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.
- Contract.Assert(_sWindowsName != null, "[CultureData.STEXTINFO] Expected _sWindowsName to be populated by already");
- return (_sWindowsName);
+ Debug.Assert(_sRealName != null, "[CultureData.STEXTINFO] Expected _sRealName to be populated by already");
+ return (_sRealName);
}
}
@@ -1677,8 +1874,8 @@ namespace System.Globalization
{
get
{
- Contract.Assert(_sWindowsName != null, "[CultureData.SCOMPAREINFO] Expected _sWindowsName to be populated by already");
- return (_sWindowsName);
+ Debug.Assert(_sRealName != null, "[CultureData.SCOMPAREINFO] Expected _sRealName to be populated by already");
+ return (_sRealName);
}
}
@@ -1690,10 +1887,63 @@ namespace System.Globalization
}
}
+ 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;
}
}
@@ -1734,21 +1984,21 @@ namespace System.Globalization
// All of our era names
internal String[] EraNames(CalendarId calendarId)
{
- Contract.Assert(calendarId > 0, "[CultureData.saEraNames] Expected Calendar.ID > 0");
+ Debug.Assert(calendarId > 0, "[CultureData.saEraNames] Expected Calendar.ID > 0");
return this.GetCalendar(calendarId).saEraNames;
}
internal String[] AbbrevEraNames(CalendarId calendarId)
{
- Contract.Assert(calendarId > 0, "[CultureData.saAbbrevEraNames] Expected Calendar.ID > 0");
+ Debug.Assert(calendarId > 0, "[CultureData.saAbbrevEraNames] Expected Calendar.ID > 0");
return this.GetCalendar(calendarId).saAbbrevEraNames;
}
internal String[] AbbreviatedEnglishEraNames(CalendarId calendarId)
{
- Contract.Assert(calendarId > 0, "[CultureData.saAbbrevEraNames] Expected Calendar.ID > 0");
+ Debug.Assert(calendarId > 0, "[CultureData.saAbbrevEraNames] Expected Calendar.ID > 0");
return this.GetCalendar(calendarId).saAbbrevEnglishEraNames;
}
@@ -1808,9 +2058,9 @@ namespace System.Globalization
////////////////////////////////////////////////////////////////////////////
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++)
@@ -1908,8 +2158,8 @@ namespace System.Globalization
private static int IndexOfTimePart(string format, int startIndex, string timeParts)
{
- Contract.Assert(startIndex >= 0, "startIndex cannot be negative");
- Contract.Assert(timeParts.IndexOfAny(new char[] { '\'', '\\' }) == -1, "timeParts cannot include quote characters");
+ 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)
{
@@ -1944,9 +2194,9 @@ namespace System.Globalization
return -1;
}
- private static bool IsCustomCultureId(int cultureId)
+ internal static bool IsCustomCultureId(int cultureId)
{
- return (cultureId == LOCALE_CUSTOM_DEFAULT || cultureId == LOCALE_CUSTOM_UNSPECIFIED);
+ return (cultureId == CultureInfo.LOCALE_CUSTOM_DEFAULT || cultureId == CultureInfo.LOCALE_CUSTOM_UNSPECIFIED);
}
internal void GetNFIValues(NumberFormatInfo nfi)
@@ -1954,7 +2204,6 @@ namespace System.Globalization
if (this.IsInvariantCulture)
{
// FUTURE: NumberFormatInfo already has default values for many of these fields. Can we not do this?
- // if we do need to do this, then why don't we set nfi.nativeDigits in this case?
nfi.positiveSign = _sPositiveSign;
nfi.negativeSign = _sNegativeSign;
@@ -1972,7 +2221,7 @@ namespace System.Globalization
}
else
{
- Contract.Assert(_sWindowsName != null, "[CultureData.GetNFIValues] Expected _sWindowsName to be populated by already");
+ 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);
@@ -1997,6 +2246,8 @@ namespace System.Globalization
{
nfi.nativeDigits[i] = new string(digits[i], 1);
}
+
+ nfi.digitSubstitution = GetDigitSubstitution(_sRealName);
}
//
@@ -2043,9 +2294,26 @@ namespace System.Globalization
// 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]);
+ }
- for (int ich = 0; ich < testString.Length; ich++)
+ 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);
@@ -2072,10 +2340,14 @@ namespace System.Globalization
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>
@@ -2086,6 +2358,10 @@ namespace System.Globalization
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>
@@ -2101,9 +2377,15 @@ namespace System.Globalization
/// <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>
@@ -2112,6 +2394,8 @@ namespace System.Globalization
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>
@@ -2138,6 +2422,10 @@ namespace System.Globalization
{
/// <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>
@@ -2168,7 +2456,15 @@ namespace System.Globalization
/// <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
+ 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.Windows.cs b/src/mscorlib/corefx/System/Globalization/CultureInfo.Windows.cs
index 16c8a06e08..c019eb2ceb 100644
--- a/src/mscorlib/corefx/System/Globalization/CultureInfo.Windows.cs
+++ b/src/mscorlib/corefx/System/Globalization/CultureInfo.Windows.cs
@@ -2,7 +2,9 @@
// 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
{
@@ -16,16 +18,18 @@ namespace System.Globalization
/// </remarks>
private static CultureInfo GetUserDefaultCultureCacheOverride()
{
+#if ENABLE_WINRT
WinRTInteropCallbacks callbacks = WinRTInterop.UnsafeCallbacks;
if (callbacks != null && callbacks.IsAppxModel())
{
return (CultureInfo)callbacks.GetUserDefaultCulture();
}
+#endif
return null;
}
- private static CultureInfo GetUserDefaultCulture()
+ internal static CultureInfo GetUserDefaultCulture()
{
const uint LOCALE_SNAME = 0x0000005c;
const string LOCALE_NAME_USER_DEFAULT = null;
diff --git a/src/mscorlib/corefx/System/Globalization/CultureInfo.cs b/src/mscorlib/corefx/System/Globalization/CultureInfo.cs
index f2b3742ab4..da084d17f9 100644
--- a/src/mscorlib/corefx/System/Globalization/CultureInfo.cs
+++ b/src/mscorlib/corefx/System/Globalization/CultureInfo.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.
@@ -26,15 +26,10 @@
//
////////////////////////////////////////////////////////////////////////////
-using System;
-using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
-using System.Runtime;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
using System.Runtime.Serialization;
-using System.Security;
using System.Threading;
namespace System.Globalization
@@ -42,9 +37,12 @@ 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]
@@ -79,6 +77,9 @@ namespace System.Globalization
[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
@@ -106,7 +107,6 @@ namespace System.Globalization
[NonSerialized]
private string m_sortName;
-
//--------------------------------------------------------------------//
//
// Static data members
@@ -139,11 +139,21 @@ namespace System.Globalization
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;
@@ -189,17 +199,55 @@ namespace System.Globalization
}
- internal CultureInfo(String name, bool useUserOverride)
+ public CultureInfo(String name, bool useUserOverride)
{
if (name == null)
{
- throw new ArgumentNullException("name",
+ 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
@@ -207,13 +255,38 @@ namespace System.Globalization
if (this.m_cultureData == null)
{
- throw new CultureNotFoundException("name", name, SR.Argument_CultureNotSupported);
+ 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)
//
@@ -239,6 +312,66 @@ namespace System.Globalization
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.
@@ -296,7 +429,7 @@ namespace System.Globalization
[OnDeserialized]
private void OnDeserialized(StreamingContext ctx)
{
- Contract.Assert(m_name != null, "[CultureInfo.OnDeserialized] m_name != null");
+ Debug.Assert(m_name != null, "[CultureInfo.OnDeserialized] m_name != null");
InitializeFromName(m_name, m_useUserOverride);
}
@@ -348,7 +481,7 @@ namespace System.Globalization
Init();
}
- Contract.Assert(s_userDefaultCulture != null);
+ Debug.Assert(s_userDefaultCulture != null);
return s_userDefaultCulture;
}
@@ -356,7 +489,7 @@ namespace System.Globalization
{
if (value == null)
{
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
if (s_asyncLocalCurrentCulture == null)
@@ -396,7 +529,7 @@ namespace System.Globalization
Init();
}
- Contract.Assert(s_userDefaultCulture != null);
+ Debug.Assert(s_userDefaultCulture != null);
return s_userDefaultCulture;
}
@@ -404,7 +537,7 @@ namespace System.Globalization
{
if (value == null)
{
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
CultureInfo.VerifyCultureName(value, true);
@@ -419,6 +552,20 @@ namespace System.Globalization
}
}
+ 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; }
@@ -513,6 +660,34 @@ namespace System.Globalization
}
}
+ 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
@@ -552,6 +727,24 @@ namespace System.Globalization
}
}
+ 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;
+ }
+ }
+ }
////////////////////////////////////////////////////////////////////////
//
@@ -567,7 +760,7 @@ namespace System.Globalization
get
{
Contract.Ensures(Contract.Result<String>() != null);
- Contract.Assert(m_name != null, "[CultureInfo.DisplayName] Always expect m_name to be set");
+ Debug.Assert(m_name != null, "[CultureInfo.DisplayName] Always expect m_name to be set");
return m_cultureData.SLOCALIZEDDISPLAYNAME;
}
@@ -619,6 +812,32 @@ namespace System.Globalization
}
}
+ // 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;
+ }
+ }
////////////////////////////////////////////////////////////////////////
//
@@ -767,6 +986,31 @@ namespace System.Globalization
}
}
+ 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
@@ -775,7 +1019,7 @@ namespace System.Globalization
{
NumberFormatInfo temp = new NumberFormatInfo(this.m_cultureData);
temp.isReadOnly = m_isReadOnly;
- numInfo = temp;
+ Interlocked.CompareExchange(ref numInfo, temp, null);
}
return (numInfo);
}
@@ -783,7 +1027,7 @@ namespace System.Globalization
{
if (value == null)
{
- throw new ArgumentNullException("value", SR.ArgumentNull_Obj);
+ throw new ArgumentNullException(nameof(value), SR.ArgumentNull_Obj);
}
VerifyWritable();
numInfo = value;
@@ -807,8 +1051,7 @@ namespace System.Globalization
// 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;
- System.Threading.Interlocked.MemoryBarrier();
- dateTimeInfo = temp;
+ Interlocked.CompareExchange(ref dateTimeInfo, temp, null);
}
return (dateTimeInfo);
}
@@ -817,13 +1060,28 @@ namespace System.Globalization
{
if (value == null)
{
- throw new ArgumentNullException("value", SR.ArgumentNull_Obj);
+ 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.
@@ -845,7 +1103,7 @@ namespace System.Globalization
//calendars unless they're required.
internal static Calendar GetCalendarInstanceRare(CalendarId calType)
{
- Contract.Assert(calType != CalendarId.GREGORIAN, "calType!=CalendarId.GREGORIAN");
+ Debug.Assert(calType != CalendarId.GREGORIAN, "calType!=CalendarId.GREGORIAN");
switch (calType)
{
@@ -889,7 +1147,7 @@ namespace System.Globalization
{
if (calendar == null)
{
- Contract.Assert(this.m_cultureData.CalendarIds.Length > 0, "this.m_cultureData.CalendarIds.Length > 0");
+ 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;
@@ -929,13 +1187,26 @@ namespace System.Globalization
}
}
-
- private bool UseUserOverride
+ public bool UseUserOverride
{
get
{
- return (this.m_cultureData.UseUserOverride);
+ 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()
@@ -979,7 +1250,7 @@ namespace System.Globalization
{
if (ci == null)
{
- throw new ArgumentNullException("ci");
+ throw new ArgumentNullException(nameof(ci));
}
Contract.Ensures(Contract.Result<CultureInfo>() != null);
Contract.EndContractBlock();
@@ -1054,26 +1325,25 @@ namespace System.Globalization
get { return Name == CultureInfo.InvariantCulture.Name; }
}
- // Helper function both both overloads of GetCachedReadOnlyCulture.
- internal static CultureInfo GetCultureInfoHelper(string 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)
{
- // 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 since the CultureInfo objects
- // are content equal (but not reference equal). Since we make no guarantees there, this race is
- // acceptable.
-
// retval is our return value.
CultureInfo retval;
- if (name == null)
- {
- return null;
- }
-
// Temporary hashtable for the names.
StringCultureInfoDictionary tempNameHT = s_NameCachedCultures;
- name = CultureData.AnsiToLower(name);
+ 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)
@@ -1082,20 +1352,66 @@ namespace System.Globalization
}
else
{
- bool ret;
- lock (m_lock)
+ // If we are called by name, check if the object exists in the hashtable. If so, return it.
+ if (lcid == -1 || lcid == 0)
{
- ret = tempNameHT.TryGetValue(name, out retval);
+ bool ret;
+ lock (m_lock)
+ {
+ ret = tempNameHT.TryGetValue(lcid == 0 ? name : name + '\xfffd' + altName, out retval);
+ }
+
+ if (ret && retval != null)
+ {
+ return retval;
+ }
}
+ }
- if (ret && retval != null)
+ // 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)
{
- return retval;
+ 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
{
- retval = new CultureInfo(name, false);
+ 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)
{
@@ -1105,14 +1421,42 @@ namespace System.Globalization
// Set it to read-only
retval.m_isReadOnly = true;
- // 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);
+ 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;
+ }
+ }
- // We add this new culture info object to both tables.
- lock (m_lock)
+ // 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)
{
- tempNameHT[newName] = retval;
+ // Only when we modify the lcid hash table, is there a need to overwrite.
+ s_LcidCachedCultures = tempLcidHT;
}
s_NameCachedCultures = tempNameHT;
@@ -1122,23 +1466,93 @@ namespace System.Globalization
}
// 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)
- internal static CultureInfo GetCultureInfo(string name)
+ public static CultureInfo GetCultureInfo(string name)
{
// Make sure we have a valid, non-zero length string as name
if (name == null)
{
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
}
- CultureInfo retval = GetCultureInfoHelper(name);
+ CultureInfo retval = GetCultureInfoHelper(0, name, null);
if (retval == null)
{
throw new CultureNotFoundException(
- "name", name, SR.Argument_CultureNotSupported);
+ 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
index 740063e4d3..64782d28c0 100644
--- a/src/mscorlib/corefx/System/Globalization/CultureNotFoundException.cs
+++ b/src/mscorlib/corefx/System/Globalization/CultureNotFoundException.cs
@@ -13,6 +13,7 @@ namespace System.Globalization
public partial class CultureNotFoundException : ArgumentException, ISerializable
{
private string _invalidCultureName; // unrecognized culture name
+ private int? _invalidCultureId; // unrecognized culture Lcid
public CultureNotFoundException()
: base(DefaultMessage)
@@ -46,8 +47,22 @@ namespace System.Globalization
_invalidCultureName = invalidCultureName;
}
- protected CultureNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context)
+ 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));
}
@@ -56,13 +71,19 @@ namespace System.Globalization
{
if (info == null)
{
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
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; }
@@ -80,7 +101,9 @@ namespace System.Globalization
{
get
{
- return InvalidCultureName;
+ return InvalidCultureId != null ?
+ String.Format(CultureInfo.InvariantCulture, "{0} (0x{0:x4})", (int)InvalidCultureId) :
+ InvalidCultureName;
}
}
@@ -89,12 +112,14 @@ namespace System.Globalization
get
{
String s = base.Message;
- if (
- _invalidCultureName != null)
+ 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
new file mode 100644
index 0000000000..80b588aabb
--- /dev/null
+++ b/src/mscorlib/corefx/System/Globalization/CultureTypes.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.
+
+// 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
index da746ada88..216fc603d0 100644
--- a/src/mscorlib/corefx/System/Globalization/DateTimeFormatInfo.cs
+++ b/src/mscorlib/corefx/System/Globalization/DateTimeFormatInfo.cs
@@ -2,15 +2,10 @@
// The .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;
using System.Diagnostics.Contracts;
-using System.Runtime.InteropServices;
using System.Runtime.Serialization;
-using System.Security;
-using System.Text;
-using System.Threading;
namespace System.Globalization
{
@@ -55,8 +50,7 @@ namespace System.Globalization
[Serializable]
- [System.Runtime.InteropServices.ComVisible(true)]
- public sealed partial class DateTimeFormatInfo : IFormatProvider, ICloneable
+ public sealed class DateTimeFormatInfo : IFormatProvider, ICloneable
{
// cache for the invariant culture.
// invariantInfo is constant irrespective of your current culture.
@@ -228,7 +222,7 @@ namespace System.Globalization
{
// Get the abbreviated day names for our current calendar
this.abbreviatedDayNames = _cultureData.AbbreviatedDayNames(Calendar.ID);
- Contract.Assert(this.abbreviatedDayNames.Length == 7, "[DateTimeFormatInfo.GetAbbreviatedDayOfWeekNames] Expected 7 day names in a week");
+ Debug.Assert(this.abbreviatedDayNames.Length == 7, "[DateTimeFormatInfo.GetAbbreviatedDayOfWeekNames] Expected 7 day names in a week");
}
return (this.abbreviatedDayNames);
}
@@ -252,7 +246,7 @@ namespace System.Globalization
{
// Get the super short day names for our current calendar
this.m_superShortDayNames = _cultureData.SuperShortDayNames(Calendar.ID);
- Contract.Assert(this.m_superShortDayNames.Length == 7, "[DateTimeFormatInfo.internalGetSuperShortDayNames] Expected 7 day names in a week");
+ Debug.Assert(this.m_superShortDayNames.Length == 7, "[DateTimeFormatInfo.internalGetSuperShortDayNames] Expected 7 day names in a week");
}
return (this.m_superShortDayNames);
}
@@ -269,7 +263,7 @@ namespace System.Globalization
{
// Get the day names for our current calendar
this.dayNames = _cultureData.DayNames(Calendar.ID);
- Contract.Assert(this.dayNames.Length == 7, "[DateTimeFormatInfo.GetDayOfWeekNames] Expected 7 day names in a week");
+ Debug.Assert(this.dayNames.Length == 7, "[DateTimeFormatInfo.GetDayOfWeekNames] Expected 7 day names in a week");
}
return (this.dayNames);
}
@@ -286,7 +280,7 @@ namespace System.Globalization
{
// Get the month names for our current calendar
this.abbreviatedMonthNames = _cultureData.AbbreviatedMonthNames(Calendar.ID);
- Contract.Assert(this.abbreviatedMonthNames.Length == 12 || this.abbreviatedMonthNames.Length == 13,
+ Debug.Assert(this.abbreviatedMonthNames.Length == 12 || this.abbreviatedMonthNames.Length == 13,
"[DateTimeFormatInfo.GetAbbreviatedMonthNames] Expected 12 or 13 month names in a year");
}
return (this.abbreviatedMonthNames);
@@ -305,7 +299,7 @@ namespace System.Globalization
{
// Get the month names for our current calendar
this.monthNames = _cultureData.MonthNames(Calendar.ID);
- Contract.Assert(this.monthNames.Length == 12 || this.monthNames.Length == 13,
+ Debug.Assert(this.monthNames.Length == 12 || this.monthNames.Length == 13,
"[DateTimeFormatInfo.GetMonthNames] Expected 12 or 13 month names in a year");
}
@@ -324,8 +318,8 @@ namespace System.Globalization
internal DateTimeFormatInfo(CultureData cultureData, Calendar cal)
{
- Contract.Requires(cultureData != null);
- Contract.Requires(cal != null);
+ Debug.Assert(cultureData != null);
+ Debug.Assert(cal != null);
// Remember our culture
_cultureData = cultureData;
@@ -335,8 +329,8 @@ namespace System.Globalization
private void InitializeOverridableProperties(CultureData cultureData, CalendarId calendarId)
{
- Contract.Requires(cultureData != null);
- Contract.Assert(calendarId != CalendarId.UNINITIALIZED_VALUE, "[DateTimeFormatInfo.Populate] Expected initalized 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; }
@@ -347,19 +341,19 @@ namespace System.Globalization
if (this.dateSeparator == null) { this.dateSeparator = cultureData.DateSeparator(calendarId); }
this.allLongTimePatterns = _cultureData.LongTimes;
- Contract.Assert(this.allLongTimePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some long time patterns");
+ Debug.Assert(this.allLongTimePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some long time patterns");
this.allShortTimePatterns = _cultureData.ShortTimes;
- Contract.Assert(this.allShortTimePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some short time patterns");
+ Debug.Assert(this.allShortTimePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some short time patterns");
this.allLongDatePatterns = cultureData.LongDates(calendarId);
- Contract.Assert(this.allLongDatePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some long date patterns");
+ Debug.Assert(this.allLongDatePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some long date patterns");
this.allShortDatePatterns = cultureData.ShortDates(calendarId);
- Contract.Assert(this.allShortDatePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some short date patterns");
+ Debug.Assert(this.allShortDatePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some short date patterns");
this.allYearMonthPatterns = cultureData.YearMonths(calendarId);
- Contract.Assert(this.allYearMonthPatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some year month patterns");
+ Debug.Assert(this.allYearMonthPatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some year month patterns");
}
[OptionalField(VersionAdded = 1)]
@@ -527,7 +521,7 @@ namespace System.Globalization
{
this.amDesignator = _cultureData.SAM1159;
}
- Contract.Assert(this.amDesignator != null, "DateTimeFormatInfo.AMDesignator, amDesignator != null");
+ Debug.Assert(this.amDesignator != null, "DateTimeFormatInfo.AMDesignator, amDesignator != null");
return (this.amDesignator);
}
@@ -537,7 +531,7 @@ namespace System.Globalization
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
if (value == null)
{
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
SR.ArgumentNull_String);
}
Contract.EndContractBlock();
@@ -553,7 +547,7 @@ namespace System.Globalization
{
Contract.Ensures(Contract.Result<Calendar>() != null);
- Contract.Assert(this.calendar != null, "DateTimeFormatInfo.Calendar: calendar != null");
+ Debug.Assert(this.calendar != null, "DateTimeFormatInfo.Calendar: calendar != null");
return (this.calendar);
}
@@ -563,7 +557,7 @@ namespace System.Globalization
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
if (value == null)
{
- throw new ArgumentNullException("value", SR.ArgumentNull_Obj);
+ throw new ArgumentNullException(nameof(value), SR.ArgumentNull_Obj);
}
Contract.EndContractBlock();
if (value == calendar)
@@ -641,7 +635,7 @@ namespace System.Globalization
}
// The assigned calendar is not a valid calendar for this culture, throw
- throw new ArgumentOutOfRangeException("value", SR.Argument_InvalidCalendar);
+ throw new ArgumentOutOfRangeException(nameof(value), SR.Argument_InvalidCalendar);
}
}
@@ -670,7 +664,7 @@ namespace System.Globalization
{
if (eraName == null)
{
- throw new ArgumentNullException("eraName",
+ throw new ArgumentNullException(nameof(eraName),
SR.ArgumentNull_String);
}
Contract.EndContractBlock();
@@ -759,7 +753,7 @@ namespace System.Globalization
{
return (m_eraNames[era]);
}
- throw new ArgumentOutOfRangeException("era", SR.ArgumentOutOfRange_InvalidEraValue);
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
internal String[] AbbreviatedEraNames
@@ -791,7 +785,7 @@ namespace System.Globalization
{
return (m_abbrevEraNames[era]);
}
- throw new ArgumentOutOfRangeException("era", SR.ArgumentOutOfRange_InvalidEraValue);
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
internal String[] AbbreviatedEnglishEraNames
@@ -800,34 +794,41 @@ namespace System.Globalization
{
if (this.m_abbrevEnglishEraNames == null)
{
- Contract.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.AbbreviatedEnglishEraNames] Expected Calendar.ID > 0");
+ 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.
- internal String DateSeparator
+ public string DateSeparator
{
get
{
- if (this.dateSeparator == null)
+ if (dateSeparator == null)
{
- this.dateSeparator = _cultureData.DateSeparator(Calendar.ID);
+ dateSeparator = _cultureData.DateSeparator(Calendar.ID);
}
- Contract.Assert(this.dateSeparator != null, "DateTimeFormatInfo.DateSeparator, dateSeparator != null");
- return (this.dateSeparator);
+ Debug.Assert(this.dateSeparator != null, "DateTimeFormatInfo.DateSeparator, dateSeparator != null");
+ return dateSeparator;
}
set
{
- throw null;
+ 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
@@ -836,7 +837,7 @@ namespace System.Globalization
{
this.firstDayOfWeek = _cultureData.IFIRSTDAYOFWEEK;
}
- Contract.Assert(this.firstDayOfWeek != -1, "DateTimeFormatInfo.FirstDayOfWeek, firstDayOfWeek != -1");
+ Debug.Assert(this.firstDayOfWeek != -1, "DateTimeFormatInfo.FirstDayOfWeek, firstDayOfWeek != -1");
return ((DayOfWeek)this.firstDayOfWeek);
}
@@ -852,7 +853,7 @@ namespace System.Globalization
else
{
throw new ArgumentOutOfRangeException(
- "value", SR.Format(SR.ArgumentOutOfRange_Range,
+ nameof(value), SR.Format(SR.ArgumentOutOfRange_Range,
DayOfWeek.Sunday, DayOfWeek.Saturday));
}
}
@@ -866,7 +867,7 @@ namespace System.Globalization
{
this.calendarWeekRule = _cultureData.IFIRSTWEEKOFYEAR;
}
- Contract.Assert(this.calendarWeekRule != -1, "DateTimeFormatInfo.CalendarWeekRule, calendarWeekRule != -1");
+ Debug.Assert(this.calendarWeekRule != -1, "DateTimeFormatInfo.CalendarWeekRule, calendarWeekRule != -1");
return ((CalendarWeekRule)this.calendarWeekRule);
}
@@ -881,7 +882,7 @@ namespace System.Globalization
else
{
throw new ArgumentOutOfRangeException(
- "value", SR.Format(SR.ArgumentOutOfRange_Range,
+ nameof(value), SR.Format(SR.ArgumentOutOfRange_Range,
CalendarWeekRule.FirstDay, CalendarWeekRule.FirstFourDayWeek));
}
}
@@ -904,7 +905,7 @@ namespace System.Globalization
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
if (value == null)
{
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
SR.ArgumentNull_String);
}
Contract.EndContractBlock();
@@ -938,7 +939,7 @@ namespace System.Globalization
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
if (value == null)
{
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
SR.ArgumentNull_String);
}
Contract.EndContractBlock();
@@ -979,7 +980,7 @@ namespace System.Globalization
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
if (value == null)
{
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
SR.ArgumentNull_String);
}
Contract.EndContractBlock();
@@ -1005,10 +1006,10 @@ namespace System.Globalization
{
if (this.monthDayPattern == null)
{
- Contract.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.MonthDayPattern] Expected calID > 0");
+ Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.MonthDayPattern] Expected calID > 0");
this.monthDayPattern = _cultureData.MonthDay(Calendar.ID);
}
- Contract.Assert(this.monthDayPattern != null, "DateTimeFormatInfo.MonthDayPattern, monthDayPattern != null");
+ Debug.Assert(this.monthDayPattern != null, "DateTimeFormatInfo.MonthDayPattern, monthDayPattern != null");
return (this.monthDayPattern);
}
@@ -1018,7 +1019,7 @@ namespace System.Globalization
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
if (value == null)
{
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
SR.ArgumentNull_String);
}
Contract.EndContractBlock();
@@ -1037,7 +1038,7 @@ namespace System.Globalization
{
this.pmDesignator = _cultureData.SPM2359;
}
- Contract.Assert(this.pmDesignator != null, "DateTimeFormatInfo.PMDesignator, pmDesignator != null");
+ Debug.Assert(this.pmDesignator != null, "DateTimeFormatInfo.PMDesignator, pmDesignator != null");
return (this.pmDesignator);
}
@@ -1047,7 +1048,7 @@ namespace System.Globalization
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
if (value == null)
{
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
SR.ArgumentNull_String);
}
Contract.EndContractBlock();
@@ -1090,7 +1091,7 @@ namespace System.Globalization
if (IsReadOnly)
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
if (value == null)
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
SR.ArgumentNull_String);
Contract.EndContractBlock();
@@ -1132,7 +1133,7 @@ namespace System.Globalization
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
if (value == null)
{
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
SR.ArgumentNull_String);
}
Contract.EndContractBlock();
@@ -1270,7 +1271,7 @@ namespace System.Globalization
// Note that cultureData derives this from the long time format (unless someone's set this previously)
// Note that this property is quite undesirable.
- internal String TimeSeparator
+ public string TimeSeparator
{
get
{
@@ -1278,17 +1279,27 @@ namespace System.Globalization
{
timeSeparator = _cultureData.TimeSeparator;
}
- Contract.Assert(this.timeSeparator != null, "DateTimeFormatInfo.TimeSeparator, timeSeparator != null");
+ Debug.Assert(this.timeSeparator != null, "DateTimeFormatInfo.TimeSeparator, timeSeparator != null");
return (timeSeparator);
}
set
{
- throw null;
+ 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
@@ -1321,7 +1332,7 @@ namespace System.Globalization
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
if (value == null)
{
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
SR.ArgumentNull_String);
}
Contract.EndContractBlock();
@@ -1339,8 +1350,8 @@ namespace System.Globalization
//
private static void CheckNullValue(String[] values, int length)
{
- Contract.Requires(values != null, "value != null");
- Contract.Requires(values.Length >= length);
+ Debug.Assert(values != null, "value != null");
+ Debug.Assert(values.Length >= length);
for (int i = 0; i < length; i++)
{
if (values[i] == null)
@@ -1365,12 +1376,12 @@ namespace System.Globalization
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
if (value == null)
{
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
SR.ArgumentNull_Array);
}
if (value.Length != 7)
{
- throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 7), "value");
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 7), nameof(value));
}
Contract.EndContractBlock();
CheckNullValue(value, value.Length);
@@ -1381,7 +1392,6 @@ namespace System.Globalization
}
// Returns the string array of the one-letter day of week names.
- [System.Runtime.InteropServices.ComVisible(false)]
public String[] ShortestDayNames
{
get
@@ -1395,12 +1405,12 @@ namespace System.Globalization
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
if (value == null)
{
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
SR.ArgumentNull_Array);
}
if (value.Length != 7)
{
- throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 7), "value");
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 7), nameof(value));
}
Contract.EndContractBlock();
CheckNullValue(value, value.Length);
@@ -1422,12 +1432,12 @@ namespace System.Globalization
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
if (value == null)
{
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
SR.ArgumentNull_Array);
}
if (value.Length != 7)
{
- throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 7), "value");
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 7), nameof(value));
}
Contract.EndContractBlock();
CheckNullValue(value, value.Length);
@@ -1451,12 +1461,12 @@ namespace System.Globalization
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
if (value == null)
{
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
SR.ArgumentNull_Array);
}
if (value.Length != 13)
{
- throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 13), "value");
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 13), nameof(value));
}
Contract.EndContractBlock();
CheckNullValue(value, value.Length - 1);
@@ -1479,12 +1489,12 @@ namespace System.Globalization
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
if (value == null)
{
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
SR.ArgumentNull_Array);
}
if (value.Length != 13)
{
- throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 13), "value");
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 13), nameof(value));
}
Contract.EndContractBlock();
CheckNullValue(value, value.Length - 1);
@@ -1550,7 +1560,7 @@ namespace System.Globalization
if ((month < 1) || (month > monthNamesArray.Length))
{
throw new ArgumentOutOfRangeException(
- "month", SR.Format(SR.ArgumentOutOfRange_Range,
+ nameof(month), SR.Format(SR.ArgumentOutOfRange_Range,
1, monthNamesArray.Length));
}
return (monthNamesArray[month - 1]);
@@ -1571,7 +1581,7 @@ namespace System.Globalization
if (this.m_genitiveAbbreviatedMonthNames == null)
{
this.m_genitiveAbbreviatedMonthNames = _cultureData.AbbreviatedGenitiveMonthNames(this.Calendar.ID);
- Contract.Assert(this.m_genitiveAbbreviatedMonthNames.Length == 13,
+ Debug.Assert(this.m_genitiveAbbreviatedMonthNames.Length == 13,
"[DateTimeFormatInfo.GetGenitiveMonthNames] Expected 13 abbreviated genitive month names in a year");
}
return (this.m_genitiveAbbreviatedMonthNames);
@@ -1580,7 +1590,7 @@ namespace System.Globalization
if (this.genitiveMonthNames == null)
{
this.genitiveMonthNames = _cultureData.GenitiveMonthNames(this.Calendar.ID);
- Contract.Assert(this.genitiveMonthNames.Length == 13,
+ Debug.Assert(this.genitiveMonthNames.Length == 13,
"[DateTimeFormatInfo.GetGenitiveMonthNames] Expected 13 genitive month names in a year");
}
return (this.genitiveMonthNames);
@@ -1597,9 +1607,9 @@ namespace System.Globalization
{
if (this.leapYearMonthNames == null)
{
- Contract.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.internalGetLeapYearMonthNames] Expected Calendar.ID > 0");
+ Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.internalGetLeapYearMonthNames] Expected Calendar.ID > 0");
this.leapYearMonthNames = _cultureData.LeapYearMonthNames(Calendar.ID);
- Contract.Assert(this.leapYearMonthNames.Length == 13,
+ Debug.Assert(this.leapYearMonthNames.Length == 13,
"[DateTimeFormatInfo.internalGetLeapYearMonthNames] Expepcted 13 leap year month names");
}
return (leapYearMonthNames);
@@ -1611,7 +1621,7 @@ namespace System.Globalization
if ((int)dayofweek < 0 || (int)dayofweek > 6)
{
throw new ArgumentOutOfRangeException(
- "dayofweek", SR.Format(SR.ArgumentOutOfRange_Range,
+ nameof(dayofweek), SR.Format(SR.ArgumentOutOfRange_Range,
DayOfWeek.Sunday, DayOfWeek.Saturday));
}
Contract.EndContractBlock();
@@ -1622,11 +1632,28 @@ namespace System.Globalization
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)
{
- Contract.Requires(patterns1 != null);
- Contract.Requires(patterns2 != null);
+ Debug.Assert(patterns1 != null);
+ Debug.Assert(patterns2 != null);
// Get array size
String[] result = new String[patterns1.Length * patterns2.Length];
@@ -1646,9 +1673,22 @@ namespace System.Globalization
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();
+ }
- // auto-generated
- internal String[] GetAllDateTimePatterns(char format)
+ public string[] GetAllDateTimePatterns(char format)
{
Contract.Ensures(Contract.Result<String[]>() != null);
String[] result = null;
@@ -1703,7 +1743,7 @@ namespace System.Globalization
result = this.AllYearMonthPatterns;
break;
default:
- throw new ArgumentException(SR.Format_BadFormatSpecifier, "format");
+ throw new ArgumentException(SR.Format_BadFormatSpecifier, nameof(format));
}
return (result);
}
@@ -1714,7 +1754,7 @@ namespace System.Globalization
if ((int)dayofweek < 0 || (int)dayofweek > 6)
{
throw new ArgumentOutOfRangeException(
- "dayofweek", SR.Format(SR.ArgumentOutOfRange_Range,
+ nameof(dayofweek), SR.Format(SR.ArgumentOutOfRange_Range,
DayOfWeek.Sunday, DayOfWeek.Saturday));
}
Contract.EndContractBlock();
@@ -1730,7 +1770,7 @@ namespace System.Globalization
if (month < 1 || month > 13)
{
throw new ArgumentOutOfRangeException(
- "month", SR.Format(SR.ArgumentOutOfRange_Range,
+ nameof(month), SR.Format(SR.ArgumentOutOfRange_Range,
1, 13));
}
Contract.EndContractBlock();
@@ -1744,7 +1784,7 @@ namespace System.Globalization
if (month < 1 || month > 13)
{
throw new ArgumentOutOfRangeException(
- "month", SR.Format(SR.ArgumentOutOfRange_Range,
+ nameof(month), SR.Format(SR.ArgumentOutOfRange_Range,
1, 13));
}
Contract.EndContractBlock();
@@ -1761,9 +1801,9 @@ namespace System.Globalization
// The resulting [] can get returned to the calling app, so clone it.
private static string[] GetMergedPatterns(string[] patterns, string defaultPattern)
{
- Contract.Assert(patterns != null && patterns.Length > 0,
+ Debug.Assert(patterns != null && patterns.Length > 0,
"[DateTimeFormatInfo.GetMergedPatterns]Expected array of at least one pattern");
- Contract.Assert(defaultPattern != null,
+ 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
@@ -1864,9 +1904,9 @@ namespace System.Globalization
{
if (this.allYearMonthPatterns == null)
{
- Contract.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.UnclonedYearMonthPatterns] Expected Calendar.ID > 0");
+ Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.UnclonedYearMonthPatterns] Expected Calendar.ID > 0");
this.allYearMonthPatterns = _cultureData.YearMonths(this.Calendar.ID);
- Contract.Assert(this.allYearMonthPatterns.Length > 0,
+ Debug.Assert(this.allYearMonthPatterns.Length > 0,
"[DateTimeFormatInfo.UnclonedYearMonthPatterns] Expected some year month patterns");
}
@@ -1883,9 +1923,9 @@ namespace System.Globalization
{
if (allShortDatePatterns == null)
{
- Contract.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.UnclonedShortDatePatterns] Expected Calendar.ID > 0");
+ Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.UnclonedShortDatePatterns] Expected Calendar.ID > 0");
this.allShortDatePatterns = _cultureData.ShortDates(this.Calendar.ID);
- Contract.Assert(this.allShortDatePatterns.Length > 0,
+ Debug.Assert(this.allShortDatePatterns.Length > 0,
"[DateTimeFormatInfo.UnclonedShortDatePatterns] Expected some short date patterns");
}
@@ -1901,9 +1941,9 @@ namespace System.Globalization
{
if (allLongDatePatterns == null)
{
- Contract.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.UnclonedLongDatePatterns] Expected Calendar.ID > 0");
+ Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.UnclonedLongDatePatterns] Expected Calendar.ID > 0");
this.allLongDatePatterns = _cultureData.LongDates(this.Calendar.ID);
- Contract.Assert(this.allLongDatePatterns.Length > 0,
+ Debug.Assert(this.allLongDatePatterns.Length > 0,
"[DateTimeFormatInfo.UnclonedLongDatePatterns] Expected some long date patterns");
}
@@ -1920,7 +1960,7 @@ namespace System.Globalization
if (this.allShortTimePatterns == null)
{
this.allShortTimePatterns = _cultureData.ShortTimes;
- Contract.Assert(this.allShortTimePatterns.Length > 0,
+ Debug.Assert(this.allShortTimePatterns.Length > 0,
"[DateTimeFormatInfo.UnclonedShortTimePatterns] Expected some short time patterns");
}
@@ -1937,7 +1977,7 @@ namespace System.Globalization
if (this.allLongTimePatterns == null)
{
this.allLongTimePatterns = _cultureData.LongTimes;
- Contract.Assert(this.allLongTimePatterns.Length > 0,
+ Debug.Assert(this.allLongTimePatterns.Length > 0,
"[DateTimeFormatInfo.UnclonedLongTimePatterns] Expected some long time patterns");
}
@@ -1949,7 +1989,7 @@ namespace System.Globalization
{
if (dtfi == null)
{
- throw new ArgumentNullException("dtfi",
+ throw new ArgumentNullException(nameof(dtfi),
SR.ArgumentNull_Obj);
}
Contract.EndContractBlock();
@@ -1973,7 +2013,99 @@ namespace System.Globalization
}
}
- [System.Runtime.InteropServices.ComVisible(false)]
+ // 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
@@ -1987,12 +2119,12 @@ namespace System.Globalization
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
if (value == null)
{
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
SR.ArgumentNull_Array);
}
if (value.Length != 13)
{
- throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 13), "value");
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 13), nameof(value));
}
Contract.EndContractBlock();
CheckNullValue(value, value.Length - 1);
@@ -2001,7 +2133,6 @@ namespace System.Globalization
}
}
- [System.Runtime.InteropServices.ComVisible(false)]
public String[] MonthGenitiveNames
{
get
@@ -2015,12 +2146,12 @@ namespace System.Globalization
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
if (value == null)
{
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
SR.ArgumentNull_Array);
}
if (value.Length != 13)
{
- throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 13), "value");
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 13), nameof(value));
}
Contract.EndContractBlock();
CheckNullValue(value, value.Length - 1);
@@ -2630,7 +2761,7 @@ namespace System.Globalization
} 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.
- Contract.Assert(state == HebrewNumberParsingState.ContinueParsing || state == HebrewNumberParsingState.FoundEndOfHebrewNumber,
+ Debug.Assert(state == HebrewNumberParsingState.ContinueParsing || state == HebrewNumberParsingState.FoundEndOfHebrewNumber,
"Invalid returned state from HebrewNumber.ParseByChar()");
if (state != HebrewNumberParsingState.FoundEndOfHebrewNumber)
@@ -2665,7 +2796,7 @@ namespace System.Globalization
tokenValue = 0;
TokenHashValue value;
- Contract.Assert(str.Index < str.Value.Length, "DateTimeFormatInfo.Tokenize(): start < value.Length");
+ Debug.Assert(str.Index < str.Value.Length, "DateTimeFormatInfo.Tokenize(): start < value.Length");
char ch = str.m_current;
bool isLetter = Char.IsLetter(ch);
@@ -2788,7 +2919,7 @@ namespace System.Globalization
}
previousNode = temp;
};
- Contract.Assert(false, "The hashtable is full. This should not happen.");
+ Debug.Assert(false, "The hashtable is full. This should not happen.");
}
private void InsertHash(TokenHashValue[] hashTable, String str, TokenType tokenType, int tokenValue)
@@ -2876,7 +3007,7 @@ namespace System.Globalization
hashcode += hashProbe;
if (hashcode >= TOKEN_HASH_SIZE) hashcode -= TOKEN_HASH_SIZE;
} while (i < TOKEN_HASH_SIZE);
- Contract.Assert(false, "The hashtable is full. This should not happen.");
+ 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)
diff --git a/src/mscorlib/corefx/System/Globalization/DayLightTime.cs b/src/mscorlib/corefx/System/Globalization/DayLightTime.cs
index 2345fb5bc2..6ec9d6a43e 100644
--- a/src/mscorlib/corefx/System/Globalization/DayLightTime.cs
+++ b/src/mscorlib/corefx/System/Globalization/DayLightTime.cs
@@ -9,11 +9,11 @@ namespace System.Globalization
// This class represents a starting/ending time for a period of daylight saving time.
[Serializable]
- public partial class DaylightTime
+ public class DaylightTime
{
- internal DateTime m_start;
- internal DateTime m_end;
- internal TimeSpan m_delta;
+ private readonly DateTime _start;
+ private readonly DateTime _end;
+ private readonly TimeSpan _delta;
private DaylightTime()
{
@@ -21,36 +21,33 @@ namespace System.Globalization
public DaylightTime(DateTime start, DateTime end, TimeSpan delta)
{
- m_start = start;
- m_end = end;
- m_delta = delta;
+ _start = start;
+ _end = end;
+ _delta = delta;
}
// The start date of a daylight saving period.
- public DateTime Start
- {
- get
- {
- return m_start;
- }
- }
+ public DateTime Start => _start;
// The end date of a daylight saving period.
- public DateTime End
- {
- get
- {
- return m_end;
- }
- }
+ public DateTime End => _end;
// Delta to stardard offset in ticks.
- public TimeSpan Delta
+ public TimeSpan Delta => _delta;
+ }
+
+ // Value type version of DaylightTime
+ internal struct DaylightTimeStruct
+ {
+ public DaylightTimeStruct(DateTime start, DateTime end, TimeSpan delta)
{
- get
- {
- return m_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
new file mode 100644
index 0000000000..7e40033a2f
--- /dev/null
+++ b/src/mscorlib/corefx/System/Globalization/DigitShapes.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.
+
+//
+// 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
index 8f2bbbc10f..84a44a990d 100644
--- a/src/mscorlib/corefx/System/Globalization/EastAsianLunisolarCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/EastAsianLunisolarCalendar.cs
@@ -38,14 +38,13 @@ namespace System.Globalization
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;
- // }
- //}
+ public override CalendarAlgorithmType AlgorithmType
+ {
+ get
+ {
+ return CalendarAlgorithmType.LunisolarCalendar;
+ }
+ }
// Return the year number in the 60-year cycle.
//
@@ -69,7 +68,7 @@ namespace System.Globalization
if ((sexagenaryYear < 1) || (sexagenaryYear > 60))
{
throw new ArgumentOutOfRangeException(
- "sexagenaryYear",
+ nameof(sexagenaryYear),
SR.Format(SR.ArgumentOutOfRange_Range, 1, 60));
}
Contract.EndContractBlock();
@@ -86,7 +85,7 @@ namespace System.Globalization
if ((sexagenaryYear < 1) || (sexagenaryYear > 60))
{
throw new ArgumentOutOfRangeException(
- "sexagenaryYear",
+ nameof(sexagenaryYear),
SR.Format(SR.ArgumentOutOfRange_Range, 1, 60));
}
Contract.EndContractBlock();
@@ -133,7 +132,7 @@ namespace System.Globalization
return (mEraInfo[i].minEraYear);
}
}
- throw new ArgumentOutOfRangeException("era", SR.ArgumentOutOfRange_InvalidEraValue);
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
internal int MaxEraCalendarYear(int era)
@@ -162,7 +161,7 @@ namespace System.Globalization
return (mEraInfo[i].maxEraYear);
}
}
- throw new ArgumentOutOfRangeException("era", SR.ArgumentOutOfRange_InvalidEraValue);
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
internal EastAsianLunisolarCalendar()
@@ -190,7 +189,7 @@ namespace System.Globalization
if ((era < GetEra(MinDate)) || (era > GetEra(MaxDate)))
{
- throw new ArgumentOutOfRangeException("era", SR.ArgumentOutOfRange_InvalidEraValue);
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
}
@@ -202,7 +201,7 @@ namespace System.Globalization
if ((year < MinCalendarYear) || (year > MaxCalendarYear))
{
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
SR.Format(SR.ArgumentOutOfRange_Range, MinEraCalendarYear(era), MaxEraCalendarYear(era)));
}
return year;
@@ -216,12 +215,12 @@ namespace System.Globalization
{
//Reject if there is no leap month this year
if (GetYearInfo(year, LeapMonth) == 0)
- throw new ArgumentOutOfRangeException("month", SR.ArgumentOutOfRange_Month);
+ throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_Month);
}
if (month < 1 || month > 13)
{
- throw new ArgumentOutOfRangeException("month", SR.ArgumentOutOfRange_Month);
+ throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_Month);
}
return year;
}
@@ -266,7 +265,7 @@ namespace System.Globalization
if (day < 1 || day > daysInMonth)
{
throw new ArgumentOutOfRangeException(
- "day",
+ nameof(day),
SR.Format(SR.ArgumentOutOfRange_Day, daysInMonth, month));
}
@@ -447,7 +446,7 @@ namespace System.Globalization
if (months < -120000 || months > 120000)
{
throw new ArgumentOutOfRangeException(
- "months",
+ nameof(months),
SR.Format(SR.ArgumentOutOfRange_Range, -120000, 120000));
}
Contract.EndContractBlock();
@@ -627,7 +626,7 @@ namespace System.Globalization
if (day < 1 || day > daysInMonth)
{
throw new ArgumentOutOfRangeException(
- "day",
+ nameof(day),
SR.Format(SR.ArgumentOutOfRange_Day, daysInMonth, month));
}
int m = GetYearInfo(year, LeapMonth);
@@ -694,7 +693,7 @@ namespace System.Globalization
if (value < 99 || value > MaxCalendarYear)
{
throw new ArgumentOutOfRangeException(
- "value",
+ nameof(value),
SR.Format(SR.ArgumentOutOfRange_Range, 99, MaxCalendarYear));
}
twoDigitYearMax = value;
@@ -706,7 +705,7 @@ namespace System.Globalization
{
if (year < 0)
{
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
SR.ArgumentOutOfRange_NeedNonNegNum);
}
Contract.EndContractBlock();
diff --git a/src/mscorlib/corefx/System/Globalization/GregorianCalendar.cs b/src/mscorlib/corefx/System/Globalization/GregorianCalendar.cs
index d0933a0fc6..c2ed2e012b 100644
--- a/src/mscorlib/corefx/System/Globalization/GregorianCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/GregorianCalendar.cs
@@ -84,6 +84,15 @@ namespace System.Globalization
}
}
+ [System.Runtime.InteropServices.ComVisible(false)]
+ 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.
@@ -114,7 +123,7 @@ namespace System.Globalization
if ((int)type < (int)GregorianCalendarTypes.Localized || (int)type > (int)GregorianCalendarTypes.TransliteratedFrench)
{
throw new ArgumentOutOfRangeException(
- "type",
+ nameof(type),
SR.Format(SR.ArgumentOutOfRange_Range,
GregorianCalendarTypes.Localized, GregorianCalendarTypes.TransliteratedFrench));
}
@@ -205,7 +214,7 @@ namespace System.Globalization
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;
+ int m = (n >> 5) + 1;
// m = 1-based month number
while (n >= days[m]) m++;
// If month was requested, return it
@@ -277,7 +286,7 @@ namespace System.Globalization
if (months < -120000 || months > 120000)
{
throw new ArgumentOutOfRangeException(
- "months",
+ nameof(months),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -366,17 +375,17 @@ namespace System.Globalization
{
if (year < 1 || year > MaxYear)
{
- throw new ArgumentOutOfRangeException("year", SR.Format(SR.ArgumentOutOfRange_Range,
+ throw new ArgumentOutOfRangeException(nameof(year), SR.Format(SR.ArgumentOutOfRange_Range,
1, MaxYear));
}
if (month < 1 || month > 12)
{
- throw new ArgumentOutOfRangeException("month", SR.ArgumentOutOfRange_Month);
+ 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("era", SR.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.
@@ -391,14 +400,14 @@ namespace System.Globalization
return ((year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? 366 : 365);
}
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
1,
MaxYear));
}
- throw new ArgumentOutOfRangeException("era", SR.ArgumentOutOfRange_InvalidEraValue);
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
// Returns the era for the specified DateTime value.
@@ -438,14 +447,14 @@ namespace System.Globalization
return (12);
}
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
1,
MaxYear));
}
- throw new ArgumentOutOfRangeException("era", SR.ArgumentOutOfRange_InvalidEraValue);
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
// Returns the year part of the specified DateTime. The returned value is an
@@ -465,25 +474,25 @@ namespace System.Globalization
{
if (month < 1 || month > 12)
{
- throw new ArgumentOutOfRangeException("month", SR.Format(SR.ArgumentOutOfRange_Range,
+ throw new ArgumentOutOfRangeException(nameof(month), SR.Format(SR.ArgumentOutOfRange_Range,
1, 12));
}
Contract.EndContractBlock();
if (era != CurrentEra && era != ADEra)
{
- throw new ArgumentOutOfRangeException("era", SR.ArgumentOutOfRange_InvalidEraValue);
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
if (year < 1 || year > MaxYear)
{
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
SR.Format(SR.ArgumentOutOfRange_Range, 1, MaxYear));
}
if (day < 1 || day > GetDaysInMonth(year, month))
{
- throw new ArgumentOutOfRangeException("day", SR.Format(SR.ArgumentOutOfRange_Range,
+ throw new ArgumentOutOfRangeException(nameof(day), SR.Format(SR.ArgumentOutOfRange_Range,
1, GetDaysInMonth(year, month)));
}
if (!IsLeapYear(year))
@@ -506,12 +515,12 @@ namespace System.Globalization
{
if (era != CurrentEra && era != ADEra)
{
- throw new ArgumentOutOfRangeException("era", SR.ArgumentOutOfRange_InvalidEraValue);
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
if (year < 1 || year > MaxYear)
{
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range, 1, MaxYear));
@@ -528,13 +537,13 @@ namespace System.Globalization
{
if (era != CurrentEra && era != ADEra)
{
- throw new ArgumentOutOfRangeException("era", SR.ArgumentOutOfRange_InvalidEraValue);
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
if (year < 1 || year > MaxYear)
{
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range, 1, MaxYear));
@@ -542,7 +551,7 @@ namespace System.Globalization
if (month < 1 || month > 12)
{
- throw new ArgumentOutOfRangeException("month", SR.Format(SR.ArgumentOutOfRange_Range,
+ throw new ArgumentOutOfRangeException(nameof(month), SR.Format(SR.ArgumentOutOfRange_Range,
1, 12));
}
Contract.EndContractBlock();
@@ -563,12 +572,12 @@ namespace System.Globalization
}
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range, 1, MaxYear));
}
- throw new ArgumentOutOfRangeException("era", SR.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.
@@ -580,7 +589,7 @@ namespace System.Globalization
{
return new DateTime(year, month, day, hour, minute, second, millisecond);
}
- throw new ArgumentOutOfRangeException("era", SR.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)
@@ -643,7 +652,7 @@ namespace System.Globalization
{
if (year < 0)
{
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
SR.ArgumentOutOfRange_NeedNonNegNum);
}
Contract.EndContractBlock();
@@ -651,7 +660,7 @@ namespace System.Globalization
if (year > MaxYear)
{
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range, 1, MaxYear));
diff --git a/src/mscorlib/corefx/System/Globalization/GregorianCalendarHelper.cs b/src/mscorlib/corefx/System/Globalization/GregorianCalendarHelper.cs
index f595e72d0d..ee8ba13894 100644
--- a/src/mscorlib/corefx/System/Globalization/GregorianCalendarHelper.cs
+++ b/src/mscorlib/corefx/System/Globalization/GregorianCalendarHelper.cs
@@ -148,7 +148,7 @@ namespace System.Globalization
{
if (year < 0)
{
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
SR.ArgumentOutOfRange_NeedNonNegNum);
}
Contract.EndContractBlock();
@@ -165,7 +165,7 @@ namespace System.Globalization
if (year < m_EraInfo[i].minEraYear || year > m_EraInfo[i].maxEraYear)
{
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -175,7 +175,7 @@ namespace System.Globalization
return (m_EraInfo[i].yearOffset + year);
}
}
- throw new ArgumentOutOfRangeException("era", SR.ArgumentOutOfRange_InvalidEraValue);
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
internal bool IsValidYear(int year, int era)
@@ -248,7 +248,7 @@ namespace System.Globalization
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;
+ int m = (n >> 5) + 1;
// m = 1-based month number
while (n >= days[m]) m++;
// If month was requested, return it
@@ -308,7 +308,7 @@ namespace System.Globalization
if (millisecond < 0 || millisecond >= MillisPerSecond)
{
throw new ArgumentOutOfRangeException(
- "millisecond",
+ nameof(millisecond),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -358,7 +358,7 @@ namespace System.Globalization
if (months < -120000 || months > 120000)
{
throw new ArgumentOutOfRangeException(
- "months",
+ nameof(months),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -446,7 +446,7 @@ namespace System.Globalization
year = GetGregorianYear(year, era);
if (month < 1 || month > 12)
{
- throw new ArgumentOutOfRangeException("month", SR.ArgumentOutOfRange_Month);
+ 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]);
@@ -476,7 +476,7 @@ namespace System.Globalization
return (m_EraInfo[i].era);
}
}
- throw new ArgumentOutOfRangeException("time", SR.ArgumentOutOfRange_Era);
+ throw new ArgumentOutOfRangeException(nameof(time), SR.ArgumentOutOfRange_Era);
}
@@ -558,7 +558,7 @@ namespace System.Globalization
if (day < 1 || day > GetDaysInMonth(year, month, era))
{
throw new ArgumentOutOfRangeException(
- "day",
+ nameof(day),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -598,7 +598,7 @@ namespace System.Globalization
if (month < 1 || month > 12)
{
throw new ArgumentOutOfRangeException(
- "month",
+ nameof(month),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -640,7 +640,7 @@ namespace System.Globalization
{
if (year < 0)
{
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
SR.ArgumentOutOfRange_NeedPosNum);
}
Contract.EndContractBlock();
@@ -654,7 +654,7 @@ namespace System.Globalization
if (year < m_minYear || year > m_maxYear)
{
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range, m_minYear, m_maxYear));
diff --git a/src/mscorlib/corefx/System/Globalization/HebrewCalendar.cs b/src/mscorlib/corefx/System/Globalization/HebrewCalendar.cs
index 5fbf2e0f09..7e63708382 100644
--- a/src/mscorlib/corefx/System/Globalization/HebrewCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/HebrewCalendar.cs
@@ -2,8 +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.Text;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
namespace System.Globalization
@@ -65,7 +64,7 @@ namespace System.Globalization
[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
- public partial class HebrewCalendar : Calendar
+ public class HebrewCalendar : Calendar
{
public static readonly int HebrewEra = 1;
@@ -317,6 +316,14 @@ namespace System.Globalization
}
}
+ public override CalendarAlgorithmType AlgorithmType
+ {
+ get
+ {
+ return CalendarAlgorithmType.LunisolarCalendar;
+ }
+ }
+
public HebrewCalendar()
{
}
@@ -371,7 +378,7 @@ namespace System.Globalization
if (month < 1 || month > monthsInYear)
{
throw new ArgumentOutOfRangeException(
- "month",
+ nameof(month),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -397,7 +404,7 @@ namespace System.Globalization
if (day < 1 || day > daysInMonth)
{
throw new ArgumentOutOfRangeException(
- "day",
+ nameof(day),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -410,7 +417,7 @@ namespace System.Globalization
{
if (era != CurrentEra && era != HebrewEra)
{
- throw new ArgumentOutOfRangeException("era", SR.ArgumentOutOfRange_InvalidEraValue);
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
}
@@ -470,7 +477,7 @@ namespace System.Globalization
int index = gregorianYear - FirstGregorianTableYear;
if (index < 0 || index > TABLESIZE)
{
- throw new ArgumentOutOfRangeException("gregorianYear");
+ throw new ArgumentOutOfRangeException(nameof(gregorianYear));
}
index *= 2;
@@ -595,7 +602,7 @@ namespace System.Globalization
// is true.
//
NumDays -= (long)(s_lunarMonthLen[hebrewYearType * MaxMonthPlusOne + lunarDate.month] - lunarDate.day);
- Contract.Assert(NumDays >= 1, "NumDays >= 1");
+ Debug.Assert(NumDays >= 1, "NumDays >= 1");
// If NumDays is 1, then we are done. Otherwise, find the correct Hebrew month
// and day.
@@ -705,7 +712,7 @@ namespace System.Globalization
catch (ArgumentException)
{
throw new ArgumentOutOfRangeException(
- "months",
+ nameof(months),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_AddValue));
@@ -728,7 +735,7 @@ namespace System.Globalization
int d = GetDatePart(time.Ticks, DatePartDay);
y += years;
- CheckHebrewYearValue(y, Calendar.CurrentEra, "years");
+ CheckHebrewYearValue(y, Calendar.CurrentEra, nameof(years));
int months = GetMonthsInYear(y, CurrentEra);
if (m > months)
@@ -771,7 +778,7 @@ namespace System.Globalization
internal static int GetHebrewYearType(int year, int era)
{
- CheckHebrewYearValue(year, era, "year");
+ 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 (s_hebrewTable[(year - HebrewYearOf1AD - FirstGregorianTableYear) * 2 + 1]);
@@ -819,12 +826,12 @@ namespace System.Globalization
int hebrewYearType = GetHebrewYearType(year, era);
CheckHebrewMonthValue(year, month, era);
- Contract.Assert(hebrewYearType >= 1 && hebrewYearType <= 6,
+ Debug.Assert(hebrewYearType >= 1 && hebrewYearType <= 6,
"hebrewYearType should be from 1 to 6, but now hebrewYearType = " + hebrewYearType + " for hebrew year " + year);
int monthDays = s_lunarMonthLen[hebrewYearType * MaxMonthPlusOne + month];
if (monthDays == 0)
{
- throw new ArgumentOutOfRangeException("month", SR.ArgumentOutOfRange_Month);
+ throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_Month);
}
return (monthDays);
}
@@ -956,7 +963,7 @@ namespace System.Globalization
public override bool IsLeapYear(int year, int era)
{
- CheckHebrewYearValue(year, era, "year");
+ CheckHebrewYearValue(year, era, nameof(year));
return (((7 * (long)year + 1) % 19) < 7);
}
@@ -1047,7 +1054,7 @@ namespace System.Globalization
public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
{
- CheckHebrewYearValue(year, era, "year");
+ CheckHebrewYearValue(year, era, nameof(year));
CheckHebrewMonthValue(year, month, era);
CheckHebrewDayValue(year, month, day, era);
DateTime dt = HebrewToGregorian(year, month, day, hour, minute, second, millisecond);
@@ -1078,7 +1085,7 @@ namespace System.Globalization
}
else
{
- CheckHebrewYearValue(value, HebrewEra, "value");
+ CheckHebrewYearValue(value, HebrewEra, nameof(value));
}
twoDigitYearMax = value;
}
@@ -1089,7 +1096,7 @@ namespace System.Globalization
{
if (year < 0)
{
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
SR.ArgumentOutOfRange_NeedNonNegNum);
}
Contract.EndContractBlock();
@@ -1102,7 +1109,7 @@ namespace System.Globalization
if (year > MaxHebrewYear || year < MinHebrewYear)
{
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
diff --git a/src/mscorlib/corefx/System/Globalization/HebrewNumber.cs b/src/mscorlib/corefx/System/Globalization/HebrewNumber.cs
index 8fc264b788..01e251d9e8 100644
--- a/src/mscorlib/corefx/System/Globalization/HebrewNumber.cs
+++ b/src/mscorlib/corefx/System/Globalization/HebrewNumber.cs
@@ -2,18 +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.Text;
using System.Diagnostics;
-using System.Diagnostics.Contracts;
namespace System.Globalization
{
-
-#if INSIDE_CLR
- using Debug = BCLDebug;
-#endif
-
////////////////////////////////////////////////////////////////////////////
//
// Used in HebrewNumber.ParseByChar to maintain the context information (
@@ -110,7 +103,7 @@ namespace System.Globalization
Number -= 5000;
}
- Contract.Assert(Number > 0 && Number <= 999, "Number is out of range."); ;
+ Debug.Assert(Number > 0 && Number <= 999, "Number is out of range."); ;
//
// Get the Hundreds.
@@ -335,7 +328,7 @@ namespace System.Globalization
//
// The state machine for Hebrew number pasing.
//
- private readonly static HS[] s_numberPasingState =
+ private static readonly HS[] s_numberPasingState =
{
// 400 300/200 100 90~10 8~1 6, 7, 9, ' "
/* 0 */
diff --git a/src/mscorlib/corefx/System/Globalization/HijriCalendar.Win32.cs b/src/mscorlib/corefx/System/Globalization/HijriCalendar.Win32.cs
new file mode 100644
index 0000000000..5f46dce61d
--- /dev/null
+++ b/src/mscorlib/corefx/System/Globalization/HijriCalendar.Win32.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 Microsoft.Win32;
+
+namespace System.Globalization
+{
+ public partial class HijriCalendar : Calendar
+ {
+ private static 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.WinRT.cs b/src/mscorlib/corefx/System/Globalization/HijriCalendar.WinRT.cs
new file mode 100644
index 0000000000..fb91c27ef6
--- /dev/null
+++ b/src/mscorlib/corefx/System/Globalization/HijriCalendar.WinRT.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 Internal.Runtime.Augments;
+
+namespace System.Globalization
+{
+ public partial class HijriCalendar : Calendar
+ {
+ private static int GetHijriDateAdjustment()
+ {
+ return WinRTInterop.Callbacks.GetHijriDateAdjustment();
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/Globalization/HijriCalendar.Windows.cs b/src/mscorlib/corefx/System/Globalization/HijriCalendar.Windows.cs
deleted file mode 100644
index 185c5184be..0000000000
--- a/src/mscorlib/corefx/System/Globalization/HijriCalendar.Windows.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 Internal.Runtime.Augments;
-
-namespace System.Globalization
-{
- public partial class HijriCalendar : Calendar
- {
- public static int GetHijriDateAdjustment()
- {
- return WinRTInterop.Callbacks.GetHijriDateAdjustment();
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/HijriCalendar.cs b/src/mscorlib/corefx/System/Globalization/HijriCalendar.cs
index 72d9ab3f52..156b2104bd 100644
--- a/src/mscorlib/corefx/System/Globalization/HijriCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/HijriCalendar.cs
@@ -48,7 +48,7 @@ namespace System.Globalization
[System.Runtime.InteropServices.ComVisible(true)]
public partial class HijriCalendar : Calendar
{
- internal static readonly int HijriEra = 1;
+ public static readonly int HijriEra = 1;
internal const int DatePartYear = 0;
internal const int DatePartDayOfYear = 1;
@@ -91,6 +91,15 @@ namespace System.Globalization
}
}
+ [System.Runtime.InteropServices.ComVisible(false)]
+ public override CalendarAlgorithmType AlgorithmType
+ {
+ get
+ {
+ return CalendarAlgorithmType.LunarCalendar;
+ }
+ }
+
public HijriCalendar()
{
}
@@ -221,7 +230,7 @@ namespace System.Globalization
{
if (era != CurrentEra && era != HijriEra)
{
- throw new ArgumentOutOfRangeException("era", SR.ArgumentOutOfRange_InvalidEraValue);
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
}
@@ -231,7 +240,7 @@ namespace System.Globalization
if (year < 1 || year > MaxCalendarYear)
{
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -248,7 +257,7 @@ namespace System.Globalization
if (month > MaxCalendarMonth)
{
throw new ArgumentOutOfRangeException(
- "month",
+ nameof(month),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -259,7 +268,7 @@ namespace System.Globalization
if (month < 1 || month > 12)
{
- throw new ArgumentOutOfRangeException("month", SR.ArgumentOutOfRange_Month);
+ throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_Month);
}
}
@@ -386,7 +395,7 @@ namespace System.Globalization
if (months < -120000 || months > 120000)
{
throw new ArgumentOutOfRangeException(
- "months",
+ nameof(months),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -542,7 +551,7 @@ namespace System.Globalization
if (day < 1 || day > daysInMonth)
{
throw new ArgumentOutOfRangeException(
- "day",
+ nameof(day),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Day,
@@ -593,7 +602,7 @@ namespace System.Globalization
if (day < 1 || day > daysInMonth)
{
throw new ArgumentOutOfRangeException(
- "day",
+ nameof(day),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Day,
@@ -633,7 +642,7 @@ namespace System.Globalization
if (value < 99 || value > MaxCalendarYear)
{
throw new ArgumentOutOfRangeException(
- "value",
+ nameof(value),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -649,7 +658,7 @@ namespace System.Globalization
{
if (year < 0)
{
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
SR.ArgumentOutOfRange_NeedNonNegNum);
}
Contract.EndContractBlock();
@@ -662,7 +671,7 @@ namespace System.Globalization
if (year > MaxCalendarYear)
{
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
diff --git a/src/mscorlib/corefx/System/Globalization/IdnMapping.Unix.cs b/src/mscorlib/corefx/System/Globalization/IdnMapping.Unix.cs
new file mode 100644
index 0000000000..58f4ccadde
--- /dev/null
+++ b/src/mscorlib/corefx/System/Globalization/IdnMapping.Unix.cs
@@ -0,0 +1,134 @@
+// Licensed to the .NET Foundation under one or more 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
new file mode 100644
index 0000000000..f39457b750
--- /dev/null
+++ b/src/mscorlib/corefx/System/Globalization/IdnMapping.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;
+using System.Runtime.InteropServices;
+
+namespace System.Globalization
+{
+ 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
new file mode 100644
index 0000000000..8424472751
--- /dev/null
+++ b/src/mscorlib/corefx/System/Globalization/IdnMapping.cs
@@ -0,0 +1,152 @@
+// Licensed to the .NET Foundation under one or more 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/JapaneseCalendar.Unix.cs b/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.Unix.cs
index 12f430c71c..b9bd94af6e 100644
--- a/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.Unix.cs
+++ b/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.Unix.cs
@@ -3,13 +3,11 @@
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
-using System.Security;
namespace System.Globalization
{
public partial class JapaneseCalendar : Calendar
{
- [SecuritySafeCritical]
private static EraInfo[] GetJapaneseEras()
{
string[] eraNames;
@@ -66,7 +64,6 @@ namespace System.Globalization
return eraNames[eraIndex].Substring(0, 1);
}
- [SecuritySafeCritical]
private static bool GetJapaneseEraStartDate(int era, out DateTime dateTime)
{
dateTime = default(DateTime);
diff --git a/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.Win32.cs b/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.Win32.cs
new file mode 100644
index 0000000000..bbde320041
--- /dev/null
+++ b/src/mscorlib/corefx/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
+ {
+ // 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(new char[] {'_'});
+
+ // 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[] JapaneseErasEnglishNames = new String[] { "M", "T", "S", "H" };
+
+ private static string GetJapaneseEnglishEraName(int era)
+ {
+ Debug.Assert(era > 0);
+ return era <= JapaneseErasEnglishNames.Length ? JapaneseErasEnglishNames[era - 1] : " ";
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.Windows.cs b/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.WinRT.cs
index 6a9df97200..6a9df97200 100644
--- a/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.Windows.cs
+++ b/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.WinRT.cs
diff --git a/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.cs b/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.cs
index 4130801de5..0b0fa77fc0 100644
--- a/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.cs
@@ -9,11 +9,6 @@ using System.Diagnostics.Contracts;
namespace System.Globalization
{
-
-#if INSIDE_CLR
- using Debug = BCLDebug;
-#endif
-
/*=================================JapaneseCalendar==========================
**
** JapaneseCalendar is based on Gregorian calendar. The month and day values are the same as
@@ -68,6 +63,15 @@ namespace System.Globalization
}
}
+ [System.Runtime.InteropServices.ComVisible(false)]
+ 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.
@@ -302,7 +306,7 @@ namespace System.Globalization
{
if (year <= 0)
{
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
SR.ArgumentOutOfRange_NeedPosNum);
}
Contract.EndContractBlock();
@@ -310,7 +314,7 @@ namespace System.Globalization
if (year > helper.MaxYear)
{
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
diff --git a/src/mscorlib/corefx/System/Globalization/JulianCalendar.cs b/src/mscorlib/corefx/System/Globalization/JulianCalendar.cs
index 6721899ac9..a4277c6d49 100644
--- a/src/mscorlib/corefx/System/Globalization/JulianCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/JulianCalendar.cs
@@ -67,17 +67,14 @@ namespace System.Globalization
}
}
- // Return the type of the Julian calendar.
- //
-
- //[System.Runtime.InteropServices.ComVisible(false)]
- //public override CalendarAlgorithmType AlgorithmType
- //{
- // get
- // {
- // return CalendarAlgorithmType.SolarCalendar;
- // }
- //}
+ [System.Runtime.InteropServices.ComVisible(false)]
+ public override CalendarAlgorithmType AlgorithmType
+ {
+ get
+ {
+ return CalendarAlgorithmType.SolarCalendar;
+ }
+ }
public JulianCalendar()
{
@@ -97,7 +94,7 @@ namespace System.Globalization
{
if (era != CurrentEra && era != JulianEra)
{
- throw new ArgumentOutOfRangeException("era", SR.ArgumentOutOfRange_InvalidEraValue);
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
}
@@ -107,7 +104,7 @@ namespace System.Globalization
if (year <= 0 || year > MaxYear)
{
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -120,7 +117,7 @@ namespace System.Globalization
{
if (month < 1 || month > 12)
{
- throw new ArgumentOutOfRangeException("month", SR.ArgumentOutOfRange_Month);
+ throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_Month);
}
}
@@ -151,7 +148,7 @@ namespace System.Globalization
if (day < 1 || day > monthDays)
{
throw new ArgumentOutOfRangeException(
- "day",
+ nameof(day),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -196,7 +193,7 @@ namespace System.Globalization
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;
+ int m = (n >> 5) + 1;
// m = 1-based month number
while (n >= days[m]) m++;
// If month was requested, return it
@@ -223,7 +220,7 @@ namespace System.Globalization
if (months < -120000 || months > 120000)
{
throw new ArgumentOutOfRangeException(
- "months",
+ nameof(months),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -383,7 +380,7 @@ namespace System.Globalization
if (millisecond < 0 || millisecond >= MillisPerSecond)
{
throw new ArgumentOutOfRangeException(
- "millisecond",
+ nameof(millisecond),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -431,7 +428,7 @@ namespace System.Globalization
{
if (year < 0)
{
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
SR.ArgumentOutOfRange_NeedNonNegNum);
}
Contract.EndContractBlock();
@@ -439,7 +436,7 @@ namespace System.Globalization
if (year > MaxYear)
{
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Bounds_Lower_Upper,
diff --git a/src/mscorlib/corefx/System/Globalization/KoreanCalendar.cs b/src/mscorlib/corefx/System/Globalization/KoreanCalendar.cs
index 38a0b41fda..27d0aa812a 100644
--- a/src/mscorlib/corefx/System/Globalization/KoreanCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/KoreanCalendar.cs
@@ -69,6 +69,15 @@ namespace System.Globalization
}
}
+ [System.Runtime.InteropServices.ComVisible(false)]
+ public override CalendarAlgorithmType AlgorithmType
+ {
+ get
+ {
+ return CalendarAlgorithmType.SolarCalendar;
+ }
+ }
+
public KoreanCalendar()
{
try
@@ -253,7 +262,7 @@ namespace System.Globalization
{
if (year < 0)
{
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
SR.ArgumentOutOfRange_NeedNonNegNum);
}
Contract.EndContractBlock();
diff --git a/src/mscorlib/corefx/System/Globalization/KoreanLunisolarCalendar.cs b/src/mscorlib/corefx/System/Globalization/KoreanLunisolarCalendar.cs
index 68c4fab58f..07d85a461e 100644
--- a/src/mscorlib/corefx/System/Globalization/KoreanLunisolarCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/KoreanLunisolarCalendar.cs
@@ -1275,12 +1275,12 @@ namespace System.Globalization
internal override int GetGregorianYear(int year, int era)
{
if (era != CurrentEra && era != GregorianEra)
- throw new ArgumentOutOfRangeException("era", SR.ArgumentOutOfRange_InvalidEraValue);
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
if (year < MIN_LUNISOLAR_YEAR || year > MAX_LUNISOLAR_YEAR)
{
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range, MIN_LUNISOLAR_YEAR, MAX_LUNISOLAR_YEAR));
diff --git a/src/mscorlib/corefx/System/Globalization/LocaleData.Unix.cs b/src/mscorlib/corefx/System/Globalization/LocaleData.Unix.cs
new file mode 100644
index 0000000000..d4c58d8a3d
--- /dev/null
+++ b/src/mscorlib/corefx/System/Globalization/LocaleData.Unix.cs
@@ -0,0 +1,4572 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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;
+
+// This file contains the handling of Windows OS specific culture features.
+
+namespace System.Globalization
+{
+ internal enum LocaleDataParts
+ {
+ Lcid = 0,
+ AnsiCodePage = 1,
+ OemCodePage = 2,
+ MacCodePage = 3,
+ EbcdicCodePage = 4,
+ GeoId = 5,
+ DigitSubstitution = 6,
+ SpecificLocaleIndex = 7,
+ ConsoleLocaleIndex = 8
+ }
+
+ internal partial class LocaleData
+ {
+ // this is done rather than using a large readonly array of strings to avoid
+ // generating a large amount of code in the static constructor.
+ // Using indices from s_localeNamesIndices, we binary search this string when mapping
+ // an culture name to Lcid. Note that these names are all lowercase and are
+ // sorted alphabetically (ordinal).
+ private const string c_localeNames =
+ // culture name Lcid
+ "aa" + // 01000 - 0
+ "aa-dj" + // 01000 - 2
+ "aa-er" + // 01000 - 7
+ "aa-et" + // 01000 - 12
+ "af" + // 00036 - 17
+ "af-na" + // 01000 - 19
+ "af-za" + // 00436 - 24
+ "agq" + // 01000 - 29
+ "agq-cm" + // 01000 - 32
+ "ak" + // 01000 - 38
+ "ak-gh" + // 01000 - 40
+ "am" + // 0005e - 45
+ "am-et" + // 0045e - 47
+ "ar" + // 00001 - 52
+ "ar-001" + // 01000 - 54
+ "ar-ae" + // 03801 - 60
+ "ar-bh" + // 03c01 - 65
+ "ar-dj" + // 01000 - 70
+ "ar-dz" + // 01401 - 75
+ "ar-eg" + // 00c01 - 80
+ "ar-er" + // 01000 - 85
+ "ar-il" + // 01000 - 90
+ "ar-iq" + // 00801 - 95
+ "ar-jo" + // 02c01 - 100
+ "ar-km" + // 01000 - 105
+ "ar-kw" + // 03401 - 110
+ "ar-lb" + // 03001 - 115
+ "ar-ly" + // 01001 - 120
+ "ar-ma" + // 01801 - 125
+ "ar-mr" + // 01000 - 130
+ "ar-om" + // 02001 - 135
+ "ar-ps" + // 01000 - 140
+ "ar-qa" + // 04001 - 145
+ "ar-sa" + // 00401 - 150
+ "ar-sd" + // 01000 - 155
+ "ar-so" + // 01000 - 160
+ "ar-ss" + // 01000 - 165
+ "ar-sy" + // 02801 - 170
+ "ar-td" + // 01000 - 175
+ "ar-tn" + // 01c01 - 180
+ "ar-ye" + // 02401 - 185
+ "arn" + // 0007a - 190
+ "arn-cl" + // 0047a - 193
+ "as" + // 0004d - 199
+ "as-in" + // 0044d - 201
+ "asa" + // 01000 - 206
+ "asa-tz" + // 01000 - 209
+ "ast" + // 01000 - 215
+ "ast-es" + // 01000 - 218
+ "az" + // 0002c - 224
+ "az-cyrl" + // 0742c - 226
+ "az-cyrl-az" + // 0082c - 233
+ "az-latn" + // 0782c - 243
+ "az-latn-az" + // 0042c - 250
+ "ba" + // 0006d - 260
+ "ba-ru" + // 0046d - 262
+ "bas" + // 01000 - 267
+ "bas-cm" + // 01000 - 270
+ "be" + // 00023 - 276
+ "be-by" + // 00423 - 278
+ "bem" + // 01000 - 283
+ "bem-zm" + // 01000 - 286
+ "bez" + // 01000 - 292
+ "bez-tz" + // 01000 - 295
+ "bg" + // 00002 - 301
+ "bg-bg" + // 00402 - 303
+ "bin" + // 00066 - 308
+ "bin-ng" + // 00466 - 311
+ "bm" + // 01000 - 317
+ "bm-latn" + // 01000 - 319
+ "bm-latn-ml" + // 01000 - 326
+ "bn" + // 00045 - 336
+ "bn-bd" + // 00845 - 338
+ "bn-in" + // 00445 - 343
+ "bo" + // 00051 - 348
+ "bo-cn" + // 00451 - 350
+ "bo-in" + // 01000 - 355
+ "br" + // 0007e - 360
+ "br-fr" + // 0047e - 362
+ "brx" + // 01000 - 367
+ "brx-in" + // 01000 - 370
+ "bs" + // 0781a - 376
+ "bs-cyrl" + // 0641a - 378
+ "bs-cyrl-ba" + // 0201a - 385
+ "bs-latn" + // 0681a - 395
+ "bs-latn-ba" + // 0141a - 402
+ "byn" + // 01000 - 412
+ "byn-er" + // 01000 - 415
+ "ca" + // 00003 - 421
+ "ca-ad" + // 01000 - 423
+ "ca-es" + // 00403 - 428
+ "ca-es-valencia" + // 00803 - 433
+ "ca-fr" + // 01000 - 447
+ "ca-it" + // 01000 - 452
+ "ce" + // 01000 - 457
+ "ce-ru" + // 01000 - 459
+ "cgg" + // 01000 - 464
+ "cgg-ug" + // 01000 - 467
+ "chr" + // 0005c - 473
+ "chr-cher" + // 07c5c - 476
+ "chr-cher-us" + // 0045c - 484
+ "co" + // 00083 - 495
+ "co-fr" + // 00483 - 497
+ "cs" + // 00005 - 502
+ "cs-cz" + // 00405 - 504
+ "cu" + // 01000 - 509
+ "cu-ru" + // 01000 - 511
+ "cy" + // 00052 - 516
+ "cy-gb" + // 00452 - 518
+ "da" + // 00006 - 523
+ "da-dk" + // 00406 - 525
+ "da-gl" + // 01000 - 530
+ "dav" + // 01000 - 535
+ "dav-ke" + // 01000 - 538
+ "de" + // 00007 - 544
+ "de-at" + // 00c07 - 546
+ "de-be" + // 01000 - 551
+ "de-ch" + // 00807 - 556
+ "de-de" + // 00407 - 561
+ "de-de_phoneb" + // 10407 - 566
+ "de-it" + // 01000 - 578
+ "de-li" + // 01407 - 583
+ "de-lu" + // 01007 - 588
+ "dje" + // 01000 - 593
+ "dje-ne" + // 01000 - 596
+ "dsb" + // 07c2e - 602
+ "dsb-de" + // 0082e - 605
+ "dua" + // 01000 - 611
+ "dua-cm" + // 01000 - 614
+ "dv" + // 00065 - 620
+ "dv-mv" + // 00465 - 622
+ "dyo" + // 01000 - 627
+ "dyo-sn" + // 01000 - 630
+ "dz" + // 01000 - 636
+ "dz-bt" + // 00c51 - 638
+ "ebu" + // 01000 - 643
+ "ebu-ke" + // 01000 - 646
+ "ee" + // 01000 - 652
+ "ee-gh" + // 01000 - 654
+ "ee-tg" + // 01000 - 659
+ "el" + // 00008 - 664
+ "el-cy" + // 01000 - 666
+ "el-gr" + // 00408 - 671
+ "en" + // 00009 - 676
+ "en-001" + // 01000 - 678
+ "en-029" + // 02409 - 684
+ "en-150" + // 01000 - 690
+ "en-ag" + // 01000 - 696
+ "en-ai" + // 01000 - 701
+ "en-as" + // 01000 - 706
+ "en-at" + // 01000 - 711
+ "en-au" + // 00c09 - 716
+ "en-bb" + // 01000 - 721
+ "en-be" + // 01000 - 726
+ "en-bi" + // 01000 - 731
+ "en-bm" + // 01000 - 736
+ "en-bs" + // 01000 - 741
+ "en-bw" + // 01000 - 746
+ "en-bz" + // 02809 - 751
+ "en-ca" + // 01009 - 756
+ "en-cc" + // 01000 - 761
+ "en-ch" + // 01000 - 766
+ "en-ck" + // 01000 - 771
+ "en-cm" + // 01000 - 776
+ "en-cx" + // 01000 - 781
+ "en-cy" + // 01000 - 786
+ "en-de" + // 01000 - 791
+ "en-dk" + // 01000 - 796
+ "en-dm" + // 01000 - 801
+ "en-er" + // 01000 - 806
+ "en-fi" + // 01000 - 811
+ "en-fj" + // 01000 - 816
+ "en-fk" + // 01000 - 821
+ "en-fm" + // 01000 - 826
+ "en-gb" + // 00809 - 831
+ "en-gd" + // 01000 - 836
+ "en-gg" + // 01000 - 841
+ "en-gh" + // 01000 - 846
+ "en-gi" + // 01000 - 851
+ "en-gm" + // 01000 - 856
+ "en-gu" + // 01000 - 861
+ "en-gy" + // 01000 - 866
+ "en-hk" + // 03c09 - 871
+ "en-id" + // 03809 - 876
+ "en-ie" + // 01809 - 881
+ "en-il" + // 01000 - 886
+ "en-im" + // 01000 - 891
+ "en-in" + // 04009 - 896
+ "en-io" + // 01000 - 901
+ "en-je" + // 01000 - 906
+ "en-jm" + // 02009 - 911
+ "en-ke" + // 01000 - 916
+ "en-ki" + // 01000 - 921
+ "en-kn" + // 01000 - 926
+ "en-ky" + // 01000 - 931
+ "en-lc" + // 01000 - 936
+ "en-lr" + // 01000 - 941
+ "en-ls" + // 01000 - 946
+ "en-mg" + // 01000 - 951
+ "en-mh" + // 01000 - 956
+ "en-mo" + // 01000 - 961
+ "en-mp" + // 01000 - 966
+ "en-ms" + // 01000 - 971
+ "en-mt" + // 01000 - 976
+ "en-mu" + // 01000 - 981
+ "en-mw" + // 01000 - 986
+ "en-my" + // 04409 - 991
+ "en-na" + // 01000 - 996
+ "en-nf" + // 01000 - 1001
+ "en-ng" + // 01000 - 1006
+ "en-nl" + // 01000 - 1011
+ "en-nr" + // 01000 - 1016
+ "en-nu" + // 01000 - 1021
+ "en-nz" + // 01409 - 1026
+ "en-pg" + // 01000 - 1031
+ "en-ph" + // 03409 - 1036
+ "en-pk" + // 01000 - 1041
+ "en-pn" + // 01000 - 1046
+ "en-pr" + // 01000 - 1051
+ "en-pw" + // 01000 - 1056
+ "en-rw" + // 01000 - 1061
+ "en-sb" + // 01000 - 1066
+ "en-sc" + // 01000 - 1071
+ "en-sd" + // 01000 - 1076
+ "en-se" + // 01000 - 1081
+ "en-sg" + // 04809 - 1086
+ "en-sh" + // 01000 - 1091
+ "en-si" + // 01000 - 1096
+ "en-sl" + // 01000 - 1101
+ "en-ss" + // 01000 - 1106
+ "en-sx" + // 01000 - 1111
+ "en-sz" + // 01000 - 1116
+ "en-tc" + // 01000 - 1121
+ "en-tk" + // 01000 - 1126
+ "en-to" + // 01000 - 1131
+ "en-tt" + // 02c09 - 1136
+ "en-tv" + // 01000 - 1141
+ "en-tz" + // 01000 - 1146
+ "en-ug" + // 01000 - 1151
+ "en-um" + // 01000 - 1156
+ "en-us" + // 00409 - 1161
+ "en-vc" + // 01000 - 1166
+ "en-vg" + // 01000 - 1171
+ "en-vi" + // 01000 - 1176
+ "en-vu" + // 01000 - 1181
+ "en-ws" + // 01000 - 1186
+ "en-za" + // 01c09 - 1191
+ "en-zm" + // 01000 - 1196
+ "en-zw" + // 03009 - 1201
+ "eo" + // 01000 - 1206
+ "eo-001" + // 01000 - 1208
+ "es" + // 0000a - 1214
+ "es-419" + // 0580a - 1216
+ "es-ar" + // 02c0a - 1222
+ "es-bo" + // 0400a - 1227
+ "es-br" + // 01000 - 1232
+ "es-cl" + // 0340a - 1237
+ "es-co" + // 0240a - 1242
+ "es-cr" + // 0140a - 1247
+ "es-cu" + // 05c0a - 1252
+ "es-do" + // 01c0a - 1257
+ "es-ec" + // 0300a - 1262
+ "es-es" + // 00c0a - 1267
+ "es-es_tradnl" + // 0040a - 1272
+ "es-gq" + // 01000 - 1284
+ "es-gt" + // 0100a - 1289
+ "es-hn" + // 0480a - 1294
+ "es-mx" + // 0080a - 1299
+ "es-ni" + // 04c0a - 1304
+ "es-pa" + // 0180a - 1309
+ "es-pe" + // 0280a - 1314
+ "es-ph" + // 01000 - 1319
+ "es-pr" + // 0500a - 1324
+ "es-py" + // 03c0a - 1329
+ "es-sv" + // 0440a - 1334
+ "es-us" + // 0540a - 1339
+ "es-uy" + // 0380a - 1344
+ "es-ve" + // 0200a - 1349
+ "et" + // 00025 - 1354
+ "et-ee" + // 00425 - 1356
+ "eu" + // 0002d - 1361
+ "eu-es" + // 0042d - 1363
+ "ewo" + // 01000 - 1368
+ "ewo-cm" + // 01000 - 1371
+ "fa" + // 00029 - 1377
+ "fa-ir" + // 00429 - 1379
+ "ff" + // 00067 - 1384
+ "ff-cm" + // 01000 - 1386
+ "ff-gn" + // 01000 - 1391
+ "ff-latn" + // 07c67 - 1396
+ "ff-latn-sn" + // 00867 - 1403
+ "ff-mr" + // 01000 - 1413
+ "ff-ng" + // 00467 - 1418
+ "fi" + // 0000b - 1423
+ "fi-fi" + // 0040b - 1425
+ "fil" + // 00064 - 1430
+ "fil-ph" + // 00464 - 1433
+ "fo" + // 00038 - 1439
+ "fo-dk" + // 01000 - 1441
+ "fo-fo" + // 00438 - 1446
+ "fr" + // 0000c - 1451
+ "fr-029" + // 01c0c - 1453
+ "fr-be" + // 0080c - 1459
+ "fr-bf" + // 01000 - 1464
+ "fr-bi" + // 01000 - 1469
+ "fr-bj" + // 01000 - 1474
+ "fr-bl" + // 01000 - 1479
+ "fr-ca" + // 00c0c - 1484
+ "fr-cd" + // 0240c - 1489
+ "fr-cf" + // 01000 - 1494
+ "fr-cg" + // 01000 - 1499
+ "fr-ch" + // 0100c - 1504
+ "fr-ci" + // 0300c - 1509
+ "fr-cm" + // 02c0c - 1514
+ "fr-dj" + // 01000 - 1519
+ "fr-dz" + // 01000 - 1524
+ "fr-fr" + // 0040c - 1529
+ "fr-ga" + // 01000 - 1534
+ "fr-gf" + // 01000 - 1539
+ "fr-gn" + // 01000 - 1544
+ "fr-gp" + // 01000 - 1549
+ "fr-gq" + // 01000 - 1554
+ "fr-ht" + // 03c0c - 1559
+ "fr-km" + // 01000 - 1564
+ "fr-lu" + // 0140c - 1569
+ "fr-ma" + // 0380c - 1574
+ "fr-mc" + // 0180c - 1579
+ "fr-mf" + // 01000 - 1584
+ "fr-mg" + // 01000 - 1589
+ "fr-ml" + // 0340c - 1594
+ "fr-mq" + // 01000 - 1599
+ "fr-mr" + // 01000 - 1604
+ "fr-mu" + // 01000 - 1609
+ "fr-nc" + // 01000 - 1614
+ "fr-ne" + // 01000 - 1619
+ "fr-pf" + // 01000 - 1624
+ "fr-pm" + // 01000 - 1629
+ "fr-re" + // 0200c - 1634
+ "fr-rw" + // 01000 - 1639
+ "fr-sc" + // 01000 - 1644
+ "fr-sn" + // 0280c - 1649
+ "fr-sy" + // 01000 - 1654
+ "fr-td" + // 01000 - 1659
+ "fr-tg" + // 01000 - 1664
+ "fr-tn" + // 01000 - 1669
+ "fr-vu" + // 01000 - 1674
+ "fr-wf" + // 01000 - 1679
+ "fr-yt" + // 01000 - 1684
+ "fur" + // 01000 - 1689
+ "fur-it" + // 01000 - 1692
+ "fy" + // 00062 - 1698
+ "fy-nl" + // 00462 - 1700
+ "ga" + // 0003c - 1705
+ "ga-ie" + // 0083c - 1707
+ "gd" + // 00091 - 1712
+ "gd-gb" + // 00491 - 1714
+ "gl" + // 00056 - 1719
+ "gl-es" + // 00456 - 1721
+ "gn" + // 00074 - 1726
+ "gn-py" + // 00474 - 1728
+ "gsw" + // 00084 - 1733
+ "gsw-ch" + // 01000 - 1736
+ "gsw-fr" + // 00484 - 1742
+ "gsw-li" + // 01000 - 1748
+ "gu" + // 00047 - 1754
+ "gu-in" + // 00447 - 1756
+ "guz" + // 01000 - 1761
+ "guz-ke" + // 01000 - 1764
+ "gv" + // 01000 - 1770
+ "gv-im" + // 01000 - 1772
+ "ha" + // 00068 - 1777
+ "ha-latn" + // 07c68 - 1779
+ "ha-latn-gh" + // 01000 - 1786
+ "ha-latn-ne" + // 01000 - 1796
+ "ha-latn-ng" + // 00468 - 1806
+ "haw" + // 00075 - 1816
+ "haw-us" + // 00475 - 1819
+ "he" + // 0000d - 1825
+ "he-il" + // 0040d - 1827
+ "hi" + // 00039 - 1832
+ "hi-in" + // 00439 - 1834
+ "hr" + // 0001a - 1839
+ "hr-ba" + // 0101a - 1841
+ "hr-hr" + // 0041a - 1846
+ "hsb" + // 0002e - 1851
+ "hsb-de" + // 0042e - 1854
+ "hu" + // 0000e - 1860
+ "hu-hu" + // 0040e - 1862
+ "hu-hu_technl" + // 1040e - 1867
+ "hy" + // 0002b - 1879
+ "hy-am" + // 0042b - 1881
+ "ia" + // 01000 - 1886
+ "ia-001" + // 01000 - 1888
+ "ia-fr" + // 01000 - 1894
+ "ibb" + // 00069 - 1899
+ "ibb-ng" + // 00469 - 1902
+ "id" + // 00021 - 1908
+ "id-id" + // 00421 - 1910
+ "ig" + // 00070 - 1915
+ "ig-ng" + // 00470 - 1917
+ "ii" + // 00078 - 1922
+ "ii-cn" + // 00478 - 1924
+ "is" + // 0000f - 1929
+ "is-is" + // 0040f - 1931
+ "it" + // 00010 - 1936
+ "it-ch" + // 00810 - 1938
+ "it-it" + // 00410 - 1943
+ "it-sm" + // 01000 - 1948
+ "iu" + // 0005d - 1953
+ "iu-cans" + // 0785d - 1955
+ "iu-cans-ca" + // 0045d - 1962
+ "iu-latn" + // 07c5d - 1972
+ "iu-latn-ca" + // 0085d - 1979
+ "ja" + // 00011 - 1989
+ "ja-jp" + // 00411 - 1991
+ "ja-jp_radstr" + // 40411 - 1996
+ "jgo" + // 01000 - 2008
+ "jgo-cm" + // 01000 - 2011
+ "jmc" + // 01000 - 2017
+ "jmc-tz" + // 01000 - 2020
+ "jv" + // 01000 - 2026
+ "jv-java" + // 01000 - 2028
+ "jv-java-id" + // 01000 - 2035
+ "jv-latn" + // 01000 - 2045
+ "jv-latn-id" + // 01000 - 2052
+ "ka" + // 00037 - 2062
+ "ka-ge" + // 00437 - 2064
+ "ka-ge_modern" + // 10437 - 2069
+ "kab" + // 01000 - 2081
+ "kab-dz" + // 01000 - 2084
+ "kam" + // 01000 - 2090
+ "kam-ke" + // 01000 - 2093
+ "kde" + // 01000 - 2099
+ "kde-tz" + // 01000 - 2102
+ "kea" + // 01000 - 2108
+ "kea-cv" + // 01000 - 2111
+ "khq" + // 01000 - 2117
+ "khq-ml" + // 01000 - 2120
+ "ki" + // 01000 - 2126
+ "ki-ke" + // 01000 - 2128
+ "kk" + // 0003f - 2133
+ "kk-kz" + // 0043f - 2135
+ "kkj" + // 01000 - 2140
+ "kkj-cm" + // 01000 - 2143
+ "kl" + // 0006f - 2149
+ "kl-gl" + // 0046f - 2151
+ "kln" + // 01000 - 2156
+ "kln-ke" + // 01000 - 2159
+ "km" + // 00053 - 2165
+ "km-kh" + // 00453 - 2167
+ "kn" + // 0004b - 2172
+ "kn-in" + // 0044b - 2174
+ "ko" + // 00012 - 2179
+ "ko-kp" + // 01000 - 2181
+ "ko-kr" + // 00412 - 2186
+ "kok" + // 00057 - 2191
+ "kok-in" + // 00457 - 2194
+ "kr" + // 00071 - 2200
+ "kr-ng" + // 00471 - 2202
+ "ks" + // 00060 - 2207
+ "ks-arab" + // 00460 - 2209
+ "ks-arab-in" + // 01000 - 2216
+ "ks-deva" + // 01000 - 2226
+ "ks-deva-in" + // 00860 - 2233
+ "ksb" + // 01000 - 2243
+ "ksb-tz" + // 01000 - 2246
+ "ksf" + // 01000 - 2252
+ "ksf-cm" + // 01000 - 2255
+ "ksh" + // 01000 - 2261
+ "ksh-de" + // 01000 - 2264
+ "ku" + // 00092 - 2270
+ "ku-arab" + // 07c92 - 2272
+ "ku-arab-iq" + // 00492 - 2279
+ "ku-arab-ir" + // 01000 - 2289
+ "kw" + // 01000 - 2299
+ "kw-gb" + // 01000 - 2301
+ "ky" + // 00040 - 2306
+ "ky-kg" + // 00440 - 2308
+ "la" + // 00076 - 2313
+ "la-001" + // 00476 - 2315
+ "lag" + // 01000 - 2321
+ "lag-tz" + // 01000 - 2324
+ "lb" + // 0006e - 2330
+ "lb-lu" + // 0046e - 2332
+ "lg" + // 01000 - 2337
+ "lg-ug" + // 01000 - 2339
+ "lkt" + // 01000 - 2344
+ "lkt-us" + // 01000 - 2347
+ "ln" + // 01000 - 2353
+ "ln-ao" + // 01000 - 2355
+ "ln-cd" + // 01000 - 2360
+ "ln-cf" + // 01000 - 2365
+ "ln-cg" + // 01000 - 2370
+ "lo" + // 00054 - 2375
+ "lo-la" + // 00454 - 2377
+ "lrc" + // 01000 - 2382
+ "lrc-iq" + // 01000 - 2385
+ "lrc-ir" + // 01000 - 2391
+ "lt" + // 00027 - 2397
+ "lt-lt" + // 00427 - 2399
+ "lu" + // 01000 - 2404
+ "lu-cd" + // 01000 - 2406
+ "luo" + // 01000 - 2411
+ "luo-ke" + // 01000 - 2414
+ "luy" + // 01000 - 2420
+ "luy-ke" + // 01000 - 2423
+ "lv" + // 00026 - 2429
+ "lv-lv" + // 00426 - 2431
+ "mas" + // 01000 - 2436
+ "mas-ke" + // 01000 - 2439
+ "mas-tz" + // 01000 - 2445
+ "mer" + // 01000 - 2451
+ "mer-ke" + // 01000 - 2454
+ "mfe" + // 01000 - 2460
+ "mfe-mu" + // 01000 - 2463
+ "mg" + // 01000 - 2469
+ "mg-mg" + // 01000 - 2471
+ "mgh" + // 01000 - 2476
+ "mgh-mz" + // 01000 - 2479
+ "mgo" + // 01000 - 2485
+ "mgo-cm" + // 01000 - 2488
+ "mi" + // 00081 - 2494
+ "mi-nz" + // 00481 - 2496
+ "mk" + // 0002f - 2501
+ "mk-mk" + // 0042f - 2503
+ "ml" + // 0004c - 2508
+ "ml-in" + // 0044c - 2510
+ "mn" + // 00050 - 2515
+ "mn-cyrl" + // 07850 - 2517
+ "mn-mn" + // 00450 - 2524
+ "mn-mong" + // 07c50 - 2529
+ "mn-mong-cn" + // 00850 - 2536
+ "mn-mong-mn" + // 00c50 - 2546
+ "mni" + // 00058 - 2556
+ "mni-in" + // 00458 - 2559
+ "moh" + // 0007c - 2565
+ "moh-ca" + // 0047c - 2568
+ "mr" + // 0004e - 2574
+ "mr-in" + // 0044e - 2576
+ "ms" + // 0003e - 2581
+ "ms-bn" + // 0083e - 2583
+ "ms-my" + // 0043e - 2588
+ "ms-sg" + // 01000 - 2593
+ "mt" + // 0003a - 2598
+ "mt-mt" + // 0043a - 2600
+ "mua" + // 01000 - 2605
+ "mua-cm" + // 01000 - 2608
+ "my" + // 00055 - 2614
+ "my-mm" + // 00455 - 2616
+ "mzn" + // 01000 - 2621
+ "mzn-ir" + // 01000 - 2624
+ "naq" + // 01000 - 2630
+ "naq-na" + // 01000 - 2633
+ "nb" + // 07c14 - 2639
+ "nb-no" + // 00414 - 2641
+ "nb-sj" + // 01000 - 2646
+ "nd" + // 01000 - 2651
+ "nd-zw" + // 01000 - 2653
+ "nds" + // 01000 - 2658
+ "nds-de" + // 01000 - 2661
+ "nds-nl" + // 01000 - 2667
+ "ne" + // 00061 - 2673
+ "ne-in" + // 00861 - 2675
+ "ne-np" + // 00461 - 2680
+ "nl" + // 00013 - 2685
+ "nl-aw" + // 01000 - 2687
+ "nl-be" + // 00813 - 2692
+ "nl-bq" + // 01000 - 2697
+ "nl-cw" + // 01000 - 2702
+ "nl-nl" + // 00413 - 2707
+ "nl-sr" + // 01000 - 2712
+ "nl-sx" + // 01000 - 2717
+ "nmg" + // 01000 - 2722
+ "nmg-cm" + // 01000 - 2725
+ "nn" + // 07814 - 2731
+ "nn-no" + // 00814 - 2733
+ "nnh" + // 01000 - 2738
+ "nnh-cm" + // 01000 - 2741
+ "no" + // 00014 - 2747
+ "nqo" + // 01000 - 2749
+ "nqo-gn" + // 01000 - 2752
+ "nr" + // 01000 - 2758
+ "nr-za" + // 01000 - 2760
+ "nso" + // 0006c - 2765
+ "nso-za" + // 0046c - 2768
+ "nus" + // 01000 - 2774
+ "nus-ss" + // 01000 - 2777
+ "nyn" + // 01000 - 2783
+ "nyn-ug" + // 01000 - 2786
+ "oc" + // 00082 - 2792
+ "oc-fr" + // 00482 - 2794
+ "om" + // 00072 - 2799
+ "om-et" + // 00472 - 2801
+ "om-ke" + // 01000 - 2806
+ "or" + // 00048 - 2811
+ "or-in" + // 00448 - 2813
+ "os" + // 01000 - 2818
+ "os-ge" + // 01000 - 2820
+ "os-ru" + // 01000 - 2825
+ "pa" + // 00046 - 2830
+ "pa-arab" + // 07c46 - 2832
+ "pa-arab-pk" + // 00846 - 2839
+ "pa-in" + // 00446 - 2849
+ "pap" + // 00079 - 2854
+ "pap-029" + // 00479 - 2857
+ "pl" + // 00015 - 2864
+ "pl-pl" + // 00415 - 2866
+ "prg" + // 01000 - 2871
+ "prg-001" + // 01000 - 2874
+ "prs" + // 0008c - 2881
+ "prs-af" + // 0048c - 2884
+ "ps" + // 00063 - 2890
+ "ps-af" + // 00463 - 2892
+ "pt" + // 00016 - 2897
+ "pt-ao" + // 01000 - 2899
+ "pt-br" + // 00416 - 2904
+ "pt-ch" + // 01000 - 2909
+ "pt-cv" + // 01000 - 2914
+ "pt-gq" + // 01000 - 2919
+ "pt-gw" + // 01000 - 2924
+ "pt-lu" + // 01000 - 2929
+ "pt-mo" + // 01000 - 2934
+ "pt-mz" + // 01000 - 2939
+ "pt-pt" + // 00816 - 2944
+ "pt-st" + // 01000 - 2949
+ "pt-tl" + // 01000 - 2954
+ "qps-latn-x-sh" + // 00901 - 2959
+ "qps-ploc" + // 00501 - 2972
+ "qps-ploca" + // 005fe - 2980
+ "qps-plocm" + // 009ff - 2989
+ "quc" + // 00086 - 2998
+ "quc-latn" + // 07c86 - 3001
+ "quc-latn-gt" + // 00486 - 3009
+ "quz" + // 0006b - 3020
+ "quz-bo" + // 0046b - 3023
+ "quz-ec" + // 0086b - 3029
+ "quz-pe" + // 00c6b - 3035
+ "rm" + // 00017 - 3041
+ "rm-ch" + // 00417 - 3043
+ "rn" + // 01000 - 3048
+ "rn-bi" + // 01000 - 3050
+ "ro" + // 00018 - 3055
+ "ro-md" + // 00818 - 3057
+ "ro-ro" + // 00418 - 3062
+ "rof" + // 01000 - 3067
+ "rof-tz" + // 01000 - 3070
+ "ru" + // 00019 - 3076
+ "ru-by" + // 01000 - 3078
+ "ru-kg" + // 01000 - 3083
+ "ru-kz" + // 01000 - 3088
+ "ru-md" + // 00819 - 3093
+ "ru-ru" + // 00419 - 3098
+ "ru-ua" + // 01000 - 3103
+ "rw" + // 00087 - 3108
+ "rw-rw" + // 00487 - 3110
+ "rwk" + // 01000 - 3115
+ "rwk-tz" + // 01000 - 3118
+ "sa" + // 0004f - 3124
+ "sa-in" + // 0044f - 3126
+ "sah" + // 00085 - 3131
+ "sah-ru" + // 00485 - 3134
+ "saq" + // 01000 - 3140
+ "saq-ke" + // 01000 - 3143
+ "sbp" + // 01000 - 3149
+ "sbp-tz" + // 01000 - 3152
+ "sd" + // 00059 - 3158
+ "sd-arab" + // 07c59 - 3160
+ "sd-arab-pk" + // 00859 - 3167
+ "sd-deva" + // 01000 - 3177
+ "sd-deva-in" + // 00459 - 3184
+ "se" + // 0003b - 3194
+ "se-fi" + // 00c3b - 3196
+ "se-no" + // 0043b - 3201
+ "se-se" + // 0083b - 3206
+ "seh" + // 01000 - 3211
+ "seh-mz" + // 01000 - 3214
+ "ses" + // 01000 - 3220
+ "ses-ml" + // 01000 - 3223
+ "sg" + // 01000 - 3229
+ "sg-cf" + // 01000 - 3231
+ "shi" + // 01000 - 3236
+ "shi-latn" + // 01000 - 3239
+ "shi-latn-ma" + // 01000 - 3247
+ "shi-tfng" + // 01000 - 3258
+ "shi-tfng-ma" + // 01000 - 3266
+ "si" + // 0005b - 3277
+ "si-lk" + // 0045b - 3279
+ "sk" + // 0001b - 3284
+ "sk-sk" + // 0041b - 3286
+ "sl" + // 00024 - 3291
+ "sl-si" + // 00424 - 3293
+ "sma" + // 0783b - 3298
+ "sma-no" + // 0183b - 3301
+ "sma-se" + // 01c3b - 3307
+ "smj" + // 07c3b - 3313
+ "smj-no" + // 0103b - 3316
+ "smj-se" + // 0143b - 3322
+ "smn" + // 0703b - 3328
+ "smn-fi" + // 0243b - 3331
+ "sms" + // 0743b - 3337
+ "sms-fi" + // 0203b - 3340
+ "sn" + // 01000 - 3346
+ "sn-latn" + // 01000 - 3348
+ "sn-latn-zw" + // 01000 - 3355
+ "so" + // 00077 - 3365
+ "so-dj" + // 01000 - 3367
+ "so-et" + // 01000 - 3372
+ "so-ke" + // 01000 - 3377
+ "so-so" + // 00477 - 3382
+ "sq" + // 0001c - 3387
+ "sq-al" + // 0041c - 3389
+ "sq-mk" + // 01000 - 3394
+ "sq-xk" + // 01000 - 3399
+ "sr" + // 07c1a - 3404
+ "sr-cyrl" + // 06c1a - 3406
+ "sr-cyrl-ba" + // 01c1a - 3413
+ "sr-cyrl-cs" + // 00c1a - 3423
+ "sr-cyrl-me" + // 0301a - 3433
+ "sr-cyrl-rs" + // 0281a - 3443
+ "sr-cyrl-xk" + // 01000 - 3453
+ "sr-latn" + // 0701a - 3463
+ "sr-latn-ba" + // 0181a - 3470
+ "sr-latn-cs" + // 0081a - 3480
+ "sr-latn-me" + // 02c1a - 3490
+ "sr-latn-rs" + // 0241a - 3500
+ "sr-latn-xk" + // 01000 - 3510
+ "ss" + // 01000 - 3520
+ "ss-sz" + // 01000 - 3522
+ "ss-za" + // 01000 - 3527
+ "ssy" + // 01000 - 3532
+ "ssy-er" + // 01000 - 3535
+ "st" + // 00030 - 3541
+ "st-ls" + // 01000 - 3543
+ "st-za" + // 00430 - 3548
+ "sv" + // 0001d - 3553
+ "sv-ax" + // 01000 - 3555
+ "sv-fi" + // 0081d - 3560
+ "sv-se" + // 0041d - 3565
+ "sw" + // 00041 - 3570
+ "sw-cd" + // 01000 - 3572
+ "sw-ke" + // 00441 - 3577
+ "sw-tz" + // 01000 - 3582
+ "sw-ug" + // 01000 - 3587
+ "swc" + // 01000 - 3592
+ "swc-cd" + // 01000 - 3595
+ "syr" + // 0005a - 3601
+ "syr-sy" + // 0045a - 3604
+ "ta" + // 00049 - 3610
+ "ta-in" + // 00449 - 3612
+ "ta-lk" + // 00849 - 3617
+ "ta-my" + // 01000 - 3622
+ "ta-sg" + // 01000 - 3627
+ "te" + // 0004a - 3632
+ "te-in" + // 0044a - 3634
+ "teo" + // 01000 - 3639
+ "teo-ke" + // 01000 - 3642
+ "teo-ug" + // 01000 - 3648
+ "tg" + // 00028 - 3654
+ "tg-cyrl" + // 07c28 - 3656
+ "tg-cyrl-tj" + // 00428 - 3663
+ "th" + // 0001e - 3673
+ "th-th" + // 0041e - 3675
+ "ti" + // 00073 - 3680
+ "ti-er" + // 00873 - 3682
+ "ti-et" + // 00473 - 3687
+ "tig" + // 01000 - 3692
+ "tig-er" + // 01000 - 3695
+ "tk" + // 00042 - 3701
+ "tk-tm" + // 00442 - 3703
+ "tn" + // 00032 - 3708
+ "tn-bw" + // 00832 - 3710
+ "tn-za" + // 00432 - 3715
+ "to" + // 01000 - 3720
+ "to-to" + // 01000 - 3722
+ "tr" + // 0001f - 3727
+ "tr-cy" + // 01000 - 3729
+ "tr-tr" + // 0041f - 3734
+ "ts" + // 00031 - 3739
+ "ts-za" + // 00431 - 3741
+ "tt" + // 00044 - 3746
+ "tt-ru" + // 00444 - 3748
+ "twq" + // 01000 - 3753
+ "twq-ne" + // 01000 - 3756
+ "tzm" + // 0005f - 3762
+ "tzm-arab" + // 01000 - 3765
+ "tzm-arab-ma" + // 0045f - 3773
+ "tzm-latn" + // 07c5f - 3784
+ "tzm-latn-dz" + // 0085f - 3792
+ "tzm-latn-ma" + // 01000 - 3803
+ "tzm-tfng" + // 0785f - 3814
+ "tzm-tfng-ma" + // 0105f - 3822
+ "ug" + // 00080 - 3833
+ "ug-cn" + // 00480 - 3835
+ "uk" + // 00022 - 3840
+ "uk-ua" + // 00422 - 3842
+ "ur" + // 00020 - 3847
+ "ur-in" + // 00820 - 3849
+ "ur-pk" + // 00420 - 3854
+ "uz" + // 00043 - 3859
+ "uz-arab" + // 01000 - 3861
+ "uz-arab-af" + // 01000 - 3868
+ "uz-cyrl" + // 07843 - 3878
+ "uz-cyrl-uz" + // 00843 - 3885
+ "uz-latn" + // 07c43 - 3895
+ "uz-latn-uz" + // 00443 - 3902
+ "vai" + // 01000 - 3912
+ "vai-latn" + // 01000 - 3915
+ "vai-latn-lr" + // 01000 - 3923
+ "vai-vaii" + // 01000 - 3934
+ "vai-vaii-lr" + // 01000 - 3942
+ "ve" + // 00033 - 3953
+ "ve-za" + // 00433 - 3955
+ "vi" + // 0002a - 3960
+ "vi-vn" + // 0042a - 3962
+ "vo" + // 01000 - 3967
+ "vo-001" + // 01000 - 3969
+ "vun" + // 01000 - 3975
+ "vun-tz" + // 01000 - 3978
+ "wae" + // 01000 - 3984
+ "wae-ch" + // 01000 - 3987
+ "wal" + // 01000 - 3993
+ "wal-et" + // 01000 - 3996
+ "wo" + // 00088 - 4002
+ "wo-sn" + // 00488 - 4004
+ "x-iv_mathan" + // 1007f - 4009
+ "xh" + // 00034 - 4020
+ "xh-za" + // 00434 - 4022
+ "xog" + // 01000 - 4027
+ "xog-ug" + // 01000 - 4030
+ "yav" + // 01000 - 4036
+ "yav-cm" + // 01000 - 4039
+ "yi" + // 0003d - 4045
+ "yi-001" + // 0043d - 4047
+ "yo" + // 0006a - 4053
+ "yo-bj" + // 01000 - 4055
+ "yo-ng" + // 0046a - 4060
+ "yue" + // 01000 - 4065
+ "yue-hk" + // 01000 - 4068
+ "zgh" + // 01000 - 4074
+ "zgh-tfng" + // 01000 - 4077
+ "zgh-tfng-ma" + // 01000 - 4085
+ "zh" + // 07804 - 4096
+ "zh-chs" + // 00004 - 4098
+ "zh-cht" + // 07c04 - 4104
+ "zh-cn" + // 00804 - 4110
+ "zh-cn_phoneb" + // 50804 - 4115
+ "zh-cn_stroke" + // 20804 - 4127
+ "zh-hans" + // 00004 - 4139
+ "zh-hans-hk" + // 01000 - 4146
+ "zh-hans-mo" + // 01000 - 4156
+ "zh-hant" + // 07c04 - 4166
+ "zh-hk" + // 00c04 - 4173
+ "zh-hk_radstr" + // 40c04 - 4178
+ "zh-mo" + // 01404 - 4190
+ "zh-mo_radstr" + // 41404 - 4195
+ "zh-mo_stroke" + // 21404 - 4207
+ "zh-sg" + // 01004 - 4219
+ "zh-sg_phoneb" + // 51004 - 4224
+ "zh-sg_stroke" + // 21004 - 4236
+ "zh-tw" + // 00404 - 4248
+ "zh-tw_pronun" + // 30404 - 4253
+ "zh-tw_radstr" + // 40404 - 4265
+ "zu" + // 00035 - 4277
+ "zu-za"; // 00435 - 4279
+
+ // c_threeLetterWindowsLanguageName is string containing 3-letter Windows language names
+ // every 3-characters entry is matching locale name entry in c_localeNames
+
+ private const string c_threeLetterWindowsLanguageName =
+ "ZZZ" + // aa
+ "ZZZ" + // aa-dj
+ "ZZZ" + // aa-er
+ "ZZZ" + // aa-et
+ "AFK" + // af
+ "ZZZ" + // af-na
+ "AFK" + // af-za
+ "ZZZ" + // agq
+ "ZZZ" + // agq-cm
+ "ZZZ" + // ak
+ "ZZZ" + // ak-gh
+ "AMH" + // am
+ "AMH" + // am-et
+ "ARA" + // ar
+ "ZZZ" + // ar-001
+ "ARU" + // ar-ae
+ "ARH" + // ar-bh
+ "ZZZ" + // ar-dj
+ "ARG" + // ar-dz
+ "ARE" + // ar-eg
+ "ZZZ" + // ar-er
+ "ZZZ" + // ar-il
+ "ARI" + // ar-iq
+ "ARJ" + // ar-jo
+ "ZZZ" + // ar-km
+ "ARK" + // ar-kw
+ "ARB" + // ar-lb
+ "ARL" + // ar-ly
+ "ARM" + // ar-ma
+ "ZZZ" + // ar-mr
+ "ARO" + // ar-om
+ "ZZZ" + // ar-ps
+ "ARQ" + // ar-qa
+ "ARA" + // ar-sa
+ "ZZZ" + // ar-sd
+ "ZZZ" + // ar-so
+ "ZZZ" + // ar-ss
+ "ARS" + // ar-sy
+ "ZZZ" + // ar-td
+ "ART" + // ar-tn
+ "ARY" + // ar-ye
+ "MPD" + // arn
+ "MPD" + // arn-cl
+ "ASM" + // as
+ "ASM" + // as-in
+ "ZZZ" + // asa
+ "ZZZ" + // asa-tz
+ "ZZZ" + // ast
+ "ZZZ" + // ast-es
+ "AZE" + // az
+ "AZC" + // az-cyrl
+ "AZC" + // az-cyrl-az
+ "AZE" + // az-latn
+ "AZE" + // az-latn-az
+ "BAS" + // ba
+ "BAS" + // ba-ru
+ "ZZZ" + // bas
+ "ZZZ" + // bas-cm
+ "BEL" + // be
+ "BEL" + // be-by
+ "ZZZ" + // bem
+ "ZZZ" + // bem-zm
+ "ZZZ" + // bez
+ "ZZZ" + // bez-tz
+ "BGR" + // bg
+ "BGR" + // bg-bg
+ "ZZZ" + // bin
+ "ZZZ" + // bin-ng
+ "ZZZ" + // bm
+ "ZZZ" + // bm-latn
+ "ZZZ" + // bm-latn-ml
+ "BNB" + // bn
+ "BNB" + // bn-bd
+ "BNG" + // bn-in
+ "BOB" + // bo
+ "BOB" + // bo-cn
+ "ZZZ" + // bo-in
+ "BRE" + // br
+ "BRE" + // br-fr
+ "ZZZ" + // brx
+ "ZZZ" + // brx-in
+ "BSB" + // bs
+ "BSC" + // bs-cyrl
+ "BSC" + // bs-cyrl-ba
+ "BSB" + // bs-latn
+ "BSB" + // bs-latn-ba
+ "ZZZ" + // byn
+ "ZZZ" + // byn-er
+ "CAT" + // ca
+ "ZZZ" + // ca-ad
+ "CAT" + // ca-es
+ "VAL" + // ca-es-valencia
+ "ZZZ" + // ca-fr
+ "ZZZ" + // ca-it
+ "ZZZ" + // ce
+ "ZZZ" + // ce-ru
+ "ZZZ" + // cgg
+ "ZZZ" + // cgg-ug
+ "CRE" + // chr
+ "CRE" + // chr-cher
+ "CRE" + // chr-cher-us
+ "COS" + // co
+ "COS" + // co-fr
+ "CSY" + // cs
+ "CSY" + // cs-cz
+ "ZZZ" + // cu
+ "ZZZ" + // cu-ru
+ "CYM" + // cy
+ "CYM" + // cy-gb
+ "DAN" + // da
+ "DAN" + // da-dk
+ "ZZZ" + // da-gl
+ "ZZZ" + // dav
+ "ZZZ" + // dav-ke
+ "DEU" + // de
+ "DEA" + // de-at
+ "ZZZ" + // de-be
+ "DES" + // de-ch
+ "DEU" + // de-de
+ "DEU" + // de-de_phoneb
+ "ZZZ" + // de-it
+ "DEC" + // de-li
+ "DEL" + // de-lu
+ "ZZZ" + // dje
+ "ZZZ" + // dje-ne
+ "DSB" + // dsb
+ "DSB" + // dsb-de
+ "ZZZ" + // dua
+ "ZZZ" + // dua-cm
+ "DIV" + // dv
+ "DIV" + // dv-mv
+ "ZZZ" + // dyo
+ "ZZZ" + // dyo-sn
+ "ZZZ" + // dz
+ "ZZZ" + // dz-bt
+ "ZZZ" + // ebu
+ "ZZZ" + // ebu-ke
+ "ZZZ" + // ee
+ "ZZZ" + // ee-gh
+ "ZZZ" + // ee-tg
+ "ELL" + // el
+ "ZZZ" + // el-cy
+ "ELL" + // el-gr
+ "ENU" + // en
+ "ZZZ" + // en-001
+ "ENB" + // en-029
+ "ZZZ" + // en-150
+ "ZZZ" + // en-ag
+ "ZZZ" + // en-ai
+ "ZZZ" + // en-as
+ "ZZZ" + // en-at
+ "ENA" + // en-au
+ "ZZZ" + // en-bb
+ "ZZZ" + // en-be
+ "ZZZ" + // en-bi
+ "ZZZ" + // en-bm
+ "ZZZ" + // en-bs
+ "ZZZ" + // en-bw
+ "ENL" + // en-bz
+ "ENC" + // en-ca
+ "ZZZ" + // en-cc
+ "ZZZ" + // en-ch
+ "ZZZ" + // en-ck
+ "ZZZ" + // en-cm
+ "ZZZ" + // en-cx
+ "ZZZ" + // en-cy
+ "ZZZ" + // en-de
+ "ZZZ" + // en-dk
+ "ZZZ" + // en-dm
+ "ZZZ" + // en-er
+ "ZZZ" + // en-fi
+ "ZZZ" + // en-fj
+ "ZZZ" + // en-fk
+ "ZZZ" + // en-fm
+ "ENG" + // en-gb
+ "ZZZ" + // en-gd
+ "ZZZ" + // en-gg
+ "ZZZ" + // en-gh
+ "ZZZ" + // en-gi
+ "ZZZ" + // en-gm
+ "ZZZ" + // en-gu
+ "ZZZ" + // en-gy
+ "ENH" + // en-hk
+ "ZZZ" + // en-id
+ "ENI" + // en-ie
+ "ZZZ" + // en-il
+ "ZZZ" + // en-im
+ "ENN" + // en-in
+ "ZZZ" + // en-io
+ "ZZZ" + // en-je
+ "ENJ" + // en-jm
+ "ZZZ" + // en-ke
+ "ZZZ" + // en-ki
+ "ZZZ" + // en-kn
+ "ZZZ" + // en-ky
+ "ZZZ" + // en-lc
+ "ZZZ" + // en-lr
+ "ZZZ" + // en-ls
+ "ZZZ" + // en-mg
+ "ZZZ" + // en-mh
+ "ZZZ" + // en-mo
+ "ZZZ" + // en-mp
+ "ZZZ" + // en-ms
+ "ZZZ" + // en-mt
+ "ZZZ" + // en-mu
+ "ZZZ" + // en-mw
+ "ENM" + // en-my
+ "ZZZ" + // en-na
+ "ZZZ" + // en-nf
+ "ZZZ" + // en-ng
+ "ZZZ" + // en-nl
+ "ZZZ" + // en-nr
+ "ZZZ" + // en-nu
+ "ENZ" + // en-nz
+ "ZZZ" + // en-pg
+ "ENP" + // en-ph
+ "ZZZ" + // en-pk
+ "ZZZ" + // en-pn
+ "ZZZ" + // en-pr
+ "ZZZ" + // en-pw
+ "ZZZ" + // en-rw
+ "ZZZ" + // en-sb
+ "ZZZ" + // en-sc
+ "ZZZ" + // en-sd
+ "ZZZ" + // en-se
+ "ENE" + // en-sg
+ "ZZZ" + // en-sh
+ "ZZZ" + // en-si
+ "ZZZ" + // en-sl
+ "ZZZ" + // en-ss
+ "ZZZ" + // en-sx
+ "ZZZ" + // en-sz
+ "ZZZ" + // en-tc
+ "ZZZ" + // en-tk
+ "ZZZ" + // en-to
+ "ENT" + // en-tt
+ "ZZZ" + // en-tv
+ "ZZZ" + // en-tz
+ "ZZZ" + // en-ug
+ "ZZZ" + // en-um
+ "ENU" + // en-us
+ "ZZZ" + // en-vc
+ "ZZZ" + // en-vg
+ "ZZZ" + // en-vi
+ "ZZZ" + // en-vu
+ "ZZZ" + // en-ws
+ "ENS" + // en-za
+ "ZZZ" + // en-zm
+ "ENW" + // en-zw
+ "ZZZ" + // eo
+ "ZZZ" + // eo-001
+ "ESN" + // es
+ "ESJ" + // es-419
+ "ESS" + // es-ar
+ "ESB" + // es-bo
+ "ZZZ" + // es-br
+ "ESL" + // es-cl
+ "ESO" + // es-co
+ "ESC" + // es-cr
+ "ESK" + // es-cu
+ "ESD" + // es-do
+ "ESF" + // es-ec
+ "ESN" + // es-es
+ "ESP" + // es-es_tradnl
+ "ZZZ" + // es-gq
+ "ESG" + // es-gt
+ "ESH" + // es-hn
+ "ESM" + // es-mx
+ "ESI" + // es-ni
+ "ESA" + // es-pa
+ "ESR" + // es-pe
+ "ZZZ" + // es-ph
+ "ESU" + // es-pr
+ "ESZ" + // es-py
+ "ESE" + // es-sv
+ "EST" + // es-us
+ "ESY" + // es-uy
+ "ESV" + // es-ve
+ "ETI" + // et
+ "ETI" + // et-ee
+ "EUQ" + // eu
+ "EUQ" + // eu-es
+ "ZZZ" + // ewo
+ "ZZZ" + // ewo-cm
+ "FAR" + // fa
+ "FAR" + // fa-ir
+ "FUL" + // ff
+ "ZZZ" + // ff-cm
+ "ZZZ" + // ff-gn
+ "FUL" + // ff-latn
+ "FUL" + // ff-latn-sn
+ "ZZZ" + // ff-mr
+ "ZZZ" + // ff-ng
+ "FIN" + // fi
+ "FIN" + // fi-fi
+ "FPO" + // fil
+ "FPO" + // fil-ph
+ "FOS" + // fo
+ "ZZZ" + // fo-dk
+ "FOS" + // fo-fo
+ "FRA" + // fr
+ "ZZZ" + // fr-029
+ "FRB" + // fr-be
+ "ZZZ" + // fr-bf
+ "ZZZ" + // fr-bi
+ "ZZZ" + // fr-bj
+ "ZZZ" + // fr-bl
+ "FRC" + // fr-ca
+ "FRD" + // fr-cd
+ "ZZZ" + // fr-cf
+ "ZZZ" + // fr-cg
+ "FRS" + // fr-ch
+ "FRI" + // fr-ci
+ "FRE" + // fr-cm
+ "ZZZ" + // fr-dj
+ "ZZZ" + // fr-dz
+ "FRA" + // fr-fr
+ "ZZZ" + // fr-ga
+ "ZZZ" + // fr-gf
+ "ZZZ" + // fr-gn
+ "ZZZ" + // fr-gp
+ "ZZZ" + // fr-gq
+ "FRH" + // fr-ht
+ "ZZZ" + // fr-km
+ "FRL" + // fr-lu
+ "FRO" + // fr-ma
+ "FRM" + // fr-mc
+ "ZZZ" + // fr-mf
+ "ZZZ" + // fr-mg
+ "FRF" + // fr-ml
+ "ZZZ" + // fr-mq
+ "ZZZ" + // fr-mr
+ "ZZZ" + // fr-mu
+ "ZZZ" + // fr-nc
+ "ZZZ" + // fr-ne
+ "ZZZ" + // fr-pf
+ "ZZZ" + // fr-pm
+ "FRR" + // fr-re
+ "ZZZ" + // fr-rw
+ "ZZZ" + // fr-sc
+ "FRN" + // fr-sn
+ "ZZZ" + // fr-sy
+ "ZZZ" + // fr-td
+ "ZZZ" + // fr-tg
+ "ZZZ" + // fr-tn
+ "ZZZ" + // fr-vu
+ "ZZZ" + // fr-wf
+ "ZZZ" + // fr-yt
+ "ZZZ" + // fur
+ "ZZZ" + // fur-it
+ "FYN" + // fy
+ "FYN" + // fy-nl
+ "IRE" + // ga
+ "IRE" + // ga-ie
+ "GLA" + // gd
+ "GLA" + // gd-gb
+ "GLC" + // gl
+ "GLC" + // gl-es
+ "GRN" + // gn
+ "GRN" + // gn-py
+ "ZZZ" + // gsw
+ "ZZZ" + // gsw-ch
+ "GSW" + // gsw-fr
+ "ZZZ" + // gsw-li
+ "GUJ" + // gu
+ "GUJ" + // gu-in
+ "ZZZ" + // guz
+ "ZZZ" + // guz-ke
+ "ZZZ" + // gv
+ "ZZZ" + // gv-im
+ "HAU" + // ha
+ "HAU" + // ha-latn
+ "ZZZ" + // ha-latn-gh
+ "ZZZ" + // ha-latn-ne
+ "HAU" + // ha-latn-ng
+ "HAW" + // haw
+ "HAW" + // haw-us
+ "HEB" + // he
+ "HEB" + // he-il
+ "HIN" + // hi
+ "HIN" + // hi-in
+ "HRV" + // hr
+ "HRB" + // hr-ba
+ "HRV" + // hr-hr
+ "HSB" + // hsb
+ "HSB" + // hsb-de
+ "HUN" + // hu
+ "HUN" + // hu-hu
+ "HUN" + // hu-hu_technl
+ "HYE" + // hy
+ "HYE" + // hy-am
+ "ZZZ" + // ia
+ "ZZZ" + // ia-001
+ "ZZZ" + // ia-fr
+ "ZZZ" + // ibb
+ "ZZZ" + // ibb-ng
+ "IND" + // id
+ "IND" + // id-id
+ "IBO" + // ig
+ "IBO" + // ig-ng
+ "III" + // ii
+ "III" + // ii-cn
+ "ISL" + // is
+ "ISL" + // is-is
+ "ITA" + // it
+ "ITS" + // it-ch
+ "ITA" + // it-it
+ "ZZZ" + // it-sm
+ "IUK" + // iu
+ "IUS" + // iu-cans
+ "IUS" + // iu-cans-ca
+ "IUK" + // iu-latn
+ "IUK" + // iu-latn-ca
+ "JPN" + // ja
+ "JPN" + // ja-jp
+ "JPN" + // ja-jp_radstr
+ "ZZZ" + // jgo
+ "ZZZ" + // jgo-cm
+ "ZZZ" + // jmc
+ "ZZZ" + // jmc-tz
+ "JAV" + // jv
+ "ZZZ" + // jv-java
+ "ZZZ" + // jv-java-id
+ "JAV" + // jv-latn
+ "JAV" + // jv-latn-id
+ "KAT" + // ka
+ "KAT" + // ka-ge
+ "KAT" + // ka-ge_modern
+ "ZZZ" + // kab
+ "ZZZ" + // kab-dz
+ "ZZZ" + // kam
+ "ZZZ" + // kam-ke
+ "ZZZ" + // kde
+ "ZZZ" + // kde-tz
+ "ZZZ" + // kea
+ "ZZZ" + // kea-cv
+ "ZZZ" + // khq
+ "ZZZ" + // khq-ml
+ "ZZZ" + // ki
+ "ZZZ" + // ki-ke
+ "KKZ" + // kk
+ "KKZ" + // kk-kz
+ "ZZZ" + // kkj
+ "ZZZ" + // kkj-cm
+ "KAL" + // kl
+ "KAL" + // kl-gl
+ "ZZZ" + // kln
+ "ZZZ" + // kln-ke
+ "KHM" + // km
+ "KHM" + // km-kh
+ "KDI" + // kn
+ "KDI" + // kn-in
+ "KOR" + // ko
+ "ZZZ" + // ko-kp
+ "KOR" + // ko-kr
+ "KNK" + // kok
+ "KNK" + // kok-in
+ "ZZZ" + // kr
+ "ZZZ" + // kr-ng
+ "ZZZ" + // ks
+ "ZZZ" + // ks-arab
+ "ZZZ" + // ks-arab-in
+ "ZZZ" + // ks-deva
+ "ZZZ" + // ks-deva-in
+ "ZZZ" + // ksb
+ "ZZZ" + // ksb-tz
+ "ZZZ" + // ksf
+ "ZZZ" + // ksf-cm
+ "ZZZ" + // ksh
+ "ZZZ" + // ksh-de
+ "KUR" + // ku
+ "KUR" + // ku-arab
+ "KUR" + // ku-arab-iq
+ "ZZZ" + // ku-arab-ir
+ "ZZZ" + // kw
+ "ZZZ" + // kw-gb
+ "KYR" + // ky
+ "KYR" + // ky-kg
+ "ZZZ" + // la
+ "ZZZ" + // la-001
+ "ZZZ" + // lag
+ "ZZZ" + // lag-tz
+ "LBX" + // lb
+ "LBX" + // lb-lu
+ "ZZZ" + // lg
+ "ZZZ" + // lg-ug
+ "ZZZ" + // lkt
+ "ZZZ" + // lkt-us
+ "ZZZ" + // ln
+ "ZZZ" + // ln-ao
+ "ZZZ" + // ln-cd
+ "ZZZ" + // ln-cf
+ "ZZZ" + // ln-cg
+ "LAO" + // lo
+ "LAO" + // lo-la
+ "ZZZ" + // lrc
+ "ZZZ" + // lrc-iq
+ "ZZZ" + // lrc-ir
+ "LTH" + // lt
+ "LTH" + // lt-lt
+ "ZZZ" + // lu
+ "ZZZ" + // lu-cd
+ "ZZZ" + // luo
+ "ZZZ" + // luo-ke
+ "ZZZ" + // luy
+ "ZZZ" + // luy-ke
+ "LVI" + // lv
+ "LVI" + // lv-lv
+ "ZZZ" + // mas
+ "ZZZ" + // mas-ke
+ "ZZZ" + // mas-tz
+ "ZZZ" + // mer
+ "ZZZ" + // mer-ke
+ "ZZZ" + // mfe
+ "ZZZ" + // mfe-mu
+ "MLG" + // mg
+ "MLG" + // mg-mg
+ "ZZZ" + // mgh
+ "ZZZ" + // mgh-mz
+ "ZZZ" + // mgo
+ "ZZZ" + // mgo-cm
+ "MRI" + // mi
+ "MRI" + // mi-nz
+ "MKI" + // mk
+ "MKI" + // mk-mk
+ "MYM" + // ml
+ "MYM" + // ml-in
+ "MNN" + // mn
+ "MNN" + // mn-cyrl
+ "MNN" + // mn-mn
+ "MNG" + // mn-mong
+ "MNG" + // mn-mong-cn
+ "MNM" + // mn-mong-mn
+ "ZZZ" + // mni
+ "ZZZ" + // mni-in
+ "MWK" + // moh
+ "MWK" + // moh-ca
+ "MAR" + // mr
+ "MAR" + // mr-in
+ "MSL" + // ms
+ "MSB" + // ms-bn
+ "MSL" + // ms-my
+ "ZZZ" + // ms-sg
+ "MLT" + // mt
+ "MLT" + // mt-mt
+ "ZZZ" + // mua
+ "ZZZ" + // mua-cm
+ "MYA" + // my
+ "MYA" + // my-mm
+ "ZZZ" + // mzn
+ "ZZZ" + // mzn-ir
+ "ZZZ" + // naq
+ "ZZZ" + // naq-na
+ "NOR" + // nb
+ "NOR" + // nb-no
+ "ZZZ" + // nb-sj
+ "ZZZ" + // nd
+ "ZZZ" + // nd-zw
+ "ZZZ" + // nds
+ "ZZZ" + // nds-de
+ "ZZZ" + // nds-nl
+ "NEP" + // ne
+ "NEI" + // ne-in
+ "NEP" + // ne-np
+ "NLD" + // nl
+ "ZZZ" + // nl-aw
+ "NLB" + // nl-be
+ "ZZZ" + // nl-bq
+ "ZZZ" + // nl-cw
+ "NLD" + // nl-nl
+ "ZZZ" + // nl-sr
+ "ZZZ" + // nl-sx
+ "ZZZ" + // nmg
+ "ZZZ" + // nmg-cm
+ "NON" + // nn
+ "NON" + // nn-no
+ "ZZZ" + // nnh
+ "ZZZ" + // nnh-cm
+ "NOR" + // no
+ "NQO" + // nqo
+ "NQO" + // nqo-gn
+ "ZZZ" + // nr
+ "ZZZ" + // nr-za
+ "NSO" + // nso
+ "NSO" + // nso-za
+ "ZZZ" + // nus
+ "ZZZ" + // nus-ss
+ "ZZZ" + // nyn
+ "ZZZ" + // nyn-ug
+ "OCI" + // oc
+ "OCI" + // oc-fr
+ "ORM" + // om
+ "ORM" + // om-et
+ "ZZZ" + // om-ke
+ "ORI" + // or
+ "ORI" + // or-in
+ "ZZZ" + // os
+ "ZZZ" + // os-ge
+ "ZZZ" + // os-ru
+ "PAN" + // pa
+ "PAP" + // pa-arab
+ "PAP" + // pa-arab-pk
+ "PAN" + // pa-in
+ "ZZZ" + // pap
+ "ZZZ" + // pap-029
+ "PLK" + // pl
+ "PLK" + // pl-pl
+ "ZZZ" + // prg
+ "ZZZ" + // prg-001
+ "PRS" + // prs
+ "PRS" + // prs-af
+ "PAS" + // ps
+ "PAS" + // ps-af
+ "PTB" + // pt
+ "PTA" + // pt-ao
+ "PTB" + // pt-br
+ "ZZZ" + // pt-ch
+ "ZZZ" + // pt-cv
+ "ZZZ" + // pt-gq
+ "ZZZ" + // pt-gw
+ "ZZZ" + // pt-lu
+ "ZZZ" + // pt-mo
+ "ZZZ" + // pt-mz
+ "PTG" + // pt-pt
+ "ZZZ" + // pt-st
+ "ZZZ" + // pt-tl
+ "ENJ" + // qps-latn-x-sh
+ "ENU" + // qps-ploc
+ "JPN" + // qps-ploca
+ "ARA" + // qps-plocm
+ "QUT" + // quc
+ "QUT" + // quc-latn
+ "QUT" + // quc-latn-gt
+ "QUB" + // quz
+ "QUB" + // quz-bo
+ "QUE" + // quz-ec
+ "QUP" + // quz-pe
+ "RMC" + // rm
+ "RMC" + // rm-ch
+ "ZZZ" + // rn
+ "ZZZ" + // rn-bi
+ "ROM" + // ro
+ "ROD" + // ro-md
+ "ROM" + // ro-ro
+ "ZZZ" + // rof
+ "ZZZ" + // rof-tz
+ "RUS" + // ru
+ "ZZZ" + // ru-by
+ "ZZZ" + // ru-kg
+ "ZZZ" + // ru-kz
+ "RUM" + // ru-md
+ "RUS" + // ru-ru
+ "ZZZ" + // ru-ua
+ "KIN" + // rw
+ "KIN" + // rw-rw
+ "ZZZ" + // rwk
+ "ZZZ" + // rwk-tz
+ "SAN" + // sa
+ "SAN" + // sa-in
+ "SAH" + // sah
+ "SAH" + // sah-ru
+ "ZZZ" + // saq
+ "ZZZ" + // saq-ke
+ "ZZZ" + // sbp
+ "ZZZ" + // sbp-tz
+ "SIP" + // sd
+ "SIP" + // sd-arab
+ "SIP" + // sd-arab-pk
+ "ZZZ" + // sd-deva
+ "ZZZ" + // sd-deva-in
+ "SME" + // se
+ "SMG" + // se-fi
+ "SME" + // se-no
+ "SMF" + // se-se
+ "ZZZ" + // seh
+ "ZZZ" + // seh-mz
+ "ZZZ" + // ses
+ "ZZZ" + // ses-ml
+ "ZZZ" + // sg
+ "ZZZ" + // sg-cf
+ "ZZZ" + // shi
+ "ZZZ" + // shi-latn
+ "ZZZ" + // shi-latn-ma
+ "ZZZ" + // shi-tfng
+ "ZZZ" + // shi-tfng-ma
+ "SIN" + // si
+ "SIN" + // si-lk
+ "SKY" + // sk
+ "SKY" + // sk-sk
+ "SLV" + // sl
+ "SLV" + // sl-si
+ "SMB" + // sma
+ "SMA" + // sma-no
+ "SMB" + // sma-se
+ "SMK" + // smj
+ "SMJ" + // smj-no
+ "SMK" + // smj-se
+ "SMN" + // smn
+ "SMN" + // smn-fi
+ "SMS" + // sms
+ "SMS" + // sms-fi
+ "SNA" + // sn
+ "SNA" + // sn-latn
+ "SNA" + // sn-latn-zw
+ "SOM" + // so
+ "ZZZ" + // so-dj
+ "ZZZ" + // so-et
+ "ZZZ" + // so-ke
+ "SOM" + // so-so
+ "SQI" + // sq
+ "SQI" + // sq-al
+ "ZZZ" + // sq-mk
+ "ZZZ" + // sq-xk
+ "SRM" + // sr
+ "SRO" + // sr-cyrl
+ "SRN" + // sr-cyrl-ba
+ "SRB" + // sr-cyrl-cs
+ "SRQ" + // sr-cyrl-me
+ "SRO" + // sr-cyrl-rs
+ "ZZZ" + // sr-cyrl-xk
+ "SRM" + // sr-latn
+ "SRS" + // sr-latn-ba
+ "SRL" + // sr-latn-cs
+ "SRP" + // sr-latn-me
+ "SRM" + // sr-latn-rs
+ "ZZZ" + // sr-latn-xk
+ "ZZZ" + // ss
+ "ZZZ" + // ss-sz
+ "ZZZ" + // ss-za
+ "ZZZ" + // ssy
+ "ZZZ" + // ssy-er
+ "SOT" + // st
+ "ZZZ" + // st-ls
+ "SOT" + // st-za
+ "SVE" + // sv
+ "ZZZ" + // sv-ax
+ "SVF" + // sv-fi
+ "SVE" + // sv-se
+ "SWK" + // sw
+ "ZZZ" + // sw-cd
+ "SWK" + // sw-ke
+ "ZZZ" + // sw-tz
+ "ZZZ" + // sw-ug
+ "ZZZ" + // swc
+ "ZZZ" + // swc-cd
+ "SYR" + // syr
+ "SYR" + // syr-sy
+ "TAI" + // ta
+ "TAI" + // ta-in
+ "TAM" + // ta-lk
+ "ZZZ" + // ta-my
+ "ZZZ" + // ta-sg
+ "TEL" + // te
+ "TEL" + // te-in
+ "ZZZ" + // teo
+ "ZZZ" + // teo-ke
+ "ZZZ" + // teo-ug
+ "TAJ" + // tg
+ "TAJ" + // tg-cyrl
+ "TAJ" + // tg-cyrl-tj
+ "THA" + // th
+ "THA" + // th-th
+ "TIR" + // ti
+ "TIR" + // ti-er
+ "TIE" + // ti-et
+ "ZZZ" + // tig
+ "ZZZ" + // tig-er
+ "TUK" + // tk
+ "TUK" + // tk-tm
+ "TSN" + // tn
+ "TSB" + // tn-bw
+ "TSN" + // tn-za
+ "ZZZ" + // to
+ "ZZZ" + // to-to
+ "TRK" + // tr
+ "ZZZ" + // tr-cy
+ "TRK" + // tr-tr
+ "TSO" + // ts
+ "TSO" + // ts-za
+ "TTT" + // tt
+ "TTT" + // tt-ru
+ "ZZZ" + // twq
+ "ZZZ" + // twq-ne
+ "TZA" + // tzm
+ "ZZZ" + // tzm-arab
+ "ZZZ" + // tzm-arab-ma
+ "TZA" + // tzm-latn
+ "TZA" + // tzm-latn-dz
+ "ZZZ" + // tzm-latn-ma
+ "TZM" + // tzm-tfng
+ "TZM" + // tzm-tfng-ma
+ "UIG" + // ug
+ "UIG" + // ug-cn
+ "UKR" + // uk
+ "UKR" + // uk-ua
+ "URD" + // ur
+ "URI" + // ur-in
+ "URD" + // ur-pk
+ "UZB" + // uz
+ "ZZZ" + // uz-arab
+ "ZZZ" + // uz-arab-af
+ "UZC" + // uz-cyrl
+ "UZC" + // uz-cyrl-uz
+ "UZB" + // uz-latn
+ "UZB" + // uz-latn-uz
+ "ZZZ" + // vai
+ "ZZZ" + // vai-latn
+ "ZZZ" + // vai-latn-lr
+ "ZZZ" + // vai-vaii
+ "ZZZ" + // vai-vaii-lr
+ "ZZZ" + // ve
+ "ZZZ" + // ve-za
+ "VIT" + // vi
+ "VIT" + // vi-vn
+ "ZZZ" + // vo
+ "ZZZ" + // vo-001
+ "ZZZ" + // vun
+ "ZZZ" + // vun-tz
+ "ZZZ" + // wae
+ "ZZZ" + // wae-ch
+ "ZZZ" + // wal
+ "ZZZ" + // wal-et
+ "WOL" + // wo
+ "WOL" + // wo-sn
+ "IVL" + // x-iv_mathan
+ "XHO" + // xh
+ "XHO" + // xh-za
+ "ZZZ" + // xog
+ "ZZZ" + // xog-ug
+ "ZZZ" + // yav
+ "ZZZ" + // yav-cm
+ "ZZZ" + // yi
+ "ZZZ" + // yi-001
+ "YOR" + // yo
+ "ZZZ" + // yo-bj
+ "YOR" + // yo-ng
+ "ZZZ" + // yue
+ "ZZZ" + // yue-hk
+ "ZHG" + // zgh
+ "ZHG" + // zgh-tfng
+ "ZHG" + // zgh-tfng-ma
+ "CHS" + // zh
+ "CHS" + // zh-chs
+ "CHT" + // zh-cht
+ "CHS" + // zh-cn
+ "CHS" + // zh-cn_phoneb
+ "CHS" + // zh-cn_stroke
+ "CHS" + // zh-hans
+ "ZZZ" + // zh-hans-hk
+ "ZZZ" + // zh-hans-mo
+ "ZHH" + // zh-hant
+ "ZHH" + // zh-hk
+ "ZHH" + // zh-hk_radstr
+ "ZHM" + // zh-mo
+ "ZHM" + // zh-mo_radstr
+ "ZHM" + // zh-mo_stroke
+ "ZHI" + // zh-sg
+ "ZHI" + // zh-sg_phoneb
+ "ZHI" + // zh-sg_stroke
+ "CHT" + // zh-tw
+ "CHT" + // zh-tw_pronun
+ "CHT" + // zh-tw_radstr
+ "ZUL" + // zu
+ "ZUL"; // zu-za
+
+ // s_localeNamesIndices contains the start index of every culture name in the string
+ // s_localeNames. We infer the length of each string by looking at the start index
+ // of the next string.
+ private static readonly int[] s_localeNamesIndices = new int[]
+ {
+ // c_localeNames index, // index to this array - culture name
+ 0 , // 0 - aa
+ 2 , // 1 - aa-dj
+ 7 , // 2 - aa-er
+ 12 , // 3 - aa-et
+ 17 , // 4 - af
+ 19 , // 5 - af-na
+ 24 , // 6 - af-za
+ 29 , // 7 - agq
+ 32 , // 8 - agq-cm
+ 38 , // 9 - ak
+ 40 , // 10 - ak-gh
+ 45 , // 11 - am
+ 47 , // 12 - am-et
+ 52 , // 13 - ar
+ 54 , // 14 - ar-001
+ 60 , // 15 - ar-ae
+ 65 , // 16 - ar-bh
+ 70 , // 17 - ar-dj
+ 75 , // 18 - ar-dz
+ 80 , // 19 - ar-eg
+ 85 , // 20 - ar-er
+ 90 , // 21 - ar-il
+ 95 , // 22 - ar-iq
+ 100 , // 23 - ar-jo
+ 105 , // 24 - ar-km
+ 110 , // 25 - ar-kw
+ 115 , // 26 - ar-lb
+ 120 , // 27 - ar-ly
+ 125 , // 28 - ar-ma
+ 130 , // 29 - ar-mr
+ 135 , // 30 - ar-om
+ 140 , // 31 - ar-ps
+ 145 , // 32 - ar-qa
+ 150 , // 33 - ar-sa
+ 155 , // 34 - ar-sd
+ 160 , // 35 - ar-so
+ 165 , // 36 - ar-ss
+ 170 , // 37 - ar-sy
+ 175 , // 38 - ar-td
+ 180 , // 39 - ar-tn
+ 185 , // 40 - ar-ye
+ 190 , // 41 - arn
+ 193 , // 42 - arn-cl
+ 199 , // 43 - as
+ 201 , // 44 - as-in
+ 206 , // 45 - asa
+ 209 , // 46 - asa-tz
+ 215 , // 47 - ast
+ 218 , // 48 - ast-es
+ 224 , // 49 - az
+ 226 , // 50 - az-cyrl
+ 233 , // 51 - az-cyrl-az
+ 243 , // 52 - az-latn
+ 250 , // 53 - az-latn-az
+ 260 , // 54 - ba
+ 262 , // 55 - ba-ru
+ 267 , // 56 - bas
+ 270 , // 57 - bas-cm
+ 276 , // 58 - be
+ 278 , // 59 - be-by
+ 283 , // 60 - bem
+ 286 , // 61 - bem-zm
+ 292 , // 62 - bez
+ 295 , // 63 - bez-tz
+ 301 , // 64 - bg
+ 303 , // 65 - bg-bg
+ 308 , // 66 - bin
+ 311 , // 67 - bin-ng
+ 317 , // 68 - bm
+ 319 , // 69 - bm-latn
+ 326 , // 70 - bm-latn-ml
+ 336 , // 71 - bn
+ 338 , // 72 - bn-bd
+ 343 , // 73 - bn-in
+ 348 , // 74 - bo
+ 350 , // 75 - bo-cn
+ 355 , // 76 - bo-in
+ 360 , // 77 - br
+ 362 , // 78 - br-fr
+ 367 , // 79 - brx
+ 370 , // 80 - brx-in
+ 376 , // 81 - bs
+ 378 , // 82 - bs-cyrl
+ 385 , // 83 - bs-cyrl-ba
+ 395 , // 84 - bs-latn
+ 402 , // 85 - bs-latn-ba
+ 412 , // 86 - byn
+ 415 , // 87 - byn-er
+ 421 , // 88 - ca
+ 423 , // 89 - ca-ad
+ 428 , // 90 - ca-es
+ 433 , // 91 - ca-es-valencia
+ 447 , // 92 - ca-fr
+ 452 , // 93 - ca-it
+ 457 , // 94 - ce
+ 459 , // 95 - ce-ru
+ 464 , // 96 - cgg
+ 467 , // 97 - cgg-ug
+ 473 , // 98 - chr
+ 476 , // 99 - chr-cher
+ 484 , // 100 - chr-cher-us
+ 495 , // 101 - co
+ 497 , // 102 - co-fr
+ 502 , // 103 - cs
+ 504 , // 104 - cs-cz
+ 509 , // 105 - cu
+ 511 , // 106 - cu-ru
+ 516 , // 107 - cy
+ 518 , // 108 - cy-gb
+ 523 , // 109 - da
+ 525 , // 110 - da-dk
+ 530 , // 111 - da-gl
+ 535 , // 112 - dav
+ 538 , // 113 - dav-ke
+ 544 , // 114 - de
+ 546 , // 115 - de-at
+ 551 , // 116 - de-be
+ 556 , // 117 - de-ch
+ 561 , // 118 - de-de
+ 566 , // 119 - de-de_phoneb
+ 578 , // 120 - de-it
+ 583 , // 121 - de-li
+ 588 , // 122 - de-lu
+ 593 , // 123 - dje
+ 596 , // 124 - dje-ne
+ 602 , // 125 - dsb
+ 605 , // 126 - dsb-de
+ 611 , // 127 - dua
+ 614 , // 128 - dua-cm
+ 620 , // 129 - dv
+ 622 , // 130 - dv-mv
+ 627 , // 131 - dyo
+ 630 , // 132 - dyo-sn
+ 636 , // 133 - dz
+ 638 , // 134 - dz-bt
+ 643 , // 135 - ebu
+ 646 , // 136 - ebu-ke
+ 652 , // 137 - ee
+ 654 , // 138 - ee-gh
+ 659 , // 139 - ee-tg
+ 664 , // 140 - el
+ 666 , // 141 - el-cy
+ 671 , // 142 - el-gr
+ 676 , // 143 - en
+ 678 , // 144 - en-001
+ 684 , // 145 - en-029
+ 690 , // 146 - en-150
+ 696 , // 147 - en-ag
+ 701 , // 148 - en-ai
+ 706 , // 149 - en-as
+ 711 , // 150 - en-at
+ 716 , // 151 - en-au
+ 721 , // 152 - en-bb
+ 726 , // 153 - en-be
+ 731 , // 154 - en-bi
+ 736 , // 155 - en-bm
+ 741 , // 156 - en-bs
+ 746 , // 157 - en-bw
+ 751 , // 158 - en-bz
+ 756 , // 159 - en-ca
+ 761 , // 160 - en-cc
+ 766 , // 161 - en-ch
+ 771 , // 162 - en-ck
+ 776 , // 163 - en-cm
+ 781 , // 164 - en-cx
+ 786 , // 165 - en-cy
+ 791 , // 166 - en-de
+ 796 , // 167 - en-dk
+ 801 , // 168 - en-dm
+ 806 , // 169 - en-er
+ 811 , // 170 - en-fi
+ 816 , // 171 - en-fj
+ 821 , // 172 - en-fk
+ 826 , // 173 - en-fm
+ 831 , // 174 - en-gb
+ 836 , // 175 - en-gd
+ 841 , // 176 - en-gg
+ 846 , // 177 - en-gh
+ 851 , // 178 - en-gi
+ 856 , // 179 - en-gm
+ 861 , // 180 - en-gu
+ 866 , // 181 - en-gy
+ 871 , // 182 - en-hk
+ 876 , // 183 - en-id
+ 881 , // 184 - en-ie
+ 886 , // 185 - en-il
+ 891 , // 186 - en-im
+ 896 , // 187 - en-in
+ 901 , // 188 - en-io
+ 906 , // 189 - en-je
+ 911 , // 190 - en-jm
+ 916 , // 191 - en-ke
+ 921 , // 192 - en-ki
+ 926 , // 193 - en-kn
+ 931 , // 194 - en-ky
+ 936 , // 195 - en-lc
+ 941 , // 196 - en-lr
+ 946 , // 197 - en-ls
+ 951 , // 198 - en-mg
+ 956 , // 199 - en-mh
+ 961 , // 200 - en-mo
+ 966 , // 201 - en-mp
+ 971 , // 202 - en-ms
+ 976 , // 203 - en-mt
+ 981 , // 204 - en-mu
+ 986 , // 205 - en-mw
+ 991 , // 206 - en-my
+ 996 , // 207 - en-na
+ 1001, // 208 - en-nf
+ 1006, // 209 - en-ng
+ 1011, // 210 - en-nl
+ 1016, // 211 - en-nr
+ 1021, // 212 - en-nu
+ 1026, // 213 - en-nz
+ 1031, // 214 - en-pg
+ 1036, // 215 - en-ph
+ 1041, // 216 - en-pk
+ 1046, // 217 - en-pn
+ 1051, // 218 - en-pr
+ 1056, // 219 - en-pw
+ 1061, // 220 - en-rw
+ 1066, // 221 - en-sb
+ 1071, // 222 - en-sc
+ 1076, // 223 - en-sd
+ 1081, // 224 - en-se
+ 1086, // 225 - en-sg
+ 1091, // 226 - en-sh
+ 1096, // 227 - en-si
+ 1101, // 228 - en-sl
+ 1106, // 229 - en-ss
+ 1111, // 230 - en-sx
+ 1116, // 231 - en-sz
+ 1121, // 232 - en-tc
+ 1126, // 233 - en-tk
+ 1131, // 234 - en-to
+ 1136, // 235 - en-tt
+ 1141, // 236 - en-tv
+ 1146, // 237 - en-tz
+ 1151, // 238 - en-ug
+ 1156, // 239 - en-um
+ 1161, // 240 - en-us
+ 1166, // 241 - en-vc
+ 1171, // 242 - en-vg
+ 1176, // 243 - en-vi
+ 1181, // 244 - en-vu
+ 1186, // 245 - en-ws
+ 1191, // 246 - en-za
+ 1196, // 247 - en-zm
+ 1201, // 248 - en-zw
+ 1206, // 249 - eo
+ 1208, // 250 - eo-001
+ 1214, // 251 - es
+ 1216, // 252 - es-419
+ 1222, // 253 - es-ar
+ 1227, // 254 - es-bo
+ 1232, // 255 - es-br
+ 1237, // 256 - es-cl
+ 1242, // 257 - es-co
+ 1247, // 258 - es-cr
+ 1252, // 259 - es-cu
+ 1257, // 260 - es-do
+ 1262, // 261 - es-ec
+ 1267, // 262 - es-es
+ 1272, // 263 - es-es_tradnl
+ 1284, // 264 - es-gq
+ 1289, // 265 - es-gt
+ 1294, // 266 - es-hn
+ 1299, // 267 - es-mx
+ 1304, // 268 - es-ni
+ 1309, // 269 - es-pa
+ 1314, // 270 - es-pe
+ 1319, // 271 - es-ph
+ 1324, // 272 - es-pr
+ 1329, // 273 - es-py
+ 1334, // 274 - es-sv
+ 1339, // 275 - es-us
+ 1344, // 276 - es-uy
+ 1349, // 277 - es-ve
+ 1354, // 278 - et
+ 1356, // 279 - et-ee
+ 1361, // 280 - eu
+ 1363, // 281 - eu-es
+ 1368, // 282 - ewo
+ 1371, // 283 - ewo-cm
+ 1377, // 284 - fa
+ 1379, // 285 - fa-ir
+ 1384, // 286 - ff
+ 1386, // 287 - ff-cm
+ 1391, // 288 - ff-gn
+ 1396, // 289 - ff-latn
+ 1403, // 290 - ff-latn-sn
+ 1413, // 291 - ff-mr
+ 1418, // 292 - ff-ng
+ 1423, // 293 - fi
+ 1425, // 294 - fi-fi
+ 1430, // 295 - fil
+ 1433, // 296 - fil-ph
+ 1439, // 297 - fo
+ 1441, // 298 - fo-dk
+ 1446, // 299 - fo-fo
+ 1451, // 300 - fr
+ 1453, // 301 - fr-029
+ 1459, // 302 - fr-be
+ 1464, // 303 - fr-bf
+ 1469, // 304 - fr-bi
+ 1474, // 305 - fr-bj
+ 1479, // 306 - fr-bl
+ 1484, // 307 - fr-ca
+ 1489, // 308 - fr-cd
+ 1494, // 309 - fr-cf
+ 1499, // 310 - fr-cg
+ 1504, // 311 - fr-ch
+ 1509, // 312 - fr-ci
+ 1514, // 313 - fr-cm
+ 1519, // 314 - fr-dj
+ 1524, // 315 - fr-dz
+ 1529, // 316 - fr-fr
+ 1534, // 317 - fr-ga
+ 1539, // 318 - fr-gf
+ 1544, // 319 - fr-gn
+ 1549, // 320 - fr-gp
+ 1554, // 321 - fr-gq
+ 1559, // 322 - fr-ht
+ 1564, // 323 - fr-km
+ 1569, // 324 - fr-lu
+ 1574, // 325 - fr-ma
+ 1579, // 326 - fr-mc
+ 1584, // 327 - fr-mf
+ 1589, // 328 - fr-mg
+ 1594, // 329 - fr-ml
+ 1599, // 330 - fr-mq
+ 1604, // 331 - fr-mr
+ 1609, // 332 - fr-mu
+ 1614, // 333 - fr-nc
+ 1619, // 334 - fr-ne
+ 1624, // 335 - fr-pf
+ 1629, // 336 - fr-pm
+ 1634, // 337 - fr-re
+ 1639, // 338 - fr-rw
+ 1644, // 339 - fr-sc
+ 1649, // 340 - fr-sn
+ 1654, // 341 - fr-sy
+ 1659, // 342 - fr-td
+ 1664, // 343 - fr-tg
+ 1669, // 344 - fr-tn
+ 1674, // 345 - fr-vu
+ 1679, // 346 - fr-wf
+ 1684, // 347 - fr-yt
+ 1689, // 348 - fur
+ 1692, // 349 - fur-it
+ 1698, // 350 - fy
+ 1700, // 351 - fy-nl
+ 1705, // 352 - ga
+ 1707, // 353 - ga-ie
+ 1712, // 354 - gd
+ 1714, // 355 - gd-gb
+ 1719, // 356 - gl
+ 1721, // 357 - gl-es
+ 1726, // 358 - gn
+ 1728, // 359 - gn-py
+ 1733, // 360 - gsw
+ 1736, // 361 - gsw-ch
+ 1742, // 362 - gsw-fr
+ 1748, // 363 - gsw-li
+ 1754, // 364 - gu
+ 1756, // 365 - gu-in
+ 1761, // 366 - guz
+ 1764, // 367 - guz-ke
+ 1770, // 368 - gv
+ 1772, // 369 - gv-im
+ 1777, // 370 - ha
+ 1779, // 371 - ha-latn
+ 1786, // 372 - ha-latn-gh
+ 1796, // 373 - ha-latn-ne
+ 1806, // 374 - ha-latn-ng
+ 1816, // 375 - haw
+ 1819, // 376 - haw-us
+ 1825, // 377 - he
+ 1827, // 378 - he-il
+ 1832, // 379 - hi
+ 1834, // 380 - hi-in
+ 1839, // 381 - hr
+ 1841, // 382 - hr-ba
+ 1846, // 383 - hr-hr
+ 1851, // 384 - hsb
+ 1854, // 385 - hsb-de
+ 1860, // 386 - hu
+ 1862, // 387 - hu-hu
+ 1867, // 388 - hu-hu_technl
+ 1879, // 389 - hy
+ 1881, // 390 - hy-am
+ 1886, // 391 - ia
+ 1888, // 392 - ia-001
+ 1894, // 393 - ia-fr
+ 1899, // 394 - ibb
+ 1902, // 395 - ibb-ng
+ 1908, // 396 - id
+ 1910, // 397 - id-id
+ 1915, // 398 - ig
+ 1917, // 399 - ig-ng
+ 1922, // 400 - ii
+ 1924, // 401 - ii-cn
+ 1929, // 402 - is
+ 1931, // 403 - is-is
+ 1936, // 404 - it
+ 1938, // 405 - it-ch
+ 1943, // 406 - it-it
+ 1948, // 407 - it-sm
+ 1953, // 408 - iu
+ 1955, // 409 - iu-cans
+ 1962, // 410 - iu-cans-ca
+ 1972, // 411 - iu-latn
+ 1979, // 412 - iu-latn-ca
+ 1989, // 413 - ja
+ 1991, // 414 - ja-jp
+ 1996, // 415 - ja-jp_radstr
+ 2008, // 416 - jgo
+ 2011, // 417 - jgo-cm
+ 2017, // 418 - jmc
+ 2020, // 419 - jmc-tz
+ 2026, // 420 - jv
+ 2028, // 421 - jv-java
+ 2035, // 422 - jv-java-id
+ 2045, // 423 - jv-latn
+ 2052, // 424 - jv-latn-id
+ 2062, // 425 - ka
+ 2064, // 426 - ka-ge
+ 2069, // 427 - ka-ge_modern
+ 2081, // 428 - kab
+ 2084, // 429 - kab-dz
+ 2090, // 430 - kam
+ 2093, // 431 - kam-ke
+ 2099, // 432 - kde
+ 2102, // 433 - kde-tz
+ 2108, // 434 - kea
+ 2111, // 435 - kea-cv
+ 2117, // 436 - khq
+ 2120, // 437 - khq-ml
+ 2126, // 438 - ki
+ 2128, // 439 - ki-ke
+ 2133, // 440 - kk
+ 2135, // 441 - kk-kz
+ 2140, // 442 - kkj
+ 2143, // 443 - kkj-cm
+ 2149, // 444 - kl
+ 2151, // 445 - kl-gl
+ 2156, // 446 - kln
+ 2159, // 447 - kln-ke
+ 2165, // 448 - km
+ 2167, // 449 - km-kh
+ 2172, // 450 - kn
+ 2174, // 451 - kn-in
+ 2179, // 452 - ko
+ 2181, // 453 - ko-kp
+ 2186, // 454 - ko-kr
+ 2191, // 455 - kok
+ 2194, // 456 - kok-in
+ 2200, // 457 - kr
+ 2202, // 458 - kr-ng
+ 2207, // 459 - ks
+ 2209, // 460 - ks-arab
+ 2216, // 461 - ks-arab-in
+ 2226, // 462 - ks-deva
+ 2233, // 463 - ks-deva-in
+ 2243, // 464 - ksb
+ 2246, // 465 - ksb-tz
+ 2252, // 466 - ksf
+ 2255, // 467 - ksf-cm
+ 2261, // 468 - ksh
+ 2264, // 469 - ksh-de
+ 2270, // 470 - ku
+ 2272, // 471 - ku-arab
+ 2279, // 472 - ku-arab-iq
+ 2289, // 473 - ku-arab-ir
+ 2299, // 474 - kw
+ 2301, // 475 - kw-gb
+ 2306, // 476 - ky
+ 2308, // 477 - ky-kg
+ 2313, // 478 - la
+ 2315, // 479 - la-001
+ 2321, // 480 - lag
+ 2324, // 481 - lag-tz
+ 2330, // 482 - lb
+ 2332, // 483 - lb-lu
+ 2337, // 484 - lg
+ 2339, // 485 - lg-ug
+ 2344, // 486 - lkt
+ 2347, // 487 - lkt-us
+ 2353, // 488 - ln
+ 2355, // 489 - ln-ao
+ 2360, // 490 - ln-cd
+ 2365, // 491 - ln-cf
+ 2370, // 492 - ln-cg
+ 2375, // 493 - lo
+ 2377, // 494 - lo-la
+ 2382, // 495 - lrc
+ 2385, // 496 - lrc-iq
+ 2391, // 497 - lrc-ir
+ 2397, // 498 - lt
+ 2399, // 499 - lt-lt
+ 2404, // 500 - lu
+ 2406, // 501 - lu-cd
+ 2411, // 502 - luo
+ 2414, // 503 - luo-ke
+ 2420, // 504 - luy
+ 2423, // 505 - luy-ke
+ 2429, // 506 - lv
+ 2431, // 507 - lv-lv
+ 2436, // 508 - mas
+ 2439, // 509 - mas-ke
+ 2445, // 510 - mas-tz
+ 2451, // 511 - mer
+ 2454, // 512 - mer-ke
+ 2460, // 513 - mfe
+ 2463, // 514 - mfe-mu
+ 2469, // 515 - mg
+ 2471, // 516 - mg-mg
+ 2476, // 517 - mgh
+ 2479, // 518 - mgh-mz
+ 2485, // 519 - mgo
+ 2488, // 520 - mgo-cm
+ 2494, // 521 - mi
+ 2496, // 522 - mi-nz
+ 2501, // 523 - mk
+ 2503, // 524 - mk-mk
+ 2508, // 525 - ml
+ 2510, // 526 - ml-in
+ 2515, // 527 - mn
+ 2517, // 528 - mn-cyrl
+ 2524, // 529 - mn-mn
+ 2529, // 530 - mn-mong
+ 2536, // 531 - mn-mong-cn
+ 2546, // 532 - mn-mong-mn
+ 2556, // 533 - mni
+ 2559, // 534 - mni-in
+ 2565, // 535 - moh
+ 2568, // 536 - moh-ca
+ 2574, // 537 - mr
+ 2576, // 538 - mr-in
+ 2581, // 539 - ms
+ 2583, // 540 - ms-bn
+ 2588, // 541 - ms-my
+ 2593, // 542 - ms-sg
+ 2598, // 543 - mt
+ 2600, // 544 - mt-mt
+ 2605, // 545 - mua
+ 2608, // 546 - mua-cm
+ 2614, // 547 - my
+ 2616, // 548 - my-mm
+ 2621, // 549 - mzn
+ 2624, // 550 - mzn-ir
+ 2630, // 551 - naq
+ 2633, // 552 - naq-na
+ 2639, // 553 - nb
+ 2641, // 554 - nb-no
+ 2646, // 555 - nb-sj
+ 2651, // 556 - nd
+ 2653, // 557 - nd-zw
+ 2658, // 558 - nds
+ 2661, // 559 - nds-de
+ 2667, // 560 - nds-nl
+ 2673, // 561 - ne
+ 2675, // 562 - ne-in
+ 2680, // 563 - ne-np
+ 2685, // 564 - nl
+ 2687, // 565 - nl-aw
+ 2692, // 566 - nl-be
+ 2697, // 567 - nl-bq
+ 2702, // 568 - nl-cw
+ 2707, // 569 - nl-nl
+ 2712, // 570 - nl-sr
+ 2717, // 571 - nl-sx
+ 2722, // 572 - nmg
+ 2725, // 573 - nmg-cm
+ 2731, // 574 - nn
+ 2733, // 575 - nn-no
+ 2738, // 576 - nnh
+ 2741, // 577 - nnh-cm
+ 2747, // 578 - no
+ 2749, // 579 - nqo
+ 2752, // 580 - nqo-gn
+ 2758, // 581 - nr
+ 2760, // 582 - nr-za
+ 2765, // 583 - nso
+ 2768, // 584 - nso-za
+ 2774, // 585 - nus
+ 2777, // 586 - nus-ss
+ 2783, // 587 - nyn
+ 2786, // 588 - nyn-ug
+ 2792, // 589 - oc
+ 2794, // 590 - oc-fr
+ 2799, // 591 - om
+ 2801, // 592 - om-et
+ 2806, // 593 - om-ke
+ 2811, // 594 - or
+ 2813, // 595 - or-in
+ 2818, // 596 - os
+ 2820, // 597 - os-ge
+ 2825, // 598 - os-ru
+ 2830, // 599 - pa
+ 2832, // 600 - pa-arab
+ 2839, // 601 - pa-arab-pk
+ 2849, // 602 - pa-in
+ 2854, // 603 - pap
+ 2857, // 604 - pap-029
+ 2864, // 605 - pl
+ 2866, // 606 - pl-pl
+ 2871, // 607 - prg
+ 2874, // 608 - prg-001
+ 2881, // 609 - prs
+ 2884, // 610 - prs-af
+ 2890, // 611 - ps
+ 2892, // 612 - ps-af
+ 2897, // 613 - pt
+ 2899, // 614 - pt-ao
+ 2904, // 615 - pt-br
+ 2909, // 616 - pt-ch
+ 2914, // 617 - pt-cv
+ 2919, // 618 - pt-gq
+ 2924, // 619 - pt-gw
+ 2929, // 620 - pt-lu
+ 2934, // 621 - pt-mo
+ 2939, // 622 - pt-mz
+ 2944, // 623 - pt-pt
+ 2949, // 624 - pt-st
+ 2954, // 625 - pt-tl
+ 2959, // 626 - qps-latn-x-sh
+ 2972, // 627 - qps-ploc
+ 2980, // 628 - qps-ploca
+ 2989, // 629 - qps-plocm
+ 2998, // 630 - quc
+ 3001, // 631 - quc-latn
+ 3009, // 632 - quc-latn-gt
+ 3020, // 633 - quz
+ 3023, // 634 - quz-bo
+ 3029, // 635 - quz-ec
+ 3035, // 636 - quz-pe
+ 3041, // 637 - rm
+ 3043, // 638 - rm-ch
+ 3048, // 639 - rn
+ 3050, // 640 - rn-bi
+ 3055, // 641 - ro
+ 3057, // 642 - ro-md
+ 3062, // 643 - ro-ro
+ 3067, // 644 - rof
+ 3070, // 645 - rof-tz
+ 3076, // 646 - ru
+ 3078, // 647 - ru-by
+ 3083, // 648 - ru-kg
+ 3088, // 649 - ru-kz
+ 3093, // 650 - ru-md
+ 3098, // 651 - ru-ru
+ 3103, // 652 - ru-ua
+ 3108, // 653 - rw
+ 3110, // 654 - rw-rw
+ 3115, // 655 - rwk
+ 3118, // 656 - rwk-tz
+ 3124, // 657 - sa
+ 3126, // 658 - sa-in
+ 3131, // 659 - sah
+ 3134, // 660 - sah-ru
+ 3140, // 661 - saq
+ 3143, // 662 - saq-ke
+ 3149, // 663 - sbp
+ 3152, // 664 - sbp-tz
+ 3158, // 665 - sd
+ 3160, // 666 - sd-arab
+ 3167, // 667 - sd-arab-pk
+ 3177, // 668 - sd-deva
+ 3184, // 669 - sd-deva-in
+ 3194, // 670 - se
+ 3196, // 671 - se-fi
+ 3201, // 672 - se-no
+ 3206, // 673 - se-se
+ 3211, // 674 - seh
+ 3214, // 675 - seh-mz
+ 3220, // 676 - ses
+ 3223, // 677 - ses-ml
+ 3229, // 678 - sg
+ 3231, // 679 - sg-cf
+ 3236, // 680 - shi
+ 3239, // 681 - shi-latn
+ 3247, // 682 - shi-latn-ma
+ 3258, // 683 - shi-tfng
+ 3266, // 684 - shi-tfng-ma
+ 3277, // 685 - si
+ 3279, // 686 - si-lk
+ 3284, // 687 - sk
+ 3286, // 688 - sk-sk
+ 3291, // 689 - sl
+ 3293, // 690 - sl-si
+ 3298, // 691 - sma
+ 3301, // 692 - sma-no
+ 3307, // 693 - sma-se
+ 3313, // 694 - smj
+ 3316, // 695 - smj-no
+ 3322, // 696 - smj-se
+ 3328, // 697 - smn
+ 3331, // 698 - smn-fi
+ 3337, // 699 - sms
+ 3340, // 700 - sms-fi
+ 3346, // 701 - sn
+ 3348, // 702 - sn-latn
+ 3355, // 703 - sn-latn-zw
+ 3365, // 704 - so
+ 3367, // 705 - so-dj
+ 3372, // 706 - so-et
+ 3377, // 707 - so-ke
+ 3382, // 708 - so-so
+ 3387, // 709 - sq
+ 3389, // 710 - sq-al
+ 3394, // 711 - sq-mk
+ 3399, // 712 - sq-xk
+ 3404, // 713 - sr
+ 3406, // 714 - sr-cyrl
+ 3413, // 715 - sr-cyrl-ba
+ 3423, // 716 - sr-cyrl-cs
+ 3433, // 717 - sr-cyrl-me
+ 3443, // 718 - sr-cyrl-rs
+ 3453, // 719 - sr-cyrl-xk
+ 3463, // 720 - sr-latn
+ 3470, // 721 - sr-latn-ba
+ 3480, // 722 - sr-latn-cs
+ 3490, // 723 - sr-latn-me
+ 3500, // 724 - sr-latn-rs
+ 3510, // 725 - sr-latn-xk
+ 3520, // 726 - ss
+ 3522, // 727 - ss-sz
+ 3527, // 728 - ss-za
+ 3532, // 729 - ssy
+ 3535, // 730 - ssy-er
+ 3541, // 731 - st
+ 3543, // 732 - st-ls
+ 3548, // 733 - st-za
+ 3553, // 734 - sv
+ 3555, // 735 - sv-ax
+ 3560, // 736 - sv-fi
+ 3565, // 737 - sv-se
+ 3570, // 738 - sw
+ 3572, // 739 - sw-cd
+ 3577, // 740 - sw-ke
+ 3582, // 741 - sw-tz
+ 3587, // 742 - sw-ug
+ 3592, // 743 - swc
+ 3595, // 744 - swc-cd
+ 3601, // 745 - syr
+ 3604, // 746 - syr-sy
+ 3610, // 747 - ta
+ 3612, // 748 - ta-in
+ 3617, // 749 - ta-lk
+ 3622, // 750 - ta-my
+ 3627, // 751 - ta-sg
+ 3632, // 752 - te
+ 3634, // 753 - te-in
+ 3639, // 754 - teo
+ 3642, // 755 - teo-ke
+ 3648, // 756 - teo-ug
+ 3654, // 757 - tg
+ 3656, // 758 - tg-cyrl
+ 3663, // 759 - tg-cyrl-tj
+ 3673, // 760 - th
+ 3675, // 761 - th-th
+ 3680, // 762 - ti
+ 3682, // 763 - ti-er
+ 3687, // 764 - ti-et
+ 3692, // 765 - tig
+ 3695, // 766 - tig-er
+ 3701, // 767 - tk
+ 3703, // 768 - tk-tm
+ 3708, // 769 - tn
+ 3710, // 770 - tn-bw
+ 3715, // 771 - tn-za
+ 3720, // 772 - to
+ 3722, // 773 - to-to
+ 3727, // 774 - tr
+ 3729, // 775 - tr-cy
+ 3734, // 776 - tr-tr
+ 3739, // 777 - ts
+ 3741, // 778 - ts-za
+ 3746, // 779 - tt
+ 3748, // 780 - tt-ru
+ 3753, // 781 - twq
+ 3756, // 782 - twq-ne
+ 3762, // 783 - tzm
+ 3765, // 784 - tzm-arab
+ 3773, // 785 - tzm-arab-ma
+ 3784, // 786 - tzm-latn
+ 3792, // 787 - tzm-latn-dz
+ 3803, // 788 - tzm-latn-ma
+ 3814, // 789 - tzm-tfng
+ 3822, // 790 - tzm-tfng-ma
+ 3833, // 791 - ug
+ 3835, // 792 - ug-cn
+ 3840, // 793 - uk
+ 3842, // 794 - uk-ua
+ 3847, // 795 - ur
+ 3849, // 796 - ur-in
+ 3854, // 797 - ur-pk
+ 3859, // 798 - uz
+ 3861, // 799 - uz-arab
+ 3868, // 800 - uz-arab-af
+ 3878, // 801 - uz-cyrl
+ 3885, // 802 - uz-cyrl-uz
+ 3895, // 803 - uz-latn
+ 3902, // 804 - uz-latn-uz
+ 3912, // 805 - vai
+ 3915, // 806 - vai-latn
+ 3923, // 807 - vai-latn-lr
+ 3934, // 808 - vai-vaii
+ 3942, // 809 - vai-vaii-lr
+ 3953, // 810 - ve
+ 3955, // 811 - ve-za
+ 3960, // 812 - vi
+ 3962, // 813 - vi-vn
+ 3967, // 814 - vo
+ 3969, // 815 - vo-001
+ 3975, // 816 - vun
+ 3978, // 817 - vun-tz
+ 3984, // 818 - wae
+ 3987, // 819 - wae-ch
+ 3993, // 820 - wal
+ 3996, // 821 - wal-et
+ 4002, // 822 - wo
+ 4004, // 823 - wo-sn
+ 4009, // 824 - x-iv_mathan
+ 4020, // 825 - xh
+ 4022, // 826 - xh-za
+ 4027, // 827 - xog
+ 4030, // 828 - xog-ug
+ 4036, // 829 - yav
+ 4039, // 830 - yav-cm
+ 4045, // 831 - yi
+ 4047, // 832 - yi-001
+ 4053, // 833 - yo
+ 4055, // 834 - yo-bj
+ 4060, // 835 - yo-ng
+ 4065, // 836 - yue
+ 4068, // 837 - yue-hk
+ 4074, // 838 - zgh
+ 4077, // 839 - zgh-tfng
+ 4085, // 840 - zgh-tfng-ma
+ 4096, // 841 - zh
+ 4098, // 842 - zh-chs
+ 4104, // 843 - zh-cht
+ 4110, // 844 - zh-cn
+ 4115, // 845 - zh-cn_phoneb
+ 4127, // 846 - zh-cn_stroke
+ 4139, // 847 - zh-hans
+ 4146, // 848 - zh-hans-hk
+ 4156, // 849 - zh-hans-mo
+ 4166, // 850 - zh-hant
+ 4173, // 851 - zh-hk
+ 4178, // 852 - zh-hk_radstr
+ 4190, // 853 - zh-mo
+ 4195, // 854 - zh-mo_radstr
+ 4207, // 855 - zh-mo_stroke
+ 4219, // 856 - zh-sg
+ 4224, // 857 - zh-sg_phoneb
+ 4236, // 858 - zh-sg_stroke
+ 4248, // 859 - zh-tw
+ 4253, // 860 - zh-tw_pronun
+ 4265, // 861 - zh-tw_radstr
+ 4277, // 862 - zu
+ 4279, // 863 - zu-za
+ 4284
+ };
+
+ private const int NUMERIC_LOCALE_DATA_COUNT_PER_ROW = 9;
+ // s_nameIndexToNumericData is mapping from index in s_localeNamesIndices to locale data.
+ // each row in the table will have the following data:
+ // Lcid, Ansi codepage, Oem codepage, MAC codepage, EBCDIC codepage, Geo Id, Digit Substitution, specific locale index, Console locale index
+ private static readonly int[] s_nameIndexToNumericData = new int[]
+ {
+ // Lcid, Ansi CP, Oem CP, MAC CP, EBCDIC CP, Geo Id, digit substitution, Specific culture index, keyboard Id, Console locale index // index - locale name
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x49 , 1 , 3 , 240 , // 0 - aa
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x3e , 1 , 1 , 240 , // 1 - aa-dj
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x47 , 1 , 2 , 240 , // 2 - aa-er
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x49 , 1 , 3 , 240 , // 3 - aa-et
+ 0x36 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xd1 , 1 , 6 , 6 , // 4 - af
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xfe , 1 , 5 , 240 , // 5 - af-na
+ 0x436 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xd1 , 1 , 6 , 6 , // 6 - af-za
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x31 , 1 , 8 , 240 , // 7 - agq
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x31 , 1 , 8 , 240 , // 8 - agq-cm
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x59 , 1 , 10 , 240 , // 9 - ak
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x59 , 1 , 10 , 240 , // 10 - ak-gh
+ 0x5e , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x49 , 1 , 12 , 143 , // 11 - am
+ 0x45e , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x49 , 1 , 12 , 143 , // 12 - am-et
+ 0x1 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0xcd , 0 , 33 , 143 , // 13 - ar
+ 0x1000 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x989e, 0 , 14 , 240 , // 14 - ar-001
+ 0x3801 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0xe0 , 0 , 15 , 143 , // 15 - ar-ae
+ 0x3c01 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x11 , 0 , 16 , 143 , // 16 - ar-bh
+ 0x1000 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x3e , 0 , 17 , 240 , // 17 - ar-dj
+ 0x1401 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x4 , 1 , 18 , 300 , // 18 - ar-dz
+ 0xc01 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x43 , 0 , 19 , 143 , // 19 - ar-eg
+ 0x1000 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x47 , 0 , 20 , 240 , // 20 - ar-er
+ 0x1000 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x75 , 0 , 21 , 240 , // 21 - ar-il
+ 0x801 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x79 , 0 , 22 , 143 , // 22 - ar-iq
+ 0x2c01 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x7e , 0 , 23 , 143 , // 23 - ar-jo
+ 0x1000 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x32 , 0 , 24 , 240 , // 24 - ar-km
+ 0x3401 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x88 , 0 , 25 , 143 , // 25 - ar-kw
+ 0x3001 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x8b , 0 , 26 , 143 , // 26 - ar-lb
+ 0x1001 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x94 , 1 , 27 , 143 , // 27 - ar-ly
+ 0x1801 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x9f , 1 , 28 , 300 , // 28 - ar-ma
+ 0x1000 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0xa2 , 0 , 29 , 240 , // 29 - ar-mr
+ 0x2001 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0xa4 , 0 , 30 , 143 , // 30 - ar-om
+ 0x1000 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0xb8 , 0 , 31 , 240 , // 31 - ar-ps
+ 0x4001 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0xc5 , 0 , 32 , 143 , // 32 - ar-qa
+ 0x401 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0xcd , 0 , 33 , 143 , // 33 - ar-sa
+ 0x1000 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0xdb , 0 , 34 , 240 , // 34 - ar-sd
+ 0x1000 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0xd8 , 0 , 35 , 240 , // 35 - ar-so
+ 0x1000 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x114 , 0 , 36 , 240 , // 36 - ar-ss
+ 0x2801 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0xde , 0 , 37 , 143 , // 37 - ar-sy
+ 0x1000 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x29 , 0 , 38 , 240 , // 38 - ar-td
+ 0x1c01 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0xea , 1 , 39 , 300 , // 39 - ar-tn
+ 0x2401 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x105 , 0 , 40 , 143 , // 40 - ar-ye
+ 0x7a , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0x2e , 1 , 42 , 42 , // 41 - arn
+ 0x47a , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0x2e , 1 , 42 , 42 , // 42 - arn-cl
+ 0x4d , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 44 , 143 , // 43 - as
+ 0x44d , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 44 , 143 , // 44 - as-in
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xef , 1 , 46 , 240 , // 45 - asa
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xef , 1 , 46 , 240 , // 46 - asa-tz
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xd9 , 1 , 48 , 240 , // 47 - ast
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xd9 , 1 , 48 , 240 , // 48 - ast-es
+ 0x2c , 0x4e6 , 0x359 , 0x2761, 0x51a9, 0x5 , 1 , 53 , 53 , // 49 - az
+ 0x742c , 0x4e3 , 0x362 , 0x2717, 0x5190, 0x5 , 1 , 51 , 51 , // 50 - az-cyrl
+ 0x82c , 0x4e3 , 0x362 , 0x2717, 0x5190, 0x5 , 1 , 51 , 51 , // 51 - az-cyrl-az
+ 0x782c , 0x4e6 , 0x359 , 0x2761, 0x51a9, 0x5 , 1 , 53 , 53 , // 52 - az-latn
+ 0x42c , 0x4e6 , 0x359 , 0x2761, 0x51a9, 0x5 , 1 , 53 , 53 , // 53 - az-latn-az
+ 0x6d , 0x4e3 , 0x362 , 0x2717, 0x5190, 0xcb , 1 , 55 , 55 , // 54 - ba
+ 0x46d , 0x4e3 , 0x362 , 0x2717, 0x5190, 0xcb , 1 , 55 , 55 , // 55 - ba-ru
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x31 , 1 , 57 , 240 , // 56 - bas
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x31 , 1 , 57 , 240 , // 57 - bas-cm
+ 0x23 , 0x4e3 , 0x362 , 0x2717, 0x1f4 , 0x1d , 1 , 59 , 59 , // 58 - be
+ 0x423 , 0x4e3 , 0x362 , 0x2717, 0x1f4 , 0x1d , 1 , 59 , 59 , // 59 - be-by
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x107 , 1 , 61 , 240 , // 60 - bem
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x107 , 1 , 61 , 240 , // 61 - bem-zm
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xef , 1 , 63 , 240 , // 62 - bez
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xef , 1 , 63 , 240 , // 63 - bez-tz
+ 0x2 , 0x4e3 , 0x362 , 0x2717, 0x5221, 0x23 , 1 , 65 , 65 , // 64 - bg
+ 0x402 , 0x4e3 , 0x362 , 0x2717, 0x5221, 0x23 , 1 , 65 , 65 , // 65 - bg-bg
+ 0x66 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xaf , 1 , 67 , 240 , // 66 - bin
+ 0x466 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xaf , 1 , 67 , 240 , // 67 - bin-ng
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x9d , 1 , 70 , 240 , // 68 - bm
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x9d , 1 , 70 , 240 , // 69 - bm-latn
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x9d , 1 , 70 , 240 , // 70 - bm-latn-ml
+ 0x45 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x17 , 1 , 72 , 143 , // 71 - bn
+ 0x845 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x17 , 1 , 72 , 143 , // 72 - bn-bd
+ 0x445 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 73 , 143 , // 73 - bn-in
+ 0x51 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x2d , 1 , 75 , 143 , // 74 - bo
+ 0x451 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x2d , 1 , 75 , 143 , // 75 - bo-cn
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 76 , 240 , // 76 - bo-in
+ 0x7e , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x54 , 1 , 78 , 78 , // 77 - br
+ 0x47e , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x54 , 1 , 78 , 78 , // 78 - br-fr
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 80 , 240 , // 79 - brx
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 80 , 240 , // 80 - brx-in
+ 0x781a , 0x4e2 , 0x354 , 0x2762, 0x366 , 0x19 , 1 , 85 , 85 , // 81 - bs
+ 0x641a , 0x4e3 , 0x357 , 0x2762, 0x366 , 0x19 , 1 , 83 , 83 , // 82 - bs-cyrl
+ 0x201a , 0x4e3 , 0x357 , 0x2762, 0x366 , 0x19 , 1 , 83 , 83 , // 83 - bs-cyrl-ba
+ 0x681a , 0x4e2 , 0x354 , 0x2762, 0x366 , 0x19 , 1 , 85 , 85 , // 84 - bs-latn
+ 0x141a , 0x4e2 , 0x354 , 0x2762, 0x366 , 0x19 , 1 , 85 , 85 , // 85 - bs-latn-ba
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x47 , 1 , 87 , 240 , // 86 - byn
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x47 , 1 , 87 , 240 , // 87 - byn-er
+ 0x3 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xd9 , 1 , 90 , 90 , // 88 - ca
+ 0x1000 , 0x4e4 , 0x352 , 0x2 , 0x1f4 , 0x8 , 1 , 89 , 240 , // 89 - ca-ad
+ 0x403 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xd9 , 1 , 90 , 90 , // 90 - ca-es
+ 0x803 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xd9 , 1 , 91 , 90 , // 91 - ca-es-valencia
+ 0x1000 , 0x4e4 , 0x352 , 0x2 , 0x1f4 , 0x54 , 1 , 92 , 240 , // 92 - ca-fr
+ 0x1000 , 0x4e4 , 0x352 , 0x2 , 0x1f4 , 0x76 , 1 , 93 , 240 , // 93 - ca-it
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xcb , 1 , 95 , 240 , // 94 - ce
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xcb , 1 , 95 , 240 , // 95 - ce-ru
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xf0 , 1 , 97 , 240 , // 96 - cgg
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xf0 , 1 , 97 , 240 , // 97 - cgg-ug
+ 0x5c , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xf4 , 1 , 100 , 240 , // 98 - chr
+ 0x7c5c , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xf4 , 1 , 100 , 240 , // 99 - chr-cher
+ 0x45c , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xf4 , 1 , 100 , 240 , // 100 - chr-cher-us
+ 0x83 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x54 , 1 , 102 , 102 , // 101 - co
+ 0x483 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x54 , 1 , 102 , 102 , // 102 - co-fr
+ 0x5 , 0x4e2 , 0x354 , 0x272d, 0x1f4 , 0x4b , 1 , 104 , 104 , // 103 - cs
+ 0x405 , 0x4e2 , 0x354 , 0x272d, 0x1f4 , 0x4b , 1 , 104 , 104 , // 104 - cs-cz
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xcb , 1 , 106 , 240 , // 105 - cu
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xcb , 1 , 106 , 240 , // 106 - cu-ru
+ 0x52 , 0x4e4 , 0x352 , 0x2710, 0x4f3d, 0xf2 , 1 , 108 , 108 , // 107 - cy
+ 0x452 , 0x4e4 , 0x352 , 0x2710, 0x4f3d, 0xf2 , 1 , 108 , 108 , // 108 - cy-gb
+ 0x6 , 0x4e4 , 0x352 , 0x2710, 0x4f35, 0x3d , 1 , 110 , 110 , // 109 - da
+ 0x406 , 0x4e4 , 0x352 , 0x2710, 0x4f35, 0x3d , 1 , 110 , 110 , // 110 - da-dk
+ 0x1000 , 0x4e4 , 0x352 , 0x2 , 0x1f4 , 0x5d , 1 , 111 , 240 , // 111 - da-gl
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x81 , 1 , 113 , 240 , // 112 - dav
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x81 , 1 , 113 , 240 , // 113 - dav-ke
+ 0x7 , 0x4e4 , 0x352 , 0x2710, 0x4f31, 0x5e , 1 , 118 , 118 , // 114 - de
+ 0xc07 , 0x4e4 , 0x352 , 0x2710, 0x4f31, 0xe , 1 , 115 , 115 , // 115 - de-at
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f31, 0x15 , 1 , 116 , 240 , // 116 - de-be
+ 0x807 , 0x4e4 , 0x352 , 0x2710, 0x4f31, 0xdf , 1 , 117 , 117 , // 117 - de-ch
+ 0x407 , 0x4e4 , 0x352 , 0x2710, 0x4f31, 0x5e , 1 , 118 , 118 , // 118 - de-de
+ 0x10407, 0x4e4 , 0x352 , 0x2710, 0x4f31, 0x5e , 1 , 118 , 118 , // 119 - de-de_phoneb
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x76 , 1 , 120 , 240 , // 120 - de-it
+ 0x1407 , 0x4e4 , 0x352 , 0x2710, 0x4f31, 0x91 , 1 , 121 , 121 , // 121 - de-li
+ 0x1007 , 0x4e4 , 0x352 , 0x2710, 0x4f31, 0x93 , 1 , 122 , 122 , // 122 - de-lu
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xad , 1 , 124 , 240 , // 123 - dje
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xad , 1 , 124 , 240 , // 124 - dje-ne
+ 0x7c2e , 0x4e4 , 0x352 , 0x2710, 0x366 , 0x5e , 1 , 126 , 126 , // 125 - dsb
+ 0x82e , 0x4e4 , 0x352 , 0x2710, 0x366 , 0x5e , 1 , 126 , 126 , // 126 - dsb-de
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x31 , 1 , 128 , 240 , // 127 - dua
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x31 , 1 , 128 , 240 , // 128 - dua-cm
+ 0x65 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xa5 , 1 , 130 , 143 , // 129 - dv
+ 0x465 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xa5 , 1 , 130 , 143 , // 130 - dv-mv
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xd2 , 1 , 132 , 240 , // 131 - dyo
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xd2 , 1 , 132 , 240 , // 132 - dyo-sn
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x22 , 2 , 134 , 240 , // 133 - dz
+ 0xc51 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x22 , 2 , 134 , 240 , // 134 - dz-bt
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x81 , 1 , 136 , 240 , // 135 - ebu
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x81 , 1 , 136 , 240 , // 136 - ebu-ke
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x59 , 1 , 138 , 240 , // 137 - ee
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x59 , 1 , 138 , 240 , // 138 - ee-gh
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xe8 , 1 , 139 , 240 , // 139 - ee-tg
+ 0x8 , 0x4e5 , 0x2e1 , 0x2716, 0x4f31, 0x62 , 1 , 142 , 142 , // 140 - el
+ 0x1000 , 0x4e5 , 0x2e1 , 0x2716, 0x4f31, 0x3b , 1 , 141 , 240 , // 141 - el-cy
+ 0x408 , 0x4e5 , 0x2e1 , 0x2716, 0x4f31, 0x62 , 1 , 142 , 142 , // 142 - el-gr
+ 0x9 , 0x4e4 , 0x1b5 , 0x2710, 0x25 , 0xf4 , 1 , 240 , 240 , // 143 - en
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x989e, 1 , 144 , 240 , // 144 - en-001
+ 0x2409 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x993248, 1 , 145 , 145 , // 145 - en-029
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x292d, 1 , 146 , 240 , // 146 - en-150
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x2 , 1 , 147 , 240 , // 147 - en-ag
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x12c , 1 , 148 , 240 , // 148 - en-ai
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xa , 1 , 149 , 240 , // 149 - en-as
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xe , 1 , 150 , 240 , // 150 - en-at
+ 0xc09 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xc , 1 , 151 , 151 , // 151 - en-au
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x12 , 1 , 152 , 240 , // 152 - en-bb
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x15 , 1 , 153 , 240 , // 153 - en-be
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x26 , 1 , 154 , 240 , // 154 - en-bi
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x14 , 1 , 155 , 240 , // 155 - en-bm
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x16 , 1 , 156 , 240 , // 156 - en-bs
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x13 , 1 , 157 , 240 , // 157 - en-bw
+ 0x2809 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x18 , 1 , 158 , 158 , // 158 - en-bz
+ 0x1009 , 0x4e4 , 0x352 , 0x2710, 0x25 , 0x27 , 1 , 159 , 159 , // 159 - en-ca
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x137 , 1 , 160 , 240 , // 160 - en-cc
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xdf , 1 , 161 , 240 , // 161 - en-ch
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x138 , 1 , 162 , 240 , // 162 - en-ck
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x31 , 1 , 163 , 240 , // 163 - en-cm
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x135 , 1 , 164 , 240 , // 164 - en-cx
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x3b , 1 , 165 , 240 , // 165 - en-cy
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x5e , 1 , 166 , 240 , // 166 - en-de
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x3d , 1 , 167 , 240 , // 167 - en-dk
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x3f , 1 , 168 , 240 , // 168 - en-dm
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x47 , 1 , 169 , 240 , // 169 - en-er
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x4d , 1 , 170 , 240 , // 170 - en-fi
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x4e , 1 , 171 , 240 , // 171 - en-fj
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x13b , 1 , 172 , 240 , // 172 - en-fk
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x50 , 1 , 173 , 240 , // 173 - en-fm
+ 0x809 , 0x4e4 , 0x352 , 0x2710, 0x4f3d, 0xf2 , 1 , 174 , 174 , // 174 - en-gb
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x5b , 1 , 175 , 240 , // 175 - en-gd
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x144 , 1 , 176 , 240 , // 176 - en-gg
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x59 , 1 , 177 , 240 , // 177 - en-gh
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x5a , 1 , 178 , 240 , // 178 - en-gi
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x56 , 1 , 179 , 240 , // 179 - en-gm
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x142 , 1 , 180 , 240 , // 180 - en-gu
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x65 , 1 , 181 , 240 , // 181 - en-gy
+ 0x3c09 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x68 , 1 , 182 , 240 , // 182 - en-hk
+ 0x3809 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x6f , 1 , 183 , 240 , // 183 - en-id
+ 0x1809 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x44 , 1 , 184 , 184 , // 184 - en-ie
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x75 , 1 , 185 , 240 , // 185 - en-il
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x3b16, 1 , 186 , 240 , // 186 - en-im
+ 0x4009 , 0x4e4 , 0x1b5 , 0x2710, 0x25 , 0x71 , 1 , 187 , 187 , // 187 - en-in
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x72 , 1 , 188 , 240 , // 188 - en-io
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x148 , 1 , 189 , 240 , // 189 - en-je
+ 0x2009 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x7c , 1 , 190 , 190 , // 190 - en-jm
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x81 , 1 , 191 , 240 , // 191 - en-ke
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x85 , 1 , 192 , 240 , // 192 - en-ki
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xcf , 1 , 193 , 240 , // 193 - en-kn
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x133 , 1 , 194 , 240 , // 194 - en-ky
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xda , 1 , 195 , 240 , // 195 - en-lc
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x8e , 1 , 196 , 240 , // 196 - en-lr
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x92 , 1 , 197 , 240 , // 197 - en-ls
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x95 , 1 , 198 , 240 , // 198 - en-mg
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xc7 , 1 , 199 , 240 , // 199 - en-mh
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x97 , 1 , 200 , 240 , // 200 - en-mo
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x151 , 1 , 201 , 240 , // 201 - en-mp
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x14c , 1 , 202 , 240 , // 202 - en-ms
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xa3 , 1 , 203 , 240 , // 203 - en-mt
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xa0 , 1 , 204 , 240 , // 204 - en-mu
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x9c , 1 , 205 , 240 , // 205 - en-mw
+ 0x4409 , 0x4e4 , 0x1b5 , 0x2710, 0x25 , 0xa7 , 1 , 206 , 206 , // 206 - en-my
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xfe , 1 , 207 , 240 , // 207 - en-na
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x150 , 1 , 208 , 240 , // 208 - en-nf
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xaf , 1 , 209 , 240 , // 209 - en-ng
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xb0 , 1 , 210 , 240 , // 210 - en-nl
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xb4 , 1 , 211 , 240 , // 211 - en-nr
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x14f , 1 , 212 , 240 , // 212 - en-nu
+ 0x1409 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xb7 , 1 , 213 , 213 , // 213 - en-nz
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xc2 , 1 , 214 , 240 , // 214 - en-pg
+ 0x3409 , 0x4e4 , 0x1b5 , 0x2710, 0x1f4 , 0xc9 , 1 , 215 , 215 , // 215 - en-ph
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xbe , 1 , 216 , 240 , // 216 - en-pk
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x153 , 1 , 217 , 240 , // 217 - en-pn
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xca , 1 , 218 , 240 , // 218 - en-pr
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xc3 , 1 , 219 , 240 , // 219 - en-pw
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xcc , 1 , 220 , 240 , // 220 - en-rw
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x1e , 1 , 221 , 240 , // 221 - en-sb
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xd0 , 1 , 222 , 240 , // 222 - en-sc
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xdb , 1 , 223 , 240 , // 223 - en-sd
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xdd , 1 , 224 , 240 , // 224 - en-se
+ 0x4809 , 0x4e4 , 0x1b5 , 0x2710, 0x25 , 0xd7 , 1 , 225 , 225 , // 225 - en-sg
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x157 , 1 , 226 , 240 , // 226 - en-sh
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xd4 , 1 , 227 , 240 , // 227 - en-si
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xd5 , 1 , 228 , 240 , // 228 - en-sl
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x114 , 1 , 229 , 240 , // 229 - en-ss
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x78f7, 1 , 230 , 240 , // 230 - en-sx
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x104 , 1 , 231 , 240 , // 231 - en-sz
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x15d , 1 , 232 , 240 , // 232 - en-tc
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x15b , 1 , 233 , 240 , // 233 - en-tk
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xe7 , 1 , 234 , 240 , // 234 - en-to
+ 0x2c09 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xe1 , 1 , 235 , 235 , // 235 - en-tt
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xec , 1 , 236 , 240 , // 236 - en-tv
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xef , 1 , 237 , 240 , // 237 - en-tz
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xf0 , 1 , 238 , 240 , // 238 - en-ug
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x9a55d40, 1 , 239 , 240 , // 239 - en-um
+ 0x409 , 0x4e4 , 0x1b5 , 0x2710, 0x25 , 0xf4 , 1 , 240 , 240 , // 240 - en-us
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xf8 , 1 , 241 , 240 , // 241 - en-vc
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x15f , 1 , 242 , 240 , // 242 - en-vg
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xfc , 1 , 243 , 240 , // 243 - en-vi
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xae , 1 , 244 , 240 , // 244 - en-vu
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x103 , 1 , 245 , 240 , // 245 - en-ws
+ 0x1c09 , 0x4e4 , 0x1b5 , 0x2710, 0x1f4 , 0xd1 , 1 , 246 , 246 , // 246 - en-za
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x107 , 1 , 247 , 240 , // 247 - en-zm
+ 0x3009 , 0x4e4 , 0x1b5 , 0x2710, 0x1f4 , 0x108 , 1 , 248 , 248 , // 248 - en-zw
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x989e, 1 , 250 , 240 , // 249 - eo
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x989e, 1 , 250 , 240 , // 250 - eo-001
+ 0xa , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0xd9 , 1 , 262 , 262 , // 251 - es
+ 0x580a , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0x9a55d41, 1 , 252 , 240 , // 252 - es-419
+ 0x2c0a , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0xb , 1 , 253 , 253 , // 253 - es-ar
+ 0x400a , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0x1a , 1 , 254 , 254 , // 254 - es-bo
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x20 , 1 , 255 , 240 , // 255 - es-br
+ 0x340a , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0x2e , 1 , 256 , 256 , // 256 - es-cl
+ 0x240a , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0x33 , 1 , 257 , 257 , // 257 - es-co
+ 0x140a , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0x36 , 1 , 258 , 258 , // 258 - es-cr
+ 0x5c0a , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0x38 , 1 , 259 , 240 , // 259 - es-cu
+ 0x1c0a , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0x41 , 1 , 260 , 260 , // 260 - es-do
+ 0x300a , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0x42 , 1 , 261 , 261 , // 261 - es-ec
+ 0xc0a , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0xd9 , 1 , 262 , 262 , // 262 - es-es
+ 0x40a , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0xd9 , 1 , 263 , 263 , // 263 - es-es_tradnl
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0x45 , 1 , 264 , 240 , // 264 - es-gq
+ 0x100a , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0x63 , 1 , 265 , 265 , // 265 - es-gt
+ 0x480a , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0x6a , 1 , 266 , 266 , // 266 - es-hn
+ 0x80a , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0xa6 , 1 , 267 , 267 , // 267 - es-mx
+ 0x4c0a , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0xb6 , 1 , 268 , 268 , // 268 - es-ni
+ 0x180a , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0xc0 , 1 , 269 , 269 , // 269 - es-pa
+ 0x280a , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0xbb , 1 , 270 , 270 , // 270 - es-pe
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0xc9 , 1 , 271 , 240 , // 271 - es-ph
+ 0x500a , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0xca , 1 , 272 , 272 , // 272 - es-pr
+ 0x3c0a , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0xb9 , 1 , 273 , 273 , // 273 - es-py
+ 0x440a , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0x48 , 1 , 274 , 274 , // 274 - es-sv
+ 0x540a , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0xf4 , 1 , 275 , 275 , // 275 - es-us
+ 0x380a , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0xf6 , 1 , 276 , 276 , // 276 - es-uy
+ 0x200a , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0xf9 , 1 , 277 , 277 , // 277 - es-ve
+ 0x25 , 0x4e9 , 0x307 , 0x272d, 0x1f4 , 0x46 , 1 , 279 , 279 , // 278 - et
+ 0x425 , 0x4e9 , 0x307 , 0x272d, 0x1f4 , 0x46 , 1 , 279 , 279 , // 279 - et-ee
+ 0x2d , 0x4e4 , 0x352 , 0x2 , 0x1f4 , 0xd9 , 1 , 281 , 240 , // 280 - eu
+ 0x42d , 0x4e4 , 0x352 , 0x2 , 0x1f4 , 0xd9 , 1 , 281 , 240 , // 281 - eu-es
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x31 , 1 , 283 , 240 , // 282 - ewo
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x31 , 1 , 283 , 240 , // 283 - ewo-cm
+ 0x29 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x74 , 0 , 285 , 143 , // 284 - fa
+ 0x429 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x74 , 0 , 285 , 143 , // 285 - fa-ir
+ 0x67 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0xd2 , 1 , 290 , 290 , // 286 - ff
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x31 , 1 , 287 , 240 , // 287 - ff-cm
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x64 , 1 , 288 , 240 , // 288 - ff-gn
+ 0x7c67 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0xd2 , 1 , 290 , 290 , // 289 - ff-latn
+ 0x867 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0xd2 , 1 , 290 , 290 , // 290 - ff-latn-sn
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0xa2 , 1 , 291 , 240 , // 291 - ff-mr
+ 0x467 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0xaf , 1 , 292 , 240 , // 292 - ff-ng
+ 0xb , 0x4e4 , 0x352 , 0x2710, 0x4f36, 0x4d , 1 , 294 , 294 , // 293 - fi
+ 0x40b , 0x4e4 , 0x352 , 0x2710, 0x4f36, 0x4d , 1 , 294 , 294 , // 294 - fi-fi
+ 0x64 , 0x4e4 , 0x1b5 , 0x2710, 0x1f4 , 0xc9 , 1 , 296 , 296 , // 295 - fil
+ 0x464 , 0x4e4 , 0x1b5 , 0x2710, 0x1f4 , 0xc9 , 1 , 296 , 296 , // 296 - fil-ph
+ 0x38 , 0x4e4 , 0x352 , 0x275f, 0x4f35, 0x51 , 1 , 299 , 299 , // 297 - fo
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x3d , 1 , 298 , 240 , // 298 - fo-dk
+ 0x438 , 0x4e4 , 0x352 , 0x275f, 0x4f35, 0x51 , 1 , 299 , 299 , // 299 - fo-fo
+ 0xc , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x54 , 1 , 316 , 316 , // 300 - fr
+ 0x1c0c , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x993248, 1 , 301 , 316 , // 301 - fr-029
+ 0x80c , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x15 , 1 , 302 , 302 , // 302 - fr-be
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0xf5 , 1 , 303 , 240 , // 303 - fr-bf
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x26 , 1 , 304 , 240 , // 304 - fr-bi
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x1c , 1 , 305 , 240 , // 305 - fr-bj
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x9a55c4f, 1 , 306 , 240 , // 306 - fr-bl
+ 0xc0c , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x27 , 1 , 307 , 307 , // 307 - fr-ca
+ 0x240c , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x2c , 1 , 308 , 240 , // 308 - fr-cd
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x37 , 1 , 309 , 240 , // 309 - fr-cf
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x2b , 1 , 310 , 240 , // 310 - fr-cg
+ 0x100c , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0xdf , 1 , 311 , 311 , // 311 - fr-ch
+ 0x300c , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x77 , 1 , 312 , 240 , // 312 - fr-ci
+ 0x2c0c , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x31 , 1 , 313 , 240 , // 313 - fr-cm
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x3e , 1 , 314 , 240 , // 314 - fr-dj
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x4 , 1 , 315 , 240 , // 315 - fr-dz
+ 0x40c , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x54 , 1 , 316 , 316 , // 316 - fr-fr
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x57 , 1 , 317 , 240 , // 317 - fr-ga
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x13d , 1 , 318 , 240 , // 318 - fr-gf
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x64 , 1 , 319 , 240 , // 319 - fr-gn
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x141 , 1 , 320 , 240 , // 320 - fr-gp
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x45 , 1 , 321 , 240 , // 321 - fr-gq
+ 0x3c0c , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x67 , 1 , 322 , 240 , // 322 - fr-ht
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x32 , 1 , 323 , 240 , // 323 - fr-km
+ 0x140c , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x93 , 1 , 324 , 324 , // 324 - fr-lu
+ 0x380c , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x9f , 1 , 325 , 240 , // 325 - fr-ma
+ 0x180c , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x9e , 1 , 326 , 326 , // 326 - fr-mc
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x7bda, 1 , 327 , 240 , // 327 - fr-mf
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x95 , 1 , 328 , 240 , // 328 - fr-mg
+ 0x340c , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x9d , 1 , 329 , 240 , // 329 - fr-ml
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x14a , 1 , 330 , 240 , // 330 - fr-mq
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0xa2 , 1 , 331 , 240 , // 331 - fr-mr
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0xa0 , 1 , 332 , 240 , // 332 - fr-mu
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x14e , 1 , 333 , 240 , // 333 - fr-nc
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0xad , 1 , 334 , 240 , // 334 - fr-ne
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x13e , 1 , 335 , 240 , // 335 - fr-pf
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0xce , 1 , 336 , 240 , // 336 - fr-pm
+ 0x200c , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0xc6 , 1 , 337 , 240 , // 337 - fr-re
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0xcc , 1 , 338 , 240 , // 338 - fr-rw
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0xd0 , 1 , 339 , 240 , // 339 - fr-sc
+ 0x280c , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0xd2 , 1 , 340 , 240 , // 340 - fr-sn
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0xde , 1 , 341 , 240 , // 341 - fr-sy
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x29 , 1 , 342 , 240 , // 342 - fr-td
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0xe8 , 1 , 343 , 240 , // 343 - fr-tg
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0xea , 1 , 344 , 240 , // 344 - fr-tn
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0xae , 1 , 345 , 240 , // 345 - fr-vu
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x160 , 1 , 346 , 240 , // 346 - fr-wf
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x14b , 1 , 347 , 240 , // 347 - fr-yt
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x76 , 1 , 349 , 240 , // 348 - fur
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x76 , 1 , 349 , 240 , // 349 - fur-it
+ 0x62 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xb0 , 1 , 351 , 351 , // 350 - fy
+ 0x462 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xb0 , 1 , 351 , 351 , // 351 - fy-nl
+ 0x3c , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x44 , 1 , 353 , 353 , // 352 - ga
+ 0x83c , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x44 , 1 , 353 , 353 , // 353 - ga-ie
+ 0x91 , 0x4e4 , 0x352 , 0x2710, 0x4f3d, 0xf2 , 1 , 355 , 355 , // 354 - gd
+ 0x491 , 0x4e4 , 0x352 , 0x2710, 0x4f3d, 0xf2 , 1 , 355 , 355 , // 355 - gd-gb
+ 0x56 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xd9 , 1 , 357 , 357 , // 356 - gl
+ 0x456 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xd9 , 1 , 357 , 357 , // 357 - gl-es
+ 0x74 , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0xb9 , 1 , 359 , 359 , // 358 - gn
+ 0x474 , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0xb9 , 1 , 359 , 359 , // 359 - gn-py
+ 0x84 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0xdf , 1 , 361 , 240 , // 360 - gsw
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0xdf , 1 , 361 , 240 , // 361 - gsw-ch
+ 0x484 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x54 , 1 , 362 , 362 , // 362 - gsw-fr
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x91 , 1 , 363 , 240 , // 363 - gsw-li
+ 0x47 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 365 , 143 , // 364 - gu
+ 0x447 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 365 , 143 , // 365 - gu-in
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x81 , 1 , 367 , 240 , // 366 - guz
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x81 , 1 , 367 , 240 , // 367 - guz-ke
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x3b16, 1 , 369 , 240 , // 368 - gv
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x3b16, 1 , 369 , 240 , // 369 - gv-im
+ 0x68 , 0x4e4 , 0x1b5 , 0x2710, 0x25 , 0xaf , 1 , 374 , 374 , // 370 - ha
+ 0x7c68 , 0x4e4 , 0x1b5 , 0x2710, 0x25 , 0xaf , 1 , 374 , 374 , // 371 - ha-latn
+ 0x1000 , 0x4e4 , 0x1b5 , 0x2710, 0x1f4 , 0x59 , 1 , 372 , 240 , // 372 - ha-latn-gh
+ 0x1000 , 0x4e4 , 0x1b5 , 0x2710, 0x1f4 , 0xad , 1 , 373 , 240 , // 373 - ha-latn-ne
+ 0x468 , 0x4e4 , 0x1b5 , 0x2710, 0x25 , 0xaf , 1 , 374 , 374 , // 374 - ha-latn-ng
+ 0x75 , 0x4e4 , 0x1b5 , 0x2710, 0x25 , 0xf4 , 1 , 376 , 376 , // 375 - haw
+ 0x475 , 0x4e4 , 0x1b5 , 0x2710, 0x25 , 0xf4 , 1 , 376 , 376 , // 376 - haw-us
+ 0xd , 0x4e7 , 0x35e , 0x2715, 0x1f4 , 0x75 , 1 , 378 , 143 , // 377 - he
+ 0x40d , 0x4e7 , 0x35e , 0x2715, 0x1f4 , 0x75 , 1 , 378 , 143 , // 378 - he-il
+ 0x39 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 380 , 143 , // 379 - hi
+ 0x439 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 380 , 143 , // 380 - hi-in
+ 0x1a , 0x4e2 , 0x354 , 0x2762, 0x1f4 , 0x6c , 1 , 383 , 383 , // 381 - hr
+ 0x101a , 0x4e2 , 0x354 , 0x2762, 0x366 , 0x19 , 1 , 382 , 382 , // 382 - hr-ba
+ 0x41a , 0x4e2 , 0x354 , 0x2762, 0x1f4 , 0x6c , 1 , 383 , 383 , // 383 - hr-hr
+ 0x2e , 0x4e4 , 0x352 , 0x2710, 0x366 , 0x5e , 1 , 385 , 385 , // 384 - hsb
+ 0x42e , 0x4e4 , 0x352 , 0x2710, 0x366 , 0x5e , 1 , 385 , 385 , // 385 - hsb-de
+ 0xe , 0x4e2 , 0x354 , 0x272d, 0x1f4 , 0x6d , 1 , 387 , 387 , // 386 - hu
+ 0x40e , 0x4e2 , 0x354 , 0x272d, 0x1f4 , 0x6d , 1 , 387 , 387 , // 387 - hu-hu
+ 0x1040e, 0x4e2 , 0x354 , 0x272d, 0x1f4 , 0x6d , 1 , 387 , 387 , // 388 - hu-hu_technl
+ 0x2b , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x7 , 1 , 390 , 390 , // 389 - hy
+ 0x42b , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x7 , 1 , 390 , 390 , // 390 - hy-am
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x54 , 1 , 393 , 240 , // 391 - ia
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x989e, 1 , 392 , 240 , // 392 - ia-001
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x54 , 1 , 393 , 240 , // 393 - ia-fr
+ 0x69 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xaf , 1 , 395 , 240 , // 394 - ibb
+ 0x469 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xaf , 1 , 395 , 240 , // 395 - ibb-ng
+ 0x21 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x6f , 1 , 397 , 397 , // 396 - id
+ 0x421 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x6f , 1 , 397 , 397 , // 397 - id-id
+ 0x70 , 0x4e4 , 0x1b5 , 0x2710, 0x25 , 0xaf , 1 , 399 , 399 , // 398 - ig
+ 0x470 , 0x4e4 , 0x1b5 , 0x2710, 0x25 , 0xaf , 1 , 399 , 399 , // 399 - ig-ng
+ 0x78 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x2d , 1 , 401 , 143 , // 400 - ii
+ 0x478 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x2d , 1 , 401 , 143 , // 401 - ii-cn
+ 0xf , 0x4e4 , 0x352 , 0x275f, 0x5187, 0x6e , 1 , 403 , 403 , // 402 - is
+ 0x40f , 0x4e4 , 0x352 , 0x275f, 0x5187, 0x6e , 1 , 403 , 403 , // 403 - is-is
+ 0x10 , 0x4e4 , 0x352 , 0x2710, 0x4f38, 0x76 , 1 , 406 , 406 , // 404 - it
+ 0x810 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xdf , 1 , 405 , 405 , // 405 - it-ch
+ 0x410 , 0x4e4 , 0x352 , 0x2710, 0x4f38, 0x76 , 1 , 406 , 406 , // 406 - it-it
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f38, 0xd6 , 1 , 407 , 240 , // 407 - it-sm
+ 0x5d , 0x4e4 , 0x1b5 , 0x2710, 0x25 , 0x27 , 1 , 412 , 412 , // 408 - iu
+ 0x785d , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x27 , 1 , 410 , 143 , // 409 - iu-cans
+ 0x45d , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x27 , 1 , 410 , 143 , // 410 - iu-cans-ca
+ 0x7c5d , 0x4e4 , 0x1b5 , 0x2710, 0x25 , 0x27 , 1 , 412 , 412 , // 411 - iu-latn
+ 0x85d , 0x4e4 , 0x1b5 , 0x2710, 0x25 , 0x27 , 1 , 412 , 412 , // 412 - iu-latn-ca
+ 0x11 , 0x3a4 , 0x3a4 , 0x2711, 0x4f42, 0x7a , 1 , 414 , 414 , // 413 - ja
+ 0x411 , 0x3a4 , 0x3a4 , 0x2711, 0x4f42, 0x7a , 1 , 414 , 414 , // 414 - ja-jp
+ 0x40411, 0x3a4 , 0x3a4 , 0x2711, 0x4f42, 0x7a , 1 , 414 , 414 , // 415 - ja-jp_radstr
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x31 , 1 , 417 , 240 , // 416 - jgo
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x31 , 1 , 417 , 240 , // 417 - jgo-cm
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xef , 1 , 419 , 240 , // 418 - jmc
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xef , 1 , 419 , 240 , // 419 - jmc-tz
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x6f , 1 , 424 , 424 , // 420 - jv
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x6f , 1 , 422 , 424 , // 421 - jv-java
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x6f , 1 , 422 , 424 , // 422 - jv-java-id
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x6f , 1 , 424 , 424 , // 423 - jv-latn
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x6f , 1 , 424 , 424 , // 424 - jv-latn-id
+ 0x37 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x58 , 1 , 426 , 426 , // 425 - ka
+ 0x437 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x58 , 1 , 426 , 426 , // 426 - ka-ge
+ 0x10437, 0x0 , 0x1 , 0x2 , 0x1f4 , 0x58 , 1 , 426 , 426 , // 427 - ka-ge_modern
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x4 , 1 , 429 , 240 , // 428 - kab
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x4 , 1 , 429 , 240 , // 429 - kab-dz
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x81 , 1 , 431 , 240 , // 430 - kam
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x81 , 1 , 431 , 240 , // 431 - kam-ke
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xef , 1 , 433 , 240 , // 432 - kde
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xef , 1 , 433 , 240 , // 433 - kde-tz
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x39 , 1 , 435 , 240 , // 434 - kea
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x39 , 1 , 435 , 240 , // 435 - kea-cv
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x9d , 1 , 437 , 240 , // 436 - khq
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x9d , 1 , 437 , 240 , // 437 - khq-ml
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x81 , 1 , 439 , 240 , // 438 - ki
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x81 , 1 , 439 , 240 , // 439 - ki-ke
+ 0x3f , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x89 , 1 , 441 , 441 , // 440 - kk
+ 0x43f , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x89 , 1 , 441 , 441 , // 441 - kk-kz
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x31 , 1 , 443 , 240 , // 442 - kkj
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x31 , 1 , 443 , 240 , // 443 - kkj-cm
+ 0x6f , 0x4e4 , 0x352 , 0x2710, 0x4f35, 0x5d , 1 , 445 , 445 , // 444 - kl
+ 0x46f , 0x4e4 , 0x352 , 0x2710, 0x4f35, 0x5d , 1 , 445 , 445 , // 445 - kl-gl
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x81 , 1 , 447 , 240 , // 446 - kln
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x81 , 1 , 447 , 240 , // 447 - kln-ke
+ 0x53 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x28 , 2 , 449 , 143 , // 448 - km
+ 0x453 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x28 , 2 , 449 , 143 , // 449 - km-kh
+ 0x4b , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 451 , 143 , // 450 - kn
+ 0x44b , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 451 , 143 , // 451 - kn-in
+ 0x12 , 0x3b5 , 0x3b5 , 0x2713, 0x5161, 0x86 , 1 , 454 , 454 , // 452 - ko
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x83 , 1 , 453 , 240 , // 453 - ko-kp
+ 0x412 , 0x3b5 , 0x3b5 , 0x2713, 0x5161, 0x86 , 1 , 454 , 454 , // 454 - ko-kr
+ 0x57 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 456 , 143 , // 455 - kok
+ 0x457 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 456 , 143 , // 456 - kok-in
+ 0x71 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xaf , 1 , 458 , 240 , // 457 - kr
+ 0x471 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xaf , 1 , 458 , 240 , // 458 - kr-ng
+ 0x60 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 2 , 461 , 240 , // 459 - ks
+ 0x460 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 2 , 461 , 240 , // 460 - ks-arab
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 2 , 461 , 240 , // 461 - ks-arab-in
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 463 , 187 , // 462 - ks-deva
+ 0x860 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 463 , 187 , // 463 - ks-deva-in
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xef , 1 , 465 , 240 , // 464 - ksb
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xef , 1 , 465 , 240 , // 465 - ksb-tz
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x31 , 1 , 467 , 240 , // 466 - ksf
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x31 , 1 , 467 , 240 , // 467 - ksf-cm
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x5e , 1 , 469 , 240 , // 468 - ksh
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x5e , 1 , 469 , 240 , // 469 - ksh-de
+ 0x92 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x79 , 0 , 472 , 143 , // 470 - ku
+ 0x7c92 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x79 , 0 , 472 , 143 , // 471 - ku-arab
+ 0x492 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x79 , 0 , 472 , 143 , // 472 - ku-arab-iq
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x74 , 0 , 473 , 240 , // 473 - ku-arab-ir
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xf2 , 1 , 475 , 240 , // 474 - kw
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xf2 , 1 , 475 , 240 , // 475 - kw-gb
+ 0x40 , 0x4e3 , 0x362 , 0x2717, 0x5190, 0x82 , 1 , 477 , 477 , // 476 - ky
+ 0x440 , 0x4e3 , 0x362 , 0x2717, 0x5190, 0x82 , 1 , 477 , 477 , // 477 - ky-kg
+ 0x76 , 0x4e4 , 0x1b5 , 0x2710, 0x25 , 0x989e, 1 , 479 , 143 , // 478 - la
+ 0x476 , 0x4e4 , 0x1b5 , 0x2710, 0x25 , 0x989e, 1 , 479 , 143 , // 479 - la-001
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xef , 1 , 481 , 240 , // 480 - lag
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xef , 1 , 481 , 240 , // 481 - lag-tz
+ 0x6e , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x93 , 1 , 483 , 483 , // 482 - lb
+ 0x46e , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x93 , 1 , 483 , 483 , // 483 - lb-lu
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xf0 , 1 , 485 , 240 , // 484 - lg
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xf0 , 1 , 485 , 240 , // 485 - lg-ug
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xf4 , 1 , 487 , 240 , // 486 - lkt
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xf4 , 1 , 487 , 240 , // 487 - lkt-us
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x2c , 1 , 490 , 240 , // 488 - ln
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x9 , 1 , 489 , 240 , // 489 - ln-ao
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x2c , 1 , 490 , 240 , // 490 - ln-cd
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x37 , 1 , 491 , 240 , // 491 - ln-cf
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x2b , 1 , 492 , 240 , // 492 - ln-cg
+ 0x54 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x8a , 1 , 494 , 143 , // 493 - lo
+ 0x454 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x8a , 1 , 494 , 143 , // 494 - lo-la
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x74 , 2 , 497 , 240 , // 495 - lrc
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x79 , 2 , 496 , 240 , // 496 - lrc-iq
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x74 , 2 , 497 , 240 , // 497 - lrc-ir
+ 0x27 , 0x4e9 , 0x307 , 0x272d, 0x1f4 , 0x8d , 1 , 499 , 499 , // 498 - lt
+ 0x427 , 0x4e9 , 0x307 , 0x272d, 0x1f4 , 0x8d , 1 , 499 , 499 , // 499 - lt-lt
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x2c , 1 , 501 , 240 , // 500 - lu
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x2c , 1 , 501 , 240 , // 501 - lu-cd
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x81 , 1 , 503 , 240 , // 502 - luo
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x81 , 1 , 503 , 240 , // 503 - luo-ke
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x81 , 1 , 505 , 240 , // 504 - luy
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x81 , 1 , 505 , 240 , // 505 - luy-ke
+ 0x26 , 0x4e9 , 0x307 , 0x272d, 0x1f4 , 0x8c , 1 , 507 , 507 , // 506 - lv
+ 0x426 , 0x4e9 , 0x307 , 0x272d, 0x1f4 , 0x8c , 1 , 507 , 507 , // 507 - lv-lv
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x81 , 1 , 509 , 240 , // 508 - mas
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x81 , 1 , 509 , 240 , // 509 - mas-ke
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xef , 1 , 510 , 240 , // 510 - mas-tz
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x81 , 1 , 512 , 240 , // 511 - mer
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x81 , 1 , 512 , 240 , // 512 - mer-ke
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xa0 , 1 , 514 , 240 , // 513 - mfe
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xa0 , 1 , 514 , 240 , // 514 - mfe-mu
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x95 , 1 , 516 , 240 , // 515 - mg
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x95 , 1 , 516 , 240 , // 516 - mg-mg
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xa8 , 1 , 518 , 240 , // 517 - mgh
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xa8 , 1 , 518 , 240 , // 518 - mgh-mz
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x31 , 1 , 520 , 240 , // 519 - mgo
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x31 , 1 , 520 , 240 , // 520 - mgo-cm
+ 0x81 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xb7 , 1 , 522 , 522 , // 521 - mi
+ 0x481 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xb7 , 1 , 522 , 522 , // 522 - mi-nz
+ 0x2f , 0x4e3 , 0x362 , 0x2717, 0x1f4 , 0x4ca2, 1 , 524 , 524 , // 523 - mk
+ 0x42f , 0x4e3 , 0x362 , 0x2717, 0x1f4 , 0x4ca2, 1 , 524 , 524 , // 524 - mk-mk
+ 0x4c , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 526 , 143 , // 525 - ml
+ 0x44c , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 526 , 143 , // 526 - ml-in
+ 0x50 , 0x4e3 , 0x362 , 0x2717, 0x5190, 0x9a , 1 , 529 , 529 , // 527 - mn
+ 0x7850 , 0x4e3 , 0x362 , 0x2717, 0x5190, 0x9a , 1 , 529 , 529 , // 528 - mn-cyrl
+ 0x450 , 0x4e3 , 0x362 , 0x2717, 0x5190, 0x9a , 1 , 529 , 529 , // 529 - mn-mn
+ 0x7c50 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x2d , 1 , 531 , 531 , // 530 - mn-mong
+ 0x850 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x2d , 1 , 531 , 531 , // 531 - mn-mong-cn
+ 0xc50 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x9a , 1 , 532 , 532 , // 532 - mn-mong-mn
+ 0x58 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 534 , 187 , // 533 - mni
+ 0x458 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 534 , 187 , // 534 - mni-in
+ 0x7c , 0x4e4 , 0x352 , 0x2710, 0x25 , 0x27 , 1 , 536 , 240 , // 535 - moh
+ 0x47c , 0x4e4 , 0x352 , 0x2710, 0x25 , 0x27 , 1 , 536 , 240 , // 536 - moh-ca
+ 0x4e , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 538 , 143 , // 537 - mr
+ 0x44e , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 538 , 143 , // 538 - mr-in
+ 0x3e , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xa7 , 1 , 541 , 541 , // 539 - ms
+ 0x83e , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x25 , 1 , 540 , 540 , // 540 - ms-bn
+ 0x43e , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xa7 , 1 , 541 , 541 , // 541 - ms-my
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xd7 , 1 , 542 , 240 , // 542 - ms-sg
+ 0x3a , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xa3 , 1 , 544 , 544 , // 543 - mt
+ 0x43a , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xa3 , 1 , 544 , 544 , // 544 - mt-mt
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x31 , 1 , 546 , 240 , // 545 - mua
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x31 , 1 , 546 , 240 , // 546 - mua-cm
+ 0x55 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x1b , 2 , 548 , 240 , // 547 - my
+ 0x455 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x1b , 2 , 548 , 240 , // 548 - my-mm
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x74 , 2 , 550 , 240 , // 549 - mzn
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x74 , 2 , 550 , 240 , // 550 - mzn-ir
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xfe , 1 , 552 , 240 , // 551 - naq
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xfe , 1 , 552 , 240 , // 552 - naq-na
+ 0x7c14 , 0x4e4 , 0x352 , 0x2710, 0x4f35, 0xb1 , 1 , 554 , 554 , // 553 - nb
+ 0x414 , 0x4e4 , 0x352 , 0x2710, 0x4f35, 0xb1 , 1 , 554 , 554 , // 554 - nb-no
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f35, 0xdc , 1 , 555 , 240 , // 555 - nb-sj
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x108 , 1 , 557 , 240 , // 556 - nd
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x108 , 1 , 557 , 240 , // 557 - nd-zw
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x5e , 1 , 559 , 240 , // 558 - nds
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x5e , 1 , 559 , 240 , // 559 - nds-de
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xb0 , 1 , 560 , 240 , // 560 - nds-nl
+ 0x61 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xb2 , 1 , 563 , 143 , // 561 - ne
+ 0x861 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 2 , 562 , 240 , // 562 - ne-in
+ 0x461 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xb2 , 1 , 563 , 143 , // 563 - ne-np
+ 0x13 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xb0 , 1 , 569 , 569 , // 564 - nl
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x12e , 1 , 565 , 240 , // 565 - nl-aw
+ 0x813 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x15 , 1 , 566 , 566 , // 566 - nl-be
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x9a55d42, 1 , 567 , 240 , // 567 - nl-bq
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x111 , 1 , 568 , 240 , // 568 - nl-cw
+ 0x413 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xb0 , 1 , 569 , 569 , // 569 - nl-nl
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xb5 , 1 , 570 , 240 , // 570 - nl-sr
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x78f7, 1 , 571 , 240 , // 571 - nl-sx
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x31 , 1 , 573 , 240 , // 572 - nmg
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x31 , 1 , 573 , 240 , // 573 - nmg-cm
+ 0x7814 , 0x4e4 , 0x352 , 0x2710, 0x4f35, 0xb1 , 1 , 575 , 575 , // 574 - nn
+ 0x814 , 0x4e4 , 0x352 , 0x2710, 0x4f35, 0xb1 , 1 , 575 , 575 , // 575 - nn-no
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x31 , 1 , 577 , 240 , // 576 - nnh
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x31 , 1 , 577 , 240 , // 577 - nnh-cm
+ 0x14 , 0x4e4 , 0x352 , 0x2710, 0x4f35, 0xb1 , 1 , 554 , 554 , // 578 - no
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x64 , 2 , 580 , 143 , // 579 - nqo
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x64 , 2 , 580 , 143 , // 580 - nqo-gn
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xd1 , 1 , 582 , 240 , // 581 - nr
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xd1 , 1 , 582 , 240 , // 582 - nr-za
+ 0x6c , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xd1 , 1 , 584 , 584 , // 583 - nso
+ 0x46c , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xd1 , 1 , 584 , 584 , // 584 - nso-za
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x114 , 1 , 586 , 240 , // 585 - nus
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x114 , 1 , 586 , 240 , // 586 - nus-ss
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xf0 , 1 , 588 , 240 , // 587 - nyn
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xf0 , 1 , 588 , 240 , // 588 - nyn-ug
+ 0x82 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x54 , 1 , 590 , 590 , // 589 - oc
+ 0x482 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x54 , 1 , 590 , 590 , // 590 - oc-fr
+ 0x72 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x49 , 1 , 592 , 240 , // 591 - om
+ 0x472 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x49 , 1 , 592 , 240 , // 592 - om-et
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x81 , 1 , 593 , 240 , // 593 - om-ke
+ 0x48 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 595 , 143 , // 594 - or
+ 0x448 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 595 , 143 , // 595 - or-in
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x58 , 1 , 597 , 240 , // 596 - os
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x58 , 1 , 597 , 240 , // 597 - os-ge
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xcb , 1 , 598 , 240 , // 598 - os-ru
+ 0x46 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 602 , 143 , // 599 - pa
+ 0x7c46 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0xbe , 2 , 601 , 143 , // 600 - pa-arab
+ 0x846 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0xbe , 2 , 601 , 143 , // 601 - pa-arab-pk
+ 0x446 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 602 , 143 , // 602 - pa-in
+ 0x79 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x993248, 1 , 604 , 145 , // 603 - pap
+ 0x479 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x993248, 1 , 604 , 145 , // 604 - pap-029
+ 0x15 , 0x4e2 , 0x354 , 0x272d, 0x5190, 0xbf , 1 , 606 , 606 , // 605 - pl
+ 0x415 , 0x4e2 , 0x354 , 0x272d, 0x5190, 0xbf , 1 , 606 , 606 , // 606 - pl-pl
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x989e, 1 , 608 , 240 , // 607 - prg
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x989e, 1 , 608 , 240 , // 608 - prg-001
+ 0x8c , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x3 , 2 , 610 , 143 , // 609 - prs
+ 0x48c , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x3 , 2 , 610 , 143 , // 610 - prs-af
+ 0x63 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x3 , 2 , 612 , 143 , // 611 - ps
+ 0x463 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x3 , 2 , 612 , 143 , // 612 - ps-af
+ 0x16 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x20 , 1 , 615 , 615 , // 613 - pt
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x9 , 1 , 614 , 240 , // 614 - pt-ao
+ 0x416 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x20 , 1 , 615 , 615 , // 615 - pt-br
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xdf , 1 , 616 , 240 , // 616 - pt-ch
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x39 , 1 , 617 , 240 , // 617 - pt-cv
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x45 , 1 , 618 , 240 , // 618 - pt-gq
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xc4 , 1 , 619 , 240 , // 619 - pt-gw
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x93 , 1 , 620 , 240 , // 620 - pt-lu
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x97 , 1 , 621 , 240 , // 621 - pt-mo
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xa8 , 1 , 622 , 240 , // 622 - pt-mz
+ 0x816 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xc1 , 1 , 623 , 623 , // 623 - pt-pt
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xe9 , 1 , 624 , 240 , // 624 - pt-st
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x6f60e7, 1 , 625 , 240 , // 625 - pt-tl
+ 0x901 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x7c , 1 , 626 , 190 , // 626 - qps-latn-x-sh
+ 0x501 , 0x4e2 , 0x354 , 0x272d, 0x5190, 0xf4 , 1 , 627 , 627 , // 627 - qps-ploc
+ 0x5fe , 0x3a4 , 0x3a4 , 0x2711, 0x4f42, 0x7a , 1 , 628 , 628 , // 628 - qps-ploca
+ 0x9ff , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0xcd , 0 , 629 , 143 , // 629 - qps-plocm
+ 0x86 , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0x63 , 1 , 632 , 632 , // 630 - quc
+ 0x7c86 , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0x63 , 1 , 632 , 632 , // 631 - quc-latn
+ 0x486 , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0x63 , 1 , 632 , 632 , // 632 - quc-latn-gt
+ 0x6b , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0x1a , 1 , 634 , 634 , // 633 - quz
+ 0x46b , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0x1a , 1 , 634 , 634 , // 634 - quz-bo
+ 0x86b , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0x42 , 1 , 635 , 635 , // 635 - quz-ec
+ 0xc6b , 0x4e4 , 0x352 , 0x2710, 0x4f3c, 0xbb , 1 , 636 , 636 , // 636 - quz-pe
+ 0x17 , 0x4e4 , 0x352 , 0x2710, 0x4f31, 0xdf , 1 , 638 , 638 , // 637 - rm
+ 0x417 , 0x4e4 , 0x352 , 0x2710, 0x4f31, 0xdf , 1 , 638 , 638 , // 638 - rm-ch
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x26 , 1 , 640 , 240 , // 639 - rn
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x26 , 1 , 640 , 240 , // 640 - rn-bi
+ 0x18 , 0x4e2 , 0x354 , 0x272d, 0x5190, 0xc8 , 1 , 643 , 643 , // 641 - ro
+ 0x818 , 0x4e2 , 0x354 , 0x2 , 0x1f4 , 0x98 , 1 , 642 , 240 , // 642 - ro-md
+ 0x418 , 0x4e2 , 0x354 , 0x272d, 0x5190, 0xc8 , 1 , 643 , 643 , // 643 - ro-ro
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xef , 1 , 645 , 240 , // 644 - rof
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xef , 1 , 645 , 240 , // 645 - rof-tz
+ 0x19 , 0x4e3 , 0x362 , 0x2717, 0x5190, 0xcb , 1 , 651 , 651 , // 646 - ru
+ 0x1000 , 0x4e3 , 0x362 , 0x2 , 0x1f4 , 0x1d , 1 , 647 , 240 , // 647 - ru-by
+ 0x1000 , 0x4e3 , 0x362 , 0x2 , 0x1f4 , 0x82 , 1 , 648 , 240 , // 648 - ru-kg
+ 0x1000 , 0x4e3 , 0x362 , 0x2 , 0x1f4 , 0x89 , 1 , 649 , 240 , // 649 - ru-kz
+ 0x819 , 0x4e3 , 0x362 , 0x2 , 0x1f4 , 0x98 , 1 , 650 , 240 , // 650 - ru-md
+ 0x419 , 0x4e3 , 0x362 , 0x2717, 0x5190, 0xcb , 1 , 651 , 651 , // 651 - ru-ru
+ 0x1000 , 0x4e3 , 0x362 , 0x2 , 0x1f4 , 0xf1 , 1 , 652 , 240 , // 652 - ru-ua
+ 0x87 , 0x4e4 , 0x1b5 , 0x2710, 0x25 , 0xcc , 1 , 654 , 654 , // 653 - rw
+ 0x487 , 0x4e4 , 0x1b5 , 0x2710, 0x25 , 0xcc , 1 , 654 , 654 , // 654 - rw-rw
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xef , 1 , 656 , 240 , // 655 - rwk
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xef , 1 , 656 , 240 , // 656 - rwk-tz
+ 0x4f , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 658 , 143 , // 657 - sa
+ 0x44f , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 658 , 143 , // 658 - sa-in
+ 0x85 , 0x4e3 , 0x362 , 0x2717, 0x5190, 0xcb , 1 , 660 , 660 , // 659 - sah
+ 0x485 , 0x4e3 , 0x362 , 0x2717, 0x5190, 0xcb , 1 , 660 , 660 , // 660 - sah-ru
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x81 , 1 , 662 , 240 , // 661 - saq
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x81 , 1 , 662 , 240 , // 662 - saq-ke
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xef , 1 , 664 , 240 , // 663 - sbp
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xef , 1 , 664 , 240 , // 664 - sbp-tz
+ 0x59 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0xbe , 2 , 667 , 143 , // 665 - sd
+ 0x7c59 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0xbe , 2 , 667 , 143 , // 666 - sd-arab
+ 0x859 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0xbe , 2 , 667 , 143 , // 667 - sd-arab-pk
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 669 , 187 , // 668 - sd-deva
+ 0x459 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 669 , 187 , // 669 - sd-deva-in
+ 0x3b , 0x4e4 , 0x352 , 0x2710, 0x4f35, 0xb1 , 1 , 672 , 672 , // 670 - se
+ 0xc3b , 0x4e4 , 0x352 , 0x2710, 0x4f36, 0x4d , 1 , 671 , 671 , // 671 - se-fi
+ 0x43b , 0x4e4 , 0x352 , 0x2710, 0x4f35, 0xb1 , 1 , 672 , 672 , // 672 - se-no
+ 0x83b , 0x4e4 , 0x352 , 0x2710, 0x4f36, 0xdd , 1 , 673 , 673 , // 673 - se-se
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xa8 , 1 , 675 , 240 , // 674 - seh
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xa8 , 1 , 675 , 240 , // 675 - seh-mz
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x9d , 1 , 677 , 240 , // 676 - ses
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x9d , 1 , 677 , 240 , // 677 - ses-ml
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x37 , 1 , 679 , 240 , // 678 - sg
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x37 , 1 , 679 , 240 , // 679 - sg-cf
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x9f , 1 , 684 , 240 , // 680 - shi
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x9f , 1 , 682 , 240 , // 681 - shi-latn
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x9f , 1 , 682 , 240 , // 682 - shi-latn-ma
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x9f , 1 , 684 , 240 , // 683 - shi-tfng
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x9f , 1 , 684 , 240 , // 684 - shi-tfng-ma
+ 0x5b , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x2a , 1 , 686 , 143 , // 685 - si
+ 0x45b , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x2a , 1 , 686 , 143 , // 686 - si-lk
+ 0x1b , 0x4e2 , 0x354 , 0x272d, 0x5190, 0x8f , 1 , 688 , 688 , // 687 - sk
+ 0x41b , 0x4e2 , 0x354 , 0x272d, 0x5190, 0x8f , 1 , 688 , 688 , // 688 - sk-sk
+ 0x24 , 0x4e2 , 0x354 , 0x272d, 0x5190, 0xd4 , 1 , 690 , 690 , // 689 - sl
+ 0x424 , 0x4e2 , 0x354 , 0x272d, 0x5190, 0xd4 , 1 , 690 , 690 , // 690 - sl-si
+ 0x783b , 0x4e4 , 0x352 , 0x2710, 0x4f36, 0xdd , 1 , 693 , 693 , // 691 - sma
+ 0x183b , 0x4e4 , 0x352 , 0x2710, 0x4f35, 0xb1 , 1 , 692 , 692 , // 692 - sma-no
+ 0x1c3b , 0x4e4 , 0x352 , 0x2710, 0x4f36, 0xdd , 1 , 693 , 693 , // 693 - sma-se
+ 0x7c3b , 0x4e4 , 0x352 , 0x2710, 0x4f36, 0xdd , 1 , 696 , 696 , // 694 - smj
+ 0x103b , 0x4e4 , 0x352 , 0x2710, 0x4f35, 0xb1 , 1 , 695 , 695 , // 695 - smj-no
+ 0x143b , 0x4e4 , 0x352 , 0x2710, 0x4f36, 0xdd , 1 , 696 , 696 , // 696 - smj-se
+ 0x703b , 0x4e4 , 0x352 , 0x2710, 0x4f36, 0x4d , 1 , 698 , 698 , // 697 - smn
+ 0x243b , 0x4e4 , 0x352 , 0x2710, 0x4f36, 0x4d , 1 , 698 , 698 , // 698 - smn-fi
+ 0x743b , 0x4e4 , 0x352 , 0x2710, 0x4f36, 0x4d , 1 , 700 , 700 , // 699 - sms
+ 0x203b , 0x4e4 , 0x352 , 0x2710, 0x4f36, 0x4d , 1 , 700 , 700 , // 700 - sms-fi
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x108 , 1 , 703 , 240 , // 701 - sn
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x108 , 1 , 703 , 240 , // 702 - sn-latn
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x108 , 1 , 703 , 240 , // 703 - sn-latn-zw
+ 0x77 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xd8 , 1 , 708 , 240 , // 704 - so
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x3e , 1 , 705 , 240 , // 705 - so-dj
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x49 , 1 , 706 , 240 , // 706 - so-et
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x81 , 1 , 707 , 240 , // 707 - so-ke
+ 0x477 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xd8 , 1 , 708 , 240 , // 708 - so-so
+ 0x1c , 0x4e2 , 0x354 , 0x272d, 0x5190, 0x6 , 1 , 710 , 710 , // 709 - sq
+ 0x41c , 0x4e2 , 0x354 , 0x272d, 0x5190, 0x6 , 1 , 710 , 710 , // 710 - sq-al
+ 0x1000 , 0x4e2 , 0x354 , 0x272d, 0x5190, 0x4ca2, 1 , 711 , 240 , // 711 - sq-mk
+ 0x1000 , 0x4e2 , 0x354 , 0x272d, 0x5190, 0x974941, 1 , 712 , 240 , // 712 - sq-xk
+ 0x7c1a , 0x4e2 , 0x354 , 0x272d, 0x1f4 , 0x10f , 1 , 724 , 724 , // 713 - sr
+ 0x6c1a , 0x4e3 , 0x357 , 0x2717, 0x5221, 0x10f , 1 , 718 , 718 , // 714 - sr-cyrl
+ 0x1c1a , 0x4e3 , 0x357 , 0x2717, 0x5221, 0x19 , 1 , 715 , 715 , // 715 - sr-cyrl-ba
+ 0xc1a , 0x4e3 , 0x357 , 0x2717, 0x5221, 0x10d , 1 , 716 , 716 , // 716 - sr-cyrl-cs
+ 0x301a , 0x4e3 , 0x357 , 0x2717, 0x5221, 0x10e , 1 , 717 , 717 , // 717 - sr-cyrl-me
+ 0x281a , 0x4e3 , 0x357 , 0x2717, 0x5221, 0x10f , 1 , 718 , 718 , // 718 - sr-cyrl-rs
+ 0x1000 , 0x4e3 , 0x357 , 0x2717, 0x5221, 0x974941, 1 , 719 , 240 , // 719 - sr-cyrl-xk
+ 0x701a , 0x4e2 , 0x354 , 0x272d, 0x1f4 , 0x10f , 1 , 724 , 724 , // 720 - sr-latn
+ 0x181a , 0x4e2 , 0x354 , 0x2762, 0x366 , 0x19 , 1 , 721 , 721 , // 721 - sr-latn-ba
+ 0x81a , 0x4e2 , 0x354 , 0x272d, 0x1f4 , 0x10d , 1 , 722 , 722 , // 722 - sr-latn-cs
+ 0x2c1a , 0x4e2 , 0x354 , 0x272d, 0x1f4 , 0x10e , 1 , 723 , 723 , // 723 - sr-latn-me
+ 0x241a , 0x4e2 , 0x354 , 0x272d, 0x1f4 , 0x10f , 1 , 724 , 724 , // 724 - sr-latn-rs
+ 0x1000 , 0x4e2 , 0x354 , 0x272d, 0x1f4 , 0x974941, 1 , 725 , 240 , // 725 - sr-latn-xk
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xd1 , 1 , 728 , 240 , // 726 - ss
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x104 , 1 , 727 , 240 , // 727 - ss-sz
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xd1 , 1 , 728 , 240 , // 728 - ss-za
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x47 , 1 , 730 , 240 , // 729 - ssy
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x47 , 1 , 730 , 240 , // 730 - ssy-er
+ 0x30 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xd1 , 1 , 733 , 240 , // 731 - st
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x92 , 1 , 732 , 240 , // 732 - st-ls
+ 0x430 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xd1 , 1 , 733 , 240 , // 733 - st-za
+ 0x1d , 0x4e4 , 0x352 , 0x2710, 0x4f36, 0xdd , 1 , 737 , 737 , // 734 - sv
+ 0x1000 , 0x4e4 , 0x352 , 0x2710, 0x4f36, 0x9906f5, 1 , 735 , 240 , // 735 - sv-ax
+ 0x81d , 0x4e4 , 0x352 , 0x2710, 0x4f36, 0x4d , 1 , 736 , 736 , // 736 - sv-fi
+ 0x41d , 0x4e4 , 0x352 , 0x2710, 0x4f36, 0xdd , 1 , 737 , 737 , // 737 - sv-se
+ 0x41 , 0x4e4 , 0x1b5 , 0x2710, 0x1f4 , 0x81 , 1 , 740 , 740 , // 738 - sw
+ 0x1000 , 0x4e4 , 0x1b5 , 0x2710, 0x1f4 , 0x2c , 1 , 739 , 740 , // 739 - sw-cd
+ 0x441 , 0x4e4 , 0x1b5 , 0x2710, 0x1f4 , 0x81 , 1 , 740 , 740 , // 740 - sw-ke
+ 0x1000 , 0x4e4 , 0x1b5 , 0x2710, 0x1f4 , 0xef , 1 , 741 , 240 , // 741 - sw-tz
+ 0x1000 , 0x4e4 , 0x1b5 , 0x2710, 0x1f4 , 0xf0 , 1 , 742 , 240 , // 742 - sw-ug
+ 0x1000 , 0x0 , 0x1 , 0x0 , 0x1f4 , 0x2c , 1 , 744 , 240 , // 743 - swc
+ 0x1000 , 0x0 , 0x1 , 0x0 , 0x1f4 , 0x2c , 1 , 744 , 240 , // 744 - swc-cd
+ 0x5a , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xde , 1 , 746 , 143 , // 745 - syr
+ 0x45a , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xde , 1 , 746 , 143 , // 746 - syr-sy
+ 0x49 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 748 , 143 , // 747 - ta
+ 0x449 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 748 , 143 , // 748 - ta-in
+ 0x849 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x2a , 1 , 749 , 143 , // 749 - ta-lk
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xa7 , 1 , 750 , 240 , // 750 - ta-my
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xd7 , 1 , 751 , 240 , // 751 - ta-sg
+ 0x4a , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 753 , 143 , // 752 - te
+ 0x44a , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x71 , 1 , 753 , 143 , // 753 - te-in
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xf0 , 1 , 756 , 240 , // 754 - teo
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x81 , 1 , 755 , 240 , // 755 - teo-ke
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xf0 , 1 , 756 , 240 , // 756 - teo-ug
+ 0x28 , 0x4e3 , 0x362 , 0x2717, 0x5190, 0xe4 , 1 , 759 , 759 , // 757 - tg
+ 0x7c28 , 0x4e3 , 0x362 , 0x2717, 0x5190, 0xe4 , 1 , 759 , 759 , // 758 - tg-cyrl
+ 0x428 , 0x4e3 , 0x362 , 0x2717, 0x5190, 0xe4 , 1 , 759 , 759 , // 759 - tg-cyrl-tj
+ 0x1e , 0x36a , 0x36a , 0x2725, 0x5166, 0xe3 , 1 , 761 , 143 , // 760 - th
+ 0x41e , 0x36a , 0x36a , 0x2725, 0x5166, 0xe3 , 1 , 761 , 143 , // 761 - th-th
+ 0x73 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x47 , 1 , 763 , 143 , // 762 - ti
+ 0x873 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x47 , 1 , 763 , 143 , // 763 - ti-er
+ 0x473 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x49 , 1 , 764 , 143 , // 764 - ti-et
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x47 , 1 , 766 , 240 , // 765 - tig
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x47 , 1 , 766 , 240 , // 766 - tig-er
+ 0x42 , 0x4e2 , 0x354 , 0x272d, 0x5190, 0xee , 1 , 768 , 768 , // 767 - tk
+ 0x442 , 0x4e2 , 0x354 , 0x272d, 0x5190, 0xee , 1 , 768 , 768 , // 768 - tk-tm
+ 0x32 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xd1 , 1 , 771 , 771 , // 769 - tn
+ 0x832 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0x13 , 1 , 770 , 770 , // 770 - tn-bw
+ 0x432 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xd1 , 1 , 771 , 771 , // 771 - tn-za
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xe7 , 1 , 773 , 240 , // 772 - to
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xe7 , 1 , 773 , 240 , // 773 - to-to
+ 0x1f , 0x4e6 , 0x359 , 0x2761, 0x51a9, 0xeb , 1 , 776 , 776 , // 774 - tr
+ 0x1000 , 0x4e6 , 0x359 , 0x2761, 0x51a9, 0x3b , 1 , 775 , 240 , // 775 - tr-cy
+ 0x41f , 0x4e6 , 0x359 , 0x2761, 0x51a9, 0xeb , 1 , 776 , 776 , // 776 - tr-tr
+ 0x31 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xd1 , 1 , 778 , 240 , // 777 - ts
+ 0x431 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xd1 , 1 , 778 , 240 , // 778 - ts-za
+ 0x44 , 0x4e3 , 0x362 , 0x2717, 0x5190, 0xcb , 1 , 780 , 780 , // 779 - tt
+ 0x444 , 0x4e3 , 0x362 , 0x2717, 0x5190, 0xcb , 1 , 780 , 780 , // 780 - tt-ru
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xad , 1 , 782 , 240 , // 781 - twq
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xad , 1 , 782 , 240 , // 782 - twq-ne
+ 0x5f , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x4 , 1 , 787 , 787 , // 783 - tzm
+ 0x1000 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x9f , 1 , 785 , 240 , // 784 - tzm-arab
+ 0x45f , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x9f , 1 , 785 , 240 , // 785 - tzm-arab-ma
+ 0x7c5f , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x4 , 1 , 787 , 787 , // 786 - tzm-latn
+ 0x85f , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0x4 , 1 , 787 , 787 , // 787 - tzm-latn-dz
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x9f , 1 , 788 , 240 , // 788 - tzm-latn-ma
+ 0x785f , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x9f , 1 , 790 , 316 , // 789 - tzm-tfng
+ 0x105f , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x9f , 1 , 790 , 316 , // 790 - tzm-tfng-ma
+ 0x80 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x2d , 1 , 792 , 143 , // 791 - ug
+ 0x480 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0x2d , 1 , 792 , 143 , // 792 - ug-cn
+ 0x22 , 0x4e3 , 0x362 , 0x2721, 0x1f4 , 0xf1 , 1 , 794 , 794 , // 793 - uk
+ 0x422 , 0x4e3 , 0x362 , 0x2721, 0x1f4 , 0xf1 , 1 , 794 , 794 , // 794 - uk-ua
+ 0x20 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0xbe , 1 , 797 , 143 , // 795 - ur
+ 0x820 , 0x4e8 , 0x2d0 , 0x2 , 0x1f4 , 0x71 , 2 , 796 , 240 , // 796 - ur-in
+ 0x420 , 0x4e8 , 0x2d0 , 0x2714, 0x4fc4, 0xbe , 1 , 797 , 143 , // 797 - ur-pk
+ 0x43 , 0x4e6 , 0x359 , 0x272d, 0x1f4 , 0xf7 , 1 , 804 , 804 , // 798 - uz
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x3 , 2 , 800 , 240 , // 799 - uz-arab
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x3 , 2 , 800 , 240 , // 800 - uz-arab-af
+ 0x7843 , 0x4e3 , 0x362 , 0x2717, 0x5190, 0xf7 , 1 , 802 , 802 , // 801 - uz-cyrl
+ 0x843 , 0x4e3 , 0x362 , 0x2717, 0x5190, 0xf7 , 1 , 802 , 802 , // 802 - uz-cyrl-uz
+ 0x7c43 , 0x4e6 , 0x359 , 0x272d, 0x1f4 , 0xf7 , 1 , 804 , 804 , // 803 - uz-latn
+ 0x443 , 0x4e6 , 0x359 , 0x272d, 0x1f4 , 0xf7 , 1 , 804 , 804 , // 804 - uz-latn-uz
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x8e , 1 , 809 , 240 , // 805 - vai
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x8e , 1 , 807 , 240 , // 806 - vai-latn
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x8e , 1 , 807 , 240 , // 807 - vai-latn-lr
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x8e , 1 , 809 , 240 , // 808 - vai-vaii
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x8e , 1 , 809 , 240 , // 809 - vai-vaii-lr
+ 0x33 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xd1 , 1 , 811 , 240 , // 810 - ve
+ 0x433 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xd1 , 1 , 811 , 240 , // 811 - ve-za
+ 0x2a , 0x4ea , 0x4ea , 0x2710, 0x1f4 , 0xfb , 1 , 813 , 143 , // 812 - vi
+ 0x42a , 0x4ea , 0x4ea , 0x2710, 0x1f4 , 0xfb , 1 , 813 , 143 , // 813 - vi-vn
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x989e, 1 , 815 , 240 , // 814 - vo
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x989e, 1 , 815 , 240 , // 815 - vo-001
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xef , 1 , 817 , 240 , // 816 - vun
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xef , 1 , 817 , 240 , // 817 - vun-tz
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xdf , 1 , 819 , 240 , // 818 - wae
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xdf , 1 , 819 , 240 , // 819 - wae-ch
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x49 , 1 , 821 , 240 , // 820 - wal
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x49 , 1 , 821 , 240 , // 821 - wal-et
+ 0x88 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0xd2 , 1 , 823 , 823 , // 822 - wo
+ 0x488 , 0x4e4 , 0x352 , 0x2710, 0x4f49, 0xd2 , 1 , 823 , 823 , // 823 - wo-sn
+ 0x1007f, 0x4e4 , 0x1b5 , 0x2710, 0x25 , 0xf4 , 1 , -1 , -1 , // 824 - x-iv_mathan
+ 0x34 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xd1 , 1 , 826 , 826 , // 825 - xh
+ 0x434 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xd1 , 1 , 826 , 826 , // 826 - xh-za
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xf0 , 1 , 828 , 240 , // 827 - xog
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0xf0 , 1 , 828 , 240 , // 828 - xog-ug
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x31 , 1 , 830 , 240 , // 829 - yav
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x31 , 1 , 830 , 240 , // 830 - yav-cm
+ 0x3d , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x989e, 1 , 832 , 240 , // 831 - yi
+ 0x43d , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x989e, 1 , 832 , 240 , // 832 - yi-001
+ 0x6a , 0x4e4 , 0x1b5 , 0x2710, 0x25 , 0xaf , 1 , 835 , 835 , // 833 - yo
+ 0x1000 , 0x4e4 , 0x1b5 , 0x2710, 0x1f4 , 0x1c , 1 , 834 , 240 , // 834 - yo-bj
+ 0x46a , 0x4e4 , 0x1b5 , 0x2710, 0x25 , 0xaf , 1 , 835 , 835 , // 835 - yo-ng
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x68 , 1 , 837 , 240 , // 836 - yue
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x68 , 1 , 837 , 240 , // 837 - yue-hk
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x9f , 1 , 840 , 316 , // 838 - zgh
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x9f , 1 , 840 , 316 , // 839 - zgh-tfng
+ 0x1000 , 0x0 , 0x1 , 0x2 , 0x1f4 , 0x9f , 1 , 840 , 316 , // 840 - zgh-tfng-ma
+ 0x7804 , 0x3a8 , 0x3a8 , 0x2718, 0x1f4 , 0x2d , 1 , 844 , 844 , // 841 - zh
+ 0x4 , 0x3a8 , 0x3a8 , 0x0 , 0x1f4 , 0x2d , 1 , 844 , 844 , // 842 - zh-chs
+ 0x7c04 , 0x3b6 , 0x3b6 , 0x0 , 0x1f4 , 0x68 , 1 , 851 , 851 , // 843 - zh-cht
+ 0x804 , 0x3a8 , 0x3a8 , 0x2718, 0x1f4 , 0x2d , 1 , 844 , 844 , // 844 - zh-cn
+ 0x50804, 0x3a8 , 0x3a8 , 0x2718, 0x1f4 , 0x2d , 1 , 844 , 844 , // 845 - zh-cn_phoneb
+ 0x20804, 0x3a8 , 0x3a8 , 0x2718, 0x1f4 , 0x2d , 1 , 844 , 844 , // 846 - zh-cn_stroke
+ 0x4 , 0x3a8 , 0x3a8 , 0x2718, 0x1f4 , 0x2d , 1 , 844 , 844 , // 847 - zh-hans
+ 0x1000 , 0x3a8 , 0x3a8 , 0x2718, 0x1f4 , 0x68 , 1 , 848 , 240 , // 848 - zh-hans-hk
+ 0x1000 , 0x3a8 , 0x3a8 , 0x2718, 0x1f4 , 0x97 , 1 , 849 , 240 , // 849 - zh-hans-mo
+ 0x7c04 , 0x3b6 , 0x3b6 , 0x2712, 0x1f4 , 0x68 , 1 , 851 , 851 , // 850 - zh-hant
+ 0xc04 , 0x3b6 , 0x3b6 , 0x2712, 0x1f4 , 0x68 , 1 , 851 , 851 , // 851 - zh-hk
+ 0x40c04, 0x3b6 , 0x3b6 , 0x2712, 0x1f4 , 0x68 , 1 , 851 , 851 , // 852 - zh-hk_radstr
+ 0x1404 , 0x3b6 , 0x3b6 , 0x2712, 0x1f4 , 0x97 , 1 , 853 , 853 , // 853 - zh-mo
+ 0x41404, 0x3b6 , 0x3b6 , 0x2712, 0x1f4 , 0x97 , 1 , 853 , 853 , // 854 - zh-mo_radstr
+ 0x21404, 0x3b6 , 0x3b6 , 0x2712, 0x1f4 , 0x97 , 1 , 853 , 853 , // 855 - zh-mo_stroke
+ 0x1004 , 0x3a8 , 0x3a8 , 0x2718, 0x1f4 , 0xd7 , 1 , 856 , 856 , // 856 - zh-sg
+ 0x51004, 0x3a8 , 0x3a8 , 0x2718, 0x1f4 , 0xd7 , 1 , 856 , 856 , // 857 - zh-sg_phoneb
+ 0x21004, 0x3a8 , 0x3a8 , 0x2718, 0x1f4 , 0xd7 , 1 , 856 , 856 , // 858 - zh-sg_stroke
+ 0x404 , 0x3b6 , 0x3b6 , 0x2712, 0x1f4 , 0xed , 1 , 859 , 859 , // 859 - zh-tw
+ 0x30404, 0x3b6 , 0x3b6 , 0x2712, 0x1f4 , 0xed , 1 , 859 , 859 , // 860 - zh-tw_pronun
+ 0x40404, 0x3b6 , 0x3b6 , 0x2712, 0x1f4 , 0xed , 1 , 859 , 859 , // 861 - zh-tw_radstr
+ 0x35 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xd1 , 1 , 863 , 863 , // 862 - zu
+ 0x435 , 0x4e4 , 0x352 , 0x2710, 0x1f4 , 0xd1 , 1 , 863 , 863 , // 863 - zu-za
+ };
+
+ // s_lcids list all supported lcids. used to binary search and we use the index of the matched lcid to
+ // get the index in s_localeNamesIndices using s_lcidToCultureNameIndices
+ private static readonly int[] s_lcids = new int[]
+ {
+ // Lcid , index - index in c_localeNames
+ 0x1 , // 0 - 52
+ 0x2 , // 1 - 301
+ 0x3 , // 2 - 421
+ 0x4 , // 3 - 4139
+ 0x5 , // 4 - 502
+ 0x6 , // 5 - 523
+ 0x7 , // 6 - 544
+ 0x8 , // 7 - 664
+ 0x9 , // 8 - 676
+ 0xa , // 9 - 1214
+ 0xb , // 10 - 1423
+ 0xc , // 11 - 1451
+ 0xd , // 12 - 1825
+ 0xe , // 13 - 1860
+ 0xf , // 14 - 1929
+ 0x10 , // 15 - 1936
+ 0x11 , // 16 - 1989
+ 0x12 , // 17 - 2179
+ 0x13 , // 18 - 2685
+ 0x14 , // 19 - 2747
+ 0x15 , // 20 - 2864
+ 0x16 , // 21 - 2897
+ 0x17 , // 22 - 3041
+ 0x18 , // 23 - 3055
+ 0x19 , // 24 - 3076
+ 0x1a , // 25 - 1839
+ 0x1b , // 26 - 3284
+ 0x1c , // 27 - 3387
+ 0x1d , // 28 - 3553
+ 0x1e , // 29 - 3673
+ 0x1f , // 30 - 3727
+ 0x20 , // 31 - 3847
+ 0x21 , // 32 - 1908
+ 0x22 , // 33 - 3840
+ 0x23 , // 34 - 276
+ 0x24 , // 35 - 3291
+ 0x25 , // 36 - 1354
+ 0x26 , // 37 - 2429
+ 0x27 , // 38 - 2397
+ 0x28 , // 39 - 3654
+ 0x29 , // 40 - 1377
+ 0x2a , // 41 - 3960
+ 0x2b , // 42 - 1879
+ 0x2c , // 43 - 224
+ 0x2d , // 44 - 1361
+ 0x2e , // 45 - 1851
+ 0x2f , // 46 - 2501
+ 0x30 , // 47 - 3541
+ 0x31 , // 48 - 3739
+ 0x32 , // 49 - 3708
+ 0x33 , // 50 - 3953
+ 0x34 , // 51 - 4020
+ 0x35 , // 52 - 4277
+ 0x36 , // 53 - 17
+ 0x37 , // 54 - 2062
+ 0x38 , // 55 - 1439
+ 0x39 , // 56 - 1832
+ 0x3a , // 57 - 2598
+ 0x3b , // 58 - 3194
+ 0x3c , // 59 - 1705
+ 0x3d , // 60 - 4045
+ 0x3e , // 61 - 2581
+ 0x3f , // 62 - 2133
+ 0x40 , // 63 - 2306
+ 0x41 , // 64 - 3570
+ 0x42 , // 65 - 3701
+ 0x43 , // 66 - 3859
+ 0x44 , // 67 - 3746
+ 0x45 , // 68 - 336
+ 0x46 , // 69 - 2830
+ 0x47 , // 70 - 1754
+ 0x48 , // 71 - 2811
+ 0x49 , // 72 - 3610
+ 0x4a , // 73 - 3632
+ 0x4b , // 74 - 2172
+ 0x4c , // 75 - 2508
+ 0x4d , // 76 - 199
+ 0x4e , // 77 - 2574
+ 0x4f , // 78 - 3124
+ 0x50 , // 79 - 2515
+ 0x51 , // 80 - 348
+ 0x52 , // 81 - 516
+ 0x53 , // 82 - 2165
+ 0x54 , // 83 - 2375
+ 0x55 , // 84 - 2614
+ 0x56 , // 85 - 1719
+ 0x57 , // 86 - 2191
+ 0x58 , // 87 - 2556
+ 0x59 , // 88 - 3158
+ 0x5a , // 89 - 3601
+ 0x5b , // 90 - 3277
+ 0x5c , // 91 - 473
+ 0x5d , // 92 - 1953
+ 0x5e , // 93 - 45
+ 0x5f , // 94 - 3762
+ 0x60 , // 95 - 2207
+ 0x61 , // 96 - 2673
+ 0x62 , // 97 - 1698
+ 0x63 , // 98 - 2890
+ 0x64 , // 99 - 1430
+ 0x65 , // 100 - 620
+ 0x66 , // 101 - 308
+ 0x67 , // 102 - 1384
+ 0x68 , // 103 - 1777
+ 0x69 , // 104 - 1899
+ 0x6a , // 105 - 4053
+ 0x6b , // 106 - 3020
+ 0x6c , // 107 - 2765
+ 0x6d , // 108 - 260
+ 0x6e , // 109 - 2330
+ 0x6f , // 110 - 2149
+ 0x70 , // 111 - 1915
+ 0x71 , // 112 - 2200
+ 0x72 , // 113 - 2799
+ 0x73 , // 114 - 3680
+ 0x74 , // 115 - 1726
+ 0x75 , // 116 - 1816
+ 0x76 , // 117 - 2313
+ 0x77 , // 118 - 3365
+ 0x78 , // 119 - 1922
+ 0x79 , // 120 - 2854
+ 0x7a , // 121 - 190
+ 0x7c , // 122 - 2565
+ 0x7e , // 123 - 360
+ 0x80 , // 124 - 3833
+ 0x81 , // 125 - 2494
+ 0x82 , // 126 - 2792
+ 0x83 , // 127 - 495
+ 0x84 , // 128 - 1733
+ 0x85 , // 129 - 3131
+ 0x86 , // 130 - 2998
+ 0x87 , // 131 - 3108
+ 0x88 , // 132 - 4002
+ 0x8c , // 133 - 2881
+ 0x91 , // 134 - 1712
+ 0x92 , // 135 - 2270
+ 0x401 , // 136 - 150
+ 0x402 , // 137 - 303
+ 0x403 , // 138 - 428
+ 0x404 , // 139 - 4248
+ 0x405 , // 140 - 504
+ 0x406 , // 141 - 525
+ 0x407 , // 142 - 561
+ 0x408 , // 143 - 671
+ 0x409 , // 144 - 1161
+ 0x40a , // 145 - 1272
+ 0x40b , // 146 - 1425
+ 0x40c , // 147 - 1529
+ 0x40d , // 148 - 1827
+ 0x40e , // 149 - 1862
+ 0x40f , // 150 - 1931
+ 0x410 , // 151 - 1943
+ 0x411 , // 152 - 1991
+ 0x412 , // 153 - 2186
+ 0x413 , // 154 - 2707
+ 0x414 , // 155 - 2641
+ 0x415 , // 156 - 2866
+ 0x416 , // 157 - 2904
+ 0x417 , // 158 - 3043
+ 0x418 , // 159 - 3062
+ 0x419 , // 160 - 3098
+ 0x41a , // 161 - 1846
+ 0x41b , // 162 - 3286
+ 0x41c , // 163 - 3389
+ 0x41d , // 164 - 3565
+ 0x41e , // 165 - 3675
+ 0x41f , // 166 - 3734
+ 0x420 , // 167 - 3854
+ 0x421 , // 168 - 1910
+ 0x422 , // 169 - 3842
+ 0x423 , // 170 - 278
+ 0x424 , // 171 - 3293
+ 0x425 , // 172 - 1356
+ 0x426 , // 173 - 2431
+ 0x427 , // 174 - 2399
+ 0x428 , // 175 - 3663
+ 0x429 , // 176 - 1379
+ 0x42a , // 177 - 3962
+ 0x42b , // 178 - 1881
+ 0x42c , // 179 - 250
+ 0x42d , // 180 - 1363
+ 0x42e , // 181 - 1854
+ 0x42f , // 182 - 2503
+ 0x430 , // 183 - 3548
+ 0x431 , // 184 - 3741
+ 0x432 , // 185 - 3715
+ 0x433 , // 186 - 3955
+ 0x434 , // 187 - 4022
+ 0x435 , // 188 - 4279
+ 0x436 , // 189 - 24
+ 0x437 , // 190 - 2064
+ 0x438 , // 191 - 1446
+ 0x439 , // 192 - 1834
+ 0x43a , // 193 - 2600
+ 0x43b , // 194 - 3201
+ 0x43d , // 195 - 4047
+ 0x43e , // 196 - 2588
+ 0x43f , // 197 - 2135
+ 0x440 , // 198 - 2308
+ 0x441 , // 199 - 3577
+ 0x442 , // 200 - 3703
+ 0x443 , // 201 - 3902
+ 0x444 , // 202 - 3748
+ 0x445 , // 203 - 343
+ 0x446 , // 204 - 2849
+ 0x447 , // 205 - 1756
+ 0x448 , // 206 - 2813
+ 0x449 , // 207 - 3612
+ 0x44a , // 208 - 3634
+ 0x44b , // 209 - 2174
+ 0x44c , // 210 - 2510
+ 0x44d , // 211 - 201
+ 0x44e , // 212 - 2576
+ 0x44f , // 213 - 3126
+ 0x450 , // 214 - 2524
+ 0x451 , // 215 - 350
+ 0x452 , // 216 - 518
+ 0x453 , // 217 - 2167
+ 0x454 , // 218 - 2377
+ 0x455 , // 219 - 2616
+ 0x456 , // 220 - 1721
+ 0x457 , // 221 - 2194
+ 0x458 , // 222 - 2559
+ 0x459 , // 223 - 3184
+ 0x45a , // 224 - 3604
+ 0x45b , // 225 - 3279
+ 0x45c , // 226 - 484
+ 0x45d , // 227 - 1962
+ 0x45e , // 228 - 47
+ 0x45f , // 229 - 3773
+ 0x460 , // 230 - 2209
+ 0x461 , // 231 - 2680
+ 0x462 , // 232 - 1700
+ 0x463 , // 233 - 2892
+ 0x464 , // 234 - 1433
+ 0x465 , // 235 - 622
+ 0x466 , // 236 - 311
+ 0x467 , // 237 - 1418
+ 0x468 , // 238 - 1806
+ 0x469 , // 239 - 1902
+ 0x46a , // 240 - 4060
+ 0x46b , // 241 - 3023
+ 0x46c , // 242 - 2768
+ 0x46d , // 243 - 262
+ 0x46e , // 244 - 2332
+ 0x46f , // 245 - 2151
+ 0x470 , // 246 - 1917
+ 0x471 , // 247 - 2202
+ 0x472 , // 248 - 2801
+ 0x473 , // 249 - 3687
+ 0x474 , // 250 - 1728
+ 0x475 , // 251 - 1819
+ 0x476 , // 252 - 2315
+ 0x477 , // 253 - 3382
+ 0x478 , // 254 - 1924
+ 0x479 , // 255 - 2857
+ 0x47a , // 256 - 193
+ 0x47c , // 257 - 2568
+ 0x47e , // 258 - 362
+ 0x480 , // 259 - 3835
+ 0x481 , // 260 - 2496
+ 0x482 , // 261 - 2794
+ 0x483 , // 262 - 497
+ 0x484 , // 263 - 1742
+ 0x485 , // 264 - 3134
+ 0x486 , // 265 - 3009
+ 0x487 , // 266 - 3110
+ 0x488 , // 267 - 4004
+ 0x48c , // 268 - 2884
+ 0x491 , // 269 - 1714
+ 0x492 , // 270 - 2279
+ 0x501 , // 271 - 2972
+ 0x5fe , // 272 - 2980
+ 0x801 , // 273 - 95
+ 0x803 , // 274 - 433
+ 0x804 , // 275 - 4110
+ 0x807 , // 276 - 556
+ 0x809 , // 277 - 831
+ 0x80a , // 278 - 1299
+ 0x80c , // 279 - 1459
+ 0x810 , // 280 - 1938
+ 0x813 , // 281 - 2692
+ 0x814 , // 282 - 2733
+ 0x816 , // 283 - 2944
+ 0x818 , // 284 - 3057
+ 0x819 , // 285 - 3093
+ 0x81a , // 286 - 3480
+ 0x81d , // 287 - 3560
+ 0x820 , // 288 - 3849
+ 0x82c , // 289 - 233
+ 0x82e , // 290 - 605
+ 0x832 , // 291 - 3710
+ 0x83b , // 292 - 3206
+ 0x83c , // 293 - 1707
+ 0x83e , // 294 - 2583
+ 0x843 , // 295 - 3885
+ 0x845 , // 296 - 338
+ 0x846 , // 297 - 2839
+ 0x849 , // 298 - 3617
+ 0x850 , // 299 - 2536
+ 0x859 , // 300 - 3167
+ 0x85d , // 301 - 1979
+ 0x85f , // 302 - 3792
+ 0x860 , // 303 - 2233
+ 0x861 , // 304 - 2675
+ 0x867 , // 305 - 1403
+ 0x86b , // 306 - 3029
+ 0x873 , // 307 - 3682
+ 0x901 , // 308 - 2959
+ 0x9ff , // 309 - 2989
+ 0xc01 , // 310 - 80
+ 0xc04 , // 311 - 4173
+ 0xc07 , // 312 - 546
+ 0xc09 , // 313 - 716
+ 0xc0a , // 314 - 1267
+ 0xc0c , // 315 - 1484
+ 0xc1a , // 316 - 3423
+ 0xc3b , // 317 - 3196
+ 0xc50 , // 318 - 2546
+ 0xc51 , // 319 - 638
+ 0xc6b , // 320 - 3035
+ 0x1001 , // 321 - 120
+ 0x1004 , // 322 - 4219
+ 0x1007 , // 323 - 588
+ 0x1009 , // 324 - 756
+ 0x100a , // 325 - 1289
+ 0x100c , // 326 - 1504
+ 0x101a , // 327 - 1841
+ 0x103b , // 328 - 3316
+ 0x105f , // 329 - 3822
+ 0x1401 , // 330 - 75
+ 0x1404 , // 331 - 4190
+ 0x1407 , // 332 - 583
+ 0x1409 , // 333 - 1026
+ 0x140a , // 334 - 1247
+ 0x140c , // 335 - 1569
+ 0x141a , // 336 - 402
+ 0x143b , // 337 - 3322
+ 0x1801 , // 338 - 125
+ 0x1809 , // 339 - 881
+ 0x180a , // 340 - 1309
+ 0x180c , // 341 - 1579
+ 0x181a , // 342 - 3470
+ 0x183b , // 343 - 3301
+ 0x1c01 , // 344 - 180
+ 0x1c09 , // 345 - 1191
+ 0x1c0a , // 346 - 1257
+ 0x1c0c , // 347 - 1453
+ 0x1c1a , // 348 - 3413
+ 0x1c3b , // 349 - 3307
+ 0x2001 , // 350 - 135
+ 0x2009 , // 351 - 911
+ 0x200a , // 352 - 1349
+ 0x200c , // 353 - 1634
+ 0x201a , // 354 - 385
+ 0x203b , // 355 - 3340
+ 0x2401 , // 356 - 185
+ 0x2409 , // 357 - 684
+ 0x240a , // 358 - 1242
+ 0x240c , // 359 - 1489
+ 0x241a , // 360 - 3500
+ 0x243b , // 361 - 3331
+ 0x2801 , // 362 - 170
+ 0x2809 , // 363 - 751
+ 0x280a , // 364 - 1314
+ 0x280c , // 365 - 1649
+ 0x281a , // 366 - 3443
+ 0x2c01 , // 367 - 100
+ 0x2c09 , // 368 - 1136
+ 0x2c0a , // 369 - 1222
+ 0x2c0c , // 370 - 1514
+ 0x2c1a , // 371 - 3490
+ 0x3001 , // 372 - 115
+ 0x3009 , // 373 - 1201
+ 0x300a , // 374 - 1262
+ 0x300c , // 375 - 1509
+ 0x301a , // 376 - 3433
+ 0x3401 , // 377 - 110
+ 0x3409 , // 378 - 1036
+ 0x340a , // 379 - 1237
+ 0x340c , // 380 - 1594
+ 0x3801 , // 381 - 60
+ 0x3809 , // 382 - 876
+ 0x380a , // 383 - 1344
+ 0x380c , // 384 - 1574
+ 0x3c01 , // 385 - 65
+ 0x3c09 , // 386 - 871
+ 0x3c0a , // 387 - 1329
+ 0x3c0c , // 388 - 1559
+ 0x4001 , // 389 - 145
+ 0x4009 , // 390 - 896
+ 0x400a , // 391 - 1227
+ 0x4409 , // 392 - 991
+ 0x440a , // 393 - 1334
+ 0x4809 , // 394 - 1086
+ 0x480a , // 395 - 1294
+ 0x4c0a , // 396 - 1304
+ 0x500a , // 397 - 1324
+ 0x540a , // 398 - 1339
+ 0x580a , // 399 - 1216
+ 0x5c0a , // 400 - 1252
+ 0x641a , // 401 - 378
+ 0x681a , // 402 - 395
+ 0x6c1a , // 403 - 3406
+ 0x701a , // 404 - 3463
+ 0x703b , // 405 - 3328
+ 0x742c , // 406 - 226
+ 0x743b , // 407 - 3337
+ 0x7804 , // 408 - 4096
+ 0x7814 , // 409 - 2731
+ 0x781a , // 410 - 376
+ 0x782c , // 411 - 243
+ 0x783b , // 412 - 3298
+ 0x7843 , // 413 - 3878
+ 0x7850 , // 414 - 2517
+ 0x785d , // 415 - 1955
+ 0x785f , // 416 - 3814
+ 0x7c04 , // 417 - 4166
+ 0x7c14 , // 418 - 2639
+ 0x7c1a , // 419 - 3404
+ 0x7c28 , // 420 - 3656
+ 0x7c2e , // 421 - 602
+ 0x7c3b , // 422 - 3313
+ 0x7c43 , // 423 - 3895
+ 0x7c46 , // 424 - 2832
+ 0x7c50 , // 425 - 2529
+ 0x7c59 , // 426 - 3160
+ 0x7c5c , // 427 - 476
+ 0x7c5d , // 428 - 1972
+ 0x7c5f , // 429 - 3784
+ 0x7c67 , // 430 - 1396
+ 0x7c68 , // 431 - 1779
+ 0x7c86 , // 432 - 3001
+ 0x7c92 , // 433 - 2272
+ 0x1007f, // 434 - 4009
+ 0x10407, // 435 - 566
+ 0x1040e, // 436 - 1867
+ 0x10437, // 437 - 2069
+ 0x20804, // 438 - 4127
+ 0x21004, // 439 - 4236
+ 0x21404, // 440 - 4207
+ 0x30404, // 441 - 4253
+ 0x40404, // 442 - 4265
+ 0x40411, // 443 - 1996
+ 0x40c04, // 444 - 4178
+ 0x41404, // 445 - 4195
+ 0x50804, // 446 - 4115
+ 0x51004 // 447 - 4224
+ };
+ // each element in s_lcidToCultureNameIndices is index to s_localeNamesIndices
+ private static readonly int[] s_lcidToCultureNameIndices = new int[]
+ {
+ // Index to s_localeNamesIndices, index to this array - lcid - index to the c_localeNames
+ 13 , // 0 - 1 - 52
+ 64 , // 1 - 2 - 301
+ 88 , // 2 - 3 - 421
+ 847 , // 3 - 4 - 4139
+ 103 , // 4 - 5 - 502
+ 109 , // 5 - 6 - 523
+ 114 , // 6 - 7 - 544
+ 140 , // 7 - 8 - 664
+ 143 , // 8 - 9 - 676
+ 251 , // 9 - a - 1214
+ 293 , // 10 - b - 1423
+ 300 , // 11 - c - 1451
+ 377 , // 12 - d - 1825
+ 386 , // 13 - e - 1860
+ 402 , // 14 - f - 1929
+ 404 , // 15 - 10 - 1936
+ 413 , // 16 - 11 - 1989
+ 452 , // 17 - 12 - 2179
+ 564 , // 18 - 13 - 2685
+ 578 , // 19 - 14 - 2747
+ 605 , // 20 - 15 - 2864
+ 613 , // 21 - 16 - 2897
+ 637 , // 22 - 17 - 3041
+ 641 , // 23 - 18 - 3055
+ 646 , // 24 - 19 - 3076
+ 381 , // 25 - 1a - 1839
+ 687 , // 26 - 1b - 3284
+ 709 , // 27 - 1c - 3387
+ 734 , // 28 - 1d - 3553
+ 760 , // 29 - 1e - 3673
+ 774 , // 30 - 1f - 3727
+ 795 , // 31 - 20 - 3847
+ 396 , // 32 - 21 - 1908
+ 793 , // 33 - 22 - 3840
+ 58 , // 34 - 23 - 276
+ 689 , // 35 - 24 - 3291
+ 278 , // 36 - 25 - 1354
+ 506 , // 37 - 26 - 2429
+ 498 , // 38 - 27 - 2397
+ 757 , // 39 - 28 - 3654
+ 284 , // 40 - 29 - 1377
+ 812 , // 41 - 2a - 3960
+ 389 , // 42 - 2b - 1879
+ 49 , // 43 - 2c - 224
+ 280 , // 44 - 2d - 1361
+ 384 , // 45 - 2e - 1851
+ 523 , // 46 - 2f - 2501
+ 731 , // 47 - 30 - 3541
+ 777 , // 48 - 31 - 3739
+ 769 , // 49 - 32 - 3708
+ 810 , // 50 - 33 - 3953
+ 825 , // 51 - 34 - 4020
+ 862 , // 52 - 35 - 4277
+ 4 , // 53 - 36 - 17
+ 425 , // 54 - 37 - 2062
+ 297 , // 55 - 38 - 1439
+ 379 , // 56 - 39 - 1832
+ 543 , // 57 - 3a - 2598
+ 670 , // 58 - 3b - 3194
+ 352 , // 59 - 3c - 1705
+ 831 , // 60 - 3d - 4045
+ 539 , // 61 - 3e - 2581
+ 440 , // 62 - 3f - 2133
+ 476 , // 63 - 40 - 2306
+ 738 , // 64 - 41 - 3570
+ 767 , // 65 - 42 - 3701
+ 798 , // 66 - 43 - 3859
+ 779 , // 67 - 44 - 3746
+ 71 , // 68 - 45 - 336
+ 599 , // 69 - 46 - 2830
+ 364 , // 70 - 47 - 1754
+ 594 , // 71 - 48 - 2811
+ 747 , // 72 - 49 - 3610
+ 752 , // 73 - 4a - 3632
+ 450 , // 74 - 4b - 2172
+ 525 , // 75 - 4c - 2508
+ 43 , // 76 - 4d - 199
+ 537 , // 77 - 4e - 2574
+ 657 , // 78 - 4f - 3124
+ 527 , // 79 - 50 - 2515
+ 74 , // 80 - 51 - 348
+ 107 , // 81 - 52 - 516
+ 448 , // 82 - 53 - 2165
+ 493 , // 83 - 54 - 2375
+ 547 , // 84 - 55 - 2614
+ 356 , // 85 - 56 - 1719
+ 455 , // 86 - 57 - 2191
+ 533 , // 87 - 58 - 2556
+ 665 , // 88 - 59 - 3158
+ 745 , // 89 - 5a - 3601
+ 685 , // 90 - 5b - 3277
+ 98 , // 91 - 5c - 473
+ 408 , // 92 - 5d - 1953
+ 11 , // 93 - 5e - 45
+ 783 , // 94 - 5f - 3762
+ 459 , // 95 - 60 - 2207
+ 561 , // 96 - 61 - 2673
+ 350 , // 97 - 62 - 1698
+ 611 , // 98 - 63 - 2890
+ 295 , // 99 - 64 - 1430
+ 129 , // 100 - 65 - 620
+ 66 , // 101 - 66 - 308
+ 286 , // 102 - 67 - 1384
+ 370 , // 103 - 68 - 1777
+ 394 , // 104 - 69 - 1899
+ 833 , // 105 - 6a - 4053
+ 633 , // 106 - 6b - 3020
+ 583 , // 107 - 6c - 2765
+ 54 , // 108 - 6d - 260
+ 482 , // 109 - 6e - 2330
+ 444 , // 110 - 6f - 2149
+ 398 , // 111 - 70 - 1915
+ 457 , // 112 - 71 - 2200
+ 591 , // 113 - 72 - 2799
+ 762 , // 114 - 73 - 3680
+ 358 , // 115 - 74 - 1726
+ 375 , // 116 - 75 - 1816
+ 478 , // 117 - 76 - 2313
+ 704 , // 118 - 77 - 3365
+ 400 , // 119 - 78 - 1922
+ 603 , // 120 - 79 - 2854
+ 41 , // 121 - 7a - 190
+ 535 , // 122 - 7c - 2565
+ 77 , // 123 - 7e - 360
+ 791 , // 124 - 80 - 3833
+ 521 , // 125 - 81 - 2494
+ 589 , // 126 - 82 - 2792
+ 101 , // 127 - 83 - 495
+ 360 , // 128 - 84 - 1733
+ 659 , // 129 - 85 - 3131
+ 630 , // 130 - 86 - 2998
+ 653 , // 131 - 87 - 3108
+ 822 , // 132 - 88 - 4002
+ 609 , // 133 - 8c - 2881
+ 354 , // 134 - 91 - 1712
+ 470 , // 135 - 92 - 2270
+ 33 , // 136 - 401 - 150
+ 65 , // 137 - 402 - 303
+ 90 , // 138 - 403 - 428
+ 859 , // 139 - 404 - 4248
+ 104 , // 140 - 405 - 504
+ 110 , // 141 - 406 - 525
+ 118 , // 142 - 407 - 561
+ 142 , // 143 - 408 - 671
+ 240 , // 144 - 409 - 1161
+ 263 , // 145 - 40a - 1272
+ 294 , // 146 - 40b - 1425
+ 316 , // 147 - 40c - 1529
+ 378 , // 148 - 40d - 1827
+ 387 , // 149 - 40e - 1862
+ 403 , // 150 - 40f - 1931
+ 406 , // 151 - 410 - 1943
+ 414 , // 152 - 411 - 1991
+ 454 , // 153 - 412 - 2186
+ 569 , // 154 - 413 - 2707
+ 554 , // 155 - 414 - 2641
+ 606 , // 156 - 415 - 2866
+ 615 , // 157 - 416 - 2904
+ 638 , // 158 - 417 - 3043
+ 643 , // 159 - 418 - 3062
+ 651 , // 160 - 419 - 3098
+ 383 , // 161 - 41a - 1846
+ 688 , // 162 - 41b - 3286
+ 710 , // 163 - 41c - 3389
+ 737 , // 164 - 41d - 3565
+ 761 , // 165 - 41e - 3675
+ 776 , // 166 - 41f - 3734
+ 797 , // 167 - 420 - 3854
+ 397 , // 168 - 421 - 1910
+ 794 , // 169 - 422 - 3842
+ 59 , // 170 - 423 - 278
+ 690 , // 171 - 424 - 3293
+ 279 , // 172 - 425 - 1356
+ 507 , // 173 - 426 - 2431
+ 499 , // 174 - 427 - 2399
+ 759 , // 175 - 428 - 3663
+ 285 , // 176 - 429 - 1379
+ 813 , // 177 - 42a - 3962
+ 390 , // 178 - 42b - 1881
+ 53 , // 179 - 42c - 250
+ 281 , // 180 - 42d - 1363
+ 385 , // 181 - 42e - 1854
+ 524 , // 182 - 42f - 2503
+ 733 , // 183 - 430 - 3548
+ 778 , // 184 - 431 - 3741
+ 771 , // 185 - 432 - 3715
+ 811 , // 186 - 433 - 3955
+ 826 , // 187 - 434 - 4022
+ 863 , // 188 - 435 - 4279
+ 6 , // 189 - 436 - 24
+ 426 , // 190 - 437 - 2064
+ 299 , // 191 - 438 - 1446
+ 380 , // 192 - 439 - 1834
+ 544 , // 193 - 43a - 2600
+ 672 , // 194 - 43b - 3201
+ 832 , // 195 - 43d - 4047
+ 541 , // 196 - 43e - 2588
+ 441 , // 197 - 43f - 2135
+ 477 , // 198 - 440 - 2308
+ 740 , // 199 - 441 - 3577
+ 768 , // 200 - 442 - 3703
+ 804 , // 201 - 443 - 3902
+ 780 , // 202 - 444 - 3748
+ 73 , // 203 - 445 - 343
+ 602 , // 204 - 446 - 2849
+ 365 , // 205 - 447 - 1756
+ 595 , // 206 - 448 - 2813
+ 748 , // 207 - 449 - 3612
+ 753 , // 208 - 44a - 3634
+ 451 , // 209 - 44b - 2174
+ 526 , // 210 - 44c - 2510
+ 44 , // 211 - 44d - 201
+ 538 , // 212 - 44e - 2576
+ 658 , // 213 - 44f - 3126
+ 529 , // 214 - 450 - 2524
+ 75 , // 215 - 451 - 350
+ 108 , // 216 - 452 - 518
+ 449 , // 217 - 453 - 2167
+ 494 , // 218 - 454 - 2377
+ 548 , // 219 - 455 - 2616
+ 357 , // 220 - 456 - 1721
+ 456 , // 221 - 457 - 2194
+ 534 , // 222 - 458 - 2559
+ 669 , // 223 - 459 - 3184
+ 746 , // 224 - 45a - 3604
+ 686 , // 225 - 45b - 3279
+ 100 , // 226 - 45c - 484
+ 410 , // 227 - 45d - 1962
+ 12 , // 228 - 45e - 47
+ 785 , // 229 - 45f - 3773
+ 460 , // 230 - 460 - 2209
+ 563 , // 231 - 461 - 2680
+ 351 , // 232 - 462 - 1700
+ 612 , // 233 - 463 - 2892
+ 296 , // 234 - 464 - 1433
+ 130 , // 235 - 465 - 622
+ 67 , // 236 - 466 - 311
+ 292 , // 237 - 467 - 1418
+ 374 , // 238 - 468 - 1806
+ 395 , // 239 - 469 - 1902
+ 835 , // 240 - 46a - 4060
+ 634 , // 241 - 46b - 3023
+ 584 , // 242 - 46c - 2768
+ 55 , // 243 - 46d - 262
+ 483 , // 244 - 46e - 2332
+ 445 , // 245 - 46f - 2151
+ 399 , // 246 - 470 - 1917
+ 458 , // 247 - 471 - 2202
+ 592 , // 248 - 472 - 2801
+ 764 , // 249 - 473 - 3687
+ 359 , // 250 - 474 - 1728
+ 376 , // 251 - 475 - 1819
+ 479 , // 252 - 476 - 2315
+ 708 , // 253 - 477 - 3382
+ 401 , // 254 - 478 - 1924
+ 604 , // 255 - 479 - 2857
+ 42 , // 256 - 47a - 193
+ 536 , // 257 - 47c - 2568
+ 78 , // 258 - 47e - 362
+ 792 , // 259 - 480 - 3835
+ 522 , // 260 - 481 - 2496
+ 590 , // 261 - 482 - 2794
+ 102 , // 262 - 483 - 497
+ 362 , // 263 - 484 - 1742
+ 660 , // 264 - 485 - 3134
+ 632 , // 265 - 486 - 3009
+ 654 , // 266 - 487 - 3110
+ 823 , // 267 - 488 - 4004
+ 610 , // 268 - 48c - 2884
+ 355 , // 269 - 491 - 1714
+ 472 , // 270 - 492 - 2279
+ 627 , // 271 - 501 - 2972
+ 628 , // 272 - 5fe - 2980
+ 22 , // 273 - 801 - 95
+ 91 , // 274 - 803 - 433
+ 844 , // 275 - 804 - 4110
+ 117 , // 276 - 807 - 556
+ 174 , // 277 - 809 - 831
+ 267 , // 278 - 80a - 1299
+ 302 , // 279 - 80c - 1459
+ 405 , // 280 - 810 - 1938
+ 566 , // 281 - 813 - 2692
+ 575 , // 282 - 814 - 2733
+ 623 , // 283 - 816 - 2944
+ 642 , // 284 - 818 - 3057
+ 650 , // 285 - 819 - 3093
+ 722 , // 286 - 81a - 3480
+ 736 , // 287 - 81d - 3560
+ 796 , // 288 - 820 - 3849
+ 51 , // 289 - 82c - 233
+ 126 , // 290 - 82e - 605
+ 770 , // 291 - 832 - 3710
+ 673 , // 292 - 83b - 3206
+ 353 , // 293 - 83c - 1707
+ 540 , // 294 - 83e - 2583
+ 802 , // 295 - 843 - 3885
+ 72 , // 296 - 845 - 338
+ 601 , // 297 - 846 - 2839
+ 749 , // 298 - 849 - 3617
+ 531 , // 299 - 850 - 2536
+ 667 , // 300 - 859 - 3167
+ 412 , // 301 - 85d - 1979
+ 787 , // 302 - 85f - 3792
+ 463 , // 303 - 860 - 2233
+ 562 , // 304 - 861 - 2675
+ 290 , // 305 - 867 - 1403
+ 635 , // 306 - 86b - 3029
+ 763 , // 307 - 873 - 3682
+ 626 , // 308 - 901 - 2959
+ 629 , // 309 - 9ff - 2989
+ 19 , // 310 - c01 - 80
+ 851 , // 311 - c04 - 4173
+ 115 , // 312 - c07 - 546
+ 151 , // 313 - c09 - 716
+ 262 , // 314 - c0a - 1267
+ 307 , // 315 - c0c - 1484
+ 716 , // 316 - c1a - 3423
+ 671 , // 317 - c3b - 3196
+ 532 , // 318 - c50 - 2546
+ 134 , // 319 - c51 - 638
+ 636 , // 320 - c6b - 3035
+ 27 , // 321 - 1001 - 120
+ 856 , // 322 - 1004 - 4219
+ 122 , // 323 - 1007 - 588
+ 159 , // 324 - 1009 - 756
+ 265 , // 325 - 100a - 1289
+ 311 , // 326 - 100c - 1504
+ 382 , // 327 - 101a - 1841
+ 695 , // 328 - 103b - 3316
+ 790 , // 329 - 105f - 3822
+ 18 , // 330 - 1401 - 75
+ 853 , // 331 - 1404 - 4190
+ 121 , // 332 - 1407 - 583
+ 213 , // 333 - 1409 - 1026
+ 258 , // 334 - 140a - 1247
+ 324 , // 335 - 140c - 1569
+ 85 , // 336 - 141a - 402
+ 696 , // 337 - 143b - 3322
+ 28 , // 338 - 1801 - 125
+ 184 , // 339 - 1809 - 881
+ 269 , // 340 - 180a - 1309
+ 326 , // 341 - 180c - 1579
+ 721 , // 342 - 181a - 3470
+ 692 , // 343 - 183b - 3301
+ 39 , // 344 - 1c01 - 180
+ 246 , // 345 - 1c09 - 1191
+ 260 , // 346 - 1c0a - 1257
+ 301 , // 347 - 1c0c - 1453
+ 715 , // 348 - 1c1a - 3413
+ 693 , // 349 - 1c3b - 3307
+ 30 , // 350 - 2001 - 135
+ 190 , // 351 - 2009 - 911
+ 277 , // 352 - 200a - 1349
+ 337 , // 353 - 200c - 1634
+ 83 , // 354 - 201a - 385
+ 700 , // 355 - 203b - 3340
+ 40 , // 356 - 2401 - 185
+ 145 , // 357 - 2409 - 684
+ 257 , // 358 - 240a - 1242
+ 308 , // 359 - 240c - 1489
+ 724 , // 360 - 241a - 3500
+ 698 , // 361 - 243b - 3331
+ 37 , // 362 - 2801 - 170
+ 158 , // 363 - 2809 - 751
+ 270 , // 364 - 280a - 1314
+ 340 , // 365 - 280c - 1649
+ 718 , // 366 - 281a - 3443
+ 23 , // 367 - 2c01 - 100
+ 235 , // 368 - 2c09 - 1136
+ 253 , // 369 - 2c0a - 1222
+ 313 , // 370 - 2c0c - 1514
+ 723 , // 371 - 2c1a - 3490
+ 26 , // 372 - 3001 - 115
+ 248 , // 373 - 3009 - 1201
+ 261 , // 374 - 300a - 1262
+ 312 , // 375 - 300c - 1509
+ 717 , // 376 - 301a - 3433
+ 25 , // 377 - 3401 - 110
+ 215 , // 378 - 3409 - 1036
+ 256 , // 379 - 340a - 1237
+ 329 , // 380 - 340c - 1594
+ 15 , // 381 - 3801 - 60
+ 183 , // 382 - 3809 - 876
+ 276 , // 383 - 380a - 1344
+ 325 , // 384 - 380c - 1574
+ 16 , // 385 - 3c01 - 65
+ 182 , // 386 - 3c09 - 871
+ 273 , // 387 - 3c0a - 1329
+ 322 , // 388 - 3c0c - 1559
+ 32 , // 389 - 4001 - 145
+ 187 , // 390 - 4009 - 896
+ 254 , // 391 - 400a - 1227
+ 206 , // 392 - 4409 - 991
+ 274 , // 393 - 440a - 1334
+ 225 , // 394 - 4809 - 1086
+ 266 , // 395 - 480a - 1294
+ 268 , // 396 - 4c0a - 1304
+ 272 , // 397 - 500a - 1324
+ 275 , // 398 - 540a - 1339
+ 252 , // 399 - 580a - 1216
+ 259 , // 400 - 5c0a - 1252
+ 82 , // 401 - 641a - 378
+ 84 , // 402 - 681a - 395
+ 714 , // 403 - 6c1a - 3406
+ 720 , // 404 - 701a - 3463
+ 697 , // 405 - 703b - 3328
+ 50 , // 406 - 742c - 226
+ 699 , // 407 - 743b - 3337
+ 841 , // 408 - 7804 - 4096
+ 574 , // 409 - 7814 - 2731
+ 81 , // 410 - 781a - 376
+ 52 , // 411 - 782c - 243
+ 691 , // 412 - 783b - 3298
+ 801 , // 413 - 7843 - 3878
+ 528 , // 414 - 7850 - 2517
+ 409 , // 415 - 785d - 1955
+ 789 , // 416 - 785f - 3814
+ 850 , // 417 - 7c04 - 4166
+ 553 , // 418 - 7c14 - 2639
+ 713 , // 419 - 7c1a - 3404
+ 758 , // 420 - 7c28 - 3656
+ 125 , // 421 - 7c2e - 602
+ 694 , // 422 - 7c3b - 3313
+ 803 , // 423 - 7c43 - 3895
+ 600 , // 424 - 7c46 - 2832
+ 530 , // 425 - 7c50 - 2529
+ 666 , // 426 - 7c59 - 3160
+ 99 , // 427 - 7c5c - 476
+ 411 , // 428 - 7c5d - 1972
+ 786 , // 429 - 7c5f - 3784
+ 289 , // 430 - 7c67 - 1396
+ 371 , // 431 - 7c68 - 1779
+ 631 , // 432 - 7c86 - 3001
+ 471 , // 433 - 7c92 - 2272
+ 824 , // 434 - 1007f - 4009
+ 119 , // 435 - 10407 - 566
+ 388 , // 436 - 1040e - 1867
+ 427 , // 437 - 10437 - 2069
+ 846 , // 438 - 20804 - 4127
+ 858 , // 439 - 21004 - 4236
+ 855 , // 440 - 21404 - 4207
+ 860 , // 441 - 30404 - 4253
+ 861 , // 442 - 40404 - 4265
+ 415 , // 443 - 40411 - 1996
+ 852 , // 444 - 40c04 - 4178
+ 854 , // 445 - 41404 - 4195
+ 845 , // 446 - 50804 - 4115
+ 857 // 447 - 51004 - 4224
+ };
+
+ internal static string LCIDToLocaleName(int culture)
+ {
+ int left = 0;
+ int right = s_lcids.Length - 1;
+ int index;
+
+ Debug.Assert(s_lcids.Length == s_lcidToCultureNameIndices.Length);
+
+ while (left <= right)
+ {
+ index = (right + left) / 2;
+
+ if (culture == s_lcids[index])
+ {
+ int indexToLocaleNamesIndices = s_lcidToCultureNameIndices[index];
+ Debug.Assert(indexToLocaleNamesIndices < s_localeNamesIndices.Length - 1);
+
+ return c_localeNames.Substring(s_localeNamesIndices[indexToLocaleNamesIndices],
+ s_localeNamesIndices[indexToLocaleNamesIndices + 1] -
+ s_localeNamesIndices[indexToLocaleNamesIndices]);
+ }
+ else if (culture < s_lcids[index])
+ {
+ right = index - 1;
+ }
+ else
+ {
+ left = index + 1;
+ }
+ }
+
+ return null;
+ }
+
+ internal static int GetLocaleDataNumericPart(string cultureName, LocaleDataParts part)
+ {
+ int index = SearchCultureName(cultureName);
+ if (index < 0)
+ {
+ return -1;
+ }
+
+ Debug.Assert((s_localeNamesIndices.Length-1 == (s_nameIndexToNumericData.Length/NUMERIC_LOCALE_DATA_COUNT_PER_ROW)) &&
+ index < s_localeNamesIndices.Length);
+
+ return s_nameIndexToNumericData[index * NUMERIC_LOCALE_DATA_COUNT_PER_ROW + (int) part];
+ }
+
+ internal static string GetThreeLetterWindowsLangageName(string cultureName)
+ {
+ int index = SearchCultureName(cultureName);
+ if (index < 0)
+ {
+ return null;
+ }
+
+ Debug.Assert(s_localeNamesIndices.Length-1 == (c_threeLetterWindowsLanguageName.Length / 3));
+ return c_threeLetterWindowsLanguageName.Substring(index * 3, 3);
+ }
+
+ internal static string GetLocaleDataMappedCulture(string cultureName, LocaleDataParts part)
+ {
+ int indexToIndicesTable = GetLocaleDataNumericPart(cultureName, part);
+ if (indexToIndicesTable < 0)
+ {
+ return ""; // fallback to invariant
+ }
+
+ Debug.Assert(indexToIndicesTable < s_localeNamesIndices.Length-1);
+
+ return c_localeNames.Substring(s_localeNamesIndices[indexToIndicesTable],
+ s_localeNamesIndices[indexToIndicesTable+1] - s_localeNamesIndices[indexToIndicesTable]);
+ }
+
+ internal static string GetSpecificCultureName(string cultureName)
+ {
+ return GetLocaleDataMappedCulture(cultureName, LocaleDataParts.SpecificLocaleIndex);
+ }
+
+ internal static string GetConsoleUICulture(string cultureName)
+ {
+ return GetLocaleDataMappedCulture(cultureName, LocaleDataParts.ConsoleLocaleIndex);
+ }
+
+ // SearchCultureName will binary search c_localeNames using s_localeNamesIndices.
+ // return index in s_localeNamesIndices, or -1 if it fail finding any match
+ private static int SearchCultureName(string name)
+ {
+ int left = 0;
+ int right = s_localeNamesIndices.Length - 2;
+ int index;
+ int result;
+
+ Debug.Assert(s_localeNamesIndices[s_localeNamesIndices.Length - 1] == c_localeNames.Length);
+
+ name = CultureData.AnsiToLower(name);
+
+ // 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;
+
+ Debug.Assert(index < s_localeNamesIndices.Length - 1);
+ result = CompareOrdinal(name, c_localeNames, s_localeNamesIndices[index], s_localeNamesIndices[index + 1] - s_localeNamesIndices[index]);
+ if (result == 0)
+ {
+ return index;
+ }
+ else if (result < 0)
+ {
+ right = index;
+ }
+ else
+ {
+ left = index;
+ }
+ }
+
+ // Walk the remaining elements (it'll be 3 or fewer).
+ for (; left <= right; left++)
+ {
+ Debug.Assert(left < s_localeNamesIndices.Length - 1);
+ if (CompareOrdinal(name, c_localeNames, s_localeNamesIndices[left], s_localeNamesIndices[left + 1] - s_localeNamesIndices[left]) == 0)
+ {
+ return (left);
+ }
+ }
+
+ // couldn't find culture name
+ return -1;
+ }
+
+ // optimized to avoid parameters checking
+ private static int CompareOrdinal(string s1, string s2, int index, int length)
+ {
+ int count = s1.Length;
+ if (count > length)
+ count = length;
+
+ int i = 0;
+ while (i < count && s1[i] == s2[index + i])
+ i++;
+
+ if (i < count)
+ return (int)(s1[i] - s2[index + i]);
+
+ return s1.Length - length;
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/Globalization/NumberFormatInfo.cs b/src/mscorlib/corefx/System/Globalization/NumberFormatInfo.cs
index 6a25eb2c4d..813554fd21 100644
--- a/src/mscorlib/corefx/System/Globalization/NumberFormatInfo.cs
+++ b/src/mscorlib/corefx/System/Globalization/NumberFormatInfo.cs
@@ -42,8 +42,7 @@ namespace System.Globalization
//
[Serializable]
- [System.Runtime.InteropServices.ComVisible(true)]
- sealed public partial class NumberFormatInfo : IFormatProvider, ICloneable
+ sealed public class NumberFormatInfo : IFormatProvider, ICloneable
{
// invariantInfo is constant irrespective of your current culture.
private static volatile NumberFormatInfo s_invariantInfo;
@@ -84,6 +83,8 @@ namespace System.Globalization
internal int percentNegativePattern = 0;
internal int percentDecimalDigits = 2;
+ [OptionalField(VersionAdded = 2)]
+ internal int digitSubstitution = (int) DigitShapes.None;
internal bool isReadOnly = false;
@@ -130,6 +131,64 @@ namespace System.Globalization
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)
{
@@ -748,6 +807,28 @@ namespace System.Globalization
}
}
+ public string [] NativeDigits
+ {
+ get { return (String[]) nativeDigits.Clone(); }
+ set
+ {
+ VerifyWritable();
+ VerifyNativeDigits(value, "NativeDigits");
+ nativeDigits = value;
+ }
+ }
+
+ public DigitShapes DigitSubstitution
+ {
+ get { return (DigitShapes) digitSubstitution; }
+ set
+ {
+ VerifyWritable();
+ VerifyDigitSubstitution(value, "DigitSubstitution");
+ digitSubstitution = (int) value;
+ }
+ }
+
public Object GetFormat(Type formatType)
{
return formatType == typeof(NumberFormatInfo) ? this : null;
@@ -757,7 +838,7 @@ namespace System.Globalization
{
if (nfi == null)
{
- throw new ArgumentNullException("nfi");
+ throw new ArgumentNullException(nameof(nfi));
}
Contract.EndContractBlock();
if (nfi.IsReadOnly)
@@ -781,7 +862,7 @@ namespace System.Globalization
// Check for undefined flags
if ((style & InvalidNumberStyles) != 0)
{
- throw new ArgumentException(SR.Argument_InvalidNumberStyles, "style");
+ throw new ArgumentException(SR.Argument_InvalidNumberStyles, nameof(style));
}
Contract.EndContractBlock();
if ((style & NumberStyles.AllowHexSpecifier) != 0)
@@ -798,7 +879,7 @@ namespace System.Globalization
// Check for undefined flags
if ((style & InvalidNumberStyles) != 0)
{
- throw new ArgumentException(SR.Argument_InvalidNumberStyles, "style");
+ throw new ArgumentException(SR.Argument_InvalidNumberStyles, nameof(style));
}
Contract.EndContractBlock();
if ((style & NumberStyles.AllowHexSpecifier) != 0)
diff --git a/src/mscorlib/corefx/System/Globalization/PersianCalendar.cs b/src/mscorlib/corefx/System/Globalization/PersianCalendar.cs
index 57bef7eee1..b8b3da6911 100644
--- a/src/mscorlib/corefx/System/Globalization/PersianCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/PersianCalendar.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.Diagnostics;
using System.Diagnostics.Contracts;
namespace System.Globalization
@@ -65,15 +65,13 @@ namespace System.Globalization
}
}
- // Return the type of the Persian calendar.
- //
-
-
- //public override CalendarAlgorithmType AlgorithmType {
- // get {
- // return CalendarAlgorithmType.SolarCalendar;
- // }
- //}
+ public override CalendarAlgorithmType AlgorithmType
+ {
+ get
+ {
+ return CalendarAlgorithmType.SolarCalendar;
+ }
+ }
// Construct an instance of Persian calendar.
@@ -138,7 +136,7 @@ namespace System.Globalization
{
if (era != CurrentEra && era != PersianEra)
{
- throw new ArgumentOutOfRangeException("era", SR.ArgumentOutOfRange_InvalidEraValue);
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
}
@@ -148,7 +146,7 @@ namespace System.Globalization
if (year < 1 || year > MaxCalendarYear)
{
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -165,7 +163,7 @@ namespace System.Globalization
if (month > MaxCalendarMonth)
{
throw new ArgumentOutOfRangeException(
- "month",
+ nameof(month),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -176,13 +174,13 @@ namespace System.Globalization
if (month < 1 || month > 12)
{
- throw new ArgumentOutOfRangeException("month", SR.ArgumentOutOfRange_Month);
+ throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_Month);
}
}
private static int MonthFromOrdinalDay(int ordinalDay)
{
- Contract.Assert(ordinalDay <= 366);
+ Debug.Assert(ordinalDay <= 366);
int index = 0;
while (ordinalDay > DaysToMonth[index])
index++;
@@ -192,7 +190,7 @@ namespace System.Globalization
private static int DaysInPreviousMonths(int month)
{
- Contract.Assert(1 <= month && month <= 12);
+ Debug.Assert(1 <= month && month <= 12);
--month; // months are one based but for calculations use 0 based
return DaysToMonth[month];
}
@@ -223,7 +221,7 @@ namespace System.Globalization
long yearStart = CalendricalCalculationsHelper.PersianNewYearOnOrBefore(NumDays);
int y = (int)(Math.Floor(((yearStart - PersianEpoch) / CalendricalCalculationsHelper.MeanTropicalYearInDays) + 0.5)) + 1;
- Contract.Assert(y >= 1);
+ Debug.Assert(y >= 1);
if (part == DatePartYear)
{
@@ -242,16 +240,16 @@ namespace System.Globalization
}
int m = MonthFromOrdinalDay(ordinalDay);
- Contract.Assert(ordinalDay >= 1);
- Contract.Assert(m >= 1 && m <= 12);
+ Debug.Assert(ordinalDay >= 1);
+ Debug.Assert(m >= 1 && m <= 12);
if (part == DatePartMonth)
{
return m;
}
int d = ordinalDay - DaysInPreviousMonths(m);
- Contract.Assert(1 <= d);
- Contract.Assert(d <= 31);
+ Debug.Assert(1 <= d);
+ Debug.Assert(d <= 31);
//
// Calculate the Persian Day.
@@ -290,7 +288,7 @@ namespace System.Globalization
if (months < -120000 || months > 120000)
{
throw new ArgumentOutOfRangeException(
- "months",
+ nameof(months),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -387,7 +385,7 @@ namespace System.Globalization
int daysInMonth = DaysToMonth[month] - DaysToMonth[month - 1];
if ((month == MonthsPerYear) && !IsLeapYear(year))
{
- Contract.Assert(daysInMonth == 30);
+ Debug.Assert(daysInMonth == 30);
--daysInMonth;
}
return daysInMonth;
@@ -471,7 +469,7 @@ namespace System.Globalization
if (day < 1 || day > daysInMonth)
{
throw new ArgumentOutOfRangeException(
- "day",
+ nameof(day),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Day,
@@ -531,7 +529,7 @@ namespace System.Globalization
{
// BCLDebug.Log("year = " + year + ", month = " + month + ", day = " + day);
throw new ArgumentOutOfRangeException(
- "day",
+ nameof(day),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Day,
@@ -570,7 +568,7 @@ namespace System.Globalization
if (value < 99 || value > MaxCalendarYear)
{
throw new ArgumentOutOfRangeException(
- "value",
+ nameof(value),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -587,7 +585,7 @@ namespace System.Globalization
{
if (year < 0)
{
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
SR.ArgumentOutOfRange_NeedNonNegNum);
}
Contract.EndContractBlock();
@@ -600,7 +598,7 @@ namespace System.Globalization
if (year > MaxCalendarYear)
{
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
diff --git a/src/mscorlib/corefx/System/Globalization/RegionInfo.cs b/src/mscorlib/corefx/System/Globalization/RegionInfo.cs
index 0669349040..0645ded0ab 100644
--- a/src/mscorlib/corefx/System/Globalization/RegionInfo.cs
+++ b/src/mscorlib/corefx/System/Globalization/RegionInfo.cs
@@ -14,15 +14,14 @@
//
////////////////////////////////////////////////////////////////////////////
-using System;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.Serialization;
namespace System.Globalization
{
[Serializable]
- [System.Runtime.InteropServices.ComVisible(true)]
- public partial class RegionInfo
+ public class RegionInfo
{
//--------------------------------------------------------------------//
// Internal Information //
@@ -61,11 +60,11 @@ namespace System.Globalization
public RegionInfo(String name)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (name.Length == 0) //The InvariantCulture has no matching region
{
- throw new ArgumentException(SR.Argument_NoRegionInvariantCulture, "name");
+ throw new ArgumentException(SR.Argument_NoRegionInvariantCulture, nameof(name));
}
Contract.EndContractBlock();
@@ -78,16 +77,46 @@ namespace System.Globalization
throw new ArgumentException(
String.Format(
CultureInfo.CurrentCulture,
- SR.Argument_InvalidCultureName, name), "name");
+ SR.Argument_InvalidCultureName, name), nameof(name));
// Not supposed to be neutral
if (_cultureData.IsNeutralCulture)
- throw new ArgumentException(SR.Format(SR.Argument_InvalidNeutralRegionName, name), "name");
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidNeutralRegionName, name), nameof(name));
SetName(name);
}
+ [System.Security.SecuritySafeCritical] // auto-generated
+ 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;
@@ -156,7 +185,7 @@ namespace System.Globalization
{
get
{
- Contract.Assert(_name != null, "Expected RegionInfo._name to be populated already");
+ Debug.Assert(_name != null, "Expected RegionInfo._name to be populated already");
return (_name);
}
}
@@ -202,7 +231,6 @@ namespace System.Globalization
// WARNING: You need a full locale name for this to make sense.
//
////////////////////////////////////////////////////////////////////////
- [System.Runtime.InteropServices.ComVisible(false)]
public virtual String NativeName
{
get
@@ -228,6 +256,38 @@ namespace System.Globalization
////////////////////////////////////////////////////////////////////////
//
+ // 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
@@ -242,6 +302,45 @@ namespace System.Globalization
}
}
+ 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
diff --git a/src/mscorlib/corefx/System/Globalization/STUBS.cs b/src/mscorlib/corefx/System/Globalization/STUBS.cs
deleted file mode 100644
index 8c85e836d6..0000000000
--- a/src/mscorlib/corefx/System/Globalization/STUBS.cs
+++ /dev/null
@@ -1,180 +0,0 @@
-namespace System.Globalization
-{
- public abstract partial class Calendar : System.ICloneable
- {
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual int GetLeapMonth(int year) { throw new NotImplementedException(); }
- }
-
- [System.Runtime.InteropServices.ComVisible(true)]
- 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.
- }
-
- public static partial class CharUnicodeInfo
- {
- public static int GetDecimalDigitValue(char ch) { throw new NotImplementedException(); }
- public static int GetDecimalDigitValue(string s, int index) { throw new NotImplementedException(); }
- public static int GetDigitValue(char ch) { throw new NotImplementedException(); }
- public static int GetDigitValue(string s, int index) { throw new NotImplementedException(); }
- }
-
- public partial class CompareInfo : System.Runtime.Serialization.IDeserializationCallback
- {
- public int LCID { get { throw new NotImplementedException(); } }
- public static System.Globalization.CompareInfo GetCompareInfo(int culture) { throw new NotImplementedException(); }
- public static System.Globalization.CompareInfo GetCompareInfo(int culture, System.Reflection.Assembly assembly) { throw new NotImplementedException(); }
- public static System.Globalization.CompareInfo GetCompareInfo(string name, System.Reflection.Assembly assembly) { throw new NotImplementedException(); }
- public virtual System.Globalization.SortKey GetSortKey(string source) { throw new NotImplementedException(); }
- public virtual System.Globalization.SortKey GetSortKey(string source, System.Globalization.CompareOptions options) { throw new NotImplementedException(); }
- public virtual int IndexOf(string source, char value, int startIndex) { throw new NotImplementedException(); }
- public virtual int IndexOf(string source, string value, int startIndex) { throw new NotImplementedException(); }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public static bool IsSortable(char ch) { throw new NotImplementedException(); }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static bool IsSortable(string text) { throw new NotImplementedException(); }
- public virtual int LastIndexOf(string source, char value, int startIndex) { throw new NotImplementedException(); }
- public virtual int LastIndexOf(string source, string value, int startIndex) { throw new NotImplementedException(); }
- }
-
- public partial class CultureInfo : System.ICloneable, System.IFormatProvider
- {
- public CultureInfo(int culture) { throw new NotImplementedException(); }
- public CultureInfo(int culture, bool useUserOverride) { throw new NotImplementedException(); }
- public static System.Globalization.CultureInfo InstalledUICulture { get { throw new NotImplementedException(); } }
- public virtual int LCID { get { throw new NotImplementedException(); } }
- public virtual string ThreeLetterISOLanguageName { get { throw new NotImplementedException(); } }
- public virtual string ThreeLetterWindowsLanguageName { get { throw new NotImplementedException(); } }
- public void ClearCachedData() { throw new NotImplementedException(); }
- public static System.Globalization.CultureInfo CreateSpecificCulture(string name) { throw new NotImplementedException(); }
- public static System.Globalization.CultureInfo GetCultureInfo(int culture) { throw new NotImplementedException(); }
- public static System.Globalization.CultureInfo GetCultureInfo(string name, string altName) { throw new NotImplementedException(); }
- public static System.Globalization.CultureInfo GetCultureInfoByIetfLanguageTag(string name) { throw new NotImplementedException(); }
- public static System.Globalization.CultureInfo[] GetCultures(System.Globalization.CultureTypes types) { throw new NotImplementedException(); }
- }
-
- public partial class CultureNotFoundException : System.ArgumentException, System.Runtime.Serialization.ISerializable
- {
- public CultureNotFoundException(string message, int invalidCultureId, System.Exception innerException) { throw new NotImplementedException(); }
- public CultureNotFoundException(string paramName, int invalidCultureId, string message) { throw new NotImplementedException(); }
- public virtual System.Nullable<int> InvalidCultureId { get { throw new NotImplementedException(); } }
- }
-
- 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,
- }
-
- public sealed partial class DateTimeFormatInfo : System.ICloneable, System.IFormatProvider
- {
- // Can't do partial properties so add the setter for DateSeparator and TimeSeparator
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public string NativeCalendarName { get { throw new NotImplementedException(); } }
- public string[] GetAllDateTimePatterns() { throw new NotImplementedException(); }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public string GetShortestDayName(System.DayOfWeek dayOfWeek) { throw new NotImplementedException(); }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public void SetAllDateTimePatterns(string[] patterns, char format) { throw new NotImplementedException(); }
- }
-
- public enum DigitShapes
- {
- Context = 0,
- NativeNational = 2,
- None = 1,
- }
-
- public sealed partial class IdnMapping
- {
- public IdnMapping() { }
- public bool AllowUnassigned { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } }
- public bool UseStd3AsciiRules { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } }
- public override bool Equals(object obj) { throw new NotImplementedException(); }
- public string GetAscii(string unicode) { throw new NotImplementedException(); }
- public string GetAscii(string unicode, int index) { throw new NotImplementedException(); }
- public string GetAscii(string unicode, int index, int count) { throw new NotImplementedException(); }
- public override int GetHashCode() { throw new NotImplementedException(); }
- public string GetUnicode(string ascii) { throw new NotImplementedException(); }
- public string GetUnicode(string ascii, int index) { throw new NotImplementedException(); }
- public string GetUnicode(string ascii, int index, int count) { throw new NotImplementedException(); }
- }
-
- public sealed partial class NumberFormatInfo : System.ICloneable, System.IFormatProvider
- {
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public System.Globalization.DigitShapes DigitSubstitution { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public string[] NativeDigits { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } }
- }
-
- public partial class RegionInfo
- {
- public RegionInfo(int culture) { throw new NotImplementedException(); }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual string CurrencyEnglishName { get { throw new NotImplementedException(); } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual string CurrencyNativeName { get { throw new NotImplementedException(); } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual int GeoId { get { throw new NotImplementedException(); } }
- public virtual string ThreeLetterISORegionName { get { throw new NotImplementedException(); } }
- public virtual string ThreeLetterWindowsRegionName { get { throw new NotImplementedException(); } }
- }
-
- public partial class SortKey
- {
- internal SortKey() { throw new NotImplementedException(); }
- public virtual byte[] KeyData { get { throw new NotImplementedException(); } }
- public virtual string OriginalString { get { throw new NotImplementedException(); } }
- public static int Compare(System.Globalization.SortKey sortkey1, System.Globalization.SortKey sortkey2) { throw new NotImplementedException(); }
- public override bool Equals(object value) { throw new NotImplementedException(); }
- public override int GetHashCode() { throw new NotImplementedException(); }
- public override string ToString() { throw new NotImplementedException(); }
- }
-
- public sealed partial class SortVersion : System.IEquatable<System.Globalization.SortVersion>
- {
- public SortVersion(int fullVersion, System.Guid sortId) { throw new NotImplementedException(); }
- public int FullVersion { get { throw new NotImplementedException(); } }
- public System.Guid SortId { get { throw new NotImplementedException(); } }
- public bool Equals(System.Globalization.SortVersion other) { throw new NotImplementedException(); }
- public override bool Equals(object obj) { throw new NotImplementedException(); }
- public override int GetHashCode() { throw new NotImplementedException(); }
- public static bool operator ==(System.Globalization.SortVersion left, System.Globalization.SortVersion right) { throw new NotImplementedException(); }
- public static bool operator !=(System.Globalization.SortVersion left, System.Globalization.SortVersion right) { throw new NotImplementedException(); }
- }
-
- public partial class StringInfo
- {
- public string SubstringByTextElements(int startingTextElement) { throw new NotImplementedException(); }
- public string SubstringByTextElements(int startingTextElement, int lengthInTextElements) { throw new NotImplementedException(); }
- }
-
- public partial class TextInfo : System.ICloneable, System.Runtime.Serialization.IDeserializationCallback
- {
- public virtual int ANSICodePage { get { throw new NotImplementedException(); } }
- public virtual int EBCDICCodePage { get { throw new NotImplementedException(); } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public int LCID { get { throw new NotImplementedException(); } }
- public virtual int MacCodePage { get { throw new NotImplementedException(); } }
- public virtual int OEMCodePage { get { throw new NotImplementedException(); } }
- public string ToTitleCase(string str) { throw new NotImplementedException(); }
- }
-} \ No newline at end of file
diff --git a/src/mscorlib/corefx/System/Globalization/SortKey.cs b/src/mscorlib/corefx/System/Globalization/SortKey.cs
new file mode 100644
index 0000000000..fc151fa37e
--- /dev/null
+++ b/src/mscorlib/corefx/System/Globalization/SortKey.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.
+
+////////////////////////////////////////////////////////////////////////////
+//
+//
+// 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;
+
+ [System.Runtime.InteropServices.ComVisible(true)]
+ [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
new file mode 100644
index 0000000000..72aa6d6b7b
--- /dev/null
+++ b/src/mscorlib/corefx/System/Globalization/SortVersion.cs
@@ -0,0 +1,101 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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
index 102f703beb..7558002413 100644
--- a/src/mscorlib/corefx/System/Globalization/StringInfo.cs
+++ b/src/mscorlib/corefx/System/Globalization/StringInfo.cs
@@ -13,6 +13,7 @@
////////////////////////////////////////////////////////////////////////////
using System;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.Serialization;
@@ -20,10 +21,10 @@ namespace System.Globalization
{
[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
- public partial class StringInfo
+ public class StringInfo
{
[OptionalField(VersionAdded = 2)]
- private String _str;
+ private string _str;
[NonSerialized]
private int[] _indexes;
@@ -32,7 +33,7 @@ namespace System.Globalization
public StringInfo() : this("") { }
// Primary, useful constructor
- public StringInfo(String value)
+ public StringInfo(string value)
{
this.String = value;
}
@@ -85,7 +86,7 @@ namespace System.Globalization
}
}
- public String String
+ public string String
{
get
{
@@ -119,7 +120,61 @@ namespace System.Globalization
}
}
- public static String GetNextTextElement(String str)
+ 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));
}
@@ -157,10 +212,10 @@ namespace System.Globalization
//
////////////////////////////////////////////////////////////////////////
- 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)
{
- Contract.Assert(index >= 0 && len >= 0, "StringInfo.GetCurrentTextElementLen() : index = " + index + ", len = " + len);
- Contract.Assert(index < len, "StringInfo.GetCurrentTextElementLen() : index = " + index + ", len = " + len);
+ 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.
@@ -220,14 +275,14 @@ namespace System.Globalization
// 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)
{
- throw new ArgumentNullException("str");
+ throw new ArgumentNullException(nameof(str));
}
Contract.EndContractBlock();
@@ -238,7 +293,7 @@ namespace System.Globalization
{
return (String.Empty);
}
- throw new ArgumentOutOfRangeException("index", SR.ArgumentOutOfRange_Index);
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
}
int charLen;
@@ -246,26 +301,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)
{
- throw new ArgumentNullException("str");
+ throw new ArgumentNullException(nameof(str));
}
Contract.EndContractBlock();
int len = str.Length;
if (index < 0 || (index > len))
{
- throw new ArgumentOutOfRangeException("index", SR.ArgumentOutOfRange_Index);
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
}
return (new TextElementEnumerator(str, index, len));
@@ -283,11 +338,11 @@ 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("str");
+ throw new ArgumentNullException(nameof(str));
}
Contract.EndContractBlock();
diff --git a/src/mscorlib/corefx/System/Globalization/TaiwanCalendar.cs b/src/mscorlib/corefx/System/Globalization/TaiwanCalendar.cs
index 89b2e4a41d..36edd5b2fd 100644
--- a/src/mscorlib/corefx/System/Globalization/TaiwanCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/TaiwanCalendar.cs
@@ -83,6 +83,15 @@ namespace System.Globalization
}
}
+ [System.Runtime.InteropServices.ComVisible(false)]
+ public override CalendarAlgorithmType AlgorithmType
+ {
+ get
+ {
+ return CalendarAlgorithmType.SolarCalendar;
+ }
+ }
+
// Return the type of the Taiwan calendar.
//
@@ -260,7 +269,7 @@ namespace System.Globalization
{
if (year <= 0)
{
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
SR.ArgumentOutOfRange_NeedPosNum);
}
Contract.EndContractBlock();
@@ -268,7 +277,7 @@ namespace System.Globalization
if (year > helper.MaxYear)
{
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
diff --git a/src/mscorlib/corefx/System/Globalization/TextElementEnumerator.cs b/src/mscorlib/corefx/System/Globalization/TextElementEnumerator.cs
index 487ef11130..c0ffc65307 100644
--- a/src/mscorlib/corefx/System/Globalization/TextElementEnumerator.cs
+++ b/src/mscorlib/corefx/System/Globalization/TextElementEnumerator.cs
@@ -11,7 +11,7 @@
////////////////////////////////////////////////////////////////////////////
using System.Collections;
-using System.Diagnostics.Contracts;
+using System.Diagnostics;
using System.Runtime.Serialization;
namespace System.Globalization
@@ -42,9 +42,9 @@ namespace System.Globalization
internal TextElementEnumerator(String str, int startIndex, int strLen)
{
- Contract.Assert(str != null, "TextElementEnumerator(): str != null");
- Contract.Assert(startIndex >= 0 && strLen >= 0, "TextElementEnumerator(): startIndex >= 0 && strLen >= 0");
- Contract.Assert(strLen >= startIndex, "TextElementEnumerator(): strLen >= startIndex");
+ 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;
@@ -125,7 +125,7 @@ namespace System.Globalization
}
//
- // Get the starting _index of the current text element.
+ // Get the starting index of the current text element.
//
public int ElementIndex
diff --git a/src/mscorlib/corefx/System/Globalization/TextInfo.Unix.cs b/src/mscorlib/corefx/System/Globalization/TextInfo.Unix.cs
index 8490057306..3d9b777f64 100644
--- a/src/mscorlib/corefx/System/Globalization/TextInfo.Unix.cs
+++ b/src/mscorlib/corefx/System/Globalization/TextInfo.Unix.cs
@@ -2,6 +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.Diagnostics;
using System.Diagnostics.Contracts;
using System.Security;
using System.Text;
@@ -35,7 +36,7 @@ namespace System.Globalization
[SecuritySafeCritical]
private unsafe string ChangeCase(string s, bool toUpper)
{
- Contract.Assert(s != null);
+ Debug.Assert(s != null);
if (s.Length == 0)
{
@@ -93,7 +94,7 @@ namespace System.Globalization
private bool NeedsTurkishCasing(string localeName)
{
- Contract.Assert(localeName != null);
+ Debug.Assert(localeName != null);
return CultureInfo.GetCultureInfo(localeName).CompareInfo.Compare("\u0131", "I", CompareOptions.IgnoreCase) == 0;
}
diff --git a/src/mscorlib/corefx/System/Globalization/TextInfo.Windows.cs b/src/mscorlib/corefx/System/Globalization/TextInfo.Windows.cs
index 238c51217b..b2f692e2d0 100644
--- a/src/mscorlib/corefx/System/Globalization/TextInfo.Windows.cs
+++ b/src/mscorlib/corefx/System/Globalization/TextInfo.Windows.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.Diagnostics.Contracts;
+using System.Diagnostics;
namespace System.Globalization
{
@@ -35,7 +35,7 @@ namespace System.Globalization
private unsafe string ChangeCase(string s, bool toUpper)
{
- Contract.Assert(s != null);
+ Debug.Assert(s != null);
//
// Get the length of the string.
@@ -80,7 +80,7 @@ namespace System.Globalization
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
}
- Contract.Assert(ret == nLengthInput, "Expected getting the same length of the original string");
+ Debug.Assert(ret == nLengthInput, "Expected getting the same length of the original string");
return result;
}
}
diff --git a/src/mscorlib/corefx/System/Globalization/TextInfo.cs b/src/mscorlib/corefx/System/Globalization/TextInfo.cs
index 6dadb5856a..5bb376f19c 100644
--- a/src/mscorlib/corefx/System/Globalization/TextInfo.cs
+++ b/src/mscorlib/corefx/System/Globalization/TextInfo.cs
@@ -12,15 +12,10 @@
//
////////////////////////////////////////////////////////////////////////////
-using System;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
-using System.Runtime;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
using System.Runtime.Serialization;
-using System.Security;
using System.Text;
-using System.Threading;
namespace System.Globalization
{
@@ -145,6 +140,64 @@ namespace System.Globalization
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);
+ }
+ }
+
+ [System.Runtime.InteropServices.ComVisible(false)]
+ public int LCID
+ {
+ get
+ {
+ // Just use the LCID from our text info name
+ return CultureInfo.GetCultureInfo(_textInfoName).LCID;
+ }
+ }
+
//////////////////////////////////////////////////////////////////////////
////
//// CultureName
@@ -177,10 +230,10 @@ namespace System.Globalization
////
//// Clone
////
- //// Is the implementation of IColnable.
+ //// Is the implementation of ICloneable.
////
//////////////////////////////////////////////////////////////////////////
- public virtual Object Clone()
+ public virtual object Clone()
{
object o = MemberwiseClone();
((TextInfo)o).SetReadOnlyState(false);
@@ -196,9 +249,9 @@ namespace System.Globalization
//
////////////////////////////////////////////////////////////////////////
[System.Runtime.InteropServices.ComVisible(false)]
- internal static TextInfo ReadOnly(TextInfo textInfo)
+ public static TextInfo ReadOnly(TextInfo textInfo)
{
- if (textInfo == null) { throw new ArgumentNullException("textInfo"); }
+ if (textInfo == null) { throw new ArgumentNullException(nameof(textInfo)); }
Contract.EndContractBlock();
if (textInfo.IsReadOnly) { return (textInfo); }
@@ -244,7 +297,7 @@ namespace System.Globalization
{
if (value == null)
{
- throw new ArgumentNullException("value", SR.ArgumentNull_String);
+ throw new ArgumentNullException(nameof(value), SR.ArgumentNull_String);
}
VerifyWritable();
_listSeparator = value;
@@ -270,7 +323,7 @@ namespace System.Globalization
public unsafe virtual String ToLower(String str)
{
- if (str == null) { throw new ArgumentNullException("str"); }
+ if (str == null) { throw new ArgumentNullException(nameof(str)); }
return ChangeCase(str, toUpper: false);
}
@@ -303,7 +356,7 @@ namespace System.Globalization
public unsafe virtual String ToUpper(String str)
{
- if (str == null) { throw new ArgumentNullException("str"); }
+ if (str == null) { throw new ArgumentNullException(nameof(str)); }
return ChangeCase(str, toUpper: true);
}
@@ -317,7 +370,7 @@ namespace System.Globalization
return c;
}
- static private bool IsAscii(Char c)
+ private static bool IsAscii(Char c)
{
return c < 0x80;
}
@@ -396,6 +449,245 @@ namespace System.Globalization
}
//
+ // 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)
@@ -403,7 +695,7 @@ namespace System.Globalization
// Validate inputs
if (str == null)
{
- throw new ArgumentNullException("str");
+ throw new ArgumentNullException(nameof(str));
}
// This code assumes that ASCII casing is safe for whatever context is passed in.
@@ -438,7 +730,7 @@ namespace System.Globalization
private unsafe int GetCaseInsensitiveHashCodeSlow(String str)
{
- Contract.Assert(str != null);
+ Debug.Assert(str != null);
string upper = ToUpper(str);
diff --git a/src/mscorlib/corefx/System/Globalization/ThaiBuddhistCalendar.cs b/src/mscorlib/corefx/System/Globalization/ThaiBuddhistCalendar.cs
index b42af30c04..8ebbfa0a69 100644
--- a/src/mscorlib/corefx/System/Globalization/ThaiBuddhistCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/ThaiBuddhistCalendar.cs
@@ -56,6 +56,15 @@ namespace System.Globalization
}
}
+ [System.Runtime.InteropServices.ComVisible(false)]
+ public override CalendarAlgorithmType AlgorithmType
+ {
+ get
+ {
+ return CalendarAlgorithmType.SolarCalendar;
+ }
+ }
+
public ThaiBuddhistCalendar()
{
helper = new GregorianCalendarHelper(this, thaiBuddhistEraInfo);
@@ -221,7 +230,7 @@ namespace System.Globalization
{
if (year < 0)
{
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
SR.ArgumentOutOfRange_NeedNonNegNum);
}
Contract.EndContractBlock();
diff --git a/src/mscorlib/corefx/System/Globalization/UmAlQuraCalendar.cs b/src/mscorlib/corefx/System/Globalization/UmAlQuraCalendar.cs
index 1116722fe9..997c5f2316 100644
--- a/src/mscorlib/corefx/System/Globalization/UmAlQuraCalendar.cs
+++ b/src/mscorlib/corefx/System/Globalization/UmAlQuraCalendar.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.Diagnostics;
using System.Diagnostics.Contracts;
namespace System.Globalization
@@ -270,6 +270,14 @@ namespace System.Globalization
}
}
+ public override CalendarAlgorithmType AlgorithmType
+ {
+ get
+ {
+ return CalendarAlgorithmType.LunarCalendar;
+ }
+ }
+
public UmAlQuraCalendar()
{
}
@@ -309,9 +317,9 @@ namespace System.Globalization
=========================ConvertHijriToGregorian============================*/
private static void ConvertHijriToGregorian(int HijriYear, int HijriMonth, int HijriDay, ref int yg, ref int mg, ref int dg)
{
- Contract.Assert((HijriYear >= MinCalendarYear) && (HijriYear <= MaxCalendarYear), "Hijri year is out of range.");
- Contract.Assert(HijriMonth >= 1, "Hijri month is out of range.");
- Contract.Assert(HijriDay >= 1, "Hijri day is out of range.");
+ 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;
@@ -368,7 +376,7 @@ namespace System.Globalization
{
if (era != CurrentEra && era != UmAlQuraEra)
{
- throw new ArgumentOutOfRangeException("era", SR.ArgumentOutOfRange_InvalidEraValue);
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
}
@@ -378,7 +386,7 @@ namespace System.Globalization
if (year < MinCalendarYear || year > MaxCalendarYear)
{
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -392,7 +400,7 @@ namespace System.Globalization
CheckYearRange(year, era);
if (month < 1 || month > 12)
{
- throw new ArgumentOutOfRangeException("month", SR.ArgumentOutOfRange_Month);
+ throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_Month);
}
}
@@ -409,7 +417,7 @@ namespace System.Globalization
TimeSpan ts;
int yh1 = 0, mh1 = 0, dh1 = 0;
- Contract.Assert((time.Ticks >= minDate.Ticks) && (time.Ticks <= maxDate.Ticks), "Gregorian date is out of range.");
+ 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.
@@ -510,7 +518,7 @@ namespace System.Globalization
if (months < -120000 || months > 120000)
{
throw new ArgumentOutOfRangeException(
- "months",
+ nameof(months),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -622,7 +630,7 @@ namespace System.Globalization
{
int days = 0, b;
- Contract.Assert((year >= MinCalendarYear) && (year <= MaxCalendarYear), "Hijri year is out of range.");
+ Debug.Assert((year >= MinCalendarYear) && (year <= MaxCalendarYear), "Hijri year is out of range.");
b = s_hijriYearInfo[year - MinCalendarYear].HijriMonthsLengthFlags;
@@ -631,7 +639,7 @@ namespace System.Globalization
days = days + 29 + (b & 1); /* Add the months lengths before mh */
b = b >> 1;
}
- Contract.Assert((days == 354) || (days == 355), "Hijri year has to be 354 or 355 days.");
+ Debug.Assert((days == 354) || (days == 355), "Hijri year has to be 354 or 355 days.");
return days;
}
@@ -711,7 +719,7 @@ namespace System.Globalization
if (day < 1 || day > daysInMonth)
{
throw new ArgumentOutOfRangeException(
- "day",
+ nameof(day),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Day,
@@ -775,7 +783,7 @@ namespace System.Globalization
if (day < 1 || day > daysInMonth)
{
throw new ArgumentOutOfRangeException(
- "day",
+ nameof(day),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Day,
@@ -815,7 +823,7 @@ namespace System.Globalization
if (value != 99 && (value < MinCalendarYear || value > MaxCalendarYear))
{
throw new ArgumentOutOfRangeException(
- "value",
+ nameof(value),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
@@ -835,7 +843,7 @@ namespace System.Globalization
{
if (year < 0)
{
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
SR.ArgumentOutOfRange_NeedNonNegNum);
}
Contract.EndContractBlock();
@@ -848,7 +856,7 @@ namespace System.Globalization
if ((year < MinCalendarYear) || (year > MaxCalendarYear))
{
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
SR.ArgumentOutOfRange_Range,
diff --git a/src/mscorlib/corefx/System/HResults.cs b/src/mscorlib/corefx/System/HResults.cs
new file mode 100644
index 0000000000..fa0e24f00b
--- /dev/null
+++ b/src/mscorlib/corefx/System/HResults.cs
@@ -0,0 +1,236 @@
+// Licensed to the .NET Foundation under one or more 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: Define HResult constants. Every exception has one of these.
+//
+//
+//===========================================================================*/
+
+using System;
+
+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.
+ internal static class HResults
+ {
+ internal const int APPMODEL_ERROR_NO_PACKAGE = unchecked((int)0x80073D54);
+ internal const int CLDB_E_FILE_CORRUPT = unchecked((int)0x8013110e);
+ internal const int CLDB_E_FILE_OLDVER = unchecked((int)0x80131107);
+ internal const int CLDB_E_INDEX_NOTFOUND = unchecked((int)0x80131124);
+ internal const int CLR_E_BIND_ASSEMBLY_NOT_FOUND = unchecked((int)0x80132004);
+ internal const int CLR_E_BIND_ASSEMBLY_PUBLIC_KEY_MISMATCH = unchecked((int)0x80132001);
+ internal const int CLR_E_BIND_ASSEMBLY_VERSION_TOO_LOW = unchecked((int)0x80132000);
+ internal const int CLR_E_BIND_TYPE_NOT_FOUND = unchecked((int)0x80132005);
+ internal const int CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT = unchecked((int)0x80132003);
+ internal const int COR_E_ABANDONEDMUTEX = unchecked((int)0x8013152D);
+ 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_ASSEMBLYEXPECTED = unchecked((int)0x80131018);
+ internal const int COR_E_BADIMAGEFORMAT = unchecked((int)0x8007000B);
+ internal const int COR_E_CANNOTUNLOADAPPDOMAIN = unchecked((int)0x80131015);
+ internal const int COR_E_CODECONTRACTFAILED = unchecked((int)0x80131542);
+ internal const int COR_E_CONTEXTMARSHAL = unchecked((int)0x80131504);
+ internal const int COR_E_CUSTOMATTRIBUTEFORMAT = unchecked((int)0x80131605);
+ internal const int COR_E_DATAMISALIGNED = unchecked((int)0x80131541);
+ internal const int COR_E_DIVIDEBYZERO = unchecked((int)0x80020012); // DISP_E_DIVBYZERO
+ internal const int COR_E_DLLNOTFOUND = unchecked((int)0x80131524);
+ internal const int COR_E_DUPLICATEWAITOBJECT = unchecked((int)0x80131529);
+ internal const int COR_E_ENTRYPOINTNOTFOUND = unchecked((int)0x80131523);
+ 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_FIXUPSINEXE = unchecked((int)0x80131019);
+ internal const int COR_E_FORMAT = unchecked((int)0x80131537);
+ internal const int COR_E_INDEXOUTOFRANGE = unchecked((int)0x80131508);
+ internal const int COR_E_INSUFFICIENTEXECUTIONSTACK = unchecked((int)0x80131578);
+ 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_KEYNOTFOUND = unchecked((int)0x80131577);
+ internal const int COR_E_LOADING_REFERENCE_ASSEMBLY = unchecked((int)0x80131058);
+ 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_MISSINGSATELLITEASSEMBLY = unchecked((int)0x80131536);
+ internal const int COR_E_MODULE_HASH_CHECK_FAILED = unchecked((int)0x80131039);
+ internal const int COR_E_MULTICASTNOTSUPPORTED = unchecked((int)0x80131514);
+ internal const int COR_E_NEWER_RUNTIME = unchecked((int)0x8013101b);
+ internal const int COR_E_NOTFINITENUMBER = unchecked((int)0x80131528);
+ 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_PLATFORMNOTSUPPORTED = unchecked((int)0x80131539);
+ internal const int COR_E_RANK = unchecked((int)0x80131517);
+ internal const int COR_E_REFLECTIONTYPELOAD = unchecked((int)0x80131602);
+ internal const int COR_E_REMOTING = unchecked((int)0x8013150b);
+ 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_SECURITY = unchecked((int)0x8013150A);
+ internal const int COR_E_SERIALIZATION = unchecked((int)0x8013150C);
+ internal const int COR_E_SERVER = unchecked((int)0x8013150e);
+ 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_THREADSTART = unchecked((int)0x80131525);
+ internal const int COR_E_THREADSTATE = unchecked((int)0x80131520);
+ internal const int COR_E_TIMEOUT = unchecked((int)0x80131505);
+ 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_TYPEUNLOADED = unchecked((int)0x80131013);
+ internal const int COR_E_UNAUTHORIZEDACCESS = unchecked((int)0x80070005);
+ internal const int COR_E_VERIFICATION = unchecked((int)0x8013150D);
+ internal const int COR_E_WAITHANDLECANNOTBEOPENED = unchecked((int)0x8013152C);
+ internal const int CORSEC_E_CRYPTO = unchecked((int)0x80131430);
+ internal const int CORSEC_E_CRYPTO_UNEX_OPER = unchecked((int)0x80131431);
+ internal const int CORSEC_E_INVALID_IMAGE_FORMAT = unchecked((int)0x8013141d);
+ internal const int CORSEC_E_INVALID_PUBLICKEY = unchecked((int)0x8013141e);
+ internal const int CORSEC_E_INVALID_STRONGNAME = unchecked((int)0x8013141a);
+ internal const int CORSEC_E_MIN_GRANT_FAIL = unchecked((int)0x80131417);
+ internal const int CORSEC_E_MISSING_STRONGNAME = unchecked((int)0x8013141b);
+ 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_SIGNATURE_MISMATCH = unchecked((int)0x80131420);
+ internal const int CORSEC_E_XMLSYNTAX = unchecked((int)0x80131419);
+ internal const int CTL_E_DEVICEIOERROR = unchecked((int)0x800A0039);
+ internal const int CTL_E_DIVISIONBYZERO = unchecked((int)0x800A000B);
+ internal const int CTL_E_FILENOTFOUND = unchecked((int)0x800A0035);
+ internal const int CTL_E_OUTOFMEMORY = unchecked((int)0x800A0007);
+ internal const int CTL_E_OUTOFSTACKSPACE = unchecked((int)0x800A001C);
+ internal const int CTL_E_OVERFLOW = unchecked((int)0x800A0006);
+ internal const int CTL_E_PATHFILEACCESSERROR = unchecked((int)0x800A004B);
+ internal const int CTL_E_PATHNOTFOUND = unchecked((int)0x800A004C);
+ internal const int CTL_E_PERMISSIONDENIED = unchecked((int)0x800A0046);
+ internal const int E_ELEMENTNOTAVAILABLE = unchecked((int)0x802B001F);
+ internal const int E_ELEMENTNOTENABLED = unchecked((int)0x802B001E);
+ internal const int E_FAIL = unchecked((int)0x80004005);
+ internal const int E_HANDLE = unchecked((int)0x80070006);
+ internal const int E_ILLEGAL_DELEGATE_ASSIGNMENT = unchecked((int)0x80000018);
+ internal const int E_ILLEGAL_METHOD_CALL = unchecked((int)0x8000000E);
+ internal const int E_ILLEGAL_STATE_CHANGE = unchecked((int)0x8000000D);
+ internal const int E_INVALIDARG = unchecked((int)0x80070057);
+ internal const int E_LAYOUTCYCLE = unchecked((int)0x802B0014);
+ internal const int E_NOTIMPL = unchecked((int)0x80004001);
+ internal const int E_OUTOFMEMORY = unchecked((int)0x8007000E);
+ internal const int E_POINTER = unchecked((int)0x80004003L);
+ internal const int E_XAMLPARSEFAILED = unchecked((int)0x802B000A);
+ internal const int ERROR_BAD_EXE_FORMAT = unchecked((int)0x800700C1);
+ internal const int ERROR_BAD_NET_NAME = unchecked((int)0x80070043);
+ internal const int ERROR_BAD_NETPATH = unchecked((int)0x80070035);
+ internal const int ERROR_DISK_CORRUPT = unchecked((int)0x80070571);
+ internal const int ERROR_DLL_INIT_FAILED = unchecked((int)0x8007045A);
+ internal const int ERROR_DLL_NOT_FOUND = unchecked((int)0x80070485);
+ internal const int ERROR_EXE_MARKED_INVALID = unchecked((int)0x800700C0);
+ internal const int ERROR_FILE_CORRUPT = unchecked((int)0x80070570);
+ internal const int ERROR_FILE_INVALID = unchecked((int)0x800703EE);
+ internal const int ERROR_FILE_NOT_FOUND = unchecked((int)0x80070002);
+ internal const int ERROR_INVALID_DLL = unchecked((int)0x80070482);
+ internal const int ERROR_INVALID_NAME = unchecked((int)0x8007007B);
+ internal const int ERROR_INVALID_ORDINAL = unchecked((int)0x800700B6);
+ internal const int ERROR_INVALID_PARAMETER = unchecked((int)0x80070057);
+ internal const int ERROR_LOCK_VIOLATION = unchecked((int)0x80070021);
+ internal const int ERROR_MOD_NOT_FOUND = unchecked((int)0x8007007E);
+ internal const int ERROR_NO_UNICODE_TRANSLATION = unchecked((int)0x80070459);
+ internal const int ERROR_NOACCESS = unchecked((int)0x800703E6);
+ internal const int ERROR_NOT_READY = unchecked((int)0x80070015);
+ internal const int ERROR_OPEN_FAILED = unchecked((int)0x8007006E);
+ internal const int ERROR_PATH_NOT_FOUND = unchecked((int)0x80070003);
+ internal const int ERROR_SHARING_VIOLATION = unchecked((int)0x80070020);
+ internal const int ERROR_TOO_MANY_OPEN_FILES = unchecked((int)0x80070004);
+ internal const int ERROR_UNRECOGNIZED_VOLUME = unchecked((int)0x800703ED);
+ internal const int ERROR_WRONG_TARGET_NAME = unchecked((int)0x80070574);
+ internal const int FUSION_E_ASM_MODULE_MISSING = unchecked((int)0x80131042);
+ internal const int FUSION_E_CACHEFILE_FAILED = unchecked((int)0x80131052);
+ internal const int FUSION_E_CODE_DOWNLOAD_DISABLED = unchecked((int)0x80131048);
+ internal const int FUSION_E_HOST_GAC_ASM_MISMATCH = unchecked((int)0x80131050);
+ internal const int FUSION_E_INVALID_NAME = unchecked((int)0x80131047);
+ internal const int FUSION_E_INVALID_PRIVATE_ASM_LOCATION = unchecked((int)0x80131041);
+ internal const int FUSION_E_LOADFROM_BLOCKED = unchecked((int)0x80131051);
+ internal const int FUSION_E_PRIVATE_ASM_DISALLOWED = unchecked((int)0x80131044);
+ internal const int FUSION_E_REF_DEF_MISMATCH = unchecked((int)0x80131040);
+ internal const int FUSION_E_SIGNATURE_CHECK_FAILED = unchecked((int)0x80131045);
+ internal const int INET_E_CANNOT_CONNECT = unchecked((int)0x800C0004);
+ internal const int INET_E_CONNECTION_TIMEOUT = unchecked((int)0x800C000B);
+ internal const int INET_E_DATA_NOT_AVAILABLE = unchecked((int)0x800C0007);
+ internal const int INET_E_DOWNLOAD_FAILURE = unchecked((int)0x800C0008);
+ internal const int INET_E_OBJECT_NOT_FOUND = unchecked((int)0x800C0006);
+ internal const int INET_E_RESOURCE_NOT_FOUND = unchecked((int)0x800C0005);
+ internal const int INET_E_UNKNOWN_PROTOCOL = unchecked((int)0x800C000D);
+ internal const int ISS_E_ALLOC_TOO_LARGE = unchecked((int)0x80131484);
+ internal const int ISS_E_BLOCK_SIZE_TOO_SMALL = unchecked((int)0x80131483);
+ internal const int ISS_E_CALLER = unchecked((int)0x801314A1);
+ internal const int ISS_E_CORRUPTED_STORE_FILE = unchecked((int)0x80131480);
+ internal const int ISS_E_CREATE_DIR = unchecked((int)0x80131468);
+ internal const int ISS_E_CREATE_MUTEX = unchecked((int)0x80131464);
+ internal const int ISS_E_DEPRECATE = unchecked((int)0x801314A0);
+ internal const int ISS_E_FILE_NOT_MAPPED = unchecked((int)0x80131482);
+ internal const int ISS_E_FILE_WRITE = unchecked((int)0x80131466);
+ internal const int ISS_E_GET_FILE_SIZE = unchecked((int)0x80131463);
+ internal const int ISS_E_ISOSTORE = unchecked((int)0x80131450);
+ internal const int ISS_E_LOCK_FAILED = unchecked((int)0x80131465);
+ internal const int ISS_E_MACHINE = unchecked((int)0x801314A3);
+ internal const int ISS_E_MACHINE_DACL = unchecked((int)0x801314A4);
+ internal const int ISS_E_MAP_VIEW_OF_FILE = unchecked((int)0x80131462);
+ internal const int ISS_E_OPEN_FILE_MAPPING = unchecked((int)0x80131461);
+ internal const int ISS_E_OPEN_STORE_FILE = unchecked((int)0x80131460);
+ internal const int ISS_E_PATH_LENGTH = unchecked((int)0x801314A2);
+ internal const int ISS_E_SET_FILE_POINTER = unchecked((int)0x80131467);
+ internal const int ISS_E_STORE_NOT_OPEN = unchecked((int)0x80131469);
+ internal const int ISS_E_STORE_VERSION = unchecked((int)0x80131481);
+ internal const int ISS_E_TABLE_ROW_NOT_FOUND = unchecked((int)0x80131486);
+ internal const int ISS_E_USAGE_WILL_EXCEED_QUOTA = unchecked((int)0x80131485);
+ internal const int META_E_BAD_SIGNATURE = unchecked((int)0x80131192);
+ internal const int META_E_CA_FRIENDS_SN_REQUIRED = unchecked((int)0x801311e6);
+ internal const int MSEE_E_ASSEMBLYLOADINPROGRESS = unchecked((int)0x80131016);
+ internal const int RO_E_CLOSED = unchecked((int)0x80000013);
+ internal const int E_BOUNDS = unchecked((int)0x8000000B);
+ internal const int RO_E_METADATA_NAME_NOT_FOUND = unchecked((int)0x8000000F);
+ internal const int SECURITY_E_INCOMPATIBLE_EVIDENCE = unchecked((int)0x80131403);
+ internal const int SECURITY_E_INCOMPATIBLE_SHARE = unchecked((int)0x80131401);
+ internal const int SECURITY_E_UNVERIFIABLE = unchecked((int)0x80131402);
+ internal const int STG_E_PATHNOTFOUND = unchecked((int)0x80030003);
+ public const int COR_E_DIRECTORYNOTFOUND = unchecked((int)0x80070003);
+ public const int COR_E_ENDOFSTREAM = unchecked((int)0x80070026); // OS defined
+ public const int COR_E_FILELOAD = unchecked((int)0x80131621);
+ public const int COR_E_FILENOTFOUND = unchecked((int)0x80070002);
+ public const int COR_E_IO = unchecked((int)0x80131620);
+ public const int COR_E_PATHTOOLONG = unchecked((int)0x800700CE);
+ }
+}
diff --git a/src/mscorlib/corefx/System/IO/Error.cs b/src/mscorlib/corefx/System/IO/Error.cs
new file mode 100644
index 0000000000..c8434ffad8
--- /dev/null
+++ b/src/mscorlib/corefx/System/IO/Error.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.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.NetStandard17.cs b/src/mscorlib/corefx/System/IO/FileStream.NetStandard17.cs
new file mode 100644
index 0000000000..dc1385fbc0
--- /dev/null
+++ b/src/mscorlib/corefx/System/IO/FileStream.NetStandard17.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 Microsoft.Win32.SafeHandles;
+using System.Threading.Tasks;
+using System.Diagnostics;
+using System.Threading;
+
+namespace System.IO
+{
+ public partial class FileStream : Stream
+ {
+ public override IAsyncResult BeginRead(byte[] array, int offset, int numBytes, AsyncCallback callback, object state)
+ {
+ if (array == null)
+ throw new ArgumentNullException(nameof(array));
+ if (offset < 0)
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum);
+ if (numBytes < 0)
+ throw new ArgumentOutOfRangeException(nameof(numBytes), SR.ArgumentOutOfRange_NeedNonNegNum);
+ if (array.Length - offset < numBytes)
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
+
+ if (IsClosed) throw new ObjectDisposedException(SR.ObjectDisposed_FileClosed);
+ if (!CanRead) throw new NotSupportedException(SR.NotSupported_UnreadableStream);
+
+ if (!IsAsync)
+ return base.BeginRead(array, offset, numBytes, callback, state);
+ else
+ return TaskToApm.Begin(ReadAsyncInternal(array, offset, numBytes, CancellationToken.None), callback, state);
+ }
+
+ public override IAsyncResult BeginWrite(byte[] array, int offset, int numBytes, AsyncCallback callback, object state)
+ {
+ if (array == null)
+ throw new ArgumentNullException(nameof(array));
+ if (offset < 0)
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum);
+ if (numBytes < 0)
+ throw new ArgumentOutOfRangeException(nameof(numBytes), SR.ArgumentOutOfRange_NeedNonNegNum);
+ if (array.Length - offset < numBytes)
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
+
+ if (IsClosed) throw new ObjectDisposedException(SR.ObjectDisposed_FileClosed);
+ if (!CanWrite) throw new NotSupportedException(SR.NotSupported_UnwritableStream);
+
+ if (!IsAsync)
+ return base.BeginWrite(array, offset, numBytes, callback, state);
+ else
+ return TaskToApm.Begin(WriteAsyncInternal(array, offset, numBytes, CancellationToken.None), callback, state);
+ }
+
+ public override int EndRead(IAsyncResult asyncResult)
+ {
+ if (asyncResult == null)
+ throw new ArgumentNullException(nameof(asyncResult));
+
+ if (!IsAsync)
+ return base.EndRead(asyncResult);
+ else
+ return TaskToApm.End<int>(asyncResult);
+ }
+
+ public override void EndWrite(IAsyncResult asyncResult)
+ {
+ if (asyncResult == null)
+ throw new ArgumentNullException(nameof(asyncResult));
+
+ if (!IsAsync)
+ base.EndWrite(asyncResult);
+ else
+ TaskToApm.End(asyncResult);
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/IO/FileStream.Unix.cs b/src/mscorlib/corefx/System/IO/FileStream.Unix.cs
new file mode 100644
index 0000000000..f83fc84259
--- /dev/null
+++ b/src/mscorlib/corefx/System/IO/FileStream.Unix.cs
@@ -0,0 +1,934 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// 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
new file mode 100644
index 0000000000..350d948b00
--- /dev/null
+++ b/src/mscorlib/corefx/System/IO/FileStream.Win32.cs
@@ -0,0 +1,1770 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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.mincore.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.mincore.SecurityOptions.SECURITY_SQOS_PRESENT | Interop.mincore.SecurityOptions.SECURITY_ANONYMOUS);
+
+ // Don't pop up a dialog for reading from an empty floppy drive
+ uint oldMode = Interop.mincore.SetErrorMode(Interop.mincore.SEM_FAILCRITICALERRORS);
+ try
+ {
+ SafeFileHandle fileHandle = Interop.mincore.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.mincore.Errors.ERROR_PATH_NOT_FOUND && _path.Equals(Directory.InternalGetDirectoryRoot(_path)))
+ errorCode = Interop.mincore.Errors.ERROR_ACCESS_DENIED;
+
+ throw Win32Marshal.GetExceptionForWin32Error(errorCode, _path);
+ }
+
+ return fileHandle;
+ }
+ finally
+ {
+ Interop.mincore.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.mincore.GetFileType(_fileHandle);
+ if (fileType != Interop.mincore.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.mincore.GetFileType(_fileHandle);
+ Debug.Assert(handleType == Interop.mincore.FileTypes.FILE_TYPE_DISK || handleType == Interop.mincore.FileTypes.FILE_TYPE_PIPE || handleType == Interop.mincore.FileTypes.FILE_TYPE_CHAR, "FileStream was passed an unknown file type!");
+
+ _canSeek = handleType == Interop.mincore.FileTypes.FILE_TYPE_DISK;
+ _isPipe = handleType == Interop.mincore.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.mincore.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.mincore.SECURITY_ATTRIBUTES GetSecAttrs(FileShare share)
+ {
+ Interop.mincore.SECURITY_ATTRIBUTES secAttrs = default(Interop.mincore.SECURITY_ATTRIBUTES);
+ if ((share & FileShare.Inheritable) != 0)
+ {
+ secAttrs = new Interop.mincore.SECURITY_ATTRIBUTES();
+ secAttrs.nLength = (uint)sizeof(Interop.mincore.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.mincore.GetFileType(_fileHandle) != Interop.mincore.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.mincore.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.mincore.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.mincore.FILE_STANDARD_INFO info = new Interop.mincore.FILE_STANDARD_INFO();
+
+ if (!Interop.mincore.GetFileInformationByHandleEx(_fileHandle, Interop.mincore.FILE_INFO_BY_HANDLE_CLASS.FileStandardInfo, out info, (uint)Marshal.SizeOf<Interop.mincore.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.mincore.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.mincore.SetEndOfFile(_fileHandle))
+ {
+ int errorCode = Marshal.GetLastWin32Error();
+ if (errorCode == Interop.mincore.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.mincore.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)
+ {
+ if (_useAsyncIO)
+ r = Interop.mincore.ReadFile(handle, p + offset, count, IntPtr.Zero, overlapped);
+ else
+ r = Interop.mincore.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)
+ {
+ if (_useAsyncIO)
+ r = Interop.mincore.WriteFile(handle, p + offset, count, IntPtr.Zero, overlapped);
+ else
+ r = Interop.mincore.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.mincore.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.mincore.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.mincore.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.mincore.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.mincore.UnlockFile(_fileHandle, positionLow, positionHigh, lengthLow, lengthHigh))
+ {
+ throw Win32Marshal.GetExceptionForLastWin32Error();
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/IO/FileStream.cs b/src/mscorlib/corefx/System/IO/FileStream.cs
new file mode 100644
index 0000000000..398f5a6162
--- /dev/null
+++ b/src/mscorlib/corefx/System/IO/FileStream.cs
@@ -0,0 +1,654 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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.Threading.Tasks;
+using Microsoft.Win32.SafeHandles;
+using System.Diagnostics;
+
+namespace System.IO
+{
+ public partial class FileStream : Stream
+ {
+ private const FileShare DefaultShare = FileShare.Read;
+ private const bool DefaultIsAsync = false;
+ internal const int DefaultBufferSize = 4096;
+
+ private byte[] _buffer;
+ private int _bufferLength;
+ private readonly SafeFileHandle _fileHandle;
+
+ /// <summary>Whether the file is opened for reading, writing, or both.</summary>
+ private readonly FileAccess _access;
+
+ /// <summary>The path to the opened file.</summary>
+ private readonly string _path;
+
+ /// <summary>The next available byte to be read from the _buffer.</summary>
+ private int _readPos;
+
+ /// <summary>The number of valid bytes in _buffer.</summary>
+ private int _readLength;
+
+ /// <summary>The next location in which a write should occur to the buffer.</summary>
+ private int _writePos;
+
+ /// <summary>
+ /// Whether asynchronous read/write/flush operations should be performed using async I/O.
+ /// On Windows FileOptions.Asynchronous controls how the file handle is configured,
+ /// and then as a result how operations are issued against that file handle. On Unix,
+ /// there isn't any distinction around how file descriptors are created for async vs
+ /// sync, but we still differentiate how the operations are issued in order to provide
+ /// similar behavioral semantics and performance characteristics as on Windows. On
+ /// Windows, if non-async, async read/write requests just delegate to the base stream,
+ /// and no attempt is made to synchronize between sync and async operations on the stream;
+ /// if async, then async read/write requests are implemented specially, and sync read/write
+ /// requests are coordinated with async ones by implementing the sync ones over the async
+ /// ones. On Unix, we do something similar. If non-async, async read/write requests just
+ /// delegate to the base stream, and no attempt is made to synchronize. If async, we use
+ /// a semaphore to coordinate both sync and async operations.
+ /// </summary>
+ private readonly bool _useAsyncIO;
+
+ /// <summary>
+ /// Currently cached position in the stream. This should always mirror the underlying file's actual position,
+ /// and should only ever be out of sync if another stream with access to this same file manipulates it, at which
+ /// point we attempt to error out.
+ /// </summary>
+ private long _filePosition;
+
+ /// <summary>Whether the file stream's handle has been exposed.</summary>
+ private bool _exposedHandle;
+
+ [Obsolete("This constructor has been deprecated. Please use new FileStream(SafeFileHandle handle, FileAccess access) instead. http://go.microsoft.com/fwlink/?linkid=14202")]
+ public FileStream(IntPtr handle, FileAccess access)
+ : this(handle, access, true, DefaultBufferSize, false)
+ {
+ }
+
+ [Obsolete("This constructor has been deprecated. Please use new FileStream(SafeFileHandle handle, FileAccess access) instead, and optionally make a new SafeFileHandle with ownsHandle=false if needed. http://go.microsoft.com/fwlink/?linkid=14202")]
+ public FileStream(IntPtr handle, FileAccess access, bool ownsHandle)
+ : this(handle, access, ownsHandle, DefaultBufferSize, false)
+ {
+ }
+
+ [Obsolete("This constructor has been deprecated. Please use new FileStream(SafeFileHandle handle, FileAccess access, int bufferSize) instead, and optionally make a new SafeFileHandle with ownsHandle=false if needed. http://go.microsoft.com/fwlink/?linkid=14202")]
+ public FileStream(IntPtr handle, FileAccess access, bool ownsHandle, int bufferSize)
+ : this(handle, access, ownsHandle, bufferSize, false)
+ {
+ }
+
+ [Obsolete("This constructor has been deprecated. Please use new FileStream(SafeFileHandle handle, FileAccess access, int bufferSize, bool isAsync) instead, and optionally make a new SafeFileHandle with ownsHandle=false if needed. http://go.microsoft.com/fwlink/?linkid=14202")]
+ public FileStream(IntPtr handle, FileAccess access, bool ownsHandle, int bufferSize, bool isAsync)
+ : this(new SafeFileHandle(handle, ownsHandle), access, bufferSize, isAsync)
+ {
+ }
+
+ public FileStream(SafeFileHandle handle, FileAccess access)
+ : this(handle, access, DefaultBufferSize)
+ {
+ }
+
+ public FileStream(SafeFileHandle handle, FileAccess access, int bufferSize)
+ : this(handle, access, bufferSize, GetDefaultIsAsync(handle))
+ {
+ }
+
+ public FileStream(SafeFileHandle handle, FileAccess access, int bufferSize, bool isAsync)
+ {
+ if (handle.IsInvalid)
+ throw new ArgumentException(SR.Arg_InvalidHandle, nameof(handle));
+
+ if (access < FileAccess.Read || access > FileAccess.ReadWrite)
+ throw new ArgumentOutOfRangeException(nameof(access), SR.ArgumentOutOfRange_Enum);
+ if (bufferSize <= 0)
+ throw new ArgumentOutOfRangeException(nameof(bufferSize), SR.ArgumentOutOfRange_NeedPosNum);
+
+ if (handle.IsClosed)
+ throw new ObjectDisposedException(SR.ObjectDisposed_FileClosed);
+ if (handle.IsAsync.HasValue && isAsync != handle.IsAsync.Value)
+ throw new ArgumentException(SR.Arg_HandleNotAsync, nameof(handle));
+
+ _access = access;
+ _useAsyncIO = isAsync;
+ _exposedHandle = true;
+ _bufferLength = bufferSize;
+ _fileHandle = handle;
+
+ InitFromHandle(handle);
+ }
+
+ public FileStream(string path, FileMode mode) :
+ this(path, mode, (mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite), DefaultShare, DefaultBufferSize, DefaultIsAsync)
+ { }
+
+ public FileStream(string path, FileMode mode, FileAccess access) :
+ this(path, mode, access, DefaultShare, DefaultBufferSize, DefaultIsAsync)
+ { }
+
+ public FileStream(string path, FileMode mode, FileAccess access, FileShare share) :
+ this(path, mode, access, share, DefaultBufferSize, DefaultIsAsync)
+ { }
+
+ public FileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize) :
+ this(path, mode, access, share, bufferSize, DefaultIsAsync)
+ { }
+
+ public FileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, bool useAsync) :
+ this(path, mode, access, share, bufferSize, useAsync ? FileOptions.Asynchronous : FileOptions.None)
+ { }
+
+ internal FileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, string msgPath, bool bFromProxy)
+ : this(path, mode, access, share, bufferSize, options, msgPath, bFromProxy, useLongPath: false)
+ {
+ }
+
+ internal FileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, string msgPath, bool bFromProxy, bool useLongPath)
+ : this(path, mode, access, share, bufferSize, options)
+ {
+ // msgPath is the path that is handed back to untrusted code, CoreCLR is always full trust
+ // bFromProxy is also related to asserting rights for limited trust and also can be ignored
+ // useLongPath was used to get around the legacy MaxPath check, this is no longer applicable as everything supports long paths
+ // checkHost is also related to limited trust scenarios
+ }
+
+ public FileStream(string path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options)
+ {
+ if (path == null)
+ throw new ArgumentNullException(nameof(path), SR.ArgumentNull_Path);
+ if (path.Length == 0)
+ throw new ArgumentException(SR.Argument_EmptyPath, nameof(path));
+
+ // don't include inheritable in our bounds check for share
+ FileShare tempshare = share & ~FileShare.Inheritable;
+ string badArg = null;
+
+ if (mode < FileMode.CreateNew || mode > FileMode.Append)
+ badArg = nameof(mode);
+ else if (access < FileAccess.Read || access > FileAccess.ReadWrite)
+ badArg = nameof(access);
+ else if (tempshare < FileShare.None || tempshare > (FileShare.ReadWrite | FileShare.Delete))
+ badArg = nameof(share);
+
+ if (badArg != null)
+ throw new ArgumentOutOfRangeException(badArg, SR.ArgumentOutOfRange_Enum);
+
+ // NOTE: any change to FileOptions enum needs to be matched here in the error validation
+ if (options != FileOptions.None && (options & ~(FileOptions.WriteThrough | FileOptions.Asynchronous | FileOptions.RandomAccess | FileOptions.DeleteOnClose | FileOptions.SequentialScan | FileOptions.Encrypted | (FileOptions)0x20000000 /* NoBuffering */)) != 0)
+ throw new ArgumentOutOfRangeException(nameof(options), SR.ArgumentOutOfRange_Enum);
+
+ if (bufferSize <= 0)
+ throw new ArgumentOutOfRangeException(nameof(bufferSize), SR.ArgumentOutOfRange_NeedPosNum);
+
+ // Write access validation
+ if ((access & FileAccess.Write) == 0)
+ {
+ if (mode == FileMode.Truncate || mode == FileMode.CreateNew || mode == FileMode.Create || mode == FileMode.Append)
+ {
+ // No write access, mode and access disagree but flag access since mode comes first
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidFileModeAndAccessCombo, mode, access), nameof(access));
+ }
+ }
+
+ if ((access & FileAccess.Read) != 0 && mode == FileMode.Append)
+ throw new ArgumentException(SR.Argument_InvalidAppendMode, nameof(access));
+
+ string fullPath = Path.GetFullPath(path);
+
+ _path = fullPath;
+ _access = access;
+ _bufferLength = bufferSize;
+
+ if ((options & FileOptions.Asynchronous) != 0)
+ _useAsyncIO = true;
+
+ _fileHandle = OpenHandle(mode, share, options);
+
+ try
+ {
+ Init(mode, share);
+ }
+ catch
+ {
+ // If anything goes wrong while setting up the stream, make sure we deterministically dispose
+ // of the opened handle.
+ _fileHandle.Dispose();
+ _fileHandle = null;
+ throw;
+ }
+ }
+
+ private static bool GetDefaultIsAsync(SafeFileHandle handle)
+ {
+ // This will eventually get more complicated as we can actually check the underlying handle type on Windows
+ return handle.IsAsync.HasValue ? handle.IsAsync.Value : false;
+ }
+
+ // InternalOpen, InternalCreate, and InternalAppend:
+ // Factory methods for FileStream used by File, FileInfo, and ReadLinesIterator
+ // Specifies default access and sharing options for FileStreams created by those classes
+ internal static FileStream InternalOpen(string path, int bufferSize = DefaultBufferSize, bool useAsync = DefaultIsAsync)
+ {
+ return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, useAsync);
+ }
+
+ internal static FileStream InternalCreate(string path, int bufferSize = DefaultBufferSize, bool useAsync = DefaultIsAsync)
+ {
+ return new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, bufferSize, useAsync);
+ }
+
+ internal static FileStream InternalAppend(string path, int bufferSize = DefaultBufferSize, bool useAsync = DefaultIsAsync)
+ {
+ return new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.Read, bufferSize, useAsync);
+ }
+
+ [Obsolete("This property has been deprecated. Please use FileStream's SafeFileHandle property instead. http://go.microsoft.com/fwlink/?linkid=14202")]
+ public virtual IntPtr Handle { get { return SafeFileHandle.DangerousGetHandle(); } }
+
+ public virtual void Lock(long position, long length)
+ {
+ if (position < 0 || length < 0)
+ {
+ throw new ArgumentOutOfRangeException(position < 0 ? nameof(position) : nameof(length), SR.ArgumentOutOfRange_NeedNonNegNum);
+ }
+
+ if (_fileHandle.IsClosed)
+ {
+ throw Error.GetFileNotOpen();
+ }
+
+ LockInternal(position, length);
+ }
+
+ public virtual void Unlock(long position, long length)
+ {
+ if (position < 0 || length < 0)
+ {
+ throw new ArgumentOutOfRangeException(position < 0 ? nameof(position) : nameof(length), SR.ArgumentOutOfRange_NeedNonNegNum);
+ }
+
+ if (_fileHandle.IsClosed)
+ {
+ throw Error.GetFileNotOpen();
+ }
+
+ UnlockInternal(position, length);
+ }
+
+ public override Task FlushAsync(CancellationToken cancellationToken)
+ {
+ // If we have been inherited into a subclass, the following implementation could be incorrect
+ // since it does not call through to Flush() which a subclass might have overridden. To be safe
+ // we will only use this implementation in cases where we know it is safe to do so,
+ // and delegate to our base class (which will call into Flush) when we are not sure.
+ if (GetType() != typeof(FileStream))
+ return base.FlushAsync(cancellationToken);
+
+ return FlushAsyncInternal(cancellationToken);
+ }
+
+ public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
+ {
+ if (buffer == null)
+ throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
+ if (offset < 0)
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum);
+ if (count < 0)
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
+ if (buffer.Length - offset < count)
+ throw new ArgumentException(SR.Argument_InvalidOffLen /*, no good single parameter name to pass*/);
+
+ // If we have been inherited into a subclass, the following implementation could be incorrect
+ // since it does not call through to Read() or ReadAsync() which a subclass might have overridden.
+ // To be safe we will only use this implementation in cases where we know it is safe to do so,
+ // and delegate to our base class (which will call into Read/ReadAsync) when we are not sure.
+ if (GetType() != typeof(FileStream))
+ return base.ReadAsync(buffer, offset, count, cancellationToken);
+
+ if (cancellationToken.IsCancellationRequested)
+ return Task.FromCanceled<int>(cancellationToken);
+
+ if (IsClosed)
+ throw Error.GetFileNotOpen();
+
+ return ReadAsyncInternal(buffer, offset, count, cancellationToken);
+ }
+
+ public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
+ {
+ if (buffer == null)
+ throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
+ if (offset < 0)
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum);
+ if (count < 0)
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
+ if (buffer.Length - offset < count)
+ throw new ArgumentException(SR.Argument_InvalidOffLen /*, no good single parameter name to pass*/);
+
+ // If we have been inherited into a subclass, the following implementation could be incorrect
+ // since it does not call through to Write() or WriteAsync() which a subclass might have overridden.
+ // To be safe we will only use this implementation in cases where we know it is safe to do so,
+ // and delegate to our base class (which will call into Write/WriteAsync) when we are not sure.
+ if (GetType() != typeof(FileStream))
+ return base.WriteAsync(buffer, offset, count, cancellationToken);
+
+ if (cancellationToken.IsCancellationRequested)
+ return Task.FromCanceled(cancellationToken);
+
+ if (IsClosed)
+ throw Error.GetFileNotOpen();
+
+ return WriteAsyncInternal(buffer, offset, count, cancellationToken);
+ }
+
+ /// <summary>
+ /// Clears buffers for this stream and causes any buffered data to be written to the file.
+ /// </summary>
+ public override void Flush()
+ {
+ // Make sure that we call through the public virtual API
+ Flush(flushToDisk: false);
+ }
+
+ /// <summary>
+ /// Clears buffers for this stream, and if <param name="flushToDisk"/> is true,
+ /// causes any buffered data to be written to the file.
+ /// </summary>
+ public virtual void Flush(bool flushToDisk)
+ {
+ if (IsClosed) throw Error.GetFileNotOpen();
+
+ FlushInternalBuffer();
+
+ if (flushToDisk && CanWrite)
+ {
+ FlushOSBuffer();
+ }
+ }
+
+ /// <summary>Gets a value indicating whether the current stream supports reading.</summary>
+ public override bool CanRead
+ {
+ get { return !_fileHandle.IsClosed && (_access & FileAccess.Read) != 0; }
+ }
+
+ /// <summary>Gets a value indicating whether the current stream supports writing.</summary>
+ public override bool CanWrite
+ {
+ get { return !_fileHandle.IsClosed && (_access & FileAccess.Write) != 0; }
+ }
+
+ /// <summary>Validates arguments to Read and Write and throws resulting exceptions.</summary>
+ /// <param name="array">The buffer to read from or write to.</param>
+ /// <param name="offset">The zero-based offset into the array.</param>
+ /// <param name="count">The maximum number of bytes to read or write.</param>
+ private void ValidateReadWriteArgs(byte[] array, int offset, int count)
+ {
+ if (array == null)
+ throw new ArgumentNullException(nameof(array), SR.ArgumentNull_Buffer);
+ if (offset < 0)
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum);
+ if (count < 0)
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
+ if (array.Length - offset < count)
+ throw new ArgumentException(SR.Argument_InvalidOffLen /*, no good single parameter name to pass*/);
+ if (_fileHandle.IsClosed)
+ throw Error.GetFileNotOpen();
+ }
+
+ /// <summary>Sets the length of this stream to the given value.</summary>
+ /// <param name="value">The new length of the stream.</param>
+ public override void SetLength(long value)
+ {
+ if (value < 0)
+ throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_NeedNonNegNum);
+ if (_fileHandle.IsClosed)
+ throw Error.GetFileNotOpen();
+ if (!CanSeek)
+ throw Error.GetSeekNotSupported();
+ if (!CanWrite)
+ throw Error.GetWriteNotSupported();
+
+ SetLengthInternal(value);
+ }
+
+ public virtual SafeFileHandle SafeFileHandle
+ {
+ get
+ {
+ Flush();
+ _exposedHandle = true;
+ return _fileHandle;
+ }
+ }
+
+ /// <summary>Gets the path that was passed to the constructor.</summary>
+ public virtual string Name { get { return _path ?? SR.IO_UnknownFileName; } }
+
+ /// <summary>Gets a value indicating whether the stream was opened for I/O to be performed synchronously or asynchronously.</summary>
+ public virtual bool IsAsync
+ {
+ get { return _useAsyncIO; }
+ }
+
+ /// <summary>Gets the length of the stream in bytes.</summary>
+ public override long Length
+ {
+ get
+ {
+ if (_fileHandle.IsClosed) throw Error.GetFileNotOpen();
+ if (!CanSeek) throw Error.GetSeekNotSupported();
+ return GetLengthInternal();
+ }
+ }
+
+ /// <summary>
+ /// Verify that the actual position of the OS's handle equals what we expect it to.
+ /// This will fail if someone else moved the UnixFileStream's handle or if
+ /// our position updating code is incorrect.
+ /// </summary>
+ private void VerifyOSHandlePosition()
+ {
+ bool verifyPosition = _exposedHandle; // in release, only verify if we've given out the handle such that someone else could be manipulating it
+#if DEBUG
+ verifyPosition = true; // in debug, always make sure our position matches what the OS says it should be
+#endif
+ if (verifyPosition && CanSeek)
+ {
+ long oldPos = _filePosition; // SeekCore will override the current _position, so save it now
+ long curPos = SeekCore(0, SeekOrigin.Current);
+ if (oldPos != curPos)
+ {
+ // For reads, this is non-fatal but we still could have returned corrupted
+ // data in some cases, so discard the internal buffer. For writes,
+ // this is a problem; discard the buffer and error out.
+ _readPos = _readLength = 0;
+ if (_writePos > 0)
+ {
+ _writePos = 0;
+ throw new IOException(SR.IO_FileStreamHandlePosition);
+ }
+ }
+ }
+ }
+
+ /// <summary>Verifies that state relating to the read/write buffer is consistent.</summary>
+ [Conditional("DEBUG")]
+ private void AssertBufferInvariants()
+ {
+ // Read buffer values must be in range: 0 <= _bufferReadPos <= _bufferReadLength <= _bufferLength
+ Debug.Assert(0 <= _readPos && _readPos <= _readLength && _readLength <= _bufferLength);
+
+ // Write buffer values must be in range: 0 <= _bufferWritePos <= _bufferLength
+ Debug.Assert(0 <= _writePos && _writePos <= _bufferLength);
+
+ // Read buffering and write buffering can't both be active
+ Debug.Assert((_readPos == 0 && _readLength == 0) || _writePos == 0);
+ }
+
+ /// <summary>Validates that we're ready to read from the stream.</summary>
+ private void PrepareForReading()
+ {
+ if (_fileHandle.IsClosed)
+ throw Error.GetFileNotOpen();
+ if (_readLength == 0 && !CanRead)
+ throw Error.GetReadNotSupported();
+
+ AssertBufferInvariants();
+ }
+
+ /// <summary>Gets or sets the position within the current stream</summary>
+ public override long Position
+ {
+ get
+ {
+ if (_fileHandle.IsClosed)
+ throw Error.GetFileNotOpen();
+
+ if (!CanSeek)
+ throw Error.GetSeekNotSupported();
+
+ AssertBufferInvariants();
+ VerifyOSHandlePosition();
+
+ // We may have read data into our buffer from the handle, such that the handle position
+ // is artificially further along than the consumer's view of the stream's position.
+ // Thus, when reading, our position is really starting from the handle position negatively
+ // offset by the number of bytes in the buffer and positively offset by the number of
+ // bytes into that buffer we've read. When writing, both the read length and position
+ // must be zero, and our position is just the handle position offset positive by how many
+ // bytes we've written into the buffer.
+ return (_filePosition - _readLength) + _readPos + _writePos;
+ }
+ set
+ {
+ if (value < 0)
+ throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ Seek(value, SeekOrigin.Begin);
+ }
+ }
+
+ internal virtual bool IsClosed => _fileHandle.IsClosed;
+
+ /// <summary>
+ /// Gets the array used for buffering reading and writing.
+ /// If the array hasn't been allocated, this will lazily allocate it.
+ /// </summary>
+ /// <returns>The buffer.</returns>
+ private byte[] GetBuffer()
+ {
+ Debug.Assert(_buffer == null || _buffer.Length == _bufferLength);
+ if (_buffer == null)
+ {
+ _buffer = new byte[_bufferLength];
+ OnBufferAllocated();
+ }
+
+ return _buffer;
+ }
+
+ partial void OnBufferAllocated();
+
+ /// <summary>
+ /// Flushes the internal read/write buffer for this stream. If write data has been buffered,
+ /// that data is written out to the underlying file. Or if data has been buffered for
+ /// reading from the stream, the data is dumped and our position in the underlying file
+ /// is rewound as necessary. This does not flush the OS buffer.
+ /// </summary>
+ private void FlushInternalBuffer()
+ {
+ AssertBufferInvariants();
+ if (_writePos > 0)
+ {
+ FlushWriteBuffer();
+ }
+ else if (_readPos < _readLength && CanSeek)
+ {
+ FlushReadBuffer();
+ }
+ }
+
+ /// <summary>Dumps any read data in the buffer and rewinds our position in the stream, accordingly, as necessary.</summary>
+ private void FlushReadBuffer()
+ {
+ // Reading is done by blocks from the file, but someone could read
+ // 1 byte from the buffer then write. At that point, the OS's file
+ // pointer is out of sync with the stream's position. All write
+ // functions should call this function to preserve the position in the file.
+
+ AssertBufferInvariants();
+ Debug.Assert(_writePos == 0, "FileStream: Write buffer must be empty in FlushReadBuffer!");
+
+ int rewind = _readPos - _readLength;
+ if (rewind != 0)
+ {
+ Debug.Assert(CanSeek, "FileStream will lose buffered read data now.");
+ SeekCore(rewind, SeekOrigin.Current);
+ }
+ _readPos = _readLength = 0;
+ }
+
+ private int ReadByteCore()
+ {
+ PrepareForReading();
+
+ byte[] buffer = GetBuffer();
+ if (_readPos == _readLength)
+ {
+ FlushWriteBuffer();
+ Debug.Assert(_bufferLength > 0, "_bufferSize > 0");
+
+ _readLength = ReadNative(buffer, 0, _bufferLength);
+ _readPos = 0;
+ if (_readLength == 0)
+ {
+ return -1;
+ }
+ }
+
+ return buffer[_readPos++];
+ }
+
+ private void WriteByteCore(byte value)
+ {
+ PrepareForWriting();
+
+ // Flush the write buffer if it's full
+ if (_writePos == _bufferLength)
+ FlushWriteBuffer();
+
+ // We now have space in the buffer. Store the byte.
+ GetBuffer()[_writePos++] = value;
+ }
+
+ /// <summary>
+ /// Validates that we're ready to write to the stream,
+ /// including flushing a read buffer if necessary.
+ /// </summary>
+ private void PrepareForWriting()
+ {
+ if (_fileHandle.IsClosed)
+ throw Error.GetFileNotOpen();
+
+ // Make sure we're good to write. We only need to do this if there's nothing already
+ // in our write buffer, since if there is something in the buffer, we've already done
+ // this checking and flushing.
+ if (_writePos == 0)
+ {
+ if (!CanWrite) throw Error.GetWriteNotSupported();
+ FlushReadBuffer();
+ Debug.Assert(_bufferLength > 0, "_bufferSize > 0");
+ }
+ }
+
+ ~FileStream()
+ {
+ // Preserved for compatibility since FileStream has defined a
+ // finalizer in past releases and derived classes may depend
+ // on Dispose(false) call.
+ Dispose(false);
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/IO/FileStreamCompletionSource.Win32.cs b/src/mscorlib/corefx/System/IO/FileStreamCompletionSource.Win32.cs
new file mode 100644
index 0000000000..532dbb0615
--- /dev/null
+++ b/src/mscorlib/corefx/System/IO/FileStreamCompletionSource.Win32.cs
@@ -0,0 +1,221 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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.mincore.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.mincore.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.mincore.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
new file mode 100644
index 0000000000..2dd1907007
--- /dev/null
+++ b/src/mscorlib/corefx/System/IO/Path.Unix.cs
@@ -0,0 +1,256 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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 readonly char DirectorySeparatorChar = '/';
+ public static readonly char VolumeSeparatorChar = '/';
+ public static readonly char PathSeparator = ':';
+
+ private const string DirectorySeparatorCharAsString = "/";
+
+ public static char[] GetInvalidFileNameChars() => new char[] { '\0', '/' };
+
+ internal static readonly int MaxPath = Interop.Sys.MaxPath;
+ private static readonly int MaxLongPath = 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 > MaxPath)
+ {
+ throw new PathTooLongException(SR.IO_PathTooLong);
+ }
+
+ string result = collapsedString.Length == 0 ? 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 > PathInternal.MaxComponentLength)
+ {
+ throw new PathTooLongException(SR.IO_PathTooLong);
+ }
+
+ // Normalize the directory separator if needed
+ if (c != Path.DirectorySeparatorChar && c == Path.AltDirectorySeparatorChar)
+ {
+ c = Path.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 + 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] == DirectorySeparatorChar;
+ }
+
+ public static string GetPathRoot(string path)
+ {
+ if (path == null) return null;
+ return IsPathRooted(path) ? DirectorySeparatorCharAsString : String.Empty;
+ }
+
+ private static unsafe void GetCryptoRandomBytes(byte* bytes, int byteCount)
+ {
+#if FEATURE_CORECLR
+ // 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);
+#else
+ if (s_isMac)
+ {
+ GetCryptoRandomBytesApple(bytes, byteCount);
+ }
+ else
+ {
+ GetCryptoRandomBytesOpenSsl(bytes, byteCount);
+ }
+#endif
+ }
+
+#if !FEATURE_CORECLR
+ private static unsafe void GetCryptoRandomBytesApple(byte* bytes, int byteCount)
+ {
+ Debug.Assert(bytes != null);
+ Debug.Assert(byteCount >= 0);
+
+ if (Interop.CommonCrypto.CCRandomGenerateBytes(bytes, byteCount) != 0)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_Cryptography);
+ }
+ }
+
+ private static unsafe void GetCryptoRandomBytesOpenSsl(byte* bytes, int byteCount)
+ {
+ Debug.Assert(bytes != null);
+ Debug.Assert(byteCount >= 0);
+
+ if (!Interop.Crypto.GetRandomBytes(bytes, byteCount))
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_Cryptography);
+ }
+ }
+#endif
+
+ /// <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
new file mode 100644
index 0000000000..8a9e62e6e5
--- /dev/null
+++ b/src/mscorlib/corefx/System/IO/Path.Win32.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.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
new file mode 100644
index 0000000000..b597efc54e
--- /dev/null
+++ b/src/mscorlib/corefx/System/IO/Path.Windows.cs
@@ -0,0 +1,153 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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 readonly char DirectorySeparatorChar = '\\';
+ public static readonly char VolumeSeparatorChar = ':';
+ public static readonly char PathSeparator = ';';
+
+ private const string DirectorySeparatorCharAsString = "\\";
+
+ 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, ':', '*', '?', '\\', '/'
+ };
+
+ // 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 static readonly int MaxPath = 260;
+ internal static readonly int MaxLongPath = short.MaxValue;
+
+ // 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] == VolumeSeparatorChar)
+ || (path.Length >= startIndex && path[startIndex - 1] == VolumeSeparatorChar && !PathInternal.IsValidDriveChar(path[startIndex - 2]))
+ || (path.Length > startIndex && path.IndexOf(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.mincore.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.mincore.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] == 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
new file mode 100644
index 0000000000..3b1ba6b07d
--- /dev/null
+++ b/src/mscorlib/corefx/System/IO/Path.cs
@@ -0,0 +1,578 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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
+ {
+ // Platform specific alternate directory separator character.
+ // There is only one directory separator char on Unix, which is the same
+ // as the alternate separator on Windows, so same definition is used for both.
+ public static readonly char AltDirectorySeparatorChar = '/';
+
+ // 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;
+ }
+
+ public static char[] GetInvalidPathChars()
+ {
+ return PathInternal.GetInvalidPathChars();
+ }
+
+ // 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(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 + 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 + DirectorySeparatorCharAsString + path3;
+ }
+ else if (hasSep2)
+ {
+ return path1 + 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(DirectorySeparatorChar)
+ .Append(path2)
+ .Append(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(DirectorySeparatorChar);
+ }
+
+ sb.Append(path2);
+ if (!hasSep2)
+ {
+ sb.Append(DirectorySeparatorChar);
+ }
+
+ sb.Append(path3);
+ if (!hasSep3)
+ {
+ sb.Append(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/corefx/System/IO/PathHelper.Windows.cs
new file mode 100644
index 0000000000..4c2cdff45e
--- /dev/null
+++ b/src/mscorlib/corefx/System/IO/PathHelper.Windows.cs
@@ -0,0 +1,389 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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.Runtime.InteropServices;
+
+namespace System.IO
+{
+ /// <summary>
+ /// Wrapper to help with path normalization.
+ /// </summary>
+ unsafe internal class PathHelper
+ {
+ // Can't be over 8.3 and be a short name
+ private const int MaxShortName = 12;
+
+ private const char LastAnsi = (char)255;
+ private const char Delete = (char)127;
+
+ [ThreadStatic]
+ private static StringBuffer t_fullPathBuffer;
+
+ /// <summary>
+ /// Normalize the given path.
+ /// </summary>
+ /// <remarks>
+ /// Normalizes via Win32 GetFullPathName(). It will also trim all "typical" whitespace at the end of the path (see s_trimEndChars). Will also trim initial
+ /// spaces if the path is determined to be rooted.
+ ///
+ /// Note that invalid characters will be checked after the path is normalized, which could remove bad characters. (C:\|\..\a.txt -- C:\a.txt)
+ /// </remarks>
+ /// <param name="path">Path to normalize</param>
+ /// <param name="checkInvalidCharacters">True to check for invalid characters</param>
+ /// <param name="expandShortPaths">Attempt to expand short paths if true</param>
+ /// <exception cref="ArgumentException">Thrown if the path is an illegal UNC (does not contain a full server/share) or contains illegal characters.</exception>
+ /// <exception cref="PathTooLongException">Thrown if the path or a path segment exceeds the filesystem limits.</exception>
+ /// <exception cref="FileNotFoundException">Thrown if Windows returns ERROR_FILE_NOT_FOUND. (See Win32Marshal.GetExceptionForWin32Error)</exception>
+ /// <exception cref="DirectoryNotFoundException">Thrown if Windows returns ERROR_PATH_NOT_FOUND. (See Win32Marshal.GetExceptionForWin32Error)</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown if Windows returns ERROR_ACCESS_DENIED. (See Win32Marshal.GetExceptionForWin32Error)</exception>
+ /// <exception cref="IOException">Thrown if Windows returns an error that doesn't map to the above. (See Win32Marshal.GetExceptionForWin32Error)</exception>
+ /// <returns>Normalized path</returns>
+ internal static string Normalize(string path, bool checkInvalidCharacters, bool expandShortPaths)
+ {
+ // Get the full path
+ StringBuffer fullPath = t_fullPathBuffer ?? (t_fullPathBuffer = new StringBuffer(PathInternal.MaxShortPath));
+ try
+ {
+ GetFullPathName(path, fullPath);
+
+ // Trim whitespace off the end of the string. Win32 normalization trims only U+0020.
+ fullPath.TrimEnd(PathInternal.s_trimEndChars);
+
+ if (fullPath.Length >= PathInternal.MaxLongPath)
+ {
+ // Fullpath is genuinely too long
+ throw new PathTooLongException(SR.IO_PathTooLong);
+ }
+
+ // Checking path validity used to happen before getting the full path name. To avoid additional input allocation
+ // (to trim trailing whitespace) we now do it after the Win32 call. This will allow legitimate paths through that
+ // used to get kicked back (notably segments with invalid characters might get removed via "..").
+ //
+ // There is no way that GetLongPath can invalidate the path so we'll do this (cheaper) check before we attempt to
+ // expand short file names.
+
+ // Scan the path for:
+ //
+ // - Illegal path characters.
+ // - Invalid UNC paths like \\, \\server, \\server\.
+ // - Segments that are too long (over MaxComponentLength)
+
+ // As the path could be > 30K, we'll combine the validity scan. None of these checks are performed by the Win32
+ // GetFullPathName() API.
+
+ bool possibleShortPath = false;
+ bool foundTilde = false;
+
+ // We can get UNCs as device paths through this code (e.g. \\.\UNC\), we won't validate them as there isn't
+ // an easy way to normalize without extensive cost (we'd have to hunt down the canonical name for any device
+ // path that contains UNC or to see if the path was doing something like \\.\GLOBALROOT\Device\Mup\,
+ // \\.\GLOBAL\UNC\, \\.\GLOBALROOT\GLOBAL??\UNC\, etc.
+ bool specialPath = fullPath.Length > 1 && fullPath[0] == '\\' && fullPath[1] == '\\';
+ bool isDevice = PathInternal.IsDevice(fullPath);
+ bool possibleBadUnc = specialPath && !isDevice;
+ uint index = specialPath ? 2u : 0;
+ uint lastSeparator = specialPath ? 1u : 0;
+ uint segmentLength;
+ char* start = fullPath.CharPointer;
+ char current;
+
+ while (index < fullPath.Length)
+ {
+ current = start[index];
+
+ // Try to skip deeper analysis. '?' and higher are valid/ignorable except for '\', '|', and '~'
+ if (current < '?' || current == '\\' || current == '|' || current == '~')
+ {
+ switch (current)
+ {
+ case '|':
+ case '>':
+ case '<':
+ case '\"':
+ if (checkInvalidCharacters) throw new ArgumentException(SR.Argument_InvalidPathChars);
+ foundTilde = false;
+ break;
+ case '~':
+ foundTilde = true;
+ break;
+ case '\\':
+ segmentLength = index - lastSeparator - 1;
+ if (segmentLength > (uint)PathInternal.MaxComponentLength)
+ throw new PathTooLongException(SR.IO_PathTooLong + fullPath.ToString());
+ lastSeparator = index;
+
+ if (foundTilde)
+ {
+ if (segmentLength <= MaxShortName)
+ {
+ // Possibly a short path.
+ possibleShortPath = true;
+ }
+
+ foundTilde = false;
+ }
+
+ if (possibleBadUnc)
+ {
+ // If we're at the end of the path and this is the first separator, we're missing the share.
+ // Otherwise we're good, so ignore UNC tracking from here.
+ if (index == fullPath.Length - 1)
+ throw new ArgumentException(SR.Arg_PathIllegalUNC);
+ else
+ possibleBadUnc = false;
+ }
+
+ break;
+
+ default:
+ if (checkInvalidCharacters && current < ' ') throw new ArgumentException(SR.Argument_InvalidPathChars, nameof(path));
+ break;
+ }
+ }
+
+ index++;
+ }
+
+ if (possibleBadUnc)
+ throw new ArgumentException(SR.Arg_PathIllegalUNC);
+
+ segmentLength = fullPath.Length - lastSeparator - 1;
+ if (segmentLength > (uint)PathInternal.MaxComponentLength)
+ throw new PathTooLongException(SR.IO_PathTooLong);
+
+ if (foundTilde && segmentLength <= MaxShortName)
+ possibleShortPath = true;
+
+ // Check for a short filename path and try and expand it. Technically you don't need to have a tilde for a short name, but
+ // this is how we've always done this. This expansion is costly so we'll continue to let other short paths slide.
+ if (expandShortPaths && possibleShortPath)
+ {
+ return TryExpandShortFileName(fullPath, originalPath: path);
+ }
+ else
+ {
+ if (fullPath.Length == (uint)path.Length && fullPath.StartsWith(path))
+ {
+ // If we have the exact same string we were passed in, don't bother to allocate another string from the StringBuilder.
+ return path;
+ }
+ else
+ {
+ return fullPath.ToString();
+ }
+ }
+ }
+ finally
+ {
+ // Clear the buffer
+ fullPath.Free();
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static bool IsDosUnc(StringBuffer buffer)
+ {
+ return !PathInternal.IsDevice(buffer) && buffer.Length > 1 && buffer[0] == '\\' && buffer[1] == '\\';
+ }
+
+ private static void GetFullPathName(string path, StringBuffer fullPath)
+ {
+ // If the string starts with an extended prefix we would need to remove it from the path before we call GetFullPathName as
+ // it doesn't root extended paths correctly. We don't currently resolve extended paths, so we'll just assert here.
+ Debug.Assert(PathInternal.IsPartiallyQualified(path) || !PathInternal.IsExtended(path));
+
+ // Historically we would skip leading spaces *only* if the path started with a drive " C:" or a UNC " \\"
+ int startIndex = PathInternal.PathStartSkip(path);
+
+ fixed (char* pathStart = path)
+ {
+ uint result = 0;
+ while ((result = Interop.mincore.GetFullPathNameW(pathStart + startIndex, fullPath.CharCapacity, fullPath.GetHandle(), IntPtr.Zero)) > fullPath.CharCapacity)
+ {
+ // Reported size (which does not include the null) is greater than the buffer size. Increase the capacity.
+ fullPath.EnsureCharCapacity(result);
+ }
+
+ if (result == 0)
+ {
+ // Failure, get the error and throw
+ int errorCode = Marshal.GetLastWin32Error();
+ if (errorCode == 0)
+ errorCode = Interop.mincore.Errors.ERROR_BAD_PATHNAME;
+ throw Win32Marshal.GetExceptionForWin32Error(errorCode, path);
+ }
+
+ fullPath.Length = result;
+ }
+ }
+
+ private static uint GetInputBuffer(StringBuffer content, bool isDosUnc, out StringBuffer buffer)
+ {
+ uint length = content.Length;
+
+ length += isDosUnc
+ ? (uint)PathInternal.UncExtendedPrefixLength - PathInternal.UncPrefixLength
+ : PathInternal.DevicePrefixLength;
+
+ buffer = new StringBuffer(length);
+
+ if (isDosUnc)
+ {
+ // Put the extended UNC prefix (\\?\UNC\) in front of the path
+ buffer.CopyFrom(bufferIndex: 0, source: PathInternal.UncExtendedPathPrefix);
+
+ // Copy the source buffer over after the existing UNC prefix
+ content.CopyTo(
+ bufferIndex: PathInternal.UncPrefixLength,
+ destination: buffer,
+ destinationIndex: PathInternal.UncExtendedPrefixLength,
+ count: content.Length - PathInternal.UncPrefixLength);
+
+ // Return the prefix difference
+ return (uint)PathInternal.UncExtendedPrefixLength - PathInternal.UncPrefixLength;
+ }
+ else
+ {
+ uint prefixSize = (uint)PathInternal.ExtendedPathPrefix.Length;
+ buffer.CopyFrom(bufferIndex: 0, source: PathInternal.ExtendedPathPrefix);
+ content.CopyTo(bufferIndex: 0, destination: buffer, destinationIndex: prefixSize, count: content.Length);
+ return prefixSize;
+ }
+ }
+
+ private static string TryExpandShortFileName(StringBuffer outputBuffer, string originalPath)
+ {
+ // We guarantee we'll expand short names for paths that only partially exist. As such, we need to find the part of the path that actually does exist. To
+ // avoid allocating like crazy we'll create only one input array and modify the contents with embedded nulls.
+
+ Debug.Assert(!PathInternal.IsPartiallyQualified(outputBuffer), "should have resolved by now");
+
+ // We'll have one of a few cases by now (the normalized path will have already:
+ //
+ // 1. Dos path (C:\)
+ // 2. Dos UNC (\\Server\Share)
+ // 3. Dos device path (\\.\C:\, \\?\C:\)
+ //
+ // We want to put the extended syntax on the front if it doesn't already have it, which may mean switching from \\.\.
+ //
+ // Note that we will never get \??\ here as GetFullPathName() does not recognize \??\ and will return it as C:\??\ (or whatever the current drive is).
+
+ uint rootLength = PathInternal.GetRootLength(outputBuffer);
+ bool isDevice = PathInternal.IsDevice(outputBuffer);
+
+ StringBuffer inputBuffer = null;
+ bool isDosUnc = false;
+ uint rootDifference = 0;
+ bool wasDotDevice = false;
+
+ // Add the extended prefix before expanding to allow growth over MAX_PATH
+ if (isDevice)
+ {
+ // We have one of the following (\\?\ or \\.\)
+ inputBuffer = new StringBuffer();
+ inputBuffer.Append(outputBuffer);
+
+ if (outputBuffer[2] == '.')
+ {
+ wasDotDevice = true;
+ inputBuffer[2] = '?';
+ }
+ }
+ else
+ {
+ isDosUnc = IsDosUnc(outputBuffer);
+ rootDifference = GetInputBuffer(outputBuffer, isDosUnc, out inputBuffer);
+ }
+
+ rootLength += rootDifference;
+ uint inputLength = inputBuffer.Length;
+
+ bool success = false;
+ uint foundIndex = inputBuffer.Length - 1;
+
+ while (!success)
+ {
+ uint result = Interop.mincore.GetLongPathNameW(inputBuffer.GetHandle(), outputBuffer.GetHandle(), outputBuffer.CharCapacity);
+
+ // Replace any temporary null we added
+ if (inputBuffer[foundIndex] == '\0') inputBuffer[foundIndex] = '\\';
+
+ if (result == 0)
+ {
+ // Look to see if we couldn't find the file
+ int error = Marshal.GetLastWin32Error();
+ if (error != Interop.mincore.Errors.ERROR_FILE_NOT_FOUND && error != Interop.mincore.Errors.ERROR_PATH_NOT_FOUND)
+ {
+ // Some other failure, give up
+ break;
+ }
+
+ // We couldn't find the path at the given index, start looking further back in the string.
+ foundIndex--;
+
+ for (; foundIndex > rootLength && inputBuffer[foundIndex] != '\\'; foundIndex--) ;
+ if (foundIndex == rootLength)
+ {
+ // Can't trim the path back any further
+ break;
+ }
+ else
+ {
+ // Temporarily set a null in the string to get Windows to look further up the path
+ inputBuffer[foundIndex] = '\0';
+ }
+ }
+ else if (result > outputBuffer.CharCapacity)
+ {
+ // Not enough space. The result count for this API does not include the null terminator.
+ outputBuffer.EnsureCharCapacity(result);
+ result = Interop.mincore.GetLongPathNameW(inputBuffer.GetHandle(), outputBuffer.GetHandle(), outputBuffer.CharCapacity);
+ }
+ else
+ {
+ // Found the path
+ success = true;
+ outputBuffer.Length = result;
+ if (foundIndex < inputLength - 1)
+ {
+ // It was a partial find, put the non-existent part of the path back
+ outputBuffer.Append(inputBuffer, foundIndex, inputBuffer.Length - foundIndex);
+ }
+ }
+ }
+
+ // Strip out the prefix and return the string
+ StringBuffer bufferToUse = success ? outputBuffer : inputBuffer;
+
+ // Switch back from \\?\ to \\.\ if necessary
+ if (wasDotDevice)
+ bufferToUse[2] = '.';
+
+ string returnValue = null;
+
+ int newLength = (int)(bufferToUse.Length - rootDifference);
+ if (isDosUnc)
+ {
+ // Need to go from \\?\UNC\ to \\?\UN\\
+ bufferToUse[PathInternal.UncExtendedPrefixLength - PathInternal.UncPrefixLength] = '\\';
+ }
+
+ // We now need to strip out any added characters at the front of the string
+ if (bufferToUse.SubstringEquals(originalPath, rootDifference, newLength))
+ {
+ // Use the original path to avoid allocating
+ returnValue = originalPath;
+ }
+ else
+ {
+ returnValue = bufferToUse.Substring(rootDifference, newLength);
+ }
+
+ inputBuffer.Dispose();
+ return returnValue;
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/IO/PathInternal.CaseSensitivity.cs b/src/mscorlib/corefx/System/IO/PathInternal.CaseSensitivity.cs
new file mode 100644
index 0000000000..bea2df93b9
--- /dev/null
+++ b/src/mscorlib/corefx/System/IO/PathInternal.CaseSensitivity.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.Diagnostics;
+
+namespace System.IO
+{
+ /// <summary>Contains internal path helpers that are shared between many projects.</summary>
+ internal static partial class PathInternal
+ {
+ private enum Tristate : byte
+ {
+ NotInitialized,
+ True,
+ False,
+ }
+
+ private static Tristate s_isCaseSensitive = Tristate.NotInitialized;
+
+ /// <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;
+ }
+ }
+
+ /// <summary>Gets whether the system is case-sensitive.</summary>
+ internal static bool IsCaseSensitive
+ {
+ get
+ {
+ // This must be lazily initialized as there are dependencies on PathInternal's static constructor
+ // being fully initialized. (GetIsCaseSensitive() calls GetFullPath() which needs to use PathInternal)
+ if (s_isCaseSensitive == Tristate.NotInitialized)
+ s_isCaseSensitive = GetIsCaseSensitive() ? Tristate.True : Tristate.False;
+
+ return s_isCaseSensitive == Tristate.True;
+ }
+ }
+
+ /// <summary>
+ /// Determines whether the file system is case sensitive.
+ /// </summary>
+ /// <remarks>
+ /// Ideally we'd use something like pathconf with _PC_CASE_SENSITIVE, but that is non-portable,
+ /// not supported on Windows or Linux, etc. For now, this function creates a tmp file with capital letters
+ /// and then tests for its existence with lower-case letters. This could return invalid results in corner
+ /// cases where, for example, different file systems are mounted with differing sensitivities.
+ /// </remarks>
+ private static bool GetIsCaseSensitive()
+ {
+ try
+ {
+ string pathWithUpperCase = Path.Combine(Path.GetTempPath(), "CASESENSITIVETEST" + Guid.NewGuid().ToString("N"));
+ using (new FileStream(pathWithUpperCase, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None, 0x1000, FileOptions.DeleteOnClose))
+ {
+ string lowerCased = pathWithUpperCase.ToLowerInvariant();
+ return !File.Exists(lowerCased);
+ }
+ }
+ catch (Exception exc)
+ {
+ // In case something goes terribly wrong, we don't want to fail just because
+ // of a casing test, so we assume case-insensitive-but-preserving.
+ Debug.Fail("Casing test failed: " + exc);
+ return false;
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/IO/PathInternal.Unix.cs b/src/mscorlib/corefx/System/IO/PathInternal.Unix.cs
new file mode 100644
index 0000000000..6c39f99556
--- /dev/null
+++ b/src/mscorlib/corefx/System/IO/PathInternal.Unix.cs
@@ -0,0 +1,122 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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
+ {
+ // There is only one invalid path character in Unix
+ private const char InvalidPathChar = '\0';
+ internal static char[] GetInvalidPathChars() => new char[] { InvalidPathChar };
+
+ internal static readonly int MaxComponentLength = Interop.Sys.MaxName;
+
+ internal const string ParentDirectoryPrefix = @"../";
+
+ /// <summary>Returns a value indicating if the given path contains invalid characters.</summary>
+ internal static bool HasIllegalCharacters(string path)
+ {
+ Debug.Assert(path != null);
+ return path.IndexOf(InvalidPathChar) >= 0;
+ }
+
+ internal static int GetRootLength(string path)
+ {
+ return path.Length > 0 && IsDirectorySeparator(path[0]) ? 1 : 0;
+ }
+
+ internal static bool IsDirectorySeparator(char c)
+ {
+ // The alternate directory separator char is the same as the directory separator,
+ // so we only need to check one.
+ Debug.Assert(Path.DirectorySeparatorChar == Path.AltDirectorySeparatorChar);
+ return c == Path.DirectorySeparatorChar;
+ }
+
+ /// <summary>
+ /// Returns true if the path is too long
+ /// </summary>
+ internal static bool IsPathTooLong(string fullPath)
+ {
+ return fullPath.Length >= Interop.Sys.MaxPath;
+ }
+
+ /// <summary>
+ /// Returns true if the directory is too long
+ /// </summary>
+ internal static bool IsDirectoryTooLong(string fullPath)
+ {
+ return fullPath.Length >= Interop.Sys.MaxPath;
+ }
+
+ /// <summary>
+ /// Normalize separators in the given path. Compresses forward slash runs.
+ /// </summary>
+ internal static string NormalizeDirectorySeparators(string path)
+ {
+ if (string.IsNullOrEmpty(path)) return path;
+
+ // 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++)
+ {
+ if (IsDirectorySeparator(path[i])
+ && (i + 1 < path.Length && IsDirectorySeparator(path[i + 1])))
+ {
+ normalized = false;
+ break;
+ }
+ }
+
+ if (normalized) return path;
+
+ StringBuilder builder = new StringBuilder(path.Length);
+
+ for (int i = 0; i < path.Length; i++)
+ {
+ char current = path[i];
+
+ // Skip if we have another separator following
+ if (IsDirectorySeparator(current)
+ && (i + 1 < path.Length && IsDirectorySeparator(path[i + 1])))
+ continue;
+
+ 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)
+ {
+ // The directory separator, volume separator, and the alternate directory
+ // separator should be the same on Unix, so we only need to check one.
+ Debug.Assert(Path.DirectorySeparatorChar == Path.AltDirectorySeparatorChar);
+ Debug.Assert(Path.DirectorySeparatorChar == Path.VolumeSeparatorChar);
+ return ch == Path.DirectorySeparatorChar;
+ }
+
+ internal static bool HasInvalidVolumeSeparator(string path)
+ {
+ // This is only ever true for Windows
+ return false;
+ }
+
+ internal static bool IsPartiallyQualified(string path)
+ {
+ // This is much simpler than Windows where paths can be rooted, but not fully qualified (such as Drive Relative)
+ // As long as the path is rooted in Unix it doesn't use the current directory and therefore is fully qualified.
+ return !Path.IsPathRooted(path);
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/IO/PathInternal.Windows.StringBuffer.cs b/src/mscorlib/corefx/System/IO/PathInternal.Windows.StringBuffer.cs
new file mode 100644
index 0000000000..fec2218844
--- /dev/null
+++ b/src/mscorlib/corefx/System/IO/PathInternal.Windows.StringBuffer.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.
+
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace System.IO
+{
+ /// <summary>Contains internal path helpers that are shared between many projects.</summary>
+ internal static partial class PathInternal
+ {
+ /// <summary>
+ /// Returns true if the path uses the extended syntax (\\?\)
+ /// </summary>
+ internal static bool IsExtended(StringBuffer 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>
+ /// Gets the length of the root of the path (drive, share, etc.).
+ /// </summary>
+ internal unsafe static uint GetRootLength(StringBuffer path)
+ {
+ if (path.Length == 0) return 0;
+ return GetRootLength(path.CharPointer, path.Length);
+ }
+
+ /// <summary>
+ /// Returns true if the path uses any of the DOS device path syntaxes. ("\\.\", "\\?\", or "\??\")
+ /// </summary>
+ internal static bool IsDevice(StringBuffer 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 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(StringBuffer 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] == Path.VolumeSeparatorChar)
+ && IsDirectorySeparator(path[2]));
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/IO/PathInternal.Windows.cs b/src/mscorlib/corefx/System/IO/PathInternal.Windows.cs
new file mode 100644
index 0000000000..bd7f1eae41
--- /dev/null
+++ b/src/mscorlib/corefx/System/IO/PathInternal.Windows.cs
@@ -0,0 +1,482 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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 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;
+
+ internal 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
+ };
+
+ // [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
+ private static readonly char[] s_wildcardChars =
+ {
+ '\"', '<', '>', '*', '?'
+ };
+
+ /// <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>
+ /// Returns true if the path is too long
+ /// </summary>
+ internal static bool IsPathTooLong(string fullPath)
+ {
+ // We'll never know precisely what will fail as paths get changed internally in Windows and
+ // may grow to exceed MaxLongPath.
+ return fullPath.Length >= MaxLongPath;
+ }
+
+ /// <summary>
+ /// Returns true if the directory is too long
+ /// </summary>
+ internal static bool IsDirectoryTooLong(string fullPath)
+ {
+ return IsPathTooLong(fullPath);
+ }
+
+ /// <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 <= '\u001f' || c == '|')
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ /// Check for known wildcard characters. '*' and '?' are the most common ones.
+ /// </summary>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal unsafe 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;
+
+ return path.IndexOfAny(s_wildcardChars, startIndex) >= 0;
+ }
+
+ /// <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 (int)GetRootLength(value, (uint)path.Length);
+ }
+ }
+
+ private unsafe static uint GetRootLength(char* path, uint pathLength)
+ {
+ uint i = 0;
+ uint volumeSeparatorLength = 2; // Length to the colon "C:"
+ uint 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 = (uint)UncExtendedPathPrefix.Length;
+ }
+ else
+ {
+ // "C:" -> "\\?\C:"
+ volumeSeparatorLength += (uint)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] == Path.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, uint sourceLength, string value)
+ {
+ if (sourceLength < (uint)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] == Path.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 == Path.DirectorySeparatorChar || c == Path.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 != Path.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(Path.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 = Path.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) || Path.VolumeSeparatorChar == ch;
+ }
+
+ /// <summary>
+ /// Validates volume separator only occurs as C: or \\?\C:. This logic is meant to filter out Alternate Data Streams.
+ /// </summary>
+ /// <returns>True if the path has an invalid volume separator.</returns>
+ internal static bool HasInvalidVolumeSeparator(string path)
+ {
+ // 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:" or "\\?\C:".
+ // (Note that we used to explicitly check "http:" and "file:"- these are caught by this check now.)
+
+ // We don't care about skipping starting space for extended paths. Assume no knowledge of extended paths if we're forcing old path behavior.
+ int startIndex = IsExtended(path) ? ExtendedPathPrefix.Length : PathStartSkip(path);
+
+ // If we start with a colon
+ if ((path.Length > startIndex && path[startIndex] == Path.VolumeSeparatorChar)
+ // Or have an invalid drive letter and colon
+ || (path.Length >= startIndex + 2 && path[startIndex + 1] == Path.VolumeSeparatorChar && !IsValidDriveChar(path[startIndex]))
+ // Or have any colons beyond the drive colon
+ || (path.Length > startIndex + 2 && path.IndexOf(Path.VolumeSeparatorChar, startIndex + 2) != -1))
+ {
+ return true;
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/IO/PathInternal.cs b/src/mscorlib/corefx/System/IO/PathInternal.cs
new file mode 100644
index 0000000000..ee67680df5
--- /dev/null
+++ b/src/mscorlib/corefx/System/IO/PathInternal.cs
@@ -0,0 +1,230 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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 true if the given StringBuilder starts with the given value.
+ /// </summary>
+ /// <param name="value">The string to compare against the start of the StringBuilder.</param>
+ internal static bool StartsWithOrdinal(this StringBuilder builder, string value)
+ {
+ if (value == null || builder.Length < value.Length)
+ return false;
+
+ for (int i = 0; i < value.Length; i++)
+ {
+ if (builder[i] != value[i]) return false;
+ }
+ return true;
+ }
+
+ /// <summary>
+ /// Returns true if the given string starts with the given value.
+ /// </summary>
+ /// <param name="value">The string to compare against the start of the source string.</param>
+ internal static bool StartsWithOrdinal(this string source, string value)
+ {
+ if (value == null || source.Length < value.Length)
+ return false;
+
+ return source.StartsWith(value, StringComparison.Ordinal);
+ }
+
+ /// <summary>
+ /// Trims the specified characters from the end of the StringBuilder.
+ /// </summary>
+ internal static StringBuilder TrimEnd(this StringBuilder builder, params char[] trimChars)
+ {
+ if (trimChars == null || trimChars.Length == 0)
+ return builder;
+
+ int end = builder.Length - 1;
+
+ for (; end >= 0; end--)
+ {
+ int i = 0;
+ char ch = builder[end];
+ for (; i < trimChars.Length; i++)
+ {
+ if (trimChars[i] == ch) break;
+ }
+ if (i == trimChars.Length)
+ {
+ // Not a trim char
+ break;
+ }
+ }
+
+ builder.Length = end + 1;
+ return builder;
+ }
+
+ /// <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/IO/Win32Marshal.cs b/src/mscorlib/corefx/System/IO/Win32Marshal.cs
new file mode 100644
index 0000000000..b4dfa04468
--- /dev/null
+++ b/src/mscorlib/corefx/System/IO/Win32Marshal.cs
@@ -0,0 +1,134 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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;
+
+namespace System.IO
+{
+ /// <summary>
+ /// Provides static methods for converting from Win32 errors codes to exceptions, HRESULTS and error messages.
+ /// </summary>
+ internal static class Win32Marshal
+ {
+ /// <summary>
+ /// Converts, resetting it, the last Win32 error into a corresponding <see cref="Exception"/> object.
+ /// </summary>
+ internal static Exception GetExceptionForLastWin32Error()
+ {
+ int errorCode = Marshal.GetLastWin32Error();
+ return GetExceptionForWin32Error(errorCode, string.Empty);
+ }
+
+ /// <summary>
+ /// Converts, resetting it, the last Win32 error into a corresponding <see cref="Exception"/> object, optionally
+ /// including the specified path in the error message.
+ /// </summary>
+ internal static Exception GetExceptionForLastWin32Error(string path)
+ {
+ int errorCode = Marshal.GetLastWin32Error();
+ return GetExceptionForWin32Error(errorCode, path);
+ }
+
+ /// <summary>
+ /// Converts the specified Win32 error into a corresponding <see cref="Exception"/> object.
+ /// </summary>
+ internal static Exception GetExceptionForWin32Error(int errorCode)
+ {
+ return GetExceptionForWin32Error(errorCode, string.Empty);
+ }
+
+ /// <summary>
+ /// Converts the specified Win32 error into a corresponding <see cref="Exception"/> object, optionally
+ /// including the specified path in the error message.
+ /// </summary>
+ internal static Exception GetExceptionForWin32Error(int errorCode, string path)
+ {
+ switch (errorCode)
+ {
+ case Interop.mincore.Errors.ERROR_FILE_NOT_FOUND:
+ if (path.Length == 0)
+ return new FileNotFoundException(SR.IO_FileNotFound);
+ else
+ return new FileNotFoundException(SR.Format(SR.IO_FileNotFound_FileName, path), path);
+
+ case Interop.mincore.Errors.ERROR_PATH_NOT_FOUND:
+ if (path.Length == 0)
+ return new DirectoryNotFoundException(SR.IO_PathNotFound_NoPathName);
+ else
+ return new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, path));
+
+ case Interop.mincore.Errors.ERROR_ACCESS_DENIED:
+ if (path.Length == 0)
+ return new UnauthorizedAccessException(SR.UnauthorizedAccess_IODenied_NoPathName);
+ else
+ return new UnauthorizedAccessException(SR.Format(SR.UnauthorizedAccess_IODenied_Path, path));
+
+ case Interop.mincore.Errors.ERROR_ALREADY_EXISTS:
+ if (path.Length == 0)
+ goto default;
+
+ return new IOException(SR.Format(SR.IO_AlreadyExists_Name, path), MakeHRFromErrorCode(errorCode));
+
+ case Interop.mincore.Errors.ERROR_FILENAME_EXCED_RANGE:
+ return new PathTooLongException(SR.IO_PathTooLong);
+
+ case Interop.mincore.Errors.ERROR_INVALID_PARAMETER:
+ return new IOException(GetMessage(errorCode), MakeHRFromErrorCode(errorCode));
+
+ case Interop.mincore.Errors.ERROR_SHARING_VIOLATION:
+ if (path.Length == 0)
+ return new IOException(SR.IO_SharingViolation_NoFileName, MakeHRFromErrorCode(errorCode));
+ else
+ return new IOException(SR.Format(SR.IO_SharingViolation_File, path), MakeHRFromErrorCode(errorCode));
+
+ case Interop.mincore.Errors.ERROR_FILE_EXISTS:
+ if (path.Length == 0)
+ goto default;
+
+ return new IOException(SR.Format(SR.IO_FileExists_Name, path), MakeHRFromErrorCode(errorCode));
+
+ case Interop.mincore.Errors.ERROR_OPERATION_ABORTED:
+ return new OperationCanceledException();
+
+ default:
+ return new IOException(GetMessage(errorCode), MakeHRFromErrorCode(errorCode));
+ }
+ }
+
+ /// <summary>
+ /// Returns a HRESULT for the specified Win32 error code.
+ /// </summary>
+ internal static int MakeHRFromErrorCode(int errorCode)
+ {
+ Debug.Assert((0xFFFF0000 & errorCode) == 0, "This is an HRESULT, not an error code!");
+
+ return unchecked(((int)0x80070000) | errorCode);
+ }
+
+ /// <summary>
+ /// Returns a Win32 error code for the specified HRESULT if it came from FACILITY_WIN32
+ /// If not, returns the HRESULT unchanged
+ /// </summary>
+ internal static int TryMakeWin32ErrorCodeFromHR(int hr)
+ {
+ if ((0xFFFF0000 & hr) == 0x80070000)
+ {
+ // Win32 error, Win32Marshal.GetExceptionForWin32Error expects the Win32 format
+ hr &= 0x0000FFFF;
+ }
+
+ return hr;
+ }
+
+ /// <summary>
+ /// Returns a string message for the specified Win32 error code.
+ /// </summary>
+ internal static string GetMessage(int errorCode)
+ {
+ return Interop.mincore.GetMessage(errorCode);
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/Runtime/InteropServices/NativeBuffer.cs b/src/mscorlib/corefx/System/Runtime/InteropServices/NativeBuffer.cs
new file mode 100644
index 0000000000..875009aee2
--- /dev/null
+++ b/src/mscorlib/corefx/System/Runtime/InteropServices/NativeBuffer.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.Runtime.CompilerServices;
+
+namespace System.Runtime.InteropServices
+{
+ /// <summary>
+ /// Wrapper for access to the native heap. Dispose to free the memory. Try to use with using statements.
+ /// Does not allocate zero size buffers, and will free the existing native buffer if capacity is dropped to zero.
+ ///
+ /// NativeBuffer utilizes a cache of heap buffers.
+ /// </summary>
+ /// <remarks>
+ /// Suggested use through P/Invoke: define DllImport arguments that take a byte buffer as SafeHandle.
+ ///
+ /// Using SafeHandle will ensure that the buffer will not get collected during a P/Invoke.
+ /// (Notably AddRef and ReleaseRef will be called by the interop layer.)
+ ///
+ /// This class is not threadsafe, changing the capacity or disposing on multiple threads risks duplicate heap
+ /// handles or worse.
+ /// </remarks>
+ internal class NativeBuffer : IDisposable
+ {
+ private readonly static SafeHeapHandleCache s_handleCache = new SafeHeapHandleCache();
+ private readonly static SafeHandle s_emptyHandle = new EmptySafeHandle();
+ private SafeHeapHandle _handle;
+ private ulong _capacity;
+
+ /// <summary>
+ /// Create a buffer with at least the specified initial capacity in bytes.
+ /// </summary>
+ public NativeBuffer(ulong initialMinCapacity = 0)
+ {
+ EnsureByteCapacity(initialMinCapacity);
+ }
+
+ protected unsafe void* VoidPointer
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get
+ {
+ return _handle == null ? null : _handle.DangerousGetHandle().ToPointer();
+ }
+ }
+
+ protected unsafe byte* BytePointer
+ {
+ get
+ {
+ return (byte*)VoidPointer;
+ }
+ }
+
+ /// <summary>
+ /// Get the handle for the buffer.
+ /// </summary>
+ public SafeHandle GetHandle()
+ {
+ // Marshalling code will throw on null for SafeHandle
+ return _handle ?? s_emptyHandle;
+ }
+
+ /// <summary>
+ /// The capacity of the buffer in bytes.
+ /// </summary>
+ public ulong ByteCapacity
+ {
+ get { return _capacity; }
+ }
+
+ /// <summary>
+ /// Ensure capacity in bytes is at least the given minimum.
+ /// </summary>
+ /// <exception cref="OutOfMemoryException">Thrown if unable to allocate memory when setting.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Thrown if attempting to set <paramref name="nameof(minCapacity)"/> to a value that is larger than the maximum addressable memory.</exception>
+ public void EnsureByteCapacity(ulong minCapacity)
+ {
+ if (_capacity < minCapacity)
+ {
+ Resize(minCapacity);
+ _capacity = minCapacity;
+ }
+ }
+
+ public unsafe byte this[ulong index]
+ {
+ get
+ {
+ if (index >= _capacity) throw new ArgumentOutOfRangeException();
+ return BytePointer[index];
+ }
+ set
+ {
+ if (index >= _capacity) throw new ArgumentOutOfRangeException();
+ BytePointer[index] = value;
+ }
+ }
+
+ private unsafe void Resize(ulong byteLength)
+ {
+ if (byteLength == 0)
+ {
+ ReleaseHandle();
+ return;
+ }
+
+ if (_handle == null)
+ {
+ _handle = s_handleCache.Acquire(byteLength);
+ }
+ else
+ {
+ _handle.Resize(byteLength);
+ }
+ }
+
+ private void ReleaseHandle()
+ {
+ if (_handle != null)
+ {
+ s_handleCache.Release(_handle);
+ _capacity = 0;
+ _handle = null;
+ }
+ }
+
+ /// <summary>
+ /// Release the backing buffer
+ /// </summary>
+ public virtual void Free()
+ {
+ ReleaseHandle();
+ }
+
+ public void Dispose()
+ {
+ Free();
+ }
+
+ private sealed class EmptySafeHandle : SafeHandle
+ {
+ public EmptySafeHandle() : base(IntPtr.Zero, true) { }
+
+ public override bool IsInvalid
+ {
+ get { return true; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ return true;
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/Runtime/InteropServices/SafeHeapHandle.cs b/src/mscorlib/corefx/System/Runtime/InteropServices/SafeHeapHandle.cs
new file mode 100644
index 0000000000..92b3d980db
--- /dev/null
+++ b/src/mscorlib/corefx/System/Runtime/InteropServices/SafeHeapHandle.cs
@@ -0,0 +1,109 @@
+// Licensed to the .NET Foundation under one or more 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
+{
+ /// <summary>
+ /// Handle for heap memory that allows tracking of capacity and reallocating.
+ /// </summary>
+ internal sealed class SafeHeapHandle : SafeBuffer
+ {
+ /// <summary>
+ /// Allocate a buffer of the given size if requested.
+ /// </summary>
+ /// <param name="byteLength">Required size in bytes. Must be less than UInt32.MaxValue for 32 bit or UInt64.MaxValue for 64 bit.</param>
+ /// <exception cref="OutOfMemoryException">Thrown if the requested memory size cannot be allocated.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Thrown if size is greater than the maximum memory size.</exception>
+ public SafeHeapHandle(ulong byteLength) : base(ownsHandle: true)
+ {
+ Resize(byteLength);
+ }
+
+ public override bool IsInvalid
+ {
+ get { return handle == IntPtr.Zero; }
+ }
+
+ /// <summary>
+ /// Resize the buffer to the given size if requested.
+ /// </summary>
+ /// <param name="byteLength">Required size in bytes. Must be less than UInt32.MaxValue for 32 bit or UInt64.MaxValue for 64 bit.</param>
+ /// <exception cref="OutOfMemoryException">Thrown if the requested memory size cannot be allocated.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Thrown if size is greater than the maximum memory size.</exception>
+ public void Resize(ulong byteLength)
+ {
+ if (IsClosed) throw new ObjectDisposedException(nameof(SafeHeapHandle));
+
+ ulong originalLength = 0;
+ if (handle == IntPtr.Zero)
+ {
+ handle = Marshal.AllocHGlobal((IntPtr)byteLength);
+ }
+ else
+ {
+ originalLength = ByteLength;
+
+ // This may or may not be the same handle, may realloc in place. If the
+ // handle changes Windows will deal with the old handle, trying to free it will
+ // cause an error.
+ handle = Marshal.ReAllocHGlobal(pv: handle, cb: (IntPtr)byteLength);
+ }
+
+ if (handle == IntPtr.Zero)
+ {
+ // Only real plausible answer
+ throw new OutOfMemoryException();
+ }
+
+ if (byteLength > originalLength)
+ {
+ // Add pressure
+ ulong addedBytes = byteLength - originalLength;
+ if (addedBytes > long.MaxValue)
+ {
+ GC.AddMemoryPressure(long.MaxValue);
+ GC.AddMemoryPressure((long)(addedBytes - long.MaxValue));
+ }
+ else
+ {
+ GC.AddMemoryPressure((long)addedBytes);
+ }
+ }
+ else
+ {
+ // Shrank or did nothing, release pressure if needed
+ RemoveMemoryPressure(originalLength - byteLength);
+ }
+
+ Initialize(byteLength);
+ }
+
+ private void RemoveMemoryPressure(ulong removedBytes)
+ {
+ if (removedBytes == 0) return;
+
+ if (removedBytes > long.MaxValue)
+ {
+ GC.RemoveMemoryPressure(long.MaxValue);
+ GC.RemoveMemoryPressure((long)(removedBytes - long.MaxValue));
+ }
+ else
+ {
+ GC.RemoveMemoryPressure((long)removedBytes);
+ }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ if (handle != IntPtr.Zero)
+ {
+ RemoveMemoryPressure(ByteLength);
+ Marshal.FreeHGlobal(handle);
+ }
+
+ handle = IntPtr.Zero;
+ return true;
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/Runtime/InteropServices/SafeHeapHandleCache.cs b/src/mscorlib/corefx/System/Runtime/InteropServices/SafeHeapHandleCache.cs
new file mode 100644
index 0000000000..725076ed66
--- /dev/null
+++ b/src/mscorlib/corefx/System/Runtime/InteropServices/SafeHeapHandleCache.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.
+
+using System.Threading;
+
+namespace System.Runtime.InteropServices
+{
+ /// <summary>
+ /// Allows limited thread safe reuse of heap buffers to limit memory pressure.
+ ///
+ /// This cache does not ensure that multiple copies of handles are not released back into the cache.
+ /// </summary>
+ internal sealed class SafeHeapHandleCache : IDisposable
+ {
+ private readonly ulong _minSize;
+ private readonly ulong _maxSize;
+
+ // internal for testing
+ internal readonly SafeHeapHandle[] _handleCache;
+
+ /// <param name="minSize">Smallest buffer size to allocate in bytes.</param>
+ /// <param name="maxSize">The largest buffer size to cache in bytes.</param>
+ /// <param name="maxHandles">The maximum number of handles to cache.</param>
+ public SafeHeapHandleCache(ulong minSize = 64, ulong maxSize = 1024 * 2, int maxHandles = 0)
+ {
+ _minSize = minSize;
+ _maxSize = maxSize;
+ _handleCache = new SafeHeapHandle[maxHandles > 0 ? maxHandles : Environment.ProcessorCount * 4];
+ }
+
+ /// <summary>
+ /// Get a HeapHandle
+ /// </summary>
+ public SafeHeapHandle Acquire(ulong minSize = 0)
+ {
+ if (minSize < _minSize) minSize = _minSize;
+
+ SafeHeapHandle handle = null;
+
+ for (int i = 0; i < _handleCache.Length; i++)
+ {
+ handle = Interlocked.Exchange(ref _handleCache[i], null);
+ if (handle != null) break;
+ }
+
+ if (handle != null)
+ {
+ // One possible future consideration is to attempt cycling through to
+ // find one that might already have sufficient capacity
+ if (handle.ByteLength < minSize)
+ handle.Resize(minSize);
+ }
+ else
+ {
+ handle = new SafeHeapHandle(minSize);
+ }
+
+ return handle;
+ }
+
+ /// <summary>
+ /// Give a HeapHandle back for potential reuse
+ /// </summary>
+ public void Release(SafeHeapHandle handle)
+ {
+ if (handle.ByteLength <= _maxSize)
+ {
+ for (int i = 0; i < _handleCache.Length; i++)
+ {
+ // Push the handles down, walking the last one off the end to keep
+ // the top of the "stack" fresh
+ handle = Interlocked.Exchange(ref _handleCache[i], handle);
+ if (handle == null) return;
+ }
+ }
+
+ handle.Dispose();
+ }
+
+ public void Dispose()
+ {
+ Dispose(disposing: true);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposing && _handleCache != null)
+ {
+ foreach (SafeHeapHandle handle in _handleCache)
+ {
+ if (handle != null) handle.Dispose();
+ }
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/Runtime/InteropServices/StringBuffer.cs b/src/mscorlib/corefx/System/Runtime/InteropServices/StringBuffer.cs
new file mode 100644
index 0000000000..29cef08b6c
--- /dev/null
+++ b/src/mscorlib/corefx/System/Runtime/InteropServices/StringBuffer.cs
@@ -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.
+
+namespace System.Runtime.InteropServices
+{
+ /// <summary>
+ /// Native buffer that deals in char size increments. Dispose to free memory. Allows buffers larger
+ /// than a maximum size string to enable working with very large string arrays. Always makes ordinal
+ /// comparisons.
+ ///
+ /// A more performant replacement for StringBuilder when performing native interop.
+ /// </summary>
+ /// <remarks>
+ /// Suggested use through P/Invoke: define DllImport arguments that take a character buffer as SafeHandle and pass StringBuffer.GetHandle().
+ /// </remarks>
+ internal class StringBuffer : NativeBuffer
+ {
+ private uint _length;
+
+ /// <summary>
+ /// Instantiate the buffer with capacity for at least the specified number of characters. Capacity
+ /// includes the trailing null character.
+ /// </summary>
+ public StringBuffer(uint initialCapacity = 0)
+ : base(initialCapacity * (ulong)sizeof(char))
+ {
+ }
+
+ /// <summary>
+ /// Get/set the character at the given index.
+ /// </summary>
+ /// <exception cref="ArgumentOutOfRangeException">Thrown if attempting to index outside of the buffer length.</exception>
+ public unsafe char this[uint index]
+ {
+ get
+ {
+ if (index >= _length) throw new ArgumentOutOfRangeException(nameof(index));
+ return CharPointer[index];
+ }
+ set
+ {
+ if (index >= _length) throw new ArgumentOutOfRangeException(nameof(index));
+ CharPointer[index] = value;
+ }
+ }
+
+ /// <summary>
+ /// Character capacity of the buffer. Includes the count for the trailing null character.
+ /// </summary>
+ public uint CharCapacity
+ {
+ get
+ {
+ ulong byteCapacity = ByteCapacity;
+ ulong charCapacity = byteCapacity == 0 ? 0 : byteCapacity / sizeof(char);
+ return charCapacity > uint.MaxValue ? uint.MaxValue : (uint)charCapacity;
+ }
+ }
+
+ /// <summary>
+ /// Ensure capacity in characters is at least the given minimum.
+ /// </summary>
+ /// <exception cref="OutOfMemoryException">Thrown if unable to allocate memory when setting.</exception>
+ public void EnsureCharCapacity(uint minCapacity)
+ {
+ EnsureByteCapacity(minCapacity * (ulong)sizeof(char));
+ }
+
+ /// <summary>
+ /// The logical length of the buffer in characters. (Does not include the final null.) Will automatically attempt to increase capacity.
+ /// This is where the usable data ends.
+ /// </summary>
+ /// <exception cref="OutOfMemoryException">Thrown if unable to allocate memory when setting.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Thrown if the set size in bytes is uint.MaxValue (as space is implicitly reserved for the trailing null).</exception>
+ public unsafe uint Length
+ {
+ get { return _length; }
+ set
+ {
+ if (value == uint.MaxValue) throw new ArgumentOutOfRangeException(nameof(Length));
+
+ // Null terminate
+ EnsureCharCapacity(value + 1);
+ CharPointer[value] = '\0';
+
+ _length = value;
+ }
+ }
+
+ /// <summary>
+ /// For use when the native api null terminates but doesn't return a length.
+ /// If no null is found, the length will not be changed.
+ /// </summary>
+ public unsafe void SetLengthToFirstNull()
+ {
+ char* buffer = CharPointer;
+ uint capacity = CharCapacity;
+ for (uint i = 0; i < capacity; i++)
+ {
+ if (buffer[i] == '\0')
+ {
+ _length = i;
+ break;
+ }
+ }
+ }
+
+ internal unsafe char* CharPointer
+ {
+ get
+ {
+ return (char*)VoidPointer;
+ }
+ }
+
+ /// <summary>
+ /// True if the buffer contains the given character.
+ /// </summary>
+ public unsafe bool Contains(char value)
+ {
+ char* start = CharPointer;
+ uint length = _length;
+
+ for (uint i = 0; i < length; i++)
+ {
+ if (*start++ == value) return true;
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ /// Returns true if the buffer starts with the given string.
+ /// </summary>
+ public bool StartsWith(string value)
+ {
+ if (value == null) throw new ArgumentNullException(nameof(value));
+ if (_length < (uint)value.Length) return false;
+ return SubstringEquals(value, startIndex: 0, count: value.Length);
+ }
+
+ /// <summary>
+ /// Returns true if the specified StringBuffer substring equals the given value.
+ /// </summary>
+ /// <param name="value">The value to compare against the specified substring.</param>
+ /// <param name="startIndex">Start index of the sub string.</param>
+ /// <param name="count">Length of the substring, or -1 to check all remaining.</param>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// Thrown if <paramref name="startIndex"/> or <paramref name="count"/> are outside the range
+ /// of the buffer's length.
+ /// </exception>
+ public unsafe bool SubstringEquals(string value, uint startIndex = 0, int count = -1)
+ {
+ if (value == null) return false;
+ if (count < -1) throw new ArgumentOutOfRangeException(nameof(count));
+ if (startIndex > _length) throw new ArgumentOutOfRangeException(nameof(startIndex));
+
+ uint realCount = count == -1 ? _length - startIndex : (uint)count;
+ if (checked(startIndex + realCount) > _length) throw new ArgumentOutOfRangeException(nameof(count));
+
+ int length = value.Length;
+
+ // Check the substring length against the input length
+ if (realCount != (uint)length) return false;
+
+ fixed (char* valueStart = value)
+ {
+ char* bufferStart = CharPointer + startIndex;
+ for (int i = 0; i < length; i++)
+ {
+ // Note that indexing in this case generates faster code than trying to copy the pointer and increment it
+ if (*bufferStart++ != valueStart[i]) return false;
+ }
+ }
+
+ return true;
+ }
+
+ /// <summary>
+ /// Append the given string.
+ /// </summary>
+ /// <param name="value">The string to append.</param>
+ /// <param name="startIndex">The index in the input string to start appending from.</param>
+ /// <param name="count">The count of characters to copy from the input string, or -1 for all remaining.</param>
+ /// <exception cref="ArgumentNullException">Thrown if <paramref name="value"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// Thrown if <paramref name="startIndex"/> or <paramref name="count"/> are outside the range
+ /// of <paramref name="value"/> characters.
+ /// </exception>
+ public void Append(string value, int startIndex = 0, int count = -1)
+ {
+ CopyFrom(
+ bufferIndex: _length,
+ source: value,
+ sourceIndex: startIndex,
+ count: count);
+ }
+
+ /// <summary>
+ /// Append the given buffer.
+ /// </summary>
+ /// <param name="value">The buffer to append.</param>
+ /// <param name="startIndex">The index in the input buffer to start appending from.</param>
+ /// <param name="count">The count of characters to copy from the buffer string.</param>
+ /// <exception cref="ArgumentNullException">Thrown if <paramref name="value"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// Thrown if <paramref name="startIndex"/> or <paramref name="count"/> are outside the range
+ /// of <paramref name="value"/> characters.
+ /// </exception>
+ public void Append(StringBuffer value, uint startIndex = 0)
+ {
+ if (value == null) throw new ArgumentNullException(nameof(value));
+ if (value.Length == 0) return;
+
+ value.CopyTo(
+ bufferIndex: startIndex,
+ destination: this,
+ destinationIndex: _length,
+ count: value.Length);
+ }
+
+ /// <summary>
+ /// Append the given buffer.
+ /// </summary>
+ /// <param name="value">The buffer to append.</param>
+ /// <param name="startIndex">The index in the input buffer to start appending from.</param>
+ /// <param name="count">The count of characters to copy from the buffer string.</param>
+ /// <exception cref="ArgumentNullException">Thrown if <paramref name="value"/> is null.</exception>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// Thrown if <paramref name="startIndex"/> or <paramref name="count"/> are outside the range
+ /// of <paramref name="value"/> characters.
+ /// </exception>
+ public void Append(StringBuffer value, uint startIndex, uint count)
+ {
+ if (value == null) throw new ArgumentNullException(nameof(value));
+ if (count == 0) return;
+
+ value.CopyTo(
+ bufferIndex: startIndex,
+ destination: this,
+ destinationIndex: _length,
+ count: count);
+ }
+
+ /// <summary>
+ /// Copy contents to the specified buffer. Destination index must be within current destination length.
+ /// Will grow the destination buffer if needed.
+ /// </summary>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// Thrown if <paramref name="bufferIndex"/> or <paramref name="destinationIndex"/> or <paramref name="count"/> are outside the range
+ /// of <paramref name="value"/> characters.
+ /// </exception>
+ /// <exception cref="ArgumentNullException">Thrown if <paramref name="destination"/> is null.</exception>
+ public unsafe void CopyTo(uint bufferIndex, StringBuffer destination, uint destinationIndex, uint count)
+ {
+ if (destination == null) throw new ArgumentNullException(nameof(destination));
+ if (destinationIndex > destination._length) throw new ArgumentOutOfRangeException(nameof(destinationIndex));
+ if (bufferIndex >= _length) throw new ArgumentOutOfRangeException(nameof(bufferIndex));
+ if (_length < checked(bufferIndex + count)) throw new ArgumentOutOfRangeException(nameof(count));
+
+ if (count == 0) return;
+ uint lastIndex = checked(destinationIndex + count);
+ if (destination._length < lastIndex) destination.Length = lastIndex;
+
+ Buffer.MemoryCopy(
+ source: CharPointer + bufferIndex,
+ destination: destination.CharPointer + destinationIndex,
+ destinationSizeInBytes: checked((long)(destination.ByteCapacity - (destinationIndex * sizeof(char)))),
+ sourceBytesToCopy: checked((long)count * sizeof(char)));
+ }
+
+ /// <summary>
+ /// Copy contents from the specified string into the buffer at the given index. Start index must be within the current length of
+ /// the buffer, will grow as necessary.
+ /// </summary>
+ public unsafe void CopyFrom(uint bufferIndex, string source, int sourceIndex = 0, int count = -1)
+ {
+ if (source == null) throw new ArgumentNullException(nameof(source));
+ if (bufferIndex > _length) throw new ArgumentOutOfRangeException(nameof(bufferIndex));
+ if (sourceIndex < 0 || sourceIndex > source.Length) throw new ArgumentOutOfRangeException(nameof(sourceIndex));
+ if (count == -1) count = source.Length - sourceIndex;
+ if (count < 0 || source.Length - count < sourceIndex) throw new ArgumentOutOfRangeException(nameof(count));
+
+ if (count == 0) return;
+ uint lastIndex = bufferIndex + (uint)count;
+ if (_length < lastIndex) Length = lastIndex;
+
+ fixed (char* content = source)
+ {
+ Buffer.MemoryCopy(
+ source: content + sourceIndex,
+ destination: CharPointer + bufferIndex,
+ destinationSizeInBytes: checked((long)(ByteCapacity - (bufferIndex * sizeof(char)))),
+ sourceBytesToCopy: (long)count * sizeof(char));
+ }
+ }
+
+ /// <summary>
+ /// Trim the specified values from the end of the buffer. If nothing is specified, nothing is trimmed.
+ /// </summary>
+ public unsafe void TrimEnd(char[] values)
+ {
+ if (values == null || values.Length == 0 || _length == 0) return;
+
+ char* end = CharPointer + _length - 1;
+
+ while (_length > 0 && Array.IndexOf(values, *end) >= 0)
+ {
+ Length = _length - 1;
+ end--;
+ }
+ }
+
+ /// <summary>
+ /// String representation of the entire buffer. If the buffer is larger than the maximum size string (int.MaxValue) this will throw.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">Thrown if the buffer is too big to fit into a string.</exception>
+ public unsafe override string ToString()
+ {
+ if (_length == 0) return string.Empty;
+ if (_length > int.MaxValue) throw new InvalidOperationException();
+ return new string(CharPointer, startIndex: 0, length: (int)_length);
+ }
+
+ /// <summary>
+ /// Get the given substring in the buffer.
+ /// </summary>
+ /// <param name="count">Count of characters to take, or remaining characters from <paramref name="startIndex"/> if -1.</param>
+ /// <exception cref="ArgumentOutOfRangeException">
+ /// Thrown if <paramref name="startIndex"/> or <paramref name="count"/> are outside the range of the buffer's length
+ /// or count is greater than the maximum string size (int.MaxValue).
+ /// </exception>
+ public unsafe string Substring(uint startIndex, int count = -1)
+ {
+ if (startIndex > (_length == 0 ? 0 : _length - 1)) throw new ArgumentOutOfRangeException(nameof(startIndex));
+ if (count < -1) throw new ArgumentOutOfRangeException(nameof(count));
+
+ uint realCount = count == -1 ? _length - startIndex : (uint)count;
+ if (realCount > int.MaxValue || checked(startIndex + realCount) > _length) throw new ArgumentOutOfRangeException(nameof(count));
+ if (realCount == 0) return string.Empty;
+
+ // The buffer could be bigger than will fit into a string, but the substring might fit. As the starting
+ // index might be bigger than int we need to index ourselves.
+ return new string(value: CharPointer + startIndex, startIndex: 0, length: (int)realCount);
+ }
+
+ public override void Free()
+ {
+ base.Free();
+ _length = 0;
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/Security/CryptographicException.cs b/src/mscorlib/corefx/System/Security/CryptographicException.cs
new file mode 100644
index 0000000000..89cb658aa9
--- /dev/null
+++ b/src/mscorlib/corefx/System/Security/CryptographicException.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.Globalization;
+using System.Runtime.Serialization;
+
+namespace System.Security.Cryptography
+{
+ [Serializable]
+ public class CryptographicException : SystemException
+ {
+ public CryptographicException()
+ : base(SR.Arg_CryptographyException)
+ {
+ }
+
+ public CryptographicException(int hr)
+ : base(SR.Arg_CryptographyException)
+ {
+ HResult = hr;
+ }
+
+ public CryptographicException(string message)
+ : base(message)
+ {
+ }
+
+ public CryptographicException(string message, Exception inner)
+ : base(message, inner)
+ {
+ }
+
+ public CryptographicException(string format, string insert)
+ : base(string.Format(CultureInfo.CurrentCulture, format, insert))
+ {
+ }
+
+ protected CryptographicException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/Security/SafeBSTRHandle.cs b/src/mscorlib/corefx/System/Security/SafeBSTRHandle.cs
new file mode 100644
index 0000000000..19d63d41e4
--- /dev/null
+++ b/src/mscorlib/corefx/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)
+ {
+ 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.Unix.cs b/src/mscorlib/corefx/System/Security/SecureString.Unix.cs
new file mode 100644
index 0000000000..0ef38e40ee
--- /dev/null
+++ b/src/mscorlib/corefx/System/Security/SecureString.Unix.cs
@@ -0,0 +1,295 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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.Security
+{
+ // SecureString attempts to provide a defense-in-depth solution.
+ //
+ // On Windows, this is done with several mechanisms:
+ // 1. keeping the data in unmanaged memory so that copies of it aren't implicitly made by the GC moving it around
+ // 2. zero'ing out that unmanaged memory so that the string is reliably removed from memory when done with it
+ // 3. encrypting the data while it's not being used (it's unencrypted to manipulate and use it)
+ //
+ // On Unix, we do 1 and 2, but we don't do 3 as there's no CryptProtectData equivalent.
+
+ public sealed partial class SecureString
+ {
+ private UnmanagedBuffer _buffer;
+
+ internal SecureString(SecureString str)
+ {
+ // Allocate enough space to store the provided string
+ EnsureCapacity(str._decryptedLength);
+ _decryptedLength = str._decryptedLength;
+
+ // Copy the string into the newly allocated space
+ if (_decryptedLength > 0)
+ {
+ UnmanagedBuffer.Copy(str._buffer, _buffer, (ulong)(str._decryptedLength * sizeof(char)));
+ }
+ }
+
+ private unsafe void InitializeSecureString(char* value, int length)
+ {
+ // Allocate enough space to store the provided string
+ EnsureCapacity(length);
+ _decryptedLength = length;
+ if (length == 0)
+ {
+ return;
+ }
+
+ // Copy the string into the newly allocated space
+ byte* ptr = null;
+ try
+ {
+ _buffer.AcquirePointer(ref ptr);
+ Buffer.MemoryCopy(value, ptr, _buffer.ByteLength, (ulong)(length * sizeof(char)));
+ }
+ finally
+ {
+ if (ptr != null)
+ {
+ _buffer.ReleasePointer();
+ }
+ }
+ }
+
+ private void DisposeCore()
+ {
+ if (_buffer != null && !_buffer.IsInvalid)
+ {
+ _buffer.Dispose();
+ _buffer = null;
+ }
+ }
+
+ private void EnsureNotDisposed()
+ {
+ if (_buffer == null)
+ {
+ throw new ObjectDisposedException(GetType().Name);
+ }
+ }
+
+ private void ClearCore()
+ {
+ _decryptedLength = 0;
+ _buffer.Clear();
+ }
+
+ private unsafe void AppendCharCore(char c)
+ {
+ // Make sure we have enough space for the new character, then write it at the end.
+ EnsureCapacity(_decryptedLength + 1);
+ _buffer.Write((ulong)(_decryptedLength * sizeof(char)), c);
+ _decryptedLength++;
+ }
+
+ private unsafe void InsertAtCore(int index, char c)
+ {
+ // Make sure we have enough space for the new character, then shift all of the characters above it and insert it.
+ EnsureCapacity(_decryptedLength + 1);
+ byte* ptr = null;
+ try
+ {
+ _buffer.AcquirePointer(ref ptr);
+ ptr += index * sizeof(char);
+ long bytesToShift = (_decryptedLength - index) * sizeof(char);
+ Buffer.MemoryCopy(ptr, ptr + sizeof(char), bytesToShift, bytesToShift);
+ *((char*)ptr) = c;
+ ++_decryptedLength;
+ }
+ finally
+ {
+ if (ptr != null)
+ {
+ _buffer.ReleasePointer();
+ }
+ }
+ }
+
+ private unsafe void RemoveAtCore(int index)
+ {
+ // Shift down all values above the specified index, then null out the empty space at the end.
+ byte* ptr = null;
+ try
+ {
+ _buffer.AcquirePointer(ref ptr);
+ ptr += index * sizeof(char);
+ long bytesToShift = (_decryptedLength - index - 1) * sizeof(char);
+ Buffer.MemoryCopy(ptr + sizeof(char), ptr, bytesToShift, bytesToShift);
+ *((char*)(ptr + bytesToShift)) = (char)0;
+ --_decryptedLength;
+ }
+ finally
+ {
+ if (ptr != null)
+ {
+ _buffer.ReleasePointer();
+ }
+ }
+ }
+
+ private void SetAtCore(int index, char c)
+ {
+ // Overwrite the character at the specified index
+ _buffer.Write((ulong)(index * sizeof(char)), c);
+ }
+
+ internal unsafe IntPtr MarshalToStringCore(bool globalAlloc, bool unicode)
+ {
+ int length = _decryptedLength;
+
+ byte* bufferPtr = null;
+ IntPtr stringPtr = IntPtr.Zero, result = IntPtr.Zero;
+ try
+ {
+ _buffer.AcquirePointer(ref bufferPtr);
+ if (unicode)
+ {
+ int resultLength = (length + 1) * sizeof(char);
+ stringPtr = globalAlloc ? Marshal.AllocHGlobal(resultLength) : Marshal.AllocCoTaskMem(resultLength);
+ Buffer.MemoryCopy(
+ source: bufferPtr,
+ destination: (byte*)stringPtr.ToPointer(),
+ destinationSizeInBytes: resultLength,
+ sourceBytesToCopy: length * sizeof(char));
+ *(length + (char*)stringPtr) = '\0';
+ }
+ else
+ {
+ int resultLength = Encoding.UTF8.GetByteCount((char*)bufferPtr, length) + 1;
+ stringPtr = globalAlloc ? Marshal.AllocHGlobal(resultLength) : Marshal.AllocCoTaskMem(resultLength);
+ int encodedLength = Encoding.UTF8.GetBytes((char*)bufferPtr, length, (byte*)stringPtr, resultLength);
+ Debug.Assert(encodedLength + 1 == resultLength, $"Expected encoded length to match result, got {encodedLength} != {resultLength}");
+ *(resultLength - 1 + (byte*)stringPtr) = 0;
+ }
+
+ result = stringPtr;
+ }
+ finally
+ {
+ // If there was a failure, such that result isn't initialized,
+ // release the string if we had one.
+ if (stringPtr != IntPtr.Zero && result == IntPtr.Zero)
+ {
+ UnmanagedBuffer.ZeroMemory((byte*)stringPtr, (ulong)(length * sizeof(char)));
+ MarshalFree(stringPtr, globalAlloc);
+ }
+
+ if (bufferPtr != null)
+ {
+ _buffer.ReleasePointer();
+ }
+ }
+
+ return result;
+ }
+
+ // -----------------------------
+ // ---- PAL layer ends here ----
+ // -----------------------------
+
+ private void EnsureCapacity(int capacity)
+ {
+ // Make sure the requested capacity doesn't exceed SecureString's defined limit
+ if (capacity > MaxLength)
+ {
+ throw new ArgumentOutOfRangeException(nameof(capacity), SR.ArgumentOutOfRange_Capacity);
+ }
+
+ // If we already have enough space allocated, we're done
+ if (_buffer != null && (capacity * sizeof(char)) <= (int)_buffer.ByteLength)
+ {
+ return;
+ }
+
+ // We need more space, so allocate a new buffer, copy all our data into it,
+ // and then swap the new for the old.
+ UnmanagedBuffer newBuffer = UnmanagedBuffer.Allocate(capacity * sizeof(char));
+ if (_buffer != null)
+ {
+ UnmanagedBuffer.Copy(_buffer, newBuffer, _buffer.ByteLength);
+ _buffer.Dispose();
+ }
+ _buffer = newBuffer;
+ }
+
+ /// <summary>SafeBuffer for managing memory meant to be kept confidential.</summary>
+ private sealed class UnmanagedBuffer : SafeBuffer
+ {
+ internal UnmanagedBuffer() : base(true) { }
+
+ internal static UnmanagedBuffer Allocate(int bytes)
+ {
+ Debug.Assert(bytes >= 0);
+ UnmanagedBuffer buffer = new UnmanagedBuffer();
+ buffer.SetHandle(Marshal.AllocHGlobal(bytes));
+ buffer.Initialize((ulong)bytes);
+ return buffer;
+ }
+
+ internal unsafe void Clear()
+ {
+ byte* ptr = null;
+ try
+ {
+ AcquirePointer(ref ptr);
+ ZeroMemory(ptr, ByteLength);
+ }
+ finally
+ {
+ if (ptr != null)
+ {
+ ReleasePointer();
+ }
+ }
+ }
+
+ internal static unsafe void Copy(UnmanagedBuffer source, UnmanagedBuffer destination, ulong bytesLength)
+ {
+ if (bytesLength == 0)
+ {
+ return;
+ }
+
+ byte* srcPtr = null, dstPtr = null;
+ try
+ {
+ source.AcquirePointer(ref srcPtr);
+ destination.AcquirePointer(ref dstPtr);
+ Buffer.MemoryCopy(srcPtr, dstPtr, destination.ByteLength, bytesLength);
+ }
+ finally
+ {
+ if (dstPtr != null)
+ {
+ destination.ReleasePointer();
+ }
+ if (srcPtr != null)
+ {
+ source.ReleasePointer();
+ }
+ }
+ }
+
+ protected override unsafe bool ReleaseHandle()
+ {
+ Marshal.FreeHGlobal(handle);
+ return true;
+ }
+
+ internal static unsafe void ZeroMemory(byte* ptr, ulong len)
+ {
+ for (ulong i = 0; i < len; i++) *ptr++ = 0;
+ }
+ }
+
+ }
+}
diff --git a/src/mscorlib/corefx/System/Security/SecureString.Windows.cs b/src/mscorlib/corefx/System/Security/SecureString.Windows.cs
new file mode 100644
index 0000000000..5f56353647
--- /dev/null
+++ b/src/mscorlib/corefx/System/Security/SecureString.Windows.cs
@@ -0,0 +1,310 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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.mincore.WideCharToMultiByte(
+ Interop.mincore.CP_ACP, Interop.mincore.WC_NO_BEST_FIT_CHARS, (char*)bufferPtr, length, null, 0, (IntPtr)(&defaultChar), IntPtr.Zero);
+ ptr = globalAlloc ? Marshal.AllocHGlobal(resultByteLength) : Marshal.AllocCoTaskMem(resultByteLength);
+ Interop.mincore.WideCharToMultiByte(
+ Interop.mincore.CP_ACP, Interop.mincore.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/corefx/System/Security/SecureString.cs
new file mode 100644
index 0000000000..9059f90e60
--- /dev/null
+++ b/src/mscorlib/corefx/System/Security/SecureString.cs
@@ -0,0 +1,189 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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;
+
+namespace System.Security
+{
+ public sealed partial class SecureString : IDisposable
+ {
+ private const int MaxLength = 65536;
+ private readonly object _methodLock = new object();
+ private bool _readOnly;
+ private int _decryptedLength;
+
+ public unsafe SecureString()
+ {
+ InitializeSecureString(null, 0);
+ }
+
+ [CLSCompliant(false)]
+ public unsafe SecureString(char* value, int length)
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value));
+ }
+ if (length < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_NeedNonNegNum);
+ }
+ if (length > MaxLength)
+ {
+ throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_Length);
+ }
+
+ InitializeSecureString(value, length);
+ }
+
+ public int Length
+ {
+ get
+ {
+ lock (_methodLock)
+ {
+ EnsureNotDisposed();
+ return _decryptedLength;
+ }
+ }
+ }
+
+ public void AppendChar(char c)
+ {
+ lock (_methodLock)
+ {
+ EnsureNotDisposed();
+ EnsureNotReadOnly();
+ AppendCharCore(c);
+ }
+ }
+
+ // clears the current contents. Only available if writable
+ public void Clear()
+ {
+ lock (_methodLock)
+ {
+ EnsureNotDisposed();
+ EnsureNotReadOnly();
+ ClearCore();
+ }
+ }
+
+ // Do a deep-copy of the SecureString
+ public SecureString Copy()
+ {
+ lock (_methodLock)
+ {
+ EnsureNotDisposed();
+ return new SecureString(this);
+ }
+ }
+
+ public void Dispose()
+ {
+ lock (_methodLock)
+ {
+ DisposeCore();
+ }
+ }
+
+ public void InsertAt(int index, char c)
+ {
+ lock (_methodLock)
+ {
+ if (index < 0 || index > _decryptedLength)
+ {
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_IndexString);
+ }
+
+ EnsureNotDisposed();
+ EnsureNotReadOnly();
+
+ InsertAtCore(index, c);
+ }
+ }
+
+ public bool IsReadOnly()
+ {
+ lock (_methodLock)
+ {
+ EnsureNotDisposed();
+ return _readOnly;
+ }
+ }
+
+ public void MakeReadOnly()
+ {
+ lock (_methodLock)
+ {
+ EnsureNotDisposed();
+ _readOnly = true;
+ }
+ }
+
+ public void RemoveAt(int index)
+ {
+ lock (_methodLock)
+ {
+ EnsureNotDisposed();
+ EnsureNotReadOnly();
+
+ if (index < 0 || index >= _decryptedLength)
+ {
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_IndexString);
+ }
+
+ RemoveAtCore(index);
+ }
+ }
+
+ public void SetAt(int index, char c)
+ {
+ lock (_methodLock)
+ {
+ if (index < 0 || index >= _decryptedLength)
+ {
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_IndexString);
+ }
+ Debug.Assert(index <= Int32.MaxValue / sizeof(char));
+
+ EnsureNotDisposed();
+ EnsureNotReadOnly();
+
+ SetAtCore(index, c);
+ }
+ }
+
+ private void EnsureNotReadOnly()
+ {
+ if (_readOnly)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ }
+ }
+
+ internal unsafe IntPtr MarshalToString(bool globalAlloc, bool unicode)
+ {
+ lock (_methodLock)
+ {
+ EnsureNotDisposed();
+ return MarshalToStringCore(globalAlloc, unicode);
+ }
+ }
+
+ private static void MarshalFree(IntPtr ptr, bool globalAlloc)
+ {
+ if (globalAlloc)
+ {
+ Marshal.FreeHGlobal(ptr);
+ }
+ else
+ {
+ Marshal.FreeCoTaskMem(ptr);
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/Threading/ClrThreadPoolBoundHandle.cs b/src/mscorlib/corefx/System/Threading/ClrThreadPoolBoundHandle.cs
new file mode 100644
index 0000000000..d0cc5afbae
--- /dev/null
+++ b/src/mscorlib/corefx/System/Threading/ClrThreadPoolBoundHandle.cs
@@ -0,0 +1,319 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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.Threading
+{
+ //
+ // Implementation of ThreadPoolBoundHandle that sits on top of the CLR's ThreadPool and Overlapped infrastructure
+ //
+
+ /// <summary>
+ /// Represents an I/O handle that is bound to the system thread pool and enables low-level
+ /// components to receive notifications for asynchronous I/O operations.
+ /// </summary>
+ public sealed partial class ThreadPoolBoundHandle : IDisposable
+ {
+ private readonly SafeHandle _handle;
+ private bool _isDisposed;
+
+ private ThreadPoolBoundHandle(SafeHandle handle)
+ {
+ _handle = handle;
+ }
+
+ /// <summary>
+ /// Gets the bound operating system handle.
+ /// </summary>
+ /// <value>
+ /// A <see cref="SafeHandle"/> object that holds the bound operating system handle.
+ /// </value>
+ public SafeHandle Handle
+ {
+ get { return _handle; }
+ }
+
+ /// <summary>
+ /// Returns a <see cref="ThreadPoolBoundHandle"/> for the specific handle,
+ /// which is bound to the system thread pool.
+ /// </summary>
+ /// <param name="handle">
+ /// A <see cref="SafeHandle"/> object that holds the operating system handle. The
+ /// handle must have been opened for overlapped I/O on the unmanaged side.
+ /// </param>
+ /// <returns>
+ /// <see cref="ThreadPoolBoundHandle"/> for <paramref name="handle"/>, which
+ /// is bound to the system thread pool.
+ /// </returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="handle"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="handle"/> has been disposed.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="handle"/> does not refer to a valid I/O handle.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="handle"/> refers to a handle that has not been opened
+ /// for overlapped I/O.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <paramref name="handle"/> refers to a handle that has already been bound.
+ /// </exception>
+ /// <remarks>
+ /// This method should be called once per handle.
+ /// <para>
+ /// -or-
+ /// </para>
+ /// <see cref="ThreadPoolBoundHandle"/> does not take ownership of <paramref name="handle"/>,
+ /// it remains the responsibility of the caller to call <see cref="SafeHandle.Dispose"/>.
+ /// </remarks>
+ public static ThreadPoolBoundHandle BindHandle(SafeHandle handle)
+ {
+ if (handle == null)
+ throw new ArgumentNullException(nameof(handle));
+
+ if (handle.IsClosed || handle.IsInvalid)
+ throw new ArgumentException(SR.Argument_InvalidHandle, nameof(handle));
+
+ try
+ {
+ // ThreadPool.BindHandle will always return true, otherwise, it throws. See the underlying FCall
+ // implementation in ThreadPoolNative::CorBindIoCompletionCallback to see the implementation.
+ bool succeeded = ThreadPool.BindHandle(handle);
+ Debug.Assert(succeeded);
+ }
+ catch (Exception ex)
+ { // BindHandle throws ApplicationException on full CLR and Exception on CoreCLR.
+ // We do not let either of these leak and convert them to ArgumentException to
+ // indicate that the specified handles are invalid.
+
+ if (ex.HResult == System.HResults.E_HANDLE) // Bad handle
+ throw new ArgumentException(SR.Argument_InvalidHandle, nameof(handle));
+
+ if (ex.HResult == System.HResults.E_INVALIDARG) // Handle already bound or sync handle
+ throw new ArgumentException(SR.Argument_AlreadyBoundOrSyncHandle, nameof(handle));
+
+ throw;
+ }
+
+ return new ThreadPoolBoundHandle(handle);
+ }
+
+ /// <summary>
+ /// Returns an unmanaged pointer to a <see cref="NativeOverlapped"/> structure, specifying
+ /// a delegate that is invoked when the asynchronous I/O operation is complete, a user-provided
+ /// object providing context, and managed objects that serve as buffers.
+ /// </summary>
+ /// <param name="callback">
+ /// An <see cref="IOCompletionCallback"/> delegate that represents the callback method
+ /// invoked when the asynchronous I/O operation completes.
+ /// </param>
+ /// <param name="state">
+ /// A user-provided object that distinguishes this <see cref="NativeOverlapped"/> from other
+ /// <see cref="NativeOverlapped"/> instances. Can be <see langword="null"/>.
+ /// </param>
+ /// <param name="pinData">
+ /// An object or array of objects representing the input or output buffer for the operation. Each
+ /// object represents a buffer, for example an array of bytes. Can be <see langword="null"/>.
+ /// </param>
+ /// <returns>
+ /// An unmanaged pointer to a <see cref="NativeOverlapped"/> structure.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// The unmanaged pointer returned by this method can be passed to the operating system in
+ /// overlapped I/O operations. The <see cref="NativeOverlapped"/> structure is fixed in
+ /// physical memory until <see cref="FreeNativeOverlapped(NativeOverlapped*)"/> is called.
+ /// </para>
+ /// <para>
+ /// The buffer or buffers specified in <paramref name="pinData"/> must be the same as those passed
+ /// to the unmanaged operating system function that performs the asynchronous I/O.
+ /// </para>
+ /// <note>
+ /// The buffers specified in <paramref name="pinData"/> are pinned for the duration of
+ /// the I/O operation.
+ /// </note>
+ /// </remarks>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="callback"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// This method was called after the <see cref="ThreadPoolBoundHandle"/> was disposed.
+ /// </exception>
+ [CLSCompliant(false)]
+ public unsafe NativeOverlapped* AllocateNativeOverlapped(IOCompletionCallback callback, object state, object pinData)
+ {
+ if (callback == null)
+ throw new ArgumentNullException(nameof(callback));
+
+ EnsureNotDisposed();
+
+ ThreadPoolBoundHandleOverlapped overlapped = new ThreadPoolBoundHandleOverlapped(callback, state, pinData, preAllocated: null);
+ overlapped._boundHandle = this;
+ return overlapped._nativeOverlapped;
+ }
+
+ /// <summary>
+ /// Returns an unmanaged pointer to a <see cref="NativeOverlapped"/> structure, using the callback,
+ /// state, and buffers associated with the specified <see cref="PreAllocatedOverlapped"/> object.
+ /// </summary>
+ /// <param name="preAllocated">
+ /// A <see cref="PreAllocatedOverlapped"/> object from which to create the NativeOverlapped pointer.
+ /// </param>
+ /// <returns>
+ /// An unmanaged pointer to a <see cref="NativeOverlapped"/> structure.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// The unmanaged pointer returned by this method can be passed to the operating system in
+ /// overlapped I/O operations. The <see cref="NativeOverlapped"/> structure is fixed in
+ /// physical memory until <see cref="FreeNativeOverlapped(NativeOverlapped*)"/> is called.
+ /// </para>
+ /// </remarks>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="preAllocated"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ArgumentException">
+ /// <paramref name="preAllocated"/> is currently in use for another I/O operation.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// This method was called after the <see cref="ThreadPoolBoundHandle"/> was disposed, or
+ /// this method was called after <paramref name="preAllocated"/> was disposed.
+ /// </exception>
+ /// <seealso cref="PreAllocatedOverlapped"/>
+ [CLSCompliant(false)]
+ public unsafe NativeOverlapped* AllocateNativeOverlapped(PreAllocatedOverlapped preAllocated)
+ {
+ if (preAllocated == null)
+ throw new ArgumentNullException(nameof(preAllocated));
+
+ EnsureNotDisposed();
+
+ preAllocated.AddRef();
+ try
+ {
+ ThreadPoolBoundHandleOverlapped overlapped = preAllocated._overlapped;
+
+ if (overlapped._boundHandle != null)
+ throw new ArgumentException(SR.Argument_PreAllocatedAlreadyAllocated, nameof(preAllocated));
+
+ overlapped._boundHandle = this;
+
+ return overlapped._nativeOverlapped;
+ }
+ catch
+ {
+ preAllocated.Release();
+ throw;
+ }
+ }
+
+ /// <summary>
+ /// Frees the unmanaged memory associated with a <see cref="NativeOverlapped"/> structure
+ /// allocated by the <see cref="AllocateNativeOverlapped"/> method.
+ /// </summary>
+ /// <param name="overlapped">
+ /// An unmanaged pointer to the <see cref="NativeOverlapped"/> structure to be freed.
+ /// </param>
+ /// <remarks>
+ /// <note type="caution">
+ /// You must call the <see cref="FreeNativeOverlapped(NativeOverlapped*)"/> method exactly once
+ /// on every <see cref="NativeOverlapped"/> unmanaged pointer allocated using the
+ /// <see cref="AllocateNativeOverlapped"/> method.
+ /// If you do not call the <see cref="FreeNativeOverlapped(NativeOverlapped*)"/> method, you will
+ /// leak memory. If you call the <see cref="FreeNativeOverlapped(NativeOverlapped*)"/> method more
+ /// than once on the same <see cref="NativeOverlapped"/> unmanaged pointer, memory will be corrupted.
+ /// </note>
+ /// </remarks>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="overlapped"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// This method was called after the <see cref="ThreadPoolBoundHandle"/> was disposed.
+ /// </exception>
+ [CLSCompliant(false)]
+ public unsafe void FreeNativeOverlapped(NativeOverlapped* overlapped)
+ {
+ if (overlapped == null)
+ throw new ArgumentNullException(nameof(overlapped));
+
+ // Note: we explicitly allow FreeNativeOverlapped calls after the ThreadPoolBoundHandle has been Disposed.
+
+ ThreadPoolBoundHandleOverlapped wrapper = GetOverlappedWrapper(overlapped, this);
+
+ if (wrapper._boundHandle != this)
+ throw new ArgumentException(SR.Argument_NativeOverlappedWrongBoundHandle, nameof(overlapped));
+
+ if (wrapper._preAllocated != null)
+ wrapper._preAllocated.Release();
+ else
+ Overlapped.Free(overlapped);
+ }
+
+ /// <summary>
+ /// Returns the user-provided object specified when the <see cref="NativeOverlapped"/> instance was
+ /// allocated using the <see cref="AllocateNativeOverlapped(IOCompletionCallback, object, byte[])"/>.
+ /// </summary>
+ /// <param name="overlapped">
+ /// An unmanaged pointer to the <see cref="NativeOverlapped"/> structure from which to return the
+ /// asscociated user-provided object.
+ /// </param>
+ /// <returns>
+ /// A user-provided object that distinguishes this <see cref="NativeOverlapped"/>
+ /// from other <see cref="NativeOverlapped"/> instances, otherwise, <see langword="null"/> if one was
+ /// not specified when the instance was allocated using <see cref="AllocateNativeOverlapped"/>.
+ /// </returns>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="overlapped"/> is <see langword="null"/>.
+ /// </exception>
+ [CLSCompliant(false)]
+ public unsafe static object GetNativeOverlappedState(NativeOverlapped* overlapped)
+ {
+ if (overlapped == null)
+ throw new ArgumentNullException(nameof(overlapped));
+
+ ThreadPoolBoundHandleOverlapped wrapper = GetOverlappedWrapper(overlapped, null);
+ Debug.Assert(wrapper._boundHandle != null);
+ return wrapper._userState;
+ }
+
+ private static unsafe ThreadPoolBoundHandleOverlapped GetOverlappedWrapper(NativeOverlapped* overlapped, ThreadPoolBoundHandle expectedBoundHandle)
+ {
+ ThreadPoolBoundHandleOverlapped wrapper;
+ try
+ {
+ wrapper = (ThreadPoolBoundHandleOverlapped)Overlapped.Unpack(overlapped);
+ }
+ catch (NullReferenceException ex)
+ {
+ throw new ArgumentException(SR.Argument_NativeOverlappedAlreadyFree, nameof(overlapped), ex);
+ }
+
+ return wrapper;
+ }
+
+ public void Dispose()
+ {
+ // .NET Native's version of ThreadPoolBoundHandle that wraps the Win32 ThreadPool holds onto
+ // native resources so it needs to be disposable. To match the contract, we are also disposable.
+ // We also implement a disposable state to mimic behavior between this implementation and
+ // .NET Native's version (code written against us, will also work against .NET Native's version).
+ _isDisposed = true;
+ }
+
+
+ private void EnsureNotDisposed()
+ {
+ if (_isDisposed)
+ throw new ObjectDisposedException(GetType().ToString());
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/Threading/ClrThreadPoolBoundHandleOverlapped.cs b/src/mscorlib/corefx/System/Threading/ClrThreadPoolBoundHandleOverlapped.cs
new file mode 100644
index 0000000000..1aea2a294b
--- /dev/null
+++ b/src/mscorlib/corefx/System/Threading/ClrThreadPoolBoundHandleOverlapped.cs
@@ -0,0 +1,52 @@
+// Licensed to the .NET Foundation under one or more 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
+{
+ /// <summary>
+ /// Overlapped subclass adding data needed by ThreadPoolBoundHandle.
+ /// </summary>
+ internal sealed class ThreadPoolBoundHandleOverlapped : Overlapped
+ {
+ private static readonly unsafe IOCompletionCallback s_completionCallback = CompletionCallback;
+
+ private readonly IOCompletionCallback _userCallback;
+ internal readonly object _userState;
+ internal PreAllocatedOverlapped _preAllocated;
+ internal unsafe NativeOverlapped* _nativeOverlapped;
+ internal ThreadPoolBoundHandle _boundHandle;
+ internal bool _completed;
+
+ public unsafe ThreadPoolBoundHandleOverlapped(IOCompletionCallback callback, object state, object pinData, PreAllocatedOverlapped preAllocated)
+ {
+ _userCallback = callback;
+ _userState = state;
+ _preAllocated = preAllocated;
+
+ _nativeOverlapped = Pack(s_completionCallback, pinData);
+ _nativeOverlapped->OffsetLow = 0; // CLR reuses NativeOverlapped instances and does not reset these
+ _nativeOverlapped->OffsetHigh = 0;
+ }
+
+ private unsafe static void CompletionCallback(uint errorCode, uint numBytes, NativeOverlapped* nativeOverlapped)
+ {
+ ThreadPoolBoundHandleOverlapped overlapped = (ThreadPoolBoundHandleOverlapped)Overlapped.Unpack(nativeOverlapped);
+
+ //
+ // The Win32 thread pool implementation of ThreadPoolBoundHandle does not permit reuse of NativeOverlapped
+ // pointers without freeing them and allocating new a new one. We need to ensure that code using the CLR
+ // ThreadPool implementation follows those rules.
+ //
+ if (overlapped._completed)
+ throw new InvalidOperationException(SR.InvalidOperation_NativeOverlappedReused);
+
+ overlapped._completed = true;
+
+ if (overlapped._boundHandle == null)
+ throw new InvalidOperationException(SR.Argument_NativeOverlappedAlreadyFree);
+
+ overlapped._userCallback(errorCode, numBytes, nativeOverlapped);
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/Threading/ClrThreadPoolPreAllocatedOverlapped.cs b/src/mscorlib/corefx/System/Threading/ClrThreadPoolPreAllocatedOverlapped.cs
new file mode 100644
index 0000000000..a42e0c7983
--- /dev/null
+++ b/src/mscorlib/corefx/System/Threading/ClrThreadPoolPreAllocatedOverlapped.cs
@@ -0,0 +1,105 @@
+// Licensed to the .NET Foundation under one or more 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
+{
+ /// <summary>
+ /// Represents pre-allocated state for native overlapped I/O operations.
+ /// </summary>
+ /// <seealso cref="ThreadPoolBoundHandle.AllocateNativeOverlapped(PreAllocatedOverlapped)"/>
+ public sealed class PreAllocatedOverlapped : IDisposable, IDeferredDisposable
+ {
+ internal readonly ThreadPoolBoundHandleOverlapped _overlapped;
+ private DeferredDisposableLifetime<PreAllocatedOverlapped> _lifetime;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PreAllocatedOverlapped"/> class, specifying
+ /// a delegate that is invoked when each asynchronous I/O operation is complete, a user-provided
+ /// object providing context, and managed objects that serve as buffers.
+ /// </summary>
+ /// <param name="callback">
+ /// An <see cref="IOCompletionCallback"/> delegate that represents the callback method
+ /// invoked when each asynchronous I/O operation completes.
+ /// </param>
+ /// <param name="state">
+ /// A user-provided object that distinguishes <see cref="NativeOverlapped"/> instance produced from this
+ /// object from other <see cref="NativeOverlapped"/> instances. Can be <see langword="null"/>.
+ /// </param>
+ /// <param name="pinData">
+ /// An object or array of objects representing the input or output buffer for the operations. Each
+ /// object represents a buffer, for example an array of bytes. Can be <see langword="null"/>.
+ /// </param>
+ /// <remarks>
+ /// The new <see cref="PreAllocatedOverlapped"/> instance can be passed to
+ /// <see cref="ThreadPoolBoundHandle.AllocateNativeOverlapped(PreAllocatedOverlapped)"/>, to produce
+ /// a <see cref="NativeOverlapped"/> instance that can be passed to the operating system in overlapped
+ /// I/O operations. A single <see cref="PreAllocatedOverlapped"/> instance can only be used for
+ /// a single native I/O operation at a time. However, the state stored in the <see cref="PreAllocatedOverlapped"/>
+ /// instance can be reused for subsequent native operations.
+ /// <note>
+ /// The buffers specified in <paramref name="pinData"/> are pinned until <see cref="Dispose"/> is called.
+ /// </note>
+ /// </remarks>
+ /// <exception cref="ArgumentNullException">
+ /// <paramref name="callback"/> is <see langword="null"/>.
+ /// </exception>
+ /// <exception cref="ObjectDisposedException">
+ /// This method was called after the <see cref="ThreadPoolBoundHandle"/> was disposed.
+ /// </exception>
+ [CLSCompliant(false)]
+ public unsafe PreAllocatedOverlapped(IOCompletionCallback callback, object state, object pinData)
+ {
+ if (callback == null)
+ throw new ArgumentNullException(nameof(callback));
+
+ _overlapped = new ThreadPoolBoundHandleOverlapped(callback, state, pinData, this);
+ }
+
+ internal bool AddRef()
+ {
+ return _lifetime.AddRef(this);
+ }
+
+ internal void Release()
+ {
+ _lifetime.Release(this);
+ }
+
+ /// <summary>
+ /// Frees the resources associated with this <see cref="PreAllocatedOverlapped"/> instance.
+ /// </summary>
+ public unsafe void Dispose()
+ {
+ _lifetime.Dispose(this);
+ GC.SuppressFinalize(this);
+ }
+
+ ~PreAllocatedOverlapped()
+ {
+ //
+ // During shutdown, don't automatically clean up, because this instance may still be
+ // reachable/usable by other code.
+ //
+ if (!Environment.HasShutdownStarted)
+ Dispose();
+ }
+
+ unsafe void IDeferredDisposable.OnFinalRelease(bool disposed)
+ {
+ if (_overlapped != null)
+ {
+ if (disposed)
+ {
+ Overlapped.Free(_overlapped._nativeOverlapped);
+ }
+ else
+ {
+ _overlapped._boundHandle = null;
+ _overlapped._completed = false;
+ *_overlapped._nativeOverlapped = default(NativeOverlapped);
+ }
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/Threading/DeferredDisposableLifetime.cs b/src/mscorlib/corefx/System/Threading/DeferredDisposableLifetime.cs
new file mode 100644
index 0000000000..89380fee60
--- /dev/null
+++ b/src/mscorlib/corefx/System/Threading/DeferredDisposableLifetime.cs
@@ -0,0 +1,116 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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>
+ /// Provides callbacks to objects whose lifetime is managed by <see cref="DeferredDisposableLifetime{T}"/>.
+ /// </summary>
+ internal interface IDeferredDisposable
+ {
+ /// <summary>
+ /// Called when the object's refcount reaches zero.
+ /// </summary>
+ /// <param name="disposed">
+ /// Indicates whether the object has been disposed.
+ /// </param>
+ /// <remarks>
+ /// If the refount reaches zero before the object is disposed, this method will be called with
+ /// <paramref name="disposed"/> set to false. If the object is then disposed, this method will be
+ /// called again, with <paramref name="disposed"/> set to true. If the refcount reaches zero
+ /// after the object has already been disposed, this will be called a single time, with
+ /// <paramref name="disposed"/> set to true.
+ /// </remarks>
+ void OnFinalRelease(bool disposed);
+ }
+
+ /// <summary>
+ /// Manages the lifetime of an object which implements IDisposable, but which must defer the actual
+ /// cleanup of state until all existing uses of the object are complete.
+ /// </summary>
+ /// <typeparam name="T">The type of object whose lifetime will be managed.</typeparam>
+ /// <remarks>
+ /// This type maintains a reference count, and tracks whether the object has been disposed. When
+ /// Callbacks are made to <see cref="IDeferredDisposable.OnFinalRelease(bool)"/> when the refcount
+ /// reaches zero. Objects that need to defer cleanup until they have been disposed *and* they have
+ /// no more references can do so in <see cref="IDeferredDisposable.OnFinalRelease(bool)"/> when
+ /// 'disposed' is true.
+ /// </remarks>
+ internal struct DeferredDisposableLifetime<T> where T : class, IDeferredDisposable
+ {
+ //
+ // _count is positive until Dispose is called, after which it's (-1 - refcount).
+ //
+ private int _count;
+
+ public bool AddRef(T obj)
+ {
+ while (true)
+ {
+ int oldCount = Volatile.Read(ref _count);
+
+ // Have we been disposed?
+ if (oldCount < 0)
+ throw new ObjectDisposedException(typeof(T).ToString());
+
+ int newCount = checked(oldCount + 1);
+
+ if (Interlocked.CompareExchange(ref _count, newCount, oldCount) == oldCount)
+ return true;
+ }
+ }
+
+ public void Release(T obj)
+ {
+ while (true)
+ {
+ int oldCount = Volatile.Read(ref _count);
+ if (oldCount > 0)
+ {
+ // We haven't been disposed. Decrement _count.
+ int newCount = oldCount - 1;
+ if (Interlocked.CompareExchange(ref _count, newCount, oldCount) == oldCount)
+ {
+ if (newCount == 0)
+ obj.OnFinalRelease(disposed: false);
+ return;
+ }
+ }
+ else
+ {
+ Debug.Assert(oldCount != 0 && oldCount != -1);
+
+ // We've been disposed. Increment _count.
+ int newCount = oldCount + 1;
+ if (Interlocked.CompareExchange(ref _count, newCount, oldCount) == oldCount)
+ {
+ if (newCount == -1)
+ obj.OnFinalRelease(disposed: true);
+ return;
+ }
+ }
+ }
+ }
+
+ public void Dispose(T obj)
+ {
+ while (true)
+ {
+ int oldCount = Volatile.Read(ref _count);
+ if (oldCount < 0)
+ return; // already disposed
+
+ int newCount = -1 - oldCount;
+ if (Interlocked.CompareExchange(ref _count, newCount, oldCount) == oldCount)
+ {
+ if (newCount == -1)
+ obj.OnFinalRelease(disposed: true);
+ return;
+ }
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/facade/TypeForwards.cs b/src/mscorlib/facade/TypeForwards.cs
deleted file mode 100644
index ba78711eef..0000000000
--- a/src/mscorlib/facade/TypeForwards.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.
-
-using System.Runtime.CompilerServices;
-
-#if WINDOWS_TYPEFORWARDS
-[assembly: TypeForwardedTo(typeof(System.Threading.WinRTSynchronizationContextFactoryBase))]
-[assembly: TypeForwardedTo(typeof(System.Resources.WindowsRuntimeResourceManagerBase))]
-[assembly: TypeForwardedTo(typeof(System.Resources.PRIExceptionInfo))]
-[assembly: TypeForwardedTo(typeof(System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeImportAttribute))]
-[assembly: TypeForwardedTo(typeof(System.Runtime.InteropServices.WindowsRuntime.IRestrictedErrorInfo))]
-[assembly: TypeForwardedTo(typeof(System.StubHelpers.EventArgsMarshaler))]
-[assembly: TypeForwardedTo(typeof(System.StubHelpers.InterfaceMarshaler))]
-#endif
-
-[assembly: TypeForwardedTo(typeof(System.Diagnostics.Tracing.FrameworkEventSource))]
-[assembly: TypeForwardedTo(typeof(System.Globalization.CultureData))]
-[assembly: TypeForwardedTo(typeof(System.Globalization.CalendarData))]
-[assembly: TypeForwardedTo(typeof(System.IO.BufferedStream))]
-[assembly: TypeForwardedTo(typeof(System.Runtime.CompilerServices.JitHelpers))]
-[assembly: TypeForwardedTo(typeof(System.Runtime.CompilerServices.ObjectHandleOnStack))]
-[assembly: TypeForwardedTo(typeof(System.Runtime.CompilerServices.PinningHelper))]
-[assembly: TypeForwardedTo(typeof(System.Runtime.CompilerServices.StackCrawlMarkHandle))]
-[assembly: TypeForwardedTo(typeof(System.Runtime.CompilerServices.StringHandleOnStack))]
-[assembly: TypeForwardedTo(typeof(System.Runtime.CompilerServices.FriendAccessAllowedAttribute))]
-[assembly: TypeForwardedTo(typeof(System.StubHelpers.StubHelpers))]
-[assembly: TypeForwardedTo(typeof(System.StubHelpers.CleanupWorkList))]
-[assembly: TypeForwardedTo(typeof(System.StubHelpers.CleanupWorkListElement))]
-[assembly: TypeForwardedTo(typeof(System.Threading.StackCrawlMark))]
-[assembly: TypeForwardedTo(typeof(System.Threading.Tasks.AsyncCausalityStatus))]
-[assembly: TypeForwardedTo(typeof(System.Threading.Tasks.CausalityRelation))]
-[assembly: TypeForwardedTo(typeof(System.Threading.Tasks.CausalitySynchronousWork))]
-[assembly: TypeForwardedTo(typeof(System.Threading.Tasks.AsyncCausalityTracer))]
-[assembly: TypeForwardedTo(typeof(System.Threading.Tasks.CausalityTraceLevel))]
-
-
diff --git a/src/mscorlib/facade/mscorlib.csproj b/src/mscorlib/facade/mscorlib.csproj
index c3a165d3d5..7d0133af39 100644
--- a/src/mscorlib/facade/mscorlib.csproj
+++ b/src/mscorlib/facade/mscorlib.csproj
@@ -48,20 +48,13 @@
<DebugType>none</DebugType>
</PropertyGroup>
- <!-- Some of the type forwards should only be build when targeting Windows. -->
- <PropertyGroup>
- <DefineConstants Condition="'$(TargetsWindows)'=='true'">$(DefineConstants);WINDOWS_TYPEFORWARDS</DefineConstants>
- </PropertyGroup>
-
<!-- Output paths -->
<PropertyGroup>
<BaseIntermediateOutputPath>$(RootBinDir)\obj</BaseIntermediateOutputPath>
- <!-- Note the trailing '\\' - they are needed so that genfacade does not fail due to an invalid path
- In particular, the facadepath is sent in quotes.
- And the IntermediateOutputPath is required to end in a '\' in the coreclr repo. This means that the
- facadepath ends up being sent as 'mypath\"' and that trips the Path normalization.
- Introducing a second '\' tricks the normalization logic to treat this '\\"' as '\"' and not complain. -->
- <IntermediateOutputPath>$(BaseIntermediateOutputPath)\$(BuildOS).$(BuildArch).$(Configuration)\facade\\</IntermediateOutputPath>
+ <!-- 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>
@@ -70,10 +63,6 @@
</ItemGroup>
<ItemGroup>
- <Compile Include="TypeForwards.cs" />
- </ItemGroup>
-
- <ItemGroup>
<None Include="project.json" />
</ItemGroup>
@@ -97,6 +86,24 @@
<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
index 485086eca5..37f8c1ba57 100644
--- a/src/mscorlib/facade/project.json
+++ b/src/mscorlib/facade/project.json
@@ -1,6 +1,7 @@
{
"dependencies": {
"System.Console": "4.0.0",
+ "System.IO": "4.1.0",
"System.Security.Cryptography.Primitives": "4.0.0",
"System.Security.Claims": "4.0.0",
},
diff --git a/src/mscorlib/model.xml b/src/mscorlib/model.xml
index 67db0a0522..c0e9746306 100644
--- a/src/mscorlib/model.xml
+++ b/src/mscorlib/model.xml
@@ -143,14 +143,23 @@
<Member Name="#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
</Type>
<Type Name="System.AppContext">
+ <Member MemberType="Event" Name="FirstChanceException" />
+ <Member MemberType="Event" Name="ProcessExit" />
+ <Member MemberType="Event" Name="UnhandledException" />
+ <Member Name="add_FirstChanceException(System.EventHandler&lt;System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs&gt;)" />
+ <Member Name="add_ProcessExit(System.EventHandler)" />
+ <Member Name="add_UnhandledException(System.UnhandledExceptionEventHandler)" />
<Member Name="get_BaseDirectory" />
- <Member MemberType="Property" Name="BaseDirectory" />
<Member Name="get_TargetFrameworkName" />
- <Member MemberType="Property" Name="TargetFrameworkName" />
- <Member Name="DefineSwitchDefault(System.String,System.Boolean)" />
+ <Member Name="GetData(System.String)" />
+ <Member Name="remove_FirstChanceException(System.EventHandler&lt;System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs&gt;)" />
+ <Member Name="remove_ProcessExit(System.EventHandler)" />
+ <Member Name="remove_UnhandledException(System.UnhandledExceptionEventHandler)" />
+ <Member Name="SetData(System.String,System.Object)" />
<Member Name="SetSwitch(System.String,System.Boolean)" />
<Member Name="TryGetSwitch(System.String,System.Boolean@)" />
- <Member Name="GetData(System.String)" />
+ <Member MemberType="Property" Name="BaseDirectory" />
+ <Member MemberType="Property" Name="TargetFrameworkName" />
</Type>
<Type Name="System.ApplicationException">
<Member Name="#ctor" />
@@ -239,6 +248,8 @@
<Member Name="CreateInstance(System.Type,System.Int64[])" />
<Member Name="Empty&lt;T&gt;" />
<Member Name="Exists&lt;T&gt;(T[],System.Predicate&lt;T&gt;)" />
+ <Member Name="Fill&lt;T&gt;(T[],T)" />
+ <Member Name="Fill&lt;T&gt;(T[],T,System.Int32,System.Int32)" />
<Member Name="Find&lt;T&gt;(T[],System.Predicate&lt;T&gt;)" />
<Member Name="FindAll&lt;T&gt;(T[],System.Predicate&lt;T&gt;)" />
<Member Name="FindIndex&lt;T&gt;(T[],System.Int32,System.Int32,System.Predicate&lt;T&gt;)" />
@@ -285,6 +296,8 @@
<Member Name="Resize&lt;T&gt;(T[]@,System.Int32)" />
<Member Name="Reverse(System.Array)" />
<Member Name="Reverse(System.Array,System.Int32,System.Int32)" />
+ <Member Name="Reverse&lt;T&gt;(T[])" />
+ <Member Name="Reverse&lt;T&gt;(T[],System.Int32,System.Int32)" />
<Member Name="SetValue(System.Object,System.Int32)" />
<Member Name="SetValue(System.Object,System.Int32,System.Int32)" />
<Member Name="SetValue(System.Object,System.Int32,System.Int32,System.Int32)" />
@@ -328,6 +341,7 @@
<Member Name="get_Array" />
<Member Name="get_Count" />
<Member Name="get_Offset" />
+ <Member Name="GetEnumerator" />
<Member Name="GetHashCode" />
<Member Name="op_Equality(System.ArraySegment&lt;T&gt;,System.ArraySegment&lt;T&gt;)" />
<Member Name="op_Inequality(System.ArraySegment&lt;T&gt;,System.ArraySegment&lt;T&gt;)" />
@@ -335,6 +349,13 @@
<Member MemberType="Property" Name="Count" />
<Member MemberType="Property" Name="Offset" />
</Type>
+ <Type Name="System.ArraySegment&lt;T&gt;+Enumerator">
+ <Member Name="Dispose" />
+ <Member Name="get_Current" />
+ <Member Name="MoveNext" />
+ <Member MemberType="Property" Name="Current" />
+ <Member Name="System.Collections.IEnumerator.Reset" />
+ </Type>
<Type Name="System.ArrayTypeMismatchException">
<Member Name="#ctor" />
<Member Name="#ctor(System.String)" />
@@ -436,6 +457,7 @@
</Type>
<Type Name="System.BitConverter">
<Member Name="DoubleToInt64Bits(System.Double)" />
+ <Member Name="Int32BitsToSingle(System.Int32)" />
<Member Name="Int64BitsToDouble(System.Int64)" />
<Member MemberType="Field" Name="IsLittleEndian" />
<Member Name="GetBytes(System.Boolean)" />
@@ -448,6 +470,7 @@
<Member Name="GetBytes(System.UInt32)" />
<Member Name="GetBytes(System.UInt64)" />
<Member Name="GetBytes(System.UInt16)" />
+ <Member Name="SingleToInt32Bits(System.Single)" />
<Member Name="ToBoolean(System.Byte[],System.Int32)" />
<Member Name="ToChar(System.Byte[],System.Int32)" />
<Member Name="ToDouble(System.Byte[],System.Int32)" />
@@ -472,6 +495,7 @@
<Member Name="#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
<Member Name="get_FileName" />
<Member Name="get_FusionLog" />
+ <Member Name="GetObjectData(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
<Member MemberType="Property" Name="FileName" />
<Member MemberType="Property" Name="FusionLog" />
</Type>
@@ -497,6 +521,15 @@
<Member Name="MemoryCopy(System.Void*,System.Void*,System.Int64,System.Int64)" />
<Member Name="MemoryCopy(System.Void*,System.Void*,System.UInt64,System.UInt64)" />
</Type>
+ <Type Name="System.Buffers.ArrayPool&lt;T&gt;">
+ <Member Name="#ctor" />
+ <Member Name="Create" />
+ <Member Name="Create(System.Int32,System.Int32)" />
+ <Member Name="get_Shared" />
+ <Member MemberType="Property" Name="Shared" />
+ <Member Name="Rent(System.Int32)" />
+ <Member Name="Return(T[],System.Boolean)" />
+ </Type>
<Type Name="System.Byte">
<Member MemberType="Field" Name="MaxValue" />
<Member MemberType="Field" Name="MinValue" />
@@ -596,38 +629,6 @@
<Member Name="get_IsCompliant" />
<Member MemberType="Property" Name="IsCompliant" />
</Type>
- <Type Name="System.Collections.BitArray">
- <Member Name="#ctor(System.Int32)" />
- <Member Name="#ctor(System.Int32,System.Boolean)" />
- <Member Name="#ctor(System.Byte[])" />
- <Member Name="#ctor(System.Boolean[])" />
- <Member Name="#ctor(System.Int32[])" />
- <Member Name="#ctor(System.Collections.BitArray)" />
- <Member Name="Get(System.Int32)" />
- <Member Name="Set(System.Int32,System.Boolean)" />
- <Member Name="SetAll(System.Boolean)" />
- <Member Name="And(System.Collections.BitArray)" />
- <Member Name="Or(System.Collections.BitArray)" />
- <Member Name="Xor(System.Collections.BitArray)" />
- <Member Name="Not" />
- <Member Name="set_Item(System.Int32,System.Boolean)" />
- <Member Name="get_Item(System.Int32)" />
- <Member MemberType="Property" Name="Item(System.Int32)" />
- <Member Name="get_Length" />
- <Member Name="set_Length(System.Int32)" />
- <Member MemberType="Property" Name="Length" />
- <Member Name="CopyTo(System.Array,System.Int32)" />
- <Member Name="get_Count" />
- <Member MemberType="Property" Name="Count" />
- <Member Name="get_IsReadOnly" />
- <Member MemberType="Property" Name="IsReadOnly" />
- <Member Name="get_IsSynchronized" />
- <Member MemberType="Property" Name="IsSynchronized" />
- <Member Name="get_SyncRoot" />
- <Member MemberType="Property" Name="SyncRoot" />
- <Member Name="Clone" />
- <Member Name="GetEnumerator" />
- </Type>
<Type Name="System.Collections.CollectionBase">
<Member Name="#ctor" />
<Member Name="get_List" />
@@ -639,6 +640,7 @@
<Member Name="get_Value" />
<Member Name="set_Key(System.Object)" />
<Member Name="set_Value(System.Object)" />
+ <Member Name="Deconstruct(System.Object@,System.Object@)" />
<Member MemberType="Property" Name="Key" />
<Member MemberType="Property" Name="Value" />
</Type>
@@ -653,6 +655,8 @@
<Member Name="#ctor" />
<Member Name="#ctor(System.Collections.Generic.IDictionary&lt;TKey,TValue&gt;)" />
<Member Name="#ctor(System.Collections.Generic.IDictionary&lt;TKey,TValue&gt;,System.Collections.Generic.IEqualityComparer&lt;TKey&gt;)" />
+ <Member Name="#ctor(System.Collections.Generic.IEnumerable&lt;System.Collections.Generic.KeyValuePair&lt;TKey,TValue&gt;&gt;)" />
+ <Member Name="#ctor(System.Collections.Generic.IEnumerable&lt;System.Collections.Generic.KeyValuePair&lt;TKey,TValue&gt;&gt;,System.Collections.Generic.IEqualityComparer&lt;TKey&gt;)" />
<Member Name="#ctor(System.Collections.Generic.IEqualityComparer&lt;TKey&gt;)" />
<Member Name="#ctor(System.Int32)" />
<Member Name="#ctor(System.Int32,System.Collections.Generic.IEqualityComparer&lt;TKey&gt;)" />
@@ -667,6 +671,8 @@
<Member Name="get_Keys" />
<Member Name="get_Values" />
<Member Name="GetEnumerator" />
+ <Member Name="GetValueOrDefault(TKey)" />
+ <Member Name="GetValueOrDefault(TKey,TValue)" />
<Member Name="Remove(TKey)" />
<Member Name="set_Item(TKey,TValue)" />
<Member Name="TryGetValue(TKey,TValue@)" />
@@ -784,11 +790,15 @@
<Member Name="#ctor(System.String,System.Exception)" />
<Member Name="#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
</Type>
+ <Type Name="System.Collections.Generic.KeyValuePair">
+ <Member Name="Create&lt;TKey,TValue&gt;(TKey,TValue)" />
+ </Type>
<Type Name="System.Collections.Generic.KeyValuePair&lt;TKey,TValue&gt;">
<Member Name="#ctor(TKey,TValue)" />
<Member Name="get_Key" />
<Member Name="get_Value" />
<Member Name="ToString" />
+ <Member Name="Deconstruct(TKey@,TValue@)" />
<Member MemberType="Property" Name="Key" />
<Member MemberType="Property" Name="Value" />
</Type>
@@ -1055,27 +1065,25 @@
<Member Name="ResolveUnmanagedDll(System.String,System.IntPtr)" />
<Member Name="LoadUnmanagedDll(System.String)" />
<Member Name="LoadUnmanagedDllFromPath(System.String)" />
+ <Member Name="GetLoadedAssemblies" />
<Member Name="get_Default" />
<Member Name="SetProfileOptimizationRoot(System.String)" />
<Member Name="StartProfileOptimization(System.String)" />
+ <Member MemberType="Event" Name="AssemblyLoad" />
+ <Member MemberType="Event" Name="AssemblyResolve" />
<Member MemberType="Event" Name="Resolving" />
+ <Member MemberType="Event" Name="ResourceResolve" />
+ <Member MemberType="Event" Name="TypeResolve" />
<Member MemberType="Event" Name="Unloading" />
</Type>
+ <Type Name="System.Runtime.MemoryFailPoint">
+ <Member Name="#ctor(System.Int32)" />
+ <Member Name="Dispose" />
+ <Member Status="ImplRoot" Name="Finalize" />
+ </Type>
<Type Name="System.Reflection.Metadata.AssemblyExtensions">
<Member Name="TryGetRawMetadata(System.Reflection.Assembly,System.Byte*@,System.Int32@)"/>
</Type>
- <Type Name="System.ContextBoundObject">
- <Member Name="#ctor" />
- </Type>
- <Type Name="System.ContextMarshalException">
- <Member Name="#ctor" />
- <Member Name="#ctor(System.String)" />
- <Member Name="#ctor(System.String,System.Exception)" />
- <Member Name="#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
- </Type>
- <Type Name="System.ContextStaticAttribute">
- <Member Name="#ctor" />
- </Type>
<Type Name="System.Convert">
<Member MemberType="Field" Name="DBNull" />
<Member Name="ChangeType(System.Object,System.Type)" />
@@ -1830,6 +1838,7 @@
<Member MemberType="Field" Name="value__" />
</Type>
<Type Name="System.Diagnostics.Debugger">
+ <Member MemberType="Field" Name="DefaultCategory" />
<Member Name="#ctor" />
<Member Name="Break" />
<Member Name="get_IsAttached" />
@@ -1957,6 +1966,8 @@
<Member Name="IsDefined(System.Type,System.Object)" />
<Member Name="Parse(System.Type,System.String)" />
<Member Name="Parse(System.Type,System.String,System.Boolean)" />
+ <Member Name="Parse&lt;TEnum&gt;(System.String)" />
+ <Member Name="Parse&lt;TEnum&gt;(System.String,System.Boolean)" />
<Member Name="ToObject(System.Type,System.Byte)" />
<Member Name="ToObject(System.Type,System.Int16)" />
<Member Name="ToObject(System.Type,System.Int32)" />
@@ -1970,6 +1981,8 @@
<Member Name="ToString(System.IFormatProvider)" />
<Member Name="ToString(System.String)" />
<Member Name="ToString(System.String,System.IFormatProvider)" />
+ <Member Name="TryParse(System.Type,System.String,System.Object@)" />
+ <Member Name="TryParse(System.Type,System.String,System.Boolean,System.Object@)" />
<Member Name="TryParse&lt;TEnum&gt;(System.String,TEnum@)" />
<Member Name="TryParse&lt;TEnum&gt;(System.String,System.Boolean,TEnum@)" />
</Type>
@@ -2014,6 +2027,12 @@
<Member Name="Exit(System.Int32)" />
<Member Name="FailFast(System.String,System.Exception)" />
<Member Name="GetCommandLineArgs" />
+ <Member Name="GetEnvironmentVariable(System.String)" />
+ <Member Name="GetEnvironmentVariable(System.String,System.EnvironmentVariableTarget)" />
+ <Member Name="GetEnvironmentVariables" />
+ <Member Name="GetEnvironmentVariables(System.EnvironmentVariableTarget)" />
+ <Member Name="SetEnvironmentVariable(System.String,System.String)" />
+ <Member Name="SetEnvironmentVariable(System.String,System.String,System.EnvironmentVariableTarget)" />
</Type>
<Type Name="System.EventArgs">
<Member MemberType="Field" Name="Empty" />
@@ -2050,6 +2069,8 @@
<Member Name="set_HResult(System.Int32)" />
<Member Name="set_Source(System.String)" />
<Member Name="ToString" />
+ <Member Name="add_SerializeObjectState(System.EventHandler&lt;System.Runtime.Serialization.SafeSerializationEventArgs&gt;)" />
+ <Member Name="remove_SerializeObjectState(System.EventHandler&lt;System.Runtime.Serialization.SafeSerializationEventArgs&gt;)" />
<Member MemberType="Property" Name="Data" />
<Member MemberType="Property" Name="HelpLink" />
<Member MemberType="Property" Name="HResult" />
@@ -2058,6 +2079,7 @@
<Member MemberType="Property" Name="Source" />
<Member MemberType="Property" Name="StackTrace" />
<Member MemberType="Property" Name="TargetSite" />
+ <Member MemberType="Event" Name="SerializeObjectState" />
<Member Status="ImplRoot" Name="InternalToString" />
<Member Status="ImplRoot" Name="InternalPreserveStackTrace" />
<Member Status="ImplRoot" Name="OnDeserialized(System.Runtime.Serialization.StreamingContext)" />
@@ -2166,6 +2188,7 @@
<Member Name="Collect(System.Int32,System.GCCollectionMode,System.Boolean)" />
<Member Name="Collect(System.Int32,System.GCCollectionMode,System.Boolean,System.Boolean)" />
<Member Name="CollectionCount(System.Int32)" />
+ <Member Name="EndNoGCRegion" />
<Member Name="GetAllocatedBytesForCurrentThread" />
<Member Name="GetGeneration(System.Object)" />
<Member Name="GetGeneration(System.WeakReference)" />
@@ -2176,6 +2199,10 @@
<Member Name="RemoveMemoryPressure(System.Int64)" />
<Member Name="ReRegisterForFinalize(System.Object)" />
<Member Name="SuppressFinalize(System.Object)" />
+ <Member Name="TryStartNoGCRegion(System.Int64)" />
+ <Member Name="TryStartNoGCRegion(System.Int64,System.Boolean)" />
+ <Member Name="TryStartNoGCRegion(System.Int64,System.Int64)" />
+ <Member Name="TryStartNoGCRegion(System.Int64,System.Int64,System.Boolean)" />
<Member Name="WaitForFullGCApproach" />
<Member Name="WaitForFullGCApproach(System.Int32)" />
<Member Name="WaitForFullGCComplete" />
@@ -2295,6 +2322,7 @@
<Member Name="Equals(System.Object)" />
<Member Name="get_LCID" />
<Member Name="get_Name" />
+ <Member Name="get_Version" />
<Member Name="GetCompareInfo(System.Int32)" />
<Member Name="GetCompareInfo(System.Int32,System.Reflection.Assembly)" />
<Member Name="GetCompareInfo(System.String)" />
@@ -2340,6 +2368,7 @@
<Member Name="ToString" />
<Member MemberType="Property" Name="LCID" />
<Member MemberType="Property" Name="Name" />
+ <Member MemberType="Property" Name="Version" />
</Type>
<Type Name="System.Globalization.CompareOptions">
<Member MemberType="Field" Name="IgnoreCase" />
@@ -2366,15 +2395,18 @@
<Member Name="get_CompareInfo" />
<Member Name="get_CurrentCulture" />
<Member Name="get_CurrentUICulture" />
+ <Member Name="get_CultureTypes" />
<Member Name="get_DefaultThreadCurrentCulture" />
<Member Name="get_DefaultThreadCurrentUICulture" />
<Member Name="get_DateTimeFormat" />
<Member Name="get_DisplayName" />
<Member Name="get_EnglishName" />
+ <Member Name="get_IetfLanguageTag" />
<Member Name="get_InstalledUICulture" />
<Member Name="get_InvariantCulture" />
<Member Name="get_IsNeutralCulture" />
<Member Name="get_IsReadOnly" />
+ <Member Name="get_KeyboardLayoutId" />
<Member Name="get_LCID" />
<Member Name="get_Name" />
<Member Name="get_NativeName" />
@@ -2386,6 +2418,7 @@
<Member Name="get_ThreeLetterWindowsLanguageName" />
<Member Name="get_TwoLetterISOLanguageName" />
<Member Name="get_UseUserOverride" />
+ <Member Name="GetConsoleFallbackUICulture" />
<Member Name="GetCultureInfo(System.Int32)" />
<Member Name="GetCultureInfo(System.String)" />
<Member Name="GetCultureInfo(System.String,System.String)" />
@@ -2408,15 +2441,18 @@
<Member MemberType="Property" Name="CompareInfo" />
<Member MemberType="Property" Name="CurrentCulture" />
<Member MemberType="Property" Name="CurrentUICulture" />
+ <Member MemberType="Property" Name="CultureTypes" />
<Member MemberType="Property" Name="DateTimeFormat" />
<Member MemberType="Property" Name="DefaultThreadCurrentCulture" />
<Member MemberType="Property" Name="DefaultThreadCurrentUICulture"/>
<Member MemberType="Property" Name="DisplayName" />
<Member MemberType="Property" Name="EnglishName" />
+ <Member MemberType="Property" Name="IetfLanguageTag" />
<Member MemberType="Property" Name="InstalledUICulture" />
<Member MemberType="Property" Name="InvariantCulture" />
<Member MemberType="Property" Name="IsNeutralCulture" />
<Member MemberType="Property" Name="IsReadOnly" />
+ <Member MemberType="Property" Name="KeyboardLayoutId" />
<Member MemberType="Property" Name="LCID" />
<Member MemberType="Property" Name="Name" />
<Member MemberType="Property" Name="NativeName" />
@@ -2591,7 +2627,7 @@
<Member Name="#ctor" />
<Member Name="AddMonths(System.DateTime,System.Int32)" />
<Member Name="AddYears(System.DateTime,System.Int32)" />
- <Member Name="get_AlgorithmType" Condition="not FEATURE_COREFX_GLOBALIZATION" />
+ <Member Name="get_AlgorithmType" />
<Member Name="get_Eras" />
<Member Name="get_MaxSupportedDateTime" />
<Member Name="get_MinSupportedDateTime" />
@@ -2627,7 +2663,7 @@
<Type Name="System.Globalization.EastAsianLunisolarCalendar">
<Member Name="AddMonths(System.DateTime,System.Int32)" />
<Member Name="AddYears(System.DateTime,System.Int32)" />
- <Member Name="get_AlgorithmType" Condition="not FEATURE_COREFX_GLOBALIZATION" />
+ <Member Name="get_AlgorithmType" />
<Member Name="get_TwoDigitYearMax" />
<Member Name="GetCelestialStem(System.Int32)" />
<Member Name="GetDayOfMonth(System.DateTime)" />
@@ -2740,7 +2776,7 @@
<Member Name="#ctor" />
<Member Name="AddMonths(System.DateTime,System.Int32)" />
<Member Name="AddYears(System.DateTime,System.Int32)" />
- <Member Name="get_AlgorithmType" Condition="not FEATURE_COREFX_GLOBALIZATION" />
+ <Member Name="get_AlgorithmType" />
<Member Name="get_Eras" />
<Member Name="get_MaxSupportedDateTime" />
<Member Name="get_MinSupportedDateTime" />
@@ -3480,11 +3516,6 @@
<Member Name="#ctor(System.String,System.Exception)" />
<Member Name="#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
</Type>
- <Type Status="ApiFxInternal" Name="System.IO.BufferedStream">
- <Member Name="#ctor(System.IO.Stream,System.Int32)" />
- <Member Name="get_UnderlyingStream" />
- <Member Name="get_BufferSize" />
- </Type>
<Type Name="System.IO.FileLoadException">
<Member Name="#ctor" />
<Member Name="#ctor(System.String)" />
@@ -3494,6 +3525,8 @@
<Member Name="#ctor(System.String,System.String,System.Int32)" /> <!-- Used by EE, do not remove -->
<Member Name="#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
<Member Name="get_FileName" />
+ <Member Name="get_FusionLog" />
+ <Member MemberType="Property" Name="FusionLog" />
</Type>
<Type Name="System.IObservable&lt;T&gt;">
<Member Name="Subscribe(System.IObserver&lt;T&gt;)"/>
@@ -3543,6 +3576,9 @@
</Type>
<Type Name="System.MarshalByRefObject">
<Member Name="#ctor" />
+ <Member Name="GetLifetimeService" />
+ <Member Name="InitializeLifetimeService" />
+ <Member Name="MemberwiseClone(System.Boolean)" />
</Type>
<Type Status="ImplRoot" Name="System.System_LazyDebugView&lt;T&gt;">
<Member Status="ImplRoot" Name="#ctor(System.Lazy&lt;T&gt;)"/>
@@ -3572,6 +3608,17 @@
<Member Name="BigMul(System.Int32,System.Int32)" />
<Member Name="Ceiling(System.Decimal)" />
<Member Name="Ceiling(System.Double)"/>
+ <Member Name="Clamp(System.Byte,System.Byte,System.Byte)" />
+ <Member Name="Clamp(System.Decimal,System.Decimal,System.Decimal)" />
+ <Member Name="Clamp(System.Double,System.Double,System.Double)" />
+ <Member Name="Clamp(System.Int16,System.Int16,System.Int16)" />
+ <Member Name="Clamp(System.Int32,System.Int32,System.Int32)" />
+ <Member Name="Clamp(System.Int64,System.Int64,System.Int64)" />
+ <Member Name="Clamp(System.SByte,System.SByte,System.SByte)" />
+ <Member Name="Clamp(System.Single,System.Single,System.Single)" />
+ <Member Name="Clamp(System.UInt16,System.UInt16,System.UInt16)" />
+ <Member Name="Clamp(System.UInt32,System.UInt32,System.UInt32)" />
+ <Member Name="Clamp(System.UInt64,System.UInt64,System.UInt64)" />
<Member Name="Cos(System.Double)" />
<Member Name="Cosh(System.Double)" />
<Member Name="DivRem(System.Int32,System.Int32,System.Int32@)" />
@@ -3629,6 +3676,38 @@
<Member Name="Truncate(System.Decimal)" />
<Member Name="Truncate(System.Double)" />
</Type>
+ <Type Name="System.MathF">
+ <Member MemberType="Field" Name="E" />
+ <Member MemberType="Field" Name="PI" />
+ <Member Name="Abs(System.Single)" />
+ <Member Name="Acos(System.Single)" />
+ <Member Name="Asin(System.Single)" />
+ <Member Name="Atan(System.Single)" />
+ <Member Name="Atan2(System.Single,System.Single)" />
+ <Member Name="Ceiling(System.Single)"/>
+ <Member Name="Cos(System.Single)" />
+ <Member Name="Cosh(System.Single)" />
+ <Member Name="Exp(System.Single)" />
+ <Member Name="Floor(System.Single)" />
+ <Member Name="IEEERemainder(System.Single,System.Single)" />
+ <Member Name="Log(System.Single)" />
+ <Member Name="Log(System.Single,System.Single)" />
+ <Member Name="Log10(System.Single)" />
+ <Member Name="Max(System.Single,System.Single)" />
+ <Member Name="Min(System.Single,System.Single)" />
+ <Member Name="Pow(System.Single,System.Single)" />
+ <Member Name="Round(System.Single)" />
+ <Member Name="Round(System.Single,System.Int32)" />
+ <Member Name="Round(System.Single,System.Int32,System.MidpointRounding)" />
+ <Member Name="Round(System.Single,System.MidpointRounding)" />
+ <Member Name="Sign(System.Single)" />
+ <Member Name="Sin(System.Single)" />
+ <Member Name="Sinh(System.Single)" />
+ <Member Name="Sqrt(System.Single)" />
+ <Member Name="Tan(System.Single)" />
+ <Member Name="Tanh(System.Single)" />
+ <Member Name="Truncate(System.Single)" />
+ </Type>
<Type Name="System.MemberAccessException">
<Member Name="#ctor" />
<Member Name="#ctor(System.String)" />
@@ -3895,14 +3974,19 @@
<Member Name="GetReferencedAssemblies" />
<Member Name="get_EntryPoint" />
<Member Name="get_FullName" />
+ <Member Name="get_GlobalAssemblyCache" />
+ <Member Name="get_HostContext" />
<Member Name="get_ImageRuntimeVersion" />
+ <Member Name="get_IsFullyTrusted" />
<Member Name="get_IsDynamic" />
<Member Name="get_CodeBase" />
+ <Member Name="get_EscapedCodeBase" />
<Member Name="get_Location" />
<Member Name="get_ManifestModule" />
<Member Name="get_CustomAttributes" />
<Member Name="get_Modules" />
<Member Name="get_ReflectionOnly" />
+ <Member Name="get_SecurityRuleSet" />
<Member Name="GetAssembly(System.Type)" />
<Member Name="op_Equality(System.Reflection.Assembly,System.Reflection.Assembly)" />
<Member Name="op_Inequality(System.Reflection.Assembly,System.Reflection.Assembly)" />
@@ -3913,6 +3997,9 @@
<Member Name="GetExecutingAssembly" />
<Member Name="GetEntryAssembly" />
<Member Name="GetExportedTypes" />
+ <Member Name="GetFile(System.String)" />
+ <Member Name="GetFiles" />
+ <Member Name="GetFiles(System.Boolean)" />
<Member Name="GetLoadedModules" />
<Member Name="GetLoadedModules(System.Boolean)" />
<Member Name="GetManifestResourceNames" />
@@ -3938,21 +4025,35 @@
<Member Name="Load(System.String)" />
<Member Name="Load(System.Byte[])" />
<Member Name="Load(System.Byte[],System.Byte[])" />
+ <Member Name="LoadFile(System.String)" />
+ <Member Name="LoadFrom(System.String)" />
+ <Member Name="LoadFrom(System.String,System.Byte[],System.Configuration.Assemblies.AssemblyHashAlgorithm)" />
+ <Member Name="LoadModule(System.String,System.Byte[])" />
+ <Member Name="LoadModule(System.String,System.Byte[],System.Byte[])" />
+ <Member Name="LoadWithPartialName(System.String)" />
<Member Name="ReflectionOnlyLoad(System.String)" />
<Member Name="ReflectionOnlyLoad(System.Byte[])" />
<Member Name="ReflectionOnlyLoadFrom(System.String)" />
<Member Name="ToString" />
+ <Member Name="UnsafeLoadFrom(System.String)" />
<Member MemberType="Property" Name="DefinedTypes" />
<Member MemberType="Property" Name="CustomAttributes" />
<Member MemberType="Property" Name="Modules" />
<Member MemberType="Property" Name="ExportedTypes" />
<Member MemberType="Property" Name="EntryPoint" />
<Member MemberType="Property" Name="FullName" />
+ <Member MemberType="Property" Name="GlobalAssemblyCache" />
+ <Member MemberType="Property" Name="HostContext" />
<Member MemberType="Property" Name="CodeBase" />
+ <Member MemberType="Property" Name="EscapedCodeBase" />
<Member MemberType="Property" Name="ImageRuntimeVersion" />
+ <Member MemberType="Property" Name="IsFullyTrusted" />
<Member MemberType="Property" Name="Location" />
<Member MemberType="Property" Name="ManifestModule" />
- <Member Status="ImplRoot" MemberType="Event" Name="ModuleResolve" />
+ <Member MemberType="Property" Name="SecurityRuleSet" />
+ <Member MemberType="Event" Name="ModuleResolve" />
+ <Member Name="add_ModuleResolve(System.Reflection.ModuleResolveEventHandler)" />
+ <Member Name="remove_ModuleResolve(System.Reflection.ModuleResolveEventHandler)" />
</Type>
<Type Name="System.Reflection.IntrospectionExtensions">
<Member Name="GetTypeInfo(System.Type)" />
@@ -4084,6 +4185,7 @@
<Member Name="get_CultureInfo" />
<Member Name="get_CultureName" />
<Member Name="get_CodeBase" />
+ <Member Name="get_EscapedCodeBase" />
<Member Name="get_ContentType" />
<Member Name="get_Flags" />
<Member Name="get_FullName" />
@@ -4092,6 +4194,8 @@
<Member Name="get_Name" />
<Member Name="get_ProcessorArchitecture" />
<Member Name="get_Version" />
+ <Member Name="get_KeyPair" />
+ <Member Name="GetAssemblyName(System.String)" />
<Member Name="GetPublicKey" />
<Member Name="GetPublicKeyToken" />
<Member Name="set_CultureInfo(System.Globalization.CultureInfo)" />
@@ -4102,17 +4206,20 @@
<Member Name="set_Name(System.String)" />
<Member Name="set_ProcessorArchitecture(System.Reflection.ProcessorArchitecture)" />
<Member Name="set_Version(System.Version)" />
+ <Member Name="set_KeyPair(System.Reflection.StrongNameKeyPair)" />
<Member Name="Clone" />
<Member Name="SetPublicKey(System.Byte[])" />
<Member Name="SetPublicKeyToken(System.Byte[])" />
<Member Name="ToString" />
<Member Name="GetObjectData(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
<Member Name="OnDeserialization(System.Object)" />
+ <Member Name="ReferenceMatchesDefinition(System.Reflection.AssemblyName,System.Reflection.AssemblyName)" />
<Member Name="#ctor(System.String)" />
<Member MemberType="Property" Name="CodeBase" />
<Member MemberType="Property" Name="CultureInfo" />
<Member MemberType="Property" Name="CultureName" />
<Member MemberType="Property" Name="ContentType" />
+ <Member MemberType="Property" Name="EscapedCodeBase" />
<Member MemberType="Property" Name="Flags" />
<Member MemberType="Property" Name="FullName" />
<Member MemberType="Property" Name="HashAlgorithm" />
@@ -4120,6 +4227,7 @@
<Member MemberType="Property" Name="ProcessorArchitecture" />
<Member MemberType="Property" Name="Version" />
<Member MemberType="Property" Name="VersionCompatibility" />
+ <Member MemberType="Property" Name="KeyPair" />
</Type>
<Type Name="System.Reflection.AssemblyNameFlags">
<Member MemberType="Field" Name="EnableJITcompileOptimizer" />
@@ -4588,6 +4696,7 @@
<Member MemberType="Field" Name="Cond_Branch" />
<Member MemberType="Field" Name="Meta" />
<Member MemberType="Field" Name="Next" />
+ <Member MemberType="Field" Name="Phi" />
<Member MemberType="Field" Name="Return" />
<Member MemberType="Field" Name="Throw" />
<Member MemberType="Field" Name="value__" />
@@ -5106,6 +5215,7 @@
<Member Name="TakesSingleByteArgument(System.Reflection.Emit.OpCode)" />
</Type>
<Type Name="System.Reflection.Emit.OpCodeType">
+ <Member MemberType="Field" Name="Annotation" />
<Member MemberType="Field" Name="Macro" />
<Member MemberType="Field" Name="Nternal" />
<Member MemberType="Field" Name="Objmodel" />
@@ -5120,6 +5230,7 @@
<Member MemberType="Field" Name="InlineI8" />
<Member MemberType="Field" Name="InlineMethod" />
<Member MemberType="Field" Name="InlineNone" />
+ <Member MemberType="Field" Name="InlinePhi" />
<Member MemberType="Field" Name="InlineR" />
<Member MemberType="Field" Name="InlineSig" />
<Member MemberType="Field" Name="InlineString" />
@@ -5540,6 +5651,9 @@
<Member MemberType="Property" Name="IsPinvokeImpl" />
<Member MemberType="Property" Name="IsPrivate" />
<Member MemberType="Property" Name="IsPublic" />
+ <Member MemberType="Property" Name="IsSecurityCritical" />
+ <Member MemberType="Property" Name="IsSecuritySafeCritical" />
+ <Member MemberType="Property" Name="IsSecurityTransparent" />
<Member MemberType="Property" Name="IsSpecialName" />
<Member MemberType="Property" Name="IsStatic" />
<Member MemberType="Property" Name="MemberType" />
@@ -5673,6 +5787,9 @@
<Member Name="get_IsSpecialName" />
<Member Name="get_IsStatic" />
<Member Name="get_IsVirtual" />
+ <Member Name="get_IsSecurityCritical" />
+ <Member Name="get_IsSecuritySafeCritical" />
+ <Member Name="get_IsSecurityTransparent" />
<Member Name="get_MethodHandle" />
<Member Name="get_MethodImplementationFlags" />
<Member Name="GetGenericArguments" />
@@ -5706,6 +5823,9 @@
<Member MemberType="Property" Name="IsSpecialName" />
<Member MemberType="Property" Name="IsStatic" />
<Member MemberType="Property" Name="IsVirtual" />
+ <Member MemberType="Property" Name="IsSecurityCritical" />
+ <Member MemberType="Property" Name="IsSecuritySafeCritical" />
+ <Member MemberType="Property" Name="IsSecurityTransparent" />
<Member MemberType="Property" Name="MethodHandle" />
<Member MemberType="Property" Name="MethodImplementationFlags" />
<Member Name="GetCurrentMethod" />
@@ -5912,6 +6032,7 @@
<Member Name="Box(System.Void*,System.Type)" />
<Member Name="Unbox(System.Object)" />
<Member Name="System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
+ <Member Status="ImplRoot" Name="#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
</Type>
<Type Name="System.Reflection.PortableExecutableKinds">
<Member MemberType="Field" Name="NotAPortableExecutableImage" />
@@ -6104,6 +6225,15 @@
<Member Name="#ctor(System.String,System.Exception)" />
<Member Name="#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
</Type>
+ <Type Name="System.Resources.MissingSatelliteAssemblyException">
+ <Member Name="#ctor" />
+ <Member Name="#ctor(System.String)" />
+ <Member Name="#ctor(System.String,System.String)" />
+ <Member Name="#ctor(System.String,System.Exception)" />
+ <Member Name="#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
+ <Member Name="get_CultureName" />
+ <Member MemberType="Property" Name="CultureName"/>
+ </Type>
<Type Name="System.Resources.NeutralResourcesLanguageAttribute">
<Member Name="#ctor(System.String)" />
<Member Name="#ctor(System.String,System.Resources.UltimateResourceFallbackLocation)" />
@@ -6112,6 +6242,19 @@
<Member Name="get_Location" />
<Member MemberType="Property" Name="Location" />
</Type>
+ <Type Name="System.Resources.IResourceReader">
+ <Member Name="Close"/>
+ <Member Name="GetEnumerator"/>
+ </Type>
+ <Type Name="System.Resources.ResourceReader">
+ <Member Name="#ctor(System.IO.Stream)"/>
+ <Member Name="#ctor(System.String)"/>
+ <Member Name="Close"/>
+ <Member Name="Dispose"/>
+ <Member Name="GetResourceData(System.String,System.String@,System.Byte[]@)"/>
+ <Member Name="GetEnumerator"/>
+ <Member Name="System.Collections.IEnumerable.GetEnumerator"/>
+ </Type>
<Type Name="System.Resources.ResourceManager">
<Member MemberType="Field" Name="BaseNameField" />
<Member MemberType="Field" Name="HeaderVersionNumber" />
@@ -6124,6 +6267,7 @@
<Member Name="get_BaseName" />
<Member Name="get_IgnoreCase" />
<Member Name="get_ResourceSetType" />
+ <Member Name="get_FallbackLocation" />
<Member Name="GetNeutralResourcesLanguage(System.Reflection.Assembly)" />
<Member Name="GetObject(System.String)" />
<Member Name="GetObject(System.String,System.Globalization.CultureInfo)" />
@@ -6140,9 +6284,12 @@
<Member Status="ImplRoot" Name="OnSerializing(System.Runtime.Serialization.StreamingContext)" />
<Member Name="ReleaseAllResources" />
<Member Name="set_IgnoreCase(System.Boolean)" />
+ <Member Name="set_FallbackLocation(System.Resources.UltimateResourceFallbackLocation)" />
<Member MemberType="Property" Name="BaseName" />
<Member MemberType="Property" Name="IgnoreCase" />
<Member MemberType="Property" Name="ResourceSetType" />
+ <Member MemberType="Property" Name="FallbackLocation" />
+ <Member Name="CreateFileBasedResourceManager(System.String,System.String,System.Type)" />
</Type>
<Type Name="System.Resources.ResourceSet">
<Member MemberType="Field" Name="Reader" />
@@ -6150,10 +6297,12 @@
<Member Name="#ctor" />
<Member Name="#ctor(System.IO.Stream)" />
<Member Name="#ctor(System.String)" />
+ <Member Name="#ctor(System.Resources.IResourceReader)" />
<Member Name="Close" />
<Member Name="Dispose" />
<Member Name="Dispose(System.Boolean)" />
<Member Name="GetDefaultReader" />
+ <Member Name="GetDefaultWriter" />
<Member Name="GetEnumerator" />
<Member Name="GetObject(System.String)" />
<Member Name="GetObject(System.String,System.Boolean)" />
@@ -6180,10 +6329,6 @@
<Member Name="#ctor(System.Runtime.CompilerServices.CompilationRelaxations)" />
<Member MemberType="Property" Name="CompilationRelaxations" />
</Type>
- <Type Name="System.Runtime.CompilerServices.CallConvCdecl" /> <!-- for MC++ -->
- <Type Name="System.Runtime.CompilerServices.CallConvStdcall" /> <!-- for MC++ -->
- <Type Name="System.Runtime.CompilerServices.CallConvThiscall" /> <!-- for MC++ -->
- <Type Name="System.Runtime.CompilerServices.CallConvFastcall" /> <!-- for MC++ -->
<Type Name="System.Runtime.CompilerServices.CompilerMarshalOverride" />
<Type Name="System.Runtime.CompilerServices.CustomConstantAttribute">
<Member Name="#ctor" />
@@ -6206,6 +6351,21 @@
<Member Name="get_Value" />
<Member MemberType="Property" Name="Value" />
</Type>
+ <Type Name="System.Runtime.CompilerServices.DefaultDependencyAttribute">
+ <Member Name="#ctor(System.Runtime.CompilerServices.LoadHint)" />
+ <Member Name="get_LoadHint" />
+ <Member MemberType="Property" Name="LoadHint" />
+ </Type>
+ <Type Name="System.Runtime.CompilerServices.DependencyAttribute">
+ <Member Name="#ctor(System.String,System.Runtime.CompilerServices.LoadHint)" />
+ <Member Name="get_DependentAssembly" />
+ <Member Name="get_LoadHint" />
+ <Member MemberType="Property" Name="DependentAssembly" />
+ <Member MemberType="Property" Name="LoadHint" />
+ </Type>
+ <Type Name="System.Runtime.CompilerServices.DiscardableAttribute">
+ <Member Name="#ctor" />
+ </Type>
<Type Name="System.Runtime.CompilerServices.DisablePrivateReflectionAttribute">
<Member Name="#ctor" />
</Type>
@@ -6247,18 +6407,6 @@
</Type>
<Type Name="System.Runtime.CompilerServices.SuppressMergeCheckAttribute"> <!-- for MC++ -->
</Type>
- <Type Name="System.Runtime.CompilerServices.RequiredAttributeAttribute"> <!-- for MC++ -->
- <Member Name="#ctor(System.Type)" />
- <Member Name="get_RequiredContract" />
- </Type>
- <Type Name="System.Runtime.CompilerServices.IsBoxed"> <!-- for MC++ -->
- </Type>
- <Type Name="System.Runtime.CompilerServices.IsByValue"> <!-- for MC++ -->
- </Type>
- <Type Name="System.Runtime.CompilerServices.IsConst"> <!-- for MC++ -->
- </Type>
- <Type Name="System.Runtime.CompilerServices.IsCopyConstructed"> <!-- for MC++ -->
- </Type>
<Type Name="System.Runtime.CompilerServices.ICastable">
<Member Name="IsInstanceOfInterface(System.RuntimeTypeHandle,System.Exception@)" /> <!-- EE -->
<Member Name="GetImplType(System.RuntimeTypeHandle)" /> <!-- EE -->
@@ -6267,22 +6415,7 @@
<Member Name="IsInstanceOfInterface(System.Runtime.CompilerServices.ICastable,System.RuntimeType,System.Exception@)" /> <!-- EE -->
<Member Name="GetImplType(System.Runtime.CompilerServices.ICastable,System.RuntimeType)" /> <!-- EE -->
</Type>
- <Type Name="System.Runtime.CompilerServices.IsExplicitlyDereferenced"> <!-- for MC++ -->
- </Type>
- <Type Name="System.Runtime.CompilerServices.IsImplicitlyDereferenced"> <!-- for MC++ -->
- </Type>
- <Type Name="System.Runtime.CompilerServices.IsLong"> <!-- for MC++ -->
- </Type>
- <Type Name="System.Runtime.CompilerServices.IsJitIntrinsic"> <!-- for MC++ -->
- </Type>
- <Type Name="System.Runtime.CompilerServices.IsSignUnspecifiedByte"> <!-- for MC++ -->
- </Type>
- <Type Name="System.Runtime.CompilerServices.IsUdtReturn"> <!-- for MC++ -->
- </Type>
- <Type Name="System.Runtime.CompilerServices.NativeCppClassAttribute"> <!-- for MC++ -->
- <Member Name="#ctor" />
- </Type>
- <Type Name="System.Runtime.CompilerServices.IsVolatile" /> <!-- for MC++ -->
+ <Type Name="System.Runtime.CompilerServices.IsVolatile" /> <!-- for All Compilers, [ C# and MC++ uses it] -->
<Type Name="System.Runtime.CompilerServices.MethodCodeType">
<Member MemberType="Field" Name="IL" />
<Member MemberType="Field" Name="Native" />
@@ -6310,21 +6443,43 @@
<Member MemberType="Field" Name="value__" />
</Type>
<Type Name="System.Runtime.CompilerServices.RuntimeHelpers">
+ <Member Name="Equals(System.Object,System.Object)" />
<Member Name="GetUninitializedObject(System.Type)" />
<Member Name="EnsureSufficientExecutionStack" />
+ <Member Name="TryEnsureSufficientExecutionStack" />
<Member Name="get_OffsetToStringData" />
<Member Name="GetObjectValue(System.Object)" />
<Member Name="InitializeArray(System.Array,System.RuntimeFieldHandle)" />
<Member Name="GetHashCode(System.Object)" />
<Member Name="RunClassConstructor(System.RuntimeTypeHandle)" />
+ <Member Name="RunModuleConstructor(System.ModuleHandle)" />
+ <Member Name="ExecuteCodeWithGuaranteedCleanup(System.Runtime.CompilerServices.RuntimeHelpers+TryCode,System.Runtime.CompilerServices.RuntimeHelpers+CleanupCode,System.Object)" />
<Member MemberType="Property" Name="OffsetToStringData" />
<Member Status="ImplRoot" Name="ExecuteBackoutCodeHelper(System.Object,System.Object,System.Boolean)" />
- <Member Status="ImplRoot" Name="PrepareConstrainedRegionsNoOP" />
- <Member Status="ImplRoot" Name="PrepareConstrainedRegions" />
+ <Member Name="PrepareConstrainedRegions" />
+ <Member Name="PrepareConstrainedRegionsNoOP" />
+ <Member Name="PrepareContractedDelegate(System.Delegate)" />
+ <Member Name="PrepareDelegate(System.Delegate)" />
+ <Member Name="PrepareMethod(System.RuntimeMethodHandle)" />
+ <Member Name="PrepareMethod(System.RuntimeMethodHandle,System.RuntimeTypeHandle[])" />
+ <Member Name="ProbeForSufficientStack" />
+ </Type>
+ <Type Name="System.Runtime.CompilerServices.RuntimeHelpers+CleanupCode">
+ <Member Name="#ctor(System.Object,System.IntPtr)" />
+ <Member Name="BeginInvoke(System.Object,System.Boolean,System.AsyncCallback,System.Object)" />
+ <Member Name="EndInvoke(System.IAsyncResult)" />
+ <Member Name="Invoke(System.Object,System.Boolean)" />
+ </Type>
+ <Type Name="System.Runtime.CompilerServices.RuntimeHelpers+TryCode">
+ <Member Name="#ctor(System.Object,System.IntPtr)" />
+ <Member Name="BeginInvoke(System.Object,System.AsyncCallback,System.Object)" />
+ <Member Name="EndInvoke(System.IAsyncResult)" />
+ <Member Name="Invoke(System.Object)" />
</Type>
<Type Name="System.Runtime.CompilerServices.ConditionalWeakTable&lt;TKey,TValue&gt;">
<Member Name="#ctor" />
<Member Name="Add(TKey,TValue)" />
+ <Member Name="AddOrUpdate(TKey,TValue)" />
<Member Name="Remove(TKey)" />
<Member Name="TryGetValue(TKey,TValue@)" />
<Member Name="GetValue(TKey,System.Runtime.CompilerServices.ConditionalWeakTable+CreateValueCallback)" />
@@ -6361,10 +6516,16 @@
<Member MemberType="Property" Name="SourceException" />
</Type>
<!-- #endif FEATURE_EXCEPTIONDISPATCHINFO -->
+ <Type Name="System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs">
+ <Member Name="#ctor(System.Exception)" />
+ <Member Name="get_Exception" />
+ <Member MemberType="Property" Name="Exception" />
+ </Type>
<Type Name="System.Runtime.GCLatencyMode">
<Member MemberType="Field" Name="Batch" />
<Member MemberType="Field" Name="Interactive" />
<Member MemberType="Field" Name="LowLatency" />
+ <Member MemberType="Field" Name="NoGCRegion" />
<Member MemberType="Field" Name="SustainedLowLatency" />
</Type>
<Type Name="System.Runtime.GCSettings">
@@ -6415,7 +6576,6 @@
<Member MemberType="Property" Name="ErrorCode" />
<Member Name="get_ErrorCode" />
</Type>
- <Type Status="ImplRoot" Name="System.Runtime.InteropServices.LCIDConversionAttribute" Condition="FEATURE_COMINTEROP" />
<Type Name="System.Runtime.InteropServices.CallingConvention">
<Member MemberType="Field" Name="value__" />
<Member MemberType="Field" Name="Winapi" />
@@ -6527,6 +6687,36 @@
<Type Name="System.Runtime.InteropServices.AllowReversePInvokeCallsAttribute">
<Member Name="#ctor" />
</Type>
+ <Type Name="System.Runtime.InteropServices.AutomationProxyAttribute">
+ <Member Name="#ctor(System.Boolean)" />
+ <Member Name="get_Value" />
+ <Member MemberType="Property" Name="Value" />
+ </Type>
+ <Type Name="System.Runtime.InteropServices.ComAliasNameAttribute">
+ <Member Name="#ctor(System.String)" />
+ <Member Name="get_Value" />
+ <Member MemberType="Property" Name="Value" />
+ </Type>
+ <Type Name="System.Runtime.InteropServices.ComCompatibleVersionAttribute">
+ <Member Name="#ctor(System.Int32,System.Int32,System.Int32,System.Int32)" />
+ <Member Name="get_MajorVersion" />
+ <Member MemberType="Property" Name="MajorVersion" />
+ <Member Name="get_MinorVersion" />
+ <Member MemberType="Property" Name="MinorVersion" />
+ <Member Name="get_BuildNumber" />
+ <Member MemberType="Property" Name="BuildNumber" />
+ <Member Name="get_RevisionNumber" />
+ <Member MemberType="Property" Name="RevisionNumber" />
+ </Type>
+ <Type Name="System.Runtime.InteropServices.ComConversionLossAttribute">
+ <Member Name="#ctor" />
+ </Type>
+ <Type Name="System.Runtime.InteropServices.ComRegisterFunctionAttribute">
+ <Member Name="#ctor" />
+ </Type>
+ <Type Name="System.Runtime.InteropServices.ComUnregisterFunctionAttribute">
+ <Member Name="#ctor" />
+ </Type>
<Type Name="System.Runtime.InteropServices.ExternalException">
<Member Name="#ctor" />
<Member Name="#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
@@ -6535,6 +6725,7 @@
<Member Name="#ctor(System.String,System.Int32)" />
<Member Name="get_ErrorCode" />
<Member MemberType="Property" Name="ErrorCode" />
+ <Member Name="ToString" />
</Type>
<Type Name="System.Runtime.InteropServices.FieldOffsetAttribute">
<Member Name="#ctor(System.Int32)" />
@@ -6572,9 +6763,26 @@
<Member MemberType="Property" Name="Value" />
<Member Name="get_Value" />
</Type>
+ <Type Name="System.Runtime.InteropServices.HandleRef">
+ <Member Name="#ctor(System.Object,System.IntPtr)"/>
+ <Member MemberType="Property" Name="Handle"/>
+ <Member Name="get_Handle"/>
+ <Member MemberType="Property" Name="Wrapper"/>
+ <Member Name="get_Wrapper"/>
+ <Member Name="op_Explicit(System.Runtime.InteropServices.HandleRef)" ReturnType="System.IntPtr" />
+ <Member Name="ToIntPtr(System.Runtime.InteropServices.HandleRef)"/>
+ </Type>
<Type Name="System.Runtime.InteropServices.ICustomQueryInterface">
<Member Name="GetInterface(System.Guid@,System.IntPtr@)" />
</Type>
+ <Type Name="System.Runtime.InteropServices.ICustomFactory">
+ <Member Name="CreateInstance(System.Type)" />
+ </Type>
+ <Type Name="System.Runtime.InteropServices.ImportedFromTypeLibAttribute">
+ <Member Name="#ctor(System.String)" />
+ <Member Name="get_Value" />
+ <Member MemberType="Property" Name="Value" />
+ </Type>
<Type Name="System.Runtime.InteropServices.InAttribute">
<Member Name="#ctor" />
</Type>
@@ -6608,16 +6816,19 @@
<Member MemberType="Field" Name="Sequential" />
<Member MemberType="Field" Name="value__" />
</Type>
- <Type Name="System.Runtime.InteropServices.NativeCallableAttribute">
- <Member Name="#ctor" />
- <Member MemberType="Field" Name="CallingConvention" /> <!-- EE -->
- <Member MemberType="Field" Name="EntryPoint" /> <!-- EE -->
+ <Type Name="System.Runtime.InteropServices.LCIDConversionAttribute">
+ <Member Name="#ctor(System.Int32)" />
+ <Member Name="get_Value" />
+ <Member MemberType="Property" Name="Value" />
</Type>
<Type Name="System.Runtime.InteropServices.Marshal">
<Member MemberType="Field" Name="SystemDefaultCharSize" />
<Member Name="AddRef(System.IntPtr)" />
<Member Name="AllocHGlobal(System.Int32)" />
<Member Name="AllocCoTaskMem(System.Int32)" />
+ <Member Name="BindToMoniker(System.String)" />
+ <Member Name="ChangeWrapperHandleStrength(System.Object,System.Boolean)" />
+ <Member Name="CleanupUnusedObjectsInCurrentContext" />
<Member Name="Copy(System.Byte[],System.Int32,System.IntPtr,System.Int32)" />
<Member Name="Copy(System.Char[],System.Int32,System.IntPtr,System.Int32)" />
<Member Name="Copy(System.Double[],System.Int32,System.IntPtr,System.Int32)" />
@@ -6635,13 +6846,18 @@
<Member Name="FinalReleaseComObject(System.Object)" />
<Member Name="FreeHGlobal(System.IntPtr)" />
<Member Name="FreeCoTaskMem(System.IntPtr)" />
+ <Member Name="GenerateGuidForType(System.Type)" />
+ <Member Name="GenerateProgIdForType(System.Type)" />
<Member Name="GetComInterfaceForObject(System.Object,System.Type)" />
<Member Name="GetComInterfaceForObject(System.Object,System.Type,System.Runtime.InteropServices.CustomQueryInterfaceMode)" />
+ <Member Name="GetComObjectData(System.Object,System.Object)" />
<Member Name="GetDelegateForFunctionPointer(System.IntPtr,System.Type)" />
<Member Name="GetExceptionForHR(System.Int32)" />
<Member Name="GetExceptionForHR(System.Int32,System.IntPtr)" />
<Member Name="GetFunctionPointerForDelegate(System.Delegate)" />
<Member Name="GetHRForException(System.Exception)" />
+ <Member Name="GetHINSTANCE(System.Reflection.Module)" />
+ <Member Name="GetIDispatchForObject(System.Object)" />
<Member Name="GetIUnknownForObject(System.Object)" />
<Member Name="GetLastWin32Error" />
<Member Name="GetHRForLastWin32Error" />
@@ -6656,6 +6872,8 @@
<Member Name="PrelinkAll(System.Type)" />
<Member Name="PtrToStringAnsi(System.IntPtr)" />
<Member Name="PtrToStringAnsi(System.IntPtr,System.Int32)" />
+ <Member Name="PtrToStringAuto(System.IntPtr)" />
+ <Member Name="PtrToStringAuto(System.IntPtr,System.Int32)" />
<Member Name="PtrToStringUTF8(System.IntPtr)" />
<Member Name="PtrToStringUTF8(System.IntPtr,System.Int32)" />
<Member Name="PtrToStringUni(System.IntPtr)" />
@@ -6675,12 +6893,14 @@
<Member Name="ReadIntPtr(System.IntPtr,System.Int32)" />
<Member Name="Release(System.IntPtr)" />
<Member Name="ReleaseComObject(System.Object)" />
+ <Member Name="SetComObjectData(System.Object,System.Object,System.Object)" />
<Member Name="SetLastWin32Error(System.Int32)" />
<Member Name="SizeOf(System.Object)" />
<Member Name="SizeOf(System.Type)" />
<Member Name="StructureToPtr(System.Object,System.IntPtr,System.Boolean)" />
<Member Name="ThrowExceptionForHR(System.Int32)" />
<Member Name="ThrowExceptionForHR(System.Int32,System.IntPtr)" />
+ <Member Name="GetTypedObjectForIUnknown(System.IntPtr,System.Type)" />
<Member Name="UnsafeAddrOfPinnedArrayElement(System.Array,System.Int32)" />
<Member Name="WriteByte(System.IntPtr,System.Byte)" />
<Member Name="WriteByte(System.IntPtr,System.Int32,System.Byte)" />
@@ -6734,8 +6954,10 @@
<Member Name="SizeOf&lt;T&gt;(T)" />
<Member Name="StringToBSTR(System.String)" />
<Member Name="StringToCoTaskMemAnsi(System.String)" />
+ <Member Name="StringToCoTaskMemAuto(System.String)" />
<Member Name="StringToCoTaskMemUni(System.String)" />
<Member Name="StringToHGlobalAnsi(System.String)" />
+ <Member Name="StringToHGlobalAuto(System.String)" />
<Member Name="StringToHGlobalUni(System.String)" />
<Member Name="StringToCoTaskMemUTF8(System.String)" />
<Member Name="StructureToPtr&lt;T&gt;(T,System.IntPtr,System.Boolean)" />
@@ -6751,6 +6973,11 @@
<Member Name="ZeroFreeGlobalAllocAnsi(System.IntPtr)" />
<Member Name="ZeroFreeGlobalAllocUnicode(System.IntPtr)" />
<Member Name="ZeroFreeCoTaskMemUTF8(System.IntPtr)" />
+ <Member Name="SecureStringToCoTaskMemAnsi(System.Security.SecureString)" />
+ <Member Name="SecureStringToCoTaskMemUnicode(System.Security.SecureString)" />
+ <Member Name="SecureStringToGlobalAllocAnsi(System.Security.SecureString)" />
+ <Member Name="SecureStringToGlobalAllocUnicode(System.Security.SecureString)" />
+ <Member Name="SecureStringToBSTR(System.Security.SecureString)" />
</Type>
<Type Name="System.Runtime.InteropServices.MarshalAsAttribute">
<Member MemberType="Field" Name="ArraySubType" />
@@ -6767,12 +6994,24 @@
<Member MemberType="Field" Name="SafeArraySubType" />
<Member MemberType="Field" Name="SafeArrayUserDefinedSubType" />
</Type>
+ <Type Name="System.Runtime.InteropServices.ManagedToNativeComInteropStubAttribute">
+ <Member Name="#ctor(System.Type,System.String)" />
+ <Member Name="get_ClassType" />
+ <Member MemberType="Property" Name="ClassType" />
+ <Member Name="get_MethodName" />
+ <Member MemberType="Property" Name="MethodName" />
+ </Type>
<Type Name="System.Runtime.InteropServices.MarshalDirectiveException" >
<Member Name="#ctor" />
<Member Name="#ctor(System.String)" />
<Member Name="#ctor(System.String,System.Exception)" />
<Member Name="#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
</Type>
+ <Type Name="System.Runtime.InteropServices.NativeCallableAttribute">
+ <Member Name="#ctor" />
+ <Member MemberType="Field" Name="CallingConvention" /> <!-- EE -->
+ <Member MemberType="Field" Name="EntryPoint" /> <!-- EE -->
+ </Type>
<Type Name="System.Runtime.InteropServices.OptionalAttribute">
<Member Name="#ctor" />
</Type>
@@ -6782,8 +7021,17 @@
<Type Name="System.Runtime.InteropServices.PreserveSigAttribute">
<Member Name="#ctor" />
</Type>
- <Type Name="System.Runtime.InteropServices.RuntimeEnvironment">
- <Member Name="GetRuntimeDirectory" /> <!-- For use in the Framework, but not public in Win8P reference assemblies. -->
+ <Type Name="System.Runtime.InteropServices.PrimaryInteropAssemblyAttribute">
+ <Member Name="#ctor(System.Int32,System.Int32)" />
+ <Member Name="get_MajorVersion" />
+ <Member MemberType="Property" Name="MajorVersion" />
+ <Member Name="get_MinorVersion" />
+ <Member MemberType="Property" Name="MinorVersion" />
+ </Type>
+ <Type Name="System.Runtime.InteropServices.ProgIdAttribute">
+ <Member Name="#ctor(System.String)" />
+ <Member Name="get_Value" />
+ <Member MemberType="Property" Name="Value" />
</Type>
<Type Name="System.Runtime.InteropServices.SafeHandle">
<Member MemberType="Field" Name="handle" />
@@ -6804,6 +7052,18 @@
<Member MemberType="Property" Name="IsClosed" />
<Member MemberType="Property" Name="IsInvalid" />
</Type>
+ <Type Name="System.Runtime.InteropServices.TypeLibImportClassAttribute">
+ <Member Name="#ctor(System.Type)" />
+ <Member Name="get_Value" />
+ <Member MemberType="Property" Name="Value" />
+ </Type>
+ <Type Name="System.Runtime.InteropServices.TypeLibVersionAttribute">
+ <Member Name="#ctor(System.Int32,System.Int32)" />
+ <Member Name="get_MajorVersion" />
+ <Member MemberType="Property" Name="MajorVersion" />
+ <Member Name="get_MinorVersion" />
+ <Member MemberType="Property" Name="MinorVersion" />
+ </Type>
<Type Name="System.Runtime.InteropServices.CriticalHandle">
<Member MemberType="Field" Name="handle" />
<Member MemberType="Field" Name="_stackTrace" Flavor="chk,dbg" />
@@ -6821,6 +7081,14 @@
<Member MemberType="Property" Name="IsClosed" />
<Member MemberType="Property" Name="IsInvalid" />
</Type>
+ <Type Name="Microsoft.Win32.SafeHandles.CriticalHandleMinusOneIsInvalid">
+ <Member Name="#ctor" />
+ <Member Name="get_IsInvalid" />
+ </Type>
+ <Type Name="Microsoft.Win32.SafeHandles.CriticalHandleZeroOrMinusOneIsInvalid">
+ <Member Name="#ctor" />
+ <Member Name="get_IsInvalid" />
+ </Type>
<Type Name="Microsoft.Win32.SafeHandles.SafeHandleMinusOneIsInvalid">
<Member Name="#ctor(System.Boolean)" />
<Member Name="get_IsInvalid" />
@@ -6829,6 +7097,9 @@
<Member Name="#ctor(System.Boolean)" />
<Member Name="get_IsInvalid" />
</Type>
+ <Type Name="Microsoft.Win32.SafeHandles.SafeFileHandle">
+ <Member Name="#ctor(System.IntPtr,System.Boolean)" />
+ </Type>
<Type Name="Microsoft.Win32.SafeHandles.SafeWaitHandle">
<Member Name="#ctor(System.IntPtr,System.Boolean)" />
<Member Status="ApiRoot" Name="ReleaseHandle" />
@@ -6899,16 +7170,6 @@
<Member MemberType="Field" Name="IInspectable" />
<Member MemberType="Field" Name="IUnknown" />
</Type>
- <Type Status="ApiRoot" Name="System.Runtime.Versioning.ComponentGuaranteesAttribute">
- <Member Name="#ctor(System.Runtime.Versioning.ComponentGuaranteesOptions)" />
- <Member MemberType="Property" Name="Guarantees" />
- </Type>
- <Type Name="System.Runtime.Versioning.ComponentGuaranteesOptions">
- <Member MemberType="Field" Name="None" />
- <Member MemberType="Field" Name="Exchange" />
- <Member MemberType="Field" Name="Stable" />
- <Member MemberType="Field" Name="value__" />
- </Type>
<Type Name="System.RuntimeFieldHandle">
<Member Status="ImplRoot" Name="#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
<Member Name="Equals(System.RuntimeFieldHandle)" />
@@ -6949,12 +7210,80 @@
</Type>
<Type Name="System.Security.AllowPartiallyTrustedCallersAttribute">
<Member Name="#ctor" />
+ <Member Name="get_PartialTrustVisibilityLevel" />
+ <Member Name="set_PartialTrustVisibilityLevel(System.Security.PartialTrustVisibilityLevel)" />
+ <Member MemberType="Property" Name="PartialTrustVisibilityLevel" />
+ </Type>
+ <Type Name="System.Security.PartialTrustVisibilityLevel">
+ <Member MemberType="Field" Name="NotVisibleByDefault" />
+ <Member MemberType="Field" Name="value__" />
+ <Member MemberType="Field" Name="VisibleToAllHosts" />
+ </Type>
+ <Type Name="System.Security.SecureString">
+ <Member Name="#ctor" />
+ <Member Name="#ctor(System.Char*,System.Int32)" />
+ <Member Name="get_Length" />
+ <Member MemberType="Property" Name="Length" />
+ <Member Name="AppendChar(System.Char)" />
+ <Member Name="Clear" />
+ <Member Name="Copy" />
+ <Member Name="Dispose" />
+ <Member Name="InsertAt(System.Int32,System.Char)" />
+ <Member Name="IsReadOnly" />
+ <Member Name="MakeReadOnly" />
+ <Member Name="RemoveAt(System.Int32)" />
+ <Member Name="SetAt(System.Int32,System.Char)" />
+ </Type>
+ <Type Name="System.Security.SecurityCriticalAttribute">
+ <Member Name="#ctor" />
+ <Member Name="#ctor(System.Security.SecurityCriticalScope)" />
+ <Member Name="get_Scope" />
+ <Member MemberType="Property" Name="Scope" />
+ </Type>
+ <Type Name="System.Security.SecurityCriticalScope">
+ <Member MemberType="Field" Name="Everything" />
+ <Member MemberType="Field" Name="Explicit" />
+ <Member MemberType="Field" Name="value__" />
</Type>
<Type Name="System.Security.SecurityException">
<Member Name="#ctor" />
+ <Member Name="#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
<Member Name="#ctor(System.String)" />
<Member Name="#ctor(System.String,System.Exception)" />
- <Member Name="#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
+ <Member Name="#ctor(System.String,System.Type)" />
+ <Member Name="#ctor(System.String,System.Type,System.String)" />
+ <Member Name="get_Demanded" />
+ <Member Name="get_DenySetInstance" />
+ <Member Name="get_FailedAssemblyInfo" />
+ <Member Name="get_GrantedSet" />
+ <Member Name="get_Method" />
+ <Member Name="get_PermissionState" />
+ <Member Name="get_PermissionType" />
+ <Member Name="get_PermitOnlySetInstance" />
+ <Member Name="get_RefusedSet" />
+ <Member Name="get_Url" />
+ <Member Name="GetObjectData(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
+ <Member Name="set_Demanded(System.Object)" />
+ <Member Name="set_DenySetInstance(System.Object)" />
+ <Member Name="set_FailedAssemblyInfo(System.Reflection.AssemblyName)" />
+ <Member Name="set_GrantedSet(System.String)" />
+ <Member Name="set_Method(System.Reflection.MethodInfo)" />
+ <Member Name="set_PermissionState(System.String)" />
+ <Member Name="set_PermissionType(System.Type)" />
+ <Member Name="set_PermitOnlySetInstance(System.Object)" />
+ <Member Name="set_RefusedSet(System.String)" />
+ <Member Name="set_Url(System.String)" />
+ <Member Name="ToString" />
+ <Member MemberType="Property" Name="Demanded" />
+ <Member MemberType="Property" Name="DenySetInstance" />
+ <Member MemberType="Property" Name="FailedAssemblyInfo" />
+ <Member MemberType="Property" Name="GrantedSet" />
+ <Member MemberType="Property" Name="Method" />
+ <Member MemberType="Property" Name="PermissionState" />
+ <Member MemberType="Property" Name="PermissionType" />
+ <Member MemberType="Property" Name="PermitOnlySetInstance" />
+ <Member MemberType="Property" Name="RefusedSet" />
+ <Member MemberType="Property" Name="Url" />
</Type>
<Type Name="System.Security.SecurityState">
<Member Name="#ctor" />
@@ -7033,16 +7362,16 @@
<Member Name="CompareOrdinal(System.String,System.String)" />
<Member Name="CompareTo(System.Object)" />
<Member Name="CompareTo(System.String)" />
+ <Member Name="Concat(System.Collections.Generic.IEnumerable&lt;System.String&gt;)" />
<Member Name="Concat(System.Object)" />
<Member Name="Concat(System.Object,System.Object)" />
<Member Name="Concat(System.Object,System.Object,System.Object)" />
<Member Name="Concat(System.Object[])" />
- <Member Name="Concat&lt;T&gt;(System.Collections.Generic.IEnumerable&lt;T&gt;)" />
- <Member Name="Concat(System.Collections.Generic.IEnumerable&lt;System.String&gt;)" />
<Member Name="Concat(System.String,System.String)" />
<Member Name="Concat(System.String,System.String,System.String)" />
<Member Name="Concat(System.String,System.String,System.String,System.String)" />
<Member Name="Concat(System.String[])" />
+ <Member Name="Concat&lt;T&gt;(System.Collections.Generic.IEnumerable&lt;T&gt;)" />
<Member Name="Contains(System.String)" />
<Member Name="Copy(System.String)" />
<Member Name="CopyTo(System.Int32,System.Char[],System.Int32,System.Int32)" />
@@ -7064,7 +7393,9 @@
<Member Name="Format(System.String,System.Object[])" />
<Member Name="get_Chars(System.Int32)" />
<Member Name="get_Length" />
+ <Member Name="GetEnumerator" />
<Member Name="GetHashCode" />
+ <Member Name="GetHashCode(System.StringComparison)" />
<Member Name="GetTypeCode" />
<Member Name="IndexOf(System.Char)" />
<Member Name="IndexOf(System.Char,System.Int32)" />
@@ -7085,6 +7416,10 @@
<Member Name="IsNormalized(System.Text.NormalizationForm)" />
<Member Name="IsNullOrEmpty(System.String)" />
<Member Name="IsNullOrWhiteSpace(System.String)" />
+ <Member Name="Join(System.Char,System.Object[])" />
+ <Member Name="Join&lt;T&gt;(System.Char,System.Collections.Generic.IEnumerable&lt;T&gt;)" />
+ <Member Name="Join(System.Char,System.String[])" />
+ <Member Name="Join(System.Char,System.String[],System.Int32,System.Int32)" />
<Member Name="Join(System.String,System.Object[])" />
<Member Name="Join&lt;T&gt;(System.String,System.Collections.Generic.IEnumerable&lt;T&gt;)" />
<Member Name="Join(System.String,System.Collections.Generic.IEnumerable&lt;System.String&gt;)" />
@@ -7114,14 +7449,12 @@
<Member Name="Remove(System.Int32,System.Int32)" />
<Member Name="Replace(System.Char,System.Char)" />
<Member Name="Replace(System.String,System.String)" />
- <Member Name="Split(System.Char)" />
<Member Name="Split(System.Char,System.Int32,System.StringSplitOptions)" />
<Member Name="Split(System.Char,System.StringSplitOptions)"/>
<Member Name="Split(System.Char[])" />
<Member Name="Split(System.Char[],System.Int32)" />
<Member Name="Split(System.Char[],System.Int32,System.StringSplitOptions)" />
<Member Name="Split(System.Char[],System.StringSplitOptions)"/>
- <Member Name="Split(System.String)" />
<Member Name="Split(System.String,System.Int32,System.StringSplitOptions)" />
<Member Name="Split(System.String,System.StringSplitOptions)"/>
<Member Name="Split(System.String[],System.Int32,System.StringSplitOptions)" />
@@ -7147,6 +7480,7 @@
<Member Name="TrimStart(System.Char[])" />
<Member MemberType="Property" Name="Chars(System.Int32)" />
<Member MemberType="Property" Name="Length" />
+ <Member Status="ImplRoot" Name="System.Collections.IEnumerable.GetEnumerator" />
<Member Status="ImplRoot" Name="System.Collections.Generic.IEnumerable&lt;System.Char&gt;.GetEnumerator" />
<Member Status="ImplRoot" Name="CtorCharArray(System.Char[])" />
<Member Status="ImplRoot" Name="CtorCharArrayStartLength(System.Char[],System.Int32,System.Int32)" />
@@ -7161,7 +7495,7 @@
<Member Name="get_StructuralEqualityComparer" />
<Member MemberType="Property" Name="StructuralComparer" />
<Member MemberType="Property" Name="StructuralEqualityComparer" />
- </Type>
+ </Type>
<Type Name="System.StringComparer">
<Member Name="#ctor" />
<Member Name="Compare(System.Object,System.Object)" />
@@ -7169,6 +7503,7 @@
<Member Name="Create(System.Globalization.CultureInfo,System.Boolean)" />
<Member Name="Equals(System.Object,System.Object)" />
<Member Name="Equals(System.String,System.String)" />
+ <Member Name="FromComparison(System.StringComparison)" />
<Member Name="get_CurrentCulture" />
<Member Name="get_CurrentCultureIgnoreCase" />
<Member Name="get_InvariantCulture" />
@@ -7432,10 +7767,12 @@
<Member Name="GetByteCount(System.Char[])" />
<Member Name="GetByteCount(System.Char[],System.Int32,System.Int32)" />
<Member Name="GetByteCount(System.String)" />
+ <Member Name="GetByteCount(System.String,System.Int32,System.Int32)" />
<Member Name="GetBytes(System.Char[])" />
<Member Name="GetBytes(System.Char[],System.Int32,System.Int32)" />
<Member Name="GetBytes(System.Char[],System.Int32,System.Int32,System.Byte[],System.Int32)" />
<Member Name="GetBytes(System.String)" />
+ <Member Name="GetBytes(System.String,System.Int32,System.Int32)" />
<Member Name="GetBytes(System.String,System.Int32,System.Int32,System.Byte[],System.Int32)" />
<Member Name="GetBytes(System.Char*,System.Int32,System.Byte*,System.Int32)" />
<Member Name="GetCharCount(System.Byte[])" />
@@ -7541,6 +7878,10 @@
<Member Name="AppendFormat(System.String,System.Object,System.Object)" />
<Member Name="AppendFormat(System.String,System.Object,System.Object,System.Object)" />
<Member Name="AppendFormat(System.String,System.Object[])" />
+ <Member Name="AppendJoin&lt;T&gt;(System.Char,System.Collections.Generic.IEnumerable&lt;T&gt;)" />
+ <Member Name="AppendJoin&lt;T&gt;(System.Char,T[])" />
+ <Member Name="AppendJoin&lt;T&gt;(System.String,System.Collections.Generic.IEnumerable&lt;T&gt;)" />
+ <Member Name="AppendJoin&lt;T&gt;(System.String,T[])" />
<Member Name="AppendLine" />
<Member Name="AppendLine(System.String)" />
<Member Name="Clear" />
@@ -7685,6 +8026,21 @@
<Member MemberType="Property" Name="Mutex" />
<Member MemberType="Property" Name="MutexIndex" />
</Type>
+ <Type Name="System.Threading.ApartmentState">
+ <Member MemberType="Field" Name="MTA" />
+ <Member MemberType="Field" Name="STA" />
+ <Member MemberType="Field" Name="Unknown" />
+ <Member MemberType="Field" Name="value__" />
+ </Type>
+ <Type Name="System.Threading.AsyncFlowControl">
+ <Member Name="Dispose" />
+ <Member Name="Equals(System.Object)" />
+ <Member Name="Equals(System.Threading.AsyncFlowControl)" />
+ <Member Name="GetHashCode" />
+ <Member Name="op_Equality(System.Threading.AsyncFlowControl,System.Threading.AsyncFlowControl)" />
+ <Member Name="op_Inequality(System.Threading.AsyncFlowControl,System.Threading.AsyncFlowControl)" />
+ <Member Name="Undo" />
+ </Type>
<Type Name="System.Threading.AutoResetEvent">
<Member Name="#ctor(System.Boolean)" />
</Type>
@@ -7784,7 +8140,9 @@
<Member Name="TryEnter(System.Object,System.TimeSpan,System.Boolean@)" />
<Member Name="Wait(System.Object)" />
<Member Name="Wait(System.Object,System.Int32)" />
+ <Member Name="Wait(System.Object,System.Int32,System.Boolean)" />
<Member Name="Wait(System.Object,System.TimeSpan)" />
+ <Member Name="Wait(System.Object,System.TimeSpan,System.Boolean)" />
</Type>
<Type Name="System.Threading.ManualResetEvent">
<Member Name="#ctor(System.Boolean)" />
@@ -7797,14 +8155,18 @@
</Type>
<Type Name="System.Threading.SynchronizationContext">
<Member Name="#ctor"/>
- <Member Name="Send(System.Threading.SendOrPostCallback,System.Object)"/>
- <Member Name="Post(System.Threading.SendOrPostCallback,System.Object)"/>
- <Member Name="OperationStarted"/>
- <Member Name="OperationCompleted"/>
- <Member Name="SetSynchronizationContext(System.Threading.SynchronizationContext)"/>
- <Member Name="get_Current"/>
<Member Name="CreateCopy"/>
<Member MemberType="Property" Name="Current"/>
+ <Member Status="ImplRoot" Name="InvokeWaitMethodHelper(System.Threading.SynchronizationContext,System.IntPtr[],System.Boolean,System.Int32)"/>
+ <Member Name="IsWaitNotificationRequired"/>
+ <Member Name="OperationCompleted"/>
+ <Member Name="OperationStarted"/>
+ <Member Name="Post(System.Threading.SendOrPostCallback,System.Object)"/>
+ <Member Name="Send(System.Threading.SendOrPostCallback,System.Object)"/>
+ <Member Name="SetSynchronizationContext(System.Threading.SynchronizationContext)"/>
+ <Member Name="SetWaitNotificationRequired"/>
+ <Member Name="Wait(System.IntPtr[],System.Boolean,System.Int32)"/>
+ <Member Name="WaitHelper(System.IntPtr[],System.Boolean,System.Int32)"/>
</Type>
<Type Name="System.Threading.SynchronizationLockException">
<Member Name="#ctor" />
@@ -7821,14 +8183,8 @@
<Member Name="get_CurrentThread" />
<Member Name="get_CurrentUICulture" />
<Member Name="GetDomain" />
- <Member Name="get_IsBackground" />
<Member Name="get_ManagedThreadId" />
<Member Name="get_Name" />
- <Member Name="get_IsAlive" />
- <Member Name="get_ThreadState" />
- <Member Name="Join" />
- <Member Name="Join(System.Int32)" />
- <Member Name="set_IsBackground(System.Boolean)" />
<Member Name="set_Name(System.String)" />
<Member Name="Sleep(System.Int32)" />
<Member Name="Sleep(System.TimeSpan)" />
@@ -7838,39 +8194,77 @@
<Member MemberType="Property" Name="CurrentCulture" />
<Member MemberType="Property" Name="CurrentThread" />
<Member MemberType="Property" Name="CurrentUICulture" />
- <Member MemberType="Property" Name="IsBackground" />
<Member MemberType="Property" Name="ManagedThreadId" />
<Member MemberType="Property" Name="Name" />
- <Member MemberType="Property" Name="IsAlive" />
- <Member MemberType="Property" Name="ThreadState" />
<Member Status="ImplRoot" Name="InternalGetCurrentThread" />
<Member Status="ImplRoot" MemberType="Field" Name="DONT_USE_InternalThread" />
<Member Status="ImplRoot" MemberType="Field" Name="m_Priority" />
<Member Status="ImplRoot" MemberType="Field" Name="m_ThreadStartArg" />
</Type>
+ <Type Name="Internal.Runtime.Augments.RuntimeThread">
+ <Member MemberType="Property" Name="CurrentThread" />
+ <Member MemberType="Property" Name="IsAlive" />
+ <Member MemberType="Property" Name="IsBackground" />
+ <Member MemberType="Property" Name="IsThreadPoolThread" />
+ <Member MemberType="Property" Name="ManagedThreadId" />
+ <Member MemberType="Property" Name="Name" />
+ <Member MemberType="Property" Name="Priority" />
+ <Member MemberType="Property" Name="ThreadState" />
+ <Member Name="Create(System.Threading.ThreadStart)" />
+ <Member Name="Create(System.Threading.ThreadStart,System.Int32)" />
+ <Member Name="Create(System.Threading.ParameterizedThreadStart)" />
+ <Member Name="Create(System.Threading.ParameterizedThreadStart,System.Int32)" />
+ <Member Name="DisableComObjectEagerCleanup" />
+ <Member Name="GetApartmentState" />
+ <Member Name="Interrupt" />
+ <Member Name="Join" />
+ <Member Name="Join(System.Int32)" />
+ <Member Name="Sleep(System.Int32)" />
+ <Member Name="SpinWait(System.Int32)" />
+ <Member Name="Start" />
+ <Member Name="Start(System.Object)" />
+ <Member Name="TrySetApartmentState(System.Threading.ApartmentState)" />
+ <Member Name="Yield" />
+ </Type>
<Type Name="System.Threading.ThreadAbortException">
<Member Status="ImplRoot" Name="#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
</Type>
<Type Name="System.Threading.ThreadPool">
+ <Member Name="BindHandle(System.IntPtr)" />
+ <Member Name="BindHandle(System.Runtime.InteropServices.SafeHandle)" />
+ <Member Status="ImplRoot" Name="GetGloballyQueuedWorkItemsForDebugger"/>
+ <Member Status="ImplRoot" Name="GetLocallyQueuedWorkItemsForDebugger"/>
+ <Member Name="GetAvailableThreads(System.Int32@,System.Int32@)" />
<Member Name="GetMaxThreads(System.Int32@,System.Int32@)" />
+ <Member Name="GetMinThreads(System.Int32@,System.Int32@)" />
+ <Member Status="ImplRoot" Name="GetQueuedWorkItemsForDebugger"/>
+ <Member Status="ImplRoot" Name="NotifyWorkItemProgress"/>
<Member Name="QueueUserWorkItem(System.Threading.WaitCallback)" />
<Member Name="QueueUserWorkItem(System.Threading.WaitCallback,System.Object)" />
- <Member Name="SetMaxThreads(System.Int32,System.Int32)" />
- <Member Name="BindHandle(System.Runtime.InteropServices.SafeHandle)" />
- <Member Name="RegisterWaitForSingleObject(System.Threading.WaitHandle,System.Threading.WaitOrTimerCallback,System.Object,System.UInt32,System.Boolean)" />
<Member Name="RegisterWaitForSingleObject(System.Threading.WaitHandle,System.Threading.WaitOrTimerCallback,System.Object,System.Int32,System.Boolean)" />
<Member Name="RegisterWaitForSingleObject(System.Threading.WaitHandle,System.Threading.WaitOrTimerCallback,System.Object,System.Int64,System.Boolean)" />
<Member Name="RegisterWaitForSingleObject(System.Threading.WaitHandle,System.Threading.WaitOrTimerCallback,System.Object,System.TimeSpan,System.Boolean)" />
- <Member Name="SetMinThreads(System.Int32,System.Int32)" />
- <Member Name="GetMinThreads(System.Int32@,System.Int32@)" />
+ <Member Name="RegisterWaitForSingleObject(System.Threading.WaitHandle,System.Threading.WaitOrTimerCallback,System.Object,System.UInt32,System.Boolean)" />
<Member Status="ImplRoot" Name="RegisterWaitForSingleObject(System.Threading.WaitHandle,System.Threading.WaitOrTimerCallback,System.Object,System.UInt32,System.Boolean,System.Threading.StackCrawlMark@,System.Boolean)" />
<Member Status="ImplRoot" Name="RegisterWaitForSingleObjectNative(System.Threading.WaitHandle,System.Object,System.UInt32,System.Boolean,System.Threading.RegisteredWaitHandle,System.Threading.StackCrawlMark@,System.Boolean)" />
- <Member Status="ImplRoot" Name="UnsafeQueueCustomWorkItem(System.Threading.IThreadPoolWorkItem,System.Boolean)"/>
+ <Member Name="SetMaxThreads(System.Int32,System.Int32)" />
+ <Member Name="SetMinThreads(System.Int32,System.Int32)" />
<Member Status="ImplRoot" Name="TryPopCustomWorkItem(System.Threading.IThreadPoolWorkItem)"/>
- <Member Status="ImplRoot" Name="GetQueuedWorkItemsForDebugger"/>
- <Member Status="ImplRoot" Name="GetGloballyQueuedWorkItemsForDebugger"/>
- <Member Status="ImplRoot" Name="GetLocallyQueuedWorkItemsForDebugger"/>
- <Member Status="ImplRoot" Name="NotifyWorkItemProgress"/>
+ <Member Status="ImplRoot" Name="UnsafeQueueCustomWorkItem(System.Threading.IThreadPoolWorkItem,System.Boolean)"/>
+ <Member Name="UnsafeQueueNativeOverlapped(System.Threading.NativeOverlapped*)" />
+ <Member Name="UnsafeQueueUserWorkItem(System.Threading.WaitCallback,System.Object)" />
+ <Member Name="UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle,System.Threading.WaitOrTimerCallback,System.Object,System.Int32,System.Boolean)" />
+ <Member Name="UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle,System.Threading.WaitOrTimerCallback,System.Object,System.Int64,System.Boolean)" />
+ <Member Name="UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle,System.Threading.WaitOrTimerCallback,System.Object,System.TimeSpan,System.Boolean)" />
+ <Member Name="UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle,System.Threading.WaitOrTimerCallback,System.Object,System.UInt32,System.Boolean)" />
+ </Type>
+ <Type Name="System.Threading.ThreadPriority">
+ <Member MemberType="Field" Name="AboveNormal" />
+ <Member MemberType="Field" Name="BelowNormal" />
+ <Member MemberType="Field" Name="Highest" />
+ <Member MemberType="Field" Name="Lowest" />
+ <Member MemberType="Field" Name="Normal" />
+ <Member MemberType="Field" Name="value__" />
</Type>
<Type Status="ImplRoot" Name="System.Threading.StackCrawlMark">
<Member MemberType="Field" Name="LookForMe" />
@@ -7887,12 +8281,18 @@
</Type>
<Type Name="System.Threading.Overlapped">
<Member Name="#ctor" />
+ <Member Name="#ctor(System.Int32,System.Int32,System.Int32,System.IAsyncResult)" />
+ <Member Name="#ctor(System.Int32,System.Int32,System.IntPtr,System.IAsyncResult)" />
<Member MemberType="Property" Name="AsyncResult" />
+ <Member MemberType="Property" Name="EventHandle" />
+ <Member MemberType="Property" Name="EventHandleIntPtr" />
<Member MemberType="Property" Name="OffsetLow" />
<Member MemberType="Property" Name="OffsetHigh" />
<Member Name="Free(System.Threading.NativeOverlapped*)" />
+ <Member Name="Pack(System.Threading.IOCompletionCallback)" />
<Member Name="Pack(System.Threading.IOCompletionCallback,System.Object)" />
<Member Name="Unpack(System.Threading.NativeOverlapped*)" />
+ <Member Name="UnsafePack(System.Threading.IOCompletionCallback)" />
<Member Name="UnsafePack(System.Threading.IOCompletionCallback,System.Object)" Condition="FEATURE_COMINTEROP" />
</Type>
<Type Name="System.Threading.IOCompletionCallback">
@@ -7993,10 +8393,6 @@
<Member Name="WaitOne(System.TimeSpan,System.Boolean)" />
<Member MemberType="Property" Name="SafeWaitHandle" />
</Type>
- <Type Name="System.Threading.WaitHandleExtensions">
- <Member Name="GetSafeWaitHandle(System.Threading.WaitHandle)" />
- <Member Name="SetSafeWaitHandle(System.Threading.WaitHandle,Microsoft.Win32.SafeHandles.SafeWaitHandle)" />
- </Type>
<Type Name="System.Threading.WaitHandleCannotBeOpenedException">
<Member Name="#ctor" />
<Member Name="#ctor(System.String)" />
@@ -8088,20 +8484,18 @@
</Type>
<Type Name="System.TimeZone">
<Member Name="#ctor" />
+ <Member Name="get_CurrentTimeZone" />
<Member Name="get_DaylightName" />
<Member Name="get_StandardName" />
<Member Name="GetDaylightChanges(System.Int32)" />
<Member Name="GetUtcOffset(System.DateTime)" />
<Member Name="IsDaylightSavingTime(System.DateTime)" />
<Member Name="IsDaylightSavingTime(System.DateTime,System.Globalization.DaylightTime)" />
+ <Member Name="ToLocalTime(System.DateTime)" />
<Member Name="ToUniversalTime(System.DateTime)" />
+ <Member MemberType="Property" Name="CurrentTimeZone" />
<Member MemberType="Property" Name="DaylightName" />
<Member MemberType="Property" Name="StandardName" />
-<!-- This members need CurrentSystemTimeZone which needs Linux implementations
- <Member Name="ToLocalTime(System.DateTime)" />
- <Member MemberType="Property" Name="CurrentTimeZone" />
- <Member Name="get_CurrentTimeZone" />
--->
</Type>
<Type Name="System.TimeZoneInfo">
<Member Status="ImplRoot" Name="#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
@@ -8109,11 +8503,9 @@
<Member Name="ConvertTime(System.DateTime,System.TimeZoneInfo)" />
<Member Name="ConvertTime(System.DateTime,System.TimeZoneInfo,System.TimeZoneInfo)" />
<Member Name="ConvertTime(System.DateTimeOffset,System.TimeZoneInfo)" />
-<!-- Need Linux Implementation
<Member Name="ConvertTimeBySystemTimeZoneId(System.DateTime,System.String)" />
<Member Name="ConvertTimeBySystemTimeZoneId(System.DateTime,System.String,System.String)" />
<Member Name="ConvertTimeBySystemTimeZoneId(System.DateTimeOffset,System.String)" />
--->
<Member Name="ConvertTimeFromUtc(System.DateTime,System.TimeZoneInfo)" />
<Member Name="ConvertTimeToUtc(System.DateTime)" />
<Member Name="ConvertTimeToUtc(System.DateTime,System.TimeZoneInfo)" />
@@ -8386,6 +8778,9 @@
<Member Name="get_IsPrimitive" />
<Member Name="get_IsPublic" />
<Member Name="get_IsSealed" />
+ <Member Name="get_IsSecurityCritical" />
+ <Member Name="get_IsSecuritySafeCritical" />
+ <Member Name="get_IsSecurityTransparent" />
<Member Name="get_IsSerializable" />
<Member Name="get_IsSpecialName" />
<Member Name="get_IsUnicodeClass" />
@@ -8451,6 +8846,9 @@
<Member Name="GetType(System.String)" />
<Member Name="GetType(System.String,System.Boolean)" />
<Member Name="GetType(System.String,System.Boolean,System.Boolean)" />
+ <Member Name="GetType(System.String,System.Func&lt;System.Reflection.AssemblyName,System.Reflection.Assembly&gt;,System.Func&lt;System.Reflection.Assembly,System.String,System.Boolean,System.Type&gt;)" />
+ <Member Name="GetType(System.String,System.Func&lt;System.Reflection.AssemblyName,System.Reflection.Assembly&gt;,System.Func&lt;System.Reflection.Assembly,System.String,System.Boolean,System.Type&gt;,System.Boolean)" />
+ <Member Name="GetType(System.String,System.Func&lt;System.Reflection.AssemblyName,System.Reflection.Assembly&gt;,System.Func&lt;System.Reflection.Assembly,System.String,System.Boolean,System.Type&gt;,System.Boolean,System.Boolean)" />
<Member Name="GetTypeArray(System.Object[])" />
<Member Name="GetTypeCode(System.Type)" />
<Member Name="GetTypeCodeImpl" />
@@ -8459,6 +8857,7 @@
<Member Name="GetTypeFromCLSID(System.Guid,System.String)" />
<Member Name="GetTypeFromCLSID(System.Guid,System.String,System.Boolean)" />
<Member Name="GetTypeFromHandle(System.RuntimeTypeHandle)" />
+ <Member Status="ImplRoot" Name="GetTypeFromHandleUnsafe(System.IntPtr)" /> <!-- Used by System.Linq.Expressions tests -->
<Member Name="GetTypeFromProgID(System.String)" />
<Member Name="GetTypeFromProgID(System.String,System.Boolean)" />
<Member Name="GetTypeFromProgID(System.String,System.String)" />
@@ -8472,6 +8871,9 @@
<Member Name="IsAssignableFrom(System.Type)" />
<Member Name="IsByRefImpl" />
<Member Name="IsCOMObjectImpl" />
+ <Member Name="get_IsContextful" />
+ <Member MemberType="Property" Name="IsContextful" />
+ <Member Name="IsContextfulImpl" />
<Member Name="IsInstanceOfType(System.Object)" />
<Member Name="IsMarshalByRefImpl" />
<Member Name="IsPointerImpl" />
@@ -8813,6 +9215,9 @@
<Type Name="System.Runtime.CompilerServices.CompilerGeneratedAttribute">
<Member Name="#ctor" />
</Type>
+ <Type Name="System.Runtime.CompilerServices.CompilerGlobalScopeAttribute">
+ <Member Name="#ctor" />
+ </Type>
<!-- SMOSIER ADDED API ROOTS FOR our build process -->
<Type Name="System.Runtime.InteropServices.ComVisibleAttribute">
<Member Name="#ctor(System.Boolean)" />
@@ -8945,9 +9350,64 @@
<Member Name="#ctor(System.String,System.String,System.Exception)" />
<Member Name="#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
<Member Name="get_FileName" />
+ <Member Name="get_FusionLog" />
<Member MemberType="Property" Name="FileName" />
+ <Member MemberType="Property" Name="FusionLog" />
<Member Status="ImplRoot" Name="#ctor(System.String,System.String,System.Int32)" />
</Type>
+ <Type Name="System.IO.FileStream">
+ <Member Name="#ctor(System.IntPtr,System.IO.FileAccess)" />
+ <Member Name="#ctor(System.IntPtr,System.IO.FileAccess,System.Boolean)" />
+ <Member Name="#ctor(System.IntPtr,System.IO.FileAccess,System.Boolean,System.Int32)" />
+ <Member Name="#ctor(System.IntPtr,System.IO.FileAccess,System.Boolean,System.Int32,System.Boolean)" />
+ <Member Name="#ctor(Microsoft.Win32.SafeHandles.SafeFileHandle,System.IO.FileAccess)" />
+ <Member Name="#ctor(Microsoft.Win32.SafeHandles.SafeFileHandle,System.IO.FileAccess,System.Int32)" />
+ <Member Name="#ctor(Microsoft.Win32.SafeHandles.SafeFileHandle,System.IO.FileAccess,System.Int32,System.Boolean)" />
+ <Member Name="#ctor(System.String,System.IO.FileMode)" />
+ <Member Name="#ctor(System.String,System.IO.FileMode,System.IO.FileAccess)" />
+ <Member Name="#ctor(System.String,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare)" />
+ <Member Name="#ctor(System.String,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare,System.Int32)" />
+ <Member Name="#ctor(System.String,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare,System.Int32,System.Boolean)" />
+ <Member Name="#ctor(System.String,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare,System.Int32,System.IO.FileOptions)" />
+ <Member Name="BeginRead(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object)" />
+ <Member Name="BeginWrite(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object)" />
+ <Member Name="Dispose(System.Boolean)" />
+ <Member Name="EndRead(System.IAsyncResult)" />
+ <Member Name="EndWrite(System.IAsyncResult)" />
+ <Member Name="Finalize" />
+ <Member Name="Flush" />
+ <Member Name="Flush(System.Boolean)" />
+ <Member Name="FlushAsync(System.Threading.CancellationToken)" />
+ <Member Name="get_CanRead" />
+ <Member Name="get_CanSeek" />
+ <Member Name="get_CanWrite" />
+ <Member Name="get_Handle" />
+ <Member Name="get_IsAsync" />
+ <Member Name="get_Length" />
+ <Member Name="get_Name" />
+ <Member Name="get_Position" />
+ <Member Name="get_SafeFileHandle" />
+ <Member Name="Lock(System.Int64,System.Int64)" />
+ <Member Name="Read(System.Byte[],System.Int32,System.Int32)" />
+ <Member Name="ReadAsync(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken)" />
+ <Member Name="ReadByte" />
+ <Member Name="Seek(System.Int64,System.IO.SeekOrigin)" />
+ <Member Name="set_Position(System.Int64)" />
+ <Member Name="SetLength(System.Int64)" />
+ <Member Name="Unlock(System.Int64,System.Int64)" />
+ <Member Name="Write(System.Byte[],System.Int32,System.Int32)" />
+ <Member Name="WriteAsync(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken)" />
+ <Member Name="WriteByte(System.Byte)" />
+ <Member MemberType="Property" Name="CanRead" />
+ <Member MemberType="Property" Name="CanSeek" />
+ <Member MemberType="Property" Name="CanWrite" />
+ <Member MemberType="Property" Name="Handle" />
+ <Member MemberType="Property" Name="IsAsync" />
+ <Member MemberType="Property" Name="Length" />
+ <Member MemberType="Property" Name="Name" />
+ <Member MemberType="Property" Name="Position" />
+ <Member MemberType="Property" Name="SafeFileHandle" />
+ </Type>
<Type Name="System.IO.IOException">
<Member Name="#ctor" />
<Member Name="#ctor(System.String)" />
@@ -9000,15 +9460,18 @@
<Member MemberType="Field" Name="DirectorySeparatorChar" />
<Member MemberType="Field" Name="PathSeparator" />
<Member MemberType="Field" Name="VolumeSeparatorChar" />
+ <Member MemberType="Field" Name="InvalidPathChars" />
<Member Name="ChangeExtension(System.String,System.String)" />
<Member Name="Combine(System.String,System.String)" />
- <Member Name="Combine(System.String,System.String,System.String)" />
+ <Member Name="Combine(System.String,System.String,System.String)" />
+ <Member Name="Combine(System.String,System.String,System.String,System.String)" />
<Member Name="Combine(System.String[])" />
<Member Name="GetDirectoryName(System.String)" />
<Member Name="GetExtension(System.String)" />
<Member Name="GetFileName(System.String)" />
<Member Name="GetFileNameWithoutExtension(System.String)" />
<Member Name="GetFullPath(System.String)" />
+ <Member Name="GetRelativePath(System.String,System.String)" />
<Member Name="GetInvalidPathChars" />
<Member Name="GetInvalidFileNameChars" />
<Member Name="GetPathRoot(System.String)" />
@@ -9046,6 +9509,7 @@
<Member Name="CopyToAsync(System.IO.Stream,System.Int32)" />
<Member Name="CopyToAsync(System.IO.Stream,System.Int32,System.Threading.CancellationToken)" />
<Member Name="Close" />
+ <Member Name="CreateWaitHandle" />
<Member Name="Dispose" />
<Member Name="Dispose(System.Boolean)" />
<Member Name="EndRead(System.IAsyncResult)" />
@@ -9061,6 +9525,7 @@
<Member Name="get_Position" />
<Member Name="get_ReadTimeout" />
<Member Name="get_WriteTimeout" />
+ <Member Name="ObjectInvariant" />
<Member Name="Read(System.Byte[],System.Int32,System.Int32)" />
<Member Name="ReadByte" />
<Member Name="ReadAsync(System.Byte[],System.Int32,System.Int32)" />
@@ -9070,6 +9535,7 @@
<Member Name="set_ReadTimeout(System.Int32)" />
<Member Name="set_WriteTimeout(System.Int32)" />
<Member Name="SetLength(System.Int64)" />
+ <Member Name="Synchronized(System.IO.Stream)" />
<Member Name="Write(System.Byte[],System.Int32,System.Int32)" />
<Member Name="WriteAsync(System.Byte[],System.Int32,System.Int32)" />
<Member Name="WriteAsync(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken)" />
@@ -9083,185 +9549,6 @@
<Member MemberType="Property" Name="ReadTimeout" />
<Member MemberType="Property" Name="WriteTimeout" />
</Type>
- <Type Name="System.IO.StreamReader">
- <Member MemberType="Field" Name="Null" />
- <Member Name="#ctor(System.IO.Stream)" />
- <Member Name="#ctor(System.IO.Stream,System.Boolean)" />
- <Member Name="#ctor(System.IO.Stream,System.Text.Encoding)" />
- <Member Name="#ctor(System.IO.Stream,System.Text.Encoding,System.Boolean)" />
- <Member Name="#ctor(System.IO.Stream,System.Text.Encoding,System.Boolean,System.Int32)" />
- <Member Name="#ctor(System.IO.Stream,System.Text.Encoding,System.Boolean,System.Int32,System.Boolean)" />
- <Member Name="#ctor(System.String)" />
- <Member Name="#ctor(System.String,System.Boolean)" />
- <Member Name="#ctor(System.String,System.Text.Encoding)" />
- <Member Name="#ctor(System.String,System.Text.Encoding,System.Boolean)" />
- <Member Name="#ctor(System.String,System.Text.Encoding,System.Boolean,System.Int32)" />
- <Member Name="Close" />
- <Member Name="DiscardBufferedData" />
- <Member Name="Dispose(System.Boolean)" />
- <Member Name="get_BaseStream" />
- <Member Name="get_CurrentEncoding" />
- <Member Name="get_EndOfStream" />
- <Member Name="Peek" />
- <Member Name="Read" />
- <Member Name="Read(System.Char[],System.Int32,System.Int32)" />
- <Member Name="ReadAsync(System.Char[],System.Int32,System.Int32)" />
- <Member Name="ReadBlock(System.Char[],System.Int32,System.Int32)" />
- <Member Name="ReadBlockAsync(System.Char[],System.Int32,System.Int32)" />
- <Member Name="ReadLine" />
- <Member Name="ReadLineAsync" />
- <Member Name="ReadToEnd" />
- <Member Name="ReadToEndAsync" />
- <Member MemberType="Property" Name="BaseStream" />
- <Member MemberType="Property" Name="CurrentEncoding" />
- <Member MemberType="Property" Name="EndOfStream" />
- </Type>
- <Type Name="System.IO.StreamWriter">
- <Member MemberType="Field" Name="Null" />
- <Member Name="#ctor(System.IO.Stream)" />
- <Member Name="#ctor(System.IO.Stream,System.Text.Encoding)" />
- <Member Name="#ctor(System.IO.Stream,System.Text.Encoding,System.Int32)" />
- <Member Name="#ctor(System.IO.Stream,System.Text.Encoding,System.Int32,System.Boolean)" />
- <Member Name="#ctor(System.String)" />
- <Member Name="#ctor(System.String,System.Boolean)" />
- <Member Name="#ctor(System.String,System.Boolean,System.Text.Encoding)" />
- <Member Name="#ctor(System.String,System.Boolean,System.Text.Encoding,System.Int32)" />
- <Member Name="Close" />
- <Member Name="Dispose(System.Boolean)" />
- <Member Name="Flush" />
- <Member Name="FlushAsync" />
- <Member Name="get_AutoFlush" />
- <Member Name="get_BaseStream" />
- <Member Name="get_Encoding" />
- <Member Name="set_AutoFlush(System.Boolean)" />
- <Member Name="Write(System.Char)" />
- <Member Name="Write(System.Char[])" />
- <Member Name="Write(System.Char[],System.Int32,System.Int32)" />
- <Member Name="Write(System.String)" />
- <Member Name="WriteAsync(System.Char)" />
- <Member Name="WriteAsync(System.Char[],System.Int32,System.Int32)" />
- <Member Name="WriteAsync(System.String)" />
- <Member Name="WriteLineAsync" />
- <Member Name="WriteLineAsync(System.Char)" />
- <Member Name="WriteLineAsync(System.Char[],System.Int32,System.Int32)" />
- <Member Name="WriteLineAsync(System.String)" />
- <Member MemberType="Property" Name="AutoFlush" />
- <Member MemberType="Property" Name="BaseStream" />
- <Member MemberType="Property" Name="Encoding" />
- </Type>
- <Type Name="System.IO.StringReader">
- <Member Name="#ctor(System.String)" />
- <Member Name="Close" />
- <Member Name="Dispose(System.Boolean)" />
- <Member Name="Peek" />
- <Member Name="Read" />
- <Member Name="Read(System.Char[],System.Int32,System.Int32)" />
- <Member Name="ReadAsync(System.Char[],System.Int32,System.Int32)" />
- <Member Name="ReadBlockAsync(System.Char[],System.Int32,System.Int32)" />
- <Member Name="ReadLine" />
- <Member Name="ReadLineAsync" />
- <Member Name="ReadToEnd" />
- <Member Name="ReadToEndAsync" />
- </Type>
- <Type Name="System.IO.StringWriter">
- <Member Name="#ctor" />
- <Member Name="#ctor(System.IFormatProvider)" />
- <Member Name="#ctor(System.Text.StringBuilder)" />
- <Member Name="#ctor(System.Text.StringBuilder,System.IFormatProvider)" />
- <Member Name="Close" />
- <Member Name="Dispose(System.Boolean)" />
- <Member Name="FlushAsync" />
- <Member Name="get_Encoding" />
- <Member Name="GetStringBuilder" />
- <Member Name="ToString" />
- <Member Name="Write(System.Char)" />
- <Member Name="Write(System.Char[],System.Int32,System.Int32)" />
- <Member Name="Write(System.String)" />
- <Member Name="WriteAsync(System.Char)" />
- <Member Name="WriteAsync(System.Char[],System.Int32,System.Int32)" />
- <Member Name="WriteAsync(System.String)" />
- <Member Name="WriteLineAsync(System.Char)" />
- <Member Name="WriteLineAsync(System.Char[],System.Int32,System.Int32)" />
- <Member Name="WriteLineAsync(System.String)" />
- <Member MemberType="Property" Name="Encoding" />
- </Type>
- <Type Name="System.IO.TextReader">
- <Member MemberType="Field" Name="Null" />
- <Member Name="#ctor" />
- <Member Name="Close" />
- <Member Name="Dispose(System.Boolean)" />
- <Member Name="Peek" />
- <Member Name="Read" />
- <Member Name="Read(System.Char[],System.Int32,System.Int32)" />
- <Member Name="ReadAsync(System.Char[],System.Int32,System.Int32)" />
- <Member Name="ReadBlock(System.Char[],System.Int32,System.Int32)" />
- <Member Name="ReadBlockAsync(System.Char[],System.Int32,System.Int32)" />
- <Member Name="ReadLine" />
- <Member Name="ReadLineAsync" />
- <Member Name="ReadToEnd" />
- <Member Name="ReadToEndAsync" />
- </Type>
- <Type Name="System.IO.TextWriter">
- <Member MemberType="Field" Name="CoreNewLine" />
- <Member MemberType="Field" Name="Null" />
- <Member Name="#ctor" />
- <Member Name="#ctor(System.IFormatProvider)" />
- <Member Name="Close" />
- <Member Name="Dispose(System.Boolean)" />
- <Member Name="Flush" />
- <Member Name="FlushAsync" />
- <Member Name="get_Encoding" />
- <Member Name="get_FormatProvider" />
- <Member Name="get_NewLine" />
- <Member Name="set_NewLine(System.String)" />
- <Member Name="Write(System.Boolean)" />
- <Member Name="Write(System.Char)" />
- <Member Name="Write(System.Char[])" />
- <Member Name="Write(System.Char[],System.Int32,System.Int32)" />
- <Member Name="Write(System.Decimal)" />
- <Member Name="Write(System.Double)" />
- <Member Name="Write(System.Int32)" />
- <Member Name="Write(System.Int64)" />
- <Member Name="Write(System.Object)" />
- <Member Name="Write(System.Single)" />
- <Member Name="Write(System.String)" />
- <Member Name="Write(System.String,System.Object)" />
- <Member Name="Write(System.String,System.Object,System.Object)" />
- <Member Name="Write(System.String,System.Object,System.Object,System.Object)" />
- <Member Name="Write(System.String,System.Object[])" />
- <Member Name="Write(System.UInt32)" />
- <Member Name="Write(System.UInt64)" />
- <Member Name="WriteAsync(System.Char)" />
- <Member Name="WriteAsync(System.Char[])" />
- <Member Name="WriteAsync(System.Char[],System.Int32,System.Int32)" />
- <Member Name="WriteAsync(System.String)" />
- <Member Name="WriteLine" />
- <Member Name="WriteLine(System.Boolean)" />
- <Member Name="WriteLine(System.Char)" />
- <Member Name="WriteLine(System.Char[])" />
- <Member Name="WriteLine(System.Char[],System.Int32,System.Int32)" />
- <Member Name="WriteLine(System.Decimal)" />
- <Member Name="WriteLine(System.Double)" />
- <Member Name="WriteLine(System.Int32)" />
- <Member Name="WriteLine(System.Int64)" />
- <Member Name="WriteLine(System.Object)" />
- <Member Name="WriteLine(System.Single)" />
- <Member Name="WriteLine(System.String)" />
- <Member Name="WriteLine(System.String,System.Object)" />
- <Member Name="WriteLine(System.String,System.Object,System.Object)" />
- <Member Name="WriteLine(System.String,System.Object,System.Object,System.Object)" />
- <Member Name="WriteLine(System.String,System.Object[])" />
- <Member Name="WriteLine(System.UInt32)" />
- <Member Name="WriteLine(System.UInt64)" />
- <Member Name="WriteLineAsync" />
- <Member Name="WriteLineAsync(System.Char)" />
- <Member Name="WriteLineAsync(System.Char[])" />
- <Member Name="WriteLineAsync(System.Char[],System.Int32,System.Int32)" />
- <Member Name="WriteLineAsync(System.String)" />
- <Member MemberType="Property" Name="Encoding" />
- <Member MemberType="Property" Name="FormatProvider" />
- <Member MemberType="Property" Name="NewLine" />
- </Type>
<Type Name="System.IO.UnmanagedMemoryAccessor">
<Member Name="#ctor" />
<Member Name="#ctor(System.Runtime.InteropServices.SafeBuffer,System.Int64,System.Int64)" />
@@ -9273,6 +9560,8 @@
<Member Name="get_Capacity" />
<Member Name="get_IsOpen" />
<Member Name="Initialize(System.Runtime.InteropServices.SafeBuffer,System.Int64,System.Int64,System.IO.FileAccess)" />
+ <Member Name="Read&lt;T&gt;(System.Int64,T@)" />
+ <Member Name="ReadArray&lt;T&gt;(System.Int64,T[],System.Int32,System.Int32)" />
<Member Name="ReadBoolean(System.Int64)" />
<Member Name="ReadByte(System.Int64)" />
<Member Name="ReadChar(System.Int64)" />
@@ -9299,6 +9588,8 @@
<Member Name="Write(System.Int64,System.UInt16)" />
<Member Name="Write(System.Int64,System.UInt32)" />
<Member Name="Write(System.Int64,System.UInt64)" />
+ <Member Name="Write&lt;T&gt;(System.Int64,T@)" />
+ <Member Name="WriteArray&lt;T&gt;(System.Int64,T[],System.Int32,System.Int32)" />
<Member MemberType="Property" Name="CanRead" />
<Member MemberType="Property" Name="CanWrite" />
<Member MemberType="Property" Name="Capacity" />
@@ -9726,7 +10017,6 @@
</Type>
<Type Name="System.Diagnostics.Tracing.FrameworkEventSource+Keywords">
<Member MemberType="Field" Name="Loader" />
- <Member MemberType="Field" Name="ThreadPool" />
<Member MemberType="Field" Name="NetClient" />
<Member MemberType="Field" Name="DynamicTypeUsage" />
<Member MemberType="Field" Name="ThreadTransfer" />
@@ -9831,12 +10121,22 @@
<Member Status="ImplRoot" MemberType="Field" Name="_empty2" />
<Member Status="ImplRoot" MemberType="Field" Name="_empty3" />
</Type>
- <Type Name="System.Reflection.TypeFilter">
+ <Type Name="System.Reflection.TypeFilter">
<Member Name="#ctor(System.Object,System.IntPtr)" />
<Member Status="ApiRoot" Name="BeginInvoke(System.Type,System.Object,System.AsyncCallback,System.Object)" />
<Member Status="ApiRoot" Name="EndInvoke(System.IAsyncResult)" />
<Member Status="ApiRoot" Name="Invoke(System.Type,System.Object)" />
</Type>
+ <Type Name="System.Reflection.StrongNameKeyPair">
+ <Member Name="#ctor(System.Byte[])" />
+ <Member Name="#ctor(System.IO.FileStream)" />
+ <Member Name="#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
+ <Member Name="#ctor(System.String)" />
+ <Member Name="get_PublicKey" />
+ <Member MemberType="Property" Name="PublicKey" />
+ <Member Status="ImplRoot" Name="System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(System.Object)" />
+ <Member Status="ImplRoot" Name="System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
+ </Type>
<Type Status="ImplRoot" Name="System.ReflectionOnlyType" />
<Type Status="ImplRoot" Name="System.ResId" />
<Type Status="ImplRoot" Name="System.Resolver">
@@ -9849,8 +10149,14 @@
<Member Name="ResolveToken(System.Int32,System.IntPtr@,System.IntPtr@,System.IntPtr@)" /> <!-- EE -->
<Member Name="ResolveSignature(System.Int32,System.Int32)" /> <!-- EE -->
</Type>
- <Type Status="ImplRoot" Name="System.Runtime.CompilerServices.RuntimeWrappedException">
+ <Type Name="System.Runtime.CompilerServices.RuntimeWrappedException">
<Member Name="#ctor(System.Object)" /> <!-- EE -->
+ <Member Name="get_WrappedException" />
+ <Member Name="GetObjectData(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
+ <Member MemberType="Property" Name="WrappedException" />
+ </Type>
+ <Type Name="System.Runtime.CompilerServices.StringFreezingAttribute">
+ <Member Name="#ctor" />
</Type>
<Type Status="ImplRoot" Name="System.Runtime.CompilerServices.TypeDependencyAttribute">
<Member Name="#ctor(System.String)" />
@@ -9865,7 +10171,13 @@
<Member Name="op_Equality(System.Runtime.InteropServices.ArrayWithOffset,System.Runtime.InteropServices.ArrayWithOffset)" />
<Member Name="op_Inequality(System.Runtime.InteropServices.ArrayWithOffset,System.Runtime.InteropServices.ArrayWithOffset)" />
</Type>
- <Type Status="ImplRoot" Name="System.Runtime.ConstrainedExecution.ReliabilityContractAttribute" />
+ <Type Name="System.Runtime.ConstrainedExecution.ReliabilityContractAttribute">
+ <Member Name="#ctor(System.Runtime.ConstrainedExecution.Consistency,System.Runtime.ConstrainedExecution.Cer)" />
+ <Member Name="get_Cer" />
+ <Member Name="get_ConsistencyGuarantee" />
+ <Member MemberType="Property" Name="Cer" />
+ <Member MemberType="Property" Name="ConsistencyGuarantee" />
+ </Type>
<Type Status="ImplRoot" Name="System.Runtime.ConstrainedExecution.PrePrepareMethodAttribute" />
<Type Name="System.Runtime.ConstrainedExecution.CriticalFinalizerObject">
<Member Name="#ctor"/>
@@ -9875,7 +10187,7 @@
<Member Name="AddField(System.String)" /> <!-- EE -->
<Member Name="RemoveMember(System.Reflection.MemberInfo)" /> <!-- EE -->
</Type>
- <Type Status="ImplRoot" Name="System.Runtime.InteropServices.ICustomMarshaler">
+ <Type Name="System.Runtime.InteropServices.ICustomMarshaler">
<Member Name="MarshalNativeToManaged(System.IntPtr)" /> <!-- EE -->
<Member Name="MarshalManagedToNative(System.Object)" /> <!-- EE -->
<Member Name="CleanUpNativeData(System.IntPtr)" /> <!-- EE -->
@@ -10278,25 +10590,11 @@
<Member Name="RemoveEventHandler&lt;T&gt;(System.Action&lt;System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken&gt;,T)" />
<Member Name="StringToHString(System.String)" />
</Type>
- <Type Status="ImplRoot" Name="System.Runtime.Versioning.ResourceConsumptionAttribute">
- <Member Name="#ctor(System.Runtime.Versioning.ResourceScope)" />
- <Member Name="#ctor(System.Runtime.Versioning.ResourceScope,System.Runtime.Versioning.ResourceScope)" />
- <Member MemberType="Property" Name="ConsumptionScope" />
- <Member MemberType="Property" Name="ResourceScope" />
- </Type>
- <Type Status="ApiRoot" Name="System.Runtime.Versioning.ResourceExposureAttribute">
- <Member Name="#ctor(System.Runtime.Versioning.ResourceScope)" />
- <Member MemberType="Property" Name="ResourceExposureLevel" />
- </Type>
<Type Status="ApiRoot" Name="System.Runtime.Versioning.TargetFrameworkAttribute">
<Member Name="#ctor(System.String)" />
<Member MemberType="Property" Name="FrameworkName" />
<Member MemberType="Property" Name="FrameworkDisplayName" />
</Type>
- <Type Status="ApiRoot" Name="System.Runtime.Versioning.VersioningHelper">
- <Member Name="MakeVersionSafeName(System.String,System.Runtime.Versioning.ResourceScope,System.Runtime.Versioning.ResourceScope)" />
- <Member Name="MakeVersionSafeName(System.String,System.Runtime.Versioning.ResourceScope,System.Runtime.Versioning.ResourceScope,System.Type)" />
- </Type>
<Type Name="System.Runtime.Serialization.FormatterServices">
<Member Name="GetUninitializedObject(System.Type)" />
</Type>
@@ -10397,6 +10695,14 @@
<Type Name="System.Runtime.Serialization.IDeserializationCallback">
<Member Name="OnDeserialization(System.Object)" />
</Type>
+ <Type Name="System.Runtime.Serialization.ISafeSerializationData">
+ <Member Name="CompleteDeserialization(System.Object)" />
+ </Type>
+ <Type Name="System.Runtime.Serialization.SafeSerializationEventArgs">
+ <Member Name="AddSerializedState(System.Runtime.Serialization.ISafeSerializationData)" />
+ <Member Name="get_StreamingContext" />
+ <Member MemberType="Property" Name="StreamingContext" />
+ </Type>
<Type Status="ApiRoot" Name="System.Runtime.Serialization.OnSerializingAttribute">
<Member Name="#ctor" />
</Type>
@@ -10450,6 +10756,15 @@
<Member Name="CheckSetDemandNoThrow(System.Security.PermissionSet)" /> <!-- EE -->
<Member Name="Update(System.Security.PermissionSet)" /> <!-- EE -->
</Type>
+ <Type Name="System.Security.Cryptography.CryptographicException">
+ <Member Name="#ctor"/>
+ <Member Name="#ctor(System.Int32)"/>
+ <Member Name="#ctor(System.String)"/>
+ <Member Name="#ctor(System.String,System.Exception)"/>
+ <Member Name="#ctor(System.String,System.String)"/>
+ <Member Name="#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
+ </Type>
+
<Type Status="ImplRoot" Name="System.Security.Permissions.PermissionState" />
<Type Name="System.Security.Permissions.SecurityAction" />
<Type Status="ImplRoot" Name="System.Security.Permissions.SecurityPermission" />
@@ -10501,17 +10816,34 @@
<Member MemberType="Field" Name="None" />
<Member MemberType="Field" Name="value__" />
</Type>
- <Type Name="System.Security.SecurityCriticalAttribute">
- <Member Name="#ctor" />
- </Type>
<Type Status="ImplRoot" Name="System.Security.SecurityRuntime">
<Member Name="FrameDescHelper(System.Security.FrameSecurityDescriptor,System.Security.IPermission,System.Security.PermissionToken,System.RuntimeMethodHandleInternal)" /> <!-- EE -->
<Member Name="FrameDescSetHelper(System.Security.FrameSecurityDescriptor,System.Security.PermissionSet,System.Security.PermissionSet@,System.RuntimeMethodHandleInternal)" /> <!-- EE -->
</Type>
+ <Type Name="System.Security.SecurityRulesAttribute">
+ <Member Name="#ctor(System.Security.SecurityRuleSet)" />
+ <Member Name="get_RuleSet" />
+ <Member Name="get_SkipVerificationInFullTrust" />
+ <Member Name="set_SkipVerificationInFullTrust(System.Boolean)" />
+ <Member MemberType="Property" Name="RuleSet" />
+ <Member MemberType="Property" Name="SkipVerificationInFullTrust" />
+ </Type>
+ <Type Name="System.Security.SecurityRuleSet">
+ <Member MemberType="Field" Name="Level1" />
+ <Member MemberType="Field" Name="Level2" />
+ <Member MemberType="Field" Name="None" />
+ <Member MemberType="Field" Name="value__" />
+ </Type>
+ <Type Name="System.Security.SecuritySafeCriticalAttribute">
+ <Member Name="#ctor" />
+ </Type>
<Type Name="System.Security.SecurityTransparentAttribute">
<Member Name="#ctor" />
</Type>
- <Type Name="System.Security.SecuritySafeCriticalAttribute" >
+ <Type Name="System.Security.SecurityTreatAsSafeAttribute">
+ <Member Name="#ctor" />
+ </Type>
+ <Type Name="System.Security.SuppressUnmanagedCodeSecurityAttribute">
<Member Name="#ctor" />
</Type>
<Type Name="System.Security.UnverifiableCodeAttribute">
@@ -10555,7 +10887,10 @@
</Type>
<Type Status="ImplRoot" Name="System.Threading.InternalCrossContextDelegate" />
<Type Status="ImplRoot" Name="System.Threading.OverlappedData" />
- <Type Status="ImplRoot" Name="System.Threading.ThreadInterruptedException">
+ <Type Name="System.Threading.ThreadInterruptedException">
+ <Member Name="#ctor" />
+ <Member Name="#ctor(System.String)" />
+ <Member Name="#ctor(System.String,System.Exception)" />
<Member Name="#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
</Type>
<Type Name="System.ThreadStaticAttribute">
@@ -11896,8 +12231,15 @@
<Member Name="get_ThreadContextChanged"/>
</Type>
<Type Name="System.Threading.ExecutionContext">
+ <Member Status="ImplRoot" Name="#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
<Member Name="Capture" />
+ <Member Name="CreateCopy" />
+ <Member Name="Dispose" />
+ <Member Name="GetObjectData(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
+ <Member Name="IsFlowSuppressed" />
+ <Member Name="RestoreFlow" />
<Member Name="Run(System.Threading.ExecutionContext,System.Threading.ContextCallback,System.Object)"/>
+ <Member Name="SuppressFlow" />
</Type>
<Type Name="System.Threading.CancellationToken">
<Member Name="#ctor(System.Boolean)"/>
@@ -12080,5 +12422,65 @@
<Member Name="WriteLine(System.String)" />
<Member Name="WriteLine" />
</Type>
+ <Type Name="System.Span&lt;T&gt;" Condition="FEATURE_SPAN_OF_T">
+ <Member Name="#ctor(T[])" />
+ <Member Name="#ctor(T[],System.Int32)" />
+ <Member Name="#ctor(T[],System.Int32,System.Int32)" />
+ <Member Name="#ctor(System.Void*,System.Int32)" />
+ <Member Name="DangerousGetPinnableReference" />
+ <Member Name="op_Implicit(T[])" ReturnType="System.Span&lt;T&gt;" />
+ <Member Name="op_Implicit(System.ArraySegment&lt;T&gt;)" ReturnType="System.Span&lt;T&gt;" />
+ <Member Name="op_Implicit(System.Span&lt;T&gt;)" ReturnType="System.ReadOnlySpan&lt;T&gt;" />
+ <Member Name="op_Equality(System.Span&lt;T&gt;,System.Span&lt;T&gt;)" />
+ <Member Name="op_Inequality(System.Span&lt;T&gt;,System.Span&lt;T&gt;)" />
+ <Member Name="get_Length" />
+ <Member Name="get_Empty" />
+ <Member Name="get_IsEmpty" />
+ <Member Name="get_Item(System.Int32)" />
+ <Member Name="set_Item(System.Int32,T)" />
+ <Member Name="ToArray" />
+ <Member Name="Slice(System.Int32)" />
+ <Member Name="Slice(System.Int32,System.Int32)" />
+ <Member Name="Equals(System.Object)" />
+ <Member Name="DangerousCreate(System.Object,T@,System.Int32)" />
+ <Member Name="GetHashCode" />
+ <Member Name="CopyTo(System.Span&lt;T&gt;)" />
+ <Member Name="TryCopyTo(System.Span&lt;T&gt;)" />
+ </Type>
+ <Type Name="System.ReadOnlySpan&lt;T&gt;" Condition="FEATURE_SPAN_OF_T">
+ <Member Name="#ctor(T[])" />
+ <Member Name="#ctor(T[],System.Int32)" />
+ <Member Name="#ctor(T[],System.Int32,System.Int32)" />
+ <Member Name="#ctor(System.Void*,System.Int32)" />
+ <Member Name="DangerousGetPinnableReference" />
+ <Member Name="op_Implicit(System.Span&lt;T&gt;)" ReturnType="System.ReadOnlySpan&lt;T&gt;" />
+ <Member Name="op_Implicit(T[])" ReturnType="System.ReadOnlySpan&lt;T&gt;" />
+ <Member Name="op_Implicit(System.ArraySegment&lt;T&gt;)" ReturnType="System.ReadOnlySpan&lt;T&gt;" />
+ <Member Name="op_Equality(System.ReadOnlySpan&lt;T&gt;,System.ReadOnlySpan&lt;T&gt;)" />
+ <Member Name="op_Inequality(System.ReadOnlySpan&lt;T&gt;,System.ReadOnlySpan&lt;T&gt;)" />
+ <Member Name="get_Length" />
+ <Member Name="get_Empty" />
+ <Member Name="get_IsEmpty" />
+ <Member Name="get_Item(System.Int32)" />
+ <Member Name="ToArray" />
+ <Member Name="Slice(System.Int32)" />
+ <Member Name="Slice(System.Int32,System.Int32)" />
+ <Member Name="Equals(System.Object)" />
+ <Member Name="DangerousCreate(System.Object,T@,System.Int32)" />
+ <Member Name="GetHashCode" />
+ <Member Name="TryCopyTo(System.Span&lt;T&gt;)" />
+ <Member Name="CopyTo(System.Span&lt;T&gt;)" />
+ </Type>
+ <Type Name="System.SpanExtensions" Condition="FEATURE_SPAN_OF_T">
+ <Member Name="AsBytes&lt;T&gt;(System.Span&lt;T&gt;)" />
+ <Member Name="AsBytes&lt;T&gt;(System.ReadOnlySpan&lt;T&gt;)" />
+ <Member Name="NonPortableCast&lt;TFrom,TTo&gt;(System.Span&lt;TFrom&gt;)" />
+ <Member Name="NonPortableCast&lt;TFrom,TTo&gt;(System.ReadOnlySpan&lt;TFrom&gt;)" />
+ </Type>
+ <Type Name="System.ReadOnlySpanExtensions" Condition="FEATURE_SPAN_OF_T">
+ <Member Name="Slice(System.String)" />
+ <Member Name="Slice(System.String,System.Int32)" />
+ <Member Name="Slice(System.String,System.Int32,System.Int32)" />
+ </Type>
</Assembly>
</ThinModel>
diff --git a/src/mscorlib/mscorlib.shared.sources.props b/src/mscorlib/mscorlib.shared.sources.props
index fc5153f062..3c4b1bce4a 100644
--- a/src/mscorlib/mscorlib.shared.sources.props
+++ b/src/mscorlib/mscorlib.shared.sources.props
@@ -2,7 +2,6 @@
<ItemGroup>
<CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\AccessedThroughPropertyAttribute.cs" />
<CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\AssemblyAttributesGoHere.cs" />
- <CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\CallingConvention.cs" />
<CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\RuntimeHelpers.cs" />
<CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\CompilerGeneratedAttribute.cs" />
<CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\CustomConstantAttribute.cs" />
@@ -21,29 +20,15 @@
<CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\MethodImplAttribute.cs" />
<CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\FixedAddressValueTypeAttribute.cs" />
<CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\UnsafeValueTypeAttribute.cs" />
- <CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\RequiredAttributeAttribute.cs" />
<CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\AssemblySettingAttributes.cs" />
<CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\TypeDependencyAttribute.cs" />
<CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\CompilerMarshalOverride.cs" />
- <CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\HasCopySemanticsAttribute.cs" />
- <CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\IsBoxed.cs" />
- <CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\IsByValue.cs" />
- <CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\IsConst.cs" />
- <CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\IsExplicitlyDereferenced.cs" />
- <CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\IsImplicitlyDereferenced.cs" />
- <CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\IsJitIntrinsic.cs" />
- <CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\IsLong.cs" />
- <CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\IsPinned.cs" />
- <CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\IsSignUnspecifiedByte.cs" />
- <CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\IsUdtReturn.cs" />
<CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\jithelpers.cs" />
- <CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\ScopelessEnumAttribute.cs" />
+ <CompilerServicesSources Condition="'$(FeatureSpanOfT)' == 'true'" Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\Unsafe.cs" />
<CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\SpecialNameAttribute.cs" />
<CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\SuppressMergeCheckAttribute.cs" />
- <CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\IsCopyConstructed.cs" />
<CompilerServicesSources Condition="'$(FeatureICastable)' == 'true'" Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\ICastable.cs" />
<CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\SuppressIldasmAttribute.cs" />
- <CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\NativeCppClassAttribute.cs" />
<CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\DecoratedNameAttribute.cs" />
<CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\TypeForwardedToAttribute.cs" />
<CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\TypeForwardedFromAttribute.cs" />
@@ -62,8 +47,6 @@
<CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\INotifyCompletion.cs" />
<CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\TaskAwaiter.cs" />
<CompilerServicesSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\YieldAwaitable.cs" />
- <CompilerServicesSources Condition="'$(FeatureCominterop)' == 'true'" Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\IDispatchConstantAttribute.cs" />
- <CompilerServicesSources Condition="'$(FeatureCominterop)' == 'true'" Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\IUnknownConstantAttribute.cs" />
</ItemGroup>
<ItemGroup>
<ReliabilitySources Include="$(BclSourcesRoot)\System\Runtime\Reliability\CriticalFinalizerObject.cs" />
@@ -78,7 +61,6 @@
<ItemGroup>
<CollectionsSources Include="$(BclSourcesRoot)\System\Collections\CollectionBase.cs" />
<CollectionsSources Include="$(BclSourcesRoot)\System\Collections\ArrayList.cs" />
- <CollectionsSources Include="$(BclSourcesRoot)\System\Collections\BitArray.cs" />
<CollectionsSources Include="$(BclSourcesRoot)\System\Collections\Stack.cs" />
<CollectionsSources Include="$(BclSourcesRoot)\System\Collections\Comparer.cs" />
<CollectionsSources Include="$(BclSourcesRoot)\System\Collections\CompatibleComparer.cs" />
@@ -123,7 +105,6 @@
<InteropSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\SEHException.cs" />
<InteropSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\SafeBuffer.cs" />
<InteropSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\SafeHandle.cs" />
- <InteropSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\SafeHeapHandle.cs" />
<InteropSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\BStrWrapper.cs" />
<InteropSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\CurrencyWrapper.cs" />
<InteropSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ErrorWrapper.cs" />
@@ -135,20 +116,23 @@
<InteropSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\InvalidComObjectException.cs" />
<InteropSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\SafeArrayRankMismatchException.cs" />
<InteropSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\SafeArrayTypeMismatchException.cs" />
- <InteropSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\NativeBuffer.cs" />
- <InteropSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\StringBuffer.cs" />
<InteropSources Condition="'$(FeatureCoreClr)'=='true'" Include="$(BclSourcesRoot)\System\Runtime\InteropServices\NativeCallableAttribute.cs" />
<InteropSources Condition="'$(FeatureCominterop)' != 'true'" Include="$(BclSourcesRoot)\System\Runtime\InteropServices\NonPortable.cs" />
<InteropSources Condition="'$(FeatureCominterop)' == 'true'" Include="$(BclSourcesRoot)\System\Runtime\InteropServices\DispatchWrapper.cs" />
<InteropSources Condition="'$(FeatureCominterop)' == 'true'" Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ExtensibleClassFactory.cs" />
- <InteropSources Condition="'$(FeatureCominterop)' == 'true'" Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ICustomFactory.cs" />
+ <InteropSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ICustomFactory.cs" />
<InteropSources Condition="'$(FeatureCominterop)' == 'true'" Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ObjectCreationDelegate.cs" />
</ItemGroup>
+ <ItemGroup>
+ <InteropSources Include="$(CoreFxSourcesRoot)\System\Runtime\InteropServices\NativeBuffer.cs" />
+ <InteropSources Include="$(CoreFxSourcesRoot)\System\Runtime\InteropServices\StringBuffer.cs" />
+ <InteropSources Include="$(CoreFxSourcesRoot)\System\Runtime\InteropServices\SafeHeapHandle.cs" />
+ <InteropSources Include="$(CoreFxSourcesRoot)\System\Runtime\InteropServices\SafeHeapHandleCache.cs" />
+ </ItemGroup>
<ItemGroup Condition="'$(FeatureClassicCominterop)' == 'true'">
<InteropSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\IRegistrationServices.cs" />
<InteropSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ITypeLibConverter.cs" />
<InteropSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\RegistrationServices.cs" />
- <InteropSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\TypeLibConverter.cs" />
<InteropSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\UCOMIBindCtx.cs" />
<InteropSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\UCOMIConnectionPointContainer.cs" />
<InteropSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\UCOMIConnectionPoint.cs" />
@@ -338,8 +322,6 @@
<SystemSources Condition="'$(FeatureCoreClr)'=='true'" Include="$(BclSourcesRoot)\System\LowLevelConsole.cs" />
<SystemSources Include="$(BclSourcesRoot)\System\ContextMarshalException.cs" />
<SystemSources Include="$(BclSourcesRoot)\System\Convert.cs" />
- <SystemSources Include="$(BclSourcesRoot)\System\ContextBoundObject.cs" />
- <SystemSources Include="$(BclSourcesRoot)\System\ContextStaticAttribute.cs" />
<SystemSources Include="$(BclSourcesRoot)\System\StringFreezingAttribute.cs" />
<SystemSources Include="$(BclSourcesRoot)\System\Currency.cs" />
<SystemSources Include="$(BclSourcesRoot)\System\DayOfWeek.cs" />
@@ -389,6 +371,7 @@
<SystemSources Include="$(BclSourcesRoot)\System\_LocalDataStoreMgr.cs" />
<SystemSources Include="$(BclSourcesRoot)\System\MarshalByRefObject.cs" />
<SystemSources Include="$(BclSourcesRoot)\System\Math.cs" />
+ <SystemSources Include="$(BclSourcesRoot)\System\MathF.cs" />
<SystemSources Include="$(BclSourcesRoot)\System\mda.cs" />
<SystemSources Include="$(BclSourcesRoot)\System\MethodAccessException.cs" />
<SystemSources Include="$(BclSourcesRoot)\System\MidpointRounding.cs" />
@@ -444,7 +427,6 @@
<SystemSources Include="$(BclSourcesRoot)\System\UnitySerializationHolder.cs" />
<SystemSources Include="$(BclSourcesRoot)\System\UnhandledExceptionEventArgs.cs" />
<SystemSources Include="$(BclSourcesRoot)\System\UnhandledExceptionEventHandler.cs" />
- <SystemSources Include="$(BclSourcesRoot)\System\UnSafeCharBuffer.cs" />
<SystemSources Include="$(BclSourcesRoot)\System\ValueType.cs" />
<SystemSources Include="$(BclSourcesRoot)\System\Version.cs" />
<SystemSources Include="$(BclSourcesRoot)\System\Void.cs" />
@@ -455,9 +437,13 @@
<SystemSources Condition="'$(FeatureCominterop)' == 'true'" Include="$(BclSourcesRoot)\System\__ComObject.cs" />
<SystemSources Condition="'$(FeatureCominterop)' == 'true'" Include="$(BclSourcesRoot)\System\Variant.cs" />
<SystemSources Condition="'$(FeatureClassicCominterop)' == 'true'" Include="$(BclSourcesRoot)\System\OleAutBinder.cs" />
+ <SystemSources Condition="'$(FeatureSpanOfT)' == 'true'" Include="$(BclSourcesRoot)\System\ByReference.cs" />
+ <SystemSources Condition="'$(FeatureSpanOfT)' == 'true'" Include="$(BclSourcesRoot)\System\Span.cs" />
+ <SystemSources Condition="'$(FeatureSpanOfT)' == 'true'" Include="$(BclSourcesRoot)\System\ReadOnlySpan.cs" />
</ItemGroup>
<ItemGroup>
<InternalSources Condition="'$(FeatureCoreclr)' == 'true'" Include="$(BclSourcesRoot)\Internal\Runtime\Augments\EnvironmentAugments.cs" />
+ <InternalSources Include="$(BclSourcesRoot)\Internal\Runtime\Augments\RuntimeThread.cs" />
</ItemGroup>
<ItemGroup>
<ReflectionSources Include="$(BclSourcesRoot)\System\Reflection\__Filters.cs" />
@@ -613,7 +599,7 @@
<GlobalizationSources Include="$(BclSourcesRoot)\System\Globalization\KoreanCalendar.cs" />
<GlobalizationSources Include="$(BclSourcesRoot)\System\Globalization\RegionInfo.cs" />
<GlobalizationSources Include="$(BclSourcesRoot)\System\Globalization\SortKey.cs" />
- <GlobalizationSources Condition="'$(FeatureCoreclr)' == 'true'" Include="$(BclSourcesRoot)\System\Globalization\SortVersion.cs" />
+ <GlobalizationSources Include="$(BclSourcesRoot)\System\Globalization\SortVersion.cs" />
<GlobalizationSources Include="$(BclSourcesRoot)\System\Globalization\StringInfo.cs" />
<GlobalizationSources Include="$(BclSourcesRoot)\System\Globalization\TaiwanCalendar.cs" />
<GlobalizationSources Include="$(BclSourcesRoot)\System\Globalization\TextElementEnumerator.cs" />
@@ -631,10 +617,12 @@
<GlobalizationSources Condition="'$(FeatureOnlyCoreCalendars)'==''" Include="$(BclSourcesRoot)\System\Globalization\KoreanLunisolarCalendar.cs" />
<GlobalizationSources Condition="'$(FeatureOnlyCoreCalendars)'==''" Include="$(BclSourcesRoot)\System\Globalization\TaiwanLunisolarCalendar.cs" />
</ItemGroup>
- <ItemGroup Condition="'$(FeatureCoreFxGlobalization)' == 'true'">
+ <ItemGroup>
<GlobalizationSources Include="$(CoreFxSourcesRoot)\SR.cs" />
- <GlobalizationSources Condition="'$(FeatureCoreClr)'=='true'" Include="$(CoreFxSourcesRoot)\System\Globalization\STUBS.cs" />
+ </ItemGroup>
+ <ItemGroup Condition="'$(FeatureCoreFxGlobalization)' == 'true'">
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\Calendar.cs" />
+ <GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\CalendarAlgorithmType.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\CalendarData.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\CalendarWeekRule.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\CalendricalCalculationsHelper.cs" />
@@ -644,6 +632,7 @@
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\CompareInfo.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\CultureData.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\CultureInfo.cs" />
+ <GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\CultureTypes.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\CultureNotFoundException.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\DateTimeFormatInfo.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\DateTimeFormatInfoScanner.cs" />
@@ -654,6 +643,7 @@
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\HebrewCalendar.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\HebrewNumber.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\HijriCalendar.cs" />
+ <GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\IdnMapping.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\InternalGlobalizationHelper.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\JapaneseCalendar.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\JapaneseLunisolarCalendar.cs" />
@@ -663,6 +653,8 @@
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\NumberFormatInfo.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\PersianCalendar.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\RegionInfo.cs" />
+ <GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\SortKey.cs" />
+ <GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\SortVersion.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\StringInfo.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\TaiwanCalendar.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\TaiwanLunisolarCalendar.cs" />
@@ -676,12 +668,14 @@
<ItemGroup Condition="'$(FeatureCoreFxGlobalization)' == 'true' and '$(TargetsUnix)' == 'true'">
<GlobalizationSources Include="$(BclSourcesRoot)\System\Globalization\EncodingTable.Unix.cs" />
<GlobalizationSources Include="$(BclSourcesRoot)\System\Globalization\EncodingDataItem.Unix.cs" />
+ <GlobalizationSources Include="$(BclSourcesRoot)\System\Text\Normalization.Unix.cs" />
- <GlobalizationSources Include="$(CoreFxSourcesRoot)\Interop\Unix\Interop.Libraries.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.Calendar.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.Casing.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.Collation.cs" />
+ <GlobalizationSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.Idna.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.Locale.cs" />
+ <GlobalizationSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.Normalization.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.ResultCode.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.TimeZoneInfo.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.Utils.cs" />
@@ -689,8 +683,11 @@
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\CompareInfo.Unix.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\CultureData.Unix.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\CultureInfo.Unix.cs" />
+ <GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\DigitShapes.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\HijriCalendar.Unix.cs" />
+ <GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\IdnMapping.Unix.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\JapaneseCalendar.Unix.cs" />
+ <GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\LocaleData.Unix.cs" />
<GlobalizationSources Include="$(CoreFxSourcesRoot)\System\Globalization\TextInfo.Unix.cs" />
</ItemGroup>
<ItemGroup>
@@ -712,7 +709,7 @@
<ThreadingSources Include="$(BclSourcesRoot)\System\Threading\Overlapped.cs" />
<ThreadingSources Include="$(BclSourcesRoot)\System\Threading\ParameterizedThreadStart.cs" />
<ThreadingSources Include="$(BclSourcesRoot)\System\Threading\ReaderWriterLock.cs" />
- <ThreadingSources Condition="'$(FeatureCoreClr)'=='true'" Include="$(BclSourcesRoot)\System\Threading\Semaphore.cs" />
+ <ThreadingSources Include="$(BclSourcesRoot)\System\Threading\Semaphore.cs" />
<ThreadingSources Include="$(BclSourcesRoot)\System\Threading\SemaphoreFullException.cs" />
<ThreadingSources Include="$(BclSourcesRoot)\System\Threading\SynchronizationLockException.cs" />
<ThreadingSources Include="$(BclSourcesRoot)\System\Threading\Thread.cs" />
@@ -729,7 +726,6 @@
<ThreadingSources Include="$(BclSourcesRoot)\System\Threading\Timer.cs" />
<ThreadingSources Include="$(BclSourcesRoot)\System\Threading\Volatile.cs" />
<ThreadingSources Include="$(BclSourcesRoot)\System\Threading\WaitHandle.cs" />
- <ThreadingSources Include="$(BclSourcesRoot)\System\Threading\WaitHandleExtensions.cs" />
<ThreadingSources Include="$(BclSourcesRoot)\System\Threading\WaitHandleCannotBeOpenedException.cs" />
<ThreadingSources Include="$(BclSourcesRoot)\System\Threading\ApartmentState.cs" />
<ThreadingSources Include="$(BclSourcesRoot)\System\Threading\SpinLock.cs" />
@@ -765,18 +761,53 @@
<ThreadingSources Condition="'$(FeatureCominterop)' == 'true'" Include="$(BclSourcesRoot)\System\Threading\Tasks\IAsyncCausalityTracerStatics.cs" />
</ItemGroup>
<ItemGroup>
- <IoSources Include="$(BclSourcesRoot)\System\IO\__DebugOutputTextWriter.cs" />
+ <FileStreamSources Include="$(CoreFxSourcesRoot)\System\IO\FileStream.cs" />
+ <FileStreamSources Include="$(CoreFxSourcesRoot)\System\IO\FileStream.NetStandard17.cs" />
+ <FileStreamSources Include="$(CoreFxSourcesRoot)\System\IO\Error.cs" />
+ </ItemGroup>
+ <ItemGroup Condition="'$(TargetsUnix)' == 'true'">
+ <SafehandleSources Include="$(CoreFxSourcesRoot)\Microsoft\Win32\SafeHandles\SafeFileHandle.Unix.cs" />
+ <FileStreamSources Include="$(CoreFxSourcesRoot)\System\IO\FileStream.Unix.cs" />
+ </ItemGroup>
+ <ItemGroup Condition="'$(TargetsUnix)' != 'true'">
+ <SafehandleSources Include="$(CoreFxSourcesRoot)\Microsoft\Win32\SafeHandles\SafeFileHandle.Windows.cs" />
+ <FileStreamSources Include="$(CoreFxSourcesRoot)\System\IO\FileStream.Win32.cs" />
+ <FileStreamSources Include="$(CoreFxSourcesRoot)\System\IO\FileStreamCompletionSource.Win32.cs" />
+ <FileStreamSources Include="$(CoreFxSourcesRoot)\System\IO\Win32Marshal.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <IoSources Include="$(CoreFxSourcesRoot)\System\IO\Path.cs" />
+ <IoSources Include="$(CoreFxSourcesRoot)\System\IO\PathInternal.cs" />
+ <IoSources Include="$(CoreFxSourcesRoot)\System\IO\PathInternal.CaseSensitivity.cs" />
+ </ItemGroup>
+ <ItemGroup Condition="'$(TargetsUnix)' == 'true'">
+ <IoSources Include="$(CoreFxSourcesRoot)\System\IO\Path.Unix.cs" />
+ <IoSources Include="$(CoreFxSourcesRoot)\System\IO\PathInternal.Unix.cs" />
+ </ItemGroup>
+ <ItemGroup Condition="'$(TargetsUnix)' != 'true'">
+ <IoSources Include="$(CoreFxSourcesRoot)\System\IO\Path.Win32.cs" />
+ <IoSources Include="$(CoreFxSourcesRoot)\System\IO\Path.Windows.cs" />
+ <IoSources Include="$(CoreFxSourcesRoot)\System\IO\PathHelper.Windows.cs" />
+ <IoSources Include="$(CoreFxSourcesRoot)\System\IO\PathInternal.Windows.cs" />
+ <IoSources Include="$(CoreFxSourcesRoot)\System\IO\PathInternal.Windows.StringBuffer.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ThreadingSources Include="$(CoreFxSourcesRoot)\System\Threading\DeferredDisposableLifetime.cs" />
+ <ThreadingSources Include="$(CoreFxSourcesRoot)\System\Threading\ClrThreadPoolBoundHandle.cs" />
+ <ThreadingSources Include="$(CoreFxSourcesRoot)\System\Threading\ClrThreadPoolBoundHandleOverlapped.cs" />
+ <ThreadingSources Include="$(CoreFxSourcesRoot)\System\Threading\ClrThreadPoolPreAllocatedOverlapped.cs" />
+ </ItemGroup>
+ <ItemGroup>
<IoSources Include="$(BclSourcesRoot)\System\IO\__Error.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\__HResults.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\BinaryReader.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\BinaryWriter.cs" />
- <IoSources Include="$(BclSourcesRoot)\System\IO\BufferedStream.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\Directory.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\DirectoryInfo.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\SearchOption.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\DirectoryNotFoundException.cs" />
- <IoSources Include="$(BclSourcesRoot)\System\IO\DriveInfo.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\DriveNotFoundException.cs" />
+ <IoSources Include="$(BclSourcesRoot)\System\IO\EncodingCache.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\EndOfStreamException.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\File.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\FileAccess.cs" />
@@ -786,32 +817,24 @@
<IoSources Include="$(BclSourcesRoot)\System\IO\FileNotFoundException.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\FileOptions.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\FileShare.cs" />
- <IoSources Include="$(BclSourcesRoot)\System\IO\FileStream.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\FileSystemEnumerable.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\FileSystemInfo.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\FileAttributes.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\IOException.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\MemoryStream.cs" />
- <IoSources Include="$(BclSourcesRoot)\System\IO\Path.cs" />
- <IoSources Include="$(BclSourcesRoot)\System\IO\PathHelper.cs" />
- <IoSources Condition="'$(TargetsUnix)' != 'true'" Include="$(BclSourcesRoot)\System\IO\LongPathHelper.cs" />
- <IoSources Include="$(BclSourcesRoot)\System\IO\PathInternal.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\PathTooLongException.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\PinnedBufferMemoryStream.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\ReadLinesIterator.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\SeekOrigin.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\Stream.cs" />
+ <IoSources Include="$(BclSourcesRoot)\System\IO\StreamHelpers.CopyValidation.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\StreamReader.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\StreamWriter.cs" />
- <IoSources Include="$(BclSourcesRoot)\System\IO\StringReader.cs" />
- <IoSources Include="$(BclSourcesRoot)\System\IO\StringWriter.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\TextReader.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\TextWriter.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\UnmanagedMemoryAccessor.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\UnmanagedMemoryStream.cs" />
<IoSources Include="$(BclSourcesRoot)\System\IO\UnmanagedMemoryStreamWrapper.cs" />
- <IoSources Condition="'$(FeatureCoreclr)' == 'true'" Include="$(BclSourcesRoot)\System\IO\FileSecurityState.cs" />
- <IoSources Condition="'$(FeatureCoreclr)' == 'true'" Include="$(BclSourcesRoot)\System\IO\FileSecurityStateAccess.cs" />
</ItemGroup>
<ItemGroup>
<SecuritySources Include="$(BclSourcesRoot)\System\Security\Attributes.cs" />
@@ -842,6 +865,7 @@
<SecuritySources Include="$(BclSourcesRoot)\System\Security\VerificationException.cs" />
<SecuritySources Condition="'$(FeatureLegacySurface)' == 'true'" Include="$(BclSourcesRoot)\System\Security\securestring.cs" />
</ItemGroup>
+
<ItemGroup>
<SecUtilSources Include="$(BclSourcesRoot)\System\Security\Util\Config.cs" />
<SecUtilSources Include="$(BclSourcesRoot)\System\Security\Util\Hex.cs" />
@@ -932,6 +956,7 @@
<ItemGroup>
<ExceptionservicesSources Condition="'$(FeatureCorruptingExceptions)' == 'true'" Include="$(BclSourcesRoot)\System\Runtime\ExceptionServices\CorruptingExceptionCommon.cs" />
<ExceptionservicesSources Condition="'$(FeatureExceptionDispatchInfo)' == 'true'" Include="$(BclSourcesRoot)\System\Runtime\ExceptionServices\ExceptionServicesCommon.cs" />
+ <ExceptionservicesSources Condition="'$(FeatureExceptionNotifications)' == 'true'" Include="$(BclSourcesRoot)\System\Runtime\ExceptionServices\ExceptionNotification.cs" />
</ItemGroup>
<ItemGroup>
<HostingSources Condition="'$(FeatureHostAssemblyResolver)' == 'true'" Include="$(BclSourcesRoot)\System\Runtime\Loader\AssemblyLoadContext.cs" />
@@ -954,11 +979,9 @@
<SerializationSources Include="$(BclSourcesRoot)\System\Runtime\Serialization\SerializationInfo.cs" />
<SerializationSources Include="$(BclSourcesRoot)\System\Runtime\Serialization\SerializationInfoEnumerator.cs" />
<SerializationSources Include="$(BclSourcesRoot)\System\Runtime\Serialization\StreamingContext.cs" />
+ <SerializationSources Include="$(BclSourcesRoot)\System\Runtime\Serialization\SafeSerializationManager.cs" />
</ItemGroup>
<ItemGroup>
- <VersioningSources Include="$(BclSourcesRoot)\System\Runtime\Versioning\BinaryCompatibility.cs" />
- <VersioningSources Include="$(BclSourcesRoot)\System\Runtime\Versioning\ComponentGuaranteesAttribute.cs" />
- <VersioningSources Include="$(BclSourcesRoot)\System\Runtime\Versioning\ResourceAttributes.cs" />
<VersioningSources Include="$(BclSourcesRoot)\System\Runtime\Versioning\TargetFrameworkAttribute.cs" />
<VersioningSources Include="$(BclSourcesRoot)\System\Runtime\Versioning\TargetFrameworkId.cs" />
<VersioningSources Include="$(BclSourcesRoot)\System\Runtime\Versioning\CompatibilitySwitch.cs" />
@@ -999,6 +1022,7 @@
<TextSources Include="$(BclSourcesRoot)\System\Text\Latin1Encoding.cs" />
<TextSources Include="$(BclSourcesRoot)\System\Text\MLangCodePageEncoding.cs" />
<TextSources Include="$(BclSourcesRoot)\System\Text\Normalization.cs" />
+ <TextSources Include="$(BclSourcesRoot)\System\Text\Normalization.Windows.cs" Condition="'$(TargetsUnix)' != 'true'"/>
<TextSources Include="$(BclSourcesRoot)\System\Text\DBCSCodePageEncoding.cs" />
<TextSources Include="$(BclSourcesRoot)\System\Text\SBCSCodePageEncoding.cs" />
<TextSources Include="$(BclSourcesRoot)\System\Text\SurrogateEncoder.cs" />
@@ -1130,7 +1154,6 @@
<GenericsSources Include="$(BclSourcesRoot)\System\Collections\Concurrent\PartitionerStatic.cs" />
</ItemGroup>
<ItemGroup>
- <SafehandleSources Include="$(BclSourcesRoot)\Microsoft\Win32\SafeHandles\SafeFileHandle.cs" />
<SafehandleSources Include="$(BclSourcesRoot)\Microsoft\Win32\SafeHandles\SafeFileMappingHandle.cs" />
<SafehandleSources Include="$(BclSourcesRoot)\Microsoft\Win32\SafeHandles\SafeFindHandle.cs" />
<SafehandleSources Include="$(BclSourcesRoot)\Microsoft\Win32\SafeHandles\SafeLocalAllocHandle.cs" />
@@ -1141,6 +1164,100 @@
<SafehandleSources Condition="'$(FeatureWin32Registry)' == 'true'" Include="$(BclSourcesRoot)\Microsoft\Win32\SafeHandles\SafeRegistryHandle.cs" />
</ItemGroup>
<ItemGroup>
+ <NumericsSources Include="$(BclSourcesRoot)\System\Numerics\Hashing\HashHelpers.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <BuffersSources Include="$(CoreFxSourcesRoot)\System\Buffers\ArrayPool.cs" />
+ <BuffersSources Include="$(CoreFxSourcesRoot)\System\Buffers\ArrayPoolEventSource.cs" />
+ <BuffersSources Include="$(CoreFxSourcesRoot)\System\Buffers\ConfigurableArrayPool.cs" />
+ <BuffersSources Include="$(CoreFxSourcesRoot)\System\Buffers\TlsOverPerCoreLockedStacksArrayPool.cs" />
+ <BuffersSources Include="$(CoreFxSourcesRoot)\System\Buffers\TlsOverPerCoreLockedStacksArrayPool.Windows.cs" Condition="'$(TargetsUnix)' != 'true'" />
+ <BuffersSources Include="$(CoreFxSourcesRoot)\System\Buffers\TlsOverPerCoreLockedStacksArrayPool.Unix.cs" Condition="'$(TargetsUnix)' == 'true'" />
+ <BuffersSources Include="$(CoreFxSourcesRoot)\System\Buffers\Utilities.cs" />
+ <SecuritySources Include="$(CoreFxSourcesRoot)\System\Security\CryptographicException.cs" />
+ </ItemGroup>
+ <ItemGroup Condition="'$(TargetsUnix)' != 'true'">
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\System\HResults.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\Interop.BOOL.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\Interop.Libraries.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\BCrypt\Interop.BCryptGenRandom.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\BCrypt\Interop.NTSTATUS.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.CancelIoEx.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.CloseHandle.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.CreateFile.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.Errors.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.FileTypes.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.FileOperations.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.FlushFileBuffers.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.FormatMessage.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.GetFileInformationByHandleEx.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.GetFileType_SafeHandle.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.GetFullPathNameW.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.GetLongPathNameW.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.GetTempFileNameW.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.GetTempPathW.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.LockFile.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.ReadFile_SafeHandle_IntPtr.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.ReadFile_SafeHandle_NativeOverlapped.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.SafeCreateFile.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.SECURITY_ATTRIBUTES.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.SecurityOptions.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.SetEndOfFile.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.SetErrorMode.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.SetFileInformationByHandle.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.SetFilePointerEx.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.UnsafeCreateFile.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.WriteFile_SafeHandle_IntPtr.cs" />
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.WriteFile_SafeHandle_NativeOverlapped.cs" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <SecuritySources Include="$(CoreFxSourcesRoot)\System\Security\SecureString.cs" />
+ </ItemGroup>
+
+ <ItemGroup Condition="'$(TargetsUnix)' != 'true'">
+ <SecuritySources Include="$(CoreFxSourcesRoot)\System\Security\SafeBSTRHandle.cs" />
+ <SecuritySources Include="$(CoreFxSourcesRoot)\System\Security\SecureString.Windows.cs" />
+ <!-- Interop sources -->
+ <SecuritySources Include="$(CoreFxSourcesRoot)\Interop\Windows\Crypt32\Interop.CryptProtectMemory.cs" />
+ <SecuritySources Include="$(CoreFxSourcesRoot)\Interop\Windows\NtDll\Interop.ZeroMemory.cs" />
+ <SecuritySources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.WideCharToMultiByte.cs" />
+ <SecuritySources Include="$(CoreFxSourcesRoot)\Interop\Windows\oleaut32\Interop.SysAllocStringLen.cs" />
+ <SecuritySources Include="$(CoreFxSourcesRoot)\Interop\Windows\oleaut32\Interop.SysStringLen.cs" />
+ </ItemGroup>
+
+ <ItemGroup Condition="'$(TargetsUnix)' == 'true'">
+ <SecuritySources Include="$(CoreFxSourcesRoot)\System\Security\SecureString.Unix.cs" />
+ </ItemGroup>
+
+ <ItemGroup Condition="'$(TargetsUnix)' == 'true'">
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\System\HResults.cs" />
+ <UnixInteropSources Include="$(CoreFxSourcesRoot)\Interop\Unix\Interop.Errors.cs" />
+ <UnixInteropSources Include="$(CoreFxSourcesRoot)\Interop\Unix\Interop.IOErrors.cs" />
+ <UnixInteropSources Include="$(CoreFxSourcesRoot)\Interop\Unix\Interop.Libraries.cs" />
+ <UnixInteropSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.Close.cs" />
+ <UnixInteropSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.GetCwd.cs" />
+ <UnixInteropSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.GetUnixName.cs" />
+ <UnixInteropSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.Fcntl.cs" />
+ <UnixInteropSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.FLock.cs" />
+ <UnixInteropSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.FSync.cs" />
+ <UnixInteropSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.FTruncate.cs" />
+ <UnixInteropSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.LSeek.cs" />
+ <UnixInteropSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.MksTemps.cs" />
+ <UnixInteropSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.Open.cs" />
+ <UnixInteropSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.OpenFlags.cs" />
+ <UnixInteropSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.PathConf.cs" />
+ <UnixInteropSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.Permissions.cs" />
+ <UnixInteropSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.PosixFAdvise.cs" />
+ <UnixInteropSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.Read.cs" />
+ <UnixInteropSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.Stat.cs" />
+ <UnixInteropSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.Unlink.cs" />
+ <UnixInteropSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.Write.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Debug.cs" />
+ </ItemGroup>
+ <ItemGroup>
<MscorlibSources Include="@(SystemSources)"/>
<MscorlibSources Include="@(ThreadingSources)"/>
<MscorlibSources Include="@(DeploymentSources)"/>
@@ -1170,6 +1287,7 @@
<MscorlibSources Include="@(WinRTTSources)"/>
<MscorlibSources Include="@(WinRTCollectionSources)"/>
<MscorlibSources Include="@(IoSources)"/>
+ <MscorlibSources Include="@(FileStreamSources)"/>
<MscorlibSources Include="@(CompilerServicesSources)"/>
<MscorlibSources Include="@(RuntimeSources)"/>
<MscorlibSources Include="@(XmlSources)"/>
@@ -1190,6 +1308,10 @@
<MscorlibSources Include="@(VersioningSources)"/>
<MscorlibSources Include="@(DesignerServicesSources)"/>
<MscorlibSources Include="@(InternalSources)"/>
+ <MscorlibSources Include="@(NumericsSources)"/>
<MscorlibSources Include="$(BclSourcesRoot)\GlobalSuppressions.cs"/>
+ <MscorlibSources Include="@(BuffersSources)"/>
+ <MscorlibSources Include="@(WindowsInteropSources)"/>
+ <MscorlibSources Include="@(UnixInteropSources)"/>
</ItemGroup>
</Project>
diff --git a/src/mscorlib/ref/mscorlib.cs b/src/mscorlib/ref/mscorlib.cs
index e5211ff4a8..da378777c9 100644
--- a/src/mscorlib/ref/mscorlib.cs
+++ b/src/mscorlib/ref/mscorlib.cs
@@ -15,10 +15,56 @@ namespace Internal.Runtime.Augments
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) { }
@@ -126,8 +172,13 @@ namespace System
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.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
@@ -560,7 +611,11 @@ namespace System
[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]
@@ -782,29 +837,9 @@ namespace System
public static partial class Console
{
[System.Security.SecuritySafeCriticalAttribute]
- public static void Write(string s) { }
+ public static void Write(string value) { }
public static void WriteLine() { }
- public static void WriteLine(string s) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class ContextBoundObject
- {
- protected ContextBoundObject() { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class ContextMarshalException : System.SystemException
- {
- public ContextMarshalException() { }
- public ContextMarshalException(string message) { }
- public ContextMarshalException(string message, System.Exception inner) { }
- protected ContextMarshalException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(256), Inherited=false)]
- [System.ObsoleteAttribute("ContextStaticAttribute is not supported in this release. It has been left in so that legacy tools can be used with this release, but it cannot be used in your code.", true)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class ContextStaticAttribute : System.Attribute
- {
- public ContextStaticAttribute() { }
+ public static void WriteLine(string value) { }
}
public static partial class Convert
{
@@ -1961,6 +1996,7 @@ namespace System
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) { }
@@ -2473,6 +2509,10 @@ namespace System
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
{
@@ -2500,6 +2540,21 @@ namespace System
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]
@@ -2579,6 +2634,58 @@ namespace System
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
{
@@ -3181,6 +3288,7 @@ namespace System
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; }
@@ -3253,6 +3361,10 @@ namespace System
[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)]
@@ -3260,6 +3372,10 @@ namespace System
[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; }
@@ -4228,32 +4344,6 @@ namespace System
namespace System.Collections
{
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class BitArray : System.Collections.ICollection, System.Collections.IEnumerable, System.ICloneable
- {
- public BitArray(bool[] values) { }
- public BitArray(byte[] bytes) { }
- public BitArray(System.Collections.BitArray bits) { }
- public BitArray(int length) { }
- public BitArray(int length, bool defaultValue) { }
- public BitArray(int[] values) { }
- public int Count { get { throw null; } }
- public bool IsReadOnly { get { throw null; } }
- public bool IsSynchronized { get { throw null; } }
- public bool this[int index] { get { throw null; } set { } }
- public int Length { get { throw null; } set { } }
- public object SyncRoot { get { throw null; } }
- public System.Collections.BitArray And(System.Collections.BitArray value) { throw null; }
- public object Clone() { throw null; }
- public void CopyTo(System.Array array, int index) { }
- public bool Get(int index) { throw null; }
- public System.Collections.IEnumerator GetEnumerator() { throw null; }
- public System.Collections.BitArray Not() { throw null; }
- public System.Collections.BitArray Or(System.Collections.BitArray value) { throw null; }
- public void Set(int index, bool value) { }
- public void SetAll(bool value) { }
- public System.Collections.BitArray Xor(System.Collections.BitArray value) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
public abstract partial class CollectionBase : System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList
{
protected CollectionBase() { }
@@ -4383,6 +4473,8 @@ namespace System.Collections.Generic
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) { }
@@ -4878,6 +4970,7 @@ namespace System.Diagnostics
[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; } }
@@ -5682,6 +5775,7 @@ namespace System.Globalization
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)]
@@ -5706,6 +5800,7 @@ namespace System.Globalization
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 { } }
@@ -5713,10 +5808,12 @@ namespace System.Globalization
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; } }
@@ -5732,6 +5829,7 @@ namespace System.Globalization
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; }
@@ -6604,9 +6702,19 @@ namespace System.IO
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
{
@@ -6617,9 +6725,72 @@ namespace System.IO
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
{
@@ -6736,6 +6907,8 @@ namespace System.IO
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; }
@@ -6745,6 +6918,8 @@ namespace System.IO
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; }
@@ -6753,6 +6928,7 @@ namespace System.IO
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; }
@@ -6910,6 +7086,7 @@ namespace System.IO
[System.Diagnostics.DebuggerStepThroughAttribute]
[System.Runtime.InteropServices.ComVisibleAttribute(false)]
public virtual System.Threading.Tasks.Task<string> ReadToEndAsync() { throw null; }
+ public static System.IO.TextReader Synchronized(System.IO.TextReader reader) { throw null; }
}
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public abstract partial class TextWriter : System.IDisposable
@@ -6927,6 +7104,7 @@ namespace System.IO
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) { }
@@ -7001,6 +7179,10 @@ namespace System.IO
[System.Security.SecuritySafeCriticalAttribute]
[System.Security.Permissions.SecurityPermissionAttribute(System.Security.Permissions.SecurityAction.Demand, Flags=(System.Security.Permissions.SecurityPermissionFlag)(2))]
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]
@@ -7057,6 +7239,10 @@ namespace System.IO
[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
{
@@ -7125,11 +7311,15 @@ namespace System.Reflection
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; } }
@@ -7137,6 +7327,7 @@ namespace System.Reflection
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; }
@@ -7155,6 +7346,9 @@ namespace System.Reflection
[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; }
@@ -7187,6 +7381,13 @@ namespace System.Reflection
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)]
@@ -7194,6 +7395,7 @@ namespace System.Reflection
[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)]
@@ -7319,14 +7521,18 @@ namespace System.Reflection
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; }
@@ -7336,6 +7542,8 @@ namespace System.Reflection
[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)]
@@ -7723,7 +7931,7 @@ namespace System.Reflection
public static System.Reflection.TypeInfo GetTypeInfo(this System.Type type) { throw null; }
}
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class InvalidFilterCriteriaException : System.Exception
+ public partial class InvalidFilterCriteriaException : System.ApplicationException
{
public InvalidFilterCriteriaException() { }
public InvalidFilterCriteriaException(string message) { }
@@ -7858,6 +8066,8 @@ namespace System.Reflection
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; }
@@ -8217,7 +8427,7 @@ namespace System.Reflection
public static System.Reflection.PropertyInfo GetRuntimeProperty(this System.Type type, string name) { throw null; }
}
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class TargetException : System.Exception
+ public partial class TargetException : System.ApplicationException
{
public TargetException() { }
public TargetException(string message) { }
@@ -8225,13 +8435,13 @@ namespace System.Reflection
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.Exception
+ 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.Exception
+ public sealed partial class TargetParameterCountException : System.ApplicationException
{
public TargetParameterCountException() { }
public TargetParameterCountException(string message) { }
@@ -8354,6 +8564,16 @@ namespace System.Reflection
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
{
@@ -8644,6 +8864,8 @@ namespace System.Reflection.Emit
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,
}
@@ -9206,6 +9428,8 @@ namespace System.Reflection.Emit
[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,
@@ -9221,6 +9445,8 @@ namespace System.Reflection.Emit
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,
@@ -9591,15 +9817,26 @@ 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) { }
- protected MissingManifestResourceException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
+ }
+ [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)]
@@ -9622,8 +9859,10 @@ namespace System.Resources
[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; }
@@ -9643,18 +9882,33 @@ namespace System.Resources
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; }
@@ -9699,6 +9953,15 @@ namespace System.Runtime
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
{
@@ -9757,26 +10020,6 @@ namespace System.Runtime.CompilerServices
[System.Security.SecuritySafeCriticalAttribute]
public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine { }
}
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class CallConvCdecl
- {
- internal CallConvCdecl() { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class CallConvFastcall
- {
- internal CallConvFastcall() { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class CallConvStdcall
- {
- internal CallConvStdcall() { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class CallConvThiscall
- {
- internal CallConvThiscall() { }
- }
[System.AttributeUsageAttribute((System.AttributeTargets)(2048), Inherited=false)]
public sealed partial class CallerFilePathAttribute : System.Attribute
{
@@ -9811,6 +10054,12 @@ namespace System.Runtime.CompilerServices
{
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
{
}
@@ -9892,11 +10141,29 @@ namespace System.Runtime.CompilerServices
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
{
@@ -9950,39 +10217,8 @@ namespace System.Runtime.CompilerServices
public bool AllInternalsVisible { get { throw null; } set { } }
public string AssemblyName { get { throw null; } }
}
- public static partial class IsBoxed
- {
- }
- public static partial class IsByValue
- {
- }
- public static partial class IsConst
- {
- }
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static partial class IsCopyConstructed
- {
- }
- public static partial class IsExplicitlyDereferenced
- {
- }
- public static partial class IsImplicitlyDereferenced
- {
- }
- public static partial class IsJitIntrinsic
- {
- }
- public static partial class IsLong
- {
- }
- public static partial class IsSignUnspecifiedByte
- {
- }
- public static partial class IsUdtReturn
- {
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static partial class IsVolatile
+ public static partial class IsVolatile
{
}
[System.AttributeUsageAttribute((System.AttributeTargets)(64), Inherited=false, AllowMultiple=false)]
@@ -9990,6 +10226,11 @@ namespace System.Runtime.CompilerServices
{
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
{
@@ -10022,12 +10263,6 @@ namespace System.Runtime.CompilerServices
Synchronized = 32,
Unmanaged = 4,
}
- [System.AttributeUsageAttribute((System.AttributeTargets)(8), Inherited=true)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class NativeCppClassAttribute : System.Attribute
- {
- public NativeCppClassAttribute() { }
- }
[System.AttributeUsageAttribute((System.AttributeTargets)(1), AllowMultiple=false)]
public sealed partial class ReferenceAssemblyAttribute : System.Attribute
{
@@ -10035,13 +10270,6 @@ namespace System.Runtime.CompilerServices
public ReferenceAssemblyAttribute(string description) { }
public string Description { get { throw null; } }
}
- [System.AttributeUsageAttribute((System.AttributeTargets)(1052), AllowMultiple=true, Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class RequiredAttributeAttribute : System.Attribute
- {
- public RequiredAttributeAttribute(System.Type requiredContract) { }
- public System.Type RequiredContract { get { throw null; } }
- }
[System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited=false, AllowMultiple=false)]
public sealed partial class RuntimeCompatibilityAttribute : System.Attribute
{
@@ -10050,6 +10278,7 @@ namespace System.Runtime.CompilerServices
}
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() { }
@@ -10061,12 +10290,48 @@ namespace System.Runtime.CompilerServices
[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
{
@@ -10140,6 +10405,27 @@ namespace System.Runtime.ConstrainedExecution
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
{
@@ -10155,6 +10441,11 @@ namespace System.Runtime.ExceptionServices
{
public HandleProcessCorruptedStateExceptionsAttribute() { }
}
+ public sealed partial class FirstChanceExceptionEventArgs : EventArgs
+ {
+ public FirstChanceExceptionEventArgs(Exception exception) { }
+ public Exception Exception { get { throw null; } }
+ }
}
namespace System.Runtime.InteropServices
{
@@ -10163,6 +10454,13 @@ namespace System.Runtime.InteropServices
{
public AllowReversePInvokeCallsAttribute() { }
}
+ [System.AttributeUsageAttribute((System.AttributeTargets)(1029), Inherited=false)]
+ [System.Runtime.InteropServices.ComVisibleAttribute(true)]
+ public sealed partial class AutomationProxyAttribute : System.Attribute
+ {
+ public AutomationProxyAttribute(bool val) { }
+ public bool Value { get { throw null; } }
+ }
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public partial struct ArrayWithOffset
@@ -10235,6 +10533,29 @@ namespace System.Runtime.InteropServices
public CoClassAttribute(System.Type coClass) { }
public System.Type CoClass { get { throw null; } }
}
+ [System.AttributeUsageAttribute((System.AttributeTargets)(10624), Inherited=false)]
+ [System.Runtime.InteropServices.ComVisibleAttribute(true)]
+ public sealed partial class ComAliasNameAttribute : System.Attribute
+ {
+ public ComAliasNameAttribute(String val) { }
+ public String Value { get { throw null; } }
+ }
+ [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited=false)]
+ [System.Runtime.InteropServices.ComVisibleAttribute(true)]
+ public sealed partial class ComCompatibleVersionAttribute : System.Attribute
+ {
+ public ComCompatibleVersionAttribute(System.Int32 major, System.Int32 minor, System.Int32 build, System.Int32 revision) { }
+ public System.Int32 MajorVersion { get { throw null; } }
+ public System.Int32 MinorVersion { get { throw null; } }
+ public System.Int32 BuildNumber { get { throw null;} }
+ public System.Int32 RevisionNumber { get { throw null; } }
+ }
+ [System.AttributeUsageAttribute((System.AttributeTargets)(32767), Inherited=false)]
+ [System.Runtime.InteropServices.ComVisibleAttribute(true)]
+ public sealed partial class ComConversionLossAttribute : Attribute
+ {
+ public ComConversionLossAttribute() { }
+ }
[System.AttributeUsageAttribute((System.AttributeTargets)(4), Inherited=false)]
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public sealed partial class ComDefaultInterfaceAttribute : System.Attribute
@@ -10289,6 +10610,12 @@ namespace System.Runtime.InteropServices
PropGet = 1,
PropSet = 2,
}
+ [System.AttributeUsageAttribute((System.AttributeTargets)(64), Inherited=false)]
+ [System.Runtime.InteropServices.ComVisibleAttribute(true)]
+ public sealed partial class ComRegisterFunctionAttribute : Attribute
+ {
+ public ComRegisterFunctionAttribute() { }
+ }
[System.AttributeUsageAttribute((System.AttributeTargets)(4), Inherited=true)]
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public sealed partial class ComSourceInterfacesAttribute : System.Attribute
@@ -10300,6 +10627,12 @@ namespace System.Runtime.InteropServices
public ComSourceInterfacesAttribute(System.Type sourceInterface1, System.Type sourceInterface2, System.Type sourceInterface3, System.Type sourceInterface4) { }
public string Value { get { throw null; } }
}
+ [System.AttributeUsageAttribute((System.AttributeTargets)(64), Inherited=false)]
+ [System.Runtime.InteropServices.ComVisibleAttribute(true)]
+ public sealed partial class ComUnregisterFunctionAttribute : Attribute
+ {
+ public ComUnregisterFunctionAttribute() { }
+ }
[System.AttributeUsageAttribute((System.AttributeTargets)(5597), Inherited=false)]
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public sealed partial class ComVisibleAttribute : System.Attribute
@@ -10418,6 +10751,7 @@ namespace System.Runtime.InteropServices
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)]
@@ -10466,17 +10800,48 @@ namespace System.Runtime.InteropServices
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)(1), Inherited=false)]
+ [System.Runtime.InteropServices.ComVisibleAttribute(true)]
+ public sealed partial class ImportedFromTypeLibAttribute : System.Attribute
+ {
+ public ImportedFromTypeLibAttribute(String val) { }
+ public String Value { get { throw null; } }
+ }
[System.AttributeUsageAttribute((System.AttributeTargets)(2048), Inherited=false)]
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public sealed partial class InAttribute : System.Attribute
@@ -10514,6 +10879,13 @@ namespace System.Runtime.InteropServices
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
{
@@ -10530,6 +10902,12 @@ namespace System.Runtime.InteropServices
[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) { }
@@ -10583,11 +10961,17 @@ namespace System.Runtime.InteropServices
[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]
@@ -10602,10 +10986,14 @@ namespace System.Runtime.InteropServices
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]
@@ -10626,6 +11014,8 @@ namespace System.Runtime.InteropServices
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; }
@@ -10643,6 +11033,10 @@ namespace System.Runtime.InteropServices
[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; }
@@ -10702,6 +11096,8 @@ namespace System.Runtime.InteropServices
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; }
@@ -10711,12 +11107,16 @@ namespace System.Runtime.InteropServices
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)]
@@ -10781,6 +11181,14 @@ namespace System.Runtime.InteropServices
[System.Security.SecurityCriticalAttribute]
public static void ZeroFreeGlobalAllocUnicode(System.IntPtr s) { }
}
+ [System.AttributeUsageAttribute((System.AttributeTargets)(64), Inherited=false)]
+ [System.Runtime.InteropServices.ComVisibleAttribute(true)]
+ public sealed partial class ManagedToNativeComInteropStubAttribute : System.Attribute
+ {
+ public ManagedToNativeComInteropStubAttribute(System.Type classType, System.String methodName) { }
+ public System.Type ClassType { get { throw null; } }
+ public System.String MethodName { get { throw null; } }
+ }
[System.AttributeUsageAttribute((System.AttributeTargets)(10496), Inherited=false)]
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public sealed partial class MarshalAsAttribute : System.Attribute
@@ -10833,12 +11241,21 @@ namespace System.Runtime.InteropServices
{
public PreserveSigAttribute() { }
}
+ [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited=false, AllowMultiple = true)]
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static partial class RuntimeEnvironment
+ public sealed partial class PrimaryInteropAssemblyAttribute : System.Attribute
{
- [System.Security.SecuritySafeCriticalAttribute]
- public static string GetRuntimeDirectory() { throw null; }
+ public PrimaryInteropAssemblyAttribute(System.Int32 major, System.Int32 minor) { }
+ public System.Int32 MajorVersion { get { throw null; } }
+ public System.Int32 MinorVersion { get { throw null; } }
}
+ [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
{
@@ -10933,6 +11350,21 @@ namespace System.Runtime.InteropServices
public string Identifier { get { throw null; } }
public string Scope { get { throw null; } }
}
+ [System.AttributeUsageAttribute((System.AttributeTargets)(1024), Inherited=false)]
+ [System.Runtime.InteropServices.ComVisibleAttribute(true)]
+ public sealed partial class TypeLibImportClassAttribute : System.Attribute
+ {
+ public TypeLibImportClassAttribute(System.Type val) { }
+ public String Value { get { throw null; } }
+ }
+ [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited=false)]
+ [System.Runtime.InteropServices.ComVisibleAttribute(true)]
+ public sealed partial class TypeLibVersionAttribute : System.Attribute
+ {
+ public TypeLibVersionAttribute(System.Int32 major, System.Int32 minor) { }
+ public System.Int32 MajorVersion { get { throw null; } }
+ public System.Int32 MinorVersion { get { throw null; } }
+ }
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public sealed partial class UnknownWrapper
{
@@ -11625,8 +12057,13 @@ namespace System.Runtime.Loader
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; }
@@ -11838,41 +12275,19 @@ namespace System.Runtime.Serialization
Persistence = 8,
Remoting = 16,
}
-}
-namespace System.Runtime.Versioning
-{
- [System.AttributeUsageAttribute((System.AttributeTargets)(5887), AllowMultiple=false, Inherited=false)]
- public sealed partial class ComponentGuaranteesAttribute : System.Attribute
- {
- public ComponentGuaranteesAttribute(System.Runtime.Versioning.ComponentGuaranteesOptions guarantees) { }
- public System.Runtime.Versioning.ComponentGuaranteesOptions Guarantees { get { throw null; } }
- }
- [System.FlagsAttribute]
- public enum ComponentGuaranteesOptions
- {
- Exchange = 1,
- None = 0,
- SideBySide = 4,
- Stable = 2,
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(480), Inherited=false)]
- [System.Diagnostics.ConditionalAttribute("RESOURCE_ANNOTATION_WORK")]
- public sealed partial class ResourceExposureAttribute : System.Attribute
+ public sealed partial class SafeSerializationEventArgs : System.EventArgs
{
- public ResourceExposureAttribute(System.Runtime.Versioning.ResourceScope exposureLevel) { }
- public System.Runtime.Versioning.ResourceScope ResourceExposureLevel { get { throw null; } }
+ internal SafeSerializationEventArgs() { }
+ public System.Runtime.Serialization.StreamingContext StreamingContext { get { throw null; } }
+ public void AddSerializedState(System.Runtime.Serialization.ISafeSerializationData serializedState) { }
}
- [System.FlagsAttribute]
- public enum ResourceScope
+ public partial interface ISafeSerializationData
{
- AppDomain = 4,
- Assembly = 32,
- Library = 8,
- Machine = 1,
- None = 0,
- Private = 16,
- Process = 2,
+ void CompleteDeserialization(object deserialized);
}
+}
+namespace System.Runtime.Versioning
+{
[System.AttributeUsageAttribute((System.AttributeTargets)(1), AllowMultiple=false, Inherited=false)]
public sealed partial class TargetFrameworkAttribute : System.Attribute
{
@@ -11880,12 +12295,6 @@ namespace System.Runtime.Versioning
public string FrameworkDisplayName { get { throw null; } set { } }
public string FrameworkName { get { throw null; } }
}
- public static partial class VersioningHelper
- {
- public static string MakeVersionSafeName(string name, System.Runtime.Versioning.ResourceScope from, System.Runtime.Versioning.ResourceScope to) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static string MakeVersionSafeName(string name, System.Runtime.Versioning.ResourceScope from, System.Runtime.Versioning.ResourceScope to, System.Type type) { throw null; }
- }
}
namespace System.Security
{
@@ -11894,23 +12303,64 @@ namespace System.Security
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) { }
- protected SecurityException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- [System.Security.SecurityCriticalAttribute]
+ 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
{
@@ -11929,6 +12379,17 @@ namespace System.Security
{
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
@@ -12646,6 +13107,12 @@ namespace System.Threading
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() { }
@@ -12890,7 +13357,9 @@ namespace System.Threading
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
@@ -13053,44 +13522,47 @@ namespace System.Threading
}
[System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class Thread : System.Runtime.ConstrainedExecution.CriticalFinalizerObject
+ 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 System.Threading.Thread CurrentThread { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
+ 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 bool IsAlive { [System.Security.SecuritySafeCriticalAttribute][System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]get { throw null; } }
- public bool IsBackground { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } [System.Security.SecuritySafeCriticalAttribute]set { } }
- public int ManagedThreadId { [System.Security.SecuritySafeCriticalAttribute][System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]get { throw null; } }
- public string Name { get { throw null; } [System.Security.SecuritySafeCriticalAttribute]set { } }
- public System.Threading.ThreadState ThreadState { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
+ 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]
public static System.AppDomain GetDomain() { throw null; }
[System.Runtime.InteropServices.ComVisibleAttribute(false)]
public override int GetHashCode() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public void Join() { }
- [System.Security.SecuritySafeCriticalAttribute]
- public bool Join(int millisecondsTimeout) { throw null; }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
public static void MemoryBarrier() { }
[System.Security.SecuritySafeCriticalAttribute]
- public static void Sleep(int millisecondsTimeout) { }
+ public static new void Sleep(int millisecondsTimeout) { }
public static void Sleep(System.TimeSpan timeout) { }
[System.Security.SecuritySafeCriticalAttribute]
- public static void SpinWait(int iterations) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public void Start() { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public void Start(object parameter) { }
+ 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
{
@@ -13136,6 +13608,14 @@ namespace System.Threading
[System.Security.Permissions.SecurityPermissionAttribute(System.Security.Permissions.SecurityAction.Demand, ControlThread=true)]
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
@@ -13276,20 +13756,13 @@ namespace System.Threading
public virtual bool WaitOne(System.TimeSpan timeout, bool exitContext) { return default(bool); }
}
[System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public partial class WaitHandleCannotBeOpenedException : System.Exception
+ 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) { }
}
- public static partial class WaitHandleExtensions
- {
- [System.Security.SecurityCriticalAttribute]
- public static Microsoft.Win32.SafeHandles.SafeWaitHandle GetSafeWaitHandle(this System.Threading.WaitHandle waitHandle) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static void SetSafeWaitHandle(this System.Threading.WaitHandle waitHandle, Microsoft.Win32.SafeHandles.SafeWaitHandle value) { }
- }
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public delegate void WaitOrTimerCallback(object state, bool timedOut);
}
diff --git a/src/mscorlib/src/Internal/Runtime/Augments/EnvironmentAugments.cs b/src/mscorlib/src/Internal/Runtime/Augments/EnvironmentAugments.cs
index 28104683c7..b22310eacb 100644
--- a/src/mscorlib/src/Internal/Runtime/Augments/EnvironmentAugments.cs
+++ b/src/mscorlib/src/Internal/Runtime/Augments/EnvironmentAugments.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
+using System.Collections;
namespace Internal.Runtime.Augments
{
@@ -17,5 +18,11 @@ namespace Internal.Runtime.Augments
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);
+ public static IDictionary GetEnvironmentVariables() => Environment.GetEnvironmentVariables();
+ 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);
}
}
diff --git a/src/mscorlib/src/Internal/Runtime/Augments/RuntimeThread.cs b/src/mscorlib/src/Internal/Runtime/Augments/RuntimeThread.cs
new file mode 100644
index 0000000000..3aafe01a2c
--- /dev/null
+++ b/src/mscorlib/src/Internal/Runtime/Augments/RuntimeThread.cs
@@ -0,0 +1,198 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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.CompilerServices;
+using System.Runtime.ConstrainedExecution;
+using System.Runtime.InteropServices;
+using System.Security;
+using System.Security.Permissions;
+using System.Threading;
+
+namespace Internal.Runtime.Augments
+{
+ public class RuntimeThread : CriticalFinalizerObject
+ {
+ public static RuntimeThread Create(ThreadStart start) => new Thread(start);
+ public static RuntimeThread Create(ThreadStart start, int maxStackSize) => new Thread(start, maxStackSize);
+ public static RuntimeThread Create(ParameterizedThreadStart start) => new Thread(start);
+ public static RuntimeThread Create(ParameterizedThreadStart start, int maxStackSize) => new Thread(start, maxStackSize);
+
+ private Thread AsThread()
+ {
+ Debug.Assert(this is Thread);
+ return (Thread)this;
+ }
+
+ public static RuntimeThread CurrentThread => Thread.CurrentThread;
+
+ /*=========================================================================
+ ** Returns true if the thread has been started and is not dead.
+ =========================================================================*/
+ public extern bool IsAlive
+ {
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ get;
+ }
+
+ /*=========================================================================
+ ** Return whether or not this thread is a background thread. Background
+ ** threads do not affect when the Execution Engine shuts down.
+ **
+ ** Exceptions: ThreadStateException if the thread is dead.
+ =========================================================================*/
+ public bool IsBackground
+ {
+ get { return IsBackgroundNative(); }
+ set { SetBackgroundNative(value); }
+ }
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private extern bool IsBackgroundNative();
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private extern void SetBackgroundNative(bool isBackground);
+
+ /*=========================================================================
+ ** Returns true if the thread is a threadpool thread.
+ =========================================================================*/
+ public extern bool IsThreadPoolThread
+ {
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ get;
+ }
+
+ public int ManagedThreadId => AsThread().ManagedThreadId;
+ public string Name { get { return AsThread().Name; } set { AsThread().Name = value; } }
+
+ /*=========================================================================
+ ** Returns the priority of the thread.
+ **
+ ** Exceptions: ThreadStateException if the thread is dead.
+ =========================================================================*/
+ public ThreadPriority Priority
+ {
+ get { return (ThreadPriority)GetPriorityNative(); }
+ set { SetPriorityNative((int)value); }
+ }
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private extern int GetPriorityNative();
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private extern void SetPriorityNative(int priority);
+
+ /*=========================================================================
+ ** Return the thread state as a consistent set of bits. This is more
+ ** general then IsAlive or IsBackground.
+ =========================================================================*/
+ public ThreadState ThreadState
+ {
+ get { return (ThreadState)GetThreadStateNative(); }
+ }
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private extern int GetThreadStateNative();
+
+ public ApartmentState GetApartmentState()
+ {
+#if FEATURE_COMINTEROP_APARTMENT_SUPPORT
+ return (ApartmentState)GetApartmentStateNative();
+#else // !FEATURE_COMINTEROP_APARTMENT_SUPPORT
+ Debug.Assert(false); // the Thread class in CoreFX should have handled this case
+ return ApartmentState.MTA;
+#endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT
+ }
+
+ /*=========================================================================
+ ** An unstarted thread can be marked to indicate that it will host a
+ ** single-threaded or multi-threaded apartment.
+ =========================================================================*/
+ public bool TrySetApartmentState(ApartmentState state)
+ {
+#if FEATURE_COMINTEROP_APARTMENT_SUPPORT
+ return SetApartmentStateHelper(state, false);
+#else // !FEATURE_COMINTEROP_APARTMENT_SUPPORT
+ Debug.Assert(false); // the Thread class in CoreFX should have handled this case
+ return false;
+#endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT
+ }
+
+#if FEATURE_COMINTEROP_APARTMENT_SUPPORT
+ internal bool SetApartmentStateHelper(ApartmentState state, bool fireMDAOnMismatch)
+ {
+ ApartmentState retState = (ApartmentState)SetApartmentStateNative((int)state, fireMDAOnMismatch);
+
+ // Special case where we pass in Unknown and get back MTA.
+ // Once we CoUninitialize the thread, the OS will still
+ // report the thread as implicitly in the MTA if any
+ // other thread in the process is CoInitialized.
+ if ((state == System.Threading.ApartmentState.Unknown) && (retState == System.Threading.ApartmentState.MTA))
+ return true;
+
+ if (retState != state)
+ return false;
+
+ return true;
+ }
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern int GetApartmentStateNative();
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern int SetApartmentStateNative(int state, bool fireMDAOnMismatch);
+#endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT
+
+#if FEATURE_COMINTEROP
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ public extern void DisableComObjectEagerCleanup();
+#else // !FEATURE_COMINTEROP
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ public void DisableComObjectEagerCleanup()
+ {
+ Debug.Assert(false); // the Thread class in CoreFX should have handled this case
+ }
+#endif // FEATURE_COMINTEROP
+
+ /*=========================================================================
+ ** Interrupts a thread that is inside a Wait(), Sleep() or Join(). If that
+ ** thread is not currently blocked in that manner, it will be interrupted
+ ** when it next begins to block.
+ =========================================================================*/
+#pragma warning disable 618 // obsolete types: SecurityPermissionAttribute, SecurityAction
+#pragma warning restore 618 // obsolete types: SecurityPermissionAttribute, SecurityAction
+ public void Interrupt() => InterruptInternal();
+
+ // Internal helper (since we can't place security demands on
+ // ecalls/fcalls).
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private extern void InterruptInternal();
+
+ /*=========================================================================
+ ** Waits for the thread to die or for timeout milliseconds to elapse.
+ ** Returns true if the thread died, or false if the wait timed out. If
+ ** Timeout.Infinite is given as the parameter, no timeout will occur.
+ **
+ ** Exceptions: ArgumentException if timeout < 0.
+ ** ThreadInterruptedException if the thread is interrupted while waiting.
+ ** ThreadStateException if the thread has not been started yet.
+ =========================================================================*/
+ public void Join() => JoinInternal(Timeout.Infinite);
+
+ public bool Join(int millisecondsTimeout) => JoinInternal(millisecondsTimeout);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private extern bool JoinInternal(int millisecondsTimeout);
+
+ public static void Sleep(int millisecondsTimeout) => Thread.Sleep(millisecondsTimeout);
+ public static void SpinWait(int iterations) => Thread.SpinWait(iterations);
+ public static bool Yield() => Thread.Yield();
+
+ public void Start() => AsThread().Start();
+ public void Start(object parameter) => AsThread().Start(parameter);
+ }
+}
diff --git a/src/mscorlib/src/Microsoft/Win32/OAVariantLib.cs b/src/mscorlib/src/Microsoft/Win32/OAVariantLib.cs
index 118c69b8b7..6c2c6e9630 100644
--- a/src/mscorlib/src/Microsoft/Win32/OAVariantLib.cs
+++ b/src/mscorlib/src/Microsoft/Win32/OAVariantLib.cs
@@ -73,13 +73,12 @@ namespace Microsoft.Win32 {
* Variant and the types that CLR supports explicitly in the
* CLR Variant class.
*/
- [System.Security.SecurityCritical] // auto-generated
internal static Variant ChangeType(Variant source, Type targetClass, short options, CultureInfo culture)
{
if (targetClass == null)
- throw new ArgumentNullException("targetClass");
+ throw new ArgumentNullException(nameof(targetClass));
if (culture == null)
- throw new ArgumentNullException("culture");
+ throw new ArgumentNullException(nameof(culture));
Variant result = new Variant ();
ChangeTypeEx(ref result, ref source,
#if FEATURE_USE_LCID
@@ -125,7 +124,6 @@ namespace Microsoft.Win32 {
#region Private FCalls
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void ChangeTypeEx(ref Variant result, ref Variant source, int lcid, IntPtr typeHandle, int cvType, short flags);
diff --git a/src/mscorlib/src/Microsoft/Win32/Registry.cs b/src/mscorlib/src/Microsoft/Win32/Registry.cs
index 4faf29da7f..3ee5f4648b 100644
--- a/src/mscorlib/src/Microsoft/Win32/Registry.cs
+++ b/src/mscorlib/src/Microsoft/Win32/Registry.cs
@@ -17,7 +17,6 @@ namespace Microsoft.Win32 {
//This class contains only static members and does not need to be serializable.
[ComVisible(true)]
public static class Registry {
- [System.Security.SecuritySafeCritical] // auto-generated
static Registry()
{
}
@@ -63,17 +62,6 @@ namespace Microsoft.Win32 {
* This is where current configuration information is stored.
*/
public static readonly RegistryKey CurrentConfig = RegistryKey.GetBaseKey(RegistryKey.HKEY_CURRENT_CONFIG);
-
-#if !FEATURE_CORECLR
- /**
- * Dynamic Data Root Key.
- *
- * LEGACY: This is where dynamic performance data is stored on Win9X.
- * This does not exist on NT.
- */
- [Obsolete("The DynData registry key only works on Win9x, which is no longer supported by the CLR. On NT-based operating systems, use the PerformanceData registry key instead.")]
- public static readonly RegistryKey DynData = RegistryKey.GetBaseKey(RegistryKey.HKEY_DYN_DATA);
-#endif
//
// Following function will parse a keyName and returns the basekey for it.
@@ -81,10 +69,9 @@ namespace Microsoft.Win32 {
// If the keyName is not valid, we will throw ArgumentException.
// The return value shouldn't be null.
//
- [System.Security.SecurityCritical] // auto-generated
private static RegistryKey GetBaseKeyFromKeyName(string keyName, out string subKeyName) {
if( keyName == null) {
- throw new ArgumentNullException("keyName");
+ throw new ArgumentNullException(nameof(keyName));
}
string basekeyName;
@@ -116,13 +103,8 @@ namespace Microsoft.Win32 {
case "HKEY_CURRENT_CONFIG":
basekey = Registry.CurrentConfig;
break;
-#if !FEATURE_CORECLR
- case "HKEY_DYN_DATA":
- basekey = RegistryKey.GetBaseKey(RegistryKey.HKEY_DYN_DATA);
- break;
-#endif
default:
- throw new ArgumentException(Environment.GetResourceString("Arg_RegInvalidKeyName", "keyName"));
+ throw new ArgumentException(Environment.GetResourceString("Arg_RegInvalidKeyName", nameof(keyName)));
}
if( i == -1 || i == keyName.Length) {
subKeyName = string.Empty;
@@ -133,7 +115,6 @@ namespace Microsoft.Win32 {
return basekey;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static object GetValue(string keyName, string valueName, object defaultValue ) {
string subKeyName;
RegistryKey basekey = GetBaseKeyFromKeyName(keyName, out subKeyName);
@@ -154,7 +135,6 @@ namespace Microsoft.Win32 {
SetValue(keyName, valueName, value, RegistryValueKind.Unknown);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static void SetValue(string keyName, string valueName, object value, RegistryValueKind valueKind ) {
string subKeyName;
RegistryKey basekey = GetBaseKeyFromKeyName(keyName, out subKeyName);
diff --git a/src/mscorlib/src/Microsoft/Win32/RegistryKey.cs b/src/mscorlib/src/Microsoft/Win32/RegistryKey.cs
index dcf31dc60c..ff678f132c 100644
--- a/src/mscorlib/src/Microsoft/Win32/RegistryKey.cs
+++ b/src/mscorlib/src/Microsoft/Win32/RegistryKey.cs
@@ -49,15 +49,12 @@
*/
-namespace Microsoft.Win32 {
-
+namespace Microsoft.Win32
+{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Security;
-#if FEATURE_MACL
- using System.Security.AccessControl;
-#endif
using System.Security.Permissions;
using System.Text;
using System.Threading;
@@ -74,7 +71,7 @@ namespace Microsoft.Win32 {
* Registry hive values. Useful only for GetRemoteBaseKey
*/
[Serializable]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public enum RegistryHive
{
ClassesRoot = unchecked((int)0x80000000),
@@ -83,9 +80,6 @@ namespace Microsoft.Win32 {
Users = unchecked((int)0x80000003),
PerformanceData = unchecked((int)0x80000004),
CurrentConfig = unchecked((int)0x80000005),
-#if !FEATURE_CORECLR
- DynData = unchecked((int)0x80000006),
-#endif
}
/**
@@ -96,13 +90,8 @@ namespace Microsoft.Win32 {
* @security(checkDllCalls=off)
* @security(checkClassLinking=on)
*/
-#if FEATURE_REMOTING
[ComVisible(true)]
public sealed class RegistryKey : MarshalByRefObject, IDisposable
-#else
- [ComVisible(true)]
- public sealed class RegistryKey : IDisposable
-#endif
{
// We could use const here, if C# supported ELEMENT_TYPE_I fully.
@@ -112,9 +101,6 @@ namespace Microsoft.Win32 {
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));
-#if !FEATURE_CORECLR
- internal static readonly IntPtr HKEY_DYN_DATA = new IntPtr(unchecked((int)0x80000006));
-#endif
// Dirty indicates that we have munged data that should be potentially
// written to disk.
@@ -142,9 +128,6 @@ namespace Microsoft.Win32 {
"HKEY_USERS",
"HKEY_PERFORMANCE_DATA",
"HKEY_CURRENT_CONFIG",
-#if !FEATURE_CORECLR
- "HKEY_DYN_DATA"
-#endif
};
// MSDN defines the following limits for registry key names & values:
@@ -154,7 +137,6 @@ namespace Microsoft.Win32 {
private const int MaxKeyLength = 255;
private const int MaxValueLength = 16383;
- [System.Security.SecurityCritical] // auto-generated
private volatile SafeRegistryHandle hkey = null;
private volatile int state = 0;
private volatile String keyName;
@@ -188,7 +170,6 @@ namespace Microsoft.Win32 {
* This key is bound to hkey, if writable is <b>false</b> then no write operations
* will be allowed.
*/
- [System.Security.SecurityCritical] // auto-generated
private RegistryKey(SafeRegistryHandle hkey, bool writable, RegistryView view)
: this(hkey, writable, false, false, false, view) {
}
@@ -203,7 +184,6 @@ 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.
*/
- [System.Security.SecurityCritical] // auto-generated
private RegistryKey(SafeRegistryHandle hkey, bool writable, bool systemkey, bool remoteKey, bool isPerfData, RegistryView view) {
this.hkey = hkey;
this.keyName = "";
@@ -227,7 +207,6 @@ namespace Microsoft.Win32 {
Dispose(true);
}
- [System.Security.SecuritySafeCritical] // auto-generated
private void Dispose(bool disposing) {
if (hkey != null) {
@@ -260,7 +239,6 @@ namespace Microsoft.Win32 {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void Flush() {
if (hkey != null) {
if (IsDirty()) {
@@ -269,11 +247,7 @@ namespace Microsoft.Win32 {
}
}
-#if FEATURE_CORECLR
void IDisposable.Dispose()
-#else
- public void Dispose()
-#endif
{
Dispose(true);
}
@@ -314,22 +288,6 @@ namespace Microsoft.Win32 {
return CreateSubKeyInternal(subkey, writable ? RegistryKeyPermissionCheck.ReadWriteSubTree : RegistryKeyPermissionCheck.ReadSubTree, null, options);
}
-
-#if FEATURE_MACL
- [ComVisible(false)]
- public unsafe RegistryKey CreateSubKey(String subkey, RegistryKeyPermissionCheck permissionCheck, RegistrySecurity registrySecurity)
- {
- return CreateSubKeyInternal(subkey, permissionCheck, registrySecurity, RegistryOptions.None);
- }
-
- [ComVisible(false)]
- public unsafe RegistryKey CreateSubKey(String subkey, RegistryKeyPermissionCheck permissionCheck, RegistryOptions registryOptions, RegistrySecurity registrySecurity)
- {
- return CreateSubKeyInternal(subkey, permissionCheck, registrySecurity, registryOptions);
- }
-#endif
-
- [System.Security.SecuritySafeCritical] // auto-generated
[ComVisible(false)]
private unsafe RegistryKey CreateSubKeyInternal(String subkey, RegistryKeyPermissionCheck permissionCheck, object registrySecurityObj, RegistryOptions registryOptions)
{
@@ -351,23 +309,9 @@ namespace Microsoft.Win32 {
}
CheckPermission(RegistryInternalCheck.CheckSubKeyCreatePermission, subkey, false, RegistryKeyPermissionCheck.Default);
-
+
Win32Native.SECURITY_ATTRIBUTES secAttrs = null;
-#if FEATURE_MACL
- RegistrySecurity registrySecurity = (RegistrySecurity)registrySecurityObj;
- // For ACL's, get the security descriptor from the RegistrySecurity.
- if (registrySecurity != null) {
- secAttrs = new Win32Native.SECURITY_ATTRIBUTES();
- secAttrs.nLength = (int)Marshal.SizeOf(secAttrs);
-
- byte[] sd = registrySecurity.GetSecurityDescriptorBinaryForm();
- // We allocate memory on the stack to improve the speed.
- // So this part of code can't be refactored into a method.
- byte* pSecDescriptor = stackalloc byte[sd.Length];
- Buffer.Memcpy(pSecDescriptor, 0, sd, 0, sd.Length);
- secAttrs.pSecurityDescriptor = pSecDescriptor;
- }
-#endif
+
int disposition = 0;
// By default, the new key will be writable.
@@ -412,7 +356,6 @@ namespace Microsoft.Win32 {
DeleteSubKey(subkey, true);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void DeleteSubKey(String subkey, bool throwOnMissingSubKey) {
ValidateKeyName(subkey);
EnsureWriteable();
@@ -466,7 +409,6 @@ namespace Microsoft.Win32 {
DeleteSubKeyTree(subkey, true /*throwOnMissingSubKey*/);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[ComVisible(false)]
public void DeleteSubKeyTree(String subkey, Boolean throwOnMissingSubKey) {
ValidateKeyName(subkey);
@@ -514,7 +456,6 @@ namespace Microsoft.Win32 {
// An internal version which does no security checks or argument checking. Skipping the
// security checks should give us a slight perf gain on large trees.
- [System.Security.SecurityCritical] // auto-generated
private void DeleteSubKeyTreeInternal(string subkey) {
RegistryKey key = InternalOpenSubKey(subkey, true);
if (key != null) {
@@ -541,7 +482,7 @@ namespace Microsoft.Win32 {
if (ret!=0) Win32Error(ret, null);
}
else {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSubKeyAbsent);
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSubKeyAbsent);
}
}
@@ -554,7 +495,6 @@ namespace Microsoft.Win32 {
DeleteValue(name, true);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void DeleteValue(String name, bool throwOnMissingValue) {
EnsureWriteable();
CheckPermission(RegistryInternalCheck.CheckValueWritePermission, name, false, RegistryKeyPermissionCheck.Default);
@@ -592,12 +532,10 @@ namespace Microsoft.Win32 {
*
* @return the RegistryKey requested.
*/
- [System.Security.SecurityCritical] // auto-generated
internal static RegistryKey GetBaseKey(IntPtr hKey) {
return GetBaseKey(hKey, RegistryView.Default);
}
- [System.Security.SecurityCritical] // auto-generated
internal static RegistryKey GetBaseKey(IntPtr hKey, RegistryView view) {
int index = ((int)hKey) & 0x0FFFFFFF;
@@ -615,7 +553,6 @@ namespace Microsoft.Win32 {
}
- [System.Security.SecuritySafeCritical] // auto-generated
[ComVisible(false)]
public static RegistryKey OpenBaseKey(RegistryHive hKey, RegistryView view) {
ValidateKeyView(view);
@@ -645,11 +582,10 @@ namespace Microsoft.Win32 {
return OpenRemoteBaseKey(hKey, machineName, RegistryView.Default);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[ComVisible(false)]
public static RegistryKey OpenRemoteBaseKey(RegistryHive hKey, String machineName, RegistryView view) {
if (machineName==null)
- throw new ArgumentNullException("machineName");
+ throw new ArgumentNullException(nameof(machineName));
int index = (int)hKey & 0x0FFFFFFF;
if (index < 0 || index >= hkeyNames.Length || ((int)hKey & 0xFFFFFFF0) != 0x80000000) {
throw new ArgumentException(Environment.GetResourceString("Arg_RegKeyOutOfRange"));
@@ -687,11 +623,6 @@ namespace Microsoft.Win32 {
*
* @return the Subkey requested, or <b>null</b> if the operation failed.
*/
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #else
- [System.Security.SecuritySafeCritical]
- #endif
public RegistryKey OpenSubKey(string name, bool writable ) {
ValidateKeyName(name);
EnsureNotDisposed();
@@ -722,63 +653,8 @@ namespace Microsoft.Win32 {
return null;
}
-#if FEATURE_MACL
-
- [System.Security.SecuritySafeCritical] // auto-generated
- [ComVisible(false)]
- public RegistryKey OpenSubKey(String name, RegistryKeyPermissionCheck permissionCheck) {
- ValidateKeyMode(permissionCheck);
- return InternalOpenSubKey(name, permissionCheck, GetRegistryKeyAccess(permissionCheck));
- }
-
- [System.Security.SecuritySafeCritical]
- [ComVisible(false)]
- public RegistryKey OpenSubKey(String name, RegistryRights rights)
- {
- return InternalOpenSubKey(name, this.checkMode, (int)rights);
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- [ComVisible(false)]
- public RegistryKey OpenSubKey(String name, RegistryKeyPermissionCheck permissionCheck, RegistryRights rights) {
- return InternalOpenSubKey(name, permissionCheck, (int)rights);
- }
-
- [System.Security.SecurityCritical] // auto-generated
- private RegistryKey InternalOpenSubKey(String name, RegistryKeyPermissionCheck permissionCheck, int rights) {
- ValidateKeyName(name);
- ValidateKeyMode(permissionCheck);
-
- ValidateKeyRights(rights);
-
- EnsureNotDisposed();
- name = FixupName(name); // Fixup multiple slashes to a single slash
-
- CheckPermission(RegistryInternalCheck.CheckOpenSubKeyPermission, name, false, permissionCheck);
- CheckPermission(RegistryInternalCheck.CheckSubTreePermission, name, false, permissionCheck);
- SafeRegistryHandle result = null;
- int ret = Win32Native.RegOpenKeyEx(hkey, name, 0, (rights | (int)regView), out result);
- if (ret == 0 && !result.IsInvalid) {
- RegistryKey key = new RegistryKey(result, (permissionCheck == RegistryKeyPermissionCheck.ReadWriteSubTree), false, remoteKey, false, regView);
- key.keyName = keyName + "\\" + name;
- key.checkMode = permissionCheck;
- return key;
- }
-
- // Return null if we didn't find the key.
- if (ret == Win32Native.ERROR_ACCESS_DENIED || ret == Win32Native.ERROR_BAD_IMPERSONATION_LEVEL) {
- // We need to throw SecurityException here for compatiblity reason,
- // although UnauthorizedAccessException will make more sense.
- ThrowHelper.ThrowSecurityException(ExceptionResource.Security_RegistryPermission);
- }
-
- return null;
- }
-#endif
-
// 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
- [System.Security.SecurityCritical] // auto-generated
internal RegistryKey InternalOpenSubKey(String name, bool writable) {
ValidateKeyName(name);
EnsureNotDisposed();
@@ -805,9 +681,6 @@ namespace Microsoft.Win32 {
*
* @return the Subkey requested, or <b>null</b> if the operation failed.
*/
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical]
-#endif
public RegistryKey OpenSubKey(String name) {
return OpenSubKey(name, false);
}
@@ -818,7 +691,6 @@ namespace Microsoft.Win32 {
* @return a count of subkeys.
*/
public int SubKeyCount {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
CheckPermission(RegistryInternalCheck.CheckKeyReadPermission, null, false, RegistryKeyPermissionCheck.Default);
return InternalSubKeyCount();
@@ -827,90 +699,12 @@ namespace Microsoft.Win32 {
[ComVisible(false)]
public RegistryView View {
- [System.Security.SecuritySafeCritical]
get {
EnsureNotDisposed();
return regView;
}
}
-#if !FEATURE_CORECLR
- [ComVisible(false)]
- public SafeRegistryHandle Handle {
- [System.Security.SecurityCritical]
- [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
- get {
- EnsureNotDisposed();
- int ret = Win32Native.ERROR_INVALID_HANDLE;
- if (IsSystemKey()) {
- IntPtr baseKey = (IntPtr)0;
- switch (keyName) {
- case "HKEY_CLASSES_ROOT":
- baseKey = HKEY_CLASSES_ROOT;
- break;
- case "HKEY_CURRENT_USER":
- baseKey = HKEY_CURRENT_USER;
- break;
- case "HKEY_LOCAL_MACHINE":
- baseKey = HKEY_LOCAL_MACHINE;
- break;
- case "HKEY_USERS":
- baseKey = HKEY_USERS;
- break;
- case "HKEY_PERFORMANCE_DATA":
- baseKey = HKEY_PERFORMANCE_DATA;
- break;
- case "HKEY_CURRENT_CONFIG":
- baseKey = HKEY_CURRENT_CONFIG;
- break;
- case "HKEY_DYN_DATA":
- baseKey = HKEY_DYN_DATA;
- break;
- default:
- Win32Error(ret, null);
- break;
- }
- // open the base key so that RegistryKey.Handle will return a valid handle
- SafeRegistryHandle result;
- ret = Win32Native.RegOpenKeyEx(baseKey,
- null,
- 0,
- GetRegistryKeyAccess(IsWritable()) | (int)regView,
- out result);
-
- if (ret == 0 && !result.IsInvalid) {
- return result;
- }
- else {
- Win32Error(ret, null);
- }
- }
- else {
- return hkey;
- }
- throw new IOException(Win32Native.GetMessage(ret), ret);
- }
- }
-
- [System.Security.SecurityCritical]
- [ComVisible(false)]
- [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
- public static RegistryKey FromHandle(SafeRegistryHandle handle) {
- return FromHandle(handle, RegistryView.Default);
- }
-
- [System.Security.SecurityCritical]
- [ComVisible(false)]
- [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
- public static RegistryKey FromHandle(SafeRegistryHandle handle, RegistryView view) {
- if (handle == null) throw new ArgumentNullException("handle");
- ValidateKeyView(view);
-
- return new RegistryKey(handle, true /* isWritable */, view);
- }
-#endif
-
- [System.Security.SecurityCritical] // auto-generated
internal int InternalSubKeyCount() {
EnsureNotDisposed();
@@ -939,17 +733,11 @@ namespace Microsoft.Win32 {
*
* @return all subkey names.
*/
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #else
- [System.Security.SecuritySafeCritical]
- #endif
public String[] GetSubKeyNames() {
CheckPermission(RegistryInternalCheck.CheckKeyReadPermission, null, false, RegistryKeyPermissionCheck.Default);
return InternalGetSubKeyNames();
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe String[] InternalGetSubKeyNames() {
EnsureNotDisposed();
int subkeys = InternalSubKeyCount();
@@ -988,14 +776,12 @@ namespace Microsoft.Win32 {
* @return a count of values.
*/
public int ValueCount {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
CheckPermission(RegistryInternalCheck.CheckKeyReadPermission, null, false, RegistryKeyPermissionCheck.Default);
return InternalValueCount();
}
}
- [System.Security.SecurityCritical] // auto-generated
internal int InternalValueCount() {
EnsureNotDisposed();
int values = 0;
@@ -1022,7 +808,6 @@ namespace Microsoft.Win32 {
*
* @return all value names.
*/
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe String[] GetValueNames() {
CheckPermission(RegistryInternalCheck.CheckKeyReadPermission, null, false, RegistryKeyPermissionCheck.Default);
EnsureNotDisposed();
@@ -1073,7 +858,6 @@ namespace Microsoft.Win32 {
*
* @return the data associated with the value.
*/
- [System.Security.SecuritySafeCritical] // auto-generated
public Object GetValue(String name) {
CheckPermission(RegistryInternalCheck.CheckValueReadPermission, name, false, RegistryKeyPermissionCheck.Default);
return InternalGetValue(name, null, false, true);
@@ -1094,32 +878,21 @@ namespace Microsoft.Win32 {
*
* @return the data associated with the value.
*/
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #else
- [System.Security.SecuritySafeCritical]
- #endif
public Object GetValue(String name, Object defaultValue) {
CheckPermission(RegistryInternalCheck.CheckValueReadPermission, name, false, RegistryKeyPermissionCheck.Default);
return InternalGetValue(name, defaultValue, false, true);
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #else
- [System.Security.SecuritySafeCritical]
- #endif
[ComVisible(false)]
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), "options");
+ 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);
}
- [System.Security.SecurityCritical] // auto-generated
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
@@ -1338,7 +1111,6 @@ namespace Microsoft.Win32 {
}
- [System.Security.SecuritySafeCritical] // auto-generated
[ComVisible(false)]
public RegistryValueKind GetValueKind(string name) {
CheckPermission(RegistryInternalCheck.CheckValueReadPermission, name, false, RegistryKeyPermissionCheck.Default);
@@ -1382,7 +1154,6 @@ namespace Microsoft.Win32 {
}
public String Name {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
EnsureNotDisposed();
return keyName;
@@ -1403,7 +1174,6 @@ namespace Microsoft.Win32 {
SetValue(name, value, RegistryValueKind.Unknown);
}
- [System.Security.SecuritySafeCritical] //auto-generated
[ComVisible(false)]
public unsafe void SetValue(String name, Object value, RegistryValueKind valueKind) {
if (value==null)
@@ -1414,7 +1184,7 @@ namespace Microsoft.Win32 {
}
if (!Enum.IsDefined(typeof(RegistryValueKind), valueKind))
- throw new ArgumentException(Environment.GetResourceString("Arg_RegBadKeyKind"), "valueKind");
+ throw new ArgumentException(Environment.GetResourceString("Arg_RegBadKeyKind"), nameof(valueKind));
EnsureWriteable();
@@ -1575,33 +1345,11 @@ namespace Microsoft.Win32 {
*
* @return a string representing the key.
*/
- [System.Security.SecuritySafeCritical] // auto-generated
public override String ToString() {
EnsureNotDisposed();
return keyName;
}
-#if FEATURE_MACL
- public RegistrySecurity GetAccessControl() {
- return GetAccessControl(AccessControlSections.Access | AccessControlSections.Owner | AccessControlSections.Group);
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public RegistrySecurity GetAccessControl(AccessControlSections includeSections) {
- EnsureNotDisposed();
- return new RegistrySecurity(hkey, keyName, includeSections);
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public void SetAccessControl(RegistrySecurity registrySecurity) {
- EnsureWriteable();
- if (registrySecurity == null)
- throw new ArgumentNullException("registrySecurity");
-
- registrySecurity.Persist(hkey, keyName);
- }
-#endif
-
/**
* After calling GetLastWin32Error(), it clears the last error field,
* so you must save the HResult and pass it to this method. This method
@@ -1609,7 +1357,6 @@ namespace Microsoft.Win32 {
* error, and depending on the error, insert a string into the message
* gotten from the ResourceManager.
*/
- [System.Security.SecuritySafeCritical] // auto-generated
internal void Win32Error(int errorCode, String str) {
switch (errorCode) {
case Win32Native.ERROR_ACCESS_DENIED:
@@ -1645,7 +1392,6 @@ namespace Microsoft.Win32 {
}
}
- [SecuritySafeCritical]
internal static void Win32ErrorStatic(int errorCode, String str) {
switch (errorCode) {
case Win32Native.ERROR_ACCESS_DENIED:
@@ -1778,18 +1524,12 @@ namespace Microsoft.Win32 {
path = keyName + "\\.";
}
- [System.Security.SecurityCritical] // auto-generated
- private void CheckPermission(RegistryInternalCheck check, string item, bool subKeyWritable, RegistryKeyPermissionCheck subKeyCheck) {
+ private void CheckPermission(RegistryInternalCheck check, string item, bool subKeyWritable, RegistryKeyPermissionCheck subKeyCheck)
+ {
bool demand = false;
RegistryPermissionAccess access = RegistryPermissionAccess.NoAccess;
string path = null;
-#if !FEATURE_CORECLR
- if (CodeAccessSecurityEngine.QuickCheckForAllDemands()) {
- return; // full trust fast path
- }
-#endif // !FEATURE_CORECLR
-
switch (check) {
//
// Read/Write/Create SubKey Permission
@@ -2020,14 +1760,12 @@ namespace Microsoft.Win32 {
}
}
- [System.Security.SecurityCritical] // auto-generated
static private void CheckUnmanagedCodePermission() {
#pragma warning disable 618
new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
#pragma warning restore 618
}
- [System.Security.SecurityCritical] // auto-generated
private bool ContainsRegistryValue(string name) {
int type = 0;
int datasize = 0;
@@ -2035,14 +1773,12 @@ namespace Microsoft.Win32 {
return retval == 0;
}
- [System.Security.SecurityCritical] // auto-generated
private void EnsureNotDisposed(){
if (hkey == null) {
ThrowHelper.ThrowObjectDisposedException(keyName, ExceptionResource.ObjectDisposed_RegKeyClosed);
}
}
- [System.Security.SecurityCritical] // auto-generated
private void EnsureWriteable() {
EnsureNotDisposed();
if (!IsWritable()) {
@@ -2134,16 +1870,6 @@ namespace Microsoft.Win32 {
}
}
-
-#if FEATURE_MACL
- static private void ValidateKeyRights(int rights) {
- if(0 != (rights & ~((int)RegistryRights.FullControl))) {
- // We need to throw SecurityException here for compatiblity reason,
- // although UnauthorizedAccessException will make more sense.
- ThrowHelper.ThrowSecurityException(ExceptionResource.Security_RegistryPermission);
- }
- }
-#endif
// Win32 constants for error handling
private const int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
private const int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
diff --git a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.cs b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.cs
deleted file mode 100644
index ab06347ee4..0000000000
--- a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.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.
-
-/*============================================================
-**
-**
-**
-** A wrapper for file handles
-**
-**
-===========================================================*/
-
-using System;
-using System.Security;
-using System.Security.Permissions;
-using System.Runtime.InteropServices;
-using System.Runtime.CompilerServices;
-using System.Runtime.ConstrainedExecution;
-using System.Runtime.Versioning;
-using Microsoft.Win32;
-
-namespace Microsoft.Win32.SafeHandles {
-
- [System.Security.SecurityCritical] // auto-generated_required
- public sealed class SafeFileHandle: SafeHandleZeroOrMinusOneIsInvalid {
-
- private SafeFileHandle() : base(true)
- {
- }
-
- public SafeFileHandle(IntPtr preexistingHandle, bool ownsHandle) : base(ownsHandle) {
- SetHandle(preexistingHandle);
- }
-
- [System.Security.SecurityCritical]
- override protected bool ReleaseHandle()
- {
- return Win32Native.CloseHandle(handle);
- }
- }
-}
-
diff --git a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFileMappingHandle.cs b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFileMappingHandle.cs
index 5e1b5100bc..cb915fe7c3 100644
--- a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFileMappingHandle.cs
+++ b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFileMappingHandle.cs
@@ -20,20 +20,16 @@ using System.Runtime.Versioning;
namespace Microsoft.Win32.SafeHandles
{
- [System.Security.SecurityCritical] // auto-generated
internal sealed class SafeFileMappingHandle : SafeHandleZeroOrMinusOneIsInvalid
{
- [System.Security.SecurityCritical] // auto-generated_required
internal SafeFileMappingHandle() : base(true) {}
// 0 is an Invalid Handle
- [System.Security.SecurityCritical] // auto-generated_required
internal SafeFileMappingHandle(IntPtr handle, bool ownsHandle) : base (ownsHandle)
{
SetHandle(handle);
}
- [System.Security.SecurityCritical]
override protected bool ReleaseHandle()
{
return Win32Native.CloseHandle(handle);
diff --git a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFindHandle.cs b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFindHandle.cs
index b24535f997..219fb77001 100644
--- a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFindHandle.cs
+++ b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFindHandle.cs
@@ -20,13 +20,10 @@ using System.Runtime.ConstrainedExecution;
using Microsoft.Win32;
namespace Microsoft.Win32.SafeHandles {
- [System.Security.SecurityCritical] // auto-generated
internal sealed class SafeFindHandle : SafeHandleZeroOrMinusOneIsInvalid
{
- [System.Security.SecurityCritical] // auto-generated_required
internal SafeFindHandle() : base(true) {}
- [System.Security.SecurityCritical]
override protected bool ReleaseHandle()
{
return Win32Native.FindClose(handle);
diff --git a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeLibraryHandle.cs b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeLibraryHandle.cs
index d2ea42b14e..23631987a5 100644
--- a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeLibraryHandle.cs
+++ b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeLibraryHandle.cs
@@ -3,24 +3,12 @@
// See the LICENSE file in the project root for more information.
namespace Microsoft.Win32 {
- using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
- using System;
- using System.Runtime.CompilerServices;
- using System.Runtime.ConstrainedExecution;
- using System.Runtime.InteropServices;
- using System.Runtime.Serialization;
- using System.Runtime.Versioning;
- using System.Security;
using System.Security.Permissions;
- using System.Text;
- [System.Security.SecurityCritical] // auto-generated
- [HostProtectionAttribute(MayLeakOnAbort = true)]
sealed internal class SafeLibraryHandle : SafeHandleZeroOrMinusOneIsInvalid {
internal SafeLibraryHandle() : base(true) {}
- [System.Security.SecurityCritical]
override protected bool ReleaseHandle()
{
return UnsafeNativeMethods.FreeLibrary(handle);
diff --git a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeLocalAllocHandle.cs b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeLocalAllocHandle.cs
index 3eea2b9937..d6c1577eeb 100644
--- a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeLocalAllocHandle.cs
+++ b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeLocalAllocHandle.cs
@@ -1,13 +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 Microsoft.Win32.SafeHandles {
+
+namespace Microsoft.Win32.SafeHandles
+{
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.ConstrainedExecution;
- [System.Security.SecurityCritical] // auto-generated
internal sealed class SafeLocalAllocHandle : SafeBuffer {
private SafeLocalAllocHandle () : base(true) {}
@@ -20,7 +21,6 @@ namespace Microsoft.Win32.SafeHandles {
get { return new SafeLocalAllocHandle(IntPtr.Zero); }
}
- [System.Security.SecurityCritical]
override protected bool ReleaseHandle()
{
return Win32Native.LocalFree(handle) == IntPtr.Zero;
diff --git a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeRegistryHandle.cs b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeRegistryHandle.cs
index d0e3f048f2..4f96b81e72 100644
--- a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeRegistryHandle.cs
+++ b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeRegistryHandle.cs
@@ -17,17 +17,13 @@ namespace Microsoft.Win32.SafeHandles {
using System.Runtime.ConstrainedExecution;
using System.Runtime.Versioning;
- [System.Security.SecurityCritical]
public sealed class SafeRegistryHandle : SafeHandleZeroOrMinusOneIsInvalid {
- [System.Security.SecurityCritical]
internal SafeRegistryHandle() : base(true) {}
- [System.Security.SecurityCritical]
public SafeRegistryHandle(IntPtr preexistingHandle, bool ownsHandle) : base(ownsHandle) {
SetHandle(preexistingHandle);
}
- [System.Security.SecurityCritical]
override protected bool ReleaseHandle() {
return (RegCloseKey(handle) == Win32Native.ERROR_SUCCESS);
}
diff --git a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeViewOfFileHandle.cs b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeViewOfFileHandle.cs
index 01ec4d2ad8..38a9323c0b 100644
--- a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeViewOfFileHandle.cs
+++ b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeViewOfFileHandle.cs
@@ -22,19 +22,15 @@ using Microsoft.Win32.SafeHandles;
namespace Microsoft.Win32.SafeHandles
{
- [System.Security.SecurityCritical] // auto-generated
internal sealed class SafeViewOfFileHandle : SafeHandleZeroOrMinusOneIsInvalid
{
- [System.Security.SecurityCritical] // auto-generated_required
internal SafeViewOfFileHandle() : base(true) {}
// 0 is an Invalid Handle
- [System.Security.SecurityCritical] // auto-generated_required
internal SafeViewOfFileHandle(IntPtr handle, bool ownsHandle) : base (ownsHandle) {
SetHandle(handle);
}
- [System.Security.SecurityCritical]
override protected bool ReleaseHandle()
{
if (Win32Native.UnmapViewOfFile(handle))
diff --git a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeWaitHandle.cs b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeWaitHandle.cs
index fa24c96718..0e57136952 100644
--- a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeWaitHandle.cs
+++ b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeWaitHandle.cs
@@ -24,7 +24,6 @@ using System.Threading;
namespace Microsoft.Win32.SafeHandles {
- [System.Security.SecurityCritical] // auto-generated_required
public sealed class SafeWaitHandle : SafeHandleZeroOrMinusOneIsInvalid
{
// Called by P/Invoke marshaler
@@ -38,7 +37,6 @@ namespace Microsoft.Win32.SafeHandles {
SetHandle(existingHandle);
}
- [System.Security.SecurityCritical]
override protected bool ReleaseHandle()
{
return Win32Native.CloseHandle(handle);
diff --git a/src/mscorlib/src/Microsoft/Win32/SafeHandles/Win32SafeHandles.cs b/src/mscorlib/src/Microsoft/Win32/SafeHandles/Win32SafeHandles.cs
index 58e0d7ad1d..08ae0955a8 100644
--- a/src/mscorlib/src/Microsoft/Win32/SafeHandles/Win32SafeHandles.cs
+++ b/src/mscorlib/src/Microsoft/Win32/SafeHandles/Win32SafeHandles.cs
@@ -22,10 +22,6 @@ namespace Microsoft.Win32.SafeHandles
using System.Runtime.ConstrainedExecution;
// Class of safe handle which uses 0 or -1 as an invalid handle.
- [System.Security.SecurityCritical] // auto-generated_required
-#if !FEATURE_CORECLR
- [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode=true)]
-#endif
public abstract class SafeHandleZeroOrMinusOneIsInvalid : SafeHandle
{
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
@@ -33,25 +29,18 @@ namespace Microsoft.Win32.SafeHandles
{
}
-#if FEATURE_CORECLR
// A default constructor is needed to satisfy CoreCLR inheritence rules. It should not be called at runtime
protected SafeHandleZeroOrMinusOneIsInvalid()
{
throw new NotImplementedException();
}
-#endif // FEATURE_CORECLR
public override bool IsInvalid {
- [System.Security.SecurityCritical]
get { return handle.IsNull() || handle == new IntPtr(-1); }
}
}
// Class of safe handle which uses only -1 as an invalid handle.
- [System.Security.SecurityCritical] // auto-generated_required
-#if !FEATURE_CORECLR
- [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode=true)]
-#endif
public abstract class SafeHandleMinusOneIsInvalid : SafeHandle
{
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
@@ -59,25 +48,18 @@ namespace Microsoft.Win32.SafeHandles
{
}
-#if FEATURE_CORECLR
// A default constructor is needed to satisfy CoreCLR inheritence rules. It should not be called at runtime
protected SafeHandleMinusOneIsInvalid()
{
throw new NotImplementedException();
}
-#endif // FEATURE_CORECLR
public override bool IsInvalid {
- [System.Security.SecurityCritical]
get { return handle == new IntPtr(-1); }
}
}
// Class of critical handle which uses 0 or -1 as an invalid handle.
- [System.Security.SecurityCritical] // auto-generated_required
-#if !FEATURE_CORECLR
- [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode=true)]
-#endif
public abstract class CriticalHandleZeroOrMinusOneIsInvalid : CriticalHandle
{
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
@@ -86,16 +68,11 @@ namespace Microsoft.Win32.SafeHandles
}
public override bool IsInvalid {
- [System.Security.SecurityCritical]
get { return handle.IsNull() || handle == new IntPtr(-1); }
}
}
// Class of critical handle which uses only -1 as an invalid handle.
- [System.Security.SecurityCritical] // auto-generated_required
-#if !FEATURE_CORECLR
- [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode=true)]
-#endif
public abstract class CriticalHandleMinusOneIsInvalid : CriticalHandle
{
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
@@ -104,9 +81,7 @@ namespace Microsoft.Win32.SafeHandles
}
public override bool IsInvalid {
- [System.Security.SecurityCritical]
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 9da9811ee8..19d638d61a 100644
--- a/src/mscorlib/src/Microsoft/Win32/UnsafeNativeMethods.cs
+++ b/src/mscorlib/src/Microsoft/Win32/UnsafeNativeMethods.cs
@@ -16,7 +16,6 @@ namespace Microsoft.Win32 {
using System.Text;
using System.Diagnostics.Tracing;
- [System.Security.SecurityCritical] // auto-generated
[SuppressUnmanagedCodeSecurityAttribute()]
internal static class UnsafeNativeMethods {
@@ -64,7 +63,6 @@ namespace Microsoft.Win32 {
internal static extern bool FreeLibrary(IntPtr hModule);
- [SecurityCritical]
[SuppressUnmanagedCodeSecurityAttribute()]
internal static unsafe class ManifestEtw
{
@@ -96,7 +94,6 @@ namespace Microsoft.Win32 {
//
// Callback
//
- [SecurityCritical]
internal unsafe delegate void EtwEnableCallback(
[In] ref Guid sourceId,
[In] int isEnabled,
@@ -110,7 +107,6 @@ namespace Microsoft.Win32 {
//
// Registration APIs
//
- [SecurityCritical]
[DllImport(Win32Native.ADVAPI32, ExactSpelling = true, EntryPoint = "EventRegister", CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
internal static extern unsafe uint EventRegister(
[In] ref Guid providerId,
@@ -120,7 +116,6 @@ namespace Microsoft.Win32 {
);
//
- [SecurityCritical]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage")]
[DllImport(Win32Native.ADVAPI32, ExactSpelling = true, EntryPoint = "EventUnregister", CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
internal static extern uint EventUnregister([In] long registrationHandle);
@@ -129,7 +124,6 @@ namespace Microsoft.Win32 {
// Writing (Publishing/Logging) APIs
//
//
- [SecurityCritical]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage")]
[DllImport(Win32Native.ADVAPI32, ExactSpelling = true, EntryPoint = "EventWrite", CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
internal static extern unsafe int EventWrite(
@@ -139,7 +133,6 @@ namespace Microsoft.Win32 {
[In] EventProvider.EventData* userData
);
- [SecurityCritical]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage")]
[DllImport(Win32Native.ADVAPI32, ExactSpelling = true, EntryPoint = "EventWriteString", CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
internal static extern unsafe int EventWriteString(
@@ -270,7 +263,6 @@ namespace Microsoft.Win32 {
}
#if FEATURE_COMINTEROP
- [SecurityCritical]
[DllImport("combase.dll", PreserveSig = true)]
internal static extern int RoGetActivationFactory(
[MarshalAs(UnmanagedType.HString)] string activatableClassId,
diff --git a/src/mscorlib/src/Microsoft/Win32/Win32Native.cs b/src/mscorlib/src/Microsoft/Win32/Win32Native.cs
index ebe53f45af..b5b808b424 100644
--- a/src/mscorlib/src/Microsoft/Win32/Win32Native.cs
+++ b/src/mscorlib/src/Microsoft/Win32/Win32Native.cs
@@ -90,9 +90,6 @@
namespace Microsoft.Win32 {
using System;
using System.Security;
-#if FEATURE_IMPERSONATION
- using System.Security.Principal;
-#endif
using System.Text;
using System.Configuration.Assemblies;
using System.Runtime.Remoting;
@@ -113,7 +110,6 @@ namespace Microsoft.Win32 {
// Remove the default demands for all P/Invoke methods with this
// global declaration on the class.
- [System.Security.SecurityCritical]
[SuppressUnmanagedCodeSecurityAttribute()]
internal static class Win32Native {
@@ -327,7 +323,7 @@ namespace Microsoft.Win32 {
// } REG_TZI_FORMAT;
//
if (bytes == null || bytes.Length != 44) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidREG_TZI_FORMAT"), "bytes");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidREG_TZI_FORMAT"), nameof(bytes));
}
Bias = BitConverter.ToInt32(bytes, 0);
StandardBias = BitConverter.ToInt32(bytes, 4);
@@ -454,7 +450,6 @@ namespace Microsoft.Win32 {
internal int fileSizeHigh;
internal int fileSizeLow;
- [System.Security.SecurityCritical]
internal void PopulateFrom(WIN32_FIND_DATA findData) {
// Copy the information to data
fileAttributes = findData.dwFileAttributes;
@@ -516,7 +511,6 @@ namespace Microsoft.Win32 {
/// strings created with this version of the constructor will be unsafe to use after the buffer
/// has been freed.
/// </remarks>
- [System.Security.SecurityCritical] // auto-generated
internal UNICODE_INTPTR_STRING (int stringBytes, SafeLocalAllocHandle buffer) {
BCLDebug.Assert(buffer == null || (stringBytes >= 0 && (ulong)stringBytes <= buffer.ByteLength),
"buffer == null || (stringBytes >= 0 && stringBytes <= buffer.ByteLength)");
@@ -802,7 +796,6 @@ namespace Microsoft.Win32 {
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
private static extern IntPtr GetModuleHandle(String moduleName);
- [System.Security.SecurityCritical] // auto-generated
internal static bool DoesWin32MethodExist(String moduleName, String methodName)
{
// GetModuleHandle does not increment the module's ref count, so we don't need to call FreeLibrary.
@@ -910,56 +903,6 @@ namespace Microsoft.Win32 {
[DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)]
internal static extern uint GetLongPathNameW(string lpszShortPath, SafeHandle lpszLongPath, uint cchBuffer);
- // Disallow access to all non-file devices from methods that take
- // a String. 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.
- [System.Security.SecurityCritical] // auto-generated
- internal static SafeFileHandle SafeCreateFile(String lpFileName,
- int dwDesiredAccess, System.IO.FileShare dwShareMode,
- SECURITY_ATTRIBUTES securityAttrs, System.IO.FileMode dwCreationDisposition,
- int dwFlagsAndAttributes, IntPtr hTemplateFile)
- {
- SafeFileHandle handle = CreateFile( lpFileName, dwDesiredAccess, dwShareMode,
- securityAttrs, dwCreationDisposition,
- dwFlagsAndAttributes, hTemplateFile );
-
- if (!handle.IsInvalid)
- {
- int fileType = Win32Native.GetFileType(handle);
- if (fileType != Win32Native.FILE_TYPE_DISK) {
- handle.Dispose();
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_FileStreamOnNonFiles"));
- }
- }
-
- return handle;
- }
-
- [System.Security.SecurityCritical] // auto-generated
- internal static SafeFileHandle UnsafeCreateFile(String lpFileName,
- int dwDesiredAccess, System.IO.FileShare dwShareMode,
- SECURITY_ATTRIBUTES securityAttrs, System.IO.FileMode dwCreationDisposition,
- int dwFlagsAndAttributes, IntPtr hTemplateFile)
- {
- SafeFileHandle handle = CreateFile( lpFileName, dwDesiredAccess, dwShareMode,
- securityAttrs, dwCreationDisposition,
- dwFlagsAndAttributes, hTemplateFile );
-
- return handle;
- }
-
- // Do not use these directly, use the safe or unsafe versions above.
- // The safe version does not support devices (aka if will only open
- // files on disk), while the unsafe version give you the full semantic
- // of the native version.
- [DllImport(KERNEL32, SetLastError=true, CharSet=CharSet.Auto, BestFitMapping=false)]
- private static extern SafeFileHandle CreateFile(String lpFileName,
- int dwDesiredAccess, System.IO.FileShare dwShareMode,
- SECURITY_ATTRIBUTES securityAttrs, System.IO.FileMode dwCreationDisposition,
- int dwFlagsAndAttributes, IntPtr hTemplateFile);
-
[DllImport(KERNEL32, SetLastError=true, CharSet=CharSet.Auto, BestFitMapping=false)]
internal static extern SafeFileMappingHandle CreateFileMapping(SafeFileHandle hFile, IntPtr lpAttributes, uint fProtect, uint dwMaximumSizeHigh, uint dwMaximumSizeLow, String lpName);
@@ -988,7 +931,6 @@ namespace Microsoft.Win32 {
[DllImport(KERNEL32, SetLastError=true, EntryPoint="SetFilePointer")]
private unsafe static extern int SetFilePointerWin32(SafeFileHandle handle, int lo, int * hi, int origin);
- [System.Security.SecurityCritical] // auto-generated
internal unsafe static long SetFilePointer(SafeFileHandle handle, long offset, System.IO.SeekOrigin origin, out int hr) {
hr = 0;
int lo = (int) offset;
@@ -1070,7 +1012,6 @@ namespace Microsoft.Win32 {
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
-#if !FEATURE_CORECLR
[StructLayout(LayoutKind.Sequential)]
internal struct NlsVersionInfoEx
{
@@ -1080,7 +1021,6 @@ namespace Microsoft.Win32 {
internal int dwEffectiveId;
internal Guid guidCustomVersion;
}
-#endif
[DllImport(KERNEL32, CharSet=CharSet.Auto, SetLastError=true, BestFitMapping=false)]
internal static extern int GetWindowsDirectory([Out]StringBuilder sb, int length);
@@ -1797,18 +1737,11 @@ namespace Microsoft.Win32 {
[In] uint dwFlags);
#endif // FEATURE_LEGACYSURFACE
-#if FEATURE_CORECLR
[DllImport(NTDLL, CharSet=CharSet.Unicode, SetLastError=true)]
internal static extern
int RtlNtStatusToDosError (
[In] int status);
-#else
- // identical to RtlNtStatusToDosError, but we are in ask mode for desktop CLR
- [DllImport(ADVAPI32, CharSet = CharSet.Unicode, SetLastError = true)]
- internal static extern
- int LsaNtStatusToWinError (
- [In] int status);
-#endif
+
// Get the current FIPS policy setting on Vista and above
[DllImport("bcrypt.dll")]
internal static extern uint BCryptGetFipsAlgorithmMode(
@@ -1930,28 +1863,6 @@ namespace Microsoft.Win32 {
[In] bool bInheritHandle,
[In] uint dwOptions);
-#if FEATURE_IMPERSONATION
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
- [DllImport(ADVAPI32, CharSet=CharSet.Auto, SetLastError=true)]
- internal static extern
- bool DuplicateTokenEx (
- [In] SafeAccessTokenHandle ExistingTokenHandle,
- [In] TokenAccessLevels DesiredAccess,
- [In] IntPtr TokenAttributes,
- [In] SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
- [In] System.Security.Principal.TokenType TokenType,
- [In,Out] ref SafeAccessTokenHandle DuplicateTokenHandle );
-
- [DllImport(ADVAPI32, CharSet=CharSet.Auto, SetLastError=true)]
- internal static extern
- bool DuplicateTokenEx (
- [In] SafeAccessTokenHandle hExistingToken,
- [In] uint dwDesiredAccess,
- [In] IntPtr lpTokenAttributes, // LPSECURITY_ATTRIBUTES
- [In] uint ImpersonationLevel,
- [In] uint TokenType,
- [In,Out] ref SafeAccessTokenHandle phNewToken);
-#endif
[DllImport(
ADVAPI32,
EntryPoint="EqualDomainSid",
@@ -2345,15 +2256,6 @@ namespace Microsoft.Win32 {
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal static extern int LsaFreeReturnBuffer(IntPtr handle);
-#if FEATURE_IMPERSONATION
- [DllImport (ADVAPI32, CharSet=CharSet.Unicode, SetLastError=true)]
- internal static extern
- bool OpenProcessToken (
- [In] IntPtr ProcessToken,
- [In] TokenAccessLevels DesiredAccess,
- [Out] out SafeAccessTokenHandle TokenHandle);
-#endif
-
[DllImport(
ADVAPI32,
EntryPoint="SetNamedSecurityInfoW",
@@ -2386,16 +2288,6 @@ namespace Microsoft.Win32 {
byte[] dacl,
byte[] sacl );
- // Fusion APIs
-#if FEATURE_FUSION
- [DllImport(MSCORWKS, CharSet=CharSet.Unicode)]
- internal static extern int CreateAssemblyNameObject(out IAssemblyName ppEnum, String szAssemblyName, uint dwFlags, IntPtr pvReserved);
-
- [DllImport(MSCORWKS, CharSet=CharSet.Auto)]
- internal static extern int CreateAssemblyEnum(out IAssemblyEnum ppEnum, IApplicationContext pAppCtx, IAssemblyName pName, uint dwFlags, IntPtr pvReserved);
-#endif // FEATURE_FUSION
-
-#if FEATURE_CORECLR
[DllImport(KERNEL32, CharSet=CharSet.Unicode)]
[SuppressUnmanagedCodeSecurityAttribute()]
internal unsafe static extern int WideCharToMultiByte(
@@ -2417,13 +2309,11 @@ namespace Microsoft.Win32 {
int cchMultiByte,
char* lpWideCharStr,
int cchWideChar);
-#endif // FEATURE_CORECLR
[DllImport(KERNEL32, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal extern static bool QueryUnbiasedInterruptTime(out ulong UnbiasedTime);
-#if FEATURE_CORECLR
#if FEATURE_PAL
[DllImport(KERNEL32, EntryPoint = "PAL_Random")]
internal extern static bool Random(bool bStrong,
@@ -2450,6 +2340,5 @@ namespace Microsoft.Win32 {
}
}
#endif
-#endif
}
}
diff --git a/src/mscorlib/src/System.Private.CoreLib.txt b/src/mscorlib/src/System.Private.CoreLib.txt
index 0369344328..cf17dae96f 100644
--- a/src/mscorlib/src/System.Private.CoreLib.txt
+++ b/src/mscorlib/src/System.Private.CoreLib.txt
@@ -49,10 +49,6 @@ 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 !FEATURE_CORECLR
-UnknownError = Unknown error.
-#endif // !FEATURE_CORECLR
-
#if INCLUDE_DEBUG
; For code contracts
@@ -70,25 +66,6 @@ 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.
-; Access Control
-#if FEATURE_MACL
-AccessControl_MustSpecifyContainerAcl = The named parameter must be a container ACL.
-AccessControl_MustSpecifyLeafObjectAcl = The named parameter must be a non-container ACL.
-AccessControl_AclTooLong = Length of the access control list exceed the allowed maximum.
-AccessControl_MustSpecifyDirectoryObjectAcl = The named parameter must be a directory-object ACL.
-AccessControl_MustSpecifyNonDirectoryObjectAcl = The named parameter must be a non-directory-object ACL.
-AccessControl_InvalidSecurityDescriptorRevision = Security descriptor with revision other than '1' are not legal.
-AccessControl_InvalidSecurityDescriptorSelfRelativeForm = Security descriptor must be in the self-relative form.
-AccessControl_NoAssociatedSecurity = Unable to perform a security operation on an object that has no associated security. This can happen when trying to get an ACL of an anonymous kernel object.
-AccessControl_InvalidHandle = The supplied handle is invalid. This can happen when trying to set an ACL on an anonymous kernel object.
-AccessControl_UnexpectedError = Method failed with unexpected error code {0}.
-AccessControl_InvalidSidInSDDLString = The SDDL string contains an invalid sid or a sid that cannot be translated.
-AccessControl_InvalidOwner = The security identifier is not allowed to be the owner of this object.
-AccessControl_InvalidGroup = The security identifier is not allowed to be the primary group of this object.
-AccessControl_InvalidAccessRuleType = The access rule is not the correct type.
-AccessControl_InvalidAuditRuleType = The audit rule is not the correct type.
-#endif // FEATURE_MACL
-
; Identity Reference Library
#if FEATURE_IDENTITY_REFERENCE
IdentityReference_IdentityNotMapped = Some or all identity references could not be translated.
@@ -121,9 +98,7 @@ Access_Void = Cannot create an instance of void.
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.
-#if FEATURE_CORECLR
Argument_AddingDuplicateWithKey = An item with the same key has already been added. Key: {0}
-#endif // FEATURE_CORECLR
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.
@@ -206,6 +181,7 @@ 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.
@@ -553,26 +529,6 @@ 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.
-#if FEATURE_CAS_POLICY
-Argument_UninitializedCertificate = Uninitialized certificate object.
-Argument_MembershipConditionElement = Element must be a <IMembershipCondition> element.
-Argument_ReservedNPMS = Cannot remove or modify reserved permissions set '{0}'.
-Argument_NPMSInUse = Permission set '{0}' was in use and could not be deleted.
-Argument_StrongNameGetPublicKey = Unable to obtain public key for StrongNameKeyPair.
-Argument_SiteCannotBeNull = Site name must be specified.
-Argument_BlobCannotBeNull = Public key must be specified.
-Argument_ZoneCannotBeNull = Zone must be specified.
-Argument_UrlCannotBeNull = URL must be specified.
-Argument_NoNPMS = Unable to find a permission set with the provided name.
-Argument_FailedCodeGroup = Failed to create a code group of type '{0}'.
-Argument_CodeGroupChildrenMustBeCodeGroups = All objects in the input list must have a parent type of 'CodeGroup'.
-#endif // FEATURE_CAS_POLICY
-#if FEATURE_IMPERSONATION
-Argument_InvalidPrivilegeName = Privilege '{0}' is not valid on this system.
-Argument_TokenZero = Token cannot be zero.
-Argument_InvalidImpersonationToken = Invalid token for impersonation - it cannot be duplicated.
-Argument_ImpersonateUser = Unable to impersonate user.
-#endif // FEATURE_IMPERSONATION
Argument_InvalidHexFormat = Improperly formatted hex string.
Argument_InvalidSite = Invalid site.
Argument_InterfaceMap = 'this' type cannot be an interface itself.
@@ -630,6 +586,14 @@ Argument_UnmanagedMemAccessorWrapAround = The UnmanagedMemoryAccessor capacity a
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.
+#if FEATURE_SPAN_OF_T
+Argument_InvalidTypeWithPointersNotSupported = Cannot use type '{0}'. Only value types without pointers or references are supported.
+Argument_DestinationTooShort = Destination is too short.
+#endif // FEATURE_SPAN_OF_T
;
; =====================================================
@@ -1140,9 +1104,6 @@ InvalidOperation_EnumFailedVersion = Collection was modified; enumeration operat
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.
-#if FEATURE_CAS_POLICY
-InvalidOperation_ModifyROPermSet = ReadOnlyPermissionSet objects may not be modified.
-#endif // FEATURE_CAS_POLICY
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.
@@ -1157,6 +1118,7 @@ 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.
@@ -1242,7 +1204,7 @@ InvalidOperation_CannotUseAFCOtherThread = AsyncFlowControl object must be used
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 the Context that had its flow suppressed.
+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.
@@ -1405,6 +1367,7 @@ NotSupported_SignalAndWaitSTAThread = SignalAndWait on a STA thread is not suppo
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.
@@ -1451,12 +1414,6 @@ NotSupported_NonBlittableTypes = Non-blittable parameter types are not supported
NotSupported_UserDllImport = DllImport cannot be used on user-defined methods.
NotSupported_UserCOM = COM Interop is not supported for user-defined types.
#endif //FEATURE_WINDOWSPHONE
-#if FEATURE_CAS_POLICY
-NotSupported_RequiresCasPolicyExplicit = This method explicitly uses CAS policy, which has been obsoleted by the .NET Framework. In order to enable CAS policy for compatibility reasons, please use the NetFx40_LegacySecurityPolicy configuration switch. Please see http://go.microsoft.com/fwlink/?LinkID=155570 for more information.
-NotSupported_RequiresCasPolicyImplicit = This method implicitly uses CAS policy, which has been obsoleted by the .NET Framework. In order to enable CAS policy for compatibility reasons, please use the NetFx40_LegacySecurityPolicy configuration switch. Please see http://go.microsoft.com/fwlink/?LinkID=155570 for more information.
-NotSupported_CasDeny = The Deny stack modifier has been obsoleted by the .NET Framework. Please see http://go.microsoft.com/fwlink/?LinkId=155571 for more information.
-NotSupported_SecurityContextSourceAppDomainInHeterogenous = SecurityContextSource.CurrentAppDomain is not supported in heterogenous AppDomains.
-#endif // FEATURE_CAS_POLICY
#if FEATURE_APPX
NotSupported_AppX = {0} is not supported in AppX.
LoadOfFxAssemblyNotSupported_AppX = {0} of .NET Framework assemblies is not supported in AppX.
@@ -1466,9 +1423,6 @@ NotSupported_WinRT_PartialTrust = Windows Runtime is not supported in partial tr
#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_CORECLR
-NotSupported_NoTypeInfo = Cannot resolve {0} to a TypeInfo object.
-#endif
#if FEATURE_COMINTEROP
NotSupported_PIAInAppxProcess = A Primary Interop Assembly is not supported in AppX.
#endif
@@ -1476,7 +1430,12 @@ NotSupported_PIAInAppxProcess = A Primary Interop Assembly is not supported in A
; Not referring to "Windows Phone" in the messages, as FEATURE_WINDOWSPHONE is defined for .NET Core as well.
NotSupported_WindowsPhone = {0} is not supported.
NotSupported_AssemblyLoadCodeBase = Assembly.Load with a Codebase is not supported.
+NotSupported_AssemblyLoadFromHash = Assembly.LoadFrom with hashValue is not supported.
#endif
+#if FEATURE_SPAN_OF_T
+NotSupported_CannotCallEqualsOnSpan = Equals() on Span and ReadOnlySpan is not supported. Use operator== instead.
+NotSupported_CannotCallGetHashCodeOnSpan = GetHashCode() on Span and ReadOnlySpan is not supported.
+#endif // FEATURE_SPAN_OF_T
; TypeLoadException
TypeLoad_ResolveType = Could not resolve type '{0}'.
@@ -1536,81 +1495,12 @@ PlatformNotSupported_WinRT = Windows Runtime is not supported on this operating
; 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.
-#if FEATURE_IMPERSONATION
-Policy_PrincipalTwice = Default principal object cannot be set twice.
-#endif // FEATURE_IMPERSONATION
-#if FEATURE_CAS_POLICY
-Policy_PolicyAlreadySet = Policy for this domain cannot be set twice.
-Policy_NoExecutionPermission = Execution permission cannot be acquired.
-Policy_NoRequiredPermission = Required permissions cannot be acquired.
-Policy_MultipleExclusive = More than one exclusive group is not allowed.
-Policy_RecoverNotFileBased = PolicyLevel object not based on a file cannot be recovered.
-Policy_RecoverNoConfigFile = No old configuration file exists to recover.
-Policy_UnableToSave = Policy level '{0}' could not be saved: {1}.
-Policy_BadXml = Policy configuration XML is invalid. The required tag '{0}' is missing.
-Policy_NonFullTrustAssembly = Policy references an assembly not in the full trust assemblies list.
-Policy_MissingActivationContextInAppEvidence = The application evidence does not contain a Fusion activation context.
-Policy_NoTrustManager = A trust manager could not be loaded for this application.
-Policy_GrantSetDoesNotMatchDomain = An assembly was provided an invalid grant set by runtime host '{0}'. In a homogenous AppDomain, the only valid grant sets are FullTrust and the AppDomain's sandbox grant set.
-#endif // FEATURE_CAS_POLICY
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.
-#if FEATURE_CAS_POLICY
-Policy_EvidenceMustBeSerializable = Objects used as evidence must be serializable.
-Policy_DuplicateEvidence = The evidence collection already contains evidence of type '{0}'. Multiple pieces of the same type of evidence are not allowed.
-Policy_IncorrectHostEvidence = Runtime host '{0}' returned evidence of type '{1}' from a request for evidence of type '{2}'.
-Policy_NullHostEvidence = Runtime host '{0}' returned null when asked for assembly evidence for assembly '{1}'.
-Policy_NullHostGrantSet = Runtime host '{0}' returned a null grant set from ResolvePolicy.
-#endif // FEATURE_CAS_POLICY
-
-; Policy codegroup and permission set names and descriptions
-#if FEATURE_CAS_POLICY
-Policy_AllCode_Name = All_Code
-Policy_AllCode_DescriptionFullTrust = Code group grants all code full trust and forms the root of the code group tree.
-Policy_AllCode_DescriptionNothing = Code group grants no permissions and forms the root of the code group tree.
-Policy_MyComputer_Name = My_Computer_Zone
-Policy_MyComputer_Description = Code group grants full trust to all code originating on the local computer
-Policy_Intranet_Name = LocalIntranet_Zone
-Policy_Intranet_Description = Code group grants the intranet permission set to code from the intranet zone. This permission set grants intranet code the right to use isolated storage, full UI access, some capability to do reflection, and limited access to environment variables.
-Policy_IntranetNet_Name = Intranet_Same_Site_Access
-Policy_IntranetNet_Description = All intranet code gets the right to connect back to the site of its origin.
-Policy_IntranetFile_Name = Intranet_Same_Directory_Access
-Policy_IntranetFile_Description = All intranet code gets the right to read from its install directory.
-Policy_Internet_Name = Internet_Zone
-Policy_Internet_Description = Code group grants code from the Internet zone the Internet permission set. This permission set grants Internet code the right to use isolated storage and limited UI access.
-Policy_InternetNet_Name = Internet_Same_Site_Access
-Policy_InternetNet_Description = All Internet code gets the right to connect back to the site of its origin.
-Policy_Trusted_Name = Trusted_Zone
-Policy_Trusted_Description = Code from a trusted zone is granted the Internet permission set. This permission set grants the right to use isolated storage and limited UI access.
-Policy_TrustedNet_Name = Trusted_Same_Site_Access
-Policy_TrustedNet_Description = All Trusted Code gets the right to connect back to the site of its origin.
-Policy_Untrusted_Name = Restricted_Zone
-Policy_Untrusted_Description = Code coming from a restricted zone does not receive any permissions.
-Policy_Microsoft_Name = Microsoft_Strong_Name
-Policy_Microsoft_Description = Code group grants full trust to code signed with the Microsoft strong name.
-Policy_Ecma_Name = ECMA_Strong_Name
-Policy_Ecma_Description = Code group grants full trust to code signed with the ECMA strong name.
-
-; Policy permission set descriptions
-Policy_PS_FullTrust = Allows full access to all resources
-Policy_PS_Everything = Allows unrestricted access to all resources covered by built-in permissions
-Policy_PS_Nothing = Denies all resources, including the right to execute
-Policy_PS_Execution = Permits execution
-Policy_PS_SkipVerification = Grants right to bypass the verification
-Policy_PS_Internet = Default rights given to Internet applications
-Policy_PS_LocalIntranet = Default rights given to applications on the local intranet
-
-; default Policy level names
-Policy_PL_Enterprise = Enterprise
-Policy_PL_Machine = Machine
-Policy_PL_User = User
-Policy_PL_AppDomain = AppDomain
-#endif // FEATURE_CAS_POLICY
-
; RankException
Rank_MultiDimNotSupported = Only single dimension arrays are supported here.
Rank_MustMatch = The specified arrays must have the same number of dimensions.
@@ -1658,125 +1548,6 @@ Remoting_Message_BadRetValOrOutArg = Bad return value or out-argument inside the
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.
-#if FEATURE_REMOTING
-Remoting_Activation_BadAttribute = Activation attribute does not implement the IContextAttribute interface.
-Remoting_Activation_BadObject = Proxy Attribute returned an incompatible object when constructing an instance of type {0}.
-Remoting_Activation_MBR_ProxyAttribute = Proxy Attributes are supported on ContextBound types only.
-Remoting_Activation_ConnectFailed = An attempt to connect to the remote activator failed with exception '{0}'.
-Remoting_Activation_Failed = Activation failed due to an unknown reason.
-Remoting_Activation_InconsistentState = Inconsistent state during activation; there may be two proxies for the same object.
-Remoting_Activation_MissingRemoteAppEntry = Cannot find an entry for remote application '{0}'.
-Remoting_Activation_NullReturnValue = Return value of construction call was null.
-Remoting_Activation_NullFromInternalUnmarshal = InternalUnmarshal of returned ObjRef from activation call returned null.
-Remoting_Activation_WellKnownCTOR = Cannot run a non-default constructor when connecting to well-known objects.
-Remoting_Activation_PermissionDenied = Type '{0}' is not registered for activation.
-Remoting_Activation_PropertyUnhappy = A context property did not approve the candidate context for activating the object.
-Remoting_Activation_AsyncUnsupported = Async Activation not supported.
-Remoting_AmbiguousCTOR = Cannot resolve the invocation to the correct constructor.
-Remoting_AmbiguousMethod = Cannot resolve the invocation to the correct method.
-Remoting_AppDomains_NYI = This feature is not yet supported for cross-application domain.
-Remoting_AppDomainsCantBeCalledRemotely = Permission denied: cannot call methods on the AppDomain class remotely.
-Remoting_AssemblyLoadFailed = Cannot load assembly '{0}'.
-Remoting_Attribute_UseAttributeNotsettable = UseAttribute not allowed in SoapTypeAttribute.
-Remoting_BadType = Cannot load type '{0}'.
-Remoting_BadField = Remoting cannot find field '{0}' on type '{1}'.
-Remoting_BadInternalState_ActivationFailure = Invalid internal state: Activation service failed to initialize.
-Remoting_BadInternalState_ProxySameAppDomain = Invalid internal state: A marshal by ref object should not have a proxy in its own AppDomain.
-Remoting_BadInternalState_FailEnvoySink = Invalid internal state: Failed to create an envoy sink for the object.
-Remoting_CantDisconnectClientProxy = Cannot call disconnect on a proxy.
-Remoting_CantInvokeIRemoteDispatch = Cannot invoke methods on IRemoteDispatch.
-Remoting_ChannelNameAlreadyRegistered = The channel '{0}' is already registered.
-Remoting_ChannelNotRegistered = The channel '{0}' is not registered with remoting services.
-Remoting_Channel_PopOnEmptySinkStack = Tried to pop data from an empty channel sink stack.
-Remoting_Channel_PopFromSinkStackWithoutPush = A channel sink tried to pop data from the stack without first pushing data onto the stack.
-Remoting_Channel_StoreOnEmptySinkStack = A channel sink called the Store method when the sink stack was empty.
-Remoting_Channel_StoreOnSinkStackWithoutPush = A channel sink called the Store method on the sink stack without first pushing data onto the stack.
-Remoting_Channel_CantCallAPRWhenStackEmpty = Cannot call the AsyncProcessResponse method on the previous channel sink because the stack is empty.
-Remoting_Channel_CantCallFRSWhenStackEmtpy = Called FlipRememberedStack() when stack was not null.
-Remoting_Channel_CantCallGetResponseStreamWhenStackEmpty = Cannot call the GetResponseStream method on the previous channel sink because the stack is empty.
-Remoting_Channel_DispatchSinkMessageMissing = No message was deserialized prior to calling the DispatchChannelSink.
-Remoting_Channel_DispatchSinkWantsNullRequestStream = The request stream should be null when the DispatchChannelSink is called.
-Remoting_Channel_CannotBeSecured = Channel {0} cannot be secured. Please consider using a channel that implements ISecurableChannel
-Remoting_Config_ChannelMissingCtor = To be used from a .config file, the channel type '{0}' must have a constructor of the form '{1}'
-Remoting_Config_SinkProviderMissingCtor = To be used from a .config file, the sink provider type '{0}' must have a constructor of the form '{1}'
-Remoting_Config_SinkProviderNotFormatter = A sink provider of type '{0}' is incorrectly labeled as a 'formatter'.
-Remoting_Config_ConfigurationFailure = Remoting configuration failed with the exception '{0}'.
-Remoting_Config_InvalidTimeFormat = Invalid time format '{0}'. Examples of valid time formats include 7D, 10H, 5M, 30S, or 20MS.
-Remoting_Config_AppNameSet = The remoting application name, '{0}', had already been set.
-Remoting_Config_ErrorsModeSet = The remoting custom errors mode had already been set.
-Remoting_Config_CantRedirectActivationOfWellKnownService = Attempt to redirect activation for type '{0}, {1}'. This is not allowed since either a well-known service type has already been registered with that type or that type has been registered has a activated service type.
-Remoting_Config_CantUseRedirectedTypeForWellKnownService = Attempt to register a well-known or activated service type of type '{0}, {1}'. This is not allowed since the type has already been redirected to activate elsewhere.
-Remoting_Config_InvalidChannelType = '{0}' does not implement IChannelReceiver or IChannelSender. All channels must implement one of these interfaces.
-Remoting_Config_InvalidSinkProviderType = Unable to use '{0}' as a channel sink provider. It does not implement '{1}'.
-Remoting_Config_MissingWellKnownModeAttribute = Well-known service entries must contain a 'mode' attribute with a value of 'Singleton' or 'SingleCall'.
-Remoting_Config_MissingTypeAttribute = '{0}' entries must contain a '{1}' attribute of the form 'typeName, assemblyName'.
-Remoting_Config_MissingXmlTypeAttribute = '{0}' entries must contain a '{1}' attribute of the form 'xmlTypeName, xmlTypeNamespace'.
-Remoting_Config_NoAppName = Improper remoting configuration: missing ApplicationName property.
-Remoting_Config_NonTemplateIdAttribute = Only '{0}' templates can have an 'id' attribute.
-Remoting_Config_PreloadRequiresTypeOrAssembly = Preload entries require a type or assembly attribute.
-Remoting_Config_ProviderNeedsElementName = Sink providers must have an element name of 'formatter' or 'provider'.
-Remoting_Config_RequiredXmlAttribute = '{0}' entries require a '{1}' attribute.
-Remoting_Config_ReadFailure = .Config file '{0}' cannot be read successfully due to exception '{1}'.
-Remoting_Config_NodeMustBeUnique = There can be only one '{0}' node in the '{1}' section of a config file.
-Remoting_Config_TemplateCannotReferenceTemplate = A '{0}' template cannot reference another '{0}' template.
-Remoting_Config_TypeAlreadyRedirected = Attempt to redirect activation of type '{0}, {1}' which is already redirected.
-Remoting_Config_UnknownValue = Unknown value {1} was found on the {0} node.
-Remoting_Config_UnableToResolveTemplate = Cannot resolve '{0}' template reference: '{1}'.
-Remoting_Config_VersionPresent = Version information is present in the assembly name '{0}' which is not allowed for '{1}' entries.
-Remoting_Contexts_BadProperty = A property that contributed a bad sink to the chain was found.
-Remoting_Contexts_NoProperty = A property with the name '{0}' was not found.
-Remoting_Contexts_ContextNotFrozenForCallBack = Context should be frozen before calling the DoCallBack method.
-Remoting_Default = Unknown remoting error.
-Remoting_HandlerNotRegistered = The tracking handler of type '{0}' is not registered with Remoting Services.
-Remoting_InvalidMsg = Invalid Message Object.
-Remoting_InvalidCallingType = Attempted to call a method declared on type '{0}' on an object which exposes '{1}'.
-Remoting_InvalidRequestedType = The server object type cannot be cast to the requested type '{0}'.
-Remoting_InternalError = Server encountered an internal error. For more information, turn off customErrors in the server's .config file.
-Remoting_Lifetime_ILeaseReturn = Expected a return object of type ILease, but received '{0}'.
-Remoting_Lifetime_InitialStateInitialLeaseTime = InitialLeaseTime property can only be set when the lease is in initial state. The state is '{0}'.
-Remoting_Lifetime_InitialStateRenewOnCall = RenewOnCallTime property can only be set when the lease is in initial state. The state is '{0}'.
-Remoting_Lifetime_InitialStateSponsorshipTimeout = SponsorshipTimeout property can only be set when the lease is in initial state. State is '{0}'.
-Remoting_Lifetime_SetOnce = '{0}' can only be set once within an AppDomain.
-Remoting_Message_ArgMismatch = {2} arguments were passed to '{0}::{1}'. {3} arguments were expected by this method.
-Remoting_Message_BadAsyncResult = The async result object is null or of an unexpected type.
-Remoting_Message_BadType = The method was called with a Message of an unexpected type.
-Remoting_Message_CoercionFailed = The argument type '{0}' cannot be converted into parameter type '{1}'.
-Remoting_Message_MissingArgValue = Expecting an instance of type '{0}' at pos {1} in the args array.
-Remoting_Message_BadSerialization = Invalid or malformed serialization information for the message object.
-Remoting_NoIdentityEntry = No remoting information was found for this object.
-Remoting_NotRemotableByReference = Trying to create a proxy to an unbound type.
-Remoting_NullMessage = The method was called with a null message.
-Remoting_Proxy_BadType = The proxy is of an unsupported type.
-Remoting_ResetURI = Attempt to reset the URI for an object from '{0}' to '{1}'.
-Remoting_ServerObjectNotFound = The server object for URI '{0}' is not registered with the remoting infrastructure (it may have been disconnected).
-Remoting_SetObjectUriForMarshal__ObjectNeedsToBeLocal = SetObjectUriForMarshal method should only be called for MarshalByRefObjects that exist in the current AppDomain.
-Remoting_SetObjectUriForMarshal__UriExists = SetObjectUriForMarshal method has already been called on this object or the object has already been marshaled.
-Remoting_Proxy_BadReturnType = Return argument has an invalid type.
-Remoting_Proxy_ReturnValueTypeCannotBeNull = ByRef value type parameter cannot be null.
-Remoting_Proxy_BadReturnTypeForActivation = Bad return type for activation call via Invoke: must be of type IConstructionReturnMessage.
-Remoting_Proxy_BadTypeForActivation = Type mismatch between proxy type '{0}' and activation type '{1}'.
-Remoting_Proxy_ExpectedOriginalMessage = The message passed to Invoke should be passed to PropagateOutParameters.
-Remoting_Proxy_InvalidCall = Trying to call proxy while constructor call is in progress.
-Remoting_Proxy_InvalidState = Channel sink does not exist. Failed to dispatch async call.
-Remoting_Proxy_NoChannelSink = This remoting proxy has no channel sink which means either the server has no registered server channels that are listening, or this application has no suitable client channel to talk to the server.
-Remoting_Proxy_InvalidCallType = Only the synchronous call type is supported for messages that are not of type Message.
-Remoting_Proxy_WrongContext = ExecuteMessage can be called only from the native context of the object.
-Remoting_SOAPInteropxsdInvalid = Soap Parse error, xsd:type '{0}' invalid {1}
-Remoting_SOAPQNameNamespace = SoapQName missing a Namespace value '{0}'.
-Remoting_ThreadAffinity_InvalidFlag = The specified flag '{0}' does not have one of the valid values.
-Remoting_TrackingHandlerAlreadyRegistered = The handler has already been registered with TrackingServices.
-Remoting_URIClash = Found two different objects associated with the same URI, '{0}'.
-Remoting_URIExists = The remoted object already has an associated URI.
-Remoting_URIToProxy = Trying to associate the URI with a proxy.
-Remoting_WellKnown_MustBeMBR = Attempted to create well-known object of type '{0}'. Well-known objects must derive from the MarshalByRefObject class.
-Remoting_WellKnown_CtorCantMarshal = '{0}': A well-known object cannot marshal itself in its constructor, or perform any action that would cause it to be marshaled (such as passing the 'this' pointer as a parameter to a remote method).
-Remoting_WellKnown_CantDirectlyConnect = Attempt to connect to a server using its object URI: '{0}'. A valid, complete URL must be used.
-Remoting_Connect_CantCreateChannelSink = Cannot create channel sink to connect to URL '{0}'. An appropriate channel has probably not been registered.
-Remoting_UnexpectedNullTP = Failed to create a transparent proxy. If a custom RealProxy is being used ensure it sets the proxy type.
-; The following remoting exception messages appear in native resources too (mscorrc.rc)
-Remoting_Disconnected = Object '{0}' has been disconnected or does not exist at the server.
-Remoting_Message_MethodMissing = The method '{0}' was not found on the interface/type '{1}'.
-#endif // FEATURE_REMOTING
; Resources exceptions
;
@@ -1805,24 +1576,6 @@ 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.
-#if FEATURE_CAS_POLICY
-Security_CannotGenerateHash = Hash for the assembly cannot be generated.
-Security_CannotGetRawData = Assembly bytes could not be retrieved.
-Security_PrincipalPermission = Request for principal permission failed.
-Security_Action = The action that failed was:
-Security_TypeFirstPermThatFailed = The type of the first permission that failed was:
-Security_FirstPermThatFailed = The first permission that failed was:
-Security_Demanded = The demand was for:
-Security_GrantedSet = The granted set of the failing assembly was:
-Security_RefusedSet = The refused set of the failing assembly was:
-Security_Denied = The denied permissions were:
-Security_PermitOnly = The only permitted permissions were:
-Security_Assembly = The assembly or AppDomain that failed was:
-Security_Method = The method that caused the failure was:
-Security_Zone = The Zone of the assembly that failed was:
-Security_Url = The Url of the assembly that failed was:
-Security_AnonymouslyHostedDynamicMethodCheckFailed = The demand failed due to the code access security information captured during the creation of an anonymously hosted dynamic method. In order for this operation to succeed, ensure that the demand would have succeeded at the time the method was created. See http://go.microsoft.com/fwlink/?LinkId=288746 for more information.
-#endif // FEATURE_CAS_POLICY
;
; HostProtection exceptions
@@ -1872,12 +1625,10 @@ 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 path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.
+IO.PathTooLong = The specified file name or path is too long, or a component of the specified path is too long.
-#if FEATURE_CORECLR
; SecurityException
FileSecurityState_OperationNotPermitted = File operation not permitted. Access to path '{0}' is denied.
-#endif
; PrivilegeNotHeldException
PrivilegeNotHeld_Default = The process does not possess some privilege required for this operation.
@@ -2275,14 +2026,6 @@ XMLSyntax_InvalidSyntaxSatAssemTag = Invalid XML in file "{0}" near element "{1}
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.
-; CodeGroup
-#if FEATURE_CAS_POLICY
-NetCodeGroup_PermissionSet = Same site Web
-MergeLogic_Union = Union
-MergeLogic_FirstMatch = First Match
-FileCodeGroup_PermissionSet = Same directory FileIO - '{0}'
-#endif // FEATURE_CAS_POLICY
-
; MembershipConditions
StrongName_ToString = StrongName - {0}{1}{2}
StrongName_Name = name = {0}
@@ -2295,12 +2038,6 @@ Zone_ToString = Zone - {0}
All_ToString = All code
Url_ToString = Url
GAC_ToString = GAC
-#if FEATURE_CAS_POLICY
-Site_ToStringArg = Site - {0}
-Publisher_ToStringArg = Publisher - {0}
-Url_ToStringArg = Url - {0}
-#endif // FEATURE_CAS_POLICY
-
; Interop non exception strings.
TypeLibConverter_ImportedTypeLibProductName = Assembly imported from type library '{0}'.
@@ -2381,956 +2118,8 @@ InvalidOperation_CollectionBackingListTooLarge=The collection backing this List
InvalidOperation_CollectionBackingDictionaryTooLarge=The collection backing this Dictionary contains too many elements.
InvalidOperation_CannotRemoveLastFromEmptyCollection=Cannot remove the last element from an empty collection.
-; Globalization resources
-;------------------
-
-#if !FEATURE_CORECLR
-Globalization.LegacyModifier = Legacy
-
-;
-;Total items: 809
-;
-Globalization.ci_ = Invariant Language (Invariant Country)
-Globalization.ci_aa = Afar
-Globalization.ci_aa-DJ = Afar (Djibouti)
-Globalization.ci_aa-ER = Afar (Eritrea)
-Globalization.ci_aa-ET = Afar (Ethiopia)
-Globalization.ci_af = Afrikaans
-Globalization.ci_af-NA = Afrikaans (Namibia)
-Globalization.ci_af-ZA = Afrikaans (South Africa)
-Globalization.ci_agq = Aghem
-Globalization.ci_agq-CM = Aghem (Cameroon)
-Globalization.ci_ak = Akan
-Globalization.ci_ak-GH = Akan (Ghana)
-Globalization.ci_am = Amharic
-Globalization.ci_am-ET = Amharic (Ethiopia)
-Globalization.ci_ar = Arabic
-Globalization.ci_ar-001 = Arabic (World)
-Globalization.ci_ar-AE = Arabic (U.A.E.)
-Globalization.ci_ar-BH = Arabic (Bahrain)
-Globalization.ci_ar-DJ = Arabic (Djibouti)
-Globalization.ci_ar-DZ = Arabic (Algeria)
-Globalization.ci_ar-EG = Arabic (Egypt)
-Globalization.ci_ar-ER = Arabic (Eritrea)
-Globalization.ci_ar-IL = Arabic (Israel)
-Globalization.ci_ar-IQ = Arabic (Iraq)
-Globalization.ci_ar-JO = Arabic (Jordan)
-Globalization.ci_ar-KM = Arabic (Comoros)
-Globalization.ci_ar-KW = Arabic (Kuwait)
-Globalization.ci_ar-LB = Arabic (Lebanon)
-Globalization.ci_ar-LY = Arabic (Libya)
-Globalization.ci_ar-MA = Arabic (Morocco)
-Globalization.ci_ar-MR = Arabic (Mauritania)
-Globalization.ci_ar-OM = Arabic (Oman)
-Globalization.ci_ar-PS = Arabic (Palestinian Authority)
-Globalization.ci_ar-QA = Arabic (Qatar)
-Globalization.ci_ar-SA = Arabic (Saudi Arabia)
-Globalization.ci_ar-SD = Arabic (Sudan)
-Globalization.ci_ar-SO = Arabic (Somalia)
-Globalization.ci_ar-SS = Arabic (South Sudan)
-Globalization.ci_ar-SY = Arabic (Syria)
-Globalization.ci_ar-TD = Arabic (Chad)
-Globalization.ci_ar-TN = Arabic (Tunisia)
-Globalization.ci_ar-YE = Arabic (Yemen)
-Globalization.ci_arn = Mapudungun
-Globalization.ci_arn-CL = Mapudungun (Chile)
-Globalization.ci_as = Assamese
-Globalization.ci_as-IN = Assamese (India)
-Globalization.ci_asa = Asu
-Globalization.ci_asa-TZ = Asu (Tanzania)
-Globalization.ci_ast = Asturian
-Globalization.ci_ast-ES = Asturian (Spain)
-Globalization.ci_az = Azerbaijani
-Globalization.ci_az-Cyrl = Azerbaijani (Cyrillic)
-Globalization.ci_az-Cyrl-AZ = Azerbaijani (Cyrillic, Azerbaijan)
-Globalization.ci_az-Latn = Azerbaijani (Latin)
-Globalization.ci_az-Latn-AZ = Azerbaijani (Latin, Azerbaijan)
-Globalization.ci_ba = Bashkir
-Globalization.ci_ba-RU = Bashkir (Russia)
-Globalization.ci_bas = Basaa
-Globalization.ci_bas-CM = Basaa (Cameroon)
-Globalization.ci_be = Belarusian
-Globalization.ci_be-BY = Belarusian (Belarus)
-Globalization.ci_bem = Bemba
-Globalization.ci_bem-ZM = Bemba (Zambia)
-Globalization.ci_bez = Bena
-Globalization.ci_bez-TZ = Bena (Tanzania)
-Globalization.ci_bg = Bulgarian
-Globalization.ci_bg-BG = Bulgarian (Bulgaria)
-Globalization.ci_bm = Bambara
-Globalization.ci_bm-Latn = Bambara (Latin)
-Globalization.ci_bm-Latn-ML = Bambara (Latin, Mali)
-Globalization.ci_bm-ML = Bamanankan (Latin, Mali)
-Globalization.ci_bn = Bangla
-Globalization.ci_bn-BD = Bangla (Bangladesh)
-Globalization.ci_bn-IN = Bangla (India)
-Globalization.ci_bo = Tibetan
-Globalization.ci_bo-CN = Tibetan (PRC)
-Globalization.ci_bo-IN = Tibetan (India)
-Globalization.ci_br = Breton
-Globalization.ci_br-FR = Breton (France)
-Globalization.ci_brx = Bodo
-Globalization.ci_brx-IN = Bodo (India)
-Globalization.ci_bs = Bosnian
-Globalization.ci_bs-Cyrl = Bosnian (Cyrillic)
-Globalization.ci_bs-Cyrl-BA = Bosnian (Cyrillic, Bosnia and Herzegovina)
-Globalization.ci_bs-Latn = Bosnian (Latin)
-Globalization.ci_bs-Latn-BA = Bosnian (Latin, Bosnia and Herzegovina)
-Globalization.ci_byn = Blin
-Globalization.ci_byn-ER = Blin (Eritrea)
-Globalization.ci_ca = Catalan
-Globalization.ci_ca-AD = Catalan (Andorra)
-Globalization.ci_ca-ES = Catalan (Catalan)
-Globalization.ci_ca-ES-valencia = Valencian (Spain)
-Globalization.ci_ca-FR = Catalan (France)
-Globalization.ci_ca-IT = Catalan (Italy)
-Globalization.ci_cgg = Chiga
-Globalization.ci_cgg-UG = Chiga (Uganda)
-Globalization.ci_chr = Cherokee
-Globalization.ci_chr-Cher = Cherokee (Cherokee)
-Globalization.ci_chr-Cher-US = Cherokee (Cherokee)
-Globalization.ci_co = Corsican
-Globalization.ci_co-FR = Corsican (France)
-Globalization.ci_cs = Czech
-Globalization.ci_cs-CZ = Czech (Czech Republic)
-Globalization.ci_cy = Welsh
-Globalization.ci_cy-GB = Welsh (United Kingdom)
-Globalization.ci_da = Danish
-Globalization.ci_da-DK = Danish (Denmark)
-Globalization.ci_da-GL = Danish (Greenland)
-Globalization.ci_dav = Taita
-Globalization.ci_dav-KE = Taita (Kenya)
-Globalization.ci_de = German
-Globalization.ci_de-AT = German (Austria)
-Globalization.ci_de-BE = German (Belgium)
-Globalization.ci_de-CH = German (Switzerland)
-Globalization.ci_de-DE = German (Germany)
-Globalization.ci_de-DE_phoneb = German (Germany)
-Globalization.ci_de-LI = German (Liechtenstein)
-Globalization.ci_de-LU = German (Luxembourg)
-Globalization.ci_dje = Zarma
-Globalization.ci_dje-NE = Zarma (Niger)
-Globalization.ci_dsb = Lower Sorbian
-Globalization.ci_dsb-DE = Lower Sorbian (Germany)
-Globalization.ci_dua = Duala
-Globalization.ci_dua-CM = Duala (Cameroon)
-Globalization.ci_dv = Divehi
-Globalization.ci_dv-MV = Divehi (Maldives)
-Globalization.ci_dyo = Jola-Fonyi
-Globalization.ci_dyo-SN = Jola-Fonyi (Senegal)
-Globalization.ci_dz = Dzongkha
-Globalization.ci_dz-BT = Dzongkha (Bhutan)
-Globalization.ci_ebu = Embu
-Globalization.ci_ebu-KE = Embu (Kenya)
-Globalization.ci_ee = Ewe
-Globalization.ci_ee-GH = Ewe (Ghana)
-Globalization.ci_ee-TG = Ewe (Togo)
-Globalization.ci_el = Greek
-Globalization.ci_el-CY = Greek (Cyprus)
-Globalization.ci_el-GR = Greek (Greece)
-Globalization.ci_en = English
-Globalization.ci_en-001 = English (World)
-Globalization.ci_en-029 = English (Caribbean)
-Globalization.ci_en-150 = English (Europe)
-Globalization.ci_en-AG = English (Antigua and Barbuda)
-Globalization.ci_en-AI = English (Anguilla)
-Globalization.ci_en-AS = English (American Samoa)
-Globalization.ci_en-AU = English (Australia)
-Globalization.ci_en-BB = English (Barbados)
-Globalization.ci_en-BE = English (Belgium)
-Globalization.ci_en-BM = English (Bermuda)
-Globalization.ci_en-BS = English (Bahamas)
-Globalization.ci_en-BW = English (Botswana)
-Globalization.ci_en-BZ = English (Belize)
-Globalization.ci_en-CA = English (Canada)
-Globalization.ci_en-CC = English (Cocos [Keeling] Islands)
-Globalization.ci_en-CK = English (Cook Islands)
-Globalization.ci_en-CM = English (Cameroon)
-Globalization.ci_en-CX = English (Christmas Island)
-Globalization.ci_en-DM = English (Dominica)
-Globalization.ci_en-ER = English (Eritrea)
-Globalization.ci_en-FJ = English (Fiji)
-Globalization.ci_en-FK = English (Falkland Islands)
-Globalization.ci_en-FM = English (Micronesia)
-Globalization.ci_en-GB = English (United Kingdom)
-Globalization.ci_en-GD = English (Grenada)
-Globalization.ci_en-GG = English (Guernsey)
-Globalization.ci_en-GH = English (Ghana)
-Globalization.ci_en-GI = English (Gibraltar)
-Globalization.ci_en-GM = English (Gambia)
-Globalization.ci_en-GU = English (Guam)
-Globalization.ci_en-GY = English (Guyana)
-Globalization.ci_en-HK = English (Hong Kong SAR)
-Globalization.ci_en-IE = English (Ireland)
-Globalization.ci_en-IM = English (Isle of Man)
-Globalization.ci_en-IN = English (India)
-Globalization.ci_en-IO = English (British Indian Ocean Territory)
-Globalization.ci_en-JE = English (Jersey)
-Globalization.ci_en-JM = English (Jamaica)
-Globalization.ci_en-KE = English (Kenya)
-Globalization.ci_en-KI = English (Kiribati)
-Globalization.ci_en-KN = English (Saint Kitts and Nevis)
-Globalization.ci_en-KY = English (Cayman Islands)
-Globalization.ci_en-LC = English (Saint Lucia)
-Globalization.ci_en-LR = English (Liberia)
-Globalization.ci_en-LS = English (Lesotho)
-Globalization.ci_en-MG = English (Madagascar)
-Globalization.ci_en-MH = English (Marshall Islands)
-Globalization.ci_en-MO = English (Macao SAR)
-Globalization.ci_en-MP = English (Northern Mariana Islands)
-Globalization.ci_en-MS = English (Montserrat)
-Globalization.ci_en-MT = English (Malta)
-Globalization.ci_en-MU = English (Mauritius)
-Globalization.ci_en-MW = English (Malawi)
-Globalization.ci_en-MY = English (Malaysia)
-Globalization.ci_en-NA = English (Namibia)
-Globalization.ci_en-NF = English (Norfolk Island)
-Globalization.ci_en-NG = English (Nigeria)
-Globalization.ci_en-NR = English (Nauru)
-Globalization.ci_en-NU = English (Niue)
-Globalization.ci_en-NZ = English (New Zealand)
-Globalization.ci_en-PG = English (Papua New Guinea)
-Globalization.ci_en-PH = English (Republic of the Philippines)
-Globalization.ci_en-PK = English (Pakistan)
-Globalization.ci_en-PN = English (Pitcairn Islands)
-Globalization.ci_en-PR = English (Puerto Rico)
-Globalization.ci_en-PW = English (Palau)
-Globalization.ci_en-RW = English (Rwanda)
-Globalization.ci_en-SB = English (Solomon Islands)
-Globalization.ci_en-SC = English (Seychelles)
-Globalization.ci_en-SD = English (Sudan)
-Globalization.ci_en-SG = English (Singapore)
-Globalization.ci_en-SH = English (St Helena, Ascension, Tristan da Cunha)
-Globalization.ci_en-SL = English (Sierra Leone)
-Globalization.ci_en-SS = English (South Sudan)
-Globalization.ci_en-SX = English (Sint Maarten)
-Globalization.ci_en-SZ = English (Swaziland)
-Globalization.ci_en-TC = English (Turks and Caicos Islands)
-Globalization.ci_en-TK = English (Tokelau)
-Globalization.ci_en-TO = English (Tonga)
-Globalization.ci_en-TT = English (Trinidad and Tobago)
-Globalization.ci_en-TV = English (Tuvalu)
-Globalization.ci_en-TZ = English (Tanzania)
-Globalization.ci_en-UG = English (Uganda)
-Globalization.ci_en-UM = English (US Minor Outlying Islands)
-Globalization.ci_en-US = English (United States)
-Globalization.ci_en-VC = English (Saint Vincent and the Grenadines)
-Globalization.ci_en-VG = English (British Virgin Islands)
-Globalization.ci_en-VI = English (US Virgin Islands)
-Globalization.ci_en-VU = English (Vanuatu)
-Globalization.ci_en-WS = English (Samoa)
-Globalization.ci_en-ZA = English (South Africa)
-Globalization.ci_en-ZM = English (Zambia)
-Globalization.ci_en-ZW = English (Zimbabwe)
-Globalization.ci_eo = Esperanto
-Globalization.ci_eo-001 = Esperanto (World)
-Globalization.ci_es = Spanish
-Globalization.ci_es-419 = Spanish (Latin America)
-Globalization.ci_es-AR = Spanish (Argentina)
-Globalization.ci_es-BO = Spanish (Bolivia)
-Globalization.ci_es-CL = Spanish (Chile)
-Globalization.ci_es-CO = Spanish (Colombia)
-Globalization.ci_es-CR = Spanish (Costa Rica)
-Globalization.ci_es-CU = Spanish (Cuba)
-Globalization.ci_es-DO = Spanish (Dominican Republic)
-Globalization.ci_es-EC = Spanish (Ecuador)
-Globalization.ci_es-ES = Spanish (Spain)
-Globalization.ci_es-ES_tradnl = Spanish (Spain)
-Globalization.ci_es-GQ = Spanish (Equatorial Guinea)
-Globalization.ci_es-GT = Spanish (Guatemala)
-Globalization.ci_es-HN = Spanish (Honduras)
-Globalization.ci_es-MX = Spanish (Mexico)
-Globalization.ci_es-NI = Spanish (Nicaragua)
-Globalization.ci_es-PA = Spanish (Panama)
-Globalization.ci_es-PE = Spanish (Peru)
-Globalization.ci_es-PH = Spanish (Philippines)
-Globalization.ci_es-PR = Spanish (Puerto Rico)
-Globalization.ci_es-PY = Spanish (Paraguay)
-Globalization.ci_es-SV = Spanish (El Salvador)
-Globalization.ci_es-US = Spanish (United States)
-Globalization.ci_es-UY = Spanish (Uruguay)
-Globalization.ci_es-VE = Spanish (Bolivarian Republic of Venezuela)
-Globalization.ci_et = Estonian
-Globalization.ci_et-EE = Estonian (Estonia)
-Globalization.ci_eu = Basque
-Globalization.ci_eu-ES = Basque (Basque)
-Globalization.ci_ewo = Ewondo
-Globalization.ci_ewo-CM = Ewondo (Cameroon)
-Globalization.ci_fa = Persian
-Globalization.ci_fa-AF = Persian (Afghanistan)
-Globalization.ci_fa-IR = Persian (Iran)
-Globalization.ci_ff = Fulah
-Globalization.ci_ff-CM = Fulah (Cameroon)
-Globalization.ci_ff-GN = Fulah (Guinea)
-Globalization.ci_ff-Latn = Fulah (Latin)
-Globalization.ci_ff-Latn-SN = Fulah (Latin, Senegal)
-Globalization.ci_ff-MR = Fulah (Mauritania)
-Globalization.ci_fi = Finnish
-Globalization.ci_fi-FI = Finnish (Finland)
-Globalization.ci_fil = Filipino
-Globalization.ci_fil-PH = Filipino (Philippines)
-Globalization.ci_fo = Faroese
-Globalization.ci_fo-FO = Faroese (Faroe Islands)
-Globalization.ci_fr = French
-Globalization.ci_fr-BE = French (Belgium)
-Globalization.ci_fr-BF = French (Burkina Faso)
-Globalization.ci_fr-BI = French (Burundi)
-Globalization.ci_fr-BJ = French (Benin)
-Globalization.ci_fr-BL = French (Saint Barthélemy)
-Globalization.ci_fr-CA = French (Canada)
-Globalization.ci_fr-CD = French (Congo DRC)
-Globalization.ci_fr-CF = French (Central African Republic)
-Globalization.ci_fr-CG = French (Congo)
-Globalization.ci_fr-CH = French (Switzerland)
-Globalization.ci_fr-CI = French (Côte d’Ivoire)
-Globalization.ci_fr-CM = French (Cameroon)
-Globalization.ci_fr-DJ = French (Djibouti)
-Globalization.ci_fr-DZ = French (Algeria)
-Globalization.ci_fr-FR = French (France)
-Globalization.ci_fr-GA = French (Gabon)
-Globalization.ci_fr-GF = French (French Guiana)
-Globalization.ci_fr-GN = French (Guinea)
-Globalization.ci_fr-GP = French (Guadeloupe)
-Globalization.ci_fr-GQ = French (Equatorial Guinea)
-Globalization.ci_fr-HT = French (Haiti)
-Globalization.ci_fr-KM = French (Comoros)
-Globalization.ci_fr-LU = French (Luxembourg)
-Globalization.ci_fr-MA = French (Morocco)
-Globalization.ci_fr-MC = French (Monaco)
-Globalization.ci_fr-MF = French (Saint Martin)
-Globalization.ci_fr-MG = French (Madagascar)
-Globalization.ci_fr-ML = French (Mali)
-Globalization.ci_fr-MQ = French (Martinique)
-Globalization.ci_fr-MR = French (Mauritania)
-Globalization.ci_fr-MU = French (Mauritius)
-Globalization.ci_fr-NC = French (New Caledonia)
-Globalization.ci_fr-NE = French (Niger)
-Globalization.ci_fr-PF = French (French Polynesia)
-Globalization.ci_fr-PM = French (Saint Pierre and Miquelon)
-Globalization.ci_fr-RE = French (Reunion)
-Globalization.ci_fr-RW = French (Rwanda)
-Globalization.ci_fr-SC = French (Seychelles)
-Globalization.ci_fr-SN = French (Senegal)
-Globalization.ci_fr-SY = French (Syria)
-Globalization.ci_fr-TD = French (Chad)
-Globalization.ci_fr-TG = French (Togo)
-Globalization.ci_fr-TN = French (Tunisia)
-Globalization.ci_fr-VU = French (Vanuatu)
-Globalization.ci_fr-WF = French (Wallis and Futuna)
-Globalization.ci_fr-YT = French (Mayotte)
-Globalization.ci_fur = Friulian
-Globalization.ci_fur-IT = Friulian (Italy)
-Globalization.ci_fy = Frisian
-Globalization.ci_fy-NL = Frisian (Netherlands)
-Globalization.ci_ga = Irish
-Globalization.ci_ga-IE = Irish (Ireland)
-Globalization.ci_gd = Scottish Gaelic
-Globalization.ci_gd-GB = Scottish Gaelic (United Kingdom)
-Globalization.ci_gl = Galician
-Globalization.ci_gl-ES = Galician (Galician)
-Globalization.ci_gn = Guarani
-Globalization.ci_gn-PY = Guarani (Paraguay)
-Globalization.ci_gsw = Alsatian
-Globalization.ci_gsw-CH = Alsatian (Switzerland)
-Globalization.ci_gsw-FR = Alsatian (France)
-Globalization.ci_gsw-LI = Alsatian (Liechtenstein)
-Globalization.ci_gu = Gujarati
-Globalization.ci_gu-IN = Gujarati (India)
-Globalization.ci_guz = Gusii
-Globalization.ci_guz-KE = Gusii (Kenya)
-Globalization.ci_gv = Manx
-Globalization.ci_gv-IM = Manx (Isle of Man)
-Globalization.ci_ha = Hausa
-Globalization.ci_ha-Latn = Hausa (Latin)
-Globalization.ci_ha-Latn-GH = Hausa (Latin, Ghana)
-Globalization.ci_ha-Latn-NE = Hausa (Latin, Niger)
-Globalization.ci_ha-Latn-NG = Hausa (Latin, Nigeria)
-Globalization.ci_haw = Hawaiian
-Globalization.ci_haw-US = Hawaiian (United States)
-Globalization.ci_he = Hebrew
-Globalization.ci_he-IL = Hebrew (Israel)
-Globalization.ci_hi = Hindi
-Globalization.ci_hi-IN = Hindi (India)
-Globalization.ci_hr = Croatian
-Globalization.ci_hr-BA = Croatian (Latin, Bosnia and Herzegovina)
-Globalization.ci_hr-HR = Croatian (Croatia)
-Globalization.ci_hsb = Upper Sorbian
-Globalization.ci_hsb-DE = Upper Sorbian (Germany)
-Globalization.ci_hu = Hungarian
-Globalization.ci_hu-HU = Hungarian (Hungary)
-Globalization.ci_hu-HU_technl = Hungarian (Hungary)
-Globalization.ci_hy = Armenian
-Globalization.ci_hy-AM = Armenian (Armenia)
-Globalization.ci_ia = Interlingua
-Globalization.ci_ia-001 = Interlingua (World)
-Globalization.ci_ia-FR = Interlingua (France)
-Globalization.ci_id = Indonesian
-Globalization.ci_id-ID = Indonesian (Indonesia)
-Globalization.ci_ig = Igbo
-Globalization.ci_ig-NG = Igbo (Nigeria)
-Globalization.ci_ii = Yi
-Globalization.ci_ii-CN = Yi (PRC)
-Globalization.ci_is = Icelandic
-Globalization.ci_is-IS = Icelandic (Iceland)
-Globalization.ci_it = Italian
-Globalization.ci_it-CH = Italian (Switzerland)
-Globalization.ci_it-IT = Italian (Italy)
-Globalization.ci_it-SM = Italian (San Marino)
-Globalization.ci_iu = Inuktitut
-Globalization.ci_iu-Cans = Inuktitut (Syllabics)
-Globalization.ci_iu-Cans-CA = Inuktitut (Syllabics, Canada)
-Globalization.ci_iu-Latn = Inuktitut (Latin)
-Globalization.ci_iu-Latn-CA = Inuktitut (Latin, Canada)
-Globalization.ci_ja = Japanese
-Globalization.ci_ja-JP = Japanese (Japan)
-Globalization.ci_ja-JP_radstr = Japanese (Japan)
-Globalization.ci_jgo = Ngomba
-Globalization.ci_jgo-CM = Ngomba (Cameroon)
-Globalization.ci_jmc = Machame
-Globalization.ci_jmc-TZ = Machame (Tanzania)
-Globalization.ci_jv = Javanese
-Globalization.ci_jv-Latn = Javanese
-Globalization.ci_jv-Latn-ID = Javanese (Indonesia)
-Globalization.ci_ka = Georgian
-Globalization.ci_ka-GE = Georgian (Georgia)
-Globalization.ci_ka-GE_modern = Georgian (Georgia)
-Globalization.ci_kab = Kabyle
-Globalization.ci_kab-DZ = Kabyle (Algeria)
-Globalization.ci_kam = Kamba
-Globalization.ci_kam-KE = Kamba (Kenya)
-Globalization.ci_kde = Makonde
-Globalization.ci_kde-TZ = Makonde (Tanzania)
-Globalization.ci_kea = Kabuverdianu
-Globalization.ci_kea-CV = Kabuverdianu (Cabo Verde)
-Globalization.ci_khq = Koyra Chiini
-Globalization.ci_khq-ML = Koyra Chiini (Mali)
-Globalization.ci_ki = Kikuyu
-Globalization.ci_ki-KE = Kikuyu (Kenya)
-Globalization.ci_kk = Kazakh
-Globalization.ci_kk-KZ = Kazakh (Kazakhstan)
-Globalization.ci_kkj = Kako
-Globalization.ci_kkj-CM = Kako (Cameroon)
-Globalization.ci_kl = Greenlandic
-Globalization.ci_kl-GL = Greenlandic (Greenland)
-Globalization.ci_kln = Kalenjin
-Globalization.ci_kln-KE = Kalenjin (Kenya)
-Globalization.ci_km = Khmer
-Globalization.ci_km-KH = Khmer (Cambodia)
-Globalization.ci_kn = Kannada
-Globalization.ci_kn-IN = Kannada (India)
-Globalization.ci_ko = Korean
-Globalization.ci_ko-KR = Korean (Korea)
-Globalization.ci_kok = Konkani
-Globalization.ci_kok-IN = Konkani (India)
-Globalization.ci_ks = Kashmiri
-Globalization.ci_ks-Arab = Kashmiri (Perso-Arabic)
-Globalization.ci_ks-Arab-IN = Kashmiri (Perso-Arabic)
-Globalization.ci_ksb = Shambala
-Globalization.ci_ksb-TZ = Shambala (Tanzania)
-Globalization.ci_ksf = Bafia
-Globalization.ci_ksf-CM = Bafia (Cameroon)
-Globalization.ci_ksh = Colognian
-Globalization.ci_ksh-DE = Ripuarian (Germany)
-Globalization.ci_ku = Central Kurdish
-Globalization.ci_ku-Arab = Central Kurdish (Arabic)
-Globalization.ci_ku-Arab-IQ = Central Kurdish (Iraq)
-Globalization.ci_kw = Cornish
-Globalization.ci_kw-GB = Cornish (United Kingdom)
-Globalization.ci_ky = Kyrgyz
-Globalization.ci_ky-KG = Kyrgyz (Kyrgyzstan)
-Globalization.ci_lag = Langi
-Globalization.ci_lag-TZ = Langi (Tanzania)
-Globalization.ci_lb = Luxembourgish
-Globalization.ci_lb-LU = Luxembourgish (Luxembourg)
-Globalization.ci_lg = Ganda
-Globalization.ci_lg-UG = Ganda (Uganda)
-Globalization.ci_lkt = Lakota
-Globalization.ci_lkt-US = Lakota (United States)
-Globalization.ci_ln = Lingala
-Globalization.ci_ln-AO = Lingala (Angola)
-Globalization.ci_ln-CD = Lingala (Congo DRC)
-Globalization.ci_ln-CF = Lingala (Central African Republic)
-Globalization.ci_ln-CG = Lingala (Congo)
-Globalization.ci_lo = Lao
-Globalization.ci_lo-LA = Lao (Lao P.D.R.)
-Globalization.ci_lt = Lithuanian
-Globalization.ci_lt-LT = Lithuanian (Lithuania)
-Globalization.ci_lu = Luba-Katanga
-Globalization.ci_lu-CD = Luba-Katanga (Congo DRC)
-Globalization.ci_luo = Luo
-Globalization.ci_luo-KE = Luo (Kenya)
-Globalization.ci_luy = Luyia
-Globalization.ci_luy-KE = Luyia (Kenya)
-Globalization.ci_lv = Latvian
-Globalization.ci_lv-LV = Latvian (Latvia)
-Globalization.ci_mas = Masai
-Globalization.ci_mas-KE = Masai (Kenya)
-Globalization.ci_mas-TZ = Masai (Tanzania)
-Globalization.ci_mer = Meru
-Globalization.ci_mer-KE = Meru (Kenya)
-Globalization.ci_mfe = Morisyen
-Globalization.ci_mfe-MU = Morisyen (Mauritius)
-Globalization.ci_mg = Malagasy
-Globalization.ci_mg-MG = Malagasy (Madagascar)
-Globalization.ci_mgh = Makhuwa-Meetto
-Globalization.ci_mgh-MZ = Makhuwa-Meetto (Mozambique)
-Globalization.ci_mgo = Meta'
-Globalization.ci_mgo-CM = Meta' (Cameroon)
-Globalization.ci_mi = Maori
-Globalization.ci_mi-NZ = Maori (New Zealand)
-Globalization.ci_mk = Macedonian (FYROM)
-Globalization.ci_mk-MK = Macedonian (Former Yugoslav Republic of Macedonia)
-Globalization.ci_ml = Malayalam
-Globalization.ci_ml-IN = Malayalam (India)
-Globalization.ci_mn = Mongolian
-Globalization.ci_mn-Cyrl = Mongolian (Cyrillic)
-Globalization.ci_mn-MN = Mongolian (Cyrillic, Mongolia)
-Globalization.ci_mn-Mong = Mongolian (Traditional Mongolian)
-Globalization.ci_mn-Mong-CN = Mongolian (Traditional Mongolian, PRC)
-Globalization.ci_mn-Mong-MN = Mongolian (Traditional Mongolian, Mongolia)
-Globalization.ci_moh = Mohawk
-Globalization.ci_moh-CA = Mohawk (Mohawk)
-Globalization.ci_mr = Marathi
-Globalization.ci_mr-IN = Marathi (India)
-Globalization.ci_ms = Malay
-Globalization.ci_ms-BN = Malay (Brunei Darussalam)
-Globalization.ci_ms-MY = Malay (Malaysia)
-Globalization.ci_ms-SG = Malay (Latin, Singapore)
-Globalization.ci_mt = Maltese
-Globalization.ci_mt-MT = Maltese (Malta)
-Globalization.ci_mua = Mundang
-Globalization.ci_mua-CM = Mundang (Cameroon)
-Globalization.ci_my = Burmese
-Globalization.ci_my-MM = Burmese (Myanmar)
-Globalization.ci_naq = Nama
-Globalization.ci_naq-NA = Nama (Namibia)
-Globalization.ci_nb = Norwegian (Bokmål)
-Globalization.ci_nb-NO = Norwegian, Bokmål (Norway)
-Globalization.ci_nb-SJ = Norwegian, Bokmål (Svalbard and Jan Mayen)
-Globalization.ci_nd = North Ndebele
-Globalization.ci_nd-ZW = North Ndebele (Zimbabwe)
-Globalization.ci_ne = Nepali
-Globalization.ci_ne-IN = Nepali (India)
-Globalization.ci_ne-NP = Nepali (Nepal)
-Globalization.ci_nl = Dutch
-Globalization.ci_nl-AW = Dutch (Aruba)
-Globalization.ci_nl-BE = Dutch (Belgium)
-Globalization.ci_nl-BQ = Dutch (Bonaire, Sint Eustatius and Saba)
-Globalization.ci_nl-CW = Dutch (Curaçao)
-Globalization.ci_nl-NL = Dutch (Netherlands)
-Globalization.ci_nl-SR = Dutch (Suriname)
-Globalization.ci_nl-SX = Dutch (Sint Maarten)
-Globalization.ci_nmg = Kwasio
-Globalization.ci_nmg-CM = Kwasio (Cameroon)
-Globalization.ci_nn = Norwegian (Nynorsk)
-Globalization.ci_nn-NO = Norwegian, Nynorsk (Norway)
-Globalization.ci_nnh = Ngiemboon
-Globalization.ci_nnh-CM = Ngiemboon (Cameroon)
-Globalization.ci_no = Norwegian
-Globalization.ci_nqo = N'ko
-Globalization.ci_nqo-GN = N'ko (Guinea)
-Globalization.ci_nr = South Ndebele
-Globalization.ci_nr-ZA = South Ndebele (South Africa)
-Globalization.ci_nso = Sesotho sa Leboa
-Globalization.ci_nso-ZA = Sesotho sa Leboa (South Africa)
-Globalization.ci_nus = Nuer
-Globalization.ci_nus-SD = Nuer (Sudan)
-Globalization.ci_nyn = Nyankole
-Globalization.ci_nyn-UG = Nyankole (Uganda)
-Globalization.ci_oc = Occitan
-Globalization.ci_oc-FR = Occitan (France)
-Globalization.ci_om = Oromo
-Globalization.ci_om-ET = Oromo (Ethiopia)
-Globalization.ci_om-KE = Oromo (Kenya)
-Globalization.ci_or = Odia
-Globalization.ci_or-IN = Odia (India)
-Globalization.ci_os = Ossetic
-Globalization.ci_os-GE = Ossetian (Cyrillic, Georgia)
-Globalization.ci_os-RU = Ossetian (Cyrillic, Russia)
-Globalization.ci_pa = Punjabi
-Globalization.ci_pa-Arab = Punjabi (Arabic)
-Globalization.ci_pa-Arab-PK = Punjabi (Islamic Republic of Pakistan)
-Globalization.ci_pa-IN = Punjabi (India)
-Globalization.ci_pl = Polish
-Globalization.ci_pl-PL = Polish (Poland)
-Globalization.ci_prs = Dari
-Globalization.ci_prs-AF = Dari (Afghanistan)
-Globalization.ci_ps = Pashto
-Globalization.ci_ps-AF = Pashto (Afghanistan)
-Globalization.ci_pt = Portuguese
-Globalization.ci_pt-AO = Portuguese (Angola)
-Globalization.ci_pt-BR = Portuguese (Brazil)
-Globalization.ci_pt-CV = Portuguese (Cabo Verde)
-Globalization.ci_pt-GW = Portuguese (Guinea-Bissau)
-Globalization.ci_pt-MO = Portuguese (Macao SAR)
-Globalization.ci_pt-MZ = Portuguese (Mozambique)
-Globalization.ci_pt-PT = Portuguese (Portugal)
-Globalization.ci_pt-ST = Portuguese (São Tomé and Príncipe)
-Globalization.ci_pt-TL = Portuguese (Timor-Leste)
-Globalization.ci_qps-ploc = Pseudo Language (Pseudo)
-Globalization.ci_qps-ploca = Pseudo Language (Pseudo Asia)
-Globalization.ci_qps-plocm = Pseudo Language (Pseudo Mirrored)
-Globalization.ci_qu = Quechua
-Globalization.ci_qu-BO = Quechua (Bolivia)
-Globalization.ci_qu-EC = Quechua (Ecuador)
-Globalization.ci_qu-PE = Quechua (Peru)
-Globalization.ci_quc = K'iche'
-Globalization.ci_quc-Latn = K'iche'
-Globalization.ci_quc-Latn-GT = K'iche' (Guatemala)
-Globalization.ci_qut = K'iche
-Globalization.ci_qut-GT = K'iche (Guatemala)
-Globalization.ci_quz = Quechua
-Globalization.ci_quz-BO = Quechua (Bolivia)
-Globalization.ci_quz-EC = Quechua (Ecuador)
-Globalization.ci_quz-PE = Quechua (Peru)
-Globalization.ci_rm = Romansh
-Globalization.ci_rm-CH = Romansh (Switzerland)
-Globalization.ci_rn = Rundi
-Globalization.ci_rn-BI = Rundi (Burundi)
-Globalization.ci_ro = Romanian
-Globalization.ci_ro-MD = Romanian (Moldova)
-Globalization.ci_ro-RO = Romanian (Romania)
-Globalization.ci_rof = Rombo
-Globalization.ci_rof-TZ = Rombo (Tanzania)
-Globalization.ci_ru = Russian
-Globalization.ci_ru-BY = Russian (Belarus)
-Globalization.ci_ru-KG = Russian (Kyrgyzstan)
-Globalization.ci_ru-KZ = Russian (Kazakhstan)
-Globalization.ci_ru-MD = Russian (Moldova)
-Globalization.ci_ru-RU = Russian (Russia)
-Globalization.ci_ru-UA = Russian (Ukraine)
-Globalization.ci_rw = Kinyarwanda
-Globalization.ci_rw-RW = Kinyarwanda (Rwanda)
-Globalization.ci_rwk = Rwa
-Globalization.ci_rwk-TZ = Rwa (Tanzania)
-Globalization.ci_sa = Sanskrit
-Globalization.ci_sa-IN = Sanskrit (India)
-Globalization.ci_sah = Sakha
-Globalization.ci_sah-RU = Sakha (Russia)
-Globalization.ci_saq = Samburu
-Globalization.ci_saq-KE = Samburu (Kenya)
-Globalization.ci_sbp = Sangu
-Globalization.ci_sbp-TZ = Sangu (Tanzania)
-Globalization.ci_sd = Sindhi
-Globalization.ci_sd-Arab = Sindhi (Arabic)
-Globalization.ci_sd-Arab-PK = Sindhi (Islamic Republic of Pakistan)
-Globalization.ci_se = Sami (Northern)
-Globalization.ci_se-FI = Sami, Northern (Finland)
-Globalization.ci_se-NO = Sami, Northern (Norway)
-Globalization.ci_se-SE = Sami, Northern (Sweden)
-Globalization.ci_seh = Sena
-Globalization.ci_seh-MZ = Sena (Mozambique)
-Globalization.ci_ses = Koyraboro Senni
-Globalization.ci_ses-ML = Koyraboro Senni (Mali)
-Globalization.ci_sg = Sango
-Globalization.ci_sg-CF = Sango (Central African Republic)
-Globalization.ci_shi = Tachelhit
-Globalization.ci_shi-Latn = Tachelhit (Latin)
-Globalization.ci_shi-Latn-MA = Tachelhit (Latin, Morocco)
-Globalization.ci_shi-Tfng = Tachelhit (Tifinagh)
-Globalization.ci_shi-Tfng-MA = Tachelhit (Tifinagh, Morocco)
-Globalization.ci_si = Sinhala
-Globalization.ci_si-LK = Sinhala (Sri Lanka)
-Globalization.ci_sk = Slovak
-Globalization.ci_sk-SK = Slovak (Slovakia)
-Globalization.ci_sl = Slovenian
-Globalization.ci_sl-SI = Slovenian (Slovenia)
-Globalization.ci_sma = Sami (Southern)
-Globalization.ci_sma-NO = Sami, Southern (Norway)
-Globalization.ci_sma-SE = Sami, Southern (Sweden)
-Globalization.ci_smj = Sami (Lule)
-Globalization.ci_smj-NO = Sami, Lule (Norway)
-Globalization.ci_smj-SE = Sami, Lule (Sweden)
-Globalization.ci_smn = Sami (Inari)
-Globalization.ci_smn-FI = Sami, Inari (Finland)
-Globalization.ci_sms = Sami (Skolt)
-Globalization.ci_sms-FI = Sami, Skolt (Finland)
-Globalization.ci_sn = Shona
-Globalization.ci_sn-Latn = Shona (Latin)
-Globalization.ci_sn-Latn-ZW = Shona (Latin, Zimbabwe)
-Globalization.ci_so = Somali
-Globalization.ci_so-DJ = Somali (Djibouti)
-Globalization.ci_so-ET = Somali (Ethiopia)
-Globalization.ci_so-KE = Somali (Kenya)
-Globalization.ci_so-SO = Somali (Somalia)
-Globalization.ci_sq = Albanian
-Globalization.ci_sq-AL = Albanian (Albania)
-Globalization.ci_sq-MK = Albanian (Macedonia, FYRO)
-Globalization.ci_sr = Serbian
-Globalization.ci_sr-Cyrl = Serbian (Cyrillic)
-Globalization.ci_sr-Cyrl-BA = Serbian (Cyrillic, Bosnia and Herzegovina)
-Globalization.ci_sr-Cyrl-CS = Serbian (Cyrillic, Serbia and Montenegro (Former))
-Globalization.ci_sr-Cyrl-ME = Serbian (Cyrillic, Montenegro)
-Globalization.ci_sr-Cyrl-RS = Serbian (Cyrillic, Serbia)
-Globalization.ci_sr-Latn = Serbian (Latin)
-Globalization.ci_sr-Latn-BA = Serbian (Latin, Bosnia and Herzegovina)
-Globalization.ci_sr-Latn-CS = Serbian (Latin, Serbia and Montenegro (Former))
-Globalization.ci_sr-Latn-ME = Serbian (Latin, Montenegro)
-Globalization.ci_sr-Latn-RS = Serbian (Latin, Serbia)
-Globalization.ci_ss = Swati
-Globalization.ci_ss-SZ = Swati (Swaziland)
-Globalization.ci_ss-ZA = Swati (South Africa)
-Globalization.ci_ssy = Saho
-Globalization.ci_ssy-ER = Saho (Eritrea)
-Globalization.ci_st = Southern Sotho
-Globalization.ci_st-LS = Sesotho (Lesotho)
-Globalization.ci_st-ZA = Southern Sotho (South Africa)
-Globalization.ci_sv = Swedish
-Globalization.ci_sv-AX = Swedish (Ã…land Islands)
-Globalization.ci_sv-FI = Swedish (Finland)
-Globalization.ci_sv-SE = Swedish (Sweden)
-Globalization.ci_sw = Kiswahili
-Globalization.ci_sw-KE = Kiswahili (Kenya)
-Globalization.ci_sw-TZ = Kiswahili (Tanzania)
-Globalization.ci_sw-UG = Kiswahili (Uganda)
-Globalization.ci_swc = Congo Swahili
-Globalization.ci_swc-CD = Congo Swahili (Congo DRC)
-Globalization.ci_syr = Syriac
-Globalization.ci_syr-SY = Syriac (Syria)
-Globalization.ci_ta = Tamil
-Globalization.ci_ta-IN = Tamil (India)
-Globalization.ci_ta-LK = Tamil (Sri Lanka)
-Globalization.ci_ta-MY = Tamil (Malaysia)
-Globalization.ci_ta-SG = Tamil (Singapore)
-Globalization.ci_te = Telugu
-Globalization.ci_te-IN = Telugu (India)
-Globalization.ci_teo = Teso
-Globalization.ci_teo-KE = Teso (Kenya)
-Globalization.ci_teo-UG = Teso (Uganda)
-Globalization.ci_tg = Tajik
-Globalization.ci_tg-Cyrl = Tajik (Cyrillic)
-Globalization.ci_tg-Cyrl-TJ = Tajik (Cyrillic, Tajikistan)
-Globalization.ci_th = Thai
-Globalization.ci_th-TH = Thai (Thailand)
-Globalization.ci_ti = Tigrinya
-Globalization.ci_ti-ER = Tigrinya (Eritrea)
-Globalization.ci_ti-ET = Tigrinya (Ethiopia)
-Globalization.ci_tig = Tigre
-Globalization.ci_tig-ER = Tigre (Eritrea)
-Globalization.ci_tk = Turkmen
-Globalization.ci_tk-TM = Turkmen (Turkmenistan)
-Globalization.ci_tn = Setswana
-Globalization.ci_tn-BW = Setswana (Botswana)
-Globalization.ci_tn-ZA = Setswana (South Africa)
-Globalization.ci_to = Tongan
-Globalization.ci_to-TO = Tongan (Tonga)
-Globalization.ci_tr = Turkish
-Globalization.ci_tr-CY = Turkish (Cyprus)
-Globalization.ci_tr-TR = Turkish (Turkey)
-Globalization.ci_ts = Tsonga
-Globalization.ci_ts-ZA = Tsonga (South Africa)
-Globalization.ci_tt = Tatar
-Globalization.ci_tt-RU = Tatar (Russia)
-Globalization.ci_twq = Tasawaq
-Globalization.ci_twq-NE = Tasawaq (Niger)
-Globalization.ci_tzm = Tamazight
-Globalization.ci_tzm-Latn = Tamazight (Latin)
-Globalization.ci_tzm-Latn-DZ = Tamazight (Latin, Algeria)
-Globalization.ci_tzm-Latn-MA = Central Atlas Tamazight (Latin, Morocco)
-Globalization.ci_tzm-Tfng = Tamazight (Tifinagh)
-Globalization.ci_tzm-Tfng-MA = Central Atlas Tamazight (Tifinagh, Morocco)
-Globalization.ci_ug = Uyghur
-Globalization.ci_ug-CN = Uyghur (PRC)
-Globalization.ci_uk = Ukrainian
-Globalization.ci_uk-UA = Ukrainian (Ukraine)
-Globalization.ci_ur = Urdu
-Globalization.ci_ur-IN = Urdu (India)
-Globalization.ci_ur-PK = Urdu (Islamic Republic of Pakistan)
-Globalization.ci_uz = Uzbek
-Globalization.ci_uz-Arab = Uzbek (Perso-Arabic)
-Globalization.ci_uz-Arab-AF = Uzbek (Perso-Arabic, Afghanistan)
-Globalization.ci_uz-Cyrl = Uzbek (Cyrillic)
-Globalization.ci_uz-Cyrl-UZ = Uzbek (Cyrillic, Uzbekistan)
-Globalization.ci_uz-Latn = Uzbek (Latin)
-Globalization.ci_uz-Latn-UZ = Uzbek (Latin, Uzbekistan)
-Globalization.ci_vai = Vai
-Globalization.ci_vai-Latn = Vai (Latin)
-Globalization.ci_vai-Latn-LR = Vai (Latin, Liberia)
-Globalization.ci_vai-Vaii = Vai (Vai)
-Globalization.ci_vai-Vaii-LR = Vai (Vai, Liberia)
-Globalization.ci_ve = Venda
-Globalization.ci_ve-ZA = Venda (South Africa)
-Globalization.ci_vi = Vietnamese
-Globalization.ci_vi-VN = Vietnamese (Vietnam)
-Globalization.ci_vo = Volapük
-Globalization.ci_vo-001 = Volapük (World)
-Globalization.ci_vun = Vunjo
-Globalization.ci_vun-TZ = Vunjo (Tanzania)
-Globalization.ci_wae = Walser
-Globalization.ci_wae-CH = Walser (Switzerland)
-Globalization.ci_wal = Wolaytta
-Globalization.ci_wal-ET = Wolaytta (Ethiopia)
-Globalization.ci_wo = Wolof
-Globalization.ci_wo-SN = Wolof (Senegal)
-Globalization.ci_x-IV = Invariant Language (Invariant Country)
-Globalization.ci_x-IV_mathan = Invariant Language (Invariant Country)
-Globalization.ci_xh = isiXhosa
-Globalization.ci_xh-ZA = isiXhosa (South Africa)
-Globalization.ci_xog = Soga
-Globalization.ci_xog-UG = Soga (Uganda)
-Globalization.ci_yav = Yangben
-Globalization.ci_yav-CM = Yangben (Cameroon)
-Globalization.ci_yi = Yiddish
-Globalization.ci_yi-001 = Yiddish (World)
-Globalization.ci_yo = Yoruba
-Globalization.ci_yo-BJ = Yoruba (Benin)
-Globalization.ci_yo-NG = Yoruba (Nigeria)
-Globalization.ci_zgh = Standard Moroccan Tamazight
-Globalization.ci_zgh-Tfng = Standard Moroccan Tamazight (Tifinagh)
-Globalization.ci_zgh-Tfng-MA = Standard Moroccan Tamazight (Tifinagh, Morocco)
-Globalization.ci_zh = Chinese
-Globalization.ci_zh-CHS = Chinese (Simplified) Legacy
-Globalization.ci_zh-CHT = Chinese (Traditional) Legacy
-Globalization.ci_zh-CN = Chinese (Simplified, PRC)
-Globalization.ci_zh-CN_stroke = Chinese (Simplified, PRC)
-Globalization.ci_zh-Hans = Chinese (Simplified)
-Globalization.ci_zh-Hant = Chinese (Traditional)
-Globalization.ci_zh-HK = Chinese (Traditional, Hong Kong S.A.R.)
-Globalization.ci_zh-HK_radstr = Chinese (Traditional, Hong Kong S.A.R.)
-Globalization.ci_zh-MO = Chinese (Traditional, Macao S.A.R.)
-Globalization.ci_zh-MO_radstr = Chinese (Traditional, Macao S.A.R.)
-Globalization.ci_zh-MO_stroke = Chinese (Traditional, Macao S.A.R.)
-Globalization.ci_zh-SG = Chinese (Simplified, Singapore)
-Globalization.ci_zh-SG_stroke = Chinese (Simplified, Singapore)
-Globalization.ci_zh-TW = Chinese (Traditional, Taiwan)
-Globalization.ci_zh-TW_pronun = Chinese (Traditional, Taiwan)
-Globalization.ci_zh-TW_radstr = Chinese (Traditional, Taiwan)
-Globalization.ci_zu = isiZulu
-Globalization.ci_zu-ZA = isiZulu (South Africa)
-;------------------
-;
-;Total items: 129
-;
-Globalization.ri_029 = Caribbean
-Globalization.ri_AE = U.A.E.
-Globalization.ri_AF = Afghanistan
-Globalization.ri_AL = Albania
-Globalization.ri_AM = Armenia
-Globalization.ri_AR = Argentina
-Globalization.ri_AT = Austria
-Globalization.ri_AU = Australia
-Globalization.ri_AZ = Azerbaijan
-Globalization.ri_BA = Bosnia and Herzegovina
-Globalization.ri_BD = Bangladesh
-Globalization.ri_BE = Belgium
-Globalization.ri_BG = Bulgaria
-Globalization.ri_BH = Bahrain
-Globalization.ri_BN = Brunei Darussalam
-Globalization.ri_BO = Bolivia
-Globalization.ri_BR = Brazil
-Globalization.ri_BY = Belarus
-Globalization.ri_BZ = Belize
-Globalization.ri_CA = Canada
-Globalization.ri_CH = Switzerland
-Globalization.ri_CL = Chile
-Globalization.ri_CN = People's Republic of China
-Globalization.ri_CO = Colombia
-Globalization.ri_CR = Costa Rica
-Globalization.ri_CS = Serbia and Montenegro (Former)
-Globalization.ri_CZ = Czech Republic
-Globalization.ri_DE = Germany
-Globalization.ri_DK = Denmark
-Globalization.ri_DO = Dominican Republic
-Globalization.ri_DZ = Algeria
-Globalization.ri_EC = Ecuador
-Globalization.ri_EE = Estonia
-Globalization.ri_EG = Egypt
-Globalization.ri_ER = Eritrea
-Globalization.ri_ES = Spain
-Globalization.ri_ET = Ethiopia
-Globalization.ri_FI = Finland
-Globalization.ri_FO = Faroe Islands
-Globalization.ri_FR = France
-Globalization.ri_GB = United Kingdom
-Globalization.ri_GE = Georgia
-Globalization.ri_GL = Greenland
-Globalization.ri_GR = Greece
-Globalization.ri_GT = Guatemala
-Globalization.ri_HK = Hong Kong S.A.R.
-Globalization.ri_HN = Honduras
-Globalization.ri_HR = Croatia
-Globalization.ri_HU = Hungary
-Globalization.ri_ID = Indonesia
-Globalization.ri_IE = Ireland
-Globalization.ri_IL = Israel
-Globalization.ri_IN = India
-Globalization.ri_IQ = Iraq
-Globalization.ri_IR = Iran
-Globalization.ri_IS = Iceland
-Globalization.ri_IT = Italy
-Globalization.ri_IV = Invariant Country
-Globalization.ri_JM = Jamaica
-Globalization.ri_JO = Jordan
-Globalization.ri_JP = Japan
-Globalization.ri_KE = Kenya
-Globalization.ri_KG = Kyrgyzstan
-Globalization.ri_KH = Cambodia
-Globalization.ri_KR = Korea
-Globalization.ri_KW = Kuwait
-Globalization.ri_KZ = Kazakhstan
-Globalization.ri_LA = Lao P.D.R.
-Globalization.ri_LB = Lebanon
-Globalization.ri_LI = Liechtenstein
-Globalization.ri_LK = Sri Lanka
-Globalization.ri_LT = Lithuania
-Globalization.ri_LU = Luxembourg
-Globalization.ri_LV = Latvia
-Globalization.ri_LY = Libya
-Globalization.ri_MA = Morocco
-Globalization.ri_MC = Principality of Monaco
-Globalization.ri_ME = Montenegro
-Globalization.ri_MK = Macedonia (FYROM)
-Globalization.ri_MN = Mongolia
-Globalization.ri_MO = Macao S.A.R.
-Globalization.ri_MT = Malta
-Globalization.ri_MV = Maldives
-Globalization.ri_MX = Mexico
-Globalization.ri_MY = Malaysia
-Globalization.ri_NG = Nigeria
-Globalization.ri_NI = Nicaragua
-Globalization.ri_NL = Netherlands
-Globalization.ri_NO = Norway
-Globalization.ri_NP = Nepal
-Globalization.ri_NZ = New Zealand
-Globalization.ri_OM = Oman
-Globalization.ri_PA = Panama
-Globalization.ri_PE = Peru
-Globalization.ri_PH = Philippines
-Globalization.ri_PK = Islamic Republic of Pakistan
-Globalization.ri_PL = Poland
-Globalization.ri_PR = Puerto Rico
-Globalization.ri_PT = Portugal
-Globalization.ri_PY = Paraguay
-Globalization.ri_QA = Qatar
-Globalization.ri_RO = Romania
-Globalization.ri_RS = Serbia
-Globalization.ri_RU = Russia
-Globalization.ri_RW = Rwanda
-Globalization.ri_SA = Saudi Arabia
-Globalization.ri_SE = Sweden
-Globalization.ri_SG = Singapore
-Globalization.ri_SI = Slovenia
-Globalization.ri_SK = Slovakia
-Globalization.ri_SN = Senegal
-Globalization.ri_SV = El Salvador
-Globalization.ri_SY = Syria
-Globalization.ri_TH = Thailand
-Globalization.ri_TJ = Tajikistan
-Globalization.ri_TM = Turkmenistan
-Globalization.ri_TN = Tunisia
-Globalization.ri_TR = Turkey
-Globalization.ri_TT = Trinidad and Tobago
-Globalization.ri_TW = Taiwan
-Globalization.ri_UA = Ukraine
-Globalization.ri_US = United States
-Globalization.ri_UY = Uruguay
-Globalization.ri_UZ = Uzbekistan
-Globalization.ri_VE = Bolivarian Republic of Venezuela
-Globalization.ri_VN = Vietnam
-Globalization.ri_YE = Yemen
-Globalization.ri_ZA = South Africa
-Globalization.ri_ZW = Zimbabwe
-#endif //!FEATURE_CORECLR
+; Buffers
+ArgumentException_BufferNotFromPool=The buffer is not associated with this pool and may not be returned to it.
;------------------
; Encoding names:
diff --git a/src/mscorlib/src/System/Action.cs b/src/mscorlib/src/System/Action.cs
index d6653c7979..27f7fafe5c 100644
--- a/src/mscorlib/src/System/Action.cs
+++ b/src/mscorlib/src/System/Action.cs
@@ -2,62 +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.
-//
-
-namespace System {
- using System.Runtime.CompilerServices;
-
+namespace System
+{
public delegate void Action<in T>(T obj);
// Action/Func delegates first shipped with .NET Framework 3.5 in System.Core.dll as part of LINQ
// These were type forwarded to mscorlib.dll in .NET Framework 4.0 and in Silverlight 5.0
-
-#if !FEATURE_CORECLR
- [TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
-#endif
public delegate void Action();
-
-#if !FEATURE_CORECLR
- [TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
-#endif
public delegate void Action<in T1,in T2>(T1 arg1, T2 arg2);
-
-#if !FEATURE_CORECLR
- [TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
-#endif
public delegate void Action<in T1,in T2,in T3>(T1 arg1, T2 arg2, T3 arg3);
-
-#if !FEATURE_CORECLR
- [TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
-#endif
public delegate void Action<in T1,in T2,in T3,in T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
-#if !FEATURE_CORECLR
- [TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
-#endif
public delegate TResult Func<out TResult>();
-
-#if !FEATURE_CORECLR
- [TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
-#endif
public delegate TResult Func<in T, out TResult>(T arg);
-
-#if !FEATURE_CORECLR
- [TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
-#endif
public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
-
-#if !FEATURE_CORECLR
- [TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
-#endif
public delegate TResult Func<in T1, in T2, in T3, out TResult>(T1 arg1, T2 arg2, T3 arg3);
-
-#if !FEATURE_CORECLR
- [TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
-#endif
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);
diff --git a/src/mscorlib/src/System/Activator.cs b/src/mscorlib/src/System/Activator.cs
index 274b0e7ec5..6fad8f3173 100644
--- a/src/mscorlib/src/System/Activator.cs
+++ b/src/mscorlib/src/System/Activator.cs
@@ -16,10 +16,6 @@ namespace System {
using System;
using System.Reflection;
using System.Runtime.Remoting;
-#if FEATURE_REMOTING
- using System.Runtime.Remoting.Activation;
- using Message = System.Runtime.Remoting.Messaging.Message;
-#endif
using System.Security;
using CultureInfo = System.Globalization.CultureInfo;
using Evidence = System.Security.Policy.Evidence;
@@ -34,7 +30,7 @@ namespace System {
// Only statics, does not need to be marked with the serializable attribute
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_Activator))]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public sealed class Activator : _Activator
{
internal const int LookupMask = 0x000000FF;
@@ -60,7 +56,6 @@ namespace System {
return CreateInstance(type, bindingAttr, binder, args, culture, null);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
static public Object CreateInstance(Type type,
BindingFlags bindingAttr,
@@ -70,7 +65,7 @@ namespace System {
Object[] activationAttributes)
{
if ((object)type == null)
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
Contract.EndContractBlock();
if (type is System.Reflection.Emit.TypeBuilder)
@@ -81,26 +76,13 @@ namespace System {
bindingAttr |= Activator.ConstructorDefault;
if (activationAttributes != null && activationAttributes.Length > 0){
- // If type does not derive from MBR
- // throw notsupportedexception
-#if FEATURE_REMOTING
- if(type.IsMarshalByRef){
- // The fix below is preventative.
- //
- if(!(type.IsContextful)){
- if(activationAttributes.Length > 1 || !(activationAttributes[0] is UrlAttribute))
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonUrlAttrOnMBR"));
- }
- }
- else
-#endif
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_ActivAttrOnNonMBR" ));
+ throw new PlatformNotSupportedException(Environment.GetResourceString("NotSupported_ActivAttr" ));
}
RuntimeType rt = type.UnderlyingSystemType as RuntimeType;
if (rt == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"type");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(type));
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return rt.CreateInstanceImpl(bindingAttr,binder,args,culture,activationAttributes, ref stackMark);
@@ -138,7 +120,6 @@ namespace System {
* types to be created remotely without having to load the type locally.
*/
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
static public ObjectHandle CreateInstance(String assemblyName,
String typeName)
@@ -156,7 +137,6 @@ namespace System {
ref stackMark);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
static public ObjectHandle CreateInstance(String assemblyName,
String typeName,
@@ -180,13 +160,13 @@ namespace System {
static public Object CreateInstance(Type type, bool nonPublic)
{
if ((object)type == null)
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
Contract.EndContractBlock();
RuntimeType rt = type.UnderlyingSystemType as RuntimeType;
if (rt == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "type");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(type));
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return rt.CreateInstanceDefaultCtor(!nonPublic, false, true, ref stackMark);
@@ -230,7 +210,6 @@ namespace System {
activationAttributes);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
[Obsolete("Methods which use evidence to sandbox are obsolete and will be removed in a future release of the .NET Framework. Please use an overload of CreateInstance which does not take an Evidence parameter. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
static public ObjectHandle CreateInstance(String assemblyName,
@@ -256,7 +235,6 @@ namespace System {
ref stackMark);
}
- [SecuritySafeCritical]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static ObjectHandle CreateInstance(string assemblyName,
string typeName,
@@ -280,7 +258,6 @@ namespace System {
ref stackMark);
}
- [System.Security.SecurityCritical] // auto-generated
static internal ObjectHandle CreateInstance(String assemblyString,
String typeName,
bool ignoreCase,
@@ -292,13 +269,6 @@ namespace System {
Evidence securityInfo,
ref StackCrawlMark stackMark)
{
-#if FEATURE_CAS_POLICY
- if (securityInfo != null && !AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyImplicit"));
- }
-#endif // FEATURE_CAS_POLICY
-
Type type = null;
Assembly assembly = null;
if (assemblyString == null) {
@@ -356,13 +326,6 @@ namespace System {
Evidence securityInfo)
{
-#if FEATURE_CAS_POLICY
- if (securityInfo != null && !AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyImplicit"));
- }
-#endif // FEATURE_CAS_POLICY
-
return CreateInstanceFromInternal(assemblyFile,
typeName,
ignoreCase,
@@ -404,10 +367,6 @@ namespace System {
Object[] activationAttributes,
Evidence securityInfo)
{
-#if FEATURE_CAS_POLICY
- Contract.Assert(AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled || securityInfo == null);
-#endif // FEATURE_CAS_POLICY
-
#pragma warning disable 618
Assembly assembly = Assembly.LoadFrom(assemblyFile, securityInfo);
#pragma warning restore 618
@@ -436,15 +395,13 @@ namespace System {
// to pass the security checks when activating the type.
//
- [System.Security.SecurityCritical] // auto-generated_required
public static ObjectHandle CreateInstance (AppDomain domain, string assemblyName, string typeName) {
if (domain == null)
- throw new ArgumentNullException("domain");
+ throw new ArgumentNullException(nameof(domain));
Contract.EndContractBlock();
return domain.InternalCreateInstanceWithNoSecurity(assemblyName, typeName);
}
- [System.Security.SecurityCritical] // auto-generated_required
[Obsolete("Methods which use evidence to sandbox are obsolete and will be removed in a future release of the .NET Framework. Please use an overload of CreateInstance which does not take an Evidence parameter. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
public static ObjectHandle CreateInstance (AppDomain domain,
string assemblyName,
@@ -457,20 +414,12 @@ namespace System {
Object[] activationAttributes,
Evidence securityAttributes) {
if (domain == null)
- throw new ArgumentNullException("domain");
+ throw new ArgumentNullException(nameof(domain));
Contract.EndContractBlock();
-#if FEATURE_CAS_POLICY
- if (securityAttributes != null && !AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyImplicit"));
- }
-#endif // FEATURE_CAS_POLICY
-
return domain.InternalCreateInstanceWithNoSecurity(assemblyName, typeName, ignoreCase, bindingAttr, binder, args, culture, activationAttributes, securityAttributes);
}
- [SecurityCritical]
public static ObjectHandle CreateInstance(AppDomain domain,
string assemblyName,
string typeName,
@@ -482,7 +431,7 @@ namespace System {
object[] activationAttributes)
{
if (domain == null)
- throw new ArgumentNullException("domain");
+ throw new ArgumentNullException(nameof(domain));
Contract.EndContractBlock();
return domain.InternalCreateInstanceWithNoSecurity(assemblyName,
@@ -503,15 +452,13 @@ namespace System {
// to pass the security checks when activating the type.
//
- [System.Security.SecurityCritical] // auto-generated_required
public static ObjectHandle CreateInstanceFrom (AppDomain domain, string assemblyFile, string typeName) {
if (domain == null)
- throw new ArgumentNullException("domain");
+ throw new ArgumentNullException(nameof(domain));
Contract.EndContractBlock();
return domain.InternalCreateInstanceFromWithNoSecurity(assemblyFile, typeName);
}
- [System.Security.SecurityCritical] // auto-generated_required
[Obsolete("Methods which use Evidence to sandbox are obsolete and will be removed in a future release of the .NET Framework. Please use an overload of CreateInstanceFrom which does not take an Evidence parameter. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
public static ObjectHandle CreateInstanceFrom (AppDomain domain,
string assemblyFile,
@@ -524,20 +471,12 @@ namespace System {
Object[] activationAttributes,
Evidence securityAttributes) {
if (domain == null)
- throw new ArgumentNullException("domain");
+ throw new ArgumentNullException(nameof(domain));
Contract.EndContractBlock();
-#if FEATURE_CAS_POLICY
- if (securityAttributes != null && !AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyImplicit"));
- }
-#endif // FEATURE_CAS_POLICY
-
return domain.InternalCreateInstanceFromWithNoSecurity(assemblyFile, typeName, ignoreCase, bindingAttr, binder, args, culture, activationAttributes, securityAttributes);
}
- [SecurityCritical]
public static ObjectHandle CreateInstanceFrom(AppDomain domain,
string assemblyFile,
string typeName,
@@ -549,7 +488,7 @@ namespace System {
object[] activationAttributes)
{
if (domain == null)
- throw new ArgumentNullException("domain");
+ throw new ArgumentNullException(nameof(domain));
Contract.EndContractBlock();
return domain.InternalCreateInstanceFromWithNoSecurity(assemblyFile,
@@ -563,28 +502,8 @@ namespace System {
null);
}
-#if FEATURE_CLICKONCE
- [System.Security.SecuritySafeCritical] // auto-generated
- public static ObjectHandle CreateInstance (ActivationContext activationContext) {
- AppDomainManager domainManager = AppDomain.CurrentDomain.DomainManager;
- if (domainManager == null)
- domainManager = new AppDomainManager();
-
- return domainManager.ApplicationActivator.CreateInstance(activationContext);
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public static ObjectHandle CreateInstance (ActivationContext activationContext, string[] activationCustomData) {
- AppDomainManager domainManager = AppDomain.CurrentDomain.DomainManager;
- if (domainManager == null)
- domainManager = new AppDomainManager();
-
- return domainManager.ApplicationActivator.CreateInstance(activationContext, activationCustomData);
- }
-#endif // FEATURE_CLICKONCE
-
public static ObjectHandle CreateComInstanceFrom(String assemblyName,
- String typeName)
+ String typeName)
{
return CreateComInstanceFrom(assemblyName,
typeName,
@@ -630,38 +549,11 @@ namespace System {
}
}
-#if FEATURE_REMOTING
- // This method is a helper method and delegates to the remoting
- // services to do the actual work.
- [System.Security.SecurityCritical] // auto-generated_required
- static public Object GetObject(Type type, String url)
- {
- return GetObject(type, url, null);
- }
-
- // This method is a helper method and delegates to the remoting
- // services to do the actual work.
- [System.Security.SecurityCritical] // auto-generated_required
- static public Object GetObject(Type type, String url, Object state)
- {
- if (type == null)
- throw new ArgumentNullException("type");
- Contract.EndContractBlock();
- return RemotingServices.Connect(type, url, state);
- }
-#endif
-
[System.Diagnostics.Conditional("_DEBUG")]
private static void Log(bool test, string title, string success, string failure)
{
-#if FEATURE_REMOTING
- if(test)
- BCLDebug.Trace("REMOTE", "{0}{1}", title, success);
- else
- BCLDebug.Trace("REMOTE", "{0}{1}", title, failure);
-#endif
}
-
+
void _Activator.GetTypeInfoCount(out uint pcTInfo)
{
throw new NotImplementedException();
diff --git a/src/mscorlib/src/System/AggregateException.cs b/src/mscorlib/src/System/AggregateException.cs
index 064432aaaa..c0f21229ed 100644
--- a/src/mscorlib/src/System/AggregateException.cs
+++ b/src/mscorlib/src/System/AggregateException.cs
@@ -69,7 +69,7 @@ namespace System
{
if (innerException == null)
{
- throw new ArgumentNullException("innerException");
+ throw new ArgumentNullException(nameof(innerException));
}
m_innerExceptions = new ReadOnlyCollection<Exception>(new Exception[] { innerException });
@@ -149,7 +149,7 @@ namespace System
{
if (innerExceptions == null)
{
- throw new ArgumentNullException("innerExceptions");
+ throw new ArgumentNullException(nameof(innerExceptions));
}
// Copy exceptions to our internal array and validate them. We must copy them,
@@ -227,7 +227,7 @@ namespace System
{
if (innerExceptionInfos == null)
{
- throw new ArgumentNullException("innerExceptionInfos");
+ throw new ArgumentNullException(nameof(innerExceptionInfos));
}
// Copy exceptions to our internal array and validate them. We must copy them,
@@ -258,13 +258,12 @@ namespace System
/// contains contextual information about the source or destination. </param>
/// <exception cref="T:System.ArgumentNullException">The <paramref name="info"/> argument is null.</exception>
/// <exception cref="T:System.Runtime.Serialization.SerializationException">The exception could not be deserialized correctly.</exception>
- [SecurityCritical]
protected AggregateException(SerializationInfo info, StreamingContext context) :
base(info, context)
{
if (info == null)
{
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Exception[] innerExceptions = info.GetValue("InnerExceptions", typeof(Exception[])) as Exception[];
@@ -285,12 +284,11 @@ namespace System
/// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that
/// contains contextual information about the source or destination. </param>
/// <exception cref="T:System.ArgumentNullException">The <paramref name="info"/> argument is null.</exception>
- [SecurityCritical]
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
{
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
base.GetObjectData(info, context);
@@ -351,7 +349,7 @@ namespace System
{
if (predicate == null)
{
- throw new ArgumentNullException("predicate");
+ throw new ArgumentNullException(nameof(predicate));
}
List<Exception> unhandledExceptions = null;
@@ -379,7 +377,8 @@ namespace System
/// <summary>
- /// Flattens an <see cref="AggregateException"/> instances into a single, new instance.
+ /// Flattens the inner instances of <see cref="AggregateException"/> by expanding its contained <see cref="Exception"/> instances
+ /// into a new <see cref="AggregateException"/>
/// </summary>
/// <returns>A new, flattened <see cref="AggregateException"/>.</returns>
/// <remarks>
diff --git a/src/mscorlib/src/System/AppContext/AppContext.cs b/src/mscorlib/src/System/AppContext/AppContext.cs
index 0b0643d7b4..41e44508f0 100644
--- a/src/mscorlib/src/System/AppContext/AppContext.cs
+++ b/src/mscorlib/src/System/AppContext/AppContext.cs
@@ -21,9 +21,6 @@ namespace System
public static string BaseDirectory
{
-#if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical]
-#endif
get
{
// The value of APP_CONTEXT_BASE_DIRECTORY key has to be a string and it is not allowed to be any other type.
@@ -41,14 +38,53 @@ namespace System
}
}
-#if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical]
-#endif
public static object GetData(string name)
{
return AppDomain.CurrentDomain.GetData(name);
}
+ public static void SetData(string name, object data)
+ {
+ AppDomain.CurrentDomain.SetData(name, data);
+ }
+
+ public static event UnhandledExceptionEventHandler UnhandledException
+ {
+ add
+ {
+ AppDomain.CurrentDomain.UnhandledException += value;
+ }
+
+ remove
+ {
+ AppDomain.CurrentDomain.UnhandledException -= value;
+ }
+ }
+
+ public static event System.EventHandler<System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs> FirstChanceException
+ {
+ add
+ {
+ AppDomain.CurrentDomain.FirstChanceException += value;
+ }
+ remove
+ {
+ AppDomain.CurrentDomain.FirstChanceException -= value;
+ }
+ }
+
+ public static event System.EventHandler ProcessExit
+ {
+ add
+ {
+ AppDomain.CurrentDomain.ProcessExit += value;
+ }
+ remove
+ {
+ AppDomain.CurrentDomain.ProcessExit -= value;
+ }
+ }
+
#region Switch APIs
static AppContext()
{
@@ -65,9 +101,9 @@ namespace System
public static bool TryGetSwitch(string switchName, out bool isEnabled)
{
if (switchName == null)
- throw new ArgumentNullException("switchName");
+ throw new ArgumentNullException(nameof(switchName));
if (switchName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "switchName");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(switchName));
// By default, the switch is not enabled.
isEnabled = false;
@@ -161,9 +197,9 @@ namespace System
public static void SetSwitch(string switchName, bool isEnabled)
{
if (switchName == null)
- throw new ArgumentNullException("switchName");
+ throw new ArgumentNullException(nameof(switchName));
if (switchName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "switchName");
+ throw new ArgumentException(Environment.GetResourceString("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 c80913e3a6..52bdf9d427 100644
--- a/src/mscorlib/src/System/AppContext/AppContextDefaultValues.Defaults.cs
+++ b/src/mscorlib/src/System/AppContext/AppContextDefaultValues.Defaults.cs
@@ -12,10 +12,6 @@ namespace System
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";
-#if FEATURE_PATHCOMPAT
- internal static readonly string SwitchUseLegacyPathHandling = "Switch.System.IO.UseLegacyPathHandling";
- internal static readonly string SwitchBlockLongPaths = "Switch.System.IO.BlockLongPaths";
-#endif
// This is a partial method. Platforms can provide an implementation of it that will set override values
// from whatever mechanism is available on that platform. If no implementation is provided, the compiler is going to remove the calls
@@ -43,13 +39,7 @@ namespace System
AppContext.DefineSwitchDefault(SwitchNoAsyncCurrentCulture, true);
AppContext.DefineSwitchDefault(SwitchThrowExceptionIfDisposedCancellationTokenSource, true);
}
-#if FEATURE_PATHCOMPAT
- if (version <= 40601)
- {
- AppContext.DefineSwitchDefault(SwitchUseLegacyPathHandling, true);
- AppContext.DefineSwitchDefault(SwitchBlockLongPaths, true);
- }
-#endif
+
break;
}
case "WindowsPhone":
diff --git a/src/mscorlib/src/System/AppContext/AppContextDefaultValues.cs b/src/mscorlib/src/System/AppContext/AppContextDefaultValues.cs
index 7ab7ffbc04..9f00e8148c 100644
--- a/src/mscorlib/src/System/AppContext/AppContextDefaultValues.cs
+++ b/src/mscorlib/src/System/AppContext/AppContextDefaultValues.cs
@@ -30,7 +30,6 @@ namespace System
if (!TryParseFrameworkName(targetFrameworkMoniker, out identifier, out version, out profile))
{
-#if FEATURE_CORECLR
// If we can't parse the TFM or we don't have a TFM, default to latest behavior for all
// switches (ie. all of them false).
// If we want to use the latest behavior it is enough to set the value of the switch to string.Empty.
@@ -39,11 +38,6 @@ namespace System
// identifier we are simply saying -- don't turn on any switches, and we are going to get the latest
// behavior for all the switches
identifier = string.Empty;
-#else
- identifier = ".NETFramework";
- version = 40000;
- profile = string.Empty;
-#endif
}
}
diff --git a/src/mscorlib/src/System/AppContext/AppContextSwitches.cs b/src/mscorlib/src/System/AppContext/AppContextSwitches.cs
index 3a96ec2159..5fdd2bc1e6 100644
--- a/src/mscorlib/src/System/AppContext/AppContextSwitches.cs
+++ b/src/mscorlib/src/System/AppContext/AppContextSwitches.cs
@@ -39,36 +39,6 @@ namespace System
}
}
-#if FEATURE_PATHCOMPAT
- private static int _useLegacyPathHandling;
-
- /// <summary>
- /// Use legacy path normalization logic and blocking of extended syntax.
- /// </summary>
- public static bool UseLegacyPathHandling
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get
- {
- return GetCachedSwitchValue(AppContextDefaultValues.SwitchUseLegacyPathHandling, ref _useLegacyPathHandling);
- }
- }
-
- private static int _blockLongPaths;
-
- /// <summary>
- /// Throw PathTooLongException for paths greater than MAX_PATH or directories greater than 248 (as per CreateDirectory Win32 limitations)
- /// </summary>
- public static bool BlockLongPaths
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get
- {
- return GetCachedSwitchValue(AppContextDefaultValues.SwitchBlockLongPaths, ref _blockLongPaths);
- }
- }
-#endif // FEATURE_PATHCOMPAT
-
//
// Implementation details
//
diff --git a/src/mscorlib/src/System/AppDomain.cs b/src/mscorlib/src/System/AppDomain.cs
index abaaf48770..fe524c4dc5 100644
--- a/src/mscorlib/src/System/AppDomain.cs
+++ b/src/mscorlib/src/System/AppDomain.cs
@@ -13,46 +13,29 @@
**
=============================================================================*/
-namespace System {
+namespace System
+{
using System;
-#if FEATURE_CLICKONCE
- using System.Deployment.Internal.Isolation;
- using System.Deployment.Internal.Isolation.Manifest;
- using System.Runtime.Hosting;
-#endif
using System.Reflection;
using System.Runtime;
using System.Runtime.CompilerServices;
-#if FEATURE_REMOTING
- using System.Runtime.Remoting.Channels;
- using System.Runtime.Remoting.Contexts;
-#endif
using System.Security;
using System.Security.Permissions;
-#if FEATURE_IMPERSONATION
- using System.Security.Principal;
-#endif
using System.Security.Policy;
using System.Security.Util;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Runtime.InteropServices;
- using System.Runtime.Remoting;
-#if FEATURE_REMOTING
- using Context = System.Runtime.Remoting.Contexts.Context;
-#endif
+ using System.Runtime.Remoting;
using System.Reflection.Emit;
using CultureInfo = System.Globalization.CultureInfo;
-#if !FEATURE_CORECLR
- using System.Globalization;
-#endif
using System.IO;
using AssemblyHashAlgorithm = System.Configuration.Assemblies.AssemblyHashAlgorithm;
using System.Text;
- using Microsoft.Win32;
using System.Runtime.ConstrainedExecution;
using System.Runtime.Versioning;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
#if FEATURE_EXCEPTION_NOTIFICATIONS
using System.Runtime.ExceptionServices;
@@ -107,10 +90,6 @@ namespace System {
}
}
-
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
[Serializable]
[ComVisible(true)]
public delegate Assembly ResolveEventHandler(Object sender, ResolveEventArgs args);
@@ -177,7 +156,6 @@ namespace System {
Info = itemInfo.ToArray();
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal AppDomainInitializer Unwrap()
{
if (Info==null)
@@ -204,17 +182,13 @@ namespace System {
[ComDefaultInterface(typeof(System._AppDomain))]
[ComVisible(true)]
public sealed class AppDomain :
-#if FEATURE_REMOTING
- MarshalByRefObject,
-#endif
_AppDomain, IEvidenceFactory
{
// Domain security information
// These fields initialized from the other side only. (NOTE: order
// of these fields cannot be changed without changing the layout in
- // the EE)
+ // the EE- AppDomainBaseObject in this case)
- [System.Security.SecurityCritical] // auto-generated
private AppDomainManager _domainManager;
private Dictionary<String, Object[]> _LocalStore;
private AppDomainSetup _FusionStore;
@@ -225,12 +199,10 @@ namespace System {
[method: System.Security.SecurityCritical]
public event AssemblyLoadEventHandler AssemblyLoad;
- [System.Security.SecurityCritical]
private ResolveEventHandler _TypeResolve;
public event ResolveEventHandler TypeResolve
{
- [System.Security.SecurityCritical]
add
{
lock (this)
@@ -239,7 +211,6 @@ namespace System {
}
}
- [System.Security.SecurityCritical]
remove
{
lock (this)
@@ -249,12 +220,10 @@ namespace System {
}
}
- [System.Security.SecurityCritical]
private ResolveEventHandler _ResourceResolve;
public event ResolveEventHandler ResourceResolve
{
- [System.Security.SecurityCritical]
add
{
lock (this)
@@ -263,7 +232,6 @@ namespace System {
}
}
- [System.Security.SecurityCritical]
remove
{
lock (this)
@@ -273,12 +241,10 @@ namespace System {
}
}
- [System.Security.SecurityCritical]
private ResolveEventHandler _AssemblyResolve;
public event ResolveEventHandler AssemblyResolve
{
- [System.Security.SecurityCritical]
add
{
lock (this)
@@ -287,7 +253,6 @@ namespace System {
}
}
- [System.Security.SecurityCritical]
remove
{
lock (this)
@@ -302,38 +267,13 @@ namespace System {
public event ResolveEventHandler ReflectionOnlyAssemblyResolve;
#endif // FEATURE_REFLECTION_ONLY
-#if FEATURE_REMOTING
- private Context _DefaultContext;
-#endif
-
-#if FEATURE_CLICKONCE
- private ActivationContext _activationContext;
- private ApplicationIdentity _applicationIdentity;
-#endif
private ApplicationTrust _applicationTrust;
-
-#if FEATURE_IMPERSONATION
- private IPrincipal _DefaultPrincipal;
-#endif // FEATURE_IMPERSONATION
-#if FEATURE_REMOTING
- private DomainSpecificRemotingData _RemotingData;
-#endif
private EventHandler _processExit;
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical]
- #endif
private EventHandler _domainUnload;
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
private UnhandledExceptionEventHandler _unhandledException;
-#if FEATURE_APTCA
- private String[] _aptcaVisibleAssemblies;
-#endif
-
// 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.
@@ -346,9 +286,6 @@ namespace System {
private IntPtr _pDomain; // this is an unmanaged pointer (AppDomain * m_pDomain)` used from the VM.
-#if FEATURE_CAS_POLICY
- private PrincipalPolicy _PrincipalPolicy; // this is an enum
-#endif
private bool _HasSetPolicy;
private bool _IsFastFullTrustDomain; // quick check to see if the AppDomain is fully trusted and homogenous
private bool _compatFlagsInitialized;
@@ -378,20 +315,18 @@ namespace System {
private static APPX_FLAGS Flags
{
- [SecuritySafeCritical]
get
{
if (s_flags == 0)
s_flags = nGetAppXFlags();
- Contract.Assert(s_flags != 0);
+ Debug.Assert(s_flags != 0);
return s_flags;
}
}
internal static bool ProfileAPICheck
{
- [SecuritySafeCritical]
get
{
return (Flags & APPX_FLAGS.APPX_FLAGS_API_CHECK) != 0;
@@ -400,7 +335,6 @@ namespace System {
internal static bool IsAppXNGen
{
- [SecuritySafeCritical]
get
{
return (Flags & APPX_FLAGS.APPX_FLAGS_APPX_NGEN) != 0;
@@ -409,56 +343,37 @@ namespace System {
#endif // FEATURE_APPX
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SecurityCritical]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool DisableFusionUpdatesFromADManager(AppDomainHandle domain);
#if FEATURE_APPX
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SecurityCritical]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.I4)]
private static extern APPX_FLAGS nGetAppXFlags();
#endif
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SecurityCritical]
[SuppressUnmanagedCodeSecurity]
private static extern void GetAppDomainManagerType(AppDomainHandle domain,
StringHandleOnStack retAssembly,
StringHandleOnStack retType);
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SecurityCritical]
[SuppressUnmanagedCodeSecurity]
private static extern void SetAppDomainManagerType(AppDomainHandle domain,
string assembly,
string type);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void nSetHostSecurityManagerFlags (HostSecurityManagerOptions flags);
- [SecurityCritical]
[SuppressUnmanagedCodeSecurity]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
private static extern void SetSecurityHomogeneousFlag(AppDomainHandle domain,
[MarshalAs(UnmanagedType.Bool)] bool runtimeSuppliedHomogenousGrantSet);
-#if FEATURE_CAS_POLICY
- [SecurityCritical]
- [SuppressUnmanagedCodeSecurity]
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- private static extern void SetLegacyCasPolicyEnabled(AppDomainHandle domain);
-
- [SecurityCritical]
- private void SetLegacyCasPolicyEnabled()
- {
- SetLegacyCasPolicyEnabled(GetNativeHandle());
- }
-#endif // FEATURE_CAS_POLICY
-
/// <summary>
/// Get a handle used to make a call into the VM pointing to this domain
/// </summary>
@@ -471,9 +386,6 @@ namespace System {
throw new InvalidOperationException(Environment.GetResourceString("Argument_InvalidHandle"));
}
-#if FEATURE_REMOTING
- BCLDebug.Assert(!RemotingServices.IsTransparentProxy(this), "QCalls should be made with the real AppDomain object rather than a transparent proxy");
-#endif // FEATURE_REMOTING
return new AppDomainHandle(_pDomain);
}
@@ -481,10 +393,9 @@ namespace System {
/// If this AppDomain is configured to have an AppDomain manager then create the instance of it.
/// This method is also called from the VM to create the domain manager in the default domain.
/// </summary>
- [SecuritySafeCritical]
private void CreateAppDomainManager()
{
- Contract.Assert(_domainManager == null, "_domainManager == null");
+ Debug.Assert(_domainManager == null, "_domainManager == null");
AppDomainSetup adSetup = FusionStore;
#if FEATURE_VERSIONING
@@ -566,17 +477,9 @@ namespace System {
if (notifyFusion)
SetupFusionStore(_FusionStore, FusionStoreOld); // Notify Fusion about the changes the user implementation of InitializeNewDomain may have made to the FusionStore object.
-
-#if FEATURE_APPDOMAINMANAGER_INITOPTIONS
- AppDomainManagerInitializationOptions flags = _domainManager.InitializationFlags;
- if ((flags & AppDomainManagerInitializationOptions.RegisterWithHost) == AppDomainManagerInitializationOptions.RegisterWithHost)
- {
- _domainManager.RegisterWithHost();
- }
-#endif // FEATURE_APPDOMAINMANAGER_INITOPTIONS
}
- InitializeCompatibilityFlags();
+ InitializeCompatibilityFlags();
}
/// <summary>
@@ -596,7 +499,7 @@ namespace System {
// for perf, we don't intialize the _compatFlags dictionary when we don't need to. However, we do need to make a
// note that we've run this method, because IsCompatibilityFlagsSet needs to return different values for the
// case where the compat flags have been setup.
- Contract.Assert(!_compatFlagsInitialized);
+ Debug.Assert(!_compatFlagsInitialized);
_compatFlagsInitialized = true;
CompatibilitySwitches.InitializeSwitches();
@@ -606,7 +509,6 @@ namespace System {
// either by a host in native, a host in managed using an AppDomainSetup, or by the
// TargetFrameworkAttribute on the executable (VS emits its target framework moniker using this
// attribute starting in version 4).
- [SecuritySafeCritical]
internal String GetTargetFrameworkName()
{
String targetFrameworkName = _FusionStore.TargetFrameworkName;
@@ -621,7 +523,7 @@ namespace System {
TargetFrameworkAttribute[] attrs = (TargetFrameworkAttribute[])assembly.GetCustomAttributes(typeof(TargetFrameworkAttribute));
if (attrs != null && attrs.Length > 0)
{
- Contract.Assert(attrs.Length == 1);
+ Debug.Assert(attrs.Length == 1);
targetFrameworkName = attrs[0].FrameworkName;
_FusionStore.TargetFrameworkName = targetFrameworkName;
}
@@ -635,7 +537,6 @@ namespace System {
/// <summary>
/// Returns the setting of the corresponding compatibility config switch (see CreateAppDomainManager for the impact).
/// </summary>
- [SecuritySafeCritical]
internal bool DisableFusionUpdatesFromADManager()
{
return DisableFusionUpdatesFromADManager(GetNativeHandle());
@@ -644,7 +545,6 @@ namespace System {
/// <summary>
/// Returns whether the current AppDomain follows the AppX rules.
/// </summary>
- [SecuritySafeCritical]
[Pure]
internal static bool IsAppXModel()
{
@@ -658,7 +558,6 @@ namespace System {
/// <summary>
/// Returns the setting of the AppXDevMode config switch.
/// </summary>
- [SecuritySafeCritical]
[Pure]
internal static bool IsAppXDesignMode()
{
@@ -672,7 +571,6 @@ namespace System {
/// <summary>
/// Checks (and throws on failure) if the domain supports Assembly.LoadFrom.
/// </summary>
- [SecuritySafeCritical]
[Pure]
internal static void CheckLoadFromSupported()
{
@@ -685,7 +583,6 @@ namespace System {
/// <summary>
/// Checks (and throws on failure) if the domain supports Assembly.LoadFile.
/// </summary>
- [SecuritySafeCritical]
[Pure]
internal static void CheckLoadFileSupported()
{
@@ -698,7 +595,6 @@ namespace System {
/// <summary>
/// Checks (and throws on failure) if the domain supports Assembly.ReflectionOnlyLoad.
/// </summary>
- [SecuritySafeCritical]
[Pure]
internal static void CheckReflectionOnlyLoadSupported()
{
@@ -711,7 +607,6 @@ namespace System {
/// <summary>
/// Checks (and throws on failure) if the domain supports Assembly.LoadWithPartialName.
/// </summary>
- [SecuritySafeCritical]
[Pure]
internal static void CheckLoadWithPartialNameSupported(StackCrawlMark stackMark)
{
@@ -731,7 +626,6 @@ namespace System {
/// <summary>
/// Checks (and throws on failure) if the domain supports DefinePInvokeMethod.
/// </summary>
- [SecuritySafeCritical]
[Pure]
internal static void CheckDefinePInvokeSupported()
{
@@ -745,7 +639,6 @@ namespace System {
/// <summary>
/// Checks (and throws on failure) if the domain supports Assembly.Load(byte[] ...).
/// </summary>
- [SecuritySafeCritical]
[Pure]
internal static void CheckLoadByteArraySupported()
{
@@ -758,7 +651,6 @@ namespace System {
/// <summary>
/// Checks (and throws on failure) if the domain supports AppDomain.CreateDomain.
/// </summary>
- [SecuritySafeCritical]
[Pure]
internal static void CheckCreateDomainSupported()
{
@@ -779,7 +671,6 @@ namespace System {
/// <summary>
/// Get the name of the assembly and type that act as the AppDomainManager for this domain
/// </summary>
- [SecuritySafeCritical]
internal void GetAppDomainManagerType(out string assembly, out string type)
{
// We can't just use our parameters because we need to ensure that the strings used for hte QCall
@@ -798,77 +689,16 @@ namespace System {
/// <summary>
/// Set the assembly and type which act as the AppDomainManager for this domain
/// </summary>
- [SecuritySafeCritical]
private void SetAppDomainManagerType(string assembly, string type)
{
- Contract.Assert(assembly != null, "assembly != null");
- Contract.Assert(type != null, "type != null");
+ Debug.Assert(assembly != null, "assembly != null");
+ Debug.Assert(type != null, "type != null");
SetAppDomainManagerType(GetNativeHandle(), assembly, type);
}
-#if FEATURE_APTCA
- internal String[] PartialTrustVisibleAssemblies
- {
- get { return _aptcaVisibleAssemblies; }
-
- [SecuritySafeCritical]
- set
- {
- _aptcaVisibleAssemblies = value;
-
- // Build up the canonical representaiton of this list to allow the VM to do optimizations in
- // common cases
- string canonicalConditionalAptcaList = null;
- if (value != null)
- {
- StringBuilder conditionalAptcaListBuilder = StringBuilderCache.Acquire();
- for (int i = 0; i < value.Length; ++i)
- {
- if (value[i] != null)
- {
- conditionalAptcaListBuilder.Append(value[i].ToUpperInvariant());
- if (i != value.Length - 1)
- {
- conditionalAptcaListBuilder.Append(';');
- }
- }
- }
-
- canonicalConditionalAptcaList = StringBuilderCache.GetStringAndRelease(conditionalAptcaListBuilder);
- }
-
- SetCanonicalConditionalAptcaList(canonicalConditionalAptcaList);
- }
- }
-
- [SecurityCritical]
- [SuppressUnmanagedCodeSecurity]
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- private static extern void SetCanonicalConditionalAptcaList(AppDomainHandle appDomain, string canonicalList);
-
- [SecurityCritical]
- private void SetCanonicalConditionalAptcaList(string canonicalList)
- {
- SetCanonicalConditionalAptcaList(GetNativeHandle(), canonicalList);
- }
-#endif // FEATURE_APTCA
-
-#if FEATURE_CLICKONCE
- /// <summary>
- /// If the CLR is being started up to run a ClickOnce applicaiton, setup the default AppDomain
- /// with information about that application.
- /// </summary>
- private void SetupDefaultClickOnceDomain(string fullName, string[] manifestPaths, string[] activationData)
- {
- Contract.Requires(fullName != null, "fullName != null");
- FusionStore.ActivationArguments = new ActivationArguments(fullName, manifestPaths, activationData);
- }
-#endif // FEATURE_CLICKONCE
-
/// <summary>
/// Called for every AppDomain (including the default domain) to initialize the security of the AppDomain)
/// </summary>
- [SecurityCritical]
private void InitializeDomainSecurity(Evidence providedSecurityInfo,
Evidence creatorsSecurityInfo,
bool generateDefaultEvidence,
@@ -877,91 +707,23 @@ namespace System {
{
AppDomainSetup adSetup = FusionStore;
-#if FEATURE_CAS_POLICY
- // If the AppDomain is setup to use legacy CAS policy, then set that bit in the application
- // security descriptor.
- if (CompatibilitySwitches.IsNetFx40LegacySecurityPolicy)
- {
- SetLegacyCasPolicyEnabled();
- }
-#endif // FEATURE_CAS_POLICY
-
-#if FEATURE_CLICKONCE
-
- // Check if the domain manager set an ActivationContext (Debug-In-Zone for example)
- // or if this is an AppDomain with an ApplicationTrust.
- if (adSetup.ActivationArguments != null) {
- // Merge the new evidence with the manifest's evidence if applicable
- ActivationContext activationContext = null;
- ApplicationIdentity appIdentity = null;
- string[] activationData = null;
- CmsUtils.CreateActivationContext(adSetup.ActivationArguments.ApplicationFullName,
- adSetup.ActivationArguments.ApplicationManifestPaths,
- adSetup.ActivationArguments.UseFusionActivationContext,
- out appIdentity, out activationContext);
- activationData = adSetup.ActivationArguments.ActivationData;
- providedSecurityInfo = CmsUtils.MergeApplicationEvidence(providedSecurityInfo,
- appIdentity,
- activationContext,
- activationData,
- adSetup.ApplicationTrust);
- SetupApplicationHelper(providedSecurityInfo, creatorsSecurityInfo, appIdentity, activationContext, activationData);
- }
- else
-#endif // FEATURE_CLICKONCE
- {
- bool runtimeSuppliedHomogenousGrant = false;
- ApplicationTrust appTrust = adSetup.ApplicationTrust;
-
-#if FEATURE_CAS_POLICY
- // In non-legacy CAS mode, domains should be homogenous. If the host has not specified a sandbox
- // of their own, we'll set it up to be fully trusted. We must read the IsLegacyCasPolicy
- // enabled property here rathern than just reading the switch from above because the entire
- // process may also be opted into legacy CAS policy mode.
- if (appTrust == null && !IsLegacyCasPolicyEnabled) {
- _IsFastFullTrustDomain = true;
- runtimeSuppliedHomogenousGrant = true;
- }
-#endif // FEATURE_CAS_POLICY
+ bool runtimeSuppliedHomogenousGrant = false;
+ ApplicationTrust appTrust = adSetup.ApplicationTrust;
- if (appTrust != null) {
- SetupDomainSecurityForHomogeneousDomain(appTrust, runtimeSuppliedHomogenousGrant);
- }
- else if (_IsFastFullTrustDomain) {
- SetSecurityHomogeneousFlag(GetNativeHandle(), runtimeSuppliedHomogenousGrant);
- }
+ if (appTrust != null) {
+ SetupDomainSecurityForHomogeneousDomain(appTrust, runtimeSuppliedHomogenousGrant);
+ }
+ 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 FEATURE_CAS_POLICY
- newAppDomainEvidence = new Evidence(new AppDomainEvidenceFactory(this));
-#else // !FEATURE_CAS_POLICY
newAppDomainEvidence = new Evidence();
-#endif // FEATURE_CAS_POLICY
}
-#if FEATURE_CAS_POLICY
- if (_domainManager != null) {
- // Give the host a chance to alter the AppDomain evidence
- HostSecurityManager securityManager = _domainManager.HostSecurityManager;
- if (securityManager != null) {
- nSetHostSecurityManagerFlags (securityManager.Flags);
- if ((securityManager.Flags & HostSecurityManagerOptions.HostAppDomainEvidence) == HostSecurityManagerOptions.HostAppDomainEvidence) {
- newAppDomainEvidence = securityManager.ProvideAppDomainEvidence(newAppDomainEvidence);
- // If this is a disconnected evidence collection, then attach it to the AppDomain,
- // allowing the host security manager to get callbacks for delay generated evidence
- if (newAppDomainEvidence != null && newAppDomainEvidence.Target == null) {
- newAppDomainEvidence.Target = new AppDomainEvidenceFactory(this);
- }
- }
- }
- }
-
-#endif // FEATURE_CAS_POLICY
-
// Set the evidence on the managed side
_SecurityIdentity = newAppDomainEvidence;
@@ -971,106 +733,8 @@ namespace System {
SetupDomainSecurity(newAppDomainEvidence,
parentSecurityDescriptor,
publishAppDomain);
-
-#if FEATURE_CAS_POLICY
- // The AppDomain is now resolved. Go ahead and set the PolicyLevel
- // from the HostSecurityManager if specified.
- if (_domainManager != null)
- RunDomainManagerPostInitialization(_domainManager);
-#endif // FEATURE_CAS_POLICY
- }
-
-#if FEATURE_CAS_POLICY
- [System.Security.SecurityCritical] // auto-generated
- private void RunDomainManagerPostInitialization (AppDomainManager domainManager)
- {
- // force creation of the HostExecutionContextManager for the current AppDomain
- HostExecutionContextManager contextManager = domainManager.HostExecutionContextManager;
-
- if (IsLegacyCasPolicyEnabled)
- {
-#pragma warning disable 618
- HostSecurityManager securityManager = domainManager.HostSecurityManager;
- if (securityManager != null)
- {
- if ((securityManager.Flags & HostSecurityManagerOptions.HostPolicyLevel) == HostSecurityManagerOptions.HostPolicyLevel)
- {
- // set AppDomain policy if specified
- PolicyLevel level = securityManager.DomainPolicy;
- if (level != null)
- SetAppDomainPolicy(level);
- }
- }
-#pragma warning restore 618
- }
- }
-#endif
-
-
-#if FEATURE_CLICKONCE
-
- [System.Security.SecurityCritical] // auto-generated
- private void SetupApplicationHelper (Evidence providedSecurityInfo, Evidence creatorsSecurityInfo, ApplicationIdentity appIdentity, ActivationContext activationContext, string[] activationData) {
- Contract.Requires(providedSecurityInfo != null);
- HostSecurityManager securityManager = AppDomain.CurrentDomain.HostSecurityManager;
- ApplicationTrust appTrust = securityManager.DetermineApplicationTrust(providedSecurityInfo, creatorsSecurityInfo, new TrustManagerContext());
- if (appTrust == null || !appTrust.IsApplicationTrustedToRun)
- throw new PolicyException(Environment.GetResourceString("Policy_NoExecutionPermission"),
- System.__HResults.CORSEC_E_NO_EXEC_PERM,
- null);
-
- // The application is trusted to run. Set up the AppDomain according to the manifests.
- if (activationContext != null)
- SetupDomainForApplication(activationContext, activationData);
- SetupDomainSecurityForApplication(appIdentity, appTrust);
- }
-
- [System.Security.SecurityCritical] // auto-generated
- private void SetupDomainForApplication(ActivationContext activationContext, string[] activationData) {
- Contract.Requires(activationContext != null);
- if (IsDefaultAppDomain()) {
- // make the ActivationArguments available off the AppDomain object.
- AppDomainSetup adSetup = this.FusionStore;
- adSetup.ActivationArguments = new ActivationArguments(activationContext, activationData);
-
- // set the application base to point at where the application resides
- string entryPointPath = CmsUtils.GetEntryPointFullPath(activationContext);
- if (!String.IsNullOrEmpty(entryPointPath))
- adSetup.SetupDefaults(entryPointPath);
- else
- adSetup.ApplicationBase = activationContext.ApplicationDirectory;
-
- // update fusion context
- SetupFusionStore(adSetup, null);
- }
-
- // perform app data directory migration.
- activationContext.PrepareForExecution();
- activationContext.SetApplicationState(ActivationContext.ApplicationState.Starting);
- // set current app data directory.
- activationContext.SetApplicationState(ActivationContext.ApplicationState.Running);
-
- // make data directory path available.
- IPermission permission = null;
- string dataDirectory = activationContext.DataDirectory;
- if (dataDirectory != null && dataDirectory.Length > 0)
- permission = new FileIOPermission(FileIOPermissionAccess.PathDiscovery, dataDirectory);
- this.SetData("DataDirectory", dataDirectory, permission);
-
- _activationContext = activationContext;
- }
-
- [System.Security.SecurityCritical] // auto-generated
- private void SetupDomainSecurityForApplication(ApplicationIdentity appIdentity,
- ApplicationTrust appTrust)
- {
- // Set the Application trust on the managed side.
- _applicationIdentity = appIdentity;
- SetupDomainSecurityForHomogeneousDomain(appTrust, false);
}
-#endif // FEATURE_CLICKONCE
- [System.Security.SecurityCritical] // auto-generated
private void SetupDomainSecurityForHomogeneousDomain(ApplicationTrust appTrust,
bool runtimeSuppliedHomogenousGrantSet)
{
@@ -1084,9 +748,6 @@ namespace System {
if (runtimeSuppliedHomogenousGrantSet)
{
BCLDebug.Assert(_FusionStore.ApplicationTrust != null, "Expected to find runtime supplied ApplicationTrust");
-#if FEATURE_CAS_POLICY
- _FusionStore.ApplicationTrust = null;
-#endif // FEATURE_CAS_POLICY
}
_applicationTrust = appTrust;
@@ -1096,38 +757,13 @@ namespace System {
runtimeSuppliedHomogenousGrantSet);
}
- // This method is called from CorHost2::ExecuteApplication to activate a ClickOnce application in the default AppDomain.
-#if FEATURE_CLICKONCE
- [System.Security.SecuritySafeCritical] // auto-generated
- private int ActivateApplication () {
- ObjectHandle oh = Activator.CreateInstance(AppDomain.CurrentDomain.ActivationContext);
- return (int) oh.Unwrap();
- }
-#endif //FEATURE_CLICKONCE
-
public AppDomainManager DomainManager {
- [System.Security.SecurityCritical] // auto-generated_required
get {
return _domainManager;
}
}
-#if FEATURE_CAS_POLICY
- internal HostSecurityManager HostSecurityManager {
- [System.Security.SecurityCritical] // auto-generated
- get {
- HostSecurityManager securityManager = null;
- AppDomainManager domainManager = AppDomain.CurrentDomain.DomainManager;
- if (domainManager != null)
- securityManager = domainManager.HostSecurityManager;
-
- if (securityManager == null)
- securityManager = new HostSecurityManager();
- return securityManager;
- }
- }
-#endif // FEATURE_CAS_POLICY
-#if FEATURE_REFLECTION_ONLY_LOAD
+#if FEATURE_REFLECTION_ONLY_LOAD
private Assembly ResolveAssemblyForIntrospection(Object sender, ResolveEventArgs args)
{
Contract.Requires(args != null);
@@ -1143,7 +779,6 @@ namespace System {
_packageGraphFilePaths = packageGraphFilePaths;
}
- [System.Security.SecurityCritical]
public void ResolveNamespace(
object sender,
System.Runtime.InteropServices.WindowsRuntime.NamespaceResolveEventArgs args)
@@ -1162,7 +797,6 @@ namespace System {
}
// Called only by native function code:ValidateWorker
- [System.Security.SecuritySafeCritical]
private void EnableResolveAssembliesForIntrospection(string verifiedFileDirectory)
{
CurrentDomain.ReflectionOnlyAssemblyResolve += new ResolveEventHandler(ResolveAssemblyForIntrospection);
@@ -1183,7 +817,6 @@ namespace System {
* to have a strong name and a hash will be computed when the assembly
* is saved.
**********************************************/
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public AssemblyBuilder DefineDynamicAssembly(
AssemblyName name,
@@ -1196,7 +829,6 @@ namespace System {
null, null, null, null, ref stackMark, null, SecurityContextSource.CurrentAssembly);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public AssemblyBuilder DefineDynamicAssembly(
AssemblyName name,
@@ -1214,7 +846,6 @@ namespace System {
}
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Due to the stack crawl mark
- [SecuritySafeCritical]
public AssemblyBuilder DefineDynamicAssembly(AssemblyName name,
AssemblyBuilderAccess access,
IEnumerable<CustomAttributeBuilder> assemblyAttributes,
@@ -1231,7 +862,6 @@ namespace System {
securityContextSource);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public AssemblyBuilder DefineDynamicAssembly(
AssemblyName name,
@@ -1248,7 +878,6 @@ namespace System {
SecurityContextSource.CurrentAssembly);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
[Obsolete("Assembly level declarative security is obsolete and is no longer enforced by the CLR by default. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
public AssemblyBuilder DefineDynamicAssembly(
@@ -1266,7 +895,6 @@ namespace System {
SecurityContextSource.CurrentAssembly);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
[Obsolete("Assembly level declarative security is obsolete and is no longer enforced by the CLR by default. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
public AssemblyBuilder DefineDynamicAssembly(
@@ -1288,7 +916,6 @@ namespace System {
SecurityContextSource.CurrentAssembly);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
[Obsolete("Methods which use evidence to sandbox are obsolete and will be removed in a future release of the .NET Framework. Please use an overload of DefineDynamicAssembly which does not take an Evidence parameter. See http://go.microsoft.com/fwlink/?LinkId=155570 for more information.")]
public AssemblyBuilder DefineDynamicAssembly(
@@ -1304,7 +931,6 @@ namespace System {
null, null, null, ref stackMark, null, SecurityContextSource.CurrentAssembly);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
[Obsolete("Assembly level declarative security is obsolete and is no longer enforced by the CLR by default. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
public AssemblyBuilder DefineDynamicAssembly(
@@ -1327,7 +953,6 @@ namespace System {
SecurityContextSource.CurrentAssembly);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
[Obsolete("Assembly level declarative security is obsolete and is no longer enforced by the CLR by default. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
public AssemblyBuilder DefineDynamicAssembly(
@@ -1351,7 +976,6 @@ namespace System {
SecurityContextSource.CurrentAssembly);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
[Obsolete("Assembly level declarative security is obsolete and is no longer enforced by the CLR by default. Please see http://go.microsoft.com/fwlink/?LinkId=155570 for more information.")]
public AssemblyBuilder DefineDynamicAssembly(
@@ -1376,8 +1000,6 @@ namespace System {
SecurityContextSource.CurrentAssembly);
}
-
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
[Obsolete("Assembly level declarative security is obsolete and is no longer enforced by the CLR by default. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
public AssemblyBuilder DefineDynamicAssembly(
@@ -1405,7 +1027,6 @@ namespace System {
SecurityContextSource.CurrentAssembly);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
[Obsolete("Assembly level declarative security is obsolete and is no longer enforced by the CLR by default. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
public AssemblyBuilder DefineDynamicAssembly(
@@ -1434,7 +1055,6 @@ namespace System {
SecurityContextSource.CurrentAssembly);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public AssemblyBuilder DefineDynamicAssembly(
AssemblyName name,
@@ -1458,7 +1078,6 @@ namespace System {
SecurityContextSource.CurrentAssembly);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
private AssemblyBuilder InternalDefineDynamicAssembly(
AssemblyName name,
@@ -1484,7 +1103,6 @@ namespace System {
securityContextSource);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern String nApplyPolicy(AssemblyName an);
@@ -1506,7 +1124,6 @@ namespace System {
return nApplyPolicy(asmName);
}
-
public ObjectHandle CreateInstance(String assemblyName,
String typeName)
@@ -1516,14 +1133,13 @@ namespace System {
throw new NullReferenceException();
if (assemblyName == null)
- throw new ArgumentNullException("assemblyName");
+ throw new ArgumentNullException(nameof(assemblyName));
Contract.EndContractBlock();
return Activator.CreateInstance(assemblyName,
typeName);
}
- [System.Security.SecurityCritical] // auto-generated
internal ObjectHandle InternalCreateInstanceWithNoSecurity (string assemblyName, string typeName) {
PermissionSet.s_fullTrust.Assert();
return CreateInstance(assemblyName, typeName);
@@ -1542,7 +1158,6 @@ namespace System {
typeName);
}
- [System.Security.SecurityCritical] // auto-generated
internal ObjectHandle InternalCreateInstanceFromWithNoSecurity (string assemblyName, string typeName) {
PermissionSet.s_fullTrust.Assert();
return CreateInstanceFrom(assemblyName, typeName);
@@ -1591,7 +1206,7 @@ namespace System {
throw new NullReferenceException();
if (assemblyName == null)
- throw new ArgumentNullException("assemblyName");
+ throw new ArgumentNullException(nameof(assemblyName));
Contract.EndContractBlock();
return Activator.CreateInstance(assemblyName,
@@ -1630,16 +1245,9 @@ namespace System {
throw new NullReferenceException();
if (assemblyName == null)
- throw new ArgumentNullException("assemblyName");
+ throw new ArgumentNullException(nameof(assemblyName));
Contract.EndContractBlock();
-#if FEATURE_CAS_POLICY
- if (securityAttributes != null && !IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyImplicit"));
- }
-#endif // FEATURE_CAS_POLICY
-
#pragma warning disable 618
return Activator.CreateInstance(assemblyName,
typeName,
@@ -1667,7 +1275,7 @@ namespace System {
throw new NullReferenceException();
if (assemblyName == null)
- throw new ArgumentNullException("assemblyName");
+ throw new ArgumentNullException(nameof(assemblyName));
Contract.EndContractBlock();
return Activator.CreateInstance(assemblyName,
@@ -1680,7 +1288,6 @@ namespace System {
activationAttributes);
}
- [System.Security.SecurityCritical] // auto-generated
internal ObjectHandle InternalCreateInstanceWithNoSecurity (string assemblyName,
string typeName,
bool ignoreCase,
@@ -1691,10 +1298,6 @@ namespace System {
Object[] activationAttributes,
Evidence securityAttributes)
{
-#if FEATURE_CAS_POLICY
- Contract.Assert(IsLegacyCasPolicyEnabled || securityAttributes == null);
-#endif // FEATURE_CAS_POLICY
-
PermissionSet.s_fullTrust.Assert();
#pragma warning disable 618
return CreateInstance(assemblyName, typeName, ignoreCase, bindingAttr, binder, args, culture, activationAttributes, securityAttributes);
@@ -1718,13 +1321,6 @@ namespace System {
throw new NullReferenceException();
Contract.EndContractBlock();
-#if FEATURE_CAS_POLICY
- if (securityAttributes != null && !IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyImplicit"));
- }
-#endif // FEATURE_CAS_POLICY
-
return Activator.CreateInstanceFrom(assemblyFile,
typeName,
ignoreCase,
@@ -1760,7 +1356,6 @@ namespace System {
activationAttributes);
}
- [System.Security.SecurityCritical] // auto-generated
internal ObjectHandle InternalCreateInstanceFromWithNoSecurity (string assemblyName,
string typeName,
bool ignoreCase,
@@ -1771,17 +1366,12 @@ namespace System {
Object[] activationAttributes,
Evidence securityAttributes)
{
-#if FEATURE_CAS_POLICY
- Contract.Assert(IsLegacyCasPolicyEnabled || securityAttributes == null);
-#endif // FEATURE_CAS_POLICY
-
PermissionSet.s_fullTrust.Assert();
#pragma warning disable 618
return CreateInstanceFrom(assemblyName, typeName, ignoreCase, bindingAttr, binder, args, culture, activationAttributes, securityAttributes);
#pragma warning restore 618
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public Assembly Load(AssemblyName assemblyRef)
{
@@ -1789,7 +1379,6 @@ namespace System {
return RuntimeAssembly.InternalLoadAssemblyName(assemblyRef, null, null, ref stackMark, true /*thrownOnFileNotFound*/, false, false);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public Assembly Load(String assemblyString)
{
@@ -1797,7 +1386,6 @@ namespace System {
return RuntimeAssembly.InternalLoad(assemblyString, null, ref stackMark, false);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public Assembly Load(byte[] rawAssembly)
{
@@ -1811,7 +1399,6 @@ namespace System {
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public Assembly Load(byte[] rawAssembly,
byte[] rawSymbolStore)
@@ -1825,23 +1412,12 @@ namespace System {
SecurityContextSource.CurrentAssembly);
}
- [System.Security.SecuritySafeCritical] // auto-generated
-#pragma warning disable 618
- [SecurityPermissionAttribute(SecurityAction.Demand, ControlEvidence = true)]
-#pragma warning restore 618
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
[Obsolete("Methods which use evidence to sandbox are obsolete and will be removed in a future release of the .NET Framework. Please use an overload of Load which does not take an Evidence parameter. See http://go.microsoft.com/fwlink/?LinkId=155570 for more information.")]
public Assembly Load(byte[] rawAssembly,
byte[] rawSymbolStore,
Evidence securityEvidence)
{
-#if FEATURE_CAS_POLICY
- if (securityEvidence != null && !IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyImplicit"));
- }
-#endif // FEATURE_CAS_POLICY
-
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return RuntimeAssembly.nLoadImage(rawAssembly,
rawSymbolStore,
@@ -1851,7 +1427,6 @@ namespace System {
SecurityContextSource.CurrentAssembly);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
[Obsolete("Methods which use evidence to sandbox are obsolete and will be removed in a future release of the .NET Framework. Please use an overload of Load which does not take an Evidence parameter. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
public Assembly Load(AssemblyName assemblyRef,
@@ -1861,7 +1436,6 @@ namespace System {
return RuntimeAssembly.InternalLoadAssemblyName(assemblyRef, assemblySecurity, null, ref stackMark, true /*thrownOnFileNotFound*/, false, false);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
[Obsolete("Methods which use evidence to sandbox are obsolete and will be removed in a future release of the .NET Framework. Please use an overload of Load which does not take an Evidence parameter. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
public Assembly Load(String assemblyString,
@@ -1888,15 +1462,8 @@ namespace System {
Evidence assemblySecurity,
String[] args)
{
-#if FEATURE_CAS_POLICY
- if (assemblySecurity != null && !IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyImplicit"));
- }
-#endif // FEATURE_CAS_POLICY
-
RuntimeAssembly assembly = (RuntimeAssembly)Assembly.LoadFrom(assemblyFile, assemblySecurity);
-
+
if (args == null)
args = new String[0];
@@ -1920,13 +1487,6 @@ namespace System {
byte[] hashValue,
AssemblyHashAlgorithm hashAlgorithm)
{
-#if FEATURE_CAS_POLICY
- if (assemblySecurity != null && !IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyImplicit"));
- }
-#endif // FEATURE_CAS_POLICY
-
RuntimeAssembly assembly = (RuntimeAssembly)Assembly.LoadFrom(assemblyFile,
assemblySecurity,
hashValue,
@@ -1951,9 +1511,6 @@ namespace System {
return nExecuteAssembly(assembly, args);
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
public int ExecuteAssemblyByName(String assemblyName)
{
return ExecuteAssemblyByName(assemblyName, (string[])null);
@@ -1973,15 +1530,8 @@ namespace System {
Evidence assemblySecurity,
params String[] args)
{
-#if FEATURE_CAS_POLICY
- if (assemblySecurity != null && !IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyImplicit"));
- }
-#endif // FEATURE_CAS_POLICY
-
RuntimeAssembly assembly = (RuntimeAssembly)Assembly.Load(assemblyName, assemblySecurity);
-
+
if (args == null)
args = new String[0];
@@ -2003,15 +1553,8 @@ namespace System {
Evidence assemblySecurity,
params String[] args)
{
-#if FEATURE_CAS_POLICY
- if (assemblySecurity != null && !IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyImplicit"));
- }
-#endif // FEATURE_CAS_POLICY
-
RuntimeAssembly assembly = (RuntimeAssembly)Assembly.Load(assemblyName, assemblySecurity);
-
+
if (args == null)
args = new String[0];
@@ -2036,114 +1579,28 @@ namespace System {
}
}
-#if FEATURE_CAS_POLICY
- public Evidence Evidence
- {
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute(SecurityAction.Demand, ControlEvidence = true)]
- get {
- return EvidenceNoDemand;
- }
- }
-
- internal Evidence EvidenceNoDemand {
- [SecurityCritical]
- get {
- if (_SecurityIdentity == null) {
- if (!IsDefaultAppDomain() && nIsDefaultAppDomainForEvidence()) {
-#if !FEATURE_CORECLR
- //
- // V1.x compatibility: If this is an AppDomain created
- // by the default appdomain without an explicit evidence
- // then reuse the evidence of the default AppDomain.
- //
- return GetDefaultDomain().Evidence;
-#else
- Contract.Assert(false,"This code should not be called for core CLR");
-
- // This operation is not allowed
- throw new InvalidOperationException();
-#endif
- }
- else {
- // We can't cache this value, since the VM needs to differentiate between AppDomains
- // which have no user supplied evidence and those which do and it uses the presence
- // of Evidence on the domain to make that switch.
- return new Evidence(new AppDomainEvidenceFactory(this));
- }
- }
- else {
- return _SecurityIdentity.Clone();
- }
- }
- }
-
- internal Evidence InternalEvidence
- {
- get {
- return _SecurityIdentity;
- }
- }
-
- internal EvidenceBase GetHostEvidence(Type type)
- {
- if (_SecurityIdentity != null)
- {
- return _SecurityIdentity.GetHostEvidence(type);
- }
- else
- {
- return new Evidence(new AppDomainEvidenceFactory(this)).GetHostEvidence(type);
- }
- }
-#endif // FEATURE_CAS_POLICY
-
public String FriendlyName
{
- [System.Security.SecuritySafeCritical] // auto-generated
get { return nGetFriendlyName(); }
}
public String BaseDirectory
{
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical]
-#endif
get {
return FusionStore.ApplicationBase;
}
}
-#if FEATURE_FUSION
- public String RelativeSearchPath
- {
- get { return FusionStore.PrivateBinPath; }
- }
-
- public bool ShadowCopyFiles
- {
- get {
- String s = FusionStore.ShadowCopyFiles;
- if((s != null) &&
- (String.Compare(s, "true", StringComparison.OrdinalIgnoreCase) == 0))
- return true;
- else
- return false;
- }
- }
-#endif
-
- [System.Security.SecuritySafeCritical] // auto-generated
public override String ToString()
{
StringBuilder sb = StringBuilderCache.Acquire();
-
+
String fn = nGetFriendlyName();
if (fn != null) {
sb.Append(Environment.GetResourceString("Loader_Name") + fn);
sb.Append(Environment.NewLine);
}
-
+
if(_Policies == null || _Policies.Length == 0)
sb.Append(Environment.GetResourceString("Loader_NoContextPolicies")
+ Environment.NewLine);
@@ -2164,222 +1621,67 @@ namespace System {
return nGetAssemblies(false /* forIntrospection */);
}
-
public Assembly[] ReflectionOnlyGetAssemblies()
{
return nGetAssemblies(true /* forIntrospection */);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern Assembly[] nGetAssemblies(bool forIntrospection);
// this is true when we've removed the handles etc so really can't do anything
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern bool IsUnloadingForcedFinalize();
- // this is true when we've just started going through the finalizers and are forcing objects to finalize
- // so must be aware that certain infrastructure may have gone away
- [System.Security.SecuritySafeCritical] // auto-generated
+ // this is true when we've just started going through the finalizers and are forcing objects to finalize
+ // so must be aware that certain infrastructure may have gone away
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern bool IsFinalizingForUnload();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void PublishAnonymouslyHostedDynamicMethodsAssembly(RuntimeAssembly assemblyHandle);
-#if FEATURE_FUSION
- // Appends the following string to the private path. Valid paths
- // are of the form "bin;util/i386" etc.
- [System.Security.SecurityCritical] // auto-generated_required
- [Obsolete("AppDomain.AppendPrivatePath has been deprecated. Please investigate the use of AppDomainSetup.PrivateBinPath instead. http://go.microsoft.com/fwlink/?linkid=14202")]
- public void AppendPrivatePath(String path)
- {
- if(path == null || path.Length == 0)
- return;
-
- String current = FusionStore.Value[(int) AppDomainSetup.LoaderInformation.PrivateBinPathValue];
- StringBuilder appendPath = StringBuilderCache.Acquire();
-
- if(current != null && current.Length > 0) {
- // See if the last character is a separator
- appendPath.Append(current);
- if((current[current.Length-1] != Path.PathSeparator) &&
- (path[0] != Path.PathSeparator))
- appendPath.Append(Path.PathSeparator);
- }
- appendPath.Append(path);
-
- String result = StringBuilderCache.GetStringAndRelease(appendPath);
- InternalSetPrivateBinPath(result);
- }
-
-
- [System.Security.SecurityCritical] // auto-generated_required
- [Obsolete("AppDomain.ClearPrivatePath has been deprecated. Please investigate the use of AppDomainSetup.PrivateBinPath instead. http://go.microsoft.com/fwlink/?linkid=14202")]
- public void ClearPrivatePath()
- {
- InternalSetPrivateBinPath(String.Empty);
- }
-
- [System.Security.SecurityCritical] // auto-generated_required
- [Obsolete("AppDomain.ClearShadowCopyPath has been deprecated. Please investigate the use of AppDomainSetup.ShadowCopyDirectories instead. http://go.microsoft.com/fwlink/?linkid=14202")]
- public void ClearShadowCopyPath()
- {
- InternalSetShadowCopyPath(String.Empty);
- }
-
- [System.Security.SecurityCritical] // auto-generated_required
- [Obsolete("AppDomain.SetCachePath has been deprecated. Please investigate the use of AppDomainSetup.CachePath instead. http://go.microsoft.com/fwlink/?linkid=14202")]
- public void SetCachePath(String path)
- {
- InternalSetCachePath(path);
- }
-#endif // FEATURE_FUSION
-
- [System.Security.SecurityCritical] // auto-generated_required
public void SetData (string name, object data) {
-#if FEATURE_CORECLR
- if (!name.Equals("LOCATION_URI"))
- {
- // Only LOCATION_URI can be set using AppDomain.SetData
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_SetData_OnlyLocationURI", name));
- }
-#endif // FEATURE_CORECLR
SetDataHelper(name, data, null);
}
- [System.Security.SecurityCritical] // auto-generated_required
- public void SetData (string name, object data, IPermission permission) {
-#if FEATURE_CORECLR
+ public void SetData (string name, object data, IPermission permission)
+ {
if (!name.Equals("LOCATION_URI"))
{
// Only LOCATION_URI can be set using AppDomain.SetData
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_SetData_OnlyLocationURI", name));
}
-#endif // FEATURE_CORECLR
+
SetDataHelper(name, data, permission);
}
- [System.Security.SecurityCritical] // auto-generated
- private void SetDataHelper (string name, object data, IPermission permission) {
+ private void SetDataHelper (string name, object data, IPermission permission)
+ {
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
Contract.EndContractBlock();
- //
- // Synopsis:
- // IgnoreSystemPolicy is provided as a legacy flag to allow callers to
- // skip enterprise, machine and user policy levels. When this flag is set,
- // any demands triggered in this AppDomain will be evaluated against the
- // AppDomain CAS policy level that is set on the AppDomain.
- // Security Requirements:
- // The caller needs to be fully trusted in order to be able to set
- // this legacy mode.
- // Remarks:
- // There needs to be an AppDomain policy level set before this compat
- // switch can be set on the AppDomain.
- //
-#if FEATURE_FUSION
- if (name.Equals(TargetFrameworkNameAppCompatSetting)) {
- _FusionStore.TargetFrameworkName = (String) data;
- return;
- }
-#if FEATURE_CAS_POLICY
- if (name.Equals("IgnoreSystemPolicy")) {
- lock (this) {
- if (!_HasSetPolicy)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_SetData"));
- }
- new PermissionSet(PermissionState.Unrestricted).Demand();
- }
-#endif
- int key = AppDomainSetup.Locate(name);
-
- if(key == -1) {
- lock (((ICollection)LocalStore).SyncRoot) {
- LocalStore[name] = new object[] {data, permission};
- }
- }
- else {
- if (permission != null)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_SetData"));
- // Be sure to call these properties, not Value, since
- // these do more than call Value.
- switch(key) {
- case (int) AppDomainSetup.LoaderInformation.DynamicBaseValue:
- FusionStore.DynamicBase = (string) data;
- break;
- case (int) AppDomainSetup.LoaderInformation.DevPathValue:
- FusionStore.DeveloperPath = (string) data;
- break;
- case (int) AppDomainSetup.LoaderInformation.ShadowCopyDirectoriesValue:
- FusionStore.ShadowCopyDirectories = (string) data;
- break;
- case (int) AppDomainSetup.LoaderInformation.DisallowPublisherPolicyValue:
- if(data != null)
- FusionStore.DisallowPublisherPolicy = true;
- else
- FusionStore.DisallowPublisherPolicy = false;
- break;
- case (int) AppDomainSetup.LoaderInformation.DisallowCodeDownloadValue:
- if (data != null)
- FusionStore.DisallowCodeDownload = true;
- else
- FusionStore.DisallowCodeDownload = false;
- break;
- case (int) AppDomainSetup.LoaderInformation.DisallowBindingRedirectsValue:
- if(data != null)
- FusionStore.DisallowBindingRedirects = true;
- else
- FusionStore.DisallowBindingRedirects = false;
- break;
- case (int) AppDomainSetup.LoaderInformation.DisallowAppBaseProbingValue:
- if(data != null)
- FusionStore.DisallowApplicationBaseProbing = true;
- else
- FusionStore.DisallowApplicationBaseProbing = false;
- break;
- case (int) AppDomainSetup.LoaderInformation.ConfigurationBytesValue:
- FusionStore.SetConfigurationBytes((byte[]) data);
- break;
- default:
- FusionStore.Value[key] = (string) data;
- break;
- }
- }
-#else // FEATURE_FUSION
-#if FEATURE_CORECLR
// SetData should only be used to set values that don't already exist.
+ object[] currentVal;
+ lock (((ICollection)LocalStore).SyncRoot) {
+ LocalStore.TryGetValue(name, out currentVal);
+ }
+ if (currentVal != null && currentVal[0] != null)
{
- object[] currentVal;
- lock (((ICollection)LocalStore).SyncRoot) {
- LocalStore.TryGetValue(name, out currentVal);
- }
- if (currentVal != null && currentVal[0] != null)
- {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_SetData_OnlyOnce"));
- }
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_SetData_OnlyOnce"));
}
-#endif // FEATURE_CORECLR
lock (((ICollection)LocalStore).SyncRoot) {
LocalStore[name] = new object[] {data, permission};
}
-#endif // FEATURE_FUSION
}
[Pure]
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #else
- [System.Security.SecuritySafeCritical]
- #endif
public Object GetData(string name)
{
if(name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
Contract.EndContractBlock();
int key = AppDomainSetup.Locate(name);
@@ -2412,43 +1714,11 @@ namespace System {
return FusionStore.ApplicationBase;
case (int) AppDomainSetup.LoaderInformation.ApplicationNameValue:
return FusionStore.ApplicationName;
-#if FEATURE_FUSION
- case (int) AppDomainSetup.LoaderInformation.ConfigurationFileValue:
- return FusionStore.ConfigurationFile;
- case (int) AppDomainSetup.LoaderInformation.DynamicBaseValue:
- return FusionStore.DynamicBase;
- case (int) AppDomainSetup.LoaderInformation.DevPathValue:
- return FusionStore.DeveloperPath;
- case (int) AppDomainSetup.LoaderInformation.PrivateBinPathValue:
- return FusionStore.PrivateBinPath;
- case (int) AppDomainSetup.LoaderInformation.PrivateBinPathProbeValue:
- return FusionStore.PrivateBinPathProbe;
- case (int) AppDomainSetup.LoaderInformation.ShadowCopyDirectoriesValue:
- return FusionStore.ShadowCopyDirectories;
- case (int) AppDomainSetup.LoaderInformation.ShadowCopyFilesValue:
- return FusionStore.ShadowCopyFiles;
- case (int) AppDomainSetup.LoaderInformation.CachePathValue:
- return FusionStore.CachePath;
- case (int) AppDomainSetup.LoaderInformation.LicenseFileValue:
- return FusionStore.LicenseFile;
- case (int) AppDomainSetup.LoaderInformation.DisallowPublisherPolicyValue:
- return FusionStore.DisallowPublisherPolicy;
- case (int) AppDomainSetup.LoaderInformation.DisallowCodeDownloadValue:
- return FusionStore.DisallowCodeDownload;
- case (int) AppDomainSetup.LoaderInformation.DisallowBindingRedirectsValue:
- return FusionStore.DisallowBindingRedirects;
- case (int) AppDomainSetup.LoaderInformation.DisallowAppBaseProbingValue:
- return FusionStore.DisallowApplicationBaseProbing;
- case (int) AppDomainSetup.LoaderInformation.ConfigurationBytesValue:
- return FusionStore.GetConfigurationBytes();
-#endif //FEATURE_FUSION
-
default:
- Contract.Assert(false, "Need to handle new LoaderInformation value in AppDomain.GetData()");
+ Debug.Assert(false, "Need to handle new LoaderInformation value in AppDomain.GetData()");
return null;
}
}
-
}
// The compat flags are set at domain creation time to indicate that the given breaking
@@ -2477,84 +1747,8 @@ namespace System {
[DllImport(Microsoft.Win32.Win32Native.KERNEL32)]
public static extern int GetCurrentThreadId();
-#if FEATURE_REMOTING
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute( SecurityAction.Demand, ControlAppDomain = true ),
- ReliabilityContract(Consistency.MayCorruptAppDomain, Cer.MayFail)]
- public static void Unload(AppDomain domain)
+ internal ApplicationTrust ApplicationTrust
{
- if (domain == null)
- throw new ArgumentNullException("domain");
- Contract.EndContractBlock();
-
- try {
- Int32 domainID = AppDomain.GetIdForUnload(domain);
- if (domainID==0)
- throw new CannotUnloadAppDomainException();
- AppDomain.nUnload(domainID);
- }
- catch(Exception e) {
- throw e; // throw it again to reset stack trace
- }
- }
-#endif
-
- // Explicitly set policy for a domain (providing policy hasn't been set
- // previously). Making this call will guarantee that previously loaded
- // assemblies will be granted permissions based on the default machine
- // policy that was in place prior to this call.
-#if FEATURE_CAS_POLICY
- [System.Security.SecurityCritical] // auto-generated_required
- [Obsolete("AppDomain policy levels are obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
- public void SetAppDomainPolicy(PolicyLevel domainPolicy)
- {
- if (domainPolicy == null)
- throw new ArgumentNullException("domainPolicy");
- Contract.EndContractBlock();
-
- if (!IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
- }
-
- // Check that policy has not been set previously.
- lock (this) {
- if (_HasSetPolicy)
- throw new PolicyException(Environment.GetResourceString("Policy_PolicyAlreadySet"));
- _HasSetPolicy = true;
-
- // Make sure that the loader allows us to change security policy
- // at this time (this will throw if not.)
- nChangeSecurityPolicy();
- }
-
- // Add the new policy level.
- SecurityManager.PolicyManager.AddLevel(domainPolicy);
- }
-#endif //#if !FEATURE_CAS_POLICY
-#if FEATURE_CLICKONCE
- public ActivationContext ActivationContext {
- [System.Security.SecurityCritical] // auto-generated_required
- get {
- return _activationContext;
- }
- }
-
- public ApplicationIdentity ApplicationIdentity {
- [System.Security.SecurityCritical] // auto-generated_required
- get {
- return _applicationIdentity;
- }
- }
-#endif // FEATURE_CLICKONCE
-
-
-#if FEATURE_CLICKONCE
- public ApplicationTrust ApplicationTrust {
- [System.Security.SecurityCritical] // auto-generated_required
-#else // FEATURE_CLICKONCE
- internal ApplicationTrust ApplicationTrust {
-#endif // FEATURE_CLICKONCE
get {
if (_applicationTrust == null && _IsFastFullTrustDomain) {
_applicationTrust = new ApplicationTrust(new PermissionSet(PermissionState.Unrestricted));
@@ -2564,66 +1758,8 @@ namespace System {
}
}
-#if FEATURE_IMPERSONATION
- // Set the default principal object to be attached to threads if they
- // attempt to bind to a principal while executing in this appdomain. The
- // default can only be set once.
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlPrincipal)]
- public void SetThreadPrincipal(IPrincipal principal)
- {
- if (principal == null)
- throw new ArgumentNullException("principal");
- Contract.EndContractBlock();
-
- lock (this) {
- // Check that principal has not been set previously.
- if (_DefaultPrincipal != null)
- throw new PolicyException(Environment.GetResourceString("Policy_PrincipalTwice"));
-
- _DefaultPrincipal = principal;
- }
- }
-#endif // FEATURE_IMPERSONATION
-
-#if FEATURE_CAS_POLICY
- // Similar to the above, but sets the class of principal to be created
- // instead.
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlPrincipal)]
- public void SetPrincipalPolicy(PrincipalPolicy policy)
- {
- _PrincipalPolicy = policy;
- }
-#endif
-
-
-#if FEATURE_REMOTING
- // This method gives AppDomain an infinite life time by preventing a lease from being
- // created
- [System.Security.SecurityCritical] // auto-generated_required
- public override Object InitializeLifetimeService()
- {
- return null;
- }
- // This is useful for requesting execution of some code
- // in another appDomain ... the delegate may be defined
- // on a marshal-by-value object or a marshal-by-ref or
- // contextBound object.
- public void DoCallBack(CrossAppDomainDelegate callBackDelegate)
- {
- if (callBackDelegate == null)
- throw new ArgumentNullException("callBackDelegate");
- Contract.EndContractBlock();
-
- callBackDelegate();
- }
-#endif
-
-
public String DynamicDirectory
{
- [System.Security.SecuritySafeCritical] // auto-generated
get {
String dyndir = GetDynamicDir();
if (dyndir != null)
@@ -2633,211 +1769,13 @@ namespace System {
}
}
-#if FEATURE_CAS_POLICY
- public static AppDomain CreateDomain(String friendlyName,
- Evidence securityInfo) // Optional
- {
- return CreateDomain(friendlyName,
- securityInfo,
- null);
- }
-
- public static AppDomain CreateDomain(String friendlyName,
- Evidence securityInfo, // Optional
- String appBasePath,
- String appRelativeSearchPath,
- bool shadowCopyFiles)
- {
- AppDomainSetup info = new AppDomainSetup();
- info.ApplicationBase = appBasePath;
- info.PrivateBinPath = appRelativeSearchPath;
- if(shadowCopyFiles)
- info.ShadowCopyFiles = "true";
-
- return CreateDomain(friendlyName,
- securityInfo,
- info);
- }
-#endif // #if FEATURE_CAS_POLICY (not exposed in core)
-
-
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
extern private String GetDynamicDir();
- // Private helpers called from unmanaged code.
-
-#if FEATURE_REMOTING
-
- public static AppDomain CreateDomain(String friendlyName)
- {
- return CreateDomain(friendlyName, null, null);
- }
-
-
- // Marshal a single object into a serialized blob.
- [System.Security.SecurityCritical] // auto-generated
- private static byte[] MarshalObject(Object o)
- {
- CodeAccessPermission.Assert(true);
-
- return Serialize(o);
- }
-
- // Marshal two objects into serialized blobs.
- [System.Security.SecurityCritical] // auto-generated
- private static byte[] MarshalObjects(Object o1, Object o2, out byte[] blob2)
- {
- CodeAccessPermission.Assert(true);
-
- byte[] blob1 = Serialize(o1);
- blob2 = Serialize(o2);
- return blob1;
- }
-
- // Unmarshal a single object from a serialized blob.
- [System.Security.SecurityCritical] // auto-generated
- private static Object UnmarshalObject(byte[] blob)
- {
- CodeAccessPermission.Assert(true);
-
- return Deserialize(blob);
- }
-
- // Unmarshal two objects from serialized blobs.
- [System.Security.SecurityCritical] // auto-generated
- private static Object UnmarshalObjects(byte[] blob1, byte[] blob2, out Object o2)
- {
- CodeAccessPermission.Assert(true);
-
- Object o1 = Deserialize(blob1);
- o2 = Deserialize(blob2);
- return o1;
- }
-
- // Helper routines.
- [System.Security.SecurityCritical] // auto-generated
- private static byte[] Serialize(Object o)
- {
- if (o == null)
- {
- return null;
- }
- else if (o is ISecurityEncodable)
- {
- SecurityElement element = ((ISecurityEncodable)o).ToXml();
- MemoryStream ms = new MemoryStream( 4096 );
- ms.WriteByte( 0 );
- StreamWriter writer = new StreamWriter( ms, Encoding.UTF8 );
- element.ToWriter( writer );
- writer.Flush();
- return ms.ToArray();
- }
- else
- {
- MemoryStream ms = new MemoryStream();
- ms.WriteByte( 1 );
- CrossAppDomainSerializer.SerializeObject(o, ms);
- return ms.ToArray();
- }
- }
-
- [System.Security.SecurityCritical] // auto-generated
- private static Object Deserialize(byte[] blob)
- {
- if (blob == null)
- return null;
-
- if (blob[0] == 0)
- {
- Parser parser = new Parser( blob, Tokenizer.ByteTokenEncoding.UTF8Tokens, 1 );
- SecurityElement root = parser.GetTopElement();
- if (root.Tag.Equals( "IPermission" ) || root.Tag.Equals( "Permission" ))
- {
- IPermission ip = System.Security.Util.XMLUtil.CreatePermission( root, PermissionState.None, false );
-
- if (ip == null)
- {
- return null;
- }
-
- ip.FromXml( root );
-
- return ip;
- }
- else if (root.Tag.Equals( "PermissionSet" ))
- {
- PermissionSet permissionSet = new PermissionSet();
-
- permissionSet.FromXml( root, false, false );
-
- return permissionSet;
- }
- else if (root.Tag.Equals( "PermissionToken" ))
- {
- PermissionToken pToken = new PermissionToken();
-
- pToken.FromXml( root );
-
- return pToken;
- }
- else
- {
- return null;
- }
-
- }
- else
- {
- Object obj = null;
- using(MemoryStream stream = new MemoryStream( blob, 1, blob.Length - 1 )) {
- obj = CrossAppDomainSerializer.DeserializeObject(stream);
- }
-
- Contract.Assert( !(obj is IPermission), "IPermission should be xml deserialized" );
- Contract.Assert( !(obj is PermissionSet), "PermissionSet should be xml deserialized" );
-
- return obj;
- }
- }
-
-#endif // FEATURE_REMOTING
-
-#if !FEATURE_CORECLR
- //
- // Called by the VM if ICLRExecutionManager::Pause is called with the PAUSE_APP_DOMAINS flag.
- // This mimics the behavior of the CoreCLR FAS (fast application switching) model, to ensure
- // that code that depends on things happening in a particular order will work.
- //
- [System.Security.SecurityCritical]
- internal static void Pause()
- {
- AppDomainPauseManager.Instance.Pausing();
- AppDomainPauseManager.Instance.Paused();
- }
-
- //
- // Called by the VM if ICLRExecutionManager::Resume is called after ICLRExecutionManager::Pause
- // was called with the PAUSE_APP_DOMAINS flag.
- // This mimics the behavior of the CoreCLR FAS (fast application switching) model, to ensure
- // that code that depends on things happening in a particular order will work.
- //
- [System.Security.SecurityCritical]
- internal static void Resume()
- {
- if (AppDomainPauseManager.IsPaused)
- {
- AppDomainPauseManager.Instance.Resuming();
- AppDomainPauseManager.Instance.Resumed();
- }
- }
-#endif
-
private AppDomain() {
throw new NotSupportedException(Environment.GetResourceString(ResId.NotSupported_Constructor));
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern int _nExecuteAssembly(RuntimeAssembly assembly, String[] args);
internal int nExecuteAssembly(RuntimeAssembly assembly, String[] args)
@@ -2849,45 +1787,18 @@ namespace System {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern void nCreateContext();
- [System.Security.SecurityCritical]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void nSetupBindingPaths(String trustedPlatformAssemblies, String platformResourceRoots, String appPath, String appNiPaths, String appLocalWinMD);
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
internal void SetupBindingPaths(String trustedPlatformAssemblies, String platformResourceRoots, String appPath, String appNiPaths, String appLocalWinMD)
{
nSetupBindingPaths(trustedPlatformAssemblies, platformResourceRoots, appPath, appNiPaths, appLocalWinMD);
}
#endif // FEATURE_VERSIONING
-#if FEATURE_REMOTING
- internal void CreateRemotingData()
- {
- lock(this) {
- if (_RemotingData == null)
- _RemotingData = new DomainSpecificRemotingData();
- }
- }
-
- internal DomainSpecificRemotingData RemotingData
- {
- get
- {
- if (_RemotingData == null)
- CreateRemotingData();
-
- return _RemotingData;
- }
- }
-#endif // FEATURE_REMOTING
-
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern String nGetFriendlyName();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern bool nIsDefaultAppDomainForEvidence();
@@ -2899,7 +1810,6 @@ namespace System {
public event EventHandler ProcessExit
{
- [System.Security.SecuritySafeCritical] // auto-generated_required
add
{
if (value != null)
@@ -2919,7 +1829,6 @@ namespace System {
public event EventHandler DomainUnload
{
- [System.Security.SecuritySafeCritical] // auto-generated_required
add
{
if (value != null)
@@ -2929,9 +1838,6 @@ namespace System {
_domainUnload += value;
}
}
-#if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical]
-#endif
remove
{
lock(this)
@@ -2942,7 +1848,6 @@ namespace System {
public event UnhandledExceptionEventHandler UnhandledException
{
- [System.Security.SecurityCritical] // auto-generated_required
add
{
if (value != null)
@@ -2952,7 +1857,6 @@ namespace System {
_unhandledException += value;
}
}
- [System.Security.SecurityCritical] // auto-generated_required
remove
{
lock(this)
@@ -2967,7 +1871,6 @@ namespace System {
// To register/unregister the callback, the code must be SecurityCritical.
public event EventHandler<FirstChanceExceptionEventArgs> FirstChanceException
{
- [System.Security.SecurityCritical] // auto-generated_required
add
{
if (value != null)
@@ -2977,7 +1880,6 @@ namespace System {
_firstChanceException += value;
}
}
- [System.Security.SecurityCritical] // auto-generated_required
remove
{
lock(this)
@@ -2996,7 +1898,6 @@ namespace System {
}
// This method is called by the VM.
- [System.Security.SecurityCritical]
private RuntimeAssembly OnResourceResolveEvent(RuntimeAssembly assembly, String resourceName)
{
ResolveEventHandler eventHandler = _ResourceResolve;
@@ -3016,7 +1917,6 @@ namespace System {
}
// This method is called by the VM
- [System.Security.SecurityCritical]
private RuntimeAssembly OnTypeResolveEvent(RuntimeAssembly assembly, String typeName)
{
ResolveEventHandler eventHandler = _TypeResolve;
@@ -3036,7 +1936,6 @@ namespace System {
}
// This method is called by the VM.
- [System.Security.SecurityCritical]
private RuntimeAssembly OnAssemblyResolveEvent(RuntimeAssembly assembly, String assemblyFullName)
{
ResolveEventHandler eventHandler = _AssemblyResolve;
@@ -3058,36 +1957,6 @@ namespace System {
return null;
}
-#if FEATURE_REFLECTION_ONLY_LOAD
-
- private RuntimeAssembly OnReflectionOnlyAssemblyResolveEvent(RuntimeAssembly assembly, String assemblyFullName)
- {
- ResolveEventHandler eventHandler = ReflectionOnlyAssemblyResolve;
- if (eventHandler != null) {
-
- Delegate[] ds = eventHandler.GetInvocationList();
- int len = ds.Length;
- 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;
- }
-
-#if FEATURE_COMINTEROP
- // Called by VM - code:CLRPrivTypeCacheReflectionOnlyWinRT::RaiseNamespaceResolveEvent
- private RuntimeAssembly[] OnReflectionOnlyNamespaceResolveEvent(RuntimeAssembly assembly, string namespaceName)
- {
- return System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMetadata.OnReflectionOnlyNamespaceResolveEvent(this, assembly, namespaceName);
- }
-#endif // FEATURE_COMINTEROP
-
-#endif // FEATURE_REFLECTION_ONLY_LOAD
-
#if FEATURE_COMINTEROP
// Called by VM - code:CLRPrivTypeCacheWinRT::RaiseDesignerNamespaceResolveEvent
private string[] OnDesignerNamespaceResolveEvent(string namespaceName)
@@ -3099,7 +1968,7 @@ namespace System {
internal AppDomainSetup FusionStore
{
get {
- Contract.Assert(_FusionStore != null,
+ Debug.Assert(_FusionStore != null,
"Fusion store has not been correctly setup in this domain");
return _FusionStore;
}
@@ -3133,319 +2002,33 @@ namespace System {
}
}
-#if FEATURE_FUSION
- private void TurnOnBindingRedirects()
- {
- _FusionStore.DisallowBindingRedirects = false;
- }
-#endif
-
- // This will throw a CannotUnloadAppDomainException if the appdomain is
- // in another process.
-#if FEATURE_REMOTING
- [System.Security.SecurityCritical] // auto-generated
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
- internal static Int32 GetIdForUnload(AppDomain domain)
- {
- if (RemotingServices.IsTransparentProxy(domain))
- {
- return RemotingServices.GetServerDomainIdForProxy(domain);
- }
- else
- return domain.Id;
- }
-#endif
-
// Used to determine if server object context is valid in
// x-domain remoting scenarios.
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal static extern bool IsDomainIdValid(Int32 id);
-
-#if FEATURE_REMOTING
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- static internal extern AppDomain GetDefaultDomain();
-#endif
-
-#if FEATURE_IMPERSONATION
- // Internal routine to retrieve the default principal object. If this is
- // called before the principal has been explicitly set, it will
- // automatically allocate a default principal based on the policy set by
- // SetPrincipalPolicy.
- internal IPrincipal GetThreadPrincipal()
- {
- IPrincipal principal = null;
- if (_DefaultPrincipal == null) {
-#if FEATURE_CAS_POLICY
- switch (_PrincipalPolicy) {
- case PrincipalPolicy.NoPrincipal:
- principal = null;
- break;
- case PrincipalPolicy.UnauthenticatedPrincipal:
- principal = new GenericPrincipal(new GenericIdentity("", ""),
- new String[] {""});
- break;
- case PrincipalPolicy.WindowsPrincipal:
- principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
- break;
- default:
- principal = null;
- break;
- }
-#else
- principal = new GenericPrincipal(new GenericIdentity("", ""),
- new String[] {""});
-
-#endif
- }
- else
- principal = _DefaultPrincipal;
-
- return principal;
- }
-#endif // FEATURE_IMPERSONATION
-
-#if FEATURE_REMOTING
-
- [System.Security.SecurityCritical] // auto-generated
- internal void CreateDefaultContext()
- {
- lock(this) {
- // if it has not been created we ask the Context class to
- // create a new default context for this appdomain.
- if (_DefaultContext == null)
- _DefaultContext = Context.CreateDefaultContext();
- }
- }
-
- [System.Security.SecurityCritical] // auto-generated
- internal Context GetDefaultContext()
- {
- if (_DefaultContext == null)
- CreateDefaultContext();
- return _DefaultContext;
- }
-
- // Ensure that evidence provided when creating an AppDomain would not have been used to create a
- // sandbox in legacy CAS mode. If it could have been used to create a sandbox, and we're not in CAS
- // mode, then we throw an exception to prevent acciental creation of unsandboxed domains where a
- // sandbox would have been expected.
- [SecuritySafeCritical]
- internal static void CheckDomainCreationEvidence(AppDomainSetup creationDomainSetup,
- Evidence creationEvidence)
- {
- if (creationEvidence != null && !CurrentDomain.IsLegacyCasPolicyEnabled)
- {
- if (creationDomainSetup == null || creationDomainSetup.ApplicationTrust == null)
- {
- // We allow non-null evidence in CAS mode to support the common pattern of passing in
- // AppDomain.CurrentDomain.Evidence. Since the zone evidence must have been changed
- // if the user has any expectation of sandboxing the domain under legacy CAS policy,
- // we use a zone comparison to check for this pattern. A strict comparison will not
- // work, since MSDN samples for creating a domain show using a modified version of the
- // current domain's evidence and we would capturce people who copied and pasted these
- // samples without intending to sandbox.
- Zone creatorsZone = CurrentDomain.EvidenceNoDemand.GetHostEvidence<Zone>();
- SecurityZone creatorsSecurityZone = creatorsZone != null ?
- creatorsZone.SecurityZone :
- SecurityZone.MyComputer;
-
- Zone suppliedZone = creationEvidence.GetHostEvidence<Zone>();
- if (suppliedZone != null)
- {
- if (suppliedZone.SecurityZone != creatorsSecurityZone &&
- suppliedZone.SecurityZone != SecurityZone.MyComputer)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyImplicit"));
- }
- }
- }
- }
- }
-
-#if FEATURE_CAS_POLICY
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute( SecurityAction.Demand, ControlAppDomain = true )]
- public static AppDomain CreateDomain(String friendlyName,
- Evidence securityInfo,
- AppDomainSetup info)
- {
- return InternalCreateDomain(friendlyName, securityInfo, info);
- }
-#else
- internal static AppDomain CreateDomain(String friendlyName,
- Evidence securityInfo,
- AppDomainSetup info)
- {
- return InternalCreateDomain(friendlyName, securityInfo, info);
- }
-#endif
-
- [System.Security.SecurityCritical] // auto-generated
- internal static AppDomain InternalCreateDomain(String friendlyName,
- Evidence securityInfo,
- AppDomainSetup info)
- {
- if (friendlyName == null)
- throw new ArgumentNullException("friendlyName", Environment.GetResourceString("ArgumentNull_String"));
-
- Contract.EndContractBlock();
-
- AppDomain.CheckCreateDomainSupported();
-
- if (info == null)
- info = new AppDomainSetup();
- if (info.TargetFrameworkName == null)
- info.TargetFrameworkName = AppDomain.CurrentDomain.GetTargetFrameworkName();
- AppDomainManager domainManager = AppDomain.CurrentDomain.DomainManager;
- if (domainManager != null)
- return domainManager.CreateDomain(friendlyName, securityInfo, info);
-
- // No AppDomainManager is set up for this domain
-
- // If evidence is provided, we check to make sure that is allowed.
- if (securityInfo != null)
- {
- new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand();
-
- // If we're potentially trying to sandbox without using a homogenous domain, we need to reject
- // the domain creation.
- CheckDomainCreationEvidence(info, securityInfo);
- }
-
- return nCreateDomain(friendlyName,
- info,
- securityInfo,
- securityInfo == null ? AppDomain.CurrentDomain.InternalEvidence : null,
- AppDomain.CurrentDomain.GetSecurityDescriptor());
- }
-#endif // FEATURE_REMOTING
-
-#if FEATURE_CAS_POLICY
-
- public static AppDomain CreateDomain (string friendlyName,
- Evidence securityInfo,
- AppDomainSetup info,
- PermissionSet grantSet,
- params StrongName[] fullTrustAssemblies)
- {
- if (info == null)
- throw new ArgumentNullException("info");
- if (info.ApplicationBase == null)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_AppDomainSandboxAPINeedsExplicitAppBase"));
- Contract.EndContractBlock();
-
- if (fullTrustAssemblies == null)
- {
- fullTrustAssemblies = new StrongName[0];
- }
-
- info.ApplicationTrust = new ApplicationTrust(grantSet, fullTrustAssemblies);
- return CreateDomain(friendlyName, securityInfo, info);
- }
-
- public static AppDomain CreateDomain(String friendlyName,
- Evidence securityInfo, // Optional
- String appBasePath,
- String appRelativeSearchPath,
- bool shadowCopyFiles,
- AppDomainInitializer adInit,
- string[] adInitArgs)
- {
- AppDomainSetup info = new AppDomainSetup();
- info.ApplicationBase = appBasePath;
- info.PrivateBinPath = appRelativeSearchPath;
- info.AppDomainInitializer=adInit;
- info.AppDomainInitializerArguments=adInitArgs;
- if(shadowCopyFiles)
- info.ShadowCopyFiles = "true";
-
- return CreateDomain(friendlyName,
- securityInfo,
- info);
- }
-#endif // FEATURE_CAS_POLICY
-
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void nSetNativeDllSearchDirectories(string paths);
-#endif
- [System.Security.SecurityCritical] // auto-generated
private void SetupFusionStore(AppDomainSetup info, AppDomainSetup oldInfo)
{
Contract.Requires(info != null);
-#if FEATURE_FUSION
- if (oldInfo == null) {
-
- // Create the application base and configuration file from the imagelocation
- // passed in or use the Win32 Image name.
- if(info.Value[(int) AppDomainSetup.LoaderInformation.ApplicationBaseValue] == null ||
- info.Value[(int) AppDomainSetup.LoaderInformation.ConfigurationFileValue] == null )
-#else
if (info.ApplicationBase == null)
-#endif
-
{
-#if FEATURE_FUSION
- AppDomain defaultDomain = GetDefaultDomain();
- if (this == defaultDomain) {
- // The default domain gets its defaults from the main process.
- info.SetupDefaults(RuntimeEnvironment.GetModuleFileName(), imageLocationAlreadyNormalized : true);
- }
- else {
- // Other domains get their defaults from the default domain. This way, a host process
- // can use AppDomainManager to set up the defaults for every domain created in the process.
- if (info.Value[(int) AppDomainSetup.LoaderInformation.ConfigurationFileValue] == null)
- info.ConfigurationFile = defaultDomain.FusionStore.Value[(int) AppDomainSetup.LoaderInformation.ConfigurationFileValue];
- if (info.Value[(int) AppDomainSetup.LoaderInformation.ApplicationBaseValue] == null)
- info.ApplicationBase = defaultDomain.FusionStore.Value[(int) AppDomainSetup.LoaderInformation.ApplicationBaseValue];
- if (info.Value[(int) AppDomainSetup.LoaderInformation.ApplicationNameValue] == null)
- info.ApplicationName = defaultDomain.FusionStore.Value[(int) AppDomainSetup.LoaderInformation.ApplicationNameValue];
- }
-#else
info.SetupDefaults(RuntimeEnvironment.GetModuleFileName(), imageLocationAlreadyNormalized : true);
-#endif
-
- }
-
-#if FEATURE_FUSION
- // If there is no relative path then check the
- // environment
- if(info.Value[(int) AppDomainSetup.LoaderInformation.PrivateBinPathValue] == null)
- info.PrivateBinPath = Environment.nativeGetEnvironmentVariable(AppDomainSetup.PrivateBinPathEnvironmentVariable);
-
- // Add the developer path if it exists on this
- // machine.
- if(info.DeveloperPath == null)
- info.DeveloperPath = RuntimeEnvironment.GetDeveloperPath();
-
}
-
- // Set up the fusion context
- IntPtr fusionContext = GetFusionContext();
- info.SetupFusionContext(fusionContext, oldInfo);
- // Set loader optimization policy
-#else
#if FEATURE_VERSIONING
nCreateContext();
#endif // FEATURE_VERSIONING
-#endif // FEATURE_FUSION
#if FEATURE_LOADER_OPTIMIZATION
if (info.LoaderOptimization != LoaderOptimization.NotSpecified || (oldInfo != null && info.LoaderOptimization != oldInfo.LoaderOptimization))
UpdateLoaderOptimization(info.LoaderOptimization);
-#endif
-
-
-
+#endif
// This must be the last action taken
_FusionStore = info;
}
@@ -3475,7 +2058,6 @@ namespace System {
// are any remoting sinks registered, they can add non-mscorlib
// objects to the message (causing an assembly load exception when
// we try to deserialize it on the other side)
- [System.Security.SecurityCritical] // auto-generated
private static object PrepareDataForSetup(String friendlyName,
AppDomainSetup setup,
Evidence providedSecurityInfo,
@@ -3488,54 +2070,6 @@ namespace System {
byte[] serializedEvidence = null;
bool generateDefaultEvidence = false;
-#if FEATURE_CAS_POLICY
- // serialize evidence
- EvidenceCollection evidenceCollection = null;
-
- if (providedSecurityInfo != null || creatorsSecurityInfo != null)
- {
- // If we're just passing through AppDomain.CurrentDomain.Evidence, and that evidence is just
- // using the standard runtime AppDomainEvidenceFactory, don't waste time serializing it and
- // deserializing it back -- instead, we can recreate a new AppDomainEvidenceFactory in the new
- // domain. We only want to do this if there is no HostSecurityManager, otherwise the
- // HostSecurityManager could have added additional evidence on top of our standard factory.
- HostSecurityManager hsm = CurrentDomain.DomainManager != null ? CurrentDomain.DomainManager.HostSecurityManager : null;
- bool hostMayContributeEvidence = hsm != null &&
- hsm.GetType() != typeof(HostSecurityManager) &&
- (hsm.Flags & HostSecurityManagerOptions.HostAppDomainEvidence) == HostSecurityManagerOptions.HostAppDomainEvidence;
- if (!hostMayContributeEvidence)
- {
- if (providedSecurityInfo != null &&
- providedSecurityInfo.IsUnmodified &&
- providedSecurityInfo.Target != null &&
- providedSecurityInfo.Target is AppDomainEvidenceFactory)
- {
- providedSecurityInfo = null;
- generateDefaultEvidence = true;
- }
- if (creatorsSecurityInfo != null &&
- creatorsSecurityInfo.IsUnmodified &&
- creatorsSecurityInfo.Target != null &&
- creatorsSecurityInfo.Target is AppDomainEvidenceFactory)
- {
- creatorsSecurityInfo = null;
- generateDefaultEvidence = true;
- }
- }
- }
- if ((providedSecurityInfo != null) ||
- (creatorsSecurityInfo != null)) {
- evidenceCollection = new EvidenceCollection();
- evidenceCollection.ProvidedSecurityInfo = providedSecurityInfo;
- evidenceCollection.CreatorsSecurityInfo = creatorsSecurityInfo;
- }
-
- if (evidenceCollection != null) {
- serializedEvidence =
- CrossAppDomainSerializer.SerializeObject(evidenceCollection).GetBuffer();
- }
-#endif // FEATURE_CAS_POLICY
-
AppDomainInitializerInfo initializerInfo = null;
if (setup!=null && setup.AppDomainInitializer!=null)
initializerInfo=new AppDomainInitializerInfo(setup.AppDomainInitializer);
@@ -3543,7 +2077,6 @@ namespace System {
// will travel x-Ad, drop non-agile data
AppDomainSetup newSetup = new AppDomainSetup(setup, false);
-#if FEATURE_CORECLR
// Remove the special AppDomainCompatSwitch entries from the set of name value pairs
// And add them to the AppDomainSetup
//
@@ -3551,7 +2084,7 @@ namespace System {
// Desktop code should use System.AppDomain.CreateDomain() or
// System.AppDomainManager.CreateDomain() and add the flags to the AppDomainSetup
List<String> compatList = new List<String>();
-
+
if(propertyNames!=null && propertyValues != null)
{
for (int i=0; i<propertyNames.Length; i++)
@@ -3559,7 +2092,7 @@ namespace System {
if(String.Compare(propertyNames[i], "AppDomainCompatSwitch", StringComparison.OrdinalIgnoreCase) == 0)
{
compatList.Add(propertyValues[i]);
- propertyNames[i] = null;
+ propertyNames[i] = null;
propertyValues[i] = null;
}
@@ -3568,10 +2101,8 @@ namespace System {
if (compatList.Count > 0)
{
newSetup.SetCompatibilitySwitches(compatList);
- }
+ }
}
-#endif // FEATURE_CORECLR
-
return new Object[]
{
@@ -3587,8 +2118,6 @@ namespace System {
};
} // PrepareDataForSetup
-
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)]
private static Object Setup(Object arg)
{
@@ -3604,44 +2133,47 @@ namespace System {
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
+ 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);
if(propertyNames!=null && propertyValues != null)
{
-#if FEATURE_CORECLR
- StringBuilder normalisedAppPathList = null;
-#endif // FEATURE_CORECLR
+ for (int i = 0; i < propertyNames.Length; i++)
+ {
+ // We want to set native dll probing directories before any P/Invokes have a
+ // chance to fire. The Path class, for one, has P/Invokes.
+ if (propertyNames[i] == "NATIVE_DLL_SEARCH_DIRECTORIES")
+ {
+ if (propertyValues[i] == null)
+ throw new ArgumentNullException("NATIVE_DLL_SEARCH_DIRECTORIES");
+
+ string paths = propertyValues[i];
+ if (paths.Length == 0)
+ break;
+
+ nSetNativeDllSearchDirectories(paths);
+ }
+ }
+
for (int i=0; i<propertyNames.Length; i++)
{
if(propertyNames[i]=="APPBASE") // make sure in sync with Fusion
{
if(propertyValues[i]==null)
throw new ArgumentNullException("APPBASE");
-
- if (Path.IsRelative(propertyValues[i]))
+
+ if (PathInternal.IsPartiallyQualified(propertyValues[i]))
throw new ArgumentException( Environment.GetResourceString( "Argument_AbsolutePathRequired" ) );
newSetup.ApplicationBase = NormalizePath(propertyValues[i], fullCheck: true);
-
- }
-#if FEATURE_CAS_POLICY
- else if(propertyNames[i]=="LOCATION_URI" && providedSecurityInfo==null)
- {
- providedSecurityInfo=new Evidence();
- providedSecurityInfo.AddHostEvidence(new Url(propertyValues[i]));
- ad.SetDataHelper(propertyNames[i],propertyValues[i],null);
}
-#endif // FEATURE_CAS_POLICY
#if FEATURE_LOADER_OPTIMIZATION
- else
- if(propertyNames[i]=="LOADER_OPTIMIZATION")
+ else if(propertyNames[i]=="LOADER_OPTIMIZATION")
{
if(propertyValues[i]==null)
throw new ArgumentNullException("LOADER_OPTIMIZATION");
@@ -3656,119 +2188,32 @@ namespace System {
}
}
#endif // FEATURE_LOADER_OPTIMIZATION
-#if FEATURE_CORECLR
- else
- if(propertyNames[i]=="NATIVE_DLL_SEARCH_DIRECTORIES")
- {
- if(propertyValues[i]==null)
- throw new ArgumentNullException("NATIVE_DLL_SEARCH_DIRECTORIES");
- ad.SetDataHelper(propertyNames[i],propertyValues[i],null);
- string paths = (string)propertyValues[i];
- if( paths.Length==0 )
- continue;
- nSetNativeDllSearchDirectories(paths);
- }
- else
- if(propertyNames[i]=="TRUSTED_PLATFORM_ASSEMBLIES" ||
+ 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]);
- int estimatedLength = values.Length + 1; // +1 for extra separator temporarily added at end
- if (normalisedAppPathList == null) {
- normalisedAppPathList = new StringBuilder(estimatedLength);
- }
- else {
- normalisedAppPathList.Clear();
- if (normalisedAppPathList.Capacity < estimatedLength)
- normalisedAppPathList.Capacity = estimatedLength;
- }
-
- for (int pos = 0; pos < values.Length; pos++)
- {
- string path;
-
- int nextPos = values.IndexOf(Path.PathSeparator, pos);
- if (nextPos == -1)
- {
- path = values.Substring(pos);
- pos = values.Length - 1;
- }
- else
- {
- path = values.Substring(pos, nextPos - pos);
- pos = nextPos;
- }
-
- if( path.Length==0 ) // skip empty dirs
- continue;
-
- if (Path.IsRelative(path))
- throw new ArgumentException( Environment.GetResourceString( "Argument_AbsolutePathRequired" ) );
-
- string appPath = NormalizePath(path, fullCheck: true);
- normalisedAppPathList.Append(appPath);
- normalisedAppPathList.Append(Path.PathSeparator);
- }
- // Strip the last separator
- if (normalisedAppPathList.Length > 0)
- {
- normalisedAppPathList.Remove(normalisedAppPathList.Length - 1, 1);
- }
- ad.SetDataHelper(propertyNames[i],normalisedAppPathList.ToString(),null); // not supported by fusion, so set explicitly
+ ad.SetDataHelper(propertyNames[i], NormalizeAppPaths(values), null);
}
- else
- if(propertyNames[i]!= null)
+ else if(propertyNames[i]!= null)
{
ad.SetDataHelper(propertyNames[i],propertyValues[i],null); // just propagate
}
-#endif
-
}
}
-#if !FEATURE_CORECLR
- AppDomainSortingSetupInfo sortingSetup = newSetup._AppDomainSortingSetupInfo;
-
- if(sortingSetup != null)
- {
- if(sortingSetup._pfnIsNLSDefinedString == IntPtr.Zero || sortingSetup._pfnCompareStringEx == IntPtr.Zero || sortingSetup._pfnLCMapStringEx == IntPtr.Zero || sortingSetup._pfnFindNLSStringEx == IntPtr.Zero
- || sortingSetup._pfnCompareStringOrdinal == IntPtr.Zero || sortingSetup._pfnGetNLSVersionEx == IntPtr.Zero)
- {
-
- if(!(sortingSetup._pfnIsNLSDefinedString == IntPtr.Zero && sortingSetup._pfnCompareStringEx == IntPtr.Zero && sortingSetup._pfnLCMapStringEx == IntPtr.Zero && sortingSetup._pfnFindNLSStringEx == IntPtr.Zero
- && sortingSetup._pfnCompareStringOrdinal == IntPtr.Zero && sortingSetup._pfnGetNLSVersionEx == IntPtr.Zero))
- {
- // Some functions defined but not all of them.
- throw new ArgumentException(Environment.GetResourceString("ArgumentException_NotAllCustomSortingFuncsDefined"));
- }
-
- }
- }
-#endif
-
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;
-#if FEATURE_CORECLR
adSetup.InternalSetApplicationTrust(sandboxName);
-#endif // FEATURE_CORECLR
-
-#if !FEATURE_CORECLR // not used by coreclr
- if (serializedEvidence != null) {
- EvidenceCollection evidenceCollection = (EvidenceCollection)
- CrossAppDomainSerializer.DeserializeObject(new MemoryStream(serializedEvidence));
- providedSecurityInfo = evidenceCollection.ProvidedSecurityInfo;
- creatorsSecurityInfo = evidenceCollection.CreatorsSecurityInfo;
- }
-#endif
+
// set up the friendly name
ad.nSetupFriendlyName(friendlyName);
@@ -3785,11 +2230,6 @@ namespace System {
ad.SetAppDomainManagerType(adSetup.AppDomainManagerAssembly, adSetup.AppDomainManagerType);
}
-#if FEATURE_APTCA
- // set any conditial-aptca visible assemblies
- ad.PartialTrustVisibleAssemblies = adSetup.PartialTrustVisibleAssemblies;
-#endif // FEATURE_APTCA
-
ad.CreateAppDomainManager(); // could modify FusionStore's object
ad.InitializeDomainSecurity(providedSecurityInfo,
creatorsSecurityInfo,
@@ -3802,221 +2242,81 @@ namespace System {
adSetup.AppDomainInitializer=initializerInfo.Unwrap();
RunInitializer(adSetup);
- // Activate the application if needed.
-#if FEATURE_CLICKONCE
- ObjectHandle oh = null;
- if (adSetup.ActivationArguments != null && adSetup.ActivationArguments.ActivateInstance)
- oh = Activator.CreateInstance(ad.ActivationContext);
- return RemotingServices.MarshalInternal(oh, null, null);
-#else
return null;
-#endif // FEATURE_CLICKONCE
}
- [SecuritySafeCritical]
- internal static string NormalizePath(string path, bool fullCheck)
+ private static string NormalizeAppPaths(string values)
{
-#if FEATURE_PATHCOMPAT
- // Appcontext switches can't currently be safely hit during AppDomain bringup
- return Path.LegacyNormalizePath(
- path: path,
- fullCheck: fullCheck,
- maxPathLength: PathInternal.MaxShortPath,
- expandShortPaths: true);
-#else
- return Path.NormalizePath(
- path: path,
- fullCheck: fullCheck,
- expandShortPaths: true);
-#endif
- }
+ int estimatedLength = values.Length + 1; // +1 for extra separator temporarily added at end
+ StringBuilder sb = StringBuilderCache.Acquire(estimatedLength);
-#if FEATURE_APTCA
- // Called from DomainAssembly in Conditional APTCA cases
- [PermissionSet(SecurityAction.Assert, Unrestricted = true)]
- [SecuritySafeCritical]
- private bool IsAssemblyOnAptcaVisibleList(RuntimeAssembly assembly)
- {
- if (_aptcaVisibleAssemblies == null)
- return false;
-
- AssemblyName assemblyName = assembly.GetName();
- String name = assemblyName.GetNameWithPublicKey();
-
- name = name.ToUpperInvariant();
-
- int index = Array.BinarySearch<string>(_aptcaVisibleAssemblies, name,
- StringComparer.OrdinalIgnoreCase);
- return (index >=0);
-
- }
-
- //Used to binary search the list of C-APTCA strings for an AssemblyName. It compares assembly name
- //and public key token.
- private class CAPTCASearcher : IComparer
- {
- int IComparer.Compare(object /*string*/lhs, object /*AssemblyName*/rhs)
+ for (int pos = 0; pos < values.Length; pos++)
{
- AssemblyName captcaEntry = new AssemblyName((string)lhs);
- AssemblyName comparand = (AssemblyName)rhs;
- int nameComp = string.Compare(captcaEntry.Name,
- comparand.Name,
- StringComparison.OrdinalIgnoreCase);
- if (nameComp != 0)
- {
- return nameComp;
- }
-
- //simple names match. Compare public key tokens.
- byte[] lhsKey = captcaEntry.GetPublicKeyToken();
- byte[] rhsKey = comparand.GetPublicKeyToken();
+ string path;
- // We require both sides have a public key token
- if (lhsKey == null)
+ int nextPos = values.IndexOf(Path.PathSeparator, pos);
+ if (nextPos == -1)
{
- return -1;
+ path = values.Substring(pos);
+ pos = values.Length - 1;
}
- if (rhsKey == null)
- {
- return 1;
- }
- if (lhsKey.Length < rhsKey.Length)
- {
- return -1;
- }
- if (lhsKey.Length > rhsKey.Length)
+ else
{
- return 1;
+ path = values.Substring(pos, nextPos - pos);
+ pos = nextPos;
}
- // Tokens seem valid - make sure the compare correctly
- for (int i = 0; i < lhsKey.Length; ++i)
- {
- byte lhsByte = lhsKey[i];
- byte rhsByte = rhsKey[i];
+ // Skip empty directories
+ if (path.Length == 0)
+ continue;
- if (lhsByte < rhsByte)
- {
- return -1;
- }
- if (lhsByte > rhsByte)
- {
- return 1;
- }
- }
+ if (PathInternal.IsPartiallyQualified(path))
+ throw new ArgumentException(Environment.GetResourceString("Argument_AbsolutePathRequired"));
- //They match.
- return 0;
+ string appPath = NormalizePath(path, fullCheck: true);
+ sb.Append(appPath);
+ sb.Append(Path.PathSeparator);
}
- }
- [System.Security.SecurityCritical]
- private unsafe bool IsAssemblyOnAptcaVisibleListRaw(char * namePtr, int nameLen, byte * keyTokenPtr,
- int keyTokenLen)
- {
- //This version is used for checking ngen dependencies against the C-APTCA list. It lets us
- //reject ngen images that depend on an assembly that has been disabled in the current domain.
- //Since we only have the public key token in the ngen image, we'll check against that. The
- //rationale is that if you have a public key token collision in your process you have many
- //problems. Since the source of this public key token is an ngen image for a full trust
- //assembly, there is essentially no risk to the reduced check.
- if (_aptcaVisibleAssemblies == null)
- return false;
-
- string name = new string(namePtr, 0, nameLen);
- byte[] keyToken = new byte[keyTokenLen];
- for( int i = 0; i < keyToken.Length; ++i )
- keyToken[i] = keyTokenPtr[i];
-
- AssemblyName asmName = new AssemblyName();
- asmName.Name = name;
- asmName.SetPublicKeyToken(keyToken);
- try
+ // Strip the last separator
+ if (sb.Length > 0)
{
- int index = Array.BinarySearch(_aptcaVisibleAssemblies, asmName, new CAPTCASearcher());
- return (index >= 0);
+ sb.Remove(sb.Length - 1, 1);
}
- catch (InvalidOperationException) { /* Can happen for poorly formed assembly names */ return false; }
+
+ return StringBuilderCache.GetStringAndRelease(sb);
}
-#endif
+ internal static string NormalizePath(string path, bool fullCheck)
+ {
+ return Path.GetFullPath(path);
+ }
// This routine is called from unmanaged code to
// set the default fusion context.
- [System.Security.SecurityCritical] // auto-generated
private void SetupDomain(bool allowRedirects, String path, String configFile, String[] propertyNames, String[] propertyValues)
{
// It is possible that we could have multiple threads initializing
// the default domain. We will just take the winner of these two.
// (eg. one thread doing a com call and another doing attach for IJW)
- lock (this) {
- if(_FusionStore == null) {
+ lock (this)
+ {
+ if(_FusionStore == null)
+ {
AppDomainSetup setup = new AppDomainSetup();
-#if FEATURE_CORECLR
+
// always use internet permission set
setup.InternalSetApplicationTrust("Internet");
-#endif // FEATURE_CORECLR
-#if FEATURE_FUSION
- setup.SetupDefaults(RuntimeEnvironment.GetModuleFileName(), imageLocationAlreadyNormalized : true);
- if(path != null)
- setup.Value[(int) AppDomainSetup.LoaderInformation.ApplicationBaseValue] = path;
- if(configFile != null)
- setup.Value[(int) AppDomainSetup.LoaderInformation.ConfigurationFileValue] = configFile;
-
- // Default fusion context starts with binding redirects turned off.
- if (!allowRedirects)
- setup.DisallowBindingRedirects = true;
-#endif
-
-#if !FEATURE_CORECLR
- if (propertyNames != null) {
- BCLDebug.Assert(propertyValues != null, "propertyValues != null");
- BCLDebug.Assert(propertyNames.Length == propertyValues.Length, "propertyNames.Length == propertyValues.Length");
-
- for (int i = 0; i < propertyNames.Length; ++i) {
- if (String.Equals(propertyNames[i], "PARTIAL_TRUST_VISIBLE_ASSEMBLIES", StringComparison.Ordinal)) {
- // The value of the PARTIAL_TRUST_VISIBLE_ASSEMBLIES property is a semicolon
- // delimited list of assembly names to add to the
- // PartialTrustVisibleAssemblies setting of the domain setup
- if (propertyValues[i] != null) {
- if (propertyValues[i].Length > 0) {
- setup.PartialTrustVisibleAssemblies = propertyValues[i].Split(';');
- }
- else {
- setup.PartialTrustVisibleAssemblies = new string[0];
- }
- }
- }
- else {
- // In v4 we disallow anything but PARTIAL_TRUST_VISIBLE_ASSEMBLIES to come
- // in via the default domain properties. That restriction could be lifted
- // in a future release, at which point this assert should be removed.
- //
- // This should be kept in sync with the real externally facing filter code
- // in CorHost2::SetPropertiesForDefaultAppDomain
- BCLDebug.Assert(false, "Unexpected default domain property");
- }
- }
- }
-#endif // !FEATURE_CORECLR
-
-#if FEATURE_APTCA
- // Propigate the set of conditional APTCA assemblies that will be used in the default
- // domain onto the domain itself and also into the VM
- PartialTrustVisibleAssemblies = setup.PartialTrustVisibleAssemblies;
-#endif // FEATURE_APTCA
-
SetupFusionStore(setup, null);
}
}
}
#if FEATURE_LOADER_OPTIMIZATION
- [System.Security.SecurityCritical] // auto-generated
private void SetupLoaderOptimization(LoaderOptimization policy)
{
if(policy != LoaderOptimization.NotSpecified) {
- Contract.Assert(FusionStore.LoaderOptimization == LoaderOptimization.NotSpecified,
+ Debug.Assert(FusionStore.LoaderOptimization == LoaderOptimization.NotSpecified,
"It is illegal to change the Loader optimization on a domain");
FusionStore.LoaderOptimization = policy;
@@ -4024,36 +2324,10 @@ namespace System {
}
}
#endif
-
-#if FEATURE_FUSION
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal extern IntPtr GetFusionContext();
-#endif // FEATURE_FUSION
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern IntPtr GetSecurityDescriptor();
-#if FEATURE_REMOTING
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern AppDomain nCreateDomain(String friendlyName,
- AppDomainSetup setup,
- Evidence providedSecurityInfo,
- Evidence creatorsSecurityInfo,
- IntPtr parentSecurityDescriptor);
-
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern ObjRef nCreateInstance(String friendlyName,
- AppDomainSetup setup,
- Evidence providedSecurityInfo,
- Evidence creatorsSecurityInfo,
- IntPtr parentSecurityDescriptor);
-#endif
-
- [SecurityCritical]
private void SetupDomainSecurity(Evidence appDomainEvidence,
IntPtr creatorsSecurityDescriptor,
bool publishAppDomain)
@@ -4066,7 +2340,6 @@ namespace System {
}
- [SecurityCritical]
[SuppressUnmanagedCodeSecurity]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
private static extern void SetupDomainSecurity(AppDomainHandle appDomain,
@@ -4074,7 +2347,6 @@ namespace System {
IntPtr creatorsSecurityDescriptor,
[MarshalAs(UnmanagedType.Bool)] bool publishAppDomain);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void nSetupFriendlyName(string friendlyName);
@@ -4084,39 +2356,10 @@ namespace System {
#endif // FEATURE_COMINTEROP
#if FEATURE_LOADER_OPTIMIZATION
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern void UpdateLoaderOptimization(LoaderOptimization optimization);
#endif
-#if FEATURE_FUSION
- //
- // This is just designed to prevent compiler warnings.
- // This field is used from native, but we need to prevent the compiler warnings.
- //
-
- [System.Security.SecurityCritical] // auto-generated_required
- [Obsolete("AppDomain.SetShadowCopyPath has been deprecated. Please investigate the use of AppDomainSetup.ShadowCopyDirectories instead. http://go.microsoft.com/fwlink/?linkid=14202")]
- public void SetShadowCopyPath(String path)
- {
- InternalSetShadowCopyPath(path);
- }
-
- [System.Security.SecurityCritical] // auto-generated_required
- [Obsolete("AppDomain.SetShadowCopyFiles has been deprecated. Please investigate the use of AppDomainSetup.ShadowCopyFiles instead. http://go.microsoft.com/fwlink/?linkid=14202")]
- public void SetShadowCopyFiles()
- {
- InternalSetShadowCopyFiles();
- }
-
- [System.Security.SecurityCritical] // auto-generated_required
- [Obsolete("AppDomain.SetDynamicBase has been deprecated. Please investigate the use of AppDomainSetup.DynamicBase instead. http://go.microsoft.com/fwlink/?linkid=14202")]
- public void SetDynamicBase(String path)
- {
- InternalSetDynamicBase(path);
- }
-#endif // FEATURE_FUSION
-
public AppDomainSetup SetupInformation
{
get {
@@ -4124,84 +2367,19 @@ namespace System {
}
}
-#if FEATURE_FUSION
- [System.Security.SecurityCritical] // auto-generated
- internal void InternalSetShadowCopyPath(String path)
- {
- if (path != null)
- {
- IntPtr fusionContext = GetFusionContext();
- AppDomainSetup.UpdateContextProperty(fusionContext, AppDomainSetup.ShadowCopyDirectoriesKey, path);
- }
- FusionStore.ShadowCopyDirectories = path;
- }
-
- [System.Security.SecurityCritical] // auto-generated
- internal void InternalSetShadowCopyFiles()
- {
- IntPtr fusionContext = GetFusionContext();
- AppDomainSetup.UpdateContextProperty(fusionContext, AppDomainSetup.ShadowCopyFilesKey, "true");
- FusionStore.ShadowCopyFiles = "true";
- }
-
- [System.Security.SecurityCritical] // auto-generated
- internal void InternalSetCachePath(String path)
- {
- FusionStore.CachePath = path;
- if (FusionStore.Value[(int) AppDomainSetup.LoaderInformation.CachePathValue] != null)
- {
- IntPtr fusionContext = GetFusionContext();
- AppDomainSetup.UpdateContextProperty(fusionContext, AppDomainSetup.CachePathKey,
- FusionStore.Value[(int) AppDomainSetup.LoaderInformation.CachePathValue]);
- }
- }
-
- [System.Security.SecurityCritical] // auto-generated
- internal void InternalSetPrivateBinPath(String path)
- {
- IntPtr fusionContext = GetFusionContext();
- AppDomainSetup.UpdateContextProperty(fusionContext, AppDomainSetup.PrivateBinPathKey, path);
- FusionStore.PrivateBinPath = path;
- }
-
- [System.Security.SecurityCritical] // auto-generated
- internal void InternalSetDynamicBase(String path)
- {
- FusionStore.DynamicBase = path;
- if (FusionStore.Value[(int) AppDomainSetup.LoaderInformation.DynamicBaseValue] != null)
- {
- IntPtr fusionContext = GetFusionContext();
- AppDomainSetup.UpdateContextProperty(fusionContext, AppDomainSetup.DynamicBaseKey,
- FusionStore.Value[(int) AppDomainSetup.LoaderInformation.DynamicBaseValue]);
- }
- }
-#endif // FEATURE_FUSION
-
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern String IsStringInterned(String str);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern String GetOrInternString(String str);
- [SecurityCritical]
[SuppressUnmanagedCodeSecurity]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
private static extern void GetGrantSet(AppDomainHandle domain, ObjectHandleOnStack retGrantSet);
-#if FEATURE_CAS_POLICY
- [SecurityCritical]
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- [return: MarshalAs(UnmanagedType.Bool)]
- private static extern bool GetIsLegacyCasPolicyEnabled(AppDomainHandle domain);
-#endif // FEATURE_CAS_POLICY
-
public PermissionSet PermissionSet
{
// SecurityCritical because permissions can contain sensitive information such as paths
- [SecurityCritical]
get
{
PermissionSet grantSet = null;
@@ -4220,7 +2398,6 @@ namespace System {
public bool IsFullyTrusted
{
- [SecuritySafeCritical]
get
{
PermissionSet grantSet = null;
@@ -4239,62 +2416,9 @@ namespace System {
}
}
-#if FEATURE_CAS_POLICY
- internal bool IsLegacyCasPolicyEnabled
- {
- [SecuritySafeCritical]
- get
- {
- return GetIsLegacyCasPolicyEnabled(GetNativeHandle());
- }
- }
-
- // Determine what this homogenous domain thinks the grant set should be for a specific set of evidence
- [SecuritySafeCritical]
- internal PermissionSet GetHomogenousGrantSet(Evidence evidence)
- {
- Contract.Assert(evidence != null);
- Contract.Assert(IsHomogenous);
- Contract.Assert(evidence.GetHostEvidence<GacInstalled>() == null);
-
- if (_IsFastFullTrustDomain)
- {
- return new PermissionSet(PermissionState.Unrestricted);
- }
-
- // If the ApplicationTrust's full trust list calls out the assembly, then it is fully trusted
- if (evidence.GetDelayEvaluatedHostEvidence<StrongName>() != null)
- {
- foreach (StrongName fullTrustAssembly in ApplicationTrust.FullTrustAssemblies)
- {
- StrongNameMembershipCondition sn = new StrongNameMembershipCondition(fullTrustAssembly.PublicKey,
- fullTrustAssembly.Name,
- fullTrustAssembly.Version);
-
- object usedEvidence = null;
- if ((sn as IReportMatchMembershipCondition).Check(evidence, out usedEvidence))
- {
- IDelayEvaluatedEvidence delayEvidence = usedEvidence as IDelayEvaluatedEvidence;
- if (usedEvidence != null)
- {
- delayEvidence.MarkUsed();
- }
-
- return new PermissionSet(PermissionState.Unrestricted);
- }
- }
- }
-
- // Otherwise, the grant set is just the default grant set
- return ApplicationTrust.DefaultGrantSet.PermissionSet.Copy();
- }
-#endif // FEATURE_CAS_POLICY
-
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void nChangeSecurityPolicy();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.MayCorruptAppDomain, Cer.MayFail)]
internal static extern void nUnload(Int32 domainInternal);
@@ -4309,7 +2433,6 @@ namespace System {
return oh.Unwrap();
} // CreateInstanceAndUnwrap
-
public Object CreateInstanceAndUnwrap(String assemblyName,
String typeName,
Object[] activationAttributes)
@@ -4454,7 +2577,6 @@ namespace System {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal extern Int32 GetId();
@@ -4468,76 +2590,35 @@ namespace System {
return false;
}
-#if FEATURE_FUSION
- private static AppDomainSetup InternalCreateDomainSetup(String imageLocation)
- {
- int i = imageLocation.LastIndexOf('\\');
-
- Contract.Assert(i != -1, "invalid image location");
-
- AppDomainSetup info = new AppDomainSetup();
- info.ApplicationBase = imageLocation.Substring(0, i+1);
-
- StringBuilder config = new StringBuilder(imageLocation.Substring(i+1));
- config.Append(AppDomainSetup.ConfigurationExtension);
- info.ConfigurationFile = config.ToString();
-
- return info;
- }
-
- // Used by the validator for testing but not executing an assembly
- private static AppDomain InternalCreateDomain(String imageLocation)
- {
- AppDomainSetup info = InternalCreateDomainSetup(imageLocation);
- return CreateDomain("Validator",
- null,
- info);
- }
-
- [System.Security.SecurityCritical] // auto-generated
- private void InternalSetDomainContext(String imageLocation)
- {
- SetupFusionStore(InternalCreateDomainSetup(imageLocation), null);
- }
-#endif
-
#if FEATURE_APPDOMAIN_RESOURCE_MONITORING
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void nEnableMonitoring();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool nMonitoringIsEnabled();
// return -1 if ARM is not supported.
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern Int64 nGetTotalProcessorTime();
// return -1 if ARM is not supported.
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern Int64 nGetTotalAllocatedMemorySize();
// return -1 if ARM is not supported.
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern Int64 nGetLastSurvivedMemorySize();
// return -1 if ARM is not supported.
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern Int64 nGetLastSurvivedProcessMemorySize();
public static bool MonitoringIsEnabled
{
- [System.Security.SecurityCritical]
get {
return nMonitoringIsEnabled();
}
- [System.Security.SecurityCritical]
set {
if (value == false)
{
@@ -4554,7 +2635,6 @@ namespace System {
// Throws NotSupportedException if ARM is not enabled.
public TimeSpan MonitoringTotalProcessorTime
{
- [System.Security.SecurityCritical]
get {
Int64 i64ProcessorTime = nGetTotalProcessorTime();
if (i64ProcessorTime == -1)
@@ -4570,7 +2650,6 @@ namespace System {
// Throws NotSupportedException if ARM is not enabled.
public Int64 MonitoringTotalAllocatedMemorySize
{
- [System.Security.SecurityCritical]
get {
Int64 i64AllocatedMemory = nGetTotalAllocatedMemorySize();
if (i64AllocatedMemory == -1)
@@ -4588,7 +2667,6 @@ namespace System {
// Throws NotSupportedException if ARM is not enabled.
public Int64 MonitoringSurvivedMemorySize
{
- [System.Security.SecurityCritical]
get {
Int64 i64LastSurvivedMemory = nGetLastSurvivedMemorySize();
if (i64LastSurvivedMemory == -1)
@@ -4608,7 +2686,6 @@ namespace System {
// Throws NotSupportedException if ARM is not enabled.
public static Int64 MonitoringSurvivedProcessMemorySize
{
- [System.Security.SecurityCritical]
get {
Int64 i64LastSurvivedProcessMemory = nGetLastSurvivedProcessMemorySize();
if (i64LastSurvivedProcessMemory == -1)
@@ -4619,49 +2696,8 @@ namespace System {
}
}
#endif
-
-#if !FEATURE_CORECLR
- // this method is required so Object.GetType is not made virtual by the compiler
- // _AppDomain.GetType()
- public new Type GetType()
- {
- return base.GetType();
- }
-
- void _AppDomain.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _AppDomain.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _AppDomain.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- // If you implement this method, make sure to include _AppDomain.Invoke in VM\DangerousAPIs.h and
- // include _AppDomain in SystemDomain::IsReflectionInvocationMethod in AppDomain.cpp.
- void _AppDomain.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
-#endif
}
- // CallBacks provide a facility to request execution of some code
- // in another context/appDomain.
- // CrossAppDomainDelegate type is defined for appdomain call backs.
- // The delegate used to request a callbak through the DoCallBack method
- // must be of CrossContextDelegate type.
-#if FEATURE_REMOTING
-[System.Runtime.InteropServices.ComVisible(true)]
- public delegate void CrossAppDomainDelegate();
-#endif
-
/// <summary>
/// Handle used to marshal an AppDomain to the VM (eg QCall). When marshaled via a QCall, the target
/// method in the VM will recieve a QCall::AppDomainHandle parameter.
diff --git a/src/mscorlib/src/System/AppDomainManager.cs b/src/mscorlib/src/System/AppDomainManager.cs
index 291099e199..71bc088d1d 100644
--- a/src/mscorlib/src/System/AppDomainManager.cs
+++ b/src/mscorlib/src/System/AppDomainManager.cs
@@ -8,151 +8,28 @@
// participate in the creation and control the settings of new AppDomains.
//
-namespace System {
- using System.Collections;
- using System.Globalization;
- using System.IO;
+namespace System
+{
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
- using System.Security.Permissions;
- using System.Security.Policy;
- using System.Threading;
-#if FEATURE_CLICKONCE
- using System.Runtime.Hosting;
-#endif
- using System.Runtime.Versioning;
using System.Runtime.InteropServices;
- using System.Diagnostics.Contracts;
-#if FEATURE_APPDOMAINMANAGER_INITOPTIONS
- [Flags]
[System.Runtime.InteropServices.ComVisible(true)]
- public enum AppDomainManagerInitializationOptions {
- None = 0x0000,
- RegisterWithHost = 0x0001
- }
-#endif // FEATURE_APPDOMAINMANAGER_INITOPTIONS
-
- [System.Security.SecurityCritical] // auto-generated_required
- [System.Runtime.InteropServices.ComVisible(true)]
-#if !FEATURE_CORECLR
- [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags = SecurityPermissionFlag.Infrastructure)]
-#endif
-#if FEATURE_REMOTING
- public class AppDomainManager : MarshalByRefObject {
-#else // FEATURE_REMOTING
- public class AppDomainManager {
-#endif // FEATURE_REMOTING
+ public class AppDomainManager : MarshalByRefObject
+ {
public AppDomainManager () {}
-#if FEATURE_REMOTING
- [System.Security.SecurityCritical] // auto-generated
- public virtual AppDomain CreateDomain (string friendlyName,
- Evidence securityInfo,
- AppDomainSetup appDomainInfo) {
- return CreateDomainHelper(friendlyName, securityInfo, appDomainInfo);
- }
-
- [System.Security.SecurityCritical] // auto-generated_required
- [SecurityPermissionAttribute(SecurityAction.Demand, ControlAppDomain = true)]
- protected static AppDomain CreateDomainHelper (string friendlyName,
- Evidence securityInfo,
- AppDomainSetup appDomainInfo) {
- if (friendlyName == null)
- throw new ArgumentNullException("friendlyName", Environment.GetResourceString("ArgumentNull_String"));
-
- Contract.EndContractBlock();
- // If evidence is provided, we check to make sure that is allowed.
- if (securityInfo != null) {
- new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand();
-
- // Check the evidence to ensure that if it expects a sandboxed domain, it actually gets one.
- AppDomain.CheckDomainCreationEvidence(appDomainInfo, securityInfo);
- }
-
- if (appDomainInfo == null) {
- appDomainInfo = new AppDomainSetup();
- }
-
- // If there was no specified AppDomainManager for the new domain, default it to being the same
- // as the current domain's AppDomainManager.
- if (appDomainInfo.AppDomainManagerAssembly == null || appDomainInfo.AppDomainManagerType == null) {
- string inheritedDomainManagerAssembly;
- string inheritedDomainManagerType;
-
- AppDomain.CurrentDomain.GetAppDomainManagerType(out inheritedDomainManagerAssembly,
- out inheritedDomainManagerType);
- if (appDomainInfo.AppDomainManagerAssembly == null) {
- appDomainInfo.AppDomainManagerAssembly = inheritedDomainManagerAssembly;
- }
- if (appDomainInfo.AppDomainManagerType == null) {
- appDomainInfo.AppDomainManagerType = inheritedDomainManagerType;
- }
- }
-
- // If there was no specified TargetFrameworkName for the new domain, default it to the current domain's.
- if (appDomainInfo.TargetFrameworkName == null)
- appDomainInfo.TargetFrameworkName = AppDomain.CurrentDomain.GetTargetFrameworkName();
-
- return AppDomain.nCreateDomain(friendlyName,
- appDomainInfo,
- securityInfo,
- securityInfo == null ? AppDomain.CurrentDomain.InternalEvidence : null,
- AppDomain.CurrentDomain.GetSecurityDescriptor());
- }
-#endif // FEATURE_REMOTING
-
- [System.Security.SecurityCritical]
- public virtual void InitializeNewDomain (AppDomainSetup appDomainInfo) {
+ public virtual void InitializeNewDomain (AppDomainSetup appDomainInfo)
+ {
// By default, InitializeNewDomain does nothing. AppDomain.CreateAppDomainManager relies on this fact.
}
-#if FEATURE_APPDOMAINMANAGER_INITOPTIONS
-
- private AppDomainManagerInitializationOptions m_flags = AppDomainManagerInitializationOptions.None;
- public AppDomainManagerInitializationOptions InitializationFlags {
- get {
- return m_flags;
- }
- set {
- m_flags = value;
- }
- }
-#endif // FEATURE_APPDOMAINMANAGER_INITOPTIONS
-
-#if FEATURE_CLICKONCE
- private ApplicationActivator m_appActivator = null;
- public virtual ApplicationActivator ApplicationActivator {
- get {
- if (m_appActivator == null)
- m_appActivator = new ApplicationActivator();
- return m_appActivator;
- }
- }
-#endif //#if FEATURE_CLICKONCE
-
-#if FEATURE_CAS_POLICY
- public virtual HostSecurityManager HostSecurityManager {
- get {
- return null;
- }
- }
-
- public virtual HostExecutionContextManager HostExecutionContextManager {
- get {
- // By default, the AppDomainManager returns the HostExecutionContextManager.
- return HostExecutionContextManager.GetInternalHostExecutionContextManager();
- }
- }
-#endif // FEATURE_CAS_POLICY
-
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
private static extern void GetEntryAssembly(ObjectHandleOnStack retAssembly);
private Assembly m_entryAssembly = null;
public virtual Assembly EntryAssembly {
- [System.Security.SecurityCritical] // auto-generated
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
@@ -160,14 +37,6 @@ namespace System {
// In the second case, we maintain the old behavior by calling GetEntryAssembly().
if (m_entryAssembly == null)
{
-
-#if FEATURE_CLICKONCE
- AppDomain domain = AppDomain.CurrentDomain;
- if (domain.IsDefaultAppDomain() && domain.ActivationContext != null) {
- ManifestRunner runner = new ManifestRunner(domain, domain.ActivationContext);
- m_entryAssembly = runner.EntryAssembly;
- } else
-#endif //#if FEATURE_CLICKONCE
{
RuntimeAssembly entryAssembly = null;
GetEntryAssembly(JitHelpers.GetObjectHandleOnStack(ref entryAssembly));
@@ -179,7 +48,6 @@ namespace System {
}
internal static AppDomainManager CurrentAppDomainManager {
- [System.Security.SecurityCritical] // auto-generated
get {
return AppDomain.CurrentDomain.DomainManager;
}
@@ -189,32 +57,5 @@ namespace System {
{
return false;
}
-
-#if FEATURE_APPDOMAINMANAGER_INITOPTIONS
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern bool HasHost();
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SecurityCritical]
- [SuppressUnmanagedCodeSecurity]
- private static extern void RegisterWithHost(IntPtr appDomainManager);
-
- internal void RegisterWithHost() {
- if (HasHost()) {
- IntPtr punkAppDomainManager = IntPtr.Zero;
-
- RuntimeHelpers.PrepareConstrainedRegions();
- try {
- punkAppDomainManager = Marshal.GetIUnknownForObject(this);
- RegisterWithHost(punkAppDomainManager);
- }
- finally {
- if (!punkAppDomainManager.IsNull()) {
- Marshal.Release(punkAppDomainManager);
- }
- }
- }
- }
-#endif // FEATURE_APPDOMAINMANAGER_INITOPTIONS
}
}
diff --git a/src/mscorlib/src/System/AppDomainSetup.cs b/src/mscorlib/src/System/AppDomainSetup.cs
index f1057da082..fc8a64c192 100644
--- a/src/mscorlib/src/System/AppDomainSetup.cs
+++ b/src/mscorlib/src/System/AppDomainSetup.cs
@@ -13,28 +13,16 @@
**
=============================================================================*/
-namespace System {
- using System;
-#if FEATURE_CLICKONCE
- using System.Deployment.Internal.Isolation;
- using System.Deployment.Internal.Isolation.Manifest;
- using System.Runtime.Hosting;
-#endif
- using System.Runtime.CompilerServices;
- using System.Runtime;
+namespace System
+{
using System.Text;
- using System.Threading;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
- using System.Reflection;
using System.Security;
- using System.Security.Permissions;
using System.Security.Policy;
- using System.Globalization;
using Path = System.IO.Path;
- using System.Runtime.Versioning;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
- using System.Collections;
using System.Collections.Generic;
[Serializable]
@@ -75,10 +63,6 @@ namespace System {
private const string MACHINE_CONFIGURATION_FILE = "config\\machine.config";
private const string ACTAG_HOST_CONFIG_FILE = "HOST_CONFIG";
-#if FEATURE_FUSION
- private const string LICENSE_FILE = "LICENSE_FILE";
-#endif
-
// Constants from fusionpriv.h
private const string ACTAG_APP_CONFIG_FILE = "APP_CONFIG_FILE";
private const string ACTAG_MACHINE_CONFIG = "MACHINE_CONFIG";
@@ -109,14 +93,9 @@ namespace System {
private AppDomainInitializer _AppDomainInitializer;
[OptionalField(VersionAdded = 2)]
private string[] _AppDomainInitializerArguments;
-#if FEATURE_CLICKONCE
- [OptionalField(VersionAdded = 2)]
- private ActivationArguments _ActivationArguments;
-#endif
-#if FEATURE_CORECLR
+
// On the CoreCLR, this contains just the name of the permission set that we install in the new appdomain.
// Not the ToXml().ToString() of an ApplicationTrust object.
-#endif
[OptionalField(VersionAdded = 2)]
private string _ApplicationTrust;
[OptionalField(VersionAdded = 2)]
@@ -130,11 +109,6 @@ namespace System {
[OptionalField(VersionAdded = 4)]
private string _AppDomainManagerType;
-#if FEATURE_APTCA
- [OptionalField(VersionAdded = 4)]
- private string[] _AptcaVisibleAssemblies;
-#endif
-
// A collection of strings used to indicate which breaking changes shouldn't be applied
// to an AppDomain. We only use the keys, the values are ignored.
[OptionalField(VersionAdded = 4)]
@@ -143,11 +117,6 @@ namespace System {
[OptionalField(VersionAdded = 5)] // This was added in .NET FX v4.5
private String _TargetFrameworkName;
-#if !FEATURE_CORECLR
- [NonSerialized]
- internal AppDomainSortingSetupInfo _AppDomainSortingSetupInfo;
-#endif
-
[OptionalField(VersionAdded = 5)] // This was added in .NET FX v4.5
private bool _CheckedForTargetFrameworkName;
@@ -156,7 +125,6 @@ namespace System {
private bool _UseRandomizedStringHashing;
#endif
- [SecuritySafeCritical]
internal AppDomainSetup(AppDomainSetup copy, bool copyDomainBoundData)
{
string[] mine = Value;
@@ -180,10 +148,8 @@ namespace System {
_LoaderOptimization = copy._LoaderOptimization;
_AppDomainInitializerArguments = copy.AppDomainInitializerArguments;
-#if FEATURE_CLICKONCE
- _ActivationArguments = copy.ActivationArguments;
-#endif
_ApplicationTrust = copy._ApplicationTrust;
+
if (copyDomainBoundData)
_AppDomainInitializer = copy.AppDomainInitializer;
else
@@ -195,21 +161,12 @@ namespace System {
#endif // FEATURE_COMINTEROP
_AppDomainManagerAssembly = copy.AppDomainManagerAssembly;
_AppDomainManagerType = copy.AppDomainManagerType;
-#if FEATURE_APTCA
- _AptcaVisibleAssemblies = copy.PartialTrustVisibleAssemblies;
-#endif
if (copy._CompatFlags != null)
{
SetCompatibilitySwitches(copy._CompatFlags.Keys);
}
-#if !FEATURE_CORECLR
- if(copy._AppDomainSortingSetupInfo != null)
- {
- _AppDomainSortingSetupInfo = new AppDomainSortingSetupInfo(copy._AppDomainSortingSetupInfo);
- }
-#endif
_TargetFrameworkName = copy._TargetFrameworkName;
#if FEATURE_RANDOMIZED_STRING_HASHING
@@ -226,32 +183,6 @@ namespace System {
_LoaderOptimization = LoaderOptimization.NotSpecified;
}
-#if FEATURE_CLICKONCE
- // Creates an AppDomainSetup object from an application identity.
- public AppDomainSetup (ActivationContext activationContext) : this (new ActivationArguments(activationContext)) {}
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public AppDomainSetup (ActivationArguments activationArguments) {
- if (activationArguments == null)
- throw new ArgumentNullException("activationArguments");
- Contract.EndContractBlock();
-
- _LoaderOptimization = LoaderOptimization.NotSpecified;
- ActivationArguments = activationArguments;
-
- Contract.Assert(activationArguments.ActivationContext != null, "Cannot set base directory without activation context");
- string entryPointPath = CmsUtils.GetEntryPointFullPath(activationArguments);
- if (!String.IsNullOrEmpty(entryPointPath))
- SetupDefaults(entryPointPath);
- else
- ApplicationBase = activationArguments.ActivationContext.ApplicationDirectory;
-
- }
-#endif // !FEATURE_CLICKONCE
-
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
internal void SetupDefaults(string imageLocation, bool imageLocationAlreadyNormalized = false) {
char[] sep = {'\\', '/'};
int i = imageLocation.LastIndexOfAny(sep);
@@ -297,37 +228,13 @@ namespace System {
set { _AppDomainManagerType = value; }
}
-#if FEATURE_APTCA
- public string[] PartialTrustVisibleAssemblies
- {
- get { return _AptcaVisibleAssemblies; }
- set {
- if (value != null) {
- _AptcaVisibleAssemblies = (string[])value.Clone();
- Array.Sort<string>(_AptcaVisibleAssemblies, StringComparer.OrdinalIgnoreCase);
- }
- else {
- _AptcaVisibleAssemblies = null;
- }
- }
- }
-#endif
-
public String ApplicationBase
{
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #else
- [System.Security.SecuritySafeCritical]
- #endif
[Pure]
get {
return VerifyDir(GetUnsecureApplicationBase(), false);
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
set {
Value[(int) LoaderInformation.ApplicationBaseValue] = NormalizePath(value, false);
}
@@ -550,7 +457,6 @@ namespace System {
public String ConfigurationFile
{
- [System.Security.SecuritySafeCritical] // auto-generated
get {
return VerifyDir(Value[(int) LoaderInformation.ConfigurationFileValue], true);
}
@@ -604,15 +510,6 @@ namespace System {
public void SetCompatibilitySwitches(IEnumerable<String> switches)
{
-
-#if !FEATURE_CORECLR
- if(_AppDomainSortingSetupInfo != null)
- {
- _AppDomainSortingSetupInfo._useV2LegacySorting = false;
- _AppDomainSortingSetupInfo._useV4LegacySorting = false;
- }
-#endif
-
#if FEATURE_RANDOMIZED_STRING_HASHING
_UseRandomizedStringHashing = false;
#endif
@@ -621,30 +518,11 @@ namespace System {
_CompatFlags = new Dictionary<string, object>();
foreach (String str in switches)
{
-#if !FEATURE_CORECLR
- if(StringComparer.OrdinalIgnoreCase.Equals("NetFx40_Legacy20SortingBehavior", str)) {
- if(_AppDomainSortingSetupInfo == null)
- {
- _AppDomainSortingSetupInfo = new AppDomainSortingSetupInfo();
- }
- _AppDomainSortingSetupInfo._useV2LegacySorting = true;
- }
-
- if(StringComparer.OrdinalIgnoreCase.Equals("NetFx45_Legacy40SortingBehavior", str)) {
- if(_AppDomainSortingSetupInfo == null)
- {
- _AppDomainSortingSetupInfo = new AppDomainSortingSetupInfo();
- }
- _AppDomainSortingSetupInfo._useV4LegacySorting = true;
- }
-#endif
-
#if FEATURE_RANDOMIZED_STRING_HASHING
if(StringComparer.OrdinalIgnoreCase.Equals("UseRandomizedStringHashAlgorithm", str)) {
_UseRandomizedStringHashing = true;
}
#endif
-
_CompatFlags.Add(str, null);
}
}
@@ -671,82 +549,12 @@ namespace System {
set { _CheckedForTargetFrameworkName = value; }
}
-#if !FEATURE_CORECLR
- [SecurityCritical]
- public void SetNativeFunction(string functionName, int functionVersion, IntPtr functionPointer)
- {
- if(functionName == null)
- {
- throw new ArgumentNullException("functionName");
- }
-
- if(functionPointer == IntPtr.Zero)
- {
- throw new ArgumentNullException("functionPointer");
- }
-
- if(String.IsNullOrWhiteSpace(functionName))
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_NPMSInvalidName"), "functionName");
- }
-
- Contract.EndContractBlock();
-
- if(functionVersion < 1)
- {
- throw new ArgumentException(Environment.GetResourceString("ArgumentException_MinSortingVersion", 1, functionName));
- }
-
- if(_AppDomainSortingSetupInfo == null)
- {
- _AppDomainSortingSetupInfo = new AppDomainSortingSetupInfo();
- }
-
- if(String.Equals(functionName, "IsNLSDefinedString", StringComparison.OrdinalIgnoreCase))
- {
- _AppDomainSortingSetupInfo._pfnIsNLSDefinedString = functionPointer;
- }
-
- if (String.Equals(functionName, "CompareStringEx", StringComparison.OrdinalIgnoreCase))
- {
- _AppDomainSortingSetupInfo._pfnCompareStringEx = functionPointer;
- }
-
- if (String.Equals(functionName, "LCMapStringEx", StringComparison.OrdinalIgnoreCase))
- {
- _AppDomainSortingSetupInfo._pfnLCMapStringEx = functionPointer;
- }
-
- if (String.Equals(functionName, "FindNLSStringEx", StringComparison.OrdinalIgnoreCase))
- {
- _AppDomainSortingSetupInfo._pfnFindNLSStringEx = functionPointer;
- }
-
- if (String.Equals(functionName, "CompareStringOrdinal", StringComparison.OrdinalIgnoreCase))
- {
- _AppDomainSortingSetupInfo._pfnCompareStringOrdinal = functionPointer;
- }
-
- if (String.Equals(functionName, "GetNLSVersionEx", StringComparison.OrdinalIgnoreCase))
- {
- _AppDomainSortingSetupInfo._pfnGetNLSVersionEx = functionPointer;
- }
-
- if (String.Equals(functionName, "FindStringOrdinal", StringComparison.OrdinalIgnoreCase))
- {
- _AppDomainSortingSetupInfo._pfnFindStringOrdinal = functionPointer;
- }
- }
-#endif
-
public String DynamicBase
{
- [System.Security.SecuritySafeCritical] // auto-generated
get {
return VerifyDir(Value[(int) LoaderInformation.DynamicBaseValue], true);
}
- [System.Security.SecuritySafeCritical] // auto-generated
set {
if (value == null)
Value[(int) LoaderInformation.DynamicBaseValue] = null;
@@ -772,7 +580,6 @@ namespace System {
}
}
-
public bool DisallowPublisherPolicy
{
get
@@ -835,7 +642,6 @@ namespace System {
}
}
- [System.Security.SecurityCritical] // auto-generated
private String VerifyDir(String dir, bool normalize)
{
if (dir != null) {
@@ -844,22 +650,12 @@ namespace System {
else {
if (normalize)
dir = NormalizePath(dir, true);
-
- // The only way AppDomainSetup is exposed in coreclr is through the AppDomainManager
- // and the AppDomainManager is a SecurityCritical type. Also, all callers of callstacks
- // leading from VerifyDir are SecurityCritical. So we can remove the Demand because
- // we have validated that all callers are SecurityCritical
-#if !FEATURE_CORECLR
- if (IsFilePath(dir))
- new FileIOPermission( FileIOPermissionAccess.PathDiscovery, dir ).Demand();
-#endif // !FEATURE_CORECLR
}
}
return dir;
}
- [System.Security.SecurityCritical] // auto-generated
private void VerifyDirList(String dirs)
{
if (dirs != null) {
@@ -873,7 +669,6 @@ namespace System {
internal String DeveloperPath
{
- [System.Security.SecurityCritical] // auto-generated
get {
String dirs = Value[(int) LoaderInformation.DevPathValue];
VerifyDirList(dirs);
@@ -896,7 +691,7 @@ namespace System {
else
fDelimiter = true;
- newPath.Append(Path.GetFullPathInternal(directories[i]));
+ newPath.Append(Path.GetFullPath(directories[i]));
}
}
@@ -988,83 +783,29 @@ namespace System {
}
}
-#if FEATURE_CLICKONCE
- [XmlIgnoreMember]
- public ActivationArguments ActivationArguments {
- [Pure]
- get {
- return _ActivationArguments;
- }
- set {
- _ActivationArguments = value;
- }
- }
-#endif // !FEATURE_CLICKONCE
-
internal ApplicationTrust InternalGetApplicationTrust()
{
-
if (_ApplicationTrust == null) return null;
-
-
-#if FEATURE_CORECLR
ApplicationTrust grantSet = new ApplicationTrust(NamedPermissionSet.GetBuiltInSet(_ApplicationTrust));
-#else
- SecurityElement securityElement = SecurityElement.FromString(_ApplicationTrust);
- ApplicationTrust grantSet = new ApplicationTrust();
- grantSet.FromXml(securityElement);
-#endif
return grantSet;
}
-#if FEATURE_CORECLR
internal void InternalSetApplicationTrust(String permissionSetName)
{
_ApplicationTrust = permissionSetName;
}
-#else
- internal void InternalSetApplicationTrust(ApplicationTrust value)
- {
- if (value != null)
- {
- _ApplicationTrust = value.ToXml().ToString();
- }
- else
- {
- _ApplicationTrust = null;
- }
- }
-#endif
-#if FEATURE_CLICKONCE
- [XmlIgnoreMember]
- public ApplicationTrust ApplicationTrust
- {
- get {
- return InternalGetApplicationTrust();
- }
- set {
- InternalSetApplicationTrust(value);
- }
- }
-#else // FEATURE_CLICKONCE
[XmlIgnoreMember]
internal ApplicationTrust ApplicationTrust
{
- get {
+ get
+ {
return InternalGetApplicationTrust();
}
-#if !FEATURE_CORECLR
- set {
- InternalSetApplicationTrust(value);
- }
-#endif
}
-#endif // FEATURE_CLICKONCE
public String PrivateBinPath
{
- [System.Security.SecuritySafeCritical] // auto-generated
get {
String dirs = Value[(int) LoaderInformation.PrivateBinPathValue];
VerifyDirList(dirs);
@@ -1083,7 +824,6 @@ namespace System {
}
}
-
public String PrivateBinPathProbe
{
get {
@@ -1104,7 +844,6 @@ namespace System {
public String ShadowCopyDirectories
{
- [System.Security.SecuritySafeCritical] // auto-generated
get {
String dirs = Value[(int) LoaderInformation.ShadowCopyDirectoriesValue];
VerifyDirList(dirs);
@@ -1147,7 +886,6 @@ namespace System {
public String CachePath
{
- [System.Security.SecuritySafeCritical] // auto-generated
get {
return VerifyDir(Value[(int) LoaderInformation.CachePathValue], false);
}
@@ -1166,7 +904,6 @@ namespace System {
public String LicenseFile
{
- [System.Security.SecuritySafeCritical] // auto-generated
get {
return VerifyDir(Value[(int) LoaderInformation.LicenseFileValue], true);
}
@@ -1229,203 +966,17 @@ namespace System {
}
}
-#if FEATURE_FUSION
- [SecurityCritical]
- internal bool UpdateContextPropertyIfNeeded(LoaderInformation FieldValue, String FieldKey, String UpdatedField, IntPtr fusionContext, AppDomainSetup oldADS)
- {
- String FieldString = Value[(int) FieldValue],
- OldFieldString = (oldADS == null ? null : oldADS.Value[(int) FieldValue]);
- if (FieldString != OldFieldString) { // Compare references since strings are immutable
- UpdateContextProperty(fusionContext, FieldKey, UpdatedField == null ? FieldString : UpdatedField);
- return true;
- }
-
- return false;
- }
-
- [SecurityCritical]
- internal void UpdateBooleanContextPropertyIfNeeded(LoaderInformation FieldValue, String FieldKey, IntPtr fusionContext, AppDomainSetup oldADS)
- {
- if (Value[(int) FieldValue] != null)
- UpdateContextProperty(fusionContext, FieldKey, "true");
- else if (oldADS != null && oldADS.Value[(int) FieldValue] != null)
- UpdateContextProperty(fusionContext, FieldKey, "false");
- }
-
- [SecurityCritical]
- internal static bool ByteArraysAreDifferent(Byte[] A, Byte[] B)
- {
- int length = A.Length;
- if (length != B.Length)
- return true;
-
- for(int i = 0; i < length; i++) {
- if (A[i] != B[i])
- return true;
- }
-
- return false;
- }
-
- [System.Security.SecurityCritical] // auto-generated
- internal static void UpdateByteArrayContextPropertyIfNeeded(Byte[] NewArray, Byte[] OldArray, String FieldKey, IntPtr fusionContext)
- {
- if ((NewArray != null && OldArray == null) ||
- (NewArray == null && OldArray != null) ||
- (NewArray != null && OldArray != null && ByteArraysAreDifferent(NewArray, OldArray)))
- UpdateContextProperty(fusionContext, FieldKey, NewArray);
- }
-
- [System.Security.SecurityCritical] // auto-generated
- internal void SetupFusionContext(IntPtr fusionContext, AppDomainSetup oldADS)
- {
- UpdateContextPropertyIfNeeded(LoaderInformation.ApplicationBaseValue, ApplicationBaseKey, null, fusionContext, oldADS);
- UpdateContextPropertyIfNeeded(LoaderInformation.PrivateBinPathValue, PrivateBinPathKey, null, fusionContext, oldADS);
- UpdateContextPropertyIfNeeded(LoaderInformation.DevPathValue, DeveloperPathKey, null, fusionContext, oldADS);
-
- UpdateBooleanContextPropertyIfNeeded(LoaderInformation.DisallowPublisherPolicyValue, DisallowPublisherPolicyKey, fusionContext, oldADS);
- UpdateBooleanContextPropertyIfNeeded(LoaderInformation.DisallowCodeDownloadValue, DisallowCodeDownloadKey, fusionContext, oldADS);
- UpdateBooleanContextPropertyIfNeeded(LoaderInformation.DisallowBindingRedirectsValue, DisallowBindingRedirectsKey, fusionContext, oldADS);
- UpdateBooleanContextPropertyIfNeeded(LoaderInformation.DisallowAppBaseProbingValue, DisallowAppBaseProbingKey, fusionContext, oldADS);
-
- if(UpdateContextPropertyIfNeeded(LoaderInformation.ShadowCopyFilesValue, ShadowCopyFilesKey, ShadowCopyFiles, fusionContext, oldADS)) {
-
- // If we are asking for shadow copy directories then default to
- // only to the ones that are in the private bin path.
- if(Value[(int) LoaderInformation.ShadowCopyDirectoriesValue] == null)
- ShadowCopyDirectories = BuildShadowCopyDirectories();
-
- UpdateContextPropertyIfNeeded(LoaderInformation.ShadowCopyDirectoriesValue, ShadowCopyDirectoriesKey, null, fusionContext, oldADS);
- }
-
- UpdateContextPropertyIfNeeded(LoaderInformation.CachePathValue, CachePathKey, null, fusionContext, oldADS);
- UpdateContextPropertyIfNeeded(LoaderInformation.PrivateBinPathProbeValue, PrivateBinPathProbeKey, PrivateBinPathProbe, fusionContext, oldADS);
- UpdateContextPropertyIfNeeded(LoaderInformation.ConfigurationFileValue, ConfigurationFileKey, null, fusionContext, oldADS);
-
- UpdateByteArrayContextPropertyIfNeeded(_ConfigurationBytes, oldADS == null ? null : oldADS.GetConfigurationBytes(), ConfigurationBytesKey, fusionContext);
-
- UpdateContextPropertyIfNeeded(LoaderInformation.ApplicationNameValue, ApplicationNameKey, ApplicationName, fusionContext, oldADS);
- UpdateContextPropertyIfNeeded(LoaderInformation.DynamicBaseValue, DynamicBaseKey, null, fusionContext, oldADS);
-
- // Always add the runtime configuration file to the appdomain
- UpdateContextProperty(fusionContext, MachineConfigKey, RuntimeEnvironment.GetRuntimeDirectoryImpl() + RuntimeConfigurationFile);
-
- String hostBindingFile = RuntimeEnvironment.GetHostBindingFile();
- if(hostBindingFile != null || oldADS != null) // If oldADS != null, we don't know the old value of the hostBindingFile, so we force an update even when hostBindingFile == null.
- UpdateContextProperty(fusionContext, HostBindingKey, hostBindingFile);
- }
-
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern void UpdateContextProperty(IntPtr fusionContext, string key, Object value);
-#endif // FEATURE_FUSION
-
static internal int Locate(String s)
{
if(String.IsNullOrEmpty(s))
return -1;
-#if FEATURE_FUSION
-
- // verify assumptions hardcoded into the switch below
- Contract.Assert('A' == ACTAG_APP_CONFIG_FILE[0] , "Assumption violated");
- Contract.Assert('A' == ACTAG_APP_NAME[0] , "Assumption violated");
- Contract.Assert('A' == ACTAG_APP_BASE_URL[0] , "Assumption violated");
- Contract.Assert('B' == ACTAG_BINPATH_PROBE_ONLY[0] , "Assumption violated");
- Contract.Assert('C' == ACTAG_APP_CACHE_BASE[0] , "Assumption violated");
- Contract.Assert('D' == ACTAG_DEV_PATH[0] , "Assumption violated");
- Contract.Assert('D' == ACTAG_APP_DYNAMIC_BASE[0] , "Assumption violated");
- Contract.Assert('F' == ACTAG_FORCE_CACHE_INSTALL[0] , "Assumption violated");
- Contract.Assert('L' == LICENSE_FILE[0] , "Assumption violated");
- Contract.Assert('P' == ACTAG_APP_PRIVATE_BINPATH[0] , "Assumption violated");
- Contract.Assert('S' == ACTAG_APP_SHADOW_COPY_DIRS[0], "Assumption violated");
- Contract.Assert('D' == ACTAG_DISALLOW_APPLYPUBLISHERPOLICY[0], "Assumption violated");
- Contract.Assert('C' == ACTAG_CODE_DOWNLOAD_DISABLED[0], "Assumption violated");
- Contract.Assert('D' == ACTAG_DISALLOW_APP_BINDING_REDIRECTS[0], "Assumption violated");
- Contract.Assert('D' == ACTAG_DISALLOW_APP_BASE_PROBING[0], "Assumption violated");
- Contract.Assert('A' == ACTAG_APP_CONFIG_BLOB[0], "Assumption violated");
-
- switch (s[0]) {
- case 'A':
- if (s == ACTAG_APP_CONFIG_FILE) return (int)LoaderInformation.ConfigurationFileValue;
- if (s == ACTAG_APP_NAME) return (int)LoaderInformation.ApplicationNameValue;
- if (s == ACTAG_APP_BASE_URL) return (int)LoaderInformation.ApplicationBaseValue;
- if (s == ACTAG_APP_CONFIG_BLOB) return (int)LoaderInformation.ConfigurationBytesValue;
- break;
- case 'B':
- if (s == ACTAG_BINPATH_PROBE_ONLY) return (int)LoaderInformation.PrivateBinPathProbeValue;
- break;
- case 'C':
- if (s == ACTAG_APP_CACHE_BASE) return (int)LoaderInformation.CachePathValue;
- if (s == ACTAG_CODE_DOWNLOAD_DISABLED) return (int)LoaderInformation.DisallowCodeDownloadValue;
- break;
- case 'D':
- if (s == ACTAG_DEV_PATH) return (int)LoaderInformation.DevPathValue;
- if (s == ACTAG_APP_DYNAMIC_BASE) return (int)LoaderInformation.DynamicBaseValue;
- if (s == ACTAG_DISALLOW_APPLYPUBLISHERPOLICY) return (int)LoaderInformation.DisallowPublisherPolicyValue;
- if (s == ACTAG_DISALLOW_APP_BINDING_REDIRECTS) return (int)LoaderInformation.DisallowBindingRedirectsValue;
- if (s == ACTAG_DISALLOW_APP_BASE_PROBING) return (int)LoaderInformation.DisallowAppBaseProbingValue;
- break;
- case 'F':
- if (s == ACTAG_FORCE_CACHE_INSTALL) return (int)LoaderInformation.ShadowCopyFilesValue;
- break;
- case 'L':
- if (s == LICENSE_FILE) return (int)LoaderInformation.LicenseFileValue;
- break;
- case 'P':
- if (s == ACTAG_APP_PRIVATE_BINPATH) return (int)LoaderInformation.PrivateBinPathValue;
- break;
- case 'S':
- if (s == ACTAG_APP_SHADOW_COPY_DIRS) return (int)LoaderInformation.ShadowCopyDirectoriesValue;
- break;
- }
-#else
- Contract.Assert('A' == ACTAG_APP_BASE_URL[0] , "Assumption violated");
+
+ Debug.Assert('A' == ACTAG_APP_BASE_URL[0] , "Assumption violated");
if (s[0]=='A' && s == ACTAG_APP_BASE_URL)
return (int)LoaderInformation.ApplicationBaseValue;
-#endif //FEATURE_FUSION
-
return -1;
}
-#if FEATURE_FUSION
- private string BuildShadowCopyDirectories()
- {
- // Default to only to the ones that are in the private bin path.
- String binPath = Value[(int) LoaderInformation.PrivateBinPathValue];
- if(binPath == null)
- return null;
-
- StringBuilder result = StringBuilderCache.Acquire();
- String appBase = Value[(int) LoaderInformation.ApplicationBaseValue];
- if(appBase != null) {
- char[] sep = {';'};
- string[] directories = binPath.Split(sep);
- int size = directories.Length;
- bool appendSlash = !( (appBase[appBase.Length-1] == '/') ||
- (appBase[appBase.Length-1] == '\\') );
-
- if (size == 0) {
- result.Append(appBase);
- if (appendSlash)
- result.Append('\\');
- result.Append(binPath);
- }
- else {
- for(int i = 0; i < size; i++) {
- result.Append(appBase);
- if (appendSlash)
- result.Append('\\');
- result.Append(directories[i]);
-
- if (i < size-1)
- result.Append(';');
- }
- }
- }
-
- return StringBuilderCache.GetStringAndRelease(result);
- }
-#endif // FEATURE_FUSION
#if FEATURE_COMINTEROP
public bool SandboxInterop
diff --git a/src/mscorlib/src/System/ApplicationId.cs b/src/mscorlib/src/System/ApplicationId.cs
index fa8be957e2..93fc37dd99 100644
--- a/src/mscorlib/src/System/ApplicationId.cs
+++ b/src/mscorlib/src/System/ApplicationId.cs
@@ -33,13 +33,13 @@ namespace System {
public ApplicationId (byte[] publicKeyToken, string name, Version version, string processorArchitecture, string culture) {
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (name.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyApplicationName"));
if (version == null)
- throw new ArgumentNullException("version");
+ throw new ArgumentNullException(nameof(version));
if (publicKeyToken == null)
- throw new ArgumentNullException("publicKeyToken");
+ throw new ArgumentNullException(nameof(publicKeyToken));
Contract.EndContractBlock();
m_publicKeyToken = new byte[publicKeyToken.Length];
diff --git a/src/mscorlib/src/System/ArgIterator.cs b/src/mscorlib/src/System/ArgIterator.cs
index 0ce27ed24a..c5bc379505 100644
--- a/src/mscorlib/src/System/ArgIterator.cs
+++ b/src/mscorlib/src/System/ArgIterator.cs
@@ -16,19 +16,16 @@ namespace System {
[StructLayout(LayoutKind.Sequential)]
public struct ArgIterator
{
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern ArgIterator(IntPtr arglist);
// create an arg iterator that points at the first argument that
// is not statically declared (that is the first ... arg)
// 'arglist' is the value returned by the ARGLIST instruction
- [System.Security.SecuritySafeCritical] // auto-generated
public ArgIterator(RuntimeArgumentHandle arglist) : this(arglist.Value)
{
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private unsafe extern ArgIterator(IntPtr arglist, void *ptr);
@@ -36,7 +33,6 @@ namespace System {
// 'arglist' is the value returned by the ARGLIST instruction
// This is much like the C va_start macro
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
public unsafe ArgIterator(RuntimeArgumentHandle arglist, void* ptr) : this(arglist.Value, ptr)
@@ -45,7 +41,6 @@ namespace System {
// Fetch an argument as a typed referece, advance the iterator.
// Throws an exception if past end of argument list
- [System.Security.SecuritySafeCritical] // auto-generated
[CLSCompliant(false)]
public TypedReference GetNextArg()
{
@@ -58,14 +53,12 @@ namespace System {
return result;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
// reference to TypedReference is banned, so have to pass result as void pointer
private unsafe extern void FCallGetNextArg(void * result);
// Alternate version of GetNextArg() intended primarily for IJW code
// generated by VC's "va_arg()" construct.
- [System.Security.SecuritySafeCritical] // auto-generated
[CLSCompliant(false)]
public TypedReference GetNextArg(RuntimeTypeHandle rth)
{
@@ -96,7 +89,6 @@ namespace System {
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
// reference to TypedReference is banned, so have to pass result as void pointer
private unsafe extern void InternalGetNextArg(void * result, RuntimeType rt);
@@ -107,16 +99,13 @@ namespace System {
}
// How many arguments are left in the list
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern int GetRemainingCount();
// Gets the type of the current arg, does NOT advance the iterator
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern unsafe void* _GetNextArgType();
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe RuntimeTypeHandle GetNextArgType()
{
return new RuntimeTypeHandle(Type.GetTypeFromHandleUnsafe((IntPtr)_GetNextArgType()));
diff --git a/src/mscorlib/src/System/ArgumentException.cs b/src/mscorlib/src/System/ArgumentException.cs
index 8edb7e4279..f37b7690a8 100644
--- a/src/mscorlib/src/System/ArgumentException.cs
+++ b/src/mscorlib/src/System/ArgumentException.cs
@@ -82,10 +82,9 @@ namespace System {
get { return m_paramName; }
}
- [System.Security.SecurityCritical] // auto-generated_required
public override void GetObjectData(SerializationInfo info, StreamingContext context) {
if (info==null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
base.GetObjectData(info, context);
diff --git a/src/mscorlib/src/System/ArgumentNullException.cs b/src/mscorlib/src/System/ArgumentNullException.cs
index 4bcb537b81..661ebd29af 100644
--- a/src/mscorlib/src/System/ArgumentNullException.cs
+++ b/src/mscorlib/src/System/ArgumentNullException.cs
@@ -48,7 +48,6 @@ namespace System {
SetErrorCode(__HResults.E_POINTER);
}
- [System.Security.SecurityCritical] // auto-generated_required
protected ArgumentNullException(SerializationInfo info, StreamingContext context) : base(info, context) {
}
}
diff --git a/src/mscorlib/src/System/ArgumentOutOfRangeException.cs b/src/mscorlib/src/System/ArgumentOutOfRangeException.cs
index a54380b39d..78a90db34e 100644
--- a/src/mscorlib/src/System/ArgumentOutOfRangeException.cs
+++ b/src/mscorlib/src/System/ArgumentOutOfRangeException.cs
@@ -89,10 +89,9 @@ namespace System {
get { return m_actualValue; }
}
- [System.Security.SecurityCritical] // auto-generated_required
public override void GetObjectData(SerializationInfo info, StreamingContext context) {
if (info==null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
base.GetObjectData(info, context);
diff --git a/src/mscorlib/src/System/Array.cs b/src/mscorlib/src/System/Array.cs
index 08790490f4..7bb6ebbdd3 100644
--- a/src/mscorlib/src/System/Array.cs
+++ b/src/mscorlib/src/System/Array.cs
@@ -19,6 +19,7 @@ namespace System {
using System.Runtime.ConstrainedExecution;
using System.Runtime.Versioning;
using System.Security;
+ using System.Diagnostics;
using System.Security.Permissions;
using System.Diagnostics.Contracts;
@@ -64,13 +65,12 @@ namespace System {
}
// Create instance will create an array
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe static Array CreateInstance(Type elementType, int length)
{
if ((object)elementType == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.elementType);
if (length < 0)
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.length, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ ThrowHelper.ThrowLengthArgumentOutOfRange_ArgumentOutOfRange_NeedNonNegNum();
Contract.Ensures(Contract.Result<Array>() != null);
Contract.Ensures(Contract.Result<Array>().Length == length);
Contract.Ensures(Contract.Result<Array>().Rank == 1);
@@ -82,7 +82,6 @@ namespace System {
return InternalCreate((void*)t.TypeHandle.Value,1,&length,null);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe static Array CreateInstance(Type elementType, int length1, int length2)
{
if ((object)elementType == null)
@@ -105,7 +104,6 @@ namespace System {
return InternalCreate((void*)t.TypeHandle.Value,2,pLengths,null);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe static Array CreateInstance(Type elementType, int length1, int length2, int length3)
{
if ((object)elementType == null)
@@ -132,7 +130,6 @@ namespace System {
return InternalCreate((void*)t.TypeHandle.Value,3,pLengths,null);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe static Array CreateInstance(Type elementType, params int[] lengths)
{
if ((object)elementType == null)
@@ -186,7 +183,6 @@ namespace System {
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe static Array CreateInstance(Type elementType, int[] lengths,int[] lowerBounds)
{
if (elementType == null)
@@ -219,41 +215,25 @@ namespace System {
fixed(int* pLowerBounds = lowerBounds)
return InternalCreate((void*)t.TypeHandle.Value,lengths.Length,pLengths,pLowerBounds);
}
- [System.Security.SecurityCritical] // auto-generated
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private unsafe static extern Array InternalCreate(void* elementType,int rank,int *pLengths,int *pLowerBounds);
- [SecurityCritical]
-#if !FEATURE_CORECLR
- [PermissionSet(SecurityAction.Assert, Unrestricted = true)]
-#endif
internal static Array UnsafeCreateInstance(Type elementType, int length)
{
return CreateInstance(elementType, length);
}
- [SecurityCritical]
-#if !FEATURE_CORECLR
- [PermissionSet(SecurityAction.Assert, Unrestricted = true)]
-#endif
internal static Array UnsafeCreateInstance(Type elementType, int length1, int length2)
{
return CreateInstance(elementType, length1, length2);
}
- [SecurityCritical]
-#if !FEATURE_CORECLR
- [PermissionSet(SecurityAction.Assert, Unrestricted = true)]
-#endif
internal static Array UnsafeCreateInstance(Type elementType, params int[] lengths)
{
return CreateInstance(elementType, lengths);
}
- [SecurityCritical]
-#if !FEATURE_CORECLR
- [PermissionSet(SecurityAction.Assert, Unrestricted = true)]
-#endif
internal static Array UnsafeCreateInstance(Type elementType, int[] lengths, int[] lowerBounds)
{
return CreateInstance(elementType, lengths, lowerBounds);
@@ -262,7 +242,6 @@ namespace System {
// Copies length elements from sourceArray, starting at index 0, to
// destinationArray, starting at index 0.
//
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
public static void Copy(Array sourceArray, Array destinationArray, int length)
{
@@ -284,7 +263,6 @@ namespace System {
// Copies length elements from sourceArray, starting at sourceIndex, to
// destinationArray, starting at destinationIndex.
//
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
public static void Copy(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length)
{
@@ -295,7 +273,6 @@ namespace System {
// instance & might fail when called from within a CER, or if the
// reliable flag is true, it will either always succeed or always
// throw an exception with no side effects.
- [System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void Copy(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length, bool reliable);
@@ -305,7 +282,6 @@ namespace System {
// compatible array types based on the array element type - this
// method does not support casting, boxing, or primitive widening.
// It will up-cast, assuming the array types are correct.
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static void ConstrainedCopy(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length)
{
@@ -338,13 +314,11 @@ namespace System {
// Sets length elements in array to 0 (or null for Object arrays), starting
// at index.
//
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static extern void Clear(Array array, int index, int length);
// The various Get values...
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe Object GetValue(params int[] indices)
{
if (indices == null)
@@ -359,7 +333,6 @@ namespace System {
return TypedReference.InternalToObject(&elemref);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe Object GetValue(int index)
{
if (Rank != 1)
@@ -371,7 +344,6 @@ namespace System {
return TypedReference.InternalToObject(&elemref);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe Object GetValue(int index1, int index2)
{
if (Rank != 2)
@@ -387,7 +359,6 @@ namespace System {
return TypedReference.InternalToObject(&elemref);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe Object GetValue(int index1, int index2, int index3)
{
if (Rank != 3)
@@ -463,7 +434,6 @@ namespace System {
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe void SetValue(Object value,int index)
{
if (Rank != 1)
@@ -475,7 +445,6 @@ namespace System {
InternalSetValue(&elemref,value);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe void SetValue(Object value,int index1, int index2)
{
if (Rank != 2)
@@ -491,7 +460,6 @@ namespace System {
InternalSetValue(&elemref,value);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe void SetValue(Object value,int index1, int index2, int index3)
{
if (Rank != 3)
@@ -508,7 +476,6 @@ namespace System {
InternalSetValue(&elemref,value);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe void SetValue(Object value,params int[] indices)
{
if (indices == null)
@@ -581,20 +548,17 @@ namespace System {
this.SetValue(value, intIndices);
}
- [System.Security.SecurityCritical] // auto-generated
[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);
// Ideally, we would like to use TypedReference.SetValue instead. Unfortunately, TypedReference.SetValue
// always throws not-supported exception
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private unsafe extern static void InternalSetValue(void * target, Object value);
public extern int Length {
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[MethodImpl(MethodImplOptions.InternalCall)]
get;
@@ -604,7 +568,7 @@ namespace System {
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);
- Contract.Assert( hi - low >= 0, "Length overflow!");
+ Debug.Assert( hi - low >= 0, "Length overflow!");
return low + ((hi - low) >> 1);
}
@@ -619,14 +583,12 @@ namespace System {
[ComVisible(false)]
public extern long LongLength {
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[MethodImpl(MethodImplOptions.InternalCall)]
get;
}
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern int GetLength(int dimension);
@@ -639,25 +601,21 @@ namespace System {
public extern int Rank {
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
get;
}
- [System.Security.SecuritySafeCritical] // auto-generated
[Pure]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public extern int GetUpperBound(int dimension);
- [System.Security.SecuritySafeCritical] // auto-generated
[Pure]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern int GetLowerBound(int dimension);
- [System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern int GetDataPtrOffsetInternal();
@@ -894,7 +852,6 @@ namespace System {
// is larger than the given search value.
//
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public static int BinarySearch(Array array, int index, int length, Object value, IComparer comparer) {
if (array==null)
@@ -904,7 +861,7 @@ namespace System {
if (index < lb)
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
if (length < 0)
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.length, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ ThrowHelper.ThrowLengthArgumentOutOfRange_ArgumentOutOfRange_NeedNonNegNum();
if (array.Length - (index - lb) < length)
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
if (array.Rank != 1)
@@ -965,7 +922,6 @@ namespace System {
return ~lo;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
private static extern bool TrySZBinarySearch(Array sourceArray, int sourceIndex, int count, Object value, out int retVal);
@@ -1002,7 +958,7 @@ namespace System {
if (index < 0)
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
if (length < 0)
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.length, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ ThrowHelper.ThrowLengthArgumentOutOfRange_ArgumentOutOfRange_NeedNonNegNum();
if (array.Length - index < length)
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
@@ -1073,6 +1029,42 @@ namespace System {
return Array.FindIndex(array, match) != -1;
}
+ public static void Fill<T>(T[] array, T value)
+ {
+ if (array == null)
+ {
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
+ }
+
+ for (int i = 0; i < array.Length; i++)
+ {
+ array[i] = value;
+ }
+ }
+
+ public static void Fill<T>(T[] array, T value, int startIndex, int count)
+ {
+ if (array == null)
+ {
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
+ }
+
+ if (startIndex < 0 || startIndex > array.Length)
+ {
+ ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
+ }
+
+ if (count < 0 || startIndex > array.Length - count)
+ {
+ ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count();
+ }
+
+ for (int i = startIndex; i < startIndex + count; i++)
+ {
+ array[i] = value;
+ }
+ }
+
public static T Find<T>(T[] array, Predicate<T> match) {
if( array == null) {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
@@ -1136,11 +1128,11 @@ namespace System {
}
if( startIndex < 0 || startIndex > array.Length ) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
}
if (count < 0 || startIndex > array.Length - count) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_Count);
+ ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count();
}
if( match == null) {
@@ -1205,19 +1197,19 @@ namespace System {
if(array.Length == 0) {
// Special case for 0 length List
if( startIndex != -1) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
}
}
else {
// Make sure we're not out of range
if ( startIndex < 0 || startIndex >= array.Length) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ 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) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_Count);
+ ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count();
}
int endIndex = startIndex - count;
@@ -1293,7 +1285,6 @@ namespace System {
// elements of the array are compared to the given value using the
// Object.Equals method.
//
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public static int IndexOf(Array array, Object value, int startIndex, int count) {
if (array==null)
@@ -1305,9 +1296,9 @@ namespace System {
int lb = array.GetLowerBound(0);
if (startIndex < lb || startIndex > array.Length + lb)
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
if (count < 0 || count > array.Length - startIndex + lb)
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_Count);
+ ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count();
// Try calling a quick native method to handle primitive types.
int retVal;
@@ -1376,11 +1367,11 @@ namespace System {
}
if (startIndex < 0 || startIndex > array.Length ) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
}
if (count < 0 || count > array.Length - startIndex) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_Count);
+ ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count();
}
Contract.Ensures(Contract.Result<int>() < array.Length);
Contract.EndContractBlock();
@@ -1388,7 +1379,6 @@ namespace System {
return EqualityComparer<T>.Default.IndexOf(array, value, startIndex, count);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
private static extern bool TrySZIndexOf(Array sourceArray, int sourceIndex, int count, Object value, out int retVal);
@@ -1429,7 +1419,6 @@ namespace System {
// the array are compared to the given value using the Object.Equals
// method.
//
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public static int LastIndexOf(Array array, Object value, int startIndex, int count) {
if (array==null)
@@ -1442,9 +1431,9 @@ namespace System {
}
if (startIndex < lb || startIndex >= array.Length + lb)
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
if (count < 0)
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_Count);
+ ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count();
if (count > startIndex - lb + 1)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.endIndex, ExceptionResource.ArgumentOutOfRange_EndIndexStartIndex);
if (array.Rank != 1)
@@ -1518,30 +1507,29 @@ namespace System {
// accept -1 and 0 as valid startIndex for compablility reason.
//
if( startIndex != -1 && startIndex != 0) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
}
// only 0 is a valid value for count if array is empty
if( count != 0) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_Count);
+ ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count();
}
return -1;
}
// Make sure we're not out of range
if ( startIndex < 0 || startIndex >= array.Length) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ 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) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_Count);
+ ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count();
}
return EqualityComparer<T>.Default.LastIndexOf(array, value, startIndex, count);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
private static extern bool TrySZLastIndexOf(Array sourceArray, int sourceIndex, int count, Object value, out int retVal);
@@ -1566,7 +1554,6 @@ namespace System {
// index index + (index + count - i - 1).
// Reliability note: This may fail because it may have to box objects.
//
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
public static void Reverse(Array array, int index, int length) {
if (array==null)
@@ -1575,7 +1562,7 @@ namespace System {
if (index < lowerBound)
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
if (length < 0)
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.length, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ ThrowHelper.ThrowLengthArgumentOutOfRange_ArgumentOutOfRange_NeedNonNegNum();
if (array.Length - (index - lowerBound) < length)
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
@@ -1610,11 +1597,44 @@ namespace System {
}
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
private static extern bool TrySZReverse(Array array, int index, int count);
-
+
+ [ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
+ public static void Reverse<T>(T[] array)
+ {
+ if (array == null)
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
+ Contract.EndContractBlock();
+ Reverse(array, 0, array.Length);
+ }
+
+ [ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
+ public static void Reverse<T>(T[] array, int index, int length)
+ {
+ if (array == null)
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
+ if (index < 0)
+ ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
+ if (length < 0)
+ ThrowHelper.ThrowLengthArgumentOutOfRange_ArgumentOutOfRange_NeedNonNegNum();
+ if (array.Length - index < length)
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
+ Contract.EndContractBlock();
+
+ int i = index;
+ int j = index + length - 1;
+ while (i < j)
+ {
+ T temp = array[i];
+ array[i] = array[j];
+ array[j] = temp;
+ i++;
+ j--;
+ }
+ }
+
// Sorts the elements of an array. The sort compares the elements to each
// other using the IComparable interface, which must be implemented
// by all elements of the array.
@@ -1710,7 +1730,6 @@ namespace System {
// the IComparable interface, which in that case must be implemented
// by all elements of the given section of the keys array.
//
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
public static void Sort(Array keys, Array items, int index, int length, IComparer comparer) {
if (keys==null)
@@ -1723,7 +1742,7 @@ namespace System {
if (index < keysLowerBound)
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
if (length < 0)
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.length, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ ThrowHelper.ThrowLengthArgumentOutOfRange_ArgumentOutOfRange_NeedNonNegNum();
if (keys.Length - (index - keysLowerBound) < length || (items != null && (index - keysLowerBound) > items.Length - length))
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
@@ -1752,7 +1771,6 @@ namespace System {
}
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
private static extern bool TrySZSort(Array keys, Array items, int left, int right);
@@ -1799,7 +1817,6 @@ namespace System {
Sort<TKey, TValue>(keys, items, 0, keys.Length, comparer);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
public static void Sort<T>(T[] array, int index, int length, System.Collections.Generic.IComparer<T> comparer) {
if (array==null)
@@ -1807,7 +1824,7 @@ namespace System {
if (index < 0)
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
if (length < 0)
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.length, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ ThrowHelper.ThrowLengthArgumentOutOfRange_ArgumentOutOfRange_NeedNonNegNum();
if (array.Length - index < length)
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
Contract.EndContractBlock();
@@ -1823,7 +1840,6 @@ namespace System {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
public static void Sort<TKey, TValue>(TKey[] keys, TValue[] items, int index, int length, System.Collections.Generic.IComparer<TKey> comparer) {
if (keys==null)
@@ -1831,7 +1847,7 @@ namespace System {
if (index < 0)
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
if (length < 0)
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.length, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ ThrowHelper.ThrowLengthArgumentOutOfRange_ArgumentOutOfRange_NeedNonNegNum();
if (keys.Length - index < length || (items != null && index > items.Length - length))
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
Contract.EndContractBlock();
@@ -1863,8 +1879,7 @@ namespace System {
}
Contract.EndContractBlock();
- IComparer<T> comparer = Comparer<T>.Create(comparison);
- Array.Sort(array, comparer);
+ ArraySortHelper<T>.Sort(array, 0, array.Length, comparison);
}
public static bool TrueForAll<T>(T[] array, Predicate<T> match) {
@@ -1935,120 +1950,7 @@ namespace System {
internal void Sort(int left, int length)
{
-#if FEATURE_CORECLR
- // Since QuickSort and IntrospectiveSort produce different sorting sequence for equal keys the upgrade
- // to IntrospectiveSort was quirked. However since the phone builds always shipped with the new sort aka
- // IntrospectiveSort and we would want to continue using this sort moving forward CoreCLR always uses the new sort.
-
IntrospectiveSort(left, length);
-#else
- if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5)
- {
- IntrospectiveSort(left, length);
- }
- else
- {
- DepthLimitedQuickSort(left, length + left - 1, IntrospectiveSortUtilities.QuickSortDepthThreshold);
- }
-#endif
- }
-
- private void DepthLimitedQuickSort(int left, int right, int depthLimit)
- {
- // Can use the much faster jit helpers for array access.
- do
- {
- if (depthLimit == 0)
- {
- // Add a try block here to detect IComparers (or their
- // underlying IComparables, etc) that are bogus.
- try
- {
- Heapsort(left, right);
- return;
- }
- catch (IndexOutOfRangeException)
- {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_BogusIComparer, ExceptionArgument.comparer);
- }
- catch (Exception e)
- {
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_IComparerFailed, e);
- }
- }
-
- int i = left;
- int j = right;
-
- // pre-sort the low, middle (pivot), and high values in place.
- // this improves performance in the face of already sorted data, or
- // data that is made up of multiple sorted runs appended together.
- int middle = GetMedian(i, j);
-
- // Add a try block here to detect IComparers (or their
- // underlying IComparables, etc) that are bogus.
- try
- {
- SwapIfGreaterWithItems(i, middle); // swap the low with the mid point
- SwapIfGreaterWithItems(i, j); // swap the low with the high
- SwapIfGreaterWithItems(middle, j); // swap the middle with the high
- }
- catch (Exception e)
- {
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_IComparerFailed, e);
- }
- Object x = keys[middle];
- do
- {
- // Add a try block here to detect IComparers (or their
- // underlying IComparables, etc) that are bogus.
- try
- {
- while (comparer.Compare(keys[i], x) < 0) i++;
- while (comparer.Compare(x, keys[j]) < 0) j--;
- }
- catch (IndexOutOfRangeException)
- {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_BogusIComparer, ExceptionArgument.comparer);
- }
- catch (Exception e)
- {
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_IComparerFailed, e);
- }
- Contract.Assert(i >= left && j <= right, "(i>=left && j<=right) Sort failed - Is your IComparer bogus?");
- if (i > j) break;
- if (i < j)
- {
- Object key = keys[i];
- keys[i] = keys[j];
- keys[j] = key;
- if (items != null)
- {
- Object item = items[i];
- items[i] = items[j];
- items[j] = item;
- }
- }
- i++;
- j--;
- } while (i <= j);
-
- // The next iteration of the while loop is to "recursively" sort the larger half of the array and the
- // following calls recursively sort the smaller half. So we subtract one from depthLimit here so
- // both sorts see the new value.
- depthLimit--;
-
- if (j - left <= right - i)
- {
- if (left < j) DepthLimitedQuickSort(left, j, depthLimit);
- left = i;
- }
- else
- {
- if (i < right) DepthLimitedQuickSort(i, right, depthLimit);
- right = j;
- }
- } while (left < right);
}
private void IntrospectiveSort(int left, int length)
@@ -2254,118 +2156,7 @@ namespace System {
internal void Sort(int left, int length)
{
-#if FEATURE_CORECLR
- // Since QuickSort and IntrospectiveSort produce different sorting sequence for equal keys the upgrade
- // to IntrospectiveSort was quirked. However since the phone builds always shipped with the new sort aka
- // IntrospectiveSort and we would want to continue using this sort moving forward CoreCLR always uses the new sort.
-
IntrospectiveSort(left, length);
-#else
- if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5)
- {
- IntrospectiveSort(left, length);
- }
- else
- {
- DepthLimitedQuickSort(left, length + left - 1, IntrospectiveSortUtilities.QuickSortDepthThreshold);
- }
-#endif
- }
-
- private void DepthLimitedQuickSort(int left, int right, int depthLimit)
- {
- // Must use slow Array accessors (GetValue & SetValue)
- do
- {
- if (depthLimit == 0)
- {
- // Add a try block here to detect IComparers (or their
- // underlying IComparables, etc) that are bogus.
- try
- {
- Heapsort(left, right);
- return;
- }
- catch (IndexOutOfRangeException)
- {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_BogusIComparer, ExceptionArgument.comparer);
- }
- catch (Exception e)
- {
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_IComparerFailed, e);
- }
- }
-
- int i = left;
- int j = right;
-
- // pre-sort the low, middle (pivot), and high values in place.
- // this improves performance in the face of already sorted data, or
- // data that is made up of multiple sorted runs appended together.
- int middle = GetMedian(i, j);
- try
- {
- SwapIfGreaterWithItems(i, middle); // swap the low with the mid point
- SwapIfGreaterWithItems(i, j); // swap the low with the high
- SwapIfGreaterWithItems(middle, j); // swap the middle with the high
- }
- catch (Exception e)
- {
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_IComparerFailed, e);
- }
-
- Object x = keys.GetValue(middle);
- do
- {
- // Add a try block here to detect IComparers (or their
- // underlying IComparables, etc) that are bogus.
- try
- {
- while (comparer.Compare(keys.GetValue(i), x) < 0) i++;
- while (comparer.Compare(x, keys.GetValue(j)) < 0) j--;
- }
- catch (IndexOutOfRangeException)
- {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_BogusIComparer, ExceptionArgument.comparer);
- }
- catch (Exception e)
- {
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_IComparerFailed, e);
- }
- Contract.Assert(i >= left && j <= right, "(i>=left && j<=right) Sort failed - Is your IComparer bogus?");
- if (i > j) break;
- if (i < j)
- {
- Object key = keys.GetValue(i);
- keys.SetValue(keys.GetValue(j), i);
- keys.SetValue(key, j);
- if (items != null)
- {
- Object item = items.GetValue(i);
- items.SetValue(items.GetValue(j), i);
- items.SetValue(item, j);
- }
- }
- if (i != Int32.MaxValue) ++i;
- if (j != Int32.MinValue) --j;
- } while (i <= j);
-
- // The next iteration of the while loop is to "recursively" sort the larger half of the array and the
- // following calls recursively sort the smaller half. So we subtract one from depthLimit here so
- // both sorts see the new value.
- depthLimit--;
-
- if (j - left <= right - i)
- {
- if (left < j) DepthLimitedQuickSort(left, j, depthLimit);
- left = i;
- }
- else
- {
- if (i < right) DepthLimitedQuickSort(i, right, depthLimit);
- right = j;
- }
- } while (left < right);
}
private void IntrospectiveSort(int left, int length)
@@ -2530,7 +2321,7 @@ namespace System {
private int _endIndex; // cache array length, since it's a little slow.
internal SZArrayEnumerator(Array array) {
- Contract.Assert(array.Rank == 1 && array.GetLowerBound(0) == 0, "SZArrayEnumerator only works on single dimension arrays w/ a lower bound of zero.");
+ 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;
_endIndex = array.Length;
@@ -2551,8 +2342,8 @@ namespace System {
public Object Current {
get {
- if (_index < 0) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumNotStarted);
- if (_index >= _endIndex) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumEnded);
+ if (_index < 0) ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumNotStarted();
+ if (_index >= _endIndex) ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumEnded();
return _array.GetValue(_index);
}
}
@@ -2629,8 +2420,8 @@ namespace System {
public Object Current {
get {
- if (index < startIndex) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumNotStarted);
- if (_complete) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumEnded);
+ if (index < startIndex) ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumNotStarted();
+ if (_complete) ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumEnded();
return array.GetValue(_indices);
}
}
@@ -2652,7 +2443,6 @@ namespace System {
// if this is an array of value classes and that value class has a default constructor
// then this calls this default constructor on every element in the value class array.
// otherwise this is a no-op. Generally this method is called automatically by the compiler
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern void Initialize();
}
@@ -2689,13 +2479,12 @@ namespace System {
sealed class SZArrayHelper {
// It is never legal to instantiate this class.
private SZArrayHelper() {
- Contract.Assert(false, "Hey! How'd I get here?");
+ Debug.Assert(false, "Hey! How'd I get here?");
}
// -----------------------------------------------------------
// ------- Implement IEnumerable<T> interface methods --------
// -----------------------------------------------------------
- [SecuritySafeCritical]
internal IEnumerator<T> GetEnumerator<T>() {
//! Warning: "this" is an array, not an SZArrayHelper. See comments above
//! or you may introduce a security hole!
@@ -2707,7 +2496,6 @@ namespace System {
// -----------------------------------------------------------
// ------- Implement ICollection<T> interface methods --------
// -----------------------------------------------------------
- [SecuritySafeCritical]
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!
@@ -2716,7 +2504,6 @@ namespace System {
Array.Copy(_this, 0, array, index, _this.Length);
}
- [SecuritySafeCritical]
internal int get_Count<T>() {
//! Warning: "this" is an array, not an SZArrayHelper. See comments above
//! or you may introduce a security hole!
@@ -2727,7 +2514,6 @@ namespace System {
// -----------------------------------------------------------
// ---------- Implement IList<T> interface methods -----------
// -----------------------------------------------------------
- [SecuritySafeCritical]
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!
@@ -2739,7 +2525,6 @@ namespace System {
return _this[index];
}
- [SecuritySafeCritical]
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!
@@ -2756,12 +2541,11 @@ namespace System {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_FixedSizeCollection);
}
- [SecuritySafeCritical]
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) != -1;
+ return Array.IndexOf(_this, value, 0, _this.Length) >= 0;
}
bool get_IsReadOnly<T>() {
@@ -2775,12 +2559,11 @@ namespace System {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- [SecuritySafeCritical]
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);
+ return Array.IndexOf(_this, value, 0, _this.Length);
}
void Insert<T>(int index, T value) {
@@ -2812,7 +2595,7 @@ namespace System {
internal SZGenericArrayEnumerator(T[] array, int endIndex) {
// We allow passing null array in case of empty enumerator.
- Contract.Assert(array != null || endIndex == -1, "endIndex should be -1 in the case of a null array (for the 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;
@@ -2828,8 +2611,8 @@ namespace System {
public T Current {
get {
- if (_index < 0) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumNotStarted);
- if (_index >= _endIndex) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumEnded);
+ if (_index < 0) ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumNotStarted();
+ if (_index >= _endIndex) ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumEnded();
return _array[_index];
}
}
diff --git a/src/mscorlib/src/System/ArraySegment.cs b/src/mscorlib/src/System/ArraySegment.cs
index bc39c2474f..b767e7bd77 100644
--- a/src/mscorlib/src/System/ArraySegment.cs
+++ b/src/mscorlib/src/System/ArraySegment.cs
@@ -16,6 +16,7 @@
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
namespace System
@@ -28,10 +29,10 @@ namespace System
[Serializable]
public struct ArraySegment<T> : IList<T>, IReadOnlyList<T>
{
- private T[] _array;
- private int _offset;
- private int _count;
-
+ private readonly T[] _array;
+ private readonly int _offset;
+ private readonly int _count;
+
public ArraySegment(T[] array)
{
if (array == null)
@@ -64,10 +65,10 @@ namespace System
{
get
{
- Contract.Assert( (null == _array && 0 == _offset && 0 == _count)
+ Debug.Assert( (null == _array && 0 == _offset && 0 == _count)
|| (null != _array && _offset >= 0 && _count >= 0 && _offset + _count <= _array.Length),
"ArraySegment is invalid");
-
+
return _array;
}
}
@@ -83,7 +84,7 @@ namespace System
// after reading each field out of an ArraySegment into their stack.
Contract.Ensures(Contract.Result<int>() >= 0);
- Contract.Assert( (null == _array && 0 == _offset && 0 == _count)
+ Debug.Assert( (null == _array && 0 == _offset && 0 == _count)
|| (null != _array && _offset >= 0 && _count >= 0 && _offset + _count <= _array.Length),
"ArraySegment is invalid");
@@ -102,19 +103,38 @@ namespace System
// after reading each field out of an ArraySegment into their stack.
Contract.Ensures(Contract.Result<int>() >= 0);
- Contract.Assert( (null == _array && 0 == _offset && 0 == _count)
+ Debug.Assert( (null == _array && 0 == _offset && 0 == _count)
|| (null != _array && _offset >= 0 && _count >= 0 && _offset + _count <= _array.Length),
"ArraySegment is invalid");
return _count;
}
}
-
+
+ public Enumerator GetEnumerator()
+ {
+ if (_array == null)
+ ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NullArray);
+ Contract.EndContractBlock();
+
+ return new Enumerator(this);
+ }
+
public override int GetHashCode()
{
- return null == _array
- ? 0
- : _array.GetHashCode() ^ _offset ^ _count;
+ if (_array == null)
+ {
+ 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 override bool Equals(Object obj)
@@ -174,7 +194,7 @@ namespace System
int index = System.Array.IndexOf<T>(_array, item, _offset, _count);
- Contract.Assert(index == -1 ||
+ Debug.Assert(index == -1 ||
(index >= _offset && index < _offset + _count));
return index >= 0 ? index - _offset : -1;
@@ -236,7 +256,7 @@ namespace System
int index = System.Array.IndexOf<T>(_array, item, _offset, _count);
- Contract.Assert(index == -1 ||
+ Debug.Assert(index == -1 ||
(index >= _offset && index < _offset + _count));
return index >= 0;
@@ -259,46 +279,34 @@ namespace System
#endregion
#region IEnumerable<T>
- IEnumerator<T> IEnumerable<T>.GetEnumerator()
- {
- if (_array == null)
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NullArray);
- Contract.EndContractBlock();
- return new ArraySegmentEnumerator(this);
- }
+ IEnumerator<T> IEnumerable<T>.GetEnumerator() => GetEnumerator();
#endregion
#region IEnumerable
- IEnumerator IEnumerable.GetEnumerator()
- {
- if (_array == null)
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NullArray);
- Contract.EndContractBlock();
- return new ArraySegmentEnumerator(this);
- }
+ IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
#endregion
[Serializable]
- private sealed class ArraySegmentEnumerator : IEnumerator<T>
+ public struct Enumerator : IEnumerator<T>
{
- private T[] _array;
- private int _start;
- private int _end;
+ private readonly T[] _array;
+ private readonly int _start;
+ private readonly int _end; // cache Offset + Count, since it's a little slow
private int _current;
- internal ArraySegmentEnumerator(ArraySegment<T> arraySegment)
+ internal Enumerator(ArraySegment<T> arraySegment)
{
Contract.Requires(arraySegment.Array != null);
Contract.Requires(arraySegment.Offset >= 0);
Contract.Requires(arraySegment.Count >= 0);
Contract.Requires(arraySegment.Offset + arraySegment.Count <= arraySegment.Array.Length);
- _array = arraySegment._array;
- _start = arraySegment._offset;
- _end = _start + arraySegment._count;
- _current = _start - 1;
+ _array = arraySegment.Array;
+ _start = arraySegment.Offset;
+ _end = arraySegment.Offset + arraySegment.Count;
+ _current = arraySegment.Offset - 1;
}
public bool MoveNext()
@@ -315,19 +323,15 @@ namespace System
{
get
{
- if (_current < _start) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumNotStarted);
- if (_current >= _end) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumEnded);
+ if (_current < _start)
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumNotStarted();
+ if (_current >= _end)
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumEnded();
return _array[_current];
}
}
- object IEnumerator.Current
- {
- get
- {
- return Current;
- }
- }
+ object IEnumerator.Current => Current;
void IEnumerator.Reset()
{
diff --git a/src/mscorlib/src/System/Attribute.cs b/src/mscorlib/src/System/Attribute.cs
index 6475d8d7e7..e77450e972 100644
--- a/src/mscorlib/src/System/Attribute.cs
+++ b/src/mscorlib/src/System/Attribute.cs
@@ -10,6 +10,7 @@ namespace System {
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Globalization;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Security;
using System.Security.Permissions;
@@ -436,7 +437,6 @@ namespace System {
Environment.GetResourceString("Format_AttributeUsage", type));
}
- [System.Security.SecuritySafeCritical]
private static Attribute[] CreateAttributeArrayHelper(Type elementType, int elementCount)
{
return (Attribute[])Array.UnsafeCreateInstance(elementType, elementCount);
@@ -456,10 +456,10 @@ namespace System {
public static Attribute[] GetCustomAttributes(MemberInfo element, Type type, bool inherit)
{
if (element == null)
- throw new ArgumentNullException("element");
+ throw new ArgumentNullException(nameof(element));
if (type == null)
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
if (!type.IsSubclassOf(typeof(Attribute)) && type != typeof(Attribute))
throw new ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass"));
@@ -486,7 +486,7 @@ namespace System {
public static Attribute[] GetCustomAttributes(MemberInfo element, bool inherit)
{
if (element == null)
- throw new ArgumentNullException("element");
+ throw new ArgumentNullException(nameof(element));
Contract.EndContractBlock();
switch (element.MemberType)
@@ -511,10 +511,10 @@ namespace System {
{
// Returns true if a custom attribute subclass of attributeType class/interface with inheritance walk
if (element == null)
- throw new ArgumentNullException("element");
+ throw new ArgumentNullException(nameof(element));
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType != typeof(Attribute))
throw new ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass"));
@@ -568,16 +568,16 @@ namespace System {
public static Attribute[] GetCustomAttributes(ParameterInfo element, Type attributeType, bool inherit)
{
if (element == null)
- throw new ArgumentNullException("element");
+ throw new ArgumentNullException(nameof(element));
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType != typeof(Attribute))
throw new ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass"));
if (element.Member == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidParameterInfo"), "element");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidParameterInfo"), nameof(element));
Contract.EndContractBlock();
@@ -591,10 +591,10 @@ namespace System {
public static Attribute[] GetCustomAttributes(ParameterInfo element, bool inherit)
{
if (element == null)
- throw new ArgumentNullException("element");
+ throw new ArgumentNullException(nameof(element));
if (element.Member == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidParameterInfo"), "element");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidParameterInfo"), nameof(element));
Contract.EndContractBlock();
@@ -614,10 +614,10 @@ namespace System {
{
// Returns true is a custom attribute subclass of attributeType class/interface with inheritance walk
if (element == null)
- throw new ArgumentNullException("element");
+ throw new ArgumentNullException(nameof(element));
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType != typeof(Attribute))
throw new ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass"));
@@ -637,7 +637,7 @@ namespace System {
return element.IsDefined(attributeType, false);
default:
- Contract.Assert(false, "Invalid type for ParameterInfo member in Attribute class");
+ Debug.Assert(false, "Invalid type for ParameterInfo member in Attribute class");
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidParamInfo"));
}
}
@@ -681,7 +681,7 @@ namespace System {
public static Attribute[] GetCustomAttributes(Module element, bool inherit)
{
if (element == null)
- throw new ArgumentNullException("element");
+ throw new ArgumentNullException(nameof(element));
Contract.EndContractBlock();
return (Attribute[])element.GetCustomAttributes(typeof(Attribute), inherit);
@@ -690,10 +690,10 @@ namespace System {
public static Attribute[] GetCustomAttributes(Module element, Type attributeType, bool inherit)
{
if (element == null)
- throw new ArgumentNullException("element");
+ throw new ArgumentNullException(nameof(element));
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType != typeof(Attribute))
throw new ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass"));
@@ -711,10 +711,10 @@ namespace System {
{
// Returns true is a custom attribute subclass of attributeType class/interface with no inheritance walk
if (element == null)
- throw new ArgumentNullException("element");
+ throw new ArgumentNullException(nameof(element));
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType != typeof(Attribute))
throw new ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass"));
@@ -754,10 +754,10 @@ namespace System {
public static Attribute[] GetCustomAttributes(Assembly element, Type attributeType, bool inherit)
{
if (element == null)
- throw new ArgumentNullException("element");
+ throw new ArgumentNullException(nameof(element));
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType != typeof(Attribute))
throw new ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass"));
@@ -774,7 +774,7 @@ namespace System {
public static Attribute[] GetCustomAttributes(Assembly element, bool inherit)
{
if (element == null)
- throw new ArgumentNullException("element");
+ throw new ArgumentNullException(nameof(element));
Contract.EndContractBlock();
return (Attribute[])element.GetCustomAttributes(typeof(Attribute), inherit);
@@ -789,10 +789,10 @@ namespace System {
{
// Returns true is a custom attribute subclass of attributeType class/interface with no inheritance walk
if (element == null)
- throw new ArgumentNullException("element");
+ throw new ArgumentNullException(nameof(element));
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType != typeof(Attribute))
throw new ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass"));
@@ -830,14 +830,13 @@ namespace System {
#endregion
#region Object Overrides
- [SecuritySafeCritical]
public override bool Equals(Object obj)
{
if (obj == null)
return false;
- RuntimeType thisType = (RuntimeType)this.GetType();
- RuntimeType thatType = (RuntimeType)obj.GetType();
+ Type thisType = this.GetType();
+ Type thatType = obj.GetType();
if (thatType != thisType)
return false;
@@ -845,18 +844,22 @@ namespace System {
Object thisObj = this;
Object thisResult, thatResult;
- FieldInfo[] thisFields = thisType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
-
- for (int i = 0; i < thisFields.Length; i++)
+ while (thisType != typeof(Attribute))
{
- // Visibility check and consistency check are not necessary.
- thisResult = ((RtFieldInfo)thisFields[i]).UnsafeGetValue(thisObj);
- thatResult = ((RtFieldInfo)thisFields[i]).UnsafeGetValue(obj);
+ FieldInfo[] thisFields = thisType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
- if (!AreFieldValuesEqual(thisResult, thatResult))
+ for (int i = 0; i < thisFields.Length; i++)
{
- return false;
+ // Visibility check and consistency check are not necessary.
+ thisResult = ((RtFieldInfo)thisFields[i]).UnsafeGetValue(thisObj);
+ thatResult = ((RtFieldInfo)thisFields[i]).UnsafeGetValue(obj);
+
+ if (!AreFieldValuesEqual(thisResult, thatResult))
+ {
+ return false;
+ }
}
+ thisType = thisType.BaseType;
}
return true;
@@ -887,7 +890,7 @@ namespace System {
// Attributes can only contain single-dimension arrays, so we don't need to worry about
// multidimensional arrays.
- Contract.Assert(thisValueArray.Rank == 1 && thatValueArray.Rank == 1);
+ Debug.Assert(thisValueArray.Rank == 1 && thatValueArray.Rank == 1);
for (int j = 0; j < thisValueArray.Length; j++)
{
if (!AreFieldValuesEqual(thisValueArray.GetValue(j), thatValueArray.GetValue(j)))
@@ -901,7 +904,7 @@ namespace System {
// An object of type Attribute will cause a stack overflow.
// However, this should never happen because custom attributes cannot contain values other than
// constants, single-dimensional arrays and typeof expressions.
- Contract.Assert(!(thisValue is Attribute));
+ Debug.Assert(!(thisValue is Attribute));
if (!thisValue.Equals(thatValue))
return false;
}
@@ -909,32 +912,36 @@ namespace System {
return true;
}
- [SecuritySafeCritical]
public override int GetHashCode()
{
Type type = GetType();
- FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
- Object vThis = null;
-
- for (int i = 0; i < fields.Length; i++)
+ while (type != typeof(Attribute))
{
- // Visibility check and consistency check are not necessary.
- Object fieldValue = ((RtFieldInfo)fields[i]).UnsafeGetValue(this);
+ FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
+ Object vThis = null;
- // The hashcode of an array ignores the contents of the array, so it can produce
- // different hashcodes for arrays with the same contents.
- // Since we do deep comparisons of arrays in Equals(), this means Equals and GetHashCode will
- // be inconsistent for arrays. Therefore, we ignore hashes of arrays.
- if (fieldValue != null && !fieldValue.GetType().IsArray)
- vThis = fieldValue;
+ for (int i = 0; i < fields.Length; i++)
+ {
+ // Visibility check and consistency check are not necessary.
+ Object fieldValue = ((RtFieldInfo)fields[i]).UnsafeGetValue(this);
+
+ // The hashcode of an array ignores the contents of the array, so it can produce
+ // different hashcodes for arrays with the same contents.
+ // Since we do deep comparisons of arrays in Equals(), this means Equals and GetHashCode will
+ // be inconsistent for arrays. Therefore, we ignore hashes of arrays.
+ if (fieldValue != null && !fieldValue.GetType().IsArray)
+ vThis = fieldValue;
+
+ if (vThis != null)
+ break;
+ }
if (vThis != null)
- break;
- }
+ return vThis.GetHashCode();
- if (vThis != null)
- return vThis.GetHashCode();
+ type = type.BaseType;
+ }
return type.GetHashCode();
}
@@ -949,27 +956,5 @@ namespace System {
#region Public Members
public virtual bool IsDefaultAttribute() { return false; }
#endregion
-
-#if !FEATURE_CORECLR
- void _Attribute.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _Attribute.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _Attribute.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- void _Attribute.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
-#endif
}
}
diff --git a/src/mscorlib/src/System/BCLDebug.cs b/src/mscorlib/src/System/BCLDebug.cs
index 9b2ade26fa..0ca6e616f2 100644
--- a/src/mscorlib/src/System/BCLDebug.cs
+++ b/src/mscorlib/src/System/BCLDebug.cs
@@ -119,7 +119,6 @@ namespace System {
[Pure]
[Conditional("_LOGGING")]
- [SecuritySafeCritical]
static public void Log(String message) {
if (AppDomain.CurrentDomain.IsUnloadingForcedFinalize())
return;
@@ -132,7 +131,6 @@ namespace System {
[Pure]
[Conditional("_LOGGING")]
- [SecuritySafeCritical]
static public void Log(String switchName, String message) {
if (AppDomain.CurrentDomain.IsUnloadingForcedFinalize())
return;
@@ -160,7 +158,6 @@ 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);
- [SecuritySafeCritical]
private static void CheckRegistry() {
if (AppDomain.CurrentDomain.IsUnloadingForcedFinalize())
return;
@@ -207,7 +204,6 @@ namespace System {
}
}
- [SecuritySafeCritical]
internal static bool CheckEnabled(String switchName) {
if (AppDomain.CurrentDomain.IsUnloadingForcedFinalize())
return false;
@@ -220,7 +216,6 @@ namespace System {
return ((int)logSwitch.MinimumLevel<=(int)LogLevel.Trace);
}
- [SecuritySafeCritical]
private static bool CheckEnabled(String switchName, LogLevel level, out LogSwitch logSwitch) {
if (AppDomain.CurrentDomain.IsUnloadingForcedFinalize())
{
@@ -236,7 +231,6 @@ namespace System {
[Pure]
[Conditional("_LOGGING")]
- [SecuritySafeCritical]
public static void Log(String switchName, LogLevel level, params Object[]messages) {
if (AppDomain.CurrentDomain.IsUnloadingForcedFinalize())
return;
@@ -338,33 +332,9 @@ namespace System {
System.Diagnostics.Log.LogMessage(LoggingLevels.TraceLevel0, logSwitch, trace.ToString());
}
- // For logging errors related to the console - we often can't expect to
- // write to stdout if it doesn't exist.
- [SecuritySafeCritical]
- [Conditional("_DEBUG")]
- internal static void ConsoleError(String msg)
- {
- if (AppDomain.CurrentDomain.IsUnloadingForcedFinalize())
- return;
-
- if (m_MakeConsoleErrorLoggingWork == null) {
- PermissionSet perms = new PermissionSet();
- perms.AddPermission(new EnvironmentPermission(PermissionState.Unrestricted));
- perms.AddPermission(new FileIOPermission(FileIOPermissionAccess.AllAccess, Path.GetFullPath(".")));
- m_MakeConsoleErrorLoggingWork = perms;
- }
- m_MakeConsoleErrorLoggingWork.Assert();
-
- using (TextWriter err = File.AppendText("ConsoleErrors.log"))
- {
- err.WriteLine(msg);
- }
- }
-
// For perf-related asserts. On a debug build, set the registry key
// BCLPerfWarnings to non-zero.
[Conditional("_DEBUG")]
- [SecuritySafeCritical]
internal static void Perf(bool expr, String msg)
{
if (AppDomain.CurrentDomain.IsUnloadingForcedFinalize())
@@ -384,7 +354,6 @@ namespace System {
// BCLCorrectnessWarnings to non-zero.
[Conditional("_DEBUG")]
#if _DEBUG
- [SecuritySafeCritical]
#endif
internal static void Correctness(bool expr, String msg)
{
@@ -409,7 +378,6 @@ namespace System {
}
#if !BIT64 // 32
- [SecuritySafeCritical]
#endif
internal static bool CorrectnessEnabled()
{
diff --git a/src/mscorlib/src/System/BadImageFormatException.cs b/src/mscorlib/src/System/BadImageFormatException.cs
index b71fcc3a49..3f3f4a5b6e 100644
--- a/src/mscorlib/src/System/BadImageFormatException.cs
+++ b/src/mscorlib/src/System/BadImageFormatException.cs
@@ -132,14 +132,11 @@ namespace System {
}
public String FusionLog {
- [System.Security.SecuritySafeCritical] // auto-generated
#pragma warning disable CS0618 // Type or member is obsolete
- [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)]
#pragma warning restore CS0618 // Type or member is obsolete
get { return _fusionLog; }
}
- [System.Security.SecurityCritical] // auto-generated_required
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 e4bb9ddc88..3a6d1c03b0 100644
--- a/src/mscorlib/src/System/BitConverter.cs
+++ b/src/mscorlib/src/System/BitConverter.cs
@@ -15,6 +15,7 @@ namespace System {
using System;
using System.Runtime.CompilerServices;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Security;
@@ -56,7 +57,6 @@ namespace System {
// Converts a short into an array of bytes with length
// two.
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe static byte[] GetBytes(short value)
{
Contract.Ensures(Contract.Result<byte[]>() != null);
@@ -70,7 +70,6 @@ namespace System {
// Converts an int into an array of bytes with length
// four.
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe static byte[] GetBytes(int value)
{
Contract.Ensures(Contract.Result<byte[]>() != null);
@@ -84,7 +83,6 @@ namespace System {
// Converts a long into an array of bytes with length
// eight.
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe static byte[] GetBytes(long value)
{
Contract.Ensures(Contract.Result<byte[]>() != null);
@@ -128,7 +126,6 @@ namespace System {
// Converts a float into an array of bytes with length
// four.
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe static byte[] GetBytes(float value)
{
Contract.Ensures(Contract.Result<byte[]>() != null);
@@ -139,7 +136,6 @@ namespace System {
// Converts a double into an array of bytes with length
// eight.
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe static byte[] GetBytes(double value)
{
Contract.Ensures(Contract.Result<byte[]>() != null);
@@ -156,7 +152,7 @@ namespace System {
}
if ((uint)startIndex >= value.Length) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
}
if (startIndex > value.Length - 2) {
@@ -168,14 +164,13 @@ namespace System {
}
// Converts an array of bytes into a short.
- [System.Security.SecuritySafeCritical] // auto-generated
public static unsafe short ToInt16(byte[] value, int startIndex) {
if( value == null) {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
}
if ((uint) startIndex >= value.Length) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
}
if (startIndex > value.Length -2) {
@@ -200,14 +195,13 @@ namespace System {
}
// Converts an array of bytes into an int.
- [System.Security.SecuritySafeCritical] // auto-generated
public static unsafe int ToInt32 (byte[] value, int startIndex) {
if( value == null) {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
}
if ((uint) startIndex >= value.Length) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
}
if (startIndex > value.Length -4) {
@@ -231,14 +225,13 @@ namespace System {
}
// Converts an array of bytes into a long.
- [System.Security.SecuritySafeCritical] // auto-generated
public static unsafe long ToInt64 (byte[] value, int startIndex) {
if (value == null) {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
}
if ((uint) startIndex >= value.Length) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
}
if (startIndex > value.Length -8) {
@@ -274,7 +267,7 @@ namespace System {
if (value == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
if ((uint)startIndex >= value.Length)
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
if (startIndex > value.Length - 2)
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
Contract.EndContractBlock();
@@ -290,7 +283,7 @@ namespace System {
if (value == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
if ((uint)startIndex >= value.Length)
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
if (startIndex > value.Length - 4)
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
Contract.EndContractBlock();
@@ -306,7 +299,7 @@ namespace System {
if (value == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
if ((uint)startIndex >= value.Length)
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
if (startIndex > value.Length - 8)
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
Contract.EndContractBlock();
@@ -315,13 +308,12 @@ namespace System {
}
// Converts an array of bytes into a float.
- [System.Security.SecuritySafeCritical] // auto-generated
unsafe public static float ToSingle (byte[] value, int startIndex)
{
if (value == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
if ((uint)startIndex >= value.Length)
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
if (startIndex > value.Length - 4)
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
Contract.EndContractBlock();
@@ -331,13 +323,12 @@ namespace System {
}
// Converts an array of bytes into a double.
- [System.Security.SecuritySafeCritical] // auto-generated
unsafe public static double ToDouble (byte[] value, int startIndex)
{
if (value == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
if ((uint)startIndex >= value.Length)
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
if (startIndex > value.Length - 8)
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
Contract.EndContractBlock();
@@ -347,7 +338,7 @@ namespace System {
}
private static char GetHexValue(int i) {
- Contract.Assert( i >=0 && i <16, "i is out of range.");
+ Debug.Assert( i >=0 && i <16, "i is out of range.");
if (i<10) {
return (char)(i + '0');
}
@@ -358,15 +349,15 @@ namespace System {
// Converts an array of bytes into a String.
public static String ToString (byte[] value, int startIndex, int length) {
if (value == null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
if (startIndex < 0 || startIndex >= value.Length && startIndex > 0) { // Don't throw for a 0 length array.
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
}
if (length < 0) {
- throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
+ throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
}
if (startIndex > value.Length - length) {
@@ -380,7 +371,7 @@ namespace System {
if (length > (Int32.MaxValue / 3)) {
// (Int32.MaxValue / 3) == 715,827,882 Bytes == 699 MB
- throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_LengthTooLarge", (Int32.MaxValue / 3)));
+ throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_LengthTooLarge", (Int32.MaxValue / 3)));
}
int chArrayLength = length * 3;
@@ -402,7 +393,7 @@ namespace System {
// Converts an array of bytes into a String.
public static String ToString(byte [] value) {
if (value == null)
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
return ToString(value, 0, value.Length);
@@ -411,7 +402,7 @@ namespace System {
// Converts an array of bytes into a String.
public static String ToString (byte [] value, int startIndex) {
if (value == null)
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
return ToString(value, startIndex, value.Length - startIndex);
@@ -428,24 +419,30 @@ namespace System {
// Converts an array of bytes into a boolean.
public static bool ToBoolean(byte[] value, int startIndex) {
if (value==null)
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
if (startIndex < 0)
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (startIndex > value.Length - 1)
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
Contract.EndContractBlock();
return (value[startIndex]==0)?false:true;
}
- [SecuritySafeCritical]
public static unsafe long DoubleToInt64Bits(double value) {
return *((long *)&value);
}
- [SecuritySafeCritical]
public static unsafe double Int64BitsToDouble(long value) {
return *((double*)&value);
- }
+ }
+
+ public static unsafe int SingleToInt32Bits(float value) {
+ return *((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 c5cd45a428..9aaec9a345 100644
--- a/src/mscorlib/src/System/Boolean.cs
+++ b/src/mscorlib/src/System/Boolean.cs
@@ -151,7 +151,7 @@ namespace System {
// Determines whether a String represents true or false.
//
public static Boolean Parse (String value) {
- if (value==null) throw new ArgumentNullException("value");
+ if (value==null) throw new ArgumentNullException(nameof(value));
Contract.EndContractBlock();
Boolean result = false;
if (!TryParse(value, out result)) {
diff --git a/src/mscorlib/src/System/Buffer.cs b/src/mscorlib/src/System/Buffer.cs
index ea647f1e9a..eee2a81b51 100644
--- a/src/mscorlib/src/System/Buffer.cs
+++ b/src/mscorlib/src/System/Buffer.cs
@@ -11,6 +11,7 @@ namespace System {
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Security;
using System.Runtime;
@@ -28,7 +29,6 @@ namespace System {
// respecting types. This calls memmove internally. The count and
// offset parameters here are in bytes. If you want to use traditional
// array element indices and counts, use Array.Copy.
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void BlockCopy(Array src, int srcOffset,
Array dst, int dstOffset, int count);
@@ -37,7 +37,6 @@ namespace System {
// parameter validation has already been done. The count and offset
// parameters here are in bytes. If you want to use traditional
// array element indices and counts, use Array.Copy.
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void InternalBlockCopy(Array src, int srcOffsetBytes,
Array dst, int dstOffsetBytes, int byteCount);
@@ -47,10 +46,9 @@ namespace System {
// It is however cross platform as the CRT hasn't ported their fast version to 64-bit
// platforms.
//
- [System.Security.SecurityCritical] // auto-generated
internal unsafe static int IndexOfByte(byte* src, byte value, int index, int count)
{
- Contract.Assert(src != null, "src should not be null");
+ Debug.Assert(src != null, "src should not be null");
byte* pByte = src + index;
@@ -122,7 +120,6 @@ namespace System {
// Returns a bool to indicate if the array is of primitive data types
// or not.
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool IsPrimitiveTypeArray(Array array);
@@ -132,24 +129,22 @@ namespace System {
// This essentially does the following:
// return ((byte*)array) + index.
//
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern byte _GetByte(Array array, int index);
- [System.Security.SecuritySafeCritical] // auto-generated
public static byte GetByte(Array array, int index)
{
// Is the array present?
if (array == null)
- throw new ArgumentNullException("array");
+ throw new ArgumentNullException(nameof(array));
// Is it of primitive types?
if (!IsPrimitiveTypeArray(array))
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBePrimArray"), "array");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBePrimArray"), nameof(array));
// Is the index in valid range of the array?
if (index < 0 || index >= _ByteLength(array))
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
return _GetByte(array, index);
}
@@ -160,24 +155,22 @@ namespace System {
// This essentially does the following:
// *(((byte*)array) + index) = value.
//
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void _SetByte(Array array, int index, byte value);
- [System.Security.SecuritySafeCritical] // auto-generated
public static void SetByte(Array array, int index, byte value)
{
// Is the array present?
if (array == null)
- throw new ArgumentNullException("array");
+ throw new ArgumentNullException(nameof(array));
// Is it of primitive types?
if (!IsPrimitiveTypeArray(array))
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBePrimArray"), "array");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBePrimArray"), nameof(array));
// Is the index in valid range of the array?
if (index < 0 || index >= _ByteLength(array))
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
// Make the FCall to do the work
_SetByte(array, index, value);
@@ -190,36 +183,32 @@ namespace System {
// This essentially does the following:
// return array.length * sizeof(array.UnderlyingElementType).
//
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern int _ByteLength(Array array);
- [System.Security.SecuritySafeCritical] // auto-generated
public static int ByteLength(Array array)
{
// Is the array present?
if (array == null)
- throw new ArgumentNullException("array");
+ throw new ArgumentNullException(nameof(array));
// Is it of primitive types?
if (!IsPrimitiveTypeArray(array))
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBePrimArray"), "array");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBePrimArray"), nameof(array));
return _ByteLength(array);
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe static void ZeroMemory(byte* src, long len)
{
while(len-- > 0)
*(src + len) = 0;
}
- [System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal unsafe static void Memcpy(byte[] dest, int destIndex, byte* src, int srcIndex, int len) {
- Contract.Assert( (srcIndex >= 0) && (destIndex >= 0) && (len >= 0), "Index and length must be non-negative!");
- Contract.Assert(dest.Length - destIndex >= len, "not enough bytes in dest");
+ 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)
@@ -229,12 +218,11 @@ namespace System {
}
}
- [SecurityCritical]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal unsafe static void Memcpy(byte* pDest, int destIndex, byte[] src, int srcIndex, int len)
{
- Contract.Assert( (srcIndex >= 0) && (destIndex >= 0) && (len >= 0), "Index and length must be non-negative!");
- Contract.Assert(src.Length - srcIndex >= len, "not enough bytes in src");
+ 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)
@@ -254,7 +242,6 @@ namespace System {
// 1. This method is given access to other internal dlls and this close to release we do not want to change it.
// 2. It is difficult to get this right for arm and again due to release dates we would like to visit it later.
[FriendAccessAllowed]
- [System.Security.SecurityCritical]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
#if ARM
[MethodImplAttribute(MethodImplOptions.InternalCall)]
@@ -262,13 +249,12 @@ namespace System {
#else // ARM
[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
internal unsafe static void Memcpy(byte* dest, byte* src, int len) {
- Contract.Assert(len >= 0, "Negative length in memcopy!");
+ Debug.Assert(len >= 0, "Negative length in memcopy!");
Memmove(dest, src, (uint)len);
}
#endif // ARM
// This method has different signature for x64 and other platforms and is done for performance reasons.
- [System.Security.SecurityCritical]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal unsafe static void Memmove(byte* dest, byte* src, nuint len)
{
@@ -524,7 +510,7 @@ namespace System {
// 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.
- Contract.Assert(end >= 7 && i <= end);
+ 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
@@ -595,7 +581,6 @@ namespace System {
// Non-inlinable wrapper around the QCall that avoids poluting the fast path
// with P/Invoke prolog/epilog.
- [SecurityCritical]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
private unsafe static void _Memmove(byte* dest, byte* src, nuint len)
@@ -605,13 +590,11 @@ namespace System {
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
- [SecurityCritical]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
extern private unsafe static void __Memmove(byte* dest, byte* src, nuint len);
// The attributes on this method are chosen for best JIT performance.
// Please do not edit unless intentional.
- [System.Security.SecurityCritical]
[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public static unsafe void MemoryCopy(void* source, void* destination, long destinationSizeInBytes, long sourceBytesToCopy)
@@ -626,7 +609,6 @@ namespace System {
// The attributes on this method are chosen for best JIT performance.
// Please do not edit unless intentional.
- [System.Security.SecurityCritical]
[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public static unsafe void MemoryCopy(void* source, void* destination, ulong destinationSizeInBytes, ulong sourceBytesToCopy)
diff --git a/src/mscorlib/src/System/ByReference.cs b/src/mscorlib/src/System/ByReference.cs
new file mode 100644
index 0000000000..6f8bb2281e
--- /dev/null
+++ b/src/mscorlib/src/System/ByReference.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.CompilerServices;
+
+namespace System
+{
+ // ByReference<T> is meant to be used to represent "ref T" fields. It is working
+ // around lack of first class support for byref fields in C# and IL. The JIT and
+ // type loader has special handling for it that turns it into a thin wrapper around ref T.
+ internal struct ByReference<T>
+ {
+ private IntPtr _value;
+
+ public ByReference(ref T value)
+ {
+ // TODO-SPAN: This has GC hole. It needs to be JIT intrinsic instead
+ unsafe { _value = (IntPtr)Unsafe.AsPointer(ref value); }
+ }
+
+ public ref T Value
+ {
+ get
+ {
+ // TODO-SPAN: This has GC hole. It needs to be JIT intrinsic instead
+ unsafe { return ref Unsafe.As<IntPtr, T>(ref *(IntPtr*)_value); }
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Byte.cs b/src/mscorlib/src/System/Byte.cs
index 2c24bf6d3b..980412b69e 100644
--- a/src/mscorlib/src/System/Byte.cs
+++ b/src/mscorlib/src/System/Byte.cs
@@ -139,28 +139,24 @@ namespace System {
}
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
public override String ToString() {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt32(m_value, null, NumberFormatInfo.CurrentInfo);
}
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(String format) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt32(m_value, format, NumberFormatInfo.CurrentInfo);
}
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(IFormatProvider provider) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt32(m_value, null, NumberFormatInfo.GetInstance(provider));
}
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(String format, IFormatProvider provider) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt32(m_value, format, NumberFormatInfo.GetInstance(provider));
diff --git a/src/mscorlib/src/System/CLRConfig.cs b/src/mscorlib/src/System/CLRConfig.cs
index 0831c4bb65..01ad7c31ab 100644
--- a/src/mscorlib/src/System/CLRConfig.cs
+++ b/src/mscorlib/src/System/CLRConfig.cs
@@ -19,12 +19,10 @@ namespace System {
internal class CLRConfig {
[FriendAccessAllowed]
- [System.Security.SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[SuppressUnmanagedCodeSecurity]
internal static extern bool CheckLegacyManagedDeflateStream();
- [System.Security.SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[SuppressUnmanagedCodeSecurity]
internal static extern bool CheckThrowUnobservedTaskExceptions();
diff --git a/src/mscorlib/src/System/CfgParser.cs b/src/mscorlib/src/System/CfgParser.cs
index ef368a9020..b21da7fe94 100644
--- a/src/mscorlib/src/System/CfgParser.cs
+++ b/src/mscorlib/src/System/CfgParser.cs
@@ -213,7 +213,6 @@ namespace System
int textLength,
int prefixLength);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern void RunParser(String fileName);
}
@@ -245,11 +244,10 @@ namespace System
return Parse(fileName, configPath, false);
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal ConfigNode Parse(String fileName, String configPath, bool skipSecurityStuff)
{
if (fileName == null)
- throw new ArgumentNullException("fileName");
+ throw new ArgumentNullException(nameof(fileName));
Contract.EndContractBlock();
this.fileName = fileName;
if (configPath[0] == '/'){
@@ -264,7 +262,7 @@ namespace System
}
if (!skipSecurityStuff) {
- (new FileIOPermission( FileIOPermissionAccess.Read, System.IO.Path.GetFullPathInternal( fileName ) )).Demand();
+ (new FileIOPermission(FileIOPermissionAccess.Read, Path.GetFullPath(fileName))).Demand();
}
#pragma warning disable 618
(new SecurityPermission(SecurityPermissionFlag.UnmanagedCode)).Assert();
@@ -291,11 +289,7 @@ namespace System
// Neither Exception nor ApplicationException are the "right" exceptions here.
// Desktop throws ApplicationException for backwards compatibility.
// On Silverlight we don't have ApplicationException, so fall back to Exception.
-#if FEATURE_CORECLR
throw new Exception(message, inner);
-#else
- throw new ApplicationException(message, inner);
-#endif
}
return rootNode;
}
@@ -440,11 +434,7 @@ namespace System
// Neither Exception nor ApplicationException are the "right" exceptions here.
// Desktop throws ApplicationException for backwards compatibility.
// On Silverlight we don't have ApplicationException, so fall back to Exception.
-#if FEATURE_CORECLR
throw new Exception(message);
-#else
- throw new ApplicationException(message);
-#endif
}
}
}
diff --git a/src/mscorlib/src/System/Char.cs b/src/mscorlib/src/System/Char.cs
index ff936c6618..b9c9305932 100644
--- a/src/mscorlib/src/System/Char.cs
+++ b/src/mscorlib/src/System/Char.cs
@@ -18,6 +18,7 @@ namespace System {
using System.Runtime;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
[System.Runtime.InteropServices.ComVisible(true)]
@@ -86,7 +87,7 @@ namespace System {
// Return the Unicode category for Unicode character <= 0x00ff.
private static UnicodeCategory GetLatin1UnicodeCategory(char ch) {
- Contract.Assert(IsLatin1(ch), "Char.GetLatin1UnicodeCategory(): ch should be <= 007f");
+ Debug.Assert(IsLatin1(ch), "Char.GetLatin1UnicodeCategory(): ch should be <= 007f");
return (UnicodeCategory)(categoryForLatin1[(int)ch]);
}
@@ -167,7 +168,7 @@ namespace System {
public static char Parse(String s) {
if (s==null) {
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
}
Contract.EndContractBlock();
@@ -364,7 +365,7 @@ namespace System {
// <;<;Not fully implemented>;>;
public static char ToUpper(char c, CultureInfo culture) {
if (culture==null)
- throw new ArgumentNullException("culture");
+ throw new ArgumentNullException(nameof(culture));
Contract.EndContractBlock();
return culture.TextInfo.ToUpper(c);
}
@@ -393,7 +394,7 @@ namespace System {
// <;<;Not fully implemented>;>;
public static char ToLower(char c, CultureInfo culture) {
if (culture==null)
- throw new ArgumentNullException("culture");
+ throw new ArgumentNullException(nameof(culture));
Contract.EndContractBlock();
return culture.TextInfo.ToLower(c);
}
@@ -508,9 +509,9 @@ namespace System {
public static bool IsControl(String s, int index) {
if (s==null)
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
}
Contract.EndContractBlock();
char c = s[index];
@@ -524,9 +525,9 @@ namespace System {
public static bool IsDigit(String s, int index)
{
if (s==null)
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
}
Contract.EndContractBlock();
char c = s[index];
@@ -539,9 +540,9 @@ namespace System {
public static bool IsLetter(String s, int index)
{
if (s==null)
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
}
Contract.EndContractBlock();
char c = s[index];
@@ -558,9 +559,9 @@ namespace System {
public static bool IsLetterOrDigit(String s, int index)
{
if (s==null)
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
}
Contract.EndContractBlock();
char c = s[index];
@@ -573,9 +574,9 @@ namespace System {
public static bool IsLower(String s, int index)
{
if (s==null)
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
}
Contract.EndContractBlock();
char c = s[index];
@@ -617,9 +618,9 @@ namespace System {
public static bool IsNumber(String s, int index)
{
if (s==null)
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
}
Contract.EndContractBlock();
char c = s[index];
@@ -643,9 +644,9 @@ namespace System {
public static bool IsPunctuation (String s, int index)
{
if (s==null)
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
}
Contract.EndContractBlock();
char c = s[index];
@@ -688,9 +689,9 @@ namespace System {
public static bool IsSeparator(String s, int index)
{
if (s==null)
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
}
Contract.EndContractBlock();
char c = s[index];
@@ -710,10 +711,10 @@ namespace System {
public static bool IsSurrogate(String s, int index)
{
if (s==null) {
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
}
if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
}
Contract.EndContractBlock();
return (IsSurrogate(s[index]));
@@ -745,9 +746,9 @@ namespace System {
public static bool IsSymbol(String s, int index)
{
if (s==null)
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
}
Contract.EndContractBlock();
if (IsLatin1(s[index])) {
@@ -760,9 +761,9 @@ namespace System {
public static bool IsUpper(String s, int index)
{
if (s==null)
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
}
Contract.EndContractBlock();
char c = s[index];
@@ -779,9 +780,9 @@ namespace System {
public static bool IsWhiteSpace(String s, int index)
{
if (s==null)
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
}
Contract.EndContractBlock();
@@ -803,9 +804,9 @@ namespace System {
public static UnicodeCategory GetUnicodeCategory(String s, int index)
{
if (s==null)
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
}
Contract.EndContractBlock();
if (IsLatin1(s[index])) {
@@ -822,9 +823,9 @@ namespace System {
public static double GetNumericValue(String s, int index)
{
if (s==null)
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
}
Contract.EndContractBlock();
return CharUnicodeInfo.GetNumericValue(s, index);
@@ -842,10 +843,10 @@ namespace System {
[Pure]
public static bool IsHighSurrogate(String s, int index) {
if (s == null) {
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
}
if (index < 0 || index >= s.Length) {
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
}
Contract.EndContractBlock();
return (IsHighSurrogate(s[index]));
@@ -862,10 +863,10 @@ namespace System {
[Pure]
public static bool IsLowSurrogate(String s, int index) {
if (s == null) {
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
}
if (index < 0 || index >= s.Length) {
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
}
Contract.EndContractBlock();
return (IsLowSurrogate(s[index]));
@@ -877,10 +878,10 @@ namespace System {
[Pure]
public static bool IsSurrogatePair(String s, int index) {
if (s == null) {
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
}
if (index < 0 || index >= s.Length) {
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
}
Contract.EndContractBlock();
if (index + 1 < s.Length) {
@@ -911,13 +912,12 @@ namespace System {
** Convert an UTF32 value into a surrogate pair.
==============================================================================*/
- [System.Security.SecuritySafeCritical]
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("utf32", Environment.GetResourceString("ArgumentOutOfRange_InvalidUTF32"));
+ throw new ArgumentOutOfRangeException(nameof(utf32), Environment.GetResourceString("ArgumentOutOfRange_InvalidUTF32"));
}
Contract.EndContractBlock();
@@ -945,10 +945,10 @@ namespace System {
public static int ConvertToUtf32(char highSurrogate, char lowSurrogate) {
if (!IsHighSurrogate(highSurrogate)) {
- throw new ArgumentOutOfRangeException("highSurrogate", Environment.GetResourceString("ArgumentOutOfRange_InvalidHighSurrogate"));
+ throw new ArgumentOutOfRangeException(nameof(highSurrogate), Environment.GetResourceString("ArgumentOutOfRange_InvalidHighSurrogate"));
}
if (!IsLowSurrogate(lowSurrogate)) {
- throw new ArgumentOutOfRangeException("lowSurrogate", Environment.GetResourceString("ArgumentOutOfRange_InvalidLowSurrogate"));
+ 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);
@@ -964,11 +964,11 @@ namespace System {
public static int ConvertToUtf32(String s, int index) {
if (s == null) {
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
}
if (index < 0 || index >= s.Length) {
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
Contract.EndContractBlock();
// Check if the character at index is a high surrogate.
@@ -983,15 +983,15 @@ namespace System {
// Found a low surrogate.
return ((temp1 * 0x400) + temp2 + UNICODE_PLANE01_START);
} else {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidHighSurrogate", index), "s");
+ 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), "s");
+ 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), "s");
+ 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.
diff --git a/src/mscorlib/src/System/Collections/ArrayList.cs b/src/mscorlib/src/System/Collections/ArrayList.cs
index 94f4dc74e8..e7f121370b 100644
--- a/src/mscorlib/src/System/Collections/ArrayList.cs
+++ b/src/mscorlib/src/System/Collections/ArrayList.cs
@@ -31,9 +31,7 @@ namespace System.Collections {
// of the ArrayList is automatically increased as required by reallocating the
// internal array.
//
-#if FEATURE_CORECLR
[FriendAccessAllowed]
-#endif
[DebuggerTypeProxy(typeof(System.Collections.ArrayList.ArrayListDebugView))]
[DebuggerDisplay("Count = {Count}")]
[Serializable]
@@ -68,7 +66,7 @@ namespace System.Collections {
// before any reallocations are required.
//
public ArrayList(int capacity) {
- if (capacity < 0) throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_MustBeNonNegNum", "capacity"));
+ if (capacity < 0) throw new ArgumentOutOfRangeException(nameof(capacity), Environment.GetResourceString("ArgumentOutOfRange_MustBeNonNegNum", nameof(capacity)));
Contract.EndContractBlock();
if (capacity == 0)
@@ -83,7 +81,7 @@ namespace System.Collections {
//
public ArrayList(ICollection c) {
if (c==null)
- throw new ArgumentNullException("c", Environment.GetResourceString("ArgumentNull_Collection"));
+ throw new ArgumentNullException(nameof(c), Environment.GetResourceString("ArgumentNull_Collection"));
Contract.EndContractBlock();
int count = c.Count;
@@ -108,7 +106,7 @@ namespace System.Collections {
}
set {
if (value < _size) {
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
+ throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
}
Contract.Ensures(Capacity >= 0);
Contract.EndContractBlock();
@@ -166,12 +164,12 @@ namespace System.Collections {
//
public virtual Object this[int index] {
get {
- if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
Contract.EndContractBlock();
return _items[index];
}
set {
- if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
Contract.EndContractBlock();
_items[index] = value;
_version++;
@@ -188,7 +186,7 @@ namespace System.Collections {
//
public static ArrayList Adapter(IList list) {
if (list==null)
- throw new ArgumentNullException("list");
+ throw new ArgumentNullException(nameof(list));
Contract.Ensures(Contract.Result<ArrayList>() != null);
Contract.EndContractBlock();
return new IListWrapper(list);
@@ -236,9 +234,9 @@ namespace System.Collections {
//
public virtual int BinarySearch(int index, int count, Object value, IComparer comparer) {
if (index < 0)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (_size - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.Ensures(Contract.Result<int>() < Count);
@@ -356,7 +354,7 @@ namespace System.Collections {
//
public static IList FixedSize(IList list) {
if (list==null)
- throw new ArgumentNullException("list");
+ throw new ArgumentNullException(nameof(list));
Contract.Ensures(Contract.Result<IList>() != null);
Contract.EndContractBlock();
return new FixedSizeList(list);
@@ -367,7 +365,7 @@ namespace System.Collections {
//
public static ArrayList FixedSize(ArrayList list) {
if (list==null)
- throw new ArgumentNullException("list");
+ throw new ArgumentNullException(nameof(list));
Contract.Ensures(Contract.Result<ArrayList>() != null);
Contract.EndContractBlock();
return new FixedSizeArrayList(list);
@@ -390,9 +388,9 @@ namespace System.Collections {
//
public virtual IEnumerator GetEnumerator(int index, int count) {
if (index < 0)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (_size - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.Ensures(Contract.Result<IEnumerator>() != null);
@@ -425,7 +423,7 @@ namespace System.Collections {
//
public virtual int IndexOf(Object value, int startIndex) {
if (startIndex > _size)
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
Contract.Ensures(Contract.Result<int>() < Count);
Contract.EndContractBlock();
return Array.IndexOf((Array)_items, value, startIndex, _size - startIndex);
@@ -442,8 +440,8 @@ namespace System.Collections {
//
public virtual int IndexOf(Object value, int startIndex, int count) {
if (startIndex > _size)
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
- if (count <0 || startIndex > _size - count) throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ if (count <0 || startIndex > _size - count) throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
Contract.Ensures(Contract.Result<int>() < Count);
Contract.EndContractBlock();
return Array.IndexOf((Array)_items, value, startIndex, count);
@@ -455,7 +453,7 @@ namespace System.Collections {
//
public virtual void Insert(int index, Object value) {
// Note that insertions at the end are legal.
- if (index < 0 || index > _size) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_ArrayListInsert"));
+ if (index < 0 || index > _size) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_ArrayListInsert"));
//Contract.Ensures(Count == Contract.OldValue(Count) + 1);
Contract.EndContractBlock();
@@ -475,8 +473,8 @@ namespace System.Collections {
//
public virtual void InsertRange(int index, ICollection c) {
if (c==null)
- throw new ArgumentNullException("c", Environment.GetResourceString("ArgumentNull_Collection"));
- if (index < 0 || index > _size) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentNullException(nameof(c), Environment.GetResourceString("ArgumentNull_Collection"));
+ if (index < 0 || index > _size) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
//Contract.Ensures(Count == Contract.OldValue(Count) + c.Count);
Contract.EndContractBlock();
@@ -522,7 +520,7 @@ namespace System.Collections {
public virtual int LastIndexOf(Object value, int startIndex)
{
if (startIndex >= _size)
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
Contract.Ensures(Contract.Result<int>() < Count);
Contract.EndContractBlock();
return LastIndexOf(value, startIndex, startIndex + 1);
@@ -539,7 +537,7 @@ namespace System.Collections {
//
public virtual int LastIndexOf(Object value, int startIndex, int count) {
if (Count != 0 && (startIndex < 0 || count < 0))
- throw new ArgumentOutOfRangeException((startIndex<0 ? "startIndex" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((startIndex<0 ? nameof(startIndex) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.Ensures(Contract.Result<int>() < Count);
Contract.EndContractBlock();
@@ -547,19 +545,17 @@ namespace System.Collections {
return -1;
if (startIndex >= _size || count > startIndex + 1)
- throw new ArgumentOutOfRangeException((startIndex>=_size ? "startIndex" : "count"), Environment.GetResourceString("ArgumentOutOfRange_BiggerThanCollection"));
+ throw new ArgumentOutOfRangeException((startIndex>=_size ? nameof(startIndex) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_BiggerThanCollection"));
return Array.LastIndexOf((Array)_items, value, startIndex, count);
}
// Returns a read-only IList wrapper for the given IList.
//
-#if FEATURE_CORECLR
[FriendAccessAllowed]
-#endif
public static IList ReadOnly(IList list) {
if (list==null)
- throw new ArgumentNullException("list");
+ throw new ArgumentNullException(nameof(list));
Contract.Ensures(Contract.Result<IList>() != null);
Contract.EndContractBlock();
return new ReadOnlyList(list);
@@ -569,7 +565,7 @@ namespace System.Collections {
//
public static ArrayList ReadOnly(ArrayList list) {
if (list==null)
- throw new ArgumentNullException("list");
+ throw new ArgumentNullException(nameof(list));
Contract.Ensures(Contract.Result<ArrayList>() != null);
Contract.EndContractBlock();
return new ReadOnlyArrayList(list);
@@ -591,7 +587,7 @@ namespace System.Collections {
// decreased by one.
//
public virtual void RemoveAt(int index) {
- if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
Contract.Ensures(Count >= 0);
//Contract.Ensures(Count == Contract.OldValue(Count) - 1);
Contract.EndContractBlock();
@@ -608,9 +604,9 @@ namespace System.Collections {
//
public virtual void RemoveRange(int index, int count) {
if (index < 0)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (_size - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.Ensures(Count >= 0);
@@ -632,7 +628,7 @@ namespace System.Collections {
//
public static ArrayList Repeat(Object value, int count) {
if (count < 0)
- throw new ArgumentOutOfRangeException("count",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.Ensures(Contract.Result<ArrayList>() != null);
Contract.EndContractBlock();
@@ -657,9 +653,9 @@ namespace System.Collections {
//
public virtual void Reverse(int index, int count) {
if (index < 0)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (_size - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -671,10 +667,10 @@ namespace System.Collections {
// given collection.
//
public virtual void SetRange(int index, ICollection c) {
- if (c==null) throw new ArgumentNullException("c", Environment.GetResourceString("ArgumentNull_Collection"));
+ if (c==null) throw new ArgumentNullException(nameof(c), Environment.GetResourceString("ArgumentNull_Collection"));
Contract.EndContractBlock();
int count = c.Count;
- if (index < 0 || index > _size - count) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ if (index < 0 || index > _size - count) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
if (count > 0) {
c.CopyTo(_items, index);
@@ -684,7 +680,7 @@ namespace System.Collections {
public virtual ArrayList GetRange(int index, int count) {
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (_size - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.Ensures(Contract.Result<ArrayList>() != null);
@@ -716,9 +712,9 @@ namespace System.Collections {
//
public virtual void Sort(int index, int count, IComparer comparer) {
if (index < 0)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (_size - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -729,10 +725,9 @@ namespace System.Collections {
// Returns a thread-safe wrapper around an IList.
//
- [HostProtection(Synchronization=true)]
public static IList Synchronized(IList list) {
if (list==null)
- throw new ArgumentNullException("list");
+ throw new ArgumentNullException(nameof(list));
Contract.Ensures(Contract.Result<IList>() != null);
Contract.EndContractBlock();
return new SyncIList(list);
@@ -740,10 +735,9 @@ namespace System.Collections {
// Returns a thread-safe wrapper around a ArrayList.
//
- [HostProtection(Synchronization=true)]
public static ArrayList Synchronized(ArrayList list) {
if (list==null)
- throw new ArgumentNullException("list");
+ throw new ArgumentNullException(nameof(list));
Contract.Ensures(Contract.Result<ArrayList>() != null);
Contract.EndContractBlock();
return new SyncArrayList(list);
@@ -764,10 +758,9 @@ namespace System.Collections {
// downcasting all elements. This copy may fail and is an O(n) operation.
// Internally, this implementation calls Array.Copy.
//
- [SecuritySafeCritical]
public virtual Array ToArray(Type type) {
if (type==null)
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
Contract.Ensures(Contract.Result<Array>() != null);
Contract.EndContractBlock();
Array array = Array.UnsafeCreateInstance(type, _size);
@@ -804,7 +797,7 @@ namespace System.Collections {
public override int Capacity {
get { return _list.Count; }
set {
- if (value < Count) throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
+ if (value < Count) throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
Contract.EndContractBlock();
}
}
@@ -854,7 +847,7 @@ namespace System.Collections {
public override int BinarySearch(int index, int count, Object value, IComparer comparer)
{
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (this.Count - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -906,11 +899,11 @@ namespace System.Collections {
public override void CopyTo(int index, Array array, int arrayIndex, int count) {
if (array==null)
- throw new ArgumentNullException("array");
+ throw new ArgumentNullException(nameof(array));
if (index < 0 || arrayIndex < 0)
- throw new ArgumentOutOfRangeException((index < 0) ? "index" : "arrayIndex", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index < 0) ? nameof(index) : nameof(arrayIndex), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if( count < 0)
- throw new ArgumentOutOfRangeException( "count" , Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException( nameof(count) , Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (array.Length - arrayIndex < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
if (array.Rank != 1)
@@ -930,7 +923,7 @@ namespace System.Collections {
public override IEnumerator GetEnumerator(int index, int count) {
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
if (_list.Count - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
@@ -948,8 +941,8 @@ namespace System.Collections {
}
public override int IndexOf(Object value, int startIndex, int count) {
- if (startIndex < 0 || startIndex > this.Count) throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
- if (count < 0 || startIndex > this.Count - count) throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ if (startIndex < 0 || startIndex > this.Count) throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ if (count < 0 || startIndex > this.Count - count) throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
Contract.EndContractBlock();
int endIndex = startIndex + count;
@@ -973,8 +966,8 @@ namespace System.Collections {
public override void InsertRange(int index, ICollection c) {
if (c==null)
- throw new ArgumentNullException("c", Environment.GetResourceString("ArgumentNull_Collection"));
- if (index < 0 || index > this.Count) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentNullException(nameof(c), Environment.GetResourceString("ArgumentNull_Collection"));
+ if (index < 0 || index > this.Count) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
Contract.EndContractBlock();
if( c.Count > 0) {
@@ -1009,8 +1002,8 @@ namespace System.Collections {
if (_list.Count == 0)
return -1;
- if (startIndex < 0 || startIndex >= _list.Count) throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
- if (count < 0 || count > startIndex + 1) throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ if (startIndex < 0 || startIndex >= _list.Count) throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ if (count < 0 || count > startIndex + 1) throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
int endIndex = startIndex - count + 1;
if (value == null) {
@@ -1039,7 +1032,7 @@ namespace System.Collections {
public override void RemoveRange(int index, int count) {
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
if (_list.Count - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
@@ -1055,7 +1048,7 @@ namespace System.Collections {
public override void Reverse(int index, int count) {
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
if (_list.Count - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
@@ -1073,12 +1066,12 @@ namespace System.Collections {
public override void SetRange(int index, ICollection c) {
if (c==null) {
- throw new ArgumentNullException("c", Environment.GetResourceString("ArgumentNull_Collection"));
+ throw new ArgumentNullException(nameof(c), Environment.GetResourceString("ArgumentNull_Collection"));
}
Contract.EndContractBlock();
if (index < 0 || index > _list.Count - c.Count) {
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
if( c.Count > 0) {
@@ -1092,7 +1085,7 @@ namespace System.Collections {
public override ArrayList GetRange(int index, int count) {
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
if (_list.Count - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
@@ -1101,7 +1094,7 @@ namespace System.Collections {
public override void Sort(int index, int count, IComparer comparer) {
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
if (_list.Count - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
@@ -1122,11 +1115,10 @@ namespace System.Collections {
return array;
}
- [SecuritySafeCritical]
public override Array ToArray(Type type)
{
if (type==null)
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
Contract.EndContractBlock();
Array array = Array.UnsafeCreateInstance(type, _list.Count);
_list.CopyTo(array, 0);
@@ -1806,7 +1798,7 @@ namespace System.Collections {
public override ArrayList GetRange(int index, int count) {
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (Count - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -2062,7 +2054,7 @@ namespace System.Collections {
public override ArrayList GetRange(int index, int count) {
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (Count - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -2191,7 +2183,7 @@ namespace System.Collections {
public override void AddRange(ICollection c) {
if( c == null ) {
- throw new ArgumentNullException("c");
+ throw new ArgumentNullException(nameof(c));
}
Contract.EndContractBlock();
@@ -2207,7 +2199,7 @@ namespace System.Collections {
// Other overloads with automatically work
public override int BinarySearch(int index, int count, Object value, IComparer comparer) {
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (_baseSize - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -2224,7 +2216,7 @@ namespace System.Collections {
}
set {
- if (value < Count) throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
+ if (value < Count) throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
Contract.EndContractBlock();
}
}
@@ -2265,11 +2257,11 @@ namespace System.Collections {
public override void CopyTo(Array array, int index) {
if (array==null)
- throw new ArgumentNullException("array");
+ throw new ArgumentNullException(nameof(array));
if (array.Rank != 1)
throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
if (index < 0)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (array.Length - index < _baseSize)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -2280,11 +2272,11 @@ namespace System.Collections {
public override void CopyTo(int index, Array array, int arrayIndex, int count) {
if (array==null)
- throw new ArgumentNullException("array");
+ throw new ArgumentNullException(nameof(array));
if (array.Rank != 1)
throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (array.Length - arrayIndex < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
if (_baseSize - index < count)
@@ -2320,7 +2312,7 @@ namespace System.Collections {
public override IEnumerator GetEnumerator(int index, int count) {
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (_baseSize - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -2331,7 +2323,7 @@ namespace System.Collections {
public override ArrayList GetRange(int index, int count) {
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (_baseSize - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -2356,9 +2348,9 @@ namespace System.Collections {
public override int IndexOf(Object value, int startIndex) {
if (startIndex < 0)
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (startIndex > _baseSize)
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
Contract.EndContractBlock();
InternalUpdateRange();
@@ -2369,10 +2361,10 @@ namespace System.Collections {
public override int IndexOf(Object value, int startIndex, int count) {
if (startIndex < 0 || startIndex > _baseSize)
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
if (count < 0 || (startIndex > _baseSize - count))
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
Contract.EndContractBlock();
InternalUpdateRange();
@@ -2382,7 +2374,7 @@ namespace System.Collections {
}
public override void Insert(int index, Object value) {
- if (index < 0 || index > _baseSize) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ if (index < 0 || index > _baseSize) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
Contract.EndContractBlock();
InternalUpdateRange();
@@ -2392,9 +2384,9 @@ namespace System.Collections {
}
public override void InsertRange(int index, ICollection c) {
- if (index < 0 || index > _baseSize) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ if (index < 0 || index > _baseSize) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
if( c == null) {
- throw new ArgumentNullException("c");
+ throw new ArgumentNullException(nameof(c));
}
Contract.EndContractBlock();
@@ -2426,9 +2418,9 @@ namespace System.Collections {
return -1;
if (startIndex >= _baseSize)
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
if (startIndex < 0)
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
int i = _baseList.LastIndexOf(value, _baseIndex + startIndex, count);
if (i >= 0) return i - _baseIndex;
@@ -2438,7 +2430,7 @@ namespace System.Collections {
// Don't need to override Remove
public override void RemoveAt(int index) {
- if (index < 0 || index >= _baseSize) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ if (index < 0 || index >= _baseSize) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
Contract.EndContractBlock();
InternalUpdateRange();
@@ -2449,7 +2441,7 @@ namespace System.Collections {
public override void RemoveRange(int index, int count) {
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (_baseSize - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -2466,7 +2458,7 @@ namespace System.Collections {
public override void Reverse(int index, int count) {
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (_baseSize - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -2479,7 +2471,7 @@ namespace System.Collections {
[SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
public override void SetRange(int index, ICollection c) {
InternalUpdateRange();
- if (index < 0 || index >= _baseSize) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ if (index < 0 || index >= _baseSize) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
_baseList.SetRange(_baseIndex + index, c);
if( c.Count > 0) {
InternalUpdateVersion();
@@ -2488,7 +2480,7 @@ namespace System.Collections {
public override void Sort(int index, int count, IComparer comparer) {
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (_baseSize - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -2501,12 +2493,12 @@ namespace System.Collections {
public override Object this[int index] {
get {
InternalUpdateRange();
- if (index < 0 || index >= _baseSize) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ if (index < 0 || index >= _baseSize) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
return _baseList[_baseIndex + index];
}
set {
InternalUpdateRange();
- if (index < 0 || index >= _baseSize) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ if (index < 0 || index >= _baseSize) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
_baseList[_baseIndex + index] = value;
InternalUpdateVersion();
}
@@ -2519,10 +2511,9 @@ namespace System.Collections {
return array;
}
- [SecuritySafeCritical]
public override Array ToArray(Type type) {
if (type==null)
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
Contract.EndContractBlock();
InternalUpdateRange();
@@ -2619,7 +2610,7 @@ namespace System.Collections {
public ArrayListDebugView( ArrayList arrayList) {
if( arrayList == null)
- throw new ArgumentNullException("arrayList");
+ throw new ArgumentNullException(nameof(arrayList));
this.arrayList = arrayList;
}
diff --git a/src/mscorlib/src/System/Collections/BitArray.cs b/src/mscorlib/src/System/Collections/BitArray.cs
deleted file mode 100644
index 2f565f83af..0000000000
--- a/src/mscorlib/src/System/Collections/BitArray.cs
+++ /dev/null
@@ -1,524 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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 BitArray class manages a compact array of bit values.
-**
-**
-=============================================================================*/
-namespace System.Collections {
-
- using System;
- using System.Security.Permissions;
- using System.Diagnostics.Contracts;
- // A vector of bits. Use this to store bits efficiently, without having to do bit
- // shifting yourself.
-[System.Runtime.InteropServices.ComVisible(true)]
- [Serializable()] public sealed class BitArray : ICollection, ICloneable {
- private BitArray() {
- }
-
- /*=========================================================================
- ** Allocates space to hold length bit values. All of the values in the bit
- ** array are set to false.
- **
- ** Exceptions: ArgumentException if length < 0.
- =========================================================================*/
- public BitArray(int length)
- : this(length, false) {
- }
-
- /*=========================================================================
- ** Allocates space to hold length bit values. All of the values in the bit
- ** array are set to defaultValue.
- **
- ** Exceptions: ArgumentOutOfRangeException if length < 0.
- =========================================================================*/
- public BitArray(int length, bool defaultValue) {
- if (length < 0) {
- throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- }
- Contract.EndContractBlock();
-
- m_array = new int[GetArrayLength(length, BitsPerInt32)];
- m_length = length;
-
- int fillValue = defaultValue ? unchecked(((int)0xffffffff)) : 0;
- for (int i = 0; i < m_array.Length; i++) {
- m_array[i] = fillValue;
- }
-
- _version = 0;
- }
-
- /*=========================================================================
- ** Allocates space to hold the bit values in bytes. bytes[0] represents
- ** bits 0 - 7, bytes[1] represents bits 8 - 15, etc. The LSB of each byte
- ** represents the lowest index value; bytes[0] & 1 represents bit 0,
- ** bytes[0] & 2 represents bit 1, bytes[0] & 4 represents bit 2, etc.
- **
- ** Exceptions: ArgumentException if bytes == null.
- =========================================================================*/
- public BitArray(byte[] bytes) {
- if (bytes == null) {
- throw new ArgumentNullException(nameof(bytes));
- }
- Contract.EndContractBlock();
- // this value is chosen to prevent overflow when computing m_length.
- // m_length is of type int32 and is exposed as a property, so
- // type of m_length can't be changed to accommodate.
- if (bytes.Length > Int32.MaxValue / BitsPerByte) {
- throw new ArgumentException(Environment.GetResourceString("Argument_ArrayTooLarge", BitsPerByte), nameof(bytes));
- }
-
- m_array = new int[GetArrayLength(bytes.Length, BytesPerInt32)];
- m_length = bytes.Length * BitsPerByte;
-
- int i = 0;
- int j = 0;
- while (bytes.Length - j >= 4) {
- m_array[i++] = (bytes[j] & 0xff) |
- ((bytes[j + 1] & 0xff) << 8) |
- ((bytes[j + 2] & 0xff) << 16) |
- ((bytes[j + 3] & 0xff) << 24);
- j += 4;
- }
-
- Contract.Assert(bytes.Length - j >= 0, "BitArray byteLength problem");
- Contract.Assert(bytes.Length - j < 4, "BitArray byteLength problem #2");
-
- switch (bytes.Length - j) {
- case 3:
- m_array[i] = ((bytes[j + 2] & 0xff) << 16);
- goto case 2;
- // fall through
- case 2:
- m_array[i] |= ((bytes[j + 1] & 0xff) << 8);
- goto case 1;
- // fall through
- case 1:
- m_array[i] |= (bytes[j] & 0xff);
- break;
- }
-
- _version = 0;
- }
-
- public BitArray(bool[] values) {
- if (values == null) {
- throw new ArgumentNullException(nameof(values));
- }
- Contract.EndContractBlock();
-
- m_array = new int[GetArrayLength(values.Length, BitsPerInt32)];
- m_length = values.Length;
-
- for (int i = 0;i<values.Length;i++) {
- if (values[i])
- m_array[i/32] |= (1 << (i%32));
- }
-
- _version = 0;
-
- }
-
- /*=========================================================================
- ** Allocates space to hold the bit values in values. values[0] represents
- ** bits 0 - 31, values[1] represents bits 32 - 63, etc. The LSB of each
- ** integer represents the lowest index value; values[0] & 1 represents bit
- ** 0, values[0] & 2 represents bit 1, values[0] & 4 represents bit 2, etc.
- **
- ** Exceptions: ArgumentException if values == null.
- =========================================================================*/
- public BitArray(int[] values) {
- if (values == null) {
- throw new ArgumentNullException(nameof(values));
- }
- Contract.EndContractBlock();
- // this value is chosen to prevent overflow when computing m_length
- if (values.Length > Int32.MaxValue / BitsPerInt32) {
- throw new ArgumentException(Environment.GetResourceString("Argument_ArrayTooLarge", BitsPerInt32), nameof(values));
- }
-
- m_array = new int[values.Length];
- m_length = values.Length * BitsPerInt32;
-
- Array.Copy(values, m_array, values.Length);
-
- _version = 0;
- }
-
- /*=========================================================================
- ** Allocates a new BitArray with the same length and bit values as bits.
- **
- ** Exceptions: ArgumentException if bits == null.
- =========================================================================*/
- public BitArray(BitArray bits) {
- if (bits == null) {
- throw new ArgumentNullException(nameof(bits));
- }
- Contract.EndContractBlock();
-
- int arrayLength = GetArrayLength(bits.m_length, BitsPerInt32);
- m_array = new int[arrayLength];
- m_length = bits.m_length;
-
- Array.Copy(bits.m_array, m_array, arrayLength);
-
- _version = bits._version;
- }
-
- public bool this[int index] {
- get {
- return Get(index);
- }
- set {
- Set(index,value);
- }
- }
-
- /*=========================================================================
- ** Returns the bit value at position index.
- **
- ** Exceptions: ArgumentOutOfRangeException if index < 0 or
- ** index >= GetLength().
- =========================================================================*/
- public bool Get(int index) {
- if (index < 0 || index >= Length) {
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- }
- Contract.EndContractBlock();
-
- return (m_array[index / 32] & (1 << (index % 32))) != 0;
- }
-
- /*=========================================================================
- ** Sets the bit value at position index to value.
- **
- ** Exceptions: ArgumentOutOfRangeException if index < 0 or
- ** index >= GetLength().
- =========================================================================*/
- public void Set(int index, bool value) {
- if (index < 0 || index >= Length) {
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- }
- Contract.EndContractBlock();
-
- if (value) {
- m_array[index / 32] |= (1 << (index % 32));
- } else {
- m_array[index / 32] &= ~(1 << (index % 32));
- }
-
- _version++;
- }
-
- /*=========================================================================
- ** Sets all the bit values to value.
- =========================================================================*/
- public void SetAll(bool value) {
- int fillValue = value ? unchecked(((int)0xffffffff)) : 0;
- int ints = GetArrayLength(m_length, BitsPerInt32);
- for (int i = 0; i < ints; i++) {
- m_array[i] = fillValue;
- }
-
- _version++;
- }
-
- /*=========================================================================
- ** Returns a reference to the current instance ANDed with value.
- **
- ** Exceptions: ArgumentException if value == null or
- ** value.Length != this.Length.
- =========================================================================*/
- public BitArray And(BitArray value) {
- if (value==null)
- throw new ArgumentNullException(nameof(value));
- if (Length != value.Length)
- throw new ArgumentException(Environment.GetResourceString("Arg_ArrayLengthsDiffer"));
- Contract.EndContractBlock();
-
- int ints = GetArrayLength(m_length, BitsPerInt32);
- for (int i = 0; i < ints; i++) {
- m_array[i] &= value.m_array[i];
- }
-
- _version++;
- return this;
- }
-
- /*=========================================================================
- ** Returns a reference to the current instance ORed with value.
- **
- ** Exceptions: ArgumentException if value == null or
- ** value.Length != this.Length.
- =========================================================================*/
- public BitArray Or(BitArray value) {
- if (value==null)
- throw new ArgumentNullException(nameof(value));
- if (Length != value.Length)
- throw new ArgumentException(Environment.GetResourceString("Arg_ArrayLengthsDiffer"));
- Contract.EndContractBlock();
-
- int ints = GetArrayLength(m_length, BitsPerInt32);
- for (int i = 0; i < ints; i++) {
- m_array[i] |= value.m_array[i];
- }
-
- _version++;
- return this;
- }
-
- /*=========================================================================
- ** Returns a reference to the current instance XORed with value.
- **
- ** Exceptions: ArgumentException if value == null or
- ** value.Length != this.Length.
- =========================================================================*/
- public BitArray Xor(BitArray value) {
- if (value==null)
- throw new ArgumentNullException(nameof(value));
- if (Length != value.Length)
- throw new ArgumentException(Environment.GetResourceString("Arg_ArrayLengthsDiffer"));
- Contract.EndContractBlock();
-
- int ints = GetArrayLength(m_length, BitsPerInt32);
- for (int i = 0; i < ints; i++) {
- m_array[i] ^= value.m_array[i];
- }
-
- _version++;
- return this;
- }
-
- /*=========================================================================
- ** Inverts all the bit values. On/true bit values are converted to
- ** off/false. Off/false bit values are turned on/true. The current instance
- ** is updated and returned.
- =========================================================================*/
- public BitArray Not() {
- int ints = GetArrayLength(m_length, BitsPerInt32);
- for (int i = 0; i < ints; i++) {
- m_array[i] = ~m_array[i];
- }
-
- _version++;
- return this;
- }
-
- public int Length {
- get {
- Contract.Ensures(Contract.Result<int>() >= 0);
- return m_length;
- }
- set {
- if (value < 0) {
- throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- }
- Contract.EndContractBlock();
-
- int newints = GetArrayLength(value, BitsPerInt32);
- if (newints > m_array.Length || newints + _ShrinkThreshold < m_array.Length) {
- // grow or shrink (if wasting more than _ShrinkThreshold ints)
- int[] newarray = new int[newints];
- Array.Copy(m_array, newarray, newints > m_array.Length ? m_array.Length : newints);
- m_array = newarray;
- }
-
- if (value > m_length) {
- // clear high bit values in the last int
- int last = GetArrayLength(m_length, BitsPerInt32) - 1;
- int bits = m_length % 32;
- if (bits > 0) {
- m_array[last] &= (1 << bits) - 1;
- }
-
- // clear remaining int values
- Array.Clear(m_array, last + 1, newints - last - 1);
- }
-
- m_length = value;
- _version++;
- }
- }
-
- // ICollection implementation
- public void CopyTo(Array array, int index)
- {
- if (array == null)
- throw new ArgumentNullException(nameof(array));
-
- if (index < 0)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (array.Rank != 1)
- throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"), nameof(array));
-
- Contract.EndContractBlock();
-
- if (array is int[])
- {
- Array.Copy(m_array, 0, array, index, GetArrayLength(m_length, BitsPerInt32));
- }
- else if (array is byte[])
- {
- int arrayLength = GetArrayLength(m_length, BitsPerByte);
- if ((array.Length - index) < arrayLength)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
-
- byte [] b = (byte[])array;
- for (int i = 0; i < arrayLength; i++)
- b[index + i] = (byte)((m_array[i/4] >> ((i%4)*8)) & 0x000000FF); // Shift to bring the required byte to LSB, then mask
- }
- else if (array is bool[])
- {
- if (array.Length - index < m_length)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
-
- bool [] b = (bool[])array;
- for (int i = 0;i<m_length;i++)
- b[index + i] = ((m_array[i/32] >> (i%32)) & 0x00000001) != 0;
- }
- else
- throw new ArgumentException(Environment.GetResourceString("Arg_BitArrayTypeUnsupported"), nameof(array));
- }
-
- public int Count
- {
- get
- {
- Contract.Ensures(Contract.Result<int>() >= 0);
-
- return m_length;
- }
- }
-
- public Object Clone()
- {
- Contract.Ensures(Contract.Result<Object>() != null);
- Contract.Ensures(((BitArray)Contract.Result<Object>()).Length == this.Length);
-
- return new BitArray(this);
- }
-
- public Object SyncRoot
- {
- get
- {
- if( _syncRoot == null) {
- System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
- }
- return _syncRoot;
- }
- }
-
- public bool IsReadOnly
- {
- get
- {
- return false;
- }
- }
-
- public bool IsSynchronized
- {
- get
- {
- return false;
- }
- }
-
- public IEnumerator GetEnumerator()
- {
- return new BitArrayEnumeratorSimple(this);
- }
-
- // XPerY=n means that n Xs can be stored in 1 Y.
- private const int BitsPerInt32 = 32;
- private const int BytesPerInt32 = 4;
- private const int BitsPerByte = 8;
-
- /// <summary>
- /// Used for conversion between different representations of bit array.
- /// Returns (n+(div-1))/div, rearranged to avoid arithmetic overflow.
- /// For example, in the bit to int case, the straightforward calc would
- /// be (n+31)/32, but that would cause overflow. So instead it's
- /// rearranged to ((n-1)/32) + 1, with special casing for 0.
- ///
- /// Usage:
- /// GetArrayLength(77, BitsPerInt32): returns how many ints must be
- /// allocated to store 77 bits.
- /// </summary>
- /// <param name="n"></param>
- /// <param name="div">use a conversion constant, e.g. BytesPerInt32 to get
- /// how many ints are required to store n bytes</param>
- /// <returns></returns>
- private static int GetArrayLength(int n, int div) {
- Contract.Assert(div > 0, "GetArrayLength: div arg must be greater than 0");
- return n > 0 ? (((n - 1) / div) + 1) : 0;
- }
-
- [Serializable]
- private class BitArrayEnumeratorSimple : IEnumerator, ICloneable
- {
- private BitArray bitarray;
- private int index;
- private int version;
- private bool currentElement;
-
- internal BitArrayEnumeratorSimple(BitArray bitarray) {
- this.bitarray = bitarray;
- this.index = -1;
- version = bitarray._version;
- }
-
- public Object Clone() {
- return MemberwiseClone();
- }
-
- public virtual bool MoveNext() {
- if (version != bitarray._version) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));
- if (index < (bitarray.Count-1)) {
- index++;
- currentElement = bitarray.Get(index);
- return true;
- }
- else
- index = bitarray.Count;
-
- return false;
- }
-
- public virtual Object Current {
- get {
- if (index == -1)
- throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumNotStarted));
- if (index >= bitarray.Count)
- throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumEnded));
- return currentElement;
- }
- }
-
- public void Reset() {
- if (version != bitarray._version) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));
- index = -1;
- }
- }
-
- private int[] m_array;
- private int m_length;
- private int _version;
- [NonSerialized]
- private Object _syncRoot;
-
- private const int _ShrinkThreshold = 256;
- }
-
-}
diff --git a/src/mscorlib/src/System/Collections/CollectionBase.cs b/src/mscorlib/src/System/Collections/CollectionBase.cs
index 1bb08af27a..ae0c0d302d 100644
--- a/src/mscorlib/src/System/Collections/CollectionBase.cs
+++ b/src/mscorlib/src/System/Collections/CollectionBase.cs
@@ -62,7 +62,7 @@ namespace System.Collections {
public void RemoveAt(int index) {
if (index < 0 || index >= Count)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
Contract.EndContractBlock();
Object temp = InnerList[index];
OnValidate(temp);
@@ -101,13 +101,13 @@ namespace System.Collections {
Object IList.this[int index] {
get {
if (index < 0 || index >= Count)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
Contract.EndContractBlock();
return InnerList[index];
}
set {
if (index < 0 || index >= Count)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
Contract.EndContractBlock();
OnValidate(value);
Object temp = InnerList[index];
@@ -163,7 +163,7 @@ namespace System.Collections {
void IList.Insert(int index, Object value) {
if (index < 0 || index > Count)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
Contract.EndContractBlock();
OnValidate(value);
OnInsert(index, value);
@@ -194,7 +194,7 @@ namespace System.Collections {
}
protected virtual void OnValidate(Object value) {
- if (value == null) throw new ArgumentNullException("value");
+ if (value == null) throw new ArgumentNullException(nameof(value));
Contract.EndContractBlock();
}
diff --git a/src/mscorlib/src/System/Collections/Comparer.cs b/src/mscorlib/src/System/Collections/Comparer.cs
index 11e26252a8..0e3c78b529 100644
--- a/src/mscorlib/src/System/Collections/Comparer.cs
+++ b/src/mscorlib/src/System/Collections/Comparer.cs
@@ -36,7 +36,7 @@ namespace System.Collections {
public Comparer(CultureInfo culture) {
if (culture==null) {
- throw new ArgumentNullException("culture");
+ throw new ArgumentNullException(nameof(culture));
}
Contract.EndContractBlock();
m_compareInfo = culture.CompareInfo;
@@ -83,10 +83,9 @@ namespace System.Collections {
throw new ArgumentException(Environment.GetResourceString("Argument_ImplementIComparable"));
}
- [System.Security.SecurityCritical] // auto-generated_required
public void GetObjectData(SerializationInfo info, StreamingContext context) {
if (info==null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
diff --git a/src/mscorlib/src/System/Collections/CompatibleComparer.cs b/src/mscorlib/src/System/Collections/CompatibleComparer.cs
index 85e6c3f0f3..e5d3961245 100644
--- a/src/mscorlib/src/System/Collections/CompatibleComparer.cs
+++ b/src/mscorlib/src/System/Collections/CompatibleComparer.cs
@@ -39,7 +39,7 @@ namespace System.Collections {
public int GetHashCode(Object obj) {
if( obj == null) {
- throw new ArgumentNullException("obj");
+ throw new ArgumentNullException(nameof(obj));
}
Contract.EndContractBlock();
diff --git a/src/mscorlib/src/System/Collections/Concurrent/ConcurrentDictionary.cs b/src/mscorlib/src/System/Collections/Concurrent/ConcurrentDictionary.cs
index d805dc8be7..c1a6f7564c 100644
--- a/src/mscorlib/src/System/Collections/Concurrent/ConcurrentDictionary.cs
+++ b/src/mscorlib/src/System/Collections/Concurrent/ConcurrentDictionary.cs
@@ -28,7 +28,6 @@ using System.Security.Permissions;
namespace System.Collections.Concurrent
{
-
/// <summary>
/// Represents a thread-safe collection of keys and values.
/// </summary>
@@ -38,13 +37,9 @@ namespace System.Collections.Concurrent
/// All public and protected members of <see cref="ConcurrentDictionary{TKey,TValue}"/> are thread-safe and may be used
/// concurrently from multiple threads.
/// </remarks>
-#if !FEATURE_CORECLR
- [Serializable]
-#endif
[ComVisible(false)]
[DebuggerTypeProxy(typeof(Mscorlib_DictionaryDebugView<,>))]
[DebuggerDisplay("Count = {Count}")]
- [HostProtection(Synchronization = true, ExternalThreading = true)]
public class ConcurrentDictionary<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary, IReadOnlyDictionary<TKey, TValue>
{
/// <summary>
@@ -68,41 +63,20 @@ namespace System.Collections.Concurrent
m_comparer = comparer;
}
}
-#if !FEATURE_CORECLR
- [NonSerialized]
-#endif
+
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;
-#if !FEATURE_CORECLR
- [NonSerialized]
-#endif
private readonly bool m_growLockArray; // Whether to dynamically increase the size of the striped lock
// How many times we resized becaused of collisions.
// This is used to make sure we don't resize the dictionary because of multi-threaded Add() calls
// that generate collisions. Whenever a GrowTable() should be the only place that changes this
-#if !FEATURE_CORECLR
- // The field should be have been marked as NonSerialized but because we shipped it without that attribute in 4.5.1.
- // we can't add it back without breaking compat. To maximize compat we are going to keep the OptionalField attribute
- // This will prevent cases where the field was not serialized.
- [OptionalField]
-#endif
private int m_keyRehashCount;
-#if !FEATURE_CORECLR
- [NonSerialized]
-#endif
private int m_budget; // The maximum number of elements per lock before a resize operation is triggered
-#if !FEATURE_CORECLR // These fields are not used in CoreCLR
- private KeyValuePair<TKey, TValue>[] m_serializationArray; // Used for custom serialization
-
- private int m_serializationConcurrencyLevel; // used to save the concurrency level in serialization
-
- private int m_serializationCapacity; // used to save the capacity in serialization
-#endif
// The default concurrency level is DEFAULT_CONCURRENCY_MULTIPLIER * #CPUs. The higher the
// DEFAULT_CONCURRENCY_MULTIPLIER, the more concurrent writes can take place without interference
// and blocking, but also the more expensive operations that require all locks become (e.g. table
@@ -229,7 +203,7 @@ namespace System.Collections.Concurrent
public ConcurrentDictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer)
: this(comparer)
{
- if (collection == null) throw new ArgumentNullException("collection");
+ if (collection == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
InitializeFromCollection(collection);
}
@@ -259,8 +233,8 @@ namespace System.Collections.Concurrent
int concurrencyLevel, IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer)
: this(concurrencyLevel, DEFAULT_CAPACITY, false, comparer)
{
- if (collection == null) throw new ArgumentNullException("collection");
- if (comparer == null) throw new ArgumentNullException("comparer");
+ if (collection == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
+ if (comparer == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.comparer);
InitializeFromCollection(collection);
}
@@ -270,11 +244,11 @@ namespace System.Collections.Concurrent
TValue dummy;
foreach (KeyValuePair<TKey, TValue> pair in collection)
{
- if (pair.Key == null) throw new ArgumentNullException("key");
+ if (pair.Key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
if (!TryAddInternal(pair.Key, pair.Value, false, false, out dummy))
{
- throw new ArgumentException(GetResource("ConcurrentDictionary_SourceContainsDuplicateKeys"));
+ ThrowHelper.ThrowArgumentException(ExceptionResource.ConcurrentDictionary_SourceContainsDuplicateKeys);
}
}
@@ -312,13 +286,13 @@ namespace System.Collections.Concurrent
{
if (concurrencyLevel < 1)
{
- throw new ArgumentOutOfRangeException("concurrencyLevel", GetResource("ConcurrentDictionary_ConcurrencyLevelMustBePositive"));
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.concurrencyLevel, ExceptionResource.ConcurrentDictionary_ConcurrencyLevelMustBePositive);
}
if (capacity < 0)
{
- throw new ArgumentOutOfRangeException("capacity", GetResource("ConcurrentDictionary_CapacityMustNotBeNegative"));
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity, ExceptionResource.ConcurrentDictionary_CapacityMustNotBeNegative);
}
- if (comparer == null) throw new ArgumentNullException("comparer");
+ if (comparer == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.comparer);
// The capacity should be at least as large as the concurrency level. Otherwise, we would have locks that don't guard
// any buckets.
@@ -358,7 +332,7 @@ namespace System.Collections.Concurrent
/// contains too many elements.</exception>
public bool TryAdd(TKey key, TValue value)
{
- if (key == null) throw new ArgumentNullException("key");
+ if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
TValue dummy;
return TryAddInternal(key, value, false, true, out dummy);
}
@@ -375,7 +349,7 @@ namespace System.Collections.Concurrent
/// (Nothing in Visual Basic).</exception>
public bool ContainsKey(TKey key)
{
- if (key == null) throw new ArgumentNullException("key");
+ if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
TValue throwAwayValue;
return TryGetValue(key, out throwAwayValue);
@@ -395,7 +369,7 @@ namespace System.Collections.Concurrent
/// (Nothing in Visual Basic).</exception>
public bool TryRemove(TKey key, out TValue value)
{
- if (key == null) throw new ArgumentNullException("key");
+ if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
return TryRemoveInternal(key, out value, false, default(TValue));
}
@@ -486,7 +460,7 @@ namespace System.Collections.Concurrent
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "Reviewed for thread safety")]
public bool TryGetValue(TKey key, out TValue value)
{
- if (key == null) throw new ArgumentNullException("key");
+ if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
int bucketNo, lockNoUnused;
@@ -531,7 +505,7 @@ namespace System.Collections.Concurrent
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "Reviewed for thread safety")]
public bool TryUpdate(TKey key, TValue newValue, TValue comparisonValue)
{
- if (key == null) throw new ArgumentNullException("key");
+ if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
IEqualityComparer<TValue> valueComparer = EqualityComparer<TValue>.Default;
@@ -642,8 +616,8 @@ namespace System.Collections.Concurrent
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "ConcurrencyCop just doesn't know about these locks")]
void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int index)
{
- if (array == null) throw new ArgumentNullException("array");
- if (index < 0) throw new ArgumentOutOfRangeException("index", GetResource("ConcurrentDictionary_IndexIsNegative"));
+ if (array == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
+ if (index < 0) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ConcurrentDictionary_IndexIsNegative);
int locksAcquired = 0;
try
@@ -659,7 +633,7 @@ namespace System.Collections.Concurrent
if (array.Length - count < index || count < 0) //"count" itself or "count + index" can overflow
{
- throw new ArgumentException(GetResource("ConcurrentDictionary_ArrayNotLargeEnough"));
+ ThrowHelper.ThrowArgumentException(ExceptionResource.ConcurrentDictionary_ArrayNotLargeEnough);
}
CopyToPairs(array, index);
@@ -803,11 +777,6 @@ namespace System.Collections.Concurrent
bool resizeDesired = false;
bool lockTaken = false;
-#if FEATURE_RANDOMIZED_STRING_HASHING
-#if !FEATURE_CORECLR
- bool resizeDueToCollisions = false;
-#endif // !FEATURE_CORECLR
-#endif
try
{
@@ -821,12 +790,6 @@ namespace System.Collections.Concurrent
continue;
}
-#if FEATURE_RANDOMIZED_STRING_HASHING
-#if !FEATURE_CORECLR
- int collisionCount = 0;
-#endif // !FEATURE_CORECLR
-#endif
-
// Try to find this key in the bucket
Node prev = null;
for (Node node = tables.m_buckets[bucketNo]; node != null; node = node.m_next)
@@ -864,23 +827,7 @@ namespace System.Collections.Concurrent
return false;
}
prev = node;
-
-#if FEATURE_RANDOMIZED_STRING_HASHING
-#if !FEATURE_CORECLR
- collisionCount++;
-#endif // !FEATURE_CORECLR
-#endif
- }
-
-#if FEATURE_RANDOMIZED_STRING_HASHING
-#if !FEATURE_CORECLR
- if(collisionCount > HashHelpers.HashCollisionThreshold && HashHelpers.IsWellKnownEqualityComparer(comparer))
- {
- resizeDesired = true;
- resizeDueToCollisions = true;
}
-#endif // !FEATURE_CORECLR
-#endif
// The key was not found in the bucket. Insert the key-value pair.
Volatile.Write<Node>(ref tables.m_buckets[bucketNo], new Node(key, value, hashcode, tables.m_buckets[bucketNo]));
@@ -916,16 +863,7 @@ namespace System.Collections.Concurrent
if (resizeDesired)
{
#if FEATURE_RANDOMIZED_STRING_HASHING
-#if !FEATURE_CORECLR
- if (resizeDueToCollisions)
- {
- GrowTable(tables, (IEqualityComparer<TKey>)HashHelpers.GetRandomizedEqualityComparer(comparer), true, m_keyRehashCount);
- }
- else
-#endif // !FEATURE_CORECLR
- {
- GrowTable(tables, tables.m_comparer, false, m_keyRehashCount);
- }
+ GrowTable(tables, tables.m_comparer, false, m_keyRehashCount);
#else
GrowTable(tables, tables.m_comparer, false, m_keyRehashCount);
#endif
@@ -956,13 +894,13 @@ namespace System.Collections.Concurrent
TValue value;
if (!TryGetValue(key, out value))
{
- throw new KeyNotFoundException();
+ ThrowHelper.ThrowKeyNotFoundException();
}
return value;
}
set
{
- if (key == null) throw new ArgumentNullException("key");
+ if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
TValue dummy;
TryAddInternal(key, value, true, true, out dummy);
}
@@ -1026,8 +964,8 @@ namespace System.Collections.Concurrent
/// if the key was not in the dictionary.</returns>
public TValue GetOrAdd(TKey key, Func<TKey, TValue> valueFactory)
{
- if (key == null) throw new ArgumentNullException("key");
- if (valueFactory == null) throw new ArgumentNullException("valueFactory");
+ if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
+ if (valueFactory == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.valueFactory);
TValue resultingValue;
if (TryGetValue(key, out resultingValue))
@@ -1052,7 +990,7 @@ namespace System.Collections.Concurrent
/// key is already in the dictionary, or the new value if the key was not in the dictionary.</returns>
public TValue GetOrAdd(TKey key, TValue value)
{
- if (key == null) throw new ArgumentNullException("key");
+ if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
TValue resultingValue;
TryAddInternal(key, value, false, true, out resultingValue);
@@ -1080,9 +1018,9 @@ namespace System.Collections.Concurrent
/// absent) or the result of updateValueFactory (if the key was present).</returns>
public TValue AddOrUpdate(TKey key, Func<TKey, TValue> addValueFactory, Func<TKey, TValue, TValue> updateValueFactory)
{
- if (key == null) throw new ArgumentNullException("key");
- if (addValueFactory == null) throw new ArgumentNullException("addValueFactory");
- if (updateValueFactory == null) throw new ArgumentNullException("updateValueFactory");
+ if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
+ if (addValueFactory == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.addValueFactory);
+ if (updateValueFactory == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.updateValueFactory);
TValue newValue, resultingValue;
while (true)
@@ -1127,8 +1065,8 @@ namespace System.Collections.Concurrent
/// absent) or the result of updateValueFactory (if the key was present).</returns>
public TValue AddOrUpdate(TKey key, TValue addValue, Func<TKey, TValue, TValue> updateValueFactory)
{
- if (key == null) throw new ArgumentNullException("key");
- if (updateValueFactory == null) throw new ArgumentNullException("updateValueFactory");
+ if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
+ if (updateValueFactory == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.updateValueFactory);
TValue newValue, resultingValue;
while (true)
{
@@ -1207,7 +1145,7 @@ namespace System.Collections.Concurrent
{
if (!TryAdd(key, value))
{
- throw new ArgumentException(GetResource("ConcurrentDictionary_KeyAlreadyExisted"));
+ ThrowHelper.ThrowArgumentException(ExceptionResource.ConcurrentDictionary_KeyAlreadyExisted);
}
}
@@ -1340,8 +1278,7 @@ namespace System.Collections.Concurrent
/// name="keyValuePair"/> is a null reference (Nothing in Visual Basic).</exception>
bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> keyValuePair)
{
- if (keyValuePair.Key == null) throw new ArgumentNullException(GetResource("ConcurrentDictionary_ItemKeyIsNull"));
-
+ if (keyValuePair.Key == null) ThrowHelper.ThrowArgumentNullException(ExceptionResource.ConcurrentDictionary_ItemKeyIsNull);
TValue throwAwayValue;
return TryRemoveInternal(keyValuePair.Key, out throwAwayValue, true, keyValuePair.Value);
}
@@ -1387,17 +1324,17 @@ namespace System.Collections.Concurrent
/// </exception>
void IDictionary.Add(object key, object value)
{
- if (key == null) throw new ArgumentNullException("key");
- if (!(key is TKey)) throw new ArgumentException(GetResource("ConcurrentDictionary_TypeOfKeyIncorrect"));
+ if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
+ if (!(key is TKey)) ThrowHelper.ThrowArgumentException(ExceptionResource.ConcurrentDictionary_TypeOfKeyIncorrect);
- TValue typedValue;
+ TValue typedValue = default(TValue);
try
{
typedValue = (TValue)value;
}
catch (InvalidCastException)
{
- throw new ArgumentException(GetResource("ConcurrentDictionary_TypeOfValueIncorrect"));
+ ThrowHelper.ThrowArgumentException(ExceptionResource.ConcurrentDictionary_TypeOfValueIncorrect);
}
((IDictionary<TKey, TValue>)this).Add((TKey)key, typedValue);
@@ -1415,7 +1352,7 @@ namespace System.Collections.Concurrent
/// (Nothing in Visual Basic).</exception>
bool IDictionary.Contains(object key)
{
- if (key == null) throw new ArgumentNullException("key");
+ if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
return (key is TKey) && ((ConcurrentDictionary<TKey, TValue>)this).ContainsKey((TKey)key);
}
@@ -1475,7 +1412,7 @@ namespace System.Collections.Concurrent
/// (Nothing in Visual Basic).</exception>
void IDictionary.Remove(object key)
{
- if (key == null) throw new ArgumentNullException("key");
+ if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
TValue throwAwayValue;
if (key is TKey)
@@ -1517,7 +1454,7 @@ namespace System.Collections.Concurrent
{
get
{
- if (key == null) throw new ArgumentNullException("key");
+ if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
TValue value;
if (key is TKey && this.TryGetValue((TKey)key, out value))
@@ -1529,10 +1466,10 @@ namespace System.Collections.Concurrent
}
set
{
- if (key == null) throw new ArgumentNullException("key");
+ if (key == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
- if (!(key is TKey)) throw new ArgumentException(GetResource("ConcurrentDictionary_TypeOfKeyIncorrect"));
- if (!(value is TValue)) throw new ArgumentException(GetResource("ConcurrentDictionary_TypeOfValueIncorrect"));
+ if (!(key is TKey)) ThrowHelper.ThrowArgumentException(ExceptionResource.ConcurrentDictionary_TypeOfKeyIncorrect);
+ if (!(value is TValue)) ThrowHelper.ThrowArgumentException(ExceptionResource.ConcurrentDictionary_TypeOfValueIncorrect);
((ConcurrentDictionary<TKey, TValue>)this)[(TKey)key] = (TValue)value;
}
@@ -1563,8 +1500,8 @@ namespace System.Collections.Concurrent
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "ConcurrencyCop just doesn't know about these locks")]
void ICollection.CopyTo(Array array, int index)
{
- if (array == null) throw new ArgumentNullException("array");
- if (index < 0) throw new ArgumentOutOfRangeException("index", GetResource("ConcurrentDictionary_IndexIsNegative"));
+ if (array == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
+ if (index < 0) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ConcurrentDictionary_IndexIsNegative);
int locksAcquired = 0;
try
@@ -1581,7 +1518,7 @@ namespace System.Collections.Concurrent
if (array.Length - count < index || count < 0) //"count" itself or "count + index" can overflow
{
- throw new ArgumentException(GetResource("ConcurrentDictionary_ArrayNotLargeEnough"));
+ ThrowHelper.ThrowArgumentException(ExceptionResource.ConcurrentDictionary_ArrayNotLargeEnough);
}
// To be consistent with the behavior of ICollection.CopyTo() in Dictionary<TKey,TValue>,
@@ -1611,7 +1548,7 @@ namespace System.Collections.Concurrent
return;
}
- throw new ArgumentException(GetResource("ConcurrentDictionary_ArrayIncorrectType"), "array");
+ ThrowHelper.ThrowArgumentException(ExceptionResource.ConcurrentDictionary_ArrayIncorrectType, ExceptionArgument.array);
}
finally
{
@@ -1641,7 +1578,8 @@ namespace System.Collections.Concurrent
{
get
{
- throw new NotSupportedException(Environment.GetResourceString("ConcurrentCollection_SyncRoot_NotSupported"));
+ ThrowHelper.ThrowNotSupportedException(ExceptionResource.ConcurrentCollection_SyncRoot_NotSupported);
+ return default(object);
}
}
@@ -1850,13 +1788,6 @@ namespace System.Collections.Concurrent
/// </summary>
private void AcquireAllLocks(ref int locksAcquired)
{
-#if !FEATURE_CORECLR
- if (CDSCollectionETWBCLProvider.Log.IsEnabled())
- {
- CDSCollectionETWBCLProvider.Log.ConcurrentDictionary_AcquiringAllLocks(m_tables.m_buckets.Length);
- }
-#endif //!FEATURE_CORECLR
-
// First, acquire lock 0
AcquireLocks(0, 1, ref locksAcquired);
@@ -1973,19 +1904,7 @@ namespace System.Collections.Concurrent
[Conditional("DEBUG")]
private void Assert(bool condition)
{
- Contract.Assert(condition);
- }
-
- /// <summary>
- /// A helper function to obtain the string for a particular resource key.
- /// </summary>
- /// <param name="key"></param>
- /// <returns></returns>
- private string GetResource(string key)
- {
- Assert(key != null);
-
- return Environment.GetResourceString(key);
+ Debug.Assert(condition);
}
/// <summary>
@@ -2050,46 +1969,5 @@ namespace System.Collections.Concurrent
m_enumerator.Reset();
}
}
-
-#if !FEATURE_CORECLR
- /// <summary>
- /// Get the data array to be serialized
- /// </summary>
- [OnSerializing]
- private void OnSerializing(StreamingContext context)
- {
- Tables tables = m_tables;
-
- // save the data into the serialization array to be saved
- m_serializationArray = ToArray();
- m_serializationConcurrencyLevel = tables.m_locks.Length;
- m_serializationCapacity = tables.m_buckets.Length;
- m_comparer = (IEqualityComparer<TKey>)HashHelpers.GetEqualityComparerForSerialization(tables.m_comparer);
- }
-
- /// <summary>
- /// Construct the dictionary from a previously serialized one
- /// </summary>
- [OnDeserialized]
- private void OnDeserialized(StreamingContext context)
- {
- KeyValuePair<TKey, TValue>[] array = m_serializationArray;
-
- var buckets = new Node[m_serializationCapacity];
- var countPerLock = new int[m_serializationConcurrencyLevel];
-
- var locks = new object[m_serializationConcurrencyLevel];
- for (int i = 0; i < locks.Length; i++)
- {
- locks[i] = new object();
- }
-
- m_tables = new Tables(buckets, locks, countPerLock, m_comparer);
-
- InitializeFromCollection(array);
- m_serializationArray = null;
-
- }
-#endif
}
}
diff --git a/src/mscorlib/src/System/Collections/Concurrent/ConcurrentQueue.cs b/src/mscorlib/src/System/Collections/Concurrent/ConcurrentQueue.cs
index 9164eadad1..7aa5971690 100644
--- a/src/mscorlib/src/System/Collections/Concurrent/ConcurrentQueue.cs
+++ b/src/mscorlib/src/System/Collections/Concurrent/ConcurrentQueue.cs
@@ -38,7 +38,6 @@ namespace System.Collections.Concurrent
[ComVisible(false)]
[DebuggerDisplay("Count = {Count}")]
[DebuggerTypeProxy(typeof(SystemCollectionsConcurrent_ProducerConsumerCollectionDebugView<>))]
- [HostProtection(Synchronization = true, ExternalThreading = true)]
[Serializable]
public class ConcurrentQueue<T> : IProducerConsumerCollection<T>, IReadOnlyCollection<T>
{
@@ -77,7 +76,7 @@ namespace System.Collections.Concurrent
int index = 0;
foreach (T element in collection)
{
- Contract.Assert(index >= 0 && index < SEGMENT_SIZE);
+ Debug.Assert(index >= 0 && index < SEGMENT_SIZE);
localTail.UnsafeAdd(element);
index++;
@@ -103,7 +102,7 @@ namespace System.Collections.Concurrent
{
if (collection == null)
{
- throw new ArgumentNullException("collection");
+ throw new ArgumentNullException(nameof(collection));
}
InitializeFromCollection(collection);
@@ -125,7 +124,7 @@ namespace System.Collections.Concurrent
[OnDeserialized]
private void OnDeserialized(StreamingContext context)
{
- Contract.Assert(m_serializationArray != null);
+ Debug.Assert(m_serializationArray != null);
InitializeFromCollection(m_serializationArray);
m_serializationArray = null;
}
@@ -160,7 +159,7 @@ namespace System.Collections.Concurrent
// Validate arguments.
if (array == null)
{
- throw new ArgumentNullException("array");
+ throw new ArgumentNullException(nameof(array));
}
// We must be careful not to corrupt the array, so we will first accumulate an
@@ -441,7 +440,7 @@ namespace System.Collections.Concurrent
{
if (array == null)
{
- throw new ArgumentNullException("array");
+ throw new ArgumentNullException(nameof(array));
}
// We must be careful not to corrupt the array, so we will first accumulate an
@@ -689,7 +688,7 @@ namespace System.Collections.Concurrent
m_array = new T[SEGMENT_SIZE];
m_state = new VolatileBool[SEGMENT_SIZE]; //all initialized to false
m_high = -1;
- Contract.Assert(index >= 0);
+ Debug.Assert(index >= 0);
m_index = index;
m_source = source;
}
@@ -721,7 +720,7 @@ namespace System.Collections.Concurrent
/// <param name="value"></param>
internal void UnsafeAdd(T value)
{
- Contract.Assert(m_high < SEGMENT_SIZE - 1);
+ Debug.Assert(m_high < SEGMENT_SIZE - 1);
m_high++;
m_array[m_high] = value;
m_state[m_high].m_value = true;
@@ -737,7 +736,7 @@ namespace System.Collections.Concurrent
/// <returns>the reference to the new Segment</returns>
internal Segment UnsafeGrow()
{
- Contract.Assert(m_high >= SEGMENT_SIZE - 1);
+ Debug.Assert(m_high >= SEGMENT_SIZE - 1);
Segment newSegment = new Segment(m_index + 1, m_source); //m_index is Int64, we don't need to worry about overflow
m_next = newSegment;
return newSegment;
@@ -753,7 +752,7 @@ namespace System.Collections.Concurrent
//no CAS is needed, since there is no contention (other threads are blocked, busy waiting)
Segment newSegment = new Segment(m_index + 1, m_source); //m_index is Int64, we don't need to worry about overflow
m_next = newSegment;
- Contract.Assert(m_source.m_tail == this);
+ Debug.Assert(m_source.m_tail == this);
m_source.m_tail = m_next;
}
@@ -860,7 +859,7 @@ namespace System.Collections.Concurrent
{
spinLocal.SpinOnce();
}
- Contract.Assert(m_source.m_head == this);
+ Debug.Assert(m_source.m_head == this);
m_source.m_head = m_next;
}
return true;
diff --git a/src/mscorlib/src/System/Collections/Concurrent/ConcurrentStack.cs b/src/mscorlib/src/System/Collections/Concurrent/ConcurrentStack.cs
index 15d4176cff..c36d96c26c 100644
--- a/src/mscorlib/src/System/Collections/Concurrent/ConcurrentStack.cs
+++ b/src/mscorlib/src/System/Collections/Concurrent/ConcurrentStack.cs
@@ -45,10 +45,6 @@ namespace System.Collections.Concurrent
/// </remarks>
[DebuggerDisplay("Count = {Count}")]
[DebuggerTypeProxy(typeof(SystemCollectionsConcurrent_ProducerConsumerCollectionDebugView<>))]
- [HostProtection(Synchronization = true, ExternalThreading = true)]
-#if !FEATURE_CORECLR
- [Serializable]
-#endif //!FEATURE_CORECLR
public class ConcurrentStack<T> : IProducerConsumerCollection<T>, IReadOnlyCollection<T>
{
/// <summary>
@@ -70,15 +66,8 @@ namespace System.Collections.Concurrent
}
}
-#if !FEATURE_CORECLR
- [NonSerialized]
-#endif //!FEATURE_CORECLR
private volatile Node m_head; // The stack is a singly linked list, and only remembers the head.
-#if !FEATURE_CORECLR
- private T[] m_serializationArray; // Used for custom serialization.
-#endif //!FEATURE_CORECLR
-
private const int BACKOFF_MAX_YIELDS = 8; // Arbitrary number to cap backoff.
/// <summary>
@@ -101,7 +90,7 @@ namespace System.Collections.Concurrent
{
if (collection == null)
{
- throw new ArgumentNullException("collection");
+ throw new ArgumentNullException(nameof(collection));
}
InitializeFromCollection(collection);
}
@@ -124,50 +113,6 @@ namespace System.Collections.Concurrent
m_head = lastNode;
}
-#if !FEATURE_CORECLR
- /// <summary>
- /// Get the data array to be serialized
- /// </summary>
- [OnSerializing]
- private void OnSerializing(StreamingContext context)
- {
- // save the data into the serialization array to be saved
- m_serializationArray = ToArray();
- }
-
- /// <summary>
- /// Construct the stack from a previously seiralized one
- /// </summary>
- [OnDeserialized]
- private void OnDeserialized(StreamingContext context)
- {
- Contract.Assert(m_serializationArray != null);
- // Add the elements to our stack. We need to add them from head-to-tail, to
- // preserve the original ordering of the stack before serialization.
- Node prevNode = null;
- Node head = null;
- for (int i = 0; i < m_serializationArray.Length; i++)
- {
- Node currNode = new Node(m_serializationArray[i]);
-
- if (prevNode == null)
- {
- head = currNode;
- }
- else
- {
- prevNode.m_next = currNode;
- }
-
- prevNode = currNode;
- }
-
- m_head = head;
- m_serializationArray = null;
- }
-#endif //!FEATURE_CORECLR
-
-
/// <summary>
/// Gets a value that indicates whether the <see cref="ConcurrentStack{T}"/> is empty.
/// </summary>
@@ -221,7 +166,6 @@ namespace System.Collections.Concurrent
}
}
-
/// <summary>
/// Gets a value indicating whether access to the <see cref="T:System.Collections.ICollection"/> is
/// synchronized with the SyncRoot.
@@ -293,7 +237,7 @@ namespace System.Collections.Concurrent
// Validate arguments.
if (array == null)
{
- throw new ArgumentNullException("array");
+ throw new ArgumentNullException(nameof(array));
}
// We must be careful not to corrupt the array, so we will first accumulate an
@@ -327,7 +271,7 @@ namespace System.Collections.Concurrent
{
if (array == null)
{
- throw new ArgumentNullException("array");
+ throw new ArgumentNullException(nameof(array));
}
// We must be careful not to corrupt the array, so we will first accumulate an
@@ -379,7 +323,7 @@ namespace System.Collections.Concurrent
{
if (items == null)
{
- throw new ArgumentNullException("items");
+ throw new ArgumentNullException(nameof(items));
}
PushRange(items, 0, items.Length);
}
@@ -455,13 +399,6 @@ namespace System.Collections.Concurrent
}
while (Interlocked.CompareExchange(
ref m_head, head, tail.m_next) != tail.m_next);
-
-#if !FEATURE_CORECLR
- if (CDSCollectionETWBCLProvider.Log.IsEnabled())
- {
- CDSCollectionETWBCLProvider.Log.ConcurrentStack_FastPushFailed(spin.Count);
- }
-#endif // !FEATURE_CORECLR
}
/// <summary>
@@ -471,16 +408,16 @@ namespace System.Collections.Concurrent
{
if (items == null)
{
- throw new ArgumentNullException("items");
+ throw new ArgumentNullException(nameof(items));
}
if (count < 0)
{
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ConcurrentStack_PushPopRange_CountOutOfRange"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ConcurrentStack_PushPopRange_CountOutOfRange"));
}
int length = items.Length;
if (startIndex >= length || startIndex < 0)
{
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ConcurrentStack_PushPopRange_StartOutOfRange"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ConcurrentStack_PushPopRange_StartOutOfRange"));
}
if (length - count < startIndex) //instead of (startIndex + count > items.Length) to prevent overflow
{
@@ -584,7 +521,7 @@ namespace System.Collections.Concurrent
{
if (items == null)
{
- throw new ArgumentNullException("items");
+ throw new ArgumentNullException(nameof(items));
}
return TryPopRange(items, 0, items.Length);
@@ -683,12 +620,6 @@ namespace System.Collections.Concurrent
// Is the stack empty?
if (head == null)
{
-#if !FEATURE_CORECLR
- if (count == 1 && CDSCollectionETWBCLProvider.Log.IsEnabled())
- {
- CDSCollectionETWBCLProvider.Log.ConcurrentStack_FastPopFailed(spin.Count);
- }
-#endif //!FEATURE_CORECLR
poppedHead = null;
return 0;
}
@@ -702,12 +633,6 @@ namespace System.Collections.Concurrent
// Try to swap the new head. If we succeed, break out of the loop.
if (Interlocked.CompareExchange(ref m_head, next.m_next, head) == head)
{
-#if !FEATURE_CORECLR
- if (count == 1 && CDSCollectionETWBCLProvider.Log.IsEnabled())
- {
- CDSCollectionETWBCLProvider.Log.ConcurrentStack_FastPopFailed(spin.Count);
- }
-#endif //!FEATURE_CORECLR
// Return the popped Node.
poppedHead = head;
return nodesCount;
diff --git a/src/mscorlib/src/System/Collections/Concurrent/IProducerConsumerCollection.cs b/src/mscorlib/src/System/Collections/Concurrent/IProducerConsumerCollection.cs
index a74f69069a..56be7759c9 100644
--- a/src/mscorlib/src/System/Collections/Concurrent/IProducerConsumerCollection.cs
+++ b/src/mscorlib/src/System/Collections/Concurrent/IProducerConsumerCollection.cs
@@ -97,7 +97,7 @@ namespace System.Collections.Concurrent
{
if (collection == null)
{
- throw new ArgumentNullException("collection");
+ throw new ArgumentNullException(nameof(collection));
}
m_collection = collection;
diff --git a/src/mscorlib/src/System/Collections/Concurrent/OrderablePartitioner.cs b/src/mscorlib/src/System/Collections/Concurrent/OrderablePartitioner.cs
index 02263b7f97..33e3c88e9a 100644
--- a/src/mscorlib/src/System/Collections/Concurrent/OrderablePartitioner.cs
+++ b/src/mscorlib/src/System/Collections/Concurrent/OrderablePartitioner.cs
@@ -61,7 +61,6 @@ namespace System.Collections.Concurrent
/// </ol>
/// </para>
/// </remarks>
- [HostProtection(Synchronization = true, ExternalThreading = true)]
public abstract class OrderablePartitioner<TSource> : Partitioner<TSource>
{
/// <summary>
diff --git a/src/mscorlib/src/System/Collections/Concurrent/Partitioner.cs b/src/mscorlib/src/System/Collections/Concurrent/Partitioner.cs
index 3d54c1471b..0192b1942c 100644
--- a/src/mscorlib/src/System/Collections/Concurrent/Partitioner.cs
+++ b/src/mscorlib/src/System/Collections/Concurrent/Partitioner.cs
@@ -44,7 +44,6 @@ namespace System.Collections.Concurrent
/// </ol>
/// </para>
/// </remarks>
- [HostProtection(Synchronization = true, ExternalThreading = true)]
public abstract class Partitioner<TSource>
{
/// <summary>
diff --git a/src/mscorlib/src/System/Collections/Concurrent/PartitionerStatic.cs b/src/mscorlib/src/System/Collections/Concurrent/PartitionerStatic.cs
index 2169c6dee7..9b36c053ad 100644
--- a/src/mscorlib/src/System/Collections/Concurrent/PartitionerStatic.cs
+++ b/src/mscorlib/src/System/Collections/Concurrent/PartitionerStatic.cs
@@ -14,6 +14,7 @@
using System.Collections.Generic;
using System.Security.Permissions;
using System.Threading;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
@@ -26,9 +27,6 @@ namespace System.Collections.Concurrent
/// non-blocking. These behaviors can be overridden via this enumeration.
/// </summary>
[Flags]
-#if !FEATURE_CORECLR
- [Serializable]
-#endif
public enum EnumerablePartitionerOptions
{
/// <summary>
@@ -71,7 +69,6 @@ namespace System.Collections.Concurrent
/// thread.
/// </para>
/// </remarks>
- [HostProtection(Synchronization = true, ExternalThreading = true)]
public static class Partitioner
{
/// <summary>
@@ -91,7 +88,7 @@ namespace System.Collections.Concurrent
{
if (list == null)
{
- throw new ArgumentNullException("list");
+ throw new ArgumentNullException(nameof(list));
}
if (loadBalance)
{
@@ -122,7 +119,7 @@ namespace System.Collections.Concurrent
if (array == null)
{
- throw new ArgumentNullException("array");
+ throw new ArgumentNullException(nameof(array));
}
if (loadBalance)
{
@@ -172,11 +169,11 @@ namespace System.Collections.Concurrent
{
if (source == null)
{
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
}
if ((partitionerOptions & (~EnumerablePartitionerOptions.NoBuffering)) != 0)
- throw new ArgumentOutOfRangeException("partitionerOptions");
+ throw new ArgumentOutOfRangeException(nameof(partitionerOptions));
return (new DynamicPartitionerForIEnumerable<TSource>(source, partitionerOptions));
}
@@ -194,7 +191,7 @@ namespace System.Collections.Concurrent
// load balancing on a busy system if you make it higher than 1.
int coreOversubscriptionRate = 3;
- if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException("toExclusive");
+ if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException(nameof(toExclusive));
long rangeSize = (toExclusive - fromInclusive) /
(PlatformHelper.ProcessorCount * coreOversubscriptionRate);
if (rangeSize == 0) rangeSize = 1;
@@ -212,8 +209,8 @@ namespace System.Collections.Concurrent
/// less than or equal to 0.</exception>
public static OrderablePartitioner<Tuple<long, long>> Create(long fromInclusive, long toExclusive, long rangeSize)
{
- if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException("toExclusive");
- if (rangeSize <= 0) throw new ArgumentOutOfRangeException("rangeSize");
+ if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException(nameof(toExclusive));
+ if (rangeSize <= 0) throw new ArgumentOutOfRangeException(nameof(rangeSize));
return Partitioner.Create(CreateRanges(fromInclusive, toExclusive, rangeSize), EnumerablePartitionerOptions.NoBuffering); // chunk one range at a time
}
@@ -251,7 +248,7 @@ namespace System.Collections.Concurrent
// load balancing on a busy system if you make it higher than 1.
int coreOversubscriptionRate = 3;
- if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException("toExclusive");
+ if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException(nameof(toExclusive));
int rangeSize = (toExclusive - fromInclusive) /
(PlatformHelper.ProcessorCount * coreOversubscriptionRate);
if (rangeSize == 0) rangeSize = 1;
@@ -269,8 +266,8 @@ namespace System.Collections.Concurrent
/// less than or equal to 0.</exception>
public static OrderablePartitioner<Tuple<int, int>> Create(int fromInclusive, int toExclusive, int rangeSize)
{
- if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException("toExclusive");
- if (rangeSize <= 0) throw new ArgumentOutOfRangeException("rangeSize");
+ if (toExclusive <= fromInclusive) throw new ArgumentOutOfRangeException(nameof(toExclusive));
+ if (rangeSize <= 0) throw new ArgumentOutOfRangeException(nameof(rangeSize));
return Partitioner.Create(CreateRanges(fromInclusive, toExclusive, rangeSize), EnumerablePartitionerOptions.NoBuffering); // chunk one range at a time
}
@@ -431,7 +428,7 @@ namespace System.Collections.Concurrent
//perform deferred allocating of the local variables.
if (m_localOffset == null)
{
- Contract.Assert(m_currentChunkSize == null);
+ Debug.Assert(m_currentChunkSize == null);
m_localOffset = new SharedInt(-1);
m_currentChunkSize = new SharedInt(0);
m_doublingCountdown = CHUNK_DOUBLING_RATE;
@@ -449,7 +446,7 @@ namespace System.Collections.Concurrent
{
// The second part of the || condition is necessary to handle the case when MoveNext() is called
// after a previous MoveNext call returned false.
- Contract.Assert(m_localOffset.Value == m_currentChunkSize.Value - 1 || m_currentChunkSize.Value == 0);
+ Debug.Assert(m_localOffset.Value == m_currentChunkSize.Value - 1 || m_currentChunkSize.Value == 0);
//set the requested chunk size to a proper value
int requestedChunkSize;
@@ -470,11 +467,11 @@ namespace System.Collections.Concurrent
// Decrement your doubling countdown
m_doublingCountdown--;
- Contract.Assert(requestedChunkSize > 0 && requestedChunkSize <= m_maxChunkSize);
+ Debug.Assert(requestedChunkSize > 0 && requestedChunkSize <= m_maxChunkSize);
//GrabNextChunk will update the value of m_currentChunkSize
if (GrabNextChunk(requestedChunkSize))
{
- Contract.Assert(m_currentChunkSize.Value <= requestedChunkSize && m_currentChunkSize.Value > 0);
+ Debug.Assert(m_currentChunkSize.Value <= requestedChunkSize && m_currentChunkSize.Value > 0);
m_localOffset.Value = 0;
return true;
}
@@ -517,7 +514,7 @@ namespace System.Collections.Concurrent
{
if (partitionCount <= 0)
{
- throw new ArgumentOutOfRangeException("partitionCount");
+ throw new ArgumentOutOfRangeException(nameof(partitionCount));
}
IEnumerator<KeyValuePair<long, TSource>>[] partitions
= new IEnumerator<KeyValuePair<long, TSource>>[partitionCount];
@@ -715,10 +712,10 @@ namespace System.Collections.Concurrent
/// </returns>
internal bool GrabChunk_Single(KeyValuePair<long,TSource>[] destArray, int requestedChunkSize, ref int actualNumElementsGrabbed)
{
- Contract.Assert(m_useSingleChunking, "Expected m_useSingleChecking to be true");
- Contract.Assert(requestedChunkSize == 1, "Got requested chunk size of " + requestedChunkSize + " when single-chunking was on");
- Contract.Assert(actualNumElementsGrabbed == 0, "Expected actualNumElementsGrabbed == 0, instead it is " + actualNumElementsGrabbed);
- Contract.Assert(destArray.Length == 1, "Expected destArray to be of length 1, instead its length is " + destArray.Length);
+ Debug.Assert(m_useSingleChunking, "Expected m_useSingleChecking to be true");
+ Debug.Assert(requestedChunkSize == 1, "Got requested chunk size of " + requestedChunkSize + " when single-chunking was on");
+ Debug.Assert(actualNumElementsGrabbed == 0, "Expected actualNumElementsGrabbed == 0, instead it is " + actualNumElementsGrabbed);
+ Debug.Assert(destArray.Length == 1, "Expected destArray to be of length 1, instead its length is " + destArray.Length);
lock (m_sharedLock)
{
@@ -764,8 +761,8 @@ namespace System.Collections.Concurrent
/// </returns>
internal bool GrabChunk_Buffered(KeyValuePair<long,TSource>[] destArray, int requestedChunkSize, ref int actualNumElementsGrabbed)
{
- Contract.Assert(requestedChunkSize > 0);
- Contract.Assert(!m_useSingleChunking, "Did not expect to be in single-chunking mode");
+ Debug.Assert(requestedChunkSize > 0);
+ Debug.Assert(!m_useSingleChunking, "Did not expect to be in single-chunking mode");
TryCopyFromFillBuffer(destArray, requestedChunkSize, ref actualNumElementsGrabbed);
@@ -803,7 +800,7 @@ namespace System.Collections.Concurrent
while( m_activeCopiers > 0) sw.SpinOnce();
}
- Contract.Assert(m_sharedIndex != null); //already been allocated in MoveNext() before calling GrabNextChunk
+ Debug.Assert(m_sharedIndex != null); //already been allocated in MoveNext() before calling GrabNextChunk
// Now's the time to actually enumerate the source
@@ -940,7 +937,7 @@ namespace System.Collections.Concurrent
/// </returns>
override protected bool GrabNextChunk(int requestedChunkSize)
{
- Contract.Assert(requestedChunkSize > 0);
+ Debug.Assert(requestedChunkSize > 0);
if (HasNoElementsLeft)
{
@@ -973,8 +970,8 @@ namespace System.Collections.Concurrent
{
//we only set it from false to true once
//we should never set it back in any circumstances
- Contract.Assert(value);
- Contract.Assert(!m_hasNoElementsLeft.Value);
+ Debug.Assert(value);
+ Debug.Assert(!m_hasNoElementsLeft.Value);
m_hasNoElementsLeft.Value = true;
}
}
@@ -988,8 +985,8 @@ namespace System.Collections.Concurrent
{
throw new InvalidOperationException(Environment.GetResourceString("PartitionerStatic_CurrentCalledBeforeMoveNext"));
}
- Contract.Assert(m_localList != null);
- Contract.Assert(m_localOffset.Value >= 0 && m_localOffset.Value < m_currentChunkSize.Value);
+ Debug.Assert(m_localList != null);
+ Debug.Assert(m_localOffset.Value >= 0 && m_localOffset.Value < m_currentChunkSize.Value);
return (m_localList[m_localOffset.Value]);
}
}
@@ -1053,7 +1050,7 @@ namespace System.Collections.Concurrent
{
if (partitionCount <= 0)
{
- throw new ArgumentOutOfRangeException("partitionCount");
+ throw new ArgumentOutOfRangeException(nameof(partitionCount));
}
IEnumerator<KeyValuePair<long, TSource>>[] partitions
= new IEnumerator<KeyValuePair<long, TSource>>[partitionCount];
@@ -1127,11 +1124,11 @@ namespace System.Collections.Concurrent
/// </returns>
override protected bool GrabNextChunk(int requestedChunkSize)
{
- Contract.Assert(requestedChunkSize > 0);
+ Debug.Assert(requestedChunkSize > 0);
while (!HasNoElementsLeft)
{
- Contract.Assert(m_sharedIndex != null);
+ Debug.Assert(m_sharedIndex != null);
// use the new Volatile.Read method because it is cheaper than Interlocked.Read on AMD64 architecture
long oldSharedIndex = Volatile.Read(ref m_sharedIndex.Value);
@@ -1173,13 +1170,13 @@ namespace System.Collections.Concurrent
{
get
{
- Contract.Assert(m_sharedIndex != null);
+ Debug.Assert(m_sharedIndex != null);
// use the new Volatile.Read method because it is cheaper than Interlocked.Read on AMD64 architecture
return Volatile.Read(ref m_sharedIndex.Value) >= SourceCount - 1;
}
set
{
- Contract.Assert(false);
+ Debug.Assert(false);
}
}
@@ -1268,7 +1265,7 @@ namespace System.Collections.Concurrent
throw new InvalidOperationException(Environment.GetResourceString("PartitionerStatic_CurrentCalledBeforeMoveNext"));
}
- Contract.Assert(m_localOffset.Value >= 0 && m_localOffset.Value < m_currentChunkSize.Value);
+ Debug.Assert(m_localOffset.Value >= 0 && m_localOffset.Value < m_currentChunkSize.Value);
return new KeyValuePair<long, TSource>(m_startIndex + m_localOffset.Value,
m_sharedReader[m_startIndex + m_localOffset.Value]);
}
@@ -1352,7 +1349,7 @@ namespace System.Collections.Concurrent
throw new InvalidOperationException(Environment.GetResourceString("PartitionerStatic_CurrentCalledBeforeMoveNext"));
}
- Contract.Assert(m_localOffset.Value >= 0 && m_localOffset.Value < m_currentChunkSize.Value);
+ Debug.Assert(m_localOffset.Value >= 0 && m_localOffset.Value < m_currentChunkSize.Value);
return new KeyValuePair<long, TSource>(m_startIndex + m_localOffset.Value,
m_sharedReader[m_startIndex + m_localOffset.Value]);
}
@@ -1417,7 +1414,7 @@ namespace System.Collections.Concurrent
{
if (partitionCount <= 0)
{
- throw new ArgumentOutOfRangeException("partitionCount");
+ throw new ArgumentOutOfRangeException(nameof(partitionCount));
}
int quotient, remainder;
@@ -1539,7 +1536,7 @@ namespace System.Collections.Concurrent
internal StaticIndexRangePartitionerForIList(IList<TSource> list)
: base()
{
- Contract.Assert(list != null);
+ Debug.Assert(list != null);
m_list = list;
}
override protected int SourceCount
@@ -1565,7 +1562,7 @@ namespace System.Collections.Concurrent
internal StaticIndexRangePartitionForIList(IList<TSource> list, int startIndex, int endIndex)
: base(startIndex, endIndex)
{
- Contract.Assert(startIndex >= 0 && endIndex <= list.Count - 1);
+ Debug.Assert(startIndex >= 0 && endIndex <= list.Count - 1);
m_list = list;
}
@@ -1579,7 +1576,7 @@ namespace System.Collections.Concurrent
throw new InvalidOperationException(Environment.GetResourceString("PartitionerStatic_CurrentCalledBeforeMoveNext"));
}
- Contract.Assert(m_offset >= m_startIndex && m_offset <= m_endIndex);
+ Debug.Assert(m_offset >= m_startIndex && m_offset <= m_endIndex);
return (new KeyValuePair<long, TSource>(m_offset, m_list[m_offset]));
}
}
@@ -1597,7 +1594,7 @@ namespace System.Collections.Concurrent
internal StaticIndexRangePartitionerForArray(TSource[] array)
: base()
{
- Contract.Assert(array != null);
+ Debug.Assert(array != null);
m_array = array;
}
override protected int SourceCount
@@ -1622,7 +1619,7 @@ namespace System.Collections.Concurrent
internal StaticIndexRangePartitionForArray(TSource[] array, int startIndex, int endIndex)
: base(startIndex, endIndex)
{
- Contract.Assert(startIndex >= 0 && endIndex <= array.Length - 1);
+ Debug.Assert(startIndex >= 0 && endIndex <= array.Length - 1);
m_array = array;
}
@@ -1636,7 +1633,7 @@ namespace System.Collections.Concurrent
throw new InvalidOperationException(Environment.GetResourceString("PartitionerStatic_CurrentCalledBeforeMoveNext"));
}
- Contract.Assert(m_offset >= m_startIndex && m_offset <= m_endIndex);
+ Debug.Assert(m_offset >= m_startIndex && m_offset <= m_endIndex);
return (new KeyValuePair<long, TSource>(m_offset, m_array[m_offset]));
}
}
@@ -1704,30 +1701,15 @@ namespace System.Collections.Concurrent
if (typeof(TSource).IsValueType)
{
-#if !FEATURE_CORECLR // Marshal.SizeOf is not supported in CoreCLR
-
- if (typeof(TSource).StructLayoutAttribute.Value == LayoutKind.Explicit)
- {
- chunkSize = Math.Max(1, DEFAULT_BYTES_PER_CHUNK / Marshal.SizeOf(typeof(TSource)));
- }
- else
- {
- // We choose '128' because this ensures, no matter the actual size of the value type,
- // the total bytes used will be a multiple of 128. This ensures it's cache aligned.
- chunkSize = 128;
- }
-#else
chunkSize = 128;
-#endif
}
else
{
- Contract.Assert((DEFAULT_BYTES_PER_CHUNK % IntPtr.Size) == 0, "bytes per chunk should be a multiple of pointer size");
+ Debug.Assert((DEFAULT_BYTES_PER_CHUNK % IntPtr.Size) == 0, "bytes per chunk should be a multiple of pointer size");
chunkSize = (DEFAULT_BYTES_PER_CHUNK / IntPtr.Size);
}
return chunkSize;
}
#endregion
-
}
}
diff --git a/src/mscorlib/src/System/Collections/DictionaryEntry.cs b/src/mscorlib/src/System/Collections/DictionaryEntry.cs
index fc1d57fe55..3ee392bb0d 100644
--- a/src/mscorlib/src/System/Collections/DictionaryEntry.cs
+++ b/src/mscorlib/src/System/Collections/DictionaryEntry.cs
@@ -51,5 +51,12 @@ namespace System.Collections {
_value = value;
}
}
+
+ // BLOCKED (do not add now): [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 6e28493ef8..a610fce016 100644
--- a/src/mscorlib/src/System/Collections/EmptyReadOnlyDictionaryInternal.cs
+++ b/src/mscorlib/src/System/Collections/EmptyReadOnlyDictionaryInternal.cs
@@ -36,16 +36,16 @@ namespace System.Collections {
public void CopyTo(Array array, int index) {
if (array==null)
- throw new ArgumentNullException("array");
+ throw new ArgumentNullException(nameof(array));
if (array.Rank != 1)
throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
if (index < 0)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if ( array.Length - index < this.Count )
- throw new ArgumentException( Environment.GetResourceString("ArgumentOutOfRange_Index"), "index");
+ throw new ArgumentException( Environment.GetResourceString("ArgumentOutOfRange_Index"), nameof(index));
Contract.EndContractBlock();
// the actual copy is a NOP
@@ -74,21 +74,21 @@ namespace System.Collections {
public Object this[Object key] {
get {
if (key == null) {
- throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key"));
+ throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
}
Contract.EndContractBlock();
return null;
}
set {
if (key == null) {
- throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key"));
+ throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
}
if (!key.GetType().IsSerializable)
- throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), "key");
+ throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), nameof(key));
if( (value != null) && (!value.GetType().IsSerializable ) )
- throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), "value");
+ throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), nameof(value));
Contract.EndContractBlock();
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
@@ -113,14 +113,14 @@ namespace System.Collections {
public void Add(Object key, Object value) {
if (key == null) {
- throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key"));
+ throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
}
if (!key.GetType().IsSerializable)
- throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), "key" );
+ throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), nameof(key) );
if( (value != null) && (!value.GetType().IsSerializable) )
- throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), "value");
+ throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), nameof(value));
Contract.EndContractBlock();
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
diff --git a/src/mscorlib/src/System/Collections/Generic/ArraySortHelper.cs b/src/mscorlib/src/System/Collections/Generic/ArraySortHelper.cs
index b2fed9d78f..298ac3e177 100644
--- a/src/mscorlib/src/System/Collections/Generic/ArraySortHelper.cs
+++ b/src/mscorlib/src/System/Collections/Generic/ArraySortHelper.cs
@@ -17,6 +17,7 @@ namespace System.Collections.Generic
using System;
using System.Globalization;
using System.Runtime.CompilerServices;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.Versioning;
@@ -49,16 +50,7 @@ namespace System.Collections.Generic
}
internal static void ThrowOrIgnoreBadComparer(Object comparer) {
- // This is hit when an invarant of QuickSort is violated due to a bad IComparer implementation (for
- // example, imagine an IComparer that returns 0 when items are equal but -1 all other times).
- //
- // We could have thrown this exception on v4, but due to changes in v4.5 around how we partition arrays
- // there are different sets of input where we would throw this exception. In order to reduce overall risk from
- // an app compat persective, we're changing to never throw on v4. Instead, we'll return with a partially
- // sorted array.
- if(BinaryCompatibility.TargetsAtLeast_Desktop_V4_5) {
- throw new ArgumentException(Environment.GetResourceString("Arg_BogusIComparer", comparer));
- }
+ throw new ArgumentException(Environment.GetResourceString("Arg_BogusIComparer", comparer));
}
}
@@ -81,7 +73,6 @@ namespace System.Collections.Generic
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
private static IArraySortHelper<T> CreateArraySortHelper()
{
if (typeof(IComparable<T>).IsAssignableFrom(typeof(T)))
@@ -99,8 +90,8 @@ namespace System.Collections.Generic
public void Sort(T[] keys, int index, int length, IComparer<T> comparer)
{
- Contract.Assert(keys != null, "Check the arguments in the caller!");
- Contract.Assert( index >= 0 && length >= 0 && (keys.Length - index >= length), "Check the arguments in the caller!");
+ 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!");
// Add a try block here to detect IComparers (or their
// underlying IComparables, etc) that are bogus.
@@ -111,22 +102,7 @@ namespace System.Collections.Generic
comparer = Comparer<T>.Default;
}
-#if FEATURE_CORECLR
- // Since QuickSort and IntrospectiveSort produce different sorting sequence for equal keys the upgrade
- // to IntrospectiveSort was quirked. However since the phone builds always shipped with the new sort aka
- // IntrospectiveSort and we would want to continue using this sort moving forward CoreCLR always uses the new sort.
-
- IntrospectiveSort(keys, index, length, comparer);
-#else
- if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5)
- {
- IntrospectiveSort(keys, index, length, comparer);
- }
- else
- {
- DepthLimitedQuickSort(keys, index, length + index - 1, comparer, IntrospectiveSortUtilities.QuickSortDepthThreshold);
- }
-#endif
+ IntrospectiveSort(keys, index, length, comparer.Compare);
}
catch (IndexOutOfRangeException)
{
@@ -157,6 +133,27 @@ namespace System.Collections.Generic
#endregion
+ internal static void Sort(T[] keys, int index, int length, Comparison<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(comparer != null, "Check the arguments in the caller!");
+
+ // Add a try block here to detect bogus comparisons
+ try
+ {
+ IntrospectiveSort(keys, index, length, comparer);
+ }
+ catch (IndexOutOfRangeException)
+ {
+ IntrospectiveSortUtilities.ThrowOrIgnoreBadComparer(comparer);
+ }
+ catch (Exception e)
+ {
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_IComparerFailed"), e);
+ }
+ }
+
internal static int InternalBinarySearch(T[] array, int index, int length, T value, IComparer<T> comparer)
{
Contract.Requires(array != null, "Check the arguments in the caller!");
@@ -183,11 +180,11 @@ namespace System.Collections.Generic
return ~lo;
}
- private static void SwapIfGreater(T[] keys, IComparer<T> comparer, int a, int b)
+ private static void SwapIfGreater(T[] keys, Comparison<T> comparer, int a, int b)
{
if (a != b)
{
- if (comparer.Compare(keys[a], keys[b]) > 0)
+ if (comparer(keys[a], keys[b]) > 0)
{
T key = keys[a];
keys[a] = keys[b];
@@ -198,7 +195,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];
@@ -206,63 +203,7 @@ namespace System.Collections.Generic
}
}
- internal static void DepthLimitedQuickSort(T[] keys, int left, int right, IComparer<T> comparer, int depthLimit)
- {
- do
- {
- if (depthLimit == 0)
- {
- Heapsort(keys, left, right, comparer);
- return;
- }
-
- int i = left;
- int j = right;
-
- // pre-sort the low, middle (pivot), and high values in place.
- // this improves performance in the face of already sorted data, or
- // data that is made up of multiple sorted runs appended together.
- int middle = i + ((j - i) >> 1);
- SwapIfGreater(keys, comparer, i, middle); // swap the low with the mid point
- SwapIfGreater(keys, comparer, i, j); // swap the low with the high
- SwapIfGreater(keys, comparer, middle, j); // swap the middle with the high
-
- T x = keys[middle];
- do
- {
- while (comparer.Compare(keys[i], x) < 0) i++;
- while (comparer.Compare(x, keys[j]) < 0) j--;
- Contract.Assert(i >= left && j <= right, "(i>=left && j<=right) Sort failed - Is your IComparer bogus?");
- if (i > j) break;
- if (i < j)
- {
- T key = keys[i];
- keys[i] = keys[j];
- keys[j] = key;
- }
- i++;
- j--;
- } while (i <= j);
-
- // The next iteration of the while loop is to "recursively" sort the larger half of the array and the
- // following calls recursively sort the smaller half. So we subtract one from depthLimit here so
- // both sorts see the new value.
- depthLimit--;
-
- if (j - left <= right - i)
- {
- if (left < j) DepthLimitedQuickSort(keys, left, j, comparer, depthLimit);
- left = i;
- }
- else
- {
- if (i < right) DepthLimitedQuickSort(keys, i, right, comparer, depthLimit);
- right = j;
- }
- } while (left < right);
- }
-
- internal static void IntrospectiveSort(T[] keys, int left, int length, IComparer<T> comparer)
+ internal static void IntrospectiveSort(T[] keys, int left, int length, Comparison<T> comparer)
{
Contract.Requires(keys != null);
Contract.Requires(comparer != null);
@@ -277,7 +218,7 @@ namespace System.Collections.Generic
IntroSort(keys, left, length + left - 1, 2 * IntrospectiveSortUtilities.FloorLog2(keys.Length), comparer);
}
- private static void IntroSort(T[] keys, int lo, int hi, int depthLimit, IComparer<T> comparer)
+ private static void IntroSort(T[] keys, int lo, int hi, int depthLimit, Comparison<T> comparer)
{
Contract.Requires(keys != null);
Contract.Requires(comparer != null);
@@ -324,7 +265,7 @@ namespace System.Collections.Generic
}
}
- private static int PickPivotAndPartition(T[] keys, int lo, int hi, IComparer<T> comparer)
+ private static int PickPivotAndPartition(T[] keys, int lo, int hi, Comparison<T> comparer)
{
Contract.Requires(keys != null);
Contract.Requires(comparer != null);
@@ -347,8 +288,8 @@ namespace System.Collections.Generic
while (left < right)
{
- while (comparer.Compare(keys[++left], pivot) < 0) ;
- while (comparer.Compare(pivot, keys[--right]) < 0) ;
+ while (comparer(keys[++left], pivot) < 0) ;
+ while (comparer(pivot, keys[--right]) < 0) ;
if (left >= right)
break;
@@ -361,7 +302,7 @@ namespace System.Collections.Generic
return left;
}
- private static void Heapsort(T[] keys, int lo, int hi, IComparer<T> comparer)
+ private static void Heapsort(T[] keys, int lo, int hi, Comparison<T> comparer)
{
Contract.Requires(keys != null);
Contract.Requires(comparer != null);
@@ -381,7 +322,7 @@ namespace System.Collections.Generic
}
}
- private static void DownHeap(T[] keys, int i, int n, int lo, IComparer<T> comparer)
+ private static void DownHeap(T[] keys, int i, int n, int lo, Comparison<T> comparer)
{
Contract.Requires(keys != null);
Contract.Requires(comparer != null);
@@ -393,11 +334,11 @@ namespace System.Collections.Generic
while (i <= n / 2)
{
child = 2 * i;
- if (child < n && comparer.Compare(keys[lo + child - 1], keys[lo + child]) < 0)
+ if (child < n && comparer(keys[lo + child - 1], keys[lo + child]) < 0)
{
child++;
}
- if (!(comparer.Compare(d, keys[lo + child - 1]) < 0))
+ if (!(comparer(d, keys[lo + child - 1]) < 0))
break;
keys[lo + i - 1] = keys[lo + child - 1];
i = child;
@@ -405,7 +346,7 @@ namespace System.Collections.Generic
keys[lo + i - 1] = d;
}
- private static void InsertionSort(T[] keys, int lo, int hi, IComparer<T> comparer)
+ private static void InsertionSort(T[] keys, int lo, int hi, Comparison<T> comparer)
{
Contract.Requires(keys != null);
Contract.Requires(lo >= 0);
@@ -418,7 +359,7 @@ namespace System.Collections.Generic
{
j = i;
t = keys[i + 1];
- while (j >= lo && comparer.Compare(t, keys[j]) < 0)
+ while (j >= lo && comparer(t, keys[j]) < 0)
{
keys[j + 1] = keys[j];
j--;
@@ -439,49 +380,18 @@ namespace System.Collections.Generic
public void Sort(T[] keys, int index, int length, IComparer<T> comparer)
{
- Contract.Assert(keys != null, "Check the arguments in the caller!");
- Contract.Assert(index >= 0 && length >= 0 && (keys.Length - index >= length), "Check the arguments in the caller!");
+ 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!");
try
{
- if (comparer == null || comparer == Comparer<T>.Default) {
-
-#if FEATURE_CORECLR
- // Since QuickSort and IntrospectiveSort produce different sorting sequence for equal keys the upgrade
- // to IntrospectiveSort was quirked. However since the phone builds always shipped with the new sort aka
- // IntrospectiveSort and we would want to continue using this sort moving forward CoreCLR always uses the new sort.
-
+ if (comparer == null || comparer == Comparer<T>.Default)
+ {
IntrospectiveSort(keys, index, length);
-#else
- // call the faster version of our sort algorithm if the user doesn't provide a comparer
- if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5)
- {
- IntrospectiveSort(keys, index, length);
- }
- else
- {
- DepthLimitedQuickSort(keys, index, length + index - 1, IntrospectiveSortUtilities.QuickSortDepthThreshold);
- }
-#endif
}
else
{
-#if FEATURE_CORECLR
- // Since QuickSort and IntrospectiveSort produce different sorting sequence for equal keys the upgrade
- // to IntrospectiveSort was quirked. However since the phone builds always shipped with the new sort aka
- // IntrospectiveSort and we would want to continue using this sort moving forward CoreCLR always uses the new sort.
-
- ArraySortHelper<T>.IntrospectiveSort(keys, index, length, comparer);
-#else
- if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5)
- {
- ArraySortHelper<T>.IntrospectiveSort(keys, index, length, comparer);
- }
- else
- {
- ArraySortHelper<T>.DepthLimitedQuickSort(keys, index, length + index - 1, comparer, IntrospectiveSortUtilities.QuickSortDepthThreshold);
- }
-#endif
+ ArraySortHelper<T>.IntrospectiveSort(keys, index, length, comparer.Compare);
}
}
catch (IndexOutOfRangeException)
@@ -496,8 +406,8 @@ namespace System.Collections.Generic
public int BinarySearch(T[] array, int index, int length, T value, IComparer<T> comparer)
{
- Contract.Assert(array != null, "Check the arguments in the caller!");
- Contract.Assert(index >= 0 && length >= 0 && (array.Length - index >= length), "Check the arguments in the caller!");
+ Debug.Assert(array != null, "Check the arguments in the caller!");
+ Debug.Assert(index >= 0 && length >= 0 && (array.Length - index >= length), "Check the arguments in the caller!");
try
{
@@ -583,78 +493,6 @@ namespace System.Collections.Generic
}
}
- private static void DepthLimitedQuickSort(T[] keys, int left, int right, int depthLimit)
- {
- Contract.Requires(keys != null);
- Contract.Requires(0 <= left && left < keys.Length);
- Contract.Requires(0 <= right && right < keys.Length);
-
- // The code in this function looks very similar to QuickSort in ArraySortHelper<T> class.
- // The difference is that T is constrainted to IComparable<T> here.
- // So the IL code will be different. This function is faster than the one in ArraySortHelper<T>.
-
- do
- {
- if (depthLimit == 0)
- {
- Heapsort(keys, left, right);
- return;
- }
-
- int i = left;
- int j = right;
-
- // pre-sort the low, middle (pivot), and high values in place.
- // this improves performance in the face of already sorted data, or
- // data that is made up of multiple sorted runs appended together.
- int middle = i + ((j - i) >> 1);
- SwapIfGreaterWithItems(keys, i, middle); // swap the low with the mid point
- SwapIfGreaterWithItems(keys, i, j); // swap the low with the high
- SwapIfGreaterWithItems(keys, middle, j); // swap the middle with the high
-
- T x = keys[middle];
- do
- {
- if (x == null)
- {
- // if x null, the loop to find two elements to be switched can be reduced.
- while (keys[j] != null) j--;
- }
- else
- {
- while (x.CompareTo(keys[i]) > 0) i++;
- while (x.CompareTo(keys[j]) < 0) j--;
- }
- Contract.Assert(i >= left && j <= right, "(i>=left && j<=right) Sort failed - Is your IComparer bogus?");
- if (i > j) break;
- if (i < j)
- {
- T key = keys[i];
- keys[i] = keys[j];
- keys[j] = key;
- }
- i++;
- j--;
- } while (i <= j);
-
- // The next iteration of the while loop is to "recursively" sort the larger half of the array and the
- // following calls recursively sort the smaller half. So we subtract one from depthLimit here so
- // both sorts see the new value.
- depthLimit--;
-
- if (j - left <= right - i)
- {
- if (left < j) DepthLimitedQuickSort(keys, left, j, depthLimit);
- left = i;
- }
- else
- {
- if (i < right) DepthLimitedQuickSort(keys, i, right, depthLimit);
- right = j;
- }
- } while (left < right);
- }
-
internal static void IntrospectiveSort(T[] keys, int left, int length)
{
Contract.Requires(keys != null);
@@ -824,7 +662,7 @@ namespace System.Collections.Generic
}
}
- #endregion
+#endregion
#region ArraySortHelper for paired key and value arrays
@@ -851,7 +689,6 @@ namespace System.Collections.Generic
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
private static IArraySortHelper<TKey, TValue> CreateArraySortHelper()
{
if (typeof(IComparable<TKey>).IsAssignableFrom(typeof(TKey)))
@@ -867,8 +704,8 @@ namespace System.Collections.Generic
public void Sort(TKey[] keys, TValue[] values, int index, int length, IComparer<TKey> comparer)
{
- Contract.Assert(keys != null, "Check the arguments in the caller!"); // Precondition on interface method
- Contract.Assert(index >= 0 && length >= 0 && (keys.Length - index >= length), "Check the arguments in the caller!");
+ Debug.Assert(keys != null, "Check the arguments in the caller!"); // Precondition on interface method
+ 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.
@@ -879,22 +716,7 @@ namespace System.Collections.Generic
comparer = Comparer<TKey>.Default;
}
-#if FEATURE_CORECLR
- // Since QuickSort and IntrospectiveSort produce different sorting sequence for equal keys the upgrade
- // to IntrospectiveSort was quirked. However since the phone builds always shipped with the new sort aka
- // IntrospectiveSort and we would want to continue using this sort moving forward CoreCLR always uses the new sort.
-
IntrospectiveSort(keys, values, index, length, comparer);
-#else
- if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5)
- {
- IntrospectiveSort(keys, values, index, length, comparer);
- }
- else
- {
- DepthLimitedQuickSort(keys, values, index, length + index - 1, comparer, IntrospectiveSortUtilities.QuickSortDepthThreshold);
- }
-#endif
}
catch (IndexOutOfRangeException)
{
@@ -947,68 +769,6 @@ namespace System.Collections.Generic
}
}
- internal static void DepthLimitedQuickSort(TKey[] keys, TValue[] values, int left, int right, IComparer<TKey> comparer, int depthLimit)
- {
- do
- {
- if (depthLimit == 0)
- {
- Heapsort(keys, values, left, right, comparer);
- return;
- }
-
- int i = left;
- int j = right;
-
- // pre-sort the low, middle (pivot), and high values in place.
- // this improves performance in the face of already sorted data, or
- // data that is made up of multiple sorted runs appended together.
- int middle = i + ((j - i) >> 1);
- SwapIfGreaterWithItems(keys, values, comparer, i, middle); // swap the low with the mid point
- SwapIfGreaterWithItems(keys, values, comparer, i, j); // swap the low with the high
- SwapIfGreaterWithItems(keys, values, comparer, middle, j); // swap the middle with the high
-
- TKey x = keys[middle];
- do
- {
- while (comparer.Compare(keys[i], x) < 0) i++;
- while (comparer.Compare(x, keys[j]) < 0) j--;
- Contract.Assert(i >= left && j <= right, "(i>=left && j<=right) Sort failed - Is your IComparer bogus?");
- if (i > j) break;
- if (i < j)
- {
- TKey key = keys[i];
- keys[i] = keys[j];
- keys[j] = key;
- if (values != null)
- {
- TValue value = values[i];
- values[i] = values[j];
- values[j] = value;
- }
- }
- i++;
- j--;
- } while (i <= j);
-
- // The next iteration of the while loop is to "recursively" sort the larger half of the array and the
- // following calls recursively sort the smaller half. So we subtract one from depthLimit here so
- // both sorts see the new value.
- depthLimit--;
-
- if (j - left <= right - i)
- {
- if (left < j) DepthLimitedQuickSort(keys, values, left, j, comparer, depthLimit);
- left = i;
- }
- else
- {
- if (i < right) DepthLimitedQuickSort(keys, values, i, right, comparer, depthLimit);
- right = j;
- }
- } while (left < right);
- }
-
internal static void IntrospectiveSort(TKey[] keys, TValue[] values, int left, int length, IComparer<TKey> comparer)
{
Contract.Requires(keys != null);
@@ -1199,8 +959,8 @@ namespace System.Collections.Generic
{
public void Sort(TKey[] keys, TValue[] values, int index, int length, IComparer<TKey> comparer)
{
- Contract.Assert(keys != null, "Check the arguments in the caller!");
- Contract.Assert( index >= 0 && length >= 0 && (keys.Length - index >= length), "Check the arguments in the caller!");
+ 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!");
// Add a try block here to detect IComparers (or their
// underlying IComparables, etc) that are bogus.
@@ -1208,44 +968,12 @@ namespace System.Collections.Generic
{
if (comparer == null || comparer == Comparer<TKey>.Default)
{
-#if FEATURE_CORECLR
- // Since QuickSort and IntrospectiveSort produce different sorting sequence for equal keys the upgrade
- // to IntrospectiveSort was quirked. However since the phone builds always shipped with the new sort aka
- // IntrospectiveSort and we would want to continue using this sort moving forward CoreCLR always uses the new sort.
-
IntrospectiveSort(keys, values, index, length);
-#else
- // call the faster version of our sort algorithm if the user doesn't provide a comparer
- if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5)
- {
- IntrospectiveSort(keys, values, index, length);
- }
- else
- {
- DepthLimitedQuickSort(keys, values, index, length + index - 1, IntrospectiveSortUtilities.QuickSortDepthThreshold);
- }
-#endif
}
else
{
-#if FEATURE_CORECLR
- // Since QuickSort and IntrospectiveSort produce different sorting sequence for equal keys the upgrade
- // to IntrospectiveSort was quirked. However since the phone builds always shipped with the new sort aka
- // IntrospectiveSort and we would want to continue using this sort moving forward CoreCLR always uses the new sort.
-
ArraySortHelper<TKey, TValue>.IntrospectiveSort(keys, values, index, length, comparer);
-#else
- if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5)
- {
- ArraySortHelper<TKey, TValue>.IntrospectiveSort(keys, values, index, length, comparer);
- }
- else
- {
- ArraySortHelper<TKey, TValue>.DepthLimitedQuickSort(keys, values, index, length + index - 1, comparer, IntrospectiveSortUtilities.QuickSortDepthThreshold);
- }
-#endif
}
-
}
catch (IndexOutOfRangeException)
{
@@ -1292,80 +1020,6 @@ namespace System.Collections.Generic
}
}
- private static void DepthLimitedQuickSort(TKey[] keys, TValue[] values, int left, int right, int depthLimit)
- {
- // The code in this function looks very similar to QuickSort in ArraySortHelper<T> class.
- // The difference is that T is constrainted to IComparable<T> here.
- // So the IL code will be different. This function is faster than the one in ArraySortHelper<T>.
-
- do
- {
- if (depthLimit == 0)
- {
- Heapsort(keys, values, left, right);
- return;
- }
-
- int i = left;
- int j = right;
-
- // pre-sort the low, middle (pivot), and high values in place.
- // this improves performance in the face of already sorted data, or
- // data that is made up of multiple sorted runs appended together.
- int middle = i + ((j - i) >> 1);
- SwapIfGreaterWithItems(keys, values, i, middle); // swap the low with the mid point
- SwapIfGreaterWithItems(keys, values, i, j); // swap the low with the high
- SwapIfGreaterWithItems(keys, values, middle, j); // swap the middle with the high
-
- TKey x = keys[middle];
- do
- {
- if (x == null)
- {
- // if x null, the loop to find two elements to be switched can be reduced.
- while (keys[j] != null) j--;
- }
- else
- {
- while (x.CompareTo(keys[i]) > 0) i++;
- while (x.CompareTo(keys[j]) < 0) j--;
- }
- Contract.Assert(i >= left && j <= right, "(i>=left && j<=right) Sort failed - Is your IComparer bogus?");
- if (i > j) break;
- if (i < j)
- {
- TKey key = keys[i];
- keys[i] = keys[j];
- keys[j] = key;
- if (values != null)
- {
- TValue value = values[i];
- values[i] = values[j];
- values[j] = value;
- }
- }
- i++;
- j--;
- } while (i <= j);
-
- // The next iteration of the while loop is to "recursively" sort the larger half of the array and the
- // following calls recursively sort the smaller half. So we subtract one from depthLimit here so
- // both sorts see the new value.
- depthLimit--;
-
- if (j - left <= right - i)
- {
- if (left < j) DepthLimitedQuickSort(keys, values, left, j, depthLimit);
- left = i;
- }
- else
- {
- if (i < right) DepthLimitedQuickSort(keys, values, i, right, depthLimit);
- right = j;
- }
- } while (left < right);
- }
-
internal static void IntrospectiveSort(TKey[] keys, TValue[] values, int left, int length)
{
Contract.Requires(keys != null);
@@ -1554,5 +1208,3 @@ namespace System.Collections.Generic
#endregion
}
-
-
diff --git a/src/mscorlib/src/System/Collections/Generic/Comparer.cs b/src/mscorlib/src/System/Collections/Generic/Comparer.cs
index 9f1a8bff6f..4f06b0af69 100644
--- a/src/mscorlib/src/System/Collections/Generic/Comparer.cs
+++ b/src/mscorlib/src/System/Collections/Generic/Comparer.cs
@@ -7,6 +7,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
//using System.Globalization;
using System.Runtime.CompilerServices;
@@ -33,7 +34,7 @@ namespace System.Collections.Generic
Contract.Ensures(Contract.Result<Comparer<T>>() != null);
if (comparison == null)
- throw new ArgumentNullException("comparison");
+ throw new ArgumentNullException(nameof(comparison));
return new ComparisonComparer<T>(comparison);
}
@@ -42,7 +43,6 @@ namespace System.Collections.Generic
// Note that logic in this method is replicated in vm\compile.cpp to ensure that NGen
// saves the right instantiations
//
- [System.Security.SecuritySafeCritical] // auto-generated
private static Comparer<T> CreateComparer()
{
object result = null;
@@ -139,7 +139,7 @@ namespace System.Collections.Generic
[Serializable]
internal sealed class NullableComparer<T> : Comparer<T?> where T : struct, IComparable<T>
{
- public override int Compare(Nullable<T> x, Nullable<T> y) {
+ public override int Compare(T? x, T? y) {
if (x.HasValue) {
if (y.HasValue) return x.value.CompareTo(y.value);
return 1;
@@ -196,7 +196,7 @@ namespace System.Collections.Generic
{
public Int32EnumComparer()
{
- Contract.Assert(typeof(T).IsEnum, "This type is only intended to be used to compare enums!");
+ Debug.Assert(typeof(T).IsEnum, "This type is only intended to be used to compare enums!");
}
// Used by the serialization engine.
@@ -216,7 +216,6 @@ namespace System.Collections.Generic
public override int GetHashCode() =>
GetType().GetHashCode();
- [SecurityCritical]
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
// Previously Comparer<T> was not specialized for enums,
@@ -232,7 +231,7 @@ namespace System.Collections.Generic
{
public UInt32EnumComparer()
{
- Contract.Assert(typeof(T).IsEnum, "This type is only intended to be used to compare enums!");
+ Debug.Assert(typeof(T).IsEnum, "This type is only intended to be used to compare enums!");
}
// Used by the serialization engine.
@@ -252,7 +251,6 @@ namespace System.Collections.Generic
public override int GetHashCode() =>
GetType().GetHashCode();
- [SecurityCritical]
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.SetType(typeof(ObjectComparer<T>));
@@ -264,7 +262,7 @@ namespace System.Collections.Generic
{
public Int64EnumComparer()
{
- Contract.Assert(typeof(T).IsEnum, "This type is only intended to be used to compare enums!");
+ Debug.Assert(typeof(T).IsEnum, "This type is only intended to be used to compare enums!");
}
// Used by the serialization engine.
@@ -284,7 +282,6 @@ namespace System.Collections.Generic
public override int GetHashCode() =>
GetType().GetHashCode();
- [SecurityCritical]
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.SetType(typeof(ObjectComparer<T>));
@@ -296,7 +293,7 @@ namespace System.Collections.Generic
{
public UInt64EnumComparer()
{
- Contract.Assert(typeof(T).IsEnum, "This type is only intended to be used to compare enums!");
+ Debug.Assert(typeof(T).IsEnum, "This type is only intended to be used to compare enums!");
}
// Used by the serialization engine.
@@ -316,7 +313,6 @@ namespace System.Collections.Generic
public override int GetHashCode() =>
GetType().GetHashCode();
- [SecurityCritical]
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.SetType(typeof(ObjectComparer<T>));
diff --git a/src/mscorlib/src/System/Collections/Generic/DebugView.cs b/src/mscorlib/src/System/Collections/Generic/DebugView.cs
index 57b91eff51..d0711e551e 100644
--- a/src/mscorlib/src/System/Collections/Generic/DebugView.cs
+++ b/src/mscorlib/src/System/Collections/Generic/DebugView.cs
@@ -110,7 +110,7 @@ namespace System.Collections.Generic {
public Mscorlib_KeyedCollectionDebugView(KeyedCollection<K, T> keyedCollection) {
if (keyedCollection == null) {
- throw new ArgumentNullException("keyedCollection");
+ throw new ArgumentNullException(nameof(keyedCollection));
}
Contract.EndContractBlock();
diff --git a/src/mscorlib/src/System/Collections/Generic/Dictionary.cs b/src/mscorlib/src/System/Collections/Generic/Dictionary.cs
index 9cbfff5a57..c2b2da9ad2 100644
--- a/src/mscorlib/src/System/Collections/Generic/Dictionary.cs
+++ b/src/mscorlib/src/System/Collections/Generic/Dictionary.cs
@@ -91,12 +91,12 @@ namespace System.Collections.Generic {
if (capacity > 0) Initialize(capacity);
this.comparer = comparer ?? EqualityComparer<TKey>.Default;
-#if FEATURE_RANDOMIZED_STRING_HASHING && FEATURE_CORECLR
+#if FEATURE_RANDOMIZED_STRING_HASHING
if (HashHelpers.s_UseRandomizedStringHashing && comparer == EqualityComparer<string>.Default)
{
this.comparer = (IEqualityComparer<TKey>) NonRandomizedStringEqualityComparer.Default;
}
-#endif // FEATURE_RANDOMIZED_STRING_HASHING && FEATURE_CORECLR
+#endif // FEATURE_RANDOMIZED_STRING_HASHING
}
public Dictionary(IDictionary<TKey,TValue> dictionary): this(dictionary, null) {}
@@ -129,6 +129,21 @@ namespace System.Collections.Generic {
}
}
+ public Dictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection):
+ this(collection, null) { }
+
+ public Dictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer):
+ this((collection as ICollection<KeyValuePair<TKey, TValue>>)?.Count ?? 0, comparer)
+ {
+ if (collection == null) {
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
+ }
+
+ foreach (KeyValuePair<TKey, TValue> pair in collection) {
+ Add(pair.Key, pair.Value);
+ }
+ }
+
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,
@@ -263,7 +278,7 @@ namespace System.Collections.Generic {
}
if (index < 0 || index > array.Length ) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
if (array.Length - index < Count) {
@@ -287,7 +302,6 @@ namespace System.Collections.Generic {
return new Enumerator(this, Enumerator.KeyValuePair);
}
- [System.Security.SecurityCritical] // auto-generated_required
public virtual void GetObjectData(SerializationInfo info, StreamingContext context) {
if (info==null) {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.info);
@@ -347,11 +361,7 @@ namespace System.Collections.Generic {
for (int i = buckets[targetBucket]; i >= 0; i = entries[i].next) {
if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)) {
if (add) {
-#if FEATURE_CORECLR
ThrowHelper.ThrowAddingDuplicateWithKeyArgumentException(key);
-#else
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate);
-#endif
}
entries[i].value = value;
version++;
@@ -386,8 +396,6 @@ namespace System.Collections.Generic {
version++;
#if FEATURE_RANDOMIZED_STRING_HASHING
-
-#if FEATURE_CORECLR
// In case we hit the collision threshold we'll need to switch to the comparer which is using randomized string hashing
// in this case will be EqualityComparer<string>.Default.
// Note, randomized string hashing is turned on by default on coreclr so EqualityComparer<string>.Default will
@@ -398,14 +406,6 @@ namespace System.Collections.Generic {
comparer = (IEqualityComparer<TKey>) EqualityComparer<string>.Default;
Resize(entries.Length, true);
}
-#else
- if(collisionCount > HashHelpers.HashCollisionThreshold && HashHelpers.IsWellKnownEqualityComparer(comparer))
- {
- comparer = (IEqualityComparer<TKey>) HashHelpers.GetRandomizedEqualityComparer(comparer);
- Resize(entries.Length, true);
- }
-#endif // FEATURE_CORECLR
-
#endif
}
@@ -459,7 +459,7 @@ namespace System.Collections.Generic {
}
private void Resize(int newSize, bool forceNewHashCodes) {
- Contract.Assert(newSize >= entries.Length);
+ 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];
@@ -523,16 +523,19 @@ namespace System.Collections.Generic {
return false;
}
- // This is a convenience method for the internal callers that were converted from using Hashtable.
- // Many were combining key doesn't exist and key exists but null value (for non-value types) checks.
- // This allows them to continue getting that behavior with minimal code delta. This is basically
- // TryGetValue without the out param
- internal TValue GetValueOrDefault(TKey key) {
+ // Method similar to TryGetValue that returns the value instead of putting it in an out param.
+ public TValue GetValueOrDefault(TKey key) => GetValueOrDefault(key, default(TValue));
+
+ // Method similar to TryGetValue that returns the value instead of putting it in an out param. If the entry
+ // doesn't exist, returns the defaultValue instead.
+ public TValue GetValueOrDefault(TKey key, TValue defaultValue)
+ {
int i = FindEntry(key);
- if (i >= 0) {
+ if (i >= 0)
+ {
return entries[i].value;
}
- return default(TValue);
+ return defaultValue;
}
bool ICollection<KeyValuePair<TKey,TValue>>.IsReadOnly {
@@ -557,7 +560,7 @@ namespace System.Collections.Generic {
}
if (index < 0 || index > array.Length) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
if (array.Length - index < Count) {
@@ -580,7 +583,7 @@ namespace System.Collections.Generic {
else {
object[] objects = array as object[];
if (objects == null) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
try {
@@ -593,7 +596,7 @@ namespace System.Collections.Generic {
}
}
catch(ArrayTypeMismatchException) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
}
}
@@ -733,7 +736,7 @@ namespace System.Collections.Generic {
public bool MoveNext() {
if (version != dictionary.version) {
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
// Use unsigned comparison since we set index to dictionary.count+1 when the enumeration ends.
@@ -762,7 +765,7 @@ namespace System.Collections.Generic {
object IEnumerator.Current {
get {
if( index == 0 || (index == dictionary.count + 1)) {
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
}
if (getEnumeratorRetType == DictEntry) {
@@ -775,7 +778,7 @@ namespace System.Collections.Generic {
void IEnumerator.Reset() {
if (version != dictionary.version) {
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
index = 0;
@@ -785,7 +788,7 @@ namespace System.Collections.Generic {
DictionaryEntry IDictionaryEnumerator.Entry {
get {
if( index == 0 || (index == dictionary.count + 1)) {
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
}
return new DictionaryEntry(current.Key, current.Value);
@@ -795,7 +798,7 @@ namespace System.Collections.Generic {
object IDictionaryEnumerator.Key {
get {
if( index == 0 || (index == dictionary.count + 1)) {
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
}
return current.Key;
@@ -805,7 +808,7 @@ namespace System.Collections.Generic {
object IDictionaryEnumerator.Value {
get {
if( index == 0 || (index == dictionary.count + 1)) {
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
}
return current.Value;
@@ -837,7 +840,7 @@ namespace System.Collections.Generic {
}
if (index < 0 || index > array.Length) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
if (array.Length - index < dictionary.Count) {
@@ -898,7 +901,7 @@ namespace System.Collections.Generic {
}
if (index < 0 || index > array.Length) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
if (array.Length - index < dictionary.Count) {
@@ -912,7 +915,7 @@ namespace System.Collections.Generic {
else {
object[] objects = array as object[];
if (objects == null) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
int count = dictionary.count;
@@ -923,7 +926,7 @@ namespace System.Collections.Generic {
}
}
catch(ArrayTypeMismatchException) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
}
}
@@ -956,7 +959,7 @@ namespace System.Collections.Generic {
public bool MoveNext() {
if (version != dictionary.version) {
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
while ((uint)index < (uint)dictionary.count) {
@@ -982,7 +985,7 @@ namespace System.Collections.Generic {
Object System.Collections.IEnumerator.Current {
get {
if( index == 0 || (index == dictionary.count + 1)) {
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
}
return currentKey;
@@ -991,7 +994,7 @@ namespace System.Collections.Generic {
void System.Collections.IEnumerator.Reset() {
if (version != dictionary.version) {
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
index = 0;
@@ -1024,7 +1027,7 @@ namespace System.Collections.Generic {
}
if (index < 0 || index > array.Length) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
if (array.Length - index < dictionary.Count) {
@@ -1085,7 +1088,7 @@ namespace System.Collections.Generic {
}
if (index < 0 || index > array.Length) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
if (array.Length - index < dictionary.Count)
@@ -1098,7 +1101,7 @@ namespace System.Collections.Generic {
else {
object[] objects = array as object[];
if (objects == null) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
int count = dictionary.count;
@@ -1109,7 +1112,7 @@ namespace System.Collections.Generic {
}
}
catch(ArrayTypeMismatchException) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
}
}
@@ -1142,7 +1145,7 @@ namespace System.Collections.Generic {
public bool MoveNext() {
if (version != dictionary.version) {
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
while ((uint)index < (uint)dictionary.count) {
@@ -1167,7 +1170,7 @@ namespace System.Collections.Generic {
Object System.Collections.IEnumerator.Current {
get {
if( index == 0 || (index == dictionary.count + 1)) {
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
}
return currentValue;
@@ -1176,7 +1179,7 @@ namespace System.Collections.Generic {
void System.Collections.IEnumerator.Reset() {
if (version != dictionary.version) {
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
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 b845d64fed..3731114119 100644
--- a/src/mscorlib/src/System/Collections/Generic/EqualityComparer.cs
+++ b/src/mscorlib/src/System/Collections/Generic/EqualityComparer.cs
@@ -32,7 +32,6 @@ namespace System.Collections.Generic
// Note that logic in this method is replicated in vm\compile.cpp to ensure that NGen
// saves the right instantiations
//
- [System.Security.SecuritySafeCritical] // auto-generated
private static EqualityComparer<T> CreateComparer()
{
Contract.Ensures(Contract.Result<EqualityComparer<T>>() != null);
@@ -144,10 +143,7 @@ namespace System.Collections.Generic
}
[Pure]
- public override int GetHashCode(T obj) {
- if (obj == null) return 0;
- return obj.GetHashCode();
- }
+ public override int GetHashCode(T obj) => obj?.GetHashCode() ?? 0;
internal override int IndexOf(T[] array, T value, int startIndex, int count) {
int endIndex = startIndex + count;
@@ -179,22 +175,21 @@ namespace System.Collections.Generic
return -1;
}
- // Equals method for the comparer itself.
- public override bool Equals(Object obj){
- GenericEqualityComparer<T> comparer = obj as GenericEqualityComparer<T>;
- return comparer != null;
- }
+ // Equals method for the comparer itself.
+ // If in the future this type is made sealed, change the is check to obj != null && GetType() == obj.GetType().
+ public override bool Equals(Object obj) =>
+ obj is GenericEqualityComparer<T>;
- public override int GetHashCode() {
- return this.GetType().Name.GetHashCode();
- }
+ // If in the future this type is made sealed, change typeof(...) to GetType().
+ public override int GetHashCode() =>
+ typeof(GenericEqualityComparer<T>).GetHashCode();
}
[Serializable]
- internal class NullableEqualityComparer<T> : EqualityComparer<Nullable<T>> where T : struct, IEquatable<T>
+ internal sealed class NullableEqualityComparer<T> : EqualityComparer<T?> where T : struct, IEquatable<T>
{
[Pure]
- public override bool Equals(Nullable<T> x, Nullable<T> y) {
+ public override bool Equals(T? x, T? y) {
if (x.HasValue) {
if (y.HasValue) return x.value.Equals(y.value);
return false;
@@ -204,11 +199,9 @@ namespace System.Collections.Generic
}
[Pure]
- public override int GetHashCode(Nullable<T> obj) {
- return obj.GetHashCode();
- }
+ public override int GetHashCode(T? obj) => obj.GetHashCode();
- internal override int IndexOf(Nullable<T>[] array, Nullable<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++) {
@@ -223,7 +216,7 @@ namespace System.Collections.Generic
return -1;
}
- internal override int LastIndexOf(Nullable<T>[] array, Nullable<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--) {
@@ -238,19 +231,16 @@ namespace System.Collections.Generic
return -1;
}
- // Equals method for the comparer itself.
- public override bool Equals(Object obj){
- NullableEqualityComparer<T> comparer = obj as NullableEqualityComparer<T>;
- return comparer != null;
- }
+ // Equals method for the comparer itself.
+ public override bool Equals(Object obj) =>
+ obj != null && GetType() == obj.GetType();
- public override int GetHashCode() {
- return this.GetType().Name.GetHashCode();
- }
+ public override int GetHashCode() =>
+ GetType().GetHashCode();
}
[Serializable]
- internal class ObjectEqualityComparer<T>: EqualityComparer<T>
+ internal sealed class ObjectEqualityComparer<T>: EqualityComparer<T>
{
[Pure]
public override bool Equals(T x, T y) {
@@ -263,10 +253,7 @@ namespace System.Collections.Generic
}
[Pure]
- public override int GetHashCode(T obj) {
- if (obj == null) return 0;
- return obj.GetHashCode();
- }
+ public override int GetHashCode(T obj) => obj?.GetHashCode() ?? 0;
internal override int IndexOf(T[] array, T value, int startIndex, int count) {
int endIndex = startIndex + count;
@@ -298,25 +285,21 @@ namespace System.Collections.Generic
return -1;
}
- // Equals method for the comparer itself.
- public override bool Equals(Object obj){
- ObjectEqualityComparer<T> comparer = obj as ObjectEqualityComparer<T>;
- return comparer != null;
- }
+ // Equals method for the comparer itself.
+ public override bool Equals(Object obj) =>
+ obj != null && GetType() == obj.GetType();
- public override int GetHashCode() {
- return this.GetType().Name.GetHashCode();
- }
+ public override int GetHashCode() =>
+ GetType().GetHashCode();
}
-#if FEATURE_CORECLR
// NonRandomizedStringEqualityComparer is the comparer used by default with the Dictionary<string,...>
// As the randomized string hashing is turned on by default on coreclr, we need to keep the performance not affected
// as much as possible in the main stream scenarios like Dictionary<string,>
// We use NonRandomizedStringEqualityComparer as default comparer as it doesnt use the randomized string hashing which
// 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;
@@ -335,12 +318,11 @@ namespace System.Collections.Generic
return obj.GetLegacyNonRandomizedHashCode();
}
}
-#endif // FEATURE_CORECLR
// 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 class ByteEqualityComparer: EqualityComparer<byte>
+ internal sealed class ByteEqualityComparer: EqualityComparer<byte>
{
[Pure]
public override bool Equals(byte x, byte y) {
@@ -352,14 +334,13 @@ namespace System.Collections.Generic
return b.GetHashCode();
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe override int IndexOf(byte[] array, byte value, int startIndex, int count) {
if (array==null)
- throw new ArgumentNullException("array");
+ throw new ArgumentNullException(nameof(array));
if (startIndex < 0)
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
if (count > array.Length - startIndex)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -377,15 +358,12 @@ namespace System.Collections.Generic
return -1;
}
- // Equals method for the comparer itself.
- public override bool Equals(Object obj){
- ByteEqualityComparer comparer = obj as ByteEqualityComparer;
- return comparer != null;
- }
+ // Equals method for the comparer itself.
+ public override bool Equals(Object obj) =>
+ obj != null && GetType() == obj.GetType();
- public override int GetHashCode() {
- return this.GetType().Name.GetHashCode();
- }
+ public override int GetHashCode() =>
+ GetType().GetHashCode();
}
[Serializable]
@@ -409,7 +387,6 @@ namespace System.Collections.Generic
// This is used by the serialization engine.
protected EnumEqualityComparer(SerializationInfo information, StreamingContext context) { }
- [SecurityCritical]
public void GetObjectData(SerializationInfo info, StreamingContext context) {
// For back-compat we need to serialize the comparers for enums with underlying types other than int as ObjectEqualityComparer
if (Type.GetTypeCode(Enum.GetUnderlyingType(typeof(T))) != TypeCode.Int32) {
@@ -417,14 +394,35 @@ namespace System.Collections.Generic
}
}
- // Equals method for the comparer itself.
- public override bool Equals(Object obj){
- EnumEqualityComparer<T> comparer = obj as EnumEqualityComparer<T>;
- return comparer != null;
+ // Equals method for the comparer itself.
+ public override bool Equals(Object obj) =>
+ obj != null && GetType() == obj.GetType();
+
+ public override int GetHashCode() =>
+ GetType().GetHashCode();
+
+ internal override int IndexOf(T[] array, T value, int startIndex, int count)
+ {
+ int toFind = JitHelpers.UnsafeEnumCast(value);
+ int endIndex = startIndex + count;
+ for (int i = startIndex; i < endIndex; i++)
+ {
+ int current = JitHelpers.UnsafeEnumCast(array[i]);
+ if (toFind == current) return i;
+ }
+ return -1;
}
- public override int GetHashCode() {
- return this.GetType().Name.GetHashCode();
+ internal override int LastIndexOf(T[] array, T value, int startIndex, int count)
+ {
+ int toFind = JitHelpers.UnsafeEnumCast(value);
+ int endIndex = startIndex - count + 1;
+ for (int i = startIndex; i >= endIndex; i--)
+ {
+ int current = JitHelpers.UnsafeEnumCast(array[i]);
+ if (toFind == current) return i;
+ }
+ return -1;
}
}
@@ -474,28 +472,48 @@ namespace System.Collections.Generic
return x_final.GetHashCode();
}
- // Equals method for the comparer itself.
- public override bool Equals(Object obj){
- LongEnumEqualityComparer<T> comparer = obj as LongEnumEqualityComparer<T>;
- return comparer != null;
- }
+ // Equals method for the comparer itself.
+ public override bool Equals(Object obj) =>
+ obj != null && GetType() == obj.GetType();
- public override int GetHashCode() {
- return this.GetType().Name.GetHashCode();
- }
+ public override int GetHashCode() =>
+ GetType().GetHashCode();
public LongEnumEqualityComparer() { }
// This is used by the serialization engine.
public LongEnumEqualityComparer(SerializationInfo information, StreamingContext context) { }
- [SecurityCritical]
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
// The LongEnumEqualityComparer does not exist on 4.0 so we need to serialize this comparer as ObjectEqualityComparer
// to allow for roundtrip between 4.0 and 4.5.
info.SetType(typeof(ObjectEqualityComparer<T>));
}
+
+ internal override int IndexOf(T[] array, T value, int startIndex, int count)
+ {
+ long toFind = JitHelpers.UnsafeEnumCastLong(value);
+ int endIndex = startIndex + count;
+ for (int i = startIndex; i < endIndex; i++)
+ {
+ long current = JitHelpers.UnsafeEnumCastLong(array[i]);
+ if (toFind == current) return i;
+ }
+ return -1;
+ }
+
+ internal override int LastIndexOf(T[] array, T value, int startIndex, int count)
+ {
+ long toFind = JitHelpers.UnsafeEnumCastLong(value);
+ int endIndex = startIndex - count + 1;
+ for (int i = startIndex; i >= endIndex; i--)
+ {
+ long current = JitHelpers.UnsafeEnumCastLong(array[i]);
+ if (toFind == current) return i;
+ }
+ return -1;
+ }
}
#if FEATURE_RANDOMIZED_STRING_HASHING
@@ -528,14 +546,12 @@ namespace System.Collections.Generic
}
[Pure]
- [SecuritySafeCritical]
public int GetHashCode(String obj) {
if(obj == null) return 0;
return String.InternalMarvin32HashString(obj, obj.Length, _entropy);
}
[Pure]
- [SecuritySafeCritical]
public int GetHashCode(Object obj) {
if(obj == null) return 0;
@@ -552,7 +568,7 @@ namespace System.Collections.Generic
}
public override int GetHashCode() {
- return (this.GetType().Name.GetHashCode() ^ ((int) (_entropy & 0x7FFFFFFF)));
+ return (this.GetType().GetHashCode() ^ ((int) (_entropy & 0x7FFFFFFF)));
}
@@ -587,7 +603,6 @@ namespace System.Collections.Generic
}
[Pure]
- [SecuritySafeCritical]
public int GetHashCode(Object obj) {
if(obj == null) return 0;
@@ -604,7 +619,7 @@ namespace System.Collections.Generic
}
public override int GetHashCode() {
- return (this.GetType().Name.GetHashCode() ^ ((int) (_entropy & 0x7FFFFFFF)));
+ return (this.GetType().GetHashCode() ^ ((int) (_entropy & 0x7FFFFFFF)));
}
IEqualityComparer IWellKnownStringEqualityComparer.GetRandomizedEqualityComparer() {
diff --git a/src/mscorlib/src/System/Collections/Generic/KeyValuePair.cs b/src/mscorlib/src/System/Collections/Generic/KeyValuePair.cs
index 17e1c531f1..ad9f7472aa 100644
--- a/src/mscorlib/src/System/Collections/Generic/KeyValuePair.cs
+++ b/src/mscorlib/src/System/Collections/Generic/KeyValuePair.cs
@@ -18,6 +18,16 @@ namespace System.Collections.Generic {
using System;
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>.
@@ -52,5 +62,12 @@ namespace System.Collections.Generic {
s.Append(']');
return StringBuilderCache.GetStringAndRelease(s);
}
+
+ // BLOCKED (do not add now): [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 ae3356d372..3e2947f5f9 100644
--- a/src/mscorlib/src/System/Collections/Generic/List.cs
+++ b/src/mscorlib/src/System/Collections/Generic/List.cs
@@ -91,14 +91,7 @@ namespace System.Collections.Generic {
else {
_size = 0;
_items = _emptyArray;
- // This enumerable could be empty. Let Add allocate a new array, if needed.
- // Note it will also go to _defaultCapacity first, not 1, then 2, etc.
-
- using(IEnumerator<T> en = collection.GetEnumerator()) {
- while(en.MoveNext()) {
- Add(en.Current);
- }
- }
+ AddEnumerable(collection);
}
}
@@ -274,7 +267,7 @@ namespace System.Collections.Generic {
//
public int BinarySearch(int index, int count, T item, IComparer<T> comparer) {
if (index < 0)
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
if (count < 0)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
if (_size - index < count)
@@ -369,7 +362,7 @@ namespace System.Collections.Generic {
Array.Copy(_items, 0, array, arrayIndex, _size);
}
catch(ArrayTypeMismatchException){
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
}
@@ -393,7 +386,7 @@ namespace System.Collections.Generic {
}
// Ensures that the capacity of this list is at least the given minimum
- // value. If the currect capacity of the list is less than min, the
+ // 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) {
@@ -454,11 +447,11 @@ namespace System.Collections.Generic {
public int FindIndex(int startIndex, int count, Predicate<T> match) {
if( (uint)startIndex > (uint)_size ) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
}
if (count < 0 || startIndex > _size - count) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_Count);
+ ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count();
}
if( match == null) {
@@ -512,19 +505,19 @@ namespace System.Collections.Generic {
if(_size == 0) {
// Special case for 0 length List
if( startIndex != -1) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
}
}
else {
// Make sure we're not out of range
if ( (uint)startIndex >= (uint)_size) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ 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) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_Count);
+ ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count();
}
int endIndex = startIndex - count;
@@ -545,14 +538,14 @@ namespace System.Collections.Generic {
int version = _version;
for(int i = 0 ; i < _size; i++) {
- if (version != _version && BinaryCompatibility.TargetsAtLeast_Desktop_V4_5) {
+ if (version != _version) {
break;
}
action(_items[i]);
}
- if (version != _version && BinaryCompatibility.TargetsAtLeast_Desktop_V4_5)
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
+ if (version != _version)
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
// Returns an enumerator for this list with the given
@@ -575,7 +568,7 @@ namespace System.Collections.Generic {
public List<T> GetRange(int index, int count) {
if (index < 0) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
if (count < 0) {
@@ -628,7 +621,7 @@ namespace System.Collections.Generic {
//
public int IndexOf(T item, int index) {
if (index > _size)
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowArgumentOutOfRange_IndexException();
Contract.Ensures(Contract.Result<int>() >= -1);
Contract.Ensures(Contract.Result<int>() < Count);
Contract.EndContractBlock();
@@ -646,9 +639,9 @@ namespace System.Collections.Generic {
//
public int IndexOf(T item, int index, int count) {
if (index > _size)
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowArgumentOutOfRange_IndexException();
- if (count <0 || index > _size - count) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.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();
@@ -698,7 +691,7 @@ namespace System.Collections.Generic {
}
if ((uint)index > (uint)_size) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowArgumentOutOfRange_IndexException();
}
Contract.EndContractBlock();
@@ -719,20 +712,24 @@ namespace System.Collections.Generic {
Array.Copy(_items, index+count, _items, index*2, _size-index);
}
else {
- T[] itemsToInsert = new T[count];
- c.CopyTo(itemsToInsert, 0);
- itemsToInsert.CopyTo(_items, index);
+ c.CopyTo(_items, index);
}
_size += count;
}
}
- else {
+ 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);
}
}
}
+ else
+ {
+ // We're adding a lazy enumerable because the index is at the end of this list.
+ AddEnumerable(collection);
+ }
_version++;
}
@@ -768,7 +765,7 @@ namespace System.Collections.Generic {
public int LastIndexOf(T item, int index)
{
if (index >= _size)
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_Index);
+ ThrowHelper.ThrowArgumentOutOfRange_IndexException();
Contract.Ensures(Contract.Result<int>() >= -1);
Contract.Ensures(((Count == 0) && (Contract.Result<int>() == -1)) || ((Count > 0) && (Contract.Result<int>() <= index)));
Contract.EndContractBlock();
@@ -786,7 +783,7 @@ namespace System.Collections.Generic {
//
public int LastIndexOf(T item, int index, int count) {
if ((Count != 0) && (index < 0)) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
if ((Count !=0) && (count < 0)) {
@@ -885,7 +882,7 @@ namespace System.Collections.Generic {
//
public void RemoveRange(int index, int count) {
if (index < 0) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
if (count < 0) {
@@ -919,7 +916,7 @@ namespace System.Collections.Generic {
//
public void Reverse(int index, int count) {
if (index < 0) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
if (count < 0) {
@@ -930,22 +927,7 @@ namespace System.Collections.Generic {
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
Contract.EndContractBlock();
- // The non-generic Array.Reverse is not used because it does not perform
- // well for non-primitive value types.
- // If/when a generic Array.Reverse<T> becomes available, the below code
- // can be deleted and replaced with a call to Array.Reverse<T>.
- int i = index;
- int j = index + count - 1;
- T[] array = _items;
- while (i < j)
- {
- T temp = array[i];
- array[i] = array[j];
- array[j] = temp;
- i++;
- j--;
- }
-
+ Array.Reverse(_items, index, count);
_version++;
}
@@ -973,7 +955,7 @@ namespace System.Collections.Generic {
//
public void Sort(int index, int count, IComparer<T> comparer) {
if (index < 0) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
if (count < 0) {
@@ -995,8 +977,7 @@ namespace System.Collections.Generic {
Contract.EndContractBlock();
if( _size > 0) {
- IComparer<T> comparer = Comparer<T>.Create(comparison);
- Array.Sort(_items, 0, _size, comparer);
+ ArraySortHelper<T>.Sort(_items, 0, _size, comparison);
}
}
@@ -1006,12 +987,10 @@ namespace System.Collections.Generic {
Contract.Ensures(Contract.Result<T[]>() != null);
Contract.Ensures(Contract.Result<T[]>().Length == Count);
-#if FEATURE_CORECLR
if (_size == 0)
{
return _emptyArray;
}
-#endif
T[] array = new T[_size];
Array.Copy(_items, 0, array, 0, _size);
@@ -1048,6 +1027,31 @@ namespace System.Collections.Generic {
return true;
}
+ private void AddEnumerable(IEnumerable<T> enumerable)
+ {
+ Debug.Assert(enumerable != null);
+ Debug.Assert(!(enumerable is ICollection<T>), "We should have optimized for this beforehand.");
+
+ using (IEnumerator<T> en = enumerable.GetEnumerator())
+ {
+ _version++; // Even if the enumerable has no items, we can update _version.
+
+ while (en.MoveNext())
+ {
+ // Capture Current before doing anything else. If this throws
+ // an exception, we want to make a clean break.
+ T current = en.Current;
+
+ if (_size == _items.Length)
+ {
+ EnsureCapacity(_size + 1);
+ }
+
+ _items[_size++] = current;
+ }
+ }
+ }
+
[Serializable]
public struct Enumerator : IEnumerator<T>, System.Collections.IEnumerator
{
@@ -1082,7 +1086,7 @@ namespace System.Collections.Generic {
private bool MoveNextRare()
{
if (version != list._version) {
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
index = list._size + 1;
@@ -1099,7 +1103,7 @@ namespace System.Collections.Generic {
Object System.Collections.IEnumerator.Current {
get {
if( index == 0 || index == list._size + 1) {
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
}
return Current;
}
@@ -1107,7 +1111,7 @@ namespace System.Collections.Generic {
void System.Collections.IEnumerator.Reset() {
if (version != list._version) {
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
index = 0;
diff --git a/src/mscorlib/src/System/Collections/Hashtable.cs b/src/mscorlib/src/System/Collections/Hashtable.cs
index 262ccedea6..d4c7d8d673 100644
--- a/src/mscorlib/src/System/Collections/Hashtable.cs
+++ b/src/mscorlib/src/System/Collections/Hashtable.cs
@@ -23,10 +23,7 @@ namespace System.Collections {
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
using System.Diagnostics.Contracts;
-#if !FEATURE_CORECLR
- using System.Security.Cryptography;
-#endif
-
+
// The Hashtable class represents a dictionary of associated keys and values
// with constant lookup time.
//
@@ -271,9 +268,9 @@ namespace System.Collections {
//
public Hashtable(int capacity, float loadFactor) {
if (capacity < 0)
- throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(capacity), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (!(loadFactor >= 0.1f && loadFactor <= 1.0f))
- throw new ArgumentOutOfRangeException("loadFactor", Environment.GetResourceString("ArgumentOutOfRange_HashtableLoadFactor", .1, 1.0));
+ throw new ArgumentOutOfRangeException(nameof(loadFactor), Environment.GetResourceString("ArgumentOutOfRange_HashtableLoadFactor", .1, 1.0));
Contract.EndContractBlock();
// Based on perf work, .72 is the optimal load factor for this table.
@@ -290,7 +287,7 @@ namespace System.Collections {
loadsize = (int)(this.loadFactor * hashsize);
isWriterInProgress = false;
// Based on the current algorithm, loadsize must be less than hashsize.
- Contract.Assert( loadsize < hashsize, "Invalid hashtable loadsize!");
+ Debug.Assert( loadsize < hashsize, "Invalid hashtable loadsize!");
}
// Constructs a new hashtable with the given initial capacity and load
@@ -375,7 +372,7 @@ namespace System.Collections {
public Hashtable(IDictionary d, float loadFactor, IHashCodeProvider hcp, IComparer comparer)
: this((d != null ? d.Count : 0), loadFactor, hcp, comparer) {
if (d==null)
- throw new ArgumentNullException("d", Environment.GetResourceString("ArgumentNull_Dictionary"));
+ throw new ArgumentNullException(nameof(d), Environment.GetResourceString("ArgumentNull_Dictionary"));
Contract.EndContractBlock();
IDictionaryEnumerator e = d.GetEnumerator();
@@ -385,7 +382,7 @@ namespace System.Collections {
public Hashtable(IDictionary d, float loadFactor, IEqualityComparer equalityComparer)
: this((d != null ? d.Count : 0), loadFactor, equalityComparer) {
if (d==null)
- throw new ArgumentNullException("d", Environment.GetResourceString("ArgumentNull_Dictionary"));
+ throw new ArgumentNullException(nameof(d), Environment.GetResourceString("ArgumentNull_Dictionary"));
Contract.EndContractBlock();
IDictionaryEnumerator e = d.GetEnumerator();
@@ -444,14 +441,11 @@ namespace System.Collections {
// Removes all entries from this hashtable.
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public virtual void Clear() {
- Contract.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.");
+ 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;
-#if !FEATURE_CORECLR
- Thread.BeginCriticalRegion();
-#endif
isWriterInProgress = true;
for (int i = 0; i < buckets.Length; i++){
buckets[i].hash_coll = 0;
@@ -463,9 +457,6 @@ namespace System.Collections {
occupancy = 0;
UpdateVersion();
isWriterInProgress = false;
-#if !FEATURE_CORECLR
- Thread.EndCriticalRegion();
-#endif
}
// Clone returns a virtually identical copy of this hash table. This does
@@ -501,7 +492,7 @@ namespace System.Collections {
//
public virtual bool ContainsKey(Object key) {
if (key == null) {
- throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key"));
+ throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
}
Contract.EndContractBlock();
@@ -526,9 +517,7 @@ namespace System.Collections {
} while (b.hash_coll < 0 && ++ntry < lbuckets.Length);
return false;
}
-
-
-
+
// Checks if this hashtable contains an entry with the given value. The
// values of the entries of the hashtable are compared to the given value
// using the Object.Equals method. This method performs a linear
@@ -590,11 +579,11 @@ namespace System.Collections {
public virtual void CopyTo(Array array, int arrayIndex)
{
if (array == null)
- throw new ArgumentNullException("array", Environment.GetResourceString("ArgumentNull_Array"));
+ throw new ArgumentNullException(nameof(array), Environment.GetResourceString("ArgumentNull_Array"));
if (array.Rank != 1)
throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
if (arrayIndex < 0)
- throw new ArgumentOutOfRangeException("arrayIndex", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(arrayIndex), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (array.Length - arrayIndex < Count)
throw new ArgumentException(Environment.GetResourceString("Arg_ArrayPlusOffTooSmall"));
Contract.EndContractBlock();
@@ -643,7 +632,7 @@ namespace System.Collections {
public virtual Object this[Object key] {
get {
if (key == null) {
- throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key"));
+ throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
}
Contract.EndContractBlock();
@@ -750,28 +739,23 @@ namespace System.Collections {
for (nb = 0; nb < buckets.Length; nb++){
bucket oldb = buckets[nb];
if ((oldb.key != null) && (oldb.key != buckets)) {
- int hashcode = ((forceNewHashCode ? GetHash(oldb.key) : oldb.hash_coll) & 0x7FFFFFFF);
+ int hashcode = ((forceNewHashCode ? GetHash(oldb.key) : oldb.hash_coll) & 0x7FFFFFFF);
putEntry(newBuckets, oldb.key, oldb.val, hashcode);
}
}
-
+
// New bucket[] is good to go - replace buckets and other internal state.
-#if !FEATURE_CORECLR
- Thread.BeginCriticalRegion();
-#endif
isWriterInProgress = true;
buckets = newBuckets;
loadsize = (int)(loadFactor * newsize);
UpdateVersion();
isWriterInProgress = false;
-#if !FEATURE_CORECLR
- Thread.EndCriticalRegion();
-#endif
+
// minimun size of hashtable is 3 now and maximum loadFactor is 0.72 now.
- Contract.Assert(loadsize < newsize, "Our current implementaion means this is not possible.");
+ Debug.Assert(loadsize < newsize, "Our current implementaion means this is not possible.");
return;
}
-
+
// Returns an enumerator for this hashtable.
// If modifications made to the hashtable while an enumeration is
// in progress, the MoveNext and Current methods of the
@@ -820,7 +804,7 @@ namespace System.Collections {
//
protected virtual bool KeyEquals(Object item, Object key)
{
- Contract.Assert(key != null, "key can't be null here!");
+ Debug.Assert(key != null, "key can't be null here!");
if( Object.ReferenceEquals(buckets, item)) {
return false;
}
@@ -872,7 +856,7 @@ namespace System.Collections {
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
private void Insert (Object key, Object nvalue, bool add) {
if (key == null) {
- throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key"));
+ throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
}
Contract.EndContractBlock();
if (count >= loadsize) {
@@ -913,36 +897,14 @@ namespace System.Collections {
// We pretty much have to insert in this order. Don't set hash
// code until the value & key are set appropriately.
-#if !FEATURE_CORECLR
- Thread.BeginCriticalRegion();
-#endif
- isWriterInProgress = true;
+ isWriterInProgress = true;
buckets[bucketNumber].val = nvalue;
buckets[bucketNumber].key = key;
buckets[bucketNumber].hash_coll |= (int) hashcode;
count++;
UpdateVersion();
isWriterInProgress = false;
-#if !FEATURE_CORECLR
- Thread.EndCriticalRegion();
-#endif
-#if FEATURE_RANDOMIZED_STRING_HASHING
-#if !FEATURE_CORECLR
- // coreclr has the randomized string hashing on by default so we don't need to resize at this point
-
- if(ntry > HashHelpers.HashCollisionThreshold && HashHelpers.IsWellKnownEqualityComparer(_keycomparer))
- {
- // PERF: We don't want to rehash if _keycomparer is already a RandomizedObjectEqualityComparer since in some
- // cases there may not be any strings in the hashtable and we wouldn't get any mixing.
- if(_keycomparer == null || !(_keycomparer is System.Collections.Generic.RandomizedObjectEqualityComparer))
- {
- _keycomparer = HashHelpers.GetRandomizedEqualityComparer(_keycomparer);
- rehash(buckets.Length, true);
- }
- }
-#endif // !FEATURE_CORECLR
-#endif // FEATURE_RANDOMIZED_STRING_HASHING
return;
}
@@ -954,31 +916,10 @@ namespace System.Collections {
if (add) {
throw new ArgumentException(Environment.GetResourceString("Argument_AddingDuplicate__", buckets[bucketNumber].key, key));
}
-#if !FEATURE_CORECLR
- Thread.BeginCriticalRegion();
-#endif
- isWriterInProgress = true;
+ isWriterInProgress = true;
buckets[bucketNumber].val = nvalue;
- UpdateVersion();
+ UpdateVersion();
isWriterInProgress = false;
-#if !FEATURE_CORECLR
- Thread.EndCriticalRegion();
-#endif
-
-#if FEATURE_RANDOMIZED_STRING_HASHING
-#if !FEATURE_CORECLR
- if(ntry > HashHelpers.HashCollisionThreshold && HashHelpers.IsWellKnownEqualityComparer(_keycomparer))
- {
- // PERF: We don't want to rehash if _keycomparer is already a RandomizedObjectEqualityComparer since in some
- // cases there may not be any strings in the hashtable and we wouldn't get any mixing.
- if(_keycomparer == null || !(_keycomparer is System.Collections.Generic.RandomizedObjectEqualityComparer))
- {
- _keycomparer = HashHelpers.GetRandomizedEqualityComparer(_keycomparer);
- rehash(buckets.Length, true);
- }
- }
-#endif // !FEATURE_CORECLR
-#endif
return;
}
@@ -992,7 +933,7 @@ namespace System.Collections {
}
}
- 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
@@ -1000,47 +941,27 @@ namespace System.Collections {
{
// We pretty much have to insert in this order. Don't set hash
// code until the value & key are set appropriately.
-#if !FEATURE_CORECLR
- Thread.BeginCriticalRegion();
-#endif
- isWriterInProgress = true;
+ isWriterInProgress = true;
buckets[emptySlotNumber].val = nvalue;
buckets[emptySlotNumber].key = key;
buckets[emptySlotNumber].hash_coll |= (int) hashcode;
count++;
UpdateVersion();
isWriterInProgress = false;
-#if !FEATURE_CORECLR
- Thread.EndCriticalRegion();
-#endif
-#if FEATURE_RANDOMIZED_STRING_HASHING
-#if !FEATURE_CORECLR
- if(buckets.Length > HashHelpers.HashCollisionThreshold && HashHelpers.IsWellKnownEqualityComparer(_keycomparer))
- {
- // PERF: We don't want to rehash if _keycomparer is already a RandomizedObjectEqualityComparer since in some
- // cases there may not be any strings in the hashtable and we wouldn't get any mixing.
- if(_keycomparer == null || !(_keycomparer is System.Collections.Generic.RandomizedObjectEqualityComparer))
- {
- _keycomparer = HashHelpers.GetRandomizedEqualityComparer(_keycomparer);
- rehash(buckets.Length, true);
- }
- }
-#endif // !FEATURE_CORECLR
-#endif
return;
}
-
+
// If you see this assert, make sure load factor & count are reasonable.
// Then verify that our double hash function (h2, described at top of file)
// meets the requirements described above. You should never see this assert.
- Contract.Assert(false, "hash table insert failed! Load factor too high, or our double hashing function is incorrect.");
+ 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"));
}
private void putEntry (bucket[] newBuckets, Object key, Object nvalue, int hashcode)
{
- Contract.Assert(hashcode >= 0, "hashcode >= 0"); // make sure collision bit (sign bit) wasn't set.
+ Debug.Assert(hashcode >= 0, "hashcode >= 0"); // make sure collision bit (sign bit) wasn't set.
uint seed = (uint) hashcode;
uint incr = (uint)(1 + ((seed * HashPrime) % ((uint)newBuckets.Length - 1)));
@@ -1058,7 +979,7 @@ namespace System.Collections {
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);
}
@@ -1069,10 +990,10 @@ namespace System.Collections {
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public virtual void Remove(Object key) {
if (key == null) {
- throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key"));
+ throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
}
Contract.EndContractBlock();
- Contract.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.");
+ 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.");
uint seed;
uint incr;
@@ -1086,9 +1007,6 @@ namespace System.Collections {
b = buckets[bn];
if (((b.hash_coll & 0x7FFFFFFF) == hashcode) &&
KeyEquals (b.key, key)) {
-#if !FEATURE_CORECLR
- Thread.BeginCriticalRegion();
-#endif
isWriterInProgress = true;
// Clear hash_coll field, then key, then value
buckets[bn].hash_coll &= unchecked((int)0x80000000);
@@ -1102,12 +1020,9 @@ namespace System.Collections {
count--;
UpdateVersion();
isWriterInProgress = false;
-#if !FEATURE_CORECLR
- Thread.EndCriticalRegion();
-#endif
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"));
@@ -1131,10 +1046,9 @@ namespace System.Collections {
// Returns a thread-safe wrapper for a Hashtable.
//
- [HostProtection(Synchronization=true)]
public static Hashtable Synchronized(Hashtable table) {
if (table==null)
- throw new ArgumentNullException("table");
+ throw new ArgumentNullException(nameof(table));
Contract.EndContractBlock();
return new SyncHashtable(table);
}
@@ -1143,10 +1057,9 @@ namespace System.Collections {
// The ISerializable Implementation
//
- [System.Security.SecurityCritical]
public virtual void GetObjectData(SerializationInfo info, StreamingContext context) {
if (info==null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
// This is imperfect - it only works well if all other writes are
@@ -1302,11 +1215,11 @@ namespace System.Collections {
public virtual void CopyTo(Array array, int arrayIndex) {
if (array==null)
- throw new ArgumentNullException("array");
+ throw new ArgumentNullException(nameof(array));
if (array.Rank != 1)
throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
if (arrayIndex < 0)
- throw new ArgumentOutOfRangeException("arrayIndex", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(arrayIndex), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
if (array.Length - arrayIndex < _hashtable.count)
throw new ArgumentException(Environment.GetResourceString("Arg_ArrayPlusOffTooSmall"));
@@ -1343,11 +1256,11 @@ namespace System.Collections {
public virtual void CopyTo(Array array, int arrayIndex) {
if (array==null)
- throw new ArgumentNullException("array");
+ throw new ArgumentNullException(nameof(array));
if (array.Rank != 1)
throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
if (arrayIndex < 0)
- throw new ArgumentOutOfRangeException("arrayIndex", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(arrayIndex), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
if (array.Length - arrayIndex < _hashtable.count)
throw new ArgumentException(Environment.GetResourceString("Arg_ArrayPlusOffTooSmall"));
@@ -1399,10 +1312,9 @@ namespace System.Collections {
** context -- the StreamingContext for the current serialization (ignored)
**Exceptions: ArgumentNullException if info is null.
==============================================================================*/
- [System.Security.SecurityCritical] // auto-generated
public override void GetObjectData(SerializationInfo info, StreamingContext context) {
if (info==null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
// Our serialization code hasn't been fully tweaked to be safe
@@ -1461,7 +1373,7 @@ namespace System.Collections {
public override bool ContainsKey(Object key) {
if (key == null) {
- throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key"));
+ throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
}
Contract.EndContractBlock();
return _table.ContainsKey(key);
@@ -1630,7 +1542,7 @@ namespace System.Collections {
public HashtableDebugView( Hashtable hashtable) {
if( hashtable == null) {
- throw new ArgumentNullException( "hashtable");
+ throw new ArgumentNullException(nameof(hashtable));
}
Contract.EndContractBlock();
@@ -1746,7 +1658,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)
{
- Contract.Assert( MaxPrimeArrayLength == GetPrime(MaxPrimeArrayLength), "Invalid MaxPrimeArrayLength");
+ Debug.Assert( MaxPrimeArrayLength == GetPrime(MaxPrimeArrayLength), "Invalid MaxPrimeArrayLength");
return MaxPrimeArrayLength;
}
@@ -1765,7 +1677,7 @@ namespace System.Collections {
public static IEqualityComparer GetRandomizedEqualityComparer(object comparer)
{
- Contract.Assert(comparer == null || comparer == System.Collections.Generic.EqualityComparer<string>.Default || comparer is IWellKnownStringEqualityComparer);
+ Debug.Assert(comparer == null || comparer == System.Collections.Generic.EqualityComparer<string>.Default || comparer is IWellKnownStringEqualityComparer);
if(comparer == null) {
return new System.Collections.Generic.RandomizedObjectEqualityComparer();
@@ -1781,7 +1693,7 @@ namespace System.Collections {
return cmp.GetRandomizedEqualityComparer();
}
- Contract.Assert(false, "Missing case in GetRandomizedEqualityComparer!");
+ Debug.Assert(false, "Missing case in GetRandomizedEqualityComparer!");
return null;
}
@@ -1804,9 +1716,6 @@ namespace System.Collections {
}
private const int bufferSize = 1024;
-#if !FEATURE_CORECLR
- private static RandomNumberGenerator rng;
-#endif
private static byte[] data;
private static int currentIndex = bufferSize;
private static readonly object lockObj = new Object();
@@ -1821,18 +1730,10 @@ namespace System.Collections {
if(data == null)
{
data = new byte[bufferSize];
- Contract.Assert(bufferSize % 8 == 0, "We increment our current index by 8, so our buffer size must be a multiple of 8");
-#if !FEATURE_CORECLR
- rng = RandomNumberGenerator.Create();
-#endif
-
+ Debug.Assert(bufferSize % 8 == 0, "We increment our current index by 8, so our buffer size must be a multiple of 8");
}
-#if FEATURE_CORECLR
Microsoft.Win32.Win32Native.Random(true, data, data.Length);
-#else
- rng.GetBytes(data);
-#endif
currentIndex = 0;
}
diff --git a/src/mscorlib/src/System/Collections/ListDictionaryInternal.cs b/src/mscorlib/src/System/Collections/ListDictionaryInternal.cs
index 944523c475..be5490b194 100644
--- a/src/mscorlib/src/System/Collections/ListDictionaryInternal.cs
+++ b/src/mscorlib/src/System/Collections/ListDictionaryInternal.cs
@@ -30,7 +30,7 @@ namespace System.Collections {
public Object this[Object key] {
get {
if (key == null) {
- throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key"));
+ throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
}
Contract.EndContractBlock();
DictionaryNode node = head;
@@ -45,16 +45,16 @@ namespace System.Collections {
}
set {
if (key == null) {
- throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key"));
+ throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
}
Contract.EndContractBlock();
#if FEATURE_SERIALIZATION
if (!key.GetType().IsSerializable)
- throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), "key");
+ throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), nameof(key));
if( (value != null) && (!value.GetType().IsSerializable ) )
- throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), "value");
+ throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), nameof(value));
#endif
version++;
@@ -132,16 +132,16 @@ namespace System.Collections {
public void Add(Object key, Object value) {
if (key == null) {
- throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key"));
+ throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
}
Contract.EndContractBlock();
#if FEATURE_SERIALIZATION
if (!key.GetType().IsSerializable)
- throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), "key" );
+ throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), nameof(key) );
if( (value != null) && (!value.GetType().IsSerializable) )
- throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), "value");
+ throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), nameof(value));
#endif
version++;
@@ -179,7 +179,7 @@ namespace System.Collections {
public bool Contains(Object key) {
if (key == null) {
- throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key"));
+ throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
}
Contract.EndContractBlock();
for (DictionaryNode node = head; node != null; node = node.next) {
@@ -192,16 +192,16 @@ namespace System.Collections {
public void CopyTo(Array array, int index) {
if (array==null)
- throw new ArgumentNullException("array");
+ throw new ArgumentNullException(nameof(array));
if (array.Rank != 1)
throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
if (index < 0)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if ( array.Length - index < this.Count )
- throw new ArgumentException( Environment.GetResourceString("ArgumentOutOfRange_Index"), "index");
+ throw new ArgumentException( Environment.GetResourceString("ArgumentOutOfRange_Index"), nameof(index));
Contract.EndContractBlock();
for (DictionaryNode node = head; node != null; node = node.next) {
@@ -220,7 +220,7 @@ namespace System.Collections {
public void Remove(Object key) {
if (key == null) {
- throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key"));
+ throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
}
Contract.EndContractBlock();
version++;
@@ -328,14 +328,14 @@ namespace System.Collections {
void ICollection.CopyTo(Array array, int index) {
if (array==null)
- throw new ArgumentNullException("array");
+ throw new ArgumentNullException(nameof(array));
if (array.Rank != 1)
throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
if (index < 0)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
if (array.Length - index < list.Count)
- throw new ArgumentException(Environment.GetResourceString("ArgumentOutOfRange_Index"), "index");
+ throw new ArgumentException(Environment.GetResourceString("ArgumentOutOfRange_Index"), nameof(index));
for (DictionaryNode node = list.head; node != null; node = node.next) {
array.SetValue(isKeys ? node.key : node.value, index);
index++;
diff --git a/src/mscorlib/src/System/Collections/ObjectModel/Collection.cs b/src/mscorlib/src/System/Collections/ObjectModel/Collection.cs
index 54aa7bb09d..a3804ad7ab 100644
--- a/src/mscorlib/src/System/Collections/ObjectModel/Collection.cs
+++ b/src/mscorlib/src/System/Collections/ObjectModel/Collection.cs
@@ -183,7 +183,7 @@ namespace System.Collections.ObjectModel
}
if (index < 0 ) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
if (array.Length - index < Count) {
@@ -204,7 +204,7 @@ namespace System.Collections.ObjectModel
Type targetType = array.GetType().GetElementType();
Type sourceType = typeof(T);
if(!(targetType.IsAssignableFrom(sourceType) || sourceType.IsAssignableFrom(targetType))) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
//
@@ -213,7 +213,7 @@ namespace System.Collections.ObjectModel
//
object[] objects = array as object[];
if( objects == null) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
int count = items.Count;
@@ -223,7 +223,7 @@ namespace System.Collections.ObjectModel
}
}
catch(ArrayTypeMismatchException) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
}
}
diff --git a/src/mscorlib/src/System/Collections/ObjectModel/KeyedCollection.cs b/src/mscorlib/src/System/Collections/ObjectModel/KeyedCollection.cs
index 7313d71950..b6fe6ded29 100644
--- a/src/mscorlib/src/System/Collections/ObjectModel/KeyedCollection.cs
+++ b/src/mscorlib/src/System/Collections/ObjectModel/KeyedCollection.cs
@@ -53,7 +53,7 @@ namespace System.Collections.ObjectModel
/// </summary>
new private List<TItem> Items {
get {
- Contract.Assert(base.Items is List<TItem>);
+ Debug.Assert(base.Items is List<TItem>);
return (List<TItem>)base.Items;
}
@@ -233,7 +233,7 @@ namespace System.Collections.ObjectModel
}
private void RemoveKey(TKey key) {
- Contract.Assert(key != null, "key shouldn't be null!");
+ Debug.Assert(key != null, "key shouldn't be null!");
if (dict != null) {
dict.Remove(key);
}
diff --git a/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyCollection.cs b/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyCollection.cs
index ec7149e4f5..a0b8b3b459 100644
--- a/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyCollection.cs
+++ b/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyCollection.cs
@@ -128,7 +128,7 @@ namespace System.Collections.ObjectModel
}
if (index < 0) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.arrayIndex, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
if (array.Length - index < Count) {
@@ -149,7 +149,7 @@ namespace System.Collections.ObjectModel
Type targetType = array.GetType().GetElementType();
Type sourceType = typeof(T);
if(!(targetType.IsAssignableFrom(sourceType) || sourceType.IsAssignableFrom(targetType))) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
//
@@ -158,7 +158,7 @@ namespace System.Collections.ObjectModel
//
object[] objects = array as object[];
if( objects == null) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
int count = list.Count;
@@ -168,7 +168,7 @@ namespace System.Collections.ObjectModel
}
}
catch(ArrayTypeMismatchException) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
}
}
diff --git a/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyDictionary.cs b/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyDictionary.cs
index 11833c2c1b..5c9e8c44c6 100644
--- a/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyDictionary.cs
+++ b/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyDictionary.cs
@@ -34,7 +34,7 @@ namespace System.Collections.ObjectModel
public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary) {
if (dictionary == null) {
- throw new ArgumentNullException("dictionary");
+ throw new ArgumentNullException(nameof(dictionary));
}
Contract.EndContractBlock();
m_dictionary = dictionary;
@@ -240,7 +240,7 @@ namespace System.Collections.ObjectModel
}
if (index < 0 || index > array.Length) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
if (array.Length - index < Count) {
@@ -261,7 +261,7 @@ namespace System.Collections.ObjectModel
else {
object[] objects = array as object[];
if (objects == null) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
try {
@@ -270,7 +270,7 @@ namespace System.Collections.ObjectModel
}
}
catch (ArrayTypeMismatchException) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
}
}
@@ -596,7 +596,7 @@ namespace System.Collections.ObjectModel
Type targetType = array.GetType().GetElementType();
Type sourceType = typeof(T);
if (!(targetType.IsAssignableFrom(sourceType) || sourceType.IsAssignableFrom(targetType))) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
//
@@ -605,7 +605,7 @@ namespace System.Collections.ObjectModel
//
object[] objects = array as object[];
if (objects == null) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
try {
@@ -614,7 +614,7 @@ namespace System.Collections.ObjectModel
}
}
catch (ArrayTypeMismatchException) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
+ ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
}
}
diff --git a/src/mscorlib/src/System/Collections/SortedList.cs b/src/mscorlib/src/System/Collections/SortedList.cs
index 8e3926af01..4a480a2c37 100644
--- a/src/mscorlib/src/System/Collections/SortedList.cs
+++ b/src/mscorlib/src/System/Collections/SortedList.cs
@@ -60,10 +60,8 @@ namespace System.Collections {
//
[DebuggerTypeProxy(typeof(System.Collections.SortedList.SortedListDebugView))]
[DebuggerDisplay("Count = {Count}")]
-[System.Runtime.InteropServices.ComVisible(true)]
-#if FEATURE_CORECLR
+ [System.Runtime.InteropServices.ComVisible(true)]
[Obsolete("Non-generic collections have been deprecated. Please use collections in System.Collections.Generic.")]
-#endif
[Serializable]
public class SortedList : IDictionary, ICloneable
{
@@ -107,7 +105,7 @@ namespace System.Collections {
//
public SortedList(int initialCapacity) {
if (initialCapacity < 0)
- throw new ArgumentOutOfRangeException("initialCapacity", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(initialCapacity), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
keys = new Object[initialCapacity];
values = new Object[initialCapacity];
@@ -164,7 +162,7 @@ namespace System.Collections {
public SortedList(IDictionary d, IComparer comparer)
: this(comparer, (d != null ? d.Count : 0)) {
if (d==null)
- throw new ArgumentNullException("d", Environment.GetResourceString("ArgumentNull_Dictionary"));
+ throw new ArgumentNullException(nameof(d), Environment.GetResourceString("ArgumentNull_Dictionary"));
Contract.EndContractBlock();
d.Keys.CopyTo(keys, 0);
d.Values.CopyTo(values, 0);
@@ -176,7 +174,7 @@ namespace System.Collections {
// ArgumentException is thrown if the key is already present in the sorted list.
//
public virtual void Add(Object key, Object value) {
- if (key == null) throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key"));
+ if (key == null) throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
Contract.EndContractBlock();
int i = Array.BinarySearch(keys, 0, _size, key, comparer);
if (i >= 0)
@@ -196,7 +194,7 @@ namespace System.Collections {
}
set {
if (value < Count) {
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
+ throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
}
Contract.EndContractBlock();
@@ -213,7 +211,7 @@ namespace System.Collections {
}
else {
// size can only be zero here.
- Contract.Assert( _size == 0, "Size is not zero");
+ Debug.Assert( _size == 0, "Size is not zero");
keys = emptyArray;
values = emptyArray;
}
@@ -325,11 +323,11 @@ namespace System.Collections {
// Copies the values in this SortedList to an array.
public virtual void CopyTo(Array array, int arrayIndex) {
if (array == null)
- throw new ArgumentNullException("array", Environment.GetResourceString("ArgumentNull_Array"));
+ throw new ArgumentNullException(nameof(array), Environment.GetResourceString("ArgumentNull_Array"));
if (array.Rank != 1)
throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
if (arrayIndex < 0)
- throw new ArgumentOutOfRangeException("arrayIndex", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(arrayIndex), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (array.Length - arrayIndex < Count)
throw new ArgumentException(Environment.GetResourceString("Arg_ArrayPlusOffTooSmall"));
Contract.EndContractBlock();
@@ -368,7 +366,7 @@ namespace System.Collections {
//
public virtual Object GetByIndex(int index) {
if (index < 0 || index >= Count)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
Contract.EndContractBlock();
return values[index];
}
@@ -394,7 +392,7 @@ namespace System.Collections {
// Returns the key of the entry at the given index.
//
public virtual Object GetKey(int index) {
- if (index < 0 || index >= Count) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ if (index < 0 || index >= Count) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
Contract.EndContractBlock();
return keys[index];
}
@@ -442,7 +440,7 @@ namespace System.Collections {
return null;
}
set {
- if (key == null) throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key"));
+ if (key == null) throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
Contract.EndContractBlock();
int i = Array.BinarySearch(keys, 0, _size, key, comparer);
if (i >= 0) {
@@ -463,7 +461,7 @@ namespace System.Collections {
//
public virtual int IndexOfKey(Object key) {
if (key == null)
- throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key"));
+ throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
Contract.EndContractBlock();
int ret = Array.BinarySearch(keys, 0, _size, key, comparer);
return ret >=0 ? ret : -1;
@@ -496,7 +494,7 @@ namespace System.Collections {
// decreased by one.
//
public virtual void RemoveAt(int index) {
- if (index < 0 || index >= Count) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ if (index < 0 || index >= Count) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
Contract.EndContractBlock();
_size--;
if (index < _size) {
@@ -522,7 +520,7 @@ namespace System.Collections {
// the given entry is overwritten.
//
public virtual void SetByIndex(int index, Object value) {
- if (index < 0 || index >= Count) throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ if (index < 0 || index >= Count) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
Contract.EndContractBlock();
values[index] = value;
version++;
@@ -530,10 +528,9 @@ namespace System.Collections {
// Returns a thread-safe SortedList.
//
- [HostProtection(Synchronization=true)]
public static SortedList Synchronized(SortedList list) {
if (list==null)
- throw new ArgumentNullException("list");
+ throw new ArgumentNullException(nameof(list));
Contract.EndContractBlock();
return new SyncSortedList(list);
}
@@ -677,7 +674,7 @@ namespace System.Collections {
public override int IndexOfKey(Object key) {
if (key == null)
- throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key"));
+ throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
Contract.EndContractBlock();
lock(_root) {
@@ -888,7 +885,7 @@ namespace System.Collections {
public virtual int IndexOf(Object key) {
if (key==null)
- throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key"));
+ throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
Contract.EndContractBlock();
int i = Array.BinarySearch(sortedList.keys, 0,
@@ -993,7 +990,7 @@ namespace System.Collections {
public SortedListDebugView( SortedList sortedList) {
if( sortedList == null) {
- throw new ArgumentNullException("sortedList");
+ throw new ArgumentNullException(nameof(sortedList));
}
Contract.EndContractBlock();
diff --git a/src/mscorlib/src/System/Collections/Stack.cs b/src/mscorlib/src/System/Collections/Stack.cs
index 0384a4ee81..c3ad15abd8 100644
--- a/src/mscorlib/src/System/Collections/Stack.cs
+++ b/src/mscorlib/src/System/Collections/Stack.cs
@@ -44,7 +44,7 @@ namespace System.Collections {
// must be a non-negative number.
public Stack(int initialCapacity) {
if (initialCapacity < 0)
- throw new ArgumentOutOfRangeException("initialCapacity", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(initialCapacity), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
if (initialCapacity < _defaultCapacity)
initialCapacity = _defaultCapacity; // Simplify doubling logic in Push.
@@ -59,7 +59,7 @@ namespace System.Collections {
public Stack(ICollection col) : this((col==null ? 32 : col.Count))
{
if (col==null)
- throw new ArgumentNullException("col");
+ throw new ArgumentNullException(nameof(col));
Contract.EndContractBlock();
IEnumerator en = col.GetEnumerator();
while(en.MoveNext())
@@ -121,11 +121,11 @@ namespace System.Collections {
// Copies the stack into an array.
public virtual void CopyTo(Array array, int index) {
if (array==null)
- throw new ArgumentNullException("array");
+ throw new ArgumentNullException(nameof(array));
if (array.Rank != 1)
throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
if (index < 0)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (array.Length - index < _size)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -189,10 +189,9 @@ namespace System.Collections {
// Returns a synchronized Stack.
//
- [HostProtection(Synchronization=true)]
public static Stack Synchronized(Stack stack) {
if (stack==null)
- throw new ArgumentNullException("stack");
+ throw new ArgumentNullException(nameof(stack));
Contract.Ensures(Contract.Result<Stack>() != null);
Contract.EndContractBlock();
return new SyncStack(stack);
@@ -363,7 +362,7 @@ namespace System.Collections {
public StackDebugView( Stack stack) {
if( stack == null)
- throw new ArgumentNullException("stack");
+ throw new ArgumentNullException(nameof(stack));
Contract.EndContractBlock();
this.stack = stack;
diff --git a/src/mscorlib/src/System/CompatibilitySwitches.cs b/src/mscorlib/src/System/CompatibilitySwitches.cs
index 7facf85df3..bb2f02a679 100644
--- a/src/mscorlib/src/System/CompatibilitySwitches.cs
+++ b/src/mscorlib/src/System/CompatibilitySwitches.cs
@@ -2,8 +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.
-
-using System.Runtime;
using System.Runtime.CompilerServices;
namespace System
@@ -12,16 +10,7 @@ namespace System
internal static class CompatibilitySwitches
{
private static bool s_AreSwitchesSet;
-
-#if FEATURE_CORECLR
private static bool s_useLatestBehaviorWhenTFMNotSpecified; // Which behavior to use when the TFM is not specified.
-#endif //FEATURE_CORECLR
-
-#if !FEATURE_CORECLR
- private static bool s_isNetFx40TimeSpanLegacyFormatMode;
- private static bool s_isNetFx40LegacySecurityPolicy;
- private static bool s_isNetFx45LegacyManagedDeflateStream;
-#endif //!FEATURE_CORECLR
public static bool IsCompatibilityBehaviorDefined
{
@@ -39,67 +28,14 @@ namespace System
internal static void InitializeSwitches()
{
-#if FEATURE_CORECLR
- s_useLatestBehaviorWhenTFMNotSpecified = IsCompatibilitySwitchSet("UseLatestBehaviorWhenTFMNotSpecified");
-#endif //FEATURE_CORECLR
-
-#if !FEATURE_CORECLR
- s_isNetFx40TimeSpanLegacyFormatMode = IsCompatibilitySwitchSet("NetFx40_TimeSpanLegacyFormatMode");
- s_isNetFx40LegacySecurityPolicy = IsCompatibilitySwitchSet("NetFx40_LegacySecurityPolicy");
- s_isNetFx45LegacyManagedDeflateStream = IsCompatibilitySwitchSet("NetFx45_LegacyManagedDeflateStream");
-#endif //FEATURE_CORECLR
-
s_AreSwitchesSet = true;
}
-#if FEATURE_CORECLR
- /// <summary>
- /// This property returns whether to give the latest behavior when the TFM is missing
- /// </summary>
- internal static bool UseLatestBehaviorWhenTFMNotSpecified
- {
- get
- {
- return s_useLatestBehaviorWhenTFMNotSpecified;
- }
- }
-#else //FEATURE_CORECLR
-
- public static bool IsAppEarlierThanSilverlight4
- {
- get
- {
- return false;
- }
- }
-
- public static bool IsAppEarlierThanWindowsPhone8
- {
- get
- {
- return false;
- }
- }
-
- public static bool IsAppEarlierThanWindowsPhoneMango
- {
- get
- {
- return false;
- }
- }
-
-#endif //FEATURE_CORECLR
-
public static bool IsNetFx40TimeSpanLegacyFormatMode
{
get
{
-#if !FEATURE_CORECLR
- return s_isNetFx40TimeSpanLegacyFormatMode;
-#else
return false;
-#endif //!FEATURE_CORECLR
}
}
@@ -107,11 +43,7 @@ namespace System
{
get
{
-#if !FEATURE_CORECLR
- return s_isNetFx40LegacySecurityPolicy;
-#else
return false;
-#endif //!FEATURE_CORECLR
}
}
@@ -119,11 +51,7 @@ namespace System
{
get
{
-#if !FEATURE_CORECLR
- return s_isNetFx45LegacyManagedDeflateStream;
-#else
return false;
-#endif //!FEATURE_CORECLR
}
}
}
diff --git a/src/mscorlib/src/System/ContextBoundObject.cs b/src/mscorlib/src/System/ContextBoundObject.cs
deleted file mode 100644
index 01929dabe3..0000000000
--- a/src/mscorlib/src/System/ContextBoundObject.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: Defines the root type for all context bound types
-**
-**
-===========================================================*/
-namespace System {
-
- using System;
- using System.Security.Permissions;
- [Serializable]
- [System.Runtime.InteropServices.ComVisible(true)]
-#if FEATURE_REMOTING
- public abstract class ContextBoundObject : MarshalByRefObject {
-#else // FEATURE_REMOTING
- public abstract class ContextBoundObject {
-#endif // FEATURE_REMOTING
- }
-}
diff --git a/src/mscorlib/src/System/ContextStaticAttribute.cs b/src/mscorlib/src/System/ContextStaticAttribute.cs
deleted file mode 100644
index b875aa33f5..0000000000
--- a/src/mscorlib/src/System/ContextStaticAttribute.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.
-
-/*============================================================
-**
-**
-**
-**
-** Purpose: Custom attribute to indicate that the field should be treated
-** as a static relative to a context.
-**
-**
-**
-===========================================================*/
-namespace System {
-
- using System;
- using System.Runtime.Remoting;
-[Serializable]
- [AttributeUsage(AttributeTargets.Field, Inherited = false)]
- [System.Runtime.InteropServices.ComVisible(true)]
-#if FEATURE_CORECLR
- [Obsolete("ContextStaticAttribute is not supported in this release. It has been left in so that legacy tools can be used with this release, but it cannot be used in your code.", true)]
-#endif // FEATURE_CORECLR
- public class ContextStaticAttribute : Attribute
- {
- public ContextStaticAttribute()
- {
- }
- }
-}
diff --git a/src/mscorlib/src/System/Convert.cs b/src/mscorlib/src/System/Convert.cs
index d1468314f2..0e14f93fee 100644
--- a/src/mscorlib/src/System/Convert.cs
+++ b/src/mscorlib/src/System/Convert.cs
@@ -19,6 +19,7 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
@@ -146,13 +147,13 @@ namespace System {
#if _DEBUG
private static bool TriggerAsserts = DoAsserts();
private static bool DoAsserts() {
- Contract.Assert(ConvertTypes!=null, "[Convert.cctor]ConvertTypes!=null");
- Contract.Assert(ConvertTypes.Length == ((int)TypeCode.String + 1), "[Convert.cctor]ConvertTypes.Length == ((int)TypeCode.String + 1)");
- Contract.Assert(ConvertTypes[(int)TypeCode.Empty]==typeof(System.Empty),
+ 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)");
- Contract.Assert(ConvertTypes[(int)TypeCode.String]==typeof(String),
+ Debug.Assert(ConvertTypes[(int)TypeCode.String]==typeof(String),
"[Convert.cctor]ConvertTypes[(int)TypeCode.String]==typeof(System.String)");
- Contract.Assert(ConvertTypes[(int)TypeCode.Int32]==typeof(int),
+ Debug.Assert(ConvertTypes[(int)TypeCode.Int32]==typeof(int),
"[Convert.cctor]ConvertTypes[(int)TypeCode.Int32]==typeof(int)");
return true;
}
@@ -259,7 +260,7 @@ namespace System {
internal static Object DefaultToType(IConvertible value, Type targetType, IFormatProvider provider) {
Contract.Requires(value != null, "[Convert.DefaultToType]value!=null");
if (targetType==null) {
- throw new ArgumentNullException("targetType");
+ throw new ArgumentNullException(nameof(targetType));
}
Contract.EndContractBlock();
@@ -322,7 +323,7 @@ namespace System {
public static Object ChangeType(Object value, Type conversionType, IFormatProvider provider) {
if( conversionType == null) {
- throw new ArgumentNullException("conversionType");
+ throw new ArgumentNullException(nameof(conversionType));
}
Contract.EndContractBlock();
@@ -575,7 +576,7 @@ namespace System {
public static char ToChar(String value, IFormatProvider provider) {
if (value == null)
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
Contract.EndContractBlock();
if (value.Length != 1)
@@ -1129,7 +1130,6 @@ namespace System {
throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static int ToInt32(decimal value) {
return Decimal.FCallToInt32(value);
}
@@ -2114,7 +2114,6 @@ namespace System {
}
// Convert the byte value to a string in base fromBase
- [System.Security.SecuritySafeCritical] // auto-generated
public static String ToString (byte value, int toBase) {
if (toBase!=2 && toBase!=8 && toBase!=10 && toBase!=16) {
throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
@@ -2124,7 +2123,6 @@ namespace System {
}
// Convert the Int16 value to a string in base fromBase
- [System.Security.SecuritySafeCritical] // auto-generated
public static String ToString (short value, int toBase) {
if (toBase!=2 && toBase!=8 && toBase!=10 && toBase!=16) {
throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
@@ -2134,7 +2132,6 @@ namespace System {
}
// Convert the Int32 value to a string in base toBase
- [System.Security.SecuritySafeCritical] // auto-generated
public static String ToString (int value, int toBase) {
if (toBase!=2 && toBase!=8 && toBase!=10 && toBase!=16) {
throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
@@ -2144,7 +2141,6 @@ namespace System {
}
// Convert the Int64 value to a string in base toBase
- [System.Security.SecuritySafeCritical] // auto-generated
public static String ToString (long value, int toBase) {
if (toBase!=2 && toBase!=8 && toBase!=10 && toBase!=16) {
throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
@@ -2155,7 +2151,7 @@ namespace System {
public static String ToBase64String(byte[] inArray) {
if (inArray==null) {
- throw new ArgumentNullException("inArray");
+ throw new ArgumentNullException(nameof(inArray));
}
Contract.Ensures(Contract.Result<string>() != null);
Contract.EndContractBlock();
@@ -2165,7 +2161,7 @@ namespace System {
[System.Runtime.InteropServices.ComVisible(false)]
public static String ToBase64String(byte[] inArray, Base64FormattingOptions options) {
if (inArray==null) {
- throw new ArgumentNullException("inArray");
+ throw new ArgumentNullException(nameof(inArray));
}
Contract.Ensures(Contract.Result<string>() != null);
Contract.EndContractBlock();
@@ -2176,16 +2172,15 @@ namespace System {
return ToBase64String(inArray, offset, length, Base64FormattingOptions.None);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(false)]
public static unsafe String ToBase64String(byte[] inArray, int offset, int length, Base64FormattingOptions options) {
//Do data verfication
if (inArray==null)
- throw new ArgumentNullException("inArray");
+ throw new ArgumentNullException(nameof(inArray));
if (length<0)
- throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_Index"));
if (offset<0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
+ 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);
@@ -2196,7 +2191,7 @@ namespace System {
inArrayLength = inArray.Length;
if (offset > (inArrayLength - length))
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_OffsetLength"));
+ throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_OffsetLength"));
if (inArrayLength == 0)
return String.Empty;
@@ -2223,20 +2218,19 @@ namespace System {
return ToBase64CharArray(inArray, offsetIn, length, outArray, offsetOut, Base64FormattingOptions.None);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(false)]
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("inArray");
+ throw new ArgumentNullException(nameof(inArray));
if (outArray==null)
- throw new ArgumentNullException("outArray");
+ throw new ArgumentNullException(nameof(outArray));
if (length<0)
- throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_Index"));
if (offsetIn<0)
- throw new ArgumentOutOfRangeException("offsetIn", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
+ throw new ArgumentOutOfRangeException(nameof(offsetIn), Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
if (offsetOut<0)
- throw new ArgumentOutOfRangeException("offsetOut", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
+ 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));
@@ -2255,7 +2249,7 @@ namespace System {
inArrayLength = inArray.Length;
if (offsetIn > (int)(inArrayLength - length))
- throw new ArgumentOutOfRangeException("offsetIn", Environment.GetResourceString("ArgumentOutOfRange_OffsetLength"));
+ throw new ArgumentOutOfRangeException(nameof(offsetIn), Environment.GetResourceString("ArgumentOutOfRange_OffsetLength"));
if (inArrayLength == 0)
return 0;
@@ -2268,7 +2262,7 @@ namespace System {
numElementsToCopy = ToBase64_CalculateAndValidateOutputLength(length, insertLineBreaks);
if (offsetOut > (int)(outArrayLength - numElementsToCopy))
- throw new ArgumentOutOfRangeException("offsetOut", Environment.GetResourceString("ArgumentOutOfRange_OffsetOut"));
+ throw new ArgumentOutOfRangeException(nameof(offsetOut), Environment.GetResourceString("ArgumentOutOfRange_OffsetOut"));
fixed (char* outChars = &outArray[offsetOut]) {
fixed (byte* inData = inArray) {
@@ -2279,7 +2273,6 @@ namespace System {
return retVal;
}
- [System.Security.SecurityCritical] // auto-generated
private static unsafe int ConvertToBase64Array(char* outChars, byte* inData, int offset, int length, bool insertLineBreaks) {
int lengthmod3 = length%3;
int calcLength = offset + (length - lengthmod3);
@@ -2366,13 +2359,12 @@ namespace System {
/// </summary>
/// <param name="s">The string to convert</param>
/// <returns>The array of bytes represented by the specifed Base64 string.</returns>
- [SecuritySafeCritical]
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("s");
+ throw new ArgumentNullException(nameof(s));
Contract.EndContractBlock();
@@ -2392,20 +2384,19 @@ namespace System {
/// <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>
- [SecuritySafeCritical]
public static Byte[] FromBase64CharArray(Char[] inArray, Int32 offset, Int32 length) {
if (inArray == null)
- throw new ArgumentNullException("inArray");
+ throw new ArgumentNullException(nameof(inArray));
if (length < 0)
- throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_Index"));
if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
+ throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
if (offset > inArray.Length - length)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_OffsetLength"));
+ throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_OffsetLength"));
Contract.EndContractBlock();
@@ -2428,12 +2419,11 @@ namespace System {
/// <param name="inputPtr">Pointer to the first input char</param>
/// <param name="inputLength">Number of input chars</param>
/// <returns></returns>
- [SecurityCritical]
private static unsafe Byte[] FromBase64CharPtr(Char* inputPtr, Int32 inputLength) {
// The validity of parameters much be checked by callers, thus we are Critical here.
- Contract.Assert(0 <= inputLength);
+ Debug.Assert(0 <= inputLength);
// We need to get rid of any trailing white spaces.
// Otherwise we would be rejecting input such as "abc= ":
@@ -2448,7 +2438,7 @@ namespace System {
// Compute the output length:
Int32 resultLength = FromBase64_ComputeResultLength(inputPtr, inputLength);
- Contract.Assert(0 <= resultLength);
+ 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").
@@ -2482,7 +2472,6 @@ namespace System {
/// <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>
- [SecurityCritical]
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.
@@ -2583,12 +2572,12 @@ namespace System {
}} // unchecked while
// 'd be nice to have an assert that we never get here, but CS0162: Unreachable code detected.
- // Contract.Assert(false, "We only leave the above loop by jumping; should never get here.");
+ // 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:
- Contract.Assert(currCode == intEq);
+ Debug.Assert(currCode == intEq);
// Recall that inputPtr is now one position past where '=' was read.
// '=' can only be at the last input pos:
@@ -2662,13 +2651,12 @@ namespace System {
/// Walk the entire input counting white spaces and padding chars, then compute result length
/// based on 3 bytes per 4 chars.
/// </summary>
- [SecurityCritical]
private static unsafe Int32 FromBase64_ComputeResultLength(Char* inputPtr, Int32 inputLength) {
const UInt32 intEq = (UInt32) '=';
const UInt32 intSpace = (UInt32) ' ';
- Contract.Assert(0 <= inputLength);
+ Debug.Assert(0 <= inputLength);
Char* inputEndPtr = inputPtr + inputLength;
Int32 usefulInputLength = inputLength;
@@ -2691,11 +2679,11 @@ namespace System {
}
}
- Contract.Assert(0 <= usefulInputLength);
+ 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.
- Contract.Assert(0 <= padding);
+ 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 '=':
diff --git a/src/mscorlib/src/System/Currency.cs b/src/mscorlib/src/System/Currency.cs
index d29ad2452c..05a09802cd 100644
--- a/src/mscorlib/src/System/Currency.cs
+++ b/src/mscorlib/src/System/Currency.cs
@@ -46,7 +46,6 @@ namespace System {
// Converts a Currency to a Decimal.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public static Decimal ToDecimal(Currency c)
{
Decimal result = new Decimal ();
@@ -54,7 +53,6 @@ namespace System {
return result;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void FCallToDecimal(ref Decimal result,Currency c);
}
diff --git a/src/mscorlib/src/System/CurrentTimeZone.cs b/src/mscorlib/src/System/CurrentTimeZone.cs
index f015c05b33..804bbcccc4 100644
--- a/src/mscorlib/src/System/CurrentTimeZone.cs
+++ b/src/mscorlib/src/System/CurrentTimeZone.cs
@@ -21,36 +21,18 @@ namespace System {
using System;
using System.Diagnostics.Contracts;
using System.Text;
- using System.Threading;
using System.Collections;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
- //
- // Currently, this is the only supported timezone.
- // The values of the timezone is from the current system timezone setting in the
- // control panel.
- //
-#if FEATURE_CORECLR
[Obsolete("System.CurrentSystemTimeZone has been deprecated. Please investigate the use of System.TimeZoneInfo.Local instead.")]
-#endif
[Serializable]
- internal class CurrentSystemTimeZone : TimeZone {
- // <BUGBUG>BUGBUG :
- // One problem is when user changes the current timezone. We
- // are not able to update currentStandardName/currentDaylightName/
- // currentDaylightChanges.
- // We need WM_TIMECHANGE to do this or use
- // RegNotifyChangeKeyValue() to monitor </BUGBUG>
- //
- private const long TicksPerMillisecond = 10000;
- private const long TicksPerSecond = TicksPerMillisecond * 1000;
- private const long TicksPerMinute = TicksPerSecond * 60;
-
+ 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 Hashtable m_CachedDaylightChanges = new Hashtable();
+ private readonly Hashtable m_CachedDaylightChanges = new Hashtable();
// Standard offset in ticks to the Universal time if
// no daylight saving is in used.
@@ -60,43 +42,40 @@ namespace System {
private String m_standardName;
private String m_daylightName;
- [System.Security.SecuritySafeCritical] // auto-generated
- internal CurrentSystemTimeZone() {
- m_ticksOffset = nativeGetTimeZoneMinuteOffset() * TicksPerMinute;
- m_standardName = null;
- m_daylightName = null;
+ internal CurrentSystemTimeZone()
+ {
+ TimeZoneInfo local = TimeZoneInfo.Local;
+
+ m_ticksOffset = local.BaseUtcOffset.Ticks;
+ m_standardName = local.StandardName;
+ m_daylightName = local.DaylightName;
}
- public override String StandardName {
- [System.Security.SecuritySafeCritical] // auto-generated
- get {
- if (m_standardName == null) {
- m_standardName = nativeGetStandardName();
- }
- return (m_standardName);
+ public override String StandardName
+ {
+ get
+ {
+ return m_standardName;
}
}
- public override String DaylightName {
- [System.Security.SecuritySafeCritical] // auto-generated
- get {
- if (m_daylightName == null) {
- m_daylightName = nativeGetDaylightName();
- if (m_daylightName == null) {
- m_daylightName = this.StandardName;
- }
- }
- return (m_daylightName);
+ public override String DaylightName
+ {
+ get
+ {
+ return m_daylightName;
}
}
- internal long GetUtcOffsetFromUniversalTime(DateTime time, ref Boolean isAmbiguousLocalDst) {
+ 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) {
+ if (daylightTime == null || daylightTime.Delta.Ticks == 0)
+ {
return offset.Ticks;
}
@@ -107,119 +86,109 @@ namespace System {
DateTime endTime = daylightTime.End - offset - daylightTime.Delta;
DateTime ambiguousStart;
DateTime ambiguousEnd;
- if (daylightTime.Delta.Ticks > 0) {
+
+ if (daylightTime.Delta.Ticks > 0)
+ {
ambiguousStart = endTime - daylightTime.Delta;
ambiguousEnd = endTime;
- } else {
+ }
+ else
+ {
ambiguousStart = startTime;
ambiguousEnd = startTime - daylightTime.Delta;
}
Boolean isDst = false;
- if (startTime > endTime) {
+ 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 {
+ else
+ {
// In northern hemisphere, the daylight saving time starts in the middle of the year.
- isDst = (time>=startTime && time<endTime);
+ isDst = (time >= startTime && time < endTime);
}
- if (isDst) {
+
+ 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 ) {
+ if (time >= ambiguousStart && time < ambiguousEnd )
+ {
isAmbiguousLocalDst = true;
}
}
return offset.Ticks;
}
- public override DateTime ToLocalTime(DateTime time) {
- if (time.Kind == DateTimeKind.Local) {
+ 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) {
+ if (tick > DateTime.MaxTicks)
+ {
return new DateTime(DateTime.MaxTicks, DateTimeKind.Local);
}
- if (tick<DateTime.MinTicks) {
+ if (tick < DateTime.MinTicks)
+ {
return new DateTime(DateTime.MinTicks, DateTimeKind.Local);
}
- return new DateTime(tick, DateTimeKind.Local, isAmbiguousLocalDst);
- }
-
- // 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;
- }
+ return new DateTime(tick, DateTimeKind.Local, isAmbiguousLocalDst);
}
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override DaylightTime GetDaylightChanges(int year) {
- if (year < 1 || year > 9999) {
- throw new ArgumentOutOfRangeException("year", Environment.GetResourceString("ArgumentOutOfRange_Range", 1, 9999));
+ 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)) {
- lock (InternalSyncObject) {
+ Object objYear = (Object) year;
- if (!m_CachedDaylightChanges.Contains(objYear)) {
+ if (!m_CachedDaylightChanges.Contains(objYear))
+ {
+ DaylightTime currentDaylightChanges = null;
- //
- // rawData is an array of 17 short (16 bit) numbers.
- // The first 8 numbers contains the
- // year/month/day/dayOfWeek/hour/minute/second/millisecond for the starting time of daylight saving time.
- // The next 8 numbers contains the
- // year/month/day/dayOfWeek/hour/minute/second/millisecond for the ending time of daylight saving time.
- // The last short number is the delta to the standard offset in minutes.
- //
- short[] rawData = nativeGetDaylightChanges(year);
+ if (TimeZoneInfo.Local.SupportsDaylightSavingTime)
+ {
+ DateTime start;
+ DateTime end;
+ TimeSpan delta;
- if (rawData == null) {
- //
- // If rawData is null, it means that daylight saving time is not used
- // in this timezone. So keep currentDaylightChanges as the empty array.
- //
- m_CachedDaylightChanges.Add(objYear, new DaylightTime(DateTime.MinValue, DateTime.MinValue, TimeSpan.Zero));
- } else {
- 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;
- //
- // Store the start of daylight saving time.
- //
-
- start = GetDayOfWeek(year, (rawData[0] != 0), rawData[1], rawData[2],
- rawData[3],
- rawData[4], rawData[5], rawData[6], rawData[7]);
+ currentDaylightChanges = new DaylightTime(start, end, delta);
+ break;
+ }
+ }
+ }
- //
- // Store the end of daylight saving time.
- //
- end = GetDayOfWeek(year, (rawData[8] != 0), rawData[9], rawData[10],
- rawData[11],
- rawData[12], rawData[13], rawData[14], rawData[15]);
+ if (currentDaylightChanges == null)
+ {
+ currentDaylightChanges = new DaylightTime(DateTime.MinValue, DateTime.MinValue, TimeSpan.Zero);
+ }
- delta = new TimeSpan(rawData[16] * TicksPerMinute);
- DaylightTime currentDaylightChanges = new DaylightTime(start, end, delta);
- m_CachedDaylightChanges.Add(objYear, currentDaylightChanges);
- }
+ lock (m_CachedDaylightChanges)
+ {
+ if (!m_CachedDaylightChanges.Contains(objYear))
+ {
+ m_CachedDaylightChanges.Add(objYear, currentDaylightChanges);
}
}
}
@@ -229,82 +198,17 @@ namespace System {
return result;
}
- public override TimeSpan GetUtcOffset(DateTime time) {
- if (time.Kind == DateTimeKind.Utc) {
+ public override TimeSpan GetUtcOffset(DateTime time)
+ {
+ if (time.Kind == DateTimeKind.Utc)
+ {
return TimeSpan.Zero;
}
- else {
+ else
+ {
return new TimeSpan(TimeZone.CalculateUtcOffset(time, GetDaylightChanges(time.Year)).Ticks + m_ticksOffset);
}
}
- //
- // Return the (numberOfSunday)th day of week in a particular year/month.
- //
- private static DateTime GetDayOfWeek(int year, bool fixedDate, int month, int targetDayOfWeek, int numberOfSunday, int hour, int minute, int second, int millisecond) {
- DateTime time;
-
- if (fixedDate) {
- //
- // Create a Fixed-Date transition time based on the supplied parameters
- // For Fixed-Dated transition times, the 'numberOfSunday' parameter actually
- // represents the day of the month.
- //
-
- // if the day is out of range for the month then use the last day of the month
- int day = DateTime.DaysInMonth(year, month);
-
- time = new DateTime(year, month, (day < numberOfSunday) ? day : numberOfSunday,
- hour, minute, second, millisecond, DateTimeKind.Local);
- }
- else if (numberOfSunday <= 4) {
- //
- // Get the (numberOfSunday)th Sunday.
- //
-
- time = new DateTime(year, month, 1, hour, minute, second, millisecond, DateTimeKind.Local);
-
- int dayOfWeek = (int)time.DayOfWeek;
- int delta = targetDayOfWeek - dayOfWeek;
- if (delta < 0) {
- delta += 7;
- }
- delta += 7 * (numberOfSunday - 1);
-
- if (delta > 0) {
- time = time.AddDays(delta);
- }
- } else {
- //
- // If numberOfSunday is greater than 4, we will get the last sunday.
- //
- Calendar cal = GregorianCalendar.GetDefaultInstance();
- time = new DateTime(year, month, cal.GetDaysInMonth(year, month), hour, minute, second, millisecond, DateTimeKind.Local);
- // This is the day of week for the last day of the month.
- int dayOfWeek = (int)time.DayOfWeek;
- int delta = dayOfWeek - targetDayOfWeek;
- if (delta < 0) {
- delta += 7;
- }
-
- if (delta > 0) {
- time = time.AddDays(-delta);
- }
- }
- return (time);
- }
-
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal extern static int nativeGetTimeZoneMinuteOffset();
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal extern static String nativeGetDaylightName();
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal extern static String nativeGetStandardName();
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal extern static short[] nativeGetDaylightChanges(int year);
} // class CurrentSystemTimeZone
}
diff --git a/src/mscorlib/src/System/DBNull.cs b/src/mscorlib/src/System/DBNull.cs
index 130366d86d..6f80af7e21 100644
--- a/src/mscorlib/src/System/DBNull.cs
+++ b/src/mscorlib/src/System/DBNull.cs
@@ -26,7 +26,6 @@ namespace System {
public static readonly DBNull Value = new DBNull();
- [System.Security.SecurityCritical]
public void GetObjectData(SerializationInfo info, StreamingContext context) {
UnitySerializationHolder.GetUnitySerializationInfo(info, UnitySerializationHolder.NullUnity, null, null);
}
diff --git a/src/mscorlib/src/System/DateTime.cs b/src/mscorlib/src/System/DateTime.cs
index c464549333..e93346c42f 100644
--- a/src/mscorlib/src/System/DateTime.cs
+++ b/src/mscorlib/src/System/DateTime.cs
@@ -143,7 +143,7 @@ namespace System {
//
public DateTime(long ticks) {
if (ticks < MinTicks || ticks > MaxTicks)
- throw new ArgumentOutOfRangeException("ticks", Environment.GetResourceString("ArgumentOutOfRange_DateTimeBadTicks"));
+ throw new ArgumentOutOfRangeException(nameof(ticks), Environment.GetResourceString("ArgumentOutOfRange_DateTimeBadTicks"));
Contract.EndContractBlock();
dateData = (UInt64)ticks;
}
@@ -154,10 +154,10 @@ namespace System {
public DateTime(long ticks, DateTimeKind kind) {
if (ticks < MinTicks || ticks > MaxTicks) {
- throw new ArgumentOutOfRangeException("ticks", Environment.GetResourceString("ArgumentOutOfRange_DateTimeBadTicks"));
+ throw new ArgumentOutOfRangeException(nameof(ticks), Environment.GetResourceString("ArgumentOutOfRange_DateTimeBadTicks"));
}
if (kind < DateTimeKind.Unspecified || kind > DateTimeKind.Local) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidDateTimeKind"), "kind");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidDateTimeKind"), nameof(kind));
}
Contract.EndContractBlock();
this.dateData = ((UInt64)ticks | ((UInt64)kind << KindShift));
@@ -165,7 +165,7 @@ namespace System {
internal DateTime(long ticks, DateTimeKind kind, Boolean isAmbiguousDst) {
if (ticks < MinTicks || ticks > MaxTicks) {
- throw new ArgumentOutOfRangeException("ticks", Environment.GetResourceString("ArgumentOutOfRange_DateTimeBadTicks"));
+ throw new ArgumentOutOfRangeException(nameof(ticks), Environment.GetResourceString("ArgumentOutOfRange_DateTimeBadTicks"));
}
Contract.Requires(kind == DateTimeKind.Local, "Internal Constructor is for local times only");
Contract.EndContractBlock();
@@ -196,7 +196,7 @@ namespace System {
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"), "kind");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidDateTimeKind"), nameof(kind));
}
Contract.EndContractBlock();
Int64 ticks = DateToTicks(year, month, day) + TimeToTicks(hour, minute, second);
@@ -208,7 +208,7 @@ namespace System {
//
public DateTime(int year, int month, int day, int hour, int minute, int second, Calendar calendar) {
if (calendar == null)
- throw new ArgumentNullException("calendar");
+ throw new ArgumentNullException(nameof(calendar));
Contract.EndContractBlock();
this.dateData = (UInt64)calendar.ToDateTime(year, month, day, hour, minute, second, 0).Ticks;
}
@@ -218,7 +218,7 @@ namespace System {
//
public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond) {
if (millisecond < 0 || millisecond >= MillisPerSecond) {
- throw new ArgumentOutOfRangeException("millisecond", Environment.GetResourceString("ArgumentOutOfRange_Range", 0, MillisPerSecond - 1));
+ throw new ArgumentOutOfRangeException(nameof(millisecond), Environment.GetResourceString("ArgumentOutOfRange_Range", 0, MillisPerSecond - 1));
}
Contract.EndContractBlock();
Int64 ticks = DateToTicks(year, month, day) + TimeToTicks(hour, minute, second);
@@ -230,10 +230,10 @@ namespace System {
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("millisecond", Environment.GetResourceString("ArgumentOutOfRange_Range", 0, MillisPerSecond - 1));
+ 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"), "kind");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidDateTimeKind"), nameof(kind));
}
Contract.EndContractBlock();
Int64 ticks = DateToTicks(year, month, day) + TimeToTicks(hour, minute, second);
@@ -248,9 +248,9 @@ namespace System {
//
public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, Calendar calendar) {
if (calendar == null)
- throw new ArgumentNullException("calendar");
+ throw new ArgumentNullException(nameof(calendar));
if (millisecond < 0 || millisecond >= MillisPerSecond) {
- throw new ArgumentOutOfRangeException("millisecond", Environment.GetResourceString("ArgumentOutOfRange_Range", 0, MillisPerSecond - 1));
+ 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;
@@ -262,12 +262,12 @@ namespace System {
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("calendar");
+ throw new ArgumentNullException(nameof(calendar));
if (millisecond < 0 || millisecond >= MillisPerSecond) {
- throw new ArgumentOutOfRangeException("millisecond", Environment.GetResourceString("ArgumentOutOfRange_Range", 0, MillisPerSecond - 1));
+ 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"), "kind");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidDateTimeKind"), nameof(kind));
}
Contract.EndContractBlock();
Int64 ticks = calendar.ToDateTime(year, month, day, hour, minute, second, 0).Ticks;
@@ -279,7 +279,7 @@ namespace System {
private DateTime(SerializationInfo info, StreamingContext context) {
if (info==null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
Boolean foundTicks = false;
@@ -346,7 +346,7 @@ namespace System {
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("value", Environment.GetResourceString("ArgumentOutOfRange_AddValue"));
+ throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_AddValue"));
return AddTicks(millis * TicksPerMillisecond);
}
@@ -408,7 +408,7 @@ namespace System {
// y1.
//
public DateTime AddMonths(int months) {
- if (months < -120000 || months > 120000) throw new ArgumentOutOfRangeException("months", Environment.GetResourceString("ArgumentOutOfRange_DateTimeBadMonths"));
+ if (months < -120000 || months > 120000) throw new ArgumentOutOfRangeException(nameof(months), Environment.GetResourceString("ArgumentOutOfRange_DateTimeBadMonths"));
Contract.EndContractBlock();
int y = GetDatePart(DatePartYear);
int m = GetDatePart(DatePartMonth);
@@ -423,7 +423,7 @@ namespace System {
y = y + (i - 11) / 12;
}
if (y < 1 || y > 9999) {
- throw new ArgumentOutOfRangeException("months", Environment.GetResourceString("ArgumentOutOfRange_DateArithmetic"));
+ throw new ArgumentOutOfRangeException(nameof(months), Environment.GetResourceString("ArgumentOutOfRange_DateArithmetic"));
}
int days = DaysInMonth(y, m);
if (d > days) d = days;
@@ -447,7 +447,7 @@ namespace System {
public DateTime AddTicks(long value) {
long ticks = InternalTicks;
if (value > MaxTicks - ticks || value < MinTicks - ticks) {
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_DateArithmetic"));
+ throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_DateArithmetic"));
}
return new DateTime((UInt64)(ticks + value) | InternalKind);
}
@@ -527,7 +527,7 @@ namespace System {
// month arguments.
//
public static int DaysInMonth(int year, int month) {
- if (month < 1 || month > 12) throw new ArgumentOutOfRangeException("month", Environment.GetResourceString("ArgumentOutOfRange_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;
@@ -556,20 +556,6 @@ namespace System {
return millis * TicksPerMillisecond;
}
-#if !FEATURE_CORECLR
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SecurityCritical]
- [SuppressUnmanagedCodeSecurity]
- [return: MarshalAs(UnmanagedType.Bool)]
- internal static extern bool LegacyParseMode();
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SecurityCritical]
- [SuppressUnmanagedCodeSecurity]
- [return: MarshalAs(UnmanagedType.Bool)]
- internal static extern bool EnableAmPmParseAdjustment();
-#endif
-
// 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
@@ -629,7 +615,7 @@ namespace System {
ticks += TicksPerDay;
}
if (ticks < MinTicks || ticks > MaxTicks) {
- throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeBadBinaryData"), "dateData");
+ throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeBadBinaryData"), nameof(dateData));
}
return new DateTime(ticks, DateTimeKind.Local, isAmbiguousLocalDst);
}
@@ -643,7 +629,7 @@ namespace System {
internal static DateTime FromBinaryRaw(Int64 dateData) {
Int64 ticks = dateData & (Int64)TicksMask;
if (ticks < MinTicks || ticks > MaxTicks)
- throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeBadBinaryData"), "dateData");
+ throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeBadBinaryData"), nameof(dateData));
return new DateTime((UInt64)dateData);
}
@@ -657,7 +643,7 @@ namespace System {
public static DateTime FromFileTimeUtc(long fileTime) {
if (fileTime < 0 || fileTime > MaxTicks - FileTimeOffset) {
- throw new ArgumentOutOfRangeException("fileTime", Environment.GetResourceString("ArgumentOutOfRange_FileTimeInvalid"));
+ throw new ArgumentOutOfRangeException(nameof(fileTime), Environment.GetResourceString("ArgumentOutOfRange_FileTimeInvalid"));
}
Contract.EndContractBlock();
@@ -675,7 +661,7 @@ namespace System {
[System.Security.SecurityCritical /*auto-generated_required*/]
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) {
if (info==null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
@@ -775,7 +761,7 @@ namespace System {
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;
+ int m = (n >> 5) + 1;
// m = 1-based month number
while (n >= days[m]) m++;
// If month was requested, return it
@@ -912,7 +898,6 @@ namespace System {
}
public static DateTime UtcNow {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
Contract.Ensures(Contract.Result<DateTime>().Kind == DateTimeKind.Utc);
// following code is tuned for speed. Don't change it without running benchmark.
@@ -924,7 +909,6 @@ namespace System {
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern long GetSystemTimeAsFileTime();
@@ -985,7 +969,7 @@ namespace System {
//
public static bool IsLeapYear(int year) {
if (year < 1 || year > 9999) {
- throw new ArgumentOutOfRangeException("year", Environment.GetResourceString("ArgumentOutOfRange_Year"));
+ throw new ArgumentOutOfRangeException(nameof(year), Environment.GetResourceString("ArgumentOutOfRange_Year"));
}
Contract.EndContractBlock();
return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
@@ -1008,7 +992,7 @@ namespace System {
}
public static DateTime Parse(String s, IFormatProvider provider, DateTimeStyles styles) {
- DateTimeFormatInfo.ValidateStyles(styles, "styles");
+ DateTimeFormatInfo.ValidateStyles(styles, nameof(styles));
return (DateTimeParse.Parse(s, DateTimeFormatInfo.GetInstance(provider), styles));
}
@@ -1025,12 +1009,12 @@ namespace System {
// Leading and trailing whitespace characters are allowed.
//
public static DateTime ParseExact(String s, String format, IFormatProvider provider, DateTimeStyles style) {
- DateTimeFormatInfo.ValidateStyles(style, "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, "style");
+ DateTimeFormatInfo.ValidateStyles(style, nameof(style));
return DateTimeParse.ParseExactMultiple(s, formats, DateTimeFormatInfo.GetInstance(provider), style);
}
@@ -1042,7 +1026,7 @@ namespace System {
long ticks = InternalTicks;
long valueTicks = value._ticks;
if (ticks - MinTicks < valueTicks || ticks - MaxTicks > valueTicks) {
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_DateArithmetic"));
+ throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_DateArithmetic"));
}
return new DateTime((UInt64)(ticks - valueTicks) | InternalKind);
}
@@ -1166,17 +1150,17 @@ namespace System {
}
public static Boolean TryParse(String s, IFormatProvider provider, DateTimeStyles styles, out DateTime result) {
- DateTimeFormatInfo.ValidateStyles(styles, "styles");
+ 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, "style");
+ 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, "style");
+ DateTimeFormatInfo.ValidateStyles(style, nameof(style));
return DateTimeParse.TryParseExactMultiple(s, formats, DateTimeFormatInfo.GetInstance(provider), style, out result);
}
@@ -1184,7 +1168,7 @@ namespace System {
long ticks = d.InternalTicks;
long valueTicks = t._ticks;
if (valueTicks > MaxTicks - ticks || valueTicks < MinTicks - ticks) {
- throw new ArgumentOutOfRangeException("t", Environment.GetResourceString("ArgumentOutOfRange_DateArithmetic"));
+ throw new ArgumentOutOfRangeException(nameof(t), Environment.GetResourceString("ArgumentOutOfRange_DateArithmetic"));
}
return new DateTime((UInt64)(ticks + valueTicks) | d.InternalKind);
}
@@ -1193,7 +1177,7 @@ namespace System {
long ticks = d.InternalTicks;
long valueTicks = t._ticks;
if (ticks - MinTicks < valueTicks || ticks - MaxTicks > valueTicks) {
- throw new ArgumentOutOfRangeException("t", Environment.GetResourceString("ArgumentOutOfRange_DateArithmetic"));
+ throw new ArgumentOutOfRangeException(nameof(t), Environment.GetResourceString("ArgumentOutOfRange_DateArithmetic"));
}
return new DateTime((UInt64)(ticks - valueTicks) | d.InternalKind);
}
diff --git a/src/mscorlib/src/System/DateTimeOffset.cs b/src/mscorlib/src/System/DateTimeOffset.cs
index 3e63c76124..5bdaa18aaa 100644
--- a/src/mscorlib/src/System/DateTimeOffset.cs
+++ b/src/mscorlib/src/System/DateTimeOffset.cs
@@ -11,6 +11,7 @@ namespace System {
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Security.Permissions;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
// DateTimeOffset is a value type that consists of a DateTime and a time zone offset,
@@ -87,12 +88,12 @@ namespace System {
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"), "offset");
+ 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"), "offset");
+ throw new ArgumentException(Environment.GetResourceString("Argument_OffsetUtcMismatch"), nameof(offset));
}
}
m_offsetMinutes = ValidateOffset(offset);
@@ -479,7 +480,7 @@ namespace System {
public static DateTimeOffset FromUnixTimeSeconds(long seconds) {
if (seconds < UnixMinSeconds || seconds > UnixMaxSeconds) {
- throw new ArgumentOutOfRangeException("seconds",
+ throw new ArgumentOutOfRangeException(nameof(seconds),
string.Format(Environment.GetResourceString("ArgumentOutOfRange_Range"), UnixMinSeconds, UnixMaxSeconds));
}
@@ -492,7 +493,7 @@ namespace System {
const long MaxMilliseconds = DateTime.MaxTicks / TimeSpan.TicksPerMillisecond - UnixEpochMilliseconds;
if (milliseconds < MinMilliseconds || milliseconds > MaxMilliseconds) {
- throw new ArgumentOutOfRangeException("milliseconds",
+ throw new ArgumentOutOfRangeException(nameof(milliseconds),
string.Format(Environment.GetResourceString("ArgumentOutOfRange_Range"), MinMilliseconds, MaxMilliseconds));
}
@@ -513,10 +514,9 @@ namespace System {
}
- [System.Security.SecurityCritical] // auto-generated_required
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) {
if (info == null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
@@ -528,7 +528,7 @@ namespace System {
DateTimeOffset(SerializationInfo info, StreamingContext context) {
if (info == null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
m_dateTime = (DateTime)info.GetValue("DateTime", typeof(DateTime));
@@ -563,7 +563,7 @@ namespace System {
}
public static DateTimeOffset Parse(String input, IFormatProvider formatProvider, DateTimeStyles styles) {
- styles = ValidateStyles(styles, "styles");
+ styles = ValidateStyles(styles, nameof(styles));
TimeSpan offset;
DateTime dateResult = DateTimeParse.Parse(input,
DateTimeFormatInfo.GetInstance(formatProvider),
@@ -585,7 +585,7 @@ namespace System {
// Leading and trailing whitespace characters are allowed.
//
public static DateTimeOffset ParseExact(String input, String format, IFormatProvider formatProvider, DateTimeStyles styles) {
- styles = ValidateStyles(styles, "styles");
+ styles = ValidateStyles(styles, nameof(styles));
TimeSpan offset;
DateTime dateResult = DateTimeParse.ParseExact(input,
format,
@@ -596,7 +596,7 @@ namespace System {
}
public static DateTimeOffset ParseExact(String input, String[] formats, IFormatProvider formatProvider, DateTimeStyles styles) {
- styles = ValidateStyles(styles, "styles");
+ styles = ValidateStyles(styles, nameof(styles));
TimeSpan offset;
DateTime dateResult = DateTimeParse.ParseExactMultiple(input,
formats,
@@ -693,7 +693,7 @@ namespace System {
}
public static Boolean TryParse(String input, IFormatProvider formatProvider, DateTimeStyles styles, out DateTimeOffset result) {
- styles = ValidateStyles(styles, "styles");
+ styles = ValidateStyles(styles, nameof(styles));
TimeSpan offset;
DateTime dateResult;
Boolean parsed = DateTimeParse.TryParse(input,
@@ -707,7 +707,7 @@ namespace System {
public static Boolean TryParseExact(String input, String format, IFormatProvider formatProvider, DateTimeStyles styles,
out DateTimeOffset result) {
- styles = ValidateStyles(styles, "styles");
+ styles = ValidateStyles(styles, nameof(styles));
TimeSpan offset;
DateTime dateResult;
Boolean parsed = DateTimeParse.TryParseExact(input,
@@ -722,7 +722,7 @@ namespace System {
public static Boolean TryParseExact(String input, String[] formats, IFormatProvider formatProvider, DateTimeStyles styles,
out DateTimeOffset result) {
- styles = ValidateStyles(styles, "styles");
+ styles = ValidateStyles(styles, nameof(styles));
TimeSpan offset;
DateTime dateResult;
Boolean parsed = DateTimeParse.TryParseExactMultiple(input,
@@ -739,10 +739,10 @@ namespace System {
private static Int16 ValidateOffset(TimeSpan offset) {
Int64 ticks = offset.Ticks;
if (ticks % TimeSpan.TicksPerMinute != 0) {
- throw new ArgumentException(Environment.GetResourceString("Argument_OffsetPrecision"), "offset");
+ throw new ArgumentException(Environment.GetResourceString("Argument_OffsetPrecision"), nameof(offset));
}
if (ticks < MinOffset || ticks > MaxOffset) {
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("Argument_OffsetOutOfRange"));
+ throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("Argument_OffsetOutOfRange"));
}
return (Int16)(offset.Ticks / TimeSpan.TicksPerMinute);
}
@@ -751,12 +751,12 @@ namespace System {
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.
- Contract.Assert(offset.Ticks >= MinOffset && offset.Ticks <= MaxOffset, "Offset not validated.");
+ 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("offset", Environment.GetResourceString("Argument_UTCOutOfRange"));
+ throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("Argument_UTCOutOfRange"));
}
// make sure the Kind is set to Unspecified
//
diff --git a/src/mscorlib/src/System/Decimal.cs b/src/mscorlib/src/System/Decimal.cs
index 8a2c30ffa8..fd16697199 100644
--- a/src/mscorlib/src/System/Decimal.cs
+++ b/src/mscorlib/src/System/Decimal.cs
@@ -206,13 +206,11 @@ namespace System {
// Constructs a Decimal from a float value.
//
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern Decimal(float value);
// Constructs a Decimal from a double value.
//
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern Decimal(double value);
@@ -264,7 +262,7 @@ namespace System {
private void SetBits(int[] bits) {
if (bits==null)
- throw new ArgumentNullException("bits");
+ throw new ArgumentNullException(nameof(bits));
Contract.EndContractBlock();
if (bits.Length == 4) {
int f = bits[3];
@@ -283,7 +281,7 @@ namespace System {
//
public Decimal(int lo, int mid, int hi, bool isNegative, byte scale) {
if (scale > 28)
- throw new ArgumentOutOfRangeException("scale", Environment.GetResourceString("ArgumentOutOfRange_DecimalScale"));
+ throw new ArgumentOutOfRangeException(nameof(scale), Environment.GetResourceString("ArgumentOutOfRange_DecimalScale"));
Contract.EndContractBlock();
this.lo = lo;
this.mid = mid;
@@ -335,7 +333,6 @@ namespace System {
// Adds two Decimal values.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public static Decimal Add(Decimal d1, Decimal d2)
{
FCallAddSub (ref d1, ref d2, DECIMAL_ADD);
@@ -346,11 +343,9 @@ namespace System {
// of the operation. Passing in DECIMAL_ADD or DECIMAL_NEG for bSign indicates
// addition or subtraction, respectively.
//
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void FCallAddSub(ref Decimal d1, ref Decimal d2, byte bSign);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void FCallAddSubOverflowed(ref Decimal d1, ref Decimal d2, byte bSign, ref bool overflowed);
@@ -363,13 +358,11 @@ namespace System {
// Compares two Decimal values, returning an integer that indicates their
// relationship.
//
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static int Compare(Decimal d1, Decimal d2) {
return FCallCompare(ref d1, ref d2);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
private static extern int FCallCompare(ref Decimal d1, ref Decimal d2);
@@ -380,7 +373,6 @@ namespace System {
// null is considered to be less than any instance.
// If object is not of type Decimal, this method throws an ArgumentException.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public int CompareTo(Object value)
{
if (value == null)
@@ -392,7 +384,6 @@ namespace System {
return FCallCompare(ref this, ref other);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public int CompareTo(Decimal value)
{
return FCallCompare(ref this, ref value);
@@ -400,7 +391,6 @@ namespace System {
// Divides two Decimal values.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public static Decimal Divide(Decimal d1, Decimal d2)
{
FCallDivide (ref d1, ref d2);
@@ -410,11 +400,9 @@ namespace System {
// FCallDivide divides two decimal values. On return, d1 contains the result
// of the operation.
//
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void FCallDivide(ref Decimal d1, ref Decimal d2);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void FCallDivideOverflowed(ref Decimal d1, ref Decimal d2, ref bool overflowed);
@@ -423,7 +411,6 @@ namespace System {
// if the given object is a boxed Decimal and its value is equal to the
// value of this Decimal. Returns false otherwise.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public override bool Equals(Object value) {
if (value is Decimal) {
Decimal other = (Decimal)value;
@@ -432,7 +419,6 @@ namespace System {
return false;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public bool Equals(Decimal value)
{
return FCallCompare(ref this, ref value) == 0;
@@ -440,14 +426,12 @@ namespace System {
// Returns the hash code for this Decimal.
//
- [System.Security.SecuritySafeCritical] // auto-generated
[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.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public static bool Equals(Decimal d1, Decimal d2) {
return FCallCompare(ref d1, ref d2) == 0;
}
@@ -455,14 +439,12 @@ namespace System {
// Rounds a Decimal to an integer value. The Decimal argument is rounded
// towards negative infinity.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public static Decimal Floor(Decimal d)
{
FCallFloor (ref d);
return d;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void FCallFloor(ref Decimal d);
@@ -471,25 +453,21 @@ namespace System {
// optionally followed by a decimal point (".") and another sequence of
// digits.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public override String ToString() {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatDecimal(this, null, NumberFormatInfo.CurrentInfo);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(String format) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatDecimal(this, format, NumberFormatInfo.CurrentInfo);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(IFormatProvider provider) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatDecimal(this, null, NumberFormatInfo.GetInstance(provider));
}
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(String format, IFormatProvider provider) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatDecimal(this, format, NumberFormatInfo.GetInstance(provider));
@@ -650,7 +628,6 @@ namespace System {
// Returns the larger of two Decimal values.
//
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal static Decimal Max(Decimal d1, Decimal d2) {
return FCallCompare(ref d1, ref d2) >= 0? d1: d2;
@@ -658,7 +635,6 @@ namespace System {
// Returns the smaller of two Decimal values.
//
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal static Decimal Min(Decimal d1, Decimal d2) {
return FCallCompare(ref d1, ref d2) < 0? d1: d2;
@@ -709,7 +685,6 @@ namespace System {
// Multiplies two Decimal values.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public static Decimal Multiply(Decimal d1, Decimal d2)
{
FCallMultiply (ref d1, ref d2);
@@ -719,11 +694,9 @@ namespace System {
// FCallMultiply multiples two decimal values. On return, d1 contains the result
// of the operation.
//
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void FCallMultiply(ref Decimal d1, ref Decimal d2);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void FCallMultiplyOverflowed(ref Decimal d1, ref Decimal d2, ref bool overflowed);
@@ -746,7 +719,6 @@ namespace System {
return Round(d, 0);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static Decimal Round(Decimal d, int decimals)
{
FCallRound (ref d, decimals);
@@ -757,12 +729,11 @@ namespace System {
return Round(d, 0, mode);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static Decimal Round(Decimal d, int decimals, MidpointRounding mode) {
if ((decimals < 0) || (decimals > 28))
- throw new ArgumentOutOfRangeException("decimals", Environment.GetResourceString("ArgumentOutOfRange_DecimalRound"));
+ throw new ArgumentOutOfRangeException(nameof(decimals), Environment.GetResourceString("ArgumentOutOfRange_DecimalRound"));
if (mode < MidpointRounding.ToEven || mode > MidpointRounding.AwayFromZero) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidEnumValue", mode, "MidpointRounding"), "mode");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidEnumValue", mode, nameof(MidpointRounding)), nameof(mode));
}
Contract.EndContractBlock();
@@ -775,13 +746,11 @@ namespace System {
return d;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void FCallRound(ref Decimal d, int decimals);
// Subtracts two Decimal values.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public static Decimal Subtract(Decimal d1, Decimal d2)
{
FCallAddSub(ref d1, ref d2, DECIMAL_NEG);
@@ -843,7 +812,6 @@ namespace System {
// has fewer significant digits than a Decimal, this operation may
// produce round-off errors.
//
- [System.Security.SecuritySafeCritical] // auto-generated
internal static Currency ToCurrency(Decimal d)
{
Currency result = new Currency ();
@@ -851,18 +819,15 @@ namespace System {
return result;
}
- [System.Security.SecurityCritical] // auto-generated
[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.
//
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern double ToDouble(Decimal d);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern int FCallToInt32(Decimal d);
@@ -870,7 +835,6 @@ namespace System {
// zero to the nearest integer value, and the result of this operation is
// returned as an integer.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public static int ToInt32(Decimal d) {
if ((d.flags & ScaleMask) != 0) FCallTruncate (ref d);
if (d.hi == 0 && d.mid == 0) {
@@ -890,7 +854,6 @@ namespace System {
// to the nearest integer value, and the result of this operation is
// returned as a long.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public static long ToInt64(Decimal d) {
if ((d.flags & ScaleMask) != 0) FCallTruncate (ref d);
if (d.hi == 0) {
@@ -927,7 +890,6 @@ namespace System {
// value is rounded towards zero to the nearest integer value, and the
// result of this operation is returned as an unsigned integer.
//
- [System.Security.SecuritySafeCritical] // auto-generated
[CLSCompliant(false)]
public static uint ToUInt32(Decimal d) {
if ((d.flags & ScaleMask) != 0) FCallTruncate (ref d);
@@ -943,7 +905,6 @@ namespace System {
// value is rounded towards zero to the nearest integer value, and the
// result of this operation is returned as a long.
//
- [System.Security.SecuritySafeCritical] // auto-generated
[CLSCompliant(false)]
public static ulong ToUInt64(Decimal d) {
if ((d.flags & ScaleMask) != 0) FCallTruncate (ref d);
@@ -958,7 +919,6 @@ namespace System {
// Converts a Decimal to a float. Since a float has fewer significant
// digits than a Decimal, this operation may produce round-off errors.
//
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern float ToSingle(Decimal d);
@@ -966,7 +926,6 @@ namespace System {
// towards zero to the nearest integer value, corresponding to removing all
// digits after the decimal point.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public static Decimal Truncate(Decimal d)
{
FCallTruncate (ref d);
@@ -974,7 +933,6 @@ namespace System {
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void FCallTruncate(ref Decimal d);
@@ -1099,25 +1057,21 @@ namespace System {
return Subtract(d, One);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static Decimal operator +(Decimal d1, Decimal d2) {
FCallAddSub(ref d1, ref d2, DECIMAL_ADD);
return d1;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static Decimal operator -(Decimal d1, Decimal d2) {
FCallAddSub(ref d1, ref d2, DECIMAL_NEG);
return d1;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static Decimal operator *(Decimal d1, Decimal d2) {
FCallMultiply (ref d1, ref d2);
return d1;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static Decimal operator /(Decimal d1, Decimal d2) {
FCallDivide (ref d1, ref d2);
return d1;
@@ -1127,32 +1081,26 @@ namespace System {
return Remainder(d1, d2);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static bool operator ==(Decimal d1, Decimal d2) {
return FCallCompare(ref d1, ref d2) == 0;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static bool operator !=(Decimal d1, Decimal d2) {
return FCallCompare(ref d1, ref d2) != 0;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static bool operator <(Decimal d1, Decimal d2) {
return FCallCompare(ref d1, ref d2) < 0;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static bool operator <=(Decimal d1, Decimal d2) {
return FCallCompare(ref d1, ref d2) <= 0;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static bool operator >(Decimal d1, Decimal d2) {
return FCallCompare(ref d1, ref d2) > 0;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static bool operator >=(Decimal d1, Decimal d2) {
return FCallCompare(ref d1, ref d2) >= 0;
}
diff --git a/src/mscorlib/src/System/DefaultBinder.cs b/src/mscorlib/src/System/DefaultBinder.cs
index 405055e844..b4681c406d 100644
--- a/src/mscorlib/src/System/DefaultBinder.cs
+++ b/src/mscorlib/src/System/DefaultBinder.cs
@@ -14,6 +14,7 @@ namespace 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.
@@ -33,13 +34,12 @@ namespace System {
//
// The most specific match will be selected.
//
- [System.Security.SecuritySafeCritical] // auto-generated
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"), "match");
+ throw new ArgumentException(Environment.GetResourceString("Arg_EmptyArray"), nameof(match));
Contract.EndContractBlock();
MethodBase[] candidates = (MethodBase[]) match.Clone();
@@ -437,11 +437,10 @@ namespace System {
// 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
- [System.Security.SecuritySafeCritical] // auto-generated
public override FieldInfo BindToField(BindingFlags bindingAttr,FieldInfo[] match, Object value,CultureInfo cultureInfo)
{
if (match == null) {
- throw new ArgumentNullException("match");
+ throw new ArgumentNullException(nameof(match));
}
int i;
@@ -514,7 +513,6 @@ namespace System {
// 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.
- [System.Security.SecuritySafeCritical] // auto-generated
public override MethodBase SelectMethod(BindingFlags bindingAttr,MethodBase[] match,Type[] types,ParameterModifier[] modifiers)
{
int i;
@@ -524,13 +522,13 @@ namespace System {
for (i=0;i<types.Length;i++) {
realTypes[i] = types[i].UnderlyingSystemType;
if (!(realTypes[i] is RuntimeType))
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"types");
+ 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"), "match");
+ throw new ArgumentException(Environment.GetResourceString("Arg_EmptyArray"), nameof(match));
MethodBase[] candidates = (MethodBase[]) match.Clone();
@@ -589,17 +587,16 @@ namespace System {
}
// Given a set of properties that match the base criteria, select one.
- [System.Security.SecuritySafeCritical] // auto-generated
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("indexes");
+ throw new ArgumentNullException(nameof(indexes));
}
if (match == null || match.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_EmptyArray"), "match");
+ throw new ArgumentException(Environment.GetResourceString("Arg_EmptyArray"), nameof(match));
Contract.EndContractBlock();
PropertyInfo[] candidates = (PropertyInfo[]) match.Clone();
@@ -732,7 +729,7 @@ namespace System {
public static MethodBase ExactBinding(MethodBase[] match,Type[] types,ParameterModifier[] modifiers)
{
if (match==null)
- throw new ArgumentNullException("match");
+ throw new ArgumentNullException(nameof(match));
Contract.EndContractBlock();
MethodBase[] aExactMatches = new MethodBase[match.Length];
int cExactMatches = 0;
@@ -772,7 +769,7 @@ namespace System {
public static PropertyInfo ExactPropertyBinding(PropertyInfo[] match,Type returnType,Type[] types,ParameterModifier[] modifiers)
{
if (match==null)
- throw new ArgumentNullException("match");
+ throw new ArgumentNullException(nameof(match));
Contract.EndContractBlock();
PropertyInfo bestMatch = null;
@@ -876,7 +873,6 @@ namespace System {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
private static int FindMostSpecificType(Type c1, Type c2, Type t)
{
// If the two types are exact move on...
@@ -987,7 +983,7 @@ namespace System {
int hierarchyDepth2 = GetHierarchyDepth(cur2.DeclaringType);
if (hierarchyDepth1 == hierarchyDepth2) {
- Contract.Assert(cur1.IsStatic != cur2.IsStatic, "hierarchyDepth1 == hierarchyDepth2");
+ Debug.Assert(cur1.IsStatic != cur2.IsStatic, "hierarchyDepth1 == hierarchyDepth2");
return 0;
}
else if (hierarchyDepth1 < hierarchyDepth2)
@@ -1084,14 +1080,12 @@ namespace System {
// CanConvertPrimitive
// This will determine if the source can be converted to the target type
- [System.Security.SecurityCritical] // auto-generated
[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.
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern bool CanConvertPrimitiveObjectToType(Object source,RuntimeType type);
diff --git a/src/mscorlib/src/System/Delegate.cs b/src/mscorlib/src/System/Delegate.cs
index 110555423c..bca88c18e9 100644
--- a/src/mscorlib/src/System/Delegate.cs
+++ b/src/mscorlib/src/System/Delegate.cs
@@ -12,6 +12,7 @@ namespace System {
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
[Serializable]
@@ -20,36 +21,31 @@ namespace System {
public abstract class Delegate : ICloneable, ISerializable
{
// _target is the object we will invoke on
- [System.Security.SecurityCritical]
internal Object _target;
// MethodBase, either cached after first request or assigned from a DynamicMethod
// For open delegates to collectible types, this may be a LoaderAllocator object
- [System.Security.SecurityCritical]
internal Object _methodBase;
// _methodPtr is a pointer to the method we will invoke
// It could be a small thunk if this is a static or UM call
- [System.Security.SecurityCritical]
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
// to _methodPtrAux.
- [System.Security.SecurityCritical]
internal IntPtr _methodPtrAux;
// This constructor is called from the class generated by the
// compiler generated code
- [System.Security.SecuritySafeCritical] // auto-generated
protected Delegate(Object target,String method)
{
if (target == null)
- throw new ArgumentNullException("target");
+ throw new ArgumentNullException(nameof(target));
if (method == null)
- throw new ArgumentNullException("method");
+ throw new ArgumentNullException(nameof(method));
Contract.EndContractBlock();
// This API existed in v1/v1.1 and only expected to create closed
@@ -67,22 +63,21 @@ namespace System {
// 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.
- [System.Security.SecuritySafeCritical] // auto-generated
protected unsafe Delegate(Type target,String method)
{
if (target == null)
- throw new ArgumentNullException("target");
+ throw new ArgumentNullException(nameof(target));
if (target.IsGenericType && target.ContainsGenericParameters)
- throw new ArgumentException(Environment.GetResourceString("Arg_UnboundGenParam"), "target");
+ throw new ArgumentException(Environment.GetResourceString("Arg_UnboundGenParam"), nameof(target));
if (method == null)
- throw new ArgumentNullException("method");
+ throw new ArgumentNullException(nameof(method));
Contract.EndContractBlock();
RuntimeType rtTarget = target as RuntimeType;
if (rtTarget == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "target");
+ throw new ArgumentException(Environment.GetResourceString("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
@@ -113,7 +108,6 @@ namespace System {
return DynamicInvokeImpl(args);
}
- [System.Security.SecuritySafeCritical] // auto-generated
protected virtual object DynamicInvokeImpl(object[] args)
{
RuntimeMethodHandleInternal method = new RuntimeMethodHandleInternal(GetInvokeMethod());
@@ -123,7 +117,6 @@ namespace System {
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override bool Equals(Object obj)
{
if (obj == null || !InternalEqualTypes(this, obj))
@@ -227,7 +220,6 @@ namespace System {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
protected virtual MethodInfo GetMethodImpl()
{
if ((_methodBase == null) || !(_methodBase is MethodInfo))
@@ -292,7 +284,6 @@ namespace System {
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static Delegate Remove(Delegate source, Delegate value)
{
if (source == null)
@@ -350,22 +341,21 @@ namespace System {
}
// V1 API.
- [System.Security.SecuritySafeCritical] // auto-generated
public static Delegate CreateDelegate(Type type, Object target, String method, bool ignoreCase, bool throwOnBindFailure)
{
if (type == null)
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
if (target == null)
- throw new ArgumentNullException("target");
+ throw new ArgumentNullException(nameof(target));
if (method == null)
- throw new ArgumentNullException("method");
+ throw new ArgumentNullException(nameof(method));
Contract.EndContractBlock();
RuntimeType rtType = type as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "type");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), nameof(type));
if (!rtType.IsDelegate())
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"),"type");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"),nameof(type));
Delegate d = InternalAlloc(rtType);
// This API existed in v1/v1.1 and only expected to create closed
@@ -402,27 +392,26 @@ namespace System {
}
// V1 API.
- [System.Security.SecuritySafeCritical] // auto-generated
public static Delegate CreateDelegate(Type type, Type target, String method, bool ignoreCase, bool throwOnBindFailure)
{
if (type == null)
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
if (target == null)
- throw new ArgumentNullException("target");
+ throw new ArgumentNullException(nameof(target));
if (target.IsGenericType && target.ContainsGenericParameters)
- throw new ArgumentException(Environment.GetResourceString("Arg_UnboundGenParam"), "target");
+ throw new ArgumentException(Environment.GetResourceString("Arg_UnboundGenParam"), nameof(target));
if (method == null)
- throw new ArgumentNullException("method");
+ throw new ArgumentNullException(nameof(method));
Contract.EndContractBlock();
RuntimeType rtType = type as RuntimeType;
RuntimeType rtTarget = target as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "type");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), nameof(type));
if (rtTarget == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "target");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), nameof(target));
if (!rtType.IsDelegate())
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"),"type");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"),nameof(type));
Delegate d = InternalAlloc(rtType);
// This API existed in v1/v1.1 and only expected to create open
@@ -443,27 +432,26 @@ namespace System {
}
// V1 API.
- [System.Security.SecuritySafeCritical]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static Delegate CreateDelegate(Type type, MethodInfo method, bool throwOnBindFailure)
{
// Validate the parameters.
if (type == null)
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
if (method == null)
- throw new ArgumentNullException("method");
+ throw new ArgumentNullException(nameof(method));
Contract.EndContractBlock();
RuntimeType rtType = type as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "type");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), nameof(type));
RuntimeMethodInfo rmi = method as RuntimeMethodInfo;
if (rmi == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), "method");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), nameof(method));
if (!rtType.IsDelegate())
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"), "type");
+ throw new ArgumentException(Environment.GetResourceString("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
@@ -494,27 +482,26 @@ namespace System {
}
// V2 API.
- [System.Security.SecuritySafeCritical]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static Delegate CreateDelegate(Type type, Object firstArgument, MethodInfo method, bool throwOnBindFailure)
{
// Validate the parameters.
if (type == null)
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
if (method == null)
- throw new ArgumentNullException("method");
+ throw new ArgumentNullException(nameof(method));
Contract.EndContractBlock();
RuntimeType rtType = type as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "type");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), nameof(type));
RuntimeMethodInfo rmi = method as RuntimeMethodInfo;
if (rmi == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), "method");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), nameof(method));
if (!rtType.IsDelegate())
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"), "type");
+ throw new ArgumentException(Environment.GetResourceString("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
@@ -555,7 +542,6 @@ namespace System {
// Implementation of ISerializable
//
- [System.Security.SecurityCritical]
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
throw new NotSupportedException();
@@ -566,23 +552,22 @@ namespace System {
// V2 internal API.
// This is Critical because it skips the security check when creating the delegate.
- [System.Security.SecurityCritical] // auto-generated
internal unsafe static Delegate CreateDelegateNoSecurityCheck(Type type, Object target, RuntimeMethodHandle method)
{
// Validate the parameters.
if (type == null)
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
Contract.EndContractBlock();
if (method.IsNullHandle())
- throw new ArgumentNullException("method");
+ throw new ArgumentNullException(nameof(method));
RuntimeType rtType = type as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "type");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), nameof(type));
if (!rtType.IsDelegate())
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"),"type");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"), nameof(type));
// Initialize the method...
Delegate d = InternalAlloc(rtType);
@@ -600,23 +585,22 @@ namespace System {
}
// Caution: this method is intended for deserialization only, no security checks are performed.
- [System.Security.SecurityCritical] // auto-generated
internal static Delegate CreateDelegateNoSecurityCheck(RuntimeType type, Object firstArgument, MethodInfo method)
{
// Validate the parameters.
if (type == null)
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
if (method == null)
- throw new ArgumentNullException("method");
+ throw new ArgumentNullException(nameof(method));
Contract.EndContractBlock();
RuntimeMethodInfo rtMethod = method as RuntimeMethodInfo;
if (rtMethod == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), "method");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), nameof(method));
if (!type.IsDelegate())
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"),"type");
+ throw new ArgumentException(Environment.GetResourceString("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
@@ -642,10 +626,9 @@ namespace System {
return CreateDelegate(type, method, true);
}
- [System.Security.SecuritySafeCritical]
internal static Delegate CreateDelegateInternal(RuntimeType rtType, RuntimeMethodInfo rtMethod, Object firstArgument, DelegateBindingFlags flags, ref StackCrawlMark stackMark)
{
- Contract.Assert((flags & DelegateBindingFlags.SkipSecurityChecks) == 0);
+ Debug.Assert((flags & DelegateBindingFlags.SkipSecurityChecks) == 0);
#if FEATURE_APPX
bool nonW8PMethod = (rtMethod.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0;
@@ -663,7 +646,6 @@ namespace System {
return UnsafeCreateDelegate(rtType, rtMethod, firstArgument, flags);
}
- [System.Security.SecurityCritical]
internal static Delegate UnsafeCreateDelegate(RuntimeType rtType, RuntimeMethodInfo rtMethod, Object firstArgument, DelegateBindingFlags flags)
{
Delegate d = InternalAlloc(rtType);
@@ -678,62 +660,49 @@ namespace System {
// internal implementation details (FCALLS and utilities)
//
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern bool BindToMethodName(Object target, RuntimeType methodType, String method, DelegateBindingFlags flags);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern bool BindToMethodInfo(Object target, IRuntimeMethodInfo method, RuntimeType methodType, DelegateBindingFlags flags);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern static MulticastDelegate InternalAlloc(RuntimeType type);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static MulticastDelegate InternalAllocLike(Delegate d);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool InternalEqualTypes(object a, object b);
// Used by the ctor. Do not call directly.
// The name of this function will appear in managed stacktraces as delegate constructor.
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void DelegateConstruct(Object target, IntPtr slot);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern IntPtr GetMulticastInvoke();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern IntPtr GetInvokeMethod();
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern IRuntimeMethodInfo FindMethodHandle();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool InternalEqualMethodHandles(Delegate left, Delegate right);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern IntPtr AdjustTarget(Object target, IntPtr methodPtr);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern IntPtr GetCallStub(IntPtr methodPtr);
- [System.Security.SecuritySafeCritical]
internal virtual Object GetTarget()
{
return (_methodPtrAux.IsNull()) ? _target : null;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool CompareUnmanagedFunctionPtrs (Delegate d1, Delegate d2);
}
diff --git a/src/mscorlib/src/System/DelegateSerializationHolder.cs b/src/mscorlib/src/System/DelegateSerializationHolder.cs
index a6280333db..83fe35ad1e 100644
--- a/src/mscorlib/src/System/DelegateSerializationHolder.cs
+++ b/src/mscorlib/src/System/DelegateSerializationHolder.cs
@@ -17,14 +17,13 @@ namespace System
internal sealed class DelegateSerializationHolder : IObjectReference, ISerializable
{
#region Static Members
- [System.Security.SecurityCritical] // auto-generated
internal static DelegateEntry GetDelegateSerializationInfo(
SerializationInfo info, Type delegateType, Object target, MethodInfo method, int targetIndex)
{
// Used for MulticastDelegate
if (method == null)
- throw new ArgumentNullException("method");
+ throw new ArgumentNullException(nameof(method));
Contract.EndContractBlock();
if (!method.IsPublic || (method.DeclaringType != null && !method.DeclaringType.IsVisible))
@@ -116,11 +115,10 @@ namespace System
#endregion
#region Constructor
- [System.Security.SecurityCritical] // auto-generated
private DelegateSerializationHolder(SerializationInfo info, StreamingContext context)
{
if (info == null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
bool bNewWire = true;
@@ -182,7 +180,7 @@ namespace System
private DelegateEntry OldDelegateWireFormat(SerializationInfo info, StreamingContext context)
{
if (info == null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
String delegateType = info.GetString("DelegateType");
@@ -195,7 +193,6 @@ namespace System
return new DelegateEntry(delegateType, delegateAssembly, target, targetTypeAssembly, targetTypeName, methodName);
}
- [System.Security.SecurityCritical]
private Delegate GetDelegate(DelegateEntry de, int index)
{
Delegate d;
@@ -218,27 +215,19 @@ namespace System
// If we received the new style delegate encoding we already have the target MethodInfo in hand.
if (m_methods != null)
{
-#if FEATURE_REMOTING
- Object target = de.target != null ? RemotingServices.CheckCast(de.target, targetType) : null;
-#else
if(de.target != null && !targetType.IsInstanceOfType(de.target))
throw new InvalidCastException();
Object target=de.target;
-#endif
d = Delegate.CreateDelegateNoSecurityCheck(type, target, m_methods[index]);
}
else
{
if (de.target != null)
-#if FEATURE_REMOTING
- d = Delegate.CreateDelegate(type, RemotingServices.CheckCast(de.target, targetType), de.methodName);
-#else
- {
- if(!targetType.IsInstanceOfType(de.target))
- throw new InvalidCastException();
- d = Delegate.CreateDelegate(type, de.target, de.methodName);
- }
-#endif
+ {
+ if(!targetType.IsInstanceOfType(de.target))
+ throw new InvalidCastException();
+ d = Delegate.CreateDelegate(type, de.target, de.methodName);
+ }
else
d = Delegate.CreateDelegate(type, targetType, de.methodName);
}
@@ -259,7 +248,6 @@ namespace System
#endregion
#region IObjectReference
- [System.Security.SecurityCritical] // auto-generated
public Object GetRealObject(StreamingContext context)
{
int count = 0;
@@ -289,7 +277,6 @@ namespace System
#endregion
#region ISerializable
- [System.Security.SecurityCritical] // auto-generated
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
throw new NotSupportedException(Environment.GetResourceString("NotSupported_DelegateSerHolderSerial"));
diff --git a/src/mscorlib/src/System/Diagnostics/Assert.cs b/src/mscorlib/src/System/Diagnostics/Assert.cs
index 40efe753af..77cc6d8e46 100644
--- a/src/mscorlib/src/System/Diagnostics/Assert.cs
+++ b/src/mscorlib/src/System/Diagnostics/Assert.cs
@@ -59,7 +59,6 @@ namespace System.Diagnostics {
Fail(conditionString, message, null, exitCode, stackTraceFormat, 0);
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static void Fail(String conditionString, String message, String windowTitle, int exitCode, StackTrace.TraceFormat stackTraceFormat, int numStackFramesToSkip)
{
// get the stacktrace
@@ -82,32 +81,15 @@ namespace System.Diagnostics {
}
else if (iResult == AssertFilters.FailTerminate)
{
-#if FEATURE_CORECLR
// We want to exit the Silverlight application, after displaying a message.
// Our best known way to emulate this is to exit the process with a known
// error code. Jolt may not be prepared for an appdomain to be unloaded.
Environment._Exit(exitCode);
-#else
- // This assert dialog will be common for code contract failures. If a code contract failure
- // occurs on an end user machine, we believe the right experience is to do a FailFast, which
- // will report this error via Watson, so someone could theoretically fix the bug.
- // However, in CLR v4, Environment.FailFast when a debugger is attached gives you an MDA
- // saying you've hit a bug in the runtime or unsafe managed code, and this is most likely caused
- // by heap corruption or a stack imbalance from COM Interop or P/Invoke. That extremely
- // misleading error isn't right, and we can temporarily work around this by using Environment.Exit
- // if a debugger is attached. The right fix is to plumb FailFast correctly through our native
- // Watson code, adding in a TypeOfReportedError for fatal managed errors.
- if (Debugger.IsAttached)
- Environment._Exit(exitCode);
- else
- Environment.FailFast(message, unchecked((uint) exitCode));
-#endif
}
}
// Called when an assert happens.
// windowTitle can be null.
- [System.Security.SecurityCritical] // auto-generated
[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 b441fc326b..ab60ee4cff 100644
--- a/src/mscorlib/src/System/Diagnostics/AssertFilter.cs
+++ b/src/mscorlib/src/System/Diagnostics/AssertFilter.cs
@@ -33,7 +33,6 @@ namespace System.Diagnostics {
{
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override AssertFilters AssertFailure(String condition, String message,
StackTrace location, StackTrace.TraceFormat stackTraceFormat,
String windowTitle)
diff --git a/src/mscorlib/src/System/Diagnostics/Contracts/Contracts.cs b/src/mscorlib/src/System/Diagnostics/Contracts/Contracts.cs
index e002e6a5c1..27f4f4cdaa 100644
--- a/src/mscorlib/src/System/Diagnostics/Contracts/Contracts.cs
+++ b/src/mscorlib/src/System/Diagnostics/Contracts/Contracts.cs
@@ -32,6 +32,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
@@ -287,7 +288,7 @@ namespace System.Diagnostics.Contracts {
/// </summary>
/// <param name="condition">Expression to assume will always be true.</param>
/// <remarks>
- /// At runtime this is equivalent to an <seealso cref="System.Diagnostics.Contracts.Contract.Assert(bool)"/>.
+ /// At runtime this is equivalent to an <seealso cref="System.Diagnostics.Contracts.Debug.Assert(bool)"/>.
/// </remarks>
[Pure]
[Conditional("DEBUG")]
@@ -308,7 +309,7 @@ namespace System.Diagnostics.Contracts {
/// <param name="condition">Expression to assume will always be true.</param>
/// <param name="userMessage">If it is not a constant string literal, then the contract may not be understood by tools.</param>
/// <remarks>
- /// At runtime this is equivalent to an <seealso cref="System.Diagnostics.Contracts.Contract.Assert(bool)"/>.
+ /// At runtime this is equivalent to an <seealso cref="System.Diagnostics.Contracts.Debug.Assert(bool)"/>.
/// </remarks>
[Pure]
[Conditional("DEBUG")]
@@ -654,7 +655,7 @@ namespace System.Diagnostics.Contracts {
throw new ArgumentException("fromInclusive must be less than or equal to toExclusive.");
#endif
if (predicate == null)
- throw new ArgumentNullException("predicate");
+ throw new ArgumentNullException(nameof(predicate));
Contract.EndContractBlock();
for (int i = fromInclusive; i < toExclusive; i++)
@@ -679,9 +680,9 @@ namespace System.Diagnostics.Contracts {
public static bool ForAll<T>(IEnumerable<T> collection, Predicate<T> predicate)
{
if (collection == null)
- throw new ArgumentNullException("collection");
+ throw new ArgumentNullException(nameof(collection));
if (predicate == null)
- throw new ArgumentNullException("predicate");
+ throw new ArgumentNullException(nameof(predicate));
Contract.EndContractBlock();
foreach (T t in collection)
@@ -716,7 +717,7 @@ namespace System.Diagnostics.Contracts {
throw new ArgumentException("fromInclusive must be less than or equal to toExclusive.");
#endif
if (predicate == null)
- throw new ArgumentNullException("predicate");
+ throw new ArgumentNullException(nameof(predicate));
Contract.EndContractBlock();
for (int i = fromInclusive; i < toExclusive; i++)
@@ -740,9 +741,9 @@ namespace System.Diagnostics.Contracts {
public static bool Exists<T>(IEnumerable<T> collection, Predicate<T> predicate)
{
if (collection == null)
- throw new ArgumentNullException("collection");
+ throw new ArgumentNullException(nameof(collection));
if (predicate == null)
- throw new ArgumentNullException("predicate");
+ throw new ArgumentNullException(nameof(predicate));
Contract.EndContractBlock();
foreach (T t in collection)
@@ -805,7 +806,6 @@ namespace System.Diagnostics.Contracts {
[CLSCompliant(false)]
[Pure]
[ContractRuntimeIgnored]
- [SecurityCritical]
#if FEATURE_RELIABILITY_CONTRACTS
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
#endif
@@ -852,7 +852,6 @@ namespace System.Diagnostics.Contracts {
[CLSCompliant(false)]
[Pure]
[ContractRuntimeIgnored]
- [SecurityCritical]
#if FEATURE_RELIABILITY_CONTRACTS
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
#endif
diff --git a/src/mscorlib/src/System/Diagnostics/Contracts/ContractsBCL.cs b/src/mscorlib/src/System/Diagnostics/Contracts/ContractsBCL.cs
index 804318e702..d5e3f29e6c 100644
--- a/src/mscorlib/src/System/Diagnostics/Contracts/ContractsBCL.cs
+++ b/src/mscorlib/src/System/Diagnostics/Contracts/ContractsBCL.cs
@@ -51,7 +51,6 @@ namespace System.Diagnostics.Contracts {
/// This method is used internally to trigger a failure indicating to the "programmer" that he is using the interface incorrectly.
/// It is NEVER used to indicate failure of actual contracts at runtime.
/// </summary>
- [SecuritySafeCritical]
static partial void AssertMustUseRewriter(ContractFailureKind kind, String contractKind)
{
if (_assertingMustUseRewriter)
@@ -99,7 +98,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), "failureKind");
+ throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", failureKind), nameof(failureKind));
Contract.EndContractBlock();
// displayMessage == null means: yes we handled it. Otherwise it is the localized failure message
@@ -121,18 +120,14 @@ namespace System.Diagnostics.Contracts {
/// </summary>
public static event EventHandler<ContractFailedEventArgs> ContractFailed {
#if FEATURE_UNTRUSTED_CALLERS
- [SecurityCritical]
#if FEATURE_LINK_DEMAND
- [SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)]
#endif
#endif
add {
System.Runtime.CompilerServices.ContractHelper.InternalContractFailed += value;
}
#if FEATURE_UNTRUSTED_CALLERS
- [SecurityCritical]
#if FEATURE_LINK_DEMAND
- [SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)]
#endif
#endif
remove {
@@ -176,9 +171,7 @@ namespace System.Diagnostics.Contracts {
}
#if FEATURE_UNTRUSTED_CALLERS
- [SecurityCritical]
#if FEATURE_LINK_DEMAND
- [SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)]
#endif
#endif
public void SetHandled()
@@ -191,9 +184,7 @@ namespace System.Diagnostics.Contracts {
}
#if FEATURE_UNTRUSTED_CALLERS
- [SecurityCritical]
#if FEATURE_LINK_DEMAND
- [SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)]
#endif
#endif
public void SetUnwind()
@@ -243,9 +234,7 @@ namespace System.Diagnostics.Contracts {
}
#if FEATURE_UNTRUSTED_CALLERS && FEATURE_SERIALIZATION
- [SecurityCritical]
#if FEATURE_LINK_DEMAND && FEATURE_SERIALIZATION
- [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
#endif // FEATURE_LINK_DEMAND
#endif // FEATURE_UNTRUSTED_CALLERS
public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
@@ -284,7 +273,6 @@ namespace System.Runtime.CompilerServices
internal static event EventHandler<ContractFailedEventArgs> InternalContractFailed
{
#if FEATURE_UNTRUSTED_CALLERS
- [SecurityCritical]
#endif
add {
// Eagerly prepare each event handler _marked with a reliability contract_, to
@@ -301,7 +289,6 @@ namespace System.Runtime.CompilerServices
}
}
#if FEATURE_UNTRUSTED_CALLERS
- [SecurityCritical]
#endif
remove {
lock (lockObject)
@@ -326,12 +313,11 @@ namespace System.Runtime.CompilerServices
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
[System.Diagnostics.DebuggerNonUserCode]
#if FEATURE_RELIABILITY_CONTRACTS
- [SecuritySafeCritical]
#endif
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), "failureKind");
+ throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", failureKind), nameof(failureKind));
Contract.EndContractBlock();
string returnValue;
@@ -361,10 +347,6 @@ namespace System.Runtime.CompilerServices
}
if (eventArgs.Unwind)
{
-#if !FEATURE_CORECLR
- if (Environment.IsCLRHosted)
- TriggerCodeContractEscalationPolicy(failureKind, displayMessage, conditionText, innerException);
-#endif
// unwind
if (innerException == null) { innerException = eventArgs.thrownDuringHandler; }
throw new ContractException(failureKind, displayMessage, userMessage, conditionText, innerException);
@@ -393,9 +375,6 @@ namespace System.Runtime.CompilerServices
[SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "kind")]
[SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "innerException")]
[System.Diagnostics.DebuggerNonUserCode]
-#if FEATURE_UNTRUSTED_CALLERS && !FEATURE_CORECLR
- [SecuritySafeCritical]
-#endif
static partial void TriggerFailureImplementation(ContractFailureKind kind, String displayMessage, String userMessage, String conditionText, Exception innerException)
{
// If we're here, our intent is to pop up a dialog box (if we can). For developers
@@ -403,21 +382,12 @@ namespace System.Runtime.CompilerServices
// hosted in Internet Explorer, the assert window is great. If we cannot
// pop up a dialog box, throw an exception (consider a library compiled with
// "Assert On Failure" but used in a process that can't pop up asserts, like an
- // NT Service). For the CLR hosted by server apps like SQL or Exchange, we should
- // trigger escalation policy.
-#if !FEATURE_CORECLR
- if (Environment.IsCLRHosted)
- {
- TriggerCodeContractEscalationPolicy(kind, displayMessage, conditionText, innerException);
- // Hosts like SQL may choose to abort the thread, so we will not get here in all cases.
- // But if the host's chosen action was to throw an exception, we should throw an exception
- // here (which is easier to do in managed code with the right parameters).
- throw new ContractException(kind, displayMessage, userMessage, conditionText, innerException);
- }
-#endif // !FEATURE_CORECLR
+ // NT Service).
+
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));
@@ -494,28 +464,6 @@ namespace System.Runtime.CompilerServices
return failureMessage;
}
}
-
-#if !FEATURE_CORECLR
- // Will trigger escalation policy, if hosted and the host requested us to do something (such as
- // abort the thread or exit the process). Starting in Dev11, for hosted apps the default behavior
- // is to throw an exception.
- // Implementation notes:
- // We implement our default behavior of throwing an exception by simply returning from our native
- // method inside the runtime and falling through to throw an exception.
- // We must call through this method before calling the method on the Environment class
- // because our security team does not yet support SecuritySafeCritical on P/Invoke methods.
- // Note this can be called in the context of throwing another exception (EnsuresOnThrow).
- [SecuritySafeCritical]
- [DebuggerNonUserCode]
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- private static void TriggerCodeContractEscalationPolicy(ContractFailureKind failureKind, String message, String conditionText, Exception innerException)
- {
- String exceptionAsString = null;
- if (innerException != null)
- exceptionAsString = innerException.ToString();
- Environment.TriggerCodeContractFailure(failureKind, message, conditionText, exceptionAsString);
- }
-#endif // !FEATURE_CORECLR
}
} // namespace System.Runtime.CompilerServices
diff --git a/src/mscorlib/src/System/Diagnostics/Debugger.cs b/src/mscorlib/src/System/Diagnostics/Debugger.cs
index 339c89eecf..8ebbc0a354 100644
--- a/src/mscorlib/src/System/Diagnostics/Debugger.cs
+++ b/src/mscorlib/src/System/Diagnostics/Debugger.cs
@@ -32,7 +32,6 @@ 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.
- [System.Security.SecuritySafeCritical] // auto-generated
public static void Break()
{
if (!Debugger.IsAttached)
@@ -61,7 +60,6 @@ namespace System.Diagnostics
BreakInternal();
}
- [System.Security.SecuritySafeCritical] // auto-generated
static void BreakCanThrow()
{
if (!Debugger.IsAttached)
@@ -75,14 +73,12 @@ namespace System.Diagnostics
BreakInternal();
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void BreakInternal();
// Launch launches & attaches a debugger to the process. If a debugger is already attached,
// nothing happens.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public static bool Launch()
{
if (Debugger.IsAttached)
@@ -147,7 +143,6 @@ namespace System.Diagnostics
}
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool LaunchInternal();
@@ -155,7 +150,6 @@ namespace System.Diagnostics
//
public static extern bool IsAttached
{
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
get;
}
@@ -173,20 +167,17 @@ namespace System.Diagnostics
// Posts a message for the attached debugger. If there is no
// debugger attached, has no effect. The debugger may or may not
// report the message depending on its settings.
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void Log(int level, String category, String message);
// Checks to see if an attached debugger has logging enabled
//
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern bool IsLogging();
// Posts a custom notification for the attached debugger. If there is no
// debugger attached, has no effect. The debugger may or may not
// report the notification depending on its settings.
- [System.Security.SecuritySafeCritical] // auto-generated
[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 6adcf34eda..e75b653a0b 100644
--- a/src/mscorlib/src/System/Diagnostics/DebuggerAttributes.cs
+++ b/src/mscorlib/src/System/Diagnostics/DebuggerAttributes.cs
@@ -142,7 +142,7 @@ namespace System.Diagnostics {
public DebuggerBrowsableAttribute(DebuggerBrowsableState state)
{
if( state < DebuggerBrowsableState.Never || state > DebuggerBrowsableState.RootHidden)
- throw new ArgumentOutOfRangeException("state");
+ throw new ArgumentOutOfRangeException(nameof(state));
Contract.EndContractBlock();
this.state = state;
@@ -166,7 +166,7 @@ namespace System.Diagnostics {
public DebuggerTypeProxyAttribute(Type type)
{
if (type == null) {
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
}
Contract.EndContractBlock();
@@ -186,7 +186,7 @@ namespace System.Diagnostics {
{
set {
if( value == null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
@@ -257,7 +257,7 @@ namespace System.Diagnostics {
{
set {
if( value == null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
@@ -302,7 +302,7 @@ namespace System.Diagnostics {
public DebuggerVisualizerAttribute(string visualizerTypeName, Type visualizerObjectSource)
{
if (visualizerObjectSource == null) {
- throw new ArgumentNullException("visualizerObjectSource");
+ throw new ArgumentNullException(nameof(visualizerObjectSource));
}
Contract.EndContractBlock();
this.visualizerName = visualizerTypeName;
@@ -311,7 +311,7 @@ namespace System.Diagnostics {
public DebuggerVisualizerAttribute(Type visualizer)
{
if (visualizer == null) {
- throw new ArgumentNullException("visualizer");
+ throw new ArgumentNullException(nameof(visualizer));
}
Contract.EndContractBlock();
this.visualizerName = visualizer.AssemblyQualifiedName;
@@ -319,10 +319,10 @@ namespace System.Diagnostics {
public DebuggerVisualizerAttribute(Type visualizer, Type visualizerObjectSource)
{
if (visualizer == null) {
- throw new ArgumentNullException("visualizer");
+ throw new ArgumentNullException(nameof(visualizer));
}
if (visualizerObjectSource == null) {
- throw new ArgumentNullException("visualizerObjectSource");
+ throw new ArgumentNullException(nameof(visualizerObjectSource));
}
Contract.EndContractBlock();
this.visualizerName = visualizer.AssemblyQualifiedName;
@@ -331,7 +331,7 @@ namespace System.Diagnostics {
public DebuggerVisualizerAttribute(Type visualizer, string visualizerObjectSourceTypeName)
{
if (visualizer == null) {
- throw new ArgumentNullException("visualizer");
+ throw new ArgumentNullException(nameof(visualizer));
}
Contract.EndContractBlock();
this.visualizerName = visualizer.AssemblyQualifiedName;
@@ -356,7 +356,7 @@ namespace System.Diagnostics {
{
set {
if( value == null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/ActivityTracker.cs b/src/mscorlib/src/System/Diagnostics/Eventing/ActivityTracker.cs
index a7124a26ff..1a1f5fa2c0 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/ActivityTracker.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/ActivityTracker.cs
@@ -72,7 +72,7 @@ namespace System.Diagnostics.Tracing
}
- Contract.Assert((options & EventActivityOptions.Disable) == 0);
+ Debug.Assert((options & EventActivityOptions.Disable) == 0);
var currentActivity = m_current.Value;
var fullActivityName = NormalizeActivityName(providerName, activityName, task);
@@ -191,7 +191,7 @@ namespace System.Diagnostics.Tracing
else
{
orphan.m_stopped = 1;
- Contract.Assert(orphan.m_stopped != 0);
+ Debug.Assert(orphan.m_stopped != 0);
}
orphan = orphan.m_creator;
}
@@ -221,7 +221,6 @@ namespace System.Diagnostics.Tracing
/// <summary>
/// Turns on activity tracking. It is sticky, once on it stays on (race issues otherwise)
/// </summary>
- [System.Security.SecuritySafeCritical]
public void Enable()
{
if (m_current == null)
@@ -366,7 +365,6 @@ namespace System.Diagnostics.Tracing
/// 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>
- [System.Security.SecuritySafeCritical]
private unsafe void CreateActivityPathGuid(out Guid idRet, out int activityPathGuidOffset)
{
fixed (Guid* outPtr = &idRet)
@@ -403,7 +401,6 @@ namespace System.Diagnostics.Tracing
/// 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>
- [System.Security.SecurityCritical]
private unsafe void CreateOverflowGuid(Guid* outPtr)
{
// Search backwards for an ancestor that has sufficient space to put the ID.
@@ -452,7 +449,6 @@ namespace System.Diagnostics.Tracing
/// 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
- [System.Security.SecurityCritical]
private static unsafe int AddIdToGuid(Guid* outPtr, int whereToAddId, uint id, bool overflow = false)
{
byte* ptr = (byte*)outPtr;
@@ -526,11 +522,10 @@ namespace System.Diagnostics.Tracing
/// 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>
- [System.Security.SecurityCritical]
private static unsafe void WriteNibble(ref byte* ptr, byte* endPtr, uint value)
{
- Contract.Assert(0 <= value && value < 16);
- Contract.Assert(ptr < endPtr);
+ Debug.Assert(0 <= value && value < 16);
+ Debug.Assert(ptr < endPtr);
if (*ptr != 0)
*ptr++ |= (byte)value;
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/EventProvider.cs b/src/mscorlib/src/System/Diagnostics/Eventing/EventProvider.cs
index 6ea8d98d92..ce0fcb6acb 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/EventProvider.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/EventProvider.cs
@@ -74,7 +74,6 @@ namespace System.Diagnostics.Tracing
private static bool m_setInformationMissing;
- [SecurityCritical]
UnsafeNativeMethods.ManifestEtw.EtwEnableCallback m_etwCallback; // Trace Callback function
private long m_regHandle; // Trace Registration Handle
private byte m_level; // Tracing Level
@@ -128,7 +127,6 @@ namespace System.Diagnostics.Tracing
// <SatisfiesLinkDemand Name="Win32Exception..ctor(System.Int32)" />
// <ReferencesCritical Name="Method: EtwEnableCallBack(Guid&, Int32, Byte, Int64, Int64, Void*, Void*):Void" Ring="1" />
// </SecurityKernel>
- [System.Security.SecurityCritical]
internal unsafe void Register(Guid providerGuid)
{
m_providerId = providerGuid;
@@ -157,7 +155,6 @@ namespace System.Diagnostics.Tracing
// <SecurityKernel Critical="True" TreatAsSafe="Does not expose critical resource" Ring="1">
// <ReferencesCritical Name="Method: Deregister():Void" Ring="1" />
// </SecurityKernel>
- [System.Security.SecuritySafeCritical]
protected virtual void Dispose(bool disposing)
{
//
@@ -175,16 +172,31 @@ namespace System.Diagnostics.Tracing
// Disable the provider.
m_enabled = false;
- // Do most of the work under a lock to avoid shutdown race.
+ // Do most of the work under a lock to avoid shutdown race.
+
+ long registrationHandle = 0;
lock (EventListener.EventListenersLock)
{
// Double check
if (m_disposed)
return;
- Deregister();
+ 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>
@@ -201,33 +213,10 @@ namespace System.Diagnostics.Tracing
Dispose(false);
}
- /// <summary>
- /// This method un-registers from ETW.
- /// </summary>
- // <SecurityKernel Critical="True" Ring="0">
- // <CallsSuppressUnmanagedCode Name="UnsafeNativeMethods.ManifestEtw.EventUnregister(System.Int64):System.Int32" />
- // </SecurityKernel>
- // TODO Check return code from UnsafeNativeMethods.ManifestEtw.EventUnregister
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", MessageId = "Microsoft.Win32.UnsafeNativeMethods.ManifestEtw.EventUnregister(System.Int64)"), System.Security.SecurityCritical]
- private unsafe void Deregister()
- {
- //
- // Unregister from ETW using the RegHandle saved from
- // the register call.
- //
-
- if (m_regHandle != 0)
- {
- EventUnregister();
- m_regHandle = 0;
- }
- }
-
// <SecurityKernel Critical="True" Ring="0">
// <UsesUnsafeCode Name="Parameter filterData of type: Void*" />
// <UsesUnsafeCode Name="Parameter callbackContext of type: Void*" />
// </SecurityKernel>
- [System.Security.SecurityCritical]
unsafe void EtwEnableCallBack(
[In] ref System.Guid sourceId,
[In] int controlCode,
@@ -348,7 +337,6 @@ namespace System.Diagnostics.Tracing
/// 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>
- [System.Security.SecuritySafeCritical]
private List<Tuple<SessionInfo, bool>> GetSessions()
{
List<SessionInfo> liveSessionList = null;
@@ -424,7 +412,6 @@ namespace System.Diagnostics.Tracing
/// 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>
- [System.Security.SecurityCritical]
private unsafe void GetSessionInfo(Action<int, long> action)
{
// We wish the EventSource package to be legal for Windows Store applications.
@@ -470,7 +457,7 @@ namespace System.Diagnostics.Tracing
}
if (providerInstance->NextOffset == 0)
break;
- Contract.Assert(0 <= providerInstance->NextOffset && providerInstance->NextOffset < buffSize);
+ Debug.Assert(0 <= providerInstance->NextOffset && providerInstance->NextOffset < buffSize);
var structBase = (byte*)providerInstance;
providerInstance = (UnsafeNativeMethods.ManifestEtw.TRACE_PROVIDER_INSTANCE_INFO*)&structBase[providerInstance->NextOffset];
}
@@ -552,7 +539,6 @@ namespace System.Diagnostics.Tracing
/// 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>
- [System.Security.SecurityCritical]
private unsafe bool GetDataFromController(int etwSessionId,
UnsafeNativeMethods.ManifestEtw.EVENT_FILTER_DESCRIPTOR* filterData, out ControllerCommand command, out byte[] data, out int dataStart)
{
@@ -685,7 +671,6 @@ namespace System.Diagnostics.Tracing
// <UsesUnsafeCode Name="Parameter dataDescriptor of type: EventData*" />
// <UsesUnsafeCode Name="Parameter dataBuffer of type: Byte*" />
// </SecurityKernel>
- [System.Security.SecurityCritical]
private static unsafe object EncodeObject(ref object data, ref EventData* dataDescriptor, ref byte* dataBuffer, ref uint totalEventSize)
/*++
@@ -934,7 +919,6 @@ namespace System.Diagnostics.Tracing
// </SecurityKernel>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "Performance-critical code")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference")]
- [System.Security.SecurityCritical]
internal unsafe bool WriteEvent(ref EventDescriptor eventDescriptor, Guid* activityID, Guid* childActivityID, params object[] eventPayload)
{
int status = 0;
@@ -1131,13 +1115,12 @@ namespace System.Diagnostics.Tracing
// <CallsSuppressUnmanagedCode Name="UnsafeNativeMethods.ManifestEtw.EventWrite(System.Int64,EventDescriptor&,System.UInt32,System.Void*):System.UInt32" />
// </SecurityKernel>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference")]
- [System.Security.SecurityCritical]
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
- Contract.Assert((EventOpcode)eventDescriptor.Opcode == EventOpcode.Send ||
+ Debug.Assert((EventOpcode)eventDescriptor.Opcode == EventOpcode.Send ||
(EventOpcode)eventDescriptor.Opcode == EventOpcode.Receive ||
(EventOpcode)eventDescriptor.Opcode == EventOpcode.Start ||
(EventOpcode)eventDescriptor.Opcode == EventOpcode.Stop);
@@ -1154,7 +1137,6 @@ namespace System.Diagnostics.Tracing
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference")]
- [System.Security.SecurityCritical]
internal unsafe bool WriteEventRaw(
ref EventDescriptor eventDescriptor,
Guid* activityID,
@@ -1183,7 +1165,6 @@ namespace System.Diagnostics.Tracing
// 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).
- [SecurityCritical]
private unsafe uint EventRegister(ref Guid providerId, UnsafeNativeMethods.ManifestEtw.EtwEnableCallback enableCallback)
{
m_providerId = providerId;
@@ -1191,12 +1172,9 @@ namespace System.Diagnostics.Tracing
return UnsafeNativeMethods.ManifestEtw.EventRegister(ref providerId, enableCallback, null, ref m_regHandle);
}
- [SecurityCritical]
- private uint EventUnregister()
+ private uint EventUnregister(long registrationHandle)
{
- uint status = UnsafeNativeMethods.ManifestEtw.EventUnregister(m_regHandle);
- m_regHandle = 0;
- return status;
+ return UnsafeNativeMethods.ManifestEtw.EventUnregister(registrationHandle);
}
static int[] nibblebits = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
@@ -1209,7 +1187,7 @@ namespace System.Diagnostics.Tracing
}
private static int bitindex(uint n)
{
- Contract.Assert(bitcount(n) == 1);
+ Debug.Assert(bitcount(n) == 1);
int idx = 0;
while ((n & (1 << idx)) == 0)
idx++;
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/EventSource.cs b/src/mscorlib/src/System/Diagnostics/Eventing/EventSource.cs
index 8c2edfdec2..aa0d8d72d1 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/EventSource.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/EventSource.cs
@@ -529,7 +529,6 @@ namespace System.Diagnostics.Tracing
/// </summary>
internal static Guid InternalCurrentThreadActivityId
{
- [System.Security.SecurityCritical]
get
{
Guid retval = CurrentThreadActivityId;
@@ -543,12 +542,11 @@ namespace System.Diagnostics.Tracing
internal static Guid FallbackActivityId
{
- [System.Security.SecurityCritical]
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),
@@ -608,7 +606,7 @@ namespace System.Diagnostics.Tracing
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;
@@ -706,7 +704,7 @@ namespace System.Diagnostics.Tracing
return;
}
-
+
/// <summary>
/// This method is called when the eventSource is updated by the controller.
/// </summary>
@@ -714,7 +712,6 @@ namespace System.Diagnostics.Tracing
#pragma warning disable 1591
// optimized for common signatures (no args)
- [SecuritySafeCritical]
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
protected unsafe void WriteEvent(int eventId)
{
@@ -722,7 +719,6 @@ namespace System.Diagnostics.Tracing
}
// optimized for common signatures (ints)
- [SecuritySafeCritical]
[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)
{
@@ -735,7 +731,6 @@ namespace System.Diagnostics.Tracing
}
}
- [SecuritySafeCritical]
[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)
{
@@ -750,7 +745,6 @@ namespace System.Diagnostics.Tracing
}
}
- [SecuritySafeCritical]
[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)
{
@@ -768,7 +762,6 @@ namespace System.Diagnostics.Tracing
}
// optimized for common signatures (longs)
- [SecuritySafeCritical]
[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)
{
@@ -781,7 +774,6 @@ namespace System.Diagnostics.Tracing
}
}
- [SecuritySafeCritical]
[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)
{
@@ -796,7 +788,6 @@ namespace System.Diagnostics.Tracing
}
}
- [SecuritySafeCritical]
[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)
{
@@ -814,7 +805,6 @@ namespace System.Diagnostics.Tracing
}
// optimized for common signatures (strings)
- [SecuritySafeCritical]
[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)
{
@@ -831,7 +821,6 @@ namespace System.Diagnostics.Tracing
}
}
- [SecuritySafeCritical]
[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)
{
@@ -852,7 +841,6 @@ namespace System.Diagnostics.Tracing
}
}
- [SecuritySafeCritical]
[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)
{
@@ -878,7 +866,6 @@ namespace System.Diagnostics.Tracing
}
// optimized for common signatures (string and ints)
- [SecuritySafeCritical]
[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)
{
@@ -897,7 +884,6 @@ namespace System.Diagnostics.Tracing
}
}
- [SecuritySafeCritical]
[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)
{
@@ -919,7 +905,6 @@ namespace System.Diagnostics.Tracing
}
// optimized for common signatures (string and longs)
- [SecuritySafeCritical]
[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)
{
@@ -939,7 +924,6 @@ namespace System.Diagnostics.Tracing
}
// optimized for common signatures (long and string)
- [SecuritySafeCritical]
[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)
{
@@ -959,7 +943,6 @@ namespace System.Diagnostics.Tracing
}
// optimized for common signatures (int and string)
- [SecuritySafeCritical]
[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)
{
@@ -977,70 +960,68 @@ namespace System.Diagnostics.Tracing
}
}
}
-
- [SecuritySafeCritical]
- [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);
- }
- }
- }
- }
-
- [SecuritySafeCritical]
- [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);
- }
- }
- }
- }
+
+ [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
@@ -1067,7 +1048,6 @@ namespace System.Diagnostics.Tracing
/// <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>
- [SecurityCritical]
internal unsafe void SetMetadata(byte* pointer, int size, int reserved)
{
this.m_Ptr = (long)(ulong)(UIntPtr)pointer;
@@ -1109,7 +1089,6 @@ namespace System.Diagnostics.Tracing
/// }
/// </code>
/// </remarks>
- [SecurityCritical]
[CLSCompliant(false)]
protected unsafe void WriteEventCore(int eventId, int eventDataCount, EventSource.EventData* data)
{
@@ -1141,7 +1120,6 @@ namespace System.Diagnostics.Tracing
/// }
/// </code>
/// </remarks>
- [SecurityCritical]
[CLSCompliant(false)]
protected unsafe void WriteEventWithRelatedActivityIdCore(int eventId, Guid* relatedActivityId, int eventDataCount, EventSource.EventData* data)
{
@@ -1149,36 +1127,37 @@ namespace System.Diagnostics.Tracing
{
try
{
- Contract.Assert(m_eventData != null); // You must have initialized this if you enabled the source.
+ 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);
-#if FEATURE_MANAGED_ETW
- if (m_eventData[eventId].EnabledForETW)
+ 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))
{
- 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)
{
- 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;
+ 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().
@@ -1298,7 +1277,6 @@ namespace System.Diagnostics.Tracing
/// 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>
- [SecuritySafeCritical]
[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)
{
@@ -1313,7 +1291,6 @@ namespace System.Diagnostics.Tracing
/// 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>
- [SecuritySafeCritical]
protected unsafe void WriteEventWithRelatedActivityId(int eventId, Guid relatedActivityId, params object[] args)
{
WriteEventVarargs(eventId, &relatedActivityId, args);
@@ -1380,7 +1357,7 @@ namespace System.Diagnostics.Tracing
#if FEATURE_ACTIVITYSAMPLING
internal void WriteStringToListener(EventListener listener, string msg, SessionMask m)
{
- Contract.Assert(listener == null || (uint)m == (uint)SessionMask.FromId(0));
+ Debug.Assert(listener == null || (uint)m == (uint)SessionMask.FromId(0));
if (m_eventSourceEnabled)
{
@@ -1390,18 +1367,18 @@ namespace System.Diagnostics.Tracing
}
else
{
- List<object> arg = new List<object>();
- arg.Add(msg);
EventWrittenEventArgs eventCallbackArgs = new EventWrittenEventArgs(this);
eventCallbackArgs.EventId = 0;
- eventCallbackArgs.Payload = new ReadOnlyCollection<object>(arg);
+ 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
- [SecurityCritical]
private unsafe void WriteEventRaw(
string eventName,
ref EventDescriptor eventDescriptor,
@@ -1443,7 +1420,6 @@ namespace System.Diagnostics.Tracing
/// member, and any future access to the "Log" would throw the cached exception).
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "guid")]
- [SecuritySafeCritical]
private unsafe void Initialize(Guid eventSourceGuid, string eventSourceName, string[] traits)
{
try
@@ -1500,7 +1476,7 @@ namespace System.Diagnostics.Tracing
#endif
{
int setInformationResult;
- System.Runtime.InteropServices.GCHandle metadataHandle =
+ System.Runtime.InteropServices.GCHandle metadataHandle =
System.Runtime.InteropServices.GCHandle.Alloc(this.providerMetadata, System.Runtime.InteropServices.GCHandleType.Pinned);
IntPtr providerMetadata = metadataHandle.AddrOfPinnedObject();
@@ -1513,7 +1489,7 @@ namespace System.Diagnostics.Tracing
}
#endif // FEATURE_MANAGED_ETW
- Contract.Assert(!m_eventSourceEnabled); // We can't be enabled until we are completely initted.
+ 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;
}
@@ -1742,7 +1718,6 @@ namespace System.Diagnostics.Tracing
return new Guid(bytes);
}
- [SecurityCritical]
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
@@ -1754,7 +1729,7 @@ namespace System.Diagnostics.Tracing
Type dataType = GetDataType(m_eventData[eventId], parameterId);
- Again:
+ Again:
if (dataType == typeof(IntPtr))
{
return *((IntPtr*)dataPointer);
@@ -1889,14 +1864,13 @@ namespace System.Diagnostics.Tracing
return dispatcher;
}
- [SecurityCritical]
private unsafe void WriteEventVarargs(int eventId, Guid* childActivityID, object[] args)
{
if (m_eventSourceEnabled)
{
try
{
- Contract.Assert(m_eventData != null); // You must have initialized this if you enabled the source.
+ 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);
@@ -1916,33 +1890,34 @@ namespace System.Diagnostics.Tracing
}
LogEventArgsMismatches(m_eventData[eventId].Parameters, args);
-#if FEATURE_MANAGED_ETW
- if (m_eventData[eventId].EnabledForETW)
+
+ 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))
{
- 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)
{
- 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;
+ 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;
@@ -2059,7 +2034,6 @@ namespace System.Diagnostics.Tracing
}
}
- [SecurityCritical]
unsafe private object[] SerializeEventArgs(int eventId, object[] args)
{
TraceLoggingEventTypes eventTypes = m_eventData[eventId].TraceLoggingEventTypes;
@@ -2120,9 +2094,9 @@ namespace System.Diagnostics.Tracing
private int GetParamLenghtIncludingByteArray(ParameterInfo[] parameters)
{
int sum = 0;
- foreach(ParameterInfo info in parameters)
+ foreach (ParameterInfo info in parameters)
{
- if(info.ParameterType == typeof(byte[]))
+ if (info.ParameterType == typeof(byte[]))
{
sum += 2;
}
@@ -2135,7 +2109,6 @@ namespace System.Diagnostics.Tracing
return sum;
}
- [SecurityCritical]
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
@@ -2159,7 +2132,6 @@ namespace System.Diagnostics.Tracing
}
// helper for writing to all EventListeners attached the current eventSource.
- [SecurityCritical]
unsafe private void WriteToAllListeners(int eventId, Guid* childActivityID, params object[] args)
{
EventWrittenEventArgs eventCallbackArgs = new EventWrittenEventArgs(this);
@@ -2173,13 +2145,12 @@ namespace System.Diagnostics.Tracing
DispatchToAllListeners(eventId, childActivityID, eventCallbackArgs);
}
- [SecurityCritical]
private unsafe void DispatchToAllListeners(int eventId, Guid* childActivityID, EventWrittenEventArgs eventCallbackArgs)
{
Exception lastThrownException = null;
for (EventDispatcher dispatcher = m_Dispatchers; dispatcher != null; dispatcher = dispatcher.m_Next)
{
- Contract.Assert(dispatcher.m_EventEnabled != null);
+ Debug.Assert(dispatcher.m_EventEnabled != null);
if (eventId == -1 || dispatcher.m_EventEnabled[eventId])
{
#if FEATURE_ACTIVITYSAMPLING
@@ -2214,8 +2185,7 @@ namespace System.Diagnostics.Tracing
throw new EventSourceException(lastThrownException);
}
}
-
- [SecuritySafeCritical]
+
[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)
{
@@ -2310,7 +2280,6 @@ namespace System.Diagnostics.Tracing
}
#if FEATURE_ACTIVITYSAMPLING
- [SecurityCritical]
unsafe private SessionMask GetEtwSessionMask(int eventId, Guid* childActivityID)
{
SessionMask etwSessions = new SessionMask();
@@ -2429,9 +2398,9 @@ namespace System.Diagnostics.Tracing
try
{
m_EventSourceExceptionRecurenceCount++;
-
+
string errorPrefix = "EventSourceException";
- if(eventName != null)
+ if (eventName != null)
{
errorPrefix += " while processing event \"" + eventName + "\"";
}
@@ -2473,7 +2442,7 @@ namespace System.Diagnostics.Tracing
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.Receive &&
(EventOpcode)eventData.Descriptor.Opcode != EventOpcode.Start)
{
ThrowEventSourceException(eventName);
@@ -2545,7 +2514,7 @@ namespace System.Diagnostics.Tracing
public TraceLoggingEventTypes TraceLoggingEventTypes;
public EventActivityOptions ActivityOptions;
-
+
#if PROJECTN
public EventParameterType[] ParameterTypes;
#endif
@@ -2611,7 +2580,7 @@ namespace System.Diagnostics.Tracing
{
// PRECONDITION: We should be holding the EventListener.EventListenersLock
// We defer commands until we are completely inited. This allows error messages to be sent.
- Contract.Assert(m_completelyInited);
+ Debug.Assert(m_completelyInited);
#if FEATURE_MANAGED_ETW
if (m_provider == null) // If we failed to construct
@@ -2623,7 +2592,7 @@ namespace System.Diagnostics.Tracing
try
{
EnsureDescriptorsInitialized();
- Contract.Assert(m_eventData != null);
+ Debug.Assert(m_eventData != null);
// Find the per-EventSource dispatcher corresponding to registered dispatcher
commandArgs.dispatcher = GetDispatcher(commandArgs.listener);
@@ -2682,7 +2651,7 @@ namespace System.Diagnostics.Tracing
// hasn't changed.
// sesisonId = SessionMask.MAX when one of the legacy ETW sessions changed
// 0 <= perEventSourceSessionId < SessionMask.MAX for activity-tracing aware sessions
- Contract.Assert(commandArgs.perEventSourceSessionId >= -1 && commandArgs.perEventSourceSessionId <= SessionMask.MAX);
+ Debug.Assert(commandArgs.perEventSourceSessionId >= -1 && commandArgs.perEventSourceSessionId <= SessionMask.MAX);
// Send the manifest if we are enabling an ETW session
if (bSessionEnable && commandArgs.dispatcher == null)
@@ -2737,7 +2706,7 @@ namespace System.Diagnostics.Tracing
// things like log messages, or test if keywords are enabled in the callback.
if (commandArgs.enable)
{
- Contract.Assert(m_eventData != null);
+ Debug.Assert(m_eventData != null);
m_eventSourceEnabled = true;
}
@@ -2825,9 +2794,9 @@ namespace System.Diagnostics.Tracing
}
// These are not used for non-update commands and thus should always be 'default' values
- // Contract.Assert(enable == true);
- // Contract.Assert(level == EventLevel.LogAlways);
- // Contract.Assert(matchAnyKeyword == EventKeywords.None);
+ // Debug.Assert(enable == true);
+ // Debug.Assert(level == EventLevel.LogAlways);
+ // Debug.Assert(matchAnyKeyword == EventKeywords.None);
this.OnEventCommand(commandArgs);
var eventCommandCallback = m_eventCommandExecuted;
@@ -3017,16 +2986,15 @@ namespace System.Diagnostics.Tracing
return false;
}
- private bool IsDisposed
+ private bool IsDisposed
{
get { return m_eventSourceDisposed; }
}
- [SecuritySafeCritical]
private void EnsureDescriptorsInitialized()
{
#if !ES_BUILD_STANDALONE
- Contract.Assert(Monitor.IsEntered(EventListener.EventListenersLock));
+ Debug.Assert(Monitor.IsEntered(EventListener.EventListenersLock));
#endif
if (m_eventData == null)
{
@@ -3042,9 +3010,9 @@ namespace System.Diagnostics.Tracing
if (eventSourceGuid.Equals(Guid.Empty) || eventSourceName == null || eventData == null || manifest == null)
{
// GetMetadata failed, so we have to set it via reflection.
- Contract.Assert(m_rawManifest == null);
+ Debug.Assert(m_rawManifest == null);
m_rawManifest = CreateManifestAndDescriptors(this.GetType(), Name, this);
- Contract.Assert(m_eventData != null);
+ Debug.Assert(m_eventData != null);
}
else
@@ -3089,7 +3057,6 @@ namespace System.Diagnostics.Tracing
// Send out the ETW manifest XML out to ETW
// Today, we only send the manifest to ETW, custom listeners don't get it.
- [SecuritySafeCritical]
private unsafe bool SendManifest(byte[] rawManifest)
{
bool success = true;
@@ -3097,7 +3064,7 @@ namespace System.Diagnostics.Tracing
if (rawManifest == null)
return false;
- Contract.Assert(!SelfDescribingEvents);
+ Debug.Assert(!SelfDescribingEvents);
#if FEATURE_MANAGED_ETW
fixed (byte* dataPtr = rawManifest)
@@ -3124,7 +3091,7 @@ namespace System.Diagnostics.Tracing
dataDescrs[1].Reserved = 0;
int chunkSize = ManifestEnvelope.MaxChunkSize;
- TRY_AGAIN_WITH_SMALLER_CHUNK_SIZE:
+ TRY_AGAIN_WITH_SMALLER_CHUNK_SIZE:
envelope.TotalChunks = (ushort)((dataLeft + (chunkSize - 1)) / chunkSize);
while (dataLeft > 0)
{
@@ -3153,10 +3120,10 @@ namespace System.Diagnostics.Tracing
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)
+ if ((envelope.ChunkNumber % 5) == 0)
Thread.Sleep(15);
}
}
@@ -3201,7 +3168,7 @@ namespace System.Diagnostics.Tracing
{
Attribute attr = null;
- Contract.Assert(data.ConstructorArguments.Count <= 1);
+ Debug.Assert(data.ConstructorArguments.Count <= 1);
if (data.ConstructorArguments.Count == 1)
{
@@ -3236,7 +3203,7 @@ namespace System.Diagnostics.Tracing
return null;
#else // ES_BUILD_PCL && PROJECTN
- throw new ArgumentException(Resources.GetResourceString("EventSource", "EventSource_PCLPlatformNotSupportedReflection"));
+ throw new ArgumentException(Resources.GetResourceString("EventSource", nameof(EventSource_PCLPlatformNotSupportedReflection)));
#endif
}
@@ -3256,8 +3223,8 @@ namespace System.Diagnostics.Tracing
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)?
+ // 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)
@@ -3488,7 +3455,7 @@ namespace System.Diagnostics.Tracing
int startEventId = eventAttribute.EventId - 1;
if (eventData != null && startEventId < eventData.Length)
{
- Contract.Assert(0 <= startEventId); // Since we reserve id 0, we know that id-1 is <= 0
+ 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?
@@ -3535,7 +3502,7 @@ namespace System.Diagnostics.Tracing
{
unchecked
{
- eventAttribute.Keywords |= (EventKeywords)manifest.GetChannelKeyword(eventAttribute.Channel, (ulong) eventAttribute.Keywords);
+ eventAttribute.Keywords |= (EventKeywords)manifest.GetChannelKeyword(eventAttribute.Channel, (ulong)eventAttribute.Keywords);
}
}
#endif
@@ -3658,7 +3625,7 @@ namespace System.Diagnostics.Tracing
}
#endif
return;
- Error:
+ Error:
manifest.ManifestError(Resources.GetResourceString("EventSource_EnumKindMismatch", staticField.Name, staticField.FieldType.Name, providerEnumKind));
}
@@ -3751,7 +3718,7 @@ namespace System.Diagnostics.Tracing
// 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....
- Contract.Assert(eventAttribute.Task != EventTask.None || eventAttribute.Opcode != EventOpcode.Info);
+ Debug.Assert(eventAttribute.Task != EventTask.None || eventAttribute.Opcode != EventOpcode.Info);
for (int idx = 0; idx < eventData.Length; ++idx)
{
// skip unused Event IDs.
@@ -3821,7 +3788,6 @@ namespace System.Diagnostics.Tracing
/// </summary>
/// <param name="method">The method to probe.</param>
/// <returns>The literal value or -1 if the value could not be determined. </returns>
- [SecuritySafeCritical]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "Switch statement is clearer than alternatives")]
static private int GetHelperCallFirstArg(MethodInfo method)
{
@@ -3840,7 +3806,7 @@ namespace System.Diagnostics.Tracing
(new ReflectionPermission(ReflectionPermissionFlag.MemberAccess)).Assert();
byte[] instrs = method.GetMethodBody().GetILAsByteArray();
int retVal = -1;
- for (int idx = 0; idx < instrs.Length; )
+ for (int idx = 0; idx < instrs.Length;)
{
switch (instrs[idx])
{
@@ -3934,7 +3900,7 @@ namespace System.Diagnostics.Tracing
goto default;
break;
default:
- /* Contract.Assert(false, "Warning: User validation code sub-optimial: Unsuported opcode " + instrs[idx] +
+ /* Debug.Assert(false, "Warning: User validation code sub-optimial: Unsuported opcode " + instrs[idx] +
" at " + idx + " in method " + method.Name); */
return -1;
}
@@ -3968,7 +3934,7 @@ namespace System.Diagnostics.Tracing
{
#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));
+ System.Diagnostics.Debugger.Log(0, null, String.Format("EventSource Error: {0}{1}", msg, Environment.NewLine));
#endif
// Send it to all listeners.
@@ -4017,7 +3983,7 @@ namespace System.Diagnostics.Tracing
{
get
{
- Contract.Assert(((m_config & EventSourceSettings.EtwManifestEventFormat) != 0) !=
+ Debug.Assert(((m_config & EventSourceSettings.EtwManifestEventFormat) != 0) !=
((m_config & EventSourceSettings.EtwSelfDescribingEventFormat) != 0));
return (m_config & EventSourceSettings.EtwSelfDescribingEventFormat) != 0;
}
@@ -4039,7 +4005,7 @@ namespace System.Diagnostics.Tracing
#if FEATURE_ACTIVITYSAMPLING
private void ReportActivitySamplingInfo(EventListener listener, SessionMask sessions)
{
- Contract.Assert(listener == null || (uint)sessions == (uint)SessionMask.FromId(0));
+ Debug.Assert(listener == null || (uint)sessions == (uint)SessionMask.FromId(0));
for (int perEventSourceSessionId = 0; perEventSourceSessionId < SessionMask.MAX; ++perEventSourceSessionId)
{
@@ -4050,7 +4016,7 @@ namespace System.Diagnostics.Tracing
if (listener == null)
{
EtwSession etwSession = m_etwSessionIdMap[perEventSourceSessionId];
- Contract.Assert(etwSession != null);
+ Debug.Assert(etwSession != null);
af = etwSession.m_activityFilter;
}
else
@@ -4090,7 +4056,7 @@ namespace System.Diagnostics.Tracing
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
@@ -4229,7 +4195,7 @@ namespace System.Diagnostics.Tracing
/// events for a particular eventSource to occur BEFORE the EventSourceCreatedCallback is issued.
/// </summary>
public event EventHandler<EventSourceCreatedEventArgs> EventSourceCreated
- {
+ {
add
{
CallBackForExistingEventSources(false, value);
@@ -4255,7 +4221,7 @@ namespace System.Diagnostics.Tracing
public EventListener()
{
// This will cause the OnEventSourceCreated callback to fire.
- CallBackForExistingEventSources(true, (obj, args) => args.EventSource.AddListener(this) );
+ CallBackForExistingEventSources(true, (obj, args) => args.EventSource.AddListener(this));
}
/// <summary>
@@ -4283,7 +4249,7 @@ namespace System.Diagnostics.Tracing
{
// Find 'this' from the s_Listeners linked list.
EventListener prev = s_Listeners;
- for (; ; )
+ for (;;)
{
EventListener cur = prev.m_Next;
if (cur == null)
@@ -4397,7 +4363,7 @@ namespace System.Diagnostics.Tracing
internal protected virtual void OnEventSourceCreated(EventSource eventSource)
{
EventHandler<EventSourceCreatedEventArgs> callBack = this._EventSourceCreated;
- if(callBack != null)
+ if (callBack != null)
{
EventSourceCreatedEventArgs args = new EventSourceCreatedEventArgs();
args.EventSource = eventSource;
@@ -4443,10 +4409,6 @@ namespace System.Diagnostics.Tracing
if (!s_EventSourceShutdownRegistered)
{
s_EventSourceShutdownRegistered = true;
-#if (!ES_BUILD_PCL && !FEATURE_CORECLR && !PROJECTN)
- AppDomain.CurrentDomain.ProcessExit += DisposeOnShutdown;
- AppDomain.CurrentDomain.DomainUnload += DisposeOnShutdown;
-#endif
}
@@ -4492,7 +4454,7 @@ namespace System.Diagnostics.Tracing
// See bug 724140 for more
private static void DisposeOnShutdown(object sender, EventArgs e)
{
- lock(EventListenersLock)
+ lock (EventListenersLock)
{
foreach (var esRef in s_EventSources)
{
@@ -4512,7 +4474,7 @@ namespace System.Diagnostics.Tracing
private static void RemoveReferencesToListenerInEventSources(EventListener listenerToRemove)
{
#if !ES_BUILD_STANDALONE
- Contract.Assert(Monitor.IsEntered(EventListener.EventListenersLock));
+ Debug.Assert(Monitor.IsEntered(EventListener.EventListenersLock));
#endif
// Foreach existing EventSource in the appdomain
foreach (WeakReference eventSourceRef in s_EventSources)
@@ -4527,12 +4489,12 @@ namespace System.Diagnostics.Tracing
{
// Remove 'listenerToRemove' from the eventSource.m_Dispatchers linked list.
EventDispatcher prev = eventSource.m_Dispatchers;
- for (; ; )
+ for (;;)
{
EventDispatcher cur = prev.m_Next;
if (cur == null)
{
- Contract.Assert(false, "EventSource did not have a registered EventListener!");
+ Debug.Assert(false, "EventSource did not have a registered EventListener!");
break;
}
if (cur.m_Listener == listenerToRemove)
@@ -4572,13 +4534,13 @@ namespace System.Diagnostics.Tracing
EventSource eventSource = eventSourceRef.Target as EventSource;
if (eventSource == null)
continue;
- Contract.Assert(eventSource.m_id == id, "Unexpected event source ID.");
+ 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)
{
- Contract.Assert(allListeners.ContainsKey(dispatcher.m_Listener), "EventSource has a listener not on the global list.");
+ Debug.Assert(allListeners.ContainsKey(dispatcher.m_Listener), "EventSource has a listener not on the global list.");
dispatcher = dispatcher.m_Next;
}
@@ -4586,9 +4548,9 @@ namespace System.Diagnostics.Tracing
foreach (EventListener listener in allListeners.Keys)
{
dispatcher = eventSource.m_Dispatchers;
- for (; ; )
+ for (;;)
{
- Contract.Assert(dispatcher != null, "Listener is not on all eventSources.");
+ Debug.Assert(dispatcher != null, "Listener is not on all eventSources.");
if (dispatcher.m_Listener == listener)
break;
dispatcher = dispatcher.m_Next;
@@ -4818,7 +4780,6 @@ namespace System.Diagnostics.Tracing
/// </summary>
public Guid ActivityId
{
- [System.Security.SecurityCritical]
get { return EventSource.CurrentThreadActivityId; }
}
@@ -4827,7 +4788,6 @@ namespace System.Diagnostics.Tracing
/// </summary>
public Guid RelatedActivityId
{
- [System.Security.SecurityCritical]
get;
internal set;
}
@@ -4848,7 +4808,7 @@ namespace System.Diagnostics.Tracing
if (m_payloadNames == null)
{
// Self described events are identified by id -1.
- Contract.Assert(EventId != -1);
+ Debug.Assert(EventId != -1);
var names = new List<string>();
foreach (var parameter in m_eventSource.m_eventData[EventId].Parameters)
@@ -4893,7 +4853,7 @@ namespace System.Diagnostics.Tracing
{
get
{
- if (EventId < 0) // TraceLogging convention EventID == -1
+ if (EventId <= 0) // TraceLogging convention EventID == -1
return m_opcode;
return (EventOpcode)m_eventSource.m_eventData[EventId].Descriptor.Opcode;
}
@@ -4906,7 +4866,7 @@ namespace System.Diagnostics.Tracing
{
get
{
- if (EventId < 0) // TraceLogging convention EventID == -1
+ if (EventId <= 0) // TraceLogging convention EventID == -1
return EventTask.None;
return (EventTask)m_eventSource.m_eventData[EventId].Descriptor.Task;
@@ -4920,20 +4880,20 @@ namespace System.Diagnostics.Tracing
{
get
{
- if (EventId < 0) // TraceLogging convention EventID == -1
+ if (EventId <= 0) // TraceLogging convention EventID == -1
return m_tags;
return m_eventSource.m_eventData[EventId].Tags;
}
}
/// <summary>
- /// Gets the message for the event.
+ /// 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
+ if (EventId <= 0) // TraceLogging convention EventID == -1
return m_message;
else
return m_eventSource.m_eventData[EventId].Message;
@@ -4953,7 +4913,7 @@ namespace System.Diagnostics.Tracing
{
get
{
- if (EventId < 0) // TraceLogging convention EventID == -1
+ if (EventId <= 0) // TraceLogging convention EventID == -1
return EventChannel.None;
return (EventChannel)m_eventSource.m_eventData[EventId].Descriptor.Channel;
}
@@ -4967,7 +4927,7 @@ namespace System.Diagnostics.Tracing
{
get
{
- if (EventId < 0) // TraceLogging convention EventID == -1
+ if (EventId <= 0) // TraceLogging convention EventID == -1
return 0;
return m_eventSource.m_eventData[EventId].Descriptor.Version;
}
@@ -4980,7 +4940,7 @@ namespace System.Diagnostics.Tracing
{
get
{
- if (EventId < 0) // TraceLogging convention EventID == -1
+ if (EventId <= 0) // TraceLogging convention EventID == -1
return m_level;
return (EventLevel)m_eventSource.m_eventData[EventId].Descriptor.Level;
}
@@ -5277,7 +5237,7 @@ namespace System.Diagnostics.Tracing
public static void DisableFilter(ref ActivityFilter filterList, EventSource source)
{
#if !ES_BUILD_STANDALONE
- Contract.Assert(Monitor.IsEntered(EventListener.EventListenersLock));
+ Debug.Assert(Monitor.IsEntered(EventListener.EventListenersLock));
#endif
if (filterList == null)
@@ -5345,7 +5305,7 @@ namespace System.Diagnostics.Tracing
string startEvents)
{
#if !ES_BUILD_STANDALONE
- Contract.Assert(Monitor.IsEntered(EventListener.EventListenersLock));
+ Debug.Assert(Monitor.IsEntered(EventListener.EventListenersLock));
#endif
// first remove all filters associated with 'source'
@@ -5432,7 +5392,6 @@ namespace System.Diagnostics.Tracing
/// If 'childActivityID' is present, it will be added to the active set if the
/// current activity is active.
/// </summary>
- [SecurityCritical]
unsafe public static bool PassesActivityFilter(
ActivityFilter filterList,
Guid* childActivityID,
@@ -5440,7 +5399,7 @@ namespace System.Diagnostics.Tracing
EventSource source,
int eventId)
{
- Contract.Assert(filterList != null && filterList.m_activeActivities != null);
+ Debug.Assert(filterList != null && filterList.m_activeActivities != null);
bool shouldBeLogged = false;
if (triggeringEvent)
{
@@ -5513,7 +5472,6 @@ namespace System.Diagnostics.Tracing
return shouldBeLogged;
}
- [System.Security.SecuritySafeCritical]
public static bool IsCurrentActivityActive(ActivityFilter filterList)
{
var activeActivities = GetActiveActivities(filterList);
@@ -5530,13 +5488,12 @@ namespace System.Diagnostics.Tracing
/// value for 'currentActivityid' is an indication tha caller has already verified
/// that the current activity is active.
/// </summary>
- [SecurityCritical]
unsafe public static void FlowActivityIfNeeded(ActivityFilter filterList, Guid* currentActivityId, Guid* childActivityID)
{
- Contract.Assert(childActivityID != null);
+ Debug.Assert(childActivityID != null);
var activeActivities = GetActiveActivities(filterList);
- Contract.Assert(activeActivities != null);
+ Debug.Assert(activeActivities != null);
// take currentActivityId == null to mean we *know* the current activity is "active"
if (currentActivityId != null && !activeActivities.ContainsKey(*currentActivityId))
@@ -5593,7 +5550,7 @@ namespace System.Diagnostics.Tracing
public void Dispose()
{
#if !ES_BUILD_STANDALONE
- Contract.Assert(Monitor.IsEntered(EventListener.EventListenersLock));
+ 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
@@ -5620,7 +5577,7 @@ namespace System.Diagnostics.Tracing
m_samplingFreq = samplingFreq;
m_next = existingFilter;
- Contract.Assert(existingFilter == null ||
+ 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
@@ -5694,10 +5651,10 @@ namespace System.Diagnostics.Tracing
private static bool EnableFilter(ref ActivityFilter filterList, EventSource source, int perEventSourceSessionId, int eventId, int samplingFreq)
{
#if !ES_BUILD_STANDALONE
- Contract.Assert(Monitor.IsEntered(EventListener.EventListenersLock));
+ Debug.Assert(Monitor.IsEntered(EventListener.EventListenersLock));
#endif
- Contract.Assert(samplingFreq > 0);
- Contract.Assert(eventId >= 0);
+ Debug.Assert(samplingFreq > 0);
+ Debug.Assert(eventId >= 0);
filterList = new ActivityFilter(source, perEventSourceSessionId, eventId, samplingFreq, filterList);
@@ -5828,7 +5785,7 @@ namespace System.Diagnostics.Tracing
public static void RemoveEtwSession(EtwSession etwSession)
{
- Contract.Assert(etwSession != null);
+ Debug.Assert(etwSession != null);
if (s_etwSessions == null || etwSession == null)
return;
@@ -5909,7 +5866,7 @@ namespace System.Diagnostics.Tracing
public static SessionMask FromId(int perEventSourceSessionId)
{
- Contract.Assert(perEventSourceSessionId < MAX);
+ Debug.Assert(perEventSourceSessionId < MAX);
return new SessionMask((uint)1 << perEventSourceSessionId);
}
@@ -5927,12 +5884,12 @@ namespace System.Diagnostics.Tracing
{
get
{
- Contract.Assert(perEventSourceSessionId < MAX);
+ Debug.Assert(perEventSourceSessionId < MAX);
return (m_mask & (1 << perEventSourceSessionId)) != 0;
}
set
{
- Contract.Assert(perEventSourceSessionId < MAX);
+ Debug.Assert(perEventSourceSessionId < MAX);
if (value) m_mask |= ((uint)1 << perEventSourceSessionId);
else m_mask &= ~((uint)1 << perEventSourceSessionId);
}
@@ -6163,7 +6120,7 @@ namespace System.Diagnostics.Tracing
private EventChannelType EventChannelToChannelType(EventChannel channel)
{
#if !ES_BUILD_STANDALONE
- Contract.Assert(channel >= EventChannel.Admin && channel <= EventChannel.Debug);
+ Debug.Assert(channel >= EventChannel.Admin && channel <= EventChannel.Debug);
#endif
return (EventChannelType)((int)channel - (int)EventChannel.Admin + (int)EventChannelType.Admin);
}
@@ -6206,8 +6163,8 @@ namespace System.Diagnostics.Tracing
#endif
public void StartEvent(string eventName, EventAttribute eventAttribute)
{
- Contract.Assert(numParams == 0);
- Contract.Assert(this.eventName == null);
+ Debug.Assert(numParams == 0);
+ Debug.Assert(this.eventName == null);
this.eventName = eventName;
numParams = 0;
byteArrArgIndices = null;
@@ -6311,7 +6268,7 @@ namespace System.Diagnostics.Tracing
// 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)
+ public ulong GetChannelKeyword(EventChannel channel, ulong channelKeyword = 0)
{
// strip off any non-channel keywords, since we are only interested in channels here.
channelKeyword &= ValidPredefinedChannelKeywords;
@@ -6560,7 +6517,7 @@ namespace System.Diagnostics.Tracing
// 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, Comparer<string>.Default);
+ ArraySortHelper<string>.IntrospectiveSort(sortedStrings, 0, sortedStrings.Length, string.Compare);
#endif
foreach (var ci in cultures)
{
@@ -6642,13 +6599,7 @@ namespace System.Diagnostics.Tracing
private static List<CultureInfo> GetSupportedCultures(ResourceManager resources)
{
var cultures = new List<CultureInfo>();
-#if !ES_BUILD_PCL && !FEATURE_CORECLR && !PROJECTN
- foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.SpecificCultures /*| CultureTypes.NeutralCultures*/))
- {
- if (resources.GetResourceSet(ci, true, false) != null)
- cultures.Add(ci);
- }
-#endif // !ES_BUILD_PCL && !FEATURE_CORECLR
+
if (!cultures.Contains(CultureInfo.CurrentUICulture))
cultures.Insert(0, CultureInfo.CurrentUICulture);
return cultures;
@@ -6701,7 +6652,7 @@ namespace System.Diagnostics.Tracing
ret = taskTab[(int)task] = eventName;
return ret;
}
-
+
private string GetOpcodeName(EventOpcode opcode, string eventName)
{
switch (opcode)
@@ -6738,12 +6689,12 @@ namespace System.Diagnostics.Tracing
}
return ret;
}
-
+
private string GetKeywords(ulong keywords, string eventName)
{
// ignore keywords associate with channels
// See ValidPredefinedChannelKeywords def for more.
- keywords &= ~ValidPredefinedChannelKeywords;
+ keywords &= ~ValidPredefinedChannelKeywords;
string ret = "";
for (ulong bit = 1; bit != 0; bit <<= 1)
@@ -6770,7 +6721,7 @@ namespace System.Diagnostics.Tracing
}
return ret;
}
-
+
private string GetTypeName(Type type)
{
if (type.IsEnum())
@@ -6779,7 +6730,7 @@ namespace System.Diagnostics.Tracing
var typeName = GetTypeName(fields[0].FieldType);
return typeName.Replace("win:Int", "win:UInt"); // ETW requires enums to be unsigned.
}
-
+
return GetTypeNameHelper(type);
}
@@ -6797,7 +6748,7 @@ namespace System.Diagnostics.Tracing
StringBuilder stringBuilder = null; // We lazily create this
int writtenSoFar = 0;
int chIdx = -1;
- for (int i = 0; ; )
+ for (int i = 0; ;)
{
if (i >= eventMessage.Length)
{
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/EventSource_CoreCLR.cs b/src/mscorlib/src/System/Diagnostics/Eventing/EventSource_CoreCLR.cs
index 00bd0b7caa..0a689efe92 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/EventSource_CoreCLR.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/EventSource_CoreCLR.cs
@@ -29,7 +29,6 @@ namespace System.Diagnostics.Tracing
/// </summary>
/// <param name="activityId">A Guid that represents the new activity with which to mark
/// the current thread</param>
- [System.Security.SecuritySafeCritical]
public static void SetCurrentThreadActivityId(Guid activityId)
{
if (TplEtwProvider.Log != null)
@@ -80,7 +79,6 @@ namespace System.Diagnostics.Tracing
/// the current thread</param>
/// <param name="oldActivityThatWillContinue">The Guid that represents the current activity
/// which will continue at some point in the future, on the current thread</param>
- [System.Security.SecuritySafeCritical]
public static void SetCurrentThreadActivityId(Guid activityId, out Guid oldActivityThatWillContinue)
{
oldActivityThatWillContinue = activityId;
@@ -104,7 +102,6 @@ namespace System.Diagnostics.Tracing
/// </summary>
public static Guid CurrentThreadActivityId
{
- [System.Security.SecuritySafeCritical]
get
{
// We ignore errors to keep with the convention that EventSources do not throw
@@ -186,7 +183,6 @@ namespace System.Diagnostics.Tracing
internal partial class EventProvider
{
- [System.Security.SecurityCritical]
internal unsafe int SetInformation(
UnsafeNativeMethods.ManifestEtw.EVENT_INFO_CLASS eventInfoClass,
IntPtr data,
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/DataCollector.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/DataCollector.cs
index d0d687e8d8..079d7f480b 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/DataCollector.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/DataCollector.cs
@@ -22,7 +22,6 @@ namespace System.Diagnostics.Tracing
/// EventWrite. The instance must be Disabled before the arrays referenced
/// by the pointers are freed or unpinned.
/// </summary>
- [SecurityCritical]
internal unsafe struct DataCollector
{
[ThreadStatic]
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventPayload.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventPayload.cs
index be97447301..5967ad6ab5 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventPayload.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventPayload.cs
@@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Collections;
+using System.Diagnostics;
#if !ES_BUILD_AGAINST_DOTNET_V35
using Contract = System.Diagnostics.Contracts.Contract;
@@ -26,7 +27,7 @@ namespace System.Diagnostics.Tracing
{
internal EventPayload(List<string> payloadNames, List<object> payloadValues)
{
- Contract.Assert(payloadNames.Count == payloadValues.Count);
+ Debug.Assert(payloadNames.Count == payloadValues.Count);
m_names = payloadNames;
m_values = payloadValues;
@@ -40,7 +41,7 @@ namespace System.Diagnostics.Tracing
get
{
if (key == null)
- throw new System.ArgumentNullException("key");
+ throw new System.ArgumentNullException(nameof(key));
int position = 0;
foreach(var name in m_names)
@@ -83,7 +84,7 @@ namespace System.Diagnostics.Tracing
public bool ContainsKey(string key)
{
if (key == null)
- throw new System.ArgumentNullException("key");
+ throw new System.ArgumentNullException(nameof(key));
foreach (var item in m_names)
{
@@ -129,7 +130,7 @@ namespace System.Diagnostics.Tracing
public bool TryGetValue(string key, out object value)
{
if (key == null)
- throw new System.ArgumentNullException("key");
+ throw new System.ArgumentNullException(nameof(key));
int position = 0;
foreach (var name in m_names)
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventSourceActivity.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventSourceActivity.cs
index fccfd48721..38c1767462 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventSourceActivity.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventSourceActivity.cs
@@ -35,7 +35,7 @@ namespace System.Diagnostics.Tracing
public EventSourceActivity(EventSource eventSource)
{
if (eventSource == null)
- throw new ArgumentNullException("eventSource");
+ throw new ArgumentNullException(nameof(eventSource));
Contract.EndContractBlock();
this.eventSource = eventSource;
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/FieldMetadata.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/FieldMetadata.cs
index 45673f7ab5..309226b84d 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/FieldMetadata.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/FieldMetadata.cs
@@ -108,7 +108,7 @@ namespace System.Diagnostics.Tracing
if (name == null)
{
throw new ArgumentNullException(
- "name",
+ nameof(name),
"This usually means that the object passed to Write is of a type that"
+ " does not support being used as the top-level object in an event,"
+ " e.g. a primitive or built-in type.");
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyValue.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyValue.cs
index 0f34d95648..3ea781252f 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyValue.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyValue.cs
@@ -1,5 +1,6 @@
using System.Reflection;
using System.Runtime.InteropServices;
+using System.Diagnostics;
#if !ES_BUILD_AGAINST_DOTNET_V35
using Contract = System.Diagnostics.Contracts.Contract;
@@ -132,7 +133,7 @@ namespace System.Diagnostics.Tracing
{
get
{
- Contract.Assert(_scalarLength == 0, "This ReflectedValue refers to an unboxed value type, not a reference type or boxed value type.");
+ Debug.Assert(_scalarLength == 0, "This ReflectedValue refers to an unboxed value type, not a reference type or boxed value type.");
return _reference;
}
}
@@ -141,7 +142,7 @@ namespace System.Diagnostics.Tracing
{
get
{
- Contract.Assert(_scalarLength > 0, "This ReflectedValue refers to a reference type or boxed value type, not an unboxed value type");
+ Debug.Assert(_scalarLength > 0, "This ReflectedValue refers to a reference type or boxed value type, not an unboxed value type");
return _scalar;
}
}
@@ -150,7 +151,7 @@ namespace System.Diagnostics.Tracing
{
get
{
- Contract.Assert(_scalarLength > 0, "This ReflectedValue refers to a reference type or boxed value type, not an unboxed value type");
+ Debug.Assert(_scalarLength > 0, "This ReflectedValue refers to a reference type or boxed value type, not an unboxed value type");
return _scalarLength;
}
}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/SimpleTypeInfos.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/SimpleTypeInfos.cs
index e51aff0380..901a0ed1a2 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/SimpleTypeInfos.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/SimpleTypeInfos.cs
@@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
using System.Reflection;
+using System.Diagnostics;
#if !ES_BUILD_AGAINST_DOTNET_V35
using Contract = System.Diagnostics.Contracts.Contract;
@@ -269,7 +270,7 @@ namespace System.Diagnostics.Tracing
: base(type)
{
var typeArgs = type.GenericTypeArguments;
- Contract.Assert(typeArgs.Length == 1);
+ Debug.Assert(typeArgs.Length == 1);
this.valueInfo = TraceLoggingTypeInfo.GetInstance(typeArgs[0], recursionCheck);
this.hasValueGetter = PropertyValue.GetPropertyGetter(type.GetTypeInfo().GetDeclaredProperty("HasValue"));
this.valueGetter = PropertyValue.GetPropertyGetter(type.GetTypeInfo().GetDeclaredProperty("Value"));
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/Statics.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/Statics.cs
index fa0f79f58f..516c8ba19a 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/Statics.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/Statics.cs
@@ -175,7 +175,7 @@ namespace System.Diagnostics.Tracing
{
if (name != null && 0 <= name.IndexOf('\0'))
{
- throw new ArgumentOutOfRangeException("name");
+ throw new ArgumentOutOfRangeException(nameof(name));
}
}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingDataCollector.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingDataCollector.cs
index 4b6e633487..04a047fb35 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingDataCollector.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingDataCollector.cs
@@ -21,7 +21,6 @@ namespace System.Diagnostics.Tracing
/// full-trust code, this abstraction is unnecessary (though it probably
/// doesn't hurt anything).
/// </summary>
- [SecuritySafeCritical]
internal unsafe class TraceLoggingDataCollector
{
internal static readonly TraceLoggingDataCollector Instance = new TraceLoggingDataCollector();
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventSource.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventSource.cs
index 963c492419..07a56751ea 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventSource.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventSource.cs
@@ -100,7 +100,7 @@ namespace System.Diagnostics.Tracing
{
if (eventSourceName == null)
{
- throw new ArgumentNullException("eventSourceName");
+ throw new ArgumentNullException(nameof(eventSourceName));
}
Contract.EndContractBlock();
}
@@ -110,12 +110,11 @@ namespace System.Diagnostics.Tracing
/// (Native API: EventWriteTransfer)
/// </summary>
/// <param name="eventName">The name of the event. Must not be null.</param>
- [SecuritySafeCritical]
public unsafe void Write(string eventName)
{
if (eventName == null)
{
- throw new ArgumentNullException("eventName");
+ throw new ArgumentNullException(nameof(eventName));
}
Contract.EndContractBlock();
@@ -138,12 +137,11 @@ namespace System.Diagnostics.Tracing
/// Options for the event, such as the level, keywords, and opcode. Unset
/// options will be set to default values.
/// </param>
- [SecuritySafeCritical]
public unsafe void Write(string eventName, EventSourceOptions options)
{
if (eventName == null)
{
- throw new ArgumentNullException("eventName");
+ throw new ArgumentNullException(nameof(eventName));
}
Contract.EndContractBlock();
@@ -175,7 +173,6 @@ namespace System.Diagnostics.Tracing
/// public instance properties of data will be written recursively to
/// create the fields of the event.
/// </param>
- [SecuritySafeCritical]
public unsafe void Write<T>(
string eventName,
T data)
@@ -212,7 +209,6 @@ namespace System.Diagnostics.Tracing
/// public instance properties of data will be written recursively to
/// create the fields of the event.
/// </param>
- [SecuritySafeCritical]
public unsafe void Write<T>(
string eventName,
EventSourceOptions options,
@@ -251,7 +247,6 @@ namespace System.Diagnostics.Tracing
/// public instance properties of data will be written recursively to
/// create the fields of the event.
/// </param>
- [SecuritySafeCritical]
public unsafe void Write<T>(
string eventName,
ref EventSourceOptions options,
@@ -297,7 +292,6 @@ namespace System.Diagnostics.Tracing
/// public instance properties of data will be written recursively to
/// create the fields of the event.
/// </param>
- [SecuritySafeCritical]
public unsafe void Write<T>(
string eventName,
ref EventSourceOptions options,
@@ -354,7 +348,6 @@ namespace System.Diagnostics.Tracing
/// the values must match the number and types of the fields described by the
/// eventTypes parameter.
/// </param>
- [SecuritySafeCritical]
private unsafe void WriteMultiMerge(
string eventName,
ref EventSourceOptions options,
@@ -415,7 +408,6 @@ namespace System.Diagnostics.Tracing
/// the values must match the number and types of the fields described by the
/// eventTypes parameter.
/// </param>
- [SecuritySafeCritical]
private unsafe void WriteMultiMergeInner(
string eventName,
ref EventSourceOptions options,
@@ -526,7 +518,6 @@ namespace System.Diagnostics.Tracing
/// The number and types of the values must match the number and types of the
/// fields described by the eventTypes parameter.
/// </param>
- [SecuritySafeCritical]
internal unsafe void WriteMultiMerge(
string eventName,
ref EventSourceOptions options,
@@ -604,7 +595,6 @@ namespace System.Diagnostics.Tracing
#endif // FEATURE_MANAGED_ETW
}
- [SecuritySafeCritical]
private unsafe void WriteImpl(
string eventName,
ref EventSourceOptions options,
@@ -721,7 +711,6 @@ namespace System.Diagnostics.Tracing
}
}
- [SecurityCritical]
private unsafe void WriteToAllListeners(string eventName, ref EventDescriptor eventDescriptor, EventTags tags, Guid* pActivityId, EventPayload payload)
{
EventWrittenEventArgs eventCallbackArgs = new EventWrittenEventArgs(this);
@@ -750,7 +739,6 @@ namespace System.Diagnostics.Tracing
System.Runtime.ConstrainedExecution.Consistency.WillNotCorruptState,
System.Runtime.ConstrainedExecution.Cer.Success)]
#endif
- [SecurityCritical]
[NonEvent]
private unsafe void WriteCleanup(GCHandle* pPins, int cPins)
{
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventTypes.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventTypes.cs
index 4e33e58a82..c2239671bb 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventTypes.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventTypes.cs
@@ -94,7 +94,7 @@ namespace System.Diagnostics.Tracing
{
if (name == null)
{
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
}
Contract.EndContractBlock();
@@ -132,7 +132,7 @@ namespace System.Diagnostics.Tracing
{
if (defaultName == null)
{
- throw new ArgumentNullException("defaultName");
+ throw new ArgumentNullException(nameof(defaultName));
}
Contract.EndContractBlock();
@@ -212,7 +212,7 @@ namespace System.Diagnostics.Tracing
{
if (paramInfos == null)
{
- throw new ArgumentNullException("paramInfos");
+ throw new ArgumentNullException(nameof(paramInfos));
}
Contract.EndContractBlock();
@@ -231,7 +231,7 @@ namespace System.Diagnostics.Tracing
{
if (types == null)
{
- throw new ArgumentNullException("types");
+ throw new ArgumentNullException(nameof(types));
}
Contract.EndContractBlock();
@@ -251,7 +251,7 @@ namespace System.Diagnostics.Tracing
{
if (typeInfos == null)
{
- throw new ArgumentNullException("typeInfos");
+ throw new ArgumentNullException(nameof(typeInfos));
}
Contract.EndContractBlock();
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingMetadataCollector.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingMetadataCollector.cs
index 0467ec43e5..41225c8626 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingMetadataCollector.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingMetadataCollector.cs
@@ -156,7 +156,7 @@ namespace System.Diagnostics.Tracing
size = 16;
break;
default:
- throw new ArgumentOutOfRangeException("type");
+ throw new ArgumentOutOfRangeException(nameof(type));
}
this.impl.AddScalar(size);
@@ -183,7 +183,7 @@ namespace System.Diagnostics.Tracing
case TraceLoggingDataType.CountedUtf16String:
break;
default:
- throw new ArgumentOutOfRangeException("type");
+ throw new ArgumentOutOfRangeException(nameof(type));
}
this.impl.AddScalar(2);
@@ -227,7 +227,7 @@ namespace System.Diagnostics.Tracing
case TraceLoggingDataType.Char8:
break;
default:
- throw new ArgumentOutOfRangeException("type");
+ throw new ArgumentOutOfRangeException(nameof(type));
}
if (this.BeginningBufferedArray)
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingTypeInfo.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingTypeInfo.cs
index 5815d12fb0..0cc17e02f3 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingTypeInfo.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingTypeInfo.cs
@@ -36,7 +36,7 @@ namespace System.Diagnostics.Tracing
{
if (dataType == null)
{
- throw new ArgumentNullException("dataType");
+ throw new ArgumentNullException(nameof(dataType));
}
Contract.EndContractBlock();
@@ -56,7 +56,7 @@ namespace System.Diagnostics.Tracing
{
if (dataType == null)
{
- throw new ArgumentNullException("dataType");
+ throw new ArgumentNullException(nameof(dataType));
}
if (name == null)
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/XplatEventLogger.cs b/src/mscorlib/src/System/Diagnostics/Eventing/XplatEventLogger.cs
index d7112fc81b..c96d2129f0 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/XplatEventLogger.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/XplatEventLogger.cs
@@ -73,9 +73,8 @@ namespace System.Diagnostics.Tracing
}
}
- private static string Serialize(ReadOnlyCollection<string> payloadName, ReadOnlyCollection<object> payload, string sep = ", ")
+ private static string Serialize(ReadOnlyCollection<string> payloadName, ReadOnlyCollection<object> payload, string eventMessage)
{
-
if (payloadName == null || payload == null )
return String.Empty;
@@ -92,8 +91,22 @@ namespace System.Diagnostics.Tracing
var sb = StringBuilderCache.Acquire();
sb.Append('{');
+
+ // If the event has a message, send that as well as a pseudo-field
+ if (!string.IsNullOrEmpty(eventMessage))
+ {
+ sb.Append("\\\"EventSource_Message\\\":\\\"");
+ minimalJsonserializer(eventMessage,sb);
+ sb.Append("\\\"");
+ if (eventDataCount != 0)
+ sb.Append(", ");
+ }
+
for (int i = 0; i < eventDataCount; i++)
{
+ if (i != 0)
+ sb.Append(", ");
+
var fieldstr = payloadName[i].ToString();
sb.Append("\\\"");
@@ -114,14 +127,9 @@ namespace System.Diagnostics.Tracing
sb.Append(payload[i].ToString());
}
- sb.Append(sep);
-
}
-
- sb.Length -= sep.Length;
- sb.Append('}');
-
- return StringBuilderCache.GetStringAndRelease(sb);
+ sb.Append('}');
+ return StringBuilderCache.GetStringAndRelease(sb);
}
internal protected override void OnEventSourceCreated(EventSource eventSource)
@@ -149,7 +157,7 @@ namespace System.Diagnostics.Tracing
if (eventData.Payload != null)
{
try{
- payload = Serialize(eventData.PayloadNames, eventData.Payload);
+ payload = Serialize(eventData.PayloadNames, eventData.Payload, eventData.Message);
}
catch (Exception ex)
{
diff --git a/src/mscorlib/src/System/Diagnostics/LogSwitch.cs b/src/mscorlib/src/System/Diagnostics/LogSwitch.cs
index e3e2b867c4..84f6b91f65 100644
--- a/src/mscorlib/src/System/Diagnostics/LogSwitch.cs
+++ b/src/mscorlib/src/System/Diagnostics/LogSwitch.cs
@@ -33,11 +33,10 @@ namespace System.Diagnostics {
//
// All switches (except for the global LogSwitch) have a parent LogSwitch.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public LogSwitch(String name, String description, LogSwitch parent)
{
if (name != null && name.Length == 0)
- throw new ArgumentOutOfRangeException("Name", Environment.GetResourceString("Argument_StringZeroLength"));
+ throw new ArgumentOutOfRangeException(nameof(Name), Environment.GetResourceString("Argument_StringZeroLength"));
Contract.EndContractBlock();
if ((name != null) && (parent != null))
@@ -55,10 +54,9 @@ namespace System.Diagnostics {
Log.AddLogSwitch (this);
}
else
- throw new ArgumentNullException ((name==null ? "name" : "parent"));
+ throw new ArgumentNullException ((name==null ? nameof(name) : nameof(parent)));
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal LogSwitch(String name, String description)
{
strName = name;
@@ -100,7 +98,6 @@ namespace System.Diagnostics {
public virtual LoggingLevels MinimumLevel
{
get { return iLevel; }
- [System.Security.SecuritySafeCritical] // auto-generated
set
{
iLevel = value;
diff --git a/src/mscorlib/src/System/Diagnostics/Stackframe.cs b/src/mscorlib/src/System/Diagnostics/Stackframe.cs
index 397c3e12e6..06d675ea08 100644
--- a/src/mscorlib/src/System/Diagnostics/Stackframe.cs
+++ b/src/mscorlib/src/System/Diagnostics/Stackframe.cs
@@ -11,13 +11,7 @@ namespace System.Diagnostics {
using System.Security.Permissions;
using System.Diagnostics.Contracts;
- // 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
- // StackTrace, we use an InheritanceDemand to prevent partially-trusted
- // subclasses.
-#if !FEATURE_CORECLR
- [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode=true)]
-#endif
+ // There is no good reason for the methods of this class to be virtual.
[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public class StackFrame
@@ -49,9 +43,6 @@ namespace System.Diagnostics {
}
// Constructs a StackFrame corresponding to the active stack frame.
-#if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical]
-#endif
public StackFrame()
{
InitMembers();
@@ -59,9 +50,6 @@ namespace System.Diagnostics {
}
// Constructs a StackFrame corresponding to the active stack frame.
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
public StackFrame(bool fNeedFileInfo)
{
InitMembers();
@@ -78,9 +66,6 @@ namespace System.Diagnostics {
// Constructs a StackFrame corresponding to a calling stack frame.
//
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
public StackFrame(int skipFrames, bool fNeedFileInfo)
{
InitMembers();
@@ -200,11 +185,6 @@ namespace System.Diagnostics {
// information is normally extracted from the debugging symbols
// for the executable.
//
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #else
- [System.Security.SecuritySafeCritical]
- #endif
public virtual String GetFileName()
{
if (strFileName != null)
@@ -242,7 +222,6 @@ namespace System.Diagnostics {
// Builds a readable representation of the stack frame
//
- [System.Security.SecuritySafeCritical] // auto-generated
public override String ToString()
{
StringBuilder sb = new StringBuilder(255);
diff --git a/src/mscorlib/src/System/Diagnostics/Stacktrace.cs b/src/mscorlib/src/System/Diagnostics/Stacktrace.cs
index 047a60f328..7dc5d9df09 100644
--- a/src/mscorlib/src/System/Diagnostics/Stacktrace.cs
+++ b/src/mscorlib/src/System/Diagnostics/Stacktrace.cs
@@ -61,14 +61,12 @@ namespace System.Diagnostics {
IntPtr inMemoryPdbAddress, int inMemoryPdbSize, int methodToken, int ilOffset,
out string sourceFile, out int sourceLine, out int sourceColumn);
-#if FEATURE_CORECLR
private static Type s_symbolsType = null;
private static MethodInfo s_symbolsMethodInfo = null;
[ThreadStatic]
private static int t_reentrancy = 0;
-#endif
-
+
public StackFrameHelper(Thread target)
{
targetThread = target;
@@ -111,7 +109,6 @@ namespace System.Diagnostics {
{
StackTrace.GetStackFramesInternal(this, iSkip, fNeedFileInfo, exception);
-#if FEATURE_CORECLR
if (!fNeedFileInfo)
return;
@@ -164,12 +161,10 @@ namespace System.Diagnostics {
{
t_reentrancy--;
}
-#endif
}
void IDisposable.Dispose()
{
-#if FEATURE_CORECLR
if (getSourceLineInfo != null)
{
IDisposable disposable = getSourceLineInfo.Target as IDisposable;
@@ -178,10 +173,8 @@ namespace System.Diagnostics {
disposable.Dispose();
}
}
-#endif
}
- [System.Security.SecuritySafeCritical]
public virtual MethodBase GetMethodBase(int i)
{
// There may be a better way to do this.
@@ -219,7 +212,6 @@ namespace System.Diagnostics {
// serialization implementation
//
[OnSerializing]
- [SecuritySafeCritical]
void OnSerializing(StreamingContext context)
{
// this is called in the process of serializing this object.
@@ -244,7 +236,6 @@ namespace System.Diagnostics {
}
[OnDeserialized]
- [SecuritySafeCritical]
void OnDeserialized(StreamingContext context)
{
// after we are done deserializing we need to transform the rgMethodBase in rgMethodHandle
@@ -267,9 +258,6 @@ namespace System.Diagnostics {
// In order to ensure trusted code can trust the data it gets from a
// StackTrace, we use an InheritanceDemand to prevent partially-trusted
// subclasses.
-#if !FEATURE_CORECLR
- [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode=true)]
-#endif
[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public class StackTrace
@@ -280,9 +268,6 @@ namespace System.Diagnostics {
private int m_iMethodsToSkip;
// Constructs a stack trace from the current location.
-#if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical]
-#endif
public StackTrace()
{
m_iNumOfFrames = 0;
@@ -292,9 +277,6 @@ namespace System.Diagnostics {
// Constructs a stack trace from the current location.
//
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
public StackTrace(bool fNeedFileInfo)
{
m_iNumOfFrames = 0;
@@ -305,14 +287,11 @@ namespace System.Diagnostics {
// Constructs a stack trace from the current location, in a caller's
// frame
//
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
public StackTrace(int skipFrames)
{
if (skipFrames < 0)
- throw new ArgumentOutOfRangeException("skipFrames",
+ throw new ArgumentOutOfRangeException(nameof(skipFrames),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -325,14 +304,11 @@ namespace System.Diagnostics {
// Constructs a stack trace from the current location, in a caller's
// frame
//
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
public StackTrace(int skipFrames, bool fNeedFileInfo)
{
if (skipFrames < 0)
- throw new ArgumentOutOfRangeException("skipFrames",
+ throw new ArgumentOutOfRangeException(nameof(skipFrames),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -347,7 +323,7 @@ namespace System.Diagnostics {
public StackTrace(Exception e)
{
if (e == null)
- throw new ArgumentNullException("e");
+ throw new ArgumentNullException(nameof(e));
Contract.EndContractBlock();
m_iNumOfFrames = 0;
@@ -357,13 +333,10 @@ namespace System.Diagnostics {
// Constructs a stack trace from the current location.
//
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
public StackTrace(Exception e, bool fNeedFileInfo)
{
if (e == null)
- throw new ArgumentNullException("e");
+ throw new ArgumentNullException(nameof(e));
Contract.EndContractBlock();
m_iNumOfFrames = 0;
@@ -374,16 +347,13 @@ namespace System.Diagnostics {
// Constructs a stack trace from the current location, in a caller's
// frame
//
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
public StackTrace(Exception e, int skipFrames)
{
if (e == null)
- throw new ArgumentNullException("e");
+ throw new ArgumentNullException(nameof(e));
if (skipFrames < 0)
- throw new ArgumentOutOfRangeException("skipFrames",
+ throw new ArgumentOutOfRangeException(nameof(skipFrames),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -396,16 +366,13 @@ namespace System.Diagnostics {
// Constructs a stack trace from the current location, in a caller's
// frame
//
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
public StackTrace(Exception e, int skipFrames, bool fNeedFileInfo)
{
if (e == null)
- throw new ArgumentNullException("e");
+ throw new ArgumentNullException(nameof(e));
if (skipFrames < 0)
- throw new ArgumentOutOfRangeException("skipFrames",
+ throw new ArgumentOutOfRangeException(nameof(skipFrames),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -430,9 +397,6 @@ namespace System.Diagnostics {
// Constructs a stack trace for the given thread
//
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
[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)
{
@@ -443,7 +407,6 @@ namespace System.Diagnostics {
}
- [System.Security.SecuritySafeCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void GetStackFramesInternal(StackFrameHelper sfh, int iSkip, bool fNeedFileInfo, Exception e);
@@ -576,9 +539,6 @@ namespace System.Diagnostics {
// Builds a readable representation of the stack trace
//
-#if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical]
-#endif
public override String ToString()
{
// Include a trailing newline for backwards compatibility
@@ -596,9 +556,6 @@ namespace System.Diagnostics {
// Builds a readable representation of the stack trace, specifying
// the format for backwards compatibility.
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
internal String ToString(TraceFormat traceFormat)
{
bool displayFilenames = true; // we'll try, but demand may fail
@@ -656,26 +613,22 @@ namespace System.Diagnostics {
else
fFirstTyParam = false;
- sb.Append(typars[k].Name);
+ sb.Append(typars[k].Name);
k++;
}
sb.Append(']');
}
ParameterInfo[] pi = null;
-#if FEATURE_CORECLR
try
{
-#endif
pi = mb.GetParameters();
-#if FEATURE_CORECLR
}
catch
{
// The parameter info cannot be loaded, so we don't
// append the parameter list.
}
-#endif
if (pi != null)
{
// arguments printing
@@ -712,15 +665,6 @@ namespace System.Diagnostics {
{
fileName = sf.GetFileName();
}
-#if FEATURE_CAS_POLICY
- catch (NotSupportedException)
- {
- // Having a deprecated stack modifier on the callstack (such as Deny) will cause
- // a NotSupportedException to be thrown. Since we don't know if the app can
- // access the file names, we'll conservatively hide them.
- displayFilenames = false;
- }
-#endif // FEATURE_CAS_POLICY
catch (SecurityException)
{
// If the demand for displaying filenames fails, then it won't
@@ -754,9 +698,6 @@ namespace System.Diagnostics {
// This helper is called from within the EE to construct a string representation
// of the current stack trace.
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
private static String GetManagedStackTraceStringHelper(bool fNeedFileInfo)
{
// Note all the frames in System.Diagnostics will be skipped when capturing
diff --git a/src/mscorlib/src/System/Diagnostics/SymbolStore/ISymWriter.cs b/src/mscorlib/src/System/Diagnostics/SymbolStore/ISymWriter.cs
index b6177be2aa..a0d3640c2c 100644
--- a/src/mscorlib/src/System/Diagnostics/SymbolStore/ISymWriter.cs
+++ b/src/mscorlib/src/System/Diagnostics/SymbolStore/ISymWriter.cs
@@ -31,9 +31,6 @@ namespace System.Diagnostics.SymbolStore {
// Define a source document. Guid's will be provided for the
// languages, vendors, and document types that we currently know
// about.
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
ISymbolDocumentWriter DefineDocument(String url,
Guid language,
Guid languageVendor,
@@ -42,9 +39,6 @@ namespace System.Diagnostics.SymbolStore {
// Define the method that the user has defined as their entrypoint
// for this module. This would be, perhaps, the user's main method
// rather than compiler generated stubs before main.
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
void SetUserEntryPoint(SymbolToken entryMethod);
// Open a method to emit symbol information into. The given method
@@ -55,25 +49,16 @@ namespace System.Diagnostics.SymbolStore {
// defined symbols for that method.
//
// There can be only one open method at a time.
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
void OpenMethod(SymbolToken method);
// Close the current method. Once a method is closed, no more
// symbols can be defined within it.
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
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
// always the offset from the start of the method, in bytes.
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
void DefineSequencePoints(ISymbolDocumentWriter document,
int[] offsets,
int[] lines,
@@ -96,17 +81,11 @@ namespace System.Diagnostics.SymbolStore {
// Note: scope id's are only valid in the current method.
//
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
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.
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
void CloseScope(int endOffset);
// Define the offset range for a given lexical scope.
@@ -120,9 +99,6 @@ namespace System.Diagnostics.SymbolStore {
// variable of the same name that has multiple homes throughout a
// scope. (Note: start/end offsets must not overlap in such a
// case.)
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
void DefineLocalVariable(String name,
FieldAttributes attributes,
byte[] signature,
@@ -178,9 +154,6 @@ namespace System.Diagnostics.SymbolStore {
// Defines a custom attribute based upon its name. Not to be
// confused with Metadata custom attributes, these attributes are
// held in the symbol store.
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
void SetSymAttribute(SymbolToken parent, String name, byte[] data);
// Opens a new namespace. Call this before defining methods or
@@ -195,9 +168,6 @@ namespace System.Diagnostics.SymbolStore {
// current scope will also stop using the namespace, and the
// namespace will be in use in all scopes that inherit from the
// currently open scope.
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
void UsingNamespace(String fullName);
// Specifies the true start and end of a method within a source
diff --git a/src/mscorlib/src/System/Diagnostics/log.cs b/src/mscorlib/src/System/Diagnostics/log.cs
index 1c68aad161..6916ce3a0a 100644
--- a/src/mscorlib/src/System/Diagnostics/log.cs
+++ b/src/mscorlib/src/System/Diagnostics/log.cs
@@ -22,7 +22,6 @@ namespace System.Diagnostics {
// programatically, by registry (specifics....) or environment
// variables.
[Serializable]
- [HostProtection(Synchronization=true, ExternalThreading=true)]
internal delegate void LogMessageEventHandler(LoggingLevels level, LogSwitch category,
String message,
StackTrace location);
@@ -140,7 +139,7 @@ namespace System.Diagnostics {
throw new ArgumentNullException ("LogSwitch");
if (level < 0)
- throw new ArgumentOutOfRangeException("level", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(level), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
// Is logging for this level for this switch enabled?
@@ -240,10 +239,8 @@ namespace System.Diagnostics {
// Native method to inform the EE about the creation of a new LogSwitch
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void AddLogSwitch(LogSwitch logSwitch);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void ModifyLogSwitch (int iNewLevel, String strSwitchName, String strParentName);
}
diff --git a/src/mscorlib/src/System/Double.cs b/src/mscorlib/src/System/Double.cs
index b2d509af8d..ce146a1227 100644
--- a/src/mscorlib/src/System/Double.cs
+++ b/src/mscorlib/src/System/Double.cs
@@ -44,7 +44,6 @@ namespace System {
internal static double NegativeZero = BitConverter.Int64BitsToDouble(unchecked((long)0x8000000000000000));
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.Versioning.NonVersionable]
public unsafe static bool IsInfinity(double d) {
return (*(long*)(&d) & 0x7FFFFFFFFFFFFFFF) == 0x7FF0000000000000;
@@ -79,14 +78,12 @@ namespace System {
}
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static bool IsNegative(double d) {
return (*(UInt64*)(&d) & 0x8000000000000000) == 0x8000000000000000;
}
[Pure]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- [System.Security.SecuritySafeCritical]
[System.Runtime.Versioning.NonVersionable]
public unsafe static bool IsNaN(double d)
{
@@ -187,7 +184,6 @@ namespace System {
//The hashcode for a double is the absolute value of the integer representation
//of that double.
//
- [System.Security.SecuritySafeCritical]
public unsafe override int GetHashCode() {
double d = m_value;
if (d == 0) {
@@ -198,25 +194,21 @@ namespace System {
return unchecked((int)value) ^ ((int)(value >> 32));
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override String ToString() {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatDouble(m_value, null, NumberFormatInfo.CurrentInfo);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(String format) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatDouble(m_value, format, NumberFormatInfo.CurrentInfo);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(IFormatProvider provider) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatDouble(m_value, null, NumberFormatInfo.GetInstance(provider));
}
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(String format, IFormatProvider provider) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatDouble(m_value, format, NumberFormatInfo.GetInstance(provider));
diff --git a/src/mscorlib/src/System/Empty.cs b/src/mscorlib/src/System/Empty.cs
index f7e7486014..4790d9a383 100644
--- a/src/mscorlib/src/System/Empty.cs
+++ b/src/mscorlib/src/System/Empty.cs
@@ -25,10 +25,9 @@ namespace System {
return String.Empty;
}
- [System.Security.SecurityCritical] // auto-generated
public void GetObjectData(SerializationInfo info, StreamingContext context) {
if (info==null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
UnitySerializationHolder.GetUnitySerializationInfo(info, UnitySerializationHolder.EmptyUnity, null, null);
diff --git a/src/mscorlib/src/System/Enum.cs b/src/mscorlib/src/System/Enum.cs
index a8104556e4..d39e005d48 100644
--- a/src/mscorlib/src/System/Enum.cs
+++ b/src/mscorlib/src/System/Enum.cs
@@ -9,6 +9,7 @@ using System.Globalization;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
namespace System
@@ -23,7 +24,6 @@ namespace System
#endregion
#region Private Static Methods
- [System.Security.SecuritySafeCritical] // auto-generated
private static TypeValuesAndNames GetCachedValuesAndNames(RuntimeType enumType, bool getNames)
{
TypeValuesAndNames entry = enumType.GenericCache as TypeValuesAndNames;
@@ -47,7 +47,6 @@ namespace System
return entry;
}
- [System.Security.SecuritySafeCritical]
private unsafe String InternalFormattedHexString()
{
fixed (void* pValue = &JitHelpers.GetPinningHelper(this).m_data)
@@ -71,7 +70,7 @@ namespace System
case CorElementType.U8:
return (*(ulong*)pValue).ToString("X16", null);
default:
- Contract.Assert(false, "Invalid Object type in Format");
+ Debug.Assert(false, "Invalid Object type in Format");
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UnknownEnumType"));
}
}
@@ -106,7 +105,7 @@ namespace System
return ((UInt64)(Int64)value).ToString("X16", null);
// All unsigned types will be directly cast
default:
- Contract.Assert(false, "Invalid Object type in Format");
+ Debug.Assert(false, "Invalid Object type in Format");
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UnknownEnumType"));
}
}
@@ -157,7 +156,7 @@ namespace System
String[] names = entry.Names;
ulong[] values = entry.Values;
- Contract.Assert(names.Length == values.Length);
+ Debug.Assert(names.Length == values.Length);
int index = values.Length - 1;
StringBuilder retval = new StringBuilder();
@@ -245,27 +244,23 @@ namespace System
break;
// All unsigned types will be directly cast
default:
- Contract.Assert(false, "Invalid Object type in ToUInt64");
+ Debug.Assert(false, "Invalid Object type in ToUInt64");
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UnknownEnumType"));
}
return result;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern int InternalCompareTo(Object o1, Object o2);
- [System.Security.SecuritySafeCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern RuntimeType InternalGetUnderlyingType(RuntimeType enumType);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[System.Security.SuppressUnmanagedCodeSecurity]
private static extern void GetEnumValuesAndNames(RuntimeTypeHandle enumType, ObjectHandleOnStack values, ObjectHandleOnStack names, bool getNames);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern Object InternalBoxEnum(RuntimeType enumType, long value);
#endregion
@@ -328,12 +323,28 @@ namespace System
return m_innerException;
default:
- Contract.Assert(false, "Unknown EnumParseFailure: " + m_failure);
+ Debug.Assert(false, "Unknown EnumParseFailure: " + m_failure);
return new ArgumentException(Environment.GetResourceString("Arg_EnumValueNotFound"));
}
}
}
+ public static bool TryParse(Type enumType, String value, out Object result)
+ {
+ return TryParse(enumType, value, false, out result);
+ }
+
+ public static bool TryParse(Type enumType, String value, bool ignoreCase, out Object result)
+ {
+ result = null;
+ EnumResult parseResult = new EnumResult();
+ bool retValue;
+
+ if (retValue = TryParseEnum(enumType, value, ignoreCase, ref parseResult))
+ result = parseResult.parsedEnum;
+ return retValue;
+ }
+
public static bool TryParse<TEnum>(String value, out TEnum result) where TEnum : struct
{
return TryParse(value, false, out result);
@@ -366,21 +377,35 @@ namespace System
throw parseResult.GetEnumParseException();
}
+ public static TEnum Parse<TEnum>(String value) where TEnum : struct
+ {
+ return Parse<TEnum>(value, false);
+ }
+
+ public static TEnum Parse<TEnum>(String value, bool ignoreCase) where TEnum : struct
+ {
+ EnumResult parseResult = new EnumResult() { canThrow = true };
+ if (TryParseEnum(typeof(TEnum), value, ignoreCase, ref parseResult))
+ return (TEnum)parseResult.parsedEnum;
+ else
+ throw parseResult.GetEnumParseException();
+ }
+
private static bool TryParseEnum(Type enumType, String value, bool ignoreCase, ref EnumResult parseResult)
{
if (enumType == null)
- throw new ArgumentNullException("enumType");
+ throw new ArgumentNullException(nameof(enumType));
Contract.EndContractBlock();
RuntimeType rtType = enumType as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "enumType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(enumType));
if (!enumType.IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), nameof(enumType));
if (value == null) {
- parseResult.SetFailure(ParseFailureKind.ArgumentNull, "value");
+ parseResult.SetFailure(ParseFailureKind.ArgumentNull, nameof(value));
return false;
}
@@ -504,7 +529,7 @@ namespace System
public static Type GetUnderlyingType(Type enumType)
{
if (enumType == null)
- throw new ArgumentNullException("enumType");
+ throw new ArgumentNullException(nameof(enumType));
Contract.Ensures(Contract.Result<Type>() != null);
Contract.EndContractBlock();
@@ -515,7 +540,7 @@ namespace System
public static Array GetValues(Type enumType)
{
if (enumType == null)
- throw new ArgumentNullException("enumType");
+ throw new ArgumentNullException(nameof(enumType));
Contract.Ensures(Contract.Result<Array>() != null);
Contract.EndContractBlock();
@@ -532,7 +557,7 @@ namespace System
public static String GetName(Type enumType, Object value)
{
if (enumType == null)
- throw new ArgumentNullException("enumType");
+ throw new ArgumentNullException(nameof(enumType));
Contract.EndContractBlock();
return enumType.GetEnumName(value);
@@ -542,7 +567,7 @@ namespace System
public static String[] GetNames(Type enumType)
{
if (enumType == null)
- throw new ArgumentNullException("enumType");
+ throw new ArgumentNullException(nameof(enumType));
Contract.Ensures(Contract.Result<String[]>() != null);
Contract.EndContractBlock();
@@ -559,7 +584,7 @@ namespace System
public static Object ToObject(Type enumType, Object value)
{
if (value == null)
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
Contract.EndContractBlock();
// Delegate rest of error checking to the other functions
@@ -599,7 +624,7 @@ namespace System
default:
// All unsigned types will be directly cast
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnumBaseTypeOrEnum"), "value");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnumBaseTypeOrEnum"), nameof(value));
}
}
@@ -608,7 +633,7 @@ namespace System
public static bool IsDefined(Type enumType, Object value)
{
if (enumType == null)
- throw new ArgumentNullException("enumType");
+ throw new ArgumentNullException(nameof(enumType));
Contract.EndContractBlock();
return enumType.IsEnumDefined(value);
@@ -618,21 +643,21 @@ namespace System
public static String Format(Type enumType, Object value, String format)
{
if (enumType == null)
- throw new ArgumentNullException("enumType");
+ throw new ArgumentNullException(nameof(enumType));
if (!enumType.IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), nameof(enumType));
if (value == null)
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
if (format == null)
- throw new ArgumentNullException("format");
+ throw new ArgumentNullException(nameof(format));
Contract.EndContractBlock();
RuntimeType rtType = enumType as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "enumType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(enumType));
// Check if both of them are of the same type
Type valueType = value.GetType();
@@ -698,7 +723,6 @@ namespace System
#endregion
#region Private Methods
- [System.Security.SecuritySafeCritical]
internal unsafe Object GetValue()
{
fixed (void* pValue = &JitHelpers.GetPinningHelper(this).m_data)
@@ -734,13 +758,12 @@ namespace System
case CorElementType.U:
return *(UIntPtr*)pValue;
default:
- Contract.Assert(false, "Invalid primitive type");
+ Debug.Assert(false, "Invalid primitive type");
return null;
}
}
}
- [System.Security.SecuritySafeCritical]
private unsafe ulong ToUInt64()
{
fixed (void* pValue = &JitHelpers.GetPinningHelper(this).m_data)
@@ -787,32 +810,29 @@ namespace System
return *(uint*)pValue;
}
default:
- Contract.Assert(false, "Invalid primitive type");
+ Debug.Assert(false, "Invalid primitive type");
return 0;
}
}
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern bool InternalHasFlag(Enum flags);
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern CorElementType InternalGetCorElementType();
#endregion
#region Object Overrides
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern override bool Equals(Object obj);
- [System.Security.SecuritySafeCritical]
public override unsafe int GetHashCode()
{
- // Avoid boxing by inlining GetValue()
- // return GetValue().GetHashCode();
+ // CONTRACT with the runtime: GetHashCode of enum types is implemented as GetHashCode of the underlying type.
+ // The runtime can bypass calls to Enum::GetHashCode and call the underlying type's GetHashCode directly
+ // to avoid boxing the enum.
fixed (void* pValue = &JitHelpers.GetPinningHelper(this).m_data)
{
@@ -847,7 +867,7 @@ namespace System
case CorElementType.U:
return (*(UIntPtr*)pValue).GetHashCode();
default:
- Contract.Assert(false, "Invalid primitive type");
+ Debug.Assert(false, "Invalid primitive type");
return 0;
}
}
@@ -876,7 +896,6 @@ namespace System
#endregion
#region IComparable
- [System.Security.SecuritySafeCritical] // auto-generated
public int CompareTo(Object target)
{
const int retIncompatibleMethodTables = 2; // indicates that the method tables did not match
@@ -904,7 +923,7 @@ namespace System
else
{
// assert valid return code (3)
- Contract.Assert(ret == retInvalidEnumType, "Enum.InternalCompareTo return code was invalid");
+ Debug.Assert(ret == retInvalidEnumType, "Enum.InternalCompareTo return code was invalid");
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UnknownEnumType"));
}
@@ -942,10 +961,9 @@ namespace System
return ToString();
}
- [System.Security.SecuritySafeCritical]
public Boolean HasFlag(Enum flag) {
if (flag == null)
- throw new ArgumentNullException("flag");
+ throw new ArgumentNullException(nameof(flag));
Contract.EndContractBlock();
if (!this.GetType().IsEquivalentTo(flag.GetType())) {
@@ -1013,7 +1031,7 @@ namespace System
return TypeCode.Char;
}
- Contract.Assert(false, "Unknown underlying type.");
+ Debug.Assert(false, "Unknown underlying type.");
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UnknownEnumType"));
}
@@ -1109,155 +1127,145 @@ namespace System
#endregion
#region ToObject
- [System.Security.SecuritySafeCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(true)]
public static Object ToObject(Type enumType, sbyte value)
{
if (enumType == null)
- throw new ArgumentNullException("enumType");
+ throw new ArgumentNullException(nameof(enumType));
if (!enumType.IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), nameof(enumType));
Contract.EndContractBlock();
RuntimeType rtType = enumType as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "enumType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(enumType));
return InternalBoxEnum(rtType, value);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(true)]
public static Object ToObject(Type enumType, short value)
{
if (enumType == null)
- throw new ArgumentNullException("enumType");
+ throw new ArgumentNullException(nameof(enumType));
if (!enumType.IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), nameof(enumType));
Contract.EndContractBlock();
RuntimeType rtType = enumType as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "enumType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(enumType));
return InternalBoxEnum(rtType, value);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(true)]
public static Object ToObject(Type enumType, int value)
{
if (enumType == null)
- throw new ArgumentNullException("enumType");
+ throw new ArgumentNullException(nameof(enumType));
if (!enumType.IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), nameof(enumType));
Contract.EndContractBlock();
RuntimeType rtType = enumType as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "enumType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(enumType));
return InternalBoxEnum(rtType, value);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(true)]
public static Object ToObject(Type enumType, byte value)
{
if (enumType == null)
- throw new ArgumentNullException("enumType");
+ throw new ArgumentNullException(nameof(enumType));
if (!enumType.IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), nameof(enumType));
Contract.EndContractBlock();
RuntimeType rtType = enumType as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "enumType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(enumType));
return InternalBoxEnum(rtType, value);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(true)]
public static Object ToObject(Type enumType, ushort value)
{
if (enumType == null)
- throw new ArgumentNullException("enumType");
+ throw new ArgumentNullException(nameof(enumType));
if (!enumType.IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), nameof(enumType));
Contract.EndContractBlock();
RuntimeType rtType = enumType as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "enumType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(enumType));
return InternalBoxEnum(rtType, value);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(true)]
public static Object ToObject(Type enumType, uint value)
{
if (enumType == null)
- throw new ArgumentNullException("enumType");
+ throw new ArgumentNullException(nameof(enumType));
if (!enumType.IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), nameof(enumType));
Contract.EndContractBlock();
RuntimeType rtType = enumType as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "enumType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(enumType));
return InternalBoxEnum(rtType, value);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(true)]
public static Object ToObject(Type enumType, long value)
{
if (enumType == null)
- throw new ArgumentNullException("enumType");
+ throw new ArgumentNullException(nameof(enumType));
if (!enumType.IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), nameof(enumType));
Contract.EndContractBlock();
RuntimeType rtType = enumType as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "enumType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(enumType));
return InternalBoxEnum(rtType, value);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(true)]
public static Object ToObject(Type enumType, ulong value)
{
if (enumType == null)
- throw new ArgumentNullException("enumType");
+ throw new ArgumentNullException(nameof(enumType));
if (!enumType.IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), nameof(enumType));
Contract.EndContractBlock();
RuntimeType rtType = enumType as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "enumType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(enumType));
return InternalBoxEnum(rtType, unchecked((long)value));
}
- [System.Security.SecuritySafeCritical] // auto-generated
private static Object ToObject(Type enumType, char value)
{
if (enumType == null)
- throw new ArgumentNullException("enumType");
+ throw new ArgumentNullException(nameof(enumType));
if (!enumType.IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), nameof(enumType));
Contract.EndContractBlock();
RuntimeType rtType = enumType as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "enumType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(enumType));
return InternalBoxEnum(rtType, value);
}
- [System.Security.SecuritySafeCritical] // auto-generated
private static Object ToObject(Type enumType, bool value)
{
if (enumType == null)
- throw new ArgumentNullException("enumType");
+ throw new ArgumentNullException(nameof(enumType));
if (!enumType.IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), nameof(enumType));
Contract.EndContractBlock();
RuntimeType rtType = enumType as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "enumType");
+ throw new ArgumentException(Environment.GetResourceString("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 5ee30bb9ba..835219a01c 100644
--- a/src/mscorlib/src/System/Environment.cs
+++ b/src/mscorlib/src/System/Environment.cs
@@ -32,17 +32,16 @@ namespace System {
using System.Diagnostics.Contracts;
[ComVisible(true)]
- public enum EnvironmentVariableTarget {
+ public enum EnvironmentVariableTarget
+ {
Process = 0,
-#if FEATURE_WIN32_REGISTRY
User = 1,
Machine = 2,
-#endif
}
[ComVisible(true)]
- public static class Environment {
-
+ public 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
// System environment variables are stored in the registry, and have
@@ -89,11 +88,10 @@ namespace System {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal String GetResourceString(String key) {
if (key == null || key.Length == 0) {
- Contract.Assert(false, "Environment::GetResourceString with null or empty key. Bug in caller, or weird recursive loading problem?");
+ 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]";
}
@@ -125,11 +123,6 @@ namespace System {
return userData.m_retVal;
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #else
- [System.Security.SecuritySafeCritical]
- #endif
private void GetResourceStringCode(Object userDataIn)
{
GetResourceStringUserData userData = (GetResourceStringUserData) userDataIn;
@@ -189,14 +182,11 @@ namespace System {
String s = rh.SystemResMgr.GetString(key, null);
rh.currentlyLoading.RemoveAt(rh.currentlyLoading.Count - 1); // Pop
- Contract.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+"\"");
+ 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+"\"");
userData.m_retVal = s;
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
[PrePrepareMethod]
private void GetResourceStringBackoutCode(Object userDataIn, bool exceptionThrown)
{
@@ -248,32 +238,24 @@ namespace System {
**Exceptions: None
==============================================================================*/
public static extern int TickCount {
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
get;
}
// Terminates this process with the given exit code.
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal static extern void _Exit(int exitCode);
- [System.Security.SecuritySafeCritical] // auto-generated
-#pragma warning disable 618
- [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)]
-#pragma warning restore 618
public static void Exit(int exitCode) {
_Exit(exitCode);
}
public static extern int ExitCode {
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
get;
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
set;
}
@@ -281,11 +263,9 @@ namespace System {
// Note: The CLR's Watson bucketization code looks at the caller of the FCALL method
// to assign blame for crashes. Don't mess with this, such as by making it call
// another managed helper method, unless you consult with some CLR Watson experts.
- [System.Security.SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void FailFast(String message);
- [System.Security.SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void FailFast(String message, uint exitCode);
@@ -302,44 +282,9 @@ namespace System {
// if the exception object is preallocated, the runtime will use the callsite's
// IP for bucketing. If the exception object is not preallocated, it will use the bucket
// details contained in the object (if any).
- [System.Security.SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void FailFast(String message, Exception exception);
-#if !FEATURE_CORECLR
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SecurityCritical] // Our security team doesn't yet allow safe-critical P/Invoke methods.
- [SuppressUnmanagedCodeSecurity]
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
- internal static extern void TriggerCodeContractFailure(ContractFailureKind failureKind, String message, String condition, String exceptionAsString);
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SecurityCritical] // Our security team doesn't yet allow safe-critical P/Invoke methods.
- [SuppressUnmanagedCodeSecurity]
- [return: MarshalAs(UnmanagedType.Bool)]
- private static extern bool GetIsCLRHosted();
-
- internal static bool IsCLRHosted {
- [SecuritySafeCritical]
- get { return GetIsCLRHosted(); }
- }
-
- public static String CommandLine {
- [System.Security.SecuritySafeCritical] // auto-generated
- get {
- new EnvironmentPermission(EnvironmentPermissionAccess.Read, "Path").Demand();
-
- String commandLine = null;
- GetCommandLine(JitHelpers.GetStringHandleOnStack(ref commandLine));
- return commandLine;
- }
- }
-
- [System.Security.SecurityCritical] // auto-generated
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
- private static extern void GetCommandLine(StringHandleOnStack retString);
-#endif // !FEATURE_CORECLR
-
/*===============================CurrentDirectory===============================
**Action: Provides a getter and setter for the current directory. The original
** current directory is the one from which the process was started.
@@ -353,9 +298,6 @@ namespace System {
return Directory.GetCurrentDirectory();
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
set {
Directory.SetCurrentDirectory(value);
}
@@ -363,22 +305,12 @@ namespace System {
// Returns the system directory (ie, C:\WinNT\System32).
public static String SystemDirectory {
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical]
-#else
- [System.Security.SecuritySafeCritical] // auto-generated
-#endif
get {
StringBuilder sb = new StringBuilder(Path.MaxPath);
int r = Win32Native.GetSystemDirectory(sb, Path.MaxPath);
- Contract.Assert(r < Path.MaxPath, "r < Path.MaxPath");
+ Debug.Assert(r < Path.MaxPath, "r < Path.MaxPath");
if (r==0) __Error.WinIOError();
String path = sb.ToString();
-
-#if !FEATURE_CORECLR
- // Do security check
- new FileIOPermission(FileIOPermissionAccess.PathDiscovery, path).Demand();
-#endif
return path;
}
@@ -387,11 +319,10 @@ namespace System {
// Returns the windows directory (ie, C:\WinNT).
// Used by NLS+ custom culures only at the moment.
internal static String InternalWindowsDirectory {
- [System.Security.SecurityCritical] // auto-generated
get {
StringBuilder sb = new StringBuilder(Path.MaxPath);
int r = Win32Native.GetWindowsDirectory(sb, Path.MaxPath);
- Contract.Assert(r < Path.MaxPath, "r < Path.MaxPath");
+ Debug.Assert(r < Path.MaxPath, "r < Path.MaxPath");
if (r==0) __Error.WinIOError();
String path = sb.ToString();
@@ -399,11 +330,10 @@ namespace System {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static String ExpandEnvironmentVariables(String name)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
Contract.EndContractBlock();
if (name.Length == 0) {
@@ -442,63 +372,6 @@ namespace System {
int size;
-#if !FEATURE_CORECLR
- bool isFullTrust = CodeAccessSecurityEngine.QuickCheckForAllDemands();
-
- // Do a security check to guarantee we can read each of the
- // individual environment variables requested here.
- String[] varArray = name.Split(new char[] {'%'});
- StringBuilder vars = isFullTrust ? null : new StringBuilder();
-
- bool fJustExpanded = false; // to accommodate expansion alg.
-
- for(int i=1; i<varArray.Length-1; i++) { // Skip first and last tokens
- // ExpandEnvironmentStrings' greedy algorithm expands every
- // non-boundary %-delimited substring, provided the previous
- // has not been expanded.
- // if "foo" is not expandable, and "PATH" is, then both
- // %foo%PATH% and %foo%foo%PATH% will expand PATH, but
- // %PATH%PATH% will expand only once.
- // Therefore, if we've just expanded, skip this substring.
- if (varArray[i].Length == 0 || fJustExpanded == true)
- {
- fJustExpanded = false;
- continue; // Nothing to expand
- }
- // Guess a somewhat reasonable initial size, call the method, then if
- // it fails (ie, the return value is larger than our buffer size),
- // make a new buffer & try again.
- blob.Length = 0;
- String envVar = "%" + varArray[i] + "%";
- size = Win32Native.ExpandEnvironmentStrings(envVar, blob, currentSize);
- if (size == 0)
- Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
-
- // some environment variable might be changed while this function is called
- while (size > currentSize) {
- currentSize = size;
- blob.Capacity = currentSize;
- blob.Length = 0;
- size = Win32Native.ExpandEnvironmentStrings(envVar, blob, currentSize);
- if (size == 0)
- Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
- }
-
- if (!isFullTrust) {
- String temp = blob.ToString();
- fJustExpanded = (temp != envVar);
- if (fJustExpanded) { // We expanded successfully, we need to do String comparison here
- // since %FOO% can become %FOOD
- vars.Append(varArray[i]);
- vars.Append(';');
- }
- }
- }
-
- if (!isFullTrust)
- new EnvironmentPermission(EnvironmentPermissionAccess.Read, vars.ToString()).Demand();
-#endif // !FEATURE_CORECLR
-
blob.Length = 0;
size = Win32Native.ExpandEnvironmentStrings(name, blob, currentSize);
if (size == 0)
@@ -519,7 +392,6 @@ namespace System {
}
public static String MachineName {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
// UWP Debug scenarios
@@ -531,9 +403,6 @@ namespace System {
// In future release of operating systems, you might be able to rename a machine without
// rebooting. Therefore, don't cache this machine name.
-#if !FEATURE_CORECLR
- new EnvironmentPermission(EnvironmentPermissionAccess.Read, "COMPUTERNAME").Demand();
-#endif
StringBuilder buf = new StringBuilder(MaxMachineNameLength);
int len = MaxMachineNameLength;
if (Win32Native.GetComputerName(buf, ref len) == 0)
@@ -542,20 +411,17 @@ namespace System {
}
}
- [SecurityCritical]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern Int32 GetProcessorCount();
public static int ProcessorCount {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
return GetProcessorCount();
}
}
public static int SystemPageSize {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
(new EnvironmentPermission(PermissionState.Unrestricted)).Demand();
Win32Native.SYSTEM_INFO info = new Win32Native.SYSTEM_INFO();
@@ -571,11 +437,9 @@ namespace System {
**Arguments: None
**Exceptions: None.
==============================================================================*/
- [System.Security.SecuritySafeCritical] // auto-generated
public static String[] GetCommandLineArgs()
{
new EnvironmentPermission(EnvironmentPermissionAccess.Read, "Path").Demand();
-#if FEATURE_CORECLR
/*
* There are multiple entry points to a hosted app.
* The host could use ::ExecuteAssembly() or ::CreateDelegate option
@@ -591,145 +455,37 @@ namespace System {
*/
if(s_CommandLineArgs != null)
return (string[])s_CommandLineArgs.Clone();
-#endif
+
return GetCommandLineArgsNative();
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern String[] GetCommandLineArgsNative();
-#if !FEATURE_CORECLR
- // We need to keep this Fcall since it is used in AppDomain.cs.
- // If we call GetEnvironmentVariable from AppDomain.cs, we will use StringBuilder class.
- // That has side effect to change the ApartmentState of the calling Thread to MTA.
- // So runtime can't change the ApartmentState of calling thread any more.
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern String nativeGetEnvironmentVariable(String variable);
-#endif //!FEATURE_CORECLR
-
-#if FEATURE_CORECLR
private static string[] s_CommandLineArgs = null;
private static void SetCommandLineArgs(string[] cmdLineArgs)
{
s_CommandLineArgs = cmdLineArgs;
}
-#endif
-
- /*============================GetEnvironmentVariable============================
- **Action:
- **Returns:
- **Arguments:
- **Exceptions:
- ==============================================================================*/
- [System.Security.SecuritySafeCritical] // auto-generated
- public static String GetEnvironmentVariable(String variable)
- {
- if (variable == null)
- throw new ArgumentNullException("variable");
- Contract.EndContractBlock();
-
- 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;
- }
-
-#if !FEATURE_CORECLR
- (new EnvironmentPermission(EnvironmentPermissionAccess.Read, variable)).Demand();
-#endif //!FEATURE_CORECLR
-
- StringBuilder blob = StringBuilderCache.Acquire(128); // A somewhat reasonable default size
- int requiredSize = Win32Native.GetEnvironmentVariable(variable, blob, blob.Capacity);
-
- if (requiredSize == 0) { // GetEnvironmentVariable failed
- if (Marshal.GetLastWin32Error() == Win32Native.ERROR_ENVVAR_NOT_FOUND) {
- StringBuilderCache.Release(blob);
- return null;
- }
- }
-
- while (requiredSize > blob.Capacity) { // need to retry since the environment variable might be changed
- blob.Capacity = requiredSize;
- blob.Length = 0;
- requiredSize = Win32Native.GetEnvironmentVariable(variable, blob, blob.Capacity);
- }
- return StringBuilderCache.GetStringAndRelease(blob);
- }
- [System.Security.SecuritySafeCritical] // auto-generated
- public static string GetEnvironmentVariable( string variable, EnvironmentVariableTarget target)
- {
- if (variable == null)
- {
- throw new ArgumentNullException("variable");
- }
- Contract.EndContractBlock();
-
- if (target == EnvironmentVariableTarget.Process)
- {
- return GetEnvironmentVariable(variable);
- }
-
-#if FEATURE_WIN32_REGISTRY
- (new EnvironmentPermission(PermissionState.Unrestricted)).Demand();
-
- if( target == EnvironmentVariableTarget.Machine) {
- using (RegistryKey environmentKey =
- Registry.LocalMachine.OpenSubKey(@"System\CurrentControlSet\Control\Session Manager\Environment", false)) {
-
- Contract.Assert(environmentKey != null, @"HKLM\System\CurrentControlSet\Control\Session Manager\Environment is missing!");
- if (environmentKey == null) {
- return null;
- }
-
- string value = environmentKey.GetValue(variable) as string;
- return value;
- }
- }
- else if( target == EnvironmentVariableTarget.User) {
- using (RegistryKey environmentKey =
- Registry.CurrentUser.OpenSubKey("Environment", false)) {
-
- Contract.Assert(environmentKey != null, @"HKCU\Environment is missing!");
- if (environmentKey == null) {
- return null;
- }
-
- string value = environmentKey.GetValue(variable) as string;
- return value;
- }
- }
- else
-#endif // FEATURE_WIN32_REGISTRY
- {
- throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)target));
- }
- }
-
- /*===========================GetEnvironmentVariables============================
- **Action: Returns an IDictionary containing all enviroment variables and their values.
- **Returns: An IDictionary containing all environment variables and their values.
- **Arguments: None.
- **Exceptions: None.
- ==============================================================================*/
- [System.Security.SecurityCritical] // auto-generated
private unsafe static char[] GetEnvironmentCharArray()
{
char[] block = null;
// Make sure pStrings is not leaked with async exceptions
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
}
- finally {
- char * pStrings = null;
+ finally
+ {
+ char* pStrings = null;
try
{
pStrings = Win32Native.GetEnvironmentStrings();
- if (pStrings == null) {
+ if (pStrings == null)
+ {
throw new OutOfMemoryException();
}
@@ -739,7 +495,7 @@ namespace System {
// CreateProcess page (null-terminated array of null-terminated strings).
// Search for terminating \0\0 (two unicode \0's).
- char * p = pStrings;
+ char* p = pStrings;
while (!(*p == '\0' && *(p + 1) == '\0'))
p++;
@@ -747,7 +503,7 @@ namespace System {
block = new char[len];
fixed (char* pBlock = block)
- String.wstrcpy(pBlock, pStrings, len);
+ string.wstrcpy(pBlock, pStrings, len);
}
finally
{
@@ -759,275 +515,12 @@ namespace System {
return block;
}
- [System.Security.SecuritySafeCritical] // auto-generated
- public static IDictionary GetEnvironmentVariables()
- {
- 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 Hashtable(0);
- }
-
-#if !FEATURE_CORECLR
- bool isFullTrust = CodeAccessSecurityEngine.QuickCheckForAllDemands();
- StringBuilder vars = isFullTrust ? null : new StringBuilder();
- bool first = true;
-#endif
-
- char[] block = GetEnvironmentCharArray();
-
- Hashtable table = new Hashtable(20);
-
- // Copy strings out, parsing into pairs and inserting into the table.
- // The first few environment variable entries start with an '='!
- // The current working directory of every drive (except for those drives
- // you haven't cd'ed into in your DOS window) are stored in the
- // environment block (as =C:=pwd) and the program's exit code is
- // as well (=ExitCode=00000000) Skip all that start with =.
- // Read docs about Environment Blocks on MSDN's CreateProcess page.
-
- // Format for GetEnvironmentStrings is:
- // (=HiddenVar=value\0 | Variable=value\0)* \0
- // See the description of Environment Blocks in MSDN's
- // CreateProcess page (null-terminated array of null-terminated strings).
- // Note the =HiddenVar's aren't always at the beginning.
-
- for(int i=0; i<block.Length; i++) {
- int startKey = i;
- // Skip to key
- // On some old OS, the environment block can be corrupted.
- // Someline will not have '=', so we need to check for '\0'.
- while(block[i]!='=' && block[i] != '\0') {
- i++;
- }
-
- if(block[i] == '\0') {
- continue;
- }
-
- // Skip over environment variables starting with '='
- if (i-startKey==0) {
- while(block[i]!=0) {
- i++;
- }
- continue;
- }
- String key = new String(block, startKey, i-startKey);
- i++; // skip over '='
- int startValue = i;
- while(block[i]!=0) {
- // Read to end of this entry
- i++;
- }
-
- String value = new String(block, startValue, i-startValue);
- // skip over 0 handled by for loop's i++
- table[key]=value;
-
-#if !FEATURE_CORECLR
- if (!isFullTrust) {
- if( first) {
- first = false;
- }
- else {
- vars.Append(';');
- }
- vars.Append(key);
- }
-#endif
- }
-
-#if !FEATURE_CORECLR
- if (!isFullTrust)
- new EnvironmentPermission(EnvironmentPermissionAccess.Read, vars.ToString()).Demand();
-#endif
- return table;
- }
-
-#if FEATURE_WIN32_REGISTRY
- internal static IDictionary GetRegistryKeyNameValuePairs(RegistryKey registryKey) {
- Hashtable table = new Hashtable(20);
-
- if (registryKey != null) {
- string[] names = registryKey.GetValueNames();
- foreach( string name in names) {
- string value = registryKey.GetValue(name, "").ToString();
- table.Add(name, value);
- }
- }
- return table;
- }
-#endif
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public static IDictionary GetEnvironmentVariables( EnvironmentVariableTarget target) {
- if( target == EnvironmentVariableTarget.Process) {
- return GetEnvironmentVariables();
- }
-
-#if FEATURE_WIN32_REGISTRY
- (new EnvironmentPermission(PermissionState.Unrestricted)).Demand();
-
- if( target == EnvironmentVariableTarget.Machine) {
- using (RegistryKey environmentKey =
- Registry.LocalMachine.OpenSubKey(@"System\CurrentControlSet\Control\Session Manager\Environment", false)) {
-
- return GetRegistryKeyNameValuePairs(environmentKey);
- }
- }
- else if( target == EnvironmentVariableTarget.User) {
- using (RegistryKey environmentKey =
- Registry.CurrentUser.OpenSubKey("Environment", false)) {
- return GetRegistryKeyNameValuePairs(environmentKey);
- }
- }
- else
-#endif // FEATURE_WIN32_REGISTRY
- {
- throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)target));
- }
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public static void SetEnvironmentVariable(string variable, string value) {
- CheckEnvironmentVariableName(variable);
-
-#if !FEATURE_CORECLR
- new EnvironmentPermission(PermissionState.Unrestricted).Demand();
-#endif
- // explicitly null out value if is the empty string.
- if (String.IsNullOrEmpty(value) || value[0] == '\0') {
- value = null;
- }
- else {
- if( value.Length >= MaxEnvVariableValueLength) {
- throw new ArgumentException(Environment.GetResourceString("Argument_LongEnvVarValue"));
- }
- }
-
- 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();
-
- // Allow user to try to clear a environment variable
- if( errorCode == Win32Native.ERROR_ENVVAR_NOT_FOUND) {
- return;
- }
-
- // The error message from Win32 is "The filename or extension is too long",
- // which is not accurate.
- if( errorCode == Win32Native.ERROR_FILENAME_EXCED_RANGE) {
- throw new ArgumentException(Environment.GetResourceString("Argument_LongEnvVarValue"));
- }
-
- throw new ArgumentException(Win32Native.GetMessage(errorCode));
- }
- }
-
- private static void CheckEnvironmentVariableName(string variable) {
- if (variable == null) {
- throw new ArgumentNullException("variable");
- }
-
- if( variable.Length == 0) {
- throw new ArgumentException(Environment.GetResourceString("Argument_StringZeroLength"), "variable");
- }
-
- if( variable[0] == '\0') {
- throw new ArgumentException(Environment.GetResourceString("Argument_StringFirstCharIsZero"), "variable");
- }
-
- // Make sure the environment variable name isn't longer than the
- // max limit on environment variable values. (MSDN is ambiguous
- // on whether this check is necessary.)
- if( variable.Length >= MaxEnvVariableValueLength ) {
- throw new ArgumentException(Environment.GetResourceString("Argument_LongEnvVarValue"));
- }
-
- if( variable.IndexOf('=') != -1) {
- throw new ArgumentException(Environment.GetResourceString("Argument_IllegalEnvVarName"));
- }
- Contract.EndContractBlock();
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public static void SetEnvironmentVariable(string variable, string value, EnvironmentVariableTarget target) {
- if( target == EnvironmentVariableTarget.Process) {
- SetEnvironmentVariable(variable, value);
- return;
- }
-
- CheckEnvironmentVariableName(variable);
-
- // System-wide environment variables stored in the registry are
- // limited to 1024 chars for the environment variable name.
- if (variable.Length >= MaxSystemEnvVariableLength) {
- throw new ArgumentException(Environment.GetResourceString("Argument_LongEnvVarName"));
- }
-
- new EnvironmentPermission(PermissionState.Unrestricted).Demand();
- // explicitly null out value if is the empty string.
- if (String.IsNullOrEmpty(value) || value[0] == '\0') {
- value = null;
- }
-#if FEATURE_WIN32_REGISTRY
- if( target == EnvironmentVariableTarget.Machine) {
- using (RegistryKey environmentKey =
- Registry.LocalMachine.OpenSubKey(@"System\CurrentControlSet\Control\Session Manager\Environment", true)) {
-
- Contract.Assert(environmentKey != null, @"HKLM\System\CurrentControlSet\Control\Session Manager\Environment is missing!");
- if (environmentKey != null) {
- if (value == null)
- environmentKey.DeleteValue(variable, false);
- else
- environmentKey.SetValue(variable, value);
- }
- }
- }
- else if( target == EnvironmentVariableTarget.User) {
- // User-wide environment variables stored in the registry are
- // limited to 255 chars for the environment variable name.
- if (variable.Length >= MaxUserEnvVariableLength) {
- throw new ArgumentException(Environment.GetResourceString("Argument_LongEnvVarValue"));
- }
- using (RegistryKey environmentKey =
- Registry.CurrentUser.OpenSubKey("Environment", true)) {
- Contract.Assert(environmentKey != null, @"HKCU\Environment is missing!");
- if (environmentKey != null) {
- if (value == null)
- environmentKey.DeleteValue(variable, false);
- else
- environmentKey.SetValue(variable, value);
- }
- }
- }
- else
- {
- throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)target));
- }
- // send a WM_SETTINGCHANGE message to all windows
- IntPtr r = Win32Native.SendMessageTimeout(new IntPtr(Win32Native.HWND_BROADCAST), Win32Native.WM_SETTINGCHANGE, IntPtr.Zero, "Environment", 0, 1000, IntPtr.Zero);
-
- if (r == IntPtr.Zero) BCLDebug.Assert(false, "SetEnvironmentVariable failed: " + Marshal.GetLastWin32Error());
-
-#else // FEATURE_WIN32_REGISTRY
- throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)target));
-#endif
- }
-
-
/*===============================GetLogicalDrives===============================
**Action: Retrieves the names of the logical drives on this machine in the form "C:\".
**Arguments: None.
**Exceptions: IOException.
**Permissions: SystemInfo Permission.
==============================================================================*/
- [System.Security.SecuritySafeCritical] // auto-generated
public static String[] GetLogicalDrives() {
new EnvironmentPermission(PermissionState.Unrestricted).Demand();
@@ -1097,12 +590,10 @@ namespace System {
**Arguments:
**Exceptions:
==============================================================================*/
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
private static extern long GetWorkingSet();
public static long WorkingSet {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
new EnvironmentPermission(PermissionState.Unrestricted).Demand();
return GetWorkingSet();
@@ -1117,7 +608,6 @@ namespace System {
**Exceptions:
==============================================================================*/
public static OperatingSystem OSVersion {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
Contract.Ensures(Contract.Result<OperatingSystem>() != null);
@@ -1141,7 +631,7 @@ namespace System {
Version v = new Version(osvi.MajorVersion, osvi.MinorVersion, osvi.BuildNumber, (osviEx.ServicePackMajor << 16) |osviEx.ServicePackMinor);
m_os = new OperatingSystem(id, v, osvi.CSDVersion);
}
- Contract.Assert(m_os != null, "m_os != null");
+ Debug.Assert(m_os != null, "m_os != null");
return m_os;
}
}
@@ -1186,7 +676,6 @@ namespace System {
// Does the current version of Windows have Windows Runtime suppport?
internal static bool IsWinRTSupported {
- [SecuritySafeCritical]
get {
if (!s_CheckedWinRT) {
s_WinRTSupported = WinRTSupported();
@@ -1197,7 +686,6 @@ namespace System {
}
}
- [SecurityCritical]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
@@ -1206,11 +694,9 @@ namespace System {
#endif // FEATURE_CORESYSTEM
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool GetVersion(Microsoft.Win32.Win32Native.OSVERSIONINFO osVer);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool GetVersionEx(Microsoft.Win32.Win32Native.OSVERSIONINFOEX osVer);
@@ -1222,7 +708,6 @@ namespace System {
**Exceptions:
==============================================================================*/
public static String StackTrace {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
Contract.Ensures(Contract.Result<String>() != null);
@@ -1231,9 +716,6 @@ namespace System {
}
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
internal static String GetStackTrace(Exception e, bool needFileInfo)
{
// Note: Setting needFileInfo to true will start up COM and set our
@@ -1250,7 +732,6 @@ namespace System {
return st.ToString( System.Diagnostics.StackTrace.TraceFormat.Normal );
}
- [System.Security.SecuritySafeCritical] // auto-generated
private static void InitResourceHelper() {
// Only the default AppDomain should have a ResourceHelper. All calls to
// GetResourceString from any AppDomain delegate to GetResourceStringLocal
@@ -1275,20 +756,13 @@ namespace System {
}
}
-#if !FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal extern static String GetResourceFromDefault(String key);
-#endif
-
// 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
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
+ // 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();
@@ -1296,30 +770,74 @@ namespace System {
return m_resHelper.GetResourceString(key);
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static String GetResourceString(String key) {
-#if FEATURE_CORECLR
return GetResourceStringLocal(key);
-#else
- return GetResourceFromDefault(key);
-#endif //FEATURE_CORECLR
}
- [System.Security.SecuritySafeCritical] // auto-generated
- internal static String GetResourceString(String key, params Object[] values) {
- String s = GetResourceString(key);
- return String.Format(CultureInfo.CurrentCulture, s, values);
+ // 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 });
}
- //The following two internal methods are not used anywhere within the framework,
+ 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, object val0, object val1, object val2, object val3, object val4)
+ {
+ return GetResourceStringFormatted(key, new object[] { val0, val1, val2, val3, val4 });
+ }
+
+ internal static string GetResourceString(string key, object val0, object val1, object val2, object val3, object val4, object val5)
+ {
+ return GetResourceStringFormatted(key, new object[] { val0, val1, val2, val3, val4, val5 });
+ }
+
+ internal static String GetResourceString(string key, params object[] values)
+ {
+ return GetResourceStringFormatted(key, values);
+ }
+
+ // 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)
+ {
+ string rs = GetResourceString(key);
+ return String.Format(CultureInfo.CurrentCulture, rs, values);
+ }
+
+ // The following two internal methods are not used anywhere within the framework,
// but are being kept around as external platforms built on top of us have taken
// dependency by using private reflection on them for getting system resource strings
- internal static String GetRuntimeResourceString(String key) {
+ private static String GetRuntimeResourceString(String key) {
return GetResourceString(key);
}
- internal static String GetRuntimeResourceString(String key, params Object[] values) {
- return GetResourceString(key,values);
+ private static String GetRuntimeResourceString(String key, params Object[] values) {
+ return GetResourceStringFormatted(key,values);
}
public static bool Is64BitProcess {
@@ -1333,7 +851,6 @@ namespace System {
}
public static bool Is64BitOperatingSystem {
- [System.Security.SecuritySafeCritical]
get {
#if BIT64
// 64-bit programs run only on 64-bit
@@ -1348,20 +865,11 @@ namespace System {
}
public static extern bool HasShutdownStarted {
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
get;
}
-#if !FEATURE_CORECLR
- // This is the temporary Whidbey stub for compatibility flags
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- [System.Security.SecurityCritical]
- internal static extern bool GetCompatibilityFlag(CompatibilityFlag flag);
-#endif //!FEATURE_CORECLR
-
public static string UserName {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
new EnvironmentPermission(EnvironmentPermissionAccess.Read,"UserName").Demand();
@@ -1375,40 +883,13 @@ namespace System {
}
}
- // Note that this is a handle to a process window station, but it does
- // not need to be closed. CloseWindowStation would ignore this handle.
- // We also do handle equality checking as well. This isn't a great fit
- // for SafeHandle. We don't gain anything by using SafeHandle here.
-#if !FEATURE_CORECLR
- private static volatile IntPtr processWinStation; // Doesn't need to be initialized as they're zero-init.
- private static volatile bool isUserNonInteractive;
-#endif
-
- public static bool UserInteractive {
- [System.Security.SecuritySafeCritical] // auto-generated
+ public static bool UserInteractive
+ {
get {
-#if !FEATURE_CORECLR
- IntPtr hwinsta = Win32Native.GetProcessWindowStation();
- if (hwinsta != IntPtr.Zero && processWinStation != hwinsta) {
- int lengthNeeded = 0;
- Win32Native.USEROBJECTFLAGS flags = new Win32Native.USEROBJECTFLAGS();
- if (Win32Native.GetUserObjectInformation(hwinsta, Win32Native.UOI_FLAGS, flags, Marshal.SizeOf(flags),ref lengthNeeded)) {
- if ((flags.dwFlags & Win32Native.WSF_VISIBLE) == 0) {
- isUserNonInteractive = true;
- }
- }
- processWinStation = hwinsta;
- }
-
- // The logic is reversed to avoid static initialization to true
- return !isUserNonInteractive;
-#else
return true;
-#endif
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static string GetFolderPath(SpecialFolder folder) {
if (!Enum.IsDefined(typeof(SpecialFolder), folder))
throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)folder));
@@ -1417,7 +898,6 @@ namespace System {
return InternalGetFolderPath(folder, SpecialFolderOption.None);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static string GetFolderPath(SpecialFolder folder, SpecialFolderOption option) {
if (!Enum.IsDefined(typeof(SpecialFolder),folder))
throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)folder));
@@ -1428,13 +908,11 @@ namespace System {
return InternalGetFolderPath(folder, option);
}
- [System.Security.SecurityCritical]
internal static string UnsafeGetFolderPath(SpecialFolder folder)
{
return InternalGetFolderPath(folder, SpecialFolderOption.None, suppressSecurityChecks: true);
}
- [System.Security.SecurityCritical]
private static string InternalGetFolderPath(SpecialFolder folder, SpecialFolderOption option, bool suppressSecurityChecks = false)
{
#if FEATURE_CORESYSTEM
@@ -1455,13 +933,6 @@ namespace System {
throw new PlatformNotSupportedException();
}
#else // FEATURE_CORESYSTEM
-#if !FEATURE_CORECLR
- if (option == SpecialFolderOption.Create && !suppressSecurityChecks) {
- FileIOPermission createPermission = new FileIOPermission(PermissionState.None);
- createPermission.AllFiles = FileIOPermissionAccess.Write;
- createPermission.Demand();
- }
-#endif
StringBuilder sb = new StringBuilder(Path.MaxPath);
int hresult = Win32Native.SHGetFolderPath(IntPtr.Zero, /* hwndOwner: [in] Reserved */
@@ -1499,14 +970,12 @@ namespace System {
// On CoreCLR we can check with the host if we're not trying to use any special options.
// Otherwise, we need to do a full demand since hosts aren't expecting to handle requests to
// create special folders.
-#if FEATURE_CORECLR
if (option == SpecialFolderOption.None)
{
FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, s);
state.EnsureState();
}
else
-#endif // FEATURE_CORECLR
{
new FileIOPermission(FileIOPermissionAccess.PathDiscovery, s).Demand();
}
@@ -1517,7 +986,6 @@ namespace System {
public static string UserDomainName
{
- [System.Security.SecuritySafeCritical] // auto-generated
get {
new EnvironmentPermission(EnvironmentPermissionAccess.Read,"UserDomain").Demand();
@@ -1650,7 +1118,7 @@ namespace System {
//
// "MyDocuments" is a better name than "Personal"
//
- MyDocuments = Win32Native.CSIDL_PERSONAL,
+ MyDocuments = Win32Native.CSIDL_PERSONAL,
//
// Represents the program files folder.
//
@@ -1658,101 +1126,7 @@ namespace System {
//
// Represents the folder for components that are shared across applications.
//
- CommonProgramFiles = Win32Native.CSIDL_PROGRAM_FILES_COMMON,
-#if !FEATURE_CORECLR
- //
- // <user name>\Start Menu\Programs\Administrative Tools
- //
- AdminTools = Win32Native.CSIDL_ADMINTOOLS,
- //
- // USERPROFILE\Local Settings\Application Data\Microsoft\CD Burning
- //
- CDBurning = Win32Native.CSIDL_CDBURN_AREA,
- //
- // All Users\Start Menu\Programs\Administrative Tools
- //
- CommonAdminTools = Win32Native.CSIDL_COMMON_ADMINTOOLS,
- //
- // All Users\Documents
- //
- CommonDocuments = Win32Native.CSIDL_COMMON_DOCUMENTS,
- //
- // All Users\My Music
- //
- CommonMusic = Win32Native.CSIDL_COMMON_MUSIC,
- //
- // Links to All Users OEM specific apps
- //
- CommonOemLinks = Win32Native.CSIDL_COMMON_OEM_LINKS,
- //
- // All Users\My Pictures
- //
- CommonPictures = Win32Native.CSIDL_COMMON_PICTURES,
- //
- // All Users\Start Menu
- //
- CommonStartMenu = Win32Native.CSIDL_COMMON_STARTMENU,
- //
- // All Users\Start Menu\Programs
- //
- CommonPrograms = Win32Native.CSIDL_COMMON_PROGRAMS,
- //
- // All Users\Startup
- //
- CommonStartup = Win32Native.CSIDL_COMMON_STARTUP,
- //
- // All Users\Desktop
- //
- CommonDesktopDirectory = Win32Native.CSIDL_COMMON_DESKTOPDIRECTORY,
- //
- // All Users\Templates
- //
- CommonTemplates = Win32Native.CSIDL_COMMON_TEMPLATES,
- //
- // All Users\My Video
- //
- CommonVideos = Win32Native.CSIDL_COMMON_VIDEO,
- //
- // windows\fonts
- //
- Fonts = Win32Native.CSIDL_FONTS,
- //
- // %APPDATA%\Microsoft\Windows\Network Shortcuts
- //
- NetworkShortcuts = Win32Native.CSIDL_NETHOOD,
- //
- // %APPDATA%\Microsoft\Windows\Printer Shortcuts
- //
- PrinterShortcuts = Win32Native.CSIDL_PRINTHOOD,
- //
- // USERPROFILE
- //
- UserProfile = Win32Native.CSIDL_PROFILE,
- //
- // x86 Program Files\Common on RISC
- //
- CommonProgramFilesX86 = Win32Native.CSIDL_PROGRAM_FILES_COMMONX86,
- //
- // x86 C:\Program Files on RISC
- //
- ProgramFilesX86 = Win32Native.CSIDL_PROGRAM_FILESX86,
- //
- // Resource Directory
- //
- Resources = Win32Native.CSIDL_RESOURCES,
- //
- // Localized Resource Directory
- //
- LocalizedResources = Win32Native.CSIDL_RESOURCES_LOCALIZED,
- //
- // %windir%\System32 or %windir%\syswow64
- //
- SystemX86 = Win32Native.CSIDL_SYSTEMX86,
- //
- // GetWindowsDirectory()
- //
- Windows = Win32Native.CSIDL_WINDOWS,
-#endif // !FEATURE_CORECLR
+ CommonProgramFiles = Win32Native.CSIDL_PROGRAM_FILES_COMMON,
}
public static int CurrentManagedThreadId
@@ -1764,5 +1138,367 @@ namespace System {
}
}
+ internal static extern int CurrentProcessorNumber
+ {
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ get;
+ }
+
+ public static string GetEnvironmentVariable(string variable)
+ {
+ if (variable == null)
+ {
+ throw new ArgumentNullException(nameof(variable));
+ }
+
+ // separated from the EnvironmentVariableTarget overload to help with tree shaking in common case
+ return GetEnvironmentVariableCore(variable);
+ }
+
+ public static string GetEnvironmentVariable(string variable, EnvironmentVariableTarget target)
+ {
+ if (variable == null)
+ {
+ throw new ArgumentNullException(nameof(variable));
+ }
+
+ ValidateTarget(target);
+
+ return GetEnvironmentVariableCore(variable, target);
+ }
+
+ public static IDictionary GetEnvironmentVariables()
+ {
+ // separated from the EnvironmentVariableTarget overload to help with tree shaking in common case
+ return GetEnvironmentVariablesCore();
+ }
+
+ public static IDictionary GetEnvironmentVariables(EnvironmentVariableTarget target)
+ {
+ ValidateTarget(target);
+
+ return GetEnvironmentVariablesCore(target);
+ }
+
+ public static void SetEnvironmentVariable(string variable, string value)
+ {
+ ValidateVariableAndValue(variable, ref value);
+
+ // separated from the EnvironmentVariableTarget overload to help with tree shaking in common case
+ SetEnvironmentVariableCore(variable, value);
+ }
+
+ public static void SetEnvironmentVariable(string variable, string value, EnvironmentVariableTarget target)
+ {
+ ValidateVariableAndValue(variable, ref value);
+ ValidateTarget(target);
+
+ SetEnvironmentVariableCore(variable, value, target);
+ }
+
+ private static void ValidateVariableAndValue(string variable, ref string value)
+ {
+ const int MaxEnvVariableValueLength = 32767;
+
+ if (variable == null)
+ {
+ throw new ArgumentNullException(nameof(variable));
+ }
+ if (variable.Length == 0)
+ {
+ throw new ArgumentException(GetResourceString("Argument_StringZeroLength"), nameof(variable));
+ }
+ if (variable[0] == '\0')
+ {
+ throw new ArgumentException(GetResourceString("Argument_StringFirstCharIsZero"), nameof(variable));
+ }
+ if (variable.Length >= MaxEnvVariableValueLength)
+ {
+ throw new ArgumentException(GetResourceString("Argument_LongEnvVarValue"), nameof(variable));
+ }
+ if (variable.IndexOf('=') != -1)
+ {
+ throw new ArgumentException(GetResourceString("Argument_IllegalEnvVarName"), nameof(variable));
+ }
+
+ if (string.IsNullOrEmpty(value) || value[0] == '\0')
+ {
+ // Explicitly null out value if it's empty
+ value = null;
+ }
+ else if (value.Length >= MaxEnvVariableValueLength)
+ {
+ throw new ArgumentException(GetResourceString("Argument_LongEnvVarValue"), nameof(value));
+ }
+ }
+
+ private static void ValidateTarget(EnvironmentVariableTarget target)
+ {
+ if (target != EnvironmentVariableTarget.Process &&
+ target != EnvironmentVariableTarget.Machine &&
+ target != EnvironmentVariableTarget.User)
+ {
+ throw new ArgumentOutOfRangeException(nameof(target), target, SR.Format(GetResourceString("Arg_EnumIllegalVal"), target));
+ }
+ }
+
+ private static Dictionary<string, string> GetRawEnvironmentVariables()
+ {
+ // Format for GetEnvironmentStrings is:
+ // (=HiddenVar=value\0 | Variable=value\0)* \0
+ // See the description of Environment Blocks in MSDN's
+ // CreateProcess page (null-terminated array of null-terminated strings).
+ // Note the =HiddenVar's aren't always at the beginning.
+
+ // Copy strings out, parsing into pairs and inserting into the table.
+ // The first few environment variable entries start with an '='.
+ // The current working directory of every drive (except for those drives
+ // you haven't cd'ed into in your DOS window) are stored in the
+ // environment block (as =C:=pwd) and the program's exit code is
+ // as well (=ExitCode=00000000).
+
+ var results = new Dictionary<string, string>();
+ char[] block = GetEnvironmentCharArray();
+ for (int i = 0; i < block.Length; i++)
+ {
+ int startKey = i;
+
+ // Skip to key. On some old OS, the environment block can be corrupted.
+ // Some will not have '=', so we need to check for '\0'.
+ while (block[i] != '=' && block[i] != '\0') i++;
+ if (block[i] == '\0') continue;
+
+ // Skip over environment variables starting with '='
+ if (i - startKey == 0)
+ {
+ while (block[i] != 0) i++;
+ continue;
+ }
+
+ string key = new string(block, startKey, i - startKey);
+ i++; // skip over '='
+
+ int startValue = i;
+ while (block[i] != 0) i++; // Read to end of this entry
+ string value = new string(block, startValue, i - startValue); // skip over 0 handled by for loop's i++
+
+ results[key] = value;
+ }
+ return results;
+ }
+
+ 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);
+
+ if (requiredSize == 0 && Marshal.GetLastWin32Error() == Win32Native.ERROR_ENVVAR_NOT_FOUND)
+ {
+ StringBuilderCache.Release(sb);
+ return null;
+ }
+
+ while (requiredSize > sb.Capacity)
+ {
+ sb.Capacity = requiredSize;
+ sb.Length = 0;
+ requiredSize = Win32Native.GetEnvironmentVariable(variable, sb, sb.Capacity);
+ }
+
+ return StringBuilderCache.GetStringAndRelease(sb);
+ }
+
+ private static string GetEnvironmentVariableCore(string variable, EnvironmentVariableTarget target)
+ {
+ if (target == EnvironmentVariableTarget.Process)
+ return GetEnvironmentVariableCore(variable);
+
+#if !FEATURE_WIN32_REGISTRY
+ return null;
+#else
+ RegistryKey baseKey;
+ string keyName;
+
+ if (target == EnvironmentVariableTarget.Machine)
+ {
+ baseKey = Registry.LocalMachine;
+ keyName = @"System\CurrentControlSet\Control\Session Manager\Environment";
+ }
+ else if (target == EnvironmentVariableTarget.User)
+ {
+ Debug.Assert(target == EnvironmentVariableTarget.User);
+ baseKey = Registry.CurrentUser;
+ keyName = "Environment";
+ }
+ else
+ {
+ throw new ArgumentException(GetResourceString("Arg_EnumIllegalVal", (int)target));
+ }
+
+ using (RegistryKey environmentKey = baseKey.OpenSubKey(keyName, writable: false))
+ {
+ return environmentKey?.GetValue(variable) as string;
+ }
+#endif
+ }
+
+ 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();
+ }
+
+ private static IDictionary GetEnvironmentVariablesCore(EnvironmentVariableTarget target)
+ {
+ if (target == EnvironmentVariableTarget.Process)
+ return GetEnvironmentVariablesCore();
+
+#if !FEATURE_WIN32_REGISTRY
+ // Without registry support we have nothing to return
+ return new Dictionary<string, string>(0);
+#else
+ RegistryKey baseKey;
+ string keyName;
+ if (target == EnvironmentVariableTarget.Machine)
+ {
+ baseKey = Registry.LocalMachine;
+ keyName = @"System\CurrentControlSet\Control\Session Manager\Environment";
+ }
+ else if (target == EnvironmentVariableTarget.User)
+ {
+ Debug.Assert(target == EnvironmentVariableTarget.User);
+ baseKey = Registry.CurrentUser;
+ keyName = @"Environment";
+ }
+ else
+ {
+ throw new ArgumentException(GetResourceString("Arg_EnumIllegalVal", (int)target));
+ }
+
+ using (RegistryKey environmentKey = baseKey.OpenSubKey(keyName, writable: false))
+ {
+ var table = new Dictionary<string, string>();
+ if (environmentKey != null)
+ {
+ foreach (string name in environmentKey.GetValueNames())
+ {
+ table.Add(name, environmentKey.GetValue(name, "").ToString());
+ }
+ }
+ return table;
+ }
+#endif // FEATURE_WIN32_REGISTRY
+ }
+
+ private static void SetEnvironmentVariableCore(string variable, string value)
+ {
+ // explicitly null out value if is the empty string.
+ 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();
+
+ switch (errorCode)
+ {
+ case Win32Native.ERROR_ENVVAR_NOT_FOUND:
+ // Allow user to try to clear a environment variable
+ return;
+ 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"));
+ default:
+ throw new ArgumentException(Win32Native.GetMessage(errorCode));
+ }
+ }
+ }
+
+ private static void SetEnvironmentVariableCore(string variable, string value, EnvironmentVariableTarget target)
+ {
+ if (target == EnvironmentVariableTarget.Process)
+ {
+ SetEnvironmentVariableCore(variable, value);
+ return;
+ }
+
+#if !FEATURE_WIN32_REGISTRY
+ // other targets ignored
+ return;
+#else
+ // explicitly null out value if is the empty string.
+ if (string.IsNullOrEmpty(value) || value[0] == '\0')
+ value = null;
+
+ RegistryKey baseKey;
+ string keyName;
+
+ if (target == EnvironmentVariableTarget.Machine)
+ {
+ baseKey = Registry.LocalMachine;
+ keyName = @"System\CurrentControlSet\Control\Session Manager\Environment";
+ }
+ else if (target == EnvironmentVariableTarget.User)
+ {
+ Debug.Assert(target == EnvironmentVariableTarget.User);
+
+ // User-wide environment variables stored in the registry are limited to 255 chars for the environment variable name.
+ const int MaxUserEnvVariableLength = 255;
+ if (variable.Length >= MaxUserEnvVariableLength)
+ {
+ throw new ArgumentException(GetResourceString("Argument_LongEnvVarValue"), nameof(variable));
+ }
+
+ baseKey = Registry.CurrentUser;
+ keyName = "Environment";
+ }
+ else
+ {
+ throw new ArgumentException(GetResourceString("Arg_EnumIllegalVal", (int)target));
+ }
+
+ using (RegistryKey environmentKey = baseKey.OpenSubKey(keyName, writable: true))
+ {
+ if (environmentKey != null)
+ {
+ if (value == null)
+ {
+ environmentKey.DeleteValue(variable, throwOnMissingValue: false);
+ }
+ else
+ {
+ environmentKey.SetValue(variable, value);
+ }
+ }
+ }
+
+ // send a WM_SETTINGCHANGE message to all windows
+ IntPtr r = Win32Native.SendMessageTimeout(new IntPtr(Win32Native.HWND_BROADCAST),
+ Win32Native.WM_SETTINGCHANGE, IntPtr.Zero, "Environment", 0, 1000, IntPtr.Zero);
+
+ if (r == IntPtr.Zero) Debug.Assert(false, "SetEnvironmentVariable failed: " + Marshal.GetLastWin32Error());
+#endif // FEATURE_WIN32_REGISTRY
+ }
}
}
diff --git a/src/mscorlib/src/System/Exception.cs b/src/mscorlib/src/System/Exception.cs
index 12799e7875..a8ee328f1c 100644
--- a/src/mscorlib/src/System/Exception.cs
+++ b/src/mscorlib/src/System/Exception.cs
@@ -73,11 +73,10 @@ namespace System {
_innerException = innerException;
}
- [System.Security.SecuritySafeCritical] // auto-generated
protected Exception(SerializationInfo info, StreamingContext context)
{
if (info==null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
_className = info.GetString("ClassName");
@@ -143,7 +142,6 @@ namespace System {
}
public virtual IDictionary Data {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
if (_data == null)
if (IsImmutableAgileException(this))
@@ -155,7 +153,6 @@ namespace System {
}
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool IsImmutableAgileException(Exception e);
@@ -260,11 +257,9 @@ namespace System {
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static extern private IRuntimeMethodInfo GetMethodFromStackTrace(Object stackTrace);
- [System.Security.SecuritySafeCritical] // auto-generated
private MethodBase GetExceptionMethodFromStackTrace()
{
IRuntimeMethodInfo method = GetMethodFromStackTrace(_stackTrace);
@@ -277,7 +272,6 @@ namespace System {
}
public MethodBase TargetSite {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
return GetTargetSiteInternal();
}
@@ -285,7 +279,6 @@ namespace System {
// this function is provided as a private helper to avoid the security demand
- [System.Security.SecurityCritical] // auto-generated
private MethodBase GetTargetSiteInternal() {
if (_exceptionMethod!=null) {
return _exceptionMethod;
@@ -306,9 +299,6 @@ namespace System {
// available, null is returned.
public virtual String StackTrace
{
-#if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical]
-#endif
get
{
// By default attempt to include file and line number info
@@ -321,24 +311,11 @@ namespace System {
// is true. Note that this requires FileIOPermission(PathDiscovery), and so
// will usually fail in CoreCLR. To avoid the demand and resulting
// SecurityException we can explicitly not even try to get fileinfo.
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
private string GetStackTrace(bool needFileInfo)
{
string stackTraceString = _stackTraceString;
string remoteStackTraceString = _remoteStackTraceString;
-#if !FEATURE_CORECLR
- if (!needFileInfo)
- {
- // Filter out file names/paths and line numbers from _stackTraceString and _remoteStackTraceString.
- // This is used only when generating stack trace for Watson where the strings must be PII-free.
- stackTraceString = StripFileInfo(stackTraceString, false);
- remoteStackTraceString = StripFileInfo(remoteStackTraceString, true);
- }
-#endif // !FEATURE_CORECLR
-
// if no stack trace, try to get one
if (stackTraceString != null)
{
@@ -380,9 +357,6 @@ namespace System {
}
public virtual String Source {
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
get {
if (_source == null)
{
@@ -411,23 +385,14 @@ namespace System {
return _source;
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
set { _source = value; }
}
-#if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical]
-#endif
public override String ToString()
{
return ToString(true, true);
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
private String ToString(bool needFileLineInfo, bool needMessage) {
String message = (needMessage ? Message : null);
String s;
@@ -454,7 +419,6 @@ namespace System {
return s;
}
- [System.Security.SecurityCritical] // auto-generated
private String GetExceptionMethodString() {
MethodBase methBase = GetTargetSiteInternal();
if (methBase==null) {
@@ -487,7 +451,7 @@ namespace System {
result.Append(separator);
result.Append(rci.ToString());
} else {
- Contract.Assert(methBase is MethodInfo, "[Exception.GetExceptionMethodString]methBase is MethodInfo");
+ Debug.Assert(methBase is MethodInfo, "[Exception.GetExceptionMethodString]methBase is MethodInfo");
RuntimeMethodInfo rmi = (RuntimeMethodInfo)methBase;
Type t = rmi.DeclaringType;
result.Append((int)MemberTypes.Method);
@@ -507,9 +471,8 @@ namespace System {
return result.ToString();
}
- [System.Security.SecurityCritical] // auto-generated
private MethodBase GetExceptionMethodFromString() {
- Contract.Assert(_exceptionMethodString != null, "Method string cannot be NULL!");
+ Debug.Assert(_exceptionMethodString != null, "Method string cannot be NULL!");
String[] args = _exceptionMethodString.Split(new char[]{'\0', '\n'});
if (args.Length!=5) {
throw new SerializationException();
@@ -536,14 +499,19 @@ namespace System {
add { _safeSerializationManager.SerializeObjectState += value; }
remove { _safeSerializationManager.SerializeObjectState -= value; }
}
+#else
+ protected event EventHandler<SafeSerializationEventArgs> SerializeObjectState
+ {
+ add { throw new PlatformNotSupportedException();}
+ remove { throw new PlatformNotSupportedException();}
+ }
#endif // FEATURE_SERIALIZATION
- [System.Security.SecurityCritical] // auto-generated_required
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
{
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
@@ -591,7 +559,7 @@ namespace System {
// often created in the VM with AllocateObject instead if the managed construtor)
// If you are adding code to use a SafeSerializationManager from an mscorlib exception, update
// this assert to ensure that it fails when that exception's _safeSerializationManager is NULL
- Contract.Assert(((_safeSerializationManager != null) || (this.GetType().Assembly == typeof(object).Assembly)),
+ Debug.Assert(((_safeSerializationManager != null) || (this.GetType().Assembly == typeof(object).Assembly)),
"User defined exceptions must have a valid _safeSerializationManager");
// Handle serializing any transparent or partial trust subclass data
@@ -656,9 +624,6 @@ namespace System {
// This is used by the runtime when re-throwing a managed exception. It will
// copy the stack trace to _remoteStackTraceString.
-#if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical]
-#endif
internal void InternalPreserveStackTrace()
{
string tmpStackTraceString;
@@ -731,33 +696,21 @@ namespace System {
}
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void PrepareForForeignExceptionRaise();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void GetStackTracesDeepCopy(Exception exception, out object currentStackTrace, out object dynamicMethodArray);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void SaveStackTracesFromDeepCopy(Exception exception, object currentStackTrace, object dynamicMethodArray);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern object CopyStackTrace(object currentStackTrace);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern object CopyDynamicMethods(object currentDynamicMethods);
-#if !FEATURE_CORECLR
- [System.Security.SecuritySafeCritical]
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private extern string StripFileInfo(string stackTrace, bool isRemoteStackTrace);
-#endif // !FEATURE_CORECLR
-
- [SecuritySafeCritical]
internal object DeepCopyStackTrace(object currentStackTrace)
{
if (currentStackTrace != null)
@@ -770,7 +723,6 @@ namespace System {
}
}
- [SecuritySafeCritical]
internal object DeepCopyDynamicMethods(object currentDynamicMethods)
{
if (currentDynamicMethods != null)
@@ -783,7 +735,6 @@ namespace System {
}
}
- [SecuritySafeCritical]
internal void GetStackTracesDeepCopy(out object currentStackTrace, out object dynamicMethodArray)
{
GetStackTracesDeepCopy(this, out currentStackTrace, out dynamicMethodArray);
@@ -791,7 +742,6 @@ namespace System {
// This is invoked by ExceptionDispatchInfo.Throw to restore the exception stack trace, corresponding to the original throw of the
// exception, just before the exception is "rethrown".
- [SecuritySafeCritical]
internal void RestoreExceptionDispatchInfo(System.Runtime.ExceptionServices.ExceptionDispatchInfo exceptionDispatchInfo)
{
bool fCanProcessException = !(IsImmutableAgileException(this));
@@ -894,7 +844,6 @@ namespace System {
// InternalToString is called by the runtime to get the exception text
// and create a corresponding CrossAppDomainMarshaledException
- [System.Security.SecurityCritical] // auto-generated
internal virtual String InternalToString()
{
try
@@ -923,13 +872,11 @@ namespace System {
internal bool IsTransient
{
- [System.Security.SecuritySafeCritical] // auto-generated
get {
return nIsTransient(_HResult);
}
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern static bool nIsTransient(int hr);
@@ -951,7 +898,6 @@ namespace System {
}
// See comment on ExceptionMessageKind
- [System.Security.SecuritySafeCritical] // auto-generated
internal static String GetMessageFromNativeResources(ExceptionMessageKind kind)
{
string retMesg = null;
@@ -959,16 +905,11 @@ namespace System {
return retMesg;
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void GetMessageFromNativeResources(ExceptionMessageKind kind, StringHandleOnStack retMesg);
}
-
-
-#if FEATURE_CORECLR
-
//--------------------------------------------------------------------------
// Telesto: Telesto doesn't support appdomain marshaling of objects so
// managed exceptions that leak across appdomain boundaries are flatted to
@@ -990,17 +931,10 @@ namespace System {
// Normally, only Telesto's UEF will see these exceptions.
// This override prints out the original Exception's ToString()
// output and hides the fact that it is wrapped inside another excepton.
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
internal override String InternalToString()
{
return Message;
}
-
}
-#endif
-
-
}
diff --git a/src/mscorlib/src/System/FormattableString.cs b/src/mscorlib/src/System/FormattableString.cs
index ef56bcf3e0..294b2c1846 100644
--- a/src/mscorlib/src/System/FormattableString.cs
+++ b/src/mscorlib/src/System/FormattableString.cs
@@ -67,7 +67,7 @@ namespace System
{
if (formattable == null)
{
- throw new ArgumentNullException("formattable");
+ throw new ArgumentNullException(nameof(formattable));
}
return formattable.ToString(Globalization.CultureInfo.InvariantCulture);
diff --git a/src/mscorlib/src/System/GC.cs b/src/mscorlib/src/System/GC.cs
index 73c676df7d..e338e44526 100644
--- a/src/mscorlib/src/System/GC.cs
+++ b/src/mscorlib/src/System/GC.cs
@@ -63,71 +63,56 @@ namespace System {
public static class GC
{
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern int GetGCLatencyMode();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern int SetGCLatencyMode(int newLatencyMode);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal static extern int _StartNoGCRegion(long totalSize, bool lohSizeKnown, long lohSize, bool disallowFullBlockingGC);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal static extern int _EndNoGCRegion();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern int GetLOHCompactionMode();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void SetLOHCompactionMode(int newLOHCompactionMode);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern int GetGenerationWR(IntPtr handle);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern long GetTotalMemory();
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void _Collect(int generation, int mode);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern int GetMaxGeneration();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
private static extern int _CollectionCount (int generation, int getSpecialGCCount);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool IsServerGC();
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
private static extern void _AddMemoryPressure(UInt64 bytesAllocated);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
private static extern void _RemoveMemoryPressure(UInt64 bytesAllocated);
- [System.Security.SecurityCritical] // auto-generated_required
public static void AddMemoryPressure (long bytesAllocated) {
if( bytesAllocated <= 0) {
- throw new ArgumentOutOfRangeException("bytesAllocated",
+ throw new ArgumentOutOfRangeException(nameof(bytesAllocated),
Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
}
@@ -140,15 +125,14 @@ namespace System {
_AddMemoryPressure((ulong)bytesAllocated);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static void RemoveMemoryPressure (long bytesAllocated) {
if( bytesAllocated <= 0) {
- throw new ArgumentOutOfRangeException("bytesAllocated",
+ throw new ArgumentOutOfRangeException(nameof(bytesAllocated),
Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
}
if( (4 == IntPtr.Size) && (bytesAllocated > Int32.MaxValue) ) {
- throw new ArgumentOutOfRangeException("bytesAllocated",
+ throw new ArgumentOutOfRangeException(nameof(bytesAllocated),
Environment.GetResourceString("ArgumentOutOfRange_MustBeNonNegInt32"));
}
Contract.EndContractBlock();
@@ -159,7 +143,6 @@ namespace System {
// Returns the generation that obj is currently in.
//
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern int GetGeneration(Object obj);
@@ -172,35 +155,31 @@ namespace System {
// Garbage Collect all generations.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public static void Collect() {
//-1 says to GC all generations.
_Collect(-1, (int)InternalGCCollectionMode.Blocking);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static void Collect(int generation, GCCollectionMode mode)
{
Collect(generation, mode, true);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static void Collect(int generation, GCCollectionMode mode, bool blocking)
{
Collect(generation, mode, blocking, false);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static void Collect(int generation, GCCollectionMode mode, bool blocking, bool compacting)
{
if (generation<0)
{
- throw new ArgumentOutOfRangeException("generation", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
+ throw new ArgumentOutOfRangeException(nameof(generation), Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
}
if ((mode < GCCollectionMode.Default) || (mode > GCCollectionMode.Optimized))
{
- throw new ArgumentOutOfRangeException("mode", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(mode), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
}
Contract.EndContractBlock();
@@ -227,26 +206,24 @@ namespace System {
_Collect(generation, iInternalModes);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static int CollectionCount (int generation)
{
if (generation<0)
{
- throw new ArgumentOutOfRangeException("generation", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
+ throw new ArgumentOutOfRangeException(nameof(generation), Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
}
Contract.EndContractBlock();
return _CollectionCount(generation, 0);
}
// pass in true to get the BGC or FGC count.
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal static int CollectionCount (int generation, bool getSpecialGCCount)
{
if (generation<0)
{
- throw new ArgumentOutOfRangeException("generation", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
+ throw new ArgumentOutOfRangeException(nameof(generation), Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
}
Contract.EndContractBlock();
return _CollectionCount(generation, (getSpecialGCCount ? 1 : 0));
@@ -295,7 +272,6 @@ namespace System {
// Returns the generation in which wo currently resides.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public static int GetGeneration(WeakReference wo) {
int result = GetGenerationWR(wo.m_handle);
KeepAlive(wo);
@@ -305,16 +281,13 @@ namespace System {
// Returns the maximum GC generation. Currently assumes only 1 heap.
//
public static int MaxGeneration {
- [System.Security.SecuritySafeCritical] // auto-generated
get { return GetMaxGeneration(); }
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void _WaitForPendingFinalizers();
- [System.Security.SecuritySafeCritical] // auto-generated
public static void WaitForPendingFinalizers() {
// QCalls can not be exposed from mscorlib directly, need to wrap it.
_WaitForPendingFinalizers();
@@ -322,16 +295,14 @@ namespace System {
// Indicates that the system should not call the Finalize() method on
// an object that would normally require this call.
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
private static extern void _SuppressFinalize(Object o);
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static void SuppressFinalize(Object obj) {
if (obj == null)
- throw new ArgumentNullException("obj");
+ throw new ArgumentNullException(nameof(obj));
Contract.EndContractBlock();
_SuppressFinalize(obj);
}
@@ -340,14 +311,12 @@ namespace System {
// for which SuppressFinalize has already been called. The other situation
// where calling ReRegisterForFinalize is useful is inside a finalizer that
// needs to resurrect itself or an object that it references.
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void _ReRegisterForFinalize(Object o);
- [System.Security.SecuritySafeCritical] // auto-generated
public static void ReRegisterForFinalize(Object obj) {
if (obj == null)
- throw new ArgumentNullException("obj");
+ throw new ArgumentNullException(nameof(obj));
Contract.EndContractBlock();
_ReRegisterForFinalize(obj);
}
@@ -356,7 +325,6 @@ 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.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public static long GetTotalMemory(bool forceFullCollection) {
long size = GetTotalMemory();
if (!forceFullCollection)
@@ -379,16 +347,13 @@ namespace System {
return newSize;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern long _GetAllocatedBytesForCurrentThread();
- [System.Security.SecuritySafeCritical] // auto-generated
public static long GetAllocatedBytesForCurrentThread() {
return _GetAllocatedBytesForCurrentThread();
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool _RegisterForFullGCNotification(int maxGenerationPercentage, int largeObjectHeapPercentage);
@@ -401,12 +366,11 @@ namespace System {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern int _WaitForFullGCComplete(int millisecondsTimeout);
- [SecurityCritical]
public static void RegisterForFullGCNotification(int maxGenerationThreshold, int largeObjectHeapThreshold)
{
if ((maxGenerationThreshold <= 0) || (maxGenerationThreshold >= 100))
{
- throw new ArgumentOutOfRangeException("maxGenerationThreshold",
+ throw new ArgumentOutOfRangeException(nameof(maxGenerationThreshold),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Bounds_Lower_Upper"),
@@ -416,7 +380,7 @@ namespace System {
if ((largeObjectHeapThreshold <= 0) || (largeObjectHeapThreshold >= 100))
{
- throw new ArgumentOutOfRangeException("largeObjectHeapThreshold",
+ throw new ArgumentOutOfRangeException(nameof(largeObjectHeapThreshold),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Bounds_Lower_Upper"),
@@ -430,7 +394,6 @@ namespace System {
}
}
- [SecurityCritical]
public static void CancelFullGCNotification()
{
if (!_CancelFullGCNotification())
@@ -439,32 +402,28 @@ namespace System {
}
}
- [SecurityCritical]
public static GCNotificationStatus WaitForFullGCApproach()
{
return (GCNotificationStatus)_WaitForFullGCApproach(-1);
}
- [SecurityCritical]
public static GCNotificationStatus WaitForFullGCApproach(int millisecondsTimeout)
{
if (millisecondsTimeout < -1)
- throw new ArgumentOutOfRangeException("millisecondsTimeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
return (GCNotificationStatus)_WaitForFullGCApproach(millisecondsTimeout);
}
- [SecurityCritical]
public static GCNotificationStatus WaitForFullGCComplete()
{
return (GCNotificationStatus)_WaitForFullGCComplete(-1);
}
- [SecurityCritical]
public static GCNotificationStatus WaitForFullGCComplete(int millisecondsTimeout)
{
if (millisecondsTimeout < -1)
- throw new ArgumentOutOfRangeException("millisecondsTimeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
return (GCNotificationStatus)_WaitForFullGCComplete(millisecondsTimeout);
}
@@ -484,12 +443,11 @@ namespace System {
AllocationExceeded = 3
}
- [SecurityCritical]
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("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");
@@ -498,31 +456,26 @@ namespace System {
return true;
}
- [SecurityCritical]
public static bool TryStartNoGCRegion(long totalSize)
{
return StartNoGCRegionWorker(totalSize, false, 0, false);
}
- [SecurityCritical]
public static bool TryStartNoGCRegion(long totalSize, long lohSize)
{
return StartNoGCRegionWorker(totalSize, true, lohSize, false);
}
- [SecurityCritical]
public static bool TryStartNoGCRegion(long totalSize, bool disallowFullBlockingGC)
{
return StartNoGCRegionWorker(totalSize, false, 0, disallowFullBlockingGC);
}
- [SecurityCritical]
public static bool TryStartNoGCRegion(long totalSize, long lohSize, bool disallowFullBlockingGC)
{
return StartNoGCRegionWorker(totalSize, true, lohSize, disallowFullBlockingGC);
}
- [SecurityCritical]
static EndNoGCRegionStatus EndNoGCRegionWorker()
{
EndNoGCRegionStatus status = (EndNoGCRegionStatus)_EndNoGCRegion();
@@ -536,106 +489,9 @@ namespace System {
return EndNoGCRegionStatus.Succeeded;
}
- [SecurityCritical]
public static void EndNoGCRegion()
{
EndNoGCRegionWorker();
}
}
-
-#if !FEATURE_CORECLR
- internal class SizedReference : IDisposable
- {
- [System.Security.SecurityCritical]
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern IntPtr CreateSizedRef(Object o);
-
- [System.Security.SecurityCritical]
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern void FreeSizedRef(IntPtr h);
-
- [System.Security.SecurityCritical]
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern Object GetTargetOfSizedRef(IntPtr h);
-
- [System.Security.SecurityCritical]
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern Int64 GetApproximateSizeOfSizedRef(IntPtr h);
-
- #pragma warning disable 420
- [System.Security.SecuritySafeCritical]
- private void Free()
- {
- IntPtr temp = _handle;
- if (temp != IntPtr.Zero &&
- (Interlocked.CompareExchange(ref _handle, IntPtr.Zero, temp) == temp))
- {
- FreeSizedRef(temp);
- }
- }
-
- internal volatile IntPtr _handle;
-
- [System.Security.SecuritySafeCritical]
- public SizedReference(Object target)
- {
- IntPtr temp = IntPtr.Zero;
- temp = CreateSizedRef(target);
- _handle = temp;
- }
-
- ~SizedReference()
- {
- Free();
- }
-
- public Object Target
- {
- [System.Security.SecuritySafeCritical]
- get
- {
- IntPtr temp = _handle;
- if (temp == IntPtr.Zero)
- {
- return null;
- }
-
- Object o = GetTargetOfSizedRef(temp);
-
- return (_handle == IntPtr.Zero) ? null : o;
- }
- }
-
- public Int64 ApproximateSize
- {
- [System.Security.SecuritySafeCritical]
- get
- {
- IntPtr temp = _handle;
-
- if (temp == IntPtr.Zero)
- {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized"));
- }
-
- Int64 size = GetApproximateSizeOfSizedRef(temp);
-
- if (_handle == IntPtr.Zero)
- {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized"));
- }
- else
- {
- return size;
- }
- }
- }
-
- public void Dispose()
- {
- Free();
- GC.SuppressFinalize(this);
- }
- }
-#endif
}
diff --git a/src/mscorlib/src/System/Globalization/Calendar.cs b/src/mscorlib/src/System/Globalization/Calendar.cs
index d6dfdc9f4b..d0460386b6 100644
--- a/src/mscorlib/src/System/Globalization/Calendar.cs
+++ b/src/mscorlib/src/System/Globalization/Calendar.cs
@@ -7,6 +7,7 @@ namespace System.Globalization {
using System.Runtime.CompilerServices;
using System.Globalization;
using System.Runtime.Versioning;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
// This abstract class represents a calendar. A calendar reckons time in
@@ -192,7 +193,7 @@ namespace System.Globalization {
[System.Runtime.InteropServices.ComVisible(false)]
public static Calendar ReadOnly(Calendar calendar)
{
- if (calendar == null) { throw new ArgumentNullException("calendar"); }
+ if (calendar == null) { throw new ArgumentNullException(nameof(calendar)); }
Contract.EndContractBlock();
if (calendar.IsReadOnly) { return (calendar); }
@@ -229,7 +230,7 @@ namespace System.Globalization {
get {
// The following code assumes that the current era value can not be -1.
if (m_currentEraValue == -1) {
- Contract.Assert(BaseCalendarID > 0, "[Calendar.CurrentEraValue] Expected ID > 0");
+ Debug.Assert(BaseCalendarID > 0, "[Calendar.CurrentEraValue] Expected ID > 0");
m_currentEraValue = CalendarData.GetCalendarData(BaseCalendarID).iCurrentEra;
}
return (m_currentEraValue);
@@ -262,7 +263,7 @@ namespace System.Globalization {
double tempMillis = (value * scale + (value >= 0 ? 0.5 : -0.5));
if (!((tempMillis > -(double)MaxMillis) && (tempMillis < (double)MaxMillis)))
{
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_AddValue"));
+ throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_AddValue"));
}
long millis = (long)tempMillis;
@@ -529,7 +530,7 @@ namespace System.Globalization {
// 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;
- Contract.Assert(offset >= 0, "Calendar.GetFirstDayWeekOfYear(): offset >= 0");
+ Debug.Assert(offset >= 0, "Calendar.GetFirstDayWeekOfYear(): offset >= 0");
return ((dayOfYear + offset) / 7 + 1);
}
@@ -651,7 +652,7 @@ namespace System.Globalization {
{
if ((int)firstDayOfWeek < 0 || (int)firstDayOfWeek > 6) {
throw new ArgumentOutOfRangeException(
- "firstDayOfWeek", Environment.GetResourceString("ArgumentOutOfRange_Range",
+ nameof(firstDayOfWeek), Environment.GetResourceString("ArgumentOutOfRange_Range",
DayOfWeek.Sunday, DayOfWeek.Saturday));
}
Contract.EndContractBlock();
@@ -664,7 +665,7 @@ namespace System.Globalization {
return (GetWeekOfYearFullDays(time, (int)firstDayOfWeek, 4));
}
throw new ArgumentOutOfRangeException(
- "rule", Environment.GetResourceString("ArgumentOutOfRange_Range",
+ nameof(rule), Environment.GetResourceString("ArgumentOutOfRange_Range",
CalendarWeekRule.FirstDay, CalendarWeekRule.FirstFourDayWeek));
}
@@ -815,7 +816,7 @@ namespace System.Globalization {
public virtual int ToFourDigitYear(int year) {
if (year < 0) {
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
Contract.EndContractBlock();
@@ -835,7 +836,7 @@ namespace System.Globalization {
{
if (millisecond < 0 || millisecond >= MillisPerSecond) {
throw new ArgumentOutOfRangeException(
- "millisecond",
+ nameof(millisecond),
String.Format(
CultureInfo.InvariantCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"), 0, MillisPerSecond - 1));
@@ -845,7 +846,6 @@ namespace System.Globalization {
throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("ArgumentOutOfRange_BadHourMinuteSecond"));
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static int GetSystemTwoDigitYearSetting(int CalID, int defaultYearValue)
{
// Call nativeGetTwoDigitYearMax
diff --git a/src/mscorlib/src/System/Globalization/CalendarData.cs b/src/mscorlib/src/System/Globalization/CalendarData.cs
index 8c187f0033..6f583fbcbc 100644
--- a/src/mscorlib/src/System/Globalization/CalendarData.cs
+++ b/src/mscorlib/src/System/Globalization/CalendarData.cs
@@ -9,6 +9,7 @@ namespace System.Globalization
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
//
// List of calendar data
@@ -121,7 +122,7 @@ namespace System.Globalization
this.bUseUserOverrides = bUseUserOverrides;
if (!nativeGetCalendarData(this, localeName, calendarId))
{
- Contract.Assert(false, "[CalendarData] nativeGetCalendarData call isn't expected to fail for calendar " + calendarId + " locale " +localeName);
+ Debug.Assert(false, "[CalendarData] nativeGetCalendarData 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.
@@ -436,17 +437,14 @@ namespace System.Globalization
// Get native two digit year max
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern int nativeGetTwoDigitYearMax(int calID);
// Call native side to load our calendar data
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool nativeGetCalendarData(CalendarData data, String localeName, int calendar);
// Call native side to figure out which calendars are allowed
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern int nativeGetCalendars(String localeName, bool useUserOverride, [In, Out] int[] calendars);
diff --git a/src/mscorlib/src/System/Globalization/CalendricalCalculationsHelper.cs b/src/mscorlib/src/System/Globalization/CalendricalCalculationsHelper.cs
index 7084511ce9..1113cd58ba 100644
--- a/src/mscorlib/src/System/Globalization/CalendricalCalculationsHelper.cs
+++ b/src/mscorlib/src/System/Globalization/CalendricalCalculationsHelper.cs
@@ -5,6 +5,7 @@
namespace System.Globalization
{
using System;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
internal class CalendricalCalculationsHelper
@@ -153,7 +154,7 @@ namespace System.Globalization
// 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)
{
- Contract.Assert(gregorianYear < 1620 || 2020 <= gregorianYear);
+ Debug.Assert(gregorianYear < 1620 || 2020 <= gregorianYear);
long january1stOfYear = GetNumberOfDays(new DateTime(gregorianYear, 1, 1));
double daysSinceStartOf1810 = january1stOfYear - StartOf1810;
double x = TwelveHours + daysSinceStartOf1810;
@@ -162,34 +163,34 @@ namespace System.Globalization
static double EphemerisCorrection1988to2019(int gregorianYear)
{
- Contract.Assert(1988 <= gregorianYear && gregorianYear <= 2019);
+ Debug.Assert(1988 <= gregorianYear && gregorianYear <= 2019);
return (double)(gregorianYear - 1933) / SecondsPerDay;
}
static double EphemerisCorrection1900to1987(int gregorianYear)
{
- Contract.Assert(1900 <= gregorianYear && gregorianYear <= 1987);
+ Debug.Assert(1900 <= gregorianYear && gregorianYear <= 1987);
double centuriesFrom1900 = CenturiesFrom1900(gregorianYear);
return PolynomialSum(Coefficients1900to1987, centuriesFrom1900);
}
static double EphemerisCorrection1800to1899(int gregorianYear)
{
- Contract.Assert(1800 <= gregorianYear && gregorianYear <= 1899);
+ Debug.Assert(1800 <= gregorianYear && gregorianYear <= 1899);
double centuriesFrom1900 = CenturiesFrom1900(gregorianYear);
return PolynomialSum(Coefficients1800to1899, centuriesFrom1900);
}
static double EphemerisCorrection1700to1799(int gregorianYear)
{
- Contract.Assert(1700 <= gregorianYear && gregorianYear <= 1799);
+ Debug.Assert(1700 <= gregorianYear && gregorianYear <= 1799);
double yearsSince1700 = gregorianYear - 1700;
return PolynomialSum(Coefficients1700to1799, yearsSince1700) / SecondsPerDay;
}
static double EphemerisCorrection1620to1699(int gregorianYear)
{
- Contract.Assert(1620 <= gregorianYear && gregorianYear <= 1699);
+ Debug.Assert(1620 <= gregorianYear && gregorianYear <= 1699);
double yearsSince1600 = gregorianYear - 1600;
return PolynomialSum(Coefficients1620to1699, yearsSince1600) / SecondsPerDay;
}
@@ -216,7 +217,7 @@ namespace System.Globalization
}
}
- Contract.Assert(false, "Not expected to come here");
+ Debug.Assert(false, "Not expected to come here");
return DefaultEphemerisCorrection(year);
}
@@ -405,7 +406,7 @@ namespace System.Globalization
break;
}
}
- Contract.Assert(day != upperBoundNewYearDay);
+ 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 63151951f9..2822b418ef 100644
--- a/src/mscorlib/src/System/Globalization/CharUnicodeInfo.cs
+++ b/src/mscorlib/src/System/Globalization/CharUnicodeInfo.cs
@@ -23,6 +23,7 @@ namespace System.Globalization {
using System.Runtime.Versioning;
using System.Reflection;
using System.Security;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
@@ -46,14 +47,11 @@ namespace System.Globalization {
static bool s_initialized = InitTable();
// The native pointer to the 12:4:4 index table of the Unicode cateogry data.
- [SecurityCritical]
unsafe static ushort* s_pCategoryLevel1Index;
- [SecurityCritical]
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.
- [SecurityCritical]
unsafe static ushort* s_pNumericLevel1Index;
// The numeric value table, which is indexed by s_pNumericLevel1Index.
@@ -61,12 +59,10 @@ namespace System.Globalization {
// 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.
- [SecurityCritical]
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.
- [SecurityCritical]
unsafe static DigitValues* s_pDigitValues;
internal const String UNICODE_INFO_FILE_NAME = "charinfo.nlp";
@@ -111,7 +107,6 @@ namespace System.Globalization {
//use. We allocate this once in the class initializer and then we don't need to worry
//about it again.
//
- [System.Security.SecuritySafeCritical] // auto-generated
unsafe static bool InitTable() {
// Go to native side and get pointer to the native table
@@ -143,8 +138,8 @@ namespace System.Globalization {
////////////////////////////////////////////////////////////////////////
internal static int InternalConvertToUtf32(String s, int index) {
- Contract.Assert(s != null, "s != null");
- Contract.Assert(index >= 0 && index < s.Length, "index < s.Length");
+ 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) {
@@ -181,9 +176,9 @@ namespace System.Globalization {
////////////////////////////////////////////////////////////////////////
internal static int InternalConvertToUtf32(String s, int index, out int charLength) {
- Contract.Assert(s != null, "s != null");
- Contract.Assert(s.Length > 0, "s.Length > 0");
- Contract.Assert(index >= 0 && index < s.Length, "index >= 0 && index < s.Length");
+ 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;
@@ -209,8 +204,8 @@ namespace System.Globalization {
internal static bool IsWhiteSpace(String s, int index)
{
- Contract.Assert(s != null, "s!=null");
- Contract.Assert(index >= 0 && index < s.Length, "index >= 0 && index < s.Length");
+ 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".
@@ -245,9 +240,8 @@ namespace System.Globalization {
//
// Note that for ch in the range D800-DFFF we just treat it as any other non-numeric character
//
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static double InternalGetNumericValue(int ch) {
- Contract.Assert(ch >= 0 && ch <= 0x10ffff, "ch is not in valid Unicode range.");
+ 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.
@@ -278,9 +272,8 @@ namespace System.Globalization {
//
// Note that for ch in the range D800-DFFF we just treat it as any other non-numeric character
//
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static DigitValues* InternalGetDigitValues(int ch) {
- Contract.Assert(ch >= 0 && ch <= 0x10ffff, "ch is not in valid Unicode range.");
+ 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.
@@ -292,12 +285,10 @@ namespace System.Globalization {
return &(s_pDigitValues[pBytePtr[(ch & 0x000f)]]);
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static sbyte InternalGetDecimalDigitValue(int ch) {
return (InternalGetDigitValues(ch)->decimalDigit);
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static sbyte InternalGetDigitValue(int ch) {
return (InternalGetDigitValues(ch)->digit);
}
@@ -326,10 +317,10 @@ namespace System.Globalization {
public static double GetNumericValue(String s, int index) {
if (s == null) {
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
}
if (index < 0 || index >= s.Length) {
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
Contract.EndContractBlock();
return (InternalGetNumericValue(InternalConvertToUtf32(s, index)));
@@ -361,10 +352,10 @@ namespace System.Globalization {
public static int GetDecimalDigitValue(String s, int index) {
if (s == null) {
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
}
if (index < 0 || index >= s.Length) {
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
Contract.EndContractBlock();
@@ -398,10 +389,10 @@ namespace System.Globalization {
public static int GetDigitValue(String s, int index) {
if (s == null) {
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
}
if (index < 0 || index >= s.Length) {
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
Contract.EndContractBlock();
return (InternalGetDigitValue(InternalConvertToUtf32(s, index)));
@@ -415,9 +406,9 @@ namespace System.Globalization {
public static UnicodeCategory GetUnicodeCategory(String s, int index)
{
if (s==null)
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
}
Contract.EndContractBlock();
return InternalGetUnicodeCategory(s, index);
@@ -441,9 +432,8 @@ namespace System.Globalization {
//
////////////////////////////////////////////////////////////////////////
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static byte InternalGetCategoryValue(int ch, int offset) {
- Contract.Assert(ch >= 0 && ch <= 0x10ffff, "ch is not in valid Unicode range.");
+ 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.
@@ -457,7 +447,7 @@ namespace System.Globalization {
// Make sure that OtherNotAssigned is the last category in UnicodeCategory.
// If that changes, change the following assertion as well.
//
- //Contract.Assert(uc >= 0 && uc <= UnicodeCategory.OtherNotAssigned, "Table returns incorrect Unicode category");
+ //Debug.Assert(uc >= 0 && uc <= UnicodeCategory.OtherNotAssigned, "Table returns incorrect Unicode category");
return (uc);
}
@@ -467,9 +457,9 @@ namespace System.Globalization {
internal static BidiCategory GetBidiCategory(String s, int index) {
if (s==null)
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
}
Contract.EndContractBlock();
return ((BidiCategory)InternalGetCategoryValue(InternalConvertToUtf32(s, index), BIDI_CATEGORY_OFFSET));
@@ -489,8 +479,8 @@ namespace System.Globalization {
////////////////////////////////////////////////////////////////////////
internal static UnicodeCategory InternalGetUnicodeCategory(String value, int index) {
- Contract.Assert(value != null, "value can not be null");
- Contract.Assert(index < value.Length, "index < value.Length");
+ Debug.Assert(value != null, "value can not be null");
+ Debug.Assert(index < value.Length, "index < value.Length");
return (InternalGetUnicodeCategory(InternalConvertToUtf32(value, index)));
}
@@ -503,15 +493,15 @@ namespace System.Globalization {
////////////////////////////////////////////////////////////////////////
internal static UnicodeCategory InternalGetUnicodeCategory(String str, int index, out int charLength) {
- Contract.Assert(str != null, "str can not be null");
- Contract.Assert(str.Length > 0, "str.Length > 0");;
- Contract.Assert(index >= 0 && index < str.Length, "index >= 0 && index < str.Length");
+ 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) {
- Contract.Assert(uc >= 0, "uc >= 0");
+ Debug.Assert(uc >= 0, "uc >= 0");
return (
uc == UnicodeCategory.NonSpacingMark ||
uc == UnicodeCategory.SpacingCombiningMark ||
diff --git a/src/mscorlib/src/System/Globalization/ChineseLunisolarCalendar.cs b/src/mscorlib/src/System/Globalization/ChineseLunisolarCalendar.cs
index a5cf37f712..6479152e09 100644
--- a/src/mscorlib/src/System/Globalization/ChineseLunisolarCalendar.cs
+++ b/src/mscorlib/src/System/Globalization/ChineseLunisolarCalendar.cs
@@ -331,12 +331,12 @@ namespace System.Globalization {
internal override int GetGregorianYear(int year, int era) {
if (era != CurrentEra && era != ChineseEra) {
- throw new ArgumentOutOfRangeException("era", Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
}
if (year < MIN_LUNISOLAR_YEAR || year > MAX_LUNISOLAR_YEAR) {
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"), MIN_LUNISOLAR_YEAR, MAX_LUNISOLAR_YEAR));
diff --git a/src/mscorlib/src/System/Globalization/CompareInfo.cs b/src/mscorlib/src/System/Globalization/CompareInfo.cs
index 0b14f05264..dcf1f32e4a 100644
--- a/src/mscorlib/src/System/Globalization/CompareInfo.cs
+++ b/src/mscorlib/src/System/Globalization/CompareInfo.cs
@@ -32,6 +32,7 @@ namespace System.Globalization {
using System.Security.Permissions;
using Microsoft.Win32;
using System.Security;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
//
@@ -135,7 +136,7 @@ namespace System.Globalization {
public static CompareInfo GetCompareInfo(int culture, Assembly assembly){
// Parameter checking.
if (assembly == null) {
- throw new ArgumentNullException("assembly");
+ throw new ArgumentNullException(nameof(assembly));
}
if (assembly!=typeof(Object).Module.Assembly) {
throw new ArgumentException(Environment.GetResourceString("Argument_OnlyMscorlib"));
@@ -161,7 +162,7 @@ namespace System.Globalization {
// 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 ? "name" : "assembly");
+ throw new ArgumentNullException(name == null ? nameof(name) : nameof(assembly));
}
Contract.EndContractBlock();
@@ -189,7 +190,7 @@ namespace System.Globalization {
if (CultureData.IsCustomCultureId(culture))
{
// Customized culture cannot be created by the LCID.
- throw new ArgumentException(Environment.GetResourceString("Argument_CustomCultureCannotBePassedByNumber", "culture"));
+ throw new ArgumentException(Environment.GetResourceString("Argument_CustomCultureCannotBePassedByNumber", nameof(culture)));
}
return CultureInfo.GetCultureInfo(culture).CompareInfo;
@@ -209,7 +210,7 @@ namespace System.Globalization {
{
if (name == null)
{
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
}
Contract.EndContractBlock();
@@ -221,12 +222,11 @@ namespace System.Globalization {
return(IsSortable(ch.ToString()));
}
- [System.Security.SecuritySafeCritical]
[System.Runtime.InteropServices.ComVisible(false)]
public static bool IsSortable(String text) {
if (text == null) {
// A null param is invalid here.
- throw new ArgumentNullException("text");
+ throw new ArgumentNullException(nameof(text));
}
if (0 == text.Length) {
@@ -291,7 +291,7 @@ namespace System.Globalization {
#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)
- Contract.Assert(m_name != null, "CompareInfo.OnSerializing - expected m_name to be set already");
+ Debug.Assert(m_name != null, "CompareInfo.OnSerializing - expected m_name to be set already");
#endif
}
@@ -321,12 +321,7 @@ namespace System.Globalization {
{
get
{
- Contract.Assert(m_name != null, "CompareInfo.Name Expected m_name to be set");
- if (m_name == "zh-CHT" || m_name == "zh-CHS")
- {
- return m_name;
- }
-
+ Debug.Assert(m_name != null, "CompareInfo.Name Expected m_name to be set");
return (m_sortName);
}
}
@@ -352,7 +347,7 @@ namespace System.Globalization {
// 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
- Contract.Assert(options != CompareOptions.OrdinalIgnoreCase, "[CompareInfo.GetNativeCompareFlags]CompareOptions.OrdinalIgnoreCase should be handled separately");
+ 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;
@@ -367,7 +362,7 @@ namespace System.Globalization {
// Suffix & Prefix shouldn't use this, make sure to turn off the NORM_LINGUISTIC_CASING flag
if (options == CompareOptions.Ordinal) { nativeCompareFlags = COMPARE_OPTIONS_ORDINAL; }
- Contract.Assert(((options & ~(CompareOptions.IgnoreCase |
+ Debug.Assert(((options & ~(CompareOptions.IgnoreCase |
CompareOptions.IgnoreKanaType |
CompareOptions.IgnoreNonSpace |
CompareOptions.IgnoreSymbols |
@@ -375,7 +370,7 @@ namespace System.Globalization {
CompareOptions.StringSort)) == 0) ||
(options == CompareOptions.Ordinal), "[CompareInfo.GetNativeCompareFlags]Expected all flags to be handled");
- Contract.Assert((nativeCompareFlags & RESERVED_FIND_ASCII_STRING) == 0, "[CompareInfo.GetNativeCompareFlags] RESERVED_FIND_ASCII_STRING shouldn't be set here");
+ Debug.Assert((nativeCompareFlags & RESERVED_FIND_ASCII_STRING) == 0, "[CompareInfo.GetNativeCompareFlags] RESERVED_FIND_ASCII_STRING shouldn't be set here");
return nativeCompareFlags;
}
@@ -398,7 +393,6 @@ namespace System.Globalization {
return (Compare(string1, string2, CompareOptions.None));
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe virtual int Compare(String string1, String string2, CompareOptions options){
if (options == CompareOptions.OrdinalIgnoreCase)
@@ -411,14 +405,14 @@ namespace System.Globalization {
{
if (options != CompareOptions.Ordinal)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_CompareOptionOrdinal"), "options");
+ throw new ArgumentException(Environment.GetResourceString("Argument_CompareOptionOrdinal"), nameof(options));
}
return String.CompareOrdinal(string1, string2);
}
if ((options & ValidCompareMaskOffFlags) != 0)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), "options");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), nameof(options));
}
//Our paradigm is that null sorts less than any other string and
@@ -469,7 +463,6 @@ namespace System.Globalization {
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe virtual int Compare(String string1, int offset1, int length1, String string2, int offset2, int length2, CompareOptions options)
{
if (options == CompareOptions.OrdinalIgnoreCase)
@@ -483,31 +476,31 @@ namespace System.Globalization {
// Verify inputs
if (length1 < 0 || length2 < 0)
{
- throw new ArgumentOutOfRangeException((length1 < 0) ? "length1" : "length2", Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
+ throw new ArgumentOutOfRangeException((length1 < 0) ? nameof(length1) : nameof(length2), Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
}
if (offset1 < 0 || offset2 < 0)
{
- throw new ArgumentOutOfRangeException((offset1 < 0) ? "offset1" : "offset2", Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
+ throw new ArgumentOutOfRangeException((offset1 < 0) ? nameof(offset1) : nameof(offset2), Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
}
if (offset1 > (string1 == null ? 0 : string1.Length) - length1)
{
- throw new ArgumentOutOfRangeException("string1", Environment.GetResourceString("ArgumentOutOfRange_OffsetLength"));
+ throw new ArgumentOutOfRangeException(nameof(string1), Environment.GetResourceString("ArgumentOutOfRange_OffsetLength"));
}
if (offset2 > (string2 == null ? 0 : string2.Length) - length2)
{
- throw new ArgumentOutOfRangeException("string2", Environment.GetResourceString("ArgumentOutOfRange_OffsetLength"));
+ throw new ArgumentOutOfRangeException(nameof(string2), Environment.GetResourceString("ArgumentOutOfRange_OffsetLength"));
}
if ((options & CompareOptions.Ordinal) != 0)
{
if (options != CompareOptions.Ordinal)
{
throw new ArgumentException(Environment.GetResourceString("Argument_CompareOptionOrdinal"),
- "options");
+ nameof(options));
}
}
else if ((options & ValidCompareMaskOffFlags) != 0)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), "options");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), nameof(options));
}
//
@@ -546,11 +539,10 @@ namespace System.Globalization {
////////////////////////////////////////////////////////////////////////
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe virtual bool IsPrefix(String source, String prefix, CompareOptions options)
{
if (source == null || prefix == null) {
- throw new ArgumentNullException((source == null ? "source" : "prefix"),
+ throw new ArgumentNullException((source == null ? nameof(source) : nameof(prefix)),
Environment.GetResourceString("ArgumentNull_String"));
}
Contract.EndContractBlock();
@@ -572,7 +564,7 @@ namespace System.Globalization {
}
if ((options & ValidIndexMaskOffFlags) != 0) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), "options");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), nameof(options));
}
@@ -601,11 +593,10 @@ namespace System.Globalization {
////////////////////////////////////////////////////////////////////////
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe virtual bool IsSuffix(String source, String suffix, CompareOptions options)
{
if (source == null || suffix == null) {
- throw new ArgumentNullException((source == null ? "source" : "suffix"),
+ throw new ArgumentNullException((source == null ? nameof(source) : nameof(suffix)),
Environment.GetResourceString("ArgumentNull_String"));
}
Contract.EndContractBlock();
@@ -625,7 +616,7 @@ namespace System.Globalization {
}
if ((options & ValidIndexMaskOffFlags) != 0) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), "options");
+ 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
@@ -659,7 +650,7 @@ namespace System.Globalization {
public unsafe virtual int IndexOf(String source, char value)
{
if (source==null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
return IndexOf(source, value, 0, source.Length, CompareOptions.None);
@@ -669,7 +660,7 @@ namespace System.Globalization {
public unsafe virtual int IndexOf(String source, String value)
{
if (source==null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
return IndexOf(source, value, 0, source.Length, CompareOptions.None);
@@ -679,7 +670,7 @@ namespace System.Globalization {
public unsafe virtual int IndexOf(String source, char value, CompareOptions options)
{
if (source==null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
return IndexOf(source, value, 0, source.Length, options);
@@ -689,7 +680,7 @@ namespace System.Globalization {
public unsafe virtual int IndexOf(String source, String value, CompareOptions options)
{
if (source==null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
return IndexOf(source, value, 0, source.Length, options);
@@ -699,7 +690,7 @@ namespace System.Globalization {
public unsafe virtual int IndexOf(String source, char value, int startIndex)
{
if (source == null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
return IndexOf(source, value, startIndex, source.Length - startIndex, CompareOptions.None);
@@ -709,7 +700,7 @@ namespace System.Globalization {
public unsafe virtual int IndexOf(String source, String value, int startIndex)
{
if (source == null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
return IndexOf(source, value, startIndex, source.Length - startIndex, CompareOptions.None);
@@ -719,7 +710,7 @@ namespace System.Globalization {
public unsafe virtual int IndexOf(String source, char value, int startIndex, CompareOptions options)
{
if (source == null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
return IndexOf(source, value, startIndex, source.Length - startIndex, options);
@@ -729,7 +720,7 @@ namespace System.Globalization {
public unsafe virtual int IndexOf(String source, String value, int startIndex, CompareOptions options)
{
if (source == null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
return IndexOf(source, value, startIndex, source.Length - startIndex, options);
@@ -747,18 +738,17 @@ namespace System.Globalization {
return IndexOf(source, value, startIndex, count, CompareOptions.None);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe virtual int IndexOf(String source, char value, int startIndex, int count, CompareOptions options)
{
// Validate inputs
if (source == null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
if (startIndex < 0 || startIndex > source.Length)
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
if (count < 0 || startIndex > source.Length - count)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
Contract.EndContractBlock();
if (options == CompareOptions.OrdinalIgnoreCase)
@@ -769,7 +759,7 @@ 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"), "options");
+ 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.
@@ -780,18 +770,17 @@ namespace System.Globalization {
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe virtual int IndexOf(String source, String value, int startIndex, int count, CompareOptions options)
{
// Validate inputs
if (source == null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
if (value == null)
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
if (startIndex > source.Length)
{
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
Contract.EndContractBlock();
@@ -808,11 +797,11 @@ namespace System.Globalization {
if (startIndex < 0)
{
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
if (count < 0 || startIndex > source.Length - count)
- throw new ArgumentOutOfRangeException("count",Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ throw new ArgumentOutOfRangeException(nameof(count),Environment.GetResourceString("ArgumentOutOfRange_Count"));
if (options == CompareOptions.OrdinalIgnoreCase)
{
@@ -822,7 +811,7 @@ 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"), "options");
+ 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.
@@ -849,7 +838,7 @@ namespace System.Globalization {
public unsafe virtual int LastIndexOf(String source, char value)
{
if (source==null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
// Can't start at negative index, so make sure we check for the length == 0 case.
@@ -861,7 +850,7 @@ namespace System.Globalization {
public virtual int LastIndexOf(String source, String value)
{
if (source==null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
// Can't start at negative index, so make sure we check for the length == 0 case.
@@ -873,7 +862,7 @@ namespace System.Globalization {
public virtual int LastIndexOf(String source, char value, CompareOptions options)
{
if (source==null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
// Can't start at negative index, so make sure we check for the length == 0 case.
@@ -884,7 +873,7 @@ namespace System.Globalization {
public unsafe virtual int LastIndexOf(String source, String value, CompareOptions options)
{
if (source==null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
// Can't start at negative index, so make sure we check for the length == 0 case.
@@ -929,12 +918,11 @@ namespace System.Globalization {
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe virtual int LastIndexOf(String source, char value, int startIndex, int count, CompareOptions options)
{
// Verify Arguments
if (source==null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
// Validate CompareOptions
@@ -942,7 +930,7 @@ namespace System.Globalization {
if ((options & ValidIndexMaskOffFlags) != 0 &&
(options != CompareOptions.Ordinal) &&
(options != CompareOptions.OrdinalIgnoreCase))
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), "options");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), nameof(options));
// Special case for 0 length input strings
if (source.Length == 0 && (startIndex == -1 || startIndex == 0))
@@ -950,7 +938,7 @@ namespace System.Globalization {
// Make sure we're not out of range
if (startIndex < 0 || startIndex > source.Length)
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
// Make sure that we allow startIndex == source.Length
if (startIndex == source.Length)
@@ -962,7 +950,7 @@ 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("count", Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
if (options == CompareOptions.OrdinalIgnoreCase)
{
@@ -978,14 +966,13 @@ namespace System.Globalization {
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe virtual int LastIndexOf(String source, String value, int startIndex, int count, CompareOptions options)
{
// Verify Arguments
if (source == null)
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
if (value == null)
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
Contract.EndContractBlock();
// Validate CompareOptions
@@ -993,7 +980,7 @@ namespace System.Globalization {
if ((options & ValidIndexMaskOffFlags) != 0 &&
(options != CompareOptions.Ordinal) &&
(options != CompareOptions.OrdinalIgnoreCase))
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), "options");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), nameof(options));
// Special case for 0 length input strings
if (source.Length == 0 && (startIndex == -1 || startIndex == 0))
@@ -1001,7 +988,7 @@ namespace System.Globalization {
// Make sure we're not out of range
if (startIndex < 0 || startIndex > source.Length)
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
// Make sure that we allow startIndex == source.Length
if (startIndex == source.Length)
@@ -1017,7 +1004,7 @@ 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("count", Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
if (options == CompareOptions.OrdinalIgnoreCase)
{
@@ -1051,10 +1038,9 @@ namespace System.Globalization {
return CreateSortKey(source, CompareOptions.None);
}
- [System.Security.SecuritySafeCritical]
private SortKey CreateSortKey(String source, CompareOptions options)
{
- if (source==null) { throw new ArgumentNullException("source"); }
+ if (source==null) { throw new ArgumentNullException(nameof(source)); }
Contract.EndContractBlock();
// Mask used to check if we have the right flags.
@@ -1067,7 +1053,7 @@ namespace System.Globalization {
if ((options & ValidSortkeyCtorMaskOffFlags) != 0)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), "options");
+ 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
@@ -1088,7 +1074,7 @@ namespace System.Globalization {
// If there was an error, return an error
if (length == 0)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), "source");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), nameof(source));
}
// If input was empty, return the empty byte[] we made earlier and skip this
@@ -1157,7 +1143,7 @@ namespace System.Globalization {
{
if (source == null)
{
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
}
if (options == CompareOptions.Ordinal)
@@ -1207,7 +1193,6 @@ namespace System.Globalization {
return GetHashCodeOfString(source, options, false, 0);
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal int GetHashCodeOfString(string source, CompareOptions options, bool forceRandomizedHashing, long additionalEntropy)
{
//
@@ -1215,12 +1200,12 @@ namespace System.Globalization {
//
if(null == source)
{
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
}
if ((options & ValidHashCodeOfStringMaskOffFlags) != 0)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), "options");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), nameof(options));
}
Contract.EndContractBlock();
@@ -1259,39 +1244,16 @@ namespace System.Globalization {
}
#endif
- [System.Security.SecuritySafeCritical]
internal static IntPtr InternalInitSortHandle(String localeName, out IntPtr handleOrigin)
{
return NativeInternalInitSortHandle(localeName, out handleOrigin);
}
-#if !FEATURE_CORECLR
- private const int SORT_VERSION_WHIDBEY = 0x00001000;
- private const int SORT_VERSION_V4 = 0x00060101;
-
- internal static bool IsLegacy20SortingBehaviorRequested
- {
- get
- {
- return InternalSortVersion == SORT_VERSION_WHIDBEY;
- }
- }
-
- private static uint InternalSortVersion
- {
- [System.Security.SecuritySafeCritical]
- get
- {
- return InternalGetSortVersion();
- }
- }
-
[OptionalField(VersionAdded = 3)]
private SortVersion m_SortVersion;
public SortVersion Version
{
- [SecuritySafeCritical]
get
{
if(m_SortVersion == null)
@@ -1306,38 +1268,27 @@ namespace System.Globalization {
}
}
- [System.Security.SecurityCritical]
[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);
- [System.Security.SecurityCritical]
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private static extern uint InternalGetSortVersion();
-
-#endif
- [System.Security.SecurityCritical]
[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
- [System.Security.SecurityCritical] // auto-generated
[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
- [System.Security.SecurityCritical] // auto-generated
[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
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern int InternalCompareString(IntPtr handle, IntPtr handleOrigin, String localeName, String string1, int offset1, int length1,
@@ -1345,13 +1296,11 @@ namespace System.Globalization {
// InternalFindNLSStringEx parameters is not exactly matching kernel32::FindNLSStringEx parameters.
// Call through to NewApis::FindNLSStringEx so we can get the right behavior
- [System.Security.SecurityCritical] // auto-generated
[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
- [System.Security.SecurityCritical] // auto-generated
[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.cs b/src/mscorlib/src/System/Globalization/CultureData.cs
index ae1eeea298..0bcb796152 100644
--- a/src/mscorlib/src/System/Globalization/CultureData.cs
+++ b/src/mscorlib/src/System/Globalization/CultureData.cs
@@ -10,13 +10,10 @@ namespace System.Globalization
using System.Collections.Generic;
using System.Text;
using System.Threading;
-#if !FEATURE_CORECLR
- using System.Reflection;
- using System.Resources;
-#endif
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Security;
@@ -451,8 +448,8 @@ namespace System.Globalization
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.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
@@ -466,23 +463,6 @@ namespace System.Globalization
}
private volatile static CultureData s_Invariant;
-
-#if !FEATURE_CORECLR
- internal static volatile ResourceSet MscorlibResourceSet;
-#endif
-
-#if !FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- private static bool IsResourcePresent(String resourceKey)
- {
- if (MscorlibResourceSet == null)
- {
- MscorlibResourceSet = new ResourceSet(typeof(Environment).Assembly.GetManifestResourceStream("mscorlib.resources"));
- }
- return MscorlibResourceSet.GetString(resourceKey) != null;
- }
-#endif
-
///////////////
// Constructors //
///////////////
@@ -549,13 +529,7 @@ namespace System.Globalization
// Ask native code if that one's real
if (culture.InitCultureData() == false)
{
-#if !FEATURE_CORECLR
- if (culture.InitCompatibilityCultureData() == false
- && culture.InitLegacyAlternateSortData() == false)
-#endif
- {
- return null;
- }
+ return null;
}
return culture;
@@ -567,142 +541,12 @@ namespace System.Globalization
{
return false;
}
-
-#if !FEATURE_CORECLR
- if (CultureInfo.IsTaiwanSku)
- {
- TreatTaiwanParentChainAsHavingTaiwanAsSpecific();
- }
-#endif
- return true;
- }
-
-#if !FEATURE_CORECLR
- [System.Security.SecuritySafeCritical]
- private void TreatTaiwanParentChainAsHavingTaiwanAsSpecific()
- {
- if (IsNeutralInParentChainOfTaiwan() && IsOsPriorToWin7() && !IsReplacementCulture)
- {
- // force population of fields that should have information that is
- // different than zh-TW:
- string s = SNATIVELANGUAGE;
- s = SENGLISHLANGUAGE;
- s = SLOCALIZEDLANGUAGE;
- s = STEXTINFO;
- s = SCOMPAREINFO;
- s = FONTSIGNATURE;
- int i = IDEFAULTANSICODEPAGE;
- i = IDEFAULTOEMCODEPAGE;
- i = IDEFAULTMACCODEPAGE;
-
- this.sSpecificCulture = "zh-TW";
- this.sWindowsName = "zh-TW";
- }
- }
-
- private bool IsNeutralInParentChainOfTaiwan()
- {
- return this.sRealName == "zh" || this.sRealName == "zh-Hant";
- }
-
- static readonly Version s_win7Version = new Version(6, 1);
- static private bool IsOsPriorToWin7()
- {
- return Environment.OSVersion.Platform == PlatformID.Win32NT &&
- Environment.OSVersion.Version < s_win7Version;
- }
- static private bool IsOsWin7OrPrior()
- {
- return Environment.OSVersion.Platform == PlatformID.Win32NT &&
- Environment.OSVersion.Version < new Version(6, 2); // Win7 is 6.1.Build.Revision so we have to check for anything less than 6.2
- }
-
- private bool InitCompatibilityCultureData()
- {
- // for compatibility handle the deprecated ids: zh-chs, zh-cht
- string cultureName = this.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;
- }
-
- this.sRealName = fallbackCultureName;
- if (InitCultureData() == false)
- {
- return false;
- }
- // fixup our data
- this.sName = realCultureName; // the name that goes back to the user
- this.sParent = fallbackCultureName;
- this.bFramework = true;
-
- return true;
- }
-
- private bool InitLegacyAlternateSortData()
- {
- if (!CompareInfo.IsLegacy20SortingBehaviorRequested)
- {
- return false;
- }
-
- // For V2 compatibility, handle deprecated alternate sorts
- string cultureName = this.sRealName;
-
- switch (AnsiToLower(cultureName))
- {
- case "ko-kr_unicod":
- cultureName = "ko-KR_unicod";
- this.sRealName = "ko-KR";
- this.iLanguage = 0x00010412;
- break;
- case "ja-jp_unicod":
- cultureName = "ja-JP_unicod";
- this.sRealName = "ja-JP";
- this.iLanguage = 0x00010411;
- break;
- case "zh-hk_stroke":
- cultureName = "zh-HK_stroke";
- this.sRealName = "zh-HK";
- this.iLanguage = 0x00020c04;
- break;
- default:
- return false;
- }
-
- if (nativeInitCultureData(this) == false)
- {
- return false;
- }
-
- this.sRealName = cultureName;
- this.sCompareInfo = cultureName;
- this.bFramework = true;
-
return true;
}
-#if FEATURE_WIN32_REGISTRY
- private static String s_RegionKey = @"System\CurrentControlSet\Control\Nls\RegionMapping";
-#endif // FEATURE_WIN32_REGISTRY
-
-#endif // !FEATURE_CORECLR
// Cache of regions we've already looked up
private static volatile Dictionary<String, CultureData> s_cachedRegions;
- [System.Security.SecurityCritical] // auto-generated
internal static CultureData GetCultureDataForRegion(String cultureName, bool useUserOverride)
{
// First do a shortcut for Invariant
@@ -749,41 +593,6 @@ namespace System.Globalization
//
// Not found in the hash table, look it up the hard way
//
-#if !FEATURE_CORECLR
-#if FEATURE_WIN32_REGISTRY
- // First try the registry in case there are overrides of our table
- try
- {
- // Open in read-only mode.
- // Use InternalOpenSubKey so that we avoid the security check.
- Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.InternalOpenSubKey(s_RegionKey, false);
-
- if (key != null)
- {
- try
- {
- Object value = key.InternalGetValue(cultureName, null, false, false);
-
- if (value != null)
- {
- // Get the name of the locale to try.
- String specificForRegion = value.ToString();
-
- // See if it's real
- retVal = GetCultureData(specificForRegion, useUserOverride);
- }
- }
- finally
- {
- key.Close();
- }
- }
- }
- // If this fails for any reason, we'll just ignore it, likely it just isn't there.
- catch (ObjectDisposedException) { }
- catch (ArgumentException) { }
-#endif // FEATURE_WIN32_REGISTRY
-#endif // !FEATURE_CORECLR
// If not a valid mapping from the registry we'll have to try the hard coded table
if (retVal == null || (retVal.IsNeutralCulture == true))
@@ -841,7 +650,6 @@ namespace System.Globalization
#if FEATURE_USE_LCID
// Obtain locale name from LCID
// NOTE: This will get neutral names, unlike the OS API
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern String LCIDToLocaleName(int lcid);
@@ -851,25 +659,6 @@ namespace System.Globalization
String localeName = null;
CultureData retVal = null;
-#if !FEATURE_CORECLR
- // If V2 legacy sort is requested, then provide deprecated alternate sorts
- if (CompareInfo.IsLegacy20SortingBehaviorRequested)
- {
- switch (culture)
- {
- case 0x00010412:
- localeName = "ko-KR_unicod";
- break;
- case 0x00010411:
- localeName = "ja-JP_unicod";
- break;
- case 0x00020c04:
- localeName = "zh-HK_stroke";
- break;
- }
- }
-#endif
-
if (localeName == null)
{
// Convert the lcid to a name, then use that
@@ -886,19 +675,6 @@ namespace System.Globalization
}
else
{
-#if !FEATURE_CORECLR
- switch (localeName)
- {
- // for compatibility with Whidbey, when requesting
- // a locale from LCID, return the old localeName
- case "zh-Hans":
- localeName = "zh-CHS";
- break;
- case "zh-Hant":
- localeName = "zh-CHT";
- break;
- }
-#endif
// Valid name, use it
retVal = GetCultureData(localeName, bUseUserOverride);
}
@@ -906,7 +682,7 @@ namespace System.Globalization
// If not successful, throw
if (retVal == null)
throw new CultureNotFoundException(
- "culture", culture, Environment.GetResourceString("Argument_CultureNotSupported"));
+ nameof(culture), culture, Environment.GetResourceString("Argument_CultureNotSupported"));
// Return the one we found
return retVal;
@@ -921,7 +697,6 @@ namespace System.Globalization
s_replacementCultureNames = null;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static CultureInfo[] GetCultures(CultureTypes types)
{
// Disable warning 618: System.Globalization.CultureTypes.FrameworkCultures' is obsolete
@@ -933,7 +708,7 @@ namespace System.Globalization
CultureTypes.FrameworkCultures)) != 0)
{
throw new ArgumentOutOfRangeException(
- "types",
+ nameof(types),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"), CultureTypes.NeutralCultures, CultureTypes.FrameworkCultures));
@@ -972,25 +747,12 @@ namespace System.Globalization
int arrayLength = cultureNames.Length;
- if ((types & (CultureTypes.NeutralCultures | CultureTypes.FrameworkCultures)) != 0) // add zh-CHT and zh-CHS
- {
- arrayLength += 2;
- }
-
CultureInfo[] cultures = new CultureInfo[arrayLength];
for (int i = 0; i < cultureNames.Length; i++)
{
cultures[i] = new CultureInfo(cultureNames[i]);
}
-
- if ((types & (CultureTypes.NeutralCultures | CultureTypes.FrameworkCultures)) != 0) // add zh-CHT and zh-CHS
- {
- Contract.Assert(arrayLength == cultureNames.Length + 2, "CultureData.nativeEnumCultureNames() Incorrect array size");
- cultures[cultureNames.Length] = new CultureInfo("zh-CHS");
- cultures[cultureNames.Length + 1] = new CultureInfo("zh-CHT");
- }
-
#pragma warning restore 618
return cultures;
@@ -1028,10 +790,9 @@ namespace System.Globalization
////////////////////////////////////////////////////////////////////////
- [System.Security.SecuritySafeCritical] // auto-generated
private static bool IsReplacementCultureName(String name)
{
- Contract.Assert(name != null, "IsReplacementCultureName(): name should not be null");
+ Debug.Assert(name != null, "IsReplacementCultureName(): name should not be null");
String[] replacementCultureNames = s_replacementCultureNames;
if (replacementCultureNames == null)
{
@@ -1041,7 +802,7 @@ namespace System.Globalization
}
// Even if we don't have any replacement cultures, the returned replacementCultureNames will still an empty string array, not null.
- Contract.Assert(name != null, "IsReplacementCultureName(): replacementCultureNames should not be null");
+ Debug.Assert(name != null, "IsReplacementCultureName(): replacementCultureNames should not be null");
Array.Sort(replacementCultureNames);
s_replacementCultureNames = replacementCultureNames;
}
@@ -1065,7 +826,7 @@ namespace System.Globalization
{
get
{
- Contract.Assert(this.sRealName != null, "[CultureData.CultureName] Expected this.sRealName to be populated by COMNlsInfo::nativeInitCultureData already");
+ Debug.Assert(this.sRealName != null, "[CultureData.CultureName] Expected this.sRealName to be populated by COMNlsInfo::nativeInitCultureData 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.
@@ -1093,7 +854,7 @@ namespace System.Globalization
{
get
{
- // Contract.Assert(this.sName != null,
+ // Debug.Assert(this.sName != null,
// "[CultureData.SNAME] Expected this.sName to be populated by COMNlsInfo::nativeInitCultureData already");
if (this.sName == null)
{
@@ -1106,31 +867,12 @@ namespace System.Globalization
// Parent name (which may be a custom locale/culture)
internal String SPARENT
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sParent == null)
{
// Ask using the real name, so that we get parents of neutrals
this.sParent = DoGetLocaleInfo(this.sRealName, LOCALE_SPARENT);
-
-#if !FEATURE_CORECLR
- // for compatibility, the chain should be:
- // zh-CN -> zh-CHS -> zh-Hans -> zh
- // zh-TW -> zh-CHT -> zh-Hant -> zh
- Contract.Assert(this.sName != "zh-CHS" && this.sName != "zh-CHT",
- "sParent should have been initialized for zh-CHS and zh-CHT when they were constructed, otherwise we get recursion");
- switch (this.sParent)
- {
- case "zh-Hans":
- this.sParent = "zh-CHS";
- break;
- case "zh-Hant":
- this.sParent = "zh-CHT";
- break;
- }
-#endif
-
}
return this.sParent;
}
@@ -1139,18 +881,10 @@ namespace System.Globalization
// Localized pretty name for this locale (ie: Inglis (estados Unitos))
internal String SLOCALIZEDDISPLAYNAME
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sLocalizedDisplayName == null)
{
-#if !FEATURE_CORECLR
- String resourceKey = "Globalization.ci_" + this.sName;
- if (IsResourcePresent(resourceKey))
- {
- this.sLocalizedDisplayName = Environment.GetResourceString(resourceKey);
- }
-#endif
// If it hasn't been found (Windows 8 and up), fallback to the system
if (String.IsNullOrEmpty(this.sLocalizedDisplayName))
{
@@ -1180,7 +914,6 @@ namespace System.Globalization
// English pretty name for this locale (ie: English (United States))
internal String SENGDISPLAYNAME
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sEnglishDisplayName == null)
@@ -1189,17 +922,6 @@ namespace System.Globalization
if (this.IsNeutralCulture)
{
this.sEnglishDisplayName = this.SENGLISHLANGUAGE;
-#if !FEATURE_CORECLR
- // differentiate the legacy display names
- switch (this.sName)
- {
- case "zh-CHS":
- case "zh-CHT":
- this.sEnglishDisplayName += " Legacy";
- break;
- }
-#endif
-
}
else
{
@@ -1233,7 +955,6 @@ namespace System.Globalization
// Native pretty name for this locale (ie: Deutsch (Deutschland))
internal String SNATIVEDISPLAYNAME
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sNativeDisplayName == null)
@@ -1242,32 +963,10 @@ namespace System.Globalization
if (this.IsNeutralCulture)
{
this.sNativeDisplayName = this.SNATIVELANGUAGE;
-#if !FEATURE_CORECLR
- // differentiate the legacy display names
- switch (this.sName)
- {
- case "zh-CHS":
- this.sNativeDisplayName += " \u65E7\u7248";
- break;
- case "zh-CHT":
- this.sNativeDisplayName += " \u820A\u7248";
- break;
- }
-#endif
}
else
{
-#if !FEATURE_CORECLR
- if (IsIncorrectNativeLanguageForSinhala())
- {
- // work around bug in Windows 7 for native name of Sinhala
- this.sNativeDisplayName ="\x0dc3\x0dd2\x0d82\x0dc4\x0dbd (\x0DC1\x0DCA\x200D\x0DBB\x0DD3\x0020\x0DBD\x0D82\x0D9A\x0DCF)";
- }
- else
-#endif
- {
- this.sNativeDisplayName = DoGetLocaleInfo(LOCALE_SNATIVEDISPLAYNAME);
- }
+ this.sNativeDisplayName = DoGetLocaleInfo(LOCALE_SNATIVEDISPLAYNAME);
// if it isn't found build one:
if (String.IsNullOrEmpty(this.sNativeDisplayName))
@@ -1287,7 +986,7 @@ namespace System.Globalization
get
{
// This got populated when ComNlsInfo::nativeInitCultureData told us we had a culture
- Contract.Assert(this.sSpecificCulture != null, "[CultureData.SSPECIFICCULTURE] Expected this.sSpecificCulture to be populated by COMNlsInfo::nativeInitCultureData already");
+ Debug.Assert(this.sSpecificCulture != null, "[CultureData.SSPECIFICCULTURE] Expected this.sSpecificCulture to be populated by COMNlsInfo::nativeInitCultureData already");
return this.sSpecificCulture;
}
}
@@ -1299,7 +998,6 @@ namespace System.Globalization
// iso 639 language name, ie: en
internal String SISO639LANGNAME
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sISO639Language == null)
@@ -1313,7 +1011,6 @@ namespace System.Globalization
// iso 639 language name, ie: eng
internal String SISO639LANGNAME2
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sISO639Language2 == null)
@@ -1327,7 +1024,6 @@ namespace System.Globalization
// abbreviated windows language name (ie: enu) (non-standard, avoid this)
internal String SABBREVLANGNAME
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sAbbrevLang == null)
@@ -1342,7 +1038,6 @@ namespace System.Globalization
// This is only valid for Windows 8 and higher neutrals:
internal String SLOCALIZEDLANGUAGE
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sLocalizedLanguage == null)
@@ -1365,7 +1060,6 @@ namespace System.Globalization
// English name for this language (Windows Only) ie: German
internal String SENGLISHLANGUAGE
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sEnglishLanguage == null)
@@ -1379,18 +1073,10 @@ namespace System.Globalization
// Native name of this language (Windows Only) ie: Deutsch
internal String SNATIVELANGUAGE
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sNativeLanguage == null)
{
-#if !FEATURE_CORECLR
- if (IsIncorrectNativeLanguageForSinhala())
- {
- this.sNativeLanguage = "\x0dc3\x0dd2\x0d82\x0dc4\x0dbd";
- }
- else
-#endif
{
this.sNativeLanguage = DoGetLocaleInfo(LOCALE_SNATIVELANGUAGENAME);
}
@@ -1399,15 +1085,6 @@ namespace System.Globalization
}
}
-#if !FEATURE_CORECLR
- private bool IsIncorrectNativeLanguageForSinhala()
- {
- return IsOsWin7OrPrior()
- && (sName == "si-LK" || sName == "si")
- && !IsReplacementCulture;
- }
-#endif
-
///////////
// Region //
///////////
@@ -1415,7 +1092,6 @@ namespace System.Globalization
// region name (eg US)
internal String SREGIONNAME
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sRegionName == null)
@@ -1451,18 +1127,10 @@ namespace System.Globalization
// localized name for the country
internal string SLOCALIZEDCOUNTRY
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sLocalizedCountry == null)
{
-#if !FEATURE_CORECLR
- String resourceKey = "Globalization.ri_" + this.SREGIONNAME;
- if (IsResourcePresent(resourceKey))
- {
- this.sLocalizedCountry = Environment.GetResourceString(resourceKey);
- }
-#endif
// If it hasn't been found (Windows 8 and up), fallback to the system
if (String.IsNullOrEmpty(this.sLocalizedCountry))
{
@@ -1484,7 +1152,6 @@ namespace System.Globalization
// english country name (RegionInfo) ie: Germany
internal String SENGCOUNTRY
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sEnglishCountry == null)
@@ -1498,7 +1165,6 @@ namespace System.Globalization
// native country name (RegionInfo) ie: Deutschland
internal String SNATIVECOUNTRY
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sNativeCountry == null)
@@ -1512,7 +1178,6 @@ namespace System.Globalization
// ISO 3166 Country Name
internal String SISO3166CTRYNAME
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sISO3166CountryName == null)
@@ -1526,7 +1191,6 @@ namespace System.Globalization
// ISO 3166 Country Name
internal String SISO3166CTRYNAME2
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sISO3166CountryName2 == null)
@@ -1540,7 +1204,6 @@ namespace System.Globalization
// abbreviated Country Name (windows version, non-standard, avoid)
internal String SABBREVCTRYNAME
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sAbbrevCountry == null)
@@ -1584,7 +1247,6 @@ namespace System.Globalization
// Console fallback name (ie: locale to use for console apps for unicode-only locales)
internal String SCONSOLEFALLBACKNAME
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sConsoleFallbackName == null)
@@ -1624,7 +1286,6 @@ namespace System.Globalization
// (user can override) grouping of digits
internal int[] WAGROUPING
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.waGrouping == null || UseUserOverride)
@@ -1642,7 +1303,6 @@ namespace System.Globalization
// Not a Number
internal String SNAN
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sNaN == null)
@@ -1656,7 +1316,6 @@ namespace System.Globalization
// + Infinity
internal String SPOSINFINITY
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sPositiveInfinity == null)
@@ -1670,7 +1329,6 @@ namespace System.Globalization
// - Infinity
internal String SNEGINFINITY
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sNegativeInfinity == null)
@@ -1717,7 +1375,6 @@ namespace System.Globalization
// Percent (%) symbol
internal String SPERCENT
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sPercent == null)
@@ -1732,7 +1389,6 @@ namespace System.Globalization
// PerMille (‰) symbol
internal String SPERMILLE
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sPerMille == null)
@@ -1751,7 +1407,6 @@ namespace System.Globalization
// (user can override) local monetary symbol, eg: $
internal String SCURRENCY
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sCurrency == null || UseUserOverride)
@@ -1765,7 +1420,6 @@ namespace System.Globalization
// international monetary symbol (RegionInfo), eg: USD
internal String SINTLSYMBOL
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sIntlMonetarySymbol == null)
@@ -1779,7 +1433,6 @@ namespace System.Globalization
// English name for this currency (RegionInfo), eg: US Dollar
internal String SENGLISHCURRENCY
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sEnglishCurrency == null)
@@ -1793,7 +1446,6 @@ namespace System.Globalization
// Native name for this currency (RegionInfo), eg: Schweiz Frank
internal String SNATIVECURRENCY
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sNativeCurrency == null)
@@ -1811,7 +1463,6 @@ namespace System.Globalization
// (user can override) monetary grouping of digits
internal int[] WAMONGROUPING
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.waMonetaryGrouping == null || UseUserOverride)
@@ -1845,7 +1496,6 @@ namespace System.Globalization
// (user can override) list Separator
internal String SLIST
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sListSeparator == null || UseUserOverride)
@@ -1872,7 +1522,6 @@ namespace System.Globalization
// (user can override) AM designator
internal String SAM1159
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sAM1159 == null || UseUserOverride)
@@ -1886,7 +1535,6 @@ namespace System.Globalization
// (user can override) PM designator
internal String SPM2359
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.sPM2359 == null || UseUserOverride)
@@ -2067,7 +1715,6 @@ namespace System.Globalization
// time duration format
internal String[] SADURATION
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (this.saDurationFormats == null)
@@ -2198,7 +1845,7 @@ namespace System.Globalization
// 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];
- Contract.Assert(this.sWindowsName != null, "[CultureData.CalendarIds] Expected this.sWindowsName to be populated by COMNlsInfo::nativeInitCultureData already");
+ 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);
// See if we had a calendar to add.
@@ -2243,7 +1890,6 @@ namespace System.Globalization
// 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 FEATURE_CORECLR
if (temp.Length > 1)
{
int i = DoGetLocaleInfoInt(LOCALE_ICALENDARTYPE);
@@ -2253,7 +1899,6 @@ namespace System.Globalization
temp[0] = i;
}
}
-#endif
this.waCalendars = temp;
}
@@ -2272,7 +1917,7 @@ namespace System.Globalization
internal CalendarData GetCalendar(int calendarId)
{
- Contract.Assert(calendarId > 0 && calendarId <= CalendarData.MAX_CALENDARS,
+ Debug.Assert(calendarId > 0 && calendarId <= CalendarData.MAX_CALENDARS,
"[CultureData.GetCalendar] Expect calendarId to be in a valid range");
// arrays are 0 based, calendarIds are 1 based
@@ -2291,16 +1936,8 @@ namespace System.Globalization
// Make sure that calendar has data
if (calendarData == null || UseUserOverride)
{
- Contract.Assert(this.sWindowsName != null, "[CultureData.GetCalendar] Expected this.sWindowsName to be populated by COMNlsInfo::nativeInitCultureData already");
+ 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);
-#if !FEATURE_CORECLR
- //Work around issue where Win7 data for MonthDay contains invalid two sets of data separated by semicolon
- //even though MonthDay is not enumerated
- if (IsOsWin7OrPrior() && !IsSupplementalCustomCulture && !IsReplacementCulture)
- {
- calendarData.FixupWin7MonthDaySemicolonBug();
- }
-#endif
calendars[calendarIndex] = calendarData;
}
@@ -2344,7 +1981,7 @@ namespace System.Globalization
{
if (this.iReadingLayout == undef)
{
- Contract.Assert(this.sRealName != null, "[CultureData.IsRightToLeft] Expected this.sRealName to be populated by COMNlsInfo::nativeInitCultureData already");
+ Debug.Assert(this.sRealName != null, "[CultureData.IsRightToLeft] Expected this.sRealName to be populated by COMNlsInfo::nativeInitCultureData already");
this.iReadingLayout = DoGetLocaleInfoInt(LOCALE_IREADINGLAYOUT);
}
@@ -2361,7 +1998,6 @@ namespace System.Globalization
// es-ES_tradnl -> es-ES
internal String STEXTINFO // Text info name to use for text information
{
- [System.Security.SecuritySafeCritical]
get
{
if (this.sTextInfo == null)
@@ -2387,7 +2023,6 @@ namespace System.Globalization
// Compare info name (including sorting key) to use if custom
internal String SCOMPAREINFO
{
- [System.Security.SecuritySafeCritical]
get
{
if (this.sCompareInfo == null)
@@ -2423,7 +2058,6 @@ namespace System.Globalization
private String SSCRIPTS
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
if (this.sScripts == null)
@@ -2436,7 +2070,6 @@ namespace System.Globalization
private String SOPENTYPELANGUAGETAG
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
return DoGetLocaleInfo(LOCALE_SOPENTYPELANGUAGETAG);
@@ -2445,7 +2078,6 @@ namespace System.Globalization
private String FONTSIGNATURE
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
if (this.fontSignature == null)
@@ -2458,7 +2090,6 @@ namespace System.Globalization
private String SKEYBOARDSTOINSTALL
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
return DoGetLocaleInfo(LOCALE_SKEYBOARDSTOINSTALL);
@@ -2516,7 +2147,6 @@ namespace System.Globalization
// Obtain locale name from LCID
// NOTE: This will get neutral names, unlike the OS API
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern int LocaleNameToLCID(String localeName);
@@ -2528,7 +2158,7 @@ namespace System.Globalization
{
if (this.iLanguage == 0)
{
- Contract.Assert(this.sRealName != null, "[CultureData.ILANGUAGE] Expected this.sRealName to be populated by COMNlsInfo::nativeInitCultureData already");
+ Debug.Assert(this.sRealName != null, "[CultureData.ILANGUAGE] Expected this.sRealName to be populated by COMNlsInfo::nativeInitCultureData already");
this.iLanguage = LocaleNameToLCID(this.sRealName);
}
return this.iLanguage;
@@ -2584,21 +2214,21 @@ namespace System.Globalization
// All of our era names
internal String[] EraNames(int calendarId)
{
- Contract.Assert(calendarId > 0, "[CultureData.saEraNames] Expected Calendar.ID > 0");
+ Debug.Assert(calendarId > 0, "[CultureData.saEraNames] Expected Calendar.ID > 0");
return this.GetCalendar(calendarId).saEraNames;
}
internal String[] AbbrevEraNames(int calendarId)
{
- Contract.Assert(calendarId > 0, "[CultureData.saAbbrevEraNames] Expected Calendar.ID > 0");
+ Debug.Assert(calendarId > 0, "[CultureData.saAbbrevEraNames] Expected Calendar.ID > 0");
return this.GetCalendar(calendarId).saAbbrevEraNames;
}
internal String[] AbbreviatedEnglishEraNames(int calendarId)
{
- Contract.Assert(calendarId > 0, "[CultureData.saAbbrevEraNames] Expected Calendar.ID > 0");
+ Debug.Assert(calendarId > 0, "[CultureData.saAbbrevEraNames] Expected Calendar.ID > 0");
return this.GetCalendar(calendarId).saAbbrevEnglishEraNames;
}
@@ -2610,7 +2240,6 @@ namespace System.Globalization
// Time separator (derived from time format)
internal String TimeSeparator
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
if (sTimeSeparator == null || UseUserOverride)
@@ -2856,8 +2485,8 @@ namespace System.Globalization
private static int IndexOfTimePart(string format, int startIndex, string timeParts)
{
- Contract.Assert(startIndex >= 0, "startIndex cannot be negative");
- Contract.Assert(timeParts.IndexOfAny(new char[] { '\'', '\\' }) == -1, "timeParts cannot include quote characters");
+ 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)
{
@@ -2892,16 +2521,14 @@ namespace System.Globalization
return -1;
}
- [System.Security.SecurityCritical]
string DoGetLocaleInfo(uint lctype)
{
- Contract.Assert(this.sWindowsName != null, "[CultureData.DoGetLocaleInfo] Expected this.sWindowsName to be populated by COMNlsInfo::nativeInitCultureData already");
+ 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.
- [System.Security.SecurityCritical] // auto-generated
string DoGetLocaleInfo(string localeName, uint lctype)
{
// Fix lctype if we don't want overrides
@@ -2911,7 +2538,7 @@ namespace System.Globalization
}
// Ask OS for data
- Contract.Assert(localeName != null, "[CultureData.DoGetLocaleInfo] Expected localeName to be not be null");
+ Debug.Assert(localeName != null, "[CultureData.DoGetLocaleInfo] Expected localeName to be not be null");
string result = CultureInfo.nativeGetLocaleInfoEx(localeName, lctype);
if (result == null)
{
@@ -2932,7 +2559,7 @@ namespace System.Globalization
// Ask OS for data, note that we presume it returns success, so we have to know that
// sWindowsName is valid before calling.
- Contract.Assert(this.sWindowsName != null, "[CultureData.DoGetLocaleInfoInt] Expected this.sWindowsName to be populated by COMNlsInfo::nativeInitCultureData already");
+ 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;
@@ -2941,7 +2568,7 @@ namespace System.Globalization
String[] DoEnumTimeFormats()
{
// Note that this gets overrides for us all the time
- Contract.Assert(this.sWindowsName != null, "[CultureData.DoEnumTimeFormats] Expected this.sWindowsName to be populated by COMNlsInfo::nativeInitCultureData already");
+ 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;
@@ -2950,7 +2577,7 @@ namespace System.Globalization
String[] DoEnumShortTimeFormats()
{
// Note that this gets overrides for us all the time
- Contract.Assert(this.sWindowsName != null, "[CultureData.DoEnumShortTimeFormats] Expected this.sWindowsName to be populated by COMNlsInfo::nativeInitCultureData already");
+ 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;
@@ -2975,7 +2602,6 @@ namespace System.Globalization
// not affected by the Calendar property in DTFI.
//
////////////////////////////////////////////////////////////////////////////
- [System.Security.SecurityCritical] // auto-generated
internal void GetNFIValues(NumberFormatInfo nfi)
{
if (this.IsInvariantCulture)
@@ -3013,7 +2639,7 @@ namespace System.Globalization
//
// Ask native side for our data.
//
- Contract.Assert(this.sWindowsName != null, "[CultureData.GetNFIValues] Expected this.sWindowsName to be populated by COMNlsInfo::nativeInitCultureData already");
+ Debug.Assert(this.sWindowsName != null, "[CultureData.GetNFIValues] Expected this.sWindowsName to be populated by COMNlsInfo::nativeInitCultureData already");
CultureData.nativeGetNumberFormatInfoValues(this.sWindowsName, nfi, UseUserOverride);
}
@@ -3056,17 +2682,6 @@ namespace System.Globalization
{
nfi.currencyDecimalSeparator = nfi.numberDecimalSeparator;
}
-
-#if !FEATURE_CORECLR
- if ((932 == this.IDEFAULTANSICODEPAGE) ||
- (949 == this.IDEFAULTANSICODEPAGE))
- {
- // Legacy behavior for cultures that use Japanese/Korean default ANSI code pages
- // Note that this is a code point, not a character. On Japanese/Korean machines this
- // will be rendered as their currency symbol, not rendered as a "\"
- nfi.ansiCurrencySymbol = "\x5c";
- }
-#endif // !FEATURE_CORECLR
}
static private int ConvertFirstDayOfWeekMonToSun(int iTemp)
@@ -3333,20 +2948,16 @@ namespace System.Globalization
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.)
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool nativeInitCultureData(CultureData cultureData);
// Grab the NumberFormatInfo data
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool nativeGetNumberFormatInfoValues(String localeName, NumberFormatInfo nfi, bool useUserOverride);
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern String[] nativeEnumTimeFormats(String localeName, uint dwFlags, bool useUserOverride);
- [System.Security.SecurityCritical] // auto-generated
[SuppressUnmanagedCodeSecurityAttribute()]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
internal static extern int nativeEnumCultureNames(int cultureTypes, ObjectHandleOnStack retStringArray);
diff --git a/src/mscorlib/src/System/Globalization/CultureInfo.cs b/src/mscorlib/src/System/Globalization/CultureInfo.cs
index d620d2dc24..9f306c3c99 100644
--- a/src/mscorlib/src/System/Globalization/CultureInfo.cs
+++ b/src/mscorlib/src/System/Globalization/CultureInfo.cs
@@ -39,6 +39,7 @@ namespace System.Globalization {
using System.Security.Permissions;
using System.Reflection;
using Microsoft.Win32;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Resources;
@@ -66,10 +67,6 @@ namespace System.Globalization {
internal bool m_isReadOnly;
internal CompareInfo compareInfo;
internal TextInfo textInfo;
- // Not serialized for now since we only build it privately for use in the CARIB (so rebuilding is OK)
-#if !FEATURE_CORECLR
- [NonSerialized]internal RegionInfo regionInfo;
-#endif
internal NumberFormatInfo numInfo;
internal DateTimeFormatInfo dateTimeInfo;
internal Calendar calendar;
@@ -88,10 +85,8 @@ namespace System.Globalization {
#if FEATURE_LEAK_CULTURE_INFO
[NonSerialized]private bool m_isSafeCrossDomain;
[NonSerialized]private int m_createdDomainID;
-#endif // !FEATURE_CORECLR
-#if !FEATURE_CORECLR
+#endif // !FEATURE_LEAK_CULTURE_INFO
[NonSerialized]private CultureInfo m_consoleFallbackCulture;
-#endif // !FEATURE_CORECLR
// Names are confusing. Here are 3 names we have:
//
@@ -152,7 +147,6 @@ namespace System.Globalization {
#if FEATURE_APPX
// When running under AppX, we use this to get some information about the language list
- [SecurityCritical]
private static volatile WindowsRuntimeResourceManagerBase s_WindowsRuntimeResourceManager;
[ThreadStatic]
@@ -197,7 +191,6 @@ namespace System.Globalization {
return true;
}
- [System.Security.SecuritySafeCritical] // auto-generated
static CultureInfo InitUserDefaultCulture()
{
String strDefault = GetDefaultLocaleName(LOCALE_USER_DEFAULT);
@@ -241,7 +234,6 @@ namespace System.Globalization {
}
#if FEATURE_APPX
- [SecuritySafeCritical]
internal static CultureInfo GetCultureInfoForUserPreferredLanguageInAppX()
{
// If a call to GetCultureInfoForUserPreferredLanguageInAppX() generated a recursive
@@ -287,7 +279,6 @@ namespace System.Globalization {
return toReturn;
}
- [SecuritySafeCritical]
internal static bool SetCultureInfoForUserPreferredLanguageInAppX(CultureInfo ci)
{
// If running within a compilation process (mscorsvw.exe, for example), it is illegal to
@@ -323,7 +314,7 @@ namespace System.Globalization {
public CultureInfo(String name, bool useUserOverride) {
if (name==null) {
- throw new ArgumentNullException("name",
+ throw new ArgumentNullException(nameof(name),
Environment.GetResourceString("ArgumentNull_String"));
}
Contract.EndContractBlock();
@@ -332,7 +323,7 @@ namespace System.Globalization {
this.m_cultureData = CultureData.GetCultureData(name, useUserOverride);
if (this.m_cultureData == null) {
- throw new CultureNotFoundException("name", name, Environment.GetResourceString("Argument_CultureNotSupported"));
+ throw new CultureNotFoundException(nameof(name), name, Environment.GetResourceString("Argument_CultureNotSupported"));
}
this.m_name = this.m_cultureData.CultureName;
@@ -347,7 +338,7 @@ namespace System.Globalization {
public CultureInfo(int culture, bool useUserOverride) {
// We don't check for other invalid LCIDS here...
if (culture < 0) {
- throw new ArgumentOutOfRangeException("culture",
+ throw new ArgumentOutOfRangeException(nameof(culture),
Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
}
Contract.EndContractBlock();
@@ -367,7 +358,7 @@ namespace System.Globalization {
// Can't support unknown custom cultures and we do not support neutral or
// non-custom user locales.
throw new CultureNotFoundException(
- "culture", culture, Environment.GetResourceString("Argument_CultureNotSupported"));
+ nameof(culture), culture, Environment.GetResourceString("Argument_CultureNotSupported"));
default:
// Now see if this LCID is supported in the system default CultureData table.
@@ -413,18 +404,18 @@ namespace System.Globalization {
// e.g. for es-ES_tradnl: v2 puts es-ES in m_name; v4 puts es-ES_tradnl
if (m_name == null || IsAlternateSortLcid(cultureID))
{
- Contract.Assert(cultureID >=0, "[CultureInfo.OnDeserialized] cultureID >= 0");
+ Debug.Assert(cultureID >=0, "[CultureInfo.OnDeserialized] cultureID >= 0");
InitializeFromCultureId(cultureID, m_useUserOverride);
}
else
{
#endif
- Contract.Assert(m_name != null, "[CultureInfo.OnDeserialized] m_name != null");
+ 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(
- "m_name", m_name, Environment.GetResourceString("Argument_CultureNotSupported"));
+ nameof(m_name), m_name, Environment.GetResourceString("Argument_CultureNotSupported"));
#if FEATURE_USE_LCID
}
@@ -486,14 +477,14 @@ namespace System.Globalization {
// For Silverlight, the answer is always no.
internal bool IsSafeCrossDomain {
get {
- Contract.Assert(m_createdDomainID != 0, "[CultureInfo.IsSafeCrossDomain] m_createdDomainID != 0");
+ Debug.Assert(m_createdDomainID != 0, "[CultureInfo.IsSafeCrossDomain] m_createdDomainID != 0");
return m_isSafeCrossDomain;
}
}
internal int CreatedDomainID {
get {
- Contract.Assert(m_createdDomainID != 0, "[CultureInfo.CreatedDomain] m_createdDomainID != 0");
+ Debug.Assert(m_createdDomainID != 0, "[CultureInfo.CreatedDomain] m_createdDomainID != 0");
return m_createdDomainID;
}
}
@@ -540,7 +531,7 @@ namespace System.Globalization {
internal CultureInfo(String cultureName, String textAndCompareCultureName)
{
if (cultureName==null) {
- throw new ArgumentNullException("cultureName",
+ throw new ArgumentNullException(nameof(cultureName),
Environment.GetResourceString("ArgumentNull_String"));
}
Contract.EndContractBlock();
@@ -548,7 +539,7 @@ namespace System.Globalization {
this.m_cultureData = CultureData.GetCultureData(cultureName, false);
if (this.m_cultureData == null)
throw new CultureNotFoundException(
- "cultureName", cultureName, Environment.GetResourceString("Argument_CultureNotSupported"));
+ nameof(cultureName), cultureName, Environment.GetResourceString("Argument_CultureNotSupported"));
this.m_name = this.m_cultureData.CultureName;
@@ -644,7 +635,7 @@ namespace System.Globalization {
}
internal static bool VerifyCultureName(CultureInfo culture, bool throwException) {
- Contract.Assert(culture!=null, "[CultureInfo.VerifyCultureName]culture!=null");
+ Debug.Assert(culture!=null, "[CultureInfo.VerifyCultureName]culture!=null");
//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.
@@ -672,9 +663,6 @@ namespace System.Globalization {
get {
Contract.Ensures(Contract.Result<CultureInfo>() != null);
-#if !FEATURE_CORECLR
- return Thread.CurrentThread.CurrentCulture;
-#else
// 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
@@ -695,13 +683,12 @@ namespace System.Globalization {
s_DefaultThreadCurrentCulture ??
s_userDefaultCulture ??
UserDefaultCulture;
-#endif
}
set {
#if FEATURE_APPX
if (value == null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
if (AppDomain.IsAppXModel()) {
@@ -770,9 +757,6 @@ namespace System.Globalization {
get {
Contract.Ensures(Contract.Result<CultureInfo>() != null);
-#if !FEATURE_CORECLR
- return Thread.CurrentThread.CurrentUICulture;
-#else
// 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
@@ -793,13 +777,12 @@ namespace System.Globalization {
s_DefaultThreadCurrentUICulture ??
s_userDefaultUICulture ??
UserDefaultUICulture;
-#endif
}
set {
#if FEATURE_APPX
if (value == null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
if (AppDomain.IsAppXModel()) {
@@ -843,10 +826,6 @@ namespace System.Globalization {
return s_DefaultThreadCurrentCulture;
}
- [System.Security.SecuritySafeCritical] // auto-generated
-#pragma warning disable 618
- [SecurityPermission(SecurityAction.Demand, ControlThread = true)]
-#pragma warning restore 618
set {
// If you add pre-conditions to this method, check to see if you also need to
@@ -861,10 +840,6 @@ namespace System.Globalization {
return s_DefaultThreadCurrentUICulture;
}
- [System.Security.SecuritySafeCritical] // auto-generated
-#pragma warning disable 618
- [SecurityPermission(SecurityAction.Demand, ControlThread = true)]
-#pragma warning restore 618
set {
//If they're trying to use a Culture with a name that we can't use in resource lookup,
@@ -915,24 +890,23 @@ namespace System.Globalization {
public virtual CultureInfo Parent
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
Contract.Ensures(Contract.Result<CultureInfo>() != null);
+ CultureInfo culture = null;
if (null == m_parent)
{
try
{
string parentName = this.m_cultureData.SPARENT;
-
if (String.IsNullOrEmpty(parentName))
{
- m_parent = InvariantCulture;
+ culture = InvariantCulture;
}
else
{
- m_parent = new CultureInfo(parentName, this.m_cultureData.UseUserOverride);
+ culture = new CultureInfo(parentName, this.m_cultureData.UseUserOverride);
}
}
catch (ArgumentException)
@@ -940,8 +914,10 @@ 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.
- m_parent = InvariantCulture;
+ culture = InvariantCulture;
}
+
+ Interlocked.CompareExchange<CultureInfo>(ref m_parent, culture, null);
}
return m_parent;
}
@@ -1034,7 +1010,6 @@ namespace System.Globalization {
}
}
-#if !FEATURE_CORECLR
[System.Runtime.InteropServices.ComVisible(false)]
public String IetfLanguageTag
{
@@ -1054,7 +1029,6 @@ namespace System.Globalization {
}
}
}
-#endif
////////////////////////////////////////////////////////////////////////
//
@@ -1067,11 +1041,10 @@ namespace System.Globalization {
////////////////////////////////////////////////////////////////////////
public virtual String DisplayName
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
Contract.Ensures(Contract.Result<String>() != null);
- Contract.Assert(m_name != null, "[CultureInfo.DisplayName]Always expect m_name to be set");
+ Debug.Assert(m_name != null, "[CultureInfo.DisplayName]Always expect m_name to be set");
return m_cultureData.SLOCALIZEDDISPLAYNAME;
}
@@ -1087,7 +1060,6 @@ namespace System.Globalization {
//
////////////////////////////////////////////////////////////////////////
public virtual String NativeName {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
Contract.Ensures(Contract.Result<String>() != null);
return (this.m_cultureData.SNATIVEDISPLAYNAME);
@@ -1104,7 +1076,6 @@ namespace System.Globalization {
//
////////////////////////////////////////////////////////////////////////
public virtual String EnglishName {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
Contract.Ensures(Contract.Result<String>() != null);
return (this.m_cultureData.SENGDISPLAYNAME);
@@ -1113,7 +1084,6 @@ namespace System.Globalization {
// ie: en
public virtual String TwoLetterISOLanguageName {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
Contract.Ensures(Contract.Result<String>() != null);
return (this.m_cultureData.SISO639LANGNAME);
@@ -1122,7 +1092,6 @@ namespace System.Globalization {
// ie: eng
public virtual String ThreeLetterISOLanguageName {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
Contract.Ensures(Contract.Result<String>() != null);
return (this.m_cultureData.SISO639LANGNAME2);
@@ -1138,7 +1107,6 @@ namespace System.Globalization {
//
////////////////////////////////////////////////////////////////////////
public virtual String ThreeLetterWindowsLanguageName {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
Contract.Ensures(Contract.Result<String>() != null);
return (this.m_cultureData.SABBREVLANGNAME);
@@ -1178,31 +1146,6 @@ namespace System.Globalization {
}
}
-#if !FEATURE_CORECLR
- ////////////////////////////////////////////////////////////////////////
- //
- // RegionInfo
- //
- // Gets the RegionInfo for this culture.
- //
- ////////////////////////////////////////////////////////////////////////
- private RegionInfo Region
- {
- get
- {
- if (regionInfo==null)
- {
- // Make a new regionInfo
- RegionInfo tempRegionInfo = new RegionInfo(this.m_cultureData);
- regionInfo = tempRegionInfo;
- }
- return (regionInfo);
- }
- }
-#endif // FEATURE_CORECLR
-
-
-
////////////////////////////////////////////////////////////////////////
//
// TextInfo
@@ -1294,7 +1237,7 @@ namespace System.Globalization {
{
Contract.Ensures(Contract.Result<String>() != null);
- Contract.Assert(m_name != null, "[CultureInfo.ToString]Always expect m_name to be set");
+ Debug.Assert(m_name != null, "[CultureInfo.ToString]Always expect m_name to be set");
return m_name;
}
@@ -1315,7 +1258,6 @@ namespace System.Globalization {
}
}
-#if !FEATURE_CORECLR
[System.Runtime.InteropServices.ComVisible(false)]
public CultureTypes CultureTypes
{
@@ -1333,15 +1275,14 @@ namespace System.Globalization {
// 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;
}
}
-#endif
public virtual NumberFormatInfo NumberFormat {
get
@@ -1351,13 +1292,13 @@ namespace System.Globalization {
if (numInfo == null) {
NumberFormatInfo temp = new NumberFormatInfo(this.m_cultureData);
temp.isReadOnly = m_isReadOnly;
- numInfo = temp;
+ Interlocked.CompareExchange(ref numInfo, temp, null);
}
return (numInfo);
}
set {
if (value == null) {
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
Environment.GetResourceString("ArgumentNull_Obj"));
}
Contract.EndContractBlock();
@@ -1385,15 +1326,14 @@ namespace System.Globalization {
DateTimeFormatInfo temp = new DateTimeFormatInfo(
this.m_cultureData, this.Calendar);
temp.m_isReadOnly = m_isReadOnly;
- System.Threading.Thread.MemoryBarrier();
- dateTimeInfo = temp;
+ Interlocked.CompareExchange(ref dateTimeInfo, temp, null);
}
return (dateTimeInfo);
}
set {
if (value == null) {
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
Environment.GetResourceString("ArgumentNull_Obj"));
}
Contract.EndContractBlock();
@@ -1402,17 +1342,16 @@ namespace System.Globalization {
}
}
-
-
public void ClearCachedData() {
s_userDefaultUICulture = null;
s_userDefaultCulture = null;
RegionInfo.s_currentRegionInfo = null;
-#if !FEATURE_CORECLR // System.TimeZone does not exist in CoreCLR
+#pragma warning disable CS0618
TimeZone.ResetTimeZone();
-#endif // FEATURE_CORECLR
+#pragma warning restore CS0618
TimeZoneInfo.ClearCachedData();
+
// Delete the cached cultures.
s_LcidCachedCultures = null;
s_NameCachedCultures = null;
@@ -1438,7 +1377,7 @@ 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) {
- Contract.Assert(calType!=Calendar.CAL_GREGORIAN, "calType!=Calendar.CAL_GREGORIAN");
+ Debug.Assert(calType!=Calendar.CAL_GREGORIAN, "calType!=Calendar.CAL_GREGORIAN");
switch (calType) {
case Calendar.CAL_GREGORIAN_US: // Gregorian (U.S.) calendar
@@ -1490,7 +1429,7 @@ namespace System.Globalization {
get {
Contract.Ensures(Contract.Result<Calendar>() != null);
if (calendar == null) {
- Contract.Assert(this.m_cultureData.CalendarIds.Length > 0, "this.m_cultureData.CalendarIds.Length > 0");
+ 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;
@@ -1534,8 +1473,6 @@ namespace System.Globalization {
}
}
-#if !FEATURE_CORECLR
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(false)]
public CultureInfo GetConsoleFallbackUICulture()
{
@@ -1550,7 +1487,6 @@ namespace System.Globalization {
}
return (temp);
}
-#endif
public virtual Object Clone()
{
@@ -1595,7 +1531,7 @@ namespace System.Globalization {
public static CultureInfo ReadOnly(CultureInfo ci) {
if (ci == null) {
- throw new ArgumentNullException("ci");
+ throw new ArgumentNullException(nameof(ci));
}
Contract.Ensures(Contract.Result<CultureInfo>() != null);
Contract.EndContractBlock();
@@ -1827,7 +1763,7 @@ namespace System.Globalization {
// 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("culture",
+ throw new ArgumentOutOfRangeException(nameof(culture),
Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
}
Contract.Ensures(Contract.Result<CultureInfo>() != null);
@@ -1836,7 +1772,7 @@ namespace System.Globalization {
if (null == retval)
{
throw new CultureNotFoundException(
- "culture", culture, Environment.GetResourceString("Argument_CultureNotSupported"));
+ nameof(culture), culture, Environment.GetResourceString("Argument_CultureNotSupported"));
}
return retval;
}
@@ -1849,7 +1785,7 @@ namespace System.Globalization {
// Make sure we have a valid, non-zero length string as name
if (name == null)
{
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
}
Contract.Ensures(Contract.Result<CultureInfo>() != null);
Contract.EndContractBlock();
@@ -1858,7 +1794,7 @@ namespace System.Globalization {
if (retval == null)
{
throw new CultureNotFoundException(
- "name", name, Environment.GetResourceString("Argument_CultureNotSupported"));
+ nameof(name), name, Environment.GetResourceString("Argument_CultureNotSupported"));
}
return retval;
@@ -1871,12 +1807,12 @@ namespace System.Globalization {
// Make sure we have a valid, non-zero length string as name
if (null == name)
{
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
}
if (null == altName)
{
- throw new ArgumentNullException("altName");
+ throw new ArgumentNullException(nameof(altName));
}
Contract.Ensures(Contract.Result<CultureInfo>() != null);
Contract.EndContractBlock();
@@ -1884,7 +1820,7 @@ namespace System.Globalization {
CultureInfo retval = GetCultureInfoHelper(-1, name, altName);
if (retval == null)
{
- throw new CultureNotFoundException("name or altName",
+ throw new CultureNotFoundException(nameof(name) + " or " + nameof(altName),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("Argument_OneOfCulturesNotSupported"),
@@ -1904,7 +1840,7 @@ namespace System.Globalization {
if (name == "zh-CHT" || name == "zh-CHS")
{
throw new CultureNotFoundException(
- "name",
+ nameof(name),
String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_CultureIetfNotSupported"), name)
);
}
@@ -1915,7 +1851,7 @@ namespace System.Globalization {
if (ci.LCID > 0xffff || ci.LCID == 0x040a)
{
throw new CultureNotFoundException(
- "name",
+ nameof(name),
String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_CultureIetfNotSupported"), name)
);
}
@@ -1943,22 +1879,18 @@ namespace System.Globalization {
//
// Get Locale Info Ex calls. So we don't have to muck with the different int/string return types we declared two of these:
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern String nativeGetLocaleInfoEx(String localeName, uint field);
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern int nativeGetLocaleInfoExInt(String localeName, uint field);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool nativeSetThreadLocale(String localeName);
- [System.Security.SecurityCritical]
private static String GetDefaultLocaleName(int localeType)
{
- Contract.Assert(localeType == LOCALE_USER_DEFAULT || localeType == LOCALE_SYSTEM_DEFAULT, "[CultureInfo.GetDefaultLocaleName] localeType must be LOCALE_USER_DEFAULT or LOCALE_SYSTEM_DEFAULT");
+ 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)))
@@ -1969,13 +1901,11 @@ namespace System.Globalization {
}
// Get the default locale name
- [System.Security.SecurityCritical] // auto-generated
[SuppressUnmanagedCodeSecurity]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool InternalGetDefaultLocaleName(int localetype, StringHandleOnStack localeString);
- [System.Security.SecuritySafeCritical] // auto-generated
private static String GetUserDefaultUILanguage()
{
string userDefaultUiLanguage = null;
@@ -1987,13 +1917,11 @@ namespace System.Globalization {
}
// Get the user's default UI language, return locale name
- [System.Security.SecurityCritical] // auto-generated
[SuppressUnmanagedCodeSecurity]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool InternalGetUserDefaultUILanguage(StringHandleOnStack userDefaultUiLanguage);
- [System.Security.SecuritySafeCritical] // auto-generated
private static String GetSystemDefaultUILanguage()
{
string systemDefaultUiLanguage = null;
@@ -2005,19 +1933,14 @@ namespace System.Globalization {
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[SuppressUnmanagedCodeSecurity]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool InternalGetSystemDefaultUILanguage(StringHandleOnStack systemDefaultUiLanguage);
-// Added but disabled from desktop in .NET 4.0, stayed disabled in .NET 4.5
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern String[] nativeGetResourceFallbackArray();
-#endif
}
}
diff --git a/src/mscorlib/src/System/Globalization/CultureNotFoundException.cs b/src/mscorlib/src/System/Globalization/CultureNotFoundException.cs
index 0486cc9d17..17c0b43f9c 100644
--- a/src/mscorlib/src/System/Globalization/CultureNotFoundException.cs
+++ b/src/mscorlib/src/System/Globalization/CultureNotFoundException.cs
@@ -66,10 +66,9 @@ namespace System.Globalization {
m_invalidCultureName = (string) info.GetValue("InvalidCultureName", typeof(string));
}
- [System.Security.SecurityCritical] // auto-generated_required
public override void GetObjectData(SerializationInfo info, StreamingContext context) {
if (info==null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
base.GetObjectData(info, context);
diff --git a/src/mscorlib/src/System/Globalization/DateTimeFormat.cs b/src/mscorlib/src/System/Globalization/DateTimeFormat.cs
index 228e5f56a2..c6e0591a74 100644
--- a/src/mscorlib/src/System/Globalization/DateTimeFormat.cs
+++ b/src/mscorlib/src/System/Globalization/DateTimeFormat.cs
@@ -11,6 +11,7 @@ namespace System {
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
/*
@@ -139,8 +140,13 @@ namespace System {
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;
-
+ 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",
@@ -166,13 +172,12 @@ namespace System {
//
////////////////////////////////////////////////////////////////////////////
internal static void FormatDigits(StringBuilder outputBuffer, int value, int len) {
- Contract.Assert(value >= 0, "DateTimeFormat.FormatDigits(): value >= 0");
+ Debug.Assert(value >= 0, "DateTimeFormat.FormatDigits(): value >= 0");
FormatDigits(outputBuffer, value, len, false);
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static void FormatDigits(StringBuilder outputBuffer, int value, int len, bool overrideLengthLimit) {
- Contract.Assert(value >= 0, "DateTimeFormat.FormatDigits(): value >= 0");
+ 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.
@@ -218,7 +223,7 @@ namespace System {
private static String FormatDayOfWeek(int dayOfWeek, int repeat, DateTimeFormatInfo dtfi)
{
- Contract.Assert(dayOfWeek >= 0 && dayOfWeek <= 6, "dayOfWeek >= 0 && dayOfWeek <= 6");
+ Debug.Assert(dayOfWeek >= 0 && dayOfWeek <= 6, "dayOfWeek >= 0 && dayOfWeek <= 6");
if (repeat == 3)
{
return (dtfi.GetAbbreviatedDayName((DayOfWeek)dayOfWeek));
@@ -230,7 +235,7 @@ namespace System {
private static String FormatMonth(int month, int repeatCount, DateTimeFormatInfo dtfi)
{
- Contract.Assert(month >=1 && month <= 12, "month >=1 && month <= 12");
+ Debug.Assert(month >=1 && month <= 12, "month >=1 && month <= 12");
if (repeatCount == 3)
{
return (dtfi.GetAbbreviatedMonthName(month));
@@ -271,7 +276,7 @@ namespace System {
*/
private static String FormatHebrewMonthName(DateTime time, int month, int repeatCount, DateTimeFormatInfo dtfi)
{
- Contract.Assert(repeatCount != 3 || repeatCount != 4, "repeateCount should be 3 or 4");
+ 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)));
@@ -703,24 +708,13 @@ namespace System {
// 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) {
-#if FEATURE_CORECLR
offset = TimeSpan.Zero;
-#else // FEATURE_CORECLR
- // This code path points to a bug in user code. It would make sense to return a 0 offset in this case.
- // However, because it was only possible to detect this in Whidbey, there is user code that takes a
- // dependency on being serialize a UTC DateTime using the 'z' format, and it will work almost all the
- // time if it is offset by an incorrect conversion to local time when parsed. Therefore, we need to
- // explicitly emit the local time offset, which we can do by removing the UTC flag.
- InvalidFormatForUtc(format, dateTime);
- dateTime = DateTime.SpecifyKind(dateTime, DateTimeKind.Local);
- offset = TimeZoneInfo.GetLocalUtcOffset(dateTime, TimeZoneInfoOptions.NoThrowOnInvalidTime);
-#endif // FEATURE_CORECLR
} else {
offset = TimeZoneInfo.GetLocalUtcOffset(dateTime, TimeZoneInfoOptions.NoThrowOnInvalidTime);
}
}
if (offset >= TimeSpan.Zero) {
- result.Append('+');
+ result.Append('+');
}
else {
result.Append('-');
@@ -739,7 +733,7 @@ namespace System {
// '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
@@ -775,7 +769,9 @@ namespace System {
offset = offset.Negate();
}
- result.AppendFormat(CultureInfo.InvariantCulture, "{0:00}:{1:00}", offset.Hours, offset.Minutes);
+ AppendNumber(result, offset.Hours, 2);
+ result.Append(':');
+ AppendNumber(result, offset.Minutes, 2);
}
@@ -957,12 +953,101 @@ namespace System {
}
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);
@@ -1042,7 +1127,6 @@ namespace System {
// This is an MDA for cases when the user is using a local format with
// a Utc DateTime.
- [System.Security.SecuritySafeCritical] // auto-generated
internal static void InvalidFormatForUtc(String format, DateTime dateTime) {
#if MDA_SUPPORTED
Mda.DateTimeInvalidLocalFormat();
diff --git a/src/mscorlib/src/System/Globalization/DateTimeFormatInfo.cs b/src/mscorlib/src/System/Globalization/DateTimeFormatInfo.cs
index 00c2d1f439..14cdeb60e9 100644
--- a/src/mscorlib/src/System/Globalization/DateTimeFormatInfo.cs
+++ b/src/mscorlib/src/System/Globalization/DateTimeFormatInfo.cs
@@ -14,6 +14,7 @@ namespace System.Globalization {
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
//
@@ -181,18 +182,6 @@ namespace System.Globalization {
// genitive form or leap year month names.
[OptionalField(VersionAdded = 2)]
internal DateTimeFormatFlags formatFlags = DateTimeFormatFlags.NotInitialized;
- internal static bool preferExistingTokens = InitPreferExistingTokens();
-
-
- [System.Security.SecuritySafeCritical]
- static bool InitPreferExistingTokens()
- {
- bool ret = false;
-#if !FEATURE_CORECLR
- ret = DateTime.LegacyParseMode();
-#endif
- return ret;
- }
private String CultureName
{
@@ -220,7 +209,6 @@ namespace System.Globalization {
private String LanguageName
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (m_langName == null)
@@ -243,7 +231,7 @@ namespace System.Globalization {
{
// Get the abbreviated day names for our current calendar
this.abbreviatedDayNames = this.m_cultureData.AbbreviatedDayNames(Calendar.ID);
- Contract.Assert(this.abbreviatedDayNames.Length == 7, "[DateTimeFormatInfo.GetAbbreviatedDayOfWeekNames] Expected 7 day names in a week");
+ Debug.Assert(this.abbreviatedDayNames.Length == 7, "[DateTimeFormatInfo.GetAbbreviatedDayOfWeekNames] Expected 7 day names in a week");
}
return (this.abbreviatedDayNames);
}
@@ -266,7 +254,7 @@ namespace System.Globalization {
{
// Get the super short day names for our current calendar
this.m_superShortDayNames = this.m_cultureData.SuperShortDayNames(Calendar.ID);
- Contract.Assert(this.m_superShortDayNames.Length == 7, "[DateTimeFormatInfo.internalGetSuperShortDayNames] Expected 7 day names in a week");
+ Debug.Assert(this.m_superShortDayNames.Length == 7, "[DateTimeFormatInfo.internalGetSuperShortDayNames] Expected 7 day names in a week");
}
return (this.m_superShortDayNames);
}
@@ -283,7 +271,7 @@ namespace System.Globalization {
{
// Get the day names for our current calendar
this.dayNames = this.m_cultureData.DayNames(Calendar.ID);
- Contract.Assert(this.dayNames.Length == 7, "[DateTimeFormatInfo.GetDayOfWeekNames] Expected 7 day names in a week");
+ Debug.Assert(this.dayNames.Length == 7, "[DateTimeFormatInfo.GetDayOfWeekNames] Expected 7 day names in a week");
}
return (this.dayNames);
}
@@ -300,7 +288,7 @@ namespace System.Globalization {
{
// Get the month names for our current calendar
this.abbreviatedMonthNames = this.m_cultureData.AbbreviatedMonthNames(Calendar.ID);
- Contract.Assert(this.abbreviatedMonthNames.Length == 12 || this.abbreviatedMonthNames.Length == 13,
+ Debug.Assert(this.abbreviatedMonthNames.Length == 12 || this.abbreviatedMonthNames.Length == 13,
"[DateTimeFormatInfo.GetAbbreviatedMonthNames] Expected 12 or 13 month names in a year");
}
return (this.abbreviatedMonthNames);
@@ -319,7 +307,7 @@ namespace System.Globalization {
{
// Get the month names for our current calendar
this.monthNames = this.m_cultureData.MonthNames(Calendar.ID);
- Contract.Assert(this.monthNames.Length == 12 || this.monthNames.Length == 13,
+ Debug.Assert(this.monthNames.Length == 12 || this.monthNames.Length == 13,
"[DateTimeFormatInfo.GetMonthNames] Expected 12 or 13 month names in a year");
}
@@ -347,16 +335,12 @@ namespace System.Globalization {
// m_isDefaultCalendar is set in the setter of Calendar below.
this.Calendar = cal;
}
-
-#if !FEATURE_CORECLR
- [System.Security.SecuritySafeCritical]
-#endif
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);
- Contract.Assert(calendarID > 0, "[DateTimeFormatInfo.Populate] Expected Calendar.ID > 0");
+ 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; }
@@ -367,19 +351,19 @@ namespace System.Globalization {
if (this.dateSeparator == null) { this.dateSeparator = cultureData.DateSeparator(calendarID); }
this.allLongTimePatterns = this.m_cultureData.LongTimes;
- Contract.Assert(this.allLongTimePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some long time patterns");
+ Debug.Assert(this.allLongTimePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some long time patterns");
this.allShortTimePatterns = this.m_cultureData.ShortTimes;
- Contract.Assert(this.allShortTimePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some short time patterns");
+ Debug.Assert(this.allShortTimePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some short time patterns");
this.allLongDatePatterns = cultureData.LongDates(calendarID);
- Contract.Assert(this.allLongDatePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some long date patterns");
+ Debug.Assert(this.allLongDatePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some long date patterns");
this.allShortDatePatterns = cultureData.ShortDates(calendarID);
- Contract.Assert(this.allShortDatePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some short date patterns");
+ Debug.Assert(this.allShortDatePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some short date patterns");
this.allYearMonthPatterns = cultureData.YearMonths(calendarID);
- Contract.Assert(this.allYearMonthPatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some year month patterns");
+ Debug.Assert(this.allYearMonthPatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some year month patterns");
}
#region Serialization
@@ -411,7 +395,7 @@ namespace System.Globalization {
if (this.m_cultureData == null)
throw new CultureNotFoundException(
- "m_name", m_name, Environment.GetResourceString("Argument_CultureNotSupported"));
+ nameof(m_name), m_name, Environment.GetResourceString("Argument_CultureNotSupported"));
}
// Note: This is for Everett compatibility
@@ -458,11 +442,6 @@ namespace System.Globalization {
// make sure the m_name is initialized.
m_name = this.CultureName;
-#if !FEATURE_CORECLR
- if (s_calendarNativeNames == null)
- s_calendarNativeNames = new Hashtable();
-#endif // FEATURE_CORECLR
-
// 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.
@@ -561,18 +540,14 @@ namespace System.Globalization {
public String AMDesignator
{
-#if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical] // auto-generated
-#endif
get
{
-#if FEATURE_CORECLR
if (this.amDesignator == null)
{
this.amDesignator = this.m_cultureData.SAM1159;
}
-#endif
- Contract.Assert(this.amDesignator != null, "DateTimeFormatInfo.AMDesignator, amDesignator != null");
+
+ Debug.Assert(this.amDesignator != null, "DateTimeFormatInfo.AMDesignator, amDesignator != null");
return (this.amDesignator);
}
@@ -582,7 +557,7 @@ namespace System.Globalization {
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
if (value == null)
{
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
Environment.GetResourceString("ArgumentNull_String"));
}
Contract.EndContractBlock();
@@ -596,7 +571,7 @@ namespace System.Globalization {
get {
Contract.Ensures(Contract.Result<Calendar>() != null);
- Contract.Assert(this.calendar != null, "DateTimeFormatInfo.Calendar: calendar != null");
+ Debug.Assert(this.calendar != null, "DateTimeFormatInfo.Calendar: calendar != null");
return (this.calendar);
}
@@ -604,7 +579,7 @@ namespace System.Globalization {
if (IsReadOnly)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
if (value == null) {
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
Environment.GetResourceString("ArgumentNull_Obj"));
}
Contract.EndContractBlock();
@@ -694,7 +669,7 @@ namespace System.Globalization {
}
// The assigned calendar is not a valid calendar for this culture, throw
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("Argument_InvalidCalendar"));
+ throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("Argument_InvalidCalendar"));
}
}
@@ -718,7 +693,7 @@ namespace System.Globalization {
public int GetEra(String eraName) {
if (eraName == null) {
- throw new ArgumentNullException("eraName",
+ throw new ArgumentNullException(nameof(eraName),
Environment.GetResourceString("ArgumentNull_String"));
}
Contract.EndContractBlock();
@@ -795,7 +770,7 @@ namespace System.Globalization {
if ((--era) < EraNames.Length && (era >= 0)) {
return (m_eraNames[era]);
}
- throw new ArgumentOutOfRangeException("era", Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
}
internal String[] AbbreviatedEraNames
@@ -823,7 +798,7 @@ namespace System.Globalization {
if ((--era) < m_abbrevEraNames.Length && (era >= 0)) {
return (m_abbrevEraNames[era]);
}
- throw new ArgumentOutOfRangeException("era", Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
}
internal String[] AbbreviatedEnglishEraNames
@@ -832,7 +807,7 @@ namespace System.Globalization {
{
if (this.m_abbrevEnglishEraNames == null)
{
- Contract.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.AbbreviatedEnglishEraNames] Expected Calendar.ID > 0");
+ Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.AbbreviatedEnglishEraNames] Expected Calendar.ID > 0");
this.m_abbrevEnglishEraNames = this.m_cultureData.AbbreviatedEnglishEraNames(Calendar.ID);
}
return (this.m_abbrevEnglishEraNames);
@@ -846,13 +821,12 @@ namespace System.Globalization {
{
get
{
-#if FEATURE_CORECLR
if (this.dateSeparator == null)
{
this.dateSeparator = this.m_cultureData.DateSeparator(Calendar.ID);
}
-#endif
- Contract.Assert(this.dateSeparator != null, "DateTimeFormatInfo.DateSeparator, dateSeparator != null");
+
+ Debug.Assert(this.dateSeparator != null, "DateTimeFormatInfo.DateSeparator, dateSeparator != null");
return (this.dateSeparator);
}
@@ -862,7 +836,7 @@ namespace System.Globalization {
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
if (value == null)
{
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
Environment.GetResourceString("ArgumentNull_String"));
}
Contract.EndContractBlock();
@@ -876,14 +850,12 @@ namespace System.Globalization {
{
get
{
-#if FEATURE_CORECLR
if (this.firstDayOfWeek == -1)
{
this.firstDayOfWeek = this.m_cultureData.IFIRSTDAYOFWEEK;
}
-#endif
- Contract.Assert(this.firstDayOfWeek != -1, "DateTimeFormatInfo.FirstDayOfWeek, firstDayOfWeek != -1");
-
+
+ Debug.Assert(this.firstDayOfWeek != -1, "DateTimeFormatInfo.FirstDayOfWeek, firstDayOfWeek != -1");
return ((DayOfWeek)this.firstDayOfWeek);
}
@@ -894,7 +866,7 @@ namespace System.Globalization {
firstDayOfWeek = (int)value;
} else {
throw new ArgumentOutOfRangeException(
- "value", Environment.GetResourceString("ArgumentOutOfRange_Range",
+ nameof(value), Environment.GetResourceString("ArgumentOutOfRange_Range",
DayOfWeek.Sunday, DayOfWeek.Saturday));
}
}
@@ -905,13 +877,12 @@ namespace System.Globalization {
{
get
{
-#if FEATURE_CORECLR
if (this.calendarWeekRule == -1)
{
this.calendarWeekRule = this.m_cultureData.IFIRSTWEEKOFYEAR;
}
-#endif
- Contract.Assert(this.calendarWeekRule != -1, "DateTimeFormatInfo.CalendarWeekRule, calendarWeekRule != -1");
+
+ Debug.Assert(this.calendarWeekRule != -1, "DateTimeFormatInfo.CalendarWeekRule, calendarWeekRule != -1");
return ((CalendarWeekRule)this.calendarWeekRule);
}
@@ -922,7 +893,7 @@ namespace System.Globalization {
calendarWeekRule = (int)value;
} else {
throw new ArgumentOutOfRangeException(
- "value", Environment.GetResourceString("ArgumentOutOfRange_Range",
+ nameof(value), Environment.GetResourceString("ArgumentOutOfRange_Range",
CalendarWeekRule.FirstDay, CalendarWeekRule.FirstFourDayWeek));
}
}
@@ -945,7 +916,7 @@ namespace System.Globalization {
if (IsReadOnly)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
if (value == null) {
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
Environment.GetResourceString("ArgumentNull_String"));
}
Contract.EndContractBlock();
@@ -977,7 +948,7 @@ namespace System.Globalization {
if (IsReadOnly)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
if (value == null) {
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
Environment.GetResourceString("ArgumentNull_String"));
}
Contract.EndContractBlock();
@@ -1016,7 +987,7 @@ namespace System.Globalization {
if (IsReadOnly)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
if (value == null) {
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
Environment.GetResourceString("ArgumentNull_String"));
}
Contract.EndContractBlock();
@@ -1042,10 +1013,10 @@ namespace System.Globalization {
{
if (this.monthDayPattern == null)
{
- Contract.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.MonthDayPattern] Expected calID > 0");
+ Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.MonthDayPattern] Expected calID > 0");
this.monthDayPattern = this.m_cultureData.MonthDay(Calendar.ID);
}
- Contract.Assert(this.monthDayPattern != null, "DateTimeFormatInfo.MonthDayPattern, monthDayPattern != null");
+ Debug.Assert(this.monthDayPattern != null, "DateTimeFormatInfo.MonthDayPattern, monthDayPattern != null");
return (this.monthDayPattern);
}
@@ -1053,7 +1024,7 @@ namespace System.Globalization {
if (IsReadOnly)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
if (value == null) {
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
Environment.GetResourceString("ArgumentNull_String"));
}
Contract.EndContractBlock();
@@ -1065,18 +1036,14 @@ namespace System.Globalization {
public String PMDesignator
{
-#if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical] // auto-generated
-#endif
get
{
-#if FEATURE_CORECLR
if (this.pmDesignator == null)
{
this.pmDesignator = this.m_cultureData.SPM2359;
}
-#endif
- Contract.Assert(this.pmDesignator != null, "DateTimeFormatInfo.PMDesignator, pmDesignator != null");
+
+ Debug.Assert(this.pmDesignator != null, "DateTimeFormatInfo.PMDesignator, pmDesignator != null");
return (this.pmDesignator);
}
@@ -1084,7 +1051,7 @@ namespace System.Globalization {
if (IsReadOnly)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
if (value == null) {
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
Environment.GetResourceString("ArgumentNull_String"));
}
Contract.EndContractBlock();
@@ -1128,7 +1095,7 @@ namespace System.Globalization {
if (IsReadOnly)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
if (value == null)
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
Environment.GetResourceString("ArgumentNull_String"));
Contract.EndContractBlock();
@@ -1168,7 +1135,7 @@ namespace System.Globalization {
if (IsReadOnly)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
if (value == null) {
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
Environment.GetResourceString("ArgumentNull_String"));
}
Contract.EndContractBlock();
@@ -1292,13 +1259,12 @@ namespace System.Globalization {
{
get
{
-#if FEATURE_CORECLR
if (timeSeparator == null)
{
timeSeparator = this.m_cultureData.TimeSeparator;
}
-#endif
- Contract.Assert(this.timeSeparator != null, "DateTimeFormatInfo.TimeSeparator, timeSeparator != null");
+
+ Debug.Assert(this.timeSeparator != null, "DateTimeFormatInfo.TimeSeparator, timeSeparator != null");
return (timeSeparator);
}
@@ -1308,7 +1274,7 @@ namespace System.Globalization {
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
if (value == null)
{
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
Environment.GetResourceString("ArgumentNull_String"));
}
Contract.EndContractBlock();
@@ -1349,7 +1315,7 @@ namespace System.Globalization {
if (IsReadOnly)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
if (value == null) {
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
Environment.GetResourceString("ArgumentNull_String"));
}
Contract.EndContractBlock();
@@ -1388,11 +1354,11 @@ namespace System.Globalization {
if (IsReadOnly)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
if (value == null) {
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
Environment.GetResourceString("ArgumentNull_Array"));
}
if (value.Length != 7) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidArrayLength", 7), "value");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidArrayLength", 7), nameof(value));
}
Contract.EndContractBlock();
CheckNullValue(value, value.Length);
@@ -1416,12 +1382,12 @@ namespace System.Globalization {
if (IsReadOnly)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
if (value == null) {
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
Environment.GetResourceString("ArgumentNull_Array"));
}
if (value.Length != 7)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidArrayLength", 7), "value");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidArrayLength", 7), nameof(value));
}
Contract.EndContractBlock();
CheckNullValue(value, value.Length);
@@ -1441,12 +1407,12 @@ namespace System.Globalization {
if (IsReadOnly)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
if (value == null) {
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
Environment.GetResourceString("ArgumentNull_Array"));
}
if (value.Length != 7)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidArrayLength", 7), "value");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidArrayLength", 7), nameof(value));
}
Contract.EndContractBlock();
CheckNullValue(value, value.Length);
@@ -1466,12 +1432,12 @@ namespace System.Globalization {
if (IsReadOnly)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
if (value == null) {
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
Environment.GetResourceString("ArgumentNull_Array"));
}
if (value.Length != 13)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidArrayLength", 13), "value");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidArrayLength", 13), nameof(value));
}
Contract.EndContractBlock();
CheckNullValue(value, value.Length - 1);
@@ -1492,12 +1458,12 @@ namespace System.Globalization {
if (IsReadOnly)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
if (value == null) {
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
Environment.GetResourceString("ArgumentNull_Array"));
}
if (value.Length != 13)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidArrayLength", 13), "value");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidArrayLength", 13), nameof(value));
}
Contract.EndContractBlock();
CheckNullValue(value, value.Length - 1);
@@ -1556,7 +1522,7 @@ namespace System.Globalization {
// (actually is 13 right now for all cases)
if ((month < 1) || (month > monthNamesArray.Length)) {
throw new ArgumentOutOfRangeException(
- "month", Environment.GetResourceString("ArgumentOutOfRange_Range",
+ nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Range",
1, monthNamesArray.Length));
}
return (monthNamesArray[month-1]);
@@ -1575,7 +1541,7 @@ namespace System.Globalization {
if (this.m_genitiveAbbreviatedMonthNames == null)
{
this.m_genitiveAbbreviatedMonthNames = this.m_cultureData.AbbreviatedGenitiveMonthNames(this.Calendar.ID);
- Contract.Assert(this.m_genitiveAbbreviatedMonthNames.Length == 13,
+ Debug.Assert(this.m_genitiveAbbreviatedMonthNames.Length == 13,
"[DateTimeFormatInfo.GetGenitiveMonthNames] Expected 13 abbreviated genitive month names in a year");
}
return (this.m_genitiveAbbreviatedMonthNames);
@@ -1584,7 +1550,7 @@ namespace System.Globalization {
if (this.genitiveMonthNames == null)
{
this.genitiveMonthNames = this.m_cultureData.GenitiveMonthNames(this.Calendar.ID);
- Contract.Assert(this.genitiveMonthNames.Length == 13,
+ Debug.Assert(this.genitiveMonthNames.Length == 13,
"[DateTimeFormatInfo.GetGenitiveMonthNames] Expected 13 genitive month names in a year");
}
return (this.genitiveMonthNames);
@@ -1600,9 +1566,9 @@ namespace System.Globalization {
internal String[] internalGetLeapYearMonthNames(/*bool abbreviated*/) {
if (this.leapYearMonthNames == null)
{
- Contract.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.internalGetLeapYearMonthNames] Expected Calendar.ID > 0");
+ Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.internalGetLeapYearMonthNames] Expected Calendar.ID > 0");
this.leapYearMonthNames = this.m_cultureData.LeapYearMonthNames(Calendar.ID);
- Contract.Assert(this.leapYearMonthNames.Length == 13,
+ Debug.Assert(this.leapYearMonthNames.Length == 13,
"[DateTimeFormatInfo.internalGetLeapYearMonthNames] Expepcted 13 leap year month names");
}
return (leapYearMonthNames);
@@ -1614,7 +1580,7 @@ namespace System.Globalization {
if ((int)dayofweek < 0 || (int)dayofweek > 6) {
throw new ArgumentOutOfRangeException(
- "dayofweek", Environment.GetResourceString("ArgumentOutOfRange_Range",
+ nameof(dayofweek), Environment.GetResourceString("ArgumentOutOfRange_Range",
DayOfWeek.Sunday, DayOfWeek.Saturday));
}
Contract.EndContractBlock();
@@ -1633,7 +1599,7 @@ namespace System.Globalization {
if ((int)dayOfWeek < 0 || (int)dayOfWeek > 6) {
throw new ArgumentOutOfRangeException(
- "dayOfWeek", Environment.GetResourceString("ArgumentOutOfRange_Range",
+ nameof(dayOfWeek), Environment.GetResourceString("ArgumentOutOfRange_Range",
DayOfWeek.Sunday, DayOfWeek.Saturday));
}
Contract.EndContractBlock();
@@ -1740,7 +1706,7 @@ namespace System.Globalization {
result = this.AllYearMonthPatterns;
break;
default:
- throw new ArgumentException(Environment.GetResourceString("Format_BadFormatSpecifier"), "format");
+ throw new ArgumentException(Environment.GetResourceString("Format_BadFormatSpecifier"), nameof(format));
}
return (result);
}
@@ -1750,7 +1716,7 @@ namespace System.Globalization {
{
if ((int)dayofweek < 0 || (int)dayofweek > 6) {
throw new ArgumentOutOfRangeException(
- "dayofweek", Environment.GetResourceString("ArgumentOutOfRange_Range",
+ nameof(dayofweek), Environment.GetResourceString("ArgumentOutOfRange_Range",
DayOfWeek.Sunday, DayOfWeek.Saturday));
}
Contract.EndContractBlock();
@@ -1765,7 +1731,7 @@ namespace System.Globalization {
{
if (month < 1 || month > 13) {
throw new ArgumentOutOfRangeException(
- "month", Environment.GetResourceString("ArgumentOutOfRange_Range",
+ nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Range",
1, 13));
}
Contract.EndContractBlock();
@@ -1778,7 +1744,7 @@ namespace System.Globalization {
{
if (month < 1 || month > 13) {
throw new ArgumentOutOfRangeException(
- "month", Environment.GetResourceString("ArgumentOutOfRange_Range",
+ nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Range",
1, 13));
}
Contract.EndContractBlock();
@@ -1795,9 +1761,9 @@ namespace System.Globalization {
// The resulting [] can get returned to the calling app, so clone it.
private static string[] GetMergedPatterns(string [] patterns, string defaultPattern)
{
- Contract.Assert(patterns != null && patterns.Length > 0,
+ Debug.Assert(patterns != null && patterns.Length > 0,
"[DateTimeFormatInfo.GetMergedPatterns]Expected array of at least one pattern");
- Contract.Assert(defaultPattern != null,
+ 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
@@ -1894,9 +1860,9 @@ namespace System.Globalization {
{
if (this.allYearMonthPatterns == null)
{
- Contract.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.UnclonedYearMonthPatterns] Expected Calendar.ID > 0");
+ Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.UnclonedYearMonthPatterns] Expected Calendar.ID > 0");
this.allYearMonthPatterns = this.m_cultureData.YearMonths(this.Calendar.ID);
- Contract.Assert(this.allYearMonthPatterns.Length > 0,
+ Debug.Assert(this.allYearMonthPatterns.Length > 0,
"[DateTimeFormatInfo.UnclonedYearMonthPatterns] Expected some year month patterns");
}
@@ -1913,9 +1879,9 @@ namespace System.Globalization {
{
if (allShortDatePatterns == null)
{
- Contract.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.UnclonedShortDatePatterns] Expected Calendar.ID > 0");
+ Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.UnclonedShortDatePatterns] Expected Calendar.ID > 0");
this.allShortDatePatterns = this.m_cultureData.ShortDates(this.Calendar.ID);
- Contract.Assert(this.allShortDatePatterns.Length > 0,
+ Debug.Assert(this.allShortDatePatterns.Length > 0,
"[DateTimeFormatInfo.UnclonedShortDatePatterns] Expected some short date patterns");
}
@@ -1931,9 +1897,9 @@ namespace System.Globalization {
{
if (allLongDatePatterns == null)
{
- Contract.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.UnclonedLongDatePatterns] Expected Calendar.ID > 0");
+ Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.UnclonedLongDatePatterns] Expected Calendar.ID > 0");
this.allLongDatePatterns = this.m_cultureData.LongDates(this.Calendar.ID);
- Contract.Assert(this.allLongDatePatterns.Length > 0,
+ Debug.Assert(this.allLongDatePatterns.Length > 0,
"[DateTimeFormatInfo.UnclonedLongDatePatterns] Expected some long date patterns");
}
@@ -1950,7 +1916,7 @@ namespace System.Globalization {
if (this.allShortTimePatterns == null)
{
this.allShortTimePatterns = this.m_cultureData.ShortTimes;
- Contract.Assert(this.allShortTimePatterns.Length > 0,
+ Debug.Assert(this.allShortTimePatterns.Length > 0,
"[DateTimeFormatInfo.UnclonedShortTimePatterns] Expected some short time patterns");
}
@@ -1967,7 +1933,7 @@ namespace System.Globalization {
if (this.allLongTimePatterns == null)
{
this.allLongTimePatterns = this.m_cultureData.LongTimes;
- Contract.Assert(this.allLongTimePatterns.Length > 0,
+ Debug.Assert(this.allLongTimePatterns.Length > 0,
"[DateTimeFormatInfo.UnclonedLongTimePatterns] Expected some long time patterns");
}
@@ -1977,7 +1943,7 @@ namespace System.Globalization {
public static DateTimeFormatInfo ReadOnly(DateTimeFormatInfo dtfi) {
if (dtfi == null) {
- throw new ArgumentNullException("dtfi",
+ throw new ArgumentNullException(nameof(dtfi),
Environment.GetResourceString("ArgumentNull_Obj"));
}
Contract.EndContractBlock();
@@ -2038,13 +2004,13 @@ namespace System.Globalization {
if (IsReadOnly)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
if (patterns == null) {
- throw new ArgumentNullException("patterns",
+ throw new ArgumentNullException(nameof(patterns),
Environment.GetResourceString("ArgumentNull_Array"));
}
if (patterns.Length == 0)
{
- throw new ArgumentException(Environment.GetResourceString("Arg_ArrayZeroError"), "patterns");
+ throw new ArgumentException(Environment.GetResourceString("Arg_ArrayZeroError"), nameof(patterns));
}
Contract.EndContractBlock();
@@ -2086,7 +2052,7 @@ namespace System.Globalization {
break;
default:
- throw new ArgumentException(Environment.GetResourceString("Format_BadFormatSpecifier"), "format");
+ throw new ArgumentException(Environment.GetResourceString("Format_BadFormatSpecifier"), nameof(format));
}
// Clear the token hash table, note that even short dates could require this
@@ -2109,12 +2075,12 @@ namespace System.Globalization {
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
if (value == null)
{
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
Environment.GetResourceString("ArgumentNull_Array"));
}
if (value.Length != 13)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidArrayLength", 13), "value");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidArrayLength", 13), nameof(value));
}
Contract.EndContractBlock();
CheckNullValue(value, value.Length - 1);
@@ -2137,12 +2103,12 @@ namespace System.Globalization {
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
if (value == null)
{
- throw new ArgumentNullException("value",
+ throw new ArgumentNullException(nameof(value),
Environment.GetResourceString("ArgumentNull_Array"));
}
if (value.Length != 13)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidArrayLength", 13), "value");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidArrayLength", 13), nameof(value));
}
Contract.EndContractBlock();
CheckNullValue(value, value.Length - 1);
@@ -2396,7 +2362,6 @@ namespace System.Globalization {
formatFlags = DateTimeFormatFlags.NotInitialized;
}
- [System.Security.SecurityCritical] // auto-generated
internal TokenHashValue[] CreateTokenHashTable() {
TokenHashValue[] temp = m_dtfiTokenHash;
if (temp == null) {
@@ -2689,7 +2654,7 @@ namespace System.Globalization {
} 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.
- Contract.Assert(state == HebrewNumberParsingState.ContinueParsing || state == HebrewNumberParsingState.FoundEndOfHebrewNumber,
+ Debug.Assert(state == HebrewNumberParsingState.ContinueParsing || state == HebrewNumberParsingState.FoundEndOfHebrewNumber,
"Invalid returned state from HebrewNumber.ParseByChar()");
if (state != HebrewNumberParsingState.FoundEndOfHebrewNumber) {
@@ -2710,13 +2675,12 @@ namespace System.Globalization {
return (ch >= '\x0590' && ch <= '\x05ff');
}
- [System.Security.SecurityCritical] // auto-generated
internal bool Tokenize(TokenType TokenMask, out TokenType tokenType, out int tokenValue, ref __DTString str) {
tokenType = TokenType.UnknownToken;
tokenValue = 0;
TokenHashValue value;
- Contract.Assert(str.Index < str.Value.Length, "DateTimeFormatInfo.Tokenize(): start < value.Length");
+ Debug.Assert(str.Index < str.Value.Length, "DateTimeFormatInfo.Tokenize(): start < value.Length");
char ch = str.m_current;
bool isLetter = Char.IsLetter(ch);
@@ -2825,7 +2789,7 @@ namespace System.Globalization {
}
previousNode = temp;
} ;
- Contract.Assert(false, "The hashtable is full. This should not happen.");
+ Debug.Assert(false, "The hashtable is full. This should not happen.");
}
void InsertHash(TokenHashValue[] hashTable, String str, TokenType tokenType, int tokenValue) {
@@ -2877,35 +2841,13 @@ namespace System.Globalization {
int nTokenType = (int)tokenType;
int nCurrentTokenTypeInHash = (int)value.tokenType;
- // The idea behind this check is:
- // - if the app is targetting 4.5.1 or above OR the compat flag is set, use the correct behavior by default.
- // - if the app is targetting 4.5 or below AND the compat switch is set, use the correct behavior
- // - if the app is targetting 4.5 or below AND the compat switch is NOT set, use the incorrect behavior
- if (preferExistingTokens || BinaryCompatibility.TargetsAtLeast_Desktop_V4_5_1)
+ if (((nCurrentTokenTypeInHash & (int)TokenType.RegularTokenMask) == 0) && ((nTokenType & (int)TokenType.RegularTokenMask) != 0) ||
+ ((nCurrentTokenTypeInHash & (int)TokenType.SeparatorTokenMask) == 0) && ((nTokenType & (int)TokenType.SeparatorTokenMask) != 0))
{
- 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;
- }
- }
- }
- else
- {
- // The following logic is incorrect and causes updates to happen depending on the bitwise relationship between the existing token type and the
- // the stored token type. It was this way in .NET 4 RTM. The behavior above is correct and will be adopted going forward.
-
- if ((((nTokenType | nCurrentTokenTypeInHash) & (int)TokenType.RegularTokenMask) == nTokenType) ||
- (((nTokenType | nCurrentTokenTypeInHash) & (int)TokenType.SeparatorTokenMask) == nTokenType))
+ value.tokenType |= tokenType;
+ if (tokenValue != 0)
{
- value.tokenType |= tokenType;
- if (tokenValue != 0)
- {
- value.tokenValue = tokenValue;
- }
+ value.tokenValue = tokenValue;
}
}
// The token to be inserted is already in the table. Skip it.
@@ -2918,7 +2860,7 @@ namespace System.Globalization {
hashcode += hashProbe;
if (hashcode >= TOKEN_HASH_SIZE) hashcode -= TOKEN_HASH_SIZE;
} while (i < TOKEN_HASH_SIZE);
- Contract.Assert(false, "The hashtable is full. This should not happen.");
+ Debug.Assert(false, "The hashtable is full. This should not happen.");
}
} // class DateTimeFormatInfo
diff --git a/src/mscorlib/src/System/Globalization/DateTimeFormatInfoScanner.cs b/src/mscorlib/src/System/Globalization/DateTimeFormatInfoScanner.cs
index 40cbabc096..4555bb2463 100644
--- a/src/mscorlib/src/System/Globalization/DateTimeFormatInfoScanner.cs
+++ b/src/mscorlib/src/System/Globalization/DateTimeFormatInfoScanner.cs
@@ -498,9 +498,6 @@ namespace System.Globalization
//
////////////////////////////////////////////////////////////////////////////
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
internal String[] GetDateWordsOfDTFI(DateTimeFormatInfo dtfi) {
// Enumarate all LongDatePatterns, and get the DateWords and scan for month postfix.
String[] datePatterns = dtfi.GetAllDateTimePatterns('D');
diff --git a/src/mscorlib/src/System/Globalization/DateTimeParse.cs b/src/mscorlib/src/System/Globalization/DateTimeParse.cs
index 8de3242f30..363747cfc3 100644
--- a/src/mscorlib/src/System/Globalization/DateTimeParse.cs
+++ b/src/mscorlib/src/System/Globalization/DateTimeParse.cs
@@ -35,16 +35,6 @@ namespace System {
internal static MatchNumberDelegate m_hebrewNumberParser = new MatchNumberDelegate(DateTimeParse.MatchHebrewDigits);
-#if !FEATURE_CORECLR
- [SecuritySafeCritical]
- internal static bool GetAmPmParseFlag()
- {
- return DateTime.EnableAmPmParseAdjustment();
- }
-
- internal static bool enableAmPmParseAdjustment = GetAmPmParseFlag();
-#endif
-
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();
@@ -97,11 +87,11 @@ namespace System {
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, "s");
+ result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(s));
return false;
}
if (format == null) {
- result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, "format");
+ result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(format));
return false;
}
if (s.Length == 0) {
@@ -114,7 +104,7 @@ namespace System {
return false;
}
- Contract.Assert(dtfi != null, "dtfi == null");
+ Debug.Assert(dtfi != null, "dtfi == null");
return DoStrictParse(s, format, style, dtfi, ref result);
}
@@ -178,11 +168,11 @@ namespace System {
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, "s");
+ result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(s));
return false;
}
if (formats == null) {
- result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, "formats");
+ result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(formats));
return false;
}
@@ -196,7 +186,7 @@ namespace System {
return false;
}
- Contract.Assert(dtfi != null, "dtfi == null");
+ Debug.Assert(dtfi != null, "dtfi == null");
//
// Do a loop through the provided formats and see if we can parse succesfully in
@@ -546,8 +536,8 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR,
// Wrong number of digits
return false;
}
- Contract.Assert(hourOffset >= 0 && hourOffset <= 99, "hourOffset >= 0 && hourOffset <= 99");
- Contract.Assert(minuteOffset >= 0 && minuteOffset <= 99, "minuteOffset >= 0 && minuteOffset <= 99");
+ 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;
}
@@ -591,7 +581,6 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR,
// 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.
//
- [System.Security.SecuritySafeCritical] // auto-generated
private static Boolean Lex(DS dps, ref __DTString str, ref DateTimeToken dtok, ref DateTimeRawInfo raw, ref DateTimeResult result, ref DateTimeFormatInfo dtfi, DateTimeStyles styles)
{
@@ -761,11 +750,7 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR,
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 !FEATURE_CORECLR
- && enableAmPmParseAdjustment
-#endif
- )
+ if (dps == DS.D_NN)
{
if (!ProcessTerminaltState(DS.DX_NN, ref result, ref styles, ref raw, dtfi))
{
@@ -1076,16 +1061,6 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR,
return (false);
}
-#if !FEATURE_CORECLR
- // If DateTimeParseIgnorePunctuation is defined, we want to have the V1.1 behavior of just
- // ignoring any unrecognized punctuation and moving on to the next character
- if (Environment.GetCompatibilityFlag(CompatibilityFlag.DateTimeParseIgnorePunctuation) && ((result.flags & ParseFlags.CaptureOffset) == 0)) {
- str.GetNext();
- LexTraceExit("0210 (success)", dps);
- return true;
- }
-#endif // FEATURE_CORECLR
-
if ((str.m_current == '-' || str.m_current == '+') && ((result.flags & ParseFlags.TimeZoneUsed) == 0)) {
Int32 originalIndex = str.Index;
if (ParseTimeZone(ref str, ref result.timeZoneOffset)) {
@@ -1096,7 +1071,7 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR,
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:
@@ -1104,7 +1079,7 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR,
//
if (VerifyValidPunctuation(ref str)) {
LexTraceExit("0230 (success)", dps);
- return true;
+ return true;
}
result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
@@ -1936,7 +1911,7 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR,
private static Boolean GetTimeOfNN(DateTimeFormatInfo dtfi, ref DateTimeResult result, ref DateTimeRawInfo raw)
{
- Contract.Assert(raw.numCount >= 2, "raw.numCount >= 2");
+ 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);
@@ -1956,7 +1931,7 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR,
result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
return false;
}
- Contract.Assert(raw.numCount >= 3, "raw.numCount >= 3");
+ Debug.Assert(raw.numCount >= 3, "raw.numCount >= 3");
result.Hour = raw.GetNumber(0);
result.Minute = raw.GetNumber(1);
result.Second = raw.GetNumber(2);
@@ -2316,10 +2291,9 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR,
//
// This is the real method to do the parsing work.
//
- [System.Security.SecuritySafeCritical] // auto-generated
internal static bool TryParse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles, ref DateTimeResult result) {
if (s == null) {
- result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, "s");
+ result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(s));
return false;
}
if (s.Length == 0) {
@@ -2327,7 +2301,7 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR,
return false;
}
- Contract.Assert(dtfi != null, "dtfi == null");
+ Debug.Assert(dtfi != null, "dtfi == null");
#if _LOGGING
DTFITrace(dtfi);
@@ -2548,17 +2522,15 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR,
// no adjustment is required in most cases
return DateTimeOffsetTimeZonePostProcessing(ref result, styles);
}
-#if FEATURE_CORECLR // on CoreCLR DateTime is also restricted to +- 14:00, just like DateTimeOffset
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;
}
}
-#endif // FEATURE_CORECLR
// The flags AssumeUniveral and AssumeLocal only apply when the input does not have a time zone
if ((result.flags & ParseFlags.TimeZoneUsed) == 0) {
@@ -2592,7 +2564,7 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR,
}
else {
// No time zone and no Assume flags, so DateTimeKind.Unspecified is fine
- Contract.Assert(result.parsedDate.Kind == DateTimeKind.Unspecified, "result.parsedDate.Kind == DateTimeKind.Unspecified");
+ Debug.Assert(result.parsedDate.Kind == DateTimeKind.Unspecified, "result.parsedDate.Kind == DateTimeKind.Unspecified");
return true;
}
}
@@ -2882,9 +2854,9 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR,
}
internal static bool ParseDigits(ref __DTString str, int minDigitLen, int maxDigitLen, out int result) {
- Contract.Assert(minDigitLen > 0, "minDigitLen > 0");
- Contract.Assert(maxDigitLen < 9, "maxDigitLen < 9");
- Contract.Assert(minDigitLen <= maxDigitLen, "minDigitLen <= maxDigitLen");
+ 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;
@@ -4151,7 +4123,7 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR,
case ParseFailureKind.FormatBadDateTimeCalendar:
return new FormatException(Environment.GetResourceString(result.failureMessageID, result.calendar));
default:
- Contract.Assert(false, "Unkown DateTimeParseFailure: " + result);
+ Debug.Assert(false, "Unkown DateTimeParseFailure: " + result);
return null;
}
@@ -4373,7 +4345,7 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR,
}
internal bool Advance(int count) {
- Contract.Assert(Index + count <= len, "__DTString::Advance: Index + count <= len");
+ Debug.Assert(Index + count <= len, "__DTString::Advance: Index + count <= len");
Index += count;
if (Index < len) {
m_current = Value[Index];
@@ -4384,7 +4356,6 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR,
// Used by DateTime.Parse() to get the next token.
- [System.Security.SecurityCritical] // auto-generated
internal void GetRegularToken(out TokenType tokenType, out int tokenValue, DateTimeFormatInfo dtfi) {
tokenValue = 0;
if (Index >= len) {
@@ -4464,7 +4435,6 @@ Start:
}
}
- [System.Security.SecurityCritical] // auto-generated
internal TokenType GetSeparatorToken(DateTimeFormatInfo dtfi, out int indexBeforeSeparator, out char charBeforeSeparator) {
indexBeforeSeparator = Index;
charBeforeSeparator = m_current;
@@ -4668,7 +4638,7 @@ Start:
// Get the current character.
//
internal char GetChar() {
- Contract.Assert(Index >= 0 && Index < len, "Index >= 0 && Index < len");
+ Debug.Assert(Index >= 0 && Index < len, "Index >= 0 && Index < len");
return (Value[Index]);
}
@@ -4676,8 +4646,8 @@ Start:
// Convert the current character to a digit, and return it.
//
internal int GetDigit() {
- Contract.Assert(Index >= 0 && Index < len, "Index >= 0 && Index < len");
- Contract.Assert(DateTimeParse.IsDigit(Value[Index]), "IsDigit(Value[Index])");
+ Debug.Assert(Index >= 0 && Index < len, "Index >= 0 && Index < len");
+ Debug.Assert(DateTimeParse.IsDigit(Value[Index]), "IsDigit(Value[Index])");
return (Value[Index] - '0');
}
@@ -4810,7 +4780,7 @@ Start:
return sub;
}
int number = ch - '0';
- Contract.Assert(number >= 0 && number <= 9, "number >= 0 && number <= 9");
+ Debug.Assert(number >= 0 && number <= 9, "number >= 0 && number <= 9");
sub.value = sub.value * 10 + number;
}
else {
@@ -4829,8 +4799,8 @@ Start:
}
internal void ConsumeSubString(DTSubString sub) {
- Contract.Assert(sub.index == Index, "sub.index == Index");
- Contract.Assert(sub.index + sub.length <= len, "sub.index + sub.length <= len");
+ 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];
@@ -4875,7 +4845,6 @@ Start:
//
internal
unsafe struct DateTimeRawInfo {
- [SecurityCritical]
private int* num;
internal int numCount;
internal int month;
@@ -4889,7 +4858,6 @@ Start:
internal bool timeZone;
- [System.Security.SecurityCritical] // auto-generated
internal void Init(int * numberBuffer) {
month = -1;
year = -1;
@@ -4899,11 +4867,9 @@ Start:
fraction = -1;
num = numberBuffer;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe void AddNumber(int value) {
num[numCount++] = value;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe int GetNumber(int index) {
return num[index];
}
diff --git a/src/mscorlib/src/System/Globalization/DaylightTime.cs b/src/mscorlib/src/System/Globalization/DaylightTime.cs
index 037d9ffdf3..a164867576 100644
--- a/src/mscorlib/src/System/Globalization/DaylightTime.cs
+++ b/src/mscorlib/src/System/Globalization/DaylightTime.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;
+using System.Runtime.InteropServices;
+
+namespace System.Globalization
+{
// This class represents a starting/ending time for a period of daylight saving time.
[Serializable]
- [System.Runtime.InteropServices.ComVisible(true)]
+ [ComVisible(true)]
public class DaylightTime
{
internal DateTime m_start;
@@ -46,4 +47,18 @@ namespace System.Globalization {
}
+ // 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/EastAsianLunisolarCalendar.cs b/src/mscorlib/src/System/Globalization/EastAsianLunisolarCalendar.cs
index 2460eee3af..3c9391fa63 100644
--- a/src/mscorlib/src/System/Globalization/EastAsianLunisolarCalendar.cs
+++ b/src/mscorlib/src/System/Globalization/EastAsianLunisolarCalendar.cs
@@ -65,7 +65,7 @@ namespace System.Globalization {
public int GetCelestialStem(int sexagenaryYear) {
if ((sexagenaryYear < 1) || (sexagenaryYear > 60)) {
throw new ArgumentOutOfRangeException(
- "sexagenaryYear",
+ nameof(sexagenaryYear),
Environment.GetResourceString("ArgumentOutOfRange_Range", 1, 60));
}
Contract.EndContractBlock();
@@ -80,7 +80,7 @@ namespace System.Globalization {
public int GetTerrestrialBranch(int sexagenaryYear) {
if ((sexagenaryYear < 1) || (sexagenaryYear > 60)) {
throw new ArgumentOutOfRangeException(
- "sexagenaryYear",
+ nameof(sexagenaryYear),
Environment.GetResourceString("ArgumentOutOfRange_Range", 1, 60));
}
Contract.EndContractBlock();
@@ -121,7 +121,7 @@ namespace System.Globalization {
return (mEraInfo[i].minEraYear);
}
}
- throw new ArgumentOutOfRangeException("era", Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
}
internal int MaxEraCalendarYear (int era) {
@@ -144,7 +144,7 @@ namespace System.Globalization {
return (mEraInfo[i].maxEraYear);
}
}
- throw new ArgumentOutOfRangeException("era", Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
}
// Construct an instance of EastAsianLunisolar calendar.
@@ -168,7 +168,7 @@ namespace System.Globalization {
}
if ((era <GetEra(MinDate)) || (era > GetEra(MaxDate))) {
- throw new ArgumentOutOfRangeException("era", Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
}
}
@@ -178,7 +178,7 @@ namespace System.Globalization {
if ((year < MinCalendarYear) || (year > MaxCalendarYear)) {
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
Environment.GetResourceString("ArgumentOutOfRange_Range", MinEraCalendarYear(era), MaxEraCalendarYear(era)));
}
return year;
@@ -191,11 +191,11 @@ namespace System.Globalization {
{
//Reject if there is no leap month this year
if (GetYearInfo(year , LeapMonth) == 0)
- throw new ArgumentOutOfRangeException("month", Environment.GetResourceString("ArgumentOutOfRange_Month"));
+ throw new ArgumentOutOfRangeException(nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Month"));
}
if (month < 1 || month > 13) {
- throw new ArgumentOutOfRangeException("month", Environment.GetResourceString("ArgumentOutOfRange_Month"));
+ throw new ArgumentOutOfRangeException(nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Month"));
}
return year;
}
@@ -236,7 +236,7 @@ namespace System.Globalization {
if (day < 1 || day > daysInMonth) {
BCLDebug.Log("year = " + year + ", month = " + month + ", day = " + day);
throw new ArgumentOutOfRangeException(
- "day",
+ nameof(day),
Environment.GetResourceString("ArgumentOutOfRange_Day", daysInMonth, month));
}
@@ -399,7 +399,7 @@ namespace System.Globalization {
public override DateTime AddMonths(DateTime time, int months) {
if (months < -120000 || months > 120000) {
throw new ArgumentOutOfRangeException(
- "months",
+ nameof(months),
Environment.GetResourceString("ArgumentOutOfRange_Range", -120000, 120000));
}
Contract.EndContractBlock();
@@ -561,7 +561,7 @@ namespace System.Globalization {
if (day < 1 || day > daysInMonth) {
throw new ArgumentOutOfRangeException(
- "day",
+ nameof(day),
Environment.GetResourceString("ArgumentOutOfRange_Day", daysInMonth, month));
}
int m = GetYearInfo(year, LeapMonth);
@@ -620,7 +620,7 @@ namespace System.Globalization {
if (value < 99 || value > MaxCalendarYear)
{
throw new ArgumentOutOfRangeException(
- "value",
+ nameof(value),
Environment.GetResourceString("ArgumentOutOfRange_Range", 99, MaxCalendarYear));
}
twoDigitYearMax = value;
@@ -630,7 +630,7 @@ namespace System.Globalization {
public override int ToFourDigitYear(int year) {
if (year < 0) {
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
Contract.EndContractBlock();
diff --git a/src/mscorlib/src/System/Globalization/EncodingDataItem.cs b/src/mscorlib/src/System/Globalization/EncodingDataItem.cs
index 1dc1bd2eaf..89ac780587 100644
--- a/src/mscorlib/src/System/Globalization/EncodingDataItem.cs
+++ b/src/mscorlib/src/System/Globalization/EncodingDataItem.cs
@@ -27,14 +27,12 @@ namespace System.Globalization {
internal String m_bodyName;
internal uint m_flags;
- [SecurityCritical]
unsafe internal CodePageDataItem(int dataIndex) {
m_dataIndex = dataIndex;
m_uiFamilyCodePage = EncodingTable.codePageDataPtr[dataIndex].uiFamilyCodePage;
m_flags = EncodingTable.codePageDataPtr[dataIndex].flags;
}
- [System.Security.SecurityCritical]
unsafe internal static String CreateString(sbyte* pStrings, uint index)
{
if (pStrings[0] == '|') // |str1|str2|str3
@@ -62,7 +60,7 @@ namespace System.Globalization {
}
}
- throw new ArgumentException("pStrings");
+ throw new ArgumentException(null, nameof(pStrings));
}
else
{
@@ -71,7 +69,6 @@ namespace System.Globalization {
}
unsafe public String WebName {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
if (m_webName==null) {
m_webName = CreateString(EncodingTable.codePageDataPtr[m_dataIndex].Names, 0);
@@ -87,7 +84,6 @@ namespace System.Globalization {
}
unsafe public String HeaderName {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
if (m_headerName==null) {
m_headerName = CreateString(EncodingTable.codePageDataPtr[m_dataIndex].Names, 1);
@@ -97,7 +93,6 @@ namespace System.Globalization {
}
unsafe public String BodyName {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
if (m_bodyName==null) {
m_bodyName = CreateString(EncodingTable.codePageDataPtr[m_dataIndex].Names, 2);
diff --git a/src/mscorlib/src/System/Globalization/EncodingTable.Unix.cs b/src/mscorlib/src/System/Globalization/EncodingTable.Unix.cs
index 5628a2def9..0fce2e58fc 100644
--- a/src/mscorlib/src/System/Globalization/EncodingTable.Unix.cs
+++ b/src/mscorlib/src/System/Globalization/EncodingTable.Unix.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.Diagnostics.Contracts;
using System.Text;
@@ -30,7 +31,7 @@ namespace System.Globalization
{
if (name == null)
{
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
}
Contract.EndContractBlock();
@@ -44,7 +45,7 @@ namespace System.Globalization
throw new ArgumentException(
string.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("Argument_EncodingNotSupported"), name), "name");
+ Environment.GetResourceString("Argument_EncodingNotSupported"), name), nameof(name));
}
internal static CodePageDataItem GetCodePageDataItem(int codepage)
@@ -82,7 +83,7 @@ namespace System.Globalization
break;
}
- Contract.Assert(item == null || item.CodePage == codepage, "item.CodePage needs to equal the specified codepage");
+ Debug.Assert(item == null || item.CodePage == codepage, "item.CodePage needs to equal the specified codepage");
return item;
}
@@ -91,7 +92,7 @@ namespace System.Globalization
#if DEBUG
static EncodingTable()
{
- Contract.Assert(
+ Debug.Assert(
s_encodingDataTable.Count == EncodingTableCapacity,
string.Format(CultureInfo.InvariantCulture,
"EncodingTable s_encodingDataTable's initial capacity (EncodingTableCapacity) is incorrect.{0}Expected (s_encodingDataTable.Count): {1}, Actual (EncodingTableCapacity): {2}",
diff --git a/src/mscorlib/src/System/Globalization/EncodingTable.cs b/src/mscorlib/src/System/Globalization/EncodingTable.cs
index cdda9eaf6d..d908a2ac2b 100644
--- a/src/mscorlib/src/System/Globalization/EncodingTable.cs
+++ b/src/mscorlib/src/System/Globalization/EncodingTable.cs
@@ -34,13 +34,11 @@ namespace System.Globalization
//
// This points to a native data table which maps an encoding name to the correct code page.
//
- [SecurityCritical]
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.
//
- [SecurityCritical]
unsafe internal static InternalCodePageDataItem *codePageDataPtr = GetCodePageData();
//
// This caches the mapping of an encoding name to a code page.
@@ -51,14 +49,12 @@ namespace System.Globalization
//
private static Hashtable hashByCodePage = Hashtable.Synchronized(new Hashtable());
- [System.Security.SecuritySafeCritical] // static constructors should be safe to call
static EncodingTable()
{
}
// Find the data item by binary searching the table that we have in native.
// nativeCompareOrdinalWC is an internal-only function.
- [System.Security.SecuritySafeCritical] // auto-generated
unsafe private static int internalGetCodePageFromName(String name) {
int left = 0;
int right = lastEncodingItem;
@@ -94,11 +90,10 @@ namespace System.Globalization
throw new ArgumentException(
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("Argument_EncodingNotSupported"), name), "name");
+ Environment.GetResourceString("Argument_EncodingNotSupported"), name), nameof(name));
}
// Return a list of all EncodingInfo objects describing all of our encodings
- [System.Security.SecuritySafeCritical] // auto-generated
internal static unsafe EncodingInfo[] GetEncodings()
{
if (lastCodePageItem == 0)
@@ -136,7 +131,7 @@ namespace System.Globalization
internal static int GetCodePageFromName(String name)
{
if (name==null) {
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
}
Contract.EndContractBlock();
@@ -161,7 +156,6 @@ namespace System.Globalization
return codePage;
}
- [System.Security.SecuritySafeCritical] // auto-generated
unsafe internal static CodePageDataItem GetCodePageDataItem(int codepage) {
CodePageDataItem dataItem;
@@ -198,22 +192,18 @@ namespace System.Globalization
return null;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private unsafe static extern InternalEncodingDataItem *GetEncodingData();
//
// Return the number of encoding data items.
//
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern int GetNumEncodingItems();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private unsafe static extern InternalCodePageDataItem* GetCodePageData();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal unsafe static extern byte* nativeCreateOpenFileMapping(
String inSectionName, int inBytesToAllocate, out IntPtr mappedFileHandle);
@@ -228,7 +218,6 @@ namespace System.Globalization
[System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
internal unsafe struct InternalEncodingDataItem {
- [SecurityCritical]
internal sbyte * webName;
internal UInt16 codePage;
}
@@ -243,7 +232,6 @@ namespace System.Globalization
internal UInt16 codePage;
internal UInt16 uiFamilyCodePage;
internal uint flags;
- [SecurityCritical]
internal sbyte * Names;
}
diff --git a/src/mscorlib/src/System/Globalization/GlobalizationAssembly.cs b/src/mscorlib/src/System/Globalization/GlobalizationAssembly.cs
index 4de3fd399b..0810d67b59 100644
--- a/src/mscorlib/src/System/Globalization/GlobalizationAssembly.cs
+++ b/src/mscorlib/src/System/Globalization/GlobalizationAssembly.cs
@@ -15,6 +15,7 @@ namespace System.Globalization {
using System.Runtime.ConstrainedExecution;
using System.Runtime.Versioning;
using System.IO;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
@@ -32,10 +33,9 @@ namespace System.Globalization {
// Instance data members and instance methods.
//
// ----------------------------------------------------------------------------------------------------
- [System.Security.SecurityCritical] // auto-generated
internal unsafe static byte* GetGlobalizationResourceBytePtr(Assembly assembly, String tableName) {
- Contract.Assert(assembly != null, "assembly can not be null. This should be generally the "+System.CoreLib.Name+" assembly.");
- Contract.Assert(tableName != null, "table name can not be null");
+ 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;
@@ -46,7 +46,7 @@ namespace System.Globalization {
}
}
- Contract.Assert(
+ Debug.Assert(
false,
String.Format(
CultureInfo.CurrentCulture,
diff --git a/src/mscorlib/src/System/Globalization/GregorianCalendar.cs b/src/mscorlib/src/System/Globalization/GregorianCalendar.cs
index e540adda9f..6cf9b2eb85 100644
--- a/src/mscorlib/src/System/Globalization/GregorianCalendar.cs
+++ b/src/mscorlib/src/System/Globalization/GregorianCalendar.cs
@@ -132,7 +132,7 @@ namespace System.Globalization {
public GregorianCalendar(GregorianCalendarTypes type) {
if ((int)type < (int)GregorianCalendarTypes.Localized || (int)type > (int)GregorianCalendarTypes.TransliteratedFrench) {
throw new ArgumentOutOfRangeException(
- "type",
+ nameof(type),
Environment.GetResourceString("ArgumentOutOfRange_Range",
GregorianCalendarTypes.Localized, GregorianCalendarTypes.TransliteratedFrench));
}
@@ -159,7 +159,7 @@ namespace System.Globalization {
break;
default:
- throw new ArgumentOutOfRangeException("m_type", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(m_type), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
}
}
}
@@ -217,7 +217,7 @@ namespace System.Globalization {
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;
+ int m = (n >> 5) + 1;
// m = 1-based month number
while (n >= days[m]) m++;
// If month was requested, return it
@@ -285,7 +285,7 @@ namespace System.Globalization {
{
if (months < -120000 || months > 120000) {
throw new ArgumentOutOfRangeException(
- "months",
+ nameof(months),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -371,16 +371,16 @@ namespace System.Globalization {
public override int GetDaysInMonth(int year, int month, int era) {
if (era == CurrentEra || era == ADEra) {
if (year < 1 || year > MaxYear) {
- throw new ArgumentOutOfRangeException("year", Environment.GetResourceString("ArgumentOutOfRange_Range",
+ throw new ArgumentOutOfRangeException(nameof(year), Environment.GetResourceString("ArgumentOutOfRange_Range",
1, MaxYear));
}
if (month < 1 || month > 12) {
- throw new ArgumentOutOfRangeException("month", Environment.GetResourceString("ArgumentOutOfRange_Month"));
+ throw new ArgumentOutOfRangeException(nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Month"));
}
int[] days = ((year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? DaysToMonth366: DaysToMonth365);
return (days[month] - days[month - 1]);
}
- throw new ArgumentOutOfRangeException("era", Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
}
// Returns the number of days in the year given by the year argument for the current era.
@@ -393,14 +393,14 @@ namespace System.Globalization {
return ((year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? 366:365);
}
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
1,
MaxYear));
}
- throw new ArgumentOutOfRangeException("era", Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
}
// Returns the era for the specified DateTime value.
@@ -437,14 +437,14 @@ namespace System.Globalization {
return (12);
}
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
1,
MaxYear));
}
- throw new ArgumentOutOfRangeException("era", Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
}
// Returns the year part of the specified DateTime. The returned value is an
@@ -463,23 +463,23 @@ namespace System.Globalization {
public override bool IsLeapDay(int year, int month, int day, int era)
{
if (month < 1 || month > 12) {
- throw new ArgumentOutOfRangeException("month", Environment.GetResourceString("ArgumentOutOfRange_Range",
+ throw new ArgumentOutOfRangeException(nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Range",
1, 12));
}
Contract.EndContractBlock();
if (era != CurrentEra && era != ADEra)
{
- throw new ArgumentOutOfRangeException("era", Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
}
if (year < 1 || year > MaxYear) {
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
Environment.GetResourceString("ArgumentOutOfRange_Range", 1, MaxYear));
}
if (day < 1 || day > GetDaysInMonth(year, month)) {
- throw new ArgumentOutOfRangeException("day", Environment.GetResourceString("ArgumentOutOfRange_Range",
+ throw new ArgumentOutOfRangeException(nameof(day), Environment.GetResourceString("ArgumentOutOfRange_Range",
1, GetDaysInMonth(year, month)));
}
if (!IsLeapYear(year)) {
@@ -500,11 +500,11 @@ namespace System.Globalization {
{
if (era != CurrentEra && era != ADEra)
{
- throw new ArgumentOutOfRangeException("era", Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
}
if (year < 1 || year > MaxYear) {
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"), 1, MaxYear));
@@ -520,19 +520,19 @@ namespace System.Globalization {
public override bool IsLeapMonth(int year, int month, int era)
{
if (era != CurrentEra && era != ADEra) {
- throw new ArgumentOutOfRangeException("era", Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
}
if (year < 1 || year > MaxYear) {
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"), 1, MaxYear));
}
if (month < 1 || month > 12) {
- throw new ArgumentOutOfRangeException("month", Environment.GetResourceString("ArgumentOutOfRange_Range",
+ throw new ArgumentOutOfRangeException(nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Range",
1, 12));
}
Contract.EndContractBlock();
@@ -551,12 +551,12 @@ namespace System.Globalization {
}
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"), 1, MaxYear));
}
- throw new ArgumentOutOfRangeException("era", Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
}
// Returns the date and time converted to a DateTime value. Throws an exception if the n-tuple is invalid.
@@ -567,7 +567,7 @@ namespace System.Globalization {
if (era == CurrentEra || era == ADEra) {
return new DateTime(year, month, day, hour, minute, second, millisecond);
}
- throw new ArgumentOutOfRangeException("era", Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("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) {
@@ -609,14 +609,14 @@ namespace System.Globalization {
public override int ToFourDigitYear(int year) {
if (year < 0) {
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
Contract.EndContractBlock();
if (year > MaxYear) {
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"), 1, MaxYear));
diff --git a/src/mscorlib/src/System/Globalization/GregorianCalendarHelper.cs b/src/mscorlib/src/System/Globalization/GregorianCalendarHelper.cs
index 75b280d457..062ae4818a 100644
--- a/src/mscorlib/src/System/Globalization/GregorianCalendarHelper.cs
+++ b/src/mscorlib/src/System/Globalization/GregorianCalendarHelper.cs
@@ -153,7 +153,7 @@ namespace System.Globalization {
internal int GetGregorianYear(int year, int era) {
if (year < 0) {
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
Contract.EndContractBlock();
@@ -166,7 +166,7 @@ namespace System.Globalization {
if (era == m_EraInfo[i].era) {
if (year < m_EraInfo[i].minEraYear || year > m_EraInfo[i].maxEraYear) {
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -176,7 +176,7 @@ namespace System.Globalization {
return (m_EraInfo[i].yearOffset + year);
}
}
- throw new ArgumentOutOfRangeException("era", Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
}
internal bool IsValidYear(int year, int era) {
@@ -243,7 +243,7 @@ namespace System.Globalization {
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;
+ int m = (n >> 5) + 1;
// m = 1-based month number
while (n >= days[m]) m++;
// If month was requested, return it
@@ -299,7 +299,7 @@ namespace System.Globalization {
{
if (millisecond < 0 || millisecond >= MillisPerSecond) {
throw new ArgumentOutOfRangeException(
- "millisecond",
+ nameof(millisecond),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -346,7 +346,7 @@ namespace System.Globalization {
{
if (months < -120000 || months > 120000) {
throw new ArgumentOutOfRangeException(
- "months",
+ nameof(months),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -432,7 +432,7 @@ namespace System.Globalization {
//
year = GetGregorianYear(year, era);
if (month < 1 || month > 12) {
- throw new ArgumentOutOfRangeException("month", Environment.GetResourceString("ArgumentOutOfRange_Month"));
+ throw new ArgumentOutOfRangeException(nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Month"));
}
int[] days = ((year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? DaysToMonth366: DaysToMonth365);
return (days[month] - days[month - 1]);
@@ -460,7 +460,7 @@ namespace System.Globalization {
return (m_EraInfo[i].era);
}
}
- throw new ArgumentOutOfRangeException("time", Environment.GetResourceString("ArgumentOutOfRange_Era"));
+ throw new ArgumentOutOfRangeException(nameof(time), Environment.GetResourceString("ArgumentOutOfRange_Era"));
}
@@ -533,7 +533,7 @@ namespace System.Globalization {
// year/month/era checking is done in GetDaysInMonth()
if (day < 1 || day > GetDaysInMonth(year, month, era)) {
throw new ArgumentOutOfRangeException(
- "day",
+ nameof(day),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -570,7 +570,7 @@ namespace System.Globalization {
year = GetGregorianYear(year, era);
if (month < 1 || month > 12) {
throw new ArgumentOutOfRangeException(
- "month",
+ nameof(month),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -607,7 +607,7 @@ namespace System.Globalization {
public int ToFourDigitYear(int year, int twoDigitYearMax) {
if (year < 0) {
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
}
Contract.EndContractBlock();
@@ -619,7 +619,7 @@ namespace System.Globalization {
if (year < m_minYear || year > m_maxYear) {
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"), m_minYear, m_maxYear));
diff --git a/src/mscorlib/src/System/Globalization/HebrewCalendar.cs b/src/mscorlib/src/System/Globalization/HebrewCalendar.cs
index 3a17494001..44cbdb8bde 100644
--- a/src/mscorlib/src/System/Globalization/HebrewCalendar.cs
+++ b/src/mscorlib/src/System/Globalization/HebrewCalendar.cs
@@ -5,6 +5,7 @@
namespace System.Globalization {
using System;
using System.Text;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
////////////////////////////////////////////////////////////////////////////
@@ -397,7 +398,7 @@ namespace System.Globalization {
int monthsInYear = GetMonthsInYear(year, era);
if (month < 1 || month > monthsInYear) {
throw new ArgumentOutOfRangeException(
- "month",
+ nameof(month),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -421,7 +422,7 @@ namespace System.Globalization {
int daysInMonth = GetDaysInMonth(year, month, era);
if (day < 1 || day > daysInMonth) {
throw new ArgumentOutOfRangeException(
- "day",
+ nameof(day),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -432,7 +433,7 @@ namespace System.Globalization {
static internal void CheckEraRange(int era) {
if (era != CurrentEra && era != HebrewEra) {
- throw new ArgumentOutOfRangeException("era", Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
}
}
@@ -486,7 +487,7 @@ namespace System.Globalization {
//
int index = gregorianYear - FirstGregorianTableYear;
if (index < 0 || index > TABLESIZE) {
- throw new ArgumentOutOfRangeException("gregorianYear");
+ throw new ArgumentOutOfRangeException(nameof(gregorianYear));
}
index *= 2;
@@ -607,7 +608,7 @@ namespace System.Globalization {
// is true.
//
NumDays -= (long)(LunarMonthLen[hebrewYearType, lunarDate.month] - lunarDate.day);
- Contract.Assert(NumDays >= 1, "NumDays >= 1");
+ Debug.Assert(NumDays >= 1, "NumDays >= 1");
// If NumDays is 1, then we are done. Otherwise, find the correct Hebrew month
// and day.
@@ -705,7 +706,7 @@ namespace System.Globalization {
catch (ArgumentException)
{
throw new ArgumentOutOfRangeException(
- "months",
+ nameof(months),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_AddValue")));
@@ -727,7 +728,7 @@ namespace System.Globalization {
int d = GetDatePart(time.Ticks, DatePartDay);
y += years;
- CheckHebrewYearValue(y, Calendar.CurrentEra, "years");
+ CheckHebrewYearValue(y, Calendar.CurrentEra, nameof(years));
int months = GetMonthsInYear(y, CurrentEra);
if (m > months) {
@@ -765,7 +766,7 @@ namespace System.Globalization {
}
static internal int GetHebrewYearType(int year, int era) {
- CheckHebrewYearValue(year, era, "year");
+ 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]);
@@ -811,11 +812,11 @@ namespace System.Globalization {
int hebrewYearType = GetHebrewYearType(year, era);
CheckHebrewMonthValue(year, month, era);
- Contract.Assert(hebrewYearType>= 1 && hebrewYearType <= 6,
+ 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("month", Environment.GetResourceString("ArgumentOutOfRange_Month"));
+ throw new ArgumentOutOfRangeException(nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Month"));
}
return (monthDays);
}
@@ -931,7 +932,7 @@ namespace System.Globalization {
//
public override bool IsLeapYear(int year, int era) {
- CheckHebrewYearValue(year, era, "year");
+ CheckHebrewYearValue(year, era, nameof(year));
return (((7 * (long)year + 1) % 19) < 7);
}
@@ -1015,7 +1016,7 @@ namespace System.Globalization {
//
public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era) {
- CheckHebrewYearValue(year, era, "year");
+ CheckHebrewYearValue(year, era, nameof(year));
CheckHebrewMonthValue(year, month, era);
CheckHebrewDayValue(year, month, day, era);
DateTime dt = HebrewToGregorian(year, month, day, hour, minute, second, millisecond);
@@ -1042,7 +1043,7 @@ namespace System.Globalization {
}
else
{
- CheckHebrewYearValue(value, HebrewEra, "value");
+ CheckHebrewYearValue(value, HebrewEra, nameof(value));
}
twoDigitYearMax = value;
}
@@ -1051,7 +1052,7 @@ namespace System.Globalization {
public override int ToFourDigitYear(int year) {
if (year < 0) {
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
Contract.EndContractBlock();
@@ -1062,7 +1063,7 @@ namespace System.Globalization {
if (year > MaxHebrewYear || year < MinHebrewYear) {
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
diff --git a/src/mscorlib/src/System/Globalization/HebrewNumber.cs b/src/mscorlib/src/System/Globalization/HebrewNumber.cs
index cf0595585a..5517cb14ea 100644
--- a/src/mscorlib/src/System/Globalization/HebrewNumber.cs
+++ b/src/mscorlib/src/System/Globalization/HebrewNumber.cs
@@ -6,6 +6,7 @@
namespace System.Globalization {
using System;
using System.Text;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
////////////////////////////////////////////////////////////////////////////
@@ -98,7 +99,7 @@ namespace System.Globalization {
Number -= 5000;
}
- Contract.Assert(Number > 0 && Number <= 999, "Number is out of range.");;
+ Debug.Assert(Number > 0 && Number <= 999, "Number is out of range.");;
//
// Get the Hundreds.
diff --git a/src/mscorlib/src/System/Globalization/HijriCalendar.cs b/src/mscorlib/src/System/Globalization/HijriCalendar.cs
index 194d329d25..39a01e5774 100644
--- a/src/mscorlib/src/System/Globalization/HijriCalendar.cs
+++ b/src/mscorlib/src/System/Globalization/HijriCalendar.cs
@@ -209,7 +209,6 @@ namespace System.Globalization {
public int HijriAdjustment {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
if (m_HijriAdvance == Int32.MinValue) {
// Never been set before. Use the system value from registry.
@@ -222,7 +221,7 @@ namespace System.Globalization {
// 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",
+ nameof(HijriAdjustment),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Bounds_Lower_Upper"),
@@ -252,7 +251,6 @@ namespace System.Globalization {
** "AddHijriDate+1" => Add +1 days to the current calculated Hijri date.
** "AddHijriDate+2" => Add +2 days to the current calculated Hijri date.
============================================================================*/
- [System.Security.SecurityCritical] // auto-generated
static int GetAdvanceHijriDate() {
#if FEATURE_WIN32_REGISTRY
@@ -320,7 +318,7 @@ namespace System.Globalization {
static internal void CheckEraRange(int era) {
if (era != CurrentEra && era != HijriEra) {
- throw new ArgumentOutOfRangeException("era", Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
}
}
@@ -328,7 +326,7 @@ namespace System.Globalization {
CheckEraRange(era);
if (year < 1 || year > MaxCalendarYear) {
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -342,7 +340,7 @@ namespace System.Globalization {
if (year == MaxCalendarYear) {
if (month > MaxCalendarMonth) {
throw new ArgumentOutOfRangeException(
- "month",
+ nameof(month),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -352,7 +350,7 @@ namespace System.Globalization {
}
if (month < 1 || month > 12) {
- throw new ArgumentOutOfRangeException("month", Environment.GetResourceString("ArgumentOutOfRange_Month"));
+ throw new ArgumentOutOfRangeException(nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Month"));
}
}
@@ -465,7 +463,7 @@ namespace System.Globalization {
public override DateTime AddMonths(DateTime time, int months) {
if (months < -120000 || months > 120000) {
throw new ArgumentOutOfRangeException(
- "months",
+ nameof(months),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -602,7 +600,7 @@ namespace System.Globalization {
int daysInMonth = GetDaysInMonth(year, month, era);
if (day < 1 || day > daysInMonth) {
throw new ArgumentOutOfRangeException(
- "day",
+ nameof(day),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Day"),
@@ -650,7 +648,7 @@ namespace System.Globalization {
if (day < 1 || day > daysInMonth) {
BCLDebug.Log("year = " + year + ", month = " + month + ", day = " + day);
throw new ArgumentOutOfRangeException(
- "day",
+ nameof(day),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Day"),
@@ -683,7 +681,7 @@ namespace System.Globalization {
if (value < 99 || value > MaxCalendarYear)
{
throw new ArgumentOutOfRangeException(
- "value",
+ nameof(value),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -698,7 +696,7 @@ namespace System.Globalization {
public override int ToFourDigitYear(int year) {
if (year < 0) {
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
Contract.EndContractBlock();
@@ -709,7 +707,7 @@ namespace System.Globalization {
if (year > MaxCalendarYear) {
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
diff --git a/src/mscorlib/src/System/Globalization/IdnMapping.cs b/src/mscorlib/src/System/Globalization/IdnMapping.cs
index 599a32ad87..bf75f5be3c 100644
--- a/src/mscorlib/src/System/Globalization/IdnMapping.cs
+++ b/src/mscorlib/src/System/Globalization/IdnMapping.cs
@@ -65,6 +65,7 @@ namespace 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
@@ -125,23 +126,22 @@ namespace System.Globalization
public String GetAscii(String unicode, int index)
{
- if (unicode==null) throw new ArgumentNullException("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)
{
- throw null;
- /*if (unicode==null) throw new ArgumentNullException("unicode");
+ if (unicode == null) throw new ArgumentNullException(nameof(unicode));
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0) ? "index" : "count",
+ throw new ArgumentOutOfRangeException((index < 0) ? nameof(index) : nameof(count),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (index > unicode.Length)
- throw new ArgumentOutOfRangeException("byteIndex",
+ throw new ArgumentOutOfRangeException(nameof(index),
Environment.GetResourceString("ArgumentOutOfRange_Index"));
if (index > unicode.Length - count)
- throw new ArgumentOutOfRangeException("unicode",
+ throw new ArgumentOutOfRangeException(nameof(unicode),
Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
Contract.EndContractBlock();
@@ -161,12 +161,12 @@ namespace System.Globalization
// Cannot be null terminated (normalization won't help us with this one, and
// may have returned false before checking the whole string above)
- Contract.Assert(unicode.Length >= 1, "[IdnMapping.GetAscii]Expected 0 length strings to fail before now.");
+ 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 ),
- "unicode");
+ nameof(unicode));
}
// Have to correctly IDNA normalize the string and Unassigned flags
@@ -178,7 +178,7 @@ namespace System.Globalization
if ((!bHasLastDot) && unicode.Length > 0 && IsDot(unicode[unicode.Length - 1]))
{
throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadLabelSize"), "unicode");
+ "Argument_IdnBadLabelSize"), nameof(unicode));
}
// May need to check Std3 rules again for non-ascii
@@ -188,24 +188,23 @@ namespace System.Globalization
}
// Go ahead and encode it
- return punycode_encode(unicode);*/
+ return punycode_encode(unicode);
}
- [System.Security.SecuritySafeCritical]
private String GetAsciiUsingOS(String unicode)
{
if (unicode.Length == 0)
{
throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadLabelSize"), "unicode");
+ "Argument_IdnBadLabelSize"), nameof(unicode));
}
if (unicode[unicode.Length - 1] == 0)
{
throw new ArgumentException(
Environment.GetResourceString("Argument_InvalidCharSequence", unicode.Length - 1),
- "unicode");
+ nameof(unicode));
}
uint flags = (uint) ((AllowUnassigned ? IDN_ALLOW_UNASSIGNED : 0) | (UseStd3AsciiRules ? IDN_USE_STD3_ASCII_RULES : 0));
@@ -218,10 +217,10 @@ namespace System.Globalization
lastError = Marshal.GetLastWin32Error();
if (lastError == ERROR_INVALID_NAME)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_IdnIllegalName"), "unicode");
+ throw new ArgumentException(Environment.GetResourceString("Argument_IdnIllegalName"), nameof(unicode));
}
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"), "unicode");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"), nameof(unicode));
}
char [] output = new char[length];
@@ -232,10 +231,10 @@ namespace System.Globalization
lastError = Marshal.GetLastWin32Error();
if (lastError == ERROR_INVALID_NAME)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_IdnIllegalName"), "unicode");
+ throw new ArgumentException(Environment.GetResourceString("Argument_IdnIllegalName"), nameof(unicode));
}
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"), "unicode");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"), nameof(unicode));
}
return new String(output, 0, length);
@@ -249,30 +248,30 @@ namespace System.Globalization
public String GetUnicode(String ascii, int index)
{
- if (ascii==null) throw new ArgumentNullException("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)
{
- if (ascii==null) throw new ArgumentNullException("ascii");
+ if (ascii==null) throw new ArgumentNullException(nameof(ascii));
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0) ? "index" : "count",
+ throw new ArgumentOutOfRangeException((index < 0) ? nameof(index) : nameof(count),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (index > ascii.Length)
throw new ArgumentOutOfRangeException("byteIndex",
Environment.GetResourceString("ArgumentOutOfRange_Index"));
if (index > ascii.Length - count)
- throw new ArgumentOutOfRangeException("ascii",
+ throw new ArgumentOutOfRangeException(nameof(ascii),
Environment.GetResourceString("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("ascii",
- Environment.GetResourceString("Argument_IdnBadPunycode"));
+ throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"),
+ nameof(ascii));
Contract.EndContractBlock();
// We're only using part of the string
@@ -289,13 +288,12 @@ namespace System.Globalization
// 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"), "ascii");
+ "Argument_IdnIllegalName"), nameof(ascii));
return strUnicode;
}
- [System.Security.SecuritySafeCritical]
private string GetUnicodeUsingOS(string ascii)
{
uint flags = (uint)((AllowUnassigned ? IDN_ALLOW_UNASSIGNED : 0) | (UseStd3AsciiRules ? IDN_USE_STD3_ASCII_RULES : 0));
@@ -307,10 +305,10 @@ namespace System.Globalization
lastError = Marshal.GetLastWin32Error();
if (lastError == ERROR_INVALID_NAME)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_IdnIllegalName"), "ascii");
+ throw new ArgumentException(Environment.GetResourceString("Argument_IdnIllegalName"), nameof(ascii));
}
- throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "ascii");
+ throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), nameof(ascii));
}
char [] output = new char[length];
@@ -321,10 +319,10 @@ namespace System.Globalization
lastError = Marshal.GetLastWin32Error();
if (lastError == ERROR_INVALID_NAME)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_IdnIllegalName"), "ascii");
+ throw new ArgumentException(Environment.GetResourceString("Argument_IdnIllegalName"), nameof(ascii));
}
- throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "ascii");
+ throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), nameof(ascii));
}
return new String(output, 0, length);
@@ -370,7 +368,7 @@ namespace System.Globalization
// If its empty, then its too small
if (unicode.Length == 0)
throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadLabelSize"), "unicode");
+ "Argument_IdnBadLabelSize"), nameof(unicode));
Contract.EndContractBlock();
int iLastDot = -1;
@@ -383,7 +381,7 @@ namespace System.Globalization
{
throw new ArgumentException(
Environment.GetResourceString("Argument_InvalidCharSequence", i ),
- "unicode");
+ nameof(unicode));
}
// If its Unicode or a control character, return false (non-ascii)
@@ -396,12 +394,12 @@ namespace System.Globalization
// Can't have 2 dots in a row
if (i == iLastDot + 1)
throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadLabelSize"), "unicode");
+ "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"), "Unicode");
+ "Argument_IdnBadLabelSize"), nameof(unicode));
// If validating Std3, then char before dot can't be - char
if (bUseStd3 && i > 0)
@@ -422,14 +420,14 @@ 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"), "unicode");
+ "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)),
- "unicode");
+ nameof(unicode));
// If last char wasn't a dot we need to check for trailing -
if (bUseStd3 && !IsDot(unicode[unicode.Length-1]))
@@ -510,7 +508,7 @@ namespace System.Globalization
static char encode_digit(int d)
{
- Contract.Assert(d >= 0 && d < punycodeBase, "[IdnMapping.encode_digit]Expected 0 <= d < punycodeBase");
+ 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');
@@ -547,7 +545,7 @@ namespace System.Globalization
uint k;
delta = firsttime ? delta / damp : delta / 2;
- Contract.Assert(numpoints != 0, "[IdnMapping.adapt]Expected non-zero numpoints.");
+ Debug.Assert(numpoints != 0, "[IdnMapping.adapt]Expected non-zero numpoints.");
delta += delta / numpoints;
for (k = 0; delta > ((punycodeBase - tmin) * tmax) / 2; k += punycodeBase)
@@ -555,7 +553,7 @@ namespace System.Globalization
delta /= punycodeBase - tmin;
}
- Contract.Assert(delta + skew != 0, "[IdnMapping.adapt]Expected non-zero delta+skew.");
+ Debug.Assert(delta + skew != 0, "[IdnMapping.adapt]Expected non-zero delta+skew.");
return (int)(k + (punycodeBase - tmin + 1) * delta / (delta + skew));
}
@@ -592,7 +590,7 @@ namespace System.Globalization
// 0 length strings aren't allowed
if (unicode.Length == 0)
throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadLabelSize"), "unicode");
+ "Argument_IdnBadLabelSize"), nameof(unicode));
Contract.EndContractBlock();
StringBuilder output = new StringBuilder(unicode.Length);
@@ -605,7 +603,7 @@ namespace System.Globalization
{
// Find end of this segment
iNextDot = unicode.IndexOfAny(M_Dots, iAfterLastDot);
- Contract.Assert(iNextDot <= unicode.Length, "[IdnMapping.punycode_encode]IndexOfAny is broken");
+ Debug.Assert(iNextDot <= unicode.Length, "[IdnMapping.punycode_encode]IndexOfAny is broken");
if (iNextDot < 0)
iNextDot = unicode.Length;
@@ -615,7 +613,7 @@ namespace System.Globalization
// Only allowed to have empty sections as trailing .
if (iNextDot != unicode.Length)
throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadLabelSize"), "unicode");
+ "Argument_IdnBadLabelSize"), nameof(unicode));
// Last dot, stop
break;
}
@@ -645,7 +643,7 @@ namespace System.Globalization
{
// Oops, last wasn't RTL, last should be RTL if first is RTL
throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadBidi"), "unicode");
+ "Argument_IdnBadBidi"), nameof(unicode));
}
}
@@ -655,7 +653,7 @@ namespace System.Globalization
for (basicCount = iAfterLastDot; basicCount < iNextDot; basicCount++)
{
// Can't be lonely surrogate because it would've thrown in normalization
- Contract.Assert(Char.IsLowSurrogate(unicode, basicCount) == false,
+ Debug.Assert(Char.IsLowSurrogate(unicode, basicCount) == false,
"[IdnMapping.punycode_encode]Unexpected low surrogate");
// Double check our bidi rules
@@ -666,7 +664,7 @@ namespace System.Globalization
{
// Oops, throw error
throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadBidi"), "unicode");
+ "Argument_IdnBadBidi"), nameof(unicode));
}
// If we're not RTL we can't have RTL chars
@@ -675,7 +673,7 @@ namespace System.Globalization
{
// Oops, throw error
throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadBidi"), "unicode");
+ "Argument_IdnBadBidi"), nameof(unicode));
}
// If its basic then add it
@@ -704,7 +702,7 @@ namespace System.Globalization
unicode.Substring(iAfterLastDot, M_strAcePrefix.Length).Equals(
M_strAcePrefix, StringComparison.OrdinalIgnoreCase))
throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadPunycode"), "unicode");
+ "Argument_IdnBadPunycode"), nameof(unicode));
// Need to do ACE encoding
int numSurrogatePairs = 0; // number of surrogate pairs so far
@@ -739,7 +737,7 @@ namespace System.Globalization
/* Increase delta enough to advance the decoder's */
/* <n,i> state to <m,0>, but guard against overflow: */
delta += (int)((m - n) * ((numProcessed - numSurrogatePairs) + 1));
- Contract.Assert(delta > 0, "[IdnMapping.cs]1 punycode_encode - delta overflowed int");
+ Debug.Assert(delta > 0, "[IdnMapping.cs]1 punycode_encode - delta overflowed int");
n = m;
for (j = iAfterLastDot; j < iNextDot; j+= IsSupplementary(test) ? 2 : 1)
@@ -753,7 +751,7 @@ namespace System.Globalization
if (test < n)
{
delta++;
- Contract.Assert(delta > 0, "[IdnMapping.cs]2 punycode_encode - delta overflowed int");
+ Debug.Assert(delta > 0, "[IdnMapping.cs]2 punycode_encode - delta overflowed int");
}
if (test == n)
@@ -765,9 +763,11 @@ namespace System.Globalization
int t = k <= bias ? tmin :
k >= bias + tmax ? tmax : k - bias;
if (q < t) break;
- Contract.Assert(punycodeBase != t, "[IdnMapping.punycode_encode]Expected punycodeBase (36) to be != t");
- output.Append(encode_digit(t + (q - t) % (punycodeBase - t)));
- q = (q - t) / (punycodeBase - t);
+ 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));
}
output.Append(encode_digit(q));
@@ -784,14 +784,14 @@ namespace System.Globalization
}
++delta;
++n;
- Contract.Assert(delta > 0, "[IdnMapping.cs]3 punycode_encode - delta overflowed int");
+ Debug.Assert(delta > 0, "[IdnMapping.cs]3 punycode_encode - delta overflowed int");
}
}
// Make sure its not too big
if (output.Length - iOutputAfterLastDot > M_labelLimit)
throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadLabelSize"), "unicode");
+ "Argument_IdnBadLabelSize"), nameof(unicode));
// Done with this segment, add dot if necessary
if (iNextDot != unicode.Length)
@@ -806,7 +806,7 @@ namespace System.Globalization
throw new ArgumentException(Environment.GetResourceString(
"Argument_IdnBadNameSize",
M_defaultNameLimit - (IsDot(unicode[unicode.Length-1]) ? 0 : 1)),
- "unicode");
+ nameof(unicode));
// Return our output string
return output.ToString();
@@ -840,14 +840,14 @@ namespace System.Globalization
// 0 length strings aren't allowed
if (ascii.Length == 0)
throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadLabelSize"), "ascii");
+ "Argument_IdnBadLabelSize"), nameof(ascii));
Contract.EndContractBlock();
// 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)), "ascii");
+ M_defaultNameLimit - (IsDot(ascii[ascii.Length-1]) ? 0 : 1)), nameof(ascii));
// output stringbuilder
StringBuilder output = new StringBuilder(ascii.Length);
@@ -870,7 +870,7 @@ namespace System.Globalization
// Only allowed to have empty sections as trailing .
if (iNextDot != ascii.Length)
throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadLabelSize"), "ascii");
+ "Argument_IdnBadLabelSize"), nameof(ascii));
// Last dot, stop
break;
@@ -879,7 +879,7 @@ namespace System.Globalization
// In either case it can't be bigger than segment size
if (iNextDot - iAfterLastDot > M_labelLimit)
throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadLabelSize"), "ascii");
+ "Argument_IdnBadLabelSize"), nameof(ascii));
// See if this section's ASCII or ACE
if (ascii.Length < M_strAcePrefix.Length + iAfterLastDot ||
@@ -893,7 +893,7 @@ namespace System.Globalization
// // Only ASCII is allowed
// if (ascii[i] >= 0x80)
// throw new ArgumentException(Environment.GetResourceString(
- // "Argument_IdnBadPunycode"), "ascii");
+ // "Argument_IdnBadPunycode"), nameof(ascii));
// }
// Its ASCII, copy it
@@ -913,7 +913,7 @@ namespace System.Globalization
// Trailing - not allowed
if (iTemp == iNextDot - 1)
throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadPunycode"), "ascii");
+ "Argument_IdnBadPunycode"), nameof(ascii));
int numBasicCodePoints;
if (iTemp <= iAfterLastDot)
@@ -931,7 +931,7 @@ namespace System.Globalization
// Make sure we don't allow unicode in the ascii part
if (ascii[copyAscii] > 0x7f)
throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadPunycode"), "ascii");
+ "Argument_IdnBadPunycode"), nameof(ascii));
// When appending make sure they get lower cased
output.Append((char)(ascii[copyAscii] >= 'A' && ascii[copyAscii] <='Z' ?
@@ -970,24 +970,24 @@ namespace System.Globalization
// Check to make sure we aren't overrunning our ascii string
if (asciiIndex >= iNextDot)
throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadPunycode"), "ascii");
+ "Argument_IdnBadPunycode"), nameof(ascii));
// decode the digit from the next char
int digit = decode_digit(ascii[asciiIndex++]);
- Contract.Assert(w > 0, "[IdnMapping.punycode_decode]Expected w > 0");
+ Debug.Assert(w > 0, "[IdnMapping.punycode_decode]Expected w > 0");
if (digit > (maxint - i) / w)
throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadPunycode"), "ascii");
+ "Argument_IdnBadPunycode"), nameof(ascii));
i += (int)(digit * w);
int t = k <= bias ? tmin :
k >= bias + tmax ? tmax : k - bias;
if (digit < t) break;
- Contract.Assert(punycodeBase != t, "[IdnMapping.punycode_decode]Expected t != punycodeBase (36)");
+ Debug.Assert(punycodeBase != t, "[IdnMapping.punycode_decode]Expected t != punycodeBase (36)");
if (w > maxint / (punycodeBase - t))
throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadPunycode"), "ascii");
+ "Argument_IdnBadPunycode"), nameof(ascii));
w *= (punycodeBase - t);
}
@@ -996,11 +996,11 @@ namespace System.Globalization
/* i was supposed to wrap around from output.Length to 0, */
/* incrementing n each time, so we'll fix that now: */
- Contract.Assert((output.Length - iOutputAfterLastDot - numSurrogatePairs) + 1 > 0,
+ 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"), "ascii");
+ "Argument_IdnBadPunycode"), nameof(ascii));
n += (int)(i / (output.Length - iOutputAfterLastDot - numSurrogatePairs + 1));
i %= (output.Length - iOutputAfterLastDot - numSurrogatePairs + 1);
@@ -1016,7 +1016,7 @@ namespace System.Globalization
// Make sure n is legal
if ((n < 0 || n > 0x10ffff) || (n >= 0xD800 && n <= 0xDFFF))
throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadPunycode"), "ascii");
+ "Argument_IdnBadPunycode"), nameof(ascii));
// insert n at position i of the output: Really tricky if we have surrogates
int iUseInsertLocation;
@@ -1034,7 +1034,7 @@ namespace System.Globalization
// If its a surrogate, we have to go one more
if (iUseInsertLocation >= output.Length)
throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadPunycode"), "ascii");
+ "Argument_IdnBadPunycode"), nameof(ascii));
if (Char.IsSurrogate(output[iUseInsertLocation]))
iUseInsertLocation++;
}
@@ -1079,7 +1079,7 @@ namespace System.Globalization
(!bRightToLeft && (eBidi == BidiCategory.RightToLeft ||
eBidi == BidiCategory.RightToLeftArabic)))
throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadBidi"), "ascii");
+ "Argument_IdnBadBidi"), nameof(ascii));
// Make it lower case if we must (so we can test IsNormalized later)
// if (output[iTest] >= 'A' && output[iTest] <= 'Z')
@@ -1091,14 +1091,14 @@ namespace System.Globalization
{
// Oops, last wasn't RTL, last should be RTL if first is RTL
throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadBidi"), "ascii");
+ "Argument_IdnBadBidi"), nameof(ascii));
}
}
// See if this label was too long
if (iNextDot - iAfterLastDot > M_labelLimit)
throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadLabelSize"), "ascii");
+ "Argument_IdnBadLabelSize"), nameof(ascii));
// Done with this segment, add dot if necessary
if (iNextDot != ascii.Length)
@@ -1112,7 +1112,7 @@ namespace System.Globalization
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)), "ascii");
+ M_defaultNameLimit -(IsDot(output[output.Length-1]) ? 0 : 1)), nameof(ascii));
// Return our output string
return output.ToString();
@@ -1157,9 +1157,8 @@ namespace System.Globalization
private const int ERROR_INVALID_NAME = 123;
- [System.Security.SecurityCritical]
[SuppressUnmanagedCodeSecurityAttribute()]
- [DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
+ [DllImport("normaliz.dll", CharSet=CharSet.Unicode, SetLastError=true)]
private static extern int IdnToAscii(
uint dwFlags,
[InAttribute()]
@@ -1171,9 +1170,8 @@ namespace System.Globalization
char [] lpASCIICharStr,
int cchASCIIChar);
- [System.Security.SecurityCritical]
[SuppressUnmanagedCodeSecurityAttribute()]
- [DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
+ [DllImport("normaliz.dll", CharSet=CharSet.Unicode, SetLastError=true)]
private static extern int IdnToUnicode(
uint dwFlags,
[InAttribute()]
diff --git a/src/mscorlib/src/System/Globalization/JapaneseCalendar.cs b/src/mscorlib/src/System/Globalization/JapaneseCalendar.cs
index 2984d08ab3..6b168ce916 100644
--- a/src/mscorlib/src/System/Globalization/JapaneseCalendar.cs
+++ b/src/mscorlib/src/System/Globalization/JapaneseCalendar.cs
@@ -159,7 +159,6 @@ namespace System.Globalization {
// . 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.
- [System.Security.SecuritySafeCritical] // auto-generated
private static EraInfo[] GetErasFromRegistry()
{
// Look in the registry key and see if we can find any ranges
@@ -491,14 +490,14 @@ namespace System.Globalization {
public override int ToFourDigitYear(int year) {
if (year <= 0) {
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
}
Contract.EndContractBlock();
if (year > helper.MaxYear) {
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
diff --git a/src/mscorlib/src/System/Globalization/JulianCalendar.cs b/src/mscorlib/src/System/Globalization/JulianCalendar.cs
index 9c8db3415c..db286e0363 100644
--- a/src/mscorlib/src/System/Globalization/JulianCalendar.cs
+++ b/src/mscorlib/src/System/Globalization/JulianCalendar.cs
@@ -112,7 +112,7 @@ namespace System.Globalization {
static internal void CheckEraRange(int era) {
if (era != CurrentEra && era != JulianEra) {
- throw new ArgumentOutOfRangeException("era", Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
}
}
@@ -120,7 +120,7 @@ namespace System.Globalization {
CheckEraRange(era);
if (year <= 0 || year > MaxYear) {
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -131,7 +131,7 @@ namespace System.Globalization {
static internal void CheckMonthRange(int month) {
if (month < 1 || month > 12) {
- throw new ArgumentOutOfRangeException("month", Environment.GetResourceString("ArgumentOutOfRange_Month"));
+ throw new ArgumentOutOfRangeException(nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Month"));
}
}
@@ -159,7 +159,7 @@ namespace System.Globalization {
int monthDays = days[month] - days[month - 1];
if (day < 1 || day > monthDays) {
throw new ArgumentOutOfRangeException(
- "day",
+ nameof(day),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -204,7 +204,7 @@ namespace System.Globalization {
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;
+ int m = (n >> 5) + 1;
// m = 1-based month number
while (n >= days[m]) m++;
// If month was requested, return it
@@ -230,7 +230,7 @@ namespace System.Globalization {
{
if (months < -120000 || months > 120000) {
throw new ArgumentOutOfRangeException(
- "months",
+ nameof(months),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -377,7 +377,7 @@ namespace System.Globalization {
CheckDayRange(year, month, day);
if (millisecond < 0 || millisecond >= MillisPerSecond) {
throw new ArgumentOutOfRangeException(
- "millisecond",
+ nameof(millisecond),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -420,14 +420,14 @@ namespace System.Globalization {
public override int ToFourDigitYear(int year) {
if (year < 0) {
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
Contract.EndContractBlock();
if (year > MaxYear) {
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Bounds_Lower_Upper"),
diff --git a/src/mscorlib/src/System/Globalization/KoreanCalendar.cs b/src/mscorlib/src/System/Globalization/KoreanCalendar.cs
index 9343884445..dde82b6e6b 100644
--- a/src/mscorlib/src/System/Globalization/KoreanCalendar.cs
+++ b/src/mscorlib/src/System/Globalization/KoreanCalendar.cs
@@ -254,7 +254,7 @@ namespace System.Globalization {
public override int ToFourDigitYear(int year) {
if (year < 0) {
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
Contract.EndContractBlock();
diff --git a/src/mscorlib/src/System/Globalization/KoreanLunisolarCalendar.cs b/src/mscorlib/src/System/Globalization/KoreanLunisolarCalendar.cs
index eb0a810864..9e36b435e7 100644
--- a/src/mscorlib/src/System/Globalization/KoreanLunisolarCalendar.cs
+++ b/src/mscorlib/src/System/Globalization/KoreanLunisolarCalendar.cs
@@ -1267,12 +1267,12 @@ namespace System.Globalization {
internal override int GetGregorianYear(int year, int era)
{
if (era != CurrentEra && era != GregorianEra)
- throw new ArgumentOutOfRangeException("era", Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
if (year < MIN_LUNISOLAR_YEAR || year > MAX_LUNISOLAR_YEAR)
{
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"), MIN_LUNISOLAR_YEAR, MAX_LUNISOLAR_YEAR));
diff --git a/src/mscorlib/src/System/Globalization/NumberFormatInfo.cs b/src/mscorlib/src/System/Globalization/NumberFormatInfo.cs
index fae91c2a1d..a5dce46aa4 100644
--- a/src/mscorlib/src/System/Globalization/NumberFormatInfo.cs
+++ b/src/mscorlib/src/System/Globalization/NumberFormatInfo.cs
@@ -120,28 +120,8 @@ namespace System.Globalization {
[OnSerializing]
private void OnSerializing(StreamingContext ctx)
{
-#if !FEATURE_CORECLR
- // Update these legacy flags, so that 1.1/2.0 versions of the framework
- // can still throw while parsing; even when using a de-serialized
- // NumberFormatInfo from a 4.0+ version of the framework
- if (numberDecimalSeparator != numberGroupSeparator) {
- validForParseAsNumber = true;
- } else {
- validForParseAsNumber = false;
- }
-
- if ((numberDecimalSeparator != numberGroupSeparator) &&
- (numberDecimalSeparator != currencyGroupSeparator) &&
- (currencyDecimalSeparator != numberGroupSeparator) &&
- (currencyDecimalSeparator != currencyGroupSeparator)) {
- validForParseAsCurrency = true;
- } else {
- validForParseAsCurrency = false;
- }
-#endif // !FEATURE_CORECLR
}
-
[OnDeserializing]
private void OnDeserializing(StreamingContext ctx)
{
@@ -153,7 +133,6 @@ namespace System.Globalization {
}
#endregion Serialization
-
static private void VerifyDecimalSeparator(String decSep, String propertyName) {
if (decSep==null) {
throw new ArgumentNullException(propertyName,
@@ -231,7 +210,6 @@ namespace System.Globalization {
// 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.
- [System.Security.SecuritySafeCritical] // auto-generated
internal NumberFormatInfo(CultureData cultureData)
{
if (cultureData != null)
@@ -316,7 +294,7 @@ namespace System.Globalization {
set {
if (value < 0 || value > 99) {
throw new ArgumentOutOfRangeException(
- "CurrencyDecimalDigits",
+ nameof(CurrencyDecimalDigits),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -376,7 +354,7 @@ namespace System.Globalization {
}
set {
if (value == null) {
- throw new ArgumentNullException("CurrencyGroupSizes",
+ throw new ArgumentNullException(nameof(CurrencyGroupSizes),
Environment.GetResourceString("ArgumentNull_Obj"));
}
Contract.EndContractBlock();
@@ -397,7 +375,7 @@ namespace System.Globalization {
}
set {
if (value == null) {
- throw new ArgumentNullException("NumberGroupSizes",
+ throw new ArgumentNullException(nameof(NumberGroupSizes),
Environment.GetResourceString("ArgumentNull_Obj"));
}
Contract.EndContractBlock();
@@ -416,7 +394,7 @@ namespace System.Globalization {
}
set {
if (value == null) {
- throw new ArgumentNullException("PercentGroupSizes",
+ throw new ArgumentNullException(nameof(PercentGroupSizes),
Environment.GetResourceString("ArgumentNull_Obj"));
}
Contract.EndContractBlock();
@@ -443,7 +421,7 @@ namespace System.Globalization {
get { return currencySymbol; }
set {
if (value == null) {
- throw new ArgumentNullException("CurrencySymbol",
+ throw new ArgumentNullException(nameof(CurrencySymbol),
Environment.GetResourceString("ArgumentNull_String"));
}
Contract.EndContractBlock();
@@ -475,7 +453,7 @@ namespace System.Globalization {
}
set {
if (value == null) {
- throw new ArgumentNullException("NaNSymbol",
+ throw new ArgumentNullException(nameof(NaNSymbol),
Environment.GetResourceString("ArgumentNull_String"));
}
Contract.EndContractBlock();
@@ -491,7 +469,7 @@ namespace System.Globalization {
set {
if (value < 0 || value > 15) {
throw new ArgumentOutOfRangeException(
- "CurrencyNegativePattern",
+ nameof(CurrencyNegativePattern),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -513,7 +491,7 @@ namespace System.Globalization {
//
if (value < 0 || value > 4) {
throw new ArgumentOutOfRangeException(
- "NumberNegativePattern",
+ nameof(NumberNegativePattern),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -535,7 +513,7 @@ namespace System.Globalization {
//
if (value < 0 || value > 3) {
throw new ArgumentOutOfRangeException(
- "PercentPositivePattern",
+ nameof(PercentPositivePattern),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -557,7 +535,7 @@ namespace System.Globalization {
//
if (value < 0 || value > 11) {
throw new ArgumentOutOfRangeException(
- "PercentNegativePattern",
+ nameof(PercentNegativePattern),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -577,7 +555,7 @@ namespace System.Globalization {
}
set {
if (value == null) {
- throw new ArgumentNullException("NegativeInfinitySymbol",
+ throw new ArgumentNullException(nameof(NegativeInfinitySymbol),
Environment.GetResourceString("ArgumentNull_String"));
}
Contract.EndContractBlock();
@@ -591,7 +569,7 @@ namespace System.Globalization {
get { return negativeSign; }
set {
if (value == null) {
- throw new ArgumentNullException("NegativeSign",
+ throw new ArgumentNullException(nameof(NegativeSign),
Environment.GetResourceString("ArgumentNull_String"));
}
Contract.EndContractBlock();
@@ -606,7 +584,7 @@ namespace System.Globalization {
set {
if (value < 0 || value > 99) {
throw new ArgumentOutOfRangeException(
- "NumberDecimalDigits",
+ nameof(NumberDecimalDigits),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -645,7 +623,7 @@ namespace System.Globalization {
set {
if (value < 0 || value > 3) {
throw new ArgumentOutOfRangeException(
- "CurrencyPositivePattern",
+ nameof(CurrencyPositivePattern),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -665,7 +643,7 @@ namespace System.Globalization {
}
set {
if (value == null) {
- throw new ArgumentNullException("PositiveInfinitySymbol",
+ throw new ArgumentNullException(nameof(PositiveInfinitySymbol),
Environment.GetResourceString("ArgumentNull_String"));
}
Contract.EndContractBlock();
@@ -679,7 +657,7 @@ namespace System.Globalization {
get { return positiveSign; }
set {
if (value == null) {
- throw new ArgumentNullException("PositiveSign",
+ throw new ArgumentNullException(nameof(PositiveSign),
Environment.GetResourceString("ArgumentNull_String"));
}
Contract.EndContractBlock();
@@ -694,7 +672,7 @@ namespace System.Globalization {
set {
if (value < 0 || value > 99) {
throw new ArgumentOutOfRangeException(
- "PercentDecimalDigits",
+ nameof(PercentDecimalDigits),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -734,7 +712,7 @@ namespace System.Globalization {
}
set {
if (value == null) {
- throw new ArgumentNullException("PercentSymbol",
+ throw new ArgumentNullException(nameof(PercentSymbol),
Environment.GetResourceString("ArgumentNull_String"));
}
Contract.EndContractBlock();
@@ -748,7 +726,7 @@ namespace System.Globalization {
get { return perMilleSymbol; }
set {
if (value == null) {
- throw new ArgumentNullException("PerMilleSymbol",
+ throw new ArgumentNullException(nameof(PerMilleSymbol),
Environment.GetResourceString("ArgumentNull_String"));
}
Contract.EndContractBlock();
@@ -788,7 +766,7 @@ namespace System.Globalization {
public static NumberFormatInfo ReadOnly(NumberFormatInfo nfi) {
if (nfi == null) {
- throw new ArgumentNullException("nfi");
+ throw new ArgumentNullException(nameof(nfi));
}
Contract.EndContractBlock();
if (nfi.IsReadOnly) {
@@ -809,7 +787,7 @@ namespace System.Globalization {
internal static void ValidateParseStyleInteger(NumberStyles style) {
// Check for undefined flags
if ((style & InvalidNumberStyles) != 0) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidNumberStyles"), "style");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidNumberStyles"), nameof(style));
}
Contract.EndContractBlock();
if ((style & NumberStyles.AllowHexSpecifier) != 0) { // Check for hex number
@@ -822,7 +800,7 @@ namespace System.Globalization {
internal static void ValidateParseStyleFloatingPoint(NumberStyles style) {
// Check for undefined flags
if ((style & InvalidNumberStyles) != 0) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidNumberStyles"), "style");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidNumberStyles"), nameof(style));
}
Contract.EndContractBlock();
if ((style & NumberStyles.AllowHexSpecifier) != 0) { // Check for hex number
diff --git a/src/mscorlib/src/System/Globalization/PersianCalendar.cs b/src/mscorlib/src/System/Globalization/PersianCalendar.cs
index 2f1ffacee7..e61a007a02 100644
--- a/src/mscorlib/src/System/Globalization/PersianCalendar.cs
+++ b/src/mscorlib/src/System/Globalization/PersianCalendar.cs
@@ -4,6 +4,7 @@
namespace System.Globalization {
using System;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
////////////////////////////////////////////////////////////////////////////
@@ -147,7 +148,7 @@ namespace System.Globalization {
static internal void CheckEraRange(int era) {
if (era != CurrentEra && era != PersianEra) {
- throw new ArgumentOutOfRangeException("era", Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
}
}
@@ -155,7 +156,7 @@ namespace System.Globalization {
CheckEraRange(era);
if (year < 1 || year > MaxCalendarYear) {
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -169,7 +170,7 @@ namespace System.Globalization {
if (year == MaxCalendarYear) {
if (month > MaxCalendarMonth) {
throw new ArgumentOutOfRangeException(
- "month",
+ nameof(month),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -179,13 +180,13 @@ namespace System.Globalization {
}
if (month < 1 || month > 12) {
- throw new ArgumentOutOfRangeException("month", Environment.GetResourceString("ArgumentOutOfRange_Month"));
+ throw new ArgumentOutOfRangeException(nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Month"));
}
}
static int MonthFromOrdinalDay(int ordinalDay)
{
- Contract.Assert(ordinalDay <= 366);
+ Debug.Assert(ordinalDay <= 366);
int index = 0;
while (ordinalDay > DaysToMonth[index])
index++;
@@ -195,7 +196,7 @@ namespace System.Globalization {
static int DaysInPreviousMonths(int month)
{
- Contract.Assert(1 <= month && month <= 12);
+ Debug.Assert(1 <= month && month <= 12);
--month; // months are one based but for calculations use 0 based
return DaysToMonth[month];
}
@@ -225,7 +226,7 @@ namespace System.Globalization {
long yearStart = CalendricalCalculationsHelper.PersianNewYearOnOrBefore(NumDays);
int y = (int)(Math.Floor(((yearStart - PersianEpoch) / CalendricalCalculationsHelper.MeanTropicalYearInDays) + 0.5)) + 1;
- Contract.Assert(y >= 1);
+ Debug.Assert(y >= 1);
if (part == DatePartYear)
{
@@ -244,16 +245,16 @@ namespace System.Globalization {
}
int m = MonthFromOrdinalDay(ordinalDay);
- Contract.Assert(ordinalDay >= 1);
- Contract.Assert(m >= 1 && m <= 12);
+ Debug.Assert(ordinalDay >= 1);
+ Debug.Assert(m >= 1 && m <= 12);
if (part == DatePartMonth)
{
return m;
}
int d = ordinalDay - DaysInPreviousMonths(m);
- Contract.Assert(1 <= d);
- Contract.Assert(d <= 31);
+ Debug.Assert(1 <= d);
+ Debug.Assert(d <= 31);
//
// Calculate the Persian Day.
@@ -290,7 +291,7 @@ namespace System.Globalization {
public override DateTime AddMonths(DateTime time, int months) {
if (months < -120000 || months > 120000) {
throw new ArgumentOutOfRangeException(
- "months",
+ nameof(months),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -377,7 +378,7 @@ namespace System.Globalization {
int daysInMonth = DaysToMonth[month] - DaysToMonth[month - 1];
if ((month == MonthsPerYear) && !IsLeapYear(year))
{
- Contract.Assert(daysInMonth == 30);
+ Debug.Assert(daysInMonth == 30);
--daysInMonth;
}
return daysInMonth;
@@ -450,7 +451,7 @@ namespace System.Globalization {
int daysInMonth = GetDaysInMonth(year, month, era);
if (day < 1 || day > daysInMonth) {
throw new ArgumentOutOfRangeException(
- "day",
+ nameof(day),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Day"),
@@ -506,7 +507,7 @@ namespace System.Globalization {
if (day < 1 || day > daysInMonth) {
BCLDebug.Log("year = " + year + ", month = " + month + ", day = " + day);
throw new ArgumentOutOfRangeException(
- "day",
+ nameof(day),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Day"),
@@ -538,7 +539,7 @@ namespace System.Globalization {
if (value < 99 || value > MaxCalendarYear)
{
throw new ArgumentOutOfRangeException(
- "value",
+ nameof(value),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -553,7 +554,7 @@ namespace System.Globalization {
public override int ToFourDigitYear(int year) {
if (year < 0) {
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
Contract.EndContractBlock();
@@ -564,7 +565,7 @@ namespace System.Globalization {
if (year > MaxCalendarYear) {
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
diff --git a/src/mscorlib/src/System/Globalization/RegionInfo.cs b/src/mscorlib/src/System/Globalization/RegionInfo.cs
index f06d63f1d2..4bed87570f 100644
--- a/src/mscorlib/src/System/Globalization/RegionInfo.cs
+++ b/src/mscorlib/src/System/Globalization/RegionInfo.cs
@@ -19,6 +19,7 @@ namespace System.Globalization {
using System;
using System.Runtime.Serialization;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
[Serializable]
@@ -59,14 +60,13 @@ namespace System.Globalization {
// In Silverlight we enforce that RegionInfos must be created with a full culture name
//
////////////////////////////////////////////////////////////////////////
- [System.Security.SecuritySafeCritical] // auto-generated
public RegionInfo(String name) {
if (name==null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (name.Length == 0) //The InvariantCulture has no matching region
{
- throw new ArgumentException(Environment.GetResourceString("Argument_NoRegionInvariantCulture"), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_NoRegionInvariantCulture"), nameof(name));
}
Contract.EndContractBlock();
@@ -83,19 +83,18 @@ namespace System.Globalization {
throw new ArgumentException(
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("Argument_InvalidCultureName"), name), "name");
+ Environment.GetResourceString("Argument_InvalidCultureName"), name), nameof(name));
// Not supposed to be neutral
if (this.m_cultureData.IsNeutralCulture)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidNeutralRegionName", name), "name");
+ throw new ArgumentException(Environment.GetResourceString("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
- [System.Security.SecuritySafeCritical] // auto-generated
public RegionInfo(int culture)
{
if (culture == CultureInfo.LOCALE_INVARIANT) //The InvariantCulture has no matching region
@@ -106,13 +105,13 @@ namespace System.Globalization {
if (culture == CultureInfo.LOCALE_NEUTRAL)
{
// Not supposed to be neutral
- throw new ArgumentException(Environment.GetResourceString("Argument_CultureIsNeutral", culture), "culture");
+ throw new ArgumentException(Environment.GetResourceString("Argument_CultureIsNeutral", culture), nameof(culture));
}
if (culture == CultureInfo.LOCALE_CUSTOM_DEFAULT)
{
// Not supposed to be neutral
- throw new ArgumentException(Environment.GetResourceString("Argument_CustomCultureCannotBePassedByNumber", culture), "culture");
+ throw new ArgumentException(Environment.GetResourceString("Argument_CustomCultureCannotBePassedByNumber", culture), nameof(culture));
}
this.m_cultureData = CultureData.GetCultureData(culture,true);
@@ -121,34 +120,23 @@ namespace System.Globalization {
if (this.m_cultureData.IsNeutralCulture)
{
// Not supposed to be neutral
- throw new ArgumentException(Environment.GetResourceString("Argument_CultureIsNeutral", culture), "culture");
+ throw new ArgumentException(Environment.GetResourceString("Argument_CultureIsNeutral", culture), nameof(culture));
}
m_cultureId = culture;
}
#endif
- [System.Security.SecuritySafeCritical] // auto-generated
internal RegionInfo(CultureData cultureData)
{
this.m_cultureData = cultureData;
this.m_name = this.m_cultureData.SREGIONNAME;
}
- [System.Security.SecurityCritical] // auto-generated
private void SetName(string name)
{
-#if FEATURE_CORECLR
// Use the name of the region we found
this.m_name = this.m_cultureData.SREGIONNAME;
-#else
- // when creating region by culture name, we keep the region name as the culture name so regions
- // created by custom culture names can be differentiated from built in regions.
- this.m_name = name.Equals(this.m_cultureData.SREGIONNAME, StringComparison.OrdinalIgnoreCase) ?
- this.m_cultureData.SREGIONNAME :
- this.m_cultureData.CultureName;
-#endif // FEATURE_CORECLR
}
-
#region Serialization
//
@@ -163,174 +151,17 @@ namespace System.Globalization {
[OptionalField(VersionAdded = 2)]
internal int m_dataItem = 0;
-#if !FEATURE_CORECLR
- static private readonly int[] IdFromEverettRegionInfoDataItem =
- {
- 0x3801, /* 0 */ // AE ar-AE Arabic (U.A.E.)
- 0x041C, /* 1 */ // AL sq-AL Albanian (Albania)
- 0x042B, /* 2 */ // AM hy-AM Armenian (Armenia)
- 0x2C0A, /* 3 */ // AR es-AR Spanish (Argentina)
- 0x0C07, /* 4 */ // AT de-AT German (Austria)
- 0x0C09, /* 5 */ // AU en-AU English (Australia)
- 0x042C, /* 6 */ // AZ az-AZ-Latn Azeri (Latin) (Azerbaijan)
- // 0x082C, 6, // AZ az-AZ-Cyrl Azeri (Cyrillic) (Azerbaijan)
- 0x080C, /* 7 */ // BE fr-BE French (Belgium)
- // 0x0813, 7, // BE nl-BE Dutch (Belgium)
- 0x0402, /* 8 */ // BG bg-BG Bulgarian (Bulgaria)
- 0x3C01, /* 9 */ // BH ar-BH Arabic (Bahrain)
- 0x083E, /* 10 */ // BN ms-BN Malay (Brunei Darussalam)
- 0x400A, /* 11 */ // BO es-BO Spanish (Bolivia)
- 0x0416, /* 12 */ // BR pt-BR Portuguese (Brazil)
- 0x0423, /* 13 */ // BY be-BY Belarusian (Belarus)
- 0x2809, /* 14 */ // BZ en-BZ English (Belize)
- 0x0C0C, /* 15 */ // CA fr-CA French (Canada)
- // 0x1009, 15, // CA en-CA English (Canada)
- 0x2409, /* 16 */ // CB en-CB English (Caribbean)
- 0x0807, /* 17 */ // CH de-CH German (Switzerland)
- // 0x0810, 17, // CH it-CH Italian (Switzerland)
- // 0x100C, 17, // CH fr-CH French (Switzerland)
- 0x340A, /* 18 */ // CL es-CL Spanish (Chile)
- 0x0804, /* 19 */ // CN zh-CN Chinese (People's Republic of China)
- 0x240A, /* 20 */ // CO es-CO Spanish (Colombia)
- 0x140A, /* 21 */ // CR es-CR Spanish (Costa Rica)
- 0x0405, /* 22 */ // CZ cs-CZ Czech (Czech Republic)
- 0x0407, /* 23 */ // DE de-DE German (Germany)
- 0x0406, /* 24 */ // DK da-DK Danish (Denmark)
- 0x1C0A, /* 25 */ // DO es-DO Spanish (Dominican Republic)
- 0x1401, /* 26 */ // DZ ar-DZ Arabic (Algeria)
- 0x300A, /* 27 */ // EC es-EC Spanish (Ecuador)
- 0x0425, /* 28 */ // EE et-EE Estonian (Estonia)
- 0x0C01, /* 29 */ // EG ar-EG Arabic (Egypt)
- 0x0403, /* 30 */ // ES ca-ES Catalan (Catalan)
- // 0x042D, 30, // ES eu-ES Basque (Basque)
- // 0x0456, 30, // ES gl-ES Galician (Galician)
- // 0x0C0A, 30, // ES es-ES Spanish (Spain)
- 0x040B, /* 31 */ // FI fi-FI Finnish (Finland)
- // 0x081D, 31, // FI sv-FI Swedish (Finland)
- 0x0438, /* 32 */ // FO fo-FO Faroese (Faroe Islands)
- 0x040C, /* 33 */ // FR fr-FR French (France)
- 0x0809, /* 34 */ // GB en-GB English (United Kingdom)
- 0x0437, /* 35 */ // GE ka-GE Georgian (Georgia)
- 0x0408, /* 36 */ // GR el-GR Greek (Greece)
- 0x100A, /* 37 */ // GT es-GT Spanish (Guatemala)
- 0x0C04, /* 38 */ // HK zh-HK Chinese (Hong Kong S.A.R.)
- 0x480A, /* 39 */ // HN es-HN Spanish (Honduras)
- 0x041A, /* 40 */ // HR hr-HR Croatian (Croatia)
- 0x040E, /* 41 */ // HU hu-HU Hungarian (Hungary)
- 0x0421, /* 42 */ // ID id-ID Indonesian (Indonesia)
- 0x1809, /* 43 */ // IE en-IE English (Ireland)
- 0x040D, /* 44 */ // IL he-IL Hebrew (Israel)
- 0x0439, /* 45 */ // IN hi-IN Hindi (India)
- // 0x0446, 45, // IN pa-IN Punjabi (India)
- // 0x0447, 45, // IN gu-IN Gujarati (India)
- // 0x0449, 45, // IN ta-IN Tamil (India)
- // 0x044A, 45, // IN te-IN Telugu (India)
- // 0x044B, 45, // IN kn-IN Kannada (India)
- // 0x044E, 45, // IN mr-IN Marathi (India)
- // 0x044F, 45, // IN sa-IN Sanskrit (India)
- // 0x0457, 45, // IN kok-IN Konkani (India)
- 0x0801, /* 46 */ // IQ ar-IQ Arabic (Iraq)
- 0x0429, /* 47 */ // IR fa-IR (Iran)
- 0x040F, /* 48 */ // IS is-IS Icelandic (Iceland)
- 0x0410, /* 49 */ // IT it-IT Italian (Italy)
- 0x2009, /* 50 */ // JM en-JM English (Jamaica)
- 0x2C01, /* 51 */ // JO ar-JO Arabic (Jordan)
- 0x0411, /* 52 */ // JP ja-JP Japanese (Japan)
- 0x0441, /* 53 */ // KE sw-KE Swahili (Kenya)
- 0x0440, /* 54 */ // KG ky-KG Kyrgyz (Kyrgyzstan)
- 0x0412, /* 55 */ // KR ko-KR Korean (Korea)
- 0x3401, /* 56 */ // KW ar-KW Arabic (Kuwait)
- 0x043F, /* 57 */ // KZ kk-KZ Kazakh (Kazakhstan)
- 0x3001, /* 58 */ // LB ar-LB Arabic (Lebanon)
- 0x1407, /* 59 */ // LI de-LI German (Liechtenstein)
- 0x0427, /* 60 */ // LT lt-LT Lithuanian (Lithuania)
- 0x1007, /* 61 */ // LU de-LU German (Luxembourg)
- // 0x140C, 61, // LU fr-LU French (Luxembourg)
- 0x0426, /* 62 */ // LV lv-LV Latvian (Latvia)
- 0x1001, /* 63 */ // LY ar-LY Arabic (Libya)
- 0x1801, /* 64 */ // MA ar-MA Arabic (Morocco)
- 0x180C, /* 65 */ // MC fr-MC French (Principality of Monaco)
- 0x042F, /* 66 */ // MK mk-MK Macedonian (Macedonia, FYRO)
- 0x0450, /* 67 */ // MN mn-MN Mongolian (Mongolia)
- 0x1404, /* 68 */ // MO zh-MO Chinese (Macau S.A.R.)
- 0x0465, /* 69 */ // MV div-MV Divehi (Maldives)
- 0x080A, /* 70 */ // MX es-MX Spanish (Mexico)
- 0x043E, /* 71 */ // MY ms-MY Malay (Malaysia)
- 0x4C0A, /* 72 */ // NI es-NI Spanish (Nicaragua)
- 0x0413, /* 73 */ // NL nl-NL Dutch (Netherlands)
- 0x0414, /* 74 */ // NO nb-NO Norwegian (Bokm?) (Norway)
- // 0x0814, 74, // NO nn-NO Norwegian (Nynorsk) (Norway)
- 0x1409, /* 75 */ // NZ en-NZ English (New Zealand)
- 0x2001, /* 76 */ // OM ar-OM Arabic (Oman)
- 0x180A, /* 77 */ // PA es-PA Spanish (Panama)
- 0x280A, /* 78 */ // PE es-PE Spanish (Peru)
- 0x3409, /* 79 */ // PH en-PH English (Republic of the Philippines)
- 0x0420, /* 80 */ // PK ur-PK Urdu (Islamic Republic of Pakistan)
- 0x0415, /* 81 */ // PL pl-PL Polish (Poland)
- 0x500A, /* 82 */ // PR es-PR Spanish (Puerto Rico)
- 0x0816, /* 83 */ // PT pt-PT Portuguese (Portugal)
- 0x3C0A, /* 84 */ // PY es-PY Spanish (Paraguay)
- 0x4001, /* 85 */ // QA ar-QA Arabic (Qatar)
- 0x0418, /* 86 */ // RO ro-RO Romanian (Romania)
- 0x0419, /* 87 */ // RU ru-RU Russian (Russia)
- // 0x0444, 87, // RU tt-RU Tatar (Russia)
- 0x0401, /* 88 */ // SA ar-SA Arabic (Saudi Arabia)
- 0x041D, /* 89 */ // SE sv-SE Swedish (Sweden)
- 0x1004, /* 90 */ // SG zh-SG Chinese (Singapore)
- 0x0424, /* 91 */ // SI sl-SI Slovenian (Slovenia)
- 0x041B, /* 92 */ // SK sk-SK Slovak (Slovakia)
- 0x081A, /* 93 */ // SP sr-SP-Latn Serbian (Latin) (Serbia)
- // 0x0C1A, 93, // SP sr-SP-Cyrl Serbian (Cyrillic) (Serbia)
- 0x440A, /* 94 */ // SV es-SV Spanish (El Salvador)
- 0x045A, /* 95 */ // SY syr-SY Syriac (Syria)
- // 0x2801, 95, // SY ar-SY Arabic (Syria)
- 0x041E, /* 96 */ // TH th-TH Thai (Thailand)
- 0x1C01, /* 97 */ // TN ar-TN Arabic (Tunisia)
- 0x041F, /* 98 */ // TR tr-TR Turkish (Turkey)
- 0x2C09, /* 99 */ // TT en-TT English (Trinidad and Tobago)
- 0x0404, /*100 */ // TW zh-TW Chinese (Taiwan)
- 0x0422, /*101 */ // UA uk-UA Ukrainian (Ukraine)
- 0x0409, /*102 */ // US en-US English (United States)
- 0x380A, /*103 */ // UY es-UY Spanish (Uruguay)
- 0x0443, /*104 */ // UZ uz-UZ-Latn Uzbek (Latin) (Uzbekistan)
- // 0x0843, 104 // UZ uz-UZ-Cyrl Uzbek (Cyrillic) (Uzbekistan)
- 0x200A, /*105*/ // VE es-VE Spanish (Venezuela)
- 0x042A, /*106*/ // VN vi-VN Vietnamese (Viet Nam)
- 0x2401, /*107*/ // YE ar-YE Arabic (Yemen)
- 0x0436, /*108*/ // ZA af-ZA Afrikaans (South Africa)
- // 0x1C09, 108, // ZA en-ZA English (South Africa)
- 0x3009, /*109*/ // ZW en-ZW English (Zimbabwe)
- };
-#endif
- [System.Security.SecurityCritical] // auto-generated
[OnDeserialized]
private void OnDeserialized(StreamingContext ctx)
{
-#if FEATURE_CORECLR
// This won't happen anyway since CoreCLR doesn't support serialization
this.m_cultureData = CultureData.GetCultureData(m_name, true);
-#else
- if (m_name == null)
- {
- Contract.Assert(m_dataItem >= 0, "[RegionInfo.OnDeserialized] null name and invalid dataItem");
- m_cultureId = IdFromEverettRegionInfoDataItem[m_dataItem];
- }
- if (m_cultureId == 0)
- {
- this.m_cultureData = CultureData.GetCultureDataForRegion(this.m_name, true);
- }
- else
- {
- this.m_cultureData = CultureData.GetCultureData(m_cultureId, true);
- }
-
-#endif
if (this.m_cultureData == null)
throw new ArgumentException(
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("Argument_InvalidCultureName"), m_name), "m_name");
+ Environment.GetResourceString("Argument_InvalidCultureName"), m_name), nameof(m_name));
if (m_cultureId == 0)
{
@@ -359,7 +190,6 @@ namespace System.Globalization {
//
////////////////////////////////////////////////////////////////////////
public static RegionInfo CurrentRegion {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
RegionInfo temp = s_currentRegionInfo;
if (temp == null)
@@ -383,7 +213,7 @@ namespace System.Globalization {
////////////////////////////////////////////////////////////////////////
public virtual String Name {
get {
- Contract.Assert(m_name != null, "Expected RegionInfo.m_name to be populated already");
+ Debug.Assert(m_name != null, "Expected RegionInfo.m_name to be populated already");
return (m_name);
}
}
@@ -397,7 +227,6 @@ namespace System.Globalization {
////////////////////////////////////////////////////////////////////////
public virtual String EnglishName
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
return (this.m_cultureData.SENGCOUNTRY);
@@ -415,7 +244,6 @@ namespace System.Globalization {
////////////////////////////////////////////////////////////////////////
public virtual String DisplayName
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
return (this.m_cultureData.SLOCALIZEDCOUNTRY);
@@ -434,7 +262,6 @@ namespace System.Globalization {
[System.Runtime.InteropServices.ComVisible(false)]
public virtual String NativeName
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
return (this.m_cultureData.SNATIVECOUNTRY);
@@ -450,7 +277,6 @@ namespace System.Globalization {
////////////////////////////////////////////////////////////////////////
public virtual String TwoLetterISORegionName
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
return (this.m_cultureData.SISO3166CTRYNAME);
@@ -467,7 +293,6 @@ namespace System.Globalization {
////////////////////////////////////////////////////////////////////////
public virtual String ThreeLetterISORegionName
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
return (this.m_cultureData.SISO3166CTRYNAME2);
@@ -483,7 +308,6 @@ namespace System.Globalization {
////////////////////////////////////////////////////////////////////////
public virtual String ThreeLetterWindowsRegionName
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
return (this.m_cultureData.SABBREVCTRYNAME);
@@ -524,7 +348,6 @@ namespace System.Globalization {
[System.Runtime.InteropServices.ComVisible(false)]
public virtual String CurrencyEnglishName
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
return (this.m_cultureData.SENGLISHCURRENCY);
@@ -542,7 +365,6 @@ namespace System.Globalization {
[System.Runtime.InteropServices.ComVisible(false)]
public virtual String CurrencyNativeName
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
return (this.m_cultureData.SNATIVECURRENCY);
@@ -557,7 +379,6 @@ namespace System.Globalization {
//
////////////////////////////////////////////////////////////////////////
public virtual String CurrencySymbol {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
return (this.m_cultureData.SCURRENCY);
}
@@ -571,7 +392,6 @@ namespace System.Globalization {
//
////////////////////////////////////////////////////////////////////////
public virtual String ISOCurrencySymbol {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
return (this.m_cultureData.SINTLSYMBOL);
}
diff --git a/src/mscorlib/src/System/Globalization/SortKey.cs b/src/mscorlib/src/System/Globalization/SortKey.cs
index e3308dc4f8..9c35f485e5 100644
--- a/src/mscorlib/src/System/Globalization/SortKey.cs
+++ b/src/mscorlib/src/System/Globalization/SortKey.cs
@@ -16,6 +16,7 @@ namespace System.Globalization {
using System;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
[System.Runtime.InteropServices.ComVisible(true)]
@@ -119,15 +120,15 @@ namespace System.Globalization {
public static int Compare(SortKey sortkey1, SortKey sortkey2) {
if (sortkey1==null || sortkey2==null) {
- throw new ArgumentNullException((sortkey1==null ? "sortkey1": "sortkey2"));
+ throw new ArgumentNullException((sortkey1==null ? nameof(sortkey1): nameof(sortkey2)));
}
Contract.EndContractBlock();
byte[] key1Data = sortkey1.m_KeyData;
byte[] key2Data = sortkey2.m_KeyData;
- Contract.Assert(key1Data!=null, "key1Data!=null");
- Contract.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) {
diff --git a/src/mscorlib/src/System/Globalization/StringInfo.cs b/src/mscorlib/src/System/Globalization/StringInfo.cs
index b1151bde4f..d86e11592e 100644
--- a/src/mscorlib/src/System/Globalization/StringInfo.cs
+++ b/src/mscorlib/src/System/Globalization/StringInfo.cs
@@ -17,6 +17,7 @@ namespace System.Globalization {
using System;
using System.Runtime.Serialization;
using System.Security.Permissions;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
[Serializable]
@@ -92,7 +93,7 @@ namespace System.Globalization {
}
set {
if (null == value) {
- throw new ArgumentNullException("String",
+ throw new ArgumentNullException(nameof(String),
Environment.GetResourceString("ArgumentNull_String"));
}
Contract.EndContractBlock();
@@ -118,11 +119,11 @@ namespace System.Globalization {
if(null == this.Indexes) {
// Just decide which error to give depending on the param they gave us....
if(startingTextElement < 0) {
- throw new ArgumentOutOfRangeException("startingTextElement",
+ throw new ArgumentOutOfRangeException(nameof(startingTextElement),
Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
}
else {
- throw new ArgumentOutOfRangeException("startingTextElement",
+ throw new ArgumentOutOfRangeException(nameof(startingTextElement),
Environment.GetResourceString("Arg_ArgumentOutOfRangeException"));
}
}
@@ -135,22 +136,22 @@ namespace System.Globalization {
// Parameter checking
//
if(startingTextElement < 0) {
- throw new ArgumentOutOfRangeException("startingTextElement",
+ throw new ArgumentOutOfRangeException(nameof(startingTextElement),
Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
}
if(this.String.Length == 0 || startingTextElement >= this.Indexes.Length) {
- throw new ArgumentOutOfRangeException("startingTextElement",
+ throw new ArgumentOutOfRangeException(nameof(startingTextElement),
Environment.GetResourceString("Arg_ArgumentOutOfRangeException"));
}
if(lengthInTextElements < 0) {
- throw new ArgumentOutOfRangeException("lengthInTextElements",
+ throw new ArgumentOutOfRangeException(nameof(lengthInTextElements),
Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
}
if(startingTextElement > this.Indexes.Length - lengthInTextElements) {
- throw new ArgumentOutOfRangeException("lengthInTextElements",
+ throw new ArgumentOutOfRangeException(nameof(lengthInTextElements),
Environment.GetResourceString("Arg_ArgumentOutOfRangeException"));
}
@@ -206,8 +207,8 @@ namespace System.Globalization {
internal static int GetCurrentTextElementLen(String str, int index, int len, ref UnicodeCategory ucCurrent, ref int currentCharCount)
{
- Contract.Assert(index >= 0 && len >= 0, "StringInfo.GetCurrentTextElementLen() : index = " + index + ", len = " + len);
- Contract.Assert(index < len, "StringInfo.GetCurrentTextElementLen() : index = " + index + ", len = " + len);
+ 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.
@@ -268,7 +269,7 @@ namespace System.Globalization {
// Validate parameters.
//
if (str==null) {
- throw new ArgumentNullException("str");
+ throw new ArgumentNullException(nameof(str));
}
Contract.EndContractBlock();
@@ -277,7 +278,7 @@ namespace System.Globalization {
if (index == len) {
return (String.Empty);
}
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
int charLen;
@@ -297,14 +298,14 @@ namespace System.Globalization {
//
if (str==null)
{
- throw new ArgumentNullException("str");
+ throw new ArgumentNullException(nameof(str));
}
Contract.EndContractBlock();
int len = str.Length;
if (index < 0 || (index > len))
{
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
return (new TextElementEnumerator(str, index, len));
@@ -326,7 +327,7 @@ namespace System.Globalization {
{
if (str == null)
{
- throw new ArgumentNullException("str");
+ throw new ArgumentNullException(nameof(str));
}
Contract.EndContractBlock();
diff --git a/src/mscorlib/src/System/Globalization/TaiwanCalendar.cs b/src/mscorlib/src/System/Globalization/TaiwanCalendar.cs
index 013e2cd50e..476ddeef7c 100644
--- a/src/mscorlib/src/System/Globalization/TaiwanCalendar.cs
+++ b/src/mscorlib/src/System/Globalization/TaiwanCalendar.cs
@@ -241,14 +241,14 @@ namespace System.Globalization {
public override int ToFourDigitYear(int year) {
if (year <= 0) {
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
}
Contract.EndContractBlock();
if (year > helper.MaxYear) {
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
diff --git a/src/mscorlib/src/System/Globalization/TextElementEnumerator.cs b/src/mscorlib/src/System/Globalization/TextElementEnumerator.cs
index 5f47f5fbd4..049ccf6f81 100644
--- a/src/mscorlib/src/System/Globalization/TextElementEnumerator.cs
+++ b/src/mscorlib/src/System/Globalization/TextElementEnumerator.cs
@@ -15,6 +15,7 @@ using System.Runtime.Serialization;
namespace System.Globalization {
using System.Collections;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
//
@@ -43,9 +44,9 @@ namespace System.Globalization {
internal TextElementEnumerator(String str, int startIndex, int strLen)
{
- Contract.Assert(str != null, "TextElementEnumerator(): str != null");
- Contract.Assert(startIndex >= 0 && strLen >= 0, "TextElementEnumerator(): startIndex >= 0 && strLen >= 0");
- Contract.Assert(strLen >= startIndex, "TextElementEnumerator(): strLen >= startIndex");
+ 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;
diff --git a/src/mscorlib/src/System/Globalization/TextInfo.cs b/src/mscorlib/src/System/Globalization/TextInfo.cs
index 9b84486f4e..c8108e4922 100644
--- a/src/mscorlib/src/System/Globalization/TextInfo.cs
+++ b/src/mscorlib/src/System/Globalization/TextInfo.cs
@@ -24,6 +24,7 @@ namespace System.Globalization {
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security.Permissions;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
@@ -106,11 +107,6 @@ namespace System.Globalization {
this.m_cultureData = cultureData;
this.m_cultureName = this.m_cultureData.CultureName;
this.m_textInfoName = this.m_cultureData.STEXTINFO;
-#if !FEATURE_CORECLR
- IntPtr handleOrigin;
- this.m_dataHandle = CompareInfo.InternalInitSortHandle(m_textInfoName, out handleOrigin);
- this.m_handleOrigin = handleOrigin;
-#endif
}
////////////////////////////////////////////////////////////////////////
@@ -179,30 +175,18 @@ namespace System.Globalization {
// 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;
-#if !FEATURE_CORECLR
- IntPtr handleOrigin;
- this.m_dataHandle = CompareInfo.InternalInitSortHandle(m_textInfoName, out handleOrigin);
- this.m_handleOrigin = handleOrigin;
-#endif
- }
+ }
}
-
[OnDeserialized]
private void OnDeserialized(StreamingContext ctx)
{
OnDeserialized();
- }
-
+ }
+
[OnSerializing]
private void OnSerializing(StreamingContext ctx)
- {
-#if !FEATURE_CORECLR
- // Initialize the fields Whidbey expects:
- // Whidbey expected this, so set it, but the value doesn't matter much
- this.m_useUserOverride = false;
-#endif // FEATURE_CORECLR
-
+ {
// Relabel our name since Whidbey expects it to be called customCultureName
this.customCultureName = this.m_cultureName;
@@ -229,7 +213,6 @@ namespace System.Globalization {
return (Invariant.GetCaseInsensitiveHashCode(s, forceRandomizedHashing, additionalEntropy));
}
- [System.Security.SecuritySafeCritical]
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);
@@ -237,7 +220,6 @@ namespace System.Globalization {
// This function doesn't check arguments. Please do check in the caller.
// The underlying unmanaged code will assert the sanity of arguments.
- [System.Security.SecuritySafeCritical] // auto-generated
internal static unsafe int CompareOrdinalIgnoreCase(String str1, String str2)
{
// Compare the whole string and ignore case.
@@ -246,19 +228,18 @@ namespace System.Globalization {
// This function doesn't check arguments. Please do check in the caller.
// The underlying unmanaged code will assert the sanity of arguments.
- [System.Security.SecuritySafeCritical] // auto-generated
internal static unsafe int CompareOrdinalIgnoreCaseEx(String strA, int indexA, String strB, int indexB, int lengthA, int lengthB )
{
- Contract.Assert(strA.Length >= indexA + lengthA, "[TextInfo.CompareOrdinalIgnoreCaseEx] Caller should've validated strA.Length >= indexA + lengthA");
- Contract.Assert(strB.Length >= indexB + lengthB, "[TextInfo.CompareOrdinalIgnoreCaseEx] Caller should've validated strB.Length >= indexB + 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);
}
internal static int IndexOfStringOrdinalIgnoreCase(String source, String value, int startIndex, int count)
{
- Contract.Assert(source != null, "[TextInfo.IndexOfStringOrdinalIgnoreCase] Caller should've validated source != null");
- Contract.Assert(value != null, "[TextInfo.IndexOfStringOrdinalIgnoreCase] Caller should've validated value != null");
- Contract.Assert(startIndex + count <= source.Length, "[TextInfo.IndexOfStringOrdinalIgnoreCase] Caller should've validated startIndex + count <= source.Length");
+ 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)
@@ -285,7 +266,7 @@ namespace System.Globalization {
for (; startIndex <= maxStartIndex; startIndex++)
{
// We should always have the same or more characters left to search than our actual pattern
- Contract.Assert(end - startIndex >= value.Length);
+ 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)
{
@@ -299,10 +280,10 @@ namespace System.Globalization {
internal static int LastIndexOfStringOrdinalIgnoreCase(String source, String value, int startIndex, int count)
{
- Contract.Assert(source != null, "[TextInfo.LastIndexOfStringOrdinalIgnoreCase] Caller should've validated source != null");
- Contract.Assert(value != null, "[TextInfo.LastIndexOfStringOrdinalIgnoreCase] Caller should've validated value != null");
- Contract.Assert(startIndex - count+1 >= 0, "[TextInfo.LastIndexOfStringOrdinalIgnoreCase] Caller should've validated startIndex - count+1 >= 0");
- Contract.Assert(startIndex <= source.Length, "[TextInfo.LastIndexOfStringOrdinalIgnoreCase] Caller should've validated startIndex <= source.Length");
+ 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)
@@ -462,7 +443,7 @@ namespace System.Globalization {
[System.Runtime.InteropServices.ComVisible(false)]
public static TextInfo ReadOnly(TextInfo textInfo)
{
- if (textInfo == null) { throw new ArgumentNullException("textInfo"); }
+ if (textInfo == null) { throw new ArgumentNullException(nameof(textInfo)); }
Contract.EndContractBlock();
if (textInfo.IsReadOnly) { return (textInfo); }
@@ -498,7 +479,6 @@ namespace System.Globalization {
public virtual String ListSeparator
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
if (m_listSeparator == null) {
@@ -512,7 +492,7 @@ namespace System.Globalization {
{
if (value == null)
{
- throw new ArgumentNullException("value", Environment.GetResourceString("ArgumentNull_String"));
+ throw new ArgumentNullException(nameof(value), Environment.GetResourceString("ArgumentNull_String"));
}
Contract.EndContractBlock();
VerifyWritable();
@@ -529,7 +509,6 @@ namespace System.Globalization {
//
////////////////////////////////////////////////////////////////////////
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe virtual char ToLower(char c)
{
if(IsAscii(c) && IsAsciiCasingSameAsInvariant)
@@ -539,10 +518,9 @@ namespace System.Globalization {
return (InternalChangeCaseChar(this.m_dataHandle, this.m_handleOrigin, this.m_textInfoName, c, false));
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe virtual String ToLower(String str)
{
- if (str == null) { throw new ArgumentNullException("str"); }
+ if (str == null) { throw new ArgumentNullException(nameof(str)); }
Contract.EndContractBlock();
return InternalChangeCaseString(this.m_dataHandle, this.m_handleOrigin, this.m_textInfoName, str, false);
@@ -567,7 +545,6 @@ namespace System.Globalization {
//
////////////////////////////////////////////////////////////////////////
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe virtual char ToUpper(char c)
{
if (IsAscii(c) && IsAsciiCasingSameAsInvariant)
@@ -578,10 +555,9 @@ namespace System.Globalization {
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe virtual String ToUpper(String str)
{
- if (str == null) { throw new ArgumentNullException("str"); }
+ if (str == null) { throw new ArgumentNullException(nameof(str)); }
Contract.EndContractBlock();
return InternalChangeCaseString(this.m_dataHandle, this.m_handleOrigin, this.m_textInfoName, str, true);
}
@@ -698,7 +674,7 @@ namespace System.Globalization {
{
if (str == null)
{
- throw new ArgumentNullException("str");
+ throw new ArgumentNullException(nameof(str));
}
Contract.EndContractBlock();
if (str.Length == 0)
@@ -809,7 +785,7 @@ namespace System.Globalization {
private static int AddNonLetter(ref StringBuilder result, ref String input, int inputIndex, int charLen)
{
- Contract.Assert(charLen == 1 || charLen == 2, "[TextInfo.AddNonLetter] CharUnicodeInfo.InternalGetUnicodeCategory returned an unexpected charLen!");
+ Debug.Assert(charLen == 1 || charLen == 2, "[TextInfo.AddNonLetter] CharUnicodeInfo.InternalGetUnicodeCategory returned an unexpected charLen!");
if (charLen == 2)
{
// Surrogate pair
@@ -826,7 +802,7 @@ namespace System.Globalization {
private int AddTitlecaseLetter(ref StringBuilder result, ref String input, int inputIndex, int charLen)
{
- Contract.Assert(charLen == 1 || charLen == 2, "[TextInfo.AddTitlecaseLetter] CharUnicodeInfo.InternalGetUnicodeCategory returned an unexpected 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)
@@ -947,19 +923,17 @@ namespace System.Globalization {
// is not null before calling this. Currenlty, CaseInsensitiveHashCodeProvider
// does that.
//
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe int GetCaseInsensitiveHashCode(String str)
{
return GetCaseInsensitiveHashCode(str, false, 0);
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe int GetCaseInsensitiveHashCode(String str, bool forceRandomizedHashing, long additionalEntropy)
{
// Validate inputs
if (str==null)
{
- throw new ArgumentNullException("str");
+ throw new ArgumentNullException(nameof(str));
}
Contract.EndContractBlock();
@@ -968,23 +942,19 @@ namespace System.Globalization {
}
// Change case (ToUpper/ToLower) -- COMNlsInfo::InternalChangeCaseChar
- [System.Security.SecurityCritical] // auto-generated
[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
- [System.Security.SecurityCritical] // auto-generated
[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
- [System.Security.SecurityCritical] // auto-generated
[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)
- [System.Security.SecurityCritical] // auto-generated
[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);
@@ -992,7 +962,6 @@ namespace System.Globalization {
// 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
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
diff --git a/src/mscorlib/src/System/Globalization/ThaiBuddhistCalendar.cs b/src/mscorlib/src/System/Globalization/ThaiBuddhistCalendar.cs
index f26c68adce..e294b51325 100644
--- a/src/mscorlib/src/System/Globalization/ThaiBuddhistCalendar.cs
+++ b/src/mscorlib/src/System/Globalization/ThaiBuddhistCalendar.cs
@@ -213,7 +213,7 @@ namespace System.Globalization {
public override int ToFourDigitYear(int year) {
if (year < 0) {
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
Contract.EndContractBlock();
diff --git a/src/mscorlib/src/System/Globalization/TimeSpanFormat.cs b/src/mscorlib/src/System/Globalization/TimeSpanFormat.cs
index 8f58623868..e5e615f1b3 100644
--- a/src/mscorlib/src/System/Globalization/TimeSpanFormat.cs
+++ b/src/mscorlib/src/System/Globalization/TimeSpanFormat.cs
@@ -6,12 +6,12 @@
namespace System.Globalization {
using System.Text;
using System;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Globalization;
internal static class TimeSpanFormat {
- [System.Security.SecuritySafeCritical] // auto-generated
private static String IntToString(int n, int digits) {
return ParseNumbers.IntToString(n, 10, digits, '0', 0);
}
@@ -143,7 +143,7 @@ namespace System.Globalization {
//
internal static String FormatCustomized(TimeSpan value, String format, DateTimeFormatInfo dtfi) {
- Contract.Assert(dtfi != null, "dtfi == null");
+ Debug.Assert(dtfi != null, "dtfi == null");
int day = (int)(value._ticks / TimeSpan.TicksPerDay);
long time = value._ticks % TimeSpan.TicksPerDay;
@@ -369,7 +369,7 @@ namespace System.Globalization {
case '\"':
if (inQuote && (quote == format[i])) {
/* we were in a quote and found a matching exit quote, so we are outside a quote now */
- Contract.Assert(field >= 0 && field <= 5, "field >= 0 && field <= 5");
+ Debug.Assert(field >= 0 && field <= 5, "field >= 0 && field <= 5");
if (field >= 0 && field <= 5) {
literals[field] = sb.ToString();
sb.Length = 0;
@@ -389,7 +389,7 @@ namespace System.Globalization {
}
break;
case '%':
- Contract.Assert(false, "Unexpected special token '%', Bug in DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern");
+ Debug.Assert(false, "Unexpected special token '%', Bug in DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern");
goto default;
case '\\':
if (!inQuote) {
@@ -399,7 +399,7 @@ namespace System.Globalization {
goto default;
case 'd':
if (!inQuote) {
- Contract.Assert((field == 0 && sb.Length == 0) || field == 1,
+ Debug.Assert((field == 0 && sb.Length == 0) || field == 1,
"field == 0 || field == 1, Bug in DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern");
field = 1; // DayHourSep
dd++;
@@ -407,7 +407,7 @@ namespace System.Globalization {
break;
case 'h':
if (!inQuote) {
- Contract.Assert((field == 1 && sb.Length == 0) || field == 2,
+ Debug.Assert((field == 1 && sb.Length == 0) || field == 2,
"field == 1 || field == 2, Bug in DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern");
field = 2; // HourMinuteSep
hh++;
@@ -415,7 +415,7 @@ namespace System.Globalization {
break;
case 'm':
if (!inQuote) {
- Contract.Assert((field == 2 && sb.Length == 0) || field == 3,
+ Debug.Assert((field == 2 && sb.Length == 0) || field == 3,
"field == 2 || field == 3, Bug in DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern");
field = 3; // MinuteSecondSep
mm++;
@@ -423,7 +423,7 @@ namespace System.Globalization {
break;
case 's':
if (!inQuote) {
- Contract.Assert((field == 3 && sb.Length == 0) || field == 4,
+ Debug.Assert((field == 3 && sb.Length == 0) || field == 4,
"field == 3 || field == 4, Bug in DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern");
field = 4; // SecondFractionSep
ss++;
@@ -432,7 +432,7 @@ namespace System.Globalization {
case 'f':
case 'F':
if (!inQuote) {
- Contract.Assert((field == 4 && sb.Length == 0) || field == 5,
+ Debug.Assert((field == 4 && sb.Length == 0) || field == 5,
"field == 4 || field == 5, Bug in DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern");
field = 5; // End
ff++;
@@ -444,14 +444,14 @@ namespace System.Globalization {
}
}
- Contract.Assert(field == 5);
+ Debug.Assert(field == 5);
AppCompatLiteral = MinuteSecondSep + SecondFractionSep;
- Contract.Assert(0 < dd && dd < 3, "0 < dd && dd < 3, Bug in System.Globalization.DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern");
- Contract.Assert(0 < hh && hh < 3, "0 < hh && hh < 3, Bug in System.Globalization.DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern");
- Contract.Assert(0 < mm && mm < 3, "0 < mm && mm < 3, Bug in System.Globalization.DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern");
- Contract.Assert(0 < ss && ss < 3, "0 < ss && ss < 3, Bug in System.Globalization.DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern");
- Contract.Assert(0 < ff && ff < 8, "0 < ff && ff < 8, Bug in System.Globalization.DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern");
+ Debug.Assert(0 < dd && dd < 3, "0 < dd && dd < 3, Bug in System.Globalization.DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern");
+ Debug.Assert(0 < hh && hh < 3, "0 < hh && hh < 3, Bug in System.Globalization.DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern");
+ Debug.Assert(0 < mm && mm < 3, "0 < mm && mm < 3, Bug in System.Globalization.DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern");
+ 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) {
dd = 2;
diff --git a/src/mscorlib/src/System/Globalization/TimeSpanParse.cs b/src/mscorlib/src/System/Globalization/TimeSpanParse.cs
index e72e582a97..d83c5fa151 100644
--- a/src/mscorlib/src/System/Globalization/TimeSpanParse.cs
+++ b/src/mscorlib/src/System/Globalization/TimeSpanParse.cs
@@ -53,6 +53,7 @@
namespace System.Globalization {
using System.Text;
using System;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Globalization;
@@ -126,10 +127,10 @@ namespace System.Globalization {
}
public bool IsInvalidNumber(int maxValue, int maxPrecision) {
- Contract.Assert(ttt == TTT.Num);
- Contract.Assert(num > -1);
- Contract.Assert(maxValue > 0);
- Contract.Assert(maxPrecision == maxFractionDigits || maxPrecision == unlimitedDigits);
+ Debug.Assert(ttt == TTT.Num);
+ Debug.Assert(num > -1);
+ Debug.Assert(maxValue > 0);
+ Debug.Assert(maxPrecision == maxFractionDigits || maxPrecision == unlimitedDigits);
if (num > maxValue)
return true;
@@ -163,7 +164,7 @@ namespace System.Globalization {
}
// used by the parsing routines that operate on standard-formats
internal TimeSpanToken GetNextToken() {
- Contract.Assert(m_pos > -1);
+ Debug.Assert(m_pos > -1);
TimeSpanToken tok = new TimeSpanToken();
char ch = CurrentChar;
@@ -374,7 +375,7 @@ namespace System.Globalization {
private const int MaxNumericTokens = 5;
internal void Init(DateTimeFormatInfo dtfi) {
- Contract.Assert(dtfi != null);
+ Debug.Assert(dtfi != null);
lastSeenTTT = TTT.None;
tokenCount = 0;
@@ -416,7 +417,7 @@ namespace System.Globalization {
}
lastSeenTTT = tok.ttt;
- Contract.Assert(tokenCount == (SepCount + NumCount), "tokenCount == (SepCount + NumCount)");
+ Debug.Assert(tokenCount == (SepCount + NumCount), "tokenCount == (SepCount + NumCount)");
return true;
}
@@ -486,7 +487,7 @@ namespace System.Globalization {
return new OverflowException(Environment.GetResourceString(m_failureMessageID));
default:
- Contract.Assert(false, "Unknown TimeSpanParseFailure: " + m_failure);
+ Debug.Assert(false, "Unknown TimeSpanParseFailure: " + m_failure);
return new FormatException(Environment.GetResourceString("Format_InvalidString"));
}
}
@@ -627,7 +628,7 @@ namespace System.Globalization {
//
private static Boolean TryParseTimeSpan(String input, TimeSpanStandardStyles style, IFormatProvider formatProvider, ref TimeSpanResult result) {
if (input == null) {
- result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, "input");
+ result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(input));
return false;
}
@@ -1117,11 +1118,11 @@ namespace System.Globalization {
//
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, "input");
+ result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(input));
return false;
}
if (format == null) {
- result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, "format");
+ result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(format));
return false;
}
if (format.Length == 0) {
@@ -1158,8 +1159,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) {
- Contract.Assert(input != null, "input != null");
- Contract.Assert(format != null, "format != null");
+ Debug.Assert(input != null, "input != null");
+ Debug.Assert(format != null, "format != null");
bool seenDD = false; // already processed days?
bool seenHH = false; // already processed hours?
@@ -1376,7 +1377,7 @@ namespace System.Globalization {
result.parsedTimeSpan._ticks = 0;
if (input == null) {
- result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, "input");
+ result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(input));
return false;
}
str = input;
@@ -1511,11 +1512,11 @@ namespace System.Globalization {
//
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, "input");
+ result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(input));
return false;
}
if (formats == null) {
- result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, "formats");
+ result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(formats));
return false;
}
diff --git a/src/mscorlib/src/System/Globalization/UmAlQuraCalendar.cs b/src/mscorlib/src/System/Globalization/UmAlQuraCalendar.cs
index 94b235085e..06e7c7d75a 100644
--- a/src/mscorlib/src/System/Globalization/UmAlQuraCalendar.cs
+++ b/src/mscorlib/src/System/Globalization/UmAlQuraCalendar.cs
@@ -4,6 +4,7 @@
namespace System.Globalization {
using System;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
@@ -338,9 +339,9 @@ namespace System.Globalization {
=========================ConvertHijriToGregorian============================*/
static void ConvertHijriToGregorian(int HijriYear, int HijriMonth, int HijriDay, ref int yg, ref int mg, ref int dg)
{
- Contract.Assert( (HijriYear >= MinCalendarYear) && (HijriYear <= MaxCalendarYear), "Hijri year is out of range.");
- Contract.Assert( HijriMonth >= 1, "Hijri month is out of range.");
- Contract.Assert( HijriDay >= 1, "Hijri day is out of range.");
+ 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;
@@ -392,7 +393,7 @@ namespace System.Globalization {
static internal void CheckEraRange(int era) {
if (era != CurrentEra && era != UmAlQuraEra) {
- throw new ArgumentOutOfRangeException("era", Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
}
}
@@ -400,7 +401,7 @@ namespace System.Globalization {
CheckEraRange(era);
if (year < MinCalendarYear || year > MaxCalendarYear) {
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -412,7 +413,7 @@ namespace System.Globalization {
static internal void CheckYearMonthRange(int year, int month, int era) {
CheckYearRange(year, era);
if (month < 1 || month > 12) {
- throw new ArgumentOutOfRangeException("month", Environment.GetResourceString("ArgumentOutOfRange_Month"));
+ throw new ArgumentOutOfRangeException(nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Month"));
}
}
@@ -430,7 +431,7 @@ namespace System.Globalization {
TimeSpan ts;
int yh1=0, mh1=0, dh1=0;
- Contract.Assert((time.Ticks >= minDate.Ticks) && (time.Ticks <= maxDate.Ticks), "Gregorian date is out of range.");
+ 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.
@@ -528,7 +529,7 @@ namespace System.Globalization {
public override DateTime AddMonths(DateTime time, int months) {
if (months < -120000 || months > 120000) {
throw new ArgumentOutOfRangeException(
- "months",
+ nameof(months),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -631,7 +632,7 @@ namespace System.Globalization {
{
int days = 0, b;
- Contract.Assert( (year >= MinCalendarYear) && (year <= MaxCalendarYear), "Hijri year is out of range.");
+ Debug.Assert( (year >= MinCalendarYear) && (year <= MaxCalendarYear), "Hijri year is out of range.");
b = HijriYearInfo[year-MinCalendarYear].HijriMonthsLengthFlags;
@@ -640,7 +641,7 @@ namespace System.Globalization {
days += 29 + (b & 0x1);
b = b >> 1;
}
- Contract.Assert((days == 354)||(days == 355), "Hijri year has to be 354 or 355 days.");
+ Debug.Assert((days == 354)||(days == 355), "Hijri year has to be 354 or 355 days.");
return days;
}
@@ -712,7 +713,7 @@ namespace System.Globalization {
int daysInMonth = GetDaysInMonth(year, month, era);
if (day < 1 || day > daysInMonth) {
throw new ArgumentOutOfRangeException(
- "day",
+ nameof(day),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Day"),
@@ -774,7 +775,7 @@ namespace System.Globalization {
if (day < 1 || day > daysInMonth) {
BCLDebug.Log("year = " + year + ", month = " + month + ", day = " + day);
throw new ArgumentOutOfRangeException(
- "day",
+ nameof(day),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Day"),
@@ -806,7 +807,7 @@ DayInRang:
set {
if (value != 99 && (value < MinCalendarYear || value > MaxCalendarYear)) {
throw new ArgumentOutOfRangeException(
- "value",
+ nameof(value),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
@@ -824,7 +825,7 @@ DayInRang:
public override int ToFourDigitYear(int year) {
if (year < 0) {
- throw new ArgumentOutOfRangeException("year",
+ throw new ArgumentOutOfRangeException(nameof(year),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
Contract.EndContractBlock();
@@ -835,7 +836,7 @@ DayInRang:
if ((year < MinCalendarYear) || (year > MaxCalendarYear)) {
throw new ArgumentOutOfRangeException(
- "year",
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
Environment.GetResourceString("ArgumentOutOfRange_Range"),
diff --git a/src/mscorlib/src/System/Guid.cs b/src/mscorlib/src/System/Guid.cs
index 1ccabeb8db..e2e36ba1b2 100644
--- a/src/mscorlib/src/System/Guid.cs
+++ b/src/mscorlib/src/System/Guid.cs
@@ -10,6 +10,7 @@ namespace System {
using Microsoft.Win32;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
// Represents a Globally Unique Identifier.
@@ -47,9 +48,9 @@ namespace System {
public Guid(byte[] b)
{
if (b==null)
- throw new ArgumentNullException("b");
+ throw new ArgumentNullException(nameof(b));
if (b.Length != 16)
- throw new ArgumentException(Environment.GetResourceString("Arg_GuidArrayCtor", "16"), "b");
+ throw new ArgumentException(Environment.GetResourceString("Arg_GuidArrayCtor", "16"), nameof(b));
Contract.EndContractBlock();
_a = ((int)b[3] << 24) | ((int)b[2] << 16) | ((int)b[1] << 8) | b[0];
@@ -87,10 +88,10 @@ namespace System {
public Guid(int a, short b, short c, byte[] d)
{
if (d==null)
- throw new ArgumentNullException("d");
+ throw new ArgumentNullException(nameof(d));
// Check that array is not too big
if(d.Length != 8)
- throw new ArgumentException(Environment.GetResourceString("Arg_GuidArrayCtor", "8"), "d");
+ throw new ArgumentException(Environment.GetResourceString("Arg_GuidArrayCtor", "8"), nameof(d));
Contract.EndContractBlock();
_a = a;
@@ -185,7 +186,7 @@ namespace System {
}
internal void SetFailure(ParseFailureKind failure, string failureMessageID, object failureMessageFormatArgument,
string failureArgumentName, Exception innerException) {
- Contract.Assert(failure != ParseFailureKind.NativeException, "ParseFailureKind.NativeException should not be used with this overload");
+ Debug.Assert(failure != ParseFailureKind.NativeException, "ParseFailureKind.NativeException should not be used with this overload");
m_failure = failure;
m_failureMessageID = failureMessageID;
m_failureMessageFormatArgument = failureMessageFormatArgument;
@@ -214,7 +215,7 @@ namespace System {
return m_innerException;
default:
- Contract.Assert(false, "Unknown GuidParseFailure: " + m_failure);
+ Debug.Assert(false, "Unknown GuidParseFailure: " + m_failure);
return new FormatException(Environment.GetResourceString("Format_GuidUnrecognized"));
}
}
@@ -231,7 +232,7 @@ namespace System {
public Guid(String g)
{
if (g==null) {
- throw new ArgumentNullException("g");
+ throw new ArgumentNullException(nameof(g));
}
Contract.EndContractBlock();
this = Guid.Empty;
@@ -250,7 +251,7 @@ namespace System {
public static Guid Parse(String input)
{
if (input == null) {
- throw new ArgumentNullException("input");
+ throw new ArgumentNullException(nameof(input));
}
Contract.EndContractBlock();
@@ -281,10 +282,10 @@ namespace System {
public static Guid ParseExact(String input, String format)
{
if (input == null)
- throw new ArgumentNullException("input");
+ throw new ArgumentNullException(nameof(input));
if (format == null)
- throw new ArgumentNullException("format");
+ throw new ArgumentNullException(nameof(format));
if( format.Length != 1) {
// all acceptable format strings are of length 1
@@ -752,17 +753,14 @@ namespace System {
//
// StringToShort, StringToInt, and StringToLong are wrappers around COMUtilNative integer parsing routines;
- [System.Security.SecuritySafeCritical]
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);
}
- [System.Security.SecuritySafeCritical]
private static unsafe bool StringToShort(String str, ref int parsePos, int requiredLength, int flags, out short result, ref GuidResult parseResult) {
fixed(int * ppos = &parsePos) {
return StringToShort(str, ppos, requiredLength, flags, out result, ref parseResult);
}
}
- [System.Security.SecurityCritical]
private static unsafe bool StringToShort(String str, int* parsePos, int requiredLength, int flags, out short result, ref GuidResult parseResult) {
result = 0;
int x;
@@ -771,17 +769,14 @@ namespace System {
return retValue;
}
- [System.Security.SecuritySafeCritical]
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);
}
- [System.Security.SecuritySafeCritical]
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);
}
}
- [System.Security.SecurityCritical]
private static unsafe bool StringToInt(String str, int* parsePos, int requiredLength, int flags, out int result, ref GuidResult parseResult) {
result = 0;
@@ -818,17 +813,14 @@ namespace System {
}
return true;
}
- [System.Security.SecuritySafeCritical]
private static unsafe bool StringToLong(String str, int flags, out long result, ref GuidResult parseResult) {
return StringToLong(str, null, flags, out result, ref parseResult);
}
- [System.Security.SecuritySafeCritical]
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);
}
}
- [System.Security.SecuritySafeCritical]
private static unsafe bool StringToLong(String str, int* parsePos, int flags, out long result, ref GuidResult parseResult) {
result = 0;
@@ -921,7 +913,6 @@ namespace System {
return ToString("D",null);
}
- [System.Security.SecuritySafeCritical]
public unsafe override int GetHashCode()
{
// Simply XOR all the bits of the GUID 32 bits at a time.
@@ -1007,7 +998,7 @@ namespace System {
return 1;
}
if (!(value is Guid)) {
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeGuid"), "value");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeGuid"), nameof(value));
}
Guid g = (Guid)value;
@@ -1143,7 +1134,6 @@ 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.
- [System.Security.SecuritySafeCritical] // auto-generated
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
@@ -1165,13 +1155,11 @@ namespace System {
return (char) ((a > 9) ? a - 10 + 0x61 : a + 0x30);
}
- [System.Security.SecurityCritical]
unsafe private static int HexsToChars(char* guidChars, int offset, int a, int b)
{
return HexsToChars(guidChars, offset, a, b, false);
}
- [System.Security.SecurityCritical]
unsafe private static int HexsToChars(char* guidChars, int offset, int a, int b, bool hex)
{
if (hex) {
@@ -1192,7 +1180,6 @@ namespace System {
// IFormattable interface
// We currently ignore provider
- [System.Security.SecuritySafeCritical]
public String ToString(String format, IFormatProvider provider)
{
if (format == null || format.Length == 0)
diff --git a/src/mscorlib/src/System/IAppDomain.cs b/src/mscorlib/src/System/IAppDomain.cs
index bd8b876577..cdb83166c8 100644
--- a/src/mscorlib/src/System/IAppDomain.cs
+++ b/src/mscorlib/src/System/IAppDomain.cs
@@ -13,256 +13,16 @@
**
**
===========================================================*/
-namespace System {
- using System.Reflection;
- using System.Runtime.CompilerServices;
- using SecurityManager = System.Security.SecurityManager;
- using System.Security.Permissions;
- using IEvidenceFactory = System.Security.IEvidenceFactory;
-#if FEATURE_IMPERSONATION
- using System.Security.Principal;
-#endif
- using System.Security.Policy;
- using System.Security;
- using System.Security.Util;
- using System.Collections;
- using System.Text;
- using System.Configuration.Assemblies;
- using System.Threading;
+namespace System
+{
using System.Runtime.InteropServices;
- using System.Runtime.Remoting;
- using System.Reflection.Emit;
- using CultureInfo = System.Globalization.CultureInfo;
- using System.IO;
- using System.Runtime.Versioning;
[GuidAttribute("05F696DC-2B29-3663-AD8B-C4389CF2A713")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[CLSCompliant(false)]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface _AppDomain
{
-#if !FEATURE_CORECLR
- void GetTypeInfoCount(out uint pcTInfo);
-
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
-
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
-
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
-
- String ToString();
-
- bool Equals (Object other);
-
- int GetHashCode ();
-
- Type GetType ();
-
-#if FEATURE_REMOTING
- [System.Security.SecurityCritical] // auto-generated_required
- Object InitializeLifetimeService ();
-
- [System.Security.SecurityCritical] // auto-generated_required
- Object GetLifetimeService ();
-#endif // FEATURE_REMOTING
-
-#if FEATURE_CAS_POLICY
- Evidence Evidence { get; }
-#endif // FEATURE_CAS_POLICY
- event EventHandler DomainUnload;
-
- [method:System.Security.SecurityCritical]
- event AssemblyLoadEventHandler AssemblyLoad;
-
- event EventHandler ProcessExit;
-
- [method:System.Security.SecurityCritical]
- event ResolveEventHandler TypeResolve;
-
- [method:System.Security.SecurityCritical]
- event ResolveEventHandler ResourceResolve;
-
- [method:System.Security.SecurityCritical]
- event ResolveEventHandler AssemblyResolve;
-
- [method:System.Security.SecurityCritical]
- event UnhandledExceptionEventHandler UnhandledException;
-
- AssemblyBuilder DefineDynamicAssembly(AssemblyName name,
- AssemblyBuilderAccess access);
-
- AssemblyBuilder DefineDynamicAssembly(AssemblyName name,
- AssemblyBuilderAccess access,
- String dir);
-
- AssemblyBuilder DefineDynamicAssembly(AssemblyName name,
- AssemblyBuilderAccess access,
- Evidence evidence);
-
- AssemblyBuilder DefineDynamicAssembly(AssemblyName name,
- AssemblyBuilderAccess access,
- PermissionSet requiredPermissions,
- PermissionSet optionalPermissions,
- PermissionSet refusedPermissions);
-
- AssemblyBuilder DefineDynamicAssembly(AssemblyName name,
- AssemblyBuilderAccess access,
- String dir,
- Evidence evidence);
-
- AssemblyBuilder DefineDynamicAssembly(AssemblyName name,
- AssemblyBuilderAccess access,
- String dir,
- PermissionSet requiredPermissions,
- PermissionSet optionalPermissions,
- PermissionSet refusedPermissions);
-
- AssemblyBuilder DefineDynamicAssembly(AssemblyName name,
- AssemblyBuilderAccess access,
- Evidence evidence,
- PermissionSet requiredPermissions,
- PermissionSet optionalPermissions,
- PermissionSet refusedPermissions);
-
- AssemblyBuilder DefineDynamicAssembly(AssemblyName name,
- AssemblyBuilderAccess access,
- String dir,
- Evidence evidence,
- PermissionSet requiredPermissions,
- PermissionSet optionalPermissions,
- PermissionSet refusedPermissions);
-
- AssemblyBuilder DefineDynamicAssembly(AssemblyName name,
- AssemblyBuilderAccess access,
- String dir,
- Evidence evidence,
- PermissionSet requiredPermissions,
- PermissionSet optionalPermissions,
- PermissionSet refusedPermissions,
- bool isSynchronized);
-
- ObjectHandle CreateInstance(String assemblyName,
- String typeName);
-
-
- ObjectHandle CreateInstanceFrom(String assemblyFile,
- String typeName);
-
-
- ObjectHandle CreateInstance(String assemblyName,
- String typeName,
- Object[] activationAttributes);
-
- ObjectHandle CreateInstanceFrom(String assemblyFile,
- String typeName,
- Object[] activationAttributes);
-
- ObjectHandle CreateInstance(String assemblyName,
- String typeName,
- bool ignoreCase,
- BindingFlags bindingAttr,
- Binder binder,
- Object[] args,
- CultureInfo culture,
- Object[] activationAttributes,
- Evidence securityAttributes);
-
- ObjectHandle CreateInstanceFrom(String assemblyFile,
- String typeName,
- bool ignoreCase,
- BindingFlags bindingAttr,
- Binder binder,
- Object[] args,
- CultureInfo culture,
- Object[] activationAttributes,
- Evidence securityAttributes);
-
- Assembly Load(AssemblyName assemblyRef);
-
- Assembly Load(String assemblyString);
-
- Assembly Load(byte[] rawAssembly);
-
- Assembly Load(byte[] rawAssembly,
- byte[] rawSymbolStore);
-
- Assembly Load(byte[] rawAssembly,
- byte[] rawSymbolStore,
- Evidence securityEvidence);
-
- Assembly Load(AssemblyName assemblyRef,
- Evidence assemblySecurity);
-
- Assembly Load(String assemblyString,
- Evidence assemblySecurity);
-
- int ExecuteAssembly(String assemblyFile,
- Evidence assemblySecurity);
-
- int ExecuteAssembly(String assemblyFile);
-
- int ExecuteAssembly(String assemblyFile,
- Evidence assemblySecurity,
- String[] args);
-
- String FriendlyName
- { get; }
-#if FEATURE_FUSION
- String BaseDirectory
- {
- get;
- }
-
- String RelativeSearchPath
- { get; }
-
- bool ShadowCopyFiles
- { get; }
-#endif
- Assembly[] GetAssemblies();
-#if FEATURE_FUSION
- [System.Security.SecurityCritical] // auto-generated_required
- void AppendPrivatePath(String path);
-
- [System.Security.SecurityCritical] // auto-generated_required
- void ClearPrivatePath();
-
- [System.Security.SecurityCritical] // auto-generated_required
- void SetShadowCopyPath (String s);
-
- [System.Security.SecurityCritical] // auto-generated_required
- void ClearShadowCopyPath ( );
-
- [System.Security.SecurityCritical] // auto-generated_required
- void SetCachePath (String s);
-#endif //FEATURE_FUSION
- [System.Security.SecurityCritical] // auto-generated_required
- void SetData(String name, Object data);
-
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
- Object GetData(string name);
-
-#if FEATURE_CAS_POLICY
- [System.Security.SecurityCritical] // auto-generated_required
- void SetAppDomainPolicy(PolicyLevel domainPolicy);
-
-#if FEATURE_IMPERSONATION
- void SetThreadPrincipal(IPrincipal principal);
-#endif // FEATURE_IMPERSONATION
-
- void SetPrincipalPolicy(PrincipalPolicy policy);
-#endif
-
-#if FEATURE_REMOTING
- void DoCallBack(CrossAppDomainDelegate theDelegate);
-#endif
-
- String DynamicDirectory
- { get; }
-#endif
}
}
diff --git a/src/mscorlib/src/System/IAppDomainPauseManager.cs b/src/mscorlib/src/System/IAppDomainPauseManager.cs
index 7e031454a4..902a79bd2a 100644
--- a/src/mscorlib/src/System/IAppDomainPauseManager.cs
+++ b/src/mscorlib/src/System/IAppDomainPauseManager.cs
@@ -20,16 +20,13 @@ namespace System
using System.Runtime.Versioning;
using System.Runtime.CompilerServices;
- [System.Security.SecurityCritical]
internal class AppDomainPauseManager
{
- [System.Security.SecurityCritical]
public AppDomainPauseManager()
{
isPaused = false;
}
- [System.Security.SecurityCritical]
static AppDomainPauseManager()
{
}
@@ -37,22 +34,19 @@ namespace System
static readonly AppDomainPauseManager instance = new AppDomainPauseManager();
internal static AppDomainPauseManager Instance
{
- [System.Security.SecurityCritical]
get { return instance; }
}
// FAS: IAppDomainPauseConsumer interface implementation
// currently there is nothing we do here as the implementation
// of updating pause times have been moved to native CorHost2
- [System.Security.SecurityCritical]
public void Pausing()
{
}
- [System.Security.SecurityCritical]
public void Paused()
{
- Contract.Assert(!isPaused);
+ Debug.Assert(!isPaused);
if(ResumeEvent == null)
ResumeEvent = new ManualResetEvent(false);
@@ -67,15 +61,13 @@ namespace System
isPaused = true;
}
- [System.Security.SecurityCritical]
public void Resuming()
{
- Contract.Assert(isPaused);
+ Debug.Assert(isPaused);
isPaused = false;
ResumeEvent.Set();
}
- [System.Security.SecurityCritical]
public void Resumed()
{
Timer.Resume();
@@ -85,15 +77,12 @@ namespace System
internal static bool IsPaused
{
- [System.Security.SecurityCritical]
get { return isPaused; }
}
internal static ManualResetEvent ResumeEvent
{
- [System.Security.SecurityCritical]
get;
- [System.Security.SecurityCritical]
set;
}
}
diff --git a/src/mscorlib/src/System/IO/BinaryReader.cs b/src/mscorlib/src/System/IO/BinaryReader.cs
index 8accf0bd77..4145a7f4f6 100644
--- a/src/mscorlib/src/System/IO/BinaryReader.cs
+++ b/src/mscorlib/src/System/IO/BinaryReader.cs
@@ -19,6 +19,7 @@ namespace System.IO {
using System.Runtime;
using System.Text;
using System.Globalization;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Security;
@@ -40,7 +41,7 @@ namespace System.IO {
private bool m_isMemoryStream; // "do we sit on MemoryStream?" for Read/ReadInt32 perf
private bool m_leaveOpen;
- public BinaryReader(Stream input) : this(input, new UTF8Encoding(), false) {
+ public BinaryReader(Stream input) : this(input, Encoding.UTF8, false) {
}
public BinaryReader(Stream input, Encoding encoding) : this(input, encoding, false) {
@@ -48,10 +49,10 @@ namespace System.IO {
public BinaryReader(Stream input, Encoding encoding, bool leaveOpen) {
if (input==null) {
- throw new ArgumentNullException("input");
+ throw new ArgumentNullException(nameof(input));
}
if (encoding==null) {
- throw new ArgumentNullException("encoding");
+ throw new ArgumentNullException(nameof(encoding));
}
if (!input.CanRead)
throw new ArgumentException(Environment.GetResourceString("Argument_StreamNotReadable"));
@@ -73,7 +74,7 @@ namespace System.IO {
m_isMemoryStream = (m_stream.GetType() == typeof(MemoryStream));
m_leaveOpen = leaveOpen;
- Contract.Assert(m_decoder!=null, "[BinaryReader.ctor]m_decoder!=null");
+ Debug.Assert(m_decoder!=null, "[BinaryReader.ctor]m_decoder!=null");
}
public virtual Stream BaseStream {
@@ -173,7 +174,7 @@ namespace System.IO {
if (m_stream==null) __Error.FileNotOpen();
// read directly from MemoryStream buffer
MemoryStream mStream = m_stream as MemoryStream;
- Contract.Assert(mStream != null, "m_stream as MemoryStream != null");
+ Debug.Assert(mStream != null, "m_stream as MemoryStream != null");
return mStream.InternalReadInt32();
}
@@ -209,14 +210,12 @@ namespace System.IO {
return ((ulong)hi) << 32 | lo;
}
- [System.Security.SecuritySafeCritical] // auto-generated
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);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public virtual unsafe double ReadDouble() {
FillBuffer(8);
uint lo = (uint)(m_buffer[0] | m_buffer[1] << 8 |
@@ -294,16 +293,15 @@ namespace System.IO {
return StringBuilderCache.GetStringAndRelease(sb);
}
- [SecuritySafeCritical]
public virtual int Read(char[] buffer, int index, int count) {
if (buffer==null) {
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
}
if (index < 0) {
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (count < 0) {
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (buffer.Length - index < count) {
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
@@ -319,11 +317,10 @@ namespace System.IO {
return InternalReadChars(buffer, index, count);
}
- [SecurityCritical]
private int InternalReadChars(char[] buffer, int index, int count) {
Contract.Requires(buffer != null);
Contract.Requires(index >= 0 && count >= 0);
- Contract.Assert(m_stream != null);
+ Debug.Assert(m_stream != null);
int numBytes = 0;
int charsRemaining = count;
@@ -355,7 +352,7 @@ namespace System.IO {
if (m_isMemoryStream)
{
MemoryStream mStream = m_stream as MemoryStream;
- Contract.Assert(mStream != null, "m_stream as MemoryStream != null");
+ Debug.Assert(mStream != null, "m_stream as MemoryStream != null");
position = mStream.InternalGetPosition();
numBytes = mStream.InternalEmulateRead(numBytes);
@@ -371,7 +368,7 @@ namespace System.IO {
return (count - charsRemaining);
}
- Contract.Assert(byteBuffer != null, "expected byteBuffer to be non-null");
+ Debug.Assert(byteBuffer != null, "expected byteBuffer to be non-null");
checked
{
@@ -398,7 +395,7 @@ namespace System.IO {
}
// this should never fail
- Contract.Assert(charsRemaining >= 0, "We read too many characters.");
+ Debug.Assert(charsRemaining >= 0, "We read too many characters.");
// we may have read fewer than the number of characters requested if end of stream reached
// or if the encoding makes the char count too big for the buffer (e.g. fallback sequence)
@@ -447,7 +444,7 @@ namespace System.IO {
return -1;
}
- Contract.Assert(numBytes == 1 || numBytes == 2, "BinaryReader::InternalReadOneChar assumes it's reading one or 2 bytes only.");
+ Debug.Assert(numBytes == 1 || numBytes == 2, "BinaryReader::InternalReadOneChar assumes it's reading one or 2 bytes only.");
try {
@@ -464,7 +461,7 @@ namespace System.IO {
throw;
}
- Contract.Assert(charsRead < 2, "InternalReadOneChar - assuming we only got 0 or 1 char, not 2!");
+ Debug.Assert(charsRead < 2, "InternalReadOneChar - assuming we only got 0 or 1 char, not 2!");
// Console.WriteLine("That became: " + charsRead + " characters.");
}
if (charsRead == 0)
@@ -472,10 +469,9 @@ namespace System.IO {
return m_singleChar[0];
}
- [SecuritySafeCritical]
public virtual char[] ReadChars(int count) {
if (count<0) {
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
Contract.Ensures(Contract.Result<char[]>() != null);
Contract.Ensures(Contract.Result<char[]>().Length <= count);
@@ -502,11 +498,11 @@ namespace System.IO {
public virtual int Read(byte[] buffer, int index, int count) {
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (index < 0)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.Ensures(Contract.Result<int>() >= 0);
@@ -518,7 +514,7 @@ namespace System.IO {
}
public virtual byte[] ReadBytes(int count) {
- if (count < 0) throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (count < 0) throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.Ensures(Contract.Result<byte[]>() != null);
Contract.Ensures(Contract.Result<byte[]>().Length <= Contract.OldValue(count));
Contract.EndContractBlock();
@@ -551,7 +547,7 @@ namespace System.IO {
protected virtual void FillBuffer(int numBytes) {
if (m_buffer != null && (numBytes < 0 || numBytes > m_buffer.Length)) {
- throw new ArgumentOutOfRangeException("numBytes", Environment.GetResourceString("ArgumentOutOfRange_BinaryReaderFillBuffer"));
+ throw new ArgumentOutOfRangeException(nameof(numBytes), Environment.GetResourceString("ArgumentOutOfRange_BinaryReaderFillBuffer"));
}
int bytesRead=0;
int n = 0;
diff --git a/src/mscorlib/src/System/IO/BinaryWriter.cs b/src/mscorlib/src/System/IO/BinaryWriter.cs
index c775cbc9ff..f99b4d3d42 100644
--- a/src/mscorlib/src/System/IO/BinaryWriter.cs
+++ b/src/mscorlib/src/System/IO/BinaryWriter.cs
@@ -17,6 +17,7 @@ using System;
using System.Runtime;
using System.Runtime.Serialization;
using System.Text;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
namespace System.IO {
@@ -25,7 +26,7 @@ namespace System.IO {
// give unique encodings.
//
[Serializable]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public class BinaryWriter : IDisposable
{
public static readonly BinaryWriter Null = new BinaryWriter();
@@ -38,14 +39,6 @@ namespace System.IO {
[OptionalField] // New in .NET FX 4.5. False is the right default value.
private bool _leaveOpen;
- // This field should never have been serialized and has not been used since before v2.0.
- // However, this type is serializable, and we need to keep the field name around when deserializing.
- // Also, we'll make .NET FX 4.5 not break if it's missing.
-#pragma warning disable 169
- [OptionalField]
- private char[] _tmpOneCharBuffer;
-#pragma warning restore 169
-
// Perf optimization stuff
private byte[] _largeByteBuffer; // temp space for writing chars.
private int _maxChars; // max # of chars we can put in _largeByteBuffer
@@ -58,11 +51,11 @@ namespace System.IO {
{
OutStream = Stream.Null;
_buffer = new byte[16];
- _encoding = new UTF8Encoding(false, true);
+ _encoding = EncodingCache.UTF8NoBOM;
_encoder = _encoding.GetEncoder();
}
- public BinaryWriter(Stream output) : this(output, new UTF8Encoding(false, true), false)
+ public BinaryWriter(Stream output) : this(output, EncodingCache.UTF8NoBOM, false)
{
}
@@ -73,9 +66,9 @@ namespace System.IO {
public BinaryWriter(Stream output, Encoding encoding, bool leaveOpen)
{
if (output==null)
- throw new ArgumentNullException("output");
+ throw new ArgumentNullException(nameof(output));
if (encoding==null)
- throw new ArgumentNullException("encoding");
+ throw new ArgumentNullException(nameof(encoding));
if (!output.CanWrite)
throw new ArgumentException(Environment.GetResourceString("Argument_StreamNotWritable"));
Contract.EndContractBlock();
@@ -166,7 +159,7 @@ namespace System.IO {
//
public virtual void Write(byte[] buffer) {
if (buffer == null)
- throw new ArgumentNullException("buffer");
+ throw new ArgumentNullException(nameof(buffer));
Contract.EndContractBlock();
OutStream.Write(buffer, 0, buffer.Length);
}
@@ -185,13 +178,12 @@ namespace System.IO {
// advanced by two.
// Note this method cannot handle surrogates properly in UTF-8.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe virtual void Write(char ch) {
if (Char.IsSurrogate(ch))
throw new ArgumentException(Environment.GetResourceString("Arg_SurrogatesNotAllowedAsSingleChar"));
Contract.EndContractBlock();
- Contract.Assert(_encoding.GetMaxByteCount(1) <= 16, "_encoding.GetMaxByteCount(1) <= 16)");
+ Debug.Assert(_encoding.GetMaxByteCount(1) <= 16, "_encoding.GetMaxByteCount(1) <= 16)");
int numBytes = 0;
fixed(byte * pBytes = _buffer) {
numBytes = _encoder.GetBytes(&ch, 1, pBytes, _buffer.Length, flush: true);
@@ -207,7 +199,7 @@ namespace System.IO {
public virtual void Write(char[] chars)
{
if (chars == null)
- throw new ArgumentNullException("chars");
+ throw new ArgumentNullException(nameof(chars));
Contract.EndContractBlock();
byte[] bytes = _encoding.GetBytes(chars, 0, chars.Length);
@@ -229,7 +221,6 @@ namespace System.IO {
// Writes a double to this stream. The current position of the stream is
// advanced by eight.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe virtual void Write(double value)
{
ulong TmpValue = *(ulong *)&value;
@@ -332,7 +323,6 @@ namespace System.IO {
// Writes a float to this stream. The current position of the stream is
// advanced by four.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe virtual void Write(float value)
{
uint TmpValue = *(uint *)&value;
@@ -349,11 +339,10 @@ namespace System.IO {
// a four-byte unsigned integer, and then writes that many characters
// to the stream.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe virtual void Write(String value)
{
if (value==null)
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
Contract.EndContractBlock();
int len = _encoding.GetByteCount(value);
@@ -366,7 +355,7 @@ namespace System.IO {
if (len <= _largeByteBuffer.Length)
{
- //Contract.Assert(len == _encoding.GetBytes(chars, 0, chars.Length, _largeByteBuffer, 0), "encoding's GetByteCount & GetBytes gave different answers! encoding type: "+_encoding.GetType().Name);
+ //Debug.Assert(len == _encoding.GetBytes(chars, 0, chars.Length, _largeByteBuffer, 0), "encoding's GetByteCount & GetBytes gave different answers! encoding type: "+_encoding.GetType().Name);
_encoding.GetBytes(value, 0, value.Length, _largeByteBuffer, 0);
OutStream.Write(_largeByteBuffer, 0, len);
}
@@ -401,14 +390,14 @@ namespace System.IO {
}
#if _DEBUG
totalBytes += byteLen;
- Contract.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;
numLeft -= charCount;
}
#if _DEBUG
- Contract.Assert(totalBytes == len, "BinaryWriter::Write(String) - Didn't write out all the bytes!");
+ Debug.Assert(totalBytes == len, "BinaryWriter::Write(String) - Didn't write out all the bytes!");
#endif
}
}
diff --git a/src/mscorlib/src/System/IO/BufferedStream.cs b/src/mscorlib/src/System/IO/BufferedStream.cs
deleted file mode 100644
index 0c73b5c0f5..0000000000
--- a/src/mscorlib/src/System/IO/BufferedStream.cs
+++ /dev/null
@@ -1,1320 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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 composable Stream that buffers reads & writes to the underlying stream.
-**
-**
-===========================================================*/
-using System;
-using System.Runtime.InteropServices;
-using System.Globalization;
-using System.Diagnostics.Contracts;
-using System.Runtime.CompilerServices;
-using System.Threading;
-using System.Collections.ObjectModel;
-using System.Security;
-using System.Threading.Tasks;
-
-namespace System.IO {
-
-/// <summary>
-/// One of the design goals here is to prevent the buffer from getting in the way and slowing
-/// down underlying stream accesses when it is not needed. If you always read & write for sizes
-/// greater than the internal buffer size, then this class may not even allocate the internal buffer.
-/// See a large comment in Write for the details of the write buffer heuristic.
-///
-/// This class buffers reads & writes in a shared buffer.
-/// (If you maintained two buffers separately, one operation would always trash the other buffer
-/// anyways, so we might as well use one buffer.)
-/// The assumption here is you will almost always be doing a series of reads or writes, but rarely
-/// alternate between the two of them on the same stream.
-///
-/// 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:
-/// <![CDATA[
-/// * 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.
-/// ]]>
-/// This class will never cache more bytes than the max specified buffer size.
-/// However, it may use a temporary buffer of up to twice the size in order to combine several IO operations on
-/// the underlying stream into a single operation. This is because we assume that memory copies are significantly
-/// faster than IO operations on the underlying stream (if this was not true, using buffering is never appropriate).
-/// The max size of this "shadow" buffer is limited as to not allocate it on the LOH.
-/// Shadowing is always transient. Even when using this technique, this class still guarantees that the number of
-/// bytes cached (not yet written to the target stream or not yet consumed by the user) is never larger than the
-/// actual specified buffer size.
-/// </summary>
-[ComVisible(true)]
-public sealed class BufferedStream : Stream {
-
-
- private const Int32 _DefaultBufferSize = 4096;
-
-
- private Stream _stream; // Underlying stream. Close sets _stream to null.
-
- private Byte[] _buffer; // Shared read/write buffer. Alloc on first use.
-
- private readonly Int32 _bufferSize; // Length of internal buffer (not counting the shadow buffer).
-
- private Int32 _readPos; // Read pointer within shared buffer.
- private Int32 _readLen; // Number of bytes read in buffer from _stream.
- private Int32 _writePos; // Write pointer within shared buffer.
-
- private BeginEndAwaitableAdapter _beginEndAwaitable; // Used to be able to await a BeginXxx call and thus to share code
- // between the APM and Async pattern implementations
-
- private Task<Int32> _lastSyncCompletedReadTask; // The last successful Task returned from ReadAsync
- // (perf optimization for successive reads of the same size)
-
-
- // Removing a private default constructor is a breaking change for the DataContractSerializer.
- // Because this ctor was here previously we need to keep it around.
- private BufferedStream() { }
-
-
- public BufferedStream(Stream stream)
-
- : this(stream, _DefaultBufferSize) {
- }
-
-
- public BufferedStream(Stream stream, Int32 bufferSize) {
-
- if (stream == null)
- throw new ArgumentNullException("stream");
-
- if (bufferSize <= 0)
- throw new ArgumentOutOfRangeException("bufferSize", Environment.GetResourceString("ArgumentOutOfRange_MustBePositive", "bufferSize"));
-
- Contract.EndContractBlock();
-
- BCLDebug.Perf(!(stream is FileStream), "FileStream is buffered - don't wrap it in a BufferedStream");
- BCLDebug.Perf(!(stream is MemoryStream), "MemoryStream shouldn't be wrapped in a BufferedStream!");
- BCLDebug.Perf(!(stream is BufferedStream), "BufferedStream shouldn't be wrapped in another BufferedStream!");
-
- _stream = stream;
- _bufferSize = bufferSize;
-
- // Allocate _buffer on its first use - it will not be used if all reads
- // & writes are greater than or equal to buffer size.
-
- if (!_stream.CanRead && !_stream.CanWrite)
- __Error.StreamIsClosed();
- }
-
-
- private void EnsureNotClosed() {
-
- if (_stream == null)
- __Error.StreamIsClosed();
- }
-
-
- private void EnsureCanSeek() {
-
- Contract.Requires(_stream != null);
-
- if (!_stream.CanSeek)
- __Error.SeekNotSupported();
- }
-
-
- private void EnsureCanRead() {
-
- Contract.Requires(_stream != null);
-
- if (!_stream.CanRead)
- __Error.ReadNotSupported();
- }
-
-
- private void EnsureCanWrite() {
-
- Contract.Requires(_stream != null);
-
- if (!_stream.CanWrite)
- __Error.WriteNotSupported();
- }
-
-
- private void EnsureBeginEndAwaitableAllocated() {
- // We support only a single ongoing async operation and enforce this with a semaphore,
- // so singleton is fine and no need to worry about a race condition here.
- if (_beginEndAwaitable == null)
- _beginEndAwaitable = new BeginEndAwaitableAdapter();
- }
-
-
- /// <summary><code>MaxShadowBufferSize</code> is chosed such that shadow buffers are not allocated on the Large Object Heap.
- /// Currently, an object is allocated on the LOH if it is larger than 85000 bytes. See LARGE_OBJECT_SIZE in ndp\clr\src\vm\gc.h
- /// We will go with exactly 80 KBytes, although this is somewhat arbitrary.</summary>
- private const Int32 MaxShadowBufferSize = 81920; // Make sure not to get to the Large Object Heap.
- private void EnsureShadowBufferAllocated() {
-
- Contract.Assert(_buffer != null);
- Contract.Assert(_bufferSize > 0);
-
- // Already have shadow buffer?
- if (_buffer.Length != _bufferSize || _bufferSize >= MaxShadowBufferSize)
- return;
-
- Byte[] shadowBuffer = new Byte[Math.Min(_bufferSize + _bufferSize, MaxShadowBufferSize)];
- Buffer.InternalBlockCopy(_buffer, 0, shadowBuffer, 0, _writePos);
- _buffer = shadowBuffer;
- }
-
-
- private void EnsureBufferAllocated() {
-
- Contract.Assert(_bufferSize > 0);
-
- // BufferedStream is not intended for multi-threaded use, so no worries about the get/set race conditions on _buffer.
- if (_buffer == null)
- _buffer = new Byte[_bufferSize];
- }
-
-
- internal Stream UnderlyingStream {
- [FriendAccessAllowed]
- [Pure]
- get { return _stream; }
- }
-
-
- internal Int32 BufferSize {
- [FriendAccessAllowed]
- [Pure]
- get { return _bufferSize; }
- }
-
-
- public override bool CanRead {
- [Pure]
- get { return _stream != null && _stream.CanRead; }
- }
-
-
- public override bool CanWrite {
- [Pure]
- get { return _stream != null && _stream.CanWrite; }
- }
-
-
- public override bool CanSeek {
- [Pure]
- get { return _stream != null && _stream.CanSeek; }
- }
-
-
- public override Int64 Length {
- get {
- EnsureNotClosed();
-
- if (_writePos > 0)
- FlushWrite();
-
- return _stream.Length;
- }
- }
-
-
- public override Int64 Position {
- get {
- EnsureNotClosed();
- EnsureCanSeek();
-
- Contract.Assert(! (_writePos > 0 && _readPos != _readLen), "Read and Write buffers cannot both have data in them at the same time.");
- return _stream.Position + (_readPos - _readLen + _writePos);
- }
- set {
- if (value < 0)
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- EnsureNotClosed();
- EnsureCanSeek();
-
- if (_writePos > 0)
- FlushWrite();
-
- _readPos = 0;
- _readLen = 0;
- _stream.Seek(value, SeekOrigin.Begin);
- }
- }
-
-
- protected override void Dispose(bool disposing) {
-
- try {
- if (disposing && _stream != null) {
- try {
- Flush();
- } finally {
- _stream.Close();
- }
- }
- } finally {
- _stream = null;
- _buffer = null;
- _lastSyncCompletedReadTask = null;
-
- // Call base.Dispose(bool) to cleanup async IO resources
- base.Dispose(disposing);
- }
- }
-
-
- public override void Flush() {
-
- EnsureNotClosed();
-
- // Has WRITE data in the buffer:
- if (_writePos > 0) {
-
- FlushWrite();
- Contract.Assert(_writePos == 0 && _readPos == 0 && _readLen == 0);
- return;
- }
-
- // Has READ data in the buffer:
- if (_readPos < _readLen) {
-
- // If the underlying stream is not seekable AND we have something in the read buffer, then FlushRead would throw.
- // We can either throw away the buffer resulting in data loss (!) or ignore the Flush.
- // (We cannot throw becasue it would be a breaking change.) We opt into ignoring the Flush in that situation.
- if (!_stream.CanSeek)
- return;
-
- FlushRead();
-
- // User streams may have opted to throw from Flush if CanWrite is false (although the abstract Stream does not do so).
- // However, if we do not forward the Flush to the underlying stream, we may have problems when chaining several streams.
- // Let us make a best effort attempt:
- if (_stream.CanWrite || _stream is BufferedStream)
- _stream.Flush();
-
- Contract.Assert(_writePos == 0 && _readPos == 0 && _readLen == 0);
- return;
- }
-
- // We had no data in the buffer, but we still need to tell the underlying stream to flush.
- if (_stream.CanWrite || _stream is BufferedStream)
- _stream.Flush();
-
- _writePos = _readPos = _readLen = 0;
- }
-
- public override Task FlushAsync(CancellationToken cancellationToken) {
-
- if (cancellationToken.IsCancellationRequested)
- return Task.FromCanceled<Int32>(cancellationToken);
-
- EnsureNotClosed();
-
- return FlushAsyncInternal(cancellationToken, this, _stream, _writePos, _readPos, _readLen);
- }
-
-
- private static async Task FlushAsyncInternal(CancellationToken cancellationToken,
- BufferedStream _this, Stream stream, Int32 writePos, Int32 readPos, Int32 readLen) {
-
- // We bring instance fields down as local parameters to this async method becasue BufferedStream is derived from MarshalByRefObject.
- // Field access would be from the async state machine i.e., not via the this pointer and would require runtime checking to see
- // if we are talking to a remote object, which is currently very slow
-
- Contract.Assert(stream != null);
-
- SemaphoreSlim sem = _this.EnsureAsyncActiveSemaphoreInitialized();
- await sem.WaitAsync().ConfigureAwait(false);
- try {
-
- if (writePos > 0) {
-
- await _this.FlushWriteAsync(cancellationToken).ConfigureAwait(false);
- Contract.Assert(_this._writePos == 0 && _this._readPos == 0 && _this._readLen == 0);
- return;
- }
-
- if (readPos < readLen) {
-
- // If the underlying stream is not seekable AND we have something in the read buffer, then FlushRead would throw.
- // We can either throw away the buffer resulting in date loss (!) or ignore the Flush. (We cannot throw becasue it
- // would be a breaking change.) We opt into ignoring the Flush in that situation.
- if (!stream.CanSeek)
- return;
-
- _this.FlushRead(); // not async; it uses Seek, but there's no SeekAsync
-
- // User streams may have opted to throw from Flush if CanWrite is false (although the abstract Stream does not do so).
- // However, if we do not forward the Flush to the underlying stream, we may have problems when chaining several streams.
- // Let us make a best effort attempt:
- if (stream.CanRead || stream is BufferedStream)
- await stream.FlushAsync(cancellationToken).ConfigureAwait(false);
-
- Contract.Assert(_this._writePos == 0 && _this._readPos == 0 && _this._readLen == 0);
- return;
- }
-
- // We had no data in the buffer, but we still need to tell the underlying stream to flush.
- if (stream.CanWrite || stream is BufferedStream)
- await stream.FlushAsync(cancellationToken).ConfigureAwait(false);
-
- // There was nothing in the buffer:
- Contract.Assert(_this._writePos == 0 && _this._readPos == _this._readLen);
-
- } finally {
- sem.Release();
- }
- }
-
-
- // Reading is done in blocks, but someone could read 1 byte from the buffer then write.
- // At that point, the underlying stream's pointer is out of sync with this stream's position.
- // All write functions should call this function to ensure that the buffered data is not lost.
- private void FlushRead() {
-
- Contract.Assert(_writePos == 0, "BufferedStream: Write buffer must be empty in FlushRead!");
-
- if (_readPos - _readLen != 0)
- _stream.Seek(_readPos - _readLen, SeekOrigin.Current);
-
- _readPos = 0;
- _readLen = 0;
- }
-
-
- private void ClearReadBufferBeforeWrite() {
-
- // This is called by write methods to clear the read buffer.
-
- Contract.Assert(_readPos <= _readLen, "_readPos <= _readLen [" + _readPos +" <= " + _readLen + "]");
-
- // No READ data in the buffer:
- if (_readPos == _readLen) {
-
- _readPos = _readLen = 0;
- return;
- }
-
- // Must have READ data.
- Contract.Assert(_readPos < _readLen);
-
- // If the underlying stream cannot seek, FlushRead would end up throwing NotSupported.
- // However, since the user did not call a method that is intuitively expected to seek, a better message is in order.
- // Ideally, we would throw an InvalidOperation here, but for backward compat we have to stick with NotSupported.
- if (!_stream.CanSeek)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_CannotWriteToBufferedStreamIfReadBufferCannotBeFlushed"));
-
- FlushRead();
- }
-
-
- private void FlushWrite() {
-
- Contract.Assert(_readPos == 0 && _readLen == 0,
- "BufferedStream: Read buffer must be empty in FlushWrite!");
- Contract.Assert(_buffer != null && _bufferSize >= _writePos,
- "BufferedStream: Write buffer must be allocated and write position must be in the bounds of the buffer in FlushWrite!");
-
- _stream.Write(_buffer, 0, _writePos);
- _writePos = 0;
- _stream.Flush();
- }
-
-
- private async Task FlushWriteAsync(CancellationToken cancellationToken) {
-
- Contract.Assert(_readPos == 0 && _readLen == 0,
- "BufferedStream: Read buffer must be empty in FlushWrite!");
- Contract.Assert(_buffer != null && _bufferSize >= _writePos,
- "BufferedStream: Write buffer must be allocated and write position must be in the bounds of the buffer in FlushWrite!");
-
- await _stream.WriteAsync(_buffer, 0, _writePos, cancellationToken).ConfigureAwait(false);
- _writePos = 0;
- await _stream.FlushAsync(cancellationToken).ConfigureAwait(false);
- }
-
-
- private Int32 ReadFromBuffer(Byte[] array, Int32 offset, Int32 count) {
-
- Int32 readBytes = _readLen - _readPos;
- Contract.Assert(readBytes >= 0);
-
- if (readBytes == 0)
- return 0;
-
- Contract.Assert(readBytes > 0);
-
- if (readBytes > count)
- readBytes = count;
-
- Buffer.InternalBlockCopy(_buffer, _readPos, array, offset, readBytes);
- _readPos += readBytes;
-
- return readBytes;
- }
-
-
- private Int32 ReadFromBuffer(Byte[] array, Int32 offset, Int32 count, out Exception error) {
-
- try {
-
- error = null;
- return ReadFromBuffer(array, offset, count);
-
- } catch (Exception ex) {
- error = ex;
- return 0;
- }
- }
-
-
- public override int Read([In, Out] Byte[] array, Int32 offset, Int32 count) {
-
- if (array == null)
- throw new ArgumentNullException("array", Environment.GetResourceString("ArgumentNull_Buffer"));
- if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (array.Length - offset < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
- Contract.EndContractBlock();
-
- EnsureNotClosed();
- EnsureCanRead();
-
- Int32 bytesFromBuffer = ReadFromBuffer(array, offset, count);
-
- // 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 and this code was used with redirected pipes for a
- // process's standard output, this can lead to deadlocks involving two processes.
- // BUT - this is a breaking change.
- // So: If we could not read all bytes the user asked for from the buffer, we will try once from the underlying
- // stream thus ensuring the same blocking behaviour as if the underlying stream was not wrapped in this BufferedStream.
- if (bytesFromBuffer == count)
- return bytesFromBuffer;
-
- Int32 alreadySatisfied = bytesFromBuffer;
- if (bytesFromBuffer > 0) {
- count -= bytesFromBuffer;
- offset += bytesFromBuffer;
- }
-
- // So the READ buffer is empty.
- Contract.Assert(_readLen == _readPos);
- _readPos = _readLen = 0;
-
- // If there was anything in the WRITE buffer, clear it.
- if (_writePos > 0)
- FlushWrite();
-
- // If the requested read is larger than buffer size, avoid the buffer and still use a single read:
- if (count >= _bufferSize) {
-
- return _stream.Read(array, offset, count) + alreadySatisfied;
- }
-
- // Ok. We can fill the buffer:
- EnsureBufferAllocated();
- _readLen = _stream.Read(_buffer, 0, _bufferSize);
-
- bytesFromBuffer = ReadFromBuffer(array, offset, count);
-
- // 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 stream,
- // 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. Additionally, translating one read on the
- // BufferedStream to more than one read on the underlying Stream may defeat the whole purpose of buffering of the
- // underlying reads are significantly more expensive.
-
- return bytesFromBuffer + alreadySatisfied;
- }
-
-
- public override IAsyncResult BeginRead(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state) {
-
- if (buffer == null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
- if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (buffer.Length - offset < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
- Contract.EndContractBlock();
-
- // Previous version incorrectly threw NotSupported instead of ObjectDisposed. We keep that behaviour for back-compat.
- // EnsureNotClosed();
- if (_stream == null) __Error.ReadNotSupported();
- EnsureCanRead();
-
- Int32 bytesFromBuffer = 0;
- // Try to satisfy the request from the buffer synchronously. But still need a sem-lock in case that another
- // Async IO Task accesses the buffer concurrently. If we fail to acquire the lock without waiting, make this
- // an Async operation.
- SemaphoreSlim sem = base.EnsureAsyncActiveSemaphoreInitialized();
- Task semaphoreLockTask = sem.WaitAsync();
- if (semaphoreLockTask.Status == TaskStatus.RanToCompletion) {
-
- bool completeSynchronously = true;
- try {
-
- Exception error;
- bytesFromBuffer = ReadFromBuffer(buffer, offset, count, out error);
-
- // If we satistied enough data from the buffer, we can complete synchronously.
- // 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 and this code was used with redirected pipes for a
- // process's standard output, this can lead to deadlocks involving two processes.
- // BUT - this is a breaking change.
- // So: If we could not read all bytes the user asked for from the buffer, we will try once from the underlying
- // stream thus ensuring the same blocking behaviour as if the underlying stream was not wrapped in this BufferedStream.
- completeSynchronously = (bytesFromBuffer == count || error != null);
-
- if (completeSynchronously) {
-
- SynchronousAsyncResult asyncResult = (error == null)
- ? new SynchronousAsyncResult(bytesFromBuffer, state)
- : new SynchronousAsyncResult(error, state, isWrite: false);
- if (callback != null)
- callback(asyncResult);
-
- return asyncResult;
- }
- } finally {
- if (completeSynchronously) // if this is FALSE, we will be entering ReadFromUnderlyingStreamAsync and releasing there.
- sem.Release();
- }
- }
-
- // Delegate to the async implementation.
- return BeginReadFromUnderlyingStream(buffer, offset + bytesFromBuffer, count - bytesFromBuffer, callback, state,
- bytesFromBuffer, semaphoreLockTask);
- }
-
-
- private IAsyncResult BeginReadFromUnderlyingStream(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state,
- Int32 bytesAlreadySatisfied, Task semaphoreLockTask) {
-
- Task<Int32> readOp = ReadFromUnderlyingStreamAsync(buffer, offset, count, CancellationToken.None,
- bytesAlreadySatisfied, semaphoreLockTask, useApmPattern: true);
- return TaskToApm.Begin(readOp, callback, state);
- }
-
-
- public override Int32 EndRead(IAsyncResult asyncResult) {
-
- if (asyncResult == null)
- throw new ArgumentNullException("asyncResult");
- Contract.Ensures(Contract.Result<Int32>() >= 0);
- Contract.EndContractBlock();
-
- var sAR = asyncResult as SynchronousAsyncResult;
- if (sAR != null)
- return SynchronousAsyncResult.EndRead(asyncResult);
- return TaskToApm.End<Int32>(asyncResult);
- }
-
-
- private Task<Int32> LastSyncCompletedReadTask(Int32 val) {
-
- Task<Int32> t = _lastSyncCompletedReadTask;
- Contract.Assert(t == null || t.Status == TaskStatus.RanToCompletion);
-
- if (t != null && t.Result == val)
- return t;
-
- t = Task.FromResult<Int32>(val);
- _lastSyncCompletedReadTask = t;
- return t;
- }
-
-
- public override Task<Int32> ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) {
-
- if (buffer == null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
- if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (buffer.Length - offset < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
- Contract.EndContractBlock();
-
- // Fast path check for cancellation already requested
- if (cancellationToken.IsCancellationRequested)
- return Task.FromCanceled<Int32>(cancellationToken);
-
- EnsureNotClosed();
- EnsureCanRead();
-
- Int32 bytesFromBuffer = 0;
- // Try to satisfy the request from the buffer synchronously. But still need a sem-lock in case that another
- // Async IO Task accesses the buffer concurrently. If we fail to acquire the lock without waiting, make this
- // an Async operation.
- SemaphoreSlim sem = base.EnsureAsyncActiveSemaphoreInitialized();
- Task semaphoreLockTask = sem.WaitAsync();
- if (semaphoreLockTask.Status == TaskStatus.RanToCompletion) {
-
- bool completeSynchronously = true;
- try {
- Exception error;
- bytesFromBuffer = ReadFromBuffer(buffer, offset, count, out error);
-
- // If we satistied enough data from the buffer, we can complete synchronously.
- // 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 and this code was used with redirected pipes for a
- // process's standard output, this can lead to deadlocks involving two processes.
- // BUT - this is a breaking change.
- // So: If we could not read all bytes the user asked for from the buffer, we will try once from the underlying
- // stream thus ensuring the same blocking behaviour as if the underlying stream was not wrapped in this BufferedStream.
- completeSynchronously = (bytesFromBuffer == count || error != null);
-
- if (completeSynchronously) {
-
- return (error == null)
- ? LastSyncCompletedReadTask(bytesFromBuffer)
- : Task.FromException<Int32>(error);
- }
- } finally {
- if (completeSynchronously) // if this is FALSE, we will be entering ReadFromUnderlyingStreamAsync and releasing there.
- sem.Release();
- }
- }
-
- // Delegate to the async implementation.
- return ReadFromUnderlyingStreamAsync(buffer, offset + bytesFromBuffer, count - bytesFromBuffer, cancellationToken,
- bytesFromBuffer, semaphoreLockTask, useApmPattern: false);
- }
-
-
- /// <summary>BufferedStream should be as thin a wrapper as possible. We want that ReadAsync delegates to
- /// ReadAsync of the underlying _stream and that BeginRead delegates to BeginRead of the underlying stream,
- /// rather than calling the base Stream which implements the one in terms of the other. This allows BufferedStream
- /// to affect the semantics of the stream it wraps as little as possible. At the same time, we want to share as
- /// much code between the APM and the Async pattern implementations as possible. This method is called by both with
- /// a corresponding useApmPattern value. Recall that Task implements IAsyncResult.</summary>
- /// <returns>-2 if _bufferSize was set to 0 while waiting on the semaphore; otherwise num of bytes read.</returns>
- private async Task<Int32> ReadFromUnderlyingStreamAsync(Byte[] array, Int32 offset, Int32 count,
- CancellationToken cancellationToken,
- Int32 bytesAlreadySatisfied,
- Task semaphoreLockTask, bool useApmPattern) {
-
- // Same conditions validated with exceptions in ReadAsync:
- // (These should be Contract.Requires(..) but that method had some issues in async methods; using Assert(..) for now.)
- Contract.Assert(array != null);
- Contract.Assert(offset >= 0);
- Contract.Assert(count >= 0);
- Contract.Assert(array.Length - offset >= count);
- Contract.Assert(_stream != null);
- Contract.Assert(_stream.CanRead);
- Contract.Assert(_bufferSize > 0);
- Contract.Assert(semaphoreLockTask != null);
-
- // Employ async waiting based on the same synchronization used in BeginRead of the abstract Stream.
- await semaphoreLockTask.ConfigureAwait(false);
- try {
-
- // The buffer might have been changed by another async task while we were waiting on the semaphore.
- // Check it now again.
- Int32 bytesFromBuffer = ReadFromBuffer(array, offset, count);
- if (bytesFromBuffer == count)
- return bytesAlreadySatisfied + bytesFromBuffer;
-
- if (bytesFromBuffer > 0) {
- count -= bytesFromBuffer;
- offset += bytesFromBuffer;
- bytesAlreadySatisfied += bytesFromBuffer;
- }
-
- Contract.Assert(_readLen == _readPos);
- _readPos = _readLen = 0;
-
- // If there was anything in the WRITE buffer, clear it.
- if (_writePos > 0)
- await FlushWriteAsync(cancellationToken).ConfigureAwait(false); // no Begin-End read version for Flush. Use Async.
-
- // If the requested read is larger than buffer size, avoid the buffer and still use a single read:
- if (count >= _bufferSize) {
-
- if (useApmPattern) {
- EnsureBeginEndAwaitableAllocated();
- _stream.BeginRead(array, offset, count, BeginEndAwaitableAdapter.Callback, _beginEndAwaitable);
- return bytesAlreadySatisfied + _stream.EndRead(await _beginEndAwaitable);
- } else {
- return bytesAlreadySatisfied + await _stream.ReadAsync(array, offset, count, cancellationToken).ConfigureAwait(false);
- }
- }
-
- // Ok. We can fill the buffer:
- EnsureBufferAllocated();
- if (useApmPattern) {
- EnsureBeginEndAwaitableAllocated();
- _stream.BeginRead(_buffer, 0, _bufferSize, BeginEndAwaitableAdapter.Callback, _beginEndAwaitable);
- _readLen = _stream.EndRead(await _beginEndAwaitable);
- } else {
- _readLen = await _stream.ReadAsync(_buffer, 0, _bufferSize, cancellationToken).ConfigureAwait(false);
- }
-
- bytesFromBuffer = ReadFromBuffer(array, offset, count);
- return bytesAlreadySatisfied + bytesFromBuffer;
-
- } finally {
- SemaphoreSlim sem = base.EnsureAsyncActiveSemaphoreInitialized();
- sem.Release();
- }
- }
-
-
- public override Int32 ReadByte() {
-
- EnsureNotClosed();
- EnsureCanRead();
-
- if (_readPos == _readLen) {
-
- if (_writePos > 0)
- FlushWrite();
-
- EnsureBufferAllocated();
- _readLen = _stream.Read(_buffer, 0, _bufferSize);
- _readPos = 0;
- }
-
- if (_readPos == _readLen)
- return -1;
-
- Int32 b = _buffer[_readPos++];
- return b;
- }
-
-
- private void WriteToBuffer(Byte[] array, ref Int32 offset, ref Int32 count) {
-
- Int32 bytesToWrite = Math.Min(_bufferSize - _writePos, count);
-
- if (bytesToWrite <= 0)
- return;
-
- EnsureBufferAllocated();
- Buffer.InternalBlockCopy(array, offset, _buffer, _writePos, bytesToWrite);
-
- _writePos += bytesToWrite;
- count -= bytesToWrite;
- offset += bytesToWrite;
- }
-
-
- private void WriteToBuffer(Byte[] array, ref Int32 offset, ref Int32 count, out Exception error) {
-
- try {
-
- error = null;
- WriteToBuffer(array, ref offset, ref count);
-
- } catch (Exception ex) {
- error = ex;
- }
- }
-
-
- public override void Write(Byte[] array, Int32 offset, Int32 count) {
-
- if (array == null)
- throw new ArgumentNullException("array", Environment.GetResourceString("ArgumentNull_Buffer"));
- if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (array.Length - offset < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
- Contract.EndContractBlock();
-
- EnsureNotClosed();
- EnsureCanWrite();
-
- if (_writePos == 0)
- ClearReadBufferBeforeWrite();
-
- #region Write algorithm comment
- // We need to use the buffer, while avoiding unnecessary buffer usage / memory copies.
- // We ASSUME that memory copies are much cheaper than writes to the underlying stream, so if an extra copy is
- // guaranteed to reduce the number of writes, we prefer it.
- // We pick a simple strategy that makes degenerate cases rare if our assumptions are right.
- //
- // For every write, we use a simple heuristic (below) to decide whether to use the buffer.
- // The heuristic has the desirable property (*) that if the specified user data can fit into the currently available
- // buffer space without filling it up completely, the heuristic will always tell us to use the buffer. It will also
- // tell us to use the buffer in cases where the current write would fill the buffer, but the remaining data is small
- // enough such that subsequent operations can use the buffer again.
- //
- // Algorithm:
- // Determine whether or not to buffer according to the heuristic (below).
- // If we decided to use the buffer:
- // Copy as much user data as we can into the buffer.
- // If we consumed all data: We are finished.
- // Otherwise, write the buffer out.
- // Copy the rest of user data into the now cleared buffer (no need to write out the buffer again as the heuristic
- // will prevent it from being filled twice).
- // If we decided not to use the buffer:
- // Can the data already in the buffer and current user data be combines to a single write
- // by allocating a "shadow" buffer of up to twice the size of _bufferSize (up to a limit to avoid LOH)?
- // Yes, it can:
- // Allocate a larger "shadow" buffer and ensure the buffered data is moved there.
- // Copy user data to the shadow buffer.
- // Write shadow buffer to the underlying stream in a single operation.
- // No, it cannot (amount of data is still too large):
- // Write out any data possibly in the buffer.
- // Write out user data directly.
- //
- // Heuristic:
- // If the subsequent write operation that follows the current write operation will result in a write to the
- // underlying stream in case that we use the buffer in the current write, while it would not have if we avoided
- // using the buffer in the current write (by writing current user data to the underlying stream directly), then we
- // prefer to avoid using the buffer since the corresponding memory copy is wasted (it will not reduce the number
- // of writes to the underlying stream, which is what we are optimising for).
- // ASSUME that the next write will be for the same amount of bytes as the current write (most common case) and
- // determine if it will cause a write to the underlying stream. If the next write is actually larger, our heuristic
- // still yields the right behaviour, if the next write is actually smaller, we may making an unnecessary write to
- // the underlying stream. However, this can only occur if the current write is larger than half the buffer size and
- // we will recover after one iteration.
- // We have:
- // useBuffer = (_writePos + count + count < _bufferSize + _bufferSize)
- //
- // Example with _bufferSize = 20, _writePos = 6, count = 10:
- //
- // +---------------------------------------+---------------------------------------+
- // | current buffer | next iteration's "future" buffer |
- // +---------------------------------------+---------------------------------------+
- // |0| | | | | | | | | |1| | | | | | | | | |2| | | | | | | | | |3| | | | | | | | | |
- // |0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|0|1|2|3|4|5|6|7|8|9|
- // +-----------+-------------------+-------------------+---------------------------+
- // | _writePos | current count | assumed next count|avail buff after next write|
- // +-----------+-------------------+-------------------+---------------------------+
- //
- // A nice property (*) of this heuristic is that it will always succeed if the user data completely fits into the
- // available buffer, i.e. if count < (_bufferSize - _writePos).
- #endregion Write algorithm comment
-
- Contract.Assert(_writePos < _bufferSize);
-
- Int32 totalUserBytes;
- bool useBuffer;
- checked { // We do not expect buffer sizes big enough for an overflow, but if it happens, lets fail early:
- totalUserBytes = _writePos + count;
- useBuffer = (totalUserBytes + count < (_bufferSize + _bufferSize));
- }
-
- if (useBuffer) {
-
- WriteToBuffer(array, ref offset, ref count);
-
- if (_writePos < _bufferSize) {
-
- Contract.Assert(count == 0);
- return;
- }
-
- Contract.Assert(count >= 0);
- Contract.Assert(_writePos == _bufferSize);
- Contract.Assert(_buffer != null);
-
- _stream.Write(_buffer, 0, _writePos);
- _writePos = 0;
-
- WriteToBuffer(array, ref offset, ref count);
-
- Contract.Assert(count == 0);
- Contract.Assert(_writePos < _bufferSize);
-
- } else { // if (!useBuffer)
-
- // Write out the buffer if necessary.
- if (_writePos > 0) {
-
- Contract.Assert(_buffer != null);
- Contract.Assert(totalUserBytes >= _bufferSize);
-
- // Try avoiding extra write to underlying stream by combining previously buffered data with current user data:
- if (totalUserBytes <= (_bufferSize + _bufferSize) && totalUserBytes <= MaxShadowBufferSize) {
-
- EnsureShadowBufferAllocated();
- Buffer.InternalBlockCopy(array, offset, _buffer, _writePos, count);
- _stream.Write(_buffer, 0, totalUserBytes);
- _writePos = 0;
- return;
- }
-
- _stream.Write(_buffer, 0, _writePos);
- _writePos = 0;
- }
-
- // Write out user data.
- _stream.Write(array, offset, count);
- }
- }
-
-
-
-
- public override IAsyncResult BeginWrite(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state) {
-
- if (buffer == null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
- if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (buffer.Length - offset < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
- Contract.EndContractBlock();
-
- // Previous version incorrectly threw NotSupported instead of ObjectDisposed. We keep that behaviour for back-compat.
- // EnsureNotClosed();
- if (_stream == null) __Error.ReadNotSupported();
- EnsureCanWrite();
-
- // Try to satisfy the request from the buffer synchronously. But still need a sem-lock in case that another
- // Async IO Task accesses the buffer concurrently. If we fail to acquire the lock without waiting, make this
- // an Async operation.
- SemaphoreSlim sem = base.EnsureAsyncActiveSemaphoreInitialized();
- Task semaphoreLockTask = sem.WaitAsync();
- if (semaphoreLockTask.Status == TaskStatus.RanToCompletion) {
-
- bool completeSynchronously = true;
- try {
- if (_writePos == 0)
- ClearReadBufferBeforeWrite();
-
- // If the write completely fits into the buffer, we can complete synchronously.
- Contract.Assert(_writePos < _bufferSize);
- completeSynchronously = (count < _bufferSize - _writePos);
-
- if (completeSynchronously) {
-
- Exception error;
- WriteToBuffer(buffer, ref offset, ref count, out error);
- Contract.Assert(count == 0);
-
- SynchronousAsyncResult asyncResult = (error == null)
- ? new SynchronousAsyncResult(state)
- : new SynchronousAsyncResult(error, state, isWrite: true);
- if (callback != null)
- callback(asyncResult);
-
- return asyncResult;
- }
- } finally {
- if (completeSynchronously) // if this is FALSE, we will be entering WriteToUnderlyingStreamAsync and releasing there.
- sem.Release();
- }
- }
-
- // Delegate to the async implementation.
- return BeginWriteToUnderlyingStream(buffer, offset, count, callback, state, semaphoreLockTask);
- }
-
-
- private IAsyncResult BeginWriteToUnderlyingStream(Byte[] buffer, Int32 offset, Int32 count, AsyncCallback callback, Object state,
- Task semaphoreLockTask) {
-
- Task writeOp = WriteToUnderlyingStreamAsync(buffer, offset, count, CancellationToken.None, semaphoreLockTask, useApmPattern: true);
- return TaskToApm.Begin(writeOp, callback, state);
- }
-
-
- public override void EndWrite(IAsyncResult asyncResult) {
-
- if (asyncResult == null)
- throw new ArgumentNullException("asyncResult");
- Contract.EndContractBlock();
-
- var sAR = asyncResult as SynchronousAsyncResult;
- if (sAR != null) {
- SynchronousAsyncResult.EndWrite(asyncResult);
- return;
- }
-
- TaskToApm.End(asyncResult);
- }
-
-
- public override Task WriteAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) {
-
- if (buffer == null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
- if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (buffer.Length - offset < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
- Contract.EndContractBlock();
-
- // Fast path check for cancellation already requested
- if (cancellationToken.IsCancellationRequested)
- return Task.FromCanceled<Int32>(cancellationToken);
-
- EnsureNotClosed();
- EnsureCanWrite();
-
- // Try to satisfy the request from the buffer synchronously. But still need a sem-lock in case that another
- // Async IO Task accesses the buffer concurrently. If we fail to acquire the lock without waiting, make this
- // an Async operation.
- SemaphoreSlim sem = base.EnsureAsyncActiveSemaphoreInitialized();
- Task semaphoreLockTask = sem.WaitAsync();
- if (semaphoreLockTask.Status == TaskStatus.RanToCompletion) {
-
- bool completeSynchronously = true;
- try {
-
- if (_writePos == 0)
- ClearReadBufferBeforeWrite();
-
- Contract.Assert(_writePos < _bufferSize);
-
- // If the write completely fits into the buffer, we can complete synchronously:
- completeSynchronously = (count < _bufferSize - _writePos);
-
- if (completeSynchronously) {
-
- Exception error;
- WriteToBuffer(buffer, ref offset, ref count, out error);
- Contract.Assert(count == 0);
-
- return (error == null)
- ? Task.CompletedTask
- : Task.FromException(error);
- }
- } finally {
- if (completeSynchronously) // if this is FALSE, we will be entering WriteToUnderlyingStreamAsync and releasing there.
- sem.Release();
- }
- }
-
- // Delegate to the async implementation.
- return WriteToUnderlyingStreamAsync(buffer, offset, count, cancellationToken, semaphoreLockTask, useApmPattern: false);
- }
-
-
- /// <summary>BufferedStream should be as thin a wrapper as possible. We want that WriteAsync delegates to
- /// WriteAsync of the underlying _stream and that BeginWrite delegates to BeginWrite of the underlying stream,
- /// rather than calling the base Stream which implements the one in terms of the other. This allows BufferedStream
- /// to affect the semantics of the stream it wraps as little as possible. At the same time, we want to share as
- /// much code between the APM and the Async pattern implementations as possible. This method is called by both with
- /// a corresponding useApmPattern value. Recall that Task implements IAsyncResult.</summary>
- private async Task WriteToUnderlyingStreamAsync(Byte[] array, Int32 offset, Int32 count,
- CancellationToken cancellationToken,
- Task semaphoreLockTask, bool useApmPattern) {
-
- // (These should be Contract.Requires(..) but that method had some issues in async methods; using Assert(..) for now.)
- Contract.Assert(array != null);
- Contract.Assert(offset >= 0);
- Contract.Assert(count >= 0);
- Contract.Assert(array.Length - offset >= count);
- Contract.Assert(_stream != null);
- Contract.Assert(_stream.CanWrite);
- Contract.Assert(_bufferSize > 0);
- Contract.Assert(semaphoreLockTask != null);
-
- // See the LARGE COMMENT in Write(..) for the explanation of the write buffer algorithm.
-
- await semaphoreLockTask.ConfigureAwait(false);
- try {
-
- // The buffer might have been changed by another async task while we were waiting on the semaphore.
- // However, note that if we recalculate the sync completion condition to TRUE, then useBuffer will also be TRUE.
-
- if (_writePos == 0)
- ClearReadBufferBeforeWrite();
-
- Int32 totalUserBytes;
- bool useBuffer;
- checked { // We do not expect buffer sizes big enough for an overflow, but if it happens, lets fail early:
- totalUserBytes = _writePos + count;
- useBuffer = (totalUserBytes + count < (_bufferSize + _bufferSize));
- }
-
- if (useBuffer) {
-
- WriteToBuffer(array, ref offset, ref count);
-
- if (_writePos < _bufferSize) {
-
- Contract.Assert(count == 0);
- return;
- }
-
- Contract.Assert(count >= 0);
- Contract.Assert(_writePos == _bufferSize);
- Contract.Assert(_buffer != null);
-
- if (useApmPattern) {
- EnsureBeginEndAwaitableAllocated();
- _stream.BeginWrite(_buffer, 0, _writePos, BeginEndAwaitableAdapter.Callback, _beginEndAwaitable);
- _stream.EndWrite(await _beginEndAwaitable);
- } else {
- await _stream.WriteAsync(_buffer, 0, _writePos, cancellationToken).ConfigureAwait(false);
- }
- _writePos = 0;
-
- WriteToBuffer(array, ref offset, ref count);
-
- Contract.Assert(count == 0);
- Contract.Assert(_writePos < _bufferSize);
-
- } else { // if (!useBuffer)
-
- // Write out the buffer if necessary.
- if (_writePos > 0) {
-
- Contract.Assert(_buffer != null);
- Contract.Assert(totalUserBytes >= _bufferSize);
-
- // Try avoiding extra write to underlying stream by combining previously buffered data with current user data:
- if (totalUserBytes <= (_bufferSize + _bufferSize) && totalUserBytes <= MaxShadowBufferSize) {
-
- EnsureShadowBufferAllocated();
- Buffer.InternalBlockCopy(array, offset, _buffer, _writePos, count);
- if (useApmPattern) {
- EnsureBeginEndAwaitableAllocated();
- _stream.BeginWrite(_buffer, 0, totalUserBytes, BeginEndAwaitableAdapter.Callback, _beginEndAwaitable);
- _stream.EndWrite(await _beginEndAwaitable);
- } else {
- await _stream.WriteAsync(_buffer, 0, totalUserBytes, cancellationToken).ConfigureAwait(false);
- }
- _writePos = 0;
- return;
- }
-
- if (useApmPattern) {
- EnsureBeginEndAwaitableAllocated();
- _stream.BeginWrite(_buffer, 0, _writePos, BeginEndAwaitableAdapter.Callback, _beginEndAwaitable);
- _stream.EndWrite(await _beginEndAwaitable);
- } else {
- await _stream.WriteAsync(_buffer, 0, _writePos, cancellationToken).ConfigureAwait(false);
- }
- _writePos = 0;
- }
-
- // Write out user data.
- if (useApmPattern) {
- EnsureBeginEndAwaitableAllocated();
- _stream.BeginWrite(array, offset, count, BeginEndAwaitableAdapter.Callback, _beginEndAwaitable);
- _stream.EndWrite(await _beginEndAwaitable);
- } else {
- await _stream.WriteAsync(array, offset, count, cancellationToken).ConfigureAwait(false);
- }
- }
- } finally {
- SemaphoreSlim sem = base.EnsureAsyncActiveSemaphoreInitialized();
- sem.Release();
- }
- }
-
-
- public override void WriteByte(Byte value) {
-
- EnsureNotClosed();
-
- if (_writePos == 0) {
-
- EnsureCanWrite();
- ClearReadBufferBeforeWrite();
- EnsureBufferAllocated();
- }
-
- // We should not be flushing here, but only writing to the underlying stream, but previous version flushed, so we keep this.
- if (_writePos >= _bufferSize - 1)
- FlushWrite();
-
- _buffer[_writePos++] = value;
-
- Contract.Assert(_writePos < _bufferSize);
- }
-
-
- public override Int64 Seek(Int64 offset, SeekOrigin origin) {
-
- EnsureNotClosed();
- EnsureCanSeek();
-
- // If we have bytes in the WRITE buffer, flush them out, seek and be done.
- if (_writePos > 0) {
-
- // We should be only writing the buffer and not flushing,
- // but the previous version did flush and we stick to it for back-compat reasons.
- FlushWrite();
- return _stream.Seek(offset, origin);
- }
-
- // The buffer is either empty or we have a buffered READ.
-
- if (_readLen - _readPos > 0 && origin == SeekOrigin.Current) {
-
- // If we have bytes in the READ buffer, adjust the seek offset to account for the resulting difference
- // between this stream's position and the underlying stream's position.
- offset -= (_readLen - _readPos);
- }
-
- Int64 oldPos = Position;
- Contract.Assert(oldPos == _stream.Position + (_readPos - _readLen));
-
- Int64 newPos = _stream.Seek(offset, origin);
-
- // If the seek destination is still within the data currently in the buffer, we want to keep the buffer data and continue using it.
- // Otherwise we will throw away the buffer. This can only happen on READ, as we flushed WRITE data above.
-
- // The offset of the new/updated seek pointer within _buffer:
- _readPos = (Int32) (newPos - (oldPos - _readPos));
-
- // If the offset of the updated seek pointer in the buffer is still legal, then we can keep using the buffer:
- if (0 <= _readPos && _readPos < _readLen) {
-
- // Adjust the seek pointer of the underlying stream to reflect the amount of useful bytes in the read buffer:
- _stream.Seek(_readLen - _readPos, SeekOrigin.Current);
-
- } else { // The offset of the updated seek pointer is not a legal offset. Loose the buffer.
-
- _readPos = _readLen = 0;
- }
-
- Contract.Assert(newPos == Position, "newPos (=" + newPos + ") == Position (=" + Position + ")");
- return newPos;
- }
-
-
- public override void SetLength(Int64 value) {
-
- if (value < 0)
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_NegFileSize"));
- Contract.EndContractBlock();
-
- EnsureNotClosed();
- EnsureCanSeek();
- EnsureCanWrite();
-
- Flush();
- _stream.SetLength(value);
- }
-
-} // class BufferedStream
-} // namespace
diff --git a/src/mscorlib/src/System/IO/Directory.cs b/src/mscorlib/src/System/IO/Directory.cs
index be74538d2d..d6b68222cd 100644
--- a/src/mscorlib/src/System/IO/Directory.cs
+++ b/src/mscorlib/src/System/IO/Directory.cs
@@ -15,168 +15,70 @@
**
===========================================================*/
-using System;
-using System.Collections;
using System.Collections.Generic;
using System.Security;
using System.Security.Permissions;
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
-using System.Text;
using System.Runtime.InteropServices;
-using System.Globalization;
-using System.Runtime.Versioning;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
-using System.Threading;
-#if FEATURE_MACL
-using System.Security.AccessControl;
-#endif
-
-namespace System.IO {
+namespace System.IO
+{
[ComVisible(true)]
public static class Directory {
public static DirectoryInfo GetParent(String path)
{
if (path==null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (path.Length==0)
- throw new ArgumentException(Environment.GetResourceString("Argument_PathEmpty"), "path");
+ throw new ArgumentException(Environment.GetResourceString("Argument_PathEmpty"), nameof(path));
Contract.EndContractBlock();
- String fullPath = Path.GetFullPathInternal(path);
-
- String s = Path.GetDirectoryName(fullPath);
+ string fullPath = Path.GetFullPath(path);
+
+ string s = Path.GetDirectoryName(fullPath);
if (s==null)
return null;
return new DirectoryInfo(s);
}
- [System.Security.SecuritySafeCritical]
public static DirectoryInfo CreateDirectory(String path) {
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (path.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_PathEmpty"));
Contract.EndContractBlock();
- return InternalCreateDirectoryHelper(path, true);
+ return InternalCreateDirectoryHelper(path);
}
- [System.Security.SecurityCritical]
- internal static DirectoryInfo UnsafeCreateDirectory(String path)
- {
- if (path == null)
- throw new ArgumentNullException("path");
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_PathEmpty"));
- Contract.EndContractBlock();
-
- return InternalCreateDirectoryHelper(path, false);
- }
-
- [System.Security.SecurityCritical]
- internal static DirectoryInfo InternalCreateDirectoryHelper(String path, bool checkHost)
+ internal static DirectoryInfo InternalCreateDirectoryHelper(String path)
{
Contract.Requires(path != null);
Contract.Requires(path.Length != 0);
- String fullPath = Path.GetFullPathInternal(path);
-
- // You need read access to the directory to be returned back and write access to all the directories
- // that you need to create. If we fail any security checks we will not create any directories at all.
- // We attempt to create directories only after all the security checks have passed. This is avoid doing
- // a demand at every level.
- String demandDir = GetDemandDir(fullPath, true);
-
-#if FEATURE_CORECLR
- if (checkHost)
- {
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, path, demandDir);
- state.EnsureState(); // do the check on the AppDomainManager to make sure this is allowed
- }
-#else
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, demandDir, false, false);
-#endif
-
- InternalCreateDirectory(fullPath, path, null, checkHost);
-
- return new DirectoryInfo(fullPath, false);
- }
-
-#if FEATURE_MACL
- [System.Security.SecuritySafeCritical] // auto-generated
- public static DirectoryInfo CreateDirectory(String path, DirectorySecurity directorySecurity) {
- if (path==null)
- throw new ArgumentNullException("path");
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_PathEmpty"));
- Contract.EndContractBlock();
-
- String fullPath = Path.GetFullPathInternal(path);
+ String fullPath = Path.GetFullPath(path);
- // You need read access to the directory to be returned back and write access to all the directories
- // that you need to create. If we fail any security checks we will not create any directories at all.
- // We attempt to create directories only after all the security checks have passed. This is avoid doing
- // a demand at every level.
- String demandDir = GetDemandDir(fullPath, true);
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, demandDir, false, false );
+ InternalCreateDirectory(fullPath, path, null);
- InternalCreateDirectory(fullPath, path, directorySecurity);
-
return new DirectoryInfo(fullPath, false);
}
-#endif // FEATURE_MACL
- // Input to this method should already be fullpath. This method will ensure that we append
- // the trailing slash only when appropriate and when thisDirOnly is specified append a "."
- // at the end of the path to indicate that the demand is only for the fullpath and not
- // everything underneath it.
- internal static String GetDemandDir(string fullPath, bool thisDirOnly)
+ internal unsafe static void InternalCreateDirectory(String fullPath, String path, Object dirSecurityObj)
{
- String demandPath;
-
- if (thisDirOnly) {
- if (fullPath.EndsWith( Path.DirectorySeparatorChar )
- || fullPath.EndsWith( Path.AltDirectorySeparatorChar ) )
- demandPath = fullPath + ".";
- else
- demandPath = fullPath + Path.DirectorySeparatorCharAsString + ".";
- }
- else {
- if (!(fullPath.EndsWith( Path.DirectorySeparatorChar )
- || fullPath.EndsWith( Path.AltDirectorySeparatorChar )) )
- demandPath = fullPath + Path.DirectorySeparatorCharAsString;
- else
- demandPath = fullPath;
- }
- return demandPath;
- }
-
- internal static void InternalCreateDirectory(String fullPath, String path, Object dirSecurityObj)
- {
- InternalCreateDirectory(fullPath, path, dirSecurityObj, false);
- }
-
-
- [System.Security.SecuritySafeCritical]
- internal unsafe static void InternalCreateDirectory(String fullPath, String path, Object dirSecurityObj, bool checkHost)
- {
-#if FEATURE_MACL
- DirectorySecurity dirSecurity = (DirectorySecurity)dirSecurityObj;
-#endif // FEATURE_MACL
-
int length = fullPath.Length;
// We need to trim the trailing slash or the code will try to create 2 directories of the same name.
- if (length >= 2 && Path.IsDirectorySeparator(fullPath[length - 1]))
+ if (length >= 2 && PathInternal.IsDirectorySeparator(fullPath[length - 1]))
length--;
- int lengthRoot = Path.GetRootLength(fullPath);
+ int lengthRoot = PathInternal.GetRootLength(fullPath);
// For UNC paths that are only // or ///
- if (length == 2 && Path.IsDirectorySeparator(fullPath[1]))
+ if (length == 2 && PathInternal.IsDirectorySeparator(fullPath[1]))
throw new IOException(Environment.GetResourceString("IO.IO_CannotCreateDirectory", path));
// We can save a bunch of work if the directory we want to create already exists. This also
@@ -215,56 +117,9 @@ namespace System.IO {
int count = stackDir.Count;
- if (stackDir.Count != 0
-#if FEATURE_CAS_POLICY
- // All demands in full trust domains are no-ops, so skip
- //
- // The full path went through validity checks by being passed through FileIOPermissions already.
- // As a sub string of the full path can't fail the checks if the full path passes.
- && !CodeAccessSecurityEngine.QuickCheckForAllDemands()
-#endif
- )
- {
- String[] securityList = new String[stackDir.Count];
- stackDir.CopyTo(securityList, 0);
- for (int j = 0 ; j < securityList.Length; j++)
- securityList[j] += "\\."; // leaf will never have a slash at the end
-
- // Security check for all directories not present only.
-#if FEATURE_MACL
- AccessControlActions control = (dirSecurity == null) ? AccessControlActions.None : AccessControlActions.Change;
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, control, securityList, false, false);
-#else
-#if FEATURE_CORECLR
- if (checkHost)
- {
- foreach (String demandPath in securityList)
- {
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Write, String.Empty, demandPath);
- state.EnsureState();
- }
- }
-#else
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, securityList, false, false);
-#endif
-#endif //FEATURE_MACL
- }
-
// If we were passed a DirectorySecurity, convert it to a security
// descriptor and set it in he call to CreateDirectory.
Win32Native.SECURITY_ATTRIBUTES secAttrs = null;
-#if FEATURE_MACL
- if (dirSecurity != null) {
- secAttrs = new Win32Native.SECURITY_ATTRIBUTES();
- secAttrs.nLength = (int)Marshal.SizeOf(secAttrs);
-
- // For ACL's, get the security descriptor from the FileSecurity.
- byte[] sd = dirSecurity.GetSecurityDescriptorBinaryForm();
- byte * bytesOnStack = stackalloc byte[sd.Length];
- Buffer.Memcpy(bytesOnStack, 0, sd, 0, sd.Length);
- secAttrs.pSecurityDescriptor = bytesOnStack;
- }
-#endif
bool r = true;
int firstError = 0;
@@ -290,22 +145,10 @@ namespace System.IO {
firstError = currentError;
else {
// If there's a file in this directory's place, or if we have ERROR_ACCESS_DENIED when checking if the directory already exists throw.
- if (File.InternalExists(name) || (!InternalExists(name, out currentError) && currentError == Win32Native.ERROR_ACCESS_DENIED)) {
+ if (File.InternalExists(name) || (!InternalExists(name, out currentError) && currentError == Win32Native.ERROR_ACCESS_DENIED))
+ {
firstError = currentError;
- // Give the user a nice error message, but don't leak path information.
- try {
-#if FEATURE_CORECLR
- if (checkHost)
- {
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, GetDemandDir(name, true));
- state.EnsureState();
- }
-#else
- FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, GetDemandDir(name, true));
-#endif // FEATURE_CORECLR
- errorString = name;
- }
- catch(SecurityException) {}
+ errorString = name;
}
}
}
@@ -335,20 +178,12 @@ namespace System.IO {
// Your application must have Read permission to the directory's
// contents.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public static bool Exists(String path)
{
- return InternalExistsHelper(path, true);
- }
-
- [System.Security.SecurityCritical]
- internal static bool UnsafeExists(String path)
- {
- return InternalExistsHelper(path, false);
+ return InternalExistsHelper(path);
}
- [System.Security.SecurityCritical]
- internal static bool InternalExistsHelper(String path, bool checkHost) {
+ internal static bool InternalExistsHelper(String path) {
try
{
if (path == null)
@@ -356,23 +191,7 @@ namespace System.IO {
if (path.Length == 0)
return false;
- // Get fully qualified file name ending in \* for security check
-
- String fullPath = Path.GetFullPathInternal(path);
- String demandPath = GetDemandDir(fullPath, true);
-
-#if FEATURE_CORECLR
- if (checkHost)
- {
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, path, demandPath);
- state.EnsureState();
- }
-#else
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, demandPath, false, false);
-#endif
-
-
- return InternalExists(fullPath);
+ return InternalExists(Path.GetFullPath(path));
}
catch (ArgumentException) { }
catch (NotSupportedException) { } // Security can throw this on ":"
@@ -380,14 +199,13 @@ namespace System.IO {
catch (IOException) { }
catch (UnauthorizedAccessException)
{
- Contract.Assert(false, "Ignore this assert and send a repro to Microsoft. This assert was tracking purposes only.");
+ Debug.Assert(false, "Ignore this assert and send a repro to Microsoft. This assert was tracking purposes only.");
}
return false;
}
// Determine whether path describes an existing directory
// on disk, avoiding security checks.
- [System.Security.SecurityCritical] // auto-generated
internal static bool InternalExists(String path) {
int lastError = Win32Native.ERROR_SUCCESS;
return InternalExists(path, out lastError);
@@ -395,7 +213,6 @@ namespace System.IO {
// Determine whether path describes an existing directory
// on disk, avoiding security checks.
- [System.Security.SecurityCritical] // auto-generated
internal static bool InternalExists(String path, out int lastError) {
Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
lastError = File.FillAttributeInfo(path, ref data, false, true);
@@ -404,25 +221,6 @@ namespace System.IO {
&& ((data.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) != 0);
}
- public static void SetCreationTime(String path,DateTime creationTime)
- {
- SetCreationTimeUtc(path, creationTime.ToUniversalTime());
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public unsafe static void SetCreationTimeUtc(String path,DateTime creationTimeUtc)
- {
- using (SafeFileHandle handle = Directory.OpenHandle(path)) {
- Win32Native.FILE_TIME fileTime = new Win32Native.FILE_TIME(creationTimeUtc.ToFileTimeUtc());
- bool r = Win32Native.SetFileTime(handle, &fileTime, null, null);
- if (!r)
- {
- int errorCode = Marshal.GetLastWin32Error();
- __Error.WinIOError(errorCode, path);
- }
- }
- }
-
public static DateTime GetCreationTime(String path)
{
return File.GetCreationTime(path);
@@ -433,25 +231,6 @@ namespace System.IO {
return File.GetCreationTimeUtc(path);
}
- public static void SetLastWriteTime(String path,DateTime lastWriteTime)
- {
- SetLastWriteTimeUtc(path, lastWriteTime.ToUniversalTime());
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public unsafe static void SetLastWriteTimeUtc(String path,DateTime lastWriteTimeUtc)
- {
- using (SafeFileHandle handle = Directory.OpenHandle(path)) {
- Win32Native.FILE_TIME fileTime = new Win32Native.FILE_TIME(lastWriteTimeUtc.ToFileTimeUtc());
- bool r = Win32Native.SetFileTime(handle, null, null, &fileTime);
- if (!r)
- {
- int errorCode = Marshal.GetLastWin32Error();
- __Error.WinIOError(errorCode, path);
- }
- }
- }
-
public static DateTime GetLastWriteTime(String path)
{
return File.GetLastWriteTime(path);
@@ -462,25 +241,6 @@ namespace System.IO {
return File.GetLastWriteTimeUtc(path);
}
- public static void SetLastAccessTime(String path,DateTime lastAccessTime)
- {
- SetLastAccessTimeUtc(path, lastAccessTime.ToUniversalTime());
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public unsafe static void SetLastAccessTimeUtc(String path,DateTime lastAccessTimeUtc)
- {
- using (SafeFileHandle handle = Directory.OpenHandle(path)) {
- Win32Native.FILE_TIME fileTime = new Win32Native.FILE_TIME(lastAccessTimeUtc.ToFileTimeUtc());
- bool r = Win32Native.SetFileTime(handle, null, &fileTime, null);
- if (!r)
- {
- int errorCode = Marshal.GetLastWin32Error();
- __Error.WinIOError(errorCode, path);
- }
- }
- }
-
public static DateTime GetLastAccessTime(String path)
{
return File.GetLastAccessTime(path);
@@ -489,36 +249,13 @@ namespace System.IO {
public static DateTime GetLastAccessTimeUtc(String path)
{
return File.GetLastAccessTimeUtc(path);
- }
-
-#if FEATURE_MACL
- public static DirectorySecurity GetAccessControl(String path)
- {
- return new DirectorySecurity(path, AccessControlSections.Access | AccessControlSections.Owner | AccessControlSections.Group);
}
- public static DirectorySecurity GetAccessControl(String path, AccessControlSections includeSections)
- {
- return new DirectorySecurity(path, includeSections);
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public static void SetAccessControl(String path, DirectorySecurity directorySecurity)
- {
- if (directorySecurity == null)
- throw new ArgumentNullException("directorySecurity");
- Contract.EndContractBlock();
-
- String fullPath = Path.GetFullPathInternal(path);
- directorySecurity.Persist(fullPath);
- }
-#endif
-
// Returns an array of filenames in the DirectoryInfo specified by path
public static String[] GetFiles(String path)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
Contract.Ensures(Contract.Result<String[]>() != null);
Contract.EndContractBlock();
@@ -530,9 +267,9 @@ namespace System.IO {
public static String[] GetFiles(String path, String searchPattern)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
Contract.Ensures(Contract.Result<String[]>() != null);
Contract.EndContractBlock();
@@ -544,11 +281,11 @@ namespace System.IO {
public static String[] GetFiles(String path, String searchPattern, SearchOption searchOption)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException("searchOption", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
Contract.Ensures(Contract.Result<String[]>() != null);
Contract.EndContractBlock();
@@ -566,7 +303,6 @@ namespace System.IO {
return InternalGetFileDirectoryNames(path, path, searchPattern, true, false, searchOption, true);
}
- [System.Security.SecurityCritical]
internal static String[] UnsafeGetFiles(String path, String searchPattern, SearchOption searchOption)
{
Contract.Requires(path != null);
@@ -580,7 +316,7 @@ namespace System.IO {
public static String[] GetDirectories(String path)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
Contract.Ensures(Contract.Result<String[]>() != null);
Contract.EndContractBlock();
@@ -592,9 +328,9 @@ namespace System.IO {
public static String[] GetDirectories(String path, String searchPattern)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
Contract.Ensures(Contract.Result<String[]>() != null);
Contract.EndContractBlock();
@@ -606,11 +342,11 @@ namespace System.IO {
public static String[] GetDirectories(String path, String searchPattern, SearchOption searchOption)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException("searchOption", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
Contract.Ensures(Contract.Result<String[]>() != null);
Contract.EndContractBlock();
@@ -629,7 +365,6 @@ namespace System.IO {
return InternalGetFileDirectoryNames(path, path, searchPattern, false, true, searchOption, true);
}
- [System.Security.SecurityCritical]
internal static String[] UnsafeGetDirectories(String path, String searchPattern, SearchOption searchOption)
{
Contract.Requires(path != null);
@@ -644,7 +379,7 @@ namespace System.IO {
public static String[] GetFileSystemEntries(String path)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
Contract.Ensures(Contract.Result<String[]>() != null);
Contract.EndContractBlock();
@@ -656,9 +391,9 @@ namespace System.IO {
public static String[] GetFileSystemEntries(String path, String searchPattern)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
Contract.Ensures(Contract.Result<String[]>() != null);
Contract.EndContractBlock();
@@ -670,11 +405,11 @@ namespace System.IO {
public static String[] GetFileSystemEntries(String path, String searchPattern, SearchOption searchOption)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException("searchOption", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
Contract.Ensures(Contract.Result<String[]>() != null);
Contract.EndContractBlock();
@@ -690,7 +425,6 @@ namespace System.IO {
return InternalGetFileDirectoryNames(path, path, searchPattern, true, true, searchOption, true);
}
-
// Private class that holds search data that is passed around
// in the heap based stack recursion
internal sealed class SearchData
@@ -734,7 +468,7 @@ namespace System.IO {
public static IEnumerable<String> EnumerateDirectories(String path)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
Contract.EndContractBlock();
return InternalEnumerateDirectories(path, "*", SearchOption.TopDirectoryOnly);
@@ -743,9 +477,9 @@ namespace System.IO {
public static IEnumerable<String> EnumerateDirectories(String path, String searchPattern)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
Contract.EndContractBlock();
return InternalEnumerateDirectories(path, searchPattern, SearchOption.TopDirectoryOnly);
@@ -754,11 +488,11 @@ namespace System.IO {
public static IEnumerable<String> EnumerateDirectories(String path, String searchPattern, SearchOption searchOption)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException("searchOption", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
Contract.EndContractBlock();
return InternalEnumerateDirectories(path, searchPattern, searchOption);
@@ -776,7 +510,7 @@ namespace System.IO {
public static IEnumerable<String> EnumerateFiles(String path)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
Contract.Ensures(Contract.Result<IEnumerable<String>>() != null);
Contract.EndContractBlock();
@@ -786,9 +520,9 @@ namespace System.IO {
public static IEnumerable<String> EnumerateFiles(String path, String searchPattern)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
Contract.Ensures(Contract.Result<IEnumerable<String>>() != null);
Contract.EndContractBlock();
@@ -798,11 +532,11 @@ namespace System.IO {
public static IEnumerable<String> EnumerateFiles(String path, String searchPattern, SearchOption searchOption)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException("searchOption", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
Contract.Ensures(Contract.Result<IEnumerable<String>>() != null);
Contract.EndContractBlock();
@@ -822,7 +556,7 @@ namespace System.IO {
public static IEnumerable<String> EnumerateFileSystemEntries(String path)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
Contract.Ensures(Contract.Result<IEnumerable<String>>() != null);
Contract.EndContractBlock();
@@ -832,9 +566,9 @@ namespace System.IO {
public static IEnumerable<String> EnumerateFileSystemEntries(String path, String searchPattern)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
Contract.Ensures(Contract.Result<IEnumerable<String>>() != null);
Contract.EndContractBlock();
@@ -844,11 +578,11 @@ namespace System.IO {
public static IEnumerable<String> EnumerateFileSystemEntries(String path, String searchPattern, SearchOption searchOption)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException("searchOption", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
Contract.Ensures(Contract.Result<IEnumerable<String>>() != null);
Contract.EndContractBlock();
@@ -882,7 +616,6 @@ namespace System.IO {
//
// Your application must have System Info permission.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public static String[] GetLogicalDrives()
{
Contract.Ensures(Contract.Result<String[]>() != null);
@@ -914,29 +647,20 @@ namespace System.IO {
return result;
}
- [System.Security.SecuritySafeCritical]
public static String GetDirectoryRoot(String path) {
if (path==null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
Contract.EndContractBlock();
-
- String fullPath = Path.GetFullPathInternal(path);
- String root = fullPath.Substring(0, Path.GetRootLength(fullPath));
- String demandPath = GetDemandDir(root, true);
-
-#if FEATURE_CORECLR
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, path, demandPath);
- state.EnsureState();
-#else
- FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, demandPath, false, false);
-#endif
-
+
+ string fullPath = Path.GetFullPath(path);
+ string root = fullPath.Substring(0, PathInternal.GetRootLength(fullPath));
+
return root;
}
internal static String InternalGetDirectoryRoot(String path) {
if (path == null) return null;
- return path.Substring(0, Path.GetRootLength(path));
+ return path.Substring(0, PathInternal.GetRootLength(path));
}
/*===============================CurrentDirectory===============================
@@ -946,77 +670,10 @@ namespace System.IO {
**Arguments: The current DirectoryInfo to which to switch to the setter.
**Exceptions:
==============================================================================*/
- [System.Security.SecuritySafeCritical]
public static String GetCurrentDirectory()
{
- return InternalGetCurrentDirectory(true);
- }
-
- [System.Security.SecurityCritical]
- internal static String UnsafeGetCurrentDirectory()
- {
- return InternalGetCurrentDirectory(false);
- }
-
- [System.Security.SecuritySafeCritical]
- private static string InternalGetCurrentDirectory(bool checkHost)
- {
- string currentDirectory = (
-#if FEATURE_PATHCOMPAT
- AppContextSwitches.UseLegacyPathHandling ? LegacyGetCurrentDirectory() :
-#endif
- NewGetCurrentDirectory());
-
- string demandPath = GetDemandDir(currentDirectory, true);
-
-#if FEATURE_CORECLR
- if (checkHost)
- {
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, demandPath);
- state.EnsureState();
- }
-#else
- FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, demandPath, false, false);
-#endif
- return currentDirectory;
- }
-
-#if FEATURE_PATHCOMPAT
- [System.Security.SecurityCritical]
- private static String LegacyGetCurrentDirectory()
- {
- StringBuilder sb = StringBuilderCache.Acquire(Path.MaxPath + 1);
- if (Win32Native.GetCurrentDirectory(sb.Capacity, sb) == 0)
- __Error.WinIOError();
- String currentDirectory = sb.ToString();
- // Note that if we have somehow put our command prompt into short
- // file name mode (ie, by running edlin or a DOS grep, etc), then
- // this will return a short file name.
- if (currentDirectory.IndexOf('~') >= 0) {
- int r = Win32Native.GetLongPathName(currentDirectory, sb, sb.Capacity);
- if (r == 0 || r >= Path.MaxPath) {
- int errorCode = Marshal.GetLastWin32Error();
- if (r >= Path.MaxPath)
- errorCode = Win32Native.ERROR_FILENAME_EXCED_RANGE;
- if (errorCode != Win32Native.ERROR_FILE_NOT_FOUND &&
- errorCode != Win32Native.ERROR_PATH_NOT_FOUND &&
- errorCode != Win32Native.ERROR_INVALID_FUNCTION && // by design - enough said.
- errorCode != Win32Native.ERROR_ACCESS_DENIED)
- __Error.WinIOError(errorCode, String.Empty);
- }
- currentDirectory = sb.ToString();
- }
- StringBuilderCache.Release(sb);
- String demandPath = GetDemandDir(currentDirectory, true);
-
- return currentDirectory;
- }
-#endif // FEATURE_PATHCOMPAT
-
- [System.Security.SecurityCritical]
- private static string NewGetCurrentDirectory()
- {
- using (StringBuffer buffer = new StringBuffer(PathInternal.MaxShortPath))
+ // Start with a buffer the size of MAX_PATH
+ using (StringBuffer buffer = new StringBuffer(260))
{
uint result = 0;
while ((result = Win32Native.GetCurrentDirectoryW(buffer.CharCapacity, buffer.GetHandle())) > buffer.CharCapacity)
@@ -1033,35 +690,23 @@ namespace System.IO {
#if !PLATFORM_UNIX
if (buffer.Contains('~'))
- return LongPathHelper.GetLongPathName(buffer);
+ return Path.GetFullPath(buffer.ToString());
#endif
return buffer.ToString();
}
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #else
- [System.Security.SecuritySafeCritical]
- #endif
public static void SetCurrentDirectory(String path)
{
if (path==null)
throw new ArgumentNullException("value");
if (path.Length==0)
throw new ArgumentException(Environment.GetResourceString("Argument_PathEmpty"));
- Contract.EndContractBlock();
if (path.Length >= Path.MaxPath)
throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
-
- // This will have some large effects on the rest of the runtime
- // and other appdomains in this process. Demand unmanaged code.
-#pragma warning disable 618
- new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
-#pragma warning restore 618
- String fulldestDirName = Path.GetFullPathInternal(path);
+ String fulldestDirName = Path.GetFullPath(path);
if (!Win32Native.SetCurrentDirectory(fulldestDirName)) {
// If path doesn't exist, this sets last error to 2 (File
@@ -1074,52 +719,19 @@ namespace System.IO {
}
}
- [System.Security.SecuritySafeCritical]
- public static void Move(String sourceDirName,String destDirName) {
- InternalMove(sourceDirName, destDirName, true);
- }
-
- [System.Security.SecurityCritical]
- internal static void UnsafeMove(String sourceDirName,String destDirName) {
- InternalMove(sourceDirName, destDirName, false);
- }
-
- [System.Security.SecurityCritical]
- private static void InternalMove(String sourceDirName,String destDirName,bool checkHost) {
+ public static void Move(String sourceDirName,String destDirName)
+ {
if (sourceDirName==null)
- throw new ArgumentNullException("sourceDirName");
+ throw new ArgumentNullException(nameof(sourceDirName));
if (sourceDirName.Length==0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "sourceDirName");
-
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(sourceDirName));
if (destDirName==null)
- throw new ArgumentNullException("destDirName");
+ throw new ArgumentNullException(nameof(destDirName));
if (destDirName.Length==0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "destDirName");
- Contract.EndContractBlock();
-
- String fullsourceDirName = Path.GetFullPathInternal(sourceDirName);
- String sourcePath = GetDemandDir(fullsourceDirName, false);
-
- if (PathInternal.IsDirectoryTooLong(sourcePath))
- throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
-
- String fulldestDirName = Path.GetFullPathInternal(destDirName);
- String destPath = GetDemandDir(fulldestDirName, false);
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destDirName));
- if (PathInternal.IsDirectoryTooLong(destPath))
- throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
-
-#if FEATURE_CORECLR
- if (checkHost) {
- FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Write | FileSecurityStateAccess.Read, sourceDirName, sourcePath);
- FileSecurityState destState = new FileSecurityState(FileSecurityStateAccess.Write, destDirName, destPath);
- sourceState.EnsureState();
- destState.EnsureState();
- }
-#else
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, sourcePath, false, false);
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, destPath, false, false);
-#endif
+ String sourcePath = Path.GetFullPath(sourceDirName);
+ String destPath = Path.GetFullPath(destDirName);
if (String.Compare(sourcePath, destPath, StringComparison.OrdinalIgnoreCase) == 0)
throw new IOException(Environment.GetResourceString("IO.IO_SourceDestMustBeDifferent"));
@@ -1135,7 +747,7 @@ namespace System.IO {
if (hr == Win32Native.ERROR_FILE_NOT_FOUND) // Source dir not found
{
hr = Win32Native.ERROR_PATH_NOT_FOUND;
- __Error.WinIOError(hr, fullsourceDirName);
+ __Error.WinIOError(hr, sourcePath);
}
// This check was originally put in for Win9x (unfortunately without special casing it to be for Win9x only). We can't change the NT codepath now for backcomp reasons.
if (hr == Win32Native.ERROR_ACCESS_DENIED) // WinNT throws IOException. This check is for Win9x. We can't change it for backcomp.
@@ -1144,49 +756,22 @@ namespace System.IO {
}
}
- [System.Security.SecuritySafeCritical]
public static void Delete(String path)
{
- String fullPath = Path.GetFullPathInternal(path);
- Delete(fullPath, path, false, true);
+ String fullPath = Path.GetFullPath(path);
+ Delete(fullPath, path, false);
}
- [System.Security.SecuritySafeCritical]
public static void Delete(String path, bool recursive)
{
- String fullPath = Path.GetFullPathInternal(path);
- Delete(fullPath, path, recursive, true);
+ String fullPath = Path.GetFullPath(path);
+ Delete(fullPath, path, recursive);
}
- [System.Security.SecurityCritical]
- internal static void UnsafeDelete(String path, bool recursive)
- {
- String fullPath = Path.GetFullPathInternal(path);
- Delete(fullPath, path, recursive, false);
- }
-
- // Called from DirectoryInfo as well. FullPath is fully qualified,
+ // Called from DirectoryInfo as well. FullPath is fully qualified,
// while the user path is used for feedback in exceptions.
- [System.Security.SecurityCritical] // auto-generated
- internal static void Delete(String fullPath, String userPath, bool recursive, bool checkHost)
+ internal static void Delete(String fullPath, String userPath, bool recursive)
{
- String demandPath;
-
- // If not recursive, do permission check only on this directory
- // else check for the whole directory structure rooted below
- demandPath = GetDemandDir(fullPath, !recursive);
-
-#if FEATURE_CORECLR
- if (checkHost)
- {
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Write, userPath, demandPath);
- state.EnsureState();
- }
-#else
- // Make sure we have write permission to this directory
- new FileIOPermission(FileIOPermissionAccess.Write, new String[] { demandPath }, false, false ).Demand();
-#endif
-
// Do not recursively delete through reparse points. Perhaps in a
// future version we will add a new flag to control this behavior,
// but for now we're much safer if we err on the conservative side.
@@ -1206,10 +791,7 @@ namespace System.IO {
DeleteHelper(fullPath, userPath, recursive, true);
}
- // Note that fullPath is fully qualified, while userPath may be
- // relative. Use userPath for all exception messages to avoid leaking
- // fully qualified path information.
- [System.Security.SecurityCritical] // auto-generated
+ // Note that fullPath is fully qualified, while userPath may be relative.
private static void DeleteHelper(String fullPath, String userPath, bool recursive, bool throwOnTopLevelDirectoryNotFound)
{
bool r;
@@ -1229,12 +811,12 @@ namespace System.IO {
Win32Native.WIN32_FIND_DATA data = new Win32Native.WIN32_FIND_DATA();
// Open a Find handle
- using (SafeFindHandle hnd = Win32Native.FindFirstFile(fullPath+Path.DirectorySeparatorCharAsString+"*", data)) {
+ using (SafeFindHandle hnd = Win32Native.FindFirstFile(fullPath + Path.DirectorySeparatorChar + "*", data)) {
if (hnd.IsInvalid) {
hr = Marshal.GetLastWin32Error();
__Error.WinIOError(hr, fullPath);
}
-
+
do {
bool isDir = (0!=(data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY));
if (isDir) {
@@ -1248,8 +830,8 @@ namespace System.IO {
// itself.
bool shouldRecurse = (0 == (data.dwFileAttributes & (int) FileAttributes.ReparsePoint));
if (shouldRecurse) {
- String newFullPath = Path.InternalCombine(fullPath, data.cFileName);
- String newUserPath = Path.InternalCombine(userPath, data.cFileName);
+ String newFullPath = Path.Combine(fullPath, data.cFileName);
+ String newUserPath = Path.Combine(userPath, data.cFileName);
try {
DeleteHelper(newFullPath, newUserPath, recursive, false);
}
@@ -1264,7 +846,7 @@ namespace System.IO {
// unmount it.
if (data.dwReserved0 == Win32Native.IO_REPARSE_TAG_MOUNT_POINT) {
// Use full path plus a trailing '\'
- String mountPoint = Path.InternalCombine(fullPath, data.cFileName + Path.DirectorySeparatorChar);
+ String mountPoint = Path.Combine(fullPath, data.cFileName + Path.DirectorySeparatorChar);
r = Win32Native.DeleteVolumeMountPoint(mountPoint);
if (!r) {
hr = Marshal.GetLastWin32Error();
@@ -1283,7 +865,7 @@ namespace System.IO {
// RemoveDirectory on a symbolic link will
// remove the link itself.
- String reparsePoint = Path.InternalCombine(fullPath, data.cFileName);
+ String reparsePoint = Path.Combine(fullPath, data.cFileName);
r = Win32Native.RemoveDirectory(reparsePoint);
if (!r) {
hr = Marshal.GetLastWin32Error();
@@ -1301,7 +883,7 @@ namespace System.IO {
}
}
else {
- String fileName = Path.InternalCombine(fullPath, data.cFileName);
+ String fileName = Path.Combine(fullPath, data.cFileName);
r = Win32Native.DeleteFile(fileName);
if (!r) {
hr = Marshal.GetLastWin32Error();
@@ -1346,44 +928,6 @@ namespace System.IO {
__Error.WinIOError(hr, fullPath);
}
}
-
- // WinNT only. Win9x this code will not work.
- [System.Security.SecurityCritical] // auto-generated
- private static SafeFileHandle OpenHandle(String path)
- {
- String fullPath = Path.GetFullPathInternal(path);
- String root = Path.GetPathRoot(fullPath);
- if (root == fullPath && root[1] == Path.VolumeSeparatorChar)
- throw new ArgumentException(Environment.GetResourceString("Arg_PathIsVolume"));
-
-#if !FEATURE_CORECLR
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, GetDemandDir(fullPath, true), false, false);
-#endif
-
- SafeFileHandle handle = Win32Native.SafeCreateFile (
- fullPath,
- GENERIC_WRITE,
- (FileShare) (FILE_SHARE_WRITE|FILE_SHARE_DELETE),
- null,
- FileMode.Open,
- FILE_FLAG_BACKUP_SEMANTICS,
- IntPtr.Zero
- );
-
- if (handle.IsInvalid) {
- int hr = Marshal.GetLastWin32Error();
- __Error.WinIOError(hr, fullPath);
- }
- return handle;
- }
-
- private const int FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
- private const int GENERIC_WRITE = unchecked((int)0x40000000);
- private const int FILE_SHARE_WRITE = 0x00000002;
- private const int FILE_SHARE_DELETE = 0x00000004;
- private const int OPEN_EXISTING = 0x00000003;
- private const int FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;
}
-
}
diff --git a/src/mscorlib/src/System/IO/DirectoryInfo.cs b/src/mscorlib/src/System/IO/DirectoryInfo.cs
index f7b0709e9e..c4c350d245 100644
--- a/src/mscorlib/src/System/IO/DirectoryInfo.cs
+++ b/src/mscorlib/src/System/IO/DirectoryInfo.cs
@@ -15,63 +15,33 @@
**
===========================================================*/
-using System;
-using System.Collections;
using System.Collections.Generic;
-using System.Security;
-#if FEATURE_MACL
-using System.Security.AccessControl;
-#endif
-using System.Security.Permissions;
using Microsoft.Win32;
-using System.Text;
using System.Runtime.InteropServices;
-using System.Globalization;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
-namespace System.IO {
+namespace System.IO
+{
[Serializable]
[ComVisible(true)]
- public sealed class DirectoryInfo : FileSystemInfo {
- private String[] demandDir;
-
-#if FEATURE_CORECLR
- // Migrating InheritanceDemands requires this default ctor, so we can annotate it.
-#if FEATURE_CORESYSTEM
- [System.Security.SecurityCritical]
-#else
- [System.Security.SecuritySafeCritical]
-#endif //FEATURE_CORESYSTEM
+ public sealed class DirectoryInfo : FileSystemInfo
+ {
+ // Migrating InheritanceDemands requires this default ctor, so we can annotate it.
private DirectoryInfo(){}
-
- [System.Security.SecurityCritical]
- public static DirectoryInfo UnsafeCreateDirectoryInfo(String path)
- {
- if (path == null)
- throw new ArgumentNullException("path");
- Contract.EndContractBlock();
-
- DirectoryInfo di = new DirectoryInfo();
- di.Init(path, false);
- return di;
- }
-#endif
-
- [System.Security.SecuritySafeCritical]
public DirectoryInfo(String path)
{
if (path==null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
Contract.EndContractBlock();
- Init(path, true);
+ Init(path);
}
- [System.Security.SecurityCritical]
- private void Init(String path, bool checkHost)
+ private void Init(String path)
{
// Special case "<DriveLetter>:" to point to "<CurrentDirectory>" instead
if ((path.Length == 2) && (path[1] == ':'))
@@ -83,138 +53,79 @@ namespace System.IO {
OriginalPath = path;
}
- // Must fully qualify the path for the security check
- String fullPath = Path.GetFullPathInternal(path);
-
- demandDir = new String[] {Directory.GetDemandDir(fullPath, true)};
-#if FEATURE_CORECLR
- if (checkHost)
- {
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, OriginalPath, fullPath);
- state.EnsureState();
- }
-#else
- new FileIOPermission(FileIOPermissionAccess.Read, demandDir, false, false ).Demand();
-#endif
-
- FullPath = fullPath;
+ FullPath = Path.GetFullPath(path); ;
DisplayPath = GetDisplayName(OriginalPath, FullPath);
}
-#if FEATURE_CORESYSTEM
- [System.Security.SecuritySafeCritical]
-#endif //FEATURE_CORESYSTEM
internal DirectoryInfo(String fullPath, bool junk)
{
- Contract.Assert(Path.GetRootLength(fullPath) > 0, "fullPath must be fully qualified!");
+ Debug.Assert(PathInternal.GetRootLength(fullPath) > 0, "fullPath must be fully qualified!");
// Fast path when we know a DirectoryInfo exists.
OriginalPath = Path.GetFileName(fullPath);
FullPath = fullPath;
DisplayPath = GetDisplayName(OriginalPath, FullPath);
- demandDir = new String[] {Directory.GetDemandDir(fullPath, true)};
}
- [System.Security.SecurityCritical] // auto-generated
private DirectoryInfo(SerializationInfo info, StreamingContext context) : base(info, context)
{
-#if !FEATURE_CORECLR
- demandDir = new String[] {Directory.GetDemandDir(FullPath, true)};
- new FileIOPermission(FileIOPermissionAccess.Read, demandDir, false, false ).Demand();
-#endif
DisplayPath = GetDisplayName(OriginalPath, FullPath);
}
- public override String Name {
+ public override String Name
+ {
get
{
-#if FEATURE_CORECLR
// DisplayPath is dir name for coreclr
return DisplayPath;
-#else
- // Return just dir name
- return GetDirName(FullPath);
-#endif
}
}
public DirectoryInfo Parent {
- [System.Security.SecuritySafeCritical]
get {
String parentName;
// FullPath might be either "c:\bar" or "c:\bar\". Handle
// those cases, as well as avoiding mangling "c:\".
String s = FullPath;
if (s.Length > 3 && s.EndsWith(Path.DirectorySeparatorChar))
- s = FullPath.Substring(0, FullPath.Length - 1);
+ s = FullPath.Substring(0, FullPath.Length - 1);
parentName = Path.GetDirectoryName(s);
if (parentName==null)
return null;
- DirectoryInfo dir = new DirectoryInfo(parentName,false);
-#if FEATURE_CORECLR
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.PathDiscovery | FileSecurityStateAccess.Read, String.Empty, dir.demandDir[0]);
- state.EnsureState();
-#else
- new FileIOPermission(FileIOPermissionAccess.PathDiscovery | FileIOPermissionAccess.Read, dir.demandDir, false, false).Demand();
-#endif
- return dir;
+
+ return new DirectoryInfo(parentName, false);
}
}
-
-#if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical]
-#endif
public DirectoryInfo CreateSubdirectory(String path) {
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
Contract.EndContractBlock();
return CreateSubdirectory(path, null);
}
-#if FEATURE_MACL
- [System.Security.SecuritySafeCritical] // auto-generated
- public DirectoryInfo CreateSubdirectory(String path, DirectorySecurity directorySecurity)
- {
- return CreateSubdirectoryHelper(path, directorySecurity);
- }
-#else // FEATURE_MACL
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
public DirectoryInfo CreateSubdirectory(String path, Object directorySecurity)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
Contract.EndContractBlock();
return CreateSubdirectoryHelper(path, directorySecurity);
}
-#endif // FEATURE_MACL
- [System.Security.SecurityCritical] // auto-generated
private DirectoryInfo CreateSubdirectoryHelper(String path, Object directorySecurity)
{
Contract.Requires(path != null);
- String newDirs = Path.InternalCombine(FullPath, path);
- String fullPath = Path.GetFullPathInternal(newDirs);
+ String newDirs = Path.Combine(FullPath, path);
+ String fullPath = Path.GetFullPath(newDirs);
if (0!=String.Compare(FullPath,0,fullPath,0, FullPath.Length,StringComparison.OrdinalIgnoreCase)) {
String displayPath = __Error.GetDisplayablePath(DisplayPath, false);
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidSubPath", path, displayPath));
}
- // Ensure we have permission to create this subdirectory.
- String demandDirForCreation = Directory.GetDemandDir(fullPath, true);
-#if FEATURE_CORECLR
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Write, OriginalPath, demandDirForCreation);
- state.EnsureState();
-#else
- new FileIOPermission(FileIOPermissionAccess.Write, new String[] { demandDirForCreation }, false, false).Demand();
-#endif
-
Directory.InternalCreateDirectory(fullPath, path, directorySecurity);
// Check for read permission to directory we hand back by calling this constructor.
@@ -223,23 +134,11 @@ namespace System.IO {
public void Create()
{
- Directory.InternalCreateDirectory(FullPath, OriginalPath, null, true);
+ Directory.InternalCreateDirectory(FullPath, OriginalPath, null);
}
-#if FEATURE_MACL
- public void Create(DirectorySecurity directorySecurity)
- {
- Directory.InternalCreateDirectory(FullPath, OriginalPath, directorySecurity, true);
- }
-#endif
-
// Tests if the given path refers to an existing DirectoryInfo on disk.
- //
- // Your application must have Read permission to the directory's
- // contents.
- //
public override bool Exists {
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
try
@@ -248,7 +147,6 @@ namespace System.IO {
Refresh();
if (_dataInitialised != 0) // Refresh was unable to initialise the data
return false;
-
return _data.fileAttributes != -1 && (_data.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) != 0;
}
catch
@@ -257,30 +155,13 @@ namespace System.IO {
}
}
}
-
-#if FEATURE_MACL
- public DirectorySecurity GetAccessControl()
- {
- return Directory.GetAccessControl(FullPath, AccessControlSections.Access | AccessControlSections.Owner | AccessControlSections.Group);
- }
-
- public DirectorySecurity GetAccessControl(AccessControlSections includeSections)
- {
- return Directory.GetAccessControl(FullPath, includeSections);
- }
-
- public void SetAccessControl(DirectorySecurity directorySecurity)
- {
- Directory.SetAccessControl(FullPath, directorySecurity);
- }
-#endif
// Returns an array of Files in the current DirectoryInfo matching the
// given search criteria (ie, "*.txt").
public FileInfo[] GetFiles(String searchPattern)
{
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
Contract.EndContractBlock();
return InternalGetFiles(searchPattern, SearchOption.TopDirectoryOnly);
@@ -291,9 +172,9 @@ namespace System.IO {
public FileInfo[] GetFiles(String searchPattern, SearchOption searchOption)
{
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException("searchOption", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
Contract.EndContractBlock();
return InternalGetFiles(searchPattern, searchOption);
@@ -328,7 +209,7 @@ namespace System.IO {
public FileSystemInfo[] GetFileSystemInfos(String searchPattern)
{
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
Contract.EndContractBlock();
return InternalGetFileSystemInfos(searchPattern, SearchOption.TopDirectoryOnly);
@@ -339,9 +220,9 @@ namespace System.IO {
public FileSystemInfo[] GetFileSystemInfos(String searchPattern, SearchOption searchOption)
{
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException("searchOption", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
Contract.EndContractBlock();
return InternalGetFileSystemInfos(searchPattern, searchOption);
@@ -372,7 +253,7 @@ namespace System.IO {
public DirectoryInfo[] GetDirectories(String searchPattern)
{
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
Contract.EndContractBlock();
return InternalGetDirectories(searchPattern, SearchOption.TopDirectoryOnly);
@@ -384,9 +265,9 @@ namespace System.IO {
public DirectoryInfo[] GetDirectories(String searchPattern, SearchOption searchOption)
{
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException("searchOption", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
Contract.EndContractBlock();
return InternalGetDirectories(searchPattern, searchOption);
@@ -413,7 +294,7 @@ namespace System.IO {
public IEnumerable<DirectoryInfo> EnumerateDirectories(String searchPattern)
{
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
Contract.EndContractBlock();
return InternalEnumerateDirectories(searchPattern, SearchOption.TopDirectoryOnly);
@@ -422,9 +303,9 @@ namespace System.IO {
public IEnumerable<DirectoryInfo> EnumerateDirectories(String searchPattern, SearchOption searchOption)
{
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException("searchOption", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
Contract.EndContractBlock();
return InternalEnumerateDirectories(searchPattern, searchOption);
@@ -446,7 +327,7 @@ namespace System.IO {
public IEnumerable<FileInfo> EnumerateFiles(String searchPattern)
{
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
Contract.EndContractBlock();
return InternalEnumerateFiles(searchPattern, SearchOption.TopDirectoryOnly);
@@ -455,9 +336,9 @@ namespace System.IO {
public IEnumerable<FileInfo> EnumerateFiles(String searchPattern, SearchOption searchOption)
{
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException("searchOption", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
Contract.EndContractBlock();
return InternalEnumerateFiles(searchPattern, searchOption);
@@ -479,7 +360,7 @@ namespace System.IO {
public IEnumerable<FileSystemInfo> EnumerateFileSystemInfos(String searchPattern)
{
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
Contract.EndContractBlock();
return InternalEnumerateFileSystemInfos(searchPattern, SearchOption.TopDirectoryOnly);
@@ -488,9 +369,9 @@ namespace System.IO {
public IEnumerable<FileSystemInfo> EnumerateFileSystemInfos(String searchPattern, SearchOption searchOption)
{
if (searchPattern == null)
- throw new ArgumentNullException("searchPattern");
+ throw new ArgumentNullException(nameof(searchPattern));
if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException("searchOption", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
Contract.EndContractBlock();
return InternalEnumerateFileSystemInfos(searchPattern, searchOption);
@@ -503,7 +384,7 @@ namespace System.IO {
return FileSystemEnumerableFactory.CreateFileSystemInfoIterator(FullPath, OriginalPath, searchPattern, searchOption);
}
-
+
// 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
@@ -512,61 +393,27 @@ namespace System.IO {
// 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 DirectoryInfo Root {
- [System.Security.SecuritySafeCritical]
get
{
- String demandPath;
- int rootLength = Path.GetRootLength(FullPath);
+ int rootLength = PathInternal.GetRootLength(FullPath);
String rootPath = FullPath.Substring(0, rootLength);
- demandPath = Directory.GetDemandDir(rootPath, true);
-
-#if FEATURE_CORECLR
- FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, demandPath);
- sourceState.EnsureState();
-#else
- new FileIOPermission(FileIOPermissionAccess.PathDiscovery, new String[] { demandPath }, false, false).Demand();
-#endif
+
return new DirectoryInfo(rootPath);
}
}
- [System.Security.SecuritySafeCritical]
public void MoveTo(String destDirName) {
if (destDirName==null)
- throw new ArgumentNullException("destDirName");
+ throw new ArgumentNullException(nameof(destDirName));
if (destDirName.Length==0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "destDirName");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destDirName));
Contract.EndContractBlock();
-
-#if FEATURE_CORECLR
- FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Write | FileSecurityStateAccess.Read, DisplayPath, Directory.GetDemandDir(FullPath, true));
- sourceState.EnsureState();
-#else
- new FileIOPermission(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, demandDir, false, false).Demand();
-#endif
- String fullDestDirName = Path.GetFullPathInternal(destDirName);
- String demandPath;
+
+ String fullDestDirName = Path.GetFullPath(destDirName);
if (!fullDestDirName.EndsWith(Path.DirectorySeparatorChar))
fullDestDirName = fullDestDirName + Path.DirectorySeparatorChar;
- demandPath = fullDestDirName + '.';
-
- // Demand read & write permission to destination. The reason is
- // we hand back a DirectoryInfo to the destination that would allow
- // you to read a directory listing from that directory. Sure, you
- // had the ability to read the file contents in the old location,
- // but you technically also need read permissions to the new
- // location as well, and write is not a true superset of read.
-#if FEATURE_CORECLR
- FileSecurityState destState = new FileSecurityState(FileSecurityStateAccess.Write, destDirName, demandPath);
- destState.EnsureState();
-#else
- new FileIOPermission(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, demandPath).Demand();
-#endif
-
String fullSourcePath;
if (FullPath.EndsWith(Path.DirectorySeparatorChar))
fullSourcePath = FullPath;
@@ -599,22 +446,19 @@ namespace System.IO {
FullPath = fullDestDirName;
OriginalPath = destDirName;
DisplayPath = GetDisplayName(OriginalPath, FullPath);
- demandDir = new String[] { Directory.GetDemandDir(FullPath, true) };
// Flush any cached information about the directory.
_dataInitialised = -1;
}
- [System.Security.SecuritySafeCritical]
public override void Delete()
{
- Directory.Delete(FullPath, OriginalPath, false, true);
+ Directory.Delete(FullPath, OriginalPath, false);
}
- [System.Security.SecuritySafeCritical]
public void Delete(bool recursive)
{
- Directory.Delete(FullPath, OriginalPath, recursive, true);
+ Directory.Delete(FullPath, OriginalPath, recursive);
}
// Returns the fully qualified path
@@ -625,8 +469,8 @@ namespace System.IO {
private static String GetDisplayName(String originalPath, String fullPath)
{
- Contract.Assert(originalPath != null);
- Contract.Assert(fullPath != null);
+ Debug.Assert(originalPath != null);
+ Debug.Assert(fullPath != null);
String displayName = "";
@@ -637,18 +481,14 @@ namespace System.IO {
}
else
{
-#if FEATURE_CORECLR
displayName = GetDirName(fullPath);
-#else
- displayName = originalPath;
-#endif
}
return displayName;
}
private static String GetDirName(String fullPath)
{
- Contract.Assert(fullPath != null);
+ Debug.Assert(fullPath != null);
String dirName = null;
if (fullPath.Length > 3)
@@ -666,7 +506,6 @@ namespace System.IO {
}
return dirName;
}
-
- }
+ }
}
diff --git a/src/mscorlib/src/System/IO/DriveInfo.cs b/src/mscorlib/src/System/IO/DriveInfo.cs
deleted file mode 100644
index be75e8979d..0000000000
--- a/src/mscorlib/src/System/IO/DriveInfo.cs
+++ /dev/null
@@ -1,281 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: Exposes routines for exploring a drive.
-**
-**
-===========================================================*/
-
-using System;
-using System.Text;
-using System.Runtime.InteropServices;
-using Microsoft.Win32;
-using System.Security.Permissions;
-using System.Runtime.Serialization;
-using System.Runtime.Versioning;
-using System.Diagnostics.Contracts;
-
-namespace System.IO
-{
- // Matches Win32's DRIVE_XXX #defines from winbase.h
- [Serializable]
-[System.Runtime.InteropServices.ComVisible(true)]
- public enum DriveType
- {
- Unknown = 0,
- NoRootDirectory = 1,
- Removable = 2,
- Fixed = 3,
- Network = 4,
- CDRom = 5,
- Ram = 6
- }
-
- // Ideally we'll get a better security permission, but possibly
- // not for Whidbey.
-#if FEATURE_SERIALIZATION
- [Serializable]
-#endif
- [ComVisible(true)]
- public sealed class DriveInfo
-#if FEATURE_SERIALIZATION
- : ISerializable
-#endif
- {
- private String _name;
-
- private const String NameField = "_name"; // For serialization
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public DriveInfo(String driveName)
- {
- if (driveName == null)
- throw new ArgumentNullException("driveName");
- Contract.EndContractBlock();
- if (driveName.Length == 1)
- _name = driveName + ":\\";
- else {
- // GetPathRoot does not check all invalid characters
- Path.CheckInvalidPathChars(driveName);
- _name = Path.GetPathRoot(driveName);
- // Disallow null or empty drive letters and UNC paths
- if (_name == null || _name.Length == 0 || _name.StartsWith("\\\\", StringComparison.Ordinal))
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDriveLetterOrRootDir"));
- }
- // We want to normalize to have a trailing backslash so we don't have two equivalent forms and
- // because some Win32 API don't work without it.
- if (_name.Length == 2 && _name[1] == ':') {
- _name = _name + "\\";
- }
-
- // Now verify that the drive letter could be a real drive name.
- // On Windows this means it's between A and Z, ignoring case.
- // On a Unix platform, perhaps this should be a device name with
- // a partition like /dev/hdc0, or possibly a mount point.
- char letter = driveName[0];
- if (!((letter >= 'A' && letter <= 'Z') || (letter >= 'a' && letter <= 'z')))
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDriveLetterOrRootDir"));
-
- // Now do a security check.
- String demandPath = _name + '.';
- new FileIOPermission(FileIOPermissionAccess.PathDiscovery, demandPath).Demand();
- }
-
- [System.Security.SecurityCritical] // auto-generated
- private DriveInfo(SerializationInfo info, StreamingContext context)
- {
- // Need to add in a security check here once it has been spec'ed.
- _name = (String) info.GetValue(NameField, typeof(String));
-
- // Now do a security check.
- String demandPath = _name + '.';
- new FileIOPermission(FileIOPermissionAccess.PathDiscovery, demandPath).Demand();
- }
-
- public String Name {
- get { return _name; }
- }
-
- public DriveType DriveType {
- [System.Security.SecuritySafeCritical] // auto-generated
- get {
- // GetDriveType can't fail
- return (DriveType) Win32Native.GetDriveType(Name);
- }
- }
-
- public String DriveFormat {
- [System.Security.SecuritySafeCritical] // auto-generated
- get {
- const int volNameLen = 50;
- StringBuilder volumeName = new StringBuilder(volNameLen);
- const int fileSystemNameLen = 50;
- StringBuilder fileSystemName = new StringBuilder(fileSystemNameLen);
- int serialNumber, maxFileNameLen, fileSystemFlags;
-
- int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS);
- try {
- bool r = Win32Native.GetVolumeInformation(Name, volumeName, volNameLen, out serialNumber, out maxFileNameLen, out fileSystemFlags, fileSystemName, fileSystemNameLen);
- if (!r) {
- int errorCode = Marshal.GetLastWin32Error();
- __Error.WinIODriveError(Name, errorCode);
- }
- }
- finally {
- Win32Native.SetErrorMode(oldMode);
- }
- return fileSystemName.ToString();
- }
- }
-
- public bool IsReady {
- [System.Security.SecuritySafeCritical] // auto-generated
- get {
- return Directory.InternalExists(Name);
- }
- }
-
- public long AvailableFreeSpace {
- [System.Security.SecuritySafeCritical] // auto-generated
- get {
- long userBytes, totalBytes, freeBytes;
- int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS);
- try {
- bool r = Win32Native.GetDiskFreeSpaceEx(Name, out userBytes, out totalBytes, out freeBytes);
- if (!r)
- __Error.WinIODriveError(Name);
- }
- finally {
- Win32Native.SetErrorMode(oldMode);
- }
- return userBytes;
- }
- }
-
- public long TotalFreeSpace {
- [System.Security.SecuritySafeCritical] // auto-generated
- get {
- long userBytes, totalBytes, freeBytes;
- int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS);
- try {
- bool r = Win32Native.GetDiskFreeSpaceEx(Name, out userBytes, out totalBytes, out freeBytes);
- if (!r)
- __Error.WinIODriveError(Name);
- }
- finally {
- Win32Native.SetErrorMode(oldMode);
- }
- return freeBytes;
- }
- }
-
- public long TotalSize {
- [System.Security.SecuritySafeCritical] // auto-generated
- get {
- // Don't cache this, to handle variable sized floppy drives
- // or other various removable media drives.
- long userBytes, totalBytes, freeBytes;
- int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS);
- try {
- bool r = Win32Native.GetDiskFreeSpaceEx(Name, out userBytes, out totalBytes, out freeBytes);
- if (!r)
- __Error.WinIODriveError(Name);
- }
- finally {
- Win32Native.SetErrorMode(oldMode);
- }
- return totalBytes;
- }
- }
-
- public static DriveInfo[] GetDrives()
- {
- // Directory.GetLogicalDrives demands unmanaged code permission
- String[] drives = Directory.GetLogicalDrives();
- DriveInfo[] di = new DriveInfo[drives.Length];
- for(int i=0; i<drives.Length; i++)
- di[i] = new DriveInfo(drives[i]);
- return di;
- }
-
- public DirectoryInfo RootDirectory {
- get {
- return new DirectoryInfo(Name);
- }
- }
-
- // Null is a valid volume label.
- public String VolumeLabel {
- [System.Security.SecuritySafeCritical] // auto-generated
- get {
- // NTFS uses a limit of 32 characters for the volume label,
- // as of Windows Server 2003.
- const int volNameLen = 50;
- StringBuilder volumeName = new StringBuilder(volNameLen);
- const int fileSystemNameLen = 50;
- StringBuilder fileSystemName = new StringBuilder(fileSystemNameLen);
- int serialNumber, maxFileNameLen, fileSystemFlags;
-
- int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS);
- try {
- bool r = Win32Native.GetVolumeInformation(Name, volumeName, volNameLen, out serialNumber, out maxFileNameLen, out fileSystemFlags, fileSystemName, fileSystemNameLen);
- if (!r) {
- int errorCode = Marshal.GetLastWin32Error();
- // Win9x appears to return ERROR_INVALID_DATA when a
- // drive doesn't exist.
- if (errorCode == Win32Native.ERROR_INVALID_DATA)
- errorCode = Win32Native.ERROR_INVALID_DRIVE;
- __Error.WinIODriveError(Name, errorCode);
- }
- }
- finally {
- Win32Native.SetErrorMode(oldMode);
- }
- return volumeName.ToString();
- }
- [System.Security.SecuritySafeCritical] // auto-generated
- set {
- String demandPath = _name + '.';
- new FileIOPermission(FileIOPermissionAccess.Write, demandPath).Demand();
-
- int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS);
- try {
- bool r = Win32Native.SetVolumeLabel(Name, value);
- if (!r) {
- int errorCode = Marshal.GetLastWin32Error();
- // Provide better message
- if (errorCode == Win32Native.ERROR_ACCESS_DENIED)
- throw new UnauthorizedAccessException(Environment.GetResourceString("InvalidOperation_SetVolumeLabelFailed"));
- __Error.WinIODriveError(Name, errorCode);
- }
- }
- finally {
- Win32Native.SetErrorMode(oldMode);
- }
- }
- }
-
- public override String ToString()
- {
- return Name;
- }
-
-#if FEATURE_SERIALIZATION
- /// <internalonly/>
- [System.Security.SecurityCritical]
- void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
- {
- // No need for an additional security check - everything is public.
- info.AddValue(NameField, _name, typeof(String));
- }
-#endif
-
- }
-}
diff --git a/src/mscorlib/src/System/IO/EncodingCache.cs b/src/mscorlib/src/System/IO/EncodingCache.cs
new file mode 100644
index 0000000000..53379bc77f
--- /dev/null
+++ b/src/mscorlib/src/System/IO/EncodingCache.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.Text;
+
+namespace System.IO
+{
+ internal static class EncodingCache
+ {
+ internal static readonly Encoding UTF8NoBOM = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);
+ }
+}
diff --git a/src/mscorlib/src/System/IO/File.cs b/src/mscorlib/src/System/IO/File.cs
index cfcb469bc3..9f89f81a91 100644
--- a/src/mscorlib/src/System/IO/File.cs
+++ b/src/mscorlib/src/System/IO/File.cs
@@ -14,34 +14,32 @@
**
===========================================================*/
-using System;
using System.Security.Permissions;
-using PermissionSet = System.Security.PermissionSet;
using Win32Native = Microsoft.Win32.Win32Native;
using System.Runtime.InteropServices;
using System.Security;
-#if FEATURE_MACL
-using System.Security.AccessControl;
-#endif
using System.Text;
using Microsoft.Win32.SafeHandles;
using System.Collections.Generic;
-using System.Globalization;
-using System.Runtime.Versioning;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
-
-namespace System.IO {
+
+namespace System.IO
+{
// Class for creating FileStream objects, and some basic file management
// routines such as Delete, etc.
[ComVisible(true)]
public static class File
{
+ private const int ERROR_INVALID_PARAMETER = 87;
+ internal const int GENERIC_READ = unchecked((int)0x80000000);
+
private const int GetFileExInfoStandard = 0;
public static StreamReader OpenText(String path)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
Contract.EndContractBlock();
return new StreamReader(path);
}
@@ -49,7 +47,7 @@ namespace System.IO {
public static StreamWriter CreateText(String path)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
Contract.EndContractBlock();
return new StreamWriter(path,false);
}
@@ -57,7 +55,7 @@ namespace System.IO {
public static StreamWriter AppendText(String path)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
Contract.EndContractBlock();
return new StreamWriter(path,true);
}
@@ -67,88 +65,51 @@ namespace System.IO {
// destination file already exists. Use the
// Copy(String, String, boolean) method to allow
// overwriting an existing file.
- //
- // The caller must have certain FileIOPermissions. The caller must have
- // Read permission to sourceFileName and Create
- // and Write permissions to destFileName.
- //
public static void Copy(String sourceFileName, String destFileName) {
if (sourceFileName == null)
- throw new ArgumentNullException("sourceFileName", Environment.GetResourceString("ArgumentNull_FileName"));
+ throw new ArgumentNullException(nameof(sourceFileName), Environment.GetResourceString("ArgumentNull_FileName"));
if (destFileName == null)
- throw new ArgumentNullException("destFileName", Environment.GetResourceString("ArgumentNull_FileName"));
+ throw new ArgumentNullException(nameof(destFileName), Environment.GetResourceString("ArgumentNull_FileName"));
if (sourceFileName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "sourceFileName");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(sourceFileName));
if (destFileName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "destFileName");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destFileName));
Contract.EndContractBlock();
- InternalCopy(sourceFileName, destFileName, false, true);
+ InternalCopy(sourceFileName, destFileName, false);
}
// Copies an existing file to a new file. If overwrite is
// false, then an IOException is thrown if the destination file
// already exists. If overwrite is true, the file is
// overwritten.
- //
- // The caller must have certain FileIOPermissions. The caller must have
- // Read permission to sourceFileName
- // and Write permissions to destFileName.
- //
public static void Copy(String sourceFileName, String destFileName, bool overwrite) {
if (sourceFileName == null)
- throw new ArgumentNullException("sourceFileName", Environment.GetResourceString("ArgumentNull_FileName"));
+ throw new ArgumentNullException(nameof(sourceFileName), Environment.GetResourceString("ArgumentNull_FileName"));
if (destFileName == null)
- throw new ArgumentNullException("destFileName", Environment.GetResourceString("ArgumentNull_FileName"));
+ throw new ArgumentNullException(nameof(destFileName), Environment.GetResourceString("ArgumentNull_FileName"));
if (sourceFileName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "sourceFileName");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(sourceFileName));
if (destFileName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "destFileName");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destFileName));
Contract.EndContractBlock();
- InternalCopy(sourceFileName, destFileName, overwrite, true);
- }
-
- [System.Security.SecurityCritical]
- internal static void UnsafeCopy(String sourceFileName, String destFileName, bool overwrite) {
- if (sourceFileName == null)
- throw new ArgumentNullException("sourceFileName", Environment.GetResourceString("ArgumentNull_FileName"));
- if (destFileName == null)
- throw new ArgumentNullException("destFileName", Environment.GetResourceString("ArgumentNull_FileName"));
- if (sourceFileName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "sourceFileName");
- if (destFileName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "destFileName");
- Contract.EndContractBlock();
-
- InternalCopy(sourceFileName, destFileName, overwrite, false);
+ InternalCopy(sourceFileName, destFileName, overwrite);
}
/// <devdoc>
/// Note: This returns the fully qualified name of the destination file.
/// </devdoc>
- [System.Security.SecuritySafeCritical]
- internal static String InternalCopy(String sourceFileName, String destFileName, bool overwrite, bool checkHost) {
+ internal static String InternalCopy(String sourceFileName, String destFileName, bool overwrite)
+ {
Contract.Requires(sourceFileName != null);
Contract.Requires(destFileName != null);
Contract.Requires(sourceFileName.Length > 0);
Contract.Requires(destFileName.Length > 0);
- String fullSourceFileName = Path.GetFullPathInternal(sourceFileName);
- String fullDestFileName = Path.GetFullPathInternal(destFileName);
-
-#if FEATURE_CORECLR
- if (checkHost) {
- FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Read, sourceFileName, fullSourceFileName);
- FileSecurityState destState = new FileSecurityState(FileSecurityStateAccess.Write, destFileName, fullDestFileName);
- sourceState.EnsureState();
- destState.EnsureState();
- }
-#else
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, fullSourceFileName, false, false);
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, fullDestFileName, false, false);
-#endif
-
+ String fullSourceFileName = Path.GetFullPath(sourceFileName);
+ String fullDestFileName = Path.GetFullPath(destFileName);
+
bool r = Win32Native.CopyFile(fullSourceFileName, fullDestFileName, !overwrite);
if (!r) {
// Save Win32 error because subsequent checks will overwrite this HRESULT.
@@ -156,14 +117,6 @@ namespace System.IO {
String fileName = destFileName;
if (errorCode != Win32Native.ERROR_FILE_EXISTS) {
- // For a number of error codes (sharing violation, path
- // not found, etc) we don't know if the problem was with
- // the source or dest file. Try reading the source file.
- using(SafeFileHandle handle = Win32Native.UnsafeCreateFile(fullSourceFileName, FileStream.GENERIC_READ, FileShare.Read, null, FileMode.Open, 0, IntPtr.Zero)) {
- if (handle.IsInvalid)
- fileName = sourceFileName;
- }
-
if (errorCode == Win32Native.ERROR_ACCESS_DENIED) {
if (Directory.InternalExists(fullDestFileName))
throw new IOException(Environment.GetResourceString("Arg_FileIsDirectory_Name", destFileName), Win32Native.ERROR_ACCESS_DENIED, fullDestFileName);
@@ -172,19 +125,14 @@ namespace System.IO {
__Error.WinIOError(errorCode, fileName);
}
-
+
return fullDestFileName;
}
-
// Creates a file in a particular path. If the file exists, it is replaced.
// The file is opened with ReadWrite accessand cannot be opened by another
// application until it has been closed. An IOException is thrown if the
// directory specified doesn't exist.
- //
- // Your application must have Create, Read, and Write permissions to
- // the file.
- //
public static FileStream Create(String path) {
return Create(path, FileStream.DefaultBufferSize);
}
@@ -193,10 +141,6 @@ namespace System.IO {
// The file is opened with ReadWrite access and cannot be opened by another
// application until it has been closed. An IOException is thrown if the
// directory specified doesn't exist.
- //
- // Your application must have Create, Read, and Write permissions to
- // the file.
- //
public static FileStream Create(String path, int bufferSize) {
return new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.None, bufferSize);
}
@@ -206,57 +150,23 @@ namespace System.IO {
FileShare.None, bufferSize, options);
}
-#if FEATURE_MACL
- public static FileStream Create(String path, int bufferSize, FileOptions options, FileSecurity fileSecurity) {
- return new FileStream(path, FileMode.Create, FileSystemRights.Read | FileSystemRights.Write,
- FileShare.None, bufferSize, options, fileSecurity);
- }
-#endif
-
// Deletes a file. The file specified by the designated path is deleted.
// If the file does not exist, Delete succeeds without throwing
// an exception.
//
// On NT, Delete will fail for a file that is open for normal I/O
// or a file that is memory mapped.
- //
- // Your application must have Delete permission to the target file.
- //
- [System.Security.SecuritySafeCritical]
public static void Delete(String path) {
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
Contract.EndContractBlock();
-
- InternalDelete(path, true);
- }
- [System.Security.SecurityCritical]
- internal static void UnsafeDelete(String path)
- {
- if (path == null)
- throw new ArgumentNullException("path");
- Contract.EndContractBlock();
-
- InternalDelete(path, false);
+ InternalDelete(path);
}
- [System.Security.SecurityCritical]
- internal static void InternalDelete(String path, bool checkHost)
+ internal static void InternalDelete(String path)
{
- String fullPath = Path.GetFullPathInternal(path);
-
-#if FEATURE_CORECLR
- if (checkHost)
- {
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Write, path, fullPath);
- state.EnsureState();
- }
-#else
- // For security check, path should be resolved to an absolute path.
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, fullPath, false, false);
-
-#endif
+ String fullPath = Path.GetFullPath(path);
bool r = Win32Native.DeleteFile(fullPath);
if (!r) {
int hr = Marshal.GetLastWin32Error();
@@ -267,76 +177,16 @@ namespace System.IO {
}
}
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public static void Decrypt(String path)
- {
- if (path == null)
- throw new ArgumentNullException("path");
- Contract.EndContractBlock();
-
- String fullPath = Path.GetFullPathInternal(path);
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Read | FileIOPermissionAccess.Write, fullPath, false, false);
-
- bool r = Win32Native.DecryptFile(fullPath, 0);
- if (!r) {
- int errorCode = Marshal.GetLastWin32Error();
- if (errorCode == Win32Native.ERROR_ACCESS_DENIED) {
- // Check to see if the file system is not NTFS. If so,
- // throw a different exception.
- DriveInfo di = new DriveInfo(Path.GetPathRoot(fullPath));
- if (!String.Equals("NTFS", di.DriveFormat))
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_EncryptionNeedsNTFS"));
- }
- __Error.WinIOError(errorCode, fullPath);
- }
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public static void Encrypt(String path)
- {
- if (path == null)
- throw new ArgumentNullException("path");
- Contract.EndContractBlock();
-
- String fullPath = Path.GetFullPathInternal(path);
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Read | FileIOPermissionAccess.Write, fullPath, false, false);
-
- bool r = Win32Native.EncryptFile(fullPath);
- if (!r) {
- int errorCode = Marshal.GetLastWin32Error();
- if (errorCode == Win32Native.ERROR_ACCESS_DENIED) {
- // Check to see if the file system is not NTFS. If so,
- // throw a different exception.
- DriveInfo di = new DriveInfo(Path.GetPathRoot(fullPath));
- if (!String.Equals("NTFS", di.DriveFormat))
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_EncryptionNeedsNTFS"));
- }
- __Error.WinIOError(errorCode, fullPath);
- }
- }
-
// Tests if a file exists. The result is true if the file
// given by the specified path exists; otherwise, the result is
// false. Note that if path describes a directory,
// Exists will return true.
- //
- // Your application must have Read permission for the target directory.
- //
- [System.Security.SecuritySafeCritical]
public static bool Exists(String path)
{
- return InternalExistsHelper(path, true);
+ return InternalExistsHelper(path);
}
- [System.Security.SecurityCritical]
- internal static bool UnsafeExists(String path)
- {
- return InternalExistsHelper(path, false);
- }
-
- [System.Security.SecurityCritical]
- private static bool InternalExistsHelper(String path, bool checkHost)
+ private static bool InternalExistsHelper(String path)
{
try
{
@@ -345,26 +195,17 @@ namespace System.IO {
if (path.Length == 0)
return false;
- path = Path.GetFullPathInternal(path);
+ path = Path.GetFullPath(path);
+
// After normalizing, check whether path ends in directory separator.
// Otherwise, FillAttributeInfo removes it and we may return a false positive.
- // GetFullPathInternal should never return null
- Contract.Assert(path != null, "File.Exists: GetFullPathInternal returned null");
- if (path.Length > 0 && Path.IsDirectorySeparator(path[path.Length - 1]))
+ // GetFullPath should never return null
+ Debug.Assert(path != null, "File.Exists: GetFullPath returned null");
+ if (path.Length > 0 && PathInternal.IsDirectorySeparator(path[path.Length - 1]))
{
return false;
}
-#if FEATURE_CORECLR
- if (checkHost)
- {
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, path);
- state.EnsureState();
- }
-#else
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, path, false, false);
-#endif
-
return InternalExists(path);
}
catch (ArgumentException) { }
@@ -376,7 +217,6 @@ namespace System.IO {
return false;
}
- [System.Security.SecurityCritical] // auto-generated
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);
@@ -397,51 +237,19 @@ namespace System.IO {
return new FileStream(path, mode, access, share);
}
- public static void SetCreationTime(String path, DateTime creationTime)
- {
- SetCreationTimeUtc(path, creationTime.ToUniversalTime());
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public unsafe static void SetCreationTimeUtc(String path, DateTime creationTimeUtc)
- {
- SafeFileHandle handle;
- using(OpenFile(path, FileAccess.Write, out handle)) {
- Win32Native.FILE_TIME fileTime = new Win32Native.FILE_TIME(creationTimeUtc.ToFileTimeUtc());
- bool r = Win32Native.SetFileTime(handle, &fileTime, null, null);
- if (!r)
- {
- int errorCode = Marshal.GetLastWin32Error();
- __Error.WinIOError(errorCode, path);
- }
- }
- }
-
- [System.Security.SecuritySafeCritical]
public static DateTime GetCreationTime(String path)
{
- return InternalGetCreationTimeUtc(path, true).ToLocalTime();
+ return InternalGetCreationTimeUtc(path).ToLocalTime();
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static DateTime GetCreationTimeUtc(String path)
{
- return InternalGetCreationTimeUtc(path, false); // this API isn't exposed in Silverlight
+ return InternalGetCreationTimeUtc(path); // this API isn't exposed in Silverlight
}
- [System.Security.SecurityCritical]
- private static DateTime InternalGetCreationTimeUtc(String path, bool checkHost)
+ private static DateTime InternalGetCreationTimeUtc(String path)
{
- String fullPath = Path.GetFullPathInternal(path);
-#if FEATURE_CORECLR
- if (checkHost)
- {
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, path, fullPath);
- state.EnsureState();
- }
-#else
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, fullPath, false, false);
-#endif
+ String fullPath = Path.GetFullPath(path);
Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
int dataInitialised = FillAttributeInfo(fullPath, ref data, false, false);
@@ -452,51 +260,19 @@ namespace System.IO {
return DateTime.FromFileTimeUtc(dt);
}
- public static void SetLastAccessTime(String path, DateTime lastAccessTime)
- {
- SetLastAccessTimeUtc(path, lastAccessTime.ToUniversalTime());
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public unsafe static void SetLastAccessTimeUtc(String path, DateTime lastAccessTimeUtc)
- {
- SafeFileHandle handle;
- using(OpenFile(path, FileAccess.Write, out handle)) {
- Win32Native.FILE_TIME fileTime = new Win32Native.FILE_TIME(lastAccessTimeUtc.ToFileTimeUtc());
- bool r = Win32Native.SetFileTime(handle, null, &fileTime, null);
- if (!r)
- {
- int errorCode = Marshal.GetLastWin32Error();
- __Error.WinIOError(errorCode, path);
- }
- }
- }
-
- [System.Security.SecuritySafeCritical]
public static DateTime GetLastAccessTime(String path)
{
- return InternalGetLastAccessTimeUtc(path, true).ToLocalTime();
+ return InternalGetLastAccessTimeUtc(path).ToLocalTime();
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static DateTime GetLastAccessTimeUtc(String path)
{
- return InternalGetLastAccessTimeUtc(path, false); // this API isn't exposed in Silverlight
+ return InternalGetLastAccessTimeUtc(path);
}
- [System.Security.SecurityCritical]
- private static DateTime InternalGetLastAccessTimeUtc(String path, bool checkHost)
- {
- String fullPath = Path.GetFullPathInternal(path);
-#if FEATURE_CORECLR
- if (checkHost)
- {
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, path, fullPath);
- state.EnsureState();
- }
-#else
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, fullPath, false, false);
-#endif
+ private static DateTime InternalGetLastAccessTimeUtc(String path)
+ {
+ String fullPath = Path.GetFullPath(path);
Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
int dataInitialised = FillAttributeInfo(fullPath, ref data, false, false);
@@ -507,51 +283,19 @@ namespace System.IO {
return DateTime.FromFileTimeUtc(dt);
}
- public static void SetLastWriteTime(String path, DateTime lastWriteTime)
- {
- SetLastWriteTimeUtc(path, lastWriteTime.ToUniversalTime());
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public unsafe static void SetLastWriteTimeUtc(String path, DateTime lastWriteTimeUtc)
- {
- SafeFileHandle handle;
- using(OpenFile(path, FileAccess.Write, out handle)) {
- Win32Native.FILE_TIME fileTime = new Win32Native.FILE_TIME(lastWriteTimeUtc.ToFileTimeUtc());
- bool r = Win32Native.SetFileTime(handle, null, null, &fileTime);
- if (!r)
- {
- int errorCode = Marshal.GetLastWin32Error();
- __Error.WinIOError(errorCode, path);
- }
- }
- }
-
- [System.Security.SecuritySafeCritical]
public static DateTime GetLastWriteTime(String path)
{
- return InternalGetLastWriteTimeUtc(path, true).ToLocalTime();
+ return InternalGetLastWriteTimeUtc(path).ToLocalTime();
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static DateTime GetLastWriteTimeUtc(String path)
{
- return InternalGetLastWriteTimeUtc(path, false); // this API isn't exposed in Silverlight
+ return InternalGetLastWriteTimeUtc(path);
}
- [System.Security.SecurityCritical]
- private static DateTime InternalGetLastWriteTimeUtc(String path, bool checkHost)
+ private static DateTime InternalGetLastWriteTimeUtc(String path)
{
- String fullPath = Path.GetFullPathInternal(path);
-#if FEATURE_CORECLR
- if (checkHost)
- {
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, path, fullPath);
- state.EnsureState();
- }
-#else
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, fullPath, false, false);
-#endif
+ String fullPath = Path.GetFullPath(path);
Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
int dataInitialised = FillAttributeInfo(fullPath, ref data, false, false);
@@ -562,16 +306,9 @@ namespace System.IO {
return DateTime.FromFileTimeUtc(dt);
}
- [System.Security.SecuritySafeCritical]
public static FileAttributes GetAttributes(String path)
{
- String fullPath = Path.GetFullPathInternal(path);
-#if FEATURE_CORECLR
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, path, fullPath);
- state.EnsureState();
-#else
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, fullPath, false, false);
-#endif
+ String fullPath = Path.GetFullPath(path);
Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
int dataInitialised = FillAttributeInfo(fullPath, ref data, false, true);
@@ -581,17 +318,9 @@ namespace System.IO {
return (FileAttributes) data.fileAttributes;
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical]
- #else
- [System.Security.SecuritySafeCritical]
- #endif
public static void SetAttributes(String path, FileAttributes fileAttributes)
{
- String fullPath = Path.GetFullPathInternal(path);
-#if !FEATURE_CORECLR
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, fullPath, false, false);
-#endif
+ String fullPath = Path.GetFullPath(path);
bool r = Win32Native.SetFileAttributes(fullPath, (int) fileAttributes);
if (!r) {
int hr = Marshal.GetLastWin32Error();
@@ -601,158 +330,88 @@ namespace System.IO {
}
}
-#if FEATURE_MACL
- public static FileSecurity GetAccessControl(String path)
- {
- return GetAccessControl(path, AccessControlSections.Access | AccessControlSections.Owner | AccessControlSections.Group);
- }
-
- public static FileSecurity GetAccessControl(String path, AccessControlSections includeSections)
- {
- // Appropriate security check should be done for us by FileSecurity.
- return new FileSecurity(path, includeSections);
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public static void SetAccessControl(String path, FileSecurity fileSecurity)
- {
- if (fileSecurity == null)
- throw new ArgumentNullException("fileSecurity");
- Contract.EndContractBlock();
-
- String fullPath = Path.GetFullPathInternal(path);
- // Appropriate security check should be done for us by FileSecurity.
- fileSecurity.Persist(fullPath);
- }
-#endif
-
public static FileStream OpenRead(String path) {
return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
}
-
public static FileStream OpenWrite(String path) {
return new FileStream(path, FileMode.OpenOrCreate,
FileAccess.Write, FileShare.None);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static String ReadAllText(String path)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (path.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
Contract.EndContractBlock();
- return InternalReadAllText(path, Encoding.UTF8, true);
+ return InternalReadAllText(path, Encoding.UTF8);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static String ReadAllText(String path, Encoding encoding)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (encoding == null)
- throw new ArgumentNullException("encoding");
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
- Contract.EndContractBlock();
-
- return InternalReadAllText(path, encoding, true);
- }
-
- [System.Security.SecurityCritical]
- internal static String UnsafeReadAllText(String path)
- {
- if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(encoding));
if (path.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
Contract.EndContractBlock();
- return InternalReadAllText(path, Encoding.UTF8, false);
+ return InternalReadAllText(path, encoding);
}
- [System.Security.SecurityCritical]
- private static String InternalReadAllText(String path, Encoding encoding, bool checkHost)
+ private static String InternalReadAllText(String path, Encoding encoding)
{
Contract.Requires(path != null);
Contract.Requires(encoding != null);
Contract.Requires(path.Length > 0);
- using (StreamReader sr = new StreamReader(path, encoding, true, StreamReader.DefaultBufferSize, checkHost))
+ using (StreamReader sr = new StreamReader(path, encoding, true, StreamReader.DefaultBufferSize))
return sr.ReadToEnd();
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static void WriteAllText(String path, String contents)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (path.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
Contract.EndContractBlock();
- InternalWriteAllText(path, contents, StreamWriter.UTF8NoBOM, true);
+ InternalWriteAllText(path, contents, StreamWriter.UTF8NoBOM);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static void WriteAllText(String path, String contents, Encoding encoding)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (encoding == null)
- throw new ArgumentNullException("encoding");
+ throw new ArgumentNullException(nameof(encoding));
if (path.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
Contract.EndContractBlock();
- InternalWriteAllText(path, contents, encoding, true);
+ InternalWriteAllText(path, contents, encoding);
}
-
- [System.Security.SecurityCritical]
- internal static void UnsafeWriteAllText(String path, String contents)
- {
- if (path == null)
- throw new ArgumentNullException("path");
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
- Contract.EndContractBlock();
- InternalWriteAllText(path, contents, StreamWriter.UTF8NoBOM, false);
- }
-
- [System.Security.SecurityCritical]
- private static void InternalWriteAllText(String path, String contents, Encoding encoding, bool checkHost)
+ private static void InternalWriteAllText(String path, String contents, Encoding encoding)
{
Contract.Requires(path != null);
Contract.Requires(encoding != null);
Contract.Requires(path.Length > 0);
- using (StreamWriter sw = new StreamWriter(path, false, encoding, StreamWriter.DefaultBufferSize, checkHost))
+ using (StreamWriter sw = new StreamWriter(path, false, encoding, StreamWriter.DefaultBufferSize))
sw.Write(contents);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static byte[] ReadAllBytes(String path)
{
- return InternalReadAllBytes(path, true);
- }
-
- [System.Security.SecurityCritical]
- internal static byte[] UnsafeReadAllBytes(String path)
- {
- return InternalReadAllBytes(path, false);
- }
-
-
- [System.Security.SecurityCritical]
- private static byte[] InternalReadAllBytes(String path, bool checkHost)
- {
byte[] bytes;
using(FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read,
- FileStream.DefaultBufferSize, FileOptions.None, Path.GetFileName(path), false, false, checkHost)) {
+ FileStream.DefaultBufferSize, FileOptions.None, Path.GetFileName(path), false, false)) {
// Do a blocking read
int index = 0;
long fileLength = fs.Length;
@@ -771,43 +430,27 @@ namespace System.IO {
return bytes;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static void WriteAllBytes(String path, byte[] bytes)
{
if (path == null)
- throw new ArgumentNullException("path", Environment.GetResourceString("ArgumentNull_Path"));
+ throw new ArgumentNullException(nameof(path), Environment.GetResourceString("ArgumentNull_Path"));
if (path.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
if (bytes == null)
- throw new ArgumentNullException("bytes");
+ throw new ArgumentNullException(nameof(bytes));
Contract.EndContractBlock();
- InternalWriteAllBytes(path, bytes, true);
+ InternalWriteAllBytes(path, bytes);
}
- [System.Security.SecurityCritical]
- internal static void UnsafeWriteAllBytes(String path, byte[] bytes)
- {
- if (path == null)
- throw new ArgumentNullException("path", Environment.GetResourceString("ArgumentNull_Path"));
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
- if (bytes == null)
- throw new ArgumentNullException("bytes");
- Contract.EndContractBlock();
-
- InternalWriteAllBytes(path, bytes, false);
- }
-
- [System.Security.SecurityCritical]
- private static void InternalWriteAllBytes(String path, byte[] bytes, bool checkHost)
+ private static void InternalWriteAllBytes(String path, byte[] bytes)
{
Contract.Requires(path != null);
Contract.Requires(path.Length != 0);
Contract.Requires(bytes != null);
using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read,
- FileStream.DefaultBufferSize, FileOptions.None, Path.GetFileName(path), false, false, checkHost))
+ FileStream.DefaultBufferSize, FileOptions.None, Path.GetFileName(path), false, false))
{
fs.Write(bytes, 0, bytes.Length);
}
@@ -816,7 +459,7 @@ namespace System.IO {
public static String[] ReadAllLines(String path)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (path.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
Contract.EndContractBlock();
@@ -827,9 +470,9 @@ namespace System.IO {
public static String[] ReadAllLines(String path, Encoding encoding)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (encoding == null)
- throw new ArgumentNullException("encoding");
+ throw new ArgumentNullException(nameof(encoding));
if (path.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
Contract.EndContractBlock();
@@ -856,9 +499,9 @@ namespace System.IO {
public static IEnumerable<String> ReadLines(String path)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"), "path");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"), nameof(path));
Contract.EndContractBlock();
return ReadLinesIterator.CreateIterator(path, Encoding.UTF8);
@@ -867,11 +510,11 @@ namespace System.IO {
public static IEnumerable<String> ReadLines(String path, Encoding encoding)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (encoding == null)
- throw new ArgumentNullException("encoding");
+ throw new ArgumentNullException(nameof(encoding));
if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"), "path");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"), nameof(path));
Contract.EndContractBlock();
return ReadLinesIterator.CreateIterator(path, encoding);
@@ -880,9 +523,9 @@ namespace System.IO {
public static void WriteAllLines(String path, String[] contents)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (contents == null)
- throw new ArgumentNullException("contents");
+ throw new ArgumentNullException(nameof(contents));
if (path.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
Contract.EndContractBlock();
@@ -893,11 +536,11 @@ namespace System.IO {
public static void WriteAllLines(String path, String[] contents, Encoding encoding)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (contents == null)
- throw new ArgumentNullException("contents");
+ throw new ArgumentNullException(nameof(contents));
if (encoding == null)
- throw new ArgumentNullException("encoding");
+ throw new ArgumentNullException(nameof(encoding));
if (path.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
Contract.EndContractBlock();
@@ -908,9 +551,9 @@ namespace System.IO {
public static void WriteAllLines(String path, IEnumerable<String> contents)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (contents == null)
- throw new ArgumentNullException("contents");
+ throw new ArgumentNullException(nameof(contents));
if (path.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
Contract.EndContractBlock();
@@ -921,11 +564,11 @@ namespace System.IO {
public static void WriteAllLines(String path, IEnumerable<String> contents, Encoding encoding)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (contents == null)
- throw new ArgumentNullException("contents");
+ throw new ArgumentNullException(nameof(contents));
if (encoding == null)
- throw new ArgumentNullException("encoding");
+ throw new ArgumentNullException(nameof(encoding));
if (path.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
Contract.EndContractBlock();
@@ -950,7 +593,7 @@ namespace System.IO {
public static void AppendAllText(String path, String contents)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (path.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
Contract.EndContractBlock();
@@ -961,9 +604,9 @@ namespace System.IO {
public static void AppendAllText(String path, String contents, Encoding encoding)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (encoding == null)
- throw new ArgumentNullException("encoding");
+ throw new ArgumentNullException(nameof(encoding));
if (path.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
Contract.EndContractBlock();
@@ -984,9 +627,9 @@ namespace System.IO {
public static void AppendAllLines(String path, IEnumerable<String> contents)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (contents == null)
- throw new ArgumentNullException("contents");
+ throw new ArgumentNullException(nameof(contents));
if (path.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
Contract.EndContractBlock();
@@ -997,11 +640,11 @@ namespace System.IO {
public static void AppendAllLines(String path, IEnumerable<String> contents, Encoding encoding)
{
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (contents == null)
- throw new ArgumentNullException("contents");
+ throw new ArgumentNullException(nameof(contents));
if (encoding == null)
- throw new ArgumentNullException("encoding");
+ throw new ArgumentNullException(nameof(encoding));
if (path.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
Contract.EndContractBlock();
@@ -1011,48 +654,23 @@ namespace System.IO {
// Moves a specified file to a new location and potentially a new file name.
// This method does work across volumes.
- //
- // The caller must have certain FileIOPermissions. The caller must
- // have Read and Write permission to
- // sourceFileName and Write
- // permissions to destFileName.
- //
- [System.Security.SecuritySafeCritical]
public static void Move(String sourceFileName, String destFileName) {
- InternalMove(sourceFileName, destFileName, true);
- }
-
- [System.Security.SecurityCritical]
- internal static void UnsafeMove(String sourceFileName, String destFileName) {
- InternalMove(sourceFileName, destFileName, false);
+ InternalMove(sourceFileName, destFileName);
}
- [System.Security.SecurityCritical]
- private static void InternalMove(String sourceFileName, String destFileName, bool checkHost) {
+ private static void InternalMove(String sourceFileName, String destFileName) {
if (sourceFileName == null)
- throw new ArgumentNullException("sourceFileName", Environment.GetResourceString("ArgumentNull_FileName"));
+ throw new ArgumentNullException(nameof(sourceFileName), Environment.GetResourceString("ArgumentNull_FileName"));
if (destFileName == null)
- throw new ArgumentNullException("destFileName", Environment.GetResourceString("ArgumentNull_FileName"));
+ throw new ArgumentNullException(nameof(destFileName), Environment.GetResourceString("ArgumentNull_FileName"));
if (sourceFileName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "sourceFileName");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(sourceFileName));
if (destFileName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "destFileName");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destFileName));
Contract.EndContractBlock();
- String fullSourceFileName = Path.GetFullPathInternal(sourceFileName);
- String fullDestFileName = Path.GetFullPathInternal(destFileName);
-
-#if FEATURE_CORECLR
- if (checkHost) {
- FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Write | FileSecurityStateAccess.Read, sourceFileName, fullSourceFileName);
- FileSecurityState destState = new FileSecurityState(FileSecurityStateAccess.Write, destFileName, fullDestFileName);
- sourceState.EnsureState();
- destState.EnsureState();
- }
-#else
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, fullSourceFileName, false, false);
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, fullDestFileName, false, false);
-#endif
+ String fullSourceFileName = Path.GetFullPath(sourceFileName);
+ String fullDestFileName = Path.GetFullPath(destFileName);
if (!InternalExists(fullSourceFileName))
__Error.WinIOError(Win32Native.ERROR_FILE_NOT_FOUND, fullSourceFileName);
@@ -1067,9 +685,9 @@ namespace System.IO {
public static void Replace(String sourceFileName, String destinationFileName, String destinationBackupFileName)
{
if (sourceFileName == null)
- throw new ArgumentNullException("sourceFileName");
+ throw new ArgumentNullException(nameof(sourceFileName));
if (destinationFileName == null)
- throw new ArgumentNullException("destinationFileName");
+ throw new ArgumentNullException(nameof(destinationFileName));
Contract.EndContractBlock();
InternalReplace(sourceFileName, destinationFileName, destinationBackupFileName, false);
@@ -1078,41 +696,24 @@ namespace System.IO {
public static void Replace(String sourceFileName, String destinationFileName, String destinationBackupFileName, bool ignoreMetadataErrors)
{
if (sourceFileName == null)
- throw new ArgumentNullException("sourceFileName");
+ throw new ArgumentNullException(nameof(sourceFileName));
if (destinationFileName == null)
- throw new ArgumentNullException("destinationFileName");
+ throw new ArgumentNullException(nameof(destinationFileName));
Contract.EndContractBlock();
InternalReplace(sourceFileName, destinationFileName, destinationBackupFileName, ignoreMetadataErrors);
}
- [System.Security.SecuritySafeCritical]
private static void InternalReplace(String sourceFileName, String destinationFileName, String destinationBackupFileName, bool ignoreMetadataErrors)
{
Contract.Requires(sourceFileName != null);
Contract.Requires(destinationFileName != null);
- // Write permission to all three files, read permission to source
- // and dest.
- String fullSrcPath = Path.GetFullPathInternal(sourceFileName);
- String fullDestPath = Path.GetFullPathInternal(destinationFileName);
+ String fullSrcPath = Path.GetFullPath(sourceFileName);
+ String fullDestPath = Path.GetFullPath(destinationFileName);
String fullBackupPath = null;
if (destinationBackupFileName != null)
- fullBackupPath = Path.GetFullPathInternal(destinationBackupFileName);
-
-#if FEATURE_CORECLR
- FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Read | FileSecurityStateAccess.Write, sourceFileName, fullSrcPath);
- FileSecurityState destState = new FileSecurityState(FileSecurityStateAccess.Read | FileSecurityStateAccess.Write, destinationFileName, fullDestPath);
- FileSecurityState backupState = new FileSecurityState(FileSecurityStateAccess.Read | FileSecurityStateAccess.Write, destinationBackupFileName, fullBackupPath);
- sourceState.EnsureState();
- destState.EnsureState();
- backupState.EnsureState();
-#else
- FileIOPermission perm = new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.Write, new String[] { fullSrcPath, fullDestPath});
- if (destinationBackupFileName != null)
- perm.AddPathList(FileIOPermissionAccess.Write, fullBackupPath);
- perm.Demand();
-#endif
+ fullBackupPath = Path.GetFullPath(destinationBackupFileName);
int flags = Win32Native.REPLACEFILE_WRITE_THROUGH;
if (ignoreMetadataErrors)
@@ -1126,7 +727,6 @@ namespace System.IO {
// Returns 0 on success, otherwise a Win32 error code. Note that
// classes should use -1 as the uninitialized state for dataInitialized.
- [System.Security.SecurityCritical] // auto-generated
internal static int FillAttributeInfo(String path, ref Win32Native.WIN32_FILE_ATTRIBUTE_DATA data, bool tryagain, bool returnErrorOnNotFound)
{
int dataInitialised = 0;
@@ -1172,7 +772,7 @@ namespace System.IO {
catch {
// if we're already returning an error, don't throw another one.
if (!error) {
- Contract.Assert(false, "File::FillAttributeInfo - FindClose failed!");
+ Debug.Assert(false, "File::FillAttributeInfo - FindClose failed!");
__Error.WinIOError();
}
}
@@ -1187,7 +787,6 @@ namespace System.IO {
}
else
{
-
// 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
@@ -1222,34 +821,5 @@ namespace System.IO {
return dataInitialised;
}
-
- [System.Security.SecurityCritical] // auto-generated
- private static FileStream OpenFile(String path, FileAccess access, out SafeFileHandle handle)
- {
- FileStream fs = new FileStream(path, FileMode.Open, access, FileShare.ReadWrite, 1);
- handle = fs.SafeFileHandle;
-
- if (handle.IsInvalid) {
- // Return a meaningful error, using the RELATIVE path to
- // the file to avoid returning extra information to the caller.
-
- // NT5 oddity - when trying to open "C:\" as a FileStream,
- // we usually get ERROR_PATH_NOT_FOUND from the OS. We should
- // probably be consistent w/ every other directory.
- int hr = Marshal.GetLastWin32Error();
- String FullPath = Path.GetFullPathInternal(path);
- if (hr==__Error.ERROR_PATH_NOT_FOUND && FullPath.Equals(Directory.GetDirectoryRoot(FullPath)))
- hr = __Error.ERROR_ACCESS_DENIED;
-
-
- __Error.WinIOError(hr, path);
- }
- return fs;
- }
-
-
- // Defined in WinError.h
- private const int ERROR_INVALID_PARAMETER = 87;
- private const int ERROR_ACCESS_DENIED = 0x5;
}
}
diff --git a/src/mscorlib/src/System/IO/FileAttributes.cs b/src/mscorlib/src/System/IO/FileAttributes.cs
index 19d5f227d7..51ef597f9d 100644
--- a/src/mscorlib/src/System/IO/FileAttributes.cs
+++ b/src/mscorlib/src/System/IO/FileAttributes.cs
@@ -11,13 +11,13 @@
===========================================================*/
using System;
-namespace System.IO {
+namespace System.IO
+{
// File attributes for use with the FileEnumerator class.
// These constants correspond to the constants in WinNT.h.
- //
-[Serializable]
+ [Serializable]
[Flags]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public enum FileAttributes
{
// From WinNT.h (FILE_ATTRIBUTE_XXX)
@@ -35,17 +35,5 @@ namespace System.IO {
Offline = 0x1000,
NotContentIndexed = 0x2000,
Encrypted = 0x4000,
-
-#if !FEATURE_CORECLR
-#if FEATURE_COMINTEROP
- [System.Runtime.InteropServices.ComVisible(false)]
-#endif // FEATURE_COMINTEROP
- IntegrityStream = 0x8000,
-
-#if FEATURE_COMINTEROP
- [System.Runtime.InteropServices.ComVisible(false)]
-#endif // FEATURE_COMINTEROP
- NoScrubData = 0x20000,
-#endif
}
}
diff --git a/src/mscorlib/src/System/IO/FileInfo.cs b/src/mscorlib/src/System/IO/FileInfo.cs
index 3ab1a5122e..32622c63a1 100644
--- a/src/mscorlib/src/System/IO/FileInfo.cs
+++ b/src/mscorlib/src/System/IO/FileInfo.cs
@@ -2,33 +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.
-/*============================================================
-**
-**
-**
-**
-**
-** Purpose: A collection of methods for manipulating Files.
-**
-** April 09,2000 (some design refactorization)
-**
-===========================================================*/
-
-using System;
-#if FEATURE_MACL
-using System.Security.AccessControl;
-#endif
-using System.Security.Permissions;
-using PermissionSet = System.Security.PermissionSet;
using Win32Native = Microsoft.Win32.Win32Native;
using System.Runtime.InteropServices;
using System.Text;
using System.Runtime.Serialization;
using System.Globalization;
using System.Runtime.Versioning;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
-namespace System.IO {
+namespace System.IO
+{
// Class for creating FileStream objects, and some basic file management
// routines such as Delete, etc.
[Serializable]
@@ -37,85 +21,40 @@ namespace System.IO {
{
private String _name;
-#if FEATURE_CORECLR
// Migrating InheritanceDemands requires this default ctor, so we can annotate it.
-#if FEATURE_CORESYSTEM
- [System.Security.SecurityCritical]
-#else
- [System.Security.SecuritySafeCritical]
-#endif //FEATURE_CORESYSTEM
private FileInfo(){}
- [System.Security.SecurityCritical]
- public static FileInfo UnsafeCreateFileInfo(String fileName)
- {
- if (fileName == null)
- throw new ArgumentNullException("fileName");
- Contract.EndContractBlock();
-
- FileInfo fi = new FileInfo();
- fi.Init(fileName, false);
- return fi;
- }
-#endif
-
- [System.Security.SecuritySafeCritical]
public FileInfo(String fileName)
{
if (fileName == null)
- throw new ArgumentNullException("fileName");
+ throw new ArgumentNullException(nameof(fileName));
Contract.EndContractBlock();
- Init(fileName, true);
+ Init(fileName);
}
- [System.Security.SecurityCritical]
- private void Init(String fileName, bool checkHost)
+ private void Init(String fileName)
{
OriginalPath = fileName;
- // Must fully qualify the path for the security check
- String fullPath = Path.GetFullPathInternal(fileName);
-#if FEATURE_CORECLR
- if (checkHost)
- {
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, fileName, fullPath);
- state.EnsureState();
- }
-#else
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Read, fullPath, false, false);
-#endif
-
_name = Path.GetFileName(fileName);
- FullPath = fullPath;
+ FullPath = Path.GetFullPath(fileName);
DisplayPath = GetDisplayPath(fileName);
}
private String GetDisplayPath(String originalPath)
{
-#if FEATURE_CORECLR
return Path.GetFileName(originalPath);
-#else
- return originalPath;
-#endif
-
}
- [System.Security.SecurityCritical] // auto-generated
private FileInfo(SerializationInfo info, StreamingContext context) : base(info, context)
{
-#if !FEATURE_CORECLR
- new FileIOPermission(FileIOPermissionAccess.Read, new String[] { FullPath }, false, false).Demand();
-#endif
_name = Path.GetFileName(OriginalPath);
DisplayPath = GetDisplayPath(OriginalPath);
}
-#if FEATURE_CORESYSTEM
- [System.Security.SecuritySafeCritical]
-#endif //FEATURE_CORESYSTEM
internal FileInfo(String fullPath, bool ignoreThis)
{
- Contract.Assert(Path.GetRootLength(fullPath) > 0, "fullPath must be fully qualified!");
+ Debug.Assert(PathInternal.GetRootLength(fullPath) > 0, "fullPath must be fully qualified!");
_name = Path.GetFileName(fullPath);
OriginalPath = _name;
FullPath = fullPath;
@@ -125,10 +64,8 @@ namespace System.IO {
public override String Name {
get { return _name; }
}
-
-
+
public long Length {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
if (_dataInitialised == -1)
Refresh();
@@ -146,20 +83,9 @@ namespace System.IO {
/* Returns the name of the directory that the file is in */
public String DirectoryName
{
- [System.Security.SecuritySafeCritical]
get
{
- String directoryName = Path.GetDirectoryName(FullPath);
- if (directoryName != null)
- {
-#if FEATURE_CORECLR
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, DisplayPath, FullPath);
- state.EnsureState();
-#else
- new FileIOPermission(FileIOPermissionAccess.PathDiscovery, new String[] { directoryName }, false, false).Demand();
-#endif
- }
- return directoryName;
+ return Path.GetDirectoryName(FullPath);
}
}
@@ -171,7 +97,7 @@ namespace System.IO {
String dirName = DirectoryName;
if (dirName == null)
return null;
- return new DirectoryInfo(dirName);
+ return new DirectoryInfo(dirName);
}
}
@@ -187,27 +113,9 @@ namespace System.IO {
}
}
-#if FEATURE_MACL
- public FileSecurity GetAccessControl()
- {
- return File.GetAccessControl(FullPath, AccessControlSections.Access | AccessControlSections.Owner | AccessControlSections.Group);
- }
-
- public FileSecurity GetAccessControl(AccessControlSections includeSections)
- {
- return File.GetAccessControl(FullPath, includeSections);
- }
-
- public void SetAccessControl(FileSecurity fileSecurity)
- {
- File.SetAccessControl(FullPath, fileSecurity);
- }
-#endif
-
- [System.Security.SecuritySafeCritical] // auto-generated
public StreamReader OpenText()
{
- return new StreamReader(FullPath, Encoding.UTF8, true, StreamReader.DefaultBufferSize, false);
+ return new StreamReader(FullPath, Encoding.UTF8, true, StreamReader.DefaultBufferSize);
}
public StreamWriter CreateText()
@@ -220,45 +128,33 @@ namespace System.IO {
return new StreamWriter(FullPath,true);
}
-
// Copies an existing file to a new file. An exception is raised if the
// destination file already exists. Use the
// Copy(String, String, boolean) method to allow
// overwriting an existing file.
- //
- // The caller must have certain FileIOPermissions. The caller must have
- // Read permission to sourceFileName
- // and Write permissions to destFileName.
- //
public FileInfo CopyTo(String destFileName) {
if (destFileName == null)
- throw new ArgumentNullException("destFileName", Environment.GetResourceString("ArgumentNull_FileName"));
+ throw new ArgumentNullException(nameof(destFileName), Environment.GetResourceString("ArgumentNull_FileName"));
if (destFileName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "destFileName");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destFileName));
Contract.EndContractBlock();
- destFileName = File.InternalCopy(FullPath, destFileName, false, true);
+ destFileName = File.InternalCopy(FullPath, destFileName, false);
return new FileInfo(destFileName, false);
}
-
// Copies an existing file to a new file. If overwrite is
// false, then an IOException is thrown if the destination file
// already exists. If overwrite is true, the file is
// overwritten.
- //
- // The caller must have certain FileIOPermissions. The caller must have
- // Read permission to sourceFileName and Create
- // and Write permissions to destFileName.
- //
public FileInfo CopyTo(String destFileName, bool overwrite) {
if (destFileName == null)
- throw new ArgumentNullException("destFileName", Environment.GetResourceString("ArgumentNull_FileName"));
+ throw new ArgumentNullException(nameof(destFileName), Environment.GetResourceString("ArgumentNull_FileName"));
if (destFileName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "destFileName");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destFileName));
Contract.EndContractBlock();
- destFileName = File.InternalCopy(FullPath, destFileName, overwrite, true);
+ destFileName = File.InternalCopy(FullPath, destFileName, overwrite);
return new FileInfo(destFileName, false);
}
@@ -271,22 +167,9 @@ namespace System.IO {
// an exception.
//
// On NT, Delete will fail for a file that is open for normal I/O
- // or a file that is memory mapped. On Win95, the file will be
- // deleted irregardless of whether the file is being used.
- //
- // Your application must have Delete permission to the target file.
- //
- [System.Security.SecuritySafeCritical]
+ // or a file that is memory mapped.
public override void Delete()
{
-#if FEATURE_CORECLR
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Write, DisplayPath, FullPath);
- state.EnsureState();
-#else
- // For security check, path should be resolved to an absolute path.
- new FileIOPermission(FileIOPermissionAccess.Write, new String[] { FullPath }, false, false).Demand();
-#endif
-
bool r = Win32Native.DeleteFile(FullPath);
if (!r) {
int hr = Marshal.GetLastWin32Error();
@@ -297,25 +180,10 @@ namespace System.IO {
}
}
- [ComVisible(false)]
- public void Decrypt()
- {
- File.Decrypt(FullPath);
- }
-
- [ComVisible(false)]
- public void Encrypt()
- {
- File.Encrypt(FullPath);
- }
-
// Tests if the given file exists. The result is true if the file
// given by the specified path exists; otherwise, the result is
// false.
- //
- // Your application must have Read permission for the target directory.
public override bool Exists {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
try {
if (_dataInitialised == -1)
@@ -335,9 +203,6 @@ namespace System.IO {
}
}
-
-
-
// User must explicitly specify opening a new file or appending to one.
public FileStream Open(FileMode mode) {
return Open(mode, FileAccess.ReadWrite, FileShare.None);
@@ -351,54 +216,28 @@ namespace System.IO {
return new FileStream(FullPath, mode, access, share);
}
-
-#if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical] // auto-generated
-#endif
public FileStream OpenRead()
{
return new FileStream(FullPath, FileMode.Open, FileAccess.Read,
FileShare.Read, 4096, false);
}
-
public FileStream OpenWrite() {
return new FileStream(FullPath, FileMode.OpenOrCreate,
FileAccess.Write, FileShare.None);
}
-
-
-
-
-
// Moves a given file to a new location and potentially a new file name.
// This method does work across volumes.
- //
- // The caller must have certain FileIOPermissions. The caller must
- // have Read and Write permission to
- // sourceFileName and Write
- // permissions to destFileName.
- //
- [System.Security.SecuritySafeCritical]
public void MoveTo(String destFileName) {
if (destFileName==null)
- throw new ArgumentNullException("destFileName");
+ throw new ArgumentNullException(nameof(destFileName));
if (destFileName.Length==0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "destFileName");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), nameof(destFileName));
Contract.EndContractBlock();
- String fullDestFileName = Path.GetFullPathInternal(destFileName);
-#if FEATURE_CORECLR
- FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Write | FileSecurityStateAccess.Read, DisplayPath, FullPath);
- FileSecurityState destState = new FileSecurityState(FileSecurityStateAccess.Write, destFileName, fullDestFileName);
- sourceState.EnsureState();
- destState.EnsureState();
-#else
- new FileIOPermission(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, new String[] { FullPath }, false, false).Demand();
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, fullDestFileName, false, false);
-#endif
-
+ string fullDestFileName = Path.GetFullPath(destFileName);
+
if (!Win32Native.MoveFile(FullPath, fullDestFileName))
__Error.WinIOError();
FullPath = fullDestFileName;
diff --git a/src/mscorlib/src/System/IO/FileLoadException.cs b/src/mscorlib/src/System/IO/FileLoadException.cs
index fabe2613c3..2b56c00191 100644
--- a/src/mscorlib/src/System/IO/FileLoadException.cs
+++ b/src/mscorlib/src/System/IO/FileLoadException.cs
@@ -91,7 +91,6 @@ namespace System.IO {
if (StackTrace != null)
s += Environment.NewLine + StackTrace;
-#if FEATURE_FUSION
try
{
if(FusionLog!=null)
@@ -107,7 +106,6 @@ namespace System.IO {
{
}
-#endif // FEATURE_FUSION
return s;
}
@@ -117,7 +115,6 @@ namespace System.IO {
_fileName = info.GetString("FileLoad_FileName");
-#if FEATURE_FUSION
try
{
_fusionLog = info.GetString("FileLoad_FusionLog");
@@ -126,7 +123,6 @@ namespace System.IO {
{
_fusionLog = null;
}
-#endif
}
private FileLoadException(String fileName, String fusionLog,int hResult)
@@ -138,15 +134,10 @@ namespace System.IO {
SetMessageField();
}
-#if FEATURE_FUSION
public String FusionLog {
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)]
get { return _fusionLog; }
}
-#endif // FEATURE_FUSION
- [System.Security.SecurityCritical] // auto-generated_required
public override void GetObjectData(SerializationInfo info, StreamingContext context) {
// Serialize data for our base classes. base will verify info != null.
base.GetObjectData(info, context);
@@ -154,7 +145,6 @@ namespace System.IO {
// Serialize data for this class
info.AddValue("FileLoad_FileName", _fileName, typeof(String));
-#if FEATURE_FUSION
try
{
info.AddValue("FileLoad_FusionLog", FusionLog, typeof(String));
@@ -162,10 +152,8 @@ namespace System.IO {
catch (SecurityException)
{
}
-#endif
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static String FormatFileLoadExceptionMessage(String fileName,
int hResult)
{
@@ -178,12 +166,10 @@ namespace System.IO {
return String.Format(CultureInfo.CurrentCulture, format, fileName, message);
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void GetFileLoadExceptionMessage(int hResult, StringHandleOnStack retString);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void GetMessageForHR(int hresult, StringHandleOnStack retString);
diff --git a/src/mscorlib/src/System/IO/FileNotFoundException.cs b/src/mscorlib/src/System/IO/FileNotFoundException.cs
index 933e4fd94c..8cc75f8232 100644
--- a/src/mscorlib/src/System/IO/FileNotFoundException.cs
+++ b/src/mscorlib/src/System/IO/FileNotFoundException.cs
@@ -93,7 +93,6 @@ namespace System.IO {
if (StackTrace != null)
s += Environment.NewLine + StackTrace;
-#if FEATURE_FUSION
try
{
if(FusionLog!=null)
@@ -109,7 +108,6 @@ namespace System.IO {
{
}
-#endif
return s;
}
@@ -118,7 +116,6 @@ namespace System.IO {
// Base class constructor will check info != null.
_fileName = info.GetString("FileNotFound_FileName");
-#if FEATURE_FUSION
try
{
_fusionLog = info.GetString("FileNotFound_FusionLog");
@@ -127,7 +124,6 @@ namespace System.IO {
{
_fusionLog = null;
}
-#endif
}
private FileNotFoundException(String fileName, String fusionLog,int hResult)
@@ -139,15 +135,10 @@ namespace System.IO {
SetMessageField();
}
-#if FEATURE_FUSION
public String FusionLog {
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)]
get { return _fusionLog; }
}
-#endif
- [System.Security.SecurityCritical] // auto-generated_required
public override void GetObjectData(SerializationInfo info, StreamingContext context) {
// Serialize data for our base classes. base will verify info != null.
base.GetObjectData(info, context);
@@ -155,7 +146,6 @@ namespace System.IO {
// Serialize data for this class
info.AddValue("FileNotFound_FileName", _fileName, typeof(String));
-#if FEATURE_FUSION
try
{
info.AddValue("FileNotFound_FusionLog", FusionLog, typeof(String));
@@ -163,7 +153,6 @@ namespace System.IO {
catch (SecurityException)
{
}
-#endif
}
}
}
diff --git a/src/mscorlib/src/System/IO/FileSecurityState.cs b/src/mscorlib/src/System/IO/FileSecurityState.cs
deleted file mode 100644
index 249848ac02..0000000000
--- a/src/mscorlib/src/System/IO/FileSecurityState.cs
+++ /dev/null
@@ -1,133 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: FileSecurityState
-**
-**
-**
-**
-** Purpose: Determines whether file system access is safe
-**
-**
-===========================================================*/
-
-using System;
-using System.Diagnostics.Contracts;
-using System.IO;
-using System.Security;
-using System.Security.Permissions;
-
-namespace System.IO
-{
- [SecurityCritical]
- [System.Runtime.CompilerServices.FriendAccessAllowed]
- internal class FileSecurityState : SecurityState
- {
-#if !PLATFORM_UNIX
- private static readonly char[] m_illegalCharacters = { '?', '*' };
-#endif // !PLATFORM_UNIX
-
- private FileSecurityStateAccess m_access;
- private String m_userPath;
- private String m_canonicalizedPath;
-
- // default ctor needed for security rule consistency
- [SecurityCritical]
- private FileSecurityState()
- {
- }
-
- internal FileSecurityState(FileSecurityStateAccess access, String path)
- {
- if (path == null)
- {
- throw new ArgumentNullException("path");
- }
- VerifyAccess(access);
- m_access = access;
- m_userPath = path;
- if (path.Equals(String.Empty, StringComparison.OrdinalIgnoreCase))
- {
- m_canonicalizedPath = String.Empty;
- }
- else
- {
- VerifyPath(path);
- m_canonicalizedPath = System.IO.Path.GetFullPathInternal(path);
- }
- }
-
- // slight perf savings for trusted internal callers
- internal FileSecurityState(FileSecurityStateAccess access, String path, String canonicalizedPath)
- {
- VerifyAccess(access);
- VerifyPath(path);
- VerifyPath(canonicalizedPath);
-
- m_access = access;
- m_userPath = path;
- m_canonicalizedPath = canonicalizedPath;
- }
-
- internal FileSecurityStateAccess Access
- {
- get
- {
- return m_access;
- }
- }
-
- public String Path {
- [System.Runtime.CompilerServices.FriendAccessAllowed]
- get
- {
- return m_canonicalizedPath;
- }
- }
-
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
- public override void EnsureState()
- {
- // this is the case for empty string machine name, etc
- if (String.Empty.Equals(m_canonicalizedPath))
- return;
-
- if (!IsStateAvailable())
- {
- throw new SecurityException(Environment.GetResourceString("FileSecurityState_OperationNotPermitted", (m_userPath == null) ? String.Empty : m_userPath));
- }
- }
-
- internal static FileSecurityStateAccess ToFileSecurityState(FileIOPermissionAccess access)
- {
- Contract.Requires((access & ~FileIOPermissionAccess.AllAccess) == 0);
- return (FileSecurityStateAccess)access; // flags are identical; just cast
- }
-
- private static void VerifyAccess(FileSecurityStateAccess access)
- {
- if ((access & ~FileSecurityStateAccess.AllAccess) != 0)
- throw new ArgumentOutOfRangeException("access", Environment.GetResourceString("Arg_EnumIllegalVal"));
- }
-
- private static void VerifyPath(String path)
- {
- if (path != null)
- {
- path = path.Trim();
-
-#if !PLATFORM_UNIX
- if (!PathInternal.IsDevice(path) && PathInternal.HasInvalidVolumeSeparator(path))
- throw new ArgumentException(Environment.GetResourceString("Argument_PathFormatNotSupported"));
-#endif
-
- System.IO.Path.CheckInvalidPathChars(path, checkAdditional: true);
- }
- }
- }
-}
diff --git a/src/mscorlib/src/System/IO/FileSecurityStateAccess.cs b/src/mscorlib/src/System/IO/FileSecurityStateAccess.cs
deleted file mode 100644
index b6378c6142..0000000000
--- a/src/mscorlib/src/System/IO/FileSecurityStateAccess.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.
-
-/*============================================================
-**
-** Enum: FileSecurityStateAccess
-**
-**
-**
-**
-** Purpose: FileSecurityState enum
-**
-**
-===========================================================*/
-
-using System;
-
-namespace System.IO
-{
- [Flags]
- internal enum FileSecurityStateAccess
- {
- NoAccess = 0,
- Read = 1,
- Write = 2,
- Append = 4,
- PathDiscovery = 8,
- AllAccess = 15
- }
-}
-
diff --git a/src/mscorlib/src/System/IO/FileStream.cs b/src/mscorlib/src/System/IO/FileStream.cs
deleted file mode 100644
index deef30c480..0000000000
--- a/src/mscorlib/src/System/IO/FileStream.cs
+++ /dev/null
@@ -1,2695 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: Exposes a Stream around a file, with full
-** synchronous and asychronous support, and buffering.
-**
-**
-===========================================================*/
-using System;
-using Microsoft.Win32;
-using Microsoft.Win32.SafeHandles;
-using System.Security;
-#if FEATURE_MACL
-using System.Security.AccessControl;
-#endif
-using System.Security.Permissions;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Runtime.InteropServices;
-#if FEATURE_REMOTING
-using System.Runtime.Remoting.Messaging;
-#endif
-using System.Runtime.CompilerServices;
-using System.Globalization;
-using System.Runtime.Versioning;
-using System.Diagnostics.Contracts;
-using System.Diagnostics.Tracing;
-
-/*
- * FileStream supports different modes of accessing the disk - async mode
- * and sync mode. They are two completely different codepaths in the
- * sync & async methods (ie, Read/Write vs. BeginRead/BeginWrite). 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 FileStream as well. Folded in the
- * code from BufferedStream, so all the comments about it being mostly
- * aggressive (and the possible perf improvement) apply to FileStream 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 {
-
- // This is an internal object implementing IAsyncResult with fields
- // for all of the relevant data necessary to complete the IO operation.
- // This is used by AsyncFSCallback and all of the async methods.
- // We should probably make this a nested type of FileStream. But
- // I don't know how to define a nested class in mscorlib.h
-
- unsafe internal sealed class FileStreamAsyncResult : IAsyncResult
- {
- // README:
- // If you modify the order of these fields, make sure to update
- // the native VM definition of this class as well!!!
- // User code callback
- private AsyncCallback _userCallback;
- private Object _userStateObject;
- private ManualResetEvent _waitHandle;
- [System.Security.SecurityCritical]
- private SafeFileHandle _handle; // For cancellation support.
-
- [SecurityCritical]
- private NativeOverlapped* _overlapped;
- internal NativeOverlapped* OverLapped { [SecurityCritical]get { return _overlapped; } }
- internal bool IsAsync { [SecuritySafeCritical]get { return _overlapped != null; } }
-
-
- internal int _EndXxxCalled; // Whether we've called EndXxx already.
- private int _numBytes; // number of bytes read OR written
- internal int NumBytes { get { return _numBytes; } }
-
- private int _errorCode;
- internal int ErrorCode { get { return _errorCode; } }
-
- private int _numBufferedBytes;
- internal int NumBufferedBytes { get { return _numBufferedBytes; } }
-
- internal int NumBytesRead { get { return _numBytes + _numBufferedBytes; } }
-
- private bool _isWrite; // Whether this is a read or a write
- internal bool IsWrite { get { return _isWrite; } }
-
- private bool _isComplete; // Value for IsCompleted property
- private bool _completedSynchronously; // Which thread called callback
-
- // The NativeOverlapped struct keeps a GCHandle to this IAsyncResult object.
- // So if the user doesn't call EndRead/EndWrite, a finalizer won't help because
- // it'll never get called.
-
- // Overlapped class will take care of the async IO operations in progress
- // when an appdomain unload occurs.
-
- [System.Security.SecurityCritical] // auto-generated
- private unsafe static IOCompletionCallback s_IOCallback;
-
- [SecuritySafeCritical]
- internal FileStreamAsyncResult(
- int numBufferedBytes,
- byte[] bytes,
- SafeFileHandle handle,
- AsyncCallback userCallback,
- Object userStateObject,
- bool isWrite)
- {
- _userCallback = userCallback;
- _userStateObject = userStateObject;
- _isWrite = isWrite;
- _numBufferedBytes = numBufferedBytes;
- _handle = handle;
-
- // For Synchronous IO, I could go with either a callback and using
- // the managed Monitor class, or I could create a handle and wait on it.
- ManualResetEvent waitHandle = new ManualResetEvent(false);
- _waitHandle = waitHandle;
-
- // Create a managed overlapped class
- // We will set the file offsets later
- Overlapped overlapped = new Overlapped(0, 0, IntPtr.Zero, this);
-
- // Pack the Overlapped class, and store it in the async result
- if (userCallback != null)
- {
- var ioCallback = s_IOCallback; // cached static delegate; delay initialized due to it being SecurityCritical
- if (ioCallback == null) s_IOCallback = ioCallback = new IOCompletionCallback(AsyncFSCallback);
- _overlapped = overlapped.Pack(ioCallback, bytes);
- }
- else
- {
- _overlapped = overlapped.UnsafePack(null, bytes);
- }
-
- Contract.Assert(_overlapped != null, "Did Overlapped.Pack or Overlapped.UnsafePack just return a null?");
- }
-
- internal static FileStreamAsyncResult CreateBufferedReadResult(int numBufferedBytes, AsyncCallback userCallback, Object userStateObject, bool isWrite)
- {
- FileStreamAsyncResult asyncResult = new FileStreamAsyncResult(numBufferedBytes, userCallback, userStateObject, isWrite);
- asyncResult.CallUserCallback();
- return asyncResult;
- }
-
- // This creates a synchronous Async Result. We should consider making this a separate class and maybe merge it with
- // System.IO.Stream.SynchronousAsyncResult
- private FileStreamAsyncResult(int numBufferedBytes, AsyncCallback userCallback, Object userStateObject, bool isWrite)
- {
- _userCallback = userCallback;
- _userStateObject = userStateObject;
- _isWrite = isWrite;
- _numBufferedBytes = numBufferedBytes;
- }
-
- public Object AsyncState
- {
- get { return _userStateObject; }
- }
-
- public bool IsCompleted
- {
- get { return _isComplete; }
- }
-
- public WaitHandle AsyncWaitHandle
- {
- [System.Security.SecuritySafeCritical] // auto-generated
- get {
- // Consider uncommenting this someday soon - the EventHandle
- // in the Overlapped struct is really useless half of the
- // time today since the OS doesn't signal it. If users call
- // EndXxx after the OS call happened to complete, there's no
- // reason to create a synchronization primitive here. Fixing
- // this will save us some perf, assuming we can correctly
- // initialize the ManualResetEvent.
- if (_waitHandle == null) {
- ManualResetEvent mre = new ManualResetEvent(false);
- if (_overlapped != null && _overlapped->EventHandle != IntPtr.Zero) {
- mre.SafeWaitHandle = new SafeWaitHandle(_overlapped->EventHandle, true);
- }
-
- // make sure only one thread sets _waitHandle
- if (Interlocked.CompareExchange<ManualResetEvent>(ref _waitHandle, mre, null) == null) {
- if (_isComplete)
- _waitHandle.Set();
- }
- else {
- // There's a slight but acceptable race condition if we weren't
- // the thread that set _waitHandle and this code path
- // returns before the code in the if statement
- // executes (on the other thread). However, the
- // caller is waiting for the wait handle to be set,
- // which will still happen.
- mre.Close();
- }
- }
- return _waitHandle;
- }
- }
-
- // Returns true iff the user callback was called by the thread that
- // called BeginRead or BeginWrite. If we use an async delegate or
- // threadpool thread internally, this will be false. This is used
- // by code to determine whether a successive call to BeginRead needs
- // to be done on their main thread or in their callback to avoid a
- // stack overflow on many reads or writes.
- public bool CompletedSynchronously
- {
- get { return _completedSynchronously; }
- }
-
- private void CallUserCallbackWorker()
- {
- _isComplete = true;
-
- // ensure _isComplete is set before reading _waitHandle
- Thread.MemoryBarrier();
- if (_waitHandle != null)
- _waitHandle.Set();
-
- _userCallback(this);
- }
-
- internal void CallUserCallback()
- {
- // Convenience method for me, since I have to do this in a number
- // of places in the buffering code for fake IAsyncResults.
- // AsyncFSCallback intentionally does not use this method.
-
- if (_userCallback != null) {
- // Call user's callback on a threadpool thread.
- // Set completedSynchronously to false, since it's on another
- // thread, not the main thread.
- _completedSynchronously = false;
- ThreadPool.QueueUserWorkItem(state => ((FileStreamAsyncResult)state).CallUserCallbackWorker(), this);
- }
- else {
- _isComplete = true;
-
- // ensure _isComplete is set before reading _waitHandle
- Thread.MemoryBarrier();
- if (_waitHandle != null)
- _waitHandle.Set();
- }
- }
-
- [SecurityCritical]
- internal void ReleaseNativeResource()
- {
- // Free memory & GC handles.
- if (this._overlapped != null)
- Overlapped.Free(_overlapped);
- }
-
- internal void Wait()
- {
- if (_waitHandle != null)
- {
- // We must block to ensure that AsyncFSCallback has completed,
- // and we should close the WaitHandle in here. AsyncFSCallback
- // and the hand-ported imitation version in COMThreadPool.cpp
- // are the only places that set this event.
- try
- {
- _waitHandle.WaitOne();
- Contract.Assert(_isComplete == true, "FileStreamAsyncResult::Wait - AsyncFSCallback didn't set _isComplete to true!");
- }
- finally
- {
- _waitHandle.Close();
- }
- }
- }
-
- // When doing IO asynchronously (ie, _isAsync==true), this callback is
- // called by a free thread in the threadpool when the IO operation
- // completes.
- [System.Security.SecurityCritical] // auto-generated
- unsafe private static void AsyncFSCallback(uint errorCode, uint numBytes, NativeOverlapped* pOverlapped)
- {
- BCLDebug.Log(String.Format("AsyncFSCallback called. errorCode: " + errorCode + " numBytes: " + numBytes));
-
- // Unpack overlapped
- Overlapped overlapped = Overlapped.Unpack(pOverlapped);
- // Free the overlapped struct in EndRead/EndWrite.
-
- // Extract async result from overlapped
- FileStreamAsyncResult asyncResult =
- (FileStreamAsyncResult)overlapped.AsyncResult;
- asyncResult._numBytes = (int)numBytes;
-
- if (FrameworkEventSource.IsInitialized && FrameworkEventSource.Log.IsEnabled(EventLevel.Informational, FrameworkEventSource.Keywords.ThreadTransfer))
- FrameworkEventSource.Log.ThreadTransferReceive((long)(asyncResult.OverLapped), 2, string.Empty);
-
- // 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.
- if (errorCode == FileStream.ERROR_BROKEN_PIPE || errorCode == FileStream.ERROR_NO_DATA)
- errorCode = 0;
-
- asyncResult._errorCode = (int)errorCode;
-
- // Call the user-provided callback. It can and often should
- // call EndRead or EndWrite. There's no reason to use an async
- // delegate here - we're already on a threadpool thread.
- // IAsyncResult's completedSynchronously property must return
- // false here, saying the user callback was called on another thread.
- asyncResult._completedSynchronously = false;
- asyncResult._isComplete = true;
-
- // ensure _isComplete is set before reading _waitHandle
- Thread.MemoryBarrier();
-
- // The OS does not signal this event. We must do it ourselves.
- ManualResetEvent wh = asyncResult._waitHandle;
- if (wh != null)
- {
- Contract.Assert(!wh.SafeWaitHandle.IsClosed, "ManualResetEvent already closed!");
- bool r = wh.Set();
- Contract.Assert(r, "ManualResetEvent::Set failed!");
- if (!r) __Error.WinIOError();
- }
-
- AsyncCallback userCallback = asyncResult._userCallback;
- if (userCallback != null)
- userCallback(asyncResult);
- }
-
- [SecuritySafeCritical]
- [HostProtection(ExternalThreading = true)]
- internal void Cancel()
- {
- Contract.Assert(_handle != null, "_handle should not be null.");
- Contract.Assert(_overlapped != null, "Cancel should only be called on true asynchronous FileStreamAsyncResult, i.e. _overlapped is not null");
-
- if (IsCompleted)
- return;
-
- if (_handle.IsInvalid)
- return;
-
- bool r = Win32Native.CancelIoEx(_handle, _overlapped);
- if (!r)
- {
- 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 != Win32Native.ERROR_NOT_FOUND)
- __Error.WinIOError(errorCode, String.Empty);
- }
- }
- }
-
- [ComVisible(true)]
- public class FileStream : Stream
- {
- internal const int DefaultBufferSize = 4096;
-
- private byte[] _buffer; // Shared read/write buffer. Alloc on first use.
- private String _fileName; // Fully qualified file name.
- private bool _isAsync; // Whether we opened the handle for overlapped IO
- private bool _canRead;
- private bool _canWrite;
- private bool _canSeek;
- private bool _exposedHandle; // Could other code be using this handle?
- private bool _isPipe; // Whether to disable async buffering code.
- private int _readPos; // Read pointer within shared buffer.
- private int _readLen; // Number of bytes read in buffer from file.
- private int _writePos; // Write pointer within shared buffer.
- private int _bufferSize; // Length of internal buffer, if it's allocated.
- [System.Security.SecurityCritical] // auto-generated
- private SafeFileHandle _handle;
- private long _pos; // Cache current location in the file.
- private long _appendStart;// When appending, prevent overwriting file.
- private static AsyncCallback s_endReadTask;
- private static AsyncCallback s_endWriteTask;
- private static Action<object> s_cancelReadHandler;
- private static Action<object> s_cancelWriteHandler;
-
- //This exists only to support IsolatedStorageFileStream.
- //Any changes to FileStream must include the corresponding changes in IsolatedStorage.
- internal FileStream() {
- }
-#if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical]
- public FileStream(String path, FileMode mode)
- : this(path, mode, (mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite), FileShare.Read, DefaultBufferSize, FileOptions.None, Path.GetFileName(path), false, false, true) {
- }
-
- [System.Security.SecuritySafeCritical]
- public FileStream(String path, FileMode mode, FileAccess access)
- : this(path, mode, access, FileShare.Read, DefaultBufferSize, FileOptions.None, Path.GetFileName(path), false, false, true) {
- }
-
- [System.Security.SecuritySafeCritical]
- public FileStream(String path, FileMode mode, FileAccess access, FileShare share)
- : this(path, mode, access, share, DefaultBufferSize, FileOptions.None, Path.GetFileName(path), false, false, true) {
- }
-
- [System.Security.SecuritySafeCritical]
- public FileStream(String path, FileMode mode, FileAccess access, FileShare share, int bufferSize)
- : this(path, mode, access, share, bufferSize, FileOptions.None, Path.GetFileName(path), false, false, true)
- {
- }
-
-#else // FEATURE_CORECLR
- [System.Security.SecuritySafeCritical] // auto-generated
- public FileStream(String path, FileMode mode)
- : this(path, mode, (mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite), FileShare.Read, DefaultBufferSize, FileOptions.None, Path.GetFileName(path), false) {
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public FileStream(String path, FileMode mode, FileAccess access)
- : this(path, mode, access, FileShare.Read, DefaultBufferSize, FileOptions.None, Path.GetFileName(path), false) {
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public FileStream(String path, FileMode mode, FileAccess access, FileShare share)
- : this(path, mode, access, share, DefaultBufferSize, FileOptions.None, Path.GetFileName(path), false) {
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public FileStream(String path, FileMode mode, FileAccess access, FileShare share, int bufferSize)
- : this(path, mode, access, share, bufferSize, FileOptions.None, Path.GetFileName(path), false)
- {
- }
-#endif // FEATURE_CORECLR
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public FileStream(String path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options)
- : this(path, mode, access, share, bufferSize, options, Path.GetFileName(path), false)
- {
- }
-
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #else
- [System.Security.SecuritySafeCritical]
- #endif
- public FileStream(String path, FileMode mode, FileAccess access, FileShare share, int bufferSize, bool useAsync)
- : this(path, mode, access, share, bufferSize, (useAsync ? FileOptions.Asynchronous : FileOptions.None), Path.GetFileName(path), false)
- {
- }
-
-#if FEATURE_MACL
- // This constructor is done differently to avoid loading a few more
- // classes, and more importantly, to build correctly on Rotor.
- [System.Security.SecuritySafeCritical] // auto-generated
- public FileStream(String path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize, FileOptions options, FileSecurity fileSecurity)
- {
- Object pinningHandle;
- Win32Native.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(share, fileSecurity, out pinningHandle);
- try {
- Init(path, mode, (FileAccess)0, (int)rights, true, share, bufferSize, options, secAttrs, Path.GetFileName(path), false, false, false);
- }
- finally {
- if (pinningHandle != null) {
- GCHandle pinHandle = (GCHandle) pinningHandle;
- pinHandle.Free();
- }
- }
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public FileStream(String path, FileMode mode, FileSystemRights rights, FileShare share, int bufferSize, FileOptions options)
- {
- Win32Native.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(share);
- Init(path, mode, (FileAccess)0, (int)rights, true, share, bufferSize, options, secAttrs, Path.GetFileName(path), false, false, false);
- }
-#endif
-
- [System.Security.SecurityCritical] // auto-generated
- internal FileStream(String path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, String msgPath, bool bFromProxy)
- {
- Win32Native.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(share);
- Init(path, mode, access, 0, false, share, bufferSize, options, secAttrs, msgPath, bFromProxy, false, false);
- }
-
- [System.Security.SecurityCritical]
- internal FileStream(String path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, String msgPath, bool bFromProxy, bool useLongPath)
- {
- Win32Native.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(share);
- Init(path, mode, access, 0, false, share, bufferSize, options, secAttrs, msgPath, bFromProxy, useLongPath, false);
- }
-
- [System.Security.SecurityCritical]
- internal FileStream(String path, FileMode mode, FileAccess access, FileShare share, int bufferSize, FileOptions options, String msgPath, bool bFromProxy, bool useLongPath, bool checkHost)
- {
- Win32Native.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(share);
- Init(path, mode, access, 0, false, share, bufferSize, options, secAttrs, msgPath, bFromProxy, useLongPath, checkHost);
- }
-
- // AccessControl namespace is not defined in Rotor
- [System.Security.SecuritySafeCritical]
- private void Init(String path, FileMode mode, FileAccess access, int rights, bool useRights, FileShare share, int bufferSize, FileOptions options, Win32Native.SECURITY_ATTRIBUTES secAttrs, String msgPath, bool bFromProxy, bool useLongPath, bool checkHost)
- {
- if (path == null)
- throw new ArgumentNullException("path", Environment.GetResourceString("ArgumentNull_Path"));
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
- Contract.EndContractBlock();
-
-#if FEATURE_MACL
- FileSystemRights fileSystemRights = (FileSystemRights)rights;
-#endif
- // msgPath must be safe to hand back to untrusted code.
-
- _fileName = msgPath; // To handle odd cases of finalizing partially constructed objects.
- _exposedHandle = false;
-
- // don't include inheritable in our bounds check for share
- FileShare tempshare = share & ~FileShare.Inheritable;
- String badArg = null;
-
- if (mode < FileMode.CreateNew || mode > FileMode.Append)
- badArg = "mode";
- else if (!useRights && (access < FileAccess.Read || access > FileAccess.ReadWrite))
- badArg = "access";
-#if FEATURE_MACL
- else if (useRights && (fileSystemRights < FileSystemRights.ReadData || fileSystemRights > FileSystemRights.FullControl))
- badArg = "rights";
-#endif
- else if (tempshare < FileShare.None || tempshare > (FileShare.ReadWrite | FileShare.Delete))
- badArg = "share";
-
- if (badArg != null)
- throw new ArgumentOutOfRangeException(badArg, Environment.GetResourceString("ArgumentOutOfRange_Enum"));
-
- // NOTE: any change to FileOptions enum needs to be matched here in the error validation
- if (options != FileOptions.None && (options & ~(FileOptions.WriteThrough | FileOptions.Asynchronous | FileOptions.RandomAccess | FileOptions.DeleteOnClose | FileOptions.SequentialScan | FileOptions.Encrypted | (FileOptions)0x20000000 /* NoBuffering */)) != 0)
- throw new ArgumentOutOfRangeException("options", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
-
- if (bufferSize <= 0)
- throw new ArgumentOutOfRangeException("bufferSize", Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
-
- // Write access validation
-#if FEATURE_MACL
- if ((!useRights && (access & FileAccess.Write) == 0)
- || (useRights && (fileSystemRights & FileSystemRights.Write) == 0))
-#else
- if (!useRights && (access & FileAccess.Write) == 0)
-#endif //FEATURE_MACL
- {
- if (mode==FileMode.Truncate || mode==FileMode.CreateNew || mode==FileMode.Create || mode==FileMode.Append) {
- // No write access
- if (!useRights)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFileMode&AccessCombo", mode, access));
-#if FEATURE_MACL
- else
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFileMode&RightsCombo", mode, fileSystemRights));
-#endif //FEATURE_MACL
- }
- }
-
-#if FEATURE_MACL
- // FileMode.Truncate only works with GENERIC_WRITE (FileAccess.Write), source:MSDN
- // For backcomp use FileAccess.Write when FileSystemRights.Write is specified
- if (useRights && (mode == FileMode.Truncate)) {
- if (fileSystemRights == FileSystemRights.Write) {
- useRights = false;
- access = FileAccess.Write;
- }
- else {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFileModeTruncate&RightsCombo", mode, fileSystemRights));
- }
- }
-#endif
-
- int fAccess;
- if (!useRights) {
- fAccess = access == FileAccess.Read? GENERIC_READ:
- access == FileAccess.Write? GENERIC_WRITE:
- GENERIC_READ | GENERIC_WRITE;
- }
- else {
- fAccess = rights;
- }
-
- // Get absolute path - Security needs this to prevent something
- // like trying to create a file in c:\tmp with the name
- // "..\WinNT\System32\ntoskrnl.exe". Store it for user convenience.
- int maxPath = useLongPath ? Path.MaxLongPath : Path.MaxPath;
- String filePath = Path.NormalizePath(path, true, maxPath);
-
- _fileName = filePath;
-
- // Prevent access to your disk drives as raw block devices.
- if (filePath.StartsWith("\\\\.\\", StringComparison.Ordinal))
- throw new ArgumentException(Environment.GetResourceString("Arg_DevicesNotSupported"));
-
- // In 4.0, we always construct a FileIOPermission object below.
- // If filePath contained a ':', we would throw a NotSupportedException in
- // System.Security.Util.StringExpressionSet.CanonicalizePath.
- // If filePath contained other illegal characters, we would throw an ArgumentException in
- // FileIOPermission.CheckIllegalCharacters.
- // In 4.5 we on longer construct the FileIOPermission object in full trust.
- // To preserve the 4.0 behavior we do an explicit check for ':' here and also call Path.CheckInvalidPathChars.
- // Note that we need to call CheckInvalidPathChars before checking for ':' because that is what FileIOPermission does.
-
- Path.CheckInvalidPathChars(filePath, true);
-
-#if !PLATFORM_UNIX
- if (filePath.IndexOf( ':', 2 ) != -1)
- throw new NotSupportedException( Environment.GetResourceString( "Argument_PathFormatNotSupported" ) );
-#endif // !PLATFORM_UNIX
-
- bool read = false;
-
-#if FEATURE_MACL
- if ((!useRights && (access & FileAccess.Read) != 0) || (useRights && (fileSystemRights & FileSystemRights.ReadAndExecute) != 0))
-#else
- if (!useRights && (access & FileAccess.Read) != 0)
-#endif //FEATURE_MACL
- {
- if (mode == FileMode.Append)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidAppendMode"));
- else
- read = true;
- }
-
- // All demands in full trust domains are no-ops, so skip
-#if FEATURE_CAS_POLICY
- if (!CodeAccessSecurityEngine.QuickCheckForAllDemands())
-#endif // FEATURE_CAS_POLICY
- {
- // Build up security permissions required, as well as validate we
- // have a sensible set of parameters. IE, creating a brand new file
- // for reading doesn't make much sense.
- FileIOPermissionAccess secAccess = FileIOPermissionAccess.NoAccess;
-
- if (read)
- {
- Contract.Assert(mode != FileMode.Append);
- secAccess = secAccess | FileIOPermissionAccess.Read;
- }
-
- // I can't think of any combos of FileMode we should disallow if we
- // don't have read access. Writing would pretty much always be valid
- // in those cases.
-
- // For any FileSystemRights other than ReadAndExecute, demand Write permission
- // This is probably bit overkill for TakeOwnership etc but we don't have any
- // matching FileIOPermissionAccess to demand. It is better that we ask for Write permission.
-
-#if FEATURE_MACL
- // FileMode.OpenOrCreate & FileSystemRights.Synchronize can create 0-byte file; demand write
- if ((!useRights && (access & FileAccess.Write) != 0)
- || (useRights && (fileSystemRights & (FileSystemRights.Write | FileSystemRights.Delete
- | FileSystemRights.DeleteSubdirectoriesAndFiles
- | FileSystemRights.ChangePermissions
- | FileSystemRights.TakeOwnership)) != 0)
- || (useRights && ((fileSystemRights & FileSystemRights.Synchronize) != 0)
- && mode==FileMode.OpenOrCreate)
- )
-#else
- if (!useRights && (access & FileAccess.Write) != 0)
-#endif //FEATURE_MACL
- {
- if (mode==FileMode.Append)
- secAccess = secAccess | FileIOPermissionAccess.Append;
- else
- secAccess = secAccess | FileIOPermissionAccess.Write;
- }
-
-#if FEATURE_MACL
- bool specifiedAcl;
- unsafe {
- specifiedAcl = secAttrs != null && secAttrs.pSecurityDescriptor != null;
- }
-
- AccessControlActions control = specifiedAcl ? AccessControlActions.Change : AccessControlActions.None;
- new FileIOPermission(secAccess, control, new String[] { filePath }, false, false).Demand();
-#else
-#if FEATURE_CORECLR
- if (checkHost) {
- FileSecurityState state = new FileSecurityState(FileSecurityState.ToFileSecurityState(secAccess), path, filePath);
- state.EnsureState();
- }
-#else
- new FileIOPermission(secAccess, new String[] { filePath }, false, false).Demand();
-#endif // FEATURE_CORECLR
-#endif
- }
-
- // 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;
-
- bool seekToEnd = (mode==FileMode.Append);
- // Must use a valid Win32 constant here...
- if (mode == FileMode.Append)
- mode = FileMode.OpenOrCreate;
-
- // WRT async IO, do the right thing for whatever platform we're on.
- // This way, someone can easily write code that opens a file
- // asynchronously no matter what their platform is.
- if ((options & FileOptions.Asynchronous) != 0)
- _isAsync = true;
- else
- options &= ~FileOptions.Asynchronous;
-
- int flagsAndAttributes = (int) options;
-
-#if !PLATFORM_UNIX
- // 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 |= (Win32Native.SECURITY_SQOS_PRESENT | Win32Native.SECURITY_ANONYMOUS);
-#endif
-
- // Don't pop up a dialog for reading from an emtpy floppy drive
- int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS);
- try {
- String tempPath = filePath;
- if (useLongPath)
- tempPath = Path.AddLongPathPrefix(tempPath);
- _handle = Win32Native.SafeCreateFile(tempPath, fAccess, share, secAttrs, mode, flagsAndAttributes, IntPtr.Zero);
-
- if (_handle.IsInvalid) {
- // Return a meaningful exception, using the RELATIVE path to
- // the file to avoid returning extra information to the caller
- // unless they have path discovery permission, in which case
- // the full path is fine & useful.
-
- // NT5 oddity - when trying to open "C:\" as a FileStream,
- // 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==__Error.ERROR_PATH_NOT_FOUND && filePath.Equals(Directory.InternalGetDirectoryRoot(filePath)))
- errorCode = __Error.ERROR_ACCESS_DENIED;
-
- // We need to give an exception, and preferably it would include
- // the fully qualified path name. Do security check here. If
- // we fail, give back the msgPath, which should not reveal much.
- // While this logic is largely duplicated in
- // __Error.WinIOError, we need this for
- // IsolatedStorageFileStream.
- bool canGiveFullPath = false;
-
- if (!bFromProxy)
- {
- try {
-#if !FEATURE_CORECLR
- new FileIOPermission(FileIOPermissionAccess.PathDiscovery, new String[] { _fileName }, false, false ).Demand();
-#endif
- canGiveFullPath = true;
- }
- catch(SecurityException) {}
- }
-
- if (canGiveFullPath)
- __Error.WinIOError(errorCode, _fileName);
- else
- __Error.WinIOError(errorCode, msgPath);
- }
- }
- finally {
- Win32Native.SetErrorMode(oldMode);
- }
-
- // Disallow access to all non-file devices from the FileStream
- // 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 = Win32Native.GetFileType(_handle);
- if (fileType != Win32Native.FILE_TYPE_DISK) {
- _handle.Close();
- throw new NotSupportedException(Environment.GetResourceString("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 (_isAsync) {
- bool b = false;
- // BindHandle requires UnmanagedCode permission
-#pragma warning disable 618
- new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
-#pragma warning restore 618
- try {
- b = ThreadPool.BindHandle(_handle);
- }
- finally {
- CodeAccessPermission.RevertAssert();
- if (!b) {
- // We should close the handle so that the handle is not open until SafeFileHandle GC
- Contract.Assert(!_exposedHandle, "Are we closing handle that we exposed/not own, how?");
- _handle.Close();
- }
- }
- if (!b)
- throw new IOException(Environment.GetResourceString("IO.IO_BindHandleFailed"));
- }
-
- if (!useRights) {
- _canRead = (access & FileAccess.Read) != 0;
- _canWrite = (access & FileAccess.Write) != 0;
- }
-#if FEATURE_MACL
- else {
- _canRead = (fileSystemRights & FileSystemRights.ReadData) != 0;
- _canWrite = ((fileSystemRights & FileSystemRights.WriteData) != 0)
- || ((fileSystemRights & FileSystemRights.AppendData) != 0);
- }
-#endif //FEATURE_MACL
-
- _canSeek = true;
- _isPipe = false;
- _pos = 0;
- _bufferSize = bufferSize;
- _readPos = 0;
- _readLen = 0;
- _writePos = 0;
-
- // For Append mode...
- if (seekToEnd) {
- _appendStart = SeekCore(0, SeekOrigin.End);
- }
- else {
- _appendStart = -1;
- }
- }
-
- [Obsolete("This constructor has been deprecated. Please use new FileStream(SafeFileHandle handle, FileAccess access) instead. http://go.microsoft.com/fwlink/?linkid=14202")]
- public FileStream(IntPtr handle, FileAccess access)
- : this(handle, access, true, DefaultBufferSize, false) {
- }
-
- [Obsolete("This constructor has been deprecated. Please use new FileStream(SafeFileHandle handle, FileAccess access) instead, and optionally make a new SafeFileHandle with ownsHandle=false if needed. http://go.microsoft.com/fwlink/?linkid=14202")]
- public FileStream(IntPtr handle, FileAccess access, bool ownsHandle)
- : this(handle, access, ownsHandle, DefaultBufferSize, false) {
- }
-
- [Obsolete("This constructor has been deprecated. Please use new FileStream(SafeFileHandle handle, FileAccess access, int bufferSize) instead, and optionally make a new SafeFileHandle with ownsHandle=false if needed. http://go.microsoft.com/fwlink/?linkid=14202")]
- public FileStream(IntPtr handle, FileAccess access, bool ownsHandle, int bufferSize)
- : this(handle, access, ownsHandle, bufferSize, false) {
- }
-
- // We explicitly do a Demand, not a LinkDemand here.
- [System.Security.SecuritySafeCritical] // auto-generated
- [Obsolete("This constructor has been deprecated. Please use new FileStream(SafeFileHandle handle, FileAccess access, int bufferSize, bool isAsync) instead, and optionally make a new SafeFileHandle with ownsHandle=false if needed. http://go.microsoft.com/fwlink/?linkid=14202")]
-#pragma warning disable 618
- [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)]
-#pragma warning restore 618
- public FileStream(IntPtr handle, FileAccess access, bool ownsHandle, int bufferSize, bool isAsync)
- : this(new SafeFileHandle(handle, ownsHandle), access, bufferSize, isAsync) {
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public FileStream(SafeFileHandle handle, FileAccess access)
- : this(handle, access, DefaultBufferSize, false) {
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public FileStream(SafeFileHandle handle, FileAccess access, int bufferSize)
- : this(handle, access, bufferSize, false) {
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
-#pragma warning disable 618
- [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)]
-#pragma warning restore 618
- public FileStream(SafeFileHandle handle, FileAccess access, int bufferSize, bool isAsync) {
- // To ensure we don't leak a handle, put it in a SafeFileHandle first
- if (handle.IsInvalid)
- throw new ArgumentException(Environment.GetResourceString("Arg_InvalidHandle"), "handle");
- Contract.EndContractBlock();
-
- _handle = handle;
- _exposedHandle = true;
-
- // Now validate arguments.
- if (access < FileAccess.Read || access > FileAccess.ReadWrite)
- throw new ArgumentOutOfRangeException("access", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
- if (bufferSize <= 0)
- throw new ArgumentOutOfRangeException("bufferSize", Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
-
- int handleType = Win32Native.GetFileType(_handle);
- Contract.Assert(handleType == Win32Native.FILE_TYPE_DISK || handleType == Win32Native.FILE_TYPE_PIPE || handleType == Win32Native.FILE_TYPE_CHAR, "FileStream was passed an unknown file type!");
- _isAsync = isAsync;
- _canRead = 0 != (access & FileAccess.Read);
- _canWrite = 0 != (access & FileAccess.Write);
- _canSeek = handleType == Win32Native.FILE_TYPE_DISK;
- _bufferSize = bufferSize;
- _readPos = 0;
- _readLen = 0;
- _writePos = 0;
- _fileName = null;
- _isPipe = handleType == Win32Native.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 !FEATURE_CORECLR
- if (_isAsync) {
- bool b = false;
- try {
- b = ThreadPool.BindHandle(_handle);
- }
- catch (ApplicationException) {
- // If you passed in a synchronous handle and told us to use
- // it asynchronously, throw here.
- throw new ArgumentException(Environment.GetResourceString("Arg_HandleNotAsync"));
- }
- if (!b) {
- throw new IOException(Environment.GetResourceString("IO.IO_BindHandleFailed"));
- }
- }
- else {
-#endif // FEATURE_CORECLR
- if (handleType != Win32Native.FILE_TYPE_PIPE)
- VerifyHandleIsSync();
-#if !FEATURE_CORECLR
- }
-#endif // FEATURE_CORECLR
-
- if (_canSeek)
- SeekCore(0, SeekOrigin.Current);
- else
- _pos = 0;
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- private static Win32Native.SECURITY_ATTRIBUTES GetSecAttrs(FileShare share)
- {
- Win32Native.SECURITY_ATTRIBUTES secAttrs = null;
- if ((share & FileShare.Inheritable) != 0) {
- secAttrs = new Win32Native.SECURITY_ATTRIBUTES();
- secAttrs.nLength = (int)Marshal.SizeOf(secAttrs);
-
- secAttrs.bInheritHandle = 1;
- }
- return secAttrs;
- }
-
-#if FEATURE_MACL
- // If pinningHandle is not null, caller must free it AFTER the call to
- // CreateFile has returned.
- [System.Security.SecuritySafeCritical] // auto-generated
- private unsafe static Win32Native.SECURITY_ATTRIBUTES GetSecAttrs(FileShare share, FileSecurity fileSecurity, out Object pinningHandle)
- {
- pinningHandle = null;
- Win32Native.SECURITY_ATTRIBUTES secAttrs = null;
- if ((share & FileShare.Inheritable) != 0 || fileSecurity != null) {
- secAttrs = new Win32Native.SECURITY_ATTRIBUTES();
- secAttrs.nLength = (int)Marshal.SizeOf(secAttrs);
-
- if ((share & FileShare.Inheritable) != 0) {
- secAttrs.bInheritHandle = 1;
- }
-
- // For ACL's, get the security descriptor from the FileSecurity.
- if (fileSecurity != null) {
- byte[] sd = fileSecurity.GetSecurityDescriptorBinaryForm();
- pinningHandle = GCHandle.Alloc(sd, GCHandleType.Pinned);
- fixed(byte* pSecDescriptor = sd)
- secAttrs.pSecurityDescriptor = pSecDescriptor;
- }
- }
- return secAttrs;
- }
-#endif
-
- // Verifies that this handle supports synchronous IO operations (unless you
- // didn't open it for either reading or writing).
- [System.Security.SecuritySafeCritical] // auto-generated
- private unsafe void VerifyHandleIsSync()
- {
- // 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
- // FileStream's thread).
-
- // Do NOT change this to use a byte[] of length 0, or test test won't
- // work. Our ReadFile & WriteFile methods are special cased to return
- // for arrays of length 0, since we'd get an IndexOutOfRangeException
- // while using C#'s fixed syntax.
- byte[] bytes = new byte[1];
- int hr = 0;
- int r = 0;
-
- // 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 (CanRead) {
- r = ReadFileNative(_handle, bytes, 0, 0, null, out hr);
- }
- else if (CanWrite) {
- r = WriteFileNative(_handle, bytes, 0, 0, null, out hr);
- }
-
- if (hr==ERROR_INVALID_PARAMETER)
- throw new ArgumentException(Environment.GetResourceString("Arg_HandleNotSync"));
- if (hr == Win32Native.ERROR_INVALID_HANDLE)
- __Error.WinIOError(hr, "<OS handle>");
- }
-
-
- public override bool CanRead {
- [Pure]
- get { return _canRead; }
- }
-
- public override bool CanWrite {
- [Pure]
- get { return _canWrite; }
- }
-
- public override bool CanSeek {
- [Pure]
- get { return _canSeek; }
- }
-
- public virtual bool IsAsync {
- get { return _isAsync; }
- }
-
- public override long Length {
- [System.Security.SecuritySafeCritical] // auto-generated
- get {
- if (_handle.IsClosed) __Error.FileNotOpen();
- if (!CanSeek) __Error.SeekNotSupported();
- int hi = 0, lo = 0;
-
- lo = Win32Native.GetFileSize(_handle, out hi);
-
- if (lo==-1) { // Check for either an error or a 4GB - 1 byte file.
- int hr = Marshal.GetLastWin32Error();
- if (hr != 0)
- __Error.WinIOError(hr, String.Empty);
- }
- long len = (((long)hi) << 32) | ((uint) lo);
- // 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 && _pos + _writePos > len)
- len = _writePos + _pos;
- return len;
- }
- }
-
- public String Name {
- [System.Security.SecuritySafeCritical]
- get {
- if (_fileName == null)
- return Environment.GetResourceString("IO_UnknownFileName");
-#if FEATURE_CORECLR
- FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, _fileName);
- sourceState.EnsureState();
-#else
- new FileIOPermission(FileIOPermissionAccess.PathDiscovery, new String[] { _fileName }, false, false).Demand();
-#endif
- return _fileName;
- }
- }
-
- internal String NameInternal {
- get {
- if (_fileName == null)
- return "<UnknownFileName>";
- return _fileName;
- }
- }
-
- public override long Position {
- [System.Security.SecuritySafeCritical] // auto-generated
- get {
- if (_handle.IsClosed) __Error.FileNotOpen();
- if (!CanSeek) __Error.SeekNotSupported();
-
- Contract.Assert((_readPos == 0 && _readLen == 0 && _writePos >= 0) || (_writePos == 0 && _readPos <= _readLen), "We're either reading or writing, but not both.");
-
- // Verify that internal position is in sync with the handle
- if (_exposedHandle)
- VerifyOSHandlePosition();
-
- // Compensate for buffer that we read from the handle (_readLen) Vs what the user
- // read so far from the internel buffer (_readPos). Of course add any unwrittern
- // buffered data
- return _pos + (_readPos - _readLen + _writePos);
- }
- set {
- if (value < 0) throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
- if (_writePos > 0) FlushWrite(false);
- _readPos = 0;
- _readLen = 0;
- Seek(value, SeekOrigin.Begin);
- }
- }
-
-#if FEATURE_MACL
- [System.Security.SecuritySafeCritical] // auto-generated
- public FileSecurity GetAccessControl()
- {
- if (_handle.IsClosed) __Error.FileNotOpen();
- return new FileSecurity(_handle, _fileName, AccessControlSections.Access | AccessControlSections.Owner | AccessControlSections.Group);
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public void SetAccessControl(FileSecurity fileSecurity)
- {
- if (fileSecurity == null)
- throw new ArgumentNullException("fileSecurity");
- Contract.EndContractBlock();
-
- if (_handle.IsClosed) __Error.FileNotOpen();
-
- fileSecurity.Persist(_handle, _fileName);
- }
-#endif
-
- [System.Security.SecuritySafeCritical] // auto-generated
- 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 FileStream, which would often "just work" when
- // finalized.
- try {
- if (_handle != null && !_handle.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) {
- FlushWrite(!disposing);
- }
- }
- }
- finally {
- if (_handle != null && !_handle.IsClosed)
- _handle.Dispose();
-
- _canRead = false;
- _canWrite = false;
- _canSeek = false;
- // Don't set the buffer to null, to avoid a NullReferenceException
- // when users have a race condition in their code (ie, they call
- // Close when calling another method on Stream like Read).
- //_buffer = null;
- base.Dispose(disposing);
- }
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- ~FileStream()
- {
- if (_handle != null) {
- BCLDebug.Correctness(_handle.IsClosed, "You didn't close a FileStream & it got finalized. Name: \""+_fileName+"\"");
- Dispose(false);
- }
- }
-
- public override void Flush()
- {
- Flush(false);
- }
-
- [System.Security.SecuritySafeCritical]
- public virtual void Flush(Boolean flushToDisk)
- {
- // This code is duplicated in Dispose
- if (_handle.IsClosed) __Error.FileNotOpen();
-
- FlushInternalBuffer();
-
- if (flushToDisk && CanWrite)
- {
- FlushOSBuffer();
- }
- }
-
- private void FlushInternalBuffer()
- {
- if (_writePos > 0)
- {
- FlushWrite(false);
- }
- else if (_readPos < _readLen && CanSeek)
- {
- FlushRead();
- }
- }
-
- [System.Security.SecuritySafeCritical]
- private void FlushOSBuffer()
- {
- if (!Win32Native.FlushFileBuffers(_handle))
- {
- __Error.WinIOError();
- }
- }
-
- // Reading is done by blocks from the file, but someone could read
- // 1 byte from the buffer then write. At that point, the OS's file
- // pointer is out of sync with the stream's position. All write
- // functions should call this function to preserve the position in the file.
- private void FlushRead() {
- Contract.Assert(_writePos == 0, "FileStream: Write buffer must be empty in FlushRead!");
- if (_readPos - _readLen != 0) {
- Contract.Assert(CanSeek, "FileStream will lose buffered read data now.");
- SeekCore(_readPos - _readLen, SeekOrigin.Current);
- }
- _readPos = 0;
- _readLen = 0;
- }
-
- // 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 FlushWrite(bool calledFromFinalizer) {
- Contract.Assert(_readPos == 0 && _readLen == 0, "FileStream: Read buffer must be empty in FlushWrite!");
-
- if (_isAsync) {
- IAsyncResult asyncResult = BeginWriteCore(_buffer, 0, _writePos, null, null);
- // 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 do'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)
- EndWrite(asyncResult);
- }
- else
- WriteCore(_buffer, 0, _writePos);
-
- _writePos = 0;
- }
-
-
- [Obsolete("This property has been deprecated. Please use FileStream's SafeFileHandle property instead. http://go.microsoft.com/fwlink/?linkid=14202")]
- public virtual IntPtr Handle {
- [System.Security.SecurityCritical] // auto-generated_required
-#if !FEATURE_CORECLR
- [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
-#endif
- get {
- Flush();
- // Explicitly dump any buffered data, since the user could move our
- // position or write to the file.
- _readPos = 0;
- _readLen = 0;
- _writePos = 0;
- _exposedHandle = true;
-
- return _handle.DangerousGetHandle();
- }
- }
-
- public virtual SafeFileHandle SafeFileHandle {
- [System.Security.SecurityCritical] // auto-generated_required
-#if !FEATURE_CORECLR
- [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
-#endif
- get {
- Flush();
- // Explicitly dump any buffered data, since the user could move our
- // position or write to the file.
- _readPos = 0;
- _readLen = 0;
- _writePos = 0;
- _exposedHandle = true;
-
- return _handle;
- }
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override void SetLength(long value)
- {
- if (value < 0)
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- if (_handle.IsClosed) __Error.FileNotOpen();
- if (!CanSeek) __Error.SeekNotSupported();
- if (!CanWrite) __Error.WriteNotSupported();
-
- // Handle buffering updates.
- if (_writePos > 0) {
- FlushWrite(false);
- }
- else if (_readPos < _readLen) {
- FlushRead();
- }
- _readPos = 0;
- _readLen = 0;
-
- if (_appendStart != -1 && value < _appendStart)
- throw new IOException(Environment.GetResourceString("IO.IO_SetLengthAppendTruncate"));
- SetLengthCore(value);
- }
-
- // We absolutely need this method broken out so that BeginWriteCore can call
- // a method without having to go through buffering code that might call
- // FlushWrite.
- [System.Security.SecuritySafeCritical] // auto-generated
- private void SetLengthCore(long value)
- {
- Contract.Assert(value >= 0, "value >= 0");
- long origPos = _pos;
-
- if (_exposedHandle)
- VerifyOSHandlePosition();
- if (_pos != value)
- SeekCore(value, SeekOrigin.Begin);
- if (!Win32Native.SetEndOfFile(_handle)) {
- int hr = Marshal.GetLastWin32Error();
- if (hr==__Error.ERROR_INVALID_PARAMETER)
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_FileLengthTooBig"));
- __Error.WinIOError(hr, String.Empty);
- }
- // 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);
- }
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override int Read([In, Out] byte[] array, int offset, int count) {
- if (array==null)
- throw new ArgumentNullException("array", Environment.GetResourceString("ArgumentNull_Buffer"));
- if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (array.Length - offset < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
- Contract.EndContractBlock();
-
- if (_handle.IsClosed) __Error.FileNotOpen();
-
- Contract.Assert((_readPos==0 && _readLen==0 && _writePos >= 0) || (_writePos==0 && _readPos <= _readLen), "We're either reading or writing, but not both.");
-
- bool isBlocked = false;
- int n = _readLen - _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) __Error.ReadNotSupported();
- if (_writePos > 0) FlushWrite(false);
- if (!CanSeek || (count >= _bufferSize)) {
- n = ReadCore(array, offset, count);
- // Throw away read buffer.
- _readPos = 0;
- _readLen = 0;
- return n;
- }
- if (_buffer == null) _buffer = new byte[_bufferSize];
- n = ReadCore(_buffer, 0, _bufferSize);
- if (n == 0) return 0;
- isBlocked = n < _bufferSize;
- _readPos = 0;
- _readLen = n;
- }
- // Now copy min of count or numBytesAvailable (ie, near EOF) to array.
- if (n > count) n = count;
- Buffer.InternalBlockCopy(_buffer, _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 (ie, we're
- // probably blocked), don't ask for more bytes.
- if (n < count && !isBlocked) {
- Contract.Assert(_readPos == _readLen, "Read buffer should be empty!");
- int moreBytesRead = ReadCore(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;
- _readLen = 0;
- }
- }
-
- return n;
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- private unsafe int ReadCore(byte[] buffer, int offset, int count) {
- Contract.Assert(!_handle.IsClosed, "!_handle.IsClosed");
- Contract.Assert(CanRead, "CanRead");
-
- Contract.Assert(buffer != null, "buffer != null");
- Contract.Assert(_writePos == 0, "_writePos == 0");
- Contract.Assert(offset >= 0, "offset is negative");
- Contract.Assert(count >= 0, "count is negative");
-
- if (_isAsync) {
- IAsyncResult result = BeginReadCore(buffer, offset, count, null, null, 0);
- return EndRead(result);
- }
-
- // Make sure we are reading from the right spot
- if (_exposedHandle)
- VerifyOSHandlePosition();
-
- int hr = 0;
- int r = ReadFileNative(_handle, buffer, offset, count, null, out hr);
- if (r == -1) {
- // For pipes, ERROR_BROKEN_PIPE is the normal end of the pipe.
- if (hr == ERROR_BROKEN_PIPE) {
- r = 0;
- }
- else {
- if (hr == ERROR_INVALID_PARAMETER)
- throw new ArgumentException(Environment.GetResourceString("Arg_HandleNotSync"));
-
- __Error.WinIOError(hr, String.Empty);
- }
- }
- Contract.Assert(r >= 0, "FileStream's ReadCore is likely broken.");
- _pos += r;
-
- return r;
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override long Seek(long offset, SeekOrigin origin) {
- if (origin<SeekOrigin.Begin || origin>SeekOrigin.End)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidSeekOrigin"));
- Contract.EndContractBlock();
- if (_handle.IsClosed) __Error.FileNotOpen();
- if (!CanSeek) __Error.SeekNotSupported();
-
- Contract.Assert((_readPos==0 && _readLen==0 && _writePos >= 0) || (_writePos==0 && _readPos <= _readLen), "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) {
- FlushWrite(false);
- }
- 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 -= (_readLen - _readPos);
- }
-
- // Verify that internal position is in sync with the handle
- if (_exposedHandle)
- VerifyOSHandlePosition();
-
- long oldPos = _pos + (_readPos - _readLen);
- 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(Environment.GetResourceString("IO.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 (_readLen > 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.InternalBlockCopy(_buffer, _readPos, _buffer, 0, _readLen - _readPos);
- _readLen -= _readPos;
- _readPos = 0;
- }
- // If we still have buffered data, we must update the stream's
- // position so our Position property is correct.
- if (_readLen > 0)
- SeekCore(_readLen, SeekOrigin.Current);
- }
- else if (oldPos - _readPos < pos && pos < oldPos + _readLen - _readPos) {
- int diff = (int)(pos - oldPos);
- //Console.WriteLine("Seek: diff was "+diff+", readpos was "+_readPos+" adjusting buffer - shrinking by "+ (_readPos + diff));
- Buffer.InternalBlockCopy(_buffer, _readPos+diff, _buffer, 0, _readLen - (_readPos + diff));
- _readLen -= (_readPos + diff);
- _readPos = 0;
- if (_readLen > 0)
- SeekCore(_readLen, SeekOrigin.Current);
- }
- else {
- // Lose the read buffer.
- _readPos = 0;
- _readLen = 0;
- }
- Contract.Assert(_readLen >= 0 && _readPos <= _readLen, "_readLen should be nonnegative, and _readPos should be less than or equal _readLen");
- Contract.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
- [System.Security.SecuritySafeCritical] // auto-generated
- private long SeekCore(long offset, SeekOrigin origin) {
- Contract.Assert(!_handle.IsClosed && CanSeek, "!_handle.IsClosed && CanSeek");
- Contract.Assert(origin>=SeekOrigin.Begin && origin<=SeekOrigin.End, "origin>=SeekOrigin.Begin && origin<=SeekOrigin.End");
- int hr = 0;
- long ret = 0;
-
- ret = Win32Native.SetFilePointer(_handle, offset, origin, out hr);
- if (ret == -1) {
- // #errorInvalidHandle
- // 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 FileStream
- // 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 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 (hr == Win32Native.ERROR_INVALID_HANDLE)
- _handle.Dispose();
- __Error.WinIOError(hr, String.Empty);
- }
-
- _pos = ret;
- return ret;
- }
-
- // Checks the position of the OS's handle equals what we expect it to.
- // This will fail if someone else moved the FileStream's handle or if
- // we've hit a bug in FileStream's position updating code.
- private void VerifyOSHandlePosition()
- {
- if (!CanSeek)
- return;
-
- // SeekCore will override the current _pos, so save it now
- long oldPos = _pos;
- long curPos = SeekCore(0, SeekOrigin.Current);
-
- if (curPos != oldPos) {
- // For reads, this is non-fatal but we still could have returned corrupted
- // data in some cases. So discard the internal buffer. Potential MDA
- _readPos = 0;
- _readLen = 0;
- if(_writePos > 0) {
- // Discard the buffer and let the user know!
- _writePos = 0;
- throw new IOException(Environment.GetResourceString("IO.IO_FileStreamHandlePosition"));
- }
- }
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override void Write(byte[] array, int offset, int count) {
- if (array==null)
- throw new ArgumentNullException("array", Environment.GetResourceString("ArgumentNull_Buffer"));
- if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (array.Length - offset < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
- Contract.EndContractBlock();
-
- if (_handle.IsClosed) __Error.FileNotOpen();
-
- if (_writePos == 0)
- {
- // Ensure we can write to the stream, and ready buffer for writing.
- if (!CanWrite) __Error.WriteNotSupported();
- if (_readPos < _readLen) FlushRead();
- _readPos = 0;
- _readLen = 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 (ie, write 1 byte, then write for the buffer
- // size repeatedly)
- if (_writePos > 0) {
- int numBytes = _bufferSize - _writePos; // space left in buffer
- if (numBytes > 0) {
- if (numBytes > count)
- numBytes = count;
- Buffer.InternalBlockCopy(array, offset, _buffer, _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 (_isAsync) {
- IAsyncResult result = BeginWriteCore(_buffer, 0, _writePos, null, null);
- EndWrite(result);
- }
- else
- {
- WriteCore(_buffer, 0, _writePos);
- }
-
- _writePos = 0;
- }
- // If the buffer would slow writes down, avoid buffer completely.
- if (count >= _bufferSize) {
- Contract.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.
- if (_buffer==null) _buffer = new byte[_bufferSize];
- // Copy remaining bytes into buffer, to write at a later date.
- Buffer.InternalBlockCopy(array, offset, _buffer, _writePos, count);
- _writePos = count;
- return;
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- private unsafe void WriteCore(byte[] buffer, int offset, int count) {
- Contract.Assert(!_handle.IsClosed, "!_handle.IsClosed");
- Contract.Assert(CanWrite, "CanWrite");
-
- Contract.Assert(buffer != null, "buffer != null");
- Contract.Assert(_readPos == _readLen, "_readPos == _readLen");
- Contract.Assert(offset >= 0, "offset is negative");
- Contract.Assert(count >= 0, "count is negative");
-
- if (_isAsync) {
- IAsyncResult result = BeginWriteCore(buffer, offset, count, null, null);
- EndWrite(result);
- return;
- }
-
- // Make sure we are writing to the position that we think we are
- if (_exposedHandle)
- VerifyOSHandlePosition();
-
- int hr = 0;
- int r = WriteFileNative(_handle, buffer, offset, count, null, out hr);
- if (r == -1) {
- // For pipes, ERROR_NO_DATA is not an error, but the pipe is closing.
- if (hr == ERROR_NO_DATA) {
- r = 0;
- }
- else {
- // ERROR_INVALID_PARAMETER may be returned for writes
- // where the position is too large (ie, writing at Int64.MaxValue
- // on Win9x) OR for synchronous writes to a handle opened
- // asynchronously.
- if (hr == ERROR_INVALID_PARAMETER)
- throw new IOException(Environment.GetResourceString("IO.IO_FileTooLongOrHandleNotSync"));
- __Error.WinIOError(hr, String.Empty);
- }
- }
- Contract.Assert(r >= 0, "FileStream's WriteCore is likely broken.");
- _pos += r;
- return;
- }
-
-
- [System.Security.SecuritySafeCritical] // auto-generated
- [HostProtection(ExternalThreading = true)]
- public override IAsyncResult BeginRead(byte[] array, int offset, int numBytes, AsyncCallback userCallback, Object stateObject)
- {
- if (array==null)
- throw new ArgumentNullException("array");
- if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (numBytes < 0)
- throw new ArgumentOutOfRangeException("numBytes", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (array.Length - offset < numBytes)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
- Contract.EndContractBlock();
-
- if (_handle.IsClosed) __Error.FileNotOpen();
-
- if (!_isAsync)
- return base.BeginRead(array, offset, numBytes, userCallback, stateObject);
- else
- return BeginReadAsync(array, offset, numBytes, userCallback, stateObject);
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- [HostProtection(ExternalThreading = true)]
- private FileStreamAsyncResult BeginReadAsync(byte[] array, int offset, int numBytes, AsyncCallback userCallback, Object stateObject)
- {
- Contract.Assert(_isAsync);
-
- if (!CanRead) __Error.ReadNotSupported();
-
- Contract.Assert((_readPos == 0 && _readLen == 0 && _writePos >= 0) || (_writePos == 0 && _readPos <= _readLen), "We're either reading or writing, but not both.");
-
- if (_isPipe)
- {
- // 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
- // FileStream's BeginRead 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 < _readLen)
- {
- int n = _readLen - _readPos;
- if (n > numBytes) n = numBytes;
- Buffer.InternalBlockCopy(_buffer, _readPos, array, offset, n);
- _readPos += n;
-
- // Return a synchronous FileStreamAsyncResult
- return FileStreamAsyncResult.CreateBufferedReadResult(n, userCallback, stateObject, false);
- }
- else
- {
- Contract.Assert(_writePos == 0, "FileStream must not have buffered write data here! Pipes should be unidirectional.");
- return BeginReadCore(array, offset, numBytes, userCallback, stateObject, 0);
- }
- }
-
- Contract.Assert(!_isPipe, "Should not be a pipe.");
-
- // Handle buffering.
- if (_writePos > 0) FlushWrite(false);
- if (_readPos == _readLen)
- {
- // 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 < _bufferSize)
- {
- if (_buffer == null) _buffer = new byte[_bufferSize];
- IAsyncResult bufferRead = BeginReadCore(_buffer, 0, _bufferSize, null, null, 0);
- _readLen = EndRead(bufferRead);
- int n = _readLen;
- if (n > numBytes) n = numBytes;
- Buffer.InternalBlockCopy(_buffer, 0, array, offset, n);
- _readPos = n;
-
- // Return a synchronous FileStreamAsyncResult
- return FileStreamAsyncResult.CreateBufferedReadResult(n, userCallback, stateObject, false);
- }
- else
- {
- // Here we're making our position pointer inconsistent
- // with our read buffer. Throw away the read buffer's contents.
- _readPos = 0;
- _readLen = 0;
- return BeginReadCore(array, offset, numBytes, userCallback, stateObject, 0);
- }
- }
- else
- {
- int n = _readLen - _readPos;
- if (n > numBytes) n = numBytes;
- Buffer.InternalBlockCopy(_buffer, _readPos, array, offset, n);
- _readPos += n;
-
- if (n >= numBytes)
- {
- // Return a synchronous FileStreamAsyncResult
- return FileStreamAsyncResult.CreateBufferedReadResult(n, userCallback, stateObject, false);
- }
- 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;
- _readLen = 0;
- return BeginReadCore(array, offset + n, numBytes - n, userCallback, stateObject, n);
- }
- // WARNING: all state on asyncResult objects must be set before
- // we call ReadFile in BeginReadCore, since the OS can run our
- // callback & the user's callback before ReadFile returns.
- }
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- unsafe private FileStreamAsyncResult BeginReadCore(byte[] bytes, int offset, int numBytes, AsyncCallback userCallback, Object stateObject, int numBufferedBytesRead)
- {
- Contract.Assert(!_handle.IsClosed, "!_handle.IsClosed");
- Contract.Assert(CanRead, "CanRead");
- Contract.Assert(bytes != null, "bytes != null");
- Contract.Assert(_writePos == 0, "_writePos == 0");
- Contract.Assert(_isAsync, "BeginReadCore doesn't work on synchronous file streams!");
- Contract.Assert(offset >= 0, "offset is negative");
- Contract.Assert(numBytes >= 0, "numBytes is negative");
-
- // Create and store async stream class library specific data in the async result
-
- // Must pass in _numBufferedBytes here to ensure all the state on the IAsyncResult
- // object is set before we call ReadFile, which gives the OS an
- // opportunity to run our callback (including the user callback &
- // the call to EndRead) before ReadFile has returned.
- FileStreamAsyncResult asyncResult = new FileStreamAsyncResult(numBufferedBytesRead, bytes, _handle, userCallback, stateObject, false);
- NativeOverlapped* intOverlapped = asyncResult.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
- if (_exposedHandle)
- VerifyOSHandlePosition();
-
- if (_pos + numBytes > len) {
- if (_pos <= len)
- numBytes = (int) (len - _pos);
- 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)_pos);
- intOverlapped->OffsetHigh = (int)(_pos>>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);
- }
-
- if (FrameworkEventSource.IsInitialized && FrameworkEventSource.Log.IsEnabled(EventLevel.Informational, FrameworkEventSource.Keywords.ThreadTransfer))
- FrameworkEventSource.Log.ThreadTransferSend((long)(asyncResult.OverLapped), 2, string.Empty, false);
-
- // queue an async ReadFile operation and pass in a packed overlapped
- int hr = 0;
- int r = ReadFileNative(_handle, bytes, offset, numBytes, intOverlapped, out hr);
- // 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/ hr==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 (hr == 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;
- asyncResult.CallUserCallback();
- // EndRead will free the Overlapped struct correctly.
- }
- else if (hr != ERROR_IO_PENDING) {
- if (!_handle.IsClosed && CanSeek) // Update Position - It could be anywhere.
- SeekCore(0, SeekOrigin.Current);
-
- if (hr == ERROR_HANDLE_EOF)
- __Error.EndOfFile();
- else
- __Error.WinIOError(hr, String.Empty);
- }
- }
- 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 asyncResult;
- }
-
- [System.Security.SecuritySafeCritical] // Although the unsafe code is only required in PAL, the block is wide scoped. Leave it here for desktop to ensure it's reviewed.
- public unsafe override int EndRead(IAsyncResult asyncResult)
- {
- // There are 3 significantly different IAsyncResults we'll accept
- // here. One is from Stream::BeginRead. The other two are variations
- // on our FileStreamAsyncResult. One is from BeginReadCore,
- // while the other is from the BeginRead buffering wrapper.
- if (asyncResult==null)
- throw new ArgumentNullException("asyncResult");
- Contract.EndContractBlock();
-
- if (!_isAsync)
- return base.EndRead(asyncResult);
-
- FileStreamAsyncResult afsar = asyncResult as FileStreamAsyncResult;
- if (afsar==null || afsar.IsWrite)
- __Error.WrongAsyncResult();
-
- // Ensure we don't have any race conditions by doing an interlocked
- // CompareExchange here. Avoids corrupting memory via freeing the
- // NativeOverlapped class or GCHandle twice. --
- if (1 == Interlocked.CompareExchange(ref afsar._EndXxxCalled, 1, 0))
- __Error.EndReadCalledTwice();
-
- // Obtain the WaitHandle, but don't use public property in case we
- // delay initialize the manual reset event in the future.
- afsar.Wait();
-
- // Free memory & GC handles.
- afsar.ReleaseNativeResource();
-
- // Now check for any error during the read.
- if (afsar.ErrorCode != 0)
- __Error.WinIOError(afsar.ErrorCode, String.Empty);
-
- return afsar.NumBytesRead;
- }
-
- // Reads a byte from the file stream. Returns the byte cast to an int
- // or -1 if reading from the end of the stream.
- [System.Security.SecuritySafeCritical] // auto-generated
- public override int ReadByte() {
- if (_handle.IsClosed) __Error.FileNotOpen();
- if (_readLen==0 && !CanRead) __Error.ReadNotSupported();
- Contract.Assert((_readPos==0 && _readLen==0 && _writePos >= 0) || (_writePos==0 && _readPos <= _readLen), "We're either reading or writing, but not both.");
- if (_readPos == _readLen) {
- if (_writePos > 0) FlushWrite(false);
- Contract.Assert(_bufferSize > 0, "_bufferSize > 0");
- if (_buffer == null) _buffer = new byte[_bufferSize];
- _readLen = ReadCore(_buffer, 0, _bufferSize);
- _readPos = 0;
- }
- if (_readPos == _readLen)
- return -1;
-
- int result = _buffer[_readPos];
- _readPos++;
- return result;
- }
-
-
- [System.Security.SecuritySafeCritical] // auto-generated
- [HostProtection(ExternalThreading=true)]
- public override IAsyncResult BeginWrite(byte[] array, int offset, int numBytes, AsyncCallback userCallback, Object stateObject)
- {
- if (array==null)
- throw new ArgumentNullException("array");
- if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (numBytes < 0)
- throw new ArgumentOutOfRangeException("numBytes", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (array.Length - offset < numBytes)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
- Contract.EndContractBlock();
-
- if (_handle.IsClosed) __Error.FileNotOpen();
-
- if (!_isAsync)
- return base.BeginWrite(array, offset, numBytes, userCallback, stateObject);
- else
- return BeginWriteAsync(array, offset, numBytes, userCallback, stateObject);
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- [HostProtection(ExternalThreading = true)]
- private FileStreamAsyncResult BeginWriteAsync(byte[] array, int offset, int numBytes, AsyncCallback userCallback, Object stateObject)
- {
- Contract.Assert(_isAsync);
-
- if (!CanWrite) __Error.WriteNotSupported();
-
- Contract.Assert((_readPos == 0 && _readLen == 0 && _writePos >= 0) || (_writePos == 0 && _readPos <= _readLen), "We're either reading or writing, but not both.");
-
- if (_isPipe)
- {
- // 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
- // FileStream's BeginRead 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.
- Contract.Assert(_readPos == 0 && _readLen == 0, "FileStream must not have buffered data here! Pipes should be unidirectional.");
-
- if (_writePos > 0)
- FlushWrite(false);
-
- return BeginWriteCore(array, offset, numBytes, userCallback, stateObject);
- }
-
- // Handle buffering.
- if (_writePos == 0)
- {
- if (_readPos < _readLen) FlushRead();
- _readPos = 0;
- _readLen = 0;
- }
-
- int n = _bufferSize - _writePos;
- if (numBytes <= n)
- {
- if (_writePos == 0) _buffer = new byte[_bufferSize];
- Buffer.InternalBlockCopy(array, offset, _buffer, _writePos, numBytes);
- _writePos += numBytes;
-
- // Return a synchronous FileStreamAsyncResult
- return FileStreamAsyncResult.CreateBufferedReadResult(numBytes, userCallback, stateObject, true);
- }
-
- if (_writePos > 0)
- FlushWrite(false);
-
- return BeginWriteCore(array, offset, numBytes, userCallback, stateObject);
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- unsafe private FileStreamAsyncResult BeginWriteCore(byte[] bytes, int offset, int numBytes, AsyncCallback userCallback, Object stateObject)
- {
- Contract.Assert(!_handle.IsClosed, "!_handle.IsClosed");
- Contract.Assert(CanWrite, "CanWrite");
- Contract.Assert(bytes != null, "bytes != null");
- Contract.Assert(_readPos == _readLen, "_readPos == _readLen");
- Contract.Assert(_isAsync, "BeginWriteCore doesn't work on synchronous file streams!");
- Contract.Assert(offset >= 0, "offset is negative");
- Contract.Assert(numBytes >= 0, "numBytes is negative");
-
- // Create and store async stream class library specific data in the async result
- FileStreamAsyncResult asyncResult = new FileStreamAsyncResult(0, bytes, _handle, userCallback, stateObject, true);
- NativeOverlapped* intOverlapped = asyncResult.OverLapped;
-
- if (CanSeek) {
- // Make sure we set the length of the file appropriately.
- long len = Length;
- //Console.WriteLine("BeginWrite - Calculating end pos. pos: "+pos+" len: "+len+" numBytes: "+numBytes);
-
- // Make sure we are writing to the position that we think we are
- if (_exposedHandle)
- VerifyOSHandlePosition();
-
- if (_pos + numBytes > len) {
- //Console.WriteLine("BeginWrite - Setting length to: "+(pos + numBytes));
- SetLengthCore(_pos + 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)_pos;
- intOverlapped->OffsetHigh = (int)(_pos>>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("BeginWrite finishing. pos: "+pos+" numBytes: "+numBytes+" _pos: "+_pos+" Position: "+Position);
-
- if (FrameworkEventSource.IsInitialized && FrameworkEventSource.Log.IsEnabled(EventLevel.Informational, FrameworkEventSource.Keywords.ThreadTransfer))
- FrameworkEventSource.Log.ThreadTransferSend((long)(asyncResult.OverLapped), 2, string.Empty, false);
-
- int hr = 0;
- // queue an async WriteFile operation and pass in a packed overlapped
- int r = WriteFileNative(_handle, bytes, offset, numBytes, intOverlapped, out hr);
-
- // 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/ hr==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 hr==3e5) hr: 0x{0:x}", hr);
-
- // For pipes, when they are closed on the other side, they will come here.
- if (hr == ERROR_NO_DATA) {
- // Not an error, but EOF. AsyncFSCallback will NOT be
- // called. Call the user callback here.
- asyncResult.CallUserCallback();
- // EndWrite will free the Overlapped struct correctly.
- }
- else if (hr != ERROR_IO_PENDING) {
- if (!_handle.IsClosed && CanSeek) // Update Position - It could be anywhere.
- SeekCore(0, SeekOrigin.Current);
-
- if (hr == ERROR_HANDLE_EOF)
- __Error.EndOfFile();
- else
- __Error.WinIOError(hr, String.Empty);
- }
- }
- 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 asyncResult;
- }
-
- [System.Security.SecuritySafeCritical] // Although the unsafe code is only required in PAL, the block is wide scoped. Leave it here for desktop to ensure it's reviewed.
- public unsafe override void EndWrite(IAsyncResult asyncResult)
- {
- if (asyncResult==null)
- throw new ArgumentNullException("asyncResult");
- Contract.EndContractBlock();
-
- if (!_isAsync) {
- base.EndWrite(asyncResult);
- return;
- }
-
- FileStreamAsyncResult afsar = asyncResult as FileStreamAsyncResult;
- if (afsar==null || !afsar.IsWrite)
- __Error.WrongAsyncResult();
-
- // Ensure we can't have any race conditions by doing an interlocked
- // CompareExchange here. Avoids corrupting memory via freeing the
- // NativeOverlapped class or GCHandle twice. --
- if (1 == Interlocked.CompareExchange(ref afsar._EndXxxCalled, 1, 0))
- __Error.EndWriteCalledTwice();
-
- // Obtain the WaitHandle, but don't use public property in case we
- // delay initialize the manual reset event in the future.
- afsar.Wait();
-
- // Free memory & GC handles.
- afsar.ReleaseNativeResource();
-
- // Now check for any error during the write.
- if (afsar.ErrorCode != 0)
- __Error.WinIOError(afsar.ErrorCode, String.Empty);
-
- // Number of bytes written is afsar._numBytes + afsar._numBufferedBytes.
- return;
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override void WriteByte(byte value)
- {
- if (_handle.IsClosed) __Error.FileNotOpen();
- if (_writePos==0) {
- if (!CanWrite) __Error.WriteNotSupported();
- if (_readPos < _readLen) FlushRead();
- _readPos = 0;
- _readLen = 0;
- Contract.Assert(_bufferSize > 0, "_bufferSize > 0");
- if (_buffer==null) _buffer = new byte[_bufferSize];
- }
- if (_writePos == _bufferSize)
- FlushWrite(false);
-
- _buffer[_writePos] = value;
- _writePos++;
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public virtual void Lock(long position, long length) {
- if (position < 0 || length < 0)
- throw new ArgumentOutOfRangeException((position < 0 ? "position" : "length"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
- if (_handle.IsClosed) __Error.FileNotOpen();
-
- int positionLow = unchecked((int)(position ));
- int positionHigh = unchecked((int)(position >> 32));
- int lengthLow = unchecked((int)(length ));
- int lengthHigh = unchecked((int)(length >> 32));
-
- if (!Win32Native.LockFile(_handle, positionLow, positionHigh, lengthLow, lengthHigh))
- __Error.WinIOError();
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public virtual void Unlock(long position, long length) {
- if (position < 0 || length < 0)
- throw new ArgumentOutOfRangeException((position < 0 ? "position" : "length"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
- if (_handle.IsClosed) __Error.FileNotOpen();
-
- int positionLow = unchecked((int)(position ));
- int positionHigh = unchecked((int)(position >> 32));
- int lengthLow = unchecked((int)(length ));
- int lengthHigh = unchecked((int)(length >> 32));
-
- if (!Win32Native.UnlockFile(_handle, positionLow, positionHigh, lengthLow, lengthHigh))
- __Error.WinIOError();
- }
-
- // 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.
- [System.Security.SecurityCritical] // auto-generated
- private unsafe int ReadFileNative(SafeFileHandle handle, byte[] bytes, int offset, int count, NativeOverlapped* overlapped, out int hr)
- {
- Contract.Requires(handle != null, "handle != null");
- Contract.Requires(offset >= 0, "offset >= 0");
- Contract.Requires(count >= 0, "count >= 0");
- Contract.Requires(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(Environment.GetResourceString("IndexOutOfRange_IORaceCondition"));
- Contract.EndContractBlock();
-
- Contract.Assert((_isAsync && overlapped != null) || (!_isAsync && overlapped == null), "Async IO parameter mismatch in call to ReadFileNative.");
-
- // You can't use the fixed statement on an array of length 0.
- if (bytes.Length==0) {
- hr = 0;
- return 0;
- }
-
- int r = 0;
- int numBytesRead = 0;
-
- fixed(byte* p = bytes) {
- if (_isAsync)
- r = Win32Native.ReadFile(handle, p + offset, count, IntPtr.Zero, overlapped);
- else
- r = Win32Native.ReadFile(handle, p + offset, count, out numBytesRead, IntPtr.Zero);
- }
-
- if (r==0) {
- hr = Marshal.GetLastWin32Error();
- // We should never silently drop an error here without some
- // extra work. We must make sure that BeginReadCore won't return an
- // IAsyncResult that will cause EndRead to block, since the OS won't
- // call AsyncFSCallback for us.
- if (hr == ERROR_BROKEN_PIPE || hr == Win32Native.ERROR_PIPE_NOT_CONNECTED) {
- // This handle was a pipe, and it's done. Not an error, but EOF.
- // However, the OS will not call AsyncFSCallback!
- // Let the caller handle this, since BeginReadCore & ReadCore
- // need to do different things.
- return -1;
- }
-
- // See code:#errorInvalidHandle in "private long SeekCore(long offset, SeekOrigin origin)".
- if (hr == Win32Native.ERROR_INVALID_HANDLE)
- _handle.Dispose();
-
- return -1;
- }
- else
- hr = 0;
- return numBytesRead;
- }
-
- [System.Security.SecurityCritical] // auto-generated
- private unsafe int WriteFileNative(SafeFileHandle handle, byte[] bytes, int offset, int count, NativeOverlapped* overlapped, out int hr) {
- Contract.Requires(handle != null, "handle != null");
- Contract.Requires(offset >= 0, "offset >= 0");
- Contract.Requires(count >= 0, "count >= 0");
- Contract.Requires(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(Environment.GetResourceString("IndexOutOfRange_IORaceCondition"));
- Contract.EndContractBlock();
-
- Contract.Assert((_isAsync && overlapped != null) || (!_isAsync && overlapped == null), "Async IO parameter missmatch in call to WriteFileNative.");
-
- // You can't use the fixed statement on an array of length 0.
- if (bytes.Length==0) {
- hr = 0;
- return 0;
- }
-
- int numBytesWritten = 0;
- int r = 0;
-
- fixed(byte* p = bytes) {
- if (_isAsync)
- r = Win32Native.WriteFile(handle, p + offset, count, IntPtr.Zero, overlapped);
- else
- r = Win32Native.WriteFile(handle, p + offset, count, out numBytesWritten, IntPtr.Zero);
- }
-
- if (r==0) {
- hr = Marshal.GetLastWin32Error();
- // We should never silently drop an error here without some
- // extra work. We must make sure that BeginWriteCore won't return an
- // IAsyncResult that will cause EndWrite to block, since the OS won't
- // call AsyncFSCallback for us.
-
- if (hr==ERROR_NO_DATA) {
- // This handle was a pipe, and the pipe is being closed on the
- // other side. Let the caller handle this, since BeginWriteCore
- // & WriteCore need to do different things.
- return -1;
- }
-
- // See code:#errorInvalidHandle in "private long SeekCore(long offset, SeekOrigin origin)".
- if (hr == Win32Native.ERROR_INVALID_HANDLE)
- _handle.Dispose();
-
- return -1;
- }
- else
- hr = 0;
- return numBytesWritten;
- }
-
-
- [HostProtection(ExternalThreading = true)]
- [ComVisible(false)]
- [SecuritySafeCritical]
- public override Task<int> ReadAsync(Byte[] buffer, int offset, int count, CancellationToken cancellationToken)
- {
- if (buffer == null)
- throw new ArgumentNullException("buffer");
- if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (buffer.Length - offset < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
- Contract.EndContractBlock();
-
- // If we have been inherited into a subclass, the following implementation could be incorrect
- // since it does not call through to Read() or BeginRead() which a subclass might have overriden.
- // To be safe we will only use this implementation in cases where we know it is safe to do so,
- // and delegate to our base class (which will call into Read/BeginRead) when we are not sure.
- if (this.GetType() != typeof(FileStream))
- return base.ReadAsync(buffer, offset, count, cancellationToken);
-
- if (cancellationToken.IsCancellationRequested)
- return Task.FromCanceled<int>(cancellationToken);
-
- if (_handle.IsClosed)
- __Error.FileNotOpen();
-
- // If async IO is not supported on this platform or
- // if this FileStream was not opened with FileOptions.Asynchronous.
- if (!_isAsync)
- return base.ReadAsync(buffer, offset, count, cancellationToken);
-
- var readTask = new FileStreamReadWriteTask<int>(cancellationToken);
- var endReadTask = s_endReadTask;
- if (endReadTask == null) s_endReadTask = endReadTask = EndReadTask; // benign initialization race condition
- readTask._asyncResult = BeginReadAsync(buffer, offset, count, endReadTask, readTask);
-
- if (readTask._asyncResult.IsAsync && cancellationToken.CanBeCanceled)
- {
- var cancelReadHandler = s_cancelReadHandler;
- if (cancelReadHandler == null) s_cancelReadHandler = cancelReadHandler = CancelTask<int>; // benign initialization race condition
- readTask._registration = cancellationToken.Register(cancelReadHandler, readTask);
-
- // In case the task is completed right before we register the cancellation callback.
- if (readTask._asyncResult.IsCompleted)
- readTask._registration.Dispose();
- }
-
- return readTask;
- }
-
- [HostProtection(ExternalThreading = true)]
- [ComVisible(false)]
- [SecuritySafeCritical]
- public override Task WriteAsync(Byte[] buffer, int offset, int count, CancellationToken cancellationToken)
- {
- if (buffer == null)
- throw new ArgumentNullException("buffer");
- if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (buffer.Length - offset < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
- Contract.EndContractBlock();
-
- // If we have been inherited into a subclass, the following implementation could be incorrect
- // since it does not call through to Write() or BeginWrite() which a subclass might have overriden.
- // To be safe we will only use this implementation in cases where we know it is safe to do so,
- // and delegate to our base class (which will call into Write/BeginWrite) when we are not sure.
- if (this.GetType() != typeof(FileStream))
- return base.WriteAsync(buffer, offset, count, cancellationToken);
-
- if (cancellationToken.IsCancellationRequested)
- return Task.FromCanceled(cancellationToken);
-
- if (_handle.IsClosed)
- __Error.FileNotOpen();
-
- // If async IO is not supported on this platform or
- // if this FileStream was not opened with FileOptions.Asynchronous.
- if (!_isAsync)
- return base.WriteAsync(buffer, offset, count, cancellationToken);
-
- var writeTask = new FileStreamReadWriteTask<VoidTaskResult>(cancellationToken);
- var endWriteTask = s_endWriteTask;
- if (endWriteTask == null) s_endWriteTask = endWriteTask = EndWriteTask; // benign initialization race condition
- writeTask._asyncResult = BeginWriteAsync(buffer, offset, count, endWriteTask, writeTask);
-
- if (writeTask._asyncResult.IsAsync && cancellationToken.CanBeCanceled)
- {
- var cancelWriteHandler = s_cancelWriteHandler;
- if (cancelWriteHandler == null) s_cancelWriteHandler = cancelWriteHandler = CancelTask<VoidTaskResult>; // benign initialization race condition
- writeTask._registration = cancellationToken.Register(cancelWriteHandler, writeTask);
-
- // In case the task is completed right before we register the cancellation callback.
- if (writeTask._asyncResult.IsCompleted)
- writeTask._registration.Dispose();
- }
-
- return writeTask;
- }
-
- // The task instance returned from ReadAsync and WriteAsync.
- // Also stores all of the state necessary for those calls to avoid closures and extraneous delegate allocations.
- private sealed class FileStreamReadWriteTask<T> : Task<T>
- {
- internal CancellationToken _cancellationToken;
- internal CancellationTokenRegistration _registration;
- internal FileStreamAsyncResult _asyncResult; // initialized after Begin call completes
-
- internal FileStreamReadWriteTask(CancellationToken cancellationToken) : base()
- {
- _cancellationToken = cancellationToken;
- }
- }
-
- // Cancellation callback for both ReadAsync and WriteAsync.
- [SecuritySafeCritical]
- private static void CancelTask<T>(object state)
- {
- var task = state as FileStreamReadWriteTask<T>;
- Contract.Assert(task != null);
- FileStreamAsyncResult asyncResult = task._asyncResult;
-
- // This method is used as both the completion callback and the cancellation callback.
- // We should try to cancel the operation if this is running as the completion callback
- // or if cancellation is not applicable:
- // 1. asyncResult is not a FileStreamAsyncResult
- // 2. asyncResult.IsAsync is false: asyncResult is a "synchronous" FileStreamAsyncResult.
- // 3. The asyncResult is completed: this should never happen.
- Contract.Assert((!asyncResult.IsWrite && typeof(T) == typeof(int)) ||
- (asyncResult.IsWrite && typeof(T) == typeof(VoidTaskResult)));
- Contract.Assert(asyncResult != null);
- Contract.Assert(asyncResult.IsAsync);
-
- try
- {
- // Cancel the overlapped read and set the task to cancelled state.
- if (!asyncResult.IsCompleted)
- asyncResult.Cancel();
- }
- catch (Exception ex)
- {
- task.TrySetException(ex);
- }
- }
-
- // Completion callback for ReadAsync
- [SecuritySafeCritical]
- private static void EndReadTask(IAsyncResult iar)
- {
- FileStreamAsyncResult asyncResult = iar as FileStreamAsyncResult;
- Contract.Assert(asyncResult != null);
- Contract.Assert(asyncResult.IsCompleted, "How can we end up in the completion callback if the IAsyncResult is not completed?");
-
- var readTask = asyncResult.AsyncState as FileStreamReadWriteTask<int>;
- Contract.Assert(readTask != null);
-
- try
- {
- if (asyncResult.IsAsync)
- {
- asyncResult.ReleaseNativeResource();
-
- // release the resource held by CancellationTokenRegistration
- readTask._registration.Dispose();
- }
-
- if (asyncResult.ErrorCode == Win32Native.ERROR_OPERATION_ABORTED)
- {
- var cancellationToken = readTask._cancellationToken;
- Contract.Assert(cancellationToken.IsCancellationRequested, "How can the IO operation be aborted if cancellation was not requested?");
- readTask.TrySetCanceled(cancellationToken);
- }
- else
- readTask.TrySetResult(asyncResult.NumBytesRead);
- }
- catch (Exception ex)
- {
- readTask.TrySetException(ex);
- }
- }
-
- // Completion callback for WriteAsync
- [SecuritySafeCritical]
- private static void EndWriteTask(IAsyncResult iar)
- {
- var asyncResult = iar as FileStreamAsyncResult;
- Contract.Assert(asyncResult != null);
- Contract.Assert(asyncResult.IsCompleted, "How can we end up in the completion callback if the IAsyncResult is not completed?");
-
- var writeTask = iar.AsyncState as FileStreamReadWriteTask<VoidTaskResult>;
- Contract.Assert(writeTask != null);
-
- try
- {
- if (asyncResult.IsAsync)
- {
- asyncResult.ReleaseNativeResource();
-
- // release the resource held by CancellationTokenRegistration
- writeTask._registration.Dispose();
- }
-
- if (asyncResult.ErrorCode == Win32Native.ERROR_OPERATION_ABORTED)
- {
- var cancellationToken = writeTask._cancellationToken;
- Contract.Assert(cancellationToken.IsCancellationRequested, "How can the IO operation be aborted if cancellation was not requested?");
- writeTask.TrySetCanceled(cancellationToken);
- }
- else
- writeTask.TrySetResult(default(VoidTaskResult));
- }
- catch (Exception ex)
- {
- writeTask.TrySetException(ex);
- }
- }
-
- // 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.
- [HostProtection(ExternalThreading = true)]
- [ComVisible(false)]
- [System.Security.SecuritySafeCritical]
- public override Task FlushAsync(CancellationToken cancellationToken)
- {
- // If we have been inherited into a subclass, the following implementation could be incorrect
- // since it does not call through to Flush() which a subclass might have overriden. To be safe
- // we will only use this implementation in cases where we know it is safe to do so,
- // and delegate to our base class (which will call into Flush) when we are not sure.
- if (this.GetType() != typeof(FileStream))
- return base.FlushAsync(cancellationToken);
-
- if (cancellationToken.IsCancellationRequested)
- return Task.FromCanceled(cancellationToken);
-
- if (_handle.IsClosed)
- __Error.FileNotOpen();
-
- // 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;
- }
-
- }
-}
diff --git a/src/mscorlib/src/System/IO/FileSystemEnumerable.cs b/src/mscorlib/src/System/IO/FileSystemEnumerable.cs
index c2e603c06a..f861805ccf 100644
--- a/src/mscorlib/src/System/IO/FileSystemEnumerable.cs
+++ b/src/mscorlib/src/System/IO/FileSystemEnumerable.cs
@@ -12,17 +12,14 @@
**
===========================================================*/
-using System;
using System.Collections;
using System.Collections.Generic;
-using System.Security;
-using System.Security.Permissions;
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
-using System.Text;
using System.Runtime.InteropServices;
using System.Globalization;
using System.Runtime.Versioning;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Threading;
@@ -158,7 +155,6 @@ namespace System.IO
// For all the dirs/files returned, demands path discovery permission for their parent folders
internal class FileSystemEnumerableIterator<TSource> : Iterator<TSource>
{
-
private const int STATE_INIT = 1;
private const int STATE_SEARCH_NEXT_DIR = 2;
private const int STATE_FIND_NEXT_FILE = 3;
@@ -168,9 +164,7 @@ namespace System.IO
private List<Directory.SearchData> searchStack;
private Directory.SearchData searchData;
private String searchCriteria;
- [System.Security.SecurityCritical]
SafeFindHandle _hnd = null;
- bool needsParentPathDiscoveryDemand;
// empty means we know in advance that we won’t find any search results, which can happen if:
// 1. we don’t have a search pattern
@@ -185,9 +179,7 @@ namespace System.IO
private String fullPath;
private String normalizedSearchPath;
private int oldMode;
- private bool _checkHost;
- [System.Security.SecuritySafeCritical]
internal FileSystemEnumerableIterator(String path, String originalUserPath, String searchPattern, SearchOption searchOption, SearchResultHandler<TSource> resultHandler, bool checkHost)
{
Contract.Requires(path != null);
@@ -211,30 +203,10 @@ namespace System.IO
_resultHandler = resultHandler;
this.searchOption = searchOption;
- fullPath = Path.GetFullPathInternal(path);
+ fullPath = Path.GetFullPath(path);
String fullSearchString = GetFullSearchString(fullPath, normalizedSearchPattern);
normalizedSearchPath = Path.GetDirectoryName(fullSearchString);
- // permission demands
- String[] demandPaths = new String[2];
- // Any illegal chars such as *, ? will be caught by FileIOPermission.HasIllegalCharacters
- demandPaths[0] = Directory.GetDemandDir(fullPath, true);
- // For filters like foo\*.cs we need to verify if the directory foo is not denied access.
- // Do a demand on the combined path so that we can fail early in case of deny
- demandPaths[1] = Directory.GetDemandDir(normalizedSearchPath, true);
- _checkHost = checkHost;
-#if FEATURE_CORECLR
- if (checkHost)
- {
- FileSecurityState state1 = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, demandPaths[0]);
- state1.EnsureState();
- FileSecurityState state2 = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, demandPaths[1]);
- state2.EnsureState();
- }
-#else
- new FileIOPermission(FileIOPermissionAccess.PathDiscovery, demandPaths, false, false).Demand();
-#endif
-
// normalize search criteria
searchCriteria = GetNormalizedSearchCriteria(fullSearchString, normalizedSearchPath);
@@ -254,13 +226,12 @@ namespace System.IO
}
- [System.Security.SecurityCritical]
private void CommonInit()
{
- Contract.Assert(searchCriteria != null && searchData != null, "searchCriteria and searchData should be initialized");
+ Debug.Assert(searchCriteria != null && searchData != null, "searchCriteria and searchData should be initialized");
// Execute searchCriteria against the current directory
- String searchPath = Path.InternalCombine(searchData.fullPath, searchCriteria);
+ String searchPath = Path.Combine(searchData.fullPath, searchCriteria);
Win32Native.WIN32_FIND_DATA data = new Win32Native.WIN32_FIND_DATA();
@@ -307,8 +278,7 @@ namespace System.IO
}
}
- [System.Security.SecuritySafeCritical]
- private FileSystemEnumerableIterator(String fullPath, String normalizedSearchPath, String searchCriteria, String userPath, SearchOption searchOption, SearchResultHandler<TSource> resultHandler, bool checkHost)
+ private FileSystemEnumerableIterator(String fullPath, String normalizedSearchPath, String searchCriteria, String userPath, SearchOption searchOption, SearchResultHandler<TSource> resultHandler)
{
this.fullPath = fullPath;
this.normalizedSearchPath = normalizedSearchPath;
@@ -316,30 +286,11 @@ namespace System.IO
this._resultHandler = resultHandler;
this.userPath = userPath;
this.searchOption = searchOption;
- this._checkHost = checkHost;
searchStack = new List<Directory.SearchData>();
if (searchCriteria != null)
{
- // permission demands
- String[] demandPaths = new String[2];
- // Any illegal chars such as *, ? will be caught by FileIOPermission.HasIllegalCharacters
- demandPaths[0] = Directory.GetDemandDir(fullPath, true);
- // For filters like foo\*.cs we need to verify if the directory foo is not denied access.
- // Do a demand on the combined path so that we can fail early in case of deny
- demandPaths[1] = Directory.GetDemandDir(normalizedSearchPath, true);
-#if FEATURE_CORECLR
- if (checkHost)
- {
- FileSecurityState state1 = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, demandPaths[0]);
- state1.EnsureState();
- FileSecurityState state2 = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, demandPaths[1]);
- state2.EnsureState();
- }
-#else
- new FileIOPermission(FileIOPermissionAccess.PathDiscovery, demandPaths, false, false).Demand();
-#endif
searchData = new Directory.SearchData(normalizedSearchPath, userPath, searchOption);
CommonInit();
}
@@ -351,10 +302,9 @@ namespace System.IO
protected override Iterator<TSource> Clone()
{
- return new FileSystemEnumerableIterator<TSource>(fullPath, normalizedSearchPath, searchCriteria, userPath, searchOption, _resultHandler, _checkHost);
+ return new FileSystemEnumerableIterator<TSource>(fullPath, normalizedSearchPath, searchCriteria, userPath, searchOption, _resultHandler);
}
- [System.Security.SecuritySafeCritical]
protected override void Dispose(bool disposing)
{
try
@@ -371,7 +321,6 @@ namespace System.IO
}
}
- [System.Security.SecuritySafeCritical]
public override bool MoveNext()
{
Win32Native.WIN32_FIND_DATA data = new Win32Native.WIN32_FIND_DATA();
@@ -404,19 +353,19 @@ namespace System.IO
}
case STATE_SEARCH_NEXT_DIR:
{
- Contract.Assert(searchData.searchOption != SearchOption.TopDirectoryOnly, "should not reach this code path if searchOption == TopDirectoryOnly");
+ Debug.Assert(searchData.searchOption != SearchOption.TopDirectoryOnly, "should not reach this code path if searchOption == TopDirectoryOnly");
// Traverse directory structure. We need to get '*'
while (searchStack.Count > 0)
{
searchData = searchStack[0];
- Contract.Assert((searchData.fullPath != null), "fullpath can't be null!");
+ Debug.Assert((searchData.fullPath != null), "fullpath can't be null!");
searchStack.RemoveAt(0);
// Traverse the subdirs
AddSearchableDirsToStack(searchData);
// Execute searchCriteria against the current directory
- String searchPath = Path.InternalCombine(searchData.fullPath, searchCriteria);
+ String searchPath = Path.Combine(searchData.fullPath, searchCriteria);
// Open a Find handle
_hnd = Win32Native.FindFirstFile(searchPath, data);
@@ -431,15 +380,9 @@ namespace System.IO
}
state = STATE_FIND_NEXT_FILE;
- needsParentPathDiscoveryDemand = true;
SearchResult searchResult = CreateSearchResult(searchData, data);
if (_resultHandler.IsResultIncluded(searchResult))
{
- if (needsParentPathDiscoveryDemand)
- {
- DoDemand(searchData.fullPath);
- needsParentPathDiscoveryDemand = false;
- }
current = _resultHandler.CreateObject(searchResult);
return true;
}
@@ -461,11 +404,6 @@ namespace System.IO
SearchResult searchResult = CreateSearchResult(searchData, data);
if (_resultHandler.IsResultIncluded(searchResult))
{
- if (needsParentPathDiscoveryDemand)
- {
- DoDemand(searchData.fullPath);
- needsParentPathDiscoveryDemand = false;
- }
current = _resultHandler.CreateObject(searchResult);
return true;
}
@@ -506,27 +444,24 @@ namespace System.IO
return false;
}
- [System.Security.SecurityCritical]
private SearchResult CreateSearchResult(Directory.SearchData localSearchData, Win32Native.WIN32_FIND_DATA findData)
{
- String userPathFinal = Path.InternalCombine(localSearchData.userPath, findData.cFileName);
- String fullPathFinal = Path.InternalCombine(localSearchData.fullPath, findData.cFileName);
+ String userPathFinal = Path.Combine(localSearchData.userPath, findData.cFileName);
+ String fullPathFinal = Path.Combine(localSearchData.fullPath, findData.cFileName);
return new SearchResult(fullPathFinal, userPathFinal, findData);
}
- [System.Security.SecurityCritical]
private void HandleError(int hr, String path)
{
Dispose();
__Error.WinIOError(hr, path);
}
- [System.Security.SecurityCritical] // auto-generated
private void AddSearchableDirsToStack(Directory.SearchData localSearchData)
{
Contract.Requires(localSearchData != null);
- String searchPath = Path.InternalCombine(localSearchData.fullPath, "*");
+ String searchPath = Path.Combine(localSearchData.fullPath, "*");
SafeFindHandle hnd = null;
Win32Native.WIN32_FIND_DATA data = new Win32Native.WIN32_FIND_DATA();
try
@@ -553,8 +488,8 @@ namespace System.IO
{
if (FileSystemEnumerableHelpers.IsDir(data))
{
- String tempFullPath = Path.InternalCombine(localSearchData.fullPath, data.cFileName);
- String tempUserPath = Path.InternalCombine(localSearchData.userPath, data.cFileName);
+ String tempFullPath = Path.Combine(localSearchData.fullPath, data.cFileName);
+ String tempUserPath = Path.Combine(localSearchData.userPath, data.cFileName);
SearchOption option = localSearchData.searchOption;
@@ -578,28 +513,12 @@ namespace System.IO
}
}
- [System.Security.SecurityCritical]
- internal void DoDemand(String fullPathToDemand)
- {
-#if FEATURE_CORECLR
- if(_checkHost) {
- String demandDir = Directory.GetDemandDir(fullPathToDemand, true);
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, demandDir);
- state.EnsureState();
- }
-#else
- String demandDir = Directory.GetDemandDir(fullPathToDemand, true);
- String[] demandPaths = new String[] { demandDir };
- new FileIOPermission(FileIOPermissionAccess.PathDiscovery, demandPaths, false, false).Demand();
-#endif
- }
-
private static String NormalizeSearchPattern(String searchPattern)
{
Contract.Requires(searchPattern != null);
- // Win32 normalization trims only U+0020.
- String tempSearchPattern = searchPattern.TrimEnd(Path.TrimEndChars);
+ // Win32 normalization trims only U+0020.
+ String tempSearchPattern = searchPattern.TrimEnd(PathInternal.s_trimEndChars);
// Make this corner case more useful, like dir
if (tempSearchPattern.Equals("."))
@@ -607,7 +526,7 @@ namespace System.IO
tempSearchPattern = "*";
}
- Path.CheckSearchPattern(tempSearchPattern);
+ PathInternal.CheckSearchPattern(tempSearchPattern);
return tempSearchPattern;
}
@@ -619,14 +538,14 @@ namespace System.IO
String searchCriteria = null;
char lastChar = fullPathMod[fullPathMod.Length - 1];
- if (Path.IsDirectorySeparator(lastChar))
+ if (PathInternal.IsDirectorySeparator(lastChar))
{
// Can happen if the path is C:\temp, in which case GetDirectoryName would return C:\
searchCriteria = fullSearchString.Substring(fullPathMod.Length);
}
else
{
- Contract.Assert(fullSearchString.Length > fullPathMod.Length);
+ Debug.Assert(fullSearchString.Length > fullPathMod.Length);
searchCriteria = fullSearchString.Substring(fullPathMod.Length + 1);
}
return searchCriteria;
@@ -637,11 +556,11 @@ namespace System.IO
Contract.Requires(fullPath != null);
Contract.Requires(searchPattern != null);
- String tempStr = Path.InternalCombine(fullPath, searchPattern);
+ String tempStr = Path.Combine(fullPath, searchPattern);
// If path ends in a trailing slash (\), append a * or we'll get a "Cannot find the file specified" exception
char lastChar = tempStr[tempStr.Length - 1];
- if (Path.IsDirectorySeparator(lastChar) || lastChar == Path.VolumeSeparatorChar)
+ if (PathInternal.IsDirectorySeparator(lastChar) || lastChar == Path.VolumeSeparatorChar)
{
tempStr = tempStr + '*';
}
@@ -653,10 +572,8 @@ namespace System.IO
internal abstract class SearchResultHandler<TSource>
{
- [System.Security.SecurityCritical]
internal abstract bool IsResultIncluded(SearchResult result);
- [System.Security.SecurityCritical]
internal abstract TSource CreateObject(SearchResult result);
}
@@ -672,16 +589,14 @@ namespace System.IO
_includeDirs = includeDirs;
}
- [System.Security.SecurityCritical]
internal override bool IsResultIncluded(SearchResult result)
{
bool includeFile = _includeFiles && FileSystemEnumerableHelpers.IsFile(result.FindData);
bool includeDir = _includeDirs && FileSystemEnumerableHelpers.IsDir(result.FindData);
- Contract.Assert(!(includeFile && includeDir), result.FindData.cFileName + ": current item can't be both file and dir!");
+ Debug.Assert(!(includeFile && includeDir), result.FindData.cFileName + ": current item can't be both file and dir!");
return (includeFile || includeDir);
}
- [System.Security.SecurityCritical]
internal override String CreateObject(SearchResult result)
{
return result.UserPath;
@@ -690,23 +605,14 @@ namespace System.IO
internal class FileInfoResultHandler : SearchResultHandler<FileInfo>
{
- [System.Security.SecurityCritical]
internal override bool IsResultIncluded(SearchResult result)
{
return FileSystemEnumerableHelpers.IsFile(result.FindData);
}
- [System.Security.SecurityCritical]
internal override FileInfo CreateObject(SearchResult result)
{
String name = result.FullPath;
-#if FEATURE_CORECLR
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, name);
- state.EnsureState();
-#else
- String[] names = new String[] { name };
- new FileIOPermission(FileIOPermissionAccess.Read, names, false, false).Demand();
-#endif
FileInfo fi = new FileInfo(name, false);
fi.InitializeFrom(result.FindData);
return fi;
@@ -715,26 +621,14 @@ namespace System.IO
internal class DirectoryInfoResultHandler : SearchResultHandler<DirectoryInfo>
{
- [System.Security.SecurityCritical]
internal override bool IsResultIncluded(SearchResult result)
{
return FileSystemEnumerableHelpers.IsDir(result.FindData);
}
- [System.Security.SecurityCritical]
internal override DirectoryInfo CreateObject(SearchResult result)
{
- String name = result.FullPath;
- String permissionName = name + "\\.";
-
-#if FEATURE_CORECLR
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, permissionName);
- state.EnsureState();
-#else
- String[] permissionNames = new String[] { permissionName };
- new FileIOPermission(FileIOPermissionAccess.Read, permissionNames, false, false).Demand();
-#endif
- DirectoryInfo di = new DirectoryInfo(name, false);
+ DirectoryInfo di = new DirectoryInfo(result.FullPath, false);
di.InitializeFrom(result.FindData);
return di;
}
@@ -743,17 +637,15 @@ namespace System.IO
internal class FileSystemInfoResultHandler : SearchResultHandler<FileSystemInfo>
{
- [System.Security.SecurityCritical]
internal override bool IsResultIncluded(SearchResult result)
{
bool includeFile = FileSystemEnumerableHelpers.IsFile(result.FindData);
bool includeDir = FileSystemEnumerableHelpers.IsDir(result.FindData);
- Contract.Assert(!(includeFile && includeDir), result.FindData.cFileName + ": current item can't be both file and dir!");
+ Debug.Assert(!(includeFile && includeDir), result.FindData.cFileName + ": current item can't be both file and dir!");
return (includeDir || includeFile);
}
- [System.Security.SecurityCritical]
internal override FileSystemInfo CreateObject(SearchResult result)
{
bool isFile = FileSystemEnumerableHelpers.IsFile(result.FindData);
@@ -761,33 +653,14 @@ namespace System.IO
if (isDir)
{
- String name = result.FullPath;
- String permissionName = name + "\\.";
-
-#if FEATURE_CORECLR
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, permissionName);
- state.EnsureState();
-#else
- String[] permissionNames = new String[] { permissionName };
- new FileIOPermission(FileIOPermissionAccess.Read, permissionNames, false, false).Demand();
-#endif
- DirectoryInfo di = new DirectoryInfo(name, false);
+ DirectoryInfo di = new DirectoryInfo(result.FullPath, false);
di.InitializeFrom(result.FindData);
return di;
}
else
{
Contract.Assert(isFile);
- String name = result.FullPath;
-
-#if FEATURE_CORECLR
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, name);
- state.EnsureState();
-#else
- String[] names = new String[] { name };
- new FileIOPermission(FileIOPermissionAccess.Read, names, false, false).Demand();
-#endif
- FileInfo fi = new FileInfo(name, false);
+ FileInfo fi = new FileInfo(result.FullPath, false);
fi.InitializeFrom(result.FindData);
return fi;
}
@@ -799,10 +672,8 @@ namespace System.IO
{
private String fullPath; // fully-qualifed path
private String userPath; // user-specified path
- [System.Security.SecurityCritical]
private Win32Native.WIN32_FIND_DATA findData;
- [System.Security.SecurityCritical]
internal SearchResult(String fullPath, String userPath, Win32Native.WIN32_FIND_DATA findData)
{
Contract.Requires(fullPath != null);
@@ -825,15 +696,12 @@ namespace System.IO
internal Win32Native.WIN32_FIND_DATA FindData
{
- [System.Security.SecurityCritical]
get { return findData; }
}
-
}
internal static class FileSystemEnumerableHelpers
{
- [System.Security.SecurityCritical] // auto-generated
internal static bool IsDir(Win32Native.WIN32_FIND_DATA data)
{
// Don't add "." nor ".."
@@ -841,7 +709,6 @@ namespace System.IO
&& !data.cFileName.Equals(".") && !data.cFileName.Equals("..");
}
- [System.Security.SecurityCritical] // auto-generated
internal static bool IsFile(Win32Native.WIN32_FIND_DATA data)
{
return 0 == (data.dwFileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY);
diff --git a/src/mscorlib/src/System/IO/FileSystemInfo.cs b/src/mscorlib/src/System/IO/FileSystemInfo.cs
index 7a17a417af..94cd531b07 100644
--- a/src/mscorlib/src/System/IO/FileSystemInfo.cs
+++ b/src/mscorlib/src/System/IO/FileSystemInfo.cs
@@ -2,43 +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:
-**
-**
-===========================================================*/
-
-using System;
-using System.Collections;
-using System.Security;
-using System.Security.Permissions;
using Microsoft.Win32;
-using System.Text;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
-using System.Runtime.Versioning;
using System.Diagnostics.Contracts;
-namespace System.IO {
+namespace System.IO
+{
#if FEATURE_SERIALIZATION
[Serializable]
#endif
-#if !FEATURE_CORECLR
- [FileIOPermissionAttribute(SecurityAction.InheritanceDemand,Unrestricted=true)]
-#endif
[ComVisible(true)]
-#if FEATURE_REMOTING
public abstract class FileSystemInfo : MarshalByRefObject, ISerializable {
-#else // FEATURE_REMOTING
- public abstract class FileSystemInfo : ISerializable {
-#endif //FEATURE_REMOTING
- [System.Security.SecurityCritical] // auto-generated
internal Win32Native.WIN32_FILE_ATTRIBUTE_DATA _data; // Cache the file information
internal int _dataInitialised = -1; // We use this field in conjunction with the Refresh methods, if we succeed
// we store a zero, on failure we store the HResult in it so that we can
@@ -51,13 +27,6 @@ namespace System.IO {
protected String OriginalPath; // path passed in by the user
private String _displayPath = ""; // path that can be displayed to the user
-#if FEATURE_CORECLR
-#if FEATURE_CORESYSTEM
- [System.Security.SecurityCritical]
-#else
- [System.Security.SecuritySafeCritical]
-#endif //FEATURE_CORESYSTEM
-#endif
protected FileSystemInfo()
{
}
@@ -65,19 +34,18 @@ namespace System.IO {
protected FileSystemInfo(SerializationInfo info, StreamingContext context)
{
if (info == null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
-
+
// Must use V1 field names here, since V1 didn't implement
// ISerializable.
- FullPath = Path.GetFullPathInternal(info.GetString("FullPath"));
+ FullPath = Path.GetFullPath(info.GetString("FullPath"));
OriginalPath = info.GetString("OriginalPath");
// Lazily initialize the file attributes.
_dataInitialised = -1;
}
- [System.Security.SecurityCritical]
internal void InitializeFrom(Win32Native.WIN32_FIND_DATA findData)
{
_data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
@@ -87,37 +55,8 @@ namespace System.IO {
// Full path of the direcory/file
public virtual String FullName {
- [System.Security.SecuritySafeCritical]
get
{
- String demandDir;
- if (this is DirectoryInfo)
- demandDir = Directory.GetDemandDir(FullPath, true);
- else
- demandDir = FullPath;
-#if FEATURE_CORECLR
- FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, String.Empty, demandDir);
- sourceState.EnsureState();
-#else
- new FileIOPermission(FileIOPermissionAccess.PathDiscovery, demandDir).Demand();
-#endif
- return FullPath;
- }
- }
-
- internal virtual String UnsafeGetFullName
- {
- [System.Security.SecurityCritical]
- get
- {
- String demandDir;
- if (this is DirectoryInfo)
- demandDir = Directory.GetDemandDir(FullPath, true);
- else
- demandDir = FullPath;
-#if !FEATURE_CORECLR
- new FileIOPermission(FileIOPermissionAccess.PathDiscovery, demandDir).Demand();
-#endif
return FullPath;
}
}
@@ -160,21 +99,11 @@ namespace System.IO {
// depends on the security check in get_CreationTimeUtc
return CreationTimeUtc.ToLocalTime();
}
-
- set {
- CreationTimeUtc = value.ToUniversalTime();
- }
}
[ComVisible(false)]
public DateTime CreationTimeUtc {
- [System.Security.SecuritySafeCritical]
get {
-#if FEATURE_CORECLR
- // get_CreationTime also depends on this security check
- FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, FullPath);
- sourceState.EnsureState();
-#endif
if (_dataInitialised == -1) {
_data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
Refresh();
@@ -187,19 +116,10 @@ namespace System.IO {
return DateTime.FromFileTimeUtc(fileTime);
}
-
- set {
- if (this is DirectoryInfo)
- Directory.SetCreationTimeUtc(FullPath,value);
- else
- File.SetCreationTimeUtc(FullPath,value);
- _dataInitialised = -1;
- }
}
-
public DateTime LastAccessTime
- {
+ {
get {
// depends on the security check in get_LastAccessTimeUtc
return LastAccessTimeUtc.ToLocalTime();
@@ -211,13 +131,7 @@ namespace System.IO {
[ComVisible(false)]
public DateTime LastAccessTimeUtc {
- [System.Security.SecuritySafeCritical]
get {
-#if FEATURE_CORECLR
- // get_LastAccessTime also depends on this security check
- FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, FullPath);
- sourceState.EnsureState();
-#endif
if (_dataInitialised == -1) {
_data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
Refresh();
@@ -228,15 +142,9 @@ namespace System.IO {
long fileTime = ((long)_data.ftLastAccessTimeHigh << 32) | _data.ftLastAccessTimeLow;
return DateTime.FromFileTimeUtc(fileTime);
-
}
set {
- if (this is DirectoryInfo)
- Directory.SetLastAccessTimeUtc(FullPath,value);
- else
- File.SetLastAccessTimeUtc(FullPath,value);
- _dataInitialised = -1;
}
}
@@ -254,13 +162,7 @@ namespace System.IO {
[ComVisible(false)]
public DateTime LastWriteTimeUtc {
- [System.Security.SecuritySafeCritical]
get {
-#if FEATURE_CORECLR
- // get_LastWriteTime also depends on this security check
- FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, FullPath);
- sourceState.EnsureState();
-#endif
if (_dataInitialised == -1) {
_data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
Refresh();
@@ -275,28 +177,17 @@ namespace System.IO {
}
set {
- if (this is DirectoryInfo)
- Directory.SetLastWriteTimeUtc(FullPath,value);
- else
- File.SetLastWriteTimeUtc(FullPath,value);
- _dataInitialised = -1;
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void Refresh()
{
_dataInitialised = File.FillAttributeInfo(FullPath, ref _data, false, false);
}
public FileAttributes Attributes {
- [System.Security.SecuritySafeCritical]
get
{
-#if FEATURE_CORECLR
- FileSecurityState sourceState = new FileSecurityState(FileSecurityStateAccess.Read, String.Empty, FullPath);
- sourceState.EnsureState();
-#endif
if (_dataInitialised == -1) {
_data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
Refresh(); // Call refresh to intialise the data
@@ -307,15 +198,8 @@ namespace System.IO {
return (FileAttributes) _data.fileAttributes;
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
+
set {
-#if !FEATURE_CORECLR
- new FileIOPermission(FileIOPermissionAccess.Write, FullPath).Demand();
-#endif
bool r = Win32Native.SetFileAttributes(FullPath, (int) value);
if (!r) {
int hr = Marshal.GetLastWin32Error();
@@ -334,14 +218,9 @@ namespace System.IO {
}
}
- [System.Security.SecurityCritical] // auto-generated_required
[ComVisible(false)]
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
-#if !FEATURE_CORECLR
- new FileIOPermission(FileIOPermissionAccess.PathDiscovery, FullPath).Demand();
-#endif
-
info.AddValue("OriginalPath", OriginalPath, typeof(String));
info.AddValue("FullPath", FullPath, typeof(String));
}
@@ -357,5 +236,5 @@ namespace System.IO {
_displayPath = value;
}
}
- }
+ }
}
diff --git a/src/mscorlib/src/System/IO/LongPathHelper.cs b/src/mscorlib/src/System/IO/LongPathHelper.cs
deleted file mode 100644
index 9746fdc0aa..0000000000
--- a/src/mscorlib/src/System/IO/LongPathHelper.cs
+++ /dev/null
@@ -1,521 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .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;
-using System.Runtime.InteropServices;
-using Microsoft.Win32;
-
-namespace System.IO
-{
- /// <summary>
- /// Wrapper to help with path normalization.
- /// </summary>
- internal class LongPathHelper
- {
- // Can't be over 8.3 and be a short name
- private const int MaxShortName = 12;
-
- private const char LastAnsi = (char)255;
- private const char Delete = (char)127;
-
- [ThreadStatic]
- private static StringBuffer t_fullPathBuffer;
-
- /// <summary>
- /// Normalize the given path.
- /// </summary>
- /// <remarks>
- /// Normalizes via Win32 GetFullPathName(). It will also trim all "typical" whitespace at the end of the path (see s_trimEndChars). Will also trim initial
- /// spaces if the path is determined to be rooted.
- ///
- /// Note that invalid characters will be checked after the path is normalized, which could remove bad characters. (C:\|\..\a.txt -- C:\a.txt)
- /// </remarks>
- /// <param name="path">Path to normalize</param>
- /// <param name="checkInvalidCharacters">True to check for invalid characters</param>
- /// <param name="expandShortPaths">Attempt to expand short paths if true</param>
- /// <exception cref="ArgumentException">Thrown if the path is an illegal UNC (does not contain a full server/share) or contains illegal characters.</exception>
- /// <exception cref="PathTooLongException">Thrown if the path or a path segment exceeds the filesystem limits.</exception>
- /// <exception cref="FileNotFoundException">Thrown if Windows returns ERROR_FILE_NOT_FOUND. (See Win32Marshal.GetExceptionForWin32Error)</exception>
- /// <exception cref="DirectoryNotFoundException">Thrown if Windows returns ERROR_PATH_NOT_FOUND. (See Win32Marshal.GetExceptionForWin32Error)</exception>
- /// <exception cref="UnauthorizedAccessException">Thrown if Windows returns ERROR_ACCESS_DENIED. (See Win32Marshal.GetExceptionForWin32Error)</exception>
- /// <exception cref="IOException">Thrown if Windows returns an error that doesn't map to the above. (See Win32Marshal.GetExceptionForWin32Error)</exception>
- /// <returns>Normalized path</returns>
- [System.Security.SecurityCritical]
- unsafe internal static string Normalize(string path, uint maxPathLength, bool checkInvalidCharacters, bool expandShortPaths)
- {
- // Get the full path
- StringBuffer fullPath = t_fullPathBuffer ?? (t_fullPathBuffer = new StringBuffer(PathInternal.MaxShortPath));
- try
- {
- GetFullPathName(path, fullPath);
-
- // Trim whitespace off the end of the string. Win32 normalization trims only U+0020.
- fullPath.TrimEnd(Path.TrimEndChars);
-
- if (fullPath.Length >= maxPathLength)
- {
- // Fullpath is genuinely too long
- throw new PathTooLongException();
- }
-
- // Checking path validity used to happen before getting the full path name. To avoid additional input allocation
- // (to trim trailing whitespace) we now do it after the Win32 call. This will allow legitimate paths through that
- // used to get kicked back (notably segments with invalid characters might get removed via "..").
- //
- // There is no way that GetLongPath can invalidate the path so we'll do this (cheaper) check before we attempt to
- // expand short file names.
-
- // Scan the path for:
- //
- // - Illegal path characters.
- // - Invalid UNC paths like \\, \\server, \\server\.
- // - Segments that are too long (over MaxComponentLength)
-
- // As the path could be > 60K, we'll combine the validity scan. None of these checks are performed by the Win32
- // GetFullPathName() API.
-
- bool possibleShortPath = false;
- bool foundTilde = false;
-
- // We can get UNCs as device paths through this code (e.g. \\.\UNC\), we won't validate them as there isn't
- // an easy way to normalize without extensive cost (we'd have to hunt down the canonical name for any device
- // path that contains UNC or to see if the path was doing something like \\.\GLOBALROOT\Device\Mup\,
- // \\.\GLOBAL\UNC\, \\.\GLOBALROOT\GLOBAL??\UNC\, etc.
- bool specialPath = fullPath.Length > 1 && fullPath[0] == '\\' && fullPath[1] == '\\';
- bool isDevice = PathInternal.IsDevice(fullPath);
- bool possibleBadUnc = specialPath && !isDevice;
- uint index = specialPath ? 2u : 0;
- uint lastSeparator = specialPath ? 1u : 0;
- uint segmentLength;
- char* start = fullPath.CharPointer;
- char current;
-
- while (index < fullPath.Length)
- {
- current = start[index];
-
- // Try to skip deeper analysis. '?' and higher are valid/ignorable except for '\', '|', and '~'
- if (current < '?' || current == '\\' || current == '|' || current == '~')
- {
- switch (current)
- {
- case '|':
- case '>':
- case '<':
- case '\"':
- if (checkInvalidCharacters) throw new ArgumentException(Environment.GetResourceString("Argument_InvalidPathChars"));
- // No point in expanding a bad path
- foundTilde = false;
- break;
- case '~':
- foundTilde = true;
- break;
- case '\\':
- segmentLength = index - lastSeparator - 1;
- if (segmentLength > (uint)PathInternal.MaxComponentLength)
- throw new PathTooLongException();
- lastSeparator = index;
-
- if (foundTilde)
- {
- if (segmentLength <= MaxShortName)
- {
- // Possibly a short path.
- possibleShortPath = true;
- }
-
- foundTilde = false;
- }
-
- if (possibleBadUnc)
- {
- // If we're at the end of the path and this is the first separator, we're missing the share.
- // Otherwise we're good, so ignore UNC tracking from here.
- if (index == fullPath.Length - 1)
- throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegalUNC"));
- else
- possibleBadUnc = false;
- }
-
- break;
-
- default:
- if (checkInvalidCharacters && current < ' ') throw new ArgumentException(Environment.GetResourceString("Argument_InvalidPathChars"));
- break;
- }
- }
-
- index++;
- }
-
- if (possibleBadUnc)
- throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegalUNC"));
-
- segmentLength = fullPath.Length - lastSeparator - 1;
- if (segmentLength > (uint)PathInternal.MaxComponentLength)
- throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
-
- if (foundTilde && segmentLength <= MaxShortName)
- possibleShortPath = true;
-
- // Check for a short filename path and try and expand it. Technically you don't need to have a tilde for a short name, but
- // this is how we've always done this. This expansion is costly so we'll continue to let other short paths slide.
- if (expandShortPaths && possibleShortPath)
- {
- return TryExpandShortFileName(fullPath, originalPath: path);
- }
- else
- {
- if (fullPath.Length == (uint)path.Length && fullPath.StartsWith(path))
- {
- // If we have the exact same string we were passed in, don't bother to allocate another string from the StringBuilder.
- return path;
- }
- else
- {
- return fullPath.ToString();
- }
- }
- }
- finally
- {
- // Clear the buffer
- fullPath.Free();
- }
- }
-
- [System.Security.SecurityCritical]
- unsafe private static void GetFullPathName(string path, StringBuffer fullPath)
- {
- // If the string starts with an extended prefix we would need to remove it from the path before we call GetFullPathName as
- // it doesn't root extended paths correctly. We don't currently resolve extended paths, so we'll just assert here.
- Contract.Assert(PathInternal.IsPartiallyQualified(path) || !PathInternal.IsExtended(path));
-
- // Historically we would skip leading spaces *only* if the path started with a drive " C:" or a UNC " \\"
- int startIndex = PathInternal.PathStartSkip(path);
-
- fixed (char* pathStart = path)
- {
- uint result = 0;
- while ((result = Win32Native.GetFullPathNameW(pathStart + startIndex, fullPath.CharCapacity, fullPath.GetHandle(), IntPtr.Zero)) > fullPath.CharCapacity)
- {
- // Reported size (which does not include the null) is greater than the buffer size. Increase the capacity.
- fullPath.EnsureCharCapacity(result);
- }
-
- if (result == 0)
- {
- // Failure, get the error and throw
- int errorCode = Marshal.GetLastWin32Error();
- if (errorCode == 0)
- errorCode = Win32Native.ERROR_BAD_PATHNAME;
- __Error.WinIOError(errorCode, path);
- }
-
- fullPath.Length = result;
- }
- }
-
- [System.Security.SecurityCritical]
- unsafe internal static string GetLongPathName(StringBuffer path)
- {
- using (StringBuffer outputBuffer = new StringBuffer(path.Length))
- {
- uint result = 0;
- while ((result = Win32Native.GetLongPathNameW(path.GetHandle(), outputBuffer.GetHandle(), outputBuffer.CharCapacity)) > outputBuffer.CharCapacity)
- {
- // Reported size (which does not include the null) is greater than the buffer size. Increase the capacity.
- outputBuffer.EnsureCharCapacity(result);
- }
-
- if (result == 0)
- {
- // Failure, get the error and throw
- GetErrorAndThrow(path.ToString());
- }
-
- outputBuffer.Length = result;
- return outputBuffer.ToString();
- }
- }
-
- [System.Security.SecurityCritical]
- unsafe internal static string GetLongPathName(string path)
- {
- using (StringBuffer outputBuffer = new StringBuffer((uint)path.Length))
- {
- uint result = 0;
- while ((result = Win32Native.GetLongPathNameW(path, outputBuffer.GetHandle(), outputBuffer.CharCapacity)) > outputBuffer.CharCapacity)
- {
- // Reported size (which does not include the null) is greater than the buffer size. Increase the capacity.
- outputBuffer.EnsureCharCapacity(result);
- }
-
- if (result == 0)
- {
- // Failure, get the error and throw
- GetErrorAndThrow(path);
- }
-
- outputBuffer.Length = result;
- return outputBuffer.ToString();
- }
- }
-
- [System.Security.SecurityCritical]
- private static void GetErrorAndThrow(string path)
- {
- int errorCode = Marshal.GetLastWin32Error();
- if (errorCode == 0)
- errorCode = Win32Native.ERROR_BAD_PATHNAME;
- __Error.WinIOError(errorCode, path);
- }
-
- // It is significantly more complicated to get the long path with minimal allocations if we're injecting the extended dos path prefix. The implicit version
- // should match up with what is in CoreFx System.Runtime.Extensions.
-#if !FEATURE_IMPLICIT_LONGPATH
- [System.Security.SecuritySafeCritical]
- private unsafe static string TryExpandShortFileName(StringBuffer outputBuffer, string originalPath)
- {
- // We guarantee we'll expand short names for paths that only partially exist. As such, we need to find the part of the path that actually does exist. To
- // avoid allocating like crazy we'll create only one input array and modify the contents with embedded nulls.
-
- Contract.Assert(!PathInternal.IsPartiallyQualified(outputBuffer), "should have resolved by now");
-
- using (StringBuffer inputBuffer = new StringBuffer(outputBuffer))
- {
- bool success = false;
- uint lastIndex = outputBuffer.Length - 1;
- uint foundIndex = lastIndex;
- uint rootLength = PathInternal.GetRootLength(outputBuffer);
-
- while (!success)
- {
- uint result = Win32Native.GetLongPathNameW(inputBuffer.GetHandle(), outputBuffer.GetHandle(), outputBuffer.CharCapacity);
-
- // Replace any temporary null we added
- if (inputBuffer[foundIndex] == '\0') inputBuffer[foundIndex] = '\\';
-
- if (result == 0)
- {
- // Look to see if we couldn't find the file
- int error = Marshal.GetLastWin32Error();
- if (error != Win32Native.ERROR_FILE_NOT_FOUND && error != Win32Native.ERROR_PATH_NOT_FOUND)
- {
- // Some other failure, give up
- break;
- }
-
- // We couldn't find the path at the given index, start looking further back in the string.
- foundIndex--;
-
- for (; foundIndex > rootLength && inputBuffer[foundIndex] != '\\'; foundIndex--) ;
- if (foundIndex == rootLength)
- {
- // Can't trim the path back any further
- break;
- }
- else
- {
- // Temporarily set a null in the string to get Windows to look further up the path
- inputBuffer[foundIndex] = '\0';
- }
- }
- else if (result > outputBuffer.CharCapacity)
- {
- // Not enough space. The result count for this API does not include the null terminator.
- outputBuffer.EnsureCharCapacity(result);
- }
- else
- {
- // Found the path
- success = true;
- outputBuffer.Length = result;
- if (foundIndex < lastIndex)
- {
- // It was a partial find, put the non-existant part of the path back
- outputBuffer.Append(inputBuffer, foundIndex, inputBuffer.Length - foundIndex);
- }
- }
- }
-
- StringBuffer bufferToUse = success ? outputBuffer : inputBuffer;
-
- if (bufferToUse.SubstringEquals(originalPath))
- {
- // Use the original path to avoid allocating
- return originalPath;
- }
-
- return bufferToUse.ToString();
- }
- }
-#else // !FEATURE_IMPLICIT_LONGPATH
-
- private static uint GetInputBuffer(StringBuffer content, bool isDosUnc, out StringBuffer buffer)
- {
- uint length = content.Length;
-
- length += isDosUnc
- ? (uint)PathInternal.UncExtendedPrefixLength - PathInternal.UncPrefixLength
- : PathInternal.DevicePrefixLength;
-
- buffer = new StringBuffer(length);
-
- if (isDosUnc)
- {
- // Put the extended UNC prefix (\\?\UNC\) in front of the path
- buffer.CopyFrom(bufferIndex: 0, source: PathInternal.UncExtendedPathPrefix);
-
- // Copy the source buffer over after the existing UNC prefix
- content.CopyTo(
- bufferIndex: PathInternal.UncPrefixLength,
- destination: buffer,
- destinationIndex: PathInternal.UncExtendedPrefixLength,
- count: content.Length - PathInternal.UncPrefixLength);
-
- // Return the prefix difference
- return (uint)PathInternal.UncExtendedPrefixLength - PathInternal.UncPrefixLength;
- }
- else
- {
- uint prefixSize = (uint)PathInternal.ExtendedPathPrefix.Length;
- buffer.CopyFrom(bufferIndex: 0, source: PathInternal.ExtendedPathPrefix);
- content.CopyTo(bufferIndex: 0, destination: buffer, destinationIndex: prefixSize, count: content.Length);
- return prefixSize;
- }
- }
-
- [System.Security.SecuritySafeCritical]
- private static string TryExpandShortFileName(StringBuffer outputBuffer, string originalPath)
- {
- // We'll have one of a few cases by now (the normalized path will have already:
- //
- // 1. Dos path (C:\)
- // 2. Dos UNC (\\Server\Share)
- // 3. Dos device path (\\.\C:\, \\?\C:\)
- //
- // We want to put the extended syntax on the front if it doesn't already have it, which may mean switching from \\.\.
-
- uint rootLength = PathInternal.GetRootLength(outputBuffer);
- bool isDevice = PathInternal.IsDevice(outputBuffer);
-
- StringBuffer inputBuffer = null;
- bool isDosUnc = false;
- uint rootDifference = 0;
- bool wasDotDevice = false;
-
- // Add the extended prefix before expanding to allow growth over MAX_PATH
- if (isDevice)
- {
- // We have one of the following (\\?\ or \\.\)
- // We will never get \??\ here as GetFullPathName() does not recognize \??\ and will return it as C:\??\ (or whatever the current drive is).
- inputBuffer = new StringBuffer();
- inputBuffer.Append(outputBuffer);
-
- if (outputBuffer[2] == '.')
- {
- wasDotDevice = true;
- inputBuffer[2] = '?';
- }
- }
- else
- {
- // \\Server\Share, but not \\.\ or \\?\.
- // We need to know this to be able to push \\?\UNC\ on if required
- isDosUnc = outputBuffer.Length > 1 && outputBuffer[0] == '\\' && outputBuffer[1] == '\\' && !PathInternal.IsDevice(outputBuffer);
- rootDifference = GetInputBuffer(outputBuffer, isDosUnc, out inputBuffer);
- }
-
- rootLength += rootDifference;
- uint inputLength = inputBuffer.Length;
-
- bool success = false;
- uint foundIndex = inputBuffer.Length - 1;
-
- while (!success)
- {
- uint result = Win32Native.GetLongPathNameW(inputBuffer.GetHandle(), outputBuffer.GetHandle(), outputBuffer.CharCapacity);
-
- // Replace any temporary null we added
- if (inputBuffer[foundIndex] == '\0') inputBuffer[foundIndex] = '\\';
-
- if (result == 0)
- {
- // Look to see if we couldn't find the file
- int error = Marshal.GetLastWin32Error();
- if (error != Win32Native.ERROR_FILE_NOT_FOUND && error != Win32Native.ERROR_PATH_NOT_FOUND)
- {
- // Some other failure, give up
- break;
- }
-
- // We couldn't find the path at the given index, start looking further back in the string.
- foundIndex--;
-
- for (; foundIndex > rootLength && inputBuffer[foundIndex] != '\\'; foundIndex--) ;
- if (foundIndex == rootLength)
- {
- // Can't trim the path back any further
- break;
- }
- else
- {
- // Temporarily set a null in the string to get Windows to look further up the path
- inputBuffer[foundIndex] = '\0';
- }
- }
- else if (result > outputBuffer.CharCapacity)
- {
- // Not enough space. The result count for this API does not include the null terminator.
- outputBuffer.EnsureCharCapacity(result);
- result = Win32Native.GetLongPathNameW(inputBuffer.GetHandle(), outputBuffer.GetHandle(), outputBuffer.CharCapacity);
- }
- else
- {
- // Found the path
- success = true;
- outputBuffer.Length = result;
- if (foundIndex < inputLength - 1)
- {
- // It was a partial find, put the non-existent part of the path back
- outputBuffer.Append(inputBuffer, foundIndex, inputBuffer.Length - foundIndex);
- }
- }
- }
-
- // Strip out the prefix and return the string
- StringBuffer bufferToUse = success ? outputBuffer : inputBuffer;
-
- // Switch back from \\?\ to \\.\ if necessary
- if (wasDotDevice)
- bufferToUse[2] = '.';
-
- string returnValue = null;
-
- int newLength = (int)(bufferToUse.Length - rootDifference);
- if (isDosUnc)
- {
- // Need to go from \\?\UNC\ to \\?\UN\\
- bufferToUse[PathInternal.UncExtendedPrefixLength - PathInternal.UncPrefixLength] = '\\';
- }
-
- // We now need to strip out any added characters at the front of the string
- if (bufferToUse.SubstringEquals(originalPath, rootDifference, newLength))
- {
- // Use the original path to avoid allocating
- returnValue = originalPath;
- }
- else
- {
- returnValue = bufferToUse.Substring(rootDifference, newLength);
- }
-
- inputBuffer.Dispose();
- return returnValue;
- }
-#endif // FEATURE_IMPLICIT_LONGPATH
- }
-} \ No newline at end of file
diff --git a/src/mscorlib/src/System/IO/MemoryStream.cs b/src/mscorlib/src/System/IO/MemoryStream.cs
index edb583b9b5..bdddc83818 100644
--- a/src/mscorlib/src/System/IO/MemoryStream.cs
+++ b/src/mscorlib/src/System/IO/MemoryStream.cs
@@ -19,6 +19,7 @@ using System;
using System.Runtime;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Threading;
using System.Threading.Tasks;
@@ -61,7 +62,7 @@ namespace System.IO {
public MemoryStream(int capacity) {
if (capacity < 0) {
- throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_NegativeCapacity"));
+ throw new ArgumentOutOfRangeException(nameof(capacity), Environment.GetResourceString("ArgumentOutOfRange_NegativeCapacity"));
}
Contract.EndContractBlock();
@@ -79,7 +80,7 @@ namespace System.IO {
}
public MemoryStream(byte[] buffer, bool writable) {
- if (buffer == null) throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ if (buffer == null) throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
Contract.EndContractBlock();
_buffer = buffer;
_length = _capacity = buffer.Length;
@@ -99,11 +100,11 @@ namespace System.IO {
public MemoryStream(byte[] buffer, int index, int count, bool writable, bool publiclyVisible) {
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (index < 0)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -180,7 +181,6 @@ namespace System.IO {
public override void Flush() {
}
- [HostProtection(ExternalThreading=true)]
[ComVisible(false)]
public override Task FlushAsync(CancellationToken cancellationToken) {
@@ -259,7 +259,7 @@ namespace System.IO {
if (n > count) n = count;
if (n < 0) n = 0;
- Contract.Assert(_position + n >= 0, "_position + n >= 0"); // len is less than 2^31 -1.
+ Debug.Assert(_position + n >= 0, "_position + n >= 0"); // len is less than 2^31 -1.
_position += n;
return n;
}
@@ -276,7 +276,7 @@ namespace System.IO {
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("value", Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
+ if (value < Length) throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
Contract.Ensures(_capacity - _origin == value);
Contract.EndContractBlock();
@@ -312,25 +312,25 @@ namespace System.IO {
}
set {
if (value < 0)
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.Ensures(Position == value);
Contract.EndContractBlock();
if (!_isOpen) __Error.StreamIsClosed();
if (value > MemStreamMaxLength)
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_StreamLength"));
+ throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_StreamLength"));
_position = _origin + (int)value;
}
}
public override int Read([In, Out] byte[] buffer, int offset, int count) {
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - offset < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -342,7 +342,7 @@ namespace System.IO {
if (n <= 0)
return 0;
- Contract.Assert(_position + n >= 0, "_position + n >= 0"); // len is less than 2^31 -1.
+ Debug.Assert(_position + n >= 0, "_position + n >= 0"); // len is less than 2^31 -1.
if (n <= 8)
{
@@ -357,16 +357,15 @@ namespace System.IO {
return n;
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public override Task<int> ReadAsync(Byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - offset < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock(); // contract validation copied from Read(...)
@@ -379,7 +378,7 @@ namespace System.IO {
{
int n = Read(buffer, offset, count);
var t = _lastReadTask;
- Contract.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));
}
@@ -402,36 +401,46 @@ namespace System.IO {
return _buffer[_position++];
}
+ public override void CopyTo(Stream destination, int bufferSize)
+ {
+ // Since we did not originally override this method, validate the arguments
+ // the same way Stream does for back-compat.
+ StreamHelpers.ValidateCopyToArgs(this, destination, bufferSize);
- public override Task CopyToAsync(Stream destination, Int32 bufferSize, CancellationToken cancellationToken) {
-
- // This implementation offers beter performance compared to the base class version.
-
- // The parameter checks must be in sync with the base version:
- if (destination == null)
- throw new ArgumentNullException("destination");
+ // If we have been inherited into a subclass, the following implementation could be incorrect
+ // since it does not call through to Read() which a subclass might have overridden.
+ // To be safe we will only use this implementation in cases where we know it is safe to do so,
+ // and delegate to our base class (which will call into Read) when we are not sure.
+ if (GetType() != typeof(MemoryStream))
+ {
+ base.CopyTo(destination, bufferSize);
+ return;
+ }
- if (bufferSize <= 0)
- throw new ArgumentOutOfRangeException("bufferSize", Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
+ int originalPosition = _position;
- if (!CanRead && !CanWrite)
- throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_StreamClosed"));
+ // Seek to the end of the MemoryStream.
+ int remaining = InternalEmulateRead(_length - originalPosition);
- if (!destination.CanRead && !destination.CanWrite)
- throw new ObjectDisposedException("destination", Environment.GetResourceString("ObjectDisposed_StreamClosed"));
+ // If we were already at or past the end, there's no copying to do so just quit.
+ if (remaining > 0)
+ {
+ // Call Write() on the other Stream, using our internal buffer and avoiding any
+ // intermediary allocations.
+ destination.Write(_buffer, originalPosition, remaining);
+ }
+ }
- if (!CanRead)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnreadableStream"));
+ public override Task CopyToAsync(Stream destination, Int32 bufferSize, CancellationToken cancellationToken) {
- if (!destination.CanWrite)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnwritableStream"));
+ // This implementation offers beter performance compared to the base class version.
- Contract.EndContractBlock();
+ StreamHelpers.ValidateCopyToArgs(this, destination, bufferSize);
// If we have been inherited into a subclass, the following implementation could be incorrect
- // since it does not call through to Read() or Write() which a subclass might have overriden.
+ // since it does not call through to ReadAsync() which a subclass might have overridden.
// To be safe we will only use this implementation in cases where we know it is safe to do so,
- // and delegate to our base class (which will call into Read/Write) when we are not sure.
+ // and delegate to our base class (which will call into ReadAsync) when we are not sure.
if (this.GetType() != typeof(MemoryStream))
return base.CopyToAsync(destination, bufferSize, cancellationToken);
@@ -467,7 +476,7 @@ namespace System.IO {
if (!_isOpen) __Error.StreamIsClosed();
if (offset > MemStreamMaxLength)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_StreamLength"));
+ throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_StreamLength"));
switch(loc) {
case SeekOrigin.Begin: {
int tempPosition = unchecked(_origin + (int)offset);
@@ -494,7 +503,7 @@ namespace System.IO {
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidSeekOrigin"));
}
- Contract.Assert(_position >= 0, "_position >= 0");
+ Debug.Assert(_position >= 0, "_position >= 0");
return _position;
}
@@ -510,16 +519,16 @@ namespace System.IO {
//
public override void SetLength(long value) {
if (value < 0 || value > Int32.MaxValue) {
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_StreamLength"));
+ throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_StreamLength"));
}
Contract.Ensures(_length - _origin == value);
Contract.EndContractBlock();
EnsureWriteable();
// Origin wasn't publicly exposed above.
- Contract.Assert(MemStreamMaxLength == Int32.MaxValue); // Check parameter validation logic in this method if this fails.
+ Debug.Assert(MemStreamMaxLength == Int32.MaxValue); // Check parameter validation logic in this method if this fails.
if (value > (Int32.MaxValue - _origin)) {
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_StreamLength"));
+ throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_StreamLength"));
}
int newLength = _origin + (int)value;
@@ -540,11 +549,11 @@ namespace System.IO {
public override void Write(byte[] buffer, int offset, int count) {
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - offset < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -580,16 +589,15 @@ namespace System.IO {
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public override Task WriteAsync(Byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
if (buffer == null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - offset < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock(); // contract validation copied from Write(...)
@@ -636,7 +644,7 @@ namespace System.IO {
// Writes this MemoryStream to another stream.
public virtual void WriteTo(Stream stream) {
if (stream==null)
- throw new ArgumentNullException("stream", Environment.GetResourceString("ArgumentNull_Stream"));
+ throw new ArgumentNullException(nameof(stream), Environment.GetResourceString("ArgumentNull_Stream"));
Contract.EndContractBlock();
if (!_isOpen) __Error.StreamIsClosed();
diff --git a/src/mscorlib/src/System/IO/Path.cs b/src/mscorlib/src/System/IO/Path.cs
deleted file mode 100644
index 4f7993633b..0000000000
--- a/src/mscorlib/src/System/IO/Path.cs
+++ /dev/null
@@ -1,1435 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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 collection of path manipulation methods.
-**
-**
-===========================================================*/
-
-using System;
-using System.Security.Permissions;
-using Win32Native = Microsoft.Win32.Win32Native;
-using System.Text;
-using System.Runtime.InteropServices;
-using System.Security;
-#if FEATURE_LEGACYSURFACE
-using System.Security.Cryptography;
-#endif
-using System.Runtime.CompilerServices;
-using System.Globalization;
-using System.Runtime.Versioning;
-using System.Diagnostics.Contracts;
-
-namespace System.IO {
- // Provides methods for processing directory strings in an ideally
- // cross-platform manner. Most of the methods don't do a complete
- // full parsing (such as examining a UNC hostname), but they will
- // handle most string operations.
- [ComVisible(true)]
- public static class Path
- {
- // Platform specific directory separator character. This is backslash
- // ('\') on Windows and slash ('/') on Unix.
- //
-#if !PLATFORM_UNIX
- public static readonly char DirectorySeparatorChar = '\\';
- internal const string DirectorySeparatorCharAsString = "\\";
-#else
- public static readonly char DirectorySeparatorChar = '/';
- internal const string DirectorySeparatorCharAsString = "/";
-#endif // !PLATFORM_UNIX
-
- // Platform specific alternate directory separator character.
- // There is only one directory separator char on Unix,
- // so the same definition is used for both Unix and Windows.
- public static readonly char AltDirectorySeparatorChar = '/';
-
- // Platform specific volume separator character. This is colon (':')
- // on Windows and MacOS, and slash ('/') on Unix. This is mostly
- // useful for parsing paths like "c:\windows" or "MacVolume:System Folder".
- //
-#if !PLATFORM_UNIX
- public static readonly char VolumeSeparatorChar = ':';
-#else
- public static readonly char VolumeSeparatorChar = '/';
-#endif // !PLATFORM_UNIX
-
- // Platform specific invalid list of characters in a path.
- // See the "Naming a File" MSDN conceptual docs for more details on
- // what is valid in a file name (which is slightly different from what
- // is legal in a path name).
- // Note: This list is duplicated in CheckInvalidPathChars
- [Obsolete("Please use GetInvalidPathChars or GetInvalidFileNameChars instead.")]
-#if !PLATFORM_UNIX
- public static readonly char[] InvalidPathChars = { '\"', '<', '>', '|', '\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 };
-#else
- public static readonly char[] InvalidPathChars = { '\0' };
-#endif // !PLATFORM_UNIX
-
- // Trim trailing white spaces, tabs etc but don't be aggressive in removing everything that has UnicodeCategory of trailing space.
- // String.WhitespaceChars will trim aggressively than what the underlying FS does (for ex, NTFS, FAT).
- internal static readonly char[] TrimEndChars =
- {
- (char)0x09, // Horizontal tab
- (char)0x0A, // Line feed
- (char)0x0B, // Vertical tab
- (char)0x0C, // Form feed
- (char)0x0D, // Carriage return
- (char)0x20, // Space
- (char)0x85, // Next line
- (char)0xA0 // Non breaking space
- };
-
-#if !PLATFORM_UNIX
- private static readonly char[] RealInvalidPathChars = PathInternal.InvalidPathChars;
-
- private static readonly char[] InvalidFileNameChars = { '\"', '<', '>', '|', '\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, ':', '*', '?', '\\', '/' };
-#else
- private static readonly char[] RealInvalidPathChars = { '\0' };
-
- private static readonly char[] InvalidFileNameChars = { '\0', '/' };
-#endif // !PLATFORM_UNIX
-
-#if !PLATFORM_UNIX
- public static readonly char PathSeparator = ';';
-#else
- public static readonly char PathSeparator = ':';
-#endif // !PLATFORM_UNIX
-
-
- // 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 static readonly int MaxPath = PathInternal.MaxShortPath;
-
- internal static readonly int MaxPathComponentLength = PathInternal.MaxComponentLength;
-
- // Windows API definitions
- internal const int MAX_PATH = 260; // From WinDef.h
- internal const int MAX_DIRECTORY_PATH = 248; // cannot create directories greater than 248 characters
-
- // 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 exsiting extension is removed from path.
- //
- public static String ChangeExtension(String path, String extension) {
- if (path != null) {
- CheckInvalidPathChars(path);
-
- String s = path;
- for (int i = path.Length; --i >= 0;) {
- char ch = path[i];
- if (ch == '.') {
- s = path.Substring(0, i);
- break;
- }
- if (ch == DirectorySeparatorChar || ch == AltDirectorySeparatorChar || ch == VolumeSeparatorChar) break;
- }
- if (extension != null && path.Length != 0) {
- if (extension.Length == 0 || extension[0] != '.') {
- s = s + ".";
- }
- s = 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)
- {
- return GetDirectoryNameInternal(path);
- }
-
- [System.Security.SecuritySafeCritical]
- private static string GetDirectoryNameInternal(string path)
- {
- if (path != null)
- {
- CheckInvalidPathChars(path);
-
- // Expanding short paths is dangerous in this case as the results will change with the current directory.
- //
- // Suppose you have a path called "PICTUR~1\Foo". Now suppose you have two folders on disk "C:\Mine\Pictures Of Me"
- // and "C:\Yours\Pictures of You". If the current directory is neither you'll get back "PICTUR~1". If it is "C:\Mine"
- // get back "Pictures Of Me". "C:\Yours" would give back "Pictures of You".
- //
- // Because of this and as it isn't documented that short paths are expanded we will not expand short names unless
- // we're in legacy mode.
- string normalizedPath = NormalizePath(path, fullCheck: false, expandShortPaths:
-#if FEATURE_PATHCOMPAT
- AppContextSwitches.UseLegacyPathHandling
-#else
- false
-#endif
- );
-
- // If there are no permissions for PathDiscovery to this path, we should NOT expand the short paths
- // as this would leak information about paths to which the user would not have access to.
- if (path.Length > 0
-#if FEATURE_CAS_POLICY
- // Only do the extra logic if we're not in full trust
- && !CodeAccessSecurityEngine.QuickCheckForAllDemands()
-#endif
- )
- {
- try
- {
- // If we were passed in a path with \\?\ we need to remove it as FileIOPermission does not like it.
- string tempPath = RemoveLongPathPrefix(path);
-
- // FileIOPermission cannot handle paths that contain ? or *
- // So we only pass to FileIOPermission the text up to them.
- int pos = 0;
- while (pos < tempPath.Length && (tempPath[pos] != '?' && tempPath[pos] != '*'))
- pos++;
-
- // GetFullPath will Demand that we have the PathDiscovery FileIOPermission and thus throw
- // SecurityException if we don't.
- // While we don't use the result of this call we are using it as a consistent way of
- // doing the security checks.
- if (pos > 0)
- GetFullPath(tempPath.Substring(0, pos));
- }
- catch (SecurityException)
- {
- // If the user did not have permissions to the path, make sure that we don't leak expanded short paths
- // Only re-normalize if the original path had a ~ in it.
- if (path.IndexOf("~", StringComparison.Ordinal) != -1)
- {
- normalizedPath = NormalizePath(path, fullCheck: false, expandShortPaths: false);
- }
- }
- catch (PathTooLongException) { }
- catch (NotSupportedException) { } // Security can throw this on "c:\foo:"
- catch (IOException) { }
- catch (ArgumentException) { } // The normalizePath with fullCheck will throw this for file: and http:
- }
-
- path = normalizedPath;
-
- int root = GetRootLength(path);
- int i = path.Length;
- if (i > root)
- {
- i = path.Length;
- if (i == root) return null;
- while (i > root && path[--i] != DirectorySeparatorChar && path[i] != AltDirectorySeparatorChar);
- return path.Substring(0, i);
- }
- }
- return null;
- }
-
- // Gets the length of the root DirectoryInfo or whatever DirectoryInfo markers
- // are specified for the first part of the DirectoryInfo name.
- //
- internal static int GetRootLength(string path)
- {
- CheckInvalidPathChars(path);
-
-#if !PLATFORM_UNIX && FEATURE_PATHCOMPAT
- if (AppContextSwitches.UseLegacyPathHandling)
- {
- int i = 0;
- int length = path.Length;
-
- if (length >= 1 && (IsDirectorySeparator(path[0])))
- {
- // handles UNC names and directories off current drive's root.
- i = 1;
- if (length >= 2 && (IsDirectorySeparator(path[1])))
- {
- i = 2;
- int n = 2;
- while (i < length && ((path[i] != DirectorySeparatorChar && path[i] != AltDirectorySeparatorChar) || --n > 0)) i++;
- }
- }
- else if (length >= 2 && path[1] == VolumeSeparatorChar)
- {
- // handles A:\foo.
- i = 2;
- if (length >= 3 && (IsDirectorySeparator(path[2]))) i++;
- }
- return i;
- }
- else
-#endif // !PLATFORM_UNIX && FEATURE_PATHCOMPAT
- {
- return PathInternal.GetRootLength(path);
- }
- }
-
- internal static bool IsDirectorySeparator(char c) {
- return (c==DirectorySeparatorChar || c == AltDirectorySeparatorChar);
- }
-
- public static char[] GetInvalidPathChars()
- {
- return (char[]) RealInvalidPathChars.Clone();
- }
-
- public static char[] GetInvalidFileNameChars()
- {
- return (char[]) InvalidFileNameChars.Clone();
- }
-
- // 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;
-
- CheckInvalidPathChars(path);
- int length = path.Length;
- for (int i = length; --i >= 0;) {
- char ch = path[i];
- if (ch == '.')
- {
- if (i != length - 1)
- return path.Substring(i, length - i);
- else
- return String.Empty;
- }
- if (ch == DirectorySeparatorChar || ch == AltDirectorySeparatorChar || ch == VolumeSeparatorChar)
- break;
- }
- return String.Empty;
- }
-
- // Expands the given path to a fully qualified path. The resulting string
- // consists of a drive letter, a colon, and a root relative path. This
- // function does not verify that the resulting path
- // refers to an existing file or directory on the associated volume.
- [Pure]
- [System.Security.SecuritySafeCritical]
- public static String GetFullPath(String path) {
- String fullPath = GetFullPathInternal(path);
-#if FEATURE_CORECLR
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.PathDiscovery, path, fullPath);
- state.EnsureState();
-#else
- FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, fullPath, false, false);
-#endif
- return fullPath;
- }
-
- [System.Security.SecurityCritical]
- internal static String UnsafeGetFullPath(String path)
- {
- String fullPath = GetFullPathInternal(path);
-#if !FEATURE_CORECLR
- FileIOPermission.QuickDemand(FileIOPermissionAccess.PathDiscovery, fullPath, false, false);
-#endif
- return fullPath;
- }
-
- // This method is package access to let us quickly get a string name
- // while avoiding a security check. This also serves a slightly
- // different purpose - when we open a file, we need to resolve the
- // path into a fully qualified, non-relative path name. This
- // method does that, finding the current drive &; directory. But
- // as long as we don't return this info to the user, we're good. However,
- // the public GetFullPath does need to do a security check.
- internal static string GetFullPathInternal(string path)
- {
- if (path == null)
- throw new ArgumentNullException("path");
- Contract.EndContractBlock();
-
- string newPath = NormalizePath(path, fullCheck: true);
- return newPath;
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- internal unsafe static string NormalizePath(string path, bool fullCheck)
- {
- return NormalizePath(path, fullCheck,
-#if FEATURE_PATHCOMPAT
- AppContextSwitches.BlockLongPaths ? PathInternal.MaxShortPath :
-#endif
- PathInternal.MaxLongPath);
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- internal unsafe static string NormalizePath(string path, bool fullCheck, bool expandShortPaths)
- {
- return NormalizePath(path, fullCheck,
-#if FEATURE_PATHCOMPAT
- AppContextSwitches.BlockLongPaths ? PathInternal.MaxShortPath :
-#endif
- PathInternal.MaxLongPath,
- expandShortPaths);
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- internal static string NormalizePath(string path, bool fullCheck, int maxPathLength)
- {
- return NormalizePath(path, fullCheck, maxPathLength, expandShortPaths: true);
- }
-
- [System.Security.SecuritySafeCritical]
- internal static string NormalizePath(string path, bool fullCheck, int maxPathLength, bool expandShortPaths)
- {
-#if FEATURE_PATHCOMPAT
- if (AppContextSwitches.UseLegacyPathHandling)
- {
- return LegacyNormalizePath(path, fullCheck, maxPathLength, expandShortPaths);
- }
- else
-#endif // FEATURE_APPCOMPAT
- {
- 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;
- }
-
- string normalizedPath = null;
-
- if (fullCheck == false)
- {
- // Disabled fullCheck is only called by GetDirectoryName and GetPathRoot.
- // Avoid adding addtional callers and try going direct to lighter weight NormalizeDirectorySeparators.
- normalizedPath = NewNormalizePathLimitedChecks(path, maxPathLength, expandShortPaths);
- }
- else
- {
- normalizedPath = NewNormalizePath(path, maxPathLength, expandShortPaths: true);
- }
-
- if (string.IsNullOrWhiteSpace(normalizedPath))
- throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal"));
- return normalizedPath;
- }
- }
-
- [System.Security.SecuritySafeCritical]
- private static string NewNormalizePathLimitedChecks(string path, int maxPathLength, bool expandShortPaths)
- {
- string normalized = PathInternal.NormalizeDirectorySeparators(path);
-
- if (PathInternal.IsPathTooLong(normalized) || PathInternal.AreSegmentsTooLong(normalized))
- throw new PathTooLongException();
-
-#if !PLATFORM_UNIX
- if (!PathInternal.IsDevice(normalized) && PathInternal.HasInvalidVolumeSeparator(path))
- throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal"));
-
- if (expandShortPaths && normalized.IndexOf('~') != -1)
- {
- try
- {
- return LongPathHelper.GetLongPathName(normalized);
- }
- catch
- {
- // Don't care if we can't get the long path- might not exist, etc.
- }
- }
-#endif
-
- return normalized;
- }
-
- /// <summary>
- /// Normalize the path and check for bad characters or other invalid syntax.
- /// </summary>
- [System.Security.SecuritySafeCritical]
- [ResourceExposure(ResourceScope.Machine)]
- [ResourceConsumption(ResourceScope.Machine)]
- private static string NewNormalizePath(string path, int maxPathLength, bool expandShortPaths)
- {
- Contract.Requires(path != null, "path can't be null");
-
- // 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(Environment.GetResourceString("Argument_InvalidPathChars"));
-
-#if !PLATFORM_UNIX
- // Note that colon and wildcard checks happen in FileIOPermissions
-
- // Technically this doesn't matter but we used to throw for this case
- if (string.IsNullOrWhiteSpace(path))
- throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal"));
-
- // We don't want to check invalid characters for device format- see comments for extended above
- return LongPathHelper.Normalize(path, (uint)maxPathLength, checkInvalidCharacters: !PathInternal.IsDevice(path), expandShortPaths: expandShortPaths);
-#else
- if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal"));
-
- // Expand with current directory if necessary
- if (!IsPathRooted(path))
- path = Combine(Directory.GetCurrentDirectory(), 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 = PathInternal.RemoveRelativeSegments(path);
-
- if (collapsedString.Length > maxPathLength)
- throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
-
- return collapsedString.Length == 0 ? "/" : collapsedString;
-#endif // PLATFORM_UNIX
- }
-
-#if FEATURE_PATHCOMPAT
- [System.Security.SecurityCritical] // auto-generated
- internal unsafe static String LegacyNormalizePath(String path, bool fullCheck, int maxPathLength, bool expandShortPaths) {
-
- Contract.Requires(path != null, "path can't be null");
- // If we're doing a full path check, trim whitespace and look for
- // illegal path characters.
- if (fullCheck) {
- // Trim whitespace off the end of the string.
- // Win32 normalization trims only U+0020.
- path = path.TrimEnd(TrimEndChars);
-
- // Look for illegal path characters.
- if (PathInternal.AnyPathHasIllegalCharacters(path))
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidPathChars"));
- }
-
- int index = 0;
- // We prefer to allocate on the stack for workingset/perf gain. If the
- // starting path is less than MaxPath then we can stackalloc; otherwise we'll
- // use a StringBuilder (PathHelper does this under the hood). The latter may
- // happen in 2 cases:
- // 1. Starting path is greater than MaxPath but it normalizes down to MaxPath.
- // This is relevant for paths containing escape sequences. In this case, we
- // attempt to normalize down to MaxPath, but the caller pays a perf penalty
- // since StringBuilder is used.
- // 2. IsolatedStorage, which supports paths longer than MaxPath (value given
- // by maxPathLength.
- PathHelper newBuffer;
- if (path.Length + 1 <= MaxPath) {
- char* m_arrayPtr = stackalloc char[MaxPath];
- newBuffer = new PathHelper(m_arrayPtr, MaxPath);
- } else {
- newBuffer = new PathHelper(path.Length + Path.MaxPath, maxPathLength);
- }
-
- uint numSpaces = 0;
- uint numDots = 0;
- bool fixupDirectorySeparator = false;
- // Number of significant chars other than potentially suppressible
- // dots and spaces since the last directory or volume separator char
- uint numSigChars = 0;
- int lastSigChar = -1; // Index of last significant character.
- // Whether this segment of the path (not the complete path) started
- // with a volume separator char. Reject "c:...".
- bool startedWithVolumeSeparator = false;
- bool firstSegment = true;
- int lastDirectorySeparatorPos = 0;
-
-#if !PLATFORM_UNIX
- bool mightBeShortFileName = false;
-
- // LEGACY: This code is here for backwards compatibility reasons. It
- // ensures that \\foo.cs\bar.cs stays \\foo.cs\bar.cs instead of being
- // turned into \foo.cs\bar.cs.
- if (path.Length > 0 && (path[0] == DirectorySeparatorChar || path[0] == AltDirectorySeparatorChar)) {
- newBuffer.Append('\\');
- index++;
- lastSigChar = 0;
- }
-#endif
-
- // Normalize the string, stripping out redundant dots, spaces, and
- // slashes.
- while (index < path.Length) {
- char currentChar = path[index];
-
- // We handle both directory separators and dots specially. For
- // directory separators, we consume consecutive appearances.
- // For dots, we consume all dots beyond the second in
- // succession. All other characters are added as is. In
- // addition we consume all spaces after the last other char
- // in a directory name up until the directory separator.
-
- if (currentChar == DirectorySeparatorChar || currentChar == AltDirectorySeparatorChar) {
- // If we have a path like "123.../foo", remove the trailing dots.
- // However, if we found "c:\temp\..\bar" or "c:\temp\...\bar", don't.
- // Also remove trailing spaces from both files & directory names.
- // This was agreed on with the OS team to fix undeletable directory
- // names ending in spaces.
-
- // If we saw a '\' as the previous last significant character and
- // are simply going to write out dots, suppress them.
- // If we only contain dots and slashes though, only allow
- // a string like [dot]+ [space]*. Ignore everything else.
- // Legal: "\.. \", "\...\", "\. \"
- // Illegal: "\.. .\", "\. .\", "\ .\"
- if (numSigChars == 0) {
- // Dot and space handling
- if (numDots > 0) {
- // Look for ".[space]*" or "..[space]*"
- int start = lastSigChar + 1;
- if (path[start] != '.')
- throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal"));
-
- // Only allow "[dot]+[space]*", and normalize the
- // legal ones to "." or ".."
- if (numDots >= 2) {
- // Reject "C:..."
- if (startedWithVolumeSeparator && numDots > 2)
-
- throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal"));
-
- if (path[start + 1] == '.') {
- // Search for a space in the middle of the
- // dots and throw
- for(int i=start + 2; i < start + numDots; i++) {
- if (path[i] != '.')
- throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal"));
- }
-
- numDots = 2;
- }
- else {
- if (numDots > 1)
- throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal"));
- numDots = 1;
- }
- }
-
- if (numDots == 2) {
- newBuffer.Append('.');
- }
-
- newBuffer.Append('.');
- fixupDirectorySeparator = false;
-
- // Continue in this case, potentially writing out '\'.
- }
-
- if (numSpaces > 0 && firstSegment) {
- // Handle strings like " \\server\share".
- if (index + 1 < path.Length &&
- (path[index + 1] == DirectorySeparatorChar || path[index + 1] == AltDirectorySeparatorChar))
- {
- newBuffer.Append(DirectorySeparatorChar);
- }
- }
- }
- numDots = 0;
- numSpaces = 0; // Suppress trailing spaces
-
- if (!fixupDirectorySeparator) {
- fixupDirectorySeparator = true;
- newBuffer.Append(DirectorySeparatorChar);
- }
- numSigChars = 0;
- lastSigChar = index;
- startedWithVolumeSeparator = false;
- firstSegment = false;
-
-#if !PLATFORM_UNIX
- // For short file names, we must try to expand each of them as
- // soon as possible. We need to allow people to specify a file
- // name that doesn't exist using a path with short file names
- // in it, such as this for a temp file we're trying to create:
- // C:\DOCUME~1\USERNA~1.RED\LOCALS~1\Temp\bg3ylpzp
- // We could try doing this afterwards piece by piece, but it's
- // probably a lot simpler to do it here.
- if (mightBeShortFileName) {
- newBuffer.TryExpandShortFileName();
- mightBeShortFileName = false;
- }
-#endif
- int thisPos = newBuffer.Length - 1;
- if (thisPos - lastDirectorySeparatorPos > MaxPathComponentLength)
- {
- throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
- }
- lastDirectorySeparatorPos = thisPos;
- } // if (Found directory separator)
- else if (currentChar == '.') {
- // Reduce only multiple .'s only after slash to 2 dots. For
- // instance a...b is a valid file name.
- numDots++;
- // Don't flush out non-terminal spaces here, because they may in
- // the end not be significant. Turn "c:\ . .\foo" -> "c:\foo"
- // which is the conclusion of removing trailing dots & spaces,
- // as well as folding multiple '\' characters.
- }
- else if (currentChar == ' ') {
- numSpaces++;
- }
- else { // Normal character logic
-#if !PLATFORM_UNIX
- if (currentChar == '~' && expandShortPaths)
- mightBeShortFileName = true;
-#endif
-
- fixupDirectorySeparator = false;
-
-#if !PLATFORM_UNIX
- // To reject strings like "C:...\foo" and "C :\foo"
- if (firstSegment && currentChar == VolumeSeparatorChar) {
- // Only accept "C:", not "c :" or ":"
- // Get a drive letter or ' ' if index is 0.
- char driveLetter = (index > 0) ? path[index-1] : ' ';
- bool validPath = ((numDots == 0) && (numSigChars >= 1) && (driveLetter != ' '));
- if (!validPath)
- throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal"));
-
- startedWithVolumeSeparator = true;
- // We need special logic to make " c:" work, we should not fix paths like " foo::$DATA"
- if (numSigChars > 1) { // Common case, simply do nothing
- int spaceCount = 0; // How many spaces did we write out, numSpaces has already been reset.
- while((spaceCount < newBuffer.Length) && newBuffer[spaceCount] == ' ')
- spaceCount++;
- if (numSigChars - spaceCount == 1) {
- //Safe to update stack ptr directly
- newBuffer.Length = 0;
- newBuffer.Append(driveLetter); // Overwrite spaces, we need a special case to not break " foo" as a relative path.
- }
- }
- numSigChars = 0;
- }
- else
-#endif // !PLATFORM_UNIX
- {
- numSigChars += 1 + numDots + numSpaces;
- }
-
- // Copy any spaces & dots since the last significant character
- // to here. Note we only counted the number of dots & spaces,
- // and don't know what order they're in. Hence the copy.
- if (numDots > 0 || numSpaces > 0) {
- int numCharsToCopy = (lastSigChar >= 0) ? index - lastSigChar - 1 : index;
- if (numCharsToCopy > 0) {
- for (int i=0; i<numCharsToCopy; i++) {
- newBuffer.Append(path[lastSigChar + 1 + i]);
- }
- }
- numDots = 0;
- numSpaces = 0;
- }
-
- newBuffer.Append(currentChar);
- lastSigChar = index;
- }
-
- index++;
- } // end while
-
- if (newBuffer.Length - 1 - lastDirectorySeparatorPos > MaxPathComponentLength)
- {
- throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
- }
-
- // Drop any trailing dots and spaces from file & directory names, EXCEPT
- // we MUST make sure that "C:\foo\.." is correctly handled.
- // Also handle "C:\foo\." -> "C:\foo", while "C:\." -> "C:\"
- if (numSigChars == 0) {
- if (numDots > 0) {
- // Look for ".[space]*" or "..[space]*"
- int start = lastSigChar + 1;
- if (path[start] != '.')
- throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal"));
-
- // Only allow "[dot]+[space]*", and normalize the
- // legal ones to "." or ".."
- if (numDots >= 2) {
- // Reject "C:..."
- if (startedWithVolumeSeparator && numDots > 2)
- throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal"));
-
- if (path[start + 1] == '.') {
- // Search for a space in the middle of the
- // dots and throw
- for(int i=start + 2; i < start + numDots; i++) {
- if (path[i] != '.')
- throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal"));
- }
-
- numDots = 2;
- }
- else {
- if (numDots > 1)
- throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal"));
- numDots = 1;
- }
- }
-
- if (numDots == 2) {
- newBuffer.Append('.');
- }
-
- newBuffer.Append('.');
- }
- } // if (numSigChars == 0)
-
- // If we ended up eating all the characters, bail out.
- if (newBuffer.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegal"));
-
- // Disallow URL's here. Some of our other Win32 API calls will reject
- // them later, so we might be better off rejecting them here.
- // Note we've probably turned them into "file:\D:\foo.tmp" by now.
- // But for compatibility, ensure that callers that aren't doing a
- // full check aren't rejected here.
- if (fullCheck) {
- if ( newBuffer.OrdinalStartsWith("http:", false) ||
- newBuffer.OrdinalStartsWith("file:", false))
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_PathUriFormatNotSupported"));
- }
- }
-
-#if !PLATFORM_UNIX
- // If the last part of the path (file or directory name) had a tilde,
- // expand that too.
- if (mightBeShortFileName) {
- newBuffer.TryExpandShortFileName();
- }
-#endif
-
- // Call the Win32 API to do the final canonicalization step.
- int result = 1;
-
- if (fullCheck) {
- // NOTE: Win32 GetFullPathName requires the input buffer to be big enough to fit the initial
- // path which is a concat of CWD and the relative path, this can be of an arbitrary
- // size and could be > MAX_PATH (which becomes an artificial limit at this point),
- // even though the final normalized path after fixing up the relative path syntax
- // might be well within the MAX_PATH restriction. For ex,
- // "c:\SomeReallyLongDirName(thinkGreaterThan_MAXPATH)\..\foo.txt" which actually requires a
- // buffer well with in the MAX_PATH as the normalized path is just "c:\foo.txt"
- // This buffer requirement seems wrong, it could be a bug or a perf optimization
- // like returning required buffer length quickly or avoid stratch buffer etc.
- // Ideally we would get the required buffer length first by calling GetFullPathName
- // once without the buffer and use that in the later call but this doesn't always work
- // due to Win32 GetFullPathName bug. For instance, in Win2k, when the path we are trying to
- // fully qualify is a single letter name (such as "a", "1", ",") GetFullPathName
- // fails to return the right buffer size (i.e, resulting in insufficient buffer).
- // To workaround this bug we will start with MAX_PATH buffer and grow it once if the
- // return value is > MAX_PATH.
-
- result = newBuffer.GetFullPathName();
-
-#if !PLATFORM_UNIX
- // If we called GetFullPathName with something like "foo" and our
- // command window was in short file name mode (ie, by running edlin or
- // DOS versions of grep, etc), we might have gotten back a short file
- // name. So, check to see if we need to expand it.
- mightBeShortFileName = false;
- for(int i=0; i < newBuffer.Length && !mightBeShortFileName; i++) {
- if (newBuffer[i] == '~' && expandShortPaths)
- mightBeShortFileName = true;
- }
-
- if (mightBeShortFileName) {
- bool r = newBuffer.TryExpandShortFileName();
- // Consider how the path "Doesn'tExist" would expand. If
- // we add in the current directory, it too will need to be
- // fully expanded, which doesn't happen if we use a file
- // name that doesn't exist.
- if (!r) {
- int lastSlash = -1;
-
- for (int i = newBuffer.Length - 1; i >= 0; i--) {
- if (newBuffer[i] == DirectorySeparatorChar) {
- lastSlash = i;
- break;
- }
- }
-
- if (lastSlash >= 0) {
-
- // This bounds check is for safe memcpy but we should never get this far
- if (newBuffer.Length >= maxPathLength)
- throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
-
- int lenSavedName = newBuffer.Length - lastSlash - 1;
- Contract.Assert(lastSlash < newBuffer.Length, "path unexpectedly ended in a '\'");
-
- newBuffer.Fixup(lenSavedName, lastSlash);
- }
- }
- }
-#endif // PLATFORM_UNIX
- }
-
- if (result != 0) {
- /* Throw an ArgumentException for paths like \\, \\server, \\server\
- This check can only be properly done after normalizing, so
- \\foo\.. will be properly rejected. Also, reject \\?\GLOBALROOT\
- (an internal kernel path) because it provides aliases for drives. */
- if (newBuffer.Length > 1 && newBuffer[0] == '\\' && newBuffer[1] == '\\') {
- int startIndex = 2;
- while (startIndex < result) {
- if (newBuffer[startIndex] == '\\') {
- startIndex++;
- break;
- }
- else {
- startIndex++;
- }
- }
- if (startIndex == result)
- throw new ArgumentException(Environment.GetResourceString("Arg_PathIllegalUNC"));
-
- // Check for \\?\Globalroot, an internal mechanism to the kernel
- // that provides aliases for drives and other undocumented stuff.
- // The kernel team won't even describe the full set of what
- // is available here - we don't want managed apps mucking
- // with this for security reasons.
- if ( newBuffer.OrdinalStartsWith("\\\\?\\globalroot", true))
- throw new ArgumentException(Environment.GetResourceString("Arg_PathGlobalRoot"));
- }
- }
-
- // Check our result and form the managed string as necessary.
- if (newBuffer.Length >= maxPathLength)
- throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
-
- if (result == 0) {
- int errorCode = Marshal.GetLastWin32Error();
- if (errorCode == 0)
- errorCode = Win32Native.ERROR_BAD_PATHNAME;
- __Error.WinIOError(errorCode, path);
- return null; // Unreachable - silence a compiler error.
- }
-
- return newBuffer.ToStringOrExisting(path);
- }
-#endif // FEATURE_PATHCOMPAT
-
- internal const int MaxLongPath = PathInternal.MaxLongPath;
-
- private const string LongPathPrefix = PathInternal.ExtendedPathPrefix;
- private const string UNCPathPrefix = PathInternal.UncPathPrefix;
- private const string UNCLongPathPrefixToInsert = PathInternal.UncExtendedPrefixToInsert;
- private const string UNCLongPathPrefix = PathInternal.UncExtendedPathPrefix;
-
- internal static bool HasLongPathPrefix(string path)
- {
-#if FEATURE_PATHCOMPAT
- if (AppContextSwitches.UseLegacyPathHandling)
- return path.StartsWith(LongPathPrefix, StringComparison.Ordinal);
- else
-#endif
- return PathInternal.IsExtended(path);
- }
-
- internal static string AddLongPathPrefix(string path)
- {
-#if FEATURE_PATHCOMPAT
- if (AppContextSwitches.UseLegacyPathHandling)
- {
- if (path.StartsWith(LongPathPrefix, StringComparison.Ordinal))
- return path;
-
- if (path.StartsWith(UNCPathPrefix, StringComparison.Ordinal))
- return path.Insert(2, UNCLongPathPrefixToInsert); // Given \\server\share in longpath becomes \\?\UNC\server\share => UNCLongPathPrefix + path.SubString(2); => The actual command simply reduces the operation cost.
-
- return LongPathPrefix + path;
- }
- else
-#endif
- {
- return PathInternal.EnsureExtendedPrefix(path);
- }
- }
-
- internal static string RemoveLongPathPrefix(string path)
- {
-#if FEATURE_PATHCOMPAT
- if (AppContextSwitches.UseLegacyPathHandling)
- {
- if (!path.StartsWith(LongPathPrefix, StringComparison.Ordinal))
- return path;
-
- if (path.StartsWith(UNCLongPathPrefix, StringComparison.OrdinalIgnoreCase))
- return path.Remove(2, 6); // Given \\?\UNC\server\share we return \\server\share => @'\\' + path.SubString(UNCLongPathPrefix.Length) => The actual command simply reduces the operation cost.
-
- return path.Substring(4);
- }
- else
-#endif
- {
- return PathInternal.RemoveExtendedPrefix(path);
- }
- }
-
- internal static StringBuilder RemoveLongPathPrefix(StringBuilder pathSB)
- {
-#if FEATURE_PATHCOMPAT
- if (AppContextSwitches.UseLegacyPathHandling)
- {
- if (!PathInternal.StartsWithOrdinal(pathSB, LongPathPrefix))
- return pathSB;
-
- // Given \\?\UNC\server\share we return \\server\share => @'\\' + path.SubString(UNCLongPathPrefix.Length) => The actual command simply reduces the operation cost.
- if (PathInternal.StartsWithOrdinal(pathSB, UNCLongPathPrefix, ignoreCase: true))
- return pathSB.Remove(2, 6);
-
- return pathSB.Remove(0, 4);
- }
- else
-#endif
- {
- return PathInternal.RemoveExtendedPrefix(pathSB);
- }
- }
-
-
- // Returns the name and extension parts of the given path. The resulting
- // string contains the characters of path that follow the last
- // backslash ("\"), slash ("/"), or colon (":") character in
- // path. The resulting string is the entire path if path
- // contains no backslash after removing trailing slashes, slash, or colon characters. The resulting
- // string is null if path is null.
- //
- [Pure]
- public static String GetFileName(String path) {
- if (path != null) {
- CheckInvalidPathChars(path);
-
- int length = path.Length;
- for (int i = length; --i >= 0;) {
- char ch = path[i];
- if (ch == DirectorySeparatorChar || ch == AltDirectorySeparatorChar || ch == VolumeSeparatorChar)
- return path.Substring(i + 1, length - i - 1);
-
- }
- }
- return path;
- }
-
- [Pure]
- public static String GetFileNameWithoutExtension(String path) {
- path = GetFileName(path);
- if (path != null)
- {
- int i;
- if ((i=path.LastIndexOf('.')) == -1)
- return path; // No path extension found
- else
- return path.Substring(0,i);
- }
- return null;
- }
-
-
-
- // 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.
- //
- [Pure]
- public static String GetPathRoot(String path) {
- if (path == null) return null;
-
- // Expanding short paths has no impact on the path root- there is no such thing as an
- // 8.3 volume or server/share name.
- path = NormalizePath(path, fullCheck: false, expandShortPaths: false);
- return path.Substring(0, GetRootLength(path));
- }
-
- [System.Security.SecuritySafeCritical]
- public static String GetTempPath()
- {
-#if !FEATURE_CORECLR
- new EnvironmentPermission(PermissionState.Unrestricted).Demand();
-#endif
- StringBuilder sb = new StringBuilder(PathInternal.MaxShortPath);
- uint r = Win32Native.GetTempPath(PathInternal.MaxShortPath, sb);
- String path = sb.ToString();
- if (r==0) __Error.WinIOError();
- path = GetFullPathInternal(path);
-#if FEATURE_CORECLR
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Write, String.Empty, path);
- state.EnsureState();
-#endif
- return path;
- }
-
- internal static bool IsRelative(string path)
- {
- Contract.Assert(path != null, "path can't be null");
- return PathInternal.IsPartiallyQualified(path);
- }
-
- // Returns a cryptographically strong random 8.3 string that can be
- // used as either a folder name or a file name.
-#if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical]
-#endif
- public static String GetRandomFileName()
- {
- // 5 bytes == 40 bits == 40/5 == 8 chars in our encoding
- // This gives us exactly 8 chars. We want to avoid the 8.3 short name issue
- byte[] key = new byte[10];
-
-#if FEATURE_CORECLR
- Win32Native.Random(true, key, key.Length);
-#else
- // RNGCryptoServiceProvider is disposable in post-Orcas desktop mscorlibs, but not in CoreCLR's
- // mscorlib, so we need to do a manual using block for it.
- RNGCryptoServiceProvider rng = null;
- try
- {
- rng = new RNGCryptoServiceProvider();
-
- rng.GetBytes(key);
- }
- finally
- {
- if (rng != null)
- {
- rng.Dispose();
- }
- }
-#endif
-
- // rndCharArray is expected to be 16 chars
- char[] rndCharArray = Path.ToBase32StringSuitableForDirName(key).ToCharArray();
- rndCharArray[8] = '.';
- return new String(rndCharArray, 0, 12);
- }
-
- // Returns a unique temporary file name, and creates a 0-byte file by that
- // name on disk.
- [System.Security.SecuritySafeCritical]
- public static String GetTempFileName()
- {
- return InternalGetTempFileName(true);
- }
-
- [System.Security.SecurityCritical]
- internal static String UnsafeGetTempFileName()
- {
- return InternalGetTempFileName(false);
- }
-
- [System.Security.SecurityCritical]
- private static String InternalGetTempFileName(bool checkHost)
- {
- String path = GetTempPath();
-
- // Since this can write to the temp directory and theoretically
- // cause a denial of service attack, demand FileIOPermission to
- // that directory.
-
-#if FEATURE_CORECLR
- if (checkHost)
- {
- FileSecurityState state = new FileSecurityState(FileSecurityStateAccess.Write, String.Empty, path);
- state.EnsureState();
- }
-#else
- FileIOPermission.QuickDemand(FileIOPermissionAccess.Write, path);
-#endif
- StringBuilder sb = new StringBuilder(MaxPath);
- uint r = Win32Native.GetTempFileName(path, "tmp", 0, sb);
- if (r==0) __Error.WinIOError();
- return sb.ToString();
- }
-
- // 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) {
- CheckInvalidPathChars(path);
-
- for (int i = path.Length; --i >= 0;) {
- char ch = path[i];
- if (ch == '.') {
- if ( i != path.Length - 1)
- return true;
- else
- return false;
- }
- if (ch == DirectorySeparatorChar || ch == AltDirectorySeparatorChar || ch == VolumeSeparatorChar) break;
- }
- }
- return false;
- }
-
- // 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 (":").
- //
- [Pure]
- public static bool IsPathRooted(String path) {
- if (path != null) {
- CheckInvalidPathChars(path);
-
- int length = path.Length;
-#if !PLATFORM_UNIX
- if ((length >= 1 && (path[0] == DirectorySeparatorChar || path[0] == AltDirectorySeparatorChar)) || (length >= 2 && path[1] == VolumeSeparatorChar))
- return true;
-#else
- if (length >= 1 && (path[0] == DirectorySeparatorChar || path[0] == AltDirectorySeparatorChar))
- return true;
-#endif
- }
- return false;
- }
-
- public static String Combine(String path1, String path2) {
- if (path1==null || path2==null)
- throw new ArgumentNullException((path1==null) ? "path1" : "path2");
- Contract.EndContractBlock();
- CheckInvalidPathChars(path1);
- 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) ? "path1" : (path2 == null) ? "path2" : "path3");
- Contract.EndContractBlock();
- CheckInvalidPathChars(path1);
- CheckInvalidPathChars(path2);
- CheckInvalidPathChars(path3);
-
- return CombineNoChecks(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) ? "path1" : (path2 == null) ? "path2" : (path3 == null) ? "path3" : "path4");
- Contract.EndContractBlock();
- CheckInvalidPathChars(path1);
- CheckInvalidPathChars(path2);
- CheckInvalidPathChars(path3);
- CheckInvalidPathChars(path4);
-
- return CombineNoChecks(CombineNoChecks(CombineNoChecks(path1, path2), path3), path4);
- }
-
- public static String Combine(params String[] paths) {
- if (paths == null) {
- throw new ArgumentNullException("paths");
- }
- Contract.EndContractBlock();
-
- int finalSize = 0;
- int firstComponent = 0;
-
- // We have two passes, the first calcuates 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("paths");
- }
-
- if (paths[i].Length == 0) {
- continue;
- }
-
- CheckInvalidPathChars(paths[i]);
-
- if (Path.IsPathRooted(paths[i])) {
- firstComponent = i;
- finalSize = paths[i].Length;
- } else {
- finalSize += paths[i].Length;
- }
-
- char ch = paths[i][paths[i].Length - 1];
- if (ch != DirectorySeparatorChar && ch != AltDirectorySeparatorChar && ch != VolumeSeparatorChar)
- 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 (ch != DirectorySeparatorChar && ch != AltDirectorySeparatorChar && ch != VolumeSeparatorChar) {
- finalPath.Append(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];
- if (ch != DirectorySeparatorChar && ch != AltDirectorySeparatorChar && ch != VolumeSeparatorChar)
- return path1 + DirectorySeparatorCharAsString + path2;
- return path1 + path2;
- }
-
- 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'};
-
- internal static String ToBase32StringSuitableForDirName(byte[] buff)
- {
- // This routine is optimised to be used with buffs of length 20
- Contract.Assert(((buff.Length % 5) == 0), "Unexpected hash length");
-
- StringBuilder sb = StringBuilderCache.Acquire();
- byte b0, b1, b2, b3, b4;
- int l, i;
-
- l = buff.Length;
- i = 0;
-
- // Create l chars using the last 5 bits of each byte.
- // Consume 3 MSB bits 5 bytes at a time.
-
- do
- {
- b0 = (i < l) ? buff[i++] : (byte)0;
- b1 = (i < l) ? buff[i++] : (byte)0;
- b2 = (i < l) ? buff[i++] : (byte)0;
- b3 = (i < l) ? buff[i++] : (byte)0;
- b4 = (i < l) ? buff[i++] : (byte)0;
-
- // Consume the 5 Least significant bits of each byte
- sb.Append(s_Base32Char[b0 & 0x1F]);
- sb.Append(s_Base32Char[b1 & 0x1F]);
- sb.Append(s_Base32Char[b2 & 0x1F]);
- sb.Append(s_Base32Char[b3 & 0x1F]);
- sb.Append(s_Base32Char[b4 & 0x1F]);
-
- // Consume 3 MSB of b0, b1, MSB bits 6, 7 of b3, b4
- sb.Append(s_Base32Char[(
- ((b0 & 0xE0) >> 5) |
- ((b3 & 0x60) >> 2))]);
-
- sb.Append(s_Base32Char[(
- ((b1 & 0xE0) >> 5) |
- ((b4 & 0x60) >> 2))]);
-
- // Consume 3 MSB bits of b2, 1 MSB bit of b3, b4
-
- b2 >>= 5;
-
- Contract.Assert(((b2 & 0xF8) == 0), "Unexpected set bits");
-
- if ((b3 & 0x80) != 0)
- b2 |= 0x08;
- if ((b4 & 0x80) != 0)
- b2 |= 0x10;
-
- sb.Append(s_Base32Char[b2]);
-
- } while (i < l);
-
- return StringBuilderCache.GetStringAndRelease(sb);
- }
-
- // ".." can only be used if it is specified as a part of a valid File/Directory name. We disallow
- // the user being able to use it to move up directories. Here are some examples eg
- // Valid: a..b abc..d
- // Invalid: ..ab ab.. .. abc..d\abc..
- //
- internal static void CheckSearchPattern(String searchPattern)
- {
- int index;
- while ((index = searchPattern.IndexOf("..", StringComparison.Ordinal)) != -1) {
-
- if (index + 2 == searchPattern.Length) // Terminal ".." . Files names cannot end in ".."
- throw new ArgumentException(Environment.GetResourceString("Arg_InvalidSearchPattern"));
-
- if ((searchPattern[index+2] == DirectorySeparatorChar)
- || (searchPattern[index+2] == AltDirectorySeparatorChar))
- throw new ArgumentException(Environment.GetResourceString("Arg_InvalidSearchPattern"));
-
- searchPattern = searchPattern.Substring(index + 2);
- }
-
- }
-
- internal static void CheckInvalidPathChars(String path, bool checkAdditional = false)
- {
- if (path == null)
- throw new ArgumentNullException("path");
-
- if (PathInternal.HasIllegalCharacters(path, checkAdditional))
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidPathChars"));
- }
-
- internal static String InternalCombine(String path1, String path2) {
- if (path1==null || path2==null)
- throw new ArgumentNullException((path1==null) ? "path1" : "path2");
- Contract.EndContractBlock();
- CheckInvalidPathChars(path1);
- CheckInvalidPathChars(path2);
-
- if (path2.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_PathEmpty"), "path2");
- if (IsPathRooted(path2))
- throw new ArgumentException(Environment.GetResourceString("Arg_Path2IsRooted"), "path2");
- int i = path1.Length;
- if (i == 0) return path2;
- char ch = path1[i - 1];
- if (ch != DirectorySeparatorChar && ch != AltDirectorySeparatorChar && ch != VolumeSeparatorChar)
- return path1 + DirectorySeparatorCharAsString + path2;
- return path1 + path2;
- }
-
- }
-}
diff --git a/src/mscorlib/src/System/IO/PathHelper.cs b/src/mscorlib/src/System/IO/PathHelper.cs
deleted file mode 100644
index 8e39b3c537..0000000000
--- a/src/mscorlib/src/System/IO/PathHelper.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.
-
-#if FEATURE_PATHCOMPAT
-using System;
-using System.Collections;
-using System.Text;
-using Microsoft.Win32;
-using System.Runtime.InteropServices;
-using System.Runtime.CompilerServices;
-using System.Globalization;
-using System.Runtime.Versioning;
-using System.Security;
-using System.Security.Permissions;
-using System.Diagnostics.Contracts;
-
-namespace System.IO {
-
- // ABOUT:
- // Helps with path normalization; support allocating on the stack or heap
- //
- // PathHelper can't stackalloc the array for obvious reasons; you must pass
- // in an array of chars allocated on the stack.
- //
- // USAGE:
- // Suppose you need to represent a char array of length len. Then this is the
- // suggested way to instantiate PathHelper:
- // ***************************************************************************
- // PathHelper pathHelper;
- // if (charArrayLength less than stack alloc threshold == Path.MaxPath)
- // char* arrayPtr = stackalloc char[Path.MaxPath];
- // pathHelper = new PathHelper(arrayPtr);
- // else
- // pathHelper = new PathHelper(capacity, maxPath);
- // ***************************************************************************
- //
- // note in the StringBuilder ctor:
- // - maxPath may be greater than Path.MaxPath (for isolated storage)
- // - capacity may be greater than maxPath. This is even used for non-isolated
- // storage scenarios where we want to temporarily allow strings greater
- // than Path.MaxPath if they can be normalized down to Path.MaxPath. This
- // can happen if the path contains escape characters "..".
- //
- unsafe internal struct PathHelper { // should not be serialized
-
- // maximum size, max be greater than max path if contains escape sequence
- private int m_capacity;
- // current length (next character position)
- private int m_length;
- // max path, may be less than capacity
- private int m_maxPath;
-
- // ptr to stack alloc'd array of chars
- [SecurityCritical]
- private char* m_arrayPtr;
-
- // StringBuilder
- private StringBuilder m_sb;
-
- // whether to operate on stack alloc'd or heap alloc'd array
- private bool useStackAlloc;
-
- // Whether to skip calls to Win32Native.GetLongPathName becasue we tried before and failed:
- private bool doNotTryExpandShortFileName;
-
- // Instantiates a PathHelper with a stack alloc'd array of chars
- [System.Security.SecurityCritical]
- internal PathHelper(char* charArrayPtr, int length) {
- Contract.Requires(charArrayPtr != null);
- // force callers to be aware of this
- Contract.Requires(length == Path.MaxPath);
- this.m_length = 0;
- this.m_sb = null;
-
- this.m_arrayPtr = charArrayPtr;
- this.m_capacity = length;
- this.m_maxPath = Path.MaxPath;
- useStackAlloc = true;
- doNotTryExpandShortFileName = false;
- }
-
- // Instantiates a PathHelper with a heap alloc'd array of ints. Will create a StringBuilder
- [System.Security.SecurityCritical]
- internal PathHelper(int capacity, int maxPath)
- {
- this.m_length = 0;
- this.m_arrayPtr = null;
- this.useStackAlloc = false;
-
- this.m_sb = new StringBuilder(capacity);
- this.m_capacity = capacity;
- this.m_maxPath = maxPath;
- doNotTryExpandShortFileName = false;
- }
-
- internal int Length {
- get {
- if (useStackAlloc) {
- return m_length;
- }
- else {
- return m_sb.Length;
- }
- }
- set {
- if (useStackAlloc) {
- m_length = value;
- }
- else {
- m_sb.Length = value;
- }
- }
- }
-
- internal int Capacity {
- get {
- return m_capacity;
- }
- }
-
- internal char this[int index] {
- [System.Security.SecurityCritical]
- get {
- Contract.Requires(index >= 0 && index < Length);
- if (useStackAlloc) {
- return m_arrayPtr[index];
- }
- else {
- return m_sb[index];
- }
- }
- [System.Security.SecurityCritical]
- set {
- Contract.Requires(index >= 0 && index < Length);
- if (useStackAlloc) {
- m_arrayPtr[index] = value;
- }
- else {
- m_sb[index] = value;
- }
- }
- }
-
- [System.Security.SecurityCritical]
- internal unsafe void Append(char value) {
- if (Length + 1 >= m_capacity)
- throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
-
- if (useStackAlloc) {
- m_arrayPtr[Length] = value;
- m_length++;
- }
- else {
- m_sb.Append(value);
- }
- }
-
- [System.Security.SecurityCritical]
- internal unsafe int GetFullPathName() {
- if (useStackAlloc) {
- char* finalBuffer = stackalloc char[Path.MaxPath + 1];
- int result = Win32Native.GetFullPathName(m_arrayPtr, Path.MaxPath + 1, finalBuffer, IntPtr.Zero);
-
- // If success, the return buffer length does not account for the terminating null character.
- // If in-sufficient buffer, the return buffer length does account for the path + the terminating null character.
- // If failure, the return buffer length is zero
- if (result > Path.MaxPath) {
- char* tempBuffer = stackalloc char[result];
- finalBuffer = tempBuffer;
- result = Win32Native.GetFullPathName(m_arrayPtr, result, finalBuffer, IntPtr.Zero);
- }
-
- // Full path is genuinely long
- if (result >= Path.MaxPath)
- throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
-
- Contract.Assert(result < Path.MaxPath, "did we accidently remove a PathTooLongException check?");
- if (result == 0 && m_arrayPtr[0] != '\0') {
- __Error.WinIOError();
- }
-
- else if (result < Path.MaxPath) {
- // Null terminate explicitly (may be only needed for some cases such as empty strings)
- // GetFullPathName return length doesn't account for null terminating char...
- finalBuffer[result] = '\0'; // Safe to write directly as result is < Path.MaxPath
- }
-
- // We have expanded the paths and GetLongPathName may or may not behave differently from before.
- // We need to call it again to see:
- doNotTryExpandShortFileName = false;
-
- String.wstrcpy(m_arrayPtr, finalBuffer, result);
- // Doesn't account for null terminating char. Think of this as the last
- // valid index into the buffer but not the length of the buffer
- Length = result;
- return result;
- }
- else {
- StringBuilder finalBuffer = new StringBuilder(m_capacity + 1);
- int result = Win32Native.GetFullPathName(m_sb.ToString(), m_capacity + 1, finalBuffer, IntPtr.Zero);
-
- // If success, the return buffer length does not account for the terminating null character.
- // If in-sufficient buffer, the return buffer length does account for the path + the terminating null character.
- // If failure, the return buffer length is zero
- if (result > m_maxPath) {
- finalBuffer.Length = result;
- result = Win32Native.GetFullPathName(m_sb.ToString(), result, finalBuffer, IntPtr.Zero);
- }
-
- // Fullpath is genuinely long
- if (result >= m_maxPath)
- throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
-
- Contract.Assert(result < m_maxPath, "did we accidentally remove a PathTooLongException check?");
- if (result == 0 && m_sb[0] != '\0') {
- if (Length >= m_maxPath) {
- throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
- }
- __Error.WinIOError();
- }
-
- // We have expanded the paths and GetLongPathName may or may not behave differently from before.
- // We need to call it again to see:
- doNotTryExpandShortFileName = false;
-
- m_sb = finalBuffer;
- return result;
- }
- }
-
- [System.Security.SecurityCritical]
- internal unsafe bool TryExpandShortFileName() {
-
- if (doNotTryExpandShortFileName)
- return false;
-
- if (useStackAlloc) {
- NullTerminate();
- char* buffer = UnsafeGetArrayPtr();
- char* shortFileNameBuffer = stackalloc char[Path.MaxPath + 1];
-
- int r = Win32Native.GetLongPathName(buffer, shortFileNameBuffer, Path.MaxPath);
-
- // If success, the return buffer length does not account for the terminating null character.
- // If in-sufficient buffer, the return buffer length does account for the path + the terminating null character.
- // If failure, the return buffer length is zero
- if (r >= Path.MaxPath)
- throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
-
- if (r == 0) {
- // Note: GetLongPathName will return ERROR_INVALID_FUNCTION on a
- // path like \\.\PHYSICALDEVICE0 - some device driver doesn't
- // support GetLongPathName on that string. This behavior is
- // by design, according to the Core File Services team.
- // We also get ERROR_NOT_ENOUGH_QUOTA in SQL_CLR_STRESS runs
- // intermittently on paths like D:\DOCUME~1\user\LOCALS~1\Temp\
-
- // We do not need to call GetLongPathName if we know it will fail becasue the path does not exist:
- int lastErr = Marshal.GetLastWin32Error();
- if (lastErr == Win32Native.ERROR_FILE_NOT_FOUND || lastErr == Win32Native.ERROR_PATH_NOT_FOUND)
- doNotTryExpandShortFileName = true;
-
- return false;
- }
-
- // Safe to copy as we have already done Path.MaxPath bound checking
- String.wstrcpy(buffer, shortFileNameBuffer, r);
- Length = r;
- // We should explicitly null terminate as in some cases the long version of the path
- // might actually be shorter than what we started with because of Win32's normalization
- // Safe to write directly as bufferLength is guaranteed to be < Path.MaxPath
- NullTerminate();
- return true;
- }
- else {
- StringBuilder sb = GetStringBuilder();
-
- String origName = sb.ToString();
- String tempName = origName;
- bool addedPrefix = false;
- if (tempName.Length > Path.MaxPath) {
- tempName = Path.AddLongPathPrefix(tempName);
- addedPrefix = true;
- }
- sb.Capacity = m_capacity;
- sb.Length = 0;
- int r = Win32Native.GetLongPathName(tempName, sb, m_capacity);
-
- if (r == 0) {
- // Note: GetLongPathName will return ERROR_INVALID_FUNCTION on a
- // path like \\.\PHYSICALDEVICE0 - some device driver doesn't
- // support GetLongPathName on that string. This behavior is
- // by design, according to the Core File Services team.
- // We also get ERROR_NOT_ENOUGH_QUOTA in SQL_CLR_STRESS runs
- // intermittently on paths like D:\DOCUME~1\user\LOCALS~1\Temp\
-
- // We do not need to call GetLongPathName if we know it will fail becasue the path does not exist:
- int lastErr = Marshal.GetLastWin32Error();
- if (Win32Native.ERROR_FILE_NOT_FOUND == lastErr || Win32Native.ERROR_PATH_NOT_FOUND == lastErr)
- doNotTryExpandShortFileName = true;
-
- sb.Length = 0;
- sb.Append(origName);
- return false;
- }
-
- if (addedPrefix)
- r -= 4;
-
- // If success, the return buffer length does not account for the terminating null character.
- // If in-sufficient buffer, the return buffer length does account for the path + the terminating null character.
- // If failure, the return buffer length is zero
- if (r >= m_maxPath)
- throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
-
-
- sb = Path.RemoveLongPathPrefix(sb);
- Length = sb.Length;
- return true;
-
- }
- }
-
- [System.Security.SecurityCritical]
- internal unsafe void Fixup(int lenSavedName, int lastSlash) {
- if (useStackAlloc) {
- char* savedName = stackalloc char[lenSavedName];
- String.wstrcpy(savedName, m_arrayPtr + lastSlash + 1, lenSavedName);
- Length = lastSlash;
- NullTerminate();
- doNotTryExpandShortFileName = false;
- bool r = TryExpandShortFileName();
- // Clean up changes made to the newBuffer.
- Append(Path.DirectorySeparatorChar);
- if (Length + lenSavedName >= Path.MaxPath)
- throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
- String.wstrcpy(m_arrayPtr + Length, savedName, lenSavedName);
- Length = Length + lenSavedName;
-
- }
- else {
- String savedName = m_sb.ToString(lastSlash + 1, lenSavedName);
- Length = lastSlash;
- doNotTryExpandShortFileName = false;
- bool r = TryExpandShortFileName();
- // Clean up changes made to the newBuffer.
- Append(Path.DirectorySeparatorChar);
- if (Length + lenSavedName >= m_maxPath)
- throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
- m_sb.Append(savedName);
- }
- }
-
- [System.Security.SecurityCritical]
- internal unsafe bool OrdinalStartsWith(String compareTo, bool ignoreCase) {
- if (Length < compareTo.Length)
- return false;
-
- if (useStackAlloc) {
- NullTerminate();
- if (ignoreCase) {
- String s = new String(m_arrayPtr, 0, compareTo.Length);
- return compareTo.Equals(s, StringComparison.OrdinalIgnoreCase);
- }
- else {
- for (int i = 0; i < compareTo.Length; i++) {
- if (m_arrayPtr[i] != compareTo[i]) {
- return false;
- }
- }
- return true;
- }
- }
- else {
- if (ignoreCase) {
- return m_sb.ToString().StartsWith(compareTo, StringComparison.OrdinalIgnoreCase);
- }
- else {
- return m_sb.ToString().StartsWith(compareTo, StringComparison.Ordinal);
- }
- }
- }
-
- [System.Security.SecurityCritical]
- private unsafe bool OrdinalEqualsStackAlloc(String compareTo)
- {
- Contract.Requires(useStackAlloc, "Currently no efficient implementation for StringBuilder.OrdinalEquals(String)");
-
- if (Length != compareTo.Length) {
- return false;
- }
-
- for (int i = 0; i < compareTo.Length; i++) {
- if (m_arrayPtr[i] != compareTo[i]) {
- return false;
- }
- }
-
- return true;
- }
-
- [System.Security.SecuritySafeCritical]
- public override String ToString() {
- if (useStackAlloc) {
- return new String(m_arrayPtr, 0, Length);
- }
- else {
- return m_sb.ToString();
- }
- }
-
- [System.Security.SecuritySafeCritical]
- internal String ToStringOrExisting(String existingString)
- {
- if (useStackAlloc) {
- return OrdinalEqualsStackAlloc(existingString) ?
- existingString :
- new String(m_arrayPtr, 0, Length);
- }
- else {
- string newString = m_sb.ToString(); // currently no good StringBuilder.OrdinalEquals(string)
- return String.Equals(newString, existingString, StringComparison.Ordinal) ?
- existingString :
- newString;
- }
- }
-
- [System.Security.SecurityCritical]
- private unsafe char* UnsafeGetArrayPtr() {
- Contract.Requires(useStackAlloc, "This should never be called for PathHelpers wrapping a StringBuilder");
- return m_arrayPtr;
- }
-
- private StringBuilder GetStringBuilder() {
- Contract.Requires(!useStackAlloc, "This should never be called for PathHelpers that wrap a stackalloc'd buffer");
- return m_sb;
- }
-
- [System.Security.SecurityCritical]
- private unsafe void NullTerminate() {
- Contract.Requires(useStackAlloc, "This should never be called for PathHelpers wrapping a StringBuilder");
- m_arrayPtr[m_length] = '\0';
- }
-
- }
-}
-#endif // FEATURE_PATHCOMPAT \ No newline at end of file
diff --git a/src/mscorlib/src/System/IO/PathInternal.cs b/src/mscorlib/src/System/IO/PathInternal.cs
deleted file mode 100644
index 3970e2264a..0000000000
--- a/src/mscorlib/src/System/IO/PathInternal.cs
+++ /dev/null
@@ -1,806 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using Microsoft.Win32;
-using System;
-using System.Diagnostics.Contracts;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Security;
-using System.Text;
-
-namespace System.IO
-{
- /// <summary>Contains internal path helpers that are shared between many projects.</summary>
- internal static class PathInternal
- {
- internal const string ExtendedPathPrefix = @"\\?\";
- internal const string UncPathPrefix = @"\\";
- internal const string UncExtendedPrefixToInsert = @"?\UNC\";
- internal const string UncExtendedPathPrefix = @"\\?\UNC\";
- internal const string DevicePathPrefix = @"\\.\";
- // \\?\, \\.\, \??\
- internal const int DevicePrefixLength = 4;
- // \\
- internal const int UncPrefixLength = 2;
- // \\?\UNC\, \\.\UNC\
- internal const int UncExtendedPrefixLength = 8;
-#if !PLATFORM_UNIX
- internal const int MaxShortPath = 260;
- internal const int MaxShortDirectoryPath = 248;
-#else
- internal const int MaxShortPath = 1024;
- internal const int MaxShortDirectoryPath = MaxShortPath;
-#endif
-
- // Windows is limited in long paths by the max size of its internal representation of a unicode string.
- // UNICODE_STRING has a max length of USHORT in _bytes_ without a trailing null.
- // https://msdn.microsoft.com/en-us/library/windows/hardware/ff564879.aspx
- internal const int MaxLongPath = short.MaxValue;
- internal static readonly int MaxComponentLength = 255;
-
-#if !PLATFORM_UNIX
- internal static readonly char[] InvalidPathChars =
- {
- '\"', '<', '>', '|', '\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
- };
-#else
- internal static readonly char[] InvalidPathChars = { '\0' };
-#endif
-
-
- /// <summary>
- /// Validates volume separator only occurs as C: or \\?\C:. This logic is meant to filter out Alternate Data Streams.
- /// </summary>
- /// <returns>True if the path has an invalid volume separator.</returns>
- internal static bool HasInvalidVolumeSeparator(string path)
- {
- // 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:" or "\\?\C:".
- // (Note that we used to explicitly check "http:" and "file:"- these are caught by this check now.)
-
- // We don't care about skipping starting space for extended paths. Assume no knowledge of extended paths if we're forcing old path behavior.
- bool isExtended =
-#if FEATURE_PATHCOMPAT
- !AppContextSwitches.UseLegacyPathHandling &&
-#endif
- IsExtended(path);
- int startIndex = isExtended ? ExtendedPathPrefix.Length : PathStartSkip(path);
-
- // If we start with a colon
- if ((path.Length > startIndex && path[startIndex] == Path.VolumeSeparatorChar)
- // Or have an invalid drive letter and colon
- || (path.Length >= startIndex + 2 && path[startIndex + 1] == Path.VolumeSeparatorChar && !IsValidDriveChar(path[startIndex]))
- // Or have any colons beyond the drive colon
- || (path.Length > startIndex + 2 && path.IndexOf(Path.VolumeSeparatorChar, startIndex + 2) != -1))
- {
- return true;
- }
-
- return false;
- }
-
- /// <summary>
- /// Returns true if the given StringBuilder starts with the given value.
- /// </summary>
- /// <param name="value">The string to compare against the start of the StringBuilder.</param>
- internal static bool StartsWithOrdinal(StringBuilder builder, string value, bool ignoreCase = false)
- {
- if (value == null || builder.Length < value.Length)
- return false;
-
- if (ignoreCase)
- {
- for (int i = 0; i < value.Length; i++)
- if (char.ToUpperInvariant(builder[i]) != char.ToUpperInvariant(value[i])) return false;
- }
- else
- {
- for (int i = 0; i < value.Length; i++)
- if (builder[i] != value[i]) return false;
- }
-
- return true;
- }
-
- /// <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>
- /// Returns true if the path is too long
- /// </summary>
- internal static bool IsPathTooLong(string fullPath)
- {
- // We'll never know precisely what will fail as paths get changed internally in Windows and
- // may grow beyond / shrink below exceed MaxLongPath.
-#if FEATURE_PATHCOMPAT
- if (AppContextSwitches.BlockLongPaths)
- {
- // We allow paths of any length if extended (and not in compat mode)
- if (AppContextSwitches.UseLegacyPathHandling || !IsExtended(fullPath))
- return fullPath.Length >= MaxShortPath;
- }
-#endif
-
- return fullPath.Length >= MaxLongPath;
- }
-
- /// <summary>
- /// Return true if any path segments are too long
- /// </summary>
- internal static bool AreSegmentsTooLong(string fullPath)
- {
- int length = fullPath.Length;
- int lastSeparator = 0;
-
- for (int i = 0; i < length; i++)
- {
- if (IsDirectorySeparator(fullPath[i]))
- {
- if (i - lastSeparator > MaxComponentLength)
- return true;
- lastSeparator = i;
- }
- }
-
- if (length - 1 - lastSeparator > MaxComponentLength)
- return true;
-
- return false;
- }
-
- /// <summary>
- /// Returns true if the directory is too long
- /// </summary>
- internal static bool IsDirectoryTooLong(string fullPath)
- {
-#if FEATURE_PATHCOMPAT
- if (AppContextSwitches.BlockLongPaths)
- {
- // We allow paths of any length if extended (and not in compat mode)
- if (AppContextSwitches.UseLegacyPathHandling || !IsExtended(fullPath))
- return (fullPath.Length >= MaxShortDirectoryPath);
- }
-#endif
-
- return IsPathTooLong(fullPath);
- }
-
- /// <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>
- /// Removes the extended path prefix (\\?\) if present.
- /// </summary>
- internal static string RemoveExtendedPrefix(string path)
- {
- if (!IsExtended(path))
- return path;
-
- // Given \\?\UNC\server\share we return \\server\share
- if (IsExtendedUnc(path))
- return path.Remove(2, 6);
-
- return path.Substring(DevicePrefixLength);
- }
-
- /// <summary>
- /// Removes the extended path prefix (\\?\) if present.
- /// </summary>
- internal static StringBuilder RemoveExtendedPrefix(StringBuilder path)
- {
- if (!IsExtended(path))
- return path;
-
- // Given \\?\UNC\server\share we return \\server\share
- if (IsExtendedUnc(path))
- return path.Remove(2, 6);
-
- return path.Remove(0, DevicePrefixLength);
- }
-
- /// <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 it 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 any of the DOS device path syntaxes. ("\\.\", "\\?\", or "\??\")
- /// </summary>
- internal static bool IsDevice(StringBuffer path)
- {
- // If the path begins with any two separators it 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 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(StringBuilder 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 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(StringBuffer 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 true if the path uses the extended UNC syntax (\\?\UNC\ or \??\UNC\)
- /// </summary>
- internal static bool IsExtendedUnc(string path)
- {
- return path.Length >= UncExtendedPathPrefix.Length
- && IsExtended(path)
- && char.ToUpper(path[4]) == 'U'
- && char.ToUpper(path[5]) == 'N'
- && char.ToUpper(path[6]) == 'C'
- && path[7] == '\\';
- }
-
- /// <summary>
- /// Returns true if the path uses the extended UNC syntax (\\?\UNC\ or \??\UNC\)
- /// </summary>
- internal static bool IsExtendedUnc(StringBuilder path)
- {
- return path.Length >= UncExtendedPathPrefix.Length
- && IsExtended(path)
- && char.ToUpper(path[4]) == 'U'
- && char.ToUpper(path[5]) == 'N'
- && char.ToUpper(path[6]) == 'C'
- && path[7] == '\\';
- }
-
- /// <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 *.
- ///
- /// Will not check if the path is a device path and not in Legacy mode as many of these
- /// characters are valid for devices (pipes for example).
- /// </summary>
- internal static bool HasIllegalCharacters(string path, bool checkAdditional = false)
- {
- if (
-#if FEATURE_PATHCOMPAT
- !AppContextSwitches.UseLegacyPathHandling &&
-#endif
- IsDevice(path))
- {
- return false;
- }
-
- return AnyPathHasIllegalCharacters(path, checkAdditional: checkAdditional);
- }
-
- /// <summary>
- /// Version of HasIllegalCharacters that checks no AppContextSwitches. Only use if you know you need to skip switches and don't care
- /// about proper device path handling.
- /// </summary>
- internal static bool AnyPathHasIllegalCharacters(string path, bool checkAdditional = false)
- {
- return path.IndexOfAny(InvalidPathChars) >= 0
-#if !PLATFORM_UNIX
- || (checkAdditional && AnyPathHasWildCardCharacters(path))
-#endif
- ;
- }
-
- /// <summary>
- /// Check for ? and *.
- /// </summary>
- internal static bool HasWildCardCharacters(string path)
- {
- // Question mark is part of some device paths
- int startIndex =
-#if FEATURE_PATHCOMPAT
- AppContextSwitches.UseLegacyPathHandling ? 0 :
-#endif
- IsDevice(path) ? ExtendedPathPrefix.Length : 0;
- return AnyPathHasWildCardCharacters(path, startIndex: startIndex);
- }
-
- /// <summary>
- /// Version of HasWildCardCharacters that checks no AppContextSwitches. Only use if you know you need to skip switches and don't care
- /// about proper device path handling.
- /// </summary>
- internal static bool AnyPathHasWildCardCharacters(string path, int startIndex = 0)
- {
- char currentChar;
- for (int i = startIndex; i < path.Length; i++)
- {
- currentChar = path[i];
- if (currentChar == '*' || currentChar == '?') return true;
- }
- return false;
- }
-
- /// <summary>
- /// Gets the length of the root of the path (drive, share, etc.).
- /// </summary>
- [System.Security.SecuritySafeCritical]
- internal unsafe static int GetRootLength(string path)
- {
- fixed (char* value = path)
- {
- return (int)GetRootLength(value, (ulong)path.Length);
- }
- }
-
- /// <summary>
- /// Gets the length of the root of the path (drive, share, etc.).
- /// </summary>
- [System.Security.SecuritySafeCritical]
- internal unsafe static uint GetRootLength(StringBuffer path)
- {
- if (path.Length == 0) return 0;
- return GetRootLength(path.CharPointer, path.Length);
- }
-
- [System.Security.SecurityCritical]
- private unsafe static uint GetRootLength(char* path, ulong pathLength)
- {
- uint i = 0;
-
-#if PLATFORM_UNIX
- if (pathLength >= 1 && (IsDirectorySeparator(path[0])))
- i = 1;
-#else
- uint volumeSeparatorLength = 2; // Length to the colon "C:"
- uint 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 = (uint)UncExtendedPathPrefix.Length;
- }
- else
- {
- // "C:" -> "\\?\C:"
- volumeSeparatorLength += (uint)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] == Path.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++;
- }
-#endif // !PLATFORM_UNIX
- return i;
- }
-
- [System.Security.SecurityCritical]
- private unsafe static bool StartsWithOrdinal(char* source, ulong sourceLength, string value)
- {
- if (sourceLength < (ulong)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 PLATFORM_UNIX
- return !(path.Length >= 1 && path[0] == Path.DirectorySeparatorChar);
-#else
- 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] == Path.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]));
-#endif // !PLATFORM_UNIX
- }
-
- /// <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(StringBuffer path)
- {
-#if PLATFORM_UNIX
- return !(path.Length >= 1 && path[0] == Path.DirectorySeparatorChar);
-#else
- 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] == Path.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]));
-#endif // !PLATFORM_UNIX
- }
-
- /// <summary>
- /// On Windows, 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)
- {
-#if !PLATFORM_UNIX
- 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] == Path.VolumeSeparatorChar && IsValidDriveChar(path[startIndex])))
- {
- // Go ahead and skip spaces as we're either " C:" or " \"
- return startIndex;
- }
-#endif
-
- return 0;
- }
-
- /// <summary>
- /// True if the given character is a directory separator.
- /// </summary>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static bool IsDirectorySeparator(char c)
- {
- return c == Path.DirectorySeparatorChar
-#if !PLATFORM_UNIX
- || c == Path.AltDirectorySeparatorChar
-#endif
- ;
- }
-
- /// <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.
- /// </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 != Path.DirectorySeparatorChar
-#if !PLATFORM_UNIX
- // 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]))
-#endif
- ))
- {
- normalized = false;
- break;
- }
- }
-
- if (normalized) return path;
- }
-
- StringBuilder builder = StringBuilderCache.Acquire(path.Length);
-
-#if !PLATFORM_UNIX
- // On Windows we always keep the first separator, even if the next is a separator (we need to keep initial two for UNC/extended)
- if (IsDirectorySeparator(path[start]))
- {
- start++;
- builder.Append(Path.DirectorySeparatorChar);
- }
-#endif
-
- 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 = Path.DirectorySeparatorChar;
- }
-
- builder.Append(current);
- }
-
- return StringBuilderCache.GetStringAndRelease(builder);
- }
-
-#if PLATFORM_UNIX
- // We rely on Windows to remove relative segments on Windows. This would need to be updated to
- // handle the proper rooting on Windows if we for some reason need it.
-
- /// <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>
- internal 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 > PathInternal.MaxComponentLength)
- {
- throw new PathTooLongException();
- }
-
- // Normalize the directory separator if needed
- if (c != Path.DirectorySeparatorChar && c == Path.AltDirectorySeparatorChar)
- {
- c = Path.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;
- }
- }
-#endif // PLATFORM_UNIX
- }
-} \ No newline at end of file
diff --git a/src/mscorlib/src/System/IO/PinnedBufferMemoryStream.cs b/src/mscorlib/src/System/IO/PinnedBufferMemoryStream.cs
index 4fd54f57f5..890669fa58 100644
--- a/src/mscorlib/src/System/IO/PinnedBufferMemoryStream.cs
+++ b/src/mscorlib/src/System/IO/PinnedBufferMemoryStream.cs
@@ -15,6 +15,7 @@
===========================================================*/
using System;
using System.Runtime.InteropServices;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
namespace System.IO {
@@ -24,13 +25,11 @@ namespace System.IO {
private GCHandle _pinningHandle;
// The new inheritance model requires a Critical default ctor since base (UnmanagedMemoryStream) has one
- [System.Security.SecurityCritical]
private PinnedBufferMemoryStream():base(){}
- [System.Security.SecurityCritical] // auto-generated
internal PinnedBufferMemoryStream(byte[] array)
{
- Contract.Assert(array != null, "Array can't be null");
+ Debug.Assert(array != null, "Array can't be null");
int len = array.Length;
// Handle 0 length byte arrays specially.
@@ -52,7 +51,6 @@ namespace System.IO {
Dispose(false);
}
- [System.Security.SecuritySafeCritical] // auto-generated
protected override void Dispose(bool disposing)
{
if (_isOpen) {
diff --git a/src/mscorlib/src/System/IO/Stream.cs b/src/mscorlib/src/System/IO/Stream.cs
index a1f29364cb..3cdfad613e 100644
--- a/src/mscorlib/src/System/IO/Stream.cs
+++ b/src/mscorlib/src/System/IO/Stream.cs
@@ -15,26 +15,23 @@
**
===========================================================*/
using System;
+using System.Buffers;
using System.Threading;
using System.Threading.Tasks;
-
using System.Runtime;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Security;
using System.Security.Permissions;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Reflection;
namespace System.IO {
[Serializable]
[ComVisible(true)]
-#if FEATURE_REMOTING
public abstract class Stream : MarshalByRefObject, IDisposable {
-#else // FEATURE_REMOTING
- public abstract class Stream : IDisposable {
-#endif // FEATURE_REMOTING
public static readonly Stream Null = new NullStream();
@@ -112,13 +109,11 @@ namespace System.IO {
}
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public Task CopyToAsync(Stream destination)
{
int bufferSize = _DefaultCopyBufferSize;
-#if FEATURE_CORECLR
if (CanSeek)
{
long length = Length;
@@ -147,23 +142,20 @@ namespace System.IO {
bufferSize = (int)Math.Min(bufferSize, remaining);
}
}
-#endif // FEATURE_CORECLR
-
+
return CopyToAsync(destination, bufferSize);
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public Task CopyToAsync(Stream destination, Int32 bufferSize)
{
return CopyToAsync(destination, bufferSize, CancellationToken.None);
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public virtual Task CopyToAsync(Stream destination, Int32 bufferSize, CancellationToken cancellationToken)
{
- ValidateCopyToArguments(destination, bufferSize);
+ StreamHelpers.ValidateCopyToArgs(this, destination, bufferSize);
return CopyToAsyncInternal(destination, bufferSize, cancellationToken);
}
@@ -175,11 +167,22 @@ namespace System.IO {
Contract.Requires(CanRead);
Contract.Requires(destination.CanWrite);
- byte[] buffer = new byte[bufferSize];
- int bytesRead;
- while ((bytesRead = await ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) != 0)
+ byte[] buffer = ArrayPool<byte>.Shared.Rent(bufferSize);
+ bufferSize = 0; // reuse same field for high water mark to avoid needing another field in the state machine
+ try
+ {
+ while (true)
+ {
+ int bytesRead = await ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false);
+ if (bytesRead == 0) break;
+ if (bytesRead > bufferSize) bufferSize = bytesRead;
+ await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false);
+ }
+ }
+ finally
{
- await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false);
+ Array.Clear(buffer, 0, bufferSize); // clear only the most we used
+ ArrayPool<byte>.Shared.Return(buffer, clearArray: false);
}
}
@@ -190,7 +193,6 @@ namespace System.IO {
{
int bufferSize = _DefaultCopyBufferSize;
-#if FEATURE_CORECLR
if (CanSeek)
{
long length = Length;
@@ -209,19 +211,30 @@ namespace System.IO {
bufferSize = (int)Math.Min(bufferSize, remaining);
}
}
-#endif // FEATURE_CORECLR
-
+
CopyTo(destination, bufferSize);
}
public virtual void CopyTo(Stream destination, int bufferSize)
{
- ValidateCopyToArguments(destination, bufferSize);
-
- byte[] buffer = new byte[bufferSize];
- int read;
- while ((read = Read(buffer, 0, buffer.Length)) != 0)
- destination.Write(buffer, 0, read);
+ StreamHelpers.ValidateCopyToArgs(this, destination, bufferSize);
+
+ byte[] buffer = ArrayPool<byte>.Shared.Rent(bufferSize);
+ int highwaterMark = 0;
+ try
+ {
+ int read;
+ while ((read = Read(buffer, 0, buffer.Length)) != 0)
+ {
+ if (read > highwaterMark) highwaterMark = read;
+ destination.Write(buffer, 0, read);
+ }
+ }
+ finally
+ {
+ Array.Clear(buffer, 0, highwaterMark); // clear only the most we used
+ ArrayPool<byte>.Shared.Return(buffer, clearArray: false);
+ }
}
// Stream used to require that all cleanup logic went into Close(),
@@ -265,14 +278,12 @@ namespace System.IO {
public abstract void Flush();
- [HostProtection(ExternalThreading=true)]
[ComVisible(false)]
public Task FlushAsync()
{
return FlushAsync(CancellationToken.None);
}
- [HostProtection(ExternalThreading=true)]
[ComVisible(false)]
public virtual Task FlushAsync(CancellationToken cancellationToken)
{
@@ -287,14 +298,12 @@ namespace System.IO {
return new ManualResetEvent(false);
}
- [HostProtection(ExternalThreading=true)]
public virtual IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, Object state)
{
Contract.Ensures(Contract.Result<IAsyncResult>() != null);
return BeginReadInternal(buffer, offset, count, callback, state, serializeAsynchronously: false, apm: true);
}
- [HostProtection(ExternalThreading = true)]
internal IAsyncResult BeginReadInternal(
byte[] buffer, int offset, int count, AsyncCallback callback, Object state,
bool serializeAsynchronously, bool apm)
@@ -326,7 +335,7 @@ namespace System.IO {
// As we're currently inside of it, we can get the current task
// and grab the parameters from it.
var thisTask = Task.InternalCurrent as ReadWriteTask;
- Contract.Assert(thisTask != null, "Inside ReadWriteTask, InternalCurrent should be the ReadWriteTask");
+ Debug.Assert(thisTask != null, "Inside ReadWriteTask, InternalCurrent should be the ReadWriteTask");
try
{
@@ -360,7 +369,7 @@ namespace System.IO {
public virtual int EndRead(IAsyncResult asyncResult)
{
if (asyncResult == null)
- throw new ArgumentNullException("asyncResult");
+ throw new ArgumentNullException(nameof(asyncResult));
Contract.Ensures(Contract.Result<int>() >= 0);
Contract.EndContractBlock();
@@ -389,14 +398,12 @@ namespace System.IO {
}
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public Task<int> ReadAsync(Byte[] buffer, int offset, int count)
{
return ReadAsync(buffer, offset, count, CancellationToken.None);
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public virtual Task<int> ReadAsync(Byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
@@ -407,7 +414,6 @@ namespace System.IO {
: BeginEndReadAsync(buffer, offset, count);
}
- [System.Security.SecuritySafeCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern bool HasOverriddenBeginEndRead();
@@ -436,14 +442,12 @@ namespace System.IO {
- [HostProtection(ExternalThreading=true)]
public virtual IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, Object state)
{
Contract.Ensures(Contract.Result<IAsyncResult>() != null);
return BeginWriteInternal(buffer, offset, count, callback, state, serializeAsynchronously: false, apm: true);
}
- [HostProtection(ExternalThreading = true)]
internal IAsyncResult BeginWriteInternal(
byte[] buffer, int offset, int count, AsyncCallback callback, Object state,
bool serializeAsynchronously, bool apm)
@@ -475,7 +479,7 @@ namespace System.IO {
// As we're currently inside of it, we can get the current task
// and grab the parameters from it.
var thisTask = Task.InternalCurrent as ReadWriteTask;
- Contract.Assert(thisTask != null, "Inside ReadWriteTask, InternalCurrent should be the ReadWriteTask");
+ Debug.Assert(thisTask != null, "Inside ReadWriteTask, InternalCurrent should be the ReadWriteTask");
try
{
@@ -508,20 +512,20 @@ namespace System.IO {
private void RunReadWriteTaskWhenReady(Task asyncWaiter, ReadWriteTask readWriteTask)
{
- Contract.Assert(readWriteTask != null); // Should be Contract.Requires, but CCRewrite is doing a poor job with
+ Debug.Assert(readWriteTask != null); // Should be Contract.Requires, but CCRewrite is doing a poor job with
// preconditions in async methods that await.
- Contract.Assert(asyncWaiter != null); // Ditto
+ Debug.Assert(asyncWaiter != null); // Ditto
// If the wait has already completed, run the task.
if (asyncWaiter.IsCompleted)
{
- Contract.Assert(asyncWaiter.IsRanToCompletion, "The semaphore wait should always complete successfully.");
+ 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) => {
- Contract.Assert(t.IsRanToCompletion, "The semaphore wait should always complete successfully.");
+ Debug.Assert(t.IsRanToCompletion, "The semaphore wait should always complete successfully.");
var rwt = (ReadWriteTask)state;
rwt._stream.RunReadWriteTask(rwt); // RunReadWriteTask(readWriteTask);
}, readWriteTask, default(CancellationToken), TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
@@ -531,7 +535,7 @@ namespace System.IO {
private void RunReadWriteTask(ReadWriteTask readWriteTask)
{
Contract.Requires(readWriteTask != null);
- Contract.Assert(_activeReadWriteTask == null, "Expected no other readers or writers");
+ Debug.Assert(_activeReadWriteTask == null, "Expected no other readers or writers");
// Schedule the task. ScheduleAndStart must happen after the write to _activeReadWriteTask to avoid a race.
// Internally, we're able to directly call ScheduleAndStart rather than Start, avoiding
@@ -545,14 +549,14 @@ namespace System.IO {
private void FinishTrackingAsyncOperation()
{
_activeReadWriteTask = null;
- Contract.Assert(_asyncActiveSemaphore != null, "Must have been initialized in order to get here.");
+ Debug.Assert(_asyncActiveSemaphore != null, "Must have been initialized in order to get here.");
_asyncActiveSemaphore.Release();
}
public virtual void EndWrite(IAsyncResult asyncResult)
{
if (asyncResult==null)
- throw new ArgumentNullException("asyncResult");
+ throw new ArgumentNullException(nameof(asyncResult));
Contract.EndContractBlock();
var writeTask = _activeReadWriteTask;
@@ -572,7 +576,7 @@ namespace System.IO {
try
{
writeTask.GetAwaiter().GetResult(); // block until completion, then propagate any exceptions
- Contract.Assert(writeTask.Status == TaskStatus.RanToCompletion);
+ Debug.Assert(writeTask.Status == TaskStatus.RanToCompletion);
}
finally
{
@@ -613,7 +617,6 @@ namespace System.IO {
_buffer = null;
}
- [SecuritySafeCritical] // necessary for EC.Capture
[MethodImpl(MethodImplOptions.NoInlining)]
public ReadWriteTask(
bool isRead,
@@ -651,7 +654,6 @@ namespace System.IO {
}
}
- [SecurityCritical] // necessary for CoreCLR
private static void InvokeAsyncCallback(object completedTask)
{
var rwc = (ReadWriteTask)completedTask;
@@ -660,10 +662,8 @@ namespace System.IO {
callback(rwc);
}
- [SecurityCritical] // necessary for CoreCLR
private static ContextCallback s_invokeAsyncCallback;
- [SecuritySafeCritical] // necessary for ExecutionContext.Run
void ITaskCompletionAction.Invoke(Task completingTask)
{
// Get the ExecutionContext. If there is none, just run the callback
@@ -690,7 +690,6 @@ namespace System.IO {
bool ITaskCompletionAction.InvokeMayRunArbitraryCode { get { return true; } }
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public Task WriteAsync(Byte[] buffer, int offset, int count)
{
@@ -699,7 +698,6 @@ namespace System.IO {
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public virtual Task WriteAsync(Byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
@@ -710,7 +708,6 @@ namespace System.IO {
: BeginEndWriteAsync(buffer, offset, count);
}
- [System.Security.SecuritySafeCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern bool HasOverriddenBeginEndWrite();
@@ -772,11 +769,10 @@ namespace System.IO {
Write(oneByteArray, 0, 1);
}
- [HostProtection(Synchronization=true)]
public static Stream Synchronized(Stream stream)
{
if (stream==null)
- throw new ArgumentNullException("stream");
+ throw new ArgumentNullException(nameof(stream));
Contract.Ensures(Contract.Result<Stream>() != null);
Contract.EndContractBlock();
if (stream is SyncStream)
@@ -853,23 +849,6 @@ namespace System.IO {
{
SynchronousAsyncResult.EndWrite(asyncResult);
}
-
- internal void ValidateCopyToArguments(Stream destination, int bufferSize)
- {
- if (destination == null)
- throw new ArgumentNullException("destination");
- if (bufferSize <= 0)
- throw new ArgumentOutOfRangeException("bufferSize", Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
- if (!CanRead && !CanWrite)
- throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_StreamClosed"));
- if (!destination.CanRead && !destination.CanWrite)
- throw new ObjectDisposedException("destination", Environment.GetResourceString("ObjectDisposed_StreamClosed"));
- if (!CanRead)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnreadableStream"));
- if (!destination.CanWrite)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnwritableStream"));
- Contract.EndContractBlock();
- }
[Serializable]
private sealed class NullStream : Stream
@@ -900,11 +879,18 @@ namespace System.IO {
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).
- ValidateCopyToArguments(destination, bufferSize);
+ StreamHelpers.ValidateCopyToArgs(this, destination, bufferSize);
return cancellationToken.IsCancellationRequested ?
Task.FromCanceled(cancellationToken) :
@@ -928,7 +914,6 @@ namespace System.IO {
Task.CompletedTask;
}
- [HostProtection(ExternalThreading = true)]
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, Object state)
{
if (!CanRead) __Error.ReadNotSupported();
@@ -939,13 +924,12 @@ namespace System.IO {
public override int EndRead(IAsyncResult asyncResult)
{
if (asyncResult == null)
- throw new ArgumentNullException("asyncResult");
+ throw new ArgumentNullException(nameof(asyncResult));
Contract.EndContractBlock();
return BlockingEndRead(asyncResult);
}
- [HostProtection(ExternalThreading = true)]
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, Object state)
{
if (!CanWrite) __Error.WriteNotSupported();
@@ -956,7 +940,7 @@ namespace System.IO {
public override void EndWrite(IAsyncResult asyncResult)
{
if (asyncResult == null)
- throw new ArgumentNullException("asyncResult");
+ throw new ArgumentNullException(nameof(asyncResult));
Contract.EndContractBlock();
BlockingEndWrite(asyncResult);
@@ -1102,7 +1086,7 @@ namespace System.IO {
internal SyncStream(Stream stream)
{
if (stream == null)
- throw new ArgumentNullException("stream");
+ throw new ArgumentNullException(nameof(stream));
Contract.EndContractBlock();
_stream = stream;
}
@@ -1217,7 +1201,6 @@ namespace System.IO {
return _stream.ReadByte();
}
- [HostProtection(ExternalThreading=true)]
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, Object state)
{
bool overridesBeginRead = _stream.HasOverriddenBeginEndRead();
@@ -1239,7 +1222,7 @@ namespace System.IO {
public override int EndRead(IAsyncResult asyncResult)
{
if (asyncResult == null)
- throw new ArgumentNullException("asyncResult");
+ throw new ArgumentNullException(nameof(asyncResult));
Contract.Ensures(Contract.Result<int>() >= 0);
Contract.EndContractBlock();
@@ -1271,7 +1254,6 @@ namespace System.IO {
_stream.WriteByte(b);
}
- [HostProtection(ExternalThreading=true)]
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, Object state)
{
bool overridesBeginWrite = _stream.HasOverriddenBeginEndWrite();
@@ -1293,7 +1275,7 @@ namespace System.IO {
public override void EndWrite(IAsyncResult asyncResult)
{
if (asyncResult == null)
- throw new ArgumentNullException("asyncResult");
+ throw new ArgumentNullException(nameof(asyncResult));
Contract.EndContractBlock();
lock(_stream)
diff --git a/src/mscorlib/src/System/IO/StreamHelpers.CopyValidation.cs b/src/mscorlib/src/System/IO/StreamHelpers.CopyValidation.cs
new file mode 100644
index 0000000000..8ff0e045ca
--- /dev/null
+++ b/src/mscorlib/src/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, 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 549733bb47..708db088e8 100644
--- a/src/mscorlib/src/System/IO/StreamReader.cs
+++ b/src/mscorlib/src/System/IO/StreamReader.cs
@@ -2,22 +2,10 @@
// 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 reading text from streams in a particular
-** encoding.
-**
-**
-===========================================================*/
-
-using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
+using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
using System.Security.Permissions;
@@ -161,11 +149,11 @@ namespace System.IO
public StreamReader(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool leaveOpen)
{
if (stream == null || encoding == null)
- throw new ArgumentNullException((stream == null ? "stream" : "encoding"));
+ throw new ArgumentNullException((stream == null ? nameof(stream) : nameof(encoding)));
if (!stream.CanRead)
throw new ArgumentException(Environment.GetResourceString("Argument_StreamNotReadable"));
if (bufferSize <= 0)
- throw new ArgumentOutOfRangeException("bufferSize", Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
+ throw new ArgumentOutOfRangeException(nameof(bufferSize), Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
Contract.EndContractBlock();
Init(stream, encoding, detectEncodingFromByteOrderMarks, bufferSize, leaveOpen);
@@ -187,26 +175,20 @@ namespace System.IO
: this(path, encoding, detectEncodingFromByteOrderMarks, DefaultBufferSize) {
}
- [System.Security.SecuritySafeCritical]
public StreamReader(String path, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize)
- : this(path, encoding, detectEncodingFromByteOrderMarks, bufferSize, true) {
- }
-
- [System.Security.SecurityCritical]
- internal StreamReader(String path, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool checkHost)
{
// Don't open a Stream before checking for invalid arguments,
// or we'll create a FileStream on disk and we won't close it until
// the finalizer runs, causing problems for applications.
if (path==null || encoding==null)
- throw new ArgumentNullException((path==null ? "path" : "encoding"));
+ throw new ArgumentNullException((path==null ? nameof(path) : nameof(encoding)));
if (path.Length==0)
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
if (bufferSize <= 0)
- throw new ArgumentOutOfRangeException("bufferSize", Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
+ throw new ArgumentOutOfRangeException(nameof(bufferSize), Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
Contract.EndContractBlock();
- Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultFileStreamBufferSize, FileOptions.SequentialScan, Path.GetFileName(path), false, false, checkHost);
+ Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultFileStreamBufferSize, FileOptions.SequentialScan, Path.GetFileName(path), false, false);
Init(stream, encoding, detectEncodingFromByteOrderMarks, bufferSize, false);
}
@@ -358,9 +340,9 @@ namespace System.IO
public override int Read([In, Out] char[] buffer, int index, int count)
{
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -416,9 +398,9 @@ namespace System.IO
public override int ReadBlock([In, Out] char[] buffer, int index, int count)
{
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -434,7 +416,7 @@ namespace System.IO
// Trims n bytes from the front of the buffer.
private void CompressBuffer(int n)
{
- Contract.Assert(byteLen >= n, "CompressBuffer was called with a number of bytes greater than the current buffer length. Are two threads using this StreamReader at the same time?");
+ Debug.Assert(byteLen >= n, "CompressBuffer was called with a number of bytes greater than the current buffer length. Are two threads using this StreamReader at the same time?");
Buffer.InternalBlockCopy(byteBuffer, n, byteBuffer, 0, byteLen - n);
byteLen -= n;
}
@@ -502,7 +484,7 @@ namespace System.IO
if (!_checkPreamble)
return _checkPreamble;
- Contract.Assert(bytePos <= _preamble.Length, "_compressPreamble was called with the current bytePos greater than the preamble buffer length. Are two threads using this StreamReader at the same time?");
+ Debug.Assert(bytePos <= _preamble.Length, "_compressPreamble was called with the current bytePos greater than the preamble buffer length. Are two threads using this StreamReader at the same time?");
int len = (byteLen >= (_preamble.Length))? (_preamble.Length - bytePos) : (byteLen - bytePos);
for(int i=0; i<len; i++, bytePos++) {
@@ -513,7 +495,7 @@ namespace System.IO
}
}
- Contract.Assert(bytePos <= _preamble.Length, "possible bug in _compressPreamble. Are two threads using this StreamReader at the same time?");
+ Debug.Assert(bytePos <= _preamble.Length, "possible bug in _compressPreamble. Are two threads using this StreamReader at the same time?");
if (_checkPreamble) {
if (bytePos == _preamble.Length) {
@@ -568,9 +550,9 @@ namespace System.IO
byteLen = 0;
do {
if (_checkPreamble) {
- Contract.Assert(bytePos <= _preamble.Length, "possible bug in _compressPreamble. Are two threads using this StreamReader at the same time?");
+ Debug.Assert(bytePos <= _preamble.Length, "possible bug in _compressPreamble. Are two threads using this StreamReader at the same time?");
int len = stream.Read(byteBuffer, bytePos, byteBuffer.Length - bytePos);
- Contract.Assert(len >= 0, "Stream.Read returned a negative number! This is a bug in your stream class.");
+ 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
@@ -588,9 +570,9 @@ namespace System.IO
byteLen += len;
}
else {
- Contract.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?");
+ 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 = stream.Read(byteBuffer, 0, byteBuffer.Length);
- Contract.Assert(byteLen >= 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 == 0) // We're at EOF
return charLen;
@@ -650,12 +632,12 @@ namespace System.IO
readToUserBuffer = desiredChars >= _maxCharsPerBuffer;
do {
- Contract.Assert(charsRead == 0);
+ Debug.Assert(charsRead == 0);
if (_checkPreamble) {
- Contract.Assert(bytePos <= _preamble.Length, "possible bug in _compressPreamble. Are two threads using this StreamReader at the same time?");
+ Debug.Assert(bytePos <= _preamble.Length, "possible bug in _compressPreamble. Are two threads using this StreamReader at the same time?");
int len = stream.Read(byteBuffer, bytePos, byteBuffer.Length - bytePos);
- Contract.Assert(len >= 0, "Stream.Read returned a negative number! This is a bug in your stream class.");
+ 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
@@ -677,11 +659,11 @@ namespace System.IO
byteLen += len;
}
else {
- Contract.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?");
+ 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 = stream.Read(byteBuffer, 0, byteBuffer.Length);
- Contract.Assert(byteLen >= 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 == 0) // EOF
break;
@@ -775,7 +757,6 @@ namespace System.IO
}
#region Task based Async APIs
- [HostProtection(ExternalThreading=true)]
[ComVisible(false)]
public override Task<String> ReadLineAsync()
{
@@ -856,7 +837,6 @@ namespace System.IO
return GetStringAndReleaseSharedStringBuilder(sb);
}
- [HostProtection(ExternalThreading=true)]
[ComVisible(false)]
public override Task<String> ReadToEndAsync()
{
@@ -893,14 +873,13 @@ namespace System.IO
return GetStringAndReleaseSharedStringBuilder(sb);
}
- [HostProtection(ExternalThreading=true)]
[ComVisible(false)]
public override Task<int> ReadAsync(char[] buffer, int index, int count)
{
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -957,14 +936,14 @@ namespace System.IO
// We break out of the loop if the stream is blocked (EOF is reached).
do
{
- Contract.Assert(n == 0);
+ Debug.Assert(n == 0);
if (CheckPreamble_Prop)
{
- Contract.Assert(BytePos_Prop <= Preamble_Prop.Length, "possible bug in _compressPreamble. Are two threads using this StreamReader at the same time?");
+ 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;
int len = await tmpStream.ReadAsync(tmpByteBuffer, tmpBytePos, tmpByteBuffer.Length - tmpBytePos).ConfigureAwait(false);
- Contract.Assert(len >= 0, "Stream.Read returned a negative number! This is a bug in your stream class.");
+ Debug.Assert(len >= 0, "Stream.Read returned a negative number! This is a bug in your stream class.");
if (len == 0)
{
@@ -985,7 +964,7 @@ namespace System.IO
}
// How can part of the preamble yield any chars?
- Contract.Assert(n == 0);
+ Debug.Assert(n == 0);
IsBlocked_Prop = true;
break;
@@ -997,11 +976,11 @@ namespace System.IO
}
else
{
- Contract.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_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);
- Contract.Assert(ByteLen_Prop >= 0, "Stream.Read returned a negative number! This is a bug in your stream class.");
+ Debug.Assert(ByteLen_Prop >= 0, "Stream.Read returned a negative number! This is a bug in your stream class.");
if (ByteLen_Prop == 0) // EOF
{
@@ -1031,7 +1010,7 @@ namespace System.IO
readToUserBuffer = count >= MaxCharsPerBuffer_Prop;
}
- Contract.Assert(n == 0);
+ Debug.Assert(n == 0);
CharPos_Prop = 0;
if (readToUserBuffer)
@@ -1039,7 +1018,7 @@ namespace System.IO
n += Decoder_Prop.GetChars(tmpByteBuffer, 0, ByteLen_Prop, buffer, index + charsRead);
// Why did the bytes yield no chars?
- Contract.Assert(n > 0);
+ Debug.Assert(n > 0);
CharLen_Prop = 0; // StreamReader's buffer is empty.
}
@@ -1048,7 +1027,7 @@ namespace System.IO
n = Decoder_Prop.GetChars(tmpByteBuffer, 0, ByteLen_Prop, CharBuffer_Prop, 0);
// Why did the bytes yield no chars?
- Contract.Assert(n > 0);
+ Debug.Assert(n > 0);
CharLen_Prop += n; // Number of chars in StreamReader's buffer.
}
@@ -1081,14 +1060,13 @@ namespace System.IO
return charsRead;
}
- [HostProtection(ExternalThreading=true)]
[ComVisible(false)]
public override Task<int> ReadBlockAsync(char[] buffer, int index, int count)
{
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -1185,10 +1163,10 @@ namespace System.IO
ByteLen_Prop = 0;
do {
if (CheckPreamble_Prop) {
- Contract.Assert(BytePos_Prop <= Preamble_Prop.Length, "possible bug in _compressPreamble. Are two threads using this StreamReader at the same time?");
+ 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;
int len = await tmpStream.ReadAsync(tmpByteBuffer, tmpBytePos, tmpByteBuffer.Length - tmpBytePos).ConfigureAwait(false);
- Contract.Assert(len >= 0, "Stream.Read returned a negative number! This is a bug in your stream class.");
+ 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
@@ -1206,9 +1184,9 @@ namespace System.IO
ByteLen_Prop += len;
}
else {
- Contract.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_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);
- Contract.Assert(ByteLen_Prop >= 0, "Stream.Read returned a negative number! Bug in stream class.");
+ Debug.Assert(ByteLen_Prop >= 0, "Stream.Read returned a negative number! Bug in stream class.");
if (ByteLen_Prop == 0) // We're at EOF
return CharLen_Prop;
diff --git a/src/mscorlib/src/System/IO/StreamWriter.cs b/src/mscorlib/src/System/IO/StreamWriter.cs
index 65613bb0a6..22eba82605 100644
--- a/src/mscorlib/src/System/IO/StreamWriter.cs
+++ b/src/mscorlib/src/System/IO/StreamWriter.cs
@@ -2,25 +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.
-/*============================================================
-**
-**
-**
-**
-**
-** Purpose: For writing text to streams in a particular
-** encoding.
-**
-**
-===========================================================*/
-using System;
using System.Text;
-using System.Threading;
-using System.Globalization;
using System.Runtime.CompilerServices;
-using System.Runtime.Versioning;
using System.Security.Permissions;
using System.Runtime.Serialization;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
@@ -45,10 +31,8 @@ namespace System.IO
private const int DefaultFileStreamBufferSize = 4096;
private const int MinBufferSize = 128;
- private const Int32 DontCopyOnWriteLineThreshold = 512;
-
// Bit bucket - Null has no backing store. Non closable.
- public new static readonly StreamWriter Null = new StreamWriter(Stream.Null, new UTF8Encoding(false, true), MinBufferSize, true);
+ public new static readonly StreamWriter Null = new StreamWriter(Stream.Null, UTF8NoBOM, MinBufferSize, true);
private Stream stream;
private Encoding encoding;
@@ -61,12 +45,6 @@ namespace System.IO
private bool haveWrittenPreamble;
private bool closable;
-#if MDA_SUPPORTED
- [NonSerialized]
- // For StreamWriterBufferedDataLost MDA
- private MdaHelper mdaHelper;
-#endif
-
// We don't guarantee thread safety on StreamWriter, but we should at
// least prevent users from trying to write anything while an Async
// write from the same thread is in progress.
@@ -93,20 +71,9 @@ namespace System.IO
// Even Close() will hit the exception as it would try to flush the unwritten data.
// Maybe we can add a DiscardBufferedData() method to get out of such situation (like
// StreamReader though for different reason). Either way, the buffered data will be lost!
- private static volatile Encoding _UTF8NoBOM;
-
internal static Encoding UTF8NoBOM {
[FriendAccessAllowed]
- get {
- if (_UTF8NoBOM == null) {
- // No need for double lock - we just want to avoid extra
- // allocations in the common case.
- UTF8Encoding noBOM = new UTF8Encoding(false, true);
- Thread.MemoryBarrier();
- _UTF8NoBOM = noBOM;
- }
- return _UTF8NoBOM;
- }
+ get { return EncodingCache.UTF8NoBOM; }
}
@@ -133,10 +100,10 @@ namespace System.IO
: base(null) // Ask for CurrentCulture all the time
{
if (stream == null || encoding == null)
- throw new ArgumentNullException((stream == null ? "stream" : "encoding"));
+ throw new ArgumentNullException((stream == null ? nameof(stream) : nameof(encoding)));
if (!stream.CanWrite)
throw new ArgumentException(Environment.GetResourceString("Argument_StreamNotWritable"));
- if (bufferSize <= 0) throw new ArgumentOutOfRangeException("bufferSize", Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
+ if (bufferSize <= 0) throw new ArgumentOutOfRangeException(nameof(bufferSize), Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
Contract.EndContractBlock();
Init(stream, encoding, bufferSize, leaveOpen);
@@ -154,28 +121,23 @@ namespace System.IO
: this(path, append, encoding, DefaultBufferSize) {
}
- [System.Security.SecuritySafeCritical]
- public StreamWriter(String path, bool append, Encoding encoding, int bufferSize): this(path, append, encoding, bufferSize, true) {
- }
-
- [System.Security.SecurityCritical]
- internal StreamWriter(String path, bool append, Encoding encoding, int bufferSize, bool checkHost)
+ public StreamWriter(String path, bool append, Encoding encoding, int bufferSize)
: base(null)
- { // Ask for CurrentCulture all the time
+ {
+ // Ask for CurrentCulture all the time
if (path == null)
- throw new ArgumentNullException("path");
+ throw new ArgumentNullException(nameof(path));
if (encoding == null)
- throw new ArgumentNullException("encoding");
+ throw new ArgumentNullException(nameof(encoding));
if (path.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
- if (bufferSize <= 0) throw new ArgumentOutOfRangeException("bufferSize", Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
+ if (bufferSize <= 0) throw new ArgumentOutOfRangeException(nameof(bufferSize), Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
Contract.EndContractBlock();
- Stream stream = CreateFile(path, append, checkHost);
+ Stream stream = CreateFile(path, append);
Init(stream, encoding, bufferSize, false);
}
- [System.Security.SecuritySafeCritical]
private void Init(Stream streamArg, Encoding encodingArg, int bufferSize, bool shouldLeaveOpen)
{
this.stream = streamArg;
@@ -190,21 +152,12 @@ namespace System.IO
if (stream.CanSeek && stream.Position > 0)
haveWrittenPreamble = true;
closable = !shouldLeaveOpen;
-#if MDA_SUPPORTED
- if (Mda.StreamWriterBufferedDataLost.Enabled) {
- String callstack = null;
- if (Mda.StreamWriterBufferedDataLost.CaptureAllocatedCallStack)
- callstack = Environment.GetStackTrace(null, false);
- mdaHelper = new MdaHelper(this, callstack);
- }
-#endif
}
- [System.Security.SecurityCritical]
- private static Stream CreateFile(String path, bool append, bool checkHost) {
+ private static Stream CreateFile(String path, bool append) {
FileMode mode = append? FileMode.Append: FileMode.Create;
FileStream f = new FileStream(path, mode, FileAccess.Write, FileShare.Read,
- DefaultFileStreamBufferSize, FileOptions.SequentialScan, Path.GetFileName(path), false, false, checkHost);
+ DefaultFileStreamBufferSize, FileOptions.SequentialScan, Path.GetFileName(path), false, false);
return f;
}
@@ -221,20 +174,11 @@ namespace System.IO
// is generally the right thing to do.
if (stream != null) {
// Note: flush on the underlying stream can throw (ex., low disk space)
-#if FEATURE_CORECLR
if (disposing)
-#else
- if (disposing || (LeaveOpen && stream is __ConsoleStream))
-#endif
{
CheckAsyncTaskInProgress();
Flush(true, true);
-#if MDA_SUPPORTED
- // Disable buffered data loss mda
- if (mdaHelper != null)
- GC.SuppressFinalize(mdaHelper);
-#endif
}
}
}
@@ -354,7 +298,7 @@ namespace System.IO
if (charPos == charLen) Flush(false, false);
int n = charLen - charPos;
if (n > count) n = count;
- Contract.Assert(n > 0, "StreamWriter::Write(char[]) isn't making progress! This is most likely a race condition in user code.");
+ Debug.Assert(n > 0, "StreamWriter::Write(char[]) isn't making progress! This is most likely a race condition in user code.");
Buffer.InternalBlockCopy(buffer, index * sizeof(char), charBuffer, charPos * sizeof(char), n * sizeof(char));
charPos += n;
index += n;
@@ -365,11 +309,11 @@ namespace System.IO
public override void Write(char[] buffer, int index, int count) {
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (index < 0)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -380,7 +324,7 @@ namespace System.IO
if (charPos == charLen) Flush(false, false);
int n = charLen - charPos;
if (n > count) n = count;
- Contract.Assert(n > 0, "StreamWriter::Write(char[], int, int) isn't making progress! This is most likely a race condition in user code.");
+ Debug.Assert(n > 0, "StreamWriter::Write(char[], int, int) isn't making progress! This is most likely a race condition in user code.");
Buffer.InternalBlockCopy(buffer, index * sizeof(char), charBuffer, charPos * sizeof(char), n * sizeof(char));
charPos += n;
index += n;
@@ -402,7 +346,7 @@ namespace System.IO
if (charPos == charLen) Flush(false, false);
int n = charLen - charPos;
if (n > count) n = count;
- Contract.Assert(n > 0, "StreamWriter::Write(String) isn't making progress! This is most likely a race condition in user code.");
+ Debug.Assert(n > 0, "StreamWriter::Write(String) isn't making progress! This is most likely a race condition in user code.");
value.CopyTo(index, charBuffer, charPos, n);
charPos += n;
index += n;
@@ -413,7 +357,6 @@ namespace System.IO
}
#region Task based Async APIs
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public override Task WriteAsync(char value)
{
@@ -444,7 +387,7 @@ namespace System.IO
{
if (charPos == charLen) {
await _this.FlushAsyncInternal(false, false, charBuffer, charPos).ConfigureAwait(false);
- Contract.Assert(_this.charPos == 0);
+ Debug.Assert(_this.charPos == 0);
charPos = 0;
}
@@ -457,7 +400,7 @@ namespace System.IO
{
if (charPos == charLen) {
await _this.FlushAsyncInternal(false, false, charBuffer, charPos).ConfigureAwait(false);
- Contract.Assert(_this.charPos == 0);
+ Debug.Assert(_this.charPos == 0);
charPos = 0;
}
@@ -468,14 +411,13 @@ namespace System.IO
if (autoFlush) {
await _this.FlushAsyncInternal(true, false, charBuffer, charPos).ConfigureAwait(false);
- Contract.Assert(_this.charPos == 0);
+ Debug.Assert(_this.charPos == 0);
charPos = 0;
}
_this.CharPos_Prop = charPos;
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public override Task WriteAsync(String value)
{
@@ -520,7 +462,7 @@ namespace System.IO
{
if (charPos == charLen) {
await _this.FlushAsyncInternal(false, false, charBuffer, charPos).ConfigureAwait(false);
- Contract.Assert(_this.charPos == 0);
+ Debug.Assert(_this.charPos == 0);
charPos = 0;
}
@@ -528,7 +470,7 @@ namespace System.IO
if (n > count)
n = count;
- Contract.Assert(n > 0, "StreamWriter::Write(String) isn't making progress! This is most likely a race condition in user code.");
+ Debug.Assert(n > 0, "StreamWriter::Write(String) isn't making progress! This is most likely a race condition in user code.");
value.CopyTo(index, charBuffer, charPos, n);
@@ -543,7 +485,7 @@ namespace System.IO
{
if (charPos == charLen) {
await _this.FlushAsyncInternal(false, false, charBuffer, charPos).ConfigureAwait(false);
- Contract.Assert(_this.charPos == 0);
+ Debug.Assert(_this.charPos == 0);
charPos = 0;
}
@@ -554,23 +496,22 @@ namespace System.IO
if (autoFlush) {
await _this.FlushAsyncInternal(true, false, charBuffer, charPos).ConfigureAwait(false);
- Contract.Assert(_this.charPos == 0);
+ Debug.Assert(_this.charPos == 0);
charPos = 0;
}
_this.CharPos_Prop = charPos;
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public override Task WriteAsync(char[] buffer, int index, int count)
{
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (index < 0)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -609,14 +550,14 @@ namespace System.IO
{
if (charPos == charLen) {
await _this.FlushAsyncInternal(false, false, charBuffer, charPos).ConfigureAwait(false);
- Contract.Assert(_this.charPos == 0);
+ Debug.Assert(_this.charPos == 0);
charPos = 0;
}
int n = charLen - charPos;
if (n > count) n = count;
- Contract.Assert(n > 0, "StreamWriter::Write(char[], int, int) isn't making progress! This is most likely a race condition in user code.");
+ Debug.Assert(n > 0, "StreamWriter::Write(char[], int, int) isn't making progress! This is most likely a race condition in user code.");
Buffer.InternalBlockCopy(buffer, index * sizeof(char), charBuffer, charPos * sizeof(char), n * sizeof(char));
@@ -631,7 +572,7 @@ namespace System.IO
{
if (charPos == charLen) {
await _this.FlushAsyncInternal(false, false, charBuffer, charPos).ConfigureAwait(false);
- Contract.Assert(_this.charPos == 0);
+ Debug.Assert(_this.charPos == 0);
charPos = 0;
}
@@ -642,14 +583,13 @@ namespace System.IO
if (autoFlush) {
await _this.FlushAsyncInternal(true, false, charBuffer, charPos).ConfigureAwait(false);
- Contract.Assert(_this.charPos == 0);
+ Debug.Assert(_this.charPos == 0);
charPos = 0;
}
_this.CharPos_Prop = charPos;
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public override Task WriteLineAsync()
{
@@ -672,7 +612,6 @@ namespace System.IO
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public override Task WriteLineAsync(char value)
{
@@ -695,7 +634,6 @@ namespace System.IO
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public override Task WriteLineAsync(String value)
{
@@ -718,16 +656,15 @@ namespace System.IO
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public override Task WriteLineAsync(char[] buffer, int index, int count)
{
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (index < 0)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -751,7 +688,6 @@ namespace System.IO
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public override Task FlushAsync()
{
@@ -825,42 +761,5 @@ namespace System.IO
await stream.FlushAsync().ConfigureAwait(false);
}
#endregion
-
-#if MDA_SUPPORTED
- // StreamWriterBufferedDataLost MDA
- // Instead of adding a finalizer to StreamWriter for detecting buffered data loss
- // (ie, when the user forgets to call Close/Flush on the StreamWriter), we will
- // have a separate object with normal finalization semantics that maintains a
- // back pointer to this StreamWriter and alerts about any data loss
- private sealed class MdaHelper
- {
- private StreamWriter streamWriter;
- private String allocatedCallstack; // captures the callstack when this streamwriter was allocated
-
- internal MdaHelper(StreamWriter sw, String cs)
- {
- streamWriter = sw;
- allocatedCallstack = cs;
- }
-
- // Finalizer
- ~MdaHelper()
- {
- // Make sure people closed this StreamWriter, exclude StreamWriter::Null.
- if (streamWriter.charPos != 0 && streamWriter.stream != null && streamWriter.stream != Stream.Null) {
- String fileName = (streamWriter.stream is FileStream) ? ((FileStream)streamWriter.stream).NameInternal : "<unknown>";
- String callStack = allocatedCallstack;
-
- if (callStack == null)
- callStack = Environment.GetResourceString("IO_StreamWriterBufferedDataLostCaptureAllocatedFromCallstackNotEnabled");
-
- String message = Environment.GetResourceString("IO_StreamWriterBufferedDataLost", streamWriter.stream.GetType().FullName, fileName, callStack);
-
- Mda.StreamWriterBufferedDataLost.ReportError(message);
- }
- }
- } // class MdaHelper
-#endif // MDA_SUPPORTED
-
} // class StreamWriter
} // namespace
diff --git a/src/mscorlib/src/System/IO/StringReader.cs b/src/mscorlib/src/System/IO/StringReader.cs
deleted file mode 100644
index e5fa811453..0000000000
--- a/src/mscorlib/src/System/IO/StringReader.cs
+++ /dev/null
@@ -1,187 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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 reading text from strings
-**
-**
-===========================================================*/
-
-using System;
-using System.Runtime.InteropServices;
-using System.Diagnostics.Contracts;
-using System.Security.Permissions;
-using System.Threading.Tasks;
-
-namespace System.IO {
- // This class implements a text reader that reads from a string.
- //
- [Serializable]
- [ComVisible(true)]
- public class StringReader : TextReader
- {
- private String _s;
- private int _pos;
- private int _length;
-
- public StringReader(String s) {
- if (s == null)
- throw new ArgumentNullException("s");
- Contract.EndContractBlock();
- _s = s;
- _length = s == null? 0: s.Length;
- }
-
- // Closes this StringReader. Following a call to this method, the String
- // Reader will throw an ObjectDisposedException.
- public override void Close() {
- Dispose(true);
- }
-
- protected override void Dispose(bool disposing) {
- _s = null;
- _pos = 0;
- _length = 0;
- base.Dispose(disposing);
- }
-
- // Returns the next available character without actually reading it from
- // the underlying string. The current position of the StringReader is not
- // changed by this operation. The returned value is -1 if no further
- // characters are available.
- //
- [Pure]
- public override int Peek() {
- if (_s == null)
- __Error.ReaderClosed();
- if (_pos == _length) return -1;
- return _s[_pos];
- }
-
- // Reads the next character from the underlying string. The returned value
- // is -1 if no further characters are available.
- //
- public override int Read() {
- if (_s == null)
- __Error.ReaderClosed();
- if (_pos == _length) return -1;
- return _s[_pos++];
- }
-
- // Reads a block of characters. This method will read up to count
- // characters from this StringReader into the buffer character
- // array starting at position index. Returns the actual number of
- // characters read, or zero if the end of the string is reached.
- //
- public override int Read([In, Out] char[] buffer, int index, int count) {
- if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
- if (index < 0)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (buffer.Length - index < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
- Contract.EndContractBlock();
- if (_s == null)
- __Error.ReaderClosed();
-
- int n = _length - _pos;
- if (n > 0) {
- if (n > count) n = count;
- _s.CopyTo(_pos, buffer, index, n);
- _pos += n;
- }
- return n;
- }
-
- public override String ReadToEnd()
- {
- if (_s == null)
- __Error.ReaderClosed();
- String s;
- if (_pos==0)
- s = _s;
- else
- s = _s.Substring(_pos, _length - _pos);
- _pos = _length;
- return s;
- }
-
- // Reads a line. A line is defined as a sequence of characters followed by
- // a carriage return ('\r'), a line feed ('\n'), or a carriage return
- // immediately followed by a line feed. The resulting string does not
- // contain the terminating carriage return and/or line feed. The returned
- // value is null if the end of the underlying string has been reached.
- //
- public override String ReadLine() {
- if (_s == null)
- __Error.ReaderClosed();
- int i = _pos;
- while (i < _length) {
- char ch = _s[i];
- if (ch == '\r' || ch == '\n') {
- String result = _s.Substring(_pos, i - _pos);
- _pos = i + 1;
- if (ch == '\r' && _pos < _length && _s[_pos] == '\n') _pos++;
- return result;
- }
- i++;
- }
- if (i > _pos) {
- String result = _s.Substring(_pos, i - _pos);
- _pos = i;
- return result;
- }
- return null;
- }
-
- #region Task based Async APIs
- [ComVisible(false)]
- public override Task<String> ReadLineAsync()
- {
- return Task.FromResult(ReadLine());
- }
-
- [ComVisible(false)]
- public override Task<String> ReadToEndAsync()
- {
- return Task.FromResult(ReadToEnd());
- }
-
- [ComVisible(false)]
- public override Task<int> ReadBlockAsync(char[] buffer, int index, int count)
- {
- if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
- if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (buffer.Length - index < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
-
- Contract.EndContractBlock();
-
- return Task.FromResult(ReadBlock(buffer, index, count));
- }
-
- [ComVisible(false)]
- public override Task<int> ReadAsync(char[] buffer, int index, int count)
- {
- if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
- if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (buffer.Length - index < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
- Contract.EndContractBlock();
-
- return Task.FromResult(Read(buffer, index, count));
- }
- #endregion
- }
-}
diff --git a/src/mscorlib/src/System/IO/StringWriter.cs b/src/mscorlib/src/System/IO/StringWriter.cs
deleted file mode 100644
index 282a7910c2..0000000000
--- a/src/mscorlib/src/System/IO/StringWriter.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: For writing text to a string
-**
-**
-===========================================================*/
-
-using System;
-using System.Runtime;
-using System.Text;
-using System.Globalization;
-using System.Diagnostics.Contracts;
-using System.Runtime.InteropServices;
-using System.Security.Permissions;
-using System.Threading.Tasks;
-
-namespace System.IO {
- // This class implements a text writer that writes to a string buffer and allows
- // the resulting sequence of characters to be presented as a string.
- //
- [Serializable]
- [ComVisible(true)]
- public class StringWriter : TextWriter
- {
- private static volatile UnicodeEncoding m_encoding=null;
-
- private StringBuilder _sb;
- private bool _isOpen;
-
- // Constructs a new StringWriter. A new StringBuilder is automatically
- // created and associated with the new StringWriter.
- public StringWriter()
- : this(new StringBuilder(), CultureInfo.CurrentCulture)
- {
- }
-
- public StringWriter(IFormatProvider formatProvider)
- : this(new StringBuilder(), formatProvider) {
- }
-
- // Constructs a new StringWriter that writes to the given StringBuilder.
- //
- public StringWriter(StringBuilder sb) : this(sb, CultureInfo.CurrentCulture) {
- }
-
- public StringWriter(StringBuilder sb, IFormatProvider formatProvider) : base(formatProvider) {
- if (sb==null)
- throw new ArgumentNullException("sb", Environment.GetResourceString("ArgumentNull_Buffer"));
- Contract.EndContractBlock();
- _sb = sb;
- _isOpen = true;
- }
-
- public override void Close()
- {
- Dispose(true);
- }
-
- protected override void Dispose(bool disposing)
- {
- // Do not destroy _sb, so that we can extract this after we are
- // done writing (similar to MemoryStream's GetBuffer & ToArray methods)
- _isOpen = false;
- base.Dispose(disposing);
- }
-
-
- public override Encoding Encoding {
- get {
- if (m_encoding==null) {
- m_encoding = new UnicodeEncoding(false, false);
- }
- return m_encoding;
- }
- }
-
- // Returns the underlying StringBuilder. This is either the StringBuilder
- // that was passed to the constructor, or the StringBuilder that was
- // automatically created.
- //
- public virtual StringBuilder GetStringBuilder() {
- return _sb;
- }
-
- // Writes a character to the underlying string buffer.
- //
- public override void Write(char value) {
- if (!_isOpen)
- __Error.WriterClosed();
- _sb.Append(value);
- }
-
- // Writes a range of a character array to the underlying string buffer.
- // This method will write count characters of data into this
- // StringWriter from the buffer character array starting at position
- // index.
- //
- public override void Write(char[] buffer, int index, int count) {
- if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
- if (index < 0)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- if (buffer.Length - index < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
- Contract.EndContractBlock();
-
- if (!_isOpen)
- __Error.WriterClosed();
-
- _sb.Append(buffer, index, count);
- }
-
- // Writes a string to the underlying string buffer. If the given string is
- // null, nothing is written.
- //
- public override void Write(String value) {
- if (!_isOpen)
- __Error.WriterClosed();
- if (value != null) _sb.Append(value);
- }
-
-
- #region Task based Async APIs
- [HostProtection(ExternalThreading = true)]
- [ComVisible(false)]
- public override Task WriteAsync(char value)
- {
- Write(value);
- return Task.CompletedTask;
- }
-
- [HostProtection(ExternalThreading = true)]
- [ComVisible(false)]
- public override Task WriteAsync(String value)
- {
- Write(value);
- return Task.CompletedTask;
- }
-
- [HostProtection(ExternalThreading = true)]
- [ComVisible(false)]
- public override Task WriteAsync(char[] buffer, int index, int count)
- {
- Write(buffer, index, count);
- return Task.CompletedTask;
- }
-
- [HostProtection(ExternalThreading = true)]
- [ComVisible(false)]
- public override Task WriteLineAsync(char value)
- {
- WriteLine(value);
- return Task.CompletedTask;
- }
-
- [HostProtection(ExternalThreading = true)]
- [ComVisible(false)]
- public override Task WriteLineAsync(String value)
- {
- WriteLine(value);
- return Task.CompletedTask;
- }
-
- [HostProtection(ExternalThreading = true)]
- [ComVisible(false)]
- public override Task WriteLineAsync(char[] buffer, int index, int count)
- {
- WriteLine(buffer, index, count);
- return Task.CompletedTask;
- }
-
- [HostProtection(ExternalThreading = true)]
- [ComVisible(false)]
- public override Task FlushAsync()
- {
- return Task.CompletedTask;
- }
- #endregion
-
- // Returns a string containing the characters written to this TextWriter
- // so far.
- //
- public override String ToString() {
- return _sb.ToString();
- }
- }
-}
diff --git a/src/mscorlib/src/System/IO/TextReader.cs b/src/mscorlib/src/System/IO/TextReader.cs
index ede482784a..6cbadfbce5 100644
--- a/src/mscorlib/src/System/IO/TextReader.cs
+++ b/src/mscorlib/src/System/IO/TextReader.cs
@@ -14,11 +14,9 @@
**
===========================================================*/
-using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
-using System.Reflection;
using System.Security.Permissions;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
@@ -35,11 +33,7 @@ namespace System.IO {
// There are methods on the Stream class for reading bytes.
[Serializable]
[ComVisible(true)]
-#if FEATURE_REMOTING
public abstract class TextReader : MarshalByRefObject, IDisposable {
-#else // FEATURE_REMOTING
- public abstract class TextReader : IDisposable {
-#endif // FEATURE_REMOTING
public static readonly TextReader Null = new NullTextReader();
@@ -101,11 +95,11 @@ namespace System.IO {
public virtual int Read([In, Out] char[] buffer, int index, int count)
{
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (index < 0)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.Ensures(Contract.Result<int>() >= 0);
@@ -176,7 +170,6 @@ namespace System.IO {
}
#region Task based Async APIs
- [HostProtection(ExternalThreading=true)]
[ComVisible(false)]
public virtual Task<String> ReadLineAsync()
{
@@ -187,7 +180,6 @@ namespace System.IO {
this, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
}
- [HostProtection(ExternalThreading=true)]
[ComVisible(false)]
public async virtual Task<String> ReadToEndAsync()
{
@@ -201,14 +193,13 @@ namespace System.IO {
return sb.ToString();
}
- [HostProtection(ExternalThreading=true)]
[ComVisible(false)]
public virtual Task<int> ReadAsync(char[] buffer, int index, int count)
{
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -232,14 +223,13 @@ namespace System.IO {
tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
}
- [HostProtection(ExternalThreading=true)]
[ComVisible(false)]
public virtual Task<int> ReadBlockAsync(char[] buffer, int index, int count)
{
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
@@ -248,7 +238,6 @@ namespace System.IO {
return ReadBlockAsyncInternal(buffer, index, count);
}
- [HostProtection(ExternalThreading=true)]
private async Task<int> ReadBlockAsyncInternal(char[] buffer, int index, int count)
{
Contract.Requires(buffer != null);
@@ -267,11 +256,10 @@ namespace System.IO {
}
#endregion
- [HostProtection(Synchronization=true)]
public static TextReader Synchronized(TextReader reader)
{
if (reader==null)
- throw new ArgumentNullException("reader");
+ throw new ArgumentNullException(nameof(reader));
Contract.Ensures(Contract.Result<TextReader>() != null);
Contract.EndContractBlock();
@@ -383,9 +371,9 @@ namespace System.IO {
public override Task<int> ReadBlockAsync(char[] buffer, int index, int count)
{
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
@@ -399,9 +387,9 @@ namespace System.IO {
public override Task<int> ReadAsync(char[] buffer, int index, int count)
{
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
diff --git a/src/mscorlib/src/System/IO/TextWriter.cs b/src/mscorlib/src/System/IO/TextWriter.cs
index 165001e1a6..131f69d35d 100644
--- a/src/mscorlib/src/System/IO/TextWriter.cs
+++ b/src/mscorlib/src/System/IO/TextWriter.cs
@@ -2,24 +2,10 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-/*============================================================
-**
-**
-**
-**
-**
-** Purpose: Abstract base class for Text-only Writers.
-** Subclasses will include StreamWriter & StringWriter.
-**
-**
-===========================================================*/
-
-using System;
using System.Text;
using System.Threading;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-using System.Reflection;
using System.Security.Permissions;
using System.Globalization;
using System.Diagnostics.CodeAnalysis;
@@ -35,11 +21,7 @@ namespace System.IO {
// There are methods on the Stream class for writing bytes.
[Serializable]
[ComVisible(true)]
-#if FEATURE_REMOTING
public abstract class TextWriter : MarshalByRefObject, IDisposable {
-#else // FEATURE_REMOTING
- public abstract class TextWriter : IDisposable {
-#endif // FEATURE_REMOTING
public static readonly TextWriter Null = new NullTextWriter();
// This should be initialized to Environment.NewLine, but
@@ -128,10 +110,9 @@ namespace System.IO {
}
- [HostProtection(Synchronization=true)]
public static TextWriter Synchronized(TextWriter writer) {
if (writer==null)
- throw new ArgumentNullException("writer");
+ throw new ArgumentNullException(nameof(writer));
Contract.Ensures(Contract.Result<TextWriter>() != null);
Contract.EndContractBlock();
@@ -162,11 +143,11 @@ namespace System.IO {
//
public virtual void Write(char[] buffer, int index, int count) {
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (index < 0)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -490,7 +471,6 @@ namespace System.IO {
}
#region Task based Async APIs
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public virtual Task WriteAsync(char value)
{
@@ -503,7 +483,6 @@ namespace System.IO {
tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public virtual Task WriteAsync(String value)
{
@@ -516,7 +495,6 @@ namespace System.IO {
tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public Task WriteAsync(char[] buffer)
{
@@ -524,7 +502,6 @@ namespace System.IO {
return WriteAsync(buffer, 0, buffer.Length);
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public virtual Task WriteAsync(char[] buffer, int index, int count)
{
@@ -537,7 +514,6 @@ namespace System.IO {
tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public virtual Task WriteLineAsync(char value)
{
@@ -550,7 +526,6 @@ namespace System.IO {
tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public virtual Task WriteLineAsync(String value)
{
@@ -563,7 +538,6 @@ namespace System.IO {
tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public Task WriteLineAsync(char[] buffer)
{
@@ -571,7 +545,6 @@ namespace System.IO {
return WriteLineAsync(buffer, 0, buffer.Length);
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public virtual Task WriteLineAsync(char[] buffer, int index, int count)
{
@@ -584,14 +557,12 @@ namespace System.IO {
tuple, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public virtual Task WriteLineAsync()
{
return WriteAsync(CoreNewLine);
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public virtual Task FlushAsync()
{
diff --git a/src/mscorlib/src/System/IO/UnmanagedMemoryAccessor.cs b/src/mscorlib/src/System/IO/UnmanagedMemoryAccessor.cs
index ea70057217..4208ebfb6d 100644
--- a/src/mscorlib/src/System/IO/UnmanagedMemoryAccessor.cs
+++ b/src/mscorlib/src/System/IO/UnmanagedMemoryAccessor.cs
@@ -19,6 +19,7 @@ using System.Runtime.ConstrainedExecution;
using System.Runtime.Versioning;
using System.Security.Permissions;
using Microsoft.Win32.SafeHandles;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
namespace System.IO {
@@ -28,7 +29,6 @@ namespace System.IO {
/// this gives better throughput; benchmarks showed about 12-15% better.
public class UnmanagedMemoryAccessor : IDisposable {
- [System.Security.SecurityCritical] // auto-generated
private SafeBuffer _buffer;
private Int64 _offset;
[ContractPublicPropertyName("Capacity")]
@@ -46,35 +46,29 @@ namespace System.IO {
// <SecurityKernel Critical="True" Ring="1">
// <ReferencesCritical Name="Method: Initialize(SafeBuffer, Int64, Int64, FileAccess):Void" Ring="1" />
// </SecurityKernel>
- [System.Security.SecuritySafeCritical]
public UnmanagedMemoryAccessor(SafeBuffer buffer, Int64 offset, Int64 capacity) {
Initialize(buffer, offset, capacity, FileAccess.Read);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public UnmanagedMemoryAccessor(SafeBuffer buffer, Int64 offset, Int64 capacity, FileAccess access) {
Initialize(buffer, offset, capacity, access);
}
- [System.Security.SecuritySafeCritical] // auto-generated
-#pragma warning disable 618
- [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
-#pragma warning restore 618
protected void Initialize(SafeBuffer buffer, Int64 offset, Int64 capacity, FileAccess access) {
if (buffer == null) {
- throw new ArgumentNullException("buffer");
+ throw new ArgumentNullException(nameof(buffer));
}
if (offset < 0) {
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (capacity < 0) {
- throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(capacity), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (buffer.ByteLength < (UInt64)(offset + capacity)) {
throw new ArgumentException(Environment.GetResourceString("Argument_OffsetAndCapacityOutOfBounds"));
}
if (access < FileAccess.Read || access > FileAccess.ReadWrite) {
- throw new ArgumentOutOfRangeException("access");
+ throw new ArgumentOutOfRangeException(nameof(access));
}
Contract.EndContractBlock();
@@ -155,7 +149,6 @@ namespace System.IO {
return InternalReadByte(position);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public char ReadChar(Int64 position) {
int sizeOfType = sizeof(char);
EnsureSafeToRead(position, sizeOfType);
@@ -192,7 +185,6 @@ namespace System.IO {
}
// See comment above.
- [System.Security.SecuritySafeCritical]
public Int16 ReadInt16(Int64 position) {
int sizeOfType = sizeof(Int16);
EnsureSafeToRead(position, sizeOfType);
@@ -229,7 +221,6 @@ namespace System.IO {
}
- [System.Security.SecuritySafeCritical] // auto-generated
public Int32 ReadInt32(Int64 position) {
int sizeOfType = sizeof(Int32);
EnsureSafeToRead(position, sizeOfType);
@@ -264,7 +255,6 @@ namespace System.IO {
return result;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public Int64 ReadInt64(Int64 position) {
int sizeOfType = sizeof(Int64);
EnsureSafeToRead(position, sizeOfType);
@@ -301,18 +291,63 @@ namespace System.IO {
return result;
}
- [System.Security.SecuritySafeCritical] // auto-generated
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private unsafe Int32 UnsafeReadInt32(byte* pointer)
+ {
+ 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);
- int[] decimalArray = new int[4];
- ReadArray<int>(position, decimalArray, 0, decimalArray.Length);
+ unsafe
+ {
+ byte* pointer = null;
+ try
+ {
+ _buffer.AcquirePointer(ref pointer);
+ pointer += (_offset + position);
- return new Decimal(decimalArray);
+ 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);
+ }
+ finally
+ {
+ if (pointer != null)
+ {
+ _buffer.ReleasePointer();
+ }
+ }
+ }
}
- [System.Security.SecuritySafeCritical] // auto-generated
public Single ReadSingle(Int64 position) {
int sizeOfType = sizeof(Single);
EnsureSafeToRead(position, sizeOfType);
@@ -329,7 +364,7 @@ namespace System.IO {
// check if pointer is aligned
if (((int)pointer & (sizeOfType - 1)) == 0) {
#endif
- result = *((Single*)(pointer));
+ result = BitConverter.Int32BitsToSingle(*((int*)(pointer)));
#if ALIGN_ACCESS
}
else {
@@ -348,7 +383,6 @@ namespace System.IO {
return result;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public Double ReadDouble(Int64 position) {
int sizeOfType = sizeof(Double);
EnsureSafeToRead(position, sizeOfType);
@@ -365,7 +399,7 @@ namespace System.IO {
// check if pointer is aligned
if (((int)pointer & (sizeOfType - 1)) == 0) {
#endif
- result = *((Double*)(pointer));
+ result = BitConverter.Int64BitsToDouble(*((long*)(pointer)));
#if ALIGN_ACCESS
}
else {
@@ -388,7 +422,6 @@ namespace System.IO {
return result;
}
- [System.Security.SecuritySafeCritical] // auto-generated
[CLSCompliant(false)]
public SByte ReadSByte(Int64 position) {
int sizeOfType = sizeof(SByte);
@@ -413,7 +446,6 @@ namespace System.IO {
return result;
}
- [System.Security.SecuritySafeCritical] // auto-generated
[CLSCompliant(false)]
public UInt16 ReadUInt16(Int64 position) {
int sizeOfType = sizeof(UInt16);
@@ -450,7 +482,6 @@ namespace System.IO {
return result;
}
- [System.Security.SecuritySafeCritical] // auto-generated
[CLSCompliant(false)]
public UInt32 ReadUInt32(Int64 position) {
int sizeOfType = sizeof(UInt32);
@@ -487,7 +518,6 @@ namespace System.IO {
return result;
}
- [System.Security.SecuritySafeCritical] // auto-generated
[CLSCompliant(false)]
public UInt64 ReadUInt64(Int64 position) {
int sizeOfType = sizeof(UInt64);
@@ -540,10 +570,9 @@ namespace System.IO {
// such, it is best to use the ReadXXX methods for small standard types such as ints, longs,
// bools, etc.
- [System.Security.SecurityCritical] // auto-generated_required
public void Read<T>(Int64 position, out T structure) where T : struct {
if (position < 0) {
- throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
Contract.EndContractBlock();
@@ -557,10 +586,10 @@ namespace System.IO {
UInt32 sizeOfT = Marshal.SizeOfType(typeof(T));
if (position > _capacity - sizeOfT) {
if (position >= _capacity) {
- throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
+ throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
}
else {
- throw new ArgumentException(Environment.GetResourceString("Argument_NotEnoughBytesToRead", typeof(T).FullName), "position");
+ throw new ArgumentException(Environment.GetResourceString("Argument_NotEnoughBytesToRead", typeof(T).FullName), nameof(position));
}
}
@@ -573,16 +602,15 @@ namespace System.IO {
// struct that contains reference members will most likely cause the runtime to AV. This
// is consistent with Marshal.PtrToStructure.
- [System.Security.SecurityCritical] // auto-generated_required
public int ReadArray<T>(Int64 position, T[] array, Int32 offset, Int32 count) where T : struct {
if (array == null) {
- throw new ArgumentNullException("array", "Buffer cannot be null.");
+ throw new ArgumentNullException(nameof(array), "Buffer cannot be null.");
}
if (offset < 0) {
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (count < 0) {
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (array.Length - offset < count) {
throw new ArgumentException(Environment.GetResourceString("Argument_OffsetAndLengthOutOfBounds"));
@@ -597,14 +625,14 @@ namespace System.IO {
}
}
if (position < 0) {
- throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("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("position", Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
+ throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
}
int n = count;
@@ -647,7 +675,6 @@ namespace System.IO {
InternalWrite(position, value);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void Write(Int64 position, char value) {
int sizeOfType = sizeof(char);
EnsureSafeToWrite(position, sizeOfType);
@@ -682,7 +709,6 @@ namespace System.IO {
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void Write(Int64 position, Int16 value) {
int sizeOfType = sizeof(Int16);
EnsureSafeToWrite(position, sizeOfType);
@@ -716,7 +742,6 @@ namespace System.IO {
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void Write(Int64 position, Int32 value) {
int sizeOfType = sizeof(Int32);
EnsureSafeToWrite(position, sizeOfType);
@@ -751,7 +776,6 @@ namespace System.IO {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void Write(Int64 position, Int64 value) {
int sizeOfType = sizeof(Int64);
EnsureSafeToWrite(position, sizeOfType);
@@ -789,28 +813,56 @@ namespace System.IO {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private unsafe void UnsafeWriteInt32(byte* pointer, Int32 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);
- byte[] decimalArray = new byte[16];
- Decimal.GetBytes(value, decimalArray);
+ unsafe
+ {
+ byte* pointer = null;
+ try
+ {
+ _buffer.AcquirePointer(ref pointer);
+ pointer += (_offset + position);
- int[] bits = new int[4];
- int flags = ((int)decimalArray[12]) | ((int)decimalArray[13] << 8) | ((int)decimalArray[14] << 16) | ((int)decimalArray[15] << 24);
- int lo = ((int)decimalArray[0]) | ((int)decimalArray[1] << 8) | ((int)decimalArray[2] << 16) | ((int)decimalArray[3] << 24);
- int mid = ((int)decimalArray[4]) | ((int)decimalArray[5] << 8) | ((int)decimalArray[6] << 16) | ((int)decimalArray[7] << 24);
- int hi = ((int)decimalArray[8]) | ((int)decimalArray[9] << 8) | ((int)decimalArray[10] << 16) | ((int)decimalArray[11] << 24);
- bits[0] = lo;
- bits[1] = mid;
- bits[2] = hi;
- bits[3] = flags;
+ int* valuePtr = (int*)(&value);
+ int flags = *valuePtr;
+ int hi = *(valuePtr + 1);
+ int lo = *(valuePtr + 2);
+ int mid = *(valuePtr + 3);
- WriteArray<int>(position, bits, 0, bits.Length);
+ UnsafeWriteInt32(pointer, lo);
+ UnsafeWriteInt32(pointer + 4, mid);
+ UnsafeWriteInt32(pointer + 8, hi);
+ UnsafeWriteInt32(pointer + 12, flags);
+ }
+ finally
+ {
+ if (pointer != null)
+ {
+ _buffer.ReleasePointer();
+ }
+ }
+ }
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void Write(Int64 position, Single value) {
int sizeOfType = sizeof(Single);
EnsureSafeToWrite(position, sizeOfType);
@@ -825,7 +877,7 @@ namespace System.IO {
// check if pointer is aligned
if (((int)pointer & (sizeOfType - 1)) == 0) {
#endif
- *((Single*)pointer) = value;
+ *((int*)pointer) = BitConverter.SingleToInt32Bits(value);
#if ALIGN_ACCESS
}
else {
@@ -846,7 +898,6 @@ namespace System.IO {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void Write(Int64 position, Double value) {
int sizeOfType = sizeof(Double);
EnsureSafeToWrite(position, sizeOfType);
@@ -861,7 +912,7 @@ namespace System.IO {
// check if pointer is aligned
if (((int)pointer & (sizeOfType - 1)) == 0) {
#endif
- *((Double*)pointer) = value;
+ *((long*)pointer) = BitConverter.DoubleToInt64Bits(value);
#if ALIGN_ACCESS
}
else {
@@ -886,7 +937,6 @@ namespace System.IO {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
[CLSCompliant(false)]
public void Write(Int64 position, SByte value) {
int sizeOfType = sizeof(SByte);
@@ -908,7 +958,6 @@ namespace System.IO {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
[CLSCompliant(false)]
public void Write(Int64 position, UInt16 value) {
int sizeOfType = sizeof(UInt16);
@@ -942,7 +991,6 @@ namespace System.IO {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
[CLSCompliant(false)]
public void Write(Int64 position, UInt32 value) {
int sizeOfType = sizeof(UInt32);
@@ -979,7 +1027,6 @@ namespace System.IO {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
[CLSCompliant(false)]
public void Write(Int64 position, UInt64 value) {
int sizeOfType = sizeof(UInt64);
@@ -1024,10 +1071,9 @@ 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.
- [System.Security.SecurityCritical] // auto-generated_required
public void Write<T>(Int64 position, ref T structure) where T : struct {
if (position < 0) {
- throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
Contract.EndContractBlock();
@@ -1041,10 +1087,10 @@ namespace System.IO {
UInt32 sizeOfT = Marshal.SizeOfType(typeof(T));
if (position > _capacity - sizeOfT) {
if (position >= _capacity) {
- throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
+ throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
}
else {
- throw new ArgumentException(Environment.GetResourceString("Argument_NotEnoughBytesToWrite", typeof(T).FullName), "position");
+ throw new ArgumentException(Environment.GetResourceString("Argument_NotEnoughBytesToWrite", typeof(T).FullName), nameof(position));
}
}
@@ -1054,25 +1100,24 @@ namespace System.IO {
// Writes 'count' structs of type T from 'array' (starting at 'offset') into unmanaged memory.
- [System.Security.SecurityCritical] // auto-generated_required
public void WriteArray<T>(Int64 position, T[] array, Int32 offset, Int32 count) where T : struct {
if (array == null) {
- throw new ArgumentNullException("array", "Buffer cannot be null.");
+ throw new ArgumentNullException(nameof(array), "Buffer cannot be null.");
}
if (offset < 0) {
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (count < 0) {
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (array.Length - offset < count) {
throw new ArgumentException(Environment.GetResourceString("Argument_OffsetAndLengthOutOfBounds"));
}
if (position < 0) {
- throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (position >= Capacity) {
- throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
+ throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
}
Contract.EndContractBlock();
@@ -1086,11 +1131,10 @@ namespace System.IO {
_buffer.WriteArray<T>((UInt64)(_offset + position), array, offset, count);
}
- [System.Security.SecuritySafeCritical] // auto-generated
private byte InternalReadByte(Int64 position) {
- Contract.Assert(CanRead, "UMA not readable");
- Contract.Assert(position >= 0, "position less than 0");
- Contract.Assert(position <= _capacity - sizeof(byte), "position is greater than capacity - sizeof(byte)");
+ 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 {
@@ -1109,11 +1153,10 @@ namespace System.IO {
return result;
}
- [System.Security.SecuritySafeCritical] // auto-generated
private void InternalWrite(Int64 position, byte value) {
- Contract.Assert(CanWrite, "UMA not writeable");
- Contract.Assert(position >= 0, "position less than 0");
- Contract.Assert(position <= _capacity - sizeof(byte), "position is greater than capacity - sizeof(byte)");
+ 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 {
byte* pointer = null;
@@ -1138,15 +1181,15 @@ namespace System.IO {
throw new NotSupportedException(Environment.GetResourceString("NotSupported_Reading"));
}
if (position < 0) {
- throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
Contract.EndContractBlock();
if (position > _capacity - sizeOfType) {
if (position >= _capacity) {
- throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
+ throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
}
else {
- throw new ArgumentException(Environment.GetResourceString("Argument_NotEnoughBytesToRead"), "position");
+ throw new ArgumentException(Environment.GetResourceString("Argument_NotEnoughBytesToRead"), nameof(position));
}
}
}
@@ -1159,15 +1202,15 @@ namespace System.IO {
throw new NotSupportedException(Environment.GetResourceString("NotSupported_Writing"));
}
if (position < 0) {
- throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
Contract.EndContractBlock();
if (position > _capacity - sizeOfType) {
if (position >= _capacity) {
- throw new ArgumentOutOfRangeException("position", Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
+ throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
}
else {
- throw new ArgumentException(Environment.GetResourceString("Argument_NotEnoughBytesToWrite", "Byte"), "position");
+ throw new ArgumentException(Environment.GetResourceString("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 6b506ea5b1..d78632639b 100644
--- a/src/mscorlib/src/System/IO/UnmanagedMemoryStream.cs
+++ b/src/mscorlib/src/System/IO/UnmanagedMemoryStream.cs
@@ -19,6 +19,7 @@ using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Threading;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Threading.Tasks;
@@ -43,7 +44,7 @@ namespace System.IO {
*
* It may become necessary to add in some sort of
* DeallocationMode enum, specifying whether we unmap a section of memory,
- * call free, run a user-provided delegate to free the memory, etc etc.
+ * call free, run a user-provided delegate to free the memory, etc.
* We'll suggest user write a subclass of UnmanagedMemoryStream that uses
* a SafeHandle subclass to hold onto the memory.
* Check for problems when using this in the negative parts of a
@@ -76,7 +77,7 @@ namespace System.IO {
* a. a race condition in WriteX that could have allowed a thread to
* read from unzeroed memory was fixed
* b. memory region cannot be expanded beyond _capacity; in other
- * words, a UMS creator is saying a writeable UMS is safe to
+ * words, a UMS creator is saying a writable UMS is safe to
* write to anywhere in the memory range up to _capacity, specified
* in the ctor. Even if the caller doesn't specify a capacity, then
* length is used as the capacity.
@@ -85,22 +86,19 @@ namespace System.IO {
{
private const long UnmanagedMemStreamMaxLength = Int64.MaxValue;
- [System.Security.SecurityCritical] // auto-generated
private SafeBuffer _buffer;
- [SecurityCritical]
private unsafe byte* _mem;
private long _length;
private long _capacity;
private long _position;
private long _offset;
private FileAccess _access;
- internal bool _isOpen;
+ internal bool _isOpen;
[NonSerialized]
private Task<Int32> _lastReadTask; // The last successful task returned from ReadAsync
// Needed for subclasses that need to map a file, etc.
- [System.Security.SecuritySafeCritical] // auto-generated
protected UnmanagedMemoryStream()
{
unsafe {
@@ -109,12 +107,10 @@ namespace System.IO {
_isOpen = false;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public UnmanagedMemoryStream(SafeBuffer buffer, long offset, long length) {
Initialize(buffer, offset, length, FileAccess.Read, false);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public UnmanagedMemoryStream(SafeBuffer buffer, long offset, long length, FileAccess access) {
Initialize(buffer, offset, length, access, false);
}
@@ -122,32 +118,29 @@ namespace System.IO {
// We must create one of these without doing a security check. This
// class is created while security is trying to start up. Plus, doing
// a Demand from Assembly.GetManifestResourceStream isn't useful.
- [System.Security.SecurityCritical] // auto-generated
internal UnmanagedMemoryStream(SafeBuffer buffer, long offset, long length, FileAccess access, bool skipSecurityCheck) {
Initialize(buffer, offset, length, access, skipSecurityCheck);
}
- [System.Security.SecuritySafeCritical] // auto-generated
protected void Initialize(SafeBuffer buffer, long offset, long length, FileAccess access) {
Initialize(buffer, offset, length, access, false);
}
- [System.Security.SecurityCritical] // auto-generated
internal void Initialize(SafeBuffer buffer, long offset, long length, FileAccess access, bool skipSecurityCheck) {
if (buffer == null) {
- throw new ArgumentNullException("buffer");
+ throw new ArgumentNullException(nameof(buffer));
}
if (offset < 0) {
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (length < 0) {
- throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (buffer.ByteLength < (ulong)(offset + length)) {
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidSafeBufferOffLen"));
}
if (access < FileAccess.Read || access > FileAccess.ReadWrite) {
- throw new ArgumentOutOfRangeException("access");
+ throw new ArgumentOutOfRangeException(nameof(access));
}
Contract.EndContractBlock();
@@ -185,14 +178,12 @@ namespace System.IO {
_isOpen = true;
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
public unsafe UnmanagedMemoryStream(byte* pointer, long length)
{
Initialize(pointer, length, length, FileAccess.Read, false);
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
public unsafe UnmanagedMemoryStream(byte* pointer, long length, long capacity, FileAccess access)
{
@@ -202,41 +193,39 @@ namespace System.IO {
// We must create one of these without doing a security check. This
// class is created while security is trying to start up. Plus, doing
// a Demand from Assembly.GetManifestResourceStream isn't useful.
- [System.Security.SecurityCritical] // auto-generated
internal unsafe UnmanagedMemoryStream(byte* pointer, long length, long capacity, FileAccess access, bool skipSecurityCheck)
{
Initialize(pointer, length, capacity, access, skipSecurityCheck);
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
protected unsafe void Initialize(byte* pointer, long length, long capacity, FileAccess access)
{
Initialize(pointer, length, capacity, access, false);
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe void Initialize(byte* pointer, long length, long capacity, FileAccess access, bool skipSecurityCheck)
{
if (pointer == null)
- throw new ArgumentNullException("pointer");
+ throw new ArgumentNullException(nameof(pointer));
if (length < 0 || capacity < 0)
- throw new ArgumentOutOfRangeException((length < 0) ? "length" : "capacity", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((length < 0) ? nameof(length) : nameof(capacity), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (length > capacity)
- throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_LengthGreaterThanCapacity"));
+ throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_LengthGreaterThanCapacity"));
Contract.EndContractBlock();
// Check for wraparound.
if (((byte*) ((long)pointer + capacity)) < pointer)
- throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_UnmanagedMemStreamWrapAround"));
+ throw new ArgumentOutOfRangeException(nameof(capacity), Environment.GetResourceString("ArgumentOutOfRange_UnmanagedMemStreamWrapAround"));
if (access < FileAccess.Read || access > FileAccess.ReadWrite)
- throw new ArgumentOutOfRangeException("access", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(access), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
if (_isOpen)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CalledTwice"));
- if (!skipSecurityCheck)
+ if (!skipSecurityCheck) {
#pragma warning disable 618
new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
#pragma warning restore 618
+ }
_mem = pointer;
_offset = 0;
@@ -261,7 +250,6 @@ namespace System.IO {
get { return _isOpen && (_access & FileAccess.Write) != 0; }
}
- [System.Security.SecuritySafeCritical] // auto-generated
protected override void Dispose(bool disposing)
{
_isOpen = false;
@@ -277,7 +265,6 @@ namespace System.IO {
if (!_isOpen) __Error.StreamIsClosed();
}
- [HostProtection(ExternalThreading=true)]
[ComVisible(false)]
public override Task FlushAsync(CancellationToken cancellationToken) {
@@ -316,10 +303,9 @@ namespace System.IO {
Contract.EndContractBlock();
return Interlocked.Read(ref _position);
}
- [System.Security.SecuritySafeCritical] // auto-generated
set {
if (value < 0)
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
if (!CanSeek) __Error.StreamIsClosed();
@@ -327,7 +313,7 @@ namespace System.IO {
unsafe {
// On 32 bit machines, ensure we don't wrap around.
if (value > (long) Int32.MaxValue || _mem + value < _mem)
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_StreamLength"));
+ throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_StreamLength"));
}
#endif
Interlocked.Exchange(ref _position, value);
@@ -336,7 +322,6 @@ namespace System.IO {
[CLSCompliant(false)]
public unsafe byte* PositionPointer {
- [System.Security.SecurityCritical] // auto-generated_required
get {
if (_buffer != null) {
throw new NotSupportedException(Environment.GetResourceString("NotSupported_UmsSafeBuffer"));
@@ -350,7 +335,6 @@ namespace System.IO {
if (!_isOpen) __Error.StreamIsClosed();
return ptr;
}
- [System.Security.SecurityCritical] // auto-generated_required
set {
if (_buffer != null)
throw new NotSupportedException(Environment.GetResourceString("NotSupported_UmsSafeBuffer"));
@@ -368,7 +352,6 @@ namespace System.IO {
}
internal unsafe byte* Pointer {
- [System.Security.SecurityCritical] // auto-generated
get {
if (_buffer != null)
throw new NotSupportedException(Environment.GetResourceString("NotSupported_UmsSafeBuffer"));
@@ -377,14 +360,13 @@ namespace System.IO {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override int Read([In, Out] byte[] buffer, int offset, int count) {
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - offset < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock(); // Keep this in sync with contract validation in ReadAsync
@@ -404,42 +386,49 @@ namespace System.IO {
int nInt = (int) n; // Safe because n <= count, which is an Int32
if (nInt < 0)
- nInt = 0; // _position could be beyond EOF
- Contract.Assert(pos + nInt >= 0, "_position + n >= 0"); // len is less than 2^63 -1.
-
- if (_buffer != null) {
- unsafe {
- byte* pointer = null;
- RuntimeHelpers.PrepareConstrainedRegions();
- try {
- _buffer.AcquirePointer(ref pointer);
- Buffer.Memcpy(buffer, offset, pointer + pos + _offset, 0, nInt);
- }
- finally {
- if (pointer != null) {
- _buffer.ReleasePointer();
+ return 0; // _position could be beyond EOF
+ Debug.Assert(pos + nInt >= 0, "_position + n >= 0"); // len is less than 2^63 -1.
+
+ unsafe
+ {
+ fixed (byte* pBuffer = buffer)
+ {
+ if (_buffer != null)
+ {
+ byte* pointer = null;
+
+ RuntimeHelpers.PrepareConstrainedRegions();
+ try
+ {
+ _buffer.AcquirePointer(ref pointer);
+ Buffer.Memcpy(pBuffer + offset, pointer + pos + _offset, nInt);
+ }
+ finally
+ {
+ if (pointer != null)
+ {
+ _buffer.ReleasePointer();
+ }
}
}
- }
- }
- else {
- unsafe {
- Buffer.Memcpy(buffer, offset, _mem + pos, 0, nInt);
+ else
+ {
+ Buffer.Memcpy(pBuffer + offset, _mem + pos, nInt);
+ }
}
}
Interlocked.Exchange(ref _position, pos + n);
return nInt;
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public override Task<Int32> ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) {
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - offset < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock(); // contract validation copied from Read(...)
@@ -455,12 +444,11 @@ namespace System.IO {
} catch (Exception ex) {
- Contract.Assert(! (ex is OperationCanceledException));
+ Debug.Assert(! (ex is OperationCanceledException));
return Task.FromException<Int32>(ex);
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override int ReadByte() {
if (!_isOpen) __Error.StreamIsClosed();
if (!CanRead) __Error.ReadNotSupported();
@@ -497,7 +485,7 @@ namespace System.IO {
public override long Seek(long offset, SeekOrigin loc) {
if (!_isOpen) __Error.StreamIsClosed();
if (offset > UnmanagedMemStreamMaxLength)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_UnmanagedMemStreamLength"));
+ throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_UnmanagedMemStreamLength"));
switch(loc) {
case SeekOrigin.Begin:
if (offset < 0)
@@ -524,11 +512,10 @@ namespace System.IO {
}
long finalPos = Interlocked.Read(ref _position);
- Contract.Assert(finalPos >= 0, "_position >= 0");
+ Debug.Assert(finalPos >= 0, "_position >= 0");
return finalPos;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override void SetLength(long value) {
if (value < 0)
throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
@@ -554,14 +541,13 @@ namespace System.IO {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override void Write(byte[] buffer, int offset, int count) {
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - offset < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock(); // Keep contract validation in sync with WriteAsync(..)
@@ -595,46 +581,52 @@ namespace System.IO {
}
}
- if (_buffer != null) {
-
- long bytesLeft = _capacity - pos;
- if (bytesLeft < count) {
- throw new ArgumentException(Environment.GetResourceString("Arg_BufferTooSmall"));
- }
+ unsafe
+ {
+ fixed (byte* pBuffer = buffer)
+ {
+ if (_buffer != null)
+ {
+ long bytesLeft = _capacity - pos;
+ if (bytesLeft < count)
+ {
+ throw new ArgumentException(Environment.GetResourceString("Arg_BufferTooSmall"));
+ }
- unsafe {
- byte* pointer = null;
- RuntimeHelpers.PrepareConstrainedRegions();
- try {
- _buffer.AcquirePointer(ref pointer);
- Buffer.Memcpy(pointer + pos + _offset, 0, buffer, offset, count);
- }
- finally {
- if (pointer != null) {
- _buffer.ReleasePointer();
+ byte* pointer = null;
+ RuntimeHelpers.PrepareConstrainedRegions();
+ try
+ {
+ _buffer.AcquirePointer(ref pointer);
+ Buffer.Memcpy(pointer + pos + _offset, pBuffer + offset, count);
+ }
+ finally
+ {
+ if (pointer != null)
+ {
+ _buffer.ReleasePointer();
+ }
}
}
- }
- }
- else {
- unsafe {
- Buffer.Memcpy(_mem + pos, 0, buffer, offset, count);
+ else
+ {
+ Buffer.Memcpy(_mem + pos, pBuffer + offset, count);
+ }
}
}
Interlocked.Exchange(ref _position, n);
return;
}
- [HostProtection(ExternalThreading = true)]
[ComVisible(false)]
public override Task WriteAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) {
if (buffer==null)
- throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
if (offset < 0)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (buffer.Length - offset < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock(); // contract validation copied from Write(..)
@@ -649,13 +641,12 @@ namespace System.IO {
} catch (Exception ex) {
- Contract.Assert(! (ex is OperationCanceledException));
+ Debug.Assert(! (ex is OperationCanceledException));
return Task.FromException<Int32>(ex);
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override void WriteByte(byte value) {
if (!_isOpen) __Error.StreamIsClosed();
if (!CanWrite) __Error.WriteNotSupported();
@@ -674,7 +665,7 @@ namespace System.IO {
// 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 (_buffer == null) {
if (pos > len) {
unsafe {
Buffer.ZeroMemory(_mem+len, pos-len);
diff --git a/src/mscorlib/src/System/IO/UnmanagedMemoryStreamWrapper.cs b/src/mscorlib/src/System/IO/UnmanagedMemoryStreamWrapper.cs
index 5727eeddf5..040ddbb3d7 100644
--- a/src/mscorlib/src/System/IO/UnmanagedMemoryStreamWrapper.cs
+++ b/src/mscorlib/src/System/IO/UnmanagedMemoryStreamWrapper.cs
@@ -106,7 +106,6 @@ namespace System.IO {
return _unmanagedStream.Seek(offset, loc);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe override byte[] ToArray() {
if (!_unmanagedStream._isOpen) __Error.StreamIsClosed();
if (!_unmanagedStream.CanRead) __Error.ReadNotSupported();
@@ -127,7 +126,7 @@ namespace System.IO {
// Writes this MemoryStream to another stream.
public unsafe override void WriteTo(Stream stream) {
if (stream==null)
- throw new ArgumentNullException("stream", Environment.GetResourceString("ArgumentNull_Stream"));
+ throw new ArgumentNullException(nameof(stream), Environment.GetResourceString("ArgumentNull_Stream"));
Contract.EndContractBlock();
if (!_unmanagedStream._isOpen) __Error.StreamIsClosed();
@@ -151,16 +150,16 @@ namespace System.IO {
// The parameter checks must be in sync with the base version:
if (destination == null)
- throw new ArgumentNullException("destination");
+ throw new ArgumentNullException(nameof(destination));
if (bufferSize <= 0)
- throw new ArgumentOutOfRangeException("bufferSize", Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
+ throw new ArgumentOutOfRangeException(nameof(bufferSize), Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
if (!CanRead && !CanWrite)
throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_StreamClosed"));
if (!destination.CanRead && !destination.CanWrite)
- throw new ObjectDisposedException("destination", Environment.GetResourceString("ObjectDisposed_StreamClosed"));
+ throw new ObjectDisposedException(nameof(destination), Environment.GetResourceString("ObjectDisposed_StreamClosed"));
if (!CanRead)
throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnreadableStream"));
diff --git a/src/mscorlib/src/System/IO/__DebugOutputTextWriter.cs b/src/mscorlib/src/System/IO/__DebugOutputTextWriter.cs
deleted file mode 100644
index 621bc41b4b..0000000000
--- a/src/mscorlib/src/System/IO/__DebugOutputTextWriter.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.
-
-#if _DEBUG
-// This class writes to wherever OutputDebugString writes to. If you don't have
-// a Windows app (ie, something hosted in IE), you can use this to redirect Console
-// output for some good old-fashioned console spew in MSDEV's debug output window.
-
-using System;
-using System.IO;
-using System.Text;
-using System.Security;
-using System.Runtime.InteropServices;
-using System.Runtime.Versioning;
-using Microsoft.Win32;
-using System.Globalization;
-
-namespace System.IO {
- internal class __DebugOutputTextWriter : TextWriter {
- private readonly String _consoleType;
-
- internal __DebugOutputTextWriter(String consoleType): base(CultureInfo.InvariantCulture)
- {
- _consoleType = consoleType;
- }
-
- public override Encoding Encoding {
-#if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical]
-#endif
- get {
- if (Marshal.SystemDefaultCharSize == 1)
- return Encoding.Default;
- else
- return new UnicodeEncoding(false, false);
- }
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override void Write(char c)
- {
- OutputDebugString(c.ToString());
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override void Write(String str)
- {
- OutputDebugString(str);
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override void Write(char[] array)
- {
- if (array != null)
- OutputDebugString(new String(array));
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override void WriteLine(String str)
- {
- if (str != null)
- OutputDebugString(_consoleType + str);
- else
- OutputDebugString("<null>");
- OutputDebugString(new String(CoreNewLine));
- }
-
- [System.Security.SecurityCritical] // auto-generated
- [DllImport(Win32Native.KERNEL32, CharSet=CharSet.Auto)]
- [SuppressUnmanagedCodeSecurityAttribute()]
- private static extern void OutputDebugString(String output);
- }
-}
-
-#endif // _DEBUG
diff --git a/src/mscorlib/src/System/IO/__Error.cs b/src/mscorlib/src/System/IO/__Error.cs
index a31d9657e8..ad4972de54 100644
--- a/src/mscorlib/src/System/IO/__Error.cs
+++ b/src/mscorlib/src/System/IO/__Error.cs
@@ -74,7 +74,6 @@ namespace System.IO {
// discovery permission to that path. If we do not, return just the
// file name. If we know it is a directory, then don't return the
// directory name.
- [System.Security.SecurityCritical] // auto-generated
internal static String GetDisplayablePath(String path, bool isInvalidPath)
{
@@ -85,7 +84,7 @@ namespace System.IO {
bool isFullyQualified = false;
if (path.Length < 2)
return path;
- if (Path.IsDirectorySeparator(path[0]) && Path.IsDirectorySeparator(path[1]))
+ if (PathInternal.IsDirectorySeparator(path[0]) && PathInternal.IsDirectorySeparator(path[1]))
isFullyQualified = true;
else if (path[1] == Path.VolumeSeparatorChar) {
isFullyQualified = true;
@@ -97,9 +96,6 @@ namespace System.IO {
bool safeToReturn = false;
try {
if (!isInvalidPath) {
-#if !FEATURE_CORECLR
- new FileIOPermission(FileIOPermissionAccess.PathDiscovery, new String[] { path }, false, false).Demand();
-#endif
safeToReturn = true;
}
}
@@ -116,7 +112,7 @@ namespace System.IO {
}
if (!safeToReturn) {
- if (Path.IsDirectorySeparator(path[path.Length - 1]))
+ if (PathInternal.IsDirectorySeparator(path[path.Length - 1]))
path = Environment.GetResourceString("IO.IO_NoPermissionToDirectoryName");
else
path = Path.GetFileName(path);
@@ -125,7 +121,6 @@ namespace System.IO {
return path;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static void WinIOError() {
int errorCode = Marshal.GetLastWin32Error();
WinIOError(errorCode, String.Empty);
@@ -136,7 +131,6 @@ namespace System.IO {
// 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.
- [System.Security.SecurityCritical] // auto-generated
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;
@@ -195,13 +189,11 @@ namespace System.IO {
}
// An alternative to WinIOError with friendlier messages for drives
- [System.Security.SecuritySafeCritical] // auto-generated
internal static void WinIODriveError(String driveName) {
int errorCode = Marshal.GetLastWin32Error();
WinIODriveError(driveName, errorCode);
}
- [System.Security.SecurityCritical] // auto-generated
internal static void WinIODriveError(String driveName, int errorCode)
{
switch (errorCode) {
diff --git a/src/mscorlib/src/System/Int16.cs b/src/mscorlib/src/System/Int16.cs
index 0adc64cd13..f02a5f2cda 100644
--- a/src/mscorlib/src/System/Int16.cs
+++ b/src/mscorlib/src/System/Int16.cs
@@ -71,13 +71,11 @@ namespace System {
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override String ToString() {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt32(m_value, null, NumberFormatInfo.CurrentInfo);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(IFormatProvider provider) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt32(m_value, null, NumberFormatInfo.GetInstance(provider));
@@ -93,7 +91,6 @@ namespace System {
return ToString(format, NumberFormatInfo.GetInstance(provider));
}
- [System.Security.SecuritySafeCritical] // auto-generated
private String ToString(String format, NumberFormatInfo info) {
Contract.Ensures(Contract.Result<String>() != null);
diff --git a/src/mscorlib/src/System/Int32.cs b/src/mscorlib/src/System/Int32.cs
index 778a893672..2da55bf089 100644
--- a/src/mscorlib/src/System/Int32.cs
+++ b/src/mscorlib/src/System/Int32.cs
@@ -77,21 +77,18 @@ namespace System {
return m_value;
}
- [System.Security.SecuritySafeCritical] // auto-generated
[Pure]
public override String ToString() {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt32(m_value, null, NumberFormatInfo.CurrentInfo);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[Pure]
public String ToString(String format) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt32(m_value, format, NumberFormatInfo.CurrentInfo);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[Pure]
public String ToString(IFormatProvider provider) {
Contract.Ensures(Contract.Result<String>() != null);
@@ -99,7 +96,6 @@ namespace System {
}
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(String format, IFormatProvider provider) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt32(m_value, format, NumberFormatInfo.GetInstance(provider));
diff --git a/src/mscorlib/src/System/Int64.cs b/src/mscorlib/src/System/Int64.cs
index 0cd2558997..e5fcf86c3b 100644
--- a/src/mscorlib/src/System/Int64.cs
+++ b/src/mscorlib/src/System/Int64.cs
@@ -76,25 +76,21 @@ namespace System {
return (unchecked((int)((long)m_value)) ^ (int)(m_value >> 32));
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override String ToString() {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt64(m_value, null, NumberFormatInfo.CurrentInfo);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(IFormatProvider provider) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt64(m_value, null, NumberFormatInfo.GetInstance(provider));
}
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(String format) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt64(m_value, format, NumberFormatInfo.CurrentInfo);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(String format, IFormatProvider provider) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt64(m_value, format, NumberFormatInfo.GetInstance(provider));
diff --git a/src/mscorlib/src/System/IntPtr.cs b/src/mscorlib/src/System/IntPtr.cs
index c7eea36447..2d66652ab8 100644
--- a/src/mscorlib/src/System/IntPtr.cs
+++ b/src/mscorlib/src/System/IntPtr.cs
@@ -26,13 +26,11 @@ namespace System {
[System.Runtime.InteropServices.ComVisible(true)]
public struct IntPtr : IEquatable<IntPtr>, ISerializable
{
- [SecurityCritical]
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
- [System.Security.SecuritySafeCritical] // auto-generated
[Pure]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal unsafe bool IsNull()
@@ -40,7 +38,6 @@ namespace System {
return (this.m_value == null);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
[System.Runtime.Versioning.NonVersionable]
public unsafe IntPtr(int value)
@@ -52,7 +49,6 @@ namespace System {
#endif
}
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
[System.Runtime.Versioning.NonVersionable]
public unsafe IntPtr(long value)
@@ -64,7 +60,6 @@ namespace System {
#endif
}
- [System.Security.SecurityCritical]
[CLSCompliant(false)]
[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
[System.Runtime.Versioning.NonVersionable]
@@ -73,7 +68,6 @@ namespace System {
m_value = value;
}
- [System.Security.SecurityCritical] // auto-generated
private unsafe IntPtr(SerializationInfo info, StreamingContext context) {
long l = info.GetInt64("value");
@@ -84,10 +78,9 @@ namespace System {
m_value = (void *)l;
}
- [System.Security.SecurityCritical]
unsafe void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) {
if (info==null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
#if BIT64
@@ -97,7 +90,6 @@ namespace System {
#endif
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe override bool Equals(Object obj) {
if (obj is IntPtr) {
return (m_value == ((IntPtr)obj).m_value);
@@ -105,27 +97,20 @@ namespace System {
return false;
}
- [SecuritySafeCritical]
unsafe bool IEquatable<IntPtr>.Equals(IntPtr other)
{
return m_value == other.m_value;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe override int GetHashCode() {
-#if FEATURE_CORECLR
#if BIT64
long l = (long)m_value;
return (unchecked((int)l) ^ (int)(l >> 32));
#else // !BIT64 (32)
return unchecked((int)m_value);
#endif
-#else
- return unchecked((int)((long)m_value));
-#endif
}
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[System.Runtime.Versioning.NonVersionable]
public unsafe int ToInt32() {
@@ -137,7 +122,6 @@ namespace System {
#endif
}
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[System.Runtime.Versioning.NonVersionable]
public unsafe long ToInt64() {
@@ -148,7 +132,6 @@ namespace System {
#endif
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe override String ToString() {
#if BIT64
return ((long)m_value).ToString(CultureInfo.InvariantCulture);
@@ -157,7 +140,6 @@ namespace System {
#endif
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe String ToString(String format)
{
Contract.Ensures(Contract.Result<String>() != null);
@@ -184,7 +166,6 @@ namespace System {
return new IntPtr(value);
}
- [System.Security.SecurityCritical]
[CLSCompliant(false), ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
[System.Runtime.Versioning.NonVersionable]
public static unsafe explicit operator IntPtr (void* value)
@@ -192,7 +173,6 @@ namespace System {
return new IntPtr(value);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.Versioning.NonVersionable]
public static unsafe explicit operator void* (IntPtr value)
@@ -200,7 +180,6 @@ namespace System {
return value.m_value;
}
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.Versioning.NonVersionable]
public unsafe static explicit operator int (IntPtr value)
{
@@ -212,7 +191,6 @@ namespace System {
#endif
}
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.Versioning.NonVersionable]
public unsafe static explicit operator long (IntPtr value)
{
@@ -223,7 +201,6 @@ namespace System {
#endif
}
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[System.Runtime.Versioning.NonVersionable]
public unsafe static bool operator == (IntPtr value1, IntPtr value2)
@@ -231,7 +208,6 @@ namespace System {
return value1.m_value == value2.m_value;
}
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[System.Runtime.Versioning.NonVersionable]
public unsafe static bool operator != (IntPtr value1, IntPtr value2)
@@ -289,7 +265,6 @@ namespace System {
}
- [System.Security.SecuritySafeCritical] // auto-generated
[CLSCompliant(false)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[System.Runtime.Versioning.NonVersionable]
diff --git a/src/mscorlib/src/System/Internal.cs b/src/mscorlib/src/System/Internal.cs
index c6be49f83f..0eb2bced72 100644
--- a/src/mscorlib/src/System/Internal.cs
+++ b/src/mscorlib/src/System/Internal.cs
@@ -85,16 +85,15 @@ namespace System
new Dictionary<Object, UInt32>();
new Dictionary<UInt32, Object>();
new Dictionary<Int64, Object>();
-#if FEATURE_CORECLR
+
// to genereate mdil for Dictionary instantiation when key is user defined value type
new Dictionary<Guid, Int32>();
-#endif
- // Microsoft.Windows.Design
+ // Microsoft.Windows.Design
new Dictionary<System.Reflection.MemberTypes, Object>();
new EnumEqualityComparer<System.Reflection.MemberTypes>();
- // Microsoft.Expression.DesignModel
+ // Microsoft.Expression.DesignModel
new Dictionary<Object, KeyValuePair<Object,Object>>();
new Dictionary<KeyValuePair<Object,Object>, Object>();
@@ -157,14 +156,12 @@ namespace System
SZArrayHelper<CustomAttributeTypedArgument>(null);
SZArrayHelper<CustomAttributeNamedArgument>(null);
-#if FEATURE_CORECLR
#pragma warning disable 4014
// This is necessary to generate MDIL for AsyncVoidMethodBuilder
AsyncHelper<int>();
AsyncHelper2<int>();
AsyncHelper3();
#pragma warning restore 4014
-#endif
}
static T NullableHelper<T>() where T : struct
@@ -183,7 +180,6 @@ namespace System
oSZArrayHelper.GetEnumerator<T>();
}
-#if FEATURE_CORECLR
// System.Runtime.CompilerServices.AsyncVoidMethodBuilder
// System.Runtime.CompilerServices.TaskAwaiter
static async void AsyncHelper<T>()
@@ -203,7 +199,6 @@ namespace System
{
await Task.FromResult<string>("");
}
-#endif
#if FEATURE_COMINTEROP
@@ -214,7 +209,6 @@ 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.
- [SecurityCritical]
static void CommonlyUsedWinRTRedirectedInterfaceStubs()
{
WinRT_IEnumerable<byte>(null, null, null);
@@ -261,7 +255,6 @@ namespace System
WinRT_Nullable<double>();
}
- [SecurityCritical]
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>
@@ -269,7 +262,6 @@ namespace System
enumerableToIterableAdapter.First_Stub<T>();
}
- [SecurityCritical]
static void WinRT_IList<T>(VectorToListAdapter vectorToListAdapter, VectorToCollectionAdapter vectorToCollectionAdapter, ListToVectorAdapter listToVectorAdapter, IVector<T> vector)
{
WinRT_IEnumerable<T>(null, null, null);
@@ -294,7 +286,6 @@ namespace System
listToVectorAdapter.Clear<T>();
}
- [SecurityCritical]
static void WinRT_IReadOnlyCollection<T>(VectorViewToReadOnlyCollectionAdapter vectorViewToReadOnlyCollectionAdapter)
{
WinRT_IEnumerable<T>(null, null, null);
@@ -303,7 +294,6 @@ namespace System
vectorViewToReadOnlyCollectionAdapter.Count<T>();
}
- [SecurityCritical]
static void WinRT_IReadOnlyList<T>(IVectorViewToIReadOnlyListAdapter vectorToListAdapter, IReadOnlyListToIVectorViewAdapter listToVectorAdapter, IVectorView<T> vectorView)
{
WinRT_IEnumerable<T>(null, null, null);
@@ -317,7 +307,6 @@ namespace System
listToVectorAdapter.Size<T>();
}
- [SecurityCritical]
static void WinRT_IDictionary<K, V>(MapToDictionaryAdapter mapToDictionaryAdapter, MapToCollectionAdapter mapToCollectionAdapter, DictionaryToMapAdapter dictionaryToMapAdapter, IMap<K, V> map)
{
WinRT_IEnumerable<KeyValuePair<K, V>>(null, null, null);
@@ -343,7 +332,6 @@ namespace System
dictionaryToMapAdapter.Clear<K, V>();
}
- [SecurityCritical]
static void WinRT_IReadOnlyDictionary<K, V>(IMapViewToIReadOnlyDictionaryAdapter mapToDictionaryAdapter, IReadOnlyDictionaryToIMapViewAdapter dictionaryToMapAdapter, IMapView<K, V> mapView, MapViewToReadOnlyCollectionAdapter mapViewToReadOnlyCollectionAdapter)
{
WinRT_IEnumerable<KeyValuePair<K, V>>(null, null, null);
@@ -364,7 +352,6 @@ namespace System
dictionaryToMapAdapter.HasKey<K, V>(default(K));
}
- [SecurityCritical]
static void WinRT_Nullable<T>() where T : struct
{
Nullable<T> nullable = new Nullable<T>();
diff --git a/src/mscorlib/src/System/InvalidTimeZoneException.cs b/src/mscorlib/src/System/InvalidTimeZoneException.cs
index 2c57bc8341..f33475497a 100644
--- a/src/mscorlib/src/System/InvalidTimeZoneException.cs
+++ b/src/mscorlib/src/System/InvalidTimeZoneException.cs
@@ -2,16 +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 {
- using System.Runtime.Serialization;
- using System.Runtime.CompilerServices;
+using System.Runtime.Serialization;
+namespace System
+{
[Serializable]
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
-#if !FEATURE_CORECLR
- [TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
-#endif
- public class InvalidTimeZoneException : Exception {
+ public class InvalidTimeZoneException : Exception
+ {
public InvalidTimeZoneException(String message)
: base(message) { }
diff --git a/src/mscorlib/src/System/Lazy.cs b/src/mscorlib/src/System/Lazy.cs
index 883979ef56..85cbb9816a 100644
--- a/src/mscorlib/src/System/Lazy.cs
+++ b/src/mscorlib/src/System/Lazy.cs
@@ -48,9 +48,6 @@ namespace System
/// </remarks>
[Serializable]
[ComVisible(false)]
-#if !FEATURE_CORECLR
- [HostProtection(Synchronization = true, ExternalThreading = true)]
-#endif
[DebuggerTypeProxy(typeof(System_LazyDebugView<>))]
[DebuggerDisplay("ThreadSafetyMode={Mode}, IsValueCreated={IsValueCreated}, IsValueFaulted={IsValueFaulted}, Value={ValueForDebugDisplay}")]
public class Lazy<T>
@@ -90,7 +87,7 @@ namespace System
// 2- Flag to m_threadSafeObj if ExecutionAndPublication mode and the value is known to be initialized
static readonly Func<T> ALREADY_INVOKED_SENTINEL = delegate
{
- Contract.Assert(false, "ALREADY_INVOKED_SENTINEL should never be invoked.");
+ Debug.Assert(false, "ALREADY_INVOKED_SENTINEL should never be invoked.");
return default(T);
};
@@ -207,7 +204,7 @@ namespace System
public Lazy(Func<T> valueFactory, LazyThreadSafetyMode mode)
{
if (valueFactory == null)
- throw new ArgumentNullException("valueFactory");
+ throw new ArgumentNullException(nameof(valueFactory));
m_threadSafeObj = GetObjectFromMode(mode);
m_valueFactory = valueFactory;
@@ -223,7 +220,7 @@ namespace System
else if (mode == LazyThreadSafetyMode.PublicationOnly)
return LazyHelpers.PUBLICATION_ONLY_SENTINEL;
else if (mode != LazyThreadSafetyMode.None)
- throw new ArgumentOutOfRangeException("mode", Environment.GetResourceString("Lazy_ctor_ModeInvalid"));
+ throw new ArgumentOutOfRangeException(nameof(mode), Environment.GetResourceString("Lazy_ctor_ModeInvalid"));
return null; // None mode
}
@@ -336,18 +333,12 @@ namespace System
}
LazyInternalExceptionHolder exc = m_boxed as LazyInternalExceptionHolder;
- Contract.Assert(exc != null);
+ Debug.Assert(exc != null);
exc.m_edi.Throw();
}
// Fall through to the slow path.
-#if !FEATURE_CORECLR
- // We call NOCTD to abort attempts by the debugger to funceval this property (e.g. on mouseover)
- // (the debugger proxy is the correct way to look at state/value of this object)
- Debugger.NotifyOfCrossThreadDependency();
-#endif
return LazyInitValue();
-
}
}
@@ -391,7 +382,7 @@ namespace System
if (threadSafeObj != (object)ALREADY_INVOKED_SENTINEL)
Monitor.Enter(threadSafeObj, ref lockTaken);
else
- Contract.Assert(m_boxed != null);
+ Debug.Assert(m_boxed != null);
if (m_boxed == null)
{
@@ -405,7 +396,7 @@ namespace System
if (boxed == null) // it is not Boxed, so it is a LazyInternalExceptionHolder
{
LazyInternalExceptionHolder exHolder = m_boxed as LazyInternalExceptionHolder;
- Contract.Assert(exHolder != null);
+ Debug.Assert(exHolder != null);
exHolder.m_edi.Throw();
}
}
@@ -416,7 +407,7 @@ namespace System
Monitor.Exit(threadSafeObj);
}
}
- Contract.Assert(boxed != null);
+ Debug.Assert(boxed != null);
return boxed.m_value;
}
diff --git a/src/mscorlib/src/System/LowLevelConsole.cs b/src/mscorlib/src/System/LowLevelConsole.cs
index 3aba3db4d1..316583e276 100644
--- a/src/mscorlib/src/System/LowLevelConsole.cs
+++ b/src/mscorlib/src/System/LowLevelConsole.cs
@@ -16,16 +16,13 @@ namespace System
public static class Console
{
- [SecurityCritical]
static SafeFileHandle _outputHandle;
- [SecuritySafeCritical]
static Console()
{
_outputHandle = new SafeFileHandle(Win32Native.GetStdHandle(Win32Native.STD_OUTPUT_HANDLE), false);
}
- [SecuritySafeCritical]
public static unsafe void Write(string s)
{
byte[] bytes = Encoding.UTF8.GetBytes(s);
diff --git a/src/mscorlib/src/System/MarshalByRefObject.cs b/src/mscorlib/src/System/MarshalByRefObject.cs
index 4948a4316d..53ebda7672 100644
--- a/src/mscorlib/src/System/MarshalByRefObject.cs
+++ b/src/mscorlib/src/System/MarshalByRefObject.cs
@@ -13,250 +13,25 @@
**
**
===========================================================*/
-namespace System {
-
- using System;
- using System.Security;
- using System.Security.Permissions;
- using System.Threading;
- using System.Runtime.Remoting;
-#if FEATURE_REMOTING
- using System.Runtime.Remoting.Lifetime;
- using System.Runtime.Remoting.Services;
-#endif
- using System.Runtime.InteropServices;
- using System.Reflection;
- using System.Runtime.CompilerServices;
- using System.Runtime.Versioning;
- using System.Diagnostics.Contracts;
- using CultureInfo = System.Globalization.CultureInfo;
-
+namespace System
+{
[Serializable]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public abstract class MarshalByRefObject
{
-#if FEATURE_REMOTING
- private Object __identity;
-
- private Object Identity { get { return __identity; } set { __identity = value; } }
-#if FEATURE_COMINTEROP
- [System.Security.SecuritySafeCritical] // auto-generated
- internal IntPtr GetComIUnknown(bool fIsBeingMarshalled)
- {
- IntPtr pUnk;
- if(RemotingServices.IsTransparentProxy(this))
- {
- pUnk = RemotingServices.GetRealProxy(this).GetCOMIUnknown(fIsBeingMarshalled);
- }
- else
- {
- pUnk = Marshal.GetIUnknownForObject(this);
- }
- return pUnk;
- }
-
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern IntPtr GetComIUnknown(MarshalByRefObject o);
-#endif // FEATURE_COMINTEROP
-
- // (1) for remote COM objects IsInstance of can't be executed on
- // the proxies, so we need this method to be executed on the
- // actual object.
- // (2) for remote objects that do not have the complete type information
- // we intercept calls to check the type and execute it on the actual
- // object
- internal bool IsInstanceOfType(Type T)
+ protected MarshalByRefObject() { }
+ public object GetLifetimeService()
{
- return T.IsInstanceOfType(this);
+ throw new PlatformNotSupportedException();
}
-
- // for remote COM Objects the late binding methods can't be
- // executed on proxies, so we need this method to execute on
- // the real object
- internal Object InvokeMember(String name,BindingFlags invokeAttr,Binder binder,
- Object[] args,ParameterModifier[] modifiers,CultureInfo culture,String[] namedParameters)
+ public virtual object InitializeLifetimeService()
{
- Type t = GetType();
-
- // Sanity check
- if(!t.IsCOMObject)
- throw new InvalidOperationException(Environment.GetResourceString("Arg_InvokeMember"));
-
- // Call into the runtime to invoke on the COM object.
- return t.InvokeMember(name, invokeAttr, binder, this, args, modifiers, culture, namedParameters);
+ throw new PlatformNotSupportedException();
}
-
- // Returns a new cloned MBR instance that is a memberwise copy of this
- // with the identity nulled out, so there are no identity conflicts
- // when the cloned object is marshalled
protected MarshalByRefObject MemberwiseClone(bool cloneIdentity)
{
MarshalByRefObject mbr = (MarshalByRefObject)base.MemberwiseClone();
- // set the identity on the cloned object to null
- if (!cloneIdentity)
- mbr.Identity = null;
return mbr;
}
-
-
-
- // A helper routine to extract the identity either from the marshalbyrefobject base
- // class if it is not a proxy, otherwise from the real proxy.
- // A flag is set to indicate whether the object passed in is a server or a proxy
- [System.Security.SecuritySafeCritical] // auto-generated
- internal static Identity GetIdentity(MarshalByRefObject obj, out bool fServer)
- {
- fServer = true;
- Identity id = null;
-
- if(null != obj)
- {
- if(!RemotingServices.IsTransparentProxy(obj))
- {
- id = (Identity)obj.Identity;
- }
- else
- {
- // Toggle flag to indicate that we have a proxy
- fServer = false;
- id = RemotingServices.GetRealProxy(obj).IdentityObject;
- }
- }
-
- return id;
- }
-
- // Another helper that delegates to the helper above
- internal static Identity GetIdentity(MarshalByRefObject obj)
- {
- Contract.Assert(!RemotingServices.IsTransparentProxy(obj), "Use this method for server objects only");
-
- bool fServer;
- return GetIdentity(obj, out fServer);
- }
-
-
- internal ServerIdentity __RaceSetServerIdentity(ServerIdentity id)
- {
- if (__identity == null)
- {
- // For strictly MBR types, the TP field in the identity
- // holds the real server
- if (!id.IsContextBound)
- {
- id.RaceSetTransparentProxy(this);
- }
- Interlocked.CompareExchange(ref __identity, id, null);
- }
- return (ServerIdentity)__identity;
- }
-
-
- internal void __ResetServerIdentity()
- {
- __identity = null;
- }
-
- // This method is used return a lifetime service object which
- // is used to control the lifetime policy to the object.
- // For the default Lifetime service this will be an object of typoe ILease.
- //
- [System.Security.SecurityCritical] // auto-generated_required
- public Object GetLifetimeService()
- {
- return LifetimeServices.GetLease(this);
- }
-
- // This method is used return lifetime service object. This method
- // can be overridden to return a LifetimeService object with properties unique to
- // this object.
- // For the default Lifetime service this will be an object of type ILease.
- //
- [System.Security.SecurityCritical] // auto-generated_required
- public virtual Object InitializeLifetimeService()
- {
- return LifetimeServices.GetLeaseInitial(this);
- }
-
- [System.Security.SecurityCritical] // auto-generated_required
- public virtual ObjRef CreateObjRef(Type requestedType)
- {
- if(__identity == null)
- {
- throw new RemotingException(Environment.GetResourceString(
- "Remoting_NoIdentityEntry"));
- }
- return new ObjRef(this, requestedType);
- }
-
- // This is for casting interop ObjRefLite's.
- // ObjRefLite's have been deprecated. These methods are not exposed
- // through any user APIs and would be removed in the future
- [System.Security.SecuritySafeCritical] // auto-generated
- internal bool CanCastToXmlType(String xmlTypeName, String xmlTypeNamespace)
- {
- Type castType = SoapServices.GetInteropTypeFromXmlType(xmlTypeName, xmlTypeNamespace);
- if (castType == null)
- {
- String typeNamespace;
- String assemblyName;
- if (!SoapServices.DecodeXmlNamespaceForClrTypeNamespace(xmlTypeNamespace,
- out typeNamespace, out assemblyName))
- return false;
-
- String typeName;
- if ((typeNamespace != null) && (typeNamespace.Length > 0))
- typeName = typeNamespace + "." + xmlTypeName;
- else
- typeName = xmlTypeName;
-
- try
- {
- Assembly asm = Assembly.Load(assemblyName);
- castType = asm.GetType(typeName, false, false);
- }
- catch
- {
- return false;
- }
- }
-
- if (castType != null)
- return castType.IsAssignableFrom(this.GetType());
-
- return false;
- } // CanCastToXmlType
-
- // helper method for calling CanCastToXmlType
- // ObjRefLite's have been deprecated. These methods are not exposed
- // through any user APIs and would be removed in the future
- [System.Security.SecuritySafeCritical] // auto-generated
- internal static bool CanCastToXmlTypeHelper(RuntimeType castType, MarshalByRefObject o)
- {
- if (castType == null)
- throw new ArgumentNullException("castType");
-
- Contract.EndContractBlock();
- // MarshalByRefObject's can only be casted to MarshalByRefObject's or interfaces.
- if (!castType.IsInterface && !castType.IsMarshalByRef)
- return false;
-
- // figure out xml type name
- String xmlTypeName = null;
- String xmlTypeNamespace = null;
- if (!SoapServices.GetXmlTypeForInteropType(castType, out xmlTypeName, out xmlTypeNamespace))
- {
- // There's no registered interop type name, so just use the default.
- xmlTypeName = castType.Name;
- xmlTypeNamespace =
- SoapServices.CodeXmlNamespaceForClrTypeNamespace(
- castType.Namespace, castType.GetRuntimeAssembly().GetSimpleName());
- }
-
- return o.CanCastToXmlType(xmlTypeName, xmlTypeNamespace);
- } // CanCastToXmlType
-
-#endif // FEATURE_REMOTING
- }
-} // namespace
+ }
+}
diff --git a/src/mscorlib/src/System/Math.cs b/src/mscorlib/src/System/Math.cs
index 4e280d5fd9..3ac1f0694a 100644
--- a/src/mscorlib/src/System/Math.cs
+++ b/src/mscorlib/src/System/Math.cs
@@ -35,16 +35,12 @@ namespace System {
public const double PI = 3.14159265358979323846;
public const double E = 2.7182818284590452354;
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern double Acos(double d);
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern double Asin(double d);
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern double Atan(double d);
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern double Atan2(double y,double x);
@@ -52,15 +48,12 @@ namespace System {
return Decimal.Ceiling(d);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern double Ceiling(double a);
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern double Cos (double d);
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern double Cosh(double value);
@@ -68,11 +61,9 @@ namespace System {
return Decimal.Floor(d);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern double Floor(double d);
- [System.Security.SecuritySafeCritical] // auto-generated
private static unsafe double InternalRound(double value, int digits, MidpointRounding mode) {
if (Abs(value) < doubleRoundLimit) {
Double power10 = roundPower10Double[digits];
@@ -92,33 +83,27 @@ namespace System {
return value;
}
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe static double InternalTruncate(double d) {
SplitFractionDouble(&d);
return d;
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern double Sin(double a);
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern double Tan(double a);
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern double Sinh(double value);
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern double Tanh(double value);
- [System.Security.SecuritySafeCritical] // auto-generated
[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("digits", Environment.GetResourceString("ArgumentOutOfRange_RoundingDigits"));
+ throw new ArgumentOutOfRangeException(nameof(digits), Environment.GetResourceString("ArgumentOutOfRange_RoundingDigits"));
Contract.EndContractBlock();
return InternalRound(value, digits, MidpointRounding.ToEven);
}
@@ -129,9 +114,9 @@ namespace System {
public static double Round(double value, int digits, MidpointRounding mode) {
if ((digits < 0) || (digits > maxRoundingDigits))
- throw new ArgumentOutOfRangeException("digits", Environment.GetResourceString("ArgumentOutOfRange_RoundingDigits"));
+ throw new ArgumentOutOfRangeException(nameof(digits), Environment.GetResourceString("ArgumentOutOfRange_RoundingDigits"));
if (mode < MidpointRounding.ToEven || mode > MidpointRounding.AwayFromZero) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidEnumValue", mode, "MidpointRounding"), "mode");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidEnumValue", mode, nameof(MidpointRounding)), nameof(mode));
}
Contract.EndContractBlock();
return InternalRound(value, digits, mode);
@@ -153,7 +138,6 @@ namespace System {
return Decimal.Round(d, decimals, mode);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static unsafe extern double SplitFractionDouble(double* value);
@@ -165,20 +149,15 @@ namespace System {
return InternalTruncate(d);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern double Sqrt(double d);
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern double Log (double d);
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern double Log10(double d);
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern double Exp(double d);
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern double Pow(double x, double y);
@@ -284,7 +263,6 @@ namespace System {
return -value;
}
- [System.Security.SecuritySafeCritical] // auto-generated
[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
@@ -296,7 +274,6 @@ namespace System {
// it runs the else case, which returns +value instead of negating it.
// return (value < 0) ? -value : value;
- [System.Security.SecuritySafeCritical] // auto-generated
[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
@@ -476,7 +453,151 @@ namespace System {
public static Decimal Min(Decimal val1, Decimal val2) {
return Decimal.Min(val1,val2);
}
-
+
+ /*=====================================Clamp====================================
+ **
+ ==============================================================================*/
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Byte Clamp(Byte value, Byte min, Byte max)
+ {
+ if (min > max)
+ ThrowMinMaxException(min, max);
+ if (value < min)
+ return min;
+ else if (value > max)
+ return max;
+ return value;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Decimal Clamp(Decimal value, Decimal min, Decimal max)
+ {
+ if (min > max)
+ ThrowMinMaxException(min, max);
+ if (value < min)
+ return min;
+ else if (value > max)
+ return max;
+ return value;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Double Clamp(Double value, Double min, Double max)
+ {
+ if (min > max)
+ ThrowMinMaxException(min, max);
+ if (value < min)
+ return min;
+ else if (value > max)
+ return max;
+ return value;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Int16 Clamp(Int16 value, Int16 min, Int16 max)
+ {
+ if (min > max)
+ ThrowMinMaxException(min, max);
+ if (value < min)
+ return min;
+ else if (value > max)
+ return max;
+ return value;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Int32 Clamp(Int32 value, Int32 min, Int32 max)
+ {
+ if (min > max)
+ ThrowMinMaxException(min, max);
+ if (value < min)
+ return min;
+ else if (value > max)
+ return max;
+ return value;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Int64 Clamp(Int64 value, Int64 min, Int64 max)
+ {
+ if (min > max)
+ ThrowMinMaxException(min, max);
+ if (value < min)
+ return min;
+ else if (value > max)
+ return max;
+ return value;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [CLSCompliant(false)]
+ public static SByte Clamp(SByte value, SByte min, SByte max)
+ {
+ if (min > max)
+ ThrowMinMaxException(min, max);
+ if (value < min)
+ return min;
+ else if (value > max)
+ return max;
+ return value;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Single Clamp(Single value, Single min, Single max)
+ {
+ if (min > max)
+ ThrowMinMaxException(min, max);
+ if (value < min)
+ return min;
+ else if (value > max)
+ return max;
+ return value;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [CLSCompliant(false)]
+ public static UInt16 Clamp(UInt16 value, UInt16 min, UInt16 max)
+ {
+ if (min > max)
+ ThrowMinMaxException(min, max);
+ if (value < min)
+ return min;
+ else if (value > max)
+ return max;
+ return value;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [CLSCompliant(false)]
+ public static UInt32 Clamp(UInt32 value, UInt32 min, UInt32 max)
+ {
+ if (min > max)
+ ThrowMinMaxException(min, max);
+ if (value < min)
+ return min;
+ else if (value > max)
+ return max;
+ return value;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [CLSCompliant(false)]
+ public static UInt64 Clamp(UInt64 value, UInt64 min, UInt64 max)
+ {
+ if (min > max)
+ ThrowMinMaxException(min, max);
+ if (value < min)
+ return min;
+ else if (value > max)
+ return max;
+ return value;
+ }
+
+ private static void ThrowMinMaxException<T>(T min, T max)
+ {
+ throw new ArgumentException(Environment.GetResourceString("Argument_MinMaxValue", min, max));
+ }
+
/*=====================================Log======================================
**
==============================================================================*/
@@ -582,13 +703,21 @@ namespace System {
}
public static int DivRem(int a, int b, out int result) {
- result = a%b;
- return a/b;
+ // 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 /.
+ int div = a / b;
+ result = a - (div * b);
+ return div;
}
public static long DivRem(long a, long b, out long result) {
- result = a%b;
- return a/b;
+ // 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 /.
+ long div = a / b;
+ result = a - (div * b);
+ return div;
}
}
}
diff --git a/src/mscorlib/src/System/MathF.cs b/src/mscorlib/src/System/MathF.cs
new file mode 100644
index 0000000000..fb800924b5
--- /dev/null
+++ b/src/mscorlib/src/System/MathF.cs
@@ -0,0 +1,253 @@
+// Licensed to the .NET Foundation under one or more 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: 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;
+
+ public static class MathF
+ {
+ private static float singleRoundLimit = 1e8f;
+
+ private const int maxRoundingDigits = 6;
+
+ // This table is required for the Round function which can specify the number of digits to round to
+ private static float[] roundPower10Single = new float[] {
+ 1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f, 1e6f
+ };
+
+ public const float PI = 3.14159265f;
+
+ public const float E = 2.71828183f;
+
+ public static float Abs(float x) => Math.Abs(x);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern float Acos(float x);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern float Asin(float x);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern float Atan(float x);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern float Atan2(float y, float x);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern float Ceiling(float x);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern float Cos(float x);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern float Cosh(float x);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern float Exp(float x);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern float Floor(float x);
+
+ public static float IEEERemainder(float x, float y)
+ {
+ if (float.IsNaN(x))
+ {
+ return x; // IEEE 754-2008: NaN payload must be preserved
+ }
+
+ if (float.IsNaN(y))
+ {
+ return y; // IEEE 754-2008: NaN payload must be preserved
+ }
+
+ var regularMod = x % y;
+
+ if (float.IsNaN(regularMod))
+ {
+ return float.NaN;
+ }
+
+ if ((regularMod == 0) && float.IsNegative(x))
+ {
+ return float.NegativeZero;
+ }
+
+ var alternativeResult = (regularMod - (Abs(y) * Sign(x)));
+
+ if (Abs(alternativeResult) == Abs(regularMod))
+ {
+ var divisionResult = x / y;
+ var roundedResult = Round(divisionResult);
+
+ if (Abs(roundedResult) > Abs(divisionResult))
+ {
+ return alternativeResult;
+ }
+ else
+ {
+ return regularMod;
+ }
+ }
+
+ if (Abs(alternativeResult) < Abs(regularMod))
+ {
+ return alternativeResult;
+ }
+ else
+ {
+ return regularMod;
+ }
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern float Log(float x);
+
+ public static float Log(float x, float y)
+ {
+ if (float.IsNaN(x))
+ {
+ return x; // IEEE 754-2008: NaN payload must be preserved
+ }
+
+ if (float.IsNaN(y))
+ {
+ return y; // IEEE 754-2008: NaN payload must be preserved
+ }
+
+ if (y == 1)
+ {
+ return float.NaN;
+ }
+
+ if ((x != 1) && ((y == 0) || float.IsPositiveInfinity(y)))
+ {
+ return float.NaN;
+ }
+
+ return Log(x) / Log(y);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern float Log10(float x);
+
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ public static float Max(float x, float y) => Math.Max(x, y);
+
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ public static float Min(float x, float y) => Math.Min(x, y);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern float Pow(float x, float y);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern float Round(float x);
+
+ public static float Round(float x, int digits)
+ {
+ if ((digits < 0) || (digits > maxRoundingDigits))
+ {
+ throw new ArgumentOutOfRangeException(nameof(digits), Environment.GetResourceString("ArgumentOutOfRange_RoundingDigits"));
+ }
+ Contract.EndContractBlock();
+
+ return InternalRound(x, digits, MidpointRounding.ToEven);
+ }
+
+ public static float Round(float x, 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_InvalidEnumx", mode, nameof(MidpointRounding)), nameof(mode));
+ }
+ Contract.EndContractBlock();
+
+ return InternalRound(x, digits, mode);
+ }
+
+ public static float Round(float x, MidpointRounding mode)
+ {
+ if (mode < MidpointRounding.ToEven || mode > MidpointRounding.AwayFromZero)
+ {
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidEnumx", mode, nameof(MidpointRounding)), nameof(mode));
+ }
+ Contract.EndContractBlock();
+
+ return InternalRound(x, 0, mode);
+ }
+
+ public static int Sign(float x) => Math.Sign(x);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern float Sin(float x);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern float Sinh(float x);
+
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern float Sqrt(float x);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern float Tan(float x);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern float Tanh(float x);
+
+ public static float Truncate(float x) => InternalTruncate(x);
+
+ private static unsafe float InternalRound(float x, int digits, MidpointRounding mode)
+ {
+ 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);
+ }
+ }
+ else
+ {
+ x = Round(x);
+ }
+
+ x /= power10;
+ }
+
+ return x;
+ }
+
+ private unsafe static float InternalTruncate(float x)
+ {
+ SplitFractionSingle(&x);
+ return x;
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static unsafe extern float SplitFractionSingle(float* x);
+ }
+}
diff --git a/src/mscorlib/src/System/MissingFieldException.cs b/src/mscorlib/src/System/MissingFieldException.cs
index 4196ea8f6b..d96d0378e3 100644
--- a/src/mscorlib/src/System/MissingFieldException.cs
+++ b/src/mscorlib/src/System/MissingFieldException.cs
@@ -39,7 +39,6 @@ namespace System {
public override String Message
{
- [System.Security.SecuritySafeCritical] // auto-generated
get {
if (ClassName == null) {
return base.Message;
diff --git a/src/mscorlib/src/System/MissingMemberException.cs b/src/mscorlib/src/System/MissingMemberException.cs
index 30ce5b8fd0..ab773dc467 100644
--- a/src/mscorlib/src/System/MissingMemberException.cs
+++ b/src/mscorlib/src/System/MissingMemberException.cs
@@ -48,7 +48,6 @@ namespace System {
public override String Message
{
- [System.Security.SecuritySafeCritical] // auto-generated
get {
if (ClassName == null) {
return base.Message;
@@ -62,7 +61,6 @@ namespace System {
}
// Called to format signature
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern String FormatSignature(byte [] signature);
@@ -82,10 +80,9 @@ namespace System {
MemberName = memberName;
}
- [System.Security.SecurityCritical] // auto-generated_required
public override void GetObjectData(SerializationInfo info, StreamingContext context) {
if (info==null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
base.GetObjectData(info, context);
diff --git a/src/mscorlib/src/System/MissingMethodException.cs b/src/mscorlib/src/System/MissingMethodException.cs
index cba33efa0f..79434900a1 100644
--- a/src/mscorlib/src/System/MissingMethodException.cs
+++ b/src/mscorlib/src/System/MissingMethodException.cs
@@ -41,7 +41,6 @@ namespace System {
public override String Message
{
- [System.Security.SecuritySafeCritical] // auto-generated
get {
if (ClassName == null) {
return base.Message;
diff --git a/src/mscorlib/src/System/MulticastDelegate.cs b/src/mscorlib/src/System/MulticastDelegate.cs
index f59db16850..a7b244cdae 100644
--- a/src/mscorlib/src/System/MulticastDelegate.cs
+++ b/src/mscorlib/src/System/MulticastDelegate.cs
@@ -9,6 +9,7 @@ namespace System
using System.Runtime;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Reflection.Emit;
@@ -20,9 +21,7 @@ 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
- [System.Security.SecurityCritical]
private Object _invocationList;
- [System.Security.SecurityCritical]
private IntPtr _invocationCount;
// This constructor is called from the class generated by the
@@ -39,19 +38,16 @@ namespace System
{
}
- [System.Security.SecuritySafeCritical]
internal bool IsUnmanagedFunctionPtr()
{
return (_invocationCount == (IntPtr)(-1));
}
- [System.Security.SecuritySafeCritical]
internal bool InvocationListLogicallyNull()
{
return (_invocationList == null) || (_invocationList is LoaderAllocator) || (_invocationList is DynamicResolver);
}
- [System.Security.SecurityCritical]
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
int targetIndex = 0;
@@ -101,7 +97,6 @@ namespace System
// equals returns true IIF the delegate is not null and has the
// same target, method and invocation list as this object
- [System.Security.SecuritySafeCritical] // auto-generated
public override sealed bool Equals(Object obj)
{
if (obj == null)
@@ -114,7 +109,7 @@ namespace System
// Since this is a MulticastDelegate and we know
// the types are the same, obj should also be a
// MulticastDelegate
- Contract.Assert(obj is MulticastDelegate, "Shouldn't have failed here since we already checked the types are the same!");
+ 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)
@@ -151,7 +146,7 @@ namespace System
}
else
{
- Contract.Assert((_invocationList as Object[]) != null, "empty invocation list on multicast delegate");
+ Debug.Assert((_invocationList as Object[]) != null, "empty invocation list on multicast delegate");
return InvocationListEquals(d);
}
}
@@ -180,10 +175,9 @@ namespace System
}
// Recursive function which will check for equality of the invocation list.
- [System.Security.SecuritySafeCritical]
private bool InvocationListEquals(MulticastDelegate d)
{
- Contract.Assert(d != null && (_invocationList as Object[]) != null, "bogus delegate in multicast list comparison");
+ Debug.Assert(d != null && (_invocationList as Object[]) != null, "bogus delegate in multicast list comparison");
Object[] invocationList = _invocationList as Object[];
if (d._invocationCount != _invocationCount)
return false;
@@ -199,7 +193,6 @@ namespace System
return true;
}
- [System.Security.SecurityCritical]
private bool TrySetSlot(Object[] a, int index, Object o)
{
if (a[index] == null && System.Threading.Interlocked.CompareExchange<Object>(ref a[index], o, null) == null)
@@ -222,7 +215,6 @@ namespace System
return false;
}
- [System.Security.SecurityCritical]
private MulticastDelegate NewMulticastDelegate(Object[] invocationList, int invocationCount, bool thisIsMultiCastAlready)
{
// First, allocate a new multicast delegate just like this one, i.e. same type as the this object
@@ -247,18 +239,16 @@ namespace System
return result;
}
- [System.Security.SecurityCritical]
internal MulticastDelegate NewMulticastDelegate(Object[] invocationList, int invocationCount)
{
return NewMulticastDelegate(invocationList, invocationCount, false);
}
- [System.Security.SecurityCritical]
internal void StoreDynamicMethod(MethodInfo dynamicMethod)
{
if (_invocationCount != (IntPtr)0)
{
- Contract.Assert(!IsUnmanagedFunctionPtr(), "dynamic method and unmanaged fntptr delegate combined");
+ 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;
@@ -270,7 +260,6 @@ namespace System
// This method will combine this delegate with the passed delegate
// to form a new delegate.
- [System.Security.SecuritySafeCritical] // auto-generated
protected override sealed Delegate CombineImpl(Delegate follow)
{
if ((Object)follow == null) // cast to object for a more efficient test
@@ -356,7 +345,6 @@ namespace System
}
}
- [System.Security.SecurityCritical]
private Object[] DeleteFromInvocationList(Object[] invocationList, int invocationCount, int deleteIndex, int deleteCount)
{
Object[] thisInvocationList = _invocationList as Object[];
@@ -390,7 +378,6 @@ namespace System
// look at the invocation list.) If this is found we remove it from
// this list and return a new delegate. If its not found a copy of the
// current list is returned.
- [System.Security.SecuritySafeCritical] // auto-generated
protected override sealed Delegate RemoveImpl(Delegate value)
{
// There is a special case were we are removing using a delegate as
@@ -464,7 +451,6 @@ namespace System
}
// This method returns the Invocation list of this multicast delegate.
- [System.Security.SecuritySafeCritical]
public override sealed Delegate[] GetInvocationList()
{
Contract.Ensures(Contract.Result<Delegate[]>() != null);
@@ -505,7 +491,6 @@ namespace System
return !d1.Equals(d2);
}
- [System.Security.SecuritySafeCritical]
public override sealed int GetHashCode()
{
if (IsUnmanagedFunctionPtr())
@@ -528,7 +513,6 @@ namespace System
}
}
- [System.Security.SecuritySafeCritical]
internal override Object GetTarget()
{
if (_invocationCount != (IntPtr)0)
@@ -562,7 +546,6 @@ namespace System
return base.GetTarget();
}
- [System.Security.SecuritySafeCritical]
protected override MethodInfo GetMethodImpl()
{
if (_invocationCount != (IntPtr)0 && _invocationList != null)
@@ -613,7 +596,6 @@ namespace System
throw new ArgumentException(Environment.GetResourceString("Arg_DlgtNullInst"));
}
- [System.Security.SecurityCritical]
[System.Diagnostics.DebuggerNonUserCode]
private void CtorClosed(Object target, IntPtr methodPtr)
{
@@ -623,7 +605,6 @@ namespace System
this._methodPtr = methodPtr;
}
- [System.Security.SecurityCritical]
[System.Diagnostics.DebuggerNonUserCode]
private void CtorClosedStatic(Object target, IntPtr methodPtr)
{
@@ -631,7 +612,6 @@ namespace System
this._methodPtr = methodPtr;
}
- [System.Security.SecurityCritical] // auto-generated
[System.Diagnostics.DebuggerNonUserCode]
private void CtorRTClosed(Object target, IntPtr methodPtr)
{
@@ -639,7 +619,6 @@ namespace System
this._methodPtr = AdjustTarget(target, methodPtr);
}
- [System.Security.SecurityCritical]
[System.Diagnostics.DebuggerNonUserCode]
private void CtorOpened(Object target, IntPtr methodPtr, IntPtr shuffleThunk)
{
@@ -648,7 +627,6 @@ namespace System
this._methodPtrAux = methodPtr;
}
- [System.Security.SecurityCritical] // auto-generated
[System.Diagnostics.DebuggerNonUserCode]
private void CtorSecureClosed(Object target, IntPtr methodPtr, IntPtr callThunk, IntPtr creatorMethod)
{
@@ -661,7 +639,6 @@ namespace System
this._invocationCount = GetInvokeMethod();
}
- [System.Security.SecurityCritical] // auto-generated
[System.Diagnostics.DebuggerNonUserCode]
private void CtorSecureClosedStatic(Object target, IntPtr methodPtr, IntPtr callThunk, IntPtr creatorMethod)
{
@@ -674,7 +651,6 @@ namespace System
this._invocationCount = GetInvokeMethod();
}
- [System.Security.SecurityCritical] // auto-generated
[System.Diagnostics.DebuggerNonUserCode]
private void CtorSecureRTClosed(Object target, IntPtr methodPtr, IntPtr callThunk, IntPtr creatorMethod)
{
@@ -687,7 +663,6 @@ namespace System
this._invocationCount = GetInvokeMethod();
}
- [System.Security.SecurityCritical] // auto-generated
[System.Diagnostics.DebuggerNonUserCode]
private void CtorSecureOpened(Object target, IntPtr methodPtr, IntPtr shuffleThunk, IntPtr callThunk, IntPtr creatorMethod)
{
@@ -700,7 +675,6 @@ namespace System
this._invocationCount = GetInvokeMethod();
}
- [System.Security.SecurityCritical] // auto-generated
[System.Diagnostics.DebuggerNonUserCode]
private void CtorVirtualDispatch(Object target, IntPtr methodPtr, IntPtr shuffleThunk)
{
@@ -709,7 +683,6 @@ namespace System
this._methodPtrAux = GetCallStub(methodPtr);
}
- [System.Security.SecurityCritical] // auto-generated
[System.Diagnostics.DebuggerNonUserCode]
private void CtorSecureVirtualDispatch(Object target, IntPtr methodPtr, IntPtr shuffleThunk, IntPtr callThunk, IntPtr creatorMethod)
{
@@ -722,7 +695,6 @@ namespace System
this._invocationCount = GetInvokeMethod();
}
- [System.Security.SecurityCritical] // auto-generated
[System.Diagnostics.DebuggerNonUserCode]
private void CtorCollectibleClosedStatic(Object target, IntPtr methodPtr, IntPtr gchandle)
{
@@ -731,7 +703,6 @@ namespace System
this._methodBase = System.Runtime.InteropServices.GCHandle.InternalGet(gchandle);
}
- [System.Security.SecurityCritical] // auto-generated
[System.Diagnostics.DebuggerNonUserCode]
private void CtorCollectibleOpened(Object target, IntPtr methodPtr, IntPtr shuffleThunk, IntPtr gchandle)
{
@@ -741,7 +712,6 @@ namespace System
this._methodBase = System.Runtime.InteropServices.GCHandle.InternalGet(gchandle);
}
- [System.Security.SecurityCritical] // auto-generated
[System.Diagnostics.DebuggerNonUserCode]
private void CtorCollectibleVirtualDispatch(Object target, IntPtr methodPtr, IntPtr shuffleThunk, IntPtr gchandle)
{
diff --git a/src/mscorlib/src/System/NotFiniteNumberException.cs b/src/mscorlib/src/System/NotFiniteNumberException.cs
index a3d455aac6..3a896ce548 100644
--- a/src/mscorlib/src/System/NotFiniteNumberException.cs
+++ b/src/mscorlib/src/System/NotFiniteNumberException.cs
@@ -57,10 +57,9 @@ namespace System {
get { return _offendingNumber; }
}
- [System.Security.SecurityCritical] // auto-generated_required
public override void GetObjectData(SerializationInfo info, StreamingContext context) {
if (info==null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
base.GetObjectData(info, context);
diff --git a/src/mscorlib/src/System/Nullable.cs b/src/mscorlib/src/System/Nullable.cs
index 2091e20af3..8a22c8e65c 100644
--- a/src/mscorlib/src/System/Nullable.cs
+++ b/src/mscorlib/src/System/Nullable.cs
@@ -130,7 +130,7 @@ namespace System
// Otherwise, returns the underlying type of the Nullable type
public static Type GetUnderlyingType(Type nullableType) {
if((object)nullableType == null) {
- throw new ArgumentNullException("nullableType");
+ throw new ArgumentNullException(nameof(nullableType));
}
Contract.EndContractBlock();
Type result = null;
diff --git a/src/mscorlib/src/System/Number.cs b/src/mscorlib/src/System/Number.cs
index 3c1215d418..3412c02c31 100644
--- a/src/mscorlib/src/System/Number.cs
+++ b/src/mscorlib/src/System/Number.cs
@@ -11,6 +11,7 @@ namespace System {
using System.Runtime.Versioning;
using System.Security;
using System.Text;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
// The Number class implements methods for formatting and parsing
@@ -289,38 +290,28 @@ namespace System {
private Number() {
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern String FormatDecimal(Decimal value, String format, NumberFormatInfo info);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern String FormatDouble(double value, String format, NumberFormatInfo info);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern String FormatInt32(int value, String format, NumberFormatInfo info);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern String FormatUInt32(uint value, String format, NumberFormatInfo info);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern String FormatInt64(long value, String format, NumberFormatInfo info);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern String FormatUInt64(ulong value, String format, NumberFormatInfo info);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern String FormatSingle(float value, String format, NumberFormatInfo info);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public unsafe static extern Boolean NumberBufferToDecimal(byte* number, ref Decimal value);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal unsafe static extern Boolean NumberBufferToDouble(byte* number, ref Double value);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[System.Runtime.CompilerServices.FriendAccessAllowed]
- [System.Security.SecurityCritical] // auto-generated
internal static extern unsafe string FormatNumberBuffer(byte* number, string format, NumberFormatInfo info, char* allDigits);
// Constants used by number parsing
@@ -350,15 +341,12 @@ namespace System {
// 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;
- [SecurityCritical]
private Byte * baseAddress;
- [SecurityCritical]
public Char * digits;
public Int32 precision;
public Int32 scale;
public Boolean sign;
- [System.Security.SecurityCritical] // auto-generated
public NumberBuffer(Byte* stackBuffer) {
this.baseAddress = stackBuffer;
this.digits = (((Char*) stackBuffer) + 6);
@@ -367,7 +355,6 @@ namespace System {
this.sign = false;
}
- [System.Security.SecurityCritical] // auto-generated
public Byte* PackForNative() {
Int32* baseInteger = (Int32*) baseAddress;
baseInteger[0] = precision;
@@ -391,7 +378,6 @@ namespace System {
return returnValue;
}
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe static Boolean HexNumberToUInt32(ref NumberBuffer number, ref UInt32 value) {
Int32 i = number.scale;
@@ -399,7 +385,7 @@ namespace System {
return false;
}
Char* p = number.digits;
- Contract.Assert(p != null, "");
+ Debug.Assert(p != null, "");
UInt32 n = 0;
while (--i >= 0) {
@@ -418,7 +404,7 @@ namespace System {
newN += (UInt32)((*p - 'A') + 10);
}
else {
- Contract.Assert(*p >= 'a' && *p <= 'f', "");
+ Debug.Assert(*p >= 'a' && *p <= 'f', "");
newN += (UInt32)((*p - 'a') + 10);
}
}
@@ -436,7 +422,6 @@ namespace System {
return true;
}
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe static Boolean HexNumberToUInt64(ref NumberBuffer number, ref UInt64 value) {
Int32 i = number.scale;
@@ -444,7 +429,7 @@ namespace System {
return false;
}
Char* p = number.digits;
- Contract.Assert(p != null, "");
+ Debug.Assert(p != null, "");
UInt64 n = 0;
while (--i >= 0) {
@@ -463,7 +448,7 @@ namespace System {
newN += (UInt64)((*p - 'A') + 10);
}
else {
- Contract.Assert(*p >= 'a' && *p <= 'f', "");
+ Debug.Assert(*p >= 'a' && *p <= 'f', "");
newN += (UInt64)((*p - 'a') + 10);
}
}
@@ -485,7 +470,6 @@ namespace System {
return (((ch) == 0x20) || ((ch) >= 0x09 && (ch) <= 0x0D));
}
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe static Boolean NumberToInt32(ref NumberBuffer number, ref Int32 value) {
Int32 i = number.scale;
@@ -493,7 +477,7 @@ namespace System {
return false;
}
char * p = number.digits;
- Contract.Assert(p != null, "");
+ Debug.Assert(p != null, "");
Int32 n = 0;
while (--i >= 0) {
if ((UInt32)n > (0x7FFFFFFF / 10)) {
@@ -519,7 +503,6 @@ namespace System {
return true;
}
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe static Boolean NumberToInt64(ref NumberBuffer number, ref Int64 value) {
Int32 i = number.scale;
@@ -527,7 +510,7 @@ namespace System {
return false;
}
char* p = number.digits;
- Contract.Assert(p != null, "");
+ Debug.Assert(p != null, "");
Int64 n = 0;
while (--i >= 0) {
if ((UInt64)n > (0x7FFFFFFFFFFFFFFF / 10)) {
@@ -553,7 +536,6 @@ namespace System {
return true;
}
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe static Boolean NumberToUInt32(ref NumberBuffer number, ref UInt32 value) {
Int32 i = number.scale;
@@ -561,7 +543,7 @@ namespace System {
return false;
}
char* p = number.digits;
- Contract.Assert(p != null, "");
+ Debug.Assert(p != null, "");
UInt32 n = 0;
while (--i >= 0) {
if (n > (0xFFFFFFFF / 10)) {
@@ -581,7 +563,6 @@ namespace System {
return true;
}
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe static Boolean NumberToUInt64(ref NumberBuffer number, ref UInt64 value) {
Int32 i = number.scale;
@@ -589,7 +570,7 @@ namespace System {
return false;
}
char * p = number.digits;
- Contract.Assert(p != null, "");
+ Debug.Assert(p != null, "");
UInt64 n = 0;
while (--i >= 0) {
if (n > (0xFFFFFFFFFFFFFFFF / 10)) {
@@ -609,32 +590,29 @@ namespace System {
return true;
}
- [System.Security.SecurityCritical] // auto-generated
private unsafe static char * MatchChars(char* p, string str) {
fixed (char* stringPointer = str) {
return MatchChars(p, stringPointer);
}
}
- [System.Security.SecurityCritical] // auto-generated
private unsafe static char * MatchChars(char* p, char* str) {
- Contract.Assert(p != null && str != null, "");
+ Debug.Assert(p != null && str != null, "");
if (*str == '\0') {
return null;
}
- for (; (*str != '\0'); p++, str++) {
- if (*p != *str) { //We only hurt the failure case
- if ((*str == '\u00A0') && (*p == '\u0020')) {// 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.
- continue;
- }
- 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.
+ while (*p == *str || (*str == '\u00a0' && *p == '\u0020'))
+ {
+ p++;
+ str++;
+ if (*str == '\0') return p;
}
- return p;
+ return null;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static Decimal ParseDecimal(String value, NumberStyles options, NumberFormatInfo numfmt) {
Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
@@ -649,10 +627,9 @@ namespace System {
return result;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static Double ParseDouble(String value, NumberStyles options, NumberFormatInfo numfmt) {
if (value == null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
@@ -683,7 +660,6 @@ namespace System {
return d;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static Int32 ParseInt32(String s, NumberStyles style, NumberFormatInfo info) {
Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
@@ -705,7 +681,6 @@ namespace System {
return i;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static Int64 ParseInt64(String value, NumberStyles options, NumberFormatInfo numfmt) {
Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
@@ -726,7 +701,6 @@ namespace System {
return i;
}
- [System.Security.SecurityCritical] // auto-generated
private unsafe static Boolean ParseNumber(ref char * str, NumberStyles options, ref NumberBuffer number, StringBuilder sb, NumberFormatInfo numfmt, Boolean parseDecimal) {
const Int32 StateSign = 0x0001;
@@ -742,26 +716,12 @@ namespace System {
string groupSep; // group separator from NumberFormatInfo.
string currSymbol = null; // currency symbol from NumberFormatInfo.
- // The alternative currency symbol used in 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)
- string ansicurrSymbol = null; // currency symbol from NumberFormatInfo.
- string altdecSep = null; // decimal separator from NumberFormatInfo as a decimal
- string altgroupSep = null; // group separator from NumberFormatInfo as a decimal
-
Boolean parsingCurrency = false;
if ((options & NumberStyles.AllowCurrencySymbol) != 0) {
currSymbol = numfmt.CurrencySymbol;
-#if !FEATURE_COREFX_GLOBALIZATION
- if (numfmt.ansiCurrencySymbol != null) {
- ansicurrSymbol = numfmt.ansiCurrencySymbol;
- }
-#endif
-
// 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.
// The values of decSep are setup to use the correct relevant separator (currency in the if part and decimal in the else part).
- altdecSep = numfmt.NumberDecimalSeparator;
- altgroupSep = numfmt.NumberGroupSeparator;
decSep = numfmt.CurrencyDecimalSeparator;
groupSep = numfmt.CurrencyGroupSeparator;
parsingCurrency = true;
@@ -772,9 +732,7 @@ namespace System {
}
Int32 state = 0;
- Boolean signflag = false; // Cache the results of "options & PARSE_LEADINGSIGN && !(state & STATE_SIGN)" to avoid doing this twice
Boolean bigNumber = (sb != null); // When a StringBuilder is provided then we use it in place of the number.digits char[50]
- Boolean bigNumberHex = (bigNumber && ((options & NumberStyles.AllowHexSpecifier) != 0));
Int32 maxParseDigits = bigNumber ? Int32.MaxValue : NumberMaxDigits;
char* p = str;
@@ -784,32 +742,26 @@ namespace System {
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 & StateSign) != 0) && (((state & StateCurrency) != 0) || numfmt.numberNegativePattern == 2)))) {
- // Do nothing here. We will increase p at the end of the loop.
- }
- else if ((signflag = (((options & NumberStyles.AllowLeadingSign) != 0) && ((state & StateSign) == 0))) && ((next = MatchChars(p, numfmt.positiveSign)) != null)) {
- state |= StateSign;
- p = next - 1;
- } else if (signflag && (next = MatchChars(p, numfmt.negativeSign)) != null) {
- state |= StateSign;
- number.sign = true;
- 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) || (ansicurrSymbol != null && (next = MatchChars(p, ansicurrSymbol)) != null)) {
- state |= StateCurrency;
- currSymbol = null;
- ansicurrSymbol = 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;
@@ -818,7 +770,7 @@ namespace System {
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 || bigNumberHex) {
+ if (ch != '0' || (state & StateNonZero) != 0 || (bigNumber && ((options & NumberStyles.AllowHexSpecifier) != 0))) {
if (digCount < maxParseDigits) {
if (bigNumber)
sb.Append(ch);
@@ -837,11 +789,11 @@ namespace System {
number.scale--;
}
}
- else if (((options & NumberStyles.AllowDecimalPoint) != 0) && ((state & StateDecimal) == 0) && ((next = MatchChars(p, decSep)) != null || ((parsingCurrency) && (state & StateCurrency) == 0) && (next = MatchChars(p, altdecSep)) != 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, altgroupSep)) != 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 {
@@ -890,27 +842,22 @@ namespace System {
}
}
while (true) {
- if (IsWhite(ch) && ((options & NumberStyles.AllowTrailingWhite) != 0)) {
- }
- else if ((signflag = (((options & NumberStyles.AllowTrailingSign) != 0) && ((state & StateSign) == 0))) && (next = MatchChars(p, numfmt.positiveSign)) != null) {
- state |= StateSign;
- p = next - 1;
- } else if (signflag && (next = MatchChars(p, numfmt.negativeSign)) != null) {
- state |= StateSign;
- number.sign = true;
- p = next - 1;
- }
- else if (ch == ')' && ((state & StateParens) != 0)) {
- state &= ~StateParens;
- }
- else if ((currSymbol != null && (next = MatchChars(p, currSymbol)) != null) || (ansicurrSymbol != null && (next = MatchChars(p, ansicurrSymbol)) != null)) {
- currSymbol = null;
- ansicurrSymbol = null;
- p = next - 1;
- }
- else {
- break;
- }
+ 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) {
@@ -930,10 +877,9 @@ namespace System {
return false;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static Single ParseSingle(String value, NumberStyles options, NumberFormatInfo numfmt) {
if (value == null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
@@ -967,7 +913,6 @@ namespace System {
return castSingle;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static UInt32 ParseUInt32(String value, NumberStyles options, NumberFormatInfo numfmt) {
Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
@@ -990,7 +935,6 @@ namespace System {
return i;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static UInt64 ParseUInt64(String value, NumberStyles options, NumberFormatInfo numfmt) {
Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
@@ -1010,14 +954,13 @@ namespace System {
return i;
}
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe static void StringToNumber(String str, NumberStyles options, ref NumberBuffer number, NumberFormatInfo info, Boolean parseDecimal) {
if (str == null) {
- throw new ArgumentNullException("String");
+ throw new ArgumentNullException(nameof(String));
}
Contract.EndContractBlock();
- Contract.Assert(info != null, "");
+ Debug.Assert(info != null, "");
fixed (char* stringPointer = str) {
char * p = stringPointer;
if (!ParseNumber(ref p, options, ref number, null, info , parseDecimal)
@@ -1037,7 +980,6 @@ namespace System {
return true;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static Boolean TryParseDecimal(String value, NumberStyles options, NumberFormatInfo numfmt, out Decimal result) {
Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
@@ -1054,7 +996,6 @@ namespace System {
return true;
}
- [System.Security.SecuritySafeCritical] // auto-generated
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);
@@ -1070,7 +1011,6 @@ namespace System {
return true;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static Boolean TryParseInt32(String s, NumberStyles style, NumberFormatInfo info, out Int32 result) {
Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
@@ -1094,7 +1034,6 @@ namespace System {
return true;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static Boolean TryParseInt64(String s, NumberStyles style, NumberFormatInfo info, out Int64 result) {
Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
@@ -1118,7 +1057,6 @@ namespace System {
return true;
}
- [System.Security.SecuritySafeCritical] // auto-generated
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);
@@ -1140,7 +1078,6 @@ namespace System {
return true;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static Boolean TryParseUInt32(String s, NumberStyles style, NumberFormatInfo info, out UInt32 result) {
Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
@@ -1164,7 +1101,6 @@ namespace System {
return true;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static Boolean TryParseUInt64(String s, NumberStyles style, NumberFormatInfo info, out UInt64 result) {
Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
@@ -1192,14 +1128,13 @@ namespace System {
return TryStringToNumber(str, options, ref number, null, numfmt, parseDecimal);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[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) {
return false;
}
- Contract.Assert(numfmt != null, "");
+ Debug.Assert(numfmt != null, "");
fixed (char* stringPointer = str) {
char * p = stringPointer;
diff --git a/src/mscorlib/src/System/Numerics/Hashing/HashHelpers.cs b/src/mscorlib/src/System/Numerics/Hashing/HashHelpers.cs
new file mode 100644
index 0000000000..0314d1af3c
--- /dev/null
+++ b/src/mscorlib/src/System/Numerics/Hashing/HashHelpers.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.Numerics.Hashing
+{
+ // Please change the corresponding file in corefx if this is changed.
+
+ internal static class HashHelpers
+ {
+ public static int Combine(int h1, int h2)
+ {
+ // The jit optimizes this to use the ROL instruction on x86
+ // Related GitHub pull request: dotnet/coreclr#1830
+ uint shift5 = ((uint)h1 << 5) | ((uint)h1 >> 27);
+ return ((int)shift5 + h1) ^ h2;
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Object.cs b/src/mscorlib/src/System/Object.cs
index 769c5a6bd6..d8d9a0e36c 100644
--- a/src/mscorlib/src/System/Object.cs
+++ b/src/mscorlib/src/System/Object.cs
@@ -12,7 +12,8 @@
**
===========================================================*/
-namespace System {
+namespace System
+{
using System;
using System.Runtime;
using System.Runtime.InteropServices;
@@ -23,9 +24,7 @@ namespace System {
using CultureInfo = System.Globalization.CultureInfo;
using FieldInfo = System.Reflection.FieldInfo;
using BindingFlags = System.Reflection.BindingFlags;
-#if FEATURE_REMOTING
- using RemotingException = System.Runtime.Remoting.RemotingException;
-#endif
+
// 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
@@ -96,7 +95,6 @@ public class Object
// Returns a Type object which represent this object instance.
//
- [System.Security.SecuritySafeCritical] // auto-generated
[Pure]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern Type GetType();
@@ -114,14 +112,12 @@ public class Object
// so that other object may only call this method on themselves. It is entended to
// support the ICloneable interface.
//
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
protected extern Object MemberwiseClone();
// Sets the value specified in the variant on the field
//
- [System.Security.SecurityCritical] // auto-generated
private void FieldSetter(String typeName, String fieldName, Object val)
{
Contract.Requires(typeName != null);
@@ -135,26 +131,21 @@ public class Object
// Make sure that the value is compatible with the type
// of field
-#if FEATURE_REMOTING
- System.Runtime.Remoting.Messaging.Message.CoerceArg(val, fldInfo.FieldType);
-#else
Type pt=fldInfo.FieldType;
if (pt.IsByRef)
{
pt = pt.GetElementType();
}
-
+
if (!pt.IsInstanceOfType(val))
{
val = Convert.ChangeType(val, pt, CultureInfo.InvariantCulture);
}
-#endif
-
- // Set the value
+ // Set the value
fldInfo.SetValue(this, val);
}
-
+
// Gets the value specified in the variant on the field
//
private void FieldGetter(String typeName, String fieldName, ref Object val)
@@ -166,7 +157,7 @@ public class Object
FieldInfo fldInfo = GetFieldInfo(typeName, fieldName);
// Get the value
- val = fldInfo.GetValue(this);
+ val = fldInfo.GetValue(this);
}
// Gets the field info object given the type name and field name.
@@ -190,13 +181,7 @@ public class Object
if (null == t)
{
-#if FEATURE_REMOTING
- throw new RemotingException(String.Format(
- CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_BadType"),
- typeName));
-#else
throw new ArgumentException();
-#endif
}
FieldInfo fldInfo = t.GetField(fieldName, BindingFlags.Public |
@@ -204,16 +189,9 @@ public class Object
BindingFlags.IgnoreCase);
if(null == fldInfo)
{
-#if FEATURE_REMOTING
- throw new RemotingException(String.Format(
- CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_BadField"),
- fieldName, typeName));
-#else
throw new ArgumentException();
-#endif
-
}
-
+
return fldInfo;
}
}
@@ -233,22 +211,16 @@ internal class __Canon
// This class is used to define the name of the base class library
internal class CoreLib
{
-
-#if FEATURE_CORECLR
public const string Name = "System.Private.CoreLib";
-#else
- public const string Name = "mscorlib";
-#endif
public static string FixupCoreLibName(string strToFixup)
{
-#if FEATURE_CORECLR
if (!String.IsNullOrEmpty(strToFixup))
{
strToFixup = strToFixup.Replace("mscorlib", System.CoreLib.Name);
}
-#endif
- return strToFixup;
+
+ return strToFixup;
}
}
diff --git a/src/mscorlib/src/System/ObjectDisposedException.cs b/src/mscorlib/src/System/ObjectDisposedException.cs
index cf92cef5ee..d2eca37325 100644
--- a/src/mscorlib/src/System/ObjectDisposedException.cs
+++ b/src/mscorlib/src/System/ObjectDisposedException.cs
@@ -64,7 +64,6 @@ namespace System {
objectName = info.GetString("ObjectName");
}
- [System.Security.SecurityCritical] // auto-generated_required
public override void GetObjectData(SerializationInfo info, StreamingContext context) {
base.GetObjectData(info, context);
info.AddValue("ObjectName",ObjectName,typeof(String));
diff --git a/src/mscorlib/src/System/OleAutBinder.cs b/src/mscorlib/src/System/OleAutBinder.cs
index 1ed1e32ca9..acae95a214 100644
--- a/src/mscorlib/src/System/OleAutBinder.cs
+++ b/src/mscorlib/src/System/OleAutBinder.cs
@@ -20,7 +20,6 @@ namespace System {
{
// ChangeType
// This binder uses OLEAUT to change the type of the variant.
- [System.Security.SecuritySafeCritical] // overrides transparent member
public override Object ChangeType(Object value, Type type, CultureInfo cultureInfo)
{
Variant myValue = new Variant(value);
@@ -60,24 +59,6 @@ namespace System {
return Enum.Parse(type, value.ToString());
}
-#if !FEATURE_CORECLR
- // Special case the convertion from DBNull.
- if (srcType == typeof(DBNull))
- {
- // The requested type is a DBNull so no convertion is required.
- if (type == typeof(DBNull))
- return value;
-
- // Visual J++ supported converting from DBNull to null so customers
- // have requested (via a CDCR) that DBNull be convertible to null.
- // We don't however allow this when converting to a value class, since null
- // doesn't make sense for these, or to object since this would change existing
- // semantics.
- if ((type.IsClass && type != typeof(Object)) || type.IsInterface)
- return null;
- }
-#endif //!FEATURE_CORECLR
-
// Use the OA variant lib to convert primitive types.
try
{
@@ -107,7 +88,5 @@ namespace System {
throw new COMException(Environment.GetResourceString("Interop.COM_TypeMismatch"), unchecked((int)0x80020005));
}
}
-
-
}
}
diff --git a/src/mscorlib/src/System/OperatingSystem.cs b/src/mscorlib/src/System/OperatingSystem.cs
index 6955310acf..a11d4bcce8 100644
--- a/src/mscorlib/src/System/OperatingSystem.cs
+++ b/src/mscorlib/src/System/OperatingSystem.cs
@@ -38,11 +38,11 @@ namespace System {
if( platform < PlatformID.Win32S || platform > PlatformID.MacOSX) {
throw new ArgumentException(
Environment.GetResourceString("Arg_EnumIllegalVal", (int)platform),
- "platform");
+ nameof(platform));
}
if ((Object) version == null)
- throw new ArgumentNullException("version");
+ throw new ArgumentNullException(nameof(version));
Contract.EndContractBlock();
_platform = platform;
@@ -71,10 +71,9 @@ namespace System {
}
}
- [System.Security.SecurityCritical] // auto-generated_required
public void GetObjectData(SerializationInfo info, StreamingContext context) {
if( info == null ) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
diff --git a/src/mscorlib/src/System/ParseNumbers.cs b/src/mscorlib/src/System/ParseNumbers.cs
index 01c2ae3019..2a375f7584 100644
--- a/src/mscorlib/src/System/ParseNumbers.cs
+++ b/src/mscorlib/src/System/ParseNumbers.cs
@@ -33,41 +33,33 @@ namespace System {
// NATIVE METHODS
// For comments on these methods please see $\src\vm\COMUtilNative.cpp
//
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe static long StringToLong(System.String s, int radix, int flags) {
return StringToLong(s,radix,flags, null);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public unsafe extern static long StringToLong(System.String s, int radix, int flags, int* currPos);
- [System.Security.SecuritySafeCritical] // auto-generated
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);
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe static int StringToInt(System.String s, int radix, int flags) {
return StringToInt(s,radix,flags, null);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public unsafe extern static int StringToInt(System.String s, int radix, int flags, int* currPos);
- [System.Security.SecuritySafeCritical] // auto-generated
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);
}
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern static String IntToString(int l, int radix, int width, char paddingChar, int flags);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern static String LongToString(long l, int radix, int width, char paddingChar, int flags);
}
diff --git a/src/mscorlib/src/System/Progress.cs b/src/mscorlib/src/System/Progress.cs
index 8800c0322a..72c43c304d 100644
--- a/src/mscorlib/src/System/Progress.cs
+++ b/src/mscorlib/src/System/Progress.cs
@@ -48,7 +48,7 @@ namespace System
// sync ctx reference identity issues where the sync ctx for one thread could be Current on another.
// If there is no current context, we use a default instance targeting the ThreadPool.
m_synchronizationContext = SynchronizationContext.CurrentNoFlow ?? ProgressStatics.DefaultContext;
- Contract.Assert(m_synchronizationContext != null);
+ Debug.Assert(m_synchronizationContext != null);
m_invokeHandlers = new SendOrPostCallback(InvokeHandlers);
}
@@ -63,7 +63,7 @@ namespace System
/// <exception cref="System.ArgumentNullException">The <paramref name="handler"/> is null (Nothing in Visual Basic).</exception>
public Progress(Action<T> handler) : this()
{
- if (handler == null) throw new ArgumentNullException("handler");
+ if (handler == null) throw new ArgumentNullException(nameof(handler));
m_handler = handler;
}
diff --git a/src/mscorlib/src/System/Random.cs b/src/mscorlib/src/System/Random.cs
index adede6a101..f5941d6718 100644
--- a/src/mscorlib/src/System/Random.cs
+++ b/src/mscorlib/src/System/Random.cs
@@ -11,13 +11,14 @@
**
===========================================================*/
namespace System {
-
+
using System;
using System.Runtime;
using System.Runtime.CompilerServices;
using System.Globalization;
using System.Diagnostics.Contracts;
-[System.Runtime.InteropServices.ComVisible(true)]
+
+ [System.Runtime.InteropServices.ComVisible(true)]
[Serializable]
public class Random {
//
@@ -46,13 +47,19 @@ namespace System {
//
// Constructors
//
-
+
+ /*=========================================================================================
+ **Action: Initializes a new instance of the Random class, using a default seed value
+ ===========================================================================================*/
public Random()
- : this(Environment.TickCount) {
+ : this(GenerateSeed()) {
}
-
+
+ /*=========================================================================================
+ **Action: Initializes a new instance of the Random class, using a specified seed value
+ ===========================================================================================*/
public Random(int Seed) {
- int ii;
+ int ii = 0;
int mj, mk;
//Initialize our Seed array.
@@ -61,7 +68,7 @@ namespace System {
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.
- ii = (21*i)%55;
+ if ((ii += 21) >= 55) ii -= 55;
SeedArray[ii]=mk;
mk = mj - mk;
if (mk<0) mk+=MBIG;
@@ -69,19 +76,21 @@ namespace System {
}
for (int k=1; k<5; k++) {
for (int i=1; i<56; i++) {
- SeedArray[i] -= SeedArray[1+(i+30)%55];
- if (SeedArray[i]<0) SeedArray[i]+=MBIG;
+ 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)
@@ -115,11 +124,41 @@ namespace System {
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
@@ -156,7 +195,7 @@ namespace System {
==============================================================================*/
public virtual int Next(int minValue, int maxValue) {
if (minValue>maxValue) {
- throw new ArgumentOutOfRangeException("minValue",Environment.GetResourceString("Argument_MinMaxValue", "minValue", "maxValue"));
+ throw new ArgumentOutOfRangeException(nameof(minValue),Environment.GetResourceString("Argument_MinMaxValue", nameof(minValue), nameof(maxValue)));
}
Contract.EndContractBlock();
@@ -177,7 +216,7 @@ namespace System {
==============================================================================*/
public virtual int Next(int maxValue) {
if (maxValue<0) {
- throw new ArgumentOutOfRangeException("maxValue", Environment.GetResourceString("ArgumentOutOfRange_MustBePositive", "maxValue"));
+ throw new ArgumentOutOfRangeException(nameof(maxValue), Environment.GetResourceString("ArgumentOutOfRange_MustBePositive", nameof(maxValue)));
}
Contract.EndContractBlock();
return (int)(Sample()*maxValue);
@@ -201,14 +240,11 @@ namespace System {
**Exceptions: None
==============================================================================*/
public virtual void NextBytes(byte [] buffer){
- if (buffer==null) throw new ArgumentNullException("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
new file mode 100644
index 0000000000..b0919d3208
--- /dev/null
+++ b/src/mscorlib/src/System/ReadOnlySpan.cs
@@ -0,0 +1,397 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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.CompilerServices;
+
+#pragma warning disable 0809 //warning CS0809: Obsolete member 'Span<T>.Equals(object)' overrides non-obsolete member 'object.Equals(object)'
+
+namespace System
+{
+ /// <summary>
+ /// ReadOnlySpan represents contiguous read-only region of arbitrary memory, with performance
+ /// characteristics on par with T[]. Unlike arrays, it can point to either managed
+ /// or native memory, or to memory allocated on the stack. It is type- and memory-safe.
+ /// </summary>
+ public struct ReadOnlySpan<T>
+ {
+ /// <summary>A byref or a native ptr.</summary>
+ private readonly ByReference<T> _pointer;
+ /// <summary>The number of elements this ReadOnlySpan contains.</summary>
+ private readonly int _length;
+
+ /// <summary>
+ /// Creates a new span over the entirety of the target array.
+ /// </summary>
+ /// <param name="array">The target array.</param>
+ /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="array"/> is a null
+ /// reference (Nothing in Visual Basic).</exception>
+ public ReadOnlySpan(T[] array)
+ {
+ if (array == null)
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
+
+ _pointer = new ByReference<T>(ref JitHelpers.GetArrayData(array));
+ _length = array.Length;
+ }
+
+ /// <summary>
+ /// Creates a new span over the portion of the target array beginning
+ /// at 'start' index and covering the remainder of the array.
+ /// </summary>
+ /// <param name="array">The target array.</param>
+ /// <param name="start">The index at which to begin the span.</param>
+ /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="array"/> is a null
+ /// reference (Nothing in Visual Basic).</exception>
+ /// <exception cref="System.ArgumentOutOfRangeException">
+ /// Thrown when the specified <paramref name="start"/> is not in the range (&lt;0 or &gt;&eq;Length).
+ /// </exception>
+ public ReadOnlySpan(T[] array, int start)
+ {
+ if (array == null)
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
+ if ((uint)start > (uint)array.Length)
+ ThrowHelper.ThrowArgumentOutOfRangeException();
+
+ _pointer = new ByReference<T>(ref Unsafe.Add(ref JitHelpers.GetArrayData(array), start));
+ _length = array.Length - start;
+ }
+
+ /// <summary>
+ /// Creates a new span over the portion of the target array beginning
+ /// at 'start' index and ending at 'end' index (exclusive).
+ /// </summary>
+ /// <param name="array">The target array.</param>
+ /// <param name="start">The index at which to begin the span.</param>
+ /// <param name="length">The number of items in the span.</param>
+ /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="array"/> 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 the range (&lt;0 or &gt;&eq;Length).
+ /// </exception>
+ public ReadOnlySpan(T[] array, int start, int length)
+ {
+ if (array == null)
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
+ if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
+ ThrowHelper.ThrowArgumentOutOfRangeException();
+
+ _pointer = new ByReference<T>(ref Unsafe.Add(ref JitHelpers.GetArrayData(array), start));
+ _length = length;
+ }
+
+ /// <summary>
+ /// Creates a new span over the target unmanaged buffer. Clearly this
+ /// is quite dangerous, because we are creating arbitrarily typed T's
+ /// out of a void*-typed block of memory. And the length is not checked.
+ /// But if this creation is correct, then all subsequent uses are correct.
+ /// </summary>
+ /// <param name="ptr">An unmanaged pointer to memory.</param>
+ /// <param name="length">The number of <typeparamref name="T"/> elements the memory contains.</param>
+ /// <exception cref="System.ArgumentException">
+ /// Thrown when <typeparamref name="T"/> is reference type or contains pointers and hence cannot be stored in unmanaged memory.
+ /// </exception>
+ /// <exception cref="System.ArgumentOutOfRangeException">
+ /// Thrown when the specified <paramref name="length"/> is negative.
+ /// </exception>
+ [CLSCompliant(false)]
+ public unsafe ReadOnlySpan(void* pointer, int length)
+ {
+ if (JitHelpers.ContainsReferences<T>())
+ ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T));
+ if (length < 0)
+ ThrowHelper.ThrowArgumentOutOfRangeException();
+
+ _pointer = new ByReference<T>(ref Unsafe.As<byte, T>(ref *(byte*)pointer));
+ _length = length;
+ }
+
+ /// <summary>
+ /// An internal helper for creating spans.
+ /// </summary>
+ internal ReadOnlySpan(ref T ptr, int length)
+ {
+ _pointer = new ByReference<T>(ref ptr);
+ _length = length;
+ }
+
+ /// <summary>
+ /// Returns a reference to the 0th element of the Span. If the Span is empty, returns a reference to the location where the 0th element
+ /// would have been stored. Such a reference can be used for pinning but must never be dereferenced.
+ /// </summary>
+ public ref T DangerousGetPinnableReference()
+ {
+ return ref _pointer.Value;
+ }
+
+ /// <summary>
+ /// This method is not supported as spans cannot be boxed. To compare two spans, use operator==.
+ /// <exception cref="System.NotSupportedException">
+ /// Always thrown by this method.
+ /// </exception>
+ /// </summary>
+ [Obsolete("Equals() on Span will always throw an exception. Use == instead.")]
+ 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);
+ }
+
+ /// <summary>
+ /// This method is not supported as spans cannot be boxed.
+ /// <exception cref="System.NotSupportedException">
+ /// Always thrown by this method.
+ /// </exception>
+ /// </summary>
+ [Obsolete("GetHashCode() on Span will always throw an exception.")]
+ public override int GetHashCode()
+ {
+ ThrowHelper.ThrowNotSupportedException_CannotCallGetHashCodeOnSpan();
+ // Prevent compiler error CS0161: 'Span<T>.GetHashCode()': not all code paths return a value
+ return default(int);
+ }
+
+ /// <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.
+ /// </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>
+ 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);
+ }
+
+ /// <summary>
+ /// Defines an implicit conversion of a <see cref="Span{T}"/> to a <see cref="ReadOnlySpan{T}"/>
+ /// </summary>
+ public static implicit operator ReadOnlySpan<T>(Span<T> slice)
+ {
+ return new ReadOnlySpan<T>(ref slice.DangerousGetPinnableReference(), slice.Length);
+ }
+
+ /// <summary>
+ /// Defines an implicit conversion of an array to a <see cref="ReadOnlySpan{T}"/>
+ /// </summary>
+ public static implicit operator ReadOnlySpan<T>(T[] array)
+ {
+ return new ReadOnlySpan<T>(array);
+ }
+
+ /// <summary>
+ /// Defines an implicit conversion of a <see cref="ArraySegment{T}"/> to a <see cref="ReadOnlySpan{T}"/>
+ /// </summary>
+ public static implicit operator ReadOnlySpan<T>(ArraySegment<T> arraySegment)
+ {
+ return new ReadOnlySpan<T>(arraySegment.Array, arraySegment.Offset, arraySegment.Count);
+ }
+
+ /// <summary>
+ /// Gets the number of elements contained in the <see cref="ReadOnlySpan{T}"/>
+ /// </summary>
+ public int Length
+ {
+ get { return _length; }
+ }
+
+ /// <summary>
+ /// Returns an empty <see cref="ReadOnlySpan{T}"/>
+ /// </summary>
+ public static ReadOnlySpan<T> Empty
+ {
+ get { return default(ReadOnlySpan<T>); }
+ }
+
+ /// <summary>
+ /// Returns whether the <see cref="ReadOnlySpan{T}"/> is empty.
+ /// </summary>
+ public bool IsEmpty
+ {
+ get { return _length == 0; }
+ }
+
+ /// <summary>
+ /// Fetches the element at the specified index.
+ /// </summary>
+ /// <exception cref="System.IndexOutOfRangeException">
+ /// Thrown when the specified <paramref name="index"/> is not in range (&lt;0 or &gt;&eq;Length).
+ /// </exception>
+ public T this[int index]
+ {
+ get
+ {
+ if ((uint)index >= (uint)_length)
+ ThrowHelper.ThrowIndexOutOfRangeException();
+
+ return Unsafe.Add(ref DangerousGetPinnableReference(), index);
+ }
+ }
+
+ /// <summary>
+ /// Copies the contents of this span into a new array. This heap
+ /// allocates, so should generally be avoided, however is sometimes
+ /// necessary to bridge the gap with APIs written in terms of arrays.
+ /// </summary>
+ public T[] ToArray()
+ {
+ if (_length == 0)
+ return Array.Empty<T>();
+
+ var destination = new T[_length];
+ SpanHelper.CopyTo<T>(ref JitHelpers.GetArrayData(destination), ref DangerousGetPinnableReference(), _length);
+ return destination;
+ }
+
+ /// <summary>
+ /// Forms a slice out of the given span, beginning at 'start'.
+ /// </summary>
+ /// <param name="start">The index at which to begin this slice.</param>
+ /// <exception cref="System.ArgumentOutOfRangeException">
+ /// Thrown when the specified <paramref name="start"/> index is not in range (&lt;0 or &gt;length).
+ /// </exception>
+ [MethodImpl(MethodImplOptions.NoOptimization)] // TODO-SPAN: Workaround for https://github.com/dotnet/coreclr/issues/7894
+ public ReadOnlySpan<T> Slice(int start)
+ {
+ if ((uint)start > (uint)_length)
+ ThrowHelper.ThrowArgumentOutOfRangeException();
+
+ return new ReadOnlySpan<T>(ref Unsafe.Add(ref DangerousGetPinnableReference(), start), _length - start);
+ }
+
+ /// <summary>
+ /// Forms a slice out of the given span, beginning at 'start', of given length
+ /// </summary>
+ /// <param name="start">The index at which to begin this slice.</param>
+ /// <param name="end">The index at which to end this slice (exclusive).</param>
+ /// <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.NoOptimization)] // TODO-SPAN: Workaround for https://github.com/dotnet/coreclr/issues/7894
+ public ReadOnlySpan<T> Slice(int start, int length)
+ {
+ if ((uint)start > (uint)_length || (uint)length > (uint)(_length - start))
+ ThrowHelper.ThrowArgumentOutOfRangeException();
+
+ return new ReadOnlySpan<T>(ref Unsafe.Add(ref DangerousGetPinnableReference(), start), length);
+ }
+
+ /// <summary>
+ /// Copies the contents of this read-only span into destination span. If the source
+ /// and destinations overlap, this method behaves as if the original values in
+ /// a temporary location before the destination is overwritten.
+ ///
+ /// <param name="destination">The span to copy items into.</param>
+ /// <exception cref="System.ArgumentException">
+ /// Thrown when the destination Span is shorter than the source Span.
+ /// </exception>
+ /// </summary>
+ public void CopyTo(Span<T> destination)
+ {
+ if (!TryCopyTo(destination))
+ ThrowHelper.ThrowArgumentException_DestinationTooShort();
+ }
+
+ /// <summary>
+ /// Copies the contents of this span into destination span. The destination
+ /// must be at least as big as the source, and may be bigger.
+ /// </summary>
+ /// <param name="destination">The span to copy items into.</param>
+ public bool TryCopyTo(Span<T> destination)
+ {
+ if ((uint)_length > (uint)destination.Length)
+ return false;
+
+ SpanHelper.CopyTo<T>(ref destination.DangerousGetPinnableReference(), ref DangerousGetPinnableReference(), _length);
+ return true;
+ }
+
+ /// <summary>
+ /// Returns true if left and right point at the same memory and have the same length. Note that
+ /// this does *not* check to see if the *contents* are equal.
+ /// </summary>
+ public static bool operator ==(ReadOnlySpan<T> left, ReadOnlySpan<T> right)
+ {
+ return left._length == right._length && Unsafe.AreSame<T>(ref left.DangerousGetPinnableReference(), ref right.DangerousGetPinnableReference());
+ }
+
+ /// <summary>
+ /// Returns false if left and right point at the same memory and have the same length. Note that
+ /// this does *not* check to see if the *contents* are equal.
+ /// </summary>
+ public static bool operator !=(ReadOnlySpan<T> left, ReadOnlySpan<T> right) => !(left == right);
+ }
+
+ public static class ReadOnlySpanExtensions
+ {
+ /// <summary>
+ /// Creates a new readonly span over the portion of the target string.
+ /// </summary>
+ /// <param name="text">The target string.</param>
+ /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> is a null
+ /// reference (Nothing in Visual Basic).</exception>
+ public static ReadOnlySpan<char> Slice(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>
+ 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>
+ 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);
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Reflection/Assembly.cs b/src/mscorlib/src/System/Reflection/Assembly.cs
index 479d6ca3a6..677e4aa964 100644
--- a/src/mscorlib/src/System/Reflection/Assembly.cs
+++ b/src/mscorlib/src/System/Reflection/Assembly.cs
@@ -37,7 +37,7 @@ namespace System.Reflection
using __HResults = System.__HResults;
using System.Runtime.Versioning;
using System.Diagnostics.Contracts;
-
+ using System.Runtime.Loader;
[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
@@ -48,14 +48,9 @@ namespace System.Reflection
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_Assembly))]
[System.Runtime.InteropServices.ComVisible(true)]
-#pragma warning disable 618
- [PermissionSetAttribute(SecurityAction.InheritanceDemand, Unrestricted = true)]
-#pragma warning restore 618
public abstract class Assembly : _Assembly, IEvidenceFactory, ICustomAttributeProvider, ISerializable
{
-#region constructors
protected Assembly() {}
-#endregion
#region public static methods
@@ -67,7 +62,7 @@ namespace System.Reflection
public static Assembly GetAssembly(Type type)
{
if (type == null)
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
Contract.EndContractBlock();
Module m = type.Module;
@@ -105,36 +100,15 @@ namespace System.Reflection
return base.GetHashCode();
}
- // Locate an assembly by the name of the file containing the manifest.
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static Assembly LoadFrom(String assemblyFile)
{
- Contract.Ensures(Contract.Result<Assembly>() != null);
- Contract.Ensures(!Contract.Result<Assembly>().ReflectionOnly);
-
-#if FEATURE_WINDOWSPHONE
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_WindowsPhone", "Assembly.LoadFrom"));
-#else
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
-
- return RuntimeAssembly.InternalLoadFrom(
- assemblyFile,
- null, // securityEvidence
- null, // hashValue
- AssemblyHashAlgorithm.None,
- false,// forIntrospection
- false,// suppressSecurityChecks
- ref stackMark);
-#endif // FEATURE_WINDOWSPHONE
+ 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.
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static Assembly ReflectionOnlyLoadFrom(String assemblyFile)
{
@@ -153,7 +127,6 @@ namespace System.Reflection
}
// Evidence is protected in Assembly.Load()
- [System.Security.SecuritySafeCritical] // auto-generated
[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
public static Assembly LoadFrom(String assemblyFile,
@@ -174,7 +147,6 @@ namespace System.Reflection
}
// Evidence is protected in Assembly.Load()
- [System.Security.SecuritySafeCritical] // auto-generated
[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
public static Assembly LoadFrom(String assemblyFile,
@@ -196,49 +168,21 @@ namespace System.Reflection
ref stackMark);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static Assembly LoadFrom(String assemblyFile,
byte[] hashValue,
AssemblyHashAlgorithm hashAlgorithm)
{
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
-
- return RuntimeAssembly.InternalLoadFrom(
- assemblyFile,
- null,
- hashValue,
- hashAlgorithm,
- false,
- false,
- ref stackMark);
+ throw new NotSupportedException(Environment.GetResourceString("NotSupported_AssemblyLoadFromHash"));
}
-#if FEATURE_CAS_POLICY
- // Load an assembly into the LoadFrom context bypassing some security checks
- [SecurityCritical]
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static Assembly UnsafeLoadFrom(string assemblyFile)
{
-
- Contract.Ensures(Contract.Result<Assembly>() != null);
- Contract.Ensures(!Contract.Result<Assembly>().ReflectionOnly);
-
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
-
- return RuntimeAssembly.InternalLoadFrom(assemblyFile,
- null, // securityEvidence
- null, // hashValue
- AssemblyHashAlgorithm.None,
- false, // forIntrospection
- true, // suppressSecurityChecks
- ref stackMark);
+ return LoadFrom(assemblyFile);
}
-#endif // FEATURE_CAS_POLICY
// 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.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static Assembly Load(String assemblyString)
{
@@ -253,7 +197,6 @@ namespace System.Reflection
// 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.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
internal static Type GetType_Compat(String assemblyString, String typeName)
{
@@ -283,7 +226,6 @@ namespace System.Reflection
// 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"
//
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static Assembly ReflectionOnlyLoad(String assemblyString)
{
@@ -293,7 +235,6 @@ namespace System.Reflection
return RuntimeAssembly.InternalLoad(assemblyString, null, ref stackMark, true /*forIntrospection*/);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
[Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. Please use an overload of Load which does not take an Evidence parameter. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
public static Assembly Load(String assemblyString, Evidence assemblySecurity)
@@ -307,11 +248,6 @@ namespace System.Reflection
// Locate an assembly by its name. The name can be strong or
// weak. The assembly is loaded into the domain of the caller.
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static Assembly Load(AssemblyName assemblyRef)
{
@@ -331,11 +267,6 @@ namespace System.Reflection
// Locate an assembly by its name. The name can be strong or
// weak. The assembly is loaded into the domain of the caller.
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
internal static Assembly Load(AssemblyName assemblyRef, IntPtr ptrLoadContextBinder)
{
@@ -353,7 +284,6 @@ namespace System.Reflection
return RuntimeAssembly.InternalLoadAssemblyName(assemblyRef, null, null, ref stackMark, true /*thrownOnFileNotFound*/, false /*forIntrospection*/, false /*suppressSecurityChecks*/, ptrLoadContextBinder);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
[Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. Please use an overload of Load which does not take an Evidence parameter. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
public static Assembly Load(AssemblyName assemblyRef, Evidence assemblySecurity)
@@ -365,34 +295,17 @@ namespace System.Reflection
return RuntimeAssembly.InternalLoadAssemblyName(assemblyRef, assemblySecurity, null, ref stackMark, true /*thrownOnFileNotFound*/, false /*forIntrospection*/, false /*suppressSecurityChecks*/);
}
-#if FEATURE_FUSION
- [System.Security.SecuritySafeCritical] // auto-generated
[Obsolete("This method has been deprecated. Please use Assembly.Load() instead. http://go.microsoft.com/fwlink/?linkid=14202")]
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static Assembly LoadWithPartialName(String partialName)
{
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return RuntimeAssembly.LoadWithPartialNameInternal(partialName, null, ref stackMark);
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- [Obsolete("This method has been deprecated. Please use Assembly.Load() instead. http://go.microsoft.com/fwlink/?linkid=14202")]
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public static Assembly LoadWithPartialName(String partialName, Evidence securityEvidence)
- {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return RuntimeAssembly.LoadWithPartialNameInternal(partialName, securityEvidence, ref stackMark);
+ if(partialName == null)
+ throw new ArgumentNullException(nameof(partialName));
+ return Load(partialName);
}
-#endif // FEATURE_FUSION
// Loads the assembly with a COFF based IMAGE containing
// an emitted assembly. The assembly is loaded into the domain
// of the caller.
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static Assembly Load(byte[] rawAssembly)
{
@@ -401,20 +314,12 @@ namespace System.Reflection
AppDomain.CheckLoadByteArraySupported();
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return RuntimeAssembly.nLoadImage(
- rawAssembly,
- null, // symbol store
- null, // evidence
- ref stackMark,
- false, // fIntrospection
- SecurityContextSource.CurrentAssembly);
+ 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.
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static Assembly ReflectionOnlyLoad(byte[] rawAssembly)
{
@@ -436,40 +341,30 @@ namespace System.Reflection
// 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.
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
[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();
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return RuntimeAssembly.nLoadImage(
- rawAssembly,
- rawSymbolStore,
- null, // evidence
- ref stackMark,
- false, // fIntrospection
- SecurityContextSource.CurrentAssembly);
+ 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);
}
// Load an assembly from a byte array, controlling where the grant set of this assembly is
// propigated from.
- [SecuritySafeCritical]
[MethodImpl(MethodImplOptions.NoInlining)] // Due to the stack crawl mark
public static Assembly Load(byte[] rawAssembly,
byte[] rawSymbolStore,
SecurityContextSource securityContextSource)
{
-
Contract.Ensures(Contract.Result<Assembly>() != null);
Contract.Ensures(!Contract.Result<Assembly>().ReflectionOnly);
@@ -478,7 +373,7 @@ namespace System.Reflection
if (securityContextSource < SecurityContextSource.CurrentAppDomain ||
securityContextSource > SecurityContextSource.CurrentAssembly)
{
- throw new ArgumentOutOfRangeException("securityContextSource");
+ throw new ArgumentOutOfRangeException(nameof(securityContextSource));
}
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -490,79 +385,37 @@ namespace System.Reflection
securityContextSource);
}
-#if FEATURE_CAS_POLICY
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlEvidence)]
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. Please use an overload of Load which does not take an Evidence parameter. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
- public static Assembly Load(byte[] rawAssembly,
- byte[] rawSymbolStore,
- Evidence securityEvidence)
- {
-
- Contract.Ensures(Contract.Result<Assembly>() != null);
- Contract.Ensures(!Contract.Result<Assembly>().ReflectionOnly);
-
- AppDomain.CheckLoadByteArraySupported();
+ private static Dictionary<string, Assembly> s_loadfile = new Dictionary<string, Assembly>();
- if (securityEvidence != null && !AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
- {
- // A zone of MyComputer could not have been used to sandbox, so for compatibility we do not
- // throw an exception when we see it.
- Zone zone = securityEvidence.GetHostEvidence<Zone>();
- if (zone == null || zone.SecurityZone != SecurityZone.MyComputer)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyImplicit"));
- }
- }
-
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return RuntimeAssembly.nLoadImage(
- rawAssembly,
- rawSymbolStore,
- securityEvidence,
- ref stackMark,
- false, // fIntrospection
- SecurityContextSource.CurrentAssembly);
- }
-#endif // FEATURE_CAS_POLICY
-
- [System.Security.SecuritySafeCritical] // auto-generated
public static Assembly LoadFile(String path)
{
-
Contract.Ensures(Contract.Result<Assembly>() != null);
Contract.Ensures(!Contract.Result<Assembly>().ReflectionOnly);
AppDomain.CheckLoadFileSupported();
- new FileIOPermission(FileIOPermissionAccess.PathDiscovery | FileIOPermissionAccess.Read, path).Demand();
- return RuntimeAssembly.nLoadFile(path, null);
- }
-
-#if FEATURE_CAS_POLICY
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlEvidence)]
- [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. Please use an overload of LoadFile which does not take an Evidence parameter. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
- public static Assembly LoadFile(String path,
- Evidence securityEvidence)
- {
-
- Contract.Ensures(Contract.Result<Assembly>() != null);
- Contract.Ensures(!Contract.Result<Assembly>().ReflectionOnly);
+ Assembly result = null;
+ if(path == null)
+ throw new ArgumentNullException(nameof(path));
- AppDomain.CheckLoadFileSupported();
+ if (PathInternal.IsPartiallyQualified(path))
+ {
+ throw new ArgumentException(Environment.GetResourceString("Argument_AbsolutePathRequired"), nameof(path));
+ }
- if (securityEvidence != null && !AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyImplicit"));
+ string normalizedPath = Path.GetFullPath(path);
- new FileIOPermission(FileIOPermissionAccess.PathDiscovery | FileIOPermissionAccess.Read, path).Demand();
- return RuntimeAssembly.nLoadFile(path, securityEvidence);
+ 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;
}
-#endif // FEATURE_CAS_POLICY
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static Assembly Load(Stream assemblyStream, Stream pdbStream)
{
@@ -572,8 +425,6 @@ namespace System.Reflection
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return RuntimeAssembly.InternalLoadFromStream(assemblyStream, pdbStream, ref stackMark);
}
-
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static Assembly Load(Stream assemblyStream)
{
@@ -583,12 +434,10 @@ namespace System.Reflection
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return RuntimeAssembly.InternalLoadFromStream(assemblyStream, null, ref stackMark);
}
-#endif //FEATURE_CORECLR
/*
* Get the assembly that the current code is running from.
*/
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static Assembly GetExecutingAssembly()
{
@@ -596,7 +445,6 @@ namespace System.Reflection
return RuntimeAssembly.GetExecutingAssembly(ref stackMark);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static Assembly GetCallingAssembly()
{
@@ -607,25 +455,22 @@ namespace System.Reflection
return RuntimeAssembly.GetExecutingAssembly(ref stackMark);
}
- [System.Security.SecuritySafeCritical] // auto-generated
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
{
- [System.Security.SecurityCritical] // auto-generated_required
add
{
throw new NotImplementedException();
}
- [System.Security.SecurityCritical] // auto-generated_required
remove
{
throw new NotImplementedException();
@@ -634,9 +479,6 @@ namespace System.Reflection
public virtual String CodeBase
{
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
get
{
throw new NotImplementedException();
@@ -645,24 +487,17 @@ namespace System.Reflection
public virtual String EscapedCodeBase
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
return AssemblyName.EscapeCodeBase(CodeBase);
}
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
public virtual AssemblyName GetName()
{
return GetName(false);
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
public virtual AssemblyName GetName(bool copiedName)
{
throw new NotImplementedException();
@@ -684,13 +519,6 @@ namespace System.Reflection
}
}
-#if !FEATURE_CORECLR
- Type _Assembly.GetType()
- {
- return base.GetType();
- }
-#endif
-
public virtual Type GetType(String name)
{
return GetType(name, false, false);
@@ -789,31 +617,11 @@ namespace System.Reflection
throw new NotImplementedException();
}
-#if FEATURE_CAS_POLICY
- public virtual Evidence Evidence
- {
- get
- {
- throw new NotImplementedException();
- }
- }
-
- public virtual PermissionSet PermissionSet
- {
- // SecurityCritical because permissions can contain sensitive information such as paths
- [SecurityCritical]
- get
- {
- throw new NotImplementedException();
- }
- }
-
public bool IsFullyTrusted
{
- [SecuritySafeCritical]
get
{
- return PermissionSet.IsUnrestricted();
+ return true;
}
}
@@ -821,14 +629,11 @@ namespace System.Reflection
{
get
{
- throw new NotImplementedException();
+ return SecurityRuleSet.None;
}
}
-#endif // FEATURE_CAS_POLICY
-
// ISerializable implementation
- [System.Security.SecurityCritical] // auto-generated_required
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
throw new NotImplementedException();
@@ -890,8 +695,6 @@ namespace System.Reflection
}
}
-#if FEATURE_MULTIMODULE_ASSEMBLIES
-
public Module LoadModule(String moduleName,
byte[] rawModule)
{
@@ -904,7 +707,6 @@ namespace System.Reflection
{
throw new NotImplementedException();
}
-#endif //FEATURE_MULTIMODULE_ASSEMBLIES
//
// Locates a type from this assembly and creates an instance of it using
@@ -986,9 +788,6 @@ namespace System.Reflection
// Returns the file in the File table of the manifest that matches the
// given name. (Name should not include path.)
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
public virtual FileStream GetFile(String name)
{
throw new NotImplementedException();
@@ -999,9 +798,6 @@ namespace System.Reflection
return GetFiles(false);
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
public virtual FileStream[] GetFiles(bool getResourceModules)
{
throw new NotImplementedException();
@@ -1034,9 +830,6 @@ namespace System.Reflection
public virtual String Location
{
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
get
{
throw new NotImplementedException();
@@ -1103,27 +896,7 @@ namespace System.Reflection
[Serializable]
internal class RuntimeAssembly : Assembly
-#if !FEATURE_CORECLR
- , ICustomQueryInterface
-#endif
{
-#if !FEATURE_CORECLR
-#region ICustomQueryInterface
- [System.Security.SecurityCritical]
- CustomQueryInterfaceResult ICustomQueryInterface.GetInterface([In]ref Guid iid, out IntPtr ppv)
- {
- if (iid == typeof(NativeMethods.IDispatch).GUID)
- {
- ppv = Marshal.GetComInterfaceForObject(this, typeof(_Assembly));
- return CustomQueryInterfaceResult.Handled;
- }
-
- ppv = IntPtr.Zero;
- return CustomQueryInterfaceResult.NotHandled;
- }
-#endregion
-#endif // !FEATURE_CORECLR
-
#if FEATURE_APPX
// The highest byte is the flags and the lowest 3 bytes are
// the cached ctor token of [DynamicallyInvocableAttribute].
@@ -1166,54 +939,12 @@ namespace System.Reflection
private ASSEMBLY_FLAGS Flags
{
- [SecuritySafeCritical]
get
{
if ((m_flags & ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_INITIALIZED) == 0)
{
- ASSEMBLY_FLAGS flags = ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_UNKNOWN;
-
-#if FEATURE_CORECLR
- flags |= ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_FRAMEWORK | ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_SAFE_REFLECTION;
-#else
- if (RuntimeAssembly.IsFrameworkAssembly(GetName()))
- {
- flags |= ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_FRAMEWORK | ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_SAFE_REFLECTION;
-
- foreach (string name in s_unsafeFrameworkAssemblyNames)
- {
- if (String.Compare(GetSimpleName(), name, StringComparison.OrdinalIgnoreCase) == 0)
- {
- flags &= ~ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_SAFE_REFLECTION;
- break;
- }
- }
-
- // Each blessed API will be annotated with a "__DynamicallyInvokableAttribute".
- // This "__DynamicallyInvokableAttribute" is a type defined in its own assembly.
- // So the ctor is always a MethodDef and the type a TypeDef.
- // We cache this ctor MethodDef token for faster custom attribute lookup.
- // If this attribute type doesn't exist in the assembly, it means the assembly
- // doesn't contain any blessed APIs.
- Type invocableAttribute = GetType("__DynamicallyInvokableAttribute", false);
- if (invocableAttribute != null)
- {
- Contract.Assert(((MetadataToken)invocableAttribute.MetadataToken).IsTypeDef);
-
- ConstructorInfo ctor = invocableAttribute.GetConstructor(Type.EmptyTypes);
- Contract.Assert(ctor != null);
-
- int token = ctor.MetadataToken;
- Contract.Assert(((MetadataToken)token).IsMethodDef);
-
- flags |= (ASSEMBLY_FLAGS)token & ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_TOKEN_MASK;
- }
- }
- else if (IsDesignerBindingContext())
- {
- flags = ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_SAFE_REFLECTION;
- }
-#endif
+ 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;
}
@@ -1221,7 +952,7 @@ namespace System.Reflection
return m_flags;
}
}
-#endif // FEATURE_CORECLR
+#endif // FEATURE_APPX
internal object SyncRoot
{
@@ -1237,12 +968,10 @@ namespace System.Reflection
public override event ModuleResolveEventHandler ModuleResolve
{
- [System.Security.SecurityCritical] // auto-generated_required
add
{
_ModuleResolve += value;
}
- [System.Security.SecurityCritical] // auto-generated_required
remove
{
_ModuleResolve -= value;
@@ -1251,14 +980,12 @@ namespace System.Reflection
private const String s_localFilePrefix = "file:";
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void GetCodeBase(RuntimeAssembly assembly,
bool copiedName,
StringHandleOnStack retString);
- [System.Security.SecurityCritical] // auto-generated
internal String GetCodeBase(bool copiedName)
{
String codeBase = null;
@@ -1268,11 +995,6 @@ namespace System.Reflection
public override String CodeBase
{
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
get {
String codeBase = GetCodeBase(false);
VerifyCodeBaseDiscovery(codeBase);
@@ -1288,11 +1010,6 @@ namespace System.Reflection
// 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.
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
public override AssemblyName GetName(bool copiedName)
{
AssemblyName an = new AssemblyName();
@@ -1326,27 +1043,12 @@ namespace System.Reflection
return an;
}
-#if FEATURE_APTCA
- // This method is called from the VM when creating conditional APTCA exceptions, in order to include
- // the text which must be added to the partial trust visible assembly list
- [SecurityCritical]
- [PermissionSet(SecurityAction.Assert, Unrestricted = true)]
- private string GetNameForConditionalAptca()
- {
- AssemblyName assemblyName = GetName();
- return assemblyName.GetNameWithPublicKey();
-
- }
-#endif // FEATURE_APTCA
-
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void GetFullName(RuntimeAssembly assembly, StringHandleOnStack retString);
public override String FullName
{
- [System.Security.SecuritySafeCritical] // auto-generated
get {
// If called by Object.ToString(), return val may be NULL.
if (m_fullname == null)
@@ -1360,14 +1062,12 @@ namespace System.Reflection
}
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void GetEntryPoint(RuntimeAssembly assembly, ObjectHandleOnStack retMethod);
public override MethodInfo EntryPoint
{
- [System.Security.SecuritySafeCritical] // auto-generated
get {
IRuntimeMethodInfo methodHandle = null;
GetEntryPoint(GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref methodHandle));
@@ -1379,7 +1079,6 @@ namespace System.Reflection
}
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void GetType(RuntimeAssembly assembly,
@@ -1389,12 +1088,11 @@ namespace System.Reflection
ObjectHandleOnStack type,
ObjectHandleOnStack keepAlive);
- [System.Security.SecuritySafeCritical]
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("name");
+ throw new ArgumentNullException(nameof(name));
RuntimeType type = null;
Object keepAlive = null;
@@ -1404,17 +1102,14 @@ namespace System.Reflection
return type;
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal extern static void GetForwardedTypes(RuntimeAssembly assembly, ObjectHandleOnStack retTypes);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void GetExportedTypes(RuntimeAssembly assembly, ObjectHandleOnStack retTypes);
- [System.Security.SecuritySafeCritical] // auto-generated
public override Type[] GetExportedTypes()
{
Type[] types = null;
@@ -1424,7 +1119,6 @@ namespace System.Reflection
public override IEnumerable<TypeInfo> DefinedTypes
{
- [System.Security.SecuritySafeCritical]
get
{
List<RuntimeType> rtTypes = new List<RuntimeType>();
@@ -1441,7 +1135,6 @@ namespace System.Reflection
}
// Load a resource based on the NameSpace of the type.
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public override Stream GetManifestResourceStream(Type type, String name)
{
@@ -1449,7 +1142,6 @@ namespace System.Reflection
return GetManifestResourceStream(type, name, false, ref stackMark);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public override Stream GetManifestResourceStream(String name)
{
@@ -1457,76 +1149,11 @@ namespace System.Reflection
return GetManifestResourceStream(name, ref stackMark, false);
}
-#if FEATURE_CAS_POLICY
- [System.Security.SecurityCritical] // auto-generated
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private extern static void GetEvidence(RuntimeAssembly assembly, ObjectHandleOnStack retEvidence);
-
- [SecurityCritical]
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private extern static SecurityRuleSet GetSecurityRuleSet(RuntimeAssembly assembly);
-
- public override Evidence Evidence
- {
- [SecuritySafeCritical]
- [SecurityPermissionAttribute( SecurityAction.Demand, ControlEvidence = true )]
- get
- {
- Evidence evidence = EvidenceNoDemand;
- return evidence.Clone();
- }
- }
-
- internal Evidence EvidenceNoDemand
- {
- [SecurityCritical]
- get
- {
- Evidence evidence = null;
- GetEvidence(GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref evidence));
- return evidence;
- }
- }
-
- public override PermissionSet PermissionSet
- {
- [SecurityCritical]
- get
- {
- PermissionSet grantSet = null;
- PermissionSet deniedSet = null;
-
- GetGrantSet(out grantSet, out deniedSet);
-
- if (grantSet != null)
- {
- return grantSet.Copy();
- }
- else
- {
- return new PermissionSet(PermissionState.Unrestricted);
- }
- }
- }
-
- public override SecurityRuleSet SecurityRuleSet
- {
- [SecuritySafeCritical]
- get
- {
- return GetSecurityRuleSet(GetNativeHandle());
- }
- }
-#endif // FEATURE_CAS_POLICY
-
// ISerializable implementation
- [System.Security.SecurityCritical] // auto-generated_required
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info==null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
@@ -1550,17 +1177,17 @@ namespace System.Reflection
{
return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType);
}
-
+
public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
{
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
Contract.EndContractBlock();
RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
}
@@ -1568,13 +1195,13 @@ namespace System.Reflection
public override bool IsDefined(Type attributeType, bool inherit)
{
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
Contract.EndContractBlock();
RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"caType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
return CustomAttribute.IsDefined(this, attributeRuntimeType);
}
@@ -1583,8 +1210,7 @@ namespace System.Reflection
{
return CustomAttributeData.GetCustomAttributesInternal(this);
}
-
- [System.Security.SecurityCritical] // auto-generated
+
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
internal static RuntimeAssembly InternalLoadFrom(String assemblyFile,
Evidence securityEvidence,
@@ -1595,16 +1221,10 @@ namespace System.Reflection
ref StackCrawlMark stackMark)
{
if (assemblyFile == null)
- throw new ArgumentNullException("assemblyFile");
+ throw new ArgumentNullException(nameof(assemblyFile));
Contract.EndContractBlock();
-#if FEATURE_CAS_POLICY
- if (securityEvidence != null && !AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyImplicit"));
- }
-#endif // FEATURE_CAS_POLICY
AssemblyName an = new AssemblyName();
an.CodeBase = assemblyFile;
an.SetHashControl(hashValue, hashAlgorithm);
@@ -1613,7 +1233,6 @@ namespace System.Reflection
}
// Wrapper function to wrap the typical use of InternalLoad.
- [System.Security.SecurityCritical] // auto-generated
internal static RuntimeAssembly InternalLoad(String assemblyString,
Evidence assemblySecurity,
ref StackCrawlMark stackMark,
@@ -1622,7 +1241,6 @@ namespace System.Reflection
return InternalLoad(assemblyString, assemblySecurity, ref stackMark, IntPtr.Zero, forIntrospection);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
internal static RuntimeAssembly InternalLoad(String assemblyString,
Evidence assemblySecurity,
@@ -1644,14 +1262,13 @@ namespace System.Reflection
}
// Creates AssemblyName. Fills assembly if AssemblyResolve event has been raised.
- [System.Security.SecurityCritical] // auto-generated
internal static AssemblyName CreateAssemblyName(
String assemblyString,
bool forIntrospection,
out RuntimeAssembly assemblyFromResolveEvent)
{
if (assemblyString == null)
- throw new ArgumentNullException("assemblyString");
+ throw new ArgumentNullException(nameof(assemblyString));
Contract.EndContractBlock();
if ((assemblyString.Length == 0) ||
@@ -1670,7 +1287,6 @@ namespace System.Reflection
}
// Wrapper function to wrap the typical use of InternalLoadAssemblyName.
- [System.Security.SecurityCritical] // auto-generated
internal static RuntimeAssembly InternalLoadAssemblyName(
AssemblyName assemblyRef,
Evidence assemblySecurity,
@@ -1684,7 +1300,6 @@ namespace System.Reflection
return InternalLoadAssemblyName(assemblyRef, assemblySecurity, reqAssembly, ref stackMark, IntPtr.Zero, true /*throwOnError*/, forIntrospection, suppressSecurityChecks, ptrLoadContextBinder);
}
- [System.Security.SecurityCritical] // auto-generated
internal static RuntimeAssembly InternalLoadAssemblyName(
AssemblyName assemblyRef,
Evidence assemblySecurity,
@@ -1698,7 +1313,7 @@ namespace System.Reflection
{
if (assemblyRef == null)
- throw new ArgumentNullException("assemblyRef");
+ throw new ArgumentNullException(nameof(assemblyRef));
Contract.EndContractBlock();
if (assemblyRef.CodeBase != null)
@@ -1717,13 +1332,6 @@ namespace System.Reflection
if (assemblySecurity != null)
{
-#if FEATURE_CAS_POLICY
- if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyImplicit"));
- }
-#endif // FEATURE_CAS_POLICY
-
if (!suppressSecurityChecks)
{
#pragma warning disable 618
@@ -1732,22 +1340,19 @@ namespace System.Reflection
}
}
-
String codeBase = VerifyCodeBase(assemblyRef.CodeBase);
- if (codeBase != null && !suppressSecurityChecks) {
-
- if (String.Compare( codeBase, 0, s_localFilePrefix, 0, 5, StringComparison.OrdinalIgnoreCase) != 0) {
-#if FEATURE_FUSION // Of all the binders, Fusion is the only one that understands Web locations
- IPermission perm = CreateWebPermission( assemblyRef.EscapedCodeBase );
- perm.Demand();
-#else
+ if (codeBase != null && !suppressSecurityChecks)
+ {
+ if (String.Compare( codeBase, 0, s_localFilePrefix, 0, 5, StringComparison.OrdinalIgnoreCase) != 0)
+ {
+ // Of all the binders, Fusion is the only one that understands Web locations
throw new ArgumentException(Environment.GetResourceString("Arg_InvalidFileName"), "assemblyRef.CodeBase");
-#endif
}
- else {
+ else
+ {
System.Security.Util.URLString urlString = new System.Security.Util.URLString( codeBase, true );
new FileIOPermission( FileIOPermissionAccess.PathDiscovery | FileIOPermissionAccess.Read , urlString.GetFileName() ).Demand();
- }
+ }
}
return nLoad(assemblyRef, codeBase, assemblySecurity, reqAssembly, ref stackMark,
@@ -1765,7 +1370,6 @@ namespace System.Reflection
};
#if FEATURE_APPX
- [System.Security.SecuritySafeCritical]
internal bool IsFrameworkAssembly()
{
ASSEMBLY_FLAGS flags = Flags;
@@ -1780,43 +1384,28 @@ namespace System.Reflection
return (flags & ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_SAFE_REFLECTION) != 0;
}
- [System.Security.SecuritySafeCritical]
private bool IsDesignerBindingContext()
{
return RuntimeAssembly.nIsDesignerBindingContext(this);
}
- [System.Security.SecurityCritical]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static bool nIsDesignerBindingContext(RuntimeAssembly assembly);
#endif
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern RuntimeAssembly _nLoad(AssemblyName fileName,
String codeBase,
Evidence assemblySecurity,
RuntimeAssembly locationHint,
- ref StackCrawlMark stackMark,
+ ref StackCrawlMark stackMark,
IntPtr pPrivHostBinder,
- bool throwOnFileNotFound,
+ bool throwOnFileNotFound,
bool forIntrospection,
bool suppressSecurityChecks,
IntPtr ptrLoadContextBinder);
-#if !FEATURE_CORECLR
- // The NGEN task uses this method, so please do not modify its signature
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern bool IsFrameworkAssembly(AssemblyName assemblyName);
-
- [System.Security.SecurityCritical]
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern bool IsNewPortableAssembly(AssemblyName assemblyName);
-#endif
-
- [System.Security.SecurityCritical] // auto-generated
private static RuntimeAssembly nLoad(AssemblyName fileName,
String codeBase,
Evidence assemblySecurity,
@@ -1832,177 +1421,6 @@ namespace System.Reflection
throwOnFileNotFound, forIntrospection, suppressSecurityChecks, ptrLoadContextBinder);
}
-#if FEATURE_FUSION
- // used by vm
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- private static unsafe RuntimeAssembly LoadWithPartialNameHack(String partialName, bool cropPublicKey)
- {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
-
- AssemblyName an = new AssemblyName(partialName);
-
- if (!IsSimplyNamed(an))
- {
- if (cropPublicKey)
- {
- an.SetPublicKey(null);
- an.SetPublicKeyToken(null);
- }
-
- if(IsFrameworkAssembly(an) || !AppDomain.IsAppXModel())
- {
- AssemblyName GACAssembly = EnumerateCache(an);
- if(GACAssembly != null)
- return InternalLoadAssemblyName(GACAssembly, null, null,ref stackMark, true /*thrownOnFileNotFound*/, false, false);
- else
- return null;
- }
- }
-
- if (AppDomain.IsAppXModel())
- {
- // also try versionless bind from the package
- an.Version = null;
- return nLoad(an, null, null, null, ref stackMark,
- IntPtr.Zero,
- false, false, false);
- }
- return null;
-
- }
-
-#if !FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- internal static RuntimeAssembly LoadWithPartialNameInternal(String partialName, Evidence securityEvidence, ref StackCrawlMark stackMark)
- {
- AssemblyName an = new AssemblyName(partialName);
- return LoadWithPartialNameInternal(an, securityEvidence, ref stackMark);
- }
-
- [System.Security.SecurityCritical] // auto-generated
- internal static RuntimeAssembly LoadWithPartialNameInternal(AssemblyName an, Evidence securityEvidence, ref StackCrawlMark stackMark)
- {
- if (securityEvidence != null)
- {
-#if FEATURE_CAS_POLICY
- if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyImplicit"));
- }
-#endif // FEATURE_CAS_POLICY
- new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand();
- }
-
- AppDomain.CheckLoadWithPartialNameSupported(stackMark);
-
- RuntimeAssembly result = null;
- try {
- result = nLoad(an, null, securityEvidence, null, ref stackMark,
- IntPtr.Zero,
- true, false, false);
- }
- catch(Exception e) {
- if (e.IsTransient)
- throw e;
-
- if (IsUserError(e))
- throw;
-
-
- if(IsFrameworkAssembly(an) || !AppDomain.IsAppXModel())
- {
- if (IsSimplyNamed(an))
- return null;
-
- AssemblyName GACAssembly = EnumerateCache(an);
- if(GACAssembly != null)
- result = InternalLoadAssemblyName(GACAssembly, securityEvidence, null, ref stackMark, true /*thrownOnFileNotFound*/, false, false);
- }
- else
- {
- an.Version = null;
- result = nLoad(an, null, securityEvidence, null, ref stackMark,
- IntPtr.Zero,
- false, false, false);
- }
- }
-
-
- return result;
- }
-#endif // !FEATURE_CORECLR
-
- [SecuritySafeCritical]
- private static bool IsUserError(Exception e)
- {
- return (uint)e.HResult == COR_E_LOADING_REFERENCE_ASSEMBLY;
- }
-
- private static bool IsSimplyNamed(AssemblyName partialName)
- {
- byte[] pk = partialName.GetPublicKeyToken();
- if ((pk != null) &&
- (pk.Length == 0))
- return true;
-
- pk = partialName.GetPublicKey();
- if ((pk != null) &&
- (pk.Length == 0))
- return true;
-
- return false;
- }
-
- [System.Security.SecurityCritical] // auto-generated
- private static AssemblyName EnumerateCache(AssemblyName partialName)
- {
- new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
-
- partialName.Version = null;
-
- ArrayList a = new ArrayList();
- Fusion.ReadCache(a, partialName.FullName, ASM_CACHE.GAC);
-
- IEnumerator myEnum = a.GetEnumerator();
- AssemblyName ainfoBest = null;
- CultureInfo refCI = partialName.CultureInfo;
-
- while (myEnum.MoveNext()) {
- AssemblyName ainfo = new AssemblyName((String)myEnum.Current);
-
- if (CulturesEqual(refCI, ainfo.CultureInfo)) {
- if (ainfoBest == null)
- ainfoBest = ainfo;
- else {
- // Choose highest version
- if (ainfo.Version > ainfoBest.Version)
- ainfoBest = ainfo;
- }
- }
- }
-
- return ainfoBest;
- }
-
- private static bool CulturesEqual(CultureInfo refCI, CultureInfo defCI)
- {
- bool defNoCulture = defCI.Equals(CultureInfo.InvariantCulture);
-
- // cultured asms aren't allowed to be bound to if
- // the ref doesn't ask for them specifically
- if ((refCI == null) || refCI.Equals(CultureInfo.InvariantCulture))
- return defNoCulture;
-
- if (defNoCulture ||
- ( !defCI.Equals(refCI) ))
- return false;
-
- return true;
- }
-#endif // FEATURE_FUSION
-
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool IsReflectionOnly(RuntimeAssembly assembly);
@@ -2011,23 +1429,20 @@ namespace System.Reflection
[ComVisible(false)]
public override bool ReflectionOnly
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
return IsReflectionOnly(GetNativeHandle());
}
}
-#if FEATURE_CORECLR
// Loads the assembly with a COFF based IMAGE containing
// an emitted assembly. The assembly is loaded into the domain
// of the caller. Currently is implemented only for UnmanagedMemoryStream
// (no derived classes since we are not calling Read())
- [System.Security.SecurityCritical] // auto-generated
internal static RuntimeAssembly InternalLoadFromStream(Stream assemblyStream, Stream pdbStream, ref StackCrawlMark stackMark)
{
if (assemblyStream == null)
- throw new ArgumentNullException("assemblyStream");
+ throw new ArgumentNullException(nameof(assemblyStream));
if (assemblyStream.GetType()!=typeof(UnmanagedMemoryStream))
throw new NotSupportedException();
@@ -2070,44 +1485,13 @@ namespace System.Reflection
return assembly;
}
}
-#endif //FEATURE_CORECLR
-
-#if FEATURE_MULTIMODULE_ASSEMBLIES
- [System.Security.SecurityCritical] // auto-generated
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private extern static void LoadModule(RuntimeAssembly assembly,
- String moduleName,
- byte[] rawModule, int cbModule,
- byte[] rawSymbolStore, int cbSymbolStore,
- ObjectHandleOnStack retModule);
-
- [SecurityPermissionAttribute(SecurityAction.Demand, ControlEvidence = true)]
- [System.Security.SecuritySafeCritical] // auto-generated
- public override Module LoadModule(String moduleName, byte[] rawModule, byte[] rawSymbolStore)
- {
- RuntimeModule retModule = null;
- LoadModule(
- GetNativeHandle(),
- moduleName,
- rawModule,
- (rawModule != null) ? rawModule.Length : 0,
- rawSymbolStore,
- (rawSymbolStore != null) ? rawSymbolStore.Length : 0,
- JitHelpers.GetObjectHandleOnStack(ref retModule));
-
- return retModule;
- }
-#endif //FEATURE_MULTIMODULE_ASSEMBLIES
// Returns the module in this assembly with name 'name'
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void GetModule(RuntimeAssembly assembly, String name, ObjectHandleOnStack retModule);
- [System.Security.SecuritySafeCritical] // auto-generated
public override Module GetModule(String name)
{
Module retModule = null;
@@ -2117,11 +1501,6 @@ namespace System.Reflection
// Returns the file in the File table of the manifest that matches the
// given name. (Name should not include path.)
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
public override FileStream GetFile(String name)
{
RuntimeModule m = (RuntimeModule)GetModule(name);
@@ -2133,11 +1512,6 @@ namespace System.Reflection
FileAccess.Read, FileShare.Read, FileStream.DefaultBufferSize, false);
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
public override FileStream[] GetFiles(bool getResourceModules)
{
Module[] m = GetModules(getResourceModules);
@@ -2152,26 +1526,20 @@ namespace System.Reflection
return fs;
}
-
// Returns the names of all the resources
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern String[] GetManifestResourceNames(RuntimeAssembly assembly);
// Returns the names of all the resources
- [System.Security.SecuritySafeCritical] // auto-generated
public override String[] GetManifestResourceNames()
{
return GetManifestResourceNames(GetNativeHandle());
}
-
-
- [System.Security.SecurityCritical] // auto-generated
+
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void GetExecutingAssembly(StackCrawlMarkHandle stackMark, ObjectHandleOnStack retAssembly);
- [System.Security.SecurityCritical] // auto-generated
internal static RuntimeAssembly GetExecutingAssembly(ref StackCrawlMark stackMark)
{
RuntimeAssembly retAssembly = null;
@@ -2180,17 +1548,14 @@ namespace System.Reflection
}
// Returns the names of all the resources
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern AssemblyName[] GetReferencedAssemblies(RuntimeAssembly assembly);
- [System.Security.SecuritySafeCritical] // auto-generated
public override AssemblyName[] GetReferencedAssemblies()
{
return GetReferencedAssemblies(GetNativeHandle());
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern int GetManifestResourceInfo(RuntimeAssembly assembly,
@@ -2199,7 +1564,6 @@ namespace System.Reflection
StringHandleOnStack retFileName,
StackCrawlMarkHandle stackMark);
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public override ManifestResourceInfo GetManifestResourceInfo(String resourceName)
{
@@ -2218,18 +1582,12 @@ namespace System.Reflection
(ResourceLocation) location);
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void GetLocation(RuntimeAssembly assembly, StringHandleOnStack retString);
public override String Location
{
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
get {
String location = null;
@@ -2242,7 +1600,6 @@ namespace System.Reflection
}
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void GetImageRuntimeVersion(RuntimeAssembly assembly, StringHandleOnStack retString);
@@ -2252,7 +1609,6 @@ namespace System.Reflection
[ComVisible(false)]
public override String ImageRuntimeVersion
{
- [System.Security.SecuritySafeCritical] // auto-generated
get{
String s = null;
GetImageRuntimeVersion(GetNativeHandle(), JitHelpers.GetStringHandleOnStack(ref s));
@@ -2261,30 +1617,26 @@ namespace System.Reflection
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern static bool IsGlobalAssemblyCache(RuntimeAssembly assembly);
public override bool GlobalAssemblyCache
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
- return IsGlobalAssemblyCache(GetNativeHandle());
+ return false;
}
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static Int64 GetHostContext(RuntimeAssembly assembly);
public override Int64 HostContext
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
- return GetHostContext(GetNativeHandle());
+ return 0;
}
}
@@ -2309,14 +1661,13 @@ namespace System.Reflection
else if ((len > 2) && (codebase[0] == '\\') && (codebase[1] == '\\'))
return "file://" + codebase;
else
- return "file:///" + Path.GetFullPathInternal( codebase );
+ return "file:///" + Path.GetFullPath(codebase);
#else
else
- return "file://" + Path.GetFullPathInternal( codebase );
+ return "file://" + Path.GetFullPath(codebase);
#endif // !PLATFORM_UNIX
}
- [System.Security.SecurityCritical] // auto-generated
internal Stream GetManifestResourceStream(
Type type,
String name,
@@ -2326,7 +1677,7 @@ namespace System.Reflection
StringBuilder sb = new StringBuilder();
if(type == null) {
if (name == null)
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
}
else {
String nameSpace = type.Namespace;
@@ -2339,25 +1690,11 @@ namespace System.Reflection
if(name != null)
sb.Append(name);
-
- return GetManifestResourceStream(sb.ToString(), ref stackMark, skipSecurityCheck);
- }
-#if FEATURE_CAS_POLICY
- internal bool IsStrongNameVerified
- {
- [System.Security.SecurityCritical] // auto-generated
- get { return GetIsStrongNameVerified(GetNativeHandle()); }
+ return GetManifestResourceStream(sb.ToString(), ref stackMark, skipSecurityCheck);
}
- [System.Security.SecurityCritical] // auto-generated
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private static extern bool GetIsStrongNameVerified(RuntimeAssembly assembly);
-#endif // FEATURE_CAS_POLICY
-
// GetResource will return a pointer to the resources in memory.
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static unsafe extern byte* GetResource(RuntimeAssembly assembly,
@@ -2366,7 +1703,6 @@ namespace System.Reflection
StackCrawlMarkHandle stackMark,
bool skipSecurityCheck);
- [System.Security.SecurityCritical] // auto-generated
internal unsafe Stream GetManifestResourceStream(String name, ref StackCrawlMark stackMark, bool skipSecurityCheck)
{
ulong length = 0;
@@ -2384,7 +1720,6 @@ namespace System.Reflection
return null;
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void GetVersion(RuntimeAssembly assembly,
@@ -2393,7 +1728,6 @@ namespace System.Reflection
out int buildNum,
out int revNum);
- [System.Security.SecurityCritical] // auto-generated
internal Version GetVersion()
{
int majorVer, minorVer, build, revision;
@@ -2401,12 +1735,10 @@ namespace System.Reflection
return new Version (majorVer, minorVer, build, revision);
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void GetLocale(RuntimeAssembly assembly, StringHandleOnStack retString);
- [System.Security.SecurityCritical] // auto-generated
internal CultureInfo GetLocale()
{
String locale = null;
@@ -2419,27 +1751,18 @@ namespace System.Reflection
return new CultureInfo(locale);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool FCallIsDynamic(RuntimeAssembly assembly);
public override bool IsDynamic
{
- [SecuritySafeCritical]
get {
return FCallIsDynamic(GetNativeHandle());
}
}
- [System.Security.SecurityCritical] // auto-generated
private void VerifyCodeBaseDiscovery(String codeBase)
{
-#if FEATURE_CAS_POLICY
- if (CodeAccessSecurityEngine.QuickCheckForAllDemands()) {
- return;
- }
-#endif // FEATURE_CAS_POLICY
-
if ((codeBase != null) &&
(String.Compare( codeBase, 0, s_localFilePrefix, 0, 5, StringComparison.OrdinalIgnoreCase) == 0)) {
System.Security.Util.URLString urlString = new System.Security.Util.URLString( codeBase, true );
@@ -2447,12 +1770,10 @@ namespace System.Reflection
}
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void GetSimpleName(RuntimeAssembly assembly, StringHandleOnStack retSimpleName);
- [SecuritySafeCritical]
internal String GetSimpleName()
{
string name = null;
@@ -2460,35 +1781,29 @@ namespace System.Reflection
return name;
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static AssemblyHashAlgorithm GetHashAlgorithm(RuntimeAssembly assembly);
- [System.Security.SecurityCritical] // auto-generated
private AssemblyHashAlgorithm GetHashAlgorithm()
{
return GetHashAlgorithm(GetNativeHandle());
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static AssemblyNameFlags GetFlags(RuntimeAssembly assembly);
- [System.Security.SecurityCritical] // auto-generated
private AssemblyNameFlags GetFlags()
{
return GetFlags(GetNativeHandle());
}
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SecurityCritical]
[SuppressUnmanagedCodeSecurity]
private static extern void GetRawBytes(RuntimeAssembly assembly, ObjectHandleOnStack retRawBytes);
// Get the raw bytes of the assembly
- [SecuritySafeCritical]
internal byte[] GetRawBytes()
{
byte[] rawBytes = null;
@@ -2497,12 +1812,10 @@ namespace System.Reflection
return rawBytes;
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void GetPublicKey(RuntimeAssembly assembly, ObjectHandleOnStack retPublicKey);
- [System.Security.SecurityCritical] // auto-generated
internal byte[] GetPublicKey()
{
byte[] publicKey = null;
@@ -2510,12 +1823,10 @@ namespace System.Reflection
return publicKey;
}
- [SecurityCritical]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void GetGrantSet(RuntimeAssembly assembly, ObjectHandleOnStack granted, ObjectHandleOnStack denied);
- [SecurityCritical]
internal void GetGrantSet(out PermissionSet newGrant, out PermissionSet newDenied)
{
PermissionSet granted = null, denied = null;
@@ -2523,134 +1834,51 @@ namespace System.Reflection
newGrant = granted; newDenied = denied;
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private extern static bool IsAllSecurityCritical(RuntimeAssembly assembly);
// Is everything introduced by this assembly critical
- [System.Security.SecuritySafeCritical] // auto-generated
internal bool IsAllSecurityCritical()
{
return IsAllSecurityCritical(GetNativeHandle());
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private extern static bool IsAllSecuritySafeCritical(RuntimeAssembly assembly);
// Is everything introduced by this assembly safe critical
- [System.Security.SecuritySafeCritical] // auto-generated
internal bool IsAllSecuritySafeCritical()
{
return IsAllSecuritySafeCritical(GetNativeHandle());
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private extern static bool IsAllPublicAreaSecuritySafeCritical(RuntimeAssembly assembly);
// Is everything introduced by this assembly safe critical
- [System.Security.SecuritySafeCritical] // auto-generated
internal bool IsAllPublicAreaSecuritySafeCritical()
{
return IsAllPublicAreaSecuritySafeCritical(GetNativeHandle());
}
- [System.Security.SecurityCritical] // auto-generated
[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
- [System.Security.SecuritySafeCritical] // auto-generated
internal bool IsAllSecurityTransparent()
{
return IsAllSecurityTransparent(GetNativeHandle());
}
-#if FEATURE_FUSION
- // demandFlag:
- // 0 demand PathDiscovery permission only
- // 1 demand Read permission only
- // 2 demand both Read and PathDiscovery
- // 3 demand Web permission only
- [System.Security.SecurityCritical] // auto-generated
- private static void DemandPermission(String codeBase, bool havePath,
- int demandFlag)
- {
- FileIOPermissionAccess access = FileIOPermissionAccess.PathDiscovery;
- switch(demandFlag) {
-
- case 0: // default
- break;
- case 1:
- access = FileIOPermissionAccess.Read;
- break;
- case 2:
- access = FileIOPermissionAccess.PathDiscovery | FileIOPermissionAccess.Read;
- break;
-
- case 3:
- IPermission perm = CreateWebPermission(AssemblyName.EscapeCodeBase(codeBase));
- perm.Demand();
- return;
- }
-
- if (!havePath) {
- System.Security.Util.URLString urlString = new System.Security.Util.URLString( codeBase, true );
- codeBase = urlString.GetFileName();
- }
-
- codeBase = Path.GetFullPathInternal(codeBase); // canonicalize
-
- new FileIOPermission(access, codeBase).Demand();
- }
-#endif
-
-#if FEATURE_FUSION
- private static IPermission CreateWebPermission( String codeBase )
- {
- Contract.Assert( codeBase != null, "Must pass in a valid CodeBase" );
- Assembly sys = Assembly.Load("System, Version=" + ThisAssembly.Version + ", Culture=neutral, PublicKeyToken=" + AssemblyRef.EcmaPublicKeyToken);
-
- Type type = sys.GetType("System.Net.NetworkAccess", true);
-
- IPermission retval = null;
- if (!type.IsEnum || !type.IsVisible)
- goto Exit;
-
- Object[] webArgs = new Object[2];
- webArgs[0] = (Enum) Enum.Parse(type, "Connect", true);
- if (webArgs[0] == null)
- goto Exit;
-
- webArgs[1] = codeBase;
-
- type = sys.GetType("System.Net.WebPermission", true);
-
- if (!type.IsVisible)
- goto Exit;
-
- retval = (IPermission) Activator.CreateInstance(type, webArgs);
-
- Exit:
- if (retval == null) {
- Contract.Assert( false, "Unable to create WebPermission" );
- throw new InvalidOperationException();
- }
-
- return retval;
- }
-#endif
// This method is called by the VM.
- [System.Security.SecurityCritical]
private RuntimeModule OnModuleResolveEvent(String moduleName)
{
ModuleResolveEventHandler moduleResolve = _ModuleResolve;
@@ -2683,14 +1911,13 @@ namespace System.Reflection
return InternalGetSatelliteAssembly(culture, version, ref stackMark);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[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("culture");
+ throw new ArgumentNullException(nameof(culture));
Contract.EndContractBlock();
@@ -2698,15 +1925,6 @@ namespace System.Reflection
return InternalGetSatelliteAssembly(name, culture, version, true, ref stackMark);
}
-#if !FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- [return: MarshalAs(UnmanagedType.Bool)]
- private static extern bool UseRelativeBindForSatellites();
-#endif
-
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
internal RuntimeAssembly InternalGetSatelliteAssembly(String name,
CultureInfo culture,
@@ -2728,104 +1946,9 @@ namespace System.Reflection
an.CultureInfo = culture;
an.Name = name;
- RuntimeAssembly retAssembly = null;
-
-#if !FEATURE_CORECLR
- bool bIsAppXDevMode = AppDomain.IsAppXDesignMode();
-
- bool useRelativeBind = false;
- if (CodeAccessSecurityEngine.QuickCheckForAllDemands())
- {
- if (IsFrameworkAssembly())
- useRelativeBind = true;
- else
- useRelativeBind = UseRelativeBindForSatellites();
- }
-
-
- if (bIsAppXDevMode || useRelativeBind)
- {
- if (GlobalAssemblyCache)
- {
- // lookup in GAC
- ArrayList a = new ArrayList();
- bool bTryLoadAnyway = false;
- try
- {
- Fusion.ReadCache(a, an.FullName, ASM_CACHE.GAC);
- }
- catch(Exception e)
- {
- if (e.IsTransient)
- throw;
-
- // We also catch any other exception types we haven't come across yet,
- // not just UnauthorizedAccessException.
-
- // We do not want this by itself to cause us to fail to load resources.
-
- // On Classic, try the old unoptimized way, for full compatibility with 4.0.
- // i.e. fall back to using nLoad.
- if (!AppDomain.IsAppXModel())
- bTryLoadAnyway = true;
-
- // On AppX:
- // Do not try nLoad since that would effectively allow Framework
- // resource satellite assemblies to be placed in AppX packages.
- // Instead, leave retAssembly == null. If we were called by the
- // ResourceManager, this will usually result in falling back to
- // the next culture in the resource fallback chain, possibly the
- // neutral culture.
-
- // Note: if throwOnFileNotFound is true, arbitrary
- // exceptions will be absorbed here and
- // FileNotFoundException will be thrown in their place.
- // (See below: "throw new FileNotFoundException").
- }
- if (a.Count > 0 || bTryLoadAnyway)
- {
- // present in the GAC, load it from there
- retAssembly = nLoad(an, null, null, this, ref stackMark,
- IntPtr.Zero,
- throwOnFileNotFound, false, false);
- }
- }
- else
- {
- String codeBase = CodeBase;
-
- if ((codeBase != null) &&
- (String.Compare(codeBase, 0, s_localFilePrefix, 0, 5, StringComparison.OrdinalIgnoreCase) == 0))
- {
- retAssembly = InternalProbeForSatelliteAssemblyNextToParentAssembly(an,
- name,
- codeBase,
- culture,
- throwOnFileNotFound,
- bIsAppXDevMode /* useLoadFile */, // if bIsAppXDevMode is false, then useRelativeBind is true.
- ref stackMark);
- if (retAssembly != null && !IsSimplyNamed(an))
- {
- AssemblyName defName = retAssembly.GetName();
- if (!AssemblyName.ReferenceMatchesDefinitionInternal(an,defName,false))
- retAssembly = null;
- }
- }
- else if (!bIsAppXDevMode)
- {
- retAssembly = nLoad(an, null, null, this, ref stackMark,
- IntPtr.Zero,
- throwOnFileNotFound, false, false);
- }
- }
- }
- else
-#endif // !FEATURE_CORECLR
- {
- retAssembly = nLoad(an, null, null, this, ref stackMark,
- IntPtr.Zero,
- throwOnFileNotFound, false, false);
- }
+ RuntimeAssembly retAssembly = nLoad(an, null, null, this, ref stackMark,
+ IntPtr.Zero,
+ throwOnFileNotFound, false, false);
if (retAssembly == this || (retAssembly == null && throwOnFileNotFound))
{
@@ -2836,7 +1959,6 @@ namespace System.Reflection
}
// Helper method used by InternalGetSatelliteAssembly only. Not abstracted for use elsewhere.
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
private RuntimeAssembly InternalProbeForSatelliteAssemblyNextToParentAssembly(AssemblyName an,
String name,
@@ -2930,7 +2052,7 @@ namespace System.Reflection
// the .DLL and .EXE load attempts if the user is interested in digging deeper.
if (retAssembly == null && throwOnFileNotFound)
- throw dllNotFoundException;
+ throw dllNotFoundException;
}
}
catch (DirectoryNotFoundException)
@@ -2944,11 +2066,9 @@ namespace System.Reflection
return retAssembly;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern RuntimeAssembly nLoadFile(String path, Evidence evidence);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern RuntimeAssembly nLoadImage(byte[] rawAssembly,
byte[] rawSymbolStore,
@@ -2956,8 +2076,7 @@ namespace System.Reflection
ref StackCrawlMark stackMark,
bool fIntrospection,
SecurityContextSource securityContextSource);
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
+
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
static internal extern unsafe void nLoadFromUnmanagedArray(bool fIntrospection,
@@ -2967,9 +2086,7 @@ namespace System.Reflection
ulong pdbSize,
StackCrawlMarkHandle stackMark,
ObjectHandleOnStack retAssembly);
-#endif
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void GetModules(RuntimeAssembly assembly,
@@ -2977,7 +2094,6 @@ namespace System.Reflection
bool getResourceModules,
ObjectHandleOnStack retModuleHandles);
- [System.Security.SecuritySafeCritical] // auto-generated
private RuntimeModule[] GetModulesInternal(bool loadIfNotFound,
bool getResourceModules)
{
@@ -2996,17 +2112,9 @@ namespace System.Reflection
return GetModulesInternal(false, getResourceModules);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern RuntimeModule GetManifestModule(RuntimeAssembly assembly);
-#if FEATURE_APTCA
- [System.Security.SecuritySafeCritical]
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern bool AptcaCheck(RuntimeAssembly targetAssembly, RuntimeAssembly sourceAssembly);
-#endif // FEATURE_APTCA
-
- [System.Security.SecurityCritical] // auto-generated
[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
index 955255572b..b2e44b0034 100644
--- a/src/mscorlib/src/System/Reflection/AssemblyAttributes.cs
+++ b/src/mscorlib/src/System/Reflection/AssemblyAttributes.cs
@@ -190,7 +190,7 @@ namespace System.Reflection {
public AssemblyFileVersionAttribute(String version)
{
if (version == null)
- throw new ArgumentNullException("version");
+ throw new ArgumentNullException(nameof(version));
Contract.EndContractBlock();
_version = version;
}
diff --git a/src/mscorlib/src/System/Reflection/AssemblyName.cs b/src/mscorlib/src/System/Reflection/AssemblyName.cs
index 051f3b5f0e..48eab33ee5 100644
--- a/src/mscorlib/src/System/Reflection/AssemblyName.cs
+++ b/src/mscorlib/src/System/Reflection/AssemblyName.cs
@@ -24,6 +24,7 @@ namespace System.Reflection {
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Diagnostics.Contracts;
+ using System.Text;
[Serializable]
[ClassInterface(ClassInterfaceType.None)]
@@ -103,19 +104,12 @@ namespace System.Reflection {
public String CodeBase
{
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
get { return _CodeBase; }
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
set { _CodeBase = value; }
}
public String EscapedCodeBase
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
if (_CodeBase == null)
@@ -189,16 +183,15 @@ namespace System.Reflection {
* if the file contains an assembly manifest. This method causes
* the file to be opened and closed.
*/
- [System.Security.SecuritySafeCritical] // auto-generated
static public AssemblyName GetAssemblyName(String assemblyFile)
{
if(assemblyFile == null)
- throw new ArgumentNullException("assemblyFile");
+ throw new ArgumentNullException(nameof(assemblyFile));
Contract.EndContractBlock();
// Assembly.GetNameInternal() will not demand path discovery
// permission, so do that first.
- String fullPath = Path.GetFullPathInternal(assemblyFile);
+ string fullPath = Path.GetFullPath(assemblyFile);
new FileIOPermission( FileIOPermissionAccess.PathDiscovery, fullPath ).Demand();
return nGetFileInformation(fullPath);
}
@@ -230,7 +223,6 @@ namespace System.Reflection {
// The compressed version of the public key formed from a truncated hash.
// Will throw a SecurityException if _PublicKey is invalid
- [System.Security.SecuritySafeCritical] // auto-generated
public byte[] GetPublicKeyToken()
{
if (_PublicKeyToken == null)
@@ -279,7 +271,6 @@ namespace System.Reflection {
public String FullName
{
- [System.Security.SecuritySafeCritical] // auto-generated
get {
return nToString();
}
@@ -295,11 +286,10 @@ namespace System.Reflection {
return s;
}
- [System.Security.SecurityCritical] // auto-generated_required
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
//Allocate the serialization info and serialize our static data.
@@ -360,11 +350,10 @@ namespace System.Reflection {
m_siInfo = info;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public AssemblyName(String assemblyName)
{
if (assemblyName == null)
- throw new ArgumentNullException("assemblyName");
+ throw new ArgumentNullException(nameof(assemblyName));
Contract.EndContractBlock();
if ((assemblyName.Length == 0) ||
(assemblyName[0] == '\0'))
@@ -374,7 +363,6 @@ namespace System.Reflection {
nInit();
}
- [System.Security.SecuritySafeCritical] // auto-generated
static public bool ReferenceMatchesDefinition(AssemblyName reference,
AssemblyName definition)
{
@@ -389,7 +377,6 @@ namespace System.Reflection {
/// "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
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern bool ReferenceMatchesDefinitionInternal(AssemblyName reference,
AssemblyName definition,
@@ -397,11 +384,9 @@ namespace System.Reflection {
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern void nInit(out RuntimeAssembly assembly, bool forIntrospection, bool raiseResolveEvent);
- [System.Security.SecurityCritical] // auto-generated
internal void nInit()
{
RuntimeAssembly dummy = null;
@@ -486,54 +471,239 @@ namespace System.Reflection {
_StrongNameKeyPair = keyPair;
}
-#if !FEATURE_CORECLR
- void _AssemblyName.GetTypeInfoCount(out uint pcTInfo)
+ // 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);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private extern String nToString();
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private extern byte[] nGetPublicKeyToken();
+
+ static internal String EscapeCodeBase(String codebase)
{
- throw new NotImplementedException();
+ 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)
+ return codebase;
+
+ return new string(dest, 0, position);
}
- void _AssemblyName.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
+ // This implementation of EscapeString has been copied from System.Private.Uri from corefx repo
+ // - forceX characters are always escaped if found
+ // - rsvd character will remain unescaped
+ //
+ // start - starting offset from input
+ // end - the exclusive ending offset in input
+ // destPos - starting offset in dest for output, on return this will be an exclusive "end" in the output.
+ //
+ // In case "dest" has lack of space it will be reallocated by preserving the _whole_ content up to current destPos
+ //
+ // Returns null if nothing has to be escaped AND passed dest was null, otherwise the resulting array with the updated destPos
+ //
+ internal unsafe static char[] EscapeString(string input, int start, int end, char[] dest, ref int destPos,
+ bool isUriString, char force1, char force2, char rsvd)
{
- throw new NotImplementedException();
+ int i = start;
+ int prevInputPos = start;
+ byte* bytes = stackalloc byte[c_MaxUnicodeCharsReallocate * c_MaxUTF_8BytesPerUnicodeChar]; // 40*4=160
+
+ fixed (char* pStr = input)
+ {
+ for (; i < end; ++i)
+ {
+ char ch = pStr[i];
+
+ // a Unicode ?
+ if (ch > '\x7F')
+ {
+ short maxSize = (short)Math.Min(end - i, (int)c_MaxUnicodeCharsReallocate - 1);
+
+ short count = 1;
+ for (; count < maxSize && pStr[i + count] > '\x7f'; ++count)
+ ;
+
+ // Is the last a high surrogate?
+ if (pStr[i + count - 1] >= 0xD800 && pStr[i + count - 1] <= 0xDBFF)
+ {
+ // 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"));
+ // need to grab one more char as a Surrogate except when it's a bogus input
+ ++count;
+ }
+
+ dest = EnsureDestinationSize(pStr, dest, i,
+ (short)(count * c_MaxUTF_8BytesPerUnicodeChar * c_EncodedCharsPerByte),
+ c_MaxUnicodeCharsReallocate * c_MaxUTF_8BytesPerUnicodeChar * c_EncodedCharsPerByte,
+ ref destPos, prevInputPos);
+
+ short numberOfBytes = (short)Encoding.UTF8.GetBytes(pStr + i, count, bytes,
+ c_MaxUnicodeCharsReallocate * c_MaxUTF_8BytesPerUnicodeChar);
+
+ // 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"));
+
+ i += (count - 1);
+
+ for (count = 0; count < numberOfBytes; ++count)
+ EscapeAsciiChar((char)bytes[count], dest, ref destPos);
+
+ prevInputPos = i + 1;
+ }
+ else if (ch == '%' && rsvd == '%')
+ {
+ // Means we don't reEncode '%' but check for the possible escaped sequence
+ dest = EnsureDestinationSize(pStr, dest, i, c_EncodedCharsPerByte,
+ c_MaxAsciiCharsReallocate * c_EncodedCharsPerByte, ref destPos, prevInputPos);
+ if (i + 2 < end && EscapedAscii(pStr[i + 1], pStr[i + 2]) != c_DummyChar)
+ {
+ // leave it escaped
+ dest[destPos++] = '%';
+ dest[destPos++] = pStr[i + 1];
+ dest[destPos++] = pStr[i + 2];
+ i += 2;
+ }
+ else
+ {
+ EscapeAsciiChar('%', dest, ref destPos);
+ }
+ prevInputPos = i + 1;
+ }
+ else if (ch == force1 || ch == force2)
+ {
+ dest = EnsureDestinationSize(pStr, dest, i, c_EncodedCharsPerByte,
+ c_MaxAsciiCharsReallocate * c_EncodedCharsPerByte, ref destPos, prevInputPos);
+ EscapeAsciiChar(ch, dest, ref destPos);
+ prevInputPos = i + 1;
+ }
+ else if (ch != rsvd && (isUriString ? !IsReservedUnreservedOrHash(ch) : !IsUnreserved(ch)))
+ {
+ dest = EnsureDestinationSize(pStr, dest, i, c_EncodedCharsPerByte,
+ c_MaxAsciiCharsReallocate * c_EncodedCharsPerByte, ref destPos, prevInputPos);
+ EscapeAsciiChar(ch, dest, ref destPos);
+ prevInputPos = i + 1;
+ }
+ }
+
+ if (prevInputPos != i)
+ {
+ // need to fill up the dest array ?
+ if (prevInputPos != start || dest != null)
+ dest = EnsureDestinationSize(pStr, dest, i, 0, 0, ref destPos, prevInputPos);
+ }
+ }
+
+ return dest;
}
- void _AssemblyName.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
+ //
+ // ensure destination array has enough space and contains all the needed input stuff
+ //
+ private unsafe static char[] EnsureDestinationSize(char* pStr, char[] dest, int currentInputPos,
+ short charsToAdd, short minReallocateChars, ref int destPos, int prevInputPos)
{
- throw new NotImplementedException();
- }
+ if ((object)dest == null || dest.Length < destPos + (currentInputPos - prevInputPos) + charsToAdd)
+ {
+ // allocating or reallocating array by ensuring enough space based on maxCharsToAdd.
+ char[] newresult = new char[destPos + (currentInputPos - prevInputPos) + minReallocateChars];
+
+ if ((object)dest != null && destPos != 0)
+ Buffer.BlockCopy(dest, 0, newresult, 0, destPos << 1);
+ dest = newresult;
+ }
- void _AssemblyName.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
+ // ensuring we copied everything form the input string left before last escaping
+ while (prevInputPos != currentInputPos)
+ dest[destPos++] = pStr[prevInputPos++];
+ return dest;
+ }
+
+ internal static void EscapeAsciiChar(char ch, char[] to, ref int pos)
{
- throw new NotImplementedException();
+ to[pos++] = '%';
+ to[pos++] = s_hexUpperChars[(ch & 0xf0) >> 4];
+ to[pos++] = s_hexUpperChars[ch & 0xf];
}
-#endif
-#if FEATURE_APTCA
- internal string GetNameWithPublicKey()
+ internal static char EscapedAscii(char digit, char next)
{
- byte[] key = GetPublicKey();
+ if (!(((digit >= '0') && (digit <= '9'))
+ || ((digit >= 'A') && (digit <= 'F'))
+ || ((digit >= 'a') && (digit <= 'f'))))
+ {
+ return c_DummyChar;
+ }
+
+ int res = (digit <= '9')
+ ? ((int)digit - (int)'0')
+ : (((digit <= 'F')
+ ? ((int)digit - (int)'A')
+ : ((int)digit - (int)'a'))
+ + 10);
+
+ if (!(((next >= '0') && (next <= '9'))
+ || ((next >= 'A') && (next <= 'F'))
+ || ((next >= 'a') && (next <= 'f'))))
+ {
+ return c_DummyChar;
+ }
+
+ return (char)((res << 4) + ((next <= '9')
+ ? ((int)next - (int)'0')
+ : (((next <= 'F')
+ ? ((int)next - (int)'A')
+ : ((int)next - (int)'a'))
+ + 10)));
+ }
- // The following string should not be localized because it is used in security decisions.
- return Name + ", PublicKey=" + System.Security.Util.Hex.EncodeHexString(key);
+ private static unsafe bool IsReservedUnreservedOrHash(char c)
+ {
+ if (IsUnreserved(c))
+ {
+ return true;
+ }
+ return (RFC3986ReservedMarks.IndexOf(c) >= 0);
}
-#endif
- // This call opens and closes the file, but does not add the
- // assembly to the domain.
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- static internal extern AssemblyName nGetFileInformation(String s);
+ internal static unsafe bool IsUnreserved(char c)
+ {
+ if (IsAsciiLetterOrDigit(c))
+ {
+ return true;
+ }
+ return (RFC3986UnreservedMarks.IndexOf(c) >= 0);
+ }
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private extern String nToString();
+ //Only consider ASCII characters
+ internal static bool IsAsciiLetter(char character)
+ {
+ return (character >= 'a' && character <= 'z') ||
+ (character >= 'A' && character <= 'Z');
+ }
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private extern byte[] nGetPublicKeyToken();
-
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- static internal extern String EscapeCodeBase(String codeBase);
+ internal static bool IsAsciiLetterOrDigit(char character)
+ {
+ 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' };
+ internal const char c_DummyChar = (char)0xFFFF; //An Invalid Unicode character used as a dummy char passed into the parameter
+ 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 string RFC3986ReservedMarks = @":/?#[]@!$&'()*+,;=";
+ private const string RFC3986UnreservedMarks = @"-._~";
}
}
diff --git a/src/mscorlib/src/System/Reflection/Associates.cs b/src/mscorlib/src/System/Reflection/Associates.cs
index 8b34e77b63..9eaf74a6e9 100644
--- a/src/mscorlib/src/System/Reflection/Associates.cs
+++ b/src/mscorlib/src/System/Reflection/Associates.cs
@@ -8,6 +8,7 @@ namespace System.Reflection
{
using System;
using System.Collections.Generic;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
internal static class Associates
@@ -35,7 +36,6 @@ namespace System.Reflection
return false;
}
- [System.Security.SecurityCritical] // auto-generated
private static unsafe RuntimeMethodInfo AssignAssociates(
int tkMethod,
RuntimeType declaredType,
@@ -44,8 +44,8 @@ namespace System.Reflection
if (MetadataToken.IsNullToken(tkMethod))
return null;
- Contract.Assert(declaredType != null);
- Contract.Assert(reflectedType != null);
+ Debug.Assert(declaredType != null);
+ Debug.Assert(reflectedType != null);
bool isInherited = declaredType != reflectedType;
@@ -63,7 +63,7 @@ namespace System.Reflection
}
RuntimeMethodHandleInternal associateMethodHandle = ModuleHandle.ResolveMethodHandleInternalCore(RuntimeTypeHandle.GetModule(declaredType), tkMethod, genericArgumentHandles, genericArgumentCount, null, 0);
- Contract.Assert(!associateMethodHandle.IsNullHandle(), "Failed to resolve associateRecord methodDef token");
+ Debug.Assert(!associateMethodHandle.IsNullHandle(), "Failed to resolve associateRecord methodDef token");
if (isInherited)
{
@@ -109,7 +109,6 @@ namespace System.Reflection
return associateMethod;
}
- [System.Security.SecurityCritical] // auto-generated
internal static unsafe void AssignAssociates(
MetadataImport scope,
int mdPropEvent,
diff --git a/src/mscorlib/src/System/Reflection/ComInterfaces.cs b/src/mscorlib/src/System/Reflection/ComInterfaces.cs
index 63438115fc..6e4b0cc19a 100644
--- a/src/mscorlib/src/System/Reflection/ComInterfaces.cs
+++ b/src/mscorlib/src/System/Reflection/ComInterfaces.cs
@@ -2,248 +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.
-using System;
-using System.Globalization;
-using System.IO;
-using System.Reflection;
-using System.Runtime.InteropServices;
-using System.Runtime.Serialization;
-using System.Security.Permissions;
-using System.Security.Policy;
-
namespace System.Runtime.InteropServices
{
[GuidAttribute("BCA8B44D-AAD6-3A86-8AB7-03349F4F2DA2")]
[CLSCompliant(false)]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[TypeLibImportClassAttribute(typeof(System.Type))]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface _Type
{
-#if !FEATURE_CORECLR
- #region IDispatch Members
- void GetTypeInfoCount(out uint pcTInfo);
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
- #endregion
-
- #region Object Members
- String ToString();
- bool Equals(Object other);
- int GetHashCode();
- Type GetType();
- #endregion
-
- #region MemberInfo Members
- MemberTypes MemberType { get; }
- String Name { get; }
- Type DeclaringType { get; }
- Type ReflectedType { get; }
- Object[] GetCustomAttributes(Type attributeType, bool inherit);
- Object[] GetCustomAttributes(bool inherit);
- bool IsDefined(Type attributeType, bool inherit);
- #endregion
-
- #region Type Members
- Guid GUID { get; }
- Module Module { get; }
- Assembly Assembly { get; }
- RuntimeTypeHandle TypeHandle { get; }
- String FullName { get; }
- String Namespace { get; }
- String AssemblyQualifiedName { get; }
- int GetArrayRank();
- Type BaseType { get; }
-
- ConstructorInfo[] GetConstructors(BindingFlags bindingAttr);
- Type GetInterface(String name, bool ignoreCase);
- Type[] GetInterfaces();
- Type[] FindInterfaces(TypeFilter filter,Object filterCriteria);
- EventInfo GetEvent(String name,BindingFlags bindingAttr);
- EventInfo[] GetEvents();
- EventInfo[] GetEvents(BindingFlags bindingAttr);
- Type[] GetNestedTypes(BindingFlags bindingAttr);
- Type GetNestedType(String name, BindingFlags bindingAttr);
- MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr);
- MemberInfo[] GetDefaultMembers();
- MemberInfo[] FindMembers(MemberTypes memberType,BindingFlags bindingAttr,MemberFilter filter,Object filterCriteria);
- Type GetElementType();
- bool IsSubclassOf(Type c);
- bool IsInstanceOfType(Object o);
- bool IsAssignableFrom(Type c);
- InterfaceMapping GetInterfaceMap(Type interfaceType);
- MethodInfo GetMethod(String name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers);
- MethodInfo GetMethod(String name, BindingFlags bindingAttr);
- MethodInfo[] GetMethods(BindingFlags bindingAttr);
- FieldInfo GetField(String name, BindingFlags bindingAttr);
- FieldInfo[] GetFields(BindingFlags bindingAttr);
- PropertyInfo GetProperty(String name, BindingFlags bindingAttr);
- PropertyInfo GetProperty(String name,BindingFlags bindingAttr,Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers);
- PropertyInfo[] GetProperties(BindingFlags bindingAttr);
- MemberInfo[] GetMember(String name, BindingFlags bindingAttr);
- MemberInfo[] GetMembers(BindingFlags bindingAttr);
- Object InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters);
- Type UnderlyingSystemType
- {
- get;
- }
-
- Object InvokeMember(String name,BindingFlags invokeAttr,Binder binder, Object target, Object[] args, CultureInfo culture);
- Object InvokeMember(String name,BindingFlags invokeAttr,Binder binder, Object target, Object[] args);
- ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers);
- ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers);
- ConstructorInfo GetConstructor(Type[] types);
- ConstructorInfo[] GetConstructors();
- ConstructorInfo TypeInitializer
- {
- get;
- }
-
- MethodInfo GetMethod(String name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers);
- MethodInfo GetMethod(String name, Type[] types, ParameterModifier[] modifiers);
- MethodInfo GetMethod(String name, Type[] types);
- MethodInfo GetMethod(String name);
- MethodInfo[] GetMethods();
- FieldInfo GetField(String name);
- FieldInfo[] GetFields();
- Type GetInterface(String name);
- EventInfo GetEvent(String name);
- PropertyInfo GetProperty(String name, Type returnType, Type[] types,ParameterModifier[] modifiers);
- PropertyInfo GetProperty(String name, Type returnType, Type[] types);
- PropertyInfo GetProperty(String name, Type[] types);
- PropertyInfo GetProperty(String name, Type returnType);
- PropertyInfo GetProperty(String name);
- PropertyInfo[] GetProperties();
- Type[] GetNestedTypes();
- Type GetNestedType(String name);
- MemberInfo[] GetMember(String name);
- MemberInfo[] GetMembers();
- TypeAttributes Attributes { get; }
- bool IsNotPublic { get; }
- bool IsPublic { get; }
- bool IsNestedPublic { get; }
- bool IsNestedPrivate { get; }
- bool IsNestedFamily { get; }
- bool IsNestedAssembly { get; }
- bool IsNestedFamANDAssem { get; }
- bool IsNestedFamORAssem { get; }
- bool IsAutoLayout { get; }
- bool IsLayoutSequential { get; }
- bool IsExplicitLayout { get; }
- bool IsClass { get; }
- bool IsInterface { get; }
- bool IsValueType { get; }
- bool IsAbstract { get; }
- bool IsSealed { get; }
- bool IsEnum { get; }
- bool IsSpecialName { get; }
- bool IsImport { get; }
- bool IsSerializable { get; }
- bool IsAnsiClass { get; }
- bool IsUnicodeClass { get; }
- bool IsAutoClass { get; }
- bool IsArray { get; }
- bool IsByRef { get; }
- bool IsPointer { get; }
- bool IsPrimitive { get; }
- bool IsCOMObject { get; }
- bool HasElementType { get; }
- bool IsContextful { get; }
- bool IsMarshalByRef { get; }
- bool Equals(Type o);
- #endregion
-#endif
}
[GuidAttribute("17156360-2f1a-384a-bc52-fde93c215c5b")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsDual)]
[TypeLibImportClassAttribute(typeof(System.Reflection.Assembly))]
[CLSCompliant(false)]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface _Assembly
{
-#if !FEATURE_CORECLR
- #region Object Members
- String ToString();
- bool Equals(Object other);
- int GetHashCode();
- Type GetType();
- #endregion
-
- #region Assembly Members
- String CodeBase {
-#if FEATURE_CORECLR
-[System.Security.SecurityCritical] // auto-generated
-#endif
-get; }
- String EscapedCodeBase { get; }
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
- AssemblyName GetName();
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
- AssemblyName GetName(bool copiedName);
- String FullName { get; }
- MethodInfo EntryPoint { get; }
- Type GetType(String name);
- Type GetType(String name, bool throwOnError);
- Type[] GetExportedTypes();
- Type[] GetTypes();
- Stream GetManifestResourceStream(Type type, String name);
- Stream GetManifestResourceStream(String name);
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
- FileStream GetFile(String name);
- FileStream[] GetFiles();
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
- FileStream[] GetFiles(bool getResourceModules);
- String[] GetManifestResourceNames();
- ManifestResourceInfo GetManifestResourceInfo(String resourceName);
- String Location {
-#if FEATURE_CORECLR
-[System.Security.SecurityCritical] // auto-generated
-#endif
-get; }
-#if FEATURE_CAS_POLICY
- Evidence Evidence { get; }
-#endif // FEATURE_CAS_POLICY
- Object[] GetCustomAttributes(Type attributeType, bool inherit);
- Object[] GetCustomAttributes(bool inherit);
- bool IsDefined(Type attributeType, bool inherit);
-#if FEATURE_SERIALIZATION
- [System.Security.SecurityCritical] // auto-generated_required
- void GetObjectData(SerializationInfo info, StreamingContext context);
-#endif
- [method: System.Security.SecurityCritical]
- event ModuleResolveEventHandler ModuleResolve;
- Type GetType(String name, bool throwOnError, bool ignoreCase);
- Assembly GetSatelliteAssembly(CultureInfo culture);
- Assembly GetSatelliteAssembly(CultureInfo culture, Version version);
-#if FEATURE_MULTIMODULE_ASSEMBLIES
- Module LoadModule(String moduleName, byte[] rawModule);
- Module LoadModule(String moduleName, byte[] rawModule, byte[] rawSymbolStore);
-#endif
- Object CreateInstance(String typeName);
- Object CreateInstance(String typeName, bool ignoreCase);
- Object CreateInstance(String typeName, bool ignoreCase, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes);
- Module[] GetLoadedModules();
- Module[] GetLoadedModules(bool getResourceModules);
- Module[] GetModules();
- Module[] GetModules(bool getResourceModules);
- Module GetModule(String name);
- AssemblyName[] GetReferencedAssemblies();
- bool GlobalAssemblyCache { get; }
- #endregion
-#endif
}
-
[GuidAttribute("f7102fa9-cabb-3a74-a6da-b4567ef1b079")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[TypeLibImportClassAttribute(typeof(System.Reflection.MemberInfo))]
@@ -251,34 +29,8 @@ get; }
[System.Runtime.InteropServices.ComVisible(true)]
public interface _MemberInfo
{
-#if !FEATURE_CORECLR
- #region IDispatch Members
- void GetTypeInfoCount(out uint pcTInfo);
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
- #endregion
-
- #region Object Members
- String ToString();
- bool Equals(Object other);
- int GetHashCode();
- Type GetType();
- #endregion
-
- #region MemberInfo Members
- MemberTypes MemberType { get; }
- String Name { get; }
- Type DeclaringType { get; }
- Type ReflectedType { get; }
- Object[] GetCustomAttributes(Type attributeType, bool inherit);
- Object[] GetCustomAttributes(bool inherit);
- bool IsDefined(Type attributeType, bool inherit);
- #endregion
-#endif
}
-
[GuidAttribute("6240837A-707F-3181-8E98-A36AE086766B")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[CLSCompliant(false)]
@@ -286,57 +38,8 @@ get; }
[System.Runtime.InteropServices.ComVisible(true)]
public interface _MethodBase
{
-#if !FEATURE_CORECLR
- #region IDispatch Members
- void GetTypeInfoCount(out uint pcTInfo);
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
- #endregion
-
- #region Object Members
- String ToString();
- bool Equals(Object other);
- int GetHashCode();
- Type GetType();
- #endregion
-
- #region MemberInfo Members
- MemberTypes MemberType { get; }
- String Name { get; }
- Type DeclaringType { get; }
- Type ReflectedType { get; }
- Object[] GetCustomAttributes(Type attributeType, bool inherit);
- Object[] GetCustomAttributes(bool inherit);
- bool IsDefined(Type attributeType, bool inherit);
- #endregion
-
- #region MethodBase Members
- ParameterInfo[] GetParameters();
- MethodImplAttributes GetMethodImplementationFlags();
- RuntimeMethodHandle MethodHandle { get; }
- MethodAttributes Attributes { get; }
- CallingConventions CallingConvention { get; }
- Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture);
- bool IsPublic { get; }
- bool IsPrivate { get; }
- bool IsFamily { get; }
- bool IsAssembly { get; }
- bool IsFamilyAndAssembly { get; }
- bool IsFamilyOrAssembly { get; }
- bool IsStatic { get; }
- bool IsFinal { get; }
- bool IsVirtual { get; }
- bool IsHideBySig { get; }
- bool IsAbstract { get; }
- bool IsSpecialName { get; }
- bool IsConstructor { get; }
- Object Invoke(Object obj, Object[] parameters);
- #endregion
-#endif
}
-
[GuidAttribute("FFCC1B5D-ECB8-38DD-9B01-3DC8ABC2AA5F")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[CLSCompliant(false)]
@@ -344,62 +47,7 @@ get; }
[System.Runtime.InteropServices.ComVisible(true)]
public interface _MethodInfo
{
-#if !FEATURE_CORECLR
- #region IDispatch Members
- void GetTypeInfoCount(out uint pcTInfo);
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
- #endregion
-
- #region Object Members
- String ToString();
- bool Equals(Object other);
- int GetHashCode();
- Type GetType();
- #endregion
-
- #region MemberInfo Members
- MemberTypes MemberType { get; }
- String Name { get; }
- Type DeclaringType { get; }
- Type ReflectedType { get; }
- Object[] GetCustomAttributes(Type attributeType, bool inherit);
- Object[] GetCustomAttributes(bool inherit);
- bool IsDefined(Type attributeType, bool inherit);
- #endregion
-
- #region MethodBase Members
- ParameterInfo[] GetParameters();
- MethodImplAttributes GetMethodImplementationFlags();
- RuntimeMethodHandle MethodHandle { get; }
- MethodAttributes Attributes { get; }
- CallingConventions CallingConvention { get; }
- Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture);
- bool IsPublic { get; }
- bool IsPrivate { get; }
- bool IsFamily { get; }
- bool IsAssembly { get; }
- bool IsFamilyAndAssembly { get; }
- bool IsFamilyOrAssembly { get; }
- bool IsStatic { get; }
- bool IsFinal { get; }
- bool IsVirtual { get; }
- bool IsHideBySig { get; }
- bool IsAbstract { get; }
- bool IsSpecialName { get; }
- bool IsConstructor { get; }
- Object Invoke(Object obj, Object[] parameters);
- #endregion
-
- #region MethodInfo Members
- Type ReturnType { get; }
- ICustomAttributeProvider ReturnTypeCustomAttributes { get; }
- MethodInfo GetBaseDefinition();
- #endregion
-#endif
}
-
[GuidAttribute("E9A19478-9646-3679-9B10-8411AE1FD57D")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
@@ -408,174 +56,26 @@ get; }
[System.Runtime.InteropServices.ComVisible(true)]
public interface _ConstructorInfo
{
-#if !FEATURE_CORECLR
- #region IDispatch Members
- void GetTypeInfoCount(out uint pcTInfo);
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
- #endregion
-
- #region Object Members
- String ToString();
- bool Equals(Object other);
- int GetHashCode();
- Type GetType();
- #endregion
-
- #region MemberInfo Members
- MemberTypes MemberType { get; }
- String Name { get; }
- Type DeclaringType { get; }
- Type ReflectedType { get; }
- Object[] GetCustomAttributes(Type attributeType, bool inherit);
- Object[] GetCustomAttributes(bool inherit);
- bool IsDefined(Type attributeType, bool inherit);
- #endregion
-
- #region MethodBase Members
- ParameterInfo[] GetParameters();
- MethodImplAttributes GetMethodImplementationFlags();
- RuntimeMethodHandle MethodHandle { get; }
- MethodAttributes Attributes { get; }
- CallingConventions CallingConvention { get; }
- Object Invoke_2(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture);
- bool IsPublic { get; }
- bool IsPrivate { get; }
- bool IsFamily { get; }
- bool IsAssembly { get; }
- bool IsFamilyAndAssembly { get; }
- bool IsFamilyOrAssembly { get; }
- bool IsStatic { get; }
- bool IsFinal { get; }
- bool IsVirtual { get; }
- bool IsHideBySig { get; }
- bool IsAbstract { get; }
- bool IsSpecialName { get; }
- bool IsConstructor { get; }
- Object Invoke_3(Object obj, Object[] parameters);
- #endregion
-
- #region ConstructorInfo
- Object Invoke_4(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture);
- Object Invoke_5(Object[] parameters);
- #endregion
-#endif
}
-
[GuidAttribute("8A7C1442-A9FB-366B-80D8-4939FFA6DBE0")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[CLSCompliant(false)]
[TypeLibImportClassAttribute(typeof(System.Reflection.FieldInfo))]
[System.Runtime.InteropServices.ComVisible(true)]
public interface _FieldInfo
- {
-#if !FEATURE_CORECLR
- #region IDispatch Members
- void GetTypeInfoCount(out uint pcTInfo);
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
- #endregion
-
- #region Object Members
- String ToString();
- bool Equals(Object other);
- int GetHashCode();
- Type GetType();
- #endregion
-
- #region MemberInfo Members
- MemberTypes MemberType { get; }
- String Name { get; }
- Type DeclaringType { get; }
- Type ReflectedType { get; }
- Object[] GetCustomAttributes(Type attributeType, bool inherit);
- Object[] GetCustomAttributes(bool inherit);
- bool IsDefined(Type attributeType, bool inherit);
- #endregion
-
- #region FieldInfo Members
- Type FieldType { get; }
- Object GetValue(Object obj);
- Object GetValueDirect(TypedReference obj);
- void SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture);
- void SetValueDirect(TypedReference obj,Object value);
- RuntimeFieldHandle FieldHandle { get; }
- FieldAttributes Attributes { get; }
- void SetValue(Object obj, Object value);
- bool IsPublic { get; }
- bool IsPrivate { get; }
- bool IsFamily { get; }
- bool IsAssembly { get; }
- bool IsFamilyAndAssembly { get; }
- bool IsFamilyOrAssembly { get; }
- bool IsStatic { get; }
- bool IsInitOnly { get; }
- bool IsLiteral { get; }
- bool IsNotSerialized { get; }
- bool IsSpecialName { get; }
- bool IsPinvokeImpl { get; }
- #endregion
-#endif
+ {
}
-
[GuidAttribute("F59ED4E4-E68F-3218-BD77-061AA82824BF")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[CLSCompliant(false)]
[TypeLibImportClassAttribute(typeof(System.Reflection.PropertyInfo))]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface _PropertyInfo
{
-#if !FEATURE_CORECLR
- #region IDispatch Members
- void GetTypeInfoCount(out uint pcTInfo);
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
- #endregion
-
- #region Object Members
- String ToString();
- bool Equals(Object other);
- int GetHashCode();
- Type GetType();
- #endregion
-
- #region MemberInfo Members
- MemberTypes MemberType { get; }
- String Name { get; }
- Type DeclaringType { get; }
- Type ReflectedType { get; }
- Object[] GetCustomAttributes(Type attributeType, bool inherit);
- Object[] GetCustomAttributes(bool inherit);
- bool IsDefined(Type attributeType, bool inherit);
- #endregion
-
- #region Property Members
- Type PropertyType { get; }
- Object GetValue(Object obj,Object[] index);
- Object GetValue(Object obj,BindingFlags invokeAttr,Binder binder, Object[] index, CultureInfo culture);
- void SetValue(Object obj, Object value, Object[] index);
- void SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture);
- MethodInfo[] GetAccessors(bool nonPublic);
- MethodInfo GetGetMethod(bool nonPublic);
- MethodInfo GetSetMethod(bool nonPublic);
- ParameterInfo[] GetIndexParameters();
- PropertyAttributes Attributes { get; }
- bool CanRead { get; }
- bool CanWrite { get; }
- MethodInfo[] GetAccessors();
- MethodInfo GetGetMethod();
- MethodInfo GetSetMethod();
- bool IsSpecialName { get; }
- #endregion
-#endif
}
-
[GuidAttribute("9DE59C64-D889-35A1-B897-587D74469E5B")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[CLSCompliant(false)]
@@ -583,91 +83,33 @@ get; }
[System.Runtime.InteropServices.ComVisible(true)]
public interface _EventInfo
{
-#if !FEATURE_CORECLR
- #region IDispatch Members
- void GetTypeInfoCount(out uint pcTInfo);
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
- #endregion
-
- #region Object Members
- String ToString();
- bool Equals(Object other);
- int GetHashCode();
- Type GetType();
- #endregion
-
- #region MemberInfo Members
- MemberTypes MemberType { get; }
- String Name { get; }
- Type DeclaringType { get; }
- Type ReflectedType { get; }
- Object[] GetCustomAttributes(Type attributeType, bool inherit);
- Object[] GetCustomAttributes(bool inherit);
- bool IsDefined(Type attributeType, bool inherit);
- #endregion
-
- #region EventInfo Members
- MethodInfo GetAddMethod(bool nonPublic);
- MethodInfo GetRemoveMethod(bool nonPublic);
- MethodInfo GetRaiseMethod(bool nonPublic);
- EventAttributes Attributes { get; }
- MethodInfo GetAddMethod();
- MethodInfo GetRemoveMethod();
- MethodInfo GetRaiseMethod();
- void AddEventHandler(Object target, Delegate handler);
- void RemoveEventHandler(Object target, Delegate handler);
- Type EventHandlerType { get; }
- bool IsSpecialName { get; }
- bool IsMulticast { get; }
- #endregion
-#endif
}
[GuidAttribute("993634C4-E47A-32CC-BE08-85F567DC27D6")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[CLSCompliant(false)]
[TypeLibImportClassAttribute(typeof(System.Reflection.ParameterInfo))]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface _ParameterInfo
{
-#if !FEATURE_CORECLR
- void GetTypeInfoCount(out uint pcTInfo);
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
-#endif
}
[GuidAttribute("D002E9BA-D9E3-3749-B1D3-D565A08B13E7")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[CLSCompliant(false)]
[TypeLibImportClassAttribute(typeof(System.Reflection.Module))]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface _Module
{
-#if !FEATURE_CORECLR
- void GetTypeInfoCount(out uint pcTInfo);
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
-#endif
}
[GuidAttribute("B42B6AAC-317E-34D5-9FA9-093BB4160C50")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[CLSCompliant(false)]
[TypeLibImportClassAttribute(typeof(System.Reflection.AssemblyName))]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface _AssemblyName
{
-#if !FEATURE_CORECLR
- void GetTypeInfoCount(out uint pcTInfo);
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
-#endif
}
}
diff --git a/src/mscorlib/src/System/Reflection/ConstructorInfo.cs b/src/mscorlib/src/System/Reflection/ConstructorInfo.cs
index d5b5cc36eb..3d927fc85c 100644
--- a/src/mscorlib/src/System/Reflection/ConstructorInfo.cs
+++ b/src/mscorlib/src/System/Reflection/ConstructorInfo.cs
@@ -14,9 +14,6 @@ namespace System.Reflection
using System.Runtime;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
-#if FEATURE_REMOTING
- using System.Runtime.Remoting.Metadata;
-#endif //FEATURE_REMOTING
using System.Runtime.Serialization;
using System.Security;
using System.Security.Permissions;
@@ -28,9 +25,6 @@ namespace System.Reflection
[Serializable]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_ConstructorInfo))]
-#pragma warning disable 618
- [PermissionSetAttribute(SecurityAction.InheritanceDemand, Name = "FullTrust")]
-#pragma warning restore 618
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class ConstructorInfo : MethodBase, _ConstructorInfo
{
@@ -101,57 +95,6 @@ namespace System.Reflection
return Invoke(BindingFlags.Default, null, parameters, null);
}
#endregion
-
-#if !FEATURE_CORECLR
- #region COM Interop Support
- Type _ConstructorInfo.GetType()
- {
- return base.GetType();
- }
-
- Object _ConstructorInfo.Invoke_2(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
- {
- return Invoke(obj, invokeAttr, binder, parameters, culture);
- }
-
- Object _ConstructorInfo.Invoke_3(Object obj, Object[] parameters)
- {
- return Invoke(obj, parameters);
- }
-
- Object _ConstructorInfo.Invoke_4(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
- {
- return Invoke(invokeAttr, binder, parameters, culture);
- }
-
- Object _ConstructorInfo.Invoke_5(Object[] parameters)
- {
- return Invoke(parameters);
- }
-
- void _ConstructorInfo.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _ConstructorInfo.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _ConstructorInfo.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- // If you implement this method, make sure to include _ConstructorInfo.Invoke in VM\DangerousAPIs.h and
- // include _ConstructorInfo in SystemDomain::IsReflectionInvocationMethod in AppDomain.cpp.
- void _ConstructorInfo.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
- #endregion
-#endif
}
[Serializable]
@@ -205,7 +148,6 @@ namespace System.Reflection
internal INVOCATION_FLAGS InvocationFlags
{
- [System.Security.SecuritySafeCritical]
get
{
if ((m_invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED) == 0)
@@ -261,7 +203,6 @@ namespace System.Reflection
#endregion
#region Constructor
- [System.Security.SecurityCritical] // auto-generated
internal RuntimeConstructorInfo(
RuntimeMethodHandleInternal handle, RuntimeType declaringType, RuntimeTypeCache reflectedTypeCache,
MethodAttributes methodAttributes, BindingFlags bindingFlags)
@@ -276,40 +217,9 @@ namespace System.Reflection
}
#endregion
-#if FEATURE_REMOTING
- #region Legacy Remoting Cache
- // The size of CachedData is accounted for by BaseObjectWithCachedData in object.h.
- // This member is currently being used by Remoting for caching remoting data. If you
- // need to cache data here, talk to the Remoting team to work out a mechanism, so that
- // both caching systems can happily work together.
- private RemotingMethodCachedData m_cachedData;
-
- internal RemotingMethodCachedData RemotingCache
- {
- get
- {
- // This grabs an internal copy of m_cachedData and uses
- // that instead of looking at m_cachedData directly because
- // the cache may get cleared asynchronously. This prevents
- // us from having to take a lock.
- RemotingMethodCachedData cache = m_cachedData;
- if (cache == null)
- {
- cache = new RemotingMethodCachedData(this);
- RemotingMethodCachedData ret = Interlocked.CompareExchange(ref m_cachedData, cache, null);
- if (ret != null)
- cache = ret;
- }
- return cache;
- }
- }
- #endregion
-#endif //FEATURE_REMOTING
-
#region NonPublic Methods
RuntimeMethodHandleInternal IRuntimeMethodInfo.Value
{
- [System.Security.SecuritySafeCritical]
get
{
return new RuntimeMethodHandleInternal(m_handle);
@@ -397,28 +307,27 @@ namespace System.Reflection
public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
{
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
Contract.EndContractBlock();
RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override bool IsDefined(Type attributeType, bool inherit)
{
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
Contract.EndContractBlock();
RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
return CustomAttribute.IsDefined(this, attributeRuntimeType);
}
@@ -433,7 +342,6 @@ namespace System.Reflection
#region MemberInfo Overrides
public override String Name
{
- [System.Security.SecuritySafeCritical] // auto-generated
get { return RuntimeMethodHandle.GetName(this); }
}
[System.Runtime.InteropServices.ComVisible(true)]
@@ -457,7 +365,6 @@ namespace System.Reflection
public override int MetadataToken
{
- [System.Security.SecuritySafeCritical] // auto-generated
get { return RuntimeMethodHandle.GetMethodDef(this); }
}
public override Module Module
@@ -475,7 +382,6 @@ namespace System.Reflection
// This seems to always returns System.Void.
internal override Type GetReturnType() { return Signature.ReturnType; }
- [System.Security.SecuritySafeCritical] // auto-generated
internal override ParameterInfo[] GetParametersNoCopy()
{
if (m_parameters == null)
@@ -532,7 +438,7 @@ namespace System.Reflection
internal static void CheckCanCreateInstance(Type declaringType, bool isVarArg)
{
if (declaringType == null)
- throw new ArgumentNullException("declaringType");
+ throw new ArgumentNullException(nameof(declaringType));
Contract.EndContractBlock();
// ctor is ReflectOnly
@@ -580,7 +486,6 @@ namespace System.Reflection
throw new TargetException();
}
- [System.Security.SecuritySafeCritical] // auto-generated
[DebuggerStepThroughAttribute]
[Diagnostics.DebuggerHidden]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
@@ -607,26 +512,10 @@ namespace System.Reflection
if (obj != null)
{
-
-#if FEATURE_CORECLR
// 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;
-#else // FEATURE_CORECLR
- new SecurityPermission(SecurityPermissionFlag.SkipVerification).Demand();
-#endif // FEATURE_CORECLR
-
- }
-
-#if !FEATURE_CORECLR
- if ((invocationFlags &(INVOCATION_FLAGS.INVOCATION_FLAGS_RISKY_METHOD | INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY)) != 0)
- {
- if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_RISKY_METHOD) != 0)
- CodeAccessPermission.Demand(PermissionType.ReflectionMemberAccess);
- if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY) != 0)
- RuntimeMethodHandle.PerformSecurityCheck(obj, this, m_declaringType, (uint)m_invocationFlags);
}
-#endif // !FEATURE_CORECLR
Signature sig = Signature;
@@ -650,7 +539,6 @@ namespace System.Reflection
}
- [System.Security.SecuritySafeCritical] // overrides SC member
#pragma warning disable 618
[ReflectionPermissionAttribute(SecurityAction.Demand, Flags = ReflectionPermissionFlag.MemberAccess)]
#pragma warning restore 618
@@ -664,17 +552,17 @@ namespace System.Reflection
public override bool IsSecurityCritical
{
- get { return RuntimeMethodHandle.IsSecurityCritical(this); }
+ get { return true; }
}
public override bool IsSecuritySafeCritical
{
- get { return RuntimeMethodHandle.IsSecuritySafeCritical(this); }
+ get { return false; }
}
public override bool IsSecurityTransparent
{
- get { return RuntimeMethodHandle.IsSecurityTransparent(this); }
+ get { return false; }
}
public override bool ContainsGenericParameters
@@ -687,7 +575,6 @@ namespace System.Reflection
#endregion
#region ConstructorInfo Overrides
- [System.Security.SecuritySafeCritical] // auto-generated
[DebuggerStepThroughAttribute]
[Diagnostics.DebuggerHidden]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
@@ -711,18 +598,6 @@ namespace System.Reflection
}
#endif
-#if !FEATURE_CORECLR
- if ((invocationFlags & (INVOCATION_FLAGS.INVOCATION_FLAGS_RISKY_METHOD | INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY | INVOCATION_FLAGS.INVOCATION_FLAGS_IS_DELEGATE_CTOR)) != 0)
- {
- if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_RISKY_METHOD) != 0)
- CodeAccessPermission.Demand(PermissionType.ReflectionMemberAccess);
- if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY) != 0)
- RuntimeMethodHandle.PerformSecurityCheck(null, this, m_declaringType, (uint)(m_invocationFlags | INVOCATION_FLAGS.INVOCATION_FLAGS_CONSTRUCTOR_INVOKE));
- if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_IS_DELEGATE_CTOR) != 0)
- new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
- }
-#endif // !FEATURE_CORECLR
-
// get the signature
Signature sig = Signature;
@@ -749,11 +624,10 @@ namespace System.Reflection
#endregion
#region ISerializable Implementation
- [System.Security.SecurityCritical] // auto-generated
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
MemberInfoSerializationHolder.GetSerializationInfo(
info,
@@ -777,5 +651,4 @@ namespace System.Reflection
}
#endregion
}
-
}
diff --git a/src/mscorlib/src/System/Reflection/CustomAttribute.cs b/src/mscorlib/src/System/Reflection/CustomAttribute.cs
index 463c976357..e568a1702f 100644
--- a/src/mscorlib/src/System/Reflection/CustomAttribute.cs
+++ b/src/mscorlib/src/System/Reflection/CustomAttribute.cs
@@ -29,7 +29,7 @@ namespace System.Reflection
public static IList<CustomAttributeData> GetCustomAttributes(MemberInfo target)
{
if (target == null)
- throw new ArgumentNullException("target");
+ throw new ArgumentNullException(nameof(target));
return target.GetCustomAttributesData();
}
@@ -37,7 +37,7 @@ namespace System.Reflection
public static IList<CustomAttributeData> GetCustomAttributes(Module target)
{
if (target == null)
- throw new ArgumentNullException("target");
+ throw new ArgumentNullException(nameof(target));
Contract.EndContractBlock();
return target.GetCustomAttributesData();
@@ -46,7 +46,7 @@ namespace System.Reflection
public static IList<CustomAttributeData> GetCustomAttributes(Assembly target)
{
if (target == null)
- throw new ArgumentNullException("target");
+ throw new ArgumentNullException(nameof(target));
Contract.EndContractBlock();
return target.GetCustomAttributesData();
@@ -55,7 +55,7 @@ namespace System.Reflection
public static IList<CustomAttributeData> GetCustomAttributes(ParameterInfo target)
{
if (target == null)
- throw new ArgumentNullException("target");
+ throw new ArgumentNullException(nameof(target));
Contract.EndContractBlock();
return target.GetCustomAttributesData();
@@ -63,10 +63,9 @@ namespace System.Reflection
#endregion
#region Internal Static Members
- [System.Security.SecuritySafeCritical] // auto-generated
internal static IList<CustomAttributeData> GetCustomAttributesInternal(RuntimeType target)
{
- Contract.Assert(target != null);
+ Debug.Assert(target != null);
IList<CustomAttributeData> cad = GetCustomAttributes(target.GetRuntimeModule(), target.MetadataToken);
@@ -86,10 +85,9 @@ namespace System.Reflection
return Array.AsReadOnly(pca);
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static IList<CustomAttributeData> GetCustomAttributesInternal(RuntimeFieldInfo target)
{
- Contract.Assert(target != null);
+ Debug.Assert(target != null);
IList<CustomAttributeData> cad = GetCustomAttributes(target.GetRuntimeModule(), target.MetadataToken);
@@ -109,10 +107,9 @@ namespace System.Reflection
return Array.AsReadOnly(pca);
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static IList<CustomAttributeData> GetCustomAttributesInternal(RuntimeMethodInfo target)
{
- Contract.Assert(target != null);
+ Debug.Assert(target != null);
IList<CustomAttributeData> cad = GetCustomAttributes(target.GetRuntimeModule(), target.MetadataToken);
@@ -132,34 +129,30 @@ namespace System.Reflection
return Array.AsReadOnly(pca);
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static IList<CustomAttributeData> GetCustomAttributesInternal(RuntimeConstructorInfo target)
{
- Contract.Assert(target != null);
+ Debug.Assert(target != null);
return GetCustomAttributes(target.GetRuntimeModule(), target.MetadataToken);
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static IList<CustomAttributeData> GetCustomAttributesInternal(RuntimeEventInfo target)
{
- Contract.Assert(target != null);
+ Debug.Assert(target != null);
return GetCustomAttributes(target.GetRuntimeModule(), target.MetadataToken);
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static IList<CustomAttributeData> GetCustomAttributesInternal(RuntimePropertyInfo target)
{
- Contract.Assert(target != null);
+ Debug.Assert(target != null);
return GetCustomAttributes(target.GetRuntimeModule(), target.MetadataToken);
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static IList<CustomAttributeData> GetCustomAttributesInternal(RuntimeModule target)
{
- Contract.Assert(target != null);
+ Debug.Assert(target != null);
if (target.IsResource())
return new List<CustomAttributeData>();
@@ -167,10 +160,9 @@ namespace System.Reflection
return GetCustomAttributes(target, target.MetadataToken);
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static IList<CustomAttributeData> GetCustomAttributesInternal(RuntimeAssembly target)
{
- Contract.Assert(target != null);
+ Debug.Assert(target != null);
IList<CustomAttributeData> cad = GetCustomAttributes((RuntimeModule)target.ManifestModule, RuntimeAssembly.GetToken(target.GetNativeHandle()));
@@ -190,10 +182,9 @@ namespace System.Reflection
return Array.AsReadOnly(pca);
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static IList<CustomAttributeData> GetCustomAttributesInternal(RuntimeParameterInfo target)
{
- Contract.Assert(target != null);
+ Debug.Assert(target != null);
IList<CustomAttributeData> cad = GetCustomAttributes(target.GetRuntimeModule(), target.MetadataToken);
@@ -279,7 +270,7 @@ namespace System.Reflection
if (type.IsValueType)
return CustomAttributeEncoding.Undefined;
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidKindOfTypeForCA"), "type");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidKindOfTypeForCA"), nameof(type));
}
private static CustomAttributeType InitCustomAttributeType(RuntimeType parameterType)
{
@@ -302,7 +293,6 @@ namespace System.Reflection
return new CustomAttributeType(encodedType, encodedArrayType, encodedEnumType, enumName);
}
- [System.Security.SecurityCritical] // auto-generated
private static IList<CustomAttributeData> GetCustomAttributes(RuntimeModule module, int tkTarget)
{
CustomAttributeRecord[] records = GetCustomAttributeRecords(module, tkTarget);
@@ -316,7 +306,6 @@ namespace System.Reflection
#endregion
#region Internal Static Members
- [System.Security.SecurityCritical] // auto-generated
internal unsafe static CustomAttributeRecord[] GetCustomAttributeRecords(RuntimeModule module, int targetToken)
{
MetadataImport scope = module.MetadataImport;
@@ -369,7 +358,6 @@ namespace System.Reflection
{
}
- [System.Security.SecuritySafeCritical] // auto-generated
private CustomAttributeData(RuntimeModule scope, CustomAttributeRecord caRecord)
{
m_scope = scope;
@@ -611,7 +599,7 @@ namespace System.Reflection
public CustomAttributeNamedArgument(MemberInfo memberInfo, object value)
{
if (memberInfo == null)
- throw new ArgumentNullException("memberInfo");
+ throw new ArgumentNullException(nameof(memberInfo));
Type type = null;
FieldInfo field = memberInfo as FieldInfo;
@@ -631,7 +619,7 @@ namespace System.Reflection
public CustomAttributeNamedArgument(MemberInfo memberInfo, CustomAttributeTypedArgument typedArgument)
{
if (memberInfo == null)
- throw new ArgumentNullException("memberInfo");
+ throw new ArgumentNullException(nameof(memberInfo));
m_memberInfo = memberInfo;
m_value = typedArgument;
@@ -749,11 +737,10 @@ namespace System.Reflection
return typeof(object);
default :
- throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)encodedType), "encodedType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)encodedType), nameof(encodedType));
}
}
- [SecuritySafeCritical]
private static object EncodedValueToRawValue(long val, CustomAttributeEncoding encodedType)
{
switch (encodedType)
@@ -795,7 +782,7 @@ namespace System.Reflection
unsafe { return *(double*)&val; }
default:
- throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)val), "val");
+ throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)val), nameof(val));
}
}
private static RuntimeType ResolveType(RuntimeModule scope, string typeName)
@@ -820,7 +807,7 @@ namespace System.Reflection
{
// value can be null.
if (argumentType == null)
- throw new ArgumentNullException("argumentType");
+ throw new ArgumentNullException(nameof(argumentType));
m_value = (value == null) ? null : CanonicalizeValue(value);
m_argumentType = argumentType;
@@ -830,7 +817,7 @@ namespace System.Reflection
{
// value cannot be null.
if (value == null)
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
m_value = CanonicalizeValue(value);
m_argumentType = value.GetType();
@@ -838,7 +825,7 @@ namespace System.Reflection
private static object CanonicalizeValue(object value)
{
- Contract.Assert(value != null);
+ Debug.Assert(value != null);
if (value.GetType().IsEnum)
{
@@ -852,7 +839,7 @@ namespace System.Reflection
CustomAttributeEncoding encodedType = encodedArg.CustomAttributeType.EncodedType;
if (encodedType == CustomAttributeEncoding.Undefined)
- throw new ArgumentException("encodedArg");
+ throw new ArgumentException(null, nameof(encodedArg));
else if (encodedType == CustomAttributeEncoding.Enum)
{
@@ -1015,7 +1002,6 @@ namespace System.Reflection
internal struct CustomAttributeEncodedArgument
{
#region Parser
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void ParseAttributeArguments(
IntPtr pCa,
@@ -1024,18 +1010,17 @@ namespace System.Reflection
ref CustomAttributeNamedParameter[] CustomAttributeTypedArgument,
RuntimeAssembly assembly);
- [System.Security.SecurityCritical] // auto-generated
internal static void ParseAttributeArguments(ConstArray attributeBlob,
ref CustomAttributeCtorParameter[] customAttributeCtorParameters,
ref CustomAttributeNamedParameter[] customAttributeNamedParameters,
RuntimeModule customAttributeModule)
{
if (customAttributeModule == null)
- throw new ArgumentNullException("customAttributeModule");
+ throw new ArgumentNullException(nameof(customAttributeModule));
Contract.EndContractBlock();
- Contract.Assert(customAttributeCtorParameters != null);
- Contract.Assert(customAttributeNamedParameters != null);
+ Debug.Assert(customAttributeCtorParameters != null);
+ Debug.Assert(customAttributeNamedParameters != null);
if (customAttributeCtorParameters.Length != 0 || customAttributeNamedParameters.Length != 0)
{
@@ -1083,7 +1068,7 @@ namespace System.Reflection
public CustomAttributeNamedParameter(string argumentName, CustomAttributeEncoding fieldOrProperty, CustomAttributeType type)
{
if (argumentName == null)
- throw new ArgumentNullException("argumentName");
+ throw new ArgumentNullException(nameof(argumentName));
Contract.EndContractBlock();
m_argumentName = argumentName;
@@ -1131,11 +1116,9 @@ namespace System.Reflection
IntPtr m_Next;
IntPtr m_Assembly;
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern void Push(RuntimeAssembly assembly);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public extern void Pop();
@@ -1183,7 +1166,6 @@ namespace System.Reflection
#endregion
#region Internal Static Members
- [System.Security.SecurityCritical] // auto-generated
internal static bool IsDefined(RuntimeType type, RuntimeType caType, bool inherit)
{
Contract.Requires(type != null);
@@ -1213,7 +1195,6 @@ namespace System.Reflection
return false;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static bool IsDefined(RuntimeMethodInfo method, RuntimeType caType, bool inherit)
{
Contract.Requires(method != null);
@@ -1241,7 +1222,6 @@ namespace System.Reflection
return false;
}
- [System.Security.SecurityCritical] // auto-generated
internal static bool IsDefined(RuntimeConstructorInfo ctor, RuntimeType caType)
{
Contract.Requires(ctor != null);
@@ -1253,7 +1233,6 @@ namespace System.Reflection
return IsCustomAttributeDefined(ctor.GetRuntimeModule(), ctor.MetadataToken, caType);
}
- [System.Security.SecurityCritical] // auto-generated
internal static bool IsDefined(RuntimePropertyInfo property, RuntimeType caType)
{
Contract.Requires(property != null);
@@ -1265,7 +1244,6 @@ namespace System.Reflection
return IsCustomAttributeDefined(property.GetRuntimeModule(), property.MetadataToken, caType);
}
- [System.Security.SecurityCritical] // auto-generated
internal static bool IsDefined(RuntimeEventInfo e, RuntimeType caType)
{
Contract.Requires(e != null);
@@ -1277,7 +1255,6 @@ namespace System.Reflection
return IsCustomAttributeDefined(e.GetRuntimeModule(), e.MetadataToken, caType);
}
- [System.Security.SecurityCritical] // auto-generated
internal static bool IsDefined(RuntimeFieldInfo field, RuntimeType caType)
{
Contract.Requires(field != null);
@@ -1289,7 +1266,6 @@ namespace System.Reflection
return IsCustomAttributeDefined(field.GetRuntimeModule(), field.MetadataToken, caType);
}
- [System.Security.SecurityCritical] // auto-generated
internal static bool IsDefined(RuntimeParameterInfo parameter, RuntimeType caType)
{
Contract.Requires(parameter != null);
@@ -1301,7 +1277,6 @@ namespace System.Reflection
return IsCustomAttributeDefined(parameter.GetRuntimeModule(), parameter.MetadataToken, caType);
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static bool IsDefined(RuntimeAssembly assembly, RuntimeType caType)
{
Contract.Requires(assembly != null);
@@ -1313,7 +1288,6 @@ namespace System.Reflection
return IsCustomAttributeDefined(assembly.ManifestModule as RuntimeModule, RuntimeAssembly.GetToken(assembly.GetNativeHandle()), caType);
}
- [System.Security.SecurityCritical] // auto-generated
internal static bool IsDefined(RuntimeModule module, RuntimeType caType)
{
Contract.Requires(module != null);
@@ -1325,7 +1299,6 @@ namespace System.Reflection
return IsCustomAttributeDefined(module, module.MetadataToken, caType);
}
- [System.Security.SecurityCritical] // auto-generated
internal static Object[] GetCustomAttributes(RuntimeType type, RuntimeType caType, bool inherit)
{
Contract.Requires(type != null);
@@ -1388,7 +1361,7 @@ namespace System.Reflection
else
{
type = type.DeclaringType as RuntimeType;
- Contract.Assert(type != null);
+ Debug.Assert(type != null);
}
}
@@ -1397,16 +1370,7 @@ namespace System.Reflection
private static bool SpecialAllowCriticalAttributes(RuntimeType type)
{
- // Types participating in Type Equivalence are always transparent.
- // See TokenSecurityDescriptor::VerifySemanticDataComputed in securitymeta.cpp.
- // Because of that we allow critical attributes applied to full trust equivalent types.
- // DeclaringType is null for global methods and fields and the global type never participates in type equivalency.
-
-#if FEATURE_CORECLR
return false;
-#else
- return type != null && type.Assembly.IsFullyTrusted && RuntimeTypeHandle.IsEquivalentType(type);
-#endif //!FEATURE_CORECLR
}
private static bool AllowCriticalCustomAttributes(MethodBase method)
@@ -1429,7 +1393,6 @@ namespace System.Reflection
return AllowCriticalCustomAttributes(parameter.DefiningMethod);
}
- [System.Security.SecurityCritical] // auto-generated
internal static Object[] GetCustomAttributes(RuntimeMethodInfo method, RuntimeType caType, bool inherit)
{
Contract.Requires(method != null);
@@ -1474,7 +1437,6 @@ namespace System.Reflection
return typedResult;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static Object[] GetCustomAttributes(RuntimeConstructorInfo ctor, RuntimeType caType)
{
Contract.Requires(ctor != null);
@@ -1487,7 +1449,6 @@ namespace System.Reflection
return attributes;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static Object[] GetCustomAttributes(RuntimePropertyInfo property, RuntimeType caType)
{
Contract.Requires(property != null);
@@ -1506,7 +1467,6 @@ namespace System.Reflection
return attributes;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static Object[] GetCustomAttributes(RuntimeEventInfo e, RuntimeType caType)
{
Contract.Requires(e != null);
@@ -1524,7 +1484,6 @@ namespace System.Reflection
return attributes;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static Object[] GetCustomAttributes(RuntimeFieldInfo field, RuntimeType caType)
{
Contract.Requires(field != null);
@@ -1537,7 +1496,6 @@ namespace System.Reflection
return attributes;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static Object[] GetCustomAttributes(RuntimeParameterInfo parameter, RuntimeType caType)
{
Contract.Requires(parameter != null);
@@ -1550,7 +1508,6 @@ namespace System.Reflection
return attributes;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static Object[] GetCustomAttributes(RuntimeAssembly assembly, RuntimeType caType)
{
Contract.Requires(assembly != null);
@@ -1565,7 +1522,6 @@ namespace System.Reflection
return attributes;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static Object[] GetCustomAttributes(RuntimeModule module, RuntimeType caType)
{
Contract.Requires(module != null);
@@ -1579,20 +1535,17 @@ namespace System.Reflection
return attributes;
}
- [System.Security.SecuritySafeCritical]
internal static bool IsAttributeDefined(RuntimeModule decoratedModule, int decoratedMetadataToken, int attributeCtorToken)
{
return IsCustomAttributeDefined(decoratedModule, decoratedMetadataToken, null, attributeCtorToken, false);
}
- [System.Security.SecurityCritical] // auto-generated
private static bool IsCustomAttributeDefined(
RuntimeModule decoratedModule, int decoratedMetadataToken, RuntimeType attributeFilterType)
{
return IsCustomAttributeDefined(decoratedModule, decoratedMetadataToken, attributeFilterType, 0, false);
}
- [System.Security.SecurityCritical] // auto-generated
private static bool IsCustomAttributeDefined(
RuntimeModule decoratedModule, int decoratedMetadataToken, RuntimeType attributeFilterType, int attributeCtorToken, bool mustBeInheritable)
{
@@ -1604,7 +1557,7 @@ namespace System.Reflection
if (attributeFilterType != null)
{
- Contract.Assert(attributeCtorToken == 0);
+ Debug.Assert(attributeCtorToken == 0);
MetadataImport scope = decoratedModule.MetadataImport;
RuntimeType attributeType;
@@ -1627,8 +1580,8 @@ namespace System.Reflection
}
else
{
- Contract.Assert(attributeFilterType == null);
- Contract.Assert(!MetadataToken.IsNullToken(attributeCtorToken));
+ Debug.Assert(attributeFilterType == null);
+ Debug.Assert(!MetadataToken.IsNullToken(attributeCtorToken));
for (int i = 0; i < car.Length; i++)
{
@@ -1642,14 +1595,12 @@ namespace System.Reflection
return false;
}
- [System.Security.SecurityCritical] // auto-generated
private unsafe static object[] GetCustomAttributes(
RuntimeModule decoratedModule, int decoratedMetadataToken, int pcaCount, RuntimeType attributeFilterType, bool isDecoratedTargetSecurityTransparent)
{
return GetCustomAttributes(decoratedModule, decoratedMetadataToken, pcaCount, attributeFilterType, false, null, isDecoratedTargetSecurityTransparent);
}
- [System.Security.SecurityCritical]
private unsafe static object[] GetCustomAttributes(
RuntimeModule decoratedModule, int decoratedMetadataToken, int pcaCount,
RuntimeType attributeFilterType, bool mustBeInheritable, IList derivedAttributes, bool isDecoratedTargetSecurityTransparent)
@@ -1841,7 +1792,6 @@ namespace System.Reflection
return result;
}
- [System.Security.SecurityCritical] // auto-generated
private unsafe static bool FilterCustomAttributeRecord(
CustomAttributeRecord caRecord,
MetadataImport scope,
@@ -1885,19 +1835,6 @@ namespace System.Reflection
return false;
}
-#if FEATURE_APTCA
- // APTCA checks
- RuntimeAssembly attributeAssembly = (RuntimeAssembly)attributeType.Assembly;
- RuntimeAssembly decoratedModuleAssembly = (RuntimeAssembly)decoratedModule.Assembly;
-
- if (attributeAssembly != lastAptcaOkAssembly &&
- !RuntimeAssembly.AptcaCheck(attributeAssembly, decoratedModuleAssembly))
- return false;
-
- // Cache last successful APTCA check (optimization)
- lastAptcaOkAssembly = decoratedModuleAssembly;
-#endif // FEATURE_APTCA
-
// Resolve the attribute ctor
ConstArray ctorSig = scope.GetMethodSignature(caRecord.tkCtor);
isVarArg = (ctorSig[0] & 0x05) != 0;
@@ -1944,7 +1881,7 @@ namespace System.Reflection
else
{
// We need to relax this when we add support for other types of decorated tokens.
- Contract.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.");
}
@@ -1959,7 +1896,6 @@ namespace System.Reflection
#endregion
#region Private Static Methods
- [System.Security.SecurityCritical] // auto-generated
private static bool AttributeUsageCheck(
RuntimeType attributeType, bool mustBeInheritable, object[] attributes, IList derivedAttributes)
{
@@ -1992,7 +1928,6 @@ namespace System.Reflection
return true;
}
- [System.Security.SecurityCritical] // auto-generated
internal static AttributeUsageAttribute GetAttributeUsage(RuntimeType decoratedAttribute)
{
RuntimeModule decoratedModule = decoratedAttribute.GetRuntimeModule();
@@ -2027,11 +1962,9 @@ namespace System.Reflection
#endregion
#region Private Static FCalls
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void _ParseAttributeUsageAttribute(
IntPtr pCa, int cCa, out int targets, out bool inherited, out bool allowMultiple);
- [System.Security.SecurityCritical] // auto-generated
private static void ParseAttributeUsageAttribute(
ConstArray ca, out AttributeTargets targets, out bool inherited, out bool allowMultiple)
{
@@ -2040,10 +1973,8 @@ namespace System.Reflection
targets = (AttributeTargets)_targets;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static unsafe extern Object _CreateCaObject(RuntimeModule pModule, IRuntimeMethodInfo pCtor, byte** ppBlob, byte* pEndBlob, int* pcNamedArgs);
- [System.Security.SecurityCritical] // auto-generated
private static unsafe Object CreateCaObject(RuntimeModule module, IRuntimeMethodInfo ctor, ref IntPtr blob, IntPtr blobEnd, out int namedArgs)
{
byte* pBlob = (byte*)blob;
@@ -2055,11 +1986,9 @@ namespace System.Reflection
return ca;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private unsafe extern static void _GetPropertyOrFieldData(
RuntimeModule pModule, byte** ppBlobStart, byte* pBlobEnd, out string name, out bool bIsProperty, out RuntimeType type, out object value);
- [System.Security.SecurityCritical] // auto-generated
private unsafe static void GetPropertyOrFieldData(
RuntimeModule module, ref IntPtr blobStart, IntPtr blobEnd, out string name, out bool isProperty, out RuntimeType type, out object value)
{
@@ -2069,7 +1998,6 @@ namespace System.Reflection
blobStart = (IntPtr)pBlobStart;
}
- [System.Security.SecuritySafeCritical]
private static object[] CreateAttributeArrayHelper(Type elementType, int elementCount)
{
return (object[])Array.UnsafeCreateInstance(elementType, elementCount);
@@ -2089,18 +2017,13 @@ namespace System.Reflection
#endregion
#region FCalls
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- unsafe private static extern void _GetSecurityAttributes(RuntimeModule module, int token, bool assembly, out object[] securityAttributes);
- [System.Security.SecurityCritical] // auto-generated
- unsafe internal static void GetSecurityAttributes(RuntimeModule module, int token, bool assembly, out object[] securityAttributes)
+ internal static void GetSecurityAttributes(RuntimeModule module, int token, bool assembly, out object[] securityAttributes)
{
- _GetSecurityAttributes(module.GetNativeHandle(), token, assembly, out securityAttributes);
+ securityAttributes = null;
}
#endregion
#region Static Constructor
- [System.Security.SecurityCritical] // auto-generated
static PseudoCustomAttribute()
{
RuntimeType[] pcas = new RuntimeType[]
@@ -2130,21 +2053,20 @@ namespace System.Reflection
s_pca = temp_pca;
}
- [System.Security.SecurityCritical] // auto-generated
[Conditional("_DEBUG")]
private static void VerifyPseudoCustomAttribute(RuntimeType pca)
{
// If any of these are invariants are no longer true will have to
// re-architect the PCA product logic and test cases -- you've been warned!
- Contract.Assert(pca.BaseType == (RuntimeType)typeof(Attribute), "Pseudo CA Error");
+ Debug.Assert(pca.BaseType == (RuntimeType)typeof(Attribute), "Pseudo CA Error");
AttributeUsageAttribute usage = CustomAttribute.GetAttributeUsage(pca);
- Contract.Assert(usage.Inherited == false, "Pseudo CA Error");
+ Debug.Assert(usage.Inherited == false, "Pseudo CA Error");
//AllowMultiple is true for TypeForwardedToAttribute
- //Contract.Assert(usage.AllowMultiple == false, "Pseudo CA Error");
+ //Debug.Assert(usage.AllowMultiple == false, "Pseudo CA Error");
}
- #endregion
+#endregion
- #region Internal Static
+#region Internal Static
internal static bool IsSecurityAttribute(RuntimeType type)
{
#pragma warning disable 618
@@ -2152,7 +2074,6 @@ namespace System.Reflection
#pragma warning restore 618
}
- [System.Security.SecurityCritical] // auto-generated
internal static Attribute[] GetCustomAttributes(RuntimeType type, RuntimeType caType, bool includeSecCa, out int count)
{
Contract.Requires(type != null);
@@ -2196,7 +2117,6 @@ namespace System.Reflection
count = pcas.Count;
return pcas.ToArray();
}
- [System.Security.SecurityCritical] // auto-generated
internal static bool IsDefined(RuntimeType type, RuntimeType caType)
{
bool all = caType == (RuntimeType)typeof(object) || caType == (RuntimeType)typeof(Attribute);
@@ -2221,7 +2141,6 @@ namespace System.Reflection
return false;
}
- [System.Security.SecurityCritical] // auto-generated
internal static Attribute[] GetCustomAttributes(RuntimeMethodInfo method, RuntimeType caType, bool includeSecCa, out int count)
{
Contract.Requires(method != null);
@@ -2260,7 +2179,6 @@ namespace System.Reflection
count = pcas.Count;
return pcas.ToArray();
}
- [System.Security.SecurityCritical] // auto-generated
internal static bool IsDefined(RuntimeMethodInfo method, RuntimeType caType)
{
bool all = caType == (RuntimeType)typeof(object) || caType == (RuntimeType)typeof(Attribute);
@@ -2286,7 +2204,6 @@ namespace System.Reflection
return false;
}
- [System.Security.SecurityCritical] // auto-generated
internal static Attribute[] GetCustomAttributes(RuntimeParameterInfo parameter, RuntimeType caType, out int count)
{
Contract.Requires(parameter != null);
@@ -2323,7 +2240,6 @@ namespace System.Reflection
}
return pcas;
}
- [System.Security.SecurityCritical] // auto-generated
internal static bool IsDefined(RuntimeParameterInfo parameter, RuntimeType caType)
{
bool all = caType == (RuntimeType)typeof(object) || caType == (RuntimeType)typeof(Attribute);
@@ -2351,7 +2267,6 @@ namespace System.Reflection
return false;
}
- [System.Security.SecurityCritical] // auto-generated
internal static Attribute[] GetCustomAttributes(RuntimeAssembly assembly, RuntimeType caType, bool includeSecCa, out int count)
{
count = 0;
@@ -2386,7 +2301,6 @@ namespace System.Reflection
count = pcas.Count;
return pcas.ToArray();
}
- [System.Security.SecurityCritical] // auto-generated
internal static bool IsDefined(RuntimeAssembly assembly, RuntimeType caType)
{
int count;
@@ -2403,7 +2317,6 @@ namespace System.Reflection
return false;
}
- [System.Security.SecurityCritical] // auto-generated
internal static Attribute[] GetCustomAttributes(RuntimeFieldInfo field, RuntimeType caType, out int count)
{
Contract.Requires(field != null);
@@ -2435,7 +2348,6 @@ namespace System.Reflection
}
return pcas;
}
- [System.Security.SecurityCritical] // auto-generated
internal static bool IsDefined(RuntimeFieldInfo field, RuntimeType caType)
{
bool all = caType == (RuntimeType)typeof(object) || caType == (RuntimeType)typeof(Attribute);
@@ -2458,7 +2370,6 @@ namespace System.Reflection
return false;
}
- [System.Security.SecurityCritical] // auto-generated
internal static Attribute[] GetCustomAttributes(RuntimeConstructorInfo ctor, RuntimeType caType, bool includeSecCa, out int count)
{
count = 0;
@@ -2484,7 +2395,6 @@ namespace System.Reflection
count = pcas.Count;
return pcas.ToArray();
}
- [System.Security.SecurityCritical] // auto-generated
internal static bool IsDefined(RuntimeConstructorInfo ctor, RuntimeType caType)
{
bool all = caType == (RuntimeType)typeof(object) || caType == (RuntimeType)typeof(Attribute);
@@ -2522,6 +2432,6 @@ namespace System.Reflection
{
return false;
}
- #endregion
+#endregion
}
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/AQNBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/AQNBuilder.cs
index 6484677c62..fb9324902a 100644
--- a/src/mscorlib/src/System/Reflection/Emit/AQNBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/AQNBuilder.cs
@@ -22,59 +22,45 @@ namespace System.Reflection.Emit
}
#region QCalls
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern IntPtr CreateTypeNameBuilder();
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void ReleaseTypeNameBuilder(IntPtr pAQN);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void OpenGenericArguments(IntPtr tnb);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void CloseGenericArguments(IntPtr tnb);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void OpenGenericArgument(IntPtr tnb);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void CloseGenericArgument(IntPtr tnb);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void AddName(IntPtr tnb, string name);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void AddPointer(IntPtr tnb);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void AddByRef(IntPtr tnb);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void AddSzArray(IntPtr tnb);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void AddArray(IntPtr tnb, int rank);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void AddAssemblySpec(IntPtr tnb, string assemblySpec);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void ToString(IntPtr tnb, StringHandleOnStack retString);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void Clear(IntPtr tnb);
@@ -83,7 +69,6 @@ namespace System.Reflection.Emit
#region Static Members
// TypeNameBuilder is NOT thread safe NOR reliable
- [System.Security.SecuritySafeCritical] // auto-generated
internal static string ToString(Type type, Format format)
{
if (format == Format.FullName || format == Format.AssemblyQualifiedName)
@@ -107,12 +92,10 @@ namespace System.Reflection.Emit
#region Constructor
private TypeNameBuilder(IntPtr typeNameBuilder) { m_typeNameBuilder = typeNameBuilder; }
- [System.Security.SecurityCritical] // auto-generated
internal void Dispose() { ReleaseTypeNameBuilder(m_typeNameBuilder); }
#endregion
#region private Members
- [System.Security.SecurityCritical] // auto-generated
private void AddElementType(Type elementType)
{
if (elementType.HasElementType)
@@ -131,7 +114,6 @@ namespace System.Reflection.Emit
AddArray(elementType.GetArrayRank());
}
- [System.Security.SecurityCritical] // auto-generated
private void ConstructAssemblyQualifiedNameWorker(Type type, Format format)
{
Type rootType = type;
@@ -179,29 +161,17 @@ namespace System.Reflection.Emit
AddAssemblySpec(type.Module.Assembly.FullName);
}
- [System.Security.SecurityCritical] // auto-generated
private void OpenGenericArguments() { OpenGenericArguments(m_typeNameBuilder); }
- [System.Security.SecurityCritical] // auto-generated
private void CloseGenericArguments() { CloseGenericArguments(m_typeNameBuilder); }
- [System.Security.SecurityCritical] // auto-generated
private void OpenGenericArgument() { OpenGenericArgument(m_typeNameBuilder); }
- [System.Security.SecurityCritical] // auto-generated
private void CloseGenericArgument() { CloseGenericArgument(m_typeNameBuilder); }
- [System.Security.SecurityCritical] // auto-generated
private void AddName(string name) { AddName(m_typeNameBuilder, name); }
- [System.Security.SecurityCritical] // auto-generated
private void AddPointer() { AddPointer(m_typeNameBuilder); }
- [System.Security.SecurityCritical] // auto-generated
private void AddByRef() { AddByRef(m_typeNameBuilder); }
- [System.Security.SecurityCritical] // auto-generated
private void AddSzArray() { AddSzArray(m_typeNameBuilder); }
- [System.Security.SecurityCritical] // auto-generated
private void AddArray(int rank) { AddArray(m_typeNameBuilder, rank); }
- [System.Security.SecurityCritical] // auto-generated
private void AddAssemblySpec(string assemblySpec) { AddAssemblySpec(m_typeNameBuilder, assemblySpec); }
- [System.Security.SecuritySafeCritical] // auto-generated
public override string ToString() { string ret = null; ToString(m_typeNameBuilder, JitHelpers.GetStringHandleOnStack(ref ret)); return ret; }
- [System.Security.SecurityCritical] // auto-generated
private void Clear() { Clear(m_typeNameBuilder); }
#endregion
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilder.cs
index 5e7f83f2df..9331ae193c 100644
--- a/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilder.cs
@@ -98,17 +98,11 @@ namespace System.Reflection.Emit
throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
public override FileStream GetFile(String name)
{
throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
public override FileStream[] GetFiles(bool getResourceModules)
{
throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
@@ -131,9 +125,6 @@ namespace System.Reflection.Emit
public override String Location
{
-#if FEATURE_CORECLR
- [SecurityCritical]
-#endif // FEATURE_CORECLR
get
{
throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
@@ -142,9 +133,6 @@ namespace System.Reflection.Emit
public override String CodeBase
{
-#if FEATURE_CORECLR
- [SecurityCritical]
-#endif // FEATURE_CORECLR
get
{
throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
@@ -168,43 +156,20 @@ namespace System.Reflection.Emit
// AssemblyBuilder class.
// deliberately not [serializable]
- [HostProtection(MayLeakOnAbort = true)]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_AssemblyBuilder))]
[ComVisible(true)]
public sealed class AssemblyBuilder : Assembly, _AssemblyBuilder
{
#region FCALL
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern RuntimeModule GetInMemoryAssemblyModule(RuntimeAssembly assembly);
- [System.Security.SecurityCritical] // auto-generated
private Module nGetInMemoryAssemblyModule()
{
return AssemblyBuilder.GetInMemoryAssemblyModule(GetNativeHandle());
}
-#if !FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern RuntimeModule GetOnDiskAssemblyModule(RuntimeAssembly assembly);
-
- [System.Security.SecurityCritical] // auto-generated
- private ModuleBuilder GetOnDiskAssemblyModuleBuilder()
- {
- if (m_onDiskAssemblyModuleBuilder == null)
- {
- Module module = AssemblyBuilder.GetOnDiskAssemblyModule(InternalAssembly.GetNativeHandle());
- ModuleBuilder modBuilder = new ModuleBuilder(this, (InternalModuleBuilder)module);
- modBuilder.Init("RefEmit_OnDiskManifestModule", null, 0);
- m_onDiskAssemblyModuleBuilder = modBuilder;
- }
-
- return m_onDiskAssemblyModuleBuilder;
- }
-#endif // FEATURE_CORECLR
-
#endregion
#region Internal Data Members
@@ -215,9 +180,6 @@ namespace System.Reflection.Emit
// Set to true if the manifest module was returned by code:DefineDynamicModule to the user
private bool m_fManifestModuleUsedAsDefinedModule;
internal const string MANIFEST_MODULE_NAME = "RefEmit_InMemoryManifestModule";
-#if !FEATURE_CORECLR
- private ModuleBuilder m_onDiskAssemblyModuleBuilder;
-#endif // !FEATURE_CORECLR
#if FEATURE_APPX
private bool m_profileAPICheck;
@@ -226,27 +188,15 @@ namespace System.Reflection.Emit
internal ModuleBuilder GetModuleBuilder(InternalModuleBuilder module)
{
Contract.Requires(module != null);
- Contract.Assert(this.InternalAssembly == module.Assembly);
+ Debug.Assert(this.InternalAssembly == module.Assembly);
lock(SyncRoot)
{
-#if !FEATURE_CORECLR
- foreach (ModuleBuilder modBuilder in m_assemblyData.m_moduleBuilderList)
- {
- if (modBuilder.InternalModule == module)
- return modBuilder;
- }
-
- // m_onDiskAssemblyModuleBuilder is null before Save
- if (m_onDiskAssemblyModuleBuilder != null && m_onDiskAssemblyModuleBuilder.InternalModule == module)
- return m_onDiskAssemblyModuleBuilder;
-#endif // !FEATURE_CORECLR
-
// in CoreCLR there is only one module in each dynamic assembly, the manifest module
if (m_manifestModuleBuilder.InternalModule == module)
return m_manifestModuleBuilder;
- throw new ArgumentException("module");
+ throw new ArgumentException(null, nameof(module));
}
}
@@ -271,7 +221,6 @@ namespace System.Reflection.Emit
return InternalAssembly.GetNativeHandle();
}
- [SecurityCritical]
internal Version GetVersion()
{
return InternalAssembly.GetVersion();
@@ -289,7 +238,6 @@ namespace System.Reflection.Emit
#endregion
#region Constructor
- [System.Security.SecurityCritical] // auto-generated
internal AssemblyBuilder(AppDomain domain,
AssemblyName name,
AssemblyBuilderAccess access,
@@ -303,13 +251,9 @@ namespace System.Reflection.Emit
SecurityContextSource securityContextSource)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (access != AssemblyBuilderAccess.Run
-#if !FEATURE_CORECLR
- && access != AssemblyBuilderAccess.Save
- && access != AssemblyBuilderAccess.RunAndSave
-#endif // !FEATURE_CORECLR
#if FEATURE_REFLECTION_ONLY_LOAD
&& access != AssemblyBuilderAccess.ReflectionOnly
#endif // FEATURE_REFLECTION_ONLY_LOAD
@@ -318,25 +262,17 @@ namespace System.Reflection.Emit
#endif // FEATURE_COLLECTIBLE_TYPES
)
{
- throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)access), "access");
+ throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)access), nameof(access));
}
if (securityContextSource < SecurityContextSource.CurrentAppDomain ||
securityContextSource > SecurityContextSource.CurrentAssembly)
{
- throw new ArgumentOutOfRangeException("securityContextSource");
+ throw new ArgumentOutOfRangeException(nameof(securityContextSource));
}
// Clone the name in case the caller modifies it underneath us.
name = (AssemblyName)name.Clone();
-
-#if !FEATURE_CORECLR
- // Set the public key from the key pair if one has been provided.
- // (Overwite any public key in the Assembly name, since it's no
- // longer valid to have a disparity).
- if (name.KeyPair != null)
- name.SetPublicKey(name.KeyPair.PublicKey);
-#endif
// If the caller is trusted they can supply identity
// evidence for the new assembly. Otherwise we copy the
@@ -350,13 +286,6 @@ namespace System.Reflection.Emit
new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand();
#pragma warning restore 618
-#if FEATURE_COLLECTIBLE_TYPES && !FEATURE_CORECLR
- // Collectible assemblies require FullTrust. This demand may be removed if we deem the
- // feature robust enough to be used directly by untrusted API consumers.
- if (access == AssemblyBuilderAccess.RunAndCollect)
- new PermissionSet(PermissionState.Unrestricted).Demand();
-#endif // FEATURE_COLLECTIBLE_TYPES && !FEATURE_CORECLR
-
// Scan the assembly level attributes for any attributes which modify how we create the
// assembly. Currently, we look for any attribute which modifies the security transparency
// of the assembly.
@@ -379,41 +308,10 @@ namespace System.Reflection.Emit
}
else if (attribute.m_con.DeclaringType == typeof(SecurityCriticalAttribute))
{
-#if !FEATURE_CORECLR
- SecurityCriticalScope scope = SecurityCriticalScope.Everything;
- if (attribute.m_constructorArgs != null &&
- attribute.m_constructorArgs.Length == 1 &&
- attribute.m_constructorArgs[0] is SecurityCriticalScope)
- {
- scope = (SecurityCriticalScope)attribute.m_constructorArgs[0];
- }
-
- assemblyFlags |= DynamicAssemblyFlags.Critical;
- if (scope == SecurityCriticalScope.Everything)
-#endif // !FEATURE_CORECLR
{
assemblyFlags |= DynamicAssemblyFlags.AllCritical;
}
}
-#if !FEATURE_CORECLR
- else if (attribute.m_con.DeclaringType == typeof(SecurityRulesAttribute))
- {
- securityRulesBlob = new byte[attribute.m_blob.Length];
- Buffer.BlockCopy(attribute.m_blob, 0, securityRulesBlob, 0, securityRulesBlob.Length);
- }
- else if (attribute.m_con.DeclaringType == typeof(SecurityTreatAsSafeAttribute))
- {
- assemblyFlags |= DynamicAssemblyFlags.TreatAsSafe;
- }
-#endif // !FEATURE_CORECLR
-#if FEATURE_APTCA
- else if (attribute.m_con.DeclaringType == typeof(AllowPartiallyTrustedCallersAttribute))
- {
- assemblyFlags |= DynamicAssemblyFlags.Aptca;
- aptcaBlob = new byte[attribute.m_blob.Length];
- Buffer.BlockCopy(attribute.m_blob, 0, aptcaBlob, 0, aptcaBlob.Length);
- }
-#endif // FEATURE_APTCA
}
#pragma warning restore 618
}
@@ -458,7 +356,6 @@ namespace System.Reflection.Emit
}
}
- [System.Security.SecurityCritical] // auto-generated
private void InitManifestModule()
{
InternalModuleBuilder modBuilder = (InternalModuleBuilder)nGetInMemoryAssemblyModule();
@@ -487,7 +384,6 @@ namespace System.Reflection.Emit
* to have a strong name and a hash will be computed when the assembly
* is saved.
**********************************************/
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static AssemblyBuilder DefineDynamicAssembly(
AssemblyName name,
@@ -500,7 +396,6 @@ namespace System.Reflection.Emit
null, null, null, null, ref stackMark, null, SecurityContextSource.CurrentAssembly);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static AssemblyBuilder DefineDynamicAssembly(
AssemblyName name,
@@ -518,7 +413,6 @@ namespace System.Reflection.Emit
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern Assembly nCreateDynamicAssembly(AppDomain domain,
AssemblyName name,
@@ -535,7 +429,6 @@ namespace System.Reflection.Emit
private class AssemblyBuilderLock { }
- [System.Security.SecurityCritical] // auto-generated
internal static AssemblyBuilder InternalDefineDynamicAssembly(
AssemblyName name,
AssemblyBuilderAccess access,
@@ -548,13 +441,6 @@ namespace System.Reflection.Emit
IEnumerable<CustomAttributeBuilder> unsafeAssemblyAttributes,
SecurityContextSource securityContextSource)
{
-#if FEATURE_CAS_POLICY
- if (evidence != null && !AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
- }
-#endif // FEATURE_CAS_POLICY
-
lock (typeof(AssemblyBuilderLock))
{
// we can only create dynamic assemblies in the current domain
@@ -581,7 +467,6 @@ namespace System.Reflection.Emit
* a transient module.
*
**********************************************/
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public ModuleBuilder DefineDynamicModule(
String name)
@@ -592,7 +477,6 @@ namespace System.Reflection.Emit
return DefineDynamicModuleInternal(name, false, ref stackMark);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public ModuleBuilder DefineDynamicModule(
String name,
@@ -604,7 +488,6 @@ namespace System.Reflection.Emit
return DefineDynamicModuleInternal( name, emitSymbolInfo, ref stackMark );
}
- [System.Security.SecurityCritical] // auto-generated
private ModuleBuilder DefineDynamicModuleInternal(
String name,
bool emitSymbolInfo, // specify if emit symbol info or not
@@ -616,115 +499,38 @@ namespace System.Reflection.Emit
}
}
- [System.Security.SecurityCritical] // auto-generated
private ModuleBuilder DefineDynamicModuleInternalNoLock(
String name,
bool emitSymbolInfo, // specify if emit symbol info or not
ref StackCrawlMark stackMark)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (name.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name));
if (name[0] == '\0')
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidName"), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidName"), nameof(name));
Contract.Ensures(Contract.Result<ModuleBuilder>() != null);
Contract.EndContractBlock();
BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.DefineDynamicModule( " + name + " )");
- Contract.Assert(m_assemblyData != null, "m_assemblyData is null in DefineDynamicModuleInternal");
+ Debug.Assert(m_assemblyData != null, "m_assemblyData is null in DefineDynamicModuleInternal");
ModuleBuilder dynModule;
ISymbolWriter writer = null;
IntPtr pInternalSymWriter = new IntPtr();
- // create the dynamic module
-
-#if FEATURE_MULTIMODULE_ASSEMBLIES
-
-#if FEATURE_CORECLR
-#error FEATURE_MULTIMODULE_ASSEMBLIES should always go with !FEATURE_CORECLR
-#endif //FEATURE_CORECLR
-
- m_assemblyData.CheckNameConflict(name);
-
- if (m_fManifestModuleUsedAsDefinedModule == true)
- { // We need to define a new module
- int tkFile;
- InternalModuleBuilder internalDynModule = (InternalModuleBuilder)DefineDynamicModule(
- InternalAssembly,
- emitSymbolInfo,
- name,
- name,
- ref stackMark,
- ref pInternalSymWriter,
- true /*fIsTransient*/,
- out tkFile);
- dynModule = new ModuleBuilder(this, internalDynModule);
-
- // initialize the dynamic module's managed side information
- dynModule.Init(name, null, tkFile);
- }
- else
- { // We will reuse the manifest module
- m_manifestModuleBuilder.ModifyModuleName(name);
- dynModule = m_manifestModuleBuilder;
-
- if (emitSymbolInfo)
- {
- pInternalSymWriter = ModuleBuilder.nCreateISymWriterForDynamicModule(dynModule.InternalModule, name);
- }
- }
-
-#else // FEATURE_MULTIMODULE_ASSEMBLIES
- // Without FEATURE_MULTIMODULE_ASSEMBLIES only one ModuleBuilder per AssemblyBuilder can be created
+ // create the dynamic module- only one ModuleBuilder per AssemblyBuilder can be created
if (m_fManifestModuleUsedAsDefinedModule == true)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NoMultiModuleAssembly"));
// Init(...) has already been called on m_manifestModuleBuilder in InitManifestModule()
dynModule = m_manifestModuleBuilder;
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
// Create the symbol writer
if (emitSymbolInfo)
{
-#if FEATURE_MULTIMODULE_ASSEMBLIES && !FEATURE_CORECLR
- // this is the code path for the desktop runtime
-
- // create the default SymWriter
- Assembly assem = LoadISymWrapper();
- Type symWriter = assem.GetType("System.Diagnostics.SymbolStore.SymWriter", true, false);
- if (symWriter != null && !symWriter.IsVisible)
- symWriter = null;
-
- if (symWriter == null)
- {
- // cannot find SymWriter - throw TypeLoadException since we couldnt find the type.
- throw new TypeLoadException(Environment.GetResourceString(ResId.MissingType, "SymWriter"));
- }
-
- new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
-
- try
- {
- (new PermissionSet(PermissionState.Unrestricted)).Assert();
- writer = (ISymbolWriter)Activator.CreateInstance(symWriter);
-
- // Set the underlying writer for the managed writer
- // that we're using. Note that this function requires
- // unmanaged code access.
- writer.SetUnderlyingWriter(pInternalSymWriter);
- }
- finally
- {
- CodeAccessPermission.RevertAssert();
- }
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES && !FEATURE_CORECLR
-
-#if !FEATURE_MULTIMODULE_ASSEMBLIES && FEATURE_CORECLR
- // this is the code path for CoreCLR
-
writer = SymWrapperCore.SymWriter.CreateSymWriter();
// Set the underlying writer for the managed writer
// that we're using. Note that this function requires
@@ -741,7 +547,6 @@ namespace System.Reflection.Emit
// In Telesto, we took the SetUnderlyingWriter method private as it's a very rickety method.
// This might someday be a good move for the desktop CLR too.
((SymWrapperCore.SymWriter)writer).InternalSetUnderlyingWriter(pInternalSymWriter);
-#endif // !FEATURE_MULTIMODULE_ASSEMBLIES && FEATURE_CORECLR
} // Creating the symbol writer
dynModule.SetSymWriter(writer);
@@ -754,174 +559,6 @@ namespace System.Reflection.Emit
return dynModule;
} // DefineDynamicModuleInternalNoLock
-
-#if !FEATURE_CORECLR
- // All dynamic modules in SilverLight are transient so we removed this overload of DefineDynamicModule
- // Note that it is assumed that !FEATURE_CORECLR always goes with FEATURE_MULTIMODULE_ASSEMBLIES
- // If we ever will build a non coreclr version of the runtime without FEATURE_MULTIMODULE_ASSEMBLIES
- // we will need to make the same changes here as the ones we made in the transient overload
-
- /**********************************************
- *
- * Defines a named dynamic module. It is an error to define multiple
- * modules within an Assembly with the same name. No symbol information
- * will be emitted.
- *
- **********************************************/
- [System.Security.SecuritySafeCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public ModuleBuilder DefineDynamicModule(
- String name,
- String fileName)
- {
- Contract.Ensures(Contract.Result<ModuleBuilder>() != null);
-
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
-
- // delegate to the next DefineDynamicModule
- return DefineDynamicModuleInternal(name, fileName, false, ref stackMark);
- }
-
- /**********************************************
- *
- * Emit symbol information if emitSymbolInfo is true using the
- * default symbol writer interface.
- * An exception will be thrown if the assembly is transient.
- *
- **********************************************/
- [System.Security.SecuritySafeCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public ModuleBuilder DefineDynamicModule(
- String name, // module name
- String fileName, // module file name
- bool emitSymbolInfo) // specify if emit symbol info or not
- {
- Contract.Ensures(Contract.Result<ModuleBuilder>() != null);
-
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return DefineDynamicModuleInternal(name, fileName, emitSymbolInfo, ref stackMark);
- }
-
- [System.Security.SecurityCritical] // auto-generated
- private ModuleBuilder DefineDynamicModuleInternal(
- String name, // module name
- String fileName, // module file name
- bool emitSymbolInfo, // specify if emit symbol info or not
- ref StackCrawlMark stackMark) // stack crawl mark used to find caller
- {
- lock(SyncRoot)
- {
- return DefineDynamicModuleInternalNoLock(name, fileName, emitSymbolInfo, ref stackMark);
- }
- }
-
- // "name" will be used for:
- // 1. The Name field in the Module table.
- // 2. ModuleBuilder.GetModule(string).
- // "fileName" will be used for:
- // 1. The name field in the ModuleRef table when this module is being referenced by
- // another module in the same assembly.
- // 2. .file record in the in memory assembly manifest when the module is created in memory
- // 3. .file record in the on disk assembly manifest when the assembly is saved to disk
- // 4. The file name of the saved module.
- [System.Security.SecurityCritical] // auto-generated
- private ModuleBuilder DefineDynamicModuleInternalNoLock(
- String name, // module name
- String fileName, // module file name
- bool emitSymbolInfo, // specify if emit symbol info or not
- ref StackCrawlMark stackMark) // stack crawl mark used to find caller
- {
- if (name == null)
- throw new ArgumentNullException("name");
- if (name.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
- if (name[0] == '\0')
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidName"), "name");
-
- if (fileName == null)
- throw new ArgumentNullException("fileName");
- if (fileName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "fileName");
- if (!String.Equals(fileName, Path.GetFileName(fileName)))
- throw new ArgumentException(Environment.GetResourceString("Argument_NotSimpleFileName"), "fileName");
- Contract.Ensures(Contract.Result<ModuleBuilder>() != null);
- Contract.EndContractBlock();
-
- BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.DefineDynamicModule( " + name + ", " + fileName + ", " + emitSymbolInfo + " )");
- if (m_assemblyData.m_access == AssemblyBuilderAccess.Run)
- {
- // Error! You cannot define a persistable module within a transient data.
- throw new NotSupportedException(Environment.GetResourceString("Argument_BadPersistableModuleInTransientAssembly"));
- }
-
- if (m_assemblyData.m_isSaved == true)
- {
- // assembly has been saved before!
- throw new InvalidOperationException(Environment.GetResourceString(
- "InvalidOperation_CannotAlterAssembly"));
- }
-
- ModuleBuilder dynModule;
- ISymbolWriter writer = null;
- IntPtr pInternalSymWriter = new IntPtr();
-
- // create the dynamic module
-
- m_assemblyData.CheckNameConflict(name);
- m_assemblyData.CheckFileNameConflict(fileName);
-
- int tkFile;
- InternalModuleBuilder internalDynModule = (InternalModuleBuilder)DefineDynamicModule(
- InternalAssembly,
- emitSymbolInfo,
- name,
- fileName,
- ref stackMark,
- ref pInternalSymWriter,
- false /*fIsTransient*/,
- out tkFile);
- dynModule = new ModuleBuilder(this, internalDynModule);
-
- // initialize the dynamic module's managed side information
- dynModule.Init(name, fileName, tkFile);
-
- // Create the symbol writer
- if (emitSymbolInfo)
- {
- // create the default SymWriter
- Assembly assem = LoadISymWrapper();
- Type symWriter = assem.GetType("System.Diagnostics.SymbolStore.SymWriter", true, false);
- if (symWriter != null && !symWriter.IsVisible)
- symWriter = null;
-
- if (symWriter == null)
- {
- // cannot find SymWriter - throw TypeLoadException since we couldnt find the type.
- throw new TypeLoadException(Environment.GetResourceString("MissingType", "SymWriter"));
- }
- try
- {
- (new PermissionSet(PermissionState.Unrestricted)).Assert();
- writer = (ISymbolWriter)Activator.CreateInstance(symWriter);
-
- // Set the underlying writer for the managed writer
- // that we're using. Note that this function requires
- // unmanaged code access.
- writer.SetUnderlyingWriter(pInternalSymWriter);
- }
- finally
- {
- CodeAccessPermission.RevertAssert();
- }
- }
-
- dynModule.SetSymWriter(writer);
-
- m_assemblyData.AddModule(dynModule);
-
- return dynModule;
- } // DefineDynamicModuleInternalNoLock
-#endif // !FEATURE_CORECLR
#endregion
private Assembly LoadISymWrapper()
@@ -970,170 +607,6 @@ namespace System.Reflection.Emit
}
}
-#if !FEATURE_CORECLR
- /**********************************************
- *
- * Define stand alone managed resource for Assembly
- *
- **********************************************/
- public IResourceWriter DefineResource(
- String name,
- String description,
- String fileName)
- {
- return DefineResource(name, description, fileName, ResourceAttributes.Public);
- }
-
- /**********************************************
- *
- * Define stand alone managed resource for Assembly
- *
- **********************************************/
- public IResourceWriter DefineResource(
- String name,
- String description,
- String fileName,
- ResourceAttributes attribute)
- {
- lock(SyncRoot)
- {
- return DefineResourceNoLock(name, description, fileName, attribute);
- }
- }
-
- private IResourceWriter DefineResourceNoLock(
- String name,
- String description,
- String fileName,
- ResourceAttributes attribute)
- {
- if (name == null)
- throw new ArgumentNullException("name");
- if (name.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), name);
- if (fileName == null)
- throw new ArgumentNullException("fileName");
- if (fileName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "fileName");
- if (!String.Equals(fileName, Path.GetFileName(fileName)))
- throw new ArgumentException(Environment.GetResourceString("Argument_NotSimpleFileName"), "fileName");
- Contract.EndContractBlock();
-
- BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.DefineResource( " + name + ", " + fileName + ")");
-
- m_assemblyData.CheckResNameConflict(name);
- m_assemblyData.CheckFileNameConflict(fileName);
-
- ResourceWriter resWriter;
- String fullFileName;
-
- if (m_assemblyData.m_strDir == null)
- {
- // If assembly directory is null, use current directory
- fullFileName = Path.Combine(Directory.GetCurrentDirectory(), fileName);
- resWriter = new ResourceWriter(fullFileName);
- }
- else
- {
- // Form the full path given the directory provided by user
- fullFileName = Path.Combine(m_assemblyData.m_strDir, fileName);
- resWriter = new ResourceWriter(fullFileName);
- }
- // get the full path
- fullFileName = Path.GetFullPath(fullFileName);
-
- // retrieve just the file name
- fileName = Path.GetFileName(fullFileName);
-
- m_assemblyData.AddResWriter( new ResWriterData( resWriter, null, name, fileName, fullFileName, attribute) );
- return resWriter;
- }
-
-#endif // !FEATURE_CORECLR
-
- /**********************************************
- *
- * Add an existing resource file to the Assembly
- *
- **********************************************/
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
- public void AddResourceFile(
- String name,
- String fileName)
- {
- AddResourceFile(name, fileName, ResourceAttributes.Public);
- }
-
- /**********************************************
- *
- * Add an existing resource file to the Assembly
- *
- **********************************************/
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
- public void AddResourceFile(
- String name,
- String fileName,
- ResourceAttributes attribute)
- {
- lock(SyncRoot)
- {
- AddResourceFileNoLock(name, fileName, attribute);
- }
- }
-
- [System.Security.SecuritySafeCritical]
- private void AddResourceFileNoLock(
- String name,
- String fileName,
- ResourceAttributes attribute)
- {
- if (name == null)
- throw new ArgumentNullException("name");
- if (name.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), name);
- if (fileName == null)
- throw new ArgumentNullException("fileName");
- if (fileName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), fileName);
- if (!String.Equals(fileName, Path.GetFileName(fileName)))
- throw new ArgumentException(Environment.GetResourceString("Argument_NotSimpleFileName"), "fileName");
- Contract.EndContractBlock();
-
- BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.AddResourceFile( " + name + ", " + fileName + ")");
-
- m_assemblyData.CheckResNameConflict(name);
- m_assemblyData.CheckFileNameConflict(fileName);
-
- String fullFileName;
-
- if (m_assemblyData.m_strDir == null)
- {
- // If assembly directory is null, use current directory
- fullFileName = Path.Combine(Directory.GetCurrentDirectory(), fileName);
- }
- else
- {
- // Form the full path given the directory provided by user
- fullFileName = Path.Combine(m_assemblyData.m_strDir, fileName);
- }
-
- // get the full path
- fullFileName = Path.UnsafeGetFullPath(fullFileName);
-
- // retrieve just the file name
- fileName = Path.GetFileName(fullFileName);
-
- if (File.UnsafeExists(fullFileName) == false)
- throw new FileNotFoundException(Environment.GetResourceString(
- "IO.FileNotFound_FileName",
- fileName), fileName);
- m_assemblyData.AddResWriter( new ResWriterData( null, null, name, fileName, fullFileName, attribute) );
- }
-
#region object overrides
public override bool Equals(object obj)
{
@@ -1172,17 +645,11 @@ namespace System.Reflection.Emit
return InternalAssembly.GetManifestResourceNames();
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
public override FileStream GetFile(String name)
{
return InternalAssembly.GetFile(name);
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
public override FileStream[] GetFiles(bool getResourceModules)
{
return InternalAssembly.GetFiles(getResourceModules);
@@ -1205,9 +672,6 @@ namespace System.Reflection.Emit
public override String Location
{
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
get
{
return InternalAssembly.Location;
@@ -1224,9 +688,6 @@ namespace System.Reflection.Emit
public override String CodeBase
{
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
get
{
return InternalAssembly.CodeBase;
@@ -1249,9 +710,6 @@ namespace System.Reflection.Emit
return InternalAssembly.GetExportedTypes();
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
public override AssemblyName GetName(bool copiedName)
{
return InternalAssembly.GetName(copiedName);
@@ -1270,33 +728,6 @@ namespace System.Reflection.Emit
return InternalAssembly.GetType(name, throwOnError, ignoreCase);
}
-#if FEATURE_CAS_POLICY
- public override Evidence Evidence
- {
- get
- {
- return InternalAssembly.Evidence;
- }
- }
-
- public override PermissionSet PermissionSet
- {
- [SecurityCritical]
- get
- {
- return InternalAssembly.PermissionSet;
- }
- }
-
- public override SecurityRuleSet SecurityRuleSet
- {
- get
- {
- return InternalAssembly.SecurityRuleSet;
- }
- }
-#endif // FEATURE_CAS_POLICY
-
public override Module ManifestModule
{
get
@@ -1371,143 +802,8 @@ namespace System.Reflection.Emit
}
}
#endregion
-
-
- /**********************************************
- *
- * Add an unmanaged Version resource to the
- * assembly
- *
- **********************************************/
- public void DefineVersionInfoResource(
- String product,
- String productVersion,
- String company,
- String copyright,
- String trademark)
- {
- lock(SyncRoot)
- {
- DefineVersionInfoResourceNoLock(
- product,
- productVersion,
- company,
- copyright,
- trademark);
- }
- }
-
- private void DefineVersionInfoResourceNoLock(
- String product,
- String productVersion,
- String company,
- String copyright,
- String trademark)
- {
- if (m_assemblyData.m_strResourceFileName != null ||
- m_assemblyData.m_resourceBytes != null ||
- m_assemblyData.m_nativeVersion != null)
- throw new ArgumentException(Environment.GetResourceString("Argument_NativeResourceAlreadyDefined"));
-
- m_assemblyData.m_nativeVersion = new NativeVersionInfo();
-
- m_assemblyData.m_nativeVersion.m_strCopyright = copyright;
- m_assemblyData.m_nativeVersion.m_strTrademark = trademark;
- m_assemblyData.m_nativeVersion.m_strCompany = company;
- m_assemblyData.m_nativeVersion.m_strProduct = product;
- m_assemblyData.m_nativeVersion.m_strProductVersion = productVersion;
- m_assemblyData.m_hasUnmanagedVersionInfo = true;
- m_assemblyData.m_OverrideUnmanagedVersionInfo = true;
-
- }
-
- public void DefineVersionInfoResource()
- {
- lock(SyncRoot)
- {
- DefineVersionInfoResourceNoLock();
- }
- }
-
- private void DefineVersionInfoResourceNoLock()
- {
- if (m_assemblyData.m_strResourceFileName != null ||
- m_assemblyData.m_resourceBytes != null ||
- m_assemblyData.m_nativeVersion != null)
- throw new ArgumentException(Environment.GetResourceString("Argument_NativeResourceAlreadyDefined"));
-
- m_assemblyData.m_hasUnmanagedVersionInfo = true;
- m_assemblyData.m_nativeVersion = new NativeVersionInfo();
- }
-
- public void DefineUnmanagedResource(Byte[] resource)
- {
- if (resource == null)
- throw new ArgumentNullException("resource");
- Contract.EndContractBlock();
-
- lock(SyncRoot)
- {
- DefineUnmanagedResourceNoLock(resource);
- }
- }
- private void DefineUnmanagedResourceNoLock(Byte[] resource)
- {
- if (m_assemblyData.m_strResourceFileName != null ||
- m_assemblyData.m_resourceBytes != null ||
- m_assemblyData.m_nativeVersion != null)
- throw new ArgumentException(Environment.GetResourceString("Argument_NativeResourceAlreadyDefined"));
-
- m_assemblyData.m_resourceBytes = new byte[resource.Length];
- Buffer.BlockCopy(resource, 0, m_assemblyData.m_resourceBytes, 0, resource.Length);
- }
- [System.Security.SecuritySafeCritical] // auto-generated
- public void DefineUnmanagedResource(String resourceFileName)
- {
- if (resourceFileName == null)
- throw new ArgumentNullException("resourceFileName");
- Contract.EndContractBlock();
-
- lock(SyncRoot)
- {
- DefineUnmanagedResourceNoLock(resourceFileName);
- }
- }
-
- [System.Security.SecurityCritical] // auto-generated
- private void DefineUnmanagedResourceNoLock(String resourceFileName)
- {
- if (m_assemblyData.m_strResourceFileName != null ||
- m_assemblyData.m_resourceBytes != null ||
- m_assemblyData.m_nativeVersion != null)
- throw new ArgumentException(Environment.GetResourceString("Argument_NativeResourceAlreadyDefined"));
-
- // Check caller has the right to read the file.
- string strFullFileName;
- if (m_assemblyData.m_strDir == null)
- {
- // If assembly directory is null, use current directory
- strFullFileName = Path.Combine(Directory.GetCurrentDirectory(), resourceFileName);
- }
- else
- {
- // Form the full path given the directory provided by user
- strFullFileName = Path.Combine(m_assemblyData.m_strDir, resourceFileName);
- }
- strFullFileName = Path.GetFullPath(resourceFileName);
- new FileIOPermission(FileIOPermissionAccess.Read, strFullFileName).Demand();
-
- if (File.Exists(strFullFileName) == false)
- throw new FileNotFoundException(Environment.GetResourceString(
- "IO.FileNotFound_FileName",
- resourceFileName), resourceFileName);
- m_assemblyData.m_strResourceFileName = strFullFileName;
- }
-
-
-
/**********************************************
*
* return a dynamic module with the specified name.
@@ -1526,9 +822,9 @@ namespace System.Reflection.Emit
String name) // the name of module for the look up
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (name.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name));
Contract.EndContractBlock();
BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.GetDynamicModule( " + name + " )");
@@ -1550,17 +846,11 @@ namespace System.Reflection.Emit
* an exe.
*
**********************************************/
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
public void SetEntryPoint(
MethodInfo entryMethod)
{
SetEntryPoint(entryMethod, PEFileKinds.ConsoleApplication);
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
public void SetEntryPoint(
MethodInfo entryMethod, // entry method for the assembly. We use this to determine the entry module
PEFileKinds fileKind) // file kind for the assembly.
@@ -1577,7 +867,7 @@ namespace System.Reflection.Emit
{
if (entryMethod == null)
- throw new ArgumentNullException("entryMethod");
+ throw new ArgumentNullException(nameof(entryMethod));
Contract.EndContractBlock();
BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.SetEntryPoint");
@@ -1588,36 +878,19 @@ namespace System.Reflection.Emit
m_assemblyData.m_entryPointMethod = entryMethod;
m_assemblyData.m_peFileKind = fileKind;
-
-#if !FEATURE_CORECLR
- // Setting the entry point
- ModuleBuilder tmpMB = tmpModule as ModuleBuilder;
- if (tmpMB != null)
- m_assemblyData.m_entryPointModule = tmpMB;
- else
- m_assemblyData.m_entryPointModule = GetModuleBuilder((InternalModuleBuilder)tmpModule);
-
- MethodToken entryMethodToken = m_assemblyData.m_entryPointModule.GetMethodToken(entryMethod);
- m_assemblyData.m_entryPointModule.SetEntryPoint(entryMethodToken);
-#endif //!FEATURE_CORECLR
}
/**********************************************
* Use this function if client decides to form the custom attribute blob themselves
**********************************************/
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #else
- [System.Security.SecuritySafeCritical]
- #endif
[System.Runtime.InteropServices.ComVisible(true)]
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
{
if (con == null)
- throw new ArgumentNullException("con");
+ throw new ArgumentNullException(nameof(con));
if (binaryAttribute == null)
- throw new ArgumentNullException("binaryAttribute");
+ throw new ArgumentNullException(nameof(binaryAttribute));
Contract.EndContractBlock();
lock(SyncRoot)
@@ -1626,7 +899,6 @@ namespace System.Reflection.Emit
}
}
- [System.Security.SecurityCritical] // auto-generated
private void SetCustomAttributeNoLock(ConstructorInfo con, byte[] binaryAttribute)
{
TypeBuilder.DefineCustomAttribute(
@@ -1648,12 +920,11 @@ namespace System.Reflection.Emit
/**********************************************
* Use this function if client wishes to build CustomAttribute using CustomAttributeBuilder
**********************************************/
- [System.Security.SecuritySafeCritical] // auto-generated
public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
{
if (customBuilder == null)
{
- throw new ArgumentNullException("customBuilder");
+ throw new ArgumentNullException(nameof(customBuilder));
}
Contract.EndContractBlock();
@@ -1663,7 +934,6 @@ namespace System.Reflection.Emit
}
}
- [System.Security.SecurityCritical] // auto-generated
private void SetCustomAttributeNoLock(CustomAttributeBuilder customBuilder)
{
customBuilder.CreateCustomAttribute(
@@ -1693,7 +963,6 @@ namespace System.Reflection.Emit
Save(assemblyFileName, System.Reflection.PortableExecutableKinds.ILOnly, System.Reflection.ImageFileMachine.I386);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void Save(String assemblyFileName,
PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
{
@@ -1703,358 +972,15 @@ namespace System.Reflection.Emit
}
}
-#if FEATURE_CORECLR
private void SaveNoLock(String assemblyFileName,
PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
{
- // AssemblyBuilderAccess.Save can never be set with FEATURE_CORECLR
+ // AssemblyBuilderAccess.Save can never be set in CoreCLR
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CantSaveTransientAssembly"));
}
-#else // FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- private void SaveNoLock(String assemblyFileName,
- PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
- {
- if (assemblyFileName == null)
- throw new ArgumentNullException("assemblyFileName");
- if (assemblyFileName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "assemblyFileName");
- if (!String.Equals(assemblyFileName, Path.GetFileName(assemblyFileName)))
- throw new ArgumentException(Environment.GetResourceString("Argument_NotSimpleFileName"), "assemblyFileName");
- Contract.EndContractBlock();
-
- int i;
- int size;
- Type type;
- TypeBuilder typeBuilder;
- ModuleBuilder modBuilder;
- String strModFileName;
- ModuleBuilder assemblyModule;
- ResWriterData tempRes;
- int[] tkAttrs = null;
- int[] tkAttrs2 = null;
- ModuleBuilder onDiskAssemblyModule;
- BCLDebug.Log("DYNIL","## DYNIL LOGGING: AssemblyBuilder.Save( " + assemblyFileName + " )");
-
- String tmpVersionFile = null;
-
- try
- {
- if (m_assemblyData.m_iCABuilder != 0)
- tkAttrs = new int[m_assemblyData.m_iCABuilder];
- if ( m_assemblyData.m_iCAs != 0)
- tkAttrs2 = new int[m_assemblyData.m_iCAs];
-
- if (m_assemblyData.m_isSaved == true)
- {
- // assembly has been saved before!
- throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_AssemblyHasBeenSaved,
- InternalAssembly.GetSimpleName()));
- }
-
- if ((m_assemblyData.m_access & AssemblyBuilderAccess.Save) != AssemblyBuilderAccess.Save)
- {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CantSaveTransientAssembly"));
- }
-
- // Check if assembly info is supposed to be stored with one of the module files.
- assemblyModule = m_assemblyData.FindModuleWithFileName(assemblyFileName);
-
- if (assemblyModule != null)
- {
- m_onDiskAssemblyModuleBuilder = assemblyModule;
-
- // In memory this module is not the manifest module and has a valid file token
- // On disk it will be the manifest module so lets clean the file token
- // We should not retrieve FileToken after the assembly has been saved
- // If that is absolutely necessary, we need two separate fields on ModuleBuilderData:
- // the in memory file token and the on disk file token.
- assemblyModule.m_moduleData.FileToken = 0;
- }
- else
- { // If assembly is to be stored alone, then no file name should conflict with it.
- // This check will ensure resource file names are different assembly file name.
- m_assemblyData.CheckFileNameConflict(assemblyFileName);
- }
-
- if (m_assemblyData.m_strDir == null)
- {
- // set it to current directory
- m_assemblyData.m_strDir = Directory.GetCurrentDirectory();
- }
- else if (Directory.Exists(m_assemblyData.m_strDir) == false)
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidDirectory",
- m_assemblyData.m_strDir));
- }
-
- // after this point, assemblyFileName is the full path name.
- assemblyFileName = Path.Combine(m_assemblyData.m_strDir, assemblyFileName);
- assemblyFileName = Path.GetFullPath(assemblyFileName);
-
- // Check caller has the right to create the assembly file itself.
- new FileIOPermission(FileIOPermissionAccess.Write | FileIOPermissionAccess.Append, assemblyFileName).Demand();
-
- // 1. setup/create the IMetaDataAssemblyEmit for the on disk version
- if (assemblyModule != null)
- {
- // prepare saving CAs on assembly def. We need to introduce the MemberRef for
- // the CA's type first of all. This is for the case the we have embedded manifest.
- // We need to introduce these MRs before we call PreSave where we will snap
- // into a ondisk metadata. If we do it after this, the ondisk metadata will
- // not contain the proper MRs.
- //
- for (i=0; i < m_assemblyData.m_iCABuilder; i++)
- {
- tkAttrs[i] = m_assemblyData.m_CABuilders[i].PrepareCreateCustomAttributeToDisk(
- assemblyModule);
- }
- for (i=0; i < m_assemblyData.m_iCAs; i++)
- {
- tkAttrs2[i] = assemblyModule.InternalGetConstructorToken(m_assemblyData.m_CACons[i], true).Token;
- }
- assemblyModule.PreSave(assemblyFileName, portableExecutableKind, imageFileMachine);
- }
-
- RuntimeModule runtimeAssemblyModule = (assemblyModule != null) ? assemblyModule.ModuleHandle.GetRuntimeModule() : null;
- PrepareForSavingManifestToDisk(GetNativeHandle(), runtimeAssemblyModule);
-
- // This function will return the embedded manifest module, an already exposed ModuleBuilder
- // created by user, or make the stand alone manifest module exposed through managed code.
- //
- onDiskAssemblyModule = GetOnDiskAssemblyModuleBuilder();
-
- // Set any native resources on the OnDiskAssemblyModule.
- if (m_assemblyData.m_strResourceFileName != null)
- onDiskAssemblyModule.DefineUnmanagedResourceFileInternalNoLock(m_assemblyData.m_strResourceFileName);
- else if (m_assemblyData.m_resourceBytes != null)
- onDiskAssemblyModule.DefineUnmanagedResourceInternalNoLock(m_assemblyData.m_resourceBytes);
- else if (m_assemblyData.m_hasUnmanagedVersionInfo == true)
- {
- // calculate unmanaged version info from assembly's custom attributes
- m_assemblyData.FillUnmanagedVersionInfo();
-
- String strFileVersion = m_assemblyData.m_nativeVersion.m_strFileVersion;
- if (strFileVersion == null)
- strFileVersion = GetVersion().ToString();
-
- // Create the file.
- CreateVersionInfoResource(
- assemblyFileName,
- m_assemblyData.m_nativeVersion.m_strTitle, // title
- null, // Icon filename
- m_assemblyData.m_nativeVersion.m_strDescription, // description
- m_assemblyData.m_nativeVersion.m_strCopyright,
- m_assemblyData.m_nativeVersion.m_strTrademark,
- m_assemblyData.m_nativeVersion.m_strCompany,
- m_assemblyData.m_nativeVersion.m_strProduct,
- m_assemblyData.m_nativeVersion.m_strProductVersion,
- strFileVersion,
- m_assemblyData.m_nativeVersion.m_lcid,
- m_assemblyData.m_peFileKind == PEFileKinds.Dll,
- JitHelpers.GetStringHandleOnStack(ref tmpVersionFile));
-
- onDiskAssemblyModule.DefineUnmanagedResourceFileInternalNoLock(tmpVersionFile);
- }
-
- if (assemblyModule == null)
- {
-
- // This is for introducing the MRs for CA's type. This case is for stand alone
- // manifest. We need to wait till PrepareForSavingManifestToDisk is called.
- // That will trigger the creation of the on-disk stand alone manifest module.
- //
- for (i=0; i < m_assemblyData.m_iCABuilder; i++)
- {
- tkAttrs[i] = m_assemblyData.m_CABuilders[i].PrepareCreateCustomAttributeToDisk(
- onDiskAssemblyModule);
- }
- for (i=0; i < m_assemblyData.m_iCAs; i++)
- {
- tkAttrs2[i] = onDiskAssemblyModule.InternalGetConstructorToken(m_assemblyData.m_CACons[i], true).Token;
- }
- }
-
- // 2. save all of the persistable modules contained by this AssemblyBuilder except the module that is going to contain
- // Assembly information
- //
- // 3. create the file list in the manifest and track the file token. If it is embedded assembly,
- // the assembly file should not be on the file list.
- //
- size = m_assemblyData.m_moduleBuilderList.Count;
- for (i = 0; i < size; i++)
- {
- ModuleBuilder mBuilder = (ModuleBuilder) m_assemblyData.m_moduleBuilderList[i];
- if (mBuilder.IsTransient() == false && mBuilder != assemblyModule)
- {
- strModFileName = mBuilder.m_moduleData.m_strFileName;
- if (m_assemblyData.m_strDir != null)
- {
- strModFileName = Path.Combine(m_assemblyData.m_strDir, strModFileName);
- strModFileName = Path.GetFullPath(strModFileName);
- }
-
- // Check caller has the right to create the Module file itself.
- new FileIOPermission(FileIOPermissionAccess.Write | FileIOPermissionAccess.Append, strModFileName).Demand();
-
- mBuilder.m_moduleData.FileToken = AddFile(GetNativeHandle(), mBuilder.m_moduleData.m_strFileName);
- mBuilder.PreSave(strModFileName, portableExecutableKind, imageFileMachine);
- mBuilder.Save(strModFileName, false, portableExecutableKind, imageFileMachine);
-
- // Cannot set the hash value when creating the file since the file token
- // is needed to created the entries for the embedded resources in the
- // module and the resources need to be there before you figure the hash.
- SetFileHashValue(GetNativeHandle(), mBuilder.m_moduleData.FileToken, strModFileName);
- }
- }
-
- // 4. Add the public ComType
- for (i=0; i < m_assemblyData.m_iPublicComTypeCount; i++)
- {
- type = m_assemblyData.m_publicComTypeList[i];
- // If the type that was added as a Public Com Type was obtained via Reflection,
- // it will be a System.RuntimeType, even if it was really, at the same time,
- // a TypeBuilder. Unfortunately, you can't get back to the TypeBuilder, so
- // this code has to deal with either-or.
- if (type is RuntimeType)
- {
- // If type is a runtime type, it must be a baked TypeBuilder,
- // ttype.Module should be an InternalModuleBuilder
-
- InternalModuleBuilder internalMB = (InternalModuleBuilder)type.Module;
- modBuilder = this.GetModuleBuilder(internalMB);
- if (modBuilder != assemblyModule)
- DefineNestedComType(type, modBuilder.m_moduleData.FileToken, type.MetadataToken);
- }
- else
- {
- // Could assert that "type" is a TypeBuilder, but next statement throws if it isn't.
- typeBuilder = (TypeBuilder) type;
- // If type is a TypeBuilder, type.Module must be a ModuleBuilder.
- modBuilder = typeBuilder.GetModuleBuilder();
- if (modBuilder != assemblyModule)
- DefineNestedComType(type, modBuilder.m_moduleData.FileToken, typeBuilder.MetadataTokenInternal);
- }
- }
-
- // 5. write AssemblyDef's CAs (only if we are not saving directly the manifest module itself)
- if (onDiskAssemblyModule != m_manifestModuleBuilder)
- {
- for (i = 0; i < m_assemblyData.m_iCABuilder; i++)
- {
- m_assemblyData.m_CABuilders[i].CreateCustomAttribute(
- onDiskAssemblyModule,
- AssemblyBuilderData.m_tkAssembly, // This is the AssemblyDef token
- tkAttrs[i], true);
- }
-
- for (i = 0; i < m_assemblyData.m_iCAs; i++)
- {
- TypeBuilder.DefineCustomAttribute(
- onDiskAssemblyModule, // pass in the in-memory assembly module
- AssemblyBuilderData.m_tkAssembly, // This is the AssemblyDef token
- tkAttrs2[i],
- m_assemblyData.m_CABytes[i],
- true, false);
- }
- }
-
- // 6. write security permission requests to the manifest.
-#pragma warning disable 618
- if (m_assemblyData.m_RequiredPset != null)
- AddDeclarativeSecurity(m_assemblyData.m_RequiredPset, SecurityAction.RequestMinimum);
-
- if (m_assemblyData.m_RefusedPset != null)
- AddDeclarativeSecurity(m_assemblyData.m_RefusedPset, SecurityAction.RequestRefuse);
-
- if (m_assemblyData.m_OptionalPset != null)
- AddDeclarativeSecurity(m_assemblyData.m_OptionalPset, SecurityAction.RequestOptional);
-#pragma warning restore 618
-
- // 7. Save the stand alone managed resources
- size = m_assemblyData.m_resWriterList.Count;
- for (i = 0; i < size; i++)
- {
- tempRes = null;
-
- try
- {
- tempRes = (ResWriterData)m_assemblyData.m_resWriterList[i];
-
- // If the user added an existing resource to the manifest, the
- // corresponding ResourceWriter will be null.
- if (tempRes.m_resWriter != null)
- // Check caller has the right to create the Resource file itself.
- new FileIOPermission(FileIOPermissionAccess.Write | FileIOPermissionAccess.Append, tempRes.m_strFullFileName).Demand();
- }
- finally
- {
- if (tempRes != null && tempRes.m_resWriter != null)
- tempRes.m_resWriter.Close();
- }
-
- // Add entry to manifest for this stand alone resource
- AddStandAloneResource(GetNativeHandle(), tempRes.m_strName, tempRes.m_strFileName, tempRes.m_strFullFileName, (int)tempRes.m_attribute);
- }
-
- // Save now!!
- if (assemblyModule == null)
- {
- onDiskAssemblyModule.DefineNativeResource(portableExecutableKind, imageFileMachine);
-
- // Stand alone manifest
- int entryPoint = (m_assemblyData.m_entryPointModule != null) ? m_assemblyData.m_entryPointModule.m_moduleData.FileToken : 0;
-
- SaveManifestToDisk(GetNativeHandle(), assemblyFileName, entryPoint, (int)m_assemblyData.m_peFileKind,
- (int)portableExecutableKind, (int)imageFileMachine);
- }
- else
- {
- // embedded manifest
-
- // If the module containing the entry point is not the manifest file, we need to
- // let the manifest file point to the module which contains the entry point.
- //
- //
- //
- //
- if (m_assemblyData.m_entryPointModule != null && m_assemblyData.m_entryPointModule != assemblyModule)
- assemblyModule.SetEntryPoint(new MethodToken(m_assemblyData.m_entryPointModule.m_moduleData.FileToken));
- assemblyModule.Save(assemblyFileName, true, portableExecutableKind, imageFileMachine);
- }
- m_assemblyData.m_isSaved = true;
- }
- finally
- {
- if (tmpVersionFile != null)
- {
- // Delete file.
- System.IO.File.Delete(tmpVersionFile);
- }
- }
- }
-#endif // FEATURE_CORECLR
-
-#if FEATURE_CAS_POLICY
- [System.Security.SecurityCritical] // auto-generated
- private void AddDeclarativeSecurity(PermissionSet pset, SecurityAction action)
- {
- // Translate sets into internal encoding (uses standard binary serialization).
- byte[] blob = pset.EncodeXml();
- AddDeclarativeSecurity(GetNativeHandle(), action, blob, blob.Length);
- }
-#endif // FEATURE_CAS_POLICY
-
internal bool IsPersistable()
{
-#if !FEATURE_CORECLR // AssemblyBuilderAccess.Save is never set in CoreCLR
- if ((m_assemblyData.m_access & AssemblyBuilderAccess.Save) == AssemblyBuilderAccess.Save)
- {
- return true;
- }
- else
-#endif // FEATURE_CORECLR
{
return false;
}
@@ -2065,7 +991,6 @@ namespace System.Reflection.Emit
* Internal helper to walk the nested type hierachy
*
**********************************************/
- [System.Security.SecurityCritical] // auto-generated
private int DefineNestedComType(Type type, int tkResolutionScope, int tkTypeDef)
{
Type enclosingType = type.DeclaringType;
@@ -2080,7 +1005,6 @@ namespace System.Reflection.Emit
return AddExportedTypeOnDisk(GetNativeHandle(), type.Name, tkResolutionScope, tkTypeDef, type.Attributes);
}
- [System.Security.SecurityCritical] // auto-generated
internal int DefineExportedTypeInMemory(Type type, int tkResolutionScope, int tkTypeDef)
{
Type enclosingType = type.DeclaringType;
@@ -2107,32 +1031,7 @@ namespace System.Reflection.Emit
**********************************************/
private AssemblyBuilder() {}
-#if !FEATURE_CORECLR
- void _AssemblyBuilder.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _AssemblyBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _AssemblyBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- // If you implement this method, make sure to include _AssemblyBuilder.Invoke in VM\DangerousAPIs.h and
- // include _AssemblyBuilder in SystemDomain::IsReflectionInvocationMethod in AppDomain.cpp.
- void _AssemblyBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
-#endif
-
// Create a new module in which to emit code. This module will not contain the manifest.
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
static private extern void DefineDynamicModule(RuntimeAssembly containingAssembly,
@@ -2145,7 +1044,6 @@ namespace System.Reflection.Emit
bool fIsTransient,
out int tkFile);
- [System.Security.SecurityCritical] // auto-generated
private static Module DefineDynamicModule(RuntimeAssembly containingAssembly,
bool emitSymbolInfo,
String name,
@@ -2171,12 +1069,10 @@ namespace System.Reflection.Emit
}
// The following functions are native helpers for creating on-disk manifest
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
static private extern void PrepareForSavingManifestToDisk(RuntimeAssembly assembly, RuntimeModule assemblyModule); // module to contain assembly information if assembly is embedded
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
static private extern void SaveManifestToDisk(RuntimeAssembly assembly,
@@ -2186,19 +1082,16 @@ namespace System.Reflection.Emit
int portableExecutableKind,
int ImageFileMachine);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
static private extern int AddFile(RuntimeAssembly assembly, String strFileName);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
static private extern void SetFileHashValue(RuntimeAssembly assembly,
int tkFile,
String strFullFileName);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
static private extern int AddExportedTypeInMemory(RuntimeAssembly assembly,
@@ -2207,7 +1100,6 @@ namespace System.Reflection.Emit
int tkTypeDef,
TypeAttributes flags);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
static private extern int AddExportedTypeOnDisk(RuntimeAssembly assembly,
@@ -2217,7 +1109,6 @@ namespace System.Reflection.Emit
TypeAttributes flags);
// Add an entry to assembly's manifestResource table for a stand alone resource.
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
static private extern void AddStandAloneResource(RuntimeAssembly assembly,
@@ -2226,7 +1117,6 @@ namespace System.Reflection.Emit
String strFullFileName,
int attribute);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
#pragma warning disable 618
@@ -2234,7 +1124,6 @@ namespace System.Reflection.Emit
#pragma warning restore 618
// Functions for defining unmanaged resources.
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
static private extern void CreateVersionInfoResource(String filename, String title, String iconFilename, String description,
diff --git a/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderAccess.cs b/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderAccess.cs
index 00a961dd89..5c86d8ec87 100644
--- a/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderAccess.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderAccess.cs
@@ -8,17 +8,13 @@ using System;
// EE uses these enum values..look for m_dwDynamicAssemblyAccess in Assembly.hpp
namespace System.Reflection.Emit
-{
+{
[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
[Flags]
public enum AssemblyBuilderAccess
{
Run = 1,
-#if !FEATURE_CORECLR // these are unsupported
- Save = 2,
- RunAndSave = Run | Save,
-#endif // !FEATURE_CORECLR
#if FEATURE_REFLECTION_ONLY_LOAD
ReflectionOnly = 6, // 4 | Save,
#endif // FEATURE_REFLECTION_ONLY_LOAD
diff --git a/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderData.cs b/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderData.cs
index f1a38c611b..f0f83e7d2a 100644
--- a/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderData.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderData.cs
@@ -14,11 +14,7 @@ namespace System.Reflection.Emit {
using System.Security;
using System.Diagnostics;
using CultureInfo = System.Globalization.CultureInfo;
-#if !FEATURE_CORECLR
- using ResourceWriter = System.Resources.ResourceWriter;
-#else // FEATURE_CORECLR
using IResourceWriter = System.Resources.IResourceWriter;
-#endif // !FEATURE_CORECLR
using System.IO;
using System.Runtime.Versioning;
using System.Diagnostics.SymbolStore;
@@ -29,7 +25,6 @@ namespace System.Reflection.Emit {
// this class cannot be accessed from the EE.
internal class AssemblyBuilderData
{
- [SecurityCritical]
internal AssemblyBuilderData(
InternalAssemblyBuilder assembly,
String strAssemblyName,
@@ -120,7 +115,6 @@ namespace System.Reflection.Emit {
// If DefineUnmanagedVersionInfo is called, the parameter provided will override
// the CA's value.
//
- [System.Security.SecurityCritical] // auto-generated
internal void FillUnmanagedVersionInfo()
{
// Get the lcid set on the assembly name as default if available
@@ -242,7 +236,7 @@ namespace System.Reflection.Emit {
}
// CultureInfo attribute overrides the lcid from AssemblyName.
CultureInfo culture = new CultureInfo(m_CABuilders[i].m_constructorArgs[0].ToString());
-#if FEATURE_USE_LCID
+#if FEATURE_USE_LCID
m_nativeVersion.m_lcid = culture.LCID;
#endif
}
@@ -469,7 +463,7 @@ namespace System.Reflection.Emit {
// hard coding the assembly def token
internal const int m_tkAssembly = 0x20000001;
-
+
// Security permission requests
internal PermissionSet m_RequiredPset;
internal PermissionSet m_OptionalPset;
@@ -485,10 +479,6 @@ namespace System.Reflection.Emit {
internal MethodInfo m_entryPointMethod;
internal Assembly m_ISymWrapperAssembly;
-#if !FEATURE_CORECLR
- internal ModuleBuilder m_entryPointModule;
-#endif //!FEATURE_CORECLR
-
// For unmanaged resources
internal String m_strResourceFileName;
internal byte[] m_resourceBytes;
@@ -507,7 +497,6 @@ namespace System.Reflection.Emit {
**********************************************/
internal class ResWriterData
{
-#if FEATURE_CORECLR
internal ResWriterData(
IResourceWriter resWriter,
Stream memoryStream,
@@ -524,29 +513,8 @@ namespace System.Reflection.Emit {
m_nextResWriter = null;
m_attribute = attribute;
}
-#else
- internal ResWriterData(
- ResourceWriter resWriter,
- Stream memoryStream,
- String strName,
- String strFileName,
- String strFullFileName,
- ResourceAttributes attribute)
- {
- m_resWriter = resWriter;
- m_memoryStream = memoryStream;
- m_strName = strName;
- m_strFileName = strFileName;
- m_strFullFileName = strFullFileName;
- m_nextResWriter = null;
- m_attribute = attribute;
- }
-#endif
-#if !FEATURE_CORECLR
- internal ResourceWriter m_resWriter;
-#else // FEATURE_CORECLR
- internal IResourceWriter m_resWriter;
-#endif // !FEATURE_CORECLR
+
+ internal IResourceWriter m_resWriter;
internal String m_strName;
internal String m_strFileName;
internal String m_strFullFileName;
diff --git a/src/mscorlib/src/System/Reflection/Emit/ComInterfaces.cs b/src/mscorlib/src/System/Reflection/Emit/ComInterfaces.cs
index 0d8ce5a8d4..8dba934bde 100644
--- a/src/mscorlib/src/System/Reflection/Emit/ComInterfaces.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/ComInterfaces.cs
@@ -2,33 +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.
-using System;
-using System.Globalization;
-using System.IO;
-using System.Reflection;
-using System.Runtime.InteropServices;
-using System.Runtime.Serialization;
-using System.Security.Permissions;
-using System.Security.Policy;
-
namespace System.Runtime.InteropServices
{
[GuidAttribute("BEBB2505-8B54-3443-AEAD-142A16DD9CC7")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[CLSCompliant(false)]
[TypeLibImportClassAttribute(typeof(System.Reflection.Emit.AssemblyBuilder))]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface _AssemblyBuilder
{
-#if !FEATURE_CORECLR
- void GetTypeInfoCount(out uint pcTInfo);
-
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
-
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
-
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
-#endif
}
[GuidAttribute("ED3E4384-D7E2-3FA7-8FFD-8940D330519A")]
@@ -38,141 +20,69 @@ namespace System.Runtime.InteropServices
[System.Runtime.InteropServices.ComVisible(true)]
public interface _ConstructorBuilder
{
-#if !FEATURE_CORECLR
- void GetTypeInfoCount(out uint pcTInfo);
-
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
-
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
-
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
-#endif
}
[GuidAttribute("BE9ACCE8-AAFF-3B91-81AE-8211663F5CAD")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[CLSCompliant(false)]
[TypeLibImportClassAttribute(typeof(System.Reflection.Emit.CustomAttributeBuilder))]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface _CustomAttributeBuilder
{
-#if !FEATURE_CORECLR
- void GetTypeInfoCount(out uint pcTInfo);
-
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
-
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
-
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
-#endif
}
[GuidAttribute("C7BD73DE-9F85-3290-88EE-090B8BDFE2DF")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[CLSCompliant(false)]
[TypeLibImportClassAttribute(typeof(System.Reflection.Emit.EnumBuilder))]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface _EnumBuilder
{
-#if !FEATURE_CORECLR
- void GetTypeInfoCount(out uint pcTInfo);
-
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
-
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
-
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
-#endif
}
[GuidAttribute("AADABA99-895D-3D65-9760-B1F12621FAE8")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[CLSCompliant(false)]
[TypeLibImportClassAttribute(typeof(System.Reflection.Emit.EventBuilder))]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface _EventBuilder
{
-#if !FEATURE_CORECLR
- void GetTypeInfoCount(out uint pcTInfo);
-
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
-
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
-
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
-#endif
}
[GuidAttribute("CE1A3BF5-975E-30CC-97C9-1EF70F8F3993")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[CLSCompliant(false)]
[TypeLibImportClassAttribute(typeof(System.Reflection.Emit.FieldBuilder))]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface _FieldBuilder
{
-#if !FEATURE_CORECLR
- void GetTypeInfoCount(out uint pcTInfo);
-
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
-
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
-
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
-#endif
}
[GuidAttribute("A4924B27-6E3B-37F7-9B83-A4501955E6A7")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[CLSCompliant(false)]
[TypeLibImportClassAttribute(typeof(System.Reflection.Emit.ILGenerator))]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface _ILGenerator
{
-#if !FEATURE_CORECLR
- void GetTypeInfoCount(out uint pcTInfo);
-
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
-
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
-
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
-#endif
}
[GuidAttribute("4E6350D1-A08B-3DEC-9A3E-C465F9AEEC0C")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[CLSCompliant(false)]
[TypeLibImportClassAttribute(typeof(System.Reflection.Emit.LocalBuilder))]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface _LocalBuilder
{
-#if !FEATURE_CORECLR
- void GetTypeInfoCount(out uint pcTInfo);
-
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
-
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
-
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
-#endif
}
[GuidAttribute("007D8A14-FDF3-363E-9A0B-FEC0618260A2")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[CLSCompliant(false)]
[TypeLibImportClassAttribute(typeof(System.Reflection.Emit.MethodBuilder))]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface _MethodBuilder
{
-#if !FEATURE_CORECLR
- void GetTypeInfoCount(out uint pcTInfo);
-
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
-
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
-
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
-#endif
}
#if FEATURE_METHOD_RENTAL
@@ -180,18 +90,9 @@ namespace System.Runtime.InteropServices
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[CLSCompliant(false)]
[TypeLibImportClassAttribute(typeof(System.Reflection.Emit.MethodRental))]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface _MethodRental
{
-#if !FEATURE_CORECLR
- void GetTypeInfoCount(out uint pcTInfo);
-
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
-
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
-
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
-#endif
}
#endif
@@ -199,90 +100,44 @@ namespace System.Runtime.InteropServices
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[CLSCompliant(false)]
[TypeLibImportClassAttribute(typeof(System.Reflection.Emit.ModuleBuilder))]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface _ModuleBuilder
{
-#if !FEATURE_CORECLR
- void GetTypeInfoCount(out uint pcTInfo);
-
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
-
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
-
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
-#endif
}
[GuidAttribute("36329EBA-F97A-3565-BC07-0ED5C6EF19FC")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[CLSCompliant(false)]
[TypeLibImportClassAttribute(typeof(System.Reflection.Emit.ParameterBuilder))]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface _ParameterBuilder
{
-#if !FEATURE_CORECLR
- void GetTypeInfoCount(out uint pcTInfo);
-
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
-
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
-
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
-#endif
}
[GuidAttribute("15F9A479-9397-3A63-ACBD-F51977FB0F02")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[CLSCompliant(false)]
[TypeLibImportClassAttribute(typeof(System.Reflection.Emit.PropertyBuilder))]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface _PropertyBuilder
{
-#if !FEATURE_CORECLR
- void GetTypeInfoCount(out uint pcTInfo);
-
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
-
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
-
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
-#endif
}
[GuidAttribute("7D13DD37-5A04-393C-BBCA-A5FEA802893D")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[CLSCompliant(false)]
[TypeLibImportClassAttribute(typeof(System.Reflection.Emit.SignatureHelper))]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface _SignatureHelper
{
-#if !FEATURE_CORECLR
- void GetTypeInfoCount(out uint pcTInfo);
-
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
-
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
-
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
-#endif
}
[GuidAttribute("7E5678EE-48B3-3F83-B076-C58543498A58")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[CLSCompliant(false)]
[TypeLibImportClassAttribute(typeof(System.Reflection.Emit.TypeBuilder))]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface _TypeBuilder
{
-#if !FEATURE_CORECLR
- void GetTypeInfoCount(out uint pcTInfo);
-
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
-
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
-
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
-#endif
}
-
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/ConstructorBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/ConstructorBuilder.cs
index e5062d3365..ef76adcf80 100644
--- a/src/mscorlib/src/System/Reflection/Emit/ConstructorBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/ConstructorBuilder.cs
@@ -16,7 +16,6 @@ namespace System.Reflection.Emit
using System.Runtime.InteropServices;
using System.Diagnostics.Contracts;
- [HostProtection(MayLeakOnAbort = true)]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_ConstructorBuilder))]
[System.Runtime.InteropServices.ComVisible(true)]
@@ -31,7 +30,6 @@ namespace System.Reflection.Emit
{
}
- [System.Security.SecurityCritical] // auto-generated
internal ConstructorBuilder(String name, MethodAttributes attributes, CallingConventions callingConvention,
Type[] parameterTypes, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers, ModuleBuilder mod, TypeBuilder type)
{
@@ -49,7 +47,6 @@ namespace System.Reflection.Emit
token = m_methodBuilder.GetToken();
}
- [System.Security.SecurityCritical] // auto-generated
internal ConstructorBuilder(String name, MethodAttributes attributes, CallingConventions callingConvention,
Type[] parameterTypes, ModuleBuilder mod, TypeBuilder type) :
this(name, attributes, callingConvention, parameterTypes, null, null, mod, type)
@@ -205,9 +202,6 @@ namespace System.Reflection.Emit
return m_methodBuilder.GetILGenerator(streamSize);
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
public void SetMethodBody(byte[] il, int maxStack, byte[] localSignature, IEnumerable<ExceptionHandler> exceptionHandlers, IEnumerable<int> tokenFixups)
{
if (m_isDefaultConstructor)
@@ -218,36 +212,6 @@ namespace System.Reflection.Emit
m_methodBuilder.SetMethodBody(il, maxStack, localSignature, exceptionHandlers, tokenFixups);
}
-#if FEATURE_CAS_POLICY
- [System.Security.SecuritySafeCritical] // auto-generated
- public void AddDeclarativeSecurity(SecurityAction action, PermissionSet pset)
- {
- if (pset == null)
- throw new ArgumentNullException("pset");
-
-#pragma warning disable 618
- if (!Enum.IsDefined(typeof(SecurityAction), action) ||
- action == SecurityAction.RequestMinimum ||
- action == SecurityAction.RequestOptional ||
- action == SecurityAction.RequestRefuse)
- {
- throw new ArgumentOutOfRangeException("action");
- }
-#pragma warning restore 618
- Contract.EndContractBlock();
-
- // Cannot add declarative security after type is created.
- if (m_methodBuilder.IsTypeCreated())
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_TypeHasBeenCreated"));
-
- // Translate permission set into serialized format (use standard binary serialization).
- byte[] blob = pset.EncodeXml();
-
- // Write the blob into the metadata.
- TypeBuilder.AddDeclarativeSecurity(GetModuleBuilder().GetNativeHandle(), GetToken().Token, action, blob, blob.Length);
- }
-#endif // FEATURE_CAS_POLICY
-
public override CallingConventions CallingConvention
{
get
@@ -282,9 +246,6 @@ namespace System.Reflection.Emit
get { return m_methodBuilder.Signature; }
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
[System.Runtime.InteropServices.ComVisible(true)]
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
{
@@ -308,28 +269,6 @@ namespace System.Reflection.Emit
}
#endregion
-
-#if !FEATURE_CORECLR
- void _ConstructorBuilder.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _ConstructorBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _ConstructorBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- void _ConstructorBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
-#endif
}
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/CustomAttributeBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/CustomAttributeBuilder.cs
index 2a29a5c190..545657a053 100644
--- a/src/mscorlib/src/System/Reflection/Emit/CustomAttributeBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/CustomAttributeBuilder.cs
@@ -22,9 +22,9 @@ namespace System.Reflection.Emit {
using System.Security.Permissions;
using System.Runtime.InteropServices;
using System.Globalization;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
- [HostProtection(MayLeakOnAbort = true)]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_CustomAttributeBuilder))]
[System.Runtime.InteropServices.ComVisible(true)]
@@ -70,8 +70,14 @@ namespace System.Reflection.Emit {
// Check that a type is suitable for use in a custom attribute.
private bool ValidateType(Type t)
{
- if (t.IsPrimitive || t == typeof(String) || t == typeof(Type))
+ if (t.IsPrimitive)
+ {
+ return t != typeof(IntPtr) && t != typeof(UIntPtr);
+ }
+ if (t == typeof(String) || t == typeof(Type))
+ {
return true;
+ }
if (t.IsEnum)
{
switch (Type.GetTypeCode(Enum.GetUnderlyingType(t)))
@@ -103,17 +109,17 @@ namespace System.Reflection.Emit {
FieldInfo[] namedFields, Object[] fieldValues)
{
if (con == null)
- throw new ArgumentNullException("con");
+ throw new ArgumentNullException(nameof(con));
if (constructorArgs == null)
- throw new ArgumentNullException("constructorArgs");
+ throw new ArgumentNullException(nameof(constructorArgs));
if (namedProperties == null)
- throw new ArgumentNullException("namedProperties");
+ throw new ArgumentNullException(nameof(namedProperties));
if (propertyValues == null)
- throw new ArgumentNullException("propertyValues");
+ throw new ArgumentNullException(nameof(propertyValues));
if (namedFields == null)
- throw new ArgumentNullException("namedFields");
+ throw new ArgumentNullException(nameof(namedFields));
if (fieldValues == null)
- throw new ArgumentNullException("fieldValues");
+ throw new ArgumentNullException(nameof(fieldValues));
if (namedProperties.Length != propertyValues.Length)
throw new ArgumentException(Environment.GetResourceString("Arg_ArrayLengthsDiffer"), "namedProperties, propertyValues");
if (namedFields.Length != fieldValues.Length)
@@ -123,7 +129,7 @@ namespace System.Reflection.Emit {
if ((con.Attributes & MethodAttributes.Static) == MethodAttributes.Static ||
(con.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private)
throw new ArgumentException(Environment.GetResourceString("Argument_BadConstructor"));
-
+
if ((con.CallingConvention & CallingConventions.Standard) != CallingConventions.Standard)
throw new ArgumentException(Environment.GetResourceString("Argument_BadConstructorCallConv"));
@@ -150,12 +156,16 @@ namespace System.Reflection.Emit {
// 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++)
{
- if (constructorArgs[i] == null)
+ object constructorArg = constructorArgs[i];
+ if (constructorArg == null)
+ {
+ if (paramTypes[i].IsValueType)
+ {
+ throw new ArgumentNullException($"{nameof(constructorArgs)}[{i}]");
+ }
continue;
- TypeCode paramTC = Type.GetTypeCode(paramTypes[i]);
- if (paramTC != Type.GetTypeCode(constructorArgs[i].GetType()))
- if (paramTC != TypeCode.Object || !ValidateType(constructorArgs[i].GetType()))
- throw new ArgumentException(Environment.GetResourceString("Argument_BadParameterTypeForConstructor", i));
+ }
+ VerifyTypeAndPassedObjectType(paramTypes[i], constructorArg.GetType(), $"{nameof(constructorArgs)}[{i}]");
}
// Allocate a memory stream to represent the CA blob in the metadata and a binary writer to help format it.
@@ -176,12 +186,14 @@ namespace System.Reflection.Emit {
for (i = 0; i < namedProperties.Length; i++)
{
// Validate the property.
- if (namedProperties[i] == null)
+ PropertyInfo property = namedProperties[i];
+ if (property == null)
throw new ArgumentNullException("namedProperties[" + i + "]");
// Allow null for non-primitive types only.
- Type propType = namedProperties[i].PropertyType;
- if (propertyValues[i] == null && propType.IsPrimitive)
+ Type propType = property.PropertyType;
+ object propertyValue = propertyValues[i];
+ if (propertyValue == null && propType.IsValueType)
throw new ArgumentNullException("propertyValues[" + i + "]");
// Validate property type.
@@ -189,55 +201,57 @@ namespace System.Reflection.Emit {
throw new ArgumentException(Environment.GetResourceString("Argument_BadTypeInCustomAttribute"));
// Property has to be writable.
- if (!namedProperties[i].CanWrite)
+ if (!property.CanWrite)
throw new ArgumentException(Environment.GetResourceString("Argument_NotAWritableProperty"));
-
+
// Property has to be from the same class or base class as ConstructorInfo.
- if (namedProperties[i].DeclaringType != con.DeclaringType
+ if (property.DeclaringType != con.DeclaringType
&& (!(con.DeclaringType is TypeBuilderInstantiation))
- && !con.DeclaringType.IsSubclassOf(namedProperties[i].DeclaringType))
+ && !con.DeclaringType.IsSubclassOf(property.DeclaringType))
{
// Might have failed check because one type is a XXXBuilder
// and the other is not. Deal with these special cases
// separately.
- if (!TypeBuilder.IsTypeEqual(namedProperties[i].DeclaringType, con.DeclaringType))
+ if (!TypeBuilder.IsTypeEqual(property.DeclaringType, con.DeclaringType))
{
// IsSubclassOf is overloaded to do the right thing if
// the constructor is a TypeBuilder, but we still need
// to deal with the case where the property's declaring
// type is one.
- if (!(namedProperties[i].DeclaringType is TypeBuilder) ||
- !con.DeclaringType.IsSubclassOf(((TypeBuilder)namedProperties[i].DeclaringType).BakedRuntimeType))
+ if (!(property.DeclaringType is TypeBuilder) ||
+ !con.DeclaringType.IsSubclassOf(((TypeBuilder)property.DeclaringType).BakedRuntimeType))
throw new ArgumentException(Environment.GetResourceString("Argument_BadPropertyForConstructorBuilder"));
}
}
// Make sure the property's type can take the given value.
// Note that there will be no coersion.
- if (propertyValues[i] != null &&
- propType != typeof(Object) &&
- Type.GetTypeCode(propertyValues[i].GetType()) != Type.GetTypeCode(propType))
- throw new ArgumentException(Environment.GetResourceString("Argument_ConstantDoesntMatch"));
-
+ if (propertyValue != null)
+ {
+ VerifyTypeAndPassedObjectType(propType, propertyValue.GetType(), $"{nameof(propertyValues)}[{i}]");
+ }
+
// First a byte indicating that this is a property.
writer.Write((byte)CustomAttributeEncoding.Property);
// Emit the property type, name and value.
EmitType(writer, propType);
EmitString(writer, namedProperties[i].Name);
- EmitValue(writer, propType, propertyValues[i]);
+ EmitValue(writer, propType, propertyValue);
}
// Emit all the field sets.
for (i = 0; i < namedFields.Length; i++)
{
// Validate the field.
- if (namedFields[i] == null)
+ FieldInfo namedField = namedFields[i];
+ if (namedField == null)
throw new ArgumentNullException("namedFields[" + i + "]");
// Allow null for non-primitive types only.
- Type fldType = namedFields[i].FieldType;
- if (fieldValues[i] == null && fldType.IsPrimitive)
+ Type fldType = namedField.FieldType;
+ object fieldValue = fieldValues[i];
+ if (fieldValue == null && fldType.IsValueType)
throw new ArgumentNullException("fieldValues[" + i + "]");
// Validate field type.
@@ -245,20 +259,20 @@ namespace System.Reflection.Emit {
throw new ArgumentException(Environment.GetResourceString("Argument_BadTypeInCustomAttribute"));
// Field has to be from the same class or base class as ConstructorInfo.
- if (namedFields[i].DeclaringType != con.DeclaringType
+ if (namedField.DeclaringType != con.DeclaringType
&& (!(con.DeclaringType is TypeBuilderInstantiation))
- && !con.DeclaringType.IsSubclassOf(namedFields[i].DeclaringType))
+ && !con.DeclaringType.IsSubclassOf(namedField.DeclaringType))
{
// Might have failed check because one type is a XXXBuilder
// and the other is not. Deal with these special cases
// separately.
- if (!TypeBuilder.IsTypeEqual(namedFields[i].DeclaringType, con.DeclaringType))
+ if (!TypeBuilder.IsTypeEqual(namedField.DeclaringType, con.DeclaringType))
{
// IsSubclassOf is overloaded to do the right thing if
// the constructor is a TypeBuilder, but we still need
// to deal with the case where the field's declaring
// type is one.
- if (!(namedFields[i].DeclaringType is TypeBuilder) ||
+ if (!(namedField.DeclaringType is TypeBuilder) ||
!con.DeclaringType.IsSubclassOf(((TypeBuilder)namedFields[i].DeclaringType).BakedRuntimeType))
throw new ArgumentException(Environment.GetResourceString("Argument_BadFieldForConstructorBuilder"));
}
@@ -266,24 +280,36 @@ namespace System.Reflection.Emit {
// Make sure the field's type can take the given value.
// Note that there will be no coersion.
- if (fieldValues[i] != null &&
- fldType != typeof(Object) &&
- Type.GetTypeCode(fieldValues[i].GetType()) != Type.GetTypeCode(fldType))
- throw new ArgumentException(Environment.GetResourceString("Argument_ConstantDoesntMatch"));
+ if (fieldValue != null)
+ {
+ VerifyTypeAndPassedObjectType(fldType, fieldValue.GetType(), $"{nameof(fieldValues)}[{i}]");
+ }
// First a byte indicating that this is a field.
writer.Write((byte)CustomAttributeEncoding.Field);
// Emit the field type, name and value.
EmitType(writer, fldType);
- EmitString(writer, namedFields[i].Name);
- EmitValue(writer, fldType, fieldValues[i]);
+ EmitString(writer, namedField.Name);
+ EmitValue(writer, fldType, fieldValue);
}
// Create the blob array.
m_blob = ((MemoryStream)writer.BaseStream).ToArray();
}
+ private static void VerifyTypeAndPassedObjectType(Type type, Type passedType, string paramName)
+ {
+ if (type != typeof(object) && Type.GetTypeCode(passedType) != Type.GetTypeCode(type))
+ {
+ throw new ArgumentException(Environment.GetResourceString("Argument_ConstantDoesntMatch"));
+ }
+ if (passedType == typeof(IntPtr) || passedType == typeof(UIntPtr))
+ {
+ throw new ArgumentException(Environment.GetResourceString("Argument_BadParameterTypeForCAB"), paramName);
+ }
+ }
+
private void EmitType(BinaryWriter writer, Type type)
{
if (type.IsPrimitive)
@@ -327,7 +353,7 @@ namespace System.Reflection.Emit {
writer.Write((byte)CustomAttributeEncoding.Double);
break;
default:
- Contract.Assert(false, "Invalid primitive type");
+ Debug.Assert(false, "Invalid primitive type");
break;
}
}
@@ -411,7 +437,7 @@ namespace System.Reflection.Emit {
writer.Write((ulong)value);
break;
default:
- Contract.Assert(false, "Invalid enum base type");
+ Debug.Assert(false, "Invalid enum base type");
break;
}
}
@@ -489,7 +515,7 @@ namespace System.Reflection.Emit {
writer.Write((double)value);
break;
default:
- Contract.Assert(false, "Invalid primitive type");
+ Debug.Assert(false, "Invalid primitive type");
break;
}
}
@@ -524,7 +550,6 @@ namespace System.Reflection.Emit {
// return the byte interpretation of the custom attribute
- [System.Security.SecurityCritical] // auto-generated
internal void CreateCustomAttribute(ModuleBuilder mod, int tkOwner)
{
CreateCustomAttribute(mod, tkOwner, mod.GetConstructorToken(m_con).Token, false);
@@ -537,7 +562,6 @@ namespace System.Reflection.Emit {
// This function has to be called before we snap the in-memory module for on disk (i.e. Presave on
// ModuleBuilder.
//*************************************************
- [System.Security.SecurityCritical] // auto-generated
internal int PrepareCreateCustomAttributeToDisk(ModuleBuilder mod)
{
return mod.InternalGetConstructorToken(m_con, true).Token;
@@ -546,35 +570,12 @@ namespace System.Reflection.Emit {
//*************************************************
// Call this function with toDisk=1, after on disk module has been snapped.
//*************************************************
- [System.Security.SecurityCritical] // auto-generated
internal void CreateCustomAttribute(ModuleBuilder mod, int tkOwner, int tkAttrib, bool toDisk)
{
TypeBuilder.DefineCustomAttribute(mod, tkOwner, tkAttrib, m_blob, toDisk,
typeof(System.Diagnostics.DebuggableAttribute) == m_con.DeclaringType);
}
-#if !FEATURE_CORECLR
- void _CustomAttributeBuilder.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _CustomAttributeBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _CustomAttributeBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- void _CustomAttributeBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
-#endif
-
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 b66fdad1e2..9e1d82986a 100644
--- a/src/mscorlib/src/System/Reflection/Emit/DynamicILGenerator.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/DynamicILGenerator.cs
@@ -9,7 +9,6 @@ namespace System.Reflection.Emit
using System;
using System.Globalization;
- using TextWriter = System.IO.TextWriter;
using System.Diagnostics.SymbolStore;
using System.Runtime.InteropServices;
using System.Reflection;
@@ -17,6 +16,7 @@ namespace System.Reflection.Emit
using System.Collections.Generic;
using System.Security.Permissions;
using System.Threading;
+ using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
using System.Security;
@@ -36,7 +36,6 @@ namespace System.Reflection.Emit
}
- [System.Security.SecurityCritical] // auto-generated
internal void GetCallableMethod(RuntimeModule module, DynamicMethod dm)
{
dm.m_methodHandle = ModuleHandle.GetDynamicMethod(dm,
@@ -62,7 +61,7 @@ namespace System.Reflection.Emit
{
LocalBuilder localBuilder;
if (localType == null)
- throw new ArgumentNullException("localType");
+ throw new ArgumentNullException(nameof(localType));
Contract.EndContractBlock();
RuntimeType rtType = localType as RuntimeType;
@@ -87,11 +86,10 @@ namespace System.Reflection.Emit
// Token resolution calls
//
//
- [System.Security.SecuritySafeCritical] // auto-generated
public override void Emit(OpCode opcode, MethodInfo meth)
{
if (meth == null)
- throw new ArgumentNullException("meth");
+ throw new ArgumentNullException(nameof(meth));
Contract.EndContractBlock();
int stackchange = 0;
@@ -101,7 +99,7 @@ namespace System.Reflection.Emit
{
RuntimeMethodInfo rtMeth = meth as RuntimeMethodInfo;
if (rtMeth == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), "meth");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), nameof(meth));
RuntimeType declaringType = rtMeth.GetRuntimeType();
if (declaringType != null && (declaringType.IsGenericType || declaringType.IsArray))
@@ -148,12 +146,12 @@ namespace System.Reflection.Emit
public override void Emit(OpCode opcode, ConstructorInfo con)
{
if (con == null)
- throw new ArgumentNullException("con");
+ throw new ArgumentNullException(nameof(con));
Contract.EndContractBlock();
RuntimeConstructorInfo rtConstructor = con as RuntimeConstructorInfo;
if (rtConstructor == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), "con");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), nameof(con));
RuntimeType declaringType = rtConstructor.GetRuntimeType();
int token;
@@ -176,7 +174,7 @@ namespace System.Reflection.Emit
public override void Emit(OpCode opcode, Type type)
{
if (type == null)
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
Contract.EndContractBlock();
RuntimeType rtType = type as RuntimeType;
@@ -193,12 +191,12 @@ namespace System.Reflection.Emit
public override void Emit(OpCode opcode, FieldInfo field)
{
if (field == null)
- throw new ArgumentNullException("field");
+ throw new ArgumentNullException(nameof(field));
Contract.EndContractBlock();
RuntimeFieldInfo runtimeField = field as RuntimeFieldInfo;
if (runtimeField == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeFieldInfo"), "field");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeFieldInfo"), nameof(field));
int token;
if (field.DeclaringType == null)
@@ -214,7 +212,7 @@ namespace System.Reflection.Emit
public override void Emit(OpCode opcode, String str)
{
if (str == null)
- throw new ArgumentNullException("str");
+ throw new ArgumentNullException(nameof(str));
Contract.EndContractBlock();
int tempVal = GetTokenForString(str);
@@ -228,7 +226,6 @@ namespace System.Reflection.Emit
// Signature related calls (vararg, calli)
//
//
- [System.Security.SecuritySafeCritical] // overrides SC
public override void EmitCalli(OpCode opcode,
CallingConventions callingConvention,
Type returnType,
@@ -307,20 +304,19 @@ namespace System.Reflection.Emit
PutInteger4(token);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override void EmitCall(OpCode opcode, MethodInfo methodInfo, Type[] optionalParameterTypes)
{
if (methodInfo == null)
- throw new ArgumentNullException("methodInfo");
+ 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"), "opcode");
+ throw new ArgumentException(Environment.GetResourceString("Argument_NotMethodCallOpcode"), nameof(opcode));
if (methodInfo.ContainsGenericParameters)
- throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), "methodInfo");
+ throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), nameof(methodInfo));
if (methodInfo.DeclaringType != null && methodInfo.DeclaringType.ContainsGenericParameters)
- throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), "methodInfo");
+ throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), nameof(methodInfo));
Contract.EndContractBlock();
int tk;
@@ -351,7 +347,7 @@ namespace System.Reflection.Emit
public override void Emit(OpCode opcode, SignatureHelper signature)
{
if (signature == null)
- throw new ArgumentNullException("signature");
+ throw new ArgumentNullException(nameof(signature));
Contract.EndContractBlock();
int stackchange = 0;
@@ -365,7 +361,7 @@ namespace System.Reflection.Emit
// SignatureHelper.
if (opcode.StackBehaviourPop == StackBehaviour.Varpop)
{
- Contract.Assert(opcode.Equals(OpCodes.Calli),
+ Debug.Assert(opcode.Equals(OpCodes.Calli),
"Unexpected opcode encountered for StackBehaviour VarPop.");
// Pop the arguments..
stackchange -= signature.ArgumentCount;
@@ -421,7 +417,7 @@ namespace System.Reflection.Emit
{
// execute this branch if previous clause is Catch or Fault
if (exceptionType == null)
- throw new ArgumentNullException("exceptionType");
+ throw new ArgumentNullException(nameof(exceptionType));
if (rtType == null)
throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"));
@@ -482,7 +478,6 @@ namespace System.Reflection.Emit
throw new NotSupportedException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod"));
}
- [System.Security.SecurityCritical] // auto-generated
private int GetMemberRefToken(MethodBase methodInfo, Type[] optionalParameterTypes)
{
Type[] parameterTypes;
@@ -494,7 +489,7 @@ namespace System.Reflection.Emit
DynamicMethod dm = methodInfo as DynamicMethod;
if (rtMeth == null && dm == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), "methodInfo");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), nameof(methodInfo));
ParameterInfo[] paramInfo = methodInfo.GetParametersNoCopy();
if (paramInfo != null && paramInfo.Length != 0)
@@ -519,7 +514,6 @@ namespace System.Reflection.Emit
return GetTokenForVarArgMethod(dm, sig);
}
- [System.Security.SecurityCritical] // auto-generated
internal override SignatureHelper GetMemberRefSignature(
CallingConventions call,
Type returnType,
@@ -704,9 +698,6 @@ namespace System.Reflection.Emit
m_method.m_resolver = this;
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
internal DynamicResolver(DynamicILInfo dynamicILInfo)
{
m_stackSize = dynamicILInfo.MaxStackSize;
@@ -774,7 +765,6 @@ namespace System.Reflection.Emit
{
internal RuntimeMethodHandleInternal m_methodHandle;
- [System.Security.SecuritySafeCritical] // auto-generated
~DestroyScout()
{
if (m_methodHandle.IsNullHandle())
@@ -887,7 +877,6 @@ namespace System.Reflection.Emit
return m_exceptionHeader;
}
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe void GetEHInfo(int excNumber, void* exc)
{
CORINFO_EH_CLAUSE* exception = (CORINFO_EH_CLAUSE*)exc;
@@ -922,7 +911,6 @@ namespace System.Reflection.Emit
}
#endif // FEATURE_COMPRESSEDSTACK
- [System.Security.SecurityCritical]
internal override void ResolveToken(int token, out IntPtr typeHandle, out IntPtr methodHandle, out IntPtr fieldHandle)
{
typeHandle = new IntPtr();
@@ -1003,9 +991,6 @@ namespace System.Reflection.Emit
}
-#if FEATURE_CORECLR
-[System.Security.SecurityCritical] // auto-generated
-#endif
[System.Runtime.InteropServices.ComVisible(true)]
public class DynamicILInfo
{
@@ -1032,7 +1017,6 @@ namespace System.Reflection.Emit
#endregion
#region Internal Methods
- [System.Security.SecurityCritical] // auto-generated
internal void GetCallableMethod(RuntimeModule module, DynamicMethod dm)
{
dm.m_methodHandle = ModuleHandle.GetDynamicMethod(dm,
@@ -1064,15 +1048,14 @@ namespace System.Reflection.Emit
m_maxStackSize = maxStackSize;
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
public unsafe void SetCode(byte* code, int codeSize, int maxStackSize)
{
if (codeSize < 0)
- throw new ArgumentOutOfRangeException("codeSize", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
+ throw new ArgumentOutOfRangeException(nameof(codeSize), Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
if (codeSize > 0 && code == null)
- throw new ArgumentNullException("code");
+ throw new ArgumentNullException(nameof(code));
Contract.EndContractBlock();
m_code = new byte[codeSize];
@@ -1090,15 +1073,14 @@ namespace System.Reflection.Emit
m_exceptions = (exceptions != null) ? (byte[])exceptions.Clone() : EmptyArray<Byte>.Value;
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
public unsafe void SetExceptions(byte* exceptions, int exceptionsSize)
{
if (exceptionsSize < 0)
- throw new ArgumentOutOfRangeException("exceptionsSize", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
+ throw new ArgumentOutOfRangeException(nameof(exceptionsSize), Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
if (exceptionsSize > 0 && exceptions == null)
- throw new ArgumentNullException("exceptions");
+ throw new ArgumentNullException(nameof(exceptions));
Contract.EndContractBlock();
m_exceptions = new byte[exceptionsSize];
@@ -1115,15 +1097,14 @@ namespace System.Reflection.Emit
m_localSignature = (localSignature != null) ? (byte[])localSignature.Clone() : EmptyArray<Byte>.Value;
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
public unsafe void SetLocalSignature(byte* localSignature, int signatureSize)
{
if (signatureSize < 0)
- throw new ArgumentOutOfRangeException("signatureSize", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
+ throw new ArgumentOutOfRangeException(nameof(signatureSize), Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
if (signatureSize > 0 && localSignature == null)
- throw new ArgumentNullException("localSignature");
+ throw new ArgumentNullException(nameof(localSignature));
Contract.EndContractBlock();
m_localSignature = new byte[signatureSize];
@@ -1136,7 +1117,6 @@ namespace System.Reflection.Emit
#endregion
#region Public Scope Methods
- [System.Security.SecuritySafeCritical] // auto-generated
public int GetTokenFor(RuntimeMethodHandle method)
{
return DynamicScope.GetTokenFor(method);
@@ -1222,7 +1202,6 @@ namespace System.Reflection.Emit
#endregion
#region Public Methods
- [System.Security.SecuritySafeCritical] // auto-generated
public int GetTokenFor(RuntimeMethodHandle method)
{
IRuntimeMethodInfo methodReal = method.GetMethodInfo();
diff --git a/src/mscorlib/src/System/Reflection/Emit/DynamicMethod.cs b/src/mscorlib/src/System/Reflection/Emit/DynamicMethod.cs
index 6f6b436706..1b8c97de65 100644
--- a/src/mscorlib/src/System/Reflection/Emit/DynamicMethod.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/DynamicMethod.cs
@@ -15,6 +15,7 @@ namespace System.Reflection.Emit
using System.Threading;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
@@ -25,9 +26,6 @@ namespace System.Reflection.Emit
internal IRuntimeMethodInfo m_methodHandle;
private RuntimeType m_returnType;
private DynamicILGenerator m_ilGenerator;
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
private DynamicILInfo m_DynamicILInfo;
private bool m_fInitLocals;
private RuntimeModule m_module;
@@ -72,7 +70,6 @@ namespace System.Reflection.Emit
private DynamicMethod() { }
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public DynamicMethod(string name,
Type returnType,
@@ -92,7 +89,6 @@ namespace System.Reflection.Emit
ref stackMark); // transparentMethod
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public DynamicMethod(string name,
Type returnType,
@@ -113,11 +109,6 @@ namespace System.Reflection.Emit
ref stackMark); // transparentMethod
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #else
- [System.Security.SecuritySafeCritical]
- #endif
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public DynamicMethod(string name,
Type returnType,
@@ -137,11 +128,6 @@ namespace System.Reflection.Emit
ref stackMark); // transparentMethod
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #else
- [System.Security.SecuritySafeCritical]
- #endif
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public DynamicMethod(string name,
Type returnType,
@@ -162,11 +148,6 @@ namespace System.Reflection.Emit
ref stackMark); // transparentMethod
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #else
- [System.Security.SecuritySafeCritical]
- #endif
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public DynamicMethod(string name,
MethodAttributes attributes,
@@ -189,11 +170,6 @@ namespace System.Reflection.Emit
ref stackMark); // transparentMethod
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #else
- [System.Security.SecuritySafeCritical]
- #endif
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public DynamicMethod(string name,
Type returnType,
@@ -213,11 +189,6 @@ namespace System.Reflection.Emit
ref stackMark); // transparentMethod
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #else
- [System.Security.SecuritySafeCritical]
- #endif
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public DynamicMethod(string name,
Type returnType,
@@ -238,11 +209,6 @@ namespace System.Reflection.Emit
ref stackMark); // transparentMethod
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #else
- [System.Security.SecuritySafeCritical]
- #endif
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public DynamicMethod(string name,
MethodAttributes attributes,
@@ -286,7 +252,6 @@ namespace System.Reflection.Emit
// 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
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
private static RuntimeModule GetDynamicMethodsModule()
{
@@ -302,21 +267,6 @@ namespace System.Reflection.Emit
CustomAttributeBuilder transparencyAttribute = new CustomAttributeBuilder(transparencyCtor, EmptyArray<Object>.Value);
List<CustomAttributeBuilder> assemblyAttributes = new List<CustomAttributeBuilder>();
assemblyAttributes.Add(transparencyAttribute);
-#if !FEATURE_CORECLR
- // On the desktop, we need to use the security rule set level 1 for anonymously hosted
- // dynamic methods. In level 2, transparency rules are strictly enforced, which leads to
- // errors when a fully trusted application causes a dynamic method to be generated that tries
- // to call a method with a LinkDemand or a SecurityCritical method. To retain compatibility
- // with the v2.0 and v3.x frameworks, these calls should be allowed.
- //
- // If this rule set was not explicitly called out, then the anonymously hosted dynamic methods
- // assembly would inherit the rule set from the creating assembly - which would cause it to
- // be level 2 because mscorlib.dll is using the level 2 rules.
- ConstructorInfo securityRulesCtor = typeof(SecurityRulesAttribute).GetConstructor(new Type[] { typeof(SecurityRuleSet) });
- CustomAttributeBuilder securityRulesAttribute =
- new CustomAttributeBuilder(securityRulesCtor, new object[] { SecurityRuleSet.Level1 });
- assemblyAttributes.Add(securityRulesAttribute);
-#endif // !FEATURE_CORECLR
AssemblyName assemblyName = new AssemblyName("Anonymously Hosted DynamicMethods Assembly");
StackCrawlMark stackMark = StackCrawlMark.LookForMe;
@@ -338,7 +288,6 @@ namespace System.Reflection.Emit
return s_anonymouslyHostedDynamicMethodsModule;
}
- [System.Security.SecurityCritical] // auto-generated
private unsafe void Init(String name,
MethodAttributes attributes,
CallingConventions callingConvention,
@@ -374,7 +323,7 @@ namespace System.Reflection.Emit
if (transparentMethod)
{
- Contract.Assert(owner == null && m == null, "owner and m cannot be set for transparent methods");
+ Debug.Assert(owner == null && m == null, "owner and m cannot be set for transparent methods");
m_module = GetDynamicMethodsModule();
if (skipVisibility)
{
@@ -387,9 +336,9 @@ namespace System.Reflection.Emit
}
else
{
- Contract.Assert(m != null || owner != null, "PerformSecurityCheck should ensure that either m or owner is set");
- Contract.Assert(m == null || !m.Equals(s_anonymouslyHostedDynamicMethodsModule), "The user cannot explicitly use this assembly");
- Contract.Assert(m == null || owner == null, "m and owner cannot both be set");
+ Debug.Assert(m != null || owner != null, "PerformSecurityCheck 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");
if (m != null)
m_module = m.ModuleHandle.GetRuntimeModule(); // this returns the underlying module for all RuntimeModule and ModuleBuilder objects.
@@ -419,7 +368,7 @@ namespace System.Reflection.Emit
m_methodHandle = null;
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
#if FEATURE_APPX
if (AppDomain.ProfileAPICheck)
@@ -435,101 +384,23 @@ namespace System.Reflection.Emit
m_dynMethod = new RTDynamicMethod(this, name, attributes, callingConvention);
}
- [System.Security.SecurityCritical] // auto-generated
private void PerformSecurityCheck(Module m, ref StackCrawlMark stackMark, bool skipVisibility)
{
if (m == null)
- throw new ArgumentNullException("m");
+ throw new ArgumentNullException(nameof(m));
Contract.EndContractBlock();
-#if !FEATURE_CORECLR
-
- RuntimeModule rtModule;
- ModuleBuilder mb = m as ModuleBuilder;
- if (mb != null)
- rtModule = mb.InternalModule;
- else
- rtModule = m as RuntimeModule;
-
- if (rtModule == null)
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeModule"), "m");
- }
-
- // The user cannot explicitly use this assembly
- if (rtModule == s_anonymouslyHostedDynamicMethodsModule)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidValue"), "m");
-
- // ask for member access if skip visibility
- if (skipVisibility)
- new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand();
-
-#if !FEATURE_CORECLR
- // ask for control evidence if outside of the caller assembly
- RuntimeType callingType = RuntimeMethodHandle.GetCallerType(ref stackMark);
- m_creatorAssembly = callingType.GetRuntimeAssembly();
- if (m.Assembly != m_creatorAssembly)
- {
- // Demand the permissions of the assembly where the DynamicMethod will live
- CodeAccessSecurityEngine.ReflectionTargetDemandHelper(PermissionType.SecurityControlEvidence,
- m.Assembly.PermissionSet);
- }
-#else //FEATURE_CORECLR
-#pragma warning disable 618
- new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand();
-#pragma warning restore 618
-#endif //FEATURE_CORECLR
-#endif //!FEATURE_CORECLR
}
- [System.Security.SecurityCritical] // auto-generated
private void PerformSecurityCheck(Type owner, ref StackCrawlMark stackMark, bool skipVisibility)
{
if (owner == null)
- throw new ArgumentNullException("owner");
-#if !FEATURE_CORECLR
-
- RuntimeType rtOwner = owner as RuntimeType;
- if (rtOwner == null)
- rtOwner = owner.UnderlyingSystemType as RuntimeType;
-
- if (rtOwner == null)
- throw new ArgumentNullException("owner", Environment.GetResourceString("Argument_MustBeRuntimeType"));
-
- // get the type the call is coming from
- RuntimeType callingType = RuntimeMethodHandle.GetCallerType(ref stackMark);
-
- // ask for member access if skip visibility
- if (skipVisibility)
- new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand();
- else
- {
- // if the call is not coming from the same class ask for member access
- if (callingType != rtOwner)
- new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand();
- }
-#if !FEATURE_CORECLR
- m_creatorAssembly = callingType.GetRuntimeAssembly();
-
- // ask for control evidence if outside of the caller module
- if (rtOwner.Assembly != m_creatorAssembly)
- {
- // Demand the permissions of the assembly where the DynamicMethod will live
- CodeAccessSecurityEngine.ReflectionTargetDemandHelper(PermissionType.SecurityControlEvidence,
- owner.Assembly.PermissionSet);
- }
-#else //FEATURE_CORECLR
-#pragma warning disable 618
- new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand();
-#pragma warning restore 618
-#endif //FEATURE_CORECLR
-#endif //!FEATURE_CORECLR
+ throw new ArgumentNullException(nameof(owner));
}
//
// Delegate and method creation
//
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(true)]
public sealed override Delegate CreateDelegate(Type delegateType) {
if (m_restrictedSkipVisibility)
@@ -545,7 +416,6 @@ namespace System.Reflection.Emit
return d;
}
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(true)]
public sealed override Delegate CreateDelegate(Type delegateType, Object target) {
if (m_restrictedSkipVisibility)
@@ -578,7 +448,6 @@ namespace System.Reflection.Emit
#endif
// This is guaranteed to return a valid handle
- [System.Security.SecurityCritical] // auto-generated
internal unsafe RuntimeMethodHandle GetMethodDescriptor() {
if (m_methodHandle == null) {
lock (this) {
@@ -636,83 +505,19 @@ namespace System.Reflection.Emit
public override bool IsSecurityCritical
{
- [SecuritySafeCritical]
- get
- {
- if (m_methodHandle != null)
- {
- return RuntimeMethodHandle.IsSecurityCritical(m_methodHandle);
- }
- else if (m_typeOwner != null)
- {
- RuntimeAssembly assembly = m_typeOwner.Assembly as RuntimeAssembly;
- Contract.Assert(assembly != null);
-
- return assembly.IsAllSecurityCritical();
- }
- else
- {
- RuntimeAssembly assembly = m_module.Assembly as RuntimeAssembly;
- Contract.Assert(assembly != null);
-
- return assembly.IsAllSecurityCritical();
- }
- }
+ get { return true; }
}
public override bool IsSecuritySafeCritical
{
- [SecuritySafeCritical]
- get
- {
- if (m_methodHandle != null)
- {
- return RuntimeMethodHandle.IsSecuritySafeCritical(m_methodHandle);
- }
- else if (m_typeOwner != null)
- {
- RuntimeAssembly assembly = m_typeOwner.Assembly as RuntimeAssembly;
- Contract.Assert(assembly != null);
-
- return assembly.IsAllPublicAreaSecuritySafeCritical();
- }
- else
- {
- RuntimeAssembly assembly = m_module.Assembly as RuntimeAssembly;
- Contract.Assert(assembly != null);
-
- return assembly.IsAllSecuritySafeCritical();
- }
- }
+ get { return false; }
}
public override bool IsSecurityTransparent
{
- [SecuritySafeCritical]
- get
- {
- if (m_methodHandle != null)
- {
- return RuntimeMethodHandle.IsSecurityTransparent(m_methodHandle);
- }
- else if (m_typeOwner != null)
- {
- RuntimeAssembly assembly = m_typeOwner.Assembly as RuntimeAssembly;
- Contract.Assert(assembly != null);
-
- return !assembly.IsAllSecurityCritical();
- }
- else
- {
- RuntimeAssembly assembly = m_module.Assembly as RuntimeAssembly;
- Contract.Assert(assembly != null);
-
- return !assembly.IsAllSecurityCritical();
- }
- }
+ get { return false; }
}
- [System.Security.SecuritySafeCritical] // auto-generated
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"));
@@ -789,7 +594,6 @@ namespace System.Reflection.Emit
return null;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public DynamicILInfo GetDynamicILInfo()
{
#pragma warning disable 618
@@ -802,7 +606,6 @@ namespace System.Reflection.Emit
return GetDynamicILInfo(new DynamicScope());
}
- [System.Security.SecurityCritical] // auto-generated
internal DynamicILInfo GetDynamicILInfo(DynamicScope scope)
{
if (m_DynamicILInfo == null)
@@ -819,7 +622,6 @@ namespace System.Reflection.Emit
return GetILGenerator(64);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public ILGenerator GetILGenerator(int streamSize)
{
if (m_ilGenerator == null)
@@ -935,7 +737,7 @@ namespace System.Reflection.Emit
public override Object[] GetCustomAttributes(Type attributeType, bool inherit) {
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
Contract.EndContractBlock();
if (attributeType.IsAssignableFrom(typeof(MethodImplAttribute)))
@@ -951,7 +753,7 @@ namespace System.Reflection.Emit
public override bool IsDefined(Type attributeType, bool inherit) {
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
Contract.EndContractBlock();
if (attributeType.IsAssignableFrom(typeof(MethodImplAttribute)))
diff --git a/src/mscorlib/src/System/Reflection/Emit/EnumBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/EnumBuilder.cs
index f8e3ab2991..82dc2828ca 100644
--- a/src/mscorlib/src/System/Reflection/Emit/EnumBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/EnumBuilder.cs
@@ -23,7 +23,6 @@ namespace System.Reflection.Emit {
using System.Security.Permissions;
- [HostProtection(MayLeakOnAbort = true)]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_EnumBuilder))]
[System.Runtime.InteropServices.ComVisible(true)]
@@ -313,9 +312,6 @@ namespace System.Reflection.Emit {
// Use this function if client decides to form the custom attribute blob themselves
-#if FEATURE_CORECLR
-[System.Security.SecurityCritical] // auto-generated
-#endif
[System.Runtime.InteropServices.ComVisible(true)]
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
{
@@ -398,7 +394,6 @@ namespace System.Reflection.Emit {
// Constructs a EnumBuilder.
// EnumBuilder can only be a top-level (not nested) enum type.
- [System.Security.SecurityCritical] // auto-generated
internal EnumBuilder(
String name, // name of type
Type underlyingType, // underlying type for an Enum
@@ -407,36 +402,13 @@ namespace System.Reflection.Emit {
{
// Client should not set any bits other than the visibility bits.
if ((visibility & ~TypeAttributes.VisibilityMask) != 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_ShouldOnlySetVisibilityFlags"), "name");
+ throw new ArgumentException(Environment.GetResourceString("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.
m_underlyingField = m_typeBuilder.DefineField("value__", underlyingType, FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName);
}
-#if !FEATURE_CORECLR
- void _EnumBuilder.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _EnumBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _EnumBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- void _EnumBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
-#endif
-
-
/*****************************************************
*
* private data members
diff --git a/src/mscorlib/src/System/Reflection/Emit/EventBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/EventBuilder.cs
index 42a5252102..449b20824c 100644
--- a/src/mscorlib/src/System/Reflection/Emit/EventBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/EventBuilder.cs
@@ -24,7 +24,6 @@ namespace System.Reflection.Emit {
// A EventBuilder is always associated with a TypeBuilder. The TypeBuilder.DefineEvent
// method will return a new EventBuilder to a client.
//
- [HostProtection(MayLeakOnAbort = true)]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_EventBuilder))]
[System.Runtime.InteropServices.ComVisible(true)]
@@ -58,12 +57,11 @@ namespace System.Reflection.Emit {
return m_evToken;
}
- [System.Security.SecurityCritical] // auto-generated
private void SetMethodSemantics(MethodBuilder mdBuilder, MethodSemanticsAttributes semantics)
{
if (mdBuilder == null)
{
- throw new ArgumentNullException("mdBuilder");
+ throw new ArgumentNullException(nameof(mdBuilder));
}
Contract.EndContractBlock();
@@ -75,25 +73,21 @@ namespace System.Reflection.Emit {
mdBuilder.GetToken().Token);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void SetAddOnMethod(MethodBuilder mdBuilder)
{
SetMethodSemantics(mdBuilder, MethodSemanticsAttributes.AddOn);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void SetRemoveOnMethod(MethodBuilder mdBuilder)
{
SetMethodSemantics(mdBuilder, MethodSemanticsAttributes.RemoveOn);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void SetRaiseMethod(MethodBuilder mdBuilder)
{
SetMethodSemantics(mdBuilder, MethodSemanticsAttributes.Fire);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void AddOtherMethod(MethodBuilder mdBuilder)
{
SetMethodSemantics(mdBuilder, MethodSemanticsAttributes.Other);
@@ -101,18 +95,13 @@ namespace System.Reflection.Emit {
// Use this function if client decides to form the custom attribute blob themselves
-#if FEATURE_CORECLR
-[System.Security.SecurityCritical] // auto-generated
-#else
-[System.Security.SecuritySafeCritical]
-#endif
[System.Runtime.InteropServices.ComVisible(true)]
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
{
if (con == null)
- throw new ArgumentNullException("con");
+ throw new ArgumentNullException(nameof(con));
if (binaryAttribute == null)
- throw new ArgumentNullException("binaryAttribute");
+ throw new ArgumentNullException(nameof(binaryAttribute));
Contract.EndContractBlock();
m_type.ThrowIfCreated();
@@ -125,41 +114,17 @@ namespace System.Reflection.Emit {
}
// Use this function if client wishes to build CustomAttribute using CustomAttributeBuilder
- [System.Security.SecuritySafeCritical] // auto-generated
public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
{
if (customBuilder == null)
{
- throw new ArgumentNullException("customBuilder");
+ throw new ArgumentNullException(nameof(customBuilder));
}
Contract.EndContractBlock();
m_type.ThrowIfCreated();
customBuilder.CreateCustomAttribute(m_module, m_evToken.Token);
}
-#if !FEATURE_CORECLR
- void _EventBuilder.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _EventBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _EventBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- void _EventBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
-#endif
-
-
// 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
@@ -167,8 +132,4 @@ namespace System.Reflection.Emit {
private EventAttributes m_attributes;
private TypeBuilder m_type;
}
-
-
-
-
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/FieldBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/FieldBuilder.cs
index 0f2de5be43..595d60ada0 100644
--- a/src/mscorlib/src/System/Reflection/Emit/FieldBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/FieldBuilder.cs
@@ -13,7 +13,6 @@ namespace System.Reflection.Emit
using System.Security.Permissions;
using System.Diagnostics.Contracts;
- [HostProtection(MayLeakOnAbort = true)]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_FieldBuilder))]
[System.Runtime.InteropServices.ComVisible(true)]
@@ -29,21 +28,20 @@ namespace System.Reflection.Emit
#endregion
#region Constructor
- [System.Security.SecurityCritical] // auto-generated
internal FieldBuilder(TypeBuilder typeBuilder, String fieldName, Type type,
Type[] requiredCustomModifiers, Type[] optionalCustomModifiers, FieldAttributes attributes)
{
if (fieldName == null)
- throw new ArgumentNullException("fieldName");
+ throw new ArgumentNullException(nameof(fieldName));
if (fieldName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "fieldName");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(fieldName));
if (fieldName[0] == '\0')
- throw new ArgumentException(Environment.GetResourceString("Argument_IllegalName"), "fieldName");
+ throw new ArgumentException(Environment.GetResourceString("Argument_IllegalName"), nameof(fieldName));
if (type == null)
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
if (type == typeof(void))
throw new ArgumentException(Environment.GetResourceString("Argument_BadFieldType"));
@@ -69,7 +67,6 @@ namespace System.Reflection.Emit
#endregion
#region Internal Members
- [System.Security.SecurityCritical] // auto-generated
internal void SetData(byte[] data, int size)
{
ModuleBuilder.SetFieldRVAContent(m_typeBuilder.GetModuleBuilder().GetNativeHandle(), m_tkField.Token, data, size);
@@ -181,11 +178,6 @@ namespace System.Reflection.Emit
return m_tkField;
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #else
- [System.Security.SecuritySafeCritical]
- #endif
public void SetOffset(int iOffset)
{
m_typeBuilder.ThrowIfCreated();
@@ -193,12 +185,11 @@ namespace System.Reflection.Emit
TypeBuilder.SetFieldLayoutOffset(m_typeBuilder.GetModuleBuilder().GetNativeHandle(), GetToken().Token, iOffset);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[Obsolete("An alternate API is available: Emit the MarshalAs custom attribute instead. http://go.microsoft.com/fwlink/?linkid=14202")]
public void SetMarshal(UnmanagedMarshal unmanagedMarshal)
{
if (unmanagedMarshal == null)
- throw new ArgumentNullException("unmanagedMarshal");
+ throw new ArgumentNullException(nameof(unmanagedMarshal));
Contract.EndContractBlock();
m_typeBuilder.ThrowIfCreated();
@@ -208,7 +199,6 @@ namespace System.Reflection.Emit
TypeBuilder.SetFieldMarshal(m_typeBuilder.GetModuleBuilder().GetNativeHandle(), GetToken().Token, ubMarshal, ubMarshal.Length);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void SetConstant(Object defaultValue)
{
m_typeBuilder.ThrowIfCreated();
@@ -217,19 +207,14 @@ namespace System.Reflection.Emit
}
-#if FEATURE_CORECLR
-[System.Security.SecurityCritical] // auto-generated
-#else
-[System.Security.SecuritySafeCritical]
-#endif
[System.Runtime.InteropServices.ComVisible(true)]
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
{
if (con == null)
- throw new ArgumentNullException("con");
+ throw new ArgumentNullException(nameof(con));
if (binaryAttribute == null)
- throw new ArgumentNullException("binaryAttribute");
+ throw new ArgumentNullException(nameof(binaryAttribute));
Contract.EndContractBlock();
ModuleBuilder module = m_typeBuilder.Module as ModuleBuilder;
@@ -240,11 +225,10 @@ namespace System.Reflection.Emit
m_tkField.Token, module.GetConstructorToken(con).Token, binaryAttribute, false, false);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
{
if (customBuilder == null)
- throw new ArgumentNullException("customBuilder");
+ throw new ArgumentNullException(nameof(customBuilder));
Contract.EndContractBlock();
m_typeBuilder.ThrowIfCreated();
@@ -255,27 +239,5 @@ namespace System.Reflection.Emit
}
#endregion
-
-#if !FEATURE_CORECLR
- void _FieldBuilder.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _FieldBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _FieldBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- void _FieldBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
-#endif
}
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/FlowControl.cs b/src/mscorlib/src/System/Reflection/Emit/FlowControl.cs
index 5bfe5bb7bb..31bb564cf4 100644
--- a/src/mscorlib/src/System/Reflection/Emit/FlowControl.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/FlowControl.cs
@@ -26,11 +26,8 @@ public enum FlowControl
Cond_Branch = 3,
Meta = 4,
Next = 5,
-#if !FEATURE_CORECLR
- /// <internalonly/>
[Obsolete("This API has been deprecated. http://go.microsoft.com/fwlink/?linkid=14202")]
Phi = 6,
-#endif
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 bcf70dbe46..6987ea139d 100644
--- a/src/mscorlib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs
@@ -212,9 +212,6 @@ namespace System.Reflection.Emit
#endregion
#region Public Members
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
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 15dece9fcb..ed0763bfda 100644
--- a/src/mscorlib/src/System/Reflection/Emit/ILGenerator.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/ILGenerator.cs
@@ -7,12 +7,12 @@
namespace System.Reflection.Emit
{
using System;
- using TextWriter = System.IO.TextWriter;
using System.Diagnostics.SymbolStore;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Security.Permissions;
using System.Globalization;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
[ClassInterface(ClassInterfaceType.None)]
@@ -210,20 +210,17 @@ namespace System.Reflection.Emit
}
}
- [System.Security.SecurityCritical] // auto-generated
private int GetMethodToken(MethodBase method, Type[] optionalParameterTypes, bool useMethodDef)
{
return ((ModuleBuilder)m_methodBuilder.Module).GetMethodTokenInternal(method, optionalParameterTypes, useMethodDef);
}
- [System.Security.SecurityCritical] // auto-generated
internal virtual SignatureHelper GetMemberRefSignature(CallingConventions call, Type returnType,
Type[] parameterTypes, Type[] optionalParameterTypes)
{
return GetMemberRefSignature(call, returnType, parameterTypes, optionalParameterTypes, 0);
}
- [System.Security.SecurityCritical] // auto-generated
private SignatureHelper GetMemberRefSignature(CallingConventions call, Type returnType,
Type[] parameterTypes, Type[] optionalParameterTypes, int cGenericParameters)
{
@@ -414,7 +411,7 @@ namespace System.Reflection.Emit
{
if (m_RelocFixupCount == 0)
{
- Contract.Assert(m_RelocFixupList == null);
+ Debug.Assert(m_RelocFixupList == null);
return null;
}
@@ -472,11 +469,10 @@ namespace System.Reflection.Emit
PutInteger4(arg);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public virtual void Emit(OpCode opcode, MethodInfo meth)
{
if (meth == null)
- throw new ArgumentNullException("meth");
+ throw new ArgumentNullException(nameof(meth));
Contract.EndContractBlock();
if (opcode.Equals(OpCodes.Call) || opcode.Equals(OpCodes.Callvirt) || opcode.Equals(OpCodes.Newobj))
@@ -504,7 +500,6 @@ namespace System.Reflection.Emit
}
- [System.Security.SecuritySafeCritical] // auto-generated
public virtual void EmitCalli(OpCode opcode, CallingConventions callingConvention,
Type returnType, Type[] parameterTypes, Type[] optionalParameterTypes)
{
@@ -593,14 +588,13 @@ namespace System.Reflection.Emit
PutInteger4(modBuilder.GetSignatureToken(sig).Token);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public virtual void EmitCall(OpCode opcode, MethodInfo methodInfo, Type[] optionalParameterTypes)
{
if (methodInfo == null)
- throw new ArgumentNullException("methodInfo");
+ 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"), "opcode");
+ throw new ArgumentException(Environment.GetResourceString("Argument_NotMethodCallOpcode"), nameof(opcode));
Contract.EndContractBlock();
@@ -634,7 +628,7 @@ namespace System.Reflection.Emit
public virtual void Emit(OpCode opcode, SignatureHelper signature)
{
if (signature == null)
- throw new ArgumentNullException("signature");
+ throw new ArgumentNullException(nameof(signature));
Contract.EndContractBlock();
int stackchange = 0;
@@ -653,7 +647,7 @@ namespace System.Reflection.Emit
// SignatureHelper.
if (opcode.StackBehaviourPop == StackBehaviour.Varpop)
{
- Contract.Assert(opcode.Equals(OpCodes.Calli),
+ Debug.Assert(opcode.Equals(OpCodes.Calli),
"Unexpected opcode encountered for StackBehaviour VarPop.");
// Pop the arguments..
stackchange -= signature.ArgumentCount;
@@ -666,12 +660,11 @@ namespace System.Reflection.Emit
PutInteger4(tempVal);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(true)]
public virtual void Emit(OpCode opcode, ConstructorInfo con)
{
if (con == null)
- throw new ArgumentNullException("con");
+ throw new ArgumentNullException(nameof(con));
Contract.EndContractBlock();
int stackchange = 0;
@@ -687,7 +680,7 @@ namespace System.Reflection.Emit
if (opcode.StackBehaviourPush == StackBehaviour.Varpush)
{
// Instruction must be one of call or callvirt.
- Contract.Assert(opcode.Equals(OpCodes.Call) ||
+ Debug.Assert(opcode.Equals(OpCodes.Call) ||
opcode.Equals(OpCodes.Callvirt),
"Unexpected opcode encountered for StackBehaviour of VarPush.");
stackchange++;
@@ -695,7 +688,7 @@ namespace System.Reflection.Emit
if (opcode.StackBehaviourPop == StackBehaviour.Varpop)
{
// Instruction must be one of call, callvirt or newobj.
- Contract.Assert(opcode.Equals(OpCodes.Call) ||
+ Debug.Assert(opcode.Equals(OpCodes.Call) ||
opcode.Equals(OpCodes.Callvirt) ||
opcode.Equals(OpCodes.Newobj),
"Unexpected opcode encountered for StackBehaviour of VarPop.");
@@ -710,7 +703,6 @@ namespace System.Reflection.Emit
PutInteger4(tk);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public virtual void Emit(OpCode opcode, Type cls)
{
// Puts opcode onto the stream and then the metadata token represented
@@ -750,7 +742,6 @@ namespace System.Reflection.Emit
m_ILStream[m_length++] = (byte) (arg>>56);
}
- [System.Security.SecuritySafeCritical] // auto-generated
unsafe public virtual void Emit(OpCode opcode, float arg) {
EnsureCapacity(7);
InternalEmit(opcode);
@@ -761,7 +752,6 @@ namespace System.Reflection.Emit
m_ILStream[m_length++] = (byte) (tempVal>>24);
}
- [System.Security.SecuritySafeCritical] // auto-generated
unsafe public virtual void Emit(OpCode opcode, double arg) {
EnsureCapacity(11);
InternalEmit(opcode);
@@ -805,7 +795,7 @@ namespace System.Reflection.Emit
public virtual void Emit(OpCode opcode, Label[] labels)
{
if (labels == null)
- throw new ArgumentNullException("labels");
+ throw new ArgumentNullException(nameof(labels));
Contract.EndContractBlock();
// Emitting a switch table
@@ -854,13 +844,13 @@ namespace System.Reflection.Emit
if (local == null)
{
- throw new ArgumentNullException("local");
+ throw new ArgumentNullException(nameof(local));
}
Contract.EndContractBlock();
int tempVal = local.GetLocalIndex();
if (local.GetMethodBuilder() != m_methodBuilder)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_UnmatchedMethodForLocal"), "local");
+ throw new ArgumentException(Environment.GetResourceString("Argument_UnmatchedMethodForLocal"), nameof(local));
}
// If the instruction is a ldloc, ldloca a stloc, morph it to the optimal form.
if (opcode.Equals(OpCodes.Ldloc))
@@ -1020,7 +1010,7 @@ namespace System.Reflection.Emit
public virtual void BeginExceptFilterBlock()
{
- // Begins a eception filter block. Emits a branch instruction to the end of the current exception block.
+ // 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"));
@@ -1051,7 +1041,7 @@ namespace System.Reflection.Emit
} else {
// execute this branch if previous clause is Catch or Fault
if (exceptionType==null) {
- throw new ArgumentNullException("exceptionType");
+ throw new ArgumentNullException(nameof(exceptionType));
}
Label endLabel = current.GetEndLabel();
@@ -1153,7 +1143,7 @@ namespace System.Reflection.Emit
// Emits the il to throw an exception
if (excType==null) {
- throw new ArgumentNullException("excType");
+ throw new ArgumentNullException(nameof(excType));
}
if (!excType.IsSubclassOf(typeof(Exception)) && excType!=typeof(Exception)) {
@@ -1212,9 +1202,9 @@ namespace System.Reflection.Emit
throw new ArgumentException(Environment.GetResourceString("NotSupported_OutputStreamUsingTypeBuilder"));
}
parameterTypes[0] = (Type)cls;
- MethodInfo mi = typeof(TextWriter).GetMethod("WriteLine", parameterTypes);
+ MethodInfo mi = prop.ReturnType.GetMethod("WriteLine", parameterTypes);
if (mi==null) {
- throw new ArgumentException(Environment.GetResourceString("Argument_EmitWriteLineType"), "localBuilder");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmitWriteLineType"), nameof(localBuilder));
}
Emit(OpCodes.Callvirt, mi);
@@ -1231,7 +1221,7 @@ namespace System.Reflection.Emit
if (fld == null)
{
- throw new ArgumentNullException("fld");
+ throw new ArgumentNullException(nameof(fld));
}
Contract.EndContractBlock();
@@ -1250,9 +1240,9 @@ namespace System.Reflection.Emit
throw new NotSupportedException(Environment.GetResourceString("NotSupported_OutputStreamUsingTypeBuilder"));
}
parameterTypes[0] = (Type)cls;
- MethodInfo mi = typeof(TextWriter).GetMethod("WriteLine", parameterTypes);
+ MethodInfo mi = prop.ReturnType.GetMethod("WriteLine", parameterTypes);
if (mi==null) {
- throw new ArgumentException(Environment.GetResourceString("Argument_EmitWriteLineType"), "fld");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmitWriteLineType"), nameof(fld));
}
Emit(OpCodes.Callvirt, mi);
}
@@ -1283,7 +1273,7 @@ namespace System.Reflection.Emit
}
if (localType==null) {
- throw new ArgumentNullException("localType");
+ throw new ArgumentNullException(nameof(localType));
}
if (methodBuilder.m_bIsBaked) {
@@ -1304,10 +1294,10 @@ namespace System.Reflection.Emit
// for the current active lexical scope.
if (usingNamespace == null)
- throw new ArgumentNullException("usingNamespace");
+ throw new ArgumentNullException(nameof(usingNamespace));
if (usingNamespace.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "usingNamespace");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(usingNamespace));
Contract.EndContractBlock();
int index;
@@ -1335,7 +1325,7 @@ namespace System.Reflection.Emit
{
if (startLine == 0 || startLine < 0 || endLine == 0 || endLine < 0)
{
- throw new ArgumentOutOfRangeException("startLine");
+ throw new ArgumentOutOfRangeException(nameof(startLine));
}
Contract.EndContractBlock();
m_LineNumberInfo.AddLineNumberInfo(document, m_length, startLine, startColumn, endLine, endColumn);
@@ -1362,28 +1352,6 @@ namespace System.Reflection.Emit
#endregion
#endregion
-
-#if !FEATURE_CORECLR
- void _ILGenerator.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _ILGenerator.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _ILGenerator.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- void _ILGenerator.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
-#endif
}
internal struct __FixupData
@@ -1472,7 +1440,7 @@ namespace System.Reflection.Emit
m_catchAddr[m_currentCatch] = -1;
if (m_currentCatch > 0)
{
- Contract.Assert(m_catchEndAddr[m_currentCatch-1] == -1,"m_catchEndAddr[m_currentCatch-1] == -1");
+ Debug.Assert(m_catchEndAddr[m_currentCatch-1] == -1,"m_catchEndAddr[m_currentCatch-1] == -1");
m_catchEndAddr[m_currentCatch-1] = catchorfilterAddr;
}
}
@@ -1489,7 +1457,7 @@ namespace System.Reflection.Emit
{
if (m_type[m_currentCatch] != Filter)
{
- Contract.Assert(m_catchEndAddr[m_currentCatch-1] == -1,"m_catchEndAddr[m_currentCatch-1] == -1");
+ Debug.Assert(m_catchEndAddr[m_currentCatch-1] == -1,"m_catchEndAddr[m_currentCatch-1] == -1");
m_catchEndAddr[m_currentCatch-1] = catchEndAddr;
}
}
@@ -1531,9 +1499,9 @@ namespace System.Reflection.Emit
}
internal void Done(int endAddr) {
- Contract.Assert(m_currentCatch > 0,"m_currentCatch > 0");
- Contract.Assert(m_catchAddr[m_currentCatch-1] > 0,"m_catchAddr[m_currentCatch-1] > 0");
- Contract.Assert(m_catchEndAddr[m_currentCatch-1] == -1,"m_catchEndAddr[m_currentCatch-1] == -1");
+ 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;
}
@@ -1596,8 +1564,8 @@ namespace System.Reflection.Emit
// not having a nesting relation.
internal bool IsInner(__ExceptionInfo exc) {
Contract.Requires(exc != null);
- Contract.Assert(m_currentCatch > 0,"m_currentCatch > 0");
- Contract.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;
@@ -1606,7 +1574,7 @@ namespace System.Reflection.Emit
return true;
else if (exc.m_catchEndAddr[exclast] == m_catchEndAddr[last])
{
- Contract.Assert(exc.GetEndAddress() != GetEndAddress(),
+ Debug.Assert(exc.GetEndAddress() != GetEndAddress(),
"exc.GetEndAddress() != GetEndAddress()");
if (exc.GetEndAddress() > GetEndAddress())
return true;
@@ -1762,9 +1730,6 @@ namespace System.Reflection.Emit
}
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
internal void EmitScopeTree(ISymbolWriter symWriter)
{
int i;
@@ -1821,7 +1786,7 @@ namespace System.Reflection.Emit
// make sure that arrays are large enough to hold addition info
i = FindDocument(document);
- Contract.Assert(i < m_DocumentCount, "Bad document look up!");
+ Debug.Assert(i < m_DocumentCount, "Bad document look up!");
m_Documents[i].AddLineNumberInfo(document, iOffset, iStartLine, iStartColumn, iEndLine, iEndColumn);
}
@@ -1874,9 +1839,6 @@ namespace System.Reflection.Emit
}
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
internal void EmitLineNumberInfo(ISymbolWriter symWriter)
{
for (int i = 0; i < m_DocumentCount; i++)
@@ -1912,7 +1874,7 @@ namespace System.Reflection.Emit
int iEndLine,
int iEndColumn)
{
- Contract.Assert(document == m_document, "Bad document look up!");
+ Debug.Assert(document == m_document, "Bad document look up!");
// make sure that arrays are large enough to hold addition info
EnsureCapacity();
@@ -1968,9 +1930,6 @@ namespace System.Reflection.Emit
}
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
internal void EmitLineNumberInfo(ISymbolWriter symWriter)
{
int[] iOffsetsTemp;
diff --git a/src/mscorlib/src/System/Reflection/Emit/ISymWrapperCore.cs b/src/mscorlib/src/System/Reflection/Emit/ISymWrapperCore.cs
index 00fdd00315..a737895829 100644
--- a/src/mscorlib/src/System/Reflection/Emit/ISymWrapperCore.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/ISymWrapperCore.cs
@@ -2,10 +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.
-//
-
-#if FEATURE_CORECLR
-
namespace System.Reflection.Emit
{
using System;
@@ -14,7 +10,6 @@ namespace System.Reflection.Emit
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.
@@ -58,9 +53,6 @@ namespace System.Reflection.Emit
//------------------------------------------------------------------------------
// Ctor
//------------------------------------------------------------------------------
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
internal SymDocumentWriter(PunkSafeHandle pDocumentWriterSafeHandle)
{
m_pDocumentWriterSafeHandle = pDocumentWriterSafeHandle;
@@ -72,9 +64,6 @@ namespace System.Reflection.Emit
//------------------------------------------------------------------------------
// Returns the underlying ISymUnmanagedDocumentWriter* (as a safehandle.)
//------------------------------------------------------------------------------
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
internal PunkSafeHandle GetUnmanaged()
{
return m_pDocumentWriterSafeHandle;
@@ -97,9 +86,6 @@ namespace System.Reflection.Emit
//------------------------------------------------------------------------------
// SetCheckSum() wrapper
//------------------------------------------------------------------------------
- #if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical]
- #endif
void ISymbolDocumentWriter.SetCheckSum(Guid algorithmId, byte [] checkSum)
{
int hr = m_vtable.SetCheckSum(m_pDocWriter, algorithmId, (uint)checkSum.Length, checkSum);
@@ -109,7 +95,6 @@ namespace System.Reflection.Emit
}
}
- [System.Security.SecurityCritical]
private delegate int DSetCheckSum(ISymUnmanagedDocumentWriter * pThis, Guid algorithmId, uint checkSumSize, [In] byte[] checkSum);
//------------------------------------------------------------------------------
@@ -117,7 +102,6 @@ namespace System.Reflection.Emit
// exactly. If a member is declared as an IntPtr rather than a delegate, it means
// we don't call that particular member.
//------------------------------------------------------------------------------
- [System.Security.SecurityCritical]
[StructLayout(LayoutKind.Sequential)]
private struct ISymUnmanagedDocumentWriterVTable
{
@@ -126,9 +110,6 @@ namespace System.Reflection.Emit
internal IntPtr Release;
internal IntPtr SetSource;
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical]
- #endif
internal DSetCheckSum SetCheckSum;
}
@@ -136,7 +117,6 @@ namespace System.Reflection.Emit
// This layout must match the (start) of the unmanaged ISymUnmanagedDocumentWriter
// COM object.
//------------------------------------------------------------------------------
- [System.Security.SecurityCritical]
[StructLayout(LayoutKind.Sequential)]
private struct ISymUnmanagedDocumentWriter
{
@@ -146,19 +126,14 @@ namespace System.Reflection.Emit
//------------------------------------------------------------------------------
// Stores underlying ISymUnmanagedDocumentWriter* pointer (wrapped in a safehandle.)
//------------------------------------------------------------------------------
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
private PunkSafeHandle m_pDocumentWriterSafeHandle;
- [SecurityCritical]
private ISymUnmanagedDocumentWriter * m_pDocWriter;
//------------------------------------------------------------------------------
// Stores the "managed vtable" (actually a structure full of delegates that
// P/Invoke to the corresponding unmanaged COM methods.)
//------------------------------------------------------------------------------
- [SecurityCritical]
private ISymUnmanagedDocumentWriterVTable m_vtable;
@@ -212,9 +187,6 @@ namespace System.Reflection.Emit
//------------------------------------------------------------------------------
// DefineDocument() wrapper
//------------------------------------------------------------------------------
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
ISymbolDocumentWriter ISymbolWriter.DefineDocument(String url,
Guid language,
Guid languageVendor,
@@ -237,9 +209,6 @@ namespace System.Reflection.Emit
//------------------------------------------------------------------------------
// SetUserEntryPoint() wrapper
//------------------------------------------------------------------------------
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
void ISymbolWriter.SetUserEntryPoint(SymbolToken entryMethod)
{
int hr = m_vtable.SetUserEntryPoint(m_pWriter, entryMethod.GetToken());
@@ -252,9 +221,6 @@ namespace System.Reflection.Emit
//------------------------------------------------------------------------------
// OpenMethod() wrapper
//------------------------------------------------------------------------------
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
void ISymbolWriter.OpenMethod(SymbolToken method)
{
int hr = m_vtable.OpenMethod(m_pWriter, method.GetToken());
@@ -267,9 +233,6 @@ namespace System.Reflection.Emit
//------------------------------------------------------------------------------
// CloseMethod() wrapper
//------------------------------------------------------------------------------
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
void ISymbolWriter.CloseMethod()
{
int hr = m_vtable.CloseMethod(m_pWriter);
@@ -282,9 +245,6 @@ namespace System.Reflection.Emit
//------------------------------------------------------------------------------
// DefineSequencePoints() wrapper
//------------------------------------------------------------------------------
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
void ISymbolWriter.DefineSequencePoints(ISymbolDocumentWriter document,
int[] offsets,
int[] lines,
@@ -344,9 +304,6 @@ namespace System.Reflection.Emit
//------------------------------------------------------------------------------
// OpenScope() wrapper
//------------------------------------------------------------------------------
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
int ISymbolWriter.OpenScope(int startOffset)
{
int ret;
@@ -361,9 +318,6 @@ namespace System.Reflection.Emit
//------------------------------------------------------------------------------
// CloseScope() wrapper
//------------------------------------------------------------------------------
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
void ISymbolWriter.CloseScope(int endOffset)
{
int hr = m_vtable.CloseScope(m_pWriter, endOffset);
@@ -388,9 +342,6 @@ namespace System.Reflection.Emit
//------------------------------------------------------------------------------
// DefineLocalVariable() wrapper
//------------------------------------------------------------------------------
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
void ISymbolWriter.DefineLocalVariable(String name,
FieldAttributes attributes,
byte[] signature,
@@ -476,9 +427,6 @@ namespace System.Reflection.Emit
//------------------------------------------------------------------------------
// SetSymAttribute() wrapper
//------------------------------------------------------------------------------
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
void ISymbolWriter.SetSymAttribute(SymbolToken parent, String name, byte[] data)
{
int hr = m_vtable.SetSymAttribute(m_pWriter, parent.GetToken(), name, data.Length, data);
@@ -515,9 +463,6 @@ namespace System.Reflection.Emit
//------------------------------------------------------------------------------
// UsingNamespace() wrapper
//------------------------------------------------------------------------------
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
void ISymbolWriter.UsingNamespace(String name)
{
int hr = m_vtable.UsingNamespace(m_pWriter, name);
@@ -557,9 +502,6 @@ namespace System.Reflection.Emit
// with the real ISymWrapper.dll, ISymWrapper performs *no* Release (or AddRef) on pointers
// furnished through SetUnderlyingWriter. Lifetime management is entirely up to the caller.
//------------------------------------------------------------------------------
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
internal void InternalSetUnderlyingWriter(IntPtr ppUnderlyingWriter)
{
m_pWriter = *((ISymUnmanagedWriter**)ppUnderlyingWriter);
@@ -569,7 +511,6 @@ namespace System.Reflection.Emit
//------------------------------------------------------------------------------
// Define delegates for the unmanaged COM methods we invoke.
//------------------------------------------------------------------------------
- [System.Security.SecurityCritical]
private delegate int DInitialize(ISymUnmanagedWriter* pthis,
IntPtr emitter, //IUnknown*
[MarshalAs(UnmanagedType.LPWStr)] String filename, //WCHAR*
@@ -577,7 +518,6 @@ namespace System.Reflection.Emit
[MarshalAs(UnmanagedType.Bool)] bool fFullBuild
);
- [System.Security.SecurityCritical]
private delegate int DDefineDocument(ISymUnmanagedWriter* pthis,
[MarshalAs(UnmanagedType.LPWStr)] String url,
[In] ref Guid language,
@@ -586,14 +526,10 @@ namespace System.Reflection.Emit
[Out] out PunkSafeHandle ppsymUnmanagedDocumentWriter
);
- [System.Security.SecurityCritical]
private delegate int DSetUserEntryPoint(ISymUnmanagedWriter* pthis, int entryMethod);
- [System.Security.SecurityCritical]
private delegate int DOpenMethod(ISymUnmanagedWriter* pthis, int entryMethod);
- [System.Security.SecurityCritical]
private delegate int DCloseMethod(ISymUnmanagedWriter* pthis);
- [System.Security.SecurityCritical]
private delegate int DDefineSequencePoints(ISymUnmanagedWriter* pthis,
PunkSafeHandle document,
int spCount,
@@ -603,15 +539,11 @@ namespace System.Reflection.Emit
[In] int[] endLines,
[In] int[] endColumns);
- [System.Security.SecurityCritical]
private delegate int DOpenScope(ISymUnmanagedWriter* pthis, int startOffset, [Out] out int pretval);
- [System.Security.SecurityCritical]
private delegate int DCloseScope(ISymUnmanagedWriter* pthis, int endOffset);
- [System.Security.SecurityCritical]
private delegate int DSetScopeRange(ISymUnmanagedWriter* pthis, int scopeID, int startOffset, int endOffset);
- [System.Security.SecurityCritical]
private delegate int DDefineLocalVariable(ISymUnmanagedWriter* pthis,
[MarshalAs(UnmanagedType.LPWStr)] String name,
int attributes,
@@ -625,10 +557,8 @@ namespace System.Reflection.Emit
int endOffset
);
- [System.Security.SecurityCritical]
private delegate int DClose(ISymUnmanagedWriter* pthis);
- [System.Security.SecurityCritical]
private delegate int DSetSymAttribute(ISymUnmanagedWriter* pthis,
int parent,
[MarshalAs(UnmanagedType.LPWStr)] String name,
@@ -637,11 +567,8 @@ namespace System.Reflection.Emit
);
- [System.Security.SecurityCritical]
private delegate int DOpenNamespace(ISymUnmanagedWriter* pthis, [MarshalAs(UnmanagedType.LPWStr)] String name);
- [System.Security.SecurityCritical]
private delegate int DCloseNamespace(ISymUnmanagedWriter* pthis);
- [System.Security.SecurityCritical]
private delegate int DUsingNamespace(ISymUnmanagedWriter* pthis, [MarshalAs(UnmanagedType.LPWStr)] String name);
@@ -658,77 +585,32 @@ namespace System.Reflection.Emit
internal IntPtr AddRef;
internal IntPtr Release;
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
internal DDefineDocument DefineDocument;
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
internal DSetUserEntryPoint SetUserEntryPoint;
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
internal DOpenMethod OpenMethod;
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
internal DCloseMethod CloseMethod;
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
internal DOpenScope OpenScope;
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
internal DCloseScope CloseScope;
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
internal DSetScopeRange SetScopeRange;
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
internal DDefineLocalVariable DefineLocalVariable;
internal IntPtr DefineParameter;
internal IntPtr DefineField;
internal IntPtr DefineGlobalVariable;
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
internal DClose Close;
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
internal DSetSymAttribute SetSymAttribute;
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
internal DOpenNamespace OpenNamespace;
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
internal DCloseNamespace CloseNamespace;
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
internal DUsingNamespace UsingNamespace;
internal IntPtr SetMethodSourceRange;
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
internal DInitialize Initialize;
internal IntPtr GetDebugInfo;
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
internal DDefineSequencePoints DefineSequencePoints;
}
@@ -749,7 +631,6 @@ 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).
//------------------------------------------------------------------------------
- [SecurityCritical]
private ISymUnmanagedWriter *m_pWriter;
//------------------------------------------------------------------------------
@@ -778,20 +659,13 @@ namespace System.Reflection.Emit
//
// Had to make this a non-nested class since FCall's don't like to bind to nested classes.
//--------------------------------------------------------------------------------------
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
sealed class PunkSafeHandle : SafeHandle
{
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
internal PunkSafeHandle()
: base((IntPtr)0, true)
{
}
- [SecurityCritical]
override protected bool ReleaseHandle()
{
m_Release(handle);
@@ -800,7 +674,6 @@ namespace System.Reflection.Emit
public override bool IsInvalid
{
- [SecurityCritical]
get { return handle == ((IntPtr)0); }
}
@@ -810,19 +683,10 @@ namespace System.Reflection.Emit
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern IntPtr nGetDReleaseTarget(); // FCall gets us the native DRelease target (so we don't need named dllexport from coreclr.dll)
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
static PunkSafeHandle()
{
m_Release = (DRelease)(Marshal.GetDelegateForFunctionPointer(nGetDReleaseTarget(), typeof(DRelease)));
m_Release((IntPtr)0); // make one call to make sure the delegate is fully prepped before we're in the critical finalizer situation.
}
-
} // PunkSafeHandle
-
} //namespace System.Reflection.Emit
-
-
-#endif //FEATURE_CORECLR
-
diff --git a/src/mscorlib/src/System/Reflection/Emit/LocalBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/LocalBuilder.cs
index 4008703ca7..a34d5ebe5d 100644
--- a/src/mscorlib/src/System/Reflection/Emit/LocalBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/LocalBuilder.cs
@@ -124,28 +124,6 @@ namespace System.Reflection.Emit
}
}
#endregion
-
-#if !FEATURE_CORECLR
- void _LocalBuilder.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _LocalBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _LocalBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- void _LocalBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
-#endif
}
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/MethodBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/MethodBuilder.cs
index 015a73be09..654e166a05 100644
--- a/src/mscorlib/src/System/Reflection/Emit/MethodBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/MethodBuilder.cs
@@ -16,12 +16,12 @@ namespace System.Reflection.Emit
using System.Collections.Generic;
using System.Security.Permissions;
using System.Runtime.InteropServices;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
- [HostProtection(MayLeakOnAbort = true)]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_MethodBuilder))]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public sealed class MethodBuilder : MethodInfo, _MethodBuilder
{
#region Private Data Members
@@ -90,16 +90,16 @@ namespace System.Reflection.Emit
ModuleBuilder mod, TypeBuilder type, bool bIsGlobalMethod)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (name.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name));
if (name[0] == '\0')
- throw new ArgumentException(Environment.GetResourceString("Argument_IllegalName"), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_IllegalName"), nameof(name));
if (mod == null)
- throw new ArgumentNullException("mod");
+ throw new ArgumentNullException(nameof(mod));
Contract.EndContractBlock();
if (parameterTypes != null)
@@ -107,7 +107,7 @@ namespace System.Reflection.Emit
foreach(Type t in parameterTypes)
{
if (t == null)
- throw new ArgumentNullException("parameterTypes");
+ throw new ArgumentNullException(nameof(parameterTypes));
}
}
@@ -196,14 +196,13 @@ namespace System.Reflection.Emit
m_module.CheckContext(types);
}
- [System.Security.SecurityCritical] // auto-generated
internal void CreateMethodBodyHelper(ILGenerator il)
{
// Sets the IL of the method. An ILGenerator is passed as an argument and the method
// queries this instance to get all of the information which it needs.
if (il == null)
{
- throw new ArgumentNullException("il");
+ throw new ArgumentNullException(nameof(il));
}
Contract.EndContractBlock();
@@ -367,7 +366,7 @@ namespace System.Reflection.Emit
}
else
{
- Contract.Assert(false, "We should never get here!");
+ Debug.Assert(false, "We should never get here!");
return null;
}
}
@@ -389,7 +388,6 @@ namespace System.Reflection.Emit
return m_mdMethodFixups;
}
- [System.Security.SecurityCritical] // auto-generated
internal SignatureHelper GetMethodSignature()
{
if (m_parameterTypes == null)
@@ -480,7 +478,6 @@ namespace System.Reflection.Emit
#endregion
#region Object Overrides
- [System.Security.SecuritySafeCritical] // auto-generated
public override bool Equals(Object obj) {
if (!(obj is MethodBuilder)) {
return false;
@@ -505,7 +502,6 @@ namespace System.Reflection.Emit
return this.m_strName.GetHashCode();
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override String ToString()
{
StringBuilder sb = new StringBuilder(1000);
@@ -599,17 +595,17 @@ namespace System.Reflection.Emit
public override bool IsSecurityCritical
{
- get { throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); }
+ get { return true; }
}
public override bool IsSecuritySafeCritical
{
- get { throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); }
+ get { return false; }
}
public override bool IsSecurityTransparent
{
- get { throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); }
+ get { return false; }
}
#endregion
@@ -693,10 +689,10 @@ namespace System.Reflection.Emit
public GenericTypeParameterBuilder[] DefineGenericParameters (params string[] names)
{
if (names == null)
- throw new ArgumentNullException("names");
+ throw new ArgumentNullException(nameof(names));
if (names.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_EmptyArray"), "names");
+ throw new ArgumentException(Environment.GetResourceString("Arg_EmptyArray"), nameof(names));
Contract.EndContractBlock();
if (m_inst != null)
@@ -704,7 +700,7 @@ namespace System.Reflection.Emit
for (int i = 0; i < names.Length; i ++)
if (names[i] == null)
- throw new ArgumentNullException("names");
+ throw new ArgumentNullException(nameof(names));
if (m_tkMethod.Token != 0)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MethodBuilderBaked"));
@@ -721,7 +717,6 @@ namespace System.Reflection.Emit
#endregion
#region Public Members
- [System.Security.SecuritySafeCritical] // auto-generated
public MethodToken GetToken()
{
// We used to always "tokenize" a MethodBuilder when it is constructed. After change list 709498
@@ -767,16 +762,15 @@ namespace System.Reflection.Emit
m_containingType.m_lastTokenizedMethod = i;
}
- Contract.Assert(currentMethod == this, "We should have found this method in m_containingType.m_listMethods");
- Contract.Assert(currentToken.Token != 0, "The token should not be 0");
+ Debug.Assert(currentMethod == this, "We should have found this method in m_containingType.m_listMethods");
+ Debug.Assert(currentToken.Token != 0, "The token should not be 0");
return currentToken;
}
- [System.Security.SecurityCritical] // auto-generated
private MethodToken GetTokenNoLock()
{
- Contract.Assert(m_tkMethod.Token == 0, "m_tkMethod should not have been initialized");
+ Debug.Assert(m_tkMethod.Token == 0, "m_tkMethod should not have been initialized");
int sigLength;
byte[] sigBytes = GetMethodSignature().InternalGetSignature(out sigLength);
@@ -841,7 +835,6 @@ namespace System.Reflection.Emit
}
- [System.Security.SecuritySafeCritical] // auto-generated
public ParameterBuilder DefineParameter(int position, ParameterAttributes attributes, String strParamName)
{
if (position < 0)
@@ -858,7 +851,6 @@ namespace System.Reflection.Emit
return new ParameterBuilder(this, position, attributes, strParamName);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[Obsolete("An alternate API is available: Emit the MarshalAs custom attribute instead. http://go.microsoft.com/fwlink/?linkid=14202")]
public void SetMarshal(UnmanagedMarshal unmanagedMarshal)
{
@@ -915,55 +907,15 @@ namespace System.Reflection.Emit
m_symCustomAttrs.Add(new SymCustomAttr(name, data));
}
-#if FEATURE_CAS_POLICY
- [System.Security.SecuritySafeCritical] // auto-generated
- public void AddDeclarativeSecurity(SecurityAction action, PermissionSet pset)
- {
- if (pset == null)
- throw new ArgumentNullException("pset");
- Contract.EndContractBlock();
-
- ThrowIfGeneric ();
-
-#pragma warning disable 618
- if (!Enum.IsDefined(typeof(SecurityAction), action) ||
- action == SecurityAction.RequestMinimum ||
- action == SecurityAction.RequestOptional ||
- action == SecurityAction.RequestRefuse)
- {
- throw new ArgumentOutOfRangeException("action");
- }
-#pragma warning restore 618
-
- // cannot declarative security after type is created
- m_containingType.ThrowIfCreated();
-
- // Translate permission set into serialized format (uses standard binary serialization format).
- byte[] blob = null;
- int length = 0;
- if (!pset.IsEmpty())
- {
- blob = pset.EncodeXml();
- length = blob.Length;
- }
-
- // Write the blob into the metadata.
- TypeBuilder.AddDeclarativeSecurity(m_module.GetNativeHandle(), MetadataTokenInternal, action, blob, length);
- }
-#endif // FEATURE_CAS_POLICY
-
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
public void SetMethodBody(byte[] il, int maxStack, byte[] localSignature, IEnumerable<ExceptionHandler> exceptionHandlers, IEnumerable<int> tokenFixups)
{
if (il == null)
{
- throw new ArgumentNullException("il", Environment.GetResourceString("ArgumentNull_Array"));
+ throw new ArgumentNullException(nameof(il), Environment.GetResourceString("ArgumentNull_Array"));
}
if (maxStack < 0)
{
- throw new ArgumentOutOfRangeException("maxStack", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(maxStack), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
Contract.EndContractBlock();
@@ -1056,9 +1008,6 @@ namespace System.Reflection.Emit
/// <summary>
/// Obsolete.
/// </summary>
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
public void CreateMethodBody(byte[] il, int count)
{
ThrowIfGeneric();
@@ -1075,7 +1024,7 @@ namespace System.Reflection.Emit
if (il != null && (count < 0 || count > il.Length))
{
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
if (il == null)
@@ -1095,7 +1044,6 @@ namespace System.Reflection.Emit
m_bIsBaked = true;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void SetImplementationFlags(MethodImplAttributes attributes)
{
ThrowIfGeneric ();
@@ -1158,7 +1106,6 @@ namespace System.Reflection.Emit
public String Signature
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
return GetMethodSignature().ToString();
@@ -1166,18 +1113,13 @@ namespace System.Reflection.Emit
}
-#if FEATURE_CORECLR
-[System.Security.SecurityCritical] // auto-generated
-#else
-[System.Security.SecuritySafeCritical]
-#endif
[System.Runtime.InteropServices.ComVisible(true)]
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
{
if (con == null)
- throw new ArgumentNullException("con");
+ throw new ArgumentNullException(nameof(con));
if (binaryAttribute == null)
- throw new ArgumentNullException("binaryAttribute");
+ throw new ArgumentNullException(nameof(binaryAttribute));
Contract.EndContractBlock();
ThrowIfGeneric();
@@ -1191,11 +1133,10 @@ namespace System.Reflection.Emit
ParseCA(con, binaryAttribute);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
{
if (customBuilder == null)
- throw new ArgumentNullException("customBuilder");
+ throw new ArgumentNullException(nameof(customBuilder));
Contract.EndContractBlock();
ThrowIfGeneric();
@@ -1239,29 +1180,6 @@ namespace System.Reflection.Emit
internal bool m_isDllImport = false;
#endregion
-
-#if !FEATURE_CORECLR
- void _MethodBuilder.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _MethodBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _MethodBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- void _MethodBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
-#endif
-
}
internal class LocalSymInfo
@@ -1366,9 +1284,6 @@ namespace System.Reflection.Emit
checked { m_iNameSpaceCount++; }
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
internal virtual void EmitLocalSymInfo(ISymbolWriter symWriter)
{
int i;
@@ -1468,51 +1383,51 @@ namespace System.Reflection.Emit
{
if (tryOffset < 0)
{
- throw new ArgumentOutOfRangeException("tryOffset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(tryOffset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (tryLength < 0)
{
- throw new ArgumentOutOfRangeException("tryLength", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(tryLength), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (filterOffset < 0)
{
- throw new ArgumentOutOfRangeException("filterOffset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(filterOffset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (handlerOffset < 0)
{
- throw new ArgumentOutOfRangeException("handlerOffset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(handlerOffset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (handlerLength < 0)
{
- throw new ArgumentOutOfRangeException("handlerLength", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(handlerLength), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if ((long)tryOffset + tryLength > Int32.MaxValue)
{
- throw new ArgumentOutOfRangeException("tryLength", Environment.GetResourceString("ArgumentOutOfRange_Range", 0, Int32.MaxValue - tryOffset));
+ throw new ArgumentOutOfRangeException(nameof(tryLength), Environment.GetResourceString("ArgumentOutOfRange_Range", 0, Int32.MaxValue - tryOffset));
}
if ((long)handlerOffset + handlerLength > Int32.MaxValue)
{
- throw new ArgumentOutOfRangeException("handlerLength", Environment.GetResourceString("ArgumentOutOfRange_Range", 0, Int32.MaxValue - handlerOffset));
+ throw new ArgumentOutOfRangeException(nameof(handlerLength), Environment.GetResourceString("ArgumentOutOfRange_Range", 0, Int32.MaxValue - handlerOffset));
}
// Other tokens migth also be invalid. We only check nil tokens as the implementation (SectEH_Emit in corhlpr.cpp) requires it,
// and we can't check for valid tokens until the module is baked.
if (kind == ExceptionHandlingClauseOptions.Clause && (exceptionTypeToken & 0x00FFFFFF) == 0)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidTypeToken", exceptionTypeToken), "exceptionTypeToken");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidTypeToken", exceptionTypeToken), nameof(exceptionTypeToken));
}
Contract.EndContractBlock();
if (!IsValidKind(kind))
{
- throw new ArgumentOutOfRangeException("kind", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(kind), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
}
m_tryStartOffset = tryOffset;
@@ -1527,13 +1442,13 @@ namespace System.Reflection.Emit
internal ExceptionHandler(int tryStartOffset, int tryEndOffset, int filterOffset, int handlerStartOffset, int handlerEndOffset,
int kind, int exceptionTypeToken)
{
- Contract.Assert(tryStartOffset >= 0);
- Contract.Assert(tryEndOffset >= 0);
- Contract.Assert(filterOffset >= 0);
- Contract.Assert(handlerStartOffset >= 0);
- Contract.Assert(handlerEndOffset >= 0);
- Contract.Assert(IsValidKind((ExceptionHandlingClauseOptions)kind));
- Contract.Assert(kind != (int)ExceptionHandlingClauseOptions.Clause || (exceptionTypeToken & 0x00FFFFFF) != 0);
+ Debug.Assert(tryStartOffset >= 0);
+ Debug.Assert(tryEndOffset >= 0);
+ Debug.Assert(filterOffset >= 0);
+ Debug.Assert(handlerStartOffset >= 0);
+ Debug.Assert(handlerEndOffset >= 0);
+ Debug.Assert(IsValidKind((ExceptionHandlingClauseOptions)kind));
+ Debug.Assert(kind != (int)ExceptionHandlingClauseOptions.Clause || (exceptionTypeToken & 0x00FFFFFF) != 0);
m_tryStartOffset = tryStartOffset;
m_tryEndOffset = tryEndOffset;
diff --git a/src/mscorlib/src/System/Reflection/Emit/ModuleBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/ModuleBuilder.cs
index ce2a592ae2..6884f50b0e 100644
--- a/src/mscorlib/src/System/Reflection/Emit/ModuleBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/ModuleBuilder.cs
@@ -12,7 +12,6 @@ namespace System.Reflection.Emit
using System.Diagnostics.SymbolStore;
using System.Globalization;
using System.Reflection;
- using System.Diagnostics;
using System.IO;
using System.Resources;
using System.Security;
@@ -22,6 +21,7 @@ namespace System.Reflection.Emit
using System.Threading;
using System.Runtime.Versioning;
using System.Runtime.CompilerServices;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
internal sealed class InternalModuleBuilder : RuntimeModule
@@ -50,7 +50,6 @@ namespace System.Reflection.Emit
}
// deliberately not [serializable]
- [HostProtection(MayLeakOnAbort = true)]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_ModuleBuilder))]
[System.Runtime.InteropServices.ComVisible(true)]
@@ -97,9 +96,6 @@ namespace System.Reflection.Emit
private Dictionary<string, Type> m_TypeBuilderDict;
private ISymbolWriter m_iSymWriter;
internal ModuleBuilderData m_moduleData;
-#if !FEATURE_CORECLR
- private MethodToken m_EntryPoint;
-#endif //!FEATURE_CORECLR
internal InternalModuleBuilder m_internalModuleBuilder;
// This is the "external" AssemblyBuilder
// only the "external" ModuleBuilder has this set
@@ -157,42 +153,35 @@ namespace System.Reflection.Emit
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static int GetTypeRef(RuntimeModule module, String strFullName, RuntimeModule refedModule, String strRefedModuleFileName, int tkResolution);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static int GetMemberRef(RuntimeModule module, RuntimeModule refedModule, int tr, int defToken);
- [System.Security.SecurityCritical] // auto-generated
private int GetMemberRef(Module refedModule, int tr, int defToken)
{
return GetMemberRef(GetNativeHandle(), GetRuntimeModuleFromModule(refedModule).GetNativeHandle(), tr, defToken);
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static int GetMemberRefFromSignature(RuntimeModule module, int tr, String methodName, byte[] signature, int length);
- [System.Security.SecurityCritical] // auto-generated
private int GetMemberRefFromSignature(int tr, String methodName, byte[] signature, int length)
{
return GetMemberRefFromSignature(GetNativeHandle(), tr, methodName, signature, length);
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static int GetMemberRefOfMethodInfo(RuntimeModule module, int tr, IRuntimeMethodInfo method);
- [System.Security.SecurityCritical] // auto-generated
private int GetMemberRefOfMethodInfo(int tr, RuntimeMethodInfo method)
{
- Contract.Assert(method != null);
+ Debug.Assert(method != null);
#if FEATURE_APPX
if (ContainingAssemblyBuilder.ProfileAPICheck)
@@ -205,10 +194,9 @@ namespace System.Reflection.Emit
return GetMemberRefOfMethodInfo(GetNativeHandle(), tr, method);
}
- [System.Security.SecurityCritical] // auto-generated
private int GetMemberRefOfMethodInfo(int tr, RuntimeConstructorInfo method)
{
- Contract.Assert(method != null);
+ Debug.Assert(method != null);
#if FEATURE_APPX
if (ContainingAssemblyBuilder.ProfileAPICheck)
@@ -221,15 +209,13 @@ namespace System.Reflection.Emit
return GetMemberRefOfMethodInfo(GetNativeHandle(), tr, method);
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static int GetMemberRefOfFieldInfo(RuntimeModule module, int tkType, RuntimeTypeHandle declaringType, int tkField);
- [System.Security.SecurityCritical] // auto-generated
private int GetMemberRefOfFieldInfo(int tkType, RuntimeTypeHandle declaringType, RuntimeFieldInfo runtimeField)
{
- Contract.Assert(runtimeField != null);
+ Debug.Assert(runtimeField != null);
#if FEATURE_APPX
if (ContainingAssemblyBuilder.ProfileAPICheck)
@@ -243,38 +229,31 @@ namespace System.Reflection.Emit
return GetMemberRefOfFieldInfo(GetNativeHandle(), tkType, declaringType, runtimeField.MetadataToken);
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static int GetTokenFromTypeSpec(RuntimeModule pModule, byte[] signature, int length);
- [System.Security.SecurityCritical] // auto-generated
private int GetTokenFromTypeSpec(byte[] signature, int length)
{
return GetTokenFromTypeSpec(GetNativeHandle(), signature, length);
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static int GetArrayMethodToken(RuntimeModule module, int tkTypeSpec, String methodName, byte[] signature, int sigLength);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static int GetStringConstant(RuntimeModule module, String str, int length);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void PreSavePEFile(RuntimeModule module, int portableExecutableKind, int imageFileMachine);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void SavePEFile(RuntimeModule module, String fileName, int entryPoint, int isExe, bool isManifestFile);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void AddResource(
@@ -282,17 +261,14 @@ namespace System.Reflection.Emit
byte[] resBytes, int resByteCount, int tkFile, int attribute,
int portableExecutableKind, int imageFileMachine);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void SetModuleName(RuntimeModule module, String strModuleName);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal extern static void SetFieldRVAContent(RuntimeModule module, int fdToken, byte[] data, int length);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void DefineNativeResourceFile(RuntimeModule module,
@@ -300,7 +276,6 @@ namespace System.Reflection.Emit
int portableExecutableKind,
int ImageFileMachine);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void DefineNativeResourceBytes(RuntimeModule module,
@@ -308,7 +283,6 @@ namespace System.Reflection.Emit
int portableExecutableKind,
int imageFileMachine);
- [System.Security.SecurityCritical] // auto-generated
internal void DefineNativeResource(PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
{
string strResourceFileName = m_moduleData.m_strResourceFileName;
@@ -351,105 +325,7 @@ namespace System.Reflection.Emit
return null;
}
-
-#if !FEATURE_CORECLR
- internal void SetEntryPoint(MethodToken entryPoint)
- {
- // Sets the entry point of the module to be a given method. If no entry point
- // is specified, calling EmitPEFile will generate a dll.
- // AssemblyBuilder.SetEntryPoint has already demanded required permission
- m_EntryPoint = entryPoint;
- }
-#endif //!FEATURE_CORECLR
-
-
-#if !FEATURE_CORECLR
- // This is a helper called by AssemblyBuilder save to presave information for the persistable modules.
- // no need to lock here because we have already taken the lock in AssemblyBuilder.Save
- [System.Security.SecurityCritical] // auto-generated
- internal void PreSave(String fileName,
- PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
- {
- if (m_moduleData.m_isSaved == true)
- {
- // can only save once
- throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture,
- Environment.GetResourceString("InvalidOperation_ModuleHasBeenSaved"),
- m_moduleData.m_strModuleName));
- }
-
- if (m_moduleData.m_fGlobalBeenCreated == false && m_moduleData.m_fHasGlobal == true)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_GlobalFunctionNotBaked"));
- TypeBuilder typeBuilder;
- foreach (Type item in m_TypeBuilderDict.Values)
- {
- if (item is TypeBuilder)
- {
- typeBuilder = (TypeBuilder)item;
- }
- else
- {
- EnumBuilder enumBuilder = (EnumBuilder)item;
- typeBuilder = enumBuilder.m_typeBuilder;
- }
-
- if (!typeBuilder.IsCreated())
- {
- // cannot save to PE file without creating all of the types first
- throw new NotSupportedException(String.Format(CultureInfo.InvariantCulture,
- Environment.GetResourceString("NotSupported_NotAllTypesAreBaked"),
- typeBuilder.FullName));
- }
- }
-
- PreSavePEFile(GetNativeHandle(), (int)portableExecutableKind, (int)imageFileMachine);
- }
-
- // no need to lock here because we have already taken the lock in AssemblyBuilder.Save
- [System.Security.SecurityCritical] // auto-generated
- internal void Save(String fileName, bool isAssemblyFile, PortableExecutableKinds portableExecutableKind,
- ImageFileMachine imageFileMachine)
- {
- // This is a helper called by AssemblyBuilder save to save information for the persistable modules.
- if (m_moduleData.m_embeddedRes != null)
- {
- // There are embedded resources for this module
- ResWriterData resWriter;
-
- // Add each resource content into the to be saved PE file
- for (resWriter = m_moduleData.m_embeddedRes; resWriter != null; resWriter = resWriter.m_nextResWriter)
- {
- if (resWriter.m_resWriter != null)
- resWriter.m_resWriter.Generate();
-
- byte[] resBytes = new byte[resWriter.m_memoryStream.Length];
- resWriter.m_memoryStream.Flush();
- resWriter.m_memoryStream.Position = 0;
- resWriter.m_memoryStream.Read(resBytes, 0, resBytes.Length);
-
- AddResource(GetNativeHandle(),
- resWriter.m_strName,
- resBytes,
- resBytes.Length,
- m_moduleData.FileToken,
- (int)resWriter.m_attribute,
- (int)portableExecutableKind,
- (int)imageFileMachine);
- }
- }
-
- DefineNativeResource(portableExecutableKind, imageFileMachine);
-
- PEFileKinds pekind = isAssemblyFile ? ContainingAssemblyBuilder.m_assemblyData.m_peFileKind : PEFileKinds.Dll;
-
- SavePEFile(GetNativeHandle(), fileName, m_EntryPoint.Token, (int)pekind, isAssemblyFile);
-
- m_moduleData.m_isSaved = true;
- }
-#endif // !FEATURE_CORECLR
-
- [System.Security.SecurityCritical] // auto-generated
private int GetTypeRefNested(Type type, Module refedModule, String strRefedModuleFileName)
{
// This function will generate correct TypeRef token for top level type and nested type.
@@ -464,8 +340,8 @@ namespace System.Reflection.Emit
typeName = UnmangleTypeName(typeName);
}
- Contract.Assert(!type.IsByRef, "Must not be ByRef.");
- Contract.Assert(!type.IsGenericType || type.IsGenericTypeDefinition, "Must not have generic arguments.");
+ 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)
@@ -481,13 +357,12 @@ namespace System.Reflection.Emit
return GetTypeRef(GetNativeHandle(), typeName, GetRuntimeModuleFromModule(refedModule).GetNativeHandle(), strRefedModuleFileName, tkResolution);
}
- [System.Security.SecurityCritical] // auto-generated
internal MethodToken InternalGetConstructorToken(ConstructorInfo con, bool usingRef)
{
// Helper to get constructor token. If usingRef is true, we will never use the def token
if (con == null)
- throw new ArgumentNullException("con");
+ throw new ArgumentNullException(nameof(con));
Contract.EndContractBlock();
int tr;
@@ -556,7 +431,6 @@ namespace System.Reflection.Emit
return new MethodToken( mr );
}
- [System.Security.SecurityCritical] // auto-generated
internal void Init(String strModuleName, String strFileName, int tkFile)
{
m_moduleData = new ModuleBuilderData(this, strModuleName, strFileName, tkFile);
@@ -565,7 +439,6 @@ namespace System.Reflection.Emit
// This is a method for changing module and file name of the manifest module (created by default for
// each assembly).
- [System.Security.SecurityCritical] // auto-generated
internal void ModifyModuleName(string name)
{
// Reset the names in the managed ModuleBuilderData
@@ -589,7 +462,7 @@ namespace System.Reflection.Emit
}
#endregion
-
+
#region Module Overrides
// m_internalModuleBuilder is null iff this is a "internal" ModuleBuilder
@@ -622,7 +495,6 @@ namespace System.Reflection.Emit
return m as RuntimeModule;
}
- [System.Security.SecurityCritical] // auto-generated
private int GetMemberRefToken(MethodBase method, IEnumerable<Type> optionalParameterTypes)
{
Type[] parameterTypes;
@@ -671,11 +543,11 @@ namespace System.Reflection.Emit
}
else
{
- Contract.Assert(method is RuntimeMethodInfo || method is RuntimeConstructorInfo);
+ Debug.Assert(method is RuntimeMethodInfo || method is RuntimeConstructorInfo);
if (method.IsGenericMethod)
{
- Contract.Assert(masmi != null);
+ Debug.Assert(masmi != null);
methDef = masmi.GetGenericMethodDefinition();
methDef = methDef.Module.ResolveMethod(
@@ -728,7 +600,6 @@ namespace System.Reflection.Emit
return GetMemberRefFromSignature(tkParent, method.Name, sigBytes, sigLength);
}
- [System.Security.SecurityCritical] // auto-generated
internal SignatureHelper GetMemberRefSignature(CallingConventions call, Type returnType,
Type[] parameterTypes, IEnumerable<Type> optionalParameterTypes, int cGenericParameters)
{
@@ -949,11 +820,6 @@ namespace System.Reflection.Emit
public override String FullyQualifiedName
{
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
get
{
String fullyQualifiedName = m_moduleData.m_strFileName;
@@ -962,7 +828,7 @@ namespace System.Reflection.Emit
if (ContainingAssemblyBuilder.m_assemblyData.m_strDir != null)
{
fullyQualifiedName = Path.Combine(ContainingAssemblyBuilder.m_assemblyData.m_strDir, fullyQualifiedName);
- fullyQualifiedName = Path.UnsafeGetFullPath(fullyQualifiedName);
+ fullyQualifiedName = Path.GetFullPath(fullyQualifiedName);
}
if (ContainingAssemblyBuilder.m_assemblyData.m_strDir != null && fullyQualifiedName != null)
@@ -1085,18 +951,11 @@ namespace System.Reflection.Emit
}
}
-#if FEATURE_X509 && FEATURE_CAS_POLICY
- public override System.Security.Cryptography.X509Certificates.X509Certificate GetSignerCertificate()
- {
- return InternalModule.GetSignerCertificate();
- }
-#endif // FEATURE_X509 && FEATURE_CAS_POLICY
#endregion
#region Public Members
#region Define Type
- [System.Security.SecuritySafeCritical] // auto-generated
public TypeBuilder DefineType(String name)
{
Contract.Ensures(Contract.Result<TypeBuilder>() != null);
@@ -1107,7 +966,6 @@ namespace System.Reflection.Emit
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public TypeBuilder DefineType(String name, TypeAttributes attr)
{
Contract.Ensures(Contract.Result<TypeBuilder>() != null);
@@ -1118,7 +976,6 @@ namespace System.Reflection.Emit
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public TypeBuilder DefineType(String name, TypeAttributes attr, Type parent)
{
Contract.Ensures(Contract.Result<TypeBuilder>() != null);
@@ -1132,11 +989,6 @@ namespace System.Reflection.Emit
}
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
public TypeBuilder DefineType(String name, TypeAttributes attr, Type parent, int typesize)
{
Contract.Ensures(Contract.Result<TypeBuilder>() != null);
@@ -1147,11 +999,6 @@ namespace System.Reflection.Emit
}
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
public TypeBuilder DefineType(String name, TypeAttributes attr, Type parent, PackingSize packingSize, int typesize)
{
Contract.Ensures(Contract.Result<TypeBuilder>() != null);
@@ -1162,7 +1009,6 @@ namespace System.Reflection.Emit
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(true)]
public TypeBuilder DefineType(String name, TypeAttributes attr, Type parent, Type[] interfaces)
{
@@ -1174,7 +1020,6 @@ namespace System.Reflection.Emit
}
}
- [System.Security.SecurityCritical] // auto-generated
private TypeBuilder DefineTypeNoLock(String name, TypeAttributes attr, Type parent, Type[] interfaces, PackingSize packingSize, int typesize)
{
Contract.Ensures(Contract.Result<TypeBuilder>() != null);
@@ -1182,11 +1027,6 @@ namespace System.Reflection.Emit
return new TypeBuilder(name, attr, parent, interfaces, this, packingSize, typesize, null); ;
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
public TypeBuilder DefineType(String name, TypeAttributes attr, Type parent, PackingSize packsize)
{
Contract.Ensures(Contract.Result<TypeBuilder>() != null);
@@ -1197,7 +1037,6 @@ namespace System.Reflection.Emit
}
}
- [System.Security.SecurityCritical] // auto-generated
private TypeBuilder DefineTypeNoLock(String name, TypeAttributes attr, Type parent, PackingSize packsize)
{
Contract.Ensures(Contract.Result<TypeBuilder>() != null);
@@ -1211,7 +1050,6 @@ namespace System.Reflection.Emit
// This API can only be used to construct a top-level (not nested) enum type.
// Nested enum types can be defined manually using ModuleBuilder.DefineType.
- [System.Security.SecuritySafeCritical] // auto-generated
public EnumBuilder DefineEnum(String name, TypeAttributes visibility, Type underlyingType)
{
Contract.Ensures(Contract.Result<EnumBuilder>() != null);
@@ -1222,17 +1060,16 @@ namespace System.Reflection.Emit
EnumBuilder enumBuilder = DefineEnumNoLock(name, visibility, underlyingType);
// This enum is not generic, nested, and cannot have any element type.
- Contract.Assert(name == enumBuilder.FullName);
+ Debug.Assert(name == enumBuilder.FullName);
// Replace the TypeBuilder object in m_TypeBuilderDict with this EnumBuilder object.
- Contract.Assert(enumBuilder.m_typeBuilder == m_TypeBuilderDict[name]);
+ Debug.Assert(enumBuilder.m_typeBuilder == m_TypeBuilderDict[name]);
m_TypeBuilderDict[name] = enumBuilder;
return enumBuilder;
}
}
- [System.Security.SecurityCritical] // auto-generated
private EnumBuilder DefineEnumNoLock(String name, TypeAttributes visibility, Type underlyingType)
{
Contract.Ensures(Contract.Result<EnumBuilder>() != null);
@@ -1243,178 +1080,7 @@ namespace System.Reflection.Emit
#endregion
#region Define Resource
-#if !FEATURE_CORECLR
- public IResourceWriter DefineResource(String name, String description)
- {
- // Define embedded managed resource to be stored in this module
- Contract.Ensures(Contract.Result<IResourceWriter>() != null);
-
- return DefineResource(name, description, ResourceAttributes.Public);
- }
-
- public IResourceWriter DefineResource(String name, String description, ResourceAttributes attribute)
- {
- // Define embedded managed resource to be stored in this module
- Contract.Ensures(Contract.Result<IResourceWriter>() != null);
-
- lock(SyncRoot)
- {
- return DefineResourceNoLock(name, description, attribute);
- }
- }
-
- private IResourceWriter DefineResourceNoLock(String name, String description, ResourceAttributes attribute)
- {
- // Define embedded managed resource to be stored in this module
-
- if (IsTransient())
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadResourceContainer"));
-
- if (name == null)
- throw new ArgumentNullException("name");
- if (name.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
- Contract.Ensures(Contract.Result<IResourceWriter>() != null);
- Contract.EndContractBlock();
-
- if (m_assemblyBuilder.IsPersistable())
- {
- m_assemblyBuilder.m_assemblyData.CheckResNameConflict(name);
-
- MemoryStream stream = new MemoryStream();
- ResourceWriter resWriter = new ResourceWriter(stream);
- ResWriterData resWriterData = new ResWriterData( resWriter, stream, name, String.Empty, String.Empty, attribute);
-
- // chain it to the embedded resource list
- resWriterData.m_nextResWriter = m_moduleData.m_embeddedRes;
- m_moduleData.m_embeddedRes = resWriterData;
- return resWriter;
- }
- else
- {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadResourceContainer"));
- }
- }
-#endif // !FEATURE_CORECLR
-
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
- public void DefineManifestResource(String name, Stream stream, ResourceAttributes attribute)
- {
- if (name == null)
- throw new ArgumentNullException("name");
-
- if (stream == null)
- throw new ArgumentNullException("stream");
- Contract.EndContractBlock();
-
- // Define embedded managed resource to be stored in this module
- lock(SyncRoot)
- {
- DefineManifestResourceNoLock(name, stream, attribute);
- }
- }
-
- private void DefineManifestResourceNoLock(String name, Stream stream, ResourceAttributes attribute)
- {
- // Define embedded managed resource to be stored in this module
- if (IsTransient())
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadResourceContainer"));
- Contract.EndContractBlock();
-
-#if !FEATURE_CORECLR
- if (name == null)
- throw new ArgumentNullException("name");
- if (name.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
-
- if (m_assemblyBuilder.IsPersistable())
- {
- m_assemblyBuilder.m_assemblyData.CheckResNameConflict(name);
-
- ResWriterData resWriterData = new ResWriterData( null, stream, name, String.Empty, String.Empty, attribute);
-
- // chain it to the embedded resource list
- resWriterData.m_nextResWriter = m_moduleData.m_embeddedRes;
- m_moduleData.m_embeddedRes = resWriterData;
- }
- else
- {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadResourceContainer"));
- }
-#endif // !FEATURE_CORECLR
- }
-
-
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
- public void DefineUnmanagedResource(Byte[] resource)
- {
- lock(SyncRoot)
- {
- DefineUnmanagedResourceInternalNoLock(resource);
- }
- }
-
- internal void DefineUnmanagedResourceInternalNoLock(Byte[] resource)
- {
- if (resource == null)
- throw new ArgumentNullException("resource");
- Contract.EndContractBlock();
-
- if (m_moduleData.m_strResourceFileName != null || m_moduleData.m_resourceBytes != null)
- throw new ArgumentException(Environment.GetResourceString("Argument_NativeResourceAlreadyDefined"));
-
- m_moduleData.m_resourceBytes = new byte[resource.Length];
- Buffer.BlockCopy(resource, 0, m_moduleData.m_resourceBytes, 0, resource.Length);
- }
-
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
- public void DefineUnmanagedResource(String resourceFileName)
- {
- lock(SyncRoot)
- {
- DefineUnmanagedResourceFileInternalNoLock(resourceFileName);
- }
- }
-
- [System.Security.SecurityCritical] // auto-generated
- internal void DefineUnmanagedResourceFileInternalNoLock(String resourceFileName)
- {
- if (resourceFileName == null)
- throw new ArgumentNullException("resourceFileName");
- Contract.EndContractBlock();
-
- if (m_moduleData.m_resourceBytes != null || m_moduleData.m_strResourceFileName != null)
- throw new ArgumentException(Environment.GetResourceString("Argument_NativeResourceAlreadyDefined"));
-
- // Check caller has the right to read the file.
- string strFullFileName;
- strFullFileName = Path.UnsafeGetFullPath(resourceFileName);
- new FileIOPermission(FileIOPermissionAccess.Read, strFullFileName).Demand();
-
- new EnvironmentPermission(PermissionState.Unrestricted).Assert();
- try
- {
- if (File.UnsafeExists(resourceFileName) == false)
- throw new FileNotFoundException(Environment.GetResourceString(
- "IO.FileNotFound_FileName",
- resourceFileName), resourceFileName);
- }
- finally
- {
- CodeAccessPermission.RevertAssert();
- }
-
- m_moduleData.m_strResourceFileName = strFullFileName;
- }
#endregion
#region Define Global Method
@@ -1453,10 +1119,10 @@ namespace System.Reflection.Emit
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_GlobalsHaveBeenCreated"));
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (name.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name));
if ((attributes & MethodAttributes.Static) == 0)
throw new ArgumentException(Environment.GetResourceString("Argument_GlobalFunctionHasToBeStatic"));
@@ -1475,9 +1141,6 @@ namespace System.Reflection.Emit
parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
public MethodBuilder DefinePInvokeMethod(String name, String dllName, MethodAttributes attributes,
CallingConventions callingConvention, Type returnType, Type[] parameterTypes,
CallingConvention nativeCallConv, CharSet nativeCharSet)
@@ -1487,9 +1150,6 @@ namespace System.Reflection.Emit
return DefinePInvokeMethod(name, dllName, name, attributes, callingConvention, returnType, parameterTypes, nativeCallConv, nativeCharSet);
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
public MethodBuilder DefinePInvokeMethod(String name, String dllName, String entryName, MethodAttributes attributes,
CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv,
CharSet nativeCharSet)
@@ -1503,9 +1163,6 @@ namespace System.Reflection.Emit
}
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
private MethodBuilder DefinePInvokeMethodNoLock(String name, String dllName, String entryName, MethodAttributes attributes,
CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv,
CharSet nativeCharSet)
@@ -1548,9 +1205,6 @@ namespace System.Reflection.Emit
#region Define Data
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
public FieldBuilder DefineInitializedData(String name, byte[] data, FieldAttributes attributes)
{
// This method will define an initialized Data in .sdata.
@@ -1564,9 +1218,6 @@ namespace System.Reflection.Emit
}
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
private FieldBuilder DefineInitializedDataNoLock(String name, byte[] data, FieldAttributes attributes)
{
// This method will define an initialized Data in .sdata.
@@ -1583,9 +1234,6 @@ namespace System.Reflection.Emit
return m_moduleData.m_globalTypeBuilder.DefineInitializedData(name, data, attributes);
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
public FieldBuilder DefineUninitializedData(String name, int size, FieldAttributes attributes)
{
Contract.Ensures(Contract.Result<FieldBuilder>() != null);
@@ -1596,9 +1244,6 @@ namespace System.Reflection.Emit
}
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
private FieldBuilder DefineUninitializedDataNoLock(String name, int size, FieldAttributes attributes)
{
// This method will define an uninitialized Data in .sdata.
@@ -1623,13 +1268,11 @@ namespace System.Reflection.Emit
// 1. GetTypeToken
// 2. ldtoken (see ILGenerator)
// For all other occasions we should return the generic type instantiated on its formal parameters.
- [System.Security.SecurityCritical] // auto-generated
internal TypeToken GetTypeTokenInternal(Type type)
{
return GetTypeTokenInternal(type, false);
}
- [System.Security.SecurityCritical] // auto-generated
private TypeToken GetTypeTokenInternal(Type type, bool getGenericDefinition)
{
lock(SyncRoot)
@@ -1638,17 +1281,15 @@ namespace System.Reflection.Emit
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public TypeToken GetTypeToken(Type type)
{
return GetTypeTokenInternal(type, true);
}
- [System.Security.SecurityCritical] // auto-generated
private TypeToken GetTypeTokenWorkerNoLock(Type type, bool getGenericDefinition)
{
if (type == null)
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
Contract.EndContractBlock();
CheckContext(type);
@@ -1710,19 +1351,6 @@ namespace System.Reflection.Emit
//
ModuleBuilder refedModuleBuilder = refedModule as ModuleBuilder;
-#if !FEATURE_CORECLR
- Contract.Assert(refedModuleBuilder != null || refedModule is RuntimeModule);
- bool isRefedModuleTransient = refedModuleBuilder != null ?
- refedModuleBuilder.IsTransient() :
- ((RuntimeModule)refedModule).IsTransientInternal();
-
- // We cannot have a non-transient module referencing to a transient module.
- if (IsTransient() == false && isRefedModuleTransient)
- {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadTransientModuleReference"));
- }
-#endif // !FEATURE_CORECLR
-
String strRefedModuleFileName = String.Empty;
if (refedModule.Assembly.Equals(this.Assembly))
{
@@ -1753,7 +1381,6 @@ namespace System.Reflection.Emit
return GetTypeToken(InternalModule.GetType(name, false, true));
}
- [System.Security.SecuritySafeCritical] // auto-generated
public MethodToken GetMethodToken(MethodInfo method)
{
lock(SyncRoot)
@@ -1762,7 +1389,6 @@ namespace System.Reflection.Emit
}
}
- [System.Security.SecurityCritical] // auto-generated
internal MethodToken GetMethodTokenInternal(MethodInfo method)
{
lock(SyncRoot)
@@ -1775,13 +1401,12 @@ namespace System.Reflection.Emit
// 1. GetMethodToken
// 2. ldtoken (see ILGenerator)
// For all other occasions we should return the method on the generic type instantiated on the formal parameters.
- [System.Security.SecurityCritical] // auto-generated
private MethodToken GetMethodTokenNoLock(MethodInfo method, bool getGenericTypeDefinition)
{
// Return a MemberRef token if MethodInfo is not defined in this module. Or
// return the MethodDef token.
if (method == null)
- throw new ArgumentNullException("method");
+ throw new ArgumentNullException(nameof(method));
Contract.EndContractBlock();
int tr;
@@ -1885,12 +1510,11 @@ namespace System.Reflection.Emit
return new MethodToken(mr);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public MethodToken GetConstructorToken(ConstructorInfo constructor, IEnumerable<Type> optionalParameterTypes)
{
if (constructor == null)
{
- throw new ArgumentNullException("constructor");
+ throw new ArgumentNullException(nameof(constructor));
}
lock (SyncRoot)
@@ -1900,12 +1524,11 @@ namespace System.Reflection.Emit
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public MethodToken GetMethodToken(MethodInfo method, IEnumerable<Type> optionalParameterTypes)
{
if (method == null)
{
- throw new ArgumentNullException("method");
+ throw new ArgumentNullException(nameof(method));
}
// useMethodDef flag only affects the result if we pass in a generic method definition.
@@ -1922,7 +1545,6 @@ namespace System.Reflection.Emit
}
}
- [System.Security.SecurityCritical] // auto-generated
internal int GetMethodTokenInternal(MethodBase method, IEnumerable<Type> optionalParameterTypes, bool useMethodDef)
{
int tk = 0;
@@ -1931,7 +1553,7 @@ namespace System.Reflection.Emit
if (method.IsGenericMethod)
{
// Constructors cannot be generic.
- Contract.Assert(methodInfo != null);
+ Debug.Assert(methodInfo != null);
// Given M<Bar> unbind to M<S>
MethodInfo methodInfoUnbound = methodInfo;
@@ -1989,7 +1611,6 @@ namespace System.Reflection.Emit
return tk;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public MethodToken GetArrayMethodToken(Type arrayClass, String methodName, CallingConventions callingConvention,
Type returnType, Type[] parameterTypes)
{
@@ -1999,18 +1620,17 @@ namespace System.Reflection.Emit
}
}
- [System.Security.SecurityCritical] // auto-generated
private MethodToken GetArrayMethodTokenNoLock(Type arrayClass, String methodName, CallingConventions callingConvention,
Type returnType, Type[] parameterTypes)
{
if (arrayClass == null)
- throw new ArgumentNullException("arrayClass");
+ throw new ArgumentNullException(nameof(arrayClass));
if (methodName == null)
- throw new ArgumentNullException("methodName");
+ throw new ArgumentNullException(nameof(methodName));
if (methodName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "methodName");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(methodName));
if (arrayClass.IsArray == false)
throw new ArgumentException(Environment.GetResourceString("Argument_HasToBeArrayClass"));
@@ -2035,7 +1655,6 @@ namespace System.Reflection.Emit
typeSpec.Token, methodName, sigBytes, length));
}
- [System.Security.SecuritySafeCritical] // auto-generated
public MethodInfo GetArrayMethod(Type arrayClass, String methodName, CallingConventions callingConvention,
Type returnType, Type[] parameterTypes)
{
@@ -2052,7 +1671,6 @@ namespace System.Reflection.Emit
return new SymbolMethod(this, token, arrayClass, methodName, callingConvention, returnType, parameterTypes);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(true)]
public MethodToken GetConstructorToken(ConstructorInfo con)
{
@@ -2060,7 +1678,6 @@ namespace System.Reflection.Emit
return InternalGetConstructorToken(con, false);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public FieldToken GetFieldToken(FieldInfo field)
{
lock(SyncRoot)
@@ -2069,7 +1686,6 @@ namespace System.Reflection.Emit
}
}
- [System.Security.SecurityCritical] // auto-generated
private FieldToken GetFieldTokenNoLock(FieldInfo field)
{
if (field == null) {
@@ -2158,12 +1774,11 @@ namespace System.Reflection.Emit
return new FieldToken(mr, field.GetType());
}
- [System.Security.SecuritySafeCritical] // auto-generated
public StringToken GetStringConstant(String str)
{
if (str == null)
{
- throw new ArgumentNullException("str");
+ throw new ArgumentNullException(nameof(str));
}
Contract.EndContractBlock();
@@ -2172,7 +1787,6 @@ namespace System.Reflection.Emit
return new StringToken(GetStringConstant(GetNativeHandle(), str, str.Length));
}
- [System.Security.SecuritySafeCritical] // auto-generated
public SignatureToken GetSignatureToken(SignatureHelper sigHelper)
{
// Define signature token given a signature helper. This will define a metadata
@@ -2180,7 +1794,7 @@ namespace System.Reflection.Emit
if (sigHelper == null)
{
- throw new ArgumentNullException("sigHelper");
+ throw new ArgumentNullException(nameof(sigHelper));
}
Contract.EndContractBlock();
@@ -2191,11 +1805,10 @@ namespace System.Reflection.Emit
sigBytes = sigHelper.InternalGetSignature(out sigLength);
return new SignatureToken(TypeBuilder.GetTokenFromSig(GetNativeHandle(), sigBytes, sigLength), this);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public SignatureToken GetSignatureToken(byte[] sigBytes, int sigLength)
{
if (sigBytes == null)
- throw new ArgumentNullException("sigBytes");
+ throw new ArgumentNullException(nameof(sigBytes));
Contract.EndContractBlock();
byte[] localSigBytes = new byte[sigBytes.Length];
@@ -2208,18 +1821,13 @@ namespace System.Reflection.Emit
#region Other
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
[System.Runtime.InteropServices.ComVisible(true)]
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
{
if (con == null)
- throw new ArgumentNullException("con");
+ throw new ArgumentNullException(nameof(con));
if (binaryAttribute == null)
- throw new ArgumentNullException("binaryAttribute");
+ throw new ArgumentNullException(nameof(binaryAttribute));
Contract.EndContractBlock();
TypeBuilder.DefineCustomAttribute(
@@ -2230,12 +1838,11 @@ namespace System.Reflection.Emit
false, false);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
{
if (customBuilder == null)
{
- throw new ArgumentNullException("customBuilder");
+ throw new ArgumentNullException(nameof(customBuilder));
}
Contract.EndContractBlock();
@@ -2276,14 +1883,11 @@ namespace System.Reflection.Emit
return m_iSymWriter;
}
-#if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical]
-#endif
public ISymbolDocumentWriter DefineDocument(String url, Guid language, Guid languageVendor, Guid documentType)
{
// url cannot be null but can be an empty string
if (url == null)
- throw new ArgumentNullException("url");
+ throw new ArgumentNullException(nameof(url));
Contract.EndContractBlock();
lock(SyncRoot)
@@ -2292,9 +1896,6 @@ namespace System.Reflection.Emit
}
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
private ISymbolDocumentWriter DefineDocumentNoLock(String url, Guid language, Guid languageVendor, Guid documentType)
{
if (m_iSymWriter == null)
@@ -2306,11 +1907,6 @@ namespace System.Reflection.Emit
return m_iSymWriter.DefineDocument(url, language, languageVendor, documentType);
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
public void SetUserEntryPoint(MethodInfo entryPoint)
{
lock(SyncRoot)
@@ -2319,7 +1915,6 @@ namespace System.Reflection.Emit
}
}
- [System.Security.SecurityCritical] // auto-generated
private void SetUserEntryPointNoLock(MethodInfo entryPoint)
{
// Set the user entry point. Compiler may generate startup stub before calling user main.
@@ -2328,7 +1923,7 @@ namespace System.Reflection.Emit
if (entryPoint == null)
{
- throw new ArgumentNullException("entryPoint");
+ throw new ArgumentNullException(nameof(entryPoint));
}
Contract.EndContractBlock();
@@ -2396,27 +1991,5 @@ namespace System.Reflection.Emit
#endregion
#endregion
-
-#if !FEATURE_CORECLR
- void _ModuleBuilder.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _ModuleBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _ModuleBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- void _ModuleBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
-#endif
}
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/ModuleBuilderData.cs b/src/mscorlib/src/System/Reflection/Emit/ModuleBuilderData.cs
index 2bec04abe5..96e60d9a4e 100644
--- a/src/mscorlib/src/System/Reflection/Emit/ModuleBuilderData.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/ModuleBuilderData.cs
@@ -9,6 +9,7 @@
namespace System.Reflection.Emit
{
using System;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Globalization;
using System.IO;
@@ -21,7 +22,6 @@ namespace System.Reflection.Emit
[Serializable]
internal class ModuleBuilderData
{
- [System.Security.SecurityCritical] // auto-generated
internal ModuleBuilderData(ModuleBuilder module, String strModuleName, String strFileName, int tkFile)
{
m_globalTypeBuilder = new TypeBuilder(module);
@@ -32,7 +32,6 @@ namespace System.Reflection.Emit
}
// Initialize module and file names.
- [System.Security.SecurityCritical] // auto-generated
private void InitNames(String strModuleName, String strFileName)
{
m_strModuleName = strModuleName;
@@ -55,10 +54,9 @@ namespace System.Reflection.Emit
// This is a method for changing module and file name of the manifest module (created by default for
// each assembly).
- [System.Security.SecurityCritical] // auto-generated
internal virtual void ModifyModuleName(String strModuleName)
{
- Contract.Assert(m_strModuleName == AssemblyBuilder.MANIFEST_MODULE_NAME, "Changing names for non-manifest module");
+ Debug.Assert(m_strModuleName == AssemblyBuilder.MANIFEST_MODULE_NAME, "Changing names for non-manifest module");
InitNames(strModuleName, null /*strFileName*/);
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/Opcode.cs b/src/mscorlib/src/System/Reflection/Emit/Opcode.cs
index cae4f0564e..d7bfacd568 100644
--- a/src/mscorlib/src/System/Reflection/Emit/Opcode.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/Opcode.cs
@@ -36,7 +36,6 @@ public struct OpCode
internal const int StackChangeShift = 28; // XXXX0000000000000000000000000000
-#if FEATURE_CORECLR
private OpCodeValues m_value;
private int m_flags;
@@ -80,7 +79,6 @@ public struct OpCode
}
}
-
public StackBehaviour StackBehaviourPop
{
get
@@ -112,121 +110,6 @@ public struct OpCode
return (short)m_value;
}
}
-#else // FEATURE_CORECLR
- //
- // The exact layout is part of the legacy COM mscorlib surface, so it is
- // pretty much set in stone for desktop CLR. Ideally, we would use the packed
- // bit field like for CoreCLR, but that would be a breaking change.
- //
-
-// disable csharp compiler warning #0414: field assigned unused value
-#pragma warning disable 0414
- private String m_stringname; // not used - computed lazily
-#pragma warning restore 0414
- private StackBehaviour m_pop;
- private StackBehaviour m_push;
- private OperandType m_operand;
- private OpCodeType m_type;
- private int m_size;
- private byte m_s1;
- private byte m_s2;
- private FlowControl m_ctrl;
-
- // Specifies whether the current instructions causes the control flow to
- // change unconditionally.
- private bool m_endsUncondJmpBlk;
-
-
- // Specifies the stack change that the current instruction causes not
- // taking into account the operand dependant stack changes.
- private int m_stackChange;
-
-
- internal OpCode(OpCodeValues value, int flags)
- {
- m_stringname = null; // computed lazily
- m_pop = (StackBehaviour)((flags >> StackBehaviourPopShift) & StackBehaviourMask);
- m_push = (StackBehaviour)((flags >> StackBehaviourPushShift) & StackBehaviourMask);
- m_operand = (OperandType)(flags & OperandTypeMask);
- m_type = (OpCodeType)((flags >> OpCodeTypeShift) & OpCodeTypeMask);
- m_size = (flags >> SizeShift) & SizeMask;
- m_s1 = (byte)((int)value >> 8);
- m_s2 = (byte)(int)value;
- m_ctrl = (FlowControl)((flags >> FlowControlShift) & FlowControlMask);
- m_endsUncondJmpBlk = (flags & EndsUncondJmpBlkFlag) != 0;
- m_stackChange = (flags >> StackChangeShift);
- }
-
- internal bool EndsUncondJmpBlk()
- {
- return m_endsUncondJmpBlk;
- }
-
- internal int StackChange()
- {
- return m_stackChange;
- }
-
- public OperandType OperandType
- {
- get
- {
- return (m_operand);
- }
- }
-
- public FlowControl FlowControl
- {
- get
- {
- return (m_ctrl);
- }
- }
-
- public OpCodeType OpCodeType
- {
- get
- {
- return (m_type);
- }
- }
-
-
- public StackBehaviour StackBehaviourPop
- {
- get
- {
- return (m_pop);
- }
- }
-
- public StackBehaviour StackBehaviourPush
- {
- get
- {
- return (m_push);
- }
- }
-
- public int Size
- {
- get
- {
- return (m_size);
- }
- }
-
- public short Value
- {
- get
- {
- if (m_size == 2)
- return (short)(m_s1 << 8 | m_s2);
- return (short)m_s2;
- }
- }
-#endif // FEATURE_CORECLR
-
private static volatile string[] g_nameCache;
@@ -308,5 +191,4 @@ public struct OpCode
return Name;
}
}
-
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/OpcodeType.cs b/src/mscorlib/src/System/Reflection/Emit/OpcodeType.cs
index 5ef5f80b15..3636cb7377 100644
--- a/src/mscorlib/src/System/Reflection/Emit/OpcodeType.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/OpcodeType.cs
@@ -21,11 +21,8 @@ using System;
public enum OpCodeType
{
-#if !FEATURE_CORECLR
- /// <internalonly/>
[Obsolete("This API has been deprecated. http://go.microsoft.com/fwlink/?linkid=14202")]
Annotation = 0,
-#endif
Macro = 1,
Nternal = 2,
Objmodel = 3,
diff --git a/src/mscorlib/src/System/Reflection/Emit/OperandType.cs b/src/mscorlib/src/System/Reflection/Emit/OperandType.cs
index fdde19a73e..808844a017 100644
--- a/src/mscorlib/src/System/Reflection/Emit/OperandType.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/OperandType.cs
@@ -27,11 +27,8 @@ public enum OperandType
InlineI8 = 3,
InlineMethod = 4,
InlineNone = 5,
-#if !FEATURE_CORECLR
- /// <internalonly/>
[Obsolete("This API has been deprecated. http://go.microsoft.com/fwlink/?linkid=14202")]
InlinePhi = 6,
-#endif
InlineR = 7,
InlineSig = 9,
InlineString = 10,
diff --git a/src/mscorlib/src/System/Reflection/Emit/ParameterBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/ParameterBuilder.cs
index 693e2d3660..7909562baa 100644
--- a/src/mscorlib/src/System/Reflection/Emit/ParameterBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/ParameterBuilder.cs
@@ -25,13 +25,12 @@ namespace System.Reflection.Emit {
public class ParameterBuilder : _ParameterBuilder
{
// set ParamMarshal
- [System.Security.SecuritySafeCritical] // auto-generated
[Obsolete("An alternate API is available: Emit the MarshalAs custom attribute instead. http://go.microsoft.com/fwlink/?linkid=14202")]
public virtual void SetMarshal(UnmanagedMarshal unmanagedMarshal)
{
if (unmanagedMarshal == null)
{
- throw new ArgumentNullException("unmanagedMarshal");
+ throw new ArgumentNullException(nameof(unmanagedMarshal));
}
Contract.EndContractBlock();
@@ -44,7 +43,6 @@ namespace System.Reflection.Emit {
}
// Set the default value of the parameter
- [System.Security.SecuritySafeCritical] // auto-generated
public virtual void SetConstant(Object defaultValue)
{
TypeBuilder.SetConstantValue(
@@ -56,14 +54,13 @@ namespace System.Reflection.Emit {
// Use this function if client decides to form the custom attribute blob themselves
- [System.Security.SecuritySafeCritical]
[System.Runtime.InteropServices.ComVisible(true)]
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
{
if (con == null)
- throw new ArgumentNullException("con");
+ throw new ArgumentNullException(nameof(con));
if (binaryAttribute == null)
- throw new ArgumentNullException("binaryAttribute");
+ throw new ArgumentNullException(nameof(binaryAttribute));
Contract.EndContractBlock();
TypeBuilder.DefineCustomAttribute(
@@ -75,12 +72,11 @@ namespace System.Reflection.Emit {
}
// Use this function if client wishes to build CustomAttribute using CustomAttributeBuilder
- [System.Security.SecuritySafeCritical] // auto-generated
public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
{
if (customBuilder == null)
{
- throw new ArgumentNullException("customBuilder");
+ throw new ArgumentNullException(nameof(customBuilder));
}
Contract.EndContractBlock();
customBuilder.CreateCustomAttribute((ModuleBuilder) (m_methodBuilder .GetModule()), m_pdToken.Token);
@@ -92,7 +88,6 @@ namespace System.Reflection.Emit {
private ParameterBuilder() {}
- [System.Security.SecurityCritical] // auto-generated
internal ParameterBuilder(
MethodBuilder methodBuilder,
int sequence,
@@ -117,28 +112,6 @@ namespace System.Reflection.Emit {
return m_pdToken;
}
-#if !FEATURE_CORECLR
- void _ParameterBuilder.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _ParameterBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _ParameterBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- void _ParameterBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
-#endif
-
internal int MetadataTokenInternal { get { return m_pdToken.Token; } }
public virtual String Name {
diff --git a/src/mscorlib/src/System/Reflection/Emit/PropertyBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/PropertyBuilder.cs
index 5ac69f205f..e7442b4e02 100644
--- a/src/mscorlib/src/System/Reflection/Emit/PropertyBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/PropertyBuilder.cs
@@ -25,7 +25,6 @@ namespace System.Reflection.Emit {
// A PropertyBuilder is always associated with a TypeBuilder. The TypeBuilder.DefineProperty
// method will return a new PropertyBuilder to a client.
//
- [HostProtection(MayLeakOnAbort = true)]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_PropertyBuilder))]
[System.Runtime.InteropServices.ComVisible(true)]
@@ -47,11 +46,11 @@ namespace System.Reflection.Emit {
TypeBuilder containingType) // the containing type
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (name.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name));
if (name[0] == '\0')
- throw new ArgumentException(Environment.GetResourceString("Argument_IllegalName"), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_IllegalName"), nameof(name));
Contract.EndContractBlock();
m_name = name;
@@ -67,7 +66,6 @@ namespace System.Reflection.Emit {
//************************************************
// Set the default value of the Property
//************************************************
- [System.Security.SecuritySafeCritical] // auto-generated
public void SetConstant(Object defaultValue)
{
m_containingType.ThrowIfCreated();
@@ -103,12 +101,11 @@ namespace System.Reflection.Emit {
}
}
- [System.Security.SecurityCritical] // auto-generated
private void SetMethodSemantics(MethodBuilder mdBuilder, MethodSemanticsAttributes semantics)
{
if (mdBuilder == null)
{
- throw new ArgumentNullException("mdBuilder");
+ throw new ArgumentNullException(nameof(mdBuilder));
}
m_containingType.ThrowIfCreated();
@@ -119,21 +116,18 @@ namespace System.Reflection.Emit {
mdBuilder.GetToken().Token);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void SetGetMethod(MethodBuilder mdBuilder)
{
SetMethodSemantics(mdBuilder, MethodSemanticsAttributes.Getter);
m_getMethod = mdBuilder;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void SetSetMethod(MethodBuilder mdBuilder)
{
SetMethodSemantics(mdBuilder, MethodSemanticsAttributes.Setter);
m_setMethod = mdBuilder;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void AddOtherMethod(MethodBuilder mdBuilder)
{
SetMethodSemantics(mdBuilder, MethodSemanticsAttributes.Other);
@@ -141,18 +135,13 @@ namespace System.Reflection.Emit {
// Use this function if client decides to form the custom attribute blob themselves
-#if FEATURE_CORECLR
-[System.Security.SecurityCritical] // auto-generated
-#else
-[System.Security.SecuritySafeCritical]
-#endif
[System.Runtime.InteropServices.ComVisible(true)]
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
{
if (con == null)
- throw new ArgumentNullException("con");
+ throw new ArgumentNullException(nameof(con));
if (binaryAttribute == null)
- throw new ArgumentNullException("binaryAttribute");
+ throw new ArgumentNullException(nameof(binaryAttribute));
m_containingType.ThrowIfCreated();
TypeBuilder.DefineCustomAttribute(
@@ -164,12 +153,11 @@ namespace System.Reflection.Emit {
}
// Use this function if client wishes to build CustomAttribute using CustomAttributeBuilder
- [System.Security.SecuritySafeCritical] // auto-generated
public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
{
if (customBuilder == null)
{
- throw new ArgumentNullException("customBuilder");
+ throw new ArgumentNullException(nameof(customBuilder));
}
m_containingType.ThrowIfCreated();
customBuilder.CreateCustomAttribute(m_moduleBuilder, m_prToken.Token);
@@ -256,28 +244,6 @@ namespace System.Reflection.Emit {
throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
}
-#if !FEATURE_CORECLR
- void _PropertyBuilder.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _PropertyBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _PropertyBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- void _PropertyBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
-#endif
-
public override String Name {
get { return m_name; }
}
@@ -302,5 +268,4 @@ namespace System.Reflection.Emit {
private MethodInfo m_setMethod;
private TypeBuilder m_containingType;
}
-
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/SignatureHelper.cs b/src/mscorlib/src/System/Reflection/Emit/SignatureHelper.cs
index 35e8cc7e31..c40035bc40 100644
--- a/src/mscorlib/src/System/Reflection/Emit/SignatureHelper.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/SignatureHelper.cs
@@ -8,6 +8,7 @@ namespace System.Reflection.Emit
{
using System.Text;
using System;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Reflection;
using System.Runtime.CompilerServices;
@@ -25,19 +26,16 @@ namespace System.Reflection.Emit
#endregion
#region Static Members
- [System.Security.SecuritySafeCritical] // auto-generated
public static SignatureHelper GetMethodSigHelper(Module mod, Type returnType, Type[] parameterTypes)
{
return GetMethodSigHelper(mod, CallingConventions.Standard, returnType, null, null, parameterTypes, null, null);
}
- [System.Security.SecurityCritical] // auto-generated
internal static SignatureHelper GetMethodSigHelper(Module mod, CallingConventions callingConvention, Type returnType, int cGenericParam)
{
return GetMethodSigHelper(mod, callingConvention, cGenericParam, returnType, null, null, null, null, null);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static SignatureHelper GetMethodSigHelper(Module mod, CallingConventions callingConvention, Type returnType)
{
return GetMethodSigHelper(mod, callingConvention, returnType, null, null, null, null, null);
@@ -52,7 +50,6 @@ namespace System.Reflection.Emit
return sigHelp;
}
- [System.Security.SecurityCritical] // auto-generated
internal static SignatureHelper GetMethodSigHelper(
Module scope, CallingConventions callingConvention,
Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers,
@@ -62,7 +59,6 @@ namespace System.Reflection.Emit
optionalReturnTypeCustomModifiers, parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
}
- [System.Security.SecurityCritical] // auto-generated
internal static SignatureHelper GetMethodSigHelper(
Module scope, CallingConventions callingConvention, int cGenericParam,
Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers,
@@ -96,7 +92,6 @@ namespace System.Reflection.Emit
return sigHelp;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static SignatureHelper GetMethodSigHelper(Module mod, CallingConvention unmanagedCallConv, Type returnType)
{
SignatureHelper sigHelp;
@@ -123,7 +118,7 @@ namespace System.Reflection.Emit
}
else
{
- throw new ArgumentException(Environment.GetResourceString("Argument_UnknownUnmanagedCallConv"), "unmanagedCallConv");
+ throw new ArgumentException(Environment.GetResourceString("Argument_UnknownUnmanagedCallConv"), nameof(unmanagedCallConv));
}
sigHelp = new SignatureHelper(mod, intCall, returnType, null, null);
@@ -168,7 +163,6 @@ namespace System.Reflection.Emit
return GetPropertySigHelper(mod, (CallingConventions)0, returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers,
parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static SignatureHelper GetPropertySigHelper(Module mod, CallingConventions callingConvention,
Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers,
Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
@@ -192,14 +186,13 @@ namespace System.Reflection.Emit
return sigHelp;
}
- [System.Security.SecurityCritical] // auto-generated
internal static SignatureHelper GetTypeSigToken(Module mod, Type type)
{
if (mod == null)
throw new ArgumentNullException("module");
if (type == null)
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
return new SignatureHelper(mod, type);
}
@@ -221,7 +214,6 @@ namespace System.Reflection.Emit
Init(mod, callingConvention);
}
- [System.Security.SecurityCritical] // auto-generated
private SignatureHelper(Module mod, MdSigCallingConvention callingConvention, int cGenericParameters,
Type returnType, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
{
@@ -234,14 +226,12 @@ namespace System.Reflection.Emit
AddOneArgTypeHelper(returnType, requiredCustomModifiers, optionalCustomModifiers);
}
- [System.Security.SecurityCritical] // auto-generated
private SignatureHelper(Module mod, MdSigCallingConvention callingConvention,
Type returnType, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
: this(mod, callingConvention, 0, returnType, requiredCustomModifiers, optionalCustomModifiers)
{
}
- [System.Security.SecurityCritical] // auto-generated
private SignatureHelper(Module mod, Type type)
{
Init(mod);
@@ -290,7 +280,6 @@ namespace System.Reflection.Emit
#endregion
#region Private Members
- [System.Security.SecurityCritical] // auto-generated
private void AddOneArgTypeHelper(Type argument, bool pinned)
{
if (pinned)
@@ -299,7 +288,6 @@ namespace System.Reflection.Emit
AddOneArgTypeHelper(argument);
}
- [System.Security.SecurityCritical] // auto-generated
private void AddOneArgTypeHelper(Type clsArgument, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
{
// This function will not increase the argument count. It only fills in bytes
@@ -315,18 +303,18 @@ namespace System.Reflection.Emit
Type t = optionalCustomModifiers[i];
if (t == null)
- throw new ArgumentNullException("optionalCustomModifiers");
+ throw new ArgumentNullException(nameof(optionalCustomModifiers));
if (t.HasElementType)
- throw new ArgumentException(Environment.GetResourceString("Argument_ArraysInvalid"), "optionalCustomModifiers");
+ throw new ArgumentException(Environment.GetResourceString("Argument_ArraysInvalid"), nameof(optionalCustomModifiers));
if (t.ContainsGenericParameters)
- throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), "optionalCustomModifiers");
+ throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), nameof(optionalCustomModifiers));
AddElementType(CorElementType.CModOpt);
int token = m_module.GetTypeToken(t).Token;
- Contract.Assert(!MetadataToken.IsNullToken(token));
+ Debug.Assert(!MetadataToken.IsNullToken(token));
AddToken(token);
}
}
@@ -338,18 +326,18 @@ namespace System.Reflection.Emit
Type t = requiredCustomModifiers[i];
if (t == null)
- throw new ArgumentNullException("requiredCustomModifiers");
+ throw new ArgumentNullException(nameof(requiredCustomModifiers));
if (t.HasElementType)
- throw new ArgumentException(Environment.GetResourceString("Argument_ArraysInvalid"), "requiredCustomModifiers");
+ throw new ArgumentException(Environment.GetResourceString("Argument_ArraysInvalid"), nameof(requiredCustomModifiers));
if (t.ContainsGenericParameters)
- throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), "requiredCustomModifiers");
+ throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), nameof(requiredCustomModifiers));
AddElementType(CorElementType.CModReqd);
int token = m_module.GetTypeToken(t).Token;
- Contract.Assert(!MetadataToken.IsNullToken(token));
+ Debug.Assert(!MetadataToken.IsNullToken(token));
AddToken(token);
}
}
@@ -357,9 +345,7 @@ namespace System.Reflection.Emit
AddOneArgTypeHelper(clsArgument);
}
- [System.Security.SecurityCritical] // auto-generated
private void AddOneArgTypeHelper(Type clsArgument) { AddOneArgTypeHelperWorker(clsArgument, false); }
- [System.Security.SecurityCritical] // auto-generated
private void AddOneArgTypeHelperWorker(Type clsArgument, bool lastWasGenericInst)
{
if (clsArgument.IsGenericParameter)
@@ -613,7 +599,6 @@ namespace System.Reflection.Emit
AddToken(clsToken.Token);
}
- [System.Security.SecurityCritical] // auto-generated
private unsafe void InternalAddRuntimeType(Type type)
{
// Add a runtime type into the signature.
@@ -822,11 +807,10 @@ namespace System.Reflection.Emit
AddArgument(clsArgument, null, null);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void AddArgument(Type argument, bool pinned)
{
if (argument == null)
- throw new ArgumentNullException("argument");
+ throw new ArgumentNullException(nameof(argument));
IncrementArgCounts();
AddOneArgTypeHelper(argument, pinned);
@@ -835,10 +819,10 @@ namespace System.Reflection.Emit
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", "requiredCustomModifiers", "arguments"));
+ throw new ArgumentException(Environment.GetResourceString("Argument_MismatchedArrays", nameof(requiredCustomModifiers), nameof(arguments)));
if (optionalCustomModifiers != null && (arguments == null || optionalCustomModifiers.Length != arguments.Length))
- throw new ArgumentException(Environment.GetResourceString("Argument_MismatchedArrays", "optionalCustomModifiers", "arguments"));
+ throw new ArgumentException(Environment.GetResourceString("Argument_MismatchedArrays", nameof(optionalCustomModifiers), nameof(arguments)));
if (arguments != null)
{
@@ -851,14 +835,13 @@ namespace System.Reflection.Emit
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void AddArgument(Type argument, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
{
if (m_sigDone)
throw new ArgumentException(Environment.GetResourceString("Argument_SigIsFinalized"));
if (argument == null)
- throw new ArgumentNullException("argument");
+ throw new ArgumentNullException(nameof(argument));
IncrementArgCounts();
@@ -968,28 +951,6 @@ namespace System.Reflection.Emit
#endregion
-#if !FEATURE_CORECLR
- void _SignatureHelper.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _SignatureHelper.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _SignatureHelper.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- void _SignatureHelper.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
-#endif
-
}
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/SymbolMethod.cs b/src/mscorlib/src/System/Reflection/Emit/SymbolMethod.cs
index 62780f4e3a..6b47770608 100644
--- a/src/mscorlib/src/System/Reflection/Emit/SymbolMethod.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/SymbolMethod.cs
@@ -26,7 +26,6 @@ namespace System.Reflection.Emit
#endregion
#region Constructor
- [System.Security.SecurityCritical] // auto-generated
internal SymbolMethod(ModuleBuilder mod, MethodToken token, Type arrayClass, String methodName,
CallingConventions callingConvention, Type returnType, Type[] parameterTypes)
{
diff --git a/src/mscorlib/src/System/Reflection/Emit/SymbolType.cs b/src/mscorlib/src/System/Reflection/Emit/SymbolType.cs
index 633a2bffb4..84ece90982 100644
--- a/src/mscorlib/src/System/Reflection/Emit/SymbolType.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/SymbolType.cs
@@ -234,7 +234,7 @@ namespace System.Reflection.Emit
internal void SetElementType(Type baseType)
{
if (baseType == null)
- throw new ArgumentNullException("baseType");
+ throw new ArgumentNullException(nameof(baseType));
Contract.EndContractBlock();
m_baseType = baseType;
diff --git a/src/mscorlib/src/System/Reflection/Emit/TypeBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/TypeBuilder.cs
index 6db04717b5..73778d5f27 100644
--- a/src/mscorlib/src/System/Reflection/Emit/TypeBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/TypeBuilder.cs
@@ -10,13 +10,13 @@ namespace System.Reflection.Emit {
using System.Reflection;
using System.Security;
using System.Security.Permissions;
- using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Collections.Generic;
using CultureInfo = System.Globalization.CultureInfo;
using System.Threading;
using System.Runtime.Versioning;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
@@ -35,7 +35,6 @@ namespace System.Reflection.Emit {
Size128 = 128,
}
- [HostProtection(MayLeakOnAbort = true)]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_TypeBuilder))]
[System.Runtime.InteropServices.ComVisible(true)]
@@ -56,10 +55,10 @@ namespace System.Reflection.Emit {
public CustAttr(ConstructorInfo con, byte[] binaryAttribute)
{
if (con == null)
- throw new ArgumentNullException("con");
+ throw new ArgumentNullException(nameof(con));
if (binaryAttribute == null)
- throw new ArgumentNullException("binaryAttribute");
+ throw new ArgumentNullException(nameof(binaryAttribute));
Contract.EndContractBlock();
m_con = con;
@@ -69,13 +68,12 @@ namespace System.Reflection.Emit {
public CustAttr(CustomAttributeBuilder customBuilder)
{
if (customBuilder == null)
- throw new ArgumentNullException("customBuilder");
+ throw new ArgumentNullException(nameof(customBuilder));
Contract.EndContractBlock();
m_customBuilder = customBuilder;
}
- [System.Security.SecurityCritical] // auto-generated
public void Bake(ModuleBuilder module, int token)
{
if (m_customBuilder == null)
@@ -105,13 +103,13 @@ namespace System.Reflection.Emit {
// 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"), "method");
+ throw new ArgumentException(Environment.GetResourceString("Argument_NeedGenericMethodDefinition"), nameof(method));
if (method.DeclaringType == null || !method.DeclaringType.IsGenericTypeDefinition)
- throw new ArgumentException(Environment.GetResourceString("Argument_MethodNeedGenericDeclaringType"), "method");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MethodNeedGenericDeclaringType"), nameof(method));
if (type.GetGenericTypeDefinition() != method.DeclaringType)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidMethodDeclaringType"), "type");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidMethodDeclaringType"), nameof(type));
Contract.EndContractBlock();
// The following converts from Type or TypeBuilder of G<T> to TypeBuilderInstantiation G<T>. These types
@@ -121,7 +119,7 @@ namespace System.Reflection.Emit {
type = type.MakeGenericType(type.GetGenericArguments());
if (!(type is TypeBuilderInstantiation))
- throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), "type");
+ throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), nameof(type));
return MethodOnTypeBuilderInstantiation.GetMethod(method, type as TypeBuilderInstantiation);
}
@@ -131,18 +129,18 @@ namespace System.Reflection.Emit {
throw new ArgumentException(Environment.GetResourceString("Argument_MustBeTypeBuilder"));
if (!constructor.DeclaringType.IsGenericTypeDefinition)
- throw new ArgumentException(Environment.GetResourceString("Argument_ConstructorNeedGenericDeclaringType"), "constructor");
+ throw new ArgumentException(Environment.GetResourceString("Argument_ConstructorNeedGenericDeclaringType"), nameof(constructor));
Contract.EndContractBlock();
if (!(type is TypeBuilderInstantiation))
- throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), "type");
+ throw new ArgumentException(Environment.GetResourceString("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"), "type");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidConstructorDeclaringType"), nameof(type));
return ConstructorOnTypeBuilderInstantiation.GetConstructor(constructor, type as TypeBuilderInstantiation);
}
@@ -152,18 +150,18 @@ namespace System.Reflection.Emit {
throw new ArgumentException(Environment.GetResourceString("Argument_MustBeTypeBuilder"));
if (!field.DeclaringType.IsGenericTypeDefinition)
- throw new ArgumentException(Environment.GetResourceString("Argument_FieldNeedGenericDeclaringType"), "field");
+ throw new ArgumentException(Environment.GetResourceString("Argument_FieldNeedGenericDeclaringType"), nameof(field));
Contract.EndContractBlock();
if (!(type is TypeBuilderInstantiation))
- throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), "type");
+ throw new ArgumentException(Environment.GetResourceString("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"), "type");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFieldDeclaringType"), nameof(type));
return FieldOnTypeBuilderInstantiation.GetField(field, type as TypeBuilderInstantiation);
}
@@ -174,36 +172,30 @@ namespace System.Reflection.Emit {
#endregion
#region Private Static FCalls
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void SetParentType(RuntimeModule module, int tdTypeDef, int tkParent);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void AddInterfaceImpl(RuntimeModule module, int tdTypeDef, int tkInterface);
#endregion
#region Internal Static FCalls
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal static extern int DefineMethod(RuntimeModule module, int tkParent, String name, byte[] signature, int sigLength,
MethodAttributes attributes);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal static extern int DefineMethodSpec(RuntimeModule module, int tkParent, byte[] signature, int sigLength);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal static extern int DefineField(RuntimeModule module, int tkParent, String name, byte[] signature, int sigLength,
FieldAttributes attributes);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void SetMethodIL(RuntimeModule module, int tk, bool isInitLocals,
@@ -213,13 +205,11 @@ namespace System.Reflection.Emit {
ExceptionHandler[] exceptions, int numExceptions,
int [] tokenFixups, int numTokenFixups);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void DefineCustomAttribute(RuntimeModule module, int tkAssociate, int tkConstructor,
byte[] attr, int attrLength, bool toDisk, bool updateCompilerFlags);
- [System.Security.SecurityCritical] // auto-generated
internal static void DefineCustomAttribute(ModuleBuilder module, int tkAssociate, int tkConstructor,
byte[] attr, bool toDisk, bool updateCompilerFlags)
{
@@ -235,75 +225,56 @@ namespace System.Reflection.Emit {
localAttr, (localAttr != null) ? localAttr.Length : 0, toDisk, updateCompilerFlags);
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal static extern void SetPInvokeData(RuntimeModule module, String DllName, String name, int token, int linkFlags);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal static extern int DefineProperty(RuntimeModule module, int tkParent, String name, PropertyAttributes attributes,
byte[] signature, int sigLength);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal static extern int DefineEvent(RuntimeModule module, int tkParent, String name, EventAttributes attributes, int tkEventType);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal static extern void DefineMethodSemantics(RuntimeModule module, int tkAssociation,
MethodSemanticsAttributes semantics, int tkMethod);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal static extern void DefineMethodImpl(RuntimeModule module, int tkType, int tkBody, int tkDecl);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal static extern void SetMethodImpl(RuntimeModule module, int tkMethod, MethodImplAttributes MethodImplAttributes);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal static extern int SetParamInfo(RuntimeModule module, int tkMethod, int iSequence,
ParameterAttributes iParamAttributes, String strParamName);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal static extern int GetTokenFromSig(RuntimeModule module, byte[] signature, int sigLength);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal static extern void SetFieldLayoutOffset(RuntimeModule module, int fdToken, int iOffset);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal static extern void SetClassLayout(RuntimeModule module, int tk, PackingSize iPackingSize, int iTypeSize);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal static extern void SetFieldMarshal(RuntimeModule module, int tk, byte[] ubMarshal, int ubSize);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern unsafe void SetConstantValue(RuntimeModule module, int tk, int corType, void* pValue);
-
-#if FEATURE_CAS_POLICY
- [System.Security.SecurityCritical] // auto-generated
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- internal static extern void AddDeclarativeSecurity(RuntimeModule module, int parent, SecurityAction action, byte[] blob, int cb);
-#endif
#endregion
#region Internal\Private Static Members
@@ -381,7 +352,6 @@ namespace System.Reflection.Emit {
return false;
}
- [System.Security.SecurityCritical] // auto-generated
internal static unsafe void SetConstantValue(ModuleBuilder module, int tk, Type destType, Object value)
{
// This is a helper function that is used by ParameterBuilder, PropertyBuilder,
@@ -433,7 +403,7 @@ namespace System.Reflection.Emit {
}
else // must be a runtime Enum Type
{
- Contract.Assert(destType is RuntimeType, "destType is not a runtime type, an EnumBuilder, or a TypeBuilder.");
+ Debug.Assert(destType is RuntimeType, "destType is not a runtime type, an EnumBuilder, or a TypeBuilder.");
underlyingType = Enum.GetUnderlyingType(destType);
@@ -576,7 +546,6 @@ namespace System.Reflection.Emit {
m_typeInterfaces = new List<Type>();
}
- [System.Security.SecurityCritical] // auto-generated
internal TypeBuilder(
String name,
TypeAttributes attr,
@@ -590,22 +559,21 @@ namespace System.Reflection.Emit {
Init(name, attr, parent, interfaces, module, iPackingSize, iTypeSize, enclosingType);
}
- [System.Security.SecurityCritical] // auto-generated
private void Init(String fullname, TypeAttributes attr, Type parent, Type[] interfaces, ModuleBuilder module,
PackingSize iPackingSize, int iTypeSize, TypeBuilder enclosingType)
{
if (fullname == null)
- throw new ArgumentNullException("fullname");
+ throw new ArgumentNullException(nameof(fullname));
if (fullname.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "fullname");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(fullname));
if (fullname[0] == '\0')
- throw new ArgumentException(Environment.GetResourceString("Argument_IllegalName"), "fullname");
+ throw new ArgumentException(Environment.GetResourceString("Argument_IllegalName"), nameof(fullname));
if (fullname.Length > 1023)
- throw new ArgumentException(Environment.GetResourceString("Argument_TypeNameTooLong"), "fullname");
+ throw new ArgumentException(Environment.GetResourceString("Argument_TypeNameTooLong"), nameof(fullname));
Contract.EndContractBlock();
int i;
@@ -621,7 +589,7 @@ 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"), "attr");
+ throw new ArgumentException(Environment.GetResourceString("Argument_BadNestedTypeFlags"), nameof(attr));
}
int[] interfaceTokens = null;
@@ -632,7 +600,7 @@ namespace System.Reflection.Emit {
if (interfaces[i] == null)
{
// cannot contain null in the interface list
- throw new ArgumentNullException("interfaces");
+ throw new ArgumentNullException(nameof(interfaces));
}
}
interfaceTokens = new int[interfaces.Length + 1];
@@ -685,32 +653,12 @@ namespace System.Reflection.Emit {
if ((m_iPackingSize != 0) ||(m_iTypeSize != 0))
SetClassLayout(GetModuleBuilder().GetNativeHandle(), m_tdType.Token, m_iPackingSize, m_iTypeSize);
-#if !FEATURE_CORECLR
- // If the type is public and it is contained in a assemblyBuilder,
- // update the public COMType list.
- if (IsPublicComType(this))
- {
- if (containingAssem.IsPersistable() && m_module.IsTransient() == false)
- {
- // This will throw InvalidOperationException if the assembly has been saved
- // Ideally we should reject all emit operations if the assembly has been saved,
- // but that would be a breaking change for some. Currently you cannot define
- // modules and public types, but you can still define private types and global methods.
- containingAssem.m_assemblyData.AddPublicComType(this);
- }
-
- // Now add the type to the ExportedType table
- if (!m_module.Equals(containingAssem.ManifestModule))
- containingAssem.DefineExportedTypeInMemory(this, m_module.m_moduleData.FileToken, m_tdType.Token);
- }
-#endif
m_module.AddType(FullName, this);
}
#endregion
#region Private Members
- [System.Security.SecurityCritical] // auto-generated
private MethodBuilder DefinePInvokeMethodHelper(
String name, String dllName, String importName, MethodAttributes attributes, CallingConventions callingConvention,
Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
@@ -733,7 +681,6 @@ namespace System.Reflection.Emit {
}
}
- [System.Security.SecurityCritical] // auto-generated
private MethodBuilder DefinePInvokeMethodHelperNoLock(
String name, String dllName, String importName, MethodAttributes attributes, CallingConventions callingConvention,
Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
@@ -741,22 +688,22 @@ namespace System.Reflection.Emit {
CallingConvention nativeCallConv, CharSet nativeCharSet)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (name.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name));
if (dllName == null)
- throw new ArgumentNullException("dllName");
+ throw new ArgumentNullException(nameof(dllName));
if (dllName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "dllName");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(dllName));
if (importName == null)
- throw new ArgumentNullException("importName");
+ throw new ArgumentNullException(nameof(importName));
if (importName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "importName");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(importName));
if ((attributes & MethodAttributes.Abstract) != 0)
throw new ArgumentException(Environment.GetResourceString("Argument_BadPInvokeMethod"));
@@ -831,7 +778,6 @@ namespace System.Reflection.Emit {
return method;
}
- [System.Security.SecurityCritical] // auto-generated
private FieldBuilder DefineDataHelper(String name, byte[] data, int size, FieldAttributes attributes)
{
String strValueClassName;
@@ -840,10 +786,10 @@ namespace System.Reflection.Emit {
TypeAttributes typeAttributes;
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (name.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name));
if (size <= 0 || size >= 0x003f0000)
throw new ArgumentException(Environment.GetResourceString("Argument_BadSizeForData"));
@@ -916,19 +862,16 @@ namespace System.Reflection.Emit {
#endregion
#region FCalls
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static int DefineType(RuntimeModule module,
String fullname, int tkParent, TypeAttributes attributes, int tkEnclosingType, int[] interfaceTokens);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static int DefineGenericParam(RuntimeModule module,
String name, int tkParent, GenericParameterAttributes attributes, int position, int[] constraints);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void TermCreateClass(RuntimeModule module, int tk, ObjectHandleOnStack type);
@@ -1363,38 +1306,17 @@ namespace System.Reflection.Emit {
public override bool IsSecurityCritical
{
- get
- {
- if (!IsCreated())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated"));
- Contract.EndContractBlock();
-
- return m_bakedRuntimeType.IsSecurityCritical;
- }
+ get { return true; }
}
public override bool IsSecuritySafeCritical
{
- get
- {
- if (!IsCreated())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated"));
- Contract.EndContractBlock();
-
- return m_bakedRuntimeType.IsSecuritySafeCritical;
- }
+ get { return false; }
}
public override bool IsSecurityTransparent
{
- get
- {
- if (!IsCreated())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated"));
- Contract.EndContractBlock();
-
- return m_bakedRuntimeType.IsSecurityTransparent;
- }
+ get { return false; }
}
[System.Runtime.InteropServices.ComVisible(true)]
@@ -1479,7 +1401,6 @@ namespace System.Reflection.Emit {
#endregion
#region ICustomAttributeProvider Implementation
- [System.Security.SecuritySafeCritical] // auto-generated
public override Object[] GetCustomAttributes(bool inherit)
{
if (!IsCreated())
@@ -1489,38 +1410,36 @@ namespace System.Reflection.Emit {
return CustomAttribute.GetCustomAttributes(m_bakedRuntimeType, typeof(object) as RuntimeType, inherit);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
{
if (!IsCreated())
throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated"));
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
Contract.EndContractBlock();
RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
return CustomAttribute.GetCustomAttributes(m_bakedRuntimeType, attributeRuntimeType, inherit);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override bool IsDefined(Type attributeType, bool inherit)
{
if (!IsCreated())
throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated"));
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
Contract.EndContractBlock();
RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"caType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
return CustomAttribute.IsDefined(m_bakedRuntimeType, attributeRuntimeType, inherit);
}
@@ -1547,7 +1466,7 @@ namespace System.Reflection.Emit {
public GenericTypeParameterBuilder[] DefineGenericParameters(params string[] names)
{
if (names == null)
- throw new ArgumentNullException("names");
+ throw new ArgumentNullException(nameof(names));
if (names.Length == 0)
throw new ArgumentException();
@@ -1555,7 +1474,7 @@ namespace System.Reflection.Emit {
for (int i = 0; i < names.Length; i ++)
if (names[i] == null)
- throw new ArgumentNullException("names");
+ throw new ArgumentNullException(nameof(names));
if (m_inst != null)
throw new InvalidOperationException();
@@ -1589,7 +1508,6 @@ namespace System.Reflection.Emit {
#endregion
#region Define Method
- [System.Security.SecuritySafeCritical] // auto-generated
public void DefineMethodOverride(MethodInfo methodInfoBody, MethodInfo methodInfoDeclaration)
{
lock(SyncRoot)
@@ -1598,14 +1516,13 @@ namespace System.Reflection.Emit {
}
}
- [System.Security.SecurityCritical] // auto-generated
private void DefineMethodOverrideNoLock(MethodInfo methodInfoBody, MethodInfo methodInfoDeclaration)
{
if (methodInfoBody == null)
- throw new ArgumentNullException("methodInfoBody");
+ throw new ArgumentNullException(nameof(methodInfoBody));
if (methodInfoDeclaration == null)
- throw new ArgumentNullException("methodInfoDeclaration");
+ throw new ArgumentNullException(nameof(methodInfoDeclaration));
Contract.EndContractBlock();
ThrowIfCreated();
@@ -1671,10 +1588,10 @@ namespace System.Reflection.Emit {
Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (name.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name));
Contract.Ensures(Contract.Result<MethodBuilder>() != null);
Contract.EndContractBlock();
@@ -1686,10 +1603,10 @@ namespace System.Reflection.Emit {
if (parameterTypes != null)
{
if (parameterTypeOptionalCustomModifiers != null && parameterTypeOptionalCustomModifiers.Length != parameterTypes.Length)
- throw new ArgumentException(Environment.GetResourceString("Argument_MismatchedArrays", "parameterTypeOptionalCustomModifiers", "parameterTypes"));
+ throw new ArgumentException(Environment.GetResourceString("Argument_MismatchedArrays", nameof(parameterTypeOptionalCustomModifiers), nameof(parameterTypes)));
if (parameterTypeRequiredCustomModifiers != null && parameterTypeRequiredCustomModifiers.Length != parameterTypes.Length)
- throw new ArgumentException(Environment.GetResourceString("Argument_MismatchedArrays", "parameterTypeRequiredCustomModifiers", "parameterTypes"));
+ throw new ArgumentException(Environment.GetResourceString("Argument_MismatchedArrays", nameof(parameterTypeRequiredCustomModifiers), nameof(parameterTypes)));
}
ThrowIfCreated();
@@ -1725,7 +1642,6 @@ namespace System.Reflection.Emit {
#endregion
#region Define Constructor
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(true)]
public ConstructorBuilder DefineTypeInitializer()
{
@@ -1735,7 +1651,6 @@ namespace System.Reflection.Emit {
}
}
- [System.Security.SecurityCritical] // auto-generated
private ConstructorBuilder DefineTypeInitializerNoLock()
{
ThrowIfCreated();
@@ -1823,7 +1738,6 @@ namespace System.Reflection.Emit {
return DefineConstructor(attributes, callingConvention, parameterTypes, null, null);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(true)]
public ConstructorBuilder DefineConstructor(MethodAttributes attributes, CallingConventions callingConvention,
Type[] parameterTypes, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
@@ -1839,7 +1753,6 @@ namespace System.Reflection.Emit {
}
}
- [System.Security.SecurityCritical] // auto-generated
private ConstructorBuilder DefineConstructorNoLock(MethodAttributes attributes, CallingConventions callingConvention,
Type[] parameterTypes, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
{
@@ -1874,11 +1787,6 @@ namespace System.Reflection.Emit {
#endregion
#region Define PInvoke
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
public MethodBuilder DefinePInvokeMethod(String name, String dllName, MethodAttributes attributes,
CallingConventions callingConvention, Type returnType, Type[] parameterTypes,
CallingConvention nativeCallConv, CharSet nativeCharSet)
@@ -1889,11 +1797,6 @@ namespace System.Reflection.Emit {
return method;
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
public MethodBuilder DefinePInvokeMethod(String name, String dllName, String entryName, MethodAttributes attributes,
CallingConventions callingConvention, Type returnType, Type[] parameterTypes,
CallingConvention nativeCallConv, CharSet nativeCharSet)
@@ -1904,11 +1807,6 @@ namespace System.Reflection.Emit {
return method;
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
public MethodBuilder DefinePInvokeMethod(String name, String dllName, String entryName, MethodAttributes attributes,
CallingConventions callingConvention,
Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
@@ -1924,7 +1822,6 @@ namespace System.Reflection.Emit {
#endregion
#region Define Nested Type
- [System.Security.SecuritySafeCritical] // auto-generated
public TypeBuilder DefineNestedType(String name)
{
lock(SyncRoot)
@@ -1933,7 +1830,6 @@ namespace System.Reflection.Emit {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(true)]
public TypeBuilder DefineNestedType(String name, TypeAttributes attr, Type parent, Type[] interfaces)
{
@@ -1947,7 +1843,6 @@ namespace System.Reflection.Emit {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public TypeBuilder DefineNestedType(String name, TypeAttributes attr, Type parent)
{
lock(SyncRoot)
@@ -1956,7 +1851,6 @@ namespace System.Reflection.Emit {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public TypeBuilder DefineNestedType(String name, TypeAttributes attr)
{
lock(SyncRoot)
@@ -1965,11 +1859,6 @@ namespace System.Reflection.Emit {
}
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
public TypeBuilder DefineNestedType(String name, TypeAttributes attr, Type parent, int typeSize)
{
lock(SyncRoot)
@@ -1978,11 +1867,6 @@ namespace System.Reflection.Emit {
}
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
public TypeBuilder DefineNestedType(String name, TypeAttributes attr, Type parent, PackingSize packSize)
{
lock(SyncRoot)
@@ -1991,11 +1875,6 @@ namespace System.Reflection.Emit {
}
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
public TypeBuilder DefineNestedType(String name, TypeAttributes attr, Type parent, PackingSize packSize, int typeSize)
{
lock (SyncRoot)
@@ -2004,7 +1883,6 @@ namespace System.Reflection.Emit {
}
}
- [System.Security.SecurityCritical] // auto-generated
private TypeBuilder DefineNestedTypeNoLock(String name, TypeAttributes attr, Type parent, Type[] interfaces, PackingSize packSize, int typeSize)
{
return new TypeBuilder(name, attr, parent, interfaces, m_module, packSize, typeSize, this);
@@ -2018,7 +1896,6 @@ namespace System.Reflection.Emit {
return DefineField(fieldName, type, null, null, attributes);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public FieldBuilder DefineField(String fieldName, Type type, Type[] requiredCustomModifiers,
Type[] optionalCustomModifiers, FieldAttributes attributes)
{
@@ -2028,7 +1905,6 @@ namespace System.Reflection.Emit {
}
}
- [System.Security.SecurityCritical] // auto-generated
private FieldBuilder DefineFieldNoLock(String fieldName, Type type, Type[] requiredCustomModifiers,
Type[] optionalCustomModifiers, FieldAttributes attributes)
{
@@ -2048,11 +1924,6 @@ namespace System.Reflection.Emit {
return new FieldBuilder(this, fieldName, type, requiredCustomModifiers, optionalCustomModifiers, attributes);
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
public FieldBuilder DefineInitializedData(String name, byte[] data, FieldAttributes attributes)
{
lock(SyncRoot)
@@ -2061,11 +1932,10 @@ namespace System.Reflection.Emit {
}
}
- [System.Security.SecurityCritical] // auto-generated
private FieldBuilder DefineInitializedDataNoLock(String name, byte[] data, FieldAttributes attributes)
{
if (data == null)
- throw new ArgumentNullException("data");
+ throw new ArgumentNullException(nameof(data));
Contract.EndContractBlock();
// This method will define an initialized Data in .sdata.
@@ -2075,11 +1945,6 @@ namespace System.Reflection.Emit {
return DefineDataHelper(name, data, data.Length, attributes);
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
public FieldBuilder DefineUninitializedData(String name, int size, FieldAttributes attributes)
{
lock(SyncRoot)
@@ -2088,7 +1953,6 @@ namespace System.Reflection.Emit {
}
}
- [System.Security.SecurityCritical] // auto-generated
private FieldBuilder DefineUninitializedDataNoLock(String name, int size, FieldAttributes attributes)
{
// This method will define an uninitialized Data in .sdata.
@@ -2121,7 +1985,6 @@ namespace System.Reflection.Emit {
parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public PropertyBuilder DefineProperty(String name, PropertyAttributes attributes, CallingConventions callingConvention,
Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
@@ -2133,15 +1996,14 @@ namespace System.Reflection.Emit {
}
}
- [System.Security.SecurityCritical] // auto-generated
private PropertyBuilder DefinePropertyNoLock(String name, PropertyAttributes attributes, CallingConventions callingConvention,
Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (name.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name));
Contract.EndContractBlock();
CheckContext(returnType);
@@ -2183,7 +2045,6 @@ namespace System.Reflection.Emit {
this);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public EventBuilder DefineEvent(String name, EventAttributes attributes, Type eventtype)
{
lock(SyncRoot)
@@ -2192,15 +2053,14 @@ namespace System.Reflection.Emit {
}
}
- [System.Security.SecurityCritical] // auto-generated
private EventBuilder DefineEventNoLock(String name, EventAttributes attributes, Type eventtype)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (name.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name));
if (name[0] == '\0')
- throw new ArgumentException(Environment.GetResourceString("Argument_IllegalName"), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_IllegalName"), nameof(name));
Contract.EndContractBlock();
int tkType;
@@ -2234,7 +2094,6 @@ namespace System.Reflection.Emit {
#region Create Type
- [System.Security.SecuritySafeCritical] // auto-generated
public TypeInfo CreateTypeInfo()
{
lock (SyncRoot)
@@ -2243,7 +2102,6 @@ namespace System.Reflection.Emit {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public Type CreateType()
{
lock (SyncRoot)
@@ -2261,7 +2119,6 @@ namespace System.Reflection.Emit {
m_module.CheckContext(types);
}
- [System.Security.SecurityCritical] // auto-generated
private TypeInfo CreateTypeNoLock()
{
if (IsCreated())
@@ -2486,13 +2343,12 @@ namespace System.Reflection.Emit {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(true)]
public void AddInterfaceImplementation(Type interfaceType)
{
if (interfaceType == null)
{
- throw new ArgumentNullException("interfaceType");
+ throw new ArgumentNullException(nameof(interfaceType));
}
Contract.EndContractBlock();
@@ -2506,50 +2362,6 @@ namespace System.Reflection.Emit {
m_typeInterfaces.Add(interfaceType);
}
-#if FEATURE_CAS_POLICY
- [System.Security.SecuritySafeCritical] // auto-generated
- public void AddDeclarativeSecurity(SecurityAction action, PermissionSet pset)
- {
- lock(SyncRoot)
- {
- AddDeclarativeSecurityNoLock(action, pset);
- }
- }
-
- [System.Security.SecurityCritical] // auto-generated
- private void AddDeclarativeSecurityNoLock(SecurityAction action, PermissionSet pset)
- {
- if (pset == null)
- throw new ArgumentNullException("pset");
-
-#pragma warning disable 618
- if (!Enum.IsDefined(typeof(SecurityAction), action) ||
- action == SecurityAction.RequestMinimum ||
- action == SecurityAction.RequestOptional ||
- action == SecurityAction.RequestRefuse)
- {
- throw new ArgumentOutOfRangeException("action");
- }
-#pragma warning restore 618
-
- Contract.EndContractBlock();
-
- ThrowIfCreated();
-
- // Translate permission set into serialized format(uses standard binary serialization format).
- byte[] blob = null;
- int length = 0;
- if (!pset.IsEmpty())
- {
- blob = pset.EncodeXml();
- length = blob.Length;
- }
-
- // Write the blob into the metadata.
- AddDeclarativeSecurity(m_module.GetNativeHandle(), m_tdType.Token, action, blob, length);
- }
-#endif // FEATURE_CAS_POLICY
-
public TypeToken TypeToken
{
get
@@ -2562,30 +2374,24 @@ public TypeToken TypeToken
}
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
[System.Runtime.InteropServices.ComVisible(true)]
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
{
if (con == null)
- throw new ArgumentNullException("con");
+ throw new ArgumentNullException(nameof(con));
if (binaryAttribute == null)
- throw new ArgumentNullException("binaryAttribute");
+ throw new ArgumentNullException(nameof(binaryAttribute));
Contract.EndContractBlock();
TypeBuilder.DefineCustomAttribute(m_module, m_tdType.Token, ((ModuleBuilder)m_module).GetConstructorToken(con).Token,
binaryAttribute, false, false);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
{
if (customBuilder == null)
- throw new ArgumentNullException("customBuilder");
+ throw new ArgumentNullException(nameof(customBuilder));
Contract.EndContractBlock();
customBuilder.CreateCustomAttribute((ModuleBuilder)m_module, m_tdType.Token);
@@ -2594,27 +2400,5 @@ public TypeToken TypeToken
#endregion
#endregion
-
-#if !FEATURE_CORECLR
- void _TypeBuilder.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _TypeBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _TypeBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- void _TypeBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
-#endif
}
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs b/src/mscorlib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs
index 13b98b6543..3bae585953 100644
--- a/src/mscorlib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs
@@ -28,13 +28,13 @@ namespace System.Reflection.Emit
throw new InvalidOperationException();
if (typeArguments == null)
- throw new ArgumentNullException("typeArguments");
+ throw new ArgumentNullException(nameof(typeArguments));
Contract.EndContractBlock();
foreach (Type t in typeArguments)
{
if (t == null)
- throw new ArgumentNullException("typeArguments");
+ throw new ArgumentNullException(nameof(typeArguments));
}
return new TypeBuilderInstantiation(type, typeArguments);
diff --git a/src/mscorlib/src/System/Reflection/Emit/UnmanagedMarshal.cs b/src/mscorlib/src/System/Reflection/Emit/UnmanagedMarshal.cs
index 09eac3a272..28e95e2456 100644
--- a/src/mscorlib/src/System/Reflection/Emit/UnmanagedMarshal.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/UnmanagedMarshal.cs
@@ -10,7 +10,6 @@ namespace System.Reflection.Emit
// This class is describing the fieldmarshal.
[Serializable]
- [HostProtection(MayLeakOnAbort = true)]
[System.Runtime.InteropServices.ComVisible(true)]
[Obsolete("An alternate API is available: Emit the MarshalAs custom attribute instead. http://go.microsoft.com/fwlink/?linkid=14202")]
public sealed class UnmanagedMarshal
diff --git a/src/mscorlib/src/System/Reflection/Emit/XXXOnTypeBuilderInstantiation.cs b/src/mscorlib/src/System/Reflection/Emit/XXXOnTypeBuilderInstantiation.cs
index 5b36e0e372..aaaffc0df6 100644
--- a/src/mscorlib/src/System/Reflection/Emit/XXXOnTypeBuilderInstantiation.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/XXXOnTypeBuilderInstantiation.cs
@@ -11,6 +11,7 @@ namespace System.Reflection.Emit
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
internal sealed class MethodOnTypeBuilderInstantiation : MethodInfo
@@ -30,7 +31,7 @@ namespace System.Reflection.Emit
#region Constructor
internal MethodOnTypeBuilderInstantiation(MethodInfo method, TypeBuilderInstantiation type)
{
- Contract.Assert(method is MethodBuilder || method is RuntimeMethodInfo);
+ Debug.Assert(method is MethodBuilder || method is RuntimeMethodInfo);
m_method = method;
m_type = type;
@@ -60,7 +61,7 @@ namespace System.Reflection.Emit
return mb.MetadataTokenInternal;
else
{
- Contract.Assert(m_method is RuntimeMethodInfo);
+ Debug.Assert(m_method is RuntimeMethodInfo);
return m_method.MetadataToken;
}
}
@@ -122,7 +123,7 @@ namespace System.Reflection.Emit
#region Constructor
internal ConstructorOnTypeBuilderInstantiation(ConstructorInfo constructor, TypeBuilderInstantiation type)
{
- Contract.Assert(constructor is ConstructorBuilder || constructor is RuntimeConstructorInfo);
+ Debug.Assert(constructor is ConstructorBuilder || constructor is RuntimeConstructorInfo);
m_ctor = constructor;
m_type = type;
@@ -157,7 +158,7 @@ namespace System.Reflection.Emit
return cb.MetadataTokenInternal;
else
{
- Contract.Assert(m_ctor is RuntimeConstructorInfo);
+ Debug.Assert(m_ctor is RuntimeConstructorInfo);
return m_ctor.MetadataToken;
}
}
@@ -231,7 +232,7 @@ namespace System.Reflection.Emit
#region Constructor
internal FieldOnTypeBuilderInstantiation(FieldInfo field, TypeBuilderInstantiation type)
{
- Contract.Assert(field is FieldBuilder || field is RuntimeFieldInfo);
+ Debug.Assert(field is FieldBuilder || field is RuntimeFieldInfo);
m_field = field;
m_type = type;
@@ -258,7 +259,7 @@ namespace System.Reflection.Emit
return fb.MetadataTokenInternal;
else
{
- Contract.Assert(m_field is RuntimeFieldInfo);
+ Debug.Assert(m_field is RuntimeFieldInfo);
return m_field.MetadataToken;
}
}
diff --git a/src/mscorlib/src/System/Reflection/EventInfo.cs b/src/mscorlib/src/System/Reflection/EventInfo.cs
index 3fd1951b6c..0eabb9d03a 100644
--- a/src/mscorlib/src/System/Reflection/EventInfo.cs
+++ b/src/mscorlib/src/System/Reflection/EventInfo.cs
@@ -19,9 +19,6 @@ namespace System.Reflection
[Serializable]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_EventInfo))]
-#pragma warning disable 618
- [PermissionSetAttribute(SecurityAction.InheritanceDemand, Name = "FullTrust")]
-#pragma warning restore 618
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class EventInfo : MemberInfo, _EventInfo
{
@@ -123,7 +120,7 @@ namespace System.Reflection
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotSupportedOnWinRTEvent"));
// Must be a normal non-WinRT event
- Contract.Assert(addMethod.ReturnType == typeof(void));
+ Debug.Assert(addMethod.ReturnType == typeof(void));
#endif // FEATURE_COMINTEROP
addMethod.Invoke(target, new object[] { handler });
@@ -140,13 +137,13 @@ namespace System.Reflection
#if FEATURE_COMINTEROP
ParameterInfo[] parameters = removeMethod.GetParametersNoCopy();
- Contract.Assert(parameters != null && parameters.Length == 1);
+ 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
- Contract.Assert(parameters[0].ParameterType.BaseType == typeof(MulticastDelegate));
+ Debug.Assert(parameters[0].ParameterType.BaseType == typeof(MulticastDelegate));
#endif // FEATURE_COMINTEROP
removeMethod.Invoke(target, new object[] { handler });
@@ -190,35 +187,6 @@ namespace System.Reflection
}
}
#endregion
-
-#if !FEATURE_CORECLR
- Type _EventInfo.GetType()
- {
- return base.GetType();
- }
-
- void _EventInfo.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _EventInfo.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _EventInfo.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- // If you implement this method, make sure to include _EventInfo.Invoke in VM\DangerousAPIs.h and
- // include _EventInfo in SystemDomain::IsReflectionInvocationMethod in AppDomain.cpp.
- void _EventInfo.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
-#endif
}
[Serializable]
@@ -228,7 +196,6 @@ namespace System.Reflection
private int m_token;
private EventAttributes m_flags;
private string m_name;
- [System.Security.SecurityCritical]
private void* m_utf8name;
private RuntimeTypeCache m_reflectedTypeCache;
private RuntimeMethodInfo m_addMethod;
@@ -244,12 +211,11 @@ namespace System.Reflection
{
// Used for dummy head node during population
}
- [System.Security.SecurityCritical] // auto-generated
internal RuntimeEventInfo(int tkEvent, RuntimeType declaredType, RuntimeTypeCache reflectedTypeCache, out bool isPrivate)
{
Contract.Requires(declaredType != null);
Contract.Requires(reflectedTypeCache != null);
- Contract.Assert(!reflectedTypeCache.IsGlobal);
+ Debug.Assert(!reflectedTypeCache.IsGlobal);
MetadataImport scope = declaredType.GetRuntimeModule().MetadataImport;
@@ -305,28 +271,27 @@ namespace System.Reflection
public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
{
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
Contract.EndContractBlock();
RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override bool IsDefined(Type attributeType, bool inherit)
{
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
Contract.EndContractBlock();
RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
return CustomAttribute.IsDefined(this, attributeRuntimeType);
}
@@ -341,7 +306,6 @@ namespace System.Reflection
public override MemberTypes MemberType { get { return MemberTypes.Event; } }
public override String Name
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
if (m_name == null)
@@ -373,11 +337,10 @@ namespace System.Reflection
#endregion
#region ISerializable
- [System.Security.SecurityCritical] // auto-generated_required
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
MemberInfoSerializationHolder.GetSerializationInfo(
diff --git a/src/mscorlib/src/System/Reflection/FieldInfo.cs b/src/mscorlib/src/System/Reflection/FieldInfo.cs
index c6a44d412b..e61207a686 100644
--- a/src/mscorlib/src/System/Reflection/FieldInfo.cs
+++ b/src/mscorlib/src/System/Reflection/FieldInfo.cs
@@ -15,9 +15,6 @@ namespace System.Reflection
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
-#if FEATURE_REMOTING
- using System.Runtime.Remoting.Metadata;
-#endif //FEATURE_REMOTING
using System.Runtime.Serialization;
using System.Security.Permissions;
using System.Threading;
@@ -26,9 +23,6 @@ namespace System.Reflection
[Serializable]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_FieldInfo))]
-#pragma warning disable 618
- [PermissionSetAttribute(SecurityAction.InheritanceDemand, Name = "FullTrust")]
-#pragma warning restore 618
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class FieldInfo : MemberInfo, _FieldInfo
{
@@ -36,7 +30,7 @@ namespace System.Reflection
public static FieldInfo GetFieldFromHandle(RuntimeFieldHandle handle)
{
if (handle.IsNullHandle())
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidHandle"), "handle");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidHandle"), nameof(handle));
FieldInfo f = RuntimeType.GetFieldInfo(handle.GetRuntimeFieldInfo());
@@ -186,35 +180,6 @@ namespace System.Reflection
}
#endregion
-
-#if !FEATURE_CORECLR
- Type _FieldInfo.GetType()
- {
- return base.GetType();
- }
-
- void _FieldInfo.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _FieldInfo.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _FieldInfo.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- // If you implement this method, make sure to include _FieldInfo.Invoke in VM\DangerousAPIs.h and
- // include _FieldInfo in SystemDomain::IsReflectionInvocationMethod in AppDomain.cpp.
- void _FieldInfo.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
-#endif
}
[Serializable]
@@ -239,36 +204,6 @@ namespace System.Reflection
}
#endregion
-#if FEATURE_REMOTING
- #region Legacy Remoting Cache
- // The size of CachedData is accounted for by BaseObjectWithCachedData in object.h.
- // This member is currently being used by Remoting for caching remoting data. If you
- // need to cache data here, talk to the Remoting team to work out a mechanism, so that
- // both caching systems can happily work together.
- private RemotingFieldCachedData m_cachedData;
-
- internal RemotingFieldCachedData RemotingCache
- {
- get
- {
- // This grabs an internal copy of m_cachedData and uses
- // that instead of looking at m_cachedData directly because
- // the cache may get cleared asynchronously. This prevents
- // us from having to take a lock.
- RemotingFieldCachedData cache = m_cachedData;
- if (cache == null)
- {
- cache = new RemotingFieldCachedData(this);
- RemotingFieldCachedData ret = Interlocked.CompareExchange(ref m_cachedData, cache, null);
- if (ret != null)
- cache = ret;
- }
- return cache;
- }
- }
- #endregion
-#endif //FEATURE_REMOTING
-
#region NonPublic Members
internal BindingFlags BindingFlags { get { return m_bindingFlags; } }
private RuntimeType ReflectedTypeInternal
@@ -325,28 +260,27 @@ namespace System.Reflection
public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
{
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
Contract.EndContractBlock();
RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override bool IsDefined(Type attributeType, bool inherit)
{
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
Contract.EndContractBlock();
RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
return CustomAttribute.IsDefined(this, attributeRuntimeType);
}
@@ -362,11 +296,10 @@ namespace System.Reflection
#endregion
#region ISerializable Implementation
- [System.Security.SecurityCritical] // auto-generated
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
MemberInfoSerializationHolder.GetSerializationInfo(
info,
@@ -382,7 +315,6 @@ namespace System.Reflection
internal unsafe sealed class RtFieldInfo : RuntimeFieldInfo, IRuntimeFieldInfo
{
#region FCalls
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static private extern void PerformVisibilityCheckOnField(IntPtr field, Object target, RuntimeType declaringType, FieldAttributes attr, uint invocationFlags);
#endregion
@@ -480,7 +412,6 @@ namespace System.Reflection
private RuntimeAssembly GetRuntimeAssembly() { return m_declaringType.GetRuntimeAssembly(); }
#region Constructor
- [System.Security.SecurityCritical] // auto-generated
internal RtFieldInfo(
RuntimeFieldHandleInternal handle, RuntimeType declaringType, RuntimeTypeCache reflectedTypeCache, BindingFlags bindingFlags)
: base(reflectedTypeCache, declaringType, bindingFlags)
@@ -493,7 +424,6 @@ namespace System.Reflection
#region Private Members
RuntimeFieldHandleInternal IRuntimeFieldInfo.Value
{
- [System.Security.SecuritySafeCritical]
get
{
return new RuntimeFieldHandleInternal(m_fieldHandle);
@@ -535,7 +465,6 @@ namespace System.Reflection
return m.m_fieldHandle == m_fieldHandle;
}
- [System.Security.SecurityCritical]
[DebuggerStepThroughAttribute]
[Diagnostics.DebuggerHidden]
internal void InternalSetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture, ref StackCrawlMark stackMark)
@@ -592,7 +521,6 @@ namespace System.Reflection
// InternalSetValue() instead. When the caller needs to perform
// consistency checks they should call CheckConsistency() before
// calling this method.
- [System.Security.SecurityCritical] // auto-generated
[DebuggerStepThroughAttribute]
[Diagnostics.DebuggerHidden]
internal void UnsafeSetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture)
@@ -614,7 +542,6 @@ namespace System.Reflection
}
}
- [System.Security.SecuritySafeCritical]
[DebuggerStepThroughAttribute]
[Diagnostics.DebuggerHidden]
internal Object InternalGetValue(Object obj, ref StackCrawlMark stackMark)
@@ -657,7 +584,6 @@ namespace System.Reflection
// InternalGetValue() instead. When the caller needs to perform
// consistency checks they should call CheckConsistency() before
// calling this method.
- [System.Security.SecurityCritical]
[DebuggerStepThroughAttribute]
[Diagnostics.DebuggerHidden]
internal Object UnsafeGetValue(Object obj)
@@ -685,7 +611,6 @@ namespace System.Reflection
#region MemberInfo Overrides
public override String Name
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
if (m_name == null)
@@ -705,11 +630,9 @@ namespace System.Reflection
public override int MetadataToken
{
- [System.Security.SecuritySafeCritical] // auto-generated
get { return RuntimeFieldHandle.GetToken(this); }
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal override RuntimeModule GetRuntimeModule()
{
return RuntimeTypeHandle.GetModule(RuntimeFieldHandle.GetApproxDeclaringType(this));
@@ -726,7 +649,6 @@ namespace System.Reflection
public override object GetRawConstantValue() { throw new InvalidOperationException(); }
- [System.Security.SecuritySafeCritical] // auto-generated
[DebuggerStepThroughAttribute]
[Diagnostics.DebuggerHidden]
public override Object GetValueDirect(TypedReference obj)
@@ -742,7 +664,6 @@ namespace System.Reflection
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
[DebuggerStepThroughAttribute]
[Diagnostics.DebuggerHidden]
public override void SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture)
@@ -751,7 +672,6 @@ namespace System.Reflection
InternalSetValue(obj, value, invokeAttr, binder, culture, ref stackMark);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[DebuggerStepThroughAttribute]
[Diagnostics.DebuggerHidden]
public override void SetValueDirect(TypedReference obj, Object value)
@@ -793,7 +713,6 @@ namespace System.Reflection
public override Type FieldType
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
if (m_fieldType == null)
@@ -803,13 +722,11 @@ namespace System.Reflection
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override Type[] GetRequiredCustomModifiers()
{
return new Signature(this, m_declaringType).GetCustomModifiers(1, true);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override Type[] GetOptionalCustomModifiers()
{
return new Signature(this, m_declaringType).GetCustomModifiers(1, false);
@@ -857,7 +774,6 @@ namespace System.Reflection
#region MemberInfo Overrides
public override String Name
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
if (m_name == null)
@@ -902,7 +818,6 @@ namespace System.Reflection
public unsafe override Object GetRawConstantValue() { return GetValue(true); }
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe Object GetValue(bool raw)
{
// Cannot cache these because they could be user defined non-agile enumerations
@@ -924,7 +839,6 @@ namespace System.Reflection
public override Type FieldType
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
if (m_fieldType == null)
diff --git a/src/mscorlib/src/System/Reflection/IntrospectionExtensions.cs b/src/mscorlib/src/System/Reflection/IntrospectionExtensions.cs
index ce2630a908..49819a942f 100644
--- a/src/mscorlib/src/System/Reflection/IntrospectionExtensions.cs
+++ b/src/mscorlib/src/System/Reflection/IntrospectionExtensions.cs
@@ -8,28 +8,21 @@
**
**
**
-** Purpose: go from type to type info
+** Purpose: Get the underlying TypeInfo from a Type
**
**
=============================================================================*/
-
namespace System.Reflection
{
- using System.Reflection;
-
public static class IntrospectionExtensions
{
- public static TypeInfo GetTypeInfo(this Type type){
- if(type == null){
- throw new ArgumentNullException("type");
- }
+ public static TypeInfo GetTypeInfo(this Type type)
+ {
+ if (type == null)
+ throw new ArgumentNullException(nameof(type));
+
var rcType=(IReflectableType)type;
- if(rcType==null){
- return null;
- }else{
- return rcType.GetTypeInfo();
- }
- }
+ return rcType.GetTypeInfo();
+ }
}
}
-
diff --git a/src/mscorlib/src/System/Reflection/InvalidFilterCriteriaException.cs b/src/mscorlib/src/System/Reflection/InvalidFilterCriteriaException.cs
index 7c980da379..fa95e37ad5 100644
--- a/src/mscorlib/src/System/Reflection/InvalidFilterCriteriaException.cs
+++ b/src/mscorlib/src/System/Reflection/InvalidFilterCriteriaException.cs
@@ -19,11 +19,7 @@ namespace System.Reflection {
using ApplicationException = System.ApplicationException;
[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
-#if FEATURE_CORECLR
- public class InvalidFilterCriteriaException : Exception {
-#else
public class InvalidFilterCriteriaException : ApplicationException {
-#endif // FEATURE_CORECLR
public InvalidFilterCriteriaException()
: base(Environment.GetResourceString("Arg_InvalidFilterCriteriaException")) {
SetErrorCode(__HResults.COR_E_INVALIDFILTERCRITERIA);
diff --git a/src/mscorlib/src/System/Reflection/LoaderAllocator.cs b/src/mscorlib/src/System/Reflection/LoaderAllocator.cs
index a8b4b0c3a0..7c6c6bd0e8 100644
--- a/src/mscorlib/src/System/Reflection/LoaderAllocator.cs
+++ b/src/mscorlib/src/System/Reflection/LoaderAllocator.cs
@@ -34,11 +34,9 @@ namespace System.Reflection
internal IntPtr m_nativeLoaderAllocator;
[SuppressUnmanagedCodeSecurity]
- [SecurityCritical]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
private static extern bool Destroy(IntPtr nativeLoaderAllocator);
- [SecuritySafeCritical]
~LoaderAllocatorScout()
{
if (m_nativeLoaderAllocator.IsNull())
diff --git a/src/mscorlib/src/System/Reflection/MdConstant.cs b/src/mscorlib/src/System/Reflection/MdConstant.cs
index 1941736787..e59244f109 100644
--- a/src/mscorlib/src/System/Reflection/MdConstant.cs
+++ b/src/mscorlib/src/System/Reflection/MdConstant.cs
@@ -10,7 +10,6 @@ namespace System.Reflection
internal static class MdConstant
{
- [System.Security.SecurityCritical] // auto-generated
public static unsafe Object GetValue(MetadataImport scope, int token, RuntimeTypeHandle fieldTypeHandle, bool raw)
{
CorElementType corElementType = 0;
diff --git a/src/mscorlib/src/System/Reflection/MdImport.cs b/src/mscorlib/src/System/Reflection/MdImport.cs
index 3bf8eddbcc..bbdf948f99 100644
--- a/src/mscorlib/src/System/Reflection/MdImport.cs
+++ b/src/mscorlib/src/System/Reflection/MdImport.cs
@@ -174,7 +174,6 @@ namespace System.Reflection
public int Length { get { return m_length; } }
public byte this[int index]
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
if (index < 0 || index >= m_length)
@@ -269,7 +268,6 @@ namespace System.Reflection
public int this[int index]
{
- [System.Security.SecurityCritical]
get
{
Contract.Requires(0 <= index && index < Length);
@@ -312,12 +310,10 @@ namespace System.Reflection
#endregion
#region Static Members
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
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);
- [System.Security.SecurityCritical] // auto-generated
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,
@@ -351,56 +347,46 @@ namespace System.Reflection
#endregion
#region FCalls
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute (MethodImplOptions.InternalCall)]
private unsafe static extern void _Enum(IntPtr scope, int type, int parent, out MetadataEnumResult result);
- [System.Security.SecurityCritical] // auto-generated
public unsafe void Enum(MetadataTokenType type, int parent, out MetadataEnumResult result)
{
_Enum(m_metadataImport2, (int)type, parent, out result);
}
- [System.Security.SecurityCritical] // auto-generated
public unsafe void EnumNestedTypes(int mdTypeDef, out MetadataEnumResult result)
{
Enum(MetadataTokenType.TypeDef, mdTypeDef, out result);
}
- [System.Security.SecurityCritical] // auto-generated
public unsafe void EnumCustomAttributes(int mdToken, out MetadataEnumResult result)
{
Enum(MetadataTokenType.CustomAttribute, mdToken, out result);
}
- [System.Security.SecurityCritical] // auto-generated
public unsafe void EnumParams(int mdMethodDef, out MetadataEnumResult result)
{
Enum(MetadataTokenType.ParamDef, mdMethodDef, out result);
}
- [System.Security.SecurityCritical] // auto-generated
public unsafe void EnumFields(int mdTypeDef, out MetadataEnumResult result)
{
Enum(MetadataTokenType.FieldDef, mdTypeDef, out result);
}
- [System.Security.SecurityCritical] // auto-generated
public unsafe void EnumProperties(int mdTypeDef, out MetadataEnumResult result)
{
Enum(MetadataTokenType.Property, mdTypeDef, out result);
}
- [System.Security.SecurityCritical] // auto-generated
public unsafe void EnumEvents(int mdTypeDef, out MetadataEnumResult result)
{
Enum(MetadataTokenType.Event, mdTypeDef, out result);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute (MethodImplOptions.InternalCall)]
private static extern String _GetDefaultValue(IntPtr scope, int mdToken, out long value, out int length, out int corElementType);
- [System.Security.SecurityCritical] // auto-generated
public String GetDefaultValue(int mdToken, out long value, out int length, out CorElementType corElementType)
{
int _corElementType;
@@ -410,10 +396,8 @@ namespace System.Reflection
return stringVal;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute (MethodImplOptions.InternalCall)]
private static unsafe extern void _GetUserString(IntPtr scope, int mdToken, void** name, out int length);
- [System.Security.SecurityCritical] // auto-generated
public unsafe String GetUserString(int mdToken)
{
void* name;
@@ -436,10 +420,8 @@ namespace System.Reflection
return new String(c);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute (MethodImplOptions.InternalCall)]
private static unsafe extern void _GetName(IntPtr scope, int mdToken, void** name);
- [System.Security.SecurityCritical] // auto-generated
public unsafe Utf8String GetName(int mdToken)
{
void* name;
@@ -448,10 +430,8 @@ namespace System.Reflection
return new Utf8String(name);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute (MethodImplOptions.InternalCall)]
private static unsafe extern void _GetNamespace(IntPtr scope, int mdToken, void** namesp);
- [System.Security.SecurityCritical] // auto-generated
public unsafe Utf8String GetNamespace(int mdToken)
{
void* namesp;
@@ -460,10 +440,8 @@ namespace System.Reflection
return new Utf8String(namesp);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute (MethodImplOptions.InternalCall)]
private unsafe static extern void _GetEventProps(IntPtr scope, int mdToken, void** name, out int eventAttributes);
- [System.Security.SecurityCritical] // auto-generated
public unsafe void GetEventProps(int mdToken, out void* name, out EventAttributes eventAttributes)
{
int _eventAttributes;
@@ -473,10 +451,8 @@ namespace System.Reflection
eventAttributes = (EventAttributes)_eventAttributes;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute (MethodImplOptions.InternalCall)]
private static extern void _GetFieldDefProps(IntPtr scope, int mdToken, out int fieldAttributes);
- [System.Security.SecurityCritical] // auto-generated
public void GetFieldDefProps(int mdToken, out FieldAttributes fieldAttributes)
{
int _fieldAttributes;
@@ -484,11 +460,9 @@ namespace System.Reflection
fieldAttributes = (FieldAttributes)_fieldAttributes;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute (MethodImplOptions.InternalCall)]
private unsafe static extern void _GetPropertyProps(IntPtr scope,
int mdToken, void** name, out int propertyAttributes, out ConstArray signature);
- [System.Security.SecurityCritical] // auto-generated
public unsafe void GetPropertyProps(int mdToken, out void* name, out PropertyAttributes propertyAttributes, out ConstArray signature)
{
int _propertyAttributes;
@@ -498,11 +472,9 @@ namespace System.Reflection
propertyAttributes = (PropertyAttributes)_propertyAttributes;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute (MethodImplOptions.InternalCall)]
private static extern void _GetParentToken(IntPtr scope,
int mdToken, out int tkParent);
- [System.Security.SecurityCritical] // auto-generated
public int GetParentToken(int tkToken)
{
int tkParent;
@@ -510,11 +482,9 @@ namespace System.Reflection
return tkParent;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void _GetParamDefProps(IntPtr scope,
int parameterToken, out int sequence, out int attributes);
- [System.Security.SecurityCritical] // auto-generated
public void GetParamDefProps(int parameterToken, out int sequence, out ParameterAttributes attributes)
{
int _attributes;
@@ -524,13 +494,11 @@ namespace System.Reflection
attributes = (ParameterAttributes)_attributes;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void _GetGenericParamProps(IntPtr scope,
int genericParameter,
out int flags);
- [System.Security.SecurityCritical] // auto-generated
public void GetGenericParamProps(
int genericParameter,
out GenericParameterAttributes attributes)
@@ -540,12 +508,10 @@ namespace System.Reflection
attributes = (GenericParameterAttributes)_attributes;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void _GetScopeProps(IntPtr scope,
out Guid mvid);
- [System.Security.SecurityCritical] // auto-generated
public void GetScopeProps(
out Guid mvid)
{
@@ -553,7 +519,6 @@ namespace System.Reflection
}
- [System.Security.SecurityCritical] // auto-generated
public ConstArray GetMethodSignature(MetadataToken token)
{
if (token.IsMemberRef)
@@ -562,13 +527,11 @@ namespace System.Reflection
return GetSigOfMethodDef(token);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void _GetSigOfMethodDef(IntPtr scope,
int methodToken,
ref ConstArray signature);
- [System.Security.SecurityCritical] // auto-generated
public ConstArray GetSigOfMethodDef(int methodToken)
{
ConstArray signature = new ConstArray();
@@ -578,13 +541,11 @@ namespace System.Reflection
return signature;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void _GetSignatureFromToken(IntPtr scope,
int methodToken,
ref ConstArray signature);
- [System.Security.SecurityCritical] // auto-generated
public ConstArray GetSignatureFromToken(int token)
{
ConstArray signature = new ConstArray();
@@ -594,13 +555,11 @@ namespace System.Reflection
return signature;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void _GetMemberRefProps(IntPtr scope,
int memberTokenRef,
out ConstArray signature);
- [System.Security.SecurityCritical] // auto-generated
public ConstArray GetMemberRefProps(int memberTokenRef)
{
ConstArray signature = new ConstArray();
@@ -610,14 +569,12 @@ namespace System.Reflection
return signature;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void _GetCustomAttributeProps(IntPtr scope,
int customAttributeToken,
out int constructorToken,
out ConstArray signature);
- [System.Security.SecurityCritical] // auto-generated
public void GetCustomAttributeProps(
int customAttributeToken,
out int constructorToken,
@@ -627,11 +584,9 @@ namespace System.Reflection
out constructorToken, out signature);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void _GetClassLayout(IntPtr scope,
int typeTokenDef, out int packSize, out int classSize);
- [System.Security.SecurityCritical] // auto-generated
public void GetClassLayout(
int typeTokenDef,
out int packSize,
@@ -640,11 +595,9 @@ namespace System.Reflection
_GetClassLayout(m_metadataImport2, typeTokenDef, out packSize, out classSize);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool _GetFieldOffset(IntPtr scope,
int typeTokenDef, int fieldTokenDef, out int offset);
- [System.Security.SecurityCritical] // auto-generated
public bool GetFieldOffset(
int typeTokenDef,
int fieldTokenDef,
@@ -653,13 +606,11 @@ namespace System.Reflection
return _GetFieldOffset(m_metadataImport2, typeTokenDef, fieldTokenDef, out offset);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void _GetSigOfFieldDef(IntPtr scope,
int fieldToken,
ref ConstArray fieldMarshal);
- [System.Security.SecurityCritical] // auto-generated
public ConstArray GetSigOfFieldDef(int fieldToken)
{
ConstArray fieldMarshal = new ConstArray();
@@ -669,13 +620,11 @@ namespace System.Reflection
return fieldMarshal;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void _GetFieldMarshal(IntPtr scope,
int fieldToken,
ref ConstArray fieldMarshal);
- [System.Security.SecurityCritical] // auto-generated
public ConstArray GetFieldMarshal(int fieldToken)
{
ConstArray fieldMarshal = new ConstArray();
@@ -685,7 +634,6 @@ namespace System.Reflection
return fieldMarshal;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private unsafe static extern void _GetPInvokeMap(IntPtr scope,
int token,
@@ -693,7 +641,6 @@ namespace System.Reflection
void** importName,
void** importDll);
- [System.Security.SecurityCritical] // auto-generated
public unsafe void GetPInvokeMap(
int token,
out PInvokeAttributes attributes,
@@ -709,10 +656,8 @@ namespace System.Reflection
attributes = (PInvokeAttributes)_attributes;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool _IsValidToken(IntPtr scope, int token);
- [System.Security.SecurityCritical] // auto-generated
public bool IsValidToken(int token)
{
return _IsValidToken(m_metadataImport2, token);
diff --git a/src/mscorlib/src/System/Reflection/MemberInfo.cs b/src/mscorlib/src/System/Reflection/MemberInfo.cs
index 248c78bf70..96a89ad37b 100644
--- a/src/mscorlib/src/System/Reflection/MemberInfo.cs
+++ b/src/mscorlib/src/System/Reflection/MemberInfo.cs
@@ -16,9 +16,6 @@ namespace System.Reflection
[Serializable]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_MemberInfo))]
-#pragma warning disable 618
- [PermissionSetAttribute(SecurityAction.InheritanceDemand, Name = "FullTrust")]
-#pragma warning restore 618
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class MemberInfo : ICustomAttributeProvider, _MemberInfo
{
@@ -116,33 +113,5 @@ namespace System.Reflection
{
return base.GetHashCode();
}
-
-#if !FEATURE_CORECLR
- // this method is required so Object.GetType is not made final virtual by the compiler
- Type _MemberInfo.GetType()
- {
- return base.GetType();
- }
-
- void _MemberInfo.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _MemberInfo.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _MemberInfo.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- void _MemberInfo.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
-#endif
}
}
diff --git a/src/mscorlib/src/System/Reflection/MemberInfoSerializationHolder.cs b/src/mscorlib/src/System/Reflection/MemberInfoSerializationHolder.cs
index c1b4ee5fe1..20ff37650c 100644
--- a/src/mscorlib/src/System/Reflection/MemberInfoSerializationHolder.cs
+++ b/src/mscorlib/src/System/Reflection/MemberInfoSerializationHolder.cs
@@ -31,7 +31,7 @@ namespace System.Reflection
Type[] genericArguments)
{
if (info == null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
String assemblyName = reflectedClass.Module.Assembly.FullName;
@@ -65,7 +65,7 @@ namespace System.Reflection
internal MemberInfoSerializationHolder(SerializationInfo info, StreamingContext context)
{
if (info == null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
String assemblyName = info.GetString("AssemblyName");
@@ -86,7 +86,6 @@ namespace System.Reflection
#endregion
#region ISerializable
- [System.Security.SecurityCritical] // auto-generated
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
throw new NotSupportedException(Environment.GetResourceString(ResId.NotSupported_Method));
@@ -94,7 +93,6 @@ namespace System.Reflection
#endregion
#region IObjectReference
- [System.Security.SecurityCritical] // auto-generated
public virtual Object GetRealObject(StreamingContext context)
{
if (m_memberName == null || m_reflectedType == null || m_memberType == 0)
diff --git a/src/mscorlib/src/System/Reflection/Metadata/AssemblyExtensions.cs b/src/mscorlib/src/System/Reflection/Metadata/AssemblyExtensions.cs
index dd5d69b1fb..388e4f475f 100644
--- a/src/mscorlib/src/System/Reflection/Metadata/AssemblyExtensions.cs
+++ b/src/mscorlib/src/System/Reflection/Metadata/AssemblyExtensions.cs
@@ -11,7 +11,6 @@ namespace System.Reflection.Metadata
public static class AssemblyExtensions
{
[DllImport(JitHelpers.QCall)]
- [SecurityCritical] // unsafe method
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private unsafe static extern bool InternalTryGetRawMetadata(RuntimeAssembly assembly, ref byte* blob, ref int length);
@@ -24,12 +23,11 @@ namespace System.Reflection.Metadata
// associated, is alive. The caller is responsible for keeping the assembly object alive while accessing the
// metadata blob.
[CLSCompliant(false)] // out byte* blob
- [SecurityCritical] // unsafe method
public unsafe static bool TryGetRawMetadata(this Assembly assembly, out byte* blob, out int length)
{
if (assembly == null)
{
- throw new ArgumentNullException("assembly");
+ throw new ArgumentNullException(nameof(assembly));
}
blob = null;
diff --git a/src/mscorlib/src/System/Reflection/MethodBase.cs b/src/mscorlib/src/System/Reflection/MethodBase.cs
index 68363bf1e0..644a1ac0b0 100644
--- a/src/mscorlib/src/System/Reflection/MethodBase.cs
+++ b/src/mscorlib/src/System/Reflection/MethodBase.cs
@@ -50,9 +50,6 @@ namespace System.Reflection
[Serializable]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_MethodBase))]
-#pragma warning disable 618
- [PermissionSetAttribute(SecurityAction.InheritanceDemand, Name = "FullTrust")]
-#pragma warning restore 618
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class MethodBase : MemberInfo, _MethodBase
{
@@ -131,7 +128,6 @@ namespace System.Reflection
#region Internal Members
// used by EE
- [System.Security.SecurityCritical]
private IntPtr GetMethodDesc() { return MethodHandle.Value; }
#if FEATURE_APPX
@@ -243,7 +239,6 @@ namespace System.Reflection
}
}
- [System.Security.SecuritySafeCritical]
#pragma warning disable 618
[ReflectionPermissionAttribute(SecurityAction.Demand, Flags=ReflectionPermissionFlag.MemberAccess)]
#pragma warning restore 618
@@ -329,7 +324,6 @@ namespace System.Reflection
return parameterTypes;
}
- [System.Security.SecuritySafeCritical]
internal Object[] CheckArguments(Object[] parameters, Binder binder,
BindingFlags invokeAttr, CultureInfo culture, Signature sig)
{
@@ -347,7 +341,7 @@ namespace System.Reflection
if (p == null)
p = GetParametersNoCopy();
if (p[i].DefaultValue == System.DBNull.Value)
- throw new ArgumentException(Environment.GetResourceString("Arg_VarMissNull"),"parameters");
+ throw new ArgumentException(Environment.GetResourceString("Arg_VarMissNull"),nameof(parameters));
arg = p[i].DefaultValue;
}
copyOfParameters[i] = argRT.CheckValue(arg, binder, culture, invokeAttr);
@@ -356,47 +350,5 @@ namespace System.Reflection
return copyOfParameters;
}
#endregion
-
- #region _MethodBase Implementation
-#if !FEATURE_CORECLR
- Type _MethodBase.GetType() { return base.GetType(); }
- bool _MethodBase.IsPublic { get { return IsPublic; } }
- bool _MethodBase.IsPrivate { get { return IsPrivate; } }
- bool _MethodBase.IsFamily { get { return IsFamily; } }
- bool _MethodBase.IsAssembly { get { return IsAssembly; } }
- bool _MethodBase.IsFamilyAndAssembly { get { return IsFamilyAndAssembly; } }
- bool _MethodBase.IsFamilyOrAssembly { get { return IsFamilyOrAssembly; } }
- bool _MethodBase.IsStatic { get { return IsStatic; } }
- bool _MethodBase.IsFinal { get { return IsFinal; } }
- bool _MethodBase.IsVirtual { get { return IsVirtual; } }
- bool _MethodBase.IsHideBySig { get { return IsHideBySig; } }
- bool _MethodBase.IsAbstract { get { return IsAbstract; } }
- bool _MethodBase.IsSpecialName { get { return IsSpecialName; } }
- bool _MethodBase.IsConstructor { get { return IsConstructor; } }
-
- void _MethodBase.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _MethodBase.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _MethodBase.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- // If you implement this method, make sure to include _MethodBase.Invoke in VM\DangerousAPIs.h and
- // include _MethodBase in SystemDomain::IsReflectionInvocationMethod in AppDomain.cpp.
- void _MethodBase.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
-#endif
- #endregion
}
-
}
diff --git a/src/mscorlib/src/System/Reflection/MethodBody.cs b/src/mscorlib/src/System/Reflection/MethodBody.cs
index 81d7a9ea0e..4634623e26 100644
--- a/src/mscorlib/src/System/Reflection/MethodBody.cs
+++ b/src/mscorlib/src/System/Reflection/MethodBody.cs
@@ -7,6 +7,7 @@
using System;
using System.Globalization;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
namespace System.Reflection
@@ -160,7 +161,7 @@ namespace System.Reflection
#endregion
#region Public Members
- public virtual Type LocalType { get { Contract.Assert(m_type != null, "type must be set!"); return m_type; } }
+ 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/MethodInfo.cs b/src/mscorlib/src/System/Reflection/MethodInfo.cs
index eeb5a815a4..39387b1f8f 100644
--- a/src/mscorlib/src/System/Reflection/MethodInfo.cs
+++ b/src/mscorlib/src/System/Reflection/MethodInfo.cs
@@ -14,9 +14,6 @@ namespace System.Reflection
using System.Runtime;
using System.Runtime.InteropServices;
using System.Runtime.ConstrainedExecution;
-#if FEATURE_REMOTING
- using System.Runtime.Remoting.Metadata;
-#endif //FEATURE_REMOTING
using System.Runtime.Serialization;
using System.Security;
using System.Security.Permissions;
@@ -29,9 +26,6 @@ namespace System.Reflection
[Serializable]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_MethodInfo))]
-#pragma warning disable 618
- [PermissionSetAttribute(SecurityAction.InheritanceDemand, Name = "FullTrust")]
-#pragma warning restore 618
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class MethodInfo : MethodBase, _MethodInfo
{
@@ -91,35 +85,6 @@ namespace System.Reflection
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
-
-#if !FEATURE_CORECLR
- Type _MethodInfo.GetType()
- {
- return base.GetType();
- }
-
- void _MethodInfo.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _MethodInfo.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _MethodInfo.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- // If you implement this method, make sure to include _MethodInfo.Invoke in VM\DangerousAPIs.h and
- // include _MethodInfo in SystemDomain::IsReflectionInvocationMethod in AppDomain.cpp.
- void _MethodInfo.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
-#endif
}
[Serializable]
@@ -180,7 +145,6 @@ namespace System.Reflection
internal INVOCATION_FLAGS InvocationFlags
{
- [System.Security.SecuritySafeCritical]
get
{
if ((m_invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED) == 0)
@@ -243,15 +207,14 @@ namespace System.Reflection
#endregion
#region Constructor
- [System.Security.SecurityCritical] // auto-generated
internal RuntimeMethodInfo(
RuntimeMethodHandleInternal handle, RuntimeType declaringType,
RuntimeTypeCache reflectedTypeCache, MethodAttributes methodAttributes, BindingFlags bindingFlags, object keepalive)
{
Contract.Ensures(!m_handle.IsNull());
- Contract.Assert(!handle.IsNullHandle());
- Contract.Assert(methodAttributes == RuntimeMethodHandle.GetAttributes(handle));
+ Debug.Assert(!handle.IsNullHandle());
+ Debug.Assert(methodAttributes == RuntimeMethodHandle.GetAttributes(handle));
m_bindingFlags = bindingFlags;
m_declaringType = declaringType;
@@ -262,40 +225,9 @@ namespace System.Reflection
}
#endregion
-#if FEATURE_REMOTING
- #region Legacy Remoting Cache
- // The size of CachedData is accounted for by BaseObjectWithCachedData in object.h.
- // This member is currently being used by Remoting for caching remoting data. If you
- // need to cache data here, talk to the Remoting team to work out a mechanism, so that
- // both caching systems can happily work together.
- private RemotingMethodCachedData m_cachedData;
-
- internal RemotingMethodCachedData RemotingCache
- {
- get
- {
- // This grabs an internal copy of m_cachedData and uses
- // that instead of looking at m_cachedData directly because
- // the cache may get cleared asynchronously. This prevents
- // us from having to take a lock.
- RemotingMethodCachedData cache = m_cachedData;
- if (cache == null)
- {
- cache = new RemotingMethodCachedData(this);
- RemotingMethodCachedData ret = Interlocked.CompareExchange(ref m_cachedData, cache, null);
- if (ret != null)
- cache = ret;
- }
- return cache;
- }
- }
- #endregion
-#endif //FEATURE_REMOTING
-
#region Private Methods
RuntimeMethodHandleInternal IRuntimeMethodInfo.Value
{
- [System.Security.SecuritySafeCritical]
get
{
return new RuntimeMethodHandleInternal(m_handle);
@@ -310,7 +242,6 @@ namespace System.Reflection
}
}
- [System.Security.SecurityCritical] // auto-generated
private ParameterInfo[] FetchNonReturnParameters()
{
if (m_parameters == null)
@@ -319,7 +250,6 @@ namespace System.Reflection
return m_parameters;
}
- [System.Security.SecurityCritical] // auto-generated
private ParameterInfo FetchReturnParameter()
{
if (m_returnParameter == null)
@@ -379,7 +309,6 @@ namespace System.Reflection
return new RuntimeMethodHandle(this);
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal RuntimeMethodInfo GetParentDefinition()
{
if (!IsVirtual || m_declaringType.IsInterface)
@@ -424,7 +353,6 @@ namespace System.Reflection
return base.GetHashCode();
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override bool Equals(object obj)
{
if (!IsGenericMethod)
@@ -469,23 +397,21 @@ namespace System.Reflection
#endregion
#region ICustomAttributeProvider
- [System.Security.SecuritySafeCritical] // auto-generated
public override Object[] GetCustomAttributes(bool inherit)
{
return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType as RuntimeType, inherit);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
{
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
Contract.EndContractBlock();
RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType, inherit);
}
@@ -493,13 +419,13 @@ namespace System.Reflection
public override bool IsDefined(Type attributeType, bool inherit)
{
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
Contract.EndContractBlock();
RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
return CustomAttribute.IsDefined(this, attributeRuntimeType, inherit);
}
@@ -513,7 +439,6 @@ namespace System.Reflection
#region MemberInfo Overrides
public override String Name
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
if (m_name == null)
@@ -548,7 +473,6 @@ namespace System.Reflection
public override MemberTypes MemberType { get { return MemberTypes.Method; } }
public override int MetadataToken
{
- [System.Security.SecuritySafeCritical] // auto-generated
get { return RuntimeMethodHandle.GetMethodDef(this); }
}
public override Module Module { get { return GetRuntimeModule(); } }
@@ -558,20 +482,19 @@ namespace System.Reflection
public override bool IsSecurityCritical
{
- get { return RuntimeMethodHandle.IsSecurityCritical(this); }
+ get { return true; }
}
public override bool IsSecuritySafeCritical
{
- get { return RuntimeMethodHandle.IsSecuritySafeCritical(this); }
+ get { return false; }
}
public override bool IsSecurityTransparent
{
- get { return RuntimeMethodHandle.IsSecurityTransparent(this); }
+ get { return false; }
}
- #endregion
+#endregion
- #region MethodBase Overrides
- [System.Security.SecuritySafeCritical] // auto-generated
+#region MethodBase Overrides
internal override ParameterInfo[] GetParametersNoCopy()
{
FetchNonReturnParameters();
@@ -579,7 +502,6 @@ namespace System.Reflection
return m_parameters;
}
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Diagnostics.Contracts.Pure]
public override ParameterInfo[] GetParameters()
{
@@ -629,12 +551,6 @@ namespace System.Reflection
}
}
- [System.Security.SecuritySafeCritical] // overrides SafeCritical member
-#if !FEATURE_CORECLR
-#pragma warning disable 618
- [ReflectionPermissionAttribute(SecurityAction.Demand, Flags = ReflectionPermissionFlag.MemberAccess)]
-#pragma warning restore 618
-#endif
public override MethodBody GetMethodBody()
{
MethodBody mb = RuntimeMethodHandle.GetMethodBody(this, ReflectedTypeInternal);
@@ -642,9 +558,9 @@ namespace System.Reflection
mb.m_methodBase = this;
return mb;
}
- #endregion
+#endregion
- #region Invocation Logic(On MemberBase)
+#region Invocation Logic(On MemberBase)
private void CheckConsistency(Object target)
{
// only test instance methods
@@ -660,7 +576,6 @@ namespace System.Reflection
}
}
- [System.Security.SecuritySafeCritical]
private void ThrowNoInvokeException()
{
// method is ReflectionOnly
@@ -698,7 +613,6 @@ namespace System.Reflection
throw new TargetException();
}
- [System.Security.SecuritySafeCritical]
[DebuggerStepThroughAttribute]
[Diagnostics.DebuggerHidden]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
@@ -706,7 +620,7 @@ namespace System.Reflection
{
object[] arguments = InvokeArgumentsCheck(obj, invokeAttr, binder, parameters, culture);
- #region Security Check
+#region Security Check
INVOCATION_FLAGS invocationFlags = InvocationFlags;
#if FEATURE_APPX
@@ -718,23 +632,11 @@ namespace System.Reflection
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", FullName));
}
#endif
-
-#if !FEATURE_CORECLR
- if ((invocationFlags & (INVOCATION_FLAGS.INVOCATION_FLAGS_RISKY_METHOD | INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY)) != 0)
- {
- if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_RISKY_METHOD) != 0)
- CodeAccessPermission.Demand(PermissionType.ReflectionMemberAccess);
-
- if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY) != 0)
- RuntimeMethodHandle.PerformSecurityCheck(obj, this, m_declaringType, (uint)m_invocationFlags);
- }
-#endif // !FEATURE_CORECLR
- #endregion
+#endregion
return UnsafeInvokeInternal(obj, parameters, arguments);
}
- [System.Security.SecurityCritical]
[DebuggerStepThroughAttribute]
[Diagnostics.DebuggerHidden]
internal object UnsafeInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
@@ -744,7 +646,6 @@ namespace System.Reflection
return UnsafeInvokeInternal(obj, parameters, arguments);
}
- [System.Security.SecurityCritical]
[DebuggerStepThroughAttribute]
[Diagnostics.DebuggerHidden]
private object UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
@@ -793,9 +694,9 @@ namespace System.Reflection
return null;
}
- #endregion
+#endregion
- #region MethodInfo Overrides
+#region MethodInfo Overrides
public override Type ReturnType
{
get { return Signature.ReturnType; }
@@ -808,7 +709,6 @@ namespace System.Reflection
public override ParameterInfo ReturnParameter
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
Contract.Ensures(m_returnParameter != null);
@@ -818,7 +718,6 @@ namespace System.Reflection
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override MethodInfo GetBaseDefinition()
{
if (!IsVirtual || IsStatic || m_declaringType == null || m_declaringType.IsInterface)
@@ -844,7 +743,6 @@ namespace System.Reflection
return(MethodInfo)RuntimeType.GetMethodBase(baseDeclaringType, baseMethodHandle);
}
- [System.Security.SecuritySafeCritical]
public override Delegate CreateDelegate(Type delegateType)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -864,7 +762,6 @@ namespace System.Reflection
ref stackMark);
}
- [System.Security.SecuritySafeCritical]
public override Delegate CreateDelegate(Type delegateType, Object target)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -881,20 +778,19 @@ namespace System.Reflection
ref stackMark);
}
- [System.Security.SecurityCritical]
private Delegate CreateDelegateInternal(Type delegateType, Object firstArgument, DelegateBindingFlags bindingFlags, ref StackCrawlMark stackMark)
{
// Validate the parameters.
if (delegateType == null)
- throw new ArgumentNullException("delegateType");
+ throw new ArgumentNullException(nameof(delegateType));
Contract.EndContractBlock();
RuntimeType rtType = delegateType as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "delegateType");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), nameof(delegateType));
if (!rtType.IsDelegate())
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"), "delegateType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"), nameof(delegateType));
Delegate d = Delegate.CreateDelegateInternal(rtType, this, firstArgument, bindingFlags, ref stackMark);
if (d == null)
@@ -905,14 +801,13 @@ namespace System.Reflection
return d;
}
- #endregion
+#endregion
- #region Generics
- [System.Security.SecuritySafeCritical] // auto-generated
+#region Generics
public override MethodInfo MakeGenericMethod(params Type[] methodInstantiation)
{
if (methodInstantiation == null)
- throw new ArgumentNullException("methodInstantiation");
+ throw new ArgumentNullException(nameof(methodInstantiation));
Contract.EndContractBlock();
RuntimeType[] methodInstantionRuntimeType = new RuntimeType[methodInstantiation.Length];
@@ -1017,14 +912,13 @@ namespace System.Reflection
return false;
}
}
- #endregion
+#endregion
- #region ISerializable Implementation
- [System.Security.SecurityCritical] // auto-generated
+#region ISerializable Implementation
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
if (m_reflectedTypeCache.IsGlobal)
@@ -1044,9 +938,9 @@ namespace System.Reflection
{
return ReturnType.FormatTypeName(true) + " " + FormatNameAndSig(true);
}
- #endregion
+#endregion
- #region Legacy Internal
+#region Legacy Internal
internal static MethodBase InternalGetCurrentMethod(ref StackCrawlMark stackMark)
{
IRuntimeMethodInfo method = RuntimeMethodHandle.GetCurrentMethod(ref stackMark);
@@ -1056,6 +950,6 @@ namespace System.Reflection
return RuntimeType.GetMethodBase(method);
}
- #endregion
+#endregion
}
}
diff --git a/src/mscorlib/src/System/Reflection/Missing.cs b/src/mscorlib/src/System/Reflection/Missing.cs
index 8289193191..24bf77bd4e 100644
--- a/src/mscorlib/src/System/Reflection/Missing.cs
+++ b/src/mscorlib/src/System/Reflection/Missing.cs
@@ -24,11 +24,10 @@ namespace System.Reflection
#endregion
#region ISerializable
- [System.Security.SecurityCritical] // auto-generated_required
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
UnitySerializationHolder.GetUnitySerializationInfo(info, this);
diff --git a/src/mscorlib/src/System/Reflection/Module.cs b/src/mscorlib/src/System/Reflection/Module.cs
index 34705a4211..b6be38e434 100644
--- a/src/mscorlib/src/System/Reflection/Module.cs
+++ b/src/mscorlib/src/System/Reflection/Module.cs
@@ -59,9 +59,6 @@ namespace System.Reflection
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_Module))]
[System.Runtime.InteropServices.ComVisible(true)]
-#pragma warning disable 618
- [PermissionSetAttribute(SecurityAction.InheritanceDemand, Unrestricted = true)]
-#pragma warning restore 618
public abstract class Module : _Module, ISerializable, ICustomAttributeProvider
{
#region Static Constructor
@@ -274,7 +271,6 @@ namespace System.Reflection
}
}
- [System.Security.SecurityCritical] // auto-generated_required
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
throw new NotImplementedException();
@@ -299,9 +295,6 @@ namespace System.Reflection
public virtual String FullyQualifiedName
{
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
get
{
throw new NotImplementedException();
@@ -432,16 +425,16 @@ namespace System.Reflection
String name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (types == null)
- throw new ArgumentNullException("types");
+ throw new ArgumentNullException(nameof(types));
Contract.EndContractBlock();
for (int i = 0; i < types.Length; i++)
{
if (types[i] == null)
- throw new ArgumentNullException("types");
+ throw new ArgumentNullException(nameof(types));
}
return GetMethodImpl(name, bindingAttr, binder, callConvention, types, modifiers);
@@ -450,16 +443,16 @@ namespace System.Reflection
public MethodInfo GetMethod(String name, Type[] types)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (types == null)
- throw new ArgumentNullException("types");
+ throw new ArgumentNullException(nameof(types));
Contract.EndContractBlock();
for (int i = 0; i < types.Length; i++)
{
if (types[i] == null)
- throw new ArgumentNullException("types");
+ throw new ArgumentNullException(nameof(types));
}
return GetMethodImpl(name, Module.DefaultLookup, null, CallingConventions.Any, types, null);
@@ -468,7 +461,7 @@ namespace System.Reflection
public MethodInfo GetMethod(String name)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
Contract.EndContractBlock();
return GetMethodImpl(name, Module.DefaultLookup, null, CallingConventions.Any,
@@ -543,36 +536,7 @@ namespace System.Reflection
{
return ModuleHandle.EmptyHandle;
}
-
-#if FEATURE_X509 && FEATURE_CAS_POLICY
- public virtual System.Security.Cryptography.X509Certificates.X509Certificate GetSignerCertificate()
- {
- throw new NotImplementedException();
- }
-#endif // FEATURE_X509 && FEATURE_CAS_POLICY
#endregion
-
-#if !FEATURE_CORECLR
- void _Module.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _Module.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _Module.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- void _Module.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
-#endif
}
[Serializable]
@@ -581,46 +545,32 @@ namespace System.Reflection
internal RuntimeModule() { throw new NotSupportedException(); }
#region FCalls
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void GetType(RuntimeModule module, String className, bool ignoreCase, bool throwOnError, ObjectHandleOnStack type, ObjectHandleOnStack keepAlive);
- [System.Security.SecurityCritical]
[DllImport(JitHelpers.QCall)]
[SuppressUnmanagedCodeSecurity]
private static extern bool nIsTransientInternal(RuntimeModule module);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void GetScopeName(RuntimeModule module, StringHandleOnStack retString);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void GetFullyQualifiedName(RuntimeModule module, StringHandleOnStack retString);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern static RuntimeType[] GetTypes(RuntimeModule module);
- [System.Security.SecuritySafeCritical] // auto-generated
internal RuntimeType[] GetDefinedTypes()
{
return GetTypes(GetNativeHandle());
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern static bool IsResource(RuntimeModule module);
-
-#if FEATURE_X509 && FEATURE_CAS_POLICY
- [System.Security.SecurityCritical] // auto-generated
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- static private extern void GetSignerCertificate(RuntimeModule module, ObjectHandleOnStack retData);
-#endif // FEATURE_X509 && FEATURE_CAS_POLICY
#endregion
#region Module overrides
@@ -646,18 +596,17 @@ namespace System.Reflection
return typeHandleArgs;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override byte[] ResolveSignature(int metadataToken)
{
MetadataToken tk = new MetadataToken(metadataToken);
if (!MetadataImport.IsValidToken(tk))
- throw new ArgumentOutOfRangeException("metadataToken",
+ 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),
- "metadataToken");
+ nameof(metadataToken));
ConstArray signature;
if (tk.IsMemberRef)
@@ -673,13 +622,12 @@ namespace System.Reflection
return sig;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override MethodBase ResolveMethod(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
{
MetadataToken tk = new MetadataToken(metadataToken);
if (!MetadataImport.IsValidToken(tk))
- throw new ArgumentOutOfRangeException("metadataToken",
+ throw new ArgumentOutOfRangeException(nameof(metadataToken),
Environment.GetResourceString("Argument_InvalidToken", tk, this));
RuntimeTypeHandle[] typeArgs = ConvertToTypeHandleArray(genericTypeArguments);
@@ -690,16 +638,16 @@ namespace System.Reflection
if (!tk.IsMethodDef && !tk.IsMethodSpec)
{
if (!tk.IsMemberRef)
- throw new ArgumentException("metadataToken",
- Environment.GetResourceString("Argument_ResolveMethod", tk, this));
+ 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("metadataToken",
- Environment.GetResourceString("Argument_ResolveMethod", tk, this));
+ throw new ArgumentException(Environment.GetResourceString("Argument_ResolveMethod", tk, this),
+ nameof(metadataToken));
}
}
@@ -724,13 +672,12 @@ namespace System.Reflection
}
}
- [System.Security.SecurityCritical] // auto-generated
private FieldInfo ResolveLiteralField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
{
MetadataToken tk = new MetadataToken(metadataToken);
if (!MetadataImport.IsValidToken(tk) || !tk.IsFieldDef)
- throw new ArgumentOutOfRangeException("metadataToken",
+ throw new ArgumentOutOfRangeException(nameof(metadataToken),
String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Argument_InvalidToken", tk, this)));
int tkDeclaringType;
@@ -752,17 +699,16 @@ namespace System.Reflection
}
catch
{
- throw new ArgumentException(Environment.GetResourceString("Argument_ResolveField", tk, this), "metadataToken");
+ throw new ArgumentException(Environment.GetResourceString("Argument_ResolveField", tk, this), nameof(metadataToken));
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override FieldInfo ResolveField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
{
MetadataToken tk = new MetadataToken(metadataToken);
if (!MetadataImport.IsValidToken(tk))
- throw new ArgumentOutOfRangeException("metadataToken",
+ throw new ArgumentOutOfRangeException(nameof(metadataToken),
Environment.GetResourceString("Argument_InvalidToken", tk, this));
RuntimeTypeHandle[] typeArgs = ConvertToTypeHandleArray(genericTypeArguments);
@@ -775,16 +721,16 @@ namespace System.Reflection
if (!tk.IsFieldDef)
{
if (!tk.IsMemberRef)
- throw new ArgumentException("metadataToken",
- Environment.GetResourceString("Argument_ResolveField", tk, this));
+ 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("metadataToken",
- Environment.GetResourceString("Argument_ResolveField", tk, this));
+ throw new ArgumentException(Environment.GetResourceString("Argument_ResolveField", tk, this),
+ nameof(metadataToken));
}
fieldHandle = ModuleHandle.ResolveFieldHandleInternal(GetNativeHandle(), tk, typeArgs, methodArgs);
@@ -811,20 +757,19 @@ namespace System.Reflection
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
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), "metadataToken");
+ throw new ArgumentException(Environment.GetResourceString("Argument_ResolveModuleType", tk), nameof(metadataToken));
if (!MetadataImport.IsValidToken(tk))
- throw new ArgumentOutOfRangeException("metadataToken",
+ 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), "metadataToken");
+ throw new ArgumentException(Environment.GetResourceString("Argument_ResolveType", tk, this), nameof(metadataToken));
RuntimeTypeHandle[] typeArgs = ConvertToTypeHandleArray(genericTypeArguments);
RuntimeTypeHandle[] methodArgs = ConvertToTypeHandleArray(genericMethodArguments);
@@ -834,7 +779,7 @@ namespace System.Reflection
Type t = GetModuleHandle().ResolveTypeHandle(metadataToken, typeArgs, methodArgs).GetRuntimeType();
if (t == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_ResolveType", tk, this), "metadataToken");
+ throw new ArgumentException(Environment.GetResourceString("Argument_ResolveType", tk, this), nameof(metadataToken));
return t;
}
@@ -844,7 +789,6 @@ namespace System.Reflection
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override MemberInfo ResolveMember(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
{
MetadataToken tk = new MetadataToken(metadataToken);
@@ -867,7 +811,7 @@ namespace System.Reflection
if (tk.IsMemberRef)
{
if (!MetadataImport.IsValidToken(tk))
- throw new ArgumentOutOfRangeException("metadataToken",
+ throw new ArgumentOutOfRangeException(nameof(metadataToken),
Environment.GetResourceString("Argument_InvalidToken", tk, this));
ConstArray sig = MetadataImport.GetMemberRefProps(tk);
@@ -885,11 +829,10 @@ namespace System.Reflection
}
}
- throw new ArgumentException("metadataToken",
- Environment.GetResourceString("Argument_ResolveMember", tk, this));
+ throw new ArgumentException(Environment.GetResourceString("Argument_ResolveMember", tk, this),
+ nameof(metadataToken));
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override string ResolveString(int metadataToken)
{
MetadataToken tk = new MetadataToken(metadataToken);
@@ -898,7 +841,7 @@ namespace System.Reflection
String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Argument_ResolveString"), metadataToken, ToString()));
if (!MetadataImport.IsValidToken(tk))
- throw new ArgumentOutOfRangeException("metadataToken",
+ throw new ArgumentOutOfRangeException(nameof(metadataToken),
String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Argument_InvalidToken", tk, this)));
string str = MetadataImport.GetUserString(metadataToken);
@@ -917,7 +860,6 @@ namespace System.Reflection
public override int MDStreamVersion
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
return ModuleHandle.GetMDStreamVersion(GetNativeHandle());
@@ -973,7 +915,6 @@ namespace System.Reflection
}
}
- [System.Security.SecuritySafeCritical]
internal bool IsTransientInternal()
{
return RuntimeModule.nIsTransientInternal(this.GetNativeHandle());
@@ -981,7 +922,6 @@ namespace System.Reflection
internal MetadataImport MetadataImport
{
- [System.Security.SecurityCritical] // auto-generated
get
{
unsafe
@@ -1001,28 +941,27 @@ namespace System.Reflection
public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
{
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
Contract.EndContractBlock();
RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override bool IsDefined(Type attributeType, bool inherit)
{
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
Contract.EndContractBlock();
RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
return CustomAttribute.IsDefined(this, attributeRuntimeType);
}
@@ -1034,24 +973,22 @@ namespace System.Reflection
#endregion
#region Public Virtuals
- [System.Security.SecurityCritical] // auto-generated_required
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
{
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
UnitySerializationHolder.GetUnitySerializationInfo(info, UnitySerializationHolder.ModuleUnity, this.ScopeName, this.GetRuntimeAssembly());
}
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(true)]
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("className");
+ throw new ArgumentNullException(nameof(className));
RuntimeType retType = null;
Object keepAlive = null;
@@ -1060,7 +997,6 @@ namespace System.Reflection
return retType;
}
- [System.Security.SecurityCritical] // auto-generated
internal string GetFullyQualifiedName()
{
String fullyQualifiedName = null;
@@ -1070,11 +1006,6 @@ namespace System.Reflection
public override String FullyQualifiedName
{
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#else
- [System.Security.SecuritySafeCritical]
-#endif
get
{
String fullyQualifiedName = GetFullyQualifiedName();
@@ -1082,7 +1013,7 @@ namespace System.Reflection
if (fullyQualifiedName != null) {
bool checkPermission = true;
try {
- Path.GetFullPathInternal(fullyQualifiedName);
+ Path.GetFullPath(fullyQualifiedName);
}
catch(ArgumentException) {
checkPermission = false;
@@ -1096,7 +1027,6 @@ namespace System.Reflection
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override Type[] GetTypes()
{
return GetTypes(GetNativeHandle());
@@ -1108,7 +1038,6 @@ namespace System.Reflection
public override Guid ModuleVersionId
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
unsafe
@@ -1122,7 +1051,6 @@ namespace System.Reflection
public override int MetadataToken
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
return ModuleHandle.GetToken(GetNativeHandle());
@@ -1145,7 +1073,7 @@ namespace System.Reflection
public override FieldInfo GetField(String name, BindingFlags bindingAttr)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (RuntimeType == null)
return null;
@@ -1163,7 +1091,6 @@ namespace System.Reflection
public override String ScopeName
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
string scopeName = null;
@@ -1174,7 +1101,6 @@ namespace System.Reflection
public override String Name
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
String s = GetFullyQualifiedName();
@@ -1215,16 +1141,6 @@ namespace System.Reflection
{
return this;
}
-
-#if FEATURE_X509 && FEATURE_CAS_POLICY
- [System.Security.SecuritySafeCritical] // auto-generated
- public override System.Security.Cryptography.X509Certificates.X509Certificate GetSignerCertificate()
- {
- byte[] data = null;
- GetSignerCertificate(GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref data));
- return (data != null) ? new System.Security.Cryptography.X509Certificates.X509Certificate(data) : null;
- }
-#endif // FEATURE_X509 && FEATURE_CAS_POLICY
#endregion
}
}
diff --git a/src/mscorlib/src/System/Reflection/ParameterInfo.cs b/src/mscorlib/src/System/Reflection/ParameterInfo.cs
index 63c6330b0a..6592e5aa20 100644
--- a/src/mscorlib/src/System/Reflection/ParameterInfo.cs
+++ b/src/mscorlib/src/System/Reflection/ParameterInfo.cs
@@ -8,13 +8,11 @@ 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;
-#if FEATURE_REMOTING
- using System.Runtime.Remoting.Metadata;
-#endif //FEATURE_REMOTING
using System.Security.Permissions;
using System.Threading;
using MdToken = System.Reflection.MetadataToken;
@@ -157,7 +155,7 @@ namespace System.Reflection
public virtual Object[] GetCustomAttributes(Type attributeType, bool inherit)
{
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
Contract.EndContractBlock();
return EmptyArray<Object>.Value;
@@ -166,7 +164,7 @@ namespace System.Reflection
public virtual bool IsDefined(Type attributeType, bool inherit)
{
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
Contract.EndContractBlock();
return false;
@@ -180,35 +178,12 @@ namespace System.Reflection
#region _ParameterInfo implementation
-#if !FEATURE_CORECLR
- void _ParameterInfo.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _ParameterInfo.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _ParameterInfo.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- void _ParameterInfo.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
-#endif
-
#endregion
#region IObjectReference
// In V4 RuntimeParameterInfo is introduced.
// To support deserializing ParameterInfo instances serialized in earlier versions
// we need to implement IObjectReference.
- [System.Security.SecurityCritical]
public object GetRealObject(StreamingContext context)
{
Contract.Ensures(Contract.Result<Object>() != null);
@@ -261,26 +236,23 @@ namespace System.Reflection
internal unsafe sealed class RuntimeParameterInfo : ParameterInfo, ISerializable
{
#region Static Members
- [System.Security.SecurityCritical] // auto-generated
internal unsafe static ParameterInfo[] GetParameters(IRuntimeMethodInfo method, MemberInfo member, Signature sig)
{
- Contract.Assert(method is RuntimeMethodInfo || method is RuntimeConstructorInfo);
+ Debug.Assert(method is RuntimeMethodInfo || method is RuntimeConstructorInfo);
ParameterInfo dummy;
return GetParameters(method, member, sig, out dummy, false);
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe static ParameterInfo GetReturnParameter(IRuntimeMethodInfo method, MemberInfo member, Signature sig)
{
- Contract.Assert(method is RuntimeMethodInfo || method is RuntimeConstructorInfo);
+ Debug.Assert(method is RuntimeMethodInfo || method is RuntimeConstructorInfo);
ParameterInfo returnParameter;
GetParameters(method, member, sig, out returnParameter, true);
return returnParameter;
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe static ParameterInfo[] GetParameters(
IRuntimeMethodInfo methodHandle, MemberInfo member, Signature sig, out ParameterInfo returnParameter, bool fetchReturnParameter)
{
@@ -392,18 +364,17 @@ namespace System.Reflection
get
{
MethodBase result = m_originalMember != null ? m_originalMember : MemberImpl as MethodBase;
- Contract.Assert(result != null);
+ Debug.Assert(result != null);
return result;
}
}
#endregion
#region VTS magic to serialize/deserialized to/from pre-Whidbey endpoints.
- [System.Security.SecurityCritical]
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// We could be serializing for consumption by a pre-Whidbey
@@ -450,7 +421,7 @@ namespace System.Reflection
// 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;
- Contract.Assert(m_originalMember != null);
+ Debug.Assert(m_originalMember != null);
// Populate all the caches -- we inherit this behavior from RTM
NameImpl = accessor.Name;
@@ -470,8 +441,8 @@ namespace System.Reflection
int position, ParameterAttributes attributes, MemberInfo member)
{
Contract.Requires(member != null);
- Contract.Assert(MdToken.IsNullToken(tkParamDef) == scope.Equals(MetadataImport.EmptyImport));
- Contract.Assert(MdToken.IsNullToken(tkParamDef) || MdToken.IsTokenOfType(tkParamDef, MetadataTokenType.ParamDef));
+ Debug.Assert(MdToken.IsNullToken(tkParamDef) == scope.Equals(MetadataImport.EmptyImport));
+ Debug.Assert(MdToken.IsNullToken(tkParamDef) || MdToken.IsTokenOfType(tkParamDef, MetadataTokenType.ParamDef));
PositionImpl = position;
MemberImpl = member;
@@ -513,7 +484,7 @@ namespace System.Reflection
else
parameterType = m_signature.Arguments[PositionImpl];
- Contract.Assert(parameterType != null);
+ 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;
}
@@ -524,7 +495,6 @@ namespace System.Reflection
public override String Name
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
if (!m_nameIsCached)
@@ -588,10 +558,9 @@ namespace System.Reflection
}
// returns DBNull.Value if the parameter doesn't have a default value
- [System.Security.SecuritySafeCritical]
private Object GetDefaultValueInternal(bool raw)
{
- Contract.Assert(!m_noMetadata);
+ Debug.Assert(!m_noMetadata);
if (m_noDefaultValue)
return DBNull.Value;
@@ -728,7 +697,7 @@ namespace System.Reflection
public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
{
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
Contract.EndContractBlock();
if (MdToken.IsNullToken(m_tkParamDef))
@@ -737,16 +706,15 @@ namespace System.Reflection
RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "attributeType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(attributeType));
return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override bool IsDefined(Type attributeType, bool inherit)
{
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
Contract.EndContractBlock();
if (MdToken.IsNullToken(m_tkParamDef))
@@ -755,7 +723,7 @@ namespace System.Reflection
RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "attributeType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(attributeType));
return CustomAttribute.IsDefined(this, attributeRuntimeType);
}
@@ -765,31 +733,5 @@ namespace System.Reflection
return CustomAttributeData.GetCustomAttributesInternal(this);
}
#endregion
-
-#if FEATURE_REMOTING
- #region Remoting Cache
- private RemotingParameterCachedData m_cachedData;
-
- internal RemotingParameterCachedData RemotingCache
- {
- get
- {
- // This grabs an internal copy of m_cachedData and uses
- // that instead of looking at m_cachedData directly because
- // the cache may get cleared asynchronously. This prevents
- // us from having to take a lock.
- RemotingParameterCachedData cache = m_cachedData;
- if (cache == null)
- {
- cache = new RemotingParameterCachedData(this);
- RemotingParameterCachedData ret = Interlocked.CompareExchange(ref m_cachedData, cache, null);
- if (ret != null)
- cache = ret;
- }
- return cache;
- }
- }
- #endregion
-#endif //FEATURE_REMOTING
}
}
diff --git a/src/mscorlib/src/System/Reflection/Pointer.cs b/src/mscorlib/src/System/Reflection/Pointer.cs
index 8105208288..95025b20ed 100644
--- a/src/mscorlib/src/System/Reflection/Pointer.cs
+++ b/src/mscorlib/src/System/Reflection/Pointer.cs
@@ -22,13 +22,11 @@ namespace System.Reflection {
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class Pointer : ISerializable
{
- [SecurityCritical]
unsafe private void* _ptr;
private RuntimeType _ptrType;
private Pointer() {}
- [System.Security.SecurityCritical] // auto-generated
private unsafe Pointer(SerializationInfo info, StreamingContext context)
{
_ptr = ((IntPtr)(info.GetValue("_ptr", typeof(IntPtr)))).ToPointer();
@@ -38,17 +36,16 @@ namespace System.Reflection {
// 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.
- [System.Security.SecurityCritical] // auto-generated
public static unsafe Object Box(void *ptr,Type type) {
if (type == null)
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
if (!type.IsPointer)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBePointer"),"ptr");
+ 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"), "ptr");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBePointer"), nameof(ptr));
Pointer x = new Pointer();
x._ptr = ptr;
@@ -57,10 +54,9 @@ namespace System.Reflection {
}
// Returned the stored pointer.
- [System.Security.SecurityCritical] // auto-generated
public static unsafe void* Unbox(Object ptr) {
if (!(ptr is Pointer))
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBePointer"),"ptr");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBePointer"),nameof(ptr));
return ((Pointer)ptr)._ptr;
}
@@ -68,12 +64,10 @@ namespace System.Reflection {
return _ptrType;
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe Object GetPointerValue() {
return (IntPtr)_ptr;
}
- [System.Security.SecurityCritical]
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/PropertyInfo.cs b/src/mscorlib/src/System/Reflection/PropertyInfo.cs
index 3e451b15b6..e31b378924 100644
--- a/src/mscorlib/src/System/Reflection/PropertyInfo.cs
+++ b/src/mscorlib/src/System/Reflection/PropertyInfo.cs
@@ -22,9 +22,6 @@ namespace System.Reflection
[Serializable]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_PropertyInfo))]
-#pragma warning disable 618
- [PermissionSetAttribute(SecurityAction.InheritanceDemand, Name = "FullTrust")]
-#pragma warning restore 618
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class PropertyInfo : MemberInfo, _PropertyInfo
{
@@ -153,35 +150,6 @@ namespace System.Reflection
public bool IsSpecialName { get { return(Attributes & PropertyAttributes.SpecialName) != 0; } }
#endregion
-
-#if !FEATURE_CORECLR
- Type _PropertyInfo.GetType()
- {
- return base.GetType();
- }
-
- void _PropertyInfo.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _PropertyInfo.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _PropertyInfo.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- // If you implement this method, make sure to include _PropertyInfo.Invoke in VM\DangerousAPIs.h and
- // include _PropertyInfo in SystemDomain::IsReflectionInvocationMethod in AppDomain.cpp.
- void _PropertyInfo.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
-#endif
}
[Serializable]
@@ -190,7 +158,6 @@ namespace System.Reflection
#region Private Data Members
private int m_token;
private string m_name;
- [System.Security.SecurityCritical]
private void* m_utf8name;
private PropertyAttributes m_flags;
private RuntimeTypeCache m_reflectedTypeCache;
@@ -204,13 +171,12 @@ namespace System.Reflection
#endregion
#region Constructor
- [System.Security.SecurityCritical] // auto-generated
internal RuntimePropertyInfo(
int tkProperty, RuntimeType declaredType, RuntimeTypeCache reflectedTypeCache, out bool isPrivate)
{
Contract.Requires(declaredType != null);
Contract.Requires(reflectedTypeCache != null);
- Contract.Assert(!reflectedTypeCache.IsGlobal);
+ Debug.Assert(!reflectedTypeCache.IsGlobal);
MetadataImport scope = declaredType.GetRuntimeModule().MetadataImport;
@@ -245,7 +211,6 @@ namespace System.Reflection
internal Signature Signature
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
if (m_signature == null)
@@ -332,28 +297,27 @@ namespace System.Reflection
public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
{
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
Contract.EndContractBlock();
RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override bool IsDefined(Type attributeType, bool inherit)
{
if (attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
Contract.EndContractBlock();
RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
return CustomAttribute.IsDefined(this, attributeRuntimeType);
}
@@ -368,7 +332,6 @@ namespace System.Reflection
public override MemberTypes MemberType { get { return MemberTypes.Property; } }
public override String Name
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
if (m_name == null)
@@ -421,7 +384,6 @@ namespace System.Reflection
return Signature.GetCustomModifiers(0, false);
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal object GetConstantValue(bool raw)
{
Object defaultValue = MdConstant.GetValue(GetRuntimeModule().MetadataImport, m_token, PropertyType.GetTypeHandleInternal(), raw);
@@ -630,11 +592,10 @@ namespace System.Reflection
#endregion
#region ISerializable Implementation
- [System.Security.SecurityCritical] // auto-generated
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
MemberInfoSerializationHolder.GetSerializationInfo(
diff --git a/src/mscorlib/src/System/Reflection/ReflectionContext.cs b/src/mscorlib/src/System/Reflection/ReflectionContext.cs
index f9bfa87d76..34f692166c 100644
--- a/src/mscorlib/src/System/Reflection/ReflectionContext.cs
+++ b/src/mscorlib/src/System/Reflection/ReflectionContext.cs
@@ -28,7 +28,7 @@ namespace System.Reflection
public virtual TypeInfo GetTypeForObject(object value)
{
if (value == null)
- throw new ArgumentNullException("value");
+ 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
index 9b55c260cf..70681138c5 100644
--- a/src/mscorlib/src/System/Reflection/ReflectionTypeLoadException.cs
+++ b/src/mscorlib/src/System/Reflection/ReflectionTypeLoadException.cs
@@ -65,10 +65,9 @@ namespace System.Reflection {
get {return _exceptions;}
}
- [System.Security.SecurityCritical] // auto-generated_required
public override void GetObjectData(SerializationInfo info, StreamingContext context) {
if (info==null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
base.GetObjectData(info, context);
diff --git a/src/mscorlib/src/System/Reflection/RuntimeReflectionExtensions.cs b/src/mscorlib/src/System/Reflection/RuntimeReflectionExtensions.cs
index b4ef9b9902..00ab975842 100644
--- a/src/mscorlib/src/System/Reflection/RuntimeReflectionExtensions.cs
+++ b/src/mscorlib/src/System/Reflection/RuntimeReflectionExtensions.cs
@@ -72,7 +72,7 @@ namespace System.Reflection
public static InterfaceMapping GetRuntimeInterfaceMap(this TypeInfo typeInfo, Type interfaceType)
{
- if (typeInfo == null) throw new ArgumentNullException("typeInfo");
+ if (typeInfo == null) throw new ArgumentNullException(nameof(typeInfo));
if (!(typeInfo is RuntimeType)) throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"));
return typeInfo.GetInterfaceMap(interfaceType);
@@ -80,7 +80,7 @@ namespace System.Reflection
public static MethodInfo GetMethodInfo(this Delegate del)
{
- if (del == null) throw new ArgumentNullException("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
index e8a441ca8f..8107cf4159 100644
--- a/src/mscorlib/src/System/Reflection/StrongNameKeyPair.cs
+++ b/src/mscorlib/src/System/Reflection/StrongNameKeyPair.cs
@@ -26,20 +26,7 @@ namespace System.Reflection
using System.Runtime.Versioning;
using Microsoft.Win32;
using System.Diagnostics.Contracts;
-#if !FEATURE_CORECLR
- using Microsoft.Runtime.Hosting;
-#endif
-#if FEATURE_CORECLR
- // Dummy type to avoid ifdefs in signature definitions
- public class StrongNameKeyPair
- {
- private StrongNameKeyPair()
- {
- throw new NotSupportedException();
- }
- }
-#else
[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public class StrongNameKeyPair : IDeserializationCallback, ISerializable
@@ -50,14 +37,10 @@ namespace System.Reflection
private byte[] _publicKey;
// Build key pair from file.
- [System.Security.SecuritySafeCritical] // auto-generated
-#pragma warning disable 618
- [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)]
-#pragma warning restore 618
public StrongNameKeyPair(FileStream keyPairFile)
{
if (keyPairFile == null)
- throw new ArgumentNullException("keyPairFile");
+ throw new ArgumentNullException(nameof(keyPairFile));
Contract.EndContractBlock();
int length = (int)keyPairFile.Length;
@@ -68,14 +51,10 @@ namespace System.Reflection
}
// Build key pair from byte array in memory.
- [System.Security.SecuritySafeCritical] // auto-generated
-#pragma warning disable 618
- [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)]
-#pragma warning restore 618
public StrongNameKeyPair(byte[] keyPairArray)
{
if (keyPairArray == null)
- throw new ArgumentNullException("keyPairArray");
+ throw new ArgumentNullException(nameof(keyPairArray));
Contract.EndContractBlock();
_keyPairArray = new byte[keyPairArray.Length];
@@ -83,27 +62,7 @@ namespace System.Reflection
_keyPairExported = true;
}
-
- // Reference key pair in named key container.
- [System.Security.SecuritySafeCritical] // auto-generated
-#pragma warning disable 618
- [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)]
-#pragma warning restore 618
- public StrongNameKeyPair(String keyPairContainer)
- {
- if (keyPairContainer == null)
- throw new ArgumentNullException("keyPairContainer");
- Contract.EndContractBlock();
-
- _keyPairContainer = keyPairContainer;
-
- _keyPairExported = false;
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
-#pragma warning disable 618
- [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)]
-#pragma warning restore 618
+
protected StrongNameKeyPair (SerializationInfo info, StreamingContext context) {
_keyPairExported = (bool) info.GetValue("_keyPairExported", typeof(bool));
_keyPairArray = (byte[]) info.GetValue("_keyPairArray", typeof(byte[]));
@@ -111,68 +70,20 @@ namespace System.Reflection
_publicKey = (byte[]) info.GetValue("_publicKey", typeof(byte[]));
}
- // Get the public portion of the key pair.
- public byte[] PublicKey
+ public StrongNameKeyPair(String keyPairContainer)
{
- [System.Security.SecuritySafeCritical] // auto-generated
- get
- {
- if (_publicKey == null)
- {
- _publicKey = ComputePublicKey();
- }
-
- byte[] publicKey = new byte[_publicKey.Length];
- Array.Copy(_publicKey, publicKey, _publicKey.Length);
-
- return publicKey;
- }
+ throw new PlatformNotSupportedException();
}
-
- [System.Security.SecurityCritical] // auto-generated
- private unsafe byte[] ComputePublicKey()
+
+ public byte[] PublicKey
{
- byte[] publicKey = null;
-
- // Make sure pbPublicKey is not leaked with async exceptions
- RuntimeHelpers.PrepareConstrainedRegions();
- try {
- }
- finally
+ get
{
- IntPtr pbPublicKey = IntPtr.Zero;
- int cbPublicKey = 0;
-
- try
- {
- bool result;
- if (_keyPairExported)
- {
- result = StrongNameHelpers.StrongNameGetPublicKey(null, _keyPairArray, _keyPairArray.Length,
- out pbPublicKey, out cbPublicKey);
- }
- else
- {
- result = StrongNameHelpers.StrongNameGetPublicKey(_keyPairContainer, null, 0,
- out pbPublicKey, out cbPublicKey);
- }
- if (!result)
- throw new ArgumentException(Environment.GetResourceString("Argument_StrongNameGetPublicKey"));
-
- publicKey = new byte[cbPublicKey];
- Buffer.Memcpy(publicKey, 0, (byte*)(pbPublicKey.ToPointer()), 0, cbPublicKey);
- }
- finally
- {
- if (pbPublicKey != IntPtr.Zero)
- StrongNameHelpers.StrongNameFreeBuffer(pbPublicKey);
- }
+ throw new PlatformNotSupportedException();
}
- return publicKey;
}
/// <internalonly/>
- [System.Security.SecurityCritical]
void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context) {
info.AddValue("_keyPairExported", _keyPairExported);
info.AddValue("_keyPairArray", _keyPairArray);
@@ -182,13 +93,5 @@ namespace System.Reflection
/// <internalonly/>
void IDeserializationCallback.OnDeserialization (Object sender) {}
-
- // Internal routine used to retrieve key pair info from unmanaged code.
- private bool GetKeyPair(out Object arrayOrContainer)
- {
- arrayOrContainer = _keyPairExported ? (Object)_keyPairArray : (Object)_keyPairContainer;
- return _keyPairExported;
- }
}
-#endif // FEATURE_CORECLR
}
diff --git a/src/mscorlib/src/System/Reflection/TargetException.cs b/src/mscorlib/src/System/Reflection/TargetException.cs
index 02772f763f..9c56c121cc 100644
--- a/src/mscorlib/src/System/Reflection/TargetException.cs
+++ b/src/mscorlib/src/System/Reflection/TargetException.cs
@@ -19,11 +19,7 @@ namespace System.Reflection {
using System.Runtime.Serialization;
[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
-#if FEATURE_CORECLR
- public class TargetException : Exception {
-#else
public class TargetException : ApplicationException {
-#endif //FEATURE_CORECLR
public TargetException() : base() {
SetErrorCode(__HResults.COR_E_TARGET);
}
diff --git a/src/mscorlib/src/System/Reflection/TargetInvocationException.cs b/src/mscorlib/src/System/Reflection/TargetInvocationException.cs
index 70de4227dd..4a32ed245d 100644
--- a/src/mscorlib/src/System/Reflection/TargetInvocationException.cs
+++ b/src/mscorlib/src/System/Reflection/TargetInvocationException.cs
@@ -19,11 +19,7 @@ namespace System.Reflection {
using System.Runtime.Serialization;
[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
-#if FEATURE_CORECLR
- public sealed class TargetInvocationException : Exception {
-#else
public sealed class TargetInvocationException : ApplicationException {
-#endif //FEATURE_CORECLR
// This exception is not creatable without specifying the
// inner exception.
private TargetInvocationException()
diff --git a/src/mscorlib/src/System/Reflection/TargetParameterCountException.cs b/src/mscorlib/src/System/Reflection/TargetParameterCountException.cs
index 4f95b09c40..846732b449 100644
--- a/src/mscorlib/src/System/Reflection/TargetParameterCountException.cs
+++ b/src/mscorlib/src/System/Reflection/TargetParameterCountException.cs
@@ -19,11 +19,7 @@ namespace System.Reflection {
using System.Runtime.Serialization;
[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
-#if FEATURE_CORECLR
- public sealed class TargetParameterCountException : Exception {
-#else
public sealed class TargetParameterCountException : ApplicationException {
-#endif //FEATURE_CORECLR
public TargetParameterCountException()
: base(Environment.GetResourceString("Arg_TargetParameterCountException")) {
SetErrorCode(__HResults.COR_E_TARGETPARAMCOUNT);
diff --git a/src/mscorlib/src/System/Reflection/TypeDelegator.cs b/src/mscorlib/src/System/Reflection/TypeDelegator.cs
index cad4a4295a..d715df8950 100644
--- a/src/mscorlib/src/System/Reflection/TypeDelegator.cs
+++ b/src/mscorlib/src/System/Reflection/TypeDelegator.cs
@@ -24,14 +24,11 @@ namespace System.Reflection {
protected Type typeImpl;
- #if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical] // auto-generated
- #endif
protected TypeDelegator() {}
public TypeDelegator(Type delegatingType) {
if (delegatingType == null)
- throw new ArgumentNullException("delegatingType");
+ throw new ArgumentNullException(nameof(delegatingType));
Contract.EndContractBlock();
typeImpl = delegatingType;
diff --git a/src/mscorlib/src/System/Resources/FileBasedResourceGroveler.cs b/src/mscorlib/src/System/Resources/FileBasedResourceGroveler.cs
index efd949f565..76bf0008f9 100644
--- a/src/mscorlib/src/System/Resources/FileBasedResourceGroveler.cs
+++ b/src/mscorlib/src/System/Resources/FileBasedResourceGroveler.cs
@@ -23,6 +23,7 @@ namespace System.Resources {
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
internal class FileBasedResourceGroveler : IResourceGroveler
@@ -31,17 +32,16 @@ namespace System.Resources {
public FileBasedResourceGroveler(ResourceManager.ResourceManagerMediator mediator)
{
- Contract.Assert(mediator != null, "mediator shouldn't be null; check caller");
+ Debug.Assert(mediator != null, "mediator shouldn't be null; check caller");
_mediator = mediator;
}
// 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.
- [System.Security.SecuritySafeCritical] // auto-generated
public ResourceSet GrovelForResourceSet(CultureInfo culture, Dictionary<String, ResourceSet> localResourceSets, bool tryParents, bool createIfNotExists, ref StackCrawlMark stackMark)
{
- Contract.Assert(culture != null, "culture shouldn't be null; check caller");
+ Debug.Assert(culture != null, "culture shouldn't be null; check caller");
String fileName = null;
ResourceSet rs = null;
@@ -79,24 +79,6 @@ namespace System.Resources {
}
}
-#if !FEATURE_CORECLR // PAL doesn't support eventing, and we don't compile event providers for coreclr
- public bool HasNeutralResources(CultureInfo culture, String defaultResName)
- {
- // Detect missing neutral locale resources.
- String defaultResPath = FindResourceFile(culture, defaultResName);
- if (defaultResPath == null || !File.Exists(defaultResPath))
- {
- String dir = _mediator.ModuleDir;
- if (defaultResPath != null)
- {
- dir = Path.GetDirectoryName(defaultResPath);
- }
- return false;
- }
- return true;
- }
-#endif
-
// Given a CultureInfo, it generates the path &; file name for
// the .resources file for that CultureInfo. This method will grovel
// the disk looking for the correct file name & path. Uses CultureInfo's
@@ -107,8 +89,8 @@ namespace System.Resources {
private String FindResourceFile(CultureInfo culture, String fileName)
{
- Contract.Assert(culture != null, "culture shouldn't be null; check caller");
- Contract.Assert(fileName != null, "fileName shouldn't be null; check caller");
+ Debug.Assert(culture != null, "culture shouldn't be null; check caller");
+ Debug.Assert(fileName != null, "fileName shouldn't be null; check caller");
// If we have a moduleDir, check there first. Get module fully
// qualified name, append path to that.
@@ -145,10 +127,9 @@ namespace System.Resources {
// Constructs a new ResourceSet for a given file name. The logic in
// here avoids a ReflectionPermission check for our RuntimeResourceSet
// for perf and working set reasons.
- [System.Security.SecurityCritical]
private ResourceSet CreateResourceSet(String file)
{
- Contract.Assert(file != null, "file shouldn't be null; check caller");
+ Debug.Assert(file != null, "file shouldn't be null; check caller");
if (_mediator.UserResourceSet == null)
{
diff --git a/src/mscorlib/src/System/Resources/IResourceGroveler.cs b/src/mscorlib/src/System/Resources/IResourceGroveler.cs
index 983fd1204c..77c5c95890 100644
--- a/src/mscorlib/src/System/Resources/IResourceGroveler.cs
+++ b/src/mscorlib/src/System/Resources/IResourceGroveler.cs
@@ -23,10 +23,5 @@ namespace System.Resources {
{
ResourceSet GrovelForResourceSet(CultureInfo culture, Dictionary<String, ResourceSet> localResourceSets, bool tryParents,
bool createIfNotExists, ref StackCrawlMark stackMark);
-
-#if !FEATURE_CORECLR // PAL doesn't support eventing, and we don't compile event providers for coreclr
-
- bool HasNeutralResources(CultureInfo culture, String defaultResName);
-#endif
}
}
diff --git a/src/mscorlib/src/System/Resources/LooselyLinkedResourceReference.cs b/src/mscorlib/src/System/Resources/LooselyLinkedResourceReference.cs
index 8235d608be..15a076bc5c 100644
--- a/src/mscorlib/src/System/Resources/LooselyLinkedResourceReference.cs
+++ b/src/mscorlib/src/System/Resources/LooselyLinkedResourceReference.cs
@@ -36,13 +36,13 @@ namespace System.Resources {
public LooselyLinkedResourceReference(String looselyLinkedResourceName, String typeName)
{
if (looselyLinkedResourceName == null)
- throw new ArgumentNullException("looselyLinkedResourceName");
+ throw new ArgumentNullException(nameof(looselyLinkedResourceName));
if (typeName == null)
- throw new ArgumentNullException("typeName");
+ throw new ArgumentNullException(nameof(typeName));
if (looselyLinkedResourceName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "looselyLinkedResourceName");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(looselyLinkedResourceName));
if (typeName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "typeName");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(typeName));
Contract.EndContractBlock();
_manifestResourceName = looselyLinkedResourceName;
@@ -60,7 +60,7 @@ namespace System.Resources {
public Object Resolve(Assembly assembly)
{
if (assembly == null)
- throw new ArgumentNullException("assembly");
+ throw new ArgumentNullException(nameof(assembly));
Contract.EndContractBlock();
Stream data = assembly.GetManifestResourceStream(_manifestResourceName);
diff --git a/src/mscorlib/src/System/Resources/ManifestBasedResourceGroveler.cs b/src/mscorlib/src/System/Resources/ManifestBasedResourceGroveler.cs
index 5fd0daad09..78e961a7f9 100644
--- a/src/mscorlib/src/System/Resources/ManifestBasedResourceGroveler.cs
+++ b/src/mscorlib/src/System/Resources/ManifestBasedResourceGroveler.cs
@@ -26,13 +26,10 @@ namespace System.Resources {
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using Microsoft.Win32;
-#if !FEATURE_CORECLR
- using System.Diagnostics.Tracing;
-#endif
-
//
// Note: this type is integral to the construction of exception objects,
// and sometimes this has to be done in low memory situtations (OOM) or
@@ -55,12 +52,11 @@ namespace System.Resources {
_mediator = mediator;
}
- [System.Security.SecuritySafeCritical]
[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)
{
- Contract.Assert(culture != null, "culture shouldn't be null; check caller");
- Contract.Assert(localResourceSets != null, "localResourceSets shouldn't be null; check caller");
+ Debug.Assert(culture != null, "culture shouldn't be null; check caller");
+ Debug.Assert(localResourceSets != null, "localResourceSets shouldn't be null; check caller");
ResourceSet rs = null;
Stream stream = null;
@@ -110,43 +106,15 @@ namespace System.Resources {
// want to add it twice.
lock (localResourceSets)
{
- if (localResourceSets.TryGetValue(culture.Name, out rs))
- {
-#if !FEATURE_CORECLR
- if (FrameworkEventSource.IsInitialized)
- {
- FrameworkEventSource.Log.ResourceManagerFoundResourceSetInCacheUnexpected(_mediator.BaseName, _mediator.MainAssembly, culture.Name);
- }
-#endif
- }
+ localResourceSets.TryGetValue(culture.Name, out rs);
}
stream = GetManifestResourceStream(satellite, fileName, ref stackMark);
}
-#if !FEATURE_CORECLR
- if (FrameworkEventSource.IsInitialized)
- {
- if (stream != null)
- {
- FrameworkEventSource.Log.ResourceManagerStreamFound(_mediator.BaseName, _mediator.MainAssembly, culture.Name, satellite, fileName);
- }
- else
- {
- FrameworkEventSource.Log.ResourceManagerStreamNotFound(_mediator.BaseName, _mediator.MainAssembly, culture.Name, satellite, fileName);
- }
- }
-#endif
-
// 4a. Found a stream; create a ResourceSet if possible
if (createIfNotExists && stream != null && rs == null)
{
-#if !FEATURE_CORECLR
- if (FrameworkEventSource.IsInitialized)
- {
- FrameworkEventSource.Log.ResourceManagerCreatingResourceSet(_mediator.BaseName, _mediator.MainAssembly, culture.Name, fileName);
- }
-#endif
rs = CreateResourceSet(stream, satellite);
}
else if (stream == null && tryParents)
@@ -159,36 +127,9 @@ namespace System.Resources {
}
}
-#if !FEATURE_CORECLR
- if (!createIfNotExists && stream != null && rs == null)
- {
- if (FrameworkEventSource.IsInitialized)
- {
- FrameworkEventSource.Log.ResourceManagerNotCreatingResourceSet(_mediator.BaseName, _mediator.MainAssembly, culture.Name);
- }
- }
-#endif
-
return rs;
}
-#if !FEATURE_CORECLR
- // Returns whether or not the main assembly contains a particular resource
- // file in it's assembly manifest. Used to verify that the neutral
- // Culture's .resources file is present in the main assembly
- public bool HasNeutralResources(CultureInfo culture, String defaultResName)
- {
- String resName = defaultResName;
- if (_mediator.LocationInfo != null && _mediator.LocationInfo.Namespace != null)
- resName = _mediator.LocationInfo.Namespace + Type.Delimiter + defaultResName;
- String[] resourceFiles = _mediator.MainAssembly.GetManifestResourceNames();
- foreach(String s in resourceFiles)
- if (s.Equals(resName))
- return true;
- return false;
- }
-#endif
-
private CultureInfo UltimateFallbackFixup(CultureInfo lookForCulture)
{
@@ -199,13 +140,6 @@ namespace System.Resources {
if (lookForCulture.Name == _mediator.NeutralResourcesCulture.Name &&
_mediator.FallbackLoc == UltimateResourceFallbackLocation.MainAssembly)
{
-#if !FEATURE_CORECLR
- if (FrameworkEventSource.IsInitialized)
- {
- FrameworkEventSource.Log.ResourceManagerNeutralResourcesSufficient(_mediator.BaseName, _mediator.MainAssembly, lookForCulture.Name);
- }
-#endif
-
returnCulture = CultureInfo.InvariantCulture;
}
else if (lookForCulture.HasInvariantCultureName && _mediator.FallbackLoc == UltimateResourceFallbackLocation.Satellite)
@@ -214,13 +148,11 @@ namespace System.Resources {
}
return returnCulture;
-
}
- [System.Security.SecurityCritical]
internal static CultureInfo GetNeutralResourcesLanguage(Assembly a, ref UltimateResourceFallbackLocation fallbackLocation)
{
- Contract.Assert(a != null, "assembly != null");
+ Debug.Assert(a != null, "assembly != null");
string cultureName = null;
short fallback = 0;
if (GetNeutralResourcesLanguageAttribute(((RuntimeAssembly)a).GetNativeHandle(),
@@ -232,11 +164,6 @@ namespace System.Resources {
fallbackLocation = (UltimateResourceFallbackLocation)fallback;
}
else {
-#if !FEATURE_CORECLR
- if (FrameworkEventSource.IsInitialized) {
- FrameworkEventSource.Log.ResourceManagerNeutralResourceAttributeMissing(a);
- }
-#endif
fallbackLocation = UltimateResourceFallbackLocation.MainAssembly;
return CultureInfo.InvariantCulture;
}
@@ -253,7 +180,7 @@ namespace System.Resources {
// fires, please fix the build process for the BCL directory.
if (a == typeof(Object).Assembly)
{
- Contract.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;
}
@@ -267,10 +194,9 @@ namespace System.Resources {
// Use the assembly to resolve assembly manifest resource references.
// Note that is can be null, but probably shouldn't be.
// This method could use some refactoring. One thing at a time.
- [System.Security.SecurityCritical]
internal ResourceSet CreateResourceSet(Stream store, Assembly assembly)
{
- Contract.Assert(store != null, "I need a Stream!");
+ Debug.Assert(store != null, "I need a Stream!");
// Check to see if this is a Stream the ResourceManager understands,
// and check for the correct resource reader type.
if (store.CanSeek && store.Length > 4)
@@ -350,7 +276,7 @@ namespace System.Resources {
Type resSetType;
if (_mediator.UserResourceSet == null)
{
- Contract.Assert(resSetTypeName != null, "We should have a ResourceSet type name from the custom resource file here.");
+ Debug.Assert(resSetTypeName != null, "We should have a ResourceSet type name from the custom resource file here.");
resSetType = Type.GetType(resSetTypeName, true, false);
}
else
@@ -413,7 +339,6 @@ namespace System.Resources {
}
}
- [System.Security.SecurityCritical]
private Stream GetManifestResourceStream(RuntimeAssembly satellite, String fileName, ref StackCrawlMark stackMark)
{
Contract.Requires(satellite != null, "satellite shouldn't be null; check caller");
@@ -437,7 +362,6 @@ 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.
- [System.Security.SecurityCritical]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
private Stream CaseInsensitiveManifestResourceStreamLookup(RuntimeAssembly satellite, String name)
{
@@ -475,48 +399,19 @@ namespace System.Resources {
}
}
-#if !FEATURE_CORECLR
- if (FrameworkEventSource.IsInitialized)
- {
- if (canonicalName != null)
- {
- FrameworkEventSource.Log.ResourceManagerCaseInsensitiveResourceStreamLookupSucceeded(_mediator.BaseName, _mediator.MainAssembly, satellite.GetSimpleName(), givenName);
- }
- else
- {
- FrameworkEventSource.Log.ResourceManagerCaseInsensitiveResourceStreamLookupFailed(_mediator.BaseName, _mediator.MainAssembly, satellite.GetSimpleName(), givenName);
- }
- }
-#endif
-
if (canonicalName == null)
{
return null;
}
+
// If we're looking in the main assembly AND if the main
// assembly was the person who created the ResourceManager,
// skip a security check for private manifest resources.
bool canSkipSecurityCheck = _mediator.MainAssembly == satellite && _mediator.CallingAssembly == _mediator.MainAssembly;
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- Stream s = satellite.GetManifestResourceStream(canonicalName, ref stackMark, canSkipSecurityCheck);
- // GetManifestResourceStream will return null if we don't have
- // permission to read this stream from the assembly. For example,
- // if the stream is private and we're trying to access it from another
- // assembly (ie, ResMgr in mscorlib accessing anything else), we
- // require Reflection TypeInformation permission to be able to read
- // this.
-#if !FEATURE_CORECLR
- if (s!=null) {
- if (FrameworkEventSource.IsInitialized)
- {
- FrameworkEventSource.Log.ResourceManagerManifestResourceAccessDenied(_mediator.BaseName, _mediator.MainAssembly, satellite.GetSimpleName(), canonicalName);
- }
- }
-#endif
- return s;
+ return satellite.GetManifestResourceStream(canonicalName, ref stackMark, canSkipSecurityCheck);
}
- [System.Security.SecurityCritical]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
private RuntimeAssembly GetSatelliteAssembly(CultureInfo lookForCulture, ref StackCrawlMark stackMark)
{
@@ -548,30 +443,16 @@ namespace System.Resources {
int hr = fle._HResult;
if (hr != Win32Native.MakeHRFromErrorCode(Win32Native.ERROR_ACCESS_DENIED))
{
- Contract.Assert(false, "[This assert catches satellite assembly build/deployment problems - report this message to your build lab & loc engineer]" + Environment.NewLine + "GetSatelliteAssembly failed for culture " + lookForCulture.Name + " and version " + (_mediator.SatelliteContractVersion == null ? _mediator.MainAssembly.GetVersion().ToString() : _mediator.SatelliteContractVersion.ToString()) + " of assembly " + _mediator.MainAssembly.GetSimpleName() + " with error code 0x" + hr.ToString("X", CultureInfo.InvariantCulture) + Environment.NewLine + "Exception: " + fle);
+ Debug.Assert(false, "[This assert catches satellite assembly build/deployment problems - report this message to your build lab & loc engineer]" + Environment.NewLine + "GetSatelliteAssembly failed for culture " + lookForCulture.Name + " and version " + (_mediator.SatelliteContractVersion == null ? _mediator.MainAssembly.GetVersion().ToString() : _mediator.SatelliteContractVersion.ToString()) + " of assembly " + _mediator.MainAssembly.GetSimpleName() + " with error code 0x" + hr.ToString("X", CultureInfo.InvariantCulture) + Environment.NewLine + "Exception: " + fle);
}
}
// Don't throw for zero-length satellite assemblies, for compat with v1
catch (BadImageFormatException bife)
{
- Contract.Assert(false, "[This assert catches satellite assembly build/deployment problems - report this message to your build lab & loc engineer]" + Environment.NewLine + "GetSatelliteAssembly failed for culture " + lookForCulture.Name + " and version " + (_mediator.SatelliteContractVersion == null ? _mediator.MainAssembly.GetVersion().ToString() : _mediator.SatelliteContractVersion.ToString()) + " of assembly " + _mediator.MainAssembly.GetSimpleName() + Environment.NewLine + "Exception: " + bife);
+ Debug.Assert(false, "[This assert catches satellite assembly build/deployment problems - report this message to your build lab & loc engineer]" + Environment.NewLine + "GetSatelliteAssembly failed for culture " + lookForCulture.Name + " and version " + (_mediator.SatelliteContractVersion == null ? _mediator.MainAssembly.GetVersion().ToString() : _mediator.SatelliteContractVersion.ToString()) + " of assembly " + _mediator.MainAssembly.GetSimpleName() + Environment.NewLine + "Exception: " + bife);
}
-#if !FEATURE_CORECLR
- if (FrameworkEventSource.IsInitialized)
- {
- if (satellite != null)
- {
- FrameworkEventSource.Log.ResourceManagerGetSatelliteAssemblySucceeded(_mediator.BaseName, _mediator.MainAssembly, lookForCulture.Name, satAssemblyName);
- }
- else
- {
- FrameworkEventSource.Log.ResourceManagerGetSatelliteAssemblyFailed(_mediator.BaseName, _mediator.MainAssembly, lookForCulture.Name, satAssemblyName);
- }
- }
-#endif
-
return satellite;
}
@@ -583,8 +464,8 @@ namespace System.Resources {
// and causes partially trusted localized apps to fail.
private bool CanUseDefaultResourceClasses(String readerTypeName, String resSetTypeName)
{
- Contract.Assert(readerTypeName != null, "readerTypeName shouldn't be null; check caller");
- Contract.Assert(resSetTypeName != null, "resSetTypeName shouldn't be null; check caller");
+ Debug.Assert(readerTypeName != null, "readerTypeName shouldn't be null; check caller");
+ Debug.Assert(resSetTypeName != null, "resSetTypeName shouldn't be null; check caller");
if (_mediator.UserResourceSet != null)
return false;
@@ -609,7 +490,6 @@ namespace System.Resources {
return true;
}
- [System.Security.SecurityCritical]
private String GetSatelliteAssemblyName()
{
String satAssemblyName = _mediator.MainAssembly.GetSimpleName();
@@ -617,7 +497,6 @@ namespace System.Resources {
return satAssemblyName;
}
- [System.Security.SecurityCritical]
private void HandleSatelliteMissing()
{
String satAssemName = _mediator.MainAssembly.GetSimpleName() + ".resources.dll";
@@ -646,14 +525,13 @@ namespace System.Resources {
throw new MissingSatelliteAssemblyException(Environment.GetResourceString("MissingSatelliteAssembly_Culture_Name", _mediator.NeutralResourcesCulture, satAssemName), missingCultureName);
}
- [System.Security.SecurityCritical] // auto-generated
private void HandleResourceStreamMissing(String fileName)
{
// Keep people from bothering me about resources problems
if (_mediator.MainAssembly == typeof(Object).Assembly && _mediator.BaseName.Equals(System.CoreLib.Name))
{
// This would break CultureInfo & all our exceptions.
- Contract.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!";
@@ -669,7 +547,6 @@ namespace System.Resources {
}
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [System.Security.SecurityCritical] // Our security team doesn't yet allow safe-critical P/Invoke methods.
[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/NeutralResourcesLanguageAttribute.cs b/src/mscorlib/src/System/Resources/NeutralResourcesLanguageAttribute.cs
index 560cd5faa9..6517a56b6a 100644
--- a/src/mscorlib/src/System/Resources/NeutralResourcesLanguageAttribute.cs
+++ b/src/mscorlib/src/System/Resources/NeutralResourcesLanguageAttribute.cs
@@ -35,7 +35,7 @@ namespace System.Resources {
public NeutralResourcesLanguageAttribute(String cultureName)
{
if (cultureName == null)
- throw new ArgumentNullException("cultureName");
+ throw new ArgumentNullException(nameof(cultureName));
Contract.EndContractBlock();
_culture = cultureName;
@@ -45,7 +45,7 @@ namespace System.Resources {
public NeutralResourcesLanguageAttribute(String cultureName, UltimateResourceFallbackLocation location)
{
if (cultureName == null)
- throw new ArgumentNullException("cultureName");
+ throw new ArgumentNullException(nameof(cultureName));
if (!Enum.IsDefined(typeof(UltimateResourceFallbackLocation), location))
throw new ArgumentException(Environment.GetResourceString("Arg_InvalidNeutralResourcesLanguage_FallbackLoc", location));
Contract.EndContractBlock();
diff --git a/src/mscorlib/src/System/Resources/ResourceFallbackManager.cs b/src/mscorlib/src/System/Resources/ResourceFallbackManager.cs
index def7836e05..de50cccc33 100644
--- a/src/mscorlib/src/System/Resources/ResourceFallbackManager.cs
+++ b/src/mscorlib/src/System/Resources/ResourceFallbackManager.cs
@@ -17,9 +17,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
-#if FEATURE_CORECLR
-using System.Diagnostics.Contracts;
-#endif
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -33,8 +30,6 @@ namespace System.Resources
private CultureInfo m_neutralResourcesCulture;
private bool m_useParents;
-// Added but disabled from desktop in .NET 4.0, stayed disabled in .NET 4.5
-#if FEATURE_CORECLR
// This is a cache of the thread, process, user, and OS-preferred fallback cultures.
// However, each thread may have a different value, and these may change during the
// lifetime of the process. So this cache must be verified each time we use it.
@@ -43,7 +38,6 @@ namespace System.Resources
// as well to avoid differences across threads.
[ThreadStatic]
private static CultureInfo[] cachedOsFallbackArray;
-#endif // FEATURE_CORECLR
internal ResourceFallbackManager(CultureInfo startingCulture, CultureInfo neutralResourcesCulture, bool useParents)
{
@@ -91,8 +85,6 @@ namespace System.Resources
yield break;
}
-// Added but disabled from desktop in .NET 4.0, stayed disabled in .NET 4.5
-#if FEATURE_CORECLR
// 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
@@ -118,7 +110,6 @@ namespace System.Resources
}
}
}
-#endif // FEATURE_CORECLR
// 3. invariant
// Don't return invariant twice though.
@@ -128,8 +119,6 @@ namespace System.Resources
yield return CultureInfo.InvariantCulture;
}
-// Added but disabled from desktop in .NET 4.0, stayed disabled in .NET 4.5
-#if FEATURE_CORECLR
private static CultureInfo[] LoadPreferredCultures()
{
// The list of preferred cultures includes thread, process, user, and OS
@@ -190,7 +179,6 @@ namespace System.Resources
// Note: May return null.
- [System.Security.SecuritySafeCritical] // auto-generated
private static String[] GetResourceFallbackArray()
{
// AppCompat note: We've added this feature for desktop V4 but we ripped it out
@@ -272,7 +260,5 @@ namespace System.Resources
return CultureInfo.nativeGetResourceFallbackArray();
#endif
}
-
-#endif // FEATURE_CORECLR
}
}
diff --git a/src/mscorlib/src/System/Resources/ResourceManager.cs b/src/mscorlib/src/System/Resources/ResourceManager.cs
index b088e7f492..15f6af7bcf 100644
--- a/src/mscorlib/src/System/Resources/ResourceManager.cs
+++ b/src/mscorlib/src/System/Resources/ResourceManager.cs
@@ -30,10 +30,8 @@ namespace System.Resources {
using Microsoft.Win32;
using System.Collections.Generic;
using System.Runtime.Versioning;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
-#if !FEATURE_CORECLR
- using System.Diagnostics.Tracing;
-#endif
#if FEATURE_APPX
//
@@ -45,21 +43,16 @@ namespace System.Resources {
// Also using interface or abstract class will not play nice with FriendAccessAllowed.
//
[FriendAccessAllowed]
- [SecurityCritical]
internal class WindowsRuntimeResourceManagerBase
{
- [SecurityCritical]
public virtual bool Initialize(string libpath, string reswFilename, out PRIExceptionInfo exceptionInfo){exceptionInfo = null; return false;}
- [SecurityCritical]
public virtual String GetString(String stringName, String startingCulture, String neutralResourcesCulture){return null;}
public virtual CultureInfo GlobalResourceContextBestFitCultureInfo {
- [SecurityCritical]
get { return null; }
}
- [SecurityCritical]
public virtual bool SetGlobalResourceContextDefaultCulture(CultureInfo ci) { return false; }
}
@@ -266,13 +259,6 @@ namespace System.Resources {
protected ResourceManager()
{
-#if !FEATURE_CORECLR
- // This constructor is not designed to be used under AppX and is not in the Win8 profile.
- // However designers may use them even if they are running under AppX since they are
- // not subject to the restrictions of the Win8 profile.
- Contract.Assert(!AppDomain.IsAppXModel() || AppDomain.IsAppXDesignMode());
-#endif
-
Init();
_lastUsedResourceCache = new CultureNameResourceSetPair();
@@ -292,18 +278,11 @@ namespace System.Resources {
//
private ResourceManager(String baseName, String resourceDir, Type usingResourceSet) {
if (null==baseName)
- throw new ArgumentNullException("baseName");
+ throw new ArgumentNullException(nameof(baseName));
if (null==resourceDir)
- throw new ArgumentNullException("resourceDir");
+ throw new ArgumentNullException(nameof(resourceDir));
Contract.EndContractBlock();
-#if !FEATURE_CORECLR
- // This constructor is not designed to be used under AppX and is not in the Win8 profile.
- // However designers may use them even if they are running under AppX since they are
- // not subject to the restrictions of the Win8 profile.
- Contract.Assert(!AppDomain.IsAppXModel() || AppDomain.IsAppXDesignMode());
-#endif
-
BaseNameField = baseName;
moduleDir = resourceDir;
@@ -317,30 +296,16 @@ namespace System.Resources {
ResourceManagerMediator mediator = new ResourceManagerMediator(this);
resourceGroveler = new FileBasedResourceGroveler(mediator);
-
-#if !FEATURE_CORECLR // PAL doesn't support eventing, and we don't compile event providers for coreclr
- if (FrameworkEventSource.IsInitialized && FrameworkEventSource.Log.IsEnabled()) {
- CultureInfo culture = CultureInfo.InvariantCulture;
- String defaultResName = GetResourceFileName(culture);
-
- if (resourceGroveler.HasNeutralResources(culture, defaultResName)) {
- FrameworkEventSource.Log.ResourceManagerNeutralResourcesFound(BaseNameField, MainAssembly, defaultResName);
- }
- else {
- FrameworkEventSource.Log.ResourceManagerNeutralResourcesNotFound(BaseNameField, MainAssembly, defaultResName);
- }
- }
-#endif
}
-
+
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public ResourceManager(String baseName, Assembly assembly)
{
if (null==baseName)
- throw new ArgumentNullException("baseName");
+ throw new ArgumentNullException(nameof(baseName));
if (null==assembly)
- throw new ArgumentNullException("assembly");
+ throw new ArgumentNullException(nameof(assembly));
Contract.EndContractBlock();
if (!(assembly is RuntimeAssembly))
@@ -368,18 +333,11 @@ namespace System.Resources {
public ResourceManager(String baseName, Assembly assembly, Type usingResourceSet)
{
if (null==baseName)
- throw new ArgumentNullException("baseName");
+ throw new ArgumentNullException(nameof(baseName));
if (null==assembly)
- throw new ArgumentNullException("assembly");
+ throw new ArgumentNullException(nameof(assembly));
Contract.EndContractBlock();
-#if !FEATURE_CORECLR
- // This constructor is not designed to be used under AppX and is not in the Win8 profile.
- // However designers may use them even if they are running under AppX since they are
- // not subject to the restrictions of the Win8 profile.
- Contract.Assert(!AppDomain.IsAppXModel() || AppDomain.IsAppXDesignMode());
-#endif
-
if (!(assembly is RuntimeAssembly))
throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeAssembly"));
@@ -387,7 +345,7 @@ namespace System.Resources {
BaseNameField = baseName;
if (usingResourceSet != null && (usingResourceSet != _minResourceSet) && !(usingResourceSet.IsSubclassOf(_minResourceSet)))
- throw new ArgumentException(Environment.GetResourceString("Arg_ResMgrNotResSet"), "usingResourceSet");
+ throw new ArgumentException(Environment.GetResourceString("Arg_ResMgrNotResSet"), nameof(usingResourceSet));
_userResourceSet = usingResourceSet;
CommonAssemblyInit();
@@ -404,7 +362,7 @@ namespace System.Resources {
public ResourceManager(Type resourceSource)
{
if (null==resourceSource)
- throw new ArgumentNullException("resourceSource");
+ throw new ArgumentNullException(nameof(resourceSource));
Contract.EndContractBlock();
if (!(resourceSource is RuntimeType))
@@ -434,7 +392,6 @@ namespace System.Resources {
this._lastUsedResourceCache = null;
}
- [System.Security.SecuritySafeCritical]
[OnDeserialized]
private void OnDeserialized(StreamingContext ctx)
{
@@ -479,7 +436,6 @@ namespace System.Resources {
// Trying to unify code as much as possible, even though having to do a
// security check in each constructor prevents it.
- [System.Security.SecuritySafeCritical]
private void CommonAssemblyInit()
{
if (_bUsingModernResourceManagement == false)
@@ -496,30 +452,6 @@ namespace System.Resources {
}
_neutralResourcesCulture = ManifestBasedResourceGroveler.GetNeutralResourcesLanguage(MainAssembly, ref _fallbackLoc);
-
-#if !FEATURE_CORECLR // PAL doesn't support eventing, and we don't compile event providers for coreclr
- if (_bUsingModernResourceManagement == false)
- {
- if (FrameworkEventSource.IsInitialized && FrameworkEventSource.Log.IsEnabled()) {
- CultureInfo culture = CultureInfo.InvariantCulture;
- String defaultResName = GetResourceFileName(culture);
-
- if (resourceGroveler.HasNeutralResources(culture, defaultResName)) {
- FrameworkEventSource.Log.ResourceManagerNeutralResourcesFound(BaseNameField, MainAssembly, defaultResName);
- }
- else {
- String outputResName = defaultResName;
- if (_locationInfo != null && _locationInfo.Namespace != null)
- outputResName = _locationInfo.Namespace + Type.Delimiter + defaultResName;
- FrameworkEventSource.Log.ResourceManagerNeutralResourcesNotFound(BaseNameField, MainAssembly, outputResName);
- }
- }
-
-#pragma warning disable 618
- ResourceSets = new Hashtable(); // for backward compatibility
-#pragma warning restore 618
- }
-#endif
}
// Gets the base name for the ResourceManager.
@@ -557,12 +489,6 @@ namespace System.Resources {
// creating a new ResourceManager isn't quite the correct behavior.
public virtual void ReleaseAllResources()
{
-#if !FEATURE_CORECLR
- if (FrameworkEventSource.IsInitialized)
- {
- FrameworkEventSource.Log.ResourceManagerReleasingResources(BaseNameField, MainAssembly);
- }
-#endif
Dictionary<String, ResourceSet> localResourceSets = _resourceSets;
// If any calls to Close throw, at least leave ourselves in a
@@ -573,27 +499,9 @@ namespace System.Resources {
lock(localResourceSets) {
IDictionaryEnumerator setEnum = localResourceSets.GetEnumerator();
-#if !FEATURE_CORECLR
- IDictionaryEnumerator setEnum2 = null;
-#pragma warning disable 618
- if (ResourceSets != null) {
- setEnum2 = ResourceSets.GetEnumerator();
- }
- ResourceSets = new Hashtable(); // for backwards compat
-#pragma warning restore 618
-#endif
-
while (setEnum.MoveNext()) {
((ResourceSet)setEnum.Value).Close();
}
-
-#if !FEATURE_CORECLR
- if (setEnum2 != null) {
- while (setEnum2.MoveNext()) {
- ((ResourceSet)setEnum2.Value).Close();
- }
- }
-#endif
}
}
@@ -677,11 +585,10 @@ namespace System.Resources {
// if it hasn't yet been loaded and if parent CultureInfos should be
// loaded as well for resource inheritance.
//
- [System.Security.SecuritySafeCritical] // auto-generated
[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)
- throw new ArgumentNullException("culture");
+ throw new ArgumentNullException(nameof(culture));
Contract.EndContractBlock();
Dictionary<String,ResourceSet> localResourceSets = _resourceSets;
@@ -721,11 +628,10 @@ 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.
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
protected virtual ResourceSet InternalGetResourceSet(CultureInfo culture, bool createIfNotExists, bool tryParents)
{
- Contract.Assert(culture != null, "culture != null");
+ Debug.Assert(culture != null, "culture != null");
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return InternalGetResourceSet(culture,createIfNotExists,tryParents, ref stackMark);
@@ -735,7 +641,6 @@ 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.
- [System.Security.SecurityCritical]
private ResourceSet InternalGetResourceSet(CultureInfo requestedCulture, bool createIfNotExists, bool tryParents, ref StackCrawlMark stackMark)
{
Dictionary<String, ResourceSet> localResourceSets = _resourceSets;
@@ -743,11 +648,6 @@ namespace System.Resources {
CultureInfo foundCulture = null;
lock (localResourceSets) {
if (localResourceSets.TryGetValue(requestedCulture.Name, out rs)) {
-#if !FEATURE_CORECLR
- if (FrameworkEventSource.IsInitialized) {
- FrameworkEventSource.Log.ResourceManagerFoundResourceSetInCache(BaseNameField, MainAssembly, requestedCulture.Name);
- }
-#endif
return rs;
}
}
@@ -756,20 +656,8 @@ namespace System.Resources {
foreach (CultureInfo currentCultureInfo in mgr)
{
-#if !FEATURE_CORECLR
- if (FrameworkEventSource.IsInitialized)
- {
- FrameworkEventSource.Log.ResourceManagerLookingForResourceSet(BaseNameField, MainAssembly, currentCultureInfo.Name);
- }
-#endif
lock(localResourceSets) {
if (localResourceSets.TryGetValue(currentCultureInfo.Name, out rs)) {
-#if !FEATURE_CORECLR
- if (FrameworkEventSource.IsInitialized)
- {
- FrameworkEventSource.Log.ResourceManagerFoundResourceSetInCache(BaseNameField, MainAssembly, currentCultureInfo.Name);
- }
-#endif
// we need to update the cache if we fellback
if(requestedCulture != currentCultureInfo) foundCulture = currentCultureInfo;
break;
@@ -846,7 +734,7 @@ namespace System.Resources {
{
// Ensure that the assembly reference is not null
if (a == null) {
- throw new ArgumentNullException("a", Environment.GetResourceString("ArgumentNull_Assembly"));
+ throw new ArgumentNullException(nameof(a), Environment.GetResourceString("ArgumentNull_Assembly"));
}
Contract.EndContractBlock();
@@ -867,7 +755,7 @@ namespace System.Resources {
Object[] attrs = a.GetCustomAttributes(typeof(SatelliteContractVersionAttribute), false);
if (attrs.Length == 0)
return null;
- Contract.Assert(attrs.Length == 1, "Cannot have multiple instances of SatelliteContractVersionAttribute on an assembly!");
+ Debug.Assert(attrs.Length == 1, "Cannot have multiple instances of SatelliteContractVersionAttribute on an assembly!");
v = ((SatelliteContractVersionAttribute)attrs[0]).Version;
}
Version ver;
@@ -880,7 +768,7 @@ namespace System.Resources {
// If this assert fires, please fix the build process for the
// BCL directory.
if (a == typeof(Object).Assembly) {
- Contract.Assert(false, System.CoreLib.Name+"'s SatelliteContractVersionAttribute is a malformed version string!");
+ Debug.Assert(false, System.CoreLib.Name+"'s SatelliteContractVersionAttribute is a malformed version string!");
return null;
}
@@ -894,7 +782,6 @@ namespace System.Resources {
#endif
}
- [System.Security.SecuritySafeCritical] // auto-generated
protected static CultureInfo GetNeutralResourcesLanguage(Assembly a)
{
// This method should be obsolete - replace it with the one below.
@@ -909,7 +796,7 @@ namespace System.Resources {
String typeName2,
AssemblyName asmName2)
{
- Contract.Assert(asmTypeName1 != null, "asmTypeName1 was unexpectedly null");
+ Debug.Assert(asmTypeName1 != null, "asmTypeName1 was unexpectedly null");
// First, compare type names
int comma = asmTypeName1.IndexOf(',');
@@ -961,13 +848,11 @@ namespace System.Resources {
}
#if FEATURE_APPX
- [SecuritySafeCritical]
- // Throws WinRT hresults
private string GetStringFromPRI(String stringName, String startingCulture, String neutralResourcesCulture) {
- Contract.Assert(_bUsingModernResourceManagement);
- Contract.Assert(_WinRTResourceManager != null);
- Contract.Assert(_PRIonAppXInitialized);
- Contract.Assert(AppDomain.IsAppXModel());
+ Debug.Assert(_bUsingModernResourceManagement);
+ Debug.Assert(_WinRTResourceManager != null);
+ Debug.Assert(_PRIonAppXInitialized);
+ Debug.Assert(AppDomain.IsAppXModel());
if (stringName.Length == 0)
return null;
@@ -987,7 +872,6 @@ namespace System.Resources {
// Since we can't directly reference System.Runtime.WindowsRuntime from mscorlib, we have to get the type via reflection.
// It would be better if we could just implement WindowsRuntimeResourceManager in mscorlib, but we can't, because
// we can do very little with WinRT in mscorlib.
- [SecurityCritical]
internal static WindowsRuntimeResourceManagerBase GetWinRTResourceManager()
{
Type WinRTResourceManagerType = Type.GetType("System.Resources.WindowsRuntimeResourceManager, " + AssemblyRef.SystemRuntimeWindowsRuntime, true);
@@ -1000,7 +884,6 @@ namespace System.Resources {
#if FEATURE_APPX
[NonSerialized]
- [SecurityCritical]
private WindowsRuntimeResourceManagerBase _WinRTResourceManager; // Written only by SetAppXConfiguration
[NonSerialized]
@@ -1029,12 +912,10 @@ namespace System.Resources {
//
// b) For any other non-FX assembly, we will use the modern resource manager with the premise that app package
// contains the PRI resources.
- [SecuritySafeCritical]
private bool ShouldUseSatelliteAssemblyResourceLookupUnderAppX(RuntimeAssembly resourcesAssembly)
{
bool fUseSatelliteAssemblyResourceLookupUnderAppX = resourcesAssembly.IsFrameworkAssembly();
-
-#if FEATURE_CORECLR
+
if (!fUseSatelliteAssemblyResourceLookupUnderAppX)
{
// Check to see if the assembly is under PLATFORM_RESOURCE_ROOTS. If it is, then we should use satellite assembly lookup for it.
@@ -1055,23 +936,21 @@ namespace System.Resources {
}
}
}
-#endif // FEATURE_CORECLR
+
return fUseSatelliteAssemblyResourceLookupUnderAppX;
-
}
-
- [SecuritySafeCritical]
+
#endif // FEATURE_APPX
// Only call SetAppXConfiguration from ResourceManager constructors, and nowhere else.
// Throws MissingManifestResourceException and WinRT HResults
private void SetAppXConfiguration()
{
- Contract.Assert(_bUsingModernResourceManagement == false); // Only this function writes to this member
+ Debug.Assert(_bUsingModernResourceManagement == false); // Only this function writes to this member
#if FEATURE_APPX
- Contract.Assert(_WinRTResourceManager == null); // Only this function writes to this member
- Contract.Assert(_PRIonAppXInitialized == false); // Only this function writes to this member
- Contract.Assert(_PRIExceptionInfo == null); // Only this function writes to this member
+ Debug.Assert(_WinRTResourceManager == null); // Only this function writes to this member
+ Debug.Assert(_PRIonAppXInitialized == false); // Only this function writes to this member
+ Debug.Assert(_PRIExceptionInfo == null); // Only this function writes to this member
bool bUsingSatelliteAssembliesUnderAppX = false;
@@ -1225,7 +1104,7 @@ namespace System.Resources {
//
public virtual String GetString(String name, CultureInfo culture) {
if (null==name)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
Contract.EndContractBlock();
#if FEATURE_APPX
@@ -1267,13 +1146,7 @@ namespace System.Resources {
// This line behaves the same way as CultureInfo.CurrentUICulture would have in .NET 4
culture = Thread.CurrentThread.GetCurrentUICultureNoAppX();
}
-
-#if !FEATURE_CORECLR
- if (FrameworkEventSource.IsInitialized)
- {
- FrameworkEventSource.Log.ResourceManagerLookupStarted(BaseNameField, MainAssembly, culture.Name);
- }
-#endif
+
ResourceSet last = GetFirstResourceSet(culture);
if (last != null)
@@ -1311,13 +1184,6 @@ namespace System.Resources {
last = rs;
}
}
-
-#if !FEATURE_CORECLR
- if (FrameworkEventSource.IsInitialized)
- {
- FrameworkEventSource.Log.ResourceManagerLookupFailed(BaseNameField, MainAssembly, culture.Name);
- }
-#endif
}
return null;
@@ -1342,7 +1208,7 @@ namespace System.Resources {
private Object GetObject(String name, CultureInfo culture, bool wrapUnmanagedMemStream)
{
if (null==name)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
Contract.EndContractBlock();
#if FEATURE_APPX
@@ -1364,12 +1230,6 @@ namespace System.Resources {
culture = Thread.CurrentThread.GetCurrentUICultureNoAppX();
}
-#if !FEATURE_CORECLR
- if (FrameworkEventSource.IsInitialized)
- {
- FrameworkEventSource.Log.ResourceManagerLookupStarted(BaseNameField, MainAssembly, culture.Name);
- }
-#endif
ResourceSet last = GetFirstResourceSet(culture);
if (last != null)
{
@@ -1422,12 +1282,6 @@ namespace System.Resources {
}
}
-#if !FEATURE_CORECLR
- if (FrameworkEventSource.IsInitialized)
- {
- FrameworkEventSource.Log.ResourceManagerLookupFailed(BaseNameField, MainAssembly, culture.Name);
- }
-#endif
return null;
}
@@ -1448,7 +1302,6 @@ namespace System.Resources {
#if RESOURCE_SATELLITE_CONFIG
// Internal helper method - gives an end user the ability to prevent
// satellite assembly probes for certain cultures via a config file.
- [System.Security.SecurityCritical] // auto-generated
private bool TryLookingForSatellite(CultureInfo lookForCulture)
{
if (!_checkedConfigFile) {
@@ -1471,110 +1324,14 @@ namespace System.Resources {
// The config file told us what satellites might be installed.
int pos = Array.IndexOf(installedSatellites, lookForCulture.Name);
-#if !FEATURE_CORECLR
- if (FrameworkEventSource.IsInitialized && FrameworkEventSource.Log.IsEnabled()) {
- if (pos < 0) {
- FrameworkEventSource.Log.ResourceManagerCultureNotFoundInConfigFile(BaseNameField, MainAssembly, lookForCulture.Name);
- }
- else {
- FrameworkEventSource.Log.ResourceManagerCultureFoundInConfigFile(BaseNameField, MainAssembly, lookForCulture.Name);
- }
- }
-#endif
return pos >= 0;
}
// Note: There is one config file per appdomain. This is not
// per-process nor per-assembly.
- [System.Security.SecurityCritical] // auto-generated
private Hashtable GetSatelliteAssembliesFromConfig()
{
-#if FEATURE_FUSION
-
- String fileName = AppDomain.CurrentDomain.FusionStore.ConfigurationFileInternal;
- if (fileName == null) {
- return null;
- }
-
- // Don't do a security assert. We need to support semi-trusted
- // scenarios, but asserting here causes infinite resource lookups
- // while initializing security & looking up mscorlib's config file.
- // Use internal methods to bypass security checks.
-
- // If we're dealing with a local file name or a UNC path instead
- // of a URL, check to see if the file exists here for perf (avoids
- // throwing a FileNotFoundException).
- if (fileName.Length >= 2 &&
- ((fileName[1] == Path.VolumeSeparatorChar) || (fileName[0] == Path.DirectorySeparatorChar && fileName[1] == Path.DirectorySeparatorChar)) &&
- !File.InternalExists(fileName))
- return null;
-
- ConfigTreeParser parser = new ConfigTreeParser();
- String queryPath = "/configuration/satelliteassemblies";
- ConfigNode node = null;
- // Catch exceptions in case a web app doesn't have a config file.
- try {
- node = parser.Parse(fileName, queryPath, true);
- }
- catch(Exception) {}
-
- if (node == null) {
- return null;
- }
-
- // The application config file will contain sections like this:
- // <?xml version="1.0"?>
- // <configuration>
- // <satelliteassemblies>
- // <assembly name="mscorlib, Version=..., PublicKeyToken=...">
- // <culture>fr</culture>
- // </assembly>
- // <assembly name="UserAssembly, ...">
- // <culture>fr-FR</culture>
- // <culture>de-CH</culture>
- // </assembly>
- // <assembly name="UserAssembly2, ...">
- // </assembly>
- // </satelliteassemblies>
- // </configuration>
- Hashtable satelliteInfo = new Hashtable(StringComparer.OrdinalIgnoreCase);
- foreach(ConfigNode assemblyNode in node.Children) {
- if (!String.Equals(assemblyNode.Name, "assembly"))
- throw new ApplicationException(Environment.GetResourceString("XMLSyntax_InvalidSyntaxSatAssemTag", Path.GetFileName(fileName), assemblyNode.Name));
-
- if (assemblyNode.Attributes.Count == 0)
- throw new ApplicationException(Environment.GetResourceString("XMLSyntax_InvalidSyntaxSatAssemTagNoAttr", Path.GetFileName(fileName)));
-
- DictionaryEntry de = (DictionaryEntry) assemblyNode.Attributes[0];
- String assemblyName = (String) de.Value;
- if (!String.Equals(de.Key, "name") || String.IsNullOrEmpty(assemblyName) || assemblyNode.Attributes.Count > 1)
- throw new ApplicationException(Environment.GetResourceString("XMLSyntax_InvalidSyntaxSatAssemTagBadAttr", Path.GetFileName(fileName), de.Key, de.Value));
-
- ArrayList list = new ArrayList(5);
- foreach(ConfigNode child in assemblyNode.Children)
- if (child.Value != null)
- list.Add(child.Value);
-
- String[] satellites = new String[list.Count];
- for(int i=0; i<satellites.Length; i++) {
- String cultureName = (String)list[i];
- satellites[i] = cultureName;
-#if !FEATURE_CORECLR
- if (FrameworkEventSource.IsInitialized)
- {
- FrameworkEventSource.Log.ResourceManagerAddingCultureFromConfigFile(BaseNameField, MainAssembly, cultureName);
- }
-#endif
- }
-
- satelliteInfo.Add(assemblyName, satellites);
- }
-
- return satelliteInfo;
-#else
return null;
-#endif //FEATURE_FUSION
-
}
#endif // RESOURCE_SATELLITE_CONFIG
@@ -1586,7 +1343,7 @@ namespace System.Resources {
{
if (rm == null)
{
- throw new ArgumentNullException("rm");
+ throw new ArgumentNullException(nameof(rm));
}
_rm = rm;
}
@@ -1667,7 +1424,6 @@ namespace System.Resources {
#if RESOURCE_SATELLITE_CONFIG
- [System.Security.SecurityCritical] // auto-generated
internal bool TryLookingForSatellite(CultureInfo lookForCulture)
{
return _rm.TryLookingForSatellite(lookForCulture);
diff --git a/src/mscorlib/src/System/Resources/ResourceReader.cs b/src/mscorlib/src/System/Resources/ResourceReader.cs
index a269d5c5fe..89cfdb1b9f 100644
--- a/src/mscorlib/src/System/Resources/ResourceReader.cs
+++ b/src/mscorlib/src/System/Resources/ResourceReader.cs
@@ -31,6 +31,7 @@ namespace System.Resources {
using System.Globalization;
using System.Configuration.Assemblies;
using System.Runtime.Versioning;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
// Provides the default implementation of IResourceReader, reading
@@ -66,7 +67,7 @@ namespace System.Resources {
internal static bool CanCache(ResourceTypeCode value)
{
- Contract.Assert(value >= 0, "negative ResourceTypeCode. What?");
+ Debug.Assert(value >= 0, "negative ResourceTypeCode. What?");
return value <= ResourceTypeCode.LastPrimitive;
}
}
@@ -94,10 +95,8 @@ namespace System.Resources {
// of the assembly. The pointers here are pointers into that block of
// memory controlled by the OS's loader.
private int[] _nameHashes; // hash values for all names.
- [SecurityCritical]
private unsafe int* _nameHashesPtr; // In case we're using UnmanagedMemoryStream
private int[] _namePositions; // relative locations of names
- [SecurityCritical]
private unsafe int* _namePositionsPtr; // If we're using UnmanagedMemoryStream
private RuntimeType[] _typeTable; // Lazy array of Types for resource values.
private int[] _typeNamePositions; // To delay initialize type table
@@ -152,11 +151,6 @@ namespace System.Resources {
};
#endif // FEATURE_SERIALIZATION
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #else
- [System.Security.SecuritySafeCritical]
- #endif
public ResourceReader(String fileName)
{
_resCache = new Dictionary<String, ResourceLocator>(FastResourceComparer.Default);
@@ -172,11 +166,10 @@ namespace System.Resources {
}
}
- [System.Security.SecurityCritical] // auto-generated_required
public ResourceReader(Stream stream)
{
if (stream==null)
- throw new ArgumentNullException("stream");
+ throw new ArgumentNullException(nameof(stream));
if (!stream.CanRead)
throw new ArgumentException(Environment.GetResourceString("Argument_StreamNotReadable"));
Contract.EndContractBlock();
@@ -194,7 +187,6 @@ namespace System.Resources {
// passing in the stream to read from and the RuntimeResourceSet's
// internal hash table (hash table of names with file offsets
// and values, coupled to this ResourceReader).
- [System.Security.SecurityCritical] // auto-generated
internal ResourceReader(Stream stream, Dictionary<String, ResourceLocator> resCache)
{
Contract.Requires(stream != null, "Need a stream!");
@@ -221,7 +213,6 @@ namespace System.Resources {
Close();
}
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe void Dispose(bool disposing)
{
if (_store != null) {
@@ -243,7 +234,6 @@ namespace System.Resources {
}
}
- [System.Security.SecurityCritical] // auto-generated
internal static unsafe int ReadUnalignedI4(int* p)
{
byte* buffer = (byte*)p;
@@ -264,11 +254,10 @@ namespace System.Resources {
_store.BaseStream.Seek(stringLength, SeekOrigin.Current);
}
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe int GetNameHash(int index)
{
- Contract.Assert(index >=0 && index < _numResources, "Bad index into hash array. index: "+index);
- Contract.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];
@@ -276,11 +265,10 @@ namespace System.Resources {
return ReadUnalignedI4(&_nameHashesPtr[index]);
}
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe int GetNamePosition(int index)
{
- Contract.Assert(index >=0 && index < _numResources, "Bad index into name position array. index: "+index);
- Contract.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)
@@ -316,7 +304,7 @@ namespace System.Resources {
// This does a binary search through the names.
internal int FindPosForResource(String name)
{
- Contract.Assert(_store != null, "ResourceReader is closed!");
+ Debug.Assert(_store != null, "ResourceReader is closed!");
int hash = FastResourceComparer.HashFunction(name);
BCLDebug.Log("RESMGRFILEFORMAT", "FindPosForResource for "+name+" hash: "+hash.ToString("x", CultureInfo.InvariantCulture));
// Binary search over the hashes. Use the _namePositions array to
@@ -395,10 +383,9 @@ namespace System.Resources {
// with the string you pass in.
// Whoever calls this method should make sure that they take a lock
// so no one else can cause us to seek in the stream.
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe bool CompareStringEqualsName(String name)
{
- Contract.Assert(_store != null, "ResourceReader is closed!");
+ Debug.Assert(_store != null, "ResourceReader is closed!");
int byteLen = _store.Read7BitEncodedInt();
if (byteLen < 0) {
throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_NegativeStringLength"));
@@ -433,10 +420,9 @@ namespace System.Resources {
// This is used in the enumerator. The enumerator iterates from 0 to n
// of our resources and this returns the resource name for a particular
// index. The parameter is NOT a virtual offset.
- [System.Security.SecurityCritical] // auto-generated
private unsafe String AllocateStringForNameIndex(int index, out int dataOffset)
{
- Contract.Assert(_store != null, "ResourceReader is closed!");
+ Debug.Assert(_store != null, "ResourceReader is closed!");
byte[] bytes;
int byteLen;
long nameVA = GetNamePosition(index);
@@ -500,7 +486,7 @@ namespace System.Resources {
// index. The parameter is NOT a virtual offset.
private Object GetValueForNameIndex(int index)
{
- Contract.Assert(_store != null, "ResourceReader is closed!");
+ Debug.Assert(_store != null, "ResourceReader is closed!");
long nameVA = GetNamePosition(index);
lock(this) {
_store.BaseStream.Seek(nameVA + _nameSectionOffset, SeekOrigin.Begin);
@@ -525,7 +511,7 @@ namespace System.Resources {
// no one can cause us to do a seek in here.
internal String LoadString(int pos)
{
- Contract.Assert(_store != null, "ResourceReader is closed!");
+ Debug.Assert(_store != null, "ResourceReader is closed!");
_store.BaseStream.Seek(_dataSectionOffset+pos, SeekOrigin.Begin);
String s = null;
int typeIndex = _store.Read7BitEncodedInt();
@@ -578,8 +564,8 @@ namespace System.Resources {
// no one can cause us to do a seek in here.
internal Object LoadObjectV1(int pos)
{
- Contract.Assert(_store != null, "ResourceReader is closed!");
- Contract.Assert(_version == 1, ".resources file was not a V1 .resources file!");
+ Debug.Assert(_store != null, "ResourceReader is closed!");
+ Debug.Assert(_version == 1, ".resources file was not a V1 .resources file!");
try {
// mega try-catch performs exceptionally bad on x64; factored out body into
@@ -595,7 +581,6 @@ namespace System.Resources {
}
#if FEATURE_SERIALIZATION
- [SecuritySafeCritical]
#endif
private Object _LoadObjectV1(int pos) {
_store.BaseStream.Seek(_dataSectionOffset+pos, SeekOrigin.Begin);
@@ -654,8 +639,8 @@ namespace System.Resources {
internal Object LoadObjectV2(int pos, out ResourceTypeCode typeCode)
{
- Contract.Assert(_store != null, "ResourceReader is closed!");
- Contract.Assert(_version >= 2, ".resources file was not a V2 (or higher) .resources file!");
+ Debug.Assert(_store != null, "ResourceReader is closed!");
+ Debug.Assert(_version >= 2, ".resources file was not a V2 (or higher) .resources file!");
try {
// mega try-catch performs exceptionally bad on x64; factored out body into
@@ -670,7 +655,6 @@ namespace System.Resources {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
private Object _LoadObjectV2(int pos, out ResourceTypeCode typeCode) {
_store.BaseStream.Seek(_dataSectionOffset+pos, SeekOrigin.Begin);
typeCode = (ResourceTypeCode) _store.Read7BitEncodedInt();
@@ -752,7 +736,7 @@ namespace System.Resources {
byte[] bytes = new byte[len];
int r = _ums.Read(bytes, 0, len);
- Contract.Assert(r == len, "ResourceReader needs to use a blocking read here. (Call _store.ReadBytes(len)?)");
+ Debug.Assert(r == len, "ResourceReader needs to use a blocking read here. (Call _store.ReadBytes(len)?)");
return bytes;
}
@@ -801,7 +785,6 @@ namespace System.Resources {
// deserialization binder to simulate a type-limiting deserializer.
// This method handles types that are safe to deserialize, as well as
// ensuring we only get back what we expect.
- [System.Security.SecurityCritical] // auto-generated
private Object DeserializeObject(int typeIndex)
{
RuntimeType type = FindType(typeIndex);
@@ -843,10 +826,9 @@ namespace System.Resources {
// Reads in the header information for a .resources file. Verifies some
// of the assumptions about this resource set, and builds the class table
// for the default resource file format.
- [System.Security.SecurityCritical] // auto-generated
private void ReadResources()
{
- Contract.Assert(_store != null, "ResourceReader is closed!");
+ Debug.Assert(_store != null, "ResourceReader is closed!");
#if FEATURE_SERIALIZATION
BinaryFormatter bf = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.File | StreamingContextStates.Persistence));
_typeLimitingBinder = new TypeLimitingDeserializationBinder();
@@ -867,7 +849,6 @@ namespace System.Resources {
}
}
- [System.Security.SecurityCritical] // auto-generated
private void _ReadResources()
{
// Read ResourceManager header
@@ -1088,12 +1069,11 @@ namespace System.Resources {
_store.BaseStream.Position = oldPos;
}
}
- Contract.Assert(_typeTable[typeIndex] != null, "Should have found a type!");
+ Debug.Assert(_typeTable[typeIndex] != null, "Should have found a type!");
return _typeTable[typeIndex];
}
#if FEATURE_SERIALIZATION
- [System.Security.SecurityCritical] // auto-generated
private void InitSafeToDeserializeArray()
{
_safeToDeserialize = new bool[_typeTable.Length];
@@ -1165,7 +1145,7 @@ namespace System.Resources {
public void GetResourceData(String resourceName, out String resourceType, out byte[] resourceData)
{
if (resourceName == null)
- throw new ArgumentNullException("resourceName");
+ throw new ArgumentNullException(nameof(resourceName));
Contract.EndContractBlock();
if (_resCache == null)
throw new InvalidOperationException(Environment.GetResourceString("ResourceReaderIsClosed"));
@@ -1200,10 +1180,10 @@ namespace System.Resources {
Array.Sort(sortedDataPositions);
int index = Array.BinarySearch(sortedDataPositions, dataPos);
- Contract.Assert(index >= 0 && index < _numResources, "Couldn't find data position within sorted data positions array!");
+ 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));
- Contract.Assert(len >= 0 && len <= (int) _store.BaseStream.Length - dataPos + _dataSectionOffset, "Length was negative or outside the bounds of the file!");
+ 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;
@@ -1227,12 +1207,12 @@ namespace System.Resources {
{
Contract.Requires(typeCode >= 0, "can't be negative");
if (typeCode < ResourceTypeCode.StartOfUserTypes) {
- Contract.Assert(!String.Equals(typeCode.ToString(), "LastPrimitive"), "Change ResourceTypeCode metadata order so LastPrimitive isn't what Enum.ToString prefers.");
+ Debug.Assert(!String.Equals(typeCode.ToString(), "LastPrimitive"), "Change ResourceTypeCode metadata order so LastPrimitive isn't what Enum.ToString prefers.");
return "ResourceTypeCode." + typeCode.ToString();
}
else {
int typeIndex = typeCode - ResourceTypeCode.StartOfUserTypes;
- Contract.Assert(typeIndex >= 0 && typeIndex < _typeTable.Length, "TypeCode is broken or corrupted!");
+ Debug.Assert(typeIndex >= 0 && typeIndex < _typeTable.Length, "TypeCode is broken or corrupted!");
long oldPos = _store.BaseStream.Position;
try {
_store.BaseStream.Position = _typeNamePositions[typeIndex];
@@ -1277,7 +1257,6 @@ namespace System.Resources {
_typeToDeserialize = type;
}
- [System.Security.SecuritySafeCritical] // overrides transparent public member
public override Type BindToType(string assemblyName, string typeName)
{
// BinaryObjectReader::Bind tries us first, then its own code.
@@ -1343,7 +1322,6 @@ namespace System.Resources {
}
public Object Key {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
if (_currentName == ENUM_DONE) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumEnded));
if (!_currentIsValid) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumNotStarted));
@@ -1367,7 +1345,6 @@ namespace System.Resources {
}
public DictionaryEntry Entry {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
if (_currentName == ENUM_DONE) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumEnded));
if (!_currentIsValid) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumNotStarted));
diff --git a/src/mscorlib/src/System/Resources/ResourceSet.cs b/src/mscorlib/src/System/Resources/ResourceSet.cs
index ed40a1237f..1b272fc6ff 100644
--- a/src/mscorlib/src/System/Resources/ResourceSet.cs
+++ b/src/mscorlib/src/System/Resources/ResourceSet.cs
@@ -31,15 +31,11 @@ namespace System.Resources {
// stores them in a hash table. Custom IResourceReaders can be used.
//
[Serializable]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public class ResourceSet : IDisposable, IEnumerable
{
[NonSerialized] protected IResourceReader Reader;
-#if FEATURE_CORECLR
internal Hashtable Table;
-#else
- protected Hashtable Table;
-#endif
private Hashtable _caseInsensitiveTable; // For case-insensitive lookups.
@@ -65,9 +61,6 @@ namespace System.Resources {
// implementation. Use this constructor to open & read from a file
// on disk.
//
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
public ResourceSet(String fileName)
{
Reader = new ResourceReader(fileName);
@@ -89,7 +82,6 @@ namespace System.Resources {
// implementation. Use this constructor to read from an open stream
// of data.
//
- [System.Security.SecurityCritical] // auto-generated_required
public ResourceSet(Stream stream)
{
Reader = new ResourceReader(stream);
@@ -98,7 +90,6 @@ namespace System.Resources {
}
#if LOOSELY_LINKED_RESOURCE_REFERENCE
- [System.Security.SecurityCritical] // auto_generated_required
public ResourceSet(Stream stream, Assembly assembly)
{
Reader = new ResourceReader(stream);
@@ -111,7 +102,7 @@ namespace System.Resources {
public ResourceSet(IResourceReader reader)
{
if (reader == null)
- throw new ArgumentNullException("reader");
+ throw new ArgumentNullException(nameof(reader));
Contract.EndContractBlock();
Reader = reader;
CommonInit();
@@ -122,7 +113,7 @@ namespace System.Resources {
public ResourceSet(IResourceReader reader, Assembly assembly)
{
if (reader == null)
- throw new ArgumentNullException("reader");
+ throw new ArgumentNullException(nameof(reader));
Contract.EndContractBlock();
Reader = reader;
CommonInit();
@@ -182,15 +173,13 @@ namespace System.Resources {
return typeof(ResourceReader);
}
-#if !FEATURE_CORECLR
// Returns the preferred IResourceWriter class for this kind of ResourceSet.
// Subclasses of ResourceSet using their own Readers &; should override
// GetDefaultReader and GetDefaultWriter.
public virtual Type GetDefaultWriter()
{
- return typeof(ResourceWriter);
+ return Type.GetType("System.Resources.ResourceWriter, System.Resources.Writer, Version=4.0.1.0, Culture=neutral, PublicKeyToken=" + AssemblyRef.MicrosoftPublicKeyToken, throwOnError: true);
}
-#endif // !FEATURE_CORECLR
[ComVisible(false)]
public virtual IDictionaryEnumerator GetEnumerator()
@@ -291,7 +280,7 @@ namespace System.Resources {
private Object GetObjectInternal(String name)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
Contract.EndContractBlock();
Hashtable copyOfTable = Table; // Avoid a race with Dispose
diff --git a/src/mscorlib/src/System/Resources/RuntimeResourceSet.cs b/src/mscorlib/src/System/Resources/RuntimeResourceSet.cs
index 6b512bcf6a..a94ac82781 100644
--- a/src/mscorlib/src/System/Resources/RuntimeResourceSet.cs
+++ b/src/mscorlib/src/System/Resources/RuntimeResourceSet.cs
@@ -20,6 +20,7 @@ namespace System.Resources {
using System.Globalization;
using System.Reflection;
using System.Runtime.Versioning;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
// A RuntimeResourceSet stores all the resources defined in one
@@ -184,7 +185,6 @@ namespace System.Resources {
// the resources once, adding them into the table.
private bool _haveReadFromReader;
- [System.Security.SecurityCritical] // auto-generated
internal RuntimeResourceSet(String fileName) : base(false)
{
BCLDebug.Log("RESMGRFILEFORMAT", "RuntimeResourceSet .ctor(String)");
@@ -204,7 +204,6 @@ namespace System.Resources {
Assembly = assembly;
}
#else
- [System.Security.SecurityCritical] // auto-generated
internal RuntimeResourceSet(Stream stream) : base(false)
{
BCLDebug.Log("RESMGRFILEFORMAT", "RuntimeResourceSet .ctor(Stream)");
@@ -285,7 +284,7 @@ namespace System.Resources {
private Object GetObject(String key, bool ignoreCase, bool isString)
{
if (key==null)
- throw new ArgumentNullException("key");
+ throw new ArgumentNullException(nameof(key));
if (Reader == null || _resCache == null)
throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_ResourceSet"));
Contract.EndContractBlock();
@@ -312,7 +311,7 @@ namespace System.Resources {
}
if (dataPos != -1 && value == null) {
- Contract.Assert(dataPos >= 0, "data section offset cannot be negative!");
+ 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
// lock on the entire RuntimeResourceSet, which is
@@ -373,7 +372,7 @@ namespace System.Resources {
Reader.Close();
}
else {
- Contract.Assert(ignoreCase, "This should only happen for case-insensitive lookups");
+ Debug.Assert(ignoreCase, "This should only happen for case-insensitive lookups");
ResourceReader.ResourceEnumerator en = _defaultReader.GetEnumeratorInternal();
while (en.MoveNext()) {
// Note: Always ask for the resource key before the data position.
diff --git a/src/mscorlib/src/System/Resources/SatelliteContractVersionAttribute.cs b/src/mscorlib/src/System/Resources/SatelliteContractVersionAttribute.cs
index f72e810227..327279062a 100644
--- a/src/mscorlib/src/System/Resources/SatelliteContractVersionAttribute.cs
+++ b/src/mscorlib/src/System/Resources/SatelliteContractVersionAttribute.cs
@@ -27,7 +27,7 @@ namespace System.Resources {
public SatelliteContractVersionAttribute(String version)
{
if (version == null)
- throw new ArgumentNullException("version");
+ throw new ArgumentNullException(nameof(version));
Contract.EndContractBlock();
_version = version;
}
diff --git a/src/mscorlib/src/System/Resources/__FastResourceComparer.cs b/src/mscorlib/src/System/Resources/__FastResourceComparer.cs
index 5bc7333863..e0911fae1d 100644
--- a/src/mscorlib/src/System/Resources/__FastResourceComparer.cs
+++ b/src/mscorlib/src/System/Resources/__FastResourceComparer.cs
@@ -17,6 +17,7 @@ namespace System.Resources {
using System;
using System.Collections;
using System.Collections.Generic;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
internal sealed class FastResourceComparer : IComparer, IEqualityComparer, IComparer<String>, IEqualityComparer<String>
@@ -78,11 +79,10 @@ namespace System.Resources {
// Input is one string to compare with, and a byte[] containing chars in
// little endian unicode. Pass in the number of valid chars.
- [System.Security.SecurityCritical] // auto-generated
public unsafe static int CompareOrdinal(String a, byte[] bytes, int bCharLength)
{
- Contract.Assert(a != null && bytes != null, "FastResourceComparer::CompareOrdinal must have non-null params");
- Contract.Assert(bCharLength * 2 <= bytes.Length, "FastResourceComparer::CompareOrdinal - numChars is too big!");
+ Debug.Assert(a != null && bytes != null, "FastResourceComparer::CompareOrdinal must have non-null params");
+ Debug.Assert(bCharLength * 2 <= bytes.Length, "FastResourceComparer::CompareOrdinal - numChars is too big!");
// This is a managed version of strcmp, but I can't take advantage
// of a terminating 0, unlike strcmp in C.
int i = 0;
@@ -107,7 +107,6 @@ namespace System.Resources {
return a.Length - bCharLength;
}
- [System.Security.SecurityCritical] // auto-generated
public static int CompareOrdinal(byte[] bytes, int aCharLength, String b)
{
return -CompareOrdinal(b, bytes, aCharLength);
@@ -115,12 +114,11 @@ namespace System.Resources {
// This method is to handle potentially misaligned data accesses.
// The byte* must point to little endian Unicode characters.
- [System.Security.SecurityCritical] // auto-generated
internal unsafe static int CompareOrdinal(byte* a, int byteLen, String b)
{
- Contract.Assert((byteLen & 1) == 0, "CompareOrdinal is expecting a UTF-16 string length, which must be even!");
- Contract.Assert(a != null && b != null, "Null args not allowed.");
- Contract.Assert(byteLen >= 0, "byteLen must be non-negative.");
+ Debug.Assert((byteLen & 1) == 0, "CompareOrdinal is expecting a UTF-16 string length, which must be even!");
+ Debug.Assert(a != null && b != null, "Null args not allowed.");
+ Debug.Assert(byteLen >= 0, "byteLen must be non-negative.");
int r = 0;
int i = 0;
diff --git a/src/mscorlib/src/System/RtType.cs b/src/mscorlib/src/System/RtType.cs
index 037576fc33..168beefd4e 100644
--- a/src/mscorlib/src/System/RtType.cs
+++ b/src/mscorlib/src/System/RtType.cs
@@ -25,12 +25,6 @@ using System.Runtime.CompilerServices;
using System.Security;
using System.Text;
using System.Runtime.Remoting;
-#if FEATURE_REMOTING
-using System.Runtime.Remoting.Proxies;
-using System.Runtime.Remoting.Messaging;
-using System.Runtime.Remoting.Activation;
-using System.Runtime.Remoting.Metadata;
-#endif
using MdSigCallingConvention = System.Signature.MdSigCallingConvention;
using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache;
using System.Runtime.InteropServices;
@@ -203,7 +197,6 @@ namespace System
private MemberListType m_listType;
private uint m_nameHash;
- [System.Security.SecurityCritical] // auto-generated
public unsafe Filter(byte* pUtf8Name, int cUtf8Name, MemberListType listType)
{
this.m_name = new Utf8String((void*) pUtf8Name, cUtf8Name);
@@ -227,7 +220,7 @@ namespace System
// Currently the callers of UsesStringComparison assume that if it returns false
// then the match always succeeds and can be skipped. Assert that this is maintained.
- Contract.Assert(retVal || RequiresStringComparison());
+ Debug.Assert(retVal || RequiresStringComparison());
return retVal;
}
@@ -248,7 +241,7 @@ namespace System
public uint GetHashToMatch()
{
- Contract.Assert(RequiresStringComparison());
+ Debug.Assert(RequiresStringComparison());
return m_nameHash;
}
@@ -272,7 +265,6 @@ namespace System
#region Constructor
#if MDA_SUPPORTED
- [System.Security.SecuritySafeCritical] // auto-generated
#endif
internal MemberInfoCache(RuntimeTypeCache runtimeTypeCache)
{
@@ -282,7 +274,6 @@ namespace System
m_runtimeTypeCache = runtimeTypeCache;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal MethodBase AddMethod(RuntimeType declaringType, RuntimeMethodHandleInternal method, CacheType cacheType)
{
T[] list = null;
@@ -310,7 +301,6 @@ namespace System
return (MethodBase)(object)list[0];
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal FieldInfo AddField(RuntimeFieldHandleInternal field)
{
// create the runtime field info
@@ -333,7 +323,6 @@ namespace System
return (FieldInfo)(object)list[0];
}
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe T[] Populate(string name, MemberListType listType, CacheType cacheType)
{
T[] list = null;
@@ -372,7 +361,6 @@ namespace System
return list;
}
- [System.Security.SecurityCritical] // auto-generated
private unsafe T[] GetListByName(char* pName, int cNameLen, byte* pUtf8Name, int cUtf8Name, MemberListType listType, CacheType cacheType)
{
if (cNameLen != 0)
@@ -415,7 +403,6 @@ namespace System
// May replace the list with a new one if certain cache
// lookups succeed. Also, may modify the contents of the list
// after merging these new data structures with cached ones.
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal void Insert(ref T[] list, string name, MemberListType listType)
{
@@ -545,7 +532,7 @@ namespace System
// Grow the list by exactly one element in this case to avoid null entries at the end.
//
- Contract.Assert(false);
+ Debug.Assert(false);
newSize = cachedMembers.Length + 1;
}
@@ -560,7 +547,7 @@ namespace System
cachedMembers = cachedMembers2;
}
- Contract.Assert(cachedMembers[freeSlotIndex] == null);
+ Debug.Assert(cachedMembers[freeSlotIndex] == null);
cachedMembers[freeSlotIndex] = newMemberInfo;
freeSlotIndex++;
}
@@ -572,13 +559,12 @@ namespace System
#region Population Logic
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe RuntimeMethodInfo[] PopulateMethods(Filter filter)
{
ListBuilder<RuntimeMethodInfo> list = new ListBuilder<RuntimeMethodInfo>();
RuntimeType declaringType = ReflectedType;
- Contract.Assert(declaringType != null);
+ Debug.Assert(declaringType != null);
if (RuntimeTypeHandle.IsInterface(declaringType))
{
@@ -590,7 +576,7 @@ namespace System
{
if (!RuntimeMethodHandle.MatchesNameHash(methodHandle, filter.GetHashToMatch()))
{
- Contract.Assert(!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)));
+ Debug.Assert(!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)));
continue;
}
@@ -599,10 +585,10 @@ namespace System
}
#region Loop through all methods on the interface
- Contract.Assert(!methodHandle.IsNullHandle());
+ Debug.Assert(!methodHandle.IsNullHandle());
// Except for .ctor, .cctor, IL_STUB*, and static methods, all interface methods should be abstract, virtual, and non-RTSpecialName.
// Note that this assumption will become invalid when we add support for non-abstract or static methods on interfaces.
- Contract.Assert(
+ Debug.Assert(
(RuntimeMethodHandle.GetAttributes(methodHandle) & (MethodAttributes.RTSpecialName | MethodAttributes.Abstract | MethodAttributes.Virtual)) == (MethodAttributes.Abstract | MethodAttributes.Virtual) ||
(RuntimeMethodHandle.GetAttributes(methodHandle) & MethodAttributes.Static) == MethodAttributes.Static ||
RuntimeMethodHandle.GetName(methodHandle).Equals(".ctor") ||
@@ -650,7 +636,7 @@ namespace System
{
if (!RuntimeMethodHandle.MatchesNameHash(methodHandle, filter.GetHashToMatch()))
{
- Contract.Assert(!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)));
+ Debug.Assert(!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)));
continue;
}
@@ -659,13 +645,13 @@ namespace System
}
#region Loop through all methods on the current type
- Contract.Assert(!methodHandle.IsNullHandle());
+ Debug.Assert(!methodHandle.IsNullHandle());
MethodAttributes methodAttributes = RuntimeMethodHandle.GetAttributes(methodHandle);
MethodAttributes methodAccess = methodAttributes & MethodAttributes.MemberAccessMask;
#region Continue if this is a constructor
- Contract.Assert(
+ Debug.Assert(
(RuntimeMethodHandle.GetAttributes(methodHandle) & MethodAttributes.RTSpecialName) == 0 ||
RuntimeMethodHandle.GetName(methodHandle).Equals(".ctor") ||
RuntimeMethodHandle.GetName(methodHandle).Equals(".cctor"));
@@ -697,7 +683,7 @@ namespace System
#region Continue if this is a virtual and is already overridden
if (isVirtual)
{
- Contract.Assert(
+ Debug.Assert(
(methodAttributes & MethodAttributes.Abstract) != 0 ||
(methodAttributes & MethodAttributes.Virtual) != 0 ||
RuntimeMethodHandle.GetDeclaringType(methodHandle) != declaringType);
@@ -714,7 +700,7 @@ namespace System
}
else
{
- Contract.Assert((methodAttributes & (MethodAttributes.Virtual | MethodAttributes.Abstract)) == 0);
+ Debug.Assert((methodAttributes & (MethodAttributes.Virtual | MethodAttributes.Abstract)) == 0);
}
#endregion
@@ -742,7 +728,6 @@ namespace System
return list.ToArray();
}
- [System.Security.SecuritySafeCritical] // auto-generated
private RuntimeConstructorInfo[] PopulateConstructors(Filter filter)
{
if (ReflectedType.IsGenericParameter)
@@ -760,7 +745,7 @@ namespace System
{
if (!RuntimeMethodHandle.MatchesNameHash(methodHandle, filter.GetHashToMatch()))
{
- Contract.Assert(!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)));
+ Debug.Assert(!filter.Match(RuntimeMethodHandle.GetUtf8Name(methodHandle)));
continue;
}
@@ -770,13 +755,13 @@ namespace System
MethodAttributes methodAttributes = RuntimeMethodHandle.GetAttributes(methodHandle);
- Contract.Assert(!methodHandle.IsNullHandle());
+ Debug.Assert(!methodHandle.IsNullHandle());
if ((methodAttributes & MethodAttributes.RTSpecialName) == 0)
continue;
// Constructors should not be virtual or abstract
- Contract.Assert(
+ Debug.Assert(
(methodAttributes & MethodAttributes.Abstract) == 0 &&
(methodAttributes & MethodAttributes.Virtual) == 0);
@@ -799,7 +784,6 @@ namespace System
return list.ToArray();
}
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe RuntimeFieldInfo[] PopulateFields(Filter filter)
{
ListBuilder<RuntimeFieldInfo> list = new ListBuilder<RuntimeFieldInfo>();
@@ -851,7 +835,6 @@ namespace System
return list.ToArray();
}
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe void PopulateRtFields(Filter filter, RuntimeType declaringType, ref ListBuilder<RuntimeFieldInfo> list)
{
IntPtr* pResult = stackalloc IntPtr[64];
@@ -871,7 +854,6 @@ namespace System
}
}
- [System.Security.SecurityCritical] // auto-generated
private unsafe void PopulateRtFields(Filter filter,
IntPtr* ppFieldHandles, int count, RuntimeType declaringType, ref ListBuilder<RuntimeFieldInfo> list)
{
@@ -889,7 +871,7 @@ namespace System
{
if (!RuntimeFieldHandle.MatchesNameHash(runtimeFieldHandle, filter.GetHashToMatch()))
{
- Contract.Assert(!filter.Match(RuntimeFieldHandle.GetUtf8Name(runtimeFieldHandle)));
+ Debug.Assert(!filter.Match(RuntimeFieldHandle.GetUtf8Name(runtimeFieldHandle)));
continue;
}
@@ -897,7 +879,7 @@ namespace System
continue;
}
- Contract.Assert(!runtimeFieldHandle.IsNullHandle());
+ Debug.Assert(!runtimeFieldHandle.IsNullHandle());
FieldAttributes fieldAttributes = RuntimeFieldHandle.GetAttributes(runtimeFieldHandle);
FieldAttributes fieldAccess = fieldAttributes & FieldAttributes.FieldAccessMask;
@@ -925,7 +907,6 @@ namespace System
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe void PopulateLiteralFields(Filter filter, RuntimeType declaringType, ref ListBuilder<RuntimeFieldInfo> list)
{
Contract.Requires(declaringType != null);
@@ -945,8 +926,8 @@ namespace System
for (int i = 0; i < tkFields.Length; i++)
{
int tkField = tkFields[i];
- Contract.Assert(MdToken.IsTokenOfType(tkField, MetadataTokenType.FieldDef));
- Contract.Assert(!MdToken.IsNullToken(tkField));
+ Debug.Assert(MdToken.IsTokenOfType(tkField, MetadataTokenType.FieldDef));
+ Debug.Assert(!MdToken.IsNullToken(tkField));
FieldAttributes fieldAttributes;
scope.GetFieldDefProps(tkField, out fieldAttributes);
@@ -1030,7 +1011,6 @@ namespace System
}
- [System.Security.SecuritySafeCritical] // auto-generated
private RuntimeType[] PopulateInterfaces(Filter filter)
{
ListBuilder<RuntimeType> list = new ListBuilder<RuntimeType>();
@@ -1053,7 +1033,7 @@ namespace System
continue;
}
- Contract.Assert(interfaceType.IsInterface);
+ Debug.Assert(interfaceType.IsInterface);
list.Add(interfaceType);
}
}
@@ -1120,7 +1100,6 @@ namespace System
return list.ToArray();
}
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe RuntimeType[] PopulateNestedClasses(Filter filter)
{
RuntimeType declaringType = ReflectedType;
@@ -1171,7 +1150,6 @@ namespace System
return list.ToArray();
}
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe RuntimeEventInfo[] PopulateEvents(Filter filter)
{
Contract.Requires(ReflectedType != null);
@@ -1204,7 +1182,6 @@ namespace System
return list.ToArray();
}
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe void PopulateEvents(
Filter filter, RuntimeType declaringType, Dictionary<String, RuntimeEventInfo> csEventInfos, ref ListBuilder<RuntimeEventInfo> list)
{
@@ -1224,8 +1201,8 @@ namespace System
int tkEvent = tkEvents[i];
bool isPrivate;
- Contract.Assert(!MdToken.IsNullToken(tkEvent));
- Contract.Assert(MdToken.IsTokenOfType(tkEvent, MetadataTokenType.Event));
+ Debug.Assert(!MdToken.IsNullToken(tkEvent));
+ Debug.Assert(MdToken.IsTokenOfType(tkEvent, MetadataTokenType.Event));
if (filter.RequiresStringComparison())
{
@@ -1265,7 +1242,6 @@ namespace System
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe RuntimePropertyInfo[] PopulateProperties(Filter filter)
{
Contract.Requires(ReflectedType != null);
@@ -1274,7 +1250,7 @@ namespace System
// is called in Populate after this returns.
RuntimeType declaringType = ReflectedType;
- Contract.Assert(declaringType != null);
+ Debug.Assert(declaringType != null);
ListBuilder<RuntimePropertyInfo> list = new ListBuilder<RuntimePropertyInfo>();
@@ -1306,7 +1282,6 @@ namespace System
return list.ToArray();
}
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe void PopulateProperties(
Filter filter,
RuntimeType declaringType,
@@ -1329,7 +1304,7 @@ namespace System
int numVirtuals = RuntimeTypeHandle.GetNumVirtuals(declaringType);
- Contract.Assert((declaringType.IsInterface && usedSlots == null && csPropertyInfos == null) ||
+ Debug.Assert((declaringType.IsInterface && usedSlots == null && csPropertyInfos == null) ||
(!declaringType.IsInterface && usedSlots != null && usedSlots.Length >= numVirtuals));
for (int i = 0; i < tkProperties.Length; i++)
@@ -1337,14 +1312,14 @@ namespace System
int tkProperty = tkProperties[i];
bool isPrivate;
- Contract.Assert(!MdToken.IsNullToken(tkProperty));
- Contract.Assert(MdToken.IsTokenOfType(tkProperty, MetadataTokenType.Property));
+ Debug.Assert(!MdToken.IsNullToken(tkProperty));
+ Debug.Assert(MdToken.IsTokenOfType(tkProperty, MetadataTokenType.Property));
if (filter.RequiresStringComparison())
{
if (!ModuleHandle.ContainsPropertyMatchingHash(declaringModuleHandle, tkProperty, filter.GetHashToMatch()))
{
- Contract.Assert(!filter.Match(declaringType.GetRuntimeModule().MetadataImport.GetName(tkProperty)));
+ Debug.Assert(!filter.Match(declaringType.GetRuntimeModule().MetadataImport.GetName(tkProperty)));
continue;
}
@@ -1389,7 +1364,7 @@ namespace System
if (slot < numVirtuals)
{
- Contract.Assert(associateMethod.IsVirtual);
+ Debug.Assert(associateMethod.IsVirtual);
if (usedSlots[slot] == true)
continue;
else
@@ -1475,7 +1450,7 @@ namespace System
return Populate(name, listType, cacheType);
default:
- Contract.Assert(listType == MemberListType.All);
+ Debug.Assert(listType == MemberListType.All);
if (Volatile.Read(ref m_cacheComplete))
return m_allMembers;
@@ -1514,9 +1489,6 @@ namespace System
private MemberInfoCache<RuntimeEventInfo> m_eventInfoCache;
private static CerHashtable<RuntimeMethodInfo, RuntimeMethodInfo> s_methodInstantiations;
private static Object s_methodInstantiationsLock;
-#if !FEATURE_CORECLR
- private RuntimeConstructorInfo m_serializationCtor;
-#endif
private string m_defaultMemberName;
private Object m_genericCache; // Generic cache for rare scenario specific data. It is used to cache Enum names and values.
#endregion
@@ -1614,7 +1586,6 @@ namespace System
}
}
- [System.Security.SecuritySafeCritical]
internal unsafe string GetNameSpace()
{
// @Optimization - Use ConstructName to populate m_namespace
@@ -1638,14 +1609,13 @@ namespace System
set { m_typeCode = value; }
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe RuntimeType GetEnclosingType()
{
if (m_enclosingType == null)
{
// Use void as a marker of null enclosing type
RuntimeType enclosingType = RuntimeTypeHandle.GetDeclaringType(GetRuntimeType());
- Contract.Assert(enclosingType != typeof(void));
+ Debug.Assert(enclosingType != typeof(void));
m_enclosingType = enclosingType ?? (RuntimeType)typeof(void);
}
@@ -1668,26 +1638,6 @@ namespace System
m_nestedClassesCache = null;
}
-#if !FEATURE_CORECLR
- internal RuntimeConstructorInfo GetSerializationCtor()
- {
- if (m_serializationCtor == null)
- {
- if (s_SICtorParamTypes == null)
- s_SICtorParamTypes = new Type[] { typeof(SerializationInfo), typeof(StreamingContext) };
-
- m_serializationCtor = m_runtimeType.GetConstructor(
- BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
- null,
- CallingConventions.Any,
- s_SICtorParamTypes,
- null) as RuntimeConstructorInfo;
- }
-
- return m_serializationCtor;
- }
-#endif //!FEATURE_CORECLR
-
internal string GetDefaultMemberName()
{
if (m_defaultMemberName == null)
@@ -1719,7 +1669,6 @@ namespace System
#endregion
#region Caches Accessors
- [System.Security.SecurityCritical] // auto-generated
internal MethodInfo GetGenericMethodInfo(RuntimeMethodHandleInternal genericMethod)
{
LoaderAllocator la = RuntimeMethodHandle.GetLoaderAllocator(genericMethod);
@@ -1832,36 +1781,6 @@ namespace System
}
#endregion
-#if FEATURE_REMOTING
- #region Legacy Remoting Cache
- // The size of CachedData is accounted for by BaseObjectWithCachedData in object.h.
- // This member is currently being used by Remoting for caching remoting data. If you
- // need to cache data here, talk to the Remoting team to work out a mechanism, so that
- // both caching systems can happily work together.
- private RemotingTypeCachedData m_cachedData;
-
- internal RemotingTypeCachedData RemotingCache
- {
- get
- {
- // This grabs an internal copy of m_cachedData and uses
- // that instead of looking at m_cachedData directly because
- // the cache may get cleared asynchronously. This prevents
- // us from having to take a lock.
- RemotingTypeCachedData cache = m_cachedData;
- if (cache == null)
- {
- cache = new RemotingTypeCachedData(this);
- RemotingTypeCachedData ret = Interlocked.CompareExchange(ref m_cachedData, cache, null);
- if (ret != null)
- cache = ret;
- }
- return cache;
- }
- }
- #endregion
-#endif //FEATURE_REMOTING
-
#region Static Members
#region Internal
@@ -1869,7 +1788,7 @@ namespace System
ref StackCrawlMark stackMark)
{
if (typeName == null)
- throw new ArgumentNullException("typeName");
+ throw new ArgumentNullException(nameof(typeName));
Contract.EndContractBlock();
return RuntimeTypeHandle.GetTypeByName(
@@ -1886,7 +1805,6 @@ namespace System
return GetMethodBase(null, methodHandle);
}
- [System.Security.SecuritySafeCritical]
internal static MethodBase GetMethodBase(RuntimeType reflectedType, IRuntimeMethodInfo methodHandle)
{
MethodBase retval = RuntimeType.GetMethodBase(reflectedType, methodHandle.Value);
@@ -1894,10 +1812,9 @@ namespace System
return retval;
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe static MethodBase GetMethodBase(RuntimeType reflectedType, RuntimeMethodHandleInternal methodHandle)
{
- Contract.Assert(!methodHandle.IsNullHandle());
+ Debug.Assert(!methodHandle.IsNullHandle());
if (RuntimeMethodHandle.IsDynamicMethod(methodHandle))
{
@@ -2037,13 +1954,11 @@ namespace System
set { Cache.DomainInitialized = value; }
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static FieldInfo GetFieldInfo(IRuntimeFieldInfo fieldHandle)
{
return GetFieldInfo(RuntimeFieldHandle.GetApproxDeclaringType(fieldHandle), fieldHandle);
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static FieldInfo GetFieldInfo(RuntimeType reflectedType, IRuntimeFieldInfo field)
{
RuntimeFieldHandleInternal fieldHandle = field.Value;
@@ -2119,7 +2034,6 @@ namespace System
Environment.GetResourceString("Argument_NotEnoughGenArguments", genericArguments.Length, genericParamters.Length));
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static void ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception e)
{
RuntimeType[] typeContext = null;
@@ -2178,7 +2092,7 @@ namespace System
name = fullname.Substring(nsDelimiter + 1, nameLength);
else
name = "";
- Contract.Assert(fullname.Equals(ns + "." + name));
+ Debug.Assert(fullname.Equals(ns + "." + name));
}
else
{
@@ -2270,7 +2184,7 @@ namespace System
// Most of the plural GetXXX methods allow prefix lookups while the singular GetXXX methods mostly do not.
private static bool FilterApplyPrefixLookup(MemberInfo memberInfo, string name, bool ignoreCase)
{
- Contract.Assert(name != null);
+ Debug.Assert(name != null);
if (ignoreCase)
{
@@ -2376,7 +2290,7 @@ namespace System
Type type, BindingFlags bindingFlags, string name, bool prefixLookup, string ns)
{
Contract.Requires((object)type != null);
- Contract.Assert(type is RuntimeType);
+ Debug.Assert(type is RuntimeType);
bool isPublic = type.IsNestedPublic || type.IsPublic;
bool isStatic = false;
@@ -2461,7 +2375,7 @@ namespace System
{
// If Binding flags did not include varargs we would have filtered this vararg method.
// This Invariant established during callConv check.
- Contract.Assert((callConv & CallingConventions.VarArgs) != 0);
+ Debug.Assert((callConv & CallingConventions.VarArgs) != 0);
}
#endregion
}
@@ -2632,7 +2546,6 @@ namespace System
private RuntimeTypeCache Cache
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
if (m_cache.IsNull())
@@ -2654,7 +2567,7 @@ namespace System
cache = existingCache;
}
- Contract.Assert(cache != null);
+ Debug.Assert(cache != null);
return cache;
}
}
@@ -2681,13 +2594,6 @@ namespace System
{
return Cache.GetDefaultMemberName();
}
-
-#if !FEATURE_CORECLR
- internal RuntimeConstructorInfo GetSerializationCtor()
- {
- return Cache.GetSerializationCtor();
- }
-#endif
#endregion
#region Type Overrides
@@ -2868,7 +2774,6 @@ namespace System
return GetFieldCandidates(null, bindingAttr, false).ToArray();
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override Type[] GetInterfaces()
{
RuntimeType[] candidates = this.Cache.GetInterfaceList(MemberListType.All, null);
@@ -2909,31 +2814,30 @@ namespace System
events.CopyTo(members, i); i += events.Count;
fields.CopyTo(members, i); i += fields.Count;
nestedTypes.CopyTo(members, i); i += nestedTypes.Count;
- Contract.Assert(i == members.Length);
+ Debug.Assert(i == members.Length);
return members;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override InterfaceMapping GetInterfaceMap(Type ifaceType)
{
if (IsGenericParameter)
throw new InvalidOperationException(Environment.GetResourceString("Arg_GenericParameter"));
if ((object)ifaceType == null)
- throw new ArgumentNullException("ifaceType");
+ throw new ArgumentNullException(nameof(ifaceType));
Contract.EndContractBlock();
RuntimeType ifaceRtType = ifaceType as RuntimeType;
if (ifaceRtType == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "ifaceType");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), nameof(ifaceType));
RuntimeTypeHandle ifaceRtTypeHandle = ifaceRtType.GetTypeHandleInternal();
GetTypeHandleInternal().VerifyInterfaceIsImplemented(ifaceRtTypeHandle);
- Contract.Assert(ifaceType.IsInterface); // VerifyInterfaceIsImplemented enforces this invariant
- Contract.Assert(!IsInterface); // VerifyInterfaceIsImplemented enforces this invariant
+ Debug.Assert(ifaceType.IsInterface); // VerifyInterfaceIsImplemented enforces this invariant
+ Debug.Assert(!IsInterface); // VerifyInterfaceIsImplemented enforces this invariant
// 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.
@@ -2954,7 +2858,7 @@ namespace System
// GetMethodBase will convert this to the instantiating/unboxing stub if necessary
MethodBase ifaceMethodBase = RuntimeType.GetMethodBase(ifaceRtType, ifaceRtMethodHandle);
- Contract.Assert(ifaceMethodBase is RuntimeMethodInfo);
+ Debug.Assert(ifaceMethodBase is RuntimeMethodInfo);
im.InterfaceMethods[i] = (MethodInfo)ifaceMethodBase;
// If the slot is -1, then virtual stub dispatch is active.
@@ -2967,7 +2871,7 @@ namespace System
// GetMethodBase will convert this to the instantiating/unboxing stub if necessary
MethodBase rtTypeMethodBase = RuntimeType.GetMethodBase(this, classRtMethodHandle);
// a class may not implement all the methods of an interface (abstract class) so null is a valid value
- Contract.Assert(rtTypeMethodBase == null || rtTypeMethodBase is RuntimeMethodInfo);
+ Debug.Assert(rtTypeMethodBase == null || rtTypeMethodBase is RuntimeMethodInfo);
im.TargetMethods[i] = (MethodInfo)rtTypeMethodBase;
}
@@ -3301,7 +3205,7 @@ namespace System
events.CopyTo(compressMembers, i); i += events.Count;
fields.CopyTo(compressMembers, i); i += fields.Count;
nestedTypes.CopyTo(compressMembers, i); i += nestedTypes.Count;
- Contract.Assert(i == compressMembers.Length);
+ Debug.Assert(i == compressMembers.Length);
return compressMembers;
}
@@ -3348,13 +3252,11 @@ namespace System
return new RuntimeTypeHandle(this);
}
- [System.Security.SecuritySafeCritical]
internal bool IsCollectible()
{
return RuntimeTypeHandle.IsCollectible(GetTypeHandleInternal());
}
- [System.Security.SecuritySafeCritical] // auto-generated
protected override TypeCode GetTypeCodeImpl()
{
TypeCode typeCode = Cache.TypeCode;
@@ -3435,7 +3337,6 @@ namespace System
#endregion
#region Hierarchy
- [System.Security.SecuritySafeCritical] // auto-generated
public override bool IsInstanceOfType(Object o)
{
return RuntimeTypeHandle.IsInstanceOfType(this, o);
@@ -3446,7 +3347,7 @@ namespace System
public override bool IsSubclassOf(Type type)
{
if ((object)type == null)
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
Contract.EndContractBlock();
RuntimeType rtType = type as RuntimeType;
if (rtType == null)
@@ -3519,23 +3420,6 @@ namespace System
return false;
}
-#if !FEATURE_CORECLR
- // Reflexive, symmetric, transitive.
- public override bool IsEquivalentTo(Type other)
- {
- RuntimeType otherRtType = other as RuntimeType;
- if ((object)otherRtType == null)
- return false;
-
- if (otherRtType == this)
- return true;
-
- // It's not worth trying to perform further checks in managed
- // as they would lead to FCalls anyway.
- return RuntimeTypeHandle.IsEquivalentTo(this, otherRtType);
- }
-#endif // FEATURE_CORECLR
-
public override Type BaseType
{
get
@@ -3636,7 +3520,6 @@ namespace System
#endregion
#region Attributes
- [System.Security.SecuritySafeCritical] // auto-generated
protected override TypeAttributes GetAttributeFlagsImpl()
{
return RuntimeTypeHandle.GetAttributes(this);
@@ -3644,7 +3527,6 @@ namespace System
public override Guid GUID
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
Guid result = new Guid ();
@@ -3653,22 +3535,13 @@ namespace System
}
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void GetGUID(ref Guid result);
- [System.Security.SecuritySafeCritical] // auto-generated
protected override bool IsContextfulImpl()
{
- return RuntimeTypeHandle.IsContextful(this);
- }
-
- /*
- protected override bool IsMarshalByRefImpl()
- {
- return GetTypeHandleInternal().IsMarshalByRef();
+ return false;
}
- */
protected override bool IsByRefImpl()
{
@@ -3685,36 +3558,30 @@ namespace System
return RuntimeTypeHandle.IsPointer(this);
}
- [System.Security.SecuritySafeCritical] // auto-generated
protected override bool IsCOMObjectImpl()
{
return RuntimeTypeHandle.IsComObject(this, false);
}
#if FEATURE_COMINTEROP
- [SecuritySafeCritical]
internal override bool IsWindowsRuntimeObjectImpl()
{
return IsWindowsRuntimeObjectType(this);
}
- [SecuritySafeCritical]
internal override bool IsExportedToWindowsRuntimeImpl()
{
return IsTypeExportedToWindowsRuntime(this);
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [SecurityCritical]
private static extern bool IsWindowsRuntimeObjectType(RuntimeType type);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [SecurityCritical]
private static extern bool IsTypeExportedToWindowsRuntime(RuntimeType type);
#endif // FEATURE_COMINTEROP
- [System.Security.SecuritySafeCritical] // auto-generated
internal override bool HasProxyAttributeImpl()
{
return RuntimeTypeHandle.HasProxyAttribute(this);
@@ -3736,16 +3603,6 @@ namespace System
return IsSubclassOf(typeof(ValueType));
}
-#if !FEATURE_CORECLR
- public override bool IsEnum
- {
- get
- {
- return GetBaseType() == RuntimeType.EnumType;
- }
- }
-#endif
-
protected override bool HasElementTypeImpl()
{
return RuntimeTypeHandle.HasElementType(this);
@@ -3753,7 +3610,6 @@ namespace System
public override GenericParameterAttributes GenericParameterAttributes
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
if (!IsGenericParameter)
@@ -3796,7 +3652,6 @@ namespace System
return RuntimeTypeHandle.IsArray(this);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override int GetArrayRank()
{
if (!IsArrayImpl())
@@ -3828,7 +3683,6 @@ namespace System
return retVal;
}
- [SecuritySafeCritical]
public override Array GetEnumValues()
{
if (!IsEnum)
@@ -3862,7 +3716,7 @@ namespace System
public override bool IsEnumDefined(object value)
{
if (value == null)
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
Contract.EndContractBlock();
// Check if both of them are of the same type
@@ -3909,13 +3763,13 @@ namespace System
public override string GetEnumName(object value)
{
if (value == null)
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
Contract.EndContractBlock();
Type valueType = value.GetType();
if (!(valueType.IsEnum || IsIntegerType(valueType)))
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnumBaseTypeOrEnum"), "value");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnumBaseTypeOrEnum"), nameof(value));
ulong ulValue = Enum.ToUInt64(value);
@@ -3939,11 +3793,10 @@ namespace System
return types;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override Type MakeGenericType(Type[] instantiation)
{
if (instantiation == null)
- throw new ArgumentNullException("instantiation");
+ throw new ArgumentNullException(nameof(instantiation));
Contract.EndContractBlock();
RuntimeType[] instantiationRuntimeType = new RuntimeType[instantiation.Length];
@@ -3953,7 +3806,7 @@ namespace System
Environment.GetResourceString("Arg_NotGenericTypeDefinition", this));
if (GetGenericArguments().Length != instantiation.Length)
- throw new ArgumentException(Environment.GetResourceString("Argument_GenericArgsCount"), "instantiation");
+ throw new ArgumentException(Environment.GetResourceString("Argument_GenericArgsCount"), nameof(instantiation));
for (int i = 0; i < instantiation.Length; i ++)
{
@@ -4055,7 +3908,6 @@ namespace System
#endregion
#region Misc
- [System.Security.SecuritySafeCritical] // auto-generated
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(); }
@@ -4069,7 +3921,6 @@ namespace System
}
public override StructLayoutAttribute StructLayoutAttribute
{
- [System.Security.SecuritySafeCritical] // overrides transparent public member
get
{
return (StructLayoutAttribute)StructLayoutAttribute.GetCustomAttribute(this);
@@ -4091,15 +3942,12 @@ namespace System
BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty;
private static RuntimeType s_typedRef = (RuntimeType)typeof(TypedReference);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static private extern bool CanValueSpecialCast(RuntimeType valueType, RuntimeType targetType);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static private extern Object AllocateValueType(RuntimeType type, object value, bool fForceTypeChange);
- [System.Security.SecuritySafeCritical] // auto-generated
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.
@@ -4107,26 +3955,9 @@ namespace System
{
// Since this cannot be a generic parameter, we use RuntimeTypeHandle.IsValueType here
// because it is faster than RuntimeType.IsValueType
- Contract.Assert(!IsGenericParameter);
-
- Type type = null;
-
-#if FEATURE_REMOTING
- // For the remoting objects Object.GetType goes through proxy. Avoid the proxy call and just get
- // the type directly. It is necessary to support proxies that do not handle GetType.
- RealProxy realProxy = System.Runtime.Remoting.RemotingServices.GetRealProxy(value);
+ Debug.Assert(!IsGenericParameter);
- if (realProxy != null)
- {
- type = realProxy.GetProxiedType();
- }
- else
- {
- type = value.GetType();
- }
-#else
- type = value.GetType();
-#endif
+ Type type = value.GetType();
if (!Object.ReferenceEquals(type, this) && RuntimeTypeHandle.IsValueType(this))
{
@@ -4186,7 +4017,6 @@ namespace System
}
// Factored out of CheckValue to reduce code complexity.
- [System.Security.SecurityCritical]
private Object TryChangeType(Object value, Binder binder, CultureInfo culture, bool needsSpecialCast)
{
if (binder != null && binder != Type.DefaultBinder)
@@ -4245,7 +4075,6 @@ namespace System
}
#if FEATURE_COMINTEROP
- [System.Security.SecuritySafeCritical] // auto-generated
#endif
[DebuggerStepThroughAttribute]
[Diagnostics.DebuggerHidden]
@@ -4260,7 +4089,7 @@ namespace System
#region Preconditions
if ((bindingFlags & InvocationMask) == 0)
// "Must specify binding flags describing the invoke operation required."
- throw new ArgumentException(Environment.GetResourceString("Arg_NoAccessSpec"),"bindingFlags");
+ throw new ArgumentException(Environment.GetResourceString("Arg_NoAccessSpec"),nameof(bindingFlags));
// Provide a default binding mask if none is provided
if ((bindingFlags & MemberBindingMask) == 0)
@@ -4278,13 +4107,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"), "namedParams");
+ throw new ArgumentException(Environment.GetResourceString("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"), "namedParams");
+ throw new ArgumentException(Environment.GetResourceString("Arg_NamedParamTooBig"), nameof(namedParams));
}
}
#endregion
@@ -4295,31 +4124,28 @@ namespace System
{
#region Preconditions
if ((bindingFlags & ClassicBindingMask) == 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_COMAccess"), "bindingFlags");
+ throw new ArgumentException(Environment.GetResourceString("Arg_COMAccess"), nameof(bindingFlags));
if ((bindingFlags & BindingFlags.GetProperty) != 0 && (bindingFlags & ClassicBindingMask & ~(BindingFlags.GetProperty | BindingFlags.InvokeMethod)) != 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_PropSetGet"), "bindingFlags");
+ throw new ArgumentException(Environment.GetResourceString("Arg_PropSetGet"), nameof(bindingFlags));
if ((bindingFlags & BindingFlags.InvokeMethod) != 0 && (bindingFlags & ClassicBindingMask & ~(BindingFlags.GetProperty | BindingFlags.InvokeMethod)) != 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_PropSetInvoke"), "bindingFlags");
+ throw new ArgumentException(Environment.GetResourceString("Arg_PropSetInvoke"), nameof(bindingFlags));
if ((bindingFlags & BindingFlags.SetProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.SetProperty) != 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_COMPropSetPut"), "bindingFlags");
+ throw new ArgumentException(Environment.GetResourceString("Arg_COMPropSetPut"), nameof(bindingFlags));
if ((bindingFlags & BindingFlags.PutDispProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.PutDispProperty) != 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_COMPropSetPut"), "bindingFlags");
+ throw new ArgumentException(Environment.GetResourceString("Arg_COMPropSetPut"), nameof(bindingFlags));
if ((bindingFlags & BindingFlags.PutRefDispProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.PutRefDispProperty) != 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_COMPropSetPut"), "bindingFlags");
+ throw new ArgumentException(Environment.GetResourceString("Arg_COMPropSetPut"), nameof(bindingFlags));
#endregion
-#if FEATURE_REMOTING
- if(!RemotingServices.IsTransparentProxy(target))
-#endif
{
#region Non-TransparentProxy case
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
bool[] isByRef = modifiers == null ? null : modifiers[0].IsByRefArray;
@@ -4329,14 +4155,6 @@ namespace System
return InvokeDispMethod(name, bindingFlags, target, providedArgs, isByRef, lcid, namedParams);
#endregion
}
-#if FEATURE_REMOTING
- else
- {
- #region TransparentProxy case
- return ((MarshalByRefObject)target).InvokeMember(name, bindingFlags, binder, providedArgs, modifiers, culture, namedParams);
- #endregion
- }
-#endif // FEATURE_REMOTING
}
#endif // FEATURE_COMINTEROP && FEATURE_USE_LCID
#endregion
@@ -4344,7 +4162,7 @@ namespace System
#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"),"namedParams");
+ throw new ArgumentException(Environment.GetResourceString("Arg_NamedParamNull"),nameof(namedParams));
#endregion
int argCnt = (providedArgs != null) ? providedArgs.Length : 0;
@@ -4361,7 +4179,7 @@ namespace System
{
if ((bindingFlags & BindingFlags.CreateInstance) != 0 && (bindingFlags & BinderNonCreateInstance) != 0)
// "Can not specify both CreateInstance and another access type."
- throw new ArgumentException(Environment.GetResourceString("Arg_CreatInstAccess"),"bindingFlags");
+ throw new ArgumentException(Environment.GetResourceString("Arg_CreatInstAccess"),nameof(bindingFlags));
return Activator.CreateInstance(this, bindingFlags, binder, providedArgs, culture);
}
@@ -4373,7 +4191,7 @@ namespace System
#region Name
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (name.Length == 0 || name.Equals(@"[DISPID=0]"))
{
@@ -4398,26 +4216,26 @@ namespace System
{
if (IsSetField)
// "Can not specify both Get and Set on a field."
- throw new ArgumentException(Environment.GetResourceString("Arg_FldSetGet"),"bindingFlags");
+ throw new ArgumentException(Environment.GetResourceString("Arg_FldSetGet"),nameof(bindingFlags));
if ((bindingFlags & BindingFlags.SetProperty) != 0)
// "Can not specify both GetField and SetProperty."
- throw new ArgumentException(Environment.GetResourceString("Arg_FldGetPropSet"),"bindingFlags");
+ throw new ArgumentException(Environment.GetResourceString("Arg_FldGetPropSet"),nameof(bindingFlags));
}
else
{
- Contract.Assert(IsSetField);
+ Debug.Assert(IsSetField);
if (providedArgs == null)
- throw new ArgumentNullException("providedArgs");
+ throw new ArgumentNullException(nameof(providedArgs));
if ((bindingFlags & BindingFlags.GetProperty) != 0)
// "Can not specify both SetField and GetProperty."
- throw new ArgumentException(Environment.GetResourceString("Arg_FldSetPropGet"),"bindingFlags");
+ throw new ArgumentException(Environment.GetResourceString("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"),"bindingFlags");
+ throw new ArgumentException(Environment.GetResourceString("Arg_FldSetInvoke"),nameof(bindingFlags));
}
#endregion
@@ -4425,7 +4243,7 @@ namespace System
FieldInfo selFld = null;
FieldInfo[] flds = GetMember(name, MemberTypes.Field, bindingFlags) as FieldInfo[];
- Contract.Assert(flds != null);
+ Debug.Assert(flds != null);
if (flds.Length == 1)
{
@@ -4491,7 +4309,7 @@ namespace System
{
#region Get the field value
if (argCnt != 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_FldGetArgErr"),"bindingFlags");
+ throw new ArgumentException(Environment.GetResourceString("Arg_FldGetArgErr"),nameof(bindingFlags));
return selFld.GetValue(target);
#endregion
@@ -4500,7 +4318,7 @@ namespace System
{
#region Set the field Value
if (argCnt != 1)
- throw new ArgumentException(Environment.GetResourceString("Arg_FldSetArgErr"),"bindingFlags");
+ throw new ArgumentException(Environment.GetResourceString("Arg_FldSetArgErr"),nameof(bindingFlags));
selFld.SetValue(target,providedArgs[0],bindingFlags,binder,culture);
@@ -4548,19 +4366,19 @@ namespace System
#region Preconditions
if (isGetProperty)
{
- Contract.Assert(!IsSetField);
+ Debug.Assert(!IsSetField);
if (isSetProperty)
- throw new ArgumentException(Environment.GetResourceString("Arg_PropSetGet"), "bindingFlags");
+ throw new ArgumentException(Environment.GetResourceString("Arg_PropSetGet"), nameof(bindingFlags));
}
else
{
- Contract.Assert(isSetProperty);
+ Debug.Assert(isSetProperty);
- Contract.Assert(!IsGetField);
+ Debug.Assert(!IsGetField);
if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_PropSetInvoke"), "bindingFlags");
+ throw new ArgumentException(Environment.GetResourceString("Arg_PropSetInvoke"), nameof(bindingFlags));
}
#endregion
}
@@ -4579,7 +4397,7 @@ namespace System
for(int i = 0; i < semiFinalists.Length; i ++)
{
MethodInfo semiFinalist = semiFinalists[i];
- Contract.Assert(semiFinalist != null);
+ Debug.Assert(semiFinalist != null);
if (!FilterApplyMethodInfo((RuntimeMethodInfo)semiFinalist, bindingFlags, CallingConventions.Any, new Type[argCnt]))
continue;
@@ -4602,7 +4420,7 @@ namespace System
if (results != null)
{
- Contract.Assert(results.Count > 1);
+ Debug.Assert(results.Count > 1);
finalists = new MethodInfo[results.Count];
results.CopyTo(finalists);
}
@@ -4610,7 +4428,7 @@ namespace System
}
#endregion
- Contract.Assert(finalists == null || finalist != null);
+ Debug.Assert(finalists == null || finalist != null);
#region BindingFlags.GetProperty or BindingFlags.SetProperty
if (finalist == null && isGetProperty || isSetProperty)
@@ -4656,7 +4474,7 @@ namespace System
if (results != null)
{
- Contract.Assert(results.Count > 1);
+ Debug.Assert(results.Count > 1);
finalists = new MethodInfo[results.Count];
results.CopyTo(finalists);
}
@@ -4726,18 +4544,6 @@ namespace System
return RuntimeHelpers.GetHashCode(this);
}
-#if !FEATURE_CORECLR
- public static bool operator ==(RuntimeType left, RuntimeType right)
- {
- return object.ReferenceEquals(left, right);
- }
-
- public static bool operator !=(RuntimeType left, RuntimeType right)
- {
- return !object.ReferenceEquals(left, right);
- }
-#endif // !FEATURE_CORECLR
-
public override String ToString()
{
return GetCachedName(TypeNameKind.ToString);
@@ -4752,11 +4558,10 @@ namespace System
#endregion
#region ISerializable
- [System.Security.SecurityCritical] // auto-generated
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info==null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
UnitySerializationHolder.GetUnitySerializationInfo(info, this);
@@ -4764,38 +4569,35 @@ namespace System
#endregion
#region ICustomAttributeProvider
- [System.Security.SecuritySafeCritical] // auto-generated
public override Object[] GetCustomAttributes(bool inherit)
{
return CustomAttribute.GetCustomAttributes(this, RuntimeType.ObjectType, inherit);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
{
if ((object)attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
Contract.EndContractBlock();
RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType, inherit);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override bool IsDefined(Type attributeType, bool inherit)
{
if ((object)attributeType == null)
- throw new ArgumentNullException("attributeType");
+ throw new ArgumentNullException(nameof(attributeType));
Contract.EndContractBlock();
RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
return CustomAttribute.IsDefined(this, attributeRuntimeType, inherit);
}
@@ -4887,7 +4689,6 @@ namespace System
public override int MetadataToken
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
return RuntimeTypeHandle.GetToken(this);
@@ -4915,7 +4716,6 @@ namespace System
throw new NotSupportedException(Environment.GetResourceString("Acc_CreateVoid"));
}
- [System.Security.SecurityCritical] // auto-generated
internal Object CreateInstanceImpl(
BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, ref StackCrawlMark stackMark)
{
@@ -4923,170 +4723,117 @@ namespace System
Object server = null;
- try
- {
- try
- {
- // Store the activation attributes in thread local storage.
- // These attributes are later picked up by specialized
- // activation services like remote activation services to
- // influence the activation.
-#if FEATURE_REMOTING
- if(null != activationAttributes)
- {
- ActivationServices.PushActivationAttributes(this, activationAttributes);
- }
-#endif
-
- if (args == null)
- args = EmptyArray<Object>.Value;
+ if (args == null)
+ args = EmptyArray<Object>.Value;
- int argCnt = args.Length;
+ int argCnt = args.Length;
- // Without a binder we need to do use the default binder...
- if (binder == null)
- binder = DefaultBinder;
+ // Without a binder we need to do use the default binder...
+ if (binder == null)
+ binder = DefaultBinder;
+
+ // 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))
+ {
+ server = CreateInstanceDefaultCtor((bindingAttr & BindingFlags.NonPublic) == 0 , false, true, ref stackMark);
+ }
+ else
+ {
+ ConstructorInfo[] candidates = GetConstructors(bindingAttr);
+ List<MethodBase> matches = new List<MethodBase>(candidates.Length);
- // 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))
+ // We cannot use Type.GetTypeArray here because some of the args might be null
+ Type[] argsType = new Type[argCnt];
+ for (int i = 0; i < argCnt; i++)
+ {
+ if (args[i] != null)
{
- server = CreateInstanceDefaultCtor((bindingAttr & BindingFlags.NonPublic) == 0 , false, true, ref stackMark);
+ argsType[i] = args[i].GetType();
}
- else
- {
- ConstructorInfo[] candidates = GetConstructors(bindingAttr);
- List<MethodBase> matches = new List<MethodBase>(candidates.Length);
-
- // We cannot use Type.GetTypeArray here because some of the args might be null
- Type[] argsType = new Type[argCnt];
- for (int i = 0; i < argCnt; i++)
- {
- if (args[i] != null)
- {
- argsType[i] = args[i].GetType();
- }
- }
-
- for(int i = 0; i < candidates.Length; i ++)
- {
- if (FilterApplyConstructorInfo((RuntimeConstructorInfo)candidates[i], bindingAttr, CallingConventions.Any, argsType))
- matches.Add(candidates[i]);
- }
+ }
- MethodBase[] cons = new MethodBase[matches.Count];
- matches.CopyTo(cons);
- if (cons != null && cons.Length == 0)
- cons = null;
+ for(int i = 0; i < candidates.Length; i ++)
+ {
+ if (FilterApplyConstructorInfo((RuntimeConstructorInfo)candidates[i], bindingAttr, CallingConventions.Any, argsType))
+ matches.Add(candidates[i]);
+ }
- if (cons == null)
- {
- // Null out activation attributes before throwing exception
-#if FEATURE_REMOTING
- if(null != activationAttributes)
- {
- ActivationServices.PopActivationAttributes(this);
- activationAttributes = null;
- }
-#endif
- throw new MissingMethodException(Environment.GetResourceString("MissingConstructor_Name", FullName));
- }
+ MethodBase[] cons = new MethodBase[matches.Count];
+ matches.CopyTo(cons);
+ if (cons != null && cons.Length == 0)
+ cons = null;
- MethodBase invokeMethod;
- Object state = null;
+ if (cons == null)
+ {
+ throw new MissingMethodException(Environment.GetResourceString("MissingConstructor_Name", FullName));
+ }
- try
- {
- invokeMethod = binder.BindToMethod(bindingAttr, cons, ref args, null, culture, null, out state);
- }
- catch (MissingMethodException) { invokeMethod = null; }
+ MethodBase invokeMethod;
+ Object state = null;
- if (invokeMethod == null)
- {
-#if FEATURE_REMOTING
- // Null out activation attributes before throwing exception
- if(null != activationAttributes)
- {
- ActivationServices.PopActivationAttributes(this);
- activationAttributes = null;
- }
-#endif
- throw new MissingMethodException(Environment.GetResourceString("MissingConstructor_Name", FullName));
- }
+ try
+ {
+ invokeMethod = binder.BindToMethod(bindingAttr, cons, ref args, null, culture, null, out state);
+ }
+ catch (MissingMethodException) { invokeMethod = null; }
- // If we're creating a delegate, we're about to call a
- // constructor taking an integer to represent a target
- // method. Since this is very difficult (and expensive)
- // to verify, we're just going to demand UnmanagedCode
- // permission before allowing this. Partially trusted
- // clients can instead use Delegate.CreateDelegate,
- // which allows specification of the target method via
- // name or MethodInfo.
- //if (isDelegate)
- if (RuntimeType.DelegateType.IsAssignableFrom(invokeMethod.DeclaringType))
- {
-#if FEATURE_CORECLR
- // In CoreCLR, CAS is not exposed externally. So what we really are looking
- // for is to see if the external caller of this API is transparent or not.
- // We get that information from the fact that a Demand will succeed only if
- // the external caller is not transparent.
- try
- {
+ if (invokeMethod == null)
+ {
+ throw new MissingMethodException(Environment.GetResourceString("MissingConstructor_Name", FullName));
+ }
+
+ // If we're creating a delegate, we're about to call a
+ // constructor taking an integer to represent a target
+ // method. Since this is very difficult (and expensive)
+ // to verify, we're just going to demand UnmanagedCode
+ // permission before allowing this. Partially trusted
+ // clients can instead use Delegate.CreateDelegate,
+ // which allows specification of the target method via
+ // name or MethodInfo.
+ //if (isDelegate)
+ if (RuntimeType.DelegateType.IsAssignableFrom(invokeMethod.DeclaringType))
+ {
+ // In CoreCLR, CAS is not exposed externally. So what we really are looking
+ // for is to see if the external caller of this API is transparent or not.
+ // We get that information from the fact that a Demand will succeed only if
+ // the external caller is not transparent.
+ try
+ {
#pragma warning disable 618
- new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
+ new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
#pragma warning restore 618
- }
- catch
- {
- throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("NotSupported_DelegateCreationFromPT")));
- }
-#else // FEATURE_CORECLR
- new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
-#endif // FEATURE_CORECLR
- }
-
- if (invokeMethod.GetParametersNoCopy().Length == 0)
- {
- if (args.Length != 0)
- {
-
- Contract.Assert((invokeMethod.CallingConvention & CallingConventions.VarArgs) ==
- CallingConventions.VarArgs);
- throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture,
- Environment.GetResourceString("NotSupported_CallToVarArg")));
- }
-
- // fast path??
- server = Activator.CreateInstance(this, true);
- }
- else
- {
- server = ((ConstructorInfo)invokeMethod).Invoke(bindingAttr, binder, args, culture);
- if (state != null)
- binder.ReorderArgumentArray(ref args, state);
- }
}
- }
- finally
+ catch
+ {
+ throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("NotSupported_DelegateCreationFromPT")));
+ }
+ }
+
+ if (invokeMethod.GetParametersNoCopy().Length == 0)
{
-#if FEATURE_REMOTING
- // Reset the TLS to null
- if(null != activationAttributes)
+ if (args.Length != 0)
{
- ActivationServices.PopActivationAttributes(this);
- activationAttributes = null;
+
+ Debug.Assert((invokeMethod.CallingConvention & CallingConventions.VarArgs) ==
+ CallingConventions.VarArgs);
+ throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture,
+ Environment.GetResourceString("NotSupported_CallToVarArg")));
}
-#endif
+
+ // fast path??
+ server = Activator.CreateInstance(this, true);
+ }
+ else
+ {
+ server = ((ConstructorInfo)invokeMethod).Invoke(bindingAttr, binder, args, culture);
+ if (state != null)
+ binder.ReorderArgumentArray(ref args, state);
}
}
- catch (Exception)
- {
- throw;
- }
-
- //Console.WriteLine(server);
- return server;
+
+ return server;
}
// the cache entry
@@ -5103,7 +4850,6 @@ namespace System
// Lazy initialization was performed
internal volatile bool m_bFullyInitialized;
- [System.Security.SecurityCritical]
internal ActivatorCacheEntry(RuntimeType t, RuntimeMethodHandleInternal rmh, bool bNeedSecurityCheck)
{
m_type = t;
@@ -5137,12 +4883,11 @@ namespace System
delegateCtorInfo = ctorInfo; // this assignment should be last
}
- [System.Security.SecuritySafeCritical] // auto-generated
private void InitializeCacheEntry(ActivatorCacheEntry ace)
{
if (!ace.m_type.IsValueType)
{
- Contract.Assert(!ace.m_hCtorMethodHandle.IsNullHandle(), "Expected the default ctor method handle for a reference type.");
+ Debug.Assert(!ace.m_hCtorMethodHandle.IsNullHandle(), "Expected the default ctor method handle for a reference type.");
if (delegateCtorInfo == null)
InitializeDelegateCreator();
@@ -5184,7 +4929,6 @@ namespace System
private static volatile ActivatorCache s_ActivatorCache;
// the slow path of CreateInstanceDefaultCtor
- [System.Security.SecuritySafeCritical] // auto-generated
internal Object CreateInstanceSlow(bool publicOnly, bool skipCheckThis, bool fillCache, ref StackCrawlMark stackMark)
{
RuntimeMethodHandleInternal runtime_ctor = default(RuntimeMethodHandleInternal);
@@ -5212,9 +4956,7 @@ namespace System
bCanBeCached = false;
}
#endif
-#if FEATURE_CORECLR
bSecurityCheckOff = true; // CoreCLR does not use security at all.
-#endif
Object instance = RuntimeTypeHandle.CreateInstance(this, publicOnly, bSecurityCheckOff, ref bCanBeCached, ref runtime_ctor, ref bNeedSecurityCheck);
@@ -5238,7 +4980,6 @@ namespace System
// Helper to invoke the default (parameterless) ctor.
// fillCache is set in the SL2/3 compat mode or when called from Marshal.PtrToStructure.
- [System.Security.SecuritySafeCritical] // auto-generated
[DebuggerStepThroughAttribute]
[Diagnostics.DebuggerHidden]
internal Object CreateInstanceDefaultCtor(bool publicOnly, bool skipCheckThis, bool fillCache, ref StackCrawlMark stackMark)
@@ -5265,16 +5006,10 @@ namespace System
Object instance = RuntimeTypeHandle.Allocate(this);
// if m_ctor is null, this type doesn't have a default ctor
- Contract.Assert(ace.m_ctor != null || this.IsValueType);
+ Debug.Assert(ace.m_ctor != null || this.IsValueType);
if (ace.m_ctor != null)
{
-#if !FEATURE_CORECLR
- // Perform security checks if needed
- if (ace.m_bNeedSecurityCheck)
- RuntimeMethodHandle.PerformSecurityCheck(instance, ace.m_hCtorMethodHandle, this, (uint)INVOCATION_FLAGS.INVOCATION_FLAGS_CONSTRUCTOR_INVOKE);
-#endif
-
// Call ctor (value types wont have any)
try
{
@@ -5296,7 +5031,6 @@ namespace System
Cache.InvalidateCachedNestedType();
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal bool IsGenericCOMObjectImpl()
{
return RuntimeTypeHandle.IsComObject(this, true);
@@ -5304,27 +5038,22 @@ namespace System
#endregion
#region Legacy Static Internal
- [System.Security.SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern Object _CreateEnum(RuntimeType enumType, long value);
- [System.Security.SecuritySafeCritical] // auto-generated
internal static Object CreateEnum(RuntimeType enumType, long value)
{
return _CreateEnum(enumType, value);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern Object InvokeDispMethod(
String name, BindingFlags invokeAttr, Object target, Object[] args,
bool[] byrefModifiers, int culture, String[] namedParameters);
#if FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern Type GetTypeFromProgIDImpl(String progID, String server, bool throwOnError);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern Type GetTypeFromCLSIDImpl(Guid clsid, String server, bool throwOnError);
#else // FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
@@ -5342,213 +5071,6 @@ namespace System
#endregion
#region COM
-#if FEATURE_COMINTEROP && FEATURE_REMOTING
- [System.Security.SecuritySafeCritical] // auto-generated
- private Object ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, int[] aWrapperTypes, ref MessageData msgData)
- {
- ParameterModifier[] aParamMod = null;
- Object ret = null;
-
- // Allocate a new message
- Message reqMsg = new Message();
- reqMsg.InitFields(msgData);
-
- // Retrieve the required information from the message object.
- MethodInfo meth = (MethodInfo)reqMsg.GetMethodBase();
- Object[] aArgs = reqMsg.Args;
- int cArgs = aArgs.Length;
-
- // Retrieve information from the method we are invoking on.
- ParameterInfo[] aParams = meth.GetParametersNoCopy();
-
- // If we have arguments, then set the byref flags to true for byref arguments.
- // We also wrap the arguments that require wrapping.
- if (cArgs > 0)
- {
- ParameterModifier paramMod = new ParameterModifier(cArgs);
- for (int i = 0; i < cArgs; i++)
- {
- if (aParams[i].ParameterType.IsByRef)
- paramMod[i] = true;
- }
-
- aParamMod = new ParameterModifier[1];
- aParamMod[0] = paramMod;
-
- if (aWrapperTypes != null)
- WrapArgsForInvokeCall(aArgs, aWrapperTypes);
- }
-
- // If the method has a void return type, then set the IgnoreReturn binding flag.
- if (Object.ReferenceEquals(meth.ReturnType, typeof(void)))
- flags |= BindingFlags.IgnoreReturn;
-
- try
- {
- // Invoke the method using InvokeMember().
- ret = InvokeMember(memberName, flags, null, target, aArgs, aParamMod, null, null);
- }
- catch (TargetInvocationException e)
- {
- // For target invocation exceptions, we need to unwrap the inner exception and
- // re-throw it.
- throw e.InnerException;
- }
-
- // Convert each byref argument that is not of the proper type to
- // the parameter type using the OleAutBinder.
- for (int i = 0; i < cArgs; i++)
- {
- if (aParamMod[0][i] && aArgs[i] != null)
- {
- // The parameter is byref.
- Type paramType = aParams[i].ParameterType.GetElementType();
- if (!Object.ReferenceEquals(paramType, aArgs[i].GetType()))
- aArgs[i] = ForwardCallBinder.ChangeType(aArgs[i], paramType, null);
- }
- }
-
- // If the return type is not of the proper type, then convert it
- // to the proper type using the OleAutBinder.
- if (ret != null)
- {
- Type retType = meth.ReturnType;
- if (!Object.ReferenceEquals(retType, ret.GetType()))
- ret = ForwardCallBinder.ChangeType(ret, retType, null);
- }
-
- // Propagate the out parameters
- RealProxy.PropagateOutParameters(reqMsg, aArgs, ret);
-
- // Return the value returned by the InvokeMember call.
- return ret;
- }
-
- [SecuritySafeCritical]
- private void WrapArgsForInvokeCall(Object[] aArgs, int[] aWrapperTypes)
- {
- int cArgs = aArgs.Length;
- for (int i = 0; i < cArgs; i++)
- {
- if (aWrapperTypes[i] == 0)
- continue;
-
- if (((DispatchWrapperType)aWrapperTypes[i] & DispatchWrapperType.SafeArray) != 0)
- {
- Type wrapperType = null;
- bool isString = false;
-
- // Determine the type of wrapper to use.
- switch ((DispatchWrapperType)aWrapperTypes[i] & ~DispatchWrapperType.SafeArray)
- {
- case DispatchWrapperType.Unknown:
- wrapperType = typeof(UnknownWrapper);
- break;
- case DispatchWrapperType.Dispatch:
- wrapperType = typeof(DispatchWrapper);
- break;
- case DispatchWrapperType.Error:
- wrapperType = typeof(ErrorWrapper);
- break;
- case DispatchWrapperType.Currency:
- wrapperType = typeof(CurrencyWrapper);
- break;
- case DispatchWrapperType.BStr:
- wrapperType = typeof(BStrWrapper);
- isString = true;
- break;
- default:
- Contract.Assert(false, "[RuntimeType.WrapArgsForInvokeCall]Invalid safe array wrapper type specified.");
- break;
- }
-
- // Allocate the new array of wrappers.
- Array oldArray = (Array)aArgs[i];
- int numElems = oldArray.Length;
- Object[] newArray = (Object[])Array.UnsafeCreateInstance(wrapperType, numElems);
-
- // Retrieve the ConstructorInfo for the wrapper type.
- ConstructorInfo wrapperCons;
- if(isString)
- {
- wrapperCons = wrapperType.GetConstructor(new Type[] {typeof(String)});
- }
- else
- {
- wrapperCons = wrapperType.GetConstructor(new Type[] {typeof(Object)});
- }
-
- // Wrap each of the elements of the array.
- for (int currElem = 0; currElem < numElems; currElem++)
- {
- if(isString)
- {
- newArray[currElem] = wrapperCons.Invoke(new Object[] {(String)oldArray.GetValue(currElem)});
- }
- else
- {
- newArray[currElem] = wrapperCons.Invoke(new Object[] {oldArray.GetValue(currElem)});
- }
- }
-
- // Update the argument.
- aArgs[i] = newArray;
- }
- else
- {
- // Determine the wrapper to use and then wrap the argument.
- switch ((DispatchWrapperType)aWrapperTypes[i])
- {
- case DispatchWrapperType.Unknown:
- aArgs[i] = new UnknownWrapper(aArgs[i]);
- break;
- case DispatchWrapperType.Dispatch:
- aArgs[i] = new DispatchWrapper(aArgs[i]);
- break;
- case DispatchWrapperType.Error:
- aArgs[i] = new ErrorWrapper(aArgs[i]);
- break;
- case DispatchWrapperType.Currency:
- aArgs[i] = new CurrencyWrapper(aArgs[i]);
- break;
- case DispatchWrapperType.BStr:
- aArgs[i] = new BStrWrapper((String)aArgs[i]);
- break;
- default:
- Contract.Assert(false, "[RuntimeType.WrapArgsForInvokeCall]Invalid wrapper type specified.");
- break;
- }
- }
- }
- }
-
- private OleAutBinder ForwardCallBinder
- {
- get
- {
- // Synchronization is not required.
- if (s_ForwardCallBinder == null)
- s_ForwardCallBinder = new OleAutBinder();
-
- return s_ForwardCallBinder;
- }
- }
-
- [Flags]
- private enum DispatchWrapperType : int
- {
- // This enum must stay in sync with the DispatchWrapperType enum defined in MLInfo.h
- Unknown = 0x00000001,
- Dispatch = 0x00000002,
- Record = 0x00000004,
- Error = 0x00000008,
- Currency = 0x00000010,
- BStr = 0x00000020,
- SafeArray = 0x00010000
- }
-
- private static volatile OleAutBinder s_ForwardCallBinder;
-#endif // FEATURE_COMINTEROP && FEATURE_REMOTING
#endregion
}
@@ -5580,21 +5102,17 @@ namespace System
#region Library
internal unsafe struct Utf8String
{
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern unsafe bool EqualsCaseSensitive(void* szLhs, void* szRhs, int cSz);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern unsafe bool EqualsCaseInsensitive(void* szLhs, void* szRhs, int cSz);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern unsafe uint HashCaseInsensitive(void* sz, int cSz);
- [System.Security.SecurityCritical] // auto-generated
private static int GetUtf8StringByteLength(void* pUtf8String)
{
int len = 0;
@@ -5613,11 +5131,9 @@ namespace System
return len;
}
- [SecurityCritical]
private void* m_pStringHeap; // This is the raw UTF8 string.
private int m_StringHeapByteLength;
- [System.Security.SecurityCritical] // auto-generated
internal Utf8String(void* pStringHeap)
{
m_pStringHeap = pStringHeap;
@@ -5631,14 +5147,12 @@ namespace System
}
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe Utf8String(void* pUtf8String, int cUtf8String)
{
m_pStringHeap = pUtf8String;
m_StringHeapByteLength = cUtf8String;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe bool Equals(Utf8String s)
{
if (m_pStringHeap == null)
@@ -5652,7 +5166,6 @@ namespace System
return false;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe bool EqualsCaseInsensitive(Utf8String s)
{
if (m_pStringHeap == null)
@@ -5666,13 +5179,11 @@ namespace System
return false;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe uint HashCaseInsensitive()
{
return Utf8String.HashCaseInsensitive(m_pStringHeap, m_StringHeapByteLength);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override string ToString()
{
unsafe
@@ -5750,7 +5261,7 @@ namespace System.Reflection
}
else
{
- Contract.Assert(!hit.Equals(key), "Key was already in CerHashtable! Potential race condition (or bug) in the Reflection cache?");
+ Debug.Assert(!hit.Equals(key), "Key was already in CerHashtable! Potential race condition (or bug) in the Reflection cache?");
index++;
if (index >= keys.Length)
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/AsyncMethodBuilder.cs b/src/mscorlib/src/System/Runtime/CompilerServices/AsyncMethodBuilder.cs
index 05850605b8..6a16462383 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/AsyncMethodBuilder.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/AsyncMethodBuilder.cs
@@ -32,7 +32,6 @@ namespace System.Runtime.CompilerServices
/// Provides a builder for asynchronous methods that return void.
/// This type is intended for compiler use only.
/// </summary>
- [HostProtection(Synchronization = true, ExternalThreading = true)]
public struct AsyncVoidMethodBuilder
{
/// <summary>The synchronization context associated with this operation.</summary>
@@ -59,14 +58,13 @@ namespace System.Runtime.CompilerServices
/// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
/// <param name="stateMachine">The state machine instance, passed by reference.</param>
/// <exception cref="System.ArgumentNullException">The <paramref name="stateMachine"/> argument was null (Nothing in Visual Basic).</exception>
- [SecuritySafeCritical]
[DebuggerStepThrough]
public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
{
// See comment on AsyncMethodBuilderCore.Start
// AsyncMethodBuilderCore.Start(ref stateMachine);
- if (stateMachine == null) throw new ArgumentNullException("stateMachine");
+ if (stateMachine == null) throw new ArgumentNullException(nameof(stateMachine));
Contract.EndContractBlock();
// Run the MoveNext method within a copy-on-write ExecutionContext scope.
@@ -112,7 +110,7 @@ namespace System.Runtime.CompilerServices
{
AsyncMethodBuilderCore.MoveNextRunner runnerToInitialize = null;
var continuation = m_coreState.GetCompletionAction(AsyncCausalityTracer.LoggingOn ? this.Task : null, ref runnerToInitialize);
- Contract.Assert(continuation != null, "GetCompletionAction should always return a valid action.");
+ Debug.Assert(continuation != null, "GetCompletionAction should always return a valid action.");
// If this is our first await, such that we've not yet boxed the state machine, do so now.
if (m_coreState.m_stateMachine == null)
@@ -149,7 +147,6 @@ namespace System.Runtime.CompilerServices
/// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
/// <param name="awaiter">The awaiter.</param>
/// <param name="stateMachine">The state machine.</param>
- [SecuritySafeCritical]
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(
ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : ICriticalNotifyCompletion
@@ -159,7 +156,7 @@ namespace System.Runtime.CompilerServices
{
AsyncMethodBuilderCore.MoveNextRunner runnerToInitialize = null;
var continuation = m_coreState.GetCompletionAction(AsyncCausalityTracer.LoggingOn ? this.Task : null, ref runnerToInitialize);
- Contract.Assert(continuation != null, "GetCompletionAction should always return a valid action.");
+ Debug.Assert(continuation != null, "GetCompletionAction should always return a valid action.");
// If this is our first await, such that we've not yet boxed the state machine, do so now.
if (m_coreState.m_stateMachine == null)
@@ -200,7 +197,7 @@ namespace System.Runtime.CompilerServices
/// <exception cref="System.InvalidOperationException">The builder is not initialized.</exception>
public void SetException(Exception exception)
{
- if (exception == null) throw new ArgumentNullException("exception");
+ if (exception == null) throw new ArgumentNullException(nameof(exception));
Contract.EndContractBlock();
if (AsyncCausalityTracer.LoggingOn)
@@ -231,7 +228,7 @@ namespace System.Runtime.CompilerServices
/// <summary>Notifies the current synchronization context that the operation completed.</summary>
private void NotifySynchronizationContextOfCompletion()
{
- Contract.Assert(m_synchronizationContext != null, "Must only be used with a non-null context.");
+ Debug.Assert(m_synchronizationContext != null, "Must only be used with a non-null context.");
try
{
m_synchronizationContext.OperationCompleted();
@@ -273,7 +270,6 @@ namespace System.Runtime.CompilerServices
/// Prior to being copied, one of its Task, SetResult, or SetException members must be accessed,
/// or else the copies may end up building distinct Task instances.
/// </remarks>
- [HostProtection(Synchronization = true, ExternalThreading = true)]
public struct AsyncTaskMethodBuilder
{
/// <summary>A cached VoidTaskResult task used for builders that complete synchronously.</summary>
@@ -294,14 +290,13 @@ namespace System.Runtime.CompilerServices
/// <summary>Initiates the builder's execution with the associated state machine.</summary>
/// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
/// <param name="stateMachine">The state machine instance, passed by reference.</param>
- [SecuritySafeCritical]
[DebuggerStepThrough]
public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
{
// See comment on AsyncMethodBuilderCore.Start
// AsyncMethodBuilderCore.Start(ref stateMachine);
- if (stateMachine == null) throw new ArgumentNullException("stateMachine");
+ if (stateMachine == null) throw new ArgumentNullException(nameof(stateMachine));
Contract.EndContractBlock();
// Run the MoveNext method within a copy-on-write ExecutionContext scope.
@@ -421,7 +416,6 @@ namespace System.Runtime.CompilerServices
/// Prior to being copied, one of its Task, SetResult, or SetException members must be accessed,
/// or else the copies may end up building distinct Task instances.
/// </remarks>
- [HostProtection(Synchronization = true, ExternalThreading = true)]
public struct AsyncTaskMethodBuilder<TResult>
{
/// <summary>A cached task for default(TResult).</summary>
@@ -450,14 +444,13 @@ namespace System.Runtime.CompilerServices
/// <summary>Initiates the builder's execution with the associated state machine.</summary>
/// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
/// <param name="stateMachine">The state machine instance, passed by reference.</param>
- [SecuritySafeCritical]
[DebuggerStepThrough]
public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
{
// See comment on AsyncMethodBuilderCore.Start
// AsyncMethodBuilderCore.Start(ref stateMachine);
- if (stateMachine == null) throw new ArgumentNullException("stateMachine");
+ if (stateMachine == null) throw new ArgumentNullException(nameof(stateMachine));
Contract.EndContractBlock();
// Run the MoveNext method within a copy-on-write ExecutionContext scope.
@@ -503,7 +496,7 @@ namespace System.Runtime.CompilerServices
{
AsyncMethodBuilderCore.MoveNextRunner runnerToInitialize = null;
var continuation = m_coreState.GetCompletionAction(AsyncCausalityTracer.LoggingOn ? this.Task : null, ref runnerToInitialize);
- Contract.Assert(continuation != null, "GetCompletionAction should always return a valid action.");
+ Debug.Assert(continuation != null, "GetCompletionAction should always return a valid action.");
// If this is our first await, such that we've not yet boxed the state machine, do so now.
if (m_coreState.m_stateMachine == null)
@@ -534,7 +527,6 @@ namespace System.Runtime.CompilerServices
/// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
/// <param name="awaiter">The awaiter.</param>
/// <param name="stateMachine">The state machine.</param>
- [SecuritySafeCritical]
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(
ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : ICriticalNotifyCompletion
@@ -544,7 +536,7 @@ namespace System.Runtime.CompilerServices
{
AsyncMethodBuilderCore.MoveNextRunner runnerToInitialize = null;
var continuation = m_coreState.GetCompletionAction(AsyncCausalityTracer.LoggingOn ? this.Task : null, ref runnerToInitialize);
- Contract.Assert(continuation != null, "GetCompletionAction should always return a valid action.");
+ Debug.Assert(continuation != null, "GetCompletionAction should always return a valid action.");
// If this is our first await, such that we've not yet boxed the state machine, do so now.
if (m_coreState.m_stateMachine == null)
@@ -595,7 +587,7 @@ namespace System.Runtime.CompilerServices
if (task == null)
{
m_task = GetTaskForResult(result);
- Contract.Assert(m_task != null, "GetTaskForResult should never return null");
+ Debug.Assert(m_task != null, "GetTaskForResult should never return null");
}
// Slow path: complete the existing task.
else
@@ -650,7 +642,7 @@ namespace System.Runtime.CompilerServices
/// <exception cref="System.InvalidOperationException">The task has already completed.</exception>
public void SetException(Exception exception)
{
- if (exception == null) throw new ArgumentNullException("exception");
+ if (exception == null) throw new ArgumentNullException(nameof(exception));
Contract.EndContractBlock();
@@ -713,7 +705,6 @@ 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>
- [SecuritySafeCritical] // for JitHelpers.UnsafeCast
private Task<TResult> GetTaskForResult(TResult result)
{
Contract.Ensures(
@@ -819,7 +810,7 @@ namespace System.Runtime.CompilerServices
/// <summary>Creates an array of cached tasks for the values in the range [INCLUSIVE_MIN,EXCLUSIVE_MAX).</summary>
private static Task<Int32>[] CreateInt32Tasks()
{
- Contract.Assert(EXCLUSIVE_INT32_MAX >= INCLUSIVE_INT32_MIN, "Expected max to be at least min");
+ Debug.Assert(EXCLUSIVE_INT32_MAX >= INCLUSIVE_INT32_MIN, "Expected max to be at least min");
var tasks = new Task<Int32>[EXCLUSIVE_INT32_MAX - INCLUSIVE_INT32_MIN];
for (int i = 0; i < tasks.Length; i++)
{
@@ -854,12 +845,11 @@ namespace System.Runtime.CompilerServices
/// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
/// <param name="stateMachine">The state machine instance, passed by reference.</param>
/// <exception cref="System.ArgumentNullException">The <paramref name="stateMachine"/> argument is null (Nothing in Visual Basic).</exception>
- [SecuritySafeCritical]
[DebuggerStepThrough]
internal static void Start<TStateMachine>(ref TStateMachine stateMachine)
where TStateMachine : IAsyncStateMachine
{
- if (stateMachine == null) throw new ArgumentNullException("stateMachine");
+ if (stateMachine == null) throw new ArgumentNullException(nameof(stateMachine));
Contract.EndContractBlock();
// Run the MoveNext method within a copy-on-write ExecutionContext scope.
@@ -887,7 +877,7 @@ 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("stateMachine");
+ if (stateMachine == null) throw new ArgumentNullException(nameof(stateMachine));
Contract.EndContractBlock();
if (m_stateMachine != null) throw new InvalidOperationException(Environment.GetResourceString("AsyncMethodBuilder_InstanceNotInitialized"));
m_stateMachine = stateMachine;
@@ -902,10 +892,9 @@ namespace System.Runtime.CompilerServices
/// <param name="builder">The builder.</param>
/// <param name="stateMachine">The state machine.</param>
/// <returns>An Action to provide to the awaiter.</returns>
- [SecuritySafeCritical]
internal Action GetCompletionAction(Task taskForTracing, ref MoveNextRunner runnerToInitialize)
{
- Contract.Assert(m_defaultContextAction == null || m_stateMachine != null,
+ Debug.Assert(m_defaultContextAction == null || m_stateMachine != null,
"Expected non-null m_stateMachine on non-null m_defaultContextAction");
// Alert a listening debugger that we can't make forward progress unless it slips threads.
@@ -928,7 +917,7 @@ namespace System.Runtime.CompilerServices
action = m_defaultContextAction;
if (action != null)
{
- Contract.Assert(m_stateMachine != null, "If the delegate was set, the state machine should have been as well.");
+ Debug.Assert(m_stateMachine != null, "If the delegate was set, the state machine should have been as well.");
return action;
}
@@ -994,8 +983,8 @@ namespace System.Runtime.CompilerServices
m_stateMachine = stateMachine;
m_stateMachine.SetStateMachine(m_stateMachine);
- Contract.Assert(runner.m_stateMachine == null, "The runner's state machine should not yet have been populated.");
- Contract.Assert(m_stateMachine != null, "The builder's state machine field should have been initialized.");
+ Debug.Assert(runner.m_stateMachine == null, "The runner's state machine should not yet have been populated.");
+ Debug.Assert(m_stateMachine != null, "The builder's state machine field should have been initialized.");
// Now that we have the state machine, store it into the runner that the action delegate points to.
// And return the action.
@@ -1045,17 +1034,15 @@ namespace System.Runtime.CompilerServices
/// <summary>Initializes the runner.</summary>
/// <param name="context">The context with which to run MoveNext.</param>
- [SecurityCritical] // Run needs to be SSC to map to Action delegate, so to prevent misuse, we only allow construction through SC
internal MoveNextRunnerWithContext(ExecutionContext context, IAsyncStateMachine stateMachine) : base(stateMachine)
{
m_context = context;
}
/// <summary>Invokes MoveNext under the provided context.</summary>
- [SecuritySafeCritical]
internal void RunWithCapturedContext()
{
- Contract.Assert(m_stateMachine != null, "The state machine must have been set before calling Run.");
+ Debug.Assert(m_stateMachine != null, "The state machine must have been set before calling Run.");
if (m_context != null)
{
@@ -1080,34 +1067,29 @@ namespace System.Runtime.CompilerServices
internal IAsyncStateMachine m_stateMachine;
/// <summary>Initializes the runner.</summary>
- [SecurityCritical] // Run needs to be SSC to map to Action delegate, so to prevent misuse, we only allow construction through SC
internal MoveNextRunner(IAsyncStateMachine stateMachine)
{
m_stateMachine = stateMachine;
}
/// <summary>Invokes MoveNext under the default context.</summary>
- [SecuritySafeCritical]
internal void RunWithDefaultContext()
{
- Contract.Assert(m_stateMachine != null, "The state machine must have been set before calling Run.");
+ Debug.Assert(m_stateMachine != null, "The state machine must have been set before calling Run.");
ExecutionContext.Run(ExecutionContext.PreAllocatedDefault, InvokeMoveNextCallback, m_stateMachine, preserveSyncCtx: true);
}
/// <summary>Gets a delegate to the InvokeMoveNext method.</summary>
protected static ContextCallback InvokeMoveNextCallback
{
- [SecuritySafeCritical]
get { return s_invokeMoveNext ?? (s_invokeMoveNext = InvokeMoveNext); }
}
/// <summary>Cached delegate used with ExecutionContext.Run.</summary>
- [SecurityCritical]
private static ContextCallback s_invokeMoveNext; // lazily-initialized due to SecurityCritical attribution
/// <summary>Invokes the MoveNext method on the supplied IAsyncStateMachine.</summary>
/// <param name="stateMachine">The IAsyncStateMachine machine instance.</param>
- [SecurityCritical] // necessary for ContextCallback in CoreCLR
private static void InvokeMoveNext(object stateMachine)
{
((IAsyncStateMachine)stateMachine).MoveNext();
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/CallingConvention.cs b/src/mscorlib/src/System/Runtime/CompilerServices/CallingConvention.cs
deleted file mode 100644
index f44251d480..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/CallingConvention.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
-{
- // Types used in Custom Modifier to specify calling conventions.
- [System.Runtime.InteropServices.ComVisible(true)]
- public class CallConvCdecl
- {
- }
-
- [System.Runtime.InteropServices.ComVisible(true)]
- public class CallConvStdcall
- {
- }
-
- [System.Runtime.InteropServices.ComVisible(true)]
- public class CallConvThiscall
- {
- }
-
- [System.Runtime.InteropServices.ComVisible(true)]
- public class CallConvFastcall
- {
- }
-
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs b/src/mscorlib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs
index 21d677241d..74559673bb 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs
@@ -60,31 +60,29 @@
** may be delayed until appdomain shutdown.
===========================================================*/
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading;
+
namespace System.Runtime.CompilerServices
{
- using System;
- using System.Collections.Generic;
- using System.Runtime.Versioning;
- using System.Runtime.InteropServices;
-
-
#region ConditionalWeakTable
- [System.Runtime.InteropServices.ComVisible(false)]
+ [ComVisible(false)]
public sealed class ConditionalWeakTable<TKey, TValue>
where TKey : class
where TValue : class
{
+ #region Fields
+ private const int InitialCapacity = 8; // Initial length of the table. Must be a power of two.
+ private readonly object _lock; // This lock protects all mutation of data in the table. Readers do not take this lock.
+ private volatile Container _container; // The actual storage for the table; swapped out as the table grows.
+ #endregion
#region Constructors
- [System.Security.SecuritySafeCritical]
public ConditionalWeakTable()
{
- _buckets = Array.Empty<int>();
- _entries = Array.Empty<Entry>();
- _freeList = -1;
- _lock = new Object();
-
- Resize(); // Resize at once (so won't need "if initialized" checks all over)
+ _lock = new object();
+ _container = new Container(this);
}
#endregion
@@ -99,18 +97,14 @@ namespace System.Runtime.CompilerServices
// Note: The key may get garbaged collected during the TryGetValue operation. If so, TryGetValue
// may at its discretion, return "false" and set "value" to the default (as if the key was not present.)
//--------------------------------------------------------------------------------------------
- [System.Security.SecuritySafeCritical]
public bool TryGetValue(TKey key, out TValue value)
{
if (key == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
- lock(_lock)
- {
- VerifyIntegrity();
- return TryGetValueWorker(key, out value);
- }
+
+ return _container.TryGetValueWorker(key, out value);
}
//--------------------------------------------------------------------------------------------
@@ -123,7 +117,6 @@ namespace System.Runtime.CompilerServices
// has the right to consider any prior entries successfully removed and add a new entry without
// throwing an exception.
//--------------------------------------------------------------------------------------------
- [System.Security.SecuritySafeCritical]
public void Add(TKey key, TValue value)
{
if (key == null)
@@ -131,22 +124,48 @@ namespace System.Runtime.CompilerServices
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
- lock(_lock)
+ lock (_lock)
{
- VerifyIntegrity();
- _invalid = true;
-
- int entryIndex = FindEntry(key);
+ object otherValue;
+ int entryIndex = _container.FindEntry(key, out otherValue);
if (entryIndex != -1)
{
- _invalid = false;
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate);
}
CreateEntry(key, value);
- _invalid = false;
}
+ }
+
+ //--------------------------------------------------------------------------------------------
+ // key: key to add or update. May not be null.
+ // value: value to associate with key.
+ //
+ // If the key is already entered into the dictionary, this method will update the value associated with key.
+ //--------------------------------------------------------------------------------------------
+ public void AddOrUpdate(TKey key, TValue value)
+ {
+ if (key == null)
+ {
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
+ }
+
+ lock (_lock)
+ {
+ object otherValue;
+ int entryIndex = _container.FindEntry(key, out otherValue);
+
+ // if we found a key we should just update, if no we should create a new entry.
+ if (entryIndex != -1)
+ {
+ _container.UpdateValue(entryIndex, value);
+ }
+ else
+ {
+ CreateEntry(key, value);
+ }
+ }
}
//--------------------------------------------------------------------------------------------
@@ -156,9 +175,8 @@ namespace System.Runtime.CompilerServices
//
// Note: The key may get garbage collected during the Remove() operation. If so,
// Remove() will not fail or throw, however, the return value can be either true or false
- // depending on the race condition.
+ // depending on who wins the race.
//--------------------------------------------------------------------------------------------
- [System.Security.SecuritySafeCritical]
public bool Remove(TKey key)
{
if (key == null)
@@ -166,40 +184,9 @@ namespace System.Runtime.CompilerServices
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
- lock(_lock)
+ lock (_lock)
{
- VerifyIntegrity();
- _invalid = true;
-
- int hashCode = RuntimeHelpers.GetHashCode(key) & Int32.MaxValue;
- int bucket = hashCode % _buckets.Length;
- int last = -1;
- for (int entriesIndex = _buckets[bucket]; entriesIndex != -1; entriesIndex = _entries[entriesIndex].next)
- {
- if (_entries[entriesIndex].hashCode == hashCode && _entries[entriesIndex].depHnd.GetPrimary() == key)
- {
- if (last == -1)
- {
- _buckets[bucket] = _entries[entriesIndex].next;
- }
- else
- {
- _entries[last].next = _entries[entriesIndex].next;
- }
-
- _entries[entriesIndex].depHnd.Free();
- _entries[entriesIndex].next = _freeList;
-
- _freeList = entriesIndex;
-
- _invalid = false;
- return true;
-
- }
- last = entriesIndex;
- }
- _invalid = false;
- return false;
+ return _container.Remove(key);
}
}
@@ -219,46 +206,39 @@ namespace System.Runtime.CompilerServices
// This rule permits the table to invoke createValueCallback outside the internal table lock
// to prevent deadlocks.
//--------------------------------------------------------------------------------------------
- [System.Security.SecuritySafeCritical]
public TValue GetValue(TKey key, CreateValueCallback createValueCallback)
{
- // Our call to TryGetValue() validates key so no need for us to.
- //
- // if (key == null)
- // {
- // ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
- // }
+ // key is validated by TryGetValue
if (createValueCallback == null)
{
- throw new ArgumentNullException("createValueCallback");
+ throw new ArgumentNullException(nameof(createValueCallback));
}
TValue existingValue;
- if (TryGetValue(key, out existingValue))
- {
- return existingValue;
- }
+ return TryGetValue(key, out existingValue) ?
+ existingValue :
+ GetValueLocked(key, createValueCallback);
+ }
- // If we got here, the key is not currently in table. Invoke the callback (outside the lock)
+ private TValue GetValueLocked(TKey key, CreateValueCallback createValueCallback)
+ {
+ // If we got here, the key was not in the table. Invoke the callback (outside the lock)
// to generate the new value for the key.
TValue newValue = createValueCallback(key);
- lock(_lock)
+ lock (_lock)
{
- VerifyIntegrity();
- _invalid = true;
-
- // Now that we've retaken the lock, must recheck in case there was a race condition to add the key.
- if (TryGetValueWorker(key, out existingValue))
+ // Now that we've taken the lock, must recheck in case we lost a race to add the key.
+ TValue existingValue;
+ if (_container.TryGetValueWorker(key, out existingValue))
{
- _invalid = false;
return existingValue;
}
else
{
+ // Verified in-lock that we won the race to add the key. Add it now.
CreateEntry(key, newValue);
- _invalid = false;
return newValue;
}
}
@@ -271,17 +251,15 @@ namespace System.Runtime.CompilerServices
// to create new instances as needed. If TValue does not have a default constructor, this will
// throw.
//--------------------------------------------------------------------------------------------
- public TValue GetOrCreateValue(TKey key)
- {
- return GetValue(key, k => Activator.CreateInstance<TValue>());
- }
+
+ public TValue GetOrCreateValue(TKey key) => GetValue(key, _ => Activator.CreateInstance<TValue>());
public delegate TValue CreateValueCallback(TKey key);
-
+
#endregion
- #region internal members
-
+ #region Internal members
+
//--------------------------------------------------------------------------------------------
// Find a key that equals (value equality) with the given key - don't use in perf critical path
// Note that it calls out to Object.Equals which may calls the override version of Equals
@@ -290,56 +268,26 @@ namespace System.Runtime.CompilerServices
// if you know for sure that either you won't run into dead locks or you need to live with the
// possiblity
//--------------------------------------------------------------------------------------------
- [System.Security.SecuritySafeCritical]
[FriendAccessAllowed]
internal TKey FindEquivalentKeyUnsafe(TKey key, out TValue value)
{
lock (_lock)
{
- for (int bucket = 0; bucket < _buckets.Length; ++bucket)
- {
- for (int entriesIndex = _buckets[bucket]; entriesIndex != -1; entriesIndex = _entries[entriesIndex].next)
- {
- object thisKey, thisValue;
- _entries[entriesIndex].depHnd.GetPrimaryAndSecondary(out thisKey, out thisValue);
- if (Object.Equals(thisKey, key))
- {
- value = (TValue) thisValue;
- return (TKey) thisKey;
- }
- }
- }
+ return _container.FindEquivalentKeyUnsafe(key, out value);
}
-
- value = default(TValue);
- return null;
}
-
+
//--------------------------------------------------------------------------------------------
// Returns a collection of keys - don't use in perf critical path
//--------------------------------------------------------------------------------------------
internal ICollection<TKey> Keys
{
- [System.Security.SecuritySafeCritical]
get
{
- List<TKey> list = new List<TKey>();
lock (_lock)
{
- for (int bucket = 0; bucket < _buckets.Length; ++bucket)
- {
- for (int entriesIndex = _buckets[bucket]; entriesIndex != -1; entriesIndex = _entries[entriesIndex].next)
- {
- TKey thisKey = (TKey) _entries[entriesIndex].depHnd.GetPrimary();
- if (thisKey != null)
- {
- list.Add(thisKey);
- }
- }
- }
+ return _container.Keys;
}
-
- return list;
}
}
@@ -348,332 +296,500 @@ namespace System.Runtime.CompilerServices
//--------------------------------------------------------------------------------------------
internal ICollection<TValue> Values
{
- [System.Security.SecuritySafeCritical]
get
{
- List<TValue> list = new List<TValue>();
lock (_lock)
{
- for (int bucket = 0; bucket < _buckets.Length; ++bucket)
- {
- for (int entriesIndex = _buckets[bucket]; entriesIndex != -1; entriesIndex = _entries[entriesIndex].next)
- {
- Object primary = null;
- Object secondary = null;
-
- _entries[entriesIndex].depHnd.GetPrimaryAndSecondary(out primary, out secondary);
-
- // Now that we've secured a strong reference to the secondary, must check the primary again
- // to ensure it didn't expire (otherwise, we open a race condition where TryGetValue misreports an
- // expired key as a live key with a null value.)
- if (primary != null)
- {
- list.Add((TValue)secondary);
- }
- }
- }
+ return _container.Values;
}
-
- return list;
}
}
-
+
//--------------------------------------------------------------------------------------------
// Clear all the key/value pairs
//--------------------------------------------------------------------------------------------
- [System.Security.SecuritySafeCritical]
internal void Clear()
{
lock (_lock)
{
- // Clear the buckets
- for (int bucketIndex = 0; bucketIndex < _buckets.Length; bucketIndex++)
- {
- _buckets[bucketIndex] = -1;
- }
-
- // Clear the entries and link them backwards together as part of free list
- int entriesIndex;
- for (entriesIndex = 0; entriesIndex < _entries.Length; entriesIndex++)
- {
- if (_entries[entriesIndex].depHnd.IsAllocated)
- {
- _entries[entriesIndex].depHnd.Free();
- }
-
- // Link back wards as free list
- _entries[entriesIndex].next = entriesIndex - 1;
- }
-
- _freeList = entriesIndex - 1;
- }
+ _container = new Container(this);
+ }
}
#endregion
-
+
#region Private Members
- [System.Security.SecurityCritical]
+
//----------------------------------------------------------------------------------------
- // Worker for finding a key/value pair
+ // Worker for adding a new key/value pair.
+ // Will resize the container if it is full
//
// Preconditions:
// Must hold _lock.
- // Key already validated as non-null
+ // Key already validated as non-null and not already in table.
//----------------------------------------------------------------------------------------
- private bool TryGetValueWorker(TKey key, out TValue value)
+ private void CreateEntry(TKey key, TValue value)
{
- int entryIndex = FindEntry(key);
- if (entryIndex != -1)
+ Debug.Assert(Monitor.IsEntered(_lock));
+
+ Container c = _container;
+ if (!c.HasCapacity)
{
- Object primary = null;
- Object secondary = null;
- _entries[entryIndex].depHnd.GetPrimaryAndSecondary(out primary, out secondary);
- // Now that we've secured a strong reference to the secondary, must check the primary again
- // to ensure it didn't expire (otherwise, we open a race condition where TryGetValue misreports an
- // expired key as a live key with a null value.)
- if (primary != null)
- {
- value = (TValue)secondary;
- return true;
- }
+ _container = c = c.Resize();
}
+ c.CreateEntryNoResize(key, value);
+ }
+
+ private static bool IsPowerOfTwo(int value) => (value > 0) && ((value & (value - 1)) == 0);
- value = default(TValue);
- return false;
+ #endregion
+
+ #region Private Data Members
+ //--------------------------------------------------------------------------------------------
+ // Entry can be in one of four states:
+ //
+ // - Unused (stored with an index _firstFreeEntry and above)
+ // depHnd.IsAllocated == false
+ // hashCode == <dontcare>
+ // next == <dontcare>)
+ //
+ // - Used with live key (linked into a bucket list where _buckets[hashCode & (_buckets.Length - 1)] points to first entry)
+ // depHnd.IsAllocated == true, depHnd.GetPrimary() != null
+ // hashCode == RuntimeHelpers.GetHashCode(depHnd.GetPrimary()) & Int32.MaxValue
+ // next links to next Entry in bucket.
+ //
+ // - Used with dead key (linked into a bucket list where _buckets[hashCode & (_buckets.Length - 1)] points to first entry)
+ // depHnd.IsAllocated == true, depHnd.GetPrimary() == null
+ // hashCode == <notcare>
+ // next links to next Entry in bucket.
+ //
+ // - Has been removed from the table (by a call to Remove)
+ // depHnd.IsAllocated == true, depHnd.GetPrimary() == <notcare>
+ // hashCode == -1
+ // next links to next Entry in bucket.
+ //
+ // The only difference between "used with live key" and "used with dead key" is that
+ // depHnd.GetPrimary() returns null. The transition from "used with live key" to "used with dead key"
+ // happens asynchronously as a result of normal garbage collection. The dictionary itself
+ // receives no notification when this happens.
+ //
+ // When the dictionary grows the _entries table, it scours it for expired keys and does not
+ // add those to the new container.
+ //--------------------------------------------------------------------------------------------
+ private struct Entry
+ {
+ public DependentHandle depHnd; // Holds key and value using a weak reference for the key and a strong reference
+ // for the value that is traversed only if the key is reachable without going through the value.
+ public int HashCode; // Cached copy of key's hashcode
+ public int Next; // Index of next entry, -1 if last
}
- //----------------------------------------------------------------------------------------
- // Worker for adding a new key/value pair.
//
- // Preconditions:
- // Must hold _lock.
- // Key already validated as non-null and not already in table.
- //----------------------------------------------------------------------------------------
- [System.Security.SecurityCritical]
- private void CreateEntry(TKey key, TValue value)
+ // Container holds the actual data for the table. A given instance of Container always has the same capacity. When we need
+ // more capacity, we create a new Container, copy the old one into the new one, and discard the old one. This helps enable lock-free
+ // reads from the table, as readers never need to deal with motion of entries due to rehashing.
+ //
+ private sealed class Container
{
- if (_freeList == -1)
+ private readonly ConditionalWeakTable<TKey, TValue> _parent; // the ConditionalWeakTable with which this container is associated
+ private int[] _buckets; // _buckets[hashcode & (_buckets.Length - 1)] contains index of the first entry in bucket (-1 if empty)
+ private Entry[] _entries; // the table entries containing the stored dependency handles
+ private int _firstFreeEntry; // _firstFreeEntry < _entries.Length => table has capacity, entries grow from the bottom of the table.
+ private bool _invalid; // flag detects if OOM or other background exception threw us out of the lock.
+ private bool _finalized; // set to true when initially finalized
+ private volatile object _oldKeepAlive; // used to ensure the next allocated container isn't finalized until this one is GC'd
+
+ internal Container(ConditionalWeakTable<TKey, TValue> parent)
{
- Resize();
+ Debug.Assert(parent != null);
+ Debug.Assert(IsPowerOfTwo(InitialCapacity));
+
+ int size = InitialCapacity;
+ _buckets = new int[size];
+ for (int i = 0; i < _buckets.Length; i++)
+ {
+ _buckets[i] = -1;
+ }
+ _entries = new Entry[size];
+
+ // Only store the parent after all of the allocations have happened successfully.
+ // Otherwise, as part of growing or clearing the container, we could end up allocating
+ // a new Container that fails (OOMs) part way through construction but that gets finalized
+ // and ends up clearing out some other container present in the associated CWT.
+ _parent = parent;
}
- int hashCode = RuntimeHelpers.GetHashCode(key) & Int32.MaxValue;
- int bucket = hashCode % _buckets.Length;
+ private Container(ConditionalWeakTable<TKey, TValue> parent, int[] buckets, Entry[] entries, int firstFreeEntry)
+ {
+ Debug.Assert(parent != null);
+ Debug.Assert(buckets != null);
+ Debug.Assert(entries != null);
+ Debug.Assert(buckets.Length == entries.Length);
+ Debug.Assert(IsPowerOfTwo(buckets.Length));
+
+ _parent = parent;
+ _buckets = buckets;
+ _entries = entries;
+ _firstFreeEntry = firstFreeEntry;
+ }
- int newEntry = _freeList;
- _freeList = _entries[newEntry].next;
+ internal bool HasCapacity => _firstFreeEntry < _entries.Length;
- _entries[newEntry].hashCode = hashCode;
- _entries[newEntry].depHnd = new DependentHandle(key, value);
- _entries[newEntry].next = _buckets[bucket];
+ //----------------------------------------------------------------------------------------
+ // Worker for adding a new key/value pair.
+ // Preconditions:
+ // Container must NOT be full
+ //----------------------------------------------------------------------------------------
+ internal void CreateEntryNoResize(TKey key, TValue value)
+ {
+ Debug.Assert(HasCapacity);
- _buckets[bucket] = newEntry;
+ VerifyIntegrity();
+ _invalid = true;
- }
+ int hashCode = RuntimeHelpers.GetHashCode(key) & int.MaxValue;
+ int newEntry = _firstFreeEntry++;
- //----------------------------------------------------------------------------------------
- // This does two things: resize and scrub expired keys off bucket lists.
- //
- // Precondition:
- // Must hold _lock.
- //
- // Postcondition:
- // _freeList is non-empty on exit.
- //----------------------------------------------------------------------------------------
- [System.Security.SecurityCritical]
- private void Resize()
- {
- // Start by assuming we won't resize.
- int newSize = _buckets.Length;
+ _entries[newEntry].HashCode = hashCode;
+ _entries[newEntry].depHnd = new DependentHandle(key, value);
+ int bucket = hashCode & (_buckets.Length - 1);
+ _entries[newEntry].Next = _buckets[bucket];
+
+ // This write must be volatile, as we may be racing with concurrent readers. If they see
+ // the new entry, they must also see all of the writes earlier in this method.
+ Volatile.Write(ref _buckets[bucket], newEntry);
+
+ _invalid = false;
+ }
- // If any expired keys exist, we won't resize.
- bool hasExpiredEntries = false;
- int entriesIndex;
- for (entriesIndex = 0; entriesIndex < _entries.Length; entriesIndex++)
+ //----------------------------------------------------------------------------------------
+ // Worker for finding a key/value pair
+ //
+ // Preconditions:
+ // Must hold _lock.
+ // Key already validated as non-null
+ //----------------------------------------------------------------------------------------
+ internal bool TryGetValueWorker(TKey key, out TValue value)
{
- if ( _entries[entriesIndex].depHnd.IsAllocated && _entries[entriesIndex].depHnd.GetPrimary() == null)
+ object secondary;
+ int entryIndex = FindEntry(key, out secondary);
+ value = JitHelpers.UnsafeCast<TValue>(secondary);
+ return entryIndex != -1;
+ }
+
+ //----------------------------------------------------------------------------------------
+ // Returns -1 if not found (if key expires during FindEntry, this can be treated as "not found.")
+ //
+ // Preconditions:
+ // Must hold _lock, or be prepared to retry the search while holding _lock.
+ // Key already validated as non-null.
+ //----------------------------------------------------------------------------------------
+ internal int FindEntry(TKey key, out object value)
+ {
+ int hashCode = RuntimeHelpers.GetHashCode(key) & int.MaxValue;
+ int bucket = hashCode & (_buckets.Length - 1);
+ for (int entriesIndex = Volatile.Read(ref _buckets[bucket]); entriesIndex != -1; entriesIndex = _entries[entriesIndex].Next)
{
- hasExpiredEntries = true;
- break;
+ if (_entries[entriesIndex].HashCode == hashCode)
+ {
+ object primary, secondary;
+ _entries[entriesIndex].depHnd.GetPrimaryAndSecondary(out primary, out secondary);
+ if (primary == key)
+ {
+ GC.KeepAlive(this); // ensure we don't get finalized while accessing DependentHandles.
+ value = secondary;
+ return entriesIndex;
+ }
+ }
}
+
+ GC.KeepAlive(this); // ensure we don't get finalized while accessing DependentHandles.
+ value = null;
+ return -1;
}
- if (!hasExpiredEntries)
+ internal bool Remove(TKey key)
{
- newSize = System.Collections.HashHelpers.GetPrime(_buckets.Length == 0 ? _initialCapacity + 1 : _buckets.Length * 2);
+ VerifyIntegrity();
+
+ object value;
+ int entryIndex = FindEntry(key, out value);
+ if (entryIndex != -1)
+ {
+ ref Entry entry = ref _entries[entryIndex];
+
+ // We do not free the handle here, as we may be racing with readers who already saw the hash code.
+ // Instead, we simply overwrite the entry's hash code, so subsequent reads will ignore it.
+ // The handle will be free'd in Container's finalizer, after the table is resized or discarded.
+ Volatile.Write(ref entry.HashCode, -1);
+
+ // Also, clear the key to allow GC to collect objects pointed to by the entry
+ entry.depHnd.SetPrimary(null);
+
+ return true;
+ }
+
+ return false;
}
- // Reallocate both buckets and entries and rebuild the bucket and freelists from scratch.
- // This serves both to scrub entries with expired keys and to put the new entries in the proper bucket.
- int newFreeList = -1;
- int[] newBuckets = new int[newSize];
- for (int bucketIndex = 0; bucketIndex < newSize; bucketIndex++)
+ internal void UpdateValue(int entryIndex, TValue newValue)
{
- newBuckets[bucketIndex] = -1;
+ Debug.Assert(entryIndex != -1);
+
+ VerifyIntegrity();
+ _invalid = true;
+
+ _entries[entryIndex].depHnd.SetSecondary(newValue);
+
+ _invalid = false;
}
- Entry[] newEntries = new Entry[newSize];
- // Migrate existing entries to the new table.
- for (entriesIndex = 0; entriesIndex < _entries.Length; entriesIndex++)
+ //----------------------------------------------------------------------------------------
+ // This does two things: resize and scrub expired keys off bucket lists.
+ //
+ // Precondition:
+ // Must hold _lock.
+ //
+ // Postcondition:
+ // _firstEntry is less than _entries.Length on exit, that is, the table has at least one free entry.
+ //----------------------------------------------------------------------------------------
+ internal Container Resize()
{
- DependentHandle depHnd = _entries[entriesIndex].depHnd;
- if (depHnd.IsAllocated && depHnd.GetPrimary() != null)
+ // Start by assuming we won't resize.
+ int newSize = _buckets.Length;
+
+ // If any expired or removed keys exist, we won't resize.
+ bool hasExpiredEntries = false;
+ for (int entriesIndex = 0; entriesIndex < _entries.Length; entriesIndex++)
{
- // Entry is used and has not expired. Link it into the appropriate bucket list.
- int bucket = _entries[entriesIndex].hashCode % newSize;
- newEntries[entriesIndex].depHnd = depHnd;
- newEntries[entriesIndex].hashCode = _entries[entriesIndex].hashCode;
- newEntries[entriesIndex].next = newBuckets[bucket];
- newBuckets[bucket] = entriesIndex;
+ if (_entries[entriesIndex].HashCode == -1)
+ {
+ // the entry was removed
+ hasExpiredEntries = true;
+ break;
+ }
+
+ if (_entries[entriesIndex].depHnd.IsAllocated && _entries[entriesIndex].depHnd.GetPrimary() == null)
+ {
+ // the entry has expired
+ hasExpiredEntries = true;
+ break;
+ }
}
- else
+
+ if (!hasExpiredEntries)
{
- // Entry has either expired or was on the freelist to begin with. Either way
- // insert it on the new freelist.
- _entries[entriesIndex].depHnd.Free();
- newEntries[entriesIndex].depHnd = new DependentHandle();
- newEntries[entriesIndex].next = newFreeList;
- newFreeList = entriesIndex;
+ // Not necessary to check for overflow here, the attempt to allocate new arrays will throw
+ newSize = _buckets.Length * 2;
}
+
+ return Resize(newSize);
}
- // Add remaining entries to freelist.
- while (entriesIndex != newEntries.Length)
+ internal Container Resize(int newSize)
{
- newEntries[entriesIndex].depHnd = new DependentHandle();
- newEntries[entriesIndex].next = newFreeList;
- newFreeList = entriesIndex;
- entriesIndex++;
- }
+ Debug.Assert(IsPowerOfTwo(newSize));
- _buckets = newBuckets;
- _entries = newEntries;
- _freeList = newFreeList;
- }
+ // Reallocate both buckets and entries and rebuild the bucket and entries from scratch.
+ // This serves both to scrub entries with expired keys and to put the new entries in the proper bucket.
+ int[] newBuckets = new int[newSize];
+ for (int bucketIndex = 0; bucketIndex < newSize; bucketIndex++)
+ {
+ newBuckets[bucketIndex] = -1;
+ }
+ Entry[] newEntries = new Entry[newSize];
+ int newEntriesIndex = 0;
- //----------------------------------------------------------------------------------------
- // Returns -1 if not found (if key expires during FindEntry, this can be treated as "not found.")
- //
- // Preconditions:
- // Must hold _lock.
- // Key already validated as non-null.
- //----------------------------------------------------------------------------------------
- [System.Security.SecurityCritical]
- private int FindEntry(TKey key)
- {
- int hashCode = RuntimeHelpers.GetHashCode(key) & Int32.MaxValue;
- for (int entriesIndex = _buckets[hashCode % _buckets.Length]; entriesIndex != -1; entriesIndex = _entries[entriesIndex].next)
+ // Migrate existing entries to the new table.
+ for (int entriesIndex = 0; entriesIndex < _entries.Length; entriesIndex++)
+ {
+ int hashCode = _entries[entriesIndex].HashCode;
+ DependentHandle depHnd = _entries[entriesIndex].depHnd;
+ if (hashCode != -1 && depHnd.IsAllocated)
+ {
+ if (depHnd.GetPrimary() != null)
+ {
+ // Entry is used and has not expired. Link it into the appropriate bucket list.
+ newEntries[newEntriesIndex].HashCode = hashCode;
+ newEntries[newEntriesIndex].depHnd = depHnd;
+ int bucket = hashCode & (newBuckets.Length - 1);
+ newEntries[newEntriesIndex].Next = newBuckets[bucket];
+ newBuckets[bucket] = newEntriesIndex;
+ newEntriesIndex++;
+ }
+ else
+ {
+ // Pretend the item was removed, so that this container's finalizer
+ // will clean up this dependent handle.
+ Volatile.Write(ref _entries[entriesIndex].HashCode, -1);
+ }
+ }
+ }
+
+ // Create the new container. We want to transfer the responsibility of freeing the handles from
+ // the old container to the new container, and also ensure that the new container isn't finalized
+ // while the old container may still be in use. As such, we store a reference from the old container
+ // to the new one, which will keep the new container alive as long as the old one is.
+ var newContainer = new Container(_parent, newBuckets, newEntries, newEntriesIndex);
+ _oldKeepAlive = newContainer; // once this is set, the old container's finalizer will not free transferred dependent handles
+
+ GC.KeepAlive(this); // ensure we don't get finalized while accessing DependentHandles.
+
+ return newContainer;
+ }
+
+ internal ICollection<TKey> Keys
{
- if (_entries[entriesIndex].hashCode == hashCode && _entries[entriesIndex].depHnd.GetPrimary() == key)
+ get
{
- return entriesIndex;
+ var list = new List<TKey>();
+
+ for (int bucket = 0; bucket < _buckets.Length; ++bucket)
+ {
+ for (int entriesIndex = _buckets[bucket]; entriesIndex != -1; entriesIndex = _entries[entriesIndex].Next)
+ {
+ TKey thisKey = JitHelpers.UnsafeCast<TKey>(_entries[entriesIndex].depHnd.GetPrimary());
+ if (thisKey != null)
+ {
+ list.Add(thisKey);
+ }
+ }
+ }
+
+ GC.KeepAlive(this); // ensure we don't get finalized while accessing DependentHandles.
+ return list;
}
}
- return -1;
- }
- //----------------------------------------------------------------------------------------
- // Precondition:
- // Must hold _lock.
- //----------------------------------------------------------------------------------------
- private void VerifyIntegrity()
- {
- if (_invalid)
+ internal ICollection<TValue> Values
{
- throw new InvalidOperationException(Environment.GetResourceString("CollectionCorrupted"));
+ get
+ {
+ var list = new List<TValue>();
+
+ for (int bucket = 0; bucket < _buckets.Length; ++bucket)
+ {
+ for (int entriesIndex = _buckets[bucket]; entriesIndex != -1; entriesIndex = _entries[entriesIndex].Next)
+ {
+ object primary = null, secondary = null;
+ _entries[entriesIndex].depHnd.GetPrimaryAndSecondary(out primary, out secondary);
+
+ // Now that we've secured a strong reference to the secondary, must check the primary again
+ // to ensure it didn't expire (otherwise, we open a race where TryGetValue misreports an
+ // expired key as a live key with a null value.)
+ if (primary != null)
+ {
+ list.Add(JitHelpers.UnsafeCast<TValue>(secondary));
+ }
+ }
+ }
+
+ GC.KeepAlive(this); // ensure we don't get finalized while accessing DependentHandles.
+ return list;
+ }
}
- }
- //----------------------------------------------------------------------------------------
- // Finalizer.
- //----------------------------------------------------------------------------------------
- [System.Security.SecuritySafeCritical]
- ~ConditionalWeakTable()
- {
+ internal TKey FindEquivalentKeyUnsafe(TKey key, out TValue value)
+ {
+ for (int bucket = 0; bucket < _buckets.Length; ++bucket)
+ {
+ for (int entriesIndex = _buckets[bucket]; entriesIndex != -1; entriesIndex = _entries[entriesIndex].Next)
+ {
+ if (_entries[entriesIndex].HashCode == -1)
+ {
+ continue; // removed entry whose handle is awaiting condemnation by the finalizer.
+ }
- // We're just freeing per-appdomain unmanaged handles here. If we're already shutting down the AD,
- // don't bother.
- //
- // (Despite its name, Environment.HasShutdownStart also returns true if the current AD is finalizing.)
- if (Environment.HasShutdownStarted)
+ object thisKey, thisValue;
+ _entries[entriesIndex].depHnd.GetPrimaryAndSecondary(out thisKey, out thisValue);
+ if (Equals(thisKey, key))
+ {
+ GC.KeepAlive(this); // ensure we don't get finalized while accessing DependentHandles.
+ value = JitHelpers.UnsafeCast<TValue>(thisValue);
+ return JitHelpers.UnsafeCast<TKey>(thisKey);
+ }
+ }
+ }
+
+ GC.KeepAlive(this); // ensure we don't get finalized while accessing DependentHandles.
+ value = default(TValue);
+ return null;
+ }
+
+ //----------------------------------------------------------------------------------------
+ // Precondition:
+ // Must hold _lock.
+ //----------------------------------------------------------------------------------------
+ private void VerifyIntegrity()
{
- return;
+ if (_invalid)
+ {
+ throw new InvalidOperationException(Environment.GetResourceString("CollectionCorrupted"));
+ }
}
- if (_lock != null)
+ //----------------------------------------------------------------------------------------
+ // Finalizer.
+ //----------------------------------------------------------------------------------------
+ ~Container()
{
- lock(_lock)
+ // We're just freeing per-appdomain unmanaged handles here. If we're already shutting down the AD,
+ // don't bother. (Despite its name, Environment.HasShutdownStart also returns true if the current
+ // AD is finalizing.) We also skip doing anything if the container is invalid, including if someone
+ // the container object was allocated but its associated table never set.
+ if (Environment.HasShutdownStarted || _invalid || _parent == null)
{
- if (_invalid)
+ return;
+ }
+
+ // It's possible that the ConditionalWeakTable could have been resurrected, in which case code could
+ // be accessing this Container as it's being finalized. We don't support usage after finalization,
+ // but we also don't want to potentially corrupt state by allowing dependency handles to be used as
+ // or after they've been freed. To avoid that, if it's at all possible that another thread has a
+ // reference to this container via the CWT, we remove such a reference and then re-register for
+ // finalization: the next time around, we can be sure that no references remain to this and we can
+ // clean up the dependency handles without fear of corruption.
+ if (!_finalized)
+ {
+ _finalized = true;
+ lock (_parent._lock)
{
- return;
+ if (_parent._container == this)
+ {
+ _parent._container = null;
+ }
}
- Entry[] entries = _entries;
+ GC.ReRegisterForFinalize(this); // next time it's finalized, we'll be sure there are no remaining refs
+ return;
+ }
- // Make sure anyone sneaking into the table post-resurrection
- // gets booted before they can damage the native handle table.
- _invalid = true;
- _entries = null;
- _buckets = null;
+ Entry[] entries = _entries;
+ _invalid = true;
+ _entries = null;
+ _buckets = null;
+ if (entries != null)
+ {
for (int entriesIndex = 0; entriesIndex < entries.Length; entriesIndex++)
{
- entries[entriesIndex].depHnd.Free();
+ // We need to free handles in two cases:
+ // - If this container still owns the dependency handle (meaning ownership hasn't been transferred
+ // to another container that replaced this one), then it should be freed.
+ // - If this container had the entry removed, then even if in general ownership was transferred to
+ // another container, removed entries are not, therefore this container must free them.
+ if (_oldKeepAlive == null || entries[entriesIndex].HashCode == -1)
+ {
+ entries[entriesIndex].depHnd.Free();
+ }
}
}
}
}
#endregion
-
- #region Private Data Members
- //--------------------------------------------------------------------------------------------
- // Entry can be in one of three states:
- //
- // - Linked into the freeList (_freeList points to first entry)
- // depHnd.IsAllocated == false
- // hashCode == <dontcare>
- // next links to next Entry on freelist)
- //
- // - Used with live key (linked into a bucket list where _buckets[hashCode % _buckets.Length] points to first entry)
- // depHnd.IsAllocated == true, depHnd.GetPrimary() != null
- // hashCode == RuntimeHelpers.GetHashCode(depHnd.GetPrimary()) & Int32.MaxValue
- // next links to next Entry in bucket.
- //
- // - Used with dead key (linked into a bucket list where _buckets[hashCode % _buckets.Length] points to first entry)
- // depHnd.IsAllocated == true, depHnd.GetPrimary() == null
- // hashCode == <notcare>
- // next links to next Entry in bucket.
- //
- // The only difference between "used with live key" and "used with dead key" is that
- // depHnd.GetPrimary() returns null. The transition from "used with live key" to "used with dead key"
- // happens asynchronously as a result of normal garbage collection. The dictionary itself
- // receives no notification when this happens.
- //
- // When the dictionary grows the _entries table, it scours it for expired keys and puts those
- // entries back on the freelist.
- //--------------------------------------------------------------------------------------------
- private struct Entry
- {
- public DependentHandle depHnd; // Holds key and value using a weak reference for the key and a strong reference
- // for the value that is traversed only if the key is reachable without going through the value.
- public int hashCode; // Cached copy of key's hashcode
- public int next; // Index of next entry, -1 if last
- }
-
- private int[] _buckets; // _buckets[hashcode & _buckets.Length] contains index of first entry in bucket (-1 if empty)
- private Entry[] _entries;
- private int _freeList; // -1 = empty, else index of first unused Entry
- private const int _initialCapacity = 5;
- private readonly Object _lock; // this could be a ReaderWriterLock but CoreCLR does not support RWLocks.
- private bool _invalid; // flag detects if OOM or other background exception threw us out of the lock.
- #endregion
}
#endregion
-
-
-
#region DependentHandle
//=========================================================================================
// This struct collects all operations on native DependentHandles. The DependentHandle
@@ -700,15 +816,10 @@ namespace System.Runtime.CompilerServices
// to use DependentHandles in a thread-safe way.
//=========================================================================================
[ComVisible(false)]
- struct DependentHandle
+ internal struct DependentHandle
{
#region Constructors
- #if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical] // auto-generated
- #else
- [System.Security.SecurityCritical]
- #endif
- public DependentHandle(Object primary, Object secondary)
+ public DependentHandle(object primary, object secondary)
{
IntPtr handle = (IntPtr)0;
nInitialize(primary, secondary, out handle);
@@ -718,44 +829,37 @@ namespace System.Runtime.CompilerServices
#endregion
#region Public Members
- public bool IsAllocated
- {
- get
- {
- return _handle != (IntPtr)0;
- }
- }
+ public bool IsAllocated => _handle != IntPtr.Zero;
// Getting the secondary object is more expensive than getting the first so
// we provide a separate primary-only accessor for those times we only want the
// primary.
- #if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical] // auto-generated
- #else
- [System.Security.SecurityCritical]
- #endif
- public Object GetPrimary()
+ public object GetPrimary()
{
- Object primary;
+ object primary;
nGetPrimary(_handle, out primary);
return primary;
}
- #if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical] // auto-generated
- #else
- [System.Security.SecurityCritical]
- #endif
- public void GetPrimaryAndSecondary(out Object primary, out Object secondary)
+ public void GetPrimaryAndSecondary(out object primary, out object secondary)
{
nGetPrimaryAndSecondary(_handle, out primary, out secondary);
}
+ public void SetPrimary(object primary)
+ {
+ nSetPrimary(_handle, primary);
+ }
+
+ public void SetSecondary(object secondary)
+ {
+ nSetSecondary(_handle, secondary);
+ }
+
//----------------------------------------------------------------------
// Forces dependentHandle back to non-allocated state (if not already there)
// and frees the handle if needed.
//----------------------------------------------------------------------
- [System.Security.SecurityCritical]
public void Free()
{
if (_handle != (IntPtr)0)
@@ -768,20 +872,22 @@ namespace System.Runtime.CompilerServices
#endregion
#region Private Members
- [System.Security.SecurityCritical]
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern void nInitialize(Object primary, Object secondary, out IntPtr dependentHandle);
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private static extern void nInitialize(object primary, object secondary, out IntPtr dependentHandle);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private static extern void nGetPrimary(IntPtr dependentHandle, out object primary);
- [System.Security.SecurityCritical]
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern void nGetPrimary(IntPtr dependentHandle, out Object primary);
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private static extern void nGetPrimaryAndSecondary(IntPtr dependentHandle, out object primary, out object secondary);
- [System.Security.SecurityCritical]
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern void nGetPrimaryAndSecondary(IntPtr dependentHandle, out Object primary, out Object secondary);
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private static extern void nSetPrimary(IntPtr dependentHandle, object primary);
- [System.Security.SecurityCritical]
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private static extern void nSetSecondary(IntPtr dependentHandle, object secondary);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
private static extern void nFree(IntPtr dependentHandle);
#endregion
@@ -792,4 +898,3 @@ namespace System.Runtime.CompilerServices
} // struct DependentHandle
#endregion
}
-
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/DecimalConstantAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/DecimalConstantAttribute.cs
index 39a4c86b72..7bfaa7aafd 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/DecimalConstantAttribute.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/DecimalConstantAttribute.cs
@@ -6,6 +6,7 @@
// Note: If you add a new ctor overloads you need to update ParameterInfo.RawDefaultValue
using System.Reflection;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Collections.Generic;
@@ -57,16 +58,16 @@ namespace System.Runtime.CompilerServices
if (namedArgument.MemberInfo.Name.Equals("Value"))
{
// This is not possible because Decimal cannot be represented directly in the metadata.
- Contract.Assert(false, "Decimal cannot be represented directly in the metadata.");
+ Debug.Assert(false, "Decimal cannot be represented directly in the metadata.");
return (Decimal)namedArgument.TypedValue.Value;
}
}
ParameterInfo[] parameters = attr.Constructor.GetParameters();
- Contract.Assert(parameters.Length == 5);
+ Debug.Assert(parameters.Length == 5);
System.Collections.Generic.IList<CustomAttributeTypedArgument> args = attr.ConstructorArguments;
- Contract.Assert(args.Count == 5);
+ Debug.Assert(args.Count == 5);
if (parameters[2].ParameterType == typeof(uint))
{
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/FormattableStringFactory.cs b/src/mscorlib/src/System/Runtime/CompilerServices/FormattableStringFactory.cs
index aee3bc2230..4b99a8a5d9 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/FormattableStringFactory.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/FormattableStringFactory.cs
@@ -26,12 +26,12 @@ namespace System.Runtime.CompilerServices
{
if (format == null)
{
- throw new ArgumentNullException("format");
+ throw new ArgumentNullException(nameof(format));
}
if (arguments == null)
{
- throw new ArgumentNullException("arguments");
+ throw new ArgumentNullException(nameof(arguments));
}
return new ConcreteFormattableString(format, arguments);
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/HasCopySemanticsAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/HasCopySemanticsAttribute.cs
deleted file mode 100644
index 944a2868f2..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/HasCopySemanticsAttribute.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
-{
-[Serializable]
-[AttributeUsage(AttributeTargets.Struct)]
- public sealed class HasCopySemanticsAttribute : Attribute
- {
- public HasCopySemanticsAttribute()
- {}
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IDispatchConstantAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IDispatchConstantAttribute.cs
deleted file mode 100644
index d6dfcbbbb9..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/IDispatchConstantAttribute.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.Runtime.InteropServices;
-
-namespace System.Runtime.CompilerServices
-{
-[Serializable]
-[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter, Inherited=false)]
-[System.Runtime.InteropServices.ComVisible(true)]
- public sealed class IDispatchConstantAttribute : CustomConstantAttribute
- {
- public IDispatchConstantAttribute()
- {
- }
-
- public override Object Value
- {
- get
- {
- return new DispatchWrapper(null);
- }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/INotifyCompletion.cs b/src/mscorlib/src/System/Runtime/CompilerServices/INotifyCompletion.cs
index 872a79b72b..aba0a0691f 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/INotifyCompletion.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/INotifyCompletion.cs
@@ -34,7 +34,6 @@ namespace System.Runtime.CompilerServices
/// <param name="continuation">The action to invoke when the operation completes.</param>
/// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
/// <remarks>Unlike OnCompleted, UnsafeOnCompleted need not propagate ExecutionContext information.</remarks>
- [SecurityCritical]
void UnsafeOnCompleted(Action continuation);
}
}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IUnknownConstantAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IUnknownConstantAttribute.cs
deleted file mode 100644
index f8717cff52..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/IUnknownConstantAttribute.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.Runtime.InteropServices;
-
-namespace System.Runtime.CompilerServices
-{
-[Serializable]
-[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter, Inherited=false)]
-[System.Runtime.InteropServices.ComVisible(true)]
- public sealed class IUnknownConstantAttribute : CustomConstantAttribute
- {
- public IUnknownConstantAttribute()
- {
- }
-
- public override Object Value
- {
- get
- {
- return new UnknownWrapper(null);
- }
- }
-
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IsBoxed.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IsBoxed.cs
deleted file mode 100644
index 8b6691c09d..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/IsBoxed.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.
-
-namespace System.Runtime.CompilerServices
-{
- // Indicates that the modified reference type is a boxed valuetype
- public static class IsBoxed
- {
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IsByValue.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IsByValue.cs
deleted file mode 100644
index d16a853597..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/IsByValue.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.
-
-namespace System.Runtime.CompilerServices
-{
- // Indicates that the modified method argument is passed by value
- public static class IsByValue
- {
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IsConst.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IsConst.cs
deleted file mode 100644
index 210e5997a7..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/IsConst.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.
-
-namespace System.Runtime.CompilerServices
-{
- // Indicates that the modified type is const (i.e. has a const modifier)
- public static class IsConst
- {
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IsCopyConstructed.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IsCopyConstructed.cs
deleted file mode 100644
index ee40ee7b02..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/IsCopyConstructed.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.
-
-namespace System.Runtime.CompilerServices
-{
- [System.Runtime.InteropServices.ComVisible(true)]
- public static class IsCopyConstructed
- {}
-}
-
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IsExplicitlyDereferenced.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IsExplicitlyDereferenced.cs
deleted file mode 100644
index 480a62175d..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/IsExplicitlyDereferenced.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.Runtime.CompilerServices
-{
- // Consider the following C++ method prototypes:
- // 1) int foo(int ^arg);
- // 2) int foo(int &arg);
- //
- // Both of these methods will have a .NET type signature that looks the
- // same, but when importing a method from a metadata scope, the compiler
- // needs to know what the calling syntax should be. This modopt and its
- // partner "IsImplicitlyDereferenced" disambiguate reference versus
- // pointer arguments.
- //
- // Indicates that the modified GC reference represents a pointer in a
- // method signature.
- public static class IsExplicitlyDereferenced
- {
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IsImplicitlyDereferenced.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IsImplicitlyDereferenced.cs
deleted file mode 100644
index ea81cb8ec5..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/IsImplicitlyDereferenced.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.Runtime.CompilerServices
-{
- // Consider the following C++ method prototypes:
- // 1) int foo(int ^arg);
- // 2) int foo(int &arg);
- //
- // Both of these methods will have a .NET type signature that looks the
- // same, but when importing a method from a metadata scope, the compiler
- // needs to know what the calling syntax should be. This modopt and its
- // partner "IsExplicitlyDereferenced" disambiguate reference versus
- // pointer arguments.
- //
- // Indicates that the modified GC reference represents a reference in a
- // method signature.
- public static class IsImplicitlyDereferenced
- {
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IsJitIntrinsic.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IsJitIntrinsic.cs
deleted file mode 100644
index 013e50f3ea..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/IsJitIntrinsic.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
-{
- // Indicates that the modified method is an intrinsic for which the JIT
- // can perform special code generation.
- public static class IsJitIntrinsic
- {
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IsLong.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IsLong.cs
deleted file mode 100644
index e8bebfb2d3..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/IsLong.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
-{
- // The C++ standard indicates that a long is always 4-bytes, whereas the
- // size of an integer is system dependent (not exceedign sizeof(long)).
- // The CLR does not offer a mechanism for encoding this distinction,
- // but it is critically important for maintaining language level type
- // safety.
- //
- // Indicates that the modified integer is a standard C++ long.
- // Could also be called IsAlternateIntegerType or something else.
- public static class IsLong
- {
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IsPinned.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IsPinned.cs
deleted file mode 100644
index e796d1a1e7..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/IsPinned.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.
-
-namespace System.Runtime.CompilerServices
-{
- // Indicates that the modified instance is pinned in memory.
- public static class IsPinned
- {
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IsSignUnspecifiedByte.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IsSignUnspecifiedByte.cs
deleted file mode 100644
index e68f4d7751..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/IsSignUnspecifiedByte.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
-{
- // C++ recognizes three char types: signed char, unsigned char, and char.
- // When a char is neither signed nor unsigned, it is a char.
- // This modopt indicates that the modified instance is a char.
- //
- // Any compiler could use this to indicate that the user has not specified
- // Sign behavior for the given byte.
- public static class IsSignUnspecifiedByte
- {
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IsUdtReturn.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IsUdtReturn.cs
deleted file mode 100644
index dd85914b53..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/IsUdtReturn.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.
-
-namespace System.Runtime.CompilerServices
-{
- // Indicates that the return type is a user defined type
- public static class IsUdtReturn
- {
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/NativeCppClassAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/NativeCppClassAttribute.cs
deleted file mode 100644
index 0d6c759d76..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/NativeCppClassAttribute.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;
-
-namespace System.Runtime.CompilerServices {
-[Serializable]
-[AttributeUsage(AttributeTargets.Struct, Inherited = true),
- System.Runtime.InteropServices.ComVisible(true)]
- public sealed class NativeCppClassAttribute : Attribute
- {
- public NativeCppClassAttribute () {}
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/RequiredAttributeAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/RequiredAttributeAttribute.cs
deleted file mode 100644
index f363696ebd..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/RequiredAttributeAttribute.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;
-
-namespace System.Runtime.CompilerServices
-{
-[Serializable]
-[AttributeUsage (AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Interface,
- AllowMultiple=true, Inherited=false)]
-[System.Runtime.InteropServices.ComVisible(true)]
- public sealed class RequiredAttributeAttribute : Attribute
- {
- private Type requiredContract;
-
- public RequiredAttributeAttribute (Type requiredContract)
- {
- this.requiredContract= requiredContract;
- }
- public Type RequiredContract
- {
- get { return this.requiredContract; }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs b/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs
index d20fe0bffd..926eb6c3cb 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs
@@ -25,16 +25,13 @@ namespace System.Runtime.CompilerServices {
public static class RuntimeHelpers
{
-#if FEATURE_CORECLR
// Exposed here as a more appropriate place than on FormatterServices itself,
// which is a high level reflection heavy type.
public static Object GetUninitializedObject(Type type)
{
return FormatterServices.GetUninitializedObject(type);
}
-#endif // FEATURE_CORECLR
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void InitializeArray(Array array,RuntimeFieldHandle fldHandle);
@@ -51,7 +48,6 @@ namespace System.Runtime.CompilerServices {
// cloned when you pass them around, and are always passed by value.
// Of course, reference types are not cloned.
//
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern Object GetObjectValue(Object obj);
@@ -63,7 +59,6 @@ namespace System.Runtime.CompilerServices {
// This call will generate an exception if the specified class constructor threw an
// exception when it ran.
- [System.Security.SecuritySafeCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void _RunClassConstructor(RuntimeType type);
@@ -80,7 +75,6 @@ namespace System.Runtime.CompilerServices {
// This call will generate an exception if the specified module constructor threw an
// exception when it ran.
- [System.Security.SecuritySafeCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void _RunModuleConstructor(System.Reflection.RuntimeModule module);
@@ -89,72 +83,25 @@ namespace System.Runtime.CompilerServices {
_RunModuleConstructor(module.GetRuntimeModule());
}
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static unsafe extern void _PrepareMethod(IRuntimeMethodInfo method, IntPtr* pInstantiation, int cInstantiation);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
internal static extern void _CompileMethod(IRuntimeMethodInfo method);
- // Simple (instantiation not required) method.
- [System.Security.SecurityCritical] // auto-generated_required
- public static void PrepareMethod(RuntimeMethodHandle method)
+ 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)
{
- unsafe
+ if (d == null)
{
- _PrepareMethod(method.GetMethodInfo(), null, 0);
+ throw new ArgumentNullException ("d");
}
}
- // Generic method or method with generic class with specific instantiation.
- [System.Security.SecurityCritical] // auto-generated_required
- public static void PrepareMethod(RuntimeMethodHandle method, RuntimeTypeHandle[] instantiation)
- {
- unsafe
- {
- int length;
- IntPtr[] instantiationHandles = RuntimeTypeHandle.CopyRuntimeTypeHandles(instantiation, out length);
- fixed (IntPtr* pInstantiation = instantiationHandles)
- {
- _PrepareMethod(method.GetMethodInfo(), pInstantiation, length);
- GC.KeepAlive(instantiation);
- }
- }
- }
-
- // 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. In other words, this service does not navigate through the
- // entire multicasting list.
- // If our own reliable event sinks perform the Combine (for example AppDomain.DomainUnload),
- // then the result is fully prepared. But if a client calls Combine himself and then
- // then adds that combination to e.g. AppDomain.DomainUnload, then the client is responsible
- // for his own preparation.
- [System.Security.SecurityCritical] // auto-generated_required
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern void PrepareDelegate(Delegate d);
-
- // See comment above for PrepareDelegate
- //
- // PrepareContractedDelegate weakens this a bit by only assuring that we prepare
- // delegates which also have a ReliabilityContract. This is useful for services that
- // want to provide opt-in reliability, generally some random event sink providing
- // always reliable semantics to random event handlers that are likely to have not
- // been written with relability in mind is a lost cause anyway.
- //
- // NOTE: that for the NGen case you can sidestep the required ReliabilityContract
- // by using the [PrePrepareMethod] attribute.
- [System.Security.SecurityCritical] // auto-generated_required
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern void PrepareContractedDelegate(Delegate d);
-
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern int GetHashCode(Object o);
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public new static extern bool Equals(Object o1, Object o2);
@@ -183,30 +130,24 @@ namespace System.Runtime.CompilerServices {
// If there is not enough stack, then it throws System.InsufficientExecutionStackException.
// Note: this method is not part of the CER support, and is not to be confused with ProbeForSufficientStack
// below.
- [System.Security.SecuritySafeCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static extern void EnsureSufficientExecutionStack();
-#if FEATURE_CORECLR
// This method ensures that there is sufficient stack to execute the average Framework function.
// If there is not enough stack, then it return false.
// Note: this method is not part of the CER support, and is not to be confused with ProbeForSufficientStack
// below.
- [System.Security.SecuritySafeCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- internal static extern bool TryEnsureSufficientExecutionStack();
-#endif
+ public static extern bool TryEnsureSufficientExecutionStack();
- [System.Security.SecurityCritical] // auto-generated_required
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
- public static extern void ProbeForSufficientStack();
+ public static void ProbeForSufficientStack()
+ {
+ }
// This method is a marker placed immediately before a try clause to mark the corresponding catch and finally blocks as
// constrained. There's no code here other than the probe because most of the work is done at JIT time when we spot a call to this routine.
- [System.Security.SecurityCritical] // auto-generated_required
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public static void PrepareConstrainedRegions()
{
@@ -215,29 +156,18 @@ namespace System.Runtime.CompilerServices {
// When we detect a CER with no calls, we can point the JIT to this non-probing version instead
// as we don't need to probe.
- [System.Security.SecurityCritical] // auto-generated_required
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public static void PrepareConstrainedRegionsNoOP()
{
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
public delegate void TryCode(Object userData);
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
public delegate void CleanupCode(Object userData, bool exceptionThrown);
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData);
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
[PrePrepareMethod]
internal static void ExecuteBackoutCodeHelper(Object backoutCode, Object userData, bool exceptionThrown)
{
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeWrappedException.cs b/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeWrappedException.cs
index 2751d61db7..d2691df6b9 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeWrappedException.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeWrappedException.cs
@@ -33,10 +33,9 @@ namespace System.Runtime.CompilerServices {
private Object m_wrappedException;
- [System.Security.SecurityCritical] // auto-generated_required
public override void GetObjectData(SerializationInfo info, StreamingContext context) {
if (info==null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
base.GetObjectData(info, context);
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/ScopelessEnumAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/ScopelessEnumAttribute.cs
deleted file mode 100644
index 91769187cc..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/ScopelessEnumAttribute.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
-{
-[Serializable]
-[AttributeUsage(AttributeTargets.Enum)]
- public sealed class ScopelessEnumAttribute : Attribute
- {
- public ScopelessEnumAttribute()
- {}
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/TaskAwaiter.cs b/src/mscorlib/src/System/Runtime/CompilerServices/TaskAwaiter.cs
index ea6bb96e16..98a81ea470 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/TaskAwaiter.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/TaskAwaiter.cs
@@ -57,7 +57,6 @@ namespace System.Runtime.CompilerServices
{
/// <summary>Provides an awaiter for awaiting a <see cref="System.Threading.Tasks.Task"/>.</summary>
/// <remarks>This type is intended for compiler use only.</remarks>
- [HostProtection(Synchronization = true, ExternalThreading = true)]
public struct TaskAwaiter : ICriticalNotifyCompletion
{
/// <summary>The task being awaited.</summary>
@@ -84,7 +83,6 @@ namespace System.Runtime.CompilerServices
/// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
/// <exception cref="System.InvalidOperationException">The awaiter was not properly initialized.</exception>
/// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
- [SecuritySafeCritical]
public void OnCompleted(Action continuation)
{
OnCompletedInternal(m_task, continuation, continueOnCapturedContext:true, flowExecutionContext:true);
@@ -95,7 +93,6 @@ namespace System.Runtime.CompilerServices
/// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
/// <exception cref="System.InvalidOperationException">The awaiter was not properly initialized.</exception>
/// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
- [SecurityCritical]
public void UnsafeOnCompleted(Action continuation)
{
OnCompletedInternal(m_task, continuation, continueOnCapturedContext:true, flowExecutionContext:false);
@@ -143,7 +140,7 @@ namespace System.Runtime.CompilerServices
if (!task.IsCompleted)
{
bool taskCompleted = task.InternalWait(Timeout.Infinite, default(CancellationToken));
- Contract.Assert(taskCompleted, "With an infinite timeout, the task should have always completed.");
+ Debug.Assert(taskCompleted, "With an infinite timeout, the task should have always completed.");
}
// Now that we're done, alert the debugger if so requested
@@ -171,7 +168,7 @@ namespace System.Runtime.CompilerServices
if (oceEdi != null)
{
oceEdi.Throw();
- Contract.Assert(false, "Throw() should have thrown");
+ Debug.Assert(false, "Throw() should have thrown");
}
throw new TaskCanceledException(task);
@@ -182,12 +179,12 @@ namespace System.Runtime.CompilerServices
if (edis.Count > 0)
{
edis[0].Throw();
- Contract.Assert(false, "Throw() should have thrown");
+ Debug.Assert(false, "Throw() should have thrown");
break; // Necessary to compile: non-reachable, but compiler can't determine that
}
else
{
- Contract.Assert(false, "There should be exceptions if we're Faulted.");
+ Debug.Assert(false, "There should be exceptions if we're Faulted.");
throw task.Exception;
}
}
@@ -202,10 +199,9 @@ namespace System.Runtime.CompilerServices
/// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
/// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
- [SecurityCritical]
internal static void OnCompletedInternal(Task task, Action continuation, bool continueOnCapturedContext, bool flowExecutionContext)
{
- if (continuation == null) throw new ArgumentNullException("continuation");
+ if (continuation == null) throw new ArgumentNullException(nameof(continuation));
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
// If TaskWait* ETW events are enabled, trace a beginning event for this await
@@ -294,7 +290,6 @@ namespace System.Runtime.CompilerServices
/// <summary>Provides an awaiter for awaiting a <see cref="System.Threading.Tasks.Task{TResult}"/>.</summary>
/// <remarks>This type is intended for compiler use only.</remarks>
- [HostProtection(Synchronization = true, ExternalThreading = true)]
public struct TaskAwaiter<TResult> : ICriticalNotifyCompletion
{
/// <summary>The task being awaited.</summary>
@@ -321,7 +316,6 @@ namespace System.Runtime.CompilerServices
/// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
/// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
/// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
- [SecuritySafeCritical]
public void OnCompleted(Action continuation)
{
TaskAwaiter.OnCompletedInternal(m_task, continuation, continueOnCapturedContext:true, flowExecutionContext:true);
@@ -332,7 +326,6 @@ namespace System.Runtime.CompilerServices
/// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
/// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
/// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
- [SecurityCritical]
public void UnsafeOnCompleted(Action continuation)
{
TaskAwaiter.OnCompletedInternal(m_task, continuation, continueOnCapturedContext:true, flowExecutionContext:false);
@@ -377,7 +370,6 @@ namespace System.Runtime.CompilerServices
/// <summary>Provides an awaiter for a <see cref="ConfiguredTaskAwaitable"/>.</summary>
/// <remarks>This type is intended for compiler use only.</remarks>
- [HostProtection(Synchronization = true, ExternalThreading = true)]
public struct ConfiguredTaskAwaiter : ICriticalNotifyCompletion
{
/// <summary>The task being awaited.</summary>
@@ -411,7 +403,6 @@ namespace System.Runtime.CompilerServices
/// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
/// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
/// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
- [SecuritySafeCritical]
public void OnCompleted(Action continuation)
{
TaskAwaiter.OnCompletedInternal(m_task, continuation, m_continueOnCapturedContext, flowExecutionContext:true);
@@ -422,7 +413,6 @@ namespace System.Runtime.CompilerServices
/// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
/// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
/// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
- [SecurityCritical]
public void UnsafeOnCompleted(Action continuation)
{
TaskAwaiter.OnCompletedInternal(m_task, continuation, m_continueOnCapturedContext, flowExecutionContext:false);
@@ -466,7 +456,6 @@ namespace System.Runtime.CompilerServices
/// <summary>Provides an awaiter for a <see cref="ConfiguredTaskAwaitable{TResult}"/>.</summary>
/// <remarks>This type is intended for compiler use only.</remarks>
- [HostProtection(Synchronization = true, ExternalThreading = true)]
public struct ConfiguredTaskAwaiter : ICriticalNotifyCompletion
{
/// <summary>The task being awaited.</summary>
@@ -499,7 +488,6 @@ namespace System.Runtime.CompilerServices
/// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
/// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
/// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
- [SecuritySafeCritical]
public void OnCompleted(Action continuation)
{
TaskAwaiter.OnCompletedInternal(m_task, continuation, m_continueOnCapturedContext, flowExecutionContext:true);
@@ -510,7 +498,6 @@ namespace System.Runtime.CompilerServices
/// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
/// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
/// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
- [SecurityCritical]
public void UnsafeOnCompleted(Action continuation)
{
TaskAwaiter.OnCompletedInternal(m_task, continuation, m_continueOnCapturedContext, flowExecutionContext:false);
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/TypeDependencyAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/TypeDependencyAttribute.cs
index db04eb9348..2de9c1f785 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/TypeDependencyAttribute.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/TypeDependencyAttribute.cs
@@ -17,7 +17,7 @@ namespace System.Runtime.CompilerServices
public TypeDependencyAttribute (string typeName)
{
- if(typeName == null) throw new ArgumentNullException("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
index c1656dcf99..671d1f0071 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/TypeForwardedFromAttribute.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/TypeForwardedFromAttribute.cs
@@ -20,7 +20,7 @@ namespace System.Runtime.CompilerServices
{
if (String.IsNullOrEmpty(assemblyFullName))
{
- throw new ArgumentNullException("assemblyFullName");
+ throw new ArgumentNullException(nameof(assemblyFullName));
}
this.assemblyFullName = assemblyFullName;
}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/TypeForwardedToAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/TypeForwardedToAttribute.cs
index 034dad1afe..d9e067bd4c 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/TypeForwardedToAttribute.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/TypeForwardedToAttribute.cs
@@ -26,7 +26,6 @@ namespace System.Runtime.CompilerServices
}
}
- [System.Security.SecurityCritical]
internal static TypeForwardedToAttribute[] GetCustomAttribute(RuntimeAssembly assembly)
{
Type[] types = null;
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/Unsafe.cs b/src/mscorlib/src/System/Runtime/CompilerServices/Unsafe.cs
new file mode 100644
index 0000000000..b212f4555b
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/Unsafe.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.
+
+using System.Runtime.Versioning;
+
+namespace System.Runtime.CompilerServices
+{
+ //
+ // Subsetted clone of System.Runtime.CompilerServices.Unsafe for internal runtime use.
+ // Keep in sync with https://github.com/dotnet/corefx/tree/master/src/System.Runtime.CompilerServices.Unsafe.
+ //
+
+ /// <summary>
+ /// Contains generic, low-level functionality for manipulating pointers.
+ /// </summary>
+ internal static unsafe class Unsafe
+ {
+ /// <summary>
+ /// Returns a pointer to the given by-ref parameter.
+ /// </summary>
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void* AsPointer<T>(ref T value)
+ {
+ // The body of this function will be replaced by the EE with unsafe code!!!
+ // See getILIntrinsicImplementationForUnsafe for how this happens.
+ throw new InvalidOperationException();
+ }
+
+ /// <summary>
+ /// Returns the size of an object of the given type parameter.
+ /// </summary>
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int SizeOf<T>()
+ {
+ // 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.
+ throw new InvalidOperationException();
+ }
+
+ /// <summary>
+ /// Reinterprets the given reference as a reference to a value of type <typeparamref name="TTo"/>.
+ /// </summary>
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static ref TTo As<TFrom, TTo>(ref TFrom source)
+ {
+ // The body of this function will be replaced by the EE with unsafe code!!!
+ // See getILIntrinsicImplementationForUnsafe for how this happens.
+ throw new InvalidOperationException();
+ }
+
+ /// <summary>
+ /// Adds an element offset to the given reference.
+ /// </summary>
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static ref T Add<T>(ref T source, int elementOffset)
+ {
+ // 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
+ throw new InvalidOperationException();
+ }
+
+ /// <summary>
+ /// Determines whether the specified references point to the same location.
+ /// </summary>
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool AreSame<T>(ref T left, ref T right)
+ {
+ // The body of this function will be replaced by the EE with unsafe code!!!
+ // See getILIntrinsicImplementationForUnsafe for how this happens.
+ throw new InvalidOperationException();
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/YieldAwaitable.cs b/src/mscorlib/src/System/Runtime/CompilerServices/YieldAwaitable.cs
index b29b39c5bf..86789bf12d 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/YieldAwaitable.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/YieldAwaitable.cs
@@ -48,7 +48,6 @@ namespace System.Runtime.CompilerServices
/// <summary>Provides an awaiter that switches into a target environment.</summary>
/// <remarks>This type is intended for compiler use only.</remarks>
- [HostProtection(Synchronization = true, ExternalThreading = true)]
public struct YieldAwaiter : ICriticalNotifyCompletion
{
/// <summary>Gets whether a yield is not required.</summary>
@@ -58,7 +57,6 @@ namespace System.Runtime.CompilerServices
/// <summary>Posts the <paramref name="continuation"/> back to the current context.</summary>
/// <param name="continuation">The action to invoke asynchronously.</param>
/// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
- [SecuritySafeCritical]
public void OnCompleted(Action continuation)
{
QueueContinuation(continuation, flowContext: true);
@@ -67,7 +65,6 @@ namespace System.Runtime.CompilerServices
/// <summary>Posts the <paramref name="continuation"/> back to the current context.</summary>
/// <param name="continuation">The action to invoke asynchronously.</param>
/// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
- [SecurityCritical]
public void UnsafeOnCompleted(Action continuation)
{
QueueContinuation(continuation, flowContext: false);
@@ -77,11 +74,10 @@ namespace System.Runtime.CompilerServices
/// <param name="continuation">The action to invoke asynchronously.</param>
/// <param name="flowContext">true to flow ExecutionContext; false if flowing is not required.</param>
/// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
- [SecurityCritical]
private static void QueueContinuation(Action continuation, bool flowContext)
{
// Validate arguments
- if (continuation == null) throw new ArgumentNullException("continuation");
+ if (continuation == null) throw new ArgumentNullException(nameof(continuation));
Contract.EndContractBlock();
if (TplEtwProvider.Log.IsEnabled())
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/jithelpers.cs b/src/mscorlib/src/System/Runtime/CompilerServices/jithelpers.cs
index 8ee50da290..c1346f7527 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/jithelpers.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/jithelpers.cs
@@ -11,6 +11,7 @@ using System;
using System.Threading;
using System.Runtime;
using System.Runtime.Versioning;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
using System.Security;
@@ -60,6 +61,12 @@ namespace System.Runtime.CompilerServices {
public byte m_data;
}
+ internal class ArrayPinningHelper
+ {
+ public IntPtr m_lengthAndPadding;
+ public byte m_arrayData;
+ }
+
[FriendAccessAllowed]
internal static class JitHelpers
{
@@ -68,7 +75,6 @@ namespace System.Runtime.CompilerServices {
// Wraps object variable into a handle. Used to return managed strings from QCalls.
// s has to be a local variable on the stack.
- [SecurityCritical]
static internal StringHandleOnStack GetStringHandleOnStack(ref string s)
{
return new StringHandleOnStack(UnsafeCastToStackPointer(ref s));
@@ -76,7 +82,6 @@ namespace System.Runtime.CompilerServices {
// Wraps object variable into a handle. Used to pass managed object references in and out of QCalls.
// o has to be a local variable on the stack.
- [SecurityCritical]
static internal ObjectHandleOnStack GetObjectHandleOnStack<T>(ref T o) where T : class
{
return new ObjectHandleOnStack(UnsafeCastToStackPointer(ref o));
@@ -84,25 +89,22 @@ namespace System.Runtime.CompilerServices {
// Wraps StackCrawlMark into a handle. Used to pass StackCrawlMark to QCalls.
// stackMark has to be a local variable on the stack.
- [SecurityCritical]
static internal StackCrawlMarkHandle GetStackCrawlMarkHandle(ref StackCrawlMark stackMark)
{
return new StackCrawlMarkHandle(UnsafeCastToStackPointer(ref stackMark));
}
#if _DEBUG
- [SecurityCritical]
[FriendAccessAllowed]
static internal T UnsafeCast<T>(Object o) where T : class
{
T ret = UnsafeCastInternal<T>(o);
- Contract.Assert(ret == (o as T), "Invalid use of JitHelpers.UnsafeCast!");
+ Debug.Assert(ret == (o as T), "Invalid use of JitHelpers.UnsafeCast!");
return ret;
}
// The IL body of this method is not critical, but its body will be replaced with unsafe code, so
// this method is effectively critical
- [SecurityCritical]
static private T UnsafeCastInternal<T>(Object o) where T : class
{
// The body of this function will be replaced by the EE with unsafe code that just returns o!!!
@@ -112,7 +114,7 @@ namespace System.Runtime.CompilerServices {
static internal int UnsafeEnumCast<T>(T val) where T : struct // Actually T must be 4 byte (or less) enum
{
- Contract.Assert(typeof(T).IsEnum
+ Debug.Assert(typeof(T).IsEnum
&& (Enum.GetUnderlyingType(typeof(T)) == typeof(int)
|| Enum.GetUnderlyingType(typeof(T)) == typeof(uint)
|| Enum.GetUnderlyingType(typeof(T)) == typeof(short)
@@ -132,7 +134,7 @@ namespace System.Runtime.CompilerServices {
static internal long UnsafeEnumCastLong<T>(T val) where T : struct // Actually T must be 8 byte enum
{
- Contract.Assert(typeof(T).IsEnum
+ 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!");
@@ -148,15 +150,13 @@ namespace System.Runtime.CompilerServices {
// Internal method for getting a raw pointer for handles in JitHelpers.
// The reference has to point into a local stack variable in order so it can not be moved by the GC.
- [SecurityCritical]
static internal IntPtr UnsafeCastToStackPointer<T>(ref T val)
{
IntPtr p = UnsafeCastToStackPointerInternal<T>(ref val);
- Contract.Assert(IsAddressInStack(p), "Pointer not in the stack!");
+ Debug.Assert(IsAddressInStack(p), "Pointer not in the stack!");
return p;
}
- [SecurityCritical]
static private IntPtr UnsafeCastToStackPointerInternal<T>(ref T val)
{
// The body of this function will be replaced by the EE with unsafe code that just returns val!!!
@@ -166,7 +166,6 @@ namespace System.Runtime.CompilerServices {
#else // _DEBUG
// The IL body of this method is not critical, but its body will be replaced with unsafe code, so
// this method is effectively critical
- [SecurityCritical]
[FriendAccessAllowed]
static internal T UnsafeCast<T>(Object o) where T : class
{
@@ -189,7 +188,6 @@ namespace System.Runtime.CompilerServices {
throw new InvalidOperationException();
}
- [SecurityCritical]
static internal IntPtr UnsafeCastToStackPointer<T>(ref T val)
{
// The body of this function will be replaced by the EE with unsafe code that just returns o!!!
@@ -199,12 +197,10 @@ namespace System.Runtime.CompilerServices {
#endif // _DEBUG
// Set the given element in the array without any type or range checks
- [SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
extern static internal void UnsafeSetArrayElement(Object[] target, int index, Object element);
// Used for unsafe pinning of arbitrary objects.
- [System.Security.SecurityCritical] // auto-generated
static internal PinningHelper GetPinningHelper(Object o)
{
// This cast is really unsafe - call the private version that does not assert in debug
@@ -216,9 +212,33 @@ namespace System.Runtime.CompilerServices {
}
#if _DEBUG
- [SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
extern static bool IsAddressInStack(IntPtr ptr);
#endif
+
+#if FEATURE_SPAN_OF_T
+ static internal bool ByRefLessThan<T>(ref T refA, ref T refB)
+ {
+ // The body of this function will be replaced by the EE with unsafe code!!!
+ // See getILIntrinsicImplementation for how this happens.
+ 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!!!
+ // See getILIntrinsicImplementation for how this happens.
+ typeof(ArrayPinningHelper).ToString(); // Type used by the actual method body
+ throw new InvalidOperationException();
+ }
+#endif // FEATURE_SPAN_OF_T
}
}
diff --git a/src/mscorlib/src/System/Runtime/ExceptionServices/ExceptionNotification.cs b/src/mscorlib/src/System/Runtime/ExceptionServices/ExceptionNotification.cs
new file mode 100644
index 0000000000..b084891768
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/ExceptionServices/ExceptionNotification.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.
+/*=============================================================================
+**
+** File: ExceptionNotification.cs
+**
+**
+** Purpose: Contains definitions for supporting Exception Notifications.
+**
+** Created: 10/07/2008
+**
+** <owner>gkhanna</owner>
+**
+=============================================================================*/
+#if FEATURE_EXCEPTION_NOTIFICATIONS
+namespace System.Runtime.ExceptionServices {
+ using System;
+ using System.Runtime.ConstrainedExecution;
+
+ // Definition of the argument-type passed to the FirstChanceException event handler
+ public class FirstChanceExceptionEventArgs : EventArgs
+ {
+ // Constructor
+ public FirstChanceExceptionEventArgs(Exception exception)
+ {
+ m_Exception = exception;
+ }
+
+ // Returns the exception object pertaining to the first chance exception
+ public Exception Exception
+ {
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ get { return m_Exception; }
+ }
+
+ // Represents the FirstChance exception instance
+ private Exception m_Exception;
+ }
+}
+#endif // FEATURE_EXCEPTION_NOTIFICATIONS \ No newline at end of file
diff --git a/src/mscorlib/src/System/Runtime/ExceptionServices/ExceptionServicesCommon.cs b/src/mscorlib/src/System/Runtime/ExceptionServices/ExceptionServicesCommon.cs
index 7251d901cd..905f12dfb5 100644
--- a/src/mscorlib/src/System/Runtime/ExceptionServices/ExceptionServicesCommon.cs
+++ b/src/mscorlib/src/System/Runtime/ExceptionServices/ExceptionServicesCommon.cs
@@ -101,7 +101,7 @@ namespace System.Runtime.ExceptionServices {
{
if (source == null)
{
- throw new ArgumentNullException("source", Environment.GetResourceString("ArgumentNull_Obj"));
+ throw new ArgumentNullException(nameof(source), Environment.GetResourceString("ArgumentNull_Obj"));
}
return new ExceptionDispatchInfo(source);
diff --git a/src/mscorlib/src/System/Runtime/GcSettings.cs b/src/mscorlib/src/System/Runtime/GcSettings.cs
index 5b4be27757..91997f5297 100644
--- a/src/mscorlib/src/System/Runtime/GcSettings.cs
+++ b/src/mscorlib/src/System/Runtime/GcSettings.cs
@@ -40,7 +40,6 @@ namespace System.Runtime {
public static GCLatencyMode LatencyMode
{
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
get
{
@@ -48,8 +47,6 @@ namespace System.Runtime {
}
// We don't want to allow this API when hosted.
- [System.Security.SecurityCritical] // auto-generated_required
- [HostProtection(MayLeakOnAbort = true)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
set
{
@@ -66,7 +63,6 @@ namespace System.Runtime {
public static GCLargeObjectHeapCompactionMode LargeObjectHeapCompactionMode
{
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
get
{
@@ -74,8 +70,6 @@ namespace System.Runtime {
}
// We don't want to allow this API when hosted.
- [System.Security.SecurityCritical] // auto-generated_required
- [HostProtection(MayLeakOnAbort = true)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
set
{
@@ -92,7 +86,6 @@ namespace System.Runtime {
public static bool IsServerGC
{
- [System.Security.SecuritySafeCritical] // auto-generated
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 83eae1c59c..77db3a7f2c 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ArrayWithOffset.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ArrayWithOffset.cs
@@ -17,7 +17,6 @@ namespace System.Runtime.InteropServices {
// throw new Exception();
//}
- [System.Security.SecuritySafeCritical] // auto-generated
public ArrayWithOffset(Object array, int offset)
{
m_array = array;
@@ -64,7 +63,6 @@ namespace System.Runtime.InteropServices {
return !(a == b);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern int CalculateCount();
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/Attributes.cs b/src/mscorlib/src/System/Runtime/InteropServices/Attributes.cs
index 06c963a555..2de7304a0b 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/Attributes.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/Attributes.cs
@@ -8,6 +8,7 @@ namespace System.Runtime.InteropServices{
using System;
using System.Reflection;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
[AttributeUsage(AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
@@ -525,31 +526,26 @@ namespace System.Runtime.InteropServices{
[System.Runtime.InteropServices.ComVisible(true)]
public unsafe sealed class MarshalAsAttribute : Attribute
{
- [System.Security.SecurityCritical] // auto-generated
internal static Attribute GetCustomAttribute(RuntimeParameterInfo parameter)
{
return GetCustomAttribute(parameter.MetadataToken, parameter.GetRuntimeModule());
}
- [System.Security.SecurityCritical] // auto-generated
internal static bool IsDefined(RuntimeParameterInfo parameter)
{
return GetCustomAttribute(parameter) != null;
}
- [System.Security.SecurityCritical] // auto-generated
internal static Attribute GetCustomAttribute(RuntimeFieldInfo field)
{
return GetCustomAttribute(field.MetadataToken, field.GetRuntimeModule()); ;
}
- [System.Security.SecurityCritical] // auto-generated
internal static bool IsDefined(RuntimeFieldInfo field)
{
return GetCustomAttribute(field) != null;
}
- [System.Security.SecurityCritical] // auto-generated
internal static Attribute GetCustomAttribute(int token, RuntimeModule scope)
{
UnmanagedType unmanagedType, arraySubType;
@@ -578,7 +574,7 @@ namespace System.Runtime.InteropServices{
{
// The user may have supplied a bad type name string causing this TypeLoadException
// Regardless, we return the bad type name
- Contract.Assert(marshalTypeName != null);
+ Debug.Assert(marshalTypeName != null);
}
return new MarshalAsAttribute(
@@ -772,7 +768,6 @@ namespace System.Runtime.InteropServices{
[System.Runtime.InteropServices.ComVisible(true)]
public unsafe sealed class DllImportAttribute : Attribute
{
- [System.Security.SecurityCritical] // auto-generated
internal static Attribute GetCustomAttribute(RuntimeMethodInfo method)
{
if ((method.Attributes & MethodAttributes.PinvokeImpl) == 0)
@@ -869,7 +864,6 @@ namespace System.Runtime.InteropServices{
{
private const int DEFAULT_PACKING_SIZE = 8;
- [System.Security.SecurityCritical] // auto-generated
internal static Attribute GetCustomAttribute(RuntimeType type)
{
if (!IsDefined(type))
@@ -940,7 +934,6 @@ namespace System.Runtime.InteropServices{
[System.Runtime.InteropServices.ComVisible(true)]
public unsafe sealed class FieldOffsetAttribute : Attribute
{
- [System.Security.SecurityCritical] // auto-generated
internal static Attribute GetCustomAttribute(RuntimeFieldInfo field)
{
int fieldOffset;
@@ -952,7 +945,6 @@ namespace System.Runtime.InteropServices{
return null;
}
- [System.Security.SecurityCritical] // auto-generated
internal static bool IsDefined(RuntimeFieldInfo field)
{
return GetCustomAttribute(field) != null;
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/BStrWrapper.cs b/src/mscorlib/src/System/Runtime/InteropServices/BStrWrapper.cs
index 58e93a87ea..1673c913a6 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/BStrWrapper.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/BStrWrapper.cs
@@ -21,19 +21,11 @@ namespace System.Runtime.InteropServices {
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class BStrWrapper
{
- [System.Security.SecuritySafeCritical] // auto-generated
-#pragma warning disable 618
- [SecurityPermissionAttribute(SecurityAction.Demand,Flags=SecurityPermissionFlag.UnmanagedCode)]
-#pragma warning restore 618
public BStrWrapper(String value)
{
m_WrappedObject = value;
}
- [System.Security.SecuritySafeCritical] // auto-generated
-#pragma warning disable 618
- [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
-#pragma warning restore 618
public BStrWrapper(Object value)
{
m_WrappedObject = (String)value;
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/COMException.cs b/src/mscorlib/src/System/Runtime/InteropServices/COMException.cs
index 95b925c3f4..fd500fdbce 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/COMException.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/COMException.cs
@@ -46,7 +46,6 @@ namespace System.Runtime.InteropServices {
SetErrorCode(errorCode);
}
- [SecuritySafeCritical]
internal COMException(int hresult)
: base(Win32Native.GetMessage(hresult))
{
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComEventsHelper.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComEventsHelper.cs
index 0bf616d94c..82692c1c54 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ComEventsHelper.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComEventsHelper.cs
@@ -115,7 +115,6 @@ 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>
- [System.Security.SecurityCritical]
public static void Combine(object rcw, Guid iid, int dispid, System.Delegate d) {
rcw = UnwrapIfTransparentProxy(rcw);
@@ -146,7 +145,6 @@ 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>
- [System.Security.SecurityCritical]
public static Delegate Remove(object rcw, Guid iid, int dispid, System.Delegate d) {
rcw = UnwrapIfTransparentProxy(rcw);
@@ -183,18 +181,8 @@ namespace System.Runtime.InteropServices {
}
}
- [System.Security.SecurityCritical]
- internal static object UnwrapIfTransparentProxy(object rcw) {
-#if FEATURE_REMOTING
- if (RemotingServices.IsTransparentProxy(rcw)) {
- IntPtr punk = Marshal.GetIUnknownForObject(rcw);
- try {
- rcw = Marshal.GetObjectForIUnknown(punk);
- } finally {
- Marshal.Release(punk);
- }
- }
-#endif
+ internal static object UnwrapIfTransparentProxy(object rcw)
+ {
return rcw;
}
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComEventsInfo.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComEventsInfo.cs
index 6feb52445d..2456ba35bf 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ComEventsInfo.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComEventsInfo.cs
@@ -17,7 +17,6 @@ namespace System.Runtime.InteropServices {
using ComTypes = System.Runtime.InteropServices.ComTypes;
// see code:ComEventsHelper#ComEventsArchitecture
- [System.Security.SecurityCritical]
internal class ComEventsInfo {
@@ -35,7 +34,6 @@ namespace System.Runtime.InteropServices {
_rcw = rcw;
}
- [System.Security.SecuritySafeCritical]
~ComEventsInfo() {
// see code:ComEventsHelper#ComEventsFinalization
_sinks = ComEventsSink.RemoveAll(_sinks);
@@ -46,13 +44,11 @@ namespace System.Runtime.InteropServices {
#region static methods
- [System.Security.SecurityCritical]
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)
- [System.Security.SecurityCritical]
internal static ComEventsInfo FromObject(object rcw) {
ComEventsInfo eventsInfo = Find(rcw);
if (eventsInfo == null) {
@@ -80,7 +76,6 @@ namespace System.Runtime.InteropServices {
}
// it is caller's responsibility to call this method under lock(rcw)
- [System.Security.SecurityCritical]
internal ComEventsSink RemoveSink(ComEventsSink sink) {
_sinks = ComEventsSink.Remove(_sinks, sink);
return _sinks;
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComEventsSink.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComEventsSink.cs
index a414eff3a1..05978a607f 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ComEventsSink.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComEventsSink.cs
@@ -16,7 +16,6 @@ namespace System.Runtime.InteropServices {
using System.Diagnostics;
// see code:ComEventsHelper#ComEventsArchitecture
- [System.Security.SecurityCritical]
internal class ComEventsSink : NativeMethods.IDispatch, ICustomQueryInterface
{
#region private fields
@@ -57,7 +56,6 @@ namespace System.Runtime.InteropServices {
return sink;
}
- [System.Security.SecurityCritical]
internal static ComEventsSink RemoveAll(ComEventsSink sinks) {
while (sinks != null) {
sinks.Unadvise();
@@ -67,7 +65,6 @@ namespace System.Runtime.InteropServices {
return null;
}
- [System.Security.SecurityCritical]
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");
@@ -114,17 +111,14 @@ namespace System.Runtime.InteropServices {
#region IDispatch Members
- [System.Security.SecurityCritical]
void NativeMethods.IDispatch.GetTypeInfoCount(out uint pctinfo) {
pctinfo = 0;
}
- [System.Security.SecurityCritical]
void NativeMethods.IDispatch.GetTypeInfo(uint iTInfo, int lcid, out IntPtr info) {
throw new NotImplementedException();
}
- [System.Security.SecurityCritical]
void NativeMethods.IDispatch.GetIDsOfNames(ref Guid iid, string[] names, uint cNames, int lcid, int[] rgDispId) {
throw new NotImplementedException();
}
@@ -149,7 +143,6 @@ namespace System.Runtime.InteropServices {
return pSrc;
}
- [System.Security.SecurityCritical]
unsafe void NativeMethods.IDispatch.Invoke(
int dispid,
ref Guid riid,
@@ -233,7 +226,6 @@ namespace System.Runtime.InteropServices {
static Guid IID_IManagedObject = new Guid("{C3FCC19E-A970-11D2-8B5A-00A0C9B7C9C4}");
- [System.Security.SecurityCritical]
CustomQueryInterfaceResult ICustomQueryInterface.GetInterface(ref Guid iid, out IntPtr ppv) {
ppv = IntPtr.Zero;
if (iid == this._iidSourceItf || iid == typeof(NativeMethods.IDispatch).GUID) {
@@ -265,7 +257,6 @@ namespace System.Runtime.InteropServices {
_connectionPoint = cp;
}
- [System.Security.SecurityCritical]
private void Unadvise() {
BCLDebug.Assert(_connectionPoint != null, "can not unadvise from empty connection point");
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/CriticalHandle.cs b/src/mscorlib/src/System/Runtime/InteropServices/CriticalHandle.cs
index 54fd6b0cdd..700e059293 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/CriticalHandle.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/CriticalHandle.cs
@@ -139,10 +139,6 @@ namespace System.Runtime.InteropServices
// 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.
-[System.Security.SecurityCritical] // auto-generated_required
-#if !FEATURE_CORECLR
-[SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode=true)]
-#endif
public abstract class CriticalHandle : CriticalFinalizerObject, IDisposable
{
// ! Do not add or rearrange fields as the EE depends on this layout.
@@ -168,19 +164,15 @@ public abstract class CriticalHandle : CriticalFinalizerObject, IDisposable
#endif
}
-#if FEATURE_CORECLR
// Adding an empty default constructor for annotation purposes
private CriticalHandle(){}
-#endif
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
~CriticalHandle()
{
Dispose(false);
}
- [System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
private void Cleanup()
{
@@ -229,20 +221,17 @@ public abstract class CriticalHandle : CriticalFinalizerObject, IDisposable
get;
}
- [System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public void Close() {
Dispose(true);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public void Dispose()
{
Dispose(true);
}
- [System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
protected virtual void Dispose(bool disposing)
{
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/CurrencyWrapper.cs b/src/mscorlib/src/System/Runtime/InteropServices/CurrencyWrapper.cs
index 1f7a9f18bf..470e7b20dd 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/CurrencyWrapper.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/CurrencyWrapper.cs
@@ -27,7 +27,7 @@ namespace System.Runtime.InteropServices {
public CurrencyWrapper(Object obj)
{
if (!(obj is Decimal))
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDecimal"), "obj");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDecimal"), nameof(obj));
m_WrappedObject = (Decimal)obj;
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/DispatchWrapper.cs b/src/mscorlib/src/System/Runtime/InteropServices/DispatchWrapper.cs
index 1fc72f74c8..47b7542caf 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/DispatchWrapper.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/DispatchWrapper.cs
@@ -21,10 +21,6 @@ namespace System.Runtime.InteropServices {
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class DispatchWrapper
{
- [System.Security.SecuritySafeCritical] // auto-generated
-#pragma warning disable 618
- [SecurityPermissionAttribute(SecurityAction.Demand,Flags=SecurityPermissionFlag.UnmanagedCode)]
-#pragma warning restore 618
public DispatchWrapper(Object obj)
{
if (obj != null)
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ErrorWrapper.cs b/src/mscorlib/src/System/Runtime/InteropServices/ErrorWrapper.cs
index d63d69cabd..a9fa58f65f 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ErrorWrapper.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ErrorWrapper.cs
@@ -28,14 +28,10 @@ namespace System.Runtime.InteropServices {
public ErrorWrapper(Object errorCode)
{
if (!(errorCode is int))
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeInt32"), "errorCode");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeInt32"), nameof(errorCode));
m_ErrorCode = (int)errorCode;
}
- [System.Security.SecuritySafeCritical] // auto-generated
-#pragma warning disable 618
- [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)]
-#pragma warning restore 618
public ErrorWrapper(Exception e)
{
m_ErrorCode = Marshal.GetHRForException(e);
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ExtensibleClassFactory.cs b/src/mscorlib/src/System/Runtime/InteropServices/ExtensibleClassFactory.cs
index 62718de757..a12a38ec6d 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ExtensibleClassFactory.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ExtensibleClassFactory.cs
@@ -34,7 +34,6 @@ namespace System.Runtime.InteropServices {
// class for which the callbacks will be made.
// It is not legal to register this callback from a class that has any
// parents that have already registered a callback.
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void RegisterObjectCreationCallback(ObjectCreationDelegate callback);
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ExternalException.cs b/src/mscorlib/src/System/Runtime/InteropServices/ExternalException.cs
index 417cf94bd4..70a6dfe366 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ExternalException.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ExternalException.cs
@@ -52,7 +52,6 @@ namespace System.Runtime.InteropServices {
}
}
-#if !FEATURE_CORECLR // Breaks the subset-of-Orcas property
public override String ToString() {
String message = Message;
String s;
@@ -75,6 +74,5 @@ namespace System.Runtime.InteropServices {
return s;
}
-#endif // !FEATURE_CORECLR
}
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/GcHandle.cs b/src/mscorlib/src/System/Runtime/InteropServices/GcHandle.cs
index 58fea97cb8..5530819c5f 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/GcHandle.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/GcHandle.cs
@@ -47,7 +47,6 @@ namespace System.Runtime.InteropServices
private const GCHandleType MaxHandleType = GCHandleType.Pinned;
#if MDA_SUPPORTED
- [System.Security.SecuritySafeCritical] // auto-generated
static GCHandle()
{
s_probeIsActive = Mda.IsInvalidGCHandleCookieProbeEnabled();
@@ -57,12 +56,11 @@ namespace System.Runtime.InteropServices
#endif
// Allocate a handle storing the object and the type.
- [System.Security.SecurityCritical] // auto-generated
internal GCHandle(Object value, GCHandleType type)
{
// Make sure the type parameter is within the valid range for the enum.
if ((uint)type > (uint)MaxHandleType)
- throw new ArgumentOutOfRangeException("type", Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(type), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
Contract.EndContractBlock();
m_handle = InternalAlloc(value, type);
@@ -73,7 +71,6 @@ namespace System.Runtime.InteropServices
}
// Used in the conversion functions below.
- [System.Security.SecurityCritical] // auto-generated
internal GCHandle(IntPtr handle)
{
InternalCheckDomain(handle);
@@ -86,13 +83,11 @@ namespace System.Runtime.InteropServices
// type - The type of GC handle to create.
//
// returns a new GC handle that protects the object.
- [System.Security.SecurityCritical] // auto-generated_required
public static GCHandle Alloc(Object value)
{
return new GCHandle(value, GCHandleType.Normal);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static GCHandle Alloc(Object value, GCHandleType type)
{
return new GCHandle(value, type);
@@ -100,7 +95,6 @@ namespace System.Runtime.InteropServices
// Frees a GC handle.
- [System.Security.SecurityCritical] // auto-generated_required
public void Free()
{
// Copy the handle instance member to a local variable. This is required to prevent
@@ -134,7 +128,6 @@ namespace System.Runtime.InteropServices
// Target property - allows getting / updating of the handle's referent.
public Object Target
{
- [System.Security.SecurityCritical] // auto-generated_required
get
{
// Check if the handle was never initialized or was freed.
@@ -144,7 +137,6 @@ namespace System.Runtime.InteropServices
return InternalGet(GetHandleValue());
}
- [System.Security.SecurityCritical] // auto-generated_required
set
{
// Check if the handle was never initialized or was freed.
@@ -157,7 +149,6 @@ namespace System.Runtime.InteropServices
// Retrieve the address of an object in a Pinned handle. This throws
// an exception if the handle is any type other than Pinned.
- [System.Security.SecurityCritical] // auto-generated_required
public IntPtr AddrOfPinnedObject()
{
// Check if the handle was not a pinned handle.
@@ -186,13 +177,11 @@ namespace System.Runtime.InteropServices
// Used to create a GCHandle from an int. This is intended to
// be used with the reverse conversion.
- [System.Security.SecurityCritical] // auto-generated_required
public static explicit operator GCHandle(IntPtr value)
{
return FromIntPtr(value);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static GCHandle FromIntPtr(IntPtr value)
{
if (value == IntPtr.Zero)
@@ -293,28 +282,20 @@ namespace System.Runtime.InteropServices
}
// Internal native calls that this implementation uses.
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern IntPtr InternalAlloc(Object value, GCHandleType type);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void InternalFree(IntPtr handle);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern Object InternalGet(IntPtr handle);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void InternalSet(IntPtr handle, Object value, bool isPinned);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern Object InternalCompareExchange(IntPtr handle, Object value, Object oldValue, bool isPinned);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern IntPtr InternalAddrOfPinnedObject(IntPtr handle);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void InternalCheckDomain(IntPtr handle);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern GCHandleType InternalGetHandleType(IntPtr handle);
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ICustomQueryInterface.cs b/src/mscorlib/src/System/Runtime/InteropServices/ICustomQueryInterface.cs
index 61688b90b4..c7d7937895 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ICustomQueryInterface.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ICustomQueryInterface.cs
@@ -33,7 +33,6 @@ namespace System.Runtime.InteropServices {
[System.Runtime.InteropServices.ComVisible(false)]
public interface ICustomQueryInterface
{
- [System.Security.SecurityCritical]
CustomQueryInterfaceResult GetInterface([In]ref Guid iid, out IntPtr ppv);
}
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/IException.cs b/src/mscorlib/src/System/Runtime/InteropServices/IException.cs
index 2da0a564a2..2330365834 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/IException.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/IException.cs
@@ -22,48 +22,9 @@ namespace System.Runtime.InteropServices {
[GuidAttribute("b36b5c63-42ef-38bc-a07e-0b34c98f164a")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsDual)]
[CLSCompliant(false)]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface _Exception
{
-#if !FEATURE_CORECLR
- // This contains all of our V1 Exception class's members.
-
- // From Object
- String ToString();
- bool Equals (Object obj);
- int GetHashCode ();
- Type GetType ();
-
- // From V1's Exception class
- String Message {
- get;
- }
-
- Exception GetBaseException();
-
- String StackTrace {
- get;
- }
-
- String HelpLink {
- get;
- set;
- }
-
- String Source {
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
- get;
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
- set;
- }
- [System.Security.SecurityCritical] // auto-generated_required
- void GetObjectData(SerializationInfo info, StreamingContext context);
-#endif
-
//
// This method is intentionally included in CoreCLR to make Exception.get_InnerException "newslot virtual final".
// Some phone apps include MEF from desktop Silverlight. MEF's ComposablePartException depends on implicit interface
@@ -73,12 +34,5 @@ namespace System.Runtime.InteropServices {
Exception InnerException {
get;
}
-
-#if !FEATURE_CORECLR
- MethodBase TargetSite {
- get;
- }
-#endif
}
-
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/IRegistrationServices.cs b/src/mscorlib/src/System/Runtime/InteropServices/IRegistrationServices.cs
index ae330e8652..f2f7c61843 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/IRegistrationServices.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/IRegistrationServices.cs
@@ -31,24 +31,18 @@ namespace System.Runtime.InteropServices {
[System.Runtime.InteropServices.ComVisible(true)]
public interface IRegistrationServices
{
- [System.Security.SecurityCritical] // auto-generated_required
bool RegisterAssembly(Assembly assembly, AssemblyRegistrationFlags flags);
- [System.Security.SecurityCritical] // auto-generated_required
bool UnregisterAssembly(Assembly assembly);
- [System.Security.SecurityCritical] // auto-generated_required
Type[] GetRegistrableTypesInAssembly(Assembly assembly);
- [System.Security.SecurityCritical] // auto-generated_required
String GetProgIdForType(Type type);
- [System.Security.SecurityCritical] // auto-generated_required
void RegisterTypeForComClients(Type type, ref Guid g);
Guid GetManagedCategoryGuid();
- [System.Security.SecurityCritical] // auto-generated_required
bool TypeRequiresRegistration(Type type);
bool TypeRepresentsComType(Type type);
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/Marshal.cs b/src/mscorlib/src/System/Runtime/InteropServices/Marshal.cs
index 86e88306f0..3a79650bd9 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/Marshal.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/Marshal.cs
@@ -29,6 +29,7 @@ namespace System.Runtime.InteropServices
using System.Runtime.Versioning;
using Win32Native = Microsoft.Win32.Win32Native;
using Microsoft.Win32.SafeHandles;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices.ComTypes;
@@ -45,9 +46,6 @@ namespace System.Runtime.InteropServices
// declaration on the class.
//========================================================================
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
public static partial class Marshal
{
//====================================================================
@@ -117,7 +115,6 @@ namespace System.Runtime.InteropServices
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern int GetSystemMaxDBCSCharSize();
- [System.Security.SecurityCritical] // auto-generated_required
unsafe public static String PtrToStringAnsi(IntPtr ptr)
{
if (IntPtr.Zero == ptr) {
@@ -137,36 +134,32 @@ namespace System.Runtime.InteropServices
}
}
- [System.Security.SecurityCritical] // auto-generated_required
unsafe public static String PtrToStringAnsi(IntPtr ptr, int len)
{
if (ptr == IntPtr.Zero)
- throw new ArgumentNullException("ptr");
+ throw new ArgumentNullException(nameof(ptr));
if (len < 0)
- throw new ArgumentException("len");
+ throw new ArgumentException(null, nameof(len));
return new String((sbyte *)ptr, 0, len);
}
- [System.Security.SecurityCritical] // auto-generated_required
unsafe public static String PtrToStringUni(IntPtr ptr, int len)
{
if (ptr == IntPtr.Zero)
- throw new ArgumentNullException("ptr");
+ throw new ArgumentNullException(nameof(ptr));
if (len < 0)
- throw new ArgumentException("len");
+ throw new ArgumentException(null, nameof(len));
return new String((char *)ptr, 0, len);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static String PtrToStringAuto(IntPtr ptr, int len)
{
// Ansi platforms are no longer supported
return PtrToStringUni(ptr, len);
}
- [System.Security.SecurityCritical] // auto-generated_required
unsafe public static String PtrToStringUni(IntPtr ptr)
{
if (IntPtr.Zero == ptr) {
@@ -180,26 +173,23 @@ namespace System.Runtime.InteropServices
}
}
- [System.Security.SecurityCritical] // auto-generated_required
public static String PtrToStringAuto(IntPtr ptr)
{
// Ansi platforms are no longer supported
return PtrToStringUni(ptr);
}
- [System.Security.SecurityCritical] // auto-generated_required
unsafe public static String PtrToStringUTF8(IntPtr ptr)
{
int nbBytes = System.StubHelpers.StubHelpers.strlen((sbyte*)ptr.ToPointer());
return PtrToStringUTF8(ptr, nbBytes);
}
- [System.Security.SecurityCritical] // auto-generated_required
unsafe public static String PtrToStringUTF8(IntPtr ptr,int byteLen)
{
if (byteLen < 0)
{
- throw new ArgumentException("byteLen");
+ throw new ArgumentException(null, nameof(byteLen));
}
else if (IntPtr.Zero == ptr)
{
@@ -227,7 +217,7 @@ namespace System.Runtime.InteropServices
public static int SizeOf(Object structure)
{
if (structure == null)
- throw new ArgumentNullException("structure");
+ throw new ArgumentNullException(nameof(structure));
// we never had a check for generics here
Contract.EndContractBlock();
@@ -243,11 +233,11 @@ namespace System.Runtime.InteropServices
public static int SizeOf(Type t)
{
if (t == null)
- throw new ArgumentNullException("t");
+ throw new ArgumentNullException(nameof(t));
if (!(t is RuntimeType))
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "t");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), nameof(t));
if (t.IsGenericType)
- throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), "t");
+ throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), nameof(t));
Contract.EndContractBlock();
return SizeOfHelper(t, true);
@@ -290,9 +280,6 @@ namespace System.Runtime.InteropServices
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
private static extern uint AlignedSizeOfType(Type type);
-#if !FEATURE_CORECLR // Marshal is critical in CoreCLR, so SafeCritical members trigger Annotator violations
- [System.Security.SecuritySafeCritical]
-#endif // !FEATURE_CORECLR
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern int SizeOfHelper(Type t, bool throwIfNotMarshalable);
@@ -302,15 +289,15 @@ namespace System.Runtime.InteropServices
public static IntPtr OffsetOf(Type t, String fieldName)
{
if (t == null)
- throw new ArgumentNullException("t");
+ 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), "fieldName");
+ throw new ArgumentException(Environment.GetResourceString("Argument_OffsetOfFieldNotFound", t.FullName), nameof(fieldName));
RtFieldInfo rtField = f as RtFieldInfo;
if (rtField == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeFieldInfo"), "fieldName");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeFieldInfo"), nameof(fieldName));
return OffsetOfHelper(rtField);
}
@@ -330,11 +317,9 @@ namespace System.Runtime.InteropServices
// an array that is not pinned or in the fixed heap can cause
// unexpected results !
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern IntPtr UnsafeAddrOfPinnedArrayElement(Array arr, int index);
- [System.Security.SecurityCritical]
public static IntPtr UnsafeAddrOfPinnedArrayElement<T>(T[] arr, int index)
{
return UnsafeAddrOfPinnedArrayElement((Array)arr, index);
@@ -343,42 +328,34 @@ namespace System.Runtime.InteropServices
//====================================================================
// Copy blocks from CLR arrays to native memory.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static void Copy(int[] source, int startIndex, IntPtr destination, int length)
{
CopyToNative(source, startIndex, destination, length);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static void Copy(char[] source, int startIndex, IntPtr destination, int length)
{
CopyToNative(source, startIndex, destination, length);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static void Copy(short[] source, int startIndex, IntPtr destination, int length)
{
CopyToNative(source, startIndex, destination, length);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static void Copy(long[] source, int startIndex, IntPtr destination, int length)
{
CopyToNative(source, startIndex, destination, length);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static void Copy(float[] source, int startIndex, IntPtr destination, int length)
{
CopyToNative(source, startIndex, destination, length);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static void Copy(double[] source, int startIndex, IntPtr destination, int length)
{
CopyToNative(source, startIndex, destination, length);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static void Copy(byte[] source, int startIndex, IntPtr destination, int length)
{
CopyToNative(source, startIndex, destination, length);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static void Copy(IntPtr[] source, int startIndex, IntPtr destination, int length)
{
CopyToNative(source, startIndex, destination, length);
@@ -389,42 +366,34 @@ namespace System.Runtime.InteropServices
//====================================================================
// Copy blocks from native memory to CLR arrays
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static void Copy(IntPtr source, int[] destination, int startIndex, int length)
{
CopyToManaged(source, destination, startIndex, length);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static void Copy(IntPtr source, char[] destination, int startIndex, int length)
{
CopyToManaged(source, destination, startIndex, length);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static void Copy(IntPtr source, short[] destination, int startIndex, int length)
{
CopyToManaged(source, destination, startIndex, length);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static void Copy(IntPtr source, long[] destination, int startIndex, int length)
{
CopyToManaged(source, destination, startIndex, length);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static void Copy(IntPtr source, float[] destination, int startIndex, int length)
{
CopyToManaged(source, destination, startIndex, length);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static void Copy(IntPtr source, double[] destination, int startIndex, int length)
{
CopyToManaged(source, destination, startIndex, length);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static void Copy(IntPtr source, byte[] destination, int startIndex, int length)
{
CopyToManaged(source, destination, startIndex, length);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static void Copy(IntPtr source, IntPtr[] destination, int startIndex, int length)
{
CopyToManaged(source, destination, startIndex, length);
@@ -435,19 +404,11 @@ namespace System.Runtime.InteropServices
//====================================================================
// Read from memory
//====================================================================
- [System.Security.SecurityCritical] // auto-generated
-#if !FEATURE_CORECLR
- [DllImport(Win32Native.SHIM, EntryPoint="ND_RU1")]
- [SuppressUnmanagedCodeSecurity]
- public static extern byte ReadByte([MarshalAs(UnmanagedType.AsAny), In] Object ptr, int ofs);
-#else
public static byte ReadByte([MarshalAs(UnmanagedType.AsAny), In] Object ptr, int ofs)
{
throw new PlatformNotSupportedException();
- }
-#endif // !FEATURE_CORECLR
+ }
- [System.Security.SecurityCritical] // auto-generated_required
public static unsafe byte ReadByte(IntPtr ptr, int ofs)
{
try
@@ -462,25 +423,16 @@ namespace System.Runtime.InteropServices
}
}
- [System.Security.SecurityCritical] // auto-generated_required
public static byte ReadByte(IntPtr ptr)
{
return ReadByte(ptr,0);
}
-
- [System.Security.SecurityCritical] // auto-generated
-#if !FEATURE_CORECLR
- [DllImport(Win32Native.SHIM, EntryPoint="ND_RI2")]
- [SuppressUnmanagedCodeSecurity]
- public static extern short ReadInt16([MarshalAs(UnmanagedType.AsAny),In] Object ptr, int ofs);
-#else
+
public static short ReadInt16([MarshalAs(UnmanagedType.AsAny),In] Object ptr, int ofs)
{
throw new PlatformNotSupportedException();
- }
-#endif // !FEATURE_CORECLR
+ }
- [System.Security.SecurityCritical] // auto-generated_required
public static unsafe short ReadInt16(IntPtr ptr, int ofs)
{
try
@@ -508,25 +460,16 @@ namespace System.Runtime.InteropServices
}
}
- [System.Security.SecurityCritical] // auto-generated_required
public static short ReadInt16(IntPtr ptr)
{
return ReadInt16(ptr, 0);
}
-
- [System.Security.SecurityCritical] // auto-generated
-#if !FEATURE_CORECLR
- [DllImport(Win32Native.SHIM, EntryPoint="ND_RI4"), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- [SuppressUnmanagedCodeSecurity]
- public static extern int ReadInt32([MarshalAs(UnmanagedType.AsAny),In] Object ptr, int ofs);
-#else
+
public static int ReadInt32([MarshalAs(UnmanagedType.AsAny),In] Object ptr, int ofs)
{
throw new PlatformNotSupportedException();
}
-#endif // !FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated_required
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static unsafe int ReadInt32(IntPtr ptr, int ofs)
{
@@ -557,14 +500,12 @@ namespace System.Runtime.InteropServices
}
}
- [System.Security.SecurityCritical] // auto-generated_required
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static int ReadInt32(IntPtr ptr)
{
return ReadInt32(ptr,0);
}
- [System.Security.SecurityCritical] // auto-generated_required
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static IntPtr ReadIntPtr([MarshalAs(UnmanagedType.AsAny),In] Object ptr, int ofs)
{
@@ -575,7 +516,6 @@ namespace System.Runtime.InteropServices
#endif
}
- [System.Security.SecurityCritical] // auto-generated_required
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static IntPtr ReadIntPtr(IntPtr ptr, int ofs)
{
@@ -586,7 +526,6 @@ namespace System.Runtime.InteropServices
#endif
}
- [System.Security.SecurityCritical] // auto-generated_required
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static IntPtr ReadIntPtr(IntPtr ptr)
{
@@ -597,19 +536,11 @@ namespace System.Runtime.InteropServices
#endif
}
- [System.Security.SecurityCritical] // auto-generated
-#if !FEATURE_CORECLR
- [DllImport(Win32Native.SHIM, EntryPoint="ND_RI8"), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- [SuppressUnmanagedCodeSecurity]
- public static extern long ReadInt64([MarshalAs(UnmanagedType.AsAny),In] Object ptr, int ofs);
-#else
public static long ReadInt64([MarshalAs(UnmanagedType.AsAny),In] Object ptr, int ofs)
{
throw new PlatformNotSupportedException();
}
-#endif // !FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated_required
public static unsafe long ReadInt64(IntPtr ptr, int ofs)
{
try
@@ -643,7 +574,6 @@ namespace System.Runtime.InteropServices
}
}
- [System.Security.SecurityCritical] // auto-generated_required
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static long ReadInt64(IntPtr ptr)
{
@@ -654,7 +584,6 @@ namespace System.Runtime.InteropServices
//====================================================================
// Write to memory
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static unsafe void WriteByte(IntPtr ptr, int ofs, byte val)
{
try
@@ -669,25 +598,16 @@ namespace System.Runtime.InteropServices
}
}
- [System.Security.SecurityCritical] // auto-generated
-#if !FEATURE_CORECLR
- [DllImport(Win32Native.SHIM, EntryPoint="ND_WU1")]
- [SuppressUnmanagedCodeSecurity]
- public static extern void WriteByte([MarshalAs(UnmanagedType.AsAny),In,Out] Object ptr, int ofs, byte val);
-#else
public static void WriteByte([MarshalAs(UnmanagedType.AsAny),In,Out] Object ptr, int ofs, byte val)
{
throw new PlatformNotSupportedException();
}
-#endif // !FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated_required
public static void WriteByte(IntPtr ptr, byte val)
{
WriteByte(ptr, 0, val);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static unsafe void WriteInt16(IntPtr ptr, int ofs, short val)
{
try
@@ -712,44 +632,32 @@ namespace System.Runtime.InteropServices
throw new AccessViolationException();
}
}
-
- [System.Security.SecurityCritical] // auto-generated
-#if !FEATURE_CORECLR
- [DllImport(Win32Native.SHIM, EntryPoint="ND_WI2")]
- [SuppressUnmanagedCodeSecurity]
- public static extern void WriteInt16([MarshalAs(UnmanagedType.AsAny),In,Out] Object ptr, int ofs, short val);
-#else
+
public static void WriteInt16([MarshalAs(UnmanagedType.AsAny),In,Out] Object ptr, int ofs, short val)
{
throw new PlatformNotSupportedException();
}
-#endif // !FEATURE_CORECLR
-
- [System.Security.SecurityCritical] // auto-generated_required
+
public static void WriteInt16(IntPtr ptr, short val)
{
WriteInt16(ptr, 0, val);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static void WriteInt16(IntPtr ptr, int ofs, char val)
{
WriteInt16(ptr, ofs, (short)val);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static void WriteInt16([In,Out]Object ptr, int ofs, char val)
{
WriteInt16(ptr, ofs, (short)val);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static void WriteInt16(IntPtr ptr, char val)
{
WriteInt16(ptr, 0, (short)val);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static unsafe void WriteInt32(IntPtr ptr, int ofs, int val)
{
try
@@ -776,26 +684,17 @@ namespace System.Runtime.InteropServices
throw new AccessViolationException();
}
}
-
- [System.Security.SecurityCritical] // auto-generated
-#if !FEATURE_CORECLR
- [DllImport(Win32Native.SHIM, EntryPoint="ND_WI4")]
- [SuppressUnmanagedCodeSecurity]
- public static extern void WriteInt32([MarshalAs(UnmanagedType.AsAny),In,Out] Object ptr, int ofs, int val);
-#else
+
public static void WriteInt32([MarshalAs(UnmanagedType.AsAny),In,Out] Object ptr, int ofs, int val)
{
throw new PlatformNotSupportedException();
}
-#endif // !FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated_required
public static void WriteInt32(IntPtr ptr, int val)
{
WriteInt32(ptr,0,val);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static void WriteIntPtr(IntPtr ptr, int ofs, IntPtr val)
{
#if BIT64
@@ -805,7 +704,6 @@ namespace System.Runtime.InteropServices
#endif
}
- [System.Security.SecurityCritical] // auto-generated_required
public static void WriteIntPtr([MarshalAs(UnmanagedType.AsAny),In,Out] Object ptr, int ofs, IntPtr val)
{
#if BIT64
@@ -815,7 +713,6 @@ namespace System.Runtime.InteropServices
#endif
}
- [System.Security.SecurityCritical] // auto-generated_required
public static void WriteIntPtr(IntPtr ptr, IntPtr val)
{
#if BIT64
@@ -825,7 +722,6 @@ namespace System.Runtime.InteropServices
#endif
}
- [System.Security.SecurityCritical] // auto-generated_required
public static unsafe void WriteInt64(IntPtr ptr, int ofs, long val)
{
try
@@ -856,20 +752,12 @@ namespace System.Runtime.InteropServices
throw new AccessViolationException();
}
}
-
- [System.Security.SecurityCritical] // auto-generated
-#if !FEATURE_CORECLR
- [DllImport(Win32Native.SHIM, EntryPoint="ND_WI8")]
- [SuppressUnmanagedCodeSecurity]
- public static extern void WriteInt64([MarshalAs(UnmanagedType.AsAny),In,Out] Object ptr, int ofs, long val);
-#else
+
public static void WriteInt64([MarshalAs(UnmanagedType.AsAny),In,Out] Object ptr, int ofs, long val)
{
throw new PlatformNotSupportedException();
}
-#endif // !FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated_required
public static void WriteInt64(IntPtr ptr, long val)
{
WriteInt64(ptr, 0, val);
@@ -879,7 +767,6 @@ namespace System.Runtime.InteropServices
//====================================================================
// GetLastWin32Error
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static extern int GetLastWin32Error();
@@ -896,7 +783,6 @@ namespace System.Runtime.InteropServices
//====================================================================
// GetHRForLastWin32Error
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static int GetHRForLastWin32Error()
{
@@ -911,11 +797,10 @@ namespace System.Runtime.InteropServices
//====================================================================
// Prelink
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static void Prelink(MethodInfo m)
{
if (m == null)
- throw new ArgumentNullException("m");
+ throw new ArgumentNullException(nameof(m));
Contract.EndContractBlock();
RuntimeMethodInfo rmi = m as RuntimeMethodInfo;
@@ -927,14 +812,12 @@ namespace System.Runtime.InteropServices
}
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
- [SecurityCritical]
private static extern void InternalPrelink(IRuntimeMethodInfo m);
- [System.Security.SecurityCritical] // auto-generated_required
public static void PrelinkAll(Type c)
{
if (c == null)
- throw new ArgumentNullException("c");
+ throw new ArgumentNullException(nameof(c));
Contract.EndContractBlock();
MethodInfo[] mi = c.GetMethods();
@@ -950,11 +833,10 @@ namespace System.Runtime.InteropServices
//====================================================================
// NumParamBytes
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static int NumParamBytes(MethodInfo m)
{
if (m == null)
- throw new ArgumentNullException("m");
+ throw new ArgumentNullException(nameof(m));
Contract.EndContractBlock();
RuntimeMethodInfo rmi = m as RuntimeMethodInfo;
@@ -965,7 +847,6 @@ namespace System.Runtime.InteropServices
}
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
- [SecurityCritical]
private static extern int InternalNumParamBytes(IRuntimeMethodInfo m);
//====================================================================
@@ -973,12 +854,10 @@ namespace System.Runtime.InteropServices
// These are mostly interesting for Structured exception handling,
// but need to be exposed for all exceptions (not just SEHException).
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[System.Runtime.InteropServices.ComVisible(true)]
public static extern /* struct _EXCEPTION_POINTERS* */ IntPtr GetExceptionPointers();
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern int GetExceptionCode();
@@ -988,12 +867,10 @@ namespace System.Runtime.InteropServices
// If the structure contains pointers to allocated blocks and
// "fDeleteOld" is true, this routine will call DestroyStructure() first.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
[System.Runtime.InteropServices.ComVisible(true)]
public static extern void StructureToPtr(Object structure, IntPtr ptr, bool fDeleteOld);
- [System.Security.SecurityCritical]
public static void StructureToPtr<T>(T structure, IntPtr ptr, bool fDeleteOld)
{
StructureToPtr((object)structure, ptr, fDeleteOld);
@@ -1002,14 +879,12 @@ namespace System.Runtime.InteropServices
//====================================================================
// Marshals data from a native memory block to a preallocated structure class.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
[System.Runtime.InteropServices.ComVisible(true)]
public static void PtrToStructure(IntPtr ptr, Object structure)
{
PtrToStructureHelper(ptr, structure, false);
}
- [System.Security.SecurityCritical]
public static void PtrToStructure<T>(IntPtr ptr, T structure)
{
PtrToStructure(ptr, (object)structure);
@@ -1019,7 +894,6 @@ namespace System.Runtime.InteropServices
// Creates a new instance of "structuretype" and marshals data from a
// native memory block to it.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
[System.Runtime.InteropServices.ComVisible(true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static Object PtrToStructure(IntPtr ptr, Type structureType)
@@ -1027,15 +901,15 @@ namespace System.Runtime.InteropServices
if (ptr == IntPtr.Zero) return null;
if (structureType == null)
- throw new ArgumentNullException("structureType");
+ throw new ArgumentNullException(nameof(structureType));
if (structureType.IsGenericType)
- throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), "structureType");
+ throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), nameof(structureType));
RuntimeType rt = structureType.UnderlyingSystemType as RuntimeType;
if (rt == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "type");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(structureType));
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -1044,7 +918,6 @@ namespace System.Runtime.InteropServices
return structure;
}
- [System.Security.SecurityCritical]
public static T PtrToStructure<T>(IntPtr ptr)
{
return (T)PtrToStructure(ptr, typeof(T));
@@ -1061,27 +934,25 @@ namespace System.Runtime.InteropServices
// Freeds all substructures pointed to by the native memory block.
// "structureclass" is used to provide layout information.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[System.Runtime.InteropServices.ComVisible(true)]
public static extern void DestroyStructure(IntPtr ptr, Type structuretype);
- [System.Security.SecurityCritical]
public static void DestroyStructure<T>(IntPtr ptr)
{
DestroyStructure(ptr, typeof(T));
}
+#if FEATURE_COMINTEROP
//====================================================================
// Returns the HInstance for this module. Returns -1 if the module
// doesn't have an HInstance. In Memory (Dynamic) Modules won't have
// an HInstance.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static IntPtr GetHINSTANCE(Module m)
{
if (m == null)
- throw new ArgumentNullException("m");
+ throw new ArgumentNullException(nameof(m));
Contract.EndContractBlock();
RuntimeModule rtModule = m as RuntimeModule;
@@ -1093,26 +964,24 @@ namespace System.Runtime.InteropServices
}
if (rtModule == null)
- throw new ArgumentNullException("m",Environment.GetResourceString("Argument_MustBeRuntimeModule"));
+ throw new ArgumentNullException(nameof(m),Environment.GetResourceString("Argument_MustBeRuntimeModule"));
return GetHINSTANCE(rtModule.GetNativeHandle());
}
- [System.Security.SecurityCritical] // auto-generated_required
[SuppressUnmanagedCodeSecurity]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
private extern static IntPtr GetHINSTANCE(RuntimeModule m);
+#endif // FEATURE_COMINTEROP
//====================================================================
// Throws a CLR exception based on the HRESULT.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static void ThrowExceptionForHR(int errorCode)
{
if (errorCode < 0)
ThrowExceptionForHRInternal(errorCode, IntPtr.Zero);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static void ThrowExceptionForHR(int errorCode, IntPtr errorInfo)
{
if (errorCode < 0)
@@ -1126,7 +995,6 @@ namespace System.Runtime.InteropServices
//====================================================================
// Converts the HRESULT to a CLR exception.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static Exception GetExceptionForHR(int errorCode)
{
if (errorCode < 0)
@@ -1134,7 +1002,6 @@ namespace System.Runtime.InteropServices
else
return null;
}
- [System.Security.SecurityCritical] // auto-generated_required
public static Exception GetExceptionForHR(int errorCode, IntPtr errorInfo)
{
if (errorCode < 0)
@@ -1151,7 +1018,6 @@ namespace System.Runtime.InteropServices
// This method is intended for compiler code generators rather
// than applications.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
[ObsoleteAttribute("The GetUnmanagedThunkForManagedMethodPtr method has been deprecated and will be removed in a future release.", false)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern IntPtr GetUnmanagedThunkForManagedMethodPtr(IntPtr pfnMethodToWrap, IntPtr pbSignature, int cbSignature);
@@ -1160,7 +1026,6 @@ namespace System.Runtime.InteropServices
// This method is intended for compiler code generators rather
// than applications.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
[ObsoleteAttribute("The GetManagedThunkForUnmanagedMethodPtr method has been deprecated and will be removed in a future release.", false)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern IntPtr GetManagedThunkForUnmanagedMethodPtr(IntPtr pfnMethodToWrap, IntPtr pbSignature, int cbSignature);
@@ -1171,12 +1036,11 @@ namespace System.Runtime.InteropServices
// activity. A fiber cookie can be redeemed for its managed Thread
// object by calling the following service.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
[ObsoleteAttribute("The GetThreadFromFiberCookie method has been deprecated. Use the hosting API to perform this operation.", false)]
public static Thread GetThreadFromFiberCookie(int cookie)
{
if (cookie == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_ArgumentZero"), "cookie");
+ throw new ArgumentException(Environment.GetResourceString("Argument_ArgumentZero"), nameof(cookie));
Contract.EndContractBlock();
return InternalGetThreadFromFiberCookie(cookie);
@@ -1189,7 +1053,6 @@ namespace System.Runtime.InteropServices
//====================================================================
// Memory allocation and deallocation.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public static IntPtr AllocHGlobal(IntPtr cb)
{
@@ -1214,14 +1077,12 @@ namespace System.Runtime.InteropServices
return pNewMem;
}
- [System.Security.SecurityCritical] // auto-generated_required
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public static IntPtr AllocHGlobal(int cb)
{
return AllocHGlobal((IntPtr)cb);
}
- [System.Security.SecurityCritical] // auto-generated_required
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static void FreeHGlobal(IntPtr hglobal)
{
@@ -1232,7 +1093,6 @@ namespace System.Runtime.InteropServices
}
}
- [System.Security.SecurityCritical] // auto-generated_required
public static IntPtr ReAllocHGlobal(IntPtr pv, IntPtr cb)
{
IntPtr pNewMem = Win32Native.LocalReAlloc(pv, cb, LMEM_MOVEABLE);
@@ -1246,7 +1106,6 @@ namespace System.Runtime.InteropServices
//====================================================================
// String convertions.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
unsafe public static IntPtr StringToHGlobalAnsi(String s)
{
if (s == null)
@@ -1259,7 +1118,7 @@ namespace System.Runtime.InteropServices
// Overflow checking
if (nb < s.Length)
- throw new ArgumentOutOfRangeException("s");
+ throw new ArgumentOutOfRangeException(nameof(s));
UIntPtr len = new UIntPtr((uint)nb);
IntPtr hglobal = Win32Native.LocalAlloc_NoSafeHandle(LMEM_FIXED, len);
@@ -1276,7 +1135,6 @@ namespace System.Runtime.InteropServices
}
}
- [System.Security.SecurityCritical] // auto-generated_required
unsafe public static IntPtr StringToHGlobalUni(String s)
{
if (s == null)
@@ -1289,7 +1147,7 @@ namespace System.Runtime.InteropServices
// Overflow checking
if (nb < s.Length)
- throw new ArgumentOutOfRangeException("s");
+ throw new ArgumentOutOfRangeException(nameof(s));
UIntPtr len = new UIntPtr((uint)nb);
IntPtr hglobal = Win32Native.LocalAlloc_NoSafeHandle(LMEM_FIXED, len);
@@ -1309,7 +1167,6 @@ namespace System.Runtime.InteropServices
}
}
- [System.Security.SecurityCritical] // auto-generated_required
public static IntPtr StringToHGlobalAuto(String s)
{
// Ansi platforms are no longer supported
@@ -1322,7 +1179,6 @@ namespace System.Runtime.InteropServices
// Converts the CLR exception to an HRESULT. This function also sets
// up an IErrorInfo for the exception.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern int GetHRForException(Exception e);
@@ -1332,7 +1188,6 @@ namespace System.Runtime.InteropServices
// This function is only used in WinRT and converts ObjectDisposedException
// to RO_E_CLOSED
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern int GetHRForException_WinRT(Exception e);
@@ -1341,7 +1196,6 @@ namespace System.Runtime.InteropServices
//====================================================================
// Given a managed object that wraps a UCOMITypeLib, return its name
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
[Obsolete("Use System.Runtime.InteropServices.Marshal.GetTypeLibName(ITypeLib pTLB) instead. http://go.microsoft.com/fwlink/?linkid=14202&ID=0000011.", false)]
public static String GetTypeLibName(UCOMITypeLib pTLB)
{
@@ -1352,11 +1206,10 @@ namespace System.Runtime.InteropServices
//====================================================================
// Given a managed object that wraps an ITypeLib, return its name
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static String GetTypeLibName(ITypeLib typelib)
{
if (typelib == null)
- throw new ArgumentNullException("typelib");
+ throw new ArgumentNullException(nameof(typelib));
Contract.EndContractBlock();
String strTypeLibName = null;
@@ -1373,11 +1226,10 @@ namespace System.Runtime.InteropServices
// Internal version of GetTypeLibName
// Support GUID_ManagedName which aligns with TlbImp
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
internal static String GetTypeLibNameInternal(ITypeLib typelib)
{
if (typelib == null)
- throw new ArgumentNullException("typelib");
+ throw new ArgumentNullException(nameof(typelib));
Contract.EndContractBlock();
// Try GUID_ManagedName first
@@ -1415,7 +1267,6 @@ namespace System.Runtime.InteropServices
//====================================================================
// Given an managed object that wraps an UCOMITypeLib, return its guid
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
[Obsolete("Use System.Runtime.InteropServices.Marshal.GetTypeLibGuid(ITypeLib pTLB) instead. http://go.microsoft.com/fwlink/?linkid=14202&ID=0000011.", false)]
public static Guid GetTypeLibGuid(UCOMITypeLib pTLB)
{
@@ -1425,7 +1276,6 @@ namespace System.Runtime.InteropServices
//====================================================================
// Given an managed object that wraps an ITypeLib, return its guid
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static Guid GetTypeLibGuid(ITypeLib typelib)
{
Guid result = new Guid ();
@@ -1439,7 +1289,6 @@ namespace System.Runtime.InteropServices
//====================================================================
// Given a managed object that wraps a UCOMITypeLib, return its lcid
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
[Obsolete("Use System.Runtime.InteropServices.Marshal.GetTypeLibLcid(ITypeLib pTLB) instead. http://go.microsoft.com/fwlink/?linkid=14202&ID=0000011.", false)]
public static int GetTypeLibLcid(UCOMITypeLib pTLB)
{
@@ -1449,7 +1298,6 @@ namespace System.Runtime.InteropServices
//====================================================================
// Given a managed object that wraps an ITypeLib, return its lcid
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern int GetTypeLibLcid(ITypeLib typelib);
@@ -1463,7 +1311,6 @@ namespace System.Runtime.InteropServices
//====================================================================
// Given a managed object that wraps an ITypeInfo, return its guid.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated
internal static Guid GetTypeInfoGuid(ITypeInfo typeInfo)
{
Guid result = new Guid ();
@@ -1478,16 +1325,15 @@ namespace System.Runtime.InteropServices
// Given a assembly, return the TLBID that will be generated for the
// typelib exported from the assembly.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static Guid GetTypeLibGuidForAssembly(Assembly asm)
{
if (asm == null)
- throw new ArgumentNullException("asm");
+ throw new ArgumentNullException(nameof(asm));
Contract.EndContractBlock();
RuntimeAssembly rtAssembly = asm as RuntimeAssembly;
if (rtAssembly == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeAssembly"), "asm");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeAssembly"), nameof(asm));
Guid result = new Guid();
FCallGetTypeLibGuidForAssembly(ref result, rtAssembly);
@@ -1504,16 +1350,15 @@ namespace System.Runtime.InteropServices
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void _GetTypeLibVersionForAssembly(RuntimeAssembly inputAssembly, out int majorVersion, out int minorVersion);
- [System.Security.SecurityCritical] // auto-generated_required
public static void GetTypeLibVersionForAssembly(Assembly inputAssembly, out int majorVersion, out int minorVersion)
{
if (inputAssembly == null)
- throw new ArgumentNullException("inputAssembly");
+ throw new ArgumentNullException(nameof(inputAssembly));
Contract.EndContractBlock();
RuntimeAssembly rtAssembly = inputAssembly as RuntimeAssembly;
if (rtAssembly == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeAssembly"), "inputAssembly");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeAssembly"), nameof(inputAssembly));
_GetTypeLibVersionForAssembly(rtAssembly, out majorVersion, out minorVersion);
}
@@ -1521,7 +1366,6 @@ namespace System.Runtime.InteropServices
//====================================================================
// Given a managed object that wraps an UCOMITypeInfo, return its name
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
[Obsolete("Use System.Runtime.InteropServices.Marshal.GetTypeInfoName(ITypeInfo pTLB) instead. http://go.microsoft.com/fwlink/?linkid=14202&ID=0000011.", false)]
public static String GetTypeInfoName(UCOMITypeInfo pTI)
{
@@ -1531,11 +1375,10 @@ namespace System.Runtime.InteropServices
//====================================================================
// Given a managed object that wraps an ITypeInfo, return its name
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static String GetTypeInfoName(ITypeInfo typeInfo)
{
if (typeInfo == null)
- throw new ArgumentNullException("typeInfo");
+ throw new ArgumentNullException(nameof(typeInfo));
Contract.EndContractBlock();
String strTypeLibName = null;
@@ -1552,11 +1395,10 @@ namespace System.Runtime.InteropServices
// Internal version of GetTypeInfoName
// Support GUID_ManagedName which aligns with TlbImp
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
internal static String GetTypeInfoNameInternal(ITypeInfo typeInfo, out bool hasManagedName)
{
if (typeInfo == null)
- throw new ArgumentNullException("typeInfo");
+ throw new ArgumentNullException(nameof(typeInfo));
Contract.EndContractBlock();
// Try ManagedNameGuid first
@@ -1590,7 +1432,6 @@ namespace System.Runtime.InteropServices
// Get the corresponding managed name as converted by TlbImp
// Used to get the type using GetType() from imported assemblies
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
internal static String GetManagedTypeInfoNameInternal(ITypeLib typeLib, ITypeInfo typeInfo)
{
bool hasManagedName;
@@ -1609,95 +1450,8 @@ namespace System.Runtime.InteropServices
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern Type GetLoadedTypeForGUID(ref Guid guid);
-#if !FEATURE_CORECLR // current implementation requires reflection only load
- //====================================================================
- // map ITypeInfo* to Type
- //====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
- public static Type GetTypeForITypeInfo(IntPtr /* ITypeInfo* */ piTypeInfo)
- {
- ITypeInfo pTI = null;
- ITypeLib pTLB = null;
- Type TypeObj = null;
- Assembly AsmBldr = null;
- TypeLibConverter TlbConverter = null;
- int Index = 0;
- Guid clsid;
-
- // If the input ITypeInfo is NULL then return NULL.
- if (piTypeInfo == IntPtr.Zero)
- return null;
-
- // Wrap the ITypeInfo in a CLR object.
- pTI = (ITypeInfo)GetObjectForIUnknown(piTypeInfo);
-
- // Check to see if a class exists with the specified GUID.
-
- clsid = GetTypeInfoGuid(pTI);
- TypeObj = GetLoadedTypeForGUID(ref clsid);
-
- // If we managed to find the type based on the GUID then return it.
- if (TypeObj != null)
- return TypeObj;
-
- // There is no type with the specified GUID in the app domain so lets
- // try and convert the containing typelib.
- try
- {
- pTI.GetContainingTypeLib(out pTLB, out Index);
- }
- catch(COMException)
- {
- pTLB = null;
- }
-
- // Check to see if we managed to get a containing typelib.
- if (pTLB != null)
- {
- // Get the assembly name from the typelib.
- AssemblyName AsmName = TypeLibConverter.GetAssemblyNameFromTypelib(pTLB, null, null, null, null, AssemblyNameFlags.None);
- String AsmNameString = AsmName.FullName;
-
- // Check to see if the assembly that will contain the type already exists.
- Assembly[] aAssemblies = Thread.GetDomain().GetAssemblies();
- int NumAssemblies = aAssemblies.Length;
- for (int i = 0; i < NumAssemblies; i++)
- {
- if (String.Compare(aAssemblies[i].FullName,
- AsmNameString,StringComparison.Ordinal) == 0)
- AsmBldr = aAssemblies[i];
- }
-
- // If we haven't imported the assembly yet then import it.
- if (AsmBldr == null)
- {
- TlbConverter = new TypeLibConverter();
- AsmBldr = TlbConverter.ConvertTypeLibToAssembly(pTLB,
- GetTypeLibName(pTLB) + ".dll", 0, new ImporterCallback(), null, null, null, null);
- }
-
- // Load the type object from the imported typelib.
- // Call GetManagedTypeInfoNameInternal to align with TlbImp behavior
- TypeObj = AsmBldr.GetType(GetManagedTypeInfoNameInternal(pTLB, pTI), true, false);
- if (TypeObj != null && !TypeObj.IsVisible)
- TypeObj = null;
- }
- else
- {
- // If the ITypeInfo does not have a containing typelib then simply
- // return Object as the type.
- TypeObj = typeof(Object);
- }
-
- return TypeObj;
- }
-#endif // #if !FEATURE_CORECLR
-
// This method is identical to Type.GetTypeFromCLSID. Since it's interop specific, we expose it
// on Marshal for more consistent API surface.
-#if !FEATURE_CORECLR
- [System.Security.SecuritySafeCritical]
-#endif //!FEATURE_CORECLR
public static Type GetTypeFromCLSID(Guid clsid)
{
return RuntimeType.GetTypeFromCLSIDImpl(clsid, null, false);
@@ -1706,7 +1460,6 @@ namespace System.Runtime.InteropServices
//====================================================================
// map Type to ITypeInfo*
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern IntPtr /* ITypeInfo* */ GetITypeInfoForType(Type t);
@@ -1715,13 +1468,11 @@ namespace System.Runtime.InteropServices
// is the one where the RCW was first seen. Will return null
// otherwise.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static IntPtr /* IUnknown* */ GetIUnknownForObject(Object o)
{
return GetIUnknownForObjectNative(o, false);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static IntPtr /* IUnknown* */ GetIUnknownForObjectInContext(Object o)
{
return GetIUnknownForObjectNative(o, true);
@@ -1737,22 +1488,22 @@ namespace System.Runtime.InteropServices
//====================================================================
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern IntPtr /* IUnknown* */ GetRawIUnknownForComObjectNoAddRef(Object o);
+#endif // FEATURE_COMINTEROP
//====================================================================
// return the IDispatch* for an Object
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static IntPtr /* IDispatch */ GetIDispatchForObject(Object o)
{
- return GetIDispatchForObjectNative(o, false);
+ throw new PlatformNotSupportedException();
}
-
+
+#if FEATURE_COMINTEROP
//====================================================================
// return the IDispatch* for an Object if the current context
// is the one where the RCW was first seen. Will return null
// otherwise.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static IntPtr /* IUnknown* */ GetIDispatchForObjectInContext(Object o)
{
return GetIDispatchForObjectNative(o, true);
@@ -1765,13 +1516,11 @@ namespace System.Runtime.InteropServices
// return the IUnknown* representing the interface for the Object
// Object o should support Type T
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static IntPtr /* IUnknown* */ GetComInterfaceForObject(Object o, Type T)
{
return GetComInterfaceForObjectNative(o, T, false, true);
}
- [System.Security.SecurityCritical]
public static IntPtr GetComInterfaceForObject<T, TInterface>(T o)
{
return GetComInterfaceForObject(o, typeof(TInterface));
@@ -1782,7 +1531,6 @@ namespace System.Runtime.InteropServices
// Object o should support Type T, it refer the value of mode to
// invoke customized QueryInterface or not
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static IntPtr /* IUnknown* */ GetComInterfaceForObject(Object o, Type T, CustomQueryInterfaceMode mode)
{
bool bEnableCustomizedQueryInterface = ((mode == CustomQueryInterfaceMode.Allow) ? true : false);
@@ -1795,7 +1543,6 @@ namespace System.Runtime.InteropServices
// is the one where the RCW was first seen. Will return null
// otherwise.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static IntPtr /* IUnknown* */ GetComInterfaceForObjectInContext(Object o, Type t)
{
return GetComInterfaceForObjectNative(o, t, true, true);
@@ -1807,7 +1554,6 @@ namespace System.Runtime.InteropServices
//====================================================================
// return an Object for IUnknown
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern Object GetObjectForIUnknown(IntPtr /* IUnknown* */ pUnk);
@@ -1818,7 +1564,6 @@ namespace System.Runtime.InteropServices
// where you want to be able to call ReleaseComObject on a RCW
// and not worry about other active uses of said RCW.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern Object GetUniqueObjectForIUnknown(IntPtr unknown);
@@ -1828,40 +1573,31 @@ namespace System.Runtime.InteropServices
// Type T should be either a COM imported Type or a sub-type of COM
// imported Type
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern Object GetTypedObjectForIUnknown(IntPtr /* IUnknown* */ pUnk, Type t);
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern IntPtr CreateAggregatedObject(IntPtr pOuter, Object o);
- [System.Security.SecurityCritical]
public static IntPtr CreateAggregatedObject<T>(IntPtr pOuter, T o)
{
return CreateAggregatedObject(pOuter, (object)o);
}
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void CleanupUnusedObjectsInCurrentContext();
- [System.Security.SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern bool AreComObjectsAvailableForCleanup();
//====================================================================
// check if the object is classic COM component
//====================================================================
-#if !FEATURE_CORECLR // with FEATURE_CORECLR, the whole type is SecurityCritical
- [System.Security.SecuritySafeCritical]
-#endif
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern bool IsComObject(Object o);
#endif // FEATURE_COMINTEROP
- [System.Security.SecurityCritical] // auto-generated_required
public static IntPtr AllocCoTaskMem(int cb)
{
IntPtr pNewMem = Win32Native.CoTaskMemAlloc(new UIntPtr((uint)cb));
@@ -1872,7 +1608,6 @@ namespace System.Runtime.InteropServices
return pNewMem;
}
- [System.Security.SecurityCritical] // auto-generated_required
unsafe public static IntPtr StringToCoTaskMemUni(String s)
{
if (s == null)
@@ -1885,7 +1620,7 @@ namespace System.Runtime.InteropServices
// Overflow checking
if (nb < s.Length)
- throw new ArgumentOutOfRangeException("s");
+ throw new ArgumentOutOfRangeException(nameof(s));
IntPtr hglobal = Win32Native.CoTaskMemAlloc(new UIntPtr((uint)nb));
@@ -1904,7 +1639,6 @@ namespace System.Runtime.InteropServices
}
}
- [System.Security.SecurityCritical] // auto-generated_required
unsafe public static IntPtr StringToCoTaskMemUTF8(String s)
{
const int MAX_UTF8_CHAR_SIZE = 3;
@@ -1918,7 +1652,7 @@ namespace System.Runtime.InteropServices
// Overflow checking
if (nb < s.Length)
- throw new ArgumentOutOfRangeException("s");
+ throw new ArgumentOutOfRangeException(nameof(s));
IntPtr pMem = Win32Native.CoTaskMemAlloc(new UIntPtr((uint)nb +1));
@@ -1936,14 +1670,12 @@ namespace System.Runtime.InteropServices
}
}
- [System.Security.SecurityCritical] // auto-generated_required
public static IntPtr StringToCoTaskMemAuto(String s)
{
// Ansi platforms are no longer supported
return StringToCoTaskMemUni(s);
}
- [System.Security.SecurityCritical] // auto-generated_required
unsafe public static IntPtr StringToCoTaskMemAnsi(String s)
{
if (s == null)
@@ -1956,7 +1688,7 @@ namespace System.Runtime.InteropServices
// Overflow checking
if (nb < s.Length)
- throw new ArgumentOutOfRangeException("s");
+ throw new ArgumentOutOfRangeException(nameof(s));
IntPtr hglobal = Win32Native.CoTaskMemAlloc(new UIntPtr((uint)nb));
@@ -1972,7 +1704,6 @@ namespace System.Runtime.InteropServices
}
}
- [System.Security.SecurityCritical] // auto-generated_required
public static void FreeCoTaskMem(IntPtr ptr)
{
if (IsNotWin32Atom(ptr)) {
@@ -1980,7 +1711,6 @@ namespace System.Runtime.InteropServices
}
}
- [System.Security.SecurityCritical] // auto-generated_required
public static IntPtr ReAllocCoTaskMem(IntPtr pv, int cb)
{
IntPtr pNewMem = Win32Native.CoTaskMemRealloc(pv, new UIntPtr((uint)cb));
@@ -1994,7 +1724,6 @@ namespace System.Runtime.InteropServices
//====================================================================
// BSTR allocation and dealocation.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static void FreeBSTR(IntPtr ptr)
{
if (IsNotWin32Atom(ptr))
@@ -2003,7 +1732,6 @@ namespace System.Runtime.InteropServices
}
}
- [System.Security.SecurityCritical] // auto-generated_required
public static IntPtr StringToBSTR(String s)
{
if (s == null)
@@ -2011,7 +1739,7 @@ namespace System.Runtime.InteropServices
// Overflow checking
if (s.Length + 1 < s.Length)
- throw new ArgumentOutOfRangeException("s");
+ throw new ArgumentOutOfRangeException(nameof(s));
IntPtr bstr = Win32Native.SysAllocStringLen(s, s.Length);
if (bstr == IntPtr.Zero)
@@ -2020,7 +1748,6 @@ namespace System.Runtime.InteropServices
return bstr;
}
- [System.Security.SecurityCritical] // auto-generated_required
public static String PtrToStringBSTR(IntPtr ptr)
{
return PtrToStringUni(ptr, (int)Win32Native.SysStringLen(ptr));
@@ -2031,7 +1758,6 @@ namespace System.Runtime.InteropServices
// release the COM component and if the reference hits 0 zombie this object
// further usage of this Object might throw an exception
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static int ReleaseComObject(Object o)
{
__ComObject co = null;
@@ -2043,7 +1769,7 @@ namespace System.Runtime.InteropServices
}
catch (InvalidCastException)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_ObjNotComObject"), "o");
+ throw new ArgumentException(Environment.GetResourceString("Argument_ObjNotComObject"), nameof(o));
}
return co.ReleaseSelf();
@@ -2057,11 +1783,10 @@ namespace System.Runtime.InteropServices
// release the COM component and zombie this object
// further usage of this Object might throw an exception
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static Int32 FinalReleaseComObject(Object o)
{
if (o == null)
- throw new ArgumentNullException("o");
+ throw new ArgumentNullException(nameof(o));
Contract.EndContractBlock();
__ComObject co = null;
@@ -2073,7 +1798,7 @@ namespace System.Runtime.InteropServices
}
catch (InvalidCastException)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_ObjNotComObject"), "o");
+ throw new ArgumentException(Environment.GetResourceString("Argument_ObjNotComObject"), nameof(o));
}
co.FinalReleaseSelf();
@@ -2083,39 +1808,14 @@ namespace System.Runtime.InteropServices
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void InternalFinalReleaseComObject(Object o);
+#endif // FEATURE_COMINTEROP
//====================================================================
// This method retrieves data from the COM object.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static Object GetComObjectData(Object obj, Object key)
{
- // Validate that the arguments aren't null.
- if (obj == null)
- throw new ArgumentNullException("obj");
- if (key == null)
- throw new ArgumentNullException("key");
- Contract.EndContractBlock();
-
- __ComObject comObj = null;
-
- // Make sure the obj is an __ComObject.
- try
- {
- comObj = (__ComObject)obj;
- }
- catch (InvalidCastException)
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_ObjNotComObject"), "obj");
- }
-
- if (obj.GetType().IsWindowsRuntimeObject)
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_ObjIsWinRTObject"), "obj");
- }
-
- // Retrieve the data from the __ComObject.
- return comObj.GetData(key);
+ throw new PlatformNotSupportedException();
}
//====================================================================
@@ -2124,55 +1824,29 @@ namespace System.Runtime.InteropServices
// true if the data has been added, false if the data could not be
// added because there already was data for the specified key.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static bool SetComObjectData(Object obj, Object key, Object data)
{
- // Validate that the arguments aren't null. The data can validly be null.
- if (obj == null)
- throw new ArgumentNullException("obj");
- if (key == null)
- throw new ArgumentNullException("key");
- Contract.EndContractBlock();
-
- __ComObject comObj = null;
-
- // Make sure the obj is an __ComObject.
- try
- {
- comObj = (__ComObject)obj;
- }
- catch (InvalidCastException)
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_ObjNotComObject"), "obj");
- }
-
- if (obj.GetType().IsWindowsRuntimeObject)
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_ObjIsWinRTObject"), "obj");
- }
-
- // Retrieve the data from the __ComObject.
- return comObj.SetData(key, data);
+ throw new PlatformNotSupportedException();
}
+#if FEATURE_COMINTEROP
//====================================================================
// This method takes the given COM object and wraps it in an object
// of the specified type. The type must be derived from __ComObject.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static Object CreateWrapperOfType(Object o, Type t)
{
// Validate the arguments.
if (t == null)
- throw new ArgumentNullException("t");
+ throw new ArgumentNullException(nameof(t));
if (!t.IsCOMObject)
- throw new ArgumentException(Environment.GetResourceString("Argument_TypeNotComObject"), "t");
+ throw new ArgumentException(Environment.GetResourceString("Argument_TypeNotComObject"), nameof(t));
if (t.IsGenericType)
- throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), "t");
+ throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), nameof(t));
Contract.EndContractBlock();
if (t.IsWindowsRuntimeObject)
- throw new ArgumentException(Environment.GetResourceString("Argument_TypeIsWinRTType"), "t");
+ throw new ArgumentException(Environment.GetResourceString("Argument_TypeIsWinRTType"), nameof(t));
// Check for the null case.
if (o == null)
@@ -2180,9 +1854,9 @@ namespace System.Runtime.InteropServices
// Make sure the object is a COM object.
if (!o.GetType().IsCOMObject)
- throw new ArgumentException(Environment.GetResourceString("Argument_ObjNotComObject"), "o");
+ throw new ArgumentException(Environment.GetResourceString("Argument_ObjNotComObject"), nameof(o));
if (o.GetType().IsWindowsRuntimeObject)
- throw new ArgumentException(Environment.GetResourceString("Argument_ObjIsWinRTObject"), "o");
+ throw new ArgumentException(Environment.GetResourceString("Argument_ObjIsWinRTObject"), nameof(o));
// Check to see if the type of the object is the requested type.
if (o.GetType() == t)
@@ -2206,7 +1880,6 @@ namespace System.Runtime.InteropServices
return Wrapper;
}
- [System.Security.SecurityCritical]
public static TWrapper CreateWrapperOfType<T, TWrapper>(T o)
{
return (TWrapper)CreateWrapperOfType(o, typeof(TWrapper));
@@ -2215,7 +1888,6 @@ namespace System.Runtime.InteropServices
//====================================================================
// Helper method called from CreateWrapperOfType.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern Object InternalCreateWrapperOfType(Object o, Type t);
@@ -2223,7 +1895,6 @@ namespace System.Runtime.InteropServices
// There may be a thread-based cache of COM components. This service can
// force the aggressive release of the current thread's cache.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
[Obsolete("This API did not perform any operation and will be removed in future versions of the CLR.", false)]
public static void ReleaseThreadCache()
{
@@ -2232,50 +1903,40 @@ namespace System.Runtime.InteropServices
//====================================================================
// check if the type is visible from COM.
//====================================================================
- [System.Security.SecuritySafeCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern bool IsTypeVisibleFromCom(Type t);
//====================================================================
// IUnknown Helpers
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern int /* HRESULT */ QueryInterface(IntPtr /* IUnknown */ pUnk, ref Guid iid, out IntPtr ppv);
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern int /* ULONG */ AddRef(IntPtr /* IUnknown */ pUnk );
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static extern int /* ULONG */ Release(IntPtr /* IUnknown */ pUnk );
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void GetNativeVariantForObject(Object obj, /* VARIANT * */ IntPtr pDstNativeVariant);
- [System.Security.SecurityCritical]
public static void GetNativeVariantForObject<T>(T obj, IntPtr pDstNativeVariant)
{
GetNativeVariantForObject((object)obj, pDstNativeVariant);
}
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern Object GetObjectForNativeVariant(/* VARIANT * */ IntPtr pSrcNativeVariant );
- [System.Security.SecurityCritical]
public static T GetObjectForNativeVariant<T>(IntPtr pSrcNativeVariant)
{
return (T)GetObjectForNativeVariant(pSrcNativeVariant);
}
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern Object[] GetObjectsForNativeVariants(/* VARIANT * */ IntPtr aSrcNativeVariant, int cVars );
- [System.Security.SecurityCritical]
public static T[] GetObjectsForNativeVariants<T>(IntPtr aSrcNativeVariant, int cVars)
{
object[] objects = GetObjectsForNativeVariants(aSrcNativeVariant, cVars);
@@ -2294,14 +1955,12 @@ namespace System.Runtime.InteropServices
/// <para>Returns the first valid COM slot that GetMethodInfoForSlot will work on
/// This will be 3 for IUnknown based interfaces and 7 for IDispatch based interfaces. </para>
/// </summary>
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern int GetStartComSlot(Type t);
/// <summary>
/// <para>Returns the last valid COM slot that GetMethodInfoForSlot will work on. </para>
/// </summary>
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern int GetEndComSlot(Type t);
@@ -2312,7 +1971,6 @@ namespace System.Runtime.InteropServices
/// For classes, the lookup is done on the default interface that will be
/// exposed for the class. </para>
/// </summary>
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern MemberInfo GetMethodInfoForComSlot(Type t, int slot, ref ComMemberType memberType);
@@ -2320,19 +1978,18 @@ namespace System.Runtime.InteropServices
/// <para>Returns the COM slot for a memeber info, taking into account whether
/// the exposed interface is IUnknown based or IDispatch based</para>
/// </summary>
- [System.Security.SecurityCritical] // auto-generated_required
public static int GetComSlotForMethodInfo(MemberInfo m)
{
if (m== null)
- throw new ArgumentNullException("m");
+ throw new ArgumentNullException(nameof(m));
if (!(m is RuntimeMethodInfo))
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), "m");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), nameof(m));
if (!m.DeclaringType.IsInterface)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeInterfaceMethod"), "m");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeInterfaceMethod"), nameof(m));
if (m.DeclaringType.IsGenericType)
- throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), "m");
+ throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), nameof(m));
Contract.EndContractBlock();
return InternalGetComSlotForMethodInfo((IRuntimeMethodInfo)m);
@@ -2340,6 +1997,7 @@ namespace System.Runtime.InteropServices
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern int InternalGetComSlotForMethodInfo(IRuntimeMethodInfo m);
+#endif // FEATURE_COMINTEROP
//====================================================================
// This method generates a GUID for the specified type. If the type
@@ -2347,38 +2005,27 @@ namespace System.Runtime.InteropServices
// guid GUID is generated based on the fully qualified name of the
// type.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static Guid GenerateGuidForType(Type type)
{
- Guid result = new Guid ();
- FCallGenerateGuidForType (ref result, type);
- return result;
+ return type.GUID;
}
- // The full assembly name is used to compute the GUID, so this should be SxS-safe
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern void FCallGenerateGuidForType(ref Guid result, Type type);
-
//====================================================================
// This method generates a PROGID for the specified type. If the type
// has a PROGID in the metadata then it is returned otherwise a stable
// PROGID is generated based on the fully qualified name of the
// type.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static String GenerateProgIdForType(Type type)
{
if (type == null)
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
if (type.IsImport)
- throw new ArgumentException(Environment.GetResourceString("Argument_TypeMustNotBeComImport"), "type");
+ throw new ArgumentException(Environment.GetResourceString("Argument_TypeMustNotBeComImport"), nameof(type));
if (type.IsGenericType)
- throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), "type");
+ throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), nameof(type));
Contract.EndContractBlock();
- if (!RegistrationServices.TypeRequiresRegistrationHelper(type))
- throw new ArgumentException(Environment.GetResourceString("Argument_TypeMustBeComCreatable"), "type");
-
IList<CustomAttributeData> cas = CustomAttributeData.GetCustomAttributes(type);
for (int i = 0; i < cas.Count; i ++)
{
@@ -2386,10 +2033,10 @@ namespace System.Runtime.InteropServices
{
// Retrieve the PROGID string from the ProgIdAttribute.
IList<CustomAttributeTypedArgument> caConstructorArgs = cas[i].ConstructorArguments;
- Contract.Assert(caConstructorArgs.Count == 1, "caConstructorArgs.Count == 1");
+ Debug.Assert(caConstructorArgs.Count == 1, "caConstructorArgs.Count == 1");
CustomAttributeTypedArgument progIdConstructorArg = caConstructorArgs[0];
- Contract.Assert(progIdConstructorArg.ArgumentType == typeof(String), "progIdConstructorArg.ArgumentType == typeof(String)");
+ Debug.Assert(progIdConstructorArg.ArgumentType == typeof(String), "progIdConstructorArg.ArgumentType == typeof(String)");
String strProgId = (String)progIdConstructorArg.Value;
@@ -2404,10 +2051,10 @@ namespace System.Runtime.InteropServices
return type.FullName;
}
+#if FEATURE_COMINTEROP
//====================================================================
// This method binds to the specified moniker.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static Object BindToMoniker(String monikerName)
{
Object obj = null;
@@ -2425,7 +2072,6 @@ namespace System.Runtime.InteropServices
//====================================================================
// This method gets the currently running object.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated_required
public static Object GetActiveObject(String progID)
{
Object obj = null;
@@ -2449,32 +2095,26 @@ namespace System.Runtime.InteropServices
[DllImport(Microsoft.Win32.Win32Native.OLE32, PreserveSig = false)]
[SuppressUnmanagedCodeSecurity]
- [System.Security.SecurityCritical] // auto-generated
private static extern void CLSIDFromProgIDEx([MarshalAs(UnmanagedType.LPWStr)] String progId, out Guid clsid);
[DllImport(Microsoft.Win32.Win32Native.OLE32, PreserveSig = false)]
[SuppressUnmanagedCodeSecurity]
- [System.Security.SecurityCritical] // auto-generated
private static extern void CLSIDFromProgID([MarshalAs(UnmanagedType.LPWStr)] String progId, out Guid clsid);
[DllImport(Microsoft.Win32.Win32Native.OLE32, PreserveSig = false)]
[SuppressUnmanagedCodeSecurity]
- [System.Security.SecurityCritical] // auto-generated
private static extern void CreateBindCtx(UInt32 reserved, out IBindCtx ppbc);
[DllImport(Microsoft.Win32.Win32Native.OLE32, PreserveSig = false)]
[SuppressUnmanagedCodeSecurity]
- [System.Security.SecurityCritical] // auto-generated
private static extern void MkParseDisplayName(IBindCtx pbc, [MarshalAs(UnmanagedType.LPWStr)] String szUserName, out UInt32 pchEaten, out IMoniker ppmk);
[DllImport(Microsoft.Win32.Win32Native.OLE32, PreserveSig = false)]
[SuppressUnmanagedCodeSecurity]
- [System.Security.SecurityCritical] // auto-generated
private static extern void BindMoniker(IMoniker pmk, UInt32 grfOpt, ref Guid iidResult, [MarshalAs(UnmanagedType.Interface)] out Object ppvResult);
[DllImport(Microsoft.Win32.Win32Native.OLEAUT32, PreserveSig = false)]
[SuppressUnmanagedCodeSecurity]
- [System.Security.SecurityCritical] // auto-generated
private static extern void GetActiveObject(ref Guid rclsid, IntPtr reserved, [MarshalAs(UnmanagedType.Interface)] out Object ppunk);
//========================================================================
@@ -2489,7 +2129,6 @@ namespace System.Runtime.InteropServices
//========================================================================
// Private method called from EE upon use of license/ICF2 marshaling.
//========================================================================
- [SecurityCritical]
private static IntPtr LoadLicenseManager()
{
Assembly sys = Assembly.Load("System, Version="+ ThisAssembly.Version +
@@ -2500,16 +2139,13 @@ namespace System.Runtime.InteropServices
return t.TypeHandle.Value;
}
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void ChangeWrapperHandleStrength(Object otp, bool fIsWeak);
- [System.Security.SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void InitializeWrapperForWinRT(object o, ref IntPtr pUnk);
#if FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION
- [System.Security.SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void InitializeManagedWinRTFactoryObject(object o, RuntimeType runtimeClassType);
#endif
@@ -2517,7 +2153,6 @@ namespace System.Runtime.InteropServices
//========================================================================
// Create activation factory and wraps it with a unique RCW
//========================================================================
- [System.Security.SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern object GetNativeActivationFactory(Type type);
@@ -2525,11 +2160,9 @@ namespace System.Runtime.InteropServices
// Methods allowing retrieval of the IIDs exposed by an underlying WinRT
// object, as specified by the object's IInspectable::GetIids()
//========================================================================
- [System.Security.SecurityCritical]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
private static extern void _GetInspectableIids(ObjectHandleOnStack obj, ObjectHandleOnStack guids);
- [System.Security.SecurityCritical]
internal static System.Guid[] GetInspectableIids(object obj)
{
System.Guid[] result = null;
@@ -2547,14 +2180,12 @@ namespace System.Runtime.InteropServices
// Methods allowing retrieval of the cached WinRT type corresponding to
// the specified GUID
//========================================================================
- [System.Security.SecurityCritical]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
private static extern void _GetCachedWinRTTypeByIid(
ObjectHandleOnStack appDomainObj,
System.Guid iid,
out IntPtr rthHandle);
- [System.Security.SecurityCritical]
internal static System.Type GetCachedWinRTTypeByIid(
System.AppDomain ad,
System.Guid iid)
@@ -2572,14 +2203,12 @@ namespace System.Runtime.InteropServices
// Methods allowing retrieval of the WinRT types cached in the specified
// app domain
//========================================================================
- [System.Security.SecurityCritical]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
private static extern void _GetCachedWinRTTypes(
ObjectHandleOnStack appDomainObj,
ref int epoch,
ObjectHandleOnStack winrtTypes);
- [System.Security.SecurityCritical]
internal static System.Type[] GetCachedWinRTTypes(
System.AppDomain ad,
ref int epoch)
@@ -2599,7 +2228,6 @@ namespace System.Runtime.InteropServices
return result;
}
- [System.Security.SecurityCritical]
internal static System.Type[] GetCachedWinRTTypes(
System.AppDomain ad)
{
@@ -2610,31 +2238,29 @@ namespace System.Runtime.InteropServices
#endif // FEATURE_COMINTEROP
- [System.Security.SecurityCritical] // auto-generated_required
public static Delegate GetDelegateForFunctionPointer(IntPtr ptr, Type t)
{
// Validate the parameters
if (ptr == IntPtr.Zero)
- throw new ArgumentNullException("ptr");
+ throw new ArgumentNullException(nameof(ptr));
if (t == null)
- throw new ArgumentNullException("t");
+ throw new ArgumentNullException(nameof(t));
Contract.EndContractBlock();
if ((t as RuntimeType) == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "t");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), nameof(t));
if (t.IsGenericType)
- throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), "t");
+ throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), nameof(t));
Type c = t.BaseType;
if (c == null || (c != typeof(Delegate) && c != typeof(MulticastDelegate)))
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"), "t");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"), nameof(t));
return GetDelegateForFunctionPointerInternal(ptr, t);
}
- [System.Security.SecurityCritical]
public static TDelegate GetDelegateForFunctionPointer<TDelegate>(IntPtr ptr)
{
return (TDelegate)(object)GetDelegateForFunctionPointer(ptr, typeof(TDelegate));
@@ -2643,17 +2269,15 @@ namespace System.Runtime.InteropServices
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern Delegate GetDelegateForFunctionPointerInternal(IntPtr ptr, Type t);
- [System.Security.SecurityCritical] // auto-generated_required
public static IntPtr GetFunctionPointerForDelegate(Delegate d)
{
if (d == null)
- throw new ArgumentNullException("d");
+ throw new ArgumentNullException(nameof(d));
Contract.EndContractBlock();
return GetFunctionPointerForDelegateInternal(d);
}
- [System.Security.SecurityCritical]
public static IntPtr GetFunctionPointerForDelegate<TDelegate>(TDelegate d)
{
return GetFunctionPointerForDelegate((Delegate)(object)d);
@@ -2662,47 +2286,39 @@ namespace System.Runtime.InteropServices
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern IntPtr GetFunctionPointerForDelegateInternal(Delegate d);
-#if FEATURE_LEGACYSURFACE
-
-#if FEATURE_COMINTEROP
- [System.Security.SecurityCritical] // auto-generated_required
public static IntPtr SecureStringToBSTR(SecureString s) {
if( s == null) {
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
}
Contract.EndContractBlock();
- return s.ToBSTR();
- }
+#if FEATURE_COMINTEROP
+ return s.MarshalToBSTR();
+#else
+ throw new PlatformNotSupportedException();
#endif
+ }
- [System.Security.SecurityCritical] // auto-generated_required
public static IntPtr SecureStringToCoTaskMemAnsi(SecureString s) {
if( s == null) {
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
}
Contract.EndContractBlock();
- return s.ToAnsiStr(false);
+ return s.MarshalToString(globalAlloc: false, unicode: false);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static IntPtr SecureStringToCoTaskMemUnicode(SecureString s)
{
- if (s == null)
- {
- throw new ArgumentNullException("s");
+ if( s == null) {
+ throw new ArgumentNullException(nameof(s));
}
Contract.EndContractBlock();
- return s.ToUniStr(false);
+ return s.MarshalToString(globalAlloc: false, unicode: true);
}
-#endif // FEATURE_LEGACYSURFACE
-
-
#if FEATURE_COMINTEROP
- [System.Security.SecurityCritical] // auto-generated_required
public static void ZeroFreeBSTR(IntPtr s)
{
Win32Native.ZeroMemory(s, (UIntPtr)(Win32Native.SysStringLen(s) * 2));
@@ -2710,97 +2326,51 @@ namespace System.Runtime.InteropServices
}
#endif
- [System.Security.SecurityCritical] // auto-generated_required
public static void ZeroFreeCoTaskMemAnsi(IntPtr s)
{
Win32Native.ZeroMemory(s, (UIntPtr)(Win32Native.lstrlenA(s)));
FreeCoTaskMem(s);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static void ZeroFreeCoTaskMemUnicode(IntPtr s)
{
Win32Native.ZeroMemory(s, (UIntPtr)(Win32Native.lstrlenW(s) * 2));
FreeCoTaskMem(s);
}
- [System.Security.SecurityCritical] // auto-generated_required
unsafe public static void ZeroFreeCoTaskMemUTF8(IntPtr s)
{
Win32Native.ZeroMemory(s, (UIntPtr)System.StubHelpers.StubHelpers.strlen((sbyte*)s));
FreeCoTaskMem(s);
}
-#if FEATURE_LEGACYSURFACE
- [System.Security.SecurityCritical] // auto-generated_required
public static IntPtr SecureStringToGlobalAllocAnsi(SecureString s) {
if( s == null) {
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
}
Contract.EndContractBlock();
- return s.ToAnsiStr(true);
+ return s.MarshalToString(globalAlloc: true, unicode: false);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static IntPtr SecureStringToGlobalAllocUnicode(SecureString s) {
if( s == null) {
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
}
Contract.EndContractBlock();
- return s.ToUniStr(true);
+ return s.MarshalToString(globalAlloc: true, unicode: true);;
}
-#endif // FEATURE_LEGACYSURFACE
- [System.Security.SecurityCritical] // auto-generated_required
public static void ZeroFreeGlobalAllocAnsi(IntPtr s) {
Win32Native.ZeroMemory(s, (UIntPtr)(Win32Native.lstrlenA(s)));
FreeHGlobal(s);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static void ZeroFreeGlobalAllocUnicode(IntPtr s) {
Win32Native.ZeroMemory(s, (UIntPtr)(Win32Native.lstrlenW(s) * 2));
FreeHGlobal(s);
}
}
-
-#if FEATURE_COMINTEROP && !FEATURE_CORECLR // current implementation requires reflection only load
- //========================================================================
- // Typelib importer callback implementation.
- //========================================================================
- internal class ImporterCallback : ITypeLibImporterNotifySink
- {
- public void ReportEvent(ImporterEventKind EventKind, int EventCode, String EventMsg)
- {
- }
-
- [System.Security.SecuritySafeCritical] // overrides transparent public member
- public Assembly ResolveRef(Object TypeLib)
- {
- try
- {
- // Create the TypeLibConverter.
- ITypeLibConverter TLBConv = new TypeLibConverter();
-
- // Convert the typelib.
- return TLBConv.ConvertTypeLibToAssembly(TypeLib,
- Marshal.GetTypeLibName((ITypeLib)TypeLib) + ".dll",
- 0,
- new ImporterCallback(),
- null,
- null,
- null,
- null);
- }
- catch(Exception)
-// catch
- {
- return null;
- }
- }
- }
-#endif // FEATURE_COMINTEROP && !FEATURE_CORECLR
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/NativeBuffer.cs b/src/mscorlib/src/System/Runtime/InteropServices/NativeBuffer.cs
deleted file mode 100644
index 94261621c3..0000000000
--- a/src/mscorlib/src/System/Runtime/InteropServices/NativeBuffer.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.
-
-using System.Runtime.CompilerServices;
-
-namespace System.Runtime.InteropServices
-{
- /// <summary>
- /// Wrapper for access to the native heap. Dispose to free the memory. Try to use with using statements.
- /// Does not allocate zero size buffers, and will free the existing native buffer if capacity is dropped to zero.
- /// </summary>
- /// <remarks>
- /// Suggested use through P/Invoke: define DllImport arguments that take a byte buffer as SafeHandle.
- ///
- /// Using SafeHandle will ensure that the buffer will not get collected during a P/Invoke.
- /// (Notably AddRef and ReleaseRef will be called by the interop layer.)
- ///
- /// This class is not threadsafe, changing the capacity or disposing on multiple threads risks duplicate heap
- /// handles or worse.
- /// </remarks>
- internal class NativeBuffer : IDisposable
- {
- [System.Security.SecurityCritical]
- private readonly static SafeHandle s_emptyHandle;
- [System.Security.SecurityCritical]
- private SafeHeapHandle _handle;
- private ulong _capacity;
-
- [System.Security.SecuritySafeCritical]
- static NativeBuffer()
- {
- s_emptyHandle = new EmptySafeHandle();
- }
-
- /// <summary>
- /// Create a buffer with at least the specified initial capacity in bytes.
- /// </summary>
- public NativeBuffer(ulong initialMinCapacity = 0)
- {
- EnsureByteCapacity(initialMinCapacity);
- }
-
- protected unsafe void* VoidPointer
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- [System.Security.SecurityCritical]
- get
- {
- return _handle == null ? null : _handle.DangerousGetHandle().ToPointer();
- }
- }
-
- protected unsafe byte* BytePointer
- {
- [System.Security.SecurityCritical]
- get
- {
- return (byte*)VoidPointer;
- }
- }
-
- /// <summary>
- /// Get the handle for the buffer.
- /// </summary>
- [System.Security.SecuritySafeCritical]
- public SafeHandle GetHandle()
- {
- // Marshalling code will throw on null for SafeHandle
- return _handle ?? s_emptyHandle;
- }
-
- /// <summary>
- /// The capacity of the buffer in bytes.
- /// </summary>
- public ulong ByteCapacity
- {
- get { return _capacity; }
- }
-
- /// <summary>
- /// Ensure capacity in bytes is at least the given minimum.
- /// </summary>
- /// <exception cref="OutOfMemoryException">Thrown if unable to allocate memory when setting.</exception>
- /// <exception cref="ArgumentOutOfRangeException">Thrown if attempting to set <paramref name="nameof(minCapacity)"/> to a value that is larger than the maximum addressable memory.</exception>
- [System.Security.SecuritySafeCritical]
- public void EnsureByteCapacity(ulong minCapacity)
- {
- if (_capacity < minCapacity)
- {
- Resize(minCapacity);
- _capacity = minCapacity;
- }
- }
-
- public unsafe byte this[ulong index]
- {
- [System.Security.SecuritySafeCritical]
- get
- {
- if (index >= _capacity) throw new ArgumentOutOfRangeException();
- return BytePointer[index];
- }
- [System.Security.SecuritySafeCritical]
- set
- {
- if (index >= _capacity) throw new ArgumentOutOfRangeException();
- BytePointer[index] = value;
- }
- }
-
- [System.Security.SecuritySafeCritical]
- private unsafe void Resize(ulong byteLength)
- {
- if (byteLength == 0)
- {
- ReleaseHandle();
- return;
- }
-
- if (_handle == null)
- {
- _handle = new SafeHeapHandle(byteLength);
- }
- else
- {
- _handle.Resize(byteLength);
- }
- }
-
- [System.Security.SecuritySafeCritical]
- private void ReleaseHandle()
- {
- if (_handle != null)
- {
- _capacity = 0;
- _handle = null;
- }
- }
-
- /// <summary>
- /// Release the backing buffer
- /// </summary>
- [System.Security.SecuritySafeCritical]
- public virtual void Free()
- {
- ReleaseHandle();
- }
-
- [System.Security.SecuritySafeCritical]
- public void Dispose()
- {
- Free();
- }
-
- [System.Security.SecurityCritical]
- private sealed class EmptySafeHandle : SafeHandle
- {
- public EmptySafeHandle() : base(IntPtr.Zero, true) { }
-
- public override bool IsInvalid
- {
- [System.Security.SecurityCritical]
- get
- { return true; }
- }
-
- [System.Security.SecurityCritical]
- protected override bool ReleaseHandle()
- {
- return true;
- }
- }
- }
-} \ No newline at end of file
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/NativeMethods.cs b/src/mscorlib/src/System/Runtime/InteropServices/NativeMethods.cs
index 82cd4fa963..650ea65697 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/NativeMethods.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/NativeMethods.cs
@@ -31,13 +31,10 @@ namespace System.Runtime.InteropServices {
]
internal interface IDispatch {
- [System.Security.SecurityCritical]
void GetTypeInfoCount(out uint pctinfo);
- [System.Security.SecurityCritical]
void GetTypeInfo(uint iTInfo, int lcid, out IntPtr info);
- [System.Security.SecurityCritical]
void GetIDsOfNames(
ref Guid iid,
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 2)]
@@ -48,7 +45,6 @@ namespace System.Runtime.InteropServices {
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I4, SizeParamIndex = 2)]
int[] rgDispId);
- [System.Security.SecurityCritical]
void Invoke(
int dispIdMember,
ref Guid riid,
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/NonPortable.cs b/src/mscorlib/src/System/Runtime/InteropServices/NonPortable.cs
index 408f56c8e2..0c8ae7649c 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/NonPortable.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/NonPortable.cs
@@ -33,6 +33,18 @@ namespace System.Runtime.InteropServices
}
[System.Security.SecurityCriticalAttribute]
+ public static Object BindToMoniker(String monikerName)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ [System.Security.SecurityCriticalAttribute]
+ public static void CleanupUnusedObjectsInCurrentContext()
+ {
+ return;
+ }
+
+ [System.Security.SecurityCriticalAttribute]
public static System.IntPtr CreateAggregatedObject<T>(System.IntPtr pOuter, T o)
{
throw new PlatformNotSupportedException();
@@ -51,6 +63,12 @@ namespace System.Runtime.InteropServices
}
[System.Security.SecurityCriticalAttribute]
+ public static void ChangeWrapperHandleStrength(Object otp, bool fIsWeak)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ [System.Security.SecurityCriticalAttribute]
public static int FinalReleaseComObject(object o)
{
throw new PlatformNotSupportedException();
@@ -75,6 +93,16 @@ namespace System.Runtime.InteropServices
}
[System.Security.SecurityCriticalAttribute]
+ public static System.IntPtr GetHINSTANCE(System.Reflection.Module m)
+ {
+ if (m == null)
+ {
+ throw new ArgumentNullException(nameof(m));
+ }
+ return (System.IntPtr) (-1);
+ }
+
+ [System.Security.SecurityCriticalAttribute]
public static System.IntPtr GetIUnknownForObject(object o)
{
throw new PlatformNotSupportedException();
@@ -93,6 +121,12 @@ namespace System.Runtime.InteropServices
}
[System.Security.SecurityCriticalAttribute]
+ public static Object GetTypedObjectForIUnknown(System.IntPtr pUnk, System.Type t)
+ {
+ throw new PlatformNotSupportedException();
+ }
+
+ [System.Security.SecurityCriticalAttribute]
public static object GetObjectForIUnknown(System.IntPtr pUnk)
{
throw new PlatformNotSupportedException();
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/RegistrationServices.cs b/src/mscorlib/src/System/Runtime/InteropServices/RegistrationServices.cs
index 7d3670d877..0105866415 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/RegistrationServices.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/RegistrationServices.cs
@@ -29,6 +29,7 @@ namespace System.Runtime.InteropServices {
using System.Runtime.CompilerServices;
using System.Globalization;
using System.Runtime.Versioning;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
[Flags]
@@ -91,12 +92,11 @@ namespace System.Runtime.InteropServices {
#region IRegistrationServices
- [System.Security.SecurityCritical] // auto-generated_required
public virtual bool RegisterAssembly(Assembly assembly, AssemblyRegistrationFlags flags)
{
// Validate the arguments.
if (assembly == null)
- throw new ArgumentNullException("assembly");
+ throw new ArgumentNullException(nameof(assembly));
if (assembly.ReflectionOnly)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_AsmLoadedForReflectionOnly"));
@@ -154,12 +154,11 @@ namespace System.Runtime.InteropServices {
return false;
}
- [System.Security.SecurityCritical] // auto-generated_required
public virtual bool UnregisterAssembly(Assembly assembly)
{
// Validate the arguments.
if (assembly == null)
- throw new ArgumentNullException("assembly");
+ throw new ArgumentNullException(nameof(assembly));
if (assembly.ReflectionOnly)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_AsmLoadedForReflectionOnly"));
@@ -214,16 +213,15 @@ namespace System.Runtime.InteropServices {
return false;
}
- [System.Security.SecurityCritical] // auto-generated_required
public virtual Type[] GetRegistrableTypesInAssembly(Assembly assembly)
{
// Validate the arguments.
if (assembly == null)
- throw new ArgumentNullException("assembly");
+ throw new ArgumentNullException(nameof(assembly));
Contract.EndContractBlock();
if (!(assembly is RuntimeAssembly))
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeAssembly"), "assembly");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeAssembly"), nameof(assembly));
// Retrieve the list of types in the assembly.
Type[] aTypes = assembly.GetExportedTypes();
@@ -246,23 +244,21 @@ namespace System.Runtime.InteropServices {
return RetArray;
}
- [System.Security.SecurityCritical] // auto-generated_required
public virtual String GetProgIdForType(Type type)
{
return Marshal.GenerateProgIdForType(type);
}
- [System.Security.SecurityCritical] // auto-generated_required
public virtual void RegisterTypeForComClients(Type type, ref Guid g)
{
#if FEATURE_COMINTEROP_MANAGED_ACTIVATION
if(type == null)
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
Contract.EndContractBlock();
if((type as RuntimeType) == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"),"type");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"),nameof(type));
if(!TypeRequiresRegistration(type))
- throw new ArgumentException(Environment.GetResourceString("Argument_TypeMustBeComCreatable"),"type");
+ throw new ArgumentException(Environment.GetResourceString("Argument_TypeMustBeComCreatable"),nameof(type));
// Call the native method to do CoRegisterClassObject
RegisterTypeForComClientsNative(type, ref g);
@@ -276,13 +272,11 @@ namespace System.Runtime.InteropServices {
return s_ManagedCategoryGuid;
}
- [System.Security.SecurityCritical] // auto-generated_required
public virtual bool TypeRequiresRegistration(Type type)
{
return TypeRequiresRegistrationHelper(type);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public virtual bool TypeRepresentsComType(Type type)
{
// If the type is not a COM import, then it does not represent a COM type.
@@ -296,7 +290,7 @@ namespace System.Runtime.InteropServices {
// If the type is derived from a tdImport class and has the same GUID as the
// imported class, then it represents a COM type.
Type baseComImportType = GetBaseComImportType(type);
- Contract.Assert(baseComImportType != null, "baseComImportType != null");
+ Debug.Assert(baseComImportType != null, "baseComImportType != null");
if (Marshal.GenerateGuidForType(type) == Marshal.GenerateGuidForType(baseComImportType))
return true;
@@ -307,18 +301,17 @@ namespace System.Runtime.InteropServices {
#region Public methods not on IRegistrationServices
- [System.Security.SecurityCritical] // auto-generated_required
[ComVisible(false)]
public virtual int RegisterTypeForComClients(Type type, RegistrationClassContext classContext, RegistrationConnectionType flags)
{
#if FEATURE_COMINTEROP_MANAGED_ACTIVATION
if (type == null)
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
Contract.EndContractBlock();
if ((type as RuntimeType) == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"),"type");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"),nameof(type));
if (!TypeRequiresRegistration(type))
- throw new ArgumentException(Environment.GetResourceString("Argument_TypeMustBeComCreatable"),"type");
+ throw new ArgumentException(Environment.GetResourceString("Argument_TypeMustBeComCreatable"),nameof(type));
// Call the native method to do CoRegisterClassObject
return RegisterTypeForComClientsExNative(type, classContext, flags);
@@ -327,7 +320,6 @@ namespace System.Runtime.InteropServices {
#endif // FEATURE_COMINTEROP_MANAGED_ACTIVATION
}
- [System.Security.SecurityCritical] // auto-generated_required
[ComVisible(false)]
public virtual void UnregisterTypeForComClients(int cookie)
{
@@ -340,7 +332,6 @@ namespace System.Runtime.InteropServices {
#region Internal helpers
- [System.Security.SecurityCritical] // auto-generated_required
internal static bool TypeRequiresRegistrationHelper(Type type)
{
// If the type is not a class or a value class, then it does not get registered.
@@ -365,7 +356,6 @@ namespace System.Runtime.InteropServices {
#region Private helpers
- [System.Security.SecurityCritical] // auto-generated
private void RegisterValueType(Type type, String strAsmName, String strAsmVersion, String strAsmCodeBase, String strRuntimeVersion)
{
// Retrieve some information that will be used during the registration process.
@@ -397,7 +387,6 @@ namespace System.Runtime.InteropServices {
}
}
- [System.Security.SecurityCritical] // auto-generated
private void RegisterManagedType(Type type, String strAsmName, String strAsmVersion, String strAsmCodeBase, String strRuntimeVersion)
{
//
@@ -483,7 +472,6 @@ namespace System.Runtime.InteropServices {
EnsureManagedCategoryExists();
}
- [System.Security.SecurityCritical] // auto-generated
private void RegisterComImportedType(Type type, String strAsmName, String strAsmVersion, String strAsmCodeBase, String strRuntimeVersion)
{
// Retrieve some information that will be used during the registration process.
@@ -525,7 +513,6 @@ namespace System.Runtime.InteropServices {
}
}
- [System.Security.SecurityCritical] // auto-generated
private bool UnregisterValueType(Type type, String strAsmVersion)
{
bool bAllVersionsGone = true;
@@ -582,7 +569,6 @@ namespace System.Runtime.InteropServices {
// Return :
// true: All versions are gone.
// false: Some versions are still left in registry
- [System.Security.SecurityCritical] // auto-generated
private bool UnregisterManagedType(Type type,String strAsmVersion)
{
bool bAllVersionsGone = true;
@@ -776,7 +762,6 @@ namespace System.Runtime.InteropServices {
// Return:
// true: All version information are gone.
// false: There are still some version left in registry
- [System.Security.SecurityCritical] // auto-generated
private bool UnregisterComImportedType(Type type, String strAsmVersion)
{
bool bAllVersionsGone = true;
@@ -846,7 +831,6 @@ namespace System.Runtime.InteropServices {
return bAllVersionsGone;
}
- [System.Security.SecurityCritical] // auto-generated
private void RegisterPrimaryInteropAssembly(RuntimeAssembly assembly, String strAsmCodeBase, PrimaryInteropAssemblyAttribute attr)
{
// Validate that the PIA has a strong name.
@@ -874,7 +858,6 @@ namespace System.Runtime.InteropServices {
}
}
- [System.Security.SecurityCritical] // auto-generated
private void UnregisterPrimaryInteropAssembly(Assembly assembly, PrimaryInteropAssemblyAttribute attr)
{
String strTlbId = "{" + Marshal.GetTypeLibGuidForAssembly(assembly).ToString().ToUpper(CultureInfo.InvariantCulture) + "}";
@@ -937,20 +920,12 @@ namespace System.Runtime.InteropServices {
private static bool ManagedCategoryExists()
{
using (RegistryKey componentCategoryKey = Registry.ClassesRoot.OpenSubKey(strComponentCategorySubKey,
-#if FEATURE_MACL
- RegistryKeyPermissionCheck.ReadSubTree))
-#else
false))
-#endif
{
if (componentCategoryKey == null)
return false;
using (RegistryKey managedCategoryKey = componentCategoryKey.OpenSubKey(strManagedCategoryGuid,
-#if FEATURE_MACL
- RegistryKeyPermissionCheck.ReadSubTree))
-#else
false))
-#endif
{
if (managedCategoryKey == null)
return false;
@@ -966,7 +941,6 @@ namespace System.Runtime.InteropServices {
return true;
}
- [System.Security.SecurityCritical] // auto-generated
private void CallUserDefinedRegistrationMethod(Type type, bool bRegister)
{
bool bFunctionCalled = false;
@@ -1069,13 +1043,11 @@ namespace System.Runtime.InteropServices {
#if FEATURE_COMINTEROP_MANAGED_ACTIVATION
// GUID versioning can be controlled by using the GuidAttribute or
// letting the runtime generate it based on type and assembly strong name.
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void RegisterTypeForComClientsNative(Type type,ref Guid g);
// GUID versioning can be controlled by using the GuidAttribute or
// letting the runtime generate it based on type and assembly strong name.
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern int RegisterTypeForComClientsExNative(Type t, RegistrationClassContext clsContext, RegistrationConnectionType flags);
#endif // FEATURE_COMINTEROP_MANAGED_ACTIVATION
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/RuntimeEnvironment.cs b/src/mscorlib/src/System/Runtime/InteropServices/RuntimeEnvironment.cs
index d722843ae8..a5c058da43 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/RuntimeEnvironment.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/RuntimeEnvironment.cs
@@ -23,70 +23,31 @@ using Microsoft.Win32;
using System.Runtime.Versioning;
using StackCrawlMark = System.Threading.StackCrawlMark;
-namespace System.Runtime.InteropServices {
-[System.Runtime.InteropServices.ComVisible(true)]
-#if FEATURE_CORECLR
- static
-#endif
- public class RuntimeEnvironment {
+namespace System.Runtime.InteropServices
+{
+ [System.Runtime.InteropServices.ComVisible(true)]
+ static public class RuntimeEnvironment {
-#if !FEATURE_CORECLR
- // This should have been a static class, but wasn't as of v3.5. Clearly, this is
- // broken. We'll keep this in V4 for binary compat, but marked obsolete as error
- // so migrated source code gets fixed. On Silverlight, this type exists but is
- // not public.
- [Obsolete("Do not create instances of the RuntimeEnvironment class. Call the static methods directly on this type instead", true)]
- public RuntimeEnvironment()
- {
- // Should not have been instantiable - here for binary compatibility in V4.
- }
-#endif
-
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern String GetModuleFileName();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern String GetDeveloperPath();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern String GetHostBindingFile();
-#if !FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- internal static extern void _GetSystemVersion(StringHandleOnStack retVer);
-#endif //!FEATURE_CORECLR
-
public static bool FromGlobalAccessCache(Assembly a)
{
return a.GlobalAssemblyCache;
}
-
-#if !FEATURE_CORECLR
- [System.Security.SecuritySafeCritical] // public member
-#endif
+
[MethodImpl (MethodImplOptions.NoInlining)]
public static String GetSystemVersion()
{
-#if FEATURE_CORECLR
-
return Assembly.GetExecutingAssembly().ImageRuntimeVersion;
-
-#else // FEATURE_CORECLR
-
- String ver = null;
- _GetSystemVersion(JitHelpers.GetStringHandleOnStack(ref ver));
- return ver;
-
-#endif // FEATURE_CORECLR
-
}
-
- [System.Security.SecuritySafeCritical] // auto-generated
+
public static String GetRuntimeDirectory()
{
String dir = GetRuntimeDirectoryImpl();
@@ -94,13 +55,11 @@ namespace System.Runtime.InteropServices {
return dir;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern String GetRuntimeDirectoryImpl();
// Returns the system ConfigurationFile
public static String SystemConfigurationFile {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
StringBuilder sb = new StringBuilder(Path.MaxPath);
sb.Append(GetRuntimeDirectory());
@@ -115,7 +74,6 @@ namespace System.Runtime.InteropServices {
}
#if FEATURE_COMINTEROP
- [System.Security.SecurityCritical]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern IntPtr GetRuntimeInterfaceImpl(
@@ -130,7 +88,6 @@ namespace System.Runtime.InteropServices {
// Returns unmanaged pointer to requested interface on success. Throws
// COMException with failed HR if there is a QI failure.
//
- [System.Security.SecurityCritical] // do not allow partial trust callers
[ComVisible(false)]
public static IntPtr GetRuntimeInterfaceAsIntPtr(Guid clsid, Guid riid)
{
@@ -145,7 +102,6 @@ namespace System.Runtime.InteropServices {
// Returns an RCW to requested interface on success. Throws
// COMException with failed HR if there is a QI failure.
//
- [System.Security.SecurityCritical] // do not allow partial trust callers
[ComVisible(false)]
public static object GetRuntimeInterfaceAsObject(Guid clsid, Guid riid)
{
@@ -159,7 +115,6 @@ namespace System.Runtime.InteropServices {
}
}
}
-
#endif // FEATURE_COMINTEROP
}
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/SafeBuffer.cs b/src/mscorlib/src/System/Runtime/InteropServices/SafeBuffer.cs
index a659daf2b5..eba67ae74e 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/SafeBuffer.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/SafeBuffer.cs
@@ -75,10 +75,10 @@ using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
using System.Runtime.Versioning;
using Microsoft.Win32.SafeHandles;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
- [System.Security.SecurityCritical]
public abstract unsafe class SafeBuffer : SafeHandleZeroOrMinusOneIsInvalid
{
// Steal UIntPtr.MaxValue as our uninitialized value.
@@ -101,13 +101,13 @@ using System.Diagnostics.Contracts;
public void Initialize(ulong numBytes)
{
if (numBytes < 0)
- throw new ArgumentOutOfRangeException("numBytes", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(numBytes), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (IntPtr.Size == 4 && numBytes > UInt32.MaxValue)
- throw new ArgumentOutOfRangeException("numBytes", Environment.GetResourceString("ArgumentOutOfRange_AddressSpace"));
+ throw new ArgumentOutOfRangeException(nameof(numBytes), Environment.GetResourceString("ArgumentOutOfRange_AddressSpace"));
Contract.EndContractBlock();
if (numBytes >= (ulong)Uninitialized)
- throw new ArgumentOutOfRangeException("numBytes", Environment.GetResourceString("ArgumentOutOfRange_UIntPtrMax-1"));
+ throw new ArgumentOutOfRangeException(nameof(numBytes), Environment.GetResourceString("ArgumentOutOfRange_UIntPtrMax-1"));
_numBytes = (UIntPtr) numBytes;
}
@@ -120,16 +120,16 @@ using System.Diagnostics.Contracts;
public void Initialize(uint numElements, uint sizeOfEachElement)
{
if (numElements < 0)
- throw new ArgumentOutOfRangeException("numElements", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(numElements), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (sizeOfEachElement < 0)
- throw new ArgumentOutOfRangeException("sizeOfEachElement", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(sizeOfEachElement), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (IntPtr.Size == 4 && numElements * sizeOfEachElement > UInt32.MaxValue)
throw new ArgumentOutOfRangeException("numBytes", Environment.GetResourceString("ArgumentOutOfRange_AddressSpace"));
Contract.EndContractBlock();
if (numElements * sizeOfEachElement >= (ulong)Uninitialized)
- throw new ArgumentOutOfRangeException("numElements", Environment.GetResourceString("ArgumentOutOfRange_UIntPtrMax-1"));
+ throw new ArgumentOutOfRangeException(nameof(numElements), Environment.GetResourceString("ArgumentOutOfRange_UIntPtrMax-1"));
_numBytes = checked((UIntPtr) (numElements * sizeOfEachElement));
}
@@ -245,11 +245,11 @@ using System.Diagnostics.Contracts;
where T : struct
{
if (array == null)
- throw new ArgumentNullException("array", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(array), Environment.GetResourceString("ArgumentNull_Buffer"));
if (index < 0)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (array.Length - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -317,11 +317,11 @@ using System.Diagnostics.Contracts;
where T : struct
{
if (array == null)
- throw new ArgumentNullException("array", Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(array), Environment.GetResourceString("ArgumentNull_Buffer"));
if (index < 0)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (array.Length - index < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -385,7 +385,7 @@ using System.Diagnostics.Contracts;
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
private static InvalidOperationException NotInitialized()
{
- Contract.Assert(false, "Uninitialized SafeBuffer! Someone needs to call Initialize before using this instance!");
+ Debug.Assert(false, "Uninitialized SafeBuffer! Someone needs to call Initialize before using this instance!");
return new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MustCallInitialize"));
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/SafeHandle.cs b/src/mscorlib/src/System/Runtime/InteropServices/SafeHandle.cs
index c26852874d..ed9910e4e4 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/SafeHandle.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/SafeHandle.cs
@@ -134,10 +134,6 @@ using System.Runtime.Versioning;
// 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.
-[System.Security.SecurityCritical] // auto-generated_required
-#if !FEATURE_CORECLR
-[SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode=true)]
-#endif
public abstract class SafeHandle : CriticalFinalizerObject, IDisposable
{
// ! Do not add or rearrange fields as the EE depends on this layout.
@@ -182,16 +178,13 @@ public abstract class SafeHandle : CriticalFinalizerObject, IDisposable
_fullyInitialized = true;
}
-#if FEATURE_CORECLR
// 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();
}
-#endif
- [System.Security.SecuritySafeCritical] // auto-generated
~SafeHandle()
{
Dispose(false);
@@ -236,19 +229,16 @@ public abstract class SafeHandle : CriticalFinalizerObject, IDisposable
get;
}
- [System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public void Close() {
Dispose(true);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public void Dispose() {
Dispose(true);
}
- [System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
protected virtual void Dispose(bool disposing)
{
@@ -266,7 +256,6 @@ public abstract class SafeHandle : CriticalFinalizerObject, IDisposable
// 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!
- [System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern void SetHandleAsInvalid();
@@ -295,7 +284,6 @@ public abstract class SafeHandle : CriticalFinalizerObject, IDisposable
// 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.
- [System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern void DangerousAddRef(ref bool success);
@@ -309,7 +297,6 @@ public abstract class SafeHandle : CriticalFinalizerObject, IDisposable
// 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.
- [System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern void DangerousRelease();
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/SafeHeapHandle.cs b/src/mscorlib/src/System/Runtime/InteropServices/SafeHeapHandle.cs
deleted file mode 100644
index b0c422d0c0..0000000000
--- a/src/mscorlib/src/System/Runtime/InteropServices/SafeHeapHandle.cs
+++ /dev/null
@@ -1,115 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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
-{
- /// <summary>
- /// Handle for heap memory that allows tracking of capacity and reallocating.
- /// </summary>
- [System.Security.SecurityCritical]
- internal sealed class SafeHeapHandle : SafeBuffer
- {
- /// <summary>
- /// Allocate a buffer of the given size if requested.
- /// </summary>
- /// <param name="byteLength">Required size in bytes. Must be less than UInt32.MaxValue for 32 bit or UInt64.MaxValue for 64 bit.</param>
- /// <exception cref="OutOfMemoryException">Thrown if the requested memory size cannot be allocated.</exception>
- /// <exception cref="ArgumentOutOfRangeException">Thrown if size is greater than the maximum memory size.</exception>
- public SafeHeapHandle(ulong byteLength) : base(ownsHandle: true)
- {
- Resize(byteLength);
- }
-
- public override bool IsInvalid
- {
- [System.Security.SecurityCritical]
- get
- { return handle == IntPtr.Zero; }
- }
-
- /// <summary>
- /// Resize the buffer to the given size if requested.
- /// </summary>
- /// <param name="byteLength">Required size in bytes. Must be less than UInt32.MaxValue for 32 bit or UInt64.MaxValue for 64 bit.</param>
- /// <exception cref="OutOfMemoryException">Thrown if the requested memory size cannot be allocated.</exception>
- /// <exception cref="ArgumentOutOfRangeException">Thrown if size is greater than the maximum memory size.</exception>
- public void Resize(ulong byteLength)
- {
- if (IsClosed) throw new ObjectDisposedException("SafeHeapHandle");
-
- ulong originalLength = 0;
- if (handle == IntPtr.Zero)
- {
- handle = Marshal.AllocHGlobal((IntPtr)byteLength);
- }
- else
- {
- originalLength = ByteLength;
-
- // This may or may not be the same handle, may realloc in place. If the
- // handle changes Windows will deal with the old handle, trying to free it will
- // cause an error.
- handle = Marshal.ReAllocHGlobal(pv: handle, cb: (IntPtr)byteLength);
- }
-
- if (handle == IntPtr.Zero)
- {
- // Only real plausible answer
- throw new OutOfMemoryException();
- }
-
- if (byteLength > originalLength)
- {
- // Add pressure
- ulong addedBytes = byteLength - originalLength;
- if (addedBytes > long.MaxValue)
- {
- GC.AddMemoryPressure(long.MaxValue);
- GC.AddMemoryPressure((long)(addedBytes - long.MaxValue));
- }
- else
- {
- GC.AddMemoryPressure((long)addedBytes);
- }
- }
- else
- {
- // Shrank or did nothing, release pressure if needed
- RemoveMemoryPressure(originalLength - byteLength);
- }
-
- Initialize(byteLength);
- }
-
- private void RemoveMemoryPressure(ulong removedBytes)
- {
- if (removedBytes == 0) return;
-
- if (removedBytes > long.MaxValue)
- {
- GC.RemoveMemoryPressure(long.MaxValue);
- GC.RemoveMemoryPressure((long)(removedBytes - long.MaxValue));
- }
- else
- {
- GC.RemoveMemoryPressure((long)removedBytes);
- }
- }
-
- [System.Security.SecurityCritical]
- protected override bool ReleaseHandle()
- {
- IntPtr handle = this.handle;
- this.handle = IntPtr.Zero;
-
- if (handle != IntPtr.Zero)
- {
- RemoveMemoryPressure(ByteLength);
- Marshal.FreeHGlobal(handle);
- }
-
- return true;
- }
- }
-} \ No newline at end of file
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/StringBuffer.cs b/src/mscorlib/src/System/Runtime/InteropServices/StringBuffer.cs
deleted file mode 100644
index 15b1b6ae8e..0000000000
--- a/src/mscorlib/src/System/Runtime/InteropServices/StringBuffer.cs
+++ /dev/null
@@ -1,402 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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
-{
- /// <summary>
- /// Native buffer that deals in char size increments. Dispose to free memory. Allows buffers larger
- /// than a maximum size string to enable working with very large string arrays. Always makes ordinal
- /// comparisons.
- ///
- /// A more performant replacement for StringBuilder when performing native interop.
- /// </summary>
- /// <remarks>
- /// Suggested use through P/Invoke: define DllImport arguments that take a character buffer as IntPtr.
- /// NativeStringBuffer has an implicit conversion to IntPtr.
- /// </remarks>
- internal class StringBuffer : NativeBuffer
- {
- private uint _length;
-
- /// <summary>
- /// Instantiate the buffer with capacity for at least the specified number of characters. Capacity
- /// includes the trailing null character.
- /// </summary>
- public StringBuffer(uint initialCapacity = 0)
- : base(initialCapacity * (ulong)sizeof(char))
- {
- }
-
- /// <summary>
- /// Instantiate the buffer with a copy of the specified string.
- /// </summary>
- public StringBuffer(string initialContents)
- : base(0)
- {
- // We don't pass the count of bytes to the base constructor, appending will
- // initialize to the correct size for the specified initial contents.
- if (initialContents != null)
- {
- Append(initialContents);
- }
- }
-
- /// <summary>
- /// Instantiate the buffer with a copy of the specified StringBuffer.
- /// </summary>
- public StringBuffer(StringBuffer initialContents)
- : base(0)
- {
- // We don't pass the count of bytes to the base constructor, appending will
- // initialize to the correct size for the specified initial contents.
- if (initialContents != null)
- {
- Append(initialContents);
- }
- }
-
- /// <summary>
- /// Get/set the character at the given index.
- /// </summary>
- /// <exception cref="ArgumentOutOfRangeException">Thrown if attempting to index outside of the buffer length.</exception>
- public unsafe char this[uint index]
- {
- [System.Security.SecuritySafeCritical]
- get
- {
- if (index >= _length) throw new ArgumentOutOfRangeException("index");
- return CharPointer[index];
- }
- [System.Security.SecuritySafeCritical]
- set
- {
- if (index >= _length) throw new ArgumentOutOfRangeException("index");
- CharPointer[index] = value;
- }
- }
-
- /// <summary>
- /// Character capacity of the buffer. Includes the count for the trailing null character.
- /// </summary>
- public uint CharCapacity
- {
- [System.Security.SecuritySafeCritical]
- get
- {
- ulong byteCapacity = ByteCapacity;
- ulong charCapacity = byteCapacity == 0 ? 0 : byteCapacity / sizeof(char);
- return charCapacity > uint.MaxValue ? uint.MaxValue : (uint)charCapacity;
- }
- }
-
- /// <summary>
- /// Ensure capacity in characters is at least the given minimum. Capacity includes space for the trailing
- /// null, which is not part of the Length.
- /// </summary>
- /// <exception cref="OutOfMemoryException">Thrown if unable to allocate memory when setting.</exception>
- [System.Security.SecuritySafeCritical]
- public void EnsureCharCapacity(uint minCapacity)
- {
- EnsureByteCapacity(minCapacity * (ulong)sizeof(char));
- }
-
- /// <summary>
- /// The logical length of the buffer in characters. (Does not include the final null, which is auto appended.) Will automatically attempt to increase capacity.
- /// This is where the usable data ends.
- /// </summary>
- /// <exception cref="OutOfMemoryException">Thrown if unable to allocate memory when setting.</exception>
- /// <exception cref="ArgumentOutOfRangeException">Thrown if the set size in bytes is uint.MaxValue (as space is implicitly reservced for the trailing null).</exception>
- public unsafe uint Length
- {
- get { return _length; }
- [System.Security.SecuritySafeCritical]
- set
- {
- if (value == uint.MaxValue) throw new ArgumentOutOfRangeException("Length");
-
- // Null terminate
- EnsureCharCapacity(value + 1);
- CharPointer[value] = '\0';
-
- _length = value;
- }
- }
-
- /// <summary>
- /// For use when the native api null terminates but doesn't return a length.
- /// If no null is found, the length will not be changed.
- /// </summary>
- [System.Security.SecuritySafeCritical]
- public unsafe void SetLengthToFirstNull()
- {
- char* buffer = CharPointer;
- uint capacity = CharCapacity;
- for (uint i = 0; i < capacity; i++)
- {
- if (buffer[i] == '\0')
- {
- _length = i;
- break;
- }
- }
- }
-
- internal unsafe char* CharPointer
- {
- [System.Security.SecurityCritical]
- get
- {
- return (char*)VoidPointer;
- }
- }
-
- /// <summary>
- /// True if the buffer contains the given character.
- /// </summary>
- [System.Security.SecurityCritical]
- public unsafe bool Contains(char value)
- {
- char* start = CharPointer;
- uint length = _length;
-
- for (uint i = 0; i < length; i++)
- {
- if (*start++ == value) return true;
- }
-
- return false;
- }
-
- /// <summary>
- /// Returns true if the buffer starts with the given string.
- /// </summary>
- [System.Security.SecuritySafeCritical]
- public bool StartsWith(string value)
- {
- if (value == null) throw new ArgumentNullException("value");
- if (_length < (uint)value.Length) return false;
- return SubstringEquals(value, startIndex: 0, count: value.Length);
- }
-
- /// <summary>
- /// Returns true if the specified StringBuffer substring equals the given value.
- /// </summary>
- /// <param name="value">The value to compare against the specified substring.</param>
- /// <param name="startIndex">Start index of the sub string.</param>
- /// <param name="count">Length of the substring, or -1 to check all remaining.</param>
- /// <exception cref="ArgumentOutOfRangeException">
- /// Thrown if <paramref name="startIndex"/> or <paramref name="count"/> are outside the range
- /// of the buffer's length.
- /// </exception>
- [System.Security.SecuritySafeCritical]
- public unsafe bool SubstringEquals(string value, uint startIndex = 0, int count = -1)
- {
- if (value == null) return false;
- if (count < -1) throw new ArgumentOutOfRangeException("count");
- if (startIndex > _length) throw new ArgumentOutOfRangeException("startIndex");
-
- uint realCount = count == -1 ? _length - startIndex : (uint)count;
- if (checked(startIndex + realCount) > _length) throw new ArgumentOutOfRangeException("count");
-
- int length = value.Length;
-
- // Check the substring length against the input length
- if (realCount != (uint)length) return false;
-
- fixed (char* valueStart = value)
- {
- char* bufferStart = CharPointer + startIndex;
- for (int i = 0; i < length; i++)
- {
- // Note that indexing in this case generates faster code than trying to copy the pointer and increment it
- if (*bufferStart++ != valueStart[i]) return false;
- }
- }
-
- return true;
- }
-
- /// <summary>
- /// Append the given string.
- /// </summary>
- /// <param name="value">The string to append.</param>
- /// <param name="startIndex">The index in the input string to start appending from.</param>
- /// <param name="count">The count of characters to copy from the input string, or -1 for all remaining.</param>
- /// <exception cref="ArgumentNullException">Thrown if <paramref name="value"/> is null.</exception>
- /// <exception cref="ArgumentOutOfRangeException">
- /// Thrown if <paramref name="startIndex"/> or <paramref name="count"/> are outside the range
- /// of <paramref name="value"/> characters.
- /// </exception>
- [System.Security.SecuritySafeCritical]
- public void Append(string value, int startIndex = 0, int count = -1)
- {
- CopyFrom(
- bufferIndex: _length,
- source: value,
- sourceIndex: startIndex,
- count: count);
- }
-
- /// <summary>
- /// Append the given buffer.
- /// </summary>
- /// <param name="value">The buffer to append.</param>
- /// <param name="startIndex">The index in the input buffer to start appending from.</param>
- /// <exception cref="ArgumentNullException">Thrown if <paramref name="value"/> is null.</exception>
- /// <exception cref="ArgumentOutOfRangeException">
- /// Thrown if <paramref name="startIndex"/> is outside the range of <paramref name="value"/> characters.
- /// </exception>
- public void Append(StringBuffer value, uint startIndex = 0)
- {
- if (value == null) throw new ArgumentNullException("value");
- if (value.Length == 0) return;
- value.CopyTo(
- bufferIndex: startIndex,
- destination: this,
- destinationIndex: _length,
- count: value.Length);
- }
-
- /// <summary>
- /// Append the given buffer.
- /// </summary>
- /// <param name="value">The buffer to append.</param>
- /// <param name="startIndex">The index in the input buffer to start appending from.</param>
- /// <param name="count">The count of characters to copy from the buffer string.</param>
- /// <exception cref="ArgumentNullException">Thrown if <paramref name="value"/> is null.</exception>
- /// <exception cref="ArgumentOutOfRangeException">
- /// Thrown if <paramref name="startIndex"/> or <paramref name="count"/> are outside the range
- /// of <paramref name="value"/> characters.
- /// </exception>
- public void Append(StringBuffer value, uint startIndex, uint count)
- {
- if (value == null) throw new ArgumentNullException("value");
- if (count == 0) return;
- value.CopyTo(
- bufferIndex: startIndex,
- destination: this,
- destinationIndex: _length,
- count: count);
- }
-
- /// <summary>
- /// Copy contents to the specified buffer. Destination index must be within current destination length.
- /// Will grow the destination buffer if needed.
- /// </summary>
- /// <exception cref="ArgumentOutOfRangeException">
- /// Thrown if <paramref name="bufferIndex"/> or <paramref name="destinationIndex"/> or <paramref name="count"/> are outside the range
- /// of <paramref name="value"/> characters.
- /// </exception>
- /// <exception cref="ArgumentNullException">Thrown if <paramref name="destination"/> is null.</exception>
- [System.Security.SecuritySafeCritical]
- public unsafe void CopyTo(uint bufferIndex, StringBuffer destination, uint destinationIndex, uint count)
- {
- if (destination == null) throw new ArgumentNullException("destination");
- if (destinationIndex > destination._length) throw new ArgumentOutOfRangeException("destinationIndex");
- if (bufferIndex >= _length) throw new ArgumentOutOfRangeException("bufferIndex");
- if (_length < checked(bufferIndex + count)) throw new ArgumentOutOfRangeException("count");
-
- if (count == 0) return;
- uint lastIndex = checked(destinationIndex + count);
- if (destination._length < lastIndex) destination.Length = lastIndex;
-
- Buffer.MemoryCopy(
- source: CharPointer + bufferIndex,
- destination: destination.CharPointer + destinationIndex,
- destinationSizeInBytes: checked((long)(destination.ByteCapacity - (destinationIndex * sizeof(char)))),
- sourceBytesToCopy: checked((long)count * sizeof(char)));
- }
-
- /// <summary>
- /// Copy contents from the specified string into the buffer at the given index. Start index must be within the current length of
- /// the buffer, will grow as necessary.
- /// </summary>
- /// <exception cref="ArgumentOutOfRangeException">
- /// Thrown if <paramref name="bufferIndex"/> or <paramref name="sourceIndex"/> or <paramref name="count"/> are outside the range
- /// of <paramref name="value"/> characters.
- /// </exception>
- /// <exception cref="ArgumentNullException">Thrown if <paramref name="source"/> is null.</exception>
- [System.Security.SecuritySafeCritical]
- public unsafe void CopyFrom(uint bufferIndex, string source, int sourceIndex = 0, int count = -1)
- {
- if (source == null) throw new ArgumentNullException("source");
- if (bufferIndex > _length) throw new ArgumentOutOfRangeException("bufferIndex");
- if (sourceIndex < 0 || sourceIndex >= source.Length) throw new ArgumentOutOfRangeException("sourceIndex");
- if (count == -1) count = source.Length - sourceIndex;
- if (count < 0 || source.Length - count < sourceIndex) throw new ArgumentOutOfRangeException("count");
-
- if (count == 0) return;
- uint lastIndex = bufferIndex + (uint)count;
- if (_length < lastIndex) Length = lastIndex;
-
- fixed (char* content = source)
- {
- Buffer.MemoryCopy(
- source: content + sourceIndex,
- destination: CharPointer + bufferIndex,
- destinationSizeInBytes: checked((long)(ByteCapacity - (bufferIndex * sizeof(char)))),
- sourceBytesToCopy: (long)count * sizeof(char));
- }
- }
-
- /// <summary>
- /// Trim the specified values from the end of the buffer. If nothing is specified, nothing is trimmed.
- /// </summary>
- [System.Security.SecuritySafeCritical]
- public unsafe void TrimEnd(char[] values)
- {
- if (values == null || values.Length == 0 || _length == 0) return;
-
- char* end = CharPointer + _length - 1;
-
- while (_length > 0 && Array.IndexOf(values, *end) >= 0)
- {
- Length = _length - 1;
- end--;
- }
- }
-
- /// <summary>
- /// String representation of the entire buffer. If the buffer is larger than the maximum size string (int.MaxValue) this will throw.
- /// </summary>
- /// <exception cref="InvalidOperationException">Thrown if the buffer is too big to fit into a string.</exception>
- [System.Security.SecuritySafeCritical]
- public unsafe override string ToString()
- {
- if (_length == 0) return string.Empty;
- if (_length > int.MaxValue) throw new InvalidOperationException();
- return new string(CharPointer, startIndex: 0, length: (int)_length);
- }
-
- /// <summary>
- /// Get the given substring in the buffer.
- /// </summary>
- /// <param name="count">Count of characters to take, or remaining characters from <paramref name="startIndex"/> if -1.</param>
- /// <exception cref="ArgumentOutOfRangeException">
- /// Thrown if <paramref name="startIndex"/> or <paramref name="count"/> are outside the range of the buffer's length
- /// or count is greater than the maximum string size (int.MaxValue).
- /// </exception>
- [System.Security.SecuritySafeCritical]
- public unsafe string Substring(uint startIndex, int count = -1)
- {
- if (startIndex > (_length == 0 ? 0 : _length - 1)) throw new ArgumentOutOfRangeException("startIndex");
- if (count < -1) throw new ArgumentOutOfRangeException("count");
-
- uint realCount = count == -1 ? _length - startIndex : (uint)count;
- if (realCount > int.MaxValue || checked(startIndex + realCount) > _length) throw new ArgumentOutOfRangeException("count");
- if (realCount == 0) return string.Empty;
-
- // The buffer could be bigger than will fit into a string, but the substring might fit. As the starting
- // index might be bigger than int we need to index ourselves.
- return new string(value: CharPointer + startIndex, startIndex: 0, length: (int)realCount);
- }
-
- [System.Security.SecuritySafeCritical]
- public override void Free()
- {
- base.Free();
- _length = 0;
- }
- }
-} \ No newline at end of file
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventProviderWriter.cs b/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventProviderWriter.cs
index 58f70e57b7..160a0ab491 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventProviderWriter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventProviderWriter.cs
@@ -10,6 +10,7 @@ namespace System.Runtime.InteropServices.TCEAdapterGen {
using System.Reflection.Emit;
using System.Collections;
using System.Threading;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
internal class EventProviderWriter
@@ -96,34 +97,34 @@ namespace System.Runtime.InteropServices.TCEAdapterGen {
// Find the delegate on the event sink helper.
FieldInfo DelegateField = SinkHelperClass.GetField( "m_" + SrcItfMethod.Name + "Delegate" );
- Contract.Assert(DelegateField != null, "Unable to find the field m_" + SrcItfMethod.Name + "Delegate on the sink helper");
+ Debug.Assert(DelegateField != null, "Unable to find the field m_" + SrcItfMethod.Name + "Delegate on the sink helper");
// Find the cookie on the event sink helper.
FieldInfo CookieField = SinkHelperClass.GetField( "m_dwCookie" );
- Contract.Assert(CookieField != null, "Unable to find the field m_dwCookie on the sink helper");
+ Debug.Assert(CookieField != null, "Unable to find the field m_dwCookie on the sink helper");
// Retrieve the sink helper's constructor.
ConstructorInfo SinkHelperCons = SinkHelperClass.GetConstructor(EventProviderWriter.DefaultLookup | BindingFlags.NonPublic, null, Array.Empty<Type>(), null );
- Contract.Assert(SinkHelperCons != null, "Unable to find the constructor for the sink helper");
+ Debug.Assert(SinkHelperCons != null, "Unable to find the constructor for the sink helper");
// Retrieve the IConnectionPoint.Advise method.
MethodInfo CPAdviseMethod = typeof(IConnectionPoint).GetMethod( "Advise" );
- Contract.Assert(CPAdviseMethod != null, "Unable to find the method ConnectionPoint.Advise");
+ Debug.Assert(CPAdviseMethod != null, "Unable to find the method ConnectionPoint.Advise");
// Retrieve the ArrayList.Add method.
aParamTypes = new Type[1];
aParamTypes[0] = typeof(Object);
MethodInfo ArrayListAddMethod = typeof(ArrayList).GetMethod( "Add", aParamTypes, null );
- Contract.Assert(ArrayListAddMethod != null, "Unable to find the method ArrayList.Add");
+ Debug.Assert(ArrayListAddMethod != null, "Unable to find the method ArrayList.Add");
// Retrieve the Monitor.Enter() method.
MethodInfo MonitorEnterMethod = typeof(Monitor).GetMethod( "Enter", MonitorEnterParamTypes, null );
- Contract.Assert(MonitorEnterMethod != null, "Unable to find the method Monitor.Enter()");
+ Debug.Assert(MonitorEnterMethod != null, "Unable to find the method Monitor.Enter()");
// Retrieve the Monitor.Exit() method.
aParamTypes[0] = typeof(Object);
MethodInfo MonitorExitMethod = typeof(Monitor).GetMethod( "Exit", aParamTypes, null );
- Contract.Assert(MonitorExitMethod != null, "Unable to find the method Monitor.Exit()");
+ Debug.Assert(MonitorExitMethod != null, "Unable to find the method Monitor.Exit()");
// Define the add_XXX method.
Type[] parameterTypes;
@@ -239,51 +240,51 @@ namespace System.Runtime.InteropServices.TCEAdapterGen {
// Find the delegate on the event sink helper.
FieldInfo DelegateField = SinkHelperClass.GetField( "m_" + SrcItfMethod.Name + "Delegate" );
- Contract.Assert(DelegateField != null, "Unable to find the field m_" + SrcItfMethod.Name + "Delegate on the sink helper");
+ Debug.Assert(DelegateField != null, "Unable to find the field m_" + SrcItfMethod.Name + "Delegate on the sink helper");
// Find the cookie on the event sink helper.
FieldInfo CookieField = SinkHelperClass.GetField( "m_dwCookie" );
- Contract.Assert(CookieField != null, "Unable to find the field m_dwCookie on the sink helper");
+ Debug.Assert(CookieField != null, "Unable to find the field m_dwCookie on the sink helper");
// Retrieve the ArrayList.RemoveAt method.
aParamTypes = new Type[1];
aParamTypes[0] = typeof(Int32);
MethodInfo ArrayListRemoveMethod = typeof(ArrayList).GetMethod( "RemoveAt", aParamTypes, null );
- Contract.Assert(ArrayListRemoveMethod != null, "Unable to find the method ArrayList.RemoveAt()");
+ Debug.Assert(ArrayListRemoveMethod != null, "Unable to find the method ArrayList.RemoveAt()");
// Retrieve the ArrayList.Item property get method.
PropertyInfo ArrayListItemProperty = typeof(ArrayList).GetProperty( "Item" );
- Contract.Assert(ArrayListItemProperty != null, "Unable to find the property ArrayList.Item");
+ Debug.Assert(ArrayListItemProperty != null, "Unable to find the property ArrayList.Item");
MethodInfo ArrayListItemGetMethod = ArrayListItemProperty.GetGetMethod();
- Contract.Assert(ArrayListItemGetMethod != null, "Unable to find the get method for property ArrayList.Item");
+ Debug.Assert(ArrayListItemGetMethod != null, "Unable to find the get method for property ArrayList.Item");
// Retrieve the ArrayList.Count property get method.
PropertyInfo ArrayListSizeProperty = typeof(ArrayList).GetProperty( "Count" );
- Contract.Assert(ArrayListSizeProperty != null, "Unable to find the property ArrayList.Count");
+ Debug.Assert(ArrayListSizeProperty != null, "Unable to find the property ArrayList.Count");
MethodInfo ArrayListSizeGetMethod = ArrayListSizeProperty.GetGetMethod();
- Contract.Assert(ArrayListSizeGetMethod != null, "Unable to find the get method for property ArrayList.Count");
+ Debug.Assert(ArrayListSizeGetMethod != null, "Unable to find the get method for property ArrayList.Count");
// Retrieve the Delegate.Equals() method.
aParamTypes[0] = typeof(Delegate);
MethodInfo DelegateEqualsMethod = typeof(Delegate).GetMethod( "Equals", aParamTypes, null );
- Contract.Assert(DelegateEqualsMethod != null, "Unable to find the method Delegate.Equlals()");
+ Debug.Assert(DelegateEqualsMethod != null, "Unable to find the method Delegate.Equlals()");
// Retrieve the Monitor.Enter() method.
MethodInfo MonitorEnterMethod = typeof(Monitor).GetMethod("Enter", MonitorEnterParamTypes, null);
- Contract.Assert(MonitorEnterMethod != null, "Unable to find the method Monitor.Enter()");
+ Debug.Assert(MonitorEnterMethod != null, "Unable to find the method Monitor.Enter()");
// Retrieve the Monitor.Exit() method.
aParamTypes[0] = typeof(Object);
MethodInfo MonitorExitMethod = typeof(Monitor).GetMethod( "Exit", aParamTypes, null );
- Contract.Assert(MonitorExitMethod != null, "Unable to find the method Monitor.Exit()");
+ Debug.Assert(MonitorExitMethod != null, "Unable to find the method Monitor.Exit()");
// Retrieve the ConnectionPoint.Unadvise() method.
MethodInfo CPUnadviseMethod = typeof(IConnectionPoint).GetMethod( "Unadvise" );
- Contract.Assert(CPUnadviseMethod != null, "Unable to find the method ConnectionPoint.Unadvise()");
+ Debug.Assert(CPUnadviseMethod != null, "Unable to find the method ConnectionPoint.Unadvise()");
// Retrieve the Marshal.ReleaseComObject() method.
MethodInfo ReleaseComObjectMethod = typeof(Marshal).GetMethod( "ReleaseComObject" );
- Contract.Assert(ReleaseComObjectMethod != null, "Unable to find the method Marshal.ReleaseComObject()");
+ Debug.Assert(ReleaseComObjectMethod != null, "Unable to find the method Marshal.ReleaseComObject()");
// Define the remove_XXX method.
Type[] parameterTypes;
@@ -463,7 +464,7 @@ namespace System.Runtime.InteropServices.TCEAdapterGen {
{
// Retrieve the constructor info for the array list's default constructor.
ConstructorInfo DefaultArrayListCons = typeof(ArrayList).GetConstructor(EventProviderWriter.DefaultLookup, null, Array.Empty<Type>(), null );
- Contract.Assert(DefaultArrayListCons != null, "Unable to find the constructor for class ArrayList");
+ Debug.Assert(DefaultArrayListCons != null, "Unable to find the constructor for class ArrayList");
// Temp byte array for Guid
ubyte[] rgByteGuid = new ubyte[16];
@@ -472,11 +473,11 @@ namespace System.Runtime.InteropServices.TCEAdapterGen {
Type[] aParamTypes = new Type[1];
aParamTypes[0] = typeof(Byte[]);
ConstructorInfo ByteArrayGUIDCons = typeof(Guid).GetConstructor(EventProviderWriter.DefaultLookup, null, aParamTypes, null );
- Contract.Assert(ByteArrayGUIDCons != null, "Unable to find the constructor for GUID that accepts a string as argument");
+ Debug.Assert(ByteArrayGUIDCons != null, "Unable to find the constructor for GUID that accepts a string as argument");
// Retrieve the IConnectionPointContainer.FindConnectionPoint() method.
MethodInfo CPCFindCPMethod = typeof(IConnectionPointContainer).GetMethod( "FindConnectionPoint" );
- Contract.Assert(CPCFindCPMethod != null, "Unable to find the method ConnectionPointContainer.FindConnectionPoint()");
+ Debug.Assert(CPCFindCPMethod != null, "Unable to find the method ConnectionPointContainer.FindConnectionPoint()");
// Define the Init method itself.
MethodBuilder Meth = OutputTypeBuilder.DefineMethod(
@@ -553,7 +554,7 @@ namespace System.Runtime.InteropServices.TCEAdapterGen {
{
// Retrieve the constructor info for the base class's constructor.
ConstructorInfo DefaultBaseClsCons = typeof(Object).GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, Array.Empty<Type>(), null );
- Contract.Assert(DefaultBaseClsCons != null, "Unable to find the object's public default constructor");
+ Debug.Assert(DefaultBaseClsCons != null, "Unable to find the object's public default constructor");
// Define the default constructor.
MethodAttributes ctorAttributes = MethodAttributes.SpecialName | (DefaultBaseClsCons.Attributes & MethodAttributes.MemberAccessMask);
@@ -584,37 +585,37 @@ namespace System.Runtime.InteropServices.TCEAdapterGen {
{
// Find the cookie on the event sink helper.
FieldInfo CookieField = SinkHelperClass.GetField( "m_dwCookie" );
- Contract.Assert(CookieField != null, "Unable to find the field m_dwCookie on the sink helper");
+ Debug.Assert(CookieField != null, "Unable to find the field m_dwCookie on the sink helper");
// Retrieve the ArrayList.Item property get method.
PropertyInfo ArrayListItemProperty = typeof(ArrayList).GetProperty( "Item" );
- Contract.Assert(ArrayListItemProperty != null, "Unable to find the property ArrayList.Item");
+ Debug.Assert(ArrayListItemProperty != null, "Unable to find the property ArrayList.Item");
MethodInfo ArrayListItemGetMethod = ArrayListItemProperty.GetGetMethod();
- Contract.Assert(ArrayListItemGetMethod != null, "Unable to find the get method for property ArrayList.Item");
+ Debug.Assert(ArrayListItemGetMethod != null, "Unable to find the get method for property ArrayList.Item");
// Retrieve the ArrayList.Count property get method.
PropertyInfo ArrayListSizeProperty = typeof(ArrayList).GetProperty( "Count" );
- Contract.Assert(ArrayListSizeProperty != null, "Unable to find the property ArrayList.Count");
+ Debug.Assert(ArrayListSizeProperty != null, "Unable to find the property ArrayList.Count");
MethodInfo ArrayListSizeGetMethod = ArrayListSizeProperty.GetGetMethod();
- Contract.Assert(ArrayListSizeGetMethod != null, "Unable to find the get method for property ArrayList.Count");
+ Debug.Assert(ArrayListSizeGetMethod != null, "Unable to find the get method for property ArrayList.Count");
// Retrieve the ConnectionPoint.Unadvise() method.
MethodInfo CPUnadviseMethod = typeof(IConnectionPoint).GetMethod( "Unadvise" );
- Contract.Assert(CPUnadviseMethod != null, "Unable to find the method ConnectionPoint.Unadvise()");
+ Debug.Assert(CPUnadviseMethod != null, "Unable to find the method ConnectionPoint.Unadvise()");
// Retrieve the Marshal.ReleaseComObject() method.
MethodInfo ReleaseComObjectMethod = typeof(Marshal).GetMethod( "ReleaseComObject" );
- Contract.Assert(ReleaseComObjectMethod != null, "Unable to find the method Marshal.ReleaseComObject()");
+ Debug.Assert(ReleaseComObjectMethod != null, "Unable to find the method Marshal.ReleaseComObject()");
// Retrieve the Monitor.Enter() method.
MethodInfo MonitorEnterMethod = typeof(Monitor).GetMethod("Enter", MonitorEnterParamTypes, null);
- Contract.Assert(MonitorEnterMethod != null, "Unable to find the method Monitor.Enter()");
+ Debug.Assert(MonitorEnterMethod != null, "Unable to find the method Monitor.Enter()");
// Retrieve the Monitor.Exit() method.
Type[] aParamTypes = new Type[1];
aParamTypes[0] = typeof(Object);
MethodInfo MonitorExitMethod = typeof(Monitor).GetMethod( "Exit", aParamTypes, null );
- Contract.Assert(MonitorExitMethod != null, "Unable to find the method Monitor.Exit()");
+ Debug.Assert(MonitorExitMethod != null, "Unable to find the method Monitor.Exit()");
// Define the Finalize method itself.
MethodBuilder Meth = OutputTypeBuilder.DefineMethod( "Finalize", MethodAttributes.Public | MethodAttributes.Virtual, null, null );
@@ -743,7 +744,7 @@ namespace System.Runtime.InteropServices.TCEAdapterGen {
{
// Retrieve the method info for GC.SuppressFinalize().
MethodInfo SuppressFinalizeMethod = typeof(GC).GetMethod("SuppressFinalize");
- Contract.Assert(SuppressFinalizeMethod != null, "Unable to find the GC.SuppressFinalize");
+ Debug.Assert(SuppressFinalizeMethod != null, "Unable to find the GC.SuppressFinalize");
// Define the Finalize method itself.
MethodBuilder Meth = OutputTypeBuilder.DefineMethod( "Dispose", MethodAttributes.Public | MethodAttributes.Virtual, null, null );
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventSinkHelperWriter.cs b/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventSinkHelperWriter.cs
index 0367e79bdd..862419cc98 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventSinkHelperWriter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/TCEAdapterGen/EventSinkHelperWriter.cs
@@ -8,6 +8,7 @@ namespace System.Runtime.InteropServices.TCEAdapterGen {
using System.Reflection;
using System.Reflection.Emit;
using System.Collections;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
internal class EventSinkHelperWriter
{
@@ -65,7 +66,7 @@ namespace System.Runtime.InteropServices.TCEAdapterGen {
// Retrieve the delegate type from the add_XXX method.
MethodInfo AddMeth = m_EventItfType.GetMethod( "add_" + aMethods[cMethods].Name );
ParameterInfo[] aParams = AddMeth.GetParameters();
- Contract.Assert(aParams.Length == 1, "All event interface methods must take a single delegate derived type and have a void return type");
+ Debug.Assert(aParams.Length == 1, "All event interface methods must take a single delegate derived type and have a void return type");
Type DelegateCls = aParams[0].ParameterType;
// Define the delegate instance field.
@@ -119,7 +120,7 @@ namespace System.Runtime.InteropServices.TCEAdapterGen {
{
// Retrieve the method info for the invoke method on the delegate.
MethodInfo DelegateInvokeMethod = DelegateCls.GetMethod( "Invoke" );
- Contract.Assert(DelegateInvokeMethod != null, "Unable to find method Delegate.Invoke()");
+ Debug.Assert(DelegateInvokeMethod != null, "Unable to find method Delegate.Invoke()");
// Retrieve the return type.
Type ReturnType = Method.ReturnType;
@@ -229,7 +230,7 @@ namespace System.Runtime.InteropServices.TCEAdapterGen {
if ( ReturnType == typeof(IntPtr) )
il.Emit( OpCodes.Ldc_I4_0 );
else
- Contract.Assert(false, "Unexpected type for Primitive type.");
+ Debug.Assert(false, "Unexpected type for Primitive type.");
break;
}
}
@@ -254,7 +255,7 @@ namespace System.Runtime.InteropServices.TCEAdapterGen {
{
// Retrieve the constructor info for the base classe's constructor.
ConstructorInfo DefaultBaseClsCons = typeof(Object).GetConstructor(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public, null, Array.Empty<Type>(), null );
- Contract.Assert(DefaultBaseClsCons != null, "Unable to find the constructor for class " + m_InputType.Name);
+ Debug.Assert(DefaultBaseClsCons != null, "Unable to find the constructor for class " + m_InputType.Name);
// Define the default constructor.
MethodBuilder Cons = OutputTypeBuilder.DefineMethod( ".ctor",
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/TypeLibConverter.cs b/src/mscorlib/src/System/Runtime/InteropServices/TypeLibConverter.cs
deleted file mode 100644
index e6b148a0a5..0000000000
--- a/src/mscorlib/src/System/Runtime/InteropServices/TypeLibConverter.cs
+++ /dev/null
@@ -1,595 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: Component that implements the ITypeLibConverter interface and
-** does the actual work of converting a typelib to metadata and
-** vice versa.
-**
-**
-=============================================================================*/
-#if !FEATURE_CORECLR // current implementation requires reflection only load
-namespace System.Runtime.InteropServices {
-
- using System;
- using System.Diagnostics.Contracts;
- using System.Collections;
- using System.Collections.Generic;
- using System.Threading;
- using System.Runtime.InteropServices.TCEAdapterGen;
- using System.IO;
- using System.Reflection;
- using System.Reflection.Emit;
- using System.Configuration.Assemblies;
- using Microsoft.Win32;
- using System.Runtime.CompilerServices;
- using System.Globalization;
- using System.Security;
- using System.Security.Permissions;
- using System.Runtime.InteropServices.ComTypes;
- using System.Runtime.Versioning;
- using WORD = System.UInt16;
- using DWORD = System.UInt32;
- using _TYPELIBATTR = System.Runtime.InteropServices.ComTypes.TYPELIBATTR;
-
- [Guid("F1C3BF79-C3E4-11d3-88E7-00902754C43A")]
- [ClassInterface(ClassInterfaceType.None)]
-[System.Runtime.InteropServices.ComVisible(true)]
- public sealed class TypeLibConverter : ITypeLibConverter
- {
- private const String s_strTypeLibAssemblyTitlePrefix = "TypeLib ";
- private const String s_strTypeLibAssemblyDescPrefix = "Assembly generated from typelib ";
- private const int MAX_NAMESPACE_LENGTH = 1024;
-
-
- //
- // ITypeLibConverter interface.
- //
-
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)]
- public AssemblyBuilder ConvertTypeLibToAssembly([MarshalAs(UnmanagedType.Interface)] Object typeLib,
- String asmFileName,
- int flags,
- ITypeLibImporterNotifySink notifySink,
- byte[] publicKey,
- StrongNameKeyPair keyPair,
- bool unsafeInterfaces)
- {
- return ConvertTypeLibToAssembly(typeLib,
- asmFileName,
- (unsafeInterfaces
- ? TypeLibImporterFlags.UnsafeInterfaces
- : 0),
- notifySink,
- publicKey,
- keyPair,
- null,
- null);
- }
-
-
-
-
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)]
- public AssemblyBuilder ConvertTypeLibToAssembly([MarshalAs(UnmanagedType.Interface)] Object typeLib,
- String asmFileName,
- TypeLibImporterFlags flags,
- ITypeLibImporterNotifySink notifySink,
- byte[] publicKey,
- StrongNameKeyPair keyPair,
- String asmNamespace,
- Version asmVersion)
- {
- // Validate the arguments.
- if (typeLib == null)
- throw new ArgumentNullException("typeLib");
- if (asmFileName == null)
- throw new ArgumentNullException("asmFileName");
- if (notifySink == null)
- throw new ArgumentNullException("notifySink");
- if (String.Empty.Equals(asmFileName))
- throw new ArgumentException(Environment.GetResourceString("Arg_InvalidFileName"), "asmFileName");
- if (asmFileName.Length > Path.MaxPath)
- throw new ArgumentException(Environment.GetResourceString("IO.PathTooLong"), asmFileName);
- if ((flags & TypeLibImporterFlags.PrimaryInteropAssembly) != 0 && publicKey == null && keyPair == null)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_PIAMustBeStrongNamed"));
- Contract.EndContractBlock();
-
- ArrayList eventItfInfoList = null;
-
- // Determine the AssemblyNameFlags
- AssemblyNameFlags asmNameFlags = AssemblyNameFlags.None;
-
- // Retrieve the assembly name from the typelib.
- AssemblyName asmName = GetAssemblyNameFromTypelib(typeLib, asmFileName, publicKey, keyPair, asmVersion, asmNameFlags);
-
- // Create the dynamic assembly that will contain the converted typelib types.
- AssemblyBuilder asmBldr = CreateAssemblyForTypeLib(typeLib, asmFileName, asmName,
- (flags & TypeLibImporterFlags.PrimaryInteropAssembly) != 0,
- (flags & TypeLibImporterFlags.ReflectionOnlyLoading) != 0,
- (flags & TypeLibImporterFlags.NoDefineVersionResource) != 0);
-
- // Define a dynamic module that will contain the contain the imported types.
- String strNonQualifiedAsmFileName = Path.GetFileName(asmFileName);
- ModuleBuilder modBldr = asmBldr.DefineDynamicModule(strNonQualifiedAsmFileName, strNonQualifiedAsmFileName);
-
- // If the namespace hasn't been specified, then use the assembly name.
- if (asmNamespace == null)
- asmNamespace = asmName.Name;
-
- // Create a type resolve handler that will also intercept resolve ref messages
- // on the sink interface to build up a list of referenced assemblies.
- TypeResolveHandler typeResolveHandler = new TypeResolveHandler(modBldr, notifySink);
-
- // Add a listener for the type resolve events.
- AppDomain currentDomain = Thread.GetDomain();
- ResolveEventHandler resolveHandler = new ResolveEventHandler(typeResolveHandler.ResolveEvent);
- ResolveEventHandler asmResolveHandler = new ResolveEventHandler(typeResolveHandler.ResolveAsmEvent);
- ResolveEventHandler ROAsmResolveHandler = new ResolveEventHandler(typeResolveHandler.ResolveROAsmEvent);
- currentDomain.TypeResolve += resolveHandler;
- currentDomain.AssemblyResolve += asmResolveHandler;
- currentDomain.ReflectionOnlyAssemblyResolve += ROAsmResolveHandler;
-
- // Convert the types contained in the typelib into metadata and add them to the assembly.
- nConvertTypeLibToMetadata(typeLib, asmBldr.InternalAssembly, modBldr.InternalModule, asmNamespace, flags, typeResolveHandler, out eventItfInfoList);
-
- // Update the COM types in the assembly.
- UpdateComTypesInAssembly(asmBldr, modBldr);
-
- // If there are any event sources then generate the TCE adapters.
- if (eventItfInfoList.Count > 0)
- new TCEAdapterGenerator().Process(modBldr, eventItfInfoList);
-
- // Remove the listener for the type resolve events.
- currentDomain.TypeResolve -= resolveHandler;
- currentDomain.AssemblyResolve -= asmResolveHandler;
- currentDomain.ReflectionOnlyAssemblyResolve -= ROAsmResolveHandler;
-
- // We have finished converting the typelib and now have a fully formed assembly.
- return asmBldr;
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)]
- [return : MarshalAs(UnmanagedType.Interface)]
- public Object ConvertAssemblyToTypeLib(Assembly assembly, String strTypeLibName, TypeLibExporterFlags flags, ITypeLibExporterNotifySink notifySink)
- {
- RuntimeAssembly rtAssembly;
- AssemblyBuilder ab = assembly as AssemblyBuilder;
- if (ab != null)
- rtAssembly = ab.InternalAssembly;
- else
- rtAssembly = assembly as RuntimeAssembly;
-
- return nConvertAssemblyToTypeLib(rtAssembly, strTypeLibName, flags, notifySink);
- }
-
- public bool GetPrimaryInteropAssembly(Guid g, Int32 major, Int32 minor, Int32 lcid, out String asmName, out String asmCodeBase)
- {
- String strTlbId = "{" + g.ToString().ToUpper(CultureInfo.InvariantCulture) + "}";
- String strVersion = major.ToString("x", CultureInfo.InvariantCulture) + "." + minor.ToString("x", CultureInfo.InvariantCulture);
-
- // Set the two out values to null before we start.
- asmName = null;
- asmCodeBase = null;
-
- // Try to open the HKEY_CLASS_ROOT\TypeLib key.
- using (RegistryKey TypeLibKey = Registry.ClassesRoot.OpenSubKey("TypeLib", false))
- {
- if (TypeLibKey != null)
- {
- // Try to open the HKEY_CLASS_ROOT\TypeLib\<TLBID> key.
- using (RegistryKey TypeLibSubKey = TypeLibKey.OpenSubKey(strTlbId))
- {
- if (TypeLibSubKey != null)
- {
- // Try to open the HKEY_CLASS_ROOT\TypeLib\<TLBID>\<Major.Minor> key.
- using (RegistryKey VersionKey = TypeLibSubKey.OpenSubKey(strVersion, false))
- {
- if (VersionKey != null)
- {
- // Attempt to retrieve the assembly name and codebase under the version key.
- asmName = (String)VersionKey.GetValue("PrimaryInteropAssemblyName");
- asmCodeBase = (String)VersionKey.GetValue("PrimaryInteropAssemblyCodeBase");
- }
- }
- }
- }
- }
- }
-
- // If the assembly name isn't null, then we found an PIA.
- return asmName != null;
- }
-
-
- //
- // Non native helper methods.
- //
-
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- private static AssemblyBuilder CreateAssemblyForTypeLib(Object typeLib, String asmFileName, AssemblyName asmName, bool bPrimaryInteropAssembly, bool bReflectionOnly, bool bNoDefineVersionResource)
- {
- // Retrieve the current app domain.
- AppDomain currentDomain = Thread.GetDomain();
-
- // Retrieve the directory from the assembly file name.
- String dir = null;
- if (asmFileName != null)
- {
- dir = Path.GetDirectoryName(asmFileName);
- if (String.IsNullOrEmpty(dir))
- dir = null;
- }
-
- AssemblyBuilderAccess aba;
- if (bReflectionOnly)
- {
- aba = AssemblyBuilderAccess.ReflectionOnly;
- }
- else
- {
- aba = AssemblyBuilderAccess.RunAndSave;
- }
-
- // Create the dynamic assembly itself.
- AssemblyBuilder asmBldr;
-
- List<CustomAttributeBuilder> assemblyAttributes = new List<CustomAttributeBuilder>();
-#if !FEATURE_CORECLR
- // mscorlib.dll must specify the security rules that assemblies it emits are to use, since by
- // default all assemblies will follow security rule set level 2, and we want to make that an
- // explicit decision.
- ConstructorInfo securityRulesCtor = typeof(SecurityRulesAttribute).GetConstructor(new Type[] { typeof(SecurityRuleSet) });
- CustomAttributeBuilder securityRulesAttribute =
- new CustomAttributeBuilder(securityRulesCtor, new object[] { SecurityRuleSet.Level2 });
- assemblyAttributes.Add(securityRulesAttribute);
-#endif // !FEATURE_CORECLR
-
- asmBldr = currentDomain.DefineDynamicAssembly(asmName, aba, dir, false, assemblyAttributes);
-
- // Set the Guid custom attribute on the assembly.
- SetGuidAttributeOnAssembly(asmBldr, typeLib);
-
- // Set the imported from COM attribute on the assembly and return it.
- SetImportedFromTypeLibAttrOnAssembly(asmBldr, typeLib);
-
- // Set the version information on the typelib.
- if (bNoDefineVersionResource)
- {
- SetTypeLibVersionAttribute(asmBldr, typeLib);
- }
- else
- {
- SetVersionInformation(asmBldr, typeLib, asmName);
- }
-
- // If we are generating a PIA, then set the PIA custom attribute.
- if (bPrimaryInteropAssembly)
- SetPIAAttributeOnAssembly(asmBldr, typeLib);
-
- return asmBldr;
- }
-
- [System.Security.SecurityCritical] // auto-generated
- internal static AssemblyName GetAssemblyNameFromTypelib(Object typeLib, String asmFileName, byte[] publicKey, StrongNameKeyPair keyPair, Version asmVersion, AssemblyNameFlags asmNameFlags)
- {
- // Extract the name of the typelib.
- String strTypeLibName = null;
- String strDocString = null;
- int dwHelpContext = 0;
- String strHelpFile = null;
- ITypeLib pTLB = (ITypeLib)typeLib;
- pTLB.GetDocumentation(-1, out strTypeLibName, out strDocString, out dwHelpContext, out strHelpFile);
-
- // Retrieve the name to use for the assembly.
- if (asmFileName == null)
- {
- asmFileName = strTypeLibName;
- }
- else
- {
- Contract.Assert((asmFileName != null) && (asmFileName.Length > 0), "The assembly file name cannot be an empty string!");
-
- String strFileNameNoPath = Path.GetFileName(asmFileName);
- String strExtension = Path.GetExtension(asmFileName);
-
- // Validate that the extension is valid.
- bool bExtensionValid = ".dll".Equals(strExtension, StringComparison.OrdinalIgnoreCase);
-
- // If the extension is not valid then tell the user and quit.
- if (!bExtensionValid)
- throw new ArgumentException(Environment.GetResourceString("Arg_InvalidFileExtension"));
-
- // The assembly cannot contain the path nor the extension.
- asmFileName = strFileNameNoPath.Substring(0, strFileNameNoPath.Length - ".dll".Length);
- }
-
- // If the version information was not specified, then retrieve it from the typelib.
- if (asmVersion == null)
- {
- int major;
- int minor;
- Marshal.GetTypeLibVersion(pTLB, out major, out minor);
- asmVersion = new Version(major, minor, 0, 0);
- }
-
- // Create the assembly name for the imported typelib's assembly.
- AssemblyName AsmName = new AssemblyName();
- AsmName.Init(
- asmFileName,
- publicKey,
- null,
- asmVersion,
- null,
- AssemblyHashAlgorithm.None,
- AssemblyVersionCompatibility.SameMachine,
- null,
- asmNameFlags,
- keyPair);
-
- return AsmName;
- }
-
- private static void UpdateComTypesInAssembly(AssemblyBuilder asmBldr, ModuleBuilder modBldr)
- {
- // Retrieve the AssemblyBuilderData associated with the assembly builder.
- AssemblyBuilderData AsmBldrData = asmBldr.m_assemblyData;
-
- // Go through the types in the module and add them as public COM types.
- Type[] aTypes = modBldr.GetTypes();
- int NumTypes = aTypes.Length;
- for (int cTypes = 0; cTypes < NumTypes; cTypes++)
- AsmBldrData.AddPublicComType(aTypes[cTypes]);
- }
-
-
- [System.Security.SecurityCritical] // auto-generated
- private static void SetGuidAttributeOnAssembly(AssemblyBuilder asmBldr, Object typeLib)
- {
- // Retrieve the GuidAttribute constructor.
- Type []aConsParams = new Type[1] {typeof(String)};
- ConstructorInfo GuidAttrCons = typeof(GuidAttribute).GetConstructor(aConsParams);
-
- // Create an instance of the custom attribute builder.
- Object[] aArgs = new Object[1] {Marshal.GetTypeLibGuid((ITypeLib)typeLib).ToString()};
- CustomAttributeBuilder GuidCABuilder = new CustomAttributeBuilder(GuidAttrCons, aArgs);
-
- // Set the GuidAttribute on the assembly builder.
- asmBldr.SetCustomAttribute(GuidCABuilder);
- }
-
- [System.Security.SecurityCritical] // auto-generated
- private static void SetImportedFromTypeLibAttrOnAssembly(AssemblyBuilder asmBldr, Object typeLib)
- {
- // Retrieve the ImportedFromTypeLibAttribute constructor.
- Type []aConsParams = new Type[1] {typeof(String)};
- ConstructorInfo ImpFromComAttrCons = typeof(ImportedFromTypeLibAttribute).GetConstructor(aConsParams);
-
- // Retrieve the name of the typelib.
- String strTypeLibName = Marshal.GetTypeLibName((ITypeLib)typeLib);
-
- // Create an instance of the custom attribute builder.
- Object[] aArgs = new Object[1] {strTypeLibName};
- CustomAttributeBuilder ImpFromComCABuilder = new CustomAttributeBuilder(ImpFromComAttrCons, aArgs);
-
- // Set the ImportedFromTypeLibAttribute on the assembly builder.
- asmBldr.SetCustomAttribute(ImpFromComCABuilder);
- }
-
- [System.Security.SecurityCritical] // auto-generated
- private static void SetTypeLibVersionAttribute(AssemblyBuilder asmBldr, Object typeLib)
- {
- Type []aConsParams = new Type[2] {typeof(int), typeof(int)};
- ConstructorInfo TypeLibVerCons = typeof(TypeLibVersionAttribute).GetConstructor(aConsParams);
-
- // Get the typelib version
- int major;
- int minor;
- Marshal.GetTypeLibVersion((ITypeLib)typeLib, out major, out minor);
-
- // Create an instance of the custom attribute builder.
- Object[] aArgs = new Object[2] {major, minor};
- CustomAttributeBuilder TypeLibVerBuilder = new CustomAttributeBuilder(TypeLibVerCons, aArgs);
-
- // Set the attribute on the assembly builder.
- asmBldr.SetCustomAttribute(TypeLibVerBuilder);
- }
-
- [System.Security.SecurityCritical] // auto-generated
- private static void SetVersionInformation(AssemblyBuilder asmBldr, Object typeLib, AssemblyName asmName)
- {
- // Extract the name of the typelib.
- String strTypeLibName = null;
- String strDocString = null;
- int dwHelpContext = 0;
- String strHelpFile = null;
- ITypeLib pTLB = (ITypeLib)typeLib;
- pTLB.GetDocumentation(-1, out strTypeLibName, out strDocString, out dwHelpContext, out strHelpFile);
-
- // Generate the product name string from the named of the typelib.
- String strProductName = String.Format(CultureInfo.InvariantCulture, Environment.GetResourceString("TypeLibConverter_ImportedTypeLibProductName"), strTypeLibName);
-
- // Set the OS version information.
- asmBldr.DefineVersionInfoResource(strProductName, asmName.Version.ToString(), null, null, null);
-
- // Set the TypeLibVersion attribute
- SetTypeLibVersionAttribute(asmBldr, typeLib);
- }
-
- [System.Security.SecurityCritical] // auto-generated
- private static void SetPIAAttributeOnAssembly(AssemblyBuilder asmBldr, Object typeLib)
- {
- IntPtr pAttr = IntPtr.Zero;
- _TYPELIBATTR Attr;
- ITypeLib pTLB = (ITypeLib)typeLib;
- int Major = 0;
- int Minor = 0;
-
- // Retrieve the PrimaryInteropAssemblyAttribute constructor.
- Type []aConsParams = new Type[2] {typeof(int), typeof(int)};
- ConstructorInfo PIAAttrCons = typeof(PrimaryInteropAssemblyAttribute).GetConstructor(aConsParams);
-
- // Retrieve the major and minor version from the typelib.
- try
- {
- pTLB.GetLibAttr(out pAttr);
- Attr = (_TYPELIBATTR)Marshal.PtrToStructure(pAttr, typeof(_TYPELIBATTR));
- Major = Attr.wMajorVerNum;
- Minor = Attr.wMinorVerNum;
- }
- finally
- {
- // Release the typelib attributes.
- if (pAttr != IntPtr.Zero)
- pTLB.ReleaseTLibAttr(pAttr);
- }
-
- // Create an instance of the custom attribute builder.
- Object[] aArgs = new Object[2] {Major, Minor};
- CustomAttributeBuilder PIACABuilder = new CustomAttributeBuilder(PIAAttrCons, aArgs);
-
- // Set the PrimaryInteropAssemblyAttribute on the assembly builder.
- asmBldr.SetCustomAttribute(PIACABuilder);
- }
-
-
- //
- // Native helper methods.
- //
-
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern void nConvertTypeLibToMetadata(Object typeLib, RuntimeAssembly asmBldr, RuntimeModule modBldr, String nameSpace, TypeLibImporterFlags flags, ITypeLibImporterNotifySink notifySink, out ArrayList eventItfInfoList);
-
- // Must use assembly versioning or GuidAttribute to avoid collisions in typelib export or registration.
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern Object nConvertAssemblyToTypeLib(RuntimeAssembly assembly, String strTypeLibName, TypeLibExporterFlags flags, ITypeLibExporterNotifySink notifySink);
-
- [System.Security.SecurityCritical] // auto-generated
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
- internal extern static void LoadInMemoryTypeByName(RuntimeModule module, String className);
-
- //
- // Helper class called when a resolve type event is fired.
- //
-
- private class TypeResolveHandler : ITypeLibImporterNotifySink
- {
- public TypeResolveHandler(ModuleBuilder mod, ITypeLibImporterNotifySink userSink)
- {
- m_Module = mod;
- m_UserSink = userSink;
- }
-
- public void ReportEvent(ImporterEventKind eventKind, int eventCode, String eventMsg)
- {
- m_UserSink.ReportEvent(eventKind, eventCode, eventMsg);
- }
-
- public Assembly ResolveRef(Object typeLib)
- {
- Contract.Ensures(Contract.Result<Assembly>() != null && Contract.Result<Assembly>() is RuntimeAssembly);
- Contract.EndContractBlock();
-
- // Call the user sink to resolve the reference.
- Assembly asm = m_UserSink.ResolveRef(typeLib);
-
- if (asm == null)
- throw new ArgumentNullException();
-
- // Return the resolved assembly. We extract the internal assembly because we are called
- // by the VM which accesses fields of the object directly and does not go via those
- // delegating properties (the fields are empty if asm is an (external) AssemblyBuilder).
-
- RuntimeAssembly rtAssembly = asm as RuntimeAssembly;
- if (rtAssembly == null)
- {
- AssemblyBuilder ab = asm as AssemblyBuilder;
- if (ab != null)
- rtAssembly = ab.InternalAssembly;
- }
-
- if (rtAssembly == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeAssembly"));
-
- // Add the assembly to the list of assemblies.
- m_AsmList.Add(rtAssembly);
-
- return rtAssembly;
- }
-
- [System.Security.SecurityCritical] // auto-generated
- public Assembly ResolveEvent(Object sender, ResolveEventArgs args)
- {
- // We need to load the type in the resolve event so that we will deal with
- // cases where we are trying to load the CoClass before the interface has
- // been loaded.
- try
- {
- LoadInMemoryTypeByName(m_Module.GetNativeHandle(), args.Name);
- return m_Module.Assembly;
- }
- catch (TypeLoadException e)
- {
- if (e.ResourceId != System.__HResults.COR_E_TYPELOAD) // type not found
- throw;
- }
-
- foreach (RuntimeAssembly asm in m_AsmList)
- {
- try
- {
- asm.GetType(args.Name, true, false);
- return asm;
- }
- catch (TypeLoadException e)
- {
- if (e._HResult != System.__HResults.COR_E_TYPELOAD) // type not found
- throw;
- }
- }
-
- return null;
- }
-
- public Assembly ResolveAsmEvent(Object sender, ResolveEventArgs args)
- {
- foreach (RuntimeAssembly asm in m_AsmList)
- {
- if (String.Compare(asm.FullName, args.Name, StringComparison.OrdinalIgnoreCase) == 0)
- return asm;
- }
-
- return null;
- }
-
- public Assembly ResolveROAsmEvent(Object sender, ResolveEventArgs args)
- {
- foreach (RuntimeAssembly asm in m_AsmList)
- {
- if (String.Compare(asm.FullName, args.Name, StringComparison.OrdinalIgnoreCase) == 0)
- return asm;
- }
-
- // We failed to find the referenced assembly in our pre-loaded assemblies, so try to load it based on policy.
- string asmName = AppDomain.CurrentDomain.ApplyPolicy(args.Name);
- return Assembly.ReflectionOnlyLoad(asmName);
- }
-
- private ModuleBuilder m_Module;
- private ITypeLibImporterNotifySink m_UserSink;
- private List<RuntimeAssembly> m_AsmList = new List<RuntimeAssembly>();
- }
- }
-}
-#endif // !FEATURE_CORECLR // current implementation requires reflection only load
-
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/Variant.cs b/src/mscorlib/src/System/Runtime/InteropServices/Variant.cs
index 9be1588ac0..c7bbb78ae6 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/Variant.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/Variant.cs
@@ -11,7 +11,6 @@ namespace System.Runtime.InteropServices {
/// to and from COM calls.
/// </summary>
[StructLayout(LayoutKind.Explicit)]
- [System.Security.SecurityCritical]
internal struct Variant {
#if DEBUG
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/BindableVectorToCollectionAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/BindableVectorToCollectionAdapter.cs
index 5574f3c251..e3c6a926d3 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/BindableVectorToCollectionAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/BindableVectorToCollectionAdapter.cs
@@ -9,6 +9,7 @@ using System.Runtime;
using System.Security;
using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
@@ -27,12 +28,11 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
private BindableVectorToCollectionAdapter()
{
- Contract.Assert(false, "This class is never instantiated");
+ Debug.Assert(false, "This class is never instantiated");
}
// int Count { get }
[Pure]
- [SecurityCritical]
internal int Count()
{
IBindableVector _this = JitHelpers.UnsafeCast<IBindableVector>(this);
@@ -47,7 +47,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// bool IsSynchronized { get }
[Pure]
- [SecurityCritical]
internal bool IsSynchronized()
{
return false;
@@ -55,7 +54,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// object SyncRoot { get }
[Pure]
- [SecurityCritical]
internal object SyncRoot()
{
return this;
@@ -63,11 +61,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// void CopyTo(Array array, int index)
[Pure]
- [SecurityCritical]
internal void CopyTo(Array array, int arrayIndex)
{
if (array == null)
- throw new ArgumentNullException("array");
+ throw new ArgumentNullException(nameof(array));
// ICollection expects the destination array to be single-dimensional.
if (array.Rank != 1)
@@ -79,7 +76,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
int destLen = array.GetLength(0);
if (arrayIndex < destLB)
- throw new ArgumentOutOfRangeException("arrayIndex");
+ throw new ArgumentOutOfRangeException(nameof(arrayIndex));
// Does the dimension in question have sufficient space to copy the expected number of entries?
// We perform this check before valid index check to ensure the exception message is in sync with
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/BindableVectorToListAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/BindableVectorToListAdapter.cs
index 73ebf721ee..d6e50f5164 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/BindableVectorToListAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/BindableVectorToListAdapter.cs
@@ -9,6 +9,7 @@ using System.Runtime;
using System.Security;
using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
@@ -27,33 +28,30 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
private BindableVectorToListAdapter()
{
- Contract.Assert(false, "This class is never instantiated");
+ Debug.Assert(false, "This class is never instantiated");
}
// object this[int index] { get }
- [SecurityCritical]
internal object Indexer_Get(int index)
{
if (index < 0)
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
IBindableVector _this = JitHelpers.UnsafeCast<IBindableVector>(this);
return GetAt(_this, (uint)index);
}
// object this[int index] { set }
- [SecurityCritical]
internal void Indexer_Set(int index, object value)
{
if (index < 0)
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
IBindableVector _this = JitHelpers.UnsafeCast<IBindableVector>(this);
SetAt(_this, (uint)index, value);
}
// int Add(object value)
- [SecurityCritical]
internal int Add(object value)
{
IBindableVector _this = JitHelpers.UnsafeCast<IBindableVector>(this);
@@ -69,7 +67,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// bool Contains(object item)
- [SecurityCritical]
internal bool Contains(object item)
{
IBindableVector _this = JitHelpers.UnsafeCast<IBindableVector>(this);
@@ -79,7 +76,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// void Clear()
- [SecurityCritical]
internal void Clear()
{
IBindableVector _this = JitHelpers.UnsafeCast<IBindableVector>(this);
@@ -88,7 +84,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// bool IsFixedSize { get }
[Pure]
- [SecurityCritical]
internal bool IsFixedSize()
{
return false;
@@ -96,14 +91,12 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// bool IsReadOnly { get }
[Pure]
- [SecurityCritical]
internal bool IsReadOnly()
{
return false;
}
// int IndexOf(object item)
- [SecurityCritical]
internal int IndexOf(object item)
{
IBindableVector _this = JitHelpers.UnsafeCast<IBindableVector>(this);
@@ -123,18 +116,16 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// void Insert(int index, object item)
- [SecurityCritical]
internal void Insert(int index, object item)
{
if (index < 0)
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
IBindableVector _this = JitHelpers.UnsafeCast<IBindableVector>(this);
InsertAtHelper(_this, (uint)index, item);
}
// bool Remove(object item)
- [SecurityCritical]
internal void Remove(object item)
{
IBindableVector _this = JitHelpers.UnsafeCast<IBindableVector>(this);
@@ -154,11 +145,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// void RemoveAt(int index)
- [SecurityCritical]
internal void RemoveAt(int index)
{
if (index < 0)
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
IBindableVector _this = JitHelpers.UnsafeCast<IBindableVector>(this);
RemoveAtHelper(_this, (uint)index);
@@ -178,7 +168,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
catch (Exception ex)
{
if (__HResults.E_BOUNDS == ex._HResult)
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
throw;
}
@@ -196,7 +186,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
catch (Exception ex)
{
if (__HResults.E_BOUNDS == ex._HResult)
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
throw;
}
@@ -214,7 +204,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
catch (Exception ex)
{
if (__HResults.E_BOUNDS == ex._HResult)
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
throw;
}
@@ -232,7 +222,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
catch (Exception ex)
{
if (__HResults.E_BOUNDS == ex._HResult)
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
throw;
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIPropertyValueImpl.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIPropertyValueImpl.cs
index c88f13dd0b..702e0c9e52 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIPropertyValueImpl.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIPropertyValueImpl.cs
@@ -184,7 +184,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
[Pure]
- [SecuritySafeCritical]
public Point GetPoint()
{
if (this.Type != PropertyType.Point)
@@ -195,7 +194,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
[Pure]
- [SecuritySafeCritical]
public Size GetSize()
{
if (this.Type != PropertyType.Size)
@@ -206,7 +204,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
[Pure]
- [SecuritySafeCritical]
public Rect GetRect()
{
if (this.Type != PropertyType.Rect)
@@ -328,7 +325,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
[Pure]
- [SecuritySafeCritical]
public Point[] GetPointArray()
{
if (this.Type != PropertyType.PointArray)
@@ -339,7 +335,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
[Pure]
- [SecuritySafeCritical]
public Size[] GetSizeArray()
{
if (this.Type != PropertyType.SizeArray)
@@ -351,7 +346,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
[Pure]
- [SecuritySafeCritical]
public Rect[] GetRectArray()
{
if (this.Type != PropertyType.RectArray)
@@ -505,7 +499,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// Unbox the data stored in the property value to a structurally equivilent type
[Pure]
- [SecurityCritical]
private unsafe T Unbox<T>(Type expectedBoxedType) where T : struct {
Contract.Requires(expectedBoxedType != null);
Contract.Requires(Marshal.SizeOf(expectedBoxedType) == Marshal.SizeOf(typeof(T)));
@@ -526,7 +519,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// Convert the array stored in the property value to a structurally equivilent array type
[Pure]
- [SecurityCritical]
private unsafe T[] UnboxArray<T>(Type expectedArrayElementType) where T : struct {
Contract.Requires(expectedArrayElementType != null);
Contract.Requires(Marshal.SizeOf(expectedArrayElementType) == Marshal.SizeOf(typeof(T)));
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIReferenceImpl.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIReferenceImpl.cs
index e379d38cf3..9705b61148 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIReferenceImpl.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIReferenceImpl.cs
@@ -6,6 +6,7 @@
using System;
using System.Collections;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Reflection;
using System.Security;
@@ -55,7 +56,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
Contract.Requires(wrapper != null);
IReference<T> reference = (IReference<T>) wrapper;
- Contract.Assert(reference != null, "CLRIReferenceImpl::UnboxHelper - QI'ed for IReference<"+typeof(T)+">, but that failed.");
+ Debug.Assert(reference != null, "CLRIReferenceImpl::UnboxHelper - QI'ed for IReference<"+typeof(T)+">, but that failed.");
return reference.Value;
}
}
@@ -216,7 +217,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
Contract.Requires(wrapper != null);
IReferenceArray<T> reference = (IReferenceArray<T>)wrapper;
- Contract.Assert(reference != null, "CLRIReferenceArrayImpl::UnboxHelper - QI'ed for IReferenceArray<" + typeof(T) + ">, but that failed.");
+ Debug.Assert(reference != null, "CLRIReferenceArrayImpl::UnboxHelper - QI'ed for IReferenceArray<" + typeof(T) + ">, but that failed.");
T[] marshaled = reference.Value;
return marshaled;
}
@@ -229,7 +230,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
internal static readonly Type s_rectType = Type.GetType("Windows.Foundation.Rect, " + AssemblyRef.SystemRuntimeWindowsRuntime);
internal static readonly Type s_sizeType = Type.GetType("Windows.Foundation.Size, " + AssemblyRef.SystemRuntimeWindowsRuntime);
- [SecuritySafeCritical]
internal static Object CreateIReference(Object obj)
{
Contract.Requires(obj != null, "Null should not be boxed.");
@@ -302,11 +302,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
return Activator.CreateInstance(specificType, new Object[] { propType.Value, obj });
}
- Contract.Assert(false, "We should not see non-WinRT type here");
+ Debug.Assert(false, "We should not see non-WinRT type here");
return null;
}
- [SecuritySafeCritical]
internal static Object CreateIReferenceArray(Array obj)
{
Contract.Requires(obj != null);
@@ -315,7 +314,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
Type type = obj.GetType().GetElementType();
- Contract.Assert(obj.Rank == 1 && obj.GetLowerBound(0) == 0 && !type.IsArray);
+ Debug.Assert(obj.Rank == 1 && obj.GetLowerBound(0) == 0 && !type.IsArray);
if (type == typeof(int))
return new CLRIReferenceArrayImpl<int>(PropertyType.Int32Array, (int[])obj);
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ConstantSplittableMap.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ConstantSplittableMap.cs
index af1381c366..a5abb4f23e 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ConstantSplittableMap.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ConstantSplittableMap.cs
@@ -45,7 +45,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
internal ConstantSplittableMap(IReadOnlyDictionary<TKey, TValue> data)
{
if (data == null)
- throw new ArgumentNullException("data");
+ throw new ArgumentNullException(nameof(data));
Contract.EndContractBlock();
this.firstItemIndex = 0;
@@ -56,7 +56,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
internal ConstantSplittableMap(IMapView<TKey, TValue> data)
{
if (data == null)
- throw new ArgumentNullException("data");
+ throw new ArgumentNullException(nameof(data));
if (((UInt32)Int32.MaxValue) < data.Size)
{
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CustomPropertyImpl.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CustomPropertyImpl.cs
index 04fe1bf9b2..d575201bb9 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CustomPropertyImpl.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CustomPropertyImpl.cs
@@ -7,6 +7,7 @@
using System;
using System.Security;
using System.Reflection;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
@@ -29,7 +30,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public CustomPropertyImpl(PropertyInfo propertyInfo)
{
if (propertyInfo == null)
- throw new ArgumentNullException("propertyInfo");
+ throw new ArgumentNullException(nameof(propertyInfo));
m_property = propertyInfo;
}
@@ -88,7 +89,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
InvokeInternal(target, new object[] { indexValue, value }, false);
}
- [SecuritySafeCritical]
private object InvokeInternal(object target, object[] args, bool getValue)
{
// Forward to the right object if we are dealing with a proxy
@@ -123,7 +123,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// 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.
- Contract.Assert(AppDomain.CurrentDomain.PermissionSet.IsUnrestricted());
+ Debug.Assert(AppDomain.CurrentDomain.PermissionSet.IsUnrestricted());
return rtMethod.UnsafeInvoke(target, BindingFlags.Default, null, args, null);
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryKeyCollection.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryKeyCollection.cs
index c1586ee9ce..c33e002e0e 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryKeyCollection.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryKeyCollection.cs
@@ -18,7 +18,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public DictionaryKeyCollection(IDictionary<TKey, TValue> dictionary)
{
if (dictionary == null)
- throw new ArgumentNullException("dictionary");
+ throw new ArgumentNullException(nameof(dictionary));
this.dictionary = dictionary;
}
@@ -26,9 +26,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public void CopyTo(TKey[] array, int index)
{
if (array == null)
- throw new ArgumentNullException("array");
+ throw new ArgumentNullException(nameof(array));
if (index < 0)
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
if (array.Length <= index && this.Count > 0)
throw new ArgumentException(Environment.GetResourceString("Arg_IndexOutOfRangeException"));
if (array.Length - index < dictionary.Count)
@@ -90,7 +90,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public DictionaryKeyEnumerator(IDictionary<TKey, TValue> dictionary)
{
if (dictionary == null)
- throw new ArgumentNullException("dictionary");
+ throw new ArgumentNullException(nameof(dictionary));
this.dictionary = dictionary;
this.enumeration = dictionary.GetEnumerator();
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryToMapAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryToMapAdapter.cs
index fa021b7f3d..24e5777768 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryToMapAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryToMapAdapter.cs
@@ -10,6 +10,7 @@ using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
@@ -28,11 +29,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
private DictionaryToMapAdapter()
{
- Contract.Assert(false, "This class is never instantiated");
+ Debug.Assert(false, "This class is never instantiated");
}
// V Lookup(K key)
- [SecurityCritical]
internal V Lookup<K, V>(K key)
{
IDictionary<K, V> _this = JitHelpers.UnsafeCast<IDictionary<K, V>>(this);
@@ -50,7 +50,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// uint Size { get }
- [SecurityCritical]
internal uint Size<K, V>()
{
IDictionary<K, V> _this = JitHelpers.UnsafeCast<IDictionary<K, V>>(this);
@@ -58,7 +57,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// bool HasKey(K key)
- [SecurityCritical]
internal bool HasKey<K, V>(K key)
{
IDictionary<K, V> _this = JitHelpers.UnsafeCast<IDictionary<K, V>>(this);
@@ -66,11 +64,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// IMapView<K, V> GetView()
- [SecurityCritical]
internal IReadOnlyDictionary<K, V> GetView<K, V>()
{
IDictionary<K, V> _this = JitHelpers.UnsafeCast<IDictionary<K, V>>(this);
- Contract.Assert(_this != null);
+ Debug.Assert(_this != null);
// Note: This dictionary is not really read-only - you could QI for a modifiable
// dictionary. We gain some perf by doing this. We believe this is acceptable.
@@ -83,7 +80,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// bool Insert(K key, V value)
- [SecurityCritical]
internal bool Insert<K, V>(K key, V value)
{
IDictionary<K, V> _this = JitHelpers.UnsafeCast<IDictionary<K, V>>(this);
@@ -93,7 +89,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// void Remove(K key)
- [SecurityCritical]
internal void Remove<K, V>(K key)
{
IDictionary<K, V> _this = JitHelpers.UnsafeCast<IDictionary<K, V>>(this);
@@ -108,7 +103,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// void Clear()
- [SecurityCritical]
internal void Clear<K, V>()
{
IDictionary<K, V> _this = JitHelpers.UnsafeCast<IDictionary<K, V>>(this);
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryValueCollection.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryValueCollection.cs
index 03e897a917..fcc7755d67 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryValueCollection.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryValueCollection.cs
@@ -21,7 +21,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime {
public DictionaryValueCollection(IDictionary<TKey, TValue> dictionary)
{
if (dictionary == null)
- throw new ArgumentNullException("dictionary");
+ throw new ArgumentNullException(nameof(dictionary));
this.dictionary = dictionary;
}
@@ -29,9 +29,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime {
public void CopyTo(TValue[] array, int index)
{
if (array == null)
- throw new ArgumentNullException("array");
+ throw new ArgumentNullException(nameof(array));
if (index < 0)
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
if (array.Length <= index && this.Count > 0)
throw new ArgumentException(Environment.GetResourceString("Arg_IndexOutOfRangeException"));
if (array.Length - index < dictionary.Count)
@@ -97,7 +97,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime {
public DictionaryValueEnumerator(IDictionary<TKey, TValue> dictionary)
{
if (dictionary == null)
- throw new ArgumentNullException("dictionary");
+ throw new ArgumentNullException(nameof(dictionary));
this.dictionary = dictionary;
this.enumeration = dictionary.GetEnumerator();
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/EnumeratorToIteratorAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/EnumeratorToIteratorAdapter.cs
index 7329d31ae8..3f9d516162 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/EnumeratorToIteratorAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/EnumeratorToIteratorAdapter.cs
@@ -7,6 +7,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
@@ -25,11 +26,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
private EnumerableToIterableAdapter()
{
- Contract.Assert(false, "This class is never instantiated");
+ Debug.Assert(false, "This class is never instantiated");
}
// This method is invoked when First is called on a managed implementation of IIterable<T>.
- [System.Security.SecurityCritical]
internal IIterator<T> First_Stub<T>()
{
IEnumerable<T> _this = JitHelpers.UnsafeCast<IEnumerable<T>>(this);
@@ -41,7 +41,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
private EnumerableToBindableIterableAdapter()
{
- Contract.Assert(false, "This class is never instantiated");
+ Debug.Assert(false, "This class is never instantiated");
}
internal sealed class NonGenericToGenericEnumerator : IEnumerator<object>
@@ -58,7 +58,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// This method is invoked when First is called on a managed implementation of IBindableIterable.
- [System.Security.SecurityCritical]
internal IBindableIterator First_Stub()
{
IEnumerable _this = JitHelpers.UnsafeCast<IEnumerable>(this);
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IClosable.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IClosable.cs
index 847147ade8..4c6169a4e8 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IClosable.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IClosable.cs
@@ -7,6 +7,7 @@
using System;
using System.Security;
using System.Collections;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
@@ -27,10 +28,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
private IDisposableToIClosableAdapter()
{
- Contract.Assert(false, "This class is never instantiated");
+ Debug.Assert(false, "This class is never instantiated");
}
- [SecurityCritical]
public void Close()
{
IDisposable _this = JitHelpers.UnsafeCast<IDisposable>(this);
@@ -39,15 +39,13 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// Adapter class which converts IDisposable.Dispose calls into IClosable.Close
- [SecurityCritical]
internal sealed class IClosableToIDisposableAdapter
{
private IClosableToIDisposableAdapter()
{
- Contract.Assert(false, "This class is never instantiated");
+ Debug.Assert(false, "This class is never instantiated");
}
- [SecurityCritical]
private void Dispose()
{
IClosable _this = JitHelpers.UnsafeCast<IClosable>(this);
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ICustomPropertyProvider.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ICustomPropertyProvider.cs
index 143a33e4c7..3bbde35a3c 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ICustomPropertyProvider.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ICustomPropertyProvider.cs
@@ -50,7 +50,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// Creates a ICustomProperty implementation for Jupiter
// Called from ICustomPropertyProvider_GetIndexedProperty from within runtime
//
- [System.Security.SecurityCritical]
static internal unsafe ICustomProperty CreateIndexedProperty(object target, string propertyName, TypeNameNative *pIndexedParamType)
{
Contract.Requires(target != null);
@@ -87,7 +86,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
return new CustomPropertyImpl(propertyInfo);
}
- [System.Security.SecurityCritical]
static internal unsafe void GetType(object target, TypeNameNative *pIndexedParamType)
{
IGetProxyTarget proxy = target as IGetProxyTarget;
@@ -207,7 +205,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
//
// ICustomQueryInterface methods
//
- [System.Security.SecurityCritical]
public CustomQueryInterfaceResult GetInterface([In]ref Guid iid, out IntPtr ppv)
{
ppv = IntPtr.Zero;
@@ -441,7 +438,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
}
- [SecuritySafeCritical]
private IBindableVector GetIBindableVectorNoThrow()
{
if ((_flags & InterfaceForwardingSupport.IBindableVector) != 0)
@@ -450,7 +446,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
return null;
}
- [SecuritySafeCritical]
private IVector_Raw<T1> GetVectorOfT()
{
if ((_flags & InterfaceForwardingSupport.IVector) != 0)
@@ -517,7 +512,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public bool MoveNext() { return _iterator.MoveNext(); }
}
- [SecuritySafeCritical]
private IBindableVectorView GetIBindableVectorViewNoThrow()
{
if ((_flags & InterfaceForwardingSupport.IBindableVectorView) != 0)
@@ -526,7 +520,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
return null;
}
- [SecuritySafeCritical]
private IVectorView<T2> GetVectorViewOfT()
{
if ((_flags & InterfaceForwardingSupport.IVectorView) != 0)
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IMapViewToIReadOnlyDictionaryAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IMapViewToIReadOnlyDictionaryAdapter.cs
index 3600a3ae70..a7424da3fb 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IMapViewToIReadOnlyDictionaryAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IMapViewToIReadOnlyDictionaryAdapter.cs
@@ -28,15 +28,14 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
private IMapViewToIReadOnlyDictionaryAdapter()
{
- Contract.Assert(false, "This class is never instantiated");
+ Debug.Assert(false, "This class is never instantiated");
}
// V this[K key] { get }
- [SecurityCritical]
internal V Indexer_Get<K, V>(K key)
{
if (key == null)
- throw new ArgumentNullException("key");
+ throw new ArgumentNullException(nameof(key));
Contract.EndContractBlock();
IMapView<K, V> _this = JitHelpers.UnsafeCast<IMapView<K, V>>(this);
@@ -44,7 +43,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// IEnumerable<K> Keys { get }
- [SecurityCritical]
internal IEnumerable<K> Keys<K, V>()
{
IMapView<K, V> _this = JitHelpers.UnsafeCast<IMapView<K, V>>(this);
@@ -53,7 +51,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// IEnumerable<V> Values { get }
- [SecurityCritical]
internal IEnumerable<V> Values<K, V>()
{
IMapView<K, V> _this = JitHelpers.UnsafeCast<IMapView<K, V>>(this);
@@ -63,22 +60,20 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// bool ContainsKey(K key)
[Pure]
- [SecurityCritical]
internal bool ContainsKey<K, V>(K key)
{
if (key == null)
- throw new ArgumentNullException("key");
+ throw new ArgumentNullException(nameof(key));
IMapView<K, V> _this = JitHelpers.UnsafeCast<IMapView<K, V>>(this);
return _this.HasKey(key);
}
// bool TryGetValue(TKey key, out TValue value)
- [SecurityCritical]
internal bool TryGetValue<K, V>(K key, out V value)
{
if (key == null)
- throw new ArgumentNullException("key");
+ throw new ArgumentNullException(nameof(key));
IMapView<K, V> _this = JitHelpers.UnsafeCast<IMapView<K, V>>(this);
@@ -137,7 +132,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public ReadOnlyDictionaryKeyCollection(IReadOnlyDictionary<TKey, TValue> dictionary)
{
if (dictionary == null)
- throw new ArgumentNullException("dictionary");
+ throw new ArgumentNullException(nameof(dictionary));
this.dictionary = dictionary;
}
@@ -146,9 +141,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public void CopyTo(TKey[] array, int index)
{
if (array == null)
- throw new ArgumentNullException("array");
+ throw new ArgumentNullException(nameof(array));
if (index < 0)
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
if (array.Length <= index && this.Count > 0)
throw new ArgumentException(Environment.GetResourceString("Arg_IndexOutOfRangeException"));
if (array.Length - index < dictionary.Count)
@@ -192,7 +187,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public ReadOnlyDictionaryKeyEnumerator(IReadOnlyDictionary<TKey, TValue> dictionary)
{
if (dictionary == null)
- throw new ArgumentNullException("dictionary");
+ throw new ArgumentNullException(nameof(dictionary));
this.dictionary = dictionary;
this.enumeration = dictionary.GetEnumerator();
@@ -232,7 +227,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public ReadOnlyDictionaryValueCollection(IReadOnlyDictionary<TKey, TValue> dictionary)
{
if (dictionary == null)
- throw new ArgumentNullException("dictionary");
+ throw new ArgumentNullException(nameof(dictionary));
this.dictionary = dictionary;
}
@@ -241,9 +236,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public void CopyTo(TValue[] array, int index)
{
if (array == null)
- throw new ArgumentNullException("array");
+ throw new ArgumentNullException(nameof(array));
if (index < 0)
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
if (array.Length <= index && this.Count > 0)
throw new ArgumentException(Environment.GetResourceString("Arg_IndexOutOfRangeException"));
if (array.Length - index < dictionary.Count)
@@ -291,7 +286,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public ReadOnlyDictionaryValueEnumerator(IReadOnlyDictionary<TKey, TValue> dictionary)
{
if (dictionary == null)
- throw new ArgumentNullException("dictionary");
+ throw new ArgumentNullException(nameof(dictionary));
this.dictionary = dictionary;
this.enumeration = dictionary.GetEnumerator();
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IReadOnlyDictionaryToIMapViewAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IReadOnlyDictionaryToIMapViewAdapter.cs
index d57f8f1f46..b185b41be0 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IReadOnlyDictionaryToIMapViewAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IReadOnlyDictionaryToIMapViewAdapter.cs
@@ -28,11 +28,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
private IReadOnlyDictionaryToIMapViewAdapter()
{
- Contract.Assert(false, "This class is never instantiated");
+ Debug.Assert(false, "This class is never instantiated");
}
// V Lookup(K key)
- [SecurityCritical]
internal V Lookup<K, V>(K key)
{
IReadOnlyDictionary<K, V> _this = JitHelpers.UnsafeCast<IReadOnlyDictionary<K, V>>(this);
@@ -50,7 +49,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// uint Size { get }
- [SecurityCritical]
internal uint Size<K, V>()
{
IReadOnlyDictionary<K, V> _this = JitHelpers.UnsafeCast<IReadOnlyDictionary<K, V>>(this);
@@ -58,7 +56,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// bool HasKey(K key)
- [SecurityCritical]
internal bool HasKey<K, V>(K key)
{
IReadOnlyDictionary<K, V> _this = JitHelpers.UnsafeCast<IReadOnlyDictionary<K, V>>(this);
@@ -66,7 +63,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// void Split(out IMapView<K, V> first, out IMapView<K, V> second)
- [SecurityCritical]
internal void Split<K, V>(out IMapView<K, V> first, out IMapView<K, V> second)
{
IReadOnlyDictionary<K, V> _this = JitHelpers.UnsafeCast<IReadOnlyDictionary<K, V>>(this);
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IReadOnlyListToIVectorViewAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IReadOnlyListToIVectorViewAdapter.cs
index 95780bcb13..431d16256e 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IReadOnlyListToIVectorViewAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IReadOnlyListToIVectorViewAdapter.cs
@@ -28,11 +28,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
private IReadOnlyListToIVectorViewAdapter()
{
- Contract.Assert(false, "This class is never instantiated");
+ Debug.Assert(false, "This class is never instantiated");
}
// T GetAt(uint index)
- [SecurityCritical]
internal T GetAt<T>(uint index)
{
IReadOnlyList<T> _this = JitHelpers.UnsafeCast<IReadOnlyList<T>>(this);
@@ -50,7 +49,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// uint Size { get }
- [SecurityCritical]
internal uint Size<T>()
{
IReadOnlyList<T> _this = JitHelpers.UnsafeCast<IReadOnlyList<T>>(this);
@@ -58,7 +56,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// bool IndexOf(T value, out uint index)
- [SecurityCritical]
internal bool IndexOf<T>(T value, out uint index)
{
IReadOnlyList<T> _this = JitHelpers.UnsafeCast<IReadOnlyList<T>>(this);
@@ -85,7 +82,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// uint GetMany(uint startIndex, T[] items)
- [SecurityCritical]
internal uint GetMany<T>(uint startIndex, T[] items)
{
IReadOnlyList<T> _this = JitHelpers.UnsafeCast<IReadOnlyList<T>>(this);
@@ -130,7 +126,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// that Size > Int32.MaxValue:
if (((uint)Int32.MaxValue) <= index || index >= (uint)listCapacity)
{
- Exception e = new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_IndexLargerThanMaxValue"));
+ Exception e = new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_IndexLargerThanMaxValue"));
e.SetErrorCode(__HResults.E_BOUNDS);
throw e;
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IRestrictedErrorInfo.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IRestrictedErrorInfo.cs
index 48bcc4f618..9de5e3f36d 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IRestrictedErrorInfo.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IRestrictedErrorInfo.cs
@@ -8,9 +8,7 @@ using System;
namespace System.Runtime.InteropServices.WindowsRuntime
{
-#if FEATURE_CORECLR
[System.Runtime.CompilerServices.FriendAccessAllowed]
-#endif
[ComImport]
[Guid("82BA7092-4C88-427D-A7BC-16DD93FEB67E")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IVectorViewToIReadOnlyListAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IVectorViewToIReadOnlyListAdapter.cs
index 72d6fa8cc3..37f21307dc 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IVectorViewToIReadOnlyListAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IVectorViewToIReadOnlyListAdapter.cs
@@ -30,15 +30,14 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
private IVectorViewToIReadOnlyListAdapter()
{
- Contract.Assert(false, "This class is never instantiated");
+ Debug.Assert(false, "This class is never instantiated");
}
// T this[int index] { get }
- [SecurityCritical]
internal T Indexer_Get<T>(int index)
{
if (index < 0)
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
IVectorView<T> _this = JitHelpers.UnsafeCast<IVectorView<T>>(this);
@@ -52,14 +51,13 @@ namespace System.Runtime.InteropServices.WindowsRuntime
catch (Exception ex)
{
if (__HResults.E_BOUNDS == ex._HResult)
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
throw;
}
}
// T this[int index] { get }
- [SecurityCritical]
internal T Indexer_Get_Variance<T>(int index) where T : class
{
bool fUseString;
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IteratorToEnumeratorAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IteratorToEnumeratorAdapter.cs
index f1b799aa84..e219a86769 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IteratorToEnumeratorAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IteratorToEnumeratorAdapter.cs
@@ -7,6 +7,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
@@ -28,11 +29,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
private IterableToEnumerableAdapter()
{
- Contract.Assert(false, "This class is never instantiated");
+ Debug.Assert(false, "This class is never instantiated");
}
// This method is invoked when GetEnumerator is called on a WinRT-backed implementation of IEnumerable<T>.
- [SecurityCritical]
internal IEnumerator<T> GetEnumerator_Stub<T>()
{
IIterable<T> _this = JitHelpers.UnsafeCast<IIterable<T>>(this);
@@ -43,7 +43,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// and it is possible that the implementation supports IEnumerable<Type>/IEnumerable<string>/IEnumerable<Exception>/
// IEnumerable<array>/IEnumerable<delegate> rather than IEnumerable<T> because T is assignable from Type/string/
// Exception/array/delegate via co-variance.
- [SecurityCritical]
internal IEnumerator<T> GetEnumerator_Variance_Stub<T>() where T : class
{
bool fUseString;
@@ -70,7 +69,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
private BindableIterableToEnumerableAdapter()
{
- Contract.Assert(false, "This class is never instantiated");
+ Debug.Assert(false, "This class is never instantiated");
}
private sealed class NonGenericToGenericIterator : IIterator<object>
@@ -87,7 +86,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// This method is invoked when GetEnumerator is called on a WinRT-backed implementation of IEnumerable.
- [SecurityCritical]
internal IEnumerator GetEnumerator_Stub()
{
IBindableIterable _this = JitHelpers.UnsafeCast<IBindableIterable>(this);
@@ -123,10 +121,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
// The enumerator has not been advanced to the first element yet.
if (!m_isInitialized)
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumNotStarted);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumNotStarted();
// The enumerator has reached the end of the collection
if (!m_hadCurrent)
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumEnded);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumEnded();
return m_current;
}
}
@@ -137,15 +135,14 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
// The enumerator has not been advanced to the first element yet.
if (!m_isInitialized)
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumNotStarted);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumNotStarted();
// The enumerator has reached the end of the collection
if (!m_hadCurrent)
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumEnded);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumEnded();
return m_current;
}
}
- [SecuritySafeCritical]
public bool MoveNext()
{
// If we've passed the end of the iteration, IEnumerable<T> should return false, while
@@ -187,7 +184,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// Translate E_CHANGED_STATE into an InvalidOperationException for an updated enumeration
if (Marshal.GetHRForException(e) == __HResults.E_CHANGED_STATE)
{
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
else
{
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToBindableVectorAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToBindableVectorAdapter.cs
index 35dc495d3f..b9fe11557d 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToBindableVectorAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToBindableVectorAdapter.cs
@@ -10,6 +10,7 @@ using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
@@ -28,11 +29,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
private ListToBindableVectorAdapter()
{
- Contract.Assert(false, "This class is never instantiated");
+ Debug.Assert(false, "This class is never instantiated");
}
// object GetAt(uint index)
- [SecurityCritical]
internal object GetAt(uint index)
{
IList _this = JitHelpers.UnsafeCast<IList>(this);
@@ -49,7 +49,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// uint Size { get }
- [SecurityCritical]
internal uint Size()
{
IList _this = JitHelpers.UnsafeCast<IList>(this);
@@ -57,7 +56,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// IBindableVectorView GetView()
- [SecurityCritical]
internal IBindableVectorView GetView()
{
IList _this = JitHelpers.UnsafeCast<IList>(this);
@@ -65,7 +63,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// bool IndexOf(object value, out uint index)
- [SecurityCritical]
internal bool IndexOf(object value, out uint index)
{
IList _this = JitHelpers.UnsafeCast<IList>(this);
@@ -82,7 +79,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// void SetAt(uint index, object value)
- [SecurityCritical]
internal void SetAt(uint index, object value)
{
IList _this = JitHelpers.UnsafeCast<IList>(this);
@@ -99,7 +95,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// void InsertAt(uint index, object value)
- [SecurityCritical]
internal void InsertAt(uint index, object value)
{
IList _this = JitHelpers.UnsafeCast<IList>(this);
@@ -121,7 +116,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// void RemoveAt(uint index)
- [SecurityCritical]
internal void RemoveAt(uint index)
{
IList _this = JitHelpers.UnsafeCast<IList>(this);
@@ -140,7 +134,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// void Append(object value)
- [SecurityCritical]
internal void Append(object value)
{
IList _this = JitHelpers.UnsafeCast<IList>(this);
@@ -148,7 +141,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// void RemoveAtEnd()
- [SecurityCritical]
internal void RemoveAtEnd()
{
IList _this = JitHelpers.UnsafeCast<IList>(this);
@@ -164,7 +156,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// void Clear()
- [SecurityCritical]
internal void Clear()
{
IList _this = JitHelpers.UnsafeCast<IList>(this);
@@ -179,7 +170,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// that Size > Int32.MaxValue:
if (((uint)Int32.MaxValue) <= index || index >= (uint)listCapacity)
{
- Exception e = new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_IndexLargerThanMaxValue"));
+ Exception e = new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("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 f760576aaa..2e2ea9b876 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToBindableVectorViewAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToBindableVectorViewAdapter.cs
@@ -25,7 +25,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
internal ListToBindableVectorViewAdapter(IList list)
{
if (list == null)
- throw new ArgumentNullException("list");
+ throw new ArgumentNullException(nameof(list));
Contract.EndContractBlock();
@@ -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("index", Environment.GetResourceString("ArgumentOutOfRange_IndexLargerThanMaxValue"));
+ Exception e = new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_IndexLargerThanMaxValue"));
e.SetErrorCode(__HResults.E_BOUNDS);
throw e;
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToVectorAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToVectorAdapter.cs
index 77f3a9464f..b73f4d7a99 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToVectorAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToVectorAdapter.cs
@@ -10,6 +10,7 @@ using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
@@ -28,11 +29,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
private ListToVectorAdapter()
{
- Contract.Assert(false, "This class is never instantiated");
+ Debug.Assert(false, "This class is never instantiated");
}
// T GetAt(uint index)
- [SecurityCritical]
internal T GetAt<T>(uint index)
{
IList<T> _this = JitHelpers.UnsafeCast<IList<T>>(this);
@@ -49,7 +49,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// uint Size { get }
- [SecurityCritical]
internal uint Size<T>()
{
IList<T> _this = JitHelpers.UnsafeCast<IList<T>>(this);
@@ -57,11 +56,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// IVectorView<T> GetView()
- [SecurityCritical]
internal IReadOnlyList<T> GetView<T>()
{
IList<T> _this = JitHelpers.UnsafeCast<IList<T>>(this);
- Contract.Assert(_this != null);
+ Debug.Assert(_this != null);
// Note: This list is not really read-only - you could QI for a modifiable
// list. We gain some perf by doing this. We believe this is acceptable.
@@ -74,7 +72,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// bool IndexOf(T value, out uint index)
- [SecurityCritical]
internal bool IndexOf<T>(T value, out uint index)
{
IList<T> _this = JitHelpers.UnsafeCast<IList<T>>(this);
@@ -91,7 +88,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// void SetAt(uint index, T value)
- [SecurityCritical]
internal void SetAt<T>(uint index, T value)
{
IList<T> _this = JitHelpers.UnsafeCast<IList<T>>(this);
@@ -108,7 +104,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// void InsertAt(uint index, T value)
- [SecurityCritical]
internal void InsertAt<T>(uint index, T value)
{
IList<T> _this = JitHelpers.UnsafeCast<IList<T>>(this);
@@ -130,7 +125,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// void RemoveAt(uint index)
- [SecurityCritical]
internal void RemoveAt<T>(uint index)
{
IList<T> _this = JitHelpers.UnsafeCast<IList<T>>(this);
@@ -149,7 +143,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// void Append(T value)
- [SecurityCritical]
internal void Append<T>(T value)
{
IList<T> _this = JitHelpers.UnsafeCast<IList<T>>(this);
@@ -157,7 +150,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// void RemoveAtEnd()
- [SecurityCritical]
internal void RemoveAtEnd<T>()
{
IList<T> _this = JitHelpers.UnsafeCast<IList<T>>(this);
@@ -173,7 +165,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// void Clear()
- [SecurityCritical]
internal void Clear<T>()
{
IList<T> _this = JitHelpers.UnsafeCast<IList<T>>(this);
@@ -181,7 +172,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// uint GetMany(uint startIndex, T[] items)
- [SecurityCritical]
internal uint GetMany<T>(uint startIndex, T[] items)
{
IList<T> _this = JitHelpers.UnsafeCast<IList<T>>(this);
@@ -189,7 +179,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// void ReplaceAll(T[] items)
- [SecurityCritical]
internal void ReplaceAll<T>(T[] items)
{
IList<T> _this = JitHelpers.UnsafeCast<IList<T>>(this);
@@ -212,7 +201,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// that Size > Int32.MaxValue:
if (((uint)Int32.MaxValue) <= index || index >= (uint)listCapacity)
{
- Exception e = new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_IndexLargerThanMaxValue"));
+ Exception e = new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("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 3e93428d26..2d08cab0ee 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ManagedActivationFactory.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ManagedActivationFactory.cs
@@ -33,16 +33,15 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
private Type m_type;
- [SecurityCritical]
internal ManagedActivationFactory(Type type)
{
if (type == null)
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
// 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), "type");
+ throw new ArgumentException(Environment.GetResourceString("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 395bef93d5..f11260eb4a 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapToCollectionAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapToCollectionAdapter.cs
@@ -8,6 +8,7 @@ using System;
using System.Security;
using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
@@ -29,12 +30,11 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
private MapToCollectionAdapter()
{
- Contract.Assert(false, "This class is never instantiated");
+ Debug.Assert(false, "This class is never instantiated");
}
// int Count { get }
[Pure]
- [SecurityCritical]
internal int Count<K, V>()
{
object _this = JitHelpers.UnsafeCast<object>(this);
@@ -66,14 +66,12 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// bool IsReadOnly { get }
- [SecurityCritical]
internal bool IsReadOnly<K, V>()
{
return false;
}
// void Add(T item)
- [SecurityCritical]
internal void Add<K, V>(KeyValuePair<K, V> item)
{
object _this = JitHelpers.UnsafeCast<object>(this);
@@ -91,7 +89,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// void Clear()
- [SecurityCritical]
internal void Clear<K, V>()
{
object _this = JitHelpers.UnsafeCast<object>(this);
@@ -109,7 +106,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// bool Contains(T item)
- [SecurityCritical]
internal bool Contains<K, V>(KeyValuePair<K, V> item)
{
object _this = JitHelpers.UnsafeCast<object>(this);
@@ -135,14 +131,13 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// void CopyTo(T[] array, int arrayIndex)
- [SecurityCritical]
internal void CopyTo<K, V>(KeyValuePair<K, V>[] array, int arrayIndex)
{
if (array == null)
- throw new ArgumentNullException("array");
+ throw new ArgumentNullException(nameof(array));
if (arrayIndex < 0)
- throw new ArgumentOutOfRangeException("arrayIndex");
+ throw new ArgumentOutOfRangeException(nameof(arrayIndex));
if (array.Length <= arrayIndex && Count<K, V>() > 0)
throw new ArgumentException(Environment.GetResourceString("Argument_IndexOutOfArrayBounds"));
@@ -160,7 +155,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// bool Remove(T item)
- [SecurityCritical]
internal bool Remove<K, V>(KeyValuePair<K, V> item)
{
object _this = JitHelpers.UnsafeCast<object>(this);
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapToDictionaryAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapToDictionaryAdapter.cs
index d7897ced9f..981972ca9f 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapToDictionaryAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapToDictionaryAdapter.cs
@@ -8,6 +8,7 @@ using System;
using System.Security;
using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
@@ -26,15 +27,14 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
private MapToDictionaryAdapter()
{
- Contract.Assert(false, "This class is never instantiated");
+ Debug.Assert(false, "This class is never instantiated");
}
// V this[K key] { get }
- [SecurityCritical]
internal V Indexer_Get<K, V>(K key)
{
if (key == null)
- throw new ArgumentNullException("key");
+ throw new ArgumentNullException(nameof(key));
Contract.EndContractBlock();
@@ -43,11 +43,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// V this[K key] { set }
- [SecurityCritical]
internal void Indexer_Set<K, V>(K key, V value)
{
if (key == null)
- throw new ArgumentNullException("key");
+ throw new ArgumentNullException(nameof(key));
Contract.EndContractBlock();
@@ -56,7 +55,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// ICollection<K> Keys { get }
- [SecurityCritical]
internal ICollection<K> Keys<K, V>()
{
IMap<K, V> _this = JitHelpers.UnsafeCast<IMap<K, V>>(this);
@@ -65,7 +63,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// ICollection<V> Values { get }
- [SecurityCritical]
internal ICollection<V> Values<K, V>()
{
IMap<K, V> _this = JitHelpers.UnsafeCast<IMap<K, V>>(this);
@@ -75,22 +72,20 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// bool ContainsKey(K key)
[Pure]
- [SecurityCritical]
internal bool ContainsKey<K, V>(K key)
{
if (key == null)
- throw new ArgumentNullException("key");
+ throw new ArgumentNullException(nameof(key));
IMap<K, V> _this = JitHelpers.UnsafeCast<IMap<K, V>>(this);
return _this.HasKey(key);
}
// void Add(K key, V value)
- [SecurityCritical]
internal void Add<K, V>(K key, V value)
{
if (key == null)
- throw new ArgumentNullException("key");
+ throw new ArgumentNullException(nameof(key));
if (ContainsKey<K, V>(key))
throw new ArgumentException(Environment.GetResourceString("Argument_AddingDuplicate"));
@@ -102,11 +97,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// bool Remove(TKey key)
- [SecurityCritical]
internal bool Remove<K, V>(K key)
{
if (key == null)
- throw new ArgumentNullException("key");
+ throw new ArgumentNullException(nameof(key));
IMap<K, V> _this = JitHelpers.UnsafeCast<IMap<K, V>>(this);
if (!_this.HasKey(key))
@@ -128,11 +122,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// bool TryGetValue(TKey key, out TValue value)
- [SecurityCritical]
internal bool TryGetValue<K, V>(K key, out V value)
{
if (key == null)
- throw new ArgumentNullException("key");
+ throw new ArgumentNullException(nameof(key));
IMap<K, V> _this = JitHelpers.UnsafeCast<IMap<K, V>>(this);
if (!_this.HasKey(key))
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapViewToReadOnlyCollectionAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapViewToReadOnlyCollectionAdapter.cs
index 58427fbd71..a3715da0b0 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapViewToReadOnlyCollectionAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapViewToReadOnlyCollectionAdapter.cs
@@ -8,6 +8,7 @@ using System;
using System.Security;
using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
@@ -29,12 +30,11 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
private MapViewToReadOnlyCollectionAdapter()
{
- Contract.Assert(false, "This class is never instantiated");
+ Debug.Assert(false, "This class is never instantiated");
}
// int Count { get }
[Pure]
- [SecurityCritical]
internal int Count<K, V>()
{
object _this = JitHelpers.UnsafeCast<object>(this);
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/NativeMethods.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/NativeMethods.cs
index b8cd65efa6..4380369754 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/NativeMethods.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/NativeMethods.cs
@@ -22,30 +22,25 @@ namespace System.Runtime.InteropServices.WindowsRuntime
internal static class UnsafeNativeMethods
{
[DllImport("api-ms-win-core-winrt-error-l1-1-1.dll", PreserveSig = false)]
- [SecurityCritical]
[SuppressUnmanagedCodeSecurity]
internal static extern IRestrictedErrorInfo GetRestrictedErrorInfo();
[DllImport("api-ms-win-core-winrt-error-l1-1-1.dll")]
- [SecurityCritical]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool RoOriginateLanguageException(int error, [MarshalAs(UnmanagedType.HString)]string message, IntPtr languageException);
[DllImport("api-ms-win-core-winrt-error-l1-1-1.dll", PreserveSig = false)]
- [SecurityCritical]
[SuppressUnmanagedCodeSecurity]
internal static extern void RoReportUnhandledError(IRestrictedErrorInfo error);
[DllImport("api-ms-win-core-winrt-string-l1-1-0.dll", CallingConvention = CallingConvention.StdCall)]
- [SecurityCritical]
[SuppressUnmanagedCodeSecurity]
internal static unsafe extern int WindowsCreateString([MarshalAs(UnmanagedType.LPWStr)] string sourceString,
int length,
[Out] IntPtr *hstring);
[DllImport("api-ms-win-core-winrt-string-l1-1-0.dll", CallingConvention = CallingConvention.StdCall)]
- [SecurityCritical]
[SuppressUnmanagedCodeSecurity]
internal static unsafe extern int WindowsCreateStringReference(char *sourceString,
int length,
@@ -53,12 +48,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
[Out] IntPtr *hstring);
[DllImport("api-ms-win-core-winrt-string-l1-1-0.dll", CallingConvention = CallingConvention.StdCall)]
- [SecurityCritical]
[SuppressUnmanagedCodeSecurity]
internal static extern int WindowsDeleteString(IntPtr hstring);
[DllImport("api-ms-win-core-winrt-string-l1-1-0.dll", CallingConvention = CallingConvention.StdCall)]
- [SecurityCritical]
[SuppressUnmanagedCodeSecurity]
internal static unsafe extern char* WindowsGetStringRawBuffer(IntPtr hstring, [Out] uint *length);
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/RuntimeClass.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/RuntimeClass.cs
index 5dd7d00579..cd3c53ab4e 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/RuntimeClass.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/RuntimeClass.cs
@@ -57,15 +57,12 @@ namespace System.Runtime.InteropServices.WindowsRuntime {
//
// Support for ToString/GetHashCode/Equals override
//
- [System.Security.SecurityCritical]
[MethodImpl(MethodImplOptions.InternalCall)]
internal extern IntPtr GetRedirectedGetHashCodeMD();
- [System.Security.SecurityCritical]
[MethodImpl(MethodImplOptions.InternalCall)]
internal extern int RedirectGetHashCode(IntPtr pMD);
- [System.Security.SecuritySafeCritical]
public override int GetHashCode()
{
IntPtr pMD = GetRedirectedGetHashCodeMD();
@@ -74,15 +71,12 @@ namespace System.Runtime.InteropServices.WindowsRuntime {
return RedirectGetHashCode(pMD);
}
- [System.Security.SecurityCritical]
[MethodImpl(MethodImplOptions.InternalCall)]
internal extern IntPtr GetRedirectedToStringMD();
- [System.Security.SecurityCritical]
[MethodImpl(MethodImplOptions.InternalCall)]
internal extern string RedirectToString(IntPtr pMD);
- [System.Security.SecuritySafeCritical]
public override string ToString()
{
// Check whether the type implements IStringable.
@@ -102,15 +96,12 @@ namespace System.Runtime.InteropServices.WindowsRuntime {
}
}
- [System.Security.SecurityCritical]
[MethodImpl(MethodImplOptions.InternalCall)]
internal extern IntPtr GetRedirectedEqualsMD();
- [System.Security.SecurityCritical]
[MethodImpl(MethodImplOptions.InternalCall)]
internal extern bool RedirectEquals(object obj, IntPtr pMD);
- [System.Security.SecuritySafeCritical]
public override bool Equals(object obj)
{
IntPtr pMD = GetRedirectedEqualsMD();
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorToCollectionAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorToCollectionAdapter.cs
index 5eeb0afcfc..898f1a68a0 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorToCollectionAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorToCollectionAdapter.cs
@@ -8,6 +8,7 @@ using System;
using System.Security;
using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
@@ -26,12 +27,11 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
private VectorToCollectionAdapter()
{
- Contract.Assert(false, "This class is never instantiated");
+ Debug.Assert(false, "This class is never instantiated");
}
// int Count { get }
[Pure]
- [SecurityCritical]
internal int Count<T>()
{
IVector<T> _this = JitHelpers.UnsafeCast<IVector<T>>(this);
@@ -45,14 +45,12 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// bool IsReadOnly { get }
- [SecurityCritical]
internal bool IsReadOnly<T>()
{
return false;
}
// void Add(T item)
- [SecurityCritical]
internal void Add<T>(T item)
{
IVector<T> _this = JitHelpers.UnsafeCast<IVector<T>>(this);
@@ -60,7 +58,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// void Clear()
- [SecurityCritical]
internal void Clear<T>()
{
IVector<T> _this = JitHelpers.UnsafeCast<IVector<T>>(this);
@@ -68,7 +65,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// bool Contains(T item)
- [SecurityCritical]
internal bool Contains<T>(T item)
{
IVector<T> _this = JitHelpers.UnsafeCast<IVector<T>>(this);
@@ -78,14 +74,13 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// void CopyTo(T[] array, int arrayIndex)
- [SecurityCritical]
internal void CopyTo<T>(T[] array, int arrayIndex)
{
if (array == null)
- throw new ArgumentNullException("array");
+ throw new ArgumentNullException(nameof(array));
if (arrayIndex < 0)
- throw new ArgumentOutOfRangeException("arrayIndex");
+ throw new ArgumentOutOfRangeException(nameof(arrayIndex));
if (array.Length <= arrayIndex && Count<T>() > 0)
throw new ArgumentException(Environment.GetResourceString("Argument_IndexOutOfArrayBounds"));
@@ -104,7 +99,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// bool Remove(T item)
- [SecurityCritical]
internal bool Remove<T>(T item)
{
IVector<T> _this = JitHelpers.UnsafeCast<IVector<T>>(this);
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorToListAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorToListAdapter.cs
index f27cc95176..3e3324864d 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorToListAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorToListAdapter.cs
@@ -8,6 +8,7 @@ using System;
using System.Security;
using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
@@ -26,33 +27,30 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
private VectorToListAdapter()
{
- Contract.Assert(false, "This class is never instantiated");
+ Debug.Assert(false, "This class is never instantiated");
}
// T this[int index] { get }
- [SecurityCritical]
internal T Indexer_Get<T>(int index)
{
if (index < 0)
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
IVector<T> _this = JitHelpers.UnsafeCast<IVector<T>>(this);
return GetAt(_this, (uint)index);
}
// T this[int index] { set }
- [SecurityCritical]
internal void Indexer_Set<T>(int index, T value)
{
if (index < 0)
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
IVector<T> _this = JitHelpers.UnsafeCast<IVector<T>>(this);
SetAt(_this, (uint)index, value);
}
// int IndexOf(T item)
- [SecurityCritical]
internal int IndexOf<T>(T item)
{
IVector<T> _this = JitHelpers.UnsafeCast<IVector<T>>(this);
@@ -72,22 +70,20 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// void Insert(int index, T item)
- [SecurityCritical]
internal void Insert<T>(int index, T item)
{
if (index < 0)
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
IVector<T> _this = JitHelpers.UnsafeCast<IVector<T>>(this);
InsertAtHelper<T>(_this, (uint)index, item);
}
// void RemoveAt(int index)
- [SecurityCritical]
internal void RemoveAt<T>(int index)
{
if (index < 0)
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
IVector<T> _this = JitHelpers.UnsafeCast<IVector<T>>(this);
RemoveAtHelper<T>(_this, (uint)index);
@@ -107,7 +103,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
catch (Exception ex)
{
if (__HResults.E_BOUNDS == ex._HResult)
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
throw;
}
@@ -125,7 +121,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
catch (Exception ex)
{
if (__HResults.E_BOUNDS == ex._HResult)
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
throw;
}
@@ -143,7 +139,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
catch (Exception ex)
{
if (__HResults.E_BOUNDS == ex._HResult)
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
throw;
}
@@ -161,7 +157,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
catch (Exception ex)
{
if (__HResults.E_BOUNDS == ex._HResult)
- throw new ArgumentOutOfRangeException("index");
+ throw new ArgumentOutOfRangeException(nameof(index));
throw;
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorViewToReadOnlyCollectionAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorViewToReadOnlyCollectionAdapter.cs
index 4b4ae5d6fc..6b7785d2dc 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorViewToReadOnlyCollectionAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorViewToReadOnlyCollectionAdapter.cs
@@ -8,6 +8,7 @@ using System;
using System.Security;
using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
@@ -26,12 +27,11 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
private VectorViewToReadOnlyCollectionAdapter()
{
- Contract.Assert(false, "This class is never instantiated");
+ Debug.Assert(false, "This class is never instantiated");
}
// int Count { get }
[Pure]
- [SecurityCritical]
internal int Count<T>()
{
IVectorView<T> _this = JitHelpers.UnsafeCast<IVectorView<T>>(this);
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeBufferHelper.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeBufferHelper.cs
index 0d59895bc4..a786880fab 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeBufferHelper.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeBufferHelper.cs
@@ -19,7 +19,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime {
internal static class WindowsRuntimeBufferHelper {
- [SecurityCritical]
[DllImport(JitHelpers.QCall)]
[SuppressUnmanagedCodeSecurity]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
@@ -27,7 +26,6 @@ internal static class WindowsRuntimeBufferHelper {
[FriendAccessAllowed]
- [SecurityCritical]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal unsafe static void StoreOverlappedInCCW(Object windowsRuntimeBuffer, NativeOverlapped* overlapped) {
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMarshal.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMarshal.cs
index 038efd5013..a7ad4912de 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMarshal.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMarshal.cs
@@ -6,6 +6,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Reflection;
using System.Runtime.CompilerServices;
@@ -23,15 +24,14 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// delegate. It then stores the corresponding token in a dictionary for easy access by RemoveEventHandler
// later. Note that the dictionary is indexed by the remove method that will be used for RemoveEventHandler
// so the removeMethod given here must match the remove method supplied there exactly.
- [SecurityCritical]
public static void AddEventHandler<T>(Func<T, EventRegistrationToken> addMethod,
Action<EventRegistrationToken> removeMethod,
T handler)
{
if (addMethod == null)
- throw new ArgumentNullException("addMethod");
+ throw new ArgumentNullException(nameof(addMethod));
if (removeMethod == null)
- throw new ArgumentNullException("removeMethod");
+ throw new ArgumentNullException(nameof(removeMethod));
Contract.EndContractBlock();
// Managed code allows adding a null event handler, the effect is a no-op. To match this behavior
@@ -54,11 +54,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// Remove the delegate handler from the Windows Runtime style event registration by looking for
// its token, previously stored via AddEventHandler<T>
- [SecurityCritical]
public static void RemoveEventHandler<T>(Action<EventRegistrationToken> removeMethod, T handler)
{
if (removeMethod == null)
- throw new ArgumentNullException("removeMethod");
+ throw new ArgumentNullException(nameof(removeMethod));
Contract.EndContractBlock();
// Managed code allows removing a null event handler, the effect is a no-op. To match this behavior
@@ -79,11 +78,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
ManagedEventRegistrationImpl.RemoveEventHandler<T>(removeMethod, handler);
}
- [SecurityCritical]
public static void RemoveAllEventHandlers(Action<EventRegistrationToken> removeMethod)
{
if (removeMethod == null)
- throw new ArgumentNullException("removeMethod");
+ throw new ArgumentNullException(nameof(removeMethod));
Contract.EndContractBlock();
// Delegate to managed event registration implementation or native event registration implementation
@@ -220,7 +218,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
ConditionalWeakTable<object, Dictionary<MethodInfo, Dictionary<object, EventRegistrationTokenList>>> s_eventRegistrations =
new ConditionalWeakTable<object, Dictionary<MethodInfo, Dictionary<object, EventRegistrationTokenList>>>();
- [SecurityCritical]
internal static void AddEventHandler<T>(Func<T, EventRegistrationToken> addMethod,
Action<EventRegistrationToken> removeMethod,
T handler)
@@ -280,7 +277,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
}
- [SecurityCritical]
internal static void RemoveEventHandler<T>(Action<EventRegistrationToken> removeMethod, T handler)
{
Contract.Requires(removeMethod != null);
@@ -322,7 +318,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
BCLDebug.Log("INTEROP", "[WinRT_Eventing] Event unsubscribed for managed instance = " + instance + ", handler = " + handler + ", token = " + token.m_value + "\n");
}
- [SecurityCritical]
internal static void RemoveAllEventHandlers(Action<EventRegistrationToken> removeMethod)
{
Contract.Requires(removeMethod != null);
@@ -538,11 +533,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
private volatile static MyReaderWriterLock s_eventCacheRWLock = new MyReaderWriterLock();
// Get InstanceKey to use in the cache
- [SecuritySafeCritical]
private static object GetInstanceKey(Action<EventRegistrationToken> removeMethod)
{
object target = removeMethod.Target;
- Contract.Assert(target == null || Marshal.IsComObject(target), "Must be null or a RCW");
+ Debug.Assert(target == null || Marshal.IsComObject(target), "Must be null or a RCW");
if (target == null)
return removeMethod.Method.DeclaringType;
@@ -550,7 +544,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
return (object) Marshal.GetRawIUnknownForComObjectNoAddRef(target);
}
- [SecurityCritical]
internal static void AddEventHandler<T>(Func<T, EventRegistrationToken> addMethod,
Action<EventRegistrationToken> removeMethod,
T handler)
@@ -685,7 +678,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
}
- [SecurityCritical]
internal static void RemoveEventHandler<T>(Action<EventRegistrationToken> removeMethod, T handler)
{
object instanceKey = GetInstanceKey(removeMethod);
@@ -721,7 +713,7 @@ 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);
- Contract.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)
{
@@ -762,7 +754,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
removeMethod(token);
}
- [SecurityCritical]
internal static void RemoveAllEventHandlers(Action<EventRegistrationToken> removeMethod)
{
object instanceKey = GetInstanceKey(removeMethod);
@@ -908,7 +899,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
internal void ReleaseReaderLock()
{
EnterMyLock();
- Contract.Assert(owners > 0, "ReleasingReaderLock: releasing lock and no read lock taken");
+ Debug.Assert(owners > 0, "ReleasingReaderLock: releasing lock and no read lock taken");
--owners;
ExitAndWakeUpAppropriateWaiters();
}
@@ -916,7 +907,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
internal void ReleaseWriterLock()
{
EnterMyLock();
- Contract.Assert(owners == -1, "Calling ReleaseWriterLock when no write lock is held");
+ Debug.Assert(owners == -1, "Calling ReleaseWriterLock when no write lock is held");
owners++;
ExitAndWakeUpAppropriateWaiters();
}
@@ -928,8 +919,8 @@ namespace System.Runtime.InteropServices.WindowsRuntime
/// set 'waitEvent'
/// </summary>
private void LazyCreateEvent(ref EventWaitHandle waitEvent, bool makeAutoResetEvent) {
- Contract.Assert(myLock != 0, "Lock must be held");
- Contract.Assert(waitEvent == null, "Wait event must be null");
+ Debug.Assert(myLock != 0, "Lock must be held");
+ Debug.Assert(waitEvent == null, "Wait event must be null");
ExitMyLock();
EventWaitHandle newEvent;
@@ -948,7 +939,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
/// </summary>
private void WaitOnEvent(EventWaitHandle waitEvent, ref uint numWaiters, int millisecondsTimeout)
{
- Contract.Assert(myLock != 0, "Lock must be held");
+ Debug.Assert(myLock != 0, "Lock must be held");
waitEvent.Reset();
numWaiters++;
@@ -976,7 +967,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
/// </summary>
private void ExitAndWakeUpAppropriateWaiters()
{
- Contract.Assert(myLock != 0, "Lock must be held");
+ Debug.Assert(myLock != 0, "Lock must be held");
if (owners == 0 && numWriteWaiters > 0)
{
@@ -1012,7 +1003,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
private void ExitMyLock()
{
- Contract.Assert(myLock != 0, "Exiting spin lock that is not held");
+ Debug.Assert(myLock != 0, "Exiting spin lock that is not held");
myLock = 0;
}
};
@@ -1044,7 +1035,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
throw new AggregateException(exceptions.ToArray());
}
- [SecurityCritical]
internal static unsafe string HStringToString(IntPtr hstring)
{
Contract.Requires(Environment.IsWinRTSupported);
@@ -1092,7 +1082,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
private static bool s_haveBlueErrorApis = true;
- [SecurityCritical]
private static bool RoOriginateLanguageException(int error, string message, IntPtr languageException)
{
if (s_haveBlueErrorApis)
@@ -1110,7 +1099,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
return false;
}
- [SecurityCritical]
private static void RoReportUnhandledError(IRestrictedErrorInfo error)
{
if (s_haveBlueErrorApis)
@@ -1134,7 +1122,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
/// </summary>
/// <returns>true if the error was reported, false if not (ie running on Win8)</returns>
[FriendAccessAllowed]
- [SecuritySafeCritical]
internal static bool ReportUnhandledError(Exception e)
{
// Only report to the WinRT global exception handler in modern apps
@@ -1200,14 +1187,12 @@ namespace System.Runtime.InteropServices.WindowsRuntime
#if FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION
// Get an IActivationFactory * for a managed type
- [SecurityCritical]
internal static IntPtr GetActivationFactoryForType(Type type)
{
ManagedActivationFactory activationFactory = GetManagedActivationFactory(type);
return Marshal.GetComInterfaceForObject(activationFactory, typeof(IActivationFactory));
}
- [SecurityCritical]
internal static ManagedActivationFactory GetManagedActivationFactory(Type type)
{
ManagedActivationFactory activationFactory = new ManagedActivationFactory(type);
@@ -1224,7 +1209,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// holds the IWinRTClassActivator* that is used for the process
private static IntPtr s_pClassActivator = IntPtr.Zero;
- [SecurityCritical]
internal static IntPtr GetClassActivatorForApplication(string appBase)
{
if (s_pClassActivator == IntPtr.Zero)
@@ -1268,11 +1252,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// factories from other apartments and make transiton to those apartments and cause
// deadlocks and create objects in incorrect apartments
//
- [SecurityCritical]
public static IActivationFactory GetActivationFactory(Type type)
{
if (type == null)
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
if (type.IsWindowsRuntimeObject && type.IsImport)
{
@@ -1291,14 +1274,13 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// HSTRING marshaling methods:
- [SecurityCritical]
public static IntPtr StringToHString(String s)
{
if (!Environment.IsWinRTSupported)
throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_WinRT"));
if (s == null)
- throw new ArgumentNullException("s");
+ throw new ArgumentNullException(nameof(s));
unsafe
{
@@ -1309,7 +1291,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
}
- [SecurityCritical]
public static String PtrToStringHString(IntPtr ptr)
{
if (!Environment.IsWinRTSupported)
@@ -1320,7 +1301,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
return HStringToString(ptr);
}
- [SecurityCritical]
public static void FreeHString(IntPtr ptr)
{
if (!Environment.IsWinRTSupported)
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMetadata.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMetadata.cs
index e2ad203583..9ca959c528 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMetadata.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMetadata.cs
@@ -19,18 +19,16 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public static class WindowsRuntimeMetadata
{
// Wrapper for Win8 API RoResolveNamespace with default Windows SDK path as installed .winmd files in %WINDIR%\system32\WinMetadata.
- [System.Security.SecurityCritical]
public static IEnumerable<string> ResolveNamespace(string namespaceName, IEnumerable<string> packageGraphFilePaths)
{
return ResolveNamespace(namespaceName, null, packageGraphFilePaths);
}
// Wrapper for Win8 API RoResolveNamespace.
- [System.Security.SecurityCritical]
public static IEnumerable<string> ResolveNamespace(string namespaceName, string windowsSdkFilePath, IEnumerable<string> packageGraphFilePaths)
{
if (namespaceName == null)
- throw new ArgumentNullException("namespaceName");
+ throw new ArgumentNullException(nameof(namespaceName));
Contract.EndContractBlock();
string[] packageGraphFilePathsArray = null;
@@ -58,7 +56,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
return retFileNames;
}
- [System.Security.SecurityCritical]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void nResolveNamespace(
diff --git a/src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs b/src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs
index 75529868bd..e158a5aa8a 100644
--- a/src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs
+++ b/src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs
@@ -17,7 +17,6 @@ using System.Threading;
namespace System.Runtime.Loader
{
- [System.Security.SecuritySafeCritical]
public abstract class AssemblyLoadContext
{
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
@@ -62,7 +61,6 @@ namespace System.Runtime.Loader
InitializeLoadContext(fRepresentsTPALoadContext);
}
- [System.Security.SecuritySafeCritical]
void InitializeLoadContext(bool fRepresentsTPALoadContext)
{
// Initialize the VM side of AssemblyLoadContext if not already done.
@@ -83,6 +81,17 @@ namespace System.Runtime.Loader
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void LoadFromPath(IntPtr ptrNativeAssemblyLoadContext, string ilPath, string niPath, ObjectHandleOnStack retAssembly);
+
+ [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.
@@ -90,12 +99,12 @@ namespace System.Runtime.Loader
{
if (assemblyPath == null)
{
- throw new ArgumentNullException("assemblyPath");
+ throw new ArgumentNullException(nameof(assemblyPath));
}
- if (Path.IsRelative(assemblyPath))
+ if (PathInternal.IsPartiallyQualified(assemblyPath))
{
- throw new ArgumentException( Environment.GetResourceString("Argument_AbsolutePathRequired"), "assemblyPath");
+ throw new ArgumentException( Environment.GetResourceString("Argument_AbsolutePathRequired"), nameof(assemblyPath));
}
RuntimeAssembly loadedAssembly = null;
@@ -107,17 +116,17 @@ namespace System.Runtime.Loader
{
if (nativeImagePath == null)
{
- throw new ArgumentNullException("nativeImagePath");
+ throw new ArgumentNullException(nameof(nativeImagePath));
}
- if (Path.IsRelative(nativeImagePath))
+ if (PathInternal.IsPartiallyQualified(nativeImagePath))
{
- throw new ArgumentException( Environment.GetResourceString("Argument_AbsolutePathRequired"), "nativeImagePath");
+ throw new ArgumentException( Environment.GetResourceString("Argument_AbsolutePathRequired"), nameof(nativeImagePath));
}
- if (assemblyPath != null && Path.IsRelative(assemblyPath))
+ if (assemblyPath != null && PathInternal.IsPartiallyQualified(assemblyPath))
{
- throw new ArgumentException(Environment.GetResourceString("Argument_AbsolutePathRequired"), "assemblyPath");
+ throw new ArgumentException(Environment.GetResourceString("Argument_AbsolutePathRequired"), nameof(assemblyPath));
}
// Basic validation has succeeded - lets try to load the NI image.
@@ -136,7 +145,7 @@ namespace System.Runtime.Loader
{
if (assembly == null)
{
- throw new ArgumentNullException("assembly");
+ throw new ArgumentNullException(nameof(assembly));
}
int iAssemblyStreamLength = (int)assembly.Length;
@@ -291,15 +300,15 @@ namespace System.Runtime.Loader
{
if (unmanagedDllPath == null)
{
- throw new ArgumentNullException("unmanagedDllPath");
+ throw new ArgumentNullException(nameof(unmanagedDllPath));
}
if (unmanagedDllPath.Length == 0)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"), "unmanagedDllPath");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"), nameof(unmanagedDllPath));
}
- if (Path.IsRelative(unmanagedDllPath))
+ if (PathInternal.IsPartiallyQualified(unmanagedDllPath))
{
- throw new ArgumentException(Environment.GetResourceString("Argument_AbsolutePathRequired"), "unmanagedDllPath");
+ throw new ArgumentException(Environment.GetResourceString("Argument_AbsolutePathRequired"), nameof(unmanagedDllPath));
}
return InternalLoadUnmanagedDllFromPath(unmanagedDllPath);
@@ -355,7 +364,7 @@ namespace System.Runtime.Loader
{
if (context == null)
{
- throw new ArgumentNullException("context");
+ throw new ArgumentNullException(nameof(context));
}
// Try to override the default assembly load context
@@ -378,10 +387,10 @@ namespace System.Runtime.Loader
{
if (assemblyPath == null)
{
- throw new ArgumentNullException("assemblyPath");
+ throw new ArgumentNullException(nameof(assemblyPath));
}
-
- String fullPath = Path.GetFullPathInternal(assemblyPath);
+
+ string fullPath = Path.GetFullPath(assemblyPath);
return nGetFileInformation(fullPath);
}
@@ -394,7 +403,7 @@ namespace System.Runtime.Loader
{
if (assembly == null)
{
- throw new ArgumentNullException("assembly");
+ throw new ArgumentNullException(nameof(assembly));
}
AssemblyLoadContext loadContextForAssembly = null;
@@ -459,16 +468,43 @@ namespace System.Runtime.Loader
// Synchronization primitive for controlling initialization of Default load context
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; }
+ }
+
+ // Occurs when resolution of type fails
+ 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; }
+ }
+
+ // 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; }
+ }
}
- [System.Security.SecuritySafeCritical]
class AppPathAssemblyLoadContext : AssemblyLoadContext
{
internal AppPathAssemblyLoadContext() : base(true)
{
}
- [System.Security.SecuritySafeCritical]
protected override Assembly Load(AssemblyName assemblyName)
{
// We were loading an assembly into TPA ALC that was not found on TPA list. As a result we are here.
@@ -476,6 +512,18 @@ namespace System.Runtime.Loader
return null;
}
}
+
+ internal class IndividualAssemblyLoadContext : AssemblyLoadContext
+ {
+ internal IndividualAssemblyLoadContext() : base(false)
+ {
+ }
+
+ protected override Assembly Load(AssemblyName assemblyName)
+ {
+ return null;
+ }
+ }
}
#endif // FEATURE_HOST_ASSEMBLY_RESOLVER
diff --git a/src/mscorlib/src/System/Runtime/MemoryFailPoint.cs b/src/mscorlib/src/System/Runtime/MemoryFailPoint.cs
index 6e35568310..bd87d9027c 100644
--- a/src/mscorlib/src/System/Runtime/MemoryFailPoint.cs
+++ b/src/mscorlib/src/System/Runtime/MemoryFailPoint.cs
@@ -22,6 +22,7 @@ using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
using System.Security.Permissions;
using System.Runtime.Versioning;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
/*
@@ -143,7 +144,6 @@ namespace System.Runtime
private ulong _reservedMemory; // The size of this request (from user)
private bool _mustSubtractReservation; // Did we add data to SharedStatics?
- [System.Security.SecuritySafeCritical] // auto-generated
static MemoryFailPoint()
{
GetMemorySettings(out GCSegmentSize, out TopOfMemory);
@@ -153,13 +153,13 @@ namespace System.Runtime
// have scenarios for this in partial trust in the future, but
// we're doing this just to restrict this in case the code below
// is somehow incorrect.
- [System.Security.SecurityCritical] // auto-generated_required
public MemoryFailPoint(int sizeInMegabytes)
{
if (sizeInMegabytes <= 0)
- throw new ArgumentOutOfRangeException("sizeInMegabytes", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(sizeInMegabytes), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
+#if !FEATURE_PAL // Remove this when CheckForAvailableMemory is able to provide legitimate estimates
ulong size = ((ulong)sizeInMegabytes) << 20;
_reservedMemory = size;
@@ -283,7 +283,7 @@ namespace System.Runtime
break;
default:
- Contract.Assert(false, "Fell through switch statement!");
+ Debug.Assert(false, "Fell through switch statement!");
break;
}
}
@@ -302,9 +302,9 @@ namespace System.Runtime
SharedStatics.AddMemoryFailPointReservation((long) size);
_mustSubtractReservation = true;
}
+#endif
}
- [System.Security.SecurityCritical] // auto-generated
private static void CheckForAvailableMemory(out ulong availPageFile, out ulong totalAddressSpaceFree)
{
bool r;
@@ -321,7 +321,6 @@ namespace System.Runtime
// returns whether there is enough space. In all cases, we update
// our last known free address space, hopefully avoiding needing to
// probe again.
- [System.Security.SecurityCritical] // auto-generated
private static unsafe bool CheckForFreeAddressSpace(ulong size, bool shouldThrow)
{
// Start walking the address space at 0. VirtualAlloc may wrap
@@ -348,7 +347,6 @@ 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.
- [System.Security.SecurityCritical] // auto-generated
private static unsafe ulong MemFreeAfterAddress(void * address, ulong size)
{
if (size >= TopOfMemory)
@@ -375,11 +373,9 @@ namespace System.Runtime
return largestFreeRegion;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void GetMemorySettings(out ulong maxGCSegmentSize, out ulong topOfMemory);
- [System.Security.SecuritySafeCritical] // destructors should be safe to call
~MemoryFailPoint()
{
Dispose(false);
@@ -392,14 +388,12 @@ namespace System.Runtime
// future create an allocation context and release it in the Dispose
// method. While the finalizer will eventually free this block of
// memory, apps will help their performance greatly by calling Dispose.
- [System.Security.SecuritySafeCritical] // auto-generated
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
- [System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
private void Dispose(bool disposing)
{
diff --git a/src/mscorlib/src/System/Runtime/ProfileOptimization.cs b/src/mscorlib/src/System/Runtime/ProfileOptimization.cs
index c877d2106d..1e42308ecc 100644
--- a/src/mscorlib/src/System/Runtime/ProfileOptimization.cs
+++ b/src/mscorlib/src/System/Runtime/ProfileOptimization.cs
@@ -27,22 +27,18 @@ namespace System.Runtime {
public static class ProfileOptimization
{
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SecurityCritical]
[SuppressUnmanagedCodeSecurity]
internal static extern void InternalSetProfileRoot(string directoryPath);
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SecurityCritical]
[SuppressUnmanagedCodeSecurity]
internal static extern void InternalStartProfile(string profile, IntPtr ptrNativeAssemblyLoadContext);
- [SecurityCritical]
public static void SetProfileRoot(string directoryPath)
{
InternalSetProfileRoot(directoryPath);
}
- [SecurityCritical]
public static void StartProfile(string profile)
{
InternalStartProfile(profile, IntPtr.Zero);
diff --git a/src/mscorlib/src/System/Runtime/Reliability/CriticalFinalizerObject.cs b/src/mscorlib/src/System/Runtime/Reliability/CriticalFinalizerObject.cs
index 2524aaaecb..eb5a186b65 100644
--- a/src/mscorlib/src/System/Runtime/Reliability/CriticalFinalizerObject.cs
+++ b/src/mscorlib/src/System/Runtime/Reliability/CriticalFinalizerObject.cs
@@ -22,15 +22,9 @@ using System.Runtime.InteropServices;
namespace System.Runtime.ConstrainedExecution
{
-#if !FEATURE_CORECLR
- [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode=true)]
-#endif
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class CriticalFinalizerObject
{
- #if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical] // auto-generated
- #endif
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
protected CriticalFinalizerObject()
{
diff --git a/src/mscorlib/src/System/Runtime/Remoting/ObjectHandle.cs b/src/mscorlib/src/System/Runtime/Remoting/ObjectHandle.cs
index d10df9d57b..5555670498 100644
--- a/src/mscorlib/src/System/Runtime/Remoting/ObjectHandle.cs
+++ b/src/mscorlib/src/System/Runtime/Remoting/ObjectHandle.cs
@@ -14,23 +14,14 @@
**
===========================================================*/
-namespace System.Runtime.Remoting{
-
+namespace System.Runtime.Remoting
+{
using System;
- using System.Security.Permissions;
using System.Runtime.InteropServices;
- using System.Runtime.Remoting;
-#if FEATURE_REMOTING
- using System.Runtime.Remoting.Activation;
- using System.Runtime.Remoting.Lifetime;
-#endif
[ClassInterface(ClassInterfaceType.AutoDual)]
[System.Runtime.InteropServices.ComVisible(true)]
public class ObjectHandle:
-#if FEATURE_REMOTING
- MarshalByRefObject,
-#endif
IObjectHandle
{
private Object WrappedObject;
@@ -48,34 +39,5 @@ namespace System.Runtime.Remoting{
{
return WrappedObject;
}
-
- // ObjectHandle has a finite lifetime. For now the default
- // lifetime is being used, this can be changed in this method to
- // specify a custom lifetime.
-#if FEATURE_REMOTING
- [System.Security.SecurityCritical] // auto-generated_required
- public override Object InitializeLifetimeService()
- {
- BCLDebug.Trace("REMOTE", "ObjectHandle.InitializeLifetimeService");
-
- //
- // If the wrapped object has implemented InitializeLifetimeService to return null,
- // we don't want to go to the base class (which will result in a lease being
- // requested from the MarshalByRefObject, which starts up the LeaseManager,
- // which starts up the ThreadPool, adding three threads to the process.
- // We check if the wrapped object is a MarshalByRef object, and call InitializeLifetimeServices on it
- // and if it returns null, we return null. Otherwise we fall back to the old behavior.
- //
-
- MarshalByRefObject mbr = WrappedObject as MarshalByRefObject;
- if (mbr != null) {
- Object o = mbr.InitializeLifetimeService();
- if (o == null)
- return null;
- }
- ILease lease = (ILease)base.InitializeLifetimeService();
- return lease;
- }
-#endif // FEATURE_REMOTING
}
}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/FormatterConverter.cs b/src/mscorlib/src/System/Runtime/Serialization/FormatterConverter.cs
index 7df221c9cd..b710ed0b3a 100644
--- a/src/mscorlib/src/System/Runtime/Serialization/FormatterConverter.cs
+++ b/src/mscorlib/src/System/Runtime/Serialization/FormatterConverter.cs
@@ -25,7 +25,7 @@ namespace System.Runtime.Serialization {
public Object Convert(Object value, Type type) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ChangeType(value, type, CultureInfo.InvariantCulture);
@@ -33,7 +33,7 @@ namespace System.Runtime.Serialization {
public Object Convert(Object value, TypeCode typeCode) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ChangeType(value, typeCode, CultureInfo.InvariantCulture);
@@ -41,7 +41,7 @@ namespace System.Runtime.Serialization {
public bool ToBoolean(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToBoolean(value, CultureInfo.InvariantCulture);
@@ -49,7 +49,7 @@ namespace System.Runtime.Serialization {
public char ToChar(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToChar(value, CultureInfo.InvariantCulture);
@@ -58,7 +58,7 @@ namespace System.Runtime.Serialization {
[CLSCompliant(false)]
public sbyte ToSByte(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToSByte(value, CultureInfo.InvariantCulture);
@@ -66,7 +66,7 @@ namespace System.Runtime.Serialization {
public byte ToByte(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToByte(value, CultureInfo.InvariantCulture);
@@ -74,7 +74,7 @@ namespace System.Runtime.Serialization {
public short ToInt16(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToInt16(value, CultureInfo.InvariantCulture);
@@ -83,7 +83,7 @@ namespace System.Runtime.Serialization {
[CLSCompliant(false)]
public ushort ToUInt16(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToUInt16(value, CultureInfo.InvariantCulture);
@@ -91,7 +91,7 @@ namespace System.Runtime.Serialization {
public int ToInt32(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToInt32(value, CultureInfo.InvariantCulture);
@@ -100,7 +100,7 @@ namespace System.Runtime.Serialization {
[CLSCompliant(false)]
public uint ToUInt32(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToUInt32(value, CultureInfo.InvariantCulture);
@@ -108,7 +108,7 @@ namespace System.Runtime.Serialization {
public long ToInt64(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToInt64(value, CultureInfo.InvariantCulture);
@@ -117,7 +117,7 @@ namespace System.Runtime.Serialization {
[CLSCompliant(false)]
public ulong ToUInt64(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToUInt64(value, CultureInfo.InvariantCulture);
@@ -125,7 +125,7 @@ namespace System.Runtime.Serialization {
public float ToSingle(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToSingle(value, CultureInfo.InvariantCulture);
@@ -133,7 +133,7 @@ namespace System.Runtime.Serialization {
public double ToDouble(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToDouble(value, CultureInfo.InvariantCulture);
@@ -141,7 +141,7 @@ namespace System.Runtime.Serialization {
public Decimal ToDecimal(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToDecimal(value, CultureInfo.InvariantCulture);
@@ -149,7 +149,7 @@ namespace System.Runtime.Serialization {
public DateTime ToDateTime(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToDateTime(value, CultureInfo.InvariantCulture);
@@ -157,7 +157,7 @@ namespace System.Runtime.Serialization {
public String ToString(Object value) {
if (value==null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToString(value, CultureInfo.InvariantCulture);
diff --git a/src/mscorlib/src/System/Runtime/Serialization/FormatterServices.cs b/src/mscorlib/src/System/Runtime/Serialization/FormatterServices.cs
index c6f27b5b2a..27c3f15136 100644
--- a/src/mscorlib/src/System/Runtime/Serialization/FormatterServices.cs
+++ b/src/mscorlib/src/System/Runtime/Serialization/FormatterServices.cs
@@ -29,16 +29,15 @@ namespace System.Runtime.Serialization {
using System.IO;
using System.Text;
using System.Globalization;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
[System.Runtime.InteropServices.ComVisible(true)]
public static class FormatterServices {
#if FEATURE_SERIALIZATION
internal static Dictionary<MemberHolder, MemberInfo[]> m_MemberInfoTable = new Dictionary<MemberHolder, MemberInfo[]>(32);
- [System.Security.SecurityCritical]
private static bool unsafeTypeForwardersIsEnabled = false;
- [System.Security.SecurityCritical]
private static volatile bool unsafeTypeForwardersIsEnabledInitialized = false;
private static Object s_FormatterServicesSyncObject = null;
@@ -56,7 +55,6 @@ namespace System.Runtime.Serialization {
}
}
- [SecuritySafeCritical]
static FormatterServices()
{
// Static initialization touches security critical types, so we need an
@@ -100,7 +98,7 @@ namespace System.Runtime.Serialization {
FieldInfo [] typeFields;
RuntimeType parentType;
- Contract.Assert((object)type != null, "[GetAllSerializableMembers]type!=null");
+ Debug.Assert((object)type != null, "[GetAllSerializableMembers]type!=null");
if (type.IsInterface) {
return new MemberInfo[0];
@@ -186,7 +184,6 @@ namespace System.Runtime.Serialization {
// be included, properties must have both a getter and a setter. N.B.: A class
// which implements ISerializable or has a serialization surrogate may not use all of these members
// (or may have additional members).
- [System.Security.SecurityCritical] // auto-generated_required
public static MemberInfo[] GetSerializableMembers(Type type) {
return GetSerializableMembers(type, new StreamingContext(StreamingContextStates.All));
}
@@ -194,12 +191,11 @@ namespace System.Runtime.Serialization {
// Get all of the Serializable Members for a particular class. If we're not cloning, this is all
// non-transient, non-static fields. If we are cloning, include the transient fields as well since
// we know that we're going to live inside of the same context.
- [System.Security.SecurityCritical] // auto-generated_required
public static MemberInfo[] GetSerializableMembers(Type type, StreamingContext context) {
MemberInfo[] members;
if ((object)type==null) {
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
}
Contract.EndContractBlock();
@@ -230,14 +226,9 @@ namespace System.Runtime.Serialization {
static readonly Type[] advancedTypes = new Type[]{
typeof(System.DelegateSerializationHolder),
-#if FEATURE_REMOTING
- typeof(System.Runtime.Remoting.ObjRef),
- typeof(System.Runtime.Remoting.IEnvoyInfo),
- typeof(System.Runtime.Remoting.Lifetime.ISponsor),
-#endif
};
-
- public static void CheckTypeSecurity(Type t, TypeFilterLevel securityLevel) {
+
+ public static void CheckTypeSecurity(Type t, TypeFilterLevel securityLevel) {
if (securityLevel == TypeFilterLevel.Low){
for(int i=0;i<advancedTypes.Length;i++){
if (advancedTypes[i].IsAssignableFrom(t))
@@ -254,10 +245,9 @@ namespace System.Runtime.Serialization {
// will not create an unitialized string because it is non-sensical to create an empty
// instance of an immutable type.
//
- [System.Security.SecurityCritical] // auto-generated_required
public static Object GetUninitializedObject(Type type) {
if ((object)type == null) {
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
}
Contract.EndContractBlock();
@@ -268,44 +258,33 @@ namespace System.Runtime.Serialization {
return nativeGetUninitializedObject((RuntimeType)type);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static Object GetSafeUninitializedObject(Type type) {
if ((object)type == null) {
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
}
Contract.EndContractBlock();
-
+
if (!(type is RuntimeType)) {
throw new SerializationException(Environment.GetResourceString("Serialization_InvalidType", type.ToString()));
}
-#if FEATURE_REMOTING
- if (Object.ReferenceEquals(type, typeof(System.Runtime.Remoting.Messaging.ConstructionCall)) ||
- Object.ReferenceEquals(type, typeof(System.Runtime.Remoting.Messaging.LogicalCallContext)) ||
- Object.ReferenceEquals(type, typeof(System.Runtime.Remoting.Contexts.SynchronizationAttribute)))
- return nativeGetUninitializedObject((RuntimeType)type);
-#endif
- try {
- return nativeGetSafeUninitializedObject((RuntimeType)type);
+ try {
+ return nativeGetSafeUninitializedObject((RuntimeType)type);
}
- catch(SecurityException e) {
+ catch(SecurityException e) {
throw new SerializationException(Environment.GetResourceString("Serialization_Security", type.FullName), e);
- }
+ }
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern Object nativeGetSafeUninitializedObject(RuntimeType type);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern Object nativeGetUninitializedObject(RuntimeType type);
#if FEATURE_SERIALIZATION
- [System.Security.SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool GetEnableUnsafeTypeForwarders();
- [SecuritySafeCritical]
internal static bool UnsafeTypeForwardersIsEnabled()
{
if (!unsafeTypeForwardersIsEnabledInitialized)
@@ -318,7 +297,6 @@ namespace System.Runtime.Serialization {
}
#endif
private static Binder s_binder = Type.DefaultBinder;
- [System.Security.SecurityCritical]
internal static void SerializationSetValue(MemberInfo fi, Object target, Object value)
{
Contract.Requires(fi != null);
@@ -345,18 +323,17 @@ namespace System.Runtime.Serialization {
// Fill in the members of obj with the data contained in data.
// Returns the number of members populated.
//
- [System.Security.SecurityCritical] // auto-generated_required
public static Object PopulateObjectMembers(Object obj, MemberInfo[] members, Object[] data) {
if (obj==null) {
- throw new ArgumentNullException("obj");
+ throw new ArgumentNullException(nameof(obj));
}
if (members==null) {
- throw new ArgumentNullException("members");
+ throw new ArgumentNullException(nameof(members));
}
if (data==null) {
- throw new ArgumentNullException("data");
+ throw new ArgumentNullException(nameof(data));
}
if (members.Length!=data.Length) {
@@ -372,7 +349,7 @@ namespace System.Runtime.Serialization {
mi = members[i];
if (mi==null) {
- throw new ArgumentNullException("members", Environment.GetResourceString("ArgumentNull_NullMember", i));
+ throw new ArgumentNullException(nameof(members), Environment.GetResourceString("ArgumentNull_NullMember", i));
}
//If we find an empty, it means that the value was never set during deserialization.
@@ -400,15 +377,14 @@ namespace System.Runtime.Serialization {
// extract (must be FieldInfos or PropertyInfos). For each supplied member, extract the matching value and
// return it in a Object[] of the same size.
//
- [System.Security.SecurityCritical] // auto-generated_required
public static Object[] GetObjectData(Object obj, MemberInfo[] members) {
if (obj==null) {
- throw new ArgumentNullException("obj");
+ throw new ArgumentNullException(nameof(obj));
}
if (members==null) {
- throw new ArgumentNullException("members");
+ throw new ArgumentNullException(nameof(members));
}
Contract.EndContractBlock();
@@ -421,11 +397,11 @@ namespace System.Runtime.Serialization {
mi=members[i];
if (mi==null) {
- throw new ArgumentNullException("members", Environment.GetResourceString("ArgumentNull_NullMember", i));
+ throw new ArgumentNullException(nameof(members), Environment.GetResourceString("ArgumentNull_NullMember", i));
}
if (mi.MemberType==MemberTypes.Field) {
- Contract.Assert(mi is RuntimeFieldInfo || mi is SerializationFieldInfo,
+ Debug.Assert(mi is RuntimeFieldInfo || mi is SerializationFieldInfo,
"[FormatterServices.GetObjectData]mi is RuntimeFieldInfo || mi is SerializationFieldInfo.");
RtFieldInfo rfi = mi as RtFieldInfo;
@@ -443,12 +419,11 @@ namespace System.Runtime.Serialization {
return data;
}
- [System.Security.SecurityCritical] // auto-generated_required
[System.Runtime.InteropServices.ComVisible(false)]
public static ISerializationSurrogate GetSurrogateForCyclicalReference(ISerializationSurrogate innerSurrogate)
{
if (innerSurrogate == null)
- throw new ArgumentNullException("innerSurrogate");
+ throw new ArgumentNullException(nameof(innerSurrogate));
Contract.EndContractBlock();
return new SurrogateForCyclicalReference(innerSurrogate);
}
@@ -459,10 +434,9 @@ namespace System.Runtime.Serialization {
**Arguments:
**Exceptions:
==============================================================================*/
- [System.Security.SecurityCritical] // auto-generated_required
public static Type GetTypeFromAssembly(Assembly assem, String name) {
if (assem==null)
- throw new ArgumentNullException("assem");
+ throw new ArgumentNullException(nameof(assem));
Contract.EndContractBlock();
return assem.GetType(name, false, false);
}
@@ -499,7 +473,7 @@ namespace System.Runtime.Serialization {
internal static string GetClrAssemblyName(Type type, out bool hasTypeForwardedFrom) {
if ((object)type == null) {
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
}
object[] typeAttributes = type.GetCustomAttributes(typeof(TypeForwardedFromAttribute), false);
@@ -566,17 +540,15 @@ namespace System.Runtime.Serialization {
internal SurrogateForCyclicalReference(ISerializationSurrogate innerSurrogate)
{
if (innerSurrogate == null)
- throw new ArgumentNullException("innerSurrogate");
+ throw new ArgumentNullException(nameof(innerSurrogate));
this.innerSurrogate = innerSurrogate;
}
- [System.Security.SecurityCritical] // auto-generated
public void GetObjectData(Object obj, SerializationInfo info, StreamingContext context)
{
innerSurrogate.GetObjectData(obj, info, context);
}
- [System.Security.SecurityCritical] // auto-generated
public Object SetObjectData(Object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
{
return innerSurrogate.SetObjectData(obj, info, context, selector);
diff --git a/src/mscorlib/src/System/Runtime/Serialization/IObjectReference.cs b/src/mscorlib/src/System/Runtime/Serialization/IObjectReference.cs
index f1a1bc0590..42662a10f6 100644
--- a/src/mscorlib/src/System/Runtime/Serialization/IObjectReference.cs
+++ b/src/mscorlib/src/System/Runtime/Serialization/IObjectReference.cs
@@ -22,7 +22,6 @@ namespace System.Runtime.Serialization {
// Interface does not need to be marked with the serializable attribute
[System.Runtime.InteropServices.ComVisible(true)]
public interface IObjectReference {
- [System.Security.SecurityCritical] // auto-generated_required
Object GetRealObject(StreamingContext context);
}
}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/ISerializable.cs b/src/mscorlib/src/System/Runtime/Serialization/ISerializable.cs
index e59fa65043..fc283d41f1 100644
--- a/src/mscorlib/src/System/Runtime/Serialization/ISerializable.cs
+++ b/src/mscorlib/src/System/Runtime/Serialization/ISerializable.cs
@@ -22,7 +22,6 @@ namespace System.Runtime.Serialization {
[System.Runtime.InteropServices.ComVisible(true)]
public interface ISerializable {
- [System.Security.SecurityCritical] // auto-generated_required
void GetObjectData(SerializationInfo info, StreamingContext context);
}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/ISerializationSurrogate.cs b/src/mscorlib/src/System/Runtime/Serialization/ISerializationSurrogate.cs
index 9bb30d99e0..226bbdcc75 100644
--- a/src/mscorlib/src/System/Runtime/Serialization/ISerializationSurrogate.cs
+++ b/src/mscorlib/src/System/Runtime/Serialization/ISerializationSurrogate.cs
@@ -24,13 +24,11 @@ namespace System.Runtime.Serialization {
// Returns a SerializationInfo completely populated with all of the data needed to reinstantiate the
// the object at the other end of serialization.
//
- [System.Security.SecurityCritical] // auto-generated_required
void GetObjectData(Object obj, SerializationInfo info, StreamingContext context);
// Reinflate the object using all of the information in data. The information in
// members is used to find the particular field or property which needs to be set.
//
- [System.Security.SecurityCritical] // auto-generated_required
Object SetObjectData(Object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector);
}
}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/ISurrogateSelector.cs b/src/mscorlib/src/System/Runtime/Serialization/ISurrogateSelector.cs
index 01b960f86b..87b7845894 100644
--- a/src/mscorlib/src/System/Runtime/Serialization/ISurrogateSelector.cs
+++ b/src/mscorlib/src/System/Runtime/Serialization/ISurrogateSelector.cs
@@ -22,16 +22,13 @@ namespace System.Runtime.Serialization {
// Interface does not need to be marked with the serializable attribute
// Specifies the next ISurrogateSelector to be examined for surrogates if the current
// instance doesn't have a surrogate for the given type and assembly in the given context.
- [System.Security.SecurityCritical] // auto-generated_required
void ChainSelector(ISurrogateSelector selector);
// Returns the appropriate surrogate for the given type in the given context.
- [System.Security.SecurityCritical] // auto-generated_required
ISerializationSurrogate GetSurrogate(Type type, StreamingContext context, out ISurrogateSelector selector);
// Return the next surrogate in the chain. Returns null if no more exist.
- [System.Security.SecurityCritical] // auto-generated_required
ISurrogateSelector GetNextSelector();
}
}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/SafeSerializationManager.cs b/src/mscorlib/src/System/Runtime/Serialization/SafeSerializationManager.cs
new file mode 100644
index 0000000000..585d367605
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/Serialization/SafeSerializationManager.cs
@@ -0,0 +1,446 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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(StreamingContext streamingContext)
+ {
+ m_streamingContext = streamingContext;
+ }
+
+ 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);
+ }
+
+ internal IList<object> SerializedStates
+ {
+ get { return m_serializedStates; }
+ }
+
+ 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);
+ }
+#if FEATURE_SERIALIZATION
+ // Helper class to implement safe serialization. Concrete ISerializable types which want to allow
+ // transparent subclasses code to participate in serialization should contain an instance of
+ // SafeSerializationManager and wire up to it as described in code:#SafeSerialization.
+ [Serializable]
+ internal sealed class SafeSerializationManager : IObjectReference, ISerializable
+ {
+ // Saved states to store in the serialization stream. This is typed as object rather than
+ // ISafeSerializationData because ISafeSerializationData can't be marked serializable.
+ private IList<object> m_serializedStates;
+
+ // This is the SerializationInfo that is used when the SafeSerializationManager type has replaced
+ // itself as the target of serialziation. It is not used directly by the safe serialization code,
+ // but just held onto so that the real object being deserialzed can use it later.
+ private SerializationInfo m_savedSerializationInfo;
+
+ // Real object that we've deserialized - this is stored when we complete construction and calling
+ // the deserialization .ctors on it and is used when we need to notify the stored safe
+ // deserialization data that they should populate the object with their fields.
+ private object m_realObject;
+
+ // Real type that should be deserialized
+ private RuntimeType m_realType;
+
+ // Event fired when we need to collect state to serialize into the parent object
+ internal event EventHandler<SafeSerializationEventArgs> SerializeObjectState;
+
+ // Name that is used to store the real type being deserialized in the main SerializationInfo
+ private const string RealTypeSerializationName = "CLR_SafeSerializationManager_RealType";
+
+ internal SafeSerializationManager()
+ {
+ }
+
+ private SafeSerializationManager(SerializationInfo info, StreamingContext context)
+ {
+ // We need to determine if we're being called to really deserialize a SafeSerializationManager,
+ // or if we're being called because we've intercepted the deserialization callback for the real
+ // object being deserialized. We use the presence of the RealTypeSerializationName field in the
+ // serialization info to indicate that this is the interception callback and we just need to
+ // safe the info. If that field is not present, then we should be in a real deserialization
+ // construction.
+ RuntimeType realType = info.GetValueNoThrow(RealTypeSerializationName, typeof(RuntimeType)) as RuntimeType;
+
+ if (realType == null)
+ {
+ m_serializedStates = info.GetValue("m_serializedStates", typeof(List<object>)) as List<object>;
+ }
+ else
+ {
+ m_realType = realType;
+ m_savedSerializationInfo = info;
+ }
+ }
+
+ // Determine if the serialization manager is in an active state - that is if any code is hooked up
+ // to use it for serialization
+ internal bool IsActive
+ {
+ get { return SerializeObjectState != null; }
+ }
+
+ // CompleteSerialization is called by the base ISerializable in its GetObjectData method. It is
+ // responsible for gathering up the serialized object state of any delegates that wish to add their
+ // own state to the serialized object.
+ internal void CompleteSerialization(object serializedObject,
+ SerializationInfo info,
+ StreamingContext context)
+ {
+ Contract.Requires(serializedObject != null);
+ Contract.Requires(info != null);
+ Contract.Requires(typeof(ISerializable).IsAssignableFrom(serializedObject.GetType()));
+ Contract.Requires(serializedObject.GetType().IsAssignableFrom(info.ObjectType));
+
+ // Clear out any stale state
+ m_serializedStates = null;
+
+ // We only want to kick in our special serialization sauce if someone wants to participate in
+ // it, otherwise if we have no delegates registered there's no reason for us to get in the way
+ // of the regular serialization machinery.
+ EventHandler<SafeSerializationEventArgs> serializeObjectStateEvent = SerializeObjectState;
+ if (serializeObjectStateEvent != null)
+ {
+ // Get any extra data to add to our serialization state now
+ SafeSerializationEventArgs eventArgs = new SafeSerializationEventArgs(context);
+ serializeObjectStateEvent(serializedObject, eventArgs);
+ m_serializedStates = eventArgs.SerializedStates;
+
+ // Replace the type to be deserialized by the standard serialization code paths with
+ // ourselves, which allows us to control the deserialization process.
+ info.AddValue(RealTypeSerializationName, serializedObject.GetType(), typeof(RuntimeType));
+ info.SetType(typeof(SafeSerializationManager));
+ }
+ }
+
+ // CompleteDeserialization is called by the base ISerializable object's OnDeserialized handler to
+ // finish the deserialization of the object by notifying the saved states that they should
+ // re-populate their portions of the deserialized object.
+ internal void CompleteDeserialization(object deserializedObject)
+ {
+ Contract.Requires(deserializedObject != null);
+
+ if (m_serializedStates != null)
+ {
+ foreach (ISafeSerializationData serializedState in m_serializedStates)
+ {
+ serializedState.CompleteDeserialization(deserializedObject);
+ }
+ }
+ }
+
+ void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ info.AddValue("m_serializedStates", m_serializedStates, typeof(List<IDeserializationCallback>));
+ }
+
+ // GetRealObject intercepts the deserialization process in order to allow deserializing part of the
+ // object's inheritance heirarchy using standard ISerializable constructors, and the remaining
+ // portion using the saved serialization states.
+ object IObjectReference.GetRealObject(StreamingContext context)
+ {
+ // If we've already deserialized the real object, use that rather than deserializing it again
+ if (m_realObject != null)
+ {
+ return m_realObject;
+ }
+
+ // If we don't have a real type to deserialize, then this is really a SafeSerializationManager
+ // and we don't need to rebuild the object that we're standing in for.
+ if (m_realType == null)
+ {
+ return this;
+ }
+
+ // Look for the last type in GetRealType's inheritance hierarchy which implements a critical
+ // deserialization constructor. This will be the object that we use as the deserialization
+ // construction type to initialize via standard ISerializable semantics
+
+ // First build up the chain starting at the type below Object and working to the real type we
+ // serialized.
+ Stack inheritanceChain = new Stack();
+ RuntimeType currentType = m_realType;
+ do
+ {
+ inheritanceChain.Push(currentType);
+ currentType = currentType.BaseType as RuntimeType;
+ }
+ while (currentType != typeof(object));
+
+ // Now look for the first type that does not implement the ISerializable .ctor. When we find
+ // that, previousType will point at the last type that did implement the .ctor. We require that
+ // the .ctor we invoke also be non-transparent
+ RuntimeConstructorInfo serializationCtor = null;
+ RuntimeType previousType = null;
+ do
+ {
+ previousType = currentType;
+ currentType = inheritanceChain.Pop() as RuntimeType;
+ serializationCtor = currentType.GetSerializationCtor();
+ }
+ while (serializationCtor != null && serializationCtor.IsSecurityCritical);
+
+ // previousType is the last type that did implement the deserialization .ctor before the first
+ // type that did not, so we'll grab it's .ctor to use for deserialization.
+ BCLDebug.Assert(previousType != null, "We should have at least one inheritance from the base type");
+ serializationCtor = ObjectManager.GetConstructor(previousType);
+
+ // Allocate an instance of the final type and run the selected .ctor on that instance to get the
+ // standard ISerializable initialization done.
+ object deserialized = FormatterServices.GetUninitializedObject(m_realType);
+ serializationCtor.SerializationInvoke(deserialized, m_savedSerializationInfo, context);
+ m_savedSerializationInfo = null;
+ m_realType = null;
+
+ // Save away the real object that was deserialized so that we can fill it in later, and return
+ // it back as the object that should result from the final deserialization.
+ m_realObject = deserialized;
+ return deserialized;
+ }
+
+ [OnDeserialized]
+ private void OnDeserialized(StreamingContext context)
+ {
+ // We only need to complete deserialization if we were hooking the deserialization process. If
+ // we have not deserialized an object in the GetRealObject call, then there's nothing more for
+ // us to do here.
+ if (m_realObject != null)
+ {
+ // Fire the real object's OnDeserialized method if they registered one. Since we replaced
+ // ourselves as the target of the deserialization, OnDeserialized on the target won't
+ // automatically get triggered unless we do it manually.
+ SerializationEvents cache = SerializationEventsCache.GetSerializationEventsForType(m_realObject.GetType());
+ cache.InvokeOnDeserialized(m_realObject, context);
+ m_realObject = null;
+ }
+ }
+ }
+#endif
+}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/SerializationFieldInfo.cs b/src/mscorlib/src/System/Runtime/Serialization/SerializationFieldInfo.cs
index 5e7851bc57..82536ce3b4 100644
--- a/src/mscorlib/src/System/Runtime/Serialization/SerializationFieldInfo.cs
+++ b/src/mscorlib/src/System/Runtime/Serialization/SerializationFieldInfo.cs
@@ -21,11 +21,9 @@ namespace System.Runtime.Serialization {
using System;
using System.Reflection;
using System.Globalization;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Threading;
-#if FEATURE_REMOTING
- using System.Runtime.Remoting.Metadata;
-#endif //FEATURE_REMOTING
internal sealed class SerializationFieldInfo : FieldInfo {
@@ -38,8 +36,8 @@ namespace System.Runtime.Serialization {
public override int MetadataToken { get { return m_field.MetadataToken; } }
internal SerializationFieldInfo(RuntimeFieldInfo field, String namePrefix) {
- Contract.Assert(field!=null, "[SerializationFieldInfo.ctor]field!=null");
- Contract.Assert(namePrefix!=null, "[SerializationFieldInfo.ctor]namePrefix!=null");
+ Debug.Assert(field!=null, "[SerializationFieldInfo.ctor]field!=null");
+ Debug.Assert(namePrefix!=null, "[SerializationFieldInfo.ctor]namePrefix!=null");
m_field = field;
m_serializationName = String.Concat(namePrefix, FakeNameSeparatorString, m_field.Name);
@@ -91,7 +89,6 @@ namespace System.Runtime.Serialization {
return m_field.GetValue(obj);
}
- [System.Security.SecurityCritical]
internal Object InternalGetValue(Object obj) {
RtFieldInfo field = m_field as RtFieldInfo;
if (field != null)
@@ -107,7 +104,6 @@ namespace System.Runtime.Serialization {
m_field.SetValue(obj, value, invokeAttr, binder, culture);
}
- [System.Security.SecurityCritical]
internal void InternalSetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture) {
RtFieldInfo field = m_field as RtFieldInfo;
if (field != null)
@@ -136,31 +132,5 @@ namespace System.Runtime.Serialization {
return m_field.Attributes;
}
}
-
-#if FEATURE_REMOTING
- #region Legacy Remoting Cache
- private RemotingFieldCachedData m_cachedData;
-
- internal RemotingFieldCachedData RemotingCache
- {
- get
- {
- // This grabs an internal copy of m_cachedData and uses
- // that instead of looking at m_cachedData directly because
- // the cache may get cleared asynchronously. This prevents
- // us from having to take a lock.
- RemotingFieldCachedData cache = m_cachedData;
- if (cache == null)
- {
- cache = new RemotingFieldCachedData(this);
- RemotingFieldCachedData ret = Interlocked.CompareExchange(ref m_cachedData, cache, null);
- if (ret != null)
- cache = ret;
- }
- return cache;
- }
- }
- #endregion
-#endif //FEATURE_REMOTING
}
}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/SerializationInfo.cs b/src/mscorlib/src/System/Runtime/Serialization/SerializationInfo.cs
index 94e6825b51..55909c85fd 100644
--- a/src/mscorlib/src/System/Runtime/Serialization/SerializationInfo.cs
+++ b/src/mscorlib/src/System/Runtime/Serialization/SerializationInfo.cs
@@ -18,15 +18,11 @@ namespace System.Runtime.Serialization
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Remoting;
-#if FEATURE_REMOTING
- using System.Runtime.Remoting.Proxies;
-#endif
using System.Globalization;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Security;
-#if FEATURE_CORECLR
using System.Runtime.CompilerServices;
-#endif
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class SerializationInfo
@@ -61,12 +57,12 @@ namespace System.Runtime.Serialization
{
if ((object)type == null)
{
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
}
if (converter == null)
{
- throw new ArgumentNullException("converter");
+ throw new ArgumentNullException(nameof(converter));
}
Contract.EndContractBlock();
@@ -96,7 +92,7 @@ namespace System.Runtime.Serialization
{
if (null == value)
{
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
@@ -111,12 +107,11 @@ namespace System.Runtime.Serialization
{
return m_assemName;
}
- [SecuritySafeCritical]
set
{
if (null == value)
{
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
if (this.requireSameTokenInPartialTrust)
@@ -128,12 +123,11 @@ namespace System.Runtime.Serialization
}
}
- [SecuritySafeCritical]
public void SetType(Type type)
{
if ((object)type == null)
{
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
}
Contract.EndContractBlock();
@@ -170,15 +164,8 @@ namespace System.Runtime.Serialization
}
}
- [SecuritySafeCritical]
internal static void DemandForUnsafeAssemblyNameAssignments(string originalAssemblyName, string newAssemblyName)
{
-#if !FEATURE_CORECLR
- if (!IsAssemblyNameAssignmentSafe(originalAssemblyName, newAssemblyName))
- {
- CodeAccessPermission.Demand(PermissionType.SecuritySerialization);
- }
-#endif
}
internal static bool IsAssemblyNameAssignmentSafe(string originalAssemblyName, string newAssemblyName)
@@ -242,7 +229,7 @@ namespace System.Runtime.Serialization
private void ExpandArrays()
{
int newSize;
- Contract.Assert(m_members.Length == m_currMember, "[SerializationInfo.ExpandArrays]m_members.Length == m_currMember");
+ Debug.Assert(m_members.Length == m_currMember, "[SerializationInfo.ExpandArrays]m_members.Length == m_currMember");
newSize = (m_currMember * 2);
@@ -280,12 +267,12 @@ namespace System.Runtime.Serialization
{
if (null == name)
{
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
}
if ((object)type == null)
{
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
}
Contract.EndContractBlock();
@@ -416,19 +403,14 @@ namespace System.Runtime.Serialization
**Exceptions: None. All error checking is done with asserts. Although public in coreclr,
** it's not exposed in a contract and is only meant to be used by corefx.
==============================================================================*/
-#if FEATURE_CORECLR
// This should not be used by clients: exposing out this functionality would allow children
// to overwrite their parent's values. It is public in order to give corefx access to it for
// its ObjectManager implementation, but it should not be exposed out of a contract.
- public
-#else
- internal
-#endif
- void UpdateValue(String name, Object value, Type type)
+ public void UpdateValue(String name, Object value, Type type)
{
- Contract.Assert(null != name, "[SerializationInfo.UpdateValue]name!=null");
- Contract.Assert(null != value, "[SerializationInfo.UpdateValue]value!=null");
- Contract.Assert(null != (object)type, "[SerializationInfo.UpdateValue]type!=null");
+ Debug.Assert(null != name, "[SerializationInfo.UpdateValue]name!=null");
+ Debug.Assert(null != value, "[SerializationInfo.UpdateValue]value!=null");
+ Debug.Assert(null != (object)type, "[SerializationInfo.UpdateValue]type!=null");
int index = FindElement(name);
if (index < 0)
@@ -447,7 +429,7 @@ namespace System.Runtime.Serialization
{
if (null == name)
{
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
}
Contract.EndContractBlock();
BCLDebug.Trace("SER", "[SerializationInfo.FindElement]Looking for ", name, " CurrMember is: ", m_currMember);
@@ -477,11 +459,11 @@ namespace System.Runtime.Serialization
throw new SerializationException(Environment.GetResourceString("Serialization_NotFound", name));
}
- Contract.Assert(index < m_data.Length, "[SerializationInfo.GetElement]index<m_data.Length");
- Contract.Assert(index < m_types.Length, "[SerializationInfo.GetElement]index<m_types.Length");
+ Debug.Assert(index < m_data.Length, "[SerializationInfo.GetElement]index<m_data.Length");
+ Debug.Assert(index < m_types.Length, "[SerializationInfo.GetElement]index<m_types.Length");
foundType = m_types[index];
- Contract.Assert((object)foundType != null, "[SerializationInfo.GetElement]foundType!=null");
+ Debug.Assert((object)foundType != null, "[SerializationInfo.GetElement]foundType!=null");
return m_data[index];
}
@@ -495,11 +477,11 @@ namespace System.Runtime.Serialization
return null;
}
- Contract.Assert(index < m_data.Length, "[SerializationInfo.GetElement]index<m_data.Length");
- Contract.Assert(index < m_types.Length, "[SerializationInfo.GetElement]index<m_types.Length");
+ Debug.Assert(index < m_data.Length, "[SerializationInfo.GetElement]index<m_data.Length");
+ Debug.Assert(index < m_types.Length, "[SerializationInfo.GetElement]index<m_types.Length");
foundType = m_types[index];
- Contract.Assert((object)foundType != null, "[SerializationInfo.GetElement]foundType!=null");
+ Debug.Assert((object)foundType != null, "[SerializationInfo.GetElement]foundType!=null");
return m_data[index];
}
@@ -508,13 +490,12 @@ namespace System.Runtime.Serialization
// form requested.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public Object GetValue(String name, Type type)
{
if ((object)type == null)
{
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
}
Contract.EndContractBlock();
@@ -526,53 +507,36 @@ namespace System.Runtime.Serialization
Object value;
value = GetElement(name, out foundType);
-#if FEATURE_REMOTING
- if (RemotingServices.IsTransparentProxy(value))
+
+ if (Object.ReferenceEquals(foundType, type) || type.IsAssignableFrom(foundType) || value == null)
{
- RealProxy proxy = RemotingServices.GetRealProxy(value);
- if (RemotingServices.ProxyCheckCast(proxy, rt))
- return value;
+ return value;
}
- else
-#endif
- if (Object.ReferenceEquals(foundType, type) || type.IsAssignableFrom(foundType) || value == null)
- {
- return value;
- }
- Contract.Assert(m_converter != null, "[SerializationInfo.GetValue]m_converter!=null");
+ Debug.Assert(m_converter != null, "[SerializationInfo.GetValue]m_converter!=null");
return m_converter.Convert(value, type);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(true)]
internal Object GetValueNoThrow(String name, Type type)
{
Type foundType;
Object value;
- Contract.Assert((object)type != null, "[SerializationInfo.GetValue]type ==null");
- Contract.Assert(type is RuntimeType, "[SerializationInfo.GetValue]type is not a runtime type");
+ Debug.Assert((object)type != null, "[SerializationInfo.GetValue]type ==null");
+ Debug.Assert(type is RuntimeType, "[SerializationInfo.GetValue]type is not a runtime type");
value = GetElementNoThrow(name, out foundType);
if (value == null)
return null;
-#if FEATURE_REMOTING
- if (RemotingServices.IsTransparentProxy(value))
+
+ if (Object.ReferenceEquals(foundType, type) || type.IsAssignableFrom(foundType) || value == null)
{
- RealProxy proxy = RemotingServices.GetRealProxy(value);
- if (RemotingServices.ProxyCheckCast(proxy, (RuntimeType)type))
- return value;
+ return value;
}
- else
-#endif
- if (Object.ReferenceEquals(foundType, type) || type.IsAssignableFrom(foundType) || value == null)
- {
- return value;
- }
- Contract.Assert(m_converter != null, "[SerializationInfo.GetValue]m_converter!=null");
+ Debug.Assert(m_converter != null, "[SerializationInfo.GetValue]m_converter!=null");
return m_converter.Convert(value, type);
}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/SerializationInfoEnumerator.cs b/src/mscorlib/src/System/Runtime/Serialization/SerializationInfoEnumerator.cs
index 6b256a6e1f..32c65492e1 100644
--- a/src/mscorlib/src/System/Runtime/Serialization/SerializationInfoEnumerator.cs
+++ b/src/mscorlib/src/System/Runtime/Serialization/SerializationInfoEnumerator.cs
@@ -14,6 +14,7 @@
============================================================*/
namespace System.Runtime.Serialization {
using System;
+ using System.Diagnostics;
using System.Collections;
using System.Diagnostics.Contracts;
@@ -66,13 +67,13 @@ namespace System.Runtime.Serialization {
bool m_current;
internal SerializationInfoEnumerator(String[] members, Object[] info, Type[] types, int numItems) {
- Contract.Assert(members!=null, "[SerializationInfoEnumerator.ctor]members!=null");
- Contract.Assert(info!=null, "[SerializationInfoEnumerator.ctor]info!=null");
- Contract.Assert(types!=null, "[SerializationInfoEnumerator.ctor]types!=null");
- Contract.Assert(numItems>=0, "[SerializationInfoEnumerator.ctor]numItems>=0");
- Contract.Assert(members.Length>=numItems, "[SerializationInfoEnumerator.ctor]members.Length>=numItems");
- Contract.Assert(info.Length>=numItems, "[SerializationInfoEnumerator.ctor]info.Length>=numItems");
- Contract.Assert(types.Length>=numItems, "[SerializationInfoEnumerator.ctor]types.Length>=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;
diff --git a/src/mscorlib/src/System/Runtime/Versioning/BinaryCompatibility.cs b/src/mscorlib/src/System/Runtime/Versioning/BinaryCompatibility.cs
deleted file mode 100644
index 99e30b5488..0000000000
--- a/src/mscorlib/src/System/Runtime/Versioning/BinaryCompatibility.cs
+++ /dev/null
@@ -1,485 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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 determine which binary compatibility
-** behaviors are enabled at runtime. A type for
-** tracking which target Framework an app was built against, or an
-** appdomain-wide setting from the host telling us which .NET
-** Framework version we should emulate.
-**
-**
-===========================================================*/
-using System;
-using System.Diagnostics.Contracts;
-using System.Globalization;
-using System.Runtime.CompilerServices;
-
-namespace System.Runtime.Versioning
-{
- // Provides a simple way to test whether an application was built against specific .NET Framework
- // flavors and versions, with the intent of allowing Framework developers to mimic behavior of older
- // Framework releases. This allows us to make behavioral breaking changes in a binary compatible way,
- // for an application. This works at the per-AppDomain level, not process nor per-Assembly.
- //
- // To opt into newer behavior, applications must specify a TargetFrameworkAttribute on their assembly
- // saying what version they targeted, or a host must set this when creating an AppDomain. Note
- // that command line apps don't have this attribute!
- //
- // To use this class:
- // Developers need to figure out whether they're working on the phone, desktop, or Silverlight, and
- // what version they are introducing a breaking change in. Pick one predicate below, and use that
- // to decide whether to run the new or old behavior. Example:
- //
- // if (BinaryCompatibility.TargetsAtLeast_Phone_V7_1) {
- // // new behavior for phone 7.1 and other releases where we will integrate this change, like .NET Framework 4.5
- // }
- // else {
- // // Legacy behavior
- // }
- //
- // If you are making a breaking change in one specific branch that won't be integrated normally to
- // all other branches (ie, say you're making breaking changes to Windows Phone 8 after .NET Framework v4.5
- // has locked down for release), then add in specific predicates for each relevant platform.
- //
- // Maintainers of this class:
- // Revisit the table once per release, perhaps at the end of the last coding milestone, to verify a
- // default policy saying whether all quirks from a particular flavor & release should be enabled in
- // other releases (ie, should all Windows Phone 8.0 quirks be enabled in .NET Framework v5)?
- //
- // History:
- // Here is the order in which releases were made along with some basic integration information. The idea
- // is to track what set of compatibility features are present in each other.
- // While we cannot guarantee this list is perfectly linear (ie, a feature could be implemented in the last
- // few weeks before shipping and make it into only one of three concommittent releases due to triaging),
- // this is a good high level summary of code flow.
- //
- // Desktop Silverlight Windows Phone
- // .NET Framework 3.0 -> Silverlight 2
- // .NET Framework 3.5
- // Silverlight 3
- // Silverlight 4
- // .NET Framework 4 Phone 8.0
- // .NET Framework 4.5 Phone 8.1
- // .NET Framework 4.5.1 Phone 8.1
- //
- // (Note: Windows Phone 7.0 was built using the .NET Compact Framework, which forked around v1 or v1.1)
- //
- // Compatibility Policy decisions:
- // If we cannot determine that an app was built for a newer .NET Framework (ie, the app has no
- // TargetFrameworkAttribute), then quirks will be enabled to emulate older behavior.
- // As such, your test code should define the TargetFrameworkAttribute (which VS does for you)
- // if you want to see the new behavior!
- [FriendAccessAllowed]
- internal static class BinaryCompatibility
- {
- // Use this for new behavior introduced in the phone branch. It will do the right thing for desktop & SL.
- [FriendAccessAllowed]
- internal static bool TargetsAtLeast_Phone_V7_1 { [FriendAccessAllowed] get { return s_map.TargetsAtLeast_Phone_V7_1; } }
-
- [FriendAccessAllowed]
- internal static bool TargetsAtLeast_Phone_V8_0 { [FriendAccessAllowed] get { return s_map.TargetsAtLeast_Phone_V8_0; } }
-
- // Use this for new behavior introduced in the Desktop branch. It will do the right thing for Phone & SL.
- [FriendAccessAllowed]
- internal static bool TargetsAtLeast_Desktop_V4_5 { [FriendAccessAllowed] get { return s_map.TargetsAtLeast_Desktop_V4_5; } }
- [FriendAccessAllowed]
- internal static bool TargetsAtLeast_Desktop_V4_5_1 { [FriendAccessAllowed] get { return s_map.TargetsAtLeast_Desktop_V4_5_1; } }
- [FriendAccessAllowed]
- internal static bool TargetsAtLeast_Desktop_V4_5_2 { [FriendAccessAllowed] get { return s_map.TargetsAtLeast_Desktop_V4_5_2; } }
- [FriendAccessAllowed]
- internal static bool TargetsAtLeast_Desktop_V4_5_3 { [FriendAccessAllowed] get { return s_map.TargetsAtLeast_Desktop_V4_5_3; } }
- [FriendAccessAllowed]
- internal static bool TargetsAtLeast_Desktop_V4_5_4 { [FriendAccessAllowed] get { return s_map.TargetsAtLeast_Desktop_V4_5_4; } }
-
- [FriendAccessAllowed]
- internal static bool TargetsAtLeast_Desktop_V5_0 { [FriendAccessAllowed] get { return s_map.TargetsAtLeast_Desktop_V5_0; } }
-
- // Use this for new behavior introduced in the Silverlight branch. It will do the right thing for desktop & Phone.
- [FriendAccessAllowed]
- internal static bool TargetsAtLeast_Silverlight_V4 { [FriendAccessAllowed] get { return s_map.TargetsAtLeast_Silverlight_V4; } }
- [FriendAccessAllowed]
- internal static bool TargetsAtLeast_Silverlight_V5 { [FriendAccessAllowed] get { return s_map.TargetsAtLeast_Silverlight_V5; } }
- [FriendAccessAllowed]
- internal static bool TargetsAtLeast_Silverlight_V6 { [FriendAccessAllowed] get { return s_map.TargetsAtLeast_Silverlight_V6; } }
-
- [FriendAccessAllowed]
- internal static TargetFrameworkId AppWasBuiltForFramework {
- [FriendAccessAllowed]
- get {
- Contract.Ensures(Contract.Result<TargetFrameworkId>() > TargetFrameworkId.NotYetChecked);
-
- if (s_AppWasBuiltForFramework == TargetFrameworkId.NotYetChecked)
- ReadTargetFrameworkId();
-
- return s_AppWasBuiltForFramework;
- }
- }
-
- // Version number is major * 10000 + minor * 100 + build (ie, 4.5.1.0 would be version 40501).
- [FriendAccessAllowed]
- internal static int AppWasBuiltForVersion {
- [FriendAccessAllowed]
- get {
- Contract.Ensures(Contract.Result<int>() > 0 || s_AppWasBuiltForFramework == TargetFrameworkId.Unspecified);
-
- if (s_AppWasBuiltForFramework == TargetFrameworkId.NotYetChecked)
- ReadTargetFrameworkId();
-
- Contract.Assert(s_AppWasBuiltForFramework != TargetFrameworkId.Unrecognized);
-
- return s_AppWasBuiltForVersion;
- }
- }
-
- #region private
- private static TargetFrameworkId s_AppWasBuiltForFramework;
- // Version number is major * 10000 + minor * 100 + build (ie, 4.5.1.0 would be version 40501).
- private static int s_AppWasBuiltForVersion;
-
- readonly static BinaryCompatibilityMap s_map = new BinaryCompatibilityMap();
-
- // For parsing a target Framework moniker, from the FrameworkName class
- private const char c_componentSeparator = ',';
- private const char c_keyValueSeparator = '=';
- private const char c_versionValuePrefix = 'v';
- private const String c_versionKey = "Version";
- private const String c_profileKey = "Profile";
-
- /// <summary>
- /// BinaryCompatibilityMap is basically a bitvector. There is a boolean field for each of the
- /// properties in BinaryCompatibility
- /// </summary>
- private sealed class BinaryCompatibilityMap
- {
- // A bit for each property
- internal bool TargetsAtLeast_Phone_V7_1;
- internal bool TargetsAtLeast_Phone_V8_0;
- internal bool TargetsAtLeast_Phone_V8_1;
- internal bool TargetsAtLeast_Desktop_V4_5;
- internal bool TargetsAtLeast_Desktop_V4_5_1;
- internal bool TargetsAtLeast_Desktop_V4_5_2;
- internal bool TargetsAtLeast_Desktop_V4_5_3;
- internal bool TargetsAtLeast_Desktop_V4_5_4;
- internal bool TargetsAtLeast_Desktop_V5_0;
- internal bool TargetsAtLeast_Silverlight_V4;
- internal bool TargetsAtLeast_Silverlight_V5;
- internal bool TargetsAtLeast_Silverlight_V6;
-
- internal BinaryCompatibilityMap()
- {
- AddQuirksForFramework(AppWasBuiltForFramework, AppWasBuiltForVersion);
- }
-
- // The purpose of this method is to capture information about integrations & behavioral compatibility
- // between our multiple different release vehicles. IE, if a behavior shows up in Silverlight version 5,
- // does it show up in the .NET Framework version 4.5 and Windows Phone 8?
- // Version number is major * 10000 + minor * 100 + build (ie, 4.5.1.0 would be version 40501).
- private void AddQuirksForFramework(TargetFrameworkId builtAgainstFramework, int buildAgainstVersion)
- {
- Contract.Requires(buildAgainstVersion > 0 || builtAgainstFramework == TargetFrameworkId.Unspecified);
-
- switch (builtAgainstFramework)
- {
- case TargetFrameworkId.NetFramework:
- case TargetFrameworkId.NetCore: // Treat Windows 8 tailored apps as normal desktop apps - same product
- if (buildAgainstVersion >= 50000)
- TargetsAtLeast_Desktop_V5_0 = true;
-
- // Potential 4.5 servicing releases
- if (buildAgainstVersion >= 40504)
- TargetsAtLeast_Desktop_V4_5_4 = true;
- if (buildAgainstVersion >= 40503)
- TargetsAtLeast_Desktop_V4_5_3 = true;
- if (buildAgainstVersion >= 40502)
- TargetsAtLeast_Desktop_V4_5_2 = true;
- if (buildAgainstVersion >= 40501)
- TargetsAtLeast_Desktop_V4_5_1 = true;
-
- if (buildAgainstVersion >= 40500)
- {
- TargetsAtLeast_Desktop_V4_5 = true;
- // On XX/XX/XX we integrated all changes from the phone V7_1 into the branch from which contains Desktop V4_5, thus
- // Any application built for V4_5 (or above) should have all the quirks for Phone V7_1 turned on.
- AddQuirksForFramework(TargetFrameworkId.Phone, 70100);
- // All Silverlight 5 behavior should be in the .NET Framework version 4.5
- AddQuirksForFramework(TargetFrameworkId.Silverlight, 50000);
- }
- break;
-
- case TargetFrameworkId.Phone:
- if (buildAgainstVersion >= 80000)
- {
- // This is for Apollo apps. For Apollo apps we don't want to enable any of the 4.5 or 4.5.1 quirks
- TargetsAtLeast_Phone_V8_0 = true;
- //TargetsAtLeast_Desktop_V4_5 = true;
- }
- if (buildAgainstVersion >= 80100)
- {
- // For WindowsPhone 8.1 and SL 8.1 scenarios we want to enable both 4.5 and 4.5.1 quirks.
- TargetsAtLeast_Desktop_V4_5 = true;
- TargetsAtLeast_Desktop_V4_5_1 = true;
- }
-
- if (buildAgainstVersion >= 710)
- TargetsAtLeast_Phone_V7_1 = true;
- break;
-
- case TargetFrameworkId.Silverlight:
- if (buildAgainstVersion >= 40000)
- TargetsAtLeast_Silverlight_V4 = true;
-
- if (buildAgainstVersion >= 50000)
- TargetsAtLeast_Silverlight_V5 = true;
-
- if (buildAgainstVersion >= 60000)
- {
- TargetsAtLeast_Silverlight_V6 = true;
- }
- break;
-
- case TargetFrameworkId.Unspecified:
- break;
-
- case TargetFrameworkId.NotYetChecked:
- case TargetFrameworkId.Unrecognized:
- Contract.Assert(false, "Bad framework kind");
- break;
- default:
- Contract.Assert(false, "Error: we introduced a new Target Framework but did not update our binary compatibility map");
- break;
- }
- }
- }
-
- #region String Parsing
-
- // If this doesn't work, perhaps we could fall back to parsing the metadata version number.
- private static bool ParseTargetFrameworkMonikerIntoEnum(String targetFrameworkMoniker, out TargetFrameworkId targetFramework, out int targetFrameworkVersion)
- {
- Contract.Requires(!String.IsNullOrEmpty(targetFrameworkMoniker));
-
- targetFramework = TargetFrameworkId.NotYetChecked;
- targetFrameworkVersion = 0;
-
- String identifier = null;
- String profile = null;
- ParseFrameworkName(targetFrameworkMoniker, out identifier, out targetFrameworkVersion, out profile);
-
- switch (identifier)
- {
- case ".NETFramework":
- targetFramework = TargetFrameworkId.NetFramework;
- break;
-
- case ".NETPortable":
- targetFramework = TargetFrameworkId.Portable;
- break;
-
- case ".NETCore":
- targetFramework = TargetFrameworkId.NetCore;
- break;
-
- case "WindowsPhone":
- if (targetFrameworkVersion >= 80100)
- {
- // A TFM of the form WindowsPhone,Version=v8.1 corresponds to SL 8.1 scenario
- // and gets the same quirks as WindowsPhoneApp\v8.1 store apps.
- targetFramework = TargetFrameworkId.Phone;
- }
- else
- {
- // There is no TFM for Apollo or below and hence we assign the targetFramework to Unspecified.
- targetFramework = TargetFrameworkId.Unspecified;
- }
- break;
-
- case "WindowsPhoneApp":
- targetFramework = TargetFrameworkId.Phone;
- break;
-
- case "Silverlight":
- targetFramework = TargetFrameworkId.Silverlight;
- // Windows Phone 7 is Silverlight,Version=v4.0,Profile=WindowsPhone
- // Windows Phone 7.1 is Silverlight,Version=v4.0,Profile=WindowsPhone71
- if (!String.IsNullOrEmpty(profile))
- {
- if (profile == "WindowsPhone")
- {
- targetFramework = TargetFrameworkId.Phone;
- targetFrameworkVersion = 70000;
- }
- else if (profile == "WindowsPhone71")
- {
- targetFramework = TargetFrameworkId.Phone;
- targetFrameworkVersion = 70100;
- }
- else if (profile == "WindowsPhone8")
- {
- targetFramework = TargetFrameworkId.Phone;
- targetFrameworkVersion = 80000;
- }
- else if (profile.StartsWith("WindowsPhone", StringComparison.Ordinal))
- {
- Contract.Assert(false, "This is a phone app, but we can't tell what version this is!");
- targetFramework = TargetFrameworkId.Unrecognized;
- targetFrameworkVersion = 70100;
- }
- else
- {
- Contract.Assert(false, String.Format(CultureInfo.InvariantCulture, "Unrecognized Silverlight profile \"{0}\". What is this, an XBox app?", profile));
- targetFramework = TargetFrameworkId.Unrecognized;
- }
- }
- break;
-
- default:
- Contract.Assert(false, String.Format(CultureInfo.InvariantCulture, "Unrecognized Target Framework Moniker in our Binary Compatibility class. Framework name: \"{0}\"", targetFrameworkMoniker));
- targetFramework = TargetFrameworkId.Unrecognized;
- break;
- }
-
- return true;
- }
-
- // This code was a constructor copied from the FrameworkName class, which is located in System.dll.
- // Parses strings in the following format: "<identifier>, Version=[v|V]<version>, Profile=<profile>"
- // - The identifier and version is required, profile is optional
- // - Only three components are allowed.
- // - The version string must be in the System.Version format; an optional "v" or "V" prefix is allowed
- private static void ParseFrameworkName(String frameworkName, out String identifier, out int version, out String profile)
- {
- if (frameworkName == null)
- {
- throw new ArgumentNullException("frameworkName");
- }
- if (frameworkName.Length == 0)
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_StringZeroLength"), "frameworkName");
- }
- Contract.EndContractBlock();
-
- String[] components = frameworkName.Split(c_componentSeparator);
- version = 0;
-
- // Identifer and Version are required, Profile is optional.
- if (components.Length < 2 || components.Length > 3)
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_FrameworkNameTooShort"), "frameworkName");
- }
-
- //
- // 1) Parse the "Identifier", which must come first. Trim any whitespace
- //
- identifier = components[0].Trim();
-
- if (identifier.Length == 0)
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_FrameworkNameInvalid"), "frameworkName");
- }
-
- bool versionFound = false;
- profile = null;
-
- //
- // The required "Version" and optional "Profile" component can be in any order
- //
- for (int i = 1; i < components.Length; i++)
- {
- // Get the key/value pair separated by '='
- string[] keyValuePair = components[i].Split(c_keyValueSeparator);
-
- if (keyValuePair.Length != 2)
- {
- throw new ArgumentException(Environment.GetResourceString("SR.Argument_FrameworkNameInvalid"), "frameworkName");
- }
-
- // Get the key and value, trimming any whitespace
- string key = keyValuePair[0].Trim();
- string value = keyValuePair[1].Trim();
-
- //
- // 2) Parse the required "Version" key value
- //
- if (key.Equals(c_versionKey, StringComparison.OrdinalIgnoreCase))
- {
- versionFound = true;
-
- // Allow the version to include a 'v' or 'V' prefix...
- if (value.Length > 0 && (value[0] == c_versionValuePrefix || value[0] == 'V'))
- {
- value = value.Substring(1);
- }
- Version realVersion = new Version(value);
- // The version class will represent some unset values as -1 internally (instead of 0).
- version = realVersion.Major * 10000;
- if (realVersion.Minor > 0)
- version += realVersion.Minor * 100;
- if (realVersion.Build > 0)
- version += realVersion.Build;
- }
- //
- // 3) Parse the optional "Profile" key value
- //
- else if (key.Equals(c_profileKey, StringComparison.OrdinalIgnoreCase))
- {
- if (!String.IsNullOrEmpty(value))
- {
- profile = value;
- }
- }
- else
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_FrameworkNameInvalid"), "frameworkName");
- }
- }
-
- if (!versionFound)
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_FrameworkNameMissingVersion"), "frameworkName");
- }
- }
-
- [System.Security.SecuritySafeCritical]
- private static void ReadTargetFrameworkId()
- {
- String targetFrameworkName = AppDomain.CurrentDomain.GetTargetFrameworkName();
-
- var overrideValue = System.Runtime.Versioning.CompatibilitySwitch.GetValueInternal("TargetFrameworkMoniker");
- if (!string.IsNullOrEmpty(overrideValue))
- {
- targetFrameworkName = overrideValue;
- }
-
- // Write to a local then to _targetFramework, after writing the version number.
- TargetFrameworkId fxId;
- int fxVersion = 0;
- if (targetFrameworkName == null)
- {
-#if FEATURE_CORECLR
- // if we don't have a value for targetFrameworkName we need to figure out if we should give the newest behavior or not.
- if (CompatibilitySwitches.UseLatestBehaviorWhenTFMNotSpecified)
- {
- fxId = TargetFrameworkId.NetFramework;
- fxVersion = 50000; // We are going to default to the latest value for version that we have in our code.
- }
- else
-#endif
- fxId = TargetFrameworkId.Unspecified;
- }
- else if (!ParseTargetFrameworkMonikerIntoEnum(targetFrameworkName, out fxId, out fxVersion))
- fxId = TargetFrameworkId.Unrecognized;
-
- s_AppWasBuiltForFramework = fxId;
- s_AppWasBuiltForVersion = fxVersion;
- }
- #endregion String Parsing
-
- #endregion private
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/Versioning/CompatibilitySwitch.cs b/src/mscorlib/src/System/Runtime/Versioning/CompatibilitySwitch.cs
index b06c42437c..6bf8f8cf45 100644
--- a/src/mscorlib/src/System/Runtime/Versioning/CompatibilitySwitch.cs
+++ b/src/mscorlib/src/System/Runtime/Versioning/CompatibilitySwitch.cs
@@ -21,13 +21,11 @@ namespace System.Runtime.Versioning
*
* These apis are for internal use only for FX assmeblies. It has not been decided if they can be used by OOB components due to EULA restrictions
*/
- [System.Security.SecurityCritical]
public static bool IsEnabled(string compatibilitySwitchName)
{
return IsEnabledInternalCall(compatibilitySwitchName, true);
}
- [System.Security.SecurityCritical]
public static string GetValue(string compatibilitySwitchName)
{
// This is used by AppContext.TryGetSwitch to check switch overrides in the Windows Quirk DB
@@ -36,19 +34,16 @@ namespace System.Runtime.Versioning
return GetValueInternalCall(compatibilitySwitchName, true);
}
- [System.Security.SecurityCritical]
internal static bool IsEnabledInternal(string compatibilitySwitchName)
{
return IsEnabledInternalCall(compatibilitySwitchName, false);
}
- [System.Security.SecurityCritical]
internal static string GetValueInternal(string compatibilitySwitchName)
{
return GetValueInternalCall(compatibilitySwitchName, false);
}
- [System.Security.SecurityCritical]
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern string GetAppContextOverridesInternalCall();
diff --git a/src/mscorlib/src/System/Runtime/Versioning/ComponentGuaranteesAttribute.cs b/src/mscorlib/src/System/Runtime/Versioning/ComponentGuaranteesAttribute.cs
deleted file mode 100644
index 0f906d518a..0000000000
--- a/src/mscorlib/src/System/Runtime/Versioning/ComponentGuaranteesAttribute.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: Tracking whether a component signs up for a
-** a strong contract spanning multiple versions.
-**
-===========================================================*/
-using System;
-
-namespace System.Runtime.Versioning {
-
- [Flags]
- [Serializable]
- public enum ComponentGuaranteesOptions
- {
- None = 0,
- Exchange = 0x1,
- Stable = 0x2,
- SideBySide = 0x4,
- }
-
- [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class |
- AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Delegate |
- AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property |
- AttributeTargets.Constructor | AttributeTargets.Event,
- AllowMultiple = false, Inherited = false)]
- public sealed class ComponentGuaranteesAttribute : Attribute {
- private ComponentGuaranteesOptions _guarantees;
-
- public ComponentGuaranteesAttribute(ComponentGuaranteesOptions guarantees)
- {
- _guarantees = guarantees;
- }
-
- public ComponentGuaranteesOptions Guarantees {
- get { return _guarantees; }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/Versioning/ResourceAttributes.cs b/src/mscorlib/src/System/Runtime/Versioning/ResourceAttributes.cs
deleted file mode 100644
index 78a9ddbd07..0000000000
--- a/src/mscorlib/src/System/Runtime/Versioning/ResourceAttributes.cs
+++ /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.
-
-/*============================================================
-**
-** Purpose: Resource annotation rules.
-**
-===========================================================*/
-using System;
-using System.Diagnostics;
-using System.Globalization;
-using System.Runtime.CompilerServices;
-using System.Text;
-using Microsoft.Win32;
-using System.Diagnostics.Contracts;
-
-namespace System.Runtime.Versioning
-{
- [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Constructor, Inherited = false)]
- [Conditional("RESOURCE_ANNOTATION_WORK")]
- public sealed class ResourceConsumptionAttribute : Attribute
- {
- private ResourceScope _consumptionScope;
- private ResourceScope _resourceScope;
-
- public ResourceConsumptionAttribute(ResourceScope resourceScope)
- {
- _resourceScope = resourceScope;
- _consumptionScope = _resourceScope;
- }
-
- public ResourceConsumptionAttribute(ResourceScope resourceScope, ResourceScope consumptionScope)
- {
- _resourceScope = resourceScope;
- _consumptionScope = consumptionScope;
- }
-
- public ResourceScope ResourceScope {
- get { return _resourceScope; }
- }
-
- public ResourceScope ConsumptionScope {
- get { return _consumptionScope; }
- }
- }
-
- [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Constructor, Inherited = false)]
- [Conditional("RESOURCE_ANNOTATION_WORK")]
- public sealed class ResourceExposureAttribute : Attribute
- {
- private ResourceScope _resourceExposureLevel;
-
- public ResourceExposureAttribute(ResourceScope exposureLevel)
- {
- _resourceExposureLevel = exposureLevel;
- }
-
- public ResourceScope ResourceExposureLevel {
- get { return _resourceExposureLevel; }
- }
- }
-
-
- // Default visibility is Public, which isn't specified in this enum.
- // Public == the lack of Private or Assembly
- // Does this actually work? Need to investigate that.
- [Flags]
- public enum ResourceScope
- {
- None = 0,
- // Resource type
- Machine = 0x1,
- Process = 0x2,
- AppDomain = 0x4,
- Library = 0x8,
- // Visibility
- Private = 0x10, // Private to this one class.
- Assembly = 0x20, // Assembly-level, like C#'s "internal"
- }
-
-
- [Flags]
- internal enum SxSRequirements
- {
- None = 0,
- AppDomainID = 0x1,
- ProcessID = 0x2,
- CLRInstanceID = 0x4, // for multiple CLR's within the process
- AssemblyName = 0x8,
- TypeName = 0x10
- }
-
- public static class VersioningHelper
- {
- // These depend on the exact values given to members of the ResourceScope enum.
- private const ResourceScope ResTypeMask = ResourceScope.Machine | ResourceScope.Process | ResourceScope.AppDomain | ResourceScope.Library;
- private const ResourceScope VisibilityMask = ResourceScope.Private | ResourceScope.Assembly;
-
- [System.Security.SecuritySafeCritical]
- [MethodImpl(MethodImplOptions.InternalCall)]
- private static extern int GetRuntimeId();
-
- public static String MakeVersionSafeName(String name, ResourceScope from, ResourceScope to)
- {
- return MakeVersionSafeName(name, from, to, null);
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public static String MakeVersionSafeName(String name, ResourceScope from, ResourceScope to, Type type)
- {
- ResourceScope fromResType = from & ResTypeMask;
- ResourceScope toResType = to & ResTypeMask;
- if (fromResType > toResType)
- throw new ArgumentException(Environment.GetResourceString("Argument_ResourceScopeWrongDirection", fromResType, toResType), "from");
-
- SxSRequirements requires = GetRequirements(to, from);
-
- if ((requires & (SxSRequirements.AssemblyName | SxSRequirements.TypeName)) != 0 && type == null)
- throw new ArgumentNullException("type", Environment.GetResourceString("ArgumentNull_TypeRequiredByResourceScope"));
-
- // Add in process ID, CLR base address, and appdomain ID's. Also, use a character identifier
- // to ensure that these can never accidentally overlap (ie, you create enough appdomains and your
- // appdomain ID might equal your process ID).
- StringBuilder safeName = new StringBuilder(name);
- char separator = '_';
- if ((requires & SxSRequirements.ProcessID) != 0) {
- safeName.Append(separator);
- safeName.Append('p');
- safeName.Append(Win32Native.GetCurrentProcessId());
- }
- if ((requires & SxSRequirements.CLRInstanceID) != 0) {
- String clrID = GetCLRInstanceString();
- safeName.Append(separator);
- safeName.Append('r');
- safeName.Append(clrID);
- }
- if ((requires & SxSRequirements.AppDomainID) != 0) {
- safeName.Append(separator);
- safeName.Append("ad");
- safeName.Append(AppDomain.CurrentDomain.Id);
- }
- if ((requires & SxSRequirements.TypeName) != 0) {
- safeName.Append(separator);
- safeName.Append(type.Name);
- }
- if ((requires & SxSRequirements.AssemblyName) != 0) {
- safeName.Append(separator);
- safeName.Append(type.Assembly.FullName);
- }
- return safeName.ToString();
- }
-
- private static String GetCLRInstanceString()
- {
- int id = GetRuntimeId();
- return id.ToString(CultureInfo.InvariantCulture);
- }
-
- private static SxSRequirements GetRequirements(ResourceScope consumeAsScope, ResourceScope calleeScope)
- {
- SxSRequirements requires = SxSRequirements.None;
-
- switch(calleeScope & ResTypeMask) {
- case ResourceScope.Machine:
- switch(consumeAsScope & ResTypeMask) {
- case ResourceScope.Machine:
- // No work
- break;
-
- case ResourceScope.Process:
- requires |= SxSRequirements.ProcessID;
- break;
-
- case ResourceScope.AppDomain:
- requires |= SxSRequirements.AppDomainID | SxSRequirements.CLRInstanceID | SxSRequirements.ProcessID;
- break;
-
- default:
- throw new ArgumentException(Environment.GetResourceString("Argument_BadResourceScopeTypeBits", consumeAsScope), "consumeAsScope");
- }
- break;
-
- case ResourceScope.Process:
- if ((consumeAsScope & ResourceScope.AppDomain) != 0)
- requires |= SxSRequirements.AppDomainID | SxSRequirements.CLRInstanceID;
- break;
-
- case ResourceScope.AppDomain:
- // No work
- break;
-
- default:
- throw new ArgumentException(Environment.GetResourceString("Argument_BadResourceScopeTypeBits", calleeScope), "calleeScope");
- }
-
- switch(calleeScope & VisibilityMask) {
- case ResourceScope.None: // Public - implied
- switch(consumeAsScope & VisibilityMask) {
- case ResourceScope.None: // Public - implied
- // No work
- break;
-
- case ResourceScope.Assembly:
- requires |= SxSRequirements.AssemblyName;
- break;
-
- case ResourceScope.Private:
- requires |= SxSRequirements.TypeName | SxSRequirements.AssemblyName;
- break;
-
- default:
- throw new ArgumentException(Environment.GetResourceString("Argument_BadResourceScopeVisibilityBits", consumeAsScope), "consumeAsScope");
- }
- break;
-
- case ResourceScope.Assembly:
- if ((consumeAsScope & ResourceScope.Private) != 0)
- requires |= SxSRequirements.TypeName;
- break;
-
- case ResourceScope.Private:
- // No work
- break;
-
- default:
- throw new ArgumentException(Environment.GetResourceString("Argument_BadResourceScopeVisibilityBits", calleeScope), "calleeScope");
- }
-
- if (consumeAsScope == calleeScope) {
- Contract.Assert(requires == SxSRequirements.None, "Computed a strange set of required resource scoping. It's probably wrong.");
- }
-
- return requires;
- }
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/Versioning/TargetFrameworkAttribute.cs b/src/mscorlib/src/System/Runtime/Versioning/TargetFrameworkAttribute.cs
index dbf98c08d8..600ba3f154 100644
--- a/src/mscorlib/src/System/Runtime/Versioning/TargetFrameworkAttribute.cs
+++ b/src/mscorlib/src/System/Runtime/Versioning/TargetFrameworkAttribute.cs
@@ -26,7 +26,7 @@ namespace System.Runtime.Versioning {
public TargetFrameworkAttribute(String frameworkName)
{
if (frameworkName == null)
- throw new ArgumentNullException("frameworkName");
+ throw new ArgumentNullException(nameof(frameworkName));
Contract.EndContractBlock();
_frameworkName = frameworkName;
}
diff --git a/src/mscorlib/src/System/RuntimeHandles.cs b/src/mscorlib/src/System/RuntimeHandles.cs
index 24ca45e309..127da1e0da 100644
--- a/src/mscorlib/src/System/RuntimeHandles.cs
+++ b/src/mscorlib/src/System/RuntimeHandles.cs
@@ -48,11 +48,9 @@ namespace System
return type;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool IsInstanceOfType(RuntimeType type, Object o);
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static Type GetTypeHelper(Type typeStart, Type[] genericArgs, IntPtr pModifiers, int cModifiers)
{
Type type = typeStart;
@@ -127,14 +125,12 @@ namespace System
public IntPtr Value
{
- [SecurityCritical]
get
{
return m_type != null ? m_type.m_handle : IntPtr.Zero;
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern IntPtr GetValueInternal(RuntimeTypeHandle handle);
@@ -148,7 +144,6 @@ namespace System
return m_type == null;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static bool IsPrimitive(RuntimeType type)
{
CorElementType corElemType = GetCorElementType(type);
@@ -157,35 +152,30 @@ namespace System
corElemType == CorElementType.U;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static bool IsByRef(RuntimeType type)
{
CorElementType corElemType = GetCorElementType(type);
return (corElemType == CorElementType.ByRef);
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static bool IsPointer(RuntimeType type)
{
CorElementType corElemType = GetCorElementType(type);
return (corElemType == CorElementType.Ptr);
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static bool IsArray(RuntimeType type)
{
CorElementType corElemType = GetCorElementType(type);
return (corElemType == CorElementType.Array || corElemType == CorElementType.SzArray);
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static bool IsSzArray(RuntimeType type)
{
CorElementType corElemType = GetCorElementType(type);
return (corElemType == CorElementType.SzArray);
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static bool HasElementType(RuntimeType type)
{
CorElementType corElemType = GetCorElementType(type);
@@ -195,7 +185,6 @@ namespace System
|| (corElemType == CorElementType.ByRef)); // IsByRef
}
- [SecurityCritical]
internal static IntPtr[] CopyRuntimeTypeHandles(RuntimeTypeHandle[] inHandles, out int length)
{
if (inHandles == null || inHandles.Length == 0)
@@ -213,7 +202,6 @@ namespace System
return outHandles;
}
- [SecurityCritical]
internal static IntPtr[] CopyRuntimeTypeHandles(Type[] inHandles, out int length)
{
if (inHandles == null || inHandles.Length == 0)
@@ -231,19 +219,15 @@ namespace System
return outHandles;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern Object CreateInstance(RuntimeType type, bool publicOnly, bool noCheck, ref bool canBeCached, ref RuntimeMethodHandleInternal ctor, ref bool bNeedSecurityCheck);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern Object CreateCaInstance(RuntimeType type, IRuntimeMethodInfo ctor);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern Object Allocate(RuntimeType type);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern Object CreateInstanceForAnotherGenericParameter(RuntimeType type, RuntimeType genericParameter);
@@ -252,15 +236,12 @@ namespace System
return m_type;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static CorElementType GetCorElementType(RuntimeType type);
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static RuntimeAssembly GetAssembly(RuntimeType type);
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal extern static RuntimeModule GetModule(RuntimeType type);
@@ -272,31 +253,24 @@ namespace System
return new ModuleHandle(RuntimeTypeHandle.GetModule(m_type));
}
- [System.Security.SecuritySafeCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static RuntimeType GetBaseType(RuntimeType type);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static TypeAttributes GetAttributes(RuntimeType type);
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static RuntimeType GetElementType(RuntimeType type);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool CompareCanonicalHandles(RuntimeType left, RuntimeType right);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static int GetArrayRank(RuntimeType type);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static int GetToken(RuntimeType type);
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static RuntimeMethodHandleInternal GetMethodAt(RuntimeType type, int slot);
@@ -306,14 +280,12 @@ namespace System
bool _firstCall;
RuntimeMethodHandleInternal _handle;
- [System.Security.SecuritySafeCritical] // auto-generated
internal IntroducedMethodEnumerator(RuntimeType type)
{
_handle = RuntimeTypeHandle.GetFirstIntroducedMethod(type);
_firstCall = true;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public bool MoveNext()
{
if (_firstCall)
@@ -346,28 +318,22 @@ namespace System
return new IntroducedMethodEnumerator(type);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern RuntimeMethodHandleInternal GetFirstIntroducedMethod(RuntimeType type);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void GetNextIntroducedMethod(ref RuntimeMethodHandleInternal method);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool GetFields(RuntimeType type, IntPtr* result, int* count);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static Type[] GetInterfaces(RuntimeType type);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void GetConstraints(RuntimeTypeHandle handle, ObjectHandleOnStack types);
- [System.Security.SecuritySafeCritical] // auto-generated
internal Type[] GetConstraints()
{
Type[] types = null;
@@ -376,118 +342,96 @@ namespace System
return types;
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static IntPtr GetGCHandle(RuntimeTypeHandle handle, GCHandleType type);
- [System.Security.SecurityCritical] // auto-generated
internal IntPtr GetGCHandle(GCHandleType type)
{
return GetGCHandle(GetNativeHandle(), type);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static int GetNumVirtuals(RuntimeType type);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void VerifyInterfaceIsImplemented(RuntimeTypeHandle handle, RuntimeTypeHandle interfaceHandle);
- [System.Security.SecuritySafeCritical] // auto-generated
internal void VerifyInterfaceIsImplemented(RuntimeTypeHandle interfaceHandle)
{
VerifyInterfaceIsImplemented(GetNativeHandle(), interfaceHandle.GetNativeHandle());
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static int GetInterfaceMethodImplementationSlot(RuntimeTypeHandle handle, RuntimeTypeHandle interfaceHandle, RuntimeMethodHandleInternal interfaceMethodHandle);
- [System.Security.SecuritySafeCritical] // auto-generated
internal int GetInterfaceMethodImplementationSlot(RuntimeTypeHandle interfaceHandle, RuntimeMethodHandleInternal interfaceMethodHandle)
{
return GetInterfaceMethodImplementationSlot(GetNativeHandle(), interfaceHandle.GetNativeHandle(), interfaceMethodHandle);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool IsComObject(RuntimeType type, bool isGenericCOM);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool IsContextful(RuntimeType type);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool IsInterface(RuntimeType type);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private extern static bool _IsVisible(RuntimeTypeHandle typeHandle);
- [System.Security.SecuritySafeCritical] // auto-generated
internal static bool IsVisible(RuntimeType type)
{
return _IsVisible(new RuntimeTypeHandle(type));
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool IsSecurityCritical(RuntimeTypeHandle typeHandle);
- [System.Security.SecuritySafeCritical] // auto-generated
internal bool IsSecurityCritical()
{
return IsSecurityCritical(GetNativeHandle());
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool IsSecuritySafeCritical(RuntimeTypeHandle typeHandle);
- [System.Security.SecuritySafeCritical] // auto-generated
internal bool IsSecuritySafeCritical()
{
return IsSecuritySafeCritical(GetNativeHandle());
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool IsSecurityTransparent(RuntimeTypeHandle typeHandle);
- [System.Security.SecuritySafeCritical] // auto-generated
internal bool IsSecurityTransparent()
{
return IsSecurityTransparent(GetNativeHandle());
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool HasProxyAttribute(RuntimeType type);
- [System.Security.SecuritySafeCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool IsValueType(RuntimeType type);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void ConstructName(RuntimeTypeHandle handle, TypeNameFormatFlags formatFlags, StringHandleOnStack retString);
- [System.Security.SecuritySafeCritical] // auto-generated
internal string ConstructName(TypeNameFormatFlags formatFlags)
{
string name = null;
@@ -495,34 +439,27 @@ namespace System
return name;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern static void* _GetUtf8Name(RuntimeType type);
- [System.Security.SecuritySafeCritical] // auto-generated
internal static Utf8String GetUtf8Name(RuntimeType type)
{
return new Utf8String(_GetUtf8Name(type));
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool CanCastTo(RuntimeType type, RuntimeType target);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static RuntimeType GetDeclaringType(RuntimeType type);
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static IRuntimeMethodInfo GetDeclaringMethod(RuntimeType type);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void GetDefaultConstructor(RuntimeTypeHandle handle, ObjectHandleOnStack method);
- [System.Security.SecuritySafeCritical] // auto-generated
internal IRuntimeMethodInfo GetDefaultConstructor()
{
IRuntimeMethodInfo ctor = null;
@@ -530,7 +467,6 @@ namespace System
return ctor;
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void GetTypeByName(string name, bool throwOnError, bool ignoreCase, bool reflectionOnly, StackCrawlMarkHandle stackMark,
@@ -543,7 +479,6 @@ namespace System
return GetTypeByName(name, throwOnError, ignoreCase, reflectionOnly, ref stackMark, IntPtr.Zero, loadTypeFromPartialName);
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static RuntimeType GetTypeByName(string name, bool throwOnError, bool ignoreCase, bool reflectionOnly, ref StackCrawlMark stackMark,
IntPtr pPrivHostBinder,
bool loadTypeFromPartialName)
@@ -573,16 +508,14 @@ namespace System
return GetTypeByName(name, false, false, false, ref stackMark, false);
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void GetTypeByNameUsingCARules(string name, RuntimeModule scope, ObjectHandleOnStack type);
- [System.Security.SecuritySafeCritical] // auto-generated
internal static RuntimeType GetTypeByNameUsingCARules(string name, RuntimeModule scope)
{
if (name == null || name.Length == 0)
- throw new ArgumentException("name");
+ throw new ArgumentException(null, nameof(name));
Contract.EndContractBlock();
RuntimeType type = null;
@@ -591,12 +524,10 @@ namespace System
return type;
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal extern static void GetInstantiation(RuntimeTypeHandle type, ObjectHandleOnStack types, bool fAsRuntimeTypeArray);
- [System.Security.SecuritySafeCritical] // auto-generated
internal RuntimeType[] GetInstantiationInternal()
{
RuntimeType[] types = null;
@@ -604,7 +535,6 @@ namespace System
return types;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal Type[] GetInstantiationPublic()
{
Type[] types = null;
@@ -612,12 +542,10 @@ namespace System
return types;
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void Instantiate(RuntimeTypeHandle handle, IntPtr* pInst, int numGenericArgs, ObjectHandleOnStack type);
- [System.Security.SecurityCritical] // auto-generated
internal RuntimeType Instantiate(Type[] inst)
{
// defensive copy to be sure array is not mutated from the outside during processing
@@ -633,12 +561,10 @@ namespace System
}
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void MakeArray(RuntimeTypeHandle handle, int rank, ObjectHandleOnStack type);
- [System.Security.SecuritySafeCritical] // auto-generated
internal RuntimeType MakeArray(int rank)
{
RuntimeType type = null;
@@ -646,12 +572,10 @@ namespace System
return type;
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void MakeSZArray(RuntimeTypeHandle handle, ObjectHandleOnStack type);
- [System.Security.SecuritySafeCritical] // auto-generated
internal RuntimeType MakeSZArray()
{
RuntimeType type = null;
@@ -659,12 +583,10 @@ namespace System
return type;
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void MakeByRef(RuntimeTypeHandle handle, ObjectHandleOnStack type);
- [System.Security.SecuritySafeCritical] // auto-generated
internal RuntimeType MakeByRef()
{
RuntimeType type = null;
@@ -672,12 +594,10 @@ namespace System
return type;
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void MakePointer(RuntimeTypeHandle handle, ObjectHandleOnStack type);
- [System.Security.SecurityCritical] // auto-generated
internal RuntimeType MakePointer()
{
RuntimeType type = null;
@@ -685,14 +605,10 @@ namespace System
return type;
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal extern static bool IsCollectible(RuntimeTypeHandle handle);
-#if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical] // auto-generated
-#endif
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool HasInstantiation(RuntimeType type);
@@ -701,12 +617,10 @@ namespace System
return HasInstantiation(GetTypeChecked());
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void GetGenericTypeDefinition(RuntimeTypeHandle type, ObjectHandleOnStack retType);
- [System.Security.SecuritySafeCritical] // auto-generated
internal static RuntimeType GetGenericTypeDefinition(RuntimeType type)
{
RuntimeType retType = type;
@@ -717,11 +631,9 @@ namespace System
return retType;
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool IsGenericTypeDefinition(RuntimeType type);
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool IsGenericVariable(RuntimeType type);
@@ -730,11 +642,9 @@ namespace System
return IsGenericVariable(GetTypeChecked());
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern static int GetGenericVariableIndex(RuntimeType type);
- [System.Security.SecuritySafeCritical] // auto-generated
internal int GetGenericVariableIndex()
{
RuntimeType type = GetTypeChecked();
@@ -745,21 +655,17 @@ namespace System
return GetGenericVariableIndex(type);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool ContainsGenericVariables(RuntimeType handle);
- [System.Security.SecuritySafeCritical] // auto-generated
internal bool ContainsGenericVariables()
{
return ContainsGenericVariables(GetTypeChecked());
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern static bool SatisfiesConstraints(RuntimeType paramType, IntPtr *pTypeContext, int typeContextLength, IntPtr *pMethodContext, int methodContextLength, RuntimeType toType);
- [System.Security.SecurityCritical]
internal static bool SatisfiesConstraints(RuntimeType paramType, RuntimeType[] typeContext, RuntimeType[] methodContext, RuntimeType toType)
{
int typeContextLength;
@@ -778,21 +684,18 @@ namespace System
}
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern static IntPtr _GetMetadataImport(RuntimeType type);
- [System.Security.SecurityCritical] // auto-generated
internal static MetadataImport GetMetadataImport(RuntimeType type)
{
return new MetadataImport(_GetMetadataImport(type), type);
}
- [System.Security.SecurityCritical] // auto-generated
private RuntimeTypeHandle(SerializationInfo info, StreamingContext context)
{
if(info == null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
RuntimeType m = (RuntimeType)info.GetValue("TypeObj", typeof(RuntimeType));
@@ -803,11 +706,10 @@ namespace System
throw new SerializationException(Environment.GetResourceString("Serialization_InsufficientState"));
}
- [System.Security.SecurityCritical]
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
if(info == null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
if (m_type == null)
@@ -815,16 +717,6 @@ namespace System
info.AddValue("TypeObj", m_type, typeof(RuntimeType));
}
-
-#if !FEATURE_CORECLR
- [System.Security.SecuritySafeCritical]
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal static extern bool IsEquivalentTo(RuntimeType rtType1, RuntimeType rtType2);
-
- [System.Security.SecuritySafeCritical]
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal static extern bool IsEquivalentType(RuntimeType type);
-#endif // FEATURE_CORECLR
}
// This type is used to remove the expense of having a managed reference object that is dynamically
@@ -853,14 +745,12 @@ namespace System
internal IntPtr Value
{
- [SecurityCritical]
get
{
return m_handle;
}
}
- [SecurityCritical]
internal RuntimeMethodHandleInternal(IntPtr value)
{
m_handle = value;
@@ -877,7 +767,6 @@ namespace System
m_value = methodHandleValue;
}
- [SecurityCritical]
public RuntimeMethodInfoStub(IntPtr methodHandleValue, object keepalive)
{
m_keepalive = keepalive;
@@ -895,10 +784,8 @@ namespace System
object m_e;
object m_f;
object m_g;
-#if FEATURE_REMOTING
- object m_h;
-#endif
#pragma warning restore 169
+
public RuntimeMethodHandleInternal m_value;
RuntimeMethodHandleInternal IRuntimeMethodInfo.Value
@@ -948,18 +835,16 @@ namespace System
}
// Used by EE
- [SecurityCritical]
private static IntPtr GetValueInternal(RuntimeMethodHandle rmh)
{
return rmh.Value;
}
// ISerializable interface
- [System.Security.SecurityCritical] // auto-generated
private RuntimeMethodHandle(SerializationInfo info, StreamingContext context)
{
if(info == null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
MethodBase m =(MethodBase)info.GetValue("MethodObj", typeof(MethodBase));
@@ -970,11 +855,10 @@ namespace System
throw new SerializationException(Environment.GetResourceString("Serialization_InsufficientState"));
}
- [System.Security.SecurityCritical]
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
if (m_value == null)
@@ -988,21 +872,18 @@ namespace System
public IntPtr Value
{
- [SecurityCritical]
get
{
return m_value != null ? m_value.Value.Value : IntPtr.Zero;
}
}
- [SecuritySafeCritical]
public override int GetHashCode()
{
return ValueType.GetHashCodeOfPtr(Value);
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- [SecuritySafeCritical]
public override bool Equals(object obj)
{
if (!(obj is RuntimeMethodHandle))
@@ -1024,7 +905,6 @@ namespace System
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- [SecuritySafeCritical]
public bool Equals(RuntimeMethodHandle handle)
{
return handle.Value == Value;
@@ -1036,12 +916,10 @@ namespace System
return m_value == null;
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal extern static IntPtr GetFunctionPointer(RuntimeMethodHandleInternal handle);
- [System.Security.SecurityCritical] // auto-generated
public IntPtr GetFunctionPointer()
{
IntPtr ptr = GetFunctionPointer(EnsureNonNullMethodInfo(m_value).Value);
@@ -1049,11 +927,9 @@ namespace System
return ptr;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal unsafe extern static void CheckLinktimeDemands(IRuntimeMethodInfo method, RuntimeModule module, bool isDecoratedTargetSecurityTransparent);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal extern static bool IsCAVisibleFromDecoratedType(
@@ -1062,21 +938,17 @@ namespace System
RuntimeTypeHandle sourceTypeHandle,
RuntimeModule sourceModule);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern IRuntimeMethodInfo _GetCurrentMethod(ref StackCrawlMark stackMark);
- [System.Security.SecuritySafeCritical] // auto-generated
internal static IRuntimeMethodInfo GetCurrentMethod(ref StackCrawlMark stackMark)
{
return _GetCurrentMethod(ref stackMark);
}
[Pure]
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern MethodAttributes GetAttributes(RuntimeMethodHandleInternal method);
- [System.Security.SecurityCritical] // auto-generated
internal static MethodAttributes GetAttributes(IRuntimeMethodInfo method)
{
MethodAttributes retVal = RuntimeMethodHandle.GetAttributes(method.Value);
@@ -1084,16 +956,13 @@ namespace System
return retVal;
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern MethodImplAttributes GetImplAttributes(IRuntimeMethodInfo method);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void ConstructInstantiation(IRuntimeMethodInfo method, TypeNameFormatFlags format, StringHandleOnStack retString);
- [System.Security.SecuritySafeCritical] // auto-generated
internal static string ConstructInstantiation(IRuntimeMethodInfo method, TypeNameFormatFlags format)
{
string name = null;
@@ -1101,11 +970,9 @@ namespace System
return name;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static RuntimeType GetDeclaringType(RuntimeMethodHandleInternal method);
- [System.Security.SecuritySafeCritical] // auto-generated
internal static RuntimeType GetDeclaringType(IRuntimeMethodInfo method)
{
RuntimeType type = RuntimeMethodHandle.GetDeclaringType(method.Value);
@@ -1113,11 +980,9 @@ namespace System
return type;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static int GetSlot(RuntimeMethodHandleInternal method);
- [System.Security.SecurityCritical] // auto-generated
internal static int GetSlot(IRuntimeMethodInfo method)
{
Contract.Requires(method != null);
@@ -1127,15 +992,12 @@ namespace System
return slot;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static int GetMethodDef(IRuntimeMethodInfo method);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static string GetName(RuntimeMethodHandleInternal method);
- [System.Security.SecurityCritical] // auto-generated
internal static string GetName(IRuntimeMethodInfo method)
{
string name = RuntimeMethodHandle.GetName(method.Value);
@@ -1143,53 +1005,33 @@ namespace System
return name;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern static void* _GetUtf8Name(RuntimeMethodHandleInternal method);
- [System.Security.SecurityCritical] // auto-generated
internal static Utf8String GetUtf8Name(RuntimeMethodHandleInternal method)
{
return new Utf8String(_GetUtf8Name(method));
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool MatchesNameHash(RuntimeMethodHandleInternal method, uint hash);
- [System.Security.SecuritySafeCritical] // auto-generated
[DebuggerStepThroughAttribute]
[Diagnostics.DebuggerHidden]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static object InvokeMethod(object target, object[] arguments, Signature sig, bool constructor);
#region Private Invocation Helpers
- [System.Security.SecurityCritical] // auto-generated
internal static INVOCATION_FLAGS GetSecurityFlags(IRuntimeMethodInfo handle)
{
return (INVOCATION_FLAGS)RuntimeMethodHandle.GetSpecialSecurityFlags(handle);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static extern internal uint GetSpecialSecurityFlags(IRuntimeMethodInfo method);
-#if !FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- static extern internal void PerformSecurityCheck(Object obj, RuntimeMethodHandleInternal method, RuntimeType parent, uint invocationFlags);
-
- [System.Security.SecurityCritical]
- static internal void PerformSecurityCheck(Object obj, IRuntimeMethodInfo method, RuntimeType parent, uint invocationFlags)
- {
- RuntimeMethodHandle.PerformSecurityCheck(obj, method.Value, parent, invocationFlags);
- GC.KeepAlive(method);
- return;
- }
-#endif //!FEATURE_CORECLR
#endregion
- [System.Security.SecuritySafeCritical] // auto-generated
[DebuggerStepThroughAttribute]
[Diagnostics.DebuggerHidden]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
@@ -1198,62 +1040,48 @@ namespace System
// This returns true if the token is SecurityTransparent:
// just the token - does not consider including module/type etc.
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool _IsTokenSecurityTransparent(RuntimeModule module, int metaDataToken);
-#if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical] // auto-generated
-#else
- [System.Security.SecurityCritical]
-#endif
internal static bool IsTokenSecurityTransparent(Module module, int metaDataToken)
{
return _IsTokenSecurityTransparent(module.ModuleHandle.GetRuntimeModule(), metaDataToken);
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool _IsSecurityCritical(IRuntimeMethodInfo method);
- [System.Security.SecuritySafeCritical] // auto-generated
internal static bool IsSecurityCritical(IRuntimeMethodInfo method)
{
return _IsSecurityCritical(method);
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool _IsSecuritySafeCritical(IRuntimeMethodInfo method);
- [System.Security.SecuritySafeCritical] // auto-generated
internal static bool IsSecuritySafeCritical(IRuntimeMethodInfo method)
{
return _IsSecuritySafeCritical(method);
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool _IsSecurityTransparent(IRuntimeMethodInfo method);
- [System.Security.SecuritySafeCritical] // auto-generated
internal static bool IsSecurityTransparent(IRuntimeMethodInfo method)
{
return _IsSecurityTransparent(method);
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void GetMethodInstantiation(RuntimeMethodHandleInternal method, ObjectHandleOnStack types, bool fAsRuntimeTypeArray);
- [System.Security.SecuritySafeCritical] // auto-generated
internal static RuntimeType[] GetMethodInstantiationInternal(IRuntimeMethodInfo method)
{
RuntimeType[] types = null;
@@ -1262,7 +1090,6 @@ namespace System
return types;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static RuntimeType[] GetMethodInstantiationInternal(RuntimeMethodHandleInternal method)
{
RuntimeType[] types = null;
@@ -1270,7 +1097,6 @@ namespace System
return types;
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static Type[] GetMethodInstantiationPublic(IRuntimeMethodInfo method)
{
RuntimeType[] types = null;
@@ -1279,11 +1105,9 @@ namespace System
return types;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool HasMethodInstantiation(RuntimeMethodHandleInternal method);
- [System.Security.SecuritySafeCritical] // auto-generated
internal static bool HasMethodInstantiation(IRuntimeMethodInfo method)
{
bool fRet = RuntimeMethodHandle.HasMethodInstantiation(method.Value);
@@ -1291,19 +1115,15 @@ namespace System
return fRet;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static RuntimeMethodHandleInternal GetStubIfNeeded(RuntimeMethodHandleInternal method, RuntimeType declaringType, RuntimeType[] methodInstantiation);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static RuntimeMethodHandleInternal GetMethodFromCanonical(RuntimeMethodHandleInternal method, RuntimeType declaringType);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool IsGenericMethodDefinition(RuntimeMethodHandleInternal method);
- [System.Security.SecuritySafeCritical] // auto-generated
internal static bool IsGenericMethodDefinition(IRuntimeMethodInfo method)
{
bool fRet = RuntimeMethodHandle.IsGenericMethodDefinition(method.Value);
@@ -1312,16 +1132,13 @@ namespace System
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool IsTypicalMethodDefinition(IRuntimeMethodInfo method);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void GetTypicalMethodDefinition(IRuntimeMethodInfo method, ObjectHandleOnStack outMethod);
- [System.Security.SecuritySafeCritical] // auto-generated
internal static IRuntimeMethodInfo GetTypicalMethodDefinition(IRuntimeMethodInfo method)
{
if (!IsTypicalMethodDefinition(method))
@@ -1330,12 +1147,10 @@ namespace System
return method;
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void StripMethodInstantiation(IRuntimeMethodInfo method, ObjectHandleOnStack outMethod);
- [System.Security.SecuritySafeCritical] // auto-generated
internal static IRuntimeMethodInfo StripMethodInstantiation(IRuntimeMethodInfo method)
{
IRuntimeMethodInfo strippedMethod = method;
@@ -1345,25 +1160,20 @@ namespace System
return strippedMethod;
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool IsDynamicMethod(RuntimeMethodHandleInternal method);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal extern static void Destroy(RuntimeMethodHandleInternal method);
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static Resolver GetResolver(RuntimeMethodHandleInternal method);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void GetCallerType(StackCrawlMarkHandle stackMark, ObjectHandleOnStack retType);
- [System.Security.SecuritySafeCritical] // auto-generated
internal static RuntimeType GetCallerType(ref StackCrawlMark stackMark)
{
RuntimeType type = null;
@@ -1372,14 +1182,11 @@ namespace System
}
[MethodImpl(MethodImplOptions.InternalCall)]
- [System.Security.SecuritySafeCritical] // auto-generated
internal extern static MethodBody GetMethodBody(IRuntimeMethodInfo method, RuntimeType declaringType);
- [System.Security.SecurityCritical] // auto-generated
[MethodImpl(MethodImplOptions.InternalCall)]
internal extern static bool IsConstructor(RuntimeMethodHandleInternal method);
- [System.Security.SecurityCritical] // auto-generated
[MethodImpl(MethodImplOptions.InternalCall)]
internal extern static LoaderAllocator GetLoaderAllocator(RuntimeMethodHandleInternal method);
}
@@ -1410,14 +1217,12 @@ namespace System
internal IntPtr Value
{
- [SecurityCritical]
get
{
return m_handle;
}
}
- [SecurityCritical]
internal RuntimeFieldHandleInternal(IntPtr value)
{
m_handle = value;
@@ -1437,7 +1242,6 @@ namespace System
[StructLayout(LayoutKind.Sequential)]
internal class RuntimeFieldInfoStub : IRuntimeFieldInfo
{
- [SecuritySafeCritical]
public RuntimeFieldInfoStub(IntPtr methodHandleValue, object keepalive)
{
m_keepalive = keepalive;
@@ -1451,9 +1255,6 @@ namespace System
object m_d;
int m_b;
object m_e;
-#if FEATURE_REMOTING
- object m_f;
-#endif
RuntimeFieldHandleInternal m_fieldHandle;
#pragma warning restore 169
@@ -1494,7 +1295,6 @@ namespace System
public IntPtr Value
{
- [SecurityCritical]
get
{
return m_ptr != null ? m_ptr.Value.Value : IntPtr.Zero;
@@ -1506,14 +1306,12 @@ namespace System
return m_ptr == null;
}
- [SecuritySafeCritical]
public override int GetHashCode()
{
return ValueType.GetHashCodeOfPtr(Value);
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- [SecuritySafeCritical]
public override bool Equals(object obj)
{
if (!(obj is RuntimeFieldHandle))
@@ -1525,7 +1323,6 @@ namespace System
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- [SecuritySafeCritical]
public unsafe bool Equals(RuntimeFieldHandle handle)
{
return handle.Value == Value;
@@ -1541,30 +1338,23 @@ namespace System
return !left.Equals(right);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern String GetName(RtFieldInfo field);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern unsafe void* _GetUtf8Name(RuntimeFieldHandleInternal field);
- [System.Security.SecuritySafeCritical] // auto-generated
internal static unsafe Utf8String GetUtf8Name(RuntimeFieldHandleInternal field) { return new Utf8String(_GetUtf8Name(field)); }
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool MatchesNameHash(RuntimeFieldHandleInternal handle, uint hash);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern FieldAttributes GetAttributes(RuntimeFieldHandleInternal field);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern RuntimeType GetApproxDeclaringType(RuntimeFieldHandleInternal field);
- [System.Security.SecurityCritical] // auto-generated
internal static RuntimeType GetApproxDeclaringType(IRuntimeFieldInfo field)
{
RuntimeType type = GetApproxDeclaringType(field.Value);
@@ -1572,81 +1362,66 @@ namespace System
return type;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern int GetToken(RtFieldInfo field);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern Object GetValue(RtFieldInfo field, Object instance, RuntimeType fieldType, RuntimeType declaringType, ref bool domainInitialized);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern Object GetValueDirect(RtFieldInfo field, RuntimeType fieldType, void *pTypedRef, RuntimeType contextType);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void SetValue(RtFieldInfo field, Object obj, Object value, RuntimeType fieldType, FieldAttributes fieldAttr, RuntimeType declaringType, ref bool domainInitialized);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void SetValueDirect(RtFieldInfo field, RuntimeType fieldType, void* pTypedRef, Object value, RuntimeType contextType);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern RuntimeFieldHandleInternal GetStaticFieldForGenericType(RuntimeFieldHandleInternal field, RuntimeType declaringType);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool AcquiresContextFromThis(RuntimeFieldHandleInternal field);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool IsSecurityCritical(RuntimeFieldHandle fieldHandle);
- [System.Security.SecuritySafeCritical] // auto-generated
internal bool IsSecurityCritical()
{
return IsSecurityCritical(GetNativeHandle());
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool IsSecuritySafeCritical(RuntimeFieldHandle fieldHandle);
- [System.Security.SecuritySafeCritical] // auto-generated
internal bool IsSecuritySafeCritical()
{
return IsSecuritySafeCritical(GetNativeHandle());
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool IsSecurityTransparent(RuntimeFieldHandle fieldHandle);
- [System.Security.SecuritySafeCritical] // auto-generated
internal bool IsSecurityTransparent()
{
return IsSecurityTransparent(GetNativeHandle());
}
- [SecurityCritical]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal static extern void CheckAttributeAccess(RuntimeFieldHandle fieldHandle, RuntimeModule decoratedTarget);
// ISerializable interface
- [System.Security.SecurityCritical] // auto-generated
private RuntimeFieldHandle(SerializationInfo info, StreamingContext context)
{
if(info==null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
FieldInfo f =(RuntimeFieldInfo) info.GetValue("FieldObj", typeof(RuntimeFieldInfo));
@@ -1660,11 +1435,10 @@ namespace System
throw new SerializationException(Environment.GetResourceString("Serialization_InsufficientState"));
}
- [System.Security.SecurityCritical]
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
if (m_ptr == null)
@@ -1744,11 +1518,9 @@ namespace System
return !left.Equals(right);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern IRuntimeMethodInfo GetDynamicMethod(DynamicMethod method, RuntimeModule module, string name, byte[] sig, Resolver resolver);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern int GetToken(RuntimeModule module);
@@ -1770,7 +1542,6 @@ namespace System
return new RuntimeTypeHandle(ModuleHandle.ResolveTypeHandleInternal(GetRuntimeModule(), typeToken, typeInstantiationContext, methodInstantiationContext));
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static RuntimeType ResolveTypeHandleInternal(RuntimeModule module, int typeToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext)
{
ValidateModulePointer(module);
@@ -1792,7 +1563,6 @@ namespace System
}
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void ResolveType(RuntimeModule module,
@@ -1812,7 +1582,6 @@ namespace System
return new RuntimeMethodHandle(ResolveMethodHandleInternal(GetRuntimeModule(), methodToken, typeInstantiationContext, methodInstantiationContext));
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static IRuntimeMethodInfo ResolveMethodHandleInternal(RuntimeModule module, int methodToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext)
{
int typeInstCount, methodInstCount;
@@ -1827,7 +1596,6 @@ namespace System
return retVal;
}
- [System.Security.SecurityCritical] // auto-generated
internal static RuntimeMethodHandleInternal ResolveMethodHandleInternalCore(RuntimeModule module, int methodToken, IntPtr[] typeInstantiationContext, int typeInstCount, IntPtr[] methodInstantiationContext, int methodInstCount)
{
ValidateModulePointer(module);
@@ -1841,7 +1609,6 @@ namespace System
}
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static RuntimeMethodHandleInternal ResolveMethod(RuntimeModule module,
@@ -1857,7 +1624,6 @@ namespace System
public RuntimeFieldHandle ResolveFieldHandle(int fieldToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext)
{ return new RuntimeFieldHandle(ResolveFieldHandleInternal(GetRuntimeModule(), fieldToken, typeInstantiationContext, methodInstantiationContext)); }
- [System.Security.SecuritySafeCritical] // auto-generated
internal static IRuntimeFieldInfo ResolveFieldHandleInternal(RuntimeModule module, int fieldToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext)
{
ValidateModulePointer(module);
@@ -1880,7 +1646,6 @@ namespace System
}
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void ResolveField(RuntimeModule module,
@@ -1891,23 +1656,19 @@ namespace System
int methodInstCount,
ObjectHandleOnStack retField);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static bool _ContainsPropertyMatchingHash(RuntimeModule module, int propertyToken, uint hash);
- [System.Security.SecurityCritical] // auto-generated
internal static bool ContainsPropertyMatchingHash(RuntimeModule module, int propertyToken, uint hash)
{
return _ContainsPropertyMatchingHash(module.GetNativeHandle(), propertyToken, hash);
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void GetAssembly(RuntimeModule handle, ObjectHandleOnStack retAssembly);
- [System.Security.SecuritySafeCritical] // auto-generated
internal static RuntimeAssembly GetAssembly(RuntimeModule module)
{
RuntimeAssembly retAssembly = null;
@@ -1915,12 +1676,10 @@ namespace System
return retAssembly;
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal extern static void GetModuleType(RuntimeModule handle, ObjectHandleOnStack type);
- [System.Security.SecuritySafeCritical] // auto-generated
internal static RuntimeType GetModuleType(RuntimeModule module)
{
RuntimeType type = null;
@@ -1928,13 +1687,11 @@ namespace System
return type;
}
- [System.Security.SecurityCritical] // auto-generated
[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
- [System.Security.SecuritySafeCritical] // auto-generated
internal static void GetPEKind(RuntimeModule module, out PortableExecutableKinds peKind, out ImageFileMachine machine)
{
int lKind, lMachine;
@@ -1943,21 +1700,17 @@ namespace System
machine = (ImageFileMachine)lMachine;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static int GetMDStreamVersion(RuntimeModule module);
public int MDStreamVersion
{
- [System.Security.SecuritySafeCritical] // auto-generated
get { return GetMDStreamVersion(GetRuntimeModule().GetNativeHandle()); }
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern static IntPtr _GetMetadataImport(RuntimeModule module);
- [System.Security.SecurityCritical] // auto-generated
internal static MetadataImport GetMetadataImport(RuntimeModule module)
{
return new MetadataImport(_GetMetadataImport(module.GetNativeHandle()), module);
@@ -1990,7 +1743,6 @@ namespace System
#endregion
#region FCalls
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void GetSignature(
void* pCorSig, int cCorSig,
@@ -2006,7 +1758,6 @@ namespace System
internal RuntimeType m_declaringType;
internal RuntimeType m_returnTypeORfieldType;
internal object m_keepalive;
- [SecurityCritical]
internal void* m_sig;
internal int m_managedCallingConventionAndArgIteratorFlags; // lowest byte is CallingConvention, upper 3 bytes are ArgIterator flags
internal int m_nSizeOfArgStack;
@@ -2015,7 +1766,6 @@ namespace System
#endregion
#region Constructors
- [System.Security.SecuritySafeCritical] // auto-generated
public Signature (
IRuntimeMethodInfo method,
RuntimeType[] arguments,
@@ -2030,20 +1780,17 @@ namespace System
GetSignature(null, 0, new RuntimeFieldHandleInternal(), method, null);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public Signature(IRuntimeMethodInfo methodHandle, RuntimeType declaringType)
{
GetSignature(null, 0, new RuntimeFieldHandleInternal(), methodHandle, declaringType);
}
- [System.Security.SecurityCritical] // auto-generated
public Signature(IRuntimeFieldInfo fieldHandle, RuntimeType declaringType)
{
GetSignature(null, 0, fieldHandle.Value, null, declaringType);
GC.KeepAlive(fieldHandle);
}
- [System.Security.SecurityCritical] // auto-generated
public Signature(void* pCorSig, int cCorSig, RuntimeType declaringType)
{
GetSignature(pCorSig, cCorSig, new RuntimeFieldHandleInternal(), null, declaringType);
@@ -2056,11 +1803,9 @@ namespace System
internal RuntimeType ReturnType { get { return m_returnTypeORfieldType; } }
internal RuntimeType FieldType { get { return m_returnTypeORfieldType; } }
- [System.Security.SecuritySafeCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool CompareSig(Signature sig1, Signature sig2);
- [System.Security.SecuritySafeCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern Type[] GetCustomModifiers(int position, bool required);
#endregion
@@ -2083,12 +1828,10 @@ namespace System
internal abstract RuntimeType GetJitContext(ref int securityControlFlags);
internal abstract byte[] GetCodeInfo(ref int stackSize, ref int initLocals, ref int EHCount);
internal abstract byte[] GetLocalsSignature();
- [System.Security.SecurityCritical] // takes a pointer parameter
internal abstract unsafe void GetEHInfo(int EHNumber, void* exception);
internal abstract unsafe byte[] GetRawEHInfo();
// token resolution
internal abstract String GetStringLiteral(int token);
- [System.Security.SecurityCritical] // passes a pointer out
internal abstract void ResolveToken(int token, out IntPtr typeHandle, out IntPtr methodHandle, out IntPtr fieldHandle);
internal abstract byte[] ResolveSignature(int token, int fromMethod);
//
diff --git a/src/mscorlib/src/System/SByte.cs b/src/mscorlib/src/System/SByte.cs
index a9ec9cf298..da6ac5c88f 100644
--- a/src/mscorlib/src/System/SByte.cs
+++ b/src/mscorlib/src/System/SByte.cs
@@ -73,13 +73,11 @@ namespace System {
// Provides a string representation of a byte.
- [System.Security.SecuritySafeCritical] // auto-generated
public override String ToString() {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt32(m_value, null, NumberFormatInfo.CurrentInfo);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(IFormatProvider provider) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt32(m_value, null, NumberFormatInfo.GetInstance(provider));
@@ -95,7 +93,6 @@ namespace System {
return ToString(format, NumberFormatInfo.GetInstance(provider));
}
- [System.Security.SecuritySafeCritical] // auto-generated
private String ToString(String format, NumberFormatInfo info) {
Contract.Ensures(Contract.Result<String>() != null);
diff --git a/src/mscorlib/src/System/Security/AccessControl/Enums.cs b/src/mscorlib/src/System/Security/AccessControl/Enums.cs
index c52176a29b..20f5c5f91a 100644
--- a/src/mscorlib/src/System/Security/AccessControl/Enums.cs
+++ b/src/mscorlib/src/System/Security/AccessControl/Enums.cs
@@ -70,12 +70,6 @@ namespace System.Security.AccessControl
[Flags]
public enum AccessControlActions {
-#if FEATURE_MACL
- None = 0,
- View = 1,
- Change = 2
-#else
None = 0
-#endif
}
}
diff --git a/src/mscorlib/src/System/Security/Attributes.cs b/src/mscorlib/src/System/Security/Attributes.cs
index d2229227a5..e4ebc53053 100644
--- a/src/mscorlib/src/System/Security/Attributes.cs
+++ b/src/mscorlib/src/System/Security/Attributes.cs
@@ -57,14 +57,12 @@ namespace System.Security
NotVisibleByDefault = 1
}
-#if !FEATURE_CORECLR
[Obsolete("SecurityCriticalScope is only used for .NET 2.0 transparency compatibility.")]
public enum SecurityCriticalScope
{
Explicit = 0,
Everything = 0x1
}
-#endif // FEATURE_CORECLR
// SecurityCriticalAttribute
// Indicates that the decorated code or assembly performs security critical operations (e.g. Assert, "unsafe", LinkDemand, etc.)
@@ -84,12 +82,10 @@ namespace System.Security
{
#pragma warning disable 618 // We still use SecurityCriticalScope for v2 compat
-#if !FEATURE_CORECLR
- private SecurityCriticalScope _val;
-#endif // FEATURE_CORECLR
+ private SecurityCriticalScope _val;
+
public SecurityCriticalAttribute () {}
-#if !FEATURE_CORECLR
public SecurityCriticalAttribute(SecurityCriticalScope scope)
{
_val = scope;
@@ -101,7 +97,6 @@ namespace System.Security
return _val;
}
}
-#endif // FEATURE_CORECLR
#pragma warning restore 618
}
@@ -167,7 +162,6 @@ namespace System.Security
public SecurityTransparentAttribute () {}
}
-#if !FEATURE_CORECLR
public enum SecurityRuleSet : byte
{
None = 0,
@@ -205,5 +199,4 @@ namespace System.Security
get { return m_ruleSet; }
}
}
-#endif // !FEATURE_CORECLR
}
diff --git a/src/mscorlib/src/System/Security/BuiltInPermissionSets.cs b/src/mscorlib/src/System/Security/BuiltInPermissionSets.cs
index e29dec3b06..48539574af 100644
--- a/src/mscorlib/src/System/Security/BuiltInPermissionSets.cs
+++ b/src/mscorlib/src/System/Security/BuiltInPermissionSets.cs
@@ -6,6 +6,7 @@
//
using System;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Security.Permissions;
using Microsoft.Win32;
@@ -180,30 +181,6 @@ namespace System.Security
Flags = ""SkipVerification"" />
</PermissionSet>";
-#if FEATURE_CAS_POLICY
- private const string s_wpfExtensionXml =
- @"<PermissionSet class = ""System.Security.PermissionSet""
- version = ""1"">
- <IPermission class = ""System.Security.Permissions.MediaPermission, " + AssemblyRef.WindowsBase + @"""
- version = ""1""
- Audio=""SafeAudio"" Video=""SafeVideo"" Image=""SafeImage"" />
- <IPermission class = ""System.Security.Permissions.WebBrowserPermission, " + AssemblyRef.WindowsBase + @"""
- version = ""1""
- Level=""Safe"" />
- </PermissionSet>";
-
- private const string s_wpfExtensionUnrestrictedXml =
- @"<PermissionSet class = ""System.Security.PermissionSet""
- version = ""1"">
- <IPermission class = ""System.Security.Permissions.MediaPermission, " + AssemblyRef.WindowsBase + @"""
- version = ""1""
- Unrestricted = ""true"" />
- <IPermission class = ""System.Security.Permissions.WebBrowserPermission, " + AssemblyRef.WindowsBase + @"""
- version = ""1""
- Unrestricted = ""true"" />
- </PermissionSet>";
-#endif //FEATURE_CAS_POLICY
-
//
// Built in permission set objects
//
@@ -222,11 +199,7 @@ namespace System.Security
internal static NamedPermissionSet Everything
{
- get { return GetOrDeserializeExtendablePermissionSet(ref s_everything, s_everythingXml
-#if FEATURE_CAS_POLICY
- , s_wpfExtensionUnrestrictedXml
-#endif // FEATURE_CAS_POLICY
- ); }
+ get { return GetOrDeserializeExtendablePermissionSet(ref s_everything, s_everythingXml); }
}
internal static NamedPermissionSet Execution
@@ -241,20 +214,12 @@ namespace System.Security
internal static NamedPermissionSet Internet
{
- get { return GetOrDeserializeExtendablePermissionSet(ref s_internet, s_internetXml
-#if FEATURE_CAS_POLICY
- , s_wpfExtensionXml
-#endif // FEATURE_CAS_POLICY
- ); }
+ get { return GetOrDeserializeExtendablePermissionSet(ref s_internet, s_internetXml); }
}
internal static NamedPermissionSet LocalIntranet
{
- get { return GetOrDeserializeExtendablePermissionSet(ref s_localIntranet, s_localIntranetXml
-#if FEATURE_CAS_POLICY
- , s_wpfExtensionXml
-#endif // FEATURE_CAS_POLICY
- ); }
+ get { return GetOrDeserializeExtendablePermissionSet(ref s_localIntranet, s_localIntranetXml); }
}
internal static NamedPermissionSet Nothing
@@ -272,71 +237,19 @@ namespace System.Security
// set extensions if necessary
//
- private static NamedPermissionSet GetOrDeserializeExtendablePermissionSet(ref NamedPermissionSet permissionSet,
- string permissionSetXml
-#if FEATURE_CAS_POLICY
- ,string extensionXml
-#endif // FEATURE_CAS_POLICY
- )
+ private static NamedPermissionSet GetOrDeserializeExtendablePermissionSet(
+ ref NamedPermissionSet permissionSet,
+ string permissionSetXml)
{
Contract.Requires(!String.IsNullOrEmpty(permissionSetXml));
-#if FEATURE_CAS_POLICY
- Contract.Requires(!String.IsNullOrEmpty(extensionXml));
-#endif // FEATURE_CAS_POLICY
-
- if (permissionSet == null)
- {
-#if FEATURE_CAS_POLICY
- SecurityElement securityElement = SecurityElement.FromString(permissionSetXml);
- NamedPermissionSet deserializedPermissionSet = new NamedPermissionSet(securityElement);
-
- PermissionSet extensions = GetPermissionSetExtensions(extensionXml);
- deserializedPermissionSet.InplaceUnion(extensions);
-
- permissionSet = deserializedPermissionSet;
-#endif // FEATURE_CAS_POLICY
- }
-
return permissionSet.Copy() as NamedPermissionSet;
}
private static NamedPermissionSet GetOrDeserializePermissionSet(ref NamedPermissionSet permissionSet,
string permissionSetXml)
{
- Contract.Assert(!String.IsNullOrEmpty(permissionSetXml));
-
-#if FEATURE_CAS_POLICY
- if (permissionSet == null)
- {
- SecurityElement securityElement = SecurityElement.FromString(permissionSetXml);
- NamedPermissionSet deserializedPermissionSet = new NamedPermissionSet(securityElement);
-
- permissionSet = deserializedPermissionSet;
- }
-#endif // FEATURE_CAS_POLICY
-
+ Debug.Assert(!String.IsNullOrEmpty(permissionSetXml));
return permissionSet.Copy() as NamedPermissionSet;
}
-
-#if FEATURE_CAS_POLICY
- private static PermissionSet GetPermissionSetExtensions(string extensionXml)
- {
- Contract.Requires(!String.IsNullOrEmpty(extensionXml));
-
- SecurityElement se = SecurityElement.FromString(extensionXml);
-
- // Return the permission set extension only if WPF is in the present framework profile.
- // XMLUtil.GetClassFromElement() helps do the quickest check, with no exception thrown and
- // minimal parsing.
- SecurityElement firstPermission = (SecurityElement)se.Children[0];
- if (System.Security.Util.XMLUtil.GetClassFromElement(firstPermission, /*ignoreTypeLoadFailures*/true) != null)
- {
- PermissionSet extensions = new NamedPermissionSet(se);
- return extensions;
- }
-
- return null;
- }
-#endif // FEATURE_CAS_POLICY
}
}
diff --git a/src/mscorlib/src/System/Security/CodeAccessPermission.cs b/src/mscorlib/src/System/Security/CodeAccessPermission.cs
index 61334c22bd..70504d902e 100644
--- a/src/mscorlib/src/System/Security/CodeAccessPermission.cs
+++ b/src/mscorlib/src/System/Security/CodeAccessPermission.cs
@@ -13,20 +13,16 @@ namespace System.Security
using System.Collections;
using System.Text;
using System;
- using System.Diagnostics;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using IUnrestrictedPermission = System.Security.Permissions.IUnrestrictedPermission;
[Serializable]
-#if !FEATURE_CORECLR
- [SecurityPermissionAttribute( SecurityAction.InheritanceDemand, ControlEvidence = true, ControlPolicy = true )]
-#endif
[System.Runtime.InteropServices.ComVisible(true)]
abstract public class CodeAccessPermission
: IPermission, ISecurityEncodable, IStackWalk
{
// Static methods for manipulation of stack
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static void RevertAssert()
{
@@ -34,7 +30,6 @@ namespace System.Security
SecurityRuntime.RevertAssert(ref stackMark);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
[Obsolete("Deny is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
public static void RevertDeny()
@@ -43,7 +38,6 @@ namespace System.Security
SecurityRuntime.RevertDeny(ref stackMark);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static void RevertPermitOnly()
{
@@ -51,7 +45,6 @@ namespace System.Security
SecurityRuntime.RevertPermitOnly(ref stackMark);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static void RevertAll()
{
@@ -66,7 +59,6 @@ namespace System.Security
// Mark this method as requiring a security object on the caller's frame
// so the caller won't be inlined (which would mess up stack crawling).
- [System.Security.SecuritySafeCritical] // auto-generated
[DynamicSecurityMethodAttribute()]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public void Demand()
@@ -78,7 +70,6 @@ namespace System.Security
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
[DynamicSecurityMethodAttribute()]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
internal static void Demand(PermissionType permissionType)
@@ -87,7 +78,7 @@ namespace System.Security
// without having to create objects.
// The security annotation fxcop rule that flags all methods with a Demand() has logic
// which checks for methods named Demand in types that implement IPermission or IStackWalk.
- Contract.Assert(new StackFrame().GetMethod().Name.Equals("Demand"), "This method needs to be named Demand");
+ Debug.Assert(new StackFrame().GetMethod().Name.Equals("Demand"), "This method needs to be named Demand");
StackCrawlMark stackMark = StackCrawlMark.LookForMyCallersCaller;
CodeAccessSecurityEngine.SpecialDemand(permissionType, ref stackMark);
@@ -96,7 +87,6 @@ namespace System.Security
// Metadata for this method should be flaged with REQ_SQ so that
// EE can allocate space on the stack frame for FrameSecurityDescriptor
- [System.Security.SecuritySafeCritical] // auto-generated
[DynamicSecurityMethodAttribute()]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public void Assert()
@@ -106,7 +96,6 @@ namespace System.Security
}
- [System.Security.SecuritySafeCritical] // auto-generated
[DynamicSecurityMethodAttribute()]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
static internal void Assert(bool allPossible)
@@ -115,7 +104,7 @@ namespace System.Security
// without having to new a PermissionSet.
// The security annotation fxcop rule that flags all methods with an Assert() has logic
// which checks for methods named Assert in types that implement IPermission or IStackWalk.
- Contract.Assert(new StackFrame().GetMethod().Name.Equals("Assert"), "This method needs to be named Assert");
+ Debug.Assert(new StackFrame().GetMethod().Name.Equals("Assert"), "This method needs to be named Assert");
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
SecurityRuntime.AssertAllPossible(ref stackMark);
@@ -124,7 +113,6 @@ namespace System.Security
// Metadata for this method should be flaged with REQ_SQ so that
// EE can allocate space on the stack frame for FrameSecurityDescriptor
- [System.Security.SecuritySafeCritical] // auto-generated
[DynamicSecurityMethodAttribute()]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
[Obsolete("Deny is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
@@ -137,7 +125,6 @@ namespace System.Security
// Metadata for this method should be flaged with REQ_SQ so that
// EE can allocate space on the stack frame for FrameSecurityDescriptor
- [System.Security.SecuritySafeCritical] // auto-generated
[DynamicSecurityMethodAttribute()]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public void PermitOnly()
@@ -160,48 +147,6 @@ namespace System.Security
// otherwise we don't support it.
throw new NotSupportedException(Environment.GetResourceString( "NotSupported_SecurityPermissionUnion" ));
}
-
-#if FEATURE_CAS_POLICY
- static internal SecurityElement CreatePermissionElement( IPermission perm, String permname )
- {
- SecurityElement root = new SecurityElement( "IPermission" );
- XMLUtil.AddClassAttribute( root, perm.GetType(), permname );
- // If you hit this assert then most likely you are trying to change the name of this class.
- // This is ok as long as you change the hard coded string above and change the assert below.
- Contract.Assert( perm.GetType().FullName.Equals( permname ), "Incorrect class name passed in! Was: " + permname + " Should be " + perm.GetType().FullName);
-
- root.AddAttribute( "version", "1" );
- return root;
- }
-
- static internal void ValidateElement( SecurityElement elem, IPermission perm )
- {
- if (elem == null)
- throw new ArgumentNullException( "elem" );
- Contract.EndContractBlock();
-
- if (!XMLUtil.IsPermissionElement( perm, elem ))
- throw new ArgumentException( Environment.GetResourceString( "Argument_NotAPermissionElement"));
-
- String version = elem.Attribute( "version" );
-
- if (version != null && !version.Equals( "1" ))
- throw new ArgumentException( Environment.GetResourceString( "Argument_InvalidXMLBadVersion") );
- }
-
- abstract public SecurityElement ToXml();
- abstract public void FromXml( SecurityElement elem );
-
- //
- // Unimplemented interface methods
- // (as a reminder only)
- //
-
- public override String ToString()
- {
- return ToXml().ToString();
- }
-#endif // FEATURE_CAS_POLICY
//
// HELPERS FOR IMPLEMENTING ABSTRACT METHODS
@@ -258,26 +203,26 @@ namespace System.Security
internal bool CheckDemand(CodeAccessPermission grant)
{
- Contract.Assert( grant == null || grant.GetType().Equals( this.GetType() ), "CheckDemand not defined for permissions of different type" );
+ Debug.Assert( grant == null || grant.GetType().Equals( this.GetType() ), "CheckDemand not defined for permissions of different type" );
return IsSubsetOf( grant );
}
internal bool CheckPermitOnly(CodeAccessPermission permitted)
{
- Contract.Assert( permitted == null || permitted.GetType().Equals( this.GetType() ), "CheckPermitOnly not defined for permissions of different type" );
+ Debug.Assert( permitted == null || permitted.GetType().Equals( this.GetType() ), "CheckPermitOnly not defined for permissions of different type" );
return IsSubsetOf( permitted );
}
internal bool CheckDeny(CodeAccessPermission denied)
{
- Contract.Assert( denied == null || denied.GetType().Equals( this.GetType() ), "CheckDeny not defined for permissions of different type" );
+ Debug.Assert( denied == null || denied.GetType().Equals( this.GetType() ), "CheckDeny not defined for permissions of different type" );
IPermission intersectPerm = Intersect(denied);
return (intersectPerm == null || intersectPerm.IsSubsetOf(null));
}
internal bool CheckAssert(CodeAccessPermission asserted)
{
- Contract.Assert( asserted == null || asserted.GetType().Equals( this.GetType() ), "CheckPermitOnly not defined for permissions of different type" );
+ Debug.Assert( asserted == null || asserted.GetType().Equals( this.GetType() ), "CheckPermitOnly not defined for permissions of different type" );
return IsSubsetOf( asserted );
}
}
diff --git a/src/mscorlib/src/System/Security/CodeAccessSecurityEngine.cs b/src/mscorlib/src/System/Security/CodeAccessSecurityEngine.cs
index 2a1cf9a0ea..d86897c02e 100644
--- a/src/mscorlib/src/System/Security/CodeAccessSecurityEngine.cs
+++ b/src/mscorlib/src/System/Security/CodeAccessSecurityEngine.cs
@@ -15,6 +15,7 @@ namespace System.Security {
using System.Globalization;
using System.Security.Policy;
using System.Runtime.Versioning;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
// Used in DemandInternal, to remember the result of previous demands
@@ -52,40 +53,22 @@ namespace System.Security {
internal static SecurityPermission AssertPermission;
internal static PermissionToken AssertPermissionToken;
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void SpecialDemand(PermissionType whatPermission, ref StackCrawlMark stackMark);
- [System.Security.SecurityCritical] // auto-generated
[System.Diagnostics.Conditional( "_DEBUG" )]
private static void DEBUG_OUT( String str )
{
-#if _DEBUG
+#if _DEBUG
if (debug)
- {
-#if !FEATURE_CORECLR
- if (to_file)
- {
- System.Text.StringBuilder sb = new System.Text.StringBuilder();
- sb.Append( str );
- sb.Append ((char)13) ;
- sb.Append ((char)10) ;
- PolicyManager.DebugOut( file, sb.ToString() );
- }
- else
-#endif
- Console.WriteLine( str );
- }
-#endif
+ Console.WriteLine( str );
+#endif
}
-
-#if _DEBUG
+
+#if _DEBUG
private static bool debug = false;
-#if !FEATURE_CORECLR
- private static readonly bool to_file = false;
-#endif
private const String file = "d:\\foo\\debug.txt";
-#endif
+#endif
// static default constructor. This will be called before any of the static members are accessed.
static CodeAccessSecurityEngine()
@@ -96,7 +79,6 @@ namespace System.Security {
AssertPermissionToken = PermissionToken.GetToken(AssertPermission);
}
- [System.Security.SecurityCritical] // auto-generated
#pragma warning disable 618
private static void ThrowSecurityException(RuntimeAssembly asm, PermissionSet granted, PermissionSet refused, RuntimeMethodHandleInternal rmh, SecurityAction action, Object demand, IPermission permThatFailed)
#pragma warning restore 618
@@ -109,20 +91,15 @@ namespace System.Security {
// there will be an infinite recursion that overflows the stack.
PermissionSet.s_fullTrust.Assert();
asmName = asm.GetName();
-#if FEATURE_CAS_POLICY
- if(asm != Assembly.GetExecutingAssembly()) // this condition is to avoid having to marshal mscorlib's evidence (which is always in teh default domain) to the current domain
- asmEvidence = asm.Evidence;
-#endif // FEATURE_CAS_POLICY
}
throw SecurityException.MakeSecurityException(asmName, asmEvidence, granted, refused, rmh, action, demand, permThatFailed);
}
- [System.Security.SecurityCritical] // auto-generated
#pragma warning disable 618
private static void ThrowSecurityException(Object assemblyOrString, PermissionSet granted, PermissionSet refused, RuntimeMethodHandleInternal rmh, SecurityAction action, Object demand, IPermission permThatFailed)
#pragma warning restore 618
{
- Contract.Assert((assemblyOrString == null || assemblyOrString is RuntimeAssembly || assemblyOrString is String), "Must pass in an Assembly object or String object here");
+ Debug.Assert((assemblyOrString == null || assemblyOrString is RuntimeAssembly || assemblyOrString is String), "Must pass in an Assembly object or String object here");
if (assemblyOrString == null || assemblyOrString is RuntimeAssembly)
ThrowSecurityException((RuntimeAssembly)assemblyOrString, granted, refused, rmh, action, demand, permThatFailed);
@@ -134,7 +111,6 @@ namespace System.Security {
}
#if FEATURE_COMPRESSEDSTACK
- [System.Security.SecurityCritical] // auto-generated
internal static void CheckSetHelper(CompressedStack cs,
PermissionSet grants,
PermissionSet refused,
@@ -149,9 +125,6 @@ namespace System.Security {
CheckSetHelper(grants, refused, demands, rmh, (Object)asm, action, true);
}
#else // FEATURE_COMPRESSEDSTACK
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
#pragma warning disable 618
internal static void CheckSetHelper(Object notUsed,
PermissionSet grants,
@@ -165,14 +138,13 @@ namespace System.Security {
// To reduce the amount of ifdef-code-churn, a dummy arg is used for the first parameter - instead of a CompressedStack object,
// we use a System.Object that should always be null. If we tried to change the signature of the function, there will need to be
// corresponding changes in VM (metasig.h, mscorlib.h, securitystackwalk.cpp, number of elements in the arg array, etc.)
- Contract.Assert(notUsed == null, "Should not reach here with a non-null first arg which is the CompressedStack");
+ Debug.Assert(notUsed == null, "Should not reach here with a non-null first arg which is the CompressedStack");
CheckSetHelper(grants, refused, demands, rmh, (Object)asm, action, true);
}
#endif // FEATURE_COMPRESSEDSTACK
- [System.Security.SecurityCritical] // auto-generated
#pragma warning disable 618
internal static bool CheckSetHelper(PermissionSet grants,
PermissionSet refused,
@@ -183,19 +155,7 @@ namespace System.Security {
bool throwException)
#pragma warning restore 618
{
-
- Contract.Assert(demands != null, "Should not reach here with a null demand set");
-#if _DEBUG && FEATURE_CAS_POLICY
- if (debug)
- {
- DEBUG_OUT("Granted: ");
- DEBUG_OUT(grants.ToXml().ToString());
- DEBUG_OUT("Refused: ");
- DEBUG_OUT(refused != null ? refused.ToXml().ToString() : "<null>");
- DEBUG_OUT("Demanded: ");
- DEBUG_OUT(demands!=null ? demands.ToXml().ToString() : "<null>");
- }
-#endif // _DEBUG && FEATURE_CAS_POLICY
+ Debug.Assert(demands != null, "Should not reach here with a null demand set");
IPermission permThatFailed = null;
if (grants != null)
@@ -248,7 +208,6 @@ namespace System.Security {
return true;
}
#if FEATURE_COMPRESSEDSTACK
- [System.Security.SecurityCritical] // auto-generated
internal static void CheckHelper(CompressedStack cs,
PermissionSet grantedSet,
PermissionSet refusedSet,
@@ -264,9 +223,6 @@ namespace System.Security {
CheckHelper(grantedSet, refusedSet, demand, permToken, rmh, (Object)asm, action, true);
}
#else // FEATURE_COMPRESSEDSTACK
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
#pragma warning disable 618
internal static void CheckHelper(Object notUsed,
PermissionSet grantedSet,
@@ -281,11 +237,10 @@ namespace System.Security {
// To reduce the amount of ifdef-code-churn, a dummy arg is used for the first parameter - instead of a CompressedStack object,
// we use a System.Object that should always be null. If we tried to change the signature of the function, there will need to be
// corresponding changes in VM (metasig.h, mscorlib.h, securitystackwalk.cpp, number of elements in the arg array, etc.)
- Contract.Assert(notUsed == null, "Should not reach here with a non-null first arg which is the CompressedStack");
+ Debug.Assert(notUsed == null, "Should not reach here with a non-null first arg which is the CompressedStack");
CheckHelper(grantedSet, refusedSet, demand, permToken, rmh, (Object)asm, action, true);
}
#endif // FEATURE_COMPRESSEDSTACK
- [System.Security.SecurityCritical] // auto-generated
#pragma warning disable 618
internal static bool CheckHelper(PermissionSet grantedSet,
PermissionSet refusedSet,
@@ -298,19 +253,7 @@ namespace System.Security {
#pragma warning restore 618
{
// We should never get here with a null demand
- Contract.Assert(demand != null, "Should not reach here with a null demand");
-
-#if _DEBUG && FEATURE_CAS_POLICY
- if (debug)
- {
- DEBUG_OUT("Granted: ");
- DEBUG_OUT(grantedSet.ToXml().ToString());
- DEBUG_OUT("Refused: ");
- DEBUG_OUT(refusedSet != null ? refusedSet.ToXml().ToString() : "<null>");
- DEBUG_OUT("Demanded: ");
- DEBUG_OUT(demand.ToString());
- }
-#endif // _DEBUG && FEATURE_CAS_POLICY
+ Debug.Assert(demand != null, "Should not reach here with a null demand");
if (permToken == null)
permToken = PermissionToken.GetToken(demand);
@@ -339,7 +282,7 @@ namespace System.Security {
// If we aren't unrestricted, there is a refused set, or our permission is not of the unrestricted
// variety, we need to do the proper callback.
- Contract.Assert(demand != null,"demand != null");
+ Debug.Assert(demand != null,"demand != null");
// Find the permission of matching type in the permission set.
@@ -411,420 +354,35 @@ namespace System.Security {
return true;
}
-#if FEATURE_CAS_POLICY
- /// <summary>
- /// Demand for the grant set of an assembly
- /// </summary>
- /// <remarks>
- /// Managed half of SecurityStackWalk::DemandGrantSet.
- /// </remarks>
- [System.Security.SecurityCritical] // auto-generated
- private static void CheckGrantSetHelper(PermissionSet grantSet)
- {
- Contract.Assert(grantSet != null, "Missing grant set");
- grantSet.CopyWithNoIdentityPermissions().Demand();
- }
-
- /// <summary>
- /// Perform a security demand which succeeds if either a compatibilty permission is granted to the
- /// call stack, or restricted member access and the grant set of the target of the reflection
- /// operation is granted.
- /// </summary>
- /// <param name="permission">compatibility permission to check</param>
- /// <param name="targetGrant">grant set of the reflection target</param>
- [System.Security.SecurityCritical] // auto-generated
- internal static void ReflectionTargetDemandHelper(PermissionType permission, PermissionSet targetGrant)
- {
- ReflectionTargetDemandHelper((int)permission, targetGrant);
- }
-
- /// <summary>
- /// Perform a security demand which succeeds if either a compatibilty permission is granted to the
- /// call stack, or restricted member access and the grant set of the target of the reflection
- /// operation is granted.
- /// </summary>
- /// <remarks>
- /// Managed half of SecurityStackWalk::ReflectionTargetDemand.
- /// </remarks>
- /// <param name="permission">compatibility permission to check (See PermissionType)</param>
- /// <param name="targetGrant">grant set of the reflection target</param>
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- private static void ReflectionTargetDemandHelper(int permission, PermissionSet targetGrant)
- {
- // Capture a compressed stack so that we can make both permission checks without walking the stack
- // multiple times.
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- CompressedStack cs = CompressedStack.GetCompressedStack(ref stackMark);
-
- ReflectionTargetDemandHelper(permission, targetGrant, cs);
- }
-
- /// <summary>
- /// Perform a reflection target demand against a given access context
- /// </summary>
- /// <remarks>
- /// Managed half of SecurityStackWalk::ReflectionTargetDemand
- /// </remarks>
- /// <param name="permission">compatibility permission to check (See PermissionType)</param>
- /// <param name="targetGrant">grant set of the reflection target</param>
- /// <param name="accessContext">access context to do the demand against</param>
- [System.Security.SecurityCritical] // auto-generated
- private static void ReflectionTargetDemandHelper(int permission,
- PermissionSet targetGrant,
- Resolver accessContext)
- {
- ReflectionTargetDemandHelper(permission, targetGrant, accessContext.GetSecurityContext());
- }
-
- /// <summary>
- /// Perform a reflection target demand against a given compressed stack
- /// </summary>
- /// <remarks>
- /// Managed half of SecurityStackWalk::ReflectionTargetDemand
- /// </remarks>
- /// <param name="permission">compatibility permission to check (See PermissionType)</param>
- /// <param name="targetGrant">grant set of the reflection target</param>
- /// <param name="securityContext">compressed stack to do the demand against</param>
- [System.Security.SecurityCritical] // auto-generated
- private static void ReflectionTargetDemandHelper(int permission,
- PermissionSet targetGrant,
- CompressedStack securityContext)
- {
- Contract.Assert(securityContext != null, "securityContext != null");
-
- // We need to remove all identity permissions from the grant set of the target, otherwise the
- // disjunctive demand will fail unless we're reflecting on the same assembly.
- PermissionSet demandSet = null;
- if (targetGrant == null)
- {
- demandSet = new PermissionSet(PermissionState.Unrestricted);
- }
- else
- {
- demandSet = targetGrant.CopyWithNoIdentityPermissions();
- demandSet.AddPermission(new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess));
- }
-
- securityContext.DemandFlagsOrGrantSet((1 << (int)permission), demandSet);
- }
-
- [System.Security.SecurityCritical] // auto-generated
- internal static void GetZoneAndOriginHelper( CompressedStack cs, PermissionSet grantSet, PermissionSet refusedSet, ArrayList zoneList, ArrayList originList )
- {
- if (cs != null)
- cs.GetZoneAndOrigin(zoneList, originList, PermissionToken.GetToken(typeof(ZoneIdentityPermission)), PermissionToken.GetToken(typeof(UrlIdentityPermission)));
- else
- {
- ZoneIdentityPermission zone = (ZoneIdentityPermission)grantSet.GetPermission( typeof( ZoneIdentityPermission ) );
- UrlIdentityPermission url = (UrlIdentityPermission)grantSet.GetPermission( typeof( UrlIdentityPermission ) );
-
- if (zone != null)
- zoneList.Add( zone.SecurityZone );
-
- if (url != null)
- originList.Add( url.Url );
- }
- }
-
- [System.Security.SecurityCritical] // auto-generated
- internal static void GetZoneAndOrigin( ref StackCrawlMark mark, out ArrayList zone, out ArrayList origin )
- {
- zone = new ArrayList();
- origin = new ArrayList();
-
- GetZoneAndOriginInternal( zone, origin, ref mark);
- }
-
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern void GetZoneAndOriginInternal(ArrayList zoneList,
- ArrayList originList,
- ref StackCrawlMark stackMark);
-
- [System.Security.SecurityCritical] // auto-generated
- internal static void CheckAssembly(RuntimeAssembly asm, CodeAccessPermission demand )
- {
- Contract.Assert( asm != null, "Must pass in a good assembly" );
- Contract.Assert( demand != null, "Must pass in a good demand" );
-
- PermissionSet granted, refused;
- asm.GetGrantSet( out granted, out refused );
-#pragma warning disable 618
- CheckHelper( granted, refused, demand, PermissionToken.GetToken(demand), RuntimeMethodHandleInternal.EmptyHandle, asm, SecurityAction.Demand, true );
-#pragma warning restore 618
- }
-
- // Check - Used to initiate a code-access security check.
- // This method invokes a stack walk after skipping to the frame
- // referenced by stackMark.
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern void Check (Object demand,
- ref StackCrawlMark stackMark,
- bool isPermSet);
-
-
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern bool QuickCheckForAllDemands();
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern bool AllDomainsHomogeneousWithNoStackModifiers();
-#endif // FEATURE_CAS_POLICY
-
- [System.Security.SecurityCritical] // auto-generated
internal static void Check(CodeAccessPermission cap, ref StackCrawlMark stackMark)
{
-#if FEATURE_CAS_POLICY
- Check(cap,
- ref stackMark,
- false);
-#endif // FEATURE_CAS_POLICY
}
- [System.Security.SecurityCritical] // auto-generated
internal static void Check(PermissionSet permSet, ref StackCrawlMark stackMark)
{
-#if FEATURE_CAS_POLICY
- Check(permSet,
- ref stackMark,
- true);
-#endif // FEATURE_CAS_POLICY
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern FrameSecurityDescriptor CheckNReturnSO(PermissionToken permToken,
CodeAccessPermission demand,
ref StackCrawlMark stackMark,
int create );
- [System.Security.SecurityCritical] // auto-generated
internal static void Assert(CodeAccessPermission cap, ref StackCrawlMark stackMark)
{
-#if FEATURE_CAS_POLICY
- // Make sure the caller of assert has the permission to assert
- //WARNING: The placement of the call here is just right to check
- // the appropriate frame.
-
- // Note: if the "AssertPermission" is not a permission that implements IUnrestrictedPermission
- // you need to change the last parameter to a zero.
- Contract.Assert(AssertPermissionToken != null && AssertPermission != null, "Assert Permission not setup correctly");
- FrameSecurityDescriptor secObj = CheckNReturnSO(AssertPermissionToken,
- AssertPermission,
- ref stackMark,
- 1 );
- if (secObj == null)
- {
- // Security: REQ_SQ flag is missing. Bad compiler ?
- // This can happen when you create delegates over functions that need the REQ_SQ
- System.Environment.FailFast(Environment.GetResourceString("ExecutionEngine_MissingSecurityDescriptor"));
- }
- else
- {
- if (secObj.HasImperativeAsserts())
- throw new SecurityException( Environment.GetResourceString( "Security_MustRevertOverride" ) );
-
- secObj.SetAssert(cap);
- }
-#endif // FEATURE_CAS_POLICY
}
- [System.Security.SecurityCritical] // auto-generated
internal static void Deny(CodeAccessPermission cap, ref StackCrawlMark stackMark)
{
-#if FEATURE_CAS_POLICY
- // Deny is only valid in legacy mode
- if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_CasDeny"));
- }
-
- FrameSecurityDescriptor secObj =
- SecurityRuntime.GetSecurityObjectForFrame(ref stackMark, true);
- if (secObj == null)
- {
- // Security: REQ_SQ flag is missing. Bad compiler ?
- // This can happen when you create delegates over functions that need the REQ_SQ
- System.Environment.FailFast(Environment.GetResourceString("ExecutionEngine_MissingSecurityDescriptor"));
- }
- else
- {
- if (secObj.HasImperativeDenials())
- throw new SecurityException( Environment.GetResourceString( "Security_MustRevertOverride" ) );
-
- secObj.SetDeny(cap);
- }
-#endif // FEATURE_CAS_POLICY
}
- [System.Security.SecurityCritical] // auto-generated
internal static void PermitOnly(CodeAccessPermission cap, ref StackCrawlMark stackMark)
{
-#if FEATURE_CAS_POLICY
- FrameSecurityDescriptor secObj =
- SecurityRuntime.GetSecurityObjectForFrame(ref stackMark, true);
- if (secObj == null)
- {
- // Security: REQ_SQ flag is missing. Bad compiler ?
- // This can happen when you create delegates over functions that need the REQ_SQ
- System.Environment.FailFast(Environment.GetResourceString("ExecutionEngine_MissingSecurityDescriptor"));
- }
- else
- {
- if (secObj.HasImperativeRestrictions())
- throw new SecurityException( Environment.GetResourceString( "Security_MustRevertOverride" ) );
-
- secObj.SetPermitOnly(cap);
- }
-#endif // FEATURE_CAS_POLICY
- }
-
-#if FEATURE_CAS_POLICY
- // Called from the VM to do a pre-domain initialization check of the security state of the
- // AppDomain. This method looks at the state of the security of an AppDomain before it is
- // completely initialized - so the output of this method does not always match what will be true
- // when the domain is completely initialized. Instead, it is used to read what the input parameters
- // to the domain setup say about the domain.
- private static void PreResolve(out bool isFullyTrusted, out bool isHomogeneous)
- {
- //
- // There are three main cases:
- // 1. The AppDomain has an explict ApplicationTrust - we can use this to read the input state
- // of the AppDomain.
- // 2. The AppDomain is using legacy CAS policy - this means we can't tell much about the
- // domain itself without a full policy resolution.
- // 3. The domain is a standard v4+ AppDomain - these are always full trust and homogenous by
- // default.
- //
-
- // If the AppDomain is setup with an ApplicationTrust then it is always homogenous and we can
- // tell its grant set right from the ApplicaitonTrust
- ApplicationTrust domainTrust = AppDomain.CurrentDomain.SetupInformation.ApplicationTrust;
- if (domainTrust != null)
- {
- isFullyTrusted = domainTrust.DefaultGrantSet.PermissionSet.IsUnrestricted();
- isHomogeneous = true;
- return;
- }
-
- // Otherwise, see if the domain is being configured on input to use legacy CAS policy
- if (CompatibilitySwitches.IsNetFx40LegacySecurityPolicy || AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
- {
- isFullyTrusted = false;
- isHomogeneous = false;
- return;
- }
-
- // If none of the above is true, then we must be a standard AppDomain
- isFullyTrusted = true;
- isHomogeneous = true;
- }
-
- // Called from the VM when either a HostSecurityManager or simple sandbox domain can determine the
- // grant set of an assembly
- private static PermissionSet ResolveGrantSet(Evidence evidence, out int specialFlags, bool checkExecutionPermission)
- {
- Contract.Assert(evidence != null);
- Contract.Assert(!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled); // This API does not do CAS policy resolution
-
- PermissionSet grantSet = null;
- if (!TryResolveGrantSet(evidence, out grantSet))
- {
- // If we couldn't figure out a grant set from the domain or the host, then we treat the
- // assembly as fully trusted.
- grantSet = new PermissionSet(PermissionState.Unrestricted);
- }
-
- // Make sure the grant set includes the ability to execute code if that has been requested.
- if (checkExecutionPermission)
- {
- SecurityPermission executionPermission = new SecurityPermission(SecurityPermissionFlag.Execution);
- if (!grantSet.Contains(executionPermission))
- {
- throw new PolicyException(Environment.GetResourceString("Policy_NoExecutionPermission"),
- System.__HResults.CORSEC_E_NO_EXEC_PERM);
- }
- }
-
- specialFlags = SecurityManager.GetSpecialFlags(grantSet, null);
- return grantSet;
- }
-
- // Consult the host and the current AppDomain if it is homogenous to determine what the grant set
- // of an assembly is. This API returns true if it was able to determine a grant set for the evidence,
- // false if it cannot and other policy needs to be applied.
- [SecuritySafeCritical]
- internal static bool TryResolveGrantSet(Evidence evidence, out PermissionSet grantSet)
- {
- Contract.Assert(evidence != null);
-
- HostSecurityManager securityManager = AppDomain.CurrentDomain.HostSecurityManager;
-
- // GAC assemblies always are fully trusted
- if (evidence.GetHostEvidence<GacInstalled>() != null)
- {
- grantSet = new PermissionSet(PermissionState.Unrestricted);
- return true;
- }
- // If the host wants to participate in policy resolution, then our next option is to ask it for
- // a grant set
- else if ((securityManager.Flags & HostSecurityManagerOptions.HostResolvePolicy) == HostSecurityManagerOptions.HostResolvePolicy)
- {
- PermissionSet hostGrantSet = securityManager.ResolvePolicy(evidence);
-
- if (hostGrantSet == null)
- {
- throw new PolicyException(Environment.GetResourceString("Policy_NullHostGrantSet", securityManager.GetType().FullName));
- }
-
- // If we're in a homogenous domain, we don't want to allow the host to create multiple
- // levels of permissions within the domain. So, if we see the host return something other
- // than full trust or the homogenous grant set, we reject the grant set.
- if (AppDomain.CurrentDomain.IsHomogenous)
- {
- // Some hosts, such as ASP.NET, return Nothing as a way of saying that the assembly should
- // not be allowed to run in the AppDomain. Reject that with a specific
- // no-execution-allowed-here exception message, rather than the return value validation
- // exception message we'd hit below.
- if (hostGrantSet.IsEmpty())
- {
- throw new PolicyException(Environment.GetResourceString("Policy_NoExecutionPermission"));
- }
-
- PermissionSet homogenousGrantSet = AppDomain.CurrentDomain.ApplicationTrust.DefaultGrantSet.PermissionSet;
- bool isValidGrantSet = hostGrantSet.IsUnrestricted() ||
- (hostGrantSet.IsSubsetOf(homogenousGrantSet) && homogenousGrantSet.IsSubsetOf(hostGrantSet));
-
- if (!isValidGrantSet)
- {
- throw new PolicyException(Environment.GetResourceString("Policy_GrantSetDoesNotMatchDomain", securityManager.GetType().FullName));
- }
- }
-
- grantSet = hostGrantSet;
- return true;
- }
- // If we're in a homogenous domain, we can get the grant set directly from the application trust
- else if (AppDomain.CurrentDomain.IsHomogenous)
- {
- grantSet = AppDomain.CurrentDomain.GetHomogenousGrantSet(evidence);
- return true;
- }
- // Otherwise we have no way to figure out what the grant set is
- else
- {
- grantSet = null;
- return false;
- }
}
-#endif // FEATURE_CAS_POLICY
#if FEATURE_PLS
// Update the PLS used for optimization in the AppDomain: called from the VM
- [System.Security.SecurityCritical] // auto-generated
private static PermissionListSet UpdateAppDomainPLS(PermissionListSet adPLS, PermissionSet grantedPerms, PermissionSet refusedPerms) {
if (adPLS == null) {
adPLS = new PermissionListSet();
diff --git a/src/mscorlib/src/System/Security/FrameSecurityDescriptor.cs b/src/mscorlib/src/System/Security/FrameSecurityDescriptor.cs
index 8f25bda617..0ef5afd282 100644
--- a/src/mscorlib/src/System/Security/FrameSecurityDescriptor.cs
+++ b/src/mscorlib/src/System/Security/FrameSecurityDescriptor.cs
@@ -12,6 +12,7 @@ namespace System.Security {
using System.Globalization;
using System.Runtime.ConstrainedExecution;
using System.Runtime.Versioning;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
#if !FEATURE_PAL
using Microsoft.Win32.SafeHandles;
@@ -40,10 +41,8 @@ namespace System.Security {
// if this frame contains a call to any WindowsIdentity.Impersonate(),
// we save the previous SafeTokenHandles here (in the next two fields)
// Used during exceptionstackwalks to revert impersonation before calling filters
- [System.Security.SecurityCritical] // auto-generated
[NonSerialized]
private SafeAccessTokenHandle m_callerToken;
- [System.Security.SecurityCritical] // auto-generated
[NonSerialized]
private SafeAccessTokenHandle m_impToken;
#endif
@@ -56,16 +55,12 @@ namespace System.Security {
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void IncrementOverridesCount();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void DecrementOverridesCount();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void IncrementAssertCount();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void DecrementAssertCount();
@@ -105,14 +100,12 @@ namespace System.Security {
// we store declarative actions in both fields, so check if they are different
return (m_restriction != null);
}
- [System.Security.SecurityCritical] // auto-generated
internal void SetAssert(IPermission perm)
{
m_assertions = CreateSingletonSet(perm);
IncrementAssertCount();
}
- [System.Security.SecurityCritical] // auto-generated
internal void SetAssert(PermissionSet permSet)
{
m_assertions = permSet.Copy();
@@ -125,7 +118,6 @@ namespace System.Security {
return (fDeclarative) ? m_DeclarativeAssertions : m_assertions;
}
- [System.Security.SecurityCritical] // auto-generated
internal void SetAssertAllPossible()
{
m_assertAllPossible = true;
@@ -141,19 +133,12 @@ namespace System.Security {
// D E N Y
//-----------------------------------------------------------+
- [System.Security.SecurityCritical] // auto-generated
internal void SetDeny(IPermission perm)
{
-#if FEATURE_CAS_POLICY
- BCLDebug.Assert(AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled, "Deny is only valid in legacy CAS mode");
-#endif // FEATURE_CAS_POLICY
-
m_denials = CreateSingletonSet(perm);
IncrementOverridesCount();
-
}
- [System.Security.SecurityCritical] // auto-generated
internal void SetDeny(PermissionSet permSet)
{
m_denials = permSet.Copy();
@@ -169,14 +154,12 @@ namespace System.Security {
// R E S T R I C T
//-----------------------------------------------------------+
- [System.Security.SecurityCritical] // auto-generated
internal void SetPermitOnly(IPermission perm)
{
m_restriction = CreateSingletonSet(perm);
IncrementOverridesCount();
}
- [System.Security.SecurityCritical] // auto-generated
internal void SetPermitOnly(PermissionSet permSet)
{
// permSet must not be null
@@ -193,7 +176,6 @@ namespace System.Security {
//-----------------------------------------------------------+
// SafeAccessTokenHandle (Impersonation + EH purposes)
//-----------------------------------------------------------+
- [System.Security.SecurityCritical] // auto-generated
internal void SetTokenHandles (SafeAccessTokenHandle callerToken, SafeAccessTokenHandle impToken)
{
m_callerToken = callerToken;
@@ -204,7 +186,6 @@ namespace System.Security {
// R E V E R T
//-----------------------------------------------------------+
- [System.Security.SecurityCritical] // auto-generated
internal void RevertAssert()
{
if (m_assertions != null)
@@ -224,7 +205,6 @@ namespace System.Security {
}
}
- [System.Security.SecurityCritical] // auto-generated
internal void RevertAssertAllPossible()
{
if (m_assertAllPossible)
@@ -234,7 +214,6 @@ namespace System.Security {
}
}
- [System.Security.SecurityCritical] // auto-generated
internal void RevertDeny()
{
if (HasImperativeDenials())
@@ -244,7 +223,6 @@ namespace System.Security {
}
}
- [System.Security.SecurityCritical] // auto-generated
internal void RevertPermitOnly()
{
if (HasImperativeRestrictions())
@@ -254,7 +232,6 @@ namespace System.Security {
}
}
- [System.Security.SecurityCritical] // auto-generated
internal void RevertAll()
{
RevertAssert();
@@ -270,7 +247,6 @@ namespace System.Security {
// This will get called when we hit a FSD while evaluating a demand on the call stack or compressedstack
- [System.Security.SecurityCritical] // auto-generated
internal bool CheckDemand(CodeAccessPermission demand, PermissionToken permToken, RuntimeMethodHandleInternal rmh)
{
// imperative security
@@ -283,13 +259,12 @@ namespace System.Security {
return fContinue;
}
- [System.Security.SecurityCritical] // auto-generated
internal bool CheckDemand2(CodeAccessPermission demand, PermissionToken permToken, RuntimeMethodHandleInternal rmh, bool fDeclarative)
{
PermissionSet permSet;
// If the demand is null, there is no need to continue
- Contract.Assert(demand != null && !demand.CheckDemand(null), "Empty demands should have been filtered out by this point");
+ Debug.Assert(demand != null && !demand.CheckDemand(null), "Empty demands should have been filtered out by this point");
// decode imperative
if (GetPermitOnly(fDeclarative) != null)
@@ -397,7 +372,6 @@ namespace System.Security {
return SecurityRuntime.StackContinue;
}
- [System.Security.SecurityCritical] // auto-generated
internal bool CheckSetDemand(PermissionSet demandSet,
out PermissionSet alteredDemandSet,
RuntimeMethodHandleInternal rmh)
@@ -429,7 +403,6 @@ namespace System.Security {
return fContinue;
}
- [System.Security.SecurityCritical] // auto-generated
internal bool CheckSetDemand2(PermissionSet demandSet,
out PermissionSet alteredDemandSet,
RuntimeMethodHandleInternal rmh, bool fDeclarative)
diff --git a/src/mscorlib/src/System/Security/HostProtectionException.cs b/src/mscorlib/src/System/Security/HostProtectionException.cs
index 83f005fe9b..b08fccd1b3 100644
--- a/src/mscorlib/src/System/Security/HostProtectionException.cs
+++ b/src/mscorlib/src/System/Security/HostProtectionException.cs
@@ -53,7 +53,7 @@ namespace System.Security
protected HostProtectionException(SerializationInfo info, StreamingContext context) : base(info, context)
{
if (info==null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
m_protected = (HostProtectionResource)info.GetValue(ProtectedResourcesName, typeof(HostProtectionResource));
@@ -120,11 +120,10 @@ namespace System.Security
}
- [System.Security.SecurityCritical] // auto-generated_required
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info==null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
base.GetObjectData( info, context );
diff --git a/src/mscorlib/src/System/Security/HostSecurityManager.cs b/src/mscorlib/src/System/Security/HostSecurityManager.cs
index 46d5552478..53137983d3 100644
--- a/src/mscorlib/src/System/Security/HostSecurityManager.cs
+++ b/src/mscorlib/src/System/Security/HostSecurityManager.cs
@@ -9,13 +9,9 @@
// participate in the security decisions in the AppDomain.
//
-namespace System.Security {
+namespace System.Security
+{
using System.Collections;
-#if FEATURE_CLICKONCE
- using System.Deployment.Internal.Isolation;
- using System.Deployment.Internal.Isolation.Manifest;
- using System.Runtime.Hosting;
-#endif
using System.Reflection;
using System.Security;
using System.Security.Permissions;
@@ -24,7 +20,7 @@ namespace System.Security {
using System.Diagnostics.Contracts;
-[Serializable]
+ [Serializable]
[Flags]
[System.Runtime.InteropServices.ComVisible(true)]
public enum HostSecurityManagerOptions {
@@ -38,11 +34,7 @@ namespace System.Security {
AllFlags = 0x001F
}
- [System.Security.SecurityCritical] // auto-generated_required
[Serializable]
-#if !FEATURE_CORECLR
- [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.Infrastructure)]
-#endif
[System.Runtime.InteropServices.ComVisible(true)]
public class HostSecurityManager {
public HostSecurityManager () {}
@@ -56,20 +48,6 @@ namespace System.Security {
}
}
-#if FEATURE_CAS_POLICY
- // provide policy for the AppDomain.
- [Obsolete("AppDomain policy levels are obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
- public virtual PolicyLevel DomainPolicy {
- get {
- if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
- }
-
- return null;
- }
- }
-#endif
public virtual Evidence ProvideAppDomainEvidence (Evidence inputEvidence) {
// The default implementation does not modify the input evidence.
return inputEvidence;
@@ -80,109 +58,6 @@ namespace System.Security {
return inputEvidence;
}
-#if FEATURE_CLICKONCE
- [System.Security.SecurityCritical] // auto-generated
- [SecurityPermissionAttribute(SecurityAction.Assert, Unrestricted=true)]
- public virtual ApplicationTrust DetermineApplicationTrust(Evidence applicationEvidence, Evidence activatorEvidence, TrustManagerContext context)
- {
- if (applicationEvidence == null)
- throw new ArgumentNullException("applicationEvidence");
- Contract.EndContractBlock();
-
- // This method looks for a trust decision for the ActivationContext in three locations, in order
- // of preference:
- //
- // 1. Supplied by the host in the AppDomainSetup. If the host supplied a decision this way, it
- // will be in the applicationEvidence.
- // 2. Reuse the ApplicationTrust from the current AppDomain
- // 3. Ask the TrustManager for a trust decision
-
- // get the activation context from the application evidence.
- // The default HostSecurityManager does not examine the activatorEvidence
- // but other security managers could use it to figure out the
- // evidence of the domain attempting to activate the application.
-
- ActivationArguments activationArgs = applicationEvidence.GetHostEvidence<ActivationArguments>();
- if (activationArgs == null)
- throw new ArgumentException(Environment.GetResourceString("Policy_MissingActivationContextInAppEvidence"));
-
- ActivationContext actCtx = activationArgs.ActivationContext;
- if (actCtx == null)
- throw new ArgumentException(Environment.GetResourceString("Policy_MissingActivationContextInAppEvidence"));
-
- // Make sure that any ApplicationTrust we find applies to the ActivationContext we're
- // creating the new AppDomain for.
- ApplicationTrust appTrust = applicationEvidence.GetHostEvidence<ApplicationTrust>();
- if (appTrust != null &&
- !CmsUtils.CompareIdentities(appTrust.ApplicationIdentity, activationArgs.ApplicationIdentity, ApplicationVersionMatch.MatchExactVersion))
- {
- appTrust = null;
- }
-
- // If there was not a trust decision supplied in the Evidence, we can reuse the existing trust
- // decision from this domain if its identity matches the ActivationContext of the new domain.
- // Otherwise consult the TrustManager for a trust decision
- if (appTrust == null)
- {
- if (AppDomain.CurrentDomain.ApplicationTrust != null &&
- CmsUtils.CompareIdentities(AppDomain.CurrentDomain.ApplicationTrust.ApplicationIdentity, activationArgs.ApplicationIdentity, ApplicationVersionMatch.MatchExactVersion))
- {
- appTrust = AppDomain.CurrentDomain.ApplicationTrust;
- }
- else
- {
- appTrust = ApplicationSecurityManager.DetermineApplicationTrustInternal(actCtx, context);
- }
- }
-
- // If the trust decision allows the application to run, then it should also have a permission set
- // which is at least the permission set the application requested.
- ApplicationSecurityInfo appRequest = new ApplicationSecurityInfo(actCtx);
- if (appTrust != null &&
- appTrust.IsApplicationTrustedToRun &&
- !appRequest.DefaultRequestSet.IsSubsetOf(appTrust.DefaultGrantSet.PermissionSet))
- {
- throw new InvalidOperationException(Environment.GetResourceString("Policy_AppTrustMustGrantAppRequest"));
- }
-
- return appTrust;
- }
-#endif // FEATURE_CLICKONCE
-
-#if FEATURE_CAS_POLICY
- // Query the CLR to see what it would have granted a specific set of evidence
- public virtual PermissionSet ResolvePolicy(Evidence evidence)
- {
- if (evidence == null)
- throw new ArgumentNullException("evidence");
- Contract.EndContractBlock();
-
- //
- // If the evidence is from the GAC then the result is full trust.
- // In a homogenous domain, then the application trust object provides the grant set.
- // When CAS policy is disabled, the result is full trust.
- // Otherwise, the result comes from evaluating CAS policy.
- //
-
- if (evidence.GetHostEvidence<GacInstalled>() != null)
- {
- return new PermissionSet(PermissionState.Unrestricted);
- }
- else if (AppDomain.CurrentDomain.IsHomogenous)
- {
- return AppDomain.CurrentDomain.GetHomogenousGrantSet(evidence);
- }
- else if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
- {
- return new PermissionSet(PermissionState.Unrestricted);
- }
- else
- {
- return SecurityManager.PolicyManager.CodeGroupResolve(evidence, false);
- }
- }
-#endif
-
/// <summary>
/// Determine what types of evidence the host might be able to supply for the AppDomain if requested
/// </summary>
diff --git a/src/mscorlib/src/System/Security/IEvidenceFactory.cs b/src/mscorlib/src/System/Security/IEvidenceFactory.cs
index 93f82a6420..592ab533be 100644
--- a/src/mscorlib/src/System/Security/IEvidenceFactory.cs
+++ b/src/mscorlib/src/System/Security/IEvidenceFactory.cs
@@ -2,19 +2,10 @@
// The .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.Runtime.Remoting;
- using System;
- using System.Security.Policy;
-[System.Runtime.InteropServices.ComVisible(true)]
+namespace System.Security
+{
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface IEvidenceFactory
{
-#if FEATURE_CAS_POLICY
- Evidence Evidence
- {
- get;
- }
-#endif // FEATURE_CAS_POLICY
}
-
}
diff --git a/src/mscorlib/src/System/Security/ISecurityEncodable.cs b/src/mscorlib/src/System/Security/ISecurityEncodable.cs
index 9915da3696..689b3e4b5f 100644
--- a/src/mscorlib/src/System/Security/ISecurityEncodable.cs
+++ b/src/mscorlib/src/System/Security/ISecurityEncodable.cs
@@ -8,22 +8,10 @@
// implement this interface
//
-namespace System.Security {
-
- using System;
- using System.Security.Util;
-
-
-[System.Runtime.InteropServices.ComVisible(true)]
+namespace System.Security
+{
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface ISecurityEncodable
{
-#if FEATURE_CAS_POLICY
- SecurityElement ToXml();
-
- void FromXml( SecurityElement e );
-#endif // FEATURE_CAS_POLICY
}
-
}
-
-
diff --git a/src/mscorlib/src/System/Security/ISecurityPolicyEncodable.cs b/src/mscorlib/src/System/Security/ISecurityPolicyEncodable.cs
index b1c8d1654f..567e41e891 100644
--- a/src/mscorlib/src/System/Security/ISecurityPolicyEncodable.cs
+++ b/src/mscorlib/src/System/Security/ISecurityPolicyEncodable.cs
@@ -8,21 +8,10 @@
// implement this interface
//
-namespace System.Security {
-
- using System;
- using System.Security.Util;
- using System.Security.Policy;
-
-
-[System.Runtime.InteropServices.ComVisible(true)]
+namespace System.Security
+{
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface ISecurityPolicyEncodable
{
-#if FEATURE_CAS_POLICY
- SecurityElement ToXml( PolicyLevel level );
-
- void FromXml( SecurityElement e, PolicyLevel level );
-#endif // FEATURE_CAS_POLICY
}
-
}
diff --git a/src/mscorlib/src/System/Security/NamedPermissionSet.cs b/src/mscorlib/src/System/Security/NamedPermissionSet.cs
index fba76749a1..1bc166fde8 100644
--- a/src/mscorlib/src/System/Security/NamedPermissionSet.cs
+++ b/src/mscorlib/src/System/Security/NamedPermissionSet.cs
@@ -7,212 +7,19 @@
// Extends PermissionSet to allow an associated name and description
//
-namespace System.Security {
-
+namespace System.Security
+{
using System;
- using System.Security.Util;
using System.Security.Permissions;
- using System.Runtime.Serialization;
- using System.Diagnostics.Contracts;
-#if !FEATURE_CAS_POLICY
- using Microsoft.Win32;
- using System.Collections;
- using System.Globalization;
- using System.IO;
- using System.Reflection;
- using System.Runtime.InteropServices;
- using System.Runtime.Remoting;
- using System.Runtime.Versioning;
- using System.Text;
-
-#else // FEATURE_CAS_POLICY
-
- using System.Threading;
-
-#endif // FEATURE_CAS_POLICY
-
[Serializable]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public sealed class NamedPermissionSet : PermissionSet
{
-#if FEATURE_CAS_POLICY
- // The name of this PermissionSet
- private String m_name;
-
- // The description of this PermissionSet
- private String m_description;
- [OptionalField(VersionAdded = 2)]
- internal String m_descrResource;
-
- internal NamedPermissionSet()
- : base()
- {
- }
-
- public NamedPermissionSet( String name )
- : base()
- {
- CheckName( name );
- m_name = name;
- }
-
- public NamedPermissionSet( String name, PermissionState state)
- : base( state )
- {
- CheckName( name );
- m_name = name;
- }
-
-
- public NamedPermissionSet( String name, PermissionSet permSet )
- : base( permSet )
- {
- CheckName( name );
- m_name = name;
- }
-
- public NamedPermissionSet( NamedPermissionSet permSet )
- : base( permSet )
- {
- m_name = permSet.m_name;
- m_description = permSet.Description;
- }
-
- internal NamedPermissionSet(SecurityElement permissionSetXml)
- : base(PermissionState.None)
- {
- Contract.Assert(permissionSetXml != null);
- FromXml(permissionSetXml);
- }
-
- public String Name {
- get { return m_name; }
- set { CheckName( value ); m_name = value; }
- }
-
- private static void CheckName( String name )
- {
- if (name == null || name.Equals( "" ))
- throw new ArgumentException( Environment.GetResourceString( "Argument_NPMSInvalidName" ));
- Contract.EndContractBlock();
- }
-
- public String Description {
- get
- {
- if(m_descrResource != null)
- {
- m_description = Environment.GetResourceString(m_descrResource);
- m_descrResource = null;
- }
- return m_description;
- }
-
- set
- {
- m_description = value;
- m_descrResource = null;
- }
- }
-
- public override PermissionSet Copy()
- {
- return new NamedPermissionSet( this );
- }
-
- public NamedPermissionSet Copy( String name )
- {
- NamedPermissionSet set = new NamedPermissionSet( this );
- set.Name = name;
- return set;
- }
-
- public override SecurityElement ToXml()
- {
- SecurityElement elem = base.ToXml("System.Security.NamedPermissionSet");
- // If you hit this assert then most likely you are trying to change the name of this class.
- // This is ok as long as you change the hard coded string above and change the assert below.
- Contract.Assert( this.GetType().FullName.Equals( "System.Security.NamedPermissionSet" ), "Class name changed!" );
-
- if (m_name != null && !m_name.Equals( "" ))
- {
- elem.AddAttribute( "Name", SecurityElement.Escape( m_name ) );
- }
-
- if (Description != null && !Description.Equals( "" ))
- {
- elem.AddAttribute( "Description", SecurityElement.Escape( Description ) );
- }
-
- return elem;
- }
-
- public override void FromXml( SecurityElement et )
- {
- FromXml( et, false, false );
- }
-
- internal override void FromXml( SecurityElement et, bool allowInternalOnly, bool ignoreTypeLoadFailures )
- {
- if (et == null)
- throw new ArgumentNullException( "et" );
- Contract.EndContractBlock();
-
- String elem;
-
- elem = et.Attribute( "Name" );
- m_name = elem == null ? null : elem;
-
- elem = et.Attribute( "Description" );
- m_description = (elem == null ? "" : elem);
- m_descrResource = null;
-
- base.FromXml( et, allowInternalOnly, ignoreTypeLoadFailures );
- }
-
- internal void FromXmlNameOnly( SecurityElement et )
+ internal static PermissionSet GetBuiltInSet(string name)
{
- // This function gets only the name for the permission set, ignoring all other info.
-
- String elem;
-
- elem = et.Attribute( "Name" );
- m_name = (elem == null ? null : elem);
- }
-
- // NamedPermissionSet Equals should have the exact semantic as PermissionSet.
- // We explicitly override them here to make sure that no one accidently
- // changes this.
-
- [System.Runtime.InteropServices.ComVisible(false)]
- public override bool Equals( Object obj )
- {
- return base.Equals( obj );
- }
-
- [System.Runtime.InteropServices.ComVisible(false)]
- public override int GetHashCode()
- {
- return base.GetHashCode();
- }
-
- private static Object s_InternalSyncObject;
- private static Object InternalSyncObject {
- get {
- if (s_InternalSyncObject == null) {
- Object o = new Object();
- Interlocked.CompareExchange(ref s_InternalSyncObject, o, null);
- }
- return s_InternalSyncObject;
- }
- }
-#else // FEATURE_CAS_POLICY
-
- internal static PermissionSet GetBuiltInSet(string name) {
// Used by PermissionSetAttribute to create one of the built-in,
// immutable permission sets.
-
if (name == null)
return null;
else if (name.Equals("FullTrust"))
@@ -264,6 +71,5 @@ namespace System.Security {
}
-#endif // !FEATURE_CAS_POLICY
}
}
diff --git a/src/mscorlib/src/System/Security/PermissionListSet.cs b/src/mscorlib/src/System/Security/PermissionListSet.cs
index 7eb13a72cf..093542ad4e 100644
--- a/src/mscorlib/src/System/Security/PermissionListSet.cs
+++ b/src/mscorlib/src/System/Security/PermissionListSet.cs
@@ -23,6 +23,7 @@ namespace System.Security
using System.Threading;
using System.Collections;
using System.Collections.Generic;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
[Serializable]
@@ -53,15 +54,13 @@ namespace System.Security
}
#if FEATURE_PLS
- [System.Security.SecurityCritical] // auto-generated
internal void UpdateDomainPLS (PermissionListSet adPLS) {
if (adPLS != null && adPLS.m_firstPermSetTriple != null)
UpdateDomainPLS(adPLS.m_firstPermSetTriple.GrantSet, adPLS.m_firstPermSetTriple.RefusedSet);
}
- [System.Security.SecurityCritical] // auto-generated
internal void UpdateDomainPLS (PermissionSet grantSet, PermissionSet deniedSet) {
- Contract.Assert(m_permSetTriples == null, "m_permSetTriples != null");
+ Debug.Assert(m_permSetTriples == null, "m_permSetTriples != null");
if (m_firstPermSetTriple == null)
m_firstPermSetTriple = new PermissionSetTriple();
@@ -76,7 +75,6 @@ namespace System.Security
UpdateTripleListAndCreateNewTriple(currentTriple, null);
}
- [System.Security.SecurityCritical] // auto-generated
private void Terminate(PermissionSetTriple currentTriple, PermissionListSet pls)
{
#if FEATURE_COMPRESSEDSTACK
@@ -86,7 +84,6 @@ namespace System.Security
this.UpdateTripleListAndCreateNewTriple(currentTriple, null);
}
- [System.Security.SecurityCritical] // auto-generated
private bool Update(PermissionSetTriple currentTriple, PermissionListSet pls)
{
#if FEATURE_COMPRESSEDSTACK
@@ -95,7 +92,6 @@ namespace System.Security
return this.UpdatePermissions(currentTriple, pls);
}
- [System.Security.SecurityCritical] // auto-generated
private bool Update(PermissionSetTriple currentTriple, FrameSecurityDescriptor fsd)
{
#if FEATURE_COMPRESSEDSTACK
@@ -117,7 +113,6 @@ namespace System.Security
}
#if FEATURE_COMPRESSEDSTACK
- [System.Security.SecurityCritical]
private bool Update2(PermissionSetTriple currentTriple, FrameSecurityDescriptorWithResolver fsdWithResolver)
{
System.Reflection.Emit.DynamicResolver resolver = fsdWithResolver.Resolver;
@@ -127,7 +122,6 @@ namespace System.Security
}
#endif // FEATURE_COMPRESSEDSTACK
- [System.Security.SecurityCritical] // auto-generated
private bool Update2(PermissionSetTriple currentTriple, FrameSecurityDescriptor fsd, bool fDeclarative)
{
// Deny
@@ -187,7 +181,6 @@ namespace System.Security
return false;
}
- [System.Security.SecurityCritical] // auto-generated
private void Update(PermissionSetTriple currentTriple, PermissionSet in_g, PermissionSet in_r)
{
#if FEATURE_COMPRESSEDSTACK
@@ -203,7 +196,6 @@ namespace System.Security
}
// Called from the VM for HG CS construction
- [System.Security.SecurityCritical] // auto-generated
private void Update(PermissionSet in_g)
{
if (m_firstPermSetTriple == null)
@@ -226,7 +218,6 @@ namespace System.Security
}
#endif // FEATURE_COMPRESSEDSTACK
- [System.Security.SecurityCritical] // auto-generated
private bool UpdatePermissions(PermissionSetTriple currentTriple, PermissionListSet pls)
{
if (pls != null)
@@ -322,7 +313,6 @@ namespace System.Security
}
}
-[System.Security.SecurityCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(true)]
// public(internal) interface begins...
// Creation functions
@@ -370,7 +360,6 @@ namespace System.Security
return pls;
}
- [System.Security.SecurityCritical] // auto-generated
static internal PermissionListSet CreateCompressedState(IntPtr unmanagedDCS, out bool bHaltConstruction)
{
PermissionListSet pls = new PermissionListSet();
@@ -411,7 +400,6 @@ namespace System.Security
return pls;
}
- [System.Security.SecurityCritical] // auto-generated
static internal PermissionListSet CreateCompressedState_HG()
{
PermissionListSet pls = new PermissionListSet();
@@ -420,11 +408,10 @@ namespace System.Security
}
#endif // #if FEATURE_COMPRESSEDSTACK
// Private Demand evaluation functions - only called from the VM
- [System.Security.SecurityCritical] // auto-generated
internal bool CheckDemandNoThrow(CodeAccessPermission demand)
{
// AppDomain permissions - no asserts. So there should only be one triple to work with
- Contract.Assert(m_permSetTriples == null && m_firstPermSetTriple != null, "More than one PermissionSetTriple encountered in AD PermissionListSet");
+ Debug.Assert(m_permSetTriples == null && m_firstPermSetTriple != null, "More than one PermissionSetTriple encountered in AD PermissionListSet");
@@ -436,18 +423,16 @@ namespace System.Security
}
- [System.Security.SecurityCritical] // auto-generated
internal bool CheckSetDemandNoThrow(PermissionSet pSet)
{
// AppDomain permissions - no asserts. So there should only be one triple to work with
- Contract.Assert(m_permSetTriples == null && m_firstPermSetTriple != null, "More than one PermissionSetTriple encountered in AD PermissionListSet");
+ Debug.Assert(m_permSetTriples == null && m_firstPermSetTriple != null, "More than one PermissionSetTriple encountered in AD PermissionListSet");
return m_firstPermSetTriple.CheckSetDemandNoThrow(pSet);
}
// Demand evauation functions
- [System.Security.SecurityCritical] // auto-generated
internal bool CheckDemand(CodeAccessPermission demand, PermissionToken permToken, RuntimeMethodHandleInternal rmh)
{
bool bRet = SecurityRuntime.StackContinue;
@@ -467,7 +452,6 @@ namespace System.Security
return bRet;
}
- [System.Security.SecurityCritical] // auto-generated
internal bool CheckSetDemand(PermissionSet pset , RuntimeMethodHandleInternal rmh)
{
PermissionSet unused;
@@ -475,7 +459,6 @@ namespace System.Security
return SecurityRuntime.StackHalt; // CS demand check always terminates the stackwalk
}
- [System.Security.SecurityCritical]
internal bool CheckSetDemandWithModification(PermissionSet pset, out PermissionSet alteredDemandSet, RuntimeMethodHandleInternal rmh)
{
bool bRet = SecurityRuntime.StackContinue;
@@ -503,10 +486,9 @@ namespace System.Security
/// Check to see if the PLS satisfies a demand for the special permissions encoded in flags
/// </summary>
/// <param name="flags">set of flags to check (See PermissionType)</param>
- [System.Security.SecurityCritical] // auto-generated
private bool CheckFlags(int flags)
{
- Contract.Assert(flags != 0, "Invalid permission flag demand");
+ Debug.Assert(flags != 0, "Invalid permission flag demand");
bool check = true;
@@ -531,7 +513,6 @@ namespace System.Security
/// </summary>
/// <param name="flags">set of flags to check (See PermissionType)</param>
/// <param name="grantSet">alternate permission set to check</param>
- [System.Security.SecurityCritical] // auto-generated
internal void DemandFlagsOrGrantSet(int flags, PermissionSet grantSet)
{
if (CheckFlags(flags))
diff --git a/src/mscorlib/src/System/Security/PermissionSet.cs b/src/mscorlib/src/System/Security/PermissionSet.cs
index e36f0752ad..11ca02a81e 100644
--- a/src/mscorlib/src/System/Security/PermissionSet.cs
+++ b/src/mscorlib/src/System/Security/PermissionSet.cs
@@ -21,6 +21,7 @@ namespace System.Security {
using System.Text;
using System.Globalization;
using System.Runtime.Versioning;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
[Serializable]
@@ -36,9 +37,6 @@ namespace System.Security {
#if FEATURE_SERIALIZATION
[Serializable]
#endif
-#if !FEATURE_CORECLR
- [StrongNameIdentityPermissionAttribute(SecurityAction.InheritanceDemand, Name = "mscorlib", PublicKey = "0x" + AssemblyRef.EcmaPublicKeyFull)]
-#endif
[System.Runtime.InteropServices.ComVisible(true)]
public class PermissionSet : ISecurityEncodable, ICollection, IStackWalk
#if FEATURE_SERIALIZATION
@@ -114,71 +112,13 @@ namespace System.Security {
internal static readonly PermissionSet s_fullTrust = new PermissionSet( true );
-#if FEATURE_REMOTING
- [OnDeserializing]
- private void OnDeserializing(StreamingContext ctx)
- {
- Reset();
- }
-
- [OnDeserialized]
- private void OnDeserialized(StreamingContext ctx)
- {
- if (m_serializedPermissionSet != null)
- {
- // Whidbey non X-AD case
- FromXml(SecurityElement.FromString(m_serializedPermissionSet));
- }
- else if (m_normalPermSet != null)
- {
- // Everett non X-AD case
- m_permSet = m_normalPermSet.SpecialUnion(m_unrestrictedPermSet);
- }
- else if (m_unrestrictedPermSet != null)
- {
- // Everett non X-AD case
- m_permSet = m_unrestrictedPermSet.SpecialUnion(m_normalPermSet);
- }
-
- m_serializedPermissionSet = null;
- m_normalPermSet = null;
- m_unrestrictedPermSet = null;
-
- }
-
- [OnSerializing]
- private void OnSerializing(StreamingContext ctx)
- {
-
- if ((ctx.State & ~(StreamingContextStates.Clone|StreamingContextStates.CrossAppDomain)) != 0)
- {
- m_serializedPermissionSet = ToString(); // For v2.x and beyond
- if (m_permSet != null)
- m_permSet.SpecialSplit(ref m_unrestrictedPermSet, ref m_normalPermSet, m_ignoreTypeLoadFailures);
- m_permSetSaved = m_permSet;
- m_permSet = null;
- }
- }
-#endif // !FEATURE_REMOTING
-
-#if FEATURE_REMOTING || _DEBUG
+#if _DEBUG
[OnSerialized]
private void OnSerialized(StreamingContext context)
{
-#if FEATURE_REMOTING
- if ((context.State & ~(StreamingContextStates.Clone|StreamingContextStates.CrossAppDomain)) != 0)
- {
- m_serializedPermissionSet = null;
- m_permSet = m_permSetSaved;
- m_permSetSaved = null;
- m_unrestrictedPermSet = null;
- m_normalPermSet = null;
- }
-#else // !FEATURE_REMOTING
- Contract.Assert(false, "PermissionSet does not support serialization on CoreCLR");
-#endif // !FEATURE_REMOTING
+ Debug.Assert(false, "PermissionSet does not support serialization on CoreCLR");
}
-#endif // FEATURE_REMOTING || _DEBUG
+#endif // _DEBUG
internal PermissionSet()
{
@@ -233,19 +173,11 @@ namespace System.Security {
{
Object obj = m_permSet.GetItem(i);
IPermission perm = obj as IPermission;
-#if FEATURE_CAS_POLICY
- ISecurityElementFactory elem = obj as ISecurityElementFactory;
-#endif // FEATURE_CAS_POLICY
+
if (perm != null)
{
m_permSet.SetItem(i, perm.Copy());
}
-#if FEATURE_CAS_POLICY
- else if (elem != null)
- {
- m_permSet.SetItem(i, elem.Copy());
- }
-#endif // FEATURE_CAS_POLICY
}
}
}
@@ -253,7 +185,7 @@ namespace System.Security {
public virtual void CopyTo(Array array, int index)
{
if (array == null)
- throw new ArgumentNullException( "array" );
+ throw new ArgumentNullException( nameof(array) );
Contract.EndContractBlock();
PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(this);
@@ -365,19 +297,7 @@ namespace System.Security {
Object obj = m_permSet.GetItem( index );
if (obj == null)
return null;
- IPermission perm = obj as IPermission;
- if (perm != null)
- return perm;
-#if FEATURE_CAS_POLICY
- perm = CreatePermission(obj, index);
-#endif // FEATURE_CAS_POLICY
- if (perm == null)
- return null;
- Contract.Assert( PermissionToken.IsTokenProperlyAssigned( perm, PermissionToken.GetToken( perm ) ),
- "PermissionToken was improperly assigned" );
- Contract.Assert( PermissionToken.GetToken( perm ).m_index == index,
- "Assigning permission to incorrect index in tokenbasedset" );
- return perm;
+ return obj as IPermission;
}
internal IPermission GetPermission(PermissionToken permToken)
@@ -396,21 +316,6 @@ namespace System.Security {
return GetPermission(PermissionToken.GetToken( perm ));
}
-#if FEATURE_CAS_POLICY
- public IPermission GetPermission(Type permClass)
- {
- return GetPermissionImpl(permClass);
- }
-
- protected virtual IPermission GetPermissionImpl(Type permClass)
- {
- if (permClass == null)
- return null;
-
- return GetPermission(PermissionToken.FindToken(permClass));
- }
-#endif // FEATURE_CAS_POLICY
-
public IPermission SetPermission(IPermission perm)
{
return SetPermissionImpl(perm);
@@ -494,29 +399,6 @@ namespace System.Security {
return (IPermission)m_permSet.RemoveItem( index ); // this cast is safe because the call to GetPermission will guarantee it is an IPermission
}
-#if FEATURE_CAS_POLICY
- public IPermission RemovePermission(Type permClass)
- {
- return RemovePermissionImpl(permClass);
- }
-
- protected virtual IPermission RemovePermissionImpl(Type permClass)
- {
- if (permClass == null)
- {
- return null;
- }
-
- PermissionToken permToken = PermissionToken.FindToken(permClass);
- if (permToken == null)
- {
- return null;
- }
-
- return RemovePermission(permToken.m_index);
- }
-#endif // FEATURE_CAS_POLICY
-
// Make this internal soon.
internal void SetUnrestricted(bool unrestricted)
{
@@ -527,12 +409,12 @@ namespace System.Security {
m_permSet = null;
}
}
-
+
public bool IsUnrestricted()
{
return m_Unrestricted;
}
-
+
internal enum IsSubsetOfType
{
Normal,
@@ -580,7 +462,7 @@ namespace System.Security {
IPermission targetPerm = target.GetPermission(i);
#if _DEBUG
PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i );
- Contract.Assert(targetPerm == null || (token.m_type & PermissionTokenType.DontKnow) == 0, "Token not properly initialized");
+ Debug.Assert(targetPerm == null || (token.m_type & PermissionTokenType.DontKnow) == 0, "Token not properly initialized");
#endif
if (target.m_Unrestricted)
@@ -692,7 +574,7 @@ namespace System.Security {
internal void CheckDecoded( CodeAccessPermission demandedPerm, PermissionToken tokenDemandedPerm )
{
- Contract.Assert( demandedPerm != null, "Expected non-null value" );
+ Debug.Assert( demandedPerm != null, "Expected non-null value" );
if (this.m_allPermissionsDecoded || this.m_permSet == null)
return;
@@ -700,7 +582,7 @@ namespace System.Security {
if (tokenDemandedPerm == null)
tokenDemandedPerm = PermissionToken.GetToken( demandedPerm );
- Contract.Assert( tokenDemandedPerm != null, "Unable to find token for demanded permission" );
+ Debug.Assert( tokenDemandedPerm != null, "Unable to find token for demanded permission" );
CheckDecoded( tokenDemandedPerm.m_index );
}
@@ -715,7 +597,7 @@ namespace System.Security {
internal void CheckDecoded(PermissionSet demandedSet)
{
- Contract.Assert(demandedSet != null, "Expected non-null value");
+ Debug.Assert(demandedSet != null, "Expected non-null value");
if (this.m_allPermissionsDecoded || this.m_permSet == null)
return;
@@ -728,37 +610,6 @@ namespace System.Security {
}
}
-#if FEATURE_CAS_POLICY
- static internal void SafeChildAdd( SecurityElement parent, ISecurityElementFactory child, bool copy )
- {
- if (child == parent)
- return;
- if (child.GetTag().Equals( "IPermission" ) || child.GetTag().Equals( "Permission" ))
- {
- parent.AddChild( child );
- }
- else if (parent.Tag.Equals( child.GetTag() ))
- {
- Contract.Assert( child is SecurityElement, "SecurityElement expected" );
- SecurityElement elChild = (SecurityElement)child;
- Contract.Assert( elChild.InternalChildren != null,
- "Non-permission elements should have children" );
-
- for (int i = 0; i < elChild.InternalChildren.Count; ++i)
- {
- ISecurityElementFactory current = (ISecurityElementFactory)elChild.InternalChildren[i];
- Contract.Assert( !current.GetTag().Equals( parent.Tag ),
- "Illegal to insert a like-typed element" );
- parent.AddChildNoDuplicates( current );
- }
- }
- else
- {
- parent.AddChild( (ISecurityElementFactory)(copy ? child.Copy() : child) );
- }
- }
-#endif // FEATURE_CAS_POLICY
-
internal void InplaceIntersect( PermissionSet other )
{
Exception savedException = null;
@@ -796,81 +647,24 @@ namespace System.Security {
{
Object thisObj = this.m_permSet.GetItem( i );
IPermission thisPerm = thisObj as IPermission;
-#if FEATURE_CAS_POLICY
- ISecurityElementFactory thisElem = thisObj as ISecurityElementFactory;
-#endif // FEATURE_CAS_POLICY
Object otherObj = other.m_permSet.GetItem( i );
IPermission otherPerm = otherObj as IPermission;
-#if FEATURE_CAS_POLICY
- ISecurityElementFactory otherElem = otherObj as ISecurityElementFactory;
-#endif // FEATURE_CAS_POLICY
if (thisObj == null && otherObj == null)
continue;
-#if FEATURE_CAS_POLICY
- if (thisElem != null && otherElem != null)
- {
- // If we already have an intersection node, just add another child
- if (thisElem.GetTag().Equals( s_str_PermissionIntersection ) ||
- thisElem.GetTag().Equals( s_str_PermissionUnrestrictedIntersection ))
- {
- Contract.Assert( thisElem is SecurityElement, "SecurityElement expected" );
- SafeChildAdd( (SecurityElement)thisElem, otherElem, true );
- }
- // If either set is unrestricted, intersect the nodes unrestricted
- else
- {
- bool copyOther = true;
- if (this.IsUnrestricted())
- {
- SecurityElement newElemUU = new SecurityElement( s_str_PermissionUnrestrictedUnion );
- newElemUU.AddAttribute( "class", thisElem.Attribute( "class" ) );
- SafeChildAdd( newElemUU, thisElem, false );
- thisElem = newElemUU;
- }
- if (other.IsUnrestricted())
- {
- SecurityElement newElemUU = new SecurityElement( s_str_PermissionUnrestrictedUnion );
- newElemUU.AddAttribute( "class", otherElem.Attribute( "class" ) );
- SafeChildAdd( newElemUU, otherElem, true );
- otherElem = newElemUU;
- copyOther = false;
- }
-
- SecurityElement newElem = new SecurityElement( s_str_PermissionIntersection );
- newElem.AddAttribute( "class", thisElem.Attribute( "class" ) );
-
- SafeChildAdd( newElem, thisElem, false );
- SafeChildAdd( newElem, otherElem, copyOther );
- this.m_permSet.SetItem( i, newElem );
- }
- }
- else
-#endif // FEATURE_CAS_POLICY
if (thisObj == null)
{
// There is no object in <this>, so intersection is empty except for IUnrestrictedPermissions
if (this.IsUnrestricted())
{
-#if FEATURE_CAS_POLICY
- if (otherElem != null)
- {
- SecurityElement newElem = new SecurityElement( s_str_PermissionUnrestrictedIntersection );
- newElem.AddAttribute( "class", otherElem.Attribute( "class" ) );
- SafeChildAdd( newElem, otherElem, true );
- this.m_permSet.SetItem( i, newElem );
- Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
- }
- else
-#endif // FEATURE_CAS_POLICY
{
PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i );
if ((token.m_type & PermissionTokenType.IUnrestricted) != 0)
{
this.m_permSet.SetItem( i, otherPerm.Copy() );
- Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
+ Debug.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
}
}
}
@@ -879,16 +673,6 @@ namespace System.Security {
{
if (other.IsUnrestricted())
{
-#if FEATURE_CAS_POLICY
- if (thisElem != null)
- {
- SecurityElement newElem = new SecurityElement( s_str_PermissionUnrestrictedIntersection );
- newElem.AddAttribute( "class", thisElem.Attribute( "class" ) );
- SafeChildAdd( newElem, thisElem, false );
- this.m_permSet.SetItem( i, newElem );
- }
- else
-#endif // FEATURE_CAS_POLICY
{
PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i );
if ((token.m_type & PermissionTokenType.IUnrestricted) == 0)
@@ -902,13 +686,6 @@ namespace System.Security {
}
else
{
-#if FEATURE_CAS_POLICY
- if (thisElem != null)
- thisPerm = this.CreatePermission(thisElem, i);
- if (otherElem != null)
- otherPerm = other.CreatePermission(otherElem, i);
-#endif // FEATURE_CAS_POLICY
-
try
{
IPermission intersectPerm;
@@ -968,71 +745,23 @@ namespace System.Security {
{
Object thisObj = this.m_permSet.GetItem( i );
IPermission thisPerm = thisObj as IPermission;
-#if FEATURE_CAS_POLICY
- ISecurityElementFactory thisElem = thisObj as ISecurityElementFactory;
-#endif // FEATURE_CAS_POLICY
-
Object otherObj = other.m_permSet.GetItem( i );
IPermission otherPerm = otherObj as IPermission;
-#if FEATURE_CAS_POLICY
- ISecurityElementFactory otherElem = otherObj as ISecurityElementFactory;
-#endif // FEATURE_CAS_POLICY
if (thisObj == null && otherObj == null)
continue;
-#if FEATURE_CAS_POLICY
- if (thisElem != null && otherElem != null)
- {
- bool copyOther = true;
- bool copyThis = true;
- SecurityElement newElem = new SecurityElement( s_str_PermissionIntersection );
- newElem.AddAttribute( "class", otherElem.Attribute( "class" ) );
- if (this.IsUnrestricted())
- {
- SecurityElement newElemUU = new SecurityElement( s_str_PermissionUnrestrictedUnion );
- newElemUU.AddAttribute( "class", thisElem.Attribute( "class" ) );
- SafeChildAdd( newElemUU, thisElem, true );
- copyThis = false;
- thisElem = newElemUU;
- }
- if (other.IsUnrestricted())
- {
- SecurityElement newElemUU = new SecurityElement( s_str_PermissionUnrestrictedUnion );
- newElemUU.AddAttribute( "class", otherElem.Attribute( "class" ) );
- SafeChildAdd( newElemUU, otherElem, true );
- copyOther = false;
- otherElem = newElemUU;
- }
-
- SafeChildAdd( newElem, otherElem, copyOther );
- SafeChildAdd( newElem, thisElem, copyThis );
- pset.m_permSet.SetItem( i, newElem );
- }
- else
-#endif // FEATURE_CAS_POLICY
if (thisObj == null)
{
if (this.m_Unrestricted)
{
-#if FEATURE_CAS_POLICY
- if (otherElem != null)
- {
- SecurityElement newElem = new SecurityElement( s_str_PermissionUnrestrictedIntersection );
- newElem.AddAttribute( "class", otherElem.Attribute( "class" ) );
- SafeChildAdd( newElem, otherElem, true );
- pset.m_permSet.SetItem( i, newElem );
- Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
- }
- else
-#endif // FEATURE_CAS_POLICY
if (otherPerm != null)
{
PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i );
if ((token.m_type & PermissionTokenType.IUnrestricted) != 0)
{
pset.m_permSet.SetItem( i, otherPerm.Copy() );
- Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
+ Debug.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
}
}
}
@@ -1041,37 +770,19 @@ namespace System.Security {
{
if (other.m_Unrestricted)
{
-#if FEATURE_CAS_POLICY
- if (thisElem != null)
- {
- SecurityElement newElem = new SecurityElement( s_str_PermissionUnrestrictedIntersection );
- newElem.AddAttribute( "class", thisElem.Attribute( "class" ) );
- SafeChildAdd( newElem, thisElem, true );
- pset.m_permSet.SetItem( i, newElem );
- Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
- }
- else
-#endif // FEATURE_CAS_POLICY
if (thisPerm != null)
{
PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i );
if ((token.m_type & PermissionTokenType.IUnrestricted) != 0)
{
pset.m_permSet.SetItem( i, thisPerm.Copy() );
- Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
+ Debug.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
}
}
}
}
else
{
-#if FEATURE_CAS_POLICY
- if (thisElem != null)
- thisPerm = this.CreatePermission(thisElem, i);
- if (otherElem != null)
- otherPerm = other.CreatePermission(otherElem, i);
-#endif // FEATURE_CAS_POLICY
-
IPermission intersectPerm;
if (thisPerm == null)
intersectPerm = otherPerm;
@@ -1080,7 +791,7 @@ namespace System.Security {
else
intersectPerm = thisPerm.Intersect( otherPerm );
pset.m_permSet.SetItem( i, intersectPerm );
- Contract.Assert( intersectPerm == null || PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
+ Debug.Assert( intersectPerm == null || PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
}
}
@@ -1102,13 +813,9 @@ namespace System.Security {
// Quick out conditions, union doesn't change this PermissionSet
if (other == null || other.FastIsEmpty())
return;
-
-
- m_CheckedForNonCas = false;
-
+ m_CheckedForNonCas = false;
-
this.m_Unrestricted = this.m_Unrestricted || other.m_Unrestricted;
if (this.m_Unrestricted)
@@ -1124,7 +831,7 @@ namespace System.Security {
int maxMax = -1;
if (other.m_permSet != null)
{
- maxMax = other.m_permSet.GetMaxUsedIndex();
+ maxMax = other.m_permSet.GetMaxUsedIndex();
this.CheckSet();
}
// Save exceptions until the end
@@ -1134,52 +841,15 @@ namespace System.Security {
{
Object thisObj = this.m_permSet.GetItem( i );
IPermission thisPerm = thisObj as IPermission;
-#if FEATURE_CAS_POLICY
- ISecurityElementFactory thisElem = thisObj as ISecurityElementFactory;
-#endif // FEATURE_CAS_POLICY
Object otherObj = other.m_permSet.GetItem( i );
IPermission otherPerm = otherObj as IPermission;
-#if FEATURE_CAS_POLICY
- ISecurityElementFactory otherElem = otherObj as ISecurityElementFactory;
-#endif // FEATURE_CAS_POLICY
if (thisObj == null && otherObj == null)
continue;
-#if FEATURE_CAS_POLICY
- if (thisElem != null && otherElem != null)
- {
- if (thisElem.GetTag().Equals( s_str_PermissionUnion ) ||
- thisElem.GetTag().Equals( s_str_PermissionUnrestrictedUnion ))
- {
- Contract.Assert( thisElem is SecurityElement, "SecurityElement expected" );
- SafeChildAdd( (SecurityElement)thisElem, otherElem, true );
- }
- else
- {
- SecurityElement newElem;
- if (this.IsUnrestricted() || other.IsUnrestricted())
- newElem = new SecurityElement( s_str_PermissionUnrestrictedUnion );
- else
- newElem = new SecurityElement( s_str_PermissionUnion );
- newElem.AddAttribute( "class", thisElem.Attribute( "class" ) );
- SafeChildAdd( newElem, thisElem, false );
- SafeChildAdd( newElem, otherElem, true );
- this.m_permSet.SetItem( i, newElem );
- }
- }
- else
-#endif // FEATURE_CAS_POLICY
if (thisObj == null)
{
-#if FEATURE_CAS_POLICY
- if (otherElem != null)
- {
- this.m_permSet.SetItem( i, otherElem.Copy() );
- }
- else
-#endif // FEATURE_CAS_POLICY
if (otherPerm != null)
{
PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i );
@@ -1195,13 +865,6 @@ namespace System.Security {
}
else
{
-#if FEATURE_CAS_POLICY
- if (thisElem != null)
- thisPerm = this.CreatePermission(thisElem, i);
- if (otherElem != null)
- otherPerm = other.CreatePermission(otherElem, i);
-#endif // FEATURE_CAS_POLICY
-
try
{
IPermission unionPerm;
@@ -1260,82 +923,39 @@ namespace System.Security {
{
Object thisObj = this.m_permSet.GetItem( i );
IPermission thisPerm = thisObj as IPermission;
-#if FEATURE_CAS_POLICY
- ISecurityElementFactory thisElem = thisObj as ISecurityElementFactory;
-#endif // FEATURE_CAS_POLICY
Object otherObj = other.m_permSet.GetItem( i );
IPermission otherPerm = otherObj as IPermission;
-#if FEATURE_CAS_POLICY
- ISecurityElementFactory otherElem = otherObj as ISecurityElementFactory;
-#endif // FEATURE_CAS_POLICY
if (thisObj == null && otherObj == null)
continue;
-#if FEATURE_CAS_POLICY
- if (thisElem != null && otherElem != null)
- {
- SecurityElement newElem;
- if (this.IsUnrestricted() || other.IsUnrestricted())
- newElem = new SecurityElement( s_str_PermissionUnrestrictedUnion );
- else
- newElem = new SecurityElement( s_str_PermissionUnion );
- newElem.AddAttribute( "class", thisElem.Attribute( "class" ) );
- SafeChildAdd( newElem, thisElem, true );
- SafeChildAdd( newElem, otherElem, true );
- pset.m_permSet.SetItem( i, newElem );
- }
- else
-#endif // FEATURE_CAS_POLICY
if (thisObj == null)
{
-#if FEATURE_CAS_POLICY
- if (otherElem != null)
- {
- pset.m_permSet.SetItem( i, otherElem.Copy() );
- Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
- }
- else
-#endif // FEATURE_CAS_POLICY
if (otherPerm != null)
{
PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i );
if (((token.m_type & PermissionTokenType.IUnrestricted) == 0) || !pset.m_Unrestricted)
{
pset.m_permSet.SetItem( i, otherPerm.Copy() );
- Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
+ Debug.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
}
}
}
else if (otherObj == null)
{
-#if FEATURE_CAS_POLICY
- if (thisElem != null)
- {
- pset.m_permSet.SetItem( i, thisElem.Copy() );
- }
- else
-#endif // FEATURE_CAS_POLICY
if (thisPerm != null)
{
PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i );
if (((token.m_type & PermissionTokenType.IUnrestricted) == 0) || !pset.m_Unrestricted)
{
pset.m_permSet.SetItem( i, thisPerm.Copy() );
- Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
+ Debug.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
}
}
}
else
{
-#if FEATURE_CAS_POLICY
- if (thisElem != null)
- thisPerm = this.CreatePermission(thisElem, i);
- if (otherElem != null)
- otherPerm = other.CreatePermission(otherElem, i);
-#endif // FEATURE_CAS_POLICY
-
IPermission unionPerm;
if(thisPerm == null)
unionPerm = otherPerm;
@@ -1344,10 +964,10 @@ namespace System.Security {
else
unionPerm = thisPerm.Union( otherPerm );
pset.m_permSet.SetItem( i, unionPerm );
- Contract.Assert( unionPerm == null || PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
+ Debug.Assert( unionPerm == null || PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
}
}
-
+
return pset;
}
@@ -1492,7 +1112,6 @@ namespace System.Security {
// Mark this method as requiring a security object on the caller's frame
// so the caller won't be inlined (which would mess up stack crawling).
- [System.Security.SecuritySafeCritical] // auto-generated
[DynamicSecurityMethodAttribute()]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public void Demand()
@@ -1513,7 +1132,6 @@ namespace System.Security {
}
}
- [System.Security.SecurityCritical] // auto-generated
internal void DemandNonCAS()
{
ContainsNonCodeAccessPermissions();
@@ -1536,7 +1154,6 @@ namespace System.Security {
// Metadata for this method should be flaged with REQ_SQ so that
// EE can allocate space on the stack frame for FrameSecurityDescriptor
- [System.Security.SecuritySafeCritical] // auto-generated
[DynamicSecurityMethodAttribute()]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public void Assert()
@@ -1548,7 +1165,6 @@ namespace System.Security {
// Metadata for this method should be flaged with REQ_SQ so that
// EE can allocate space on the stack frame for FrameSecurityDescriptor
- [System.Security.SecuritySafeCritical] // auto-generated
[DynamicSecurityMethodAttribute()]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
[Obsolete("Deny is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
@@ -1561,7 +1177,6 @@ namespace System.Security {
// Metadata for this method should be flaged with REQ_SQ so that
// EE can allocate space on the stack frame for FrameSecurityDescriptor
- [System.Security.SecuritySafeCritical] // auto-generated
[DynamicSecurityMethodAttribute()]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public void PermitOnly()
@@ -1588,21 +1203,7 @@ namespace System.Security {
{
// Explicitly make a new PermissionSet, rather than copying, since we may have a
// ReadOnlyPermissionSet which cannot have identity permissions removed from it in a true copy.
- PermissionSet copy = new PermissionSet(this);
-
- // There's no easy way to distinguish an identity permission from any other CodeAccessPermission,
- // so remove them directly.
-#if FEATURE_CAS_POLICY
- copy.RemovePermission(typeof(GacIdentityPermission));
-#if FEATURE_X509
- copy.RemovePermission(typeof(PublisherIdentityPermission));
-#endif
- copy.RemovePermission(typeof(StrongNameIdentityPermission));
- copy.RemovePermission(typeof(UrlIdentityPermission));
- copy.RemovePermission(typeof(ZoneIdentityPermission));
-#endif // FEATURE_CAS_POLICY
-
- return copy;
+ return new PermissionSet(this);
}
public IEnumerator GetEnumerator()
@@ -1620,13 +1221,6 @@ namespace System.Security {
return new PermissionSetEnumeratorInternal(this);
}
-#if FEATURE_CAS_POLICY
- public override String ToString()
- {
- return ToXml().ToString();
- }
-#endif // FEATURE_CAS_POLICY
-
private void NormalizePermissionSet()
{
// This function guarantees that all the permissions are placed at
@@ -1645,12 +1239,6 @@ namespace System.Security {
{
Object obj = this.m_permSet.GetItem(i);
IPermission perm = obj as IPermission;
-#if FEATURE_CAS_POLICY
- ISecurityElementFactory elem = obj as ISecurityElementFactory;
-
- if (elem != null)
- perm = CreatePerm( elem );
-#endif // FEATURE_CAS_POLICY
if (perm != null)
permSetTemp.SetPermission( perm );
}
@@ -1659,29 +1247,6 @@ namespace System.Security {
this.m_permSet = permSetTemp.m_permSet;
}
-#if FEATURE_CAS_POLICY
- private bool DecodeXml(byte[] data, HostProtectionResource fullTrustOnlyResources, HostProtectionResource inaccessibleResources )
- {
- if (data != null && data.Length > 0)
- {
- FromXml( new Parser( data, Tokenizer.ByteTokenEncoding.UnicodeTokens ).GetTopElement() );
- }
-
- FilterHostProtectionPermissions(fullTrustOnlyResources, inaccessibleResources);
-
- // We call this method from unmanaged to code a set we are going to use declaratively. In
- // this case, all the lazy evaluation for partial policy resolution is wasted since we'll
- // need to decode all of these shortly to make the demand for whatever. Therefore, we
- // pay that price now so that we can calculate whether all the permissions in the set
- // implement the IUnrestrictedPermission interface (the common case) for use in some
- // unmanaged optimizations.
-
- DecodeAllPermissions();
-
- return true;
- }
-#endif // FEATURE_CAS_POLICY
-
private void DecodeAllPermissions()
{
if (m_permSet == null)
@@ -1710,11 +1275,7 @@ namespace System.Security {
HostProtectionPermission newHpp = (HostProtectionPermission)hpp.Intersect(new HostProtectionPermission(fullTrustOnly));
if (newHpp == null)
{
-#if FEATURE_CAS_POLICY
- RemovePermission(typeof(HostProtectionPermission));
-#else // !FEATURE_CAS_POLICY
RemovePermission(HostProtectionPermission.GetTokenIndex());
-#endif // FEATURE_CAS_POLICY
}
else if (newHpp.Resources != hpp.Resources)
{
@@ -1722,539 +1283,8 @@ namespace System.Security {
}
}
-#if FEATURE_CAS_POLICY
- public virtual void FromXml( SecurityElement et )
- {
- FromXml( et, false, false );
- }
-
- internal static bool IsPermissionTag( String tag, bool allowInternalOnly )
- {
- if (tag.Equals( s_str_Permission ) ||
- tag.Equals( s_str_IPermission ))
- {
- return true;
- }
-
- if (allowInternalOnly &&
- (tag.Equals( s_str_PermissionUnion ) ||
- tag.Equals( s_str_PermissionIntersection ) ||
- tag.Equals( s_str_PermissionUnrestrictedIntersection ) ||
- tag.Equals( s_str_PermissionUnrestrictedUnion)))
- {
- return true;
- }
-
- return false;
- }
-
- internal virtual void FromXml( SecurityElement et, bool allowInternalOnly, bool ignoreTypeLoadFailures )
- {
- if (et == null)
- throw new ArgumentNullException("et");
-
- if (!et.Tag.Equals(s_str_PermissionSet))
- throw new ArgumentException(String.Format( null, Environment.GetResourceString( "Argument_InvalidXMLElement" ), "PermissionSet", this.GetType().FullName) );
- Contract.EndContractBlock();
-
- Reset();
- m_ignoreTypeLoadFailures = ignoreTypeLoadFailures;
- m_allPermissionsDecoded = false;
- m_Unrestricted = XMLUtil.IsUnrestricted( et );
-
- if (et.InternalChildren != null)
- {
- int childCount = et.InternalChildren.Count;
- for (int i = 0; i < childCount; ++i)
- {
- SecurityElement elem = (SecurityElement)et.Children[i];
-
- if (IsPermissionTag( elem.Tag, allowInternalOnly ))
- {
- String className = elem.Attribute( "class" );
-
- PermissionToken token;
- Object objectToInsert;
-
- if (className != null)
- {
- token = PermissionToken.GetToken( className );
- if (token == null)
- {
- objectToInsert = CreatePerm( elem );
-#if _DEBUG
- PermissionToken tokenDebug = PermissionToken.GetToken( (IPermission)objectToInsert );
- Contract.Assert( tokenDebug != null && (tokenDebug.m_type & PermissionTokenType.BuiltIn) != 0, "This should only be called for built-ins" );
-#endif
- if (objectToInsert != null)
- {
- Contract.Assert( objectToInsert.GetType().Module.Assembly == System.Reflection.Assembly.GetExecutingAssembly(),
- "PermissionToken.GetToken returned null for non-mscorlib permission" );
- token = PermissionToken.GetToken( (IPermission)objectToInsert );
- Contract.Assert( (token.m_type & PermissionTokenType.DontKnow) == 0, "We should always know the permission type when getting a token from an instance" );
- }
- }
- else
- {
- objectToInsert = elem;
- }
- }
- else
- {
- IPermission ip = CreatePerm( elem );
- if (ip == null)
- {
- token = null;
- objectToInsert = null;
- }
- else
- {
- token = PermissionToken.GetToken( ip );
- Contract.Assert( PermissionToken.IsTokenProperlyAssigned( ip, token ),
- "PermissionToken was improperly assigned" );
- objectToInsert = ip;
- }
- }
-
- if (token != null && objectToInsert != null)
- {
- if (m_permSet == null)
- m_permSet = new TokenBasedSet();
-
- if (this.m_permSet.GetItem( token.m_index ) != null)
- {
- // If there is already something in that slot, let's union them
- // together.
-
- IPermission permInSlot;
-
- if (this.m_permSet.GetItem( token.m_index ) is IPermission)
- permInSlot = (IPermission)this.m_permSet.GetItem( token.m_index );
- else
- permInSlot = CreatePerm( (SecurityElement)this.m_permSet.GetItem( token.m_index ) );
-
- if (objectToInsert is IPermission)
- objectToInsert = ((IPermission)objectToInsert).Union( permInSlot );
- else
- objectToInsert = CreatePerm( (SecurityElement)objectToInsert ).Union( permInSlot );
- }
-
- if(m_Unrestricted && objectToInsert is IPermission)
- objectToInsert = null;
-
- this.m_permSet.SetItem( token.m_index, objectToInsert );
- }
- }
- }
- }
- }
-
- internal virtual void FromXml( SecurityDocument doc, int position, bool allowInternalOnly )
- {
- if (doc == null)
- throw new ArgumentNullException("doc");
- Contract.EndContractBlock();
-
- if (!doc.GetTagForElement( position ).Equals(s_str_PermissionSet))
- throw new ArgumentException(String.Format( null, Environment.GetResourceString( "Argument_InvalidXMLElement" ), "PermissionSet", this.GetType().FullName) );
-
- Reset();
- m_allPermissionsDecoded = false;
- Exception savedException = null;
- String strUnrestricted = doc.GetAttributeForElement( position, "Unrestricted" );
- if (strUnrestricted != null)
- m_Unrestricted = strUnrestricted.Equals( "True" ) || strUnrestricted.Equals( "true" ) || strUnrestricted.Equals( "TRUE" );
- else
- m_Unrestricted = false;
-
- ArrayList childrenIndices = doc.GetChildrenPositionForElement( position );
- int childCount = childrenIndices.Count;
- for (int i = 0; i < childCount; ++i)
- {
- int childIndex = (int)childrenIndices[i];
- if (IsPermissionTag( doc.GetTagForElement( childIndex ), allowInternalOnly ))
- {
- try
- {
- String className = doc.GetAttributeForElement( childIndex, "class" );
-
- PermissionToken token;
- Object objectToInsert;
-
- if (className != null)
- {
- token = PermissionToken.GetToken( className );
- if (token == null)
- {
- objectToInsert = CreatePerm( doc.GetElement( childIndex, true ) );
-
- if (objectToInsert != null)
- {
-#if _DEBUG
- PermissionToken tokenDebug = PermissionToken.GetToken( (IPermission)objectToInsert );
- Contract.Assert((tokenDebug != null), "PermissionToken.GetToken returned null ");
- Contract.Assert( (tokenDebug.m_type & PermissionTokenType.BuiltIn) != 0, "This should only be called for built-ins" );
-#endif
- Contract.Assert( objectToInsert.GetType().Module.Assembly == System.Reflection.Assembly.GetExecutingAssembly(),
- "PermissionToken.GetToken returned null for non-mscorlib permission" );
- token = PermissionToken.GetToken( (IPermission)objectToInsert );
- Contract.Assert((token != null), "PermissionToken.GetToken returned null ");
- Contract.Assert( (token.m_type & PermissionTokenType.DontKnow) == 0, "We should always know the permission type when getting a token from an instance" );
- }
- }
- else
- {
- objectToInsert = ((ISecurityElementFactory)new SecurityDocumentElement(doc, childIndex)).CreateSecurityElement();
- }
- }
- else
- {
- IPermission ip = CreatePerm( doc.GetElement( childIndex, true ) );
- if (ip == null)
- {
- token = null;
- objectToInsert = null;
- }
- else
- {
- token = PermissionToken.GetToken( ip );
- Contract.Assert( PermissionToken.IsTokenProperlyAssigned( ip, token ),
- "PermissionToken was improperly assigned" );
- objectToInsert = ip;
- }
- }
-
- if (token != null && objectToInsert != null)
- {
- if (m_permSet == null)
- m_permSet = new TokenBasedSet();
-
- IPermission permInSlot = null;
- if (this.m_permSet.GetItem( token.m_index ) != null)
- {
- // If there is already something in that slot, let's union them
- // together.
-
- if (this.m_permSet.GetItem( token.m_index ) is IPermission)
- permInSlot = (IPermission)this.m_permSet.GetItem( token.m_index );
- else
- permInSlot = CreatePerm( this.m_permSet.GetItem( token.m_index ) );
- }
-
- if (permInSlot != null)
- {
- if (objectToInsert is IPermission)
- objectToInsert = permInSlot.Union((IPermission)objectToInsert);
- else
- objectToInsert = permInSlot.Union(CreatePerm( objectToInsert ));
- }
-
- if(m_Unrestricted && objectToInsert is IPermission)
- objectToInsert = null;
-
- this.m_permSet.SetItem( token.m_index, objectToInsert );
- }
- }
- catch (Exception e)
- {
-#if _DEBUG
- if (debug)
- DEBUG_WRITE( "error while decoding permission set =\n" + e.ToString() );
-#endif
- if (savedException == null)
- savedException = e;
-
- }
- }
- }
-
- if (savedException != null)
- throw savedException;
-
- }
-
- private IPermission CreatePerm(Object obj)
- {
- return CreatePerm(obj, m_ignoreTypeLoadFailures);
- }
-
- internal static IPermission CreatePerm(Object obj, bool ignoreTypeLoadFailures)
- {
- SecurityElement el = obj as SecurityElement;
- ISecurityElementFactory isf = obj as ISecurityElementFactory;
- if (el == null && isf != null)
- {
- el = isf.CreateSecurityElement();
- }
-
- IEnumerator enumerator;
- IPermission finalPerm = null;
-
- switch (el.Tag)
- {
- case s_str_PermissionUnion:
- enumerator = el.Children.GetEnumerator();
- while (enumerator.MoveNext())
- {
- IPermission tempPerm = CreatePerm( (SecurityElement)enumerator.Current, ignoreTypeLoadFailures);
-
- if (finalPerm != null)
- finalPerm = finalPerm.Union( tempPerm );
- else
- finalPerm = tempPerm;
- }
- break;
-
- case s_str_PermissionIntersection:
- enumerator = el.Children.GetEnumerator();
- while (enumerator.MoveNext())
- {
- IPermission tempPerm = CreatePerm( (SecurityElement)enumerator.Current, ignoreTypeLoadFailures);
-
- if (finalPerm != null)
- finalPerm = finalPerm.Intersect( tempPerm );
- else
- finalPerm = tempPerm;
-
- if (finalPerm == null)
- return null;
- }
- break;
-
- case s_str_PermissionUnrestrictedUnion:
- enumerator = el.Children.GetEnumerator();
- bool first = true;
- while (enumerator.MoveNext())
- {
- IPermission tempPerm = CreatePerm( (SecurityElement)enumerator.Current, ignoreTypeLoadFailures );
-
- if (tempPerm == null)
- continue;
-
- PermissionToken token = PermissionToken.GetToken( tempPerm );
-
- Contract.Assert( (token.m_type & PermissionTokenType.DontKnow) == 0, "We should know the permission type already" );
-
- if ((token.m_type & PermissionTokenType.IUnrestricted) != 0)
- {
- finalPerm = XMLUtil.CreatePermission( GetPermissionElement((SecurityElement)enumerator.Current), PermissionState.Unrestricted, ignoreTypeLoadFailures );
- first = false;
- break;
- }
- else
- {
- Contract.Assert( tempPerm != null, "We should only come here if we have a real permission" );
- if (first)
- finalPerm = tempPerm;
- else
- finalPerm = tempPerm.Union( finalPerm );
- first = false;
- }
- }
- break;
-
- case s_str_PermissionUnrestrictedIntersection:
- enumerator = el.Children.GetEnumerator();
- while (enumerator.MoveNext())
- {
- IPermission tempPerm = CreatePerm( (SecurityElement)enumerator.Current, ignoreTypeLoadFailures );
-
- if (tempPerm == null)
- return null;
-
- PermissionToken token = PermissionToken.GetToken( tempPerm );
-
- Contract.Assert( (token.m_type & PermissionTokenType.DontKnow) == 0, "We should know the permission type already" );
-
- if ((token.m_type & PermissionTokenType.IUnrestricted) != 0)
- {
- if (finalPerm != null)
- finalPerm = tempPerm.Intersect( finalPerm );
- else
- finalPerm = tempPerm;
- }
- else
- {
- finalPerm = null;
- }
-
- if (finalPerm == null)
- return null;
- }
- break;
-
- case "IPermission":
- case "Permission":
- finalPerm = el.ToPermission(ignoreTypeLoadFailures);
- break;
-
- default:
- Contract.Assert( false, "Unrecognized case found during permission creation" );
- break;
- }
-
- return finalPerm;
- }
-
- internal IPermission CreatePermission(Object obj, int index)
- {
- IPermission perm = CreatePerm(obj);
- if(perm == null)
- return null;
-
- // See if the PermissionSet.m_Unrestricted flag covers this permission
- if(m_Unrestricted)
- perm = null;
-
- // Store the decoded result
- CheckSet();
- m_permSet.SetItem(index, perm);
-
- // Do some consistency checks
- Contract.Assert(perm == null || PermissionToken.IsTokenProperlyAssigned( perm, PermissionToken.GetToken( perm ) ), "PermissionToken was improperly assigned");
- if (perm != null)
- {
- PermissionToken permToken = PermissionToken.GetToken(perm);
- if (permToken != null && permToken.m_index != index)
- throw new ArgumentException( Environment.GetResourceString( "Argument_UnableToGeneratePermissionSet"));
- }
-
-
- return perm;
- }
-
- private static SecurityElement GetPermissionElement( SecurityElement el )
- {
- switch (el.Tag)
- {
- case "IPermission":
- case "Permission":
- return el;
- }
- IEnumerator enumerator = el.Children.GetEnumerator();
- if (enumerator.MoveNext())
- return GetPermissionElement((SecurityElement)enumerator.Current);
- Contract.Assert( false, "No Permission or IPermission tag found" );
- return null;
- }
-
- internal static SecurityElement CreateEmptyPermissionSetXml()
- {
-
- SecurityElement elTrunk = new SecurityElement("PermissionSet");
- elTrunk.AddAttribute( "class", "System.Security.PermissionSet" );
-
- elTrunk.AddAttribute( "version", "1" );
- return elTrunk;
-
- }
- // internal helper which takes in the hardcoded permission name to avoid lookup at runtime
- // can be called from classes that derive from PermissionSet
- internal SecurityElement ToXml(String permName)
- {
- SecurityElement elTrunk = new SecurityElement("PermissionSet");
- elTrunk.AddAttribute( "class", permName );
-
- elTrunk.AddAttribute( "version", "1" );
-
- PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(this);
-
- if (m_Unrestricted)
- {
- elTrunk.AddAttribute(s_str_Unrestricted, "true" );
- }
-
- while (enumerator.MoveNext())
- {
- IPermission perm = (IPermission)enumerator.Current;
-
- if (!m_Unrestricted)
- elTrunk.AddChild( perm.ToXml() );
- }
- return elTrunk;
- }
-
- internal SecurityElement InternalToXml()
- {
- SecurityElement elTrunk = new SecurityElement("PermissionSet");
- elTrunk.AddAttribute( "class", this.GetType().FullName);
- elTrunk.AddAttribute( "version", "1" );
-
- if (m_Unrestricted)
- {
- elTrunk.AddAttribute(s_str_Unrestricted, "true" );
- }
-
- if (this.m_permSet != null)
- {
- int maxIndex = this.m_permSet.GetMaxUsedIndex();
-
- for (int i = m_permSet.GetStartingIndex(); i <= maxIndex; ++i)
- {
- Object obj = this.m_permSet.GetItem( i );
- if (obj != null)
- {
- if (obj is IPermission)
- {
- if (!m_Unrestricted)
- elTrunk.AddChild( ((IPermission)obj).ToXml() );
- }
- else
- {
- elTrunk.AddChild( (SecurityElement)obj );
- }
- }
-
- }
- }
- return elTrunk ;
- }
-
- public virtual SecurityElement ToXml()
- {
- // If you hit this assert then most likely you are trying to change the name of this class.
- // This is ok as long as you change the hard coded string above and change the assert below.
- Contract.Assert( this.GetType().FullName.Equals( "System.Security.PermissionSet" ), "Class name changed! Was: System.Security.PermissionSet Should be:" + this.GetType().FullName);
-
- return ToXml("System.Security.PermissionSet");
- }
-#endif // FEATURE_CAS_POLICY
-
-#if FEATURE_CAS_POLICY && FEATURE_SERIALIZATION
- internal
- byte[] EncodeXml()
- {
- MemoryStream ms = new MemoryStream();
- BinaryWriter writer = new BinaryWriter( ms, Encoding.Unicode );
- writer.Write( this.ToXml().ToString() );
- writer.Flush();
-
- // The BinaryWriter is going to place
- // two bytes indicating a Unicode stream.
- // We want to chop those off before returning
- // the bytes out.
-
- ms.Position = 2;
- int countBytes = (int)ms.Length - 2;
- byte[] retval = new byte[countBytes];
- ms.Read( retval, 0, retval.Length );
- return retval;
- }
-
- /// <internalonly/>
- [Obsolete("This method is obsolete and shoud no longer be used.")]
- public static byte[] ConvertPermissionSet(String inFormat, byte[] inData, String outFormat)
- {
- // Since this method has shipped and is public, we cannot remove it without being a breaking change
- throw new NotImplementedException();
- }
-#endif
-
// Determines whether the permission set contains any non-code access
// security permissions.
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
public bool ContainsNonCodeAccessPermissions()
{
if (m_CheckedForNonCas)
@@ -2324,59 +1354,11 @@ namespace System.Security {
return pset;
}
-#if FEATURE_CAS_POLICY
- private const String s_str_PermissionSet = "PermissionSet";
- private const String s_str_Permission = "Permission";
- private const String s_str_IPermission = "IPermission";
- private const String s_str_Unrestricted = "Unrestricted";
- private const String s_str_PermissionUnion = "PermissionUnion";
- private const String s_str_PermissionIntersection = "PermissionIntersection";
- private const String s_str_PermissionUnrestrictedUnion = "PermissionUnrestrictedUnion";
- private const String s_str_PermissionUnrestrictedIntersection = "PermissionUnrestrictedIntersection";
-
- // This method supports v1.x security attrbutes only - we'll require legacy CAS policy mode
- // to be enabled for that to work.
-#pragma warning disable 618
- // Internal routine used to setup a special security context
- // for creating and manipulated security custom attributes
- // that we use when the Runtime is hosted.
- [System.Security.SecurityCritical] // auto-generated
- private static void SetupSecurity()
- {
- PolicyLevel level = PolicyLevel.CreateAppDomainLevel();
-
- CodeGroup rootGroup = new UnionCodeGroup( new AllMembershipCondition(), level.GetNamedPermissionSet( "Execution" ) );
-
- StrongNamePublicKeyBlob microsoftBlob = new StrongNamePublicKeyBlob( AssemblyRef.MicrosoftPublicKeyFull );
- CodeGroup microsoftGroup = new UnionCodeGroup( new StrongNameMembershipCondition( microsoftBlob, null, null ), level.GetNamedPermissionSet( "FullTrust" ) );
-
- StrongNamePublicKeyBlob ecmaBlob = new StrongNamePublicKeyBlob( AssemblyRef.EcmaPublicKeyFull );
- CodeGroup ecmaGroup = new UnionCodeGroup( new StrongNameMembershipCondition( ecmaBlob, null, null ), level.GetNamedPermissionSet( "FullTrust" ) );
-
- CodeGroup gacGroup = new UnionCodeGroup( new GacMembershipCondition(), level.GetNamedPermissionSet( "FullTrust" ) );
-
- rootGroup.AddChild( microsoftGroup );
- rootGroup.AddChild( ecmaGroup );
- rootGroup.AddChild( gacGroup );
-
- level.RootCodeGroup = rootGroup;
-
- try
- {
- AppDomain.CurrentDomain.SetAppDomainPolicy( level );
- }
- catch (PolicyException)
- {
- }
- }
-#endif
-#pragma warning restore 618
-
// Internal routine used by CreateSerialized to add a permission to the set
private static void MergePermission(IPermission perm, bool separateCasFromNonCas, ref PermissionSet casPset, ref PermissionSet nonCasPset)
{
- Contract.Assert(casPset == null || !casPset.IsReadOnly);
- Contract.Assert(nonCasPset == null || !nonCasPset.IsReadOnly);
+ Debug.Assert(casPset == null || !casPset.IsReadOnly);
+ Debug.Assert(nonCasPset == null || !nonCasPset.IsReadOnly);
if (perm == null)
return;
@@ -2402,9 +1384,6 @@ namespace System.Security {
}
// Converts an array of SecurityAttributes to a PermissionSet
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
private static byte[] CreateSerialized(Object[] attrs,
bool serialize,
ref byte[] nonCasBlob,
@@ -2422,7 +1401,7 @@ namespace System.Security {
for (int i = 0; i < attrs.Length; i++)
{
#pragma warning disable 618
- Contract.Assert(i == 0 || ((SecurityAttribute)attrs[i]).m_action == ((SecurityAttribute)attrs[i - 1]).m_action, "Mixed SecurityActions");
+ Debug.Assert(i == 0 || ((SecurityAttribute)attrs[i]).m_action == ((SecurityAttribute)attrs[i - 1]).m_action, "Mixed SecurityActions");
#pragma warning restore 618
if (attrs[i] is PermissionSetAttribute)
{
@@ -2451,7 +1430,7 @@ namespace System.Security {
MergePermission(perm, serialize, ref casPset, ref nonCasPset);
}
}
- Contract.Assert(serialize || nonCasPset == null, "We shouldn't separate nonCAS permissions unless fSerialize is true");
+ Debug.Assert(serialize || nonCasPset == null, "We shouldn't separate nonCAS permissions unless fSerialize is true");
//
// Filter HostProtection permission. In the VM, some optimizations are done based upon these
@@ -2475,22 +1454,8 @@ namespace System.Security {
nonCasPset = null;
}
- // Serialize the set(s).
- byte[] casBlob = null;
- nonCasBlob = null;
-#if FEATURE_CAS_POLICY
- if(serialize)
- {
- if(casPset != null)
- casBlob = casPset.EncodeXml();
- if(nonCasPset != null)
- nonCasBlob = nonCasPset.EncodeXml();
- }
-#else // FEATURE_CAS_POLICY
- Contract.Assert(!serialize, "Cannot serialize permission sets on CoreCLR");
-#endif // FEATURE_CAS_POLICY
-
- return casBlob;
+ Debug.Assert(!serialize, "Cannot serialize permission sets on CoreCLR");
+ return null;
}
#if FEATURE_SERIALIZATION
@@ -2502,7 +1467,6 @@ namespace System.Security {
}
#endif
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static void RevertAssert()
{
@@ -2512,7 +1476,7 @@ namespace System.Security {
internal static PermissionSet RemoveRefusedPermissionSet(PermissionSet assertSet, PermissionSet refusedSet, out bool bFailedToCompress)
{
- Contract.Assert((assertSet == null || !assertSet.IsUnrestricted()), "Cannot be unrestricted here");
+ Debug.Assert((assertSet == null || !assertSet.IsUnrestricted()), "Cannot be unrestricted here");
PermissionSet retPs = null;
bFailedToCompress = false;
if (assertSet == null)
@@ -2568,7 +1532,7 @@ namespace System.Security {
internal static void RemoveAssertedPermissionSet(PermissionSet demandSet, PermissionSet assertSet, out PermissionSet alteredDemandSet)
{
- Contract.Assert(!assertSet.IsUnrestricted(), "Cannot call this function if assertSet is unrestricted");
+ Debug.Assert(!assertSet.IsUnrestricted(), "Cannot call this function if assertSet is unrestricted");
alteredDemandSet = null;
PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(demandSet);
diff --git a/src/mscorlib/src/System/Security/PermissionSetEnumerator.cs b/src/mscorlib/src/System/Security/PermissionSetEnumerator.cs
index 55b56cb570..7b234e9cf4 100644
--- a/src/mscorlib/src/System/Security/PermissionSetEnumerator.cs
+++ b/src/mscorlib/src/System/Security/PermissionSetEnumerator.cs
@@ -81,20 +81,6 @@ namespace System.Security
enm.Current = perm;
return true;
}
-
-#if FEATURE_CAS_POLICY
- SecurityElement elem = obj as SecurityElement;
-
- if (elem != null)
- {
- perm = m_permSet.CreatePermission(elem, enm.Index);
- if (perm != null)
- {
- enm.Current = perm;
- return true;
- }
- }
-#endif // FEATURE_CAS_POLICY
}
return false;
}
diff --git a/src/mscorlib/src/System/Security/PermissionSetTriple.cs b/src/mscorlib/src/System/Security/PermissionSetTriple.cs
index f1527ac4b1..56eb22996e 100644
--- a/src/mscorlib/src/System/Security/PermissionSetTriple.cs
+++ b/src/mscorlib/src/System/Security/PermissionSetTriple.cs
@@ -19,6 +19,7 @@ namespace System.Security
using System.Security;
using System.Security.Permissions;
using System.Runtime.InteropServices;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
@@ -53,7 +54,6 @@ namespace System.Security
private PermissionToken ZoneToken
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (s_zoneToken == null)
@@ -63,7 +63,6 @@ namespace System.Security
}
private PermissionToken UrlToken
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (s_urlToken == null)
@@ -71,7 +70,6 @@ namespace System.Security
return s_urlToken;
}
}
- [System.Security.SecurityCritical] // auto-generated
internal bool Update(PermissionSetTriple psTriple, out PermissionSetTriple retTriple)
{
retTriple = null;
@@ -86,13 +84,12 @@ namespace System.Security
return false;
}
- [System.Security.SecurityCritical] // auto-generated
internal PermissionSetTriple UpdateAssert(PermissionSet in_a)
{
PermissionSetTriple retTriple = null;
if (in_a != null)
{
- Contract.Assert((!in_a.IsUnrestricted() || RefusedSet == null), "Cannot be unrestricted or refused must be null");
+ Debug.Assert((!in_a.IsUnrestricted() || RefusedSet == null), "Cannot be unrestricted or refused must be null");
// if we're already asserting in_a, nothing to do
if (in_a.IsSubsetOf(AssertSet))
return null;
@@ -128,7 +125,6 @@ namespace System.Security
}
return retTriple;
}
- [System.Security.SecurityCritical] // auto-generated
internal void UpdateGrant(PermissionSet in_g, out ZoneIdentityPermission z,out UrlIdentityPermission u)
{
z = null;
@@ -145,7 +141,6 @@ namespace System.Security
}
}
- [System.Security.SecurityCritical] // auto-generated
internal void UpdateGrant(PermissionSet in_g)
{
if (in_g != null)
@@ -168,7 +163,6 @@ namespace System.Security
}
- [System.Security.SecurityCritical] // auto-generated
static bool CheckAssert(PermissionSet pSet, CodeAccessPermission demand, PermissionToken permToken)
{
if (pSet != null)
@@ -193,7 +187,6 @@ namespace System.Security
return SecurityRuntime.StackContinue;
}
- [System.Security.SecurityCritical] // auto-generated
static bool CheckAssert(PermissionSet assertPset, PermissionSet demandSet, out PermissionSet newDemandSet)
{
newDemandSet = null;
@@ -210,7 +203,6 @@ namespace System.Security
}
- [System.Security.SecurityCritical] // auto-generated
internal bool CheckDemand(CodeAccessPermission demand, PermissionToken permToken, RuntimeMethodHandleInternal rmh)
{
if (CheckAssert(AssertSet, demand, permToken) == SecurityRuntime.StackHalt)
@@ -222,7 +214,6 @@ namespace System.Security
return SecurityRuntime.StackContinue;
}
- [System.Security.SecurityCritical] // auto-generated
internal bool CheckSetDemand(PermissionSet demandSet , out PermissionSet alteredDemandset, RuntimeMethodHandleInternal rmh)
{
alteredDemandset = null;
@@ -239,18 +230,16 @@ namespace System.Security
}
- [System.Security.SecurityCritical] // auto-generated
internal bool CheckDemandNoThrow(CodeAccessPermission demand, PermissionToken permToken)
{
- Contract.Assert(AssertSet == null, "AssertSet not null");
+ Debug.Assert(AssertSet == null, "AssertSet not null");
#pragma warning disable 618
return CodeAccessSecurityEngine.CheckHelper(GrantSet, RefusedSet, demand, permToken, RuntimeMethodHandleInternal.EmptyHandle, null, SecurityAction.Demand, false);
#pragma warning restore 618
}
- [System.Security.SecurityCritical] // auto-generated
internal bool CheckSetDemandNoThrow(PermissionSet demandSet)
{
- Contract.Assert(AssertSet == null, "AssertSet not null");
+ Debug.Assert(AssertSet == null, "AssertSet not null");
#pragma warning disable 618
return CodeAccessSecurityEngine.CheckSetHelper(GrantSet, RefusedSet, demandSet, RuntimeMethodHandleInternal.EmptyHandle, null, SecurityAction.Demand, false);
@@ -263,7 +252,6 @@ namespace System.Security
/// If the triple asserts for one of the bits in the flags, it is zeroed out.
/// </remarks>
/// <param name="flags">set of flags to check (See PermissionType)</param>
- [System.Security.SecurityCritical] // auto-generated
internal bool CheckFlags(ref int flags)
{
if (AssertSet != null)
diff --git a/src/mscorlib/src/System/Security/PermissionToken.cs b/src/mscorlib/src/System/Security/PermissionToken.cs
index e78c0f1a93..5c6a322c1c 100644
--- a/src/mscorlib/src/System/Security/PermissionToken.cs
+++ b/src/mscorlib/src/System/Security/PermissionToken.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.Security {
+namespace System.Security
+{
using System;
using System.Security.Util;
using System.Security.Permissions;
@@ -11,6 +12,7 @@ namespace System.Security {
using System.Threading;
using System.Globalization;
using System.Runtime.CompilerServices;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
[Flags]
@@ -34,7 +36,6 @@ namespace System.Security {
_info = CultureInfo.InvariantCulture.TextInfo;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public int Compare(Object a, Object b)
{
String strA = a as String;
@@ -64,7 +65,7 @@ namespace System.Security {
// The data structure consuming this will be responsible for dealing with null objects as keys.
public int GetHashCode(Object obj)
{
- if (obj == null) throw new ArgumentNullException("obj");
+ if (obj == null) throw new ArgumentNullException(nameof(obj));
Contract.EndContractBlock();
String str = obj as String;
@@ -90,20 +91,13 @@ namespace System.Security {
internal sealed class PermissionToken : ISecurityEncodable
{
private static readonly PermissionTokenFactory s_theTokenFactory;
-#if FEATURE_CAS_POLICY
- private static volatile ReflectionPermission s_reflectPerm = null;
-#endif // FEATURE_CAS_POLICY
-
private const string c_mscorlibName = System.CoreLib.Name;
internal int m_index;
internal volatile PermissionTokenType m_type;
-#if FEATURE_CAS_POLICY
- internal String m_strTypeName;
-#endif // FEATURE_CAS_POLICY
static internal TokenBasedSet s_tokenSet = new TokenBasedSet();
internal static bool IsMscorlibClassName (string className) {
- Contract.Assert( c_mscorlibName == ((RuntimeAssembly)Assembly.GetExecutingAssembly()).GetSimpleName(),
+ Debug.Assert( c_mscorlibName == ((RuntimeAssembly)Assembly.GetExecutingAssembly()).GetSimpleName(),
System.CoreLib.Name+" name mismatch" );
// If the class name does not look like a fully qualified name, we cannot simply determine if it's
@@ -119,11 +113,7 @@ namespace System.Security {
// Search for the string 'mscorlib' in the classname. If we find it, we will conservatively assume it's an mscorlib.dll type and load it.
for (int i = index; i < className.Length; i++) {
-#if FEATURE_CORECLR
- if (className[i] == 's' || className[i] == 'S')
-#else
- if (className[i] == 'm' || className[i] == 'M')
-#endif
+ if (className[i] == 's' || className[i] == 'S')
{
if (String.Compare(className, i, c_mscorlibName, 0, c_mscorlibName.Length, StringComparison.OrdinalIgnoreCase) == 0)
return true;
@@ -145,39 +135,14 @@ namespace System.Security {
{
m_index = index;
m_type = type;
-#if FEATURE_CAS_POLICY
- m_strTypeName = strTypeName;
-#endif // FEATURE_CAS_POLICY
}
- [System.Security.SecurityCritical] // auto-generated
public static PermissionToken GetToken(Type cls)
{
if (cls == null)
return null;
-
-#if FEATURE_CAS_POLICY
- if (cls.GetInterface( "System.Security.Permissions.IBuiltInPermission" ) != null)
- {
- if (s_reflectPerm == null)
- s_reflectPerm = new ReflectionPermission(PermissionState.Unrestricted);
- s_reflectPerm.Assert();
- MethodInfo method = cls.GetMethod( "GetTokenIndex", BindingFlags.Static | BindingFlags.NonPublic );
- Contract.Assert( method != null, "IBuiltInPermission types should have a static method called 'GetTokenIndex'" );
-
- // GetTokenIndex needs to be invoked without any security checks, since doing a security check
- // will involve a ReflectionTargetDemand which creates a CompressedStack and attempts to get the
- // token.
- RuntimeMethodInfo getTokenIndex = method as RuntimeMethodInfo;
- Contract.Assert(getTokenIndex != null, "method is not a RuntimeMethodInfo");
- int token = (int)getTokenIndex.UnsafeInvoke(null, BindingFlags.Default, null, null, null);
- return s_theTokenFactory.BuiltInGetToken(token, null, cls);
- }
- else
-#endif // FEATURE_CAS_POLICY
- {
- return s_theTokenFactory.GetToken(cls, null);
- }
+
+ return s_theTokenFactory.GetToken(cls, null);
}
public static PermissionToken GetToken(IPermission perm)
@@ -193,82 +158,6 @@ namespace System.Security {
return s_theTokenFactory.GetToken(perm.GetType(), perm);
}
-#if FEATURE_CAS_POLICY
- public static PermissionToken GetToken(String typeStr)
- {
- return GetToken( typeStr, false );
- }
-
-#if _DEBUG
- [System.Security.SecuritySafeCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- private static void GetTokenHelper(String typeStr)
- {
- new PermissionSet(PermissionState.Unrestricted).Assert();
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- Type type = RuntimeTypeHandle.GetTypeByName( typeStr.Trim().Replace( '\'', '\"' ), ref stackMark);
- Contract.Assert( (type == null) || (type.Module.Assembly != System.Reflection.Assembly.GetExecutingAssembly()) || (typeStr.IndexOf("mscorlib", StringComparison.Ordinal) < 0),
- "We should not go through this path for mscorlib based permissions" );
- }
-#endif
-
- public static PermissionToken GetToken(String typeStr, bool bCreateMscorlib)
- {
- if (typeStr == null)
- return null;
-
- if (IsMscorlibClassName( typeStr ))
- {
- if (!bCreateMscorlib)
- {
- return null;
- }
- else
- {
- return FindToken( Type.GetType( typeStr ) );
- }
- }
- else
- {
- PermissionToken token = s_theTokenFactory.GetToken(typeStr);
-#if _DEBUG
- GetTokenHelper(typeStr);
-#endif
- return token;
- }
- }
-
- [SecuritySafeCritical]
- public static PermissionToken FindToken( Type cls )
- {
- if (cls == null)
- return null;
-
-#if FEATURE_CAS_POLICY
- if (cls.GetInterface( "System.Security.Permissions.IBuiltInPermission" ) != null)
- {
- if (s_reflectPerm == null)
- s_reflectPerm = new ReflectionPermission(PermissionState.Unrestricted);
- s_reflectPerm.Assert();
- MethodInfo method = cls.GetMethod( "GetTokenIndex", BindingFlags.Static | BindingFlags.NonPublic );
- Contract.Assert( method != null, "IBuiltInPermission types should have a static method called 'GetTokenIndex'" );
-
- // GetTokenIndex needs to be invoked without any security checks, since doing a security check
- // will involve a ReflectionTargetDemand which creates a CompressedStack and attempts to get the
- // token.
- RuntimeMethodInfo getTokenIndex = method as RuntimeMethodInfo;
- Contract.Assert(getTokenIndex != null, "method is not a RuntimeMethodInfo");
- int token = (int)getTokenIndex.UnsafeInvoke(null, BindingFlags.Default, null, null, null);
- return s_theTokenFactory.BuiltInGetToken(token, null, cls);
- }
- else
-#endif // FEATURE_CAS_POLICY
- {
- return s_theTokenFactory.FindToken( cls );
- }
- }
-#endif // FEATURE_CAS_POLICY
-
public static PermissionToken FindTokenByIndex( int i )
{
return s_theTokenFactory.FindTokenByIndex( i );
@@ -289,41 +178,6 @@ namespace System.Security {
return true;
}
-
-#if FEATURE_CAS_POLICY
- public SecurityElement ToXml()
- {
- Contract.Assert( (m_type & PermissionTokenType.DontKnow) == 0, "Should have valid token type when ToXml is called" );
- SecurityElement elRoot = new SecurityElement( "PermissionToken" );
- if ((m_type & PermissionTokenType.BuiltIn) != 0)
- elRoot.AddAttribute( "Index", "" + this.m_index );
- else
- elRoot.AddAttribute( "Name", SecurityElement.Escape( m_strTypeName ) );
- elRoot.AddAttribute("Type", m_type.ToString("F"));
- return elRoot;
- }
-
- public void FromXml(SecurityElement elRoot)
- {
- // For the most part there is no parameter checking here since this is an
- // internal class and the serialization/deserialization path is controlled.
-
- if (!elRoot.Tag.Equals( "PermissionToken" ))
- Contract.Assert( false, "Tried to deserialize non-PermissionToken element here" );
-
- String strName = elRoot.Attribute( "Name" );
- PermissionToken realToken;
- if (strName != null)
- realToken = GetToken( strName, true );
- else
- realToken = FindTokenByIndex( Int32.Parse( elRoot.Attribute( "Index" ), CultureInfo.InvariantCulture ) );
-
- this.m_index = realToken.m_index;
- this.m_type = (PermissionTokenType) Enum.Parse(typeof(PermissionTokenType), elRoot.Attribute("Type"));
- Contract.Assert((this.m_type & PermissionTokenType.DontKnow) == 0, "Should have valid token type when FromXml is called.");
- this.m_strTypeName = realToken.m_strTypeName;
- }
-#endif // FEATURE_CAS_POLICY
}
// Package access only
@@ -357,33 +211,6 @@ namespace System.Security {
m_indexTable = new Hashtable(size);
}
-#if FEATURE_CAS_POLICY
- [SecuritySafeCritical]
- internal PermissionToken FindToken( Type cls )
- {
- IntPtr typePtr = cls.TypeHandle.Value;
- PermissionToken tok = (PermissionToken)m_handleTable[typePtr];
-
- if (tok != null)
- return tok;
-
- if (m_tokenTable == null)
- return null;
-
- tok = (PermissionToken)m_tokenTable[cls.AssemblyQualifiedName];
-
- if (tok != null)
- {
- lock (this)
- {
- m_handleTable.Add(typePtr, tok);
- }
- }
-
- return tok;
- }
-#endif // FEATURE_CAS_POLICY
-
internal PermissionToken FindTokenByIndex( int i )
{
PermissionToken token;
@@ -400,10 +227,9 @@ namespace System.Security {
return token;
}
- [SecuritySafeCritical]
internal PermissionToken GetToken(Type cls, IPermission perm)
{
- Contract.Assert( cls != null, "Must pass in valid type" );
+ Debug.Assert( cls != null, "Must pass in valid type" );
IntPtr typePtr = cls.TypeHandle.Value;
object tok = m_handleTable[typePtr];
@@ -459,22 +285,16 @@ namespace System.Security {
{
if (perm != null)
{
- Contract.Assert( !(perm is IBuiltInPermission), "This should not be called for built-ins" );
+ Debug.Assert( !(perm is IBuiltInPermission), "This should not be called for built-ins" );
((PermissionToken)tok).m_type = PermissionTokenType.IUnrestricted;
-#if FEATURE_CAS_POLICY
- ((PermissionToken)tok).m_strTypeName = perm.GetType().AssemblyQualifiedName;
-#endif // FEATURE_CAS_POLICY
}
else
{
- Contract.Assert( cls.GetInterface( "System.Security.Permissions.IBuiltInPermission" ) == null, "This shoudl not be called for built-ins" );
+ Debug.Assert( cls.GetInterface( "System.Security.Permissions.IBuiltInPermission" ) == null, "This shoudl not be called for built-ins" );
if (cls.GetInterface(s_unrestrictedPermissionInferfaceName) != null)
((PermissionToken)tok).m_type = PermissionTokenType.IUnrestricted;
else
((PermissionToken)tok).m_type = PermissionTokenType.Normal;
-#if FEATURE_CAS_POLICY
- ((PermissionToken)tok).m_strTypeName = cls.AssemblyQualifiedName;
-#endif // FEATURE_CAS_POLICY
}
}
diff --git a/src/mscorlib/src/System/Security/Permissions/EnvironmentPermission.cs b/src/mscorlib/src/System/Security/Permissions/EnvironmentPermission.cs
index 8208ed3fb0..567fe513c0 100644
--- a/src/mscorlib/src/System/Security/Permissions/EnvironmentPermission.cs
+++ b/src/mscorlib/src/System/Security/Permissions/EnvironmentPermission.cs
@@ -56,7 +56,6 @@ namespace System.Security.Permissions {
return str;
}
- [SecuritySafeCritical]
public override string ToString()
{
// SafeCritical: we're not storing path information in the strings, so exposing them out is fine ...
@@ -103,7 +102,6 @@ namespace System.Security.Permissions {
AddPathList( flag, pathList );
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void AddPathList( EnvironmentPermissionAccess flag, String pathList )
{
VerifyFlag( flag );
@@ -204,7 +202,6 @@ namespace System.Security.Permissions {
//
//------------------------------------------------------
- [System.Security.SecuritySafeCritical] // auto-generated
public override bool IsSubsetOf(IPermission target)
{
if (target == null)
@@ -232,7 +229,6 @@ namespace System.Security.Permissions {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override IPermission Intersect(IPermission target)
{
if (target == null)
@@ -275,7 +271,6 @@ namespace System.Security.Permissions {
return intersectPermission;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override IPermission Union(IPermission other)
{
if (other == null)
@@ -334,61 +329,8 @@ namespace System.Security.Permissions {
}
}
- return copy;
+ return copy;
}
-
-#if FEATURE_CAS_POLICY
- public override SecurityElement ToXml()
- {
- SecurityElement esd = CodeAccessPermission.CreatePermissionElement( this, "System.Security.Permissions.EnvironmentPermission" );
- if (!IsUnrestricted())
- {
- if (this.m_read != null && !this.m_read.IsEmpty())
- {
- esd.AddAttribute( "Read", SecurityElement.Escape( m_read.ToString() ) );
- }
- if (this.m_write != null && !this.m_write.IsEmpty())
- {
- esd.AddAttribute( "Write", SecurityElement.Escape( m_write.ToString() ) );
- }
- }
- else
- {
- esd.AddAttribute( "Unrestricted", "true" );
- }
- return esd;
- }
-
- public override void FromXml(SecurityElement esd)
- {
- CodeAccessPermission.ValidateElement( esd, this );
-
- String et;
-
- if (XMLUtil.IsUnrestricted(esd))
- {
- m_unrestricted = true;
- return;
- }
-
- m_unrestricted = false;
- m_read = null;
- m_write = null;
-
- et = esd.Attribute( "Read" );
- if (et != null)
- {
- m_read = new EnvironmentStringExpressionSet( et );
- }
-
- et = esd.Attribute( "Write" );
- if (et != null)
- {
- m_write = new EnvironmentStringExpressionSet( et );
- }
-
- }
-#endif // FEATURE_CAS_POLICY
/// <internalonly/>
int IBuiltInPermission.GetTokenIndex()
diff --git a/src/mscorlib/src/System/Security/Permissions/FileDialogPermission.cs b/src/mscorlib/src/System/Security/Permissions/FileDialogPermission.cs
index 6d6c221cc9..98a7d54c68 100644
--- a/src/mscorlib/src/System/Security/Permissions/FileDialogPermission.cs
+++ b/src/mscorlib/src/System/Security/Permissions/FileDialogPermission.cs
@@ -66,22 +66,6 @@ namespace System.Security.Permissions {
return new FileDialogPermission(this.access);
}
-#if FEATURE_CAS_POLICY
- public override void FromXml(SecurityElement esd) {
- CodeAccessPermission.ValidateElement(esd, this);
- if (XMLUtil.IsUnrestricted(esd)) {
- SetUnrestricted(true);
- return;
- }
-
- access = FileDialogPermissionAccess.None;
-
- string accessXml = esd.Attribute("Access");
- if (accessXml != null)
- access = (FileDialogPermissionAccess)Enum.Parse(typeof(FileDialogPermissionAccess), accessXml);
- }
-#endif // FEATURE_CAS_POLICY
-
/// <internalonly/>
int IBuiltInPermission.GetTokenIndex() {
return FileDialogPermission.GetTokenIndex();
@@ -152,21 +136,6 @@ namespace System.Security.Permissions {
}
}
-#if FEATURE_CAS_POLICY
- public override SecurityElement ToXml() {
- SecurityElement esd = CodeAccessPermission.CreatePermissionElement( this, "System.Security.Permissions.FileDialogPermission" );
- if (!IsUnrestricted()) {
- if (access != FileDialogPermissionAccess.None) {
- esd.AddAttribute("Access", Enum.GetName(typeof(FileDialogPermissionAccess), access));
- }
- }
- else {
- esd.AddAttribute("Unrestricted", "true");
- }
- return esd;
- }
-#endif // FEATURE_CAS_POLICY
-
public override IPermission Union(IPermission target) {
if (target == null) {
return this.Copy();
@@ -177,7 +146,7 @@ namespace System.Security.Permissions {
FileDialogPermission operand = (FileDialogPermission)target;
return new FileDialogPermission(access | operand.Access);
- }
+ }
static void VerifyAccess(FileDialogPermissionAccess access) {
if ((access & ~FileDialogPermissionAccess.OpenSave) != 0 ) {
diff --git a/src/mscorlib/src/System/Security/Permissions/FileIOPermission.cs b/src/mscorlib/src/System/Security/Permissions/FileIOPermission.cs
index b4d4141f82..34b9f1ef80 100644
--- a/src/mscorlib/src/System/Security/Permissions/FileIOPermission.cs
+++ b/src/mscorlib/src/System/Security/Permissions/FileIOPermission.cs
@@ -2,13 +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.Security.Permissions {
+namespace System.Security.Permissions
+{
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-#if FEATURE_CAS_POLICY
- using SecurityElement = System.Security.SecurityElement;
-#endif // FEATURE_CAS_POLICY
using System.Security.AccessControl;
using System.Security.Util;
using System.IO;
@@ -16,11 +14,12 @@ namespace System.Security.Permissions {
using System.Globalization;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
-[Serializable]
+ [Serializable]
[Flags]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public enum FileIOPermissionAccess
{
NoAccess = 0x00,
@@ -30,9 +29,8 @@ namespace System.Security.Permissions {
PathDiscovery = 0x08,
AllAccess = 0x0F,
}
-
-
-[System.Runtime.InteropServices.ComVisible(true)]
+
+ [System.Runtime.InteropServices.ComVisible(true)]
[Serializable]
sealed public class FileIOPermission : CodeAccessPermission, IUnrestrictedPermission, IBuiltInPermission
{
@@ -62,7 +60,6 @@ namespace System.Security.Permissions {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public FileIOPermission( FileIOPermissionAccess access, String path )
{
VerifyAccess( access );
@@ -71,7 +68,6 @@ namespace System.Security.Permissions {
AddPathList( access, pathList, false, true, false );
}
- [System.Security.SecuritySafeCritical] // auto-generated
public FileIOPermission( FileIOPermissionAccess access, String[] pathList )
{
VerifyAccess( access );
@@ -79,24 +75,6 @@ namespace System.Security.Permissions {
AddPathList( access, pathList, false, true, false );
}
-#if FEATURE_MACL
- [System.Security.SecuritySafeCritical] // auto-generated
- public FileIOPermission( FileIOPermissionAccess access, AccessControlActions control, String path )
- {
- VerifyAccess( access );
-
- String[] pathList = new String[] { path };
- AddPathList( access, control, pathList, false, true, false );
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public FileIOPermission( FileIOPermissionAccess access, AccessControlActions control, String[] pathList )
- : this( access, control, pathList, true, true )
- {
- }
-#endif
-
- [System.Security.SecurityCritical] // auto-generated
internal FileIOPermission( FileIOPermissionAccess access, String[] pathList, bool checkForDuplicates, bool needFullPath )
{
VerifyAccess( access );
@@ -104,16 +82,6 @@ namespace System.Security.Permissions {
AddPathList( access, pathList, checkForDuplicates, needFullPath, true );
}
-#if FEATURE_MACL
- [System.Security.SecurityCritical] // auto-generated
- internal FileIOPermission( FileIOPermissionAccess access, AccessControlActions control, String[] pathList, bool checkForDuplicates, bool needFullPath )
- {
- VerifyAccess( access );
-
- AddPathList( access, control, pathList, checkForDuplicates, needFullPath, true );
- }
-#endif
-
public void SetPathList( FileIOPermissionAccess access, String path )
{
String[] pathList;
@@ -135,7 +103,6 @@ namespace System.Security.Permissions {
SetPathList( access, AccessControlActions.None, pathList, checkForDuplicates );
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal void SetPathList( FileIOPermissionAccess access, AccessControlActions control, String[] pathList, bool checkForDuplicates )
{
VerifyAccess( access );
@@ -152,26 +119,13 @@ namespace System.Security.Permissions {
if ((access & FileIOPermissionAccess.PathDiscovery) != 0)
m_pathDiscovery = null;
-#if FEATURE_MACL
- if ((control & AccessControlActions.View) != 0)
- m_viewAcl = null;
-
- if ((control & AccessControlActions.Change) != 0)
- m_changeAcl = null;
-#else
m_viewAcl = null;
m_changeAcl = null;
-#endif
-
m_unrestricted = false;
-#if FEATURE_MACL
- AddPathList( access, control, pathList, checkForDuplicates, true, true );
-#else
+
AddPathList( access, pathList, checkForDuplicates, true, true );
-#endif
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void AddPathList( FileIOPermissionAccess access, String path )
{
String[] pathList;
@@ -182,19 +136,16 @@ namespace System.Security.Permissions {
AddPathList( access, pathList, false, true, false );
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void AddPathList( FileIOPermissionAccess access, String[] pathList )
{
AddPathList( access, pathList, true, true, true );
}
- [System.Security.SecurityCritical] // auto-generated
internal void AddPathList( FileIOPermissionAccess access, String[] pathListOrig, bool checkForDuplicates, bool needFullPath, bool copyPathList )
{
AddPathList( access, AccessControlActions.None, pathListOrig, checkForDuplicates, needFullPath, copyPathList );
}
- [System.Security.SecurityCritical] // auto-generated
internal void AddPathList(FileIOPermissionAccess access, AccessControlActions control, String[] pathListOrig, bool checkForDuplicates, bool needFullPath, bool copyPathList)
{
if (pathListOrig == null)
@@ -267,29 +218,8 @@ namespace System.Security.Permissions {
}
m_pathDiscovery.AddExpressions( pathArrayList, checkForDuplicates);
}
-
-#if FEATURE_MACL
- if ((control & AccessControlActions.View) != 0)
- {
- if (m_viewAcl == null)
- {
- m_viewAcl = new FileIOAccess();
- }
- m_viewAcl.AddExpressions( pathArrayList, checkForDuplicates);
- }
-
- if ((control & AccessControlActions.Change) != 0)
- {
- if (m_changeAcl == null)
- {
- m_changeAcl = new FileIOAccess();
- }
- m_changeAcl.AddExpressions( pathArrayList, checkForDuplicates);
- }
-#endif
}
-
- [SecuritySafeCritical]
+
public String[] GetPathList( FileIOPermissionAccess access )
{
VerifyAccess( access );
@@ -335,7 +265,6 @@ namespace System.Security.Permissions {
return null;
}
-
public FileIOPermissionAccess AllLocalFiles
{
@@ -558,7 +487,7 @@ namespace System.Security.Permissions {
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidPathChars"));
if (!onlyCheckExtras)
- Path.CheckInvalidPathChars(str[i]);
+ PathInternal.CheckInvalidPathChars(str[i]);
}
#else
// There are no "extras" on Unix
@@ -567,7 +496,7 @@ namespace System.Security.Permissions {
for (int i = 0; i < str.Length; ++i)
{
- Path.CheckInvalidPathChars(str[i]);
+ PathInternal.CheckInvalidPathChars(str[i]);
}
#endif
}
@@ -785,123 +714,6 @@ namespace System.Security.Permissions {
}
return copy;
}
-
-#if FEATURE_CAS_POLICY
- public override SecurityElement ToXml()
- {
- SecurityElement esd = CodeAccessPermission.CreatePermissionElement( this, "System.Security.Permissions.FileIOPermission" );
- if (!IsUnrestricted())
- {
- if (this.m_read != null && !this.m_read.IsEmpty())
- {
- esd.AddAttribute( "Read", SecurityElement.Escape( m_read.ToString() ) );
- }
- if (this.m_write != null && !this.m_write.IsEmpty())
- {
- esd.AddAttribute( "Write", SecurityElement.Escape( m_write.ToString() ) );
- }
- if (this.m_append != null && !this.m_append.IsEmpty())
- {
- esd.AddAttribute( "Append", SecurityElement.Escape( m_append.ToString() ) );
- }
- if (this.m_pathDiscovery != null && !this.m_pathDiscovery.IsEmpty())
- {
- esd.AddAttribute( "PathDiscovery", SecurityElement.Escape( m_pathDiscovery.ToString() ) );
- }
- if (this.m_viewAcl != null && !this.m_viewAcl.IsEmpty())
- {
- esd.AddAttribute( "ViewAcl", SecurityElement.Escape( m_viewAcl.ToString() ) );
- }
- if (this.m_changeAcl != null && !this.m_changeAcl.IsEmpty())
- {
- esd.AddAttribute( "ChangeAcl", SecurityElement.Escape( m_changeAcl.ToString() ) );
- }
-
- }
- else
- {
- esd.AddAttribute( "Unrestricted", "true" );
- }
- return esd;
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public override void FromXml(SecurityElement esd)
- {
- CodeAccessPermission.ValidateElement( esd, this );
- String et;
-
- if (XMLUtil.IsUnrestricted(esd))
- {
- m_unrestricted = true;
- return;
- }
-
-
- m_unrestricted = false;
-
- et = esd.Attribute( "Read" );
- if (et != null)
- {
- m_read = new FileIOAccess( et );
- }
- else
- {
- m_read = null;
- }
-
- et = esd.Attribute( "Write" );
- if (et != null)
- {
- m_write = new FileIOAccess( et );
- }
- else
- {
- m_write = null;
- }
-
- et = esd.Attribute( "Append" );
- if (et != null)
- {
- m_append = new FileIOAccess( et );
- }
- else
- {
- m_append = null;
- }
-
- et = esd.Attribute( "PathDiscovery" );
- if (et != null)
- {
- m_pathDiscovery = new FileIOAccess( et );
- m_pathDiscovery.PathDiscovery = true;
- }
- else
- {
- m_pathDiscovery = null;
- }
-
- et = esd.Attribute( "ViewAcl" );
- if (et != null)
- {
- m_viewAcl = new FileIOAccess( et );
- }
- else
- {
- m_viewAcl = null;
- }
-
- et = esd.Attribute( "ChangeAcl" );
- if (et != null)
- {
- m_changeAcl = new FileIOAccess( et );
- }
- else
- {
- m_changeAcl = null;
- }
- }
-#endif // FEATURE_CAS_POLICY
/// <internalonly/>
int IBuiltInPermission.GetTokenIndex()
@@ -993,19 +805,9 @@ namespace System.Security.Permissions {
///
/// IMPORTANT: This method should only be used after calling GetFullPath on the path to verify
/// </summary>
- [System.Security.SecuritySafeCritical]
internal static void QuickDemand(FileIOPermissionAccess access, string fullPath, bool checkForDuplicates = false, bool needFullPath = false)
{
-#if FEATURE_CAS_POLICY
- if (!CodeAccessSecurityEngine.QuickCheckForAllDemands())
- {
- new FileIOPermission(access, new string[] { fullPath }, checkForDuplicates, needFullPath).Demand();
- }
- else
-#endif
- {
- EmulateFileIOPermissionChecks(fullPath);
- }
+ EmulateFileIOPermissionChecks(fullPath);
}
/// <summary>
@@ -1018,67 +820,19 @@ namespace System.Security.Permissions {
/// IMPORTANT: This method should only be used after calling GetFullPath on the path to verify
///
/// </summary>
- [System.Security.SecuritySafeCritical]
internal static void QuickDemand(FileIOPermissionAccess access, string[] fullPathList, bool checkForDuplicates = false, bool needFullPath = true)
{
-#if FEATURE_CAS_POLICY
- if (!CodeAccessSecurityEngine.QuickCheckForAllDemands())
- {
- new FileIOPermission(access, fullPathList, checkForDuplicates, needFullPath).Demand();
- }
- else
-#endif
+ foreach (string fullPath in fullPathList)
{
- foreach (string fullPath in fullPathList)
- {
- EmulateFileIOPermissionChecks(fullPath);
- }
+ EmulateFileIOPermissionChecks(fullPath);
}
}
- [System.Security.SecuritySafeCritical]
internal static void QuickDemand(PermissionState state)
{
// Should be a no-op without CAS
-#if FEATURE_CAS_POLICY
- if (!CodeAccessSecurityEngine.QuickCheckForAllDemands())
- {
- new FileIOPermission(state).Demand();
- }
-#endif
- }
-
-#if FEATURE_MACL
- [System.Security.SecuritySafeCritical]
- internal static void QuickDemand(FileIOPermissionAccess access, AccessControlActions control, string fullPath, bool checkForDuplicates = false, bool needFullPath = true)
- {
- if (!CodeAccessSecurityEngine.QuickCheckForAllDemands())
- {
- new FileIOPermission(access, control, new string[] { fullPath }, checkForDuplicates, needFullPath).Demand();
- }
- else
- {
- EmulateFileIOPermissionChecks(fullPath);
- }
}
- [System.Security.SecuritySafeCritical]
- internal static void QuickDemand(FileIOPermissionAccess access, AccessControlActions control, string[] fullPathList, bool checkForDuplicates = true, bool needFullPath = true)
- {
- if (!CodeAccessSecurityEngine.QuickCheckForAllDemands())
- {
- new FileIOPermission(access, control, fullPathList, checkForDuplicates, needFullPath).Demand();
- }
- else
- {
- foreach (string fullPath in fullPathList)
- {
- EmulateFileIOPermissionChecks(fullPath);
- }
- }
- }
-#endif
-
/// <summary>
/// Perform the additional path checks that would normally happen when creating a FileIOPermission object.
/// </summary>
@@ -1088,18 +842,10 @@ namespace System.Security.Permissions {
// Callers should have already made checks for invalid path format via normalization. This method will only make the
// additional checks needed to throw the same exceptions that would normally throw when using FileIOPermission.
// These checks are done via CheckIllegalCharacters() and StringExpressionSet in AddPathList() above.
- //
- // We have to check the beginning as some paths may be passed in as path + @"\.", which will be normalized away.
- BCLDebug.Assert(
- fullPath.StartsWith(Path.NormalizePath(fullPath, fullCheck: false), StringComparison.OrdinalIgnoreCase),
- string.Format("path isn't normalized: {0}", fullPath));
+#if !PLATFORM_UNIX
// Checking for colon / invalid characters on device paths blocks legitimate access to objects such as named pipes.
- if (
-#if FEATURE_PATHCOMPAT
- AppContextSwitches.UseLegacyPathHandling ||
-#endif
- !PathInternal.IsDevice(fullPath))
+ if (!PathInternal.IsDevice(fullPath))
{
// GetFullPath already checks normal invalid path characters. We need to just check additional (wildcard) characters here.
// (By calling the standard helper we can allow extended paths \\?\ through when the support is enabled.)
@@ -1113,6 +859,7 @@ namespace System.Security.Permissions {
throw new NotSupportedException(Environment.GetResourceString("Argument_PathFormatNotSupported"));
}
}
+#endif // !PLATFORM_UNIX
}
}
@@ -1149,7 +896,6 @@ namespace System.Security.Permissions {
m_pathDiscovery = pathDiscovery;
}
- [System.Security.SecurityCritical] // auto-generated
public FileIOAccess( String value )
{
if (value == null)
@@ -1204,7 +950,6 @@ namespace System.Security.Permissions {
m_pathDiscovery = operand.m_pathDiscovery;
}
- [System.Security.SecurityCritical] // auto-generated
public void AddExpressions(ArrayList values, bool checkForDuplicates)
{
m_allFiles = false;
@@ -1255,7 +1000,6 @@ namespace System.Security.Permissions {
return new FileIOAccess( this );
}
- [System.Security.SecuritySafeCritical] // auto-generated
public FileIOAccess Union( FileIOAccess operand )
{
if (operand == null)
@@ -1263,7 +1007,7 @@ namespace System.Security.Permissions {
return this.IsEmpty() ? null : this.Copy();
}
- Contract.Assert( this.m_pathDiscovery == operand.m_pathDiscovery, "Path discovery settings must match" );
+ Debug.Assert( this.m_pathDiscovery == operand.m_pathDiscovery, "Path discovery settings must match" );
if (this.m_allFiles || operand.m_allFiles)
{
@@ -1273,7 +1017,6 @@ namespace System.Security.Permissions {
return new FileIOAccess( this.m_set.Union( operand.m_set ), false, this.m_allLocalFiles || operand.m_allLocalFiles, this.m_pathDiscovery );
}
- [System.Security.SecuritySafeCritical] // auto-generated
public FileIOAccess Intersect( FileIOAccess operand )
{
if (operand == null)
@@ -1281,7 +1024,7 @@ namespace System.Security.Permissions {
return null;
}
- Contract.Assert( this.m_pathDiscovery == operand.m_pathDiscovery, "Path discovery settings must match" );
+ Debug.Assert( this.m_pathDiscovery == operand.m_pathDiscovery, "Path discovery settings must match" );
if (this.m_allFiles)
{
@@ -1343,7 +1086,6 @@ namespace System.Security.Permissions {
return new FileIOAccess( intersectionSet, false, this.m_allLocalFiles && operand.m_allLocalFiles, this.m_pathDiscovery );
}
- [System.Security.SecuritySafeCritical] // auto-generated
public bool IsSubsetOf( FileIOAccess operand )
{
if (operand == null)
@@ -1356,7 +1098,7 @@ namespace System.Security.Permissions {
return true;
}
- Contract.Assert( this.m_pathDiscovery == operand.m_pathDiscovery, "Path discovery settings must match" );
+ Debug.Assert( this.m_pathDiscovery == operand.m_pathDiscovery, "Path discovery settings must match" );
if (!((m_pathDiscovery && this.m_set.IsSubsetOfPathDiscovery( operand.m_set )) || this.m_set.IsSubsetOf( operand.m_set )))
{
@@ -1400,7 +1142,6 @@ namespace System.Security.Permissions {
}
}
- [SecuritySafeCritical]
public override String ToString()
{
// SafeCritical: all string expression sets are constructed with the throwOnRelative bit set, so
@@ -1429,7 +1170,6 @@ namespace System.Security.Permissions {
}
}
- [SecuritySafeCritical]
public String[] ToStringArray()
{
// SafeCritical: all string expression sets are constructed with the throwOnRelative bit set, so
@@ -1437,18 +1177,16 @@ namespace System.Security.Permissions {
return m_set.UnsafeToStringArray();
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal static extern bool IsLocalDrive(String path);
- [System.Security.SecuritySafeCritical] // auto-generated
public override bool Equals(Object obj)
{
FileIOAccess operand = obj as FileIOAccess;
if(operand == null)
return (IsEmpty() && obj == null);
- Contract.Assert( this.m_pathDiscovery == operand.m_pathDiscovery, "Path discovery settings must match" );
+ Debug.Assert( this.m_pathDiscovery == operand.m_pathDiscovery, "Path discovery settings must match" );
if(m_pathDiscovery)
{
if(this.m_allFiles && operand.m_allFiles)
diff --git a/src/mscorlib/src/System/Security/Permissions/GACIdentityPermission.cs b/src/mscorlib/src/System/Security/Permissions/GACIdentityPermission.cs
index 5c209afb9d..f93f26daa9 100644
--- a/src/mscorlib/src/System/Security/Permissions/GACIdentityPermission.cs
+++ b/src/mscorlib/src/System/Security/Permissions/GACIdentityPermission.cs
@@ -5,9 +5,6 @@
namespace System.Security.Permissions
{
using System;
-#if FEATURE_CAS_POLICY
- using SecurityElement = System.Security.SecurityElement;
-#endif // FEATURE_CAS_POLICY
using System.Globalization;
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly, AllowMultiple = true, Inherited = false )]
@@ -92,19 +89,6 @@ namespace System.Security.Permissions
return this.Copy();
}
-#if FEATURE_CAS_POLICY
- public override SecurityElement ToXml()
- {
- SecurityElement securityElement = CodeAccessPermission.CreatePermissionElement( this, "System.Security.Permissions.GacIdentityPermission" );
- return securityElement;
- }
-
- public override void FromXml(SecurityElement securityElement)
- {
- CodeAccessPermission.ValidateElement(securityElement, this);
- }
-#endif // FEATURE_CAS_POLICY
-
/// <internalonly/>
int IBuiltInPermission.GetTokenIndex()
{
diff --git a/src/mscorlib/src/System/Security/Permissions/HostProtectionPermission.cs b/src/mscorlib/src/System/Security/Permissions/HostProtectionPermission.cs
index 85be61a00d..c4facbb67e 100644
--- a/src/mscorlib/src/System/Security/Permissions/HostProtectionPermission.cs
+++ b/src/mscorlib/src/System/Security/Permissions/HostProtectionPermission.cs
@@ -41,11 +41,9 @@ namespace System.Security.Permissions
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly | AttributeTargets.Delegate, AllowMultiple = true, Inherited = false )]
[System.Runtime.InteropServices.ComVisible(true)]
[Serializable]
-#if FEATURE_CORECLR
// This needs to be in the asmmeta to enable SecAnnotate to successfully resolve and run the security rules. It gets marked
// as internal by BCLRewriter so we are simply marking it as FriendAccessAllowed so it stays in the asmmeta.
[System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
-#endif // FEATURE_CORECLR
#pragma warning disable 618
sealed public class HostProtectionAttribute : CodeAccessSecurityAttribute
#pragma warning restore 618
@@ -247,38 +245,6 @@ namespace System.Security.Permissions
return new HostProtectionPermission(m_resources);
}
-#if FEATURE_CAS_POLICY
- //------------------------------------------------------
- //
- // XML
- //
- //------------------------------------------------------
- public override SecurityElement ToXml()
- {
- SecurityElement esd = CodeAccessPermission.CreatePermissionElement( this, this.GetType().FullName );
- if(IsUnrestricted())
- esd.AddAttribute( "Unrestricted", "true" );
- else
- esd.AddAttribute( "Resources", XMLUtil.BitFieldEnumToString( typeof( HostProtectionResource ), Resources ) );
- return esd;
- }
-
- public override void FromXml(SecurityElement esd)
- {
- CodeAccessPermission.ValidateElement( esd, this );
- if (XMLUtil.IsUnrestricted( esd ))
- Resources = HostProtectionResource.All;
- else
- {
- String resources = esd.Attribute( "Resources" );
- if (resources == null)
- Resources = HostProtectionResource.None;
- else
- Resources = (HostProtectionResource)Enum.Parse( typeof( HostProtectionResource ), resources );
- }
- }
-#endif // FEATURE_CAS_POLICY
-
//------------------------------------------------------
//
// OBJECT OVERRIDES
diff --git a/src/mscorlib/src/System/Security/Permissions/IsolatedStorageFilePermission.cs b/src/mscorlib/src/System/Security/Permissions/IsolatedStorageFilePermission.cs
index 1e11b4aa7f..42bc648c72 100644
--- a/src/mscorlib/src/System/Security/Permissions/IsolatedStorageFilePermission.cs
+++ b/src/mscorlib/src/System/Security/Permissions/IsolatedStorageFilePermission.cs
@@ -158,19 +158,6 @@ namespace System.Security.Permissions {
{
return BuiltInPermissionIndex.IsolatedStorageFilePermissionIndex;
}
-
- //------------------------------------------------------
- //
- // IsolatedStoragePermission OVERRIDES
- //
- //------------------------------------------------------
-#if FEATURE_CAS_POLICY
- [System.Runtime.InteropServices.ComVisible(false)]
- public override SecurityElement ToXml()
- {
- return base.ToXml( "System.Security.Permissions.IsolatedStorageFilePermission" );
- }
-#endif // FEATURE_CAS_POLICY
}
}
diff --git a/src/mscorlib/src/System/Security/Permissions/IsolatedStoragePermission.cs b/src/mscorlib/src/System/Security/Permissions/IsolatedStoragePermission.cs
index 308adbdab3..9f09a37098 100644
--- a/src/mscorlib/src/System/Security/Permissions/IsolatedStoragePermission.cs
+++ b/src/mscorlib/src/System/Security/Permissions/IsolatedStoragePermission.cs
@@ -32,9 +32,6 @@ namespace System.Security.Permissions {
[Serializable]
-#if !FEATURE_CORECLR
- [SecurityPermissionAttribute( SecurityAction.InheritanceDemand, ControlEvidence = true, ControlPolicy = true )]
-#endif
[System.Runtime.InteropServices.ComVisible(true)]
abstract public class IsolatedStoragePermission
: CodeAccessPermission, IUnrestrictedPermission
@@ -182,93 +179,5 @@ namespace System.Security.Permissions {
//------------------------------------------------------
internal static long min(long x,long y) {return x>y?y:x;}
internal static long max(long x,long y) {return x<y?y:x;}
-
-#if FEATURE_CAS_POLICY
- //------------------------------------------------------
- //
- // PUBLIC ENCODING METHODS
- //
- //------------------------------------------------------
-
- private const String _strUserQuota = "UserQuota";
- private const String _strMachineQuota = "MachineQuota";
- private const String _strExpiry = "Expiry";
- private const String _strPermDat = "Permanent";
-
- public override SecurityElement ToXml()
- {
- return ToXml ( this.GetType().FullName );
- }
-
- internal SecurityElement ToXml(String permName)
- {
- SecurityElement esd = CodeAccessPermission.CreatePermissionElement( this, permName );
- if (!IsUnrestricted())
- {
- esd.AddAttribute( "Allowed", Enum.GetName( typeof( IsolatedStorageContainment ), m_allowed ) );
- if (m_userQuota>0)
- {
- esd.AddAttribute(_strUserQuota, (m_userQuota).ToString(CultureInfo.InvariantCulture)) ;
- }
- if (m_machineQuota>0)
- {
- esd.AddAttribute(_strMachineQuota, (m_machineQuota).ToString(CultureInfo.InvariantCulture)) ;
- }
- if (m_expirationDays>0)
- {
- esd.AddAttribute( _strExpiry, (m_expirationDays).ToString(CultureInfo.InvariantCulture)) ;
- }
- if (m_permanentData)
- {
- esd.AddAttribute(_strPermDat, (m_permanentData).ToString()) ;
- }
- }
- else
- {
- esd.AddAttribute( "Unrestricted", "true" );
- }
- return esd;
- }
-
-
- public override void FromXml(SecurityElement esd)
- {
- CodeAccessPermission.ValidateElement( esd, this );
-
- m_allowed = IsolatedStorageContainment.None; // default if no match
-
- if (XMLUtil.IsUnrestricted(esd))
- {
- m_allowed = IsolatedStorageContainment.UnrestrictedIsolatedStorage;
- }
- else
- {
- String allowed = esd.Attribute( "Allowed" );
-
- if (allowed != null)
- m_allowed = (IsolatedStorageContainment)Enum.Parse( typeof( IsolatedStorageContainment ), allowed );
- }
-
- if (m_allowed == IsolatedStorageContainment.UnrestrictedIsolatedStorage)
- {
- m_userQuota = Int64.MaxValue;
- m_machineQuota = Int64.MaxValue;
- m_expirationDays = Int64.MaxValue ;
- m_permanentData = true;
- }
- else
- {
- String param;
- param = esd.Attribute (_strUserQuota) ;
- m_userQuota = param != null ? Int64.Parse(param, CultureInfo.InvariantCulture) : 0 ;
- param = esd.Attribute (_strMachineQuota) ;
- m_machineQuota = param != null ? Int64.Parse(param, CultureInfo.InvariantCulture) : 0 ;
- param = esd.Attribute (_strExpiry) ;
- m_expirationDays = param != null ? Int64.Parse(param, CultureInfo.InvariantCulture) : 0 ;
- param = esd.Attribute (_strPermDat) ;
- m_permanentData = param != null ? (Boolean.Parse(param)) : false ;
- }
- }
-#endif // FEATURE_CAS_POLICY
}
}
diff --git a/src/mscorlib/src/System/Security/Permissions/PermissionAttributes.cs b/src/mscorlib/src/System/Security/Permissions/PermissionAttributes.cs
index f14fb0d1b3..b6ac8ece3c 100644
--- a/src/mscorlib/src/System/Security/Permissions/PermissionAttributes.cs
+++ b/src/mscorlib/src/System/Security/Permissions/PermissionAttributes.cs
@@ -8,9 +8,6 @@ namespace System.Security.Permissions
using System.Security.Util;
using System.IO;
using System.Security.Policy;
-#if FEATURE_MACL
- using System.Security.AccessControl;
-#endif
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
@@ -23,11 +20,9 @@ namespace System.Security.Permissions
using System.Diagnostics.Contracts;
[Serializable]
-[System.Runtime.InteropServices.ComVisible(true)]
-#if !FEATURE_CAS_POLICY
+ [System.Runtime.InteropServices.ComVisible(true)]
// The csharp compiler requires these types to be public, but they are not used elsewhere.
[Obsolete("SecurityAction is no longer accessible to application code.")]
-#endif
public enum SecurityAction
{
// Demand permission of all caller
@@ -62,14 +57,11 @@ namespace System.Security.Permissions
RequestRefuse = 10,
}
-
-[Serializable]
-[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly, AllowMultiple = true, Inherited = false )]
-[System.Runtime.InteropServices.ComVisible(true)]
-#if !FEATURE_CAS_POLICY
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly, AllowMultiple = true, Inherited = false )]
+ [System.Runtime.InteropServices.ComVisible(true)]
// The csharp compiler requires these types to be public, but they are not used elsewhere.
[Obsolete("SecurityAttribute is no longer accessible to application code.")]
-#endif
public abstract class SecurityAttribute : System.Attribute
{
/// <internalonly/>
@@ -96,7 +88,6 @@ namespace System.Security.Permissions
abstract public IPermission CreatePermission();
- [System.Security.SecurityCritical] // auto-generated
internal static unsafe IntPtr FindSecurityAttributeTypeHandle(String typeName)
{
PermissionSet.s_fullTrust.Assert();
@@ -108,13 +99,11 @@ namespace System.Security.Permissions
}
}
-[Serializable]
-[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly, AllowMultiple = true, Inherited = false )]
-[System.Runtime.InteropServices.ComVisible(true)]
-#if !FEATURE_CAS_POLICY
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly, AllowMultiple = true, Inherited = false )]
+ [System.Runtime.InteropServices.ComVisible(true)]
// The csharp compiler requires these types to be public, but they are not used elsewhere.
[Obsolete("CodeAccessSecurityAttribute is no longer accessible to application code.")]
-#endif
public abstract class CodeAccessSecurityAttribute : SecurityAttribute
{
protected CodeAccessSecurityAttribute( SecurityAction action )
@@ -307,12 +296,6 @@ namespace System.Security.Permissions
perm.SetPathList( FileIOPermissionAccess.Append, m_append );
if (m_pathDiscovery != null)
perm.SetPathList( FileIOPermissionAccess.PathDiscovery, m_pathDiscovery );
-#if FEATURE_MACL
- if (m_viewAccess != null)
- perm.SetPathList( FileIOPermissionAccess.NoAccess, AccessControlActions.View, new String[] { m_viewAccess }, false );
- if (m_changeAccess != null)
- perm.SetPathList( FileIOPermissionAccess.NoAccess, AccessControlActions.Change, new String[] { m_changeAccess }, false );
-#endif
perm.AllFiles = m_allFiles;
perm.AllLocalFiles = m_allLocalFiles;
@@ -384,59 +367,6 @@ namespace System.Security.Permissions
}
}
-#if !FEATURE_CORECLR
- // PrincipalPermissionAttribute currently derives from
- // CodeAccessSecurityAttribute, even though it's not related to code access
- // security. This is because compilers are currently looking for
- // CodeAccessSecurityAttribute as a direct parent class rather than
- // SecurityAttribute as the root class.
- [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true, Inherited = false )]
-[System.Runtime.InteropServices.ComVisible(true)]
- [Serializable]
- sealed public class PrincipalPermissionAttribute : CodeAccessSecurityAttribute
- {
- private String m_name = null;
- private String m_role = null;
- private bool m_authenticated = true;
-
- public PrincipalPermissionAttribute( SecurityAction action )
- : base( action )
- {
- }
-
- public String Name
- {
- get { return m_name; }
- set { m_name = value; }
- }
-
- public String Role
- {
- get { return m_role; }
- set { m_role = value; }
- }
-
- public bool Authenticated
- {
- get { return m_authenticated; }
- set { m_authenticated = value; }
- }
-
-
- public override IPermission CreatePermission()
- {
- if (m_unrestricted)
- {
- return new PrincipalPermission( PermissionState.Unrestricted );
- }
- else
- {
- return new PrincipalPermission( m_name, m_role, m_authenticated );
- }
- }
- }
-#endif // !FEATURE_CORECLR
-
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly, AllowMultiple = true, Inherited = false )]
[System.Runtime.InteropServices.ComVisible(true)]
[Serializable]
@@ -570,24 +500,16 @@ namespace System.Security.Permissions
perm.SetPathList( RegistryPermissionAccess.Write, m_write );
if (m_create != null)
perm.SetPathList( RegistryPermissionAccess.Create, m_create );
-#if FEATURE_MACL
- if (m_viewAcl != null)
- perm.SetPathList( AccessControlActions.View, m_viewAcl );
- if (m_changeAcl != null)
- perm.SetPathList( AccessControlActions.Change, m_changeAcl );
-#endif
return perm;
}
}
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly, AllowMultiple = true, Inherited = false )]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
[Serializable]
-#if !FEATURE_CAS_POLICY
// The csharp compiler requires these types to be public, but they are not used elsewhere.
[Obsolete("SecurityPermissionAttribute is no longer accessible to application code.")]
-#endif
sealed public class SecurityPermissionAttribute : CodeAccessSecurityAttribute
{
private SecurityPermissionFlag m_flag = SecurityPermissionFlag.NoFlags;
@@ -662,7 +584,7 @@ namespace System.Security.Permissions
set { m_flag = value ? m_flag | SecurityPermissionFlag.RemotingConfiguration : m_flag & ~SecurityPermissionFlag.RemotingConfiguration; }
}
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public bool Infrastructure {
get { return (m_flag & SecurityPermissionFlag.Infrastructure) != 0; }
set { m_flag = value ? m_flag | SecurityPermissionFlag.Infrastructure : m_flag & ~SecurityPermissionFlag.Infrastructure; }
@@ -893,170 +815,6 @@ namespace System.Security.Permissions
}
}
}
-
-#if FEATURE_X509 && FEATURE_CAS_POLICY
- [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly, AllowMultiple = true, Inherited = false )]
-[System.Runtime.InteropServices.ComVisible(true)]
- [Serializable]
- sealed public class PublisherIdentityPermissionAttribute : CodeAccessSecurityAttribute
- {
- private String m_x509cert = null;
- private String m_certFile = null;
- private String m_signedFile = null;
-
- public PublisherIdentityPermissionAttribute( SecurityAction action )
- : base( action )
- {
- m_x509cert = null;
- m_certFile = null;
- m_signedFile = null;
- }
-
- public String X509Certificate {
- get { return m_x509cert; }
- set { m_x509cert = value; }
- }
-
- public String CertFile {
- get { return m_certFile; }
- set { m_certFile = value; }
- }
-
- public String SignedFile {
- get { return m_signedFile; }
- set { m_signedFile = value; }
- }
-
- public override IPermission CreatePermission()
- {
- if (m_unrestricted)
- {
- return new PublisherIdentityPermission( PermissionState.Unrestricted );
- }
- else
- {
- if (m_x509cert != null)
- {
- return new PublisherIdentityPermission( new X509Certificate( System.Security.Util.Hex.DecodeHexString( m_x509cert ) ) );
- }
- else if (m_certFile != null)
- {
- return new PublisherIdentityPermission( System.Security.Cryptography.X509Certificates.X509Certificate.CreateFromCertFile( m_certFile ) );
- }
- else if (m_signedFile != null)
- {
- return new PublisherIdentityPermission( System.Security.Cryptography.X509Certificates.X509Certificate.CreateFromSignedFile( m_signedFile ) );
- }
- else
- {
- return new PublisherIdentityPermission( PermissionState.None );
- }
- }
- }
- }
-#endif // #if FEATURE_X509 && FEATURE_CAS_POLICY
-
-#if !FEATURE_CORECLR
-[Serializable]
-[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor
- | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly,
- AllowMultiple=true, Inherited=false)]
-[System.Runtime.InteropServices.ComVisible(true)]
- public abstract class IsolatedStoragePermissionAttribute : CodeAccessSecurityAttribute
- {
- /// <internalonly/>
- internal long m_userQuota;
-#if false
- /// <internalonly/>
- internal long m_machineQuota;
- /// <internalonly/>
- internal long m_expirationDays;
- /// <internalonly/>
- internal bool m_permanentData;
-#endif
- /// <internalonly/>
- internal IsolatedStorageContainment m_allowed;
- protected IsolatedStoragePermissionAttribute(SecurityAction action) : base(action)
- {
- }
-
- // properties
- public long UserQuota {
- set{
- m_userQuota = value;
- }
- get{
- return m_userQuota;
- }
- }
-#if false
- internal long MachineQuota {
- set{
- m_machineQuota = value;
- }
- get{
- return m_machineQuota;
- }
- }
- internal long ExpirationDays {
- set{
- m_expirationDays = value;
- }
- get{
- return m_expirationDays;
- }
- }
- internal bool PermanentData {
- set{
- m_permanentData = value;
- }
- get{
- return m_permanentData;
- }
- }
-#endif
- public IsolatedStorageContainment UsageAllowed {
- set{
- m_allowed = value;
- }
- get{
- return m_allowed;
- }
- }
-
- }
-
- [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor
- | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly,
- AllowMultiple=true, Inherited=false)]
-[System.Runtime.InteropServices.ComVisible(true)]
- [Serializable]
- sealed public class IsolatedStorageFilePermissionAttribute : IsolatedStoragePermissionAttribute
- {
- public IsolatedStorageFilePermissionAttribute(SecurityAction action) : base(action)
- {
-
- }
- public override IPermission CreatePermission()
- {
- IsolatedStorageFilePermission p;
- if (m_unrestricted) {
- p = new IsolatedStorageFilePermission
- (PermissionState.Unrestricted);
- } else {
- p = new IsolatedStorageFilePermission(PermissionState.None);
- p.UserQuota = m_userQuota;
- p.UsageAllowed = m_allowed;
-#if false
- p.PermanentData = m_permanentData;
- p.MachineQuota = m_machineQuota;
- p.ExpirationDays = m_expirationDays;
-#endif
- }
- return p;
- }
- }
-#endif // FEATURE_CORECLR
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly, AllowMultiple = true, Inherited = false )]
[System.Runtime.InteropServices.ComVisible(true)]
@@ -1109,66 +867,12 @@ namespace System.Security.Permissions
return null;
}
-#if FEATURE_CAS_POLICY
- private PermissionSet BruteForceParseStream(Stream stream)
- {
- Encoding[] encodings = new Encoding[] { Encoding.UTF8,
- Encoding.ASCII,
- Encoding.Unicode };
-
- StreamReader reader = null;
- Exception exception = null;
-
- for (int i = 0; reader == null && i < encodings.Length; ++i)
- {
- try
- {
- stream.Position = 0;
- reader = new StreamReader( stream, encodings[i] );
-
- return ParsePermissionSet( new Parser(reader) );
- }
- catch (Exception e1)
- {
- if (exception == null)
- exception = e1;
- }
- }
-
- throw exception;
- }
-
- private PermissionSet ParsePermissionSet(Parser parser)
- {
- SecurityElement e = parser.GetTopElement();
- PermissionSet permSet = new PermissionSet( PermissionState.None );
- permSet.FromXml( e );
-
- return permSet;
- }
-#endif // FEATURE_CAS_POLICY
-
-#if FEATURE_CAS_POLICY
- [System.Security.SecuritySafeCritical] // auto-generated
-#endif
public PermissionSet CreatePermissionSet()
{
if (m_unrestricted)
return new PermissionSet( PermissionState.Unrestricted );
else if (m_name != null)
-#if FEATURE_CAS_POLICY
- return PolicyLevel.GetBuiltInSet( m_name );
-#else
return NamedPermissionSet.GetBuiltInSet( m_name );
-#endif // FEATURE_CAS_POLICY
-#if FEATURE_CAS_POLICY
- else if (m_xml != null)
- return ParsePermissionSet( new Parser(m_xml.ToCharArray()) );
- else if (m_hex != null)
- return BruteForceParseStream( new MemoryStream(Util.Hex.DecodeHexString(m_hex)) );
- else if (m_file != null)
- return BruteForceParseStream( new FileStream( m_file, FileMode.Open, FileAccess.Read) );
-#endif // FEATURE_CAS_POLICY
else
return new PermissionSet( PermissionState.None );
}
diff --git a/src/mscorlib/src/System/Security/Permissions/ReflectionPermission.cs b/src/mscorlib/src/System/Security/Permissions/ReflectionPermission.cs
index 2bc3c08ff9..1c9dd7696c 100644
--- a/src/mscorlib/src/System/Security/Permissions/ReflectionPermission.cs
+++ b/src/mscorlib/src/System/Security/Permissions/ReflectionPermission.cs
@@ -259,45 +259,6 @@ namespace System.Security.Permissions
throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)type));
Contract.EndContractBlock();
}
-
-#if FEATURE_CAS_POLICY
- //------------------------------------------------------
- //
- // PUBLIC ENCODING METHODS
- //
- //------------------------------------------------------
-
- public override SecurityElement ToXml()
- {
- SecurityElement esd = CodeAccessPermission.CreatePermissionElement( this, "System.Security.Permissions.ReflectionPermission" );
- if (!IsUnrestricted())
- {
- esd.AddAttribute( "Flags", XMLUtil.BitFieldEnumToString( typeof( ReflectionPermissionFlag ), m_flags ) );
- }
- else
- {
- esd.AddAttribute( "Unrestricted", "true" );
- }
- return esd;
- }
-
- public override void FromXml(SecurityElement esd)
- {
- CodeAccessPermission.ValidateElement( esd, this );
- if (XMLUtil.IsUnrestricted( esd ))
- {
- m_flags = ReflectionPermission.AllFlagsAndMore;
- return;
- }
-
- Reset () ;
- SetUnrestricted (false) ;
-
- String flags = esd.Attribute( "Flags" );
- if (flags != null)
- m_flags = (ReflectionPermissionFlag)Enum.Parse( typeof( ReflectionPermissionFlag ), flags );
- }
-#endif // FEATURE_CAS_POLICY
/// <internalonly/>
int IBuiltInPermission.GetTokenIndex()
diff --git a/src/mscorlib/src/System/Security/Permissions/RegistryPermission.cs b/src/mscorlib/src/System/Security/Permissions/RegistryPermission.cs
index bf801d625b..c0c51e94a2 100644
--- a/src/mscorlib/src/System/Security/Permissions/RegistryPermission.cs
+++ b/src/mscorlib/src/System/Security/Permissions/RegistryPermission.cs
@@ -59,14 +59,6 @@ namespace System.Security.Permissions
SetPathList( access, pathList );
}
-#if FEATURE_MACL
- public RegistryPermission( RegistryPermissionAccess access, AccessControlActions control, String pathList )
- {
- m_unrestricted = false;
- AddPathList( access, control, pathList );
- }
-#endif
-
public void SetPathList( RegistryPermissionAccess access, String pathList )
{
VerifyAccess( access );
@@ -85,27 +77,11 @@ namespace System.Security.Permissions
AddPathList( access, pathList );
}
-#if FEATURE_MACL
- internal void SetPathList( AccessControlActions control, String pathList )
- {
- m_unrestricted = false;
-
- if ((control & AccessControlActions.View) != 0)
- m_viewAcl = null;
-
- if ((control & AccessControlActions.Change) != 0)
- m_changeAcl = null;
-
- AddPathList( RegistryPermissionAccess.NoAccess, control, pathList );
- }
-#endif
-
public void AddPathList( RegistryPermissionAccess access, String pathList )
{
AddPathList( access, AccessControlActions.None, pathList );
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void AddPathList( RegistryPermissionAccess access, AccessControlActions control, String pathList )
{
VerifyAccess( access );
@@ -130,25 +106,8 @@ namespace System.Security.Permissions
m_create = new StringExpressionSet();
m_create.AddExpressions( pathList );
}
-
-#if FEATURE_MACL
- if ((control & AccessControlActions.View) != 0)
- {
- if (m_viewAcl == null)
- m_viewAcl = new StringExpressionSet();
- m_viewAcl.AddExpressions( pathList );
- }
-
- if ((control & AccessControlActions.Change) != 0)
- {
- if (m_changeAcl == null)
- m_changeAcl = new StringExpressionSet();
- m_changeAcl.AddExpressions( pathList );
- }
-#endif
}
- [SecuritySafeCritical]
public String GetPathList( RegistryPermissionAccess access )
{
// SafeCritical: these are registry paths, which means we're not leaking file system information here
@@ -233,7 +192,6 @@ namespace System.Security.Permissions
//
//------------------------------------------------------
- [System.Security.SecuritySafeCritical] // auto-generated
public override bool IsSubsetOf(IPermission target)
{
if (target == null)
@@ -257,7 +215,6 @@ namespace System.Security.Permissions
(this.m_changeAcl == null || this.m_changeAcl.IsSubsetOf( operand.m_changeAcl )));
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override IPermission Intersect(IPermission target)
{
if (target == null)
@@ -309,7 +266,6 @@ namespace System.Security.Permissions
return intersectPermission;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override IPermission Union(IPermission other)
{
if (other == null)
@@ -391,93 +347,6 @@ namespace System.Security.Permissions
}
return copy;
}
-
-#if FEATURE_CAS_POLICY
- [SecuritySafeCritical]
- public override SecurityElement ToXml()
- {
- // SafeCritical: our string expression sets don't contain paths, so there's no information that
- // needs to be guarded in them.
- SecurityElement esd = CodeAccessPermission.CreatePermissionElement( this, "System.Security.Permissions.RegistryPermission" );
- if (!IsUnrestricted())
- {
- if (this.m_read != null && !this.m_read.IsEmpty())
- {
- esd.AddAttribute( "Read", SecurityElement.Escape( m_read.UnsafeToString() ) );
- }
- if (this.m_write != null && !this.m_write.IsEmpty())
- {
- esd.AddAttribute( "Write", SecurityElement.Escape( m_write.UnsafeToString() ) );
- }
- if (this.m_create != null && !this.m_create.IsEmpty())
- {
- esd.AddAttribute( "Create", SecurityElement.Escape( m_create.UnsafeToString() ) );
- }
- if (this.m_viewAcl != null && !this.m_viewAcl.IsEmpty())
- {
- esd.AddAttribute( "ViewAccessControl", SecurityElement.Escape( m_viewAcl.UnsafeToString() ) );
- }
- if (this.m_changeAcl != null && !this.m_changeAcl.IsEmpty())
- {
- esd.AddAttribute( "ChangeAccessControl", SecurityElement.Escape( m_changeAcl.UnsafeToString() ) );
- }
- }
- else
- {
- esd.AddAttribute( "Unrestricted", "true" );
- }
- return esd;
- }
-
- public override void FromXml(SecurityElement esd)
- {
- CodeAccessPermission.ValidateElement( esd, this );
- String et;
-
- if (XMLUtil.IsUnrestricted( esd ))
- {
- m_unrestricted = true;
- return;
- }
-
- m_unrestricted = false;
- m_read = null;
- m_write = null;
- m_create = null;
- m_viewAcl = null;
- m_changeAcl = null;
-
- et = esd.Attribute( "Read" );
- if (et != null)
- {
- m_read = new StringExpressionSet( et );
- }
-
- et = esd.Attribute( "Write" );
- if (et != null)
- {
- m_write = new StringExpressionSet( et );
- }
-
- et = esd.Attribute( "Create" );
- if (et != null)
- {
- m_create = new StringExpressionSet( et );
- }
-
- et = esd.Attribute( "ViewAccessControl" );
- if (et != null)
- {
- m_viewAcl = new StringExpressionSet( et );
- }
-
- et = esd.Attribute( "ChangeAccessControl" );
- if (et != null)
- {
- m_changeAcl = new StringExpressionSet( et );
- }
- }
-#endif // FEATURE_CAS_POLICY
/// <internalonly/>
int IBuiltInPermission.GetTokenIndex()
diff --git a/src/mscorlib/src/System/Security/Permissions/SecurityPermission.cs b/src/mscorlib/src/System/Security/Permissions/SecurityPermission.cs
index b359cc530d..cf3002989d 100644
--- a/src/mscorlib/src/System/Security/Permissions/SecurityPermission.cs
+++ b/src/mscorlib/src/System/Security/Permissions/SecurityPermission.cs
@@ -16,13 +16,11 @@ namespace System.Security.Permissions
using System.Globalization;
using System.Diagnostics.Contracts;
-[Serializable]
+ [Serializable]
[Flags]
-[System.Runtime.InteropServices.ComVisible(true)]
-#if !FEATURE_CAS_POLICY
+ [System.Runtime.InteropServices.ComVisible(true)]
// The csharp compiler requires these types to be public, but they are not used elsewhere.
[Obsolete("SecurityPermissionFlag is no longer accessible to application code.")]
-#endif
public enum SecurityPermissionFlag
{
NoFlags = 0x00,
@@ -254,99 +252,9 @@ namespace System.Security.Permissions
Contract.EndContractBlock();
}
-#if FEATURE_CAS_POLICY
- //------------------------------------------------------
- //
- // PUBLIC ENCODING METHODS
- //
- //------------------------------------------------------
-
- private const String _strHeaderAssertion = "Assertion";
- private const String _strHeaderUnmanagedCode = "UnmanagedCode";
- private const String _strHeaderExecution = "Execution";
- private const String _strHeaderSkipVerification = "SkipVerification";
- private const String _strHeaderControlThread = "ControlThread";
- private const String _strHeaderControlEvidence = "ControlEvidence";
- private const String _strHeaderControlPolicy = "ControlPolicy";
- private const String _strHeaderSerializationFormatter = "SerializationFormatter";
- private const String _strHeaderControlDomainPolicy = "ControlDomainPolicy";
- private const String _strHeaderControlPrincipal = "ControlPrincipal";
- private const String _strHeaderControlAppDomain = "ControlAppDomain";
-
- public override SecurityElement ToXml()
- {
- SecurityElement esd = CodeAccessPermission.CreatePermissionElement( this, "System.Security.Permissions.SecurityPermission" );
- if (!IsUnrestricted())
- {
- esd.AddAttribute( "Flags", XMLUtil.BitFieldEnumToString( typeof( SecurityPermissionFlag ), m_flags ) );
- }
- else
- {
- esd.AddAttribute( "Unrestricted", "true" );
- }
- return esd;
- }
-
- public override void FromXml(SecurityElement esd)
- {
- CodeAccessPermission.ValidateElement( esd, this );
- if (XMLUtil.IsUnrestricted( esd ))
- {
- m_flags = SecurityPermissionFlag.AllFlags;
- return;
- }
-
- Reset () ;
- SetUnrestricted (false) ;
-
- String flags = esd.Attribute( "Flags" );
-
- if (flags != null)
- m_flags = (SecurityPermissionFlag)Enum.Parse( typeof( SecurityPermissionFlag ), flags );
- }
-#endif // FEATURE_CAS_POLICY
-
//
// Object Overrides
//
-
- #if ZERO // Do not remove this code, usefull for debugging
- public override String ToString()
- {
- StringBuilder sb = new StringBuilder();
- sb.Append("SecurityPermission(");
- if (IsUnrestricted())
- {
- sb.Append("Unrestricted");
- }
- else
- {
- if (GetFlag(SecurityPermissionFlag.Assertion))
- sb.Append("Assertion; ");
- if (GetFlag(SecurityPermissionFlag.UnmanagedCode))
- sb.Append("UnmangedCode; ");
- if (GetFlag(SecurityPermissionFlag.SkipVerification))
- sb.Append("SkipVerification; ");
- if (GetFlag(SecurityPermissionFlag.Execution))
- sb.Append("Execution; ");
- if (GetFlag(SecurityPermissionFlag.ControlThread))
- sb.Append("ControlThread; ");
- if (GetFlag(SecurityPermissionFlag.ControlEvidence))
- sb.Append("ControlEvidence; ");
- if (GetFlag(SecurityPermissionFlag.ControlPolicy))
- sb.Append("ControlPolicy; ");
- if (GetFlag(SecurityPermissionFlag.SerializationFormatter))
- sb.Append("SerializationFormatter; ");
- if (GetFlag(SecurityPermissionFlag.ControlDomainPolicy))
- sb.Append("ControlDomainPolicy; ");
- if (GetFlag(SecurityPermissionFlag.ControlPrincipal))
- sb.Append("ControlPrincipal; ");
- }
-
- sb.Append(")");
- return sb.ToString();
- }
- #endif
/// <internalonly/>
int IBuiltInPermission.GetTokenIndex()
diff --git a/src/mscorlib/src/System/Security/Permissions/SiteIdentityPermission.cs b/src/mscorlib/src/System/Security/Permissions/SiteIdentityPermission.cs
index 6050b580df..ff38d515a1 100644
--- a/src/mscorlib/src/System/Security/Permissions/SiteIdentityPermission.cs
+++ b/src/mscorlib/src/System/Security/Permissions/SiteIdentityPermission.cs
@@ -5,9 +5,6 @@
namespace System.Security.Permissions
{
using System;
-#if FEATURE_CAS_POLICY
- using SecurityElement = System.Security.SecurityElement;
-#endif // FEATURE_CAS_POLICY
using SiteString = System.Security.Util.SiteString;
using System.Text;
using System.Collections;
@@ -31,55 +28,6 @@ namespace System.Security.Permissions
[OptionalField(VersionAdded = 2)]
private SiteString[] m_sites;
-#if FEATURE_REMOTING
- // This field will be populated only for non X-AD scenarios where we create a XML-ised string of the Permission
- [OptionalField(VersionAdded = 2)]
- private String m_serializedPermission;
-
- // This field is legacy info from v1.x and is never used in v2.0 and beyond: purely for serialization purposes
- private SiteString m_site;
-
- [OnDeserialized]
- private void OnDeserialized(StreamingContext ctx)
- {
- // v2.0 and beyond XML case
- if (m_serializedPermission != null)
- {
- FromXml(SecurityElement.FromString(m_serializedPermission));
- m_serializedPermission = null;
- }
- else if (m_site != null) //v1.x case where we read the m_site value
- {
- m_unrestricted = false;
- m_sites = new SiteString[1];
- m_sites[0] = m_site;
- m_site = null;
- }
- }
-
- [OnSerializing]
- private void OnSerializing(StreamingContext ctx)
- {
-
- if ((ctx.State & ~(StreamingContextStates.Clone|StreamingContextStates.CrossAppDomain)) != 0)
- {
- m_serializedPermission = ToXml().ToString(); //for the v2 and beyond case
- if (m_sites != null && m_sites.Length == 1) // for the v1.x case
- m_site = m_sites[0];
-
- }
- }
- [OnSerialized]
- private void OnSerialized(StreamingContext ctx)
- {
- if ((ctx.State & ~(StreamingContextStates.Clone|StreamingContextStates.CrossAppDomain)) != 0)
- {
- m_serializedPermission = null;
- m_site = null;
- }
- }
-#endif // FEATURE_REMOTING
-
//------------------------------------------------------
//
// PUBLIC CONSTRUCTORS
@@ -150,8 +98,6 @@ namespace System.Security.Permissions
// IPERMISSION IMPLEMENTATION
//
//------------------------------------------------------
-
-
public override IPermission Copy()
{
SiteIdentityPermission perm = new SiteIdentityPermission( PermissionState.None );
@@ -291,60 +237,6 @@ namespace System.Security.Permissions
return result;
}
-#if FEATURE_CAS_POLICY
- public override void FromXml(SecurityElement esd)
- {
- m_unrestricted = false;
- m_sites = null;
- CodeAccessPermission.ValidateElement( esd, this );
- String unr = esd.Attribute( "Unrestricted" );
- if(unr != null && String.Compare(unr, "true", StringComparison.OrdinalIgnoreCase) == 0)
- {
- m_unrestricted = true;
- return;
- }
- String elem = esd.Attribute( "Site" );
- List<SiteString> al = new List<SiteString>();
- if(elem != null)
- al.Add(new SiteString( elem ));
- ArrayList alChildren = esd.Children;
- if(alChildren != null)
- {
- foreach(SecurityElement child in alChildren)
- {
- elem = child.Attribute( "Site" );
- if(elem != null)
- al.Add(new SiteString( elem ));
- }
- }
- if(al.Count != 0)
- m_sites = al.ToArray();
- }
-
- public override SecurityElement ToXml()
- {
- SecurityElement esd = CodeAccessPermission.CreatePermissionElement( this, "System.Security.Permissions.SiteIdentityPermission" );
- if (m_unrestricted)
- esd.AddAttribute( "Unrestricted", "true" );
- else if (m_sites != null)
- {
- if (m_sites.Length == 1)
- esd.AddAttribute( "Site", m_sites[0].ToString() );
- else
- {
- int n;
- for(n = 0; n < m_sites.Length; n++)
- {
- SecurityElement child = new SecurityElement("Site");
- child.AddAttribute( "Site", m_sites[n].ToString() );
- esd.AddChild(child);
- }
- }
- }
- return esd;
- }
-#endif // FEATURE_CAS_POLICY
-
/// <internalonly/>
int IBuiltInPermission.GetTokenIndex()
{
diff --git a/src/mscorlib/src/System/Security/Permissions/StrongNameIdentityPermission.cs b/src/mscorlib/src/System/Security/Permissions/StrongNameIdentityPermission.cs
index 5f5de0ef80..f09d84de34 100644
--- a/src/mscorlib/src/System/Security/Permissions/StrongNameIdentityPermission.cs
+++ b/src/mscorlib/src/System/Security/Permissions/StrongNameIdentityPermission.cs
@@ -5,9 +5,6 @@
namespace System.Security.Permissions
{
using System;
-#if FEATURE_CAS_POLICY
- using SecurityElement = System.Security.SecurityElement;
-#endif // FEATURE_CAS_POLICY
using System.Security.Util;
using System.IO;
using String = System.String;
@@ -135,7 +132,7 @@ namespace System.Security.Permissions
public StrongNameIdentityPermission( StrongNamePublicKeyBlob blob, String name, Version version )
{
if (blob == null)
- throw new ArgumentNullException( "blob" );
+ throw new ArgumentNullException( nameof(blob) );
if (name != null && name.Equals( "" ))
throw new ArgumentException( Environment.GetResourceString( "Argument_EmptyStrongName" ) );
Contract.EndContractBlock();
@@ -156,7 +153,7 @@ namespace System.Security.Permissions
set
{
if (value == null)
- throw new ArgumentNullException( "PublicKey" );
+ throw new ArgumentNullException( nameof(PublicKey) );
Contract.EndContractBlock();
m_unrestricted = false;
if(m_strongNames != null && m_strongNames.Length == 1)
@@ -389,89 +386,6 @@ namespace System.Security.Permissions
return result;
}
-#if FEATURE_CAS_POLICY
- public override void FromXml(SecurityElement e)
- {
- m_unrestricted = false;
- m_strongNames = null;
- CodeAccessPermission.ValidateElement( e, this );
- String unr = e.Attribute( "Unrestricted" );
- if(unr != null && String.Compare(unr, "true", StringComparison.OrdinalIgnoreCase) == 0)
- {
- m_unrestricted = true;
- return;
- }
- String elBlob = e.Attribute("PublicKeyBlob");
- String elName = e.Attribute("Name");
- String elVersion = e.Attribute("AssemblyVersion");
- StrongName2 sn;
- List<StrongName2> al = new List<StrongName2>();
- if(elBlob != null || elName != null || elVersion != null)
- {
- sn = new StrongName2(
- (elBlob == null ? null : new StrongNamePublicKeyBlob(elBlob)),
- elName,
- (elVersion == null ? null : new Version(elVersion)));
- al.Add(sn);
- }
- ArrayList alChildren = e.Children;
- if(alChildren != null)
- {
- foreach(SecurityElement child in alChildren)
- {
- elBlob = child.Attribute("PublicKeyBlob");
- elName = child.Attribute("Name");
- elVersion = child.Attribute("AssemblyVersion");
- if(elBlob != null || elName != null || elVersion != null)
- {
- sn = new StrongName2(
- (elBlob == null ? null : new StrongNamePublicKeyBlob(elBlob)),
- elName,
- (elVersion == null ? null : new Version(elVersion)));
- al.Add(sn);
- }
- }
- }
- if(al.Count != 0)
- m_strongNames = al.ToArray();
- }
-
- public override SecurityElement ToXml()
- {
- SecurityElement esd = CodeAccessPermission.CreatePermissionElement( this, "System.Security.Permissions.StrongNameIdentityPermission" );
- if (m_unrestricted)
- esd.AddAttribute( "Unrestricted", "true" );
- else if (m_strongNames != null)
- {
- if (m_strongNames.Length == 1)
- {
- if (m_strongNames[0].m_publicKeyBlob != null)
- esd.AddAttribute("PublicKeyBlob", Hex.EncodeHexString(m_strongNames[0].m_publicKeyBlob.PublicKey));
- if (m_strongNames[0].m_name != null)
- esd.AddAttribute("Name", m_strongNames[0].m_name);
- if ((Object)m_strongNames[0].m_version != null)
- esd.AddAttribute("AssemblyVersion", m_strongNames[0].m_version.ToString());
- }
- else
- {
- int n;
- for(n = 0; n < m_strongNames.Length; n++)
- {
- SecurityElement child = new SecurityElement("StrongName");
- if (m_strongNames[n].m_publicKeyBlob != null)
- child.AddAttribute("PublicKeyBlob", Hex.EncodeHexString(m_strongNames[n].m_publicKeyBlob.PublicKey));
- if (m_strongNames[n].m_name != null)
- child.AddAttribute("Name", m_strongNames[n].m_name);
- if ((Object)m_strongNames[n].m_version != null)
- child.AddAttribute("AssemblyVersion", m_strongNames[n].m_version.ToString());
- esd.AddChild(child);
- }
- }
- }
- return esd;
- }
-#endif // FEATURE_CAS_POLICY
-
/// <internalonly/>
int IBuiltInPermission.GetTokenIndex()
{
diff --git a/src/mscorlib/src/System/Security/Permissions/StrongNamePublicKeyBlob.cs b/src/mscorlib/src/System/Security/Permissions/StrongNamePublicKeyBlob.cs
index e0aacaf80c..823eaba938 100644
--- a/src/mscorlib/src/System/Security/Permissions/StrongNamePublicKeyBlob.cs
+++ b/src/mscorlib/src/System/Security/Permissions/StrongNamePublicKeyBlob.cs
@@ -20,7 +20,7 @@ namespace System.Security.Permissions
public StrongNamePublicKeyBlob( byte[] publicKey )
{
if (publicKey == null)
- throw new ArgumentNullException( "PublicKey" );
+ throw new ArgumentNullException( nameof(PublicKey) );
Contract.EndContractBlock();
this.PublicKey = new byte[publicKey.Length];
diff --git a/src/mscorlib/src/System/Security/Permissions/UIPermission.cs b/src/mscorlib/src/System/Security/Permissions/UIPermission.cs
index bb122b734c..4abe801e41 100644
--- a/src/mscorlib/src/System/Security/Permissions/UIPermission.cs
+++ b/src/mscorlib/src/System/Security/Permissions/UIPermission.cs
@@ -309,50 +309,6 @@ namespace System.Security.Permissions
{
return new UIPermission(this.m_windowFlag, this.m_clipboardFlag);
}
-
-#if FEATURE_CAS_POLICY
- public override SecurityElement ToXml()
- {
- SecurityElement esd = CodeAccessPermission.CreatePermissionElement( this, "System.Security.Permissions.UIPermission" );
- if (!IsUnrestricted())
- {
- if (m_windowFlag != UIPermissionWindow.NoWindows)
- {
- esd.AddAttribute( "Window", Enum.GetName( typeof( UIPermissionWindow ), m_windowFlag ) );
- }
- if (m_clipboardFlag != UIPermissionClipboard.NoClipboard)
- {
- esd.AddAttribute( "Clipboard", Enum.GetName( typeof( UIPermissionClipboard ), m_clipboardFlag ) );
- }
- }
- else
- {
- esd.AddAttribute( "Unrestricted", "true" );
- }
- return esd;
- }
-
- public override void FromXml(SecurityElement esd)
- {
- CodeAccessPermission.ValidateElement( esd, this );
- if (XMLUtil.IsUnrestricted( esd ))
- {
- SetUnrestricted( true );
- return;
- }
-
- m_windowFlag = UIPermissionWindow.NoWindows;
- m_clipboardFlag = UIPermissionClipboard.NoClipboard;
-
- String window = esd.Attribute( "Window" );
- if (window != null)
- m_windowFlag = (UIPermissionWindow)Enum.Parse( typeof( UIPermissionWindow ), window );
-
- String clipboard = esd.Attribute( "Clipboard" );
- if (clipboard != null)
- m_clipboardFlag = (UIPermissionClipboard)Enum.Parse( typeof( UIPermissionClipboard ), clipboard );
- }
-#endif // FEATURE_CAS_POLICY
/// <internalonly/>
int IBuiltInPermission.GetTokenIndex()
diff --git a/src/mscorlib/src/System/Security/Permissions/URLIdentityPermission.cs b/src/mscorlib/src/System/Security/Permissions/URLIdentityPermission.cs
index e62449cf3e..0883bf8979 100644
--- a/src/mscorlib/src/System/Security/Permissions/URLIdentityPermission.cs
+++ b/src/mscorlib/src/System/Security/Permissions/URLIdentityPermission.cs
@@ -5,9 +5,6 @@
namespace System.Security.Permissions
{
using System;
-#if FEATURE_CAS_POLICY
- using SecurityElement = System.Security.SecurityElement;
-#endif // FEATURE_CAS_POLICY
using System.Security.Util;
using System.IO;
using System.Text;
@@ -31,58 +28,8 @@ namespace System.Security.Permissions
[OptionalField(VersionAdded = 2)]
private bool m_unrestricted;
- [OptionalField(VersionAdded = 2)]
- private URLString[] m_urls;
-
-#if FEATURE_REMOTING
- // This field will be populated only for non X-AD scenarios where we create a XML-ised string of the Permission
[OptionalField(VersionAdded = 2)]
- private String m_serializedPermission;
-
- // This field is legacy info from v1.x and is never used in v2.0 and beyond: purely for serialization purposes
- private URLString m_url;
-
- [OnDeserialized]
- private void OnDeserialized(StreamingContext ctx)
- {
- // v2.0 and beyond XML case
- if (m_serializedPermission != null)
- {
- FromXml(SecurityElement.FromString(m_serializedPermission));
- m_serializedPermission = null;
- }
- else if (m_url != null) //v1.x case where we read the m_site value
- {
- m_unrestricted = false;
- m_urls = new URLString[1];
- m_urls[0] = m_url;
- m_url = null;
- }
-
- }
-
- [OnSerializing]
- private void OnSerializing(StreamingContext ctx)
- {
-
- if ((ctx.State & ~(StreamingContextStates.Clone|StreamingContextStates.CrossAppDomain)) != 0)
- {
- m_serializedPermission = ToXml().ToString(); //for the v2 and beyond case
- if (m_urls != null && m_urls.Length == 1) // for the v1.x case
- m_url = m_urls[0];
-
- }
- }
- [OnSerialized]
- private void OnSerialized(StreamingContext ctx)
- {
- if ((ctx.State & ~(StreamingContextStates.Clone|StreamingContextStates.CrossAppDomain)) != 0)
- {
- m_serializedPermission = null;
- m_url = null;
- }
- }
-#endif // FEATURE_REMOTING
+ private URLString[] m_urls;
//------------------------------------------------------
//
@@ -110,7 +57,7 @@ namespace System.Security.Permissions
public UrlIdentityPermission( String site )
{
if (site == null)
- throw new ArgumentNullException( "site" );
+ throw new ArgumentNullException( nameof(site) );
Contract.EndContractBlock();
Url = site;
}
@@ -323,60 +270,6 @@ namespace System.Security.Permissions
return result;
}
-#if FEATURE_CAS_POLICY
- public override void FromXml(SecurityElement esd)
- {
- m_unrestricted = false;
- m_urls = null;
- CodeAccessPermission.ValidateElement( esd, this );
- String unr = esd.Attribute( "Unrestricted" );
- if(unr != null && String.Compare(unr, "true", StringComparison.OrdinalIgnoreCase) == 0)
- {
- m_unrestricted = true;
- return;
- }
- String elem = esd.Attribute( "Url" );
- List<URLString> al = new List<URLString>();
- if(elem != null)
- al.Add(new URLString( elem, true ));
- ArrayList alChildren = esd.Children;
- if(alChildren != null)
- {
- foreach(SecurityElement child in alChildren)
- {
- elem = child.Attribute( "Url" );
- if(elem != null)
- al.Add(new URLString( elem, true ));
- }
- }
- if(al.Count != 0)
- m_urls = al.ToArray();
- }
-
- public override SecurityElement ToXml()
- {
- SecurityElement esd = CodeAccessPermission.CreatePermissionElement( this, "System.Security.Permissions.UrlIdentityPermission" );
- if (m_unrestricted)
- esd.AddAttribute( "Unrestricted", "true" );
- else if (m_urls != null)
- {
- if (m_urls.Length == 1)
- esd.AddAttribute( "Url", m_urls[0].ToString() );
- else
- {
- int n;
- for(n = 0; n < m_urls.Length; n++)
- {
- SecurityElement child = new SecurityElement("Url");
- child.AddAttribute( "Url", m_urls[n].ToString() );
- esd.AddChild(child);
- }
- }
- }
- return esd;
- }
-#endif // FEATURE_CAS_POLICY
-
/// <internalonly/>
int IBuiltInPermission.GetTokenIndex()
{
diff --git a/src/mscorlib/src/System/Security/Permissions/ZoneIdentityPermission.cs b/src/mscorlib/src/System/Security/Permissions/ZoneIdentityPermission.cs
index 803bd34cf1..9023c7eece 100644
--- a/src/mscorlib/src/System/Security/Permissions/ZoneIdentityPermission.cs
+++ b/src/mscorlib/src/System/Security/Permissions/ZoneIdentityPermission.cs
@@ -8,9 +8,6 @@
namespace System.Security.Permissions
{
using System;
-#if FEATURE_CAS_POLICY
- using SecurityElement = System.Security.SecurityElement;
-#endif // FEATURE_CAS_POLICY
using System.Globalization;
using System.Runtime.Serialization;
using System.Collections;
@@ -42,57 +39,6 @@ namespace System.Security.Permissions
[OptionalField(VersionAdded = 2)]
private uint m_zones;
-#if FEATURE_REMOTING
- // This field will be populated only for non X-AD scenarios where we create a XML-ised string of the Permission
- [OptionalField(VersionAdded = 2)]
- private String m_serializedPermission;
-
- // This field is legacy info from v1.x and is never used in v2.0 and beyond: purely for serialization purposes
- private SecurityZone m_zone = SecurityZone.NoZone;
-
- [OnDeserialized]
- private void OnDeserialized(StreamingContext ctx)
- {
- if ((ctx.State & ~(StreamingContextStates.Clone|StreamingContextStates.CrossAppDomain)) != 0)
- {
- // v2.0 and beyond XML case
- if (m_serializedPermission != null)
- {
- FromXml(SecurityElement.FromString(m_serializedPermission));
- m_serializedPermission = null;
- }
- else //v1.x case where we read the m_zone value
- {
- SecurityZone = m_zone;
- m_zone = SecurityZone.NoZone;
- }
- }
-
-
- }
-
- [OnSerializing]
- private void OnSerializing(StreamingContext ctx)
- {
-
- if ((ctx.State & ~(StreamingContextStates.Clone|StreamingContextStates.CrossAppDomain)) != 0)
- {
- m_serializedPermission = ToXml().ToString(); //for the v2 and beyond case
- m_zone = SecurityZone;
-
- }
- }
- [OnSerialized]
- private void OnSerialized(StreamingContext ctx)
- {
- if ((ctx.State & ~(StreamingContextStates.Clone|StreamingContextStates.CrossAppDomain)) != 0)
- {
- m_serializedPermission = null;
- m_zone = SecurityZone.NoZone;
- }
- }
-#endif // FEATURE_REMOTING
-
//------------------------------------------------------
//
// PUBLIC CONSTRUCTORS
@@ -247,53 +193,6 @@ namespace System.Security.Permissions
return new ZoneIdentityPermission(this.m_zones | that.m_zones);
}
-#if FEATURE_CAS_POLICY
- public override SecurityElement ToXml()
- {
- SecurityElement esd = CodeAccessPermission.CreatePermissionElement( this, "System.Security.Permissions.ZoneIdentityPermission" );
- if (SecurityZone != SecurityZone.NoZone)
- {
- esd.AddAttribute( "Zone", Enum.GetName( typeof( SecurityZone ), this.SecurityZone ) );
- }
- else
- {
- int nEnum = 0;
- uint nFlag;
- for(nFlag = 1; nFlag < AllZones; nFlag <<= 1)
- {
- if((m_zones & nFlag) != 0)
- {
- SecurityElement child = new SecurityElement("Zone");
- child.AddAttribute( "Zone", Enum.GetName( typeof( SecurityZone ), (SecurityZone)nEnum ) );
- esd.AddChild(child);
- }
- nEnum++;
- }
- }
- return esd;
- }
-
- public override void FromXml(SecurityElement esd)
- {
- m_zones = 0;
- CodeAccessPermission.ValidateElement( esd, this );
- String eZone = esd.Attribute( "Zone" );
- if (eZone != null)
- SecurityZone = (SecurityZone)Enum.Parse( typeof( SecurityZone ), eZone );
- if(esd.Children != null)
- {
- foreach(SecurityElement child in esd.Children)
- {
- eZone = child.Attribute( "Zone" );
- int enm = (int)Enum.Parse( typeof( SecurityZone ), eZone );
- if(enm == (int)SecurityZone.NoZone)
- continue;
- m_zones |= ((uint)1 << enm);
- }
- }
- }
-#endif // FEATURE_CAS_POLICY
-
/// <internalonly/>
int IBuiltInPermission.GetTokenIndex()
{
diff --git a/src/mscorlib/src/System/Security/Permissions/keycontainerpermission.cs b/src/mscorlib/src/System/Security/Permissions/keycontainerpermission.cs
index 9691c03da3..d4f1c273c6 100644
--- a/src/mscorlib/src/System/Security/Permissions/keycontainerpermission.cs
+++ b/src/mscorlib/src/System/Security/Permissions/keycontainerpermission.cs
@@ -11,6 +11,7 @@ namespace System.Security.Permissions {
#endif
using System.Security.Util;
using System.Globalization;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
[Serializable]
@@ -88,7 +89,7 @@ namespace System.Security.Permissions {
m_keyStore = "*";
} else {
if (value != "User" && value != "Machine" && value != "*")
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidKeyStore", value), "value");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidKeyStore", value), nameof(value));
m_keyStore = value;
}
}
@@ -232,7 +233,7 @@ namespace System.Security.Permissions {
if (index < 0)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumNotStarted"));
if (index >= Count)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
Contract.EndContractBlock();
return (KeyContainerPermissionAccessEntry)m_list[index];
@@ -247,7 +248,7 @@ namespace System.Security.Permissions {
public int Add (KeyContainerPermissionAccessEntry accessEntry) {
if (accessEntry == null)
- throw new ArgumentNullException("accessEntry");
+ throw new ArgumentNullException(nameof(accessEntry));
Contract.EndContractBlock();
int index = m_list.IndexOf(accessEntry);
@@ -275,7 +276,7 @@ namespace System.Security.Permissions {
public void Remove (KeyContainerPermissionAccessEntry accessEntry) {
if (accessEntry == null)
- throw new ArgumentNullException("accessEntry");
+ throw new ArgumentNullException(nameof(accessEntry));
Contract.EndContractBlock();
m_list.Remove(accessEntry);
}
@@ -292,11 +293,11 @@ namespace System.Security.Permissions {
/// <internalonly/>
void ICollection.CopyTo (Array array, int index) {
if (array == null)
- throw new ArgumentNullException("array");
+ throw new ArgumentNullException(nameof(array));
if (array.Rank != 1)
throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
if (index < 0 || index >= array.Length)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
if (index + this.Count > array.Length)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Contract.EndContractBlock();
@@ -385,7 +386,7 @@ namespace System.Security.Permissions {
public KeyContainerPermission (KeyContainerPermissionFlags flags, KeyContainerPermissionAccessEntry[] accessList) {
if (accessList == null)
- throw new ArgumentNullException("accessList");
+ throw new ArgumentNullException(nameof(accessList));
Contract.EndContractBlock();
VerifyFlags(flags);
@@ -525,61 +526,6 @@ namespace System.Security.Permissions {
return cp;
}
-#if FEATURE_CAS_POLICY
- public override SecurityElement ToXml () {
- SecurityElement securityElement = CodeAccessPermission.CreatePermissionElement(this, "System.Security.Permissions.KeyContainerPermission");
- if (!IsUnrestricted()) {
- securityElement.AddAttribute("Flags", m_flags.ToString());
- if (AccessEntries.Count > 0) {
- SecurityElement al = new SecurityElement("AccessList");
- foreach (KeyContainerPermissionAccessEntry accessEntry in AccessEntries) {
- SecurityElement entryElem = new SecurityElement("AccessEntry");
- entryElem.AddAttribute("KeyStore", accessEntry.KeyStore);
- entryElem.AddAttribute("ProviderName", accessEntry.ProviderName);
- entryElem.AddAttribute("ProviderType", accessEntry.ProviderType.ToString(null, null));
- entryElem.AddAttribute("KeyContainerName", accessEntry.KeyContainerName);
- entryElem.AddAttribute("KeySpec", accessEntry.KeySpec.ToString(null, null));
- entryElem.AddAttribute("Flags", accessEntry.Flags.ToString());
- al.AddChild(entryElem);
- }
- securityElement.AddChild(al);
- }
- } else
- securityElement.AddAttribute("Unrestricted", "true");
-
- return securityElement;
- }
-
- public override void FromXml (SecurityElement securityElement) {
- CodeAccessPermission.ValidateElement(securityElement, this);
- if (XMLUtil.IsUnrestricted(securityElement)) {
- m_flags = KeyContainerPermissionFlags.AllFlags;
- m_accessEntries = new KeyContainerPermissionAccessEntryCollection(m_flags);
- return;
- }
-
- m_flags = KeyContainerPermissionFlags.NoFlags;
- string strFlags = securityElement.Attribute("Flags");
- if (strFlags != null) {
- KeyContainerPermissionFlags flags = (KeyContainerPermissionFlags) Enum.Parse(typeof(KeyContainerPermissionFlags), strFlags);
- VerifyFlags(flags);
- m_flags = flags;
- }
- m_accessEntries = new KeyContainerPermissionAccessEntryCollection(m_flags);
-
- if (securityElement.InternalChildren != null && securityElement.InternalChildren.Count != 0) {
- IEnumerator enumerator = securityElement.Children.GetEnumerator();
- while (enumerator.MoveNext()) {
- SecurityElement current = (SecurityElement) enumerator.Current;
- if (current != null) {
- if (String.Equals(current.Tag, "AccessList"))
- AddAccessEntries(current);
- }
- }
- }
- }
-#endif // FEATURE_CAS_POLICY
-
/// <internalonly/>
int IBuiltInPermission.GetTokenIndex () {
return KeyContainerPermission.GetTokenIndex();
@@ -597,7 +543,7 @@ namespace System.Security.Permissions {
if (current != null) {
if (String.Equals(current.Tag, "AccessEntry")) {
int iMax = current.m_lAttributes.Count;
- Contract.Assert(iMax % 2 == 0, "Odd number of strings means the attr/value pairs were not added correctly");
+ Debug.Assert(iMax % 2 == 0, "Odd number of strings means the attr/value pairs were not added correctly");
string keyStore = null;
string providerName = null;
int providerType = -1;
diff --git a/src/mscorlib/src/System/Security/Policy/ApplicationTrust.cs b/src/mscorlib/src/System/Security/Policy/ApplicationTrust.cs
index 57b216e462..3d4e35adf4 100644
--- a/src/mscorlib/src/System/Security/Policy/ApplicationTrust.cs
+++ b/src/mscorlib/src/System/Security/Policy/ApplicationTrust.cs
@@ -2,20 +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.
-//
-
-//
//
// This class encapsulates security decisions about an application.
//
-namespace System.Security.Policy {
+namespace System.Security.Policy
+{
using System.Collections;
using System.Collections.Generic;
-#if FEATURE_CLICKONCE
- using System.Deployment.Internal.Isolation;
- using System.Deployment.Internal.Isolation.Manifest;
-#endif
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
@@ -40,14 +34,6 @@ namespace System.Security.Policy {
[Serializable]
public sealed class ApplicationTrust : EvidenceBase, ISecurityEncodable
{
-#if FEATURE_CLICKONCE
- private ApplicationIdentity m_appId;
- private bool m_appTrustedToRun;
- private bool m_persist;
-
- private object m_extraInfo;
- private SecurityElement m_elExtraInfo;
-#endif
private PolicyStatement m_psDefaultGrant;
private IList<StrongName> m_fullTrustAssemblies;
@@ -65,11 +51,6 @@ namespace System.Security.Policy {
[NonSerialized]
private int m_grantSetSpecialFlags;
-#if FEATURE_CLICKONCE
- public ApplicationTrust (ApplicationIdentity applicationIdentity) : this () {
- ApplicationIdentity = applicationIdentity;
- }
-#endif
public ApplicationTrust () : this (new PermissionSet(PermissionState.None))
{
}
@@ -83,7 +64,7 @@ namespace System.Security.Policy {
public ApplicationTrust(PermissionSet defaultGrantSet, IEnumerable<StrongName> fullTrustAssemblies) {
if (fullTrustAssemblies == null) {
- throw new ArgumentNullException("fullTrustAssemblies");
+ throw new ArgumentNullException(nameof(fullTrustAssemblies));
}
InitDefaultGrantSet(defaultGrantSet);
@@ -91,7 +72,7 @@ namespace System.Security.Policy {
List<StrongName> fullTrustList = new List<StrongName>();
foreach (StrongName strongName in fullTrustAssemblies) {
if (strongName == null) {
- throw new ArgumentException(Environment.GetResourceString("Argument_NullFullTrustAssembly"), "fullTrustAssemblies");
+ throw new ArgumentException(Environment.GetResourceString("Argument_NullFullTrustAssembly"), nameof(fullTrustAssemblies));
}
fullTrustList.Add(new StrongName(strongName.PublicKey, strongName.Name, strongName.Version));
@@ -104,7 +85,7 @@ namespace System.Security.Policy {
// IEnumerable virtual dispatches on startup when there are no fullTrustAssemblies (CoreCLR)
private void InitDefaultGrantSet(PermissionSet defaultGrantSet) {
if (defaultGrantSet == null) {
- throw new ArgumentNullException("defaultGrantSet");
+ throw new ArgumentNullException(nameof(defaultGrantSet));
}
// Creating a PolicyStatement copies the incoming permission set, so we don't have to worry
@@ -113,19 +94,6 @@ namespace System.Security.Policy {
DefaultGrantSet = new PolicyStatement(defaultGrantSet);
}
-#if FEATURE_CLICKONCE
- public ApplicationIdentity ApplicationIdentity {
- get {
- return m_appId;
- }
- set {
- if (value == null)
- throw new ArgumentNullException("value", Environment.GetResourceString("Argument_InvalidAppId"));
- Contract.EndContractBlock();
- m_appId = value;
- }
- }
-#endif
public PolicyStatement DefaultGrantSet {
get {
if (m_psDefaultGrant == null)
@@ -149,541 +117,10 @@ namespace System.Security.Policy {
return m_fullTrustAssemblies;
}
}
-#if FEATURE_CLICKONCE
- public bool IsApplicationTrustedToRun {
- get {
- return m_appTrustedToRun;
- }
- set {
- m_appTrustedToRun = value;
- }
- }
-
- public bool Persist {
- get {
- return m_persist;
- }
- set {
- m_persist = value;
- }
- }
-
- public object ExtraInfo {
- get {
- if (m_elExtraInfo != null) {
- m_extraInfo = ObjectFromXml(m_elExtraInfo);
- m_elExtraInfo = null;
- }
- return m_extraInfo;
- }
- set {
- m_elExtraInfo = null;
- m_extraInfo = value;
- }
- }
-#endif //FEATURE_CLICKONCE
-
-#if FEATURE_CAS_POLICY
- public SecurityElement ToXml () {
- SecurityElement elRoot = new SecurityElement("ApplicationTrust");
- elRoot.AddAttribute("version", "1");
-
-#if FEATURE_CLICKONCE
- if (m_appId != null) {
- elRoot.AddAttribute("FullName", SecurityElement.Escape(m_appId.FullName));
- }
- if (m_appTrustedToRun) {
- elRoot.AddAttribute("TrustedToRun", "true");
- }
- if (m_persist) {
- elRoot.AddAttribute("Persist", "true");
- }
-#endif // FEATURE_CLICKONCE
-
- if (m_psDefaultGrant != null) {
- SecurityElement elDefaultGrant = new SecurityElement("DefaultGrant");
- elDefaultGrant.AddChild(m_psDefaultGrant.ToXml());
- elRoot.AddChild(elDefaultGrant);
- }
- if (m_fullTrustAssemblies.Count > 0) {
- SecurityElement elFullTrustAssemblies = new SecurityElement("FullTrustAssemblies");
- foreach (StrongName fullTrustAssembly in m_fullTrustAssemblies) {
- elFullTrustAssemblies.AddChild(fullTrustAssembly.ToXml());
- }
- elRoot.AddChild(elFullTrustAssemblies);
- }
-
-#if FEATURE_CLICKONCE
- if (ExtraInfo != null) {
- elRoot.AddChild(ObjectToXml("ExtraInfo", ExtraInfo));
- }
-#endif // FEATURE_CLICKONCE
- return elRoot;
- }
-
- public void FromXml (SecurityElement element) {
- if (element == null)
- throw new ArgumentNullException("element");
- if (String.Compare(element.Tag, "ApplicationTrust", StringComparison.Ordinal) != 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidXML"));
-
-#if FEATURE_CLICKONCE
- m_appTrustedToRun = false;
- string isAppTrustedToRun = element.Attribute("TrustedToRun");
- if (isAppTrustedToRun != null && String.Compare(isAppTrustedToRun, "true", StringComparison.Ordinal) == 0) {
- m_appTrustedToRun = true;
- }
-
- m_persist = false;
- string persist = element.Attribute("Persist");
- if (persist != null && String.Compare(persist, "true", StringComparison.Ordinal) == 0) {
- m_persist = true;
- }
-
- m_appId = null;
- string fullName = element.Attribute("FullName");
- if (fullName != null && fullName.Length > 0) {
- m_appId = new ApplicationIdentity(fullName);
- }
-#endif // FEATURE_CLICKONCE
-
- m_psDefaultGrant = null;
- m_grantSetSpecialFlags = 0;
- SecurityElement elDefaultGrant = element.SearchForChildByTag("DefaultGrant");
- if (elDefaultGrant != null) {
- SecurityElement elDefaultGrantPS = elDefaultGrant.SearchForChildByTag("PolicyStatement");
- if (elDefaultGrantPS != null) {
- PolicyStatement ps = new PolicyStatement(null);
- ps.FromXml(elDefaultGrantPS);
- m_psDefaultGrant = ps;
- m_grantSetSpecialFlags = SecurityManager.GetSpecialFlags(ps.PermissionSet, null);
- }
- }
-
- List<StrongName> fullTrustAssemblies = new List<StrongName>();
- SecurityElement elFullTrustAssemblies = element.SearchForChildByTag("FullTrustAssemblies");
- if (elFullTrustAssemblies != null && elFullTrustAssemblies.InternalChildren != null) {
- IEnumerator enumerator = elFullTrustAssemblies.Children.GetEnumerator();
- while (enumerator.MoveNext()) {
- StrongName fullTrustAssembly = new StrongName();
- fullTrustAssembly.FromXml(enumerator.Current as SecurityElement);
- fullTrustAssemblies.Add(fullTrustAssembly);
- }
- }
-
- m_fullTrustAssemblies = fullTrustAssemblies.AsReadOnly();
-
-#if FEATURE_CLICKONCE
- m_elExtraInfo = element.SearchForChildByTag("ExtraInfo");
-#endif // FEATURE_CLICKONCE
- }
-
-#if FEATURE_CLICKONCE
- private static SecurityElement ObjectToXml (string tag, Object obj) {
- BCLDebug.Assert(obj != null, "You need to pass in an object");
-
- ISecurityEncodable encodableObj = obj as ISecurityEncodable;
-
- SecurityElement elObject;
- if (encodableObj != null) {
- elObject = encodableObj.ToXml();
- if (!elObject.Tag.Equals(tag))
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidXML"));
- }
- MemoryStream stream = new MemoryStream();
- BinaryFormatter formatter = new BinaryFormatter();
- formatter.Serialize(stream, obj);
- byte[] array = stream.ToArray();
-
- elObject = new SecurityElement(tag);
- elObject.AddAttribute("Data", Hex.EncodeHexString(array));
- return elObject;
- }
-
- private static Object ObjectFromXml (SecurityElement elObject) {
- BCLDebug.Assert(elObject != null, "You need to pass in a security element");
-
- if (elObject.Attribute("class") != null) {
- ISecurityEncodable encodableObj = XMLUtil.CreateCodeGroup(elObject) as ISecurityEncodable;
- if (encodableObj != null) {
- encodableObj.FromXml(elObject);
- return encodableObj;
- }
- }
-
- string objectData = elObject.Attribute("Data");
- MemoryStream stream = new MemoryStream(Hex.DecodeHexString(objectData));
- BinaryFormatter formatter = new BinaryFormatter();
- return formatter.Deserialize(stream);
- }
-#endif // FEATURE_CLICKONCE
-#endif // FEATURE_CAS_POLICY
-
-#pragma warning disable 618
- [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
-#pragma warning restore 618
- [SecuritySafeCritical]
public override EvidenceBase Clone()
{
return base.Clone();
}
}
-
-#if FEATURE_CLICKONCE
- [System.Security.SecurityCritical] // auto-generated_required
- [System.Runtime.InteropServices.ComVisible(true)]
- public sealed class ApplicationTrustCollection : ICollection {
- private const string ApplicationTrustProperty = "ApplicationTrust";
- private const string InstallerIdentifier = "{60051b8f-4f12-400a-8e50-dd05ebd438d1}";
- private static Guid ClrPropertySet = new Guid("c989bb7a-8385-4715-98cf-a741a8edb823");
-
- // The CLR specific constant install reference.
- private static object s_installReference = null;
- private static StoreApplicationReference InstallReference {
- get {
- if (s_installReference == null) {
- Interlocked.CompareExchange(ref s_installReference,
- new StoreApplicationReference(
- IsolationInterop.GUID_SXS_INSTALL_REFERENCE_SCHEME_OPAQUESTRING,
- InstallerIdentifier,
- null),
- null);
- }
- return (StoreApplicationReference) s_installReference;
- }
- }
-
- private object m_appTrusts = null;
- private ArrayList AppTrusts {
- [System.Security.SecurityCritical] // auto-generated
- get {
- if (m_appTrusts == null) {
- ArrayList appTrusts = new ArrayList();
- if (m_storeBounded) {
- RefreshStorePointer();
- // enumerate the user store and populate the collection
- StoreDeploymentMetadataEnumeration deplEnum = m_pStore.EnumInstallerDeployments(IsolationInterop.GUID_SXS_INSTALL_REFERENCE_SCHEME_OPAQUESTRING, InstallerIdentifier, ApplicationTrustProperty, null);
- foreach (IDefinitionAppId defAppId in deplEnum) {
- StoreDeploymentMetadataPropertyEnumeration metadataEnum = m_pStore.EnumInstallerDeploymentProperties(IsolationInterop.GUID_SXS_INSTALL_REFERENCE_SCHEME_OPAQUESTRING, InstallerIdentifier, ApplicationTrustProperty, defAppId);
- foreach (StoreOperationMetadataProperty appTrustProperty in metadataEnum) {
- string appTrustXml = appTrustProperty.Value;
- if (appTrustXml != null && appTrustXml.Length > 0) {
- SecurityElement seTrust = SecurityElement.FromString(appTrustXml);
- ApplicationTrust appTrust = new ApplicationTrust();
- appTrust.FromXml(seTrust);
- appTrusts.Add(appTrust);
- }
- }
- }
- }
- Interlocked.CompareExchange(ref m_appTrusts, appTrusts, null);
- }
- return m_appTrusts as ArrayList;
- }
- }
-
- private bool m_storeBounded = false;
- private Store m_pStore = null; // Component store interface pointer.
-
- // Only internal constructors are exposed.
- [System.Security.SecurityCritical] // auto-generated
- internal ApplicationTrustCollection () : this(false) {}
- internal ApplicationTrustCollection (bool storeBounded) {
- m_storeBounded = storeBounded;
- }
-
- [System.Security.SecurityCritical] // auto-generated
- private void RefreshStorePointer () {
- // Refresh store pointer.
- if (m_pStore != null)
- Marshal.ReleaseComObject(m_pStore.InternalStore);
- m_pStore = IsolationInterop.GetUserStore();
- }
-
- public int Count
- {
- [System.Security.SecuritySafeCritical] // overrides public transparent member
- get {
- return AppTrusts.Count;
- }
- }
-
- public ApplicationTrust this[int index] {
- [System.Security.SecurityCritical] // auto-generated
- get {
- return AppTrusts[index] as ApplicationTrust;
- }
- }
-
- public ApplicationTrust this[string appFullName] {
- [System.Security.SecurityCritical] // auto-generated
- get {
- ApplicationIdentity identity = new ApplicationIdentity(appFullName);
- ApplicationTrustCollection appTrusts = Find(identity, ApplicationVersionMatch.MatchExactVersion);
- if (appTrusts.Count > 0)
- return appTrusts[0];
- return null;
- }
- }
-
- [System.Security.SecurityCritical] // auto-generated
- private void CommitApplicationTrust(ApplicationIdentity applicationIdentity, string trustXml) {
- StoreOperationMetadataProperty[] properties = new StoreOperationMetadataProperty[] {
- new StoreOperationMetadataProperty(ClrPropertySet, ApplicationTrustProperty, trustXml)
- };
-
- IEnumDefinitionIdentity idenum = applicationIdentity.Identity.EnumAppPath();
- IDefinitionIdentity[] asbId = new IDefinitionIdentity[1];
- IDefinitionIdentity deplId = null;
- if (idenum.Next(1, asbId) == 1)
- deplId = asbId[0];
-
- IDefinitionAppId defAppId = IsolationInterop.AppIdAuthority.CreateDefinition();
- defAppId.SetAppPath(1, new IDefinitionIdentity[] {deplId});
- defAppId.put_Codebase(applicationIdentity.CodeBase);
-
- using (StoreTransaction storeTxn = new StoreTransaction()) {
- storeTxn.Add(new StoreOperationSetDeploymentMetadata(defAppId, InstallReference, properties));
- RefreshStorePointer();
- m_pStore.Transact(storeTxn.Operations);
- }
-
- m_appTrusts = null; // reset the app trusts in the collection.
- }
-
- [System.Security.SecurityCritical] // auto-generated
- public int Add (ApplicationTrust trust) {
- if (trust == null)
- throw new ArgumentNullException("trust");
- if (trust.ApplicationIdentity == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_ApplicationTrustShouldHaveIdentity"));
- Contract.EndContractBlock();
-
- // Add the trust decision of the application to the fusion store.
- if (m_storeBounded) {
- CommitApplicationTrust(trust.ApplicationIdentity, trust.ToXml().ToString());
- return -1;
- } else {
- return AppTrusts.Add(trust);
- }
- }
-
- [System.Security.SecurityCritical] // auto-generated
- public void AddRange (ApplicationTrust[] trusts) {
- if (trusts == null)
- throw new ArgumentNullException("trusts");
- Contract.EndContractBlock();
-
- int i=0;
- try {
- for (; i<trusts.Length; i++) {
- Add(trusts[i]);
- }
- } catch {
- for (int j=0; j<i; j++) {
- Remove(trusts[j]);
- }
- throw;
- }
- }
-
- [System.Security.SecurityCritical] // auto-generated
- public void AddRange (ApplicationTrustCollection trusts) {
- if (trusts == null)
- throw new ArgumentNullException("trusts");
- Contract.EndContractBlock();
-
- int i = 0;
- try {
- foreach (ApplicationTrust trust in trusts) {
- Add(trust);
- i++;
- }
- } catch {
- for (int j=0; j<i; j++) {
- Remove(trusts[j]);
- }
- throw;
- }
- }
-
- [System.Security.SecurityCritical] // auto-generated
- public ApplicationTrustCollection Find (ApplicationIdentity applicationIdentity, ApplicationVersionMatch versionMatch) {
- ApplicationTrustCollection collection = new ApplicationTrustCollection(false);
- foreach (ApplicationTrust trust in this) {
- if (CmsUtils.CompareIdentities(trust.ApplicationIdentity, applicationIdentity, versionMatch))
- collection.Add(trust);
- }
- return collection;
- }
-
- [System.Security.SecurityCritical] // auto-generated
- public void Remove (ApplicationIdentity applicationIdentity, ApplicationVersionMatch versionMatch) {
- ApplicationTrustCollection collection = Find(applicationIdentity, versionMatch);
- RemoveRange(collection);
- }
-
- [System.Security.SecurityCritical] // auto-generated
- public void Remove (ApplicationTrust trust) {
- if (trust == null)
- throw new ArgumentNullException("trust");
- if (trust.ApplicationIdentity == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_ApplicationTrustShouldHaveIdentity"));
- Contract.EndContractBlock();
-
- // Remove the trust decision of the application from the fusion store.
- if (m_storeBounded) {
- CommitApplicationTrust(trust.ApplicationIdentity, null);
- } else {
- AppTrusts.Remove(trust);
- }
- }
-
- [System.Security.SecurityCritical] // auto-generated
- public void RemoveRange (ApplicationTrust[] trusts) {
- if (trusts == null)
- throw new ArgumentNullException("trusts");
- Contract.EndContractBlock();
-
- int i=0;
- try {
- for (; i<trusts.Length; i++) {
- Remove(trusts[i]);
- }
- } catch {
- for (int j=0; j<i; j++) {
- Add(trusts[j]);
- }
- throw;
- }
- }
-
- [System.Security.SecurityCritical] // auto-generated
- public void RemoveRange (ApplicationTrustCollection trusts) {
- if (trusts == null)
- throw new ArgumentNullException("trusts");
- Contract.EndContractBlock();
-
- int i = 0;
- try {
- foreach (ApplicationTrust trust in trusts) {
- Remove(trust);
- i++;
- }
- } catch {
- for (int j=0; j<i; j++) {
- Add(trusts[j]);
- }
- throw;
- }
- }
-
- [System.Security.SecurityCritical] // auto-generated
- public void Clear() {
- // remove all trust decisions in the collection.
- ArrayList trusts = this.AppTrusts;
- if (m_storeBounded) {
- foreach (ApplicationTrust trust in trusts) {
- if (trust.ApplicationIdentity == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_ApplicationTrustShouldHaveIdentity"));
-
- // Remove the trust decision of the application from the fusion store.
- CommitApplicationTrust(trust.ApplicationIdentity, null);
- }
- }
- trusts.Clear();
- }
-
- public ApplicationTrustEnumerator GetEnumerator() {
- return new ApplicationTrustEnumerator(this);
- }
-
- /// <internalonly/>
- [System.Security.SecuritySafeCritical] // overrides public transparent member
- IEnumerator IEnumerable.GetEnumerator()
- {
- return new ApplicationTrustEnumerator(this);
- }
-
- /// <internalonly/>
- [System.Security.SecuritySafeCritical] // overrides public transparent member
- void ICollection.CopyTo(Array array, int index) {
- if (array == null)
- throw new ArgumentNullException("array");
- if (array.Rank != 1)
- throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
- if (index < 0 || index >= array.Length)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
- if (array.Length - index < this.Count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
- Contract.EndContractBlock();
-
- for (int i=0; i < this.Count; i++) {
- array.SetValue(this[i], index++);
- }
- }
-
- public void CopyTo (ApplicationTrust[] array, int index) {
- ((ICollection)this).CopyTo(array, index);
- }
-
- public bool IsSynchronized {
- [System.Security.SecuritySafeCritical] // overrides public transparent member
- get
- {
- return false;
- }
- }
-
- public object SyncRoot {
- [System.Security.SecuritySafeCritical] // overrides public transparent member
- get
- {
- return this;
- }
- }
- }
-
- [System.Runtime.InteropServices.ComVisible(true)]
- public sealed class ApplicationTrustEnumerator : IEnumerator {
- [System.Security.SecurityCritical] // auto-generated
- private ApplicationTrustCollection m_trusts;
- private int m_current;
-
- private ApplicationTrustEnumerator() {}
- [System.Security.SecurityCritical] // auto-generated
- internal ApplicationTrustEnumerator(ApplicationTrustCollection trusts) {
- m_trusts = trusts;
- m_current = -1;
- }
-
- public ApplicationTrust Current {
- [System.Security.SecuritySafeCritical] // auto-generated
- get {
- return m_trusts[m_current];
- }
- }
-
- /// <internalonly/>
- object IEnumerator.Current {
- [System.Security.SecuritySafeCritical] // auto-generated
- get {
- return (object) m_trusts[m_current];
- }
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public bool MoveNext() {
- if (m_current == ((int) m_trusts.Count - 1))
- return false;
- m_current++;
- return true;
- }
-
- public void Reset() {
- m_current = -1;
- }
- }
-#endif // FEATURE_CLICKONCE
}
diff --git a/src/mscorlib/src/System/Security/Policy/Evidence.cs b/src/mscorlib/src/System/Security/Policy/Evidence.cs
index 8bf8aa7e92..22479dff6c 100644
--- a/src/mscorlib/src/System/Security/Policy/Evidence.cs
+++ b/src/mscorlib/src/System/Security/Policy/Evidence.cs
@@ -2,28 +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.Security.Policy
{
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Configuration.Assemblies;
- using System.Diagnostics.Contracts;
- using System.IO;
- using System.Reflection;
- using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
- using System.Runtime.Remoting;
#if FEATURE_SERIALIZATION
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
#endif // FEATURE_SERIALIZATION
- using System.Security.Permissions;
- using System.Security.Util;
- using System.Threading;
- using Microsoft.Win32.SafeHandles;
/// <summary>
/// The Evidence class keeps track of information that can be used to make security decisions about
@@ -48,1856 +33,6 @@ namespace System.Security.Policy
#endif
[ComVisible(true)]
public sealed class Evidence
-#if FEATURE_CAS_POLICY
- : ICollection
-#endif // FEATURE_CAS_POLICY
{
-#if !FEATURE_CORECLR && FEATURE_RWLOCK
-#if FEATURE_SERIALIZATION
- [OptionalField(VersionAdded = 4)]
- private Dictionary<Type, EvidenceTypeDescriptor> m_evidence;
-
- [OptionalField(VersionAdded = 4)]
- private bool m_deserializedTargetEvidence;
-
- // These fields are only used to deserialize v2.0 serialized versions of Evidence. It will be null
- // after the seriailzation process is complete, and should not be used.
-#pragma warning disable 414
- private volatile ArrayList m_hostList;
- private volatile ArrayList m_assemblyList;
-#pragma warning restore 414
-#else // !FEATURE_SERIALIZATION
- private Dictionary<Type, EvidenceTypeDescriptor> m_evidence;
-#endif // FEATURE_SERIALIZATION
-
- [NonSerialized]
- private ReaderWriterLock m_evidenceLock;
-
- [NonSerialized]
- private uint m_version;
-
- [NonSerialized]
- private IRuntimeEvidenceFactory m_target;
-
- private bool m_locked;
-
- // If this evidence collection is a clone where we may need to backpatch to the original, this will
- // reference the collection it was cloned from. See
- // code:System.Security.Policy.Evidence#BackpatchGeneratedEvidence
- [NonSerialized]
- private WeakReference m_cloneOrigin;
-
- private static volatile Type[] s_runtimeEvidenceTypes;
-
- /// <summary>
- /// Set of actions that we could perform if we detect that we are attempting to add evidence
- /// when we already have evidence of that type stored.
- /// </summary>
- private enum DuplicateEvidenceAction
- {
- Throw, // Throw an exception
- Merge, // Create a list of all the evidence objects
- SelectNewObject // The newly added object wins
- }
-
-#if FEATURE_CAS_POLICY
- public Evidence()
- {
- m_evidence = new Dictionary<Type, EvidenceTypeDescriptor>();
- m_evidenceLock = new ReaderWriterLock();
- }
-#endif // FEATURE_CAS_POLICY
-
- /// <summary>
- /// Create a deep copy of an evidence object
- /// </summary>
- public Evidence(Evidence evidence)
- {
- m_evidence = new Dictionary<Type, EvidenceTypeDescriptor>();
-
- if (evidence != null)
- {
- using (EvidenceLockHolder lockHolder = new EvidenceLockHolder(evidence, EvidenceLockHolder.LockType.Reader))
- {
- foreach (KeyValuePair<Type, EvidenceTypeDescriptor> evidenceType in evidence.m_evidence)
- {
- EvidenceTypeDescriptor cloneDescriptor = evidenceType.Value;
- if (cloneDescriptor != null)
- {
- cloneDescriptor = cloneDescriptor.Clone();
- }
-
- m_evidence[evidenceType.Key] = cloneDescriptor;
- }
-
- m_target = evidence.m_target;
- m_locked = evidence.m_locked;
-#if FEATURE_SERIALIZATION
- m_deserializedTargetEvidence = evidence.m_deserializedTargetEvidence;
-#endif // FEATURE_SERIALIZATION
-
- // see code:System.Security.Policy.Evidence#BackpatchGeneratedEvidence
- if (evidence.Target != null)
- {
- m_cloneOrigin = new WeakReference(evidence);
- }
- }
- }
-
- // see code:System.Security.Policy.Evidence#EvidenceLock
- m_evidenceLock = new ReaderWriterLock();
- }
-
- [Obsolete("This constructor is obsolete. Please use the constructor which takes arrays of EvidenceBase instead.")]
- public Evidence(object[] hostEvidence, object[] assemblyEvidence)
- {
- m_evidence = new Dictionary<Type, EvidenceTypeDescriptor>();
-
- // This is a legacy evidence entry point, so we add through the legacy add APIs in order to get
- // proper legacy wrapping and merge behavior.
-#pragma warning disable 618
- if (hostEvidence != null)
- {
- foreach (object hostEvidenceObject in hostEvidence)
- {
- AddHost(hostEvidenceObject);
- }
- }
-
- if (assemblyEvidence != null)
- {
- foreach (object assemblyEvidenceObject in assemblyEvidence)
- {
- AddAssembly(assemblyEvidenceObject);
- }
- }
-#pragma warning restore 618
-
- // see code:System.Security.Policy.Evidence#EvidenceLock
- m_evidenceLock = new ReaderWriterLock();
- }
-
- public Evidence(EvidenceBase[] hostEvidence, EvidenceBase[] assemblyEvidence)
- {
- m_evidence = new Dictionary<Type, EvidenceTypeDescriptor>();
-
- if (hostEvidence != null)
- {
- foreach (EvidenceBase hostEvidenceObject in hostEvidence)
- {
- AddHostEvidence(hostEvidenceObject, GetEvidenceIndexType(hostEvidenceObject), DuplicateEvidenceAction.Throw);
- }
- }
-
- if (assemblyEvidence != null)
- {
- foreach (EvidenceBase assemblyEvidenceObject in assemblyEvidence)
- {
- AddAssemblyEvidence(assemblyEvidenceObject, GetEvidenceIndexType(assemblyEvidenceObject), DuplicateEvidenceAction.Throw);
- }
- }
-
- // see code:System.Security.Policy.Evidence#EvidenceLock
- m_evidenceLock = new ReaderWriterLock();
- }
-
- /// <summary>
- /// Create an empty evidence collection which will contain evidence for a specific assembly or
- /// AppDomain
- /// </summary>
- [SecuritySafeCritical]
- internal Evidence(IRuntimeEvidenceFactory target)
- {
- Contract.Assert(target != null);
-
- m_evidence = new Dictionary<Type, EvidenceTypeDescriptor>();
- m_target = target;
-
- // Setup the types of evidence that the CLR can generate for a target as keys in the dictionary
- foreach (Type runtimeEvidenceType in RuntimeEvidenceTypes)
- {
- BCLDebug.Assert(typeof(EvidenceBase).IsAssignableFrom(runtimeEvidenceType), "All runtime evidence types should be EvidenceBases");
- m_evidence[runtimeEvidenceType] = null;
- }
-
- QueryHostForPossibleEvidenceTypes();
-
- // see code:System.Security.Policy.Evidence#EvidenceLock
- m_evidenceLock = new ReaderWriterLock();
- }
-
- internal static Type[] RuntimeEvidenceTypes
- {
- get
- {
- if (s_runtimeEvidenceTypes == null)
- {
- Type[] runtimeEvidenceTypes = new Type[]
- {
-#if FEATURE_CLICKONCE
- typeof(System.Runtime.Hosting.ActivationArguments),
-#endif // FEATURE_CLICKONCE
-#if FEATURE_CAS_POLICY
- typeof(ApplicationDirectory),
-#endif // FEATURE_CAS_POLICY
- typeof(ApplicationTrust),
-#if FEATURE_CAS_POLICY
- typeof(GacInstalled),
- typeof(Hash),
- typeof(Publisher),
-#endif // FEATURE_CAS_POLICY
- typeof(Site),
- typeof(StrongName),
- typeof(Url),
- typeof(Zone)
- };
-
-#if FEATURE_CAS_POLICY
- // We only supply permission request evidence in legacy CAS mode
- if (AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
- {
-#pragma warning disable 618 // We need to generate PermissionRequestEvidence in compatibility mode
- int l = runtimeEvidenceTypes.Length;
- Array.Resize(ref runtimeEvidenceTypes, l+1);
- runtimeEvidenceTypes[l] = typeof(PermissionRequestEvidence);
-#pragma warning restore 618
- }
-#endif // FEATURE_CAS_POLICY
-
- s_runtimeEvidenceTypes = runtimeEvidenceTypes;
- }
-
- return s_runtimeEvidenceTypes;
- }
- }
-
- //
- // #EvidenceLock
- //
- // Evidence synchronization locking wrappers. In the case where the lock has not yet been created,
- // we know that we're in the process of constructing the evidence collection and therefore we can
- // act as though the evidence is locked. If there is a lock in place, then just delegate back to it.
- //
- // The nested EvidenceLockHolder and EvidenceUpgradeLockHolder utility classes can be used to wrap
- // these methods when acquiring and releasing the evidence lock.
- //
-
- // Millisecond timeout when waiting to acquire the evidence lock
- private const int LockTimeout = 5000;
-
- private bool IsReaderLockHeld
- {
- get { return m_evidenceLock == null || m_evidenceLock.IsReaderLockHeld; }
- }
-
- private bool IsWriterLockHeld
- {
- get { return m_evidenceLock == null || m_evidenceLock.IsWriterLockHeld; }
- }
-
- private void AcquireReaderLock()
- {
- Contract.Assert(m_evidenceLock == null || !IsReaderLockHeld);
-
- if (m_evidenceLock != null)
- {
- m_evidenceLock.AcquireReaderLock(LockTimeout);
- }
- }
-
- private void AcquireWriterlock()
- {
- Contract.Assert(m_evidenceLock == null || !IsWriterLockHeld);
-
- if (m_evidenceLock != null)
- {
- m_evidenceLock.AcquireWriterLock(LockTimeout);
- }
- }
-
- private void DowngradeFromWriterLock(ref LockCookie lockCookie)
- {
- Contract.Assert(IsWriterLockHeld);
- if (m_evidenceLock != null)
- {
- m_evidenceLock.DowngradeFromWriterLock(ref lockCookie);
- }
- }
-
- private LockCookie UpgradeToWriterLock()
- {
- Contract.Assert(IsReaderLockHeld);
- return m_evidenceLock != null ? m_evidenceLock.UpgradeToWriterLock(LockTimeout) : new LockCookie();
- }
-
- private void ReleaseReaderLock()
- {
- Contract.Assert(IsReaderLockHeld);
-
- if (m_evidenceLock != null)
- {
- m_evidenceLock.ReleaseReaderLock();
- }
- }
-
- private void ReleaseWriterLock()
- {
- Contract.Assert(IsWriterLockHeld);
-
- if (m_evidenceLock != null)
- {
- m_evidenceLock.ReleaseWriterLock();
- }
- }
-
- [Obsolete("This method is obsolete. Please use AddHostEvidence instead.")]
- [SecuritySafeCritical]
- public void AddHost(object id)
- {
- if (id == null)
- throw new ArgumentNullException("id");
- if (!id.GetType().IsSerializable)
- throw new ArgumentException(Environment.GetResourceString("Policy_EvidenceMustBeSerializable"), "id");
- Contract.EndContractBlock();
-
- if (m_locked)
- {
- new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand();
- }
-
- EvidenceBase evidence = WrapLegacyEvidence(id);
- Type evidenceIndex = GetEvidenceIndexType(evidence);
-
- // Whidbey allowed for multiple types of the same evidence, so if we're being called via the Whidbey
- // APIs, then allow the evidences to merge together.
- AddHostEvidence(evidence, evidenceIndex, DuplicateEvidenceAction.Merge);
- }
-
- [Obsolete("This method is obsolete. Please use AddAssemblyEvidence instead.")]
- public void AddAssembly(object id)
- {
- if (id == null)
- throw new ArgumentNullException("id");
- if (!id.GetType().IsSerializable)
- throw new ArgumentException(Environment.GetResourceString("Policy_EvidenceMustBeSerializable"), "id");
- Contract.EndContractBlock();
-
- EvidenceBase evidence = WrapLegacyEvidence(id);
- Type evidenceIndex = GetEvidenceIndexType(evidence);
-
- // Whidbey allowed for multiple types of the same evidence, so if we're being called via the Whidbey
- // APIs, then allow the evidences to merge together.
- AddAssemblyEvidence(evidence, evidenceIndex, DuplicateEvidenceAction.Merge);
- }
-
- /// <summary>
- /// Add a piece of evidence to the assembly supplied evidence list. This method will disallow adding
- /// evidence if there is already evidence of that type in the assembly list.
- /// </summary>
- [ComVisible(false)]
- public void AddAssemblyEvidence<T>(T evidence) where T : EvidenceBase
- {
- if (evidence == null)
- throw new ArgumentNullException("evidence");
- Contract.EndContractBlock();
-
- // Index the evidence under the type that the Add function was called with, unless we were given
- // a plain EvidenceBase or a wrapped legacy evidence. In that case, we need to index under a
- // more specific type.
- Type evidenceType = typeof(T);
- if (typeof(T) == typeof(EvidenceBase) || evidence is ILegacyEvidenceAdapter)
- {
- evidenceType = GetEvidenceIndexType(evidence);
- }
-
- AddAssemblyEvidence(evidence, evidenceType, DuplicateEvidenceAction.Throw);
- }
-
- private void AddAssemblyEvidence(EvidenceBase evidence, Type evidenceType, DuplicateEvidenceAction duplicateAction)
- {
- using (EvidenceLockHolder lockHolder = new EvidenceLockHolder(this, EvidenceLockHolder.LockType.Writer))
- {
- AddAssemblyEvidenceNoLock(evidence, evidenceType, duplicateAction);
- }
- }
-
- private void AddAssemblyEvidenceNoLock(EvidenceBase evidence, Type evidenceType, DuplicateEvidenceAction duplicateAction)
- {
- Contract.Assert(IsWriterLockHeld);
- Contract.Assert(evidence != null);
- Contract.Assert(evidenceType != null);
-
- // We need to make sure that any target supplied evidence is deserialized before adding to the
- // Assembly collection in order to preserve the semantics that the evidence objects supplied by
- // the target are the original versions and evidence objects added via the APIs are the duplicates.
- DeserializeTargetEvidence();
-
- EvidenceTypeDescriptor descriptor = GetEvidenceTypeDescriptor(evidenceType, true);
-
- ++m_version;
- if (descriptor.AssemblyEvidence == null)
- {
- descriptor.AssemblyEvidence = evidence;
- }
- else
- {
- descriptor.AssemblyEvidence = HandleDuplicateEvidence(descriptor.AssemblyEvidence,
- evidence,
- duplicateAction);
- }
- }
-
- /// <summary>
- /// Add a piece of evidence to the host supplied evidence list. This method will disallow adding
- /// evidence if there is already evidence of that type in the host list.
- /// </summary>
- [ComVisible(false)]
- public void AddHostEvidence<T>(T evidence) where T : EvidenceBase
- {
- if (evidence == null)
- throw new ArgumentNullException("evidence");
- Contract.EndContractBlock();
-
- // Index the evidence under the type that the Add function was called with, unless we were given
- // a plain EvidenceBase or a wrapped legacy evidence. In that case, we need to index under a
- // more specific type.
- Type evidenceType = typeof(T);
- if (typeof(T) == typeof(EvidenceBase) || evidence is ILegacyEvidenceAdapter)
- {
- evidenceType = GetEvidenceIndexType(evidence);
- }
-
- AddHostEvidence(evidence, evidenceType, DuplicateEvidenceAction.Throw);
- }
-
- [SecuritySafeCritical]
- private void AddHostEvidence(EvidenceBase evidence, Type evidenceType, DuplicateEvidenceAction duplicateAction)
- {
- Contract.Assert(evidence != null);
- Contract.Assert(evidenceType != null);
-
- if (Locked)
- {
- new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand();
- }
-
- using (EvidenceLockHolder lockHolder = new EvidenceLockHolder(this, EvidenceLockHolder.LockType.Writer))
- {
- AddHostEvidenceNoLock(evidence, evidenceType, duplicateAction);
- }
- }
-
- /// <summary>
- /// Add evidence to the host supplied evidence collection without acquiring the evidence lock or
- /// checking to make sure that the caller has permission to bypass locked evidence.
- /// </summary>
- private void AddHostEvidenceNoLock(EvidenceBase evidence, Type evidenceType, DuplicateEvidenceAction duplicateAction)
- {
- Contract.Assert(IsWriterLockHeld);
- Contract.Assert(evidence != null);
- Contract.Assert(evidenceType != null);
-
- EvidenceTypeDescriptor descriptor = GetEvidenceTypeDescriptor(evidenceType, true);
-
- ++m_version;
- if (descriptor.HostEvidence == null)
- {
- descriptor.HostEvidence = evidence;
- }
- else
- {
- descriptor.HostEvidence = HandleDuplicateEvidence(descriptor.HostEvidence,
- evidence,
- duplicateAction);
- }
- }
-
- /// <summary>
- /// Ask the host for the types of evidence that it might provide if it is asked.
- ///
- /// This should only be called when setting up the Evidence collection to interact with the
- /// host, and should not be used once that connection is established and the evidence has been
- /// made available to user code.
- /// </summary>
- [SecurityCritical]
- private void QueryHostForPossibleEvidenceTypes()
- {
-#if FEATURE_CAS_POLICY
- Contract.Assert(IsWriterLockHeld);
-
- // First check to see if we have a HostSecurityManager
- if (AppDomain.CurrentDomain.DomainManager != null)
- {
- HostSecurityManager hsm = AppDomain.CurrentDomain.DomainManager.HostSecurityManager;
- if (hsm != null)
- {
- Type[] hostSuppliedTypes = null;
-
- AppDomain targetDomain = m_target.Target as AppDomain;
- Assembly targetAssembly = m_target.Target as Assembly;
-
- //
- // If the HostSecurityManager wants to supply evidence for the type of target that we have,
- // then ask it what types of evidence it might supply.
- //
-
- if (targetAssembly != null &&
- (hsm.Flags & HostSecurityManagerOptions.HostAssemblyEvidence) == HostSecurityManagerOptions.HostAssemblyEvidence)
- {
- hostSuppliedTypes = hsm.GetHostSuppliedAssemblyEvidenceTypes(targetAssembly);
- }
- else if (targetDomain != null &&
- (hsm.Flags & HostSecurityManagerOptions.HostAppDomainEvidence) == HostSecurityManagerOptions.HostAppDomainEvidence)
- {
- hostSuppliedTypes = hsm.GetHostSuppliedAppDomainEvidenceTypes();
- }
-
- //
- // Finally, mark the descriptor for each of the types that the host can supply to indicate
- // we should ask the host to generate them if we're asked.
- //
-
- if (hostSuppliedTypes != null)
- {
- foreach (Type hostEvidenceType in hostSuppliedTypes)
- {
- EvidenceTypeDescriptor evidenceDescriptor = GetEvidenceTypeDescriptor(hostEvidenceType, true);
- evidenceDescriptor.HostCanGenerate = true;
- }
- }
- }
- }
-#endif // FEATURE_CAS_POLICY
- }
-
- internal bool IsUnmodified
- {
- get { return m_version == 0; }
- }
-
- /// <summary>
- /// Set or check to see if the evidence is locked. Locked evidence cannot have its host supplied
- /// evidence list be modified without a successful demand for ControlEvidence. Any code can lock
- /// evidence, but only code with ControlEvidence may unlock it.
- ///
- /// This lock is not the same as the synchronization lock that gates access to the evidence collection.
- /// </summary>
- public bool Locked
- {
- get
- {
- return m_locked;
- }
-
- [SecuritySafeCritical]
- set
- {
- if (!value)
- {
- new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand();
-
- m_locked = false;
- }
- else
- {
- m_locked = true;
- }
- }
- }
-
- /// <summary>
- /// Target of any delay generated evidence objects
- /// </summary>
- internal IRuntimeEvidenceFactory Target
- {
- get { return m_target; }
-
- //
- // There are two retargeting scenarios supported:
- //
- // 1. A PEFileEvidenceFactory is being upgraded to an AssemblyEvidenceFactory and we don't want
- // to throw away any already generated evidence.
- // 2. A detached evidence collection is being applied to an AppDomain and that domain has a
- // HostSecurityManager. In that case, we want to attach the target to the AppDomain to
- // allow the HostSecurityManager to get callbacks for delay generated evidence.
- //
-
- [SecurityCritical]
- set
- {
-#if FEATURE_CAS_POLICY
- Contract.Assert((m_target != null && m_target is PEFileEvidenceFactory && value != null && value is AssemblyEvidenceFactory) ||
- (m_target == null && value != null && value is AppDomainEvidenceFactory),
- "Evidence retargeting should only be from PEFile -> Assembly or detached -> AppDomain.");
-#endif // FEATURE_CAS_POLICY
-
- using (EvidenceLockHolder lockHolder = new EvidenceLockHolder(this, EvidenceLockHolder.LockType.Writer))
- {
- m_target = value;
-
- // Since we've updated what we're pointing at, we need to query the host to determine what
- // types of evidence that it can generate for this new target.
- QueryHostForPossibleEvidenceTypes();
- }
- }
- }
-
- /// <summary>
- /// Get the type that would be used to index into the evidence dictionary for this object
- /// </summary>
- private static Type GetEvidenceIndexType(EvidenceBase evidence)
- {
- Contract.Assert(evidence != null);
-
- //
- // Legacy wrapper evidence types should be indexed via the type of evidence that they're wrapping
- // so check to see if we have one of those; otherwise just return the type itself.
- //
-
- ILegacyEvidenceAdapter adapter = evidence as ILegacyEvidenceAdapter;
- return adapter == null ? evidence.GetType() : adapter.EvidenceType;
- }
-
- /// <summary>
- /// Get the type descriptor for a specific type of evidence. This method should be used instead
- /// of accessing the dictionary directly as it will handle the case where a new descriptor needs
- /// to be created.
- /// </summary>
- internal EvidenceTypeDescriptor GetEvidenceTypeDescriptor(Type evidenceType)
- {
- return GetEvidenceTypeDescriptor(evidenceType, false);
- }
-
- /// <summary>
- /// Get the type descriptor for a specific type of evidence, optionally creating a descriptor if
- /// we did not yet know about this type of evidence. This method should be used instead of
- /// accessing the dictionary directly as it will handle the case where a new descriptor needs
- /// to be created.
- /// </summary>
- private EvidenceTypeDescriptor GetEvidenceTypeDescriptor(Type evidenceType, bool addIfNotExist)
- {
- Contract.Assert(IsReaderLockHeld || IsWriterLockHeld);
- Contract.Assert(evidenceType != null);
-
- // If we don't know about the type being indexed and we don't want to add it then exit out
- EvidenceTypeDescriptor descriptor = null;
- if (!m_evidence.TryGetValue(evidenceType, out descriptor) && !addIfNotExist)
- {
- return null;
- }
-
- // If we haven't yet created a descriptor for this type then create one now
- if (descriptor == null)
- {
- descriptor = new EvidenceTypeDescriptor();
-#if _DEBUG
- descriptor.SetEvidenceType(evidenceType);
-#endif // _DEBUG
-
- bool upgradedLock = false;
- LockCookie upgradeCookie = new LockCookie();
- try
- {
- if (!IsWriterLockHeld)
- {
- upgradeCookie = UpgradeToWriterLock();
- upgradedLock = true;
- }
-
- m_evidence[evidenceType] = descriptor;
- }
- finally
- {
- if (upgradedLock)
- DowngradeFromWriterLock(ref upgradeCookie);
- }
- }
-
- return descriptor;
- }
-
- /// <summary>
- /// This method is called if a piece of evidence is added but another piece of evidence of the same
- /// type already existed. We have different strategies depending on compatibility concerns of the
- /// calling code.
- /// </summary>
- private static EvidenceBase HandleDuplicateEvidence(EvidenceBase original,
- EvidenceBase duplicate,
- DuplicateEvidenceAction action)
- {
- Contract.Assert(original != null);
- Contract.Assert(duplicate != null);
- Contract.Assert(original.GetType() == duplicate.GetType() || original.GetType() == typeof(LegacyEvidenceList));
-
- switch (action)
- {
- // Throw - duplicate evidence is not allowed (Arrowhead behavior), so throw an exception
- case DuplicateEvidenceAction.Throw:
- throw new InvalidOperationException(Environment.GetResourceString("Policy_DuplicateEvidence", duplicate.GetType().FullName));
-
- // SelectNewObject - MergeWithNoDuplicates behavior - the duplicate object wins
- case DuplicateEvidenceAction.SelectNewObject:
- return duplicate;
-
- // Merge - compat behavior. Merge the old and new evidence into a list so that both may exist
- case DuplicateEvidenceAction.Merge:
-
- LegacyEvidenceList list = original as LegacyEvidenceList;
- if (list == null)
- {
- list = new LegacyEvidenceList();
- list.Add(original);
- }
-
- list.Add(duplicate);
- return list;
-
- default:
- BCLDebug.Assert(false, "Uknown DuplicateEvidenceAction");
- return null;
- }
- }
-
- /// <summary>
- /// Wrap evidence we recieved through a legacy API to ensure that it is stored in an EvidenceBase
- /// </summary>
- private static EvidenceBase WrapLegacyEvidence(object evidence)
- {
- Contract.Assert(evidence != null);
-
- EvidenceBase wrappedEvidence = evidence as EvidenceBase;
- if (wrappedEvidence == null)
- {
- wrappedEvidence = new LegacyEvidenceWrapper(evidence);
- }
-
- return wrappedEvidence;
- }
-
- /// <summary>
- /// Upwrap evidence stored in a legacy adapter.
- ///
- /// This is only necessary for the case where multiple objects derived from EvidenceBase is
- /// are added via the legacy APIs and are then retrieved via GetHostEvidence. This may occur if
- /// a legacy application adds CLR supplied evidence types via the old APIs and a new application
- /// consumes the resulting evidence.
- /// </summary>
- private static object UnwrapEvidence(EvidenceBase evidence)
- {
- ILegacyEvidenceAdapter adapter = evidence as ILegacyEvidenceAdapter;
- return adapter == null ? evidence : adapter.EvidenceObject;
- }
-
- /// <summary>
- /// Merge two evidence collections together. Note that this will cause all of the lazily
- /// generated evidence for the input collection to be generated, as well as causing any lazily
- /// generated evidence that both collections share to be generated in the target.
- /// </summary>
- [SecuritySafeCritical]
- public void Merge(Evidence evidence)
- {
- if (evidence == null)
- {
- return;
- }
-
- using (EvidenceLockHolder lockHolder = new EvidenceLockHolder(this, EvidenceLockHolder.LockType.Writer))
- {
- bool checkedLock = false;
- IEnumerator hostEnumerator = evidence.GetHostEnumerator();
- while (hostEnumerator.MoveNext())
- {
- if (Locked && !checkedLock)
- {
- new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand();
- checkedLock = true;
- }
-
- // If we could potentially have evidence of the type about to be merged into our host list,
- // then make sure that we generate that evidence before merging. This will prevent the
- // newly merged evidence from masking the value that we would have generated on our own.
- Type hostEvidenceType = hostEnumerator.Current.GetType();
- if (m_evidence.ContainsKey(hostEvidenceType))
- {
- GetHostEvidenceNoLock(hostEvidenceType);
- }
-
- EvidenceBase hostEvidence = WrapLegacyEvidence(hostEnumerator.Current);
- AddHostEvidenceNoLock(hostEvidence,
- GetEvidenceIndexType(hostEvidence),
- DuplicateEvidenceAction.Merge);
- }
-
- // Add each piece of assembly evidence. We don't need to deserialize our copy of the
- // evidence because AddAssemblyEvidenceNoLock will do this for us.
- IEnumerator assemblyEnumerator = evidence.GetAssemblyEnumerator();
- while (assemblyEnumerator.MoveNext())
- {
- EvidenceBase assemblyEvidence = WrapLegacyEvidence(assemblyEnumerator.Current);
- AddAssemblyEvidenceNoLock(assemblyEvidence,
- GetEvidenceIndexType(assemblyEvidence),
- DuplicateEvidenceAction.Merge);
- }
- }
- }
-
- /// <summary>
- /// Same as merge, except only one instance of any one evidence type is allowed. When duplicates
- /// are found, the evidence in the input argument will have priority. Note this will force the
- /// entire input evidence to be generated, and does not check for locked evidence
- /// </summary>
- internal void MergeWithNoDuplicates(Evidence evidence)
- {
- if (evidence == null)
- {
- return;
- }
-
- using (EvidenceLockHolder lockHolder = new EvidenceLockHolder(this, EvidenceLockHolder.LockType.Writer))
- {
- IEnumerator hostEnumerator = evidence.GetHostEnumerator();
- while (hostEnumerator.MoveNext())
- {
- EvidenceBase hostEvidence = WrapLegacyEvidence(hostEnumerator.Current);
- AddHostEvidenceNoLock(hostEvidence,
- GetEvidenceIndexType(hostEvidence),
- DuplicateEvidenceAction.SelectNewObject);
- }
-
- IEnumerator assemblyEnumerator = evidence.GetAssemblyEnumerator();
- while (assemblyEnumerator.MoveNext())
- {
- EvidenceBase assemblyEvidence = WrapLegacyEvidence(assemblyEnumerator.Current);
- AddAssemblyEvidenceNoLock(assemblyEvidence,
- GetEvidenceIndexType(assemblyEvidence),
- DuplicateEvidenceAction.SelectNewObject);
- }
- }
- }
-
-#if FEATURE_SERIALIZATION
- /// <summary>
- /// Do a full serialization of the evidence, which requires that we generate all of the evidence
- /// we can and disconnect ourselves from the host and source assembly.
- /// </summary>
- [ComVisible(false)]
- [OnSerializing]
- [SecurityCritical]
- [PermissionSet(SecurityAction.Assert, Unrestricted = true)]
- private void OnSerializing(StreamingContext context)
- {
- using (EvidenceLockHolder lockHolder = new EvidenceLockHolder(this, EvidenceLockHolder.LockType.Reader))
- {
- // First, force all of the host evidence that might be lazily generated to be created
- foreach (Type evidenceType in new List<Type>(m_evidence.Keys))
- {
- GetHostEvidenceNoLock(evidenceType);
- }
-
- // Also ensure that all serialized assembly evidence has been created
- DeserializeTargetEvidence();
- }
-
- // Fill in legacy evidence lists. We can't guarantee thread-safety here using locks
- // because we can't put a lock in the serialization code that will read the lists.
- // The best we can do is prevent another thread from seeing a half-populated list.
- // Therefore, we assign the lists after we've populated them fully (and declare them volatile.)
- ArrayList hostList = new ArrayList();
- IEnumerator hostEnumerator = GetHostEnumerator();
- while (hostEnumerator.MoveNext())
- {
- hostList.Add(hostEnumerator.Current);
- }
- m_hostList = hostList;
-
- ArrayList assemblyList = new ArrayList();
- IEnumerator assemblyEnumerator = GetAssemblyEnumerator();
- while (assemblyEnumerator.MoveNext())
- {
- assemblyList.Add(assemblyEnumerator.Current);
- }
- m_assemblyList = assemblyList;
- }
-
- /// <summary>
- /// Finish deserializing legacy evidence
- /// </summary>
- [ComVisible(false)]
- [OnDeserialized]
- [SecurityCritical]
- private void OnDeserialized(StreamingContext context)
- {
- // Look at host and assembly evidence lists only if we serialized using Whidbey.
- if (m_evidence == null)
- {
- m_evidence = new Dictionary<Type, EvidenceTypeDescriptor>();
-
- // Whidbey evidence may need to be wrapped or added to a LegacyEvidenceList, so we go
- // through the legacy APIs to add them.
-#pragma warning disable 618
- if (m_hostList != null)
- {
- foreach (object evidenceObject in m_hostList)
- {
- if (evidenceObject != null)
- {
- AddHost(evidenceObject);
- }
- }
-
- m_hostList = null;
- }
-
- if (m_assemblyList != null)
- {
- foreach (object evidenceObject in m_assemblyList)
- {
- if (evidenceObject != null)
- {
- AddAssembly(evidenceObject);
- }
- }
-
- m_assemblyList = null;
- }
-#pragma warning restore 618
- }
-
- // see code:System.Security.Policy.Evidence#EvidenceLock
- m_evidenceLock = new ReaderWriterLock();
- }
-#endif // FEATURE_SERIALIZATION
-
- /// <summary>
- /// Load any serialized evidence out of the target assembly into our evidence collection.
- ///
- /// We allow entry to this method with only a reader lock held, since most of the time we will
- /// not need to write to the evidence dictionary. If we haven't yet deserialized the target
- /// evidence, then we will upgrade to a writer lock at that point.
- /// </summary>
- private void DeserializeTargetEvidence()
- {
-#if FEATURE_SERIALIZATION
- Contract.Assert(IsReaderLockHeld || IsWriterLockHeld);
-
- if (m_target != null && !m_deserializedTargetEvidence)
- {
- bool upgradedLock = false;
- LockCookie lockCookie = new LockCookie();
- try
- {
- if (!IsWriterLockHeld)
- {
- lockCookie = UpgradeToWriterLock();
- upgradedLock = true;
- }
-
- // Set this to true here because AddAssemblyEvidenceNoLock will attempt to reenter this
- // method creating possible infinite recursion.
- m_deserializedTargetEvidence = true;
-
- foreach (EvidenceBase targetEvidence in m_target.GetFactorySuppliedEvidence())
- {
- AddAssemblyEvidenceNoLock(targetEvidence, GetEvidenceIndexType(targetEvidence), DuplicateEvidenceAction.Throw);
- }
- }
- finally
- {
- if (upgradedLock)
- DowngradeFromWriterLock(ref lockCookie);
- }
- }
-#endif // FEATURE_SERIALIZATION
- }
-
-#if FEATURE_SERIALIZATION
- /// <summary>
- /// Serialize out raw evidence objects which have already been generated, ignoring any evidence
- /// which might be present but has not yet been created for this assembly.
- ///
- /// This is used for indexing into the security policy cache, since we know that once policy is
- /// resolved, the relevent membership conditions will have checked for any applicable evidence
- /// and therefore after poliyc resolution this evidence collection will contain any evidence
- /// objects necessary to arrive at its grant set.
- /// </summary>
- [SecurityCritical]
- internal byte[] RawSerialize()
- {
- try
- {
- using (EvidenceLockHolder lockHolder = new EvidenceLockHolder(this, EvidenceLockHolder.LockType.Reader))
- {
- // Filter out any evidence which is not yet generated
- Dictionary<Type, EvidenceBase> generatedEvidence = new Dictionary<Type, EvidenceBase>();
- foreach (KeyValuePair<Type, EvidenceTypeDescriptor> evidenceType in m_evidence)
- {
- if (evidenceType.Value != null && evidenceType.Value.HostEvidence != null)
- {
- generatedEvidence[evidenceType.Key] = evidenceType.Value.HostEvidence;
- }
- }
-
- using (MemoryStream serializationStream = new MemoryStream())
- {
- BinaryFormatter formatter = new BinaryFormatter();
- formatter.Serialize(serializationStream, generatedEvidence);
- return serializationStream.ToArray();
- }
- }
- }
- catch (SecurityException)
- {
- // We're running in a context where it's not safe to serialize the evidence out. In this case
- // Simply decline to cache the result of the policy evaluation
- return null;
- }
- }
-#endif // FEATURE_SERIALIZATION
-
- //
- // ICollection implementation. All ICollection interface members are potentially much more
- // expensive in Arrowhead then they were downlevel. They should not be used if the standard Get and
- // Add methods will work instead.
- //
-
- [Obsolete("Evidence should not be treated as an ICollection. Please use the GetHostEnumerator and GetAssemblyEnumerator methods rather than using CopyTo.")]
- public void CopyTo(Array array, int index)
- {
- if (array == null)
- throw new ArgumentNullException("array");
- if (index < 0 || index > array.Length - Count)
- throw new ArgumentOutOfRangeException("index");
- Contract.EndContractBlock();
-
- int currentIndex = index;
-
- IEnumerator hostEnumerator = GetHostEnumerator();
- while (hostEnumerator.MoveNext())
- {
- array.SetValue(hostEnumerator.Current, currentIndex);
- ++currentIndex;
- }
-
- IEnumerator assemblyEnumerator = GetAssemblyEnumerator();
- while (assemblyEnumerator.MoveNext())
- {
- array.SetValue(assemblyEnumerator.Current, currentIndex);
- ++currentIndex;
- }
- }
-
- public IEnumerator GetHostEnumerator()
- {
- using (EvidenceLockHolder lockHolder = new EvidenceLockHolder(this, EvidenceLockHolder.LockType.Reader))
- {
- return new EvidenceEnumerator(this, EvidenceEnumerator.Category.Host);
- }
- }
-
- public IEnumerator GetAssemblyEnumerator()
- {
- using (EvidenceLockHolder lockHolder = new EvidenceLockHolder(this, EvidenceLockHolder.LockType.Reader))
- {
- DeserializeTargetEvidence();
- return new EvidenceEnumerator(this, EvidenceEnumerator.Category.Assembly);
- }
- }
-
- /// <summary>
- /// Get an enumerator that can iterate over the raw evidence objects stored for the assembly
- /// </summary>
- internal RawEvidenceEnumerator GetRawAssemblyEvidenceEnumerator()
- {
- Contract.Assert(IsReaderLockHeld);
- DeserializeTargetEvidence();
- return new RawEvidenceEnumerator(this, new List<Type>(m_evidence.Keys), false);
- }
-
- /// <summary>
- /// Get an enumerator that can iterate over the raw evidence objects stored for the host
- /// </summary>
- /// <returns></returns>
- internal RawEvidenceEnumerator GetRawHostEvidenceEnumerator()
- {
- Contract.Assert(IsReaderLockHeld);
- return new RawEvidenceEnumerator(this, new List<Type>(m_evidence.Keys), true);
- }
-
- [Obsolete("GetEnumerator is obsolete. Please use GetAssemblyEnumerator and GetHostEnumerator instead.")]
- public IEnumerator GetEnumerator()
- {
- using (EvidenceLockHolder lockHolder = new EvidenceLockHolder(this, EvidenceLockHolder.LockType.Reader))
- {
- return new EvidenceEnumerator(this, EvidenceEnumerator.Category.Host | EvidenceEnumerator.Category.Assembly);
- }
- }
-
- /// <summary>
- /// Get a specific type of assembly supplied evidence
- /// </summary>
- [ComVisible(false)]
- public T GetAssemblyEvidence<T>() where T : EvidenceBase
- {
- return UnwrapEvidence(GetAssemblyEvidence(typeof(T))) as T;
- }
-
- internal EvidenceBase GetAssemblyEvidence(Type type)
- {
- Contract.Assert(type != null);
-
- using (EvidenceLockHolder lockHolder = new EvidenceLockHolder(this, EvidenceLockHolder.LockType.Reader))
- {
- return GetAssemblyEvidenceNoLock(type);
- }
- }
-
- private EvidenceBase GetAssemblyEvidenceNoLock(Type type)
- {
- Contract.Assert(IsReaderLockHeld || IsWriterLockHeld);
- Contract.Assert(type != null);
-
- DeserializeTargetEvidence();
- EvidenceTypeDescriptor descriptor = GetEvidenceTypeDescriptor(type);
- if (descriptor != null)
- {
- return descriptor.AssemblyEvidence;
- }
-
- return null;
- }
-
- /// <summary>
- /// Get a specific type of host supplied evidence
- /// </summary>
- [ComVisible(false)]
- public T GetHostEvidence<T>() where T : EvidenceBase
- {
- return UnwrapEvidence(GetHostEvidence(typeof(T))) as T;
- }
-
- /// <summary>
- /// Get a specific type of evidence from the host which may not have been verified yet. If the
- /// evidence was not verified, then don't mark it as being used yet.
- /// </summary>
- internal T GetDelayEvaluatedHostEvidence<T>() where T : EvidenceBase, IDelayEvaluatedEvidence
- {
- return UnwrapEvidence(GetHostEvidence(typeof(T), false)) as T;
- }
-
- internal EvidenceBase GetHostEvidence(Type type)
- {
- Contract.Assert(type != null);
-
- return GetHostEvidence(type, true);
- }
-
- [SecuritySafeCritical]
- private EvidenceBase GetHostEvidence(Type type, bool markDelayEvaluatedEvidenceUsed)
- {
- Contract.Assert(type != null);
-
- using (EvidenceLockHolder lockHolder = new EvidenceLockHolder(this, EvidenceLockHolder.LockType.Reader))
- {
- EvidenceBase evidence = GetHostEvidenceNoLock(type);
-
- if (markDelayEvaluatedEvidenceUsed)
- {
- IDelayEvaluatedEvidence delayEvidence = evidence as IDelayEvaluatedEvidence;
- if (delayEvidence != null)
- {
- delayEvidence.MarkUsed();
- }
- }
-
- return evidence;
- }
- }
-
- /// <summary>
- /// Get host supplied evidence from the collection
- ///
- /// We attempt to find host evdience in the following order:
- ///
- /// 1. Already generated or explicitly supplied evidence
- /// 2. Evidence supplied by the CLR host
- /// 3. Evidence supplied by the CLR itself
- /// </summary>
- [SecurityCritical]
- private EvidenceBase GetHostEvidenceNoLock(Type type)
- {
- Contract.Assert(IsReaderLockHeld || IsWriterLockHeld);
- Contract.Assert(type != null);
-
- EvidenceTypeDescriptor descriptor = GetEvidenceTypeDescriptor(type);
-
- // If the evidence descriptor doesn't exist for the host evidence type than the evidence doesn't
- // exist and neither the host nor the runtime can produce it.
- if (descriptor == null)
- {
- return null;
- }
-
- // If the evidence has already been generated or if it was explicitly provided then return that
- if (descriptor.HostEvidence != null)
- {
- return descriptor.HostEvidence;
- }
-
- // If we have a target, then the host or the runtime might be able to generate this type of
- // evidence on demand.
- if (m_target != null && !descriptor.Generated)
- {
- using (EvidenceUpgradeLockHolder lockHolder = new EvidenceUpgradeLockHolder(this))
- {
- // Make sure that we don't attempt to generate this type of evidencea again if we fail to
- // generate it now.
- descriptor.Generated = true;
-
- EvidenceBase generatedEvidence = GenerateHostEvidence(type, descriptor.HostCanGenerate);
- if (generatedEvidence != null)
- {
- descriptor.HostEvidence = generatedEvidence;
-
- //
- // #BackpatchGeneratedEvidence
- //
- // If we were cloned from another evidence collection propigate any generated evidence
- // back to the original collection. Since Assembly and AppDomain both clone their
- // evidence before giving it to users, this prevents us from having to regenerate
- // evidence types on each clone that gets created. Note that we do not want to do this
- // backpatching if the origin already has evidence of this type or if it has had
- // this type of evidence removed from its collection.
- //
-
- Evidence cloneOrigin = m_cloneOrigin != null ? m_cloneOrigin.Target as Evidence : null;
- if (cloneOrigin != null)
- {
- BCLDebug.Assert(cloneOrigin.Target != null && cloneOrigin.Target == Target,
- "Attempt to backpatch evidence to a collection with a different target.");
-
- using (EvidenceLockHolder cloneLockHolder = new EvidenceLockHolder(cloneOrigin, EvidenceLockHolder.LockType.Writer))
- {
- EvidenceTypeDescriptor cloneDescriptor = cloneOrigin.GetEvidenceTypeDescriptor(type);
- if (cloneDescriptor != null && cloneDescriptor.HostEvidence == null)
- {
- cloneDescriptor.HostEvidence = generatedEvidence.Clone() as EvidenceBase;
- }
- }
- }
-
- }
-
- return generatedEvidence;
- }
- }
-
- // The evidence could not be generated and was not found
- return null;
- }
-
- /// <summary>
- /// Attempt to generate host evidence on demand via calls to the runtime host or the evidence facotry
- /// </summary>
- [SecurityCritical]
- private EvidenceBase GenerateHostEvidence(Type type, bool hostCanGenerate)
- {
- Contract.Assert(type != null);
- Contract.Assert(IsWriterLockHeld);
-
-#if FEATURE_CAS_POLICY
- // First let the host generate the evidence if it can.
- if (hostCanGenerate)
- {
- AppDomain targetDomain = m_target.Target as AppDomain;
- Assembly targetAssembly = m_target.Target as Assembly;
-
- EvidenceBase hostEvidence = null;
- if (targetDomain != null)
- {
- hostEvidence = AppDomain.CurrentDomain.HostSecurityManager.GenerateAppDomainEvidence(type);
- }
- else if (targetAssembly != null)
- {
- hostEvidence = AppDomain.CurrentDomain.HostSecurityManager.GenerateAssemblyEvidence(type, targetAssembly);
- }
-
- // If the host generated the evidence, verify that it generated the evidence we expected
- // and use that.
- if (hostEvidence != null)
- {
- if (!type.IsAssignableFrom(hostEvidence.GetType()))
- {
- string hostType = AppDomain.CurrentDomain.HostSecurityManager.GetType().FullName;
- string recievedType = hostEvidence.GetType().FullName;
- string requestedType = type.FullName;
-
- throw new InvalidOperationException(Environment.GetResourceString("Policy_IncorrectHostEvidence", hostType, recievedType, requestedType));
- }
-
- return hostEvidence;
- }
- }
-#endif // FEATURE_CAS_POLICY
-
- // Finally, check to see if the CLR can generate the evidence
- return m_target.GenerateEvidence(type);
- }
-
- [Obsolete("Evidence should not be treated as an ICollection. Please use GetHostEnumerator and GetAssemblyEnumerator to iterate over the evidence to collect a count.")]
- public int Count
- {
- get
- {
- int count = 0;
-
- IEnumerator hostEvidence = GetHostEnumerator();
- while (hostEvidence.MoveNext())
- {
- ++count;
- }
-
- IEnumerator assemblyEvidence = GetAssemblyEnumerator();
- while (assemblyEvidence.MoveNext())
- {
- ++count;
- }
-
- return count;
- }
- }
-
- /// <summary>
- /// Get the number of pieces of evidence which are currently generated, without causing any
- /// lazily generated evidence to be created.
- /// </summary>
- [ComVisible(false)]
- internal int RawCount
- {
- get
- {
- int count = 0;
-
- using (EvidenceLockHolder lockHolder = new EvidenceLockHolder(this, EvidenceLockHolder.LockType.Reader))
- {
- foreach (Type evidenceType in new List<Type>(m_evidence.Keys))
- {
- EvidenceTypeDescriptor descriptor = GetEvidenceTypeDescriptor(evidenceType);
-
- if (descriptor != null)
- {
- if (descriptor.AssemblyEvidence != null)
- {
- ++count;
- }
- if (descriptor.HostEvidence != null)
- {
- ++count;
- }
- }
- }
- }
-
- return count;
- }
- }
-
- public Object SyncRoot
- {
- get { return this; }
- }
-
- public bool IsSynchronized
- {
- get { return true; }
- }
-
- public bool IsReadOnly
- {
- get { return false; }
- }
-
-#if FEATURE_CAS_POLICY
- [ComVisible(false)]
- public Evidence Clone()
- {
- return new Evidence(this);
- }
-#endif // FEATURE_CAS_POLICY
-
- [ComVisible(false)]
- [SecuritySafeCritical]
- public void Clear()
- {
- if (Locked)
- {
- new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand();
- }
-
- using (EvidenceLockHolder lockHolder = new EvidenceLockHolder(this, EvidenceLockHolder.LockType.Writer))
- {
- ++m_version;
- m_evidence.Clear();
- }
- }
-
- [ComVisible(false)]
- [SecuritySafeCritical]
- public void RemoveType(Type t)
- {
- if (t == null)
- throw new ArgumentNullException("t");
- Contract.EndContractBlock();
-
- using (EvidenceLockHolder lockHolder = new EvidenceLockHolder(this, EvidenceLockHolder.LockType.Writer))
- {
- EvidenceTypeDescriptor descriptor = GetEvidenceTypeDescriptor(t);
- if (descriptor != null)
- {
- ++m_version;
-
- // If we've locked this evidence collection, we need to do the lock check in the case that
- // either we have host evidence, or that the host might generate it, since removing the
- // evidence will cause us to bypass the host's ability to ever generate the evidence.
- if (Locked && (descriptor.HostEvidence != null || descriptor.HostCanGenerate))
- {
- new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand();
- }
-
- m_evidence.Remove(t);
- }
- }
- }
-
- /// <summary>
- /// Mark all of the already generated evidence in the collection as having been used during a
- /// policy evaluation.
- /// </summary>
- internal void MarkAllEvidenceAsUsed()
- {
- using (EvidenceLockHolder lockHolder = new EvidenceLockHolder(this, EvidenceLockHolder.LockType.Reader))
- {
- foreach (KeyValuePair<Type, EvidenceTypeDescriptor> evidenceType in m_evidence)
- {
- if (evidenceType.Value != null)
- {
- IDelayEvaluatedEvidence hostEvidence = evidenceType.Value.HostEvidence as IDelayEvaluatedEvidence;
- if (hostEvidence != null)
- {
- hostEvidence.MarkUsed();
- }
-
- IDelayEvaluatedEvidence assemblyEvidence = evidenceType.Value.AssemblyEvidence as IDelayEvaluatedEvidence;
- if (assemblyEvidence != null)
- {
- assemblyEvidence.MarkUsed();
- }
- }
- }
- }
- }
-
-#if FEATURE_CAS_POLICY
- /// <summary>
- /// Determine if delay evaluated strong name evidence is contained in this collection, and if so
- /// if it was used during policy evaluation.
- ///
- /// This method is called from the VM in SecurityPolicy::WasStrongNameEvidenceUsed
- /// This class should be used as an adapter layer to allow the public facing EvidenceEnumerator to
- /// be able to get the evidence values out of an Evidence class. It is tightly coupled with the
- /// internal data structures holding the evidence objects in the Evidence class.
- /// </summary>
- private bool WasStrongNameEvidenceUsed()
- {
- using (EvidenceLockHolder lockHolder = new EvidenceLockHolder(this, EvidenceLockHolder.LockType.Reader))
- {
- EvidenceTypeDescriptor snTypeDescriptor = GetEvidenceTypeDescriptor(typeof(StrongName));
- if (snTypeDescriptor != null)
- {
- IDelayEvaluatedEvidence snEvidence = snTypeDescriptor.HostEvidence as IDelayEvaluatedEvidence;
- return snEvidence != null && snEvidence.WasUsed;
- }
-
- return false;
- }
- }
-#endif // FEATURE_CAS_POLICY
-
- /// <summary>
- /// Utility class to wrap acquiring a lock onto the evidence collection
- /// </summary>
- private class EvidenceLockHolder : IDisposable
- {
- private Evidence m_target;
- private LockType m_lockType;
-
- public enum LockType
- {
- Reader,
- Writer
- }
-
- public EvidenceLockHolder(Evidence target, LockType lockType)
- {
- Contract.Assert(target != null);
- Contract.Assert(lockType == LockType.Reader || lockType == LockType.Writer);
-
- m_target = target;
- m_lockType = lockType;
-
- if (m_lockType == LockType.Reader)
- {
- m_target.AcquireReaderLock();
- }
- else
- {
- m_target.AcquireWriterlock();
- }
- }
-
- public void Dispose()
- {
- if (m_lockType == LockType.Reader && m_target.IsReaderLockHeld)
- {
- m_target.ReleaseReaderLock();
- }
- else if (m_lockType == LockType.Writer && m_target.IsWriterLockHeld)
- {
- m_target.ReleaseWriterLock();
- }
- }
- }
-
- /// <summary>
- /// Utility class to wrap upgrading an acquired reader lock to a writer lock and then
- /// downgrading it back to a reader lock.
- /// </summary>
- private class EvidenceUpgradeLockHolder : IDisposable
- {
- private Evidence m_target;
- private LockCookie m_cookie;
-
- public EvidenceUpgradeLockHolder(Evidence target)
- {
- Contract.Assert(target != null);
-
- m_target = target;
- m_cookie = m_target.UpgradeToWriterLock();
- }
-
- public void Dispose()
- {
- if (m_target.IsWriterLockHeld)
- {
- m_target.DowngradeFromWriterLock(ref m_cookie);
- }
- }
- }
-
- /// <summary>
- /// Enumerator that iterates directly over the evidence type map, returning back the evidence objects
- /// that are contained in it. This enumerator will generate any lazy evaluated evidence it finds,
- /// but it does not attempt to deal with legacy evidence adapters.
- ///
- /// This class should be used as an adapter layer to allow the public facing EvidenceEnumerator to
- /// be able to get the evidence values out of an Evidence class. It is tightly coupled with the
- /// internal data structures holding the evidence objects in the Evidence class.
- /// </summary>
- internal sealed class RawEvidenceEnumerator : IEnumerator<EvidenceBase>
- {
- private Evidence m_evidence;
- private bool m_hostEnumerator; // true to enumerate host evidence, false to enumerate assembly evidence
- private uint m_evidenceVersion;
-
- private Type[] m_evidenceTypes;
- private int m_typeIndex;
- private EvidenceBase m_currentEvidence;
-
- private static volatile List<Type> s_expensiveEvidence;
-
- public RawEvidenceEnumerator(Evidence evidence, IEnumerable<Type> evidenceTypes, bool hostEnumerator)
- {
- Contract.Assert(evidence != null);
- Contract.Assert(evidenceTypes != null);
-
- m_evidence = evidence;
- m_hostEnumerator = hostEnumerator;
- m_evidenceTypes = GenerateEvidenceTypes(evidence, evidenceTypes, hostEnumerator);
- m_evidenceVersion = evidence.m_version;
-
- Reset();
- }
-
- public EvidenceBase Current
- {
- get
- {
- if (m_evidence.m_version != m_evidenceVersion)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumFailedVersion"));
-
- return m_currentEvidence;
- }
- }
-
- object IEnumerator.Current
- {
- get
- {
- if (m_evidence.m_version != m_evidenceVersion)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumFailedVersion"));
-
- return m_currentEvidence;
- }
- }
-
- /// <summary>
- /// List of types of evidence that we would like to avoid generating if possible
- /// </summary>
- private static List<Type> ExpensiveEvidence
- {
- get
- {
- if (s_expensiveEvidence == null)
- {
- List<Type> expensiveEvidence = new List<Type>();
-#if FEATURE_CAS_POLICY
- expensiveEvidence.Add(typeof(Hash));
- expensiveEvidence.Add(typeof(Publisher));
-#endif // FEATURE_CAS_POLICY
- s_expensiveEvidence = expensiveEvidence;
-
-#if _DEBUG
- List<Type> runtimeTypes = new List<Type>(Evidence.RuntimeEvidenceTypes);
- foreach (Type expensiveType in s_expensiveEvidence)
- {
- BCLDebug.Assert(runtimeTypes.Contains(expensiveType),
- "Evidence type not generated by the runtime found in expensive evidence type list");
- }
-#endif // _DEBUG
- }
-
- return s_expensiveEvidence;
- }
- }
-
- public void Dispose()
- {
- return;
- }
-
- /// <summary>
- /// Generate the array of types of evidence that could have values for
- /// </summary>
- private static Type[] GenerateEvidenceTypes(Evidence evidence,
- IEnumerable<Type> evidenceTypes,
- bool hostEvidence)
- {
- Contract.Assert(evidence != null);
- Contract.Assert(evidenceTypes != null);
-
- //
- // Sort the evidence being generated into three categories, which we enumerate in order:
- // 1. Evidence which has already been generated
- // 2. Evidence which is relatively inexpensive to generate
- // 3. Evidence which is expensive to generate.
- //
- // This allows us to be as efficient as possible in case the user of the enumerator stops the
- // enumeration before we step up to the next more expensive category.
- //
-
- List<Type> alreadyGeneratedList = new List<Type>();
- List<Type> inexpensiveList = new List<Type>();
- List<Type> expensiveList = new List<Type>(ExpensiveEvidence.Count);
-
- // Iterate over the evidence types classifying into the three groups. We need to copy the list
- // here since GetEvidenceTypeDescriptor will potentially update the evidence dictionary, which
- // evidenceTypes iterates over.
- foreach (Type evidenceType in evidenceTypes)
- {
- EvidenceTypeDescriptor descriptor = evidence.GetEvidenceTypeDescriptor(evidenceType);
- BCLDebug.Assert(descriptor != null, "descriptor != null");
-
- bool alreadyGenerated = (hostEvidence && descriptor.HostEvidence != null) ||
- (!hostEvidence && descriptor.AssemblyEvidence != null);
-
- if (alreadyGenerated)
- {
- alreadyGeneratedList.Add(evidenceType);
- }
- else if (ExpensiveEvidence.Contains(evidenceType))
- {
- expensiveList.Add(evidenceType);
- }
- else
- {
- inexpensiveList.Add(evidenceType);
- }
- }
-
- Type[] enumerationTypes = new Type[alreadyGeneratedList.Count + inexpensiveList.Count + expensiveList.Count];
- alreadyGeneratedList.CopyTo(enumerationTypes, 0);
- inexpensiveList.CopyTo(enumerationTypes, alreadyGeneratedList.Count);
- expensiveList.CopyTo(enumerationTypes, alreadyGeneratedList.Count + inexpensiveList.Count);
-
- return enumerationTypes;
- }
-
- [SecuritySafeCritical]
- public bool MoveNext()
- {
- using (EvidenceLockHolder lockHolder = new EvidenceLockHolder(m_evidence, EvidenceLockHolder.LockType.Reader))
- {
- if (m_evidence.m_version != m_evidenceVersion)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumFailedVersion"));
-
- m_currentEvidence = null;
-
- // Iterate over the possible types of evidence that we could have until we find one that
- // really exists, or we run out of posibilities.
- do
- {
- ++m_typeIndex;
-
- if (m_typeIndex < m_evidenceTypes.Length)
- {
- if (m_hostEnumerator)
- {
- m_currentEvidence = m_evidence.GetHostEvidenceNoLock(m_evidenceTypes[m_typeIndex]);
- }
- else
- {
- m_currentEvidence = m_evidence.GetAssemblyEvidenceNoLock(m_evidenceTypes[m_typeIndex]);
- }
- }
- }
- while (m_typeIndex < m_evidenceTypes.Length && m_currentEvidence == null);
- }
-
- return m_currentEvidence != null;
- }
-
- public void Reset()
- {
- if (m_evidence.m_version != m_evidenceVersion)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumFailedVersion"));
-
- m_typeIndex = -1;
- m_currentEvidence = null;
- }
- }
-
- private sealed class EvidenceEnumerator : IEnumerator
- {
- private Evidence m_evidence;
- private Category m_category;
- private Stack m_enumerators;
-
- private object m_currentEvidence;
-
- [Flags]
- internal enum Category
- {
- Host = 0x1, // Enumerate only host supplied evidence
- Assembly = 0x2 // Enumerate only assembly supplied evidence
- }
-
- internal EvidenceEnumerator(Evidence evidence, Category category)
- {
- Contract.Assert(evidence != null);
- Contract.Assert(evidence.IsReaderLockHeld);
-
- m_evidence = evidence;
- m_category = category;
- ResetNoLock();
- }
-
- public bool MoveNext()
- {
- IEnumerator currentEnumerator = CurrentEnumerator;
-
- // No more enumerators means we can't go any further
- if (currentEnumerator == null)
- {
- m_currentEvidence = null;
- return false;
- }
-
- // See if the current enumerator can continue
- if (currentEnumerator.MoveNext())
- {
- //
- // If we've found an adapter for legacy evidence, we need to unwrap it for it to be the
- // current enumerator's value. For wrapped evidence, this is a simple unwrap, for a list of
- // evidence, we need to make that the current enumerator and get its first value.
- //
-
- LegacyEvidenceWrapper legacyWrapper = currentEnumerator.Current as LegacyEvidenceWrapper;
- LegacyEvidenceList legacyList = currentEnumerator.Current as LegacyEvidenceList;
-
- if (legacyWrapper != null)
- {
- m_currentEvidence = legacyWrapper.EvidenceObject;
- }
- else if (legacyList != null)
- {
- IEnumerator legacyListEnumerator = legacyList.GetEnumerator();
- m_enumerators.Push(legacyListEnumerator);
- MoveNext();
- }
- else
- {
- m_currentEvidence = currentEnumerator.Current;
- }
-
- BCLDebug.Assert(m_currentEvidence != null, "m_currentEvidence != null");
- return true;
- }
- else
- {
- // If we've reached the end of the current enumerator, move to the next one and try again
- m_enumerators.Pop();
- return MoveNext();
- }
- }
-
- public object Current
- {
- get { return m_currentEvidence; }
- }
-
- private IEnumerator CurrentEnumerator
- {
- get
- {
- return m_enumerators.Count > 0 ? m_enumerators.Peek() as IEnumerator : null;
- }
- }
-
- public void Reset()
- {
- using (EvidenceLockHolder lockHolder = new EvidenceLockHolder(m_evidence, EvidenceLockHolder.LockType.Reader))
- {
- ResetNoLock();
- }
- }
-
- private void ResetNoLock()
- {
- Contract.Assert(m_evidence != null);
- Contract.Assert(m_evidence.IsReaderLockHeld);
-
- m_currentEvidence = null;
- m_enumerators = new Stack();
-
- if ((m_category & Category.Host) == Category.Host)
- {
- m_enumerators.Push(m_evidence.GetRawHostEvidenceEnumerator());
- }
- if ((m_category & Category.Assembly) == Category.Assembly)
- {
- m_enumerators.Push(m_evidence.GetRawAssemblyEvidenceEnumerator());
- }
- }
- }
-#endif //!FEATURE_CORECLR && FEATURE_RWLOCK
}
}
diff --git a/src/mscorlib/src/System/Security/Policy/EvidenceBase.cs b/src/mscorlib/src/System/Security/Policy/EvidenceBase.cs
index f142ebea2a..7fef1ded3c 100644
--- a/src/mscorlib/src/System/Security/Policy/EvidenceBase.cs
+++ b/src/mscorlib/src/System/Security/Policy/EvidenceBase.cs
@@ -7,6 +7,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.IO;
using System.Runtime.InteropServices;
@@ -22,9 +23,6 @@ namespace System.Security.Policy
/// </summary>
[ComVisible(true)]
[Serializable]
-#pragma warning disable 618
- [PermissionSet(SecurityAction.InheritanceDemand, Unrestricted = true)]
-#pragma warning restore 618
public abstract class EvidenceBase
{
protected EvidenceBase()
@@ -44,11 +42,6 @@ namespace System.Security.Policy
/// Since legacy evidence objects would be cloned by being serialized, the default implementation
/// of EvidenceBase will do the same.
/// </remarks>
-#pragma warning disable 618
- [SecurityPermission(SecurityAction.Assert, SerializationFormatter = true)]
- [PermissionSet(SecurityAction.InheritanceDemand, Unrestricted = true)]
-#pragma warning restore 618
- [SecuritySafeCritical]
public virtual EvidenceBase Clone()
{
#if FEATURE_SERIALIZATION
@@ -86,9 +79,9 @@ namespace System.Security.Policy
internal LegacyEvidenceWrapper(object legacyEvidence)
{
- Contract.Assert(legacyEvidence != null);
- Contract.Assert(legacyEvidence.GetType() != typeof(EvidenceBase), "Attempt to wrap an EvidenceBase in a LegacyEvidenceWrapper");
- Contract.Assert(legacyEvidence.GetType().IsSerializable, "legacyEvidence.GetType().IsSerializable");
+ Debug.Assert(legacyEvidence != null);
+ Debug.Assert(legacyEvidence.GetType() != typeof(EvidenceBase), "Attempt to wrap an EvidenceBase in a LegacyEvidenceWrapper");
+ Debug.Assert(legacyEvidence.GetType().IsSerializable, "legacyEvidence.GetType().IsSerializable");
m_legacyEvidence = legacyEvidence;
}
@@ -113,10 +106,6 @@ namespace System.Security.Policy
return m_legacyEvidence.GetHashCode();
}
-#pragma warning disable 618
- [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
-#pragma warning restore 618
- [SecuritySafeCritical]
public override EvidenceBase Clone()
{
return base.Clone();
@@ -153,7 +142,7 @@ namespace System.Security.Policy
{
get
{
- Contract.Assert(m_legacyEvidenceList.Count > 0, "No items in LegacyEvidenceList, cannot tell what type they are");
+ Debug.Assert(m_legacyEvidenceList.Count > 0, "No items in LegacyEvidenceList, cannot tell what type they are");
ILegacyEvidenceAdapter adapter = m_legacyEvidenceList[0] as ILegacyEvidenceAdapter;
return adapter == null ? m_legacyEvidenceList[0].GetType() : adapter.EvidenceType;
@@ -162,10 +151,10 @@ namespace System.Security.Policy
public void Add(EvidenceBase evidence)
{
- Contract.Assert(evidence != null);
- Contract.Assert(m_legacyEvidenceList.Count == 0 || EvidenceType == evidence.GetType() || (evidence is LegacyEvidenceWrapper && (evidence as LegacyEvidenceWrapper).EvidenceType == EvidenceType),
+ Debug.Assert(evidence != null);
+ Debug.Assert(m_legacyEvidenceList.Count == 0 || EvidenceType == evidence.GetType() || (evidence is LegacyEvidenceWrapper && (evidence as LegacyEvidenceWrapper).EvidenceType == EvidenceType),
"LegacyEvidenceList must be homogeonous");
- Contract.Assert(evidence.GetType() != typeof(LegacyEvidenceList),
+ Debug.Assert(evidence.GetType() != typeof(LegacyEvidenceList),
"Attempt to add a legacy evidence list to another legacy evidence list");
m_legacyEvidenceList.Add(evidence);
@@ -181,10 +170,6 @@ namespace System.Security.Policy
return m_legacyEvidenceList.GetEnumerator();
}
-#pragma warning disable 618
- [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
-#pragma warning restore 618
- [SecuritySafeCritical]
public override EvidenceBase Clone()
{
return base.Clone();
diff --git a/src/mscorlib/src/System/Security/Policy/EvidenceTypeDescriptor.cs b/src/mscorlib/src/System/Security/Policy/EvidenceTypeDescriptor.cs
index bccf39218b..8deb145102 100644
--- a/src/mscorlib/src/System/Security/Policy/EvidenceTypeDescriptor.cs
+++ b/src/mscorlib/src/System/Security/Policy/EvidenceTypeDescriptor.cs
@@ -41,7 +41,7 @@ namespace System.Security.Policy
/// </summary>
private EvidenceTypeDescriptor(EvidenceTypeDescriptor descriptor)
{
- Contract.Assert(descriptor != null);
+ Debug.Assert(descriptor != null);
m_hostCanGenerate = descriptor.m_hostCanGenerate;
@@ -68,9 +68,9 @@ namespace System.Security.Policy
set
{
- Contract.Assert(value != null);
+ Debug.Assert(value != null);
#if _DEBUG
- Contract.Assert(CheckEvidenceType(value), "Incorrect type of AssemblyEvidence set");
+ Debug.Assert(CheckEvidenceType(value), "Incorrect type of AssemblyEvidence set");
#endif
m_assemblyEvidence = value;
}
@@ -85,7 +85,7 @@ namespace System.Security.Policy
set
{
- Contract.Assert(value, "Attempt to clear the Generated flag");
+ Debug.Assert(value, "Attempt to clear the Generated flag");
m_generated = value;
}
}
@@ -99,7 +99,7 @@ namespace System.Security.Policy
set
{
- Contract.Assert(value, "Attempt to clear HostCanGenerate flag");
+ Debug.Assert(value, "Attempt to clear HostCanGenerate flag");
m_hostCanGenerate = value;
}
}
@@ -113,9 +113,9 @@ namespace System.Security.Policy
set
{
- Contract.Assert(value != null);
+ Debug.Assert(value != null);
#if _DEBUG
- Contract.Assert(CheckEvidenceType(value), "Incorrect type of HostEvidence set");
+ Debug.Assert(CheckEvidenceType(value), "Incorrect type of HostEvidence set");
#endif
m_hostEvidence = value;
}
@@ -127,7 +127,7 @@ namespace System.Security.Policy
/// </summary>
private bool CheckEvidenceType(EvidenceBase evidence)
{
- Contract.Assert(evidence != null);
+ Debug.Assert(evidence != null);
ILegacyEvidenceAdapter legacyAdapter = evidence as ILegacyEvidenceAdapter;
Type storedType = legacyAdapter == null ? evidence.GetType() : legacyAdapter.EvidenceType;
@@ -150,8 +150,8 @@ namespace System.Security.Policy
/// </summary>
internal void SetEvidenceType(Type evidenceType)
{
- Contract.Assert(evidenceType != null);
- Contract.Assert(m_evidenceType == null, "Attempt to reset evidence type");
+ Debug.Assert(evidenceType != null);
+ Debug.Assert(m_evidenceType == null, "Attempt to reset evidence type");
m_evidenceType = evidenceType;
}
diff --git a/src/mscorlib/src/System/Security/Policy/IDelayEvaluatedEvidence.cs b/src/mscorlib/src/System/Security/Policy/IDelayEvaluatedEvidence.cs
index 5bd36485db..8f8c07c9e4 100644
--- a/src/mscorlib/src/System/Security/Policy/IDelayEvaluatedEvidence.cs
+++ b/src/mscorlib/src/System/Security/Policy/IDelayEvaluatedEvidence.cs
@@ -18,7 +18,6 @@ namespace System.Security.Policy {
/// </summary>
bool IsVerified
{
- [System.Security.SecurityCritical]
get;
}
diff --git a/src/mscorlib/src/System/Security/Policy/PolicyStatement.cs b/src/mscorlib/src/System/Security/Policy/PolicyStatement.cs
index 72c07d1246..9b58ece9f1 100644
--- a/src/mscorlib/src/System/Security/Policy/PolicyStatement.cs
+++ b/src/mscorlib/src/System/Security/Policy/PolicyStatement.cs
@@ -35,14 +35,6 @@ namespace System.Security.Policy {
// The PermissionSet associated with this policy
internal PermissionSet m_permSet;
-#if FEATURE_CAS_POLICY
- // Evidence which was not verified but which was required to generate this policy statement.
- // This is not serialized, since once we serialize we lose the ability to verify the evidence,
- // meaning that restoring this state is meaningless.
- [NonSerialized]
- private List<IDelayEvaluatedEvidence> m_dependentEvidence;
-#endif
-
// The bitfield of inheritance properties associated with this policy
internal PolicyStatementAttribute m_attributes;
@@ -144,20 +136,13 @@ namespace System.Security.Policy {
}
}
}
-
+
public PolicyStatement Copy()
{
- PolicyStatement copy = new PolicyStatement(m_permSet, Attributes, true); // The PolicyStatement .ctor will copy the permission set
-#if FEATURE_CAS_POLICY
- if (HasDependentEvidence)
- {
- copy.m_dependentEvidence = new List<IDelayEvaluatedEvidence>(m_dependentEvidence);
- }
-#endif
-
- return copy;
+ // The PolicyStatement .ctor will copy the permission set
+ return new PolicyStatement(m_permSet, Attributes, true);
}
-
+
public String AttributeString
{
get
@@ -199,44 +184,6 @@ namespace System.Security.Policy {
return (flag & (int)m_attributes) != 0;
}
-#if FEATURE_CAS_POLICY
- /// <summary>
- /// Gets all of the delay evaluated evidence which needs to be verified before this policy can
- /// be used.
- /// </summary>
- internal IEnumerable<IDelayEvaluatedEvidence> DependentEvidence
- {
- get
- {
- BCLDebug.Assert(HasDependentEvidence, "HasDependentEvidence");
- return m_dependentEvidence.AsReadOnly();
- }
- }
-
- /// <summary>
- /// Determine if this policy dependent upon the evaluation of any delay evaluated evidence
- /// </summary>
- internal bool HasDependentEvidence
- {
- get { return m_dependentEvidence != null && m_dependentEvidence.Count > 0; }
- }
-
- /// <summary>
- /// Add evidence which this policy statement is depending upon being verified to be valid.
- /// </summary>
- internal void AddDependentEvidence(IDelayEvaluatedEvidence dependentEvidence)
- {
- BCLDebug.Assert(dependentEvidence != null, "dependentEvidence != null");
-
- if (m_dependentEvidence == null)
- {
- m_dependentEvidence = new List<IDelayEvaluatedEvidence>();
- }
-
- m_dependentEvidence.Add(dependentEvidence);
- }
-#endif
-
/// <summary>
/// Union a child policy statement into this policy statement
/// </summary>
@@ -249,27 +196,6 @@ namespace System.Security.Policy {
throw new PolicyException(Environment.GetResourceString( "Policy_MultipleExclusive" ));
}
-#if FEATURE_CAS_POLICY
- // If our code group generated a grant set based upon unverified evidence, or it generated a grant
- // set strictly less than that of a child group based upon unverified evidence, we need to keep
- // track of any unverified evidence our child group has.
- if (childPolicy.HasDependentEvidence)
- {
- bool childEvidenceNeedsVerification = m_permSet.IsSubsetOf(childPolicy.GetPermissionSetNoCopy()) &&
- !childPolicy.GetPermissionSetNoCopy().IsSubsetOf(m_permSet);
-
- if (HasDependentEvidence || childEvidenceNeedsVerification)
- {
- if (m_dependentEvidence == null)
- {
- m_dependentEvidence = new List<IDelayEvaluatedEvidence>();
- }
-
- m_dependentEvidence.AddRange(childPolicy.DependentEvidence);
- }
- }
-#endif
-
// We need to merge together our grant set and attributes. The result of this merge is
// dependent upon if we're merging a child marked exclusive or not. If the child is not
// exclusive, we need to union in its grant set and or in its attributes. However, if the child
@@ -287,226 +213,6 @@ namespace System.Security.Policy {
}
}
-#if FEATURE_CAS_POLICY
-
- public SecurityElement ToXml()
- {
- return ToXml( null );
- }
-
- public void FromXml( SecurityElement et )
- {
- FromXml( et, null );
- }
-
- public SecurityElement ToXml( PolicyLevel level )
- {
- return ToXml( level, false );
- }
-
- internal SecurityElement ToXml( PolicyLevel level, bool useInternal )
- {
- SecurityElement e = new SecurityElement( "PolicyStatement" );
- e.AddAttribute( "version", "1" );
- if (m_attributes != PolicyStatementAttribute.Nothing)
- e.AddAttribute( "Attributes", XMLUtil.BitFieldEnumToString( typeof( PolicyStatementAttribute ), m_attributes ) );
-
- lock (this)
- {
- if (m_permSet != null)
- {
- if (m_permSet is NamedPermissionSet)
- {
- // If the named permission set exists in the parent level of this
- // policy struct, then just save the name of the permission set.
- // Otherwise, serialize it like normal.
-
- NamedPermissionSet namedPermSet = (NamedPermissionSet)m_permSet;
- if (level != null && level.GetNamedPermissionSet( namedPermSet.Name ) != null)
- {
- e.AddAttribute( "PermissionSetName", namedPermSet.Name );
- }
- else
- {
- if (useInternal)
- e.AddChild( namedPermSet.InternalToXml() );
- else
- e.AddChild( namedPermSet.ToXml() );
- }
- }
- else
- {
- if (useInternal)
- e.AddChild( m_permSet.InternalToXml() );
- else
- e.AddChild( m_permSet.ToXml() );
- }
- }
- }
-
- return e;
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public void FromXml( SecurityElement et, PolicyLevel level )
- {
- FromXml( et, level, false );
- }
-
- [System.Security.SecurityCritical] // auto-generated
- internal void FromXml( SecurityElement et, PolicyLevel level, bool allowInternalOnly )
- {
- if (et == null)
- throw new ArgumentNullException( "et" );
-
- if (!et.Tag.Equals( "PolicyStatement" ))
- throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Argument_InvalidXMLElement" ), "PolicyStatement", this.GetType().FullName ) );
- Contract.EndContractBlock();
-
- m_attributes = (PolicyStatementAttribute) 0;
-
- String strAttributes = et.Attribute( "Attributes" );
-
- if (strAttributes != null)
- m_attributes = (PolicyStatementAttribute)Enum.Parse( typeof( PolicyStatementAttribute ), strAttributes );
-
- lock (this)
- {
- m_permSet = null;
-
- if (level != null)
- {
- String permSetName = et.Attribute( "PermissionSetName" );
-
- if (permSetName != null)
- {
- m_permSet = level.GetNamedPermissionSetInternal( permSetName );
-
- if (m_permSet == null)
- m_permSet = new PermissionSet( PermissionState.None );
- }
- }
-
-
- if (m_permSet == null)
- {
- // There is no provided level, it is not a named permission set, or
- // the named permission set doesn't exist in the provided level,
- // so just create the class through reflection and decode normally.
-
- SecurityElement e = et.SearchForChildByTag( "PermissionSet" );
-
- if (e != null)
- {
- String className = e.Attribute( "class" );
-
- if (className != null && (className.Equals( "NamedPermissionSet" ) ||
- className.Equals( "System.Security.NamedPermissionSet" )))
- m_permSet = new NamedPermissionSet( "DefaultName", PermissionState.None );
- else
- m_permSet = new PermissionSet( PermissionState.None );
-
- try
- {
- m_permSet.FromXml( e, allowInternalOnly, true );
- }
- catch
- {
- // ignore any exceptions from the decode process.
- // Note: we go ahead and use the permission set anyway. This should be safe since
- // the decode process should never give permission beyond what a proper decode would have
- // given.
- }
- }
- else
- {
- throw new ArgumentException( Environment.GetResourceString( "Argument_InvalidXML" ) );
- }
- }
-
- if (m_permSet == null)
- m_permSet = new PermissionSet( PermissionState.None );
- }
- }
-
-
- [System.Security.SecurityCritical] // auto-generated
- internal void FromXml( SecurityDocument doc, int position, PolicyLevel level, bool allowInternalOnly )
- {
- if (doc == null)
- throw new ArgumentNullException( "doc" );
- Contract.EndContractBlock();
-
- if (!doc.GetTagForElement( position ).Equals( "PolicyStatement" ))
- throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Argument_InvalidXMLElement" ), "PolicyStatement", this.GetType().FullName ) );
-
- m_attributes = (PolicyStatementAttribute) 0;
-
- String strAttributes = doc.GetAttributeForElement( position, "Attributes" );
-
- if (strAttributes != null)
- m_attributes = (PolicyStatementAttribute)Enum.Parse( typeof( PolicyStatementAttribute ), strAttributes );
-
- lock (this)
- {
- m_permSet = null;
-
- if (level != null)
- {
- String permSetName = doc.GetAttributeForElement( position, "PermissionSetName" );
-
- if (permSetName != null)
- {
- m_permSet = level.GetNamedPermissionSetInternal( permSetName );
-
- if (m_permSet == null)
- m_permSet = new PermissionSet( PermissionState.None );
- }
- }
-
-
- if (m_permSet == null)
- {
- // There is no provided level, it is not a named permission set, or
- // the named permission set doesn't exist in the provided level,
- // so just create the class through reflection and decode normally.
-
- ArrayList childPositions = doc.GetChildrenPositionForElement( position );
- int positionPermissionSet = -1;
-
- for (int i = 0; i < childPositions.Count; ++i)
- {
- if (doc.GetTagForElement( (int)childPositions[i] ).Equals( "PermissionSet" ))
- {
- positionPermissionSet = (int)childPositions[i];
- }
- }
-
- if (positionPermissionSet != -1)
- {
- String className = doc.GetAttributeForElement( positionPermissionSet, "class" );
-
- if (className != null && (className.Equals( "NamedPermissionSet" ) ||
- className.Equals( "System.Security.NamedPermissionSet" )))
- m_permSet = new NamedPermissionSet( "DefaultName", PermissionState.None );
- else
- m_permSet = new PermissionSet( PermissionState.None );
-
- m_permSet.FromXml( doc, positionPermissionSet, allowInternalOnly );
- }
- else
- {
- throw new ArgumentException( Environment.GetResourceString( "Argument_InvalidXML" ) );
- }
- }
-
- if (m_permSet == null)
- m_permSet = new PermissionSet( PermissionState.None );
- }
- }
-#endif // FEATURE_CAS_POLICY
-
-
[System.Runtime.InteropServices.ComVisible(false)]
public override bool Equals( Object obj )
{
diff --git a/src/mscorlib/src/System/Security/Policy/Site.cs b/src/mscorlib/src/System/Security/Policy/Site.cs
index e7c6cd3d83..14a95e1666 100644
--- a/src/mscorlib/src/System/Security/Policy/Site.cs
+++ b/src/mscorlib/src/System/Security/Policy/Site.cs
@@ -10,6 +10,7 @@
//
using System;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Globalization;
using System.Security.Permissions;
@@ -26,7 +27,7 @@ namespace System.Security.Policy
public Site(String name)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
Contract.EndContractBlock();
m_name = new SiteString( name );
@@ -34,7 +35,7 @@ namespace System.Security.Policy
private Site(SiteString name)
{
- Contract.Assert(name != null);
+ Debug.Assert(name != null);
m_name = name;
}
@@ -94,30 +95,6 @@ namespace System.Security.Policy
return Clone();
}
-#if FEATURE_CAS_POLICY
- internal SecurityElement ToXml()
- {
- SecurityElement elem = new SecurityElement( "System.Security.Policy.Site" );
- // If you hit this assert then most likely you are trying to change the name of this class.
- // This is ok as long as you change the hard coded string above and change the assert below.
- Contract.Assert( this.GetType().FullName.Equals( "System.Security.Policy.Site" ), "Class name changed!" );
-
- elem.AddAttribute( "version", "1" );
-
- if(m_name != null)
- elem.AddChild( new SecurityElement( "Name", m_name.ToString() ) );
-
- return elem;
- }
-#endif // FEATURE_CAS_POLICY
-
-#if FEATURE_CAS_POLICY
- public override String ToString()
- {
- return ToXml().ToString();
- }
-#endif // FEATURE_CAS_POLICY
-
// INormalizeForIsolatedStorage is not implemented for startup perf
// equivalent to INormalizeForIsolatedStorage.Normalize()
internal Object Normalize()
diff --git a/src/mscorlib/src/System/Security/Policy/StrongName.cs b/src/mscorlib/src/System/Security/Policy/StrongName.cs
index c49f2b0674..999b478ba7 100644
--- a/src/mscorlib/src/System/Security/Policy/StrongName.cs
+++ b/src/mscorlib/src/System/Security/Policy/StrongName.cs
@@ -42,20 +42,20 @@ namespace System.Security.Policy {
internal StrongName(StrongNamePublicKeyBlob blob, String name, Version version, Assembly assembly)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (String.IsNullOrEmpty(name))
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyStrongName"));
if (blob == null)
- throw new ArgumentNullException("blob");
+ throw new ArgumentNullException(nameof(blob));
if (version == null)
- throw new ArgumentNullException("version");
+ throw new ArgumentNullException(nameof(version));
Contract.EndContractBlock();
RuntimeAssembly rtAssembly = assembly as RuntimeAssembly;
if (assembly != null && rtAssembly == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeAssembly"), "assembly");
+ throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeAssembly"), nameof(assembly));
m_publicKeyBlob = blob;
m_name = name;
@@ -89,14 +89,9 @@ namespace System.Security.Policy {
bool IDelayEvaluatedEvidence.IsVerified
{
- [System.Security.SecurityCritical] // auto-generated
get
{
-#if FEATURE_CAS_POLICY
- return m_assembly != null ? m_assembly.IsStrongNameVerified : true;
-#else // !FEATURE_CAS_POLICY
return true;
-#endif // FEATURE_CAS_POLICY
}
}
@@ -133,52 +128,6 @@ namespace System.Security.Policy {
return Clone();
}
-#if FEATURE_CAS_POLICY
- internal SecurityElement ToXml()
- {
- SecurityElement root = new SecurityElement( "StrongName" );
- root.AddAttribute( "version", "1" );
-
- if (m_publicKeyBlob != null)
- root.AddAttribute( "Key", System.Security.Util.Hex.EncodeHexString( m_publicKeyBlob.PublicKey ) );
-
- if (m_name != null)
- root.AddAttribute( "Name", m_name );
-
- if (m_version != null)
- root.AddAttribute( "Version", m_version.ToString() );
-
- return root;
- }
-
- internal void FromXml (SecurityElement element)
- {
- if (element == null)
- throw new ArgumentNullException("element");
- if (String.Compare(element.Tag, "StrongName", StringComparison.Ordinal) != 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidXML"));
- Contract.EndContractBlock();
-
- m_publicKeyBlob = null;
- m_version = null;
-
- string key = element.Attribute("Key");
- if (key != null)
- m_publicKeyBlob = new StrongNamePublicKeyBlob(System.Security.Util.Hex.DecodeHexString(key));
-
- m_name = element.Attribute("Name");
-
- string version = element.Attribute("Version");
- if (version != null)
- m_version = new Version(version);
- }
-
- public override String ToString()
- {
- return ToXml().ToString();
- }
-#endif // FEATURE_CAS_POLICY
-
public override bool Equals( Object o )
{
StrongName that = (o as StrongName);
diff --git a/src/mscorlib/src/System/Security/Policy/URL.cs b/src/mscorlib/src/System/Security/Policy/URL.cs
index d3ad4f8724..3541124ac6 100644
--- a/src/mscorlib/src/System/Security/Policy/URL.cs
+++ b/src/mscorlib/src/System/Security/Policy/URL.cs
@@ -14,6 +14,7 @@ namespace System.Security.Policy {
using System.Security.Util;
using UrlIdentityPermission = System.Security.Permissions.UrlIdentityPermission;
using System.Runtime.Serialization;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
[Serializable]
@@ -25,7 +26,7 @@ namespace System.Security.Policy {
internal Url( String name, bool parsed )
{
if (name == null)
- throw new ArgumentNullException( "name" );
+ throw new ArgumentNullException( nameof(name) );
Contract.EndContractBlock();
m_url = new URLString( name, parsed );
@@ -34,7 +35,7 @@ namespace System.Security.Policy {
public Url( String name )
{
if (name == null)
- throw new ArgumentNullException( "name" );
+ throw new ArgumentNullException( nameof(name) );
Contract.EndContractBlock();
m_url = new URLString( name );
@@ -42,7 +43,7 @@ namespace System.Security.Policy {
private Url(Url url)
{
- Contract.Assert(url != null);
+ Debug.Assert(url != null);
m_url = url.m_url;
}
@@ -87,28 +88,6 @@ namespace System.Security.Policy {
return Clone();
}
-#if FEATURE_CAS_POLICY
- internal SecurityElement ToXml()
- {
- SecurityElement root = new SecurityElement( "System.Security.Policy.Url" );
- // If you hit this assert then most likely you are trying to change the name of this class.
- // This is ok as long as you change the hard coded string above and change the assert below.
- Contract.Assert( this.GetType().FullName.Equals( "System.Security.Policy.Url" ), "Class name changed!" );
-
- root.AddAttribute( "version", "1" );
-
- if (m_url != null)
- root.AddChild( new SecurityElement( "Url", m_url.ToString() ) );
-
- return root;
- }
-
- public override String ToString()
- {
- return ToXml().ToString();
- }
-#endif // FEATURE_CAS_POLICY
-
// INormalizeForIsolatedStorage is not implemented for startup perf
// equivalent to INormalizeForIsolatedStorage.Normalize()
internal Object Normalize()
diff --git a/src/mscorlib/src/System/Security/Policy/Zone.cs b/src/mscorlib/src/System/Security/Policy/Zone.cs
index c999abe340..a9f5d84aeb 100644
--- a/src/mscorlib/src/System/Security/Policy/Zone.cs
+++ b/src/mscorlib/src/System/Security/Policy/Zone.cs
@@ -9,23 +9,21 @@
// Zone is an IIdentity representing Internet/Intranet/MyComputer etc.
//
-namespace System.Security.Policy {
+namespace System.Security.Policy
+{
using System.Security.Util;
using ZoneIdentityPermission = System.Security.Permissions.ZoneIdentityPermission;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Runtime.Serialization;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class Zone : EvidenceBase, IIdentityPermissionFactory
{
-#if FEATURE_CAS_POLICY
- [OptionalField(VersionAdded = 2)]
- private String m_url;
-#endif // FEATURE_CAS_POLICY
private SecurityZone m_zone;
private static readonly String[] s_names =
@@ -42,36 +40,10 @@ namespace System.Security.Policy {
private Zone(Zone zone)
{
- Contract.Assert(zone != null);
-
-#if FEATURE_CAS_POLICY
- m_url = zone.m_url;
-#endif // FEATURE_CAS_POLICY
+ Debug.Assert(zone != null);
m_zone = zone.m_zone;
}
-#if FEATURE_CAS_POLICY
- private Zone(String url)
- {
- m_url = url;
- m_zone = SecurityZone.NoZone;
- }
-
- public static Zone CreateFromUrl( String url )
- {
- if (url == null)
- throw new ArgumentNullException( "url" );
- Contract.EndContractBlock();
-
- return new Zone( url );
- }
-
- [System.Security.SecurityCritical] // auto-generated
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private extern static SecurityZone _CreateFromUrl( String url );
-#endif // FEATURE_CAS_POLICY
-
public IPermission CreateIdentityPermission( Evidence evidence )
{
return new ZoneIdentityPermission( SecurityZone );
@@ -79,14 +51,8 @@ namespace System.Security.Policy {
public SecurityZone SecurityZone
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
-#if FEATURE_CAS_POLICY
- if (m_url != null)
- m_zone = _CreateFromUrl( m_url );
-#endif // FEATURE_CAS_POLICY
-
return m_zone;
}
}
@@ -117,30 +83,6 @@ namespace System.Security.Policy {
return Clone();
}
-#if FEATURE_CAS_POLICY
- internal SecurityElement ToXml()
- {
- SecurityElement elem = new SecurityElement( "System.Security.Policy.Zone" );
- // If you hit this assert then most likely you are trying to change the name of this class.
- // This is ok as long as you change the hard coded string above and change the assert below.
- Contract.Assert( this.GetType().FullName.Equals( "System.Security.Policy.Zone" ), "Class name changed!" );
-
- elem.AddAttribute( "version", "1" );
- if (SecurityZone != SecurityZone.NoZone)
- elem.AddChild( new SecurityElement( "Zone", s_names[(int)SecurityZone] ) );
- else
- elem.AddChild( new SecurityElement( "Zone", s_names[s_names.Length-1] ) );
- return elem;
- }
-#endif // FEATURE_CAS_POLICY
-
-#if FEATURE_CAS_POLICY
- public override String ToString()
- {
- return ToXml().ToString();
- }
-#endif // FEATURE_CAS_POLICY
-
// INormalizeForIsolatedStorage is not implemented for startup perf
// equivalent to INormalizeForIsolatedStorage.Normalize()
internal Object Normalize()
diff --git a/src/mscorlib/src/System/Security/Principal/TokenImpersonationLevel.cs b/src/mscorlib/src/System/Security/Principal/TokenImpersonationLevel.cs
index fa77ac50f9..9eec46f774 100644
--- a/src/mscorlib/src/System/Security/Principal/TokenImpersonationLevel.cs
+++ b/src/mscorlib/src/System/Security/Principal/TokenImpersonationLevel.cs
@@ -2,15 +2,10 @@
// The .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.Principal
{
-#if !FEATURE_CORECLR
- [Serializable]
- [System.Runtime.InteropServices.ComVisible(true)]
-#endif
- public enum TokenImpersonationLevel {
+ public enum TokenImpersonationLevel
+ {
None = 0,
Anonymous = 1,
Identification = 2,
diff --git a/src/mscorlib/src/System/Security/SafeSecurityHandles.cs b/src/mscorlib/src/System/Security/SafeSecurityHandles.cs
index ea9cd4be0f..9a84164460 100644
--- a/src/mscorlib/src/System/Security/SafeSecurityHandles.cs
+++ b/src/mscorlib/src/System/Security/SafeSecurityHandles.cs
@@ -11,7 +11,6 @@ namespace Microsoft.Win32.SafeHandles {
// Introduce this handle to replace internal SafeTokenHandle,
// which is mainly used to hold Windows thread or process access token
- [SecurityCritical]
public sealed class SafeAccessTokenHandle : SafeHandle
{
private SafeAccessTokenHandle()
@@ -27,24 +26,20 @@ namespace Microsoft.Win32.SafeHandles {
public static SafeAccessTokenHandle InvalidHandle
{
- [SecurityCritical]
get { return new SafeAccessTokenHandle(IntPtr.Zero); }
}
public override bool IsInvalid
{
- [SecurityCritical]
get { return handle == IntPtr.Zero || handle == new IntPtr(-1); }
}
- [SecurityCritical]
protected override bool ReleaseHandle()
{
return Win32Native.CloseHandle(handle);
}
}
- [System.Security.SecurityCritical] // auto-generated
internal sealed class SafeLsaLogonProcessHandle : SafeHandleZeroOrMinusOneIsInvalid {
private SafeLsaLogonProcessHandle() : base (true) {}
@@ -57,7 +52,6 @@ namespace Microsoft.Win32.SafeHandles {
get { return new SafeLsaLogonProcessHandle(IntPtr.Zero); }
}
- [System.Security.SecurityCritical]
override protected bool ReleaseHandle()
{
// LsaDeregisterLogonProcess returns an NTSTATUS
@@ -65,7 +59,6 @@ namespace Microsoft.Win32.SafeHandles {
}
}
- [System.Security.SecurityCritical] // auto-generated
internal sealed class SafeLsaMemoryHandle : SafeBuffer {
private SafeLsaMemoryHandle() : base(true) {}
@@ -78,14 +71,12 @@ namespace Microsoft.Win32.SafeHandles {
get { return new SafeLsaMemoryHandle( IntPtr.Zero ); }
}
- [System.Security.SecurityCritical]
override protected bool ReleaseHandle()
{
return Win32Native.LsaFreeMemory(handle) == 0;
}
}
- [System.Security.SecurityCritical] // auto-generated
internal sealed class SafeLsaPolicyHandle : SafeHandleZeroOrMinusOneIsInvalid {
private SafeLsaPolicyHandle() : base(true) {}
@@ -98,14 +89,12 @@ namespace Microsoft.Win32.SafeHandles {
get { return new SafeLsaPolicyHandle( IntPtr.Zero ); }
}
- [System.Security.SecurityCritical]
override protected bool ReleaseHandle()
{
return Win32Native.LsaClose(handle) == 0;
}
}
- [System.Security.SecurityCritical] // auto-generated
internal sealed class SafeLsaReturnBufferHandle : SafeBuffer {
private SafeLsaReturnBufferHandle() : base (true) {}
@@ -118,7 +107,6 @@ namespace Microsoft.Win32.SafeHandles {
get { return new SafeLsaReturnBufferHandle(IntPtr.Zero); }
}
- [System.Security.SecurityCritical]
override protected bool ReleaseHandle()
{
// LsaFreeReturnBuffer returns an NTSTATUS
@@ -126,7 +114,6 @@ namespace Microsoft.Win32.SafeHandles {
}
}
- [System.Security.SecurityCritical] // auto-generated
internal sealed class SafeProcessHandle : SafeHandleZeroOrMinusOneIsInvalid {
private SafeProcessHandle() : base (true) {}
@@ -139,14 +126,12 @@ namespace Microsoft.Win32.SafeHandles {
get { return new SafeProcessHandle(IntPtr.Zero); }
}
- [System.Security.SecurityCritical]
override protected bool ReleaseHandle()
{
return Win32Native.CloseHandle(handle);
}
}
- [System.Security.SecurityCritical] // auto-generated
internal sealed class SafeThreadHandle : SafeHandleZeroOrMinusOneIsInvalid {
private SafeThreadHandle() : base (true) {}
@@ -155,7 +140,6 @@ namespace Microsoft.Win32.SafeHandles {
SetHandle(handle);
}
- [System.Security.SecurityCritical]
override protected bool ReleaseHandle()
{
return Win32Native.CloseHandle(handle);
diff --git a/src/mscorlib/src/System/Security/SecurityContext.cs b/src/mscorlib/src/System/Security/SecurityContext.cs
index e422a312df..674c04196f 100644
--- a/src/mscorlib/src/System/Security/SecurityContext.cs
+++ b/src/mscorlib/src/System/Security/SecurityContext.cs
@@ -12,14 +12,11 @@
**
===========================================================*/
namespace System.Security
-{
+{
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
using System.Threading;
using System.Runtime.Remoting;
-#if FEATURE_IMPERSONATION
- using System.Security.Principal;
-#endif
using System.Collections;
using System.Runtime.Serialization;
using System.Security.Permissions;
@@ -30,6 +27,7 @@ namespace System.Security
#endif // FEATURE_CORRUPTING_EXCEPTIONS
using System.Runtime.ConstrainedExecution;
using System.Runtime.Versioning;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
// This enum must be kept in sync with the SecurityContextSource enum in the VM
@@ -46,15 +44,6 @@ namespace System.Security
All = 0x3FFF
}
-#if FEATURE_IMPERSONATION
- internal enum WindowsImpersonationFlowMode {
- IMP_FASTFLOW = 0,
- IMP_NOFLOW = 1,
- IMP_ALWAYSFLOW = 2,
- IMP_DEFAULT = IMP_FASTFLOW
- }
-#endif
-
#if FEATURE_COMPRESSEDSTACK
internal struct SecurityContextSwitcher: IDisposable
{
@@ -62,17 +51,12 @@ namespace System.Security
internal SecurityContext currSC; //current SC - SetSecurityContext that created the switcher set this on the Thread
internal ExecutionContext currEC; // current ExecutionContext on Thread
internal CompressedStackSwitcher cssw;
-#if FEATURE_IMPERSONATION
- internal WindowsImpersonationContext wic;
-#endif
- [System.Security.SecuritySafeCritical] // overrides public transparent member
public void Dispose()
{
Undo();
}
- [System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
#if FEATURE_CORRUPTING_EXCEPTIONS
[HandleProcessCorruptedStateExceptions]
@@ -90,7 +74,6 @@ namespace System.Security
return true;
}
- [System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
#if FEATURE_CORRUPTING_EXCEPTIONS
[HandleProcessCorruptedStateExceptions]
@@ -104,8 +87,8 @@ namespace System.Security
if (currEC != null)
{
- Contract.Assert(currEC == Thread.CurrentThread.GetMutableExecutionContext(), "SecurityContextSwitcher used from another thread");
- Contract.Assert(currSC == currEC.SecurityContext, "SecurityContextSwitcher context mismatch");
+ Debug.Assert(currEC == Thread.CurrentThread.GetMutableExecutionContext(), "SecurityContextSwitcher used from another thread");
+ Debug.Assert(currSC == currEC.SecurityContext, "SecurityContextSwitcher context mismatch");
// restore the saved security context
currEC.SecurityContext = prevSC.DangerousGetRawSecurityContext();
@@ -113,26 +96,13 @@ namespace System.Security
else
{
// caller must have already restored the ExecutionContext
- Contract.Assert(Thread.CurrentThread.GetExecutionContextReader().SecurityContext.IsSame(prevSC));
+ Debug.Assert(Thread.CurrentThread.GetExecutionContextReader().SecurityContext.IsSame(prevSC));
}
currSC = null; // this will prevent the switcher object being used again
bool bNoException = true;
-#if FEATURE_IMPERSONATION
- try
- {
- if (wic != null)
- bNoException &= wic.UndoNoThrow();
- }
- catch
- {
- // Failfast since we can't continue safely...
- bNoException &= cssw.UndoNoThrow();
- System.Environment.FailFast(Environment.GetResourceString("ExecutionContext_UndoFailed"));
-
- }
-#endif
+
bNoException &= cssw.UndoNoThrow();
@@ -144,15 +114,9 @@ namespace System.Security
}
}
-
public sealed class SecurityContext : IDisposable
{
-#if FEATURE_IMPERSONATION
- // Note that only one of the following variables will be true. The way we set up the flow mode in the g_pConfig guarantees this.
- static bool _LegacyImpersonationPolicy = (GetImpersonationFlowMode() == WindowsImpersonationFlowMode.IMP_NOFLOW);
- static bool _alwaysFlowImpersonationPolicy = (GetImpersonationFlowMode() == WindowsImpersonationFlowMode.IMP_ALWAYSFLOW);
-#endif
/*=========================================================================
** Data accessed from managed code that needs to be defined in
** SecurityContextObject to maintain alignment between the two classes.
@@ -160,9 +124,6 @@ namespace System.Security
=========================================================================*/
private ExecutionContext _executionContext;
-#if FEATURE_IMPERSONATION
- private volatile WindowsIdentity _windowsIdentity;
-#endif
private volatile CompressedStack _compressedStack;
static private volatile SecurityContext _fullTrustSC;
@@ -204,7 +165,6 @@ namespace System.Security
static internal SecurityContext FullTrustSecurityContext
{
- [System.Security.SecurityCritical] // auto-generated
get
{
if (_fullTrustSC == null)
@@ -222,27 +182,7 @@ namespace System.Security
_executionContext = value;
}
}
-
-#if FEATURE_IMPERSONATION
-
-
- internal WindowsIdentity WindowsIdentity
- {
- get
- {
- return _windowsIdentity;
- }
- set
- {
- // Note, we do not dispose of the existing windows identity, since some code such as remoting
- // relies on reusing that identity. If you are not going to reuse the existing identity, then
- // you should dispose of the existing identity before resetting it.
- _windowsIdentity = value;
- }
- }
-#endif // FEATURE_IMPERSONATION
-
internal CompressedStack CompressedStack
{
get
@@ -258,25 +198,18 @@ namespace System.Security
public void Dispose()
{
-#if FEATURE_IMPERSONATION
- if (_windowsIdentity != null)
- _windowsIdentity.Dispose();
-#endif // FEATURE_IMPERSONATION
}
- [System.Security.SecurityCritical] // auto-generated_required
public static AsyncFlowControl SuppressFlow()
{
return SuppressFlow(SecurityContextDisableFlow.All);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static AsyncFlowControl SuppressFlowWindowsIdentity()
{
return SuppressFlow(SecurityContextDisableFlow.WI);
}
- [SecurityCritical]
internal static AsyncFlowControl SuppressFlow(SecurityContextDisableFlow flags)
{
if (IsFlowSuppressed(flags))
@@ -292,7 +225,6 @@ namespace System.Security
return afc;
}
- [SecuritySafeCritical]
public static void RestoreFlow()
{
SecurityContext sc = Thread.CurrentThread.GetMutableExecutionContext().SecurityContext;
@@ -307,13 +239,7 @@ namespace System.Security
{
return SecurityContext.IsFlowSuppressed(SecurityContextDisableFlow.All);
}
-#if FEATURE_IMPERSONATION
- public static bool IsWindowsIdentityFlowSuppressed()
- {
- return (_LegacyImpersonationPolicy|| SecurityContext.IsFlowSuppressed(SecurityContextDisableFlow.WI));
- }
-#endif
- [SecuritySafeCritical]
+
internal static bool IsFlowSuppressed(SecurityContextDisableFlow flags)
{
return Thread.CurrentThread.GetExecutionContextReader().SecurityContext.IsFlowSuppressed(flags);
@@ -323,7 +249,6 @@ namespace System.Security
// continue past the call to SecurityContext.Run. If you change the signature to this method, or
// provide an alternate way to do a SecurityContext.Run make sure to update
// SecurityStackWalk::IsSpecialRunFrame in the VM to search for the new method.
- [System.Security.SecurityCritical] // auto-generated_required
[DynamicSecurityMethodAttribute()]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static void Run(SecurityContext securityContext, ContextCallback callback, Object state)
@@ -360,7 +285,7 @@ namespace System.Security
// and automatically goes away when the callback returns.
WindowsIdentity.SafeRevertToSelf(ref stackMark);
// Ensure we have reverted to the state we entered in.
- Contract.Assert(GetCurrentWI(Thread.CurrentThread.GetExecutionContextReader()) == null);
+ Debug.Assert(GetCurrentWI(Thread.CurrentThread.GetExecutionContextReader()) == null);
}
}
else
@@ -369,7 +294,6 @@ namespace System.Security
}
}
- [System.Security.SecurityCritical] // auto-generated
internal static void RunInternal(SecurityContext securityContext, ContextCallback callBack, Object state)
{
if (cleanupCode == null)
@@ -397,7 +321,6 @@ namespace System.Security
}
}
- [System.Security.SecurityCritical] // auto-generated
static internal void runTryCode(Object userData)
{
SecurityContextRunData rData = (SecurityContextRunData) userData;
@@ -406,7 +329,6 @@ namespace System.Security
}
- [System.Security.SecurityCritical] // auto-generated
[PrePrepareMethod]
static internal void runFinallyCode(Object userData, bool exceptionThrown)
{
@@ -421,7 +343,6 @@ namespace System.Security
// Internal API that gets called from public SetSecurityContext and from SetExecutionContext
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
- [System.Security.SecurityCritical] // auto-generated
[DynamicSecurityMethodAttribute()]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
internal static SecurityContextSwitcher SetSecurityContext(SecurityContext sc, SecurityContext.Reader prevSecurityContext, bool modifyCurrentExecutionContext)
@@ -430,7 +351,6 @@ namespace System.Security
return SetSecurityContext(sc, prevSecurityContext, modifyCurrentExecutionContext, ref stackMark);
}
- [System.Security.SecurityCritical] // auto-generated
#if FEATURE_CORRUPTING_EXCEPTIONS
[HandleProcessCorruptedStateExceptions]
#endif // FEATURE_CORRUPTING_EXCEPTIONS
@@ -458,22 +378,6 @@ namespace System.Security
RuntimeHelpers.PrepareConstrainedRegions();
try
{
-#if FEATURE_IMPERSONATION
- scsw.wic = null;
- if (!_LegacyImpersonationPolicy)
- {
- if (sc.WindowsIdentity != null)
- {
- scsw.wic = sc.WindowsIdentity.Impersonate(ref stackMark);
- }
- else if ( ((_capturedFlowState & SecurityContextDisableFlow.WI) == 0)
- && prevSecurityContext.WindowsIdentity != null)
- {
- // revert impersonation if there was no WI flow supression at capture and we're currently impersonating
- scsw.wic = WindowsIdentity.SafeRevertToSelf(ref stackMark);
- }
- }
-#endif
scsw.cssw = CompressedStack.SetCompressedStack(sc.CompressedStack, prevSecurityContext.CompressedStack);
}
catch
@@ -486,7 +390,6 @@ namespace System.Security
}
/// <internalonly/>
- [System.Security.SecuritySafeCritical] // auto-generated
public SecurityContext CreateCopy()
{
if (!isNewCapture)
@@ -498,11 +401,6 @@ namespace System.Security
sc.isNewCapture = true;
sc._disableFlow = _disableFlow;
-#if FEATURE_IMPERSONATION
- if (WindowsIdentity != null)
- sc._windowsIdentity = new WindowsIdentity(WindowsIdentity.AccessToken);
-#endif //FEATURE_IMPERSONATION
-
if (_compressedStack != null)
sc._compressedStack = _compressedStack.CreateCopy();
@@ -510,26 +408,19 @@ namespace System.Security
}
/// <internalonly/>
- [System.Security.SecuritySafeCritical] // auto-generated
internal SecurityContext CreateMutableCopy()
{
- Contract.Assert(!this.isNewCapture);
+ Debug.Assert(!this.isNewCapture);
SecurityContext sc = new SecurityContext();
sc._disableFlow = this._disableFlow;
-#if FEATURE_IMPERSONATION
- if (this.WindowsIdentity != null)
- sc._windowsIdentity = new WindowsIdentity(this.WindowsIdentity.AccessToken);
-#endif //FEATURE_IMPERSONATION
-
if (this._compressedStack != null)
sc._compressedStack = this._compressedStack.CreateCopy();
return sc;
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static SecurityContext Capture( )
{
@@ -545,7 +436,6 @@ namespace System.Security
}
// create a clone from a non-existing SecurityContext
- [System.Security.SecurityCritical] // auto-generated
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static internal SecurityContext Capture(ExecutionContext.Reader currThreadEC, ref StackCrawlMark stackMark)
{
@@ -560,125 +450,26 @@ namespace System.Security
return CaptureCore(currThreadEC, ref stackMark);
}
- [System.Security.SecurityCritical] // auto-generated
static private SecurityContext CaptureCore(ExecutionContext.Reader currThreadEC, ref StackCrawlMark stackMark)
{
SecurityContext sc = new SecurityContext();
sc.isNewCapture = true;
-#if FEATURE_IMPERSONATION
- // Force create WindowsIdentity
- if (!IsWindowsIdentityFlowSuppressed())
- {
- WindowsIdentity currentIdentity = GetCurrentWI(currThreadEC);
- if (currentIdentity != null)
- sc._windowsIdentity = new WindowsIdentity(currentIdentity.AccessToken);
- }
- else
- {
- sc._disableFlow = SecurityContextDisableFlow.WI;
- }
-#endif // FEATURE_IMPERSONATION
-
// Force create CompressedStack
sc.CompressedStack = CompressedStack.GetCompressedStack(ref stackMark);
return sc;
}
- [System.Security.SecurityCritical] // auto-generated
+
static internal SecurityContext CreateFullTrustSecurityContext()
{
SecurityContext sc = new SecurityContext();
sc.isNewCapture = true;
-
-#if FEATURE_IMPERSONATION
- if (IsWindowsIdentityFlowSuppressed())
- {
- sc._disableFlow = SecurityContextDisableFlow.WI;
- }
-#endif // FEATURE_IMPERSONATION
-
// Force create CompressedStack
sc.CompressedStack = new CompressedStack(null);
return sc;
}
-#if FEATURE_IMPERSONATION
-
- static internal bool AlwaysFlowImpersonationPolicy { get { return _alwaysFlowImpersonationPolicy; } }
-
- // Check to see if we have a WI on the thread and return if we do
- [System.Security.SecurityCritical] // auto-generated
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- static internal WindowsIdentity GetCurrentWI(ExecutionContext.Reader threadEC)
- {
- return GetCurrentWI(threadEC, _alwaysFlowImpersonationPolicy);
- }
-
- [System.Security.SecurityCritical] // auto-generated
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- static internal WindowsIdentity GetCurrentWI(ExecutionContext.Reader threadEC, bool cachedAlwaysFlowImpersonationPolicy)
- {
- Contract.Assert(cachedAlwaysFlowImpersonationPolicy == _alwaysFlowImpersonationPolicy);
- if (cachedAlwaysFlowImpersonationPolicy)
- {
- // Examine the threadtoken at the cost of a kernel call if the user has set the IMP_ALWAYSFLOW mode
- return WindowsIdentity.GetCurrentInternal(TokenAccessLevels.MaximumAllowed, true);
- }
-
- return threadEC.SecurityContext.WindowsIdentity;
- }
-
- [System.Security.SecurityCritical]
- static internal void RestoreCurrentWI(ExecutionContext.Reader currentEC, ExecutionContext.Reader prevEC, WindowsIdentity targetWI, bool cachedAlwaysFlowImpersonationPolicy)
- {
- Contract.Assert(currentEC.IsSame(Thread.CurrentThread.GetExecutionContextReader()));
- Contract.Assert(cachedAlwaysFlowImpersonationPolicy == _alwaysFlowImpersonationPolicy);
-
- // NOTE: cachedAlwaysFlowImpersonationPolicy is a perf optimization to avoid always having to access a static variable here.
- if (cachedAlwaysFlowImpersonationPolicy || prevEC.SecurityContext.WindowsIdentity != targetWI)
- {
- //
- // Either we're always flowing, or the target WI was obtained from the current EC in the first place.
- //
- Contract.Assert(_alwaysFlowImpersonationPolicy || currentEC.SecurityContext.WindowsIdentity == targetWI);
-
- RestoreCurrentWIInternal(targetWI);
- }
- }
-
- [System.Security.SecurityCritical]
- static private void RestoreCurrentWIInternal(WindowsIdentity targetWI)
- {
- int hr = Win32.RevertToSelf();
- if (hr < 0)
- Environment.FailFast(Win32Native.GetMessage(hr));
-
- if (targetWI != null)
- {
- SafeAccessTokenHandle tokenHandle = targetWI.AccessToken;
- if (tokenHandle != null && !tokenHandle.IsInvalid)
- {
- hr = Win32.ImpersonateLoggedOnUser(tokenHandle);
- if (hr < 0)
- Environment.FailFast(Win32Native.GetMessage(hr));
- }
- }
- }
-
- [System.Security.SecurityCritical] // auto-generated
- internal bool IsDefaultFTSecurityContext()
- {
- return (WindowsIdentity == null && (CompressedStack == null || CompressedStack.CompressedStackHandle == null));
- }
- [System.Security.SecurityCritical] // auto-generated
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- static internal bool CurrentlyInDefaultFTSecurityContext(ExecutionContext.Reader threadEC)
- {
- return (IsDefaultThreadSecurityInfo() && GetCurrentWI(threadEC) == null);
- }
-#else
-
internal bool IsDefaultFTSecurityContext()
{
return (CompressedStack == null || CompressedStack.CompressedStackHandle == null);
@@ -687,16 +478,9 @@ namespace System.Security
{
return (IsDefaultThreadSecurityInfo());
}
-#endif
-#if FEATURE_IMPERSONATION
- [System.Security.SecuritySafeCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- internal extern static WindowsImpersonationFlowMode GetImpersonationFlowMode();
-#endif
- [System.Security.SecurityCritical] // auto-generated
+
[MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal extern static bool IsDefaultThreadSecurityInfo();
-
}
#endif // FEATURE_COMPRESSEDSTACK
}
diff --git a/src/mscorlib/src/System/Security/SecurityElement.cs b/src/mscorlib/src/System/Security/SecurityElement.cs
index aa63029422..f57665b278 100644
--- a/src/mscorlib/src/System/Security/SecurityElement.cs
+++ b/src/mscorlib/src/System/Security/SecurityElement.cs
@@ -14,6 +14,7 @@ namespace System.Security
using System.Globalization;
using System.IO;
using System.Security.Permissions;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
internal enum SecurityElementType
@@ -93,23 +94,10 @@ namespace System.Security
return ((SecurityElement)this).Attribute( attributeName );
}
-//////////////
-
-#if FEATURE_CAS_POLICY
- public static SecurityElement FromString( String xml )
- {
- if (xml == null)
- throw new ArgumentNullException( "xml" );
- Contract.EndContractBlock();
-
- return new Parser( xml ).GetTopElement();
- }
-#endif // FEATURE_CAS_POLICY
-
public SecurityElement( String tag )
{
if (tag == null)
- throw new ArgumentNullException( "tag" );
+ throw new ArgumentNullException( nameof(tag) );
if (!IsValidTag( tag ))
throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Argument_InvalidElementTag" ), tag ) );
@@ -122,7 +110,7 @@ namespace System.Security
public SecurityElement( String tag, String text )
{
if (tag == null)
- throw new ArgumentNullException( "tag" );
+ throw new ArgumentNullException( nameof(tag) );
if (!IsValidTag( tag ))
throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Argument_InvalidElementTag" ), tag ) );
@@ -148,7 +136,7 @@ namespace System.Security
set
{
if (value == null)
- throw new ArgumentNullException( "Tag" );
+ throw new ArgumentNullException( nameof(Tag) );
if (!IsValidTag( value ))
throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Argument_InvalidElementTag" ), value ) );
@@ -171,7 +159,7 @@ namespace System.Security
Hashtable hashtable = new Hashtable( m_lAttributes.Count/2 );
int iMax = m_lAttributes.Count;
- Contract.Assert( iMax % 2 == 0, "Odd number of strings means the attr/value pairs were not added correctly" );
+ Debug.Assert( iMax % 2 == 0, "Odd number of strings means the attr/value pairs were not added correctly" );
for (int i = 0; i < iMax; i += 2)
{
@@ -296,7 +284,7 @@ namespace System.Security
else
{
int iMax = m_lAttributes.Count;
- Contract.Assert( iMax % 2 == 0, "Odd number of strings means the attr/value pairs were not added correctly" );
+ Debug.Assert( iMax % 2 == 0, "Odd number of strings means the attr/value pairs were not added correctly" );
for (int i = 0; i < iMax; i += 2)
{
@@ -314,10 +302,10 @@ namespace System.Security
public void AddAttribute( String name, String value )
{
if (name == null)
- throw new ArgumentNullException( "name" );
+ throw new ArgumentNullException( nameof(name) );
if (value == null)
- throw new ArgumentNullException( "value" );
+ throw new ArgumentNullException( nameof(value) );
if (!IsValidAttributeName( name ))
throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Argument_InvalidElementName" ), name ) );
@@ -332,7 +320,7 @@ namespace System.Security
public void AddChild( SecurityElement child )
{
if (child == null)
- throw new ArgumentNullException( "child" );
+ throw new ArgumentNullException( nameof(child) );
Contract.EndContractBlock();
if (m_lChildren == null)
@@ -344,7 +332,7 @@ namespace System.Security
internal void AddChild( ISecurityElementFactory child )
{
if (child == null)
- throw new ArgumentNullException( "child" );
+ throw new ArgumentNullException( nameof(child) );
Contract.EndContractBlock();
if (m_lChildren == null)
@@ -356,7 +344,7 @@ namespace System.Security
internal void AddChildNoDuplicates( ISecurityElementFactory child )
{
if (child == null)
- throw new ArgumentNullException( "child" );
+ throw new ArgumentNullException( nameof(child) );
Contract.EndContractBlock();
if (m_lChildren == null)
@@ -400,7 +388,7 @@ namespace System.Security
else
{
int iMax = m_lAttributes.Count;
- Contract.Assert( iMax % 2 == 0, "Odd number of strings means the attr/value pairs were not added correctly" );
+ Debug.Assert( iMax % 2 == 0, "Odd number of strings means the attr/value pairs were not added correctly" );
if (iMax != other.m_lAttributes.Count)
return false;
@@ -495,7 +483,7 @@ namespace System.Security
private static String GetEscapeSequence( char c )
{
int iMax = s_escapeStringPairs.Length;
- Contract.Assert( iMax % 2 == 0, "Odd number of strings means the attr/value pairs were not added correctly" );
+ Debug.Assert( iMax % 2 == 0, "Odd number of strings means the attr/value pairs were not added correctly" );
for (int i = 0; i < iMax; i += 2)
{
@@ -506,7 +494,7 @@ namespace System.Security
return strEscValue;
}
- Contract.Assert( false, "Unable to find escape sequence for this character" );
+ Debug.Assert( false, "Unable to find escape sequence for this character" );
return c.ToString();
}
@@ -557,7 +545,7 @@ namespace System.Security
int maxCompareLength = str.Length - index;
int iMax = s_escapeStringPairs.Length;
- Contract.Assert( iMax % 2 == 0, "Odd number of strings means the attr/value pairs were not added correctly" );
+ Debug.Assert( iMax % 2 == 0, "Odd number of strings means the attr/value pairs were not added correctly" );
for (int i = 0; i < iMax; i += 2)
{
@@ -616,7 +604,7 @@ namespace System.Security
while (true);
// C# reports a warning if I leave this in, but I still kinda want to just in case.
- // Contract.Assert( false, "If you got here, the execution engine or compiler is really confused" );
+ // Debug.Assert( false, "If you got here, the execution engine or compiler is really confused" );
// return str;
}
@@ -626,11 +614,6 @@ namespace System.Security
{
((StringBuilder)obj).Append( str );
}
-
- private static void ToStringHelperStreamWriter( Object obj, String str )
- {
- ((StreamWriter)obj).Write( str );
- }
public override String ToString ()
{
@@ -641,16 +624,11 @@ namespace System.Security
return sb.ToString();
}
- internal void ToWriter( StreamWriter writer )
- {
- ToString( "", writer, new ToStringHelperFunc( ToStringHelperStreamWriter ) );
- }
-
private void ToString( String indent, Object obj, ToStringHelperFunc func )
{
// First add the indent
- // func( obj, indent );
+ // func( obj, indent );
// Add in the opening bracket and the tag.
@@ -679,7 +657,7 @@ namespace System.Security
func( obj, " " );
int iMax = m_lAttributes.Count;
- Contract.Assert( iMax % 2 == 0, "Odd number of strings means the attr/value pairs were not added correctly" );
+ Debug.Assert( iMax % 2 == 0, "Odd number of strings means the attr/value pairs were not added correctly" );
for (int i = 0; i < iMax; i += 2)
{
@@ -770,7 +748,7 @@ namespace System.Security
public String Attribute( String name )
{
if (name == null)
- throw new ArgumentNullException( "name" );
+ throw new ArgumentNullException( nameof(name) );
Contract.EndContractBlock();
// Note: we don't check for validity here because an
@@ -783,7 +761,7 @@ namespace System.Security
// the one we are asked for
int iMax = m_lAttributes.Count;
- Contract.Assert( iMax % 2 == 0, "Odd number of strings means the attr/value pairs were not added correctly" );
+ Debug.Assert( iMax % 2 == 0, "Odd number of strings means the attr/value pairs were not added correctly" );
for (int i = 0; i < iMax; i += 2)
{
@@ -808,7 +786,7 @@ namespace System.Security
// find the one are are asked for (matching tags)
if (tag == null)
- throw new ArgumentNullException( "tag" );
+ throw new ArgumentNullException( nameof(tag) );
Contract.EndContractBlock();
// Note: we don't check for a valid tag here because
@@ -829,45 +807,13 @@ namespace System.Security
return null;
}
-#if FEATURE_CAS_POLICY
- internal IPermission ToPermission(bool ignoreTypeLoadFailures)
- {
- IPermission ip = XMLUtil.CreatePermission( this, PermissionState.None, ignoreTypeLoadFailures );
- if (ip == null)
- return null;
- ip.FromXml(this);
-
- // Get the permission token here to ensure that the token
- // type is updated appropriately now that we've loaded the type.
- PermissionToken token = PermissionToken.GetToken( ip );
- Contract.Assert((token.m_type & PermissionTokenType.DontKnow) == 0, "Token type not properly assigned");
-
- return ip;
- }
-
- [System.Security.SecurityCritical] // auto-generated
- internal Object ToSecurityObject()
- {
- switch (m_strTag)
- {
- case "PermissionSet":
- PermissionSet pset = new PermissionSet(PermissionState.None);
- pset.FromXml(this);
- return pset;
-
- default:
- return ToPermission(false);
- }
- }
-#endif // FEATURE_CAS_POLICY
-
internal String SearchForTextOfLocalName(String strLocalName)
{
// Search on each child in order and each
// child's child, depth-first
if (strLocalName == null)
- throw new ArgumentNullException( "strLocalName" );
+ throw new ArgumentNullException( nameof(strLocalName) );
Contract.EndContractBlock();
// Note: we don't check for a valid tag here because
@@ -899,7 +845,7 @@ namespace System.Security
// child's child, depth-first
if (tag == null)
- throw new ArgumentNullException( "tag" );
+ throw new ArgumentNullException( nameof(tag) );
Contract.EndContractBlock();
// Note: we don't check for a valid tag here because
diff --git a/src/mscorlib/src/System/Security/SecurityException.cs b/src/mscorlib/src/System/Security/SecurityException.cs
index 9fbd8023d2..c76674cdb9 100644
--- a/src/mscorlib/src/System/Security/SecurityException.cs
+++ b/src/mscorlib/src/System/Security/SecurityException.cs
@@ -34,589 +34,60 @@ namespace System.Security
[Serializable]
public class SecurityException : SystemException
{
-#if FEATURE_CAS_POLICY
- private String m_debugString; // NOTE: If you change the name of this field, you'll have to update SOS as well!
- private SecurityAction m_action;
- [NonSerialized] private Type m_typeOfPermissionThatFailed;
- private String m_permissionThatFailed;
- private String m_demanded;
- private String m_granted;
- private String m_refused;
- private String m_denied;
- private String m_permitOnly;
- private AssemblyName m_assemblyName;
- private byte[] m_serializedMethodInfo;
- private String m_strMethodInfo;
- private SecurityZone m_zone;
- private String m_url;
-
- private const String ActionName = "Action";
- private const String FirstPermissionThatFailedName = "FirstPermissionThatFailed";
- private const String DemandedName = "Demanded";
- private const String GrantedSetName = "GrantedSet";
- private const String RefusedSetName = "RefusedSet";
- private const String DeniedName = "Denied";
- private const String PermitOnlyName = "PermitOnly";
- private const String Assembly_Name = "Assembly";
- private const String MethodName_Serialized = "Method";
- private const String MethodName_String = "Method_String";
- private const String ZoneName = "Zone";
- private const String UrlName = "Url";
-#endif // #if FEATURE_CAS_POLICY
-
- [System.Security.SecuritySafeCritical] // auto-generated
internal static string GetResString(string sResourceName)
{
PermissionSet.s_fullTrust.Assert();
return Environment.GetResourceString(sResourceName);
}
- [System.Security.SecurityCritical] // auto-generated
#pragma warning disable 618
internal static Exception MakeSecurityException(AssemblyName asmName, Evidence asmEvidence, PermissionSet granted, PermissionSet refused, RuntimeMethodHandleInternal rmh, SecurityAction action, Object demand, IPermission permThatFailed)
#pragma warning restore 618
{
-#if FEATURE_CAS_POLICY
- // See if we need to throw a HostProtectionException instead
- HostProtectionPermission hostProtectionPerm = permThatFailed as HostProtectionPermission;
- if(hostProtectionPerm != null)
- return new HostProtectionException(GetResString("HostProtection_HostProtection"), HostProtectionPermission.protectedResources, hostProtectionPerm.Resources);
-
- // Produce relevant strings
- String message = "";
- MethodInfo method = null;
- try
- {
- if(granted == null && refused == null && demand == null)
- {
- message = GetResString("Security_NoAPTCA");
- }
- else
- {
- if(demand != null && demand is IPermission)
- message = String.Format(CultureInfo.InvariantCulture, GetResString("Security_Generic"), demand.GetType().AssemblyQualifiedName );
- else if (permThatFailed != null)
- message = String.Format(CultureInfo.InvariantCulture, GetResString("Security_Generic"), permThatFailed.GetType().AssemblyQualifiedName);
- else
- message = GetResString("Security_GenericNoType");
- }
-
- method = SecurityRuntime.GetMethodInfo(rmh);
- }
- catch(Exception e)
- {
- // Environment.GetResourceString will throw if we are ReadyForAbort (thread abort). (We shouldn't do a Contract.Assert in this case or it will lock up the thread.)
- if(e is System.Threading.ThreadAbortException)
- throw;
- }
-
-/* catch(System.Threading.ThreadAbortException)
- {
- // Environment.GetResourceString will throw if we are ReadyForAbort (thread abort). (We shouldn't do a BCLDebug.Assert in this case or it will lock up the thread.)
- throw;
- }
- catch
- {
- }
-*/
- // make the exception object
- return new SecurityException(message, asmName, granted, refused, method, action, demand, permThatFailed, asmEvidence);
-#else
return new SecurityException(GetResString("Arg_SecurityException"));
-#endif
-
}
-#if FEATURE_CAS_POLICY
- private static byte[] ObjectToByteArray(Object obj)
- {
- if(obj == null)
- return null;
- MemoryStream stream = new MemoryStream();
- BinaryFormatter formatter = new BinaryFormatter();
- try {
- formatter.Serialize(stream, obj);
- byte[] array = stream.ToArray();
- return array;
- } catch (NotSupportedException) {
- // Serialization of certain methods is not supported (namely
- // global methods, since they have no representation outside of
- // a module scope).
- return null;
- }
- }
-
- private static Object ByteArrayToObject(byte[] array)
- {
- if(array == null || array.Length == 0)
- return null;
- MemoryStream stream = new MemoryStream(array);
- BinaryFormatter formatter = new BinaryFormatter();
- Object obj = formatter.Deserialize(stream);
- return obj;
- }
-#endif // FEATURE_CAS_POLICY
-
- public 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);
- }
-#if FEATURE_CAS_POLICY
- [System.Security.SecuritySafeCritical] // auto-generated
- public SecurityException(String message, Type type )
+ public SecurityException(String message)
: base(message)
{
- PermissionSet.s_fullTrust.Assert();
- SetErrorCode(System.__HResults.COR_E_SECURITY);
- m_typeOfPermissionThatFailed = type;
- }
-
- // *** Don't use this constructor internally ***
- [System.Security.SecuritySafeCritical] // auto-generated
- public SecurityException(String message, Type type, String state )
- : base(message)
- {
- PermissionSet.s_fullTrust.Assert();
+ // 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);
- m_typeOfPermissionThatFailed = type;
- m_demanded = state;
}
-#endif //FEATURE_CAS_POLICY
- public SecurityException(String message, Exception inner)
+ public SecurityException(String message, Exception inner)
: base(message, inner)
{
SetErrorCode(System.__HResults.COR_E_SECURITY);
}
-#if FEATURE_CAS_POLICY
- // *** Don't use this constructor internally ***
- [System.Security.SecurityCritical] // auto-generated
- internal SecurityException( PermissionSet grantedSetObj, PermissionSet refusedSetObj )
- : base(GetResString("Arg_SecurityException"))
- {
- PermissionSet.s_fullTrust.Assert();
- SetErrorCode(System.__HResults.COR_E_SECURITY);
- if (grantedSetObj != null)
- m_granted = grantedSetObj.ToXml().ToString();
- if (refusedSetObj != null)
- m_refused = refusedSetObj.ToXml().ToString();
- }
-
- // *** Don't use this constructor internally ***
- [System.Security.SecurityCritical] // auto-generated
- internal SecurityException( String message, PermissionSet grantedSetObj, PermissionSet refusedSetObj )
- : base(message)
- {
- PermissionSet.s_fullTrust.Assert();
- SetErrorCode(System.__HResults.COR_E_SECURITY);
- if (grantedSetObj != null)
- m_granted = grantedSetObj.ToXml().ToString();
- if (refusedSetObj != null)
- m_refused = refusedSetObj.ToXml().ToString();
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- protected SecurityException(SerializationInfo info, StreamingContext context) : base (info, context)
- {
- if (info==null)
- throw new ArgumentNullException("info");
- Contract.EndContractBlock();
-
- try
- {
- m_action = (SecurityAction)info.GetValue(ActionName, typeof(SecurityAction));
- m_permissionThatFailed = (String)info.GetValueNoThrow(FirstPermissionThatFailedName, typeof(String));
- m_demanded = (String)info.GetValueNoThrow(DemandedName, typeof(String));
- m_granted = (String)info.GetValueNoThrow(GrantedSetName, typeof(String));
- m_refused = (String)info.GetValueNoThrow(RefusedSetName, typeof(String));
- m_denied = (String)info.GetValueNoThrow(DeniedName, typeof(String));
- m_permitOnly = (String)info.GetValueNoThrow(PermitOnlyName, typeof(String));
- m_assemblyName = (AssemblyName)info.GetValueNoThrow(Assembly_Name, typeof(AssemblyName));
- m_serializedMethodInfo = (byte[])info.GetValueNoThrow(MethodName_Serialized, typeof(byte[]));
- m_strMethodInfo = (String)info.GetValueNoThrow(MethodName_String, typeof(String));
- m_zone = (SecurityZone)info.GetValue(ZoneName, typeof(SecurityZone));
- m_url = (String)info.GetValueNoThrow(UrlName, typeof(String));
- }
- catch
- {
- m_action = 0;
- m_permissionThatFailed = "";
- m_demanded = "";
- m_granted = "";
- m_refused = "";
- m_denied = "";
- m_permitOnly = "";
- m_assemblyName = null;
- m_serializedMethodInfo = null;
- m_strMethodInfo = null;
- m_zone = SecurityZone.NoZone;
- m_url = "";
- }
- }
-
- // ------------------------------------------
- // | For failures due to insufficient grant |
- // ------------------------------------------
- [System.Security.SecuritySafeCritical] // auto-generated
- public SecurityException(string message, AssemblyName assemblyName, PermissionSet grant, PermissionSet refused, MethodInfo method, SecurityAction action, Object demanded, IPermission permThatFailed, Evidence evidence)
- : base(message)
- {
- PermissionSet.s_fullTrust.Assert();
- SetErrorCode(System.__HResults.COR_E_SECURITY);
- Action = action;
- if(permThatFailed != null)
- m_typeOfPermissionThatFailed = permThatFailed.GetType();
- FirstPermissionThatFailed = permThatFailed;
- Demanded = demanded;
- m_granted = (grant == null ? "" : grant.ToXml().ToString());
- m_refused = (refused == null ? "" : refused.ToXml().ToString());
- m_denied = "";
- m_permitOnly = "";
- m_assemblyName = assemblyName;
- Method = method;
- m_url = "";
- m_zone = SecurityZone.NoZone;
- if(evidence != null)
- {
- Url url = evidence.GetHostEvidence<Url>();
- if(url != null)
- m_url = url.GetURLString().ToString();
- Zone zone = evidence.GetHostEvidence<Zone>();
- if(zone != null)
- m_zone = zone.SecurityZone;
- }
- m_debugString = this.ToString(true, false);
- }
-
- // ------------------------------------------
- // | For failures due to deny or PermitOnly |
- // ------------------------------------------
- [System.Security.SecuritySafeCritical] // auto-generated
- public SecurityException(string message, Object deny, Object permitOnly, MethodInfo method, Object demanded, IPermission permThatFailed)
- : base(message)
- {
- PermissionSet.s_fullTrust.Assert();
- SetErrorCode(System.__HResults.COR_E_SECURITY);
- Action = SecurityAction.Demand;
- if(permThatFailed != null)
- m_typeOfPermissionThatFailed = permThatFailed.GetType();
- FirstPermissionThatFailed = permThatFailed;
- Demanded = demanded;
- m_granted = "";
- m_refused = "";
- DenySetInstance = deny;
- PermitOnlySetInstance = permitOnly;
- m_assemblyName = null;
- Method = method;
- m_zone = SecurityZone.NoZone;
- m_url = "";
- m_debugString = this.ToString(true, false);
- }
-
-
-
-
-
-
-
-
-
-
-
- [System.Runtime.InteropServices.ComVisible(false)]
- public SecurityAction Action
- {
- get
- {
- return m_action;
- }
-
- set
- {
- m_action = value;
- }
- }
-
- public Type PermissionType
- {
- [System.Security.SecuritySafeCritical] // auto-generated
- get
- {
- if(m_typeOfPermissionThatFailed == null)
- {
- Object ob = XMLUtil.XmlStringToSecurityObject(m_permissionThatFailed);
- if(ob == null)
- ob = XMLUtil.XmlStringToSecurityObject(m_demanded);
- if(ob != null)
- m_typeOfPermissionThatFailed = ob.GetType();
- }
- return m_typeOfPermissionThatFailed;
- }
-
- set
- {
- m_typeOfPermissionThatFailed = value;
- }
- }
-
- public IPermission FirstPermissionThatFailed
- {
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)]
- get
- {
- return (IPermission)XMLUtil.XmlStringToSecurityObject(m_permissionThatFailed);
- }
-
- set
- {
- m_permissionThatFailed = XMLUtil.SecurityObjectToXmlString(value);
- }
- }
-
- public String PermissionState
- {
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)]
- get
- {
- return m_demanded;
- }
-
- set
- {
- m_demanded = value;
- }
- }
-
- [System.Runtime.InteropServices.ComVisible(false)]
- public Object Demanded
- {
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)]
- get
- {
- return XMLUtil.XmlStringToSecurityObject(m_demanded);
- }
-
- set
- {
- m_demanded = XMLUtil.SecurityObjectToXmlString(value);
- }
- }
-
- public String GrantedSet
- {
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)]
- get
- {
- return m_granted;
- }
-
- set
- {
- m_granted = value;
- }
- }
-
- public String RefusedSet
- {
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)]
- get
- {
- return m_refused;
- }
-
- set
- {
- m_refused = value;
- }
- }
-
- [System.Runtime.InteropServices.ComVisible(false)]
- public Object DenySetInstance
- {
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)]
- get
- {
- return XMLUtil.XmlStringToSecurityObject(m_denied);
- }
-
- set
- {
- m_denied = XMLUtil.SecurityObjectToXmlString(value);
- }
- }
-
- [System.Runtime.InteropServices.ComVisible(false)]
- public Object PermitOnlySetInstance
- {
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)]
- get
- {
- return XMLUtil.XmlStringToSecurityObject(m_permitOnly);
- }
-
- set
- {
- m_permitOnly = XMLUtil.SecurityObjectToXmlString(value);
- }
- }
-
- [System.Runtime.InteropServices.ComVisible(false)]
- public AssemblyName FailedAssemblyInfo
- {
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)]
- get
- {
- return m_assemblyName;
- }
-
- set
- {
- m_assemblyName = value;
- }
- }
-
- private MethodInfo getMethod()
- {
- return (MethodInfo)ByteArrayToObject(m_serializedMethodInfo);
- }
-
- [System.Runtime.InteropServices.ComVisible(false)]
- public MethodInfo Method
- {
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)]
- get
- {
- return getMethod();
- }
-
- set
- {
- RuntimeMethodInfo m = value as RuntimeMethodInfo;
- m_serializedMethodInfo = ObjectToByteArray(m);
- if (m != null)
- {
- m_strMethodInfo = m.ToString();
- }
- }
- }
-
- public SecurityZone Zone
- {
- get
- {
- return m_zone;
- }
-
- set
- {
- m_zone = value;
- }
- }
-
- public String Url
- {
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)]
- get
- {
- return m_url;
- }
-
- set
- {
- m_url = value;
- }
- }
-
- private void ToStringHelper(StringBuilder sb, String resourceString, Object attr)
- {
- if (attr == null)
- return;
- String attrString = attr as String;
- if (attrString == null)
- attrString = attr.ToString();
- if (attrString.Length == 0)
- return;
- sb.Append(Environment.NewLine);
- sb.Append(GetResString(resourceString));
- sb.Append(Environment.NewLine);
- sb.Append(attrString);
- }
-
- [System.Security.SecurityCritical] // auto-generated
- private String ToString(bool includeSensitiveInfo, bool includeBaseInfo)
- {
- PermissionSet.s_fullTrust.Assert();
- StringBuilder sb = new StringBuilder();
-
- if(includeBaseInfo)
- sb.Append(base.ToString());
- if(Action > 0)
- ToStringHelper(sb, "Security_Action", Action);
- ToStringHelper(sb, "Security_TypeFirstPermThatFailed", PermissionType);
- if(includeSensitiveInfo)
- {
- ToStringHelper(sb, "Security_FirstPermThatFailed", m_permissionThatFailed);
- ToStringHelper(sb, "Security_Demanded", m_demanded);
- ToStringHelper(sb, "Security_GrantedSet", m_granted);
- ToStringHelper(sb, "Security_RefusedSet", m_refused);
- ToStringHelper(sb, "Security_Denied", m_denied);
- ToStringHelper(sb, "Security_PermitOnly", m_permitOnly);
- ToStringHelper(sb, "Security_Assembly", m_assemblyName);
- ToStringHelper(sb, "Security_Method", m_strMethodInfo);
- }
- if(m_zone != SecurityZone.NoZone)
- ToStringHelper(sb, "Security_Zone", m_zone);
- if(includeSensitiveInfo)
- ToStringHelper(sb, "Security_Url", m_url);
- return sb.ToString();
- }
-#else // FEATURE_CAS_POLICY
- internal SecurityException( PermissionSet grantedSetObj, PermissionSet refusedSetObj )
+ internal SecurityException(PermissionSet grantedSetObj, PermissionSet refusedSetObj)
: this(){}
#pragma warning disable 618
internal SecurityException(string message, AssemblyName assemblyName, PermissionSet grant, PermissionSet refused, MethodInfo method, SecurityAction action, Object demanded, IPermission permThatFailed, Evidence evidence)
#pragma warning restore 618
: this(){}
-
+
internal SecurityException(string message, Object deny, Object permitOnly, MethodInfo method, Object demanded, IPermission permThatFailed)
: this(){}
- [System.Security.SecuritySafeCritical] // auto-generated
protected SecurityException(SerializationInfo info, StreamingContext context) : base(info, context)
{
if (info == null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
}
- public override String ToString()
- {
- return base.ToString();
- }
-
-#endif // FEATURE_CAS_POLICY
+ public override String ToString()
+ {
+ return base.ToString();
+ }
- [System.Security.SecurityCritical] // auto-generated
private bool CanAccessSensitiveInfo()
{
bool retVal = false;
@@ -627,41 +98,46 @@ namespace System.Security
#pragma warning restore 618
retVal = true;
}
- catch(SecurityException)
+ catch (SecurityException)
{
}
return retVal;
- }
-#if FEATURE_CAS_POLICY
- [System.Security.SecuritySafeCritical] // auto-generated
- public override String ToString()
- {
- return ToString(CanAccessSensitiveInfo(), true);
}
-#endif //FEATURE_CAS_POLICY
- [System.Security.SecurityCritical] // auto-generated_required
+
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
- if (info==null)
- throw new ArgumentNullException("info");
+ if (info == null)
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
- base.GetObjectData( info, context );
-#if FEATURE_CAS_POLICY
+ base.GetObjectData(info, context);
+ }
- info.AddValue(ActionName, m_action, typeof(SecurityAction));
- info.AddValue(FirstPermissionThatFailedName, m_permissionThatFailed, typeof(String));
- info.AddValue(DemandedName, m_demanded, typeof(String));
- info.AddValue(GrantedSetName, m_granted, typeof(String));
- info.AddValue(RefusedSetName, m_refused, typeof(String));
- info.AddValue(DeniedName, m_denied, typeof(String));
- info.AddValue(PermitOnlyName, m_permitOnly, typeof(String));
- info.AddValue(Assembly_Name, m_assemblyName, typeof(AssemblyName));
- info.AddValue(MethodName_Serialized, m_serializedMethodInfo, typeof(byte[]));
- info.AddValue(MethodName_String, m_strMethodInfo, typeof(String));
- info.AddValue(ZoneName, m_zone, typeof(SecurityZone));
- info.AddValue(UrlName, m_url, typeof(String));
-#endif // FEATURE_CAS_POLICY
+ // 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/SecurityManager.cs b/src/mscorlib/src/System/Security/SecurityManager.cs
index 5c46dfcbfc..933fe0be3d 100644
--- a/src/mscorlib/src/System/Security/SecurityManager.cs
+++ b/src/mscorlib/src/System/Security/SecurityManager.cs
@@ -2,32 +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.
-//
-
-//
//
// The SecurityManager class provides a general purpose API for interacting
// with the security system.
//
-namespace System.Security {
+namespace System.Security
+{
using System;
- using System.Security.Util;
- using System.Security.Policy;
using System.Security.Permissions;
- using System.Collections;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
-#if FEATURE_CLICKONCE
- using System.Runtime.Hosting;
-#endif // FEATURE_CLICKONCE
- using System.Text;
- using System.Threading;
- using System.Reflection;
- using System.IO;
- using System.Globalization;
- using System.Runtime.Versioning;
- using System.Diagnostics.Contracts;
[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
@@ -40,504 +25,8 @@ namespace System.Security {
}
[System.Runtime.InteropServices.ComVisible(true)]
- static public class SecurityManager {
-#if FEATURE_CAS_POLICY
- private static volatile SecurityPermission executionSecurityPermission = null;
-
- private static PolicyManager polmgr = new PolicyManager();
- internal static PolicyManager PolicyManager {
- get {
- return polmgr;
- }
- }
-
- //
- // Public APIs
- //
- [System.Security.SecuritySafeCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- [Obsolete("IsGranted is obsolete and will be removed in a future release of the .NET Framework. Please use the PermissionSet property of either AppDomain or Assembly instead.")]
- public static bool IsGranted( IPermission perm )
- {
- if (perm == null)
- return true;
-
- PermissionSet granted = null, denied = null;
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- GetGrantedPermissions( JitHelpers.GetObjectHandleOnStack(ref granted),
- JitHelpers.GetObjectHandleOnStack(ref denied),
- JitHelpers.GetStackCrawlMarkHandle(ref stackMark) );
- return granted.Contains( perm ) && (denied == null || !denied.Contains( perm ));
- }
-
- // Get a sandbox permission set that the CLR considers safe to grant an application with the given
- // evidence. Note that this API is not a policy API, but rather a host helper API so that a host can
- // determine if an application's requested permission set is reasonable. This is esentially just a
- // hard coded mapping of Zone -> Sandbox and is not configurable in any way.
- public static PermissionSet GetStandardSandbox(Evidence evidence)
- {
- if (evidence == null)
- throw new ArgumentNullException("evidence");
- Contract.EndContractBlock();
-
- //
- // The top-level switch for grant set is based upon Zone
- // MyComputer -> FullTrust
- // Intranet -> LocalIntranet
- // Trusted -> Internet
- // Internet -> Internet
- // All else -> Nothing
- //
- // Both the Internet and LocalIntranet zones can have permission set extensions applied to them
- // if there is Activation.
- //
-
- Zone zone = evidence.GetHostEvidence<Zone>();
- if (zone == null)
- {
- return new PermissionSet(PermissionState.None);
- }
-#if FEATURE_CAS_POLICY
- else if (zone.SecurityZone == SecurityZone.MyComputer)
- {
- return new PermissionSet(PermissionState.Unrestricted);
- }
- else if (zone.SecurityZone == SecurityZone.Intranet)
- {
- PermissionSet intranetGrantSet = BuiltInPermissionSets.LocalIntranet;
-
- // We also need to add in same site web and file IO permission
- PolicyStatement webPolicy =
- new NetCodeGroup(new AllMembershipCondition()).Resolve(evidence);
- PolicyStatement filePolicy =
- new FileCodeGroup(new AllMembershipCondition(), FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery).Resolve(evidence);
-
- if (webPolicy != null)
- {
- intranetGrantSet.InplaceUnion(webPolicy.PermissionSet);
- }
- if (filePolicy != null)
- {
- intranetGrantSet.InplaceUnion(filePolicy.PermissionSet);
- }
-
- return intranetGrantSet;
- }
- else if (zone.SecurityZone == SecurityZone.Internet ||
- zone.SecurityZone == SecurityZone.Trusted)
- {
- PermissionSet internetGrantSet = BuiltInPermissionSets.Internet;
-
- // We also need to add in same site web permission
- PolicyStatement webPolicy =
- new NetCodeGroup(new AllMembershipCondition()).Resolve(evidence);
-
- if (webPolicy != null)
- {
- internetGrantSet.InplaceUnion(webPolicy.PermissionSet);
- }
-
- return internetGrantSet;
- }
-#endif // FEATURE_CAS_POLICY
- else
- {
- return new PermissionSet(PermissionState.None);
- }
- }
-
- /// <internalonly/>
- [System.Security.SecurityCritical] // auto-generated_required
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- static public void GetZoneAndOrigin( out ArrayList zone, out ArrayList origin )
- {
- StackCrawlMark mark = StackCrawlMark.LookForMyCaller;
- CodeAccessSecurityEngine.GetZoneAndOrigin( ref mark, out zone, out origin );
- }
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlPolicy )]
- [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
- static public PolicyLevel LoadPolicyLevelFromFile(string path, PolicyLevelType type)
- {
- if (path == null)
- throw new ArgumentNullException( "path" );
- Contract.EndContractBlock();
-
- if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
- }
-
- // We need to retain V1.x compatibility by throwing the same exception type.
- if (!File.InternalExists(path))
- throw new ArgumentException( Environment.GetResourceString("Argument_PolicyFileDoesNotExist"));
-
- String fullPath = Path.GetFullPath( path );
-
- FileIOPermission perm = new FileIOPermission( PermissionState.None );
- perm.AddPathList( FileIOPermissionAccess.Read, fullPath );
- perm.AddPathList( FileIOPermissionAccess.Write, fullPath );
- perm.Demand();
-
- using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read)) {
- using (StreamReader reader = new StreamReader(stream)) {
- return LoadPolicyLevelFromStringHelper(reader.ReadToEnd(), path, type);
- }
- }
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlPolicy )]
- [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
- static public PolicyLevel LoadPolicyLevelFromString(string str, PolicyLevelType type)
- {
- return LoadPolicyLevelFromStringHelper(str, null, type);
- }
-
- private static PolicyLevel LoadPolicyLevelFromStringHelper (string str, string path, PolicyLevelType type)
- {
- if (str == null)
- throw new ArgumentNullException( "str" );
- Contract.EndContractBlock();
-
- PolicyLevel level = new PolicyLevel(type, path);
-
- Parser parser = new Parser( str );
- SecurityElement elRoot = parser.GetTopElement();
- if (elRoot == null)
- throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Policy_BadXml" ), "configuration" ) );
-
- SecurityElement elMscorlib = elRoot.SearchForChildByTag( "mscorlib" );
- if (elMscorlib == null)
- throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Policy_BadXml" ), "mscorlib" ) );
-
- SecurityElement elSecurity = elMscorlib.SearchForChildByTag( "security" );
- if (elSecurity == null)
- throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Policy_BadXml" ), "security" ) );
-
- SecurityElement elPolicy = elSecurity.SearchForChildByTag( "policy" );
- if (elPolicy == null)
- throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Policy_BadXml" ), "policy" ) );
-
- SecurityElement elPolicyLevel = elPolicy.SearchForChildByTag( "PolicyLevel" );
- if (elPolicyLevel != null)
- level.FromXml( elPolicyLevel );
- else
- throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Policy_BadXml" ), "PolicyLevel" ) );
-
- return level;
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlPolicy )]
- [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
- static public void SavePolicyLevel( PolicyLevel level )
- {
- if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
- }
-
- PolicyManager.EncodeLevel( level );
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
- static public PermissionSet ResolvePolicy(Evidence evidence,
- PermissionSet reqdPset,
- PermissionSet optPset,
- PermissionSet denyPset,
- out PermissionSet denied)
- {
- if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
- }
-
- return ResolvePolicy(evidence, reqdPset, optPset, denyPset, out denied, true);
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
- static public PermissionSet ResolvePolicy(Evidence evidence)
- {
- if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
- }
-
- // If we aren't passed any evidence, just make an empty object
- if (evidence == null)
- {
- evidence = new Evidence();
- }
-
- return polmgr.Resolve(evidence);
- }
-
- [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
- static public PermissionSet ResolvePolicy( Evidence[] evidences )
- {
- if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
- }
-
- if (evidences == null || evidences.Length == 0)
- evidences = new Evidence[] { null };
-
- PermissionSet retval = ResolvePolicy( evidences[0] );
- if (retval == null)
- return null;
-
- for (int i = 1; i < evidences.Length; ++i)
- {
- retval = retval.Intersect( ResolvePolicy( evidences[i] ) );
- if (retval == null || retval.IsEmpty())
- return retval;
- }
-
- return retval;
- }
-
-#if FEATURE_CAS_POLICY
- // Determine if the current thread would require a security context capture if the security state of
- // the thread needs to be re-created at a later point in time. This can be used, for instance, if
- // sensitive data is being obtained after security demands succeed, and that data is to be cached.
- // If there is an Assert up the stack, then we wouldn't want to cache the data without capturing the
- // corresponding security context to go along with it - otherwise we risk leaking data obtained
- // under an assert to code which may no longer be running with that assert in place.
- //
- // A return value of false indicates that the CLR guarantees all of the following conditions are true:
- // 1. No partial trust AppDomains are on the stack
- // 2. No partial trust assemblies are on the stack
- // 3. There are no currently active PermitOnly or Deny modifiers on the stack
- //
- // A return value of true means only that the CLR cannot guarantee that all of the conditions are
- // true, and not that one of the conditions really is false.
- //
- // IMPORTANT: The above means is only reliable in the false return case. If we say that the thread
- // does not require a context capture, then that answer is guaranteed to be correct. However, we may
- // say that the thread does require a capture when it does not actually strictly need to capture the
- // state. This is fine, as being overly conservative when capturing context will not lead to
- // security holes; being overly agresssive in avoding the capture could lead to holes however.
- //
- // This API is SecurityCritical because its main use is to optimize away unnecessary security
- // context captures, which means that the code using it is security sensitive and needs to be audited.
- [SecurityCritical]
- public static bool CurrentThreadRequiresSecurityContextCapture()
- {
- // If we know that the thread is not made up of entirely full trust code, and that there are no
- // security stack modifiers on the thread, then there is no need to capture a security context.
- return !CodeAccessSecurityEngine.QuickCheckForAllDemands();
- }
-#endif // FEATURE_CAS_POLICY
-
- //
- // This method resolves the policy for the specified evidence, but it
- // ignores the AppDomain level even when one is available in the current policy.
- //
-
- [System.Security.SecuritySafeCritical] // auto-generated
- [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
- public static PermissionSet ResolveSystemPolicy (Evidence evidence)
- {
- if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
- }
-
- if (PolicyManager.IsGacAssembly(evidence))
- {
- return new PermissionSet(PermissionState.Unrestricted);
- }
-
- return polmgr.CodeGroupResolve(evidence, true);
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
- static public IEnumerator ResolvePolicyGroups(Evidence evidence)
- {
- if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
- }
-
- return polmgr.ResolveCodeGroups(evidence);
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
- public static IEnumerator PolicyHierarchy()
- {
- if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
- }
-
- return polmgr.PolicyHierarchy();
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlPolicy )]
- [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
- public static void SavePolicy()
- {
- if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
- }
-
- polmgr.Save();
- }
-
-
- [System.Security.SecurityCritical] // auto-generated
- private static PermissionSet ResolveCasPolicy(Evidence evidence,
- PermissionSet reqdPset,
- PermissionSet optPset,
- PermissionSet denyPset,
- out PermissionSet denied,
- out int securitySpecialFlags,
- bool checkExecutionPermission)
- {
- Contract.Assert(AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled);
-
- CodeAccessPermission.Assert(true);
-
- PermissionSet granted = ResolvePolicy(evidence,
- reqdPset,
- optPset,
- denyPset,
- out denied,
- checkExecutionPermission);
-
- securitySpecialFlags = SecurityManager.GetSpecialFlags(granted, denied);
- return granted;
- }
-
- [System.Security.SecurityCritical] // auto-generated
- static private PermissionSet ResolvePolicy(Evidence evidence,
- PermissionSet reqdPset,
- PermissionSet optPset,
- PermissionSet denyPset,
- out PermissionSet denied,
- bool checkExecutionPermission)
- {
- Contract.Assert(AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled);
-
- if (executionSecurityPermission == null)
- executionSecurityPermission = new SecurityPermission(SecurityPermissionFlag.Execution);
-
- PermissionSet requested = null;
- PermissionSet optional;
- PermissionSet allowed;
-
- Exception savedException = null;
-
- // We don't want to recurse back into here as a result of a
- // stackwalk during resolution. So simply assert full trust (this
- // implies that custom permissions cannot use any permissions that
- // don't implement IUnrestrictedPermission.
- // PermissionSet.s_fullTrust.Assert();
-
- // The requested set is the union of the minimal request and the
- // optional request. Minimal request defaults to empty, optional
- // is "AllPossible" (includes any permission that can be defined)
- // which is symbolized by null.
- optional = optPset;
-
- if (reqdPset == null)
- requested = optional;
- else
- // If optional is null, the requested set becomes null/"AllPossible".
- requested = optional == null ? null : reqdPset.Union(optional);
-
- // Make sure that the right to execute is requested (if this feature is
- // enabled).
-
- if (requested != null && !requested.IsUnrestricted())
- requested.AddPermission( executionSecurityPermission );
-
- // If we aren't passed any evidence, just make an empty object
- if (evidence == null)
- {
- evidence = new Evidence();
- }
-
- allowed = polmgr.Resolve(evidence);
- // Intersect the grant with the RequestOptional
- if (requested != null)
- allowed.InplaceIntersect(requested);
-
- // Check that we were granted the right to execute.
- if (checkExecutionPermission)
- {
- if (!allowed.Contains(executionSecurityPermission) ||
- (denyPset != null && denyPset.Contains(executionSecurityPermission)))
- {
- throw new PolicyException(Environment.GetResourceString("Policy_NoExecutionPermission"),
- System.__HResults.CORSEC_E_NO_EXEC_PERM,
- savedException);
- }
- }
-
- // Check that we were granted at least the minimal set we asked for. Do
- // this before pruning away any overlap with the refused set so that
- // users have the flexability of defining minimal permissions that are
- // only expressable as set differences (e.g. allow access to "C:\" but
- // disallow "C:\Windows").
- if (reqdPset != null && !reqdPset.IsSubsetOf(allowed))
- {
- BCLDebug.Assert(AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled, "Evaluating assembly level declarative security without legacy CAS policy enabled");
- throw new PolicyException(Environment.GetResourceString( "Policy_NoRequiredPermission" ),
- System.__HResults.CORSEC_E_MIN_GRANT_FAIL,
- savedException );
- }
-
- // Remove any granted permissions that are safe subsets of some denied
- // permission. The remaining denied permissions (if any) are returned
- // along with the modified grant set for use in checks.
- if (denyPset != null)
- {
- BCLDebug.Assert(AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled, "Evaluating assembly level declarative security without legacy CAS policy enabled");
- denied = denyPset.Copy();
- allowed.MergeDeniedSet(denied);
- if (denied.IsEmpty())
- denied = null;
- }
- else
- denied = null;
-
- allowed.IgnoreTypeLoadFailures = true;
-
- return allowed;
- }
-
- [Obsolete("Because execution permission checks can no longer be turned off, the CheckExecutionRights property no longer has any effect.")]
- static public bool CheckExecutionRights
- {
- get { return true; }
-
- set
- {
- // The setter for this property is a no-op since execution checking can no longer be turned off
- }
- }
-
- [Obsolete("Because security can no longer be turned off, the SecurityEnabled property no longer has any effect.")]
- public static bool SecurityEnabled
- {
- get { return true; }
-
- set
- {
- // The setter for this property is a no-op since security cannot be turned off
- }
- }
-#endif // #if FEATURE_CAS_POLICY
-
+ static public class SecurityManager
+ {
private static int[][] s_BuiltInPermissionIndexMap = {
new int[] { BuiltInPermissionIndex.EnvironmentPermissionIndex, (int) PermissionType.EnvironmentPermission },
new int[] { BuiltInPermissionIndex.FileDialogPermissionIndex, (int) PermissionType.FileDialogPermission },
@@ -653,17 +142,14 @@ namespace System.Security {
return flags;
}
#pragma warning restore 618
-
- [System.Security.SecurityCritical] // auto-generated
+
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal static extern bool IsSameType(String strLeft, String strRight);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool _SetThreadSecurity(bool bThreadSecurity);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal static extern void GetGrantedPermissions(ObjectHandleOnStack retGranted, ObjectHandleOnStack retDenied, StackCrawlMarkHandle stackMark);
diff --git a/src/mscorlib/src/System/Security/SecurityRuntime.cs b/src/mscorlib/src/System/Security/SecurityRuntime.cs
index 9d776affd3..d037fe939d 100644
--- a/src/mscorlib/src/System/Security/SecurityRuntime.cs
+++ b/src/mscorlib/src/System/Security/SecurityRuntime.cs
@@ -4,7 +4,8 @@
//
-namespace System.Security {
+namespace System.Security
+{
using System;
using System.Globalization;
using System.Threading;
@@ -26,7 +27,6 @@ namespace System.Security {
//
// Internal only, do not doc.
//
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern
FrameSecurityDescriptor GetSecurityObjectForFrame(ref StackCrawlMark stackMark,
@@ -37,7 +37,6 @@ namespace System.Security {
internal const bool StackHalt = false;
// this method is a big perf hit, so don't call unnecessarily
- [System.Security.SecurityCritical] // auto-generated
internal static MethodInfo GetMethodInfo(RuntimeMethodHandleInternal rmh)
{
if (rmh.IsNullHandle())
@@ -60,7 +59,6 @@ namespace System.Security {
#endif
}
- [System.Security.SecurityCritical] // auto-generated
private static bool FrameDescSetHelper(FrameSecurityDescriptor secDesc,
PermissionSet demandSet,
out PermissionSet alteredDemandSet,
@@ -69,7 +67,6 @@ namespace System.Security {
return secDesc.CheckSetDemand(demandSet, out alteredDemandSet, rmh);
}
- [System.Security.SecurityCritical] // auto-generated
private static bool FrameDescHelper(FrameSecurityDescriptor secDesc,
IPermission demandIn,
PermissionToken permToken,
@@ -79,7 +76,6 @@ namespace System.Security {
}
#if FEATURE_COMPRESSEDSTACK
- [System.Security.SecurityCritical]
private static bool CheckDynamicMethodSetHelper(System.Reflection.Emit.DynamicResolver dynamicResolver,
PermissionSet demandSet,
out PermissionSet alteredDemandSet,
@@ -99,7 +95,6 @@ namespace System.Security {
return result;
}
- [System.Security.SecurityCritical]
private static bool CheckDynamicMethodHelper(System.Reflection.Emit.DynamicResolver dynamicResolver,
IPermission demandIn,
PermissionToken permToken,
@@ -122,176 +117,41 @@ namespace System.Security {
//
// API for PermissionSets
//
-
- [System.Security.SecurityCritical] // auto-generated
+
internal static void Assert(PermissionSet permSet, ref StackCrawlMark stackMark)
{
-#if FEATURE_CAS_POLICY
- // Note: if the "AssertPermission" is not a permission that implements IUnrestrictedPermission
- // you need to change the fourth parameter to a zero.
- FrameSecurityDescriptor secObj = CodeAccessSecurityEngine.CheckNReturnSO(
- CodeAccessSecurityEngine.AssertPermissionToken,
- CodeAccessSecurityEngine.AssertPermission,
- ref stackMark,
- 1 );
-
- Contract.Assert(secObj != null,"Failure in SecurityRuntime.Assert() - secObj != null");
- if (secObj == null)
- {
- // Security: REQ_SQ flag is missing. Bad compiler ?
- System.Environment.FailFast(Environment.GetResourceString("ExecutionEngine_MissingSecurityDescriptor"));
- }
- else
- {
- if (secObj.HasImperativeAsserts())
- throw new SecurityException( Environment.GetResourceString( "Security_MustRevertOverride" ) );
-
- secObj.SetAssert(permSet);
- }
-#endif // FEATURE_CAS_POLICY
}
-
- [System.Security.SecurityCritical] // auto-generated
+
internal static void AssertAllPossible(ref StackCrawlMark stackMark)
{
-#if FEATURE_CAS_POLICY
- FrameSecurityDescriptor secObj =
- SecurityRuntime.GetSecurityObjectForFrame(ref stackMark, true);
-
- Contract.Assert(secObj != null, "Failure in SecurityRuntime.AssertAllPossible() - secObj != null");
- if (secObj == null)
- {
- // Security: REQ_SQ flag is missing. Bad compiler ?
- System.Environment.FailFast(Environment.GetResourceString("ExecutionEngine_MissingSecurityDescriptor"));
- }
- else
- {
- if (secObj.GetAssertAllPossible())
- throw new SecurityException( Environment.GetResourceString( "Security_MustRevertOverride" ) );
-
- secObj.SetAssertAllPossible();
- }
-#endif // FEATURE_CAS_POLICY
}
-
- [System.Security.SecurityCritical] // auto-generated
+
internal static void Deny(PermissionSet permSet, ref StackCrawlMark stackMark)
{
-#if FEATURE_CAS_POLICY
- // Deny is only valid in legacy mode
- if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_CasDeny"));
- }
-
- FrameSecurityDescriptor secObj =
- SecurityRuntime.GetSecurityObjectForFrame(ref stackMark, true);
-
- Contract.Assert(secObj != null, "Failure in SecurityRuntime.Deny() - secObj != null");
- if (secObj == null)
- {
- // Security: REQ_SQ flag is missing. Bad compiler ?
- System.Environment.FailFast(Environment.GetResourceString("ExecutionEngine_MissingSecurityDescriptor"));
- }
- else
- {
- if (secObj.HasImperativeDenials())
- throw new SecurityException( Environment.GetResourceString( "Security_MustRevertOverride" ) );
-
- secObj.SetDeny(permSet);
- }
-#endif // FEATURE_CAS_POLICY
}
-
- [System.Security.SecurityCritical] // auto-generated
+
internal static void PermitOnly(PermissionSet permSet, ref StackCrawlMark stackMark)
{
-#if FEATURE_CAS_POLICY
- FrameSecurityDescriptor secObj =
- SecurityRuntime.GetSecurityObjectForFrame(ref stackMark, true);
-
- Contract.Assert(secObj != null, "Failure in SecurityRuntime.PermitOnly() - secObj != null");
- if (secObj == null)
- {
- // Security: REQ_SQ flag is missing. Bad compiler ?
- System.Environment.FailFast(Environment.GetResourceString("ExecutionEngine_MissingSecurityDescriptor"));
- }
- else
- {
- if (secObj.HasImperativeRestrictions())
- throw new SecurityException( Environment.GetResourceString( "Security_MustRevertOverride" ) );
-
- secObj.SetPermitOnly(permSet);
- }
-#endif // FEATURE_CAS_POLICY
}
-
+
//
// Revert API
//
-
- [System.Security.SecurityCritical] // auto-generated
+
internal static void RevertAssert(ref StackCrawlMark stackMark)
{
-#if FEATURE_CAS_POLICY
- FrameSecurityDescriptor secObj = GetSecurityObjectForFrame(ref stackMark, false);
- if (secObj != null)
- {
- secObj.RevertAssert();
- }
- else
- {
- throw new InvalidOperationException(Environment.GetResourceString("ExecutionEngine_MissingSecurityDescriptor"));
- }
-#endif // FEATURE_CAS_POLICY
}
- [System.Security.SecurityCritical] // auto-generated
internal static void RevertDeny(ref StackCrawlMark stackMark)
{
-#if FEATURE_CAS_POLICY
- FrameSecurityDescriptor secObj = GetSecurityObjectForFrame(ref stackMark, false);
- if (secObj != null)
- {
- secObj.RevertDeny();
- }
- else
- {
- throw new InvalidOperationException(Environment.GetResourceString("ExecutionEngine_MissingSecurityDescriptor"));
- }
-#endif // FEATURE_CAS_POLICY
}
- [System.Security.SecurityCritical] // auto-generated
internal static void RevertPermitOnly(ref StackCrawlMark stackMark)
{
-#if FEATURE_CAS_POLICY
- FrameSecurityDescriptor secObj = GetSecurityObjectForFrame(ref stackMark, false);
- if (secObj != null)
- {
- secObj.RevertPermitOnly();
- }
- else
- {
- throw new InvalidOperationException(Environment.GetResourceString("ExecutionEngine_MissingSecurityDescriptor"));
- }
-#endif // FEATURE_CAS_POLICY
}
- [System.Security.SecurityCritical] // auto-generated
internal static void RevertAll(ref StackCrawlMark stackMark)
{
-#if FEATURE_CAS_POLICY
- FrameSecurityDescriptor secObj = GetSecurityObjectForFrame(ref stackMark, false);
- if (secObj != null)
- {
- secObj.RevertAll();
- }
- else
- {
- throw new InvalidOperationException(Environment.GetResourceString("ExecutionEngine_MissingSecurityDescriptor"));
- }
-#endif // FEATURE_CAS_POLICY
}
}
}
diff --git a/src/mscorlib/src/System/Security/SecurityState.cs b/src/mscorlib/src/System/Security/SecurityState.cs
index bd23acd813..3c7f8bf49f 100644
--- a/src/mscorlib/src/System/Security/SecurityState.cs
+++ b/src/mscorlib/src/System/Security/SecurityState.cs
@@ -7,25 +7,17 @@ using System.Security.Permissions;
namespace System.Security
{
- [System.Security.SecurityCritical] // auto-generated_required
-#pragma warning disable 618
- [PermissionSet(SecurityAction.InheritanceDemand, Unrestricted = true)]
-#pragma warning restore 618
public abstract class SecurityState
{
protected SecurityState(){}
- [System.Security.SecurityCritical] // auto-generated
public bool IsStateAvailable()
{
AppDomainManager domainManager = AppDomainManager.CurrentAppDomainManager;
-#if FEATURE_CORECLR
+
// 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;
-#else
- return domainManager != null ? domainManager.CheckSecuritySettings(this) : false;
-#endif
}
// override this function and throw the appropriate
public abstract void EnsureState();
diff --git a/src/mscorlib/src/System/Security/Util/Config.cs b/src/mscorlib/src/System/Security/Util/Config.cs
index 988a39a9d6..afc9b8c336 100644
--- a/src/mscorlib/src/System/Security/Util/Config.cs
+++ b/src/mscorlib/src/System/Security/Util/Config.cs
@@ -37,7 +37,6 @@ namespace System.Security.Util {
private static volatile string m_machineConfig;
private static volatile string m_userConfig;
- [System.Security.SecurityCritical] // auto-generated
private static void GetFileLocales()
{
if (m_machineConfig == null)
@@ -56,7 +55,6 @@ namespace System.Security.Util {
internal static string MachineDirectory
{
- [System.Security.SecurityCritical] // auto-generated
get
{
GetFileLocales();
@@ -66,7 +64,6 @@ namespace System.Security.Util {
internal static string UserDirectory
{
- [System.Security.SecurityCritical] // auto-generated
get
{
GetFileLocales();
@@ -74,57 +71,12 @@ namespace System.Security.Util {
}
}
-#if FEATURE_CAS_POLICY
- [System.Security.SecurityCritical] // auto-generated
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
- internal static extern int SaveDataByte(string path, [In] byte[] data, int length);
-
- [System.Security.SecurityCritical] // auto-generated
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
- internal static extern bool RecoverData(ConfigId id);
-
- [System.Security.SecurityCritical] // auto-generated
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
- internal static extern void SetQuickCache(ConfigId id, QuickCacheEntryType quickCacheFlags);
-
- [System.Security.SecurityCritical] // auto-generated
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
- private static extern bool GetCacheEntry(ConfigId id, int numKey, [In] byte[] key, int keyLength, ObjectHandleOnStack retData);
-
- [System.Security.SecurityCritical] // auto-generated
- internal static bool GetCacheEntry(ConfigId id, int numKey, byte[] key, out byte[] data)
- {
- byte[] retData = null;
- bool ret = GetCacheEntry(id, numKey, key, key.Length, JitHelpers.GetObjectHandleOnStack(ref retData));
-
- data = retData;
- return ret;
- }
-
- [System.Security.SecurityCritical] // auto-generated
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
- private static extern void AddCacheEntry(ConfigId id, int numKey, [In] byte[] key, int keyLength, byte[] data, int dataLength);
-
- [System.Security.SecurityCritical] // auto-generated
- internal static void AddCacheEntry(ConfigId id, int numKey, byte[] key, byte[] data)
- {
- AddCacheEntry(id, numKey, key, key.Length, data, data.Length);
- }
-
- [System.Security.SecurityCritical] // auto-generated
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
- internal static extern void ResetCacheData(ConfigId id);
-#endif
-
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
private static extern void GetMachineDirectory(StringHandleOnStack retDirectory);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
private static extern void GetUserDirectory(StringHandleOnStack retDirectory);
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
internal static extern bool WriteToEventLog(string message);
}
diff --git a/src/mscorlib/src/System/Security/Util/Hex.cs b/src/mscorlib/src/System/Security/Util/Hex.cs
index 709744f2a2..4ca1cf678b 100644
--- a/src/mscorlib/src/System/Security/Util/Hex.cs
+++ b/src/mscorlib/src/System/Security/Util/Hex.cs
@@ -73,7 +73,7 @@ namespace System.Security.Util
public static byte[] DecodeHexString(String hexString)
{
if (hexString == null)
- throw new ArgumentNullException( "hexString" );
+ throw new ArgumentNullException( nameof(hexString) );
Contract.EndContractBlock();
bool spaceSkippingMode = false;
diff --git a/src/mscorlib/src/System/Security/Util/StringExpressionSet.cs b/src/mscorlib/src/System/Security/Util/StringExpressionSet.cs
index 19937f5ae6..8a12235106 100644
--- a/src/mscorlib/src/System/Security/Util/StringExpressionSet.cs
+++ b/src/mscorlib/src/System/Security/Util/StringExpressionSet.cs
@@ -12,6 +12,7 @@ namespace System.Security.Util {
using System.Globalization;
using System.Runtime.Versioning;
using System.IO;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
[Serializable]
@@ -26,12 +27,9 @@ namespace System.Security.Util {
// 2. Ensuring that the partial trust code has permission to see full path data
// 3. Not using this set for paths (eg EnvironmentStringExpressionSet)
//
- [SecurityCritical]
protected ArrayList m_list;
protected bool m_ignoreCase;
- [SecurityCritical]
protected String m_expressions;
- [SecurityCritical]
protected String[] m_expressionsArray;
protected bool m_throwOnRelative;
@@ -61,7 +59,6 @@ namespace System.Security.Util {
{
}
- [System.Security.SecuritySafeCritical] // auto-generated
public StringExpressionSet( bool ignoreCase, String str, bool throwOnRelative )
{
m_list = null;
@@ -78,7 +75,6 @@ namespace System.Security.Util {
return new StringExpressionSet();
}
- [SecuritySafeCritical]
public virtual StringExpressionSet Copy()
{
// SafeCritical: just copying this value around, not leaking it
@@ -118,11 +114,10 @@ namespace System.Security.Util {
return StaticProcessSingleString(str);
}
- [System.Security.SecurityCritical] // auto-generated
public void AddExpressions( String str )
{
if (str == null)
- throw new ArgumentNullException( "str" );
+ throw new ArgumentNullException( nameof(str) );
Contract.EndContractBlock();
if (str.Length == 0)
return;
@@ -165,7 +160,7 @@ namespace System.Security.Util {
{
if (m_throwOnRelative)
{
- if (Path.IsRelative(temp))
+ if (PathInternal.IsPartiallyQualified(temp))
{
throw new ArgumentException( Environment.GetResourceString( "Argument_AbsolutePathRequired" ) );
}
@@ -181,16 +176,14 @@ namespace System.Security.Util {
Reduce();
}
- [System.Security.SecurityCritical] // auto-generated
public void AddExpressions( String[] str, bool checkForDuplicates, bool needFullPath )
{
AddExpressions(CreateListFromExpressions(str, needFullPath), checkForDuplicates);
}
- [System.Security.SecurityCritical] // auto-generated
public void AddExpressions( ArrayList exprArrayList, bool checkForDuplicates)
{
- Contract.Assert( m_throwOnRelative, "This should only be called when throw on relative is set" );
+ Debug.Assert( m_throwOnRelative, "This should only be called when throw on relative is set" );
m_expressionsArray = null;
m_expressions = null;
@@ -205,19 +198,18 @@ namespace System.Security.Util {
}
- [System.Security.SecurityCritical] // auto-generated
internal static ArrayList CreateListFromExpressions(String[] str, bool needFullPath)
{
if (str == null)
{
- throw new ArgumentNullException( "str" );
+ throw new ArgumentNullException( nameof(str) );
}
Contract.EndContractBlock();
ArrayList retArrayList = new ArrayList();
for (int index = 0; index < str.Length; ++index)
{
if (str[index] == null)
- throw new ArgumentNullException( "str" );
+ throw new ArgumentNullException( nameof(str) );
// Replace alternate directory separators
String oneString = StaticProcessWholeString( str[index] );
@@ -249,7 +241,6 @@ namespace System.Security.Util {
return retArrayList;
}
- [System.Security.SecurityCritical] // auto-generated
protected void CheckList()
{
if (m_list == null && m_expressions != null)
@@ -303,7 +294,6 @@ namespace System.Security.Util {
}
- [System.Security.SecurityCritical] // auto-generated
protected void CreateList()
{
String[] expressionsArray = Split( m_expressions );
@@ -325,7 +315,7 @@ namespace System.Security.Util {
{
if (m_throwOnRelative)
{
- if (Path.IsRelative(temp))
+ if (PathInternal.IsPartiallyQualified(temp))
{
throw new ArgumentException( Environment.GetResourceString( "Argument_AbsolutePathRequired" ) );
}
@@ -339,7 +329,6 @@ namespace System.Security.Util {
}
}
- [SecuritySafeCritical]
public bool IsEmpty()
{
// SafeCritical: we're just showing that the expressions are empty, the sensitive portion is their
@@ -354,7 +343,6 @@ namespace System.Security.Util {
}
}
- [System.Security.SecurityCritical] // auto-generated
public bool IsSubsetOf( StringExpressionSet ses )
{
if (this.IsEmpty())
@@ -376,7 +364,6 @@ namespace System.Security.Util {
return true;
}
- [System.Security.SecurityCritical] // auto-generated
public bool IsSubsetOfPathDiscovery( StringExpressionSet ses )
{
if (this.IsEmpty())
@@ -399,7 +386,6 @@ namespace System.Security.Util {
}
- [System.Security.SecurityCritical] // auto-generated
public StringExpressionSet Union( StringExpressionSet ses )
{
// If either set is empty, the union represents a copy of the other.
@@ -434,7 +420,6 @@ namespace System.Security.Util {
}
- [System.Security.SecurityCritical] // auto-generated
public StringExpressionSet Intersect( StringExpressionSet ses )
{
// If either set is empty, the intersection is empty
@@ -477,7 +462,6 @@ namespace System.Security.Util {
return intersectSet;
}
- [SecuritySafeCritical]
protected void GenerateString()
{
// SafeCritical - moves critical data around, but doesn't expose it out
@@ -522,7 +506,6 @@ namespace System.Security.Util {
// expressions contain paths that were canonicalized and expanded from the input that would cause
// information disclosure, so we instead only expose this out to trusted code that can ensure they
// either don't leak the information or required full path information.
- [SecurityCritical]
public string UnsafeToString()
{
CheckList();
@@ -534,7 +517,6 @@ namespace System.Security.Util {
return m_expressions;
}
- [SecurityCritical]
public String[] UnsafeToStringArray()
{
if (m_expressionsArray == null && m_list != null)
@@ -550,7 +532,6 @@ namespace System.Security.Util {
// protected static helper functions
//-------------------------------
- [SecurityCritical]
private bool StringSubsetStringExpression( String left, StringExpressionSet right, bool ignoreCase )
{
for (int index = 0; index < right.m_list.Count; ++index)
@@ -563,7 +544,6 @@ namespace System.Security.Util {
return false;
}
- [SecurityCritical]
private static bool StringSubsetStringExpressionPathDiscovery( String left, StringExpressionSet right, bool ignoreCase )
{
for (int index = 0; index < right.m_list.Count; ++index)
@@ -661,7 +641,6 @@ namespace System.Security.Util {
// protected helper functions
//-------------------------------
- [SecuritySafeCritical]
protected void AddSingleExpressionNoDuplicates( String expression )
{
// SafeCritical: We're not exposing out the string sets, just allowing modification of them
@@ -691,7 +670,6 @@ namespace System.Security.Util {
this.m_list.Add( expression );
}
- [System.Security.SecurityCritical] // auto-generated
protected void Reduce()
{
CheckList();
@@ -726,23 +704,20 @@ namespace System.Security.Util {
}
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal static extern void GetLongPathName( String path, StringHandleOnStack retLongPath );
- [System.Security.SecurityCritical] // auto-generated
internal static String CanonicalizePath( String path )
{
return CanonicalizePath( path, true );
}
- [System.Security.SecurityCritical] // auto-generated
internal static string CanonicalizePath(string path, bool needFullPath)
{
if (needFullPath)
{
- string newPath = Path.GetFullPathInternal(path);
+ string newPath = Path.GetFullPath(path);
if (path.EndsWith(m_directorySeparator + ".", StringComparison.Ordinal))
{
if (newPath.EndsWith(m_directorySeparator))
diff --git a/src/mscorlib/src/System/Security/Util/TokenBasedSet.cs b/src/mscorlib/src/System/Security/Util/TokenBasedSet.cs
index 590a909662..8589fa7c42 100644
--- a/src/mscorlib/src/System/Security/Util/TokenBasedSet.cs
+++ b/src/mscorlib/src/System/Security/Util/TokenBasedSet.cs
@@ -9,6 +9,7 @@ namespace System.Security.Util
using System.Security.Permissions;
using System.Runtime.Serialization;
using System.Threading;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Diagnostics.CodeAnalysis;
@@ -368,31 +369,17 @@ namespace System.Security.Util
{
Object thisObj = this.GetItem( i );
IPermission thisPerm = thisObj as IPermission;
-#if FEATURE_CAS_POLICY
- ISecurityElementFactory thisElem = thisObj as ISecurityElementFactory;
-#endif // FEATURE_CAS_POLICY
Object otherObj = (other != null)?other.GetItem( i ):null;
IPermission otherPerm = otherObj as IPermission;
-#if FEATURE_CAS_POLICY
- ISecurityElementFactory otherElem = otherObj as ISecurityElementFactory;
-#endif // FEATURE_CAS_POLICY
if (thisObj == null && otherObj == null)
continue;
-
-
+
if (thisObj == null)
{
-#if FEATURE_CAS_POLICY
- if (otherElem != null)
- {
- otherPerm = PermissionSet.CreatePerm(otherElem, false);
- }
-#endif // FEATURE_CAS_POLICY
-
PermissionToken token = PermissionToken.GetToken(otherPerm);
-
+
if (token == null)
{
throw new SerializationException(Environment.GetResourceString("Serialization_InsufficientState"));
@@ -402,13 +389,6 @@ namespace System.Security.Util
}
else if (otherObj == null)
{
-#if FEATURE_CAS_POLICY
- if (thisElem != null)
- {
- thisPerm = PermissionSet.CreatePerm(thisElem, false);
- }
-#endif // FEATURE_CAS_POLICY
-
PermissionToken token = PermissionToken.GetToken(thisPerm);
if (token == null)
{
@@ -418,7 +398,7 @@ namespace System.Security.Util
}
else
{
- Contract.Assert( (thisObj == null || otherObj == null), "Permission cannot be in both TokenBasedSets" );
+ Debug.Assert( (thisObj == null || otherObj == null), "Permission cannot be in both TokenBasedSets" );
}
}
return unionSet;
@@ -434,10 +414,6 @@ namespace System.Security.Util
if (obj != null)
{
IPermission perm = obj as IPermission;
-#if FEATURE_CAS_POLICY
- if (perm == null)
- perm = PermissionSet.CreatePerm(obj, ignoreTypeLoadFailures);
-#endif // FEATURE_CAS_POLICY
PermissionToken token = PermissionToken.GetToken(perm);
if (perm == null || token == null)
diff --git a/src/mscorlib/src/System/Security/Util/URLString.cs b/src/mscorlib/src/System/Security/Util/URLString.cs
index 51ae24cf4a..83f9ce483f 100644
--- a/src/mscorlib/src/System/Security/Util/URLString.cs
+++ b/src/mscorlib/src/System/Security/Util/URLString.cs
@@ -484,10 +484,11 @@ namespace System.Security.Util {
private static void CheckPathTooLong(StringBuilder path)
{
if (path.Length >= (
-#if FEATURE_PATHCOMPAT
- AppContextSwitches.BlockLongPaths ? PathInternal.MaxShortPath :
-#endif
+#if PLATFORM_UNIX
+ Interop.Sys.MaxPath))
+#else
PathInternal.MaxLongPath))
+#endif
{
throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
}
@@ -513,7 +514,7 @@ namespace System.Security.Util {
// file:/home/johndoe/here
// file:../johndoe/here
// file:~/johndoe/here
- String temp = url;
+ String temp = url;
int nbSlashes = 0;
while(nbSlashes<temp.Length && '/'==temp[nbSlashes])
nbSlashes++;
@@ -533,7 +534,7 @@ namespace System.Security.Util {
{
String temp = url;
-#if !PLATFORM_UNIX
+#if !PLATFORM_UNIX
int index = temp.IndexOf( '/');
if (index != -1 &&
@@ -651,7 +652,7 @@ namespace System.Security.Util {
}
else
{
-#if !PLATFORM_UNIX
+#if !PLATFORM_UNIX
String site = temp.Substring( 0, index );
m_localSite = null;
m_siteString = new SiteString( site );
@@ -680,7 +681,7 @@ namespace System.Security.Util {
{
if (url == null)
{
- throw new ArgumentNullException( "url" );
+ throw new ArgumentNullException( nameof(url) );
}
Contract.EndContractBlock();
@@ -1127,7 +1128,6 @@ namespace System.Security.Util {
}
#if !PLATFORM_UNIX
- [System.Security.SecuritySafeCritical] // auto-generated
internal URLString SpecialNormalizeUrl()
{
// Under WinXP, file protocol urls can be mapped to
@@ -1177,7 +1177,6 @@ namespace System.Security.Util {
}
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void GetDeviceName( String driveLetter, StringHandleOnStack retDeviceName );
diff --git a/src/mscorlib/src/System/Security/Util/XMLUtil.cs b/src/mscorlib/src/System/Security/Util/XMLUtil.cs
index df8f0c4670..3a1aaa3b09 100644
--- a/src/mscorlib/src/System/Security/Util/XMLUtil.cs
+++ b/src/mscorlib/src/System/Security/Util/XMLUtil.cs
@@ -25,6 +25,7 @@ namespace System.Security.Util {
using System.Threading;
using System.Globalization;
using System.Reflection;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
internal static class XMLUtil
@@ -35,12 +36,7 @@ namespace System.Security.Util {
//
private const String BuiltInPermission = "System.Security.Permissions.";
-#if FEATURE_CAS_POLICY
- private const String BuiltInMembershipCondition = "System.Security.Policy.";
- private const String BuiltInCodeGroup = "System.Security.Policy.";
- private const String BuiltInApplicationSecurityManager = "System.Security.Policy.";
- private static readonly char[] sepChar = {',', ' '};
-#endif
+
public static SecurityElement
NewPermissionElement (IPermission ip)
{
@@ -66,7 +62,7 @@ namespace System.Security.Util {
if ( typename == null )
typename = type.FullName;
- Contract.Assert( type.FullName.Equals( typename ), "Incorrect class name passed! Was : " + typename + " Shoule be: " + type.FullName);
+ Debug.Assert( type.FullName.Equals( typename ), "Incorrect class name passed! Was : " + typename + " Shoule be: " + type.FullName);
element.AddAttribute( "class", typename + ", " + type.Module.Assembly.FullName.Replace( '\"', '\'' ) );
}
@@ -110,7 +106,6 @@ namespace System.Security.Util {
assemblyVersion = an.Version.ToString();
return true;
}
- [System.Security.SecurityCritical] // auto-generated
private static bool
ParseElementForObjectCreation( SecurityElement el,
String requiredNamespace,
@@ -175,29 +170,6 @@ namespace System.Security.Util {
return false;
}
-#if FEATURE_CAS_POLICY
- public static String SecurityObjectToXmlString(Object ob)
- {
- if(ob == null)
- return "";
- PermissionSet pset = ob as PermissionSet;
- if(pset != null)
- return pset.ToXml().ToString();
- return ((IPermission)ob).ToXml().ToString();
- }
-
- [System.Security.SecurityCritical] // auto-generated
- public static Object XmlStringToSecurityObject(String s)
- {
- if(s == null)
- return null;
- if(s.Length < 1)
- return null;
- return SecurityElement.FromString(s).ToSecurityObject();
- }
-#endif // FEATURE_CAS_POLICY
-
- [SecuritySafeCritical]
public static IPermission
CreatePermission (SecurityElement el, PermissionState permState, bool ignoreTypeLoadFailures)
{
@@ -235,9 +207,6 @@ namespace System.Security.Util {
// UnsafeForHostPermission
// HostProtectionPermission
// StrongNameIdentityPermission
-#if !FEATURE_CORECLR
- // IsolatedStorageFilePermission
-#endif
// RegistryPermission
// PublisherIdentityPermission
@@ -274,15 +243,6 @@ namespace System.Security.Util {
else
goto USEREFLECTION;
}
-
-#if !FEATURE_CORECLR
- case 19:
- // PrincipalPermission
- if (String.Compare(className, classNameStart, "PrincipalPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
- return new PrincipalPermission( permState );
- else
- goto USEREFLECTION;
-#endif // !FEATURE_CORECLR
case 20:
// ReflectionPermission
// FileDialogPermission
@@ -326,8 +286,6 @@ namespace System.Security.Util {
else
goto USEREFLECTION;
}
-
-
case 22:
// SiteIdentityPermission
// ZoneIdentityPermission
@@ -353,42 +311,22 @@ namespace System.Security.Util {
else
goto USEREFLECTION;
}
-
-
case 24:
// HostProtectionPermission
if (String.Compare(className, classNameStart, "HostProtectionPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
return new HostProtectionPermission( permState );
else
goto USEREFLECTION;
-
-#if FEATURE_X509 && FEATURE_CAS_POLICY
- case 27:
- // PublisherIdentityPermission
- if (String.Compare(className, classNameStart, "PublisherIdentityPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
- return new PublisherIdentityPermission( permState );
- else
- goto USEREFLECTION;
-#endif // FEATURE_X509 && FEATURE_CAS_POLICY
-
case 28:
// StrongNameIdentityPermission
if (String.Compare(className, classNameStart, "StrongNameIdentityPermission", 0, classNameLength, StringComparison.Ordinal) == 0)
return new StrongNameIdentityPermission( permState );
else
goto USEREFLECTION;
-#if !FEATURE_CORECLR
- case 29:
- // IsolatedStorageFilePermission
- if (String.Compare(className, classNameStart, "IsolatedStorageFilePermission", 0, classNameLength, StringComparison.Ordinal) == 0)
- return new IsolatedStorageFilePermission( permState );
- else
- goto USEREFLECTION;
-#endif
default:
goto USEREFLECTION;
}
-
+
USEREFLECTION:
Object[] objs = new Object[1];
@@ -409,204 +347,6 @@ USEREFLECTION:
return perm;
}
-#if FEATURE_CAS_POLICY
-#pragma warning disable 618 // CodeGroups are obsolete
- [System.Security.SecuritySafeCritical] // auto-generated
- public static CodeGroup
- CreateCodeGroup (SecurityElement el)
- {
- if (el == null || !el.Tag.Equals("CodeGroup"))
- throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Argument_WrongElementType" ), "<CodeGroup>" ) ) ;
- Contract.EndContractBlock();
-
- String className;
- int classNameLength;
- int classNameStart;
-
- if (!ParseElementForObjectCreation( el,
- BuiltInCodeGroup,
- out className,
- out classNameStart,
- out classNameLength ))
- {
- goto USEREFLECTION;
- }
-
- switch (classNameLength)
- {
- case 12:
- // NetCodeGroup
- if (String.Compare(className, classNameStart, "NetCodeGroup", 0, classNameLength, StringComparison.Ordinal) == 0)
- return new NetCodeGroup();
- else
- goto USEREFLECTION;
-
- case 13:
- // FileCodeGroup
- if (String.Compare(className, classNameStart, "FileCodeGroup", 0, classNameLength, StringComparison.Ordinal) == 0)
- return new FileCodeGroup();
- else
- goto USEREFLECTION;
- case 14:
- // UnionCodeGroup
- if (String.Compare(className, classNameStart, "UnionCodeGroup", 0, classNameLength, StringComparison.Ordinal) == 0)
- return new UnionCodeGroup();
- else
- goto USEREFLECTION;
-
- case 19:
- // FirstMatchCodeGroup
- if (String.Compare(className, classNameStart, "FirstMatchCodeGroup", 0, classNameLength, StringComparison.Ordinal) == 0)
- return new FirstMatchCodeGroup();
- else
- goto USEREFLECTION;
-
- default:
- goto USEREFLECTION;
- }
-
-USEREFLECTION:
- Type groupClass = null;
- CodeGroup group = null;
-
- new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Assert();
- groupClass = GetClassFromElement(el, true);
- if (groupClass == null)
- return null;
- if (!(typeof(CodeGroup).IsAssignableFrom(groupClass)))
- throw new ArgumentException( Environment.GetResourceString("Argument_NotACodeGroupType") );
-
- group = (CodeGroup) Activator.CreateInstance(groupClass, true);
-
- Contract.Assert( groupClass.Module.Assembly != Assembly.GetExecutingAssembly(),
- "This path should not get called for mscorlib based classes" );
-
- return group;
- }
-#pragma warning restore 618
-
- [System.Security.SecurityCritical] // auto-generated
- internal static IMembershipCondition
- CreateMembershipCondition( SecurityElement el )
- {
- if (el == null || !el.Tag.Equals("IMembershipCondition"))
- throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Argument_WrongElementType" ), "<IMembershipCondition>" ) ) ;
- Contract.EndContractBlock();
-
- String className;
- int classNameStart;
- int classNameLength;
-
- if (!ParseElementForObjectCreation( el,
- BuiltInMembershipCondition,
- out className,
- out classNameStart,
- out classNameLength ))
- {
- goto USEREFLECTION;
- }
-
- // We have a built in membership condition, figure out which it is.
-
- // Here's the list of built in membership conditions as of 9/17/2002
- // System.Security.Policy.AllMembershipCondition
- // System.Security.Policy.URLMembershipCondition
- // System.Security.Policy.SHA1MembershipCondition
- // System.Security.Policy.SiteMembershipCondition
- // System.Security.Policy.ZoneMembershipCondition
- // System.Security.Policy.PublisherMembershipCondition
- // System.Security.Policy.StrongNameMembershipCondition
- // System.Security.Policy.ApplicationMembershipCondition
- // System.Security.Policy.DomainApplicationMembershipCondition
- // System.Security.Policy.ApplicationDirectoryMembershipCondition
-
- switch (classNameLength)
- {
- case 22:
- // AllMembershipCondition
- // URLMembershipCondition
- if (className[classNameStart] == 'A')
- {
- if (String.Compare(className, classNameStart, "AllMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0)
- return new AllMembershipCondition();
- else
- goto USEREFLECTION;
- }
- else
- {
- if (String.Compare(className, classNameStart, "UrlMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0)
- return new UrlMembershipCondition();
- else
- goto USEREFLECTION;
- }
-
- case 23:
- // HashMembershipCondition
- // SiteMembershipCondition
- // ZoneMembershipCondition
- if (className[classNameStart] == 'H')
- {
- if (String.Compare(className, classNameStart, "HashMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0)
- return new HashMembershipCondition();
- else
- goto USEREFLECTION;
- }
- else if (className[classNameStart] == 'S')
- {
- if (String.Compare(className, classNameStart, "SiteMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0)
- return new SiteMembershipCondition();
- else
- goto USEREFLECTION;
- }
- else
- {
- if (String.Compare(className, classNameStart, "ZoneMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0)
- return new ZoneMembershipCondition();
- else
- goto USEREFLECTION;
- }
-
- case 28:
- // PublisherMembershipCondition
- if (String.Compare(className, classNameStart, "PublisherMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0)
- return new PublisherMembershipCondition();
- else
- goto USEREFLECTION;
-
- case 29:
- // StrongNameMembershipCondition
- if (String.Compare(className, classNameStart, "StrongNameMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0)
- return new StrongNameMembershipCondition();
- else
- goto USEREFLECTION;
-
- case 39:
- // ApplicationDirectoryMembershipCondition
- if (String.Compare(className, classNameStart, "ApplicationDirectoryMembershipCondition", 0, classNameLength, StringComparison.Ordinal) == 0)
- return new ApplicationDirectoryMembershipCondition();
- else
- goto USEREFLECTION;
-
- default:
- goto USEREFLECTION;
- }
-
-USEREFLECTION:
- Type condClass = null;
- IMembershipCondition cond = null;
-
- new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Assert();
- condClass = GetClassFromElement(el, true);
- if (condClass == null)
- return null;
- if (!(typeof(IMembershipCondition).IsAssignableFrom(condClass)))
- throw new ArgumentException( Environment.GetResourceString("Argument_NotAMembershipCondition") );
-
- cond = (IMembershipCondition) Activator.CreateInstance(condClass, true);
-
- return cond;
- }
-#endif //#if FEATURE_CAS_POLICY
internal static Type
GetClassFromElement (SecurityElement el, bool ignoreTypeLoadFailures)
{
@@ -624,7 +364,7 @@ USEREFLECTION:
{
try
{
- return Type.GetType(className, false, false);
+ return Type.GetType(className, false, false);
}
catch (SecurityException)
{
@@ -632,7 +372,7 @@ USEREFLECTION:
}
}
else
- return Type.GetType(className, true, false);
+ return Type.GetType(className, true, false);
}
public static bool
diff --git a/src/mscorlib/src/System/Security/securestring.cs b/src/mscorlib/src/System/Security/securestring.cs
index b53d0db5b4..548126f4d0 100644
--- a/src/mscorlib/src/System/Security/securestring.cs
+++ b/src/mscorlib/src/System/Security/securestring.cs
@@ -14,6 +14,7 @@ namespace System.Security {
using System.Runtime.ConstrainedExecution;
using System.Runtime.Versioning;
using Microsoft.Win32.SafeHandles;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
public sealed class SecureString: IDisposable {
@@ -105,15 +106,15 @@ namespace System.Security {
[CLSCompliant(false)]
public unsafe SecureString(char* value, int length) {
if( value == null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
if( length < 0) {
- throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if( length > MaxLength) {
- throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_Length"));
+ throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_Length"));
}
Contract.EndContractBlock();
@@ -192,7 +193,7 @@ namespace System.Security {
#endif // FEATURE_CORRUPTING_EXCEPTIONS
public void InsertAt( int index, char c ) {
if( index < 0 || index > m_length) {
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_IndexString"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_IndexString"));
}
Contract.EndContractBlock();
@@ -251,7 +252,7 @@ namespace System.Security {
EnsureNotReadOnly();
if( index < 0 || index >= m_length) {
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_IndexString"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_IndexString"));
}
unsafe
@@ -290,10 +291,10 @@ namespace System.Security {
#endif // FEATURE_CORRUPTING_EXCEPTIONS
public void SetAt( int index, char c ) {
if( index < 0 || index >= m_length) {
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_IndexString"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_IndexString"));
}
Contract.EndContractBlock();
- Contract.Assert(index <= Int32.MaxValue / sizeof(char));
+ Debug.Assert(index <= Int32.MaxValue / sizeof(char));
EnsureNotDisposed();
EnsureNotReadOnly();
@@ -315,7 +316,7 @@ namespace System.Security {
private int BufferLength {
[System.Security.SecurityCritical] // auto-generated
get {
- Contract.Assert(m_buffer != null, "Buffer is not initialized!");
+ Debug.Assert(m_buffer != null, "Buffer is not initialized!");
return m_buffer.Length;
}
}
@@ -341,7 +342,7 @@ namespace System.Security {
[System.Security.SecurityCritical] // auto-generated
private void EnsureCapacity(int capacity) {
if( capacity > MaxLength) {
- throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_Capacity"));
+ throw new ArgumentOutOfRangeException(nameof(capacity), Environment.GetResourceString("ArgumentOutOfRange_Capacity"));
}
Contract.EndContractBlock();
@@ -377,7 +378,7 @@ namespace System.Security {
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
private static uint GetAlignedSize( int size) {
- Contract.Assert(size >= 0, "size must be non-negative");
+ Debug.Assert(size >= 0, "size must be non-negative");
uint alignedSize = ((uint)size / BlockSize) * BlockSize;
if( (size % BlockSize != 0) || size == 0) { // if size is 0, set allocated size to blocksize
@@ -449,8 +450,8 @@ namespace System.Security {
[System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
private void ProtectMemory() {
- Contract.Assert(!m_buffer.IsInvalid && m_buffer.Length != 0, "Invalid buffer!");
- Contract.Assert(m_buffer.Length % BlockSize == 0, "buffer length must be multiple of blocksize!");
+ Debug.Assert(!m_buffer.IsInvalid && m_buffer.Length != 0, "Invalid buffer!");
+ Debug.Assert(m_buffer.Length % BlockSize == 0, "buffer length must be multiple of blocksize!");
if( m_length == 0 || m_encrypted) {
return;
@@ -650,8 +651,8 @@ namespace System.Security {
[System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
private void UnProtectMemory() {
- Contract.Assert(!m_buffer.IsInvalid && m_buffer.Length != 0, "Invalid buffer!");
- Contract.Assert(m_buffer.Length % BlockSize == 0, "buffer length must be multiple of blocksize!");
+ Debug.Assert(!m_buffer.IsInvalid && m_buffer.Length != 0, "Invalid buffer!");
+ Debug.Assert(m_buffer.Length % BlockSize == 0, "buffer length must be multiple of blocksize!");
if( m_length == 0) {
return;
@@ -733,7 +734,7 @@ namespace System.Security {
source.AcquirePointer(ref sourcePtr);
target.AcquirePointer(ref targetPtr);
- Contract.Assert(Win32Native.SysStringLen((IntPtr)targetPtr) >= Win32Native.SysStringLen((IntPtr)sourcePtr), "Target buffer is not large enough!");
+ Debug.Assert(Win32Native.SysStringLen((IntPtr)targetPtr) >= Win32Native.SysStringLen((IntPtr)sourcePtr), "Target buffer is not large enough!");
Buffer.Memcpy(targetPtr, sourcePtr, (int) Win32Native.SysStringLen((IntPtr)sourcePtr) * 2);
}
diff --git a/src/mscorlib/src/System/SharedStatics.cs b/src/mscorlib/src/System/SharedStatics.cs
index ec63a0ec25..cbc5c354a1 100644
--- a/src/mscorlib/src/System/SharedStatics.cs
+++ b/src/mscorlib/src/System/SharedStatics.cs
@@ -11,18 +11,16 @@
**
=============================================================================*/
-namespace System {
-
+namespace System
+{
using System.Threading;
using System.Runtime.Remoting;
using System.Security;
using System.Security.Util;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
-#if FEATURE_CAS_POLICY
- using StringMaker = System.Security.Util.Tokenizer.StringMaker;
-#endif // FEATURE_CAS_POLICY
internal sealed class SharedStatics
{
@@ -40,7 +38,6 @@ namespace System {
private volatile String _Remoting_Identity_IDGuid;
public static String Remoting_Identity_IDGuid
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
if (_sharedStatics._Remoting_Identity_IDGuid == null)
@@ -61,63 +58,12 @@ namespace System {
}
}
- Contract.Assert(_sharedStatics._Remoting_Identity_IDGuid != null,
+ Debug.Assert(_sharedStatics._Remoting_Identity_IDGuid != null,
"_sharedStatics._Remoting_Identity_IDGuid != null");
return _sharedStatics._Remoting_Identity_IDGuid;
}
}
-#if FEATURE_CAS_POLICY
- private StringMaker _maker;
- [System.Security.SecuritySafeCritical] // auto-generated
- static public StringMaker GetSharedStringMaker()
- {
- StringMaker maker = null;
-
- bool tookLock = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try {
- Monitor.Enter(_sharedStatics, ref tookLock);
-
- if (_sharedStatics._maker != null)
- {
- maker = _sharedStatics._maker;
- _sharedStatics._maker = null;
- }
- }
- finally {
- if (tookLock)
- Monitor.Exit(_sharedStatics);
- }
-
- if (maker == null)
- {
- maker = new StringMaker();
- }
-
- return maker;
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- static public void ReleaseSharedStringMaker(ref StringMaker maker)
- {
- // save this stringmaker so someone else can use it
- bool tookLock = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- Monitor.Enter(_sharedStatics, ref tookLock);
-
- _sharedStatics._maker = maker;
- maker = null;
- }
- finally {
- if (tookLock)
- Monitor.Exit(_sharedStatics);
- }
- }
-#endif // FEATURE_CAS_POLICY
-
// Note this may not need to be process-wide.
private int _Remoting_Identity_IDSeqNum;
internal static int Remoting_Identity_GetNextSeqNum()
@@ -140,7 +86,7 @@ namespace System {
internal static ulong MemoryFailPointReservedMemory {
get {
- Contract.Assert(Volatile.Read(ref _sharedStatics._memFailPointReservedMemory) >= 0, "Process-wide MemoryFailPoint reserved memory was negative!");
+ Debug.Assert(Volatile.Read(ref _sharedStatics._memFailPointReservedMemory) >= 0, "Process-wide MemoryFailPoint reserved memory was negative!");
return (ulong) Volatile.Read(ref _sharedStatics._memFailPointReservedMemory);
}
}
diff --git a/src/mscorlib/src/System/Single.cs b/src/mscorlib/src/System/Single.cs
index 6a77f086b5..481c088617 100644
--- a/src/mscorlib/src/System/Single.cs
+++ b/src/mscorlib/src/System/Single.cs
@@ -37,22 +37,21 @@ namespace System {
public const float NegativeInfinity = (float)-1.0 / (float)0.0;
public const float NaN = (float)0.0 / (float)0.0;
+ internal static float NegativeZero = BitConverter.Int32BitsToSingle(unchecked((int)0x80000000));
+
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.Versioning.NonVersionable]
public unsafe static bool IsInfinity(float f) {
return (*(int*)(&f) & 0x7FFFFFFF) == 0x7F800000;
}
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.Versioning.NonVersionable]
public unsafe static bool IsPositiveInfinity(float f) {
return *(int*)(&f) == 0x7F800000;
}
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.Versioning.NonVersionable]
public unsafe static bool IsNegativeInfinity(float f) {
return *(int*)(&f) == unchecked((int)0xFF800000);
@@ -60,11 +59,15 @@ namespace System {
[Pure]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- [System.Security.SecuritySafeCritical]
[System.Runtime.Versioning.NonVersionable]
public unsafe static bool IsNaN(float f) {
return (*(int*)(&f) & 0x7FFFFFFF) > 0x7F800000;
}
+
+ [Pure]
+ internal unsafe static bool IsNegative(float f) {
+ return (*(uint*)(&f) & 0x80000000) == 0x80000000;
+ }
// Compares this object to another object, returning an integer that
// indicates the relationship.
@@ -155,7 +158,6 @@ namespace System {
return IsNaN(obj) && IsNaN(m_value);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe override int GetHashCode() {
float f = m_value;
if (f == 0) {
@@ -166,25 +168,21 @@ namespace System {
return v;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override String ToString() {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatSingle(m_value, null, NumberFormatInfo.CurrentInfo);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(IFormatProvider provider) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatSingle(m_value, null, NumberFormatInfo.GetInstance(provider));
}
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(String format) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatSingle(m_value, format, NumberFormatInfo.CurrentInfo);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(String format, IFormatProvider provider) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatSingle(m_value, format, NumberFormatInfo.GetInstance(provider));
diff --git a/src/mscorlib/src/System/Span.cs b/src/mscorlib/src/System/Span.cs
new file mode 100644
index 0000000000..9fa55c63d7
--- /dev/null
+++ b/src/mscorlib/src/System/Span.cs
@@ -0,0 +1,477 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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.CompilerServices;
+
+#pragma warning disable 0809 //warning CS0809: Obsolete member 'Span<T>.Equals(object)' overrides non-obsolete member 'object.Equals(object)'
+
+namespace System
+{
+ /// <summary>
+ /// Span represents contiguous region of arbitrary memory, with performance
+ /// characteristics on par with T[]. Unlike arrays, it can point to either managed
+ /// or native memory, or to memory allocated on the stack. It is type- and memory-safe.
+ /// </summary>
+ public struct Span<T>
+ {
+ /// <summary>A byref or a native ptr.</summary>
+ private readonly ByReference<T> _pointer;
+ /// <summary>The number of elements this Span contains.</summary>
+ private readonly int _length;
+
+ /// <summary>
+ /// Creates a new span over the entirety of the target array.
+ /// </summary>
+ /// <param name="array">The target array.</param>
+ /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="array"/> is a null
+ /// reference (Nothing in Visual Basic).</exception>
+ /// <exception cref="System.ArrayTypeMismatchException">Thrown when <paramref name="array"/> is covariant and array's type is not exactly T[].</exception>
+ public Span(T[] array)
+ {
+ if (array == null)
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
+ if (default(T) == null) { // Arrays of valuetypes are never covariant
+ if (array.GetType() != typeof(T[]))
+ ThrowHelper.ThrowArrayTypeMismatchException();
+ }
+
+ _pointer = new ByReference<T>(ref JitHelpers.GetArrayData(array));
+ _length = array.Length;
+ }
+
+ /// <summary>
+ /// Creates a new span over the portion of the target array beginning
+ /// at 'start' index and covering the remainder of the array.
+ /// </summary>
+ /// <param name="array">The target array.</param>
+ /// <param name="start">The index at which to begin the span.</param>
+ /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="array"/> is a null
+ /// reference (Nothing in Visual Basic).</exception>
+ /// <exception cref="System.ArrayTypeMismatchException">Thrown when <paramref name="array"/> is covariant and array's type is not exactly T[].</exception>
+ /// <exception cref="System.ArgumentOutOfRangeException">
+ /// Thrown when the specified <paramref name="start"/> is not in the range (&lt;0 or &gt;=Length).
+ /// </exception>
+ public Span(T[] array, int start)
+ {
+ if (array == null)
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
+ if (default(T) == null) { // Arrays of valuetypes are never covariant
+ if (array.GetType() != typeof(T[]))
+ ThrowHelper.ThrowArrayTypeMismatchException();
+ }
+ if ((uint)start > (uint)array.Length)
+ ThrowHelper.ThrowArgumentOutOfRangeException();
+
+ _pointer = new ByReference<T>(ref Unsafe.Add(ref JitHelpers.GetArrayData(array), start));
+ _length = array.Length - start;
+ }
+
+ /// <summary>
+ /// Creates a new span over the portion of the target array beginning
+ /// at 'start' index and ending at 'end' index (exclusive).
+ /// </summary>
+ /// <param name="array">The target array.</param>
+ /// <param name="start">The index at which to begin the span.</param>
+ /// <param name="length">The number of items in the span.</param>
+ /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="array"/> is a null
+ /// reference (Nothing in Visual Basic).</exception>
+ /// <exception cref="System.ArrayTypeMismatchException">Thrown when <paramref name="array"/> is covariant and array's type is not exactly T[].</exception>
+ /// <exception cref="System.ArgumentOutOfRangeException">
+ /// Thrown when the specified <paramref name="start"/> or end index is not in the range (&lt;0 or &gt;=Length).
+ /// </exception>
+ public Span(T[] array, int start, int length)
+ {
+ if (array == null)
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
+ if (default(T) == null) { // Arrays of valuetypes are never covariant
+ if (array.GetType() != typeof(T[]))
+ ThrowHelper.ThrowArrayTypeMismatchException();
+ }
+ if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
+ ThrowHelper.ThrowArgumentOutOfRangeException();
+
+ _pointer = new ByReference<T>(ref Unsafe.Add(ref JitHelpers.GetArrayData(array), start));
+ _length = length;
+ }
+
+ /// <summary>
+ /// Creates a new span over the target unmanaged buffer. Clearly this
+ /// is quite dangerous, because we are creating arbitrarily typed T's
+ /// out of a void*-typed block of memory. And the length is not checked.
+ /// But if this creation is correct, then all subsequent uses are correct.
+ /// </summary>
+ /// <param name="pointer">An unmanaged pointer to memory.</param>
+ /// <param name="length">The number of <typeparamref name="T"/> elements the memory contains.</param>
+ /// <exception cref="System.ArgumentException">
+ /// Thrown when <typeparamref name="T"/> is reference type or contains pointers and hence cannot be stored in unmanaged memory.
+ /// </exception>
+ /// <exception cref="System.ArgumentOutOfRangeException">
+ /// Thrown when the specified <paramref name="length"/> is negative.
+ /// </exception>
+ [CLSCompliant(false)]
+ public unsafe Span(void* pointer, int length)
+ {
+ if (JitHelpers.ContainsReferences<T>())
+ ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T));
+ if (length < 0)
+ ThrowHelper.ThrowArgumentOutOfRangeException();
+
+ _pointer = new ByReference<T>(ref Unsafe.As<byte, T>(ref *(byte*)pointer));
+ _length = length;
+ }
+
+ /// <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.
+ /// </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>
+ 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);
+ }
+
+
+ /// <summary>
+ /// An internal helper for creating spans.
+ /// </summary>
+ internal Span(ref T ptr, int length)
+ {
+ _pointer = new ByReference<T>(ref ptr);
+ _length = length;
+ }
+
+ /// <summary>
+ /// Returns a reference to the 0th element of the Span. If the Span is empty, returns a reference to the location where the 0th element
+ /// would have been stored. Such a reference can be used for pinning but must never be dereferenced.
+ /// </summary>
+ public ref T DangerousGetPinnableReference()
+ {
+ return ref _pointer.Value;
+ }
+
+ /// <summary>
+ /// Gets the number of elements contained in the <see cref="Span{T}"/>
+ /// </summary>
+ public int Length => _length;
+
+ /// <summary>
+ /// Returns whether the <see cref="Span{T}"/> is empty.
+ /// </summary>
+ public bool IsEmpty => _length == 0;
+
+ /// <summary>
+ /// Fetches the element at the specified index.
+ /// </summary>
+ /// <exception cref="System.IndexOutOfRangeException">
+ /// Thrown when the specified <paramref name="index"/> is not in range (&lt;0 or &gt;&eq;Length).
+ /// </exception>
+ public T this[int index]
+ {
+ get
+ {
+ if ((uint)index >= (uint)_length)
+ ThrowHelper.ThrowIndexOutOfRangeException();
+
+ return Unsafe.Add(ref DangerousGetPinnableReference(), index);
+ }
+ set
+ {
+ if ((uint)index >= (uint)_length)
+ ThrowHelper.ThrowIndexOutOfRangeException();
+
+ Unsafe.Add(ref DangerousGetPinnableReference(), index) = value;
+ }
+ }
+
+ /// <summary>
+ /// Copies the contents of this span into destination span. If the source
+ /// and destinations overlap, this method behaves as if the original values in
+ /// a temporary location before the destination is overwritten.
+ /// </summary>
+ /// <param name="destination">The span to copy items into.</param>
+ /// <exception cref="System.ArgumentException">
+ /// Thrown when the destination Span is shorter than the source Span.
+ /// </exception>
+ public void CopyTo(Span<T> destination)
+ {
+ if (!TryCopyTo(destination))
+ ThrowHelper.ThrowArgumentException_DestinationTooShort();
+ }
+
+ /// <summary>
+ /// Copies the contents of this span into destination span. If the source
+ /// and destinations overlap, this method behaves as if the original values in
+ /// a temporary location before the destination is overwritten.
+ /// </summary>
+ /// <param name="destination">The span to copy items into.</param>
+ /// <returns>If the destination span is shorter than the source span, this method
+ /// return false and no data is written to the destination.</returns>
+ public bool TryCopyTo(Span<T> destination)
+ {
+ if ((uint)_length > (uint)destination.Length)
+ return false;
+
+ SpanHelper.CopyTo<T>(ref destination.DangerousGetPinnableReference(), ref DangerousGetPinnableReference(), _length);
+ return true;
+ }
+
+ /// <summary>
+ /// Returns true if left and right point at the same memory and have the same length. Note that
+ /// this does *not* check to see if the *contents* are equal.
+ /// </summary>
+ public static bool operator ==(Span<T> left, Span<T> right)
+ {
+ return left._length == right._length && Unsafe.AreSame<T>(ref left.DangerousGetPinnableReference(), ref right.DangerousGetPinnableReference());
+ }
+
+ /// <summary>
+ /// Returns false if left and right point at the same memory and have the same length. Note that
+ /// this does *not* check to see if the *contents* are equal.
+ /// </summary>
+ public static bool operator !=(Span<T> left, Span<T> right) => !(left == right);
+
+ /// <summary>
+ /// This method is not supported as spans cannot be boxed. To compare two spans, use operator==.
+ /// <exception cref="System.NotSupportedException">
+ /// Always thrown by this method.
+ /// </exception>
+ /// </summary>
+ [Obsolete("Equals() on Span will always throw an exception. Use == instead.")]
+ 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);
+ }
+
+ /// <summary>
+ /// This method is not supported as spans cannot be boxed.
+ /// <exception cref="System.NotSupportedException">
+ /// Always thrown by this method.
+ /// </exception>
+ /// </summary>
+ [Obsolete("GetHashCode() on Span will always throw an exception.")]
+ public override int GetHashCode()
+ {
+ ThrowHelper.ThrowNotSupportedException_CannotCallGetHashCodeOnSpan();
+ // Prevent compiler error CS0161: 'Span<T>.GetHashCode()': not all code paths return a value
+ return default(int);
+ }
+
+ /// <summary>
+ /// Defines an implicit conversion of an array to a <see cref="Span{T}"/>
+ /// </summary>
+ public static implicit operator Span<T>(T[] array) => new Span<T>(array);
+
+ /// <summary>
+ /// Defines an implicit conversion of a <see cref="ArraySegment{T}"/> to a <see cref="Span{T}"/>
+ /// </summary>
+ public static implicit operator Span<T>(ArraySegment<T> arraySegment) => new Span<T>(arraySegment.Array, arraySegment.Offset, arraySegment.Count);
+
+ /// <summary>
+ /// Defines an implicit conversion of a <see cref="Span{T}"/> to a <see cref="ReadOnlySpan{T}"/>
+ /// </summary>
+ public static implicit operator ReadOnlySpan<T>(Span<T> span) => new ReadOnlySpan<T>(ref span.DangerousGetPinnableReference(), span._length);
+
+ /// <summary>
+ /// Forms a slice out of the given span, beginning at 'start'.
+ /// </summary>
+ /// <param name="start">The index at which to begin this slice.</param>
+ /// <exception cref="System.ArgumentOutOfRangeException">
+ /// Thrown when the specified <paramref name="start"/> index is not in range (&lt;0 or &gt;Length).
+ /// </exception>
+ [MethodImpl(MethodImplOptions.NoOptimization)] // TODO-SPAN: Workaround for https://github.com/dotnet/coreclr/issues/7894
+ public Span<T> Slice(int start)
+ {
+ if ((uint)start > (uint)_length)
+ ThrowHelper.ThrowArgumentOutOfRangeException();
+
+ return new Span<T>(ref Unsafe.Add(ref DangerousGetPinnableReference(), start), _length - start);
+ }
+
+ /// <summary>
+ /// Forms a slice out of the given span, beginning at 'start', of given length
+ /// </summary>
+ /// <param name="start">The index at which to begin this slice.</param>
+ /// <param name="length">The desired length for the slice (exclusive).</param>
+ /// <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.NoOptimization)] // TODO-SPAN: Workaround for https://github.com/dotnet/coreclr/issues/7894
+ public Span<T> Slice(int start, int length)
+ {
+ if ((uint)start > (uint)_length || (uint)length > (uint)(_length - start))
+ ThrowHelper.ThrowArgumentOutOfRangeException();
+
+ return new Span<T>(ref Unsafe.Add(ref DangerousGetPinnableReference(), start), length);
+ }
+
+ /// <summary>
+ /// Copies the contents of this span into a new array. This heap
+ /// allocates, so should generally be avoided, however it is sometimes
+ /// necessary to bridge the gap with APIs written in terms of arrays.
+ /// </summary>
+ public T[] ToArray()
+ {
+ if (_length == 0)
+ return Array.Empty<T>();
+
+ var destination = new T[_length];
+ SpanHelper.CopyTo<T>(ref JitHelpers.GetArrayData(destination), ref DangerousGetPinnableReference(), _length);
+ return destination;
+ }
+
+ // <summary>
+ /// Returns an empty <see cref="Span{T}"/>
+ /// </summary>
+ public static Span<T> Empty => default(Span<T>);
+ }
+
+ public static class SpanExtensions
+ {
+ /// <summary>
+ /// Casts a Span of one primitive type <typeparamref name="T"/> to Span of bytes.
+ /// That type may not contain pointers or references. This is checked at runtime in order to preserve type safety.
+ /// </summary>
+ /// <param name="source">The source slice, of type <typeparamref name="T"/>.</param>
+ /// <exception cref="System.ArgumentException">
+ /// Thrown when <typeparamref name="T"/> contains pointers.
+ /// </exception>
+ public static Span<byte> AsBytes<T>(this Span<T> source)
+ where T : struct
+ {
+ if (JitHelpers.ContainsReferences<T>())
+ ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T));
+
+ return new Span<byte>(
+ ref Unsafe.As<T, byte>(ref source.DangerousGetPinnableReference()),
+ checked(source.Length * Unsafe.SizeOf<T>()));
+ }
+
+ /// <summary>
+ /// Casts a ReadOnlySpan of one primitive type <typeparamref name="T"/> to ReadOnlySpan of bytes.
+ /// That type may not contain pointers or references. This is checked at runtime in order to preserve type safety.
+ /// </summary>
+ /// <param name="source">The source slice, of type <typeparamref name="T"/>.</param>
+ /// <exception cref="System.ArgumentException">
+ /// Thrown when <typeparamref name="T"/> contains pointers.
+ /// </exception>
+ public static ReadOnlySpan<byte> AsBytes<T>(this ReadOnlySpan<T> source)
+ where T : struct
+ {
+ if (JitHelpers.ContainsReferences<T>())
+ ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T));
+
+ return new ReadOnlySpan<byte>(
+ ref Unsafe.As<T, byte>(ref source.DangerousGetPinnableReference()),
+ checked(source.Length * Unsafe.SizeOf<T>()));
+ }
+
+ /// <summary>
+ /// Casts a Span of one primitive type <typeparamref name="TFrom"/> to another primitive type <typeparamref name="TTo"/>.
+ /// These types may not contain pointers or references. This is checked at runtime in order to preserve type safety.
+ /// </summary>
+ /// <remarks>
+ /// Supported only for platforms that support misaligned memory access.
+ /// </remarks>
+ /// <param name="source">The source slice, of type <typeparamref name="TFrom"/>.</param>
+ /// <exception cref="System.ArgumentException">
+ /// Thrown when <typeparamref name="TFrom"/> or <typeparamref name="TTo"/> contains pointers.
+ /// </exception>
+ public static Span<TTo> NonPortableCast<TFrom, TTo>(this Span<TFrom> source)
+ where TFrom : struct
+ where TTo : struct
+ {
+ if (JitHelpers.ContainsReferences<TFrom>())
+ ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(TFrom));
+ if (JitHelpers.ContainsReferences<TTo>())
+ ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(TTo));
+
+ return new Span<TTo>(
+ ref Unsafe.As<TFrom, TTo>(ref source.DangerousGetPinnableReference()),
+ checked((int)((long)source.Length * Unsafe.SizeOf<TFrom>() / Unsafe.SizeOf<TTo>())));
+ }
+
+ /// <summary>
+ /// Casts a ReadOnlySpan of one primitive type <typeparamref name="TFrom"/> to another primitive type <typeparamref name="TTo"/>.
+ /// These types may not contain pointers or references. This is checked at runtime in order to preserve type safety.
+ /// </summary>
+ /// <remarks>
+ /// Supported only for platforms that support misaligned memory access.
+ /// </remarks>
+ /// <param name="source">The source slice, of type <typeparamref name="TFrom"/>.</param>
+ /// <exception cref="System.ArgumentException">
+ /// Thrown when <typeparamref name="TFrom"/> or <typeparamref name="TTo"/> contains pointers.
+ /// </exception>
+ public static ReadOnlySpan<TTo> NonPortableCast<TFrom, TTo>(this ReadOnlySpan<TFrom> source)
+ where TFrom : struct
+ where TTo : struct
+ {
+ if (JitHelpers.ContainsReferences<TFrom>())
+ ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(TFrom));
+ if (JitHelpers.ContainsReferences<TTo>())
+ ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(TTo));
+
+ return new ReadOnlySpan<TTo>(
+ ref Unsafe.As<TFrom, TTo>(ref source.DangerousGetPinnableReference()),
+ checked((int)((long)source.Length * Unsafe.SizeOf<TFrom>() / Unsafe.SizeOf<TTo>())));
+ }
+ }
+
+ internal static class SpanHelper
+ {
+ internal static unsafe void CopyTo<T>(ref T destination, ref T source, int elementsCount)
+ {
+ if (elementsCount == 0)
+ return;
+
+ if (Unsafe.AreSame(ref destination, ref source))
+ return;
+
+ if (!JitHelpers.ContainsReferences<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
+ }
+ }
+ }
+ 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
+ {
+ for (int i = elementsCount - 1; i >= 0; i--)
+ Unsafe.Add(ref destination, i) = Unsafe.Add(ref source, i);
+ }
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/String.Comparison.cs b/src/mscorlib/src/System/String.Comparison.cs
index a05f9f201a..07f2f9de22 100644
--- a/src/mscorlib/src/System/String.Comparison.cs
+++ b/src/mscorlib/src/System/String.Comparison.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Collections;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Globalization;
using System.Runtime.CompilerServices;
@@ -17,7 +18,6 @@ namespace System
//Native Static Methods
//
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe static int CompareOrdinalIgnoreCaseHelper(String strA, String strB)
{
Contract.Requires(strA != null);
@@ -35,7 +35,7 @@ namespace System
int charA = *a;
int charB = *b;
- Contract.Assert((charA | charB) <= 0x7F, "strings have to be ASCII");
+ Debug.Assert((charA | charB) <= 0x7F, "strings have to be ASCII");
// uppercase both chars - notice that we need just one compare per char
if ((uint)(charA - 'a') <= (uint)('z' - 'a')) charA -= 0x20;
@@ -55,13 +55,11 @@ namespace System
}
// native call to COMString::CompareOrdinalEx
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern int CompareOrdinalHelper(String strA, int indexA, int countA, String strB, int indexB, int countB);
//This will not work in case-insensitive mode for any character greater than 0x80.
//We'll throw an ArgumentException.
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
unsafe internal static extern int nativeCompareOrdinalIgnoreCaseWC(String strA, sbyte *strBBytes);
@@ -75,7 +73,6 @@ namespace System
// Search/Query methods
//
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
private unsafe static bool EqualsHelper(String strA, String strB)
{
@@ -137,7 +134,6 @@ namespace System
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
private unsafe static bool StartsWithOrdinalHelper(String str, String startsWith)
{
@@ -155,7 +151,7 @@ namespace System
#if BIT64
// Single int read aligns pointers for the following long reads
// No length check needed as this method is called when length >= 2
- Contract.Assert(length >= 2);
+ Debug.Assert(length >= 2);
if (*(int*)a != *(int*)b) goto ReturnFalse;
length -= 2; a += 2; b += 2;
@@ -194,7 +190,6 @@ namespace System
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe static int CompareOrdinalHelper(String strA, String strB)
{
Contract.Requires(strA != null);
@@ -202,7 +197,7 @@ namespace System
// NOTE: This may be subject to change if eliminating the check
// in the callers makes them small enough to be inlined by the JIT
- Contract.Assert(strA.m_firstChar == strB.m_firstChar,
+ Debug.Assert(strA.m_firstChar == strB.m_firstChar,
"For performance reasons, callers of this method should " +
"check/short-circuit beforehand if the first char is the same.");
@@ -310,7 +305,7 @@ namespace System
if (*a != *b) return *a - *b;
DiffOffset1:
- Contract.Assert(*(a + 1) != *(b + 1), "This char must be different if we reach here!");
+ Debug.Assert(*(a + 1) != *(b + 1), "This char must be different if we reach here!");
return *(a + 1) - *(b + 1);
}
}
@@ -342,13 +337,12 @@ namespace System
// Provides a more flexible function for string comparision. See StringComparison
// for meaning of different comparisonType.
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
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"), "comparisonType");
+ throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), nameof(comparisonType));
}
Contract.EndContractBlock();
@@ -417,7 +411,7 @@ namespace System
public static int Compare(String strA, String strB, CultureInfo culture, CompareOptions options) {
if (culture == null)
{
- throw new ArgumentNullException("culture");
+ throw new ArgumentNullException(nameof(culture));
}
Contract.EndContractBlock();
@@ -511,7 +505,7 @@ namespace System
{
if (culture == null)
{
- throw new ArgumentNullException("culture");
+ throw new ArgumentNullException(nameof(culture));
}
Contract.EndContractBlock();
@@ -532,10 +526,9 @@ namespace System
}
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
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"), "comparisonType");
+ throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), nameof(comparisonType));
}
Contract.EndContractBlock();
@@ -552,18 +545,18 @@ namespace System
if (length < 0)
{
- throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
+ throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
}
if (indexA < 0 || indexB < 0)
{
- string paramName = indexA < 0 ? "indexA" : "indexB";
+ string paramName = indexA < 0 ? nameof(indexA) : nameof(indexB);
throw new ArgumentOutOfRangeException(paramName, Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
if (strA.Length - indexA < 0 || strB.Length - indexB < 0)
{
- string paramName = strA.Length - indexA < 0 ? "indexA" : "indexB";
+ string paramName = strA.Length - indexA < 0 ? nameof(indexA) : nameof(indexB);
throw new ArgumentOutOfRangeException(paramName, Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
@@ -638,7 +631,6 @@ namespace System
// Compares strA and strB using an ordinal (code-point) comparison.
//
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
public static int CompareOrdinal(String strA, int indexA, String strB, int indexB, int length)
{
if (strA == null || strB == null)
@@ -657,12 +649,12 @@ namespace System
if (length < 0)
{
- throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NegativeCount"));
+ throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_NegativeCount"));
}
if (indexA < 0 || indexB < 0)
{
- string paramName = indexA < 0 ? "indexA" : "indexB";
+ string paramName = indexA < 0 ? nameof(indexA) : nameof(indexB);
throw new ArgumentOutOfRangeException(paramName, Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
@@ -671,7 +663,7 @@ namespace System
if (lengthA < 0 || lengthB < 0)
{
- string paramName = lengthA < 0 ? "indexA" : "indexB";
+ string paramName = lengthA < 0 ? nameof(indexA) : nameof(indexB);
throw new ArgumentOutOfRangeException(paramName, Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
@@ -724,15 +716,14 @@ namespace System
}
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
[ComVisible(false)]
public Boolean EndsWith(String value, StringComparison comparisonType) {
if( (Object)value == null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
if( comparisonType < StringComparison.CurrentCulture || comparisonType > StringComparison.OrdinalIgnoreCase) {
- throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), "comparisonType");
+ throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), nameof(comparisonType));
}
Contract.EndContractBlock();
@@ -767,14 +758,14 @@ namespace System
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"), "comparisonType");
+ throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), nameof(comparisonType));
}
}
[Pure]
public Boolean EndsWith(String value, Boolean ignoreCase, CultureInfo culture) {
if (null==value) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
@@ -846,10 +837,9 @@ namespace System
}
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
public bool Equals(String value, StringComparison comparisonType) {
if (comparisonType < StringComparison.CurrentCulture || comparisonType > StringComparison.OrdinalIgnoreCase)
- throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), "comparisonType");
+ throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), nameof(comparisonType));
Contract.EndContractBlock();
if ((Object)this == (Object)value) {
@@ -895,7 +885,7 @@ namespace System
#endif
default:
- throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), "comparisonType");
+ throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), nameof(comparisonType));
}
}
@@ -915,10 +905,9 @@ namespace System
}
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
public static bool Equals(String a, String b, StringComparison comparisonType) {
if (comparisonType < StringComparison.CurrentCulture || comparisonType > StringComparison.OrdinalIgnoreCase)
- throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), "comparisonType");
+ throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), nameof(comparisonType));
Contract.EndContractBlock();
if ((Object)a==(Object)b) {
@@ -966,7 +955,7 @@ namespace System
}
default:
- throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), "comparisonType");
+ throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), nameof(comparisonType));
}
}
@@ -981,16 +970,13 @@ namespace System
#if FEATURE_RANDOMIZED_STRING_HASHING
// Do not remove!
// This method is called by reflection in System.Xml
- [System.Security.SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern int InternalMarvin32HashString(string s, int strLen, long additionalEntropy);
- [System.Security.SecuritySafeCritical]
internal static bool UseRandomizedHashing() {
return InternalUseRandomizedHashing();
}
- [System.Security.SecurityCritical]
[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
private static extern bool InternalUseRandomizedHashing();
@@ -998,7 +984,6 @@ namespace System
// Gets a hash code for this string. If strings A and B are such that A.Equals(B), then
// they will return the same hash code.
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public override int GetHashCode()
{
@@ -1012,15 +997,19 @@ namespace System
return GetLegacyNonRandomizedHashCode();
}
+ // Gets a hash code for this string and this comparison. If strings A and B and comparition C are such
+ // that String.Equals(A, B, C), then they will return the same hash code with this comparison C.
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
+ public int GetHashCode(StringComparison comparisonType) => StringComparer.FromComparison(comparisonType).GetHashCode(this);
+
// 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).
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal int GetLegacyNonRandomizedHashCode() {
unsafe {
fixed (char* src = &m_firstChar) {
- Contract.Assert(src[this.Length] == '\0', "src[this.Length] == '\\0'");
- Contract.Assert( ((int)src)%4 == 0, "Managed string should start at 4 bytes boundary");
+ Debug.Assert(src[this.Length] == '\0', "src[this.Length] == '\\0'");
+ Debug.Assert( ((int)src)%4 == 0, "Managed string should start at 4 bytes boundary");
#if BIT64
int hash1 = 5381;
#else // !BIT64 (32)
@@ -1073,22 +1062,21 @@ namespace System
[Pure]
public Boolean StartsWith(String value) {
if ((Object)value == null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return StartsWith(value, StringComparison.CurrentCulture);
}
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
[ComVisible(false)]
public Boolean StartsWith(String value, StringComparison comparisonType) {
if( (Object)value == null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
if( comparisonType < StringComparison.CurrentCulture || comparisonType > StringComparison.OrdinalIgnoreCase) {
- throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), "comparisonType");
+ throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), nameof(comparisonType));
}
Contract.EndContractBlock();
@@ -1133,14 +1121,14 @@ namespace System
#endif
default:
- throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), "comparisonType");
+ throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), nameof(comparisonType));
}
}
[Pure]
public Boolean StartsWith(String value, Boolean ignoreCase, CultureInfo culture) {
if (null==value) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
diff --git a/src/mscorlib/src/System/String.Manipulation.cs b/src/mscorlib/src/System/String.Manipulation.cs
index e9568a6d03..194b4f8c59 100644
--- a/src/mscorlib/src/System/String.Manipulation.cs
+++ b/src/mscorlib/src/System/String.Manipulation.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.Diagnostics.Contracts;
using System.Globalization;
using System.Runtime.CompilerServices;
@@ -17,7 +18,6 @@ namespace System
private const int TrimTail = 1;
private const int TrimBoth = 2;
- [System.Security.SecuritySafeCritical] // auto-generated
unsafe private static void FillStringChecked(String dest, int destPos, String src)
{
Contract.Requires(dest != null);
@@ -109,12 +109,11 @@ namespace System
return Concat(objArgs);
}
- [System.Security.SecuritySafeCritical]
public static string Concat(params object[] args)
{
if (args == null)
{
- throw new ArgumentNullException("args");
+ throw new ArgumentNullException(nameof(args));
}
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
@@ -167,8 +166,8 @@ namespace System
{
string s = strings[i];
- Contract.Assert(s != null);
- Contract.Assert(position <= totalLength - s.Length, "We didn't allocate enough space for the result string!");
+ Debug.Assert(s != null);
+ Debug.Assert(position <= totalLength - s.Length, "We didn't allocate enough space for the result string!");
FillStringChecked(result, position, s);
position += s.Length;
@@ -181,7 +180,7 @@ namespace System
public static string Concat<T>(IEnumerable<T> values)
{
if (values == null)
- throw new ArgumentNullException("values");
+ throw new ArgumentNullException(nameof(values));
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
@@ -232,7 +231,7 @@ namespace System
public static string Concat(IEnumerable<string> values)
{
if (values == null)
- throw new ArgumentNullException("values");
+ throw new ArgumentNullException(nameof(values));
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
@@ -262,7 +261,6 @@ namespace System
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static String Concat(String str0, String str1) {
Contract.Ensures(Contract.Result<String>() != null);
Contract.Ensures(Contract.Result<String>().Length ==
@@ -291,7 +289,6 @@ namespace System
return result;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static String Concat(String str0, String str1, String str2) {
Contract.Ensures(Contract.Result<String>() != null);
Contract.Ensures(Contract.Result<String>().Length ==
@@ -325,7 +322,6 @@ namespace System
return result;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static String Concat(String str0, String str1, String str2, String str3) {
Contract.Ensures(Contract.Result<String>() != null);
Contract.Ensures(Contract.Result<String>().Length ==
@@ -366,10 +362,9 @@ namespace System
return result;
}
- [System.Security.SecuritySafeCritical]
public static String Concat(params String[] values) {
if (values == null)
- throw new ArgumentNullException("values");
+ throw new ArgumentNullException(nameof(values));
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
@@ -456,7 +451,7 @@ namespace System
{
// 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 FormatHelper.
- throw new ArgumentNullException((format == null) ? "format" : "args");
+ throw new ArgumentNullException((format == null) ? nameof(format) : nameof(args));
}
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
@@ -484,7 +479,7 @@ namespace System
{
// 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 FormatHelper.
- throw new ArgumentNullException((format == null) ? "format" : "args");
+ throw new ArgumentNullException((format == null) ? nameof(format) : nameof(args));
}
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
@@ -494,7 +489,7 @@ namespace System
private static String FormatHelper(IFormatProvider provider, String format, ParamsArray args) {
if (format == null)
- throw new ArgumentNullException("format");
+ throw new ArgumentNullException(nameof(format));
return StringBuilderCache.GetStringAndRelease(
StringBuilderCache
@@ -502,13 +497,12 @@ namespace System
.AppendFormatHelper(provider, format, args));
}
- [System.Security.SecuritySafeCritical] // auto-generated
public String Insert(int startIndex, String value)
{
if (value == null)
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
if (startIndex < 0 || startIndex > this.Length)
- throw new ArgumentOutOfRangeException("startIndex");
+ throw new ArgumentOutOfRangeException(nameof(startIndex));
Contract.Ensures(Contract.Result<String>() != null);
Contract.Ensures(Contract.Result<String>().Length == this.Length + value.Length);
Contract.EndContractBlock();
@@ -541,27 +535,131 @@ namespace System
}
return result;
}
+
+ public static string Join(char separator, params string[] value)
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value));
+ }
+
+ return Join(separator, value, 0, value.Length);
+ }
+
+ public unsafe static string Join(char separator, params object[] values)
+ {
+ // Defer argument validation to the internal function
+ return JoinCore(&separator, 1, values);
+ }
+
+ public unsafe static string Join<T>(char separator, IEnumerable<T> values)
+ {
+ // Defer argument validation to the internal function
+ return JoinCore(&separator, 1, values);
+ }
+
+ public unsafe static string Join(char separator, string[] value, int startIndex, int count)
+ {
+ // 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) {
- if (value==null)
- throw new ArgumentNullException("value");
- Contract.EndContractBlock();
+ public static string Join(string separator, params string[] value)
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value));
+ }
return Join(separator, value, 0, value.Length);
}
[ComVisible(false)]
- public static string Join(string separator, params object[] values)
+ public unsafe static string Join(string separator, params object[] values)
+ {
+ separator = separator ?? string.Empty;
+ fixed (char* pSeparator = &separator.m_firstChar)
+ {
+ // Defer argument validation to the internal function
+ return JoinCore(pSeparator, separator.Length, values);
+ }
+ }
+
+ [ComVisible(false)]
+ public unsafe static string Join<T>(string separator, IEnumerable<T> values)
+ {
+ separator = separator ?? string.Empty;
+ fixed (char* pSeparator = &separator.m_firstChar)
+ {
+ // Defer argument validation to the internal function
+ return JoinCore(pSeparator, separator.Length, values);
+ }
+ }
+
+ [ComVisible(false)]
+ public static string Join(string separator, IEnumerable<string> values)
{
if (values == null)
- throw new ArgumentNullException("values");
- Contract.EndContractBlock();
+ {
+ throw new ArgumentNullException(nameof(values));
+ }
+
+ using (IEnumerator<string> en = values.GetEnumerator())
+ {
+ if (!en.MoveNext())
+ {
+ return string.Empty;
+ }
+
+ string firstValue = en.Current;
- if (values.Length == 0 || values[0] == null)
+ if (!en.MoveNext())
+ {
+ // Only one value available
+ return firstValue ?? string.Empty;
+ }
+
+ // Null separator and values are handled by the StringBuilder
+ StringBuilder result = StringBuilderCache.Acquire();
+ result.Append(firstValue);
+
+ do
+ {
+ result.Append(separator);
+ result.Append(en.Current);
+ }
+ while (en.MoveNext());
+
+ return StringBuilderCache.GetStringAndRelease(result);
+ }
+ }
+
+ // Joins an array of strings together as one string with a separator between each original string.
+ //
+ public unsafe static string Join(string separator, string[] value, int startIndex, int count)
+ {
+ separator = separator ?? string.Empty;
+ fixed (char* pSeparator = &separator.m_firstChar)
+ {
+ // Defer argument validation to the internal function
+ return JoinCore(pSeparator, separator.Length, value, startIndex, count);
+ }
+ }
+
+ private unsafe static string JoinCore(char* separator, int separatorLength, object[] values)
+ {
+ if (values == null)
+ {
+ throw new ArgumentNullException(nameof(values));
+ }
+
+ if (values.Length == 0)
+ {
return string.Empty;
+ }
- string firstString = values[0].ToString();
+ string firstString = values[0]?.ToString();
if (values.Length == 1)
{
@@ -573,7 +671,7 @@ namespace System
for (int i = 1; i < values.Length; i++)
{
- result.Append(separator);
+ result.Append(separator, separatorLength);
object value = values[i];
if (value != null)
{
@@ -584,18 +682,19 @@ namespace System
return StringBuilderCache.GetStringAndRelease(result);
}
- [ComVisible(false)]
- public static String Join<T>(String separator, IEnumerable<T> values)
+ private unsafe static string JoinCore<T>(char* separator, int separatorLength, IEnumerable<T> values)
{
if (values == null)
- throw new ArgumentNullException("values");
- Contract.Ensures(Contract.Result<String>() != null);
- Contract.EndContractBlock();
+ {
+ throw new ArgumentNullException(nameof(values));
+ }
using (IEnumerator<T> en = values.GetEnumerator())
{
if (!en.MoveNext())
+ {
return string.Empty;
+ }
// We called MoveNext once, so this will be the first item
T currentValue = en.Current;
@@ -616,14 +715,14 @@ namespace System
}
StringBuilder result = StringBuilderCache.Acquire();
-
+
result.Append(firstString);
do
{
currentValue = en.Current;
- result.Append(separator);
+ result.Append(separator, separatorLength);
if (currentValue != null)
{
result.Append(currentValue.ToString());
@@ -635,107 +734,113 @@ namespace System
}
}
- [ComVisible(false)]
- public static String Join(String separator, IEnumerable<String> values) {
- if (values == null)
- throw new ArgumentNullException("values");
- Contract.Ensures(Contract.Result<String>() != null);
- Contract.EndContractBlock();
-
- using(IEnumerator<String> en = values.GetEnumerator()) {
- if (!en.MoveNext())
- return String.Empty;
-
- String firstValue = en.Current;
-
- if (!en.MoveNext()) {
- // Only one value available
- return firstValue ?? String.Empty;
- }
-
- // Null separator and values are handled by the StringBuilder
- StringBuilder result = StringBuilderCache.Acquire();
- result.Append(firstValue);
-
- do {
- result.Append(separator);
- result.Append(en.Current);
- } while (en.MoveNext());
- return StringBuilderCache.GetStringAndRelease(result);
- }
- }
+ private unsafe static string JoinCore(char* separator, int separatorLength, string[] value, int startIndex, int count)
+ {
+ // If the separator is null, it is converted to an empty string before entering this function.
+ // Even for empty strings, fixed should never return null (it should return a pointer to a null char).
+ Debug.Assert(separator != null);
+ Debug.Assert(separatorLength >= 0);
- // Joins an array of strings together as one string with a separator between each original string.
- //
- [System.Security.SecuritySafeCritical] // auto-generated
- public unsafe static String Join(String separator, String[] value, int startIndex, int count) {
- //Range check the array
if (value == null)
- throw new ArgumentNullException("value");
-
+ {
+ throw new ArgumentNullException(nameof(value));
+ }
if (startIndex < 0)
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
+ {
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
+ }
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NegativeCount"));
-
+ {
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NegativeCount"));
+ }
if (startIndex > value.Length - count)
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
- Contract.EndContractBlock();
-
- //Treat null as empty string.
- if (separator == null) {
- separator = String.Empty;
+ {
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
}
-
- //If count is 0, that skews a whole bunch of the calculations below, so just special case that.
- if (count == 0) {
- return String.Empty;
+
+ if (count <= 1)
+ {
+ return count == 0 ?
+ string.Empty :
+ value[startIndex] ?? string.Empty;
}
- if (count == 1) {
- return value[startIndex] ?? String.Empty;
+ long totalSeparatorsLength = (long)(count - 1) * separatorLength;
+ if (totalSeparatorsLength > int.MaxValue)
+ {
+ throw new OutOfMemoryException();
}
+ int totalLength = (int)totalSeparatorsLength;
- int jointLength = 0;
- //Figure out the total length of the strings in value
- int endIndex = startIndex + count - 1;
- for (int stringToJoinIndex = startIndex; stringToJoinIndex <= endIndex; stringToJoinIndex++) {
- string currentValue = value[stringToJoinIndex];
-
- if (currentValue != null) {
- jointLength += currentValue.Length;
+ // Calculate the length of the resultant string so we know how much space to allocate.
+ for (int i = startIndex, end = startIndex + count; i < end; i++)
+ {
+ string currentValue = value[i];
+ if (currentValue != null)
+ {
+ totalLength += currentValue.Length;
+ if (totalLength < 0) // Check for overflow
+ {
+ throw new OutOfMemoryException();
+ }
}
}
-
- //Add enough room for the separator.
- jointLength += (count - 1) * separator.Length;
- // Note that we may not catch all overflows with this check (since we could have wrapped around the 4gb range any number of times
- // and landed back in the positive range.) The input array might be modifed from other threads,
- // so we have to do an overflow check before each append below anyway. Those overflows will get caught down there.
- if ((jointLength < 0) || ((jointLength + 1) < 0) ) {
- throw new OutOfMemoryException();
- }
+ // Copy each of the strings into the resultant buffer, interleaving with the separator.
+ string result = FastAllocateString(totalLength);
+ int copiedLength = 0;
- //If this is an empty string, just return.
- if (jointLength == 0) {
- return String.Empty;
- }
+ for (int i = startIndex, end = startIndex + count; i < end; i++)
+ {
+ // It's possible that another thread may have mutated the input array
+ // such that our second read of an index will not be the same string
+ // we got during the first read.
- string jointString = FastAllocateString( jointLength );
- fixed (char * pointerToJointString = &jointString.m_firstChar) {
- UnSafeCharBuffer charBuffer = new UnSafeCharBuffer( pointerToJointString, jointLength);
-
- // Append the first string first and then append each following string prefixed by the separator.
- charBuffer.AppendString( value[startIndex] );
- for (int stringToJoinIndex = startIndex + 1; stringToJoinIndex <= endIndex; stringToJoinIndex++) {
- charBuffer.AppendString( separator );
- charBuffer.AppendString( value[stringToJoinIndex] );
+ // We range check again to avoid buffer overflows if this happens.
+
+ string currentValue = value[i];
+ if (currentValue != null)
+ {
+ int valueLen = currentValue.Length;
+ if (valueLen > totalLength - copiedLength)
+ {
+ copiedLength = -1;
+ break;
+ }
+
+ // Fill in the value.
+ FillStringChecked(result, copiedLength, currentValue);
+ copiedLength += valueLen;
+ }
+
+ if (i < end - 1)
+ {
+ // Fill in the separator.
+ fixed (char* pResult = &result.m_firstChar)
+ {
+ // If we are called from the char-based overload, we will not
+ // want to call MemoryCopy each time we fill in the separator. So
+ // specialize for 1-length separators.
+ if (separatorLength == 1)
+ {
+ pResult[copiedLength] = *separator;
+ }
+ else
+ {
+ wstrcpy(pResult + copiedLength, separator, separatorLength);
+ }
+ }
+ copiedLength += separatorLength;
}
- Contract.Assert(*(pointerToJointString + charBuffer.Length) == '\0', "String must be null-terminated!");
}
- return jointString;
+ // If we copied exactly the right amount, return the new string. Otherwise,
+ // something changed concurrently to mutate the input array: fall back to
+ // doing the concatenation again, but this time with a defensive copy. This
+ // fall back should be extremely rare.
+ return copiedLength == totalLength ?
+ result :
+ JoinCore(separator, separatorLength, (string[])value.Clone(), startIndex, count);
}
//
@@ -746,10 +851,9 @@ namespace System
}
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
public String PadLeft(int totalWidth, char paddingChar) {
if (totalWidth < 0)
- throw new ArgumentOutOfRangeException("totalWidth", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(totalWidth), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
int oldLength = Length;
int count = totalWidth - oldLength;
if (count <= 0)
@@ -776,10 +880,9 @@ namespace System
}
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
public String PadRight(int totalWidth, char paddingChar) {
if (totalWidth < 0)
- throw new ArgumentOutOfRangeException("totalWidth", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(totalWidth), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
int oldLength = Length;
int count = totalWidth - oldLength;
if (count <= 0)
@@ -800,17 +903,16 @@ namespace System
return result;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public String Remove(int startIndex, int count)
{
if (startIndex < 0)
- throw new ArgumentOutOfRangeException("startIndex",
+ throw new ArgumentOutOfRangeException(nameof(startIndex),
Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count",
+ throw new ArgumentOutOfRangeException(nameof(count),
Environment.GetResourceString("ArgumentOutOfRange_NegativeCount"));
if (count > Length - startIndex)
- throw new ArgumentOutOfRangeException("count",
+ throw new ArgumentOutOfRangeException(nameof(count),
Environment.GetResourceString("ArgumentOutOfRange_IndexCount"));
Contract.Ensures(Contract.Result<String>() != null);
Contract.Ensures(Contract.Result<String>().Length == this.Length - count);
@@ -840,12 +942,12 @@ namespace System
// a remove that just takes a startindex.
public string Remove( int startIndex ) {
if (startIndex < 0) {
- throw new ArgumentOutOfRangeException("startIndex",
+ throw new ArgumentOutOfRangeException(nameof(startIndex),
Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
}
if (startIndex >= Length) {
- throw new ArgumentOutOfRangeException("startIndex",
+ throw new ArgumentOutOfRangeException(nameof(startIndex),
Environment.GetResourceString("ArgumentOutOfRange_StartIndexLessThanLength"));
}
@@ -857,7 +959,6 @@ namespace System
// Replaces all instances of oldChar with newChar.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public String Replace(char oldChar, char newChar)
{
Contract.Ensures(Contract.Result<String>() != null);
@@ -928,14 +1029,13 @@ namespace System
// This method contains the same functionality as StringBuilder Replace. The only difference is that
// a new String has to be allocated since Strings are immutable
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern String ReplaceInternal(String oldValue, String newValue);
public String Replace(String oldValue, String newValue)
{
if (oldValue == null)
- throw new ArgumentNullException("oldValue");
+ throw new ArgumentNullException(nameof(oldValue));
// Note that if newValue is null, we treat it like String.Empty.
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
@@ -944,19 +1044,13 @@ namespace System
}
[ComVisible(false)]
- public String[] Split(char separator) {
- Contract.Ensures(Contract.Result<String[]>() != null);
- return SplitInternal(separator, Int32.MaxValue, StringSplitOptions.None);
- }
-
- [ComVisible(false)]
- public String[] Split(char separator, StringSplitOptions options) {
+ public String[] Split(char separator, StringSplitOptions options = StringSplitOptions.None) {
Contract.Ensures(Contract.Result<String[]>() != null);
return SplitInternal(separator, Int32.MaxValue, options);
}
[ComVisible(false)]
- public String[] Split(char separator, int count, StringSplitOptions options) {
+ public String[] Split(char separator, int count, StringSplitOptions options = StringSplitOptions.None) {
Contract.Ensures(Contract.Result<String[]>() != null);
return SplitInternal(separator, count, options);
}
@@ -1004,33 +1098,24 @@ namespace System
return SplitInternal(separator, count, options);
}
- [System.Security.SecuritySafeCritical]
private unsafe String[] SplitInternal(char separator, int count, StringSplitOptions options)
{
- char* pSeparators = stackalloc char[1];
- pSeparators[0] = separator;
- return SplitInternal(pSeparators, /*separatorsLength*/ 1, count, options);
+ return SplitInternal(&separator, 1, count, options);
}
- [ComVisible(false)]
- [System.Security.SecuritySafeCritical]
- internal String[] SplitInternal(char[] separator, int count, StringSplitOptions options)
+ private unsafe String[] SplitInternal(char[] separator, int count, StringSplitOptions options)
{
- unsafe
+ fixed (char* pSeparators = separator)
{
- fixed (char* pSeparators = separator)
- {
- int separatorsLength = separator == null ? 0 : separator.Length;
- return SplitInternal(pSeparators, separatorsLength, count, options);
- }
+ int separatorsLength = separator == null ? 0 : separator.Length;
+ return SplitInternal(pSeparators, separatorsLength, count, options);
}
}
- [System.Security.SecurityCritical]
private unsafe String[] SplitInternal(char* separators, int separatorsLength, int count, StringSplitOptions options)
{
if (count < 0)
- throw new ArgumentOutOfRangeException("count",
+ throw new ArgumentOutOfRangeException(nameof(count),
Environment.GetResourceString("ArgumentOutOfRange_NegativeCount"));
if (options < StringSplitOptions.None || options > StringSplitOptions.RemoveEmptyEntries)
@@ -1041,14 +1126,8 @@ namespace System
bool omitEmptyEntries = (options == StringSplitOptions.RemoveEmptyEntries);
if ((count == 0) || (omitEmptyEntries && this.Length == 0))
- {
-#if FEATURE_CORECLR
+ {
return EmptyArray<String>.Value;
-#else
- // Keep the old behavior of returning a new empty array
- // to mitigate any potential compat risk.
- return new String[0];
-#endif
}
if (count == 1)
@@ -1056,38 +1135,32 @@ namespace System
return new String[] { this };
}
- int[] sepList = new int[Length];
+ int[] sepList = new int[Length];
int numReplaces = MakeSeparatorList(separators, separatorsLength, sepList);
// Handle the special case of no replaces.
if (0 == numReplaces) {
return new String[] { this };
- }
+ }
if(omitEmptyEntries)
{
- return InternalSplitOmitEmptyEntries(sepList, null, 1, numReplaces, count);
+ return SplitOmitEmptyEntries(sepList, null, 1, numReplaces, count);
}
else
{
- return InternalSplitKeepEmptyEntries(sepList, null, 1, numReplaces, count);
- }
- }
-
- [ComVisible(false)]
- public String[] Split(String separator) {
- Contract.Ensures(Contract.Result<String[]>() != null);
- return SplitInternal(separator ?? String.Empty, null, Int32.MaxValue, StringSplitOptions.None);
+ return SplitKeepEmptyEntries(sepList, null, 1, numReplaces, count);
+ }
}
[ComVisible(false)]
- public String[] Split(String separator, StringSplitOptions options) {
+ public String[] Split(String separator, StringSplitOptions options = StringSplitOptions.None) {
Contract.Ensures(Contract.Result<String[]>() != null);
return SplitInternal(separator ?? String.Empty, null, Int32.MaxValue, options);
}
[ComVisible(false)]
- public String[] Split(String separator, Int32 count, StringSplitOptions options) {
+ 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);
}
@@ -1107,7 +1180,7 @@ namespace System
private String[] SplitInternal(String separator, String[] separators, Int32 count, StringSplitOptions options)
{
if (count < 0) {
- throw new ArgumentOutOfRangeException("count",
+ throw new ArgumentOutOfRangeException(nameof(count),
Environment.GetResourceString("ArgumentOutOfRange_NegativeCount"));
}
@@ -1125,23 +1198,13 @@ namespace System
}
if ((count == 0) || (omitEmptyEntries && this.Length ==0)) {
-#if FEATURE_CORECLR
return EmptyArray<String>.Value;
-#else
- // Keep the old behavior of returning a new empty array
- // to mitigate any potential compat risk.
- return new String[0];
-#endif
}
- if (count == 1) {
+ if (count == 1 || (singleSeparator && separator.Length == 0)) {
return new String[] { this };
}
- if (singleSeparator && separator.Length == 0) {
- return new[] { this };
- }
-
int[] sepList = new int[Length];
int[] lengthList;
int defaultLength;
@@ -1164,10 +1227,10 @@ namespace System
}
if (omitEmptyEntries) {
- return InternalSplitOmitEmptyEntries(sepList, lengthList, defaultLength, numReplaces, count);
+ return SplitOmitEmptyEntries(sepList, lengthList, defaultLength, numReplaces, count);
}
else {
- return InternalSplitKeepEmptyEntries(sepList, lengthList, defaultLength, numReplaces, count);
+ return SplitKeepEmptyEntries(sepList, lengthList, defaultLength, numReplaces, count);
}
}
@@ -1176,7 +1239,7 @@ namespace System
// the original string will be returned regardless of the count.
//
- private String[] InternalSplitKeepEmptyEntries(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);
@@ -1212,7 +1275,7 @@ namespace System
// This function will not keep the Empty String
- private String[] InternalSplitOmitEmptyEntries(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);
@@ -1242,7 +1305,7 @@ namespace System
}
// we must have at least one slot left to fill in the last string.
- Contract.Assert(arrIndex < maxItems);
+ Debug.Assert(arrIndex < maxItems);
//Handle the last string at the end of the array if there is one.
if (currIndex< Length) {
@@ -1265,9 +1328,8 @@ namespace System
// Args: separator -- A string containing all of the split characters.
// sepList -- an array of ints for split char indicies.
//--------------------------------------------------------------------
- [System.Security.SecurityCritical]
private unsafe int MakeSeparatorList(char* separators, int separatorsLength, int[] sepList) {
- Contract.Assert(separatorsLength >= 0, "separatorsLength >= 0");
+ Debug.Assert(separatorsLength >= 0, "separatorsLength >= 0");
int foundCount=0;
if (separators == null || separatorsLength == 0) {
@@ -1304,9 +1366,8 @@ namespace System
// Args: separator -- the separator
// sepList -- an array of ints for split string indicies.
//--------------------------------------------------------------------
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe int MakeSeparatorList(string separator, int[] sepList) {
- Contract.Assert(!string.IsNullOrEmpty(separator), "!string.IsNullOrEmpty(separator)");
+ Debug.Assert(!string.IsNullOrEmpty(separator), "!string.IsNullOrEmpty(separator)");
int foundCount = 0;
int sepListCount = sepList.Length;
@@ -1334,9 +1395,8 @@ namespace System
// sepList -- an array of ints for split string indicies.
// lengthList -- an array of ints for split string lengths.
//--------------------------------------------------------------------
- [System.Security.SecuritySafeCritical] // auto-generated
private unsafe int MakeSeparatorList(String[] separators, int[] sepList, int[] lengthList) {
- Contract.Assert(separators != null && separators.Length > 0, "separators != null && separators.Length > 0");
+ Debug.Assert(separators != null && separators.Length > 0, "separators != null && separators.Length > 0");
int foundCount = 0;
int sepListCount = sepList.Length;
@@ -1374,24 +1434,23 @@ namespace System
// Returns a substring of this string.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public String Substring(int startIndex, int length) {
//Bounds Checking.
if (startIndex < 0) {
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
}
if (startIndex > Length) {
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndexLargerThanLength"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndexLargerThanLength"));
}
if (length < 0) {
- throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
+ throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
}
if (startIndex > Length - length) {
- throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_IndexLength"));
+ throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_IndexLength"));
}
Contract.EndContractBlock();
@@ -1406,10 +1465,9 @@ namespace System
return InternalSubString(startIndex, length);
}
- [System.Security.SecurityCritical] // auto-generated
unsafe string InternalSubString(int startIndex, int length) {
- Contract.Assert( startIndex >= 0 && startIndex <= this.Length, "StartIndex is out of range!");
- Contract.Assert( length >= 0 && startIndex <= this.Length - length, "length is out of range!");
+ 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);
@@ -1434,7 +1492,7 @@ namespace System
public String ToLower(CultureInfo culture) {
if (culture == null)
{
- throw new ArgumentNullException("culture");
+ throw new ArgumentNullException(nameof(culture));
}
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
@@ -1463,7 +1521,7 @@ namespace System
public String ToUpper(CultureInfo culture) {
if (culture == null)
{
- throw new ArgumentNullException("culture");
+ throw new ArgumentNullException(nameof(culture));
}
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
@@ -1517,7 +1575,6 @@ namespace System
}
- [System.Security.SecuritySafeCritical] // auto-generated
private String TrimHelper(int trimType) {
//end will point to the first non-trimmed character on the right
//start will point to the first non-trimmed character on the Left
@@ -1541,7 +1598,6 @@ namespace System
}
- [System.Security.SecuritySafeCritical] // auto-generated
private String TrimHelper(char[] trimChars, int trimType) {
//end will point to the first non-trimmed character on the right
//start will point to the first non-trimmed character on the Left
@@ -1579,7 +1635,6 @@ namespace System
}
- [System.Security.SecurityCritical] // auto-generated
private String CreateTrimmedString(int start, int end) {
int len = end -start + 1;
if (len == this.Length) {
diff --git a/src/mscorlib/src/System/String.Searching.cs b/src/mscorlib/src/System/String.Searching.cs
index b972529694..2620cfd0dc 100644
--- a/src/mscorlib/src/System/String.Searching.cs
+++ b/src/mscorlib/src/System/String.Searching.cs
@@ -29,13 +29,12 @@ namespace System
}
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe int IndexOf(char value, int startIndex, int count) {
if (startIndex < 0 || startIndex > Length)
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
if (count < 0 || count > Length - startIndex)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
fixed (char* pChars = &m_firstChar)
{
@@ -85,7 +84,6 @@ namespace System
}
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern int IndexOfAny(char [] anyOf, int startIndex, int count);
@@ -116,11 +114,11 @@ namespace System
[Pure]
public int IndexOf(String value, int startIndex, int count) {
if (startIndex < 0 || startIndex > this.Length) {
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
if (count < 0 || count > this.Length - startIndex) {
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
}
Contract.EndContractBlock();
@@ -138,17 +136,16 @@ namespace System
}
[Pure]
- [System.Security.SecuritySafeCritical]
public int IndexOf(String value, int startIndex, int count, StringComparison comparisonType) {
// Validate inputs
if (value == null)
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
if (startIndex < 0 || startIndex > this.Length)
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
if (count < 0 || startIndex > this.Length - count)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
Contract.EndContractBlock();
switch (comparisonType) {
@@ -174,7 +171,7 @@ namespace System
return TextInfo.IndexOfStringOrdinalIgnoreCase(this, value, startIndex, count);
default:
- throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), "comparisonType");
+ throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), nameof(comparisonType));
}
}
@@ -194,16 +191,15 @@ namespace System
}
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe int LastIndexOf(char value, int startIndex, int count) {
if (Length == 0)
return -1;
if (startIndex < 0 || startIndex >= Length)
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
if (count < 0 || count - 1 > startIndex)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
fixed (char* pChars = &m_firstChar)
{
@@ -258,7 +254,6 @@ namespace System
}
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern int LastIndexOfAny(char [] anyOf, int startIndex, int count);
@@ -281,7 +276,7 @@ namespace System
[Pure]
public int LastIndexOf(String value, int startIndex, int count) {
if (count<0) {
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
}
Contract.EndContractBlock();
@@ -299,10 +294,9 @@ namespace System
}
[Pure]
- [System.Security.SecuritySafeCritical]
public int LastIndexOf(String value, int startIndex, int count, StringComparison comparisonType) {
if (value == null)
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
Contract.EndContractBlock();
// Special case for 0 length input strings
@@ -311,7 +305,7 @@ namespace System
// Now after handling empty strings, make sure we're not out of range
if (startIndex < 0 || startIndex > this.Length)
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
// Make sure that we allow startIndex == this.Length
if (startIndex == this.Length)
@@ -327,7 +321,7 @@ 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("count", Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
switch (comparisonType) {
@@ -351,7 +345,7 @@ namespace System
else
return TextInfo.LastIndexOfStringOrdinalIgnoreCase(this, value, startIndex, count);
default:
- throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), "comparisonType");
+ throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), nameof(comparisonType));
}
}
}
diff --git a/src/mscorlib/src/System/String.cs b/src/mscorlib/src/System/String.cs
index d406fd09b3..f9162ff528 100644
--- a/src/mscorlib/src/System/String.cs
+++ b/src/mscorlib/src/System/String.cs
@@ -24,6 +24,7 @@ namespace System {
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using Microsoft.Win32;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Security;
@@ -67,7 +68,6 @@ 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.
//
- [System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static string SmallCharToUpper(string strIn) {
Contract.Requires(strIn != null);
Contract.EndContractBlock();
@@ -83,7 +83,7 @@ namespace System {
for(int i = 0; i < length; i++) {
int c = inBuff[i];
- Contract.Assert(c <= 0x7F, "string has to be ASCII");
+ Debug.Assert(c <= 0x7F, "string has to be ASCII");
// uppercase - notice that we need just one compare
if ((uint)(c - 'a') <= (uint)('z' - 'a')) c -= 0x20;
@@ -91,7 +91,7 @@ namespace System {
outBuff[i] = (char)c;
}
- Contract.Assert(outBuff[length]=='\0', "outBuff[length]=='\0'");
+ Debug.Assert(outBuff[length]=='\0', "outBuff[length]=='\0'");
}
return strOut;
}
@@ -102,7 +102,6 @@ namespace System {
[System.Runtime.CompilerServices.IndexerName("Chars")]
public extern char this[int index] {
[MethodImpl(MethodImplOptions.InternalCall)]
- [System.Security.SecuritySafeCritical] // public member
get;
}
@@ -111,19 +110,18 @@ namespace System {
// sourceIndex + count - 1 to the character array buffer, beginning
// at destinationIndex.
//
- [System.Security.SecuritySafeCritical] // auto-generated
unsafe public void CopyTo(int sourceIndex, char[] destination, int destinationIndex, int count)
{
if (destination == null)
- throw new ArgumentNullException("destination");
+ throw new ArgumentNullException(nameof(destination));
if (count < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NegativeCount"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NegativeCount"));
if (sourceIndex < 0)
- throw new ArgumentOutOfRangeException("sourceIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(sourceIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
if (count > Length - sourceIndex)
- throw new ArgumentOutOfRangeException("sourceIndex", Environment.GetResourceString("ArgumentOutOfRange_IndexCount"));
+ throw new ArgumentOutOfRangeException(nameof(sourceIndex), Environment.GetResourceString("ArgumentOutOfRange_IndexCount"));
if (destinationIndex > destination.Length - count || destinationIndex < 0)
- throw new ArgumentOutOfRangeException("destinationIndex", Environment.GetResourceString("ArgumentOutOfRange_IndexCount"));
+ throw new ArgumentOutOfRangeException(nameof(destinationIndex), Environment.GetResourceString("ArgumentOutOfRange_IndexCount"));
Contract.EndContractBlock();
// Note: fixed does not like empty arrays
@@ -136,7 +134,6 @@ namespace System {
}
// Returns the entire string as an array of characters.
- [System.Security.SecuritySafeCritical] // auto-generated
unsafe public char[] ToCharArray() {
int length = Length;
if (length > 0)
@@ -148,24 +145,19 @@ namespace System {
}
return chars;
}
-
-#if FEATURE_CORECLR
+
return Array.Empty<char>();
-#else
- return new char[0];
-#endif
}
// Returns a substring of this string as an array of characters.
//
- [System.Security.SecuritySafeCritical] // auto-generated
unsafe public char[] ToCharArray(int startIndex, int length)
{
// Range check everything.
if (startIndex < 0 || startIndex > Length || startIndex > Length - length)
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
if (length < 0)
- throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_Index"));
Contract.EndContractBlock();
if (length > 0)
@@ -177,12 +169,8 @@ namespace System {
}
return chars;
}
-
-#if FEATURE_CORECLR
+
return Array.Empty<char>();
-#else
- return new char[0];
-#endif
}
[Pure]
@@ -210,7 +198,6 @@ namespace System {
//
// Spec#: Add postcondition in a contract assembly. Potential perf problem.
public extern int Length {
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
get;
}
@@ -218,36 +205,30 @@ namespace System {
// Creates a new string with the characters copied in from ptr. If
// ptr is null, a 0-length string (like String.Empty) is returned.
//
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
unsafe public extern String(char *value);
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
unsafe public extern String(char *value, int startIndex, int length);
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
unsafe public extern String(sbyte *value);
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
unsafe public extern String(sbyte *value, int startIndex, int length);
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
unsafe public extern String(sbyte *value, int startIndex, int length, Encoding enc);
- [System.Security.SecurityCritical] // auto-generated
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("length", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (startIndex < 0)
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
if ((value + startIndex) < value) {
// overflow check
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_PartialWCHAR"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_PartialWCHAR"));
}
byte [] b = new byte[length];
@@ -258,7 +239,7 @@ namespace System {
catch(NullReferenceException) {
// If we got a NullReferencException. It means the pointer or
// the index is out of range
- throw new ArgumentOutOfRangeException("value",
+ throw new ArgumentOutOfRangeException(nameof(value),
Environment.GetResourceString("ArgumentOutOfRange_PartialWCHAR"));
}
@@ -267,7 +248,6 @@ namespace System {
// Helper for encodings so they can talk to our buffer directly
// stringLength must be the exact size we'll expect
- [System.Security.SecurityCritical] // auto-generated
unsafe static internal String CreateStringFromEncoding(
byte* bytes, int byteLength, Encoding encoding)
{
@@ -276,7 +256,7 @@ namespace System {
// Get our string length
int stringLength = encoding.GetCharCount(bytes, byteLength, null);
- Contract.Assert(stringLength >= 0, "stringLength >= 0");
+ 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
@@ -287,7 +267,7 @@ namespace System {
fixed(char* pTempChars = &s.m_firstChar)
{
int doubleCheck = encoding.GetChars(bytes, byteLength, pTempChars, stringLength, null);
- Contract.Assert(stringLength == doubleCheck,
+ Debug.Assert(stringLength == doubleCheck,
"Expected encoding.GetChars to return same length as encoding.GetCharCount");
}
@@ -297,7 +277,6 @@ namespace System {
// This is only intended to be used by char.ToString.
// It is necessary to put the code in this class instead of Char, since m_firstChar is a private member.
// Making m_firstChar internal would be dangerous since it would make it much easier to break String's immutability.
- [SecuritySafeCritical]
internal static string CreateFromChar(char c)
{
string result = FastAllocateString(1);
@@ -305,7 +284,6 @@ namespace System {
return result;
}
- [System.Security.SecuritySafeCritical] // auto-generated
unsafe internal int GetBytesFromEncoding(byte* pbNativeBuffer, int cbNativeBuffer,Encoding encoding)
{
// encoding == Encoding.UTF8
@@ -315,10 +293,9 @@ namespace System {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
unsafe internal int ConvertToAnsi(byte *pbNativeBuffer, int cbNativeBuffer, bool fBestFit, bool fThrowOnUnmappableChar)
{
- Contract.Assert(cbNativeBuffer >= (Length + 1) * Marshal.SystemMaxDBCSCharSize, "Insufficient buffer length passed to ConvertToAnsi");
+ Debug.Assert(cbNativeBuffer >= (Length + 1) * Marshal.SystemMaxDBCSCharSize, "Insufficient buffer length passed to ConvertToAnsi");
const uint CP_ACP = 0;
int nb;
@@ -363,7 +340,6 @@ namespace System {
#endif
}
- [System.Security.SecuritySafeCritical] // auto-generated
public bool IsNormalized(NormalizationForm normalizationForm)
{
#if !FEATURE_NORM_IDNA_ONLY
@@ -391,7 +367,6 @@ namespace System {
#endif
}
- [System.Security.SecuritySafeCritical] // auto-generated
public String Normalize(NormalizationForm normalizationForm)
{
#if !FEATURE_NORM_IDNA_ONLY
@@ -408,7 +383,6 @@ namespace System {
return Normalization.Normalize(this, normalizationForm);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static String FastAllocateString(int length);
@@ -416,7 +390,6 @@ namespace System {
// be created from the characters in value between startIndex and
// startIndex + length - 1.
//
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern String(char [] value, int startIndex, int length);
@@ -424,17 +397,14 @@ namespace System {
// created from the characters in value.
//
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern String(char [] value);
- [System.Security.SecurityCritical] // auto-generated
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)
}
- [System.Security.SecuritySafeCritical] // auto-generated
private String CtorCharArray(char [] value)
{
if (value != null && value.Length != 0) {
@@ -451,20 +421,19 @@ namespace System {
return String.Empty;
}
- [System.Security.SecuritySafeCritical] // auto-generated
private String CtorCharArrayStartLength(char [] value, int startIndex, int length)
{
if (value == null)
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
if (startIndex < 0)
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
if (length < 0)
- throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
+ throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
if (startIndex > value.Length - length)
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
Contract.EndContractBlock();
if (length > 0) {
@@ -481,7 +450,6 @@ namespace System {
return String.Empty;
}
- [System.Security.SecuritySafeCritical] // auto-generated
private String CtorCharCount(char c, int count)
{
if (count > 0) {
@@ -519,10 +487,9 @@ namespace System {
else if (count == 0)
return String.Empty;
else
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_MustBeNonNegNum", "count"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_MustBeNonNegNum", nameof(count)));
}
- [System.Security.SecurityCritical] // auto-generated
private static unsafe int wcslen(char *ptr)
{
char *end = ptr;
@@ -553,7 +520,7 @@ namespace System {
end += 2;
}
- Contract.Assert(end[0] == 0 || end[1] == 0);
+ Debug.Assert(end[0] == 0 || end[1] == 0);
if (end[0] != 0) end++;
#else // !BIT64
// Based on https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord
@@ -610,14 +577,13 @@ namespace System {
#endif // !BIT64
FoundZero:
- Contract.Assert(*end == 0);
+ Debug.Assert(*end == 0);
int count = (int)(end - ptr);
return count;
}
- [System.Security.SecurityCritical] // auto-generated
private unsafe String CtorCharPtr(char *ptr)
{
if (ptr == null)
@@ -628,7 +594,7 @@ namespace System {
throw new ArgumentException(Environment.GetResourceString("Arg_MustBeStringPtrNotAtom"));
#endif // FEATURE_PAL
- Contract.Assert(this == null, "this == null"); // this is the string constructor, we allocate it
+ Debug.Assert(this == null, "this == null"); // this is the string constructor, we allocate it
try {
int count = wcslen(ptr);
@@ -641,27 +607,26 @@ namespace System {
return result;
}
catch (NullReferenceException) {
- throw new ArgumentOutOfRangeException("ptr", Environment.GetResourceString("ArgumentOutOfRange_PartialWCHAR"));
+ throw new ArgumentOutOfRangeException(nameof(ptr), Environment.GetResourceString("ArgumentOutOfRange_PartialWCHAR"));
}
}
- [System.Security.SecurityCritical] // auto-generated
private unsafe String CtorCharPtrStartLength(char *ptr, int startIndex, int length)
{
if (length < 0) {
- throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
+ throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
}
if (startIndex < 0) {
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
}
Contract.EndContractBlock();
- Contract.Assert(this == null, "this == null"); // this is the string constructor, we allocate it
+ Debug.Assert(this == null, "this == null"); // this is the string constructor, we allocate it
char *pFrom = ptr + startIndex;
if (pFrom < ptr) {
// This means that the pointer operation has had an overflow
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_PartialWCHAR"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_PartialWCHAR"));
}
if (length == 0)
@@ -675,11 +640,10 @@ namespace System {
return result;
}
catch (NullReferenceException) {
- throw new ArgumentOutOfRangeException("ptr", Environment.GetResourceString("ArgumentOutOfRange_PartialWCHAR"));
+ throw new ArgumentOutOfRangeException(nameof(ptr), Environment.GetResourceString("ArgumentOutOfRange_PartialWCHAR"));
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern String(char c, int count);
@@ -705,10 +669,9 @@ namespace System {
return this;
}
- [System.Security.SecuritySafeCritical] // auto-generated
unsafe public static String Copy (String str) {
if (str==null) {
- throw new ArgumentNullException("str");
+ throw new ArgumentNullException(nameof(str));
}
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
@@ -724,10 +687,9 @@ namespace System {
return result;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static String Intern(String str) {
if (str==null) {
- throw new ArgumentNullException("str");
+ throw new ArgumentNullException(nameof(str));
}
Contract.Ensures(Contract.Result<String>().Length == str.Length);
Contract.Ensures(str.Equals(Contract.Result<String>()));
@@ -737,10 +699,9 @@ namespace System {
}
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
public static String IsInterned(String str) {
if (str==null) {
- throw new ArgumentNullException("str");
+ throw new ArgumentNullException(nameof(str));
}
Contract.Ensures(Contract.Result<String>() == null || Contract.Result<String>().Length == str.Length);
Contract.EndContractBlock();
@@ -834,31 +795,25 @@ namespace System {
// Is this a string that can be compared quickly (that is it has only characters > 0x80
// and not a - or '
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern bool IsFastSort();
// Is this a string that only contains characters < 0x80.
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern bool IsAscii();
// Set extra byte for odd-sized strings that came from interop as BSTR.
- [System.Security.SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern void SetTrailByte(byte data);
// Try to retrieve the extra byte - returns false if not present.
- [System.Security.SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern bool TryGetTrailByte(out byte data);
-#if !FEATURE_CORECLR
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);
}
-#endif // !FEATURE_CORECLR
IEnumerator<char> IEnumerable<char>.GetEnumerator() {
Contract.Ensures(Contract.Result<IEnumerator<char>>() != null);
@@ -876,7 +831,6 @@ namespace System {
}
// Copies the source String (byte buffer) to the destination IntPtr memory allocated with len bytes.
- [System.Security.SecurityCritical] // auto-generated
internal unsafe static void InternalCopy(String src, IntPtr dest,int len)
{
if (len == 0)
@@ -886,6 +840,12 @@ namespace System {
byte* dstPtr = (byte*) dest;
Buffer.Memcpy(dstPtr, srcPtr, len);
}
- }
+ }
+
+#if FEATURE_SPAN_OF_T
+ internal ref char GetFirstCharRef() {
+ return ref m_firstChar;
+ }
+#endif
}
}
diff --git a/src/mscorlib/src/System/StringComparer.cs b/src/mscorlib/src/System/StringComparer.cs
index 57bdf4c6b2..02e8d71d0e 100644
--- a/src/mscorlib/src/System/StringComparer.cs
+++ b/src/mscorlib/src/System/StringComparer.cs
@@ -62,9 +62,31 @@ namespace System {
}
}
+ // 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("culture");
+ throw new ArgumentNullException(nameof(culture));
}
Contract.Ensures(Contract.Result<StringComparer>() != null);
Contract.EndContractBlock();
@@ -110,7 +132,7 @@ namespace System {
public int GetHashCode(object obj) {
if( obj == null) {
- throw new ArgumentNullException("obj");
+ throw new ArgumentNullException(nameof(obj));
}
Contract.EndContractBlock();
@@ -161,7 +183,7 @@ namespace System {
public override int GetHashCode(string obj) {
if( obj == null) {
- throw new ArgumentNullException("obj");
+ throw new ArgumentNullException(nameof(obj));
}
Contract.EndContractBlock();
@@ -229,7 +251,7 @@ namespace System {
public override int GetHashCode(string obj) {
if( obj == null) {
- throw new ArgumentNullException("obj");
+ throw new ArgumentNullException(nameof(obj));
}
Contract.EndContractBlock();
@@ -311,7 +333,7 @@ namespace System {
public override int GetHashCode(string obj) {
if( obj == null) {
- throw new ArgumentNullException("obj");
+ throw new ArgumentNullException(nameof(obj));
}
Contract.EndContractBlock();
@@ -385,10 +407,9 @@ namespace System {
return x.Equals(y);
}
- [System.Security.SecuritySafeCritical]
public override int GetHashCode(string obj) {
if( obj == null) {
- throw new ArgumentNullException("obj");
+ throw new ArgumentNullException(nameof(obj));
}
Contract.EndContractBlock();
diff --git a/src/mscorlib/src/System/StubHelpers.cs b/src/mscorlib/src/System/StubHelpers.cs
index a9c584e9fc..26a227628a 100644
--- a/src/mscorlib/src/System/StubHelpers.cs
+++ b/src/mscorlib/src/System/StubHelpers.cs
@@ -16,6 +16,7 @@ namespace System.StubHelpers {
#endif // FEATURE_COMINTEROP
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
@@ -23,7 +24,6 @@ namespace System.StubHelpers {
{
// The length of the returned array is an approximation based on the length of the input string and the system
// character set. It is only guaranteed to be larger or equal to cbLength, don't depend on the exact value.
- [System.Security.SecurityCritical]
unsafe static internal byte[] DoAnsiConversion(string str, bool fBestFit, bool fThrowOnUnmappableChar, out int cbLength)
{
byte[] buffer = new byte[(str.Length + 1) * Marshal.SystemMaxDBCSCharSize];
@@ -34,7 +34,6 @@ namespace System.StubHelpers {
return buffer;
}
- [System.Security.SecurityCritical]
unsafe static internal byte ConvertToNative(char managedChar, bool fBestFit, bool fThrowOnUnmappableChar)
{
int cbAllocLength = (1 + 1) * Marshal.SystemMaxDBCSCharSize;
@@ -57,7 +56,6 @@ namespace System.StubHelpers {
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal static class CSTRMarshaler
{
- [System.Security.SecurityCritical] // auto-generated
static internal unsafe IntPtr ConvertToNative(int flags, string strManaged, IntPtr pNativeBuffer)
{
if (null == strManaged)
@@ -109,7 +107,6 @@ namespace System.StubHelpers {
return (IntPtr)pbNativeBuffer;
}
- [System.Security.SecurityCritical] // auto-generated
static internal unsafe string ConvertToManaged(IntPtr cstr)
{
if (IntPtr.Zero == cstr)
@@ -118,7 +115,6 @@ namespace System.StubHelpers {
return new String((sbyte*)cstr);
}
- [System.Security.SecurityCritical] // auto-generated
static internal void ClearNative(IntPtr pNative)
{
Win32Native.CoTaskMemFree(pNative);
@@ -129,7 +125,6 @@ namespace System.StubHelpers {
internal static class UTF8Marshaler
{
const int MAX_UTF8_CHAR_SIZE = 3;
- [System.Security.SecurityCritical]
static internal unsafe IntPtr ConvertToNative(int flags, string strManaged, IntPtr pNativeBuffer)
{
if (null == strManaged)
@@ -166,7 +161,6 @@ namespace System.StubHelpers {
return (IntPtr)pbNativeBuffer;
}
- [System.Security.SecurityCritical]
static internal unsafe string ConvertToManaged(IntPtr cstr)
{
if (IntPtr.Zero == cstr)
@@ -175,7 +169,6 @@ namespace System.StubHelpers {
return String.CreateStringFromEncoding((byte*)cstr, nbBytes, Encoding.UTF8);
}
- [System.Security.SecurityCritical]
static internal void ClearNative(IntPtr pNative)
{
if (pNative != IntPtr.Zero)
@@ -188,7 +181,6 @@ namespace System.StubHelpers {
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal static class UTF8BufferMarshaler
{
- [System.Security.SecurityCritical]
static internal unsafe IntPtr ConvertToNative(StringBuilder sb, IntPtr pNativeBuffer, int flags)
{
if (null == sb)
@@ -210,7 +202,6 @@ namespace System.StubHelpers {
return (IntPtr)pbNativeBuffer;
}
- [System.Security.SecurityCritical]
static internal unsafe void ConvertToManaged(StringBuilder sb, IntPtr pNative)
{
if (pNative == null)
@@ -241,7 +232,6 @@ namespace System.StubHelpers {
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal static class BSTRMarshaler
{
- [System.Security.SecurityCritical] // auto-generated
static internal unsafe IntPtr ConvertToNative(string strManaged, IntPtr pNativeBuffer)
{
if (null == strManaged)
@@ -311,7 +301,6 @@ namespace System.StubHelpers {
}
}
- [System.Security.SecurityCritical] // auto-generated
static internal unsafe string ConvertToManaged(IntPtr bstr)
{
if (IntPtr.Zero == bstr)
@@ -356,7 +345,6 @@ namespace System.StubHelpers {
}
}
- [System.Security.SecurityCritical] // auto-generated
static internal void ClearNative(IntPtr pNative)
{
if (IntPtr.Zero != pNative)
@@ -372,7 +360,6 @@ namespace System.StubHelpers {
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal static class VBByValStrMarshaler
{
- [System.Security.SecurityCritical] // auto-generated
static internal unsafe IntPtr ConvertToNative(string strManaged, bool fBestFit, bool fThrowOnUnmappableChar, ref int cch)
{
if (null == strManaged)
@@ -414,7 +401,6 @@ namespace System.StubHelpers {
return new IntPtr(pNative);
}
- [System.Security.SecurityCritical] // auto-generated
static internal unsafe string ConvertToManaged(IntPtr pNative, int cch)
{
if (IntPtr.Zero == pNative)
@@ -425,7 +411,6 @@ namespace System.StubHelpers {
return new String((sbyte*)pNative, 0, cch);
}
- [System.Security.SecurityCritical] // auto-generated
static internal unsafe void ClearNative(IntPtr pNative)
{
if (IntPtr.Zero != pNative)
@@ -441,7 +426,6 @@ namespace System.StubHelpers {
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal static class AnsiBSTRMarshaler
{
- [System.Security.SecurityCritical] // auto-generated
static internal unsafe IntPtr ConvertToNative(int flags, string strManaged)
{
if (null == strManaged)
@@ -464,7 +448,6 @@ namespace System.StubHelpers {
return Win32Native.SysAllocStringByteLen(bytes, (uint)nb);
}
- [System.Security.SecurityCritical] // auto-generated
static internal unsafe string ConvertToManaged(IntPtr bstr)
{
if (IntPtr.Zero == bstr)
@@ -480,7 +463,6 @@ namespace System.StubHelpers {
}
}
- [System.Security.SecurityCritical] // auto-generated
static internal unsafe void ClearNative(IntPtr pNative)
{
if (IntPtr.Zero != pNative)
@@ -498,19 +480,19 @@ namespace System.StubHelpers {
{
static internal IntPtr ConvertToNative(string strManaged)
{
- Contract.Assert(false, "NYI");
+ Debug.Assert(false, "NYI");
return IntPtr.Zero;
}
static internal unsafe string ConvertToManaged(IntPtr bstr)
{
- Contract.Assert(false, "NYI");
+ Debug.Assert(false, "NYI");
return null;
}
static internal void ClearNative(IntPtr pNative)
{
- Contract.Assert(false, "NYI");
+ Debug.Assert(false, "NYI");
}
} // class WSTRBufferMarshaler
@@ -531,14 +513,12 @@ namespace System.StubHelpers {
// You can get this through: (new DateTimeOffset(1601, 1, 1, 0, 0, 1, TimeSpan.Zero)).Ticks;
private const Int64 ManagedUtcTicksAtNativeZero = 504911232000000000;
- [SecurityCritical]
internal static void ConvertToNative(ref DateTimeOffset managedDTO, out DateTimeNative dateTime) {
Int64 managedUtcTicks = managedDTO.UtcTicks;
dateTime.UniversalTime = managedUtcTicks - ManagedUtcTicksAtNativeZero;
}
- [SecurityCritical]
internal static void ConvertToManaged(out DateTimeOffset managedLocalDTO, ref DateTimeNative nativeTicks) {
Int64 managedUtcTicks = ManagedUtcTicksAtNativeZero + nativeTicks.UniversalTime;
@@ -558,7 +538,6 @@ namespace System.StubHelpers {
internal static class HStringMarshaler
{
// Slow-path, which requires making a copy of the managed string into the resulting HSTRING
- [SecurityCritical]
internal static unsafe IntPtr ConvertToNative(string managed)
{
if (!Environment.IsWinRTSupported)
@@ -578,7 +557,6 @@ namespace System.StubHelpers {
// Note that the managed string input to this method MUST be pinned, and stay pinned for the lifetime of
// 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.
- [SecurityCritical]
internal static unsafe IntPtr ConvertToNativeReference(string managed,
[Out] HSTRING_HEADER *hstringHeader)
{
@@ -598,7 +576,6 @@ namespace System.StubHelpers {
}
}
- [SecurityCritical]
internal static string ConvertToManaged(IntPtr hstring)
{
if (!Environment.IsWinRTSupported)
@@ -609,10 +586,9 @@ namespace System.StubHelpers {
return WindowsRuntimeMarshal.HStringToString(hstring);
}
- [SecurityCritical]
internal static void ClearNative(IntPtr hstring)
{
- Contract.Assert(Environment.IsWinRTSupported);
+ Debug.Assert(Environment.IsWinRTSupported);
if (hstring != IntPtr.Zero)
{
@@ -639,7 +615,6 @@ namespace System.StubHelpers {
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal static class ValueClassMarshaler
{
- [SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern void ConvertToNative(IntPtr dst, IntPtr src, IntPtr pMT, ref CleanupWorkList pCleanupWorkList);
@@ -672,7 +647,6 @@ namespace System.StubHelpers {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern object ConvertToManaged(IntPtr pUnk, IntPtr itfMT, IntPtr classMT, int flags);
- [SecurityCritical]
[DllImport(JitHelpers.QCall), SuppressUnmanagedCodeSecurity]
static internal extern void ClearNative(IntPtr pUnk);
@@ -690,10 +664,8 @@ namespace System.StubHelpers {
static internal extern string GetRawUriFromNative(IntPtr pUri);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [System.Security.SecurityCritical]
static unsafe internal extern IntPtr CreateNativeUriInstanceHelper(char* rawUri, int strLen);
- [System.Security.SecurityCritical]
static unsafe internal IntPtr CreateNativeUriInstance(string rawUri)
{
fixed(char* pManaged = rawUri)
@@ -707,7 +679,6 @@ namespace System.StubHelpers {
[FriendAccessAllowed]
internal static class EventArgsMarshaler
{
- [SecurityCritical]
[FriendAccessAllowed]
static internal IntPtr CreateNativeNCCEventArgsInstance(int action, object newItems, object oldItems, int newIndex, int oldIndex)
{
@@ -733,12 +704,10 @@ namespace System.StubHelpers {
}
}
- [SecurityCritical]
[FriendAccessAllowed]
[DllImport(JitHelpers.QCall), SuppressUnmanagedCodeSecurity]
static extern internal IntPtr CreateNativePCEventArgsInstance([MarshalAs(UnmanagedType.HString)]string name);
- [SecurityCritical]
[DllImport(JitHelpers.QCall), SuppressUnmanagedCodeSecurity]
static extern internal IntPtr CreateNativeNCCEventArgsInstanceHelper(int action, IntPtr newItem, IntPtr oldItem, int newIndex, int oldIndex);
}
@@ -796,19 +765,15 @@ namespace System.StubHelpers {
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal static class MngdHiddenLengthArrayMarshaler
{
- [SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern void CreateMarshaler(IntPtr pMarshalState, IntPtr pMT, IntPtr cbElementSize, ushort vt);
- [SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void ConvertSpaceToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
- [SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void ConvertContentsToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
- [SecurityCritical]
internal static unsafe void ConvertContentsToNative_DateTime(ref DateTimeOffset[] managedArray, IntPtr pNativeHome)
{
if (managedArray != null)
@@ -821,7 +786,6 @@ namespace System.StubHelpers {
}
}
- [SecurityCritical]
internal static unsafe void ConvertContentsToNative_Type(ref System.Type[] managedArray, IntPtr pNativeHome)
{
if (managedArray != null)
@@ -834,7 +798,6 @@ namespace System.StubHelpers {
}
}
- [SecurityCritical]
internal static unsafe void ConvertContentsToNative_Exception(ref Exception[] managedArray, IntPtr pNativeHome)
{
if (managedArray != null)
@@ -847,7 +810,6 @@ namespace System.StubHelpers {
}
}
- [SecurityCritical]
internal static unsafe void ConvertContentsToNative_Nullable<T>(ref Nullable<T>[] managedArray, IntPtr pNativeHome)
where T : struct
{
@@ -861,7 +823,6 @@ namespace System.StubHelpers {
}
}
- [SecurityCritical]
internal static unsafe void ConvertContentsToNative_KeyValuePair<K, V>(ref KeyValuePair<K, V>[] managedArray, IntPtr pNativeHome)
{
if (managedArray != null)
@@ -874,15 +835,12 @@ namespace System.StubHelpers {
}
}
- [SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void ConvertSpaceToManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome, int elementCount);
- [SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void ConvertContentsToManaged(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
- [SecurityCritical]
internal static unsafe void ConvertContentsToManaged_DateTime(ref DateTimeOffset[] managedArray, IntPtr pNativeHome)
{
if (managedArray != null)
@@ -895,7 +853,6 @@ namespace System.StubHelpers {
}
}
- [SecurityCritical]
internal static unsafe void ConvertContentsToManaged_Type(ref System.Type[] managedArray, IntPtr pNativeHome)
{
if (managedArray != null)
@@ -908,7 +865,6 @@ namespace System.StubHelpers {
}
}
- [SecurityCritical]
internal static unsafe void ConvertContentsToManaged_Exception(ref Exception[] managedArray, IntPtr pNativeHome)
{
if (managedArray != null)
@@ -921,7 +877,6 @@ namespace System.StubHelpers {
}
}
- [SecurityCritical]
internal static unsafe void ConvertContentsToManaged_Nullable<T>(ref Nullable<T>[] managedArray, IntPtr pNativeHome)
where T : struct
{
@@ -935,7 +890,6 @@ namespace System.StubHelpers {
}
}
- [SecurityCritical]
internal static unsafe void ConvertContentsToManaged_KeyValuePair<K, V>(ref KeyValuePair<K, V>[] managedArray, IntPtr pNativeHome)
{
if (managedArray != null)
@@ -948,14 +902,12 @@ namespace System.StubHelpers {
}
}
- [SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void ClearNativeContents(IntPtr pMarshalState, IntPtr pNativeHome, int cElements);
- [SecurityCritical]
internal static unsafe void ClearNativeContents_Type(IntPtr pNativeHome, int cElements)
{
- Contract.Assert(Environment.IsWinRTSupported);
+ Debug.Assert(Environment.IsWinRTSupported);
TypeNameNative *pNativeTypeArray = *(TypeNameNative **)pNativeHome;
if (pNativeTypeArray != null)
@@ -991,7 +943,6 @@ namespace System.StubHelpers {
} // class MngdRefCustomMarshaler
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
- [System.Security.SecurityCritical]
internal struct AsAnyMarshaler
{
private const ushort VTHACK_ANSICHAR = 253;
@@ -1037,7 +988,6 @@ namespace System.StubHelpers {
#region ConvertToNative helpers
- [System.Security.SecurityCritical]
private unsafe IntPtr ConvertArrayToNative(object pManagedHome, int dwFlags)
{
Type elementType = pManagedHome.GetType().GetElementType();
@@ -1109,7 +1059,6 @@ namespace System.StubHelpers {
return pNativeHome;
}
- [System.Security.SecurityCritical]
private static IntPtr ConvertStringToNative(string pManagedHome, int dwFlags)
{
IntPtr pNativeHome;
@@ -1137,7 +1086,6 @@ namespace System.StubHelpers {
return pNativeHome;
}
- [System.Security.SecurityCritical]
private unsafe IntPtr ConvertStringBuilderToNative(StringBuilder pManagedHome, int dwFlags)
{
IntPtr pNativeHome;
@@ -1176,7 +1124,7 @@ namespace System.StubHelpers {
ptr, allocSize,
IsBestFit(dwFlags),
IsThrowOn(dwFlags));
- Contract.Assert(length < allocSize, "Expected a length less than the allocated size");
+ Debug.Assert(length < allocSize, "Expected a length less than the allocated size");
}
if (IsOut(dwFlags))
{
@@ -1211,7 +1159,6 @@ namespace System.StubHelpers {
return pNativeHome;
}
- [System.Security.SecurityCritical]
private unsafe IntPtr ConvertLayoutToNative(object pManagedHome, int dwFlags)
{
// Note that the following call will not throw exception if the type
@@ -1237,7 +1184,6 @@ namespace System.StubHelpers {
#endregion
- [System.Security.SecurityCritical]
internal IntPtr ConvertToNative(object pManagedHome, int dwFlags)
{
if (pManagedHome == null)
@@ -1283,7 +1229,6 @@ namespace System.StubHelpers {
return pNativeHome;
}
- [System.Security.SecurityCritical]
internal unsafe void ConvertToManaged(object pManagedHome, IntPtr pNativeHome)
{
switch (backPropAction)
@@ -1321,7 +1266,6 @@ namespace System.StubHelpers {
}
}
- [System.Security.SecurityCritical]
internal void ClearNative(IntPtr pNativeHome)
{
if (pNativeHome != IntPtr.Zero)
@@ -1341,7 +1285,6 @@ namespace System.StubHelpers {
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal static class NullableMarshaler
{
- [SecurityCritical]
static internal IntPtr ConvertToNative<T>(ref Nullable<T> pManaged) where T : struct
{
if (pManaged.HasValue)
@@ -1355,14 +1298,12 @@ namespace System.StubHelpers {
}
}
- [SecurityCritical]
static internal void ConvertToManagedRetVoid<T>(IntPtr pNative, ref Nullable<T> retObj) where T : struct
{
retObj = ConvertToManaged<T>(pNative);
}
- [SecurityCritical]
static internal Nullable<T> ConvertToManaged<T>(IntPtr pNative) where T : struct
{
if (pNative != IntPtr.Zero)
@@ -1406,7 +1347,6 @@ namespace System.StubHelpers {
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal static class SystemTypeMarshaler
{
- [SecurityCritical]
internal static unsafe void ConvertToNative(System.Type managedType, TypeNameNative *pNativeType)
{
if (!Environment.IsWinRTSupported)
@@ -1450,7 +1390,6 @@ namespace System.StubHelpers {
Marshal.ThrowExceptionForHR(hrCreate, new IntPtr(-1));
}
- [SecurityCritical]
internal static unsafe void ConvertToManaged(TypeNameNative *pNativeType, ref System.Type managedType)
{
if (!Environment.IsWinRTSupported)
@@ -1480,10 +1419,9 @@ namespace System.StubHelpers {
}
}
- [SecurityCritical]
internal static unsafe void ClearNative(TypeNameNative *pNativeType)
{
- Contract.Assert(Environment.IsWinRTSupported);
+ Debug.Assert(Environment.IsWinRTSupported);
if (pNativeType->typeName != IntPtr.Zero)
{
@@ -1509,7 +1447,6 @@ namespace System.StubHelpers {
return ex._HResult;
}
- [SecuritySafeCritical]
static internal unsafe Exception ConvertToManaged(int hr)
{
Contract.Ensures(Contract.Result<Exception>() != null || hr >= 0);
@@ -1527,7 +1464,7 @@ namespace System.StubHelpers {
// S_OK should be marshaled as null. WinRT API's should not return S_FALSE by convention.
// We've chosen to treat S_FALSE as success and return null.
- Contract.Assert(e != null || hr == 0 || hr == 1, "Unexpected HRESULT - it is a success HRESULT (without the high bit set) other than S_OK & S_FALSE.");
+ Debug.Assert(e != null || hr == 0 || hr == 1, "Unexpected HRESULT - it is a success HRESULT (without the high bit set) other than S_OK & S_FALSE.");
return e;
}
} // class HResultExceptionMarshaler
@@ -1535,14 +1472,12 @@ namespace System.StubHelpers {
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal static class KeyValuePairMarshaler
{
- [SecurityCritical]
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>));
}
- [SecurityCritical]
internal static KeyValuePair<K, V> ConvertToManaged<K, V>(IntPtr pInsp)
{
object obj = InterfaceMarshaler.ConvertToManagedWithoutUnboxing(pInsp);
@@ -1552,7 +1487,6 @@ namespace System.StubHelpers {
}
// Called from COMInterfaceMarshaler
- [SecurityCritical]
internal static object ConvertToManagedBox<K, V>(IntPtr pInsp)
{
return (object)ConvertToManaged<K, V>(pInsp);
@@ -1583,48 +1517,9 @@ namespace System.StubHelpers {
#endif
} // struct NativeVariant
-#if !BIT64 && !FEATURE_CORECLR
- // Structure filled by IL stubs if copy constructor(s) and destructor(s) need to be called
- // on value types pushed on the stack. The structure is stored in s_copyCtorStubDesc by
- // SetCopyCtorCookieChain and fetched by CopyCtorCallStubWorker. Must be stack-allocated.
- [StructLayout(LayoutKind.Sequential)]
- unsafe internal struct CopyCtorStubCookie
- {
- public void SetData(IntPtr srcInstancePtr, uint dstStackOffset, IntPtr ctorPtr, IntPtr dtorPtr)
- {
- m_srcInstancePtr = srcInstancePtr;
- m_dstStackOffset = dstStackOffset;
- m_ctorPtr = ctorPtr;
- m_dtorPtr = dtorPtr;
- }
-
- public void SetNext(IntPtr pNext)
- {
- m_pNext = pNext;
- }
-
- public IntPtr m_srcInstancePtr; // pointer to the source instance
- public uint m_dstStackOffset; // offset from the start of stack arguments of the pushed 'this' instance
-
- public IntPtr m_ctorPtr; // fnptr to the managed copy constructor, result of ldftn
- public IntPtr m_dtorPtr; // fnptr to the managed destructor, result of ldftn
-
- public IntPtr m_pNext; // pointer to next cookie in the chain or IntPtr.Zero
- } // struct CopyCtorStubCookie
-
- // Aggregates pointer to CopyCtorStubCookie and the target of the interop call.
- [StructLayout(LayoutKind.Sequential)]
- unsafe internal struct CopyCtorStubDesc
- {
- public IntPtr m_pCookie;
- public IntPtr m_pTarget;
- } // struct CopyCtorStubDes
-#endif // !BIT64 && !FEATURE_CORECLR
-
// Aggregates SafeHandle and the "owned" bit which indicates whether the SafeHandle
// has been successfully AddRef'ed. This allows us to do realiable cleanup (Release)
// if and only if it is needed.
- [System.Security.SecurityCritical]
internal sealed class CleanupWorkListElement
{
public CleanupWorkListElement(SafeHandle handle)
@@ -1640,7 +1535,6 @@ namespace System.StubHelpers {
} // class CleanupWorkListElement
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
- [System.Security.SecurityCritical]
internal sealed class CleanupWorkList
{
private List<CleanupWorkListElement> m_list = new List<CleanupWorkListElement>();
@@ -1662,7 +1556,6 @@ namespace System.StubHelpers {
}
} // class CleanupWorkList
- [System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
[SuppressUnmanagedCodeSecurityAttribute()]
internal static class StubHelpers
@@ -1679,33 +1572,8 @@ namespace System.StubHelpers {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern IntPtr GetDelegateTarget(Delegate pThis, ref IntPtr pStubArg);
-#if !BIT64 && !FEATURE_CORECLR
- // Written to by a managed stub helper, read by CopyCtorCallStubWorker in VM.
- [ThreadStatic]
- static CopyCtorStubDesc s_copyCtorStubDesc;
-
- static internal void SetCopyCtorCookieChain(IntPtr pStubArg, IntPtr pUnmngThis, int dwStubFlags, IntPtr pCookie)
- {
- // we store both the cookie chain head and the target of the copy ctor stub to a thread
- // static field to be accessed by the copy ctor (see code:CopyCtorCallStubWorker)
- s_copyCtorStubDesc.m_pCookie = pCookie;
- s_copyCtorStubDesc.m_pTarget = GetFinalStubTarget(pStubArg, pUnmngThis, dwStubFlags);
- }
-
- // Returns the final unmanaged stub target, ignores interceptors.
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- static internal extern IntPtr GetFinalStubTarget(IntPtr pStubArg, IntPtr pUnmngThis, int dwStubFlags);
-#endif // !FEATURE_CORECLR && !BIT64
-
-#if !FEATURE_CORECLR
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- static internal extern void DemandPermission(IntPtr pNMD);
-#endif // !FEATURE_CORECLR
-
-#if FEATURE_CORECLR
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern void ClearLastError();
-#endif
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern void SetLastError();
@@ -1713,7 +1581,6 @@ namespace System.StubHelpers {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern void ThrowInteropParamException(int resID, int paramIdx);
- [System.Security.SecurityCritical]
static internal IntPtr AddToCleanupList(ref CleanupWorkList pCleanupWorkList, SafeHandle handle)
{
if (pCleanupWorkList == null)
@@ -1726,7 +1593,6 @@ namespace System.StubHelpers {
return SafeHandleAddRef(handle, ref element.m_owned);
}
- [System.Security.SecurityCritical]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
static internal void DestroyCleanupList(ref CleanupWorkList pCleanupWorkList)
{
@@ -1775,12 +1641,11 @@ namespace System.StubHelpers {
//-------------------------------------------------------
// AddRefs the SH and returns the underlying unmanaged handle.
- [System.Security.SecurityCritical] // auto-generated
static internal IntPtr SafeHandleAddRef(SafeHandle pHandle, ref bool success)
{
if (pHandle == null)
{
- throw new ArgumentNullException("pHandle", Environment.GetResourceString("ArgumentNull_SafeHandle"));
+ throw new ArgumentNullException(nameof(pHandle), Environment.GetResourceString("ArgumentNull_SafeHandle"));
}
Contract.EndContractBlock();
@@ -1790,13 +1655,12 @@ namespace System.StubHelpers {
}
// Releases the SH (to be called from finally block).
- [System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
static internal void SafeHandleRelease(SafeHandle pHandle)
{
if (pHandle == null)
{
- throw new ArgumentNullException("pHandle", Environment.GetResourceString("ArgumentNull_SafeHandle"));
+ throw new ArgumentNullException(nameof(pHandle), Environment.GetResourceString("ArgumentNull_SafeHandle"));
}
Contract.EndContractBlock();
@@ -1848,15 +1712,12 @@ namespace System.StubHelpers {
static internal extern IntPtr GetDelegateInvokeMethod(Delegate pThis);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [System.Security.SecurityCritical]
static internal extern object GetWinRTFactoryObject(IntPtr pCPCMD);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [System.Security.SecurityCritical]
static internal extern IntPtr GetWinRTFactoryReturnValue(object pThis, IntPtr pCtorEntry);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [System.Security.SecurityCritical]
static internal extern IntPtr GetOuterInspectable(object pThis, IntPtr pCtorMD);
#if MDA_SUPPORTED
diff --git a/src/mscorlib/src/System/Text/ASCIIEncoding.cs b/src/mscorlib/src/System/Text/ASCIIEncoding.cs
index bf1a62df55..fc7589f2d8 100644
--- a/src/mscorlib/src/System/Text/ASCIIEncoding.cs
+++ b/src/mscorlib/src/System/Text/ASCIIEncoding.cs
@@ -7,6 +7,7 @@ namespace System.Text
using System;
using System.Runtime.Serialization;
using System.Security.Permissions;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
// ASCIIEncoding
@@ -70,7 +71,6 @@ namespace System.Text
return EncodingForwarder.GetByteCount(this, chars);
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public override unsafe int GetByteCount(char* chars, int count)
@@ -99,7 +99,6 @@ namespace System.Text
return EncodingForwarder.GetBytes(this, chars, charIndex, charCount, bytes, byteIndex);
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
@@ -115,7 +114,6 @@ namespace System.Text
return EncodingForwarder.GetCharCount(this, bytes, index, count);
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public override unsafe int GetCharCount(byte* bytes, int count)
@@ -129,7 +127,6 @@ namespace System.Text
return EncodingForwarder.GetChars(this, bytes, byteIndex, byteCount, chars, charIndex);
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
@@ -150,15 +147,14 @@ namespace System.Text
// GetByteCount
// Note: We start by assuming that the output will be the same as count. Having
// an encoder or fallback may change that assumption
- [System.Security.SecurityCritical] // auto-generated
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
- Contract.Assert(charCount >= 0, "[ASCIIEncoding.GetByteCount]count is negative");
- Contract.Assert(chars != null, "[ASCIIEncoding.GetByteCount]chars is null");
+ 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.
- Contract.Assert(encoderFallback != null, "[ASCIIEncoding.GetByteCount]Attempting to use null fallback encoder");
+ Debug.Assert(encoderFallback != null, "[ASCIIEncoding.GetByteCount]Attempting to use null fallback encoder");
char charLeftOver = (char)0;
EncoderReplacementFallback fallback = null;
@@ -172,7 +168,7 @@ namespace System.Text
if (encoder != null)
{
charLeftOver = encoder.charLeftOver;
- Contract.Assert(charLeftOver == 0 || Char.IsHighSurrogate(charLeftOver),
+ Debug.Assert(charLeftOver == 0 || Char.IsHighSurrogate(charLeftOver),
"[ASCIIEncoding.GetByteCount]leftover character should be high surrogate");
fallback = encoder.Fallback as EncoderReplacementFallback;
@@ -191,7 +187,7 @@ namespace System.Text
}
// Verify that we have no fallbackbuffer, for ASCII its always empty, so just assert
- Contract.Assert(!encoder.m_throwOnOverflow || !encoder.InternalHasFallbackBuffer ||
+ Debug.Assert(!encoder.m_throwOnOverflow || !encoder.InternalHasFallbackBuffer ||
encoder.FallbackBuffer.Remaining == 0,
"[ASCIICodePageEncoding.GetByteCount]Expected empty fallback buffer");
// if (encoder.InternalHasFallbackBuffer && encoder.FallbackBuffer.Remaining > 0)
@@ -228,8 +224,8 @@ namespace System.Text
// We may have a left over character from last time, try and process it.
if (charLeftOver > 0)
{
- Contract.Assert(Char.IsHighSurrogate(charLeftOver), "[ASCIIEncoding.GetByteCount]leftover character should be high surrogate");
- Contract.Assert(encoder != null, "[ASCIIEncoding.GetByteCount]Expected encoder");
+ 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
@@ -279,24 +275,23 @@ namespace System.Text
byteCount++;
}
- Contract.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
"[ASCIIEncoding.GetByteCount]Expected Empty fallback buffer");
return byteCount;
}
- [System.Security.SecurityCritical] // auto-generated
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
- Contract.Assert(bytes != null, "[ASCIIEncoding.GetBytes]bytes is null");
- Contract.Assert(byteCount >= 0, "[ASCIIEncoding.GetBytes]byteCount is negative");
- Contract.Assert(chars != null, "[ASCIIEncoding.GetBytes]chars is null");
- Contract.Assert(charCount >= 0, "[ASCIIEncoding.GetBytes]charCount is negative");
+ 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.
- Contract.Assert(encoderFallback != null, "[ASCIIEncoding.GetBytes]Attempting to use null encoder fallback");
+ Debug.Assert(encoderFallback != null, "[ASCIIEncoding.GetBytes]Attempting to use null encoder fallback");
// Get any left over characters
char charLeftOver = (char)0;
@@ -328,11 +323,11 @@ namespace System.Text
fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, true);
}
- Contract.Assert(charLeftOver == 0 || Char.IsHighSurrogate(charLeftOver),
+ 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
- Contract.Assert(!encoder.m_throwOnOverflow || !encoder.InternalHasFallbackBuffer ||
+ Debug.Assert(!encoder.m_throwOnOverflow || !encoder.InternalHasFallbackBuffer ||
encoder.FallbackBuffer.Remaining == 0,
"[ASCIICodePageEncoding.GetBytes]Expected empty fallback buffer");
// if (encoder.m_throwOnOverflow && encoder.InternalHasFallbackBuffer &&
@@ -411,7 +406,7 @@ namespace System.Text
if (charLeftOver > 0)
{
// Initialize the buffer
- Contract.Assert(encoder != null,
+ 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);
@@ -465,7 +460,7 @@ namespace System.Text
// didn't use this char, we'll throw or use buffer
if (fallbackBuffer == null || fallbackBuffer.bFallingBack == false)
{
- Contract.Assert(chars > charStart || bytes == byteStart,
+ Debug.Assert(chars > charStart || bytes == byteStart,
"[ASCIIEncoding.GetBytes]Expected chars to have advanced already.");
chars--; // don't use last char
}
@@ -494,7 +489,7 @@ namespace System.Text
encoder.m_charsUsed = (int)(chars - charStart);
}
- Contract.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0 ||
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0 ||
(encoder != null && !encoder.m_throwOnOverflow ),
"[ASCIIEncoding.GetBytes]Expected Empty fallback buffer at end");
@@ -502,12 +497,11 @@ namespace System.Text
}
// This is internal and called by something else,
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS decoder)
{
// Just assert, we're called internally so these should be safe, checked already
- Contract.Assert(bytes != null, "[ASCIIEncoding.GetCharCount]bytes is null");
- Contract.Assert(count >= 0, "[ASCIIEncoding.GetCharCount]byteCount is negative");
+ 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;
@@ -517,7 +511,7 @@ namespace System.Text
else
{
fallback = decoder.Fallback as DecoderReplacementFallback;
- Contract.Assert(!decoder.m_throwOnOverflow || !decoder.InternalHasFallbackBuffer ||
+ Debug.Assert(!decoder.m_throwOnOverflow || !decoder.InternalHasFallbackBuffer ||
decoder.FallbackBuffer.Remaining == 0,
"[ASCIICodePageEncoding.GetCharCount]Expected empty fallback buffer");
}
@@ -568,22 +562,21 @@ namespace System.Text
}
// Fallback buffer must be empty
- Contract.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
"[ASCIIEncoding.GetCharCount]Expected Empty fallback buffer");
// Converted sequence is same length as input
return charCount;
}
- [System.Security.SecurityCritical] // auto-generated
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
- Contract.Assert(bytes != null, "[ASCIIEncoding.GetChars]bytes is null");
- Contract.Assert(byteCount >= 0, "[ASCIIEncoding.GetChars]byteCount is negative");
- Contract.Assert(chars != null, "[ASCIIEncoding.GetChars]chars is null");
- Contract.Assert(charCount >= 0, "[ASCIIEncoding.GetChars]charCount is negative");
+ 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;
@@ -600,7 +593,7 @@ namespace System.Text
else
{
fallback = decoder.Fallback as DecoderReplacementFallback;
- Contract.Assert(!decoder.m_throwOnOverflow || !decoder.InternalHasFallbackBuffer ||
+ Debug.Assert(!decoder.m_throwOnOverflow || !decoder.InternalHasFallbackBuffer ||
decoder.FallbackBuffer.Remaining == 0,
"[ASCIICodePageEncoding.GetChars]Expected empty fallback buffer");
}
@@ -668,7 +661,7 @@ namespace System.Text
if (!fallbackBuffer.InternalFallback(byteBuffer, bytes, ref chars))
{
// May or may not throw, but we didn't get this byte
- Contract.Assert(bytes > byteStart || chars == charStart,
+ 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
@@ -681,7 +674,7 @@ namespace System.Text
// Make sure we have buffer space
if (chars >= charEnd)
{
- Contract.Assert(bytes > byteStart || chars == charStart,
+ Debug.Assert(bytes > byteStart || chars == charStart,
"[ASCIIEncoding.GetChars]Expected bytes to have advanced already (normal case)");
bytes--; // unused byte
ThrowCharsOverflow(decoder, chars == charStart); // throw?
@@ -698,7 +691,7 @@ namespace System.Text
decoder.m_bytesUsed = (int)(bytes - byteStart);
// Expect Empty fallback buffer for GetChars
- Contract.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
"[ASCIIEncoding.GetChars]Expected Empty fallback buffer");
return (int)(chars - charStart);
@@ -708,7 +701,7 @@ namespace System.Text
public override int GetMaxByteCount(int charCount)
{
if (charCount < 0)
- throw new ArgumentOutOfRangeException("charCount",
+ throw new ArgumentOutOfRangeException(nameof(charCount),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -721,7 +714,7 @@ namespace System.Text
// 1 to 1 for most characters. Only surrogates with fallbacks have less.
if (byteCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException("charCount", Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
+ throw new ArgumentOutOfRangeException(nameof(charCount), Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
return (int)byteCount;
}
@@ -729,7 +722,7 @@ namespace System.Text
public override int GetMaxCharCount(int byteCount)
{
if (byteCount < 0)
- throw new ArgumentOutOfRangeException("byteCount",
+ throw new ArgumentOutOfRangeException(nameof(byteCount),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -741,7 +734,7 @@ namespace System.Text
charCount *= DecoderFallback.MaxCharCount;
if (charCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException("byteCount", Environment.GetResourceString("ArgumentOutOfRange_GetCharCountOverflow"));
+ throw new ArgumentOutOfRangeException(nameof(byteCount), Environment.GetResourceString("ArgumentOutOfRange_GetCharCountOverflow"));
return (int)charCount;
}
diff --git a/src/mscorlib/src/System/Text/BaseCodePageEncoding.cs b/src/mscorlib/src/System/Text/BaseCodePageEncoding.cs
index 4c9ca6eaaf..0a42237dc1 100644
--- a/src/mscorlib/src/System/Text/BaseCodePageEncoding.cs
+++ b/src/mscorlib/src/System/Text/BaseCodePageEncoding.cs
@@ -6,6 +6,7 @@
namespace System.Text
{
using System;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Globalization;
using System.Runtime.InteropServices;
@@ -72,7 +73,6 @@ namespace System.Text
[NonSerialized]
protected bool m_bUseMlangTypeForSerialization = false;
- [System.Security.SecuritySafeCritical] // static constructors should be safe to call
static BaseCodePageEncoding()
{
}
@@ -136,32 +136,26 @@ namespace System.Text
}
// Initialize our global stuff
- [SecurityCritical]
unsafe static CodePageDataFileHeader* m_pCodePageFileHeader =
(CodePageDataFileHeader*)GlobalizationAssembly.GetGlobalizationResourceBytePtr(
typeof(CharUnicodeInfo).Assembly, CODE_PAGE_DATA_FILE_NAME);
// Real variables
[NonSerialized]
- [SecurityCritical]
unsafe protected CodePageHeader* pCodePage = null;
// Safe handle wrapper around section map view
- [System.Security.SecurityCritical] // auto-generated
[NonSerialized]
protected SafeViewOfFileHandle safeMemorySectionHandle = null;
// Safe handle wrapper around mapped file handle
- [System.Security.SecurityCritical] // auto-generated
[NonSerialized]
protected SafeFileMappingHandle safeFileMappingHandle = null;
- [System.Security.SecurityCritical] // auto-generated
internal BaseCodePageEncoding(int codepage) : this(codepage, codepage)
{
}
- [System.Security.SecurityCritical] // auto-generated
internal BaseCodePageEncoding(int codepage, int dataCodePage) :
base(codepage == 0? Microsoft.Win32.Win32Native.GetACP(): codepage)
{
@@ -171,7 +165,6 @@ namespace System.Text
}
// Constructor called by serialization.
- [System.Security.SecurityCritical] // auto-generated
internal BaseCodePageEncoding(SerializationInfo info, StreamingContext context) : base(0)
{
// We cannot ever call this, we've proxied ourselved to CodePageEncoding
@@ -179,12 +172,11 @@ namespace System.Text
}
// ISerializable implementation
- [System.Security.SecurityCritical] // auto-generated_required
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
// Make sure to get the base stuff too This throws if info is null
SerializeEncoding(info, context);
- Contract.Assert(info!=null, "[BaseCodePageEncoding.GetObjectData] Expected null info to throw");
+ Debug.Assert(info!=null, "[BaseCodePageEncoding.GetObjectData] Expected null info to throw");
// Just need Everett maxCharSize (BaseCodePageEncoding) or m_maxByteSize (MLangBaseCodePageEncoding)
info.AddValue(m_bUseMlangTypeForSerialization ? "m_maxByteSize" : "maxCharSize",
@@ -196,7 +188,6 @@ namespace System.Text
}
// We need to load tables for our code page
- [System.Security.SecurityCritical] // auto-generated
private unsafe void LoadCodePageTables()
{
CodePageHeader* pCodePage = FindCodePage(dataTableCodePage);
@@ -217,7 +208,6 @@ namespace System.Text
}
// Look up the code page pointer
- [System.Security.SecurityCritical] // auto-generated
private static unsafe CodePageHeader* FindCodePage(int codePage)
{
// We'll have to loop through all of the m_pCodePageIndex[] items to find our code page, this isn't
@@ -240,7 +230,6 @@ namespace System.Text
}
// Get our code page byte count
- [System.Security.SecurityCritical] // auto-generated
internal static unsafe int GetCodePageByteSize(int codePage)
{
// Get our code page info
@@ -250,18 +239,16 @@ namespace System.Text
if (pCodePage == null)
return 0;
- Contract.Assert(pCodePage->ByteCount == 1 || pCodePage->ByteCount == 2,
+ Debug.Assert(pCodePage->ByteCount == 1 || pCodePage->ByteCount == 2,
"[BaseCodePageEncoding] Code page (" + codePage + ") has invalid byte size (" + pCodePage->ByteCount + ") in table");
// Return what it says for byte count
return pCodePage->ByteCount;
}
// We have a managed code page entry, so load our tables
- [System.Security.SecurityCritical]
protected abstract unsafe void LoadManagedCodePage();
// Allocate memory to load our code page
- [System.Security.SecurityCritical] // auto-generated
protected unsafe byte* GetSharedMemory(int iSize)
{
// Build our name
@@ -271,7 +258,7 @@ namespace System.Text
// This gets shared memory for our map. If its can't, it gives us clean memory.
Byte *pMemorySection = EncodingTable.nativeCreateOpenFileMapping(strName, iSize, out mappedFileHandle);
- Contract.Assert(pMemorySection != null,
+ Debug.Assert(pMemorySection != null,
"[BaseCodePageEncoding.GetSharedMemory] Expected non-null memory section to be opened");
// If that failed, we have to die.
@@ -291,7 +278,6 @@ namespace System.Text
return pMemorySection;
}
- [System.Security.SecurityCritical] // auto-generated
protected unsafe virtual String GetMemorySectionName()
{
int iUseCodePage = this.bFlagDataTable ? dataTableCodePage : CodePage;
@@ -303,29 +289,26 @@ namespace System.Text
return strName;
}
- [System.Security.SecurityCritical]
protected abstract unsafe void ReadBestFitTable();
- [System.Security.SecuritySafeCritical]
internal override char[] GetBestFitUnicodeToBytesData()
{
// Read in our best fit table if necessary
if (arrayUnicodeBestFit == null) ReadBestFitTable();
- Contract.Assert(arrayUnicodeBestFit != null,
+ Debug.Assert(arrayUnicodeBestFit != null,
"[BaseCodePageEncoding.GetBestFitUnicodeToBytesData]Expected non-null arrayUnicodeBestFit");
// Normally we don't have any best fit data.
return arrayUnicodeBestFit;
}
- [System.Security.SecuritySafeCritical]
internal override char[] GetBestFitBytesToUnicodeData()
{
// Read in our best fit table if necessary
if (arrayBytesBestFit == null) ReadBestFitTable();
- Contract.Assert(arrayBytesBestFit != null,
+ Debug.Assert(arrayBytesBestFit != null,
"[BaseCodePageEncoding.GetBestFitBytesToUnicodeData]Expected non-null arrayBytesBestFit");
// Normally we don't have any best fit data.
@@ -336,7 +319,6 @@ namespace System.Text
// is invalid. so we detect that by validating the memory section handle then re-initialize the memory
// section by calling LoadManagedCodePage() method and eventually the mapped file handle and
// the memory section pointer will get finalized one more time.
- [System.Security.SecurityCritical] // auto-generated
internal unsafe void CheckMemorySection()
{
if (safeMemorySectionHandle != null && safeMemorySectionHandle.DangerousGetHandle() == IntPtr.Zero)
diff --git a/src/mscorlib/src/System/Text/CodePageEncoding.cs b/src/mscorlib/src/System/Text/CodePageEncoding.cs
index 9f1b2d2620..7805c6580a 100644
--- a/src/mscorlib/src/System/Text/CodePageEncoding.cs
+++ b/src/mscorlib/src/System/Text/CodePageEncoding.cs
@@ -11,6 +11,7 @@ namespace System.Text
using System;
using System.Runtime.Serialization;
using System.Security.Permissions;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
/*=================================CodePageEncoding==================================
@@ -44,7 +45,7 @@ namespace System.Text
internal CodePageEncoding(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException("info");
+ if (info==null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// All versions have a code page
@@ -74,7 +75,6 @@ namespace System.Text
}
// Just get it from GetEncoding
- [System.Security.SecurityCritical] // auto-generated
public Object GetRealObject(StreamingContext context)
{
// Get our encoding (Note: This has default fallbacks for readonly and everett cases)
@@ -93,11 +93,10 @@ namespace System.Text
}
// ISerializable implementation
- [System.Security.SecurityCritical] // auto-generated_required
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
// We cannot ever call this.
- Contract.Assert(false, "Didn't expect to make it to CodePageEncoding ISerializable.GetObjectData");
+ Debug.Assert(false, "Didn't expect to make it to CodePageEncoding ISerializable.GetObjectData");
throw new ArgumentException(Environment.GetResourceString("Arg_ExecutionEngineException"));
}
@@ -113,25 +112,23 @@ namespace System.Text
internal Decoder(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException("info");
+ if (info==null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
this.realEncoding = (Encoding)info.GetValue("encoding", typeof(Encoding));
}
// Just get it from GetDecider
- [System.Security.SecurityCritical] // auto-generated
public Object GetRealObject(StreamingContext context)
{
return this.realEncoding.GetDecoder();
}
// ISerializable implementation, get data for this object
- [System.Security.SecurityCritical] // auto-generated_required
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
// We cannot ever call this.
- Contract.Assert(false, "Didn't expect to make it to CodePageEncoding.Decoder.GetObjectData");
+ Debug.Assert(false, "Didn't expect to make it to CodePageEncoding.Decoder.GetObjectData");
throw new ArgumentException(Environment.GetResourceString("Arg_ExecutionEngineException"));
}
}
diff --git a/src/mscorlib/src/System/Text/DBCSCodePageEncoding.cs b/src/mscorlib/src/System/Text/DBCSCodePageEncoding.cs
index c103d7898f..28b85d591e 100644
--- a/src/mscorlib/src/System/Text/DBCSCodePageEncoding.cs
+++ b/src/mscorlib/src/System/Text/DBCSCodePageEncoding.cs
@@ -6,6 +6,7 @@
namespace System.Text
{
using System;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Text;
using System.Threading;
@@ -20,13 +21,10 @@ namespace System.Text
{
// Pointers to our memory section parts
[NonSerialized]
- [SecurityCritical]
protected unsafe char* mapBytesToUnicode = null; // char 65536
[NonSerialized]
- [SecurityCritical]
protected unsafe ushort* mapUnicodeToBytes = null; // byte 65536
[NonSerialized]
- [SecurityCritical]
protected unsafe int* mapCodePageCached = null; // to remember which CP is cached
[NonSerialized]
@@ -45,23 +43,20 @@ namespace System.Text
[NonSerialized]
protected char charUnknown = (char)0;
- [System.Security.SecurityCritical] // auto-generated
public DBCSCodePageEncoding(int codePage) : this(codePage, codePage)
{
}
- [System.Security.SecurityCritical] // auto-generated
internal DBCSCodePageEncoding(int codePage, int dataCodePage) : base(codePage, dataCodePage)
{
}
// Constructor called by serialization.
// Note: We use the base GetObjectData however
- [System.Security.SecurityCritical] // auto-generated
internal DBCSCodePageEncoding(SerializationInfo info, StreamingContext context) : base(0)
{
// Actually this can't ever get called, CodePageEncoding is our proxy
- Contract.Assert(false, "Didn't expect to make it to DBCSCodePageEncoding serialization constructor");
+ Debug.Assert(false, "Didn't expect to make it to DBCSCodePageEncoding serialization constructor");
throw new ArgumentNullException("this");
}
@@ -93,11 +88,10 @@ namespace System.Text
// corrospond to those unicode code points.
// We have a managed code page entry, so load our tables
//
- [System.Security.SecurityCritical] // auto-generated
protected override unsafe void LoadManagedCodePage()
{
// Should be loading OUR code page
- Contract.Assert(pCodePage->CodePage == this.dataTableCodePage,
+ Debug.Assert(pCodePage->CodePage == this.dataTableCodePage,
"[DBCSCodePageEncoding.LoadManagedCodePage]Expected to load data table code page");
// Make sure we're really a 1 byte code page
@@ -120,7 +114,7 @@ namespace System.Text
byteCountUnknown++;
// We use fallback encoder, which uses ?, which so far all of our tables do as well
- Contract.Assert(bytesUnknown == 0x3f,
+ Debug.Assert(bytesUnknown == 0x3f,
"[DBCSCodePageEncoding.LoadManagedCodePage]Expected 0x3f (?) as unknown byte character");
// Get our mapped section (bytes to allocate = 2 bytes per 65536 Unicode chars + 2 bytes per 65536 DBCS chars)
@@ -134,7 +128,7 @@ namespace System.Text
// If its cached (& filled in) we don't have to do anything else
if (*mapCodePageCached != 0)
{
- Contract.Assert(((*mapCodePageCached == this.dataTableCodePage && this.bFlagDataTable) ||
+ Debug.Assert(((*mapCodePageCached == this.dataTableCodePage && this.bFlagDataTable) ||
(*mapCodePageCached == this.CodePage && !this.bFlagDataTable)),
"[DBCSCodePageEncoding.LoadManagedCodePage]Expected mapped section cached page flag to be set to data table or regular code page.");
@@ -188,7 +182,7 @@ namespace System.Text
else if (input == LEAD_BYTE_CHAR) // 0xfffe
{
// Lead byte mark
- Contract.Assert(bytePosition < 0x100, "[DBCSCodePageEncoding.LoadManagedCodePage]expected lead byte to be < 0x100");
+ Debug.Assert(bytePosition < 0x100, "[DBCSCodePageEncoding.LoadManagedCodePage]expected lead byte to be < 0x100");
useBytes = bytePosition;
// input stays 0xFFFE
}
@@ -235,7 +229,6 @@ namespace System.Text
}
// Any special processing for this code page
- [System.Security.SecurityCritical] // auto-generated
protected virtual unsafe void CleanUpEndBytes(char* chars)
{
}
@@ -256,7 +249,6 @@ namespace System.Text
}
// Read in our best fit table
- [System.Security.SecurityCritical] // auto-generated
protected unsafe override void ReadBestFitTable()
{
// Lock so we don't confuse ourselves.
@@ -407,7 +399,7 @@ namespace System.Text
// If they're out of order we need to sort them.
if (bOutOfOrder)
{
- Contract.Assert((arrayTemp.Length / 2) < 20,
+ Debug.Assert((arrayTemp.Length / 2) < 20,
"[DBCSCodePageEncoding.ReadBestFitTable]Expected small best fit table < 20 for code page " + CodePage + ", not " + arrayTemp.Length / 2);
for (int i = 0; i < arrayTemp.Length - 2; i+=2)
@@ -515,7 +507,7 @@ namespace System.Text
// We can't do this assert for CP 51932 & 50220 because they aren't
// calling CleanUpBytes() for best fit. All the string stuff here
// also makes this assert slow.
- // Contract.Assert(arrayTemp[iBestFitCount-1] != (char)0xFFFD, String.Format(
+ // Debug.Assert(arrayTemp[iBestFitCount-1] != (char)0xFFFD, String.Format(
// "[DBCSCodePageEncoding.ReadBestFitTable] No valid Unicode value {0:X4} for round trip bytes {1:X4}, encoding {2}",
// (int)mapBytesToUnicode[input], (int)input, CodePage));
}
@@ -534,15 +526,14 @@ namespace System.Text
// GetByteCount
// Note: We start by assuming that the output will be the same as count. Having
// an encoder or fallback may change that assumption
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetByteCount(char* chars, int count, EncoderNLS encoder)
{
// Just need to ASSERT, this is called by something else internal that checked parameters already
- Contract.Assert(count >= 0, "[DBCSCodePageEncoding.GetByteCount]count is negative");
- Contract.Assert(chars != null, "[DBCSCodePageEncoding.GetByteCount]chars is null");
+ Debug.Assert(count >= 0, "[DBCSCodePageEncoding.GetByteCount]count is negative");
+ Debug.Assert(chars != null, "[DBCSCodePageEncoding.GetByteCount]chars is null");
// Assert because we shouldn't be able to have a null encoder.
- Contract.Assert(encoderFallback != null, "[DBCSCodePageEncoding.GetByteCount]Attempting to use null fallback");
+ Debug.Assert(encoderFallback != null, "[DBCSCodePageEncoding.GetByteCount]Attempting to use null fallback");
CheckMemorySection();
@@ -568,8 +559,8 @@ namespace System.Text
// We may have a left over character from last time, try and process it.
if (charLeftOver > 0)
{
- Contract.Assert(Char.IsHighSurrogate(charLeftOver), "[DBCSCodePageEncoding.GetByteCount]leftover character should be high surrogate");
- Contract.Assert(encoder != null,
+ Debug.Assert(Char.IsHighSurrogate(charLeftOver), "[DBCSCodePageEncoding.GetByteCount]leftover character should be high surrogate");
+ Debug.Assert(encoder != null,
"[DBCSCodePageEncoding.GetByteCount]Expect to have encoder if we have a charLeftOver");
// Since left over char was a surrogate, it'll have to be fallen back.
@@ -625,18 +616,17 @@ namespace System.Text
return (int)byteCount;
}
- [System.Security.SecurityCritical] // auto-generated
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
- Contract.Assert(bytes != null, "[DBCSCodePageEncoding.GetBytes]bytes is null");
- Contract.Assert(byteCount >= 0, "[DBCSCodePageEncoding.GetBytes]byteCount is negative");
- Contract.Assert(chars != null, "[DBCSCodePageEncoding.GetBytes]chars is null");
- Contract.Assert(charCount >= 0, "[DBCSCodePageEncoding.GetBytes]charCount is negative");
+ Debug.Assert(bytes != null, "[DBCSCodePageEncoding.GetBytes]bytes is null");
+ Debug.Assert(byteCount >= 0, "[DBCSCodePageEncoding.GetBytes]byteCount is negative");
+ Debug.Assert(chars != null, "[DBCSCodePageEncoding.GetBytes]chars is null");
+ Debug.Assert(charCount >= 0, "[DBCSCodePageEncoding.GetBytes]charCount is negative");
// Assert because we shouldn't be able to have a null encoder.
- Contract.Assert(encoderFallback != null, "[DBCSCodePageEncoding.GetBytes]Attempting to use null encoder fallback");
+ Debug.Assert(encoderFallback != null, "[DBCSCodePageEncoding.GetBytes]Attempting to use null encoder fallback");
CheckMemorySection();
@@ -654,7 +644,7 @@ namespace System.Text
if (encoder != null)
{
charLeftOver = encoder.charLeftOver;
- Contract.Assert(charLeftOver == 0 || Char.IsHighSurrogate(charLeftOver),
+ Debug.Assert(charLeftOver == 0 || Char.IsHighSurrogate(charLeftOver),
"[DBCSCodePageEncoding.GetBytes]leftover character should be high surrogate");
// Go ahead and get the fallback buffer (need leftover fallback if converting)
@@ -669,7 +659,7 @@ namespace System.Text
// We may have a left over character from last time, try and process it.
if (charLeftOver > 0)
{
- Contract.Assert(encoder != null,
+ Debug.Assert(encoder != null,
"[DBCSCodePageEncoding.GetBytes]Expect to have encoder if we have a charLeftOver");
// Since left over char was a surrogate, it'll have to be fallen back.
@@ -702,7 +692,7 @@ namespace System.Text
if (fallbackBuffer == null)
{
// Initialize the buffer
- Contract.Assert(encoder == null,
+ Debug.Assert(encoder == null,
"[DBCSCodePageEncoding.GetBytes]Expected delayed create fallback only if no encoder.");
fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
fallbackBuffer.InternalInitialize(charEnd - charCount, charEnd, encoder, true);
@@ -724,7 +714,7 @@ namespace System.Text
// didn't use this char, we'll throw or use buffer
if (fallbackBuffer == null || fallbackBuffer.bFallingBack == false)
{
- Contract.Assert(chars > charStart,
+ Debug.Assert(chars > charStart,
"[DBCSCodePageEncoding.GetBytes]Expected chars to have advanced (double byte case)");
chars--; // don't use last char
}
@@ -743,7 +733,7 @@ namespace System.Text
// didn't use this char, we'll throw or use buffer
if (fallbackBuffer == null || fallbackBuffer.bFallingBack == false)
{
- Contract.Assert(chars > charStart,
+ Debug.Assert(chars > charStart,
"[DBCSCodePageEncoding.GetBytes]Expected chars to have advanced (single byte case)");
chars--; // don't use last char
}
@@ -771,7 +761,7 @@ namespace System.Text
// If we're not converting we must not have a fallback buffer
// (We don't really have a way to clear none-encoder using fallbacks however)
-// Contract.Assert((encoder == null || encoder.m_throwOnOverflow) &&
+// Debug.Assert((encoder == null || encoder.m_throwOnOverflow) &&
// (fallbackBuffer == null || fallbackBuffer.Remaining == 0),
// "[DBCSEncoding.GetBytes]Expected empty fallback buffer at end if not converting");
@@ -779,12 +769,11 @@ namespace System.Text
}
// This is internal and called by something else,
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS baseDecoder)
{
// Just assert, we're called internally so these should be safe, checked already
- Contract.Assert(bytes != null, "[DBCSCodePageEncoding.GetCharCount]bytes is null");
- Contract.Assert(count >= 0, "[DBCSCodePageEncoding.GetCharCount]byteCount is negative");
+ Debug.Assert(bytes != null, "[DBCSCodePageEncoding.GetCharCount]bytes is null");
+ Debug.Assert(count >= 0, "[DBCSCodePageEncoding.GetCharCount]byteCount is negative");
CheckMemorySection();
@@ -800,7 +789,7 @@ namespace System.Text
// Shouldn't have anything in fallback buffer for GetCharCount
// (don't have to check m_throwOnOverflow for count)
- Contract.Assert(decoder == null ||
+ Debug.Assert(decoder == null ||
!decoder.InternalHasFallbackBuffer || decoder.FallbackBuffer.Remaining == 0,
"[DBCSCodePageEncoding.GetCharCount]Expected empty fallback buffer at start");
@@ -818,7 +807,7 @@ namespace System.Text
}
- Contract.Assert(fallbackBuffer == null,
+ Debug.Assert(fallbackBuffer == null,
"[DBCSCodePageEncoding.GetCharCount]Expected empty fallback buffer");
fallbackBuffer = decoder.FallbackBuffer;
fallbackBuffer.InternalInitialize(bytes, null);
@@ -842,7 +831,7 @@ namespace System.Text
charCount--;
// We'll need a fallback
- Contract.Assert(fallbackBuffer == null,
+ Debug.Assert(fallbackBuffer == null,
"[DBCSCodePageEncoding.GetCharCount]Expected empty fallback buffer for unknown pair");
fallbackBuffer = decoder.FallbackBuffer;
fallbackBuffer.InternalInitialize(byteEnd - count, null);
@@ -917,7 +906,7 @@ namespace System.Text
}
// Shouldn't have anything in fallback buffer for GetChars
- Contract.Assert(decoder == null || !decoder.m_throwOnOverflow ||
+ Debug.Assert(decoder == null || !decoder.m_throwOnOverflow ||
!decoder.InternalHasFallbackBuffer || decoder.FallbackBuffer.Remaining == 0,
"[DBCSCodePageEncoding.GetCharCount]Expected empty fallback buffer at end");
@@ -925,15 +914,14 @@ namespace System.Text
return charCount;
}
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetChars(byte* bytes, int byteCount,
char* chars, int charCount, DecoderNLS baseDecoder)
{
// Just need to ASSERT, this is called by something else internal that checked parameters already
- Contract.Assert(bytes != null, "[DBCSCodePageEncoding.GetChars]bytes is null");
- Contract.Assert(byteCount >= 0, "[DBCSCodePageEncoding.GetChars]byteCount is negative");
- Contract.Assert(chars != null, "[DBCSCodePageEncoding.GetChars]chars is null");
- Contract.Assert(charCount >= 0, "[DBCSCodePageEncoding.GetChars]charCount is negative");
+ Debug.Assert(bytes != null, "[DBCSCodePageEncoding.GetChars]bytes is null");
+ Debug.Assert(byteCount >= 0, "[DBCSCodePageEncoding.GetChars]byteCount is negative");
+ Debug.Assert(chars != null, "[DBCSCodePageEncoding.GetChars]chars is null");
+ Debug.Assert(charCount >= 0, "[DBCSCodePageEncoding.GetChars]charCount is negative");
CheckMemorySection();
@@ -951,7 +939,7 @@ namespace System.Text
DecoderFallbackBuffer fallbackBuffer = null;
// Shouldn't have anything in fallback buffer for GetChars
- Contract.Assert(decoder == null || !decoder.m_throwOnOverflow ||
+ Debug.Assert(decoder == null || !decoder.m_throwOnOverflow ||
!decoder.InternalHasFallbackBuffer || decoder.FallbackBuffer.Remaining == 0,
"[DBCSCodePageEncoding.GetChars]Expected empty fallback buffer at start");
@@ -970,7 +958,7 @@ namespace System.Text
// Well, we're flushing, so use '?' or fallback
// fallback leftover byte
- Contract.Assert(fallbackBuffer == null,
+ Debug.Assert(fallbackBuffer == null,
"[DBCSCodePageEncoding.GetChars]Expected empty fallback");
fallbackBuffer = decoder.FallbackBuffer;
fallbackBuffer.InternalInitialize(bytes, charEnd);
@@ -995,7 +983,7 @@ namespace System.Text
char cDecoder = mapBytesToUnicode[iBytes];
if (cDecoder == UNKNOWN_CHAR_FLAG && iBytes != 0)
{
- Contract.Assert(fallbackBuffer == null,
+ Debug.Assert(fallbackBuffer == null,
"[DBCSCodePageEncoding.GetChars]Expected empty fallback for two bytes");
fallbackBuffer = decoder.FallbackBuffer;
fallbackBuffer.InternalInitialize(byteEnd - byteCount, charEnd);
@@ -1073,7 +1061,7 @@ namespace System.Text
if (!fallbackBuffer.InternalFallback(byteBuffer, bytes, ref chars))
{
// May or may not throw, but we didn't get these byte(s)
- Contract.Assert(bytes >= byteStart + byteBuffer.Length,
+ Debug.Assert(bytes >= byteStart + byteBuffer.Length,
"[DBCSCodePageEncoding.GetChars]Expected bytes to have advanced for fallback");
bytes-=byteBuffer.Length; // didn't use these byte(s)
fallbackBuffer.InternalReset(); // Didn't fall this back
@@ -1087,12 +1075,12 @@ namespace System.Text
if (chars >= charEnd)
{
// May or may not throw, but we didn't get these byte(s)
- Contract.Assert(bytes > byteStart,
+ Debug.Assert(bytes > byteStart,
"[DBCSCodePageEncoding.GetChars]Expected bytes to have advanced for lead byte");
bytes--; // unused byte
if (iBytes >= 0x100)
{
- Contract.Assert(bytes > byteStart,
+ Debug.Assert(bytes > byteStart,
"[DBCSCodePageEncoding.GetChars]Expected bytes to have advanced for trail byte");
bytes--; // 2nd unused byte
}
@@ -1118,7 +1106,7 @@ namespace System.Text
}
// Shouldn't have anything in fallback buffer for GetChars
- Contract.Assert(decoder == null || !decoder.m_throwOnOverflow ||
+ Debug.Assert(decoder == null || !decoder.m_throwOnOverflow ||
!decoder.InternalHasFallbackBuffer || decoder.FallbackBuffer.Remaining == 0,
"[DBCSCodePageEncoding.GetChars]Expected empty fallback buffer at end");
@@ -1129,7 +1117,7 @@ namespace System.Text
public override int GetMaxByteCount(int charCount)
{
if (charCount < 0)
- throw new ArgumentOutOfRangeException("charCount",
+ throw new ArgumentOutOfRangeException(nameof(charCount),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -1143,7 +1131,7 @@ namespace System.Text
byteCount *= 2;
if (byteCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException("charCount", Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
+ throw new ArgumentOutOfRangeException(nameof(charCount), Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
return (int)byteCount;
}
@@ -1151,7 +1139,7 @@ namespace System.Text
public override int GetMaxCharCount(int byteCount)
{
if (byteCount < 0)
- throw new ArgumentOutOfRangeException("byteCount",
+ throw new ArgumentOutOfRangeException(nameof(byteCount),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -1163,7 +1151,7 @@ namespace System.Text
charCount *= DecoderFallback.MaxCharCount;
if (charCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException("byteCount", Environment.GetResourceString("ArgumentOutOfRange_GetCharCountOverflow"));
+ throw new ArgumentOutOfRangeException(nameof(byteCount), Environment.GetResourceString("ArgumentOutOfRange_GetCharCountOverflow"));
return (int)charCount;
}
diff --git a/src/mscorlib/src/System/Text/Decoder.cs b/src/mscorlib/src/System/Text/Decoder.cs
index f794dc4dce..0ebbacddcf 100644
--- a/src/mscorlib/src/System/Text/Decoder.cs
+++ b/src/mscorlib/src/System/Text/Decoder.cs
@@ -7,6 +7,7 @@ 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,
@@ -49,13 +50,13 @@ namespace System.Text
set
{
if (value == null)
- throw new ArgumentNullException("value");
+ 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"), "value");
+ Environment.GetResourceString("Argument_FallbackBufferNotEmpty"), nameof(value));
m_fallback = value;
m_fallbackBuffer = null;
@@ -124,18 +125,17 @@ namespace System.Text
// We expect this to be the workhorse for NLS Encodings, but for existing
// ones we need a working (if slow) default implimentation)
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public virtual unsafe int GetCharCount(byte* bytes, int count, bool flush)
{
// Validate input parameters
if (bytes == null)
- throw new ArgumentNullException("bytes",
+ throw new ArgumentNullException(nameof(bytes),
Environment.GetResourceString("ArgumentNull_Array"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count",
+ throw new ArgumentOutOfRangeException(nameof(count),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -189,7 +189,6 @@ namespace System.Text
// 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.
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public virtual unsafe int GetChars(byte* bytes, int byteCount,
@@ -197,11 +196,11 @@ namespace System.Text
{
// Validate input parameters
if (chars == null || bytes == null)
- throw new ArgumentNullException(chars == null ? "chars" : "bytes",
+ throw new ArgumentNullException(chars == null ? nameof(chars) : nameof(bytes),
Environment.GetResourceString("ArgumentNull_Array"));
if (byteCount < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((byteCount<0 ? "byteCount" : "charCount"),
+ throw new ArgumentOutOfRangeException((byteCount<0 ? nameof(byteCount) : nameof(charCount)),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -218,7 +217,7 @@ namespace System.Text
// Do the work
int result = GetChars(arrByte, 0, byteCount, arrChar, 0, flush);
- Contract.Assert(result <= charCount, "Returned more chars than we have space for");
+ 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
@@ -256,23 +255,23 @@ namespace System.Text
{
// Validate parameters
if (bytes == null || chars == null)
- throw new ArgumentNullException((bytes == null ? "bytes" : "chars"),
+ throw new ArgumentNullException((bytes == null ? nameof(bytes) : nameof(chars)),
Environment.GetResourceString("ArgumentNull_Array"));
if (byteIndex < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((byteIndex<0 ? "byteIndex" : "byteCount"),
+ throw new ArgumentOutOfRangeException((byteIndex<0 ? nameof(byteIndex) : nameof(byteCount)),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (charIndex < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((charIndex<0 ? "charIndex" : "charCount"),
+ throw new ArgumentOutOfRangeException((charIndex<0 ? nameof(charIndex) : nameof(charCount)),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (bytes.Length - byteIndex < byteCount)
- throw new ArgumentOutOfRangeException("bytes",
+ throw new ArgumentOutOfRangeException(nameof(bytes),
Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
if (chars.Length - charIndex < charCount)
- throw new ArgumentOutOfRangeException("chars",
+ throw new ArgumentOutOfRangeException(nameof(chars),
Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
Contract.EndContractBlock();
@@ -306,7 +305,6 @@ namespace System.Text
// 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)
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public virtual unsafe void Convert(byte* bytes, int byteCount,
@@ -315,11 +313,11 @@ namespace System.Text
{
// Validate input parameters
if (chars == null || bytes == null)
- throw new ArgumentNullException(chars == null ? "chars" : "bytes",
+ throw new ArgumentNullException(chars == null ? nameof(chars) : nameof(bytes),
Environment.GetResourceString("ArgumentNull_Array"));
if (byteCount < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((byteCount<0 ? "byteCount" : "charCount"),
+ throw new ArgumentOutOfRangeException((byteCount<0 ? nameof(byteCount) : nameof(charCount)),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
diff --git a/src/mscorlib/src/System/Text/DecoderBestFitFallback.cs b/src/mscorlib/src/System/Text/DecoderBestFitFallback.cs
index 5c1dcd9682..6389b4b141 100644
--- a/src/mscorlib/src/System/Text/DecoderBestFitFallback.cs
+++ b/src/mscorlib/src/System/Text/DecoderBestFitFallback.cs
@@ -10,6 +10,7 @@ namespace System.Text
using System;
using System.Text;
using System.Threading;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
[Serializable]
@@ -101,7 +102,7 @@ namespace System.Text
public override bool Fallback(byte[] bytesUnknown, int index)
{
// We expect no previous fallback in our buffer
- Contract.Assert(iCount < 1, "[DecoderReplacementFallbackBuffer.Fallback] Calling fallback without a previously empty buffer");
+ Debug.Assert(iCount < 1, "[DecoderReplacementFallbackBuffer.Fallback] Calling fallback without a previously empty buffer");
cBestFit = TryBestFit(bytesUnknown);
if (cBestFit == '\0')
@@ -155,7 +156,6 @@ namespace System.Text
}
// Clear the buffer
- [System.Security.SecuritySafeCritical] // overrides public transparent member
public override unsafe void Reset()
{
iCount = -1;
@@ -163,7 +163,6 @@ namespace System.Text
}
// This version just counts the fallback and doesn't actually copy anything.
- [System.Security.SecurityCritical] // auto-generated
internal unsafe override int InternalFallback(byte[] bytes, byte* pBytes)
// Right now this has both bytes and bytes[], since we might have extra bytes, hence the
// array, and we might need the index, hence the byte*
@@ -212,7 +211,7 @@ namespace System.Text
if (cTest == cCheck)
{
// We found it
- Contract.Assert(index + 1 < oFallback.arrayBestFit.Length,
+ Debug.Assert(index + 1 < oFallback.arrayBestFit.Length,
"[InternalDecoderBestFitFallbackBuffer.TryBestFit]Expected replacement character at end of array");
return oFallback.arrayBestFit[index + 1];
}
@@ -233,7 +232,7 @@ namespace System.Text
if (oFallback.arrayBestFit[index] == cCheck)
{
// We found it
- Contract.Assert(index + 1 < oFallback.arrayBestFit.Length,
+ Debug.Assert(index + 1 < oFallback.arrayBestFit.Length,
"[InternalDecoderBestFitFallbackBuffer.TryBestFit]Expected replacement character at end of array");
return oFallback.arrayBestFit[index + 1];
}
diff --git a/src/mscorlib/src/System/Text/DecoderFallback.cs b/src/mscorlib/src/System/Text/DecoderFallback.cs
index 1698fd37ab..42483a724d 100644
--- a/src/mscorlib/src/System/Text/DecoderFallback.cs
+++ b/src/mscorlib/src/System/Text/DecoderFallback.cs
@@ -7,6 +7,7 @@ using System;
using System.Security;
using System.Threading;
using System.Globalization;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
namespace System.Text
@@ -115,13 +116,10 @@ namespace System.Text
// 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
- [SecurityCritical]
internal unsafe byte* byteStart;
- [SecurityCritical]
internal unsafe char* charEnd;
// Internal Reset
- [System.Security.SecurityCritical] // auto-generated
internal unsafe void InternalReset()
{
byteStart = null;
@@ -130,7 +128,6 @@ namespace System.Text
// Set the above values
// This can't be part of the constructor because DecoderFallbacks would have to know how to impliment these.
- [System.Security.SecurityCritical] // auto-generated
internal unsafe void InternalInitialize(byte* byteStart, char* charEnd)
{
this.byteStart = byteStart;
@@ -145,7 +142,6 @@ namespace System.Text
// Right now this has both bytes and bytes[], since we might have extra bytes, hence the
// array, and we might need the index, hence the byte*
// Don't touch ref chars unless we succeed
- [System.Security.SecurityCritical] // auto-generated
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.
@@ -153,7 +149,7 @@ namespace System.Text
// for (int i = 0; i < count; i++)
// bytesUnknown[i] = *(bytes++);
- Contract.Assert(byteStart != null, "[DecoderFallback.InternalFallback]Used InternalFallback without calling InternalInitialize");
+ Debug.Assert(byteStart != null, "[DecoderFallback.InternalFallback]Used InternalFallback without calling InternalInitialize");
// See if there's a fallback character and we have an output buffer then copy our string.
if (this.Fallback(bytes, (int)(pBytes - byteStart - bytes.Length)))
@@ -204,7 +200,6 @@ namespace System.Text
}
// This version just counts the fallback and doesn't actually copy anything.
- [System.Security.SecurityCritical] // auto-generated
internal unsafe virtual int InternalFallback(byte[] bytes, byte* pBytes)
// Right now this has both bytes and bytes[], since we might have extra bytes, hence the
// array, and we might need the index, hence the byte*
@@ -214,7 +209,7 @@ namespace System.Text
// for (int i = 0; i < count; i++)
// bytesUnknown[i] = *(bytes++);
- Contract.Assert(byteStart != null, "[DecoderFallback.InternalFallback]Used InternalFallback without calling InternalInitialize");
+ Debug.Assert(byteStart != null, "[DecoderFallback.InternalFallback]Used InternalFallback without calling InternalInitialize");
// See if there's a fallback character and we have an output buffer then copy our string.
if (this.Fallback(bytes, (int)(pBytes - byteStart - bytes.Length)))
@@ -277,7 +272,7 @@ namespace System.Text
// Throw it, using our complete bytes
throw new ArgumentException(
Environment.GetResourceString("Argument_RecursiveFallbackBytes",
- strBytes.ToString()), "bytesUnknown");
+ strBytes.ToString()), nameof(bytesUnknown));
}
}
diff --git a/src/mscorlib/src/System/Text/DecoderNLS.cs b/src/mscorlib/src/System/Text/DecoderNLS.cs
index c2e82dd250..e44c43adef 100644
--- a/src/mscorlib/src/System/Text/DecoderNLS.cs
+++ b/src/mscorlib/src/System/Text/DecoderNLS.cs
@@ -42,7 +42,6 @@ namespace System.Text
}
// ISerializable implementation. called during serialization.
- [System.Security.SecurityCritical] // auto-generated_required
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
SerializeDecoder(info);
@@ -77,20 +76,19 @@ namespace System.Text
return GetCharCount(bytes, index, count, false);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override unsafe int GetCharCount(byte[] bytes, int index, int count, bool flush)
{
// Validate Parameters
if (bytes == null)
- throw new ArgumentNullException("bytes",
+ throw new ArgumentNullException(nameof(bytes),
Environment.GetResourceString("ArgumentNull_Array"));
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"),
+ throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (bytes.Length - index < count)
- throw new ArgumentOutOfRangeException("bytes",
+ throw new ArgumentOutOfRangeException(nameof(bytes),
Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
Contract.EndContractBlock();
@@ -104,16 +102,15 @@ namespace System.Text
return GetCharCount(pBytes + index, count, flush);
}
- [System.Security.SecurityCritical] // auto-generated
public unsafe override int GetCharCount(byte* bytes, int count, bool flush)
{
// Validate parameters
if (bytes == null)
- throw new ArgumentNullException("bytes",
+ throw new ArgumentNullException(nameof(bytes),
Environment.GetResourceString("ArgumentNull_Array"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count",
+ throw new ArgumentOutOfRangeException(nameof(count),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -131,25 +128,24 @@ namespace System.Text
return GetChars(bytes, byteIndex, byteCount, chars, charIndex, false);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override unsafe int GetChars(byte[] bytes, int byteIndex, int byteCount,
char[] chars, int charIndex, bool flush)
{
// Validate Parameters
if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? "bytes" : "chars",
+ throw new ArgumentNullException(bytes == null ? nameof(bytes) : nameof(chars),
Environment.GetResourceString("ArgumentNull_Array"));
if (byteIndex < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((byteIndex<0 ? "byteIndex" : "byteCount"),
+ throw new ArgumentOutOfRangeException((byteIndex<0 ? nameof(byteIndex) : nameof(byteCount)),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if ( bytes.Length - byteIndex < byteCount)
- throw new ArgumentOutOfRangeException("bytes",
+ throw new ArgumentOutOfRangeException(nameof(bytes),
Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
if (charIndex < 0 || charIndex > chars.Length)
- throw new ArgumentOutOfRangeException("charIndex",
+ throw new ArgumentOutOfRangeException(nameof(charIndex),
Environment.GetResourceString("ArgumentOutOfRange_Index"));
Contract.EndContractBlock();
@@ -170,17 +166,16 @@ namespace System.Text
pChars + charIndex, charCount, flush);
}
- [System.Security.SecurityCritical] // auto-generated
public unsafe override int GetChars(byte* bytes, int byteCount,
char* chars, int charCount, bool flush)
{
// Validate parameters
if (chars == null || bytes == null)
- throw new ArgumentNullException((chars == null ? "chars" : "bytes"),
+ throw new ArgumentNullException((chars == null ? nameof(chars) : nameof(bytes)),
Environment.GetResourceString("ArgumentNull_Array"));
if (byteCount < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((byteCount<0 ? "byteCount" : "charCount"),
+ throw new ArgumentOutOfRangeException((byteCount<0 ? nameof(byteCount) : nameof(charCount)),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -194,30 +189,29 @@ namespace System.Text
// This method is used when the output buffer might not be big enough.
// Just call the pointer version. (This gets chars)
- [System.Security.SecuritySafeCritical] // auto-generated
public override unsafe 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 ? "bytes" : "chars"),
+ throw new ArgumentNullException((bytes == null ? nameof(bytes) : nameof(chars)),
Environment.GetResourceString("ArgumentNull_Array"));
if (byteIndex < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((byteIndex<0 ? "byteIndex" : "byteCount"),
+ throw new ArgumentOutOfRangeException((byteIndex<0 ? nameof(byteIndex) : nameof(byteCount)),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (charIndex < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((charIndex<0 ? "charIndex" : "charCount"),
+ throw new ArgumentOutOfRangeException((charIndex<0 ? nameof(charIndex) : nameof(charCount)),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (bytes.Length - byteIndex < byteCount)
- throw new ArgumentOutOfRangeException("bytes",
+ throw new ArgumentOutOfRangeException(nameof(bytes),
Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
if (chars.Length - charIndex < charCount)
- throw new ArgumentOutOfRangeException("chars",
+ throw new ArgumentOutOfRangeException(nameof(chars),
Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
Contract.EndContractBlock();
@@ -241,18 +235,17 @@ namespace System.Text
// This is the version that used pointers. We call the base encoding worker function
// after setting our appropriate internal variables. This is getting chars
- [System.Security.SecurityCritical] // auto-generated
public unsafe override 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 ? "chars" : "bytes",
+ throw new ArgumentNullException(chars == null ? nameof(chars) : nameof(bytes),
Environment.GetResourceString("ArgumentNull_Array"));
if (byteCount < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((byteCount<0 ? "byteCount" : "charCount"),
+ throw new ArgumentOutOfRangeException((byteCount<0 ? nameof(byteCount) : nameof(charCount)),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
diff --git a/src/mscorlib/src/System/Text/DecoderReplacementFallback.cs b/src/mscorlib/src/System/Text/DecoderReplacementFallback.cs
index c732d15816..77c856046d 100644
--- a/src/mscorlib/src/System/Text/DecoderReplacementFallback.cs
+++ b/src/mscorlib/src/System/Text/DecoderReplacementFallback.cs
@@ -5,6 +5,7 @@
namespace System.Text
{
using System;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
[Serializable]
@@ -21,7 +22,7 @@ namespace System.Text
public DecoderReplacementFallback(String replacement)
{
if (replacement == null)
- throw new ArgumentNullException("replacement");
+ throw new ArgumentNullException(nameof(replacement));
Contract.EndContractBlock();
// Make sure it doesn't have bad surrogate pairs
@@ -58,7 +59,7 @@ namespace System.Text
break;
}
if (bFoundHigh)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex", "replacement"));
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex", nameof(replacement)));
strDefault = replacement;
}
@@ -156,7 +157,7 @@ namespace System.Text
}
// Now make sure its in the expected range
- Contract.Assert(fallbackIndex < strDefault.Length && fallbackIndex >= 0,
+ Debug.Assert(fallbackIndex < strDefault.Length && fallbackIndex >= 0,
"Index exceeds buffer range");
return strDefault[fallbackIndex];
@@ -187,7 +188,6 @@ namespace System.Text
}
// Clear the buffer
- [System.Security.SecuritySafeCritical] // auto-generated
public override unsafe void Reset()
{
fallbackCount = -1;
@@ -196,7 +196,6 @@ namespace System.Text
}
// This version just counts the fallback and doesn't actually copy anything.
- [System.Security.SecurityCritical] // auto-generated
internal unsafe override int InternalFallback(byte[] bytes, byte* pBytes)
// Right now this has both bytes and bytes[], since we might have extra bytes, hence the
// array, and we might need the index, hence the byte*
diff --git a/src/mscorlib/src/System/Text/EUCJPEncoding.cs b/src/mscorlib/src/System/Text/EUCJPEncoding.cs
index 7c90caec0b..44345b22b9 100644
--- a/src/mscorlib/src/System/Text/EUCJPEncoding.cs
+++ b/src/mscorlib/src/System/Text/EUCJPEncoding.cs
@@ -50,13 +50,11 @@ namespace System.Text
internal class EUCJPEncoding : DBCSCodePageEncoding
{
// This pretends to be CP 932 as far as memory tables are concerned.
- [System.Security.SecurityCritical] // auto-generated
public EUCJPEncoding() : base(51932, 932)
{
this.m_bUseMlangTypeForSerialization = true;
}
- [System.Security.SecurityCritical] // auto-generated
protected unsafe override String GetMemorySectionName()
{
int iUseCodePage = this.bFlagDataTable ? dataTableCodePage : CodePage;
@@ -165,7 +163,6 @@ namespace System.Text
return true;
}
- [System.Security.SecurityCritical] // auto-generated
protected override unsafe void CleanUpEndBytes(char* chars)
{
// Need to special case CP 51932
diff --git a/src/mscorlib/src/System/Text/Encoder.cs b/src/mscorlib/src/System/Text/Encoder.cs
index d223dd9d46..b9d4581276 100644
--- a/src/mscorlib/src/System/Text/Encoder.cs
+++ b/src/mscorlib/src/System/Text/Encoder.cs
@@ -7,6 +7,7 @@ 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,
@@ -49,13 +50,13 @@ namespace System.Text
set
{
if (value == null)
- throw new ArgumentNullException("value");
+ 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"), "value");
+ Environment.GetResourceString("Argument_FallbackBufferNotEmpty"), nameof(value));
m_fallback = value;
m_fallbackBuffer = null;
@@ -120,18 +121,17 @@ namespace System.Text
// 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.
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public virtual unsafe int GetByteCount(char* chars, int count, bool flush)
{
// Validate input parameters
if (chars == null)
- throw new ArgumentNullException("chars",
+ throw new ArgumentNullException(nameof(chars),
Environment.GetResourceString("ArgumentNull_Array"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count",
+ throw new ArgumentOutOfRangeException(nameof(count),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -182,7 +182,6 @@ namespace System.Text
// 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.
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public virtual unsafe int GetBytes(char* chars, int charCount,
@@ -190,11 +189,11 @@ namespace System.Text
{
// Validate input parameters
if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? "bytes" : "chars",
+ throw new ArgumentNullException(bytes == null ? nameof(bytes) : nameof(chars),
Environment.GetResourceString("ArgumentNull_Array"));
if (charCount < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((charCount<0 ? "charCount" : "byteCount"),
+ throw new ArgumentOutOfRangeException((charCount<0 ? nameof(charCount) : nameof(byteCount)),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -211,7 +210,7 @@ namespace System.Text
// Do the work
int result = GetBytes(arrChar, 0, charCount, arrByte, 0, flush);
- Contract.Assert(result <= byteCount, "Returned more bytes than we have space for");
+ 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
@@ -248,23 +247,23 @@ namespace System.Text
{
// Validate parameters
if (chars == null || bytes == null)
- throw new ArgumentNullException((chars == null ? "chars" : "bytes"),
+ throw new ArgumentNullException((chars == null ? nameof(chars) : nameof(bytes)),
Environment.GetResourceString("ArgumentNull_Array"));
if (charIndex < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((charIndex<0 ? "charIndex" : "charCount"),
+ throw new ArgumentOutOfRangeException((charIndex<0 ? nameof(charIndex) : nameof(charCount)),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (byteIndex < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((byteIndex<0 ? "byteIndex" : "byteCount"),
+ throw new ArgumentOutOfRangeException((byteIndex<0 ? nameof(byteIndex) : nameof(byteCount)),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (chars.Length - charIndex < charCount)
- throw new ArgumentOutOfRangeException("chars",
+ throw new ArgumentOutOfRangeException(nameof(chars),
Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
if (bytes.Length - byteIndex < byteCount)
- throw new ArgumentOutOfRangeException("bytes",
+ throw new ArgumentOutOfRangeException(nameof(bytes),
Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
Contract.EndContractBlock();
@@ -299,7 +298,6 @@ namespace System.Text
// 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)
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public virtual unsafe void Convert(char* chars, int charCount,
@@ -308,10 +306,10 @@ namespace System.Text
{
// Validate input parameters
if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? "bytes" : "chars",
+ throw new ArgumentNullException(bytes == null ? nameof(bytes) : nameof(chars),
Environment.GetResourceString("ArgumentNull_Array"));
if (charCount < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((charCount<0 ? "charCount" : "byteCount"),
+ throw new ArgumentOutOfRangeException((charCount<0 ? nameof(charCount) : nameof(byteCount)),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
diff --git a/src/mscorlib/src/System/Text/EncoderBestFitFallback.cs b/src/mscorlib/src/System/Text/EncoderBestFitFallback.cs
index 352e9695cf..c5f82a299b 100644
--- a/src/mscorlib/src/System/Text/EncoderBestFitFallback.cs
+++ b/src/mscorlib/src/System/Text/EncoderBestFitFallback.cs
@@ -11,6 +11,7 @@ namespace System.Text
using System.Globalization;
using System.Text;
using System.Threading;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
[Serializable]
@@ -103,7 +104,7 @@ namespace System.Text
// If we had a buffer already we're being recursive, throw, it's probably at the suspect
// character in our array.
// Shouldn't be able to get here for all of our code pages, table would have to be messed up.
- Contract.Assert(iCount < 1, "[InternalEncoderBestFitFallbackBuffer.Fallback(non surrogate)] Fallback char " + ((int)cBestFit).ToString("X4", CultureInfo.InvariantCulture) + " caused recursive fallback");
+ Debug.Assert(iCount < 1, "[InternalEncoderBestFitFallbackBuffer.Fallback(non surrogate)] Fallback char " + ((int)cBestFit).ToString("X4", CultureInfo.InvariantCulture) + " caused recursive fallback");
iCount = iSize = 1;
cBestFit = TryBestFit(charUnknown);
@@ -117,7 +118,7 @@ namespace System.Text
{
// Double check input surrogate pair
if (!Char.IsHighSurrogate(charUnknownHigh))
- throw new ArgumentOutOfRangeException("charUnknownHigh",
+ throw new ArgumentOutOfRangeException(nameof(charUnknownHigh),
Environment.GetResourceString("ArgumentOutOfRange_Range",
0xD800, 0xDBFF));
@@ -130,7 +131,7 @@ namespace System.Text
// If we had a buffer already we're being recursive, throw, it's probably at the suspect
// character in our array. 0 is processing last character, < 0 is not falling back
// Shouldn't be able to get here, table would have to be messed up.
- Contract.Assert(iCount < 1, "[InternalEncoderBestFitFallbackBuffer.Fallback(surrogate)] Fallback char " + ((int)cBestFit).ToString("X4", CultureInfo.InvariantCulture) + " caused recursive fallback");
+ Debug.Assert(iCount < 1, "[InternalEncoderBestFitFallbackBuffer.Fallback(surrogate)] Fallback char " + ((int)cBestFit).ToString("X4", CultureInfo.InvariantCulture) + " caused recursive fallback");
// Go ahead and get our fallback, surrogates don't have best fit
cBestFit = '?';
@@ -183,7 +184,6 @@ namespace System.Text
}
// Clear the buffer
- [System.Security.SecuritySafeCritical] // overrides public transparent member
public override unsafe void Reset()
{
iCount = -1;
@@ -212,7 +212,7 @@ namespace System.Text
if (cTest == cUnknown)
{
// We found it
- Contract.Assert(index + 1 < oFallback.arrayBestFit.Length,
+ Debug.Assert(index + 1 < oFallback.arrayBestFit.Length,
"[InternalEncoderBestFitFallbackBuffer.TryBestFit]Expected replacement character at end of array");
return oFallback.arrayBestFit[index + 1];
}
@@ -233,7 +233,7 @@ namespace System.Text
if (oFallback.arrayBestFit[index] == cUnknown)
{
// We found it
- Contract.Assert(index + 1 < oFallback.arrayBestFit.Length,
+ Debug.Assert(index + 1 < oFallback.arrayBestFit.Length,
"[InternalEncoderBestFitFallbackBuffer.TryBestFit]Expected replacement character at end of array");
return oFallback.arrayBestFit[index + 1];
}
diff --git a/src/mscorlib/src/System/Text/EncoderExceptionFallback.cs b/src/mscorlib/src/System/Text/EncoderExceptionFallback.cs
index 5ab51cb6dd..051f50ac7c 100644
--- a/src/mscorlib/src/System/Text/EncoderExceptionFallback.cs
+++ b/src/mscorlib/src/System/Text/EncoderExceptionFallback.cs
@@ -62,7 +62,7 @@ namespace System.Text
{
if (!Char.IsHighSurrogate(charUnknownHigh))
{
- throw new ArgumentOutOfRangeException("charUnknownHigh",
+ throw new ArgumentOutOfRangeException(nameof(charUnknownHigh),
Environment.GetResourceString("ArgumentOutOfRange_Range",
0xD800, 0xDBFF));
}
@@ -145,13 +145,13 @@ namespace System.Text
{
if (!Char.IsHighSurrogate(charUnknownHigh))
{
- throw new ArgumentOutOfRangeException("charUnknownHigh",
+ throw new ArgumentOutOfRangeException(nameof(charUnknownHigh),
Environment.GetResourceString("ArgumentOutOfRange_Range",
0xD800, 0xDBFF));
}
if (!Char.IsLowSurrogate(charUnknownLow))
{
- throw new ArgumentOutOfRangeException("CharUnknownLow",
+ throw new ArgumentOutOfRangeException(nameof(CharUnknownLow),
Environment.GetResourceString("ArgumentOutOfRange_Range",
0xDC00, 0xDFFF));
}
diff --git a/src/mscorlib/src/System/Text/EncoderFallback.cs b/src/mscorlib/src/System/Text/EncoderFallback.cs
index 4b170414d5..db2bf93bdd 100644
--- a/src/mscorlib/src/System/Text/EncoderFallback.cs
+++ b/src/mscorlib/src/System/Text/EncoderFallback.cs
@@ -5,6 +5,7 @@
using System;
using System.Security;
using System.Threading;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
namespace System.Text
@@ -111,9 +112,7 @@ namespace System.Text
// 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
- [SecurityCritical]
internal unsafe char* charStart;
- [SecurityCritical]
internal unsafe char* charEnd;
internal EncoderNLS encoder;
internal bool setEncoder;
@@ -124,7 +123,6 @@ namespace System.Text
// Internal Reset
// For example, what if someone fails a conversion and wants to reset one of our fallback buffers?
- [System.Security.SecurityCritical] // auto-generated
internal unsafe void InternalReset()
{
charStart = null;
@@ -135,7 +133,6 @@ namespace System.Text
// Set the above values
// This can't be part of the constructor because EncoderFallbacks would have to know how to impliment these.
- [System.Security.SecurityCritical] // auto-generated
internal unsafe void InternalInitialize(char* charStart, char* charEnd, EncoderNLS encoder, bool setEncoder)
{
this.charStart = charStart;
@@ -163,11 +160,10 @@ namespace System.Text
// Note that this could also change the contents of this.encoder, which is the same
// object that the caller is using, so the caller could mess up the encoder for us
// if they aren't careful.
- [System.Security.SecurityCritical] // auto-generated
internal unsafe virtual bool InternalFallback(char ch, ref char* chars)
{
// Shouldn't have null charStart
- Contract.Assert(charStart != null,
+ Debug.Assert(charStart != null,
"[EncoderFallback.InternalFallbackBuffer]Fallback buffer is not initialized");
// Get our index, remember chars was preincremented to point at next char, so have to -1
diff --git a/src/mscorlib/src/System/Text/EncoderNLS.cs b/src/mscorlib/src/System/Text/EncoderNLS.cs
index d5c52f48d8..2add017d68 100644
--- a/src/mscorlib/src/System/Text/EncoderNLS.cs
+++ b/src/mscorlib/src/System/Text/EncoderNLS.cs
@@ -45,7 +45,6 @@ namespace System.Text
}
// ISerializable implementation. called during serialization.
- [System.Security.SecurityCritical] // auto-generated_required
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
SerializeEncoder(info);
@@ -77,20 +76,19 @@ namespace System.Text
m_fallbackBuffer.Reset();
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override unsafe int GetByteCount(char[] chars, int index, int count, bool flush)
{
// Validate input parameters
if (chars == null)
- throw new ArgumentNullException( "chars",
+ throw new ArgumentNullException(nameof(chars),
Environment.GetResourceString("ArgumentNull_Array"));
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index<0 ? "index" : "count"),
+ throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (chars.Length - index < count)
- throw new ArgumentOutOfRangeException("chars",
+ throw new ArgumentOutOfRangeException(nameof(chars),
Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
Contract.EndContractBlock();
@@ -107,16 +105,15 @@ namespace System.Text
return result;
}
- [System.Security.SecurityCritical] // auto-generated
public unsafe override int GetByteCount(char* chars, int count, bool flush)
{
// Validate input parameters
if (chars == null)
- throw new ArgumentNullException( "chars",
+ throw new ArgumentNullException(nameof(chars),
Environment.GetResourceString("ArgumentNull_Array"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count",
+ throw new ArgumentOutOfRangeException(nameof(count),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -125,25 +122,24 @@ namespace System.Text
return m_encoding.GetByteCount(chars, count, this);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override unsafe int GetBytes(char[] chars, int charIndex, int charCount,
byte[] bytes, int byteIndex, bool flush)
{
// Validate parameters
if (chars == null || bytes == null)
- throw new ArgumentNullException((chars == null ? "chars" : "bytes"),
+ throw new ArgumentNullException((chars == null ? nameof(chars) : nameof(bytes)),
Environment.GetResourceString("ArgumentNull_Array"));
if (charIndex < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((charIndex<0 ? "charIndex" : "charCount"),
+ throw new ArgumentOutOfRangeException((charIndex<0 ? nameof(charIndex) : nameof(charCount)),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (chars.Length - charIndex < charCount)
- throw new ArgumentOutOfRangeException("chars",
+ throw new ArgumentOutOfRangeException(nameof(chars),
Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
if (byteIndex < 0 || byteIndex > bytes.Length)
- throw new ArgumentOutOfRangeException("byteIndex",
+ throw new ArgumentOutOfRangeException(nameof(byteIndex),
Environment.GetResourceString("ArgumentOutOfRange_Index"));
Contract.EndContractBlock();
@@ -163,16 +159,15 @@ namespace System.Text
pBytes + byteIndex, byteCount, flush);
}
- [System.Security.SecurityCritical] // auto-generated
public unsafe override int GetBytes(char* chars, int charCount, byte* bytes, int byteCount, bool flush)
{
// Validate parameters
if (chars == null || bytes == null)
- throw new ArgumentNullException((chars == null ? "chars" : "bytes"),
+ throw new ArgumentNullException((chars == null ? nameof(chars) : nameof(bytes)),
Environment.GetResourceString("ArgumentNull_Array"));
if (byteCount < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((byteCount<0 ? "byteCount" : "charCount"),
+ throw new ArgumentOutOfRangeException((byteCount<0 ? nameof(byteCount) : nameof(charCount)),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -183,30 +178,29 @@ namespace System.Text
// This method is used when your output buffer might not be large enough for the entire result.
// Just call the pointer version. (This gets bytes)
- [System.Security.SecuritySafeCritical] // auto-generated
public override unsafe 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 ? "chars" : "bytes"),
+ throw new ArgumentNullException((chars == null ? nameof(chars) : nameof(bytes)),
Environment.GetResourceString("ArgumentNull_Array"));
if (charIndex < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((charIndex<0 ? "charIndex" : "charCount"),
+ throw new ArgumentOutOfRangeException((charIndex<0 ? nameof(charIndex) : nameof(charCount)),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (byteIndex < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((byteIndex<0 ? "byteIndex" : "byteCount"),
+ throw new ArgumentOutOfRangeException((byteIndex<0 ? nameof(byteIndex) : nameof(byteCount)),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (chars.Length - charIndex < charCount)
- throw new ArgumentOutOfRangeException("chars",
+ throw new ArgumentOutOfRangeException(nameof(chars),
Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
if (bytes.Length - byteIndex < byteCount)
- throw new ArgumentOutOfRangeException("bytes",
+ throw new ArgumentOutOfRangeException(nameof(bytes),
Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
Contract.EndContractBlock();
@@ -230,17 +224,16 @@ namespace System.Text
// This is the version that uses pointers. We call the base encoding worker function
// after setting our appropriate internal variables. This is getting bytes
- [System.Security.SecurityCritical] // auto-generated
public override 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 ? "bytes" : "chars",
+ throw new ArgumentNullException(bytes == null ? nameof(bytes) : nameof(chars),
Environment.GetResourceString("ArgumentNull_Array"));
if (charCount < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((charCount<0 ? "charCount" : "byteCount"),
+ throw new ArgumentOutOfRangeException((charCount<0 ? nameof(charCount) : nameof(byteCount)),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
diff --git a/src/mscorlib/src/System/Text/EncoderReplacementFallback.cs b/src/mscorlib/src/System/Text/EncoderReplacementFallback.cs
index 15dfee8912..604cddf9bb 100644
--- a/src/mscorlib/src/System/Text/EncoderReplacementFallback.cs
+++ b/src/mscorlib/src/System/Text/EncoderReplacementFallback.cs
@@ -6,6 +6,7 @@ namespace System.Text
{
using System;
using System.Runtime;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
[Serializable]
@@ -23,7 +24,7 @@ namespace System.Text
{
// Must not be null
if (replacement == null)
- throw new ArgumentNullException("replacement");
+ throw new ArgumentNullException(nameof(replacement));
Contract.EndContractBlock();
// Make sure it doesn't have bad surrogate pairs
@@ -60,7 +61,7 @@ namespace System.Text
break;
}
if (bFoundHigh)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex", "replacement"));
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex", nameof(replacement)));
strDefault = replacement;
}
@@ -147,7 +148,7 @@ namespace System.Text
{
// Double check input surrogate pair
if (!Char.IsHighSurrogate(charUnknownHigh))
- throw new ArgumentOutOfRangeException("charUnknownHigh",
+ throw new ArgumentOutOfRangeException(nameof(charUnknownHigh),
Environment.GetResourceString("ArgumentOutOfRange_Range",
0xD800, 0xDBFF));
@@ -189,7 +190,7 @@ namespace System.Text
}
// Now make sure its in the expected range
- Contract.Assert(fallbackIndex < strDefault.Length && fallbackIndex >= 0,
+ Debug.Assert(fallbackIndex < strDefault.Length && fallbackIndex >= 0,
"Index exceeds buffer range");
return strDefault[fallbackIndex];
@@ -220,7 +221,6 @@ namespace System.Text
}
// Clear the buffer
- [System.Security.SecuritySafeCritical] // auto-generated
public override unsafe void Reset()
{
fallbackCount = -1;
diff --git a/src/mscorlib/src/System/Text/Encoding.cs b/src/mscorlib/src/System/Text/Encoding.cs
index 8533016293..658bdbb133 100644
--- a/src/mscorlib/src/System/Text/Encoding.cs
+++ b/src/mscorlib/src/System/Text/Encoding.cs
@@ -15,6 +15,7 @@ namespace System.Text
using System.Security.Permissions;
using System.Threading;
using System.Text;
+ using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
using Win32Native = Microsoft.Win32.Win32Native;
@@ -189,7 +190,7 @@ namespace System.Text
// Validate code page
if (codePage < 0)
{
- throw new ArgumentOutOfRangeException("codePage");
+ throw new ArgumentOutOfRangeException(nameof(codePage));
}
Contract.EndContractBlock();
@@ -208,7 +209,7 @@ namespace System.Text
// Validate code page
if (codePage < 0)
{
- throw new ArgumentOutOfRangeException("codePage");
+ throw new ArgumentOutOfRangeException(nameof(codePage));
}
Contract.EndContractBlock();
@@ -275,7 +276,7 @@ namespace System.Text
internal void DeserializeEncoding(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException("info");
+ if (info==null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// All versions have a code page
@@ -314,7 +315,7 @@ namespace System.Text
internal void SerializeEncoding(SerializationInfo info, StreamingContext context)
{
// Any Info?
- if (info==null) throw new ArgumentNullException("info");
+ if (info==null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// These are new V2.0 Whidbey stuff
@@ -344,7 +345,7 @@ namespace System.Text
public static byte[] Convert(Encoding srcEncoding, Encoding dstEncoding,
byte[] bytes) {
if (bytes==null)
- throw new ArgumentNullException("bytes");
+ throw new ArgumentNullException(nameof(bytes));
Contract.Ensures(Contract.Result<byte[]>() != null);
return Convert(srcEncoding, dstEncoding, bytes, 0, bytes.Length);
@@ -359,11 +360,11 @@ namespace System.Text
public static byte[] Convert(Encoding srcEncoding, Encoding dstEncoding,
byte[] bytes, int index, int count) {
if (srcEncoding == null || dstEncoding == null) {
- throw new ArgumentNullException((srcEncoding == null ? "srcEncoding" : "dstEncoding"),
+ throw new ArgumentNullException((srcEncoding == null ? nameof(srcEncoding) : nameof(dstEncoding)),
Environment.GetResourceString("ArgumentNull_Array"));
}
if (bytes == null) {
- throw new ArgumentNullException("bytes",
+ throw new ArgumentNullException(nameof(bytes),
Environment.GetResourceString("ArgumentNull_Array"));
}
Contract.Ensures(Contract.Result<byte[]>() != null);
@@ -389,9 +390,6 @@ namespace System.Text
private static volatile Hashtable encodings;
#endif
-#if !FEATURE_CORECLR
- [System.Security.SecurityCritical]
-#endif
public static void RegisterProvider(EncodingProvider provider)
{
// Parameters validated inside EncodingProvider
@@ -399,9 +397,6 @@ namespace System.Text
}
[Pure]
-#if !FEATURE_CORECLR
- [System.Security.SecuritySafeCritical] // auto-generated
-#endif
public static Encoding GetEncoding(int codepage)
{
Encoding result = EncodingProvider.GetEncodingFromProvider(codepage);
@@ -416,7 +411,7 @@ namespace System.Text
//
if (codepage < 0 || codepage > 65535) {
throw new ArgumentOutOfRangeException(
- "codepage", Environment.GetResourceString("ArgumentOutOfRange_Range",
+ nameof(codepage), Environment.GetResourceString("ArgumentOutOfRange_Range",
0, 65535));
}
@@ -443,7 +438,7 @@ namespace System.Text
case CodePageNoThread: // 3 CP_THREAD_ACP
case CodePageNoSymbol: // 42 CP_SYMBOL
throw new ArgumentException(Environment.GetResourceString(
- "Argument_CodepageNotSupported", codepage), "codepage");
+ "Argument_CodepageNotSupported", codepage), nameof(codepage));
}
#if FEATURE_CODEPAGES_FILE
@@ -478,7 +473,7 @@ namespace System.Text
result = GetEncodingCodePage(codepage) ?? GetEncodingRare(codepage);
}
- Contract.Assert(result != null, "result != null");
+ Debug.Assert(result != null, "result != null");
encodings.Add(key, result);
}
@@ -516,10 +511,9 @@ namespace System.Text
return fallbackEncoding;
}
#if FEATURE_CODEPAGES_FILE
- [System.Security.SecurityCritical] // auto-generated
private static Encoding GetEncodingRare(int codepage)
{
- Contract.Assert(codepage != 0 && codepage != 1200 && codepage != 1201 && codepage != 65001,
+ Debug.Assert(codepage != 0 && codepage != 1200 && codepage != 1201 && codepage != 65001,
"[Encoding.GetEncodingRare]This code page (" + codepage + ") isn't supported by GetEncodingRare!");
Encoding result;
switch (codepage)
@@ -585,7 +579,6 @@ namespace System.Text
return result;
}
- [System.Security.SecurityCritical] // auto-generated
private static Encoding GetEncodingCodePage(int CodePage)
{
// Single Byte or Double Byte Code Page? (0 if not found)
@@ -795,7 +788,7 @@ namespace System.Text
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
if (value == null)
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
Contract.EndContractBlock();
encoderFallback = value;
@@ -817,7 +810,7 @@ namespace System.Text
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
if (value == null)
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
Contract.EndContractBlock();
decoderFallback = value;
@@ -865,7 +858,7 @@ namespace System.Text
{
if (chars == null)
{
- throw new ArgumentNullException("chars",
+ throw new ArgumentNullException(nameof(chars),
Environment.GetResourceString("ArgumentNull_Array"));
}
Contract.EndContractBlock();
@@ -876,8 +869,8 @@ namespace System.Text
[Pure]
public virtual int GetByteCount(String s)
{
- if (s==null)
- throw new ArgumentNullException("s");
+ if (s == null)
+ throw new ArgumentNullException(nameof(s));
Contract.EndContractBlock();
char[] chars = s.ToCharArray();
@@ -891,23 +884,50 @@ namespace System.Text
[Pure]
public abstract int GetByteCount(char[] chars, int index, int count);
+ // Returns the number of bytes required to encode a string range.
+ //
+ [Pure]
+ public int GetByteCount(string s, int index, int count)
+ {
+ if (s == null)
+ throw new ArgumentNullException(nameof(s),
+ Environment.GetResourceString("ArgumentNull_String"));
+ if (index < 0)
+ throw new ArgumentOutOfRangeException(nameof(index),
+ Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (count < 0)
+ throw new ArgumentOutOfRangeException(nameof(count),
+ Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (index > s.Length - count)
+ throw new ArgumentOutOfRangeException(nameof(index),
+ Environment.GetResourceString("ArgumentOutOfRange_IndexCount"));
+ Contract.EndContractBlock();
+
+ unsafe
+ {
+ fixed (char* pChar = s)
+ {
+ return GetByteCount(pChar + index, count);
+ }
+ }
+ }
+
// 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 this method should be avoided if you're calling
// a 3rd party encoding.
[Pure]
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public virtual unsafe int GetByteCount(char* chars, int count)
{
// Validate input parameters
if (chars == null)
- throw new ArgumentNullException("chars",
+ throw new ArgumentNullException(nameof(chars),
Environment.GetResourceString("ArgumentNull_Array"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count",
+ throw new ArgumentOutOfRangeException(nameof(count),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -922,7 +942,6 @@ namespace System.Text
// For NLS Encodings, workhorse takes an encoder (may be null)
// Always validate parameters before calling internal version, which will only assert.
- [System.Security.SecurityCritical] // auto-generated
internal virtual unsafe int GetByteCount(char* chars, int count, EncoderNLS encoder)
{
Contract.Requires(chars != null);
@@ -939,7 +958,7 @@ namespace System.Text
{
if (chars == null)
{
- throw new ArgumentNullException("chars",
+ throw new ArgumentNullException(nameof(chars),
Environment.GetResourceString("ArgumentNull_Array"));
}
Contract.EndContractBlock();
@@ -976,29 +995,67 @@ namespace System.Text
public virtual byte[] GetBytes(String s)
{
if (s == null)
- throw new ArgumentNullException("s",
+ throw new ArgumentNullException(nameof(s),
Environment.GetResourceString("ArgumentNull_String"));
Contract.EndContractBlock();
int byteCount = GetByteCount(s);
byte[] bytes = new byte[byteCount];
int bytesReceived = GetBytes(s, 0, s.Length, bytes, 0);
- Contract.Assert(byteCount == bytesReceived);
+ Debug.Assert(byteCount == bytesReceived);
return bytes;
}
+ // Returns a byte array containing the encoded representation of the given
+ // string range.
+ //
+ [Pure]
+ public byte[] GetBytes(string s, int index, int count)
+ {
+ if (s == null)
+ throw new ArgumentNullException(nameof(s),
+ Environment.GetResourceString("ArgumentNull_String"));
+ if (index < 0)
+ throw new ArgumentOutOfRangeException(nameof(index),
+ Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (count < 0)
+ throw new ArgumentOutOfRangeException(nameof(count),
+ Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (index > s.Length - count)
+ throw new ArgumentOutOfRangeException(nameof(index),
+ Environment.GetResourceString("ArgumentOutOfRange_IndexCount"));
+ Contract.EndContractBlock();
+
+ unsafe
+ {
+ fixed (char* pChar = s)
+ {
+ int byteCount = GetByteCount(pChar + index, count);
+ if (byteCount == 0)
+ return Array.Empty<byte>();
+
+ byte[] bytes = new byte[byteCount];
+ fixed (byte* pBytes = &bytes[0])
+ {
+ int bytesReceived = GetBytes(pChar + index, count, pBytes, byteCount);
+ Debug.Assert(byteCount == bytesReceived);
+ }
+ return bytes;
+ }
+ }
+ }
+
public virtual int GetBytes(String s, int charIndex, int charCount,
byte[] bytes, int byteIndex)
{
- if (s==null)
- throw new ArgumentNullException("s");
+ if (s == null)
+ throw new ArgumentNullException(nameof(s));
Contract.EndContractBlock();
return GetBytes(s.ToCharArray(), charIndex, charCount, bytes, byteIndex);
}
// This is our internal workhorse
// Always validate parameters before calling internal version, which will only assert.
- [System.Security.SecurityCritical] // auto-generated
internal virtual unsafe int GetBytes(char* chars, int charCount,
byte* bytes, int byteCount, EncoderNLS encoder)
{
@@ -1022,7 +1079,6 @@ namespace System.Text
// 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.
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public virtual unsafe int GetBytes(char* chars, int charCount,
@@ -1030,11 +1086,11 @@ namespace System.Text
{
// Validate input parameters
if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? "bytes" : "chars",
+ throw new ArgumentNullException(bytes == null ? nameof(bytes) : nameof(chars),
Environment.GetResourceString("ArgumentNull_Array"));
if (charCount < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((charCount<0 ? "charCount" : "byteCount"),
+ throw new ArgumentOutOfRangeException((charCount<0 ? nameof(charCount) : nameof(byteCount)),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -1051,7 +1107,7 @@ namespace System.Text
// Do the work
int result = GetBytes(arrChar, 0, charCount, arrByte, 0);
- Contract.Assert(result <= byteCount, "[Encoding.GetBytes]Returned more bytes than we have space for");
+ Debug.Assert(result <= byteCount, "[Encoding.GetBytes]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
@@ -1076,7 +1132,7 @@ namespace System.Text
{
if (bytes == null)
{
- throw new ArgumentNullException("bytes",
+ throw new ArgumentNullException(nameof(bytes),
Environment.GetResourceString("ArgumentNull_Array"));
}
Contract.EndContractBlock();
@@ -1092,18 +1148,17 @@ namespace System.Text
// We expect this to be the workhorse for NLS Encodings, but for existing
// ones we need a working (if slow) default implimentation)
[Pure]
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public virtual unsafe int GetCharCount(byte* bytes, int count)
{
// Validate input parameters
if (bytes == null)
- throw new ArgumentNullException("bytes",
+ throw new ArgumentNullException(nameof(bytes),
Environment.GetResourceString("ArgumentNull_Array"));
if (count < 0)
- throw new ArgumentOutOfRangeException("count",
+ throw new ArgumentOutOfRangeException(nameof(count),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -1118,7 +1173,6 @@ namespace System.Text
// This is our internal workhorse
// Always validate parameters before calling internal version, which will only assert.
- [System.Security.SecurityCritical] // auto-generated
internal virtual unsafe int GetCharCount(byte* bytes, int count, DecoderNLS decoder)
{
return GetCharCount(bytes, count);
@@ -1132,7 +1186,7 @@ namespace System.Text
{
if (bytes == null)
{
- throw new ArgumentNullException("bytes",
+ throw new ArgumentNullException(nameof(bytes),
Environment.GetResourceString("ArgumentNull_Array"));
}
Contract.EndContractBlock();
@@ -1181,7 +1235,6 @@ namespace System.Text
// 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.
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public virtual unsafe int GetChars(byte* bytes, int byteCount,
@@ -1189,11 +1242,11 @@ namespace System.Text
{
// Validate input parameters
if (chars == null || bytes == null)
- throw new ArgumentNullException(chars == null ? "chars" : "bytes",
+ throw new ArgumentNullException(chars == null ? nameof(chars) : nameof(bytes),
Environment.GetResourceString("ArgumentNull_Array"));
if (byteCount < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((byteCount<0 ? "byteCount" : "charCount"),
+ throw new ArgumentOutOfRangeException((byteCount<0 ? nameof(byteCount) : nameof(charCount)),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -1210,7 +1263,7 @@ namespace System.Text
// Do the work
int result = GetChars(arrByte, 0, byteCount, arrChar, 0);
- Contract.Assert(result <= charCount, "[Encoding.GetChars]Returned more chars than we have space for");
+ Debug.Assert(result <= charCount, "[Encoding.GetChars]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
@@ -1230,7 +1283,6 @@ namespace System.Text
// This is our internal workhorse
// Always validate parameters before calling internal version, which will only assert.
- [System.Security.SecurityCritical] // auto-generated
internal virtual unsafe int GetChars(byte* bytes, int byteCount,
char* chars, int charCount, DecoderNLS decoder)
{
@@ -1238,16 +1290,15 @@ namespace System.Text
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public unsafe string GetString(byte* bytes, int byteCount)
{
if (bytes == null)
- throw new ArgumentNullException("bytes", Environment.GetResourceString("ArgumentNull_Array"));
+ throw new ArgumentNullException(nameof(bytes), Environment.GetResourceString("ArgumentNull_Array"));
if (byteCount < 0)
- throw new ArgumentOutOfRangeException("byteCount", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(byteCount), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
return String.CreateStringFromEncoding(bytes, byteCount, this);
@@ -1306,7 +1357,6 @@ namespace System.Text
return new DefaultDecoder(this);
}
- [System.Security.SecuritySafeCritical]
private static Encoding CreateDefaultEncoding()
{
// defaultEncoding should be null if we get here, but we can't
@@ -1391,7 +1441,7 @@ namespace System.Text
public virtual String GetString(byte[] bytes)
{
if (bytes == null)
- throw new ArgumentNullException("bytes",
+ throw new ArgumentNullException(nameof(bytes),
Environment.GetResourceString("ArgumentNull_Array"));
Contract.EndContractBlock();
@@ -1482,7 +1532,6 @@ namespace System.Text
EncodingName, EncoderFallback.GetType()), "bytes");
}
- [System.Security.SecurityCritical] // auto-generated
internal void ThrowBytesOverflow(EncoderNLS encoder, bool nothingEncoded)
{
if (encoder == null || encoder.m_throwOnOverflow || nothingEncoded)
@@ -1507,7 +1556,6 @@ namespace System.Text
EncodingName, DecoderFallback.GetType()), "chars");
}
- [System.Security.SecurityCritical] // auto-generated
internal void ThrowCharsOverflow(DecoderNLS decoder, bool nothingDecoded)
{
if (decoder == null || decoder.m_throwOnOverflow || nothingDecoded)
@@ -1541,7 +1589,7 @@ 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("info");
+ if (info==null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// All we have is our encoding
@@ -1558,7 +1606,6 @@ namespace System.Text
}
// Just get it from GetEncoding
- [System.Security.SecurityCritical] // auto-generated
public Object GetRealObject(StreamingContext context)
{
// upon deserialization since the DefaultEncoder implement IObjectReference the
@@ -1584,11 +1631,10 @@ namespace System.Text
}
// ISerializable implementation, get data for this object
- [System.Security.SecurityCritical] // auto-generated_required
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException("info");
+ if (info==null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// All we have is our encoding
@@ -1608,7 +1654,6 @@ namespace System.Text
return m_encoding.GetByteCount(chars, index, count);
}
- [System.Security.SecurityCritical] // auto-generated
[SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
public unsafe override int GetByteCount(char* chars, int count, bool flush)
{
@@ -1641,7 +1686,6 @@ namespace System.Text
return m_encoding.GetBytes(chars, charIndex, charCount, bytes, byteIndex);
}
- [System.Security.SecurityCritical] // auto-generated
[SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
public unsafe override int GetBytes(char* chars, int charCount,
byte* bytes, int byteCount, bool flush)
@@ -1667,7 +1711,7 @@ namespace System.Text
internal DefaultDecoder(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException("info");
+ if (info==null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// All we have is our encoding
@@ -1684,7 +1728,6 @@ namespace System.Text
}
// Just get it from GetEncoding
- [System.Security.SecurityCritical] // auto-generated
public Object GetRealObject(StreamingContext context)
{
// upon deserialization since the DefaultEncoder implement IObjectReference the
@@ -1705,11 +1748,10 @@ namespace System.Text
}
// ISerializable implementation, get data for this object
- [System.Security.SecurityCritical] // auto-generated_required
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException("info");
+ if (info==null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// All we have is our encoding
@@ -1733,7 +1775,6 @@ namespace System.Text
return m_encoding.GetCharCount(bytes, index, count);
}
- [System.Security.SecurityCritical] // auto-generated
[SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
public unsafe override int GetCharCount(byte* bytes, int count, bool flush)
{
@@ -1770,7 +1811,6 @@ namespace System.Text
return m_encoding.GetChars(bytes, byteIndex, byteCount, chars, charIndex);
}
- [System.Security.SecurityCritical] // auto-generated
[SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
public unsafe override int GetChars(byte* bytes, int byteCount,
char* chars, int charCount, bool flush)
@@ -1782,24 +1822,17 @@ namespace System.Text
internal class EncodingCharBuffer
{
- [SecurityCritical]
unsafe char* chars;
- [SecurityCritical]
unsafe char* charStart;
- [SecurityCritical]
unsafe char* charEnd;
int charCountResult = 0;
Encoding enc;
DecoderNLS decoder;
- [SecurityCritical]
unsafe byte* byteStart;
- [SecurityCritical]
unsafe byte* byteEnd;
- [SecurityCritical]
unsafe byte* bytes;
DecoderFallbackBuffer fallbackBuffer;
- [System.Security.SecurityCritical] // auto-generated
internal unsafe EncodingCharBuffer(Encoding enc, DecoderNLS decoder, char* charStart, int charCount,
byte* byteStart, int byteCount)
{
@@ -1821,12 +1854,11 @@ namespace System.Text
// 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)
- Contract.Assert(fallbackBuffer.Remaining == 0,
+ Debug.Assert(fallbackBuffer.Remaining == 0,
"[Encoding.EncodingCharBuffer.EncodingCharBuffer]Expected empty fallback buffer for getchars/charcount");
fallbackBuffer.InternalInitialize(bytes, charEnd);
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe bool AddChar(char ch, int numBytes)
{
if (chars != null)
@@ -1845,14 +1877,12 @@ namespace System.Text
return true;
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe bool AddChar(char ch)
{
return AddChar(ch,1);
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe bool AddChar(char ch1, char ch2, int numBytes)
{
// Need room for 2 chars
@@ -1866,7 +1896,6 @@ namespace System.Text
return AddChar(ch1, numBytes) && AddChar(ch2, numBytes);
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe void AdjustBytes(int count)
{
bytes += count;
@@ -1874,7 +1903,6 @@ namespace System.Text
internal unsafe bool MoreData
{
- [System.Security.SecurityCritical] // auto-generated
get
{
return bytes < byteEnd;
@@ -1882,7 +1910,6 @@ namespace System.Text
}
// Do we have count more bytes?
- [System.Security.SecurityCritical] // auto-generated
internal unsafe bool EvenMoreData(int count)
{
return (bytes <= byteEnd - count);
@@ -1890,10 +1917,9 @@ namespace System.Text
// GetNextByte shouldn't be called unless the caller's already checked more data or even more data,
// but we'll double check just to make sure.
- [System.Security.SecurityCritical] // auto-generated
internal unsafe byte GetNextByte()
{
- Contract.Assert(bytes < byteEnd, "[EncodingCharBuffer.GetNextByte]Expected more date");
+ Debug.Assert(bytes < byteEnd, "[EncodingCharBuffer.GetNextByte]Expected more date");
if (bytes >= byteEnd)
return 0;
return *(bytes++);
@@ -1901,14 +1927,12 @@ namespace System.Text
internal unsafe int BytesUsed
{
- [System.Security.SecurityCritical] // auto-generated
get
{
return (int)(bytes - byteStart);
}
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe bool Fallback(byte fallbackByte)
{
// Build our buffer
@@ -1918,7 +1942,6 @@ namespace System.Text
return Fallback(byteBuffer);
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe bool Fallback(byte byte1, byte byte2)
{
// Build our buffer
@@ -1928,7 +1951,6 @@ namespace System.Text
return Fallback(byteBuffer);
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe bool Fallback(byte byte1, byte byte2, byte byte3, byte byte4)
{
// Build our buffer
@@ -1938,7 +1960,6 @@ namespace System.Text
return Fallback(byteBuffer);
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe bool Fallback(byte[] byteBuffer)
{
// Do the fallback and add the data.
@@ -1974,24 +1995,17 @@ namespace System.Text
internal class EncodingByteBuffer
{
- [SecurityCritical]
unsafe byte* bytes;
- [SecurityCritical]
unsafe byte* byteStart;
- [SecurityCritical]
unsafe byte* byteEnd;
- [SecurityCritical]
unsafe char* chars;
- [SecurityCritical]
unsafe char* charStart;
- [SecurityCritical]
unsafe char* charEnd;
int byteCountResult = 0;
Encoding enc;
EncoderNLS encoder;
internal EncoderFallbackBuffer fallbackBuffer;
- [System.Security.SecurityCritical] // auto-generated
internal unsafe EncodingByteBuffer(Encoding inEncoding, EncoderNLS inEncoder,
byte* inByteStart, int inByteCount, char* inCharStart, int inCharCount)
{
@@ -2020,10 +2034,9 @@ namespace System.Text
fallbackBuffer.InternalInitialize(chars, charEnd, encoder, bytes != null);
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe bool AddByte(byte b, int moreBytesExpected)
{
- Contract.Assert(moreBytesExpected >= 0, "[EncodingByteBuffer.AddByte]expected non-negative moreBytesExpected");
+ Debug.Assert(moreBytesExpected >= 0, "[EncodingByteBuffer.AddByte]expected non-negative moreBytesExpected");
if (bytes != null)
{
if (bytes >= byteEnd - moreBytesExpected)
@@ -2039,31 +2052,26 @@ namespace System.Text
return true;
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe bool AddByte(byte b1)
{
return (AddByte(b1, 0));
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe bool AddByte(byte b1, byte b2)
{
return (AddByte(b1, b2, 0));
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe bool AddByte(byte b1, byte b2, int moreBytesExpected)
{
return (AddByte(b1, 1 + moreBytesExpected) && AddByte(b2, moreBytesExpected));
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe bool AddByte(byte b1, byte b2, byte b3)
{
return AddByte(b1, b2, b3, (int)0);
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe bool AddByte(byte b1, byte b2, byte b3, int moreBytesExpected)
{
return (AddByte(b1, 2 + moreBytesExpected) &&
@@ -2071,7 +2079,6 @@ namespace System.Text
AddByte(b3, moreBytesExpected));
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe bool AddByte(byte b1, byte b2, byte b3, byte b4)
{
return (AddByte(b1, 3) &&
@@ -2080,14 +2087,13 @@ namespace System.Text
AddByte(b4, 0));
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe void MovePrevious(bool bThrow)
{
if (fallbackBuffer.bFallingBack)
fallbackBuffer.MovePrevious(); // don't use last fallback
else
{
- Contract.Assert(chars > charStart ||
+ Debug.Assert(chars > charStart ||
((bThrow == true) && (bytes == byteStart)),
"[EncodingByteBuffer.MovePrevious]expected previous data or throw");
if (chars > charStart)
@@ -2098,7 +2104,6 @@ namespace System.Text
enc.ThrowBytesOverflow(encoder, bytes == byteStart); // Throw? (and reset fallback if not converting)
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe bool Fallback(char charFallback)
{
// Do the fallback
@@ -2107,7 +2112,6 @@ namespace System.Text
internal unsafe bool MoreData
{
- [System.Security.SecurityCritical] // auto-generated
get
{
// See if fallbackBuffer is not empty or if there's data left in chars buffer.
@@ -2115,7 +2119,6 @@ namespace System.Text
}
}
- [System.Security.SecurityCritical] // auto-generated
internal unsafe char GetNextChar()
{
// See if there's something in our fallback buffer
@@ -2133,7 +2136,6 @@ namespace System.Text
internal unsafe int CharsUsed
{
- [System.Security.SecurityCritical] // auto-generated
get
{
return (int)(chars - charStart);
diff --git a/src/mscorlib/src/System/Text/EncodingForwarder.cs b/src/mscorlib/src/System/Text/EncodingForwarder.cs
index d4bcf800e3..9a8dd26627 100644
--- a/src/mscorlib/src/System/Text/EncodingForwarder.cs
+++ b/src/mscorlib/src/System/Text/EncodingForwarder.cs
@@ -2,6 +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.Diagnostics;
using System.Diagnostics.Contracts;
using System.Security;
@@ -31,23 +32,22 @@ namespace System.Text
// the parameter, it will call the same method again, which will eventually
// lead to a StackOverflowException.
- [SecuritySafeCritical]
public unsafe static int GetByteCount(Encoding encoding, char[] chars, int index, int count)
{
// Validate parameters
- Contract.Assert(encoding != null); // this parameter should only be affected internally, so just do a debug check here
+ Debug.Assert(encoding != null); // this parameter should only be affected internally, so just do a debug check here
if (chars == null)
{
- throw new ArgumentNullException("chars", Environment.GetResourceString("ArgumentNull_Array"));
+ throw new ArgumentNullException(nameof(chars), Environment.GetResourceString("ArgumentNull_Array"));
}
if (index < 0 || count < 0)
{
- throw new ArgumentOutOfRangeException(index < 0 ? "index" : "count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(index < 0 ? nameof(index) : nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (chars.Length - index < count)
{
- throw new ArgumentOutOfRangeException("chars", Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
+ throw new ArgumentOutOfRangeException(nameof(chars), Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
}
Contract.EndContractBlock();
@@ -60,13 +60,12 @@ namespace System.Text
return encoding.GetByteCount(pChars + index, count, encoder: null);
}
- [SecuritySafeCritical]
public unsafe static int GetByteCount(Encoding encoding, string s)
{
- Contract.Assert(encoding != null);
+ Debug.Assert(encoding != null);
if (s == null)
{
- string paramName = encoding is ASCIIEncoding ? "chars" : "s"; // ASCIIEncoding calls the string chars
+ 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);
}
@@ -84,17 +83,16 @@ namespace System.Text
return encoding.GetByteCount(pChars, s.Length, encoder: null);
}
- [SecurityCritical]
public unsafe static int GetByteCount(Encoding encoding, char* chars, int count)
{
- Contract.Assert(encoding != null);
+ Debug.Assert(encoding != null);
if (chars == null)
{
- throw new ArgumentNullException("chars", Environment.GetResourceString("ArgumentNull_Array"));
+ throw new ArgumentNullException(nameof(chars), Environment.GetResourceString("ArgumentNull_Array"));
}
if (count < 0)
{
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
Contract.EndContractBlock();
@@ -102,28 +100,27 @@ namespace System.Text
return encoding.GetByteCount(chars, count, encoder: null);
}
- [SecuritySafeCritical]
public unsafe static int GetBytes(Encoding encoding, string s, int charIndex, int charCount, byte[] bytes, int byteIndex)
{
- Contract.Assert(encoding != null);
+ Debug.Assert(encoding != null);
if (s == null || bytes == null)
{
- string stringName = encoding is ASCIIEncoding ? "chars" : "s"; // ASCIIEncoding calls the first parameter chars
- throw new ArgumentNullException(s == null ? stringName : "bytes", Environment.GetResourceString("ArgumentNull_Array"));
+ 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 ? "charIndex" : "charCount", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(charIndex < 0 ? nameof(charIndex) : nameof(charCount), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (s.Length - charIndex < charCount)
{
- string stringName = encoding is ASCIIEncoding ? "chars" : "s"; // ASCIIEncoding calls the first parameter chars
+ 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("byteIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(byteIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
Contract.EndContractBlock();
@@ -139,25 +136,24 @@ namespace System.Text
}
}
- [SecuritySafeCritical]
public unsafe static int GetBytes(Encoding encoding, char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
{
- Contract.Assert(encoding != null);
+ Debug.Assert(encoding != null);
if (chars == null || bytes == null)
{
- throw new ArgumentNullException(chars == null ? "chars" : "bytes", Environment.GetResourceString("ArgumentNull_Array"));
+ throw new ArgumentNullException(chars == null ? nameof(chars) : nameof(bytes), Environment.GetResourceString("ArgumentNull_Array"));
}
if (charIndex < 0 || charCount < 0)
{
- throw new ArgumentOutOfRangeException(charIndex < 0 ? "charIndex" : "charCount", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(charIndex < 0 ? nameof(charIndex) : nameof(charCount), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (chars.Length - charIndex < charCount)
{
- throw new ArgumentOutOfRangeException("chars", Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
+ throw new ArgumentOutOfRangeException(nameof(chars), Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
}
if (byteIndex < 0 || byteIndex > bytes.Length)
{
- throw new ArgumentOutOfRangeException("byteIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(byteIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
Contract.EndContractBlock();
@@ -180,38 +176,36 @@ namespace System.Text
}
}
- [SecurityCritical]
public unsafe static int GetBytes(Encoding encoding, char* chars, int charCount, byte* bytes, int byteCount)
{
- Contract.Assert(encoding != null);
+ Debug.Assert(encoding != null);
if (bytes == null || chars == null)
{
- throw new ArgumentNullException(bytes == null ? "bytes" : "chars", Environment.GetResourceString("ArgumentNull_Array"));
+ throw new ArgumentNullException(bytes == null ? nameof(bytes) : nameof(chars), Environment.GetResourceString("ArgumentNull_Array"));
}
if (charCount < 0 || byteCount < 0)
{
- throw new ArgumentOutOfRangeException(charCount < 0 ? "charCount" : "byteCount", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(charCount < 0 ? nameof(charCount) : nameof(byteCount), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
Contract.EndContractBlock();
return encoding.GetBytes(chars, charCount, bytes, byteCount, encoder: null);
}
- [SecuritySafeCritical]
public unsafe static int GetCharCount(Encoding encoding, byte[] bytes, int index, int count)
{
- Contract.Assert(encoding != null);
+ Debug.Assert(encoding != null);
if (bytes == null)
{
- throw new ArgumentNullException("bytes", Environment.GetResourceString("ArgumentNull_Array"));
+ throw new ArgumentNullException(nameof(bytes), Environment.GetResourceString("ArgumentNull_Array"));
}
if (index < 0 || count < 0)
{
- throw new ArgumentOutOfRangeException(index < 0 ? "index" : "count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(index < 0 ? nameof(index) : nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (bytes.Length - index < count)
{
- throw new ArgumentOutOfRangeException("bytes", Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
+ throw new ArgumentOutOfRangeException(nameof(bytes), Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
}
Contract.EndContractBlock();
@@ -224,42 +218,40 @@ namespace System.Text
return encoding.GetCharCount(pBytes + index, count, decoder: null);
}
- [SecurityCritical]
public unsafe static int GetCharCount(Encoding encoding, byte* bytes, int count)
{
- Contract.Assert(encoding != null);
+ Debug.Assert(encoding != null);
if (bytes == null)
{
- throw new ArgumentNullException("bytes", Environment.GetResourceString("ArgumentNull_Array"));
+ throw new ArgumentNullException(nameof(bytes), Environment.GetResourceString("ArgumentNull_Array"));
}
if (count < 0)
{
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
Contract.EndContractBlock();
return encoding.GetCharCount(bytes, count, decoder: null);
}
- [SecuritySafeCritical]
public unsafe static int GetChars(Encoding encoding, byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
{
- Contract.Assert(encoding != null);
+ Debug.Assert(encoding != null);
if (bytes == null || chars == null)
{
- throw new ArgumentNullException(bytes == null ? "bytes" : "chars", Environment.GetResourceString("ArgumentNull_Array"));
+ throw new ArgumentNullException(bytes == null ? nameof(bytes) : nameof(chars), Environment.GetResourceString("ArgumentNull_Array"));
}
if (byteIndex < 0 || byteCount < 0)
{
- throw new ArgumentOutOfRangeException(byteIndex < 0 ? "byteIndex" : "byteCount", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(byteIndex < 0 ? nameof(byteIndex) : nameof(byteCount), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (bytes.Length - byteIndex < byteCount)
{
- throw new ArgumentOutOfRangeException("bytes", Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
+ throw new ArgumentOutOfRangeException(nameof(bytes), Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
}
if (charIndex < 0 || charIndex > chars.Length)
{
- throw new ArgumentOutOfRangeException("charIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(charIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
Contract.EndContractBlock();
@@ -280,42 +272,40 @@ namespace System.Text
}
}
- [SecurityCritical]
public unsafe static int GetChars(Encoding encoding, byte* bytes, int byteCount, char* chars, int charCount)
{
- Contract.Assert(encoding != null);
+ Debug.Assert(encoding != null);
if (bytes == null || chars == null)
{
- throw new ArgumentNullException(bytes == null ? "bytes" : "chars", Environment.GetResourceString("ArgumentNull_Array"));
+ throw new ArgumentNullException(bytes == null ? nameof(bytes) : nameof(chars), Environment.GetResourceString("ArgumentNull_Array"));
}
if (charCount < 0 || byteCount < 0)
{
- throw new ArgumentOutOfRangeException(charCount < 0 ? "charCount" : "byteCount", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(charCount < 0 ? nameof(charCount) : nameof(byteCount), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
Contract.EndContractBlock();
return encoding.GetChars(bytes, byteCount, chars, charCount, decoder: null);
}
- [SecuritySafeCritical]
public unsafe static string GetString(Encoding encoding, byte[] bytes, int index, int count)
{
- Contract.Assert(encoding != null);
+ Debug.Assert(encoding != null);
if (bytes == null)
{
- throw new ArgumentNullException("bytes", Environment.GetResourceString("ArgumentNull_Array"));
+ 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" : "index";
- string countName = ascii ? "byteCount" : "count";
+ 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("bytes", Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
+ throw new ArgumentOutOfRangeException(nameof(bytes), Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
}
Contract.EndContractBlock();
diff --git a/src/mscorlib/src/System/Text/EncodingNLS.cs b/src/mscorlib/src/System/Text/EncodingNLS.cs
index d670d6daa7..fbddf37e88 100644
--- a/src/mscorlib/src/System/Text/EncodingNLS.cs
+++ b/src/mscorlib/src/System/Text/EncodingNLS.cs
@@ -50,7 +50,6 @@ namespace System.Text
return EncodingForwarder.GetByteCount(this, s);
}
- [System.Security.SecurityCritical] // auto-generated
public override unsafe int GetByteCount(char* chars, int count)
{
return EncodingForwarder.GetByteCount(this, chars, count);
@@ -77,7 +76,6 @@ namespace System.Text
return EncodingForwarder.GetBytes(this, chars, charIndex, charCount, bytes, byteIndex);
}
- [System.Security.SecurityCritical] // auto-generated
public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
{
return EncodingForwarder.GetBytes(this, chars, charCount, bytes, byteCount);
@@ -91,7 +89,6 @@ namespace System.Text
return EncodingForwarder.GetCharCount(this, bytes, index, count);
}
- [System.Security.SecurityCritical] // auto-generated
public override unsafe int GetCharCount(byte* bytes, int count)
{
return EncodingForwarder.GetCharCount(this, bytes, count);
@@ -103,7 +100,6 @@ namespace System.Text
return EncodingForwarder.GetChars(this, bytes, byteIndex, byteCount, chars, charIndex);
}
- [System.Security.SecurityCritical] // auto-generated
public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
{
return EncodingForwarder.GetChars(this, bytes, byteCount, chars, charCount);
diff --git a/src/mscorlib/src/System/Text/EncodingProvider.cs b/src/mscorlib/src/System/Text/EncodingProvider.cs
index b1dea2cd3c..a7f745a753 100644
--- a/src/mscorlib/src/System/Text/EncodingProvider.cs
+++ b/src/mscorlib/src/System/Text/EncodingProvider.cs
@@ -45,7 +45,7 @@ namespace System.Text
internal static void AddProvider(EncodingProvider provider)
{
if (provider == null)
- throw new ArgumentNullException("provider");
+ throw new ArgumentNullException(nameof(provider));
lock (s_InternalSyncObject)
{
diff --git a/src/mscorlib/src/System/Text/GB18030Encoding.cs b/src/mscorlib/src/System/Text/GB18030Encoding.cs
index 98746fcdb0..8ed52a6ab8 100644
--- a/src/mscorlib/src/System/Text/GB18030Encoding.cs
+++ b/src/mscorlib/src/System/Text/GB18030Encoding.cs
@@ -85,6 +85,7 @@
namespace System.Text
{
using System;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Text;
using System.Runtime.InteropServices;
@@ -107,10 +108,8 @@ namespace System.Text
// This is the table of 4 byte conversions.
private const int GBLast4ByteCode = 0x99FB;
[NonSerialized]
- [SecurityCritical]
unsafe internal char* map4BytesToUnicode = null; // new char[GBLast4ByteCode + 1]; // Need to map all 4 byte sequences to Unicode
[NonSerialized]
- [SecurityCritical]
unsafe internal byte* mapUnicodeTo4BytesFlags = null; // new byte[0x10000 / 8]; // Need 1 bit for each code point to say if its 4 byte or not
private const int GB18030 = 54936;
@@ -120,37 +119,33 @@ namespace System.Text
private const int GBLastSurrogateOffset = 0x12E247; // GBE3329A35
// We have to load the 936 code page tables, so impersonate 936 as our base
- [System.Security.SecurityCritical] // auto-generated
internal GB18030Encoding() : base(GB18030, 936)
{
}
// Constructor called by serialization.
- [System.Security.SecurityCritical] // auto-generated
internal GB18030Encoding(SerializationInfo info, StreamingContext context) :
base(GB18030, 936)
{
// Set up our base, also throws if info was empty
DeserializeEncoding(info, context);
- Contract.Assert(info!=null, "[GB18030Encoding(Serialization...)] Expected null info to throw");
+ Debug.Assert(info!=null, "[GB18030Encoding(Serialization...)] Expected null info to throw");
// Already build our code page, fallbacks & read only, so we're good to go!
}
// ISerializable implementation
- [System.Security.SecurityCritical] // auto-generated_required
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
// Make sure to get the base stuff too This throws if info is null
SerializeEncoding(info, context);
- Contract.Assert(info!=null, "[GB18030.GetObjectData] Expected null info to throw");
+ Debug.Assert(info!=null, "[GB18030.GetObjectData] Expected null info to throw");
// Everett doesn't need more than the basics
}
// This loads our base 936 code page and then applys the changes from the tableUnicodeToGBDiffs table.
// See table comments for table format.
- [System.Security.SecurityCritical] // auto-generated
protected override unsafe void LoadManagedCodePage()
{
// Use base code page loading algorithm.
@@ -199,7 +194,7 @@ namespace System.Text
// It was GB 18030 4 byte data, next <data> characters are 4 byte sequences.
while (data > 0)
{
- Contract.Assert(count4Byte <= GBLast4ByteCode,
+ Debug.Assert(count4Byte <= GBLast4ByteCode,
"[GB18030Encoding.LoadManagedCodePage] Found too many 4 byte codes in data table.");
// Set the 4 byte -> Unicode value
@@ -217,11 +212,11 @@ namespace System.Text
}
// unicodeCount should've wrapped back to 0
- Contract.Assert(unicodeCount == 0,
+ Debug.Assert(unicodeCount == 0,
"[GB18030Encoding.LoadManagedCodePage] Expected unicodeCount to wrap around to 0 as all chars were processed");
// We should've read in GBLast4ByteCode 4 byte sequences
- Contract.Assert(count4Byte == GBLast4ByteCode + 1,
+ Debug.Assert(count4Byte == GBLast4ByteCode + 1,
"[GB18030Encoding.LoadManagedCodePage] Expected 0x99FB to be last 4 byte offset, found 0x" + count4Byte.ToString("X4", CultureInfo.InvariantCulture));
// Need to flag ourselves saying we've built this CP.
@@ -238,7 +233,6 @@ namespace System.Text
// Is4Byte
// Checks the 4 byte table and returns true if this is a 4 byte code.
// Its a 4 byte code if the flag is set in mapUnicodeTo4BytesFlags
- [System.Security.SecurityCritical] // auto-generated
internal unsafe bool Is4Byte(char charTest)
{
// See what kind it is
@@ -247,26 +241,24 @@ namespace System.Text
}
// GetByteCount
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetByteCount(char* chars, int count, EncoderNLS encoder)
{
// Just call GetBytes() with null bytes
return GetBytes(chars, count, null, 0, encoder);
}
- [System.Security.SecurityCritical] // auto-generated
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
// We'll allow null bytes as a count
-// Contract.Assert(bytes != null, "[GB18030Encoding.GetBytes]bytes is null");
- Contract.Assert(byteCount >= 0, "[GB18030Encoding.GetBytes]byteCount is negative");
- Contract.Assert(chars != null, "[GB18030Encoding.GetBytes]chars is null");
- Contract.Assert(charCount >= 0, "[GB18030Encoding.GetBytes]charCount is negative");
+// Debug.Assert(bytes != null, "[GB18030Encoding.GetBytes]bytes is null");
+ Debug.Assert(byteCount >= 0, "[GB18030Encoding.GetBytes]byteCount is negative");
+ Debug.Assert(chars != null, "[GB18030Encoding.GetBytes]chars is null");
+ Debug.Assert(charCount >= 0, "[GB18030Encoding.GetBytes]charCount is negative");
// Assert because we shouldn't be able to have a null encoder.
- Contract.Assert(encoderFallback != null, "[GB18030Encoding.GetBytes]Attempting to use null encoder fallback");
+ Debug.Assert(encoderFallback != null, "[GB18030Encoding.GetBytes]Attempting to use null encoder fallback");
// Get any left over characters
char charLeftOver = (char)0;
@@ -289,7 +281,7 @@ namespace System.Text
// Have to check for charLeftOver
if (charLeftOver != 0)
{
- Contract.Assert(Char.IsHighSurrogate(charLeftOver),
+ Debug.Assert(Char.IsHighSurrogate(charLeftOver),
"[GB18030Encoding.GetBytes] leftover character should be high surrogate, not 0x" + ((int)charLeftOver).ToString("X4", CultureInfo.InvariantCulture));
// If our next char isn't a low surrogate, then we need to do fallback.
@@ -319,7 +311,7 @@ namespace System.Text
offset /= 0x7e;
byte byte2 = (byte)((offset % 0x0a) + 0x30);
offset /= 0x0a;
- Contract.Assert(offset < 0x6f,
+ Debug.Assert(offset < 0x6f,
"[GB18030Encoding.GetBytes](1) Expected offset < 0x6f, not 0x" + offset.ToString("X2", CultureInfo.InvariantCulture));
charLeftOver = (char)0;
@@ -369,7 +361,7 @@ namespace System.Text
iBytes /= 0x7e;
byte byte2 = (byte)((iBytes % 0x0a) + 0x30);
iBytes /= 0x0a;
- Contract.Assert(iBytes < 0x7e,
+ Debug.Assert(iBytes < 0x7e,
"[GB18030Encoding.GetBytes]Expected iBytes < 0x7e, not 0x" + iBytes.ToString("X2", CultureInfo.InvariantCulture));
if (!buffer.AddByte((byte)(iBytes + 0x81), byte2, byte3, byte4))
break;
@@ -436,23 +428,21 @@ namespace System.Text
}
// This is internal and called by something else,
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS baseDecoder)
{
// Just call GetChars() with null chars to count
return GetChars(bytes, count, null, 0, baseDecoder);
}
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetChars(byte* bytes, int byteCount,
char* chars, int charCount, DecoderNLS baseDecoder)
{
// Just need to ASSERT, this is called by something else internal that checked parameters already
// We'll allow null chars as a count
- Contract.Assert(bytes != null, "[GB18030Encoding.GetChars]bytes is null");
- Contract.Assert(byteCount >= 0, "[GB18030Encoding.GetChars]byteCount is negative");
-// Contract.Assert(chars != null, "[GB18030Encoding.GetChars]chars is null");
- Contract.Assert(charCount >= 0, "[GB18030Encoding.GetChars]charCount is negative");
+ Debug.Assert(bytes != null, "[GB18030Encoding.GetChars]bytes is null");
+ Debug.Assert(byteCount >= 0, "[GB18030Encoding.GetChars]byteCount is negative");
+// Debug.Assert(chars != null, "[GB18030Encoding.GetChars]chars is null");
+ Debug.Assert(charCount >= 0, "[GB18030Encoding.GetChars]charCount is negative");
// Fix our decoder
GB18030Decoder decoder = (GB18030Decoder)baseDecoder;
@@ -793,7 +783,7 @@ namespace System.Text
public override int GetMaxByteCount(int charCount)
{
if (charCount < 0)
- throw new ArgumentOutOfRangeException("charCount",
+ throw new ArgumentOutOfRangeException(nameof(charCount),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -807,7 +797,7 @@ namespace System.Text
byteCount *= 4;
if (byteCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException("charCount", Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
+ throw new ArgumentOutOfRangeException(nameof(charCount), Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
return (int)byteCount;
}
@@ -815,7 +805,7 @@ namespace System.Text
public override int GetMaxCharCount(int byteCount)
{
if (byteCount < 0)
- throw new ArgumentOutOfRangeException("byteCount",
+ throw new ArgumentOutOfRangeException(nameof(byteCount),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -828,7 +818,7 @@ namespace System.Text
charCount *= DecoderFallback.MaxCharCount;
if (charCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException("byteCount", Environment.GetResourceString("ArgumentOutOfRange_GetCharCountOverflow"));
+ throw new ArgumentOutOfRangeException(nameof(byteCount), Environment.GetResourceString("ArgumentOutOfRange_GetCharCountOverflow"));
return (int)charCount;
}
@@ -852,11 +842,10 @@ namespace System.Text
}
// Constructor called by serialization, have to handle deserializing from Everett
- [System.Security.SecurityCritical] // auto-generated
internal GB18030Decoder(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException("info");
+ if (info==null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
try
@@ -879,11 +868,10 @@ namespace System.Text
}
// ISerializable implementation, get data for this object
- [System.Security.SecurityCritical] // auto-generated_required
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException("info");
+ if (info==null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// Save Whidbey data
diff --git a/src/mscorlib/src/System/Text/ISCIIEncoding.cs b/src/mscorlib/src/System/Text/ISCIIEncoding.cs
index 89d9c9953a..751b8217c0 100644
--- a/src/mscorlib/src/System/Text/ISCIIEncoding.cs
+++ b/src/mscorlib/src/System/Text/ISCIIEncoding.cs
@@ -9,6 +9,7 @@
namespace System.Text
{
using System;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Globalization;
using System.Runtime.Serialization;
@@ -72,13 +73,13 @@ namespace System.Text
defaultCodePage = codePage - 57000;
// Legal windows code pages are between Devanagari and Punjabi
- Contract.Assert(defaultCodePage >= CodeDevanagari && defaultCodePage <= CodePunjabi,
+ Debug.Assert(defaultCodePage >= CodeDevanagari && defaultCodePage <= CodePunjabi,
"[ISCIIEncoding] Code page (" + codePage + " isn't supported by ISCIIEncoding!");
// This shouldn't really be possible
if (defaultCodePage < CodeDevanagari || defaultCodePage > CodePunjabi)
throw new ArgumentException(Environment.GetResourceString(
- "Argument_CodepageNotSupported", codePage), "codePage");
+ "Argument_CodepageNotSupported", codePage), nameof(codePage));
}
// Constructor called by serialization.
@@ -86,17 +87,16 @@ namespace System.Text
{
// Actually this can't ever get called, MLangCodePageEncoding is our proxy
// (In Everett this was done by MLang)
- Contract.Assert(false, "Didn't expect to make it to ISCIIEncoding serialization constructor");
+ Debug.Assert(false, "Didn't expect to make it to ISCIIEncoding serialization constructor");
throw new ArgumentException(Environment.GetResourceString("Arg_ExecutionEngineException"));
}
// ISerializable implementation
- [System.Security.SecurityCritical] // auto-generated_required
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
// Make sure to get the base stuff too This throws if info is null
SerializeEncoding(info, context);
- Contract.Assert(info!=null, "[ISCIIEncoding.GetObjectData] Expected null info to throw");
+ Debug.Assert(info!=null, "[ISCIIEncoding.GetObjectData] Expected null info to throw");
// Just need Everett MLangCodePageEncoding maxCharSize
info.AddValue("m_maxByteSize", 2);
@@ -111,7 +111,7 @@ namespace System.Text
public override int GetMaxByteCount(int charCount)
{
if (charCount < 0)
- throw new ArgumentOutOfRangeException("charCount",
+ throw new ArgumentOutOfRangeException(nameof(charCount),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -125,7 +125,7 @@ namespace System.Text
byteCount *= 4;
if (byteCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException("charCount", Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
+ throw new ArgumentOutOfRangeException(nameof(charCount), Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
return (int)byteCount;
}
@@ -135,7 +135,7 @@ namespace System.Text
public override int GetMaxCharCount(int byteCount)
{
if (byteCount < 0)
- throw new ArgumentOutOfRangeException("byteCount",
+ throw new ArgumentOutOfRangeException(nameof(byteCount),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -149,13 +149,12 @@ namespace System.Text
charCount *= DecoderFallback.MaxCharCount;
if (charCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException("byteCount", Environment.GetResourceString("ArgumentOutOfRange_GetCharCountOverflow"));
+ throw new ArgumentOutOfRangeException(nameof(byteCount), Environment.GetResourceString("ArgumentOutOfRange_GetCharCountOverflow"));
return (int)charCount;
}
// Our workhorse version
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetByteCount(char* chars, int count, EncoderNLS baseEncoder)
{
// Use null pointer to ask GetBytes for count
@@ -163,15 +162,14 @@ namespace System.Text
}
// Workhorse
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetBytes(char *chars, int charCount,
byte* bytes, int byteCount, EncoderNLS baseEncoder)
{
// Allow null bytes for counting
- Contract.Assert(chars != null, "[ISCIIEncoding.GetBytes]chars!=null");
-// Contract.Assert(bytes != null, "[ISCIIEncoding.GetBytes]bytes!=null");
- Contract.Assert(charCount >=0, "[ISCIIEncoding.GetBytes]charCount >=0");
- Contract.Assert(byteCount >=0, "[ISCIIEncoding.GetBytes]byteCount >=0");
+ Debug.Assert(chars != null, "[ISCIIEncoding.GetBytes]chars!=null");
+// Debug.Assert(bytes != null, "[ISCIIEncoding.GetBytes]bytes!=null");
+ Debug.Assert(charCount >=0, "[ISCIIEncoding.GetBytes]charCount >=0");
+ Debug.Assert(byteCount >=0, "[ISCIIEncoding.GetBytes]byteCount >=0");
// Need the ISCII Encoder
ISCIIEncoder encoder = (ISCIIEncoder) baseEncoder;
@@ -268,7 +266,7 @@ namespace System.Text
// See if our code page ("font" in ISCII spec) has to change
// (This if doesn't add character, just changes character set)
- Contract.Assert(indicScript!=0, "[ISCIIEncoding.GetBytes]expected an indic script value");
+ Debug.Assert(indicScript!=0, "[ISCIIEncoding.GetBytes]expected an indic script value");
if (indicScript != currentCodePage)
{
// It changed, spit out the ATR
@@ -279,7 +277,7 @@ namespace System.Text
currentCodePage = indicScript;
// We only know how to map from Unicode to pages from Devanagari to Punjabi (2 to 11)
- Contract.Assert(currentCodePage >= CodeDevanagari && currentCodePage <= CodePunjabi,
+ Debug.Assert(currentCodePage >= CodeDevanagari && currentCodePage <= CodePunjabi,
"[ISCIIEncoding.GetBytes]Code page (" + currentCodePage + " shouldn't appear in ISCII from Unicode table!");
}
@@ -294,7 +292,7 @@ namespace System.Text
if (indicTwoBytes != 0)
{
// This one needs another byte
- Contract.Assert((indicTwoBytes >> 12) > 0 && (indicTwoBytes >> 12) <= 3,
+ Debug.Assert((indicTwoBytes >> 12) > 0 && (indicTwoBytes >> 12) <= 3,
"[ISCIIEncoding.GetBytes]Expected indicTwoBytes from 1-3, not " + (indicTwoBytes >> 12));
// Already did buffer checking, but...
@@ -341,7 +339,6 @@ namespace System.Text
}
// Workhorse
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS baseDecoder)
{
// Just call GetChars with null chars saying we want count
@@ -354,16 +351,15 @@ namespace System.Text
// Devenagari F0, B8 -> \u0952
// Devenagari F0, BF -> \u0970
// Some characters followed by E9 become a different character instead.
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetChars(byte* bytes, int byteCount,
char* chars, int charCount, DecoderNLS baseDecoder)
{
// Just need to ASSERT, this is called by something else internal that checked parameters already
// Allow null chars for counting
- Contract.Assert(bytes != null, "[ISCIIEncoding.GetChars]bytes is null");
- Contract.Assert(byteCount >= 0, "[ISCIIEncoding.GetChars]byteCount is negative");
-// Contract.Assert(chars != null, "[ISCIIEncoding.GetChars]chars is null");
- Contract.Assert(charCount >= 0, "[ISCIIEncoding.GetChars]charCount is negative");
+ Debug.Assert(bytes != null, "[ISCIIEncoding.GetChars]bytes is null");
+ Debug.Assert(byteCount >= 0, "[ISCIIEncoding.GetChars]byteCount is negative");
+// Debug.Assert(chars != null, "[ISCIIEncoding.GetChars]chars is null");
+ Debug.Assert(charCount >= 0, "[ISCIIEncoding.GetChars]charCount is negative");
// Need the ISCII Decoder
ISCIIDecoder decoder = (ISCIIDecoder) baseDecoder;
@@ -395,7 +391,7 @@ namespace System.Text
// Get our current code page index (some code pages are dups)
int currentCodePageIndex = -1;
- Contract.Assert(currentCodePage >= CodeDevanagari && currentCodePage <= CodePunjabi,
+ Debug.Assert(currentCodePage >= CodeDevanagari && currentCodePage <= CodePunjabi,
"[ISCIIEncoding.GetChars]Decoder code page must be >= Devanagari and <= Punjabi, not " + currentCodePage);
if (currentCodePage >= CodeDevanagari && currentCodePage <= CodePunjabi)
@@ -415,7 +411,7 @@ namespace System.Text
bLastSpecial = false;
// One and only one of our flags should be set
- Contract.Assert(((bLastVirama ? 1 : 0) + (bLastATR ? 1 : 0) +
+ Debug.Assert(((bLastVirama ? 1 : 0) + (bLastATR ? 1 : 0) +
(bLastDevenagariStressAbbr ? 1 : 0) +
((cLastCharForNextNukta > 0) ? 1 : 0)) == 1,
String.Format(CultureInfo.InvariantCulture,
@@ -476,10 +472,10 @@ namespace System.Text
bLastATR = false;
// we know we can't have any of these other modes
- Contract.Assert(bLastVirama == false, "[ISCIIEncoding.GetChars] Expected no bLastVirama in bLastATR mode");
- Contract.Assert(bLastDevenagariStressAbbr == false, "[ISCIIEncoding.GetChars] Expected no bLastDevenagariStressAbbr in bLastATR mode");
- Contract.Assert(cLastCharForNextNukta == (char)0, "[ISCIIEncoding.GetChars] Expected no cLastCharForNextNukta in bLastATR mode");
- Contract.Assert(cLastCharForNoNextNukta == (char)0, "[ISCIIEncoding.GetChars] Expected no cLastCharForNoNextNukta in bLastATR mode");
+ Debug.Assert(bLastVirama == false, "[ISCIIEncoding.GetChars] Expected no bLastVirama in bLastATR mode");
+ Debug.Assert(bLastDevenagariStressAbbr == false, "[ISCIIEncoding.GetChars] Expected no bLastDevenagariStressAbbr in bLastATR mode");
+ Debug.Assert(cLastCharForNextNukta == (char)0, "[ISCIIEncoding.GetChars] Expected no cLastCharForNextNukta in bLastATR mode");
+ Debug.Assert(cLastCharForNoNextNukta == (char)0, "[ISCIIEncoding.GetChars] Expected no cLastCharForNoNextNukta in bLastATR mode");
// Keep processing this byte
}
@@ -508,10 +504,10 @@ namespace System.Text
bLastVirama = false;
// We know we can't have any of these other modes
- Contract.Assert(bLastATR == false, "[ISCIIEncoding.GetChars] Expected no bLastATR in bLastVirama mode");
- Contract.Assert(bLastDevenagariStressAbbr == false, "[ISCIIEncoding.GetChars] Expected no bLastDevenagariStressAbbr in bLastVirama mode");
- Contract.Assert(cLastCharForNextNukta == (char)0, "[ISCIIEncoding.GetChars] Expected no cLastCharForNextNukta in bLastVirama mode");
- Contract.Assert(cLastCharForNoNextNukta == (char)0, "[ISCIIEncoding.GetChars] Expected no cLastCharForNoNextNukta in bLastVirama mode");
+ Debug.Assert(bLastATR == false, "[ISCIIEncoding.GetChars] Expected no bLastATR in bLastVirama mode");
+ Debug.Assert(bLastDevenagariStressAbbr == false, "[ISCIIEncoding.GetChars] Expected no bLastDevenagariStressAbbr in bLastVirama mode");
+ Debug.Assert(cLastCharForNextNukta == (char)0, "[ISCIIEncoding.GetChars] Expected no cLastCharForNextNukta in bLastVirama mode");
+ Debug.Assert(cLastCharForNoNextNukta == (char)0, "[ISCIIEncoding.GetChars] Expected no cLastCharForNoNextNukta in bLastVirama mode");
}
else if (bLastDevenagariStressAbbr)
{
@@ -544,15 +540,15 @@ namespace System.Text
// (last character was added when mode was set)
bLastDevenagariStressAbbr = false;
- Contract.Assert(bLastATR == false, "[ISCIIEncoding.GetChars] Expected no bLastATR in bLastDevenagariStressAbbr mode");
- Contract.Assert(bLastVirama == false, "[ISCIIEncoding.GetChars] Expected no bLastVirama in bLastDevenagariStressAbbr mode");
- Contract.Assert(cLastCharForNextNukta == (char)0, "[ISCIIEncoding.GetChars] Expected no cLastCharForNextNukta in bLastDevenagariStressAbbr mode");
- Contract.Assert(cLastCharForNoNextNukta == (char)0, "[ISCIIEncoding.GetChars] Expected no cLastCharForNoNextNukta in bLastDevenagariStressAbbr mode");
+ Debug.Assert(bLastATR == false, "[ISCIIEncoding.GetChars] Expected no bLastATR in bLastDevenagariStressAbbr mode");
+ Debug.Assert(bLastVirama == false, "[ISCIIEncoding.GetChars] Expected no bLastVirama in bLastDevenagariStressAbbr mode");
+ Debug.Assert(cLastCharForNextNukta == (char)0, "[ISCIIEncoding.GetChars] Expected no cLastCharForNextNukta in bLastDevenagariStressAbbr mode");
+ Debug.Assert(cLastCharForNoNextNukta == (char)0, "[ISCIIEncoding.GetChars] Expected no cLastCharForNoNextNukta in bLastDevenagariStressAbbr mode");
}
else
{
// We were checking for next char being a nukta
- Contract.Assert(cLastCharForNextNukta > 0 && cLastCharForNoNextNukta > 0,
+ Debug.Assert(cLastCharForNextNukta > 0 && cLastCharForNoNextNukta > 0,
"[ISCIIEncoding.GetChars]No other special case found, but cLastCharFor(No)NextNukta variable(s) aren't set.");
// We'll either add combined char or last char
@@ -574,14 +570,14 @@ namespace System.Text
// Keep processing this byte, turn off mode.
cLastCharForNextNukta = cLastCharForNoNextNukta = '\0';
- Contract.Assert(bLastATR == false, "[ISCIIEncoding.GetChars] Expected no bLastATR in cLastCharForNextNukta mode");
- Contract.Assert(bLastVirama == false, "[ISCIIEncoding.GetChars] Expected no bLastVirama in cLastCharForNextNukta mode");
- Contract.Assert(bLastDevenagariStressAbbr == false, "[ISCIIEncoding.GetChars] Expected no bLastDevenagariStressAbbr in cLastCharForNextNukta mode");
+ Debug.Assert(bLastATR == false, "[ISCIIEncoding.GetChars] Expected no bLastATR in cLastCharForNextNukta mode");
+ Debug.Assert(bLastVirama == false, "[ISCIIEncoding.GetChars] Expected no bLastVirama in cLastCharForNextNukta mode");
+ Debug.Assert(bLastDevenagariStressAbbr == false, "[ISCIIEncoding.GetChars] Expected no bLastDevenagariStressAbbr in cLastCharForNextNukta mode");
}
}
// Now bLastSpecial should be false and all flags false.
- Contract.Assert (!bLastSpecial && !bLastDevenagariStressAbbr && !bLastVirama && !bLastATR &&
+ Debug.Assert (!bLastSpecial && !bLastDevenagariStressAbbr && !bLastVirama && !bLastATR &&
cLastCharForNextNukta == '\0',
"[ISCIIEncoding.GetChars]No special state for last code point should exist at this point.");
@@ -600,7 +596,7 @@ namespace System.Text
continue;
}
- Contract.Assert (currentCodePageIndex != -1, "[ISCIIEncoding.GetChars]Expected valid currentCodePageIndex != -1");
+ Debug.Assert (currentCodePageIndex != -1, "[ISCIIEncoding.GetChars]Expected valid currentCodePageIndex != -1");
char ch = IndicMapping[currentCodePageIndex, 0, b - MultiByteBegin];
char cAlt = IndicMapping[currentCodePageIndex, 1, b - MultiByteBegin];
@@ -646,7 +642,7 @@ namespace System.Text
}
// We must be the Devenagari special case for F0, B8 & F0, BF
- Contract.Assert(currentCodePage == CodeDevanagari && b == DevenagariExt,
+ Debug.Assert(currentCodePage == CodeDevanagari && b == DevenagariExt,
String.Format(CultureInfo.InvariantCulture,
"[ISCIIEncoding.GetChars] Devenagari special case must {0} not {1} or in Devanagari code page {2} not {3}.",
DevenagariExt, b, CodeDevanagari, currentCodePage));
@@ -701,7 +697,7 @@ namespace System.Text
cLastCharForNoNextNukta != '\0' || bLastATR || bLastDevenagariStressAbbr)
{
// Either not flushing or had state (from convert)
- Contract.Assert(!decoder.MustFlush || !decoder.m_throwOnOverflow,
+ Debug.Assert(!decoder.MustFlush || !decoder.m_throwOnOverflow,
"[ISCIIEncoding.GetChars]Expected no state or not converting or not flushing");
decoder.currentCodePage = currentCodePage;
decoder.bLastVirama = bLastVirama;
diff --git a/src/mscorlib/src/System/Text/ISO2022Encoding.cs b/src/mscorlib/src/System/Text/ISO2022Encoding.cs
index fe57e7cc57..fca579fe56 100644
--- a/src/mscorlib/src/System/Text/ISO2022Encoding.cs
+++ b/src/mscorlib/src/System/Text/ISO2022Encoding.cs
@@ -28,6 +28,7 @@
namespace System.Text
{
using System.Globalization;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Text;
using System.Runtime.InteropServices;
@@ -53,7 +54,6 @@ namespace System.Text
// We have to load the 936 code page tables, so impersonate 936 as our base
// This pretends to be other code pages as far as memory sections are concerned.
- [System.Security.SecurityCritical] // auto-generated
internal ISO2022Encoding(int codePage) : base(codePage, tableBaseCodePages[codePage % 10])
{
this.m_bUseMlangTypeForSerialization = true;
@@ -61,11 +61,10 @@ namespace System.Text
// Constructor called by serialization.
// Note: We use the base GetObjectData however
- [System.Security.SecurityCritical] // auto-generated
internal ISO2022Encoding(SerializationInfo info, StreamingContext context) : base(info, context)
{
// Actually this can't ever get called, CodePageEncoding is our proxy
- Contract.Assert(false, "Didn't expect to make it to DBCSCodePageEncoding serialization constructor");
+ Debug.Assert(false, "Didn't expect to make it to DBCSCodePageEncoding serialization constructor");
throw new ArgumentException(Environment.GetResourceString("Arg_ExecutionEngineException"));
}
@@ -102,7 +101,6 @@ namespace System.Text
ModeNOOP = -3
}
- [System.Security.SecurityCritical] // auto-generated
protected unsafe override String GetMemorySectionName()
{
int iUseCodePage = this.bFlagDataTable ? dataTableCodePage : CodePage;
@@ -123,7 +121,7 @@ namespace System.Text
strFormat = "CodePage_{0}_{1}_{2}_{3}_{4}_HZ";
break;
default:
- Contract.Assert(false, "[ISO2022Encoding.GetMemorySectionName] Don't expect to get here for code page " + this.CodePage);
+ Debug.Assert(false, "[ISO2022Encoding.GetMemorySectionName] Don't expect to get here for code page " + this.CodePage);
strFormat = "CodePage_{0}_{1}_{2}_{3}_{4}";
break;
}
@@ -263,28 +261,26 @@ namespace System.Text
}
// GetByteCount
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetByteCount(char* chars, int count, EncoderNLS baseEncoder)
{
// Just need to ASSERT, this is called by something else internal that checked parameters already
- Contract.Assert(count >= 0, "[ISO2022Encoding.GetByteCount]count is negative");
- Contract.Assert(chars != null, "[ISO2022Encoding.GetByteCount]chars is null");
+ Debug.Assert(count >= 0, "[ISO2022Encoding.GetByteCount]count is negative");
+ Debug.Assert(chars != null, "[ISO2022Encoding.GetByteCount]chars is null");
// Just call GetBytes with null byte* to get count
return GetBytes(chars, count, null, 0, baseEncoder);
}
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetBytes(char* chars, int charCount,
byte* bytes, int byteCount, EncoderNLS baseEncoder)
{
// Just need to ASSERT, this is called by something else internal that checked parameters already
- Contract.Assert(chars != null, "[ISO2022Encoding.GetBytes]chars is null");
- Contract.Assert(byteCount >= 0, "[ISO2022Encoding.GetBytes]byteCount is negative");
- Contract.Assert(charCount >= 0, "[ISO2022Encoding.GetBytes]charCount is negative");
+ Debug.Assert(chars != null, "[ISO2022Encoding.GetBytes]chars is null");
+ Debug.Assert(byteCount >= 0, "[ISO2022Encoding.GetBytes]byteCount is negative");
+ Debug.Assert(charCount >= 0, "[ISO2022Encoding.GetBytes]charCount is negative");
// Assert because we shouldn't be able to have a null encoder.
- Contract.Assert(encoderFallback != null, "[ISO2022Encoding.GetBytes]Attempting to use null encoder fallback");
+ Debug.Assert(encoderFallback != null, "[ISO2022Encoding.GetBytes]Attempting to use null encoder fallback");
// Fix our encoder
ISO2022Encoder encoder = (ISO2022Encoder)baseEncoder;
@@ -316,25 +312,23 @@ namespace System.Text
}
// This is internal and called by something else,
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS baseDecoder)
{
// Just assert, we're called internally so these should be safe, checked already
- Contract.Assert(bytes != null, "[ISO2022Encoding.GetCharCount]bytes is null");
- Contract.Assert(count >= 0, "[ISO2022Encoding.GetCharCount]byteCount is negative");
+ Debug.Assert(bytes != null, "[ISO2022Encoding.GetCharCount]bytes is null");
+ Debug.Assert(count >= 0, "[ISO2022Encoding.GetCharCount]byteCount is negative");
// Just call getChars with null char* to get count
return GetChars(bytes, count, null, 0, baseDecoder);
}
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetChars(byte* bytes, int byteCount,
char* chars, int charCount, DecoderNLS baseDecoder)
{
// Just need to ASSERT, this is called by something else internal that checked parameters already
- Contract.Assert(bytes != null, "[ISO2022Encoding.GetChars]bytes is null");
- Contract.Assert(byteCount >= 0, "[ISO2022Encoding.GetChars]byteCount is negative");
- Contract.Assert(charCount >= 0, "[ISO2022Encoding.GetChars]charCount is negative");
+ Debug.Assert(bytes != null, "[ISO2022Encoding.GetChars]bytes is null");
+ Debug.Assert(byteCount >= 0, "[ISO2022Encoding.GetChars]byteCount is negative");
+ Debug.Assert(charCount >= 0, "[ISO2022Encoding.GetChars]charCount is negative");
// Fix our decoder
ISO2022Decoder decoder = (ISO2022Decoder)baseDecoder;
@@ -358,7 +352,7 @@ namespace System.Text
iCount = GetCharsCP52936( bytes, byteCount, chars, charCount, decoder);
break;
default:
- Contract.Assert(false, "[ISO2022Encoding.GetChars] had unexpected code page");
+ Debug.Assert(false, "[ISO2022Encoding.GetChars] had unexpected code page");
break;
}
@@ -399,7 +393,6 @@ namespace System.Text
// undefined, so we maintain that behavior when decoding. We will never generate characters using
// that technique, but the decoder will process them.
//
- [System.Security.SecurityCritical] // auto-generated
private unsafe int GetBytesCP5022xJP(char* chars, int charCount,
byte* bytes, int byteCount, ISO2022Encoder encoder)
{
@@ -422,7 +415,7 @@ namespace System.Text
// We may have a left over character from last time, try and process it.
if (charLeftOver > 0)
{
- Contract.Assert(Char.IsHighSurrogate(charLeftOver), "[ISO2022Encoding.GetBytesCP5022xJP]leftover character should be high surrogate");
+ Debug.Assert(Char.IsHighSurrogate(charLeftOver), "[ISO2022Encoding.GetBytesCP5022xJP]leftover character should be high surrogate");
// It has to be a high surrogate, which we don't support, so it has to be a fallback
buffer.Fallback(charLeftOver);
@@ -483,7 +476,7 @@ namespace System.Text
else
{
// 50221 does halfwidth katakana by escape sequence
- Contract.Assert(CodePage == 50221, "[ISO2022Encoding.GetBytesCP5022xJP]Expected Code Page 50221");
+ Debug.Assert(CodePage == 50221, "[ISO2022Encoding.GetBytesCP5022xJP]Expected Code Page 50221");
// Add our escape sequence
if (!buffer.AddByte(ESCAPE, unchecked((byte)'('), unchecked((byte)'I')))
@@ -642,7 +635,6 @@ namespace System.Text
// Also Mlang always assumed KR mode, even if the designator wasn't found yet, so we do that as
// well. So basically we just ignore <ESC>$)C when decoding.
//
- [System.Security.SecurityCritical] // auto-generated
private unsafe int GetBytesCP50225KR(char* chars, int charCount,
byte* bytes, int byteCount, ISO2022Encoder encoder)
{
@@ -665,7 +657,7 @@ namespace System.Text
// We may have a l left over character from last time, try and process it.
if (charLeftOver > 0)
{
- Contract.Assert(Char.IsHighSurrogate(charLeftOver), "[ISO2022Encoding.GetBytesCP50225KR]leftover character should be high surrogate");
+ Debug.Assert(Char.IsHighSurrogate(charLeftOver), "[ISO2022Encoding.GetBytesCP50225KR]leftover character should be high surrogate");
// It has to be a high surrogate, which we don't support, so it has to be a fallback
buffer.Fallback(charLeftOver);
@@ -765,7 +757,7 @@ namespace System.Text
if (!encoder.MustFlush || encoder.charLeftOver != (char)0)
{
// We should be not flushing or converting
- Contract.Assert(!encoder.MustFlush || !encoder.m_throwOnOverflow,
+ Debug.Assert(!encoder.MustFlush || !encoder.m_throwOnOverflow,
"[ISO2022Encoding.GetBytesCP50225KR]Expected no left over data or not flushing or not converting");
encoder.shiftInOutMode = shiftOutMode;
}
@@ -793,7 +785,6 @@ namespace System.Text
//
// This encoding is designed for transmission by e-mail and news. No bytes should have high bit set.
// (all bytes <= 0x7f)
- [System.Security.SecurityCritical] // auto-generated
private unsafe int GetBytesCP52936(char* chars, int charCount,
byte* bytes, int byteCount, ISO2022Encoder encoder)
{
@@ -813,7 +804,7 @@ namespace System.Text
// We may have a left over character from last time, try and process it.
if (charLeftOver > 0)
{
- Contract.Assert(Char.IsHighSurrogate(charLeftOver), "[ISO2022Encoding.GetBytesCP52936]leftover character should be high surrogate");
+ Debug.Assert(Char.IsHighSurrogate(charLeftOver), "[ISO2022Encoding.GetBytesCP52936]leftover character should be high surrogate");
// It has to be a high surrogate, which we don't support, so it has to be a fallback
buffer.Fallback(charLeftOver);
@@ -928,7 +919,6 @@ namespace System.Text
return buffer.Count;
}
- [System.Security.SecurityCritical] // auto-generated
private unsafe int GetCharsCP5022xJP(byte* bytes, int byteCount,
char* chars, int charCount, ISO2022Decoder decoder)
{
@@ -1139,7 +1129,7 @@ namespace System.Text
if (!decoder.MustFlush || escapeCount != 0)
{
// Either not flushing or had state (from convert)
- Contract.Assert(!decoder.MustFlush || !decoder.m_throwOnOverflow,
+ Debug.Assert(!decoder.MustFlush || !decoder.m_throwOnOverflow,
"[ISO2022Encoding.GetCharsCP5022xJP]Expected no state or not converting or not flushing");
decoder.currentMode = currentMode;
@@ -1233,7 +1223,7 @@ namespace System.Text
private byte DecrementEscapeBytes(ref byte[] bytes, ref int count)
{
- Contract.Assert(count > 0, "[ISO2022Encoding.DecrementEscapeBytes]count > 0");
+ Debug.Assert(count > 0, "[ISO2022Encoding.DecrementEscapeBytes]count > 0");
// Decrement our count
count--;
@@ -1256,7 +1246,6 @@ namespace System.Text
// Note that in DBCS mode mlang passed through ' ', '\t' and '\n' as SBCS characters
// probably to allow mailer formatting without too much extra work.
- [System.Security.SecurityCritical] // auto-generated
private unsafe int GetCharsCP50225KR(byte* bytes, int byteCount,
char* chars, int charCount, ISO2022Decoder decoder)
{
@@ -1441,7 +1430,7 @@ namespace System.Text
if (!decoder.MustFlush || escapeCount != 0)
{
// Either not flushing or had state (from convert)
- Contract.Assert(!decoder.MustFlush || !decoder.m_throwOnOverflow,
+ Debug.Assert(!decoder.MustFlush || !decoder.m_throwOnOverflow,
"[ISO2022Encoding.GetCharsCP50225KR]Expected no state or not converting or not flushing");
decoder.currentMode = currentMode;
@@ -1496,12 +1485,11 @@ namespace System.Text
//
// This encoding is designed for transmission by e-mail and news. No bytes should have high bit set.
// (all bytes <= 0x7f)
- [System.Security.SecurityCritical] // auto-generated
private unsafe int GetCharsCP52936(byte* bytes, int byteCount,
char* chars, int charCount, ISO2022Decoder decoder)
{
- Contract.Assert(byteCount >=0, "[ISO2022Encoding.GetCharsCP52936]count >=0");
- Contract.Assert(bytes!=null, "[ISO2022Encoding.GetCharsCP52936]bytes!=null");
+ Debug.Assert(byteCount >=0, "[ISO2022Encoding.GetCharsCP52936]count >=0");
+ Debug.Assert(bytes!=null, "[ISO2022Encoding.GetCharsCP52936]bytes!=null");
// Get our info.
Encoding.EncodingCharBuffer buffer = new Encoding.EncodingCharBuffer(
@@ -1612,7 +1600,7 @@ namespace System.Text
if (currentMode != ISO2022Modes.ModeASCII)
{
// Should be ModeHZ
- Contract.Assert(currentMode == ISO2022Modes.ModeHZ, "[ISO2022Encoding.GetCharsCP52936]Expected ModeHZ");
+ Debug.Assert(currentMode == ISO2022Modes.ModeHZ, "[ISO2022Encoding.GetCharsCP52936]Expected ModeHZ");
char cm;
// Everett allowed characters < 0x20 to be passed as if they were ASCII
@@ -1737,7 +1725,7 @@ namespace System.Text
else
{
// Either not flushing or had state (from convert)
- Contract.Assert(!decoder.MustFlush || !decoder.m_throwOnOverflow,
+ Debug.Assert(!decoder.MustFlush || !decoder.m_throwOnOverflow,
"[ISO2022Encoding.GetCharsCP52936]Expected no state or not converting or not flushing");
decoder.currentMode = currentMode;
@@ -1754,7 +1742,7 @@ namespace System.Text
public override int GetMaxByteCount(int charCount)
{
if (charCount < 0)
- throw new ArgumentOutOfRangeException("charCount",
+ throw new ArgumentOutOfRangeException(nameof(charCount),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -1801,7 +1789,7 @@ namespace System.Text
byteCount += extraStart + extraEnd;
if (byteCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException("charCount", Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
+ throw new ArgumentOutOfRangeException(nameof(charCount), Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
return (int)byteCount;
}
@@ -1809,7 +1797,7 @@ namespace System.Text
public override int GetMaxCharCount(int byteCount)
{
if (byteCount < 0)
- throw new ArgumentOutOfRangeException("byteCount",
+ throw new ArgumentOutOfRangeException(nameof(byteCount),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -1839,7 +1827,7 @@ namespace System.Text
charCount *= DecoderFallback.MaxCharCount;
if (charCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException("byteCount", Environment.GetResourceString("ArgumentOutOfRange_GetCharCountOverflow"));
+ throw new ArgumentOutOfRangeException(nameof(byteCount), Environment.GetResourceString("ArgumentOutOfRange_GetCharCountOverflow"));
return (int)charCount;
}
diff --git a/src/mscorlib/src/System/Text/Latin1Encoding.cs b/src/mscorlib/src/System/Text/Latin1Encoding.cs
index a24f9c00ae..56a6c1f949 100644
--- a/src/mscorlib/src/System/Text/Latin1Encoding.cs
+++ b/src/mscorlib/src/System/Text/Latin1Encoding.cs
@@ -5,6 +5,7 @@
namespace System.Text
{
using System;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Globalization;
using System.Runtime.InteropServices;
@@ -43,12 +44,11 @@ namespace System.Text
}
// ISerializable implementation, serialize it as a CodePageEncoding
- [System.Security.SecurityCritical] // auto-generated_required
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
// Make sure to get the base stuff too This throws if info is null
SerializeEncoding(info, context);
- Contract.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);
@@ -61,15 +61,14 @@ namespace System.Text
// GetByteCount
// Note: We start by assuming that the output will be the same as count. Having
// an encoder or fallback may change that assumption
- [System.Security.SecurityCritical] // auto-generated
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
- Contract.Assert(charCount >= 0, "[Latin1Encoding.GetByteCount]count is negative");
- Contract.Assert(chars != null, "[Latin1Encoding.GetByteCount]chars is null");
+ Debug.Assert(charCount >= 0, "[Latin1Encoding.GetByteCount]count is negative");
+ Debug.Assert(chars != null, "[Latin1Encoding.GetByteCount]chars is null");
// Assert because we shouldn't be able to have a null encoder.
- Contract.Assert(encoderFallback != null, "[Latin1Encoding.GetByteCount]Attempting to use null fallback encoder");
+ Debug.Assert(encoderFallback != null, "[Latin1Encoding.GetByteCount]Attempting to use null fallback encoder");
char charLeftOver = (char)0;
@@ -79,13 +78,13 @@ namespace System.Text
if (encoder != null)
{
charLeftOver = encoder.charLeftOver;
- Contract.Assert(charLeftOver == 0 || Char.IsHighSurrogate(charLeftOver),
+ Debug.Assert(charLeftOver == 0 || Char.IsHighSurrogate(charLeftOver),
"[Latin1Encoding.GetByteCount]leftover character should be high surrogate");
fallback = encoder.Fallback as EncoderReplacementFallback;
// Verify that we have no fallbackbuffer, for Latin1 its always empty, so just assert
- Contract.Assert(!encoder.m_throwOnOverflow || !encoder.InternalHasFallbackBuffer ||
+ Debug.Assert(!encoder.m_throwOnOverflow || !encoder.InternalHasFallbackBuffer ||
encoder.FallbackBuffer.Remaining == 0,
"[Latin1CodePageEncoding.GetByteCount]Expected empty fallback buffer");
}
@@ -122,7 +121,7 @@ namespace System.Text
if (charLeftOver > 0)
{
// Initialize the buffer
- Contract.Assert(encoder != null,
+ Debug.Assert(encoder != null,
"[Latin1Encoding.GetByteCount]Expected encoder if we have charLeftOver");
fallbackBuffer = encoder.FallbackBuffer;
fallbackBuffer.InternalInitialize(chars, charEnd, encoder, false);
@@ -171,24 +170,23 @@ namespace System.Text
byteCount++;
}
- Contract.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
"[Latin1Encoding.GetByteCount]Expected Empty fallback buffer");
return byteCount;
}
- [System.Security.SecurityCritical] // auto-generated
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
- Contract.Assert(bytes != null, "[Latin1Encoding.GetBytes]bytes is null");
- Contract.Assert(byteCount >= 0, "[Latin1Encoding.GetBytes]byteCount is negative");
- Contract.Assert(chars != null, "[Latin1Encoding.GetBytes]chars is null");
- Contract.Assert(charCount >= 0, "[Latin1Encoding.GetBytes]charCount is negative");
+ Debug.Assert(bytes != null, "[Latin1Encoding.GetBytes]bytes is null");
+ Debug.Assert(byteCount >= 0, "[Latin1Encoding.GetBytes]byteCount is negative");
+ Debug.Assert(chars != null, "[Latin1Encoding.GetBytes]chars is null");
+ Debug.Assert(charCount >= 0, "[Latin1Encoding.GetBytes]charCount is negative");
// Assert because we shouldn't be able to have a null encoder.
- Contract.Assert(encoderFallback != null, "[Latin1Encoding.GetBytes]Attempting to use null encoder fallback");
+ Debug.Assert(encoderFallback != null, "[Latin1Encoding.GetBytes]Attempting to use null encoder fallback");
// Get any left over characters & check fast or slower fallback type
char charLeftOver = (char)0;
@@ -197,11 +195,11 @@ namespace System.Text
{
charLeftOver = encoder.charLeftOver;
fallback = encoder.Fallback as EncoderReplacementFallback;
- Contract.Assert(charLeftOver == 0 || Char.IsHighSurrogate(charLeftOver),
+ Debug.Assert(charLeftOver == 0 || Char.IsHighSurrogate(charLeftOver),
"[Latin1Encoding.GetBytes]leftover character should be high surrogate");
// Verify that we have no fallbackbuffer, for ASCII its always empty, so just assert
- Contract.Assert(!encoder.m_throwOnOverflow || !encoder.InternalHasFallbackBuffer ||
+ Debug.Assert(!encoder.m_throwOnOverflow || !encoder.InternalHasFallbackBuffer ||
encoder.FallbackBuffer.Remaining == 0,
"[Latin1CodePageEncoding.GetBytes]Expected empty fallback buffer");
}
@@ -284,7 +282,7 @@ namespace System.Text
{
// Since left over char was a surrogate, it'll have to be fallen back.
// Get Fallback
- Contract.Assert(encoder != null,
+ Debug.Assert(encoder != null,
"[Latin1Encoding.GetBytes]Expected encoder if we have charLeftOver");
fallbackBuffer = encoder.FallbackBuffer;
fallbackBuffer.InternalInitialize(chars, charEnd, encoder, true);
@@ -338,7 +336,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
- Contract.Assert(chars > charStart,
+ Debug.Assert(chars > charStart,
"[Latin1Encoding.GetBytes]Expected chars to have advanced (fallback case)");
chars--;
fallbackBuffer.InternalReset();
@@ -356,11 +354,11 @@ namespace System.Text
if (bytes >= byteEnd)
{
// didn't use this char, we'll throw or use buffer
- Contract.Assert(fallbackBuffer == null || fallbackBuffer.bFallingBack == false,
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.bFallingBack == false,
"[Latin1Encoding.GetBytes]Expected fallback to have throw initially if insufficient space");
if (fallbackBuffer == null || fallbackBuffer.bFallingBack == false)
{
- Contract.Assert(chars > charStart,
+ Debug.Assert(chars > charStart,
"[Latin1Encoding.GetBytes]Expected chars to have advanced (fallback case)");
chars--; // don't use last char
}
@@ -385,34 +383,32 @@ namespace System.Text
encoder.m_charsUsed = (int)(chars - charStart);
}
- Contract.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
"[Latin1Encoding.GetBytes]Expected Empty fallback buffer");
return (int)(bytes - byteStart);
}
// This is internal and called by something else,
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS decoder)
{
// Just assert, we're called internally so these should be safe, checked already
- Contract.Assert(bytes != null, "[Latin1Encoding.GetCharCount]bytes is null");
- Contract.Assert(count >= 0, "[Latin1Encoding.GetCharCount]byteCount is negative");
+ Debug.Assert(bytes != null, "[Latin1Encoding.GetCharCount]bytes is null");
+ Debug.Assert(count >= 0, "[Latin1Encoding.GetCharCount]byteCount is negative");
// Just return length, SBCS stay the same length because they don't map to surrogate
// pairs and we don't have to fallback because all latin1Encoding code points are unicode
return count;
}
- [System.Security.SecurityCritical] // auto-generated
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
- Contract.Assert(bytes != null, "[Latin1Encoding.GetChars]bytes is null");
- Contract.Assert(byteCount >= 0, "[Latin1Encoding.GetChars]byteCount is negative");
- Contract.Assert(chars != null, "[Latin1Encoding.GetChars]chars is null");
- Contract.Assert(charCount >= 0, "[Latin1Encoding.GetChars]charCount is negative");
+ Debug.Assert(bytes != null, "[Latin1Encoding.GetChars]bytes is null");
+ Debug.Assert(byteCount >= 0, "[Latin1Encoding.GetChars]byteCount is negative");
+ Debug.Assert(chars != null, "[Latin1Encoding.GetChars]chars is null");
+ Debug.Assert(charCount >= 0, "[Latin1Encoding.GetChars]charCount is negative");
// Need byteCount chars, otherwise too small buffer
if (charCount < byteCount)
@@ -446,7 +442,7 @@ namespace System.Text
public override int GetMaxByteCount(int charCount)
{
if (charCount < 0)
- throw new ArgumentOutOfRangeException("charCount",
+ throw new ArgumentOutOfRangeException(nameof(charCount),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -459,14 +455,14 @@ namespace System.Text
// 1 to 1 for most characters. Only surrogates with fallbacks have less.
if (byteCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException("charCount", Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
+ throw new ArgumentOutOfRangeException(nameof(charCount), Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
return (int)byteCount;
}
public override int GetMaxCharCount(int byteCount)
{
if (byteCount < 0)
- throw new ArgumentOutOfRangeException("byteCount",
+ throw new ArgumentOutOfRangeException(nameof(byteCount),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -478,7 +474,7 @@ namespace System.Text
charCount *= DecoderFallback.MaxCharCount;
if (charCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException("byteCount", Environment.GetResourceString("ArgumentOutOfRange_GetCharCountOverflow"));
+ throw new ArgumentOutOfRangeException(nameof(byteCount), Environment.GetResourceString("ArgumentOutOfRange_GetCharCountOverflow"));
return (int)charCount;
}
diff --git a/src/mscorlib/src/System/Text/MLangCodePageEncoding.cs b/src/mscorlib/src/System/Text/MLangCodePageEncoding.cs
index 53924a936d..a82db91b98 100644
--- a/src/mscorlib/src/System/Text/MLangCodePageEncoding.cs
+++ b/src/mscorlib/src/System/Text/MLangCodePageEncoding.cs
@@ -13,6 +13,7 @@ namespace System.Text
using System;
using System.Runtime.Serialization;
using System.Security.Permissions;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
/*=================================MLangCodePageEncoding==================================
@@ -46,7 +47,7 @@ namespace System.Text
internal MLangCodePageEncoding(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException("info");
+ if (info==null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// All versions have a code page
@@ -76,7 +77,6 @@ namespace System.Text
}
// Just get it from GetEncoding
- [System.Security.SecurityCritical] // auto-generated
public Object GetRealObject(StreamingContext context)
{
// Get our encoding (Note: This has default fallbacks for readonly and everett cases)
@@ -95,11 +95,10 @@ namespace System.Text
}
// ISerializable implementation
- [System.Security.SecurityCritical] // auto-generated_required
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
// We cannot ever call this.
- Contract.Assert(false, "Didn't expect to make it to MLangCodePageEncoding ISerializable.GetObjectData");
+ Debug.Assert(false, "Didn't expect to make it to MLangCodePageEncoding ISerializable.GetObjectData");
throw new ArgumentException(Environment.GetResourceString("Arg_ExecutionEngineException"));
}
@@ -115,25 +114,23 @@ namespace System.Text
internal MLangEncoder(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException("info");
+ if (info==null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
this.realEncoding = (Encoding)info.GetValue("m_encoding", typeof(Encoding));
}
// Just get it from GetEncoder
- [System.Security.SecurityCritical] // auto-generated
public Object GetRealObject(StreamingContext context)
{
return this.realEncoding.GetEncoder();
}
// ISerializable implementation, get data for this object
- [System.Security.SecurityCritical] // auto-generated_required
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
// We cannot ever call this.
- Contract.Assert(false, "Didn't expect to make it to MLangCodePageEncoding.MLangEncoder.GetObjectData");
+ Debug.Assert(false, "Didn't expect to make it to MLangCodePageEncoding.MLangEncoder.GetObjectData");
throw new ArgumentException(Environment.GetResourceString("Arg_ExecutionEngineException"));
}
}
@@ -151,25 +148,23 @@ namespace System.Text
internal MLangDecoder(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException("info");
+ if (info==null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
this.realEncoding = (Encoding)info.GetValue("m_encoding", typeof(Encoding));
}
// Just get it from GetDecoder
- [System.Security.SecurityCritical] // auto-generated
public Object GetRealObject(StreamingContext context)
{
return this.realEncoding.GetDecoder();
}
// ISerializable implementation, get data for this object
- [System.Security.SecurityCritical] // auto-generated_required
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
// We cannot ever call this.
- Contract.Assert(false, "Didn't expect to make it to MLangCodePageEncoding.MLangDecoder.GetObjectData");
+ Debug.Assert(false, "Didn't expect to make it to MLangCodePageEncoding.MLangDecoder.GetObjectData");
throw new ArgumentException(Environment.GetResourceString("Arg_ExecutionEngineException"));
}
}
diff --git a/src/mscorlib/src/System/Text/Normalization.Unix.cs b/src/mscorlib/src/System/Text/Normalization.Unix.cs
new file mode 100644
index 0000000000..d49bdc6c21
--- /dev/null
+++ b/src/mscorlib/src/System/Text/Normalization.Unix.cs
@@ -0,0 +1,123 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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.Text;
+
+namespace System.Text
+{
+ static partial class Normalization
+ {
+ public static bool IsNormalized(this string strInput, NormalizationForm normalizationForm)
+ {
+ ValidateArguments(strInput, normalizationForm);
+
+ int ret = Interop.GlobalizationInterop.IsNormalized(normalizationForm, strInput, strInput.Length);
+
+ if (ret == -1)
+ {
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"), nameof(strInput));
+ }
+
+ return ret == 1;
+ }
+
+ public static string Normalize(this string strInput, NormalizationForm normalizationForm)
+ {
+ ValidateArguments(strInput, normalizationForm);
+
+ char[] buf = new char[strInput.Length];
+
+ for (int attempts = 2; attempts > 0; attempts--)
+ {
+ int realLen = Interop.GlobalizationInterop.NormalizeString(normalizationForm, strInput, strInput.Length, buf, buf.Length);
+
+ if (realLen == -1)
+ {
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"), nameof(strInput));
+ }
+
+ if (realLen <= buf.Length)
+ {
+ return new string(buf, 0, realLen);
+ }
+
+ buf = new char[realLen];
+ }
+
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"), nameof(strInput));
+ }
+
+ // -----------------------------
+ // ---- PAL layer ends here ----
+ // -----------------------------
+
+ private static void ValidateArguments(string strInput, NormalizationForm normalizationForm)
+ {
+ if (strInput == null)
+ {
+ throw new ArgumentNullException(nameof(strInput));
+ }
+
+ if (normalizationForm != NormalizationForm.FormC && normalizationForm != NormalizationForm.FormD &&
+ normalizationForm != NormalizationForm.FormKC && normalizationForm != NormalizationForm.FormKD)
+ {
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidNormalizationForm"), nameof(normalizationForm));
+ }
+
+ if (HasInvalidUnicodeSequence(strInput))
+ {
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"), nameof(strInput));
+ }
+ }
+
+ /// <summary>
+ /// ICU does not signal an error during normalization if the input string has invalid unicode,
+ /// unlike Windows (which uses the ERROR_NO_UNICODE_TRANSLATION error value to signal an error).
+ ///
+ /// We walk the string ourselves looking for these bad sequences so we can continue to throw
+ /// ArgumentException in these cases.
+ /// </summary>
+ private static bool HasInvalidUnicodeSequence(string s)
+ {
+ for (int i = 0; i < s.Length; i++)
+ {
+ char c = s[i];
+
+ if (c < '\ud800')
+ {
+ continue;
+ }
+
+ if (c == '\uFFFE')
+ {
+ return true;
+ }
+
+ // If we see low surrogate before a high one, the string is invalid.
+ if (char.IsLowSurrogate(c))
+ {
+ return true;
+ }
+
+ if (char.IsHighSurrogate(c))
+ {
+ if (i + 1 >= s.Length || !char.IsLowSurrogate(s[i + 1]))
+ {
+ // A high surrogate at the end of the string or a high surrogate
+ // not followed by a low surrogate
+ return true;
+ }
+ else
+ {
+ i++; // consume the low surrogate.
+ continue;
+ }
+ }
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Text/Normalization.Windows.cs b/src/mscorlib/src/System/Text/Normalization.Windows.cs
new file mode 100644
index 0000000000..b2faf0db68
--- /dev/null
+++ b/src/mscorlib/src/System/Text/Normalization.Windows.cs
@@ -0,0 +1,286 @@
+// Licensed to the .NET Foundation under one or more 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.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
+ //
+#if !FEATURE_NORM_IDNA_ONLY
+ private static volatile bool NFC;
+ private static volatile bool NFD;
+ private static volatile bool NFKC;
+ private static volatile bool NFKD;
+#endif // !FEATURE_NORM_IDNA_ONLY
+ private static volatile bool IDNA;
+#if !FEATURE_NORM_IDNA_ONLY
+ private static volatile bool NFCDisallowUnassigned;
+ private static volatile bool NFDDisallowUnassigned;
+ private static volatile bool NFKCDisallowUnassigned;
+ private static volatile bool NFKDDisallowUnassigned;
+#endif // !FEATURE_NORM_IDNA_ONLY
+ 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)
+ {
+ byte* pTables = null;
+
+ // Normalization uses OS on Win8
+ if (!Environment.IsWindows8OrAbove)
+ {
+ 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"));
+ }
+ }
+
+ nativeNormalizationInitNormalization(form, pTables);
+ }
+
+ static private void EnsureInitialized(NormalizationForm form)
+ {
+ switch ((ExtendedNormalizationForms)form)
+ {
+#if !FEATURE_NORM_IDNA_ONLY
+ 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;
+#endif // !FEATURE_NORM_IDNA_ONLY
+
+ case ExtendedNormalizationForms.FormIdna:
+ if (IDNA) return;
+ InitializeForm(form, "normidna.nlp");
+ IDNA = true;
+ break;
+
+#if !FEATURE_NORM_IDNA_ONLY
+ case ExtendedNormalizationForms.FormCDisallowUnassigned:
+ if (NFCDisallowUnassigned) return;
+ InitializeForm(form, "normnfc.nlp");
+ NFCDisallowUnassigned = true;
+ break;
+
+ case ExtendedNormalizationForms.FormDDisallowUnassigned:
+ if (NFDDisallowUnassigned) return;
+ InitializeForm(form, "normnfd.nlp");
+ NFDDisallowUnassigned = true;
+ break;
+
+ case ExtendedNormalizationForms.FormKCDisallowUnassigned:
+ if (NFKCDisallowUnassigned) return;
+ InitializeForm(form, "normnfkc.nlp");
+ NFKCDisallowUnassigned = true;
+ break;
+
+ case ExtendedNormalizationForms.FormKDDisallowUnassigned:
+ if (NFKDDisallowUnassigned) return;
+ InitializeForm(form, "normnfkd.nlp");
+ NFKDDisallowUnassigned = true;
+ break;
+#endif // !FEATURE_NORM_IDNA_ONLY
+
+ case ExtendedNormalizationForms.FormIdnaDisallowUnassigned:
+ if (IDNADisallowUnassigned) return;
+ InitializeForm(form, "normidna.nlp");
+ IDNADisallowUnassigned = true;
+ break;
+
+ 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));
+ }
+
+ return result;
+ }
+
+ internal static String Normalize(String strInput, NormalizationForm normForm)
+ {
+ Contract.Requires(strInput != null);
+
+ EnsureInitialized(normForm);
+
+ int iError = ERROR_SUCCESS;
+
+ // Guess our buffer size first
+ int iLength = nativeNormalizationNormalizeString(normForm, ref iError, strInput, strInput.Length, null, 0);
+
+ // Could have an error (actually it'd be quite hard to have an error here)
+ if (iError != ERROR_SUCCESS)
+ {
+ if (iError == ERROR_INVALID_PARAMETER)
+ throw new ArgumentException(
+ Environment.GetResourceString("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"));
+
+ // Who knows what happened? Not us!
+ throw new InvalidOperationException(
+ Environment.GetResourceString("UnknownError_Num", iError));
+ }
+
+ // Don't break for empty strings (only possible for D & KD and not really possible at that)
+ if (iLength == 0) return String.Empty;
+
+ // Someplace to stick our buffer
+ char[] cBuffer = null;
+
+ for (;;)
+ {
+ // (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)
+ break;
+
+ // Could have an error (actually it'd be quite hard to have an error here)
+ switch(iError)
+ {
+ // Do appropriate stuff for the individual errors:
+ case ERROR_INSUFFICIENT_BUFFER:
+ Debug.Assert(iLength > cBuffer.Length, "Buffer overflow should have iLength > cBuffer.Length");
+ continue;
+
+ case ERROR_INVALID_PARAMETER:
+ case 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"));
+
+ default:
+ // We shouldn't get here...
+ throw new InvalidOperationException(
+ Environment.GetResourceString("UnknownError_Num", iError));
+ }
+ }
+
+ // Copy our buffer into our new string, which will be the appropriate size
+ 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
index ce3c0c8e32..e7e733a587 100644
--- a/src/mscorlib/src/System/Text/Normalization.cs
+++ b/src/mscorlib/src/System/Text/Normalization.cs
@@ -4,15 +4,6 @@
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.Contracts;
-
// This is the enumeration for Normalization Forms
[System.Runtime.InteropServices.ComVisible(true)]
public enum NormalizationForm
@@ -42,309 +33,4 @@ namespace System.Text
#endif // !FEATURE_NORM_IDNA_ONLY
FormIdnaDisallowUnassigned = 0x10d
}
-
- // This internal class wraps up our normalization behavior
-
- internal class Normalization
- {
- //
- // Flags that track whether given normalization form was initialized
- //
-#if !FEATURE_NORM_IDNA_ONLY
- private static volatile bool NFC;
- private static volatile bool NFD;
- private static volatile bool NFKC;
- private static volatile bool NFKD;
-#endif // !FEATURE_NORM_IDNA_ONLY
- private static volatile bool IDNA;
-#if !FEATURE_NORM_IDNA_ONLY
- private static volatile bool NFCDisallowUnassigned;
- private static volatile bool NFDDisallowUnassigned;
- private static volatile bool NFKCDisallowUnassigned;
- private static volatile bool NFKDDisallowUnassigned;
-#endif // !FEATURE_NORM_IDNA_ONLY
- 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;
-
- [System.Security.SecurityCritical] // auto-generated
- static private unsafe void InitializeForm(NormalizationForm form, String strDataFile)
- {
-#if FEATURE_COREFX_GLOBALIZATION
- //TODO: Implement this fully. We might need a PAL here.
- throw new NotImplementedException();
-#else
- byte* pTables = null;
-
- // Normalization uses OS on Win8
- if (!Environment.IsWindows8OrAbove)
- {
- 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"));
- }
- }
-
- nativeNormalizationInitNormalization(form, pTables);
-#endif
- }
-
- [System.Security.SecurityCritical] // auto-generated
- static private void EnsureInitialized(NormalizationForm form)
- {
- switch ((ExtendedNormalizationForms)form)
- {
-#if !FEATURE_NORM_IDNA_ONLY
- 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;
-#endif // !FEATURE_NORM_IDNA_ONLY
-
- case ExtendedNormalizationForms.FormIdna:
- if (IDNA) return;
- InitializeForm(form, "normidna.nlp");
- IDNA = true;
- break;
-
-#if !FEATURE_NORM_IDNA_ONLY
- case ExtendedNormalizationForms.FormCDisallowUnassigned:
- if (NFCDisallowUnassigned) return;
- InitializeForm(form, "normnfc.nlp");
- NFCDisallowUnassigned = true;
- break;
-
- case ExtendedNormalizationForms.FormDDisallowUnassigned:
- if (NFDDisallowUnassigned) return;
- InitializeForm(form, "normnfd.nlp");
- NFDDisallowUnassigned = true;
- break;
-
- case ExtendedNormalizationForms.FormKCDisallowUnassigned:
- if (NFKCDisallowUnassigned) return;
- InitializeForm(form, "normnfkc.nlp");
- NFKCDisallowUnassigned = true;
- break;
-
- case ExtendedNormalizationForms.FormKDDisallowUnassigned:
- if (NFKDDisallowUnassigned) return;
- InitializeForm(form, "normnfkd.nlp");
- NFKDDisallowUnassigned = true;
- break;
-#endif // !FEATURE_NORM_IDNA_ONLY
-
- case ExtendedNormalizationForms.FormIdnaDisallowUnassigned:
- if (IDNADisallowUnassigned) return;
- InitializeForm(form, "normidna.nlp");
- IDNADisallowUnassigned = true;
- break;
-
- default:
- if (Other) return;
- InitializeForm(form, null);
- Other = true;
- break;
- }
- }
-
- [System.Security.SecurityCritical]
- 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" ),
- "strInput");
- case ERROR_NOT_ENOUGH_MEMORY:
- throw new OutOfMemoryException(
- Environment.GetResourceString("Arg_OutOfMemoryException"));
- default:
- throw new InvalidOperationException(
- Environment.GetResourceString("UnknownError_Num", iError));
- }
-
- return result;
- }
-
- [System.Security.SecurityCritical]
- internal static String Normalize(String strInput, NormalizationForm normForm)
- {
- Contract.Requires(strInput != null);
-
- EnsureInitialized(normForm);
-
- int iError = ERROR_SUCCESS;
-
- // Guess our buffer size first
- int iLength = nativeNormalizationNormalizeString(normForm, ref iError, strInput, strInput.Length, null, 0);
-
- // Could have an error (actually it'd be quite hard to have an error here)
- if (iError != ERROR_SUCCESS)
- {
- if (iError == ERROR_INVALID_PARAMETER)
- throw new ArgumentException(
- Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex" ),
- "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"));
-
- // Who knows what happened? Not us!
- throw new InvalidOperationException(
- Environment.GetResourceString("UnknownError_Num", iError));
- }
-
- // Don't break for empty strings (only possible for D & KD and not really possible at that)
- if (iLength == 0) return String.Empty;
-
- // Someplace to stick our buffer
- char[] cBuffer = null;
-
- for (;;)
- {
- // (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)
- break;
-
- // Could have an error (actually it'd be quite hard to have an error here)
- switch(iError)
- {
- // Do appropriate stuff for the individual errors:
- case ERROR_INSUFFICIENT_BUFFER:
- Contract.Assert(iLength > cBuffer.Length, "Buffer overflow should have iLength > cBuffer.Length");
- continue;
-
- case ERROR_INVALID_PARAMETER:
- case ERROR_NO_UNICODE_TRANSLATION:
- // Illegal code point or order found. Ie: FFFE or D800 D800, etc.
- throw new ArgumentException(
- Environment.GetResourceString("Argument_InvalidCharSequence", iLength ),
- "strInput");
- case ERROR_NOT_ENOUGH_MEMORY:
- throw new OutOfMemoryException(
- Environment.GetResourceString("Arg_OutOfMemoryException"));
-
- default:
- // We shouldn't get here...
- throw new InvalidOperationException(
- Environment.GetResourceString("UnknownError_Num", iError));
- }
- }
-
- // Copy our buffer into our new string, which will be the appropriate size
- return new String(cBuffer, 0, iLength);
- }
-
-#if !FEATURE_COREFX_GLOBALIZATION
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- unsafe private static extern int nativeNormalizationNormalizeString(
- NormalizationForm normForm, ref int iError,
- String lpSrcString, int cwSrcLength,
- char[] lpDstString, int cwDstLength);
-
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- unsafe private static extern bool nativeNormalizationIsNormalizedString(
- NormalizationForm normForm, ref int iError,
- String lpString, int cwLength);
-
- [System.Security.SecurityCritical] // auto-generated
- [SuppressUnmanagedCodeSecurity]
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- unsafe private static extern void nativeNormalizationInitNormalization(
- NormalizationForm normForm, byte* pTableData);
-#else
- unsafe private static int nativeNormalizationNormalizeString(
- NormalizationForm normForm, ref int iError,
- String lpSrcString, int cwSrcLength,
- char[] lpDstString, int cwDstLength)
- {
- throw new NotImplementedException();
- }
-
- unsafe private static bool nativeNormalizationIsNormalizedString(
- NormalizationForm normForm, ref int iError,
- String lpString, int cwLength)
- {
- throw new NotImplementedException();
- }
-
- unsafe private static void nativeNormalizationInitNormalization(
- NormalizationForm normForm, byte* pTableData)
- {
- throw new NotImplementedException();
- }
-#endif
- }
}
diff --git a/src/mscorlib/src/System/Text/SBCSCodePageEncoding.cs b/src/mscorlib/src/System/Text/SBCSCodePageEncoding.cs
index ce611d8b1f..8b07149fb7 100644
--- a/src/mscorlib/src/System/Text/SBCSCodePageEncoding.cs
+++ b/src/mscorlib/src/System/Text/SBCSCodePageEncoding.cs
@@ -6,6 +6,7 @@
namespace System.Text
{
using System;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Text;
using System.Threading;
@@ -20,13 +21,10 @@ namespace System.Text
{
// Pointers to our memory section parts
[NonSerialized]
- [SecurityCritical]
unsafe char* mapBytesToUnicode = null; // char 256
[NonSerialized]
- [SecurityCritical]
unsafe byte* mapUnicodeToBytes = null; // byte 65536
[NonSerialized]
- [SecurityCritical]
unsafe int* mapCodePageCached = null; // to remember which CP is cached
const char UNKNOWN_CHAR=(char)0xFFFD;
@@ -37,23 +35,20 @@ namespace System.Text
[NonSerialized]
char charUnknown;
- [System.Security.SecurityCritical] // auto-generated
public SBCSCodePageEncoding(int codePage) : this(codePage, codePage)
{
}
- [System.Security.SecurityCritical] // auto-generated
internal SBCSCodePageEncoding(int codePage, int dataCodePage) : base(codePage, dataCodePage)
{
}
// Constructor called by serialization.
// Note: We use the base GetObjectData however
- [System.Security.SecurityCritical] // auto-generated
internal SBCSCodePageEncoding(SerializationInfo info, StreamingContext context) : base(0)
{
// Actually this can't ever get called, CodePageEncoding is our proxy
- Contract.Assert(false, "Didn't expect to make it to SBCSCodePageEncoding serialization constructor");
+ Debug.Assert(false, "Didn't expect to make it to SBCSCodePageEncoding serialization constructor");
throw new ArgumentNullException("this");
}
@@ -69,11 +64,10 @@ namespace System.Text
// byte < 0x20 means skip the next n positions. (Where n is the byte #)
// byte == 1 means that next word is another unicode code point #
// byte == 0 is unknown. (doesn't override initial WCHAR[256] table!
- [System.Security.SecurityCritical] // auto-generated
protected override unsafe void LoadManagedCodePage()
{
// Should be loading OUR code page
- Contract.Assert(pCodePage->CodePage == this.dataTableCodePage,
+ Debug.Assert(pCodePage->CodePage == this.dataTableCodePage,
"[SBCSCodePageEncoding.LoadManagedCodePage]Expected to load data table code page");
// Make sure we're really a 1 byte code page
@@ -96,7 +90,7 @@ namespace System.Text
// If its cached (& filled in) we don't have to do anything else
if (*mapCodePageCached != 0)
{
- Contract.Assert(*mapCodePageCached == this.dataTableCodePage,
+ Debug.Assert(*mapCodePageCached == this.dataTableCodePage,
"[DBCSCodePageEncoding.LoadManagedCodePage]Expected mapped section cached page to be same as data table code page. Cached : " +
*mapCodePageCached + " Expected:" + this.dataTableCodePage);
@@ -151,7 +145,6 @@ namespace System.Text
}
// Read in our best fit table
- [System.Security.SecurityCritical] // auto-generated
protected unsafe override void ReadBestFitTable()
{
// Lock so we don't confuse ourselves.
@@ -180,7 +173,7 @@ namespace System.Text
while ((byteTemp = *((ushort*)pData)) != 0)
{
- Contract.Assert(arrayTemp[byteTemp] == UNKNOWN_CHAR, String.Format(CultureInfo.InvariantCulture,
+ Debug.Assert(arrayTemp[byteTemp] == UNKNOWN_CHAR, String.Format(CultureInfo.InvariantCulture,
"[SBCSCodePageEncoding::ReadBestFitTable] Expected unallocated byte (not 0x{2:X2}) for best fit byte at 0x{0:X2} for code page {1}",
byteTemp, CodePage, (int)arrayTemp[byteTemp]));
pData += 2;
@@ -281,7 +274,7 @@ namespace System.Text
arrayTemp[iBestFitCount++] = mapBytesToUnicode[input];
// This won't work if it won't round trip.
- Contract.Assert(arrayTemp[iBestFitCount-1] != (char)0,
+ Debug.Assert(arrayTemp[iBestFitCount-1] != (char)0,
String.Format(CultureInfo.InvariantCulture,
"[SBCSCodePageEncoding.ReadBestFitTable] No valid Unicode value {0:X4} for round trip bytes {1:X4}, encoding {2}",
(int)mapBytesToUnicode[input], (int)input, CodePage));
@@ -299,15 +292,14 @@ namespace System.Text
// GetByteCount
// Note: We start by assuming that the output will be the same as count. Having
// an encoder or fallback may change that assumption
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetByteCount(char* chars, int count, EncoderNLS encoder)
{
// Just need to ASSERT, this is called by something else internal that checked parameters already
- Contract.Assert(count >= 0, "[SBCSCodePageEncoding.GetByteCount]count is negative");
- Contract.Assert(chars != null, "[SBCSCodePageEncoding.GetByteCount]chars is null");
+ Debug.Assert(count >= 0, "[SBCSCodePageEncoding.GetByteCount]count is negative");
+ Debug.Assert(chars != null, "[SBCSCodePageEncoding.GetByteCount]chars is null");
// Assert because we shouldn't be able to have a null encoder.
- Contract.Assert(encoderFallback != null, "[SBCSCodePageEncoding.GetByteCount]Attempting to use null fallback");
+ Debug.Assert(encoderFallback != null, "[SBCSCodePageEncoding.GetByteCount]Attempting to use null fallback");
CheckMemorySection();
@@ -319,12 +311,12 @@ namespace System.Text
if (encoder != null)
{
charLeftOver = encoder.charLeftOver;
- Contract.Assert(charLeftOver == 0 || Char.IsHighSurrogate(charLeftOver),
+ Debug.Assert(charLeftOver == 0 || Char.IsHighSurrogate(charLeftOver),
"[SBCSCodePageEncoding.GetByteCount]leftover character should be high surrogate");
fallback = encoder.Fallback as EncoderReplacementFallback;
// Verify that we have no fallbackbuffer, actually for SBCS this is always empty, so just assert
- Contract.Assert(!encoder.m_throwOnOverflow || !encoder.InternalHasFallbackBuffer ||
+ Debug.Assert(!encoder.m_throwOnOverflow || !encoder.InternalHasFallbackBuffer ||
encoder.FallbackBuffer.Remaining == 0,
"[SBCSCodePageEncoding.GetByteCount]Expected empty fallback buffer at start");
}
@@ -363,7 +355,7 @@ namespace System.Text
{
// Since left over char was a surrogate, it'll have to be fallen back.
// Get Fallback
- Contract.Assert(encoder != null, "[SBCSCodePageEncoding.GetByteCount]Expect to have encoder if we have a charLeftOver");
+ Debug.Assert(encoder != null, "[SBCSCodePageEncoding.GetByteCount]Expect to have encoder if we have a charLeftOver");
fallbackBuffer = encoder.FallbackBuffer;
fallbackBuffer.InternalInitialize(chars, charEnd, encoder, false);
@@ -414,24 +406,23 @@ namespace System.Text
byteCount++;
}
- Contract.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
"[SBCSEncoding.GetByteCount]Expected Empty fallback buffer at end");
return (int)byteCount;
}
- [System.Security.SecurityCritical] // auto-generated
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
- Contract.Assert(bytes != null, "[SBCSCodePageEncoding.GetBytes]bytes is null");
- Contract.Assert(byteCount >= 0, "[SBCSCodePageEncoding.GetBytes]byteCount is negative");
- Contract.Assert(chars != null, "[SBCSCodePageEncoding.GetBytes]chars is null");
- Contract.Assert(charCount >= 0, "[SBCSCodePageEncoding.GetBytes]charCount is negative");
+ Debug.Assert(bytes != null, "[SBCSCodePageEncoding.GetBytes]bytes is null");
+ Debug.Assert(byteCount >= 0, "[SBCSCodePageEncoding.GetBytes]byteCount is negative");
+ Debug.Assert(chars != null, "[SBCSCodePageEncoding.GetBytes]chars is null");
+ Debug.Assert(charCount >= 0, "[SBCSCodePageEncoding.GetBytes]charCount is negative");
// Assert because we shouldn't be able to have a null encoder.
- Contract.Assert(encoderFallback != null, "[SBCSCodePageEncoding.GetBytes]Attempting to use null encoder fallback");
+ Debug.Assert(encoderFallback != null, "[SBCSCodePageEncoding.GetBytes]Attempting to use null encoder fallback");
CheckMemorySection();
@@ -443,12 +434,12 @@ namespace System.Text
if (encoder != null)
{
charLeftOver = encoder.charLeftOver;
- Contract.Assert(charLeftOver == 0 || Char.IsHighSurrogate(charLeftOver),
+ Debug.Assert(charLeftOver == 0 || Char.IsHighSurrogate(charLeftOver),
"[SBCSCodePageEncoding.GetBytes]leftover character should be high surrogate");
fallback = encoder.Fallback as EncoderReplacementFallback;
// Verify that we have no fallbackbuffer, for SBCS its always empty, so just assert
- Contract.Assert(!encoder.m_throwOnOverflow || !encoder.InternalHasFallbackBuffer ||
+ Debug.Assert(!encoder.m_throwOnOverflow || !encoder.InternalHasFallbackBuffer ||
encoder.FallbackBuffer.Remaining == 0,
"[SBCSCodePageEncoding.GetBytes]Expected empty fallback buffer at start");
// if (encoder.m_throwOnOverflow && encoder.InternalHasFallbackBuffer &&
@@ -545,7 +536,7 @@ namespace System.Text
{
// Since left over char was a surrogate, it'll have to be fallen back.
// Get Fallback
- Contract.Assert(encoder != null, "[SBCSCodePageEncoding.GetBytes]Expect to have encoder if we have a charLeftOver");
+ Debug.Assert(encoder != null, "[SBCSCodePageEncoding.GetBytes]Expect to have encoder if we have a charLeftOver");
fallbackBuffer = encoder.FallbackBuffer;
fallbackBuffer.InternalInitialize(chars, charEnd, encoder, true);
@@ -598,7 +589,7 @@ namespace System.Text
if (fallbackBuffer.Remaining > byteEnd - bytes)
{
// Didn't use this char, reset it
- Contract.Assert(chars > charStart,
+ Debug.Assert(chars > charStart,
"[SBCSCodePageEncoding.GetBytes]Expected chars to have advanced (fallback)");
chars--;
fallbackBuffer.InternalReset();
@@ -615,11 +606,11 @@ namespace System.Text
if (bytes >= byteEnd)
{
// didn't use this char, we'll throw or use buffer
- Contract.Assert(fallbackBuffer == null || fallbackBuffer.bFallingBack == false,
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.bFallingBack == false,
"[SBCSCodePageEncoding.GetBytes]Expected to NOT be falling back");
if (fallbackBuffer == null || fallbackBuffer.bFallingBack == false)
{
- Contract.Assert(chars > charStart,
+ Debug.Assert(chars > charStart,
"[SBCSCodePageEncoding.GetBytes]Expected chars to have advanced (normal)");
chars--; // don't use last char
}
@@ -645,19 +636,18 @@ namespace System.Text
}
// Expect Empty fallback buffer for SBCS
- Contract.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
"[SBCSEncoding.GetBytes]Expected Empty fallback buffer at end");
return (int)(bytes - byteStart);
}
// This is internal and called by something else,
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS decoder)
{
// Just assert, we're called internally so these should be safe, checked already
- Contract.Assert(bytes != null, "[SBCSCodePageEncoding.GetCharCount]bytes is null");
- Contract.Assert(count >= 0, "[SBCSCodePageEncoding.GetCharCount]byteCount is negative");
+ Debug.Assert(bytes != null, "[SBCSCodePageEncoding.GetCharCount]bytes is null");
+ Debug.Assert(count >= 0, "[SBCSCodePageEncoding.GetCharCount]byteCount is negative");
CheckMemorySection();
@@ -676,7 +666,7 @@ namespace System.Text
{
fallback = decoder.Fallback as DecoderReplacementFallback;
bUseBestFit = decoder.Fallback.IsMicrosoftBestFitFallback;
- Contract.Assert(!decoder.m_throwOnOverflow || !decoder.InternalHasFallbackBuffer ||
+ Debug.Assert(!decoder.m_throwOnOverflow || !decoder.InternalHasFallbackBuffer ||
decoder.FallbackBuffer.Remaining == 0,
"[SBCSCodePageEncoding.GetChars]Expected empty fallback buffer at start");
}
@@ -729,22 +719,21 @@ namespace System.Text
}
// Fallback buffer must be empty
- Contract.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
"[SBCSEncoding.GetCharCount]Expected Empty fallback buffer at end");
// Converted sequence is same length as input
return charCount;
}
- [System.Security.SecurityCritical] // auto-generated
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
- Contract.Assert(bytes != null, "[SBCSCodePageEncoding.GetChars]bytes is null");
- Contract.Assert(byteCount >= 0, "[SBCSCodePageEncoding.GetChars]byteCount is negative");
- Contract.Assert(chars != null, "[SBCSCodePageEncoding.GetChars]chars is null");
- Contract.Assert(charCount >= 0, "[SBCSCodePageEncoding.GetChars]charCount is negative");
+ Debug.Assert(bytes != null, "[SBCSCodePageEncoding.GetChars]bytes is null");
+ Debug.Assert(byteCount >= 0, "[SBCSCodePageEncoding.GetChars]byteCount is negative");
+ Debug.Assert(chars != null, "[SBCSCodePageEncoding.GetChars]chars is null");
+ Debug.Assert(charCount >= 0, "[SBCSCodePageEncoding.GetChars]charCount is negative");
CheckMemorySection();
@@ -768,7 +757,7 @@ namespace System.Text
{
fallback = decoder.Fallback as DecoderReplacementFallback;
bUseBestFit = decoder.Fallback.IsMicrosoftBestFitFallback;
- Contract.Assert(!decoder.m_throwOnOverflow || !decoder.InternalHasFallbackBuffer ||
+ Debug.Assert(!decoder.m_throwOnOverflow || !decoder.InternalHasFallbackBuffer ||
decoder.FallbackBuffer.Remaining == 0,
"[SBCSCodePageEncoding.GetChars]Expected empty fallback buffer at start");
}
@@ -848,7 +837,7 @@ namespace System.Text
}
// Use fallback buffer
- Contract.Assert(bytes > byteStart,
+ Debug.Assert(bytes > byteStart,
"[SBCSCodePageEncoding.GetChars]Expected bytes to have advanced already (unknown byte)");
byteBuffer[0] = *(bytes - 1);
// Fallback adds fallback to chars, but doesn't increment chars unless the whole thing fits.
@@ -866,7 +855,7 @@ namespace System.Text
// Make sure we have buffer space
if (chars >= charEnd)
{
- Contract.Assert(bytes > byteStart,
+ Debug.Assert(bytes > byteStart,
"[SBCSCodePageEncoding.GetChars]Expected bytes to have advanced already (known byte)");
bytes--; // unused byte
ThrowCharsOverflow(decoder, bytes == byteStart); // throw?
@@ -883,7 +872,7 @@ namespace System.Text
decoder.m_bytesUsed = (int)(bytes - byteStart);
// Expect Empty fallback buffer for GetChars
- Contract.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
"[SBCSEncoding.GetChars]Expected Empty fallback buffer at end");
return (int)(chars - charStart);
@@ -892,7 +881,7 @@ namespace System.Text
public override int GetMaxByteCount(int charCount)
{
if (charCount < 0)
- throw new ArgumentOutOfRangeException("charCount",
+ throw new ArgumentOutOfRangeException(nameof(charCount),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -905,14 +894,14 @@ namespace System.Text
// 1 to 1 for most characters. Only surrogates with fallbacks have less.
if (byteCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException("charCount", Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
+ throw new ArgumentOutOfRangeException(nameof(charCount), Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
return (int)byteCount;
}
public override int GetMaxCharCount(int byteCount)
{
if (byteCount < 0)
- throw new ArgumentOutOfRangeException("byteCount",
+ throw new ArgumentOutOfRangeException(nameof(byteCount),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -924,7 +913,7 @@ namespace System.Text
charCount *= DecoderFallback.MaxCharCount;
if (charCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException("byteCount", Environment.GetResourceString("ArgumentOutOfRange_GetCharCountOverflow"));
+ throw new ArgumentOutOfRangeException(nameof(byteCount), Environment.GetResourceString("ArgumentOutOfRange_GetCharCountOverflow"));
return (int)charCount;
}
diff --git a/src/mscorlib/src/System/Text/StringBuilder.cs b/src/mscorlib/src/System/Text/StringBuilder.cs
index 8026c98e78..f20146fe00 100644
--- a/src/mscorlib/src/System/Text/StringBuilder.cs
+++ b/src/mscorlib/src/System/Text/StringBuilder.cs
@@ -20,7 +20,9 @@ namespace System.Text {
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
@@ -55,7 +57,7 @@ namespace System.Text {
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 logial offset (sum of all characters in previous blocks)
+ internal int m_ChunkOffset; // The logical offset (sum of all characters in previous blocks)
internal int m_MaxCapacity = 0;
//
@@ -117,18 +119,17 @@ namespace System.Text {
// Creates a new string builder from the specifed substring with the specified
// capacity. The maximum number of characters is set by capacity.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public StringBuilder(String value, int startIndex, int length, int capacity) {
if (capacity<0) {
- throw new ArgumentOutOfRangeException("capacity",
- Environment.GetResourceString("ArgumentOutOfRange_MustBePositive", "capacity"));
+ throw new ArgumentOutOfRangeException(nameof(capacity),
+ Environment.GetResourceString("ArgumentOutOfRange_MustBePositive", nameof(capacity)));
}
if (length<0) {
- throw new ArgumentOutOfRangeException("length",
- Environment.GetResourceString("ArgumentOutOfRange_MustBeNonNegNum", "length"));
+ throw new ArgumentOutOfRangeException(nameof(length),
+ Environment.GetResourceString("ArgumentOutOfRange_MustBeNonNegNum", nameof(length)));
}
if (startIndex<0) {
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
}
Contract.EndContractBlock();
@@ -136,7 +137,7 @@ namespace System.Text {
value = String.Empty;
}
if (startIndex > value.Length - length) {
- throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_IndexLength"));
+ throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_IndexLength"));
}
m_MaxCapacity = Int32.MaxValue;
if (capacity == 0) {
@@ -158,14 +159,14 @@ namespace System.Text {
// and a maximum capacity of maxCapacity.
public StringBuilder(int capacity, int maxCapacity) {
if (capacity>maxCapacity) {
- throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_Capacity"));
+ throw new ArgumentOutOfRangeException(nameof(capacity), Environment.GetResourceString("ArgumentOutOfRange_Capacity"));
}
if (maxCapacity<1) {
- throw new ArgumentOutOfRangeException("maxCapacity", Environment.GetResourceString("ArgumentOutOfRange_SmallMaxCapacity"));
+ throw new ArgumentOutOfRangeException(nameof(maxCapacity), Environment.GetResourceString("ArgumentOutOfRange_SmallMaxCapacity"));
}
if (capacity<0) {
- throw new ArgumentOutOfRangeException("capacity",
- Environment.GetResourceString("ArgumentOutOfRange_MustBePositive", "capacity"));
+ throw new ArgumentOutOfRangeException(nameof(capacity),
+ Environment.GetResourceString("ArgumentOutOfRange_MustBePositive", nameof(capacity)));
}
Contract.EndContractBlock();
@@ -177,10 +178,9 @@ namespace System.Text {
m_ChunkChars = new char[capacity];
}
- [System.Security.SecurityCritical] // auto-generated
private StringBuilder(SerializationInfo info, StreamingContext context) {
if (info == null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
int persistedCapacity = 0;
@@ -240,11 +240,10 @@ namespace System.Text {
VerifyClassInvariant();
}
- [System.Security.SecurityCritical] // auto-generated
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info==null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
@@ -264,21 +263,21 @@ namespace System.Text {
for (; ; )
{
// All blocks have copy of the maxCapacity.
- Contract.Assert(currentBlock.m_MaxCapacity == maxCapacity, "Bad maxCapacity");
- Contract.Assert(currentBlock.m_ChunkChars != null, "Empty Buffer");
+ Debug.Assert(currentBlock.m_MaxCapacity == maxCapacity, "Bad maxCapacity");
+ Debug.Assert(currentBlock.m_ChunkChars != null, "Empty Buffer");
- Contract.Assert(currentBlock.m_ChunkLength <= currentBlock.m_ChunkChars.Length, "Out of range length");
- Contract.Assert(currentBlock.m_ChunkLength >= 0, "Negative length");
- Contract.Assert(currentBlock.m_ChunkOffset >= 0, "Negative offset");
+ 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)
{
- Contract.Assert(currentBlock.m_ChunkOffset == 0, "First chunk's offset is not 0");
+ Debug.Assert(currentBlock.m_ChunkOffset == 0, "First chunk's offset is not 0");
break;
}
// There are no gaps in the blocks.
- Contract.Assert(currentBlock.m_ChunkOffset == prevBlock.m_ChunkOffset + prevBlock.m_ChunkLength, "There is a gap between chunks!");
+ Debug.Assert(currentBlock.m_ChunkOffset == prevBlock.m_ChunkOffset + prevBlock.m_ChunkLength, "There is a gap between chunks!");
currentBlock = prevBlock;
}
}
@@ -287,13 +286,13 @@ namespace System.Text {
get { return m_ChunkChars.Length + m_ChunkOffset; }
set {
if (value < 0) {
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_NegativeCapacity"));
+ throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_NegativeCapacity"));
}
if (value > MaxCapacity) {
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_Capacity"));
+ throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_Capacity"));
}
if (value < Length) {
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
+ throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
}
Contract.EndContractBlock();
@@ -317,7 +316,7 @@ namespace System.Text {
//
public int EnsureCapacity(int capacity) {
if (capacity < 0) {
- throw new ArgumentOutOfRangeException("capacity", Environment.GetResourceString("ArgumentOutOfRange_NegativeCapacity"));
+ throw new ArgumentOutOfRangeException(nameof(capacity), Environment.GetResourceString("ArgumentOutOfRange_NegativeCapacity"));
}
Contract.EndContractBlock();
@@ -326,7 +325,6 @@ namespace System.Text {
return Capacity;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override String ToString() {
Contract.Ensures(Contract.Result<String>() != null);
@@ -357,7 +355,7 @@ namespace System.Text {
}
else
{
- throw new ArgumentOutOfRangeException("chunkLength", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(chunkLength), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
}
chunk = chunk.m_ChunkPrevious;
@@ -370,26 +368,25 @@ namespace System.Text {
// Converts a substring of this string builder to a String.
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(int startIndex, int length) {
Contract.Ensures(Contract.Result<String>() != null);
int currentLength = this.Length;
if (startIndex < 0)
{
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
}
if (startIndex > currentLength)
{
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndexLargerThanLength"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndexLargerThanLength"));
}
if (length < 0)
{
- throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
+ throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
}
if (startIndex > (currentLength - length))
{
- throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_IndexLength"));
+ throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_IndexLength"));
}
VerifyClassInvariant();
@@ -433,7 +430,7 @@ namespace System.Text {
}
else
{
- throw new ArgumentOutOfRangeException("chunkCount", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(chunkCount), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
}
}
@@ -463,11 +460,11 @@ namespace System.Text {
set {
//If the new length is less than 0 or greater than our Maximum capacity, bail.
if (value<0) {
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
+ throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
}
if (value>MaxCapacity) {
- throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
+ throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
}
Contract.EndContractBlock();
@@ -477,7 +474,7 @@ namespace System.Text {
{
m_ChunkLength = 0;
m_ChunkOffset = 0;
- Contract.Assert(Capacity >= originalCapacity, "setting the Length should never decrease the Capacity");
+ Debug.Assert(Capacity >= originalCapacity, "setting the Length should never decrease the Capacity");
return;
}
@@ -499,7 +496,7 @@ namespace System.Text {
int newLen = originalCapacity - chunk.m_ChunkOffset;
char[] newArray = new char[newLen];
- Contract.Assert(newLen > chunk.m_ChunkChars.Length, "the new chunk should be larger than the one it is replacing");
+ 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;
@@ -509,7 +506,7 @@ namespace System.Text {
m_ChunkLength = value - chunk.m_ChunkOffset;
VerifyClassInvariant();
}
- Contract.Assert(Capacity >= originalCapacity, "setting the Length should never decrease the Capacity");
+ Debug.Assert(Capacity >= originalCapacity, "setting the Length should never decrease the Capacity");
}
}
@@ -539,13 +536,13 @@ namespace System.Text {
if (indexInBlock >= 0)
{
if (indexInBlock >= chunk.m_ChunkLength)
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ 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("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
}
}
@@ -553,7 +550,7 @@ namespace System.Text {
// 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("repeatCount", Environment.GetResourceString("ArgumentOutOfRange_NegativeCount"));
+ throw new ArgumentOutOfRangeException(nameof(repeatCount), Environment.GetResourceString("ArgumentOutOfRange_NegativeCount"));
}
Contract.Ensures(Contract.Result<StringBuilder>() != null);
Contract.EndContractBlock();
@@ -561,6 +558,14 @@ namespace System.Text {
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)
{
@@ -573,7 +578,7 @@ namespace System.Text {
{
m_ChunkLength = idx;
ExpandByABlock(repeatCount);
- Contract.Assert(m_ChunkLength == 0, "Expand should create a new block");
+ Debug.Assert(m_ChunkLength == 0, "Expand should create a new block");
idx = 0;
}
}
@@ -583,10 +588,9 @@ namespace System.Text {
}
// Appends an array of characters at the end of this string builder. The capacity is adjusted as needed.
- [System.Security.SecuritySafeCritical] // auto-generated
public StringBuilder Append(char[] value, int startIndex, int charCount) {
if (startIndex < 0) {
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
}
if (charCount<0) {
throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
@@ -598,7 +602,7 @@ namespace System.Text {
if (startIndex == 0 && charCount == 0) {
return this;
}
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
if (charCount > value.Length - startIndex) {
throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Index"));
@@ -620,7 +624,6 @@ namespace System.Text {
// Appends a copy of this string at the end of this string builder.
- [System.Security.SecuritySafeCritical] // auto-generated
public StringBuilder Append(String value) {
Contract.Ensures(Contract.Result<StringBuilder>() != null);
@@ -659,7 +662,6 @@ namespace System.Text {
// We put this fixed in its own helper to avoid the cost zero initing valueChars in the
// case we don't actually use it.
- [System.Security.SecuritySafeCritical] // auto-generated
private void AppendHelper(string value) {
unsafe {
fixed (char* valueChars = value)
@@ -668,23 +670,20 @@ namespace System.Text {
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [SecurityCritical]
internal unsafe extern void ReplaceBufferInternal(char* newBuffer, int newLength);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [SecurityCritical]
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.
- [System.Security.SecuritySafeCritical] // auto-generated
public StringBuilder Append(String value, int startIndex, int count) {
if (startIndex < 0) {
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
if (count < 0) {
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
}
Contract.Ensures(Contract.Result<StringBuilder>() != null);
@@ -694,7 +693,7 @@ namespace System.Text {
if (startIndex == 0 && count == 0) {
return this;
}
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
if (count == 0) {
@@ -702,7 +701,7 @@ namespace System.Text {
}
if (startIndex > value.Length - count) {
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
unsafe
@@ -730,19 +729,18 @@ namespace System.Text {
}
[System.Runtime.InteropServices.ComVisible(false)]
- [SecuritySafeCritical]
public void CopyTo(int sourceIndex, char[] destination, int destinationIndex, int count) {
if (destination == null) {
- throw new ArgumentNullException("destination");
+ throw new ArgumentNullException(nameof(destination));
}
if (count < 0) {
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("Arg_NegativeArgCount"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("Arg_NegativeArgCount"));
}
if (destinationIndex < 0) {
- throw new ArgumentOutOfRangeException("destinationIndex",
- Environment.GetResourceString("ArgumentOutOfRange_MustBeNonNegNum", "destinationIndex"));
+ throw new ArgumentOutOfRangeException(nameof(destinationIndex),
+ Environment.GetResourceString("ArgumentOutOfRange_MustBeNonNegNum", nameof(destinationIndex)));
}
if (destinationIndex > destination.Length - count) {
@@ -750,7 +748,7 @@ namespace System.Text {
}
if ((uint)sourceIndex > (uint)Length) {
- throw new ArgumentOutOfRangeException("sourceIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(sourceIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
if (sourceIndex > Length - count) {
@@ -794,10 +792,9 @@ namespace System.Text {
// The capacity is adjusted as needed. If value equals String.Empty, this
// string builder is not changed.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public StringBuilder Insert(int index, String value, int count) {
if (count < 0) {
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
Contract.Ensures(Contract.Result<StringBuilder>() != null);
Contract.EndContractBlock();
@@ -805,7 +802,7 @@ namespace System.Text {
//Range check the index.
int currentLength = Length;
if ((uint)index > (uint)currentLength) {
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
//If value is null, empty or count is 0, do nothing. This is ECMA standard.
@@ -819,7 +816,7 @@ namespace System.Text {
if (insertingChars > MaxCapacity - this.Length) {
throw new OutOfMemoryException();
}
- Contract.Assert(insertingChars + this.Length < Int32.MaxValue);
+ Debug.Assert(insertingChars + this.Length < Int32.MaxValue);
StringBuilder chunk;
int indexInChunk;
@@ -843,11 +840,11 @@ namespace System.Text {
//
public StringBuilder Remove(int startIndex, int length) {
if (length<0) {
- throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
+ throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
}
if (startIndex<0) {
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
}
if (length > Length - startIndex) {
@@ -989,7 +986,6 @@ namespace System.Text {
}
// Appends all of the characters in value to the current instance.
- [System.Security.SecuritySafeCritical] // auto-generated
public StringBuilder Append(char[] value) {
Contract.Ensures(Contract.Result<StringBuilder>() != null);
@@ -1003,6 +999,88 @@ namespace System.Text {
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====================================
**
==============================================================================*/
@@ -1012,10 +1090,9 @@ namespace System.Text {
// The capacity is adjusted as needed. If value equals String.Empty, the
// StringBuilder is not changed.
//
- [System.Security.SecuritySafeCritical] // auto-generated
public StringBuilder Insert(int index, String value) {
if ((uint)index > (uint)Length) {
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
Contract.Ensures(Contract.Result<StringBuilder>() != null);
Contract.EndContractBlock();
@@ -1075,7 +1152,6 @@ namespace System.Text {
// 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.
- [SecuritySafeCritical]
public StringBuilder Insert(int index, char value) {
Contract.Ensures(Contract.Result<StringBuilder>() != null);
@@ -1092,7 +1168,7 @@ namespace System.Text {
//
public StringBuilder Insert(int index, char[] value) {
if ((uint)index > (uint)Length) {
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
Contract.Ensures(Contract.Result<StringBuilder>() != null);
Contract.EndContractBlock();
@@ -1106,13 +1182,12 @@ namespace System.Text {
// 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.
- [System.Security.SecuritySafeCritical] // auto-generated
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("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
//If they passed in a null char array, just jump out quickly.
@@ -1121,12 +1196,12 @@ namespace System.Text {
{
return this;
}
- throw new ArgumentNullException("value", Environment.GetResourceString("ArgumentNull_String"));
+ throw new ArgumentNullException(nameof(value), Environment.GetResourceString("ArgumentNull_String"));
}
//Range check the array.
if (startIndex < 0) {
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
}
if (charCount < 0) {
@@ -1134,7 +1209,7 @@ namespace System.Text {
}
if (startIndex > value.Length - charCount) {
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
if (charCount > 0)
@@ -1255,7 +1330,7 @@ namespace System.Text {
{
// 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) ? "format" : "args");
+ throw new ArgumentNullException((format == null) ? nameof(format) : nameof(args));
}
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
@@ -1283,7 +1358,7 @@ namespace System.Text {
{
// 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) ? "format" : "args");
+ throw new ArgumentNullException((format == null) ? nameof(format) : nameof(args));
}
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
@@ -1301,7 +1376,7 @@ namespace System.Text {
internal StringBuilder AppendFormatHelper(IFormatProvider provider, String format, ParamsArray args) {
if (format == null) {
- throw new ArgumentNullException("format");
+ throw new ArgumentNullException(nameof(format));
}
Contract.Ensures(Contract.Result<StringBuilder>() != null);
Contract.EndContractBlock();
@@ -1582,19 +1657,19 @@ namespace System.Text {
int currentLength = Length;
if ((uint)startIndex > (uint)currentLength)
{
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
if (count < 0 || startIndex > currentLength - count)
{
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
if (oldValue == null)
{
- throw new ArgumentNullException("oldValue");
+ throw new ArgumentNullException(nameof(oldValue));
}
if (oldValue.Length == 0)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "oldValue");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(oldValue));
}
if (newValue == null)
@@ -1648,7 +1723,7 @@ namespace System.Text {
chunk = FindChunkForIndex(index);
indexInChunk = index - chunk.m_ChunkOffset;
- Contract.Assert(chunk != null || count == 0, "Chunks ended prematurely");
+ Debug.Assert(chunk != null || count == 0, "Chunks ended prematurely");
}
}
VerifyClassInvariant();
@@ -1668,11 +1743,11 @@ namespace System.Text {
int currentLength = Length;
if ((uint)startIndex > (uint)currentLength) {
- throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
if (count < 0 || startIndex > currentLength - count) {
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
int endIndex = startIndex + count;
@@ -1702,14 +1777,20 @@ namespace System.Text {
/// <summary>
/// Appends 'value' of length 'count' to the stringBuilder.
/// </summary>
- [SecurityCritical]
[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("valueCount", Environment.GetResourceString("ArgumentOutOfRange_NegativeCount"));
+ 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.
@@ -1732,7 +1813,7 @@ namespace System.Text {
// Expand the builder to add another chunk.
int restLength = valueCount - firstLength;
ExpandByABlock(restLength);
- Contract.Assert(m_ChunkLength == 0, "Expand did not make a new block");
+ Debug.Assert(m_ChunkLength == 0, "Expand did not make a new block");
// Copy the second chunk
ThreadSafeCopy(value + firstLength, m_ChunkChars, 0, restLength);
@@ -1745,12 +1826,11 @@ namespace System.Text {
/// <summary>
/// Inserts 'value' of length 'cou
/// </summary>
- [SecurityCritical]
unsafe private void Insert(int index, char* value, int valueCount)
{
if ((uint)index > (uint)Length)
{
- throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
if (valueCount > 0)
@@ -1768,7 +1848,6 @@ namespace System.Text {
/// replacements in bulk (and therefore very efficiently.
/// with the string 'value'.
/// </summary>
- [System.Security.SecuritySafeCritical] // auto-generated
private void ReplaceAllInChunk(int[] replacements, int replacementsCount, StringBuilder sourceChunk, int removeCount, string value)
{
if (replacementsCount <= 0)
@@ -1798,9 +1877,9 @@ namespace System.Text {
break;
int gapEnd = replacements[i];
- Contract.Assert(gapStart < sourceChunk.m_ChunkChars.Length, "gap starts at end of buffer. Should not happen");
- Contract.Assert(gapStart <= gapEnd, "negative gap size");
- Contract.Assert(gapEnd <= sourceChunk.m_ChunkLength, "gap too big");
+ 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
@@ -1810,7 +1889,7 @@ namespace System.Text {
else
{
targetIndexInChunk += gapEnd - gapStart;
- Contract.Assert(targetIndexInChunk <= targetChunk.m_ChunkLength, "gap not in chunk");
+ Debug.Assert(targetIndexInChunk <= targetChunk.m_ChunkLength, "gap not in chunk");
}
}
@@ -1855,7 +1934,6 @@ namespace System.Text {
/// point at the end of the characters just copyied (thus you can splice in strings from multiple
/// places by calling this mulitple times.
/// </summary>
- [SecurityCritical]
unsafe private void ReplaceInPlaceAtChunk(ref StringBuilder chunk, ref int indexInChunk, char* value, int count)
{
if (count != 0)
@@ -1863,7 +1941,7 @@ namespace System.Text {
for (; ; )
{
int lengthInChunk = chunk.m_ChunkLength - indexInChunk;
- Contract.Assert(lengthInChunk >= 0, "index not in chunk");
+ Debug.Assert(lengthInChunk >= 0, "index not in chunk");
int lengthToCopy = Math.Min(lengthInChunk, count);
ThreadSafeCopy(value, chunk.m_ChunkChars, indexInChunk, lengthToCopy);
@@ -1888,7 +1966,6 @@ namespace System.Text {
/// 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>
- [SecurityCritical]
unsafe private static void ThreadSafeCopy(char* sourcePtr, char[] destination, int destinationIndex, int count)
{
if (count > 0)
@@ -1900,11 +1977,10 @@ namespace System.Text {
}
else
{
- throw new ArgumentOutOfRangeException("destinationIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(destinationIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
}
}
- [SecurityCritical]
private static void ThreadSafeCopy(char[] source, int sourceIndex, char[] destination, int destinationIndex, int count)
{
if (count > 0)
@@ -1918,13 +1994,12 @@ namespace System.Text {
}
else
{
- throw new ArgumentOutOfRangeException("sourceIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(sourceIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
}
}
// Copies the source StringBuilder to the destination IntPtr memory allocated with len bytes.
- [System.Security.SecurityCritical] // auto-generated
internal unsafe void InternalCopy(IntPtr dest, int len) {
if(len ==0)
return;
@@ -1957,13 +2032,13 @@ namespace System.Text {
/// <returns></returns>
private StringBuilder FindChunkForIndex(int index)
{
- Contract.Assert(0 <= index && index <= Length, "index not in string");
+ Debug.Assert(0 <= index && index <= Length, "index not in string");
StringBuilder ret = this;
while (ret.m_ChunkOffset > index)
ret = ret.m_ChunkPrevious;
- Contract.Assert(ret != null, "index not in string");
+ Debug.Assert(ret != null, "index not in string");
return ret;
}
@@ -1974,13 +2049,13 @@ namespace System.Text {
/// <returns></returns>
private StringBuilder FindChunkForByte(int byteIndex)
{
- Contract.Assert(0 <= byteIndex && byteIndex <= Length*sizeof(char), "Byte Index not in string");
+ 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;
- Contract.Assert(ret != null, "Byte Index not in string");
+ Debug.Assert(ret != null, "Byte Index not in string");
return ret;
}
@@ -2063,12 +2138,11 @@ namespace System.Text {
/// 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>
- [System.Security.SecuritySafeCritical] // auto-generated
private void MakeRoom(int index, int count, out StringBuilder chunk, out int indexInChunk, bool doneMoveFollowingChars)
{
VerifyClassInvariant();
- Contract.Assert(count > 0, "Count must be strictly positive");
- Contract.Assert(index >= 0, "Index can't be negative");
+ 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"));
@@ -2133,8 +2207,8 @@ namespace System.Text {
/// </summary>
private StringBuilder(int size, int maxCapacity, StringBuilder previousBlock)
{
- Contract.Assert(size > 0, "size not positive");
- Contract.Assert(maxCapacity > 0, "maxCapacity not positive");
+ 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;
@@ -2147,11 +2221,10 @@ namespace System.Text {
/// 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>
- [SecuritySafeCritical]
private void Remove(int startIndex, int count, out StringBuilder chunk, out int indexInChunk)
{
VerifyClassInvariant();
- Contract.Assert(startIndex >= 0 && startIndex < Length, "startIndex not in string");
+ Debug.Assert(startIndex >= 0 && startIndex < Length, "startIndex not in string");
int endIndex = startIndex + count;
@@ -2180,7 +2253,7 @@ namespace System.Text {
}
chunk = chunk.m_ChunkPrevious;
}
- Contract.Assert(chunk != null, "fell off beginning of string!");
+ Debug.Assert(chunk != null, "fell off beginning of string!");
int copyTargetIndexInChunk = indexInChunk;
int copyCount = endChunk.m_ChunkLength - endIndexInChunk;
@@ -2210,7 +2283,7 @@ namespace System.Text {
if (copyTargetIndexInChunk != endIndexInChunk) // Sometimes no move is necessary
ThreadSafeCopy(endChunk.m_ChunkChars, endIndexInChunk, endChunk.m_ChunkChars, copyTargetIndexInChunk, copyCount);
- Contract.Assert(chunk != null, "fell off beginning of string!");
+ Debug.Assert(chunk != null, "fell off beginning of string!");
VerifyClassInvariant();
}
}
diff --git a/src/mscorlib/src/System/Text/SurrogateEncoder.cs b/src/mscorlib/src/System/Text/SurrogateEncoder.cs
index 409e8a34aa..bbfa180f29 100644
--- a/src/mscorlib/src/System/Text/SurrogateEncoder.cs
+++ b/src/mscorlib/src/System/Text/SurrogateEncoder.cs
@@ -12,6 +12,7 @@ namespace System.Text
using System;
using System.Runtime.Serialization;
using System.Security.Permissions;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
/*=================================SurrogateEncoder==================================
@@ -30,7 +31,7 @@ namespace System.Text
internal SurrogateEncoder(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException("info");
+ if (info==null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// All versions have a code page
@@ -38,7 +39,6 @@ namespace System.Text
}
// Just get it from GetEncoding
- [System.Security.SecurityCritical] // auto-generated
public Object GetRealObject(StreamingContext context)
{
// Need to get our Encoding's Encoder
@@ -46,11 +46,10 @@ namespace System.Text
}
// ISerializable implementation
- [System.Security.SecurityCritical] // auto-generated_required
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
// We cannot ever call this.
- Contract.Assert(false, "Didn't expect to make it to SurrogateEncoder.GetObjectData");
+ Debug.Assert(false, "Didn't expect to make it to SurrogateEncoder.GetObjectData");
throw new ArgumentException(Environment.GetResourceString("Arg_ExecutionEngineException"));
}
}
diff --git a/src/mscorlib/src/System/Text/UTF32Encoding.cs b/src/mscorlib/src/System/Text/UTF32Encoding.cs
index 0bdbaefbf2..a7ac1d8539 100644
--- a/src/mscorlib/src/System/Text/UTF32Encoding.cs
+++ b/src/mscorlib/src/System/Text/UTF32Encoding.cs
@@ -10,6 +10,7 @@ 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
@@ -109,7 +110,6 @@ namespace System.Text
return EncodingForwarder.GetByteCount(this, s);
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
public override unsafe int GetByteCount(char* chars, int count)
{
@@ -137,7 +137,6 @@ namespace System.Text
return EncodingForwarder.GetBytes(this, chars, charIndex, charCount, bytes, byteIndex);
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
{
@@ -152,7 +151,6 @@ namespace System.Text
return EncodingForwarder.GetCharCount(this, bytes, index, count);
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
public override unsafe int GetCharCount(byte* bytes, int count)
{
@@ -165,7 +163,6 @@ namespace System.Text
return EncodingForwarder.GetChars(this, bytes, byteIndex, byteCount, chars, charIndex);
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
{
@@ -182,11 +179,10 @@ namespace System.Text
// End of overridden methods which use EncodingForwarder
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetByteCount(char *chars, int count, EncoderNLS encoder)
{
- Contract.Assert(chars!=null, "[UTF32Encoding.GetByteCount]chars!=null");
- Contract.Assert(count >=0, "[UTF32Encoding.GetByteCount]count >=0");
+ Debug.Assert(chars!=null, "[UTF32Encoding.GetByteCount]chars!=null");
+ Debug.Assert(count >=0, "[UTF32Encoding.GetByteCount]count >=0");
char* end = chars + count;
char* charStart = chars;
@@ -248,7 +244,7 @@ namespace System.Text
// 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.
- Contract.Assert(chars > charStart,
+ Debug.Assert(chars > charStart,
"[UTF32Encoding.GetByteCount]Expected chars to have advanced if no low surrogate");
chars--;
@@ -296,26 +292,25 @@ namespace System.Text
// Check for overflows.
if (byteCount < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString(
+ 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)
- Contract.Assert(fallbackBuffer.Remaining == 0,
+ Debug.Assert(fallbackBuffer.Remaining == 0,
"[UTF32Encoding.GetByteCount]Expected empty fallback buffer at end");
// Return our count
return byteCount;
}
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetBytes(char *chars, int charCount,
byte* bytes, int byteCount, EncoderNLS encoder)
{
- Contract.Assert(chars!=null, "[UTF32Encoding.GetBytes]chars!=null");
- Contract.Assert(bytes!=null, "[UTF32Encoding.GetBytes]bytes!=null");
- Contract.Assert(byteCount >=0, "[UTF32Encoding.GetBytes]byteCount >=0");
- Contract.Assert(charCount >=0, "[UTF32Encoding.GetBytes]charCount >=0");
+ 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;
@@ -384,7 +379,7 @@ namespace System.Text
{
// If we don't have enough room, then either we should've advanced a while
// or we should have bytes==byteStart and throw below
- Contract.Assert(chars > charStart + 1 || bytes == byteStart,
+ 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
}
@@ -412,7 +407,7 @@ namespace System.Text
// 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.
- Contract.Assert(chars > charStart,
+ Debug.Assert(chars > charStart,
"[UTF32Encoding.GetBytes]Expected chars to have advanced if no low surrogate");
chars--;
@@ -453,7 +448,7 @@ namespace System.Text
else
{
// Must've advanced already
- Contract.Assert(chars > charStart,
+ Debug.Assert(chars > charStart,
"[UTF32Encoding.GetBytes]Expected chars to have advanced if normal character");
chars--; // Aren't using this char
}
@@ -487,7 +482,7 @@ namespace System.Text
}
// Fix our encoder if we have one
- Contract.Assert(highSurrogate == 0 || (encoder != null && !encoder.MustFlush),
+ Debug.Assert(highSurrogate == 0 || (encoder != null && !encoder.MustFlush),
"[UTF32Encoding.GetBytes]Expected encoder to be flushed.");
if (encoder != null)
@@ -503,11 +498,10 @@ namespace System.Text
return (int)(bytes - byteStart);
}
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS baseDecoder)
{
- Contract.Assert(bytes!=null, "[UTF32Encoding.GetCharCount]bytes!=null");
- Contract.Assert(count >=0, "[UTF32Encoding.GetCharCount]count >=0");
+ Debug.Assert(bytes!=null, "[UTF32Encoding.GetCharCount]bytes!=null");
+ Debug.Assert(count >=0, "[UTF32Encoding.GetCharCount]count >=0");
UTF32Decoder decoder = (UTF32Decoder)baseDecoder;
@@ -532,7 +526,7 @@ namespace System.Text
// Shouldn't have anything in fallback buffer for GetCharCount
// (don't have to check m_throwOnOverflow for chars or count)
- Contract.Assert(fallbackBuffer.Remaining == 0,
+ Debug.Assert(fallbackBuffer.Remaining == 0,
"[UTF32Encoding.GetCharCount]Expected empty fallback buffer at start");
}
else
@@ -635,25 +629,24 @@ namespace System.Text
// Check for overflows.
if (charCount < 0)
- throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
+ 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)
- Contract.Assert(fallbackBuffer.Remaining == 0,
+ Debug.Assert(fallbackBuffer.Remaining == 0,
"[UTF32Encoding.GetCharCount]Expected empty fallback buffer at end");
// Return our count
return charCount;
}
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetChars(byte* bytes, int byteCount,
char* chars, int charCount, DecoderNLS baseDecoder)
{
- Contract.Assert(chars!=null, "[UTF32Encoding.GetChars]chars!=null");
- Contract.Assert(bytes!=null, "[UTF32Encoding.GetChars]bytes!=null");
- Contract.Assert(byteCount >=0, "[UTF32Encoding.GetChars]byteCount >=0");
- Contract.Assert(charCount >=0, "[UTF32Encoding.GetChars]charCount >=0");
+ 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;
@@ -680,7 +673,7 @@ namespace System.Text
// Shouldn't have anything in fallback buffer for GetChars
// (don't have to check m_throwOnOverflow for chars)
- Contract.Assert(fallbackBuffer.Remaining == 0,
+ Debug.Assert(fallbackBuffer.Remaining == 0,
"[UTF32Encoding.GetChars]Expected empty fallback buffer at start");
}
else
@@ -741,7 +734,7 @@ namespace System.Text
// 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
- Contract.Assert(bytes >= byteStart + 4 || 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
@@ -765,7 +758,7 @@ namespace System.Text
// Throwing or stopping
// We either read enough bytes for bytes-=4 to work, or we're
// going to throw in ThrowCharsOverflow because chars == charStart
- Contract.Assert(bytes >= byteStart + 4 || 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
@@ -782,7 +775,7 @@ namespace System.Text
// Throwing or stopping
// We either read enough bytes for bytes-=4 to work, or we're
// going to throw in ThrowCharsOverflow because chars == charStart
- Contract.Assert(bytes >= byteStart + 4 || 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
@@ -846,7 +839,7 @@ namespace System.Text
// Shouldn't have anything in fallback buffer for GetChars
// (don't have to check m_throwOnOverflow for chars)
- Contract.Assert(fallbackBuffer.Remaining == 0,
+ Debug.Assert(fallbackBuffer.Remaining == 0,
"[UTF32Encoding.GetChars]Expected empty fallback buffer at end");
// Return our count
@@ -885,7 +878,7 @@ namespace System.Text
public override int GetMaxByteCount(int charCount)
{
if (charCount < 0)
- throw new ArgumentOutOfRangeException("charCount",
+ throw new ArgumentOutOfRangeException(nameof(charCount),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -899,7 +892,7 @@ namespace System.Text
byteCount *= 4;
if (byteCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException("charCount", Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
+ throw new ArgumentOutOfRangeException(nameof(charCount), Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
return (int)byteCount;
}
@@ -908,7 +901,7 @@ namespace System.Text
public override int GetMaxCharCount(int byteCount)
{
if (byteCount < 0)
- throw new ArgumentOutOfRangeException("byteCount",
+ throw new ArgumentOutOfRangeException(nameof(byteCount),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -929,7 +922,7 @@ namespace System.Text
}
if (charCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException("byteCount", Environment.GetResourceString("ArgumentOutOfRange_GetCharCountOverflow"));
+ throw new ArgumentOutOfRangeException(nameof(byteCount), Environment.GetResourceString("ArgumentOutOfRange_GetCharCountOverflow"));
return (int)charCount;
}
diff --git a/src/mscorlib/src/System/Text/UTF7Encoding.cs b/src/mscorlib/src/System/Text/UTF7Encoding.cs
index 654fb8b80f..624ca735f6 100644
--- a/src/mscorlib/src/System/Text/UTF7Encoding.cs
+++ b/src/mscorlib/src/System/Text/UTF7Encoding.cs
@@ -11,6 +11,7 @@ namespace System.Text
using System;
using System.Runtime.Serialization;
using System.Security.Permissions;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
@@ -175,7 +176,6 @@ namespace System.Text
return EncodingForwarder.GetByteCount(this, s);
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public override unsafe int GetByteCount(char* chars, int count)
@@ -205,7 +205,6 @@ namespace System.Text
return EncodingForwarder.GetBytes(this, chars, charIndex, charCount, bytes, byteIndex);
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
@@ -221,7 +220,6 @@ namespace System.Text
return EncodingForwarder.GetCharCount(this, bytes, index, count);
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public override unsafe int GetCharCount(byte* bytes, int count)
@@ -235,7 +233,6 @@ namespace System.Text
return EncodingForwarder.GetChars(this, bytes, byteIndex, byteCount, chars, charIndex);
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
@@ -254,23 +251,21 @@ namespace System.Text
// End of overridden methods which use EncodingForwarder
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetByteCount(char* chars, int count, EncoderNLS baseEncoder)
{
- Contract.Assert(chars!=null, "[UTF7Encoding.GetByteCount]chars!=null");
- Contract.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);
}
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetBytes(char* chars, int charCount,
byte* bytes, int byteCount, EncoderNLS baseEncoder)
{
- Contract.Assert(byteCount >=0, "[UTF7Encoding.GetBytes]byteCount >=0");
- Contract.Assert(chars!=null, "[UTF7Encoding.GetBytes]chars!=null");
- Contract.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;
@@ -405,23 +400,21 @@ namespace System.Text
return buffer.Count;
}
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS baseDecoder)
{
- Contract.Assert(count >=0, "[UTF7Encoding.GetCharCount]count >=0");
- Contract.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);
}
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetChars(byte* bytes, int byteCount,
char* chars, int charCount, DecoderNLS baseDecoder)
{
- Contract.Assert(byteCount >=0, "[UTF7Encoding.GetChars]byteCount >=0");
- Contract.Assert(bytes!=null, "[UTF7Encoding.GetChars]bytes!=null");
- Contract.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;
@@ -440,7 +433,7 @@ namespace System.Text
bitCount = decoder.bitCount;
firstByte = decoder.firstByte;
- Contract.Assert(firstByte == false || decoder.bitCount <= 0,
+ Debug.Assert(firstByte == false || decoder.bitCount <= 0,
"[UTF7Encoding.GetChars]If remembered bits, then first byte flag shouldn't be set");
}
@@ -599,7 +592,7 @@ namespace System.Text
public override int GetMaxByteCount(int charCount)
{
if (charCount < 0)
- throw new ArgumentOutOfRangeException("charCount",
+ throw new ArgumentOutOfRangeException(nameof(charCount),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -623,7 +616,7 @@ namespace System.Text
// check for overflow
if (byteCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException("charCount", Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
+ throw new ArgumentOutOfRangeException(nameof(charCount), Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
return (int)byteCount;
}
@@ -632,7 +625,7 @@ namespace System.Text
public override int GetMaxCharCount(int byteCount)
{
if (byteCount < 0)
- throw new ArgumentOutOfRangeException("byteCount",
+ throw new ArgumentOutOfRangeException(nameof(byteCount),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -663,7 +656,7 @@ namespace System.Text
internal Decoder(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException("info");
+ if (info==null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// Get common info
@@ -674,11 +667,10 @@ namespace System.Text
}
// ISerializable implementation, get data for this object
- [System.Security.SecurityCritical] // auto-generated_required
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException("info");
+ if (info==null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// Save Whidbey data
@@ -727,7 +719,7 @@ namespace System.Text
internal Encoder(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException("info");
+ if (info==null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// Get common info
@@ -737,11 +729,10 @@ namespace System.Text
}
// ISerializable implementation, get data for this object
- [System.Security.SecurityCritical] // auto-generated_required
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException("info");
+ if (info==null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// Save Whidbey data
@@ -825,8 +816,8 @@ namespace System.Text
public override bool Fallback(byte[] bytesUnknown, int index)
{
// We expect no previous fallback in our buffer
- Contract.Assert(iCount < 0, "[DecoderUTF7FallbackBuffer.Fallback] Can't have recursive fallbacks");
- Contract.Assert(bytesUnknown.Length == 1, "[DecoderUTF7FallbackBuffer.Fallback] Only possible fallback case should be 1 unknown byte");
+ Debug.Assert(iCount < 0, "[DecoderUTF7FallbackBuffer.Fallback] Can't have recursive fallbacks");
+ Debug.Assert(bytesUnknown.Length == 1, "[DecoderUTF7FallbackBuffer.Fallback] Only possible fallback case should be 1 unknown byte");
// Go ahead and get our fallback
cFallback = (char)bytesUnknown[0];
@@ -872,7 +863,6 @@ namespace System.Text
}
// Clear the buffer
- [System.Security.SecuritySafeCritical] // overrides public transparent member
public override unsafe void Reset()
{
iCount = -1;
@@ -880,13 +870,12 @@ namespace System.Text
}
// This version just counts the fallback and doesn't actually copy anything.
- [System.Security.SecurityCritical] // auto-generated
internal unsafe override int InternalFallback(byte[] bytes, byte* pBytes)
// Right now this has both bytes and bytes[], since we might have extra bytes, hence the
// array, and we might need the index, hence the byte*
{
// We expect no previous fallback in our buffer
- Contract.Assert(iCount < 0, "[DecoderUTF7FallbackBuffer.InternalFallback] Can't have recursive fallbacks");
+ Debug.Assert(iCount < 0, "[DecoderUTF7FallbackBuffer.InternalFallback] Can't have recursive fallbacks");
if (bytes.Length != 1)
{
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"));
diff --git a/src/mscorlib/src/System/Text/UTF8Encoding.cs b/src/mscorlib/src/System/Text/UTF8Encoding.cs
index a527de7b61..ba19649b56 100644
--- a/src/mscorlib/src/System/Text/UTF8Encoding.cs
+++ b/src/mscorlib/src/System/Text/UTF8Encoding.cs
@@ -21,6 +21,7 @@ namespace System.Text
using System.Globalization;
using System.Runtime.Serialization;
using System.Security.Permissions;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
// Encodes text into and out of UTF-8. UTF-8 is a way of writing
@@ -129,7 +130,6 @@ namespace System.Text
return EncodingForwarder.GetByteCount(this, chars);
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public override unsafe int GetByteCount(char* chars, int count)
@@ -158,7 +158,6 @@ namespace System.Text
return EncodingForwarder.GetBytes(this, chars, charIndex, charCount, bytes, byteIndex);
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
@@ -174,7 +173,6 @@ namespace System.Text
return EncodingForwarder.GetCharCount(this, bytes, index, count);
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public override unsafe int GetCharCount(byte* bytes, int count)
@@ -188,7 +186,6 @@ namespace System.Text
return EncodingForwarder.GetChars(this, bytes, byteIndex, byteCount, chars, charIndex);
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
@@ -209,7 +206,6 @@ namespace System.Text
// To simplify maintenance, the structure of GetByteCount and GetBytes should be
// kept the same as much as possible
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetByteCount(char *chars, int count, EncoderNLS baseEncoder)
{
// For fallback we may need a fallback buffer.
@@ -254,7 +250,7 @@ namespace System.Text
} else {
// Case of surrogates in the fallback.
if (fallbackBuffer != null && fallbackBuffer.bFallingBack) {
- Contract.Assert(ch >= 0xD800 && ch <= 0xDBFF,
+ Debug.Assert(ch >= 0xD800 && ch <= 0xDBFF,
"[UTF8Encoding.GetBytes]expected high surrogate, not 0x" + ((int)ch).ToString("X4", CultureInfo.InvariantCulture));
ch = fallbackBuffer.InternalGetNextChar();
@@ -286,7 +282,7 @@ namespace System.Text
}
if (ch > 0) {
- Contract.Assert(ch >= 0xD800 && ch <= 0xDBFF,
+ 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
@@ -557,7 +553,7 @@ namespace System.Text
}
#endif
- Contract.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
"[UTF8Encoding.GetByteCount]Expected Empty fallback buffer");
return byteCount;
@@ -566,14 +562,12 @@ namespace System.Text
// 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
- [System.Security.SecurityCritical] // auto-generated
unsafe private static int PtrDiff(char *a, char* b)
{
return (int)(((uint)((byte*)a - (byte*)b)) >> 1);
}
// byte* flavor just for parity
- [System.Security.SecurityCritical] // auto-generated
unsafe private static int PtrDiff(byte* a, byte* b)
{
return (int)(a - b);
@@ -586,14 +580,13 @@ namespace System.Text
// Our workhorse
// Note: We ignore mismatched surrogates, unless the exception flag is set in which case we throw
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetBytes(char* chars, int charCount,
byte* bytes, int byteCount, EncoderNLS baseEncoder)
{
- Contract.Assert(chars!=null, "[UTF8Encoding.GetBytes]chars!=null");
- Contract.Assert(byteCount >=0, "[UTF8Encoding.GetBytes]byteCount >=0");
- Contract.Assert(charCount >=0, "[UTF8Encoding.GetBytes]charCount >=0");
- Contract.Assert(bytes!=null, "[UTF8Encoding.GetBytes]bytes!=null");
+ 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;
@@ -642,7 +635,7 @@ namespace System.Text
} else {
// Case of leftover surrogates in the fallback buffer
if (fallbackBuffer != null && fallbackBuffer.bFallingBack) {
- Contract.Assert(ch >= 0xD800 && ch <= 0xDBFF,
+ Debug.Assert(ch >= 0xD800 && ch <= 0xDBFF,
"[UTF8Encoding.GetBytes]expected high surrogate, not 0x" + ((int)ch).ToString("X4", CultureInfo.InvariantCulture));
int cha = ch;
@@ -670,7 +663,7 @@ namespace System.Text
if (ch > 0) {
// We have a high surrogate left over from a previous loop.
- Contract.Assert(ch >= 0xD800 && ch <= 0xDBFF,
+ 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
@@ -767,7 +760,7 @@ namespace System.Text
if (ch > 0xFFFF)
pSrc--; // Was surrogate, didn't use 2nd part either
}
- Contract.Assert(pSrc >= chars || pTarget == bytes,
+ 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)
@@ -989,7 +982,7 @@ namespace System.Text
pTarget++;
}
- Contract.Assert(pTarget <= pAllocatedBufferEnd, "[UTF8Encoding.GetBytes]pTarget <= pAllocatedBufferEnd");
+ Debug.Assert(pTarget <= pAllocatedBufferEnd, "[UTF8Encoding.GetBytes]pTarget <= pAllocatedBufferEnd");
#endif // FASTLOOP
@@ -1000,14 +993,14 @@ namespace System.Text
// Do we have to set the encoder bytes?
if (encoder != null)
{
- Contract.Assert(!encoder.MustFlush || ch == 0,
+ 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);
}
- Contract.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0 ||
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0 ||
baseEncoder == null || !baseEncoder.m_throwOnOverflow,
"[UTF8Encoding.GetBytes]Expected empty fallback buffer if not converting");
@@ -1029,11 +1022,10 @@ namespace System.Text
//
// To simplify maintenance, the structure of GetCharCount and GetChars should be
// kept the same as much as possible
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS baseDecoder)
{
- Contract.Assert(count >=0, "[UTF8Encoding.GetCharCount]count >=0");
- Contract.Assert(bytes!=null, "[UTF8Encoding.GetCharCount]bytes!=null");
+ Debug.Assert(count >=0, "[UTF8Encoding.GetCharCount]count >=0");
+ Debug.Assert(bytes!=null, "[UTF8Encoding.GetCharCount]bytes!=null");
// Initialize stuff
byte *pSrc = bytes;
@@ -1052,7 +1044,7 @@ namespace System.Text
// Shouldn't have anything in fallback buffer for GetCharCount
// (don't have to check m_throwOnOverflow for count)
- Contract.Assert(!decoder.InternalHasFallbackBuffer || decoder.FallbackBuffer.Remaining == 0,
+ Debug.Assert(!decoder.InternalHasFallbackBuffer || decoder.FallbackBuffer.Remaining == 0,
"[UTF8Encoding.GetCharCount]Expected empty fallback buffer at start");
}
@@ -1087,7 +1079,7 @@ namespace System.Text
ch = (ch << 6) | (cha & 0x3F);
if ((ch & FinalByte) == 0) {
- Contract.Assert( (ch & (SupplimentarySeq | ThreeByteSeq)) != 0,
+ Debug.Assert( (ch & (SupplimentarySeq | ThreeByteSeq)) != 0,
"[UTF8Encoding.GetChars]Invariant volation");
if ((ch & SupplimentarySeq) != 0) {
@@ -1408,7 +1400,7 @@ namespace System.Text
// Shouldn't have anything in fallback buffer for GetCharCount
// (don't have to check m_throwOnOverflow for count)
- Contract.Assert(fallback == null || fallback.Remaining == 0,
+ Debug.Assert(fallback == null || fallback.Remaining == 0,
"[UTF8Encoding.GetCharCount]Expected empty fallback buffer at end");
return charCount;
@@ -1424,14 +1416,13 @@ namespace System.Text
//
// To simplify maintenance, the structure of GetCharCount and GetChars should be
// kept the same as much as possible
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetChars(byte* bytes, int byteCount,
char* chars, int charCount, DecoderNLS baseDecoder)
{
- Contract.Assert(chars!=null, "[UTF8Encoding.GetChars]chars!=null");
- Contract.Assert(byteCount >=0, "[UTF8Encoding.GetChars]count >=0");
- Contract.Assert(charCount >=0, "[UTF8Encoding.GetChars]charCount >=0");
- Contract.Assert(bytes!=null, "[UTF8Encoding.GetChars]bytes!=null");
+ 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;
@@ -1448,7 +1439,7 @@ namespace System.Text
// 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)
- Contract.Assert(!decoder.InternalHasFallbackBuffer || decoder.FallbackBuffer.Remaining == 0,
+ Debug.Assert(!decoder.InternalHasFallbackBuffer || decoder.FallbackBuffer.Remaining == 0,
"[UTF8Encoding.GetChars]Expected empty fallback buffer at start");
}
@@ -1483,7 +1474,7 @@ namespace System.Text
if ((ch & FinalByte) == 0) {
// Not at last byte yet
- Contract.Assert( (ch & (SupplimentarySeq | ThreeByteSeq)) != 0,
+ Debug.Assert( (ch & (SupplimentarySeq | ThreeByteSeq)) != 0,
"[UTF8Encoding.GetChars]Invariant volation");
if ((ch & SupplimentarySeq) != 0) {
@@ -1546,14 +1537,14 @@ namespace System.Text
{
// Ran out of buffer space
// Need to throw an exception?
- Contract.Assert(pSrc >= bytes || pTarget == chars,
+ 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;
}
- Contract.Assert(pSrc >= bytes,
+ Debug.Assert(pSrc >= bytes,
"[UTF8Encoding.GetChars]Expected invalid byte sequence to have remained within the byte array");
ch = 0;
continue;
@@ -1639,7 +1630,7 @@ namespace System.Text
// Throw that we don't have enough room (pSrc could be < chars if we had started to process
// a 4 byte sequence alredy)
- Contract.Assert(pSrc >= bytes || pTarget == chars,
+ 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);
@@ -1893,7 +1884,7 @@ namespace System.Text
}
#endif // FASTLOOP
- Contract.Assert(pTarget <= pAllocatedBufferEnd, "[UTF8Encoding.GetChars]pTarget <= pAllocatedBufferEnd");
+ Debug.Assert(pTarget <= pAllocatedBufferEnd, "[UTF8Encoding.GetChars]pTarget <= pAllocatedBufferEnd");
// no pending bits at this point
ch = 0;
@@ -1920,7 +1911,7 @@ namespace System.Text
// This'll back us up the appropriate # of bytes if we didn't get anywhere
if (!FallbackInvalidByteSequence(ref pSrc, ch, fallback, ref pTarget))
{
- Contract.Assert(pSrc >= bytes || pTarget == chars,
+ Debug.Assert(pSrc >= bytes || pTarget == chars,
"[UTF8Encoding.GetChars]Expected to throw or remain in byte buffer while flushing");
// Ran out of buffer space
@@ -1928,7 +1919,7 @@ namespace System.Text
fallback.InternalReset();
ThrowCharsOverflow(baseDecoder, pTarget == chars);
}
- Contract.Assert(pSrc >= bytes,
+ Debug.Assert(pSrc >= bytes,
"[UTF8Encoding.GetChars]Expected flushing invalid byte sequence to have remained within the byte array");
ch = 0;
}
@@ -1939,7 +1930,7 @@ namespace System.Text
// If we're storing flush data we expect all bits to be used or else
// we're stuck in the middle of a conversion
- Contract.Assert(!baseDecoder.MustFlush || ch == 0 || !baseDecoder.m_throwOnOverflow,
+ 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.
@@ -1950,7 +1941,7 @@ namespace System.Text
// Shouldn't have anything in fallback buffer for GetChars
// (don't have to check m_throwOnOverflow for chars)
- Contract.Assert(fallback == null || fallback.Remaining == 0,
+ Debug.Assert(fallback == null || fallback.Remaining == 0,
"[UTF8Encoding.GetChars]Expected empty fallback buffer at end");
return PtrDiff(pTarget, chars);
@@ -1959,7 +1950,6 @@ namespace System.Text
// 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.
- [System.Security.SecurityCritical] // auto-generated
private unsafe bool FallbackInvalidByteSequence(
ref byte* pSrc, int ch, DecoderFallbackBuffer fallback, ref char* pTarget)
{
@@ -1982,7 +1972,6 @@ namespace System.Text
// 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)
- [System.Security.SecurityCritical] // auto-generated
private unsafe int FallbackInvalidByteSequence(
byte* pSrc, int ch, DecoderFallbackBuffer fallback)
{
@@ -2001,7 +1990,6 @@ namespace System.Text
// 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.
- [System.Security.SecurityCritical] // auto-generated
private unsafe byte[] GetBytesUnknown(ref byte* pSrc, int ch)
{
// Get our byte[]
@@ -2085,7 +2073,7 @@ namespace System.Text
public override int GetMaxByteCount(int charCount)
{
if (charCount < 0)
- throw new ArgumentOutOfRangeException("charCount",
+ throw new ArgumentOutOfRangeException(nameof(charCount),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -2099,7 +2087,7 @@ namespace System.Text
byteCount *= 3;
if (byteCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException("charCount", Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
+ throw new ArgumentOutOfRangeException(nameof(charCount), Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
return (int)byteCount;
}
@@ -2108,7 +2096,7 @@ namespace System.Text
public override int GetMaxCharCount(int byteCount)
{
if (byteCount < 0)
- throw new ArgumentOutOfRangeException("byteCount",
+ throw new ArgumentOutOfRangeException(nameof(byteCount),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -2123,7 +2111,7 @@ namespace System.Text
}
if (charCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException("byteCount", Environment.GetResourceString("ArgumentOutOfRange_GetCharCountOverflow"));
+ throw new ArgumentOutOfRangeException(nameof(byteCount), Environment.GetResourceString("ArgumentOutOfRange_GetCharCountOverflow"));
return (int)charCount;
}
@@ -2174,7 +2162,7 @@ namespace System.Text
internal UTF8Encoder(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException("info");
+ if (info==null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// Get common info
@@ -2194,11 +2182,10 @@ namespace System.Text
}
// ISerializable implementation, get data for this object
- [System.Security.SecurityCritical] // auto-generated_required
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException("info");
+ if (info==null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// Save Whidbey data
@@ -2247,7 +2234,7 @@ namespace System.Text
internal UTF8Decoder(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException("info");
+ if (info==null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// Get common info
@@ -2268,11 +2255,10 @@ namespace System.Text
}
// ISerializable implementation, get data for this object
- [System.Security.SecurityCritical] // auto-generated_required
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException("info");
+ if (info==null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// Save new Whidbey data
diff --git a/src/mscorlib/src/System/Text/UnicodeEncoding.cs b/src/mscorlib/src/System/Text/UnicodeEncoding.cs
index 41d4f3b5ea..25255c3230 100644
--- a/src/mscorlib/src/System/Text/UnicodeEncoding.cs
+++ b/src/mscorlib/src/System/Text/UnicodeEncoding.cs
@@ -12,6 +12,7 @@ namespace System.Text
using System.Globalization;
using System.Runtime.Serialization;
using System.Security.Permissions;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
@@ -109,7 +110,6 @@ namespace System.Text
return EncodingForwarder.GetByteCount(this, s);
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public override unsafe int GetByteCount(char* chars, int count)
@@ -138,7 +138,6 @@ namespace System.Text
return EncodingForwarder.GetBytes(this, chars, charIndex, charCount, bytes, byteIndex);
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
@@ -154,7 +153,6 @@ namespace System.Text
return EncodingForwarder.GetCharCount(this, bytes, index, count);
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public override unsafe int GetCharCount(byte* bytes, int count)
@@ -168,7 +166,6 @@ namespace System.Text
return EncodingForwarder.GetChars(this, bytes, byteIndex, byteCount, chars, charIndex);
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(false)]
public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
@@ -187,11 +184,10 @@ namespace System.Text
// End of overridden methods which use EncodingForwarder
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetByteCount(char* chars, int count, EncoderNLS encoder)
{
- Contract.Assert(chars!=null, "[UnicodeEncoding.GetByteCount]chars!=null");
- Contract.Assert(count >= 0, "[UnicodeEncoding.GetByteCount]count >=0");
+ 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;
@@ -200,7 +196,7 @@ namespace System.Text
// (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("count", Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
+ throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
char* charStart = chars;
char* charEnd = chars + count;
@@ -340,7 +336,7 @@ namespace System.Text
// Unwind the current character, this should be safe because we
// don't have leftover data in the fallback, so chars must have
// advanced already.
- Contract.Assert(chars > charStart,
+ Debug.Assert(chars > charStart,
"[UnicodeEncoding.GetByteCount]Expected chars to have advanced in unexpected high surrogate");
chars--;
@@ -407,7 +403,7 @@ namespace System.Text
// 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.
- Contract.Assert(chars > charStart,
+ Debug.Assert(chars > charStart,
"[UnicodeEncoding.GetByteCount]Expected chars to have advanced when expected low surrogate");
chars--;
@@ -448,7 +444,7 @@ namespace System.Text
// Throw it, using our complete character
throw new ArgumentException(
Environment.GetResourceString("Argument_RecursiveFallback",
- charLeftOver), "chars");
+ charLeftOver), nameof(chars));
}
else
{
@@ -473,21 +469,20 @@ namespace System.Text
// Shouldn't have anything in fallback buffer for GetByteCount
// (don't have to check m_throwOnOverflow for count)
- Contract.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
"[UnicodeEncoding.GetByteCount]Expected empty fallback buffer at end");
// Don't remember fallbackBuffer.encoder for counting
return byteCount;
}
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetBytes(char* chars, int charCount,
byte* bytes, int byteCount, EncoderNLS encoder)
{
- Contract.Assert(chars!=null, "[UnicodeEncoding.GetBytes]chars!=null");
- Contract.Assert(byteCount >=0, "[UnicodeEncoding.GetBytes]byteCount >=0");
- Contract.Assert(charCount >=0, "[UnicodeEncoding.GetBytes]charCount >=0");
- Contract.Assert(bytes!=null, "[UnicodeEncoding.GetBytes]bytes!=null");
+ 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;
@@ -691,7 +686,7 @@ namespace System.Text
// Unwind the current character, this should be safe because we
// don't have leftover data in the fallback, so chars must have
// advanced already.
- Contract.Assert(chars > charStart,
+ Debug.Assert(chars > charStart,
"[UnicodeEncoding.GetBytes]Expected chars to have advanced in unexpected high surrogate");
chars--;
@@ -757,7 +752,7 @@ namespace System.Text
{
// If we don't have enough room, then either we should've advanced a while
// or we should have bytes==byteStart and throw below
- Contract.Assert(chars > charStart + 1 || bytes == byteStart,
+ 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
}
@@ -786,7 +781,7 @@ namespace System.Text
// 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.
- Contract.Assert(chars > charStart,
+ Debug.Assert(chars > charStart,
"[UnicodeEncoding.GetBytes]Expected chars to have advanced after expecting low surrogate");
chars--;
@@ -820,7 +815,7 @@ namespace System.Text
{
// 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.
- Contract.Assert(chars > charStart,
+ Debug.Assert(chars > charStart,
"[UnicodeEncoding.GetBytes]Expected chars to have advanced for failed fallback");
chars--; // Not using this char
}
@@ -851,7 +846,7 @@ namespace System.Text
// Throw it, using our complete character
throw new ArgumentException(
Environment.GetResourceString("Argument_RecursiveFallback",
- charLeftOver), "chars");
+ charLeftOver), nameof(chars));
}
else
{
@@ -888,10 +883,10 @@ namespace System.Text
// Remember charLeftOver if we must, or clear it if we're flushing
// (charLeftOver should be 0 if we're flushing)
- Contract.Assert((encoder != null && !encoder.MustFlush) || charLeftOver == (char)0,
+ Debug.Assert((encoder != null && !encoder.MustFlush) || charLeftOver == (char)0,
"[UnicodeEncoding.GetBytes] Expected no left over characters if flushing");
- Contract.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0 ||
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0 ||
encoder == null || !encoder.m_throwOnOverflow,
"[UnicodeEncoding.GetBytes]Expected empty fallback buffer if not converting");
@@ -901,11 +896,10 @@ namespace System.Text
return (int)(bytes - byteStart);
}
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS baseDecoder)
{
- Contract.Assert(bytes!=null, "[UnicodeEncoding.GetCharCount]bytes!=null");
- Contract.Assert(count >= 0, "[UnicodeEncoding.GetCharCount]count >=0");
+ Debug.Assert(bytes!=null, "[UnicodeEncoding.GetCharCount]bytes!=null");
+ Debug.Assert(count >= 0, "[UnicodeEncoding.GetCharCount]count >=0");
UnicodeEncoding.Decoder decoder = (UnicodeEncoding.Decoder)baseDecoder;
@@ -944,7 +938,7 @@ namespace System.Text
// Shouldn't have anything in fallback buffer for GetCharCount
// (don't have to check m_throwOnOverflow for count)
- Contract.Assert(!decoder.InternalHasFallbackBuffer || decoder.FallbackBuffer.Remaining == 0,
+ Debug.Assert(!decoder.InternalHasFallbackBuffer || decoder.FallbackBuffer.Remaining == 0,
"[UnicodeEncoding.GetCharCount]Expected empty fallback buffer at start");
}
@@ -1234,20 +1228,19 @@ namespace System.Text
// Shouldn't have anything in fallback buffer for GetCharCount
// (don't have to check m_throwOnOverflow for count)
- Contract.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
"[UnicodeEncoding.GetCharCount]Expected empty fallback buffer at end");
return charCount;
}
- [System.Security.SecurityCritical] // auto-generated
internal override unsafe int GetChars(byte* bytes, int byteCount,
char* chars, int charCount, DecoderNLS baseDecoder )
{
- Contract.Assert(chars!=null, "[UnicodeEncoding.GetChars]chars!=null");
- Contract.Assert(byteCount >=0, "[UnicodeEncoding.GetChars]byteCount >=0");
- Contract.Assert(charCount >=0, "[UnicodeEncoding.GetChars]charCount >=0");
- Contract.Assert(bytes!=null, "[UnicodeEncoding.GetChars]bytes!=null");
+ 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;
@@ -1263,7 +1256,7 @@ namespace System.Text
// Shouldn't have anything in fallback buffer for GetChars
// (don't have to check m_throwOnOverflow for chars)
- Contract.Assert(!decoder.InternalHasFallbackBuffer || decoder.FallbackBuffer.Remaining == 0,
+ Debug.Assert(!decoder.InternalHasFallbackBuffer || decoder.FallbackBuffer.Remaining == 0,
"[UnicodeEncoding.GetChars]Expected empty fallback buffer at start");
}
@@ -1421,7 +1414,7 @@ namespace System.Text
{
// couldn't fall back lonely surrogate
// We either advanced bytes or chars should == charStart and throw below
- Contract.Assert(bytes >= byteStart + 2 || chars == charStart,
+ 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();
@@ -1470,7 +1463,7 @@ namespace System.Text
{
// couldn't fall back lonely surrogate
// We either advanced bytes or chars should == charStart and throw below
- Contract.Assert(bytes >= byteStart + 2 || chars == charStart,
+ 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();
@@ -1487,7 +1480,7 @@ namespace System.Text
{
// couldn't find room for this surrogate pair
// We either advanced bytes or chars should == charStart and throw below
- Contract.Assert(bytes >= byteStart + 2 || chars == charStart,
+ 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
@@ -1529,7 +1522,7 @@ namespace System.Text
{
// couldn't fall back high surrogate, or char that would be next
// We either advanced bytes or chars should == charStart and throw below
- Contract.Assert(bytes >= byteStart + 2 || chars == charStart,
+ 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();
@@ -1546,7 +1539,7 @@ namespace System.Text
{
// 2 bytes couldn't fall back
// We either advanced bytes or chars should == charStart and throw below
- Contract.Assert(bytes >= byteStart + 2 || chars == charStart,
+ 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
@@ -1591,7 +1584,7 @@ namespace System.Text
{
// 2 bytes couldn't fall back
// We either advanced bytes or chars should == charStart and throw below
- Contract.Assert(bytes >= byteStart + 2 || chars == charStart,
+ 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)
@@ -1644,7 +1637,7 @@ namespace System.Text
// Remember our decoder if we must
if (decoder != null)
{
- Contract.Assert((decoder.MustFlush == false) || ((lastChar == (char)0) && (lastByte == -1)),
+ 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")
);
@@ -1659,7 +1652,7 @@ namespace System.Text
// Shouldn't have anything in fallback buffer for GetChars
// (don't have to check m_throwOnOverflow for count or chars)
- Contract.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
"[UnicodeEncoding.GetChars]Expected empty fallback buffer at end");
return (int)(chars - charStart);
@@ -1697,7 +1690,7 @@ namespace System.Text
public override int GetMaxByteCount(int charCount)
{
if (charCount < 0)
- throw new ArgumentOutOfRangeException("charCount",
+ throw new ArgumentOutOfRangeException(nameof(charCount),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -1711,7 +1704,7 @@ namespace System.Text
byteCount <<= 1;
if (byteCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException("charCount", Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
+ throw new ArgumentOutOfRangeException(nameof(charCount), Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
return (int)byteCount;
}
@@ -1720,7 +1713,7 @@ namespace System.Text
public override int GetMaxCharCount(int byteCount)
{
if (byteCount < 0)
- throw new ArgumentOutOfRangeException("byteCount",
+ throw new ArgumentOutOfRangeException(nameof(byteCount),
Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
@@ -1735,7 +1728,7 @@ namespace System.Text
charCount *= DecoderFallback.MaxCharCount;
if (charCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException("byteCount", Environment.GetResourceString("ArgumentOutOfRange_GetCharCountOverflow"));
+ throw new ArgumentOutOfRangeException(nameof(byteCount), Environment.GetResourceString("ArgumentOutOfRange_GetCharCountOverflow"));
return (int)charCount;
}
@@ -1781,7 +1774,7 @@ namespace System.Text
internal Decoder(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException("info");
+ if (info==null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// Get Common Info
@@ -1803,11 +1796,10 @@ namespace System.Text
}
// ISerializable implementation, get data for this object
- [System.Security.SecurityCritical] // auto-generated_required
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException("info");
+ if (info==null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// Save Whidbey data
diff --git a/src/mscorlib/src/System/Threading/AsyncLocal.cs b/src/mscorlib/src/System/Threading/AsyncLocal.cs
index 264f2a6ff7..6ed1545ac7 100644
--- a/src/mscorlib/src/System/Threading/AsyncLocal.cs
+++ b/src/mscorlib/src/System/Threading/AsyncLocal.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Security;
@@ -40,7 +41,6 @@ namespace System.Threading
//
public sealed class AsyncLocal<T> : IAsyncLocal
{
- [SecurityCritical] // critical because this action will terminate the process if it throws.
private readonly Action<AsyncLocalValueChangedArgs<T>> m_valueChangedHandler;
//
@@ -54,7 +54,6 @@ namespace System.Threading
// Constructs an AsyncLocal<T> with a delegate that is called whenever the current value changes
// on any thread.
//
- [SecurityCritical]
public AsyncLocal(Action<AsyncLocalValueChangedArgs<T>> valueChangedHandler)
{
m_valueChangedHandler = valueChangedHandler;
@@ -62,23 +61,20 @@ namespace System.Threading
public T Value
{
- [SecuritySafeCritical]
get
{
object obj = ExecutionContext.GetLocalValue(this);
return (obj == null) ? default(T) : (T)obj;
}
- [SecuritySafeCritical]
set
{
ExecutionContext.SetLocalValue(this, value, m_valueChangedHandler != null);
}
}
- [SecurityCritical]
void IAsyncLocal.OnValueChanged(object previousValueObj, object currentValueObj, bool contextChanged)
{
- Contract.Assert(m_valueChangedHandler != null);
+ 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));
@@ -90,7 +86,6 @@ namespace System.Threading
//
internal interface IAsyncLocal
{
- [SecurityCritical]
void OnValueChanged(object previousValue, object currentValue, bool contextChanged);
}
@@ -113,4 +108,382 @@ namespace System.Threading
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();
+
+ public static IAsyncLocalValueMap Create(IAsyncLocal key, object value) => new OneElementAsyncLocalValueMap(key, value);
+
+ // 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
index 6fe6c06232..78a6fa1234 100644
--- a/src/mscorlib/src/System/Threading/AutoResetEvent.cs
+++ b/src/mscorlib/src/System/Threading/AutoResetEvent.cs
@@ -17,7 +17,6 @@ namespace System.Threading {
using System.Security.Permissions;
using System.Runtime.InteropServices;
- [HostProtection(Synchronization=true, ExternalThreading=true)]
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class AutoResetEvent : EventWaitHandle
{
diff --git a/src/mscorlib/src/System/Threading/CancellationToken.cs b/src/mscorlib/src/System/Threading/CancellationToken.cs
index 48a2344c31..5b78f20900 100644
--- a/src/mscorlib/src/System/Threading/CancellationToken.cs
+++ b/src/mscorlib/src/System/Threading/CancellationToken.cs
@@ -8,9 +8,9 @@
#pragma warning disable 0420 // turn off 'a reference to a volatile field will not be treated as volatile' during CAS.
using System;
-using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security.Permissions;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime;
using System.Runtime.CompilerServices;
@@ -39,7 +39,6 @@ namespace System.Threading
/// </para>
/// </remarks>
[ComVisible(false)]
- [HostProtection(Synchronization = true, ExternalThreading = true)]
[DebuggerDisplay("IsCancellationRequested = {IsCancellationRequested}")]
public struct CancellationToken
{
@@ -167,7 +166,7 @@ namespace System.Threading
private static void ActionToActionObjShunt(object obj)
{
Action action = obj as Action;
- Contract.Assert(action != null, "Expected an Action here");
+ Debug.Assert(action != null, "Expected an Action here");
action();
}
@@ -192,7 +191,7 @@ namespace System.Threading
public CancellationTokenRegistration Register(Action callback)
{
if (callback == null)
- throw new ArgumentNullException("callback");
+ throw new ArgumentNullException(nameof(callback));
return Register(
s_ActionToActionObjShunt,
@@ -227,7 +226,7 @@ namespace System.Threading
public CancellationTokenRegistration Register(Action callback, bool useSynchronizationContext)
{
if (callback == null)
- throw new ArgumentNullException("callback");
+ throw new ArgumentNullException(nameof(callback));
return Register(
s_ActionToActionObjShunt,
@@ -260,7 +259,7 @@ namespace System.Threading
public CancellationTokenRegistration Register(Action<Object> callback, Object state)
{
if (callback == null)
- throw new ArgumentNullException("callback");
+ throw new ArgumentNullException(nameof(callback));
return Register(
callback,
@@ -318,14 +317,13 @@ namespace System.Threading
}
// the real work..
- [SecuritySafeCritical]
[MethodImpl(MethodImplOptions.NoInlining)]
private CancellationTokenRegistration Register(Action<Object> callback, Object state, bool useSynchronizationContext, bool useExecutionContext)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
if (callback == null)
- throw new ArgumentNullException("callback");
+ throw new ArgumentNullException(nameof(callback));
if (CanBeCanceled == false)
{
diff --git a/src/mscorlib/src/System/Threading/CancellationTokenRegistration.cs b/src/mscorlib/src/System/Threading/CancellationTokenRegistration.cs
index 34e0bb0aba..ac27fe30e6 100644
--- a/src/mscorlib/src/System/Threading/CancellationTokenRegistration.cs
+++ b/src/mscorlib/src/System/Threading/CancellationTokenRegistration.cs
@@ -17,7 +17,6 @@ namespace System.Threading
/// <remarks>
/// To unregister a callback, dispose the corresponding Registration instance.
/// </remarks>
- [HostProtection(Synchronization = true, ExternalThreading = true)]
public struct CancellationTokenRegistration : IEquatable<CancellationTokenRegistration>, IDisposable
{
private readonly CancellationCallbackInfo m_callbackInfo;
diff --git a/src/mscorlib/src/System/Threading/CancellationTokenSource.cs b/src/mscorlib/src/System/Threading/CancellationTokenSource.cs
index 954cd38344..fe9e0dec76 100644
--- a/src/mscorlib/src/System/Threading/CancellationTokenSource.cs
+++ b/src/mscorlib/src/System/Threading/CancellationTokenSource.cs
@@ -11,6 +11,7 @@ using System.Security;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security.Permissions;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime;
@@ -35,7 +36,6 @@ namespace System.Threading
/// </para>
/// </remarks>
[ComVisible(false)]
- [HostProtection(Synchronization = true, ExternalThreading = true)]
public class CancellationTokenSource : IDisposable
{
@@ -275,7 +275,7 @@ namespace System.Threading
long totalMilliseconds = (long)delay.TotalMilliseconds;
if (totalMilliseconds < -1 || totalMilliseconds > Int32.MaxValue)
{
- throw new ArgumentOutOfRangeException("delay");
+ throw new ArgumentOutOfRangeException(nameof(delay));
}
InitializeWithTimer((int)totalMilliseconds);
@@ -304,7 +304,7 @@ namespace System.Threading
{
if (millisecondsDelay < -1)
{
- throw new ArgumentOutOfRangeException("millisecondsDelay");
+ throw new ArgumentOutOfRangeException(nameof(millisecondsDelay));
}
InitializeWithTimer(millisecondsDelay);
@@ -414,7 +414,7 @@ namespace System.Threading
long totalMilliseconds = (long)delay.TotalMilliseconds;
if (totalMilliseconds < -1 || totalMilliseconds > Int32.MaxValue)
{
- throw new ArgumentOutOfRangeException("delay");
+ throw new ArgumentOutOfRangeException(nameof(delay));
}
CancelAfter((int)totalMilliseconds);
@@ -450,7 +450,7 @@ namespace System.Threading
if (millisecondsDelay < -1)
{
- throw new ArgumentOutOfRangeException("millisecondsDelay");
+ throw new ArgumentOutOfRangeException(nameof(millisecondsDelay));
}
if (IsCancellationRequested) return;
@@ -629,7 +629,7 @@ namespace System.Threading
}
// the CancellationToken has already checked that the token is cancelable before calling this method.
- Contract.Assert(CanBeCanceled, "Cannot register for uncancelable token src");
+ Debug.Assert(CanBeCanceled, "Cannot register for uncancelable token src");
// if not canceled, register the event handlers
// if canceled already, run the callback synchronously
@@ -730,7 +730,7 @@ namespace System.Threading
// - After transition, no more delegates will be added to the
// - list of handlers, and hence it can be consumed and cleared at leisure by ExecuteCallbackHandlers.
ExecuteCallbackHandlers(throwOnFirstException);
- Contract.Assert(IsCancellationCompleted, "Expected cancellation to have finished");
+ Debug.Assert(IsCancellationCompleted, "Expected cancellation to have finished");
}
}
@@ -742,8 +742,8 @@ namespace System.Threading
/// </remarks>
private void ExecuteCallbackHandlers(bool throwOnFirstException)
{
- Contract.Assert(IsCancellationRequested, "ExecuteCallbackHandlers should only be called after setting IsCancellationRequested->true");
- Contract.Assert(ThreadIDExecutingCallbacks != -1, "ThreadIDExecutingCallbacks should have been set.");
+ Debug.Assert(IsCancellationRequested, "ExecuteCallbackHandlers should only be called after setting IsCancellationRequested->true");
+ Debug.Assert(ThreadIDExecutingCallbacks != -1, "ThreadIDExecutingCallbacks should have been set.");
// Design decision: call the delegates in LIFO order so that callbacks fire 'deepest first'.
// This is intended to help with nesting scenarios so that child enlisters cancel before their parents.
@@ -791,7 +791,7 @@ namespace System.Threading
var wsc = m_executingCallback as CancellationCallbackInfo.WithSyncContext;
if (wsc != null)
{
- Contract.Assert(wsc.TargetSyncContext != null, "Should only have derived CCI if non-null SyncCtx");
+ Debug.Assert(wsc.TargetSyncContext != null, "Should only have derived CCI if non-null SyncCtx");
wsc.TargetSyncContext.Send(CancellationCallbackCoreWork_OnSyncContext, args);
// CancellationCallbackCoreWork_OnSyncContext may have altered ThreadIDExecutingCallbacks, so reset it.
ThreadIDExecutingCallbacks = Thread.CurrentThread.ManagedThreadId;
@@ -828,7 +828,7 @@ namespace System.Threading
if (exceptionList != null)
{
- Contract.Assert(exceptionList.Count > 0, "Expected exception count > 0");
+ Debug.Assert(exceptionList.Count > 0, "Expected exception count > 0");
throw new AggregateException(exceptionList);
}
}
@@ -882,7 +882,7 @@ namespace System.Threading
public static CancellationTokenSource CreateLinkedTokenSource(params CancellationToken[] tokens)
{
if (tokens == null)
- throw new ArgumentNullException("tokens");
+ throw new ArgumentNullException(nameof(tokens));
if (tokens.Length == 0)
throw new ArgumentException(Environment.GetResourceString("CancellationToken_CreateLinkedToken_TokensIsEmpty"));
@@ -1029,14 +1029,12 @@ namespace System.Threading
}
// Cached callback delegate that's lazily initialized due to ContextCallback being SecurityCritical
- [SecurityCritical]
private static ContextCallback s_executionContextCallback;
/// <summary>
/// InternalExecuteCallbackSynchronously_GeneralPath
/// This will be called on the target synchronization context, however, we still need to restore the required execution context
/// </summary>
- [SecuritySafeCritical]
internal void ExecuteCallback()
{
if (TargetExecutionContext != null)
@@ -1059,11 +1057,10 @@ namespace System.Threading
// the worker method to actually run the callback
// The signature is such that it can be used as a 'ContextCallback'
- [SecurityCritical]
private static void ExecutionContextCallback(object obj)
{
CancellationCallbackInfo callbackInfo = obj as CancellationCallbackInfo;
- Contract.Assert(callbackInfo != null);
+ Debug.Assert(callbackInfo != null);
callbackInfo.Callback(callbackInfo.StateForCallback);
}
}
@@ -1147,14 +1144,14 @@ namespace System.Threading
start = 0;
curr.m_freeCount--; // Too many free elements; fix up.
}
- Contract.Assert(start >= 0 && start < c, "start is outside of bounds");
+ Debug.Assert(start >= 0 && start < c, "start is outside of bounds");
// Now walk the array until we find a free slot (or reach the end).
for (int i = 0; i < c; i++)
{
// If the slot is null, try to CAS our element into it.
int tryIndex = (start + i) % c;
- Contract.Assert(tryIndex >= 0 && tryIndex < curr.m_elements.Length, "tryIndex is outside of bounds");
+ 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)
{
@@ -1193,8 +1190,8 @@ namespace System.Threading
internal SparselyPopulatedArrayAddInfo(SparselyPopulatedArrayFragment<T> source, int index)
{
- Contract.Assert(source != null);
- Contract.Assert(index >= 0 && index < source.Length);
+ Debug.Assert(source != null);
+ Debug.Assert(index >= 0 && index < source.Length);
m_source = source;
m_index = index;
}
diff --git a/src/mscorlib/src/System/Threading/CountdownEvent.cs b/src/mscorlib/src/System/Threading/CountdownEvent.cs
index 1374766863..d86a2ccfb8 100644
--- a/src/mscorlib/src/System/Threading/CountdownEvent.cs
+++ b/src/mscorlib/src/System/Threading/CountdownEvent.cs
@@ -11,10 +11,10 @@
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
using System;
-using System.Diagnostics;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using System.Threading;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
namespace System.Threading
@@ -32,7 +32,6 @@ namespace System.Threading
/// </remarks>
[ComVisible(false)]
[DebuggerDisplay("Initial Count={InitialCount}, Current Count={CurrentCount}")]
- [HostProtection(Synchronization = true, ExternalThreading = true)]
public class CountdownEvent : IDisposable
{
// CountdownEvent is a simple synchronization primitive used for fork/join parallelism. We create a
@@ -59,7 +58,7 @@ namespace System.Threading
{
if (initialCount < 0)
{
- throw new ArgumentOutOfRangeException("initialCount");
+ throw new ArgumentOutOfRangeException(nameof(initialCount));
}
m_initialCount = initialCount;
@@ -186,7 +185,7 @@ namespace System.Threading
public bool Signal()
{
ThrowIfDisposed();
- Contract.Assert(m_event != null);
+ Debug.Assert(m_event != null);
if (m_currentCount <= 0)
{
@@ -229,11 +228,11 @@ namespace System.Threading
{
if (signalCount <= 0)
{
- throw new ArgumentOutOfRangeException("signalCount");
+ throw new ArgumentOutOfRangeException(nameof(signalCount));
}
ThrowIfDisposed();
- Contract.Assert(m_event != null);
+ Debug.Assert(m_event != null);
int observedCount;
SpinWait spin = new SpinWait();
@@ -267,7 +266,7 @@ namespace System.Threading
return true;
}
- Contract.Assert(m_currentCount >= 0, "latch was decremented below zero");
+ Debug.Assert(m_currentCount >= 0, "latch was decremented below zero");
return false;
}
@@ -340,7 +339,7 @@ namespace System.Threading
{
if (signalCount <= 0)
{
- throw new ArgumentOutOfRangeException("signalCount");
+ throw new ArgumentOutOfRangeException(nameof(signalCount));
}
ThrowIfDisposed();
@@ -409,7 +408,7 @@ namespace System.Threading
if (count < 0)
{
- throw new ArgumentOutOfRangeException("count");
+ throw new ArgumentOutOfRangeException(nameof(count));
}
m_currentCount = count;
@@ -481,7 +480,7 @@ namespace System.Threading
long totalMilliseconds = (long)timeout.TotalMilliseconds;
if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue)
{
- throw new ArgumentOutOfRangeException("timeout");
+ throw new ArgumentOutOfRangeException(nameof(timeout));
}
return Wait((int)totalMilliseconds, new CancellationToken());
@@ -511,7 +510,7 @@ namespace System.Threading
long totalMilliseconds = (long)timeout.TotalMilliseconds;
if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue)
{
- throw new ArgumentOutOfRangeException("timeout");
+ throw new ArgumentOutOfRangeException(nameof(timeout));
}
return Wait((int)totalMilliseconds, cancellationToken);
@@ -555,7 +554,7 @@ namespace System.Threading
{
if (millisecondsTimeout < -1)
{
- throw new ArgumentOutOfRangeException("millisecondsTimeout");
+ throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout));
}
ThrowIfDisposed();
diff --git a/src/mscorlib/src/System/Threading/EventWaitHandle.cs b/src/mscorlib/src/System/Threading/EventWaitHandle.cs
index f56da1fa26..4b1611c6aa 100644
--- a/src/mscorlib/src/System/Threading/EventWaitHandle.cs
+++ b/src/mscorlib/src/System/Threading/EventWaitHandle.cs
@@ -13,7 +13,6 @@
=============================================================================*/
-#if !FEATURE_MACL
namespace System.Security.AccessControl
{
public class EventWaitHandleSecurity
@@ -23,7 +22,6 @@ namespace System.Security.AccessControl
{
}
}
-#endif
namespace System.Threading
{
@@ -39,14 +37,11 @@ namespace System.Threading
using System.Security.AccessControl;
using System.Diagnostics.Contracts;
- [HostProtection(Synchronization=true, ExternalThreading=true)]
[ComVisibleAttribute(true)]
public class EventWaitHandle : WaitHandle
{
- [System.Security.SecuritySafeCritical] // auto-generated
public EventWaitHandle(bool initialState, EventResetMode mode) : this(initialState,mode,null) { }
- [System.Security.SecurityCritical] // auto-generated_required
public EventWaitHandle(bool initialState, EventResetMode mode, string name)
{
if(name != null)
@@ -56,7 +51,7 @@ namespace System.Threading
#else
if (System.IO.Path.MaxPath < name.Length)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), nameof(name));
}
#endif
}
@@ -89,13 +84,11 @@ namespace System.Threading
SetHandleInternal(_handle);
}
- [System.Security.SecurityCritical] // auto-generated_required
public EventWaitHandle(bool initialState, EventResetMode mode, string name, out bool createdNew)
: this(initialState, mode, name, out createdNew, null)
{
}
- [System.Security.SecurityCritical] // auto-generated_required
public unsafe EventWaitHandle(bool initialState, EventResetMode mode, string name, out bool createdNew, EventWaitHandleSecurity eventSecurity)
{
if(name != null)
@@ -105,24 +98,12 @@ namespace System.Threading
#else
if (System.IO.Path.MaxPath < name.Length)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), nameof(name));
}
#endif
}
Contract.EndContractBlock();
Win32Native.SECURITY_ATTRIBUTES secAttrs = null;
-#if FEATURE_MACL
- // For ACL's, get the security descriptor from the EventWaitHandleSecurity.
- if (eventSecurity != null) {
- secAttrs = new Win32Native.SECURITY_ATTRIBUTES();
- secAttrs.nLength = (int)Marshal.SizeOf(secAttrs);
-
- byte[] sd = eventSecurity.GetSecurityDescriptorBinaryForm();
- byte* pSecDescriptor = stackalloc byte[sd.Length];
- Buffer.Memcpy(pSecDescriptor, 0, sd, 0, sd.Length);
- secAttrs.pSecurityDescriptor = pSecDescriptor;
- }
-#endif
SafeWaitHandle _handle = null;
Boolean isManualReset;
@@ -155,23 +136,16 @@ namespace System.Threading
SetHandleInternal(_handle);
}
- [System.Security.SecurityCritical] // auto-generated
private EventWaitHandle(SafeWaitHandle handle)
{
SetHandleInternal(handle);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static EventWaitHandle OpenExisting(string name)
{
-#if !FEATURE_MACL
return OpenExisting(name, (EventWaitHandleRights)0);
-#else
- return OpenExisting(name, EventWaitHandleRights.Modify | EventWaitHandleRights.Synchronize);
-#endif
}
- [System.Security.SecurityCritical] // auto-generated_required
public static EventWaitHandle OpenExisting(string name, EventWaitHandleRights rights)
{
EventWaitHandle result;
@@ -192,23 +166,16 @@ namespace System.Threading
}
}
- [System.Security.SecurityCritical] // auto-generated_required
public static bool TryOpenExisting(string name, out EventWaitHandle result)
{
-#if !FEATURE_MACL
return OpenExistingWorker(name, (EventWaitHandleRights)0, out result) == OpenExistingResult.Success;
-#else
- return OpenExistingWorker(name, EventWaitHandleRights.Modify | EventWaitHandleRights.Synchronize, out result) == OpenExistingResult.Success;
-#endif
}
- [System.Security.SecurityCritical] // auto-generated_required
public static bool TryOpenExisting(string name, EventWaitHandleRights rights, out EventWaitHandle result)
{
return OpenExistingWorker(name, rights, out result) == OpenExistingResult.Success;
}
- [System.Security.SecurityCritical] // auto-generated_required
private static OpenExistingResult OpenExistingWorker(string name, EventWaitHandleRights rights, out EventWaitHandle result)
{
#if PLATFORM_UNIX
@@ -216,29 +183,25 @@ namespace System.Threading
#else
if (name == null)
{
- throw new ArgumentNullException("name", Environment.GetResourceString("ArgumentNull_WithParamName"));
+ throw new ArgumentNullException(nameof(name), Environment.GetResourceString("ArgumentNull_WithParamName"));
}
if(name.Length == 0)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name));
}
if(null != name && System.IO.Path.MaxPath < name.Length)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), nameof(name));
}
Contract.EndContractBlock();
result = null;
-#if FEATURE_MACL
- SafeWaitHandle myHandle = Win32Native.OpenEvent((int) rights, false, name);
-#else
SafeWaitHandle myHandle = Win32Native.OpenEvent(Win32Native.EVENT_MODIFY_STATE | Win32Native.SYNCHRONIZE, false, name);
-#endif
-
+
if (myHandle.IsInvalid)
{
int errorCode = Marshal.GetLastWin32Error();
@@ -256,7 +219,6 @@ namespace System.Threading
return OpenExistingResult.Success;
#endif
}
- [System.Security.SecuritySafeCritical] // auto-generated
public bool Reset()
{
bool res = Win32Native.ResetEvent(safeWaitHandle);
@@ -264,7 +226,6 @@ namespace System.Threading
__Error.WinIOError();
return res;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public bool Set()
{
bool res = Win32Native.SetEvent(safeWaitHandle);
@@ -274,24 +235,6 @@ namespace System.Threading
return res;
}
-
-#if FEATURE_MACL
- [System.Security.SecuritySafeCritical] // auto-generated
- public EventWaitHandleSecurity GetAccessControl()
- {
- return new EventWaitHandleSecurity(safeWaitHandle, AccessControlSections.Access | AccessControlSections.Owner | AccessControlSections.Group);
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public void SetAccessControl(EventWaitHandleSecurity eventSecurity)
- {
- if (eventSecurity == null)
- throw new ArgumentNullException("eventSecurity");
- Contract.EndContractBlock();
-
- eventSecurity.Persist(safeWaitHandle);
- }
-#endif
}
}
diff --git a/src/mscorlib/src/System/Threading/ExecutionContext.cs b/src/mscorlib/src/System/Threading/ExecutionContext.cs
index 0440368608..5ea9942f65 100644
--- a/src/mscorlib/src/System/Threading/ExecutionContext.cs
+++ b/src/mscorlib/src/System/Threading/ExecutionContext.cs
@@ -14,33 +14,22 @@ namespace System.Threading
using System;
using System.Security;
using System.Runtime.Remoting;
-#if FEATURE_IMPERSONATION
- using System.Security.Principal;
-#endif
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.ExceptionServices;
using System.Runtime.Serialization;
using System.Security.Permissions;
-#if FEATURE_REMOTING
- using System.Runtime.Remoting.Messaging;
-#endif // FEATURE_REMOTING
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Diagnostics.CodeAnalysis;
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
[System.Runtime.InteropServices.ComVisible(true)]
public delegate void ContextCallback(Object state);
-#if FEATURE_CORECLR
-
- [SecurityCritical]
internal struct ExecutionContextSwitcher
{
internal ExecutionContext m_ec;
@@ -48,7 +37,7 @@ namespace System.Threading
internal void Undo(Thread currentThread)
{
- Contract.Assert(currentThread == 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)
@@ -63,32 +52,108 @@ namespace System.Threading
}
}
- public sealed class ExecutionContext : IDisposable
+ [Serializable]
+ public sealed class ExecutionContext : IDisposable, ISerializable
{
private static readonly ExecutionContext Default = new ExecutionContext();
- private readonly Dictionary<IAsyncLocal, object> m_localValues;
+ private readonly IAsyncLocalValueMap m_localValues;
private readonly IAsyncLocal[] m_localChangeNotifications;
+ private readonly bool m_isFlowSuppressed;
private ExecutionContext()
{
- m_localValues = new Dictionary<IAsyncLocal, object>();
+ m_localValues = AsyncLocalValueMap.Empty;
m_localChangeNotifications = Array.Empty<IAsyncLocal>();
}
- private ExecutionContext(Dictionary<IAsyncLocal, object> localValues, IAsyncLocal[] localChangeNotifications)
+ 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)
+ {
}
- [SecuritySafeCritical]
public static ExecutionContext Capture()
{
- return Thread.CurrentThread.ExecutionContext ?? ExecutionContext.Default;
+ ExecutionContext executionContext = Thread.CurrentThread.ExecutionContext;
+ if (executionContext == null)
+ {
+ return Default;
+ }
+ if (executionContext.m_isFlowSuppressed)
+ {
+ // Prevent ExecutionContext.Run on a suppressed-flow context for desktop framework compatibility
+ return null;
+ }
+ return 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;
}
- [SecurityCritical]
[HandleProcessCorruptedStateExceptions]
public static void Run(ExecutionContext executionContext, ContextCallback callback, Object state)
{
@@ -115,10 +180,9 @@ namespace System.Threading
ecsw.Undo(currentThread);
}
- [SecurityCritical]
internal static void Restore(Thread currentThread, ExecutionContext executionContext)
{
- Contract.Assert(currentThread == Thread.CurrentThread);
+ Debug.Assert(currentThread == Thread.CurrentThread);
ExecutionContext previous = currentThread.ExecutionContext ?? Default;
currentThread.ExecutionContext = executionContext;
@@ -133,22 +197,20 @@ namespace System.Threading
}
}
- [SecurityCritical]
static internal void EstablishCopyOnWriteScope(Thread currentThread, ref ExecutionContextSwitcher ecsw)
{
- Contract.Assert(currentThread == Thread.CurrentThread);
+ Debug.Assert(currentThread == Thread.CurrentThread);
ecsw.m_ec = currentThread.ExecutionContext;
ecsw.m_sc = currentThread.SynchronizationContext;
}
- [SecurityCritical]
[HandleProcessCorruptedStateExceptions]
private static void OnContextChanged(ExecutionContext previous, ExecutionContext current)
{
- Contract.Assert(previous != null);
- Contract.Assert(current != null);
- Contract.Assert(previous != current);
+ Debug.Assert(previous != null);
+ Debug.Assert(current != null);
+ Debug.Assert(previous != current);
foreach (IAsyncLocal local in previous.m_localChangeNotifications)
{
@@ -189,7 +251,6 @@ namespace System.Threading
}
}
- [SecurityCritical]
internal static object GetLocalValue(IAsyncLocal local)
{
ExecutionContext current = Thread.CurrentThread.ExecutionContext;
@@ -201,7 +262,6 @@ namespace System.Threading
return value;
}
- [SecurityCritical]
internal static void SetLocalValue(IAsyncLocal local, object newValue, bool needChangeNotifications)
{
ExecutionContext current = Thread.CurrentThread.ExecutionContext ?? ExecutionContext.Default;
@@ -212,16 +272,7 @@ namespace System.Threading
if (previousValue == newValue)
return;
- //
- // Allocate a new Dictionary containing a copy of the old values, plus the new value. We have to do this manually to
- // minimize allocations of IEnumerators, etc.
- //
- Dictionary<IAsyncLocal, object> newValues = new Dictionary<IAsyncLocal, object>(current.m_localValues.Count + (hadPreviousValue ? 0 : 1));
-
- foreach (KeyValuePair<IAsyncLocal, object> pair in current.m_localValues)
- newValues.Add(pair.Key, pair.Value);
-
- newValues[local] = newValue;
+ 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.
@@ -231,7 +282,7 @@ namespace System.Threading
{
if (hadPreviousValue)
{
- Contract.Assert(Array.IndexOf(newChangeNotifications, local) >= 0);
+ Debug.Assert(Array.IndexOf(newChangeNotifications, local) >= 0);
}
else
{
@@ -241,7 +292,8 @@ namespace System.Threading
}
}
- Thread.CurrentThread.ExecutionContext = new ExecutionContext(newValues, newChangeNotifications);
+ Thread.CurrentThread.ExecutionContext =
+ new ExecutionContext(newValues, newChangeNotifications, current.m_isFlowSuppressed);
if (needChangeNotifications)
{
@@ -259,33 +311,28 @@ namespace System.Threading
OptimizeDefaultCase = 0x02,
}
- [SecurityCritical]
internal static ExecutionContext Capture(ref StackCrawlMark stackMark, CaptureOptions captureOptions)
{
return Capture();
}
- [SecuritySafeCritical]
[FriendAccessAllowed]
internal static ExecutionContext FastCapture()
{
return Capture();
}
- [SecurityCritical]
[FriendAccessAllowed]
internal static void Run(ExecutionContext executionContext, ContextCallback callback, Object state, bool preserveSyncCtx)
{
Run(executionContext, callback, state);
}
- [SecurityCritical]
internal bool IsDefaultFTContext(bool ignoreSyncCtx)
{
return this == Default;
}
- [SecuritySafeCritical]
public ExecutionContext CreateCopy()
{
return this; // since CoreCLR's ExecutionContext is immutable, we don't need to create copies.
@@ -296,14 +343,8 @@ namespace System.Threading
// For CLR compat only
}
- public static bool IsFlowSuppressed()
- {
- return false;
- }
-
internal static ExecutionContext PreAllocatedDefault
{
- [SecuritySafeCritical]
get { return ExecutionContext.Default; }
}
@@ -315,1084 +356,77 @@ namespace System.Threading
#endregion
}
-#else // FEATURE_CORECLR
-
- // Legacy desktop ExecutionContext implementation
-
- internal struct ExecutionContextSwitcher
+ public struct AsyncFlowControl : IDisposable
{
- internal ExecutionContext.Reader outerEC; // previous EC we need to restore on Undo
- internal bool outerECBelongsToScope;
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
- internal SecurityContextSwitcher scsw;
-#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
- internal Object hecsw;
-#if FEATURE_IMPERSONATION
- internal WindowsIdentity wi;
- internal bool cachedAlwaysFlowImpersonationPolicy;
- internal bool wiIsValid;
-#endif
- internal Thread thread;
-
- [System.Security.SecurityCritical] // auto-generated
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
-#if FEATURE_CORRUPTING_EXCEPTIONS
- [HandleProcessCorruptedStateExceptions]
-#endif // FEATURE_CORRUPTING_EXCEPTIONS
- internal bool UndoNoThrow(Thread currentThread)
- {
- try
- {
- Undo(currentThread);
- }
- catch
- {
- return false;
- }
- return true;
- }
-
- [System.Security.SecurityCritical] // auto-generated
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
- internal void Undo(Thread currentThread)
- {
- //
- // Don't use an uninitialized switcher, or one that's already been used.
- //
- if (thread == null)
- return; // Don't do anything
-
- Contract.Assert(Thread.CurrentThread == this.thread);
-
- //
- // Restore the HostExecutionContext before restoring the ExecutionContext.
- //
-#if FEATURE_CAS_POLICY
- if (hecsw != null)
- HostExecutionContextSwitcher.Undo(hecsw);
-#endif // FEATURE_CAS_POLICY
-
- //
- // restore the saved Execution Context. Note that this will also restore the
- // SynchronizationContext, Logical/IllogicalCallContext, etc.
- //
- ExecutionContext.Reader innerEC = currentThread.GetExecutionContextReader();
- currentThread.SetExecutionContext(outerEC, outerECBelongsToScope);
-
-#if DEBUG
- try
- {
- currentThread.ForbidExecutionContextMutation = true;
-#endif
-
- //
- // Tell the SecurityContext to do the side-effects of restoration.
- //
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
- if (scsw.currSC != null)
- {
- // Any critical failure inside scsw will cause FailFast
- scsw.Undo();
- }
-#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
-
-#if FEATURE_IMPERSONATION
- if (wiIsValid)
- SecurityContext.RestoreCurrentWI(outerEC, innerEC, wi, cachedAlwaysFlowImpersonationPolicy);
-#endif
-
- thread = null; // this will prevent the switcher object being used again
-#if DEBUG
- }
- finally
- {
- currentThread.ForbidExecutionContextMutation = false;
- }
-#endif
- ExecutionContext.OnAsyncLocalContextChanged(innerEC.DangerousGetRawExecutionContext(), outerEC.DangerousGetRawExecutionContext());
- }
- }
-
-
- public struct AsyncFlowControl: IDisposable
- {
- private bool useEC;
- private ExecutionContext _ec;
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
- private SecurityContext _sc;
-#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
private Thread _thread;
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
- [SecurityCritical]
- internal void Setup(SecurityContextDisableFlow flags)
- {
- useEC = false;
- Thread currentThread = Thread.CurrentThread;
- _sc = currentThread.GetMutableExecutionContext().SecurityContext;
- _sc._disableFlow = flags;
- _thread = currentThread;
- }
-#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
- [SecurityCritical]
- internal void Setup()
+
+ internal void Initialize(Thread currentThread)
{
- useEC = true;
- Thread currentThread = Thread.CurrentThread;
- _ec = currentThread.GetMutableExecutionContext();
- _ec.isFlowSuppressed = true;
+ Debug.Assert(currentThread == Thread.CurrentThread);
_thread = currentThread;
}
-
- public void Dispose()
- {
- Undo();
- }
-
- [SecuritySafeCritical]
+
public void Undo()
{
if (_thread == null)
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotUseAFCMultiple"));
- }
- if (_thread != Thread.CurrentThread)
- {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotUseAFCOtherThread"));
- }
- if (useEC)
- {
- if (Thread.CurrentThread.GetMutableExecutionContext() != _ec)
- {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_AsyncFlowCtrlCtxMismatch"));
- }
- ExecutionContext.RestoreFlow();
- }
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
- else
- {
- if (!Thread.CurrentThread.GetExecutionContextReader().SecurityContext.IsSame(_sc))
- {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_AsyncFlowCtrlCtxMismatch"));
- }
- SecurityContext.RestoreFlow();
- }
-#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
- _thread = null;
- }
-
- public override int GetHashCode()
- {
- return _thread == null ? ToString().GetHashCode() : _thread.GetHashCode();
- }
-
- public override bool Equals(Object obj)
- {
- if (obj is AsyncFlowControl)
- return Equals((AsyncFlowControl)obj);
- else
- return false;
- }
-
- public bool Equals(AsyncFlowControl obj)
- {
- return obj.useEC == useEC && obj._ec == _ec &&
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
- obj._sc == _sc &&
-#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
- obj._thread == _thread;
- }
-
- public static bool operator ==(AsyncFlowControl a, AsyncFlowControl b)
- {
- return a.Equals(b);
- }
-
- public static bool operator !=(AsyncFlowControl a, AsyncFlowControl b)
- {
- return !(a == b);
- }
-
- }
-
-
-#if FEATURE_SERIALIZATION
- [Serializable]
-#endif
- public sealed class ExecutionContext : IDisposable, ISerializable
- {
- /*=========================================================================
- ** Data accessed from managed code that needs to be defined in
- ** ExecutionContextObject to maintain alignment between the two classes.
- ** DON'T CHANGE THESE UNLESS YOU MODIFY ExecutionContextObject in vm\object.h
- =========================================================================*/
-#if FEATURE_CAS_POLICY
- private HostExecutionContext _hostExecutionContext;
-#endif // FEATURE_CAS_POLICY
- private SynchronizationContext _syncContext;
- private SynchronizationContext _syncContextNoFlow;
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
- private SecurityContext _securityContext;
-#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
-#if FEATURE_REMOTING
- [System.Security.SecurityCritical] // auto-generated
- private LogicalCallContext _logicalCallContext;
- private IllogicalCallContext _illogicalCallContext; // this call context follows the physical thread
-#endif // #if FEATURE_REMOTING
-
- enum Flags
- {
- None = 0x0,
- IsNewCapture = 0x1,
- IsFlowSuppressed = 0x2,
- IsPreAllocatedDefault = 0x4
- }
- private Flags _flags;
-
- private Dictionary<IAsyncLocal, object> _localValues;
- private List<IAsyncLocal> _localChangeNotifications;
-
- internal bool isNewCapture
- {
- get
- {
- return (_flags & (Flags.IsNewCapture | Flags.IsPreAllocatedDefault)) != Flags.None;
- }
- set
- {
- Contract.Assert(!IsPreAllocatedDefault);
- if (value)
- _flags |= Flags.IsNewCapture;
- else
- _flags &= ~Flags.IsNewCapture;
- }
- }
- internal bool isFlowSuppressed
- {
- get
- {
- return (_flags & Flags.IsFlowSuppressed) != Flags.None;
- }
- set
- {
- Contract.Assert(!IsPreAllocatedDefault);
- if (value)
- _flags |= Flags.IsFlowSuppressed;
- else
- _flags &= ~Flags.IsFlowSuppressed;
- }
- }
-
-
- private static readonly ExecutionContext s_dummyDefaultEC = new ExecutionContext(isPreAllocatedDefault: true);
-
- static internal ExecutionContext PreAllocatedDefault
- {
- [SecuritySafeCritical]
- get { return s_dummyDefaultEC; }
- }
-
- internal bool IsPreAllocatedDefault
- {
- get
- {
- // we use _flags instead of a direct comparison w/ s_dummyDefaultEC to avoid the static access on
- // hot code paths.
- if ((_flags & Flags.IsPreAllocatedDefault) != Flags.None)
- {
- Contract.Assert(this == s_dummyDefaultEC);
- return true;
- }
- else
- {
- return false;
- }
- }
- }
-
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- internal ExecutionContext()
- {
- }
-
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- internal ExecutionContext(bool isPreAllocatedDefault)
- {
- if (isPreAllocatedDefault)
- _flags = Flags.IsPreAllocatedDefault;
- }
-
- // Read-only wrapper around ExecutionContext. This enables safe reading of an ExecutionContext without accidentally modifying it.
- internal struct Reader
- {
- ExecutionContext m_ec;
-
- public Reader(ExecutionContext ec) { m_ec = ec; }
-
- public ExecutionContext DangerousGetRawExecutionContext() { return m_ec; }
-
- public bool IsNull { get { return m_ec == null; } }
- [SecurityCritical]
- public bool IsDefaultFTContext(bool ignoreSyncCtx) { return m_ec.IsDefaultFTContext(ignoreSyncCtx); }
- public bool IsFlowSuppressed
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get { return IsNull ? false : m_ec.isFlowSuppressed; }
- }
- //public Thread Thread { get { return m_ec._thread; } }
- public bool IsSame(ExecutionContext.Reader other) { return m_ec == other.m_ec; }
-
- public SynchronizationContext SynchronizationContext { get { return IsNull ? null : m_ec.SynchronizationContext; } }
- public SynchronizationContext SynchronizationContextNoFlow { get { return IsNull ? null : m_ec.SynchronizationContextNoFlow; } }
-
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
- public SecurityContext.Reader SecurityContext
- {
- [SecurityCritical]
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get { return new SecurityContext.Reader(IsNull ? null : m_ec.SecurityContext); }
- }
-#endif
-
-#if FEATURE_REMOTING
- public LogicalCallContext.Reader LogicalCallContext
- {
- [SecurityCritical]
- get { return new LogicalCallContext.Reader(IsNull ? null : m_ec.LogicalCallContext); }
- }
-
- public IllogicalCallContext.Reader IllogicalCallContext
- {
- [SecurityCritical]
- get { return new IllogicalCallContext.Reader(IsNull ? null : m_ec.IllogicalCallContext); }
- }
-#endif
-
- [SecurityCritical]
- public object GetLocalValue(IAsyncLocal local)
- {
- if (IsNull)
- return null;
-
- if (m_ec._localValues == null)
- return null;
-
- object value;
- m_ec._localValues.TryGetValue(local, out value);
- return value;
- }
-
- [SecurityCritical]
- public bool HasSameLocalValues(ExecutionContext other)
- {
- var thisLocalValues = IsNull ? null : m_ec._localValues;
- var otherLocalValues = other == null ? null : other._localValues;
- return thisLocalValues == otherLocalValues;
- }
-
- [SecurityCritical]
- public bool HasLocalValues()
- {
- return !this.IsNull && m_ec._localValues != null;
- }
- }
-
- [SecurityCritical]
- internal static object GetLocalValue(IAsyncLocal local)
- {
- return Thread.CurrentThread.GetExecutionContextReader().GetLocalValue(local);
- }
-
- [SecurityCritical]
- internal static void SetLocalValue(IAsyncLocal local, object newValue, bool needChangeNotifications)
- {
- ExecutionContext current = Thread.CurrentThread.GetMutableExecutionContext();
-
- object previousValue = null;
- bool hadPreviousValue = current._localValues != null && current._localValues.TryGetValue(local, out previousValue);
-
- if (previousValue == newValue)
- return;
-
- if (current._localValues == null)
- current._localValues = new Dictionary<IAsyncLocal, object>();
- else
- current._localValues = new Dictionary<IAsyncLocal, object>(current._localValues);
-
- current._localValues[local] = newValue;
-
- if (needChangeNotifications)
- {
- if (hadPreviousValue)
- {
- Contract.Assert(current._localChangeNotifications != null);
- Contract.Assert(current._localChangeNotifications.Contains(local));
- }
- else
- {
- if (current._localChangeNotifications == null)
- current._localChangeNotifications = new List<IAsyncLocal>();
- else
- current._localChangeNotifications = new List<IAsyncLocal>(current._localChangeNotifications);
-
- current._localChangeNotifications.Add(local);
- }
-
- local.OnValueChanged(previousValue, newValue, false);
- }
- }
-
- [SecurityCritical]
- [HandleProcessCorruptedStateExceptions]
- internal static void OnAsyncLocalContextChanged(ExecutionContext previous, ExecutionContext current)
- {
- List<IAsyncLocal> previousLocalChangeNotifications = (previous == null) ? null : previous._localChangeNotifications;
- if (previousLocalChangeNotifications != null)
- {
- foreach (IAsyncLocal local in previousLocalChangeNotifications)
- {
- object previousValue = null;
- if (previous != null && previous._localValues != null)
- previous._localValues.TryGetValue(local, out previousValue);
-
- object currentValue = null;
- if (current != null && current._localValues != null)
- current._localValues.TryGetValue(local, out currentValue);
-
- if (previousValue != currentValue)
- local.OnValueChanged(previousValue, currentValue, true);
- }
- }
-
- List<IAsyncLocal> currentLocalChangeNotifications = (current == null) ? null : current._localChangeNotifications;
- if (currentLocalChangeNotifications != null && currentLocalChangeNotifications != previousLocalChangeNotifications)
- {
- try
- {
- foreach (IAsyncLocal local in currentLocalChangeNotifications)
- {
- // If the local has a value in the previous context, we already fired the event for that local
- // in the code above.
- object previousValue = null;
- if (previous == null ||
- previous._localValues == null ||
- !previous._localValues.TryGetValue(local, out previousValue))
- {
- object currentValue = null;
- if (current != null && current._localValues != null)
- current._localValues.TryGetValue(local, out currentValue);
-
- if (previousValue != currentValue)
- local.OnValueChanged(previousValue, currentValue, true);
- }
- }
- }
- catch (Exception ex)
- {
- Environment.FailFast(
- Environment.GetResourceString("ExecutionContext_ExceptionInAsyncLocalNotification"),
- ex);
- }
- }
- }
-
-
-#if FEATURE_REMOTING
- internal LogicalCallContext LogicalCallContext
- {
- [System.Security.SecurityCritical] // auto-generated
- get
- {
- if (_logicalCallContext == null)
- {
- _logicalCallContext = new LogicalCallContext();
- }
- return _logicalCallContext;
- }
- [System.Security.SecurityCritical] // auto-generated
- set
- {
- Contract.Assert(this != s_dummyDefaultEC);
- _logicalCallContext = value;
- }
- }
-
- internal IllogicalCallContext IllogicalCallContext
- {
- get
- {
- if (_illogicalCallContext == null)
- {
- _illogicalCallContext = new IllogicalCallContext();
- }
- return _illogicalCallContext;
- }
- set
- {
- Contract.Assert(this != s_dummyDefaultEC);
- _illogicalCallContext = value;
- }
- }
-#endif // #if FEATURE_REMOTING
-
- internal SynchronizationContext SynchronizationContext
- {
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- get
- {
- return _syncContext;
- }
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- set
- {
- Contract.Assert(this != s_dummyDefaultEC);
- _syncContext = value;
- }
- }
-
- internal SynchronizationContext SynchronizationContextNoFlow
- {
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- get
- {
- return _syncContextNoFlow;
- }
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- set
- {
- Contract.Assert(this != s_dummyDefaultEC);
- _syncContextNoFlow = value;
- }
- }
-
-#if FEATURE_CAS_POLICY
- internal HostExecutionContext HostExecutionContext
- {
- get
- {
- return _hostExecutionContext;
}
- set
+ if (Thread.CurrentThread != _thread)
{
- Contract.Assert(this != s_dummyDefaultEC);
- _hostExecutionContext = value;
- }
- }
-#endif // FEATURE_CAS_POLICY
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
- internal SecurityContext SecurityContext
- {
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- get
- {
- return _securityContext;
- }
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- set
- {
- Contract.Assert(this != s_dummyDefaultEC);
- // store the new security context
- _securityContext = value;
- // perform the reverse link too
- if (value != null)
- _securityContext.ExecutionContext = this;
- }
- }
-#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
-
-
- public void Dispose()
- {
- if(this.IsPreAllocatedDefault)
- return; //Do nothing if this is the default context
-#if FEATURE_CAS_POLICY
- if (_hostExecutionContext != null)
- _hostExecutionContext.Dispose();
-#endif // FEATURE_CAS_POLICY
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
- if (_securityContext != null)
- _securityContext.Dispose();
-#endif //FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
- }
-
- [DynamicSecurityMethod]
- [System.Security.SecurityCritical] // auto-generated_required
- public static void Run(ExecutionContext executionContext, ContextCallback callback, Object state)
- {
- if (executionContext == null)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NullContext"));
- if (!executionContext.isNewCapture)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotNewCaptureContext"));
-
- Run(executionContext, callback, state, false);
- }
-
- // This method is special from a security perspective - the VM will not allow a stack walk to
- // continue past the call to ExecutionContext.Run. If you change the signature to this method, make
- // sure to update SecurityStackWalk::IsSpecialRunFrame in the VM to search for the new signature.
- [DynamicSecurityMethod]
- [SecurityCritical]
- [FriendAccessAllowed]
- internal static void Run(ExecutionContext executionContext, ContextCallback callback, Object state, bool preserveSyncCtx)
- {
- RunInternal(executionContext, callback, state, preserveSyncCtx);
- }
-
- // Actual implementation of Run is here, in a non-DynamicSecurityMethod, because the JIT seems to refuse to inline callees into
- // a DynamicSecurityMethod.
- [SecurityCritical]
- [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "Reviewed for thread safety")]
- [HandleProcessCorruptedStateExceptions]
- internal static void RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, bool preserveSyncCtx)
- {
- Contract.Assert(executionContext != null);
- if (executionContext.IsPreAllocatedDefault)
- {
- Contract.Assert(executionContext.IsDefaultFTContext(preserveSyncCtx));
- }
- else
- {
- Contract.Assert(executionContext.isNewCapture);
- executionContext.isNewCapture = false;
- }
-
- Thread currentThread = Thread.CurrentThread;
- ExecutionContextSwitcher ecsw = default(ExecutionContextSwitcher);
-
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- ExecutionContext.Reader ec = currentThread.GetExecutionContextReader();
- if ( (ec.IsNull || ec.IsDefaultFTContext(preserveSyncCtx)) &&
- #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
- SecurityContext.CurrentlyInDefaultFTSecurityContext(ec) &&
- #endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
- executionContext.IsDefaultFTContext(preserveSyncCtx) &&
- ec.HasSameLocalValues(executionContext)
- )
- {
- // Neither context is interesting, so we don't need to set the context.
- // We do need to reset any changes made by the user's callback,
- // so here we establish a "copy-on-write scope". Any changes will
- // result in a copy of the context being made, preserving the original
- // context.
- EstablishCopyOnWriteScope(currentThread, true, ref ecsw);
- }
- else
- {
- if (executionContext.IsPreAllocatedDefault)
- executionContext = new ExecutionContext();
- ecsw = SetExecutionContext(executionContext, preserveSyncCtx);
- }
-
- //
- // Call the user's callback
- //
- callback(state);
- }
- finally
- {
- ecsw.Undo(currentThread);
- }
- }
-
- [SecurityCritical]
- static internal void EstablishCopyOnWriteScope(Thread currentThread, ref ExecutionContextSwitcher ecsw)
- {
- EstablishCopyOnWriteScope(currentThread, false, ref ecsw);
- }
-
- [SecurityCritical]
- static private void EstablishCopyOnWriteScope(Thread currentThread, bool knownNullWindowsIdentity, ref ExecutionContextSwitcher ecsw)
- {
- Contract.Assert(currentThread == Thread.CurrentThread);
-
- ecsw.outerEC = currentThread.GetExecutionContextReader();
- ecsw.outerECBelongsToScope = currentThread.ExecutionContextBelongsToCurrentScope;
-
-#if FEATURE_IMPERSONATION
- ecsw.cachedAlwaysFlowImpersonationPolicy = SecurityContext.AlwaysFlowImpersonationPolicy;
- if (knownNullWindowsIdentity)
- Contract.Assert(SecurityContext.GetCurrentWI(ecsw.outerEC, ecsw.cachedAlwaysFlowImpersonationPolicy) == null);
- else
- ecsw.wi = SecurityContext.GetCurrentWI(ecsw.outerEC, ecsw.cachedAlwaysFlowImpersonationPolicy);
- ecsw.wiIsValid = true;
-#endif
- currentThread.ExecutionContextBelongsToCurrentScope = false;
- ecsw.thread = currentThread;
- }
-
-
- // Sets the given execution context object on the thread.
- // Returns the previous one.
- [System.Security.SecurityCritical] // auto-generated
- [DynamicSecurityMethodAttribute()]
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
-#if FEATURE_CORRUPTING_EXCEPTIONS
- [HandleProcessCorruptedStateExceptions]
-#endif // FEATURE_CORRUPTING_EXCEPTIONS
- internal static ExecutionContextSwitcher SetExecutionContext(ExecutionContext executionContext, bool preserveSyncCtx)
- {
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
-#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
-
- Contract.Assert(executionContext != null);
- Contract.Assert(executionContext != s_dummyDefaultEC);
-
- // Set up the switcher object to return;
- ExecutionContextSwitcher ecsw = new ExecutionContextSwitcher();
-
- Thread currentThread = Thread.CurrentThread;
- ExecutionContext.Reader outerEC = currentThread.GetExecutionContextReader();
-
- ecsw.thread = currentThread;
- ecsw.outerEC = outerEC;
- ecsw.outerECBelongsToScope = currentThread.ExecutionContextBelongsToCurrentScope;
-
- if (preserveSyncCtx)
- executionContext.SynchronizationContext = outerEC.SynchronizationContext;
- executionContext.SynchronizationContextNoFlow = outerEC.SynchronizationContextNoFlow;
-
- currentThread.SetExecutionContext(executionContext, belongsToCurrentScope: true);
-
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- OnAsyncLocalContextChanged(outerEC.DangerousGetRawExecutionContext(), executionContext);
-
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
- //set the security context
- SecurityContext sc = executionContext.SecurityContext;
- if (sc != null)
- {
- // non-null SC: needs to be set
- SecurityContext.Reader prevSeC = outerEC.SecurityContext;
- ecsw.scsw = SecurityContext.SetSecurityContext(sc, prevSeC, false, ref stackMark);
- }
- else if (!SecurityContext.CurrentlyInDefaultFTSecurityContext(ecsw.outerEC))
- {
- // null incoming SC, but we're currently not in FT: use static FTSC to set
- SecurityContext.Reader prevSeC = outerEC.SecurityContext;
- ecsw.scsw = SecurityContext.SetSecurityContext(SecurityContext.FullTrustSecurityContext, prevSeC, false, ref stackMark);
- }
-#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
-#if FEATURE_CAS_POLICY
- // set the Host Context
- HostExecutionContext hostContext = executionContext.HostExecutionContext;
- if (hostContext != null)
- {
- ecsw.hecsw = HostExecutionContextManager.SetHostExecutionContextInternal(hostContext);
- }
-#endif // FEATURE_CAS_POLICY
- }
- catch
- {
- ecsw.UndoNoThrow(currentThread);
- throw;
- }
- return ecsw;
- }
-
- //
- // Public CreateCopy. Used to copy captured ExecutionContexts so they can be reused multiple times.
- // This should only copy the portion of the context that we actually capture.
- //
- [SecuritySafeCritical]
- public ExecutionContext CreateCopy()
- {
- if (!isNewCapture)
- {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotCopyUsedContext"));
- }
- ExecutionContext ec = new ExecutionContext();
- ec.isNewCapture = true;
- ec._syncContext = _syncContext == null ? null : _syncContext.CreateCopy();
- ec._localValues = _localValues;
- ec._localChangeNotifications = _localChangeNotifications;
-#if FEATURE_CAS_POLICY
- // capture the host execution context
- ec._hostExecutionContext = _hostExecutionContext == null ? null : _hostExecutionContext.CreateCopy();
-#endif // FEATURE_CAS_POLICY
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
- if (_securityContext != null)
- {
- ec._securityContext = _securityContext.CreateCopy();
- ec._securityContext.ExecutionContext = ec;
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotUseAFCOtherThread"));
}
-#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
-
-#if FEATURE_REMOTING
- if (this._logicalCallContext != null)
- ec.LogicalCallContext = (LogicalCallContext)this.LogicalCallContext.Clone();
-
- Contract.Assert(this._illogicalCallContext == null);
-#endif // #if FEATURE_REMOTING
-
- return ec;
- }
-
- //
- // Creates a complete copy, used for copy-on-write.
- //
- [SecuritySafeCritical]
- internal ExecutionContext CreateMutableCopy()
- {
- Contract.Assert(!this.isNewCapture);
-
- ExecutionContext ec = new ExecutionContext();
- // We don't deep-copy the SyncCtx, since we're still in the same context after copy-on-write.
- ec._syncContext = this._syncContext;
- ec._syncContextNoFlow = this._syncContextNoFlow;
-
-#if FEATURE_CAS_POLICY
- // capture the host execution context
- ec._hostExecutionContext = this._hostExecutionContext == null ? null : _hostExecutionContext.CreateCopy();
-#endif // FEATURE_CAS_POLICY
-
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
- if (_securityContext != null)
+ // 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())
{
- ec._securityContext = this._securityContext.CreateMutableCopy();
- ec._securityContext.ExecutionContext = ec;
- }
-#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
-
-#if FEATURE_REMOTING
- if (this._logicalCallContext != null)
- ec.LogicalCallContext = (LogicalCallContext)this.LogicalCallContext.Clone();
-
- if (this._illogicalCallContext != null)
- ec.IllogicalCallContext = (IllogicalCallContext)this.IllogicalCallContext.CreateCopy();
-#endif // #if FEATURE_REMOTING
-
- ec._localValues = this._localValues;
- ec._localChangeNotifications = this._localChangeNotifications;
- ec.isFlowSuppressed = this.isFlowSuppressed;
-
- return ec;
- }
-
- [System.Security.SecurityCritical] // auto-generated_required
- public static AsyncFlowControl SuppressFlow()
- {
- if (IsFlowSuppressed())
- {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotSupressFlowMultipleTimes"));
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_AsyncFlowCtrlCtxMismatch"));
}
Contract.EndContractBlock();
- AsyncFlowControl afc = new AsyncFlowControl();
- afc.Setup();
- return afc;
- }
-
- [SecuritySafeCritical]
- public static void RestoreFlow()
- {
- ExecutionContext ec = Thread.CurrentThread.GetMutableExecutionContext();
- if (!ec.isFlowSuppressed)
- {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotRestoreUnsupressedFlow"));
- }
- ec.isFlowSuppressed = false;
- }
- [Pure]
- public static bool IsFlowSuppressed()
- {
- return Thread.CurrentThread.GetExecutionContextReader().IsFlowSuppressed;
+ _thread = null;
+ ExecutionContext.RestoreFlow();
}
- [System.Security.SecuritySafeCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public static ExecutionContext Capture()
+ public void Dispose()
{
- // set up a stack mark for finding the caller
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return ExecutionContext.Capture(ref stackMark, CaptureOptions.None);
+ Undo();
}
- //
- // Captures an ExecutionContext with optimization for the "default" case, and captures a "null" synchronization context.
- // When calling ExecutionContext.Run on the returned context, specify ignoreSyncCtx = true
- //
- [System.Security.SecuritySafeCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- [FriendAccessAllowed]
- internal static ExecutionContext FastCapture()
+ public override bool Equals(object obj)
{
- // set up a stack mark for finding the caller
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return ExecutionContext.Capture(ref stackMark, CaptureOptions.IgnoreSyncCtx | CaptureOptions.OptimizeDefaultCase);
+ return obj is AsyncFlowControl && Equals((AsyncFlowControl)obj);
}
-
- [Flags]
- internal enum CaptureOptions
+ public bool Equals(AsyncFlowControl obj)
{
- None = 0x00,
-
- IgnoreSyncCtx = 0x01, //Don't flow SynchronizationContext
-
- OptimizeDefaultCase = 0x02, //Faster in the typical case, but can't show the result to users
- // because they could modify the shared default EC.
- // Use this only if you won't be exposing the captured EC to users.
+ return _thread == obj._thread;
}
- // internal helper to capture the current execution context using a passed in stack mark
- [System.Security.SecurityCritical] // auto-generated
- static internal ExecutionContext Capture(ref StackCrawlMark stackMark, CaptureOptions options)
+ public override int GetHashCode()
{
- ExecutionContext.Reader ecCurrent = Thread.CurrentThread.GetExecutionContextReader();
-
- // check to see if Flow is suppressed
- if (ecCurrent.IsFlowSuppressed)
- return null;
-
- //
- // Attempt to capture context. There may be nothing to capture...
- //
-
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
- // capture the security context
- SecurityContext secCtxNew = SecurityContext.Capture(ecCurrent, ref stackMark);
-#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
-#if FEATURE_CAS_POLICY
- // capture the host execution context
- HostExecutionContext hostCtxNew = HostExecutionContextManager.CaptureHostExecutionContext();
-#endif // FEATURE_CAS_POLICY
-
- SynchronizationContext syncCtxNew = null;
-
-#if FEATURE_REMOTING
- LogicalCallContext logCtxNew = null;
-#endif
-
- if (!ecCurrent.IsNull)
- {
- // capture the sync context
- if (0 == (options & CaptureOptions.IgnoreSyncCtx))
- syncCtxNew = (ecCurrent.SynchronizationContext == null) ? null : ecCurrent.SynchronizationContext.CreateCopy();
-
-#if FEATURE_REMOTING
- // copy over the Logical Call Context
- if (ecCurrent.LogicalCallContext.HasInfo)
- logCtxNew = ecCurrent.LogicalCallContext.Clone();
-#endif // #if FEATURE_REMOTING
- }
-
- Dictionary<IAsyncLocal, object> localValues = null;
- List<IAsyncLocal> localChangeNotifications = null;
- if (!ecCurrent.IsNull)
- {
- localValues = ecCurrent.DangerousGetRawExecutionContext()._localValues;
- localChangeNotifications = ecCurrent.DangerousGetRawExecutionContext()._localChangeNotifications;
- }
-
- //
- // If we didn't get anything but defaults, and we're allowed to return the
- // dummy default EC, don't bother allocating a new context.
- //
- if (0 != (options & CaptureOptions.OptimizeDefaultCase) &&
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
- secCtxNew == null &&
-#endif
-#if FEATURE_CAS_POLICY
- hostCtxNew == null &&
-#endif // FEATURE_CAS_POLICY
- syncCtxNew == null &&
-#if FEATURE_REMOTING
- (logCtxNew == null || !logCtxNew.HasInfo) &&
-#endif // #if FEATURE_REMOTING
- localValues == null &&
- localChangeNotifications == null
- )
- {
- return s_dummyDefaultEC;
- }
-
- //
- // Allocate the new context, and fill it in.
- //
- ExecutionContext ecNew = new ExecutionContext();
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
- ecNew.SecurityContext = secCtxNew;
- if (ecNew.SecurityContext != null)
- ecNew.SecurityContext.ExecutionContext = ecNew;
-#endif
-#if FEATURE_CAS_POLICY
- ecNew._hostExecutionContext = hostCtxNew;
-#endif // FEATURE_CAS_POLICY
- ecNew._syncContext = syncCtxNew;
-#if FEATURE_REMOTING
- ecNew.LogicalCallContext = logCtxNew;
-#endif // #if FEATURE_REMOTING
- ecNew._localValues = localValues;
- ecNew._localChangeNotifications = localChangeNotifications;
- ecNew.isNewCapture = true;
-
- return ecNew;
+ return _thread?.GetHashCode() ?? 0;
}
- //
- // Implementation of ISerializable
- //
-
- [System.Security.SecurityCritical] // auto-generated_required
- public void GetObjectData(SerializationInfo info, StreamingContext context)
+ public static bool operator ==(AsyncFlowControl a, AsyncFlowControl b)
{
- if (info==null)
- throw new ArgumentNullException("info");
- Contract.EndContractBlock();
-
-#if FEATURE_REMOTING
- if (_logicalCallContext != null)
- {
- info.AddValue("LogicalCallContext", _logicalCallContext, typeof(LogicalCallContext));
- }
-#endif // #if FEATURE_REMOTING
+ return a.Equals(b);
}
- [System.Security.SecurityCritical] // auto-generated
- private ExecutionContext(SerializationInfo info, StreamingContext context)
- {
- SerializationInfoEnumerator e = info.GetEnumerator();
- while (e.MoveNext())
- {
-#if FEATURE_REMOTING
- if (e.Name.Equals("LogicalCallContext"))
- {
- _logicalCallContext = (LogicalCallContext) e.Value;
- }
-#endif // #if FEATURE_REMOTING
- }
- } // ObjRef .ctor
-
-
- [System.Security.SecurityCritical] // auto-generated
- internal bool IsDefaultFTContext(bool ignoreSyncCtx)
+ public static bool operator !=(AsyncFlowControl a, AsyncFlowControl b)
{
-#if FEATURE_CAS_POLICY
- if (_hostExecutionContext != null)
- return false;
-#endif // FEATURE_CAS_POLICY
- if (!ignoreSyncCtx && _syncContext != null)
- return false;
-#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
- if (_securityContext != null && !_securityContext.IsDefaultFTSecurityContext())
- return false;
-#endif //#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
-#if FEATURE_REMOTING
- if (_logicalCallContext != null && _logicalCallContext.HasInfo)
- return false;
- if (_illogicalCallContext != null && _illogicalCallContext.HasUserData)
- return false;
-#endif //#if FEATURE_REMOTING
- return true;
+ return !(a == b);
}
- } // class ExecutionContext
-
-#endif //FEATURE_CORECLR
+ }
}
diff --git a/src/mscorlib/src/System/Threading/Interlocked.cs b/src/mscorlib/src/System/Threading/Interlocked.cs
index 50cc766d61..8a0b527fc0 100644
--- a/src/mscorlib/src/System/Threading/Interlocked.cs
+++ b/src/mscorlib/src/System/Threading/Interlocked.cs
@@ -66,34 +66,27 @@ namespace System.Threading
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- [System.Security.SecuritySafeCritical]
public static extern int Exchange(ref int location1, int value);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [System.Security.SecuritySafeCritical]
public static extern long Exchange(ref long location1, long value);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [System.Security.SecuritySafeCritical]
public static extern float Exchange(ref float location1, float value);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [System.Security.SecuritySafeCritical]
public static extern double Exchange(ref double location1, double value);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- [System.Security.SecuritySafeCritical]
public static extern Object Exchange(ref Object location1, Object value);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- [System.Security.SecuritySafeCritical]
public static extern IntPtr Exchange(ref IntPtr location1, IntPtr value);
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[System.Runtime.InteropServices.ComVisible(false)]
- [System.Security.SecuritySafeCritical]
public static T Exchange<T>(ref T location1, T value) where T : class
{
_Exchange(__makeref(location1), __makeref(value));
@@ -106,7 +99,6 @@ namespace System.Threading
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- [System.Security.SecuritySafeCritical]
private static extern void _Exchange(TypedReference location1, TypedReference value);
/******************************
@@ -121,29 +113,23 @@ namespace System.Threading
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- [System.Security.SecuritySafeCritical]
public static extern int CompareExchange(ref int location1, int value, int comparand);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [System.Security.SecuritySafeCritical]
public static extern long CompareExchange(ref long location1, long value, long comparand);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [System.Security.SecuritySafeCritical]
public static extern float CompareExchange(ref float location1, float value, float comparand);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [System.Security.SecuritySafeCritical]
public static extern double CompareExchange(ref double location1, double value, double comparand);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- [System.Security.SecuritySafeCritical]
public static extern Object CompareExchange(ref Object location1, Object value, Object comparand);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- [System.Security.SecuritySafeCritical]
public static extern IntPtr CompareExchange(ref IntPtr location1, IntPtr value, IntPtr comparand);
/*****************************************************************
@@ -172,7 +158,6 @@ namespace System.Threading
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[System.Runtime.InteropServices.ComVisible(false)]
- [System.Security.SecuritySafeCritical]
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'
@@ -182,13 +167,11 @@ namespace System.Threading
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- [System.Security.SecuritySafeCritical]
private static extern void _CompareExchange(TypedReference location1, TypedReference value, Object comparand);
// BCL-internal overload that returns success via a ref bool param, useful for reliable spin locks.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- [System.Security.SecuritySafeCritical]
internal static extern int CompareExchange(ref int location1, int value, int comparand, ref bool succeeded);
/******************************
diff --git a/src/mscorlib/src/System/Threading/LazyInitializer.cs b/src/mscorlib/src/System/Threading/LazyInitializer.cs
index c8e74e30e3..238cc89dbd 100644
--- a/src/mscorlib/src/System/Threading/LazyInitializer.cs
+++ b/src/mscorlib/src/System/Threading/LazyInitializer.cs
@@ -12,6 +12,7 @@
using System.Security.Permissions;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
namespace System.Threading
{
@@ -54,7 +55,6 @@ namespace System.Threading
/// These routines avoid needing to allocate a dedicated, lazy-initialization instance, instead using
/// references to ensure targets have been initialized as they are accessed.
/// </remarks>
- [HostProtection(Synchronization = true, ExternalThreading = true)]
public static class LazyInitializer
{
/// <summary>
@@ -149,7 +149,7 @@ namespace System.Threading
}
Interlocked.CompareExchange(ref target, value, null);
- Contract.Assert(target != null);
+ Debug.Assert(target != null);
return target;
}
diff --git a/src/mscorlib/src/System/Threading/LockRecursionException.cs b/src/mscorlib/src/System/Threading/LockRecursionException.cs
index c5e3146cbc..ab95e70c7e 100644
--- a/src/mscorlib/src/System/Threading/LockRecursionException.cs
+++ b/src/mscorlib/src/System/Threading/LockRecursionException.cs
@@ -20,9 +20,6 @@ namespace System.Threading
[Serializable]
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
-#if !FEATURE_CORECLR
- [TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
-#endif
public class LockRecursionException : System.Exception
{
public LockRecursionException() { }
diff --git a/src/mscorlib/src/System/Threading/ManualResetEvent.cs b/src/mscorlib/src/System/Threading/ManualResetEvent.cs
index 504cfb423c..00041567df 100644
--- a/src/mscorlib/src/System/Threading/ManualResetEvent.cs
+++ b/src/mscorlib/src/System/Threading/ManualResetEvent.cs
@@ -17,7 +17,6 @@ namespace System.Threading {
using System.Security.Permissions;
using System.Runtime.InteropServices;
- [HostProtection(Synchronization=true, ExternalThreading=true)]
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class ManualResetEvent : EventWaitHandle
{
diff --git a/src/mscorlib/src/System/Threading/ManualResetEventSlim.cs b/src/mscorlib/src/System/Threading/ManualResetEventSlim.cs
index b6114ef917..509af5bfa0 100644
--- a/src/mscorlib/src/System/Threading/ManualResetEventSlim.cs
+++ b/src/mscorlib/src/System/Threading/ManualResetEventSlim.cs
@@ -13,10 +13,10 @@
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
using System;
-using System.Diagnostics;
using System.Security.Permissions;
using System.Threading;
using System.Runtime.InteropServices;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
namespace System.Threading
@@ -47,7 +47,6 @@ namespace System.Threading
/// </remarks>
[ComVisible(false)]
[DebuggerDisplay("Set = {IsSet}")]
- [HostProtection(Synchronization = true, ExternalThreading = true)]
public class ManualResetEventSlim : IDisposable
{
// These are the default spin counts we use on single-proc and MP machines.
@@ -144,8 +143,8 @@ namespace System.Threading
private set
{
- Contract.Assert(value >= 0, "SpinCount is a restricted-width integer. The value supplied is outside the legal range.");
- Contract.Assert(value <= SpinCountState_MaxValue, "SpinCount is a restricted-width integer. The value supplied is outside the legal range.");
+ Debug.Assert(value >= 0, "SpinCount is a restricted-width integer. The value supplied is outside the legal range.");
+ Debug.Assert(value <= SpinCountState_MaxValue, "SpinCount is a restricted-width integer. The value supplied is outside the legal range.");
// Don't worry about thread safety because it's set one time from the constructor
m_combinedState = (m_combinedState & ~SpinCountState_BitMask) | (value << SpinCountState_ShiftCount);
}
@@ -164,7 +163,7 @@ namespace System.Threading
set
{
//setting to <0 would indicate an internal flaw, hence Assert is appropriate.
- Contract.Assert(value >= 0, "NumWaiters should never be less than zero. This indicates an internal error.");
+ Debug.Assert(value >= 0, "NumWaiters should never be less than zero. This indicates an internal error.");
// 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)
@@ -218,13 +217,13 @@ namespace System.Threading
{
if (spinCount < 0)
{
- throw new ArgumentOutOfRangeException("spinCount");
+ throw new ArgumentOutOfRangeException(nameof(spinCount));
}
if (spinCount > SpinCountState_MaxValue)
{
throw new ArgumentOutOfRangeException(
- "spinCount",
+ nameof(spinCount),
String.Format(Environment.GetResourceString("ManualResetEventSlim_ctor_SpinCountOutOfRange"), SpinCountState_MaxValue));
}
@@ -242,8 +241,8 @@ namespace System.Threading
this.m_combinedState = initialState ? (1 << SignalledState_ShiftCount) : 0;
//the spinCount argument has been validated by the ctors.
//but we now sanity check our predefined constants.
- Contract.Assert(DEFAULT_SPIN_SP >= 0, "Internal error - DEFAULT_SPIN_SP is outside the legal range.");
- Contract.Assert(DEFAULT_SPIN_SP <= SpinCountState_MaxValue, "Internal error - DEFAULT_SPIN_SP is outside the legal range.");
+ 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;
@@ -295,7 +294,7 @@ namespace System.Threading
bool currentIsSet = IsSet;
if (currentIsSet != preInitializeIsSet)
{
- Contract.Assert(currentIsSet,
+ Debug.Assert(currentIsSet,
"The only safe concurrent transition is from unset->set: detected set->unset.");
// We saw it as unsignaled, but it has since become set.
@@ -337,7 +336,7 @@ namespace System.Threading
// If there are waiting threads, we need to pulse them.
if (Waiters > 0)
{
- Contract.Assert(m_lock != null); //if waiters>0, then m_lock has already been created.
+ Debug.Assert(m_lock != null); //if waiters>0, then m_lock has already been created.
lock (m_lock)
{
@@ -464,7 +463,7 @@ namespace System.Threading
long totalMilliseconds = (long)timeout.TotalMilliseconds;
if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue)
{
- throw new ArgumentOutOfRangeException("timeout");
+ throw new ArgumentOutOfRangeException(nameof(timeout));
}
return Wait((int)totalMilliseconds, new CancellationToken());
@@ -495,7 +494,7 @@ namespace System.Threading
long totalMilliseconds = (long)timeout.TotalMilliseconds;
if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue)
{
- throw new ArgumentOutOfRangeException("timeout");
+ throw new ArgumentOutOfRangeException(nameof(timeout));
}
return Wait((int)totalMilliseconds, cancellationToken);
@@ -544,7 +543,7 @@ namespace System.Threading
if (millisecondsTimeout < -1)
{
- throw new ArgumentOutOfRangeException("millisecondsTimeout");
+ throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout));
}
if (!IsSet)
@@ -738,8 +737,8 @@ namespace System.Threading
private static void CancellationTokenCallback(object obj)
{
ManualResetEventSlim mre = obj as ManualResetEventSlim;
- Contract.Assert(mre != null, "Expected a ManualResetEventSlim");
- Contract.Assert(mre.m_lock != null); //the lock should have been created before this callback is registered for use.
+ Debug.Assert(mre != null, "Expected a ManualResetEventSlim");
+ Debug.Assert(mre.m_lock != null); //the lock should have been created before this callback is registered for use.
lock (mre.m_lock)
{
Monitor.PulseAll(mre.m_lock); // awaken all waiters
@@ -759,7 +758,7 @@ namespace System.Threading
{
SpinWait sw = new SpinWait();
- Contract.Assert((newBits | updateBitsMask) == updateBitsMask, "newBits do not fall within the updateBitsMask.");
+ Debug.Assert((newBits | updateBitsMask) == updateBitsMask, "newBits do not fall within the updateBitsMask.");
do
{
diff --git a/src/mscorlib/src/System/Threading/Monitor.cs b/src/mscorlib/src/System/Threading/Monitor.cs
index 415948b425..94dec13d05 100644
--- a/src/mscorlib/src/System/Threading/Monitor.cs
+++ b/src/mscorlib/src/System/Threading/Monitor.cs
@@ -24,9 +24,9 @@ namespace System.Threading {
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
using System.Runtime.Versioning;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
- [HostProtection(Synchronization=true, ExternalThreading=true)]
[System.Runtime.InteropServices.ComVisible(true)]
public static class Monitor
{
@@ -38,7 +38,6 @@ namespace System.Threading {
**
** Exceptions: ArgumentNullException if object is null.
=========================================================================*/
- [System.Security.SecuritySafeCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void Enter(Object obj);
@@ -54,7 +53,7 @@ namespace System.Threading {
ThrowLockTakenException();
ReliableEnter(obj, ref lockTaken);
- Contract.Assert(lockTaken);
+ Debug.Assert(lockTaken);
}
private static void ThrowLockTakenException()
@@ -62,7 +61,6 @@ namespace System.Threading {
throw new ArgumentException(Environment.GetResourceString("Argument_MustBeFalse"), "lockTaken");
}
- [System.Security.SecuritySafeCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void ReliableEnter(Object obj, ref bool lockTaken);
@@ -77,7 +75,6 @@ namespace System.Threading {
** SynchronizationLockException if the current thread does not
** own the lock.
=========================================================================*/
- [System.Security.SecuritySafeCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static extern void Exit(Object obj);
@@ -127,7 +124,7 @@ namespace System.Threading {
{
long tm = (long)timeout.TotalMilliseconds;
if (tm < -1 || tm > (long)Int32.MaxValue)
- throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
return (int)tm;
}
@@ -154,20 +151,17 @@ namespace System.Threading {
ReliableEnterTimeout(obj, MillisecondsTimeoutFromTimeSpan(timeout), ref lockTaken);
}
- [System.Security.SecuritySafeCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void ReliableEnterTimeout(Object obj, int timeout, ref bool lockTaken);
- [System.Security.SecuritySafeCritical]
public static bool IsEntered(object obj)
{
if (obj == null)
- throw new ArgumentNullException("obj");
+ throw new ArgumentNullException(nameof(obj));
return IsEnteredNative(obj);
}
- [System.Security.SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool IsEnteredNative(Object obj);
@@ -182,15 +176,13 @@ namespace System.Threading {
**
** Exceptions: ArgumentNullException if object is null.
========================================================================*/
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool ObjWait(bool exitContext, int millisecondsTimeout, Object obj);
- [System.Security.SecuritySafeCritical] // auto-generated
public static bool Wait(Object obj, int millisecondsTimeout, bool exitContext)
{
if (obj == null)
- throw (new ArgumentNullException("obj"));
+ throw (new ArgumentNullException(nameof(obj)));
return ObjWait(exitContext, millisecondsTimeout, obj);
}
@@ -219,16 +211,14 @@ namespace System.Threading {
* Exceptions: SynchronizationLockException if this method is not called inside
* a synchronized block of code.
========================================================================*/
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void ObjPulse(Object obj);
- [System.Security.SecuritySafeCritical] // auto-generated
public static void Pulse(Object obj)
{
if (obj == null)
{
- throw new ArgumentNullException("obj");
+ throw new ArgumentNullException(nameof(obj));
}
Contract.EndContractBlock();
@@ -237,16 +227,14 @@ namespace System.Threading {
/*========================================================================
** Sends a notification to all waiting objects.
========================================================================*/
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void ObjPulseAll(Object obj);
- [System.Security.SecuritySafeCritical] // auto-generated
public static void PulseAll(Object obj)
{
if (obj == null)
{
- throw new ArgumentNullException("obj");
+ throw new ArgumentNullException(nameof(obj));
}
Contract.EndContractBlock();
diff --git a/src/mscorlib/src/System/Threading/Mutex.cs b/src/mscorlib/src/System/Threading/Mutex.cs
index 2e9b68176d..506abb7a07 100644
--- a/src/mscorlib/src/System/Threading/Mutex.cs
+++ b/src/mscorlib/src/System/Threading/Mutex.cs
@@ -24,31 +24,24 @@ namespace System.Threading
using System.Runtime.ConstrainedExecution;
using System.Runtime.Versioning;
using System.Security;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
-
-#if FEATURE_MACL
- using System.Security.AccessControl;
-#endif
- [HostProtection(Synchronization=true, ExternalThreading=true)]
[ComVisible(true)]
public sealed class Mutex : WaitHandle
{
static bool dummyBool;
-#if !FEATURE_MACL
- public class MutexSecurity {
+ public class MutexSecurity
+ {
}
-#endif
- [System.Security.SecurityCritical] // auto-generated_required
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public Mutex(bool initiallyOwned, String name, out bool createdNew)
: this(initiallyOwned, name, out createdNew, (MutexSecurity)null)
{
}
- [System.Security.SecurityCritical] // auto-generated_required
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public unsafe Mutex(bool initiallyOwned, String name, out bool createdNew, MutexSecurity mutexSecurity)
{
@@ -60,29 +53,15 @@ namespace System.Threading
#if !PLATFORM_UNIX
if (name != null && System.IO.Path.MaxPath < name.Length)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), nameof(name));
}
#endif
Contract.EndContractBlock();
Win32Native.SECURITY_ATTRIBUTES secAttrs = null;
-#if FEATURE_MACL
- // For ACL's, get the security descriptor from the MutexSecurity.
- if (mutexSecurity != null) {
-
- secAttrs = new Win32Native.SECURITY_ATTRIBUTES();
- secAttrs.nLength = (int)Marshal.SizeOf(secAttrs);
-
- byte[] sd = mutexSecurity.GetSecurityDescriptorBinaryForm();
- byte* pSecDescriptor = stackalloc byte[sd.Length];
- Buffer.Memcpy(pSecDescriptor, 0, sd, 0, sd.Length);
- secAttrs.pSecurityDescriptor = pSecDescriptor;
- }
-#endif
CreateMutexWithGuaranteedCleanup(initiallyOwned, name, out createdNew, secAttrs);
}
- [System.Security.SecurityCritical] // auto-generated_required
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal Mutex(bool initiallyOwned, String name, out bool createdNew, Win32Native.SECURITY_ATTRIBUTES secAttrs)
{
@@ -94,7 +73,7 @@ namespace System.Threading
#if !PLATFORM_UNIX
if (name != null && System.IO.Path.MaxPath < name.Length)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), nameof(name));
}
#endif
Contract.EndContractBlock();
@@ -102,7 +81,6 @@ namespace System.Threading
CreateMutexWithGuaranteedCleanup(initiallyOwned, name, out createdNew, secAttrs);
}
- [System.Security.SecurityCritical] // auto-generated_required
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal void CreateMutexWithGuaranteedCleanup(bool initiallyOwned, String name, out bool createdNew, Win32Native.SECURITY_ATTRIBUTES secAttrs)
{
@@ -123,15 +101,13 @@ namespace System.Threading
MutexCleanupInfo m_cleanupInfo;
internal bool m_newMutex;
String m_name;
- [System.Security.SecurityCritical] // auto-generated
Win32Native.SECURITY_ATTRIBUTES m_secAttrs;
Mutex m_mutex;
- [System.Security.SecurityCritical] // auto-generated
[PrePrepareMethod]
internal MutexTryCodeHelper(bool initiallyOwned,MutexCleanupInfo cleanupInfo, String name, Win32Native.SECURITY_ATTRIBUTES secAttrs, Mutex mutex)
{
- Contract.Assert(name == null || name.Length != 0);
+ Debug.Assert(name == null || name.Length != 0);
m_initiallyOwned = initiallyOwned;
m_cleanupInfo = cleanupInfo;
@@ -140,7 +116,6 @@ namespace System.Threading
m_mutex = mutex;
}
- [System.Security.SecurityCritical] // auto-generated
[PrePrepareMethod]
internal void MutexTryCode(object userData)
{
@@ -155,14 +130,10 @@ namespace System.Threading
if (m_initiallyOwned)
{
m_cleanupInfo.inCriticalRegion = true;
-#if !FEATURE_CORECLR
- Thread.BeginThreadAffinity();
- Thread.BeginCriticalRegion();
-#endif //!FEATURE_CORECLR
}
}
- int errorCode = 0;
+ int errorCode = 0;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
@@ -182,7 +153,7 @@ 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", Path.MaxPathComponentLength), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", PathInternal.MaxComponentLength), "name");
#endif
case Win32Native.ERROR_INVALID_HANDLE:
@@ -199,38 +170,27 @@ namespace System.Threading
}
}
- [System.Security.SecurityCritical] // auto-generated
[PrePrepareMethod]
private void MutexCleanupCode(Object userData, bool exceptionThrown)
{
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.
+ // on this OS thread before ending our thread affninity.
if(!hasThreadAffinity) {
if (cleanupInfo.mutexHandle != null && !cleanupInfo.mutexHandle.IsInvalid) {
if( cleanupInfo.inCriticalRegion) {
- Win32Native.ReleaseMutex(cleanupInfo.mutexHandle);
+ Win32Native.ReleaseMutex(cleanupInfo.mutexHandle);
}
- cleanupInfo.mutexHandle.Dispose();
-
+ cleanupInfo.mutexHandle.Dispose();
}
-
- if( cleanupInfo.inCriticalRegion) {
-#if !FEATURE_CORECLR
- Thread.EndCriticalRegion();
- Thread.EndThreadAffinity();
-#endif
- }
}
}
internal class MutexCleanupInfo
{
- [System.Security.SecurityCritical] // auto-generated
internal SafeWaitHandle mutexHandle;
internal bool inCriticalRegion;
- [System.Security.SecurityCritical] // auto-generated
internal MutexCleanupInfo(SafeWaitHandle mutexHandle, bool inCriticalRegion)
{
this.mutexHandle = mutexHandle;
@@ -238,24 +198,20 @@ namespace System.Threading
}
}
- [System.Security.SecurityCritical] // auto-generated_required
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public Mutex(bool initiallyOwned, String name) : this(initiallyOwned, name, out dummyBool) {
}
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public Mutex(bool initiallyOwned) : this(initiallyOwned, null, out dummyBool)
{
}
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public Mutex() : this(false, null, out dummyBool)
{
}
- [System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
private Mutex(SafeWaitHandle handle)
{
@@ -263,23 +219,15 @@ namespace System.Threading
hasThreadAffinity = true;
}
- [System.Security.SecurityCritical] // auto-generated_required
public static Mutex OpenExisting(string name)
{
-#if !FEATURE_MACL
return OpenExisting(name, (MutexRights) 0);
-#else // FEATURE_MACL
- return OpenExisting(name, MutexRights.Modify | MutexRights.Synchronize);
-#endif // FEATURE_MACL
}
-#if !FEATURE_MACL
public enum MutexRights
{
}
-#endif
- [System.Security.SecurityCritical] // auto-generated_required
public static Mutex OpenExisting(string name, MutexRights rights)
{
Mutex result;
@@ -300,38 +248,31 @@ namespace System.Threading
}
}
- [System.Security.SecurityCritical] // auto-generated_required
public static bool TryOpenExisting(string name, out Mutex result)
{
-#if !FEATURE_MACL
return OpenExistingWorker(name, (MutexRights)0, out result) == OpenExistingResult.Success;
-#else // FEATURE_MACL
- return OpenExistingWorker(name, MutexRights.Modify | MutexRights.Synchronize, out result) == OpenExistingResult.Success;
-#endif // FEATURE_MACL
}
- [System.Security.SecurityCritical] // auto-generated_required
public static bool TryOpenExisting(string name, MutexRights rights, out Mutex result)
{
return OpenExistingWorker(name, rights, out result) == OpenExistingResult.Success;
}
- [System.Security.SecurityCritical]
private static OpenExistingResult OpenExistingWorker(string name, MutexRights rights, out Mutex result)
{
if (name == null)
{
- throw new ArgumentNullException("name", Environment.GetResourceString("ArgumentNull_WithParamName"));
+ throw new ArgumentNullException(nameof(name), Environment.GetResourceString("ArgumentNull_WithParamName"));
}
if(name.Length == 0)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name));
}
#if !PLATFORM_UNIX
if(System.IO.Path.MaxPath < name.Length)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), nameof(name));
}
#endif
Contract.EndContractBlock();
@@ -342,11 +283,7 @@ namespace System.Threading
// with parameters to allow us to view & edit the ACL. This will
// fail if we don't have permission to view or edit the ACL's.
// If that happens, ask for less permissions.
-#if FEATURE_MACL
- SafeWaitHandle myHandle = Win32Native.OpenMutex((int) rights, false, name);
-#else
SafeWaitHandle myHandle = Win32Native.OpenMutex(Win32Native.MUTEX_MODIFY_STATE | Win32Native.SYNCHRONIZE, false, name);
-#endif
int errorCode = 0;
if (myHandle.IsInvalid)
@@ -357,7 +294,7 @@ 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", Path.MaxPathComponentLength), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", PathInternal.MaxComponentLength), nameof(name));
}
#endif
@@ -379,110 +316,51 @@ namespace System.Threading
// Note: To call ReleaseMutex, you must have an ACL granting you
// MUTEX_MODIFY_STATE rights (0x0001). The other interesting value
// in a Mutex's ACL is MUTEX_ALL_ACCESS (0x1F0001).
- [System.Security.SecuritySafeCritical] // auto-generated
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public void ReleaseMutex()
{
if (Win32Native.ReleaseMutex(safeWaitHandle))
{
-#if !FEATURE_CORECLR
- Thread.EndCriticalRegion();
- Thread.EndThreadAffinity();
-#endif
}
else
{
-#if FEATURE_CORECLR
throw new Exception(Environment.GetResourceString("Arg_SynchronizationLockException"));
-#else
- throw new ApplicationException(Environment.GetResourceString("Arg_SynchronizationLockException"));
-#endif // FEATURE_CORECLR
- }
+ }
}
- [System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
- static int CreateMutexHandle(bool initiallyOwned, String name, Win32Native.SECURITY_ATTRIBUTES securityAttribute, out SafeWaitHandle mutexHandle) {
- int errorCode;
- bool fAffinity = false;
-
- while(true) {
+ static int CreateMutexHandle(bool initiallyOwned, String name, Win32Native.SECURITY_ATTRIBUTES securityAttribute, out SafeWaitHandle mutexHandle)
+ {
+ int errorCode;
+
+ while (true)
+ {
mutexHandle = Win32Native.CreateMutex(securityAttribute, initiallyOwned, name);
- errorCode = Marshal.GetLastWin32Error();
- if( !mutexHandle.IsInvalid) {
- break;
- }
+ errorCode = Marshal.GetLastWin32Error();
+ if (!mutexHandle.IsInvalid) break;
- if( errorCode == Win32Native.ERROR_ACCESS_DENIED) {
- // If a mutex with the name already exists, OS will try to open it with FullAccess.
- // It might fail if we don't have enough access. In that case, we try to open the mutex will modify and synchronize access.
- //
-
- RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
- try
- {
- }
- finally
- {
-#if !FEATURE_CORECLR
- Thread.BeginThreadAffinity();
-#endif
- fAffinity = true;
- }
- mutexHandle = Win32Native.OpenMutex(Win32Native.MUTEX_MODIFY_STATE | Win32Native.SYNCHRONIZE, false, name);
- if(!mutexHandle.IsInvalid)
- {
- errorCode = Win32Native.ERROR_ALREADY_EXISTS;
- }
- else
- {
- errorCode = Marshal.GetLastWin32Error();
- }
- }
- finally
- {
- if (fAffinity) {
-#if !FEATURE_CORECLR
- Thread.EndThreadAffinity();
-#endif
- }
- }
+ if (errorCode != Win32Native.ERROR_ACCESS_DENIED) break;
- // There could be a race condition here, the other owner of the mutex can free the mutex,
- // We need to retry creation in that case.
- if( errorCode != Win32Native.ERROR_FILE_NOT_FOUND) {
- if( errorCode == Win32Native.ERROR_SUCCESS) {
- errorCode = Win32Native.ERROR_ALREADY_EXISTS;
- }
- break;
- }
- }
- else {
+ // If a mutex with the name already exists, OS will try to open it with FullAccess.
+ // It might fail if we don't have enough access. In that case, we try to open the mutex will modify and synchronize access.
+ RuntimeHelpers.PrepareConstrainedRegions();
+
+ mutexHandle = Win32Native.OpenMutex(
+ Win32Native.MUTEX_MODIFY_STATE | Win32Native.SYNCHRONIZE,
+ false,
+ name);
+
+ errorCode = !mutexHandle.IsInvalid ? Win32Native.ERROR_ALREADY_EXISTS : Marshal.GetLastWin32Error();
+
+ // There could be a race condition here, the other owner of the mutex can free the mutex,
+ // We need to retry creation in that case.
+ if (errorCode != Win32Native.ERROR_FILE_NOT_FOUND)
+ {
+ if (errorCode == Win32Native.ERROR_SUCCESS) errorCode = Win32Native.ERROR_ALREADY_EXISTS;
break;
}
- }
+ }
return errorCode;
}
-
-#if FEATURE_MACL
- [System.Security.SecuritySafeCritical] // auto-generated
- public MutexSecurity GetAccessControl()
- {
- return new MutexSecurity(safeWaitHandle, AccessControlSections.Access | AccessControlSections.Owner | AccessControlSections.Group);
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public void SetAccessControl(MutexSecurity mutexSecurity)
- {
- if (mutexSecurity == null)
- throw new ArgumentNullException("mutexSecurity");
- Contract.EndContractBlock();
-
- mutexSecurity.Persist(safeWaitHandle);
- }
-#endif
-
}
}
diff --git a/src/mscorlib/src/System/Threading/Overlapped.cs b/src/mscorlib/src/System/Threading/Overlapped.cs
index 3f9fbc4989..2b192c7b3a 100644
--- a/src/mscorlib/src/System/Threading/Overlapped.cs
+++ b/src/mscorlib/src/System/Threading/Overlapped.cs
@@ -33,6 +33,7 @@ namespace System.Threading
using System.Security;
using System.Security.Permissions;
using System.Runtime.ConstrainedExecution;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Collections.Concurrent;
@@ -60,20 +61,16 @@ namespace System.Threading
unsafe internal class _IOCompletionCallback
{
- [System.Security.SecurityCritical] // auto-generated
IOCompletionCallback _ioCompletionCallback;
ExecutionContext _executionContext;
uint _errorCode; // Error code
uint _numBytes; // No. of bytes transferred
- [SecurityCritical]
NativeOverlapped* _pOVERLAP;
- [System.Security.SecuritySafeCritical] // auto-generated
static _IOCompletionCallback()
{
}
- [System.Security.SecurityCritical] // auto-generated
internal _IOCompletionCallback(IOCompletionCallback ioCompletionCallback, ref StackCrawlMark stackMark)
{
_ioCompletionCallback = ioCompletionCallback;
@@ -83,21 +80,16 @@ namespace System.Threading
ExecutionContext.CaptureOptions.IgnoreSyncCtx | ExecutionContext.CaptureOptions.OptimizeDefaultCase);
}
// Context callback: same sig for SendOrPostCallback and ContextCallback
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #endif
static internal ContextCallback _ccb = new ContextCallback(IOCompletionCallback_Context);
- [System.Security.SecurityCritical]
static internal void IOCompletionCallback_Context(Object state)
{
_IOCompletionCallback helper = (_IOCompletionCallback)state;
- Contract.Assert(helper != null,"_IOCompletionCallback cannot be null");
+ Debug.Assert(helper != null,"_IOCompletionCallback cannot be null");
helper._ioCompletionCallback(helper._errorCode, helper._numBytes, helper._pOVERLAP);
}
// call back helper
- [System.Security.SecurityCritical] // auto-generated
static unsafe internal void PerformIOCompletionCallback(uint errorCode, // Error code
uint numBytes, // No. of bytes transferred
NativeOverlapped* pOVERLAP // ptr to OVERLAP structure
@@ -146,7 +138,6 @@ namespace System.Threading
// ! If you make any change to the layout here, you need to make matching change
// ! to OverlappedObject in vm\nativeoverlapped.h
internal IAsyncResult m_asyncResult;
- [System.Security.SecurityCritical] // auto-generated
internal IOCompletionCallback m_iocb;
internal _IOCompletionCallback m_iocbHelper;
internal Overlapped m_overlapped;
@@ -162,14 +153,9 @@ namespace System.Threading
#pragma warning restore 169
internal NativeOverlapped m_nativeOverlapped;
-#if FEATURE_CORECLR
// Adding an empty default ctor for annotation purposes
- [System.Security.SecuritySafeCritical] // auto-generated
internal OverlappedData(){}
-#endif // FEATURE_CORECLR
-
- [System.Security.SecurityCritical]
internal void ReInitialize()
{
m_asyncResult = null;
@@ -177,10 +163,10 @@ namespace System.Threading
m_iocbHelper = null;
m_overlapped = null;
m_userObject = null;
- Contract.Assert(m_pinSelf.IsNull(), "OverlappedData has not been freed: m_pinSelf");
+ Debug.Assert(m_pinSelf.IsNull(), "OverlappedData has not been freed: m_pinSelf");
m_pinSelf = (IntPtr)0;
m_userObjectInternal = (IntPtr)0;
- Contract.Assert(m_AppDomainId == 0 || m_AppDomainId == AppDomain.CurrentDomain.Id, "OverlappedData is not in the current domain");
+ Debug.Assert(m_AppDomainId == 0 || m_AppDomainId == AppDomain.CurrentDomain.Id, "OverlappedData is not in the current domain");
m_AppDomainId = 0;
m_nativeOverlapped.EventHandle = (IntPtr)0;
m_isArray = 0;
@@ -188,7 +174,6 @@ namespace System.Threading
m_nativeOverlapped.InternalHigh = (IntPtr)0;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
unsafe internal NativeOverlapped* Pack(IOCompletionCallback iocb, Object userData)
{
@@ -222,7 +207,6 @@ namespace System.Threading
return AllocateNativeOverlapped();
}
- [System.Security.SecurityCritical] // auto-generated_required
unsafe internal NativeOverlapped* UnsafePack(IOCompletionCallback iocb, Object userData)
{
if (!m_pinSelf.IsNull()) {
@@ -252,19 +236,15 @@ namespace System.Threading
set { m_nativeOverlapped.EventHandle = value; }
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
unsafe private extern NativeOverlapped* AllocateNativeOverlapped();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
unsafe internal static extern void FreeNativeOverlapped(NativeOverlapped* nativeOverlappedPtr);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
unsafe internal static extern OverlappedData GetOverlappedFromNative(NativeOverlapped* nativeOverlappedPtr);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
unsafe internal static extern void CheckVMForIOPacket(out NativeOverlapped* pOVERLAP, out uint errorCode, out uint numBytes);
}
@@ -281,9 +261,6 @@ namespace System.Threading
private OverlappedData m_overlappedData;
private static PinnableBufferCache s_overlappedDataCache = new PinnableBufferCache("System.Threading.OverlappedData", ()=> new OverlappedData());
-#if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical] // auto-generated
-#endif
public Overlapped()
{
m_overlappedData = (OverlappedData) s_overlappedDataCache.Allocate();
@@ -344,7 +321,6 @@ namespace System.Threading
internal IOCompletionCallback UserCallback
{
- [System.Security.SecurityCritical]
get { return m_overlappedData.m_iocb; }
}
@@ -353,7 +329,6 @@ namespace System.Threading
* Roots the iocb and stores it in the ReservedCOR field of native Overlapped
* Pins the native Overlapped struct and returns the pinned index.
====================================================================*/
- [System.Security.SecurityCritical] // auto-generated
[Obsolete("This method is not safe. Use Pack (iocb, userData) instead. http://go.microsoft.com/fwlink/?linkid=14202")]
[CLSCompliant(false)]
unsafe public NativeOverlapped* Pack(IOCompletionCallback iocb)
@@ -361,14 +336,12 @@ namespace System.Threading
return Pack (iocb, null);
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false),ComVisible(false)]
unsafe public NativeOverlapped* Pack(IOCompletionCallback iocb, Object userData)
{
return m_overlappedData.Pack(iocb, userData);
}
- [System.Security.SecurityCritical] // auto-generated_required
[Obsolete("This method is not safe. Use UnsafePack (iocb, userData) instead. http://go.microsoft.com/fwlink/?linkid=14202")]
[CLSCompliant(false)]
unsafe public NativeOverlapped* UnsafePack(IOCompletionCallback iocb)
@@ -376,7 +349,6 @@ namespace System.Threading
return UnsafePack (iocb, null);
}
- [System.Security.SecurityCritical] // auto-generated_required
[CLSCompliant(false), ComVisible(false)]
unsafe public NativeOverlapped* UnsafePack(IOCompletionCallback iocb, Object userData)
{
@@ -387,12 +359,11 @@ namespace System.Threading
* Unpacks an unmanaged native Overlapped struct.
* Unpins the native Overlapped struct
====================================================================*/
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
unsafe public static Overlapped Unpack(NativeOverlapped* nativeOverlappedPtr)
{
if (nativeOverlappedPtr == null)
- throw new ArgumentNullException("nativeOverlappedPtr");
+ throw new ArgumentNullException(nameof(nativeOverlappedPtr));
Contract.EndContractBlock();
Overlapped overlapped = OverlappedData.GetOverlappedFromNative(nativeOverlappedPtr).m_overlapped;
@@ -400,12 +371,11 @@ namespace System.Threading
return overlapped;
}
- [System.Security.SecurityCritical] // auto-generated
[CLSCompliant(false)]
unsafe public static void Free(NativeOverlapped* nativeOverlappedPtr)
{
if (nativeOverlappedPtr == null)
- throw new ArgumentNullException("nativeOverlappedPtr");
+ throw new ArgumentNullException(nameof(nativeOverlappedPtr));
Contract.EndContractBlock();
Overlapped overlapped = OverlappedData.GetOverlappedFromNative(nativeOverlappedPtr).m_overlapped;
diff --git a/src/mscorlib/src/System/Threading/ReaderWriterLock.cs b/src/mscorlib/src/System/Threading/ReaderWriterLock.cs
index 8cead1a87a..e35ac7685b 100644
--- a/src/mscorlib/src/System/Threading/ReaderWriterLock.cs
+++ b/src/mscorlib/src/System/Threading/ReaderWriterLock.cs
@@ -25,14 +25,12 @@ namespace System.Threading {
using System.Runtime.Versioning;
using System.Diagnostics.Contracts;
- [HostProtection(Synchronization=true, ExternalThreading=true)]
[ComVisible(true)]
public sealed class ReaderWriterLock: CriticalFinalizerObject
{
/*
* Constructor
*/
- [System.Security.SecuritySafeCritical] // auto-generated
public ReaderWriterLock()
{
PrivateInitialize();
@@ -41,7 +39,6 @@ namespace System.Threading {
/*
* Destructor
*/
- [System.Security.SecuritySafeCritical] // auto-generated
~ReaderWriterLock()
{
PrivateDestruct();
@@ -52,7 +49,6 @@ namespace System.Threading {
* by the current thread
*/
public bool IsReaderLockHeld {
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
get {
return(PrivateGetIsReaderLockHeld());
@@ -64,7 +60,6 @@ namespace System.Threading {
* by the current thread
*/
public bool IsWriterLockHeld {
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
get {
return(PrivateGetIsWriterLockHeld());
@@ -77,7 +72,6 @@ namespace System.Threading {
* meaningful results
*/
public int WriterSeqNum {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
return(PrivateGetWriterSeqNum());
}
@@ -87,23 +81,20 @@ namespace System.Threading {
* Acquires reader lock. The thread will block if a different
* thread has writer lock.
*/
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void AcquireReaderLockInternal(int millisecondsTimeout);
- [System.Security.SecuritySafeCritical] // auto-generated
public void AcquireReaderLock(int millisecondsTimeout)
{
AcquireReaderLockInternal(millisecondsTimeout);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void AcquireReaderLock(TimeSpan timeout)
{
long tm = (long)timeout.TotalMilliseconds;
if (tm < -1 || tm > (long) Int32.MaxValue)
- throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
AcquireReaderLockInternal((int)tm);
}
@@ -113,22 +104,19 @@ namespace System.Threading {
* has reader lock. Use UpgardeToWriterLock when you are not
* sure if the thread has reader lock
*/
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void AcquireWriterLockInternal(int millisecondsTimeout);
- [System.Security.SecuritySafeCritical] // auto-generated
public void AcquireWriterLock(int millisecondsTimeout)
{
AcquireWriterLockInternal(millisecondsTimeout);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public void AcquireWriterLock(TimeSpan timeout)
{
long tm = (long)timeout.TotalMilliseconds;
if (tm < -1 || tm > (long) Int32.MaxValue)
- throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
AcquireWriterLockInternal((int)tm);
}
@@ -136,12 +124,10 @@ namespace System.Threading {
/*
* Releases reader lock.
*/
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
private extern void ReleaseReaderLockInternal();
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public void ReleaseReaderLock()
{
@@ -151,12 +137,10 @@ namespace System.Threading {
/*
* Releases writer lock.
*/
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
private extern void ReleaseWriterLockInternal();
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public void ReleaseWriterLock()
{
@@ -168,7 +152,6 @@ namespace System.Threading {
* reader, it is possible that the reader lock was
* released before writer lock was acquired.
*/
- [System.Security.SecuritySafeCritical] // auto-generated
public LockCookie UpgradeToWriterLock(int millisecondsTimeout)
{
LockCookie result = new LockCookie ();
@@ -176,7 +159,6 @@ namespace System.Threading {
return result;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void FCallUpgradeToWriterLock(ref LockCookie result, int millisecondsTimeout);
@@ -184,7 +166,7 @@ namespace System.Threading {
{
long tm = (long)timeout.TotalMilliseconds;
if (tm < -1 || tm > (long) Int32.MaxValue)
- throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
return UpgradeToWriterLock((int)tm);
}
@@ -192,11 +174,9 @@ namespace System.Threading {
* Restores the lock status of the thread to the one it was
* in when it called UpgradeToWriterLock.
*/
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void DowngradeFromWriterLockInternal(ref LockCookie lockCookie);
- [System.Security.SecuritySafeCritical] // auto-generated
public void DowngradeFromWriterLock(ref LockCookie lockCookie)
{
DowngradeFromWriterLockInternal(ref lockCookie);
@@ -206,7 +186,6 @@ namespace System.Threading {
* Releases the lock irrespective of the number of times the thread
* acquired the lock
*/
- [System.Security.SecuritySafeCritical] // auto-generated
public LockCookie ReleaseLock()
{
LockCookie result = new LockCookie ();
@@ -214,7 +193,6 @@ namespace System.Threading {
return result;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void FCallReleaseLock(ref LockCookie result);
@@ -222,11 +200,9 @@ namespace System.Threading {
* Restores the lock status of the thread to the one it was
* in when it called ReleaseLock.
*/
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void RestoreLockInternal(ref LockCookie lockCookie);
- [System.Security.SecuritySafeCritical] // auto-generated
public void RestoreLock(ref LockCookie lockCookie)
{
RestoreLockInternal(ref lockCookie);
@@ -236,7 +212,6 @@ namespace System.Threading {
* Internal helper that returns TRUE if the reader lock is held
* by the current thread
*/
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
private extern bool PrivateGetIsReaderLockHeld();
@@ -245,7 +220,6 @@ namespace System.Threading {
* Internal helper that returns TRUE if the writer lock is held
* by the current thread
*/
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
private extern bool PrivateGetIsWriterLockHeld();
@@ -255,7 +229,6 @@ namespace System.Threading {
* number. The caller should be a reader or writer for getting
* meaningful results
*/
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern int PrivateGetWriterSeqNum();
@@ -264,17 +237,14 @@ namespace System.Threading {
* sequence number was obtained. The caller should be
* a reader or writer for getting meaningful results
*/
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern bool AnyWritersSince(int seqNum);
// Initialize state kept inside the lock
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void PrivateInitialize();
// Destruct resource associated with the lock
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void PrivateDestruct();
diff --git a/src/mscorlib/src/System/Threading/Semaphore.cs b/src/mscorlib/src/System/Threading/Semaphore.cs
index 303593b776..1eac4aaaeb 100644
--- a/src/mscorlib/src/System/Threading/Semaphore.cs
+++ b/src/mscorlib/src/System/Threading/Semaphore.cs
@@ -4,6 +4,7 @@
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.IO;
using System.Runtime.InteropServices;
@@ -13,20 +14,18 @@ namespace System.Threading
{
public sealed partial class Semaphore : WaitHandle
{
- [SecuritySafeCritical]
public Semaphore(int initialCount, int maximumCount) : this(initialCount, maximumCount, null) { }
- [SecurityCritical]
public Semaphore(int initialCount, int maximumCount, string name)
{
if (initialCount < 0)
{
- throw new ArgumentOutOfRangeException("initialCount", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(initialCount), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (maximumCount < 1)
{
- throw new ArgumentOutOfRangeException("maximumCount", Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
+ throw new ArgumentOutOfRangeException(nameof(maximumCount), Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
}
if (initialCount > maximumCount)
@@ -49,17 +48,16 @@ namespace System.Threading
this.SafeWaitHandle = myHandle;
}
- [SecurityCritical]
public Semaphore(int initialCount, int maximumCount, string name, out bool createdNew)
{
if (initialCount < 0)
{
- throw new ArgumentOutOfRangeException("initialCount", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(initialCount), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (maximumCount < 1)
{
- throw new ArgumentOutOfRangeException("maximumCount", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(maximumCount), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if (initialCount > maximumCount)
@@ -81,13 +79,11 @@ namespace System.Threading
this.SafeWaitHandle = myHandle;
}
- [SecurityCritical]
private Semaphore(SafeWaitHandle handle)
{
this.SafeWaitHandle = handle;
}
- [SecurityCritical]
private static SafeWaitHandle CreateSemaphone(int initialCount, int maximumCount, string name)
{
if (name != null)
@@ -96,19 +92,17 @@ namespace System.Threading
throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_NamedSynchronizationPrimitives"));
#else
if (name.Length > Path.MaxPath)
- throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), nameof(name));
#endif
}
- Contract.Assert(initialCount >= 0);
- Contract.Assert(maximumCount >= 1);
- Contract.Assert(initialCount <= maximumCount);
+ Debug.Assert(initialCount >= 0);
+ Debug.Assert(maximumCount >= 1);
+ Debug.Assert(initialCount <= maximumCount);
return Win32Native.CreateSemaphore(null, initialCount, maximumCount, name);
}
- [SecurityCritical]
-
public static Semaphore OpenExisting(string name)
{
Semaphore result;
@@ -125,24 +119,22 @@ namespace System.Threading
}
}
- [SecurityCritical]
public static bool TryOpenExisting(string name, out Semaphore result)
{
return OpenExistingWorker(name, out result) == OpenExistingResult.Success;
}
- [SecurityCritical]
private static OpenExistingResult OpenExistingWorker(string name, out Semaphore result)
{
#if PLATFORM_UNIX
throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_NamedSynchronizationPrimitives"));
#else
if (name == null)
- throw new ArgumentNullException("name", Environment.GetResourceString("ArgumentNull_WithParamName"));
+ throw new ArgumentNullException(nameof(name), Environment.GetResourceString("ArgumentNull_WithParamName"));
if (name.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name));
if (name.Length > Path.MaxPath)
- throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), "name");
+ throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), nameof(name));
const int SYNCHRONIZE = 0x00100000;
const int SEMAPHORE_MODIFY_STATE = 0x00000002;
@@ -177,12 +169,11 @@ namespace System.Threading
}
// increase the count on a semaphore, returns previous count
- [SecuritySafeCritical]
public int Release(int releaseCount)
{
if (releaseCount < 1)
{
- throw new ArgumentOutOfRangeException("releaseCount", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(releaseCount), Environment.GetResourceString("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
index e1928e05de..01c5040b7e 100644
--- a/src/mscorlib/src/System/Threading/SemaphoreFullException.cs
+++ b/src/mscorlib/src/System/Threading/SemaphoreFullException.cs
@@ -9,9 +9,6 @@ namespace System.Threading {
[Serializable]
[ComVisibleAttribute(false)]
-#if !FEATURE_CORECLR
- [System.Runtime.CompilerServices.TypeForwardedFrom("System, Version=2.0.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
-#endif
public class SemaphoreFullException : SystemException {
public SemaphoreFullException() : base(Environment.GetResourceString("Threading_SemaphoreFullException")){
diff --git a/src/mscorlib/src/System/Threading/SemaphoreSlim.cs b/src/mscorlib/src/System/Threading/SemaphoreSlim.cs
index c2dcbb3451..92d760d77d 100644
--- a/src/mscorlib/src/System/Threading/SemaphoreSlim.cs
+++ b/src/mscorlib/src/System/Threading/SemaphoreSlim.cs
@@ -40,7 +40,6 @@ namespace System.Threading
/// </para>
/// </remarks>
[ComVisible(false)]
- [HostProtection(Synchronization = true, ExternalThreading = true)]
[DebuggerDisplay("Current Count = {m_currentCount}")]
public class SemaphoreSlim : IDisposable
{
@@ -89,14 +88,12 @@ namespace System.Threading
internal TaskNode Prev, Next;
internal TaskNode() : base() {}
- [SecurityCritical]
void IThreadPoolWorkItem.ExecuteWorkItem()
{
bool setSuccessfully = TrySetResult(true);
- Contract.Assert(setSuccessfully, "Should have been able to complete task");
+ Debug.Assert(setSuccessfully, "Should have been able to complete task");
}
- [SecurityCritical]
void IThreadPoolWorkItem.MarkAborted(ThreadAbortException tae) { /* nop */ }
}
#endregion
@@ -182,13 +179,13 @@ namespace System.Threading
if (initialCount < 0 || initialCount > maxCount)
{
throw new ArgumentOutOfRangeException(
- "initialCount", initialCount, GetResourceString("SemaphoreSlim_ctor_InitialCountWrong"));
+ nameof(initialCount), initialCount, GetResourceString("SemaphoreSlim_ctor_InitialCountWrong"));
}
//validate input
if (maxCount <= 0)
{
- throw new ArgumentOutOfRangeException("maxCount", maxCount, GetResourceString("SemaphoreSlim_ctor_MaxCountWrong"));
+ throw new ArgumentOutOfRangeException(nameof(maxCount), maxCount, GetResourceString("SemaphoreSlim_ctor_MaxCountWrong"));
}
m_maxCount = maxCount;
@@ -245,7 +242,7 @@ namespace System.Threading
if (totalMilliseconds < -1 || totalMilliseconds > Int32.MaxValue)
{
throw new System.ArgumentOutOfRangeException(
- "timeout", timeout, GetResourceString("SemaphoreSlim_Wait_TimeoutWrong"));
+ nameof(timeout), timeout, GetResourceString("SemaphoreSlim_Wait_TimeoutWrong"));
}
// Call wait with the timeout milliseconds
@@ -275,7 +272,7 @@ namespace System.Threading
if (totalMilliseconds < -1 || totalMilliseconds > Int32.MaxValue)
{
throw new System.ArgumentOutOfRangeException(
- "timeout", timeout, GetResourceString("SemaphoreSlim_Wait_TimeoutWrong"));
+ nameof(timeout), timeout, GetResourceString("SemaphoreSlim_Wait_TimeoutWrong"));
}
// Call wait with the timeout milliseconds
@@ -372,7 +369,7 @@ namespace System.Threading
// then block on (once we've released the lock).
if (m_asyncHead != null)
{
- Contract.Assert(m_asyncTail != null, "tail should not be null if head isn't");
+ 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.
@@ -404,7 +401,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.
- Contract.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)
{
@@ -579,7 +576,7 @@ namespace System.Threading
if (totalMilliseconds < -1 || totalMilliseconds > Int32.MaxValue)
{
throw new System.ArgumentOutOfRangeException(
- "timeout", timeout, GetResourceString("SemaphoreSlim_Wait_TimeoutWrong"));
+ nameof(timeout), timeout, GetResourceString("SemaphoreSlim_Wait_TimeoutWrong"));
}
// Call wait with the timeout milliseconds
@@ -638,7 +635,7 @@ namespace System.Threading
// the semaphore or when the timeout expired or cancellation was requested.
else
{
- Contract.Assert(m_currentCount == 0, "m_currentCount should never be negative");
+ Debug.Assert(m_currentCount == 0, "m_currentCount should never be negative");
var asyncWaiter = CreateAndAddAsyncWaiter();
return (millisecondsTimeout == Timeout.Infinite && !cancellationToken.CanBeCanceled) ?
asyncWaiter :
@@ -651,7 +648,7 @@ namespace System.Threading
/// <returns>The created task.</returns>
private TaskNode CreateAndAddAsyncWaiter()
{
- Contract.Assert(Monitor.IsEntered(m_lockObj), "Requires the lock be held");
+ Debug.Assert(Monitor.IsEntered(m_lockObj), "Requires the lock be held");
// Create the task
var task = new TaskNode();
@@ -659,13 +656,13 @@ namespace System.Threading
// Add it to the linked list
if (m_asyncHead == null)
{
- Contract.Assert(m_asyncTail == null, "If head is null, so too should be tail");
+ Debug.Assert(m_asyncTail == null, "If head is null, so too should be tail");
m_asyncHead = task;
m_asyncTail = task;
}
else
{
- Contract.Assert(m_asyncTail != null, "If head is not null, neither should be tail");
+ Debug.Assert(m_asyncTail != null, "If head is not null, neither should be tail");
m_asyncTail.Next = task;
task.Prev = m_asyncTail;
m_asyncTail = task;
@@ -681,7 +678,7 @@ namespace System.Threading
private bool RemoveAsyncWaiter(TaskNode task)
{
Contract.Requires(task != null, "Expected non-null task");
- Contract.Assert(Monitor.IsEntered(m_lockObj), "Requires the lock be held");
+ Debug.Assert(Monitor.IsEntered(m_lockObj), "Requires the lock be held");
// Is the task in the list? To be in the list, either it's the head or it has a predecessor that's in the list.
bool wasInList = m_asyncHead == task || task.Prev != null;
@@ -691,7 +688,7 @@ namespace System.Threading
if (task.Prev != null) task.Prev.Next = task.Next;
if (m_asyncHead == task) m_asyncHead = task.Next;
if (m_asyncTail == task) m_asyncTail = task.Prev;
- Contract.Assert((m_asyncHead == null) == (m_asyncTail == null), "Head is null iff tail is null");
+ Debug.Assert((m_asyncHead == null) == (m_asyncTail == null), "Head is null iff tail is null");
// Make sure not to leak
task.Next = task.Prev = null;
@@ -706,8 +703,8 @@ namespace System.Threading
/// <returns>The task to return to the caller.</returns>
private async Task<bool> WaitUntilCountOrTimeoutAsync(TaskNode asyncWaiter, int millisecondsTimeout, CancellationToken cancellationToken)
{
- Contract.Assert(asyncWaiter != null, "Waiter should have been constructed");
- Contract.Assert(Monitor.IsEntered(m_lockObj), "Requires the lock be held");
+ Debug.Assert(asyncWaiter != null, "Waiter should have been constructed");
+ Debug.Assert(Monitor.IsEntered(m_lockObj), "Requires the lock be held");
// Wait until either the task is completed, timeout occurs, or cancellation is requested.
// We need to ensure that the Task.Delay task is appropriately cleaned up if the await
@@ -776,7 +773,7 @@ namespace System.Threading
if (releaseCount < 1)
{
throw new ArgumentOutOfRangeException(
- "releaseCount", releaseCount, GetResourceString("SemaphoreSlim_Release_CountWrong"));
+ nameof(releaseCount), releaseCount, GetResourceString("SemaphoreSlim_Release_CountWrong"));
}
int returnCount;
@@ -797,14 +794,12 @@ namespace System.Threading
// Signal to any synchronous waiters
int waitCount = m_waitCount;
- if (currentCount == 1 || waitCount == 1)
+
+ int waitersToNotify = Math.Min(releaseCount, waitCount);
+ for (int i = 0; i < waitersToNotify; i++)
{
Monitor.Pulse(m_lockObj);
}
- else if (waitCount > 1)
- {
- Monitor.PulseAll(m_lockObj);
- }
// Now signal to any asynchronous waiters, if there are any. While we've already
// signaled the synchronous waiters, we still hold the lock, and thus
@@ -814,7 +809,7 @@ namespace System.Threading
// waits are canceled, but the wait code path will handle that.
if (m_asyncHead != null)
{
- Contract.Assert(m_asyncTail != null, "tail should not be null if head isn't null");
+ Debug.Assert(m_asyncTail != null, "tail should not be null if head isn't null");
int maxAsyncToRelease = currentCount - waitCount;
while (maxAsyncToRelease > 0 && m_asyncHead != null)
{
@@ -844,7 +839,6 @@ namespace System.Threading
/// Queues a waiter task to the ThreadPool. We use this small helper method so that
/// the larger Release(count) method does not need to be SecuritySafeCritical.
/// </summary>
- [SecuritySafeCritical] // for ThreadPool.UnsafeQueueCustomWorkItem
private static void QueueWaiterTask(TaskNode waiterTask)
{
ThreadPool.UnsafeQueueCustomWorkItem(waiterTask, forceGlobal: false);
@@ -898,7 +892,7 @@ namespace System.Threading
private static void CancellationTokenCanceledEventHandler(object obj)
{
SemaphoreSlim semaphore = obj as SemaphoreSlim;
- Contract.Assert(semaphore != null, "Expected a SemaphoreSlim");
+ Debug.Assert(semaphore != null, "Expected a SemaphoreSlim");
lock (semaphore.m_lockObj)
{
Monitor.PulseAll(semaphore.m_lockObj); //wake up all waiters.
diff --git a/src/mscorlib/src/System/Threading/SpinLock.cs b/src/mscorlib/src/System/Threading/SpinLock.cs
index dea87435a7..1d90890d6e 100644
--- a/src/mscorlib/src/System/Threading/SpinLock.cs
+++ b/src/mscorlib/src/System/Threading/SpinLock.cs
@@ -12,11 +12,11 @@
//
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
using System;
-using System.Diagnostics;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
namespace System.Threading
@@ -55,7 +55,6 @@ namespace System.Threading
/// </para>
/// </remarks>
[ComVisible(false)]
- [HostProtection(Synchronization = true, ExternalThreading = true)]
[DebuggerTypeProxy(typeof(SystemThreading_SpinLockDebugView))]
[DebuggerDisplay("IsHeld = {IsHeld}")]
public struct SpinLock
@@ -107,7 +106,6 @@ namespace System.Threading
// The waiters count is calculated by m_owner & WAITERS_MASK 01111....110
private static int MAXIMUM_WAITERS = WAITERS_MASK;
-
/// <summary>
/// Initializes a new instance of the <see cref="T:System.Threading.SpinLock"/>
/// structure with the option to track thread IDs to improve debugging.
@@ -123,11 +121,10 @@ namespace System.Threading
if (!enableThreadOwnerTracking)
{
m_owner |= LOCK_ID_DISABLE_MASK;
- Contract.Assert(!IsThreadOwnerTrackingEnabled, "property should be false by now");
+ Debug.Assert(!IsThreadOwnerTrackingEnabled, "property should be false by now");
}
}
-
/// <summary>
/// Initializes a new instance of the <see cref="T:System.Threading.SpinLock"/>
/// structure with the option to track thread IDs to improve debugging.
@@ -157,9 +154,6 @@ namespace System.Threading
/// </exception>
public void Enter(ref bool lockTaken)
{
-#if !FEATURE_CORECLR
- Thread.BeginCriticalRegion();
-#endif
//Try to keep the code and branching in this method as small as possible in order to inline the method
int observedOwner = m_owner;
if (lockTaken || //invalid parameter
@@ -225,7 +219,7 @@ namespace System.Threading
if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue)
{
throw new System.ArgumentOutOfRangeException(
- "timeout", timeout, Environment.GetResourceString("SpinLock_TryEnter_ArgumentOutOfRange"));
+ nameof(timeout), timeout, Environment.GetResourceString("SpinLock_TryEnter_ArgumentOutOfRange"));
}
// Call reliable enter with the int-based timeout milliseconds
@@ -256,10 +250,6 @@ namespace System.Threading
/// a negative number other than -1, which represents an infinite time-out.</exception>
public void TryEnter(int millisecondsTimeout, ref bool lockTaken)
{
-#if !FEATURE_CORECLR
- Thread.BeginCriticalRegion();
-#endif
-
int observedOwner = m_owner;
if (millisecondsTimeout < -1 || //invalid parameter
lockTaken || //invalid parameter
@@ -277,10 +267,6 @@ namespace System.Threading
/// <param name="lockTaken">The lockTaken param</param>
private void ContinueTryEnter(int millisecondsTimeout, ref bool lockTaken)
{
- //Leave the critical region which is entered by the fast path
-#if !FEATURE_CORECLR
- Thread.EndCriticalRegion();
-#endif
// The fast path doesn't throw any exception, so we have to validate the parameters here
if (lockTaken)
{
@@ -291,23 +277,15 @@ namespace System.Threading
if (millisecondsTimeout < -1)
{
throw new ArgumentOutOfRangeException(
- "millisecondsTimeout", millisecondsTimeout, Environment.GetResourceString("SpinLock_TryEnter_ArgumentOutOfRange"));
+ nameof(millisecondsTimeout), millisecondsTimeout, Environment.GetResourceString("SpinLock_TryEnter_ArgumentOutOfRange"));
}
-
uint startTime = 0;
if (millisecondsTimeout != Timeout.Infinite && millisecondsTimeout != 0)
{
startTime = TimeoutHelper.GetTime();
}
-#if !FEATURE_CORECLR
- if (CdsSyncEtwBCLProvider.Log.IsEnabled())
- {
- CdsSyncEtwBCLProvider.Log.SpinLock_FastPathFailed(m_owner);
- }
-#endif
-
if (IsThreadOwnerTrackingEnabled)
{
// Slow path for enabled thread tracking mode
@@ -333,18 +311,22 @@ namespace System.Threading
observedOwner = m_owner;
if ((observedOwner & LOCK_ANONYMOUS_OWNED) == LOCK_UNOWNED)
{
-#if !FEATURE_CORECLR
- Thread.BeginCriticalRegion();
-#endif
-
if (Interlocked.CompareExchange(ref m_owner, observedOwner | 1, observedOwner, ref lockTaken) == observedOwner)
{
+ // Aquired lock
return;
}
-#if !FEATURE_CORECLR
- Thread.EndCriticalRegion();
-#endif
+ if (millisecondsTimeout == 0)
+ {
+ // Did not aquire lock in CompareExchange and timeout is 0 so fail fast
+ return;
+ }
+ }
+ else if (millisecondsTimeout == 0)
+ {
+ // Did not aquire lock as owned and timeout is 0 so fail fast
+ return;
}
else //failed to acquire the lock,then try to update the waiters. If the waiters count reached the maximum, jsut break the loop to avoid overflow
{
@@ -352,17 +334,6 @@ namespace System.Threading
turn = (Interlocked.Add(ref m_owner, 2) & WAITERS_MASK) >> 1 ;
}
-
-
- // Check the timeout.
- if (millisecondsTimeout == 0 ||
- (millisecondsTimeout != Timeout.Infinite &&
- TimeoutHelper.UpdateTimeOut(startTime, millisecondsTimeout) <= 0))
- {
- DecrementWaiters();
- return;
- }
-
//***Step 2. Spinning
//lock acquired failed and waiters updated
int processorCount = PlatformHelper.ProcessorCount;
@@ -377,32 +348,24 @@ namespace System.Threading
observedOwner = m_owner;
if ((observedOwner & LOCK_ANONYMOUS_OWNED) == LOCK_UNOWNED)
{
-#if !FEATURE_CORECLR
- Thread.BeginCriticalRegion();
-#endif
-
int newOwner = (observedOwner & WAITERS_MASK) == 0 ? // Gets the number of waiters, if zero
observedOwner | 1 // don't decrement it. just set the lock bit, it is zzero because a previous call of Exit(false) ehich corrupted the waiters
: (observedOwner - 2) | 1; // otherwise decrement the waiters and set the lock bit
- Contract.Assert((newOwner & WAITERS_MASK) >= 0);
+ Debug.Assert((newOwner & WAITERS_MASK) >= 0);
if (Interlocked.CompareExchange(ref m_owner, newOwner, observedOwner, ref lockTaken) == observedOwner)
{
return;
}
-
-#if !FEATURE_CORECLR
- Thread.EndCriticalRegion();
-#endif
}
}
- }
- // Check the timeout.
- if (millisecondsTimeout != Timeout.Infinite && TimeoutHelper.UpdateTimeOut(startTime, millisecondsTimeout) <= 0)
- {
- DecrementWaiters();
- return;
+ // Check the timeout.
+ if (millisecondsTimeout != Timeout.Infinite && TimeoutHelper.UpdateTimeOut(startTime, millisecondsTimeout) <= 0)
+ {
+ DecrementWaiters();
+ return;
+ }
}
//*** Step 3, Yielding
@@ -413,22 +376,15 @@ namespace System.Threading
observedOwner = m_owner;
if ((observedOwner & LOCK_ANONYMOUS_OWNED) == LOCK_UNOWNED)
{
-#if !FEATURE_CORECLR
- Thread.BeginCriticalRegion();
-#endif
int newOwner = (observedOwner & WAITERS_MASK) == 0 ? // Gets the number of waiters, if zero
observedOwner | 1 // don't decrement it. just set the lock bit, it is zzero because a previous call of Exit(false) ehich corrupted the waiters
: (observedOwner - 2) | 1; // otherwise decrement the waiters and set the lock bit
- Contract.Assert((newOwner & WAITERS_MASK) >= 0);
+ Debug.Assert((newOwner & WAITERS_MASK) >= 0);
if (Interlocked.CompareExchange(ref m_owner, newOwner, observedOwner, ref lockTaken) == observedOwner)
{
return;
}
-
-#if !FEATURE_CORECLR
- Thread.EndCriticalRegion();
-#endif
}
if (yieldsoFar % SLEEP_ONE_FREQUENCY == 0)
@@ -470,7 +426,7 @@ namespace System.Threading
if ((observedOwner & WAITERS_MASK) == 0) return; // don't decrement the waiters if it's corrupted by previous call of Exit(false)
if (Interlocked.CompareExchange(ref m_owner, observedOwner - 2, observedOwner) == observedOwner)
{
- Contract.Assert(!IsThreadOwnerTrackingEnabled); // Make sure the waiters never be negative which will cause the thread tracking bit to be flipped
+ Debug.Assert(!IsThreadOwnerTrackingEnabled); // Make sure the waiters never be negative which will cause the thread tracking bit to be flipped
break;
}
spinner.SpinOnce();
@@ -483,7 +439,7 @@ namespace System.Threading
/// </summary>
private void ContinueTryEnterWithThreadTracking(int millisecondsTimeout, uint startTime, ref bool lockTaken)
{
- Contract.Assert(IsThreadOwnerTrackingEnabled);
+ Debug.Assert(IsThreadOwnerTrackingEnabled);
int lockUnowned = 0;
// We are using thread IDs to mark ownership. Snap the thread ID and check for recursion.
@@ -510,17 +466,10 @@ namespace System.Threading
if (m_owner == lockUnowned)
{
-#if !FEATURE_CORECLR
- Thread.BeginCriticalRegion();
-#endif
if (Interlocked.CompareExchange(ref m_owner, m_newOwner, lockUnowned, ref lockTaken) == lockUnowned)
{
return;
}
-#if !FEATURE_CORECLR
- // The thread failed to get the lock, so we don't need to remain in a critical region.
- Thread.EndCriticalRegion();
-#endif
}
// Check the timeout. We only RDTSC if the next spin will yield, to amortize the cost.
if (millisecondsTimeout == 0 ||
@@ -550,11 +499,6 @@ namespace System.Threading
ExitSlowPath(true);
else
Interlocked.Decrement(ref m_owner);
-
-#if !FEATURE_CORECLR
- Thread.EndCriticalRegion();
-#endif
-
}
/// <summary>
@@ -586,10 +530,6 @@ namespace System.Threading
}
else
ExitSlowPath(useMemoryBarrier);
-
-#if !FEATURE_CORECLR
- Thread.EndCriticalRegion();
-#endif
}
/// <summary>
diff --git a/src/mscorlib/src/System/Threading/SpinWait.cs b/src/mscorlib/src/System/Threading/SpinWait.cs
index c2cd0b6203..1b31407e0f 100644
--- a/src/mscorlib/src/System/Threading/SpinWait.cs
+++ b/src/mscorlib/src/System/Threading/SpinWait.cs
@@ -14,6 +14,7 @@ using System;
using System.Runtime.ConstrainedExecution;
using System.Security.Permissions;
using System.Threading;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Diagnostics.CodeAnalysis;
@@ -69,7 +70,6 @@ namespace System.Threading
/// threads must spin, each should use its own instance of SpinWait.
/// </para>
/// </remarks>
- [HostProtection(Synchronization = true, ExternalThreading = true)]
public struct SpinWait
{
@@ -132,10 +132,6 @@ namespace System.Threading
// remove the thread from the scheduler's queue for 10+ms, if the system is
// configured to use the (default) coarse-grained system timer.
//
-
-#if !FEATURE_CORECLR
- CdsSyncEtwBCLProvider.Log.SpinWait_NextSpinWillYield();
-#endif
int yieldsSoFar = (m_count >= YIELD_THRESHOLD ? m_count - YIELD_THRESHOLD : m_count);
if ((yieldsSoFar % SLEEP_1_EVERY_HOW_MANY_TIMES) == (SLEEP_1_EVERY_HOW_MANY_TIMES - 1))
@@ -197,7 +193,7 @@ namespace System.Threading
#endif
SpinUntil(condition, Timeout.Infinite);
#if DEBUG
- Contract.Assert(result);
+ Debug.Assert(result);
#endif
}
@@ -220,7 +216,7 @@ namespace System.Threading
if (totalMilliseconds < -1 || totalMilliseconds > Int32.MaxValue)
{
throw new System.ArgumentOutOfRangeException(
- "timeout", timeout, Environment.GetResourceString("SpinWait_SpinUntil_TimeoutWrong"));
+ nameof(timeout), timeout, Environment.GetResourceString("SpinWait_SpinUntil_TimeoutWrong"));
}
// Call wait with the timeout milliseconds
@@ -242,11 +238,11 @@ namespace System.Threading
if (millisecondsTimeout < Timeout.Infinite)
{
throw new ArgumentOutOfRangeException(
- "millisecondsTimeout", millisecondsTimeout, Environment.GetResourceString("SpinWait_SpinUntil_TimeoutWrong"));
+ nameof(millisecondsTimeout), millisecondsTimeout, Environment.GetResourceString("SpinWait_SpinUntil_TimeoutWrong"));
}
if (condition == null)
{
- throw new ArgumentNullException("condition", Environment.GetResourceString("SpinWait_SpinUntil_ArgumentNull"));
+ throw new ArgumentNullException(nameof(condition), Environment.GetResourceString("SpinWait_SpinUntil_ArgumentNull"));
}
uint startTime = 0;
if (millisecondsTimeout != 0 && millisecondsTimeout != Timeout.Infinite)
@@ -304,7 +300,7 @@ namespace System.Threading
s_lastProcessorCountRefreshTicks = now;
}
- Contract.Assert(procCount > 0 && procCount <= 64,
+ Debug.Assert(procCount > 0 && procCount <= 64,
"Processor count not within the expected range (1 - 64).");
return procCount;
@@ -345,7 +341,7 @@ namespace System.Threading
public static int UpdateTimeOut(uint startTime, int originalWaitMillisecondsTimeout)
{
// The function must be called in case the time out is not infinite
- Contract.Assert(originalWaitMillisecondsTimeout != Timeout.Infinite);
+ Debug.Assert(originalWaitMillisecondsTimeout != Timeout.Infinite);
uint elapsedMilliseconds = (GetTime() - startTime);
diff --git a/src/mscorlib/src/System/Threading/SynchronizationContext.cs b/src/mscorlib/src/System/Threading/SynchronizationContext.cs
index a3f28d1d73..5531597229 100644
--- a/src/mscorlib/src/System/Threading/SynchronizationContext.cs
+++ b/src/mscorlib/src/System/Threading/SynchronizationContext.cs
@@ -24,6 +24,7 @@ namespace System.Threading
using System.Runtime.ConstrainedExecution;
using System.Reflection;
using System.Security;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Diagnostics.CodeAnalysis;
@@ -43,17 +44,12 @@ namespace System.Threading
// I'd like this to be an interface, or at least an abstract class - but neither seems to play nice with FriendAccessAllowed.
//
[FriendAccessAllowed]
- [SecurityCritical]
internal class WinRTSynchronizationContextFactoryBase
{
- [SecurityCritical]
public virtual SynchronizationContext Create(object coreDispatcher) {return null;}
}
#endif //FEATURE_COMINTEROP
-#if !FEATURE_CORECLR
- [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags =SecurityPermissionFlag.ControlPolicy|SecurityPermissionFlag.ControlEvidence)]
-#endif
public class SynchronizationContext
{
#if FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
@@ -76,7 +72,6 @@ namespace System.Threading
static Type s_cachedPreparedType5;
// protected so that only the derived sync context class can enable these flags
- [System.Security.SecuritySafeCritical] // auto-generated
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "We never dereference s_cachedPreparedType*, so ordering is unimportant")]
protected void SetWaitNotificationRequired()
{
@@ -143,39 +138,43 @@ namespace System.Threading
}
#if FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
- // Method called when the CLR does a wait operation
- [System.Security.SecurityCritical] // auto-generated_required
+ // Method called when the CLR does a wait operation
[CLSCompliant(false)]
[PrePrepareMethod]
public virtual int Wait(IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout)
{
+ return WaitHelper(waitHandles, waitAll, millisecondsTimeout);
+ }
+
+ // Method that can be called by Wait overrides
+ [CLSCompliant(false)]
+ [PrePrepareMethod]
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
+ protected static int WaitHelper(IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout)
+ {
if (waitHandles == null)
{
- throw new ArgumentNullException("waitHandles");
+ throw new ArgumentNullException(nameof(waitHandles));
}
Contract.EndContractBlock();
- return WaitHelper(waitHandles, waitAll, millisecondsTimeout);
+
+ return WaitHelperNative(waitHandles, waitAll, millisecondsTimeout);
}
-
- // Static helper to which the above method can delegate to in order to get the default
+
+ // Static helper to which the above method can delegate to in order to get the default
// COM behavior.
- [System.Security.SecurityCritical] // auto-generated_required
[CLSCompliant(false)]
[PrePrepareMethod]
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
- protected static extern int WaitHelper(IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout);
+ private static extern int WaitHelperNative(IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout);
#endif
-#if FEATURE_CORECLR
-
- [System.Security.SecurityCritical]
public static void SetSynchronizationContext(SynchronizationContext syncContext)
{
Thread.CurrentThread.SynchronizationContext = syncContext;
}
- [System.Security.SecurityCritical]
public static void SetThreadStaticContext(SynchronizationContext syncContext)
{
Thread.CurrentThread.SynchronizationContext = syncContext;
@@ -206,56 +205,11 @@ namespace System.Threading
}
}
-#else //FEATURE_CORECLR
-
- // set SynchronizationContext on the current thread
- [System.Security.SecurityCritical] // auto-generated_required
- public static void SetSynchronizationContext(SynchronizationContext syncContext)
- {
- ExecutionContext ec = Thread.CurrentThread.GetMutableExecutionContext();
- ec.SynchronizationContext = syncContext;
- ec.SynchronizationContextNoFlow = syncContext;
- }
-
- // Get the current SynchronizationContext on the current thread
- public static SynchronizationContext Current
- {
- get
- {
- return Thread.CurrentThread.GetExecutionContextReader().SynchronizationContext ?? GetThreadLocalContext();
- }
- }
-
- // Get the last SynchronizationContext that was set explicitly (not flowed via ExecutionContext.Capture/Run)
- internal static SynchronizationContext CurrentNoFlow
- {
- [FriendAccessAllowed]
- get
- {
- return Thread.CurrentThread.GetExecutionContextReader().SynchronizationContextNoFlow ?? GetThreadLocalContext();
- }
- }
-
- private static SynchronizationContext GetThreadLocalContext()
- {
- SynchronizationContext context = null;
-
-#if FEATURE_APPX
- if (context == null && AppDomain.IsAppXModel())
- context = GetWinRTContext();
-#endif
-
- return context;
- }
-
-#endif //FEATURE_CORECLR
-
#if FEATURE_APPX
- [SecuritySafeCritical]
private static SynchronizationContext GetWinRTContext()
{
- Contract.Assert(Environment.IsWinRTSupported);
- Contract.Assert(AppDomain.IsAppXModel());
+ Debug.Assert(Environment.IsWinRTSupported);
+ Debug.Assert(AppDomain.IsAppXModel());
//
// We call into the VM to get the dispatcher. This is because:
@@ -274,10 +228,8 @@ namespace System.Threading
return null;
}
- [SecurityCritical]
static WinRTSynchronizationContextFactoryBase s_winRTContextFactory;
- [SecurityCritical]
private static WinRTSynchronizationContextFactoryBase GetWinRTSynchronizationContextFactory()
{
//
@@ -295,7 +247,6 @@ namespace System.Threading
}
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SecurityCritical]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Interface)]
private static extern object GetWinRTDispatcherForCurrentThread();
@@ -310,7 +261,6 @@ namespace System.Threading
}
#if FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
- [System.Security.SecurityCritical] // auto-generated
private static int InvokeWaitMethodHelper(SynchronizationContext syncContext, IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout)
{
return syncContext.Wait(waitHandles, waitAll, millisecondsTimeout);
diff --git a/src/mscorlib/src/System/Threading/Tasks/AsyncCausalityTracer.cs b/src/mscorlib/src/System/Threading/Tasks/AsyncCausalityTracer.cs
index c29b11a922..ec7c5aaeea 100644
--- a/src/mscorlib/src/System/Threading/Tasks/AsyncCausalityTracer.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/AsyncCausalityTracer.cs
@@ -131,7 +131,6 @@ namespace System.Threading.Tasks
private static Loggers f_LoggingOn; //assumes false by default
// The precise static constructor will run first time somebody attempts to access this class
- [SecuritySafeCritical]
static AsyncCausalityTracer()
{
if (!Environment.IsWinRTSupported) return;
@@ -153,7 +152,7 @@ namespace System.Threading.Tasks
s_TracerFactory = (WFD.IAsyncCausalityTracerStatics)factory;
EventRegistrationToken token = s_TracerFactory.add_TracingStatusChanged(new EventHandler<WFD.TracingStatusChangedEventArgs>(TracingStatusChangedHandler));
- Contract.Assert(token != default(EventRegistrationToken), "EventRegistrationToken is null");
+ Debug.Assert(token != default(EventRegistrationToken), "EventRegistrationToken is null");
}
catch (Exception ex)
{
@@ -165,7 +164,6 @@ namespace System.Threading.Tasks
}
- [SecuritySafeCritical]
private static void TracingStatusChangedHandler(Object sender, WFD.TracingStatusChangedEventArgs args)
{
if (args.Enabled)
diff --git a/src/mscorlib/src/System/Threading/Tasks/BeginEndAwaitableAdapter.cs b/src/mscorlib/src/System/Threading/Tasks/BeginEndAwaitableAdapter.cs
index 05e6dbf1a9..71eb787c5e 100644
--- a/src/mscorlib/src/System/Threading/Tasks/BeginEndAwaitableAdapter.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/BeginEndAwaitableAdapter.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.IO;
using System.Runtime.CompilerServices;
@@ -62,9 +63,9 @@ internal sealed class BeginEndAwaitableAdapter : ICriticalNotifyCompletion {
/// It expects that an BeginEndAwaitableAdapter instance was supplied to the APM Begin method as the object state.</summary>
public readonly static AsyncCallback Callback = (asyncResult) => {
- Contract.Assert(asyncResult != null);
- Contract.Assert(asyncResult.IsCompleted);
- Contract.Assert(asyncResult.AsyncState is BeginEndAwaitableAdapter);
+ Debug.Assert(asyncResult != null);
+ Debug.Assert(asyncResult.IsCompleted);
+ Debug.Assert(asyncResult.AsyncState is BeginEndAwaitableAdapter);
// Get the adapter object supplied as the "object state" to the Begin method
BeginEndAwaitableAdapter adapter = (BeginEndAwaitableAdapter) asyncResult.AsyncState;
@@ -81,7 +82,7 @@ internal sealed class BeginEndAwaitableAdapter : ICriticalNotifyCompletion {
Action continuation = Interlocked.Exchange(ref adapter._continuation, CALLBACK_RAN);
if (continuation != null) {
- Contract.Assert(continuation != CALLBACK_RAN);
+ Debug.Assert(continuation != CALLBACK_RAN);
continuation();
}
};
@@ -108,10 +109,9 @@ internal sealed class BeginEndAwaitableAdapter : ICriticalNotifyCompletion {
/// <summary>Schedules the continuation to run when the operation completes.</summary>
/// <param name="continuation">The continuation.</param>
- [SecurityCritical]
public void UnsafeOnCompleted(Action continuation) {
- Contract.Assert(continuation != null);
+ Debug.Assert(continuation != null);
OnCompleted(continuation);
}
@@ -120,7 +120,7 @@ internal sealed class BeginEndAwaitableAdapter : ICriticalNotifyCompletion {
/// <param name="continuation">The continuation.</param>
public void OnCompleted(Action continuation) {
- Contract.Assert(continuation != null);
+ Debug.Assert(continuation != null);
// If the continuation field is null, then set it to be the target continuation
// so that when the operation completes, it'll invoke the continuation. If it's non-null,
@@ -139,7 +139,7 @@ internal sealed class BeginEndAwaitableAdapter : ICriticalNotifyCompletion {
/// <returns>The IAsyncResult for the operation.</returns>
public IAsyncResult GetResult() {
- Contract.Assert(_asyncResult != null && _asyncResult.IsCompleted);
+ Debug.Assert(_asyncResult != null && _asyncResult.IsCompleted);
// Get the IAsyncResult
IAsyncResult result = _asyncResult;
diff --git a/src/mscorlib/src/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs b/src/mscorlib/src/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs
index cb4a22bb2b..c7a96b0394 100644
--- a/src/mscorlib/src/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs
@@ -28,7 +28,6 @@ namespace System.Threading.Tasks
/// Provides concurrent and exclusive task schedulers that coordinate to execute
/// tasks while ensuring that concurrent tasks may run concurrently and exclusive tasks never do.
/// </summary>
- [HostProtection(Synchronization = true, ExternalThreading = true)]
[DebuggerDisplay("Concurrent={ConcurrentTaskCountForDebugger}, Exclusive={ExclusiveTaskCountForDebugger}, Mode={ModeForDebugger}")]
[DebuggerTypeProxy(typeof(ConcurrentExclusiveSchedulerPair.DebugView))]
public class ConcurrentExclusiveSchedulerPair
@@ -101,9 +100,9 @@ namespace System.Threading.Tasks
public ConcurrentExclusiveSchedulerPair(TaskScheduler taskScheduler, int maxConcurrencyLevel, int maxItemsPerTask)
{
// Validate arguments
- if (taskScheduler == null) throw new ArgumentNullException("taskScheduler");
- if (maxConcurrencyLevel == 0 || maxConcurrencyLevel < -1) throw new ArgumentOutOfRangeException("maxConcurrencyLevel");
- if (maxItemsPerTask == 0 || maxItemsPerTask < -1) throw new ArgumentOutOfRangeException("maxItemsPerTask");
+ if (taskScheduler == null) throw new ArgumentNullException(nameof(taskScheduler));
+ if (maxConcurrencyLevel == 0 || maxConcurrencyLevel < -1) throw new ArgumentOutOfRangeException(nameof(maxConcurrencyLevel));
+ if (maxItemsPerTask == 0 || maxItemsPerTask < -1) throw new ArgumentOutOfRangeException(nameof(maxItemsPerTask));
Contract.EndContractBlock();
// Store configuration
@@ -213,13 +212,13 @@ namespace System.Threading.Tasks
ThreadPool.QueueUserWorkItem(state =>
{
var localCs = (CompletionState)state; // don't use 'cs', as it'll force a closure
- Contract.Assert(!localCs.Task.IsCompleted, "Completion should only happen once.");
+ Debug.Assert(!localCs.Task.IsCompleted, "Completion should only happen once.");
var exceptions = localCs.m_exceptions;
bool success = (exceptions != null && exceptions.Count > 0) ?
localCs.TrySetException(exceptions) :
localCs.TrySetResult(default(VoidTaskResult));
- Contract.Assert(success, "Expected to complete completion task.");
+ Debug.Assert(success, "Expected to complete completion task.");
}, cs);
}
}
@@ -336,7 +335,7 @@ namespace System.Threading.Tasks
// Check to see if all tasks have completed and if completion has been requested.
CleanupStateIfCompletingAndQuiesced();
}
- else Contract.Assert(m_processingCount == EXCLUSIVE_PROCESSING_SENTINEL, "The processing count must be the sentinel if it's not >= 0.");
+ else Debug.Assert(m_processingCount == EXCLUSIVE_PROCESSING_SENTINEL, "The processing count must be the sentinel if it's not >= 0.");
}
/// <summary>
@@ -351,7 +350,7 @@ namespace System.Threading.Tasks
try
{
// Note that we're processing exclusive tasks on the current thread
- Contract.Assert(!m_threadProcessingMapping.ContainsKey(Thread.CurrentThread.ManagedThreadId),
+ Debug.Assert(!m_threadProcessingMapping.ContainsKey(Thread.CurrentThread.ManagedThreadId),
"This thread should not yet be involved in this pair's processing.");
m_threadProcessingMapping[Thread.CurrentThread.ManagedThreadId] = ProcessingMode.ProcessingExclusiveTask;
@@ -372,7 +371,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);
- Contract.Assert(currentMode == ProcessingMode.ProcessingExclusiveTask,
+ Debug.Assert(currentMode == ProcessingMode.ProcessingExclusiveTask,
"Somehow we ended up escaping exclusive mode.");
lock (ValueLock)
@@ -382,7 +381,7 @@ namespace System.Threading.Tasks
// There might be more concurrent tasks available, for example, if concurrent tasks arrived
// after we exited the loop, or if we exited the loop while concurrent tasks were still
// available but we hit our maxItemsPerTask limit.
- Contract.Assert(m_processingCount == EXCLUSIVE_PROCESSING_SENTINEL, "The processing mode should not have deviated from exclusive.");
+ Debug.Assert(m_processingCount == EXCLUSIVE_PROCESSING_SENTINEL, "The processing mode should not have deviated from exclusive.");
m_processingCount = 0;
ProcessAsyncIfNecessary(true);
}
@@ -400,7 +399,7 @@ namespace System.Threading.Tasks
try
{
// Note that we're processing concurrent tasks on the current thread
- Contract.Assert(!m_threadProcessingMapping.ContainsKey(Thread.CurrentThread.ManagedThreadId),
+ Debug.Assert(!m_threadProcessingMapping.ContainsKey(Thread.CurrentThread.ManagedThreadId),
"This thread should not yet be involved in this pair's processing.");
m_threadProcessingMapping[Thread.CurrentThread.ManagedThreadId] = ProcessingMode.ProcessingConcurrentTasks;
@@ -432,7 +431,7 @@ namespace System.Threading.Tasks
// We're no longer processing concurrent tasks on the current thread
ProcessingMode currentMode;
m_threadProcessingMapping.TryRemove(Thread.CurrentThread.ManagedThreadId, out currentMode);
- Contract.Assert(currentMode == ProcessingMode.ProcessingConcurrentTasks,
+ Debug.Assert(currentMode == ProcessingMode.ProcessingConcurrentTasks,
"Somehow we ended up escaping concurrent mode.");
lock (ValueLock)
@@ -442,7 +441,7 @@ namespace System.Threading.Tasks
// There might be more concurrent tasks available, for example, if concurrent tasks arrived
// after we exited the loop, or if we exited the loop while concurrent tasks were still
// available but we hit our maxItemsPerTask limit.
- Contract.Assert(m_processingCount > 0, "The procesing mode should not have deviated from concurrent.");
+ Debug.Assert(m_processingCount > 0, "The procesing mode should not have deviated from concurrent.");
if (m_processingCount > 0) --m_processingCount;
ProcessAsyncIfNecessary(true);
}
@@ -524,10 +523,9 @@ namespace System.Threading.Tasks
/// <summary>Queues a task to the scheduler.</summary>
/// <param name="task">The task to be queued.</param>
- [SecurityCritical]
protected internal override void QueueTask(Task task)
{
- Contract.Assert(task != null, "Infrastructure should have provided a non-null task.");
+ Debug.Assert(task != null, "Infrastructure should have provided a non-null task.");
lock (m_pair.ValueLock)
{
// If the scheduler has already had completion requested, no new work is allowed to be scheduled
@@ -541,10 +539,9 @@ namespace System.Threading.Tasks
/// <summary>Executes a task on this scheduler.</summary>
/// <param name="task">The task to be executed.</param>
- [SecuritySafeCritical]
internal void ExecuteTask(Task task)
{
- Contract.Assert(task != null, "Infrastructure should have provided a non-null task.");
+ Debug.Assert(task != null, "Infrastructure should have provided a non-null task.");
base.TryExecuteTask(task);
}
@@ -552,10 +549,9 @@ namespace System.Threading.Tasks
/// <param name="task">The task to execute.</param>
/// <param name="taskWasPreviouslyQueued">Whether the task was previously queued to the scheduler.</param>
/// <returns>true if the task could be executed; otherwise, false.</returns>
- [SecurityCritical]
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
- Contract.Assert(task != null, "Infrastructure should have provided a non-null task.");
+ Debug.Assert(task != null, "Infrastructure should have provided a non-null task.");
// If the scheduler has had completion requested, no new work is allowed to be scheduled.
// A non-locked read on m_completionRequested (in CompletionRequested) is acceptable here because:
@@ -628,7 +624,7 @@ namespace System.Threading.Tasks
}
catch
{
- Contract.Assert(t.IsFaulted, "Task should be faulted due to the scheduler faulting it and throwing the exception.");
+ Debug.Assert(t.IsFaulted, "Task should be faulted due to the scheduler faulting it and throwing the exception.");
var ignored = t.Exception;
throw;
}
@@ -642,7 +638,6 @@ namespace System.Threading.Tasks
/// This method is separated out not because of performance reasons but so that
/// the SecuritySafeCritical attribute may be employed.
/// </remarks>
- [SecuritySafeCritical]
private static bool TryExecuteTaskShim(object state)
{
var tuple = (Tuple<ConcurrentExclusiveTaskScheduler, Task>)state;
@@ -651,7 +646,6 @@ namespace System.Threading.Tasks
/// <summary>Gets for debugging purposes the tasks scheduled to this scheduler.</summary>
/// <returns>An enumerable of the tasks queued.</returns>
- [SecurityCritical]
protected override IEnumerable<Task> GetScheduledTasks() { return m_tasks; }
/// <summary>Gets the number of tasks queued to this scheduler.</summary>
@@ -748,11 +742,11 @@ namespace System.Threading.Tasks
exceptionThrown = false;
}
catch (SynchronizationLockException) { exceptionThrown = true; }
- Contract.Assert(held == !exceptionThrown, "The locking scheme was not correctly followed.");
+ Debug.Assert(held == !exceptionThrown, "The locking scheme was not correctly followed.");
}
#endif
#else
- Contract.Assert(Monitor.IsEntered(syncObj) == held, "The locking scheme was not correctly followed.");
+ Debug.Assert(Monitor.IsEntered(syncObj) == held, "The locking scheme was not correctly followed.");
#endif
}
diff --git a/src/mscorlib/src/System/Threading/Tasks/FutureFactory.cs b/src/mscorlib/src/System/Threading/Tasks/FutureFactory.cs
index b1f634c707..c98e219e86 100644
--- a/src/mscorlib/src/System/Threading/Tasks/FutureFactory.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/FutureFactory.cs
@@ -15,6 +15,7 @@ using System.Security;
using System.Security.Permissions;
using System.Runtime.CompilerServices;
using System.Threading;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.Versioning;
@@ -38,7 +39,6 @@ namespace System.Threading.Tasks
/// <see cref="System.Threading.Tasks.Task{TResult}.Factory">Task{TResult}.Factory</see> property.
/// </para>
/// </remarks>
- [HostProtection(Synchronization = true, ExternalThreading = true)]
public class TaskFactory<TResult>
{
// Member variables, DefaultScheduler, other properties and ctors
@@ -832,32 +832,17 @@ namespace System.Threading.Tasks
try
{
- // Do NOT change the code below.
- // 4.5 relies on the fact that IAsyncResult CompletedSynchronously flag needs to be set correctly,
- // sadly this has not been the case that is why the behaviour from 4.5 broke 4.0 buggy apps. Any other
- // change will likely brake 4.5 behavior so if possible never touch this code again.
- if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5)
+ //This is 4.5 behaviour
+ //if we don't require synchronization, a faster set result path is taken
+ var asyncResult = beginMethod(iar =>
{
- //This is 4.5 behaviour
- //if we don't require synchronization, a faster set result path is taken
- var asyncResult = beginMethod(iar =>
- {
- if (!iar.CompletedSynchronously)
- FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true);
- }, state);
- if (asyncResult.CompletedSynchronously)
- {
- Contract.Assert(asyncResult.IsCompleted, "If the operation completed synchronously, it must be completed.");
- FromAsyncCoreLogic(asyncResult, endFunction, endAction, promise, requiresSynchronization: false);
- }
- }
- else
- {
- //This is the original 4.0 behaviour
- var asyncResult = beginMethod(iar =>
- {
+ if (!iar.CompletedSynchronously)
FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true);
- }, state);
+ }, state);
+ if (asyncResult.CompletedSynchronously)
+ {
+ Debug.Assert(asyncResult.IsCompleted, "If the operation completed synchronously, it must be completed.");
+ FromAsyncCoreLogic(asyncResult, endFunction, endAction, promise, requiresSynchronization: false);
}
}
catch
@@ -969,31 +954,16 @@ namespace System.Threading.Tasks
try
{
- // Do NOT change the code below.
- // 4.5 relies on the fact that IAsyncResult CompletedSynchronously flag needs to be set correctly,
- // sadly this has not been the case that is why the behaviour from 4.5 broke 4.0 buggy apps. Any other
- // change will likely brake 4.5 behavior so if possible never touch this code again.
- if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5)
+ //if we don't require synchronization, a faster set result path is taken
+ var asyncResult = beginMethod(arg1, iar =>
{
- //if we don't require synchronization, a faster set result path is taken
- var asyncResult = beginMethod(arg1, iar =>
- {
- if (!iar.CompletedSynchronously)
- FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true);
- }, state);
- if (asyncResult.CompletedSynchronously)
- {
- Contract.Assert(asyncResult.IsCompleted, "If the operation completed synchronously, it must be completed.");
- FromAsyncCoreLogic(asyncResult, endFunction, endAction, promise, requiresSynchronization: false);
- }
- }
- else
- {
- //quirk for previous versions
- var asyncResult = beginMethod(arg1, iar =>
- {
+ if (!iar.CompletedSynchronously)
FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true);
- }, state);
+ }, state);
+ if (asyncResult.CompletedSynchronously)
+ {
+ Debug.Assert(asyncResult.IsCompleted, "If the operation completed synchronously, it must be completed.");
+ FromAsyncCoreLogic(asyncResult, endFunction, endAction, promise, requiresSynchronization: false);
}
}
catch
@@ -1114,31 +1084,16 @@ namespace System.Threading.Tasks
try
{
- // Do NOT change the code below.
- // 4.5 relies on the fact that IAsyncResult CompletedSynchronously flag needs to be set correctly,
- // sadly this has not been the case that is why the behaviour from 4.5 broke 4.0 buggy apps. Any other
- // change will likely brake 4.5 behavior so if possible never touch this code again.
- if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5)
+ //if we don't require synchronization, a faster set result path is taken
+ var asyncResult = beginMethod(arg1, arg2, iar =>
{
- //if we don't require synchronization, a faster set result path is taken
- var asyncResult = beginMethod(arg1, arg2, iar =>
- {
- if (!iar.CompletedSynchronously)
- FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true);
- }, state);
- if (asyncResult.CompletedSynchronously)
- {
- Contract.Assert(asyncResult.IsCompleted, "If the operation completed synchronously, it must be completed.");
- FromAsyncCoreLogic(asyncResult, endFunction, endAction, promise, requiresSynchronization: false);
- }
- }
- else
- {
- //quirk for previous versions
- var asyncResult = beginMethod(arg1, arg2, iar =>
- {
+ if (!iar.CompletedSynchronously)
FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true);
- }, state);
+ }, state);
+ if (asyncResult.CompletedSynchronously)
+ {
+ Debug.Assert(asyncResult.IsCompleted, "If the operation completed synchronously, it must be completed.");
+ FromAsyncCoreLogic(asyncResult, endFunction, endAction, promise, requiresSynchronization: false);
}
}
catch
@@ -1266,31 +1221,16 @@ namespace System.Threading.Tasks
try
{
- // Do NOT change the code below.
- // 4.5 relies on the fact that IAsyncResult CompletedSynchronously flag needs to be set correctly,
- // sadly this has not been the case that is why the behaviour from 4.5 broke 4.0 buggy apps. Any other
- // change will likely brake 4.5 behavior so if possible never touch this code again.
- if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5)
+ //if we don't require synchronization, a faster set result path is taken
+ var asyncResult = beginMethod(arg1, arg2, arg3, iar =>
{
- //if we don't require synchronization, a faster set result path is taken
- var asyncResult = beginMethod(arg1, arg2, arg3, iar =>
- {
- if (!iar.CompletedSynchronously)
- FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true);
- }, state);
- if (asyncResult.CompletedSynchronously)
- {
- Contract.Assert(asyncResult.IsCompleted, "If the operation completed synchronously, it must be completed.");
- FromAsyncCoreLogic(asyncResult, endFunction, endAction, promise, requiresSynchronization: false);
- }
- }
- else
- {
- //quirk for previous versions
- var asyncResult = beginMethod(arg1, arg2, arg3, iar =>
- {
+ if (!iar.CompletedSynchronously)
FromAsyncCoreLogic(iar, endFunction, endAction, promise, requiresSynchronization: true);
- }, state);
+ }, state);
+ if (asyncResult.CompletedSynchronously)
+ {
+ Debug.Assert(asyncResult.IsCompleted, "If the operation completed synchronously, it must be completed.");
+ FromAsyncCoreLogic(asyncResult, endFunction, endAction, promise, requiresSynchronization: false);
}
}
catch
@@ -1330,9 +1270,9 @@ namespace System.Threading.Tasks
where TInstance : class
{
// Validate arguments, but only with asserts, as this is an internal only implementation.
- Contract.Assert(thisRef != null, "Expected a non-null thisRef");
- Contract.Assert(beginMethod != null, "Expected a non-null beginMethod");
- Contract.Assert(endMethod != null, "Expected a non-null endMethod");
+ Debug.Assert(thisRef != null, "Expected a non-null thisRef");
+ Debug.Assert(beginMethod != null, "Expected a non-null beginMethod");
+ Debug.Assert(endMethod != null, "Expected a non-null endMethod");
// Create the promise and start the operation.
// No try/catch is necessary here as we want exceptions to bubble out, and because
@@ -1345,7 +1285,7 @@ namespace System.Threading.Tasks
// If it completed synchronously, we'll handle that here.
if (asyncResult.CompletedSynchronously)
{
- Contract.Assert(asyncResult.IsCompleted, "If the operation completed synchronously, it must be completed.");
+ Debug.Assert(asyncResult.IsCompleted, "If the operation completed synchronously, it must be completed.");
promise.Complete(thisRef, endMethod, asyncResult, requiresSynchronization: false);
}
@@ -1425,7 +1365,7 @@ namespace System.Threading.Tasks
TInstance thisRef, Func<TInstance, IAsyncResult, TResult> endMethod, IAsyncResult asyncResult,
bool requiresSynchronization)
{
- Contract.Assert(!IsCompleted, "The task should not have been completed yet.");
+ Debug.Assert(!IsCompleted, "The task should not have been completed yet.");
// Run the end method and complete the task
bool successfullySet = false;
@@ -1454,7 +1394,7 @@ namespace System.Threading.Tasks
{
successfullySet = TrySetException(exc);
}
- Contract.Assert(successfullySet, "Expected the task to not yet be completed");
+ Debug.Assert(successfullySet, "Expected the task to not yet be completed");
}
}
@@ -1801,7 +1741,7 @@ namespace System.Threading.Tasks
}
else
{
- Contract.Assert(continuationAction != null);
+ Debug.Assert(continuationAction != null);
return starter.ContinueWith<TResult>(
// use a cached delegate
@@ -1854,7 +1794,7 @@ namespace System.Threading.Tasks
}
else
{
- Contract.Assert(continuationAction != null);
+ Debug.Assert(continuationAction != null);
return starter.ContinueWith<TResult>(
//the following delegate avoids closure capture as much as possible
//completedTasks.Result == tasksCopy;
@@ -2200,7 +2140,7 @@ namespace System.Threading.Tasks
}
else
{
- Contract.Assert(continuationAction != null);
+ Debug.Assert(continuationAction != null);
return starter.ContinueWith<TResult>(
//the following delegate avoids closure capture as much as possible
//completedTask.Result is the winning task; state == continuationAction
@@ -2246,7 +2186,7 @@ namespace System.Threading.Tasks
}
else
{
- Contract.Assert(continuationAction != null);
+ Debug.Assert(continuationAction != null);
return starter.ContinueWith<TResult>(
// Use a cached delegate
GenericDelegateCache<TAntecedentResult,TResult>.CWAnyActionDelegate,
diff --git a/src/mscorlib/src/System/Threading/Tasks/Parallel.cs b/src/mscorlib/src/System/Threading/Tasks/Parallel.cs
index 5ec2ae33c0..7808943870 100644
--- a/src/mscorlib/src/System/Threading/Tasks/Parallel.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/Parallel.cs
@@ -98,7 +98,7 @@ namespace System.Threading.Tasks
set
{
if ((value == 0) || (value < -1))
- throw new ArgumentOutOfRangeException("MaxDegreeOfParallelism");
+ throw new ArgumentOutOfRangeException(nameof(MaxDegreeOfParallelism));
m_maxDegreeOfParallelism = value;
}
}
@@ -142,7 +142,6 @@ namespace System.Threading.Tasks
/// The <see cref="T:System.Threading.Tasks.Parallel"/> class provides library-based data parallel replacements
/// for common operations such as for loops, for each loops, and execution of a set of statements.
/// </remarks>
- [HostProtection(Synchronization = true, ExternalThreading = true)]
public static class Parallel
{
// static counter for generating unique Fork/Join Context IDs to be used in ETW events
@@ -208,11 +207,11 @@ namespace System.Threading.Tasks
{
if (actions == null)
{
- throw new ArgumentNullException("actions");
+ throw new ArgumentNullException(nameof(actions));
}
if (parallelOptions == null)
{
- throw new ArgumentNullException("parallelOptions");
+ throw new ArgumentNullException(nameof(parallelOptions));
}
// Throw an ODE if we're passed a disposed CancellationToken.
@@ -423,7 +422,7 @@ namespace System.Threading.Tasks
{
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
return ForWorker<object>(
@@ -452,7 +451,7 @@ namespace System.Threading.Tasks
{
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
return ForWorker64<object>(
@@ -491,11 +490,11 @@ namespace System.Threading.Tasks
{
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
if (parallelOptions == null)
{
- throw new ArgumentNullException("parallelOptions");
+ throw new ArgumentNullException(nameof(parallelOptions));
}
return ForWorker<object>(
@@ -534,11 +533,11 @@ namespace System.Threading.Tasks
{
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
if (parallelOptions == null)
{
- throw new ArgumentNullException("parallelOptions");
+ throw new ArgumentNullException(nameof(parallelOptions));
}
return ForWorker64<object>(
@@ -590,7 +589,7 @@ namespace System.Threading.Tasks
{
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
return ForWorker<object>(
@@ -620,7 +619,7 @@ namespace System.Threading.Tasks
{
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
return ForWorker64<object>(
@@ -661,11 +660,11 @@ namespace System.Threading.Tasks
{
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
if (parallelOptions == null)
{
- throw new ArgumentNullException("parallelOptions");
+ throw new ArgumentNullException(nameof(parallelOptions));
}
return ForWorker<object>(
@@ -707,11 +706,11 @@ namespace System.Threading.Tasks
{
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
if (parallelOptions == null)
{
- throw new ArgumentNullException("parallelOptions");
+ throw new ArgumentNullException(nameof(parallelOptions));
}
return ForWorker64<object>(
@@ -765,15 +764,15 @@ namespace System.Threading.Tasks
{
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
if (localInit == null)
{
- throw new ArgumentNullException("localInit");
+ throw new ArgumentNullException(nameof(localInit));
}
if (localFinally == null)
{
- throw new ArgumentNullException("localFinally");
+ throw new ArgumentNullException(nameof(localFinally));
}
return ForWorker(
@@ -827,15 +826,15 @@ namespace System.Threading.Tasks
{
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
if (localInit == null)
{
- throw new ArgumentNullException("localInit");
+ throw new ArgumentNullException(nameof(localInit));
}
if (localFinally == null)
{
- throw new ArgumentNullException("localFinally");
+ throw new ArgumentNullException(nameof(localFinally));
}
return ForWorker64(
@@ -900,19 +899,19 @@ namespace System.Threading.Tasks
{
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
if (localInit == null)
{
- throw new ArgumentNullException("localInit");
+ throw new ArgumentNullException(nameof(localInit));
}
if (localFinally == null)
{
- throw new ArgumentNullException("localFinally");
+ throw new ArgumentNullException(nameof(localFinally));
}
if (parallelOptions == null)
{
- throw new ArgumentNullException("parallelOptions");
+ throw new ArgumentNullException(nameof(parallelOptions));
}
return ForWorker(
@@ -977,19 +976,19 @@ namespace System.Threading.Tasks
{
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
if (localInit == null)
{
- throw new ArgumentNullException("localInit");
+ throw new ArgumentNullException(nameof(localInit));
}
if (localFinally == null)
{
- throw new ArgumentNullException("localFinally");
+ throw new ArgumentNullException(nameof(localFinally));
}
if (parallelOptions == null)
{
- throw new ArgumentNullException("parallelOptions");
+ throw new ArgumentNullException(nameof(parallelOptions));
}
@@ -1031,9 +1030,9 @@ namespace System.Threading.Tasks
Func<int, ParallelLoopState, TLocal, TLocal> bodyWithLocal,
Func<TLocal> localInit, Action<TLocal> localFinally)
{
- Contract.Assert(((body == null ? 0 : 1) + (bodyWithState == null ? 0 : 1) + (bodyWithLocal == null ? 0 : 1)) == 1,
+ Debug.Assert(((body == null ? 0 : 1) + (bodyWithState == null ? 0 : 1) + (bodyWithLocal == null ? 0 : 1)) == 1,
"expected exactly one body function to be supplied");
- Contract.Assert(bodyWithLocal != null || (localInit == null && localFinally == null),
+ Debug.Assert(bodyWithLocal != null || (localInit == null && localFinally == null),
"thread local functions should only be supplied for loops w/ thread local bodies");
// Instantiate our result. Specifics will be filled in later.
@@ -1157,12 +1156,12 @@ namespace System.Threading.Tasks
if (bodyWithState != null)
{
- Contract.Assert(sharedPStateFlags != null);
+ Debug.Assert(sharedPStateFlags != null);
state = new ParallelLoopState32(sharedPStateFlags);
}
else if (bodyWithLocal != null)
{
- Contract.Assert(sharedPStateFlags != null);
+ Debug.Assert(sharedPStateFlags != null);
state = new ParallelLoopState32(sharedPStateFlags);
if (localInit != null)
{
@@ -1346,9 +1345,9 @@ namespace System.Threading.Tasks
Func<long, ParallelLoopState, TLocal, TLocal> bodyWithLocal,
Func<TLocal> localInit, Action<TLocal> localFinally)
{
- Contract.Assert(((body == null ? 0 : 1) + (bodyWithState == null ? 0 : 1) + (bodyWithLocal == null ? 0 : 1)) == 1,
+ Debug.Assert(((body == null ? 0 : 1) + (bodyWithState == null ? 0 : 1) + (bodyWithLocal == null ? 0 : 1)) == 1,
"expected exactly one body function to be supplied");
- Contract.Assert(bodyWithLocal != null || (localInit == null && localFinally == null),
+ Debug.Assert(bodyWithLocal != null || (localInit == null && localFinally == null),
"thread local functions should only be supplied for loops w/ thread local bodies");
// Instantiate our result. Specifics will be filled in later.
@@ -1471,12 +1470,12 @@ namespace System.Threading.Tasks
if (bodyWithState != null)
{
- Contract.Assert(sharedPStateFlags != null);
+ Debug.Assert(sharedPStateFlags != null);
state = new ParallelLoopState64(sharedPStateFlags);
}
else if (bodyWithLocal != null)
{
- Contract.Assert(sharedPStateFlags != null);
+ Debug.Assert(sharedPStateFlags != null);
state = new ParallelLoopState64(sharedPStateFlags);
// If a thread-local selector was supplied, invoke it. Otherwise, use the default.
@@ -1656,11 +1655,11 @@ namespace System.Threading.Tasks
{
if (source == null)
{
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
}
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
return ForEachWorker<TSource, object>(
@@ -1701,15 +1700,15 @@ namespace System.Threading.Tasks
{
if (source == null)
{
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
}
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
if (parallelOptions == null)
{
- throw new ArgumentNullException("parallelOptions");
+ throw new ArgumentNullException(nameof(parallelOptions));
}
return ForEachWorker<TSource, object>(
@@ -1741,11 +1740,11 @@ namespace System.Threading.Tasks
{
if (source == null)
{
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
}
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
return ForEachWorker<TSource, object>(
@@ -1788,15 +1787,15 @@ namespace System.Threading.Tasks
{
if (source == null)
{
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
}
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
if (parallelOptions == null)
{
- throw new ArgumentNullException("parallelOptions");
+ throw new ArgumentNullException(nameof(parallelOptions));
}
return ForEachWorker<TSource, object>(
@@ -1828,11 +1827,11 @@ namespace System.Threading.Tasks
{
if (source == null)
{
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
}
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
return ForEachWorker<TSource, object>(
@@ -1875,15 +1874,15 @@ namespace System.Threading.Tasks
{
if (source == null)
{
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
}
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
if (parallelOptions == null)
{
- throw new ArgumentNullException("parallelOptions");
+ throw new ArgumentNullException(nameof(parallelOptions));
}
return ForEachWorker<TSource, object>(
@@ -1936,19 +1935,19 @@ namespace System.Threading.Tasks
{
if (source == null)
{
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
}
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
if (localInit == null)
{
- throw new ArgumentNullException("localInit");
+ throw new ArgumentNullException(nameof(localInit));
}
if (localFinally == null)
{
- throw new ArgumentNullException("localFinally");
+ throw new ArgumentNullException(nameof(localFinally));
}
return ForEachWorker<TSource, TLocal>(
@@ -2013,23 +2012,23 @@ namespace System.Threading.Tasks
{
if (source == null)
{
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
}
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
if (localInit == null)
{
- throw new ArgumentNullException("localInit");
+ throw new ArgumentNullException(nameof(localInit));
}
if (localFinally == null)
{
- throw new ArgumentNullException("localFinally");
+ throw new ArgumentNullException(nameof(localFinally));
}
if (parallelOptions == null)
{
- throw new ArgumentNullException("parallelOptions");
+ throw new ArgumentNullException(nameof(parallelOptions));
}
return ForEachWorker<TSource, TLocal>(
@@ -2082,19 +2081,19 @@ namespace System.Threading.Tasks
{
if (source == null)
{
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
}
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
if (localInit == null)
{
- throw new ArgumentNullException("localInit");
+ throw new ArgumentNullException(nameof(localInit));
}
if (localFinally == null)
{
- throw new ArgumentNullException("localFinally");
+ throw new ArgumentNullException(nameof(localFinally));
}
return ForEachWorker<TSource, TLocal>(
@@ -2158,23 +2157,23 @@ namespace System.Threading.Tasks
{
if (source == null)
{
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
}
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
if (localInit == null)
{
- throw new ArgumentNullException("localInit");
+ throw new ArgumentNullException(nameof(localInit));
}
if (localFinally == null)
{
- throw new ArgumentNullException("localFinally");
+ throw new ArgumentNullException(nameof(localFinally));
}
if (parallelOptions == null)
{
- throw new ArgumentNullException("parallelOptions");
+ throw new ArgumentNullException(nameof(parallelOptions));
}
return ForEachWorker<TSource, TLocal>(
@@ -2214,10 +2213,10 @@ namespace System.Threading.Tasks
Func<TSource, ParallelLoopState, long, TLocal, TLocal> bodyWithEverything,
Func<TLocal> localInit, Action<TLocal> localFinally)
{
- Contract.Assert(((body == null ? 0 : 1) + (bodyWithState == null ? 0 : 1) +
+ Debug.Assert(((body == null ? 0 : 1) + (bodyWithState == null ? 0 : 1) +
(bodyWithStateAndIndex == null ? 0 : 1) + (bodyWithStateAndLocal == null ? 0 : 1) + (bodyWithEverything == null ? 0 : 1)) == 1,
"expected exactly one body function to be supplied");
- Contract.Assert((bodyWithStateAndLocal != null) || (bodyWithEverything != null) || (localInit == null && localFinally == null),
+ Debug.Assert((bodyWithStateAndLocal != null) || (bodyWithEverything != null) || (localInit == null && localFinally == null),
"thread local functions should only be supplied for loops w/ thread local bodies");
// Before getting started, do a quick peek to see if we have been canceled already
@@ -2278,8 +2277,8 @@ namespace System.Threading.Tasks
Func<TSource, ParallelLoopState, long, TLocal, TLocal> bodyWithEverything,
Func<TLocal> localInit, Action<TLocal> localFinally)
{
- Contract.Assert(array != null);
- Contract.Assert(parallelOptions != null, "ForEachWorker(array): parallelOptions is null");
+ Debug.Assert(array != null);
+ Debug.Assert(parallelOptions != null, "ForEachWorker(array): parallelOptions is null");
int from = array.GetLowerBound(0);
int to = array.GetUpperBound(0) + 1;
@@ -2337,8 +2336,8 @@ namespace System.Threading.Tasks
Func<TSource, ParallelLoopState, long, TLocal, TLocal> bodyWithEverything,
Func<TLocal> localInit, Action<TLocal> localFinally)
{
- Contract.Assert(list != null);
- Contract.Assert(parallelOptions != null, "ForEachWorker(list): parallelOptions is null");
+ Debug.Assert(list != null);
+ Debug.Assert(parallelOptions != null, "ForEachWorker(list): parallelOptions is null");
if (body != null)
{
@@ -2416,11 +2415,11 @@ namespace System.Threading.Tasks
{
if (source == null)
{
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
}
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
return PartitionerForEachWorker<TSource, object>(source, s_defaultParallelOptions, body, null, null, null, null, null, null);
@@ -2475,11 +2474,11 @@ namespace System.Threading.Tasks
{
if (source == null)
{
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
}
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
return PartitionerForEachWorker<TSource, object>(source, s_defaultParallelOptions, null, body, null, null, null, null, null);
@@ -2537,11 +2536,11 @@ namespace System.Threading.Tasks
{
if (source == null)
{
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
}
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
if (!source.KeysNormalized)
@@ -2621,19 +2620,19 @@ namespace System.Threading.Tasks
{
if (source == null)
{
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
}
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
if (localInit == null)
{
- throw new ArgumentNullException("localInit");
+ throw new ArgumentNullException(nameof(localInit));
}
if (localFinally == null)
{
- throw new ArgumentNullException("localFinally");
+ throw new ArgumentNullException(nameof(localFinally));
}
return PartitionerForEachWorker<TSource, TLocal>(source, s_defaultParallelOptions, null, null, null, body, null, localInit, localFinally);
@@ -2711,19 +2710,19 @@ namespace System.Threading.Tasks
{
if (source == null)
{
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
}
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
if (localInit == null)
{
- throw new ArgumentNullException("localInit");
+ throw new ArgumentNullException(nameof(localInit));
}
if (localFinally == null)
{
- throw new ArgumentNullException("localFinally");
+ throw new ArgumentNullException(nameof(localFinally));
}
if (!source.KeysNormalized)
@@ -2793,15 +2792,15 @@ namespace System.Threading.Tasks
{
if (source == null)
{
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
}
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
if (parallelOptions == null)
{
- throw new ArgumentNullException("parallelOptions");
+ throw new ArgumentNullException(nameof(parallelOptions));
}
return PartitionerForEachWorker<TSource, object>(source, parallelOptions, body, null, null, null, null, null, null);
@@ -2868,15 +2867,15 @@ namespace System.Threading.Tasks
{
if (source == null)
{
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
}
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
if (parallelOptions == null)
{
- throw new ArgumentNullException("parallelOptions");
+ throw new ArgumentNullException(nameof(parallelOptions));
}
return PartitionerForEachWorker<TSource, object>(source, parallelOptions, null, body, null, null, null, null, null);
@@ -2946,15 +2945,15 @@ namespace System.Threading.Tasks
{
if (source == null)
{
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
}
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
if (parallelOptions == null)
{
- throw new ArgumentNullException("parallelOptions");
+ throw new ArgumentNullException(nameof(parallelOptions));
}
if (!source.KeysNormalized)
@@ -3046,23 +3045,23 @@ namespace System.Threading.Tasks
{
if (source == null)
{
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
}
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
if (localInit == null)
{
- throw new ArgumentNullException("localInit");
+ throw new ArgumentNullException(nameof(localInit));
}
if (localFinally == null)
{
- throw new ArgumentNullException("localFinally");
+ throw new ArgumentNullException(nameof(localFinally));
}
if (parallelOptions == null)
{
- throw new ArgumentNullException("parallelOptions");
+ throw new ArgumentNullException(nameof(parallelOptions));
}
return PartitionerForEachWorker<TSource, TLocal>(source, parallelOptions, null, null, null, body, null, localInit, localFinally);
@@ -3152,23 +3151,23 @@ namespace System.Threading.Tasks
{
if (source == null)
{
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
}
if (body == null)
{
- throw new ArgumentNullException("body");
+ throw new ArgumentNullException(nameof(body));
}
if (localInit == null)
{
- throw new ArgumentNullException("localInit");
+ throw new ArgumentNullException(nameof(localInit));
}
if (localFinally == null)
{
- throw new ArgumentNullException("localFinally");
+ throw new ArgumentNullException(nameof(localFinally));
}
if (parallelOptions == null)
{
- throw new ArgumentNullException("parallelOptions");
+ throw new ArgumentNullException(nameof(parallelOptions));
}
if (!source.KeysNormalized)
@@ -3191,14 +3190,14 @@ namespace System.Threading.Tasks
Func<TLocal> localInit,
Action<TLocal> localFinally)
{
- Contract.Assert(((simpleBody == null ? 0 : 1) + (bodyWithState == null ? 0 : 1) +
+ Debug.Assert(((simpleBody == null ? 0 : 1) + (bodyWithState == null ? 0 : 1) +
(bodyWithStateAndIndex == null ? 0 : 1) + (bodyWithStateAndLocal == null ? 0 : 1) + (bodyWithEverything == null ? 0 : 1)) == 1,
"PartitionForEach: expected exactly one body function to be supplied");
- Contract.Assert((bodyWithStateAndLocal != null) || (bodyWithEverything != null) || (localInit == null && localFinally == null),
+ Debug.Assert((bodyWithStateAndLocal != null) || (bodyWithEverything != null) || (localInit == null && localFinally == null),
"PartitionForEach: thread local functions should only be supplied for loops w/ thread local bodies");
OrderablePartitioner<TSource> orderedSource = source as OrderablePartitioner<TSource>;
- Contract.Assert((orderedSource != null) || (bodyWithStateAndIndex == null && bodyWithEverything == null),
+ Debug.Assert((orderedSource != null) || (bodyWithStateAndIndex == null && bodyWithEverything == null),
"PartitionForEach: bodies with indices are only allowable for OrderablePartitioner");
if (!source.SupportsDynamicPartitions)
@@ -3401,7 +3400,7 @@ namespace System.Threading.Tasks
else if (bodyWithStateAndLocal != null)
localValue = bodyWithStateAndLocal(t, state, localValue);
else
- Contract.Assert(false, "PartitionerForEach: illegal body type in Partitioner handler");
+ Debug.Assert(false, "PartitionerForEach: illegal body type in Partitioner handler");
// Any break, stop or exception causes us to halt
@@ -3576,7 +3575,7 @@ namespace System.Threading.Tasks
public bool LimitExceeded()
{
- Contract.Assert(m_timeLimit != 0, "Probably the default initializer for LoopTimer was used somewhere");
+ Debug.Assert(m_timeLimit != 0, "Probably the default initializer for LoopTimer was used somewhere");
// comparing against the next expected time saves an addition operation here
// Also we omit the comparison for wrap around here. The only side effect is one extra early yield every 38 days.
diff --git a/src/mscorlib/src/System/Threading/Tasks/ParallelLoopState.cs b/src/mscorlib/src/System/Threading/Tasks/ParallelLoopState.cs
index 4db3a9d105..6a62cf8977 100644
--- a/src/mscorlib/src/System/Threading/Tasks/ParallelLoopState.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/ParallelLoopState.cs
@@ -26,7 +26,6 @@ namespace System.Threading.Tasks
/// Enables iterations of <see cref="T:System.Threading.Tasks.Parallel"/> loops to interact with
/// other iterations.
/// </summary>
- [HostProtection(Synchronization = true, ExternalThreading = true)]
[DebuggerDisplay("ShouldExitCurrentIteration = {ShouldExitCurrentIteration}")]
public class ParallelLoopState
{
@@ -47,7 +46,7 @@ namespace System.Threading.Tasks
{
get
{
- Contract.Assert(false);
+ Debug.Assert(false);
throw new NotSupportedException(
Environment.GetResourceString("ParallelState_NotSupportedException_UnsupportedMethod"));
}
@@ -104,7 +103,7 @@ namespace System.Threading.Tasks
{
get
{
- Contract.Assert(false);
+ Debug.Assert(false);
throw new NotSupportedException(
Environment.GetResourceString("ParallelState_NotSupportedException_UnsupportedMethod"));
}
@@ -152,7 +151,7 @@ namespace System.Threading.Tasks
// Internal/virtual support for Break().
internal virtual void InternalBreak()
{
- Contract.Assert(false);
+ Debug.Assert(false);
throw new NotSupportedException(
Environment.GetResourceString("ParallelState_NotSupportedException_UnsupportedMethod"));
}
diff --git a/src/mscorlib/src/System/Threading/Tasks/ParallelRangeManager.cs b/src/mscorlib/src/System/Threading/Tasks/ParallelRangeManager.cs
index c4b66c41a9..49f61a6614 100644
--- a/src/mscorlib/src/System/Threading/Tasks/ParallelRangeManager.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/ParallelRangeManager.cs
@@ -12,6 +12,7 @@
using System;
using System.Threading;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
#pragma warning disable 0420
@@ -160,7 +161,7 @@ namespace System.Threading.Tasks
bool bRetVal = FindNewWork(out nFromInclusiveLocal, out nToExclusiveLocal);
- Contract.Assert((nFromInclusiveLocal <= Int32.MaxValue) && (nFromInclusiveLocal >= Int32.MinValue) &&
+ Debug.Assert((nFromInclusiveLocal <= Int32.MaxValue) && (nFromInclusiveLocal >= Int32.MinValue) &&
(nToExclusiveLocal <= Int32.MaxValue) && (nToExclusiveLocal >= Int32.MinValue));
// convert to 32 bit before returning
@@ -218,7 +219,7 @@ namespace System.Threading.Tasks
//
// find the actual number of index ranges we will need
//
- Contract.Assert((uSpan / uRangeSize) < Int32.MaxValue);
+ Debug.Assert((uSpan / uRangeSize) < Int32.MaxValue);
int nNumRanges = (int)(uSpan / uRangeSize);
@@ -251,7 +252,7 @@ namespace System.Threading.Tasks
nCurrentIndex > nToExclusive)
{
// this should only happen at the last index
- Contract.Assert(i == nNumRanges - 1);
+ Debug.Assert(i == nNumRanges - 1);
nCurrentIndex = nToExclusive;
}
@@ -267,7 +268,7 @@ namespace System.Threading.Tasks
/// </summary>
internal RangeWorker RegisterNewWorker()
{
- Contract.Assert(m_indexRanges != null && m_indexRanges.Length != 0);
+ Debug.Assert(m_indexRanges != null && m_indexRanges.Length != 0);
int nInitialRange = (Interlocked.Increment(ref m_nCurrentIndexRangeToAssign) - 1) % m_indexRanges.Length;
diff --git a/src/mscorlib/src/System/Threading/Tasks/ProducerConsumerQueues.cs b/src/mscorlib/src/System/Threading/Tasks/ProducerConsumerQueues.cs
index 462ee0a9bd..6b9dfbbe37 100644
--- a/src/mscorlib/src/System/Threading/Tasks/ProducerConsumerQueues.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/ProducerConsumerQueues.cs
@@ -140,10 +140,10 @@ namespace System.Threading.Tasks
internal SingleProducerSingleConsumerQueue()
{
// Validate constants in ctor rather than in an explicit cctor that would cause perf degradation
- Contract.Assert(INIT_SEGMENT_SIZE > 0, "Initial segment size must be > 0.");
- Contract.Assert((INIT_SEGMENT_SIZE & (INIT_SEGMENT_SIZE - 1)) == 0, "Initial segment size must be a power of 2");
- Contract.Assert(INIT_SEGMENT_SIZE <= MAX_SEGMENT_SIZE, "Initial segment size should be <= maximum.");
- Contract.Assert(MAX_SEGMENT_SIZE < Int32.MaxValue / 2, "Max segment size * 2 must be < Int32.MaxValue, or else overflow could occur.");
+ Debug.Assert(INIT_SEGMENT_SIZE > 0, "Initial segment size must be > 0.");
+ Debug.Assert((INIT_SEGMENT_SIZE & (INIT_SEGMENT_SIZE - 1)) == 0, "Initial segment size must be a power of 2");
+ Debug.Assert(INIT_SEGMENT_SIZE <= MAX_SEGMENT_SIZE, "Initial segment size should be <= maximum.");
+ Debug.Assert(MAX_SEGMENT_SIZE < Int32.MaxValue / 2, "Max segment size * 2 must be < Int32.MaxValue, or else overflow could occur.");
// Initialize the queue
m_head = m_tail = new Segment(INIT_SEGMENT_SIZE);
@@ -183,7 +183,7 @@ namespace System.Threading.Tasks
}
int newSegmentSize = m_tail.m_array.Length << 1; // double size
- Contract.Assert(newSegmentSize > 0, "The max size should always be small enough that we don't overflow.");
+ Debug.Assert(newSegmentSize > 0, "The max size should always be small enough that we don't overflow.");
if (newSegmentSize > MAX_SEGMENT_SIZE) newSegmentSize = MAX_SEGMENT_SIZE;
var newSegment = new Segment(newSegmentSize);
@@ -456,7 +456,7 @@ namespace System.Threading.Tasks
/// <remarks>The Count is not thread safe, so we need to acquire the lock.</remarks>
int IProducerConsumerQueue<T>.GetCountSafe(object syncObj)
{
- Contract.Assert(syncObj != null, "The syncObj parameter is null.");
+ Debug.Assert(syncObj != null, "The syncObj parameter is null.");
lock (syncObj)
{
return Count;
diff --git a/src/mscorlib/src/System/Threading/Tasks/TPLETWProvider.cs b/src/mscorlib/src/System/Threading/Tasks/TPLETWProvider.cs
index 5f79f30b35..325aa91b44 100644
--- a/src/mscorlib/src/System/Threading/Tasks/TPLETWProvider.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/TPLETWProvider.cs
@@ -216,7 +216,6 @@ namespace System.Threading.Tasks
/// <param name="OperationType">The kind of fork/join operation.</param>
/// <param name="InclusiveFrom">The lower bound of the loop.</param>
/// <param name="ExclusiveTo">The upper bound of the loop.</param>
- [SecuritySafeCritical]
[Event(PARALLELLOOPBEGIN_ID, Level = EventLevel.Informational, ActivityOptions=EventActivityOptions.Recursive,
Task = TplEtwProvider.Tasks.Loop, Opcode = EventOpcode.Start)]
public void ParallelLoopBegin(
@@ -261,7 +260,6 @@ namespace System.Threading.Tasks
/// <param name="OriginatingTaskID">The task ID.</param>
/// <param name="ForkJoinContextID">The loop ID.</param>
/// <param name="TotalIterations">the total number of iterations processed.</param>
- [SecuritySafeCritical]
[Event(PARALLELLOOPEND_ID, Level = EventLevel.Informational, Task = TplEtwProvider.Tasks.Loop, Opcode = EventOpcode.Stop)]
public void ParallelLoopEnd(
int OriginatingTaskSchedulerID, int OriginatingTaskID, // PFX_COMMON_EVENT_HEADER
@@ -298,7 +296,6 @@ namespace System.Threading.Tasks
/// <param name="ForkJoinContextID">The invoke ID.</param>
/// <param name="OperationType">The kind of fork/join operation.</param>
/// <param name="ActionCount">The number of actions being invoked.</param>
- [SecuritySafeCritical]
[Event(PARALLELINVOKEBEGIN_ID, Level = EventLevel.Informational, ActivityOptions=EventActivityOptions.Recursive,
Task = TplEtwProvider.Tasks.Invoke, Opcode = EventOpcode.Start)]
public void ParallelInvokeBegin(
@@ -412,7 +409,6 @@ 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>
- [SecuritySafeCritical]
[Event(TASKSCHEDULED_ID, Task = Tasks.TaskScheduled, Version=1, Opcode = EventOpcode.Send,
Level = EventLevel.Informational, Keywords = Keywords.TaskTransfer|Keywords.Tasks)]
public void TaskScheduled(
@@ -475,7 +471,6 @@ 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>
- [SecuritySafeCritical]
[Event(TASKCOMPLETED_ID, Version=1,
Level = EventLevel.Informational, Keywords = Keywords.TaskStops)]
public void TaskCompleted(
@@ -513,7 +508,6 @@ 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>
- [SecuritySafeCritical]
[Event(TASKWAITBEGIN_ID, Version=3, Task = TplEtwProvider.Tasks.TaskWait, Opcode = EventOpcode.Send,
Level = EventLevel.Informational, Keywords = Keywords.TaskTransfer|Keywords.Tasks)]
public void TaskWaitBegin(
@@ -600,7 +594,6 @@ 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>
- [SecuritySafeCritical]
[Event(AWAITTASKCONTINUATIONSCHEDULED_ID, Task = Tasks.AwaitTaskContinuationScheduled, Opcode = EventOpcode.Send,
Level = EventLevel.Informational, Keywords = Keywords.TaskTransfer|Keywords.Tasks)]
public void AwaitTaskContinuationScheduled(
@@ -629,7 +622,6 @@ namespace System.Threading.Tasks
}
}
- [SecuritySafeCritical]
[Event(TRACEOPERATIONSTART_ID, Version=1,
Level = EventLevel.Informational, Keywords = Keywords.AsyncCausalityOperation)]
public void TraceOperationBegin(int TaskID, string OperationName, long RelatedContext)
@@ -655,7 +647,6 @@ namespace System.Threading.Tasks
}
}
- [SecuritySafeCritical]
[Event(TRACEOPERATIONRELATION_ID, Version=1,
Level = EventLevel.Informational, Keywords = Keywords.AsyncCausalityRelation)]
public void TraceOperationRelation(int TaskID, CausalityRelation Relation)
@@ -664,7 +655,6 @@ namespace System.Threading.Tasks
WriteEvent(TRACEOPERATIONRELATION_ID, TaskID,(int) Relation); // optmized overload for this exists
}
- [SecuritySafeCritical]
[Event(TRACEOPERATIONSTOP_ID, Version=1,
Level = EventLevel.Informational, Keywords = Keywords.AsyncCausalityOperation)]
public void TraceOperationEnd(int TaskID, AsyncCausalityStatus Status)
@@ -673,7 +663,6 @@ namespace System.Threading.Tasks
WriteEvent(TRACEOPERATIONSTOP_ID, TaskID,(int) Status); // optmized overload for this exists
}
- [SecuritySafeCritical]
[Event(TRACESYNCHRONOUSWORKSTART_ID, Version=1,
Level = EventLevel.Informational, Keywords = Keywords.AsyncCausalitySynchronousWork)]
public void TraceSynchronousWorkBegin(int TaskID, CausalitySynchronousWork Work)
@@ -682,7 +671,6 @@ namespace System.Threading.Tasks
WriteEvent(TRACESYNCHRONOUSWORKSTART_ID, TaskID,(int) Work); // optmized overload for this exists
}
- [SecuritySafeCritical]
[Event(TRACESYNCHRONOUSWORKSTOP_ID, Version=1,
Level = EventLevel.Informational, Keywords = Keywords.AsyncCausalitySynchronousWork)]
public void TraceSynchronousWorkEnd(CausalitySynchronousWork Work)
diff --git a/src/mscorlib/src/System/Threading/Tasks/Task.cs b/src/mscorlib/src/System/Threading/Tasks/Task.cs
index 36f8401a4d..cf081f75fd 100644
--- a/src/mscorlib/src/System/Threading/Tasks/Task.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/Task.cs
@@ -137,7 +137,6 @@ namespace System.Threading.Tasks
/// InternalWait method serves a potential marker for when a Task is entering a wait operation.
/// </para>
/// </remarks>
- [HostProtection(Synchronization = true, ExternalThreading = true)]
[DebuggerTypeProxy(typeof(SystemThreadingTasks_TaskDebugView))]
[DebuggerDisplay("Id = {Id}, Status = {Status}, Method = {DebuggerDisplayMethodDescription}")]
public class Task : IThreadPoolWorkItem, IAsyncResult, IDisposable
@@ -152,7 +151,7 @@ namespace System.Threading.Tasks
private volatile int m_taskId; // this task's unique ID. initialized only if it is ever requested
- internal object m_action; // The body of the task. Might be Action<object>, Action<TState> or Action. Or possibly a Func.
+ internal Delegate m_action; // The body of the task. Might be Action<object>, Action<TState> or Action. Or possibly a Func.
// If m_action is set to null it will indicate that we operate in the
// "externally triggered completion" mode, which is exclusively meant
// for the signalling Task<TResult> (aka. promise). In this mode,
@@ -339,7 +338,7 @@ namespace System.Threading.Tasks
// (action,TCO). It should always be true.
internal Task(object state, TaskCreationOptions creationOptions, bool promiseStyle)
{
- Contract.Assert(promiseStyle, "Promise CTOR: promiseStyle was false");
+ Debug.Assert(promiseStyle, "Promise CTOR: promiseStyle was false");
// Check the creationOptions. We allow the AttachedToParent option to be specified for promise tasks.
// Also allow RunContinuationsAsynchronously because this is the constructor called by TCS
@@ -580,7 +579,7 @@ namespace System.Threading.Tasks
/// <param name="cancellationToken">A CancellationToken for the Task.</param>
/// <param name="creationOptions">Options to customize behavior of Task.</param>
/// <param name="internalOptions">Internal options to customize behavior of Task.</param>
- internal void TaskConstructorCore(object action, object state, CancellationToken cancellationToken,
+ internal void TaskConstructorCore(Delegate action, object state, CancellationToken cancellationToken,
TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler scheduler)
{
m_action = action;
@@ -609,7 +608,7 @@ namespace System.Threading.Tasks
InternalTaskOptions.ContinuationTask |
InternalTaskOptions.LazyCancellation |
InternalTaskOptions.QueuedByRuntime));
- Contract.Assert(illegalInternalOptions == 0, "TaskConstructorCore: Illegal internal options");
+ Debug.Assert(illegalInternalOptions == 0, "TaskConstructorCore: Illegal internal options");
#endif
// Throw exception if the user specifies both LongRunning and SelfReplicating
@@ -620,8 +619,8 @@ namespace System.Threading.Tasks
}
// Assign options to m_stateAndOptionsFlag.
- Contract.Assert(m_stateFlags == 0, "TaskConstructorCore: non-zero m_stateFlags");
- Contract.Assert((((int)creationOptions) | OptionsMask) == OptionsMask, "TaskConstructorCore: options take too many bits");
+ 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))
{
@@ -649,7 +648,7 @@ namespace System.Threading.Tasks
// we need to do this as the very last thing in the construction path, because the CT registration could modify m_stateFlags
if (cancellationToken.CanBeCanceled)
{
- Contract.Assert((internalOptions &
+ Debug.Assert((internalOptions &
(InternalTaskOptions.ChildReplica | InternalTaskOptions.SelfReplicating | InternalTaskOptions.ContinuationTask)) == 0,
"TaskConstructorCore: Did not expect to see cancelable token for replica/replicating or continuation task.");
@@ -743,7 +742,7 @@ namespace System.Threading.Tasks
antecedentTask.RemoveContinuation(continuation);
}
}
- Contract.Assert(targetTask != null,
+ Debug.Assert(targetTask != null,
"targetTask should have been non-null, with the supplied argument being a task or a tuple containing one");
targetTask.InternalCancel(false);
}
@@ -753,7 +752,7 @@ namespace System.Threading.Tasks
{
get
{
- Delegate d = (Delegate)m_action;
+ Delegate d = m_action;
return d != null ? d.Method.ToString() : "{null}";
}
}
@@ -764,10 +763,9 @@ namespace System.Threading.Tasks
/// </summary>
/// <param name="stackMark">A stack crawl mark pointing to the frame of the caller.</param>
- [SecuritySafeCritical]
internal void PossiblyCaptureContext(ref StackCrawlMark stackMark)
{
- Contract.Assert(m_contingentProperties == null || m_contingentProperties.m_capturedContext == null,
+ Debug.Assert(m_contingentProperties == null || m_contingentProperties.m_capturedContext == null,
"Captured an ExecutionContext when one was already captured.");
// In the legacy .NET 3.5 build, we don't have the optimized overload of Capture()
@@ -791,7 +789,7 @@ namespace System.Threading.Tasks
// a read of the volatile m_stateFlags field.
internal static TaskCreationOptions OptionsMethod(int flags)
{
- Contract.Assert((OptionsMask & 1) == 1, "OptionsMask needs a shift in Options.get");
+ Debug.Assert((OptionsMask & 1) == 1, "OptionsMask needs a shift in Options.get");
return (TaskCreationOptions)(flags & OptionsMask);
}
@@ -841,7 +839,7 @@ namespace System.Threading.Tasks
/// <param name="enabled">true to set the bit; false to unset the bit.</param>
internal void SetNotificationForWaitCompletion(bool enabled)
{
- Contract.Assert((Options & (TaskCreationOptions)InternalTaskOptions.PromiseTask) != 0,
+ Debug.Assert((Options & (TaskCreationOptions)InternalTaskOptions.PromiseTask) != 0,
"Should only be used for promise-style tasks"); // hasn't been vetted on other kinds as there hasn't been a need
if (enabled)
@@ -849,7 +847,7 @@ namespace System.Threading.Tasks
// Atomically set the END_AWAIT_NOTIFICATION bit
bool success = AtomicStateUpdate(TASK_STATE_WAIT_COMPLETION_NOTIFICATION,
TASK_STATE_COMPLETED_MASK | TASK_STATE_COMPLETION_RESERVED);
- Contract.Assert(success, "Tried to set enabled on completed Task");
+ Debug.Assert(success, "Tried to set enabled on completed Task");
}
else
{
@@ -886,7 +884,7 @@ namespace System.Threading.Tasks
/// <returns>true if any of the tasks require notification; otherwise, false.</returns>
internal static bool AnyTaskRequiresNotifyDebuggerOfWaitCompletion(Task[] tasks)
{
- Contract.Assert(tasks != null, "Expected non-null array of tasks");
+ Debug.Assert(tasks != null, "Expected non-null array of tasks");
foreach (var task in tasks)
{
if (task != null &&
@@ -926,7 +924,7 @@ namespace System.Threading.Tasks
// bit was unset between the time that it was checked and this method was called.
// It's so remote a chance that it's worth having the assert to protect against misuse.
bool isWaitNotificationEnabled = IsWaitNotificationEnabled;
- Contract.Assert(isWaitNotificationEnabled, "Should only be called if the wait completion bit is set.");
+ Debug.Assert(isWaitNotificationEnabled, "Should only be called if the wait completion bit is set.");
return isWaitNotificationEnabled;
}
}
@@ -946,7 +944,7 @@ namespace System.Threading.Tasks
// It's theoretically possible but extremely rare that this assert could fire because the
// bit was unset between the time that it was checked and this method was called.
// It's so remote a chance that it's worth having the assert to protect against misuse.
- Contract.Assert(IsWaitNotificationEnabled, "Should only be called if the wait completion bit is set.");
+ Debug.Assert(IsWaitNotificationEnabled, "Should only be called if the wait completion bit is set.");
// Now that we're notifying the debugger, clear the bit. The debugger should do this anyway,
// but this adds a bit of protection in case it fails to, and given that the debugger is involved,
@@ -991,7 +989,7 @@ namespace System.Threading.Tasks
/// </summary>
internal void AddNewChild()
{
- Contract.Assert(Task.InternalCurrent == this || this.IsSelfReplicatingRoot, "Task.AddNewChild(): Called from an external context");
+ Debug.Assert(Task.InternalCurrent == this || this.IsSelfReplicatingRoot, "Task.AddNewChild(): Called from an external context");
var props = EnsureContingentPropertiesInitialized();
@@ -1014,10 +1012,10 @@ namespace System.Threading.Tasks
// We need to subtract that child from m_completionCountdown, or the parent will never complete.
internal void DisregardChild()
{
- Contract.Assert(Task.InternalCurrent == this, "Task.DisregardChild(): Called from an external context");
+ Debug.Assert(Task.InternalCurrent == this, "Task.DisregardChild(): Called from an external context");
var props = EnsureContingentPropertiesInitialized();
- Contract.Assert(props.m_completionCountdown >= 2, "Task.DisregardChild(): Expected parent count to be >= 2");
+ Debug.Assert(props.m_completionCountdown >= 2, "Task.DisregardChild(): Expected parent count to be >= 2");
Interlocked.Decrement(ref props.m_completionCountdown);
}
@@ -1161,7 +1159,6 @@ namespace System.Threading.Tasks
//
// Internal version of RunSynchronously that allows not waiting for completion.
//
- [SecuritySafeCritical] // Needed for QueueTask
internal void InternalRunSynchronously(TaskScheduler scheduler, bool waitForCompletion)
{
Contract.Requires(scheduler != null, "Task.InternalRunSynchronously(): null TaskScheduler");
@@ -1235,7 +1232,7 @@ namespace System.Threading.Tasks
// Mark ourselves as "handled" to avoid crashing the finalizer thread if the caller neglects to
// call Wait() on this task.
// m_contingentProperties.m_exceptionsHolder *should* already exist after AddException()
- Contract.Assert(
+ Debug.Assert(
(m_contingentProperties != null) &&
(m_contingentProperties.m_exceptionsHolder != null) &&
(m_contingentProperties.m_exceptionsHolder.ContainsFaultList),
@@ -1252,7 +1249,7 @@ namespace System.Threading.Tasks
}
else
{
- Contract.Assert((m_stateFlags & TASK_STATE_CANCELED) != 0, "Task.RunSynchronously: expected TASK_STATE_CANCELED to be set");
+ Debug.Assert((m_stateFlags & TASK_STATE_CANCELED) != 0, "Task.RunSynchronously: expected TASK_STATE_CANCELED to be set");
// Can't call this method on canceled task.
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.Task_RunSynchronously_TaskCompleted);
}
@@ -1403,7 +1400,7 @@ namespace System.Threading.Tasks
// Only return an exception in faulted state (skip manufactured exceptions)
// A "benevolent" race condition makes it possible to return null when IsFaulted is
// true (i.e., if IsFaulted is set just after the check to IsFaulted above).
- Contract.Assert((e == null) || IsFaulted, "Task.Exception_get(): returning non-null value when not Faulted");
+ Debug.Assert((e == null) || IsFaulted, "Task.Exception_get(): returning non-null value when not Faulted");
return e;
}
@@ -1884,11 +1881,10 @@ namespace System.Threading.Tasks
/// underneath us. If false, TASK_STATE_STARTED bit is OR-ed right in. This
/// allows us to streamline things a bit for StartNew(), where competing cancellations
/// are not a problem.</param>
- [SecuritySafeCritical] // Needed for QueueTask
internal void ScheduleAndStart(bool needsProtection)
{
- Contract.Assert(m_taskScheduler != null, "expected a task scheduler to have been selected");
- Contract.Assert((m_stateFlags & TASK_STATE_STARTED) == 0, "task has already started");
+ Debug.Assert(m_taskScheduler != null, "expected a task scheduler to have been selected");
+ Debug.Assert((m_stateFlags & TASK_STATE_STARTED) == 0, "task has already started");
// Set the TASK_STATE_STARTED bit
if (needsProtection)
@@ -1912,7 +1908,7 @@ namespace System.Threading.Tasks
if (AsyncCausalityTracer.LoggingOn && (Options & (TaskCreationOptions)InternalTaskOptions.ContinuationTask) == 0)
{
//For all other task than TaskContinuations we want to log. TaskContinuations log in their constructor
- AsyncCausalityTracer.TraceOperationCreation(CausalityTraceLevel.Required, this.Id, "Task: "+((Delegate)m_action).Method.Name, 0);
+ AsyncCausalityTracer.TraceOperationCreation(CausalityTraceLevel.Required, this.Id, "Task: " + m_action.Method.Name, 0);
}
@@ -1942,7 +1938,7 @@ namespace System.Threading.Tasks
if ((Options & (TaskCreationOptions)InternalTaskOptions.ContinuationTask) == 0)
{
// m_contingentProperties.m_exceptionsHolder *should* already exist after AddException()
- Contract.Assert(
+ Debug.Assert(
(m_contingentProperties != null) &&
(m_contingentProperties.m_exceptionsHolder != null) &&
(m_contingentProperties.m_exceptionsHolder.ContainsFaultList),
@@ -1981,13 +1977,13 @@ namespace System.Threading.Tasks
var eoAsEdi = exceptionObject as ExceptionDispatchInfo;
var eoAsEnumerableEdi = exceptionObject as IEnumerable<ExceptionDispatchInfo>;
- Contract.Assert(
+ Debug.Assert(
eoAsException != null || eoAsEnumerableException != null || eoAsEdi != null || eoAsEnumerableEdi != null,
"Task.AddException: Expected an Exception, ExceptionDispatchInfo, or an IEnumerable<> of one of those");
var eoAsOce = exceptionObject as OperationCanceledException;
- Contract.Assert(
+ Debug.Assert(
!representsCancellation ||
eoAsOce != null ||
(eoAsEdi != null && eoAsEdi.SourceException is OperationCanceledException),
@@ -2078,7 +2074,7 @@ namespace System.Threading.Tasks
{
// There are exceptions; get the aggregate and optionally add the canceled
// exception to the aggregate (if applicable).
- Contract.Assert(m_contingentProperties != null); // ExceptionRecorded ==> m_contingentProperties != null
+ Debug.Assert(m_contingentProperties != null); // ExceptionRecorded ==> m_contingentProperties != null
// No need to lock around this, as other logic prevents the consumption of exceptions
// before they have been completely processed.
@@ -2097,7 +2093,7 @@ namespace System.Threading.Tasks
internal ReadOnlyCollection<ExceptionDispatchInfo> GetExceptionDispatchInfos()
{
bool exceptionsAvailable = IsFaulted && ExceptionRecorded;
- Contract.Assert(exceptionsAvailable, "Must only be used when the task has faulted with exceptions.");
+ Debug.Assert(exceptionsAvailable, "Must only be used when the task has faulted with exceptions.");
return exceptionsAvailable ?
m_contingentProperties.m_exceptionsHolder.GetExceptionDispatchInfos() :
new ReadOnlyCollection<ExceptionDispatchInfo>(new ExceptionDispatchInfo[0]);
@@ -2107,7 +2103,7 @@ namespace System.Threading.Tasks
/// <returns>The ExceptionDispatchInfo. May be null if no OCE was stored for the task.</returns>
internal ExceptionDispatchInfo GetCancellationExceptionDispatchInfo()
{
- Contract.Assert(IsCanceled, "Must only be used when the task has canceled.");
+ Debug.Assert(IsCanceled, "Must only be used when the task has canceled.");
return Volatile.Read(ref m_contingentProperties)?.m_exceptionsHolder?.GetCancellationExceptionDispatchInfo(); // may be null
}
@@ -2344,7 +2340,7 @@ namespace System.Threading.Tasks
Contract.Requires(childTask != null);
Contract.Requires(childTask.IsCompleted, "ProcessChildCompletion was called for an uncompleted task");
- Contract.Assert(childTask.m_contingentProperties?.m_parent == this, "ProcessChildCompletion should only be called for a child of this task");
+ Debug.Assert(childTask.m_contingentProperties?.m_parent == this, "ProcessChildCompletion should only be called for a child of this task");
var props = Volatile.Read(ref m_contingentProperties);
@@ -2404,11 +2400,11 @@ namespace System.Threading.Tasks
{
// Ensure any exceptions thrown by children are added to the parent.
// In doing this, we are implicitly marking children as being "handled".
- Contract.Assert(task.IsCompleted, "Expected all tasks in list to be completed");
+ Debug.Assert(task.IsCompleted, "Expected all tasks in list to be completed");
if (task.IsFaulted && !task.IsExceptionObservedByParent)
{
TaskExceptionHolder exceptionHolder = Volatile.Read(ref task.m_contingentProperties).m_exceptionsHolder;
- Contract.Assert(exceptionHolder != null);
+ Debug.Assert(exceptionHolder != null);
// No locking necessary since child task is finished adding exceptions
// and concurrent CreateExceptionObject() calls do not constitute
@@ -2435,7 +2431,7 @@ namespace System.Threading.Tasks
/// <param name="delegateRan">Whether the delegate was executed.</param>
internal void FinishThreadAbortedTask(bool bTAEAddedToExceptionHolder, bool delegateRan)
{
- Contract.Assert(!bTAEAddedToExceptionHolder || m_contingentProperties?.m_exceptionsHolder != null,
+ Debug.Assert(!bTAEAddedToExceptionHolder || m_contingentProperties?.m_exceptionsHolder != null,
"FinishThreadAbortedTask() called on a task whose exception holder wasn't initialized");
// this will only be false for non-root self replicating task copies, because all of their exceptions go to the root task.
@@ -2671,7 +2667,6 @@ namespace System.Threading.Tasks
/// IThreadPoolWorkItem override, which is the entry function for this task when the TP scheduler decides to run it.
///
/// </summary>
- [SecurityCritical]
void IThreadPoolWorkItem.ExecuteWorkItem()
{
ExecuteEntry(false);
@@ -2681,7 +2676,6 @@ namespace System.Threading.Tasks
/// The ThreadPool calls this if a ThreadAbortException is thrown while trying to execute this workitem. This may occur
/// before Task would otherwise be able to observe it.
/// </summary>
- [SecurityCritical]
void IThreadPoolWorkItem.MarkAborted(ThreadAbortException tae)
{
// If the task has marked itself as Completed, then it either a) already observed this exception (so we shouldn't handle it here)
@@ -2700,7 +2694,6 @@ namespace System.Threading.Tasks
/// </summary>
/// <param name="bPreventDoubleExecution"> Performs atomic updates to prevent double execution. Should only be set to true
/// in codepaths servicing user provided TaskSchedulers. The ConcRT or ThreadPool schedulers don't need this. </param>
- [SecuritySafeCritical]
internal bool ExecuteEntry(bool bPreventDoubleExecution)
{
if (bPreventDoubleExecution || ((Options & (TaskCreationOptions)InternalTaskOptions.SelfReplicating) != 0))
@@ -2742,7 +2735,6 @@ namespace System.Threading.Tasks
}
// A trick so we can refer to the TLS slot with a byref.
- [SecurityCritical]
private void ExecuteWithThreadLocal(ref Task currentTaskSlot)
{
// Remember the current task so we can restore it after running, and then
@@ -2819,14 +2811,12 @@ namespace System.Threading.Tasks
}
// Cached callback delegate that's lazily initialized due to ContextCallback being SecurityCritical
- [SecurityCritical]
private static ContextCallback s_ecCallback;
- [SecurityCritical]
private static void ExecutionContextCallback(object obj)
{
Task task = obj as Task;
- Contract.Assert(task != null, "expected a task object");
+ Debug.Assert(task != null, "expected a task object");
task.Execute();
}
@@ -2837,7 +2827,7 @@ namespace System.Threading.Tasks
internal virtual void InnerInvoke()
{
// Invoke the delegate
- Contract.Assert(m_action != null, "Null action in InnerInvoke()");
+ Debug.Assert(m_action != null, "Null action in InnerInvoke()");
var action = m_action as Action;
if (action != null)
{
@@ -2850,7 +2840,7 @@ namespace System.Threading.Tasks
actionWithState(m_stateObject);
return;
}
- Contract.Assert(false, "Invalid m_action in Task");
+ Debug.Assert(false, "Invalid m_action in Task");
}
/// <summary>
@@ -2929,7 +2919,6 @@ namespace System.Threading.Tasks
/// <param name="flowExecutionContext">Whether to flow ExecutionContext across the await.</param>
/// <param name="stackMark">A stack crawl mark tied to execution context.</param>
/// <exception cref="System.InvalidOperationException">The awaiter was not properly initialized.</exception>
- [SecurityCritical]
internal void SetContinuationForAwait(
Action continuationAction, bool continueOnCapturedContext, bool flowExecutionContext, ref StackCrawlMark stackMark)
{
@@ -2986,7 +2975,7 @@ namespace System.Threading.Tasks
}
else
{
- Contract.Assert(!flowExecutionContext, "We already determined we're not required to flow context.");
+ Debug.Assert(!flowExecutionContext, "We already determined we're not required to flow context.");
if (!AddTaskContinuation(continuationAction, addBeforeOthers: false))
AwaitTaskContinuation.UnsafeScheduleAction(continuationAction, this);
}
@@ -3019,7 +3008,7 @@ namespace System.Threading.Tasks
Wait(Timeout.Infinite, default(CancellationToken));
#if DEBUG
- Contract.Assert(waitResult, "expected wait to succeed");
+ Debug.Assert(waitResult, "expected wait to succeed");
#endif
}
@@ -3154,7 +3143,7 @@ namespace System.Threading.Tasks
ThrowIfExceptional(true);
}
- Contract.Assert((m_stateFlags & TASK_STATE_FAULTED) == 0, "Task.Wait() completing when in Faulted state.");
+ Debug.Assert((m_stateFlags & TASK_STATE_FAULTED) == 0, "Task.Wait() completing when in Faulted state.");
return true;
}
@@ -3230,7 +3219,7 @@ namespace System.Threading.Tasks
}
}
- Contract.Assert(IsCompleted || millisecondsTimeout != Timeout.Infinite);
+ Debug.Assert(IsCompleted || millisecondsTimeout != Timeout.Infinite);
// ETW event for Task Wait End
if (etwIsEnabled)
@@ -3358,7 +3347,6 @@ namespace System.Threading.Tasks
/// For custom schedulers we also attempt an atomic state transition.
/// </param>
/// <returns>true if the task was successfully canceled; otherwise, false.</returns>
- [SecuritySafeCritical]
internal bool InternalCancel(bool bCancelNonExecutingOnly)
{
Contract.Requires((Options & (TaskCreationOptions)InternalTaskOptions.PromiseTask) == 0, "Task.InternalCancel() did not expect promise-style task");
@@ -3426,7 +3414,7 @@ namespace System.Threading.Tasks
if (bPopSucceeded)
{
// hitting this would mean something wrong with the AtomicStateUpdate above
- Contract.Assert(!mustCleanup, "Possibly an invalid state transition call was made in InternalCancel()");
+ Debug.Assert(!mustCleanup, "Possibly an invalid state transition call was made in InternalCancel()");
// Include TASK_STATE_DELEGATE_INVOKED in "illegal" bits to protect against the situation where
// TS.TryDequeue() returns true but the task is still left on the queue.
@@ -3466,8 +3454,8 @@ namespace System.Threading.Tasks
{
RecordInternalCancellationRequest();
- Contract.Assert((Options & (TaskCreationOptions)InternalTaskOptions.PromiseTask) != 0, "Task.RecordInternalCancellationRequest(CancellationToken) only valid for promise-style task");
- Contract.Assert(m_contingentProperties.m_cancellationToken == default(CancellationToken));
+ Debug.Assert((Options & (TaskCreationOptions)InternalTaskOptions.PromiseTask) != 0, "Task.RecordInternalCancellationRequest(CancellationToken) only valid for promise-style task");
+ Debug.Assert(m_contingentProperties.m_cancellationToken == default(CancellationToken));
// Store the supplied cancellation token as this task's token.
// Waiting on this task will then result in an OperationCanceledException containing this token.
@@ -3492,11 +3480,11 @@ namespace System.Threading.Tasks
if (oce == null)
{
var edi = cancellationException as ExceptionDispatchInfo;
- Contract.Assert(edi != null, "Expected either an OCE or an EDI");
+ Debug.Assert(edi != null, "Expected either an OCE or an EDI");
oce = edi.SourceException as OperationCanceledException;
- Contract.Assert(oce != null, "Expected EDI to contain an OCE");
+ Debug.Assert(oce != null, "Expected EDI to contain an OCE");
}
- Contract.Assert(oce.CancellationToken == tokenToRecord,
+ Debug.Assert(oce.CancellationToken == tokenToRecord,
"Expected OCE's token to match the provided token.");
#endif
AddException(cancellationException, representsCancellation: true);
@@ -3507,10 +3495,10 @@ namespace System.Threading.Tasks
// And this method should be called at most once per task.
internal void CancellationCleanupLogic()
{
- Contract.Assert((m_stateFlags & (TASK_STATE_CANCELED | TASK_STATE_COMPLETION_RESERVED)) != 0, "Task.CancellationCleanupLogic(): Task not canceled or reserved.");
+ Debug.Assert((m_stateFlags & (TASK_STATE_CANCELED | TASK_STATE_COMPLETION_RESERVED)) != 0, "Task.CancellationCleanupLogic(): Task not canceled or reserved.");
// I'd like to do this, but there is a small window for a race condition. If someone calls Wait() between InternalCancel() and
// here, that will set m_completionEvent, leading to a meaningless/harmless assertion.
- //Contract.Assert((m_completionEvent == null) || !m_completionEvent.IsSet, "Task.CancellationCleanupLogic(): Completion event already set.");
+ //Debug.Assert((m_completionEvent == null) || !m_completionEvent.IsSet, "Task.CancellationCleanupLogic(): Completion event already set.");
// This may have been set already, but we need to make sure.
Interlocked.Exchange(ref m_stateFlags, m_stateFlags | TASK_STATE_CANCELED);
@@ -3541,8 +3529,8 @@ namespace System.Threading.Tasks
/// </summary>
private void SetCancellationAcknowledged()
{
- Contract.Assert(this == Task.InternalCurrent, "SetCancellationAcknowledged() should only be called while this is still the current task");
- Contract.Assert(IsCancellationRequested, "SetCancellationAcknowledged() should not be called if the task's CT wasn't signaled");
+ Debug.Assert(this == Task.InternalCurrent, "SetCancellationAcknowledged() should only be called while this is still the current task");
+ Debug.Assert(IsCancellationRequested, "SetCancellationAcknowledged() should not be called if the task's CT wasn't signaled");
m_stateFlags |= TASK_STATE_CANCELLATIONACKNOWLEDGED;
}
@@ -3558,7 +3546,6 @@ namespace System.Threading.Tasks
/// <summary>
/// Runs all of the continuations, as appropriate.
/// </summary>
- [SecuritySafeCritical] // for AwaitTaskContinuation.RunOrScheduleAction
internal void FinishContinuations()
{
// Atomically store the fact that this task is completing. From this point on, the adding of continuations will
@@ -3684,7 +3671,7 @@ namespace System.Threading.Tasks
// Otherwise, it must be an ITaskCompletionAction, so invoke it.
else
{
- Contract.Assert(currentContinuation is ITaskCompletionAction, "Expected continuation element to be Action, TaskContinuation, or ITaskContinuationAction");
+ Debug.Assert(currentContinuation is ITaskCompletionAction, "Expected continuation element to be Action, TaskContinuation, or ITaskContinuationAction");
var action = (ITaskCompletionAction)currentContinuation;
if (bCanInlineContinuations || !action.InvokeMayRunArbitraryCode)
@@ -4730,7 +4717,7 @@ namespace System.Threading.Tasks
// m_continuationObject is guaranteed at this point to be either a List or
// s_taskCompletionSentinel.
List<object> list = m_continuationObject as List<object>;
- Contract.Assert((list != null) || (m_continuationObject == s_taskCompletionSentinel),
+ Debug.Assert((list != null) || (m_continuationObject == s_taskCompletionSentinel),
"Expected m_continuationObject to be list or sentinel");
// If list is null, it can only mean that s_taskCompletionSentinel has been exchanged
@@ -4873,7 +4860,7 @@ namespace System.Threading.Tasks
WaitAll(tasks, Timeout.Infinite);
#if DEBUG
- Contract.Assert(waitResult, "expected wait to succeed");
+ Debug.Assert(waitResult, "expected wait to succeed");
#endif
}
@@ -5134,7 +5121,7 @@ namespace System.Threading.Tasks
// Now gather up and throw all of the exceptions.
foreach (var task in tasks) AddExceptionsForCompletedTask(ref exceptions, task);
- Contract.Assert(exceptions != null, "Should have seen at least one exception");
+ Debug.Assert(exceptions != null, "Should have seen at least one exception");
ThrowHelper.ThrowAggregateException(exceptions);
}
@@ -5159,8 +5146,8 @@ namespace System.Threading.Tasks
/// <returns>true if all of the tasks completed; otherwise, false.</returns>
private static bool WaitAllBlockingCore(List<Task> tasks, int millisecondsTimeout, CancellationToken cancellationToken)
{
- Contract.Assert(tasks != null, "Expected a non-null list of tasks");
- Contract.Assert(tasks.Count > 0, "Expected at least one task");
+ Debug.Assert(tasks != null, "Expected a non-null list of tasks");
+ Debug.Assert(tasks.Count > 0, "Expected at least one task");
bool waitCompleted = false;
var mres = new SetOnCountdownMres(tasks.Count);
@@ -5206,14 +5193,14 @@ namespace System.Threading.Tasks
internal SetOnCountdownMres(int count)
{
- Contract.Assert(count > 0, "Expected count > 0");
+ Debug.Assert(count > 0, "Expected count > 0");
_count = count;
}
public void Invoke(Task completingTask)
{
if (Interlocked.Decrement(ref _count) == 0) Set();
- Contract.Assert(_count >= 0, "Count should never go below 0");
+ Debug.Assert(_count >= 0, "Count should never go below 0");
}
public bool InvokeMayRunArbitraryCode { get { return false; } }
@@ -5304,7 +5291,7 @@ namespace System.Threading.Tasks
public static int WaitAny(params Task[] tasks)
{
int waitResult = WaitAny(tasks, Timeout.Infinite);
- Contract.Assert(tasks.Length == 0 || waitResult != -1, "expected wait to succeed");
+ Debug.Assert(tasks.Length == 0 || waitResult != -1, "expected wait to succeed");
return waitResult;
}
@@ -5475,9 +5462,9 @@ namespace System.Threading.Tasks
bool waitCompleted = firstCompleted.Wait(millisecondsTimeout, cancellationToken);
if (waitCompleted)
{
- Contract.Assert(firstCompleted.Status == TaskStatus.RanToCompletion);
+ Debug.Assert(firstCompleted.Status == TaskStatus.RanToCompletion);
signaledTaskIndex = Array.IndexOf(tasks, firstCompleted.Result);
- Contract.Assert(signaledTaskIndex >= 0);
+ Debug.Assert(signaledTaskIndex >= 0);
}
}
@@ -5521,7 +5508,7 @@ namespace System.Threading.Tasks
var task = new Task<TResult>();
bool succeeded = task.TrySetException(exception);
- Contract.Assert(succeeded, "This should always succeed on a new task.");
+ Debug.Assert(succeeded, "This should always succeed on a new task.");
return task;
}
@@ -5559,7 +5546,7 @@ namespace System.Threading.Tasks
var task = new Task<TResult>();
bool succeeded = task.TrySetCanceled(exception.CancellationToken, exception);
- Contract.Assert(succeeded, "This should always succeed on a new task.");
+ Debug.Assert(succeeded, "This should always succeed on a new task.");
return task;
}
@@ -6124,7 +6111,7 @@ namespace System.Threading.Tasks
for (int i = 0; i < m_tasks.Length; i++)
{
var task = m_tasks[i];
- Contract.Assert(task != null, "Constituent task in WhenAll should never be null");
+ Debug.Assert(task != null, "Constituent task in WhenAll should never be null");
if (task.IsFaulted)
{
@@ -6144,7 +6131,7 @@ namespace System.Threading.Tasks
if (observedExceptions != null)
{
- Contract.Assert(observedExceptions.Count > 0, "Expected at least one exception");
+ Debug.Assert(observedExceptions.Count > 0, "Expected at least one exception");
//We don't need to TraceOperationCompleted here because TrySetException will call Finish and we'll log it there
@@ -6166,7 +6153,7 @@ namespace System.Threading.Tasks
TrySetResult(default(VoidTaskResult));
}
}
- Contract.Assert(m_count >= 0, "Count should never go below 0");
+ Debug.Assert(m_count >= 0, "Count should never go below 0");
}
public bool InvokeMayRunArbitraryCode { get { return true; } }
@@ -6371,7 +6358,7 @@ namespace System.Threading.Tasks
for (int i = 0; i < m_tasks.Length; i++)
{
Task<T> task = m_tasks[i];
- Contract.Assert(task != null, "Constituent task in WhenAll should never be null");
+ Debug.Assert(task != null, "Constituent task in WhenAll should never be null");
if (task.IsFaulted)
{
@@ -6384,7 +6371,7 @@ namespace System.Threading.Tasks
}
else
{
- Contract.Assert(task.Status == TaskStatus.RanToCompletion);
+ Debug.Assert(task.Status == TaskStatus.RanToCompletion);
results[i] = task.GetResultCore(waitCompletionNotification: false); // avoid Result, which would triggering debug notification
}
@@ -6396,7 +6383,7 @@ namespace System.Threading.Tasks
if (observedExceptions != null)
{
- Contract.Assert(observedExceptions.Count > 0, "Expected at least one exception");
+ Debug.Assert(observedExceptions.Count > 0, "Expected at least one exception");
//We don't need to TraceOperationCompleted here because TrySetException will call Finish and we'll log it there
@@ -6418,7 +6405,7 @@ namespace System.Threading.Tasks
TrySetResult(results);
}
}
- Contract.Assert(m_count >= 0, "Count should never go below 0");
+ Debug.Assert(m_count >= 0, "Count should never go below 0");
}
public bool InvokeMayRunArbitraryCode { get { return true; } }
@@ -6612,7 +6599,7 @@ namespace System.Threading.Tasks
Task continuationTask = continuationObject as Task;
if (continuationTask != null)
{
- Contract.Assert(continuationTask.m_action == null);
+ Debug.Assert(continuationTask.m_action == null);
Delegate[] delegates = continuationTask.GetDelegateContinuationsForDebugger();
if (delegates != null)
return delegates;
@@ -6677,13 +6664,11 @@ namespace System.Threading.Tasks
m_completingTask = completingTask;
}
- [SecurityCritical]
void IThreadPoolWorkItem.ExecuteWorkItem()
{
m_action.Invoke(m_completingTask);
}
- [SecurityCritical]
void IThreadPoolWorkItem.MarkAborted(ThreadAbortException tae)
{
/* NOP */
@@ -6999,25 +6984,12 @@ namespace System.Threading.Tasks
// that can SO in 20 inlines on a typical 1MB stack size probably needs to be revisited anyway.
private const int MAX_UNCHECKED_INLINING_DEPTH = 20;
-#if !FEATURE_CORECLR
-
- private UInt64 m_lastKnownWatermark;
- private static int s_pageSize;
-
- // We are conservative here. We assume that the platform needs a whole 64KB to
- // respond to stack overflow. This means that for very small stacks (e.g. 128KB)
- // we'll fail a lot of stack checks incorrectly.
- private const long STACK_RESERVED_SPACE = 4096 * 16;
-
-#endif // !FEATURE_CORECLR
-
/// <summary>
/// This method needs to be called before attempting inline execution on the current thread.
/// If false is returned, it means we are too close to the end of the stack and should give up inlining.
/// Each call to TryBeginInliningScope() that returns true must be matched with a
/// call to EndInliningScope() regardless of whether inlining actually took place.
/// </summary>
- [SecuritySafeCritical]
internal bool TryBeginInliningScope()
{
// If we're still under the 'safe' limit we'll just skip the stack probe to save p/invoke calls
@@ -7037,59 +7009,15 @@ namespace System.Threading.Tasks
internal void EndInliningScope()
{
m_inliningDepth--;
- Contract.Assert(m_inliningDepth >= 0, "Inlining depth count should never go negative.");
+ Debug.Assert(m_inliningDepth >= 0, "Inlining depth count should never go negative.");
// do the right thing just in case...
if (m_inliningDepth < 0) m_inliningDepth = 0;
}
- [SecurityCritical]
private unsafe bool CheckForSufficientStack()
{
-#if FEATURE_CORECLR
return RuntimeHelpers.TryEnsureSufficientExecutionStack();
-#else
- // see if we already have the system page size info recorded
- int pageSize = s_pageSize;
- if (pageSize == 0)
- {
- // If not we need to query it from GetSystemInfo()
- // Note that this happens only once for the process lifetime
- Win32Native.SYSTEM_INFO sysInfo = new Win32Native.SYSTEM_INFO();
- Win32Native.GetSystemInfo(ref sysInfo);
-
- s_pageSize = pageSize = sysInfo.dwPageSize;
- }
-
- Win32Native.MEMORY_BASIC_INFORMATION stackInfo = new Win32Native.MEMORY_BASIC_INFORMATION();
-
- // We subtract one page for our request. VirtualQuery rounds UP to the next page.
- // Unfortunately, the stack grows down. If we're on the first page (last page in the
- // VirtualAlloc), we'll be moved to the next page, which is off the stack!
-
- UIntPtr currentAddr = new UIntPtr(&stackInfo - pageSize);
- UInt64 current64 = currentAddr.ToUInt64();
-
- // Check whether we previously recorded a deeper stack than where we currently are,
- // If so we don't need to do the P/Invoke to VirtualQuery
- if (m_lastKnownWatermark != 0 && current64 > m_lastKnownWatermark)
- return true;
-
- // Actual stack probe. P/Invoke to query for the current stack allocation information.
- Win32Native.VirtualQuery(currentAddr.ToPointer(), ref stackInfo, (UIntPtr)(sizeof(Win32Native.MEMORY_BASIC_INFORMATION)));
-
- // If the current address minus the base (remember: the stack grows downward in the
- // address space) is greater than the number of bytes requested plus the reserved
- // space at the end, the request has succeeded.
-
- if ((current64 - ((UIntPtr)stackInfo.AllocationBase).ToUInt64()) > STACK_RESERVED_SPACE)
- {
- m_lastKnownWatermark = current64;
- return true;
- }
-
- return false;
-#endif
}
}
@@ -7204,16 +7132,15 @@ namespace System.Threading.Tasks
case STATE_WAITING_ON_INNER_TASK:
bool result = TrySetFromTask(completingTask, lookForOce: false);
_state = STATE_DONE; // bump the state
- Contract.Assert(result, "Expected TrySetFromTask from inner task to succeed");
+ Debug.Assert(result, "Expected TrySetFromTask from inner task to succeed");
break;
default:
- Contract.Assert(false, "UnwrapPromise in illegal state");
+ Debug.Assert(false, "UnwrapPromise in illegal state");
break;
}
}
// Calls InvokeCore asynchronously.
- [SecuritySafeCritical]
private void InvokeCoreAsync(Task completingTask)
{
// Queue a call to Invoke. If we're so deep on the stack that we're at risk of overflowing,
@@ -7233,7 +7160,7 @@ namespace System.Threading.Tasks
private void ProcessCompletedOuterTask(Task task)
{
Contract.Requires(task != null && task.IsCompleted, "Expected non-null, completed outer task");
- Contract.Assert(_state == STATE_WAITING_ON_OUTER_TASK, "We're in the wrong state!");
+ Debug.Assert(_state == STATE_WAITING_ON_OUTER_TASK, "We're in the wrong state!");
// Bump our state before proceeding any further
_state = STATE_WAITING_ON_INNER_TASK;
@@ -7245,7 +7172,7 @@ namespace System.Threading.Tasks
case TaskStatus.Canceled:
case TaskStatus.Faulted:
bool result = TrySetFromTask(task, _lookForOce);
- Contract.Assert(result, "Expected TrySetFromTask from outer task to succeed");
+ Debug.Assert(result, "Expected TrySetFromTask from outer task to succeed");
break;
// Otherwise, process the inner task it returned.
diff --git a/src/mscorlib/src/System/Threading/Tasks/TaskCompletionSource.cs b/src/mscorlib/src/System/Threading/Tasks/TaskCompletionSource.cs
index 8b1dd2a62f..320f704f09 100644
--- a/src/mscorlib/src/System/Threading/Tasks/TaskCompletionSource.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/TaskCompletionSource.cs
@@ -12,6 +12,7 @@
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
using System;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
@@ -47,7 +48,6 @@ namespace System.Threading.Tasks
/// </remarks>
/// <typeparam name="TResult">The type of the result value assocatied with this <see
/// cref="TaskCompletionSource{TResult}"/>.</typeparam>
- [HostProtection(Synchronization = true, ExternalThreading = true)]
public class TaskCompletionSource<TResult>
{
private readonly Task<TResult> m_task;
@@ -209,9 +209,9 @@ namespace System.Threading.Tasks
/// <remarks>Unlike the public methods, this method doesn't currently validate that its arguments are correct.</remarks>
internal bool TrySetException(IEnumerable<ExceptionDispatchInfo> exceptions)
{
- Contract.Assert(exceptions != null);
+ Debug.Assert(exceptions != null);
#if DEBUG
- foreach(var edi in exceptions) Contract.Assert(edi != null, "Contents must be non-null");
+ foreach(var edi in exceptions) Debug.Assert(edi != null, "Contents must be non-null");
#endif
bool rval = m_task.TrySetException(exceptions);
diff --git a/src/mscorlib/src/System/Threading/Tasks/TaskContinuation.cs b/src/mscorlib/src/System/Threading/Tasks/TaskContinuation.cs
index 4c035dfddb..70b9418dbf 100644
--- a/src/mscorlib/src/System/Threading/Tasks/TaskContinuation.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/TaskContinuation.cs
@@ -11,6 +11,7 @@
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
using System.Security;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.ExceptionServices;
using System.Runtime.CompilerServices;
@@ -45,7 +46,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;
- Contract.Assert(antecedent != null,
+ Debug.Assert(antecedent != null,
"No antecedent was set for the ContinuationTaskFromTask.");
m_antecedent = null;
@@ -53,7 +54,7 @@ namespace System.Threading.Tasks
antecedent.NotifyDebuggerOfWaitCompletionIfNecessary();
// Invoke the delegate
- Contract.Assert(m_action != null);
+ Debug.Assert(m_action != null);
var action = m_action as Action<Task>;
if (action != null)
{
@@ -66,7 +67,7 @@ namespace System.Threading.Tasks
actionWithState(antecedent, m_stateObject);
return;
}
- Contract.Assert(false, "Invalid m_action in ContinuationTaskFromTask");
+ Debug.Assert(false, "Invalid m_action in ContinuationTaskFromTask");
}
}
@@ -93,7 +94,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;
- Contract.Assert(antecedent != null,
+ Debug.Assert(antecedent != null,
"No antecedent was set for the ContinuationResultTaskFromTask.");
m_antecedent = null;
@@ -101,7 +102,7 @@ namespace System.Threading.Tasks
antecedent.NotifyDebuggerOfWaitCompletionIfNecessary();
// Invoke the delegate
- Contract.Assert(m_action != null);
+ Debug.Assert(m_action != null);
var func = m_action as Func<Task, TResult>;
if (func != null)
{
@@ -114,7 +115,7 @@ namespace System.Threading.Tasks
m_result = funcWithState(antecedent, m_stateObject);
return;
}
- Contract.Assert(false, "Invalid m_action in ContinuationResultTaskFromTask");
+ Debug.Assert(false, "Invalid m_action in ContinuationResultTaskFromTask");
}
}
@@ -141,7 +142,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;
- Contract.Assert(antecedent != null,
+ Debug.Assert(antecedent != null,
"No antecedent was set for the ContinuationTaskFromResultTask.");
m_antecedent = null;
@@ -149,7 +150,7 @@ namespace System.Threading.Tasks
antecedent.NotifyDebuggerOfWaitCompletionIfNecessary();
// Invoke the delegate
- Contract.Assert(m_action != null);
+ Debug.Assert(m_action != null);
var action = m_action as Action<Task<TAntecedentResult>>;
if (action != null)
{
@@ -162,7 +163,7 @@ namespace System.Threading.Tasks
actionWithState(antecedent, m_stateObject);
return;
}
- Contract.Assert(false, "Invalid m_action in ContinuationTaskFromResultTask");
+ Debug.Assert(false, "Invalid m_action in ContinuationTaskFromResultTask");
}
}
@@ -189,7 +190,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;
- Contract.Assert(antecedent != null,
+ Debug.Assert(antecedent != null,
"No antecedent was set for the ContinuationResultTaskFromResultTask.");
m_antecedent = null;
@@ -197,7 +198,7 @@ namespace System.Threading.Tasks
antecedent.NotifyDebuggerOfWaitCompletionIfNecessary();
// Invoke the delegate
- Contract.Assert(m_action != null);
+ Debug.Assert(m_action != null);
var func = m_action as Func<Task<TAntecedentResult>, TResult>;
if (func != null)
{
@@ -210,7 +211,7 @@ namespace System.Threading.Tasks
m_result = funcWithState(antecedent, m_stateObject);
return;
}
- Contract.Assert(false, "Invalid m_action in ContinuationResultTaskFromResultTask");
+ Debug.Assert(false, "Invalid m_action in ContinuationResultTaskFromResultTask");
}
}
@@ -235,11 +236,10 @@ namespace System.Threading.Tasks
/// <param name="needsProtection">
/// true if we need to protect against multiple threads racing to start/cancel the task; otherwise, false.
/// </param>
- [SecuritySafeCritical]
protected static void InlineIfPossibleOrElseQueue(Task task, bool needsProtection)
{
Contract.Requires(task != null);
- Contract.Assert(task.m_taskScheduler != null);
+ Debug.Assert(task.m_taskScheduler != null);
// Set the TASK_STATE_STARTED flag. This only needs to be done
// if the task may be canceled or if someone else has a reference to it
@@ -305,7 +305,7 @@ namespace System.Threading.Tasks
m_options = options;
m_taskScheduler = scheduler;
if (AsyncCausalityTracer.LoggingOn)
- AsyncCausalityTracer.TraceOperationCreation(CausalityTraceLevel.Required, m_task.Id, "Task.ContinueWith: " + ((Delegate)task.m_action).Method.Name, 0);
+ AsyncCausalityTracer.TraceOperationCreation(CausalityTraceLevel.Required, m_task.Id, "Task.ContinueWith: " + task.m_action.Method.Name, 0);
if (Task.s_asyncDebuggingEnabled)
{
@@ -318,8 +318,8 @@ namespace System.Threading.Tasks
/// <param name="bCanInlineContinuationTask">Whether the continuation can be inlined.</param>
internal override void Run(Task completedTask, bool bCanInlineContinuationTask)
{
- Contract.Assert(completedTask != null);
- Contract.Assert(completedTask.IsCompleted, "ContinuationTask.Run(): completedTask not completed");
+ Debug.Assert(completedTask != null);
+ Debug.Assert(completedTask.IsCompleted, "ContinuationTask.Run(): completedTask not completed");
// Check if the completion status of the task works with the desired
// activation criteria of the TaskContinuationOptions.
@@ -374,7 +374,7 @@ namespace System.Threading.Tasks
return m_task.GetDelegateContinuationsForDebugger();
}
- return new Delegate[] { m_task.m_action as Delegate };
+ return new Delegate[] { m_task.m_action };
}
}
@@ -384,7 +384,6 @@ namespace System.Threading.Tasks
/// <summary>SendOrPostCallback delegate to invoke the action.</summary>
private readonly static SendOrPostCallback s_postCallback = state => ((Action)state)(); // can't use InvokeAction as it's SecurityCritical
/// <summary>Cached delegate for PostAction</summary>
- [SecurityCritical]
private static ContextCallback s_postActionCallback;
/// <summary>The context with which to run the action.</summary>
private readonly SynchronizationContext m_syncContext;
@@ -394,19 +393,17 @@ namespace System.Threading.Tasks
/// <param name="action">The action to invoke. Must not be null.</param>
/// <param name="flowExecutionContext">Whether to capture and restore ExecutionContext.</param>
/// <param name="stackMark">The captured stack mark.</param>
- [SecurityCritical]
internal SynchronizationContextAwaitTaskContinuation(
SynchronizationContext context, Action action, bool flowExecutionContext, ref StackCrawlMark stackMark) :
base(action, flowExecutionContext, ref stackMark)
{
- Contract.Assert(context != null);
+ Debug.Assert(context != null);
m_syncContext = context;
}
/// <summary>Inlines or schedules the continuation.</summary>
/// <param name="ignored">The antecedent task, which is ignored.</param>
/// <param name="canInlineContinuationTask">true if inlining is permitted; otherwise, false.</param>
- [SecuritySafeCritical]
internal sealed override void Run(Task task, bool canInlineContinuationTask)
{
// If we're allowed to inline, run the action on this thread.
@@ -431,7 +428,6 @@ namespace System.Threading.Tasks
/// <summary>Calls InvokeOrPostAction(false) on the supplied SynchronizationContextAwaitTaskContinuation.</summary>
/// <param name="state">The SynchronizationContextAwaitTaskContinuation.</param>
- [SecurityCritical]
private static void PostAction(object state)
{
var c = (SynchronizationContextAwaitTaskContinuation)state;
@@ -465,7 +461,6 @@ namespace System.Threading.Tasks
/// to be passed as state.
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [SecurityCritical]
private static ContextCallback GetPostActionCallback()
{
ContextCallback callback = s_postActionCallback;
@@ -485,12 +480,11 @@ namespace System.Threading.Tasks
/// <param name="action">The action to invoke. Must not be null.</param>
/// <param name="flowExecutionContext">Whether to capture and restore ExecutionContext.</param>
/// <param name="stackMark">The captured stack mark.</param>
- [SecurityCritical]
internal TaskSchedulerAwaitTaskContinuation(
TaskScheduler scheduler, Action action, bool flowExecutionContext, ref StackCrawlMark stackMark) :
base(action, flowExecutionContext, ref stackMark)
{
- Contract.Assert(scheduler != null);
+ Debug.Assert(scheduler != null);
m_scheduler = scheduler;
}
@@ -550,7 +544,6 @@ namespace System.Threading.Tasks
/// <param name="action">The action to invoke. Must not be null.</param>
/// <param name="flowExecutionContext">Whether to capture and restore ExecutionContext.</param>
/// <param name="stackMark">The captured stack mark with which to construct an ExecutionContext.</param>
- [SecurityCritical]
internal AwaitTaskContinuation(Action action, bool flowExecutionContext, ref StackCrawlMark stackMark)
{
Contract.Requires(action != null);
@@ -566,7 +559,6 @@ namespace System.Threading.Tasks
/// <summary>Initializes the continuation.</summary>
/// <param name="action">The action to invoke. Must not be null.</param>
/// <param name="flowExecutionContext">Whether to capture and restore ExecutionContext.</param>
- [SecurityCritical]
internal AwaitTaskContinuation(Action action, bool flowExecutionContext)
{
Contract.Requires(action != null);
@@ -598,7 +590,6 @@ namespace System.Threading.Tasks
/// <summary>Inlines or schedules the continuation onto the default scheduler.</summary>
/// <param name="ignored">The antecedent task, which is ignored.</param>
/// <param name="canInlineContinuationTask">true if inlining is permitted; otherwise, false.</param>
- [SecuritySafeCritical]
internal override void Run(Task task, bool canInlineContinuationTask)
{
// For the base AwaitTaskContinuation, we allow inlining if our caller allows it
@@ -657,7 +648,6 @@ namespace System.Threading.Tasks
}
/// <summary>IThreadPoolWorkItem override, which is the entry function for this when the ThreadPool scheduler decides to run it.</summary>
- [SecurityCritical]
void ExecuteWorkItemHelper()
{
var etwLog = TplEtwProvider.Log;
@@ -696,7 +686,6 @@ namespace System.Threading.Tasks
}
}
- [SecurityCritical]
void IThreadPoolWorkItem.ExecuteWorkItem()
{
// inline the fast path
@@ -714,20 +703,16 @@ namespace System.Threading.Tasks
/// <summary>
/// The ThreadPool calls this if a ThreadAbortException is thrown while trying to execute this workitem.
/// </summary>
- [SecurityCritical]
void IThreadPoolWorkItem.MarkAborted(ThreadAbortException tae) { /* nop */ }
/// <summary>Cached delegate that invokes an Action passed as an object parameter.</summary>
- [SecurityCritical]
private static ContextCallback s_invokeActionCallback;
/// <summary>Runs an action provided as an object parameter.</summary>
/// <param name="state">The Action to invoke.</param>
- [SecurityCritical]
private static void InvokeAction(object state) { ((Action)state)(); }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [SecurityCritical]
protected static ContextCallback GetInvokeActionCallback()
{
ContextCallback callback = s_invokeActionCallback;
@@ -739,11 +724,10 @@ namespace System.Threading.Tasks
/// <param name="callback">The callback to run.</param>
/// <param name="state">The state to pass to the callback.</param>
/// <param name="currentTask">A reference to Task.t_currentTask.</param>
- [SecurityCritical]
protected void RunCallback(ContextCallback callback, object state, ref Task currentTask)
{
Contract.Requires(callback != null);
- Contract.Assert(currentTask == Task.t_currentTask);
+ Debug.Assert(currentTask == Task.t_currentTask);
// Pretend there's no current task, so that no task is seen as a parent
// and TaskScheduler.Current does not reflect false information
@@ -787,10 +771,9 @@ namespace System.Threading.Tasks
/// only happens in Task.SetContinuationForAwait if execution context flow was disabled
/// via using TaskAwaiter.UnsafeOnCompleted or a similar path.
/// </remarks>
- [SecurityCritical]
internal static void RunOrScheduleAction(Action action, bool allowInlining, ref Task currentTask)
{
- Contract.Assert(currentTask == Task.t_currentTask);
+ Debug.Assert(currentTask == Task.t_currentTask);
// If we're not allowed to run here, schedule the action
if (!allowInlining || !IsValidLocationForInlining)
@@ -818,7 +801,6 @@ namespace System.Threading.Tasks
/// <summary>Schedules the action to be executed. No ExecutionContext work is performed used.</summary>
/// <param name="action">The action to invoke or queue.</param>
- [SecurityCritical]
internal static void UnsafeScheduleAction(Action action, Task task)
{
AwaitTaskContinuation atc = new AwaitTaskContinuation(action, flowExecutionContext: false);
@@ -859,7 +841,7 @@ namespace System.Threading.Tasks
internal override Delegate[] GetDelegateContinuationsForDebugger()
{
- Contract.Assert(m_action != null);
+ Debug.Assert(m_action != null);
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 198db8e15c..45817dab23 100644
--- a/src/mscorlib/src/System/Threading/Tasks/TaskExceptionHolder.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/TaskExceptionHolder.cs
@@ -18,6 +18,7 @@ namespace System.Threading.Tasks
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.ExceptionServices;
using System.Security;
@@ -62,14 +63,9 @@ namespace System.Threading.Tasks
EnsureADUnloadCallbackRegistered();
}
- [SecuritySafeCritical]
private static bool ShouldFailFastOnUnobservedException()
{
- bool shouldFailFast = false;
- #if !FEATURE_CORECLR
- shouldFailFast = System.CLRConfig.CheckThrowUnobservedTaskExceptions();
- #endif
- return shouldFailFast;
+ return false;
}
private static void EnsureADUnloadCallbackRegistered()
@@ -202,12 +198,12 @@ namespace System.Threading.Tasks
{
Contract.Requires(exceptionObject != null, "Expected exceptionObject to be non-null.");
- Contract.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.
- Contract.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.
@@ -221,7 +217,7 @@ namespace System.Threading.Tasks
else
{
var edi = exceptionObject as ExceptionDispatchInfo;
- Contract.Assert(edi != null && edi.SourceException is OperationCanceledException,
+ Debug.Assert(edi != null && edi.SourceException is OperationCanceledException,
"Expected an OCE or an EDI that contained an OCE");
m_cancellationException = edi;
}
@@ -242,7 +238,7 @@ namespace System.Threading.Tasks
// Initialize the exceptions list if necessary. The list should be non-null iff it contains exceptions.
var exceptions = m_faultExceptions;
if (exceptions == null) m_faultExceptions = exceptions = new List<ExceptionDispatchInfo>(1);
- else Contract.Assert(exceptions.Count > 0, "Expected existing exceptions list to have > 0 exceptions.");
+ else Debug.Assert(exceptions.Count > 0, "Expected existing exceptions list to have > 0 exceptions.");
// Handle Exception by capturing it into an ExceptionDispatchInfo and storing that
var exception = exceptionObject as Exception;
@@ -270,13 +266,13 @@ namespace System.Threading.Tasks
foreach (var exc in exColl)
{
#if DEBUG
- Contract.Assert(exc != null, "No exceptions should be null");
+ Debug.Assert(exc != null, "No exceptions should be null");
numExceptions++;
#endif
exceptions.Add(ExceptionDispatchInfo.Capture(exc));
}
#if DEBUG
- Contract.Assert(numExceptions > 0, "Collection should contain at least one exception.");
+ Debug.Assert(numExceptions > 0, "Collection should contain at least one exception.");
#endif
}
else
@@ -287,17 +283,17 @@ namespace System.Threading.Tasks
{
exceptions.AddRange(ediColl);
#if DEBUG
- Contract.Assert(exceptions.Count > 0, "There should be at least one dispatch info.");
+ Debug.Assert(exceptions.Count > 0, "There should be at least one dispatch info.");
foreach(var tmp in exceptions)
{
- Contract.Assert(tmp != null, "No dispatch infos should be null");
+ Debug.Assert(tmp != null, "No dispatch infos should be null");
}
#endif
}
// Anything else is a programming error
else
{
- throw new ArgumentException(Environment.GetResourceString("TaskExceptionHolder_UnknownExceptionType"), "exceptionObject");
+ throw new ArgumentException(Environment.GetResourceString("TaskExceptionHolder_UnknownExceptionType"), nameof(exceptionObject));
}
}
}
@@ -370,8 +366,8 @@ namespace System.Threading.Tasks
internal AggregateException CreateExceptionObject(bool calledFromFinalizer, Exception includeThisException)
{
var exceptions = m_faultExceptions;
- Contract.Assert(exceptions != null, "Expected an initialized list.");
- Contract.Assert(exceptions.Count > 0, "Expected at least one exception.");
+ Debug.Assert(exceptions != null, "Expected an initialized list.");
+ Debug.Assert(exceptions.Count > 0, "Expected at least one exception.");
// Mark as handled and aggregate the exceptions.
MarkAsHandled(calledFromFinalizer);
@@ -400,8 +396,8 @@ namespace System.Threading.Tasks
internal ReadOnlyCollection<ExceptionDispatchInfo> GetExceptionDispatchInfos()
{
var exceptions = m_faultExceptions;
- Contract.Assert(exceptions != null, "Expected an initialized list.");
- Contract.Assert(exceptions.Count > 0, "Expected at least one exception.");
+ Debug.Assert(exceptions != null, "Expected an initialized list.");
+ Debug.Assert(exceptions.Count > 0, "Expected at least one exception.");
MarkAsHandled(false);
return new ReadOnlyCollection<ExceptionDispatchInfo>(exceptions);
}
@@ -416,7 +412,7 @@ namespace System.Threading.Tasks
internal ExceptionDispatchInfo GetCancellationExceptionDispatchInfo()
{
var edi = m_cancellationException;
- Contract.Assert(edi == null || edi.SourceException is OperationCanceledException,
+ Debug.Assert(edi == null || edi.SourceException is OperationCanceledException,
"Expected the EDI to be for an OperationCanceledException");
return edi;
}
diff --git a/src/mscorlib/src/System/Threading/Tasks/TaskFactory.cs b/src/mscorlib/src/System/Threading/Tasks/TaskFactory.cs
index 52b471628a..aa4c2df74b 100644
--- a/src/mscorlib/src/System/Threading/Tasks/TaskFactory.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/TaskFactory.cs
@@ -18,6 +18,7 @@ using System.Security;
using System.Security.Permissions;
using System.Runtime.CompilerServices;
using System.Threading;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
namespace System.Threading.Tasks
@@ -37,7 +38,6 @@ namespace System.Threading.Tasks
/// <see cref="System.Threading.Tasks.Task.Factory">Task.Factory</see> property.
/// </para>
/// </remarks>
- [HostProtection(Synchronization = true, ExternalThreading = true)]
public class TaskFactory
{
// member variables
@@ -225,7 +225,7 @@ namespace System.Threading.Tasks
TaskCreationOptions.PreferFairness |
TaskCreationOptions.RunContinuationsAsynchronously)) != 0)
{
- throw new ArgumentOutOfRangeException("creationOptions");
+ throw new ArgumentOutOfRangeException(nameof(creationOptions));
}
Contract.EndContractBlock();
}
@@ -1593,9 +1593,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("creationOptions", Environment.GetResourceString("Task_FromAsync_LongRunning"));
+ throw new ArgumentOutOfRangeException(nameof(creationOptions), Environment.GetResourceString("Task_FromAsync_LongRunning"));
if ((creationOptions & TaskCreationOptions.PreferFairness) != 0)
- throw new ArgumentOutOfRangeException("creationOptions", Environment.GetResourceString("Task_FromAsync_PreferFairness"));
+ throw new ArgumentOutOfRangeException(nameof(creationOptions), Environment.GetResourceString("Task_FromAsync_PreferFairness"));
}
// Check for general validity of options
@@ -1606,7 +1606,7 @@ namespace System.Threading.Tasks
TaskCreationOptions.PreferFairness |
TaskCreationOptions.LongRunning)) != 0)
{
- throw new ArgumentOutOfRangeException("creationOptions");
+ throw new ArgumentOutOfRangeException(nameof(creationOptions));
}
}
@@ -1666,7 +1666,7 @@ namespace System.Threading.Tasks
TrySetResult(_tasks);
}
- Contract.Assert(_count >= 0, "Count should never go below 0");
+ Debug.Assert(_count >= 0, "Count should never go below 0");
}
public bool InvokeMayRunArbitraryCode { get { return true; } }
@@ -1746,7 +1746,7 @@ namespace System.Threading.Tasks
TrySetResult(_tasks);
}
- Contract.Assert(_count >= 0, "Count should never go below 0");
+ Debug.Assert(_count >= 0, "Count should never go below 0");
}
public bool InvokeMayRunArbitraryCode { get { return true; } }
@@ -1801,7 +1801,7 @@ namespace System.Threading.Tasks
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAll(Task[] tasks, Action<Task[]> continuationAction)
{
- if (continuationAction == null) throw new ArgumentNullException("continuationAction");
+ if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -1833,7 +1833,7 @@ namespace System.Threading.Tasks
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAll(Task[] tasks, Action<Task[]> continuationAction, CancellationToken cancellationToken)
{
- if (continuationAction == null) throw new ArgumentNullException("continuationAction");
+ if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -1870,7 +1870,7 @@ namespace System.Threading.Tasks
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAll(Task[] tasks, Action<Task[]> continuationAction, TaskContinuationOptions continuationOptions)
{
- if (continuationAction == null) throw new ArgumentNullException("continuationAction");
+ if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -1918,7 +1918,7 @@ namespace System.Threading.Tasks
public Task ContinueWhenAll(Task[] tasks, Action<Task[]> continuationAction, CancellationToken cancellationToken,
TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
{
- if (continuationAction == null) throw new ArgumentNullException("continuationAction");
+ if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -1945,7 +1945,7 @@ namespace System.Threading.Tasks
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAll<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>[]> continuationAction)
{
- if (continuationAction == null) throw new ArgumentNullException("continuationAction");
+ if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -1979,7 +1979,7 @@ namespace System.Threading.Tasks
public Task ContinueWhenAll<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>[]> continuationAction,
CancellationToken cancellationToken)
{
- if (continuationAction == null) throw new ArgumentNullException("continuationAction");
+ if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -2018,7 +2018,7 @@ namespace System.Threading.Tasks
public Task ContinueWhenAll<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>[]> continuationAction,
TaskContinuationOptions continuationOptions)
{
- if (continuationAction == null) throw new ArgumentNullException("continuationAction");
+ if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -2067,7 +2067,7 @@ namespace System.Threading.Tasks
public Task ContinueWhenAll<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>[]> continuationAction,
CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
{
- if (continuationAction == null) throw new ArgumentNullException("continuationAction");
+ if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -2097,7 +2097,7 @@ namespace System.Threading.Tasks
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task<TResult> ContinueWhenAll<TResult>(Task[] tasks, Func<Task[], TResult> continuationFunction)
{
- if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
+ if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -2133,7 +2133,7 @@ namespace System.Threading.Tasks
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task<TResult> ContinueWhenAll<TResult>(Task[] tasks, Func<Task[], TResult> continuationFunction, CancellationToken cancellationToken)
{
- if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
+ if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -2174,7 +2174,7 @@ namespace System.Threading.Tasks
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task<TResult> ContinueWhenAll<TResult>(Task[] tasks, Func<Task[], TResult> continuationFunction, TaskContinuationOptions continuationOptions)
{
- if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
+ if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -2226,7 +2226,7 @@ namespace System.Threading.Tasks
public Task<TResult> ContinueWhenAll<TResult>(Task[] tasks, Func<Task[], TResult> continuationFunction, CancellationToken cancellationToken,
TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
{
- if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
+ if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -2258,7 +2258,7 @@ namespace System.Threading.Tasks
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>[], TResult> continuationFunction)
{
- if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
+ if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -2295,7 +2295,7 @@ namespace System.Threading.Tasks
public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>[], TResult> continuationFunction,
CancellationToken cancellationToken)
{
- if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
+ if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -2338,7 +2338,7 @@ namespace System.Threading.Tasks
public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>[], TResult> continuationFunction,
TaskContinuationOptions continuationOptions)
{
- if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
+ if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -2391,7 +2391,7 @@ namespace System.Threading.Tasks
public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>[], TResult> continuationFunction,
CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
{
- if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
+ if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -2448,7 +2448,7 @@ namespace System.Threading.Tasks
}
bool success = TrySetResult(completingTask);
- Contract.Assert(success, "Only one task should have gotten to this point, and thus this must be successful.");
+ Debug.Assert(success, "Only one task should have gotten to this point, and thus this must be successful.");
// We need to remove continuations that may be left straggling on other tasks.
// Otherwise, repeated calls to WhenAny using the same task could leak actions.
@@ -2489,7 +2489,7 @@ namespace System.Threading.Tasks
for(int i=0; i<numTasks; i++)
{
var task = tasks[i];
- if (task == null) throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_NullTask"), "tasks");
+ if (task == null) throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_NullTask"), nameof(tasks));
if (checkArgsOnly) continue;
@@ -2531,7 +2531,7 @@ namespace System.Threading.Tasks
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAny(Task[] tasks, Action<Task> continuationAction)
{
- if (continuationAction == null) throw new ArgumentNullException("continuationAction");
+ if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -2562,7 +2562,7 @@ namespace System.Threading.Tasks
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAny(Task[] tasks, Action<Task> continuationAction, CancellationToken cancellationToken)
{
- if (continuationAction == null) throw new ArgumentNullException("continuationAction");
+ if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -2599,7 +2599,7 @@ namespace System.Threading.Tasks
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAny(Task[] tasks, Action<Task> continuationAction, TaskContinuationOptions continuationOptions)
{
- if (continuationAction == null) throw new ArgumentNullException("continuationAction");
+ if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -2647,7 +2647,7 @@ namespace System.Threading.Tasks
public Task ContinueWhenAny(Task[] tasks, Action<Task> continuationAction, CancellationToken cancellationToken,
TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
{
- if (continuationAction == null) throw new ArgumentNullException("continuationAction");
+ if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -2678,7 +2678,7 @@ namespace System.Threading.Tasks
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task<TResult> ContinueWhenAny<TResult>(Task[] tasks, Func<Task, TResult> continuationFunction)
{
- if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
+ if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -2713,7 +2713,7 @@ namespace System.Threading.Tasks
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task<TResult> ContinueWhenAny<TResult>(Task[] tasks, Func<Task, TResult> continuationFunction, CancellationToken cancellationToken)
{
- if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
+ if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -2754,7 +2754,7 @@ namespace System.Threading.Tasks
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task<TResult> ContinueWhenAny<TResult>(Task[] tasks, Func<Task, TResult> continuationFunction, TaskContinuationOptions continuationOptions)
{
- if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
+ if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -2806,7 +2806,7 @@ namespace System.Threading.Tasks
public Task<TResult> ContinueWhenAny<TResult>(Task[] tasks, Func<Task, TResult> continuationFunction, CancellationToken cancellationToken,
TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
{
- if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
+ if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -2838,7 +2838,7 @@ namespace System.Threading.Tasks
public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>, TResult> continuationFunction)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
+ if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction));
return TaskFactory<TResult>.ContinueWhenAnyImpl<TAntecedentResult>(tasks, continuationFunction, null, m_defaultContinuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
}
@@ -2872,7 +2872,7 @@ namespace System.Threading.Tasks
public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>, TResult> continuationFunction,
CancellationToken cancellationToken)
{
- if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
+ if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -2915,7 +2915,7 @@ namespace System.Threading.Tasks
public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>, TResult> continuationFunction,
TaskContinuationOptions continuationOptions)
{
- if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
+ if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -2968,7 +2968,7 @@ namespace System.Threading.Tasks
public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>, TResult> continuationFunction,
CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
{
- if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
+ if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -2996,7 +2996,7 @@ namespace System.Threading.Tasks
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public Task ContinueWhenAny<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>> continuationAction)
{
- if (continuationAction == null) throw new ArgumentNullException("continuationAction");
+ if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -3029,7 +3029,7 @@ namespace System.Threading.Tasks
public Task ContinueWhenAny<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>> continuationAction,
CancellationToken cancellationToken)
{
- if (continuationAction == null) throw new ArgumentNullException("continuationAction");
+ if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -3068,7 +3068,7 @@ namespace System.Threading.Tasks
public Task ContinueWhenAny<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>> continuationAction,
TaskContinuationOptions continuationOptions)
{
- if (continuationAction == null) throw new ArgumentNullException("continuationAction");
+ if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -3117,7 +3117,7 @@ namespace System.Threading.Tasks
public Task ContinueWhenAny<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>> continuationAction,
CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
{
- if (continuationAction == null) throw new ArgumentNullException("continuationAction");
+ if (continuationAction == null) throw new ArgumentNullException(nameof(continuationAction));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -3129,9 +3129,9 @@ namespace System.Threading.Tasks
internal static Task[] CheckMultiContinuationTasksAndCopy(Task[] tasks)
{
if (tasks == null)
- throw new ArgumentNullException("tasks");
+ throw new ArgumentNullException(nameof(tasks));
if (tasks.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_EmptyTaskList"), "tasks");
+ throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_EmptyTaskList"), nameof(tasks));
Contract.EndContractBlock();
Task[] tasksCopy = new Task[tasks.Length];
@@ -3140,7 +3140,7 @@ namespace System.Threading.Tasks
tasksCopy[i] = tasks[i];
if (tasksCopy[i] == null)
- throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_NullTask"), "tasks");
+ throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_NullTask"), nameof(tasks));
}
return tasksCopy;
@@ -3149,9 +3149,9 @@ namespace System.Threading.Tasks
internal static Task<TResult>[] CheckMultiContinuationTasksAndCopy<TResult>(Task<TResult>[] tasks)
{
if (tasks == null)
- throw new ArgumentNullException("tasks");
+ throw new ArgumentNullException(nameof(tasks));
if (tasks.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_EmptyTaskList"), "tasks");
+ throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_EmptyTaskList"), nameof(tasks));
Contract.EndContractBlock();
Task<TResult>[] tasksCopy = new Task<TResult>[tasks.Length];
@@ -3160,7 +3160,7 @@ namespace System.Threading.Tasks
tasksCopy[i] = tasks[i];
if (tasksCopy[i] == null)
- throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_NullTask"), "tasks");
+ throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_NullTask"), nameof(tasks));
}
return tasksCopy;
@@ -3179,7 +3179,7 @@ namespace System.Threading.Tasks
const TaskContinuationOptions illegalMask = TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.LongRunning;
if ((continuationOptions & illegalMask) == illegalMask)
{
- throw new ArgumentOutOfRangeException("continuationOptions", Environment.GetResourceString("Task_ContinueWith_ESandLR"));
+ throw new ArgumentOutOfRangeException(nameof(continuationOptions), Environment.GetResourceString("Task_ContinueWith_ESandLR"));
}
// Check that no nonsensical options are specified.
@@ -3193,12 +3193,12 @@ namespace System.Threading.Tasks
NotOnAny |
TaskContinuationOptions.ExecuteSynchronously)) != 0)
{
- throw new ArgumentOutOfRangeException("continuationOptions");
+ throw new ArgumentOutOfRangeException(nameof(continuationOptions));
}
// Check that no "fire" options are specified.
if ((continuationOptions & NotOnAny) != 0)
- throw new ArgumentOutOfRangeException("continuationOptions", Environment.GetResourceString("Task_MultiTaskContinuation_FireOptions"));
+ throw new ArgumentOutOfRangeException(nameof(continuationOptions), Environment.GetResourceString("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 f82492499c..fad3fc06c5 100644
--- a/src/mscorlib/src/System/Threading/Tasks/TaskScheduler.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/TaskScheduler.cs
@@ -41,10 +41,6 @@ namespace System.Threading.Tasks
/// </remarks>
[DebuggerDisplay("Id={Id}")]
[DebuggerTypeProxy(typeof(SystemThreadingTasks_TaskSchedulerDebugView))]
- [HostProtection(Synchronization = true, ExternalThreading = true)]
-#pragma warning disable 618
- [PermissionSet(SecurityAction.InheritanceDemand, Unrestricted = true)]
-#pragma warning restore 618
public abstract class TaskScheduler
{
////////////////////////////////////////////////////////////
@@ -70,7 +66,6 @@ namespace System.Threading.Tasks
/// </remarks>
/// <param name="task">The <see cref="T:System.Threading.Tasks.Task">Task</see> to be queued.</param>
/// <exception cref="T:System.ArgumentNullException">The <paramref name="task"/> argument is null.</exception>
- [SecurityCritical]
protected internal abstract void QueueTask(Task task);
/// <summary>
@@ -113,7 +108,6 @@ namespace System.Threading.Tasks
/// null.</exception>
/// <exception cref="T:System.InvalidOperationException">The <paramref name="task"/> was already
/// executed.</exception>
- [SecurityCritical]
protected abstract bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued);
/// <summary>
@@ -157,7 +151,6 @@ namespace System.Threading.Tasks
/// <exception cref="T:System.NotSupportedException">
/// This scheduler is unable to generate a list of queued tasks at this time.
/// </exception>
- [SecurityCritical]
protected abstract IEnumerable<Task> GetScheduledTasks();
/// <summary>
@@ -185,7 +178,6 @@ namespace System.Threading.Tasks
/// <param name="taskWasPreviouslyQueued">True if the task may have been previously queued,
/// false if the task was absolutely not previously queued.</param>
/// <returns>True if it ran, false otherwise.</returns>
- [SecuritySafeCritical]
internal bool TryRunInline(Task task, bool taskWasPreviouslyQueued)
{
// Do not inline unstarted tasks (i.e., task.ExecutingTaskScheduler == null).
@@ -237,7 +229,6 @@ namespace System.Threading.Tasks
/// <param name="task">The <see cref="T:System.Threading.Tasks.Task">Task</see> to be dequeued.</param>
/// <returns>A Boolean denoting whether the <paramref name="task"/> argument was successfully dequeued.</returns>
/// <exception cref="T:System.ArgumentNullException">The <paramref name="task"/> argument is null.</exception>
- [SecurityCritical]
protected internal virtual bool TryDequeue(Task task)
{
return false;
@@ -262,7 +253,6 @@ namespace System.Threading.Tasks
/// <summary>
/// Calls QueueTask() after performing any needed firing of events
/// </summary>
- [SecurityCritical]
internal void InternalQueueTask(Task task)
{
Contract.Requires(task != null);
@@ -444,7 +434,6 @@ namespace System.Threading.Tasks
/// <returns>A Boolean that is true if <paramref name="task"/> was successfully executed, false if it
/// was not. A common reason for execution failure is that the task had previously been executed or
/// is in the process of being executed by another thread.</returns>
- [SecurityCritical]
protected bool TryExecuteTask(Task task)
{
if (task.ExecutingTaskScheduler != this)
@@ -475,7 +464,6 @@ namespace System.Threading.Tasks
/// </remarks>
public static event EventHandler<UnobservedTaskExceptionEventArgs> UnobservedTaskException
{
- [System.Security.SecurityCritical]
add
{
if (value != null)
@@ -485,7 +473,6 @@ namespace System.Threading.Tasks
}
}
- [System.Security.SecurityCritical]
remove
{
lock (_unobservedTaskExceptionLockObject) _unobservedTaskException -= value;
@@ -531,7 +518,6 @@ namespace System.Threading.Tasks
/// <exception cref="T:System.NotSupportedException">
/// This scheduler is unable to generate a list of queued tasks at this time.
/// </exception>
- [SecurityCritical]
internal Task[] GetScheduledTasksForDebugger()
{
// this can throw InvalidOperationException indicating that they are unable to provide the info
@@ -566,7 +552,6 @@ namespace System.Threading.Tasks
/// It should not be called by any other codepaths.
/// </remarks>
/// <returns>An array of <see cref="System.Threading.Tasks.TaskScheduler">TaskScheduler</see> instances.</returns>
- [SecurityCritical]
internal static TaskScheduler[] GetTaskSchedulersForDebugger()
{
if (s_activeTaskSchedulers == null)
@@ -587,7 +572,7 @@ namespace System.Threading.Tasks
schedulers.CopyTo(arr, 0);
foreach (var scheduler in arr)
{
- Contract.Assert(scheduler != null, "Table returned an incorrect Count or CopyTo failed");
+ Debug.Assert(scheduler != null, "Table returned an incorrect Count or CopyTo failed");
int tmp = scheduler.Id; // force Ids for debugger
}
return arr;
@@ -613,7 +598,6 @@ namespace System.Threading.Tasks
// returns the scheduler’s GetScheduledTasks
public IEnumerable<Task> ScheduledTasks
{
- [SecurityCritical]
get { return m_taskScheduler.GetScheduledTasks(); }
}
}
@@ -656,7 +640,6 @@ namespace System.Threading.Tasks
/// Simply posts the tasks to be executed on the associated <see cref="T:System.Threading.SynchronizationContext"/>.
/// </summary>
/// <param name="task"></param>
- [SecurityCritical]
protected internal override void QueueTask(Task task)
{
m_synchronizationContext.Post(s_postCallback, (object)task);
@@ -670,7 +653,6 @@ namespace System.Threading.Tasks
/// </summary>
/// <param name="task"></param>
/// <param name="taskWasPreviouslyQueued"></param>
- [SecurityCritical]
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
if (SynchronizationContext.Current == m_synchronizationContext)
@@ -682,7 +664,6 @@ namespace System.Threading.Tasks
}
// not implemented
- [SecurityCritical]
protected override IEnumerable<Task> GetScheduledTasks()
{
return null;
diff --git a/src/mscorlib/src/System/Threading/Tasks/TaskToApm.cs b/src/mscorlib/src/System/Threading/Tasks/TaskToApm.cs
index 02b130c297..90743aeec5 100644
--- a/src/mscorlib/src/System/Threading/Tasks/TaskToApm.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/TaskToApm.cs
@@ -22,6 +22,7 @@
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
using System.IO;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
namespace System.Threading.Tasks
@@ -76,7 +77,7 @@ namespace System.Threading.Tasks
if (twar != null)
{
task = twar.Task;
- Contract.Assert(task != null, "TaskWrapperAsyncResult should never wrap a null Task.");
+ Debug.Assert(task != null, "TaskWrapperAsyncResult should never wrap a null Task.");
}
// Otherwise, the IAsyncResult should be a Task.
else
@@ -101,7 +102,7 @@ namespace System.Threading.Tasks
if (twar != null)
{
task = twar.Task as Task<TResult>;
- Contract.Assert(twar.Task != null, "TaskWrapperAsyncResult should never wrap a null Task.");
+ Debug.Assert(twar.Task != null, "TaskWrapperAsyncResult should never wrap a null Task.");
}
// Otherwise, the IAsyncResult should be a Task<TResult>.
else
diff --git a/src/mscorlib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs b/src/mscorlib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs
index dd4cbc9a66..5c6ca9bb76 100644
--- a/src/mscorlib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs
@@ -13,6 +13,7 @@
using System;
using System.Security;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Collections.Generic;
using System.Text;
@@ -39,7 +40,7 @@ namespace System.Threading.Tasks
{
Contract.Requires(obj != null, "TaskScheduler.LongRunningThreadWork: obj is null");
Task t = obj as Task;
- Contract.Assert(t != null, "TaskScheduler.LongRunningThreadWork: t is null");
+ Debug.Assert(t != null, "TaskScheduler.LongRunningThreadWork: t is null");
t.ExecuteEntry(false);
}
@@ -47,7 +48,6 @@ namespace System.Threading.Tasks
/// Schedules a task to the ThreadPool.
/// </summary>
/// <param name="task">The task to schedule.</param>
- [SecurityCritical]
protected internal override void QueueTask(Task task)
{
if ((task.Options & TaskCreationOptions.LongRunning) != 0)
@@ -73,7 +73,6 @@ namespace System.Threading.Tasks
/// 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.
/// </summary>
- [SecurityCritical]
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
// If the task was previously scheduled, and we can't pop it, then return false.
@@ -95,14 +94,12 @@ namespace System.Threading.Tasks
return rval;
}
- [SecurityCritical]
protected internal override bool TryDequeue(Task task)
{
// just delegate to TP
return ThreadPool.TryPopCustomWorkItem(task);
}
- [SecurityCritical]
protected override IEnumerable<Task> GetScheduledTasks()
{
return FilterTasksFromWorkItems(ThreadPool.GetQueuedWorkItems());
diff --git a/src/mscorlib/src/System/Threading/Tasks/future.cs b/src/mscorlib/src/System/Threading/Tasks/future.cs
index 39e6ca1d45..0c3fec89b7 100644
--- a/src/mscorlib/src/System/Threading/Tasks/future.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/future.cs
@@ -65,7 +65,6 @@ namespace System.Threading.Tasks
/// and may be used from multiple threads concurrently.
/// </para>
/// </remarks>
- [HostProtection(Synchronization = true, ExternalThreading = true)]
[DebuggerTypeProxy(typeof(SystemThreadingTasks_FutureDebugView<>))]
[DebuggerDisplay("Id = {Id}, Status = {Status}, Method = {DebuggerDisplayMethodDescription}, Result = {DebuggerDisplayResultDescription}")]
public class Task<TResult> : Task
@@ -447,7 +446,7 @@ namespace System.Threading.Tasks
{
get
{
- Delegate d = (Delegate)m_action;
+ Delegate d = m_action;
return d != null ? d.Method.ToString() : "{null}";
}
}
@@ -457,7 +456,7 @@ namespace System.Threading.Tasks
internal bool TrySetResult(TResult result)
{
if (IsCompleted) return false;
- Contract.Assert(m_action == null, "Task<T>.TrySetResult(): non-null m_action");
+ 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
// has been made, (2) The result has not already been set, (3) An exception has not previously
@@ -497,7 +496,7 @@ namespace System.Threading.Tasks
// the task, avoiding expensive completion paths, before the task is actually given to anyone.
internal void DangerousSetResult(TResult result)
{
- Contract.Assert(!IsCompleted, "The promise must not yet be completed.");
+ Debug.Assert(!IsCompleted, "The promise must not yet be completed.");
// If we have a parent, we need to notify it of the completion. Take the slow path to handle that.
if (m_contingentProperties?.m_parent != null)
@@ -505,7 +504,7 @@ namespace System.Threading.Tasks
bool success = TrySetResult(result);
// Nobody else has had a chance to complete this Task yet, so we should succeed.
- Contract.Assert(success);
+ Debug.Assert(success);
}
else
{
@@ -539,7 +538,7 @@ namespace System.Threading.Tasks
{
get
{
- Contract.Assert(!IsWaitNotificationEnabledOrNotRanToCompletion,
+ Debug.Assert(!IsWaitNotificationEnabledOrNotRanToCompletion,
"Should only be used when the task completed successfully and there's no wait notification enabled");
return m_result;
}
@@ -558,7 +557,7 @@ namespace System.Threading.Tasks
if (!IsRanToCompletion) ThrowIfExceptional(includeTaskCanceledExceptions: true);
// We shouldn't be here if the result has not been set.
- Contract.Assert(IsRanToCompletion, "Task<T>.Result getter: Expected result to have been set.");
+ Debug.Assert(IsRanToCompletion, "Task<T>.Result getter: Expected result to have been set.");
return m_result;
}
@@ -572,13 +571,13 @@ namespace System.Threading.Tasks
// Called from TaskCompletionSource<T>.SetException(IEnumerable<Exception>).
internal bool TrySetException(object exceptionObject)
{
- Contract.Assert(m_action == null, "Task<T>.TrySetException(): non-null m_action");
+ Debug.Assert(m_action == null, "Task<T>.TrySetException(): non-null m_action");
// TCS.{Try}SetException() should have checked for this
- Contract.Assert(exceptionObject != null, "Expected non-null exceptionObject argument");
+ Debug.Assert(exceptionObject != null, "Expected non-null exceptionObject argument");
// Only accept these types.
- Contract.Assert(
+ Debug.Assert(
(exceptionObject is Exception) || (exceptionObject is IEnumerable<Exception>) ||
(exceptionObject is ExceptionDispatchInfo) || (exceptionObject is IEnumerable<ExceptionDispatchInfo>),
"Expected exceptionObject to be either Exception, ExceptionDispatchInfo, or IEnumerable<> of one of those");
@@ -620,10 +619,10 @@ namespace System.Threading.Tasks
// This method is only valid for promise tasks.
internal bool TrySetCanceled(CancellationToken tokenToRecord, object cancellationException)
{
- Contract.Assert(m_action == null, "Task<T>.TrySetCanceled(): non-null m_action");
+ Debug.Assert(m_action == null, "Task<T>.TrySetCanceled(): non-null m_action");
#if DEBUG
var ceAsEdi = cancellationException as ExceptionDispatchInfo;
- Contract.Assert(
+ Debug.Assert(
cancellationException == null ||
cancellationException is OperationCanceledException ||
(ceAsEdi != null && ceAsEdi.SourceException is OperationCanceledException),
@@ -669,7 +668,7 @@ namespace System.Threading.Tasks
internal override void InnerInvoke()
{
// Invoke the delegate
- Contract.Assert(m_action != null);
+ Debug.Assert(m_action != null);
var func = m_action as Func<TResult>;
if (func != null)
{
@@ -682,7 +681,7 @@ namespace System.Threading.Tasks
m_result = funcWithState(m_stateObject);
return;
}
- Contract.Assert(false, "Invalid m_action in Task<TResult>");
+ Debug.Assert(false, "Invalid m_action in Task<TResult>");
}
#region Await Support
diff --git a/src/mscorlib/src/System/Threading/Thread.cs b/src/mscorlib/src/System/Threading/Thread.cs
index e62cfae9fe..8294c20c4d 100644
--- a/src/mscorlib/src/System/Threading/Thread.cs
+++ b/src/mscorlib/src/System/Threading/Thread.cs
@@ -12,16 +12,13 @@
**
=============================================================================*/
+using Internal.Runtime.Augments;
+
namespace System.Threading {
using System.Threading;
using System.Runtime;
using System.Runtime.InteropServices;
-#if FEATURE_REMOTING
- using System.Runtime.Remoting.Contexts;
- using System.Runtime.Remoting.Messaging;
-#endif
using System;
- using System.Diagnostics;
using System.Security.Permissions;
using System.Security.Principal;
using System.Globalization;
@@ -31,13 +28,13 @@ namespace System.Threading {
using System.Runtime.ConstrainedExecution;
using System.Security;
using System.Runtime.Versioning;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
internal delegate Object InternalCrossContextDelegate(Object[] args);
internal class ThreadHelper
{
- [System.Security.SecuritySafeCritical]
static ThreadHelper() {}
Delegate _start;
@@ -53,10 +50,8 @@ namespace System.Threading {
_executionContext = ec;
}
- [System.Security.SecurityCritical]
static internal ContextCallback _ccb = new ContextCallback(ThreadStart_Context);
- [System.Security.SecurityCritical]
static private void ThreadStart_Context(Object state)
{
ThreadHelper t = (ThreadHelper)state;
@@ -71,11 +66,6 @@ namespace System.Threading {
}
// call back helper
- #if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical] // auto-generated
- #else
- [System.Security.SecurityCritical]
- #endif
internal void ThreadStart(object obj)
{
_startArg = obj;
@@ -90,11 +80,6 @@ namespace System.Threading {
}
// call back helper
- #if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical] // auto-generated
- #else
- [System.Security.SecurityCritical]
- #endif
internal void ThreadStart()
{
if (_executionContext != null)
@@ -121,25 +106,20 @@ namespace System.Threading {
// deliberately not [serializable]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_Thread))]
-[System.Runtime.InteropServices.ComVisible(true)]
- public sealed class Thread : CriticalFinalizerObject, _Thread
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class Thread : RuntimeThread, _Thread
{
/*=========================================================================
** Data accessed from managed code that needs to be defined in
** ThreadBaseObject to maintain alignment between the two classes.
** DON'T CHANGE THESE UNLESS YOU MODIFY ThreadBaseObject in vm\object.h
=========================================================================*/
-#if FEATURE_REMOTING
- private Context m_Context;
-#endif
private ExecutionContext m_ExecutionContext; // this call context follows the logical thread
-#if FEATURE_CORECLR
private SynchronizationContext m_SynchronizationContext; // On CoreCLR, this is maintained separately from ExecutionContext
-#endif
private String m_Name;
private Delegate m_Delegate; // Delegate
-
+
#if FEATURE_LEAK_CULTURE_INFO
private CultureInfo m_CurrentCulture;
private CultureInfo m_CurrentUICulture;
@@ -212,11 +192,8 @@ namespace System.Threading {
#endif // FEATURE_LEAK_CULTURE_INFO
}
-#if FEATURE_CORECLR
// Adding an empty default ctor for annotation purposes
- [System.Security.SecuritySafeCritical] // auto-generated
internal Thread(){}
-#endif // FEATURE_CORECLR
/*=========================================================================
** Creates a new Thread object which will begin execution at
@@ -224,41 +201,37 @@ namespace System.Threading {
**
** Exceptions: ArgumentNullException if start == null.
=========================================================================*/
- [System.Security.SecuritySafeCritical] // auto-generated
public Thread(ThreadStart start) {
if (start == null) {
- throw new ArgumentNullException("start");
+ throw new ArgumentNullException(nameof(start));
}
Contract.EndContractBlock();
SetStartHelper((Delegate)start,0); //0 will setup Thread with default stackSize
}
- [System.Security.SecuritySafeCritical] // auto-generated
public Thread(ThreadStart start, int maxStackSize) {
if (start == null) {
- throw new ArgumentNullException("start");
+ throw new ArgumentNullException(nameof(start));
}
if (0 > maxStackSize)
- throw new ArgumentOutOfRangeException("maxStackSize",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(maxStackSize),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
SetStartHelper((Delegate)start, maxStackSize);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public Thread(ParameterizedThreadStart start) {
if (start == null) {
- throw new ArgumentNullException("start");
+ throw new ArgumentNullException(nameof(start));
}
Contract.EndContractBlock();
SetStartHelper((Delegate)start, 0);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public Thread(ParameterizedThreadStart start, int maxStackSize) {
if (start == null) {
- throw new ArgumentNullException("start");
+ throw new ArgumentNullException(nameof(start));
}
if (0 > maxStackSize)
- throw new ArgumentOutOfRangeException("maxStackSize",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(maxStackSize),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
SetStartHelper((Delegate)start, maxStackSize);
}
@@ -269,11 +242,10 @@ namespace System.Threading {
return m_ManagedThreadId;
}
- extern public int ManagedThreadId
+ extern public new int ManagedThreadId
{
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [System.Security.SecuritySafeCritical] // auto-generated
get;
}
@@ -299,17 +271,15 @@ namespace System.Threading {
**
** Exceptions: ThreadStateException if the thread has already been started.
=========================================================================*/
- [HostProtection(Synchronization=true,ExternalThreading=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public void Start()
+ public new void Start()
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
Start(ref stackMark);
}
- [HostProtection(Synchronization=true,ExternalThreading=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public void Start(object parameter)
+ 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
@@ -325,7 +295,6 @@ namespace System.Threading {
Start(ref stackMark);
}
- [System.Security.SecuritySafeCritical]
private void Start(ref StackCrawlMark stackMark)
{
#if FEATURE_COMINTEROP_APARTMENT_SUPPORT
@@ -346,16 +315,11 @@ namespace System.Threading {
ExecutionContext.CaptureOptions.IgnoreSyncCtx);
t.SetExecutionContextHelper(ec);
}
-#if FEATURE_IMPERSONATION
- IPrincipal principal = (IPrincipal)CallContext.Principal;
-#else
+
IPrincipal principal = null;
-#endif
StartInternal(principal, ref stackMark);
}
-
-#if FEATURE_CORECLR
internal ExecutionContext ExecutionContext
{
get { return m_ExecutionContext; }
@@ -366,89 +330,12 @@ namespace System.Threading {
{
get { return m_SynchronizationContext; }
set { m_SynchronizationContext = value; }
- }
-#else // !FEATURE_CORECLR
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- internal ExecutionContext.Reader GetExecutionContextReader()
- {
- return new ExecutionContext.Reader(m_ExecutionContext);
- }
-
- internal bool ExecutionContextBelongsToCurrentScope
- {
- get { return !m_ExecutionContextBelongsToOuterScope; }
- set { m_ExecutionContextBelongsToOuterScope = !value; }
- }
-
-#if DEBUG
- internal bool ForbidExecutionContextMutation
- {
- set { m_ForbidExecutionContextMutation = value; }
- }
-#endif
-
- // note: please don't access this directly from mscorlib. Use GetMutableExecutionContext or GetExecutionContextReader instead.
- public ExecutionContext ExecutionContext
- {
- [SecuritySafeCritical]
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
- get
- {
- ExecutionContext result;
- if (this == Thread.CurrentThread)
- result = GetMutableExecutionContext();
- else
- result = m_ExecutionContext;
-
- return result;
- }
}
- [SecurityCritical]
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
- internal ExecutionContext GetMutableExecutionContext()
- {
- Contract.Assert(Thread.CurrentThread == this);
-#if DEBUG
- Contract.Assert(!m_ForbidExecutionContextMutation);
-#endif
- if (m_ExecutionContext == null)
- {
- m_ExecutionContext = new ExecutionContext();
- }
- else if (!ExecutionContextBelongsToCurrentScope)
- {
- ExecutionContext copy = m_ExecutionContext.CreateMutableCopy();
- m_ExecutionContext = copy;
- }
-
- ExecutionContextBelongsToCurrentScope = true;
- return m_ExecutionContext;
- }
-
- [SecurityCritical]
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- internal void SetExecutionContext(ExecutionContext value, bool belongsToCurrentScope)
- {
- m_ExecutionContext = value;
- ExecutionContextBelongsToCurrentScope = belongsToCurrentScope;
- }
-
- [SecurityCritical]
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- internal void SetExecutionContext(ExecutionContext.Reader value, bool belongsToCurrentScope)
- {
- m_ExecutionContext = value.DangerousGetRawExecutionContext();
- ExecutionContextBelongsToCurrentScope = belongsToCurrentScope;
- }
-#endif //!FEATURE_CORECLR
-
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void StartInternal(IPrincipal principal, ref StackCrawlMark stackMark);
#if FEATURE_COMPRESSEDSTACK
/// <internalonly/>
- [System.Security.SecurityCritical] // auto-generated_required
[DynamicSecurityMethodAttribute()]
[Obsolete("Thread.SetCompressedStack is no longer supported. Please use the System.Threading.CompressedStack class")]
public void SetCompressedStack( CompressedStack stack )
@@ -456,17 +343,14 @@ namespace System.Threading {
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ThreadAPIsNotSupported"));
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal extern IntPtr SetAppDomainStack( SafeCompressedStackHandle csHandle);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
internal extern void RestoreAppDomainStack( IntPtr appDomainStack);
/// <internalonly/>
- [System.Security.SecurityCritical] // auto-generated_required
[Obsolete("Thread.GetCompressedStack is no longer supported. Please use the System.Threading.CompressedStack class")]
public CompressedStack GetCompressedStack()
{
@@ -478,7 +362,6 @@ namespace System.Threading {
// Helper method to get a logical thread ID for StringBuilder (for
// correctness) and for FileStream's async code path (for perf, to
// avoid creating a Thread instance).
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static IntPtr InternalGetCurrentThread();
@@ -497,34 +380,6 @@ namespace System.Threading {
** If Abort is called twice on the same thread, a DuplicateThreadAbort
** exception is thrown.
=========================================================================*/
-
-#if !FEATURE_CORECLR
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread=true)]
- public void Abort(Object stateInfo)
- {
- // If two aborts come at the same time, it is possible that the state info
- // gets set by one, and the actual abort gets delivered by another. But this
- // is not distinguishable by an application.
- // The accessor helper will only set the value if it isn't already set,
- // and that particular bit of native code can test much faster than this
- // code could, because testing might cause a cross-appdomain marshalling.
- AbortReason = stateInfo;
-
- // Note: we demand ControlThread permission, then call AbortInternal directly
- // rather than delegating to the Abort() function below. We do this to ensure
- // that only callers with ControlThread are allowed to change the AbortReason
- // of the thread. We call AbortInternal directly to avoid demanding the same
- // permission twice.
- AbortInternal();
- }
-#endif
-
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #else
- [System.Security.SecuritySafeCritical]
- #endif
#pragma warning disable 618
[SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)]
#pragma warning restore 618
@@ -535,152 +390,14 @@ namespace System.Threading {
// Internal helper (since we can't place security demands on
// ecalls/fcalls).
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void AbortInternal();
-#if !FEATURE_CORECLR
- /*=========================================================================
- ** Resets a thread abort.
- ** Should be called by trusted code only
- =========================================================================*/
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread=true)]
- public static void ResetAbort()
- {
- Thread thread = Thread.CurrentThread;
- if ((thread.ThreadState & ThreadState.AbortRequested) == 0)
- throw new ThreadStateException(Environment.GetResourceString("ThreadState_NoAbortRequested"));
- thread.ResetAbortNative();
- thread.ClearAbortReason();
- }
-
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private extern void ResetAbortNative();
-
- /*=========================================================================
- ** Suspends the thread. If the thread is already suspended, this call has
- ** no effect.
- **
- ** Exceptions: ThreadStateException if the thread has not been started or
- ** it is dead.
- =========================================================================*/
- [System.Security.SecuritySafeCritical] // auto-generated
- [Obsolete("Thread.Suspend has been deprecated. Please use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources. http://go.microsoft.com/fwlink/?linkid=14202", false)][SecurityPermission(SecurityAction.Demand, ControlThread=true)]
- [SecurityPermission(SecurityAction.Demand, ControlThread=true)]
- public void Suspend() { SuspendInternal(); }
-
- // Internal helper (since we can't place security demands on
- // ecalls/fcalls).
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private extern void SuspendInternal();
-
- /*=========================================================================
- ** Resumes a thread that has been suspended.
- **
- ** Exceptions: ThreadStateException if the thread has not been started or
- ** it is dead or it isn't in the suspended state.
- =========================================================================*/
- [System.Security.SecuritySafeCritical] // auto-generated
- [Obsolete("Thread.Resume has been deprecated. Please use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources. http://go.microsoft.com/fwlink/?linkid=14202", false)]
- [SecurityPermission(SecurityAction.Demand, ControlThread=true)]
- public void Resume() { ResumeInternal(); }
-
- // Internal helper (since we can't place security demands on
- // ecalls/fcalls).
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private extern void ResumeInternal();
-
- /*=========================================================================
- ** Interrupts a thread that is inside a Wait(), Sleep() or Join(). If that
- ** thread is not currently blocked in that manner, it will be interrupted
- ** when it next begins to block.
- =========================================================================*/
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermission(SecurityAction.Demand, ControlThread=true)]
- public void Interrupt() { InterruptInternal(); }
-
- // Internal helper (since we can't place security demands on
- // ecalls/fcalls).
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private extern void InterruptInternal();
-#endif
-
- /*=========================================================================
- ** Returns the priority of the thread.
- **
- ** Exceptions: ThreadStateException if the thread is dead.
- =========================================================================*/
-
- public ThreadPriority Priority {
- [System.Security.SecuritySafeCritical] // auto-generated
- get { return (ThreadPriority)GetPriorityNative(); }
- [System.Security.SecuritySafeCritical] // auto-generated
- [HostProtection(SelfAffectingThreading=true)]
- set { SetPriorityNative((int)value); }
- }
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private extern int GetPriorityNative();
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private extern void SetPriorityNative(int priority);
-
- /*=========================================================================
- ** Returns true if the thread has been started and is not dead.
- =========================================================================*/
- public extern bool IsAlive {
- [System.Security.SecuritySafeCritical] // auto-generated
- [MethodImpl(MethodImplOptions.InternalCall)]
- get;
- }
-
- /*=========================================================================
- ** Returns true if the thread is a threadpool thread.
- =========================================================================*/
- public extern bool IsThreadPoolThread {
- [System.Security.SecuritySafeCritical] // auto-generated
- [MethodImpl(MethodImplOptions.InternalCall)]
- get;
- }
-
- /*=========================================================================
- ** Waits for the thread to die or for timeout milliseconds to elapse.
- ** Returns true if the thread died, or false if the wait timed out. If
- ** Timeout.Infinite is given as the parameter, no timeout will occur.
- **
- ** Exceptions: ArgumentException if timeout < 0.
- ** ThreadInterruptedException if the thread is interrupted while waiting.
- ** ThreadStateException if the thread has not been started yet.
- =========================================================================*/
- [System.Security.SecurityCritical]
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private extern bool JoinInternal(int millisecondsTimeout);
-
- [System.Security.SecuritySafeCritical]
- [HostProtection(Synchronization=true, ExternalThreading=true)]
- public void Join()
- {
- JoinInternal(Timeout.Infinite);
- }
-
- [System.Security.SecuritySafeCritical]
- [HostProtection(Synchronization=true, ExternalThreading=true)]
- public bool Join(int millisecondsTimeout)
- {
- return JoinInternal(millisecondsTimeout);
- }
-
- [HostProtection(Synchronization=true, ExternalThreading=true)]
public bool Join(TimeSpan timeout)
{
long tm = (long)timeout.TotalMilliseconds;
if (tm < -1 || tm > (long) Int32.MaxValue)
- throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
return Join((int)tm);
}
@@ -693,12 +410,10 @@ namespace System.Threading {
** Exceptions: ArgumentException if timeout < 0.
** ThreadInterruptedException if the thread is interrupted while sleeping.
=========================================================================*/
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void SleepInternal(int millisecondsTimeout);
- [System.Security.SecuritySafeCritical] // auto-generated
- public static void Sleep(int millisecondsTimeout)
+ public static new void Sleep(int millisecondsTimeout)
{
SleepInternal(millisecondsTimeout);
// Ensure we don't return to app code when the pause is underway
@@ -710,7 +425,7 @@ namespace System.Threading {
{
long tm = (long)timeout.TotalMilliseconds;
if (tm < -1 || tm > (long) Int32.MaxValue)
- throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
Sleep((int)tm);
}
@@ -719,69 +434,41 @@ namespace System.Threading {
only take a few machine instructions. Calling this API is preferable to coding
a explict busy loop because the hardware can be informed that it is busy waiting. */
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [HostProtection(Synchronization=true,ExternalThreading=true)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
private static extern void SpinWaitInternal(int iterations);
- [System.Security.SecuritySafeCritical] // auto-generated
- [HostProtection(Synchronization=true,ExternalThreading=true)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- public static void SpinWait(int iterations)
+ public static new void SpinWait(int iterations)
{
SpinWaitInternal(iterations);
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
- [HostProtection(Synchronization = true, ExternalThreading = true)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
private static extern bool YieldInternal();
- [System.Security.SecuritySafeCritical] // auto-generated
- [HostProtection(Synchronization = true, ExternalThreading = true)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- public static bool Yield()
+ public static new bool Yield()
{
return YieldInternal();
}
- public static Thread CurrentThread {
- [System.Security.SecuritySafeCritical] // auto-generated
+ public static new Thread CurrentThread {
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
get {
Contract.Ensures(Contract.Result<Thread>() != null);
return GetCurrentThreadNative();
}
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
private static extern Thread GetCurrentThreadNative();
- [System.Security.SecurityCritical] // auto-generated
private void SetStartHelper(Delegate start, int maxStackSize)
{
-#if FEATURE_CORECLR
// We only support default stacks in CoreCLR
- Contract.Assert(maxStackSize == 0);
-#else
- // Only fully-trusted code is allowed to create "large" stacks. Partial-trust falls back to
- // the default stack size.
- ulong defaultStackSize = GetProcessDefaultStackSize();
- if ((ulong)(uint)maxStackSize > defaultStackSize)
- {
- try
- {
- SecurityPermission.Demand(PermissionType.FullTrust);
- }
- catch (SecurityException)
- {
- maxStackSize = (int)Math.Min(defaultStackSize, (ulong)(uint)int.MaxValue);
- }
- }
-#endif
+ Debug.Assert(maxStackSize == 0);
ThreadHelper threadStartCallBack = new ThreadHelper(start);
if(start is ThreadStart)
@@ -794,7 +481,6 @@ namespace System.Threading {
}
}
- [SecurityCritical]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern ulong GetProcessDefaultStackSize();
@@ -803,14 +489,12 @@ namespace System.Threading {
** PRIVATE Sets the IThreadable interface for the thread. Assumes that
** start != null.
=========================================================================*/
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void SetStart(Delegate start, int maxStackSize);
/*=========================================================================
** Clean up the thread when it goes away.
=========================================================================*/
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
~Thread()
{
@@ -818,52 +502,10 @@ namespace System.Threading {
InternalFinalize();
}
- [System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void InternalFinalize();
-#if FEATURE_COMINTEROP
- [System.Security.SecurityCritical] // auto-generated
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public extern void DisableComObjectEagerCleanup();
-#endif //FEATURE_COMINTEROP
-
- /*=========================================================================
- ** Return whether or not this thread is a background thread. Background
- ** threads do not affect when the Execution Engine shuts down.
- **
- ** Exceptions: ThreadStateException if the thread is dead.
- =========================================================================*/
- public bool IsBackground {
- [System.Security.SecuritySafeCritical] // auto-generated
- get { return IsBackgroundNative(); }
- [System.Security.SecuritySafeCritical] // auto-generated
- [HostProtection(SelfAffectingThreading=true)]
- set { SetBackgroundNative(value); }
- }
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private extern bool IsBackgroundNative();
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private extern void SetBackgroundNative(bool isBackground);
-
-
- /*=========================================================================
- ** Return the thread state as a consistent set of bits. This is more
- ** general then IsAlive or IsBackground.
- =========================================================================*/
- public ThreadState ThreadState {
- [System.Security.SecuritySafeCritical] // auto-generated
- get { return (ThreadState)GetThreadStateNative(); }
- }
-
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private extern int GetThreadStateNative();
-
#if FEATURE_COMINTEROP_APARTMENT_SUPPORT
/*=========================================================================
** An unstarted thread can be marked to indicate that it will host a
@@ -875,35 +517,17 @@ namespace System.Threading {
[Obsolete("The ApartmentState property has been deprecated. Use GetApartmentState, SetApartmentState or TrySetApartmentState instead.", false)]
public ApartmentState ApartmentState
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
return (ApartmentState)GetApartmentStateNative();
}
- [System.Security.SecuritySafeCritical] // auto-generated
- [HostProtection(Synchronization=true, SelfAffectingThreading=true)]
set
{
SetApartmentStateNative((int)value, true);
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
- public ApartmentState GetApartmentState()
- {
- return (ApartmentState)GetApartmentStateNative();
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- [HostProtection(Synchronization=true, SelfAffectingThreading=true)]
- public bool TrySetApartmentState(ApartmentState state)
- {
- return SetApartmentStateHelper(state, false);
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- [HostProtection(Synchronization=true, SelfAffectingThreading=true)]
public void SetApartmentState(ApartmentState state)
{
bool result = SetApartmentStateHelper(state, true);
@@ -911,31 +535,6 @@ namespace System.Threading {
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ApartmentStateSwitchFailed"));
}
- [System.Security.SecurityCritical] // auto-generated
- private bool SetApartmentStateHelper(ApartmentState state, bool fireMDAOnMismatch)
- {
- ApartmentState retState = (ApartmentState)SetApartmentStateNative((int)state, fireMDAOnMismatch);
-
- // Special case where we pass in Unknown and get back MTA.
- // Once we CoUninitialize the thread, the OS will still
- // report the thread as implicitly in the MTA if any
- // other thread in the process is CoInitialized.
- if ((state == System.Threading.ApartmentState.Unknown) && (retState == System.Threading.ApartmentState.MTA))
- return true;
-
- if (retState != state)
- return false;
-
- return true;
- }
-
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private extern int GetApartmentStateNative();
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private extern int SetApartmentStateNative(int state, bool fireMDAOnMismatch);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void StartupSetApartmentStateInternal();
#endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT
@@ -944,7 +543,6 @@ namespace System.Threading {
** Allocates an un-named data slot. The slot is allocated on ALL the
** threads.
=========================================================================*/
- [HostProtection(SharedState=true, ExternalThreading=true)]
public static LocalDataStoreSlot AllocateDataSlot()
{
return LocalDataStoreManager.AllocateDataSlot();
@@ -955,7 +553,6 @@ namespace System.Threading {
** threads. Named data slots are "public" and can be manipulated by
** anyone.
=========================================================================*/
- [HostProtection(SharedState=true, ExternalThreading=true)]
public static LocalDataStoreSlot AllocateNamedDataSlot(String name)
{
return LocalDataStoreManager.AllocateNamedDataSlot(name);
@@ -966,7 +563,6 @@ namespace System.Threading {
** allocated. Named data slots are "public" and can be manipulated by
** anyone.
=========================================================================*/
- [HostProtection(SharedState=true, ExternalThreading=true)]
public static LocalDataStoreSlot GetNamedDataSlot(String name)
{
return LocalDataStoreManager.GetNamedDataSlot(name);
@@ -977,7 +573,6 @@ namespace System.Threading {
** threads. Named data slots are "public" and can be manipulated by
** anyone.
=========================================================================*/
- [HostProtection(SharedState=true, ExternalThreading=true)]
public static void FreeNamedDataSlot(String name)
{
LocalDataStoreManager.FreeNamedDataSlot(name);
@@ -986,7 +581,6 @@ namespace System.Threading {
/*=========================================================================
** Retrieves the value from the specified slot on the current thread, for that thread's current domain.
=========================================================================*/
- [HostProtection(SharedState=true, ExternalThreading=true)]
public static Object GetData(LocalDataStoreSlot slot)
{
LocalDataStoreHolder dls = s_LocalDataStore;
@@ -1003,7 +597,6 @@ namespace System.Threading {
/*=========================================================================
** Sets the data in the specified slot on the currently running thread, for that thread's current domain.
=========================================================================*/
- [HostProtection(SharedState=true, ExternalThreading=true)]
public static void SetData(LocalDataStoreSlot slot, Object data)
{
LocalDataStoreHolder dls = s_LocalDataStore;
@@ -1044,7 +637,6 @@ namespace System.Threading {
// default domain to lookup resources. See Environment.cs for more details.
//
#if FEATURE_LEAK_CULTURE_INFO
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static extern private bool nativeGetSafeCulture(Thread t, int appDomainId, bool isUI, ref CultureInfo safeCulture);
#endif // FEATURE_LEAK_CULTURE_INFO
@@ -1075,11 +667,9 @@ namespace System.Threading {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
- [HostProtection(ExternalThreading=true)]
set {
if (value == null) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
@@ -1119,7 +709,6 @@ namespace System.Threading {
}
#if FEATURE_LEAK_CULTURE_INFO
- [System.Security.SecuritySafeCritical] // auto-generated
#endif
internal CultureInfo GetCurrentUICultureNoAppX() {
@@ -1152,7 +741,6 @@ namespace System.Threading {
// This returns the exposed context for a given context ID.
#if FEATURE_LEAK_CULTURE_INFO
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static extern private bool nativeSetThreadUILocale(String locale);
#endif
@@ -1184,13 +772,11 @@ namespace System.Threading {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
#if FEATURE_LEAK_CULTURE_INFO
- [SecurityPermission(SecurityAction.Demand, ControlThread = true)]
#endif
set {
if (null==value) {
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
@@ -1225,7 +811,6 @@ namespace System.Threading {
}
#if FEATURE_LEAK_CULTURE_INFO
- [System.Security.SecuritySafeCritical] // auto-generated
#endif
private CultureInfo GetCurrentCultureNoAppX() {
@@ -1255,114 +840,21 @@ namespace System.Threading {
#endif
}
-#if! FEATURE_LEAK_CULTURE_INFO
- [System.Security.SecurityCritical] // auto-generated
+#if !FEATURE_LEAK_CULTURE_INFO
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void nativeInitCultureAccessors();
#endif
- /*=============================================================*/
-
- /*======================================================================
- ** Current thread context is stored in a slot in the thread local store
- ** CurrentContext gets the Context from the slot.
- ======================================================================*/
-#if FEATURE_REMOTING
- public static Context CurrentContext
- {
- [System.Security.SecurityCritical] // auto-generated_required
- get
- {
- return CurrentThread.GetCurrentContextInternal();
- }
- }
-
- [System.Security.SecurityCritical] // auto-generated
- internal Context GetCurrentContextInternal()
- {
- if (m_Context == null)
- {
- m_Context = Context.DefaultContext;
- }
- return m_Context;
- }
-#endif
-
-
-#if FEATURE_IMPERSONATION
- // Get and set thread's current principal (for role based security).
- public static IPrincipal CurrentPrincipal
- {
- [System.Security.SecuritySafeCritical] // auto-generated
- get
- {
- lock (CurrentThread)
- {
- IPrincipal principal = (IPrincipal)
- CallContext.Principal;
- if (principal == null)
- {
- principal = GetDomain().GetThreadPrincipal();
- CallContext.Principal = principal;
- }
- return principal;
- }
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlPrincipal)]
- set
- {
- CallContext.Principal = value;
- }
- }
-
- // Private routine called from unmanaged code to set an initial
- // principal for a newly created thread.
- [System.Security.SecurityCritical] // auto-generated
- private void SetPrincipalInternal(IPrincipal principal)
- {
- GetMutableExecutionContext().LogicalCallContext.SecurityData.Principal = principal;
- }
-#endif // FEATURE_IMPERSONATION
-
-#if FEATURE_REMOTING
-
- // This returns the exposed context for a given context ID.
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern Context GetContextInternal(IntPtr id);
-
- [System.Security.SecurityCritical] // auto-generated
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal extern Object InternalCrossContextCallback(Context ctx, IntPtr ctxID, Int32 appDomainID, InternalCrossContextDelegate ftnToCall, Object[] args);
-
- [System.Security.SecurityCritical] // auto-generated
- internal Object InternalCrossContextCallback(Context ctx, InternalCrossContextDelegate ftnToCall, Object[] args)
- {
- return InternalCrossContextCallback(ctx, ctx.InternalContextID, 0, ftnToCall, args);
- }
-
- // CompleteCrossContextCallback is called by the EE after transitioning to the requested context
- private static Object CompleteCrossContextCallback(InternalCrossContextDelegate ftnToCall, Object[] args)
- {
- return ftnToCall(args);
- }
-#endif // FEATURE_REMOTING
-
/*======================================================================
** Returns the current domain in which current thread is running.
======================================================================*/
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern AppDomain GetDomainInternal();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern AppDomain GetFastDomainInternal();
- [System.Security.SecuritySafeCritical] // auto-generated
public static AppDomain GetDomain()
{
Contract.Ensures(Contract.Result<AppDomain>() != null);
@@ -1373,9 +865,6 @@ namespace System.Threading {
if (ad == null)
ad = GetDomainInternal();
-#if FEATURE_REMOTING
- Contract.Assert(CurrentThread.m_Context == null || CurrentThread.m_Context.AppDomain == ad, "AppDomains on the managed & unmanaged threads should match");
-#endif
return ad;
}
@@ -1391,13 +880,10 @@ namespace System.Threading {
// Retrieves the name of the thread.
//
- public String Name {
+ public new String Name {
get {
return m_Name;
-
}
- [System.Security.SecuritySafeCritical] // auto-generated
- [HostProtection(ExternalThreading=true)]
set {
lock(this) {
if (m_Name != null)
@@ -1409,13 +895,11 @@ namespace System.Threading {
}
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void InformThreadNameChange(ThreadHandle t, String name, int len);
internal Object AbortReason {
- [System.Security.SecurityCritical] // auto-generated
get {
object result = null;
try
@@ -1428,46 +912,9 @@ namespace System.Threading {
}
return result;
}
- [System.Security.SecurityCritical] // auto-generated
set { SetAbortReason(value); }
}
-#if !FEATURE_CORECLR
- /*
- * This marks the beginning of a critical code region.
- */
- [System.Security.SecuritySafeCritical] // auto-generated
- [HostProtection(Synchronization=true, ExternalThreading=true)]
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
- public static extern void BeginCriticalRegion();
-
- /*
- * This marks the end of a critical code region.
- */
- [System.Security.SecuritySafeCritical] // auto-generated
- [HostProtection(Synchronization=true, ExternalThreading=true)]
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- public static extern void EndCriticalRegion();
-
- /*
- * This marks the beginning of a code region that requires thread affinity.
- */
- [System.Security.SecurityCritical] // auto-generated_required
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
- public static extern void BeginThreadAffinity();
-
- /*
- * This marks the end of a code region that requires thread affinity.
- */
- [System.Security.SecurityCritical] // auto-generated_required
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
- public static extern void EndThreadAffinity();
-#endif // !FEATURE_CORECLR
-
/*=========================================================================
** Volatile Read & Write and MemoryBarrier methods.
** Provides the ability to read and write values ensuring that the values
@@ -1679,7 +1126,6 @@ namespace System.Threading {
address = value;
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void MemoryBarrier();
@@ -1696,45 +1142,20 @@ namespace System.Threading {
}
}
-#if !FEATURE_CORECLR
- void _Thread.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _Thread.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _Thread.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- void _Thread.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
-#endif
-
// Helper function to set the AbortReason for a thread abort.
// Checks that they're not alredy set, and then atomically updates
// the reason info (object + ADID).
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern void SetAbortReason(Object o);
// Helper function to retrieve the AbortReason from a thread
// abort. Will perform cross-AppDomain marshalling if the object
// lives in a different AppDomain from the requester.
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern Object GetAbortReason();
// Helper function to clear the AbortReason. Takes care of
// AppDomain related cleanup if required.
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern void ClearAbortReason();
diff --git a/src/mscorlib/src/System/Threading/ThreadAbortException.cs b/src/mscorlib/src/System/Threading/ThreadAbortException.cs
index 11c8744c72..09ad4e1bd6 100644
--- a/src/mscorlib/src/System/Threading/ThreadAbortException.cs
+++ b/src/mscorlib/src/System/Threading/ThreadAbortException.cs
@@ -39,7 +39,6 @@ namespace System.Threading
public Object ExceptionState
{
- [System.Security.SecuritySafeCritical] // auto-generated
get {return Thread.CurrentThread.AbortReason;}
}
}
diff --git a/src/mscorlib/src/System/Threading/ThreadLocal.cs b/src/mscorlib/src/System/Threading/ThreadLocal.cs
index b4cf12ab7c..2b996cb34d 100644
--- a/src/mscorlib/src/System/Threading/ThreadLocal.cs
+++ b/src/mscorlib/src/System/Threading/ThreadLocal.cs
@@ -15,9 +15,9 @@
//
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-using System.Diagnostics;
using System.Collections.Generic;
using System.Security.Permissions;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
namespace System.Threading
@@ -35,7 +35,6 @@ namespace System.Threading
/// </remarks>
[DebuggerTypeProxy(typeof(SystemThreading_ThreadLocalDebugView<>))]
[DebuggerDisplay("IsValueCreated={IsValueCreated}, Value={ValueForDebugDisplay}, Count={ValuesCountForDebugDisplay}")]
- [HostProtection(Synchronization = true, ExternalThreading = true)]
public class ThreadLocal<T> : IDisposable
{
@@ -107,7 +106,7 @@ namespace System.Threading
public ThreadLocal(Func<T> valueFactory)
{
if (valueFactory == null)
- throw new ArgumentNullException("valueFactory");
+ throw new ArgumentNullException(nameof(valueFactory));
Initialize(valueFactory, false);
}
@@ -127,7 +126,7 @@ namespace System.Threading
public ThreadLocal(Func<T> valueFactory, bool trackAllValues)
{
if (valueFactory == null)
- throw new ArgumentNullException("valueFactory");
+ throw new ArgumentNullException(nameof(valueFactory));
Initialize(valueFactory, trackAllValues);
}
@@ -193,7 +192,7 @@ namespace System.Threading
if (id < 0 || !m_initialized)
{
- Contract.Assert(id >= 0 || !m_initialized, "expected id >= 0 if initialized");
+ Debug.Assert(id >= 0 || !m_initialized, "expected id >= 0 if initialized");
// Handle double Dispose calls or disposal of an instance whose constructor threw an exception.
return;
@@ -550,7 +549,7 @@ namespace System.Threading
/// </summary>
private void GrowTable(ref LinkedSlotVolatile[] table, int minLength)
{
- Contract.Assert(table.Length < minLength);
+ Debug.Assert(table.Length < minLength);
// Determine the size of the new table and allocate it.
int newLen = GetNewTableSize(minLength);
@@ -588,7 +587,7 @@ namespace System.Threading
// Intentionally return a value that will result in an OutOfMemoryException
return int.MaxValue;
}
- Contract.Assert(minSize > 0);
+ Debug.Assert(minSize > 0);
//
// Round up the size to the next power of 2
@@ -737,7 +736,7 @@ namespace System.Threading
~FinalizationHelper()
{
LinkedSlotVolatile[] slotArray = SlotArray;
- Contract.Assert(slotArray != null);
+ Debug.Assert(slotArray != null);
for (int i = 0; i < slotArray.Length; i++)
{
@@ -765,7 +764,7 @@ namespace System.Threading
}
// Since the list uses a dummy head node, the Previous reference should never be null.
- Contract.Assert(linkedSlot.Previous != null);
+ Debug.Assert(linkedSlot.Previous != null);
linkedSlot.Previous.Next = linkedSlot.Next;
}
}
diff --git a/src/mscorlib/src/System/Threading/ThreadPool.cs b/src/mscorlib/src/System/Threading/ThreadPool.cs
index 09fe93c682..451b15d22f 100644
--- a/src/mscorlib/src/System/Threading/ThreadPool.cs
+++ b/src/mscorlib/src/System/Threading/ThreadPool.cs
@@ -29,15 +29,14 @@
namespace System.Threading
{
using System.Security;
- using System.Runtime.Remoting;
using System.Security.Permissions;
using System;
using Microsoft.Win32;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
- using System.Runtime.Versioning;
using System.Collections.Generic;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Tracing;
@@ -46,19 +45,17 @@ namespace System.Threading
{
//Per-appDomain quantum (in ms) for which the thread keeps processing
//requests in the current domain.
- public static uint tpQuantum = 30U;
+ public const uint TP_QUANTUM = 30U;
- public static int processorCount = Environment.ProcessorCount;
+ public static readonly int processorCount = Environment.ProcessorCount;
- public static bool tpHosted = ThreadPool.IsThreadPoolHosted();
+ public static readonly bool tpHosted = ThreadPool.IsThreadPoolHosted();
public static volatile bool vmTpInitialized;
public static bool enableWorkerTracking;
- [SecurityCritical]
- public static ThreadPoolWorkQueue workQueue = new ThreadPoolWorkQueue();
+ public static readonly ThreadPoolWorkQueue workQueue = new ThreadPoolWorkQueue();
- [System.Security.SecuritySafeCritical] // static constructors should be safe to call
static ThreadPoolGlobals()
{
}
@@ -173,7 +170,7 @@ namespace System.Threading
//
m_headIndex = m_headIndex & m_mask;
m_tailIndex = tail = m_tailIndex & m_mask;
- Contract.Assert(m_headIndex <= m_tailIndex);
+ Debug.Assert(m_headIndex <= m_tailIndex);
}
}
finally
@@ -235,7 +232,7 @@ namespace System.Threading
IThreadPoolWorkItem unused;
if (LocalPop(out unused))
{
- Contract.Assert(unused == obj);
+ Debug.Assert(unused == obj);
return true;
}
return false;
@@ -434,23 +431,23 @@ namespace System.Threading
upper = (i >> 16) & SixteenBits;
lower = i & SixteenBits;
- Contract.Assert(upper >= lower);
- Contract.Assert(upper <= nodes.Length);
- Contract.Assert(lower <= nodes.Length);
- Contract.Assert(upper >= 0);
- Contract.Assert(lower >= 0);
+ Debug.Assert(upper >= lower);
+ Debug.Assert(upper <= nodes.Length);
+ Debug.Assert(lower <= nodes.Length);
+ Debug.Assert(upper >= 0);
+ Debug.Assert(lower >= 0);
}
bool CompareExchangeIndexes(ref int prevUpper, int newUpper, ref int prevLower, int newLower)
{
- Contract.Assert(newUpper >= newLower);
- Contract.Assert(newUpper <= nodes.Length);
- Contract.Assert(newLower <= nodes.Length);
- Contract.Assert(newUpper >= 0);
- Contract.Assert(newLower >= 0);
- Contract.Assert(newUpper >= prevUpper);
- Contract.Assert(newLower >= prevLower);
- Contract.Assert(newUpper == prevUpper ^ newLower == prevLower);
+ Debug.Assert(newUpper >= newLower);
+ Debug.Assert(newUpper <= nodes.Length);
+ Debug.Assert(newLower <= nodes.Length);
+ Debug.Assert(newUpper >= 0);
+ Debug.Assert(newLower >= 0);
+ Debug.Assert(newUpper >= prevUpper);
+ Debug.Assert(newLower >= prevLower);
+ Debug.Assert(newUpper == prevUpper ^ newLower == prevLower);
int oldIndexes = (prevUpper << 16) | (prevLower & SixteenBits);
int newIndexes = (newUpper << 16) | (newLower & SixteenBits);
@@ -463,7 +460,7 @@ namespace System.Threading
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public QueueSegment()
{
- Contract.Assert(QueueSegmentLength <= SixteenBits);
+ Debug.Assert(QueueSegmentLength <= SixteenBits);
nodes = new IThreadPoolWorkItem[QueueSegmentLength];
}
@@ -486,7 +483,7 @@ namespace System.Threading
// with a busy-wait loop, waiting for the element to become non-null. This implies
// that we can never store null nodes in this data structure.
//
- Contract.Assert(null != node);
+ Debug.Assert(null != node);
int upper, lower;
GetIndexes(out upper, out lower);
@@ -498,7 +495,7 @@ namespace System.Threading
if (CompareExchangeIndexes(ref upper, upper + 1, ref lower, lower))
{
- Contract.Assert(Volatile.Read(ref nodes[upper]) == null);
+ Debug.Assert(Volatile.Read(ref nodes[upper]) == null);
Volatile.Write(ref nodes[upper], node);
return true;
}
@@ -546,7 +543,7 @@ namespace System.Threading
internal volatile QueueSegment queueTail;
internal bool loggingEnabled;
- internal static SparseArray<WorkStealingQueue> allThreadQueues = new SparseArray<WorkStealingQueue>(16);
+ internal static readonly SparseArray<WorkStealingQueue> allThreadQueues = new SparseArray<WorkStealingQueue>(16);
private volatile int numOutstandingThreadRequests = 0;
@@ -556,7 +553,6 @@ namespace System.Threading
loggingEnabled = FrameworkEventSource.Log.IsEnabled(EventLevel.Verbose, FrameworkEventSource.Keywords.ThreadPool|FrameworkEventSource.Keywords.ThreadTransfer);
}
- [SecurityCritical]
public ThreadPoolWorkQueueThreadLocals EnsureCurrentThreadHasQueue()
{
if (null == ThreadPoolWorkQueueThreadLocals.threadLocals)
@@ -564,7 +560,6 @@ namespace System.Threading
return ThreadPoolWorkQueueThreadLocals.threadLocals;
}
- [SecurityCritical]
internal void EnsureThreadRequested()
{
//
@@ -585,7 +580,6 @@ namespace System.Threading
}
}
- [SecurityCritical]
internal void MarkThreadRequestSatisfied()
{
//
@@ -606,7 +600,6 @@ namespace System.Threading
}
}
- [SecurityCritical]
public void Enqueue(IThreadPoolWorkItem callback, bool forceGlobal)
{
ThreadPoolWorkQueueThreadLocals tl = null;
@@ -639,7 +632,6 @@ namespace System.Threading
EnsureThreadRequested();
}
- [SecurityCritical]
internal bool LocalFindAndPop(IThreadPoolWorkItem callback)
{
ThreadPoolWorkQueueThreadLocals tl = ThreadPoolWorkQueueThreadLocals.threadLocals;
@@ -649,7 +641,6 @@ namespace System.Threading
return tl.workStealingQueue.LocalFindAndPop(callback);
}
- [SecurityCritical]
public void Dequeue(ThreadPoolWorkQueueThreadLocals tl, out IThreadPoolWorkItem callback, out bool missedSteal)
{
callback = null;
@@ -657,7 +648,7 @@ namespace System.Threading
WorkStealingQueue wsq = tl.workStealingQueue;
if (wsq.LocalPop(out callback))
- Contract.Assert(null != callback);
+ Debug.Assert(null != callback);
if (null == callback)
{
@@ -666,7 +657,7 @@ namespace System.Threading
{
if (tail.TryDequeue(out callback))
{
- Contract.Assert(null != callback);
+ Debug.Assert(null != callback);
break;
}
@@ -696,7 +687,7 @@ namespace System.Threading
otherQueue != wsq &&
otherQueue.TrySteal(out callback, ref missedSteal))
{
- Contract.Assert(null != callback);
+ Debug.Assert(null != callback);
break;
}
c--;
@@ -704,12 +695,11 @@ namespace System.Threading
}
}
- [SecurityCritical]
static internal bool Dispatch()
{
var workQueue = ThreadPoolGlobals.workQueue;
//
- // The clock is ticking! We have ThreadPoolGlobals.tpQuantum milliseconds to get some work done, and then
+ // The clock is ticking! We have ThreadPoolGlobals.TP_QUANTUM milliseconds to get some work done, and then
// we need to return to the VM.
//
int quantumStartTime = Environment.TickCount;
@@ -743,7 +733,7 @@ namespace System.Threading
//
// Loop until our quantum expires.
//
- while ((Environment.TickCount - quantumStartTime) < ThreadPoolGlobals.tpQuantum)
+ while ((Environment.TickCount - quantumStartTime) < ThreadPoolGlobals.TP_QUANTUM)
{
//
// Dequeue and EnsureThreadRequested must be protected from ThreadAbortException.
@@ -855,7 +845,7 @@ namespace System.Threading
}
// we can never reach this point, but the C# compiler doesn't know that, because it doesn't know the ThreadAbortException will be reraised above.
- Contract.Assert(false);
+ Debug.Assert(false);
return true;
}
}
@@ -864,7 +854,6 @@ namespace System.Threading
internal sealed class ThreadPoolWorkQueueThreadLocals
{
[ThreadStatic]
- [SecurityCritical]
public static ThreadPoolWorkQueueThreadLocals threadLocals;
public readonly ThreadPoolWorkQueue workQueue;
@@ -878,7 +867,6 @@ namespace System.Threading
ThreadPoolWorkQueue.allThreadQueues.Add(workStealingQueue);
}
- [SecurityCritical]
private void CleanUp()
{
if (null != workStealingQueue)
@@ -895,7 +883,7 @@ namespace System.Threading
IThreadPoolWorkItem cb = null;
if (workStealingQueue.LocalPop(out cb))
{
- Contract.Assert(null != cb);
+ Debug.Assert(null != cb);
workQueue.Enqueue(cb, true);
}
else
@@ -910,7 +898,6 @@ namespace System.Threading
}
}
- [SecuritySafeCritical]
~ThreadPoolWorkQueueThreadLocals()
{
// Since the purpose of calling CleanUp is to transfer any pending workitems into the global
@@ -927,7 +914,6 @@ namespace System.Threading
{
private static IntPtr InvalidHandle
{
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
return Win32Native.INVALID_HANDLE_VALUE;
@@ -938,9 +924,6 @@ namespace System.Threading
private bool bReleaseNeeded = false;
private volatile int m_lock = 0;
- #if FEATURE_CORECLR
- [System.Security.SecuritySafeCritical] // auto-generated
- #endif
internal RegisteredWaitHandleSafe()
{
registeredWaitHandle = InvalidHandle;
@@ -956,7 +939,6 @@ namespace System.Threading
registeredWaitHandle = handle;
}
- [System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal void SetWaitObject(WaitHandle waitObject)
{
@@ -975,7 +957,6 @@ namespace System.Threading
}
}
- [System.Security.SecurityCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
internal bool Unregister(
WaitHandle waitObject // object to be notified when all callbacks to delegates have completed
@@ -1033,7 +1014,6 @@ namespace System.Threading
return (registeredWaitHandle != InvalidHandle && registeredWaitHandle != IntPtr.Zero);
}
- [System.Security.SecuritySafeCritical] // auto-generated
~RegisteredWaitHandleSafe()
{
// if the app has already unregistered the wait, there is nothing to cleanup
@@ -1084,21 +1064,15 @@ namespace System.Threading
}
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void WaitHandleCleanupNative(IntPtr handle);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool UnregisterWaitNative(IntPtr handle, SafeHandle waitObject);
}
[System.Runtime.InteropServices.ComVisible(true)]
-#if FEATURE_REMOTING
public sealed class RegisteredWaitHandle : MarshalByRefObject {
-#else // FEATURE_REMOTING
- public sealed class RegisteredWaitHandle {
-#endif // FEATURE_REMOTING
private RegisteredWaitHandleSafe internalRegisteredWait;
internal RegisteredWaitHandle()
@@ -1111,14 +1085,12 @@ namespace System.Threading
internalRegisteredWait.SetHandle(handle);
}
- [System.Security.SecurityCritical] // auto-generated
internal void SetWaitObject(WaitHandle waitObject)
{
internalRegisteredWait.SetWaitObject(waitObject);
}
-[System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.InteropServices.ComVisible(true)]
// This is the only public method on this class
public bool Unregister(
@@ -1143,7 +1115,6 @@ namespace System.Threading
//
internal static class _ThreadPoolWaitCallback
{
- [System.Security.SecurityCritical]
static internal bool PerformWaitCallback()
{
return ThreadPoolWorkQueue.Dispatch();
@@ -1161,15 +1132,12 @@ namespace System.Threading
//
internal interface IThreadPoolWorkItem
{
- [SecurityCritical]
void ExecuteWorkItem();
- [SecurityCritical]
void MarkAborted(ThreadAbortException tae);
}
internal sealed class QueueUserWorkItemCallback : IThreadPoolWorkItem
{
- [System.Security.SecuritySafeCritical]
static QueueUserWorkItemCallback() {}
private WaitCallback callback;
@@ -1181,7 +1149,7 @@ namespace System.Threading
~QueueUserWorkItemCallback()
{
- Contract.Assert(
+ Debug.Assert(
executed != 0 || Environment.HasShutdownStarted || AppDomain.CurrentDomain.IsFinalizingForUnload(),
"A QueueUserWorkItemCallback was never called!");
}
@@ -1189,13 +1157,12 @@ namespace System.Threading
void MarkExecuted(bool aborted)
{
GC.SuppressFinalize(this);
- Contract.Assert(
+ Debug.Assert(
0 == Interlocked.Exchange(ref executed, 1) || aborted,
"A QueueUserWorkItemCallback was called twice!");
}
#endif
- [SecurityCritical]
internal QueueUserWorkItemCallback(WaitCallback waitCallback, Object stateObj, ExecutionContext ec)
{
callback = waitCallback;
@@ -1203,7 +1170,6 @@ namespace System.Threading
context = ec;
}
- [SecurityCritical]
void IThreadPoolWorkItem.ExecuteWorkItem()
{
#if DEBUG
@@ -1222,7 +1188,6 @@ namespace System.Threading
}
}
- [SecurityCritical]
void IThreadPoolWorkItem.MarkAborted(ThreadAbortException tae)
{
#if DEBUG
@@ -1232,22 +1197,19 @@ namespace System.Threading
#endif
}
- [System.Security.SecurityCritical]
static internal ContextCallback ccb = new ContextCallback(WaitCallback_Context);
- [System.Security.SecurityCritical]
static private void WaitCallback_Context(Object state)
{
QueueUserWorkItemCallback obj = (QueueUserWorkItemCallback)state;
WaitCallback wc = obj.callback as WaitCallback;
- Contract.Assert(null != wc);
+ Debug.Assert(null != wc);
wc(obj.state);
}
}
internal sealed class QueueUserWorkItemCallbackDefaultContext : IThreadPoolWorkItem
{
- [System.Security.SecuritySafeCritical]
static QueueUserWorkItemCallbackDefaultContext() { }
private WaitCallback callback;
@@ -1258,7 +1220,7 @@ namespace System.Threading
~QueueUserWorkItemCallbackDefaultContext()
{
- Contract.Assert(
+ Debug.Assert(
executed != 0 || Environment.HasShutdownStarted || AppDomain.CurrentDomain.IsFinalizingForUnload(),
"A QueueUserWorkItemCallbackDefaultContext was never called!");
}
@@ -1266,20 +1228,18 @@ namespace System.Threading
void MarkExecuted(bool aborted)
{
GC.SuppressFinalize(this);
- Contract.Assert(
+ Debug.Assert(
0 == Interlocked.Exchange(ref executed, 1) || aborted,
"A QueueUserWorkItemCallbackDefaultContext was called twice!");
}
#endif
- [SecurityCritical]
internal QueueUserWorkItemCallbackDefaultContext(WaitCallback waitCallback, Object stateObj)
{
callback = waitCallback;
state = stateObj;
}
- [SecurityCritical]
void IThreadPoolWorkItem.ExecuteWorkItem()
{
#if DEBUG
@@ -1288,7 +1248,6 @@ namespace System.Threading
ExecutionContext.Run(ExecutionContext.PreAllocatedDefault, ccb, this, true);
}
- [SecurityCritical]
void IThreadPoolWorkItem.MarkAborted(ThreadAbortException tae)
{
#if DEBUG
@@ -1298,15 +1257,13 @@ namespace System.Threading
#endif
}
- [System.Security.SecurityCritical]
static internal ContextCallback ccb = new ContextCallback(WaitCallback_Context);
- [System.Security.SecurityCritical]
static private void WaitCallback_Context(Object state)
{
QueueUserWorkItemCallbackDefaultContext obj = (QueueUserWorkItemCallbackDefaultContext)state;
WaitCallback wc = obj.callback as WaitCallback;
- Contract.Assert(null != wc);
+ Debug.Assert(null != wc);
obj.callback = null;
wc(obj.state);
}
@@ -1314,18 +1271,14 @@ namespace System.Threading
internal class _ThreadPoolWaitOrTimerCallback
{
- [System.Security.SecuritySafeCritical]
static _ThreadPoolWaitOrTimerCallback() {}
WaitOrTimerCallback _waitOrTimerCallback;
ExecutionContext _executionContext;
Object _state;
- [System.Security.SecurityCritical]
static private ContextCallback _ccbt = new ContextCallback(WaitOrTimerCallback_Context_t);
- [System.Security.SecurityCritical]
static private ContextCallback _ccbf = new ContextCallback(WaitOrTimerCallback_Context_f);
- [System.Security.SecurityCritical] // auto-generated
internal _ThreadPoolWaitOrTimerCallback(WaitOrTimerCallback waitOrTimerCallback, Object state, bool compressStack, ref StackCrawlMark stackMark)
{
_waitOrTimerCallback = waitOrTimerCallback;
@@ -1340,13 +1293,11 @@ namespace System.Threading
}
}
- [System.Security.SecurityCritical]
static private void WaitOrTimerCallback_Context_t(Object state)
{
WaitOrTimerCallback_Context(state, true);
}
- [System.Security.SecurityCritical]
static private void WaitOrTimerCallback_Context_f(Object state)
{
WaitOrTimerCallback_Context(state, false);
@@ -1359,11 +1310,10 @@ namespace System.Threading
}
// call back helper
- [System.Security.SecurityCritical] // auto-generated
static internal void PerformWaitOrTimerCallback(Object state, bool timedOut)
{
_ThreadPoolWaitOrTimerCallback helper = (_ThreadPoolWaitOrTimerCallback)state;
- Contract.Assert(helper != null, "Null state passed to PerformWaitOrTimerCallback!");
+ 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)
{
@@ -1384,7 +1334,6 @@ namespace System.Threading
}
- [System.Security.SecurityCritical]
[CLSCompliant(false)]
[System.Runtime.InteropServices.ComVisible(true)]
unsafe public delegate void IOCompletionCallback(uint errorCode, // Error code
@@ -1392,55 +1341,34 @@ namespace System.Threading
NativeOverlapped* pOVERLAP // ptr to OVERLAP structure
);
- [HostProtection(Synchronization=true, ExternalThreading=true)]
public static class ThreadPool
{
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #else
- [System.Security.SecuritySafeCritical]
- #endif
-#pragma warning disable 618
- [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)]
-#pragma warning restore 618
public static bool SetMaxThreads(int workerThreads, int completionPortThreads)
{
return SetMaxThreadsNative(workerThreads, completionPortThreads);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static void GetMaxThreads(out int workerThreads, out int completionPortThreads)
{
GetMaxThreadsNative(out workerThreads, out completionPortThreads);
}
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #else
- [System.Security.SecuritySafeCritical]
- #endif
-#pragma warning disable 618
- [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)]
-#pragma warning restore 618
public static bool SetMinThreads(int workerThreads, int completionPortThreads)
{
return SetMinThreadsNative(workerThreads, completionPortThreads);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static void GetMinThreads(out int workerThreads, out int completionPortThreads)
{
GetMinThreadsNative(out workerThreads, out completionPortThreads);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static void GetAvailableThreads(out int workerThreads, out int completionPortThreads)
{
GetAvailableThreadsNative(out workerThreads, out completionPortThreads);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static RegisteredWaitHandle RegisterWaitForSingleObject( // throws RegisterWaitException
@@ -1455,7 +1383,6 @@ namespace System.Threading
return RegisterWaitForSingleObject(waitObject,callBack,state,millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,true);
}
- [System.Security.SecurityCritical] // auto-generated_required
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( // throws RegisterWaitException
@@ -1471,7 +1398,6 @@ namespace System.Threading
}
- [System.Security.SecurityCritical] // auto-generated
private static RegisteredWaitHandle RegisterWaitForSingleObject( // throws RegisterWaitException
WaitHandle waitObject,
WaitOrTimerCallback callBack,
@@ -1482,12 +1408,6 @@ namespace System.Threading
bool compressStack
)
{
-#if FEATURE_REMOTING
- if (RemotingServices.IsTransparentProxy(waitObject))
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_WaitOnTransparentProxy"));
- Contract.EndContractBlock();
-#endif
-
RegisteredWaitHandle registeredWaitHandle = new RegisteredWaitHandle();
if (callBack != null)
@@ -1508,13 +1428,12 @@ namespace System.Threading
}
else
{
- throw new ArgumentNullException("WaitOrTimerCallback");
+ throw new ArgumentNullException(nameof(WaitOrTimerCallback));
}
return registeredWaitHandle;
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static RegisteredWaitHandle RegisterWaitForSingleObject( // throws RegisterWaitException
WaitHandle waitObject,
@@ -1525,13 +1444,12 @@ namespace System.Threading
)
{
if (millisecondsTimeOutInterval < -1)
- throw new ArgumentOutOfRangeException("millisecondsTimeOutInterval", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(millisecondsTimeOutInterval), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,true);
}
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( // throws RegisterWaitException
WaitHandle waitObject,
@@ -1542,13 +1460,12 @@ namespace System.Threading
)
{
if (millisecondsTimeOutInterval < -1)
- throw new ArgumentOutOfRangeException("millisecondsTimeOutInterval", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(millisecondsTimeOutInterval), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,false);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static RegisteredWaitHandle RegisterWaitForSingleObject( // throws RegisterWaitException
WaitHandle waitObject,
@@ -1559,13 +1476,12 @@ namespace System.Threading
)
{
if (millisecondsTimeOutInterval < -1)
- throw new ArgumentOutOfRangeException("millisecondsTimeOutInterval", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(millisecondsTimeOutInterval), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,true);
}
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( // throws RegisterWaitException
WaitHandle waitObject,
@@ -1576,13 +1492,12 @@ namespace System.Threading
)
{
if (millisecondsTimeOutInterval < -1)
- throw new ArgumentOutOfRangeException("millisecondsTimeOutInterval", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(millisecondsTimeOutInterval), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,false);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static RegisteredWaitHandle RegisterWaitForSingleObject(
WaitHandle waitObject,
@@ -1594,14 +1509,13 @@ namespace System.Threading
{
long tm = (long)timeout.TotalMilliseconds;
if (tm < -1)
- throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
if (tm > (long) Int32.MaxValue)
- throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_LessEqualToIntegerMaxVal"));
+ throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_LessEqualToIntegerMaxVal"));
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)tm,executeOnlyOnce,ref stackMark,true);
}
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject(
WaitHandle waitObject,
@@ -1613,14 +1527,13 @@ namespace System.Threading
{
long tm = (long)timeout.TotalMilliseconds;
if (tm < -1)
- throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
if (tm > (long) Int32.MaxValue)
- throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_LessEqualToIntegerMaxVal"));
+ throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_LessEqualToIntegerMaxVal"));
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)tm,executeOnlyOnce,ref stackMark,false);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static bool QueueUserWorkItem(
WaitCallback callBack, // NOTE: we do not expose options that allow the callback to be queued as an APC
@@ -1631,7 +1544,6 @@ namespace System.Threading
return QueueUserWorkItemHelper(callBack,state,ref stackMark,true);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static bool QueueUserWorkItem(
WaitCallback callBack // NOTE: we do not expose options that allow the callback to be queued as an APC
@@ -1641,7 +1553,6 @@ namespace System.Threading
return QueueUserWorkItemHelper(callBack,null,ref stackMark,true);
}
- [System.Security.SecurityCritical] // auto-generated_required
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public static bool UnsafeQueueUserWorkItem(
WaitCallback callBack, // NOTE: we do not expose options that allow the callback to be queued as an APC
@@ -1655,7 +1566,6 @@ namespace System.Threading
//ThreadPool has per-appdomain managed queue of work-items. The VM is
//responsible for just scheduling threads into appdomains. After that
//work-items are dispatched from the managed queue.
- [System.Security.SecurityCritical] // auto-generated
private static bool QueueUserWorkItemHelper(WaitCallback callBack, Object state, ref StackCrawlMark stackMark, bool compressStack )
{
bool success = true;
@@ -1690,15 +1600,14 @@ namespace System.Threading
}
else
{
- throw new ArgumentNullException("WaitCallback");
+ throw new ArgumentNullException(nameof(WaitCallback));
}
return success;
}
- [SecurityCritical]
internal static void UnsafeQueueCustomWorkItem(IThreadPoolWorkItem workItem, bool forceGlobal)
{
- Contract.Assert(null != workItem);
+ Debug.Assert(null != workItem);
EnsureVMInitialized();
//
@@ -1712,17 +1621,15 @@ namespace System.Threading
}
// This method tries to take the target callback out of the current thread's queue.
- [SecurityCritical]
internal static bool TryPopCustomWorkItem(IThreadPoolWorkItem workItem)
{
- Contract.Assert(null != workItem);
+ Debug.Assert(null != workItem);
if (!ThreadPoolGlobals.vmTpInitialized)
return false; //Not initialized, so there's no way this workitem was ever queued.
return ThreadPoolGlobals.workQueue.LocalFindAndPop(workItem);
}
// Get all workitems. Called by TaskScheduler in its debugger hooks.
- [SecurityCritical]
internal static IEnumerable<IThreadPoolWorkItem> GetQueuedWorkItems()
{
return EnumerateQueuedWorkItems(ThreadPoolWorkQueue.allThreadQueues.Current, ThreadPoolGlobals.workQueue.queueTail);
@@ -1766,13 +1673,11 @@ namespace System.Threading
}
}
- [SecurityCritical]
internal static IEnumerable<IThreadPoolWorkItem> GetLocallyQueuedWorkItems()
{
return EnumerateQueuedWorkItems(new ThreadPoolWorkQueue.WorkStealingQueue[] { ThreadPoolWorkQueueThreadLocals.threadLocals.workStealingQueue }, null);
}
- [SecurityCritical]
internal static IEnumerable<IThreadPoolWorkItem> GetGloballyQueuedWorkItems()
{
return EnumerateQueuedWorkItems(null, ThreadPoolGlobals.workQueue.queueTail);
@@ -1800,41 +1705,34 @@ namespace System.Threading
// This is the method the debugger will actually call, if it ends up calling
// into ThreadPool directly. Tests can use this to simulate a debugger, as well.
- [SecurityCritical]
internal static object[] GetQueuedWorkItemsForDebugger()
{
return ToObjectArray(GetQueuedWorkItems());
}
- [SecurityCritical]
internal static object[] GetGloballyQueuedWorkItemsForDebugger()
{
return ToObjectArray(GetGloballyQueuedWorkItems());
}
- [SecurityCritical]
internal static object[] GetLocallyQueuedWorkItemsForDebugger()
{
return ToObjectArray(GetLocallyQueuedWorkItems());
}
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal static extern bool RequestWorkerThread();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
unsafe private static extern bool PostQueuedCompletionStatus(NativeOverlapped* overlapped);
- [System.Security.SecurityCritical] // auto-generated_required
[CLSCompliant(false)]
unsafe public static bool UnsafeQueueNativeOverlapped(NativeOverlapped* overlapped)
{
return PostQueuedCompletionStatus(overlapped);
}
- [SecurityCritical]
private static void EnsureVMInitialized()
{
if (!ThreadPoolGlobals.vmTpInitialized)
@@ -1846,35 +1744,27 @@ namespace System.Threading
// Native methods:
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool SetMinThreadsNative(int workerThreads, int completionPortThreads);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool SetMaxThreadsNative(int workerThreads, int completionPortThreads);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void GetMinThreadsNative(out int workerThreads, out int completionPortThreads);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void GetMaxThreadsNative(out int workerThreads, out int completionPortThreads);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void GetAvailableThreadsNative(out int workerThreads, out int completionPortThreads);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool NotifyWorkItemComplete();
- [System.Security.SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void ReportThreadStatus(bool isWorking);
- [System.Security.SecuritySafeCritical]
internal static void NotifyWorkItemProgress()
{
if (!ThreadPoolGlobals.vmTpInitialized)
@@ -1882,20 +1772,16 @@ namespace System.Threading
NotifyWorkItemProgressNative();
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void NotifyWorkItemProgressNative();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool IsThreadPoolHosted();
- [System.Security.SecurityCritical] // auto-generated
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void InitializeVMTp(ref bool enableWorkerTracking);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern IntPtr RegisterWaitForSingleObjectNative(
WaitHandle waitHandle,
@@ -1907,30 +1793,19 @@ namespace System.Threading
bool compressStack
);
-#if !FEATURE_CORECLR
- [System.Security.SecuritySafeCritical] // auto-generated
+
[Obsolete("ThreadPool.BindHandle(IntPtr) has been deprecated. Please use ThreadPool.BindHandle(SafeHandle) instead.", false)]
- [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public static bool BindHandle(
IntPtr osHandle
)
{
return BindIOCompletionCallbackNative(osHandle);
}
-#endif
- #if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
- #else
- [System.Security.SecuritySafeCritical]
- #endif
-#pragma warning disable 618
- [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
-#pragma warning restore 618
public static bool BindHandle(SafeHandle osHandle)
{
if (osHandle == null)
- throw new ArgumentNullException("osHandle");
+ throw new ArgumentNullException(nameof(osHandle));
bool ret = false;
bool mustReleaseSafeHandle = false;
@@ -1946,7 +1821,6 @@ namespace System.Threading
return ret;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
private static extern bool BindIOCompletionCallbackNative(IntPtr fileHandle);
diff --git a/src/mscorlib/src/System/Threading/Timer.cs b/src/mscorlib/src/System/Threading/Timer.cs
index cb08c6e033..5bfefccad2 100644
--- a/src/mscorlib/src/System/Threading/Timer.cs
+++ b/src/mscorlib/src/System/Threading/Timer.cs
@@ -14,6 +14,7 @@ namespace System.Threading
using System.Runtime.InteropServices;
using System.Runtime.ConstrainedExecution;
using System.Runtime.Versioning;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Diagnostics.Tracing;
using Microsoft.Win32.SafeHandles;
@@ -76,7 +77,6 @@ namespace System.Threading
//
private static int TickCount
{
- [SecuritySafeCritical]
get
{
#if !FEATURE_PAL
@@ -102,7 +102,6 @@ namespace System.Threading
//
// We use a SafeHandle to ensure that the native timer is destroyed when the AppDomain is unloaded.
//
- [SecurityCritical]
class AppDomainTimerSafeHandle : SafeHandleZeroOrMinusOneIsInvalid
{
public AppDomainTimerSafeHandle()
@@ -110,7 +109,6 @@ namespace System.Threading
{
}
- [SecurityCritical]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
protected override bool ReleaseHandle()
{
@@ -118,14 +116,12 @@ namespace System.Threading
}
}
- [SecurityCritical]
AppDomainTimerSafeHandle m_appDomainTimer;
bool m_isAppDomainTimerScheduled;
int m_currentAppDomainTimerStartTicks;
uint m_currentAppDomainTimerDuration;
- [SecuritySafeCritical]
private bool EnsureAppDomainTimerFiresBy(uint requestedDuration)
{
//
@@ -154,14 +150,14 @@ namespace System.Threading
// A later update during resume will re-schedule
if(m_pauseTicks != 0)
{
- Contract.Assert(!m_isAppDomainTimerScheduled);
- Contract.Assert(m_appDomainTimer == null);
+ Debug.Assert(!m_isAppDomainTimerScheduled);
+ Debug.Assert(m_appDomainTimer == null);
return true;
}
if (m_appDomainTimer == null || m_appDomainTimer.IsInvalid)
{
- Contract.Assert(!m_isAppDomainTimerScheduled);
+ Debug.Assert(!m_isAppDomainTimerScheduled);
m_appDomainTimer = CreateAppDomainTimer(actualDuration);
if (!m_appDomainTimer.IsInvalid)
@@ -195,23 +191,19 @@ namespace System.Threading
//
// The VM calls this when the native timer fires.
//
- [SecuritySafeCritical]
internal static void AppDomainTimerCallback()
{
Instance.FireNextTimers();
}
- [System.Security.SecurityCritical]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
static extern AppDomainTimerSafeHandle CreateAppDomainTimer(uint dueTime);
- [System.Security.SecurityCritical]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
static extern bool ChangeAppDomainTimer(AppDomainTimerSafeHandle handle, uint dueTime);
- [System.Security.SecurityCritical]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
@@ -229,7 +221,6 @@ namespace System.Threading
volatile int m_pauseTicks = 0; // Time when Pause was called
- [SecurityCritical]
internal void Pause()
{
lock(this)
@@ -245,7 +236,6 @@ namespace System.Threading
}
}
- [SecurityCritical]
internal void Resume()
{
//
@@ -269,8 +259,8 @@ namespace System.Threading
TimerQueueTimer timer = m_timers;
while (timer != null)
{
- Contract.Assert(timer.m_dueTime != Timeout.UnsignedInfinite);
- Contract.Assert(resumedTicks >= timer.m_startTicks);
+ Debug.Assert(timer.m_dueTime != Timeout.UnsignedInfinite);
+ Debug.Assert(resumedTicks >= timer.m_startTicks);
uint elapsed; // How much of the timer dueTime has already elapsed
@@ -343,7 +333,7 @@ namespace System.Threading
TimerQueueTimer timer = m_timers;
while (timer != null)
{
- Contract.Assert(timer.m_dueTime != Timeout.UnsignedInfinite);
+ Debug.Assert(timer.m_dueTime != Timeout.UnsignedInfinite);
uint elapsed = (uint)(nowTicks - timer.m_startTicks);
if (elapsed >= timer.m_dueTime)
@@ -413,7 +403,6 @@ namespace System.Threading
timerToFireOnThisThread.Fire();
}
- [SecuritySafeCritical]
private static void QueueTimerCompletion(TimerQueueTimer timer)
{
WaitCallback callback = s_fireQueuedTimerCompletion;
@@ -523,7 +512,6 @@ namespace System.Threading
volatile WaitHandle m_notifyWhenNoCallbacksRunning;
- [SecurityCritical]
internal TimerQueueTimer(TimerCallback timerCallback, object state, uint dueTime, uint period, ref StackCrawlMark stackMark)
{
m_timerCallback = timerCallback;
@@ -673,13 +661,11 @@ namespace System.Threading
SignalNoCallbacksRunning();
}
- [SecuritySafeCritical]
internal void SignalNoCallbacksRunning()
{
Win32Native.SetEvent(m_notifyWhenNoCallbacksRunning.SafeWaitHandle);
}
- [SecuritySafeCritical]
internal void CallCallback()
{
if (FrameworkEventSource.IsInitialized && FrameworkEventSource.Log.IsEnabled(EventLevel.Informational, FrameworkEventSource.Keywords.ThreadTransfer))
@@ -708,10 +694,8 @@ namespace System.Threading
}
}
- [SecurityCritical]
private static ContextCallback s_callCallbackInContext;
- [SecurityCritical]
private static void CallCallbackInContext(object state)
{
TimerQueueTimer t = (TimerQueueTimer)state;
@@ -772,19 +756,13 @@ namespace System.Threading
}
- [HostProtection(Synchronization=true, ExternalThreading=true)]
[System.Runtime.InteropServices.ComVisible(true)]
-#if FEATURE_REMOTING
public sealed class Timer : MarshalByRefObject, IDisposable
-#else // FEATURE_REMOTING
- public sealed class Timer : IDisposable
-#endif // FEATURE_REMOTING
{
private const UInt32 MAX_SUPPORTED_TIMEOUT = (uint)0xfffffffe;
private TimerHolder m_timer;
- [SecuritySafeCritical]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public Timer(TimerCallback callback,
Object state,
@@ -792,16 +770,15 @@ namespace System.Threading
int period)
{
if (dueTime < -1)
- throw new ArgumentOutOfRangeException("dueTime", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(dueTime), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
if (period < -1 )
- throw new ArgumentOutOfRangeException("period", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(period), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
TimerSetup(callback,state,(UInt32)dueTime,(UInt32)period,ref stackMark);
}
- [SecuritySafeCritical]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public Timer(TimerCallback callback,
Object state,
@@ -810,22 +787,21 @@ namespace System.Threading
{
long dueTm = (long)dueTime.TotalMilliseconds;
if (dueTm < -1)
- throw new ArgumentOutOfRangeException("dueTm",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(dueTm),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
if (dueTm > MAX_SUPPORTED_TIMEOUT)
- throw new ArgumentOutOfRangeException("dueTm",Environment.GetResourceString("ArgumentOutOfRange_TimeoutTooLarge"));
+ throw new ArgumentOutOfRangeException(nameof(dueTm),Environment.GetResourceString("ArgumentOutOfRange_TimeoutTooLarge"));
long periodTm = (long)period.TotalMilliseconds;
if (periodTm < -1)
- throw new ArgumentOutOfRangeException("periodTm",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(periodTm),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
if (periodTm > MAX_SUPPORTED_TIMEOUT)
- throw new ArgumentOutOfRangeException("periodTm",Environment.GetResourceString("ArgumentOutOfRange_PeriodTooLarge"));
+ throw new ArgumentOutOfRangeException(nameof(periodTm),Environment.GetResourceString("ArgumentOutOfRange_PeriodTooLarge"));
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
TimerSetup(callback,state,(UInt32)dueTm,(UInt32)periodTm,ref stackMark);
}
[CLSCompliant(false)]
- [SecuritySafeCritical]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public Timer(TimerCallback callback,
Object state,
@@ -836,7 +812,6 @@ namespace System.Threading
TimerSetup(callback,state,dueTime,period,ref stackMark);
}
- [SecuritySafeCritical]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public Timer(TimerCallback callback,
Object state,
@@ -844,19 +819,18 @@ namespace System.Threading
long period)
{
if (dueTime < -1)
- throw new ArgumentOutOfRangeException("dueTime",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(dueTime),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
if (period < -1)
- throw new ArgumentOutOfRangeException("period",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(period),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
if (dueTime > MAX_SUPPORTED_TIMEOUT)
- throw new ArgumentOutOfRangeException("dueTime",Environment.GetResourceString("ArgumentOutOfRange_TimeoutTooLarge"));
+ throw new ArgumentOutOfRangeException(nameof(dueTime),Environment.GetResourceString("ArgumentOutOfRange_TimeoutTooLarge"));
if (period > MAX_SUPPORTED_TIMEOUT)
- throw new ArgumentOutOfRangeException("period",Environment.GetResourceString("ArgumentOutOfRange_PeriodTooLarge"));
+ throw new ArgumentOutOfRangeException(nameof(period),Environment.GetResourceString("ArgumentOutOfRange_PeriodTooLarge"));
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
TimerSetup(callback,state,(UInt32) dueTime, (UInt32) period,ref stackMark);
}
- [SecuritySafeCritical]
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public Timer(TimerCallback callback)
{
@@ -869,7 +843,6 @@ namespace System.Threading
TimerSetup(callback, this, (UInt32)dueTime, (UInt32)period, ref stackMark);
}
- [SecurityCritical]
private void TimerSetup(TimerCallback callback,
Object state,
UInt32 dueTime,
@@ -877,19 +850,17 @@ namespace System.Threading
ref StackCrawlMark stackMark)
{
if (callback == null)
- throw new ArgumentNullException("TimerCallback");
+ throw new ArgumentNullException(nameof(TimerCallback));
Contract.EndContractBlock();
m_timer = new TimerHolder(new TimerQueueTimer(callback, state, dueTime, period, ref stackMark));
}
- [SecurityCritical]
internal static void Pause()
{
TimerQueue.Instance.Pause();
}
- [SecurityCritical]
internal static void Resume()
{
TimerQueue.Instance.Resume();
@@ -898,9 +869,9 @@ namespace System.Threading
public bool Change(int dueTime, int period)
{
if (dueTime < -1 )
- throw new ArgumentOutOfRangeException("dueTime",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(dueTime),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
if (period < -1)
- throw new ArgumentOutOfRangeException("period",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(period),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
Contract.EndContractBlock();
return m_timer.m_timer.Change((UInt32)dueTime, (UInt32)period);
@@ -920,13 +891,13 @@ namespace System.Threading
public bool Change(long dueTime, long period)
{
if (dueTime < -1 )
- throw new ArgumentOutOfRangeException("dueTime", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(dueTime), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
if (period < -1)
- throw new ArgumentOutOfRangeException("period", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(period), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
if (dueTime > MAX_SUPPORTED_TIMEOUT)
- throw new ArgumentOutOfRangeException("dueTime", Environment.GetResourceString("ArgumentOutOfRange_TimeoutTooLarge"));
+ throw new ArgumentOutOfRangeException(nameof(dueTime), Environment.GetResourceString("ArgumentOutOfRange_TimeoutTooLarge"));
if (period > MAX_SUPPORTED_TIMEOUT)
- throw new ArgumentOutOfRangeException("period", Environment.GetResourceString("ArgumentOutOfRange_PeriodTooLarge"));
+ throw new ArgumentOutOfRangeException(nameof(period), Environment.GetResourceString("ArgumentOutOfRange_PeriodTooLarge"));
Contract.EndContractBlock();
return m_timer.m_timer.Change((UInt32)dueTime, (UInt32)period);
@@ -935,7 +906,7 @@ namespace System.Threading
public bool Dispose(WaitHandle notifyObject)
{
if (notifyObject==null)
- throw new ArgumentNullException("notifyObject");
+ throw new ArgumentNullException(nameof(notifyObject));
Contract.EndContractBlock();
return m_timer.Close(notifyObject);
diff --git a/src/mscorlib/src/System/Threading/Volatile.cs b/src/mscorlib/src/System/Threading/Volatile.cs
index af687fbae1..3894b435fa 100644
--- a/src/mscorlib/src/System/Threading/Volatile.cs
+++ b/src/mscorlib/src/System/Threading/Volatile.cs
@@ -129,7 +129,6 @@ namespace System.Threading
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[CLSCompliant(false)]
[System.Runtime.Versioning.NonVersionable]
- [SecuritySafeCritical] // to match 32-bit version
public static ulong Read(ref ulong location)
{
//
@@ -154,7 +153,6 @@ namespace System.Threading
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[CLSCompliant(false)]
- [SecuritySafeCritical] // contains unsafe code
public static ulong Read(ref ulong location)
{
unsafe
@@ -222,7 +220,6 @@ namespace System.Threading
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- [SecuritySafeCritical] //the intrinsic implementation of this method contains unverifiable code
[System.Runtime.Versioning.NonVersionable]
public static T Read<T>(ref T location) where T : class
{
@@ -332,7 +329,6 @@ namespace System.Threading
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[CLSCompliant(false)]
[System.Runtime.Versioning.NonVersionable]
- [SecuritySafeCritical] // to match 32-bit version
public static void Write(ref ulong location, ulong value)
{
//
@@ -356,7 +352,6 @@ namespace System.Threading
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[CLSCompliant(false)]
- [SecuritySafeCritical] // contains unsafe code
public static void Write(ref ulong location, ulong value)
{
//
@@ -427,7 +422,6 @@ namespace System.Threading
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- [SecuritySafeCritical] //the intrinsic implementation of this method contains unverifiable code
[System.Runtime.Versioning.NonVersionable]
public static void Write<T>(ref T location, T value) where T : class
{
diff --git a/src/mscorlib/src/System/Threading/WaitHandle.cs b/src/mscorlib/src/System/Threading/WaitHandle.cs
index 9980c822a6..7638c8b35b 100644
--- a/src/mscorlib/src/System/Threading/WaitHandle.cs
+++ b/src/mscorlib/src/System/Threading/WaitHandle.cs
@@ -27,12 +27,8 @@ namespace System.Threading
using System.Diagnostics.CodeAnalysis;
using Win32Native = Microsoft.Win32.Win32Native;
-[System.Runtime.InteropServices.ComVisible(true)]
-#if FEATURE_REMOTING
+ [System.Runtime.InteropServices.ComVisible(true)]
public abstract class WaitHandle : MarshalByRefObject, IDisposable {
-#else // FEATURE_REMOTING
- public abstract class WaitHandle : IDisposable {
-#endif // FEATURE_REMOTING
public const int WaitTimeout = 0x102;
private const int MAX_WAITHANDLES = 64;
@@ -41,12 +37,10 @@ namespace System.Threading
private IntPtr waitHandle; // !!! DO NOT MOVE THIS FIELD. (See defn of WAITHANDLEREF in object.h - has hardcoded access to this field.)
#pragma warning restore 414
- [System.Security.SecurityCritical] // auto-generated
internal volatile SafeWaitHandle safeWaitHandle;
internal bool hasThreadAffinity;
- [System.Security.SecuritySafeCritical] // auto-generated
private static IntPtr GetInvalidHandle()
{
return Win32Native.INVALID_HANDLE_VALUE;
@@ -70,7 +64,6 @@ namespace System.Threading
Init();
}
- [System.Security.SecuritySafeCritical] // auto-generated
private void Init()
{
safeWaitHandle = null;
@@ -82,13 +75,7 @@ namespace System.Threading
[Obsolete("Use the SafeWaitHandle property instead.")]
public virtual IntPtr Handle
{
- [System.Security.SecuritySafeCritical] // auto-generated
get { return safeWaitHandle == null ? InvalidHandle : safeWaitHandle.DangerousGetHandle();}
-
- [System.Security.SecurityCritical] // auto-generated_required
-#if !FEATURE_CORECLR
- [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
-#endif
set
{
if (value == InvalidHandle)
@@ -113,13 +100,8 @@ namespace System.Threading
}
}
-
public SafeWaitHandle SafeWaitHandle
{
- [System.Security.SecurityCritical] // auto-generated_required
-#if !FEATURE_CORECLR
- [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
-#endif
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
get
{
@@ -129,11 +111,7 @@ namespace System.Threading
}
return safeWaitHandle;
}
-
- [System.Security.SecurityCritical] // auto-generated_required
-#if !FEATURE_CORECLR
- [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
-#endif
+
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
set
{
@@ -168,7 +146,6 @@ namespace System.Threading
// FileStream, which will then call Sethandle, which requires a link time
// security check.). While security has fixed that problem, we still
// don't need to do a linktime check here.
- [System.Security.SecurityCritical] // auto-generated
internal void SetHandleInternal(SafeWaitHandle handle)
{
safeWaitHandle = handle;
@@ -179,7 +156,7 @@ namespace System.Threading
{
if (millisecondsTimeout < -1)
{
- throw new ArgumentOutOfRangeException("millisecondsTimeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
}
Contract.EndContractBlock();
return WaitOne((long)millisecondsTimeout,exitContext);
@@ -190,7 +167,7 @@ namespace System.Threading
long tm = (long)timeout.TotalMilliseconds;
if (-1 > tm || (long) Int32.MaxValue < tm)
{
- throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
}
return WaitOne(tm,exitContext);
}
@@ -211,14 +188,12 @@ namespace System.Threading
return WaitOne(timeout, false);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "Reviewed for thread-safety.")]
private bool WaitOne(long timeout, bool exitContext)
{
return InternalWaitOne(safeWaitHandle, timeout, hasThreadAffinity, exitContext);
}
- [System.Security.SecurityCritical] // auto-generated
internal static bool InternalWaitOne(SafeHandle waitableSafeHandle, long millisecondsTimeout, bool hasThreadAffinity, bool exitContext)
{
if (waitableSafeHandle == null)
@@ -238,7 +213,6 @@ namespace System.Threading
return (ret != WaitTimeout);
}
- [System.Security.SecurityCritical]
internal bool WaitOneWithoutFAS()
{
// version of waitone without fast application switch (FAS) support
@@ -258,7 +232,6 @@ namespace System.Threading
return (ret != WaitTimeout);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern int WaitOneNative(SafeHandle waitableSafeHandle, uint millisecondsTimeout, bool hasThreadAffinity, bool exitContext);
@@ -271,17 +244,15 @@ namespace System.Threading
** (if in a synchronized context) is exited before the wait and reacquired
========================================================================*/
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
private static extern int WaitMultiple(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext, bool WaitAll);
- [System.Security.SecuritySafeCritical] // auto-generated
public static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
{
if (waitHandles == null)
{
- throw new ArgumentNullException("waitHandles", Environment.GetResourceString("ArgumentNull_Waithandles"));
+ throw new ArgumentNullException(nameof(waitHandles), Environment.GetResourceString("ArgumentNull_Waithandles"));
}
if(waitHandles.Length == 0)
{
@@ -294,11 +265,7 @@ namespace System.Threading
// in CoreCLR, and ArgumentNullException in the desktop CLR. This is ugly, but so is breaking
// user code.
//
-#if FEATURE_CORECLR
throw new ArgumentException(Environment.GetResourceString("Argument_EmptyWaithandleArray"));
-#else
- throw new ArgumentNullException("waitHandles", Environment.GetResourceString("Argument_EmptyWaithandleArray"));
-#endif
}
if (waitHandles.Length > MAX_WAITHANDLES)
{
@@ -306,7 +273,7 @@ namespace System.Threading
}
if (-1 > millisecondsTimeout)
{
- throw new ArgumentOutOfRangeException("millisecondsTimeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
}
Contract.EndContractBlock();
WaitHandle[] internalWaitHandles = new WaitHandle[waitHandles.Length];
@@ -317,11 +284,6 @@ namespace System.Threading
if (waitHandle == null)
throw new ArgumentNullException("waitHandles[" + i + "]", Environment.GetResourceString("ArgumentNull_ArrayElement"));
-#if FEATURE_REMOTING
- if (RemotingServices.IsTransparentProxy(waitHandle))
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_WaitOnTransparentProxy"));
-#endif
-
internalWaitHandles[i] = waitHandle;
}
#if _DEBUG
@@ -354,7 +316,7 @@ namespace System.Threading
long tm = (long)timeout.TotalMilliseconds;
if (-1 > tm || (long) Int32.MaxValue < tm)
{
- throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
}
return WaitAll(waitHandles,(int)tm, exitContext);
}
@@ -388,13 +350,12 @@ namespace System.Threading
** (if in a synchronized context) is exited before the wait and reacquired
========================================================================*/
- [System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
{
if (waitHandles==null)
{
- throw new ArgumentNullException("waitHandles", Environment.GetResourceString("ArgumentNull_Waithandles"));
+ throw new ArgumentNullException(nameof(waitHandles), Environment.GetResourceString("ArgumentNull_Waithandles"));
}
if(waitHandles.Length == 0)
{
@@ -406,7 +367,7 @@ namespace System.Threading
}
if (-1 > millisecondsTimeout)
{
- throw new ArgumentOutOfRangeException("millisecondsTimeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
}
Contract.EndContractBlock();
WaitHandle[] internalWaitHandles = new WaitHandle[waitHandles.Length];
@@ -417,11 +378,6 @@ namespace System.Threading
if (waitHandle == null)
throw new ArgumentNullException("waitHandles[" + i + "]", Environment.GetResourceString("ArgumentNull_ArrayElement"));
-#if FEATURE_REMOTING
- if (RemotingServices.IsTransparentProxy(waitHandle))
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_WaitOnTransparentProxy"));
-#endif
-
internalWaitHandles[i] = waitHandle;
}
#if _DEBUG
@@ -459,7 +415,7 @@ namespace System.Threading
long tm = (long)timeout.TotalMilliseconds;
if (-1 > tm || (long) Int32.MaxValue < tm)
{
- throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
}
return WaitAny(waitHandles,(int)tm, exitContext);
}
@@ -491,7 +447,6 @@ namespace System.Threading
==
==================================================*/
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern int SignalAndWaitOne(SafeWaitHandle waitHandleToSignal,SafeWaitHandle waitHandleToWaitOn, int millisecondsTimeout,
bool hasThreadAffinity, bool exitContext);
@@ -519,13 +474,12 @@ namespace System.Threading
long tm = (long)timeout.TotalMilliseconds;
if (-1 > tm || (long) Int32.MaxValue < tm)
{
- throw new ArgumentOutOfRangeException("timeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
}
return SignalAndWait(toSignal,toWaitOn,(int)tm,exitContext);
#endif
}
- [System.Security.SecuritySafeCritical] // auto-generated
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "Reviewed for thread-safety.")]
public static bool SignalAndWait(
WaitHandle toSignal,
@@ -538,15 +492,15 @@ namespace System.Threading
#else
if(null == toSignal)
{
- throw new ArgumentNullException("toSignal");
+ throw new ArgumentNullException(nameof(toSignal));
}
if(null == toWaitOn)
{
- throw new ArgumentNullException("toWaitOn");
+ throw new ArgumentNullException(nameof(toWaitOn));
}
if (-1 > millisecondsTimeout)
{
- throw new ArgumentOutOfRangeException("millisecondsTimeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
}
Contract.EndContractBlock();
@@ -554,14 +508,6 @@ namespace System.Threading
int ret = SignalAndWaitOne(toSignal.safeWaitHandle,toWaitOn.safeWaitHandle,millisecondsTimeout,
toWaitOn.hasThreadAffinity,exitContext);
-#if !FEATURE_CORECLR
- if(WAIT_FAILED != ret && toSignal.hasThreadAffinity)
- {
- Thread.EndCriticalRegion();
- Thread.EndThreadAffinity();
- }
-#endif
-
if(WAIT_ABANDONED == ret)
{
ThrowAbandonedMutexException();
@@ -599,7 +545,6 @@ namespace System.Threading
GC.SuppressFinalize(this);
}
- [System.Security.SecuritySafeCritical] // auto-generated
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
index f873057992..68445a78d9 100644
--- a/src/mscorlib/src/System/Threading/WaitHandleCannotBeOpenedException.cs
+++ b/src/mscorlib/src/System/Threading/WaitHandleCannotBeOpenedException.cs
@@ -12,11 +12,7 @@ namespace System.Threading
[Serializable]
[ComVisibleAttribute(false)]
-#if FEATURE_CORECLR
- public class WaitHandleCannotBeOpenedException : Exception {
-#else
public class WaitHandleCannotBeOpenedException : ApplicationException {
-#endif // FEATURE_CORECLR
public WaitHandleCannotBeOpenedException() : base(Environment.GetResourceString("Threading.WaitHandleCannotBeOpenedException"))
{
SetErrorCode(__HResults.COR_E_WAITHANDLECANNOTBEOPENED);
diff --git a/src/mscorlib/src/System/Threading/WaitHandleExtensions.cs b/src/mscorlib/src/System/Threading/WaitHandleExtensions.cs
deleted file mode 100644
index 76c3feb649..0000000000
--- a/src/mscorlib/src/System/Threading/WaitHandleExtensions.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.
-
-//
-
-using Microsoft.Win32.SafeHandles;
-using System.Security;
-
-namespace System.Threading
-{
- public static class WaitHandleExtensions
- {
- /// <summary>
- /// Gets the native operating system handle.
- /// </summary>
- /// <param name="waitHandle">The <see cref="System.Threading.WaitHandle"/> to operate on.</param>
- /// <returns>A <see cref="System.Runtime.InteropServices.SafeHandle"/> representing the native operating system handle.</returns>
- [SecurityCritical]
- public static SafeWaitHandle GetSafeWaitHandle(this WaitHandle waitHandle)
- {
- if (waitHandle == null)
- {
- throw new ArgumentNullException("waitHandle");
- }
-
- return waitHandle.SafeWaitHandle;
- }
-
- /// <summary>
- /// Sets the native operating system handle
- /// </summary>
- /// <param name="waitHandle">The <see cref="System.Threading.WaitHandle"/> to operate on.</param>
- /// <param name="value">A <see cref="System.Runtime.InteropServices.SafeHandle"/> representing the native operating system handle.</param>
- [SecurityCritical]
- public static void SetSafeWaitHandle(this WaitHandle waitHandle, SafeWaitHandle value)
- {
- if (waitHandle == null)
- {
- throw new ArgumentNullException("waitHandle");
- }
-
- waitHandle.SafeWaitHandle = value;
- }
- }
-}
diff --git a/src/mscorlib/src/System/ThrowHelper.cs b/src/mscorlib/src/System/ThrowHelper.cs
index 3105d56f7c..a534dec818 100644
--- a/src/mscorlib/src/System/ThrowHelper.cs
+++ b/src/mscorlib/src/System/ThrowHelper.cs
@@ -10,7 +10,7 @@ namespace System {
// 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("key", Environment.GetResourceString("ArgumentNull_Key"));
+ // throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
// IL code:
// IL_0003: ldstr "key"
// IL_0008: ldstr "ArgumentNull_Key"
@@ -39,112 +39,206 @@ namespace System {
using Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
[Pure]
internal static class ThrowHelper {
+#if FEATURE_SPAN_OF_T
+ internal static void ThrowArrayTypeMismatchException() {
+ throw new ArrayTypeMismatchException();
+ }
+
+ internal static void ThrowInvalidTypeWithPointersNotSupported(Type targetType) {
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidTypeWithPointersNotSupported", targetType));
+ }
+
+ internal static void ThrowIndexOutOfRangeException() {
+ throw new IndexOutOfRangeException();
+ }
+
+ 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"));
+ }
+#endif
+
internal static void ThrowArgumentOutOfRange_IndexException() {
- throw new ArgumentOutOfRangeException(GetArgumentName(ExceptionArgument.index),
- Environment.GetResourceString(GetResourceName(ExceptionResource.ArgumentOutOfRange_Index)));
+ throw GetArgumentOutOfRangeException(ExceptionArgument.index,
+ ExceptionResource.ArgumentOutOfRange_Index);
}
internal static void ThrowIndexArgumentOutOfRange_NeedNonNegNumException() {
- throw new ArgumentOutOfRangeException(
- GetArgumentName(ExceptionArgument.index),
- Environment.GetResourceString(GetResourceName(ExceptionResource.ArgumentOutOfRange_NeedNonNegNum)));
+ throw GetArgumentOutOfRangeException(ExceptionArgument.index,
+ ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ }
+
+ internal static void ThrowLengthArgumentOutOfRange_ArgumentOutOfRange_NeedNonNegNum() {
+ throw GetArgumentOutOfRangeException(ExceptionArgument.length,
+ ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ }
+
+ internal static void ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index() {
+ throw GetArgumentOutOfRangeException(ExceptionArgument.startIndex,
+ ExceptionResource.ArgumentOutOfRange_Index);
+ }
+
+ internal static void ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count() {
+ throw GetArgumentOutOfRangeException(ExceptionArgument.count,
+ ExceptionResource.ArgumentOutOfRange_Count);
}
internal static void ThrowWrongKeyTypeArgumentException(object key, Type targetType) {
- throw new ArgumentException(Environment.GetResourceString("Arg_WrongType", key, targetType), "key");
+ throw GetWrongKeyTypeArgumentException(key, targetType);
}
internal static void ThrowWrongValueTypeArgumentException(object value, Type targetType) {
- throw new ArgumentException(Environment.GetResourceString("Arg_WrongType", value, targetType), "value");
+ throw GetWrongValueTypeArgumentException(value, targetType);
+ }
+
+ private static ArgumentException GetAddingDuplicateWithKeyArgumentException(object key) {
+ return new ArgumentException(Environment.GetResourceString("Argument_AddingDuplicateWithKey", key));
}
-#if FEATURE_CORECLR
internal static void ThrowAddingDuplicateWithKeyArgumentException(object key) {
- throw new ArgumentException(Environment.GetResourceString("Argument_AddingDuplicateWithKey", key));
+ throw GetAddingDuplicateWithKeyArgumentException(key);
}
-#endif
internal static void ThrowKeyNotFoundException() {
throw new System.Collections.Generic.KeyNotFoundException();
}
internal static void ThrowArgumentException(ExceptionResource resource) {
- throw new ArgumentException(Environment.GetResourceString(GetResourceName(resource)));
+ throw GetArgumentException(resource);
}
internal static void ThrowArgumentException(ExceptionResource resource, ExceptionArgument argument) {
- throw new ArgumentException(Environment.GetResourceString(GetResourceName(resource)), GetArgumentName(argument));
+ throw GetArgumentException(resource, argument);
}
internal static void ThrowArgumentNullException(ExceptionArgument argument) {
throw new ArgumentNullException(GetArgumentName(argument));
}
+ internal static void ThrowArgumentNullException(ExceptionResource resource) {
+ throw new ArgumentNullException(GetResourceString(resource));
+ }
+
internal static void ThrowArgumentOutOfRangeException(ExceptionArgument argument) {
throw new ArgumentOutOfRangeException(GetArgumentName(argument));
}
internal static void ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource) {
- throw new ArgumentOutOfRangeException(GetArgumentName(argument),
- Environment.GetResourceString(GetResourceName(resource)));
+ throw GetArgumentOutOfRangeException(argument, resource);
}
internal static void ThrowArgumentOutOfRangeException(ExceptionArgument argument, int paramNumber, ExceptionResource resource) {
- throw new ArgumentOutOfRangeException(GetArgumentName(argument) + "[" + paramNumber.ToString() + "]",
- Environment.GetResourceString(GetResourceName(resource)));
+ throw GetArgumentOutOfRangeException(argument, paramNumber, resource);
}
internal static void ThrowInvalidOperationException(ExceptionResource resource) {
- throw new InvalidOperationException(Environment.GetResourceString(GetResourceName(resource)));
+ throw GetInvalidOperationException(resource);
}
internal static void ThrowInvalidOperationException(ExceptionResource resource, Exception e) {
- throw new InvalidOperationException(Environment.GetResourceString(GetResourceName(resource)), e);
+ throw new InvalidOperationException(GetResourceString(resource), e);
}
internal static void ThrowSerializationException(ExceptionResource resource) {
- throw new SerializationException(Environment.GetResourceString(GetResourceName(resource)));
+ throw new SerializationException(GetResourceString(resource));
}
internal static void ThrowSecurityException(ExceptionResource resource) {
- throw new System.Security.SecurityException(Environment.GetResourceString(GetResourceName(resource)));
+ throw new System.Security.SecurityException(GetResourceString(resource));
}
internal static void ThrowRankException(ExceptionResource resource) {
- throw new RankException(Environment.GetResourceString(GetResourceName(resource)));
+ throw new RankException(GetResourceString(resource));
}
internal static void ThrowNotSupportedException(ExceptionResource resource) {
- throw new NotSupportedException(Environment.GetResourceString(GetResourceName(resource)));
+ throw new NotSupportedException(GetResourceString(resource));
}
internal static void ThrowUnauthorizedAccessException(ExceptionResource resource) {
- throw new UnauthorizedAccessException(Environment.GetResourceString(GetResourceName(resource)));
+ throw new UnauthorizedAccessException(GetResourceString(resource));
}
internal static void ThrowObjectDisposedException(string objectName, ExceptionResource resource) {
- throw new ObjectDisposedException(objectName, Environment.GetResourceString(GetResourceName(resource)));
+ throw new ObjectDisposedException(objectName, GetResourceString(resource));
}
- internal static void ThrowObjectDisposedException(ExceptionResource resource)
- {
- throw new ObjectDisposedException(null, Environment.GetResourceString(GetResourceName(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() {
+ throw GetArgumentException(ExceptionResource.Argument_InvalidArrayType);
+ }
+
+ internal static void ThrowInvalidOperationException_InvalidOperation_EnumNotStarted() {
+ throw GetInvalidOperationException(ExceptionResource.InvalidOperation_EnumNotStarted);
+ }
+
+ internal static void ThrowInvalidOperationException_InvalidOperation_EnumEnded() {
+ throw GetInvalidOperationException(ExceptionResource.InvalidOperation_EnumEnded);
+ }
+
+ internal static void ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion() {
+ throw GetInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
+ }
+
+ internal static void ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen() {
+ throw GetInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);
+ }
+
+ private static ArgumentException GetArgumentException(ExceptionResource resource) {
+ return new ArgumentException(GetResourceString(resource));
+ }
+
+ private 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 GetWrongValueTypeArgumentException(object value, Type targetType) {
+ return new ArgumentException(Environment.GetResourceString("Arg_WrongType", value, targetType), nameof(value));
+ }
+
+ private static ArgumentOutOfRangeException GetArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource) {
+ return new ArgumentOutOfRangeException(GetArgumentName(argument), GetResourceString(resource));
+ }
+
+ 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) {
+ return new ArgumentOutOfRangeException(GetArgumentName(argument) + "[" + paramNumber.ToString() + "]", GetResourceString(resource));
+ }
+
// Allow nulls for reference types and Nullable<U>, but not for value types.
// 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
@@ -155,26 +249,43 @@ namespace System {
ThrowHelper.ThrowArgumentNullException(argName);
}
- //
// This function will convert an ExceptionArgument enum value to the argument name string.
- //
- internal static string GetArgumentName(ExceptionArgument argument) {
- Contract.Assert(Enum.IsDefined(typeof(ExceptionArgument), argument),
+ 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) {
+ Debug.Assert(Enum.IsDefined(typeof(ExceptionArgument), argument),
"The enum value is not defined, please check the ExceptionArgument Enum.");
return argument.ToString();
}
- //
// This function will convert an ExceptionResource enum value to the resource string.
- //
- internal static string GetResourceName(ExceptionResource resource) {
- Contract.Assert(Enum.IsDefined(typeof(ExceptionResource), resource),
+ 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) {
+ Debug.Assert(Enum.IsDefined(typeof(ExceptionResource), resource),
"The enum value is not defined, please check the ExceptionResource Enum.");
- return resource.ToString();
+ return Environment.GetResourceString(resource.ToString());
}
-
}
//
@@ -247,6 +358,11 @@ namespace System {
beginMethod,
continuationOptions,
continuationAction,
+ valueFactory,
+ addValueFactory,
+ updateValueFactory,
+ concurrencyLevel,
+ text,
}
@@ -341,6 +457,17 @@ namespace System {
TaskCompletionSourceT_TrySetException_NullException,
TaskCompletionSourceT_TrySetException_NoExceptions,
InvalidOperation_WrongAsyncResultOrEndCalledMultiple,
+ ConcurrentDictionary_ConcurrencyLevelMustBePositive,
+ ConcurrentDictionary_CapacityMustNotBeNegative,
+ ConcurrentDictionary_TypeOfValueIncorrect,
+ ConcurrentDictionary_TypeOfKeyIncorrect,
+ ConcurrentDictionary_SourceContainsDuplicateKeys,
+ ConcurrentDictionary_KeyAlreadyExisted,
+ ConcurrentDictionary_ItemKeyIsNull,
+ ConcurrentDictionary_IndexIsNegative,
+ ConcurrentDictionary_ArrayNotLargeEnough,
+ ConcurrentDictionary_ArrayIncorrectType,
+ ConcurrentCollection_SyncRoot_NotSupported,
}
}
diff --git a/src/mscorlib/src/System/TimeSpan.cs b/src/mscorlib/src/System/TimeSpan.cs
index c9cfc084f3..a594da20e7 100644
--- a/src/mscorlib/src/System/TimeSpan.cs
+++ b/src/mscorlib/src/System/TimeSpan.cs
@@ -28,7 +28,7 @@ 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.
//
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
[Serializable] public struct TimeSpan : IComparable
, IComparable<TimeSpan>, IEquatable<TimeSpan>, IFormattable
{
@@ -289,11 +289,11 @@ namespace System {
return TimeSpanParse.ParseExactMultiple(input, formats, formatProvider, TimeSpanStyles.None);
}
public static TimeSpan ParseExact(String input, String format, IFormatProvider formatProvider, TimeSpanStyles styles) {
- TimeSpanParse.ValidateStyles(styles, "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) {
- TimeSpanParse.ValidateStyles(styles, "styles");
+ TimeSpanParse.ValidateStyles(styles, nameof(styles));
return TimeSpanParse.ParseExactMultiple(input, formats, formatProvider, styles);
}
public static Boolean TryParse(String s, out TimeSpan result) {
@@ -309,11 +309,11 @@ namespace System {
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) {
- TimeSpanParse.ValidateStyles(styles, "styles");
+ 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) {
- TimeSpanParse.ValidateStyles(styles, "styles");
+ TimeSpanParse.ValidateStyles(styles, nameof(styles));
return TimeSpanParse.TryParseExactMultiple(input, formats, formatProvider, styles, out result);
}
public override String ToString() {
@@ -406,26 +406,8 @@ namespace System {
// [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
// "TimeSpan_LegacyFormatMode"=dword:00000001
//
-#if !FEATURE_CORECLR
- [System.Security.SecurityCritical]
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern bool LegacyFormatMode();
-#endif // !FEATURE_CORECLR
- //
- // In Silverlight v4, specifying the APP_EARLIER_THAN_SL4.0 quirks mode allows applications to
- // run in v2 - v3 legacy behavior.
- //
-#if !FEATURE_CORECLR
- [System.Security.SecuritySafeCritical]
-#endif
private static bool GetLegacyFormatMode() {
-#if !FEATURE_CORECLR
- if (LegacyFormatMode()) // FCALL to check COMPlus_TimeSpan_LegacyFormatMode
- return true;
- return CompatibilitySwitches.IsNetFx40TimeSpanLegacyFormatMode;
-#else
return false;
-#endif // !FEATURE_CORECLR
}
private static volatile bool _legacyConfigChecked;
diff --git a/src/mscorlib/src/System/TimeZone.cs b/src/mscorlib/src/System/TimeZone.cs
index 602e86ab54..c0a369fd3c 100644
--- a/src/mscorlib/src/System/TimeZone.cs
+++ b/src/mscorlib/src/System/TimeZone.cs
@@ -26,10 +26,8 @@ namespace System {
using System.Globalization;
[Serializable]
-[System.Runtime.InteropServices.ComVisible(true)]
-#if FEATURE_CORECLR
+ [System.Runtime.InteropServices.ComVisible(true)]
[Obsolete("System.TimeZone has been deprecated. Please investigate the use of System.TimeZoneInfo instead.")]
-#endif
public abstract class TimeZone {
private static volatile TimeZone currentTimeZone = null;
diff --git a/src/mscorlib/src/System/TimeZoneInfo.cs b/src/mscorlib/src/System/TimeZoneInfo.cs
index a9d194afab..72fc28fc3e 100644
--- a/src/mscorlib/src/System/TimeZoneInfo.cs
+++ b/src/mscorlib/src/System/TimeZoneInfo.cs
@@ -49,22 +49,18 @@ namespace System {
NoThrowOnInvalidTime = 2
};
-
[Serializable]
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
-#if !FEATURE_CORECLR
- [TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
-#endif
sealed public class TimeZoneInfo : IEquatable<TimeZoneInfo>, ISerializable, IDeserializationCallback
{
// ---- SECTION: members supporting exposed properties -------------*
- private String m_id;
- private String m_displayName;
- private String m_standardDisplayName;
- private String m_daylightDisplayName;
- private TimeSpan m_baseUtcOffset;
- private Boolean m_supportsDaylightSavingTime;
- private AdjustmentRule[] m_adjustmentRules;
+ private readonly String m_id;
+ private readonly String m_displayName;
+ private readonly String m_standardDisplayName;
+ private readonly String m_daylightDisplayName;
+ private readonly TimeSpan m_baseUtcOffset;
+ private readonly Boolean m_supportsDaylightSavingTime;
+ private readonly AdjustmentRule[] m_adjustmentRules;
// ---- SECTION: members for internal support ---------*
private enum TimeZoneInfoResult {
@@ -115,6 +111,8 @@ namespace System {
private const long c_ticksPerDay = c_ticksPerHour * 24;
private const long c_ticksPerDayRange = c_ticksPerDay - c_ticksPerMillisecond;
+ private static readonly TimeZoneInfo s_utcTimeZone = CreateCustomTimeZone(c_utcId, TimeSpan.Zero, c_utcId, c_utcId);
+
//
// All cached data are encapsulated in a helper class to allow consistent view even when the data are refreshed using ClearCachedData()
//
@@ -125,7 +123,6 @@ namespace System {
class CachedData
{
private volatile TimeZoneInfo m_localTimeZone;
- private volatile TimeZoneInfo m_utcTimeZone;
private TimeZoneInfo CreateLocal()
{
@@ -163,31 +160,6 @@ namespace System {
}
}
- private TimeZoneInfo CreateUtc()
- {
- lock (this)
- {
- TimeZoneInfo timeZone = m_utcTimeZone;
- if (timeZone == null) {
- timeZone = CreateCustomTimeZone(c_utcId, TimeSpan.Zero, c_utcId, c_utcId);
- m_utcTimeZone = timeZone;
- }
- return timeZone;
- }
- }
-
- public TimeZoneInfo Utc {
- get {
- Contract.Ensures(Contract.Result<TimeZoneInfo>() != null);
-
- TimeZoneInfo timeZone = m_utcTimeZone;
- if (timeZone == null) {
- timeZone = CreateUtc();
- }
- return timeZone;
- }
- }
-
//
// GetCorrespondingKind-
//
@@ -215,7 +187,7 @@ namespace System {
// in this example. Only when the user passes in TimeZoneInfo.Local or
// TimeZoneInfo.Utc to the ConvertTime(...) methods will this check succeed.
//
- if ((object)timeZone == (object)m_utcTimeZone) {
+ if ((object)timeZone == (object)s_utcTimeZone) {
kind = DateTimeKind.Utc;
}
else if ((object)timeZone == (object)m_localTimeZone) {
@@ -233,7 +205,6 @@ namespace System {
public bool m_allSystemTimeZonesRead;
#if FEATURE_WIN32_REGISTRY
- [System.Security.SecuritySafeCritical]
private static TimeZoneInfo GetCurrentOneYearLocal() {
// load the data from the OS
TimeZoneInfo match;
@@ -319,24 +290,58 @@ namespace System {
}
}
+#if PLATFORM_UNIX
+ // 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
+ // and can use it as it is used in Windows
- // ---- SECTION: public methods --------------*
+ private AdjustmentRule[] GetFilledRules()
+ {
+ Debug.Assert(m_adjustmentRules != null, "m_adjustmentRules expected to be not null");
+ AdjustmentRule[] rules = new AdjustmentRule[m_adjustmentRules.Length];
+
+ for (int i = 0; i < m_adjustmentRules.Length; i++)
+ {
+ var rule = m_adjustmentRules[i];
+ var start = rule.DateStart.Kind == DateTimeKind.Utc ?
+ new DateTime(TimeZoneInfo.ConvertTime(rule.DateStart, this).Ticks, DateTimeKind.Unspecified) :
+ rule.DateStart;
+ var end = rule.DateEnd.Kind == DateTimeKind.Utc ?
+ new DateTime(TimeZoneInfo.ConvertTime(rule.DateEnd, this).Ticks - 1, DateTimeKind.Unspecified) :
+ rule.DateEnd;
+
+ var startTransition = TimeZoneInfo.TransitionTime.CreateFixedDateRule(new DateTime(1, 1, 1, start.Hour, start.Minute, start.Second), start.Month, start.Day);
+ var endTransition = TimeZoneInfo.TransitionTime.CreateFixedDateRule(new DateTime(1, 1, 1, end.Hour, end.Minute, end.Second), end.Month, end.Day);
+
+ rules[i] = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(start.Date, end.Date, rule.DaylightDelta, startTransition, endTransition);
+ }
+
+ return rules;
+ }
+#endif // PLATFORM_UNIX
+ // ---- SECTION: public methods --------------*
//
// GetAdjustmentRules -
//
// returns a cloned array of AdjustmentRule objects
//
- public AdjustmentRule [] GetAdjustmentRules() {
- if (m_adjustmentRules == null) {
- return new AdjustmentRule[0];
+ public AdjustmentRule [] GetAdjustmentRules()
+ {
+ if (m_adjustmentRules == null)
+ {
+ return Array.Empty<AdjustmentRule>();
}
- else {
- return (AdjustmentRule[])m_adjustmentRules.Clone();
+ else
+ {
+#if PLATFORM_UNIX
+ return GetFilledRules();
+#else
+ return (AdjustmentRule[]) m_adjustmentRules.Clone();
+#endif // PLATFORM_UNIX
}
}
-
//
// GetAmbiguousTimeOffsets -
//
@@ -345,7 +350,7 @@ namespace System {
//
public TimeSpan[] GetAmbiguousTimeOffsets(DateTimeOffset dateTimeOffset) {
if (!SupportsDaylightSavingTime) {
- throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeOffsetIsNotAmbiguous"), "dateTimeOffset");
+ throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeOffsetIsNotAmbiguous"), nameof(dateTimeOffset));
}
Contract.EndContractBlock();
@@ -354,12 +359,12 @@ namespace System {
Boolean isAmbiguous = false;
AdjustmentRule rule = GetAdjustmentRuleForAmbiguousOffsets(adjustedTime);
if (rule != null && rule.HasDaylightSaving) {
- DaylightTime daylightTime = GetDaylightTime(adjustedTime.Year, rule);
+ DaylightTimeStruct daylightTime = GetDaylightTime(adjustedTime.Year, rule);
isAmbiguous = GetIsAmbiguousTime(adjustedTime, rule, daylightTime);
}
if (!isAmbiguous) {
- throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeOffsetIsNotAmbiguous"), "dateTimeOffset");
+ throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeOffsetIsNotAmbiguous"), nameof(dateTimeOffset));
}
// the passed in dateTime is ambiguous in this TimeZoneInfo instance
@@ -382,7 +387,7 @@ namespace System {
public TimeSpan[] GetAmbiguousTimeOffsets(DateTime dateTime) {
if (!SupportsDaylightSavingTime) {
- throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeIsNotAmbiguous"), "dateTime");
+ throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeIsNotAmbiguous"), nameof(dateTime));
}
Contract.EndContractBlock();
@@ -393,7 +398,7 @@ namespace System {
}
else if (dateTime.Kind == DateTimeKind.Utc) {
CachedData cachedData = s_cachedData;
- adjustedTime = TimeZoneInfo.ConvertTime(dateTime, cachedData.Utc, this, TimeZoneInfoOptions.None, cachedData);
+ adjustedTime = TimeZoneInfo.ConvertTime(dateTime, s_utcTimeZone, this, TimeZoneInfoOptions.None, cachedData);
}
else {
adjustedTime = dateTime;
@@ -402,12 +407,12 @@ namespace System {
Boolean isAmbiguous = false;
AdjustmentRule rule = GetAdjustmentRuleForAmbiguousOffsets(adjustedTime);
if (rule != null && rule.HasDaylightSaving) {
- DaylightTime daylightTime = GetDaylightTime(adjustedTime.Year, rule);
+ DaylightTimeStruct daylightTime = GetDaylightTime(adjustedTime.Year, rule);
isAmbiguous = GetIsAmbiguousTime(adjustedTime, rule, daylightTime);
}
if (!isAmbiguous) {
- throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeIsNotAmbiguous"), "dateTime");
+ throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeIsNotAmbiguous"), nameof(dateTime));
}
// the passed in dateTime is ambiguous in this TimeZoneInfo instance
@@ -491,7 +496,7 @@ namespace System {
//
// normal case of converting from Local to Utc and then getting the offset from the UTC DateTime
//
- DateTime adjustedTime = TimeZoneInfo.ConvertTime(dateTime, cachedData.Local, cachedData.Utc, flags);
+ DateTime adjustedTime = TimeZoneInfo.ConvertTime(dateTime, cachedData.Local, s_utcTimeZone, flags);
return GetUtcOffsetFromUtc(adjustedTime, this);
}
@@ -558,7 +563,7 @@ namespace System {
}
else if (dateTime.Kind == DateTimeKind.Utc) {
CachedData cachedData = s_cachedData;
- adjustedTime = TimeZoneInfo.ConvertTime(dateTime, cachedData.Utc, this, flags, cachedData);
+ adjustedTime = TimeZoneInfo.ConvertTime(dateTime, s_utcTimeZone, this, flags, cachedData);
}
else {
adjustedTime = dateTime;
@@ -566,7 +571,7 @@ namespace System {
AdjustmentRule rule = GetAdjustmentRuleForTime(adjustedTime);
if (rule != null && rule.HasDaylightSaving) {
- DaylightTime daylightTime = GetDaylightTime(adjustedTime.Year, rule);
+ DaylightTimeStruct daylightTime = GetDaylightTime(adjustedTime.Year, rule);
return GetIsAmbiguousTime(adjustedTime, rule, daylightTime);
}
return false;
@@ -644,7 +649,7 @@ namespace System {
//
AdjustmentRule rule = GetAdjustmentRuleForTime(adjustedTime);
if (rule != null && rule.HasDaylightSaving) {
- DaylightTime daylightTime = GetDaylightTime(adjustedTime.Year, rule);
+ DaylightTimeStruct daylightTime = GetDaylightTime(adjustedTime.Year, rule);
return GetIsDaylightSavings(adjustedTime, rule, daylightTime, flags);
}
else {
@@ -668,7 +673,7 @@ namespace System {
AdjustmentRule rule = GetAdjustmentRuleForTime(dateTime);
if (rule != null && rule.HasDaylightSaving) {
- DaylightTime daylightTime = GetDaylightTime(dateTime.Year, rule);
+ DaylightTimeStruct daylightTime = GetDaylightTime(dateTime.Year, rule);
isInvalid = GetIsInvalidTime(dateTime, rule, daylightTime);
}
else {
@@ -690,22 +695,25 @@ namespace System {
s_cachedData = new CachedData();
}
-#if FEATURE_WIN32_REGISTRY
//
// ConvertTimeBySystemTimeZoneId -
//
// Converts the value of a DateTime object from sourceTimeZone to destinationTimeZone
//
- static public DateTimeOffset ConvertTimeBySystemTimeZoneId(DateTimeOffset dateTimeOffset, String destinationTimeZoneId) {
+ static public DateTimeOffset ConvertTimeBySystemTimeZoneId(DateTimeOffset dateTimeOffset, String destinationTimeZoneId)
+ {
return ConvertTime(dateTimeOffset, FindSystemTimeZoneById(destinationTimeZoneId));
}
- static public DateTime ConvertTimeBySystemTimeZoneId(DateTime dateTime, String destinationTimeZoneId) {
+ static public DateTime ConvertTimeBySystemTimeZoneId(DateTime dateTime, String destinationTimeZoneId)
+ {
return ConvertTime(dateTime, FindSystemTimeZoneById(destinationTimeZoneId));
}
- static public DateTime ConvertTimeBySystemTimeZoneId(DateTime dateTime, String sourceTimeZoneId, String destinationTimeZoneId) {
- if (dateTime.Kind == DateTimeKind.Local && String.Compare(sourceTimeZoneId, TimeZoneInfo.Local.Id, StringComparison.OrdinalIgnoreCase) == 0) {
+ static public DateTime ConvertTimeBySystemTimeZoneId(DateTime dateTime, String sourceTimeZoneId, String destinationTimeZoneId)
+ {
+ if (dateTime.Kind == DateTimeKind.Local && String.Compare(sourceTimeZoneId, TimeZoneInfo.Local.Id, StringComparison.OrdinalIgnoreCase) == 0)
+ {
// TimeZoneInfo.Local can be cleared by another thread calling TimeZoneInfo.ClearCachedData.
// Take snapshot of cached data to guarantee this method will not be impacted by the ClearCachedData call.
// Without the snapshot, there is a chance that ConvertTime will throw since 'source' won't
@@ -714,21 +722,21 @@ namespace System {
CachedData cachedData = s_cachedData;
return ConvertTime(dateTime, cachedData.Local, FindSystemTimeZoneById(destinationTimeZoneId), TimeZoneInfoOptions.None, cachedData);
}
- else if (dateTime.Kind == DateTimeKind.Utc && String.Compare(sourceTimeZoneId, TimeZoneInfo.Utc.Id, StringComparison.OrdinalIgnoreCase) == 0) {
+ else if (dateTime.Kind == DateTimeKind.Utc && String.Compare(sourceTimeZoneId, TimeZoneInfo.Utc.Id, StringComparison.OrdinalIgnoreCase) == 0)
+ {
// TimeZoneInfo.Utc can be cleared by another thread calling TimeZoneInfo.ClearCachedData.
// Take snapshot of cached data to guarantee this method will not be impacted by the ClearCachedData call.
// Without the snapshot, there is a chance that ConvertTime will throw since 'source' won't
// be reference equal to the new TimeZoneInfo.Utc
//
CachedData cachedData = s_cachedData;
- return ConvertTime(dateTime, cachedData.Utc, FindSystemTimeZoneById(destinationTimeZoneId), TimeZoneInfoOptions.None, cachedData);
+ return ConvertTime(dateTime, s_utcTimeZone, FindSystemTimeZoneById(destinationTimeZoneId), TimeZoneInfoOptions.None, cachedData);
}
- else {
+ else
+ {
return ConvertTime(dateTime, FindSystemTimeZoneById(sourceTimeZoneId), FindSystemTimeZoneById(destinationTimeZoneId));
}
}
-#endif // FEATURE_WIN32_REGISTRY
-
//
// ConvertTime -
@@ -738,7 +746,7 @@ namespace System {
static public DateTimeOffset ConvertTime(DateTimeOffset dateTimeOffset, TimeZoneInfo destinationTimeZone) {
if (destinationTimeZone == null) {
- throw new ArgumentNullException("destinationTimeZone");
+ throw new ArgumentNullException(nameof(destinationTimeZone));
}
Contract.EndContractBlock();
@@ -762,7 +770,7 @@ namespace System {
static public DateTime ConvertTime(DateTime dateTime, TimeZoneInfo destinationTimeZone) {
if (destinationTimeZone == null) {
- throw new ArgumentNullException("destinationTimeZone");
+ throw new ArgumentNullException(nameof(destinationTimeZone));
}
Contract.EndContractBlock();
@@ -772,7 +780,7 @@ namespace System {
}
CachedData cachedData = s_cachedData;
if (dateTime.Kind == DateTimeKind.Utc) {
- return ConvertTime(dateTime, cachedData.Utc, destinationTimeZone, TimeZoneInfoOptions.None, cachedData);
+ return ConvertTime(dateTime, s_utcTimeZone, destinationTimeZone, TimeZoneInfoOptions.None, cachedData);
}
else {
return ConvertTime(dateTime, cachedData.Local, destinationTimeZone, TimeZoneInfoOptions.None, cachedData);
@@ -790,17 +798,17 @@ namespace System {
static private DateTime ConvertTime(DateTime dateTime, TimeZoneInfo sourceTimeZone, TimeZoneInfo destinationTimeZone, TimeZoneInfoOptions flags, CachedData cachedData) {
if (sourceTimeZone == null) {
- throw new ArgumentNullException("sourceTimeZone");
+ throw new ArgumentNullException(nameof(sourceTimeZone));
}
if (destinationTimeZone == null) {
- throw new ArgumentNullException("destinationTimeZone");
+ throw new ArgumentNullException(nameof(destinationTimeZone));
}
Contract.EndContractBlock();
DateTimeKind sourceKind = cachedData.GetCorrespondingKind(sourceTimeZone);
if ( ((flags & TimeZoneInfoOptions.NoThrowOnInvalidTime) == 0) && (dateTime.Kind != DateTimeKind.Unspecified) && (dateTime.Kind != sourceKind) ) {
- throw new ArgumentException(Environment.GetResourceString("Argument_ConvertMismatch"), "sourceTimeZone");
+ throw new ArgumentException(Environment.GetResourceString("Argument_ConvertMismatch"), nameof(sourceTimeZone));
}
//
@@ -818,12 +826,12 @@ namespace System {
sourceOffset = sourceOffset + sourceRule.BaseUtcOffsetDelta;
if (sourceRule.HasDaylightSaving) {
Boolean sourceIsDaylightSavings = false;
- DaylightTime sourceDaylightTime = sourceTimeZone.GetDaylightTime(dateTime.Year, sourceRule);
+ DaylightTimeStruct sourceDaylightTime = sourceTimeZone.GetDaylightTime(dateTime.Year, sourceRule);
// 'dateTime' might be in an invalid time range since it is in an AdjustmentRule
// period that supports DST
if (((flags & TimeZoneInfoOptions.NoThrowOnInvalidTime) == 0) && GetIsInvalidTime(dateTime, sourceRule, sourceDaylightTime)) {
- throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeIsInvalid"), "dateTime");
+ throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeIsInvalid"), nameof(dateTime));
}
sourceIsDaylightSavings = GetIsDaylightSavings(dateTime, sourceRule, sourceDaylightTime, flags);
@@ -866,7 +874,7 @@ namespace System {
//
static public DateTime ConvertTimeFromUtc(DateTime dateTime, TimeZoneInfo destinationTimeZone) {
CachedData cachedData = s_cachedData;
- return ConvertTime(dateTime, cachedData.Utc, destinationTimeZone, TimeZoneInfoOptions.None, cachedData);
+ return ConvertTime(dateTime, s_utcTimeZone, destinationTimeZone, TimeZoneInfoOptions.None, cachedData);
}
@@ -880,7 +888,7 @@ namespace System {
return dateTime;
}
CachedData cachedData = s_cachedData;
- return ConvertTime(dateTime, cachedData.Local, cachedData.Utc, TimeZoneInfoOptions.None, cachedData);
+ return ConvertTime(dateTime, cachedData.Local, s_utcTimeZone, TimeZoneInfoOptions.None, cachedData);
}
@@ -889,12 +897,12 @@ namespace System {
return dateTime;
}
CachedData cachedData = s_cachedData;
- return ConvertTime(dateTime, cachedData.Local, cachedData.Utc, flags, cachedData);
+ return ConvertTime(dateTime, cachedData.Local, s_utcTimeZone, flags, cachedData);
}
static public DateTime ConvertTimeToUtc(DateTime dateTime, TimeZoneInfo sourceTimeZone) {
CachedData cachedData = s_cachedData;
- return ConvertTime(dateTime, sourceTimeZone, cachedData.Utc, TimeZoneInfoOptions.None, cachedData);
+ return ConvertTime(dateTime, sourceTimeZone, s_utcTimeZone, TimeZoneInfoOptions.None, cachedData);
}
@@ -909,11 +917,7 @@ namespace System {
}
public override bool Equals(object obj) {
- TimeZoneInfo tzi = obj as TimeZoneInfo;
- if (null == tzi) {
- return false;
- }
- return Equals(tzi);
+ return Equals(obj as TimeZoneInfo);
}
//
@@ -921,10 +925,10 @@ namespace System {
//
static public TimeZoneInfo FromSerializedString(string source) {
if (source == null) {
- throw new ArgumentNullException("source");
+ throw new ArgumentNullException(nameof(source));
}
if (source.Length == 0) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidSerializedString", source), "source");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidSerializedString", source), nameof(source));
}
Contract.EndContractBlock();
@@ -936,7 +940,7 @@ namespace System {
// GetHashCode -
//
public override int GetHashCode() {
- return m_id.ToUpper(CultureInfo.InvariantCulture).GetHashCode();
+ return StringComparer.OrdinalIgnoreCase.GetHashCode(m_id);
}
//
@@ -952,7 +956,6 @@ namespace System {
// <SecurityKernel Critical="True" Ring="0">
// <Asserts Name="Imperative: System.Security.PermissionSet" />
// </SecurityKernel>
- [System.Security.SecuritySafeCritical] // auto-generated
static public ReadOnlyCollection<TimeZoneInfo> GetSystemTimeZones() {
CachedData cachedData = s_cachedData;
@@ -973,7 +976,12 @@ namespace System {
}
// sort and copy the TimeZoneInfo's into a ReadOnlyCollection for the user
- list.Sort(new TimeZoneInfoComparer());
+ list.Sort((x, y) =>
+ {
+ // sort by BaseUtcOffset first and by DisplayName second - this is similar to the Windows Date/Time control panel
+ int comparison = x.BaseUtcOffset.CompareTo(y.BaseUtcOffset);
+ return comparison == 0 ? string.CompareOrdinal(x.DisplayName, y.DisplayName) : comparison;
+ });
cachedData.m_readOnlySystemTimeZones = new ReadOnlyCollection<TimeZoneInfo>(list);
}
@@ -981,26 +989,19 @@ namespace System {
return cachedData.m_readOnlySystemTimeZones;
}
- [SecuritySafeCritical]
private static void PopulateAllSystemTimeZones(CachedData cachedData)
{
#if FEATURE_WIN32_REGISTRY
PermissionSet permSet = new PermissionSet(PermissionState.None);
permSet.AddPermission(new RegistryPermission(RegistryPermissionAccess.Read, c_timeZonesRegistryHivePermissionList));
permSet.Assert();
-
- using (RegistryKey reg = Registry.LocalMachine.OpenSubKey(
- c_timeZonesRegistryHive,
-#if FEATURE_MACL
- RegistryKeyPermissionCheck.Default,
- System.Security.AccessControl.RegistryRights.ReadKey
-#else
- false
-#endif
- )) {
- if (reg != null) {
- foreach (string keyName in reg.GetSubKeyNames()) {
+ using (RegistryKey reg = Registry.LocalMachine.OpenSubKey(c_timeZonesRegistryHive, false))
+ {
+ if (reg != null)
+ {
+ foreach (string keyName in reg.GetSubKeyNames())
+ {
TimeZoneInfo value;
Exception ex;
TryGetTimeZone(keyName, false, out value, out ex, cachedData); // populate the cache
@@ -1025,7 +1026,7 @@ namespace System {
//
public Boolean HasSameRules(TimeZoneInfo other) {
if (other == null) {
- throw new ArgumentNullException("other");
+ throw new ArgumentNullException(nameof(other));
}
// check the utcOffset and supportsDaylightSavingTime members
@@ -1118,7 +1119,7 @@ namespace System {
static public TimeZoneInfo Utc {
get {
Contract.Ensures(Contract.Result<TimeZoneInfo>() != null);
- return s_cachedData.Utc;
+ return s_utcTimeZone;
}
}
@@ -1130,7 +1131,6 @@ namespace System {
// private ctor
//
#if FEATURE_WIN32_REGISTRY
- [System.Security.SecurityCritical] // auto-generated
private TimeZoneInfo(Win32Native.TimeZoneInformation zone, Boolean dstDisabled) {
if (String.IsNullOrEmpty(zone.StandardName)) {
@@ -1262,16 +1262,13 @@ namespace System {
Boolean adjustmentRulesSupportDst;
ValidateTimeZoneInfo(id, baseUtcOffset, adjustmentRules, out adjustmentRulesSupportDst);
- if (!disableDaylightSavingTime && adjustmentRules != null && adjustmentRules.Length > 0) {
- m_adjustmentRules = (AdjustmentRule[])adjustmentRules.Clone();
- }
-
m_id = id;
m_baseUtcOffset = baseUtcOffset;
m_displayName = displayName;
m_standardDisplayName = standardDisplayName;
m_daylightDisplayName = (disableDaylightSavingTime ? null : daylightDisplayName);
m_supportsDaylightSavingTime = adjustmentRulesSupportDst && !disableDaylightSavingTime;
+ m_adjustmentRules = adjustmentRules;
}
// -------- SECTION: factory methods -----------------*
@@ -1312,7 +1309,7 @@ namespace System {
String daylightDisplayName,
AdjustmentRule [] adjustmentRules) {
- return new TimeZoneInfo(
+ return CreateCustomTimeZone(
id,
baseUtcOffset,
displayName,
@@ -1341,7 +1338,11 @@ namespace System {
AdjustmentRule [] adjustmentRules,
Boolean disableDaylightSavingTime) {
- return new TimeZoneInfo(
+ if (!disableDaylightSavingTime && adjustmentRules?.Length > 0) {
+ adjustmentRules = (AdjustmentRule[])adjustmentRules.Clone();
+ }
+
+ return new TimeZoneInfo(
id,
baseUtcOffset,
displayName,
@@ -1373,10 +1374,9 @@ namespace System {
}
- [System.Security.SecurityCritical] // auto-generated_required
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) {
if (info == null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
@@ -1392,7 +1392,7 @@ namespace System {
TimeZoneInfo(SerializationInfo info, StreamingContext context) {
if (info == null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
m_id = (String)info.GetValue("Id", typeof(String));
@@ -1554,7 +1554,6 @@ namespace System {
//
// This check is only meant to be used for "Local".
//
- [System.Security.SecurityCritical] // auto-generated
static private Boolean CheckDaylightSavingTimeNotSupported(Win32Native.TimeZoneInformation timeZone) {
return ( timeZone.DaylightDate.Year == timeZone.StandardDate.Year
&& timeZone.DaylightDate.Month == timeZone.StandardDate.Month
@@ -1612,7 +1611,6 @@ namespace System {
//
// Converts a Win32Native.RegistryTimeZoneInformation (REG_TZI_FORMAT struct) to an AdjustmentRule
//
- [System.Security.SecurityCritical] // auto-generated
static private AdjustmentRule CreateAdjustmentRuleFromTimeZoneInformation(Win32Native.RegistryTimeZoneInformation timeZoneInformation, DateTime startDate, DateTime endDate, int defaultBaseUtcOffset) {
AdjustmentRule rule;
bool supportsDst = (timeZoneInformation.StandardDate.Month != 0);
@@ -1670,7 +1668,6 @@ namespace System {
// Helper function that searches the registry for a time zone entry
// that matches the TimeZoneInformation struct
//
- [System.Security.SecuritySafeCritical] // auto-generated
static private String FindIdFromTimeZoneInformation(Win32Native.TimeZoneInformation timeZone, out Boolean dstDisabled) {
dstDisabled = false;
@@ -1679,21 +1676,16 @@ namespace System {
permSet.AddPermission(new RegistryPermission(RegistryPermissionAccess.Read, c_timeZonesRegistryHivePermissionList));
permSet.Assert();
- using (RegistryKey key = Registry.LocalMachine.OpenSubKey(
- c_timeZonesRegistryHive,
-#if FEATURE_MACL
- RegistryKeyPermissionCheck.Default,
- System.Security.AccessControl.RegistryRights.ReadKey
-#else
- false
-#endif
- )) {
-
- if (key == null) {
+ using (RegistryKey key = Registry.LocalMachine.OpenSubKey(c_timeZonesRegistryHive, false))
+ {
+ if (key == null)
+ {
return null;
}
- foreach (string keyName in key.GetSubKeyNames()) {
- if (TryCompareTimeZoneInformationToRegistry(timeZone, keyName, out dstDisabled)) {
+ foreach (string keyName in key.GetSubKeyNames())
+ {
+ if (TryCompareTimeZoneInformationToRegistry(timeZone, keyName, out dstDisabled))
+ {
return keyName;
}
}
@@ -1712,7 +1704,7 @@ namespace System {
//
// Helper function that returns a DaylightTime from a year and AdjustmentRule
//
- private DaylightTime GetDaylightTime(Int32 year, AdjustmentRule rule) {
+ private DaylightTimeStruct GetDaylightTime(Int32 year, AdjustmentRule rule) {
TimeSpan delta = rule.DaylightDelta;
DateTime startTime;
DateTime endTime;
@@ -1733,7 +1725,7 @@ namespace System {
startTime = TransitionTimeToDateTime(year, rule.DaylightTransitionStart);
endTime = TransitionTimeToDateTime(year, rule.DaylightTransitionEnd);
}
- return new DaylightTime(startTime, endTime, delta);
+ return new DaylightTimeStruct(startTime, endTime, delta);
}
//
@@ -1742,7 +1734,7 @@ namespace System {
// Helper function that checks if a given dateTime is in Daylight Saving Time (DST)
// This function assumes the dateTime and AdjustmentRule are both in the same time zone
//
- static private Boolean GetIsDaylightSavings(DateTime time, AdjustmentRule rule, DaylightTime daylightTime, TimeZoneInfoOptions flags) {
+ static private Boolean GetIsDaylightSavings(DateTime time, AdjustmentRule rule, DaylightTimeStruct daylightTime, TimeZoneInfoOptions flags) {
if (rule == null) {
return false;
}
@@ -1837,7 +1829,7 @@ namespace System {
// Get the daylight changes for the year of the specified time.
- DaylightTime daylightTime = zone.GetDaylightTime(Year, rule);
+ DaylightTimeStruct daylightTime = zone.GetDaylightTime(Year, rule);
// 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
@@ -1856,7 +1848,7 @@ namespace System {
if (rule.IsStartDateMarkerForBeginningOfYear() && daylightTime.Start.Year > DateTime.MinValue.Year) {
AdjustmentRule previousYearRule = zone.GetAdjustmentRuleForTime(new DateTime(daylightTime.Start.Year - 1, 12, 31));
if (previousYearRule != null && previousYearRule.IsEndDateMarkerForEndOfYear()) {
- DaylightTime previousDaylightTime = zone.GetDaylightTime(daylightTime.Start.Year - 1, previousYearRule);
+ DaylightTimeStruct previousDaylightTime = zone.GetDaylightTime(daylightTime.Start.Year - 1, previousYearRule);
startTime = previousDaylightTime.Start - utc - previousYearRule.BaseUtcOffsetDelta;
ignoreYearAdjustment = true;
} else {
@@ -1874,7 +1866,7 @@ namespace System {
if (nextYearRule.IsEndDateMarkerForEndOfYear()) {// next year end with daylight saving on too
endTime = new DateTime(daylightTime.End.Year + 1, 12, 31) - utc - nextYearRule.BaseUtcOffsetDelta - nextYearRule.DaylightDelta;
} else {
- DaylightTime nextdaylightTime = zone.GetDaylightTime(daylightTime.End.Year + 1, nextYearRule);
+ DaylightTimeStruct nextdaylightTime = zone.GetDaylightTime(daylightTime.End.Year + 1, nextYearRule);
endTime = nextdaylightTime.End - utc - nextYearRule.BaseUtcOffsetDelta - nextYearRule.DaylightDelta;
}
ignoreYearAdjustment = true;
@@ -1980,7 +1972,7 @@ namespace System {
// In this example, any DateTime values that fall into the [1AM - 1:59:59AM] range
// are ambiguous; as it is unclear if these times are in Daylight Saving Time.
//
- static private Boolean GetIsAmbiguousTime(DateTime time, AdjustmentRule rule, DaylightTime daylightTime) {
+ static private Boolean GetIsAmbiguousTime(DateTime time, AdjustmentRule rule, DaylightTimeStruct daylightTime) {
Boolean isAmbiguous = false;
if (rule == null || rule.DaylightDelta == TimeSpan.Zero) {
return isAmbiguous;
@@ -2044,7 +2036,7 @@ namespace System {
// A "time hole" is not limited to only occurring at the start of DST, and may occur at
// the end of DST as well.
//
- static private Boolean GetIsInvalidTime(DateTime time, AdjustmentRule rule, DaylightTime daylightTime) {
+ static private Boolean GetIsInvalidTime(DateTime time, AdjustmentRule rule, DaylightTimeStruct daylightTime) {
Boolean isInvalid = false;
if (rule == null || rule.DaylightDelta == TimeSpan.Zero) {
return isInvalid;
@@ -2112,7 +2104,6 @@ namespace System {
// assumes cachedData lock is taken
//
- [System.Security.SecuritySafeCritical] // auto-generated
static private TimeZoneInfo GetLocalTimeZone(CachedData cachedData) {
@@ -2280,7 +2271,6 @@ namespace System {
/// 3. Look for the data in GetTimeZoneDirectory()/localtime.
/// 4. Use UTC if all else fails.
/// </summary>
- [SecurityCritical]
private static bool TryGetLocalTzFile(out byte[] rawData, out string id)
{
rawData = null;
@@ -2360,7 +2350,6 @@ namespace System {
/// Finds the time zone id by using 'readlink' on the path to see if tzFilePath is
/// a symlink to a file
/// </summary>
- [SecuritySafeCritical]
private static string FindTimeZoneIdUsingReadLink(string tzFilePath)
{
string id = null;
@@ -2476,7 +2465,6 @@ namespace System {
//
// The TryGetLocalTzFile() call returns a Byte[] containing the compiled tzfile.
//
- [System.Security.SecurityCritical]
static private TimeZoneInfo GetLocalTimeZoneFromTzFile()
{
byte[] rawData;
@@ -2539,7 +2527,6 @@ namespace System {
// try/catch logic for handling the TimeZoneInfo private constructor that takes
// a Win32Native.TimeZoneInformation structure.
//
- [System.Security.SecurityCritical] // auto-generated
static private TimeZoneInfo GetLocalTimeZoneFromWin32Data(Win32Native.TimeZoneInformation timeZoneInformation, Boolean dstDisabled) {
// first try to create the TimeZoneInfo with the original 'dstDisabled' flag
try {
@@ -2582,7 +2569,7 @@ namespace System {
}
if (id == null) {
- throw new ArgumentNullException("id");
+ throw new ArgumentNullException(nameof(id));
}
else if (!IsValidSystemTimeZoneId(id)) {
throw new TimeZoneNotFoundException(Environment.GetResourceString("TimeZoneNotFound_MissingData", id));
@@ -2606,7 +2593,7 @@ namespace System {
#if FEATURE_WIN32_REGISTRY
throw new InvalidTimeZoneException(Environment.GetResourceString("InvalidTimeZone_InvalidRegistryData", id), e);
#elif PLATFORM_UNIX
- Contract.Assert(e is InvalidTimeZoneException,
+ Debug.Assert(e is InvalidTimeZoneException,
"TryGetTimeZone must create an InvalidTimeZoneException when it returns TimeZoneInfoResult.InvalidTimeZoneException");
throw e;
#endif
@@ -2647,7 +2634,7 @@ namespace System {
if (rule != null) {
baseOffset = baseOffset + rule.BaseUtcOffsetDelta;
if (rule.HasDaylightSaving) {
- DaylightTime daylightTime = zone.GetDaylightTime(time.Year, rule);
+ DaylightTimeStruct daylightTime = zone.GetDaylightTime(time.Year, rule);
Boolean isDaylightSavings = GetIsDaylightSavings(time, rule, daylightTime, flags);
baseOffset += (isDaylightSavings ? rule.DaylightDelta : TimeSpan.Zero /* FUTURE: rule.StandardDelta */);
}
@@ -2719,7 +2706,7 @@ namespace System {
// As we get the associated rule using the adjusted targetTime, we should use the adjusted year (targetTime.Year) too as after adding the baseOffset,
// sometimes the year value can change if the input datetime was very close to the beginning or the end of the year. Examples of such cases:
- // “Libya Standard Time” when used with the date 2011-12-31T23:59:59.9999999Z
+ // Libya Standard Time when used with the date 2011-12-31T23:59:59.9999999Z
// "W. Australia Standard Time" used with date 2005-12-31T23:59:00.0000000Z
DateTime targetTime = time + baseOffset;
year = targetTime.Year;
@@ -2745,7 +2732,6 @@ namespace System {
// * when the argument 'readStart' is true the corresponding daylightTransitionTimeStart field is read
// * when the argument 'readStart' is false the corresponding dayightTransitionTimeEnd field is read
//
- [System.Security.SecurityCritical] // auto-generated
static private bool TransitionTimeFromTimeZoneInformation(Win32Native.RegistryTimeZoneInformation timeZoneInformation, out TransitionTime transitionTime, bool readStartDate) {
//
// SYSTEMTIME -
@@ -2856,7 +2842,7 @@ namespace System {
//
// Helper function that converts a year and TransitionTime into a DateTime
//
- static private DateTime TransitionTimeToDateTime(Int32 year, TransitionTime transitionTime) {
+ internal static DateTime TransitionTimeToDateTime(Int32 year, TransitionTime transitionTime) {
DateTime value;
DateTime timeOfDay = transitionTime.TimeOfDay;
@@ -2951,33 +2937,27 @@ namespace System {
//
// This method expects that its caller has already Asserted RegistryPermission.Read
//
- [System.Security.SecurityCritical] // auto-generated
static private bool TryCreateAdjustmentRules(string id, Win32Native.RegistryTimeZoneInformation defaultTimeZoneInformation, out AdjustmentRule[] rules, out Exception e, int defaultBaseUtcOffset) {
e = null;
try {
using (RegistryKey dynamicKey = Registry.LocalMachine.OpenSubKey(
- String.Format(CultureInfo.InvariantCulture, "{0}\\{1}\\Dynamic DST",
- c_timeZonesRegistryHive, id),
-#if FEATURE_MACL
- RegistryKeyPermissionCheck.Default,
- System.Security.AccessControl.RegistryRights.ReadKey
-#else
- false
-#endif
- )) {
+ c_timeZonesRegistryHive + "\\" + id + "\\Dynamic DST",
+ false)) {
if (dynamicKey == null) {
AdjustmentRule rule = CreateAdjustmentRuleFromTimeZoneInformation(
defaultTimeZoneInformation, DateTime.MinValue.Date, DateTime.MaxValue.Date, defaultBaseUtcOffset);
- if (rule == null) {
+ if (rule == null)
+ {
rules = null;
}
- else {
+ else
+ {
rules = new AdjustmentRule[1];
rules[0] = rule;
}
-
+
return true;
}
@@ -2992,7 +2972,8 @@ namespace System {
Int32 first = (Int32)dynamicKey.GetValue(c_firstEntryValue, -1, RegistryValueOptions.None);
Int32 last = (Int32)dynamicKey.GetValue(c_lastEntryValue, -1, RegistryValueOptions.None);
- if (first == -1 || last == -1 || first > last) {
+ if (first == -1 || last == -1 || first > last)
+ {
rules = null;
return false;
}
@@ -3000,20 +2981,24 @@ namespace System {
// read the first year entry
Win32Native.RegistryTimeZoneInformation dtzi;
Byte[] regValue = dynamicKey.GetValue(first.ToString(CultureInfo.InvariantCulture), null, RegistryValueOptions.None) as Byte[];
- if (regValue == null || regValue.Length != c_regByteLength) {
+ if (regValue == null || regValue.Length != c_regByteLength)
+ {
rules = null;
return false;
}
dtzi = new Win32Native.RegistryTimeZoneInformation(regValue);
- if (first == last) {
+ if (first == last)
+ {
// there is just 1 dynamic rule for this time zone.
- AdjustmentRule rule = CreateAdjustmentRuleFromTimeZoneInformation(dtzi, DateTime.MinValue.Date, DateTime.MaxValue.Date, defaultBaseUtcOffset);
+ AdjustmentRule rule = CreateAdjustmentRuleFromTimeZoneInformation(dtzi, DateTime.MinValue.Date, DateTime.MaxValue.Date, defaultBaseUtcOffset);
- if (rule == null) {
+ if (rule == null)
+ {
rules = null;
}
- else {
+ else
+ {
rules = new AdjustmentRule[1];
rules[0] = rule;
}
@@ -3023,20 +3008,23 @@ namespace System {
List<AdjustmentRule> rulesList = new List<AdjustmentRule>(1);
- // there are more than 1 dynamic rules for this time zone.
+ // there are more than 1 dynamic rules for this time zone.
AdjustmentRule firstRule = CreateAdjustmentRuleFromTimeZoneInformation(
dtzi,
DateTime.MinValue.Date, // MinValue
new DateTime(first, 12, 31), // December 31, <FirstYear>
- defaultBaseUtcOffset);
- if (firstRule != null) {
+ defaultBaseUtcOffset);
+ if (firstRule != null)
+ {
rulesList.Add(firstRule);
}
// read the middle year entries
- for (Int32 i = first + 1; i < last; i++) {
+ for (Int32 i = first + 1; i < last; i++)
+ {
regValue = dynamicKey.GetValue(i.ToString(CultureInfo.InvariantCulture), null, RegistryValueOptions.None) as Byte[];
- if (regValue == null || regValue.Length != c_regByteLength) {
+ if (regValue == null || regValue.Length != c_regByteLength)
+ {
rules = null;
return false;
}
@@ -3046,14 +3034,16 @@ namespace System {
new DateTime(i, 1, 1), // January 01, <Year>
new DateTime(i, 12, 31), // December 31, <Year>
defaultBaseUtcOffset);
- if (middleRule != null) {
+ if (middleRule != null)
+ {
rulesList.Add(middleRule);
}
}
// read the last year entry
regValue = dynamicKey.GetValue(last.ToString(CultureInfo.InvariantCulture), null, RegistryValueOptions.None) as Byte[];
dtzi = new Win32Native.RegistryTimeZoneInformation(regValue);
- if (regValue == null || regValue.Length != c_regByteLength) {
+ if (regValue == null || regValue.Length != c_regByteLength)
+ {
rules = null;
return false;
}
@@ -3062,13 +3052,15 @@ namespace System {
new DateTime(last, 1, 1), // January 01, <LastYear>
DateTime.MaxValue.Date, // MaxValue
defaultBaseUtcOffset);
- if (lastRule != null) {
+ if (lastRule != null)
+ {
rulesList.Add(lastRule);
}
// convert the ArrayList to an AdjustmentRule array
rules = rulesList.ToArray();
- if (rules != null && rules.Length == 0) {
+ if (rules != null && rules.Length == 0)
+ {
rules = null;
}
} // end of: using (RegistryKey dynamicKey...
@@ -3098,7 +3090,6 @@ namespace System {
// Helper function that compares the StandardBias and StandardDate portion a
// TimeZoneInformation struct to a time zone registry entry
//
- [System.Security.SecurityCritical] // auto-generated
static private Boolean TryCompareStandardDate(Win32Native.TimeZoneInformation timeZone, Win32Native.RegistryTimeZoneInformation registryTimeZoneInfo) {
return timeZone.Bias == registryTimeZoneInfo.Bias
&& timeZone.StandardBias == registryTimeZoneInfo.StandardBias
@@ -3117,9 +3108,8 @@ namespace System {
//
// Helper function that compares a TimeZoneInformation struct to a time zone registry entry
//
- [System.Security.SecuritySafeCritical] // auto-generated
- static private Boolean TryCompareTimeZoneInformationToRegistry(Win32Native.TimeZoneInformation timeZone, string id, out Boolean dstDisabled) {
-
+ static private Boolean TryCompareTimeZoneInformationToRegistry(Win32Native.TimeZoneInformation timeZone, string id, out Boolean dstDisabled)
+ {
dstDisabled = false;
try {
PermissionSet permSet = new PermissionSet(PermissionState.None);
@@ -3127,15 +3117,9 @@ namespace System {
permSet.Assert();
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(
- String.Format(CultureInfo.InvariantCulture, "{0}\\{1}",
- c_timeZonesRegistryHive, id),
-#if FEATURE_MACL
- RegistryKeyPermissionCheck.Default,
- System.Security.AccessControl.RegistryRights.ReadKey
-#else
- false
-#endif
- )) {
+ c_timeZonesRegistryHive + "\\" + id,
+ false))
+ {
if (key == null) {
return false;
@@ -3152,7 +3136,8 @@ namespace System {
//
Boolean result = TryCompareStandardDate(timeZone, registryTimeZoneInfo);
- if (!result) {
+ if (!result)
+ {
return false;
}
@@ -3161,14 +3146,14 @@ namespace System {
// since Daylight Saving Time is not "disabled", do a straight comparision between
// the Win32 API data and the registry data ...
//
- ||( timeZone.DaylightBias == registryTimeZoneInfo.DaylightBias
- && timeZone.DaylightDate.Year == registryTimeZoneInfo.DaylightDate.Year
- && timeZone.DaylightDate.Month == registryTimeZoneInfo.DaylightDate.Month
- && timeZone.DaylightDate.DayOfWeek == registryTimeZoneInfo.DaylightDate.DayOfWeek
- && timeZone.DaylightDate.Day == registryTimeZoneInfo.DaylightDate.Day
- && timeZone.DaylightDate.Hour == registryTimeZoneInfo.DaylightDate.Hour
- && timeZone.DaylightDate.Minute == registryTimeZoneInfo.DaylightDate.Minute
- && timeZone.DaylightDate.Second == registryTimeZoneInfo.DaylightDate.Second
+ || (timeZone.DaylightBias == registryTimeZoneInfo.DaylightBias
+ && timeZone.DaylightDate.Year == registryTimeZoneInfo.DaylightDate.Year
+ && timeZone.DaylightDate.Month == registryTimeZoneInfo.DaylightDate.Month
+ && timeZone.DaylightDate.DayOfWeek == registryTimeZoneInfo.DaylightDate.DayOfWeek
+ && timeZone.DaylightDate.Day == registryTimeZoneInfo.DaylightDate.Day
+ && timeZone.DaylightDate.Hour == registryTimeZoneInfo.DaylightDate.Hour
+ && timeZone.DaylightDate.Minute == registryTimeZoneInfo.DaylightDate.Minute
+ && timeZone.DaylightDate.Second == registryTimeZoneInfo.DaylightDate.Second
&& timeZone.DaylightDate.Milliseconds == registryTimeZoneInfo.DaylightDate.Milliseconds);
// Finally compare the "StandardName" string value...
@@ -3176,11 +3161,12 @@ namespace System {
// we do not compare "DaylightName" as this TimeZoneInformation field may contain
// either "StandardName" or "DaylightName" depending on the time of year and current machine settings
//
- if (result) {
+ if (result)
+ {
String registryStandardName = key.GetValue(c_standardValue, String.Empty, RegistryValueOptions.None) as String;
result = String.Compare(registryStandardName, timeZone.StandardName, StringComparison.Ordinal) == 0;
}
- return result;
+ return result;
}
}
finally {
@@ -3204,10 +3190,6 @@ namespace System {
// <CallsSuppressUnmanagedCode Name="UnsafeNativeMethods.GetFileMUIPath(System.Int32,System.String,System.Text.StringBuilder,System.Int32&,System.Text.StringBuilder,System.Int32&,System.Int64&):System.Boolean" />
// <ReferencesCritical Name="Method: TryGetLocalizedNameByNativeResource(String, Int32):String" Ring="1" />
// </SecurityKernel>
- [System.Security.SecuritySafeCritical] // auto-generated
-#if !FEATURE_CORECLR
- [FileIOPermissionAttribute(SecurityAction.Assert, AllLocalFiles = FileIOPermissionAccess.PathDiscovery)]
-#endif
static private string TryGetLocalizedNameByMuiNativeResource(string resource) {
if (String.IsNullOrEmpty(resource)) {
return String.Empty;
@@ -3277,7 +3259,6 @@ namespace System {
// "resource.dll" is a language-specific resource DLL.
// If the localized resource DLL exists, LoadString(resource) is returned.
//
- [SecurityCritical]
static private string TryGetLocalizedNameByNativeResource(string filePath, int resource) {
using (SafeLibraryHandle handle =
UnsafeNativeMethods.LoadLibraryEx(filePath, IntPtr.Zero, Win32Native.LOAD_LIBRARY_AS_DATAFILE)) {
@@ -3308,9 +3289,6 @@ namespace System {
//
// This method expects that its caller has already Asserted RegistryPermission.Read
//
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
static private Boolean TryGetLocalizedNamesByRegistryKey(RegistryKey key, out String displayName, out String standardName, out String daylightName) {
displayName = String.Empty;
standardName = String.Empty;
@@ -3387,7 +3365,6 @@ namespace System {
// * TZI, REG_BINARY REG_TZI_FORMAT
// See Win32Native.RegistryTimeZoneInformation
//
- [System.Security.SecuritySafeCritical] // auto-generated
static private TimeZoneInfoResult TryGetTimeZoneByRegistryKey(string id, out TimeZoneInfo value, out Exception e) {
e = null;
@@ -3397,15 +3374,8 @@ namespace System {
permSet.Assert();
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(
- String.Format(CultureInfo.InvariantCulture, "{0}\\{1}",
- c_timeZonesRegistryHive, id),
-#if FEATURE_MACL
- RegistryKeyPermissionCheck.Default,
- System.Security.AccessControl.RegistryRights.ReadKey
-#else
- false
-#endif
- )) {
+ c_timeZonesRegistryHive + "\\" + id,
+ false)) {
if (key == null) {
value = null;
@@ -4204,7 +4174,6 @@ namespace System {
// Converts an array of bytes into an int - always using standard byte order (Big Endian)
// per TZif file standard
- [System.Security.SecuritySafeCritical] // auto-generated
static private unsafe int TZif_ToInt32 (byte[]value, int startIndex) {
fixed( byte * pbyte = &value[startIndex]) {
return (*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | (*(pbyte + 3));
@@ -4213,7 +4182,6 @@ namespace System {
// Converts an array of bytes into a long - always using standard byte order (Big Endian)
// per TZif file standard
- [System.Security.SecuritySafeCritical] // auto-generated
static private unsafe long TZif_ToInt64(byte[] value, int startIndex)
{
fixed (byte* pbyte = &value[startIndex])
@@ -4386,20 +4354,20 @@ namespace System {
out Boolean adjustmentRulesSupportDst) {
if (id == null) {
- throw new ArgumentNullException("id");
+ throw new ArgumentNullException(nameof(id));
}
if (id.Length == 0) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidId", id), "id");
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidId", id), nameof(id));
}
if (UtcOffsetOutOfRange(baseUtcOffset)) {
- throw new ArgumentOutOfRangeException("baseUtcOffset", Environment.GetResourceString("ArgumentOutOfRange_UtcOffset"));
+ throw new ArgumentOutOfRangeException(nameof(baseUtcOffset), Environment.GetResourceString("ArgumentOutOfRange_UtcOffset"));
}
if (baseUtcOffset.Ticks % TimeSpan.TicksPerMinute != 0) {
- throw new ArgumentException(Environment.GetResourceString("Argument_TimeSpanHasSeconds"), "baseUtcOffset");
+ throw new ArgumentException(Environment.GetResourceString("Argument_TimeSpanHasSeconds"), nameof(baseUtcOffset));
}
Contract.EndContractBlock();
@@ -4454,20 +4422,17 @@ namespace System {
============================================================*/
[Serializable]
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
-#if !FEATURE_CORECLR
- [TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
-#endif
sealed public class AdjustmentRule : IEquatable<AdjustmentRule>, ISerializable, IDeserializationCallback
{
// ---- SECTION: members supporting exposed properties -------------*
- private DateTime m_dateStart;
- private DateTime m_dateEnd;
- private TimeSpan m_daylightDelta;
- private TransitionTime m_daylightTransitionStart;
- private TransitionTime m_daylightTransitionEnd;
- private TimeSpan m_baseUtcOffsetDelta; // delta from the default Utc offset (utcOffset = defaultUtcOffset + m_baseUtcOffsetDelta)
- private bool m_noDaylightTransitions;
+ private readonly DateTime m_dateStart;
+ private readonly DateTime m_dateEnd;
+ private readonly TimeSpan m_daylightDelta;
+ private readonly TransitionTime m_daylightTransitionStart;
+ private readonly TransitionTime m_daylightTransitionEnd;
+ private readonly TimeSpan m_baseUtcOffsetDelta; // delta from the default Utc offset (utcOffset = defaultUtcOffset + m_baseUtcOffsetDelta)
+ private readonly bool m_noDaylightTransitions;
// ---- SECTION: public properties --------------*
public DateTime DateStart {
@@ -4534,16 +4499,13 @@ namespace System {
// IEquatable<AdjustmentRule>
public bool Equals(AdjustmentRule other) {
- bool equals = (other != null
- && this.m_dateStart == other.m_dateStart
- && this.m_dateEnd == other.m_dateEnd
- && this.m_daylightDelta == other.m_daylightDelta
- && this.m_baseUtcOffsetDelta == other.m_baseUtcOffsetDelta);
-
- equals = equals && this.m_daylightTransitionEnd.Equals(other.m_daylightTransitionEnd)
- && this.m_daylightTransitionStart.Equals(other.m_daylightTransitionStart);
-
- return equals;
+ return other != null
+ && m_dateStart == other.m_dateStart
+ && m_dateEnd == other.m_dateEnd
+ && m_daylightDelta == other.m_daylightDelta
+ && m_baseUtcOffsetDelta == other.m_baseUtcOffsetDelta
+ && m_daylightTransitionEnd.Equals(other.m_daylightTransitionEnd)
+ && m_daylightTransitionStart.Equals(other.m_daylightTransitionStart);
}
@@ -4555,33 +4517,29 @@ namespace System {
// -------- SECTION: constructors -----------------*
- private AdjustmentRule() { }
-
-
- // -------- SECTION: factory methods -----------------*
-
- static internal AdjustmentRule CreateAdjustmentRule(
- DateTime dateStart,
- DateTime dateEnd,
- TimeSpan daylightDelta,
- TransitionTime daylightTransitionStart,
- TransitionTime daylightTransitionEnd,
- bool noDaylightTransitions) {
+ private AdjustmentRule(
+ DateTime dateStart,
+ DateTime dateEnd,
+ TimeSpan daylightDelta,
+ TransitionTime daylightTransitionStart,
+ TransitionTime daylightTransitionEnd,
+ TimeSpan baseUtcOffsetDelta,
+ bool noDaylightTransitions)
+ {
ValidateAdjustmentRule(dateStart, dateEnd, daylightDelta,
daylightTransitionStart, daylightTransitionEnd, noDaylightTransitions);
- AdjustmentRule rule = new AdjustmentRule();
+ m_dateStart = dateStart;
+ m_dateEnd = dateEnd;
+ m_daylightDelta = daylightDelta;
+ m_daylightTransitionStart = daylightTransitionStart;
+ m_daylightTransitionEnd = daylightTransitionEnd;
+ m_baseUtcOffsetDelta = baseUtcOffsetDelta;
+ m_noDaylightTransitions = noDaylightTransitions;
+ }
- rule.m_dateStart = dateStart;
- rule.m_dateEnd = dateEnd;
- rule.m_daylightDelta = daylightDelta;
- rule.m_daylightTransitionStart = daylightTransitionStart;
- rule.m_daylightTransitionEnd = daylightTransitionEnd;
- rule.m_baseUtcOffsetDelta = TimeSpan.Zero;
- rule.m_noDaylightTransitions = noDaylightTransitions;
- return rule;
- }
+ // -------- SECTION: factory methods -----------------*
static public AdjustmentRule CreateAdjustmentRule(
DateTime dateStart,
@@ -4590,8 +4548,14 @@ namespace System {
TransitionTime daylightTransitionStart,
TransitionTime daylightTransitionEnd)
{
- return CreateAdjustmentRule(dateStart, dateEnd, daylightDelta,
- daylightTransitionStart, daylightTransitionEnd, noDaylightTransitions: false);
+ return new AdjustmentRule(
+ dateStart,
+ dateEnd,
+ daylightDelta,
+ daylightTransitionStart,
+ daylightTransitionEnd,
+ baseUtcOffsetDelta: TimeSpan.Zero,
+ noDaylightTransitions: false);
}
static internal AdjustmentRule CreateAdjustmentRule(
@@ -4601,12 +4565,16 @@ namespace System {
TransitionTime daylightTransitionStart,
TransitionTime daylightTransitionEnd,
TimeSpan baseUtcOffsetDelta,
- bool noDaylightTransitions) {
- AdjustmentRule rule = CreateAdjustmentRule(dateStart, dateEnd, daylightDelta,
- daylightTransitionStart, daylightTransitionEnd, noDaylightTransitions);
-
- rule.m_baseUtcOffsetDelta = baseUtcOffsetDelta;
- return rule;
+ bool noDaylightTransitions)
+ {
+ return new AdjustmentRule(
+ dateStart,
+ dateEnd,
+ daylightDelta,
+ daylightTransitionStart,
+ daylightTransitionEnd,
+ baseUtcOffsetDelta,
+ noDaylightTransitions);
}
// ----- SECTION: internal utility methods ----------------*
@@ -4649,21 +4617,21 @@ namespace System {
if (dateStart.Kind != DateTimeKind.Unspecified && dateStart.Kind != DateTimeKind.Utc) {
- throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeKindMustBeUnspecifiedOrUtc"), "dateStart");
+ throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeKindMustBeUnspecifiedOrUtc"), nameof(dateStart));
}
if (dateEnd.Kind != DateTimeKind.Unspecified && dateEnd.Kind != DateTimeKind.Utc) {
- throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeKindMustBeUnspecifiedOrUtc"), "dateEnd");
+ throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeKindMustBeUnspecifiedOrUtc"), nameof(dateEnd));
}
if (daylightTransitionStart.Equals(daylightTransitionEnd) && !noDaylightTransitions) {
throw new ArgumentException(Environment.GetResourceString("Argument_TransitionTimesAreIdentical"),
- "daylightTransitionEnd");
+ nameof(daylightTransitionEnd));
}
if (dateStart > dateEnd) {
- throw new ArgumentException(Environment.GetResourceString("Argument_OutOfOrderDateTimes"), "dateStart");
+ throw new ArgumentException(Environment.GetResourceString("Argument_OutOfOrderDateTimes"), nameof(dateStart));
}
// This cannot use UtcOffsetOutOfRange to account for the scenario where Samoa moved across the International Date Line,
@@ -4671,23 +4639,23 @@ namespace System {
// So when trying to describe DaylightDeltas for those times, the DaylightDelta needs
// 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("daylightDelta", daylightDelta,
+ throw new ArgumentOutOfRangeException(nameof(daylightDelta), daylightDelta,
Environment.GetResourceString("ArgumentOutOfRange_UtcOffset"));
}
if (daylightDelta.Ticks % TimeSpan.TicksPerMinute != 0) {
throw new ArgumentException(Environment.GetResourceString("Argument_TimeSpanHasSeconds"),
- "daylightDelta");
+ nameof(daylightDelta));
}
if (dateStart != DateTime.MinValue && dateStart.Kind == DateTimeKind.Unspecified && dateStart.TimeOfDay != TimeSpan.Zero) {
throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeHasTimeOfDay"),
- "dateStart");
+ nameof(dateStart));
}
if (dateEnd != DateTime.MaxValue && dateEnd.Kind == DateTimeKind.Unspecified && dateEnd.TimeOfDay != TimeSpan.Zero) {
throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeHasTimeOfDay"),
- "dateEnd");
+ nameof(dateEnd));
}
Contract.EndContractBlock();
}
@@ -4709,10 +4677,9 @@ namespace System {
}
}
- [System.Security.SecurityCritical] // auto-generated_required
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) {
if (info == null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
@@ -4727,7 +4694,7 @@ namespace System {
AdjustmentRule(SerializationInfo info, StreamingContext context) {
if (info == null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
m_dateStart = (DateTime)info.GetValue("DateStart", typeof(DateTime));
@@ -4764,18 +4731,15 @@ namespace System {
============================================================*/
[Serializable]
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
-#if !FEATURE_CORECLR
- [TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
-#endif
public struct TransitionTime : IEquatable<TransitionTime>, ISerializable, IDeserializationCallback
{
// ---- SECTION: members supporting exposed properties -------------*
- private DateTime m_timeOfDay;
- private byte m_month;
- private byte m_week;
- private byte m_day;
- private DayOfWeek m_dayOfWeek;
- private Boolean m_isFixedDateRule;
+ private readonly DateTime m_timeOfDay;
+ private readonly byte m_month;
+ private readonly byte m_week;
+ private readonly byte m_day;
+ private readonly DayOfWeek m_dayOfWeek;
+ private readonly Boolean m_isFixedDateRule;
// ---- SECTION: public properties --------------*
@@ -4859,16 +4823,24 @@ namespace System {
// -------- SECTION: constructors -----------------*
-/*
- private TransitionTime() {
- m_timeOfDay = new DateTime();
- m_month = 0;
- m_week = 0;
- m_day = 0;
- m_dayOfWeek = DayOfWeek.Sunday;
- m_isFixedDateRule = false;
+
+ private TransitionTime(
+ DateTime timeOfDay,
+ Int32 month,
+ Int32 week,
+ Int32 day,
+ DayOfWeek dayOfWeek,
+ Boolean isFixedDateRule)
+ {
+ ValidateTransitionTime(timeOfDay, month, week, day, dayOfWeek);
+
+ m_timeOfDay = timeOfDay;
+ m_month = (byte)month;
+ m_week = (byte)week;
+ m_day = (byte)day;
+ m_dayOfWeek = dayOfWeek;
+ m_isFixedDateRule = isFixedDateRule;
}
-*/
// -------- SECTION: factory methods -----------------*
@@ -4879,7 +4851,7 @@ namespace System {
Int32 month,
Int32 day) {
- return CreateTransitionTime(timeOfDay, month, 1, day, DayOfWeek.Sunday, true);
+ return new TransitionTime(timeOfDay, month, 1, day, DayOfWeek.Sunday, isFixedDateRule: true);
}
@@ -4889,29 +4861,7 @@ namespace System {
Int32 week,
DayOfWeek dayOfWeek) {
- return CreateTransitionTime(timeOfDay, month, week, 1, dayOfWeek, false);
- }
-
-
- static private TransitionTime CreateTransitionTime(
- DateTime timeOfDay,
- Int32 month,
- Int32 week,
- Int32 day,
- DayOfWeek dayOfWeek,
- Boolean isFixedDateRule) {
-
- ValidateTransitionTime(timeOfDay, month, week, day, dayOfWeek);
-
- TransitionTime t = new TransitionTime();
- t.m_isFixedDateRule = isFixedDateRule;
- t.m_timeOfDay = timeOfDay;
- t.m_dayOfWeek = dayOfWeek;
- t.m_day = (byte)day;
- t.m_week = (byte)week;
- t.m_month = (byte)month;
-
- return t;
+ return new TransitionTime(timeOfDay, month, week, 1, dayOfWeek, isFixedDateRule: false);
}
@@ -4930,33 +4880,33 @@ namespace System {
DayOfWeek dayOfWeek) {
if (timeOfDay.Kind != DateTimeKind.Unspecified) {
- throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeKindMustBeUnspecified"), "timeOfDay");
+ throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeKindMustBeUnspecified"), nameof(timeOfDay));
}
// Month range 1-12
if (month < 1 || month > 12) {
- throw new ArgumentOutOfRangeException("month", Environment.GetResourceString("ArgumentOutOfRange_MonthParam"));
+ throw new ArgumentOutOfRangeException(nameof(month), Environment.GetResourceString("ArgumentOutOfRange_MonthParam"));
}
// Day range 1-31
if (day < 1 || day > 31) {
- throw new ArgumentOutOfRangeException("day", Environment.GetResourceString("ArgumentOutOfRange_DayParam"));
+ throw new ArgumentOutOfRangeException(nameof(day), Environment.GetResourceString("ArgumentOutOfRange_DayParam"));
}
// Week range 1-5
if (week < 1 || week > 5) {
- throw new ArgumentOutOfRangeException("week", Environment.GetResourceString("ArgumentOutOfRange_Week"));
+ throw new ArgumentOutOfRangeException(nameof(week), Environment.GetResourceString("ArgumentOutOfRange_Week"));
}
// DayOfWeek range 0-6
if ((int)dayOfWeek < 0 || (int)dayOfWeek > 6) {
- throw new ArgumentOutOfRangeException("dayOfWeek", Environment.GetResourceString("ArgumentOutOfRange_DayOfWeek"));
+ throw new ArgumentOutOfRangeException(nameof(dayOfWeek), Environment.GetResourceString("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"), "timeOfDay");
+ throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeHasTicks"), nameof(timeOfDay));
}
}
@@ -4973,10 +4923,9 @@ namespace System {
}
- [System.Security.SecurityCritical] // auto-generated_required
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) {
if (info == null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
@@ -4990,7 +4939,7 @@ namespace System {
TransitionTime(SerializationInfo info, StreamingContext context) {
if (info == null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
m_timeOfDay = (DateTime)info.GetValue("TimeOfDay", typeof(DateTime));
@@ -5125,7 +5074,7 @@ namespace System {
AdjustmentRule[] rules = s.GetNextAdjustmentRuleArrayValue(false);
try {
- return TimeZoneInfo.CreateCustomTimeZone(id, baseUtcOffset, displayName, standardName, daylightName, rules);
+ return new TimeZoneInfo(id, baseUtcOffset, displayName, standardName, daylightName, rules, disableDaylightSavingTime: false);
}
catch (ArgumentException ex) {
throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"), ex);
@@ -5653,14 +5602,6 @@ namespace System {
}
}
- private class TimeZoneInfoComparer : System.Collections.Generic.IComparer<TimeZoneInfo> {
- int System.Collections.Generic.IComparer<TimeZoneInfo>.Compare(TimeZoneInfo x, TimeZoneInfo y) {
- // sort by BaseUtcOffset first and by DisplayName second - this is similar to the Windows Date/Time control panel
- int comparison = x.BaseUtcOffset.CompareTo(y.BaseUtcOffset);
- return comparison == 0 ? String.Compare(x.DisplayName, y.DisplayName, StringComparison.Ordinal) : comparison;
- }
- }
-
#if PLATFORM_UNIX
private struct TZifType
{
@@ -5681,7 +5622,7 @@ namespace System {
{
if (data == null || data.Length < index + c_len)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_TimeZoneInfoInvalidTZif"), "data");
+ throw new ArgumentException(Environment.GetResourceString("Argument_TimeZoneInfoInvalidTZif"), nameof(data));
}
Contract.EndContractBlock();
UtcOffset = new TimeSpan(0, 0, TZif_ToInt32(data, index + 00));
@@ -5705,7 +5646,7 @@ namespace System {
{
if (data == null || data.Length < c_len)
{
- throw new ArgumentException("bad data", "data");
+ throw new ArgumentException("bad data", nameof(data));
}
Contract.EndContractBlock();
@@ -5714,7 +5655,7 @@ namespace System {
if (Magic != 0x545A6966)
{
// 0x545A6966 = {0x54, 0x5A, 0x69, 0x66} = "TZif"
- throw new ArgumentException(Environment.GetResourceString("Argument_TimeZoneInfoBadTZif"), "data");
+ throw new ArgumentException(Environment.GetResourceString("Argument_TimeZoneInfoBadTZif"), nameof(data));
}
byte version = data[index + 04];
diff --git a/src/mscorlib/src/System/TimeZoneNotFoundException.cs b/src/mscorlib/src/System/TimeZoneNotFoundException.cs
index 5f8b919a76..cabcc150f6 100644
--- a/src/mscorlib/src/System/TimeZoneNotFoundException.cs
+++ b/src/mscorlib/src/System/TimeZoneNotFoundException.cs
@@ -7,9 +7,6 @@ namespace System {
using System.Runtime.CompilerServices;
[Serializable]
-#if !FEATURE_CORECLR
- [TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
-#endif
[System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
public class TimeZoneNotFoundException : Exception {
public TimeZoneNotFoundException(String message)
diff --git a/src/mscorlib/src/System/Tuple.cs b/src/mscorlib/src/System/Tuple.cs
index 99164bc654..037b2ceee8 100644
--- a/src/mscorlib/src/System/Tuple.cs
+++ b/src/mscorlib/src/System/Tuple.cs
@@ -5,8 +5,13 @@ using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
+//
+// Note: F# compiler depends on the exact tuple hashing algorithm. Do not ever change it.
+//
+
namespace System {
/// <summary>
@@ -119,7 +124,7 @@ namespace System {
Tuple<T1> objTuple = other as Tuple<T1>;
if (objTuple == null) {
- throw new ArgumentException(Environment.GetResourceString("ArgumentException_TupleIncorrectType", this.GetType().ToString()), "other");
+ throw new ArgumentException(Environment.GetResourceString("ArgumentException_TupleIncorrectType", this.GetType().ToString()), nameof(other));
}
return comparer.Compare(m_Item1, objTuple.m_Item1);
@@ -195,7 +200,7 @@ namespace System {
Tuple<T1, T2> objTuple = other as Tuple<T1, T2>;
if (objTuple == null) {
- throw new ArgumentException(Environment.GetResourceString("ArgumentException_TupleIncorrectType", this.GetType().ToString()), "other");
+ throw new ArgumentException(Environment.GetResourceString("ArgumentException_TupleIncorrectType", this.GetType().ToString()), nameof(other));
}
int c = 0;
@@ -282,7 +287,7 @@ namespace System {
Tuple<T1, T2, T3> objTuple = other as Tuple<T1, T2, T3>;
if (objTuple == null) {
- throw new ArgumentException(Environment.GetResourceString("ArgumentException_TupleIncorrectType", this.GetType().ToString()), "other");
+ throw new ArgumentException(Environment.GetResourceString("ArgumentException_TupleIncorrectType", this.GetType().ToString()), nameof(other));
}
int c = 0;
@@ -378,7 +383,7 @@ namespace System {
Tuple<T1, T2, T3, T4> objTuple = other as Tuple<T1, T2, T3, T4>;
if (objTuple == null) {
- throw new ArgumentException(Environment.GetResourceString("ArgumentException_TupleIncorrectType", this.GetType().ToString()), "other");
+ throw new ArgumentException(Environment.GetResourceString("ArgumentException_TupleIncorrectType", this.GetType().ToString()), nameof(other));
}
int c = 0;
@@ -483,7 +488,7 @@ namespace System {
Tuple<T1, T2, T3, T4, T5> objTuple = other as Tuple<T1, T2, T3, T4, T5>;
if (objTuple == null) {
- throw new ArgumentException(Environment.GetResourceString("ArgumentException_TupleIncorrectType", this.GetType().ToString()), "other");
+ throw new ArgumentException(Environment.GetResourceString("ArgumentException_TupleIncorrectType", this.GetType().ToString()), nameof(other));
}
int c = 0;
@@ -597,7 +602,7 @@ namespace System {
Tuple<T1, T2, T3, T4, T5, T6> objTuple = other as Tuple<T1, T2, T3, T4, T5, T6>;
if (objTuple == null) {
- throw new ArgumentException(Environment.GetResourceString("ArgumentException_TupleIncorrectType", this.GetType().ToString()), "other");
+ throw new ArgumentException(Environment.GetResourceString("ArgumentException_TupleIncorrectType", this.GetType().ToString()), nameof(other));
}
int c = 0;
@@ -720,7 +725,7 @@ namespace System {
Tuple<T1, T2, T3, T4, T5, T6, T7> objTuple = other as Tuple<T1, T2, T3, T4, T5, T6, T7>;
if (objTuple == null) {
- throw new ArgumentException(Environment.GetResourceString("ArgumentException_TupleIncorrectType", this.GetType().ToString()), "other");
+ throw new ArgumentException(Environment.GetResourceString("ArgumentException_TupleIncorrectType", this.GetType().ToString()), nameof(other));
}
int c = 0;
@@ -856,7 +861,7 @@ namespace System {
Tuple<T1, T2, T3, T4, T5, T6, T7, TRest> objTuple = other as Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>;
if (objTuple == null) {
- throw new ArgumentException(Environment.GetResourceString("ArgumentException_TupleIncorrectType", this.GetType().ToString()), "other");
+ throw new ArgumentException(Environment.GetResourceString("ArgumentException_TupleIncorrectType", this.GetType().ToString()), nameof(other));
}
int c = 0;
@@ -919,7 +924,7 @@ namespace System {
case 7:
return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item1), comparer.GetHashCode(m_Item2), comparer.GetHashCode(m_Item3), comparer.GetHashCode(m_Item4), comparer.GetHashCode(m_Item5), comparer.GetHashCode(m_Item6), comparer.GetHashCode(m_Item7), t.GetHashCode(comparer));
}
- Contract.Assert(false, "Missed all cases for computing Tuple hash code");
+ Debug.Assert(false, "Missed all cases for computing Tuple hash code");
return -1;
}
diff --git a/src/mscorlib/src/System/Type.cs b/src/mscorlib/src/System/Type.cs
index 730003307a..2d30c4c7f2 100644
--- a/src/mscorlib/src/System/Type.cs
+++ b/src/mscorlib/src/System/Type.cs
@@ -9,8 +9,8 @@
//
// ======================================================================================
-namespace System {
-
+namespace System
+{
using System;
using System.Reflection;
using System.Threading;
@@ -154,7 +154,6 @@ namespace System {
// param progID: the progID of the class to retrieve
// returns: the class object associated to the progID
////
- [System.Security.SecurityCritical] // auto-generated_required
public static Type GetTypeFromProgID(String progID)
{
return RuntimeType.GetTypeFromProgIDImpl(progID, null, false);
@@ -169,19 +168,16 @@ namespace System {
// param progID: the progID of the class to retrieve
// returns: the class object associated to the progID
////
- [System.Security.SecurityCritical] // auto-generated_required
public static Type GetTypeFromProgID(String progID, bool throwOnError)
{
return RuntimeType.GetTypeFromProgIDImpl(progID, null, throwOnError);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static Type GetTypeFromProgID(String progID, String server)
{
return RuntimeType.GetTypeFromProgIDImpl(progID, server, false);
}
- [System.Security.SecurityCritical] // auto-generated_required
public static Type GetTypeFromProgID(String progID, String server, bool throwOnError)
{
return RuntimeType.GetTypeFromProgIDImpl(progID, server, throwOnError);
@@ -194,25 +190,21 @@ namespace System {
// param CLSID: the CLSID of the class to retrieve
// returns: the class object associated to the CLSID
////
- [System.Security.SecuritySafeCritical] // auto-generated
public static Type GetTypeFromCLSID(Guid clsid)
{
return RuntimeType.GetTypeFromCLSIDImpl(clsid, null, false);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static Type GetTypeFromCLSID(Guid clsid, bool throwOnError)
{
return RuntimeType.GetTypeFromCLSIDImpl(clsid, null, throwOnError);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static Type GetTypeFromCLSID(Guid clsid, String server)
{
return RuntimeType.GetTypeFromCLSIDImpl(clsid, server, false);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public static Type GetTypeFromCLSID(Guid clsid, String server, bool throwOnError)
{
return RuntimeType.GetTypeFromCLSIDImpl(clsid, server, throwOnError);
@@ -338,12 +330,10 @@ namespace System {
}
// Given a class handle, this will return the class for that handle.
- [System.Security.SecurityCritical]
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern RuntimeType GetTypeFromHandleUnsafe(IntPtr handle);
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern Type GetTypeFromHandle(RuntimeTypeHandle handle);
@@ -395,11 +385,11 @@ namespace System {
{
// Must provide some types (Type[0] for nothing)
if (types == null)
- throw new ArgumentNullException("types");
+ throw new ArgumentNullException(nameof(types));
Contract.EndContractBlock();
for (int i=0;i<types.Length;i++)
if (types[i] == null)
- throw new ArgumentNullException("types");
+ throw new ArgumentNullException(nameof(types));
return GetConstructorImpl(bindingAttr, binder, callConvention, types, modifiers);
}
@@ -407,11 +397,11 @@ namespace System {
public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
{
if (types == null)
- throw new ArgumentNullException("types");
+ throw new ArgumentNullException(nameof(types));
Contract.EndContractBlock();
for (int i=0;i<types.Length;i++)
if (types[i] == null)
- throw new ArgumentNullException("types");
+ throw new ArgumentNullException(nameof(types));
return GetConstructorImpl(bindingAttr, binder, CallingConventions.Any, types, modifiers);
}
@@ -464,13 +454,13 @@ namespace System {
ParameterModifier[] modifiers)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (types == null)
- throw new ArgumentNullException("types");
+ throw new ArgumentNullException(nameof(types));
Contract.EndContractBlock();
for (int i = 0; i < types.Length; i++)
if (types[i] == null)
- throw new ArgumentNullException("types");
+ throw new ArgumentNullException(nameof(types));
return GetMethodImpl(name, bindingAttr, binder, callConvention, types, modifiers);
}
@@ -481,46 +471,46 @@ namespace System {
ParameterModifier[] modifiers)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (types == null)
- throw new ArgumentNullException("types");
+ throw new ArgumentNullException(nameof(types));
Contract.EndContractBlock();
for (int i = 0; i < types.Length; i++)
if (types[i] == null)
- throw new ArgumentNullException("types");
+ 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("name");
+ throw new ArgumentNullException(nameof(name));
if (types == null)
- throw new ArgumentNullException("types");
+ throw new ArgumentNullException(nameof(types));
Contract.EndContractBlock();
for (int i=0;i<types.Length;i++)
if (types[i] == null)
- throw new ArgumentNullException("types");
+ 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("name");
+ throw new ArgumentNullException(nameof(name));
if (types == null)
- throw new ArgumentNullException("types");
+ throw new ArgumentNullException(nameof(types));
Contract.EndContractBlock();
for (int i=0;i<types.Length;i++)
if (types[i] == null)
- throw new ArgumentNullException("types");
+ 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("name");
+ throw new ArgumentNullException(nameof(name));
Contract.EndContractBlock();
return GetMethodImpl(name, bindingAttr, null, CallingConventions.Any, null, null);
}
@@ -528,7 +518,7 @@ namespace System {
public MethodInfo GetMethod(String name)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
Contract.EndContractBlock();
return GetMethodImpl(name, Type.DefaultLookup, null, CallingConventions.Any, null, null);
}
@@ -584,7 +574,7 @@ namespace System {
public virtual Type[] FindInterfaces(TypeFilter filter,Object filterCriteria)
{
if (filter == null)
- throw new ArgumentNullException("filter");
+ throw new ArgumentNullException(nameof(filter));
Contract.EndContractBlock();
Type[] c = GetInterfaces();
int cnt = 0;
@@ -631,9 +621,9 @@ namespace System {
Type returnType, Type[] types, ParameterModifier[] modifiers)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (types == null)
- throw new ArgumentNullException("types");
+ throw new ArgumentNullException(nameof(types));
Contract.EndContractBlock();
return GetPropertyImpl(name,bindingAttr,binder,returnType,types,modifiers);
}
@@ -641,9 +631,9 @@ namespace System {
public PropertyInfo GetProperty(String name, Type returnType, Type[] types,ParameterModifier[] modifiers)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (types == null)
- throw new ArgumentNullException("types");
+ throw new ArgumentNullException(nameof(types));
Contract.EndContractBlock();
return GetPropertyImpl(name,Type.DefaultLookup,null,returnType,types,modifiers);
}
@@ -651,7 +641,7 @@ namespace System {
public PropertyInfo GetProperty(String name, BindingFlags bindingAttr)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
Contract.EndContractBlock();
return GetPropertyImpl(name,bindingAttr,null,null,null,null);
}
@@ -659,9 +649,9 @@ namespace System {
public PropertyInfo GetProperty(String name, Type returnType, Type[] types)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (types == null)
- throw new ArgumentNullException("types");
+ throw new ArgumentNullException(nameof(types));
Contract.EndContractBlock();
return GetPropertyImpl(name,Type.DefaultLookup,null,returnType,types,null);
}
@@ -669,9 +659,9 @@ namespace System {
public PropertyInfo GetProperty(String name, Type[] types)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (types == null)
- throw new ArgumentNullException("types");
+ throw new ArgumentNullException(nameof(types));
Contract.EndContractBlock();
return GetPropertyImpl(name,Type.DefaultLookup,null,null,types,null);
}
@@ -679,9 +669,9 @@ namespace System {
public PropertyInfo GetProperty(String name, Type returnType)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (returnType == null)
- throw new ArgumentNullException("returnType");
+ throw new ArgumentNullException(nameof(returnType));
Contract.EndContractBlock();
return GetPropertyImpl(name,Type.DefaultLookup,null,returnType,null,null);
}
@@ -689,9 +679,9 @@ namespace System {
internal PropertyInfo GetProperty(String name, BindingFlags bindingAttr, Type returnType)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
if (returnType == null)
- throw new ArgumentNullException("returnType");
+ throw new ArgumentNullException(nameof(returnType));
Contract.EndContractBlock();
return GetPropertyImpl(name, bindingAttr, null, returnType, null, null);
}
@@ -699,7 +689,7 @@ namespace System {
public PropertyInfo GetProperty(String name)
{
if (name == null)
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
Contract.EndContractBlock();
return GetPropertyImpl(name,Type.DefaultLookup,null,null,null,null);
}
@@ -716,8 +706,7 @@ namespace System {
{
return GetProperties(Type.DefaultLookup);
}
-#if !FEATURE_CORECLR
-#endif
+
// GetNestedTypes()
// This set of method will return any nested types that are found inside
// of the type.
@@ -728,9 +717,6 @@ namespace System {
abstract public Type[] GetNestedTypes(BindingFlags bindingAttr);
-#if !FEATURE_CORECLR
- // GetNestedType()
-#endif
public Type GetNestedType(String name)
{
return GetNestedType(name,Type.DefaultLookup);
@@ -1050,7 +1036,6 @@ namespace System {
public bool IsInterface {
[Pure]
- [System.Security.SecuritySafeCritical] // auto-generated
get
{
RuntimeType rt = this as RuntimeType;
@@ -1076,11 +1061,7 @@ namespace System {
get {return ((GetAttributeFlagsImpl() & TypeAttributes.Sealed) != 0);}
}
-#if FEATURE_CORECLR
- public bool IsEnum {
-#else
public virtual bool IsEnum {
-#endif
[Pure]
get
{
@@ -1305,14 +1286,15 @@ namespace System {
// Protected routine to determine if this class is contextful
- protected virtual bool IsContextfulImpl(){
- return typeof(ContextBoundObject).IsAssignableFrom(this);
+ protected virtual bool IsContextfulImpl()
+ {
+ return false;
}
-
// Protected routine to determine if this class is marshaled by ref
- protected virtual bool IsMarshalByRefImpl(){
- return typeof(MarshalByRefObject).IsAssignableFrom(this);
+ protected virtual bool IsMarshalByRefImpl()
+ {
+ return false;
}
internal virtual bool HasProxyAttributeImpl()
@@ -1362,7 +1344,7 @@ namespace System {
return rootElementType;
}
- #region Enum methods
+#region Enum methods
// Default implementations of GetEnumNames, GetEnumValues, and GetEnumUnderlyingType
// Subclass of types can override these methods.
@@ -1465,7 +1447,7 @@ namespace System {
public virtual bool IsEnumDefined(object value)
{
if (value == null)
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
if (!IsEnum)
throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
@@ -1513,7 +1495,7 @@ namespace System {
public virtual string GetEnumName(object value)
{
if (value == null)
- throw new ArgumentNullException("value");
+ throw new ArgumentNullException(nameof(value));
if (!IsEnum)
throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
@@ -1522,7 +1504,7 @@ namespace System {
Type valueType = value.GetType();
if (!(valueType.IsEnum || Type.IsIntegerType(valueType)))
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnumBaseTypeOrEnum"), "value");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnumBaseTypeOrEnum"), nameof(value));
Array values = GetEnumRawConstantValues();
int index = BinarySearch(values, value);
@@ -1561,7 +1543,7 @@ namespace System {
t == typeof(char) ||
t == typeof(bool));
}
- #endregion
+#endregion
public virtual bool IsSecurityCritical { [Pure] get { throw new NotImplementedException(); } }
@@ -1743,7 +1725,7 @@ namespace System {
// types.
public static Type[] GetTypeArray(Object[] args) {
if (args == null)
- throw new ArgumentNullException("args");
+ throw new ArgumentNullException(nameof(args));
Contract.EndContractBlock();
Type[] cls = new Type[args.Length];
for (int i = 0;i < cls.Length;i++)
@@ -1766,11 +1748,7 @@ namespace System {
// _Type.Equals(Type)
[Pure]
-#if !FEATURE_CORECLR
public virtual bool Equals(Type o)
-#else
- public bool Equals(Type o)
-#endif
{
if ((object)o == null)
return false;
@@ -1778,12 +1756,10 @@ namespace System {
return (Object.ReferenceEquals(this.UnderlyingSystemType, o.UnderlyingSystemType));
}
- [System.Security.SecuritySafeCritical]
[Pure]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern bool operator ==(Type left, Type right);
- [System.Security.SecuritySafeCritical]
[Pure]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern bool operator !=(Type left, Type right);
@@ -1814,30 +1790,6 @@ namespace System {
return base.GetType();
}
-#if !FEATURE_CORECLR
- void _Type.GetTypeInfoCount(out uint pcTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _Type.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
- {
- throw new NotImplementedException();
- }
-
- void _Type.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
- {
- throw new NotImplementedException();
- }
-
- // If you implement this method, make sure to include _Type.Invoke in VM\DangerousAPIs.h and
- // include _Type in SystemDomain::IsReflectionInvocationMethod in AppDomain.cpp.
- void _Type.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
- {
- throw new NotImplementedException();
- }
-#endif
-
// 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/TypeInitializationException.cs b/src/mscorlib/src/System/TypeInitializationException.cs
index 62d189d53b..bcc1c3e968 100644
--- a/src/mscorlib/src/System/TypeInitializationException.cs
+++ b/src/mscorlib/src/System/TypeInitializationException.cs
@@ -56,7 +56,6 @@ namespace System {
}
}
- [System.Security.SecurityCritical] // auto-generated_required
public override void GetObjectData(SerializationInfo info, StreamingContext context) {
base.GetObjectData(info, context);
info.AddValue("TypeName",TypeName,typeof(String));
diff --git a/src/mscorlib/src/System/TypeLoadException.cs b/src/mscorlib/src/System/TypeLoadException.cs
index 9b5d28dfba..d73a97f9c5 100644
--- a/src/mscorlib/src/System/TypeLoadException.cs
+++ b/src/mscorlib/src/System/TypeLoadException.cs
@@ -44,14 +44,12 @@ namespace System {
public override String Message
{
- [System.Security.SecuritySafeCritical] // auto-generated
get {
SetMessageField();
return _message;
}
}
- [System.Security.SecurityCritical] // auto-generated
private void SetMessageField()
{
if (_message == null) {
@@ -83,7 +81,6 @@ namespace System {
}
// This is called from inside the EE.
- [System.Security.SecurityCritical] // auto-generated
private TypeLoadException(String className,
String assemblyName,
String messageArg,
@@ -103,7 +100,7 @@ namespace System {
protected TypeLoadException(SerializationInfo info, StreamingContext context) : base(info, context) {
if (info == null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
ClassName = info.GetString("TypeLoadClassName");
@@ -112,17 +109,15 @@ namespace System {
ResourceId = info.GetInt32("TypeLoadResourceID");
}
- [System.Security.SecurityCritical] // auto-generated
[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.
- [System.Security.SecurityCritical] // auto-generated_required
public override void GetObjectData(SerializationInfo info, StreamingContext context) {
if (info == null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
base.GetObjectData(info, context);
diff --git a/src/mscorlib/src/System/TypeNameParser.cs b/src/mscorlib/src/System/TypeNameParser.cs
index fee0f3aa64..844578210f 100644
--- a/src/mscorlib/src/System/TypeNameParser.cs
+++ b/src/mscorlib/src/System/TypeNameParser.cs
@@ -2,6 +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.Diagnostics;
using System.Diagnostics.Contracts;
using System.IO;
using System.Reflection;
@@ -15,11 +16,9 @@ using Microsoft.Win32.SafeHandles;
namespace System
{
- [SecurityCritical]
internal class SafeTypeNameParserHandle : SafeHandleZeroOrMinusOneIsInvalid
{
#region QCalls
- [SecurityCritical]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void _ReleaseTypeNameParser(IntPtr pTypeNameParser);
@@ -30,7 +29,6 @@ namespace System
{
}
- [SecurityCritical]
protected override bool ReleaseHandle()
{
_ReleaseTypeNameParser(handle);
@@ -42,34 +40,28 @@ namespace System
internal sealed class TypeNameParser : IDisposable
{
#region QCalls
- [SecurityCritical]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void _CreateTypeNameParser(string typeName, ObjectHandleOnStack retHandle, bool throwOnError);
- [SecurityCritical]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void _GetNames(SafeTypeNameParserHandle pTypeNameParser, ObjectHandleOnStack retArray);
- [SecurityCritical]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void _GetTypeArguments(SafeTypeNameParserHandle pTypeNameParser, ObjectHandleOnStack retArray);
- [SecurityCritical]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void _GetModifiers(SafeTypeNameParserHandle pTypeNameParser, ObjectHandleOnStack retArray);
- [SecurityCritical]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void _GetAssemblyName(SafeTypeNameParserHandle pTypeNameParser, StringHandleOnStack retString);
#endregion
#region Static Members
- [SecuritySafeCritical]
internal static Type GetType(
string typeName,
Func<AssemblyName, Assembly> assemblyResolver,
@@ -79,7 +71,7 @@ namespace System
ref StackCrawlMark stackMark)
{
if (typeName == null)
- throw new ArgumentNullException("typeName");
+ throw new ArgumentNullException(nameof(typeName));
if (typeName.Length > 0 && typeName[0] == '\0')
throw new ArgumentException(Environment.GetResourceString("Format_StringZeroLength"));
Contract.EndContractBlock();
@@ -103,19 +95,16 @@ namespace System
#endregion
#region Private Data Members
- [SecurityCritical]
private SafeTypeNameParserHandle m_NativeParser;
private static readonly char[] SPECIAL_CHARS = {',', '[', ']', '&', '*', '+', '\\'}; /* see typeparse.h */
#endregion
#region Constructor and Disposer
- [SecuritySafeCritical]
private TypeNameParser(SafeTypeNameParserHandle handle)
{
m_NativeParser = handle;
}
- [SecuritySafeCritical]
public void Dispose()
{
m_NativeParser.Dispose();
@@ -123,7 +112,6 @@ namespace System
#endregion
#region private Members
- [SecuritySafeCritical]
private unsafe Type ConstructType(
Func<AssemblyName, Assembly> assemblyResolver,
Func<Assembly, string, bool, Type> typeResolver,
@@ -136,7 +124,7 @@ namespace System
string asmName = GetAssemblyName();
// GetAssemblyName never returns null
- Contract.Assert(asmName != null);
+ Debug.Assert(asmName != null);
if (asmName.Length > 0)
{
@@ -164,7 +152,7 @@ namespace System
if (baseType == null)
{
// Cannot resolve the type. If throwOnError is true we should have already thrown.
- Contract.Assert(throwOnError == false);
+ Debug.Assert(throwOnError == false);
return null;
}
@@ -176,7 +164,7 @@ namespace System
types = new Type[typeArguments.Length];
for (int i = 0; i < typeArguments.Length; i++)
{
- Contract.Assert(typeArguments[i] != null);
+ Debug.Assert(typeArguments[i] != null);
using (TypeNameParser argParser = new TypeNameParser(typeArguments[i]))
{
@@ -186,7 +174,7 @@ namespace System
if (types[i] == null)
{
// If throwOnError is true argParser.ConstructType should have already thrown.
- Contract.Assert(throwOnError == false);
+ Debug.Assert(throwOnError == false);
return null;
}
}
@@ -201,7 +189,6 @@ namespace System
}
}
- [SecuritySafeCritical]
private static Assembly ResolveAssembly(string asmName, Func<AssemblyName, Assembly> assemblyResolver, bool throwOnError, ref StackCrawlMark stackMark)
{
Contract.Requires(asmName != null && asmName.Length > 0);
@@ -316,7 +303,6 @@ namespace System
return StringBuilderCache.GetStringAndRelease(sb);
}
- [SecuritySafeCritical]
private static SafeTypeNameParserHandle CreateTypeNameParser(string typeName, bool throwOnError)
{
SafeTypeNameParserHandle retHandle = null;
@@ -325,7 +311,6 @@ namespace System
return retHandle;
}
- [SecuritySafeCritical]
private string[] GetNames()
{
string[] names = null;
@@ -334,7 +319,6 @@ namespace System
return names;
}
- [SecuritySafeCritical]
private SafeTypeNameParserHandle[] GetTypeArguments()
{
SafeTypeNameParserHandle[] arguments = null;
@@ -343,7 +327,6 @@ namespace System
return arguments;
}
- [SecuritySafeCritical]
private int[] GetModifiers()
{
int[] modifiers = null;
@@ -352,7 +335,6 @@ namespace System
return modifiers;
}
- [SecuritySafeCritical]
private string GetAssemblyName()
{
string assemblyName = null;
diff --git a/src/mscorlib/src/System/TypedReference.cs b/src/mscorlib/src/System/TypedReference.cs
index 7c68c4164f..b65652e590 100644
--- a/src/mscorlib/src/System/TypedReference.cs
+++ b/src/mscorlib/src/System/TypedReference.cs
@@ -23,13 +23,12 @@ namespace System {
private IntPtr Value;
private IntPtr Type;
- [System.Security.SecurityCritical] // auto-generated_required
[CLSCompliant(false)]
public static TypedReference MakeTypedReference(Object target, FieldInfo[] flds) {
if (target == null)
- throw new ArgumentNullException("target");
+ throw new ArgumentNullException(nameof(target));
if (flds == null)
- throw new ArgumentNullException("flds");
+ throw new ArgumentNullException(nameof(flds));
Contract.EndContractBlock();
if (flds.Length == 0)
throw new ArgumentException(Environment.GetResourceString("Arg_ArrayZeroError"));
@@ -71,7 +70,6 @@ namespace System {
return result;
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
// reference to TypedReference is banned, so have to pass result as pointer
private unsafe static extern void InternalMakeTypedReference(void* result, Object target, IntPtr[] flds, RuntimeType lastFieldType);
@@ -89,13 +87,11 @@ namespace System {
throw new NotSupportedException(Environment.GetResourceString("NotSupported_NYI"));
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe static Object ToObject(TypedReference value)
{
return InternalToObject(&value);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal unsafe extern static Object InternalToObject(void * value);
@@ -118,14 +114,12 @@ namespace System {
}
// This may cause the type to be changed.
- [System.Security.SecuritySafeCritical] // auto-generated
[CLSCompliant(false)]
public unsafe static void SetTypedReference(TypedReference target, Object value)
{
InternalSetTypedReference(&target, value);
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
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 dba7f97b77..399ef02d7d 100644
--- a/src/mscorlib/src/System/UInt16.cs
+++ b/src/mscorlib/src/System/UInt16.cs
@@ -68,26 +68,22 @@ namespace System {
}
// Converts the current value to a String in base-10 with no extra padding.
- [System.Security.SecuritySafeCritical] // auto-generated
public override String ToString() {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatUInt32(m_value, null, NumberFormatInfo.CurrentInfo);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(IFormatProvider provider) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatUInt32(m_value, null, NumberFormatInfo.GetInstance(provider));
}
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(String format) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatUInt32(m_value, format, NumberFormatInfo.CurrentInfo);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(String format, IFormatProvider provider) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatUInt32(m_value, format, NumberFormatInfo.GetInstance(provider));
diff --git a/src/mscorlib/src/System/UInt32.cs b/src/mscorlib/src/System/UInt32.cs
index 7010daec43..f3d60092f7 100644
--- a/src/mscorlib/src/System/UInt32.cs
+++ b/src/mscorlib/src/System/UInt32.cs
@@ -79,25 +79,21 @@ namespace System {
}
// The base 10 representation of the number with no extra padding.
- [System.Security.SecuritySafeCritical] // auto-generated
public override String ToString() {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatUInt32(m_value, null, NumberFormatInfo.CurrentInfo);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(IFormatProvider provider) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatUInt32(m_value, null, NumberFormatInfo.GetInstance(provider));
}
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(String format) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatUInt32(m_value, format, NumberFormatInfo.CurrentInfo);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(String format, IFormatProvider provider) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatUInt32(m_value, format, NumberFormatInfo.GetInstance(provider));
diff --git a/src/mscorlib/src/System/UInt64.cs b/src/mscorlib/src/System/UInt64.cs
index 83549cf423..b55cd7ce6a 100644
--- a/src/mscorlib/src/System/UInt64.cs
+++ b/src/mscorlib/src/System/UInt64.cs
@@ -75,25 +75,21 @@ namespace System {
return ((int)m_value) ^ (int)(m_value >> 32);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public override String ToString() {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatUInt64(m_value, null, NumberFormatInfo.CurrentInfo);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(IFormatProvider provider) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatUInt64(m_value, null, NumberFormatInfo.GetInstance(provider));
}
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(String format) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatUInt64(m_value, format, NumberFormatInfo.CurrentInfo);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public String ToString(String format, IFormatProvider provider) {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatUInt64(m_value, format, NumberFormatInfo.GetInstance(provider));
diff --git a/src/mscorlib/src/System/UIntPtr.cs b/src/mscorlib/src/System/UIntPtr.cs
index ac3b811b42..eab424fc69 100644
--- a/src/mscorlib/src/System/UIntPtr.cs
+++ b/src/mscorlib/src/System/UIntPtr.cs
@@ -24,20 +24,17 @@ namespace System {
[System.Runtime.InteropServices.ComVisible(true)]
public struct UIntPtr : IEquatable<UIntPtr>, ISerializable
{
- [SecurityCritical]
unsafe private void* m_value;
public static readonly UIntPtr Zero;
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.Versioning.NonVersionable]
public unsafe UIntPtr(uint value)
{
m_value = (void *)value;
}
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.Versioning.NonVersionable]
public unsafe UIntPtr(ulong value)
{
@@ -48,7 +45,6 @@ namespace System {
#endif
}
- [System.Security.SecurityCritical]
[CLSCompliant(false)]
[System.Runtime.Versioning.NonVersionable]
public unsafe UIntPtr(void* value)
@@ -56,7 +52,6 @@ namespace System {
m_value = value;
}
- [System.Security.SecurityCritical] // auto-generated
private unsafe UIntPtr(SerializationInfo info, StreamingContext context) {
ulong l = info.GetUInt64("value");
@@ -67,17 +62,15 @@ namespace System {
m_value = (void *)l;
}
- [System.Security.SecurityCritical]
unsafe void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info==null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
info.AddValue("value", (ulong)m_value);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe override bool Equals(Object obj) {
if (obj is UIntPtr) {
return (m_value == ((UIntPtr)obj).m_value);
@@ -85,27 +78,20 @@ namespace System {
return false;
}
- [SecuritySafeCritical]
unsafe bool IEquatable<UIntPtr>.Equals(UIntPtr other)
{
return m_value == other.m_value;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe override int GetHashCode() {
-#if FEATURE_CORECLR
#if BIT64
ulong l = (ulong)m_value;
return (unchecked((int)l) ^ (int)(l >> 32));
#else // 32
return unchecked((int)m_value);
#endif
-#else
- return unchecked((int)((long)m_value)) & 0x7fffffff;
-#endif
}
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.Versioning.NonVersionable]
public unsafe uint ToUInt32() {
#if BIT64
@@ -115,13 +101,11 @@ namespace System {
#endif
}
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.Versioning.NonVersionable]
public unsafe ulong ToUInt64() {
return (ulong)m_value;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public unsafe override String ToString() {
Contract.Ensures(Contract.Result<String>() != null);
@@ -144,7 +128,6 @@ namespace System {
return new UIntPtr(value);
}
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.Versioning.NonVersionable]
public unsafe static explicit operator uint(UIntPtr value)
{
@@ -155,14 +138,12 @@ namespace System {
#endif
}
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.Versioning.NonVersionable]
public unsafe static explicit operator ulong (UIntPtr value)
{
return (ulong)value.m_value;
}
- [System.Security.SecurityCritical]
[CLSCompliant(false)]
[System.Runtime.Versioning.NonVersionable]
public static unsafe explicit operator UIntPtr (void* value)
@@ -170,7 +151,6 @@ namespace System {
return new UIntPtr(value);
}
- [System.Security.SecurityCritical]
[CLSCompliant(false)]
[System.Runtime.Versioning.NonVersionable]
public static unsafe explicit operator void* (UIntPtr value)
@@ -179,7 +159,6 @@ namespace System {
}
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.Versioning.NonVersionable]
public unsafe static bool operator == (UIntPtr value1, UIntPtr value2)
{
@@ -187,7 +166,6 @@ namespace System {
}
- [System.Security.SecuritySafeCritical] // auto-generated
[System.Runtime.Versioning.NonVersionable]
public unsafe static bool operator != (UIntPtr value1, UIntPtr value2)
{
@@ -235,7 +213,6 @@ namespace System {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
[CLSCompliant(false)]
[System.Runtime.Versioning.NonVersionable]
public unsafe void* ToPointer()
diff --git a/src/mscorlib/src/System/UnSafeCharBuffer.cs b/src/mscorlib/src/System/UnSafeCharBuffer.cs
deleted file mode 100644
index 78059b623a..0000000000
--- a/src/mscorlib/src/System/UnSafeCharBuffer.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: A class to detect incorrect usage of UnSafeBuffer
-**
-**
-===========================================================*/
-
-namespace System {
- using System.Security;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
- unsafe internal struct UnSafeCharBuffer{
- [SecurityCritical]
- char * m_buffer;
- int m_totalSize;
- int m_length;
-
- [System.Security.SecurityCritical] // auto-generated
- public UnSafeCharBuffer( char *buffer, int bufferSize) {
- Contract.Assert( buffer != null, "buffer pointer can't be null." );
- Contract.Assert( bufferSize >= 0, "buffer size can't be negative." );
- m_buffer = buffer;
- m_totalSize = bufferSize;
- m_length = 0;
- }
-
- [System.Security.SecuritySafeCritical] // auto-generated
- public void AppendString(string stringToAppend) {
- if( String.IsNullOrEmpty( stringToAppend ) ) {
- return;
- }
-
- if ( (m_totalSize - m_length) < stringToAppend.Length ) {
- throw new IndexOutOfRangeException();
- }
-
- fixed( char* pointerToString = stringToAppend ) {
- Buffer.Memcpy( (byte*) (m_buffer + m_length), (byte *) pointerToString, stringToAppend.Length * sizeof(char));
- }
-
- m_length += stringToAppend.Length;
- Contract.Assert(m_length <= m_totalSize, "Buffer has been overflowed!");
- }
-
- public int Length {
- get {
- return m_length;
- }
- }
- }
-}
diff --git a/src/mscorlib/src/System/UnhandledExceptionEventHandler.cs b/src/mscorlib/src/System/UnhandledExceptionEventHandler.cs
index 7d6531945e..8c2798230c 100644
--- a/src/mscorlib/src/System/UnhandledExceptionEventHandler.cs
+++ b/src/mscorlib/src/System/UnhandledExceptionEventHandler.cs
@@ -5,9 +5,6 @@
namespace System {
using System;
-#if FEATURE_CORECLR
- [System.Security.SecurityCritical] // auto-generated
-#endif
[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public delegate void UnhandledExceptionEventHandler(Object sender, UnhandledExceptionEventArgs e);
diff --git a/src/mscorlib/src/System/UnitySerializationHolder.cs b/src/mscorlib/src/System/UnitySerializationHolder.cs
index ec32fce348..712391a915 100644
--- a/src/mscorlib/src/System/UnitySerializationHolder.cs
+++ b/src/mscorlib/src/System/UnitySerializationHolder.cs
@@ -166,7 +166,7 @@ namespace System {
internal UnitySerializationHolder(SerializationInfo info, StreamingContext context)
{
if (info == null)
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
m_unityType = info.GetInt32("UnityType");
@@ -204,7 +204,6 @@ namespace System {
#endregion
#region ISerializable
- [System.Security.SecurityCritical] // auto-generated
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnitySerHolder"));
@@ -212,7 +211,6 @@ namespace System {
#endregion
#region IObjectReference
- [System.Security.SecurityCritical] // auto-generated
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
diff --git a/src/mscorlib/src/System/ValueType.cs b/src/mscorlib/src/System/ValueType.cs
index ae08b7d0ba..102a0d2b92 100644
--- a/src/mscorlib/src/System/ValueType.cs
+++ b/src/mscorlib/src/System/ValueType.cs
@@ -20,7 +20,6 @@ namespace System {
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class ValueType {
- [System.Security.SecuritySafeCritical]
public override bool Equals (Object obj) {
BCLDebug.Perf(false, "ValueType::Equals is not fast. "+this.GetType().FullName+" should override Equals(Object)");
if (null==obj) {
@@ -60,11 +59,9 @@ namespace System {
return true;
}
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool CanCompareBits(Object obj);
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool FastEqualsCheck(Object a, Object b);
@@ -78,7 +75,6 @@ namespace System {
**Arguments: None.
**Exceptions: None.
==============================================================================*/
- [System.Security.SecuritySafeCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern override int GetHashCode();
diff --git a/src/mscorlib/src/System/Variant.cs b/src/mscorlib/src/System/Variant.cs
index 26e2e4aa1a..2a9593cf42 100644
--- a/src/mscorlib/src/System/Variant.cs
+++ b/src/mscorlib/src/System/Variant.cs
@@ -19,6 +19,7 @@ namespace System {
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
[Serializable]
@@ -118,19 +119,14 @@ namespace System {
//
// Native Methods
//
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern double GetR8FromVar();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern float GetR4FromVar();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern void SetFieldsR4(float val);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern void SetFieldsR8(double val);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern void SetFieldsObject(Object val);
@@ -224,7 +220,6 @@ namespace System {
m_data2 = (int)(val >> 32);
}
- [System.Security.SecuritySafeCritical] // auto-generated
public Variant(float val) {
m_objref=null;
m_flags=CV_R4;
@@ -233,7 +228,6 @@ namespace System {
SetFieldsR4(val);
}
- [System.Security.SecurityCritical] // auto-generated
public Variant(double val) {
m_objref=null;
m_flags=CV_R8;
@@ -257,7 +251,6 @@ namespace System {
m_data2=0;
}
- [System.Security.SecuritySafeCritical] // auto-generated
public Variant(Object obj) {
m_data1=0;
m_data2=0;
@@ -317,13 +310,13 @@ namespace System {
{
vt = VarEnum.VT_ERROR;
obj = (Object)(((ErrorWrapper)obj).ErrorCode);
- Contract.Assert(obj != null, "obj != null");
+ Debug.Assert(obj != null, "obj != null");
}
else if (obj is CurrencyWrapper)
{
vt = VarEnum.VT_CY;
obj = (Object)(((CurrencyWrapper)obj).WrappedObject);
- Contract.Assert(obj != null, "obj != null");
+ Debug.Assert(obj != null, "obj != null");
}
else if (obj is BStrWrapper)
{
@@ -342,12 +335,11 @@ namespace System {
}
- [System.Security.SecurityCritical] // auto-generated
unsafe public Variant(void* voidPointer,Type pointerType) {
if (pointerType == null)
- throw new ArgumentNullException("pointerType");
+ throw new ArgumentNullException(nameof(pointerType));
if (!pointerType.IsPointer)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBePointer"),"pointerType");
+ throw new ArgumentException(Environment.GetResourceString("Arg_MustBePointer"),nameof(pointerType));
Contract.EndContractBlock();
m_objref = pointerType;
@@ -365,7 +357,6 @@ namespace System {
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
public Object ToObject() {
switch (CVType) {
case CV_EMPTY:
@@ -413,21 +404,16 @@ namespace System {
}
// This routine will return an boxed enum.
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern Object BoxEnum();
// Helper code for marshaling managed objects to VARIANT's (we use
// managed variants as an intermediate type.
- [System.Security.SecuritySafeCritical] // auto-generated
internal static void MarshalHelperConvertObjectToVariant(Object o, ref Variant v)
{
-#if FEATURE_REMOTING
- IConvertible ic = System.Runtime.Remoting.RemotingServices.IsTransparentProxy(o) ? null : o as IConvertible;
-#else
IConvertible ic = o as IConvertible;
-#endif
+
if (o == null)
{
v = Empty;
@@ -532,7 +518,6 @@ namespace System {
// Helper code: on the back propagation path where a VT_BYREF VARIANT*
// is marshaled to a "ref Object", we use this helper to force the
// updated object back to the original type.
- [System.Security.SecurityCritical] // auto-generated
internal static void MarshalHelperCastVariant(Object pValue, int vt, ref Variant v)
{
IConvertible iv = pValue as IConvertible;
diff --git a/src/mscorlib/src/System/Version.cs b/src/mscorlib/src/System/Version.cs
index f3520b81a2..f2ef5d4486 100644
--- a/src/mscorlib/src/System/Version.cs
+++ b/src/mscorlib/src/System/Version.cs
@@ -12,6 +12,7 @@
===========================================================*/
namespace System {
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Text;
using CultureInfo = System.Globalization.CultureInfo;
@@ -29,24 +30,24 @@ namespace System {
, IComparable<Version>, IEquatable<Version>
{
// AssemblyName depends on the order staying the same
- private int _Major;
- private int _Minor;
- private int _Build = -1;
- private int _Revision = -1;
+ private readonly int _Major;
+ private readonly int _Minor;
+ private readonly int _Build = -1;
+ private readonly int _Revision = -1;
private static readonly char[] SeparatorsArray = new char[] { '.' };
public Version(int major, int minor, int build, int revision) {
if (major < 0)
- throw new ArgumentOutOfRangeException("major",Environment.GetResourceString("ArgumentOutOfRange_Version"));
+ throw new ArgumentOutOfRangeException(nameof(major),Environment.GetResourceString("ArgumentOutOfRange_Version"));
if (minor < 0)
- throw new ArgumentOutOfRangeException("minor",Environment.GetResourceString("ArgumentOutOfRange_Version"));
+ throw new ArgumentOutOfRangeException(nameof(minor),Environment.GetResourceString("ArgumentOutOfRange_Version"));
if (build < 0)
- throw new ArgumentOutOfRangeException("build",Environment.GetResourceString("ArgumentOutOfRange_Version"));
+ throw new ArgumentOutOfRangeException(nameof(build),Environment.GetResourceString("ArgumentOutOfRange_Version"));
if (revision < 0)
- throw new ArgumentOutOfRangeException("revision",Environment.GetResourceString("ArgumentOutOfRange_Version"));
+ throw new ArgumentOutOfRangeException(nameof(revision),Environment.GetResourceString("ArgumentOutOfRange_Version"));
Contract.EndContractBlock();
_Major = major;
@@ -57,13 +58,13 @@ namespace System {
public Version(int major, int minor, int build) {
if (major < 0)
- throw new ArgumentOutOfRangeException("major",Environment.GetResourceString("ArgumentOutOfRange_Version"));
+ throw new ArgumentOutOfRangeException(nameof(major),Environment.GetResourceString("ArgumentOutOfRange_Version"));
if (minor < 0)
- throw new ArgumentOutOfRangeException("minor",Environment.GetResourceString("ArgumentOutOfRange_Version"));
+ throw new ArgumentOutOfRangeException(nameof(minor),Environment.GetResourceString("ArgumentOutOfRange_Version"));
if (build < 0)
- throw new ArgumentOutOfRangeException("build",Environment.GetResourceString("ArgumentOutOfRange_Version"));
+ throw new ArgumentOutOfRangeException(nameof(build),Environment.GetResourceString("ArgumentOutOfRange_Version"));
Contract.EndContractBlock();
@@ -74,10 +75,10 @@ namespace System {
public Version(int major, int minor) {
if (major < 0)
- throw new ArgumentOutOfRangeException("major",Environment.GetResourceString("ArgumentOutOfRange_Version"));
+ throw new ArgumentOutOfRangeException(nameof(major),Environment.GetResourceString("ArgumentOutOfRange_Version"));
if (minor < 0)
- throw new ArgumentOutOfRangeException("minor",Environment.GetResourceString("ArgumentOutOfRange_Version"));
+ throw new ArgumentOutOfRangeException(nameof(minor),Environment.GetResourceString("ArgumentOutOfRange_Version"));
Contract.EndContractBlock();
_Major = major;
@@ -98,6 +99,16 @@ namespace System {
_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; }
@@ -124,12 +135,7 @@ namespace System {
}
public Object Clone() {
- Version v = new Version();
- v._Major = _Major;
- v._Minor = _Minor;
- v._Build = _Build;
- v._Revision = _Revision;
- return(v);
+ return new Version(this);
}
public int CompareTo(Object version)
@@ -145,93 +151,33 @@ namespace System {
throw new ArgumentException(Environment.GetResourceString("Arg_MustBeVersion"));
}
- if (this._Major != v._Major)
- if (this._Major > v._Major)
- return 1;
- else
- return -1;
-
- if (this._Minor != v._Minor)
- if (this._Minor > v._Minor)
- return 1;
- else
- return -1;
-
- if (this._Build != v._Build)
- if (this._Build > v._Build)
- return 1;
- else
- return -1;
-
- if (this._Revision != v._Revision)
- if (this._Revision > v._Revision)
- return 1;
- else
- return -1;
-
- return 0;
+ return CompareTo(v);
}
public int CompareTo(Version value)
{
- if (value == null)
- return 1;
-
- if (this._Major != value._Major)
- if (this._Major > value._Major)
- return 1;
- else
- return -1;
-
- if (this._Minor != value._Minor)
- if (this._Minor > value._Minor)
- return 1;
- else
- return -1;
-
- if (this._Build != value._Build)
- if (this._Build > value._Build)
- return 1;
- else
- return -1;
-
- if (this._Revision != value._Revision)
- if (this._Revision > value._Revision)
- return 1;
- else
- return -1;
-
- return 0;
+ 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) {
- Version v = obj as Version;
- if (v == null)
- return false;
-
- // check that major, minor, build & revision numbers match
- if ((this._Major != v._Major) ||
- (this._Minor != v._Minor) ||
- (this._Build != v._Build) ||
- (this._Revision != v._Revision))
- return false;
-
- return true;
+ return Equals(obj as Version);
}
public bool Equals(Version obj)
{
- if (obj == null)
- return false;
-
- // check that major, minor, build & revision numbers match
- if ((this._Major != obj._Major) ||
- (this._Minor != obj._Minor) ||
- (this._Build != obj._Build) ||
- (this._Revision != obj._Revision))
- return false;
-
- return true;
+ 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()
@@ -270,7 +216,7 @@ namespace System {
return StringBuilderCache.GetStringAndRelease(sb);
default:
if (_Build == -1)
- throw new ArgumentException(Environment.GetResourceString("ArgumentOutOfRange_Bounds_Lower_Upper", "0", "2"), "fieldCount");
+ throw new ArgumentException(Environment.GetResourceString("ArgumentOutOfRange_Bounds_Lower_Upper", "0", "2"), nameof(fieldCount));
if (fieldCount == 3)
{
@@ -284,7 +230,7 @@ namespace System {
}
if (_Revision == -1)
- throw new ArgumentException(Environment.GetResourceString("ArgumentOutOfRange_Bounds_Lower_Upper", "0", "3"), "fieldCount");
+ throw new ArgumentException(Environment.GetResourceString("ArgumentOutOfRange_Bounds_Lower_Upper", "0", "3"), nameof(fieldCount));
if (fieldCount == 4)
{
@@ -299,7 +245,7 @@ namespace System {
return StringBuilderCache.GetStringAndRelease(sb);
}
- throw new ArgumentException(Environment.GetResourceString("ArgumentOutOfRange_Bounds_Lower_Upper", "0", "4"), "fieldCount");
+ throw new ArgumentException(Environment.GetResourceString("ArgumentOutOfRange_Bounds_Lower_Upper", "0", "4"), nameof(fieldCount));
}
}
@@ -307,12 +253,12 @@ namespace System {
// 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
+ // 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)
{
- Contract.Assert(num >= 0, "AppendPositiveNumber expect positive numbers");
+ Debug.Assert(num >= 0, "AppendPositiveNumber expect positive numbers");
int index = sb.Length;
int reminder;
@@ -327,12 +273,12 @@ namespace System {
public static Version Parse(string input) {
if (input == null) {
- throw new ArgumentNullException("input");
+ throw new ArgumentNullException(nameof(input));
}
Contract.EndContractBlock();
VersionResult r = new VersionResult();
- r.Init("input", true);
+ r.Init(nameof(input), true);
if (!TryParseVersion(input, ref r)) {
throw r.GetVersionParseException();
}
@@ -341,7 +287,7 @@ namespace System {
public static bool TryParse(string input, out Version result) {
VersionResult r = new VersionResult();
- r.Init("input", false);
+ r.Init(nameof(input), false);
bool b = TryParseVersion(input, ref r);
result = r.m_parsedVersion;
return b;
@@ -362,11 +308,11 @@ namespace System {
return false;
}
- if (!TryParseComponent(parsedComponents[0], "version", ref result, out major)) {
+ if (!TryParseComponent(parsedComponents[0], nameof(version), ref result, out major)) {
return false;
}
- if (!TryParseComponent(parsedComponents[1], "version", ref result, out minor)) {
+ if (!TryParseComponent(parsedComponents[1], nameof(version), ref result, out minor)) {
return false;
}
@@ -423,14 +369,14 @@ namespace System {
public static bool operator <(Version v1, Version v2) {
if ((Object) v1 == null)
- throw new ArgumentNullException("v1");
+ 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("v1");
+ throw new ArgumentNullException(nameof(v1));
Contract.EndContractBlock();
return (v1.CompareTo(v2) <= 0);
}
@@ -491,10 +437,10 @@ namespace System {
} catch (OverflowException e) {
return e;
}
- Contract.Assert(false, "Int32.Parse() did not throw exception but TryParse failed: " + m_exceptionArgument);
+ Debug.Assert(false, "Int32.Parse() did not throw exception but TryParse failed: " + m_exceptionArgument);
return new FormatException(Environment.GetResourceString("Format_InvalidString"));
default:
- Contract.Assert(false, "Unmatched case in Version.GetVersionParseException() for value: " + m_failure);
+ 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 d12ca3e853..d5648527f0 100644
--- a/src/mscorlib/src/System/WeakReference.cs
+++ b/src/mscorlib/src/System/WeakReference.cs
@@ -16,11 +16,10 @@ namespace System {
using System.Security.Permissions;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
+
[System.Runtime.InteropServices.ComVisible(true)]
-#if !FEATURE_CORECLR
- [SecurityPermissionAttribute(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.UnmanagedCode)] // Don't call Object::MemberwiseClone.
-#endif
[Serializable]
public class WeakReference : ISerializable
{
@@ -28,15 +27,12 @@ namespace System {
// This field is not a regular GC handle. It can have a special values that are used to prevent a race condition between setting the target and finalization.
internal IntPtr m_handle;
-
-#if FEATURE_CORECLR
+
// Migrating InheritanceDemands requires this default ctor, so we can mark it SafeCritical
- [SecuritySafeCritical]
protected WeakReference() {
- Contract.Assert(false, "WeakReference's protected default ctor should never be used!");
+ Debug.Assert(false, "WeakReference's protected default ctor should never be used!");
throw new NotImplementedException();
}
-#endif
// Creates a new WeakReference that keeps track of target.
// Assumes a Short Weak Reference (ie TrackResurrection is false.)
@@ -53,7 +49,7 @@ namespace System {
protected WeakReference(SerializationInfo info, StreamingContext context) {
if (info==null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
@@ -68,7 +64,6 @@ namespace System {
//
public extern virtual bool IsAlive {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [SecuritySafeCritical]
get;
}
@@ -85,10 +80,8 @@ namespace System {
//
public extern virtual Object Target {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [SecuritySafeCritical]
get;
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [SecuritySafeCritical]
set;
}
@@ -99,14 +92,12 @@ namespace System {
// This is needed for subclasses deriving from WeakReference, however.
// Additionally, there may be some cases during shutdown when we run this finalizer.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [SecuritySafeCritical]
extern ~WeakReference();
- [SecurityCritical]
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info==null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
info.AddValue("TrackedObject", Target, typeof(Object));
@@ -114,11 +105,9 @@ namespace System {
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [SecuritySafeCritical]
private extern void Create(Object target, bool trackResurrection);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [SecuritySafeCritical]
private extern bool IsTrackResurrection();
}
diff --git a/src/mscorlib/src/System/WeakReferenceOfT.cs b/src/mscorlib/src/System/WeakReferenceOfT.cs
index b8195df6d9..0972e5fb9e 100644
--- a/src/mscorlib/src/System/WeakReferenceOfT.cs
+++ b/src/mscorlib/src/System/WeakReferenceOfT.cs
@@ -46,7 +46,7 @@ namespace System
internal WeakReference(SerializationInfo info, StreamingContext context)
{
if (info == null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
@@ -81,10 +81,8 @@ namespace System
private extern T Target
{
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [SecuritySafeCritical]
get;
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [SecuritySafeCritical]
set;
}
@@ -95,14 +93,12 @@ namespace System
// This is needed for subclasses deriving from WeakReference<T>, however.
// Additionally, there may be some cases during shutdown when we run this finalizer.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [SecuritySafeCritical]
extern ~WeakReference();
- [SecurityCritical]
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null) {
- throw new ArgumentNullException("info");
+ throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
@@ -111,11 +107,9 @@ namespace System
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [SecuritySafeCritical]
private extern void Create(T target, bool trackResurrection);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- [SecuritySafeCritical]
private extern bool IsTrackResurrection();
}
}
diff --git a/src/mscorlib/src/System/_LocalDataStore.cs b/src/mscorlib/src/System/_LocalDataStore.cs
index a3a312f104..a1fa488076 100644
--- a/src/mscorlib/src/System/_LocalDataStore.cs
+++ b/src/mscorlib/src/System/_LocalDataStore.cs
@@ -17,6 +17,7 @@ namespace System {
using System;
using System.Threading;
using System.Runtime.CompilerServices;
+ using System.Diagnostics;
using System.Diagnostics.Contracts;
// Helper class to aid removal of LocalDataStore from the LocalDataStoreMgr
@@ -197,7 +198,6 @@ namespace System {
/*=========================================================================
** Method used to expand the capacity of the local data store.
=========================================================================*/
- [System.Security.SecuritySafeCritical] // auto-generated
private LocalDataStoreElement PopulateElement(LocalDataStoreSlot slot)
{
bool tookLock = false;
@@ -215,7 +215,7 @@ namespace System {
int capacity = m_Manager.GetSlotTableLength();
// Validate that the specified capacity is larger than the current one.
- Contract.Assert(capacity >= m_DataTable.Length, "LocalDataStore corrupted: capacity >= m_DataTable.Length");
+ Debug.Assert(capacity >= m_DataTable.Length, "LocalDataStore corrupted: capacity >= m_DataTable.Length");
// Allocate the new data table.
LocalDataStoreElement[] NewDataTable = new LocalDataStoreElement[capacity];
@@ -228,7 +228,7 @@ namespace System {
}
// Validate that there is enough space in the local data store now
- Contract.Assert(slotIdx < m_DataTable.Length, "LocalDataStore corrupted: slotIdx < m_DataTable.Length");
+ Debug.Assert(slotIdx < m_DataTable.Length, "LocalDataStore corrupted: slotIdx < m_DataTable.Length");
if (m_DataTable[slotIdx] == null)
m_DataTable[slotIdx] = new LocalDataStoreElement(slot.Cookie);
diff --git a/src/mscorlib/src/System/_LocalDataStoreMgr.cs b/src/mscorlib/src/System/_LocalDataStoreMgr.cs
index 615413848d..8f60d6f754 100644
--- a/src/mscorlib/src/System/_LocalDataStoreMgr.cs
+++ b/src/mscorlib/src/System/_LocalDataStoreMgr.cs
@@ -58,7 +58,7 @@ namespace System {
get
{
return m_cookie;
- }
+ }
}
// Release the slot reserved by this object when this object goes away.
@@ -70,8 +70,8 @@ namespace System {
int slot = m_slot;
- // Mark the slot as free.
- m_slot = -1;
+ // Mark the slot as free.
+ m_slot = -1;
mgr.FreeDataSlot(slot, m_cookie);
}
@@ -89,7 +89,6 @@ namespace System {
** list. The initial size of the new store matches the number of slots
** allocated in this manager.
=========================================================================*/
- [System.Security.SecuritySafeCritical] // auto-generated
public LocalDataStoreHolder CreateLocalDataStore()
{
// Create a new local data store.
@@ -115,7 +114,6 @@ namespace System {
/*=========================================================================
* Remove the specified store from the list of managed stores..
=========================================================================*/
- [System.Security.SecuritySafeCritical] // auto-generated
public void DeleteLocalDataStore(LocalDataStore store)
{
bool tookLock = false;
@@ -138,7 +136,6 @@ namespace System {
** an object to prevent clients from manipulating it directly, allowing us
** to make assumptions its integrity.
=========================================================================*/
- [System.Security.SecuritySafeCritical] // auto-generated
public LocalDataStoreSlot AllocateDataSlot()
{
bool tookLock = false;
@@ -208,7 +205,6 @@ namespace System {
/*=========================================================================
** Allocate a slot and associate a name with it.
=========================================================================*/
- [System.Security.SecuritySafeCritical] // auto-generated
public LocalDataStoreSlot AllocateNamedDataSlot(String name)
{
bool tookLock = false;
@@ -235,7 +231,6 @@ namespace System {
** Retrieve the slot associated with a name, allocating it if no such
** association has been defined.
=========================================================================*/
- [System.Security.SecuritySafeCritical] // auto-generated
public LocalDataStoreSlot GetNamedDataSlot(String name)
{
bool tookLock = false;
@@ -264,7 +259,6 @@ namespace System {
** Eliminate the association of a name with a slot. The actual slot will
** be reclaimed when the finalizer for the slot object runs.
=========================================================================*/
- [System.Security.SecuritySafeCritical] // auto-generated
public void FreeNamedDataSlot(String name)
{
bool tookLock = false;
@@ -285,7 +279,6 @@ namespace System {
/*=========================================================================
** Free's a previously allocated data slot on ALL the managed data stores.
=========================================================================*/
- [System.Security.SecuritySafeCritical] // auto-generated
internal void FreeDataSlot(int slot, long cookie)
{
bool tookLock = false;
diff --git a/src/mscorlib/src/System/__ComObject.cs b/src/mscorlib/src/System/__ComObject.cs
index a5923707b6..9f9bac6084 100644
--- a/src/mscorlib/src/System/__ComObject.cs
+++ b/src/mscorlib/src/System/__ComObject.cs
@@ -12,8 +12,8 @@
**
**
===========================================================*/
-namespace System {
-
+namespace System
+{
using System;
using System.Collections;
using System.Threading;
@@ -59,7 +59,6 @@ namespace System {
return base.ToString();
}
- [System.Security.SecurityCritical] // auto-generated
internal IntPtr GetIUnknown(out bool fIsURTAggregated)
{
fIsURTAggregated = !GetType().IsDefined(typeof(ComImportAttribute), false);
@@ -118,7 +117,6 @@ namespace System {
// This method is called from within the EE and releases all the
// cached data for the __ComObject.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated
internal void ReleaseAllData()
{
// Synchronize access to the map.
@@ -154,7 +152,6 @@ namespace System {
// This method is called from within the EE and is used to handle
// calls on methods of event interfaces.
//====================================================================
- [System.Security.SecurityCritical] // auto-generated
internal Object GetEventProvider(RuntimeType t)
{
// Check to see if we already have a cached event provider for this type.
@@ -167,22 +164,16 @@ namespace System {
return EvProvider;
}
- [System.Security.SecurityCritical] // auto-generated
internal int ReleaseSelf()
{
return Marshal.InternalReleaseComObject(this);
}
- [System.Security.SecurityCritical] // auto-generated
internal void FinalReleaseSelf()
{
Marshal.InternalFinalReleaseComObject(this);
}
- [System.Security.SecurityCritical] // auto-generated
-#if !FEATURE_CORECLR
- [ReflectionPermissionAttribute(SecurityAction.Assert, MemberAccess=true)]
-#endif
private Object CreateEventProvider(RuntimeType t)
{
// Create the event provider for the specified type.
diff --git a/src/mscorlib/src/System/cominterfaces.cs b/src/mscorlib/src/System/cominterfaces.cs
index 7d3620a22d..a83943d586 100644
--- a/src/mscorlib/src/System/cominterfaces.cs
+++ b/src/mscorlib/src/System/cominterfaces.cs
@@ -2,23 +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.Globalization;
-using System.IO;
-using System.Reflection;
-using System.Runtime.InteropServices;
-using System.Runtime.Serialization;
-using System.Security.Permissions;
-using System.Security.Policy;
-
namespace System.Runtime.InteropServices
{
[GuidAttribute("03973551-57A1-3900-A2B5-9083E3FF2943")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[CLSCompliant(false)]
[TypeLibImportClassAttribute(typeof(System.Activator))]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface _Activator
{
void GetTypeInfoCount(out uint pcTInfo);
@@ -34,35 +24,17 @@ namespace System.Runtime.InteropServices
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[CLSCompliant(false)]
[TypeLibImportClassAttribute(typeof(System.Attribute))]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface _Attribute
{
-#if !FEATURE_CORECLR
- void GetTypeInfoCount(out uint pcTInfo);
-
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
-
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
-
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
-#endif
}
[GuidAttribute("C281C7F1-4AA9-3517-961A-463CFED57E75")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[CLSCompliant(false)]
[TypeLibImportClassAttribute(typeof(System.Threading.Thread))]
-[System.Runtime.InteropServices.ComVisible(true)]
+ [System.Runtime.InteropServices.ComVisible(true)]
public interface _Thread
{
-#if !FEATURE_CORECLR
- void GetTypeInfoCount(out uint pcTInfo);
-
- void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo);
-
- void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId);
-
- void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr);
-#endif
}
}
diff --git a/src/mscorlib/src/System/mda.cs b/src/mscorlib/src/System/mda.cs
index 089039c73c..f750e99a8b 100644
--- a/src/mscorlib/src/System/mda.cs
+++ b/src/mscorlib/src/System/mda.cs
@@ -18,7 +18,6 @@ namespace System
private static volatile int _captureAllocatedCallStackState;
internal static bool Enabled {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
if (_enabledState == 0) {
if (Mda.IsStreamWriterBufferedDataLostEnabled())
@@ -32,7 +31,6 @@ namespace System
}
internal static bool CaptureAllocatedCallStack {
- [System.Security.SecuritySafeCritical] // auto-generated
get {
if (_captureAllocatedCallStackState == 0) {
if (Mda.IsStreamWriterBufferedDataLostCaptureAllocatedCallStack())
@@ -45,42 +43,33 @@ namespace System
}
}
- [System.Security.SecuritySafeCritical] // auto-generated
internal static void ReportError(String text) {
Mda.ReportStreamWriterBufferedDataLost(text);
}
}
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void ReportStreamWriterBufferedDataLost(String text);
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool IsStreamWriterBufferedDataLostEnabled();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool IsStreamWriterBufferedDataLostCaptureAllocatedCallStack();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void MemberInfoCacheCreation();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void DateTimeInvalidLocalFormat();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool IsInvalidGCHandleCookieProbeEnabled();
- [System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void FireInvalidGCHandleCookieProbe(IntPtr cookie);
- [System.Security.SecurityCritical]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void ReportErrorSafeHandleRelease(Exception ex);
}
diff --git a/src/mscorlib/src/mscorlib.Friends.cs b/src/mscorlib/src/mscorlib.Friends.cs
index fc8ed53fff..0e55301656 100644
--- a/src/mscorlib/src/mscorlib.Friends.cs
+++ b/src/mscorlib/src/mscorlib.Friends.cs
@@ -3,10 +3,8 @@
// See the LICENSE file in the project root for more information.
using System.Runtime.CompilerServices;
-#if FEATURE_CORECLR
// We need this to be able to typeforward to internal types
[assembly: InternalsVisibleTo("mscorlib, PublicKey=00240000048000009400000006020000002400005253413100040000010001008d56c76f9e8649383049f383c44be0ec204181822a6c31cf5eb7ef486944d032188ea1d3920763712ccb12d75fb77e9811149e6148e5d32fbaab37611c1878ddc19e20ef135d0cb2cff2bfec3d115810c3d9069638fe4be215dbf795861920e5ab6f7db2e2ceef136ac23d5dd2bf031700aec232f6c6b1c785b4305c123b37ab", AllInternalsVisible=false)]
-#endif
// 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.
diff --git a/src/mscorlib/src/mscorlib.txt b/src/mscorlib/src/mscorlib.txt
deleted file mode 100644
index 01d593b778..0000000000
--- a/src/mscorlib/src/mscorlib.txt
+++ /dev/null
@@ -1,3494 +0,0 @@
-; Licensed to the .NET Foundation under one or more 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 !FEATURE_CORECLR
-UnknownError = Unknown error.
-#endif // !FEATURE_CORECLR
-
-#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.
-
-; Access Control
-#if FEATURE_MACL
-AccessControl_MustSpecifyContainerAcl = The named parameter must be a container ACL.
-AccessControl_MustSpecifyLeafObjectAcl = The named parameter must be a non-container ACL.
-AccessControl_AclTooLong = Length of the access control list exceed the allowed maximum.
-AccessControl_MustSpecifyDirectoryObjectAcl = The named parameter must be a directory-object ACL.
-AccessControl_MustSpecifyNonDirectoryObjectAcl = The named parameter must be a non-directory-object ACL.
-AccessControl_InvalidSecurityDescriptorRevision = Security descriptor with revision other than '1' are not legal.
-AccessControl_InvalidSecurityDescriptorSelfRelativeForm = Security descriptor must be in the self-relative form.
-AccessControl_NoAssociatedSecurity = Unable to perform a security operation on an object that has no associated security. This can happen when trying to get an ACL of an anonymous kernel object.
-AccessControl_InvalidHandle = The supplied handle is invalid. This can happen when trying to set an ACL on an anonymous kernel object.
-AccessControl_UnexpectedError = Method failed with unexpected error code {0}.
-AccessControl_InvalidSidInSDDLString = The SDDL string contains an invalid sid or a sid that cannot be translated.
-AccessControl_InvalidOwner = The security identifier is not allowed to be the owner of this object.
-AccessControl_InvalidGroup = The security identifier is not allowed to be the primary group of this object.
-AccessControl_InvalidAccessRuleType = The access rule is not the correct type.
-AccessControl_InvalidAuditRuleType = The audit rule is not the correct type.
-#endif // FEATURE_MACL
-
-; 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.
-#if FEATURE_CORECLR
-Argument_AddingDuplicateWithKey = An item with the same key has already been added. Key: {0}
-#endif // FEATURE_CORECLR
-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 260 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_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 srcIndex and length, and the array's lower bounds.
-Arg_LongerThanDestArray = Destination array was not long enough. Check destIndex and 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.
-#if FEATURE_CAS_POLICY
-Argument_UninitializedCertificate = Uninitialized certificate object.
-Argument_MembershipConditionElement = Element must be a <IMembershipCondition> element.
-Argument_ReservedNPMS = Cannot remove or modify reserved permissions set '{0}'.
-Argument_NPMSInUse = Permission set '{0}' was in use and could not be deleted.
-Argument_StrongNameGetPublicKey = Unable to obtain public key for StrongNameKeyPair.
-Argument_SiteCannotBeNull = Site name must be specified.
-Argument_BlobCannotBeNull = Public key must be specified.
-Argument_ZoneCannotBeNull = Zone must be specified.
-Argument_UrlCannotBeNull = URL must be specified.
-Argument_NoNPMS = Unable to find a permission set with the provided name.
-Argument_FailedCodeGroup = Failed to create a code group of type '{0}'.
-Argument_CodeGroupChildrenMustBeCodeGroups = All objects in the input list must have a parent type of 'CodeGroup'.
-#endif // FEATURE_CAS_POLICY
-#if FEATURE_IMPERSONATION
-Argument_InvalidPrivilegeName = Privilege '{0}' is not valid on this system.
-Argument_TokenZero = Token cannot be zero.
-Argument_InvalidImpersonationToken = Invalid token for impersonation - it cannot be duplicated.
-Argument_ImpersonateUser = Unable to impersonate user.
-#endif // FEATURE_IMPERSONATION
-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}.
-
-;
-; =====================================================
-; 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.
-
-#if FEATURE_CRYPTO
-Cryptography_Config_EncodedOIDError = Encoded OID length is too large (greater than 0x7f bytes).
-Cryptography_CSP_AlgKeySizeNotAvailable = Algorithm implementation does not support a key size of {0}.
-Cryptography_CSP_AlgorithmNotAvailable = Cryptographic service provider (CSP) could not be found for this algorithm.
-Cryptography_CSP_CFBSizeNotSupported = Feedback size for the cipher feedback mode (CFB) must be 8 bits.
-Cryptography_CSP_NotFound = The requested key container was not found.
-Cryptography_CSP_NoPrivateKey = Object contains only the public half of a key pair. A private key must also be provided.
-Cryptography_CSP_OFBNotSupported = Output feedback mode (OFB) is not supported by this implementation.
-Cryptography_CSP_WrongKeySpec = The specified cryptographic service provider (CSP) does not support this key algorithm.
-Cryptography_HashNameSet = Hash name cannot be changed after the first write to the stream.
-Cryptography_HashAlgorithmNameNullOrEmpty = The hash algorithm name cannot be null or empty.
-Cryptography_InvalidHashSize = {0} algorithm hash size is {1} bytes.
-Cryptography_InvalidKey_Weak = Specified key is a known weak key for '{0}' and cannot be used.
-Cryptography_InvalidKey_SemiWeak = Specified key is a known semi-weak key for '{0}' and cannot be used.
-Cryptography_InvalidKeyParameter = Parameter '{0}' is not a valid key parameter.
-Cryptography_InvalidFeedbackSize = Specified feedback size is invalid.
-Cryptography_InvalidOperation = This operation is not supported for this class.
-Cryptography_InvalidPaddingMode = Specified padding mode is not valid for this algorithm.
-Cryptography_InvalidFromXmlString = Input string does not contain a valid encoding of the '{0}' '{1}' parameter.
-Cryptography_MissingKey = No asymmetric key object has been associated with this formatter object.
-Cryptography_MissingOID = Required object identifier (OID) cannot be found.
-Cryptography_NotInteractive = The current session is not interactive.
-Cryptography_NonCompliantFIPSAlgorithm = This implementation is not part of the Windows Platform FIPS validated cryptographic algorithms.
-Cryptography_Padding_Win2KEnhOnly = Direct Encryption and decryption using RSA are not available on this platform.
-Cryptography_Padding_EncDataTooBig = The data to be encrypted exceeds the maximum for this modulus of {0} bytes.
-Cryptography_Padding_DecDataTooBig = The data to be decrypted exceeds the maximum for this modulus of {0} bytes.
-Cryptography_PasswordDerivedBytes_ValuesFixed = Value of '{0}' cannot be changed after the bytes have been retrieved.
-Cryptography_PasswordDerivedBytes_TooManyBytes = Requested number of bytes exceeds the maximum.
-Cryptography_PasswordDerivedBytes_InvalidAlgorithm = Algorithm is unavailable or is not supported for this operation.
-Cryptography_PKCS1Decoding = Error occurred while decoding PKCS1 padding.
-Cryptography_RC2_EKSKS = EffectiveKeySize value must be at least as large as the KeySize value.
-Cryptography_RC2_EKSKS2 = EffectiveKeySize must be the same as KeySize in this implementation.
-Cryptography_RC2_EKS40 = EffectiveKeySize value must be at least 40 bits.
-Cryptography_SSD_InvalidDataSize = Length of the data to decrypt is invalid.
-Cryptography_AddNullOrEmptyName = CryptoConfig cannot add a mapping for a null or empty name.
-Cryptography_AlgorithmTypesMustBeVisible = Algorithms added to CryptoConfig must be accessable from outside their assembly.
-#endif // FEATURE_CRYPTO
-
-; 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_SubclassedObject = Cannot set sub-classed {0} object to {1} object.
-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.
-#if FEATURE_CAS_POLICY
-InvalidOperation_ModifyROPermSet = ReadOnlyPermissionSet objects may not be modified.
-#endif // FEATURE_CAS_POLICY
-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_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 the 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_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.
-
-#if FEATURE_WINDOWSPHONE
-NotSupported_UserDllImport = DllImport cannot be used on user-defined methods.
-NotSupported_UserCOM = COM Interop is not supported for user-defined types.
-#endif //FEATURE_WINDOWSPHONE
-#if FEATURE_CAS_POLICY
-NotSupported_RequiresCasPolicyExplicit = This method explicitly uses CAS policy, which has been obsoleted by the .NET Framework. In order to enable CAS policy for compatibility reasons, please use the NetFx40_LegacySecurityPolicy configuration switch. Please see http://go.microsoft.com/fwlink/?LinkID=155570 for more information.
-NotSupported_RequiresCasPolicyImplicit = This method implicitly uses CAS policy, which has been obsoleted by the .NET Framework. In order to enable CAS policy for compatibility reasons, please use the NetFx40_LegacySecurityPolicy configuration switch. Please see http://go.microsoft.com/fwlink/?LinkID=155570 for more information.
-NotSupported_CasDeny = The Deny stack modifier has been obsoleted by the .NET Framework. Please see http://go.microsoft.com/fwlink/?LinkId=155571 for more information.
-NotSupported_SecurityContextSourceAppDomainInHeterogenous = SecurityContextSource.CurrentAppDomain is not supported in heterogenous AppDomains.
-#endif // FEATURE_CAS_POLICY
-#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_CORECLR
-NotSupported_NoTypeInfo = Cannot resolve {0} to a TypeInfo object.
-#endif
-#if FEATURE_COMINTEROP
-NotSupported_PIAInAppxProcess = A Primary Interop Assembly is not supported in AppX.
-#endif
-#if FEATURE_WINDOWSPHONE
-; Not referring to "Windows Phone" in the messages, as FEATURE_WINDOWSPHONE is defined for .NET Core as well.
-NotSupported_WindowsPhone = {0} is not supported.
-NotSupported_AssemblyLoadCodeBase = Assembly.Load with a Codebase is not supported.
-#endif
-
-; 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.
-#if FEATURE_IMPERSONATION
-Policy_PrincipalTwice = Default principal object cannot be set twice.
-#endif // FEATURE_IMPERSONATION
-#if FEATURE_CAS_POLICY
-Policy_PolicyAlreadySet = Policy for this domain cannot be set twice.
-Policy_NoExecutionPermission = Execution permission cannot be acquired.
-Policy_NoRequiredPermission = Required permissions cannot be acquired.
-Policy_MultipleExclusive = More than one exclusive group is not allowed.
-Policy_RecoverNotFileBased = PolicyLevel object not based on a file cannot be recovered.
-Policy_RecoverNoConfigFile = No old configuration file exists to recover.
-Policy_UnableToSave = Policy level '{0}' could not be saved: {1}.
-Policy_BadXml = Policy configuration XML is invalid. The required tag '{0}' is missing.
-Policy_NonFullTrustAssembly = Policy references an assembly not in the full trust assemblies list.
-Policy_MissingActivationContextInAppEvidence = The application evidence does not contain a Fusion activation context.
-Policy_NoTrustManager = A trust manager could not be loaded for this application.
-Policy_GrantSetDoesNotMatchDomain = An assembly was provided an invalid grant set by runtime host '{0}'. In a homogenous AppDomain, the only valid grant sets are FullTrust and the AppDomain's sandbox grant set.
-#endif // FEATURE_CAS_POLICY
-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.
-
-#if FEATURE_CAS_POLICY
-Policy_EvidenceMustBeSerializable = Objects used as evidence must be serializable.
-Policy_DuplicateEvidence = The evidence collection already contains evidence of type '{0}'. Multiple pieces of the same type of evidence are not allowed.
-Policy_IncorrectHostEvidence = Runtime host '{0}' returned evidence of type '{1}' from a request for evidence of type '{2}'.
-Policy_NullHostEvidence = Runtime host '{0}' returned null when asked for assembly evidence for assembly '{1}'.
-Policy_NullHostGrantSet = Runtime host '{0}' returned a null grant set from ResolvePolicy.
-#endif // FEATURE_CAS_POLICY
-
-; Policy codegroup and permission set names and descriptions
-#if FEATURE_CAS_POLICY
-Policy_AllCode_Name = All_Code
-Policy_AllCode_DescriptionFullTrust = Code group grants all code full trust and forms the root of the code group tree.
-Policy_AllCode_DescriptionNothing = Code group grants no permissions and forms the root of the code group tree.
-Policy_MyComputer_Name = My_Computer_Zone
-Policy_MyComputer_Description = Code group grants full trust to all code originating on the local computer
-Policy_Intranet_Name = LocalIntranet_Zone
-Policy_Intranet_Description = Code group grants the intranet permission set to code from the intranet zone. This permission set grants intranet code the right to use isolated storage, full UI access, some capability to do reflection, and limited access to environment variables.
-Policy_IntranetNet_Name = Intranet_Same_Site_Access
-Policy_IntranetNet_Description = All intranet code gets the right to connect back to the site of its origin.
-Policy_IntranetFile_Name = Intranet_Same_Directory_Access
-Policy_IntranetFile_Description = All intranet code gets the right to read from its install directory.
-Policy_Internet_Name = Internet_Zone
-Policy_Internet_Description = Code group grants code from the Internet zone the Internet permission set. This permission set grants Internet code the right to use isolated storage and limited UI access.
-Policy_InternetNet_Name = Internet_Same_Site_Access
-Policy_InternetNet_Description = All Internet code gets the right to connect back to the site of its origin.
-Policy_Trusted_Name = Trusted_Zone
-Policy_Trusted_Description = Code from a trusted zone is granted the Internet permission set. This permission set grants the right to use isolated storage and limited UI access.
-Policy_TrustedNet_Name = Trusted_Same_Site_Access
-Policy_TrustedNet_Description = All Trusted Code gets the right to connect back to the site of its origin.
-Policy_Untrusted_Name = Restricted_Zone
-Policy_Untrusted_Description = Code coming from a restricted zone does not receive any permissions.
-Policy_Microsoft_Name = Microsoft_Strong_Name
-Policy_Microsoft_Description = Code group grants full trust to code signed with the Microsoft strong name.
-Policy_Ecma_Name = ECMA_Strong_Name
-Policy_Ecma_Description = Code group grants full trust to code signed with the ECMA strong name.
-
-; Policy permission set descriptions
-Policy_PS_FullTrust = Allows full access to all resources
-Policy_PS_Everything = Allows unrestricted access to all resources covered by built-in permissions
-Policy_PS_Nothing = Denies all resources, including the right to execute
-Policy_PS_Execution = Permits execution
-Policy_PS_SkipVerification = Grants right to bypass the verification
-Policy_PS_Internet = Default rights given to Internet applications
-Policy_PS_LocalIntranet = Default rights given to applications on the local intranet
-
-; default Policy level names
-Policy_PL_Enterprise = Enterprise
-Policy_PL_Machine = Machine
-Policy_PL_User = User
-Policy_PL_AppDomain = AppDomain
-#endif // FEATURE_CAS_POLICY
-
-; 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.
-#if FEATURE_REMOTING
-Remoting_Activation_BadAttribute = Activation attribute does not implement the IContextAttribute interface.
-Remoting_Activation_BadObject = Proxy Attribute returned an incompatible object when constructing an instance of type {0}.
-Remoting_Activation_MBR_ProxyAttribute = Proxy Attributes are supported on ContextBound types only.
-Remoting_Activation_ConnectFailed = An attempt to connect to the remote activator failed with exception '{0}'.
-Remoting_Activation_Failed = Activation failed due to an unknown reason.
-Remoting_Activation_InconsistentState = Inconsistent state during activation; there may be two proxies for the same object.
-Remoting_Activation_MissingRemoteAppEntry = Cannot find an entry for remote application '{0}'.
-Remoting_Activation_NullReturnValue = Return value of construction call was null.
-Remoting_Activation_NullFromInternalUnmarshal = InternalUnmarshal of returned ObjRef from activation call returned null.
-Remoting_Activation_WellKnownCTOR = Cannot run a non-default constructor when connecting to well-known objects.
-Remoting_Activation_PermissionDenied = Type '{0}' is not registered for activation.
-Remoting_Activation_PropertyUnhappy = A context property did not approve the candidate context for activating the object.
-Remoting_Activation_AsyncUnsupported = Async Activation not supported.
-Remoting_AmbiguousCTOR = Cannot resolve the invocation to the correct constructor.
-Remoting_AmbiguousMethod = Cannot resolve the invocation to the correct method.
-Remoting_AppDomains_NYI = This feature is not yet supported for cross-application domain.
-Remoting_AppDomainsCantBeCalledRemotely = Permission denied: cannot call methods on the AppDomain class remotely.
-Remoting_AssemblyLoadFailed = Cannot load assembly '{0}'.
-Remoting_Attribute_UseAttributeNotsettable = UseAttribute not allowed in SoapTypeAttribute.
-Remoting_BadType = Cannot load type '{0}'.
-Remoting_BadField = Remoting cannot find field '{0}' on type '{1}'.
-Remoting_BadInternalState_ActivationFailure = Invalid internal state: Activation service failed to initialize.
-Remoting_BadInternalState_ProxySameAppDomain = Invalid internal state: A marshal by ref object should not have a proxy in its own AppDomain.
-Remoting_BadInternalState_FailEnvoySink = Invalid internal state: Failed to create an envoy sink for the object.
-Remoting_CantDisconnectClientProxy = Cannot call disconnect on a proxy.
-Remoting_CantInvokeIRemoteDispatch = Cannot invoke methods on IRemoteDispatch.
-Remoting_ChannelNameAlreadyRegistered = The channel '{0}' is already registered.
-Remoting_ChannelNotRegistered = The channel '{0}' is not registered with remoting services.
-Remoting_Channel_PopOnEmptySinkStack = Tried to pop data from an empty channel sink stack.
-Remoting_Channel_PopFromSinkStackWithoutPush = A channel sink tried to pop data from the stack without first pushing data onto the stack.
-Remoting_Channel_StoreOnEmptySinkStack = A channel sink called the Store method when the sink stack was empty.
-Remoting_Channel_StoreOnSinkStackWithoutPush = A channel sink called the Store method on the sink stack without first pushing data onto the stack.
-Remoting_Channel_CantCallAPRWhenStackEmpty = Cannot call the AsyncProcessResponse method on the previous channel sink because the stack is empty.
-Remoting_Channel_CantCallFRSWhenStackEmtpy = Called FlipRememberedStack() when stack was not null.
-Remoting_Channel_CantCallGetResponseStreamWhenStackEmpty = Cannot call the GetResponseStream method on the previous channel sink because the stack is empty.
-Remoting_Channel_DispatchSinkMessageMissing = No message was deserialized prior to calling the DispatchChannelSink.
-Remoting_Channel_DispatchSinkWantsNullRequestStream = The request stream should be null when the DispatchChannelSink is called.
-Remoting_Channel_CannotBeSecured = Channel {0} cannot be secured. Please consider using a channel that implements ISecurableChannel
-Remoting_Config_ChannelMissingCtor = To be used from a .config file, the channel type '{0}' must have a constructor of the form '{1}'
-Remoting_Config_SinkProviderMissingCtor = To be used from a .config file, the sink provider type '{0}' must have a constructor of the form '{1}'
-Remoting_Config_SinkProviderNotFormatter = A sink provider of type '{0}' is incorrectly labeled as a 'formatter'.
-Remoting_Config_ConfigurationFailure = Remoting configuration failed with the exception '{0}'.
-Remoting_Config_InvalidTimeFormat = Invalid time format '{0}'. Examples of valid time formats include 7D, 10H, 5M, 30S, or 20MS.
-Remoting_Config_AppNameSet = The remoting application name, '{0}', had already been set.
-Remoting_Config_ErrorsModeSet = The remoting custom errors mode had already been set.
-Remoting_Config_CantRedirectActivationOfWellKnownService = Attempt to redirect activation for type '{0}, {1}'. This is not allowed since either a well-known service type has already been registered with that type or that type has been registered has a activated service type.
-Remoting_Config_CantUseRedirectedTypeForWellKnownService = Attempt to register a well-known or activated service type of type '{0}, {1}'. This is not allowed since the type has already been redirected to activate elsewhere.
-Remoting_Config_InvalidChannelType = '{0}' does not implement IChannelReceiver or IChannelSender. All channels must implement one of these interfaces.
-Remoting_Config_InvalidSinkProviderType = Unable to use '{0}' as a channel sink provider. It does not implement '{1}'.
-Remoting_Config_MissingWellKnownModeAttribute = Well-known service entries must contain a 'mode' attribute with a value of 'Singleton' or 'SingleCall'.
-Remoting_Config_MissingTypeAttribute = '{0}' entries must contain a '{1}' attribute of the form 'typeName, assemblyName'.
-Remoting_Config_MissingXmlTypeAttribute = '{0}' entries must contain a '{1}' attribute of the form 'xmlTypeName, xmlTypeNamespace'.
-Remoting_Config_NoAppName = Improper remoting configuration: missing ApplicationName property.
-Remoting_Config_NonTemplateIdAttribute = Only '{0}' templates can have an 'id' attribute.
-Remoting_Config_PreloadRequiresTypeOrAssembly = Preload entries require a type or assembly attribute.
-Remoting_Config_ProviderNeedsElementName = Sink providers must have an element name of 'formatter' or 'provider'.
-Remoting_Config_RequiredXmlAttribute = '{0}' entries require a '{1}' attribute.
-Remoting_Config_ReadFailure = .Config file '{0}' cannot be read successfully due to exception '{1}'.
-Remoting_Config_NodeMustBeUnique = There can be only one '{0}' node in the '{1}' section of a config file.
-Remoting_Config_TemplateCannotReferenceTemplate = A '{0}' template cannot reference another '{0}' template.
-Remoting_Config_TypeAlreadyRedirected = Attempt to redirect activation of type '{0}, {1}' which is already redirected.
-Remoting_Config_UnknownValue = Unknown value {1} was found on the {0} node.
-Remoting_Config_UnableToResolveTemplate = Cannot resolve '{0}' template reference: '{1}'.
-Remoting_Config_VersionPresent = Version information is present in the assembly name '{0}' which is not allowed for '{1}' entries.
-Remoting_Contexts_BadProperty = A property that contributed a bad sink to the chain was found.
-Remoting_Contexts_NoProperty = A property with the name '{0}' was not found.
-Remoting_Contexts_ContextNotFrozenForCallBack = Context should be frozen before calling the DoCallBack method.
-Remoting_Default = Unknown remoting error.
-Remoting_HandlerNotRegistered = The tracking handler of type '{0}' is not registered with Remoting Services.
-Remoting_InvalidMsg = Invalid Message Object.
-Remoting_InvalidCallingType = Attempted to call a method declared on type '{0}' on an object which exposes '{1}'.
-Remoting_InvalidRequestedType = The server object type cannot be cast to the requested type '{0}'.
-Remoting_InternalError = Server encountered an internal error. For more information, turn off customErrors in the server's .config file.
-Remoting_Lifetime_ILeaseReturn = Expected a return object of type ILease, but received '{0}'.
-Remoting_Lifetime_InitialStateInitialLeaseTime = InitialLeaseTime property can only be set when the lease is in initial state. The state is '{0}'.
-Remoting_Lifetime_InitialStateRenewOnCall = RenewOnCallTime property can only be set when the lease is in initial state. The state is '{0}'.
-Remoting_Lifetime_InitialStateSponsorshipTimeout = SponsorshipTimeout property can only be set when the lease is in initial state. State is '{0}'.
-Remoting_Lifetime_SetOnce = '{0}' can only be set once within an AppDomain.
-Remoting_Message_ArgMismatch = {2} arguments were passed to '{0}::{1}'. {3} arguments were expected by this method.
-Remoting_Message_BadAsyncResult = The async result object is null or of an unexpected type.
-Remoting_Message_BadType = The method was called with a Message of an unexpected type.
-Remoting_Message_CoercionFailed = The argument type '{0}' cannot be converted into parameter type '{1}'.
-Remoting_Message_MissingArgValue = Expecting an instance of type '{0}' at pos {1} in the args array.
-Remoting_Message_BadSerialization = Invalid or malformed serialization information for the message object.
-Remoting_NoIdentityEntry = No remoting information was found for this object.
-Remoting_NotRemotableByReference = Trying to create a proxy to an unbound type.
-Remoting_NullMessage = The method was called with a null message.
-Remoting_Proxy_BadType = The proxy is of an unsupported type.
-Remoting_ResetURI = Attempt to reset the URI for an object from '{0}' to '{1}'.
-Remoting_ServerObjectNotFound = The server object for URI '{0}' is not registered with the remoting infrastructure (it may have been disconnected).
-Remoting_SetObjectUriForMarshal__ObjectNeedsToBeLocal = SetObjectUriForMarshal method should only be called for MarshalByRefObjects that exist in the current AppDomain.
-Remoting_SetObjectUriForMarshal__UriExists = SetObjectUriForMarshal method has already been called on this object or the object has already been marshaled.
-Remoting_Proxy_BadReturnType = Return argument has an invalid type.
-Remoting_Proxy_ReturnValueTypeCannotBeNull = ByRef value type parameter cannot be null.
-Remoting_Proxy_BadReturnTypeForActivation = Bad return type for activation call via Invoke: must be of type IConstructionReturnMessage.
-Remoting_Proxy_BadTypeForActivation = Type mismatch between proxy type '{0}' and activation type '{1}'.
-Remoting_Proxy_ExpectedOriginalMessage = The message passed to Invoke should be passed to PropagateOutParameters.
-Remoting_Proxy_InvalidCall = Trying to call proxy while constructor call is in progress.
-Remoting_Proxy_InvalidState = Channel sink does not exist. Failed to dispatch async call.
-Remoting_Proxy_NoChannelSink = This remoting proxy has no channel sink which means either the server has no registered server channels that are listening, or this application has no suitable client channel to talk to the server.
-Remoting_Proxy_InvalidCallType = Only the synchronous call type is supported for messages that are not of type Message.
-Remoting_Proxy_WrongContext = ExecuteMessage can be called only from the native context of the object.
-Remoting_SOAPInteropxsdInvalid = Soap Parse error, xsd:type '{0}' invalid {1}
-Remoting_SOAPQNameNamespace = SoapQName missing a Namespace value '{0}'.
-Remoting_ThreadAffinity_InvalidFlag = The specified flag '{0}' does not have one of the valid values.
-Remoting_TrackingHandlerAlreadyRegistered = The handler has already been registered with TrackingServices.
-Remoting_URIClash = Found two different objects associated with the same URI, '{0}'.
-Remoting_URIExists = The remoted object already has an associated URI.
-Remoting_URIToProxy = Trying to associate the URI with a proxy.
-Remoting_WellKnown_MustBeMBR = Attempted to create well-known object of type '{0}'. Well-known objects must derive from the MarshalByRefObject class.
-Remoting_WellKnown_CtorCantMarshal = '{0}': A well-known object cannot marshal itself in its constructor, or perform any action that would cause it to be marshaled (such as passing the 'this' pointer as a parameter to a remote method).
-Remoting_WellKnown_CantDirectlyConnect = Attempt to connect to a server using its object URI: '{0}'. A valid, complete URL must be used.
-Remoting_Connect_CantCreateChannelSink = Cannot create channel sink to connect to URL '{0}'. An appropriate channel has probably not been registered.
-Remoting_UnexpectedNullTP = Failed to create a transparent proxy. If a custom RealProxy is being used ensure it sets the proxy type.
-; The following remoting exception messages appear in native resources too (mscorrc.rc)
-Remoting_Disconnected = Object '{0}' has been disconnected or does not exist at the server.
-Remoting_Message_MethodMissing = The method '{0}' was not found on the interface/type '{1}'.
-#endif // FEATURE_REMOTING
-
-; 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.
-#if FEATURE_CAS_POLICY
-Security_CannotGenerateHash = Hash for the assembly cannot be generated.
-Security_CannotGetRawData = Assembly bytes could not be retrieved.
-Security_PrincipalPermission = Request for principal permission failed.
-Security_Action = The action that failed was:
-Security_TypeFirstPermThatFailed = The type of the first permission that failed was:
-Security_FirstPermThatFailed = The first permission that failed was:
-Security_Demanded = The demand was for:
-Security_GrantedSet = The granted set of the failing assembly was:
-Security_RefusedSet = The refused set of the failing assembly was:
-Security_Denied = The denied permissions were:
-Security_PermitOnly = The only permitted permissions were:
-Security_Assembly = The assembly or AppDomain that failed was:
-Security_Method = The method that caused the failure was:
-Security_Zone = The Zone of the assembly that failed was:
-Security_Url = The Url of the assembly that failed was:
-Security_AnonymouslyHostedDynamicMethodCheckFailed = The demand failed due to the code access security information captured during the creation of an anonymously hosted dynamic method. In order for this operation to succeed, ensure that the demand would have succeeded at the time the method was created. See http://go.microsoft.com/fwlink/?LinkId=288746 for more information.
-#endif // FEATURE_CAS_POLICY
-
-;
-; 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 path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.
-
-#if FEATURE_CORECLR
-; SecurityException
-FileSecurityState_OperationNotPermitted = File operation not permitted. Access to path '{0}' is denied.
-#endif
-
-; 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}'.
-#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.
-
-#if FEATURE_COMINTEROP_WINRT_DESKTOP_HOST
-WinRTHostDomainName = Windows Runtime Object Host Domain for '{0}'
-#endif
-
-;
-; 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.
-
-#if FEATURE_HOST_ASSEMBLY_RESOLVER
-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.
-#endif // FEATURE_HOST_ASSEMBLY_RESOLVER
-;
-; 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.
-
-; CodeGroup
-#if FEATURE_CAS_POLICY
-NetCodeGroup_PermissionSet = Same site Web
-MergeLogic_Union = Union
-MergeLogic_FirstMatch = First Match
-FileCodeGroup_PermissionSet = Same directory FileIO - '{0}'
-#endif // FEATURE_CAS_POLICY
-
-; 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
-#if FEATURE_CAS_POLICY
-Site_ToStringArg = Site - {0}
-Publisher_ToStringArg = Publisher - {0}
-Url_ToStringArg = Url - {0}
-#endif // FEATURE_CAS_POLICY
-
-
-; 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.
-
-; Globalization resources
-;------------------
-
-#if !FEATURE_CORECLR
-Globalization.LegacyModifier = Legacy
-
-;
-;Total items: 809
-;
-Globalization.ci_ = Invariant Language (Invariant Country)
-Globalization.ci_aa = Afar
-Globalization.ci_aa-DJ = Afar (Djibouti)
-Globalization.ci_aa-ER = Afar (Eritrea)
-Globalization.ci_aa-ET = Afar (Ethiopia)
-Globalization.ci_af = Afrikaans
-Globalization.ci_af-NA = Afrikaans (Namibia)
-Globalization.ci_af-ZA = Afrikaans (South Africa)
-Globalization.ci_agq = Aghem
-Globalization.ci_agq-CM = Aghem (Cameroon)
-Globalization.ci_ak = Akan
-Globalization.ci_ak-GH = Akan (Ghana)
-Globalization.ci_am = Amharic
-Globalization.ci_am-ET = Amharic (Ethiopia)
-Globalization.ci_ar = Arabic
-Globalization.ci_ar-001 = Arabic (World)
-Globalization.ci_ar-AE = Arabic (U.A.E.)
-Globalization.ci_ar-BH = Arabic (Bahrain)
-Globalization.ci_ar-DJ = Arabic (Djibouti)
-Globalization.ci_ar-DZ = Arabic (Algeria)
-Globalization.ci_ar-EG = Arabic (Egypt)
-Globalization.ci_ar-ER = Arabic (Eritrea)
-Globalization.ci_ar-IL = Arabic (Israel)
-Globalization.ci_ar-IQ = Arabic (Iraq)
-Globalization.ci_ar-JO = Arabic (Jordan)
-Globalization.ci_ar-KM = Arabic (Comoros)
-Globalization.ci_ar-KW = Arabic (Kuwait)
-Globalization.ci_ar-LB = Arabic (Lebanon)
-Globalization.ci_ar-LY = Arabic (Libya)
-Globalization.ci_ar-MA = Arabic (Morocco)
-Globalization.ci_ar-MR = Arabic (Mauritania)
-Globalization.ci_ar-OM = Arabic (Oman)
-Globalization.ci_ar-PS = Arabic (Palestinian Authority)
-Globalization.ci_ar-QA = Arabic (Qatar)
-Globalization.ci_ar-SA = Arabic (Saudi Arabia)
-Globalization.ci_ar-SD = Arabic (Sudan)
-Globalization.ci_ar-SO = Arabic (Somalia)
-Globalization.ci_ar-SS = Arabic (South Sudan)
-Globalization.ci_ar-SY = Arabic (Syria)
-Globalization.ci_ar-TD = Arabic (Chad)
-Globalization.ci_ar-TN = Arabic (Tunisia)
-Globalization.ci_ar-YE = Arabic (Yemen)
-Globalization.ci_arn = Mapudungun
-Globalization.ci_arn-CL = Mapudungun (Chile)
-Globalization.ci_as = Assamese
-Globalization.ci_as-IN = Assamese (India)
-Globalization.ci_asa = Asu
-Globalization.ci_asa-TZ = Asu (Tanzania)
-Globalization.ci_ast = Asturian
-Globalization.ci_ast-ES = Asturian (Spain)
-Globalization.ci_az = Azerbaijani
-Globalization.ci_az-Cyrl = Azerbaijani (Cyrillic)
-Globalization.ci_az-Cyrl-AZ = Azerbaijani (Cyrillic, Azerbaijan)
-Globalization.ci_az-Latn = Azerbaijani (Latin)
-Globalization.ci_az-Latn-AZ = Azerbaijani (Latin, Azerbaijan)
-Globalization.ci_ba = Bashkir
-Globalization.ci_ba-RU = Bashkir (Russia)
-Globalization.ci_bas = Basaa
-Globalization.ci_bas-CM = Basaa (Cameroon)
-Globalization.ci_be = Belarusian
-Globalization.ci_be-BY = Belarusian (Belarus)
-Globalization.ci_bem = Bemba
-Globalization.ci_bem-ZM = Bemba (Zambia)
-Globalization.ci_bez = Bena
-Globalization.ci_bez-TZ = Bena (Tanzania)
-Globalization.ci_bg = Bulgarian
-Globalization.ci_bg-BG = Bulgarian (Bulgaria)
-Globalization.ci_bm = Bambara
-Globalization.ci_bm-Latn = Bambara (Latin)
-Globalization.ci_bm-Latn-ML = Bambara (Latin, Mali)
-Globalization.ci_bm-ML = Bamanankan (Latin, Mali)
-Globalization.ci_bn = Bangla
-Globalization.ci_bn-BD = Bangla (Bangladesh)
-Globalization.ci_bn-IN = Bangla (India)
-Globalization.ci_bo = Tibetan
-Globalization.ci_bo-CN = Tibetan (PRC)
-Globalization.ci_bo-IN = Tibetan (India)
-Globalization.ci_br = Breton
-Globalization.ci_br-FR = Breton (France)
-Globalization.ci_brx = Bodo
-Globalization.ci_brx-IN = Bodo (India)
-Globalization.ci_bs = Bosnian
-Globalization.ci_bs-Cyrl = Bosnian (Cyrillic)
-Globalization.ci_bs-Cyrl-BA = Bosnian (Cyrillic, Bosnia and Herzegovina)
-Globalization.ci_bs-Latn = Bosnian (Latin)
-Globalization.ci_bs-Latn-BA = Bosnian (Latin, Bosnia and Herzegovina)
-Globalization.ci_byn = Blin
-Globalization.ci_byn-ER = Blin (Eritrea)
-Globalization.ci_ca = Catalan
-Globalization.ci_ca-AD = Catalan (Andorra)
-Globalization.ci_ca-ES = Catalan (Catalan)
-Globalization.ci_ca-ES-valencia = Valencian (Spain)
-Globalization.ci_ca-FR = Catalan (France)
-Globalization.ci_ca-IT = Catalan (Italy)
-Globalization.ci_cgg = Chiga
-Globalization.ci_cgg-UG = Chiga (Uganda)
-Globalization.ci_chr = Cherokee
-Globalization.ci_chr-Cher = Cherokee (Cherokee)
-Globalization.ci_chr-Cher-US = Cherokee (Cherokee)
-Globalization.ci_co = Corsican
-Globalization.ci_co-FR = Corsican (France)
-Globalization.ci_cs = Czech
-Globalization.ci_cs-CZ = Czech (Czech Republic)
-Globalization.ci_cy = Welsh
-Globalization.ci_cy-GB = Welsh (United Kingdom)
-Globalization.ci_da = Danish
-Globalization.ci_da-DK = Danish (Denmark)
-Globalization.ci_da-GL = Danish (Greenland)
-Globalization.ci_dav = Taita
-Globalization.ci_dav-KE = Taita (Kenya)
-Globalization.ci_de = German
-Globalization.ci_de-AT = German (Austria)
-Globalization.ci_de-BE = German (Belgium)
-Globalization.ci_de-CH = German (Switzerland)
-Globalization.ci_de-DE = German (Germany)
-Globalization.ci_de-DE_phoneb = German (Germany)
-Globalization.ci_de-LI = German (Liechtenstein)
-Globalization.ci_de-LU = German (Luxembourg)
-Globalization.ci_dje = Zarma
-Globalization.ci_dje-NE = Zarma (Niger)
-Globalization.ci_dsb = Lower Sorbian
-Globalization.ci_dsb-DE = Lower Sorbian (Germany)
-Globalization.ci_dua = Duala
-Globalization.ci_dua-CM = Duala (Cameroon)
-Globalization.ci_dv = Divehi
-Globalization.ci_dv-MV = Divehi (Maldives)
-Globalization.ci_dyo = Jola-Fonyi
-Globalization.ci_dyo-SN = Jola-Fonyi (Senegal)
-Globalization.ci_dz = Dzongkha
-Globalization.ci_dz-BT = Dzongkha (Bhutan)
-Globalization.ci_ebu = Embu
-Globalization.ci_ebu-KE = Embu (Kenya)
-Globalization.ci_ee = Ewe
-Globalization.ci_ee-GH = Ewe (Ghana)
-Globalization.ci_ee-TG = Ewe (Togo)
-Globalization.ci_el = Greek
-Globalization.ci_el-CY = Greek (Cyprus)
-Globalization.ci_el-GR = Greek (Greece)
-Globalization.ci_en = English
-Globalization.ci_en-001 = English (World)
-Globalization.ci_en-029 = English (Caribbean)
-Globalization.ci_en-150 = English (Europe)
-Globalization.ci_en-AG = English (Antigua and Barbuda)
-Globalization.ci_en-AI = English (Anguilla)
-Globalization.ci_en-AS = English (American Samoa)
-Globalization.ci_en-AU = English (Australia)
-Globalization.ci_en-BB = English (Barbados)
-Globalization.ci_en-BE = English (Belgium)
-Globalization.ci_en-BM = English (Bermuda)
-Globalization.ci_en-BS = English (Bahamas)
-Globalization.ci_en-BW = English (Botswana)
-Globalization.ci_en-BZ = English (Belize)
-Globalization.ci_en-CA = English (Canada)
-Globalization.ci_en-CC = English (Cocos [Keeling] Islands)
-Globalization.ci_en-CK = English (Cook Islands)
-Globalization.ci_en-CM = English (Cameroon)
-Globalization.ci_en-CX = English (Christmas Island)
-Globalization.ci_en-DM = English (Dominica)
-Globalization.ci_en-ER = English (Eritrea)
-Globalization.ci_en-FJ = English (Fiji)
-Globalization.ci_en-FK = English (Falkland Islands)
-Globalization.ci_en-FM = English (Micronesia)
-Globalization.ci_en-GB = English (United Kingdom)
-Globalization.ci_en-GD = English (Grenada)
-Globalization.ci_en-GG = English (Guernsey)
-Globalization.ci_en-GH = English (Ghana)
-Globalization.ci_en-GI = English (Gibraltar)
-Globalization.ci_en-GM = English (Gambia)
-Globalization.ci_en-GU = English (Guam)
-Globalization.ci_en-GY = English (Guyana)
-Globalization.ci_en-HK = English (Hong Kong SAR)
-Globalization.ci_en-IE = English (Ireland)
-Globalization.ci_en-IM = English (Isle of Man)
-Globalization.ci_en-IN = English (India)
-Globalization.ci_en-IO = English (British Indian Ocean Territory)
-Globalization.ci_en-JE = English (Jersey)
-Globalization.ci_en-JM = English (Jamaica)
-Globalization.ci_en-KE = English (Kenya)
-Globalization.ci_en-KI = English (Kiribati)
-Globalization.ci_en-KN = English (Saint Kitts and Nevis)
-Globalization.ci_en-KY = English (Cayman Islands)
-Globalization.ci_en-LC = English (Saint Lucia)
-Globalization.ci_en-LR = English (Liberia)
-Globalization.ci_en-LS = English (Lesotho)
-Globalization.ci_en-MG = English (Madagascar)
-Globalization.ci_en-MH = English (Marshall Islands)
-Globalization.ci_en-MO = English (Macao SAR)
-Globalization.ci_en-MP = English (Northern Mariana Islands)
-Globalization.ci_en-MS = English (Montserrat)
-Globalization.ci_en-MT = English (Malta)
-Globalization.ci_en-MU = English (Mauritius)
-Globalization.ci_en-MW = English (Malawi)
-Globalization.ci_en-MY = English (Malaysia)
-Globalization.ci_en-NA = English (Namibia)
-Globalization.ci_en-NF = English (Norfolk Island)
-Globalization.ci_en-NG = English (Nigeria)
-Globalization.ci_en-NR = English (Nauru)
-Globalization.ci_en-NU = English (Niue)
-Globalization.ci_en-NZ = English (New Zealand)
-Globalization.ci_en-PG = English (Papua New Guinea)
-Globalization.ci_en-PH = English (Republic of the Philippines)
-Globalization.ci_en-PK = English (Pakistan)
-Globalization.ci_en-PN = English (Pitcairn Islands)
-Globalization.ci_en-PR = English (Puerto Rico)
-Globalization.ci_en-PW = English (Palau)
-Globalization.ci_en-RW = English (Rwanda)
-Globalization.ci_en-SB = English (Solomon Islands)
-Globalization.ci_en-SC = English (Seychelles)
-Globalization.ci_en-SD = English (Sudan)
-Globalization.ci_en-SG = English (Singapore)
-Globalization.ci_en-SH = English (St Helena, Ascension, Tristan da Cunha)
-Globalization.ci_en-SL = English (Sierra Leone)
-Globalization.ci_en-SS = English (South Sudan)
-Globalization.ci_en-SX = English (Sint Maarten)
-Globalization.ci_en-SZ = English (Swaziland)
-Globalization.ci_en-TC = English (Turks and Caicos Islands)
-Globalization.ci_en-TK = English (Tokelau)
-Globalization.ci_en-TO = English (Tonga)
-Globalization.ci_en-TT = English (Trinidad and Tobago)
-Globalization.ci_en-TV = English (Tuvalu)
-Globalization.ci_en-TZ = English (Tanzania)
-Globalization.ci_en-UG = English (Uganda)
-Globalization.ci_en-UM = English (US Minor Outlying Islands)
-Globalization.ci_en-US = English (United States)
-Globalization.ci_en-VC = English (Saint Vincent and the Grenadines)
-Globalization.ci_en-VG = English (British Virgin Islands)
-Globalization.ci_en-VI = English (US Virgin Islands)
-Globalization.ci_en-VU = English (Vanuatu)
-Globalization.ci_en-WS = English (Samoa)
-Globalization.ci_en-ZA = English (South Africa)
-Globalization.ci_en-ZM = English (Zambia)
-Globalization.ci_en-ZW = English (Zimbabwe)
-Globalization.ci_eo = Esperanto
-Globalization.ci_eo-001 = Esperanto (World)
-Globalization.ci_es = Spanish
-Globalization.ci_es-419 = Spanish (Latin America)
-Globalization.ci_es-AR = Spanish (Argentina)
-Globalization.ci_es-BO = Spanish (Bolivia)
-Globalization.ci_es-CL = Spanish (Chile)
-Globalization.ci_es-CO = Spanish (Colombia)
-Globalization.ci_es-CR = Spanish (Costa Rica)
-Globalization.ci_es-CU = Spanish (Cuba)
-Globalization.ci_es-DO = Spanish (Dominican Republic)
-Globalization.ci_es-EC = Spanish (Ecuador)
-Globalization.ci_es-ES = Spanish (Spain)
-Globalization.ci_es-ES_tradnl = Spanish (Spain)
-Globalization.ci_es-GQ = Spanish (Equatorial Guinea)
-Globalization.ci_es-GT = Spanish (Guatemala)
-Globalization.ci_es-HN = Spanish (Honduras)
-Globalization.ci_es-MX = Spanish (Mexico)
-Globalization.ci_es-NI = Spanish (Nicaragua)
-Globalization.ci_es-PA = Spanish (Panama)
-Globalization.ci_es-PE = Spanish (Peru)
-Globalization.ci_es-PH = Spanish (Philippines)
-Globalization.ci_es-PR = Spanish (Puerto Rico)
-Globalization.ci_es-PY = Spanish (Paraguay)
-Globalization.ci_es-SV = Spanish (El Salvador)
-Globalization.ci_es-US = Spanish (United States)
-Globalization.ci_es-UY = Spanish (Uruguay)
-Globalization.ci_es-VE = Spanish (Bolivarian Republic of Venezuela)
-Globalization.ci_et = Estonian
-Globalization.ci_et-EE = Estonian (Estonia)
-Globalization.ci_eu = Basque
-Globalization.ci_eu-ES = Basque (Basque)
-Globalization.ci_ewo = Ewondo
-Globalization.ci_ewo-CM = Ewondo (Cameroon)
-Globalization.ci_fa = Persian
-Globalization.ci_fa-AF = Persian (Afghanistan)
-Globalization.ci_fa-IR = Persian (Iran)
-Globalization.ci_ff = Fulah
-Globalization.ci_ff-CM = Fulah (Cameroon)
-Globalization.ci_ff-GN = Fulah (Guinea)
-Globalization.ci_ff-Latn = Fulah (Latin)
-Globalization.ci_ff-Latn-SN = Fulah (Latin, Senegal)
-Globalization.ci_ff-MR = Fulah (Mauritania)
-Globalization.ci_fi = Finnish
-Globalization.ci_fi-FI = Finnish (Finland)
-Globalization.ci_fil = Filipino
-Globalization.ci_fil-PH = Filipino (Philippines)
-Globalization.ci_fo = Faroese
-Globalization.ci_fo-FO = Faroese (Faroe Islands)
-Globalization.ci_fr = French
-Globalization.ci_fr-BE = French (Belgium)
-Globalization.ci_fr-BF = French (Burkina Faso)
-Globalization.ci_fr-BI = French (Burundi)
-Globalization.ci_fr-BJ = French (Benin)
-Globalization.ci_fr-BL = French (Saint Barthélemy)
-Globalization.ci_fr-CA = French (Canada)
-Globalization.ci_fr-CD = French (Congo DRC)
-Globalization.ci_fr-CF = French (Central African Republic)
-Globalization.ci_fr-CG = French (Congo)
-Globalization.ci_fr-CH = French (Switzerland)
-Globalization.ci_fr-CI = French (Côte d’Ivoire)
-Globalization.ci_fr-CM = French (Cameroon)
-Globalization.ci_fr-DJ = French (Djibouti)
-Globalization.ci_fr-DZ = French (Algeria)
-Globalization.ci_fr-FR = French (France)
-Globalization.ci_fr-GA = French (Gabon)
-Globalization.ci_fr-GF = French (French Guiana)
-Globalization.ci_fr-GN = French (Guinea)
-Globalization.ci_fr-GP = French (Guadeloupe)
-Globalization.ci_fr-GQ = French (Equatorial Guinea)
-Globalization.ci_fr-HT = French (Haiti)
-Globalization.ci_fr-KM = French (Comoros)
-Globalization.ci_fr-LU = French (Luxembourg)
-Globalization.ci_fr-MA = French (Morocco)
-Globalization.ci_fr-MC = French (Monaco)
-Globalization.ci_fr-MF = French (Saint Martin)
-Globalization.ci_fr-MG = French (Madagascar)
-Globalization.ci_fr-ML = French (Mali)
-Globalization.ci_fr-MQ = French (Martinique)
-Globalization.ci_fr-MR = French (Mauritania)
-Globalization.ci_fr-MU = French (Mauritius)
-Globalization.ci_fr-NC = French (New Caledonia)
-Globalization.ci_fr-NE = French (Niger)
-Globalization.ci_fr-PF = French (French Polynesia)
-Globalization.ci_fr-PM = French (Saint Pierre and Miquelon)
-Globalization.ci_fr-RE = French (Reunion)
-Globalization.ci_fr-RW = French (Rwanda)
-Globalization.ci_fr-SC = French (Seychelles)
-Globalization.ci_fr-SN = French (Senegal)
-Globalization.ci_fr-SY = French (Syria)
-Globalization.ci_fr-TD = French (Chad)
-Globalization.ci_fr-TG = French (Togo)
-Globalization.ci_fr-TN = French (Tunisia)
-Globalization.ci_fr-VU = French (Vanuatu)
-Globalization.ci_fr-WF = French (Wallis and Futuna)
-Globalization.ci_fr-YT = French (Mayotte)
-Globalization.ci_fur = Friulian
-Globalization.ci_fur-IT = Friulian (Italy)
-Globalization.ci_fy = Frisian
-Globalization.ci_fy-NL = Frisian (Netherlands)
-Globalization.ci_ga = Irish
-Globalization.ci_ga-IE = Irish (Ireland)
-Globalization.ci_gd = Scottish Gaelic
-Globalization.ci_gd-GB = Scottish Gaelic (United Kingdom)
-Globalization.ci_gl = Galician
-Globalization.ci_gl-ES = Galician (Galician)
-Globalization.ci_gn = Guarani
-Globalization.ci_gn-PY = Guarani (Paraguay)
-Globalization.ci_gsw = Alsatian
-Globalization.ci_gsw-CH = Alsatian (Switzerland)
-Globalization.ci_gsw-FR = Alsatian (France)
-Globalization.ci_gsw-LI = Alsatian (Liechtenstein)
-Globalization.ci_gu = Gujarati
-Globalization.ci_gu-IN = Gujarati (India)
-Globalization.ci_guz = Gusii
-Globalization.ci_guz-KE = Gusii (Kenya)
-Globalization.ci_gv = Manx
-Globalization.ci_gv-IM = Manx (Isle of Man)
-Globalization.ci_ha = Hausa
-Globalization.ci_ha-Latn = Hausa (Latin)
-Globalization.ci_ha-Latn-GH = Hausa (Latin, Ghana)
-Globalization.ci_ha-Latn-NE = Hausa (Latin, Niger)
-Globalization.ci_ha-Latn-NG = Hausa (Latin, Nigeria)
-Globalization.ci_haw = Hawaiian
-Globalization.ci_haw-US = Hawaiian (United States)
-Globalization.ci_he = Hebrew
-Globalization.ci_he-IL = Hebrew (Israel)
-Globalization.ci_hi = Hindi
-Globalization.ci_hi-IN = Hindi (India)
-Globalization.ci_hr = Croatian
-Globalization.ci_hr-BA = Croatian (Latin, Bosnia and Herzegovina)
-Globalization.ci_hr-HR = Croatian (Croatia)
-Globalization.ci_hsb = Upper Sorbian
-Globalization.ci_hsb-DE = Upper Sorbian (Germany)
-Globalization.ci_hu = Hungarian
-Globalization.ci_hu-HU = Hungarian (Hungary)
-Globalization.ci_hu-HU_technl = Hungarian (Hungary)
-Globalization.ci_hy = Armenian
-Globalization.ci_hy-AM = Armenian (Armenia)
-Globalization.ci_ia = Interlingua
-Globalization.ci_ia-001 = Interlingua (World)
-Globalization.ci_ia-FR = Interlingua (France)
-Globalization.ci_id = Indonesian
-Globalization.ci_id-ID = Indonesian (Indonesia)
-Globalization.ci_ig = Igbo
-Globalization.ci_ig-NG = Igbo (Nigeria)
-Globalization.ci_ii = Yi
-Globalization.ci_ii-CN = Yi (PRC)
-Globalization.ci_is = Icelandic
-Globalization.ci_is-IS = Icelandic (Iceland)
-Globalization.ci_it = Italian
-Globalization.ci_it-CH = Italian (Switzerland)
-Globalization.ci_it-IT = Italian (Italy)
-Globalization.ci_it-SM = Italian (San Marino)
-Globalization.ci_iu = Inuktitut
-Globalization.ci_iu-Cans = Inuktitut (Syllabics)
-Globalization.ci_iu-Cans-CA = Inuktitut (Syllabics, Canada)
-Globalization.ci_iu-Latn = Inuktitut (Latin)
-Globalization.ci_iu-Latn-CA = Inuktitut (Latin, Canada)
-Globalization.ci_ja = Japanese
-Globalization.ci_ja-JP = Japanese (Japan)
-Globalization.ci_ja-JP_radstr = Japanese (Japan)
-Globalization.ci_jgo = Ngomba
-Globalization.ci_jgo-CM = Ngomba (Cameroon)
-Globalization.ci_jmc = Machame
-Globalization.ci_jmc-TZ = Machame (Tanzania)
-Globalization.ci_jv = Javanese
-Globalization.ci_jv-Latn = Javanese
-Globalization.ci_jv-Latn-ID = Javanese (Indonesia)
-Globalization.ci_ka = Georgian
-Globalization.ci_ka-GE = Georgian (Georgia)
-Globalization.ci_ka-GE_modern = Georgian (Georgia)
-Globalization.ci_kab = Kabyle
-Globalization.ci_kab-DZ = Kabyle (Algeria)
-Globalization.ci_kam = Kamba
-Globalization.ci_kam-KE = Kamba (Kenya)
-Globalization.ci_kde = Makonde
-Globalization.ci_kde-TZ = Makonde (Tanzania)
-Globalization.ci_kea = Kabuverdianu
-Globalization.ci_kea-CV = Kabuverdianu (Cabo Verde)
-Globalization.ci_khq = Koyra Chiini
-Globalization.ci_khq-ML = Koyra Chiini (Mali)
-Globalization.ci_ki = Kikuyu
-Globalization.ci_ki-KE = Kikuyu (Kenya)
-Globalization.ci_kk = Kazakh
-Globalization.ci_kk-KZ = Kazakh (Kazakhstan)
-Globalization.ci_kkj = Kako
-Globalization.ci_kkj-CM = Kako (Cameroon)
-Globalization.ci_kl = Greenlandic
-Globalization.ci_kl-GL = Greenlandic (Greenland)
-Globalization.ci_kln = Kalenjin
-Globalization.ci_kln-KE = Kalenjin (Kenya)
-Globalization.ci_km = Khmer
-Globalization.ci_km-KH = Khmer (Cambodia)
-Globalization.ci_kn = Kannada
-Globalization.ci_kn-IN = Kannada (India)
-Globalization.ci_ko = Korean
-Globalization.ci_ko-KR = Korean (Korea)
-Globalization.ci_kok = Konkani
-Globalization.ci_kok-IN = Konkani (India)
-Globalization.ci_ks = Kashmiri
-Globalization.ci_ks-Arab = Kashmiri (Perso-Arabic)
-Globalization.ci_ks-Arab-IN = Kashmiri (Perso-Arabic)
-Globalization.ci_ksb = Shambala
-Globalization.ci_ksb-TZ = Shambala (Tanzania)
-Globalization.ci_ksf = Bafia
-Globalization.ci_ksf-CM = Bafia (Cameroon)
-Globalization.ci_ksh = Colognian
-Globalization.ci_ksh-DE = Ripuarian (Germany)
-Globalization.ci_ku = Central Kurdish
-Globalization.ci_ku-Arab = Central Kurdish (Arabic)
-Globalization.ci_ku-Arab-IQ = Central Kurdish (Iraq)
-Globalization.ci_kw = Cornish
-Globalization.ci_kw-GB = Cornish (United Kingdom)
-Globalization.ci_ky = Kyrgyz
-Globalization.ci_ky-KG = Kyrgyz (Kyrgyzstan)
-Globalization.ci_lag = Langi
-Globalization.ci_lag-TZ = Langi (Tanzania)
-Globalization.ci_lb = Luxembourgish
-Globalization.ci_lb-LU = Luxembourgish (Luxembourg)
-Globalization.ci_lg = Ganda
-Globalization.ci_lg-UG = Ganda (Uganda)
-Globalization.ci_lkt = Lakota
-Globalization.ci_lkt-US = Lakota (United States)
-Globalization.ci_ln = Lingala
-Globalization.ci_ln-AO = Lingala (Angola)
-Globalization.ci_ln-CD = Lingala (Congo DRC)
-Globalization.ci_ln-CF = Lingala (Central African Republic)
-Globalization.ci_ln-CG = Lingala (Congo)
-Globalization.ci_lo = Lao
-Globalization.ci_lo-LA = Lao (Lao P.D.R.)
-Globalization.ci_lt = Lithuanian
-Globalization.ci_lt-LT = Lithuanian (Lithuania)
-Globalization.ci_lu = Luba-Katanga
-Globalization.ci_lu-CD = Luba-Katanga (Congo DRC)
-Globalization.ci_luo = Luo
-Globalization.ci_luo-KE = Luo (Kenya)
-Globalization.ci_luy = Luyia
-Globalization.ci_luy-KE = Luyia (Kenya)
-Globalization.ci_lv = Latvian
-Globalization.ci_lv-LV = Latvian (Latvia)
-Globalization.ci_mas = Masai
-Globalization.ci_mas-KE = Masai (Kenya)
-Globalization.ci_mas-TZ = Masai (Tanzania)
-Globalization.ci_mer = Meru
-Globalization.ci_mer-KE = Meru (Kenya)
-Globalization.ci_mfe = Morisyen
-Globalization.ci_mfe-MU = Morisyen (Mauritius)
-Globalization.ci_mg = Malagasy
-Globalization.ci_mg-MG = Malagasy (Madagascar)
-Globalization.ci_mgh = Makhuwa-Meetto
-Globalization.ci_mgh-MZ = Makhuwa-Meetto (Mozambique)
-Globalization.ci_mgo = Meta'
-Globalization.ci_mgo-CM = Meta' (Cameroon)
-Globalization.ci_mi = Maori
-Globalization.ci_mi-NZ = Maori (New Zealand)
-Globalization.ci_mk = Macedonian (FYROM)
-Globalization.ci_mk-MK = Macedonian (Former Yugoslav Republic of Macedonia)
-Globalization.ci_ml = Malayalam
-Globalization.ci_ml-IN = Malayalam (India)
-Globalization.ci_mn = Mongolian
-Globalization.ci_mn-Cyrl = Mongolian (Cyrillic)
-Globalization.ci_mn-MN = Mongolian (Cyrillic, Mongolia)
-Globalization.ci_mn-Mong = Mongolian (Traditional Mongolian)
-Globalization.ci_mn-Mong-CN = Mongolian (Traditional Mongolian, PRC)
-Globalization.ci_mn-Mong-MN = Mongolian (Traditional Mongolian, Mongolia)
-Globalization.ci_moh = Mohawk
-Globalization.ci_moh-CA = Mohawk (Mohawk)
-Globalization.ci_mr = Marathi
-Globalization.ci_mr-IN = Marathi (India)
-Globalization.ci_ms = Malay
-Globalization.ci_ms-BN = Malay (Brunei Darussalam)
-Globalization.ci_ms-MY = Malay (Malaysia)
-Globalization.ci_ms-SG = Malay (Latin, Singapore)
-Globalization.ci_mt = Maltese
-Globalization.ci_mt-MT = Maltese (Malta)
-Globalization.ci_mua = Mundang
-Globalization.ci_mua-CM = Mundang (Cameroon)
-Globalization.ci_my = Burmese
-Globalization.ci_my-MM = Burmese (Myanmar)
-Globalization.ci_naq = Nama
-Globalization.ci_naq-NA = Nama (Namibia)
-Globalization.ci_nb = Norwegian (Bokmål)
-Globalization.ci_nb-NO = Norwegian, Bokmål (Norway)
-Globalization.ci_nb-SJ = Norwegian, Bokmål (Svalbard and Jan Mayen)
-Globalization.ci_nd = North Ndebele
-Globalization.ci_nd-ZW = North Ndebele (Zimbabwe)
-Globalization.ci_ne = Nepali
-Globalization.ci_ne-IN = Nepali (India)
-Globalization.ci_ne-NP = Nepali (Nepal)
-Globalization.ci_nl = Dutch
-Globalization.ci_nl-AW = Dutch (Aruba)
-Globalization.ci_nl-BE = Dutch (Belgium)
-Globalization.ci_nl-BQ = Dutch (Bonaire, Sint Eustatius and Saba)
-Globalization.ci_nl-CW = Dutch (Curaçao)
-Globalization.ci_nl-NL = Dutch (Netherlands)
-Globalization.ci_nl-SR = Dutch (Suriname)
-Globalization.ci_nl-SX = Dutch (Sint Maarten)
-Globalization.ci_nmg = Kwasio
-Globalization.ci_nmg-CM = Kwasio (Cameroon)
-Globalization.ci_nn = Norwegian (Nynorsk)
-Globalization.ci_nn-NO = Norwegian, Nynorsk (Norway)
-Globalization.ci_nnh = Ngiemboon
-Globalization.ci_nnh-CM = Ngiemboon (Cameroon)
-Globalization.ci_no = Norwegian
-Globalization.ci_nqo = N'ko
-Globalization.ci_nqo-GN = N'ko (Guinea)
-Globalization.ci_nr = South Ndebele
-Globalization.ci_nr-ZA = South Ndebele (South Africa)
-Globalization.ci_nso = Sesotho sa Leboa
-Globalization.ci_nso-ZA = Sesotho sa Leboa (South Africa)
-Globalization.ci_nus = Nuer
-Globalization.ci_nus-SD = Nuer (Sudan)
-Globalization.ci_nyn = Nyankole
-Globalization.ci_nyn-UG = Nyankole (Uganda)
-Globalization.ci_oc = Occitan
-Globalization.ci_oc-FR = Occitan (France)
-Globalization.ci_om = Oromo
-Globalization.ci_om-ET = Oromo (Ethiopia)
-Globalization.ci_om-KE = Oromo (Kenya)
-Globalization.ci_or = Odia
-Globalization.ci_or-IN = Odia (India)
-Globalization.ci_os = Ossetic
-Globalization.ci_os-GE = Ossetian (Cyrillic, Georgia)
-Globalization.ci_os-RU = Ossetian (Cyrillic, Russia)
-Globalization.ci_pa = Punjabi
-Globalization.ci_pa-Arab = Punjabi (Arabic)
-Globalization.ci_pa-Arab-PK = Punjabi (Islamic Republic of Pakistan)
-Globalization.ci_pa-IN = Punjabi (India)
-Globalization.ci_pl = Polish
-Globalization.ci_pl-PL = Polish (Poland)
-Globalization.ci_prs = Dari
-Globalization.ci_prs-AF = Dari (Afghanistan)
-Globalization.ci_ps = Pashto
-Globalization.ci_ps-AF = Pashto (Afghanistan)
-Globalization.ci_pt = Portuguese
-Globalization.ci_pt-AO = Portuguese (Angola)
-Globalization.ci_pt-BR = Portuguese (Brazil)
-Globalization.ci_pt-CV = Portuguese (Cabo Verde)
-Globalization.ci_pt-GW = Portuguese (Guinea-Bissau)
-Globalization.ci_pt-MO = Portuguese (Macao SAR)
-Globalization.ci_pt-MZ = Portuguese (Mozambique)
-Globalization.ci_pt-PT = Portuguese (Portugal)
-Globalization.ci_pt-ST = Portuguese (São Tomé and Príncipe)
-Globalization.ci_pt-TL = Portuguese (Timor-Leste)
-Globalization.ci_qps-ploc = Pseudo Language (Pseudo)
-Globalization.ci_qps-ploca = Pseudo Language (Pseudo Asia)
-Globalization.ci_qps-plocm = Pseudo Language (Pseudo Mirrored)
-Globalization.ci_qu = Quechua
-Globalization.ci_qu-BO = Quechua (Bolivia)
-Globalization.ci_qu-EC = Quechua (Ecuador)
-Globalization.ci_qu-PE = Quechua (Peru)
-Globalization.ci_quc = K'iche'
-Globalization.ci_quc-Latn = K'iche'
-Globalization.ci_quc-Latn-GT = K'iche' (Guatemala)
-Globalization.ci_qut = K'iche
-Globalization.ci_qut-GT = K'iche (Guatemala)
-Globalization.ci_quz = Quechua
-Globalization.ci_quz-BO = Quechua (Bolivia)
-Globalization.ci_quz-EC = Quechua (Ecuador)
-Globalization.ci_quz-PE = Quechua (Peru)
-Globalization.ci_rm = Romansh
-Globalization.ci_rm-CH = Romansh (Switzerland)
-Globalization.ci_rn = Rundi
-Globalization.ci_rn-BI = Rundi (Burundi)
-Globalization.ci_ro = Romanian
-Globalization.ci_ro-MD = Romanian (Moldova)
-Globalization.ci_ro-RO = Romanian (Romania)
-Globalization.ci_rof = Rombo
-Globalization.ci_rof-TZ = Rombo (Tanzania)
-Globalization.ci_ru = Russian
-Globalization.ci_ru-BY = Russian (Belarus)
-Globalization.ci_ru-KG = Russian (Kyrgyzstan)
-Globalization.ci_ru-KZ = Russian (Kazakhstan)
-Globalization.ci_ru-MD = Russian (Moldova)
-Globalization.ci_ru-RU = Russian (Russia)
-Globalization.ci_ru-UA = Russian (Ukraine)
-Globalization.ci_rw = Kinyarwanda
-Globalization.ci_rw-RW = Kinyarwanda (Rwanda)
-Globalization.ci_rwk = Rwa
-Globalization.ci_rwk-TZ = Rwa (Tanzania)
-Globalization.ci_sa = Sanskrit
-Globalization.ci_sa-IN = Sanskrit (India)
-Globalization.ci_sah = Sakha
-Globalization.ci_sah-RU = Sakha (Russia)
-Globalization.ci_saq = Samburu
-Globalization.ci_saq-KE = Samburu (Kenya)
-Globalization.ci_sbp = Sangu
-Globalization.ci_sbp-TZ = Sangu (Tanzania)
-Globalization.ci_sd = Sindhi
-Globalization.ci_sd-Arab = Sindhi (Arabic)
-Globalization.ci_sd-Arab-PK = Sindhi (Islamic Republic of Pakistan)
-Globalization.ci_se = Sami (Northern)
-Globalization.ci_se-FI = Sami, Northern (Finland)
-Globalization.ci_se-NO = Sami, Northern (Norway)
-Globalization.ci_se-SE = Sami, Northern (Sweden)
-Globalization.ci_seh = Sena
-Globalization.ci_seh-MZ = Sena (Mozambique)
-Globalization.ci_ses = Koyraboro Senni
-Globalization.ci_ses-ML = Koyraboro Senni (Mali)
-Globalization.ci_sg = Sango
-Globalization.ci_sg-CF = Sango (Central African Republic)
-Globalization.ci_shi = Tachelhit
-Globalization.ci_shi-Latn = Tachelhit (Latin)
-Globalization.ci_shi-Latn-MA = Tachelhit (Latin, Morocco)
-Globalization.ci_shi-Tfng = Tachelhit (Tifinagh)
-Globalization.ci_shi-Tfng-MA = Tachelhit (Tifinagh, Morocco)
-Globalization.ci_si = Sinhala
-Globalization.ci_si-LK = Sinhala (Sri Lanka)
-Globalization.ci_sk = Slovak
-Globalization.ci_sk-SK = Slovak (Slovakia)
-Globalization.ci_sl = Slovenian
-Globalization.ci_sl-SI = Slovenian (Slovenia)
-Globalization.ci_sma = Sami (Southern)
-Globalization.ci_sma-NO = Sami, Southern (Norway)
-Globalization.ci_sma-SE = Sami, Southern (Sweden)
-Globalization.ci_smj = Sami (Lule)
-Globalization.ci_smj-NO = Sami, Lule (Norway)
-Globalization.ci_smj-SE = Sami, Lule (Sweden)
-Globalization.ci_smn = Sami (Inari)
-Globalization.ci_smn-FI = Sami, Inari (Finland)
-Globalization.ci_sms = Sami (Skolt)
-Globalization.ci_sms-FI = Sami, Skolt (Finland)
-Globalization.ci_sn = Shona
-Globalization.ci_sn-Latn = Shona (Latin)
-Globalization.ci_sn-Latn-ZW = Shona (Latin, Zimbabwe)
-Globalization.ci_so = Somali
-Globalization.ci_so-DJ = Somali (Djibouti)
-Globalization.ci_so-ET = Somali (Ethiopia)
-Globalization.ci_so-KE = Somali (Kenya)
-Globalization.ci_so-SO = Somali (Somalia)
-Globalization.ci_sq = Albanian
-Globalization.ci_sq-AL = Albanian (Albania)
-Globalization.ci_sq-MK = Albanian (Macedonia, FYRO)
-Globalization.ci_sr = Serbian
-Globalization.ci_sr-Cyrl = Serbian (Cyrillic)
-Globalization.ci_sr-Cyrl-BA = Serbian (Cyrillic, Bosnia and Herzegovina)
-Globalization.ci_sr-Cyrl-CS = Serbian (Cyrillic, Serbia and Montenegro (Former))
-Globalization.ci_sr-Cyrl-ME = Serbian (Cyrillic, Montenegro)
-Globalization.ci_sr-Cyrl-RS = Serbian (Cyrillic, Serbia)
-Globalization.ci_sr-Latn = Serbian (Latin)
-Globalization.ci_sr-Latn-BA = Serbian (Latin, Bosnia and Herzegovina)
-Globalization.ci_sr-Latn-CS = Serbian (Latin, Serbia and Montenegro (Former))
-Globalization.ci_sr-Latn-ME = Serbian (Latin, Montenegro)
-Globalization.ci_sr-Latn-RS = Serbian (Latin, Serbia)
-Globalization.ci_ss = Swati
-Globalization.ci_ss-SZ = Swati (Swaziland)
-Globalization.ci_ss-ZA = Swati (South Africa)
-Globalization.ci_ssy = Saho
-Globalization.ci_ssy-ER = Saho (Eritrea)
-Globalization.ci_st = Southern Sotho
-Globalization.ci_st-LS = Sesotho (Lesotho)
-Globalization.ci_st-ZA = Southern Sotho (South Africa)
-Globalization.ci_sv = Swedish
-Globalization.ci_sv-AX = Swedish (Ã…land Islands)
-Globalization.ci_sv-FI = Swedish (Finland)
-Globalization.ci_sv-SE = Swedish (Sweden)
-Globalization.ci_sw = Kiswahili
-Globalization.ci_sw-KE = Kiswahili (Kenya)
-Globalization.ci_sw-TZ = Kiswahili (Tanzania)
-Globalization.ci_sw-UG = Kiswahili (Uganda)
-Globalization.ci_swc = Congo Swahili
-Globalization.ci_swc-CD = Congo Swahili (Congo DRC)
-Globalization.ci_syr = Syriac
-Globalization.ci_syr-SY = Syriac (Syria)
-Globalization.ci_ta = Tamil
-Globalization.ci_ta-IN = Tamil (India)
-Globalization.ci_ta-LK = Tamil (Sri Lanka)
-Globalization.ci_ta-MY = Tamil (Malaysia)
-Globalization.ci_ta-SG = Tamil (Singapore)
-Globalization.ci_te = Telugu
-Globalization.ci_te-IN = Telugu (India)
-Globalization.ci_teo = Teso
-Globalization.ci_teo-KE = Teso (Kenya)
-Globalization.ci_teo-UG = Teso (Uganda)
-Globalization.ci_tg = Tajik
-Globalization.ci_tg-Cyrl = Tajik (Cyrillic)
-Globalization.ci_tg-Cyrl-TJ = Tajik (Cyrillic, Tajikistan)
-Globalization.ci_th = Thai
-Globalization.ci_th-TH = Thai (Thailand)
-Globalization.ci_ti = Tigrinya
-Globalization.ci_ti-ER = Tigrinya (Eritrea)
-Globalization.ci_ti-ET = Tigrinya (Ethiopia)
-Globalization.ci_tig = Tigre
-Globalization.ci_tig-ER = Tigre (Eritrea)
-Globalization.ci_tk = Turkmen
-Globalization.ci_tk-TM = Turkmen (Turkmenistan)
-Globalization.ci_tn = Setswana
-Globalization.ci_tn-BW = Setswana (Botswana)
-Globalization.ci_tn-ZA = Setswana (South Africa)
-Globalization.ci_to = Tongan
-Globalization.ci_to-TO = Tongan (Tonga)
-Globalization.ci_tr = Turkish
-Globalization.ci_tr-CY = Turkish (Cyprus)
-Globalization.ci_tr-TR = Turkish (Turkey)
-Globalization.ci_ts = Tsonga
-Globalization.ci_ts-ZA = Tsonga (South Africa)
-Globalization.ci_tt = Tatar
-Globalization.ci_tt-RU = Tatar (Russia)
-Globalization.ci_twq = Tasawaq
-Globalization.ci_twq-NE = Tasawaq (Niger)
-Globalization.ci_tzm = Tamazight
-Globalization.ci_tzm-Latn = Tamazight (Latin)
-Globalization.ci_tzm-Latn-DZ = Tamazight (Latin, Algeria)
-Globalization.ci_tzm-Latn-MA = Central Atlas Tamazight (Latin, Morocco)
-Globalization.ci_tzm-Tfng = Tamazight (Tifinagh)
-Globalization.ci_tzm-Tfng-MA = Central Atlas Tamazight (Tifinagh, Morocco)
-Globalization.ci_ug = Uyghur
-Globalization.ci_ug-CN = Uyghur (PRC)
-Globalization.ci_uk = Ukrainian
-Globalization.ci_uk-UA = Ukrainian (Ukraine)
-Globalization.ci_ur = Urdu
-Globalization.ci_ur-IN = Urdu (India)
-Globalization.ci_ur-PK = Urdu (Islamic Republic of Pakistan)
-Globalization.ci_uz = Uzbek
-Globalization.ci_uz-Arab = Uzbek (Perso-Arabic)
-Globalization.ci_uz-Arab-AF = Uzbek (Perso-Arabic, Afghanistan)
-Globalization.ci_uz-Cyrl = Uzbek (Cyrillic)
-Globalization.ci_uz-Cyrl-UZ = Uzbek (Cyrillic, Uzbekistan)
-Globalization.ci_uz-Latn = Uzbek (Latin)
-Globalization.ci_uz-Latn-UZ = Uzbek (Latin, Uzbekistan)
-Globalization.ci_vai = Vai
-Globalization.ci_vai-Latn = Vai (Latin)
-Globalization.ci_vai-Latn-LR = Vai (Latin, Liberia)
-Globalization.ci_vai-Vaii = Vai (Vai)
-Globalization.ci_vai-Vaii-LR = Vai (Vai, Liberia)
-Globalization.ci_ve = Venda
-Globalization.ci_ve-ZA = Venda (South Africa)
-Globalization.ci_vi = Vietnamese
-Globalization.ci_vi-VN = Vietnamese (Vietnam)
-Globalization.ci_vo = Volapük
-Globalization.ci_vo-001 = Volapük (World)
-Globalization.ci_vun = Vunjo
-Globalization.ci_vun-TZ = Vunjo (Tanzania)
-Globalization.ci_wae = Walser
-Globalization.ci_wae-CH = Walser (Switzerland)
-Globalization.ci_wal = Wolaytta
-Globalization.ci_wal-ET = Wolaytta (Ethiopia)
-Globalization.ci_wo = Wolof
-Globalization.ci_wo-SN = Wolof (Senegal)
-Globalization.ci_x-IV = Invariant Language (Invariant Country)
-Globalization.ci_x-IV_mathan = Invariant Language (Invariant Country)
-Globalization.ci_xh = isiXhosa
-Globalization.ci_xh-ZA = isiXhosa (South Africa)
-Globalization.ci_xog = Soga
-Globalization.ci_xog-UG = Soga (Uganda)
-Globalization.ci_yav = Yangben
-Globalization.ci_yav-CM = Yangben (Cameroon)
-Globalization.ci_yi = Yiddish
-Globalization.ci_yi-001 = Yiddish (World)
-Globalization.ci_yo = Yoruba
-Globalization.ci_yo-BJ = Yoruba (Benin)
-Globalization.ci_yo-NG = Yoruba (Nigeria)
-Globalization.ci_zgh = Standard Moroccan Tamazight
-Globalization.ci_zgh-Tfng = Standard Moroccan Tamazight (Tifinagh)
-Globalization.ci_zgh-Tfng-MA = Standard Moroccan Tamazight (Tifinagh, Morocco)
-Globalization.ci_zh = Chinese
-Globalization.ci_zh-CHS = Chinese (Simplified) Legacy
-Globalization.ci_zh-CHT = Chinese (Traditional) Legacy
-Globalization.ci_zh-CN = Chinese (Simplified, PRC)
-Globalization.ci_zh-CN_stroke = Chinese (Simplified, PRC)
-Globalization.ci_zh-Hans = Chinese (Simplified)
-Globalization.ci_zh-Hant = Chinese (Traditional)
-Globalization.ci_zh-HK = Chinese (Traditional, Hong Kong S.A.R.)
-Globalization.ci_zh-HK_radstr = Chinese (Traditional, Hong Kong S.A.R.)
-Globalization.ci_zh-MO = Chinese (Traditional, Macao S.A.R.)
-Globalization.ci_zh-MO_radstr = Chinese (Traditional, Macao S.A.R.)
-Globalization.ci_zh-MO_stroke = Chinese (Traditional, Macao S.A.R.)
-Globalization.ci_zh-SG = Chinese (Simplified, Singapore)
-Globalization.ci_zh-SG_stroke = Chinese (Simplified, Singapore)
-Globalization.ci_zh-TW = Chinese (Traditional, Taiwan)
-Globalization.ci_zh-TW_pronun = Chinese (Traditional, Taiwan)
-Globalization.ci_zh-TW_radstr = Chinese (Traditional, Taiwan)
-Globalization.ci_zu = isiZulu
-Globalization.ci_zu-ZA = isiZulu (South Africa)
-;------------------
-;
-;Total items: 129
-;
-Globalization.ri_029 = Caribbean
-Globalization.ri_AE = U.A.E.
-Globalization.ri_AF = Afghanistan
-Globalization.ri_AL = Albania
-Globalization.ri_AM = Armenia
-Globalization.ri_AR = Argentina
-Globalization.ri_AT = Austria
-Globalization.ri_AU = Australia
-Globalization.ri_AZ = Azerbaijan
-Globalization.ri_BA = Bosnia and Herzegovina
-Globalization.ri_BD = Bangladesh
-Globalization.ri_BE = Belgium
-Globalization.ri_BG = Bulgaria
-Globalization.ri_BH = Bahrain
-Globalization.ri_BN = Brunei Darussalam
-Globalization.ri_BO = Bolivia
-Globalization.ri_BR = Brazil
-Globalization.ri_BY = Belarus
-Globalization.ri_BZ = Belize
-Globalization.ri_CA = Canada
-Globalization.ri_CH = Switzerland
-Globalization.ri_CL = Chile
-Globalization.ri_CN = People's Republic of China
-Globalization.ri_CO = Colombia
-Globalization.ri_CR = Costa Rica
-Globalization.ri_CS = Serbia and Montenegro (Former)
-Globalization.ri_CZ = Czech Republic
-Globalization.ri_DE = Germany
-Globalization.ri_DK = Denmark
-Globalization.ri_DO = Dominican Republic
-Globalization.ri_DZ = Algeria
-Globalization.ri_EC = Ecuador
-Globalization.ri_EE = Estonia
-Globalization.ri_EG = Egypt
-Globalization.ri_ER = Eritrea
-Globalization.ri_ES = Spain
-Globalization.ri_ET = Ethiopia
-Globalization.ri_FI = Finland
-Globalization.ri_FO = Faroe Islands
-Globalization.ri_FR = France
-Globalization.ri_GB = United Kingdom
-Globalization.ri_GE = Georgia
-Globalization.ri_GL = Greenland
-Globalization.ri_GR = Greece
-Globalization.ri_GT = Guatemala
-Globalization.ri_HK = Hong Kong S.A.R.
-Globalization.ri_HN = Honduras
-Globalization.ri_HR = Croatia
-Globalization.ri_HU = Hungary
-Globalization.ri_ID = Indonesia
-Globalization.ri_IE = Ireland
-Globalization.ri_IL = Israel
-Globalization.ri_IN = India
-Globalization.ri_IQ = Iraq
-Globalization.ri_IR = Iran
-Globalization.ri_IS = Iceland
-Globalization.ri_IT = Italy
-Globalization.ri_IV = Invariant Country
-Globalization.ri_JM = Jamaica
-Globalization.ri_JO = Jordan
-Globalization.ri_JP = Japan
-Globalization.ri_KE = Kenya
-Globalization.ri_KG = Kyrgyzstan
-Globalization.ri_KH = Cambodia
-Globalization.ri_KR = Korea
-Globalization.ri_KW = Kuwait
-Globalization.ri_KZ = Kazakhstan
-Globalization.ri_LA = Lao P.D.R.
-Globalization.ri_LB = Lebanon
-Globalization.ri_LI = Liechtenstein
-Globalization.ri_LK = Sri Lanka
-Globalization.ri_LT = Lithuania
-Globalization.ri_LU = Luxembourg
-Globalization.ri_LV = Latvia
-Globalization.ri_LY = Libya
-Globalization.ri_MA = Morocco
-Globalization.ri_MC = Principality of Monaco
-Globalization.ri_ME = Montenegro
-Globalization.ri_MK = Macedonia (FYROM)
-Globalization.ri_MN = Mongolia
-Globalization.ri_MO = Macao S.A.R.
-Globalization.ri_MT = Malta
-Globalization.ri_MV = Maldives
-Globalization.ri_MX = Mexico
-Globalization.ri_MY = Malaysia
-Globalization.ri_NG = Nigeria
-Globalization.ri_NI = Nicaragua
-Globalization.ri_NL = Netherlands
-Globalization.ri_NO = Norway
-Globalization.ri_NP = Nepal
-Globalization.ri_NZ = New Zealand
-Globalization.ri_OM = Oman
-Globalization.ri_PA = Panama
-Globalization.ri_PE = Peru
-Globalization.ri_PH = Philippines
-Globalization.ri_PK = Islamic Republic of Pakistan
-Globalization.ri_PL = Poland
-Globalization.ri_PR = Puerto Rico
-Globalization.ri_PT = Portugal
-Globalization.ri_PY = Paraguay
-Globalization.ri_QA = Qatar
-Globalization.ri_RO = Romania
-Globalization.ri_RS = Serbia
-Globalization.ri_RU = Russia
-Globalization.ri_RW = Rwanda
-Globalization.ri_SA = Saudi Arabia
-Globalization.ri_SE = Sweden
-Globalization.ri_SG = Singapore
-Globalization.ri_SI = Slovenia
-Globalization.ri_SK = Slovakia
-Globalization.ri_SN = Senegal
-Globalization.ri_SV = El Salvador
-Globalization.ri_SY = Syria
-Globalization.ri_TH = Thailand
-Globalization.ri_TJ = Tajikistan
-Globalization.ri_TM = Turkmenistan
-Globalization.ri_TN = Tunisia
-Globalization.ri_TR = Turkey
-Globalization.ri_TT = Trinidad and Tobago
-Globalization.ri_TW = Taiwan
-Globalization.ri_UA = Ukraine
-Globalization.ri_US = United States
-Globalization.ri_UY = Uruguay
-Globalization.ri_UZ = Uzbekistan
-Globalization.ri_VE = Bolivarian Republic of Venezuela
-Globalization.ri_VN = Vietnam
-Globalization.ri_YE = Yemen
-Globalization.ri_ZA = South Africa
-Globalization.ri_ZW = Zimbabwe
-#endif //!FEATURE_CORECLR
-
-;------------------
-; 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
-
-;------------------
-
diff --git a/src/nativeresources/resourcestring.cpp b/src/nativeresources/resourcestring.cpp
index 13d5aeeef9..236a2a3ca7 100644
--- a/src/nativeresources/resourcestring.cpp
+++ b/src/nativeresources/resourcestring.cpp
@@ -42,11 +42,11 @@ int LoadNativeStringResource(const NativeStringResourceTable &nativeStringResour
else
{
// The resource ID wasn't found in our array. Fall back on returning the ID as a string.
- len = _snwprintf(szBuffer, iMax - 1, W("[Undefined resource string ID:0x%X]"), iResourceID);
- if ((len < 0) || (len == (iMax - 1)))
- {
- // Add string terminator if the result of _snwprintf didn't fit the buffer.
- szBuffer[iMax - 1] = W('\0');
+ len = _snwprintf_s(szBuffer, iMax, _TRUNCATE, W("[Undefined resource string ID:0x%X]"), iResourceID);
+ if (len < 0)
+ {
+ // The only possible failure is that that string didn't fit the buffer. So the buffer contains
+ // partial string terminated by '\0'
len = iMax - 1;
}
}
diff --git a/src/pal/inc/mbusafecrt.h b/src/pal/inc/mbusafecrt.h
index c25676c499..8cf050f419 100644
--- a/src/pal/inc/mbusafecrt.h
+++ b/src/pal/inc/mbusafecrt.h
@@ -31,16 +31,6 @@ typedef int errno_t;
// define the return value for success
#define SAFECRT_SUCCESS 0
-/*
- * Sizes for buffers used by the _makepath() and _splitpath() functions.
- * note that the sizes include space for 0-terminator
- */
-//#define _MAX_PATH 260 /* max. length of full pathname */
-//#define _MAX_DRIVE 3 /* max. length of drive component */
-//#define _MAX_DIR 256 /* max. length of path component */
-//#define _MAX_FNAME 256 /* max. length of file name component */
-//#define _MAX_EXT 256 /* max. length of extension component */
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -65,7 +55,7 @@ extern WCHAR* wcstok_s( WCHAR* inString, const WCHAR* inControl, WCHAR** ioConte
// strnlen is not required unless the source string is completely untrusted (e.g. anonymous input on a website)
#ifndef SUPPRESS_STRNLEN
- extern size_t strnlen( const char* inString, size_t inMaxSize );
+ extern size_t PAL_strnlen( const char* inString, size_t inMaxSize );
extern size_t wcsnlen( const WCHAR* inString, size_t inMaxSize );
#endif
@@ -96,10 +86,10 @@ extern int swprintf_s( WCHAR *string, size_t sizeInWords, const WCHAR *format, .
extern int _snprintf_s( char *string, size_t sizeInBytes, size_t count, const char *format, ... );
extern int _snwprintf_s( WCHAR *string, size_t sizeInWords, size_t count, const WCHAR *format, ... );
-extern int _vsprintf_s( char* string, size_t sizeInBytes, const char* format, va_list arglist );
+extern int vsprintf_s( char* string, size_t sizeInBytes, const char* format, va_list arglist );
extern int _vsnprintf_s( char* string, size_t sizeInBytes, size_t count, const char* format, va_list arglist );
-extern int _vswprintf_s( WCHAR* string, size_t sizeInWords, const WCHAR* format, va_list arglist );
+extern int vswprintf_s( WCHAR* string, size_t sizeInWords, const WCHAR* format, va_list arglist );
extern int _vsnwprintf_s( WCHAR* string, size_t sizeInWords, size_t count, const WCHAR* format, va_list arglist );
extern int sscanf_s( const char *string, const char *format, ... );
diff --git a/src/pal/inc/pal.h b/src/pal/inc/pal.h
index 260528285e..0d7c89e6fa 100644
--- a/src/pal/inc/pal.h
+++ b/src/pal/inc/pal.h
@@ -331,7 +331,7 @@ typedef char * va_list;
PALIMPORT
BOOL
PALAPI
-PAL_IsDebuggerPresent();
+PAL_IsDebuggerPresent(VOID);
#define MAXIMUM_SUSPEND_COUNT MAXCHAR
@@ -507,7 +507,7 @@ PAL_Initialize(
PALIMPORT
int
PALAPI
-PAL_InitializeDLL();
+PAL_InitializeDLL(VOID);
PALIMPORT
DWORD
@@ -581,7 +581,7 @@ PAL_UnregisterForRuntimeStartup(
PALIMPORT
BOOL
PALAPI
-PAL_NotifyRuntimeStarted();
+PAL_NotifyRuntimeStarted(VOID);
static const int MAX_DEBUGGER_TRANSPORT_PIPE_NAME_LENGTH = 64;
@@ -648,6 +648,13 @@ PAL_DeleteExecWatchpoint(
#endif
+PALIMPORT
+BOOL
+PALAPI
+PAL_ProbeMemory(
+ PVOID pBuffer,
+ DWORD cbBuffer,
+ BOOL fWriteAccess);
/******************* winuser.h Entrypoints *******************************/
@@ -671,28 +678,6 @@ CharNextExA(
#endif
-PALIMPORT
-int
-PALAPIV
-wsprintfA(
- OUT LPSTR,
- IN LPCSTR,
- ...);
-
-PALIMPORT
-int
-PALAPIV
-wsprintfW(
- OUT LPWSTR,
- IN LPCWSTR,
- ...);
-
-#ifdef UNICODE
-#define wsprintf wsprintfW
-#else
-#define wsprintf wsprintfA
-#endif
-
#define MB_OK 0x00000000L
#define MB_OKCANCEL 0x00000001L
#define MB_ABORTRETRYIGNORE 0x00000002L
@@ -1853,6 +1838,13 @@ QueueUserAPC(
#define MAXIMUM_SUPPORTED_EXTENSION 512
+#define CONTEXT_XSTATE (CONTEXT_i386 | 0x40L)
+
+#define CONTEXT_EXCEPTION_ACTIVE 0x8000000L
+#define CONTEXT_SERVICE_ACTIVE 0x10000000L
+#define CONTEXT_EXCEPTION_REQUEST 0x40000000L
+#define CONTEXT_EXCEPTION_REPORTING 0x80000000L
+
typedef struct _FLOATING_SAVE_AREA {
DWORD ControlWord;
DWORD StatusWord;
@@ -1911,6 +1903,16 @@ 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_POINTERS {
+
+ // TODO WIP x86/Linux, need to fix this.
+ PDWORD Ebx;
+ PDWORD Esi;
+ PDWORD Edi;
+ PDWORD Ebp;
+
+} KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS;
+
#elif defined(_PPC_)
//
@@ -3256,22 +3258,22 @@ TlsFree(
PALIMPORT
void *
PALAPI
-PAL_GetStackBase();
+PAL_GetStackBase(VOID);
PALIMPORT
void *
PALAPI
-PAL_GetStackLimit();
+PAL_GetStackLimit(VOID);
PALIMPORT
DWORD
PALAPI
-PAL_GetLogicalCpuCountFromOS();
+PAL_GetLogicalCpuCountFromOS(VOID);
PALIMPORT
size_t
PALAPI
-PAL_GetLogicalProcessorCacheSizeFromOS();
+PAL_GetLogicalProcessorCacheSizeFromOS(VOID);
typedef BOOL (*ReadMemoryWordCallback)(SIZE_T address, SIZE_T *value);
@@ -3304,6 +3306,8 @@ PALIMPORT BOOL PALAPI PAL_VirtualUnwindOutOfProc(CONTEXT *context,
#define PAL_CS_NATIVE_DATA_SIZE 80
#elif defined(__linux__) && defined(_ARM64_)
#define PAL_CS_NATIVE_DATA_SIZE 116
+#elif defined(__linux__) && defined(__i386__)
+#define PAL_CS_NATIVE_DATA_SIZE 76
#elif defined(__linux__) && defined(__x86_64__)
#define PAL_CS_NATIVE_DATA_SIZE 96
#elif defined(__NetBSD__) && defined(__amd64__)
@@ -3656,16 +3660,6 @@ VirtualQuery(
IN SIZE_T dwLength);
PALIMPORT
-BOOL
-PALAPI
-ReadProcessMemory(
- IN HANDLE hProcess,
- IN LPCVOID lpBaseAddress,
- OUT LPVOID lpBuffer,
- IN SIZE_T nSize,
- OUT SIZE_T * lpNumberOfBytesRead);
-
-PALIMPORT
VOID
PALAPI
RtlMoveMemory(
@@ -4712,19 +4706,12 @@ enum {
//
typedef struct _RUNTIME_FUNCTION {
DWORD BeginAddress;
+#ifdef _AMD64_
DWORD EndAddress;
+#endif
DWORD UnwindData;
} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
-PALIMPORT
-BOOL
-PALAPI
-WriteProcessMemory(IN HANDLE hProcess,
- IN LPVOID lpBaseAddress,
- IN LPCVOID lpBuffer,
- IN SIZE_T nSize,
- OUT SIZE_T * lpNumberOfBytesWritten);
-
#define STANDARD_RIGHTS_REQUIRED (0x000F0000L)
#define SYNCHRONIZE (0x00100000L)
#define READ_CONTROL (0x00020000L)
@@ -4801,28 +4788,6 @@ DebugBreak(
VOID);
PALIMPORT
-LPWSTR
-PALAPI
-lstrcatW(
- IN OUT LPWSTR lpString1,
- IN LPCWSTR lpString2);
-
-#ifdef UNICODE
-#define lstrcat lstrcatW
-#endif
-
-PALIMPORT
-LPWSTR
-PALAPI
-lstrcpyW(
- OUT LPWSTR lpString1,
- IN LPCWSTR lpString2);
-
-#ifdef UNICODE
-#define lstrcpy lstrcpyW
-#endif
-
-PALIMPORT
int
PALAPI
lstrlenA(
@@ -4841,19 +4806,6 @@ lstrlenW(
#endif
PALIMPORT
-LPWSTR
-PALAPI
-lstrcpynW(
- OUT LPWSTR lpString1,
- IN LPCWSTR lpString2,
- IN int iMaxLength);
-
-#ifdef UNICODE
-#define lstrcpyn lstrcpynW
-#endif
-
-
-PALIMPORT
DWORD
PALAPI
GetEnvironmentVariableW(
@@ -4937,7 +4889,7 @@ GetTickCount(
PALIMPORT
ULONGLONG
PALAPI
-GetTickCount64();
+GetTickCount64(VOID);
PALIMPORT
BOOL
@@ -5377,7 +5329,7 @@ YieldProcessor(
PALIMPORT
DWORD
PALAPI
-GetCurrentProcessorNumber();
+GetCurrentProcessorNumber(VOID);
/*++
Function:
@@ -5389,7 +5341,7 @@ Checks if GetCurrentProcessorNumber is available in the current environment
PALIMPORT
BOOL
PALAPI
-PAL_HasGetCurrentProcessorNumber();
+PAL_HasGetCurrentProcessorNumber(VOID);
#define FORMAT_MESSAGE_ALLOCATE_BUFFER 0x00000100
#define FORMAT_MESSAGE_IGNORE_INSERTS 0x00000200
@@ -5475,7 +5427,7 @@ ResetWriteWatch(
PALIMPORT
VOID
PALAPI
-FlushProcessWriteBuffers();
+FlushProcessWriteBuffers(VOID);
typedef void (*PAL_ActivationFunction)(CONTEXT *context);
typedef BOOL (*PAL_SafeActivationCheckFunction)(SIZE_T ip, BOOL checkingCurrentThread);
@@ -5715,9 +5667,7 @@ CoCreateGuid(OUT GUID * pguid);
#define printf PAL_printf
#define vprintf PAL_vprintf
#define wprintf PAL_wprintf
-#define sprintf PAL_sprintf
#define swprintf PAL_swprintf
-#define sscanf PAL_sscanf
#define wcsspn PAL_wcsspn
#define wcstod PAL_wcstod
#define wcstol PAL_wcstol
@@ -5791,6 +5741,13 @@ CoCreateGuid(OUT GUID * pguid);
#define log PAL_log
#define log10 PAL_log10
#define pow PAL_pow
+#define acosf PAL_acosf
+#define asinf PAL_asinf
+#define atan2f PAL_atan2f
+#define expf PAL_expf
+#define logf PAL_logf
+#define log10f PAL_log10f
+#define powf PAL_powf
#define malloc PAL_malloc
#define free PAL_free
#define mkstemp PAL_mkstemp
@@ -5802,6 +5759,7 @@ CoCreateGuid(OUT GUID * pguid);
#define _wcstoui64 PAL__wcstoui64
#define _flushall PAL__flushall
#define _vsnprintf PAL__vsnprintf
+#define strnlen PAL_strnlen
#ifdef _AMD64_
#define _mm_getcsr PAL__mm_getcsr
@@ -5878,9 +5836,7 @@ PALIMPORT char * __cdecl strstr(const char *, const char *);
PALIMPORT char * __cdecl strtok(char *, const char *);
PALIMPORT size_t __cdecl strspn(const char *, const char *);
PALIMPORT size_t __cdecl strcspn(const char *, const char *);
-PALIMPORT int __cdecl sprintf(char *, const char *, ...);
PALIMPORT int __cdecl vsprintf(char *, const char *, va_list);
-PALIMPORT int __cdecl sscanf(const char *, const char *, ...);
PALIMPORT int __cdecl atoi(const char *);
PALIMPORT LONG __cdecl atol(const char *);
PALIMPORT ULONG __cdecl strtoul(const char *, char **, int);
@@ -5899,23 +5855,35 @@ PALIMPORT int __cdecl toupper(int);
#endif // PAL_STDCPP_COMPAT
+/* _TRUNCATE */
+#if !defined(_TRUNCATE)
+#define _TRUNCATE ((size_t)-1)
+#endif
+
PALIMPORT errno_t __cdecl memcpy_s(void *, size_t, const void *, size_t);
PALIMPORT errno_t __cdecl memmove_s(void *, size_t, const void *, size_t);
PALIMPORT char * __cdecl _strlwr(char *);
PALIMPORT int __cdecl _stricmp(const char *, const char *);
-PALIMPORT int __cdecl _snprintf(char *, size_t, const char *, ...);
+PALIMPORT int __cdecl vsprintf_s(char *, size_t, const char *, va_list);
PALIMPORT char * __cdecl _gcvt_s(char *, int, double, int);
PALIMPORT char * __cdecl _ecvt(double, int, int *, int *);
PALIMPORT int __cdecl __iscsym(int);
-PALIMPORT size_t __cdecl _mbslen(const unsigned char *);
PALIMPORT unsigned char * __cdecl _mbsinc(const unsigned char *);
PALIMPORT unsigned char * __cdecl _mbsninc(const unsigned char *, size_t);
PALIMPORT unsigned char * __cdecl _mbsdec(const unsigned char *, const unsigned char *);
PALIMPORT int __cdecl _wcsicmp(const WCHAR *, const WCHAR*);
PALIMPORT int __cdecl _wcsnicmp(const WCHAR *, const WCHAR *, size_t);
PALIMPORT int __cdecl _vsnprintf(char *, size_t, const char *, va_list);
-PALIMPORT int __cdecl _vsnwprintf(WCHAR *, size_t, const WCHAR *, va_list);
-PALIMPORT WCHAR * __cdecl _itow(int, WCHAR *, int);
+PALIMPORT int __cdecl _vsnprintf_s(char *, size_t, size_t, const char *, va_list);
+PALIMPORT int __cdecl _vsnwprintf_s(WCHAR *, size_t, size_t, const WCHAR *, va_list);
+PALIMPORT int __cdecl _snwprintf_s(WCHAR *, size_t, size_t, const WCHAR *, ...);
+PALIMPORT int __cdecl _snprintf_s(char *, size_t, size_t, const char *, ...);
+PALIMPORT int __cdecl sprintf_s(char *, size_t, const char *, ... );
+PALIMPORT int __cdecl swprintf_s(WCHAR *, size_t, const WCHAR *, ... );
+PALIMPORT int __cdecl _snwprintf_s(WCHAR *, size_t, size_t, const WCHAR *, ...);
+PALIMPORT int __cdecl vswprintf_s( WCHAR *, size_t, const WCHAR *, va_list);
+PALIMPORT int __cdecl sscanf_s(const char *, const char *, ...);
+PALIMPORT errno_t __cdecl _itow_s(int, WCHAR *, size_t, int);
PALIMPORT size_t __cdecl PAL_wcslen(const WCHAR *);
PALIMPORT int __cdecl PAL_wcscmp(const WCHAR*, const WCHAR*);
@@ -5933,7 +5901,6 @@ PALIMPORT size_t __cdecl PAL_wcscspn(const WCHAR *, const WCHAR *);
PALIMPORT int __cdecl PAL_swprintf(WCHAR *, const WCHAR *, ...);
PALIMPORT int __cdecl PAL_vswprintf(WCHAR *, const WCHAR *, va_list);
PALIMPORT int __cdecl PAL__vsnprintf(LPSTR Buffer, size_t Count, LPCSTR Format, va_list ap);
-PALIMPORT int __cdecl _snwprintf(WCHAR *, size_t, const WCHAR *, ...);
PALIMPORT int __cdecl PAL_swscanf(const WCHAR *, const WCHAR *, ...);
PALIMPORT LONG __cdecl PAL_wcstol(const WCHAR *, WCHAR **, int);
PALIMPORT ULONG __cdecl PAL_wcstoul(const WCHAR *, WCHAR **, int);
@@ -5950,8 +5917,7 @@ PALIMPORT WCHAR __cdecl PAL_towupper(WCHAR);
PALIMPORT WCHAR * __cdecl _wcslwr(WCHAR *);
PALIMPORT ULONGLONG _wcstoui64(const WCHAR *, WCHAR **, int);
-PALIMPORT WCHAR * __cdecl _i64tow(__int64, WCHAR *, int);
-PALIMPORT WCHAR * __cdecl _ui64tow(unsigned __int64, WCHAR *, int);
+PALIMPORT errno_t __cdecl _i64tow_s(long long, WCHAR *, size_t, int);
PALIMPORT int __cdecl _wtoi(const WCHAR *);
#ifdef __cplusplus
@@ -6039,9 +6005,29 @@ PALIMPORT double __cdecl sqrt(double);
PALIMPORT double __cdecl tan(double);
PALIMPORT double __cdecl tanh(double);
+PALIMPORT int __cdecl _finitef(float);
+PALIMPORT int __cdecl _isnanf(float);
+PALIMPORT float __cdecl _copysignf(float, float);
+PALIMPORT float __cdecl acosf(float);
+PALIMPORT float __cdecl asinf(float);
+PALIMPORT float __cdecl atanf(float);
+PALIMPORT float __cdecl atan2f(float, float);
+PALIMPORT float __cdecl ceilf(float);
+PALIMPORT float __cdecl cosf(float);
+PALIMPORT float __cdecl coshf(float);
+PALIMPORT float __cdecl expf(float);
PALIMPORT float __cdecl fabsf(float);
+PALIMPORT float __cdecl floorf(float);
PALIMPORT float __cdecl fmodf(float, float);
+PALIMPORT float __cdecl logf(float);
+PALIMPORT float __cdecl log10f(float);
PALIMPORT float __cdecl modff(float, float*);
+PALIMPORT float __cdecl powf(float, float);
+PALIMPORT float __cdecl sinf(float);
+PALIMPORT float __cdecl sinhf(float);
+PALIMPORT float __cdecl sqrtf(float);
+PALIMPORT float __cdecl tanf(float);
+PALIMPORT float __cdecl tanhf(float);
#ifndef PAL_STDCPP_COMPAT
@@ -6086,14 +6072,8 @@ PALIMPORT void __cdecl qsort(void *, size_t, size_t, int (__cdecl *)(const void
PALIMPORT void * __cdecl bsearch(const void *, const void *, size_t, size_t,
int (__cdecl *)(const void *, const void *));
-PALIMPORT void __cdecl _splitpath(const char *, char *, char *, char *, char *);
-PALIMPORT void __cdecl _wsplitpath(const WCHAR *, WCHAR *, WCHAR *, WCHAR *, WCHAR *);
-PALIMPORT void __cdecl _makepath(char *, const char *, const char *, const char *, const char *);
-PALIMPORT void __cdecl _wmakepath(WCHAR *, const WCHAR *, const WCHAR *, const WCHAR *, const WCHAR *);
PALIMPORT char * __cdecl _fullpath(char *, const char *, size_t);
-PALIMPORT void __cdecl _swab(char *, char *, int);
-
#ifndef PAL_STDCPP_COMPAT
PALIMPORT time_t __cdecl time(time_t *);
@@ -6307,14 +6287,14 @@ PAL_Enter(PAL_Boundary boundary);
PALIMPORT
BOOL
PALAPI
-PAL_HasEntered();
+PAL_HasEntered(VOID);
// Equivalent to PAL_Enter(PAL_BoundaryTop) and is for stub
// code generation use.
PALIMPORT
DWORD
PALAPI
-PAL_EnterTop();
+PAL_EnterTop(VOID);
// This function needs to be called on a thread when it enters
// a region of code that depends on this instance of the PAL
@@ -6349,14 +6329,14 @@ PAL_Leave(PAL_Boundary boundary);
PALIMPORT
VOID
PALAPI
-PAL_LeaveBottom();
+PAL_LeaveBottom(VOID);
// This function is equivalent to PAL_Leave(PAL_BoundaryTop)
// and is available to limit the creation of stub code.
PALIMPORT
VOID
PALAPI
-PAL_LeaveTop();
+PAL_LeaveTop(VOID);
#ifdef __cplusplus
//
diff --git a/src/pal/inc/pal_char16.h b/src/pal/inc/pal_char16.h
index b118e98e31..4600cc7ff6 100644
--- a/src/pal/inc/pal_char16.h
+++ b/src/pal/inc/pal_char16.h
@@ -37,7 +37,8 @@ This file is used to define the wchar_t type as a 16-bit type on Unix.
// Set up the wchar_t type (which got preprocessed to __wchar_16_cpp__).
// In C++11, the standard gives us char16_t, which is what we want (and matches types with u"")
// In C, this doesn't exist, so use unsigned short.
-
+// **** WARNING: Linking C and C++ objects will break with -fstrict-aliasing with GCC/Clang
+// due to conditional typedef
#if !defined(_WCHAR_T_DEFINED) || !defined(_MSC_VER)
#if defined (PLATFORM_UNIX)
#if defined(__cplusplus)
diff --git a/src/pal/inc/pal_mstypes.h b/src/pal/inc/pal_mstypes.h
index df17767747..b9c3ac2e4a 100644
--- a/src/pal/inc/pal_mstypes.h
+++ b/src/pal/inc/pal_mstypes.h
@@ -56,12 +56,6 @@ extern "C" {
#define CDECL __cdecl
#endif
-#ifndef PAL_STDCPP_COMPAT
-#undef __fastcall
-#define __fastcall __stdcall
-#undef _fastcall
-#define _fastcall __fastcall
-#endif // PAL_STDCPP_COMPAT
#else // !defined(__i386__)
@@ -215,6 +209,9 @@ extern "C" {
// Defined in gnu's types.h. For non PAL_IMPLEMENTATION system
// includes are not included, so we need to define them.
#ifndef PAL_IMPLEMENTATION
+
+// OS X already defines these types in 64 bit
+#if !defined(_TARGET_MAC64)
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
typedef __int32 int32_t;
@@ -223,6 +220,8 @@ typedef __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef __int8 int8_t;
typedef unsigned __int8 uint8_t;
+#endif
+
#endif // PAL_IMPLEMENTATION
#ifndef _MSC_VER
diff --git a/src/pal/inc/rt/palrt.h b/src/pal/inc/rt/palrt.h
index 336a13f529..c181f38c2b 100644
--- a/src/pal/inc/rt/palrt.h
+++ b/src/pal/inc/rt/palrt.h
@@ -834,7 +834,6 @@ enum tagMIMECONTF {
// note: diff in NULL handing and calling convetion
#define StrCpyW PAL_wcscpy
-#define StrCpyNW lstrcpynW // note: can't be wcsncpy!
#define StrCatW PAL_wcscat
#define StrChrW (WCHAR*)PAL_wcschr
#define StrCmpW PAL_wcscmp
@@ -850,12 +849,9 @@ STDAPI_(LPWSTR) StrCatBuffW(LPWSTR pszDest, LPCWSTR pszSrc, int cchDestBuffSize)
#define lstrcmpW PAL_wcscmp
#define lstrcmpiW _wcsicmp
-#define wnsprintfW _snwprintf // note: not 100% compatible (wsprintf should be subset of sprintf...)
-#define wvnsprintfW _vsnwprintf // note: not 100% compatible (wsprintf should be subset of sprintf...)
#ifdef UNICODE
#define StrCpy StrCpyW
-#define StrCpyN StrCpyNW
#define StrCat StrCatW
#define StrNCat StrNCatW
#define StrChr StrChrW
@@ -871,7 +867,6 @@ STDAPI_(LPWSTR) StrCatBuffW(LPWSTR pszDest, LPCWSTR pszSrc, int cchDestBuffSize)
#define lstrcmp lstrcmpW
#define lstrcmpi lstrcmpiW
-#define wnsprintf wnsprintfW
#endif
@@ -898,12 +893,8 @@ Remember to fix the errcode defintion in safecrt.h.
*/
#define _wcslwr_s _wcslwr_unsafe
-#define _snwprintf_s _snwprintf_unsafe
-#define _vsnwprintf_s _vsnwprintf_unsafe
#define _snprintf_s _snprintf_unsafe
-#define _vsnprintf_s _vsnprintf_unsafe
#define swscanf_s swscanf
-#define sscanf_s sscanf
#define _wfopen_s _wfopen_unsafe
#define fopen_s _fopen_unsafe
@@ -911,12 +902,8 @@ Remember to fix the errcode defintion in safecrt.h.
#define _strlwr_s _strlwr_unsafe
#define _vscprintf _vscprintf_unsafe
-#define _vscwprintf _vscwprintf_unsafe
-#define sprintf_s _snprintf
-#define swprintf_s _snwprintf
#define vsprintf_s _vsnprintf
-#define vswprintf_s _vsnwprintf
extern "C++" {
@@ -982,51 +969,6 @@ inline int __cdecl _vscprintf_unsafe(const char *_Format, va_list _ArgList)
}
}
-inline int __cdecl _vscwprintf_unsafe(const WCHAR *_Format, va_list _ArgList)
-{
- int guess = 256;
-
- for (;;)
- {
- WCHAR *buf = (WCHAR *)malloc(guess * sizeof(WCHAR));
- if (buf == nullptr)
- return 0;
-
- va_list apcopy;
- va_copy(apcopy, _ArgList);
- int ret = _vsnwprintf(buf, guess, _Format, apcopy);
- free(buf);
- va_end(apcopy);
-
- if ((ret != -1) && (ret < guess))
- return ret;
-
- guess *= 2;
- }
-}
-
-inline int __cdecl _vsnwprintf_unsafe(WCHAR *_Dst, size_t _SizeInWords, size_t _Count, const WCHAR *_Format, va_list _ArgList)
-{
- if (_Count == _TRUNCATE) _Count = _SizeInWords - 1;
- int ret = _vsnwprintf(_Dst, _Count, _Format, _ArgList);
- _Dst[_SizeInWords - 1] = L'\0';
- if (ret < 0 && errno == 0)
- {
- errno = ERANGE;
- }
- return ret;
-}
-
-inline int __cdecl _snwprintf_unsafe(WCHAR *_Dst, size_t _SizeInWords, size_t _Count, const WCHAR *_Format, ...)
-{
- int ret;
- va_list _ArgList;
- va_start(_ArgList, _Format);
- ret = _vsnwprintf_unsafe(_Dst, _SizeInWords, _Count, _Format, _ArgList);
- va_end(_ArgList);
- return ret;
-}
-
inline int __cdecl _vsnprintf_unsafe(char *_Dst, size_t _SizeInWords, size_t _Count, const char *_Format, va_list _ArgList)
{
if (_Count == _TRUNCATE) _Count = _SizeInWords - 1;
@@ -1071,100 +1013,6 @@ inline errno_t __cdecl _fopen_unsafe(PAL_FILE * *ff, const char *fileName, const
}
}
-/* _itow_s */
-_SAFECRT__EXTERN_C
-errno_t __cdecl _itow_s(int _Value, WCHAR *_Dst, size_t _SizeInWords, int _Radix);
-
-#if defined(__cplusplus) && _SAFECRT_USE_CPP_OVERLOADS
-template <size_t _SizeInWords>
-inline
-errno_t __cdecl _itow_s(int _Value, WCHAR (&_Dst)[_SizeInWords], int _Radix)
-{
- return _itow_s(_Value, _Dst, _SizeInWords, _Radix);
-}
-#endif
-
-#if _SAFECRT_USE_INLINES
-
-__inline
-errno_t __cdecl _itow_s(int _Value, WCHAR *_Dst, size_t _SizeInWords, int _Radix)
-{
- /* validation section */
- _SAFECRT__VALIDATE_STRING(_Dst, _SizeInWords);
-
- /* TODO: do not write past buffer size */
- _itow(_Value, _Dst, _Radix);
- return 0;
-}
-
-#endif
-
-/* _i64tow_s */
-_SAFECRT__EXTERN_C
-errno_t __cdecl _i64tow_s(__int64 _Value, WCHAR *_Dst, size_t _SizeInWords, int _Radix);
-
-#if defined(__cplusplus) && _SAFECRT_USE_CPP_OVERLOADS
-template <size_t _SizeInWords>
-inline
-errno_t __cdecl _i64tow_s(__int64 _Value, WCHAR (&_Dst)[_SizeInWords], int _Radix)
-{
- return _i64tow_s(_Value, _Dst, _SizeInWords, _Radix);
-}
-#endif
-
-#if _SAFECRT_USE_INLINES
-
-__inline
-errno_t __cdecl _i64tow_s(__int64 _Value, WCHAR *_Dst, size_t _SizeInWords, int _Radix)
-{
- /* validation section */
- _SAFECRT__VALIDATE_STRING(_Dst, _SizeInWords);
-
- /* TODO: do not write past buffer size */
- _i64tow(_Value, _Dst, _Radix);
- return 0;
-}
-
-#endif
-
-/* getenv_s */
-/*
- * _ReturnValue indicates if the variable has been found and size needed
- */
-_SAFECRT__EXTERN_C
-errno_t __cdecl getenv_s(size_t *_ReturnValue, char *_Dst, size_t _SizeInWords, const char *_Name);
-
-#if defined(__cplusplus) && _SAFECRT_USE_CPP_OVERLOADS
-template <size_t _SizeInWords>
-inline
-errno_t __cdecl getenv_s(size_t *_ReturnValue, char *_Dst, size_t _SizeInWords, const char *_Name)
-{
- return getenv_s(_ReturnValue, _Dst, _SizeInWords, _Name);
-}
-#endif
-
-#if _SAFECRT_USE_INLINES
-
-__inline
-errno_t __cdecl getenv_s(size_t *_ReturnValue, char *_Dst, size_t _SizeInWords, const char *_Name)
-{
- char *szFound;
-
- /* validation section */
- _SAFECRT__VALIDATE_STRING(_Dst, _SizeInWords);
-
- szFound = getenv(_Name);
- if (szFound == nullptr)
- {
- *_ReturnValue = 0;
- return 0;
- }
- *_ReturnValue = strlen(szFound) + 1;
- return strcpy_s(_Dst, _SizeInWords, szFound);
-}
-
-#endif
-
}
#endif /* __cplusplus */
@@ -1247,6 +1095,7 @@ namespace std
typedef decltype(nullptr) nullptr_t;
}
+extern "C++"
template< class T >
typename std::remove_reference<T>::type&& move( T&& t );
#endif // __cplusplus
@@ -1327,7 +1176,7 @@ typedef VOID (__stdcall *WAITORTIMERCALLBACK)(PVOID, BOOLEAN);
// The message in these two macros should not contain any keywords like TODO
// or NYI. It should be just the brief description of the problem.
-#if defined(_TARGET_X86_)
+#ifdef PORTABILITY_CHECK
// Finished ports - compile-time errors
#define PORTABILITY_WARNING(message) NEED_TO_PORT_THIS_ONE(NEED_TO_PORT_THIS_ONE)
#define PORTABILITY_ASSERT(message) NEED_TO_PORT_THIS_ONE(NEED_TO_PORT_THIS_ONE)
@@ -1666,7 +1515,7 @@ typedef struct _DISPATCHER_CONTEXT {
ULONG64 Reserved;
} DISPATCHER_CONTEXT, *PDISPATCHER_CONTEXT;
-#else
+#elif defined(_AMD64_)
typedef struct _DISPATCHER_CONTEXT {
ULONG64 ControlPc;
@@ -1680,6 +1529,29 @@ typedef struct _DISPATCHER_CONTEXT {
PUNWIND_HISTORY_TABLE HistoryTable;
} DISPATCHER_CONTEXT, *PDISPATCHER_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;
+ PCONTEXT ContextRecord;
+ PEXCEPTION_ROUTINE LanguageHandler;
+ PVOID HandlerData;
+ PUNWIND_HISTORY_TABLE HistoryTable;
+} DISPATCHER_CONTEXT, *PDISPATCHER_CONTEXT;
+
+#else
+
+#error Unknown architecture for defining DISPATCHER_CONTEXT.
+
#endif
// #endif // !defined(_TARGET_MAC64)
diff --git a/src/pal/inc/rt/safecrt.h b/src/pal/inc/rt/safecrt.h
index 6b95e28dfb..3cc10cef33 100644
--- a/src/pal/inc/rt/safecrt.h
+++ b/src/pal/inc/rt/safecrt.h
@@ -409,7 +409,6 @@ void __cdecl _invalid_parameter(const WCHAR *_Message, const WCHAR *_FunctionNam
#define _tmakepath_s _makepath_s
#define _tsplitpath_s _splitpath_s
#define _stprintf_s sprintf_s
-#define _vstprintf_s vsprintf_s
#define _sntprintf_s _snprintf_s
#define _vsntprintf_s _vsnprintf_s
#define _tscanf_s scanf_s
@@ -428,8 +427,6 @@ void __cdecl _invalid_parameter(const WCHAR *_Message, const WCHAR *_FunctionNam
#define _tmakepath_s _wmakepath_s
#define _tsplitpath_s _wsplitpath_s
#define _stprintf_s swprintf_s
-#define _vstprintf_s vswprintf_s
-#define _sntprintf_s _snwprintf_s
#define _vsntprintf_s _vsnwprintf_s
#define _tscanf_s wscanf_s
#define _tsscanf_s swscanf_s
@@ -447,9 +444,7 @@ void __cdecl _invalid_parameter(const WCHAR *_Message, const WCHAR *_FunctionNam
#define _tmakepath_s _makepath_s
#define _tsplitpath_s _splitpath_s
#define _stprintf_s sprintf_s
-#define _vstprintf_s vsprintf_s
#define _sntprintf_s _snprintf_s
-#define _vsntprintf_s _vsnprintf_s
#define _tscanf_s scanf_s
#define _tsscanf_s sscanf_s
#define _tsnscanf_s _snscanf_s
@@ -3222,7 +3217,7 @@ int __cdecl vswprintf_s(WCHAR *_Dst, size_t _SizeInWords, const WCHAR *_Format,
#if defined(__cplusplus) && _SAFECRT_USE_CPP_OVERLOADS
template <size_t _SizeInWords>
inline
-int __cdecl swprintf_s(char (&_Dst)[_SizeInWords], const char *_Format, ...)
+int __cdecl swprintf_s(WCHAR (&_Dst)[_SizeInWords], const WCHAR *_Format, ...)
{
int ret;
va_list _ArgList;
@@ -3234,7 +3229,7 @@ int __cdecl swprintf_s(char (&_Dst)[_SizeInWords], const char *_Format, ...)
template <size_t _SizeInWords>
inline
-int __cdecl vswprintf_s(char (&_Dst)[_SizeInWords], const char *_Format, va_list _ArgList)
+int __cdecl vswprintf_s(WCHAR (&_Dst)[_SizeInWords], const WCHAR *_Format, va_list _ArgList)
{
return vswprintf_s(_Dst, _SizeInWords, _Format, _ArgList);
}
@@ -3288,14 +3283,12 @@ int __cdecl _vsnprintf_s(char (&_Dst)[_SizeInBytes], size_t _Count, const char *
/* _snwprintf_s, _vsnwprintf_s */
_SAFECRT__EXTERN_C
-int __cdecl _snwprintf_s(WCHAR *_Dst, size_t _SizeInWords, size_t _Count, const WCHAR *_Format, ...);
-_SAFECRT__EXTERN_C
int __cdecl _vsnwprintf_s(WCHAR *_Dst, size_t _SizeInWords, size_t _Count, const WCHAR *_Format, va_list _ArgList);
#if defined(__cplusplus) && _SAFECRT_USE_CPP_OVERLOADS
template <size_t _SizeInWords>
inline
-int __cdecl _snwprintf_s(char (&_Dst)[_SizeInWords], size_t _Count, const char *_Format, ...)
+int __cdecl _snwprintf_s(WCHAR (&_Dst)[_SizeInWords], size_t _Count, const WCHAR *_Format, ...)
{
int ret;
va_list _ArgList;
diff --git a/src/pal/inc/strsafe.h b/src/pal/inc/strsafe.h
index 5a9f0edd43..58749f27ee 100644
--- a/src/pal/inc/strsafe.h
+++ b/src/pal/inc/strsafe.h
@@ -32,7 +32,7 @@
#define _vsnprintf vsnprintf
#endif // defined(PLATFORM_UNIX) && !defined (FEATURE_PAL)
-#include <stdio.h> // for _vsnprintf, _vsnwprintf, getc, getwc
+#include <stdio.h> // for _vsnprintf, getc, getwc
#include <string.h> // for memset
#include <stdarg.h> // for va_start, etc.
@@ -146,10 +146,6 @@ STRSAFEAPI StringCatNWorkerA(char* pszDest, size_t cchDest, const char* pszSrc,
STRSAFEAPI StringCatNWorkerW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszSrc, size_t cchMaxAppend);
STRSAFEAPI StringCatNExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, size_t cchMaxAppend, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags);
STRSAFEAPI StringCatNExWorkerW(WCHAR* pszDest, size_t cchDest, size_t cbDest, const WCHAR* pszSrc, size_t cchMaxAppend, WCHAR** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags);
-STRSAFEAPI StringVPrintfWorkerA(char* pszDest, size_t cchDest, const char* pszFormat, va_list argList);
-STRSAFEAPI StringVPrintfWorkerW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszFormat, va_list argList);
-STRSAFEAPI StringVPrintfExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const char* pszFormat, va_list argList);
-STRSAFEAPI StringVPrintfExWorkerW(WCHAR* pszDest, size_t cchDest, size_t cbDest, WCHAR** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const WCHAR* pszFormat, va_list argList);
STRSAFEAPI StringLengthWorkerA(const char* psz, size_t cchMax, size_t* pcch);
STRSAFEAPI StringLengthWorkerW(const WCHAR* psz, size_t cchMax, size_t* pcch);
#endif // STRSAFE_INLINE
@@ -2356,1124 +2352,6 @@ STRSAFEAPI StringCbCatNExW(WCHAR* pszDest, size_t cbDest, const WCHAR* pszSrc, s
#ifndef STRSAFE_NO_CCH_FUNCTIONS
/*++
-STDAPI StringCchVPrintf(LPTSTR pszDest,
- size_t cchDest,
- LPCTSTR pszFormat,
- va_list argList);
-
-Routine Description:
-
- This routine is a safer version of the C built-in function 'vsprintf'.
- The size of the destination buffer (in characters) is a parameter and
- this function will not write past the end of this buffer and it will
- ALWAYS null terminate the destination buffer (unless it is zero length).
-
- This function returns a hresult, and not a pointer. It returns a S_OK
- if the string was printed without truncation and null terminated, otherwise
- it will return a failure code. In failure cases it will return a truncated
- version of the ideal result.
-
-Arguments:
-
- pszDest - destination string
-
- cchDest - size of destination buffer in characters
- length must be sufficient to hold the resulting formatted
- string, including the null terminator.
-
- pszFormat - format string which must be null terminated
-
- argList - va_list from the variable arguments according to the
- stdarg.h convention
-
-Notes:
- Behavior is undefined if destination, format strings or any arguments
- strings overlap.
-
- pszDest and pszFormat should not be NULL. See StringCchVPrintfEx if you
- require the handling of NULL values.
-
-Return Value:
-
- S_OK - if there was sufficient space in the dest buffer for
- the resultant string and it was null terminated.
-
- failure - you can use the macro HRESULT_CODE() to get a win32 error
- code for all falure cases
-
- STRSAFE_E_INSUFFICIENT_BUFFER /
- HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
- - this return value is an indication that the print operation
- failed due to insufficient space. When this error occurs,
- the destination buffer is modified to contain a truncated
- version of the ideal result and is null terminated. This
- is useful for situations where truncation is ok.
-
- It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
- return value of this function
-
---*/
-
-STRSAFEAPI StringCchVPrintfA(char* pszDest, size_t cchDest, const char* pszFormat, va_list argList);
-STRSAFEAPI StringCchVPrintfW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszFormat, va_list argList);
-#ifdef UNICODE
-#define StringCchVPrintf StringCchVPrintfW
-#else
-#define StringCchVPrintf StringCchVPrintfA
-#endif // !UNICODE
-
-#ifdef STRSAFE_INLINE
-STRSAFEAPI StringCchVPrintfA(char* pszDest, size_t cchDest, const char* pszFormat, va_list argList)
-{
- HRESULT hr;
-
- if (cchDest > STRSAFE_MAX_CCH)
- {
- hr = STRSAFE_E_INVALID_PARAMETER;
- }
- else
- {
- hr = StringVPrintfWorkerA(pszDest, cchDest, pszFormat, argList);
- }
-
- return hr;
-}
-
-#if defined(FEATURE_PAL) || !defined(PLATFORM_UNIX)
-STRSAFEAPI StringCchVPrintfW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszFormat, va_list argList)
-{
- HRESULT hr;
-
- if (cchDest > STRSAFE_MAX_CCH)
- {
- hr = STRSAFE_E_INVALID_PARAMETER;
- }
- else
- {
- hr = StringVPrintfWorkerW(pszDest, cchDest, pszFormat, argList);
- }
-
- return hr;
-}
-#endif // FEATURE_PAL || !PLATFORM_UNIX
-#endif // STRSAFE_INLINE
-#endif // !STRSAFE_NO_CCH_FUNCTIONS
-
-
-#ifndef STRSAFE_NO_CB_FUNCTIONS
-/*++
-
-STDAPI StringCbVPrintf(LPTSTR pszDest,
- size_t cbDest,
- LPCTSTR pszFormat,
- va_list argList);
-
-Routine Description:
-
- This routine is a safer version of the C built-in function 'vsprintf'.
- The size of the destination buffer (in bytes) is a parameter and
- this function will not write past the end of this buffer and it will
- ALWAYS null terminate the destination buffer (unless it is zero length).
-
- This function returns a hresult, and not a pointer. It returns a S_OK
- if the string was printed without truncation and null terminated, otherwise
- it will return a failure code. In failure cases it will return a truncated
- version of the ideal result.
-
-Arguments:
-
- pszDest - destination string
-
- cbDest - size of destination buffer in bytes
- length must be sufficient to hold the resulting formatted
- string, including the null terminator.
-
- pszFormat - format string which must be null terminated
-
- argList - va_list from the variable arguments according to the
- stdarg.h convention
-
-Notes:
- Behavior is undefined if destination, format strings or any arguments
- strings overlap.
-
- pszDest and pszFormat should not be NULL. See StringCbVPrintfEx if you
- require the handling of NULL values.
-
-
-Return Value:
-
- S_OK - if there was sufficient space in the dest buffer for
- the resultant string and it was null terminated.
-
- failure - you can use the macro HRESULT_CODE() to get a win32 error
- code for all falure cases
-
- STRSAFE_E_INSUFFICIENT_BUFFER /
- HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
- - this return value is an indication that the print operation
- failed due to insufficient space. When this error occurs,
- the destination buffer is modified to contain a truncated
- version of the ideal result and is null terminated. This
- is useful for situations where truncation is ok.
-
- It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
- return value of this function
-
---*/
-
-STRSAFEAPI StringCbVPrintfA(char* pszDest, size_t cbDest, const char* pszFormat, va_list argList);
-STRSAFEAPI StringCbVPrintfW(WCHAR* pszDest, size_t cbDest, const WCHAR* pszFormat, va_list argList);
-#ifdef UNICODE
-#define StringCbVPrintf StringCbVPrintfW
-#else
-#define StringCbVPrintf StringCbVPrintfA
-#endif // !UNICODE
-
-#ifdef STRSAFE_INLINE
-STRSAFEAPI StringCbVPrintfA(char* pszDest, size_t cbDest, const char* pszFormat, va_list argList)
-{
- HRESULT hr;
- size_t cchDest;
-
- cchDest = cbDest / sizeof(char);
-
- if (cchDest > STRSAFE_MAX_CCH)
- {
- hr = STRSAFE_E_INVALID_PARAMETER;
- }
- else
- {
- hr = StringVPrintfWorkerA(pszDest, cchDest, pszFormat, argList);
- }
-
- return hr;
-}
-
-#if defined(FEATURE_PAL) || !defined(PLATFORM_UNIX)
-STRSAFEAPI StringCbVPrintfW(WCHAR* pszDest, size_t cbDest, const WCHAR* pszFormat, va_list argList)
-{
- HRESULT hr;
- size_t cchDest;
-
- cchDest = cbDest / sizeof(WCHAR);
-
- if (cchDest > STRSAFE_MAX_CCH)
- {
- hr = STRSAFE_E_INVALID_PARAMETER;
- }
- else
- {
- hr = StringVPrintfWorkerW(pszDest, cchDest, pszFormat, argList);
- }
-
- return hr;
-}
-#endif // FEATURE_PAL || !PLATFORM_UNIX
-#endif // STRSAFE_INLINE
-#endif // !STRSAFE_NO_CB_FUNCTIONS
-
-
-#ifndef STRSAFE_NO_CCH_FUNCTIONS
-/*++
-
-STDAPI StringCchPrintf(LPTSTR pszDest,
- size_t cchDest,
- LPCTSTR pszFormat,
- ...);
-
-Routine Description:
-
- This routine is a safer version of the C built-in function 'sprintf'.
- The size of the destination buffer (in characters) is a parameter and
- this function will not write past the end of this buffer and it will
- ALWAYS null terminate the destination buffer (unless it is zero length).
-
- This function returns a hresult, and not a pointer. It returns a S_OK
- if the string was printed without truncation and null terminated, otherwise
- it will return a failure code. In failure cases it will return a truncated
- version of the ideal result.
-
-Arguments:
-
- pszDest - destination string
-
- cchDest - size of destination buffer in characters
- length must be sufficient to hold the resulting formatted
- string, including the null terminator.
-
- pszFormat - format string which must be null terminated
-
- ... - additional parameters to be formatted according to
- the format string
-
-Notes:
- Behavior is undefined if destination, format strings or any arguments
- strings overlap.
-
- pszDest and pszFormat should not be NULL. See StringCchPrintfEx if you
- require the handling of NULL values.
-
-Return Value:
-
- S_OK - if there was sufficient space in the dest buffer for
- the resultant string and it was null terminated.
-
- failure - you can use the macro HRESULT_CODE() to get a win32 error
- code for all falure cases
-
- STRSAFE_E_INSUFFICIENT_BUFFER /
- HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
- - this return value is an indication that the print operation
- failed due to insufficient space. When this error occurs,
- the destination buffer is modified to contain a truncated
- version of the ideal result and is null terminated. This
- is useful for situations where truncation is ok.
-
- It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
- return value of this function
-
---*/
-
-STRSAFEAPI StringCchPrintfA(char* pszDest, size_t cchDest, const char* pszFormat, ...);
-STRSAFEAPI StringCchPrintfW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszFormat, ...);
-#ifdef UNICODE
-#define StringCchPrintf StringCchPrintfW
-#else
-#define StringCchPrintf StringCchPrintfA
-#endif // !UNICODE
-
-#ifdef STRSAFE_INLINE
-STRSAFEAPI StringCchPrintfA(char* pszDest, size_t cchDest, const char* pszFormat, ...)
-{
- HRESULT hr;
-
- if (cchDest > STRSAFE_MAX_CCH)
- {
- hr = STRSAFE_E_INVALID_PARAMETER;
- }
- else
- {
- va_list argList;
-
- va_start(argList, pszFormat);
-
- hr = StringVPrintfWorkerA(pszDest, cchDest, pszFormat, argList);
-
- va_end(argList);
- }
-
- return hr;
-}
-
-#if defined(FEATURE_PAL) || !defined(PLATFORM_UNIX)
-STRSAFEAPI StringCchPrintfW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszFormat, ...)
-{
- HRESULT hr;
-
- if (cchDest > STRSAFE_MAX_CCH)
- {
- hr = STRSAFE_E_INVALID_PARAMETER;
- }
- else
- {
- va_list argList;
-
- va_start(argList, pszFormat);
-
- hr = StringVPrintfWorkerW(pszDest, cchDest, pszFormat, argList);
-
- va_end(argList);
- }
-
- return hr;
-}
-#endif // FEATURE_PAL || !PLATFORM_UNIX
-#endif // STRSAFE_INLINE
-#endif // !STRSAFE_NO_CCH_FUNCTIONS
-
-
-#ifndef STRSAFE_NO_CB_FUNCTIONS
-/*++
-
-STDAPI StringCbPrintf(LPTSTR pszDest,
- size_t cbDest,
- LPCTSTR pszFormat,
- ...);
-
-Routine Description:
-
- This routine is a safer version of the C built-in function 'sprintf'.
- The size of the destination buffer (in bytes) is a parameter and
- this function will not write past the end of this buffer and it will
- ALWAYS null terminate the destination buffer (unless it is zero length).
-
- This function returns a hresult, and not a pointer. It returns a S_OK
- if the string was printed without truncation and null terminated, otherwise
- it will return a failure code. In failure cases it will return a truncated
- version of the ideal result.
-
-Arguments:
-
- pszDest - destination string
-
- cbDest - size of destination buffer in bytes
- length must be sufficient to hold the resulting formatted
- string, including the null terminator.
-
- pszFormat - format string which must be null terminated
-
- ... - additional parameters to be formatted according to
- the format string
-
-Notes:
- Behavior is undefined if destination, format strings or any arguments
- strings overlap.
-
- pszDest and pszFormat should not be NULL. See StringCbPrintfEx if you
- require the handling of NULL values.
-
-
-Return Value:
-
- S_OK - if there was sufficient space in the dest buffer for
- the resultant string and it was null terminated.
-
- failure - you can use the macro HRESULT_CODE() to get a win32 error
- code for all falure cases
-
- STRSAFE_E_INSUFFICIENT_BUFFER /
- HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
- - this return value is an indication that the print operation
- failed due to insufficient space. When this error occurs,
- the destination buffer is modified to contain a truncated
- version of the ideal result and is null terminated. This
- is useful for situations where truncation is ok.
-
- It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
- return value of this function
-
---*/
-
-STRSAFEAPI StringCbPrintfA(char* pszDest, size_t cbDest, const char* pszFormat, ...);
-STRSAFEAPI StringCbPrintfW(WCHAR* pszDest, size_t cbDest, const WCHAR* pszFormat, ...);
-#ifdef UNICODE
-#define StringCbPrintf StringCbPrintfW
-#else
-#define StringCbPrintf StringCbPrintfA
-#endif // !UNICODE
-
-#ifdef STRSAFE_INLINE
-STRSAFEAPI StringCbPrintfA(char* pszDest, size_t cbDest, const char* pszFormat, ...)
-{
- HRESULT hr;
- size_t cchDest;
-
- cchDest = cbDest / sizeof(char);
-
- if (cchDest > STRSAFE_MAX_CCH)
- {
- hr = STRSAFE_E_INVALID_PARAMETER;
- }
- else
- {
- va_list argList;
-
- va_start(argList, pszFormat);
-
- hr = StringVPrintfWorkerA(pszDest, cchDest, pszFormat, argList);
-
- va_end(argList);
- }
-
- return hr;
-}
-
-#if defined(FEATURE_PAL) || !defined(PLATFORM_UNIX)
-STRSAFEAPI StringCbPrintfW(WCHAR* pszDest, size_t cbDest, const WCHAR* pszFormat, ...)
-{
- HRESULT hr;
- size_t cchDest;
-
- cchDest = cbDest / sizeof(WCHAR);
-
- if (cchDest > STRSAFE_MAX_CCH)
- {
- hr = STRSAFE_E_INVALID_PARAMETER;
- }
- else
- {
- va_list argList;
-
- va_start(argList, pszFormat);
-
- hr = StringVPrintfWorkerW(pszDest, cchDest, pszFormat, argList);
-
- va_end(argList);
- }
-
- return hr;
-}
-#endif // FEATURE_PAL || !PLATFORM_UNIX
-#endif // STRSAFE_INLINE
-#endif // !STRSAFE_NO_CB_FUNCTIONS
-
-
-#ifndef STRSAFE_NO_CCH_FUNCTIONS
-/*++
-
-STDAPI StringCchPrintfEx(LPTSTR pszDest,
- size_t cchDest,
- LPTSTR* ppszDestEnd,
- size_t* pcchRemaining,
- DWORD dwFlags,
- LPCTSTR pszFormat,
- ...);
-
-Routine Description:
-
- This routine is a safer version of the C built-in function 'sprintf' with
- some additional parameters. In addition to functionality provided by
- StringCchPrintf, this routine also returns a pointer to the end of the
- destination string and the number of characters left in the destination string
- including the null terminator. The flags parameter allows additional controls.
-
-Arguments:
-
- pszDest - destination string
-
- cchDest - size of destination buffer in characters.
- length must be sufficient to contain the resulting
- formatted string plus the null terminator.
-
- ppszDestEnd - if ppszDestEnd is non-null, the function will return a
- pointer to the end of the destination string. If the
- function printed any data, the result will point to the
- null termination character
-
- pcchRemaining - if pcchRemaining is non-null, the function will return
- the number of characters left in the destination string,
- including the null terminator
-
- dwFlags - controls some details of the string copy:
-
- STRSAFE_FILL_BEHIND_NULL
- if the function succeeds, the low byte of dwFlags will be
- used to fill the uninitialize part of destination buffer
- behind the null terminator
-
- STRSAFE_IGNORE_NULLS
- treat NULL string pointers like empty strings (TEXT(""))
-
- STRSAFE_FILL_ON_FAILURE
- if the function fails, the low byte of dwFlags will be
- used to fill all of the destination buffer, and it will
- be null terminated. This will overwrite any truncated
- string returned when the failure is
- STRSAFE_E_INSUFFICIENT_BUFFER
-
- STRSAFE_NO_TRUNCATION /
- STRSAFE_NULL_ON_FAILURE
- if the function fails, the destination buffer will be set
- to the empty string. This will overwrite any truncated string
- returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER.
-
- pszFormat - format string which must be null terminated
-
- ... - additional parameters to be formatted according to
- the format string
-
-Notes:
- Behavior is undefined if destination, format strings or any arguments
- strings overlap.
-
- pszDest and pszFormat should not be NULL unless the STRSAFE_IGNORE_NULLS
- flag is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and
- pszFormat may be NULL. An error may still be returned even though NULLS
- are ignored due to insufficient space.
-
-Return Value:
-
- S_OK - if there was source data and it was all concatenated and the
- resultant dest string was null terminated
-
- failure - you can use the macro HRESULT_CODE() to get a win32 error
- code for all falure cases
-
- STRSAFE_E_INSUFFICIENT_BUFFER /
- HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
- - this return value is an indication that the print operation
- failed due to insufficient space. When this error occurs,
- the destination buffer is modified to contain a truncated
- version of the ideal result and is null terminated. This
- is useful for situations where truncation is ok.
-
- It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
- return value of this function
-
---*/
-
-STRSAFEAPI StringCchPrintfExA(char* pszDest, size_t cchDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const char* pszFormat, ...);
-STRSAFEAPI StringCchPrintfExW(WCHAR* pszDest, size_t cchDest, WCHAR** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const WCHAR* pszFormat, ...);
-#ifdef UNICODE
-#define StringCchPrintfEx StringCchPrintfExW
-#else
-#define StringCchPrintfEx StringCchPrintfExA
-#endif // !UNICODE
-
-#ifdef STRSAFE_INLINE
-STRSAFEAPI StringCchPrintfExA(char* pszDest, size_t cchDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const char* pszFormat, ...)
-{
- HRESULT hr;
-
- if (cchDest > STRSAFE_MAX_CCH)
- {
- hr = STRSAFE_E_INVALID_PARAMETER;
- }
- else
- {
- size_t cbDest;
- va_list argList;
-
- // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1
- cbDest = cchDest * sizeof(char);
- va_start(argList, pszFormat);
-
- hr = StringVPrintfExWorkerA(pszDest, cchDest, cbDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, argList);
-
- va_end(argList);
- }
-
- return hr;
-}
-
-#if defined(FEATURE_PAL) || !defined(PLATFORM_UNIX)
-STRSAFEAPI StringCchPrintfExW(WCHAR* pszDest, size_t cchDest, WCHAR** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const WCHAR* pszFormat, ...)
-{
- HRESULT hr;
-
- if (cchDest > STRSAFE_MAX_CCH)
- {
- hr = STRSAFE_E_INVALID_PARAMETER;
- }
- else
- {
- size_t cbDest;
- va_list argList;
-
- // safe to multiply cchDest * sizeof(WCHAR) since cchDest < STRSAFE_MAX_CCH and sizeof(WCHAR) is 2
- cbDest = cchDest * sizeof(WCHAR);
- va_start(argList, pszFormat);
-
- hr = StringVPrintfExWorkerW(pszDest, cchDest, cbDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, argList);
-
- va_end(argList);
- }
-
- return hr;
-}
-#endif // FEATURE_PAL || !PLATFORM_UNIX
-#endif // STRSAFE_INLINE
-#endif // !STRSAFE_NO_CCH_FUNCTIONS
-
-
-#ifndef STRSAFE_NO_CB_FUNCTIONS
-/*++
-
-STDAPI StringCbPrintfEx(LPTSTR pszDest,
- size_t cbDest,
- LPTSTR* ppszDestEnd,
- size_t* pcbRemaining,
- DWORD dwFlags,
- LPCTSTR pszFormat,
- ...);
-
-Routine Description:
-
- This routine is a safer version of the C built-in function 'sprintf' with
- some additional parameters. In addition to functionality provided by
- StringCbPrintf, this routine also returns a pointer to the end of the
- destination string and the number of bytes left in the destination string
- including the null terminator. The flags parameter allows additional controls.
-
-Arguments:
-
- pszDest - destination string
-
- cbDest - size of destination buffer in bytes.
- length must be sufficient to contain the resulting
- formatted string plus the null terminator.
-
- ppszDestEnd - if ppszDestEnd is non-null, the function will return a
- pointer to the end of the destination string. If the
- function printed any data, the result will point to the
- null termination character
-
- pcbRemaining - if pcbRemaining is non-null, the function will return
- the number of bytes left in the destination string,
- including the null terminator
-
- dwFlags - controls some details of the string copy:
-
- STRSAFE_FILL_BEHIND_NULL
- if the function succeeds, the low byte of dwFlags will be
- used to fill the uninitialize part of destination buffer
- behind the null terminator
-
- STRSAFE_IGNORE_NULLS
- treat NULL string pointers like empty strings (TEXT(""))
-
- STRSAFE_FILL_ON_FAILURE
- if the function fails, the low byte of dwFlags will be
- used to fill all of the destination buffer, and it will
- be null terminated. This will overwrite any truncated
- string returned when the failure is
- STRSAFE_E_INSUFFICIENT_BUFFER
-
- STRSAFE_NO_TRUNCATION /
- STRSAFE_NULL_ON_FAILURE
- if the function fails, the destination buffer will be set
- to the empty string. This will overwrite any truncated string
- returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER.
-
- pszFormat - format string which must be null terminated
-
- ... - additional parameters to be formatted according to
- the format string
-
-Notes:
- Behavior is undefined if destination, format strings or any arguments
- strings overlap.
-
- pszDest and pszFormat should not be NULL unless the STRSAFE_IGNORE_NULLS
- flag is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and
- pszFormat may be NULL. An error may still be returned even though NULLS
- are ignored due to insufficient space.
-
-Return Value:
-
- S_OK - if there was source data and it was all concatenated and the
- resultant dest string was null terminated
-
- failure - you can use the macro HRESULT_CODE() to get a win32 error
- code for all falure cases
-
- STRSAFE_E_INSUFFICIENT_BUFFER /
- HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
- - this return value is an indication that the print operation
- failed due to insufficient space. When this error occurs,
- the destination buffer is modified to contain a truncated
- version of the ideal result and is null terminated. This
- is useful for situations where truncation is ok.
-
- It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
- return value of this function
-
---*/
-
-STRSAFEAPI StringCbPrintfExA(char* pszDest, size_t cbDest, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const char* pszFormat, ...);
-STRSAFEAPI StringCbPrintfExW(WCHAR* pszDest, size_t cbDest, WCHAR** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const WCHAR* pszFormat, ...);
-#ifdef UNICODE
-#define StringCbPrintfEx StringCbPrintfExW
-#else
-#define StringCbPrintfEx StringCbPrintfExA
-#endif // !UNICODE
-
-#ifdef STRSAFE_INLINE
-STRSAFEAPI StringCbPrintfExA(char* pszDest, size_t cbDest, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const char* pszFormat, ...)
-{
- HRESULT hr;
- size_t cchDest;
- size_t cchRemaining = 0;
-
- cchDest = cbDest / sizeof(char);
-
- if (cchDest > STRSAFE_MAX_CCH)
- {
- hr = STRSAFE_E_INVALID_PARAMETER;
- }
- else
- {
- va_list argList;
-
- va_start(argList, pszFormat);
-
- hr = StringVPrintfExWorkerA(pszDest, cchDest, cbDest, ppszDestEnd, &cchRemaining, dwFlags, pszFormat, argList);
-
- va_end(argList);
- }
-
- if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
- {
- if (pcbRemaining)
- {
- // safe to multiply cchRemaining * sizeof(char) since cchRemaining < STRSAFE_MAX_CCH and sizeof(char) is 1
- *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char));
- }
- }
-
- return hr;
-}
-
-#if defined(FEATURE_PAL) || !defined(PLATFORM_UNIX)
-STRSAFEAPI StringCbPrintfExW(WCHAR* pszDest, size_t cbDest, WCHAR** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const WCHAR* pszFormat, ...)
-{
- HRESULT hr;
- size_t cchDest;
- size_t cchRemaining = 0;
-
- cchDest = cbDest / sizeof(WCHAR);
-
- if (cchDest > STRSAFE_MAX_CCH)
- {
- hr = STRSAFE_E_INVALID_PARAMETER;
- }
- else
- {
- va_list argList;
-
- va_start(argList, pszFormat);
-
- hr = StringVPrintfExWorkerW(pszDest, cchDest, cbDest, ppszDestEnd, &cchRemaining, dwFlags, pszFormat, argList);
-
- va_end(argList);
- }
-
- if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
- {
- if (pcbRemaining)
- {
- // safe to multiply cchRemaining * sizeof(WCHAR) since cchRemaining < STRSAFE_MAX_CCH and sizeof(WCHAR) is 2
- *pcbRemaining = (cchRemaining * sizeof(WCHAR)) + (cbDest % sizeof(WCHAR));
- }
- }
-
- return hr;
-}
-#endif // FEATURE_PAL || !PLATFORM_UNIX
-#endif // STRSAFE_INLINE
-#endif // !STRSAFE_NO_CB_FUNCTIONS
-
-
-#ifndef STRSAFE_NO_CCH_FUNCTIONS
-/*++
-
-STDAPI StringCchVPrintfEx(LPTSTR pszDest,
- size_t cchDest,
- LPTSTR* ppszDestEnd,
- size_t* pcchRemaining,
- DWORD dwFlags,
- LPCTSTR pszFormat,
- va_list argList);
-
-Routine Description:
-
- This routine is a safer version of the C built-in function 'vsprintf' with
- some additional parameters. In addition to functionality provided by
- StringCchVPrintf, this routine also returns a pointer to the end of the
- destination string and the number of characters left in the destination string
- including the null terminator. The flags parameter allows additional controls.
-
-Arguments:
-
- pszDest - destination string
-
- cchDest - size of destination buffer in characters.
- length must be sufficient to contain the resulting
- formatted string plus the null terminator.
-
- ppszDestEnd - if ppszDestEnd is non-null, the function will return a
- pointer to the end of the destination string. If the
- function printed any data, the result will point to the
- null termination character
-
- pcchRemaining - if pcchRemaining is non-null, the function will return
- the number of characters left in the destination string,
- including the null terminator
-
- dwFlags - controls some details of the string copy:
-
- STRSAFE_FILL_BEHIND_NULL
- if the function succeeds, the low byte of dwFlags will be
- used to fill the uninitialize part of destination buffer
- behind the null terminator
-
- STRSAFE_IGNORE_NULLS
- treat NULL string pointers like empty strings (TEXT(""))
-
- STRSAFE_FILL_ON_FAILURE
- if the function fails, the low byte of dwFlags will be
- used to fill all of the destination buffer, and it will
- be null terminated. This will overwrite any truncated
- string returned when the failure is
- STRSAFE_E_INSUFFICIENT_BUFFER
-
- STRSAFE_NO_TRUNCATION /
- STRSAFE_NULL_ON_FAILURE
- if the function fails, the destination buffer will be set
- to the empty string. This will overwrite any truncated string
- returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER.
-
- pszFormat - format string which must be null terminated
-
- argList - va_list from the variable arguments according to the
- stdarg.h convention
-
-Notes:
- Behavior is undefined if destination, format strings or any arguments
- strings overlap.
-
- pszDest and pszFormat should not be NULL unless the STRSAFE_IGNORE_NULLS
- flag is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and
- pszFormat may be NULL. An error may still be returned even though NULLS
- are ignored due to insufficient space.
-
-Return Value:
-
- S_OK - if there was source data and it was all concatenated and the
- resultant dest string was null terminated
-
- failure - you can use the macro HRESULT_CODE() to get a win32 error
- code for all falure cases
-
- STRSAFE_E_INSUFFICIENT_BUFFER /
- HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
- - this return value is an indication that the print operation
- failed due to insufficient space. When this error occurs,
- the destination buffer is modified to contain a truncated
- version of the ideal result and is null terminated. This
- is useful for situations where truncation is ok.
-
- It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
- return value of this function
-
---*/
-
-STRSAFEAPI StringCchVPrintfExA(char* pszDest, size_t cchDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const char* pszFormat, va_list argList);
-STRSAFEAPI StringCchVPrintfExW(WCHAR* pszDest, size_t cchDest, WCHAR** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const WCHAR* pszFormat, va_list argList);
-#ifdef UNICODE
-#define StringCchVPrintfEx StringCchVPrintfExW
-#else
-#define StringCchVPrintfEx StringCchVPrintfExA
-#endif // !UNICODE
-
-#ifdef STRSAFE_INLINE
-STRSAFEAPI StringCchVPrintfExA(char* pszDest, size_t cchDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const char* pszFormat, va_list argList)
-{
- HRESULT hr;
-
- if (cchDest > STRSAFE_MAX_CCH)
- {
- hr = STRSAFE_E_INVALID_PARAMETER;
- }
- else
- {
- size_t cbDest;
-
- // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1
- cbDest = cchDest * sizeof(char);
-
- hr = StringVPrintfExWorkerA(pszDest, cchDest, cbDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, argList);
- }
-
- return hr;
-}
-
-#if defined(FEATURE_PAL) || !defined(PLATFORM_UNIX)
-STRSAFEAPI StringCchVPrintfExW(WCHAR* pszDest, size_t cchDest, WCHAR** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const WCHAR* pszFormat, va_list argList)
-{
- HRESULT hr;
-
- if (cchDest > STRSAFE_MAX_CCH)
- {
- hr = STRSAFE_E_INVALID_PARAMETER;
- }
- else
- {
- size_t cbDest;
-
- // safe to multiply cchDest * sizeof(WCHAR) since cchDest < STRSAFE_MAX_CCH and sizeof(WCHAR) is 2
- cbDest = cchDest * sizeof(WCHAR);
-
- hr = StringVPrintfExWorkerW(pszDest, cchDest, cbDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, argList);
- }
-
- return hr;
-}
-#endif // FEATURE_PAL || !PLATFORM_UNIX
-#endif // STRSAFE_INLINE
-#endif // !STRSAFE_NO_CCH_FUNCTIONS
-
-
-#ifndef STRSAFE_NO_CB_FUNCTIONS
-/*++
-
-STDAPI StringCbVPrintfEx(LPTSTR pszDest,
- size_t cbDest,
- LPTSTR* ppszDestEnd,
- size_t* pcbRemaining,
- DWORD dwFlags,
- LPCTSTR pszFormat,
- va_list argList);
-
-Routine Description:
-
- This routine is a safer version of the C built-in function 'vsprintf' with
- some additional parameters. In addition to functionality provided by
- StringCbVPrintf, this routine also returns a pointer to the end of the
- destination string and the number of characters left in the destination string
- including the null terminator. The flags parameter allows additional controls.
-
-Arguments:
-
- pszDest - destination string
-
- cbDest - size of destination buffer in bytes.
- length must be sufficient to contain the resulting
- formatted string plus the null terminator.
-
- ppszDestEnd - if ppszDestEnd is non-null, the function will return
- a pointer to the end of the destination string. If the
- function printed any data, the result will point to the
- null termination character
-
- pcbRemaining - if pcbRemaining is non-null, the function will return
- the number of bytes left in the destination string,
- including the null terminator
-
- dwFlags - controls some details of the string copy:
-
- STRSAFE_FILL_BEHIND_NULL
- if the function succeeds, the low byte of dwFlags will be
- used to fill the uninitialize part of destination buffer
- behind the null terminator
-
- STRSAFE_IGNORE_NULLS
- treat NULL string pointers like empty strings (TEXT(""))
-
- STRSAFE_FILL_ON_FAILURE
- if the function fails, the low byte of dwFlags will be
- used to fill all of the destination buffer, and it will
- be null terminated. This will overwrite any truncated
- string returned when the failure is
- STRSAFE_E_INSUFFICIENT_BUFFER
-
- STRSAFE_NO_TRUNCATION /
- STRSAFE_NULL_ON_FAILURE
- if the function fails, the destination buffer will be set
- to the empty string. This will overwrite any truncated string
- returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER.
-
- pszFormat - format string which must be null terminated
-
- argList - va_list from the variable arguments according to the
- stdarg.h convention
-
-Notes:
- Behavior is undefined if destination, format strings or any arguments
- strings overlap.
-
- pszDest and pszFormat should not be NULL unless the STRSAFE_IGNORE_NULLS
- flag is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and
- pszFormat may be NULL. An error may still be returned even though NULLS
- are ignored due to insufficient space.
-
-Return Value:
-
- S_OK - if there was source data and it was all concatenated and the
- resultant dest string was null terminated
-
- failure - you can use the macro HRESULT_CODE() to get a win32 error
- code for all falure cases
-
- STRSAFE_E_INSUFFICIENT_BUFFER /
- HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER
- - this return value is an indication that the print operation
- failed due to insufficient space. When this error occurs,
- the destination buffer is modified to contain a truncated
- version of the ideal result and is null terminated. This
- is useful for situations where truncation is ok.
-
- It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the
- return value of this function
-
---*/
-
-STRSAFEAPI StringCbVPrintfExA(char* pszDest, size_t cbDest, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const char* pszFormat, va_list argList);
-STRSAFEAPI StringCbVPrintfExW(WCHAR* pszDest, size_t cbDest, WCHAR** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const WCHAR* pszFormat, va_list argList);
-#ifdef UNICODE
-#define StringCbVPrintfEx StringCbVPrintfExW
-#else
-#define StringCbVPrintfEx StringCbVPrintfExA
-#endif // !UNICODE
-
-#ifdef STRSAFE_INLINE
-STRSAFEAPI StringCbVPrintfExA(char* pszDest, size_t cbDest, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const char* pszFormat, va_list argList)
-{
- HRESULT hr;
- size_t cchDest;
- size_t cchRemaining = 0;
-
- cchDest = cbDest / sizeof(char);
-
- if (cchDest > STRSAFE_MAX_CCH)
- {
- hr = STRSAFE_E_INVALID_PARAMETER;
- }
- else
- {
- hr = StringVPrintfExWorkerA(pszDest, cchDest, cbDest, ppszDestEnd, &cchRemaining, dwFlags, pszFormat, argList);
- }
-
- if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
- {
- if (pcbRemaining)
- {
- // safe to multiply cchRemaining * sizeof(char) since cchRemaining < STRSAFE_MAX_CCH and sizeof(char) is 1
- *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char));
- }
- }
-
- return hr;
-}
-
-#if defined(FEATURE_PAL) || !defined(PLATFORM_UNIX)
-STRSAFEAPI StringCbVPrintfExW(WCHAR* pszDest, size_t cbDest, WCHAR** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags, const WCHAR* pszFormat, va_list argList)
-{
- HRESULT hr;
- size_t cchDest;
- size_t cchRemaining = 0;
-
- cchDest = cbDest / sizeof(WCHAR);
-
- if (cchDest > STRSAFE_MAX_CCH)
- {
- hr = STRSAFE_E_INVALID_PARAMETER;
- }
- else
- {
- hr = StringVPrintfExWorkerW(pszDest, cchDest, cbDest, ppszDestEnd, &cchRemaining, dwFlags, pszFormat, argList);
- }
-
- if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
- {
- if (pcbRemaining)
- {
- // safe to multiply cchRemaining * sizeof(WCHAR) since cchRemaining < STRSAFE_MAX_CCH and sizeof(WCHAR) is 2
- *pcbRemaining = (cchRemaining * sizeof(WCHAR)) + (cbDest % sizeof(WCHAR));
- }
- }
-
- return hr;
-}
-#endif // FEATURE_PAL || !PLATFORM_UNIX
-#endif // STRSAFE_INLINE
-#endif // !STRSAFE_NO_CB_FUNCTIONS
-
-
-#ifndef STRSAFE_NO_CCH_FUNCTIONS
-/*++
-
STDAPI StringCchGets(LPTSTR pszDest,
size_t cchDest);
@@ -5543,394 +4421,6 @@ STRSAFEAPI StringCatNExWorkerW(WCHAR* pszDest, size_t cchDest, size_t cbDest, co
}
#endif // FEATURE_PAL || !PLATFORM_UNIX
-STRSAFEAPI StringVPrintfWorkerA(char* pszDest, size_t cchDest, const char* pszFormat, va_list argList)
-{
- HRESULT hr = S_OK;
-
- if (cchDest == 0)
- {
- // can not null terminate a zero-byte dest buffer
- hr = STRSAFE_E_INVALID_PARAMETER;
- }
- else
- {
- int iRet;
- size_t cchMax;
-
- // leave the last space for the null terminator
- cchMax = cchDest - 1;
-
- iRet = _vsnprintf(pszDest, cchMax, pszFormat, argList);
- // ASSERT((iRet < 0) || (((size_t)iRet) <= cchMax));
-
- if ((iRet < 0) || (((size_t)iRet) > cchMax))
- {
- // need to null terminate the string
- pszDest += cchMax;
- *pszDest = '\0';
-
- // we have truncated pszDest
- hr = STRSAFE_E_INSUFFICIENT_BUFFER;
- }
- else if (((size_t)iRet) == cchMax)
- {
- // need to null terminate the string
- pszDest += cchMax;
- *pszDest = '\0';
- }
- }
-
- return hr;
-}
-
-#if defined(FEATURE_PAL) || !defined(PLATFORM_UNIX)
-STRSAFEAPI StringVPrintfWorkerW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszFormat, va_list argList)
-{
- HRESULT hr = S_OK;
-
- if (cchDest == 0)
- {
- // can not null terminate a zero-byte dest buffer
- hr = STRSAFE_E_INVALID_PARAMETER;
- }
- else
- {
- int iRet;
- size_t cchMax;
-
- // leave the last space for the null terminator
- cchMax = cchDest - 1;
-
- iRet = _vsnwprintf(pszDest, cchMax, pszFormat, argList);
- // ASSERT((iRet < 0) || (((size_t)iRet) <= cchMax));
-
- if ((iRet < 0) || (((size_t)iRet) > cchMax))
- {
- // need to null terminate the string
- pszDest += cchMax;
- *pszDest = L'\0';
-
- // we have truncated pszDest
- hr = STRSAFE_E_INSUFFICIENT_BUFFER;
- }
- else if (((size_t)iRet) == cchMax)
- {
- // need to null terminate the string
- pszDest += cchMax;
- *pszDest = L'\0';
- }
- }
-
- return hr;
-}
-#endif // FEATURE_PAL || !PLATFORM_UNIX
-
-STRSAFEAPI StringVPrintfExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const char* pszFormat, va_list argList)
-{
- HRESULT hr = S_OK;
- char* pszDestEnd = pszDest;
- size_t cchRemaining = 0;
-
- // ASSERT(cbDest == (cchDest * sizeof(char)) ||
- // cbDest == (cchDest * sizeof(char)) + (cbDest % sizeof(char)));
-
- // only accept valid flags
- if (dwFlags & (~STRSAFE_VALID_FLAGS))
- {
- hr = STRSAFE_E_INVALID_PARAMETER;
- }
- else
- {
- if (dwFlags & STRSAFE_IGNORE_NULLS)
- {
- if (pszDest == NULL)
- {
- if ((cchDest != 0) || (cbDest != 0))
- {
- // NULL pszDest and non-zero cchDest/cbDest is invalid
- hr = STRSAFE_E_INVALID_PARAMETER;
- }
- }
-
- if (pszFormat == NULL)
- {
- pszFormat = "";
- }
- }
-
- if (SUCCEEDED(hr))
- {
- if (cchDest == 0)
- {
- pszDestEnd = pszDest;
- cchRemaining = 0;
-
- // only fail if there was actually a non-empty format string
- if (*pszFormat != '\0')
- {
- if (pszDest == NULL)
- {
- hr = STRSAFE_E_INVALID_PARAMETER;
- }
- else
- {
- hr = STRSAFE_E_INSUFFICIENT_BUFFER;
- }
- }
- }
- else
- {
- int iRet;
- size_t cchMax;
-
- // leave the last space for the null terminator
- cchMax = cchDest - 1;
-
- iRet = _vsnprintf(pszDest, cchMax, pszFormat, argList);
- // ASSERT((iRet < 0) || (((size_t)iRet) <= cchMax));
-
- if ((iRet < 0) || (((size_t)iRet) > cchMax))
- {
- // we have truncated pszDest
- pszDestEnd = pszDest + cchMax;
- cchRemaining = 1;
-
- // need to null terminate the string
- *pszDestEnd = '\0';
-
- hr = STRSAFE_E_INSUFFICIENT_BUFFER;
- }
- else if (((size_t)iRet) == cchMax)
- {
- // string fit perfectly
- pszDestEnd = pszDest + cchMax;
- cchRemaining = 1;
-
- // need to null terminate the string
- *pszDestEnd = '\0';
- }
- else if (((size_t)iRet) < cchMax)
- {
- // there is extra room
- pszDestEnd = pszDest + iRet;
- cchRemaining = cchDest - iRet;
-
- if (dwFlags & STRSAFE_FILL_BEHIND_NULL)
- {
- memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(char)) + (cbDest % sizeof(char)));
- }
- }
- }
- }
- }
-
- if (FAILED(hr))
- {
- if (pszDest)
- {
- if (dwFlags & STRSAFE_FILL_ON_FAILURE)
- {
- memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest);
-
- if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0)
- {
- pszDestEnd = pszDest;
- cchRemaining = cchDest;
- }
- else if (cchDest > 0)
- {
- pszDestEnd = pszDest + cchDest - 1;
- cchRemaining = 1;
-
- // null terminate the end of the string
- *pszDestEnd = '\0';
- }
- }
-
- if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION))
- {
- if (cchDest > 0)
- {
- pszDestEnd = pszDest;
- cchRemaining = cchDest;
-
- // null terminate the beginning of the string
- *pszDestEnd = '\0';
- }
- }
- }
- }
-
- if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
- {
- if (ppszDestEnd)
- {
- *ppszDestEnd = pszDestEnd;
- }
-
- if (pcchRemaining)
- {
- *pcchRemaining = cchRemaining;
- }
- }
-
- return hr;
-}
-
-#if defined(FEATURE_PAL) || !defined(PLATFORM_UNIX)
-STRSAFEAPI StringVPrintfExWorkerW(WCHAR* pszDest, size_t cchDest, size_t cbDest, WCHAR** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags, const WCHAR* pszFormat, va_list argList)
-{
- HRESULT hr = S_OK;
- WCHAR* pszDestEnd = pszDest;
- size_t cchRemaining = 0;
-
- // ASSERT(cbDest == (cchDest * sizeof(WCHAR)) ||
- // cbDest == (cchDest * sizeof(WCHAR)) + (cbDest % sizeof(WCHAR)));
-
- // only accept valid flags
- if (dwFlags & (~STRSAFE_VALID_FLAGS))
- {
- hr = STRSAFE_E_INVALID_PARAMETER;
- }
- else
- {
- if (dwFlags & STRSAFE_IGNORE_NULLS)
- {
- if (pszDest == NULL)
- {
- if ((cchDest != 0) || (cbDest != 0))
- {
- // NULL pszDest and non-zero cchDest/cbDest is invalid
- hr = STRSAFE_E_INVALID_PARAMETER;
- }
- }
-
- if (pszFormat == NULL)
- {
- pszFormat = u"";
- }
- }
-
- if (SUCCEEDED(hr))
- {
- if (cchDest == 0)
- {
- pszDestEnd = pszDest;
- cchRemaining = 0;
-
- // only fail if there was actually a non-empty format string
- if (*pszFormat != L'\0')
- {
- if (pszDest == NULL)
- {
- hr = STRSAFE_E_INVALID_PARAMETER;
- }
- else
- {
- hr = STRSAFE_E_INSUFFICIENT_BUFFER;
- }
- }
- }
- else
- {
- int iRet;
- size_t cchMax;
-
- // leave the last space for the null terminator
- cchMax = cchDest - 1;
-
- iRet = _vsnwprintf(pszDest, cchMax, pszFormat, argList);
- // ASSERT((iRet < 0) || (((size_t)iRet) <= cchMax));
-
- if ((iRet < 0) || (((size_t)iRet) > cchMax))
- {
- // we have truncated pszDest
- pszDestEnd = pszDest + cchMax;
- cchRemaining = 1;
-
- // need to null terminate the string
- *pszDestEnd = L'\0';
-
- hr = STRSAFE_E_INSUFFICIENT_BUFFER;
- }
- else if (((size_t)iRet) == cchMax)
- {
- // string fit perfectly
- pszDestEnd = pszDest + cchMax;
- cchRemaining = 1;
-
- // need to null terminate the string
- *pszDestEnd = L'\0';
- }
- else if (((size_t)iRet) < cchMax)
- {
- // there is extra room
- pszDestEnd = pszDest + iRet;
- cchRemaining = cchDest - iRet;
-
- if (dwFlags & STRSAFE_FILL_BEHIND_NULL)
- {
- memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(WCHAR)) + (cbDest % sizeof(WCHAR)));
- }
- }
- }
- }
- }
-
- if (FAILED(hr))
- {
- if (pszDest)
- {
- if (dwFlags & STRSAFE_FILL_ON_FAILURE)
- {
- memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest);
-
- if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0)
- {
- pszDestEnd = pszDest;
- cchRemaining = cchDest;
- }
- else if (cchDest > 0)
- {
- pszDestEnd = pszDest + cchDest - 1;
- cchRemaining = 1;
-
- // null terminate the end of the string
- *pszDestEnd = L'\0';
- }
- }
-
- if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION))
- {
- if (cchDest > 0)
- {
- pszDestEnd = pszDest;
- cchRemaining = cchDest;
-
- // null terminate the beginning of the string
- *pszDestEnd = L'\0';
- }
- }
- }
- }
-
- if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
- {
- if (ppszDestEnd)
- {
- *ppszDestEnd = pszDestEnd;
- }
-
- if (pcchRemaining)
- {
- *pcchRemaining = cchRemaining;
- }
- }
-
- return hr;
-}
-#endif // FEATURE_PAL || !PLATFORM_UNIX
-
STRSAFEAPI StringLengthWorkerA(const char* psz, size_t cchMax, size_t* pcch)
{
HRESULT hr = S_OK;
diff --git a/src/pal/inc/unixasmmacros.inc b/src/pal/inc/unixasmmacros.inc
index 7186645b34..e7a5eba898 100644
--- a/src/pal/inc/unixasmmacros.inc
+++ b/src/pal/inc/unixasmmacros.inc
@@ -28,7 +28,9 @@
.equiv \New, \Old
.endm
-#if defined(_AMD64_)
+#if defined(_X86_)
+#include "unixasmmacrosx86.inc"
+#elif defined(_AMD64_)
#include "unixasmmacrosamd64.inc"
#elif defined(_ARM_)
#include "unixasmmacrosarm.inc"
diff --git a/src/pal/inc/unixasmmacrosamd64.inc b/src/pal/inc/unixasmmacrosamd64.inc
index f221b4406b..c3321ce598 100644
--- a/src/pal/inc/unixasmmacrosamd64.inc
+++ b/src/pal/inc/unixasmmacrosamd64.inc
@@ -8,7 +8,7 @@
#if defined(__APPLE__)
.cfi_personality 0x9b, C_FUNC(\Handler) // 0x9b == DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4
#else
- .cfi_personality 0, C_FUNC(\Handler) // 0 == DW_EH_PE_absptr
+ .cfi_personality 0x1b, C_FUNC(\Handler) // 0x1b == DW_EH_PE_pcrel | DW_EH_PE_sdata4
#endif
.endif
.endm
diff --git a/src/pal/inc/unixasmmacrosarm.inc b/src/pal/inc/unixasmmacrosarm.inc
index 14b0b4160e..76ea5eb93c 100644
--- a/src/pal/inc/unixasmmacrosarm.inc
+++ b/src/pal/inc/unixasmmacrosarm.inc
@@ -229,7 +229,8 @@ C_FUNC(\Name\()_End):
.endm
.macro EPILOG_STACK_RESTORE_OFFSET Register, Offset
- sub sp, \Register, \Offset
+ sub \Register, \Offset
+ mov sp, \Register
.endm
.macro EPILOG_BRANCH Target
diff --git a/src/pal/inc/unixasmmacrosarm64.inc b/src/pal/inc/unixasmmacrosarm64.inc
index ae60db4d35..60142053b0 100644
--- a/src/pal/inc/unixasmmacrosarm64.inc
+++ b/src/pal/inc/unixasmmacrosarm64.inc
@@ -5,7 +5,7 @@
.macro NESTED_ENTRY Name, Section, Handler
LEAF_ENTRY \Name, \Section
.ifnc \Handler, NoHandler
- .cfi_personality 0, C_FUNC(\Handler) // 0 == DW_EH_PE_absptr
+ .cfi_personality 0x1b, C_FUNC(\Handler) // 0x1b == DW_EH_PE_pcrel | DW_EH_PE_sdata4
.endif
.endm
diff --git a/src/pal/inc/unixasmmacrosx86.inc b/src/pal/inc/unixasmmacrosx86.inc
new file mode 100644
index 0000000000..77b3a63484
--- /dev/null
+++ b/src/pal/inc/unixasmmacrosx86.inc
@@ -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.
+
+.macro NESTED_ENTRY Name, Section, Handler
+ LEAF_ENTRY \Name, \Section
+ .ifnc \Handler, NoHandler
+ .cfi_personality 0x1b, C_FUNC(\Handler) // 0x1b == DW_EH_PE_pcrel | DW_EH_PE_sdata4
+ .endif
+.endm
+
+.macro NESTED_END Name, Section
+ LEAF_END \Name, \Section
+.endm
+
+.macro LEAF_ENTRY Name, Section
+ .global C_FUNC(\Name)
+ .type \Name, %function
+C_FUNC(\Name):
+ .cfi_startproc
+.endm
+
+.macro PATCH_LABEL Name
+ .global C_FUNC(\Name)
+C_FUNC(\Name):
+.endm
+
+.macro LEAF_END Name, Section
+ .size \Name, .-\Name
+ .cfi_endproc
+.endm
+
+.macro LEAF_END_MARKED Name, Section
+C_FUNC(\Name\()_End):
+ .global C_FUNC(\Name\()_End)
+ LEAF_END \Name, \Section
+.endm
+
+.macro PROLOG_BEG
+ push ebp
+ .cfi_def_cfa_offset 8
+ .cfi_offset ebp, -8
+ mov ebp, esp
+.endm
+
+.macro PROLOG_PUSH Reg
+ push \Reg
+ .cfi_adjust_cfa_offset 4
+ .cfi_rel_offset \Reg, 0
+.endm
+
+.macro PROLOG_END
+ .cfi_def_cfa_register ebp
+ .cfi_def_cfa_offset 8
+.endm
+
+.macro EPILOG_BEG
+.endm
+
+.macro EPILOG_POP Reg
+ pop \Reg
+ .cfi_restore \Reg
+.endm
+
+.macro EPILOG_END
+ pop ebp
+.endm
+
+.macro PREPARE_EXTERNAL_VAR Name, Reg
+.att_syntax
+ call 0f
+0:
+ popl %\Reg
+1:
+ addl $_GLOBAL_OFFSET_TABLE_ + (1b - 0b), %\Reg
+ movl C_FUNC(\Name)@GOT(%\Reg), %\Reg
+.intel_syntax noprefix
+.endm
+
+.macro CHECK_STACK_ALIGNMENT
+#ifdef _DEBUG
+ test esp, 0Fh
+ je 0f
+ int3
+0:
+#endif // _DEBUG
+.endm
diff --git a/src/pal/prebuilt/idl/clrdata_i.c b/src/pal/prebuilt/idl/clrdata_i.cpp
index bb9616a9f8..bb9616a9f8 100644
--- a/src/pal/prebuilt/idl/clrdata_i.c
+++ b/src/pal/prebuilt/idl/clrdata_i.cpp
diff --git a/src/pal/prebuilt/idl/clrinternal_i.c b/src/pal/prebuilt/idl/clrinternal_i.cpp
index 58a16672cf..58a16672cf 100644
--- a/src/pal/prebuilt/idl/clrinternal_i.c
+++ b/src/pal/prebuilt/idl/clrinternal_i.cpp
diff --git a/src/pal/prebuilt/idl/clrprivappxhosting_i.c b/src/pal/prebuilt/idl/clrprivappxhosting_i.cpp
index c46d033d1a..c46d033d1a 100644
--- a/src/pal/prebuilt/idl/clrprivappxhosting_i.c
+++ b/src/pal/prebuilt/idl/clrprivappxhosting_i.cpp
diff --git a/src/pal/prebuilt/idl/clrprivbinding_i.c b/src/pal/prebuilt/idl/clrprivbinding_i.cpp
index ee08cc3583..ee08cc3583 100644
--- a/src/pal/prebuilt/idl/clrprivbinding_i.c
+++ b/src/pal/prebuilt/idl/clrprivbinding_i.cpp
diff --git a/src/pal/prebuilt/idl/clrprivhosting_i.c b/src/pal/prebuilt/idl/clrprivhosting_i.cpp
index 07a40b290e..07a40b290e 100644
--- a/src/pal/prebuilt/idl/clrprivhosting_i.c
+++ b/src/pal/prebuilt/idl/clrprivhosting_i.cpp
diff --git a/src/pal/prebuilt/idl/clrprivruntimebinders_i.c b/src/pal/prebuilt/idl/clrprivruntimebinders_i.cpp
index 0fe4a180df..0fe4a180df 100644
--- a/src/pal/prebuilt/idl/clrprivruntimebinders_i.c
+++ b/src/pal/prebuilt/idl/clrprivruntimebinders_i.cpp
diff --git a/src/pal/prebuilt/idl/cordebug_i.c b/src/pal/prebuilt/idl/cordebug_i.c
deleted file mode 100644
index e3c8d2edcb..0000000000
--- a/src/pal/prebuilt/idl/cordebug_i.c
+++ /dev/null
@@ -1,451 +0,0 @@
-
-
-/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */
-
-/* link this file in with the server and any clients */
-
-
- /* File created by MIDL compiler version 8.00.0613 */
-/* at Mon Jan 18 19:14:07 2038
- */
-/* Compiler settings for C:/ssd/coreclr/src/inc/cordebug.idl:
- Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.00.0613
- 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 */
-
-
-#ifdef __cplusplus
-extern "C"{
-#endif
-
-
-#include <rpc.h>
-#include <rpcndr.h>
-
-#ifdef _MIDL_USE_GUIDDEF_
-
-#ifndef INITGUID
-#define INITGUID
-#include <guiddef.h>
-#undef INITGUID
-#else
-#include <guiddef.h>
-#endif
-
-#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
- DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8)
-
-#else // !_MIDL_USE_GUIDDEF_
-
-#ifndef __IID_DEFINED__
-#define __IID_DEFINED__
-
-typedef struct _IID
-{
- unsigned long x;
- unsigned short s1;
- unsigned short s2;
- unsigned char c[8];
-} IID;
-
-#endif // __IID_DEFINED__
-
-#ifndef CLSID_DEFINED
-#define CLSID_DEFINED
-typedef IID CLSID;
-#endif // CLSID_DEFINED
-
-#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
- const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
-
-#endif !_MIDL_USE_GUIDDEF_
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugDataTarget,0xFE06DC28,0x49FB,0x4636,0xA4,0xA3,0xE8,0x0D,0xB4,0xAE,0x11,0x6C);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugStaticFieldSymbol,0xCBF9DA63,0xF68D,0x4BBB,0xA2,0x1C,0x15,0xA4,0x5E,0xAA,0xDF,0x5B);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugInstanceFieldSymbol,0xA074096B,0x3ADC,0x4485,0x81,0xDA,0x68,0xC7,0xA4,0xEA,0x52,0xDB);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugVariableSymbol,0x707E8932,0x1163,0x48D9,0x8A,0x93,0xF5,0xB1,0xF4,0x80,0xFB,0xB7);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugMemoryBuffer,0x677888B3,0xD160,0x4B8C,0xA7,0x3B,0xD7,0x9E,0x6A,0xAA,0x1D,0x13);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugMergedAssemblyRecord,0xFAA8637B,0x3BBE,0x4671,0x8E,0x26,0x3B,0x59,0x87,0x5B,0x92,0x2A);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugSymbolProvider,0x3948A999,0xFD8A,0x4C38,0xA7,0x08,0x8A,0x71,0xE9,0xB0,0x4D,0xBB);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugSymbolProvider2,0xF9801807,0x4764,0x4330,0x9E,0x67,0x4F,0x68,0x50,0x94,0x16,0x5E);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugVirtualUnwinder,0xF69126B7,0xC787,0x4F6B,0xAE,0x96,0xA5,0x69,0x78,0x6F,0xC6,0x70);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugDataTarget2,0x2eb364da,0x605b,0x4e8d,0xb3,0x33,0x33,0x94,0xc4,0x82,0x8d,0x41);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugLoadedModule,0x817F343A,0x6630,0x4578,0x96,0xC5,0xD1,0x1B,0xC0,0xEC,0x5E,0xE2);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugDataTarget3,0xD05E60C3,0x848C,0x4E7D,0x89,0x4E,0x62,0x33,0x20,0xFF,0x6A,0xFA);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugDataTarget4,0xE799DC06,0xE099,0x4713,0xBD,0xD9,0x90,0x6D,0x3C,0xC0,0x2C,0xF2);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugMutableDataTarget,0xA1B8A756,0x3CB6,0x4CCB,0x97,0x9F,0x3D,0xF9,0x99,0x67,0x3A,0x59);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugMetaDataLocator,0x7cef8ba9,0x2ef7,0x42bf,0x97,0x3f,0x41,0x71,0x47,0x4f,0x87,0xd9);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugManagedCallback,0x3d6f5f60,0x7538,0x11d3,0x8d,0x5b,0x00,0x10,0x4b,0x35,0xe7,0xef);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugManagedCallback3,0x264EA0FC,0x2591,0x49AA,0x86,0x8E,0x83,0x5E,0x65,0x15,0x32,0x3F);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugManagedCallback2,0x250E5EEA,0xDB5C,0x4C76,0xB6,0xF3,0x8C,0x46,0xF1,0x2E,0x32,0x03);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugUnmanagedCallback,0x5263E909,0x8CB5,0x11d3,0xBD,0x2F,0x00,0x00,0xF8,0x08,0x49,0xBD);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebug,0x3d6f5f61,0x7538,0x11d3,0x8d,0x5b,0x00,0x10,0x4b,0x35,0xe7,0xef);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugRemoteTarget,0xC3ED8383,0x5A49,0x4cf5,0xB4,0xB7,0x01,0x86,0x4D,0x9E,0x58,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugRemote,0xD5EBB8E2,0x7BBE,0x4c1d,0x98,0xA6,0xA3,0xC0,0x4C,0xBD,0xEF,0x64);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebug2,0xECCCCF2E,0xB286,0x4b3e,0xA9,0x83,0x86,0x0A,0x87,0x93,0xD1,0x05);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugController,0x3d6f5f62,0x7538,0x11d3,0x8d,0x5b,0x00,0x10,0x4b,0x35,0xe7,0xef);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugAppDomain,0x3d6f5f63,0x7538,0x11d3,0x8d,0x5b,0x00,0x10,0x4b,0x35,0xe7,0xef);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugAppDomain2,0x096E81D5,0xECDA,0x4202,0x83,0xF5,0xC6,0x59,0x80,0xA9,0xEF,0x75);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugEnum,0xCC7BCB01,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugGuidToTypeEnum,0x6164D242,0x1015,0x4BD6,0x8C,0xBE,0xD0,0xDB,0xD4,0xB8,0x27,0x5A);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugAppDomain3,0x8CB96A16,0xB588,0x42E2,0xB7,0x1C,0xDD,0x84,0x9F,0xC2,0xEC,0xCC);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugAppDomain4,0xFB99CC40,0x83BE,0x4724,0xAB,0x3B,0x76,0x8E,0x79,0x6E,0xBA,0xC2);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugAssembly,0xdf59507c,0xd47a,0x459e,0xbc,0xe2,0x64,0x27,0xea,0xc8,0xfd,0x06);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugAssembly2,0x426d1f9e,0x6dd4,0x44c8,0xae,0xc7,0x26,0xcd,0xba,0xf4,0xe3,0x98);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugAssembly3,0x76361AB2,0x8C86,0x4FE9,0x96,0xF2,0xF7,0x3D,0x88,0x43,0x57,0x0A);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugHeapEnum,0x76D7DAB8,0xD044,0x11DF,0x9A,0x15,0x7E,0x29,0xDF,0xD7,0x20,0x85);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugHeapSegmentEnum,0xA2FA0F8E,0xD045,0x11DF,0xAC,0x8E,0xCE,0x2A,0xDF,0xD7,0x20,0x85);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugGCReferenceEnum,0x7F3C24D3,0x7E1D,0x4245,0xAC,0x3A,0xF7,0x2F,0x88,0x59,0xC8,0x0C);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugProcess,0x3d6f5f64,0x7538,0x11d3,0x8d,0x5b,0x00,0x10,0x4b,0x35,0xe7,0xef);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugProcess2,0xAD1B3588,0x0EF0,0x4744,0xA4,0x96,0xAA,0x09,0xA9,0xF8,0x03,0x71);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugProcess3,0x2EE06488,0xC0D4,0x42B1,0xB2,0x6D,0xF3,0x79,0x5E,0xF6,0x06,0xFB);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugProcess5,0x21e9d9c0,0xfcb8,0x11df,0x8c,0xff,0x08,0x00,0x20,0x0c,0x9a,0x66);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugDebugEvent,0x41BD395D,0xDE99,0x48F1,0xBF,0x7A,0xCC,0x0F,0x44,0xA6,0xD2,0x81);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugProcess6,0x11588775,0x7205,0x4CEB,0xA4,0x1A,0x93,0x75,0x3C,0x31,0x53,0xE9);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugProcess7,0x9B2C54E4,0x119F,0x4D6F,0xB4,0x02,0x52,0x76,0x03,0x26,0x6D,0x69);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugProcess8,0x2E6F28C1,0x85EB,0x4141,0x80,0xAD,0x0A,0x90,0x94,0x4B,0x96,0x39);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugModuleDebugEvent,0x51A15E8D,0x9FFF,0x4864,0x9B,0x87,0xF4,0xFB,0xDE,0xA7,0x47,0xA2);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugExceptionDebugEvent,0xAF79EC94,0x4752,0x419C,0xA6,0x26,0x5F,0xB1,0xCC,0x1A,0x5A,0xB7);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugBreakpoint,0xCC7BCAE8,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugFunctionBreakpoint,0xCC7BCAE9,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugModuleBreakpoint,0xCC7BCAEA,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugValueBreakpoint,0xCC7BCAEB,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugStepper,0xCC7BCAEC,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugStepper2,0xC5B6E9C3,0xE7D1,0x4a8e,0x87,0x3B,0x7F,0x04,0x7F,0x07,0x06,0xF7);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugRegisterSet,0xCC7BCB0B,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugRegisterSet2,0x6DC7BA3F,0x89BA,0x4459,0x9E,0xC1,0x9D,0x60,0x93,0x7B,0x46,0x8D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugThread,0x938c6d66,0x7fb6,0x4f69,0xb3,0x89,0x42,0x5b,0x89,0x87,0x32,0x9b);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugThread2,0x2BD956D9,0x7B07,0x4bef,0x8A,0x98,0x12,0xAA,0x86,0x24,0x17,0xC5);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugThread3,0xF8544EC3,0x5E4E,0x46c7,0x8D,0x3E,0xA5,0x2B,0x84,0x05,0xB1,0xF5);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugThread4,0x1A1F204B,0x1C66,0x4637,0x82,0x3F,0x3E,0xE6,0xC7,0x44,0xA6,0x9C);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugStackWalk,0xA0647DE9,0x55DE,0x4816,0x92,0x9C,0x38,0x52,0x71,0xC6,0x4C,0xF7);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugChain,0xCC7BCAEE,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugFrame,0xCC7BCAEF,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugInternalFrame,0xB92CC7F7,0x9D2D,0x45c4,0xBC,0x2B,0x62,0x1F,0xCC,0x9D,0xFB,0xF4);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugInternalFrame2,0xC0815BDC,0xCFAB,0x447e,0xA7,0x79,0xC1,0x16,0xB4,0x54,0xEB,0x5B);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugILFrame,0x03E26311,0x4F76,0x11d3,0x88,0xC6,0x00,0x60,0x97,0x94,0x54,0x18);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugILFrame2,0x5D88A994,0x6C30,0x479b,0x89,0x0F,0xBC,0xEF,0x88,0xB1,0x29,0xA5);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugILFrame3,0x9A9E2ED6,0x04DF,0x4FE0,0xBB,0x50,0xCA,0xB6,0x41,0x26,0xAD,0x24);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugILFrame4,0xAD914A30,0xC6D1,0x4AC5,0x9C,0x5E,0x57,0x7F,0x3B,0xAA,0x8A,0x45);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugNativeFrame,0x03E26314,0x4F76,0x11d3,0x88,0xC6,0x00,0x60,0x97,0x94,0x54,0x18);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugNativeFrame2,0x35389FF1,0x3684,0x4c55,0xA2,0xEE,0x21,0x0F,0x26,0xC6,0x0E,0x5E);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugModule3,0x86F012BF,0xFF15,0x4372,0xBD,0x30,0xB6,0xF1,0x1C,0xAA,0xE1,0xDD);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugRuntimeUnwindableFrame,0x879CAC0A,0x4A53,0x4668,0xB8,0xE3,0xCB,0x84,0x73,0xCB,0x18,0x7F);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugModule,0xdba2d8c1,0xe5c5,0x4069,0x8c,0x13,0x10,0xa7,0xc6,0xab,0xf4,0x3d);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugModule2,0x7FCC5FB5,0x49C0,0x41de,0x99,0x38,0x3B,0x88,0xB5,0xB9,0xAD,0xD7);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugFunction,0xCC7BCAF3,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugFunction2,0xEF0C490B,0x94C3,0x4e4d,0xB6,0x29,0xDD,0xC1,0x34,0xC5,0x32,0xD8);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugFunction3,0x09B70F28,0xE465,0x482D,0x99,0xE0,0x81,0xA1,0x65,0xEB,0x05,0x32);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugCode,0xCC7BCAF4,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugCode2,0x5F696509,0x452F,0x4436,0xA3,0xFE,0x4D,0x11,0xFE,0x7E,0x23,0x47);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugCode3,0xD13D3E88,0xE1F2,0x4020,0xAA,0x1D,0x3D,0x16,0x2D,0xCB,0xE9,0x66);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugILCode,0x598D46C2,0xC877,0x42A7,0x89,0xD2,0x3D,0x0C,0x7F,0x1C,0x12,0x64);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugILCode2,0x46586093,0xD3F5,0x4DB6,0xAC,0xDB,0x95,0x5B,0xCE,0x22,0x8C,0x15);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugClass,0xCC7BCAF5,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugClass2,0xB008EA8D,0x7AB1,0x43f7,0xBB,0x20,0xFB,0xB5,0xA0,0x40,0x38,0xAE);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugEval,0xCC7BCAF6,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugEval2,0xFB0D9CE7,0xBE66,0x4683,0x9D,0x32,0xA4,0x2A,0x04,0xE2,0xFD,0x91);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugValue,0xCC7BCAF7,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugValue2,0x5E0B54E7,0xD88A,0x4626,0x94,0x20,0xA6,0x91,0xE0,0xA7,0x8B,0x49);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugValue3,0x565005FC,0x0F8A,0x4F3E,0x9E,0xDB,0x83,0x10,0x2B,0x15,0x65,0x95);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugGenericValue,0xCC7BCAF8,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugReferenceValue,0xCC7BCAF9,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugHeapValue,0xCC7BCAFA,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugHeapValue2,0xE3AC4D6C,0x9CB7,0x43e6,0x96,0xCC,0xB2,0x15,0x40,0xE5,0x08,0x3C);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugHeapValue3,0xA69ACAD8,0x2374,0x46e9,0x9F,0xF8,0xB1,0xF1,0x41,0x20,0xD2,0x96);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugObjectValue,0x18AD3D6E,0xB7D2,0x11d2,0xBD,0x04,0x00,0x00,0xF8,0x08,0x49,0xBD);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugObjectValue2,0x49E4A320,0x4A9B,0x4eca,0xB1,0x05,0x22,0x9F,0xB7,0xD5,0x00,0x9F);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugBoxValue,0xCC7BCAFC,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugStringValue,0xCC7BCAFD,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugArrayValue,0x0405B0DF,0xA660,0x11d2,0xBD,0x02,0x00,0x00,0xF8,0x08,0x49,0xBD);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugHandleValue,0x029596E8,0x276B,0x46a1,0x98,0x21,0x73,0x2E,0x96,0xBB,0xB0,0x0B);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugContext,0xCC7BCB00,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugComObjectValue,0x5F69C5E5,0x3E12,0x42DF,0xB3,0x71,0xF9,0xD7,0x61,0xD6,0xEE,0x24);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugObjectEnum,0xCC7BCB02,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugBreakpointEnum,0xCC7BCB03,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugStepperEnum,0xCC7BCB04,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugProcessEnum,0xCC7BCB05,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugThreadEnum,0xCC7BCB06,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugFrameEnum,0xCC7BCB07,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugChainEnum,0xCC7BCB08,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugModuleEnum,0xCC7BCB09,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugValueEnum,0xCC7BCB0A,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugCodeEnum,0x55E96461,0x9645,0x45e4,0xA2,0xFF,0x03,0x67,0x87,0x7A,0xBC,0xDE);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugTypeEnum,0x10F27499,0x9DF2,0x43ce,0x83,0x33,0xA3,0x21,0xD7,0xC9,0x9C,0xB4);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugType,0xD613F0BB,0xACE1,0x4c19,0xBD,0x72,0xE4,0xC0,0x8D,0x5D,0xA7,0xF5);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugErrorInfoEnum,0xF0E18809,0x72B5,0x11d2,0x97,0x6F,0x00,0xA0,0xC9,0xB4,0xD5,0x0C);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugAppDomainEnum,0x63ca1b24,0x4359,0x4883,0xbd,0x57,0x13,0xf8,0x15,0xf5,0x87,0x44);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugAssemblyEnum,0x4a2a1ec9,0x85ec,0x4bfb,0x9f,0x15,0xa8,0x9f,0xdf,0xe0,0xfe,0x83);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugBlockingObjectEnum,0x976A6278,0x134A,0x4a81,0x81,0xA3,0x8F,0x27,0x79,0x43,0xF4,0xC3);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugMDA,0xCC726F2F,0x1DB7,0x459b,0xB0,0xEC,0x05,0xF0,0x1D,0x84,0x1B,0x42);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugEditAndContinueErrorInfo,0x8D600D41,0xF4F6,0x4cb3,0xB7,0xEC,0x7B,0xD1,0x64,0x94,0x40,0x36);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugEditAndContinueSnapshot,0x6DC3FA01,0xD7CB,0x11d2,0x8A,0x95,0x00,0x80,0xC7,0x92,0xE5,0xD8);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugExceptionObjectCallStackEnum,0xED775530,0x4DC4,0x41F7,0x86,0xD0,0x9E,0x2D,0xEF,0x7D,0xFC,0x66);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorDebugExceptionObjectValue,0xAE4CA65D,0x59DD,0x42A2,0x83,0xA5,0x57,0xE8,0xA0,0x8D,0x87,0x19);
-
-
-MIDL_DEFINE_GUID(IID, LIBID_CORDBLib,0x53D13620,0xF417,0x11d1,0x97,0x62,0xA6,0x38,0x26,0xA4,0xF2,0x55);
-
-
-MIDL_DEFINE_GUID(CLSID, CLSID_CorDebug,0x6fef44d0,0x39e7,0x4c77,0xbe,0x8e,0xc9,0xf8,0xcf,0x98,0x86,0x30);
-
-
-MIDL_DEFINE_GUID(CLSID, CLSID_EmbeddedCLRCorDebug,0x211f1254,0xbc7e,0x4af5,0xb9,0xaa,0x06,0x73,0x08,0xd8,0x3d,0xd1);
-
-#undef MIDL_DEFINE_GUID
-
-#ifdef __cplusplus
-}
-#endif
-
-
-
diff --git a/src/pal/prebuilt/idl/cordebug_i.cpp b/src/pal/prebuilt/idl/cordebug_i.cpp
new file mode 100644
index 0000000000..dd69e57086
--- /dev/null
+++ b/src/pal/prebuilt/idl/cordebug_i.cpp
@@ -0,0 +1,463 @@
+
+
+/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */
+
+/* link this file in with the server and any clients */
+
+
+ /* File created by MIDL compiler version 8.00.0603 */
+/* at Fri Sep 23 15:43:16 2016
+ */
+/* Compiler settings for cordebug.idl:
+ Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.00.0603
+ 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 */
+
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+
+#include <rpc.h>
+#include <rpcndr.h>
+
+#ifdef _MIDL_USE_GUIDDEF_
+
+#ifndef INITGUID
+#define INITGUID
+#include <guiddef.h>
+#undef INITGUID
+#else
+#include <guiddef.h>
+#endif
+
+#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
+ DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8)
+
+#else // !_MIDL_USE_GUIDDEF_
+
+#ifndef __IID_DEFINED__
+#define __IID_DEFINED__
+
+typedef struct _IID
+{
+ unsigned long x;
+ unsigned short s1;
+ unsigned short s2;
+ unsigned char c[8];
+} IID;
+
+#endif // __IID_DEFINED__
+
+#ifndef CLSID_DEFINED
+#define CLSID_DEFINED
+typedef IID CLSID;
+#endif // CLSID_DEFINED
+
+#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
+ const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
+
+#endif !_MIDL_USE_GUIDDEF_
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugDataTarget,0xFE06DC28,0x49FB,0x4636,0xA4,0xA3,0xE8,0x0D,0xB4,0xAE,0x11,0x6C);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugStaticFieldSymbol,0xCBF9DA63,0xF68D,0x4BBB,0xA2,0x1C,0x15,0xA4,0x5E,0xAA,0xDF,0x5B);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugInstanceFieldSymbol,0xA074096B,0x3ADC,0x4485,0x81,0xDA,0x68,0xC7,0xA4,0xEA,0x52,0xDB);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugVariableSymbol,0x707E8932,0x1163,0x48D9,0x8A,0x93,0xF5,0xB1,0xF4,0x80,0xFB,0xB7);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugMemoryBuffer,0x677888B3,0xD160,0x4B8C,0xA7,0x3B,0xD7,0x9E,0x6A,0xAA,0x1D,0x13);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugMergedAssemblyRecord,0xFAA8637B,0x3BBE,0x4671,0x8E,0x26,0x3B,0x59,0x87,0x5B,0x92,0x2A);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugSymbolProvider,0x3948A999,0xFD8A,0x4C38,0xA7,0x08,0x8A,0x71,0xE9,0xB0,0x4D,0xBB);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugSymbolProvider2,0xF9801807,0x4764,0x4330,0x9E,0x67,0x4F,0x68,0x50,0x94,0x16,0x5E);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugVirtualUnwinder,0xF69126B7,0xC787,0x4F6B,0xAE,0x96,0xA5,0x69,0x78,0x6F,0xC6,0x70);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugDataTarget2,0x2eb364da,0x605b,0x4e8d,0xb3,0x33,0x33,0x94,0xc4,0x82,0x8d,0x41);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugLoadedModule,0x817F343A,0x6630,0x4578,0x96,0xC5,0xD1,0x1B,0xC0,0xEC,0x5E,0xE2);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugDataTarget3,0xD05E60C3,0x848C,0x4E7D,0x89,0x4E,0x62,0x33,0x20,0xFF,0x6A,0xFA);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugDataTarget4,0xE799DC06,0xE099,0x4713,0xBD,0xD9,0x90,0x6D,0x3C,0xC0,0x2C,0xF2);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugMutableDataTarget,0xA1B8A756,0x3CB6,0x4CCB,0x97,0x9F,0x3D,0xF9,0x99,0x67,0x3A,0x59);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugMetaDataLocator,0x7cef8ba9,0x2ef7,0x42bf,0x97,0x3f,0x41,0x71,0x47,0x4f,0x87,0xd9);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugManagedCallback,0x3d6f5f60,0x7538,0x11d3,0x8d,0x5b,0x00,0x10,0x4b,0x35,0xe7,0xef);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugManagedCallback3,0x264EA0FC,0x2591,0x49AA,0x86,0x8E,0x83,0x5E,0x65,0x15,0x32,0x3F);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugManagedCallback2,0x250E5EEA,0xDB5C,0x4C76,0xB6,0xF3,0x8C,0x46,0xF1,0x2E,0x32,0x03);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugUnmanagedCallback,0x5263E909,0x8CB5,0x11d3,0xBD,0x2F,0x00,0x00,0xF8,0x08,0x49,0xBD);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebug,0x3d6f5f61,0x7538,0x11d3,0x8d,0x5b,0x00,0x10,0x4b,0x35,0xe7,0xef);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugRemoteTarget,0xC3ED8383,0x5A49,0x4cf5,0xB4,0xB7,0x01,0x86,0x4D,0x9E,0x58,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugRemote,0xD5EBB8E2,0x7BBE,0x4c1d,0x98,0xA6,0xA3,0xC0,0x4C,0xBD,0xEF,0x64);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebug2,0xECCCCF2E,0xB286,0x4b3e,0xA9,0x83,0x86,0x0A,0x87,0x93,0xD1,0x05);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugController,0x3d6f5f62,0x7538,0x11d3,0x8d,0x5b,0x00,0x10,0x4b,0x35,0xe7,0xef);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugAppDomain,0x3d6f5f63,0x7538,0x11d3,0x8d,0x5b,0x00,0x10,0x4b,0x35,0xe7,0xef);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugAppDomain2,0x096E81D5,0xECDA,0x4202,0x83,0xF5,0xC6,0x59,0x80,0xA9,0xEF,0x75);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugEnum,0xCC7BCB01,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugGuidToTypeEnum,0x6164D242,0x1015,0x4BD6,0x8C,0xBE,0xD0,0xDB,0xD4,0xB8,0x27,0x5A);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugAppDomain3,0x8CB96A16,0xB588,0x42E2,0xB7,0x1C,0xDD,0x84,0x9F,0xC2,0xEC,0xCC);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugAppDomain4,0xFB99CC40,0x83BE,0x4724,0xAB,0x3B,0x76,0x8E,0x79,0x6E,0xBA,0xC2);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugAssembly,0xdf59507c,0xd47a,0x459e,0xbc,0xe2,0x64,0x27,0xea,0xc8,0xfd,0x06);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugAssembly2,0x426d1f9e,0x6dd4,0x44c8,0xae,0xc7,0x26,0xcd,0xba,0xf4,0xe3,0x98);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugAssembly3,0x76361AB2,0x8C86,0x4FE9,0x96,0xF2,0xF7,0x3D,0x88,0x43,0x57,0x0A);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugHeapEnum,0x76D7DAB8,0xD044,0x11DF,0x9A,0x15,0x7E,0x29,0xDF,0xD7,0x20,0x85);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugHeapSegmentEnum,0xA2FA0F8E,0xD045,0x11DF,0xAC,0x8E,0xCE,0x2A,0xDF,0xD7,0x20,0x85);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugGCReferenceEnum,0x7F3C24D3,0x7E1D,0x4245,0xAC,0x3A,0xF7,0x2F,0x88,0x59,0xC8,0x0C);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugProcess,0x3d6f5f64,0x7538,0x11d3,0x8d,0x5b,0x00,0x10,0x4b,0x35,0xe7,0xef);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugProcess2,0xAD1B3588,0x0EF0,0x4744,0xA4,0x96,0xAA,0x09,0xA9,0xF8,0x03,0x71);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugProcess3,0x2EE06488,0xC0D4,0x42B1,0xB2,0x6D,0xF3,0x79,0x5E,0xF6,0x06,0xFB);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugProcess5,0x21e9d9c0,0xfcb8,0x11df,0x8c,0xff,0x08,0x00,0x20,0x0c,0x9a,0x66);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugDebugEvent,0x41BD395D,0xDE99,0x48F1,0xBF,0x7A,0xCC,0x0F,0x44,0xA6,0xD2,0x81);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugProcess6,0x11588775,0x7205,0x4CEB,0xA4,0x1A,0x93,0x75,0x3C,0x31,0x53,0xE9);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugProcess7,0x9B2C54E4,0x119F,0x4D6F,0xB4,0x02,0x52,0x76,0x03,0x26,0x6D,0x69);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugProcess8,0x2E6F28C1,0x85EB,0x4141,0x80,0xAD,0x0A,0x90,0x94,0x4B,0x96,0x39);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugModuleDebugEvent,0x51A15E8D,0x9FFF,0x4864,0x9B,0x87,0xF4,0xFB,0xDE,0xA7,0x47,0xA2);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugExceptionDebugEvent,0xAF79EC94,0x4752,0x419C,0xA6,0x26,0x5F,0xB1,0xCC,0x1A,0x5A,0xB7);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugBreakpoint,0xCC7BCAE8,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugFunctionBreakpoint,0xCC7BCAE9,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugModuleBreakpoint,0xCC7BCAEA,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugValueBreakpoint,0xCC7BCAEB,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugStepper,0xCC7BCAEC,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugStepper2,0xC5B6E9C3,0xE7D1,0x4a8e,0x87,0x3B,0x7F,0x04,0x7F,0x07,0x06,0xF7);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugRegisterSet,0xCC7BCB0B,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugRegisterSet2,0x6DC7BA3F,0x89BA,0x4459,0x9E,0xC1,0x9D,0x60,0x93,0x7B,0x46,0x8D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugThread,0x938c6d66,0x7fb6,0x4f69,0xb3,0x89,0x42,0x5b,0x89,0x87,0x32,0x9b);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugThread2,0x2BD956D9,0x7B07,0x4bef,0x8A,0x98,0x12,0xAA,0x86,0x24,0x17,0xC5);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugThread3,0xF8544EC3,0x5E4E,0x46c7,0x8D,0x3E,0xA5,0x2B,0x84,0x05,0xB1,0xF5);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugThread4,0x1A1F204B,0x1C66,0x4637,0x82,0x3F,0x3E,0xE6,0xC7,0x44,0xA6,0x9C);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugStackWalk,0xA0647DE9,0x55DE,0x4816,0x92,0x9C,0x38,0x52,0x71,0xC6,0x4C,0xF7);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugChain,0xCC7BCAEE,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugFrame,0xCC7BCAEF,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugInternalFrame,0xB92CC7F7,0x9D2D,0x45c4,0xBC,0x2B,0x62,0x1F,0xCC,0x9D,0xFB,0xF4);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugInternalFrame2,0xC0815BDC,0xCFAB,0x447e,0xA7,0x79,0xC1,0x16,0xB4,0x54,0xEB,0x5B);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugILFrame,0x03E26311,0x4F76,0x11d3,0x88,0xC6,0x00,0x60,0x97,0x94,0x54,0x18);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugILFrame2,0x5D88A994,0x6C30,0x479b,0x89,0x0F,0xBC,0xEF,0x88,0xB1,0x29,0xA5);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugILFrame3,0x9A9E2ED6,0x04DF,0x4FE0,0xBB,0x50,0xCA,0xB6,0x41,0x26,0xAD,0x24);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugILFrame4,0xAD914A30,0xC6D1,0x4AC5,0x9C,0x5E,0x57,0x7F,0x3B,0xAA,0x8A,0x45);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugNativeFrame,0x03E26314,0x4F76,0x11d3,0x88,0xC6,0x00,0x60,0x97,0x94,0x54,0x18);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugNativeFrame2,0x35389FF1,0x3684,0x4c55,0xA2,0xEE,0x21,0x0F,0x26,0xC6,0x0E,0x5E);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugModule3,0x86F012BF,0xFF15,0x4372,0xBD,0x30,0xB6,0xF1,0x1C,0xAA,0xE1,0xDD);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugRuntimeUnwindableFrame,0x879CAC0A,0x4A53,0x4668,0xB8,0xE3,0xCB,0x84,0x73,0xCB,0x18,0x7F);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugModule,0xdba2d8c1,0xe5c5,0x4069,0x8c,0x13,0x10,0xa7,0xc6,0xab,0xf4,0x3d);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugModule2,0x7FCC5FB5,0x49C0,0x41de,0x99,0x38,0x3B,0x88,0xB5,0xB9,0xAD,0xD7);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugFunction,0xCC7BCAF3,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugFunction2,0xEF0C490B,0x94C3,0x4e4d,0xB6,0x29,0xDD,0xC1,0x34,0xC5,0x32,0xD8);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugFunction3,0x09B70F28,0xE465,0x482D,0x99,0xE0,0x81,0xA1,0x65,0xEB,0x05,0x32);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugCode,0xCC7BCAF4,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugCode2,0x5F696509,0x452F,0x4436,0xA3,0xFE,0x4D,0x11,0xFE,0x7E,0x23,0x47);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugCode3,0xD13D3E88,0xE1F2,0x4020,0xAA,0x1D,0x3D,0x16,0x2D,0xCB,0xE9,0x66);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugCode4,0x18221fa4,0x20cb,0x40fa,0xb1,0x9d,0x9f,0x91,0xc4,0xfa,0x8c,0x14);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugILCode,0x598D46C2,0xC877,0x42A7,0x89,0xD2,0x3D,0x0C,0x7F,0x1C,0x12,0x64);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugILCode2,0x46586093,0xD3F5,0x4DB6,0xAC,0xDB,0x95,0x5B,0xCE,0x22,0x8C,0x15);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugClass,0xCC7BCAF5,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugClass2,0xB008EA8D,0x7AB1,0x43f7,0xBB,0x20,0xFB,0xB5,0xA0,0x40,0x38,0xAE);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugEval,0xCC7BCAF6,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugEval2,0xFB0D9CE7,0xBE66,0x4683,0x9D,0x32,0xA4,0x2A,0x04,0xE2,0xFD,0x91);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugValue,0xCC7BCAF7,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugValue2,0x5E0B54E7,0xD88A,0x4626,0x94,0x20,0xA6,0x91,0xE0,0xA7,0x8B,0x49);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugValue3,0x565005FC,0x0F8A,0x4F3E,0x9E,0xDB,0x83,0x10,0x2B,0x15,0x65,0x95);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugGenericValue,0xCC7BCAF8,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugReferenceValue,0xCC7BCAF9,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugHeapValue,0xCC7BCAFA,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugHeapValue2,0xE3AC4D6C,0x9CB7,0x43e6,0x96,0xCC,0xB2,0x15,0x40,0xE5,0x08,0x3C);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugHeapValue3,0xA69ACAD8,0x2374,0x46e9,0x9F,0xF8,0xB1,0xF1,0x41,0x20,0xD2,0x96);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugObjectValue,0x18AD3D6E,0xB7D2,0x11d2,0xBD,0x04,0x00,0x00,0xF8,0x08,0x49,0xBD);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugObjectValue2,0x49E4A320,0x4A9B,0x4eca,0xB1,0x05,0x22,0x9F,0xB7,0xD5,0x00,0x9F);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugBoxValue,0xCC7BCAFC,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugStringValue,0xCC7BCAFD,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugArrayValue,0x0405B0DF,0xA660,0x11d2,0xBD,0x02,0x00,0x00,0xF8,0x08,0x49,0xBD);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugVariableHome,0x50847b8d,0xf43f,0x41b0,0x92,0x4c,0x63,0x83,0xa5,0xf2,0x27,0x8b);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugHandleValue,0x029596E8,0x276B,0x46a1,0x98,0x21,0x73,0x2E,0x96,0xBB,0xB0,0x0B);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugContext,0xCC7BCB00,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugComObjectValue,0x5F69C5E5,0x3E12,0x42DF,0xB3,0x71,0xF9,0xD7,0x61,0xD6,0xEE,0x24);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugObjectEnum,0xCC7BCB02,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugBreakpointEnum,0xCC7BCB03,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugStepperEnum,0xCC7BCB04,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugProcessEnum,0xCC7BCB05,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugThreadEnum,0xCC7BCB06,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugFrameEnum,0xCC7BCB07,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugChainEnum,0xCC7BCB08,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugModuleEnum,0xCC7BCB09,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugValueEnum,0xCC7BCB0A,0x8A68,0x11d2,0x98,0x3C,0x00,0x00,0xF8,0x08,0x34,0x2D);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugVariableHomeEnum,0xe76b7a57,0x4f7a,0x4309,0x85,0xa7,0x5d,0x91,0x8c,0x3d,0xea,0xf7);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugCodeEnum,0x55E96461,0x9645,0x45e4,0xA2,0xFF,0x03,0x67,0x87,0x7A,0xBC,0xDE);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugTypeEnum,0x10F27499,0x9DF2,0x43ce,0x83,0x33,0xA3,0x21,0xD7,0xC9,0x9C,0xB4);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugType,0xD613F0BB,0xACE1,0x4c19,0xBD,0x72,0xE4,0xC0,0x8D,0x5D,0xA7,0xF5);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugType2,0xe6e91d79,0x693d,0x48bc,0xb4,0x17,0x82,0x84,0xb4,0xf1,0x0f,0xb5);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugErrorInfoEnum,0xF0E18809,0x72B5,0x11d2,0x97,0x6F,0x00,0xA0,0xC9,0xB4,0xD5,0x0C);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugAppDomainEnum,0x63ca1b24,0x4359,0x4883,0xbd,0x57,0x13,0xf8,0x15,0xf5,0x87,0x44);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugAssemblyEnum,0x4a2a1ec9,0x85ec,0x4bfb,0x9f,0x15,0xa8,0x9f,0xdf,0xe0,0xfe,0x83);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugBlockingObjectEnum,0x976A6278,0x134A,0x4a81,0x81,0xA3,0x8F,0x27,0x79,0x43,0xF4,0xC3);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugMDA,0xCC726F2F,0x1DB7,0x459b,0xB0,0xEC,0x05,0xF0,0x1D,0x84,0x1B,0x42);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugEditAndContinueErrorInfo,0x8D600D41,0xF4F6,0x4cb3,0xB7,0xEC,0x7B,0xD1,0x64,0x94,0x40,0x36);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugEditAndContinueSnapshot,0x6DC3FA01,0xD7CB,0x11d2,0x8A,0x95,0x00,0x80,0xC7,0x92,0xE5,0xD8);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugExceptionObjectCallStackEnum,0xED775530,0x4DC4,0x41F7,0x86,0xD0,0x9E,0x2D,0xEF,0x7D,0xFC,0x66);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorDebugExceptionObjectValue,0xAE4CA65D,0x59DD,0x42A2,0x83,0xA5,0x57,0xE8,0xA0,0x8D,0x87,0x19);
+
+
+MIDL_DEFINE_GUID(IID, LIBID_CORDBLib,0x53D13620,0xF417,0x11d1,0x97,0x62,0xA6,0x38,0x26,0xA4,0xF2,0x55);
+
+
+MIDL_DEFINE_GUID(CLSID, CLSID_CorDebug,0x6fef44d0,0x39e7,0x4c77,0xbe,0x8e,0xc9,0xf8,0xcf,0x98,0x86,0x30);
+
+
+MIDL_DEFINE_GUID(CLSID, CLSID_EmbeddedCLRCorDebug,0x211f1254,0xbc7e,0x4af5,0xb9,0xaa,0x06,0x73,0x08,0xd8,0x3d,0xd1);
+
+#undef MIDL_DEFINE_GUID
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
diff --git a/src/pal/prebuilt/idl/corprof_i.c b/src/pal/prebuilt/idl/corprof_i.c
deleted file mode 100644
index 4686c76d54..0000000000
--- a/src/pal/prebuilt/idl/corprof_i.c
+++ /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.
-
-/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */
-
-/* link this file in with the server and any clients */
-
-
- /* File created by MIDL compiler version 8.00.0603 */
-/* @@MIDL_FILE_HEADING( ) */
-
-#pragma warning( disable: 4049 ) /* more than 64k source lines */
-
-
-#ifdef __cplusplus
-extern "C"{
-#endif
-
-
-#include <rpc.h>
-#include <rpcndr.h>
-
-#ifdef _MIDL_USE_GUIDDEF_
-
-#ifndef INITGUID
-#define INITGUID
-#include <guiddef.h>
-#undef INITGUID
-#else
-#include <guiddef.h>
-#endif
-
-#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
- DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8)
-
-#else // !_MIDL_USE_GUIDDEF_
-
-#ifndef __IID_DEFINED__
-#define __IID_DEFINED__
-
-typedef struct _IID
-{
- unsigned long x;
- unsigned short s1;
- unsigned short s2;
- unsigned char c[8];
-} IID;
-
-#endif // __IID_DEFINED__
-
-#ifndef CLSID_DEFINED
-#define CLSID_DEFINED
-typedef IID CLSID;
-#endif // CLSID_DEFINED
-
-#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
- const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
-
-#endif !_MIDL_USE_GUIDDEF_
-
-MIDL_DEFINE_GUID(IID, IID_ICorProfilerCallback,0x176FBED1,0xA55C,0x4796,0x98,0xCA,0xA9,0xDA,0x0E,0xF8,0x83,0xE7);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorProfilerCallback2,0x8A8CC829,0xCCF2,0x49fe,0xBB,0xAE,0x0F,0x02,0x22,0x28,0x07,0x1A);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorProfilerCallback3,0x4FD2ED52,0x7731,0x4b8d,0x94,0x69,0x03,0xD2,0xCC,0x30,0x86,0xC5);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorProfilerCallback4,0x7B63B2E3,0x107D,0x4d48,0xB2,0xF6,0xF6,0x1E,0x22,0x94,0x70,0xD2);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorProfilerCallback5,0x8DFBA405,0x8C9F,0x45F8,0xBF,0xFA,0x83,0xB1,0x4C,0xEF,0x78,0xB5);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorProfilerCallback6,0xFC13DF4B,0x4448,0x4F4F,0x95,0x0C,0xBA,0x8D,0x19,0xD0,0x0C,0x36);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorProfilerCallback7,0xF76A2DBA,0x1D52,0x4539,0x86,0x6C,0x2A,0xA5,0x18,0xF9,0xEF,0xC3);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorProfilerInfo,0x28B5557D,0x3F3F,0x48b4,0x90,0xB2,0x5F,0x9E,0xEA,0x2F,0x6C,0x48);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorProfilerInfo2,0xCC0935CD,0xA518,0x487d,0xB0,0xBB,0xA9,0x32,0x14,0xE6,0x54,0x78);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorProfilerInfo3,0xB555ED4F,0x452A,0x4E54,0x8B,0x39,0xB5,0x36,0x0B,0xAD,0x32,0xA0);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorProfilerObjectEnum,0x2C6269BD,0x2D13,0x4321,0xAE,0x12,0x66,0x86,0x36,0x5F,0xD6,0xAF);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorProfilerFunctionEnum,0xFF71301A,0xB994,0x429D,0xA1,0x0B,0xB3,0x45,0xA6,0x52,0x80,0xEF);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorProfilerModuleEnum,0xb0266d75,0x2081,0x4493,0xaf,0x7f,0x02,0x8b,0xa3,0x4d,0xb8,0x91);
-
-
-MIDL_DEFINE_GUID(IID, IID_IMethodMalloc,0xA0EFB28B,0x6EE2,0x4d7b,0xB9,0x83,0xA7,0x5E,0xF7,0xBE,0xED,0xB8);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorProfilerFunctionControl,0xF0963021,0xE1EA,0x4732,0x85,0x81,0xE0,0x1B,0x0B,0xD3,0xC0,0xC6);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorProfilerInfo4,0x0d8fdcaa,0x6257,0x47bf,0xb1,0xbf,0x94,0xda,0xc8,0x84,0x66,0xee);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorProfilerInfo5,0x07602928,0xCE38,0x4B83,0x81,0xE7,0x74,0xAD,0xAF,0x78,0x12,0x14);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorProfilerInfo6,0xF30A070D,0xBFFB,0x46A7,0xB1,0xD8,0x87,0x81,0xEF,0x7B,0x69,0x8A);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorProfilerInfo7,0x9AEECC0D,0x63E0,0x4187,0x8C,0x00,0xE3,0x12,0xF5,0x03,0xF6,0x63);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorProfilerMethodEnum,0xFCCEE788,0x0088,0x454B,0xA8,0x11,0xC9,0x9F,0x29,0x8D,0x19,0x42);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorProfilerThreadEnum,0x571194f7,0x25ed,0x419f,0xaa,0x8b,0x70,0x16,0xb3,0x15,0x97,0x01);
-
-
-MIDL_DEFINE_GUID(IID, IID_ICorProfilerAssemblyReferenceProvider,0x66A78C24,0x2EEF,0x4F65,0xB4,0x5F,0xDD,0x1D,0x80,0x38,0xBF,0x3C);
-
-#undef MIDL_DEFINE_GUID
-
-#ifdef __cplusplus
-}
-#endif
-
-
-
diff --git a/src/pal/prebuilt/idl/corprof_i.cpp b/src/pal/prebuilt/idl/corprof_i.cpp
new file mode 100644
index 0000000000..3758da041c
--- /dev/null
+++ b/src/pal/prebuilt/idl/corprof_i.cpp
@@ -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.
+
+/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */
+
+/* link this file in with the server and any clients */
+
+
+ /* File created by MIDL compiler version 8.00.0603 */
+/* @@MIDL_FILE_HEADING( ) */
+
+#pragma warning( disable: 4049 ) /* more than 64k source lines */
+
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+
+#include <rpc.h>
+#include <rpcndr.h>
+
+#ifdef _MIDL_USE_GUIDDEF_
+
+#ifndef INITGUID
+#define INITGUID
+#include <guiddef.h>
+#undef INITGUID
+#else
+#include <guiddef.h>
+#endif
+
+#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
+ DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8)
+
+#else // !_MIDL_USE_GUIDDEF_
+
+#ifndef __IID_DEFINED__
+#define __IID_DEFINED__
+
+typedef struct _IID
+{
+ unsigned long x;
+ unsigned short s1;
+ unsigned short s2;
+ unsigned char c[8];
+} IID;
+
+#endif // __IID_DEFINED__
+
+#ifndef CLSID_DEFINED
+#define CLSID_DEFINED
+typedef IID CLSID;
+#endif // CLSID_DEFINED
+
+#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
+ const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
+
+#endif !_MIDL_USE_GUIDDEF_
+
+MIDL_DEFINE_GUID(IID, IID_ICorProfilerCallback,0x176FBED1,0xA55C,0x4796,0x98,0xCA,0xA9,0xDA,0x0E,0xF8,0x83,0xE7);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorProfilerCallback2,0x8A8CC829,0xCCF2,0x49fe,0xBB,0xAE,0x0F,0x02,0x22,0x28,0x07,0x1A);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorProfilerCallback3,0x4FD2ED52,0x7731,0x4b8d,0x94,0x69,0x03,0xD2,0xCC,0x30,0x86,0xC5);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorProfilerCallback4,0x7B63B2E3,0x107D,0x4d48,0xB2,0xF6,0xF6,0x1E,0x22,0x94,0x70,0xD2);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorProfilerCallback5,0x8DFBA405,0x8C9F,0x45F8,0xBF,0xFA,0x83,0xB1,0x4C,0xEF,0x78,0xB5);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorProfilerCallback6,0xFC13DF4B,0x4448,0x4F4F,0x95,0x0C,0xBA,0x8D,0x19,0xD0,0x0C,0x36);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorProfilerCallback7,0xF76A2DBA,0x1D52,0x4539,0x86,0x6C,0x2A,0xA5,0x18,0xF9,0xEF,0xC3);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorProfilerCallback8,0x5BED9B15,0xC079,0x4D47,0xBF,0xE2,0x21,0x5A,0x14,0x0C,0x07,0xE0);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorProfilerInfo,0x28B5557D,0x3F3F,0x48b4,0x90,0xB2,0x5F,0x9E,0xEA,0x2F,0x6C,0x48);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorProfilerInfo2,0xCC0935CD,0xA518,0x487d,0xB0,0xBB,0xA9,0x32,0x14,0xE6,0x54,0x78);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorProfilerInfo3,0xB555ED4F,0x452A,0x4E54,0x8B,0x39,0xB5,0x36,0x0B,0xAD,0x32,0xA0);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorProfilerObjectEnum,0x2C6269BD,0x2D13,0x4321,0xAE,0x12,0x66,0x86,0x36,0x5F,0xD6,0xAF);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorProfilerFunctionEnum,0xFF71301A,0xB994,0x429D,0xA1,0x0B,0xB3,0x45,0xA6,0x52,0x80,0xEF);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorProfilerModuleEnum,0xb0266d75,0x2081,0x4493,0xaf,0x7f,0x02,0x8b,0xa3,0x4d,0xb8,0x91);
+
+
+MIDL_DEFINE_GUID(IID, IID_IMethodMalloc,0xA0EFB28B,0x6EE2,0x4d7b,0xB9,0x83,0xA7,0x5E,0xF7,0xBE,0xED,0xB8);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorProfilerFunctionControl,0xF0963021,0xE1EA,0x4732,0x85,0x81,0xE0,0x1B,0x0B,0xD3,0xC0,0xC6);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorProfilerInfo4,0x0d8fdcaa,0x6257,0x47bf,0xb1,0xbf,0x94,0xda,0xc8,0x84,0x66,0xee);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorProfilerInfo5,0x07602928,0xCE38,0x4B83,0x81,0xE7,0x74,0xAD,0xAF,0x78,0x12,0x14);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorProfilerInfo6,0xF30A070D,0xBFFB,0x46A7,0xB1,0xD8,0x87,0x81,0xEF,0x7B,0x69,0x8A);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorProfilerInfo7,0x9AEECC0D,0x63E0,0x4187,0x8C,0x00,0xE3,0x12,0xF5,0x03,0xF6,0x63);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorProfilerInfo8,0xC5AC80A6,0x782E,0x4716,0x80,0x44,0x39,0x59,0x8C,0x60,0xCF,0xBF);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorProfilerMethodEnum,0xFCCEE788,0x0088,0x454B,0xA8,0x11,0xC9,0x9F,0x29,0x8D,0x19,0x42);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorProfilerThreadEnum,0x571194f7,0x25ed,0x419f,0xaa,0x8b,0x70,0x16,0xb3,0x15,0x97,0x01);
+
+
+MIDL_DEFINE_GUID(IID, IID_ICorProfilerAssemblyReferenceProvider,0x66A78C24,0x2EEF,0x4F65,0xB4,0x5F,0xDD,0x1D,0x80,0x38,0xBF,0x3C);
+
+#undef MIDL_DEFINE_GUID
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
diff --git a/src/pal/prebuilt/idl/corpub_i.c b/src/pal/prebuilt/idl/corpub_i.cpp
index 982f89724e..982f89724e 100644
--- a/src/pal/prebuilt/idl/corpub_i.c
+++ b/src/pal/prebuilt/idl/corpub_i.cpp
diff --git a/src/pal/prebuilt/idl/corsym_i.c b/src/pal/prebuilt/idl/corsym_i.cpp
index 7ef9242315..7ef9242315 100644
--- a/src/pal/prebuilt/idl/corsym_i.c
+++ b/src/pal/prebuilt/idl/corsym_i.cpp
diff --git a/src/pal/prebuilt/idl/fusionpriv_i.c b/src/pal/prebuilt/idl/fusionpriv_i.cpp
index ece9622114..ece9622114 100644
--- a/src/pal/prebuilt/idl/fusionpriv_i.c
+++ b/src/pal/prebuilt/idl/fusionpriv_i.cpp
diff --git a/src/pal/prebuilt/idl/gchost_i.c b/src/pal/prebuilt/idl/gchost_i.cpp
index 32ecfbe9d5..32ecfbe9d5 100644
--- a/src/pal/prebuilt/idl/gchost_i.c
+++ b/src/pal/prebuilt/idl/gchost_i.cpp
diff --git a/src/pal/prebuilt/idl/ivalidator_i.c b/src/pal/prebuilt/idl/ivalidator_i.cpp
index 0edbec448a..0edbec448a 100644
--- a/src/pal/prebuilt/idl/ivalidator_i.c
+++ b/src/pal/prebuilt/idl/ivalidator_i.cpp
diff --git a/src/pal/prebuilt/idl/ivehandler_i.c b/src/pal/prebuilt/idl/ivehandler_i.cpp
index 44d0b961bb..44d0b961bb 100644
--- a/src/pal/prebuilt/idl/ivehandler_i.c
+++ b/src/pal/prebuilt/idl/ivehandler_i.cpp
diff --git a/src/pal/prebuilt/idl/mscorsvc_i.c b/src/pal/prebuilt/idl/mscorsvc_i.cpp
index 05d04e58a6..05d04e58a6 100644
--- a/src/pal/prebuilt/idl/mscorsvc_i.c
+++ b/src/pal/prebuilt/idl/mscorsvc_i.cpp
diff --git a/src/pal/prebuilt/idl/sospriv_i.c b/src/pal/prebuilt/idl/sospriv_i.c
deleted file mode 100644
index 7fee909ca3..0000000000
--- a/src/pal/prebuilt/idl/sospriv_i.c
+++ /dev/null
@@ -1,100 +0,0 @@
-
-
-/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */
-
-/* link this file in with the server and any clients */
-
-
- /* File created by MIDL compiler version 8.00.0613 */
-/* at Mon Jan 18 19:14:07 2038
- */
-/* Compiler settings for C:/ssd/coreclr/src/inc/sospriv.idl:
- Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.00.0613
- 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 */
-
-
-#ifdef __cplusplus
-extern "C"{
-#endif
-
-
-#include <rpc.h>
-#include <rpcndr.h>
-
-#ifdef _MIDL_USE_GUIDDEF_
-
-#ifndef INITGUID
-#define INITGUID
-#include <guiddef.h>
-#undef INITGUID
-#else
-#include <guiddef.h>
-#endif
-
-#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
- DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8)
-
-#else // !_MIDL_USE_GUIDDEF_
-
-#ifndef __IID_DEFINED__
-#define __IID_DEFINED__
-
-typedef struct _IID
-{
- unsigned long x;
- unsigned short s1;
- unsigned short s2;
- unsigned char c[8];
-} IID;
-
-#endif // __IID_DEFINED__
-
-#ifndef CLSID_DEFINED
-#define CLSID_DEFINED
-typedef IID CLSID;
-#endif // CLSID_DEFINED
-
-#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
- const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
-
-#endif !_MIDL_USE_GUIDDEF_
-
-MIDL_DEFINE_GUID(IID, IID_ISOSEnum,0x286CA186,0xE763,0x4F61,0x97,0x60,0x48,0x7D,0x43,0xAE,0x43,0x41);
-
-
-MIDL_DEFINE_GUID(IID, IID_ISOSHandleEnum,0x3E269830,0x4A2B,0x4301,0x8E,0xE2,0xD6,0x80,0x5B,0x29,0xB2,0xFA);
-
-
-MIDL_DEFINE_GUID(IID, IID_ISOSStackRefErrorEnum,0x774F4E1B,0xFB7B,0x491B,0x97,0x6D,0xA8,0x13,0x0F,0xE3,0x55,0xE9);
-
-
-MIDL_DEFINE_GUID(IID, IID_ISOSStackRefEnum,0x8FA642BD,0x9F10,0x4799,0x9A,0xA3,0x51,0x2A,0xE7,0x8C,0x77,0xEE);
-
-
-MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface,0x436f00f2,0xb42a,0x4b9f,0x87,0x0c,0xe7,0x3d,0xb6,0x6a,0xe9,0x30);
-
-
-MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface2,0xA16026EC,0x96F4,0x40BA,0x87,0xFB,0x55,0x75,0x98,0x6F,0xB7,0xAF);
-
-
-MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface3,0xB08C5CDC,0xFD8A,0x49C5,0xAB,0x38,0x5F,0xEE,0xF3,0x52,0x35,0xB4);
-
-
-MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface4,0x74B9D34C,0xA612,0x4B07,0x93,0xDD,0x54,0x62,0x17,0x8F,0xCE,0x11);
-
-#undef MIDL_DEFINE_GUID
-
-#ifdef __cplusplus
-}
-#endif
-
-
-
diff --git a/src/pal/prebuilt/idl/sospriv_i.cpp b/src/pal/prebuilt/idl/sospriv_i.cpp
new file mode 100644
index 0000000000..3584b761d2
--- /dev/null
+++ b/src/pal/prebuilt/idl/sospriv_i.cpp
@@ -0,0 +1,98 @@
+
+
+/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */
+
+/* link this file in with the server and any clients */
+
+
+ /* File created by MIDL compiler version 8.00.0613 */
+/* at Mon Jan 18 19:14:07 2038
+ */
+/* Compiler settings for C:/ssd/coreclr/src/inc/sospriv.idl:
+ Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.00.0613
+ 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 */
+
+#include <rpc.h>
+#include <rpcndr.h>
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+#ifdef _MIDL_USE_GUIDDEF_
+
+#ifndef INITGUID
+#define INITGUID
+#include <guiddef.h>
+#undef INITGUID
+#else
+#include <guiddef.h>
+#endif
+
+#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
+ DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8)
+
+#else // !_MIDL_USE_GUIDDEF_
+
+#ifndef __IID_DEFINED__
+#define __IID_DEFINED__
+
+typedef struct _IID
+{
+ unsigned long x;
+ unsigned short s1;
+ unsigned short s2;
+ unsigned char c[8];
+} IID;
+
+#endif // __IID_DEFINED__
+
+#ifndef CLSID_DEFINED
+#define CLSID_DEFINED
+typedef IID CLSID;
+#endif // CLSID_DEFINED
+
+#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
+ const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
+
+#endif !_MIDL_USE_GUIDDEF_
+
+MIDL_DEFINE_GUID(IID, IID_ISOSEnum,0x286CA186,0xE763,0x4F61,0x97,0x60,0x48,0x7D,0x43,0xAE,0x43,0x41);
+
+
+MIDL_DEFINE_GUID(IID, IID_ISOSHandleEnum,0x3E269830,0x4A2B,0x4301,0x8E,0xE2,0xD6,0x80,0x5B,0x29,0xB2,0xFA);
+
+
+MIDL_DEFINE_GUID(IID, IID_ISOSStackRefErrorEnum,0x774F4E1B,0xFB7B,0x491B,0x97,0x6D,0xA8,0x13,0x0F,0xE3,0x55,0xE9);
+
+
+MIDL_DEFINE_GUID(IID, IID_ISOSStackRefEnum,0x8FA642BD,0x9F10,0x4799,0x9A,0xA3,0x51,0x2A,0xE7,0x8C,0x77,0xEE);
+
+
+MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface,0x436f00f2,0xb42a,0x4b9f,0x87,0x0c,0xe7,0x3d,0xb6,0x6a,0xe9,0x30);
+
+
+MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface2,0xA16026EC,0x96F4,0x40BA,0x87,0xFB,0x55,0x75,0x98,0x6F,0xB7,0xAF);
+
+
+MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface3,0xB08C5CDC,0xFD8A,0x49C5,0xAB,0x38,0x5F,0xEE,0xF3,0x52,0x35,0xB4);
+
+
+MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface4,0x74B9D34C,0xA612,0x4B07,0x93,0xDD,0x54,0x62,0x17,0x8F,0xCE,0x11);
+
+#undef MIDL_DEFINE_GUID
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
diff --git a/src/pal/prebuilt/idl/tlbimpexp_i.c b/src/pal/prebuilt/idl/tlbimpexp_i.cpp
index 0eb2791fa3..0eb2791fa3 100644
--- a/src/pal/prebuilt/idl/tlbimpexp_i.c
+++ b/src/pal/prebuilt/idl/tlbimpexp_i.cpp
diff --git a/src/pal/prebuilt/idl/xclrdata_i.c b/src/pal/prebuilt/idl/xclrdata_i.cpp
index 6dd642da4c..6dd642da4c 100644
--- a/src/pal/prebuilt/idl/xclrdata_i.c
+++ b/src/pal/prebuilt/idl/xclrdata_i.cpp
diff --git a/src/pal/prebuilt/idl/xcordebug_i.c b/src/pal/prebuilt/idl/xcordebug_i.cpp
index ffafd17c34..ffafd17c34 100644
--- a/src/pal/prebuilt/idl/xcordebug_i.c
+++ b/src/pal/prebuilt/idl/xcordebug_i.cpp
diff --git a/src/pal/prebuilt/inc/cordebug.h b/src/pal/prebuilt/inc/cordebug.h
index a5a5cf2e8a..39310403dc 100644
--- a/src/pal/prebuilt/inc/cordebug.h
+++ b/src/pal/prebuilt/inc/cordebug.h
@@ -4,9 +4,9 @@
/* File created by MIDL compiler version 8.00.0603 */
-/* at Fri Jul 15 18:01:08 2016
+/* at Fri Sep 23 15:43:16 2016
*/
-/* Compiler settings for E:/git/coreclr/src/inc/cordebug.idl:
+/* Compiler settings for cordebug.idl:
Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.00.0603
protocol : dce , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
@@ -598,6 +598,13 @@ typedef interface ICorDebugCode3 ICorDebugCode3;
#endif /* __ICorDebugCode3_FWD_DEFINED__ */
+#ifndef __ICorDebugCode4_FWD_DEFINED__
+#define __ICorDebugCode4_FWD_DEFINED__
+typedef interface ICorDebugCode4 ICorDebugCode4;
+
+#endif /* __ICorDebugCode4_FWD_DEFINED__ */
+
+
#ifndef __ICorDebugILCode_FWD_DEFINED__
#define __ICorDebugILCode_FWD_DEFINED__
typedef interface ICorDebugILCode ICorDebugILCode;
@@ -731,6 +738,13 @@ typedef interface ICorDebugArrayValue ICorDebugArrayValue;
#endif /* __ICorDebugArrayValue_FWD_DEFINED__ */
+#ifndef __ICorDebugVariableHome_FWD_DEFINED__
+#define __ICorDebugVariableHome_FWD_DEFINED__
+typedef interface ICorDebugVariableHome ICorDebugVariableHome;
+
+#endif /* __ICorDebugVariableHome_FWD_DEFINED__ */
+
+
#ifndef __ICorDebugHandleValue_FWD_DEFINED__
#define __ICorDebugHandleValue_FWD_DEFINED__
typedef interface ICorDebugHandleValue ICorDebugHandleValue;
@@ -815,6 +829,13 @@ typedef interface ICorDebugValueEnum ICorDebugValueEnum;
#endif /* __ICorDebugValueEnum_FWD_DEFINED__ */
+#ifndef __ICorDebugVariableHomeEnum_FWD_DEFINED__
+#define __ICorDebugVariableHomeEnum_FWD_DEFINED__
+typedef interface ICorDebugVariableHomeEnum ICorDebugVariableHomeEnum;
+
+#endif /* __ICorDebugVariableHomeEnum_FWD_DEFINED__ */
+
+
#ifndef __ICorDebugCodeEnum_FWD_DEFINED__
#define __ICorDebugCodeEnum_FWD_DEFINED__
typedef interface ICorDebugCodeEnum ICorDebugCodeEnum;
@@ -836,6 +857,13 @@ typedef interface ICorDebugType ICorDebugType;
#endif /* __ICorDebugType_FWD_DEFINED__ */
+#ifndef __ICorDebugType2_FWD_DEFINED__
+#define __ICorDebugType2_FWD_DEFINED__
+typedef interface ICorDebugType2 ICorDebugType2;
+
+#endif /* __ICorDebugType2_FWD_DEFINED__ */
+
+
#ifndef __ICorDebugErrorInfoEnum_FWD_DEFINED__
#define __ICorDebugErrorInfoEnum_FWD_DEFINED__
typedef interface ICorDebugErrorInfoEnum ICorDebugErrorInfoEnum;
@@ -1321,6 +1349,7 @@ enum CorDebugNGENPolicy
+
#pragma warning(pop)
typedef ULONG64 CORDB_ADDRESS;
@@ -12423,6 +12452,86 @@ EXTERN_C const IID IID_ICorDebugCode3;
#endif /* __ICorDebugCode3_INTERFACE_DEFINED__ */
+#ifndef __ICorDebugCode4_INTERFACE_DEFINED__
+#define __ICorDebugCode4_INTERFACE_DEFINED__
+
+/* interface ICorDebugCode4 */
+/* [unique][uuid][local][object] */
+
+
+EXTERN_C const IID IID_ICorDebugCode4;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("18221fa4-20cb-40fa-b19d-9f91c4fa8c14")
+ ICorDebugCode4 : public IUnknown
+ {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE EnumerateVariableHomes(
+ /* [out] */ ICorDebugVariableHomeEnum **ppEnum) = 0;
+
+ };
+
+
+#else /* C style interface */
+
+ typedef struct ICorDebugCode4Vtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ ICorDebugCode4 * This,
+ /* [in] */ REFIID riid,
+ /* [annotation][iid_is][out] */
+ _COM_Outptr_ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ ICorDebugCode4 * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ ICorDebugCode4 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *EnumerateVariableHomes )(
+ ICorDebugCode4 * This,
+ /* [out] */ ICorDebugVariableHomeEnum **ppEnum);
+
+ END_INTERFACE
+ } ICorDebugCode4Vtbl;
+
+ interface ICorDebugCode4
+ {
+ CONST_VTBL struct ICorDebugCode4Vtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define ICorDebugCode4_QueryInterface(This,riid,ppvObject) \
+ ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
+
+#define ICorDebugCode4_AddRef(This) \
+ ( (This)->lpVtbl -> AddRef(This) )
+
+#define ICorDebugCode4_Release(This) \
+ ( (This)->lpVtbl -> Release(This) )
+
+
+#define ICorDebugCode4_EnumerateVariableHomes(This,ppEnum) \
+ ( (This)->lpVtbl -> EnumerateVariableHomes(This,ppEnum) )
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+
+#endif /* __ICorDebugCode4_INTERFACE_DEFINED__ */
+
+
#ifndef __ICorDebugILCode_INTERFACE_DEFINED__
#define __ICorDebugILCode_INTERFACE_DEFINED__
@@ -14382,15 +14491,15 @@ EXTERN_C const IID IID_ICorDebugBoxValue;
#endif /* __ICorDebugBoxValue_INTERFACE_DEFINED__ */
-/* interface __MIDL_itf_cordebug_0000_0095 */
+/* interface __MIDL_itf_cordebug_0000_0096 */
/* [local] */
#pragma warning(push)
#pragma warning(disable:28718)
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0095_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0095_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0096_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0096_v0_0_s_ifspec;
#ifndef __ICorDebugStringValue_INTERFACE_DEFINED__
#define __ICorDebugStringValue_INTERFACE_DEFINED__
@@ -14530,14 +14639,14 @@ EXTERN_C const IID IID_ICorDebugStringValue;
#endif /* __ICorDebugStringValue_INTERFACE_DEFINED__ */
-/* interface __MIDL_itf_cordebug_0000_0096 */
+/* interface __MIDL_itf_cordebug_0000_0097 */
/* [local] */
#pragma warning(pop)
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0096_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0096_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0097_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0097_v0_0_s_ifspec;
#ifndef __ICorDebugArrayValue_INTERFACE_DEFINED__
#define __ICorDebugArrayValue_INTERFACE_DEFINED__
@@ -14743,6 +14852,156 @@ EXTERN_C const IID IID_ICorDebugArrayValue;
#endif /* __ICorDebugArrayValue_INTERFACE_DEFINED__ */
+#ifndef __ICorDebugVariableHome_INTERFACE_DEFINED__
+#define __ICorDebugVariableHome_INTERFACE_DEFINED__
+
+/* interface ICorDebugVariableHome */
+/* [unique][uuid][local][object] */
+
+typedef
+enum VariableLocationType
+ {
+ VLT_REGISTER = 0,
+ VLT_REGISTER_RELATIVE = ( VLT_REGISTER + 1 ) ,
+ VLT_INVALID = ( VLT_REGISTER_RELATIVE + 1 )
+ } VariableLocationType;
+
+
+EXTERN_C const IID IID_ICorDebugVariableHome;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("50847b8d-f43f-41b0-924c-6383a5f2278b")
+ ICorDebugVariableHome : public IUnknown
+ {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE GetCode(
+ /* [out] */ ICorDebugCode **ppCode) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetSlotIndex(
+ /* [out] */ ULONG32 *pSlotIndex) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetArgumentIndex(
+ /* [out] */ ULONG32 *pArgumentIndex) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetLiveRange(
+ /* [out] */ ULONG32 *pStartOffset,
+ /* [out] */ ULONG32 *pEndOffset) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetLocationType(
+ /* [out] */ VariableLocationType *pLocationType) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetRegister(
+ /* [out] */ CorDebugRegister *pRegister) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetOffset(
+ /* [out] */ LONG *pOffset) = 0;
+
+ };
+
+
+#else /* C style interface */
+
+ typedef struct ICorDebugVariableHomeVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ ICorDebugVariableHome * This,
+ /* [in] */ REFIID riid,
+ /* [annotation][iid_is][out] */
+ _COM_Outptr_ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ ICorDebugVariableHome * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ ICorDebugVariableHome * This);
+
+ HRESULT ( STDMETHODCALLTYPE *GetCode )(
+ ICorDebugVariableHome * This,
+ /* [out] */ ICorDebugCode **ppCode);
+
+ HRESULT ( STDMETHODCALLTYPE *GetSlotIndex )(
+ ICorDebugVariableHome * This,
+ /* [out] */ ULONG32 *pSlotIndex);
+
+ HRESULT ( STDMETHODCALLTYPE *GetArgumentIndex )(
+ ICorDebugVariableHome * This,
+ /* [out] */ ULONG32 *pArgumentIndex);
+
+ HRESULT ( STDMETHODCALLTYPE *GetLiveRange )(
+ ICorDebugVariableHome * This,
+ /* [out] */ ULONG32 *pStartOffset,
+ /* [out] */ ULONG32 *pEndOffset);
+
+ HRESULT ( STDMETHODCALLTYPE *GetLocationType )(
+ ICorDebugVariableHome * This,
+ /* [out] */ VariableLocationType *pLocationType);
+
+ HRESULT ( STDMETHODCALLTYPE *GetRegister )(
+ ICorDebugVariableHome * This,
+ /* [out] */ CorDebugRegister *pRegister);
+
+ HRESULT ( STDMETHODCALLTYPE *GetOffset )(
+ ICorDebugVariableHome * This,
+ /* [out] */ LONG *pOffset);
+
+ END_INTERFACE
+ } ICorDebugVariableHomeVtbl;
+
+ interface ICorDebugVariableHome
+ {
+ CONST_VTBL struct ICorDebugVariableHomeVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define ICorDebugVariableHome_QueryInterface(This,riid,ppvObject) \
+ ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
+
+#define ICorDebugVariableHome_AddRef(This) \
+ ( (This)->lpVtbl -> AddRef(This) )
+
+#define ICorDebugVariableHome_Release(This) \
+ ( (This)->lpVtbl -> Release(This) )
+
+
+#define ICorDebugVariableHome_GetCode(This,ppCode) \
+ ( (This)->lpVtbl -> GetCode(This,ppCode) )
+
+#define ICorDebugVariableHome_GetSlotIndex(This,pSlotIndex) \
+ ( (This)->lpVtbl -> GetSlotIndex(This,pSlotIndex) )
+
+#define ICorDebugVariableHome_GetArgumentIndex(This,pArgumentIndex) \
+ ( (This)->lpVtbl -> GetArgumentIndex(This,pArgumentIndex) )
+
+#define ICorDebugVariableHome_GetLiveRange(This,pStartOffset,pEndOffset) \
+ ( (This)->lpVtbl -> GetLiveRange(This,pStartOffset,pEndOffset) )
+
+#define ICorDebugVariableHome_GetLocationType(This,pLocationType) \
+ ( (This)->lpVtbl -> GetLocationType(This,pLocationType) )
+
+#define ICorDebugVariableHome_GetRegister(This,pRegister) \
+ ( (This)->lpVtbl -> GetRegister(This,pRegister) )
+
+#define ICorDebugVariableHome_GetOffset(This,pOffset) \
+ ( (This)->lpVtbl -> GetOffset(This,pOffset) )
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+
+#endif /* __ICorDebugVariableHome_INTERFACE_DEFINED__ */
+
+
#ifndef __ICorDebugHandleValue_INTERFACE_DEFINED__
#define __ICorDebugHandleValue_INTERFACE_DEFINED__
@@ -16154,6 +16413,118 @@ EXTERN_C const IID IID_ICorDebugValueEnum;
#endif /* __ICorDebugValueEnum_INTERFACE_DEFINED__ */
+#ifndef __ICorDebugVariableHomeEnum_INTERFACE_DEFINED__
+#define __ICorDebugVariableHomeEnum_INTERFACE_DEFINED__
+
+/* interface ICorDebugVariableHomeEnum */
+/* [unique][uuid][local][object] */
+
+
+EXTERN_C const IID IID_ICorDebugVariableHomeEnum;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("e76b7a57-4f7a-4309-85a7-5d918c3deaf7")
+ ICorDebugVariableHomeEnum : public ICorDebugEnum
+ {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE Next(
+ /* [in] */ ULONG celt,
+ /* [length_is][size_is][out] */ ICorDebugVariableHome *homes[ ],
+ /* [out] */ ULONG *pceltFetched) = 0;
+
+ };
+
+
+#else /* C style interface */
+
+ typedef struct ICorDebugVariableHomeEnumVtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ ICorDebugVariableHomeEnum * This,
+ /* [in] */ REFIID riid,
+ /* [annotation][iid_is][out] */
+ _COM_Outptr_ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ ICorDebugVariableHomeEnum * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ ICorDebugVariableHomeEnum * This);
+
+ HRESULT ( STDMETHODCALLTYPE *Skip )(
+ ICorDebugVariableHomeEnum * This,
+ /* [in] */ ULONG celt);
+
+ HRESULT ( STDMETHODCALLTYPE *Reset )(
+ ICorDebugVariableHomeEnum * This);
+
+ HRESULT ( STDMETHODCALLTYPE *Clone )(
+ ICorDebugVariableHomeEnum * This,
+ /* [out] */ ICorDebugEnum **ppEnum);
+
+ HRESULT ( STDMETHODCALLTYPE *GetCount )(
+ ICorDebugVariableHomeEnum * This,
+ /* [out] */ ULONG *pcelt);
+
+ HRESULT ( STDMETHODCALLTYPE *Next )(
+ ICorDebugVariableHomeEnum * This,
+ /* [in] */ ULONG celt,
+ /* [length_is][size_is][out] */ ICorDebugVariableHome *homes[ ],
+ /* [out] */ ULONG *pceltFetched);
+
+ END_INTERFACE
+ } ICorDebugVariableHomeEnumVtbl;
+
+ interface ICorDebugVariableHomeEnum
+ {
+ CONST_VTBL struct ICorDebugVariableHomeEnumVtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define ICorDebugVariableHomeEnum_QueryInterface(This,riid,ppvObject) \
+ ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
+
+#define ICorDebugVariableHomeEnum_AddRef(This) \
+ ( (This)->lpVtbl -> AddRef(This) )
+
+#define ICorDebugVariableHomeEnum_Release(This) \
+ ( (This)->lpVtbl -> Release(This) )
+
+
+#define ICorDebugVariableHomeEnum_Skip(This,celt) \
+ ( (This)->lpVtbl -> Skip(This,celt) )
+
+#define ICorDebugVariableHomeEnum_Reset(This) \
+ ( (This)->lpVtbl -> Reset(This) )
+
+#define ICorDebugVariableHomeEnum_Clone(This,ppEnum) \
+ ( (This)->lpVtbl -> Clone(This,ppEnum) )
+
+#define ICorDebugVariableHomeEnum_GetCount(This,pcelt) \
+ ( (This)->lpVtbl -> GetCount(This,pcelt) )
+
+
+#define ICorDebugVariableHomeEnum_Next(This,celt,homes,pceltFetched) \
+ ( (This)->lpVtbl -> Next(This,celt,homes,pceltFetched) )
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+
+#endif /* __ICorDebugVariableHomeEnum_INTERFACE_DEFINED__ */
+
+
#ifndef __ICorDebugCodeEnum_INTERFACE_DEFINED__
#define __ICorDebugCodeEnum_INTERFACE_DEFINED__
@@ -16522,6 +16893,86 @@ EXTERN_C const IID IID_ICorDebugType;
#endif /* __ICorDebugType_INTERFACE_DEFINED__ */
+#ifndef __ICorDebugType2_INTERFACE_DEFINED__
+#define __ICorDebugType2_INTERFACE_DEFINED__
+
+/* interface ICorDebugType2 */
+/* [unique][uuid][local][object] */
+
+
+EXTERN_C const IID IID_ICorDebugType2;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("e6e91d79-693d-48bc-b417-8284b4f10fb5")
+ ICorDebugType2 : public IUnknown
+ {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE GetTypeID(
+ /* [out] */ COR_TYPEID *id) = 0;
+
+ };
+
+
+#else /* C style interface */
+
+ typedef struct ICorDebugType2Vtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ ICorDebugType2 * This,
+ /* [in] */ REFIID riid,
+ /* [annotation][iid_is][out] */
+ _COM_Outptr_ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ ICorDebugType2 * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ ICorDebugType2 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *GetTypeID )(
+ ICorDebugType2 * This,
+ /* [out] */ COR_TYPEID *id);
+
+ END_INTERFACE
+ } ICorDebugType2Vtbl;
+
+ interface ICorDebugType2
+ {
+ CONST_VTBL struct ICorDebugType2Vtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define ICorDebugType2_QueryInterface(This,riid,ppvObject) \
+ ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
+
+#define ICorDebugType2_AddRef(This) \
+ ( (This)->lpVtbl -> AddRef(This) )
+
+#define ICorDebugType2_Release(This) \
+ ( (This)->lpVtbl -> Release(This) )
+
+
+#define ICorDebugType2_GetTypeID(This,id) \
+ ( (This)->lpVtbl -> GetTypeID(This,id) )
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+
+#endif /* __ICorDebugType2_INTERFACE_DEFINED__ */
+
+
#ifndef __ICorDebugErrorInfoEnum_INTERFACE_DEFINED__
#define __ICorDebugErrorInfoEnum_INTERFACE_DEFINED__
@@ -16970,15 +17421,15 @@ EXTERN_C const IID IID_ICorDebugBlockingObjectEnum;
#endif /* __ICorDebugBlockingObjectEnum_INTERFACE_DEFINED__ */
-/* interface __MIDL_itf_cordebug_0000_0117 */
+/* interface __MIDL_itf_cordebug_0000_0121 */
/* [local] */
#pragma warning(push)
#pragma warning(disable:28718)
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0117_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0117_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0121_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0121_v0_0_s_ifspec;
#ifndef __ICorDebugMDA_INTERFACE_DEFINED__
#define __ICorDebugMDA_INTERFACE_DEFINED__
@@ -17118,7 +17569,7 @@ EXTERN_C const IID IID_ICorDebugMDA;
#endif /* __ICorDebugMDA_INTERFACE_DEFINED__ */
-/* interface __MIDL_itf_cordebug_0000_0118 */
+/* interface __MIDL_itf_cordebug_0000_0122 */
/* [local] */
#pragma warning(pop)
@@ -17126,8 +17577,8 @@ EXTERN_C const IID IID_ICorDebugMDA;
#pragma warning(disable:28718)
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0118_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0118_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0122_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0122_v0_0_s_ifspec;
#ifndef __ICorDebugEditAndContinueErrorInfo_INTERFACE_DEFINED__
#define __ICorDebugEditAndContinueErrorInfo_INTERFACE_DEFINED__
@@ -17243,14 +17694,14 @@ EXTERN_C const IID IID_ICorDebugEditAndContinueErrorInfo;
#endif /* __ICorDebugEditAndContinueErrorInfo_INTERFACE_DEFINED__ */
-/* interface __MIDL_itf_cordebug_0000_0119 */
+/* interface __MIDL_itf_cordebug_0000_0123 */
/* [local] */
#pragma warning(pop)
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0119_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0119_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0123_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0123_v0_0_s_ifspec;
#ifndef __ICorDebugEditAndContinueSnapshot_INTERFACE_DEFINED__
#define __ICorDebugEditAndContinueSnapshot_INTERFACE_DEFINED__
diff --git a/src/pal/prebuilt/inc/corprof.h b/src/pal/prebuilt/inc/corprof.h
index 70b7e77df2..6778fb526f 100644
--- a/src/pal/prebuilt/inc/corprof.h
+++ b/src/pal/prebuilt/inc/corprof.h
@@ -5,7 +5,7 @@
/* this ALWAYS GENERATED file contains the definitions for the interfaces */
- /* File created by MIDL compiler version 8.00.0603 */
+ /* File created by MIDL compiler version 8.01.0620 */
/* @@MIDL_FILE_HEADING( ) */
#pragma warning( disable: 4049 ) /* more than 64k source lines */
@@ -21,7 +21,7 @@
#ifndef __RPCNDR_H_VERSION__
#error this stub requires an updated version of <rpcndr.h>
-#endif // __RPCNDR_H_VERSION__
+#endif /* __RPCNDR_H_VERSION__ */
#ifndef COM_NO_WINDOWS_H
#include "windows.h"
@@ -86,6 +86,13 @@ typedef interface ICorProfilerCallback7 ICorProfilerCallback7;
#endif /* __ICorProfilerCallback7_FWD_DEFINED__ */
+#ifndef __ICorProfilerCallback8_FWD_DEFINED__
+#define __ICorProfilerCallback8_FWD_DEFINED__
+typedef interface ICorProfilerCallback8 ICorProfilerCallback8;
+
+#endif /* __ICorProfilerCallback8_FWD_DEFINED__ */
+
+
#ifndef __ICorProfilerInfo_FWD_DEFINED__
#define __ICorProfilerInfo_FWD_DEFINED__
typedef interface ICorProfilerInfo ICorProfilerInfo;
@@ -170,6 +177,13 @@ typedef interface ICorProfilerInfo7 ICorProfilerInfo7;
#endif /* __ICorProfilerInfo7_FWD_DEFINED__ */
+#ifndef __ICorProfilerInfo8_FWD_DEFINED__
+#define __ICorProfilerInfo8_FWD_DEFINED__
+typedef interface ICorProfilerInfo8 ICorProfilerInfo8;
+
+#endif /* __ICorProfilerInfo8_FWD_DEFINED__ */
+
+
#ifndef __ICorProfilerMethodEnum_FWD_DEFINED__
#define __ICorProfilerMethodEnum_FWD_DEFINED__
typedef interface ICorProfilerMethodEnum ICorProfilerMethodEnum;
@@ -244,6 +258,12 @@ typedef const BYTE *LPCBYTE;
typedef BYTE *LPBYTE;
+typedef BYTE COR_SIGNATURE;
+
+typedef COR_SIGNATURE *PCOR_SIGNATURE;
+
+typedef const COR_SIGNATURE *PCCOR_SIGNATURE;
+
#ifndef _COR_IL_MAP
#define _COR_IL_MAP
typedef struct _COR_IL_MAP
@@ -5807,11 +5827,795 @@ EXTERN_C const IID IID_ICorProfilerCallback7;
#endif /* __ICorProfilerCallback7_INTERFACE_DEFINED__ */
-/* interface __MIDL_itf_corprof_0000_0007 */
+#ifndef __ICorProfilerCallback8_INTERFACE_DEFINED__
+#define __ICorProfilerCallback8_INTERFACE_DEFINED__
+
+/* interface ICorProfilerCallback8 */
+/* [local][unique][uuid][object] */
+
+
+EXTERN_C const IID IID_ICorProfilerCallback8;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("5BED9B15-C079-4D47-BFE2-215A140C07E0")
+ ICorProfilerCallback8 : public ICorProfilerCallback7
+ {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE DynamicMethodJITCompilationStarted(
+ /* [in] */ FunctionID functionId,
+ /* [in] */ BOOL fIsSafeToBlock,
+ /* [in] */ LPCBYTE pILHeader,
+ /* [in] */ ULONG cbILHeader) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE DynamicMethodJITCompilationFinished(
+ /* [in] */ FunctionID functionId,
+ /* [in] */ HRESULT hrStatus,
+ /* [in] */ BOOL fIsSafeToBlock) = 0;
+
+ };
+
+
+#else /* C style interface */
+
+ typedef struct ICorProfilerCallback8Vtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ REFIID riid,
+ /* [annotation][iid_is][out] */
+ _COM_Outptr_ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ ICorProfilerCallback8 * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ ICorProfilerCallback8 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *Initialize )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ IUnknown *pICorProfilerInfoUnk);
+
+ HRESULT ( STDMETHODCALLTYPE *Shutdown )(
+ ICorProfilerCallback8 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *AppDomainCreationStarted )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ AppDomainID appDomainId);
+
+ HRESULT ( STDMETHODCALLTYPE *AppDomainCreationFinished )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ AppDomainID appDomainId,
+ /* [in] */ HRESULT hrStatus);
+
+ HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownStarted )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ AppDomainID appDomainId);
+
+ HRESULT ( STDMETHODCALLTYPE *AppDomainShutdownFinished )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ AppDomainID appDomainId,
+ /* [in] */ HRESULT hrStatus);
+
+ HRESULT ( STDMETHODCALLTYPE *AssemblyLoadStarted )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ AssemblyID assemblyId);
+
+ HRESULT ( STDMETHODCALLTYPE *AssemblyLoadFinished )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ AssemblyID assemblyId,
+ /* [in] */ HRESULT hrStatus);
+
+ HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadStarted )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ AssemblyID assemblyId);
+
+ HRESULT ( STDMETHODCALLTYPE *AssemblyUnloadFinished )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ AssemblyID assemblyId,
+ /* [in] */ HRESULT hrStatus);
+
+ HRESULT ( STDMETHODCALLTYPE *ModuleLoadStarted )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ModuleID moduleId);
+
+ HRESULT ( STDMETHODCALLTYPE *ModuleLoadFinished )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ModuleID moduleId,
+ /* [in] */ HRESULT hrStatus);
+
+ HRESULT ( STDMETHODCALLTYPE *ModuleUnloadStarted )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ModuleID moduleId);
+
+ HRESULT ( STDMETHODCALLTYPE *ModuleUnloadFinished )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ModuleID moduleId,
+ /* [in] */ HRESULT hrStatus);
+
+ HRESULT ( STDMETHODCALLTYPE *ModuleAttachedToAssembly )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ModuleID moduleId,
+ /* [in] */ AssemblyID AssemblyId);
+
+ HRESULT ( STDMETHODCALLTYPE *ClassLoadStarted )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ClassID classId);
+
+ HRESULT ( STDMETHODCALLTYPE *ClassLoadFinished )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ClassID classId,
+ /* [in] */ HRESULT hrStatus);
+
+ HRESULT ( STDMETHODCALLTYPE *ClassUnloadStarted )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ClassID classId);
+
+ HRESULT ( STDMETHODCALLTYPE *ClassUnloadFinished )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ClassID classId,
+ /* [in] */ HRESULT hrStatus);
+
+ HRESULT ( STDMETHODCALLTYPE *FunctionUnloadStarted )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ FunctionID functionId);
+
+ HRESULT ( STDMETHODCALLTYPE *JITCompilationStarted )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ BOOL fIsSafeToBlock);
+
+ HRESULT ( STDMETHODCALLTYPE *JITCompilationFinished )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ HRESULT hrStatus,
+ /* [in] */ BOOL fIsSafeToBlock);
+
+ HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchStarted )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ FunctionID functionId,
+ /* [out] */ BOOL *pbUseCachedFunction);
+
+ HRESULT ( STDMETHODCALLTYPE *JITCachedFunctionSearchFinished )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ COR_PRF_JIT_CACHE result);
+
+ HRESULT ( STDMETHODCALLTYPE *JITFunctionPitched )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ FunctionID functionId);
+
+ HRESULT ( STDMETHODCALLTYPE *JITInlining )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ FunctionID callerId,
+ /* [in] */ FunctionID calleeId,
+ /* [out] */ BOOL *pfShouldInline);
+
+ HRESULT ( STDMETHODCALLTYPE *ThreadCreated )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ThreadID threadId);
+
+ HRESULT ( STDMETHODCALLTYPE *ThreadDestroyed )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ThreadID threadId);
+
+ HRESULT ( STDMETHODCALLTYPE *ThreadAssignedToOSThread )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ThreadID managedThreadId,
+ /* [in] */ DWORD osThreadId);
+
+ HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationStarted )(
+ ICorProfilerCallback8 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *RemotingClientSendingMessage )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ GUID *pCookie,
+ /* [in] */ BOOL fIsAsync);
+
+ HRESULT ( STDMETHODCALLTYPE *RemotingClientReceivingReply )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ GUID *pCookie,
+ /* [in] */ BOOL fIsAsync);
+
+ HRESULT ( STDMETHODCALLTYPE *RemotingClientInvocationFinished )(
+ ICorProfilerCallback8 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *RemotingServerReceivingMessage )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ GUID *pCookie,
+ /* [in] */ BOOL fIsAsync);
+
+ HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationStarted )(
+ ICorProfilerCallback8 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *RemotingServerInvocationReturned )(
+ ICorProfilerCallback8 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *RemotingServerSendingReply )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ GUID *pCookie,
+ /* [in] */ BOOL fIsAsync);
+
+ HRESULT ( STDMETHODCALLTYPE *UnmanagedToManagedTransition )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ COR_PRF_TRANSITION_REASON reason);
+
+ HRESULT ( STDMETHODCALLTYPE *ManagedToUnmanagedTransition )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ COR_PRF_TRANSITION_REASON reason);
+
+ HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendStarted )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ COR_PRF_SUSPEND_REASON suspendReason);
+
+ HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendFinished )(
+ ICorProfilerCallback8 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *RuntimeSuspendAborted )(
+ ICorProfilerCallback8 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *RuntimeResumeStarted )(
+ ICorProfilerCallback8 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *RuntimeResumeFinished )(
+ ICorProfilerCallback8 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *RuntimeThreadSuspended )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ThreadID threadId);
+
+ HRESULT ( STDMETHODCALLTYPE *RuntimeThreadResumed )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ThreadID threadId);
+
+ HRESULT ( STDMETHODCALLTYPE *MovedReferences )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ULONG cMovedObjectIDRanges,
+ /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ],
+ /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ],
+ /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *ObjectAllocated )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ObjectID objectId,
+ /* [in] */ ClassID classId);
+
+ HRESULT ( STDMETHODCALLTYPE *ObjectsAllocatedByClass )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ULONG cClassCount,
+ /* [size_is][in] */ ClassID classIds[ ],
+ /* [size_is][in] */ ULONG cObjects[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *ObjectReferences )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ObjectID objectId,
+ /* [in] */ ClassID classId,
+ /* [in] */ ULONG cObjectRefs,
+ /* [size_is][in] */ ObjectID objectRefIds[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *RootReferences )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ULONG cRootRefs,
+ /* [size_is][in] */ ObjectID rootRefIds[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionThrown )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ObjectID thrownObjectId);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionEnter )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ FunctionID functionId);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFunctionLeave )(
+ ICorProfilerCallback8 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterEnter )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ FunctionID functionId);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionSearchFilterLeave )(
+ ICorProfilerCallback8 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionSearchCatcherFound )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ FunctionID functionId);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerEnter )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ UINT_PTR __unused);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionOSHandlerLeave )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ UINT_PTR __unused);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionEnter )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ FunctionID functionId);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFunctionLeave )(
+ ICorProfilerCallback8 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyEnter )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ FunctionID functionId);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionUnwindFinallyLeave )(
+ ICorProfilerCallback8 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherEnter )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ ObjectID objectId);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionCatcherLeave )(
+ ICorProfilerCallback8 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *COMClassicVTableCreated )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ClassID wrappedClassId,
+ /* [in] */ REFGUID implementedIID,
+ /* [in] */ void *pVTable,
+ /* [in] */ ULONG cSlots);
+
+ HRESULT ( STDMETHODCALLTYPE *COMClassicVTableDestroyed )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ClassID wrappedClassId,
+ /* [in] */ REFGUID implementedIID,
+ /* [in] */ void *pVTable);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherFound )(
+ ICorProfilerCallback8 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *ExceptionCLRCatcherExecute )(
+ ICorProfilerCallback8 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *ThreadNameChanged )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ThreadID threadId,
+ /* [in] */ ULONG cchName,
+ /* [annotation][in] */
+ _In_reads_opt_(cchName) WCHAR name[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *GarbageCollectionStarted )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ int cGenerations,
+ /* [size_is][in] */ BOOL generationCollected[ ],
+ /* [in] */ COR_PRF_GC_REASON reason);
+
+ HRESULT ( STDMETHODCALLTYPE *SurvivingReferences )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ULONG cSurvivingObjectIDRanges,
+ /* [size_is][in] */ ObjectID objectIDRangeStart[ ],
+ /* [size_is][in] */ ULONG cObjectIDRangeLength[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *GarbageCollectionFinished )(
+ ICorProfilerCallback8 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *FinalizeableObjectQueued )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ DWORD finalizerFlags,
+ /* [in] */ ObjectID objectID);
+
+ HRESULT ( STDMETHODCALLTYPE *RootReferences2 )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ULONG cRootRefs,
+ /* [size_is][in] */ ObjectID rootRefIds[ ],
+ /* [size_is][in] */ COR_PRF_GC_ROOT_KIND rootKinds[ ],
+ /* [size_is][in] */ COR_PRF_GC_ROOT_FLAGS rootFlags[ ],
+ /* [size_is][in] */ UINT_PTR rootIds[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *HandleCreated )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ GCHandleID handleId,
+ /* [in] */ ObjectID initialObjectId);
+
+ HRESULT ( STDMETHODCALLTYPE *HandleDestroyed )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ GCHandleID handleId);
+
+ HRESULT ( STDMETHODCALLTYPE *InitializeForAttach )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ IUnknown *pCorProfilerInfoUnk,
+ /* [in] */ void *pvClientData,
+ /* [in] */ UINT cbClientData);
+
+ HRESULT ( STDMETHODCALLTYPE *ProfilerAttachComplete )(
+ ICorProfilerCallback8 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *ProfilerDetachSucceeded )(
+ ICorProfilerCallback8 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *ReJITCompilationStarted )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ ReJITID rejitId,
+ /* [in] */ BOOL fIsSafeToBlock);
+
+ HRESULT ( STDMETHODCALLTYPE *GetReJITParameters )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ModuleID moduleId,
+ /* [in] */ mdMethodDef methodId,
+ /* [in] */ ICorProfilerFunctionControl *pFunctionControl);
+
+ HRESULT ( STDMETHODCALLTYPE *ReJITCompilationFinished )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ ReJITID rejitId,
+ /* [in] */ HRESULT hrStatus,
+ /* [in] */ BOOL fIsSafeToBlock);
+
+ HRESULT ( STDMETHODCALLTYPE *ReJITError )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ModuleID moduleId,
+ /* [in] */ mdMethodDef methodId,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ HRESULT hrStatus);
+
+ HRESULT ( STDMETHODCALLTYPE *MovedReferences2 )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ULONG cMovedObjectIDRanges,
+ /* [size_is][in] */ ObjectID oldObjectIDRangeStart[ ],
+ /* [size_is][in] */ ObjectID newObjectIDRangeStart[ ],
+ /* [size_is][in] */ SIZE_T cObjectIDRangeLength[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *SurvivingReferences2 )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ULONG cSurvivingObjectIDRanges,
+ /* [size_is][in] */ ObjectID objectIDRangeStart[ ],
+ /* [size_is][in] */ SIZE_T cObjectIDRangeLength[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *ConditionalWeakTableElementReferences )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ ULONG cRootRefs,
+ /* [size_is][in] */ ObjectID keyRefIds[ ],
+ /* [size_is][in] */ ObjectID valueRefIds[ ],
+ /* [size_is][in] */ GCHandleID rootIds[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *GetAssemblyReferences )(
+ ICorProfilerCallback8 * This,
+ /* [string][in] */ const WCHAR *wszAssemblyPath,
+ /* [in] */ ICorProfilerAssemblyReferenceProvider *pAsmRefProvider);
+
+ HRESULT ( STDMETHODCALLTYPE *ModuleInMemorySymbolsUpdated )(
+ ICorProfilerCallback8 * This,
+ ModuleID moduleId);
+
+ HRESULT ( STDMETHODCALLTYPE *DynamicMethodJITCompilationStarted )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ BOOL fIsSafeToBlock,
+ /* [in] */ LPCBYTE pILHeader,
+ /* [in] */ ULONG cbILHeader);
+
+ HRESULT ( STDMETHODCALLTYPE *DynamicMethodJITCompilationFinished )(
+ ICorProfilerCallback8 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ HRESULT hrStatus,
+ /* [in] */ BOOL fIsSafeToBlock);
+
+ END_INTERFACE
+ } ICorProfilerCallback8Vtbl;
+
+ interface ICorProfilerCallback8
+ {
+ CONST_VTBL struct ICorProfilerCallback8Vtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define ICorProfilerCallback8_QueryInterface(This,riid,ppvObject) \
+ ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
+
+#define ICorProfilerCallback8_AddRef(This) \
+ ( (This)->lpVtbl -> AddRef(This) )
+
+#define ICorProfilerCallback8_Release(This) \
+ ( (This)->lpVtbl -> Release(This) )
+
+
+#define ICorProfilerCallback8_Initialize(This,pICorProfilerInfoUnk) \
+ ( (This)->lpVtbl -> Initialize(This,pICorProfilerInfoUnk) )
+
+#define ICorProfilerCallback8_Shutdown(This) \
+ ( (This)->lpVtbl -> Shutdown(This) )
+
+#define ICorProfilerCallback8_AppDomainCreationStarted(This,appDomainId) \
+ ( (This)->lpVtbl -> AppDomainCreationStarted(This,appDomainId) )
+
+#define ICorProfilerCallback8_AppDomainCreationFinished(This,appDomainId,hrStatus) \
+ ( (This)->lpVtbl -> AppDomainCreationFinished(This,appDomainId,hrStatus) )
+
+#define ICorProfilerCallback8_AppDomainShutdownStarted(This,appDomainId) \
+ ( (This)->lpVtbl -> AppDomainShutdownStarted(This,appDomainId) )
+
+#define ICorProfilerCallback8_AppDomainShutdownFinished(This,appDomainId,hrStatus) \
+ ( (This)->lpVtbl -> AppDomainShutdownFinished(This,appDomainId,hrStatus) )
+
+#define ICorProfilerCallback8_AssemblyLoadStarted(This,assemblyId) \
+ ( (This)->lpVtbl -> AssemblyLoadStarted(This,assemblyId) )
+
+#define ICorProfilerCallback8_AssemblyLoadFinished(This,assemblyId,hrStatus) \
+ ( (This)->lpVtbl -> AssemblyLoadFinished(This,assemblyId,hrStatus) )
+
+#define ICorProfilerCallback8_AssemblyUnloadStarted(This,assemblyId) \
+ ( (This)->lpVtbl -> AssemblyUnloadStarted(This,assemblyId) )
+
+#define ICorProfilerCallback8_AssemblyUnloadFinished(This,assemblyId,hrStatus) \
+ ( (This)->lpVtbl -> AssemblyUnloadFinished(This,assemblyId,hrStatus) )
+
+#define ICorProfilerCallback8_ModuleLoadStarted(This,moduleId) \
+ ( (This)->lpVtbl -> ModuleLoadStarted(This,moduleId) )
+
+#define ICorProfilerCallback8_ModuleLoadFinished(This,moduleId,hrStatus) \
+ ( (This)->lpVtbl -> ModuleLoadFinished(This,moduleId,hrStatus) )
+
+#define ICorProfilerCallback8_ModuleUnloadStarted(This,moduleId) \
+ ( (This)->lpVtbl -> ModuleUnloadStarted(This,moduleId) )
+
+#define ICorProfilerCallback8_ModuleUnloadFinished(This,moduleId,hrStatus) \
+ ( (This)->lpVtbl -> ModuleUnloadFinished(This,moduleId,hrStatus) )
+
+#define ICorProfilerCallback8_ModuleAttachedToAssembly(This,moduleId,AssemblyId) \
+ ( (This)->lpVtbl -> ModuleAttachedToAssembly(This,moduleId,AssemblyId) )
+
+#define ICorProfilerCallback8_ClassLoadStarted(This,classId) \
+ ( (This)->lpVtbl -> ClassLoadStarted(This,classId) )
+
+#define ICorProfilerCallback8_ClassLoadFinished(This,classId,hrStatus) \
+ ( (This)->lpVtbl -> ClassLoadFinished(This,classId,hrStatus) )
+
+#define ICorProfilerCallback8_ClassUnloadStarted(This,classId) \
+ ( (This)->lpVtbl -> ClassUnloadStarted(This,classId) )
+
+#define ICorProfilerCallback8_ClassUnloadFinished(This,classId,hrStatus) \
+ ( (This)->lpVtbl -> ClassUnloadFinished(This,classId,hrStatus) )
+
+#define ICorProfilerCallback8_FunctionUnloadStarted(This,functionId) \
+ ( (This)->lpVtbl -> FunctionUnloadStarted(This,functionId) )
+
+#define ICorProfilerCallback8_JITCompilationStarted(This,functionId,fIsSafeToBlock) \
+ ( (This)->lpVtbl -> JITCompilationStarted(This,functionId,fIsSafeToBlock) )
+
+#define ICorProfilerCallback8_JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \
+ ( (This)->lpVtbl -> JITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) )
+
+#define ICorProfilerCallback8_JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) \
+ ( (This)->lpVtbl -> JITCachedFunctionSearchStarted(This,functionId,pbUseCachedFunction) )
+
+#define ICorProfilerCallback8_JITCachedFunctionSearchFinished(This,functionId,result) \
+ ( (This)->lpVtbl -> JITCachedFunctionSearchFinished(This,functionId,result) )
+
+#define ICorProfilerCallback8_JITFunctionPitched(This,functionId) \
+ ( (This)->lpVtbl -> JITFunctionPitched(This,functionId) )
+
+#define ICorProfilerCallback8_JITInlining(This,callerId,calleeId,pfShouldInline) \
+ ( (This)->lpVtbl -> JITInlining(This,callerId,calleeId,pfShouldInline) )
+
+#define ICorProfilerCallback8_ThreadCreated(This,threadId) \
+ ( (This)->lpVtbl -> ThreadCreated(This,threadId) )
+
+#define ICorProfilerCallback8_ThreadDestroyed(This,threadId) \
+ ( (This)->lpVtbl -> ThreadDestroyed(This,threadId) )
+
+#define ICorProfilerCallback8_ThreadAssignedToOSThread(This,managedThreadId,osThreadId) \
+ ( (This)->lpVtbl -> ThreadAssignedToOSThread(This,managedThreadId,osThreadId) )
+
+#define ICorProfilerCallback8_RemotingClientInvocationStarted(This) \
+ ( (This)->lpVtbl -> RemotingClientInvocationStarted(This) )
+
+#define ICorProfilerCallback8_RemotingClientSendingMessage(This,pCookie,fIsAsync) \
+ ( (This)->lpVtbl -> RemotingClientSendingMessage(This,pCookie,fIsAsync) )
+
+#define ICorProfilerCallback8_RemotingClientReceivingReply(This,pCookie,fIsAsync) \
+ ( (This)->lpVtbl -> RemotingClientReceivingReply(This,pCookie,fIsAsync) )
+
+#define ICorProfilerCallback8_RemotingClientInvocationFinished(This) \
+ ( (This)->lpVtbl -> RemotingClientInvocationFinished(This) )
+
+#define ICorProfilerCallback8_RemotingServerReceivingMessage(This,pCookie,fIsAsync) \
+ ( (This)->lpVtbl -> RemotingServerReceivingMessage(This,pCookie,fIsAsync) )
+
+#define ICorProfilerCallback8_RemotingServerInvocationStarted(This) \
+ ( (This)->lpVtbl -> RemotingServerInvocationStarted(This) )
+
+#define ICorProfilerCallback8_RemotingServerInvocationReturned(This) \
+ ( (This)->lpVtbl -> RemotingServerInvocationReturned(This) )
+
+#define ICorProfilerCallback8_RemotingServerSendingReply(This,pCookie,fIsAsync) \
+ ( (This)->lpVtbl -> RemotingServerSendingReply(This,pCookie,fIsAsync) )
+
+#define ICorProfilerCallback8_UnmanagedToManagedTransition(This,functionId,reason) \
+ ( (This)->lpVtbl -> UnmanagedToManagedTransition(This,functionId,reason) )
+
+#define ICorProfilerCallback8_ManagedToUnmanagedTransition(This,functionId,reason) \
+ ( (This)->lpVtbl -> ManagedToUnmanagedTransition(This,functionId,reason) )
+
+#define ICorProfilerCallback8_RuntimeSuspendStarted(This,suspendReason) \
+ ( (This)->lpVtbl -> RuntimeSuspendStarted(This,suspendReason) )
+
+#define ICorProfilerCallback8_RuntimeSuspendFinished(This) \
+ ( (This)->lpVtbl -> RuntimeSuspendFinished(This) )
+
+#define ICorProfilerCallback8_RuntimeSuspendAborted(This) \
+ ( (This)->lpVtbl -> RuntimeSuspendAborted(This) )
+
+#define ICorProfilerCallback8_RuntimeResumeStarted(This) \
+ ( (This)->lpVtbl -> RuntimeResumeStarted(This) )
+
+#define ICorProfilerCallback8_RuntimeResumeFinished(This) \
+ ( (This)->lpVtbl -> RuntimeResumeFinished(This) )
+
+#define ICorProfilerCallback8_RuntimeThreadSuspended(This,threadId) \
+ ( (This)->lpVtbl -> RuntimeThreadSuspended(This,threadId) )
+
+#define ICorProfilerCallback8_RuntimeThreadResumed(This,threadId) \
+ ( (This)->lpVtbl -> RuntimeThreadResumed(This,threadId) )
+
+#define ICorProfilerCallback8_MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \
+ ( (This)->lpVtbl -> MovedReferences(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) )
+
+#define ICorProfilerCallback8_ObjectAllocated(This,objectId,classId) \
+ ( (This)->lpVtbl -> ObjectAllocated(This,objectId,classId) )
+
+#define ICorProfilerCallback8_ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) \
+ ( (This)->lpVtbl -> ObjectsAllocatedByClass(This,cClassCount,classIds,cObjects) )
+
+#define ICorProfilerCallback8_ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) \
+ ( (This)->lpVtbl -> ObjectReferences(This,objectId,classId,cObjectRefs,objectRefIds) )
+
+#define ICorProfilerCallback8_RootReferences(This,cRootRefs,rootRefIds) \
+ ( (This)->lpVtbl -> RootReferences(This,cRootRefs,rootRefIds) )
+
+#define ICorProfilerCallback8_ExceptionThrown(This,thrownObjectId) \
+ ( (This)->lpVtbl -> ExceptionThrown(This,thrownObjectId) )
+
+#define ICorProfilerCallback8_ExceptionSearchFunctionEnter(This,functionId) \
+ ( (This)->lpVtbl -> ExceptionSearchFunctionEnter(This,functionId) )
+
+#define ICorProfilerCallback8_ExceptionSearchFunctionLeave(This) \
+ ( (This)->lpVtbl -> ExceptionSearchFunctionLeave(This) )
+
+#define ICorProfilerCallback8_ExceptionSearchFilterEnter(This,functionId) \
+ ( (This)->lpVtbl -> ExceptionSearchFilterEnter(This,functionId) )
+
+#define ICorProfilerCallback8_ExceptionSearchFilterLeave(This) \
+ ( (This)->lpVtbl -> ExceptionSearchFilterLeave(This) )
+
+#define ICorProfilerCallback8_ExceptionSearchCatcherFound(This,functionId) \
+ ( (This)->lpVtbl -> ExceptionSearchCatcherFound(This,functionId) )
+
+#define ICorProfilerCallback8_ExceptionOSHandlerEnter(This,__unused) \
+ ( (This)->lpVtbl -> ExceptionOSHandlerEnter(This,__unused) )
+
+#define ICorProfilerCallback8_ExceptionOSHandlerLeave(This,__unused) \
+ ( (This)->lpVtbl -> ExceptionOSHandlerLeave(This,__unused) )
+
+#define ICorProfilerCallback8_ExceptionUnwindFunctionEnter(This,functionId) \
+ ( (This)->lpVtbl -> ExceptionUnwindFunctionEnter(This,functionId) )
+
+#define ICorProfilerCallback8_ExceptionUnwindFunctionLeave(This) \
+ ( (This)->lpVtbl -> ExceptionUnwindFunctionLeave(This) )
+
+#define ICorProfilerCallback8_ExceptionUnwindFinallyEnter(This,functionId) \
+ ( (This)->lpVtbl -> ExceptionUnwindFinallyEnter(This,functionId) )
+
+#define ICorProfilerCallback8_ExceptionUnwindFinallyLeave(This) \
+ ( (This)->lpVtbl -> ExceptionUnwindFinallyLeave(This) )
+
+#define ICorProfilerCallback8_ExceptionCatcherEnter(This,functionId,objectId) \
+ ( (This)->lpVtbl -> ExceptionCatcherEnter(This,functionId,objectId) )
+
+#define ICorProfilerCallback8_ExceptionCatcherLeave(This) \
+ ( (This)->lpVtbl -> ExceptionCatcherLeave(This) )
+
+#define ICorProfilerCallback8_COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) \
+ ( (This)->lpVtbl -> COMClassicVTableCreated(This,wrappedClassId,implementedIID,pVTable,cSlots) )
+
+#define ICorProfilerCallback8_COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) \
+ ( (This)->lpVtbl -> COMClassicVTableDestroyed(This,wrappedClassId,implementedIID,pVTable) )
+
+#define ICorProfilerCallback8_ExceptionCLRCatcherFound(This) \
+ ( (This)->lpVtbl -> ExceptionCLRCatcherFound(This) )
+
+#define ICorProfilerCallback8_ExceptionCLRCatcherExecute(This) \
+ ( (This)->lpVtbl -> ExceptionCLRCatcherExecute(This) )
+
+
+#define ICorProfilerCallback8_ThreadNameChanged(This,threadId,cchName,name) \
+ ( (This)->lpVtbl -> ThreadNameChanged(This,threadId,cchName,name) )
+
+#define ICorProfilerCallback8_GarbageCollectionStarted(This,cGenerations,generationCollected,reason) \
+ ( (This)->lpVtbl -> GarbageCollectionStarted(This,cGenerations,generationCollected,reason) )
+
+#define ICorProfilerCallback8_SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \
+ ( (This)->lpVtbl -> SurvivingReferences(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) )
+
+#define ICorProfilerCallback8_GarbageCollectionFinished(This) \
+ ( (This)->lpVtbl -> GarbageCollectionFinished(This) )
+
+#define ICorProfilerCallback8_FinalizeableObjectQueued(This,finalizerFlags,objectID) \
+ ( (This)->lpVtbl -> FinalizeableObjectQueued(This,finalizerFlags,objectID) )
+
+#define ICorProfilerCallback8_RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) \
+ ( (This)->lpVtbl -> RootReferences2(This,cRootRefs,rootRefIds,rootKinds,rootFlags,rootIds) )
+
+#define ICorProfilerCallback8_HandleCreated(This,handleId,initialObjectId) \
+ ( (This)->lpVtbl -> HandleCreated(This,handleId,initialObjectId) )
+
+#define ICorProfilerCallback8_HandleDestroyed(This,handleId) \
+ ( (This)->lpVtbl -> HandleDestroyed(This,handleId) )
+
+
+#define ICorProfilerCallback8_InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) \
+ ( (This)->lpVtbl -> InitializeForAttach(This,pCorProfilerInfoUnk,pvClientData,cbClientData) )
+
+#define ICorProfilerCallback8_ProfilerAttachComplete(This) \
+ ( (This)->lpVtbl -> ProfilerAttachComplete(This) )
+
+#define ICorProfilerCallback8_ProfilerDetachSucceeded(This) \
+ ( (This)->lpVtbl -> ProfilerDetachSucceeded(This) )
+
+
+#define ICorProfilerCallback8_ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) \
+ ( (This)->lpVtbl -> ReJITCompilationStarted(This,functionId,rejitId,fIsSafeToBlock) )
+
+#define ICorProfilerCallback8_GetReJITParameters(This,moduleId,methodId,pFunctionControl) \
+ ( (This)->lpVtbl -> GetReJITParameters(This,moduleId,methodId,pFunctionControl) )
+
+#define ICorProfilerCallback8_ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) \
+ ( (This)->lpVtbl -> ReJITCompilationFinished(This,functionId,rejitId,hrStatus,fIsSafeToBlock) )
+
+#define ICorProfilerCallback8_ReJITError(This,moduleId,methodId,functionId,hrStatus) \
+ ( (This)->lpVtbl -> ReJITError(This,moduleId,methodId,functionId,hrStatus) )
+
+#define ICorProfilerCallback8_MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) \
+ ( (This)->lpVtbl -> MovedReferences2(This,cMovedObjectIDRanges,oldObjectIDRangeStart,newObjectIDRangeStart,cObjectIDRangeLength) )
+
+#define ICorProfilerCallback8_SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) \
+ ( (This)->lpVtbl -> SurvivingReferences2(This,cSurvivingObjectIDRanges,objectIDRangeStart,cObjectIDRangeLength) )
+
+
+#define ICorProfilerCallback8_ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) \
+ ( (This)->lpVtbl -> ConditionalWeakTableElementReferences(This,cRootRefs,keyRefIds,valueRefIds,rootIds) )
+
+
+#define ICorProfilerCallback8_GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) \
+ ( (This)->lpVtbl -> GetAssemblyReferences(This,wszAssemblyPath,pAsmRefProvider) )
+
+
+#define ICorProfilerCallback8_ModuleInMemorySymbolsUpdated(This,moduleId) \
+ ( (This)->lpVtbl -> ModuleInMemorySymbolsUpdated(This,moduleId) )
+
+
+#define ICorProfilerCallback8_DynamicMethodJITCompilationStarted(This,functionId,fIsSafeToBlock,pILHeader,cbILHeader) \
+ ( (This)->lpVtbl -> DynamicMethodJITCompilationStarted(This,functionId,fIsSafeToBlock,pILHeader,cbILHeader) )
+
+#define ICorProfilerCallback8_DynamicMethodJITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) \
+ ( (This)->lpVtbl -> DynamicMethodJITCompilationFinished(This,functionId,hrStatus,fIsSafeToBlock) )
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+
+#endif /* __ICorProfilerCallback8_INTERFACE_DEFINED__ */
+
+
+/* interface __MIDL_itf_corprof_0000_0008 */
/* [local] */
typedef /* [public] */
-enum __MIDL___MIDL_itf_corprof_0000_0007_0001
+enum __MIDL___MIDL_itf_corprof_0000_0008_0001
{
COR_PRF_CODEGEN_DISABLE_INLINING = 0x1,
COR_PRF_CODEGEN_DISABLE_ALL_OPTIMIZATIONS = 0x2
@@ -5819,8 +6623,8 @@ enum __MIDL___MIDL_itf_corprof_0000_0007_0001
-extern RPC_IF_HANDLE __MIDL_itf_corprof_0000_0007_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_corprof_0000_0007_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_corprof_0000_0008_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_corprof_0000_0008_v0_0_s_ifspec;
#ifndef __ICorProfilerInfo_INTERFACE_DEFINED__
#define __ICorProfilerInfo_INTERFACE_DEFINED__
@@ -11712,6 +12516,904 @@ EXTERN_C const IID IID_ICorProfilerInfo7;
#endif /* __ICorProfilerInfo7_INTERFACE_DEFINED__ */
+#ifndef __ICorProfilerInfo8_INTERFACE_DEFINED__
+#define __ICorProfilerInfo8_INTERFACE_DEFINED__
+
+/* interface ICorProfilerInfo8 */
+/* [local][unique][uuid][object] */
+
+
+EXTERN_C const IID IID_ICorProfilerInfo8;
+
+#if defined(__cplusplus) && !defined(CINTERFACE)
+
+ MIDL_INTERFACE("C5AC80A6-782E-4716-8044-39598C60CFBF")
+ ICorProfilerInfo8 : public ICorProfilerInfo7
+ {
+ public:
+ virtual HRESULT STDMETHODCALLTYPE IsFunctionDynamic(
+ /* [in] */ FunctionID functionId,
+ /* [out] */ BOOL *isDynamic) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetFunctionFromIP3(
+ /* [in] */ LPCBYTE ip,
+ /* [out] */ FunctionID *functionId,
+ /* [out] */ ReJITID *pReJitId) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetDynamicFunctionInfo(
+ /* [in] */ FunctionID functionId,
+ /* [out] */ ModuleID *moduleId,
+ /* [out] */ PCCOR_SIGNATURE *ppvSig,
+ /* [out] */ ULONG *pbSig,
+ /* [in] */ ULONG cchName,
+ /* [out] */ ULONG *pcchName,
+ /* [out] */ WCHAR wszName[ ]) = 0;
+
+ };
+
+
+#else /* C style interface */
+
+ typedef struct ICorProfilerInfo8Vtbl
+ {
+ BEGIN_INTERFACE
+
+ HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ REFIID riid,
+ /* [annotation][iid_is][out] */
+ _COM_Outptr_ void **ppvObject);
+
+ ULONG ( STDMETHODCALLTYPE *AddRef )(
+ ICorProfilerInfo8 * This);
+
+ ULONG ( STDMETHODCALLTYPE *Release )(
+ ICorProfilerInfo8 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *GetClassFromObject )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ObjectID objectId,
+ /* [out] */ ClassID *pClassId);
+
+ HRESULT ( STDMETHODCALLTYPE *GetClassFromToken )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ModuleID moduleId,
+ /* [in] */ mdTypeDef typeDef,
+ /* [out] */ ClassID *pClassId);
+
+ HRESULT ( STDMETHODCALLTYPE *GetCodeInfo )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ FunctionID functionId,
+ /* [out] */ LPCBYTE *pStart,
+ /* [out] */ ULONG *pcSize);
+
+ HRESULT ( STDMETHODCALLTYPE *GetEventMask )(
+ ICorProfilerInfo8 * This,
+ /* [out] */ DWORD *pdwEvents);
+
+ HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ LPCBYTE ip,
+ /* [out] */ FunctionID *pFunctionId);
+
+ HRESULT ( STDMETHODCALLTYPE *GetFunctionFromToken )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ModuleID moduleId,
+ /* [in] */ mdToken token,
+ /* [out] */ FunctionID *pFunctionId);
+
+ HRESULT ( STDMETHODCALLTYPE *GetHandleFromThread )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ThreadID threadId,
+ /* [out] */ HANDLE *phThread);
+
+ HRESULT ( STDMETHODCALLTYPE *GetObjectSize )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ObjectID objectId,
+ /* [out] */ ULONG *pcSize);
+
+ HRESULT ( STDMETHODCALLTYPE *IsArrayClass )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ClassID classId,
+ /* [out] */ CorElementType *pBaseElemType,
+ /* [out] */ ClassID *pBaseClassId,
+ /* [out] */ ULONG *pcRank);
+
+ HRESULT ( STDMETHODCALLTYPE *GetThreadInfo )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ThreadID threadId,
+ /* [out] */ DWORD *pdwWin32ThreadId);
+
+ HRESULT ( STDMETHODCALLTYPE *GetCurrentThreadID )(
+ ICorProfilerInfo8 * This,
+ /* [out] */ ThreadID *pThreadId);
+
+ HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ClassID classId,
+ /* [out] */ ModuleID *pModuleId,
+ /* [out] */ mdTypeDef *pTypeDefToken);
+
+ HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ FunctionID functionId,
+ /* [out] */ ClassID *pClassId,
+ /* [out] */ ModuleID *pModuleId,
+ /* [out] */ mdToken *pToken);
+
+ HRESULT ( STDMETHODCALLTYPE *SetEventMask )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ DWORD dwEvents);
+
+ HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ FunctionEnter *pFuncEnter,
+ /* [in] */ FunctionLeave *pFuncLeave,
+ /* [in] */ FunctionTailcall *pFuncTailcall);
+
+ HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ FunctionIDMapper *pFunc);
+
+ HRESULT ( STDMETHODCALLTYPE *GetTokenAndMetaDataFromFunction )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ REFIID riid,
+ /* [out] */ IUnknown **ppImport,
+ /* [out] */ mdToken *pToken);
+
+ HRESULT ( STDMETHODCALLTYPE *GetModuleInfo )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ModuleID moduleId,
+ /* [out] */ LPCBYTE *ppBaseLoadAddress,
+ /* [in] */ ULONG cchName,
+ /* [out] */ ULONG *pcchName,
+ /* [annotation][out] */
+ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ],
+ /* [out] */ AssemblyID *pAssemblyId);
+
+ HRESULT ( STDMETHODCALLTYPE *GetModuleMetaData )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ModuleID moduleId,
+ /* [in] */ DWORD dwOpenFlags,
+ /* [in] */ REFIID riid,
+ /* [out] */ IUnknown **ppOut);
+
+ HRESULT ( STDMETHODCALLTYPE *GetILFunctionBody )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ModuleID moduleId,
+ /* [in] */ mdMethodDef methodId,
+ /* [out] */ LPCBYTE *ppMethodHeader,
+ /* [out] */ ULONG *pcbMethodSize);
+
+ HRESULT ( STDMETHODCALLTYPE *GetILFunctionBodyAllocator )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ModuleID moduleId,
+ /* [out] */ IMethodMalloc **ppMalloc);
+
+ HRESULT ( STDMETHODCALLTYPE *SetILFunctionBody )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ModuleID moduleId,
+ /* [in] */ mdMethodDef methodid,
+ /* [in] */ LPCBYTE pbNewILMethodHeader);
+
+ HRESULT ( STDMETHODCALLTYPE *GetAppDomainInfo )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ AppDomainID appDomainId,
+ /* [in] */ ULONG cchName,
+ /* [out] */ ULONG *pcchName,
+ /* [annotation][out] */
+ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ],
+ /* [out] */ ProcessID *pProcessId);
+
+ HRESULT ( STDMETHODCALLTYPE *GetAssemblyInfo )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ AssemblyID assemblyId,
+ /* [in] */ ULONG cchName,
+ /* [out] */ ULONG *pcchName,
+ /* [annotation][out] */
+ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ],
+ /* [out] */ AppDomainID *pAppDomainId,
+ /* [out] */ ModuleID *pModuleId);
+
+ HRESULT ( STDMETHODCALLTYPE *SetFunctionReJIT )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ FunctionID functionId);
+
+ HRESULT ( STDMETHODCALLTYPE *ForceGC )(
+ ICorProfilerInfo8 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *SetILInstrumentedCodeMap )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ BOOL fStartJit,
+ /* [in] */ ULONG cILMapEntries,
+ /* [size_is][in] */ COR_IL_MAP rgILMapEntries[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionInterface )(
+ ICorProfilerInfo8 * This,
+ /* [out] */ IUnknown **ppicd);
+
+ HRESULT ( STDMETHODCALLTYPE *GetInprocInspectionIThisThread )(
+ ICorProfilerInfo8 * This,
+ /* [out] */ IUnknown **ppicd);
+
+ HRESULT ( STDMETHODCALLTYPE *GetThreadContext )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ThreadID threadId,
+ /* [out] */ ContextID *pContextId);
+
+ HRESULT ( STDMETHODCALLTYPE *BeginInprocDebugging )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ BOOL fThisThreadOnly,
+ /* [out] */ DWORD *pdwProfilerContext);
+
+ HRESULT ( STDMETHODCALLTYPE *EndInprocDebugging )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ DWORD dwProfilerContext);
+
+ HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ ULONG32 cMap,
+ /* [out] */ ULONG32 *pcMap,
+ /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *DoStackSnapshot )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ThreadID thread,
+ /* [in] */ StackSnapshotCallback *callback,
+ /* [in] */ ULONG32 infoFlags,
+ /* [in] */ void *clientData,
+ /* [size_is][in] */ BYTE context[ ],
+ /* [in] */ ULONG32 contextSize);
+
+ HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks2 )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ FunctionEnter2 *pFuncEnter,
+ /* [in] */ FunctionLeave2 *pFuncLeave,
+ /* [in] */ FunctionTailcall2 *pFuncTailcall);
+
+ HRESULT ( STDMETHODCALLTYPE *GetFunctionInfo2 )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ FunctionID funcId,
+ /* [in] */ COR_PRF_FRAME_INFO frameInfo,
+ /* [out] */ ClassID *pClassId,
+ /* [out] */ ModuleID *pModuleId,
+ /* [out] */ mdToken *pToken,
+ /* [in] */ ULONG32 cTypeArgs,
+ /* [out] */ ULONG32 *pcTypeArgs,
+ /* [out] */ ClassID typeArgs[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *GetStringLayout )(
+ ICorProfilerInfo8 * This,
+ /* [out] */ ULONG *pBufferLengthOffset,
+ /* [out] */ ULONG *pStringLengthOffset,
+ /* [out] */ ULONG *pBufferOffset);
+
+ HRESULT ( STDMETHODCALLTYPE *GetClassLayout )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ClassID classID,
+ /* [out][in] */ COR_FIELD_OFFSET rFieldOffset[ ],
+ /* [in] */ ULONG cFieldOffset,
+ /* [out] */ ULONG *pcFieldOffset,
+ /* [out] */ ULONG *pulClassSize);
+
+ HRESULT ( STDMETHODCALLTYPE *GetClassIDInfo2 )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ClassID classId,
+ /* [out] */ ModuleID *pModuleId,
+ /* [out] */ mdTypeDef *pTypeDefToken,
+ /* [out] */ ClassID *pParentClassId,
+ /* [in] */ ULONG32 cNumTypeArgs,
+ /* [out] */ ULONG32 *pcNumTypeArgs,
+ /* [out] */ ClassID typeArgs[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *GetCodeInfo2 )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ FunctionID functionID,
+ /* [in] */ ULONG32 cCodeInfos,
+ /* [out] */ ULONG32 *pcCodeInfos,
+ /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *GetClassFromTokenAndTypeArgs )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ModuleID moduleID,
+ /* [in] */ mdTypeDef typeDef,
+ /* [in] */ ULONG32 cTypeArgs,
+ /* [size_is][in] */ ClassID typeArgs[ ],
+ /* [out] */ ClassID *pClassID);
+
+ HRESULT ( STDMETHODCALLTYPE *GetFunctionFromTokenAndTypeArgs )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ModuleID moduleID,
+ /* [in] */ mdMethodDef funcDef,
+ /* [in] */ ClassID classId,
+ /* [in] */ ULONG32 cTypeArgs,
+ /* [size_is][in] */ ClassID typeArgs[ ],
+ /* [out] */ FunctionID *pFunctionID);
+
+ HRESULT ( STDMETHODCALLTYPE *EnumModuleFrozenObjects )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ModuleID moduleID,
+ /* [out] */ ICorProfilerObjectEnum **ppEnum);
+
+ HRESULT ( STDMETHODCALLTYPE *GetArrayObjectInfo )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ObjectID objectId,
+ /* [in] */ ULONG32 cDimensions,
+ /* [size_is][out] */ ULONG32 pDimensionSizes[ ],
+ /* [size_is][out] */ int pDimensionLowerBounds[ ],
+ /* [out] */ BYTE **ppData);
+
+ HRESULT ( STDMETHODCALLTYPE *GetBoxClassLayout )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ClassID classId,
+ /* [out] */ ULONG32 *pBufferOffset);
+
+ HRESULT ( STDMETHODCALLTYPE *GetThreadAppDomain )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ThreadID threadId,
+ /* [out] */ AppDomainID *pAppDomainId);
+
+ HRESULT ( STDMETHODCALLTYPE *GetRVAStaticAddress )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ClassID classId,
+ /* [in] */ mdFieldDef fieldToken,
+ /* [out] */ void **ppAddress);
+
+ HRESULT ( STDMETHODCALLTYPE *GetAppDomainStaticAddress )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ClassID classId,
+ /* [in] */ mdFieldDef fieldToken,
+ /* [in] */ AppDomainID appDomainId,
+ /* [out] */ void **ppAddress);
+
+ HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ClassID classId,
+ /* [in] */ mdFieldDef fieldToken,
+ /* [in] */ ThreadID threadId,
+ /* [out] */ void **ppAddress);
+
+ HRESULT ( STDMETHODCALLTYPE *GetContextStaticAddress )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ClassID classId,
+ /* [in] */ mdFieldDef fieldToken,
+ /* [in] */ ContextID contextId,
+ /* [out] */ void **ppAddress);
+
+ HRESULT ( STDMETHODCALLTYPE *GetStaticFieldInfo )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ClassID classId,
+ /* [in] */ mdFieldDef fieldToken,
+ /* [out] */ COR_PRF_STATIC_TYPE *pFieldInfo);
+
+ HRESULT ( STDMETHODCALLTYPE *GetGenerationBounds )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ULONG cObjectRanges,
+ /* [out] */ ULONG *pcObjectRanges,
+ /* [length_is][size_is][out] */ COR_PRF_GC_GENERATION_RANGE ranges[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *GetObjectGeneration )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ObjectID objectId,
+ /* [out] */ COR_PRF_GC_GENERATION_RANGE *range);
+
+ HRESULT ( STDMETHODCALLTYPE *GetNotifiedExceptionClauseInfo )(
+ ICorProfilerInfo8 * This,
+ /* [out] */ COR_PRF_EX_CLAUSE_INFO *pinfo);
+
+ HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions )(
+ ICorProfilerInfo8 * This,
+ /* [out] */ ICorProfilerFunctionEnum **ppEnum);
+
+ HRESULT ( STDMETHODCALLTYPE *RequestProfilerDetach )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ DWORD dwExpectedCompletionMilliseconds);
+
+ HRESULT ( STDMETHODCALLTYPE *SetFunctionIDMapper2 )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ FunctionIDMapper2 *pFunc,
+ /* [in] */ void *clientData);
+
+ HRESULT ( STDMETHODCALLTYPE *GetStringLayout2 )(
+ ICorProfilerInfo8 * This,
+ /* [out] */ ULONG *pStringLengthOffset,
+ /* [out] */ ULONG *pBufferOffset);
+
+ HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3 )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ FunctionEnter3 *pFuncEnter3,
+ /* [in] */ FunctionLeave3 *pFuncLeave3,
+ /* [in] */ FunctionTailcall3 *pFuncTailcall3);
+
+ HRESULT ( STDMETHODCALLTYPE *SetEnterLeaveFunctionHooks3WithInfo )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ FunctionEnter3WithInfo *pFuncEnter3WithInfo,
+ /* [in] */ FunctionLeave3WithInfo *pFuncLeave3WithInfo,
+ /* [in] */ FunctionTailcall3WithInfo *pFuncTailcall3WithInfo);
+
+ HRESULT ( STDMETHODCALLTYPE *GetFunctionEnter3Info )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ COR_PRF_ELT_INFO eltInfo,
+ /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo,
+ /* [out][in] */ ULONG *pcbArgumentInfo,
+ /* [size_is][out] */ COR_PRF_FUNCTION_ARGUMENT_INFO *pArgumentInfo);
+
+ HRESULT ( STDMETHODCALLTYPE *GetFunctionLeave3Info )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ COR_PRF_ELT_INFO eltInfo,
+ /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo,
+ /* [out] */ COR_PRF_FUNCTION_ARGUMENT_RANGE *pRetvalRange);
+
+ HRESULT ( STDMETHODCALLTYPE *GetFunctionTailcall3Info )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ COR_PRF_ELT_INFO eltInfo,
+ /* [out] */ COR_PRF_FRAME_INFO *pFrameInfo);
+
+ HRESULT ( STDMETHODCALLTYPE *EnumModules )(
+ ICorProfilerInfo8 * This,
+ /* [out] */ ICorProfilerModuleEnum **ppEnum);
+
+ HRESULT ( STDMETHODCALLTYPE *GetRuntimeInformation )(
+ ICorProfilerInfo8 * This,
+ /* [out] */ USHORT *pClrInstanceId,
+ /* [out] */ COR_PRF_RUNTIME_TYPE *pRuntimeType,
+ /* [out] */ USHORT *pMajorVersion,
+ /* [out] */ USHORT *pMinorVersion,
+ /* [out] */ USHORT *pBuildNumber,
+ /* [out] */ USHORT *pQFEVersion,
+ /* [in] */ ULONG cchVersionString,
+ /* [out] */ ULONG *pcchVersionString,
+ /* [annotation][out] */
+ _Out_writes_to_(cchVersionString, *pcchVersionString) WCHAR szVersionString[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *GetThreadStaticAddress2 )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ClassID classId,
+ /* [in] */ mdFieldDef fieldToken,
+ /* [in] */ AppDomainID appDomainId,
+ /* [in] */ ThreadID threadId,
+ /* [out] */ void **ppAddress);
+
+ HRESULT ( STDMETHODCALLTYPE *GetAppDomainsContainingModule )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ModuleID moduleId,
+ /* [in] */ ULONG32 cAppDomainIds,
+ /* [out] */ ULONG32 *pcAppDomainIds,
+ /* [length_is][size_is][out] */ AppDomainID appDomainIds[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *GetModuleInfo2 )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ModuleID moduleId,
+ /* [out] */ LPCBYTE *ppBaseLoadAddress,
+ /* [in] */ ULONG cchName,
+ /* [out] */ ULONG *pcchName,
+ /* [annotation][out] */
+ _Out_writes_to_(cchName, *pcchName) WCHAR szName[ ],
+ /* [out] */ AssemblyID *pAssemblyId,
+ /* [out] */ DWORD *pdwModuleFlags);
+
+ HRESULT ( STDMETHODCALLTYPE *EnumThreads )(
+ ICorProfilerInfo8 * This,
+ /* [out] */ ICorProfilerThreadEnum **ppEnum);
+
+ HRESULT ( STDMETHODCALLTYPE *InitializeCurrentThread )(
+ ICorProfilerInfo8 * This);
+
+ HRESULT ( STDMETHODCALLTYPE *RequestReJIT )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ULONG cFunctions,
+ /* [size_is][in] */ ModuleID moduleIds[ ],
+ /* [size_is][in] */ mdMethodDef methodIds[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *RequestRevert )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ULONG cFunctions,
+ /* [size_is][in] */ ModuleID moduleIds[ ],
+ /* [size_is][in] */ mdMethodDef methodIds[ ],
+ /* [size_is][out] */ HRESULT status[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *GetCodeInfo3 )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ FunctionID functionID,
+ /* [in] */ ReJITID reJitId,
+ /* [in] */ ULONG32 cCodeInfos,
+ /* [out] */ ULONG32 *pcCodeInfos,
+ /* [length_is][size_is][out] */ COR_PRF_CODE_INFO codeInfos[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP2 )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ LPCBYTE ip,
+ /* [out] */ FunctionID *pFunctionId,
+ /* [out] */ ReJITID *pReJitId);
+
+ HRESULT ( STDMETHODCALLTYPE *GetReJITIDs )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ ULONG cReJitIds,
+ /* [out] */ ULONG *pcReJitIds,
+ /* [length_is][size_is][out] */ ReJITID reJitIds[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *GetILToNativeMapping2 )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ FunctionID functionId,
+ /* [in] */ ReJITID reJitId,
+ /* [in] */ ULONG32 cMap,
+ /* [out] */ ULONG32 *pcMap,
+ /* [length_is][size_is][out] */ COR_DEBUG_IL_TO_NATIVE_MAP map[ ]);
+
+ HRESULT ( STDMETHODCALLTYPE *EnumJITedFunctions2 )(
+ ICorProfilerInfo8 * This,
+ /* [out] */ ICorProfilerFunctionEnum **ppEnum);
+
+ HRESULT ( STDMETHODCALLTYPE *GetObjectSize2 )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ObjectID objectId,
+ /* [out] */ SIZE_T *pcSize);
+
+ HRESULT ( STDMETHODCALLTYPE *GetEventMask2 )(
+ ICorProfilerInfo8 * This,
+ /* [out] */ DWORD *pdwEventsLow,
+ /* [out] */ DWORD *pdwEventsHigh);
+
+ HRESULT ( STDMETHODCALLTYPE *SetEventMask2 )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ DWORD dwEventsLow,
+ /* [in] */ DWORD dwEventsHigh);
+
+ HRESULT ( STDMETHODCALLTYPE *EnumNgenModuleMethodsInliningThisMethod )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ModuleID inlinersModuleId,
+ /* [in] */ ModuleID inlineeModuleId,
+ /* [in] */ mdMethodDef inlineeMethodId,
+ /* [out] */ BOOL *incompleteData,
+ /* [out] */ ICorProfilerMethodEnum **ppEnum);
+
+ HRESULT ( STDMETHODCALLTYPE *ApplyMetaData )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ModuleID moduleId);
+
+ HRESULT ( STDMETHODCALLTYPE *GetInMemorySymbolsLength )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ModuleID moduleId,
+ /* [out] */ DWORD *pCountSymbolBytes);
+
+ HRESULT ( STDMETHODCALLTYPE *ReadInMemorySymbols )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ ModuleID moduleId,
+ /* [in] */ DWORD symbolsReadOffset,
+ /* [out] */ BYTE *pSymbolBytes,
+ /* [in] */ DWORD countSymbolBytes,
+ /* [out] */ DWORD *pCountSymbolBytesRead);
+
+ HRESULT ( STDMETHODCALLTYPE *IsFunctionDynamic )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ FunctionID functionId,
+ /* [out] */ BOOL *isDynamic);
+
+ HRESULT ( STDMETHODCALLTYPE *GetFunctionFromIP3 )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ LPCBYTE ip,
+ /* [out] */ FunctionID *functionId,
+ /* [out] */ ReJITID *pReJitId);
+
+ HRESULT ( STDMETHODCALLTYPE *GetDynamicFunctionInfo )(
+ ICorProfilerInfo8 * This,
+ /* [in] */ FunctionID functionId,
+ /* [out] */ ModuleID *moduleId,
+ /* [out] */ PCCOR_SIGNATURE *ppvSig,
+ /* [out] */ ULONG *pbSig,
+ /* [in] */ ULONG cchName,
+ /* [out] */ ULONG *pcchName,
+ /* [out] */ WCHAR wszName[ ]);
+
+ END_INTERFACE
+ } ICorProfilerInfo8Vtbl;
+
+ interface ICorProfilerInfo8
+ {
+ CONST_VTBL struct ICorProfilerInfo8Vtbl *lpVtbl;
+ };
+
+
+
+#ifdef COBJMACROS
+
+
+#define ICorProfilerInfo8_QueryInterface(This,riid,ppvObject) \
+ ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
+
+#define ICorProfilerInfo8_AddRef(This) \
+ ( (This)->lpVtbl -> AddRef(This) )
+
+#define ICorProfilerInfo8_Release(This) \
+ ( (This)->lpVtbl -> Release(This) )
+
+
+#define ICorProfilerInfo8_GetClassFromObject(This,objectId,pClassId) \
+ ( (This)->lpVtbl -> GetClassFromObject(This,objectId,pClassId) )
+
+#define ICorProfilerInfo8_GetClassFromToken(This,moduleId,typeDef,pClassId) \
+ ( (This)->lpVtbl -> GetClassFromToken(This,moduleId,typeDef,pClassId) )
+
+#define ICorProfilerInfo8_GetCodeInfo(This,functionId,pStart,pcSize) \
+ ( (This)->lpVtbl -> GetCodeInfo(This,functionId,pStart,pcSize) )
+
+#define ICorProfilerInfo8_GetEventMask(This,pdwEvents) \
+ ( (This)->lpVtbl -> GetEventMask(This,pdwEvents) )
+
+#define ICorProfilerInfo8_GetFunctionFromIP(This,ip,pFunctionId) \
+ ( (This)->lpVtbl -> GetFunctionFromIP(This,ip,pFunctionId) )
+
+#define ICorProfilerInfo8_GetFunctionFromToken(This,moduleId,token,pFunctionId) \
+ ( (This)->lpVtbl -> GetFunctionFromToken(This,moduleId,token,pFunctionId) )
+
+#define ICorProfilerInfo8_GetHandleFromThread(This,threadId,phThread) \
+ ( (This)->lpVtbl -> GetHandleFromThread(This,threadId,phThread) )
+
+#define ICorProfilerInfo8_GetObjectSize(This,objectId,pcSize) \
+ ( (This)->lpVtbl -> GetObjectSize(This,objectId,pcSize) )
+
+#define ICorProfilerInfo8_IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) \
+ ( (This)->lpVtbl -> IsArrayClass(This,classId,pBaseElemType,pBaseClassId,pcRank) )
+
+#define ICorProfilerInfo8_GetThreadInfo(This,threadId,pdwWin32ThreadId) \
+ ( (This)->lpVtbl -> GetThreadInfo(This,threadId,pdwWin32ThreadId) )
+
+#define ICorProfilerInfo8_GetCurrentThreadID(This,pThreadId) \
+ ( (This)->lpVtbl -> GetCurrentThreadID(This,pThreadId) )
+
+#define ICorProfilerInfo8_GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) \
+ ( (This)->lpVtbl -> GetClassIDInfo(This,classId,pModuleId,pTypeDefToken) )
+
+#define ICorProfilerInfo8_GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) \
+ ( (This)->lpVtbl -> GetFunctionInfo(This,functionId,pClassId,pModuleId,pToken) )
+
+#define ICorProfilerInfo8_SetEventMask(This,dwEvents) \
+ ( (This)->lpVtbl -> SetEventMask(This,dwEvents) )
+
+#define ICorProfilerInfo8_SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) \
+ ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks(This,pFuncEnter,pFuncLeave,pFuncTailcall) )
+
+#define ICorProfilerInfo8_SetFunctionIDMapper(This,pFunc) \
+ ( (This)->lpVtbl -> SetFunctionIDMapper(This,pFunc) )
+
+#define ICorProfilerInfo8_GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) \
+ ( (This)->lpVtbl -> GetTokenAndMetaDataFromFunction(This,functionId,riid,ppImport,pToken) )
+
+#define ICorProfilerInfo8_GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) \
+ ( (This)->lpVtbl -> GetModuleInfo(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId) )
+
+#define ICorProfilerInfo8_GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) \
+ ( (This)->lpVtbl -> GetModuleMetaData(This,moduleId,dwOpenFlags,riid,ppOut) )
+
+#define ICorProfilerInfo8_GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) \
+ ( (This)->lpVtbl -> GetILFunctionBody(This,moduleId,methodId,ppMethodHeader,pcbMethodSize) )
+
+#define ICorProfilerInfo8_GetILFunctionBodyAllocator(This,moduleId,ppMalloc) \
+ ( (This)->lpVtbl -> GetILFunctionBodyAllocator(This,moduleId,ppMalloc) )
+
+#define ICorProfilerInfo8_SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) \
+ ( (This)->lpVtbl -> SetILFunctionBody(This,moduleId,methodid,pbNewILMethodHeader) )
+
+#define ICorProfilerInfo8_GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) \
+ ( (This)->lpVtbl -> GetAppDomainInfo(This,appDomainId,cchName,pcchName,szName,pProcessId) )
+
+#define ICorProfilerInfo8_GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) \
+ ( (This)->lpVtbl -> GetAssemblyInfo(This,assemblyId,cchName,pcchName,szName,pAppDomainId,pModuleId) )
+
+#define ICorProfilerInfo8_SetFunctionReJIT(This,functionId) \
+ ( (This)->lpVtbl -> SetFunctionReJIT(This,functionId) )
+
+#define ICorProfilerInfo8_ForceGC(This) \
+ ( (This)->lpVtbl -> ForceGC(This) )
+
+#define ICorProfilerInfo8_SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) \
+ ( (This)->lpVtbl -> SetILInstrumentedCodeMap(This,functionId,fStartJit,cILMapEntries,rgILMapEntries) )
+
+#define ICorProfilerInfo8_GetInprocInspectionInterface(This,ppicd) \
+ ( (This)->lpVtbl -> GetInprocInspectionInterface(This,ppicd) )
+
+#define ICorProfilerInfo8_GetInprocInspectionIThisThread(This,ppicd) \
+ ( (This)->lpVtbl -> GetInprocInspectionIThisThread(This,ppicd) )
+
+#define ICorProfilerInfo8_GetThreadContext(This,threadId,pContextId) \
+ ( (This)->lpVtbl -> GetThreadContext(This,threadId,pContextId) )
+
+#define ICorProfilerInfo8_BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) \
+ ( (This)->lpVtbl -> BeginInprocDebugging(This,fThisThreadOnly,pdwProfilerContext) )
+
+#define ICorProfilerInfo8_EndInprocDebugging(This,dwProfilerContext) \
+ ( (This)->lpVtbl -> EndInprocDebugging(This,dwProfilerContext) )
+
+#define ICorProfilerInfo8_GetILToNativeMapping(This,functionId,cMap,pcMap,map) \
+ ( (This)->lpVtbl -> GetILToNativeMapping(This,functionId,cMap,pcMap,map) )
+
+
+#define ICorProfilerInfo8_DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) \
+ ( (This)->lpVtbl -> DoStackSnapshot(This,thread,callback,infoFlags,clientData,context,contextSize) )
+
+#define ICorProfilerInfo8_SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) \
+ ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks2(This,pFuncEnter,pFuncLeave,pFuncTailcall) )
+
+#define ICorProfilerInfo8_GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) \
+ ( (This)->lpVtbl -> GetFunctionInfo2(This,funcId,frameInfo,pClassId,pModuleId,pToken,cTypeArgs,pcTypeArgs,typeArgs) )
+
+#define ICorProfilerInfo8_GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) \
+ ( (This)->lpVtbl -> GetStringLayout(This,pBufferLengthOffset,pStringLengthOffset,pBufferOffset) )
+
+#define ICorProfilerInfo8_GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) \
+ ( (This)->lpVtbl -> GetClassLayout(This,classID,rFieldOffset,cFieldOffset,pcFieldOffset,pulClassSize) )
+
+#define ICorProfilerInfo8_GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) \
+ ( (This)->lpVtbl -> GetClassIDInfo2(This,classId,pModuleId,pTypeDefToken,pParentClassId,cNumTypeArgs,pcNumTypeArgs,typeArgs) )
+
+#define ICorProfilerInfo8_GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) \
+ ( (This)->lpVtbl -> GetCodeInfo2(This,functionID,cCodeInfos,pcCodeInfos,codeInfos) )
+
+#define ICorProfilerInfo8_GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) \
+ ( (This)->lpVtbl -> GetClassFromTokenAndTypeArgs(This,moduleID,typeDef,cTypeArgs,typeArgs,pClassID) )
+
+#define ICorProfilerInfo8_GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) \
+ ( (This)->lpVtbl -> GetFunctionFromTokenAndTypeArgs(This,moduleID,funcDef,classId,cTypeArgs,typeArgs,pFunctionID) )
+
+#define ICorProfilerInfo8_EnumModuleFrozenObjects(This,moduleID,ppEnum) \
+ ( (This)->lpVtbl -> EnumModuleFrozenObjects(This,moduleID,ppEnum) )
+
+#define ICorProfilerInfo8_GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) \
+ ( (This)->lpVtbl -> GetArrayObjectInfo(This,objectId,cDimensions,pDimensionSizes,pDimensionLowerBounds,ppData) )
+
+#define ICorProfilerInfo8_GetBoxClassLayout(This,classId,pBufferOffset) \
+ ( (This)->lpVtbl -> GetBoxClassLayout(This,classId,pBufferOffset) )
+
+#define ICorProfilerInfo8_GetThreadAppDomain(This,threadId,pAppDomainId) \
+ ( (This)->lpVtbl -> GetThreadAppDomain(This,threadId,pAppDomainId) )
+
+#define ICorProfilerInfo8_GetRVAStaticAddress(This,classId,fieldToken,ppAddress) \
+ ( (This)->lpVtbl -> GetRVAStaticAddress(This,classId,fieldToken,ppAddress) )
+
+#define ICorProfilerInfo8_GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) \
+ ( (This)->lpVtbl -> GetAppDomainStaticAddress(This,classId,fieldToken,appDomainId,ppAddress) )
+
+#define ICorProfilerInfo8_GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) \
+ ( (This)->lpVtbl -> GetThreadStaticAddress(This,classId,fieldToken,threadId,ppAddress) )
+
+#define ICorProfilerInfo8_GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) \
+ ( (This)->lpVtbl -> GetContextStaticAddress(This,classId,fieldToken,contextId,ppAddress) )
+
+#define ICorProfilerInfo8_GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) \
+ ( (This)->lpVtbl -> GetStaticFieldInfo(This,classId,fieldToken,pFieldInfo) )
+
+#define ICorProfilerInfo8_GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) \
+ ( (This)->lpVtbl -> GetGenerationBounds(This,cObjectRanges,pcObjectRanges,ranges) )
+
+#define ICorProfilerInfo8_GetObjectGeneration(This,objectId,range) \
+ ( (This)->lpVtbl -> GetObjectGeneration(This,objectId,range) )
+
+#define ICorProfilerInfo8_GetNotifiedExceptionClauseInfo(This,pinfo) \
+ ( (This)->lpVtbl -> GetNotifiedExceptionClauseInfo(This,pinfo) )
+
+
+#define ICorProfilerInfo8_EnumJITedFunctions(This,ppEnum) \
+ ( (This)->lpVtbl -> EnumJITedFunctions(This,ppEnum) )
+
+#define ICorProfilerInfo8_RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) \
+ ( (This)->lpVtbl -> RequestProfilerDetach(This,dwExpectedCompletionMilliseconds) )
+
+#define ICorProfilerInfo8_SetFunctionIDMapper2(This,pFunc,clientData) \
+ ( (This)->lpVtbl -> SetFunctionIDMapper2(This,pFunc,clientData) )
+
+#define ICorProfilerInfo8_GetStringLayout2(This,pStringLengthOffset,pBufferOffset) \
+ ( (This)->lpVtbl -> GetStringLayout2(This,pStringLengthOffset,pBufferOffset) )
+
+#define ICorProfilerInfo8_SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) \
+ ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3(This,pFuncEnter3,pFuncLeave3,pFuncTailcall3) )
+
+#define ICorProfilerInfo8_SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) \
+ ( (This)->lpVtbl -> SetEnterLeaveFunctionHooks3WithInfo(This,pFuncEnter3WithInfo,pFuncLeave3WithInfo,pFuncTailcall3WithInfo) )
+
+#define ICorProfilerInfo8_GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) \
+ ( (This)->lpVtbl -> GetFunctionEnter3Info(This,functionId,eltInfo,pFrameInfo,pcbArgumentInfo,pArgumentInfo) )
+
+#define ICorProfilerInfo8_GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) \
+ ( (This)->lpVtbl -> GetFunctionLeave3Info(This,functionId,eltInfo,pFrameInfo,pRetvalRange) )
+
+#define ICorProfilerInfo8_GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) \
+ ( (This)->lpVtbl -> GetFunctionTailcall3Info(This,functionId,eltInfo,pFrameInfo) )
+
+#define ICorProfilerInfo8_EnumModules(This,ppEnum) \
+ ( (This)->lpVtbl -> EnumModules(This,ppEnum) )
+
+#define ICorProfilerInfo8_GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) \
+ ( (This)->lpVtbl -> GetRuntimeInformation(This,pClrInstanceId,pRuntimeType,pMajorVersion,pMinorVersion,pBuildNumber,pQFEVersion,cchVersionString,pcchVersionString,szVersionString) )
+
+#define ICorProfilerInfo8_GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) \
+ ( (This)->lpVtbl -> GetThreadStaticAddress2(This,classId,fieldToken,appDomainId,threadId,ppAddress) )
+
+#define ICorProfilerInfo8_GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) \
+ ( (This)->lpVtbl -> GetAppDomainsContainingModule(This,moduleId,cAppDomainIds,pcAppDomainIds,appDomainIds) )
+
+#define ICorProfilerInfo8_GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) \
+ ( (This)->lpVtbl -> GetModuleInfo2(This,moduleId,ppBaseLoadAddress,cchName,pcchName,szName,pAssemblyId,pdwModuleFlags) )
+
+
+#define ICorProfilerInfo8_EnumThreads(This,ppEnum) \
+ ( (This)->lpVtbl -> EnumThreads(This,ppEnum) )
+
+#define ICorProfilerInfo8_InitializeCurrentThread(This) \
+ ( (This)->lpVtbl -> InitializeCurrentThread(This) )
+
+#define ICorProfilerInfo8_RequestReJIT(This,cFunctions,moduleIds,methodIds) \
+ ( (This)->lpVtbl -> RequestReJIT(This,cFunctions,moduleIds,methodIds) )
+
+#define ICorProfilerInfo8_RequestRevert(This,cFunctions,moduleIds,methodIds,status) \
+ ( (This)->lpVtbl -> RequestRevert(This,cFunctions,moduleIds,methodIds,status) )
+
+#define ICorProfilerInfo8_GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) \
+ ( (This)->lpVtbl -> GetCodeInfo3(This,functionID,reJitId,cCodeInfos,pcCodeInfos,codeInfos) )
+
+#define ICorProfilerInfo8_GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) \
+ ( (This)->lpVtbl -> GetFunctionFromIP2(This,ip,pFunctionId,pReJitId) )
+
+#define ICorProfilerInfo8_GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) \
+ ( (This)->lpVtbl -> GetReJITIDs(This,functionId,cReJitIds,pcReJitIds,reJitIds) )
+
+#define ICorProfilerInfo8_GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) \
+ ( (This)->lpVtbl -> GetILToNativeMapping2(This,functionId,reJitId,cMap,pcMap,map) )
+
+#define ICorProfilerInfo8_EnumJITedFunctions2(This,ppEnum) \
+ ( (This)->lpVtbl -> EnumJITedFunctions2(This,ppEnum) )
+
+#define ICorProfilerInfo8_GetObjectSize2(This,objectId,pcSize) \
+ ( (This)->lpVtbl -> GetObjectSize2(This,objectId,pcSize) )
+
+
+#define ICorProfilerInfo8_GetEventMask2(This,pdwEventsLow,pdwEventsHigh) \
+ ( (This)->lpVtbl -> GetEventMask2(This,pdwEventsLow,pdwEventsHigh) )
+
+#define ICorProfilerInfo8_SetEventMask2(This,dwEventsLow,dwEventsHigh) \
+ ( (This)->lpVtbl -> SetEventMask2(This,dwEventsLow,dwEventsHigh) )
+
+
+#define ICorProfilerInfo8_EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) \
+ ( (This)->lpVtbl -> EnumNgenModuleMethodsInliningThisMethod(This,inlinersModuleId,inlineeModuleId,inlineeMethodId,incompleteData,ppEnum) )
+
+
+#define ICorProfilerInfo8_ApplyMetaData(This,moduleId) \
+ ( (This)->lpVtbl -> ApplyMetaData(This,moduleId) )
+
+#define ICorProfilerInfo8_GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) \
+ ( (This)->lpVtbl -> GetInMemorySymbolsLength(This,moduleId,pCountSymbolBytes) )
+
+#define ICorProfilerInfo8_ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) \
+ ( (This)->lpVtbl -> ReadInMemorySymbols(This,moduleId,symbolsReadOffset,pSymbolBytes,countSymbolBytes,pCountSymbolBytesRead) )
+
+
+#define ICorProfilerInfo8_IsFunctionDynamic(This,functionId,isDynamic) \
+ ( (This)->lpVtbl -> IsFunctionDynamic(This,functionId,isDynamic) )
+
+#define ICorProfilerInfo8_GetFunctionFromIP3(This,ip,functionId,pReJitId) \
+ ( (This)->lpVtbl -> GetFunctionFromIP3(This,ip,functionId,pReJitId) )
+
+#define ICorProfilerInfo8_GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) \
+ ( (This)->lpVtbl -> GetDynamicFunctionInfo(This,functionId,moduleId,ppvSig,pbSig,cchName,pcchName,wszName) )
+
+#endif /* COBJMACROS */
+
+
+#endif /* C style interface */
+
+
+
+
+#endif /* __ICorProfilerInfo8_INTERFACE_DEFINED__ */
+
+
#ifndef __ICorProfilerMethodEnum_INTERFACE_DEFINED__
#define __ICorProfilerMethodEnum_INTERFACE_DEFINED__
diff --git a/src/pal/prebuilt/inc/xclrdata.h b/src/pal/prebuilt/inc/xclrdata.h
index 3f46c31319..da7acb34ab 100644
--- a/src/pal/prebuilt/inc/xclrdata.h
+++ b/src/pal/prebuilt/inc/xclrdata.h
@@ -1017,7 +1017,7 @@ EXTERN_C const IID IID_IXCLRDataDisplay;
IXCLRDataDisplay : public IUnknown
{
public:
- virtual HRESULT STDMETHODCALLTYPE ErrorPrintF(
+ virtual HRESULT STDMETHODVCALLTYPE ErrorPrintF(
const char *const fmt,
...) = 0;
@@ -1063,11 +1063,11 @@ EXTERN_C const IID IID_IXCLRDataDisplay;
virtual HRESULT STDMETHODCALLTYPE EndTextElement( void) = 0;
- virtual HRESULT STDMETHODCALLTYPE WriteXmlText(
+ virtual HRESULT STDMETHODVCALLTYPE WriteXmlText(
const char *const fmt,
...) = 0;
- virtual HRESULT STDMETHODCALLTYPE WriteXmlTextBlock(
+ virtual HRESULT STDMETHODVCALLTYPE WriteXmlTextBlock(
const char *const fmt,
...) = 0;
@@ -1258,7 +1258,7 @@ EXTERN_C const IID IID_IXCLRDataDisplay;
ULONG ( STDMETHODCALLTYPE *Release )(
IXCLRDataDisplay * This);
- HRESULT ( STDMETHODCALLTYPE *ErrorPrintF )(
+ HRESULT ( STDMETHODVCALLTYPE *ErrorPrintF )(
IXCLRDataDisplay * This,
const char *const fmt,
...);
@@ -1319,12 +1319,12 @@ EXTERN_C const IID IID_IXCLRDataDisplay;
HRESULT ( STDMETHODCALLTYPE *EndTextElement )(
IXCLRDataDisplay * This);
- HRESULT ( STDMETHODCALLTYPE *WriteXmlText )(
+ HRESULT ( STDMETHODVCALLTYPE *WriteXmlText )(
IXCLRDataDisplay * This,
const char *const fmt,
...);
- HRESULT ( STDMETHODCALLTYPE *WriteXmlTextBlock )(
+ HRESULT ( STDMETHODVCALLTYPE *WriteXmlTextBlock )(
IXCLRDataDisplay * This,
const char *const fmt,
...);
diff --git a/src/pal/src/CMakeLists.txt b/src/pal/src/CMakeLists.txt
index 7df0aaf360..28ee83a77c 100644
--- a/src/pal/src/CMakeLists.txt
+++ b/src/pal/src/CMakeLists.txt
@@ -2,13 +2,6 @@ cmake_minimum_required(VERSION 2.8.12.2)
include_directories(SYSTEM /usr/local/include)
-# set kernel version to detect Alpine
-EXEC_PROGRAM(uname ARGS -v OUTPUT_VARIABLE CMAKE_SYSTEM_KERNEL_VERSION)
-string(FIND "${CMAKE_SYSTEM_KERNEL_VERSION}" "Alpine" PAL_SYSTEM_ALPINE)
-if(PAL_SYSTEM_ALPINE EQUAL -1)
- unset(PAL_SYSTEM_ALPINE)
-endif()
-
include(configure.cmake)
project(coreclrpal)
@@ -39,16 +32,20 @@ elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL armv7l)
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64)
set(PAL_CMAKE_PLATFORM_ARCH_ARM64 1)
add_definitions(-D_ARM64_)
+elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL i686)
+ set(CLR_CMAKE_PLATFORM_ARCH_I386 1)
+ add_definitions(-D_X86_)
else()
message(FATAL_ERROR "Only ARM and AMD64 is supported")
endif()
if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
add_definitions(-D_TARGET_MAC64)
+ add_definitions(-DXSTATE_SUPPORTED)
set(PLATFORM_SOURCES
- arch/i386/activationhandlerwrapper.S
- arch/i386/context.S
- arch/i386/dispatchexceptionwrapper.S
+ arch/amd64/activationhandlerwrapper.S
+ arch/amd64/context.S
+ arch/amd64/dispatchexceptionwrapper.S
exception/machexception.cpp
exception/machmessage.cpp
)
@@ -68,8 +65,20 @@ elseif(PAL_CMAKE_PLATFORM_ARCH_ARM)
elseif(PAL_CMAKE_PLATFORM_ARCH_ARM64)
add_definitions(-DBIT64=1)
add_definitions(-D_WIN64=1)
+elseif(CLR_CMAKE_PLATFORM_ARCH_I386)
+ add_definitions(-DBIT32=1)
endif()
+if(CMAKE_SYSTEM_NAME STREQUAL Linux AND NOT CLR_CMAKE_PLATFORM_ALPINE_LINUX)
+ # Currently the _xstate is not available on Alpine Linux
+ add_definitions(-DXSTATE_SUPPORTED)
+endif(CMAKE_SYSTEM_NAME STREQUAL Linux AND NOT CLR_CMAKE_PLATFORM_ALPINE_LINUX)
+
+if(CLR_CMAKE_PLATFORM_ALPINE_LINUX)
+ # Setting RLIMIT_NOFILE breaks debugging of coreclr on Alpine Linux for some reason
+ add_definitions(-DDONT_SET_RLIMIT_NOFILE)
+endif(CLR_CMAKE_PLATFORM_ALPINE_LINUX)
+
# turn off capability to remove unused functions (which was enabled in debug build with sanitizers)
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -Wl,--no-gc-sections")
@@ -77,10 +86,10 @@ add_compile_options(-fPIC)
if(PAL_CMAKE_PLATFORM_ARCH_AMD64)
set(ARCH_SOURCES
- arch/i386/context2.S
- arch/i386/debugbreak.S
- arch/i386/exceptionhelper.S
- arch/i386/processor.cpp
+ 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
@@ -96,6 +105,13 @@ elseif(PAL_CMAKE_PLATFORM_ARCH_ARM64)
arch/arm64/exceptionhelper.S
arch/arm64/processor.cpp
)
+elseif(CLR_CMAKE_PLATFORM_ARCH_I386)
+ set(ARCH_SOURCES
+ arch/i386/context2.S
+ arch/i386/debugbreak.S
+ arch/i386/exceptionhelper.S
+ arch/i386/processor.cpp
+ )
endif()
if(PAL_CMAKE_PLATFORM_ARCH_ARM)
@@ -160,37 +176,37 @@ set(SOURCES
objmgr/palobjbase.cpp
objmgr/shmobject.cpp
objmgr/shmobjectmanager.cpp
- safecrt/makepath_s.c
- safecrt/memcpy_s.c
- safecrt/memmove_s.c
- safecrt/mbusafecrt.c
- safecrt/safecrt_input_s.c
- safecrt/safecrt_output_l.c
- safecrt/safecrt_output_s.c
- safecrt/safecrt_winput_s.c
- safecrt/safecrt_woutput_s.c
- safecrt/splitpath_s.c
- safecrt/sprintf.c
- safecrt/sscanf.c
- safecrt/strcat_s.c
- safecrt/strcpy_s.c
- safecrt/strlen_s.c
- safecrt/strncat_s.c
- safecrt/strncpy_s.c
- safecrt/strtok_s.c
- safecrt/swprintf.c
- safecrt/vsprintf.c
- safecrt/vswprint.c
- safecrt/wcscat_s.c
- safecrt/wcscpy_s.c
- safecrt/wcslen_s.c
- safecrt/wcsncat_s.c
- safecrt/wcsncpy_s.c
- safecrt/wcstok_s.c
- safecrt/wmakepath_s.c
- safecrt/wsplitpath_s.c
- safecrt/xtoa_s.c
- safecrt/xtow_s.c
+ safecrt/makepath_s.cpp
+ safecrt/memcpy_s.cpp
+ safecrt/memmove_s.cpp
+ safecrt/mbusafecrt.cpp
+ safecrt/safecrt_input_s.cpp
+ safecrt/safecrt_output_l.cpp
+ safecrt/safecrt_output_s.cpp
+ safecrt/safecrt_winput_s.cpp
+ safecrt/safecrt_woutput_s.cpp
+ safecrt/splitpath_s.cpp
+ safecrt/sprintf_s.cpp
+ safecrt/sscanf_s.cpp
+ safecrt/strcat_s.cpp
+ safecrt/strcpy_s.cpp
+ safecrt/strlen_s.cpp
+ safecrt/strncat_s.cpp
+ safecrt/strncpy_s.cpp
+ safecrt/strtok_s.cpp
+ safecrt/swprintf.cpp
+ safecrt/vsprintf.cpp
+ safecrt/vswprint.cpp
+ safecrt/wcscat_s.cpp
+ safecrt/wcscpy_s.cpp
+ safecrt/wcslen_s.cpp
+ safecrt/wcsncat_s.cpp
+ safecrt/wcsncpy_s.cpp
+ safecrt/wcstok_s.cpp
+ safecrt/wmakepath_s.cpp
+ safecrt/wsplitpath_s.cpp
+ safecrt/xtoa_s.cpp
+ safecrt/xtow_s.cpp
sharedmemory/sharedmemory.cpp
shmemory/shmemory.cpp
sync/cs.cpp
@@ -252,7 +268,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL Linux)
find_library(UNWIND_ARCH NAMES unwind-x86_64)
endif()
- if(PAL_SYSTEM_ALPINE)
+ if(CLR_CMAKE_PLATFORM_ALPINE_LINUX)
find_library(INTL intl)
endif()
diff --git a/src/pal/src/arch/i386/activationhandlerwrapper.S b/src/pal/src/arch/amd64/activationhandlerwrapper.S
index 63f718e81f..63f718e81f 100644
--- a/src/pal/src/arch/i386/activationhandlerwrapper.S
+++ b/src/pal/src/arch/amd64/activationhandlerwrapper.S
diff --git a/src/pal/src/arch/amd64/asmconstants.h b/src/pal/src/arch/amd64/asmconstants.h
new file mode 100644
index 0000000000..182c1191e4
--- /dev/null
+++ b/src/pal/src/arch/amd64/asmconstants.h
@@ -0,0 +1,106 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#ifdef BIT64
+
+#define CONTEXT_AMD64 0x100000
+
+#define CONTEXT_CONTROL 1 // SegSs, Rsp, SegCs, Rip, and EFlags
+#define CONTEXT_INTEGER 2 // Rax, Rcx, Rdx, Rbx, Rbp, Rsi, Rdi, R8-R15
+#define CONTEXT_SEGMENTS 4 // SegDs, SegEs, SegFs, SegGs
+#define CONTEXT_FLOATING_POINT 8
+#define CONTEXT_DEBUG_REGISTERS 16 // Dr0-Dr3 and Dr6-Dr7
+
+#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT)
+
+#define CONTEXT_XSTATE 64
+
+#define CONTEXT_ContextFlags 6*8
+#define CONTEXT_SegCs CONTEXT_ContextFlags+8
+#define CONTEXT_SegDs CONTEXT_SegCs+2
+#define CONTEXT_SegEs CONTEXT_SegDs+2
+#define CONTEXT_SegFs CONTEXT_SegEs+2
+#define CONTEXT_SegGs CONTEXT_SegFs+2
+#define CONTEXT_SegSs CONTEXT_SegGs+2
+#define CONTEXT_EFlags CONTEXT_SegSs+2
+#define CONTEXT_Dr0 CONTEXT_EFlags+4
+#define CONTEXT_Dr1 CONTEXT_Dr0+8
+#define CONTEXT_Dr2 CONTEXT_Dr1+8
+#define CONTEXT_Dr3 CONTEXT_Dr2+8
+#define CONTEXT_Dr6 CONTEXT_Dr3+8
+#define CONTEXT_Dr7 CONTEXT_Dr6+8
+#define CONTEXT_Rax CONTEXT_Dr7+8
+#define CONTEXT_Rcx CONTEXT_Rax+8
+#define CONTEXT_Rdx CONTEXT_Rcx+8
+#define CONTEXT_Rbx CONTEXT_Rdx+8
+#define CONTEXT_Rsp CONTEXT_Rbx+8
+#define CONTEXT_Rbp CONTEXT_Rsp+8
+#define CONTEXT_Rsi CONTEXT_Rbp+8
+#define CONTEXT_Rdi CONTEXT_Rsi+8
+#define CONTEXT_R8 CONTEXT_Rdi+8
+#define CONTEXT_R9 CONTEXT_R8+8
+#define CONTEXT_R10 CONTEXT_R9+8
+#define CONTEXT_R11 CONTEXT_R10+8
+#define CONTEXT_R12 CONTEXT_R11+8
+#define CONTEXT_R13 CONTEXT_R12+8
+#define CONTEXT_R14 CONTEXT_R13+8
+#define CONTEXT_R15 CONTEXT_R14+8
+#define CONTEXT_Rip CONTEXT_R15+8
+#define CONTEXT_FltSave CONTEXT_Rip+8
+#define FLOATING_SAVE_AREA_SIZE 4*8+24*16+96
+#define CONTEXT_Xmm0 CONTEXT_FltSave+10*16
+#define CONTEXT_Xmm1 CONTEXT_Xmm0+16
+#define CONTEXT_Xmm2 CONTEXT_Xmm1+16
+#define CONTEXT_Xmm3 CONTEXT_Xmm2+16
+#define CONTEXT_Xmm4 CONTEXT_Xmm3+16
+#define CONTEXT_Xmm5 CONTEXT_Xmm4+16
+#define CONTEXT_Xmm6 CONTEXT_Xmm5+16
+#define CONTEXT_Xmm7 CONTEXT_Xmm6+16
+#define CONTEXT_Xmm8 CONTEXT_Xmm7+16
+#define CONTEXT_Xmm9 CONTEXT_Xmm8+16
+#define CONTEXT_Xmm10 CONTEXT_Xmm9+16
+#define CONTEXT_Xmm11 CONTEXT_Xmm10+16
+#define CONTEXT_Xmm12 CONTEXT_Xmm11+16
+#define CONTEXT_Xmm13 CONTEXT_Xmm12+16
+#define CONTEXT_Xmm14 CONTEXT_Xmm13+16
+#define CONTEXT_Xmm15 CONTEXT_Xmm14+16
+#define CONTEXT_VectorRegister CONTEXT_FltSave+FLOATING_SAVE_AREA_SIZE
+#define CONTEXT_VectorControl CONTEXT_VectorRegister+16*26
+#define CONTEXT_DebugControl CONTEXT_VectorControl+8
+#define CONTEXT_LastBranchToRip CONTEXT_DebugControl+8
+#define CONTEXT_LastBranchFromRip CONTEXT_LastBranchToRip+8
+#define CONTEXT_LastExceptionToRip CONTEXT_LastBranchFromRip+8
+#define CONTEXT_LastExceptionFromRip CONTEXT_LastExceptionToRip+8
+#define CONTEXT_Size CONTEXT_LastExceptionFromRip+8
+
+#else // BIT64
+
+#define CONTEXT_ContextFlags 0
+#define CONTEXT_FLOATING_POINT 8
+#define CONTEXT_FloatSave 7*4
+#define FLOATING_SAVE_AREA_SIZE 8*4+80
+#define CONTEXT_Edi CONTEXT_FloatSave + FLOATING_SAVE_AREA_SIZE + 4*4
+#define CONTEXT_Esi CONTEXT_Edi+4
+#define CONTEXT_Ebx CONTEXT_Esi+4
+#define CONTEXT_Edx CONTEXT_Ebx+4
+#define CONTEXT_Ecx CONTEXT_Edx+4
+#define CONTEXT_Eax CONTEXT_Ecx+4
+#define CONTEXT_Ebp CONTEXT_Eax+4
+#define CONTEXT_Eip CONTEXT_Ebp+4
+#define CONTEXT_SegCs CONTEXT_Eip+4
+#define CONTEXT_EFlags CONTEXT_SegCs+4
+#define CONTEXT_Esp CONTEXT_EFlags+4
+#define CONTEXT_SegSs CONTEXT_Esp+4
+#define CONTEXT_EXTENDED_REGISTERS 32
+#define CONTEXT_ExtendedRegisters CONTEXT_SegSs+4
+#define CONTEXT_Xmm0 CONTEXT_ExtendedRegisters+160
+#define CONTEXT_Xmm1 CONTEXT_Xmm0+16
+#define CONTEXT_Xmm2 CONTEXT_Xmm1+16
+#define CONTEXT_Xmm3 CONTEXT_Xmm2+16
+#define CONTEXT_Xmm4 CONTEXT_Xmm3+16
+#define CONTEXT_Xmm5 CONTEXT_Xmm4+16
+#define CONTEXT_Xmm6 CONTEXT_Xmm5+16
+#define CONTEXT_Xmm7 CONTEXT_Xmm6+16
+
+#endif // BIT64
diff --git a/src/pal/src/arch/i386/context.S b/src/pal/src/arch/amd64/context.S
index f8a2dca89c..f8a2dca89c 100644
--- a/src/pal/src/arch/i386/context.S
+++ b/src/pal/src/arch/amd64/context.S
diff --git a/src/pal/src/arch/amd64/context2.S b/src/pal/src/arch/amd64/context2.S
new file mode 100644
index 0000000000..0e93e81a55
--- /dev/null
+++ b/src/pal/src/arch/amd64/context2.S
@@ -0,0 +1,259 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+// Implementation of _CONTEXT_CaptureContext for the Intel x86 platform.
+// This function is processor dependent. It is used by exception handling,
+// and is always apply to the current thread.
+//
+
+.intel_syntax noprefix
+#include "unixasmmacros.inc"
+#include "asmconstants.h"
+
+#ifdef BIT64
+
+#define IRETFRAME_Rip 0
+#define IRETFRAME_SegCs IRETFRAME_Rip+8
+#define IRETFRAME_EFlags IRETFRAME_SegCs+8
+#define IRETFRAME_Rsp IRETFRAME_EFlags+8
+#define IRETFRAME_SegSs IRETFRAME_Rsp+8
+#define IRetFrameLength IRETFRAME_SegSs+8
+#define IRetFrameLengthAligned 16*((IRetFrameLength+8)/16)
+
+// Incoming:
+// RDI: Context*
+//
+LEAF_ENTRY CONTEXT_CaptureContext, _TEXT
+ // Save processor flags before calling any of the following 'test' instructions
+ // because they will modify state of some flags
+ push_eflags
+ END_PROLOGUE
+
+ test BYTE PTR [rdi + CONTEXT_ContextFlags], CONTEXT_INTEGER
+ je LOCAL_LABEL(Done_CONTEXT_INTEGER)
+ mov [rdi + CONTEXT_Rdi], rdi
+ mov [rdi + CONTEXT_Rsi], rsi
+ mov [rdi + CONTEXT_Rbx], rbx
+ mov [rdi + CONTEXT_Rdx], rdx
+ mov [rdi + CONTEXT_Rcx], rcx
+ mov [rdi + CONTEXT_Rax], rax
+ mov [rdi + CONTEXT_Rbp], rbp
+ mov [rdi + CONTEXT_R8], r8
+ mov [rdi + CONTEXT_R9], r9
+ mov [rdi + CONTEXT_R10], r10
+ mov [rdi + CONTEXT_R11], r11
+ mov [rdi + CONTEXT_R12], r12
+ mov [rdi + CONTEXT_R13], r13
+ mov [rdi + CONTEXT_R14], r14
+ mov [rdi + CONTEXT_R15], r15
+LOCAL_LABEL(Done_CONTEXT_INTEGER):
+
+ test BYTE PTR [rdi + CONTEXT_ContextFlags], CONTEXT_CONTROL
+ je LOCAL_LABEL(Done_CONTEXT_CONTROL)
+
+ // Return address is @ (RSP + 8)
+ mov rdx, [rsp + 8]
+ mov [rdi + CONTEXT_Rip], rdx
+.att_syntax
+ mov %cs, CONTEXT_SegCs(%rdi)
+.intel_syntax noprefix
+ // Get the value of EFlags that was pushed on stack at the beginning of the function
+ mov rdx, [rsp]
+ mov [rdi + CONTEXT_EFlags], edx
+ lea rdx, [rsp + 16]
+ mov [rdi + CONTEXT_Rsp], rdx
+.att_syntax
+ mov %ss, CONTEXT_SegSs(%rdi)
+.intel_syntax noprefix
+LOCAL_LABEL(Done_CONTEXT_CONTROL):
+
+ // Need to double check this is producing the right result
+ // also that FFSXR (fast save/restore) is not turned on
+ // otherwise it omits the xmm registers.
+ test BYTE PTR [rdi + CONTEXT_ContextFlags], CONTEXT_FLOATING_POINT
+ je LOCAL_LABEL(Done_CONTEXT_FLOATING_POINT)
+ fxsave [rdi + CONTEXT_FltSave]
+LOCAL_LABEL(Done_CONTEXT_FLOATING_POINT):
+
+ test BYTE PTR [rdi + CONTEXT_ContextFlags], CONTEXT_DEBUG_REGISTERS
+ je LOCAL_LABEL(Done_CONTEXT_DEBUG_REGISTERS)
+ mov rdx, dr0
+ mov [rdi + CONTEXT_Dr0], rdx
+ mov rdx, dr1
+ mov [rdi + CONTEXT_Dr1], rdx
+ mov rdx, dr2
+ mov [rdi + CONTEXT_Dr2], rdx
+ mov rdx, dr3
+ mov [rdi + CONTEXT_Dr3], rdx
+ mov rdx, dr6
+ mov [rdi + CONTEXT_Dr6], rdx
+ mov rdx, dr7
+ mov [rdi + CONTEXT_Dr7], rdx
+LOCAL_LABEL(Done_CONTEXT_DEBUG_REGISTERS):
+
+ free_stack 8
+ ret
+LEAF_END CONTEXT_CaptureContext, _TEXT
+
+LEAF_ENTRY RtlCaptureContext, _TEXT
+ mov DWORD PTR [rdi + CONTEXT_ContextFlags], (CONTEXT_AMD64 | CONTEXT_FULL | CONTEXT_SEGMENTS)
+ jmp C_FUNC(CONTEXT_CaptureContext)
+LEAF_END RtlCaptureContext, _TEXT
+
+LEAF_ENTRY RtlRestoreContext, _TEXT
+ push_nonvol_reg rbp
+ alloc_stack (IRetFrameLengthAligned)
+
+ test BYTE PTR [rdi + CONTEXT_ContextFlags], CONTEXT_DEBUG_REGISTERS
+ je LOCAL_LABEL(Done_Restore_CONTEXT_DEBUG_REGISTERS)
+ mov rdx, [rdi + CONTEXT_Dr0]
+ mov dr0, rdx
+ mov rdx, [rdi + CONTEXT_Dr1]
+ mov dr1, rdx
+ mov rdx, [rdi + CONTEXT_Dr2]
+ mov dr2, rdx
+ mov rdx, [rdi + CONTEXT_Dr3]
+ mov dr3, rdx
+ mov rdx, [rdi + CONTEXT_Dr6]
+ mov dr6, rdx
+ mov rdx, [rdi + CONTEXT_Dr7]
+ mov dr7, rdx
+LOCAL_LABEL(Done_Restore_CONTEXT_DEBUG_REGISTERS):
+
+ test BYTE PTR [rdi + CONTEXT_ContextFlags], CONTEXT_FLOATING_POINT
+ je LOCAL_LABEL(Done_Restore_CONTEXT_FLOATING_POINT)
+ fxrstor [rdi + CONTEXT_FltSave]
+LOCAL_LABEL(Done_Restore_CONTEXT_FLOATING_POINT):
+
+ test BYTE PTR [rdi + CONTEXT_ContextFlags], CONTEXT_XSTATE
+ je LOCAL_LABEL(Done_Restore_CONTEXT_XSTATE)
+
+ // Restore the extended state (for now, this is just the upper halves of YMM registers)
+ vinsertf128 ymm0, ymm0, xmmword ptr [rdi + (CONTEXT_VectorRegister + 0 * 16)], 1
+ vinsertf128 ymm1, ymm1, xmmword ptr [rdi + (CONTEXT_VectorRegister + 1 * 16)], 1
+ vinsertf128 ymm2, ymm2, xmmword ptr [rdi + (CONTEXT_VectorRegister + 2 * 16)], 1
+ vinsertf128 ymm3, ymm3, xmmword ptr [rdi + (CONTEXT_VectorRegister + 3 * 16)], 1
+ vinsertf128 ymm4, ymm4, xmmword ptr [rdi + (CONTEXT_VectorRegister + 4 * 16)], 1
+ vinsertf128 ymm5, ymm5, xmmword ptr [rdi + (CONTEXT_VectorRegister + 5 * 16)], 1
+ vinsertf128 ymm6, ymm6, xmmword ptr [rdi + (CONTEXT_VectorRegister + 6 * 16)], 1
+ vinsertf128 ymm7, ymm7, xmmword ptr [rdi + (CONTEXT_VectorRegister + 7 * 16)], 1
+ vinsertf128 ymm8, ymm8, xmmword ptr [rdi + (CONTEXT_VectorRegister + 8 * 16)], 1
+ vinsertf128 ymm9, ymm9, xmmword ptr [rdi + (CONTEXT_VectorRegister + 9 * 16)], 1
+ vinsertf128 ymm10, ymm10, xmmword ptr [rdi + (CONTEXT_VectorRegister + 10 * 16)], 1
+ vinsertf128 ymm11, ymm11, xmmword ptr [rdi + (CONTEXT_VectorRegister + 11 * 16)], 1
+ vinsertf128 ymm12, ymm12, xmmword ptr [rdi + (CONTEXT_VectorRegister + 12 * 16)], 1
+ vinsertf128 ymm13, ymm13, xmmword ptr [rdi + (CONTEXT_VectorRegister + 13 * 16)], 1
+ vinsertf128 ymm14, ymm14, xmmword ptr [rdi + (CONTEXT_VectorRegister + 14 * 16)], 1
+ vinsertf128 ymm15, ymm15, xmmword ptr [rdi + (CONTEXT_VectorRegister + 15 * 16)], 1
+LOCAL_LABEL(Done_Restore_CONTEXT_XSTATE):
+
+ test BYTE PTR [rdi + CONTEXT_ContextFlags], CONTEXT_CONTROL
+ je LOCAL_LABEL(Done_Restore_CONTEXT_CONTROL)
+
+ // The control registers are restored via the iret instruction
+ // so we build the frame for the iret on the stack.
+#ifdef __APPLE__
+.att_syntax
+ // On OSX, we cannot read SS via the thread_get_context and RtlRestoreContext
+ // needs to be used on context extracted by thread_get_context. So we
+ // don't change the SS.
+ mov %ss, %ax
+.intel_syntax noprefix
+#else
+ mov ax, [rdi + CONTEXT_SegSs]
+#endif
+ mov [rsp + IRETFRAME_SegSs], ax
+ mov rax, [rdi + CONTEXT_Rsp]
+ mov [rsp + IRETFRAME_Rsp], rax
+ mov eax, [rdi + CONTEXT_EFlags]
+ mov [rsp + IRETFRAME_EFlags], eax
+ mov ax, [rdi + CONTEXT_SegCs]
+ mov [rsp + IRETFRAME_SegCs], ax
+ mov rax, [rdi + CONTEXT_Rip]
+ mov [rsp + IRETFRAME_Rip], rax
+
+LOCAL_LABEL(Done_Restore_CONTEXT_CONTROL):
+ // Remember the result of the test for the CONTEXT_CONTROL
+ push_eflags
+ test BYTE PTR [rdi + CONTEXT_ContextFlags], CONTEXT_INTEGER
+ je LOCAL_LABEL(Done_Restore_CONTEXT_INTEGER)
+ mov rsi, [rdi + CONTEXT_Rsi]
+ mov rbx, [rdi + CONTEXT_Rbx]
+ mov rdx, [rdi + CONTEXT_Rdx]
+ mov rcx, [rdi + CONTEXT_Rcx]
+ mov rax, [rdi + CONTEXT_Rax]
+ mov rbp, [rdi + CONTEXT_Rbp]
+ mov r8, [rdi + CONTEXT_R8]
+ mov r9, [rdi + CONTEXT_R9]
+ mov r10, [rdi + CONTEXT_R10]
+ mov r11, [rdi + CONTEXT_R11]
+ mov r12, [rdi + CONTEXT_R12]
+ mov r13, [rdi + CONTEXT_R13]
+ mov r14, [rdi + CONTEXT_R14]
+ mov r15, [rdi + CONTEXT_R15]
+ mov rdi, [rdi + CONTEXT_Rdi]
+LOCAL_LABEL(Done_Restore_CONTEXT_INTEGER):
+
+ // Restore the result of the test for the CONTEXT_CONTROL
+ pop_eflags
+ je LOCAL_LABEL(No_Restore_CONTEXT_CONTROL)
+ // The function was asked to restore the control registers, so
+ // we perform iretq that restores them all.
+ // We don't return to the caller in this case.
+ iretq
+LOCAL_LABEL(No_Restore_CONTEXT_CONTROL):
+
+ // The function was not asked to restore the control registers
+ // so we return back to the caller.
+ free_stack (IRetFrameLengthAligned)
+ pop_nonvol_reg rbp
+ ret
+LEAF_END RtlRestoreContext, _TEXT
+
+#else
+
+ .globl C_FUNC(CONTEXT_CaptureContext)
+C_FUNC(CONTEXT_CaptureContext):
+ push %eax
+ mov 8(%esp), %eax
+ mov %edi, CONTEXT_Edi(%eax)
+ mov %esi, CONTEXT_Esi(%eax)
+ mov %ebx, CONTEXT_Ebx(%eax)
+ mov %edx, CONTEXT_Edx(%eax)
+ mov %ecx, CONTEXT_Ecx(%eax)
+ pop %ecx
+ mov %ecx, CONTEXT_Eax(%eax)
+ mov %ebp, CONTEXT_Ebp(%eax)
+ mov (%esp), %edx
+ mov %edx, CONTEXT_Eip(%eax)
+ push %cs
+ pop %edx
+ mov %edx, CONTEXT_SegCs(%eax)
+ pushf
+ pop %edx
+ mov %edx, CONTEXT_EFlags(%eax)
+ lea 4(%esp), %edx
+ mov %edx, CONTEXT_Esp(%eax)
+ push %ss
+ pop %edx
+ mov %edx, CONTEXT_SegSs(%eax)
+ testb $CONTEXT_FLOATING_POINT, CONTEXT_ContextFlags(%eax)
+ je 0f
+ fnsave CONTEXT_FloatSave(%eax)
+ frstor CONTEXT_FloatSave(%eax)
+0:
+ testb $CONTEXT_EXTENDED_REGISTERS, CONTEXT_ContextFlags(%eax)
+ je 2f
+ movdqu %xmm0, CONTEXT_Xmm0(%eax)
+ movdqu %xmm1, CONTEXT_Xmm1(%eax)
+ movdqu %xmm2, CONTEXT_Xmm2(%eax)
+ movdqu %xmm3, CONTEXT_Xmm3(%eax)
+ movdqu %xmm4, CONTEXT_Xmm4(%eax)
+ movdqu %xmm5, CONTEXT_Xmm5(%eax)
+ movdqu %xmm6, CONTEXT_Xmm6(%eax)
+ movdqu %xmm7, CONTEXT_Xmm7(%eax)
+2:
+ ret
+
+#endif
diff --git a/src/pal/src/arch/amd64/debugbreak.S b/src/pal/src/arch/amd64/debugbreak.S
new file mode 100644
index 0000000000..3065e4064c
--- /dev/null
+++ b/src/pal/src/arch/amd64/debugbreak.S
@@ -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.
+
+.intel_syntax noprefix
+#include "unixasmmacros.inc"
+
+LEAF_ENTRY DBG_DebugBreak, _TEXT
+ int3
+ ret
+LEAF_END_MARKED DBG_DebugBreak, _TEXT
+
diff --git a/src/pal/src/arch/i386/dispatchexceptionwrapper.S b/src/pal/src/arch/amd64/dispatchexceptionwrapper.S
index ee5ff468d6..ee5ff468d6 100644
--- a/src/pal/src/arch/i386/dispatchexceptionwrapper.S
+++ b/src/pal/src/arch/amd64/dispatchexceptionwrapper.S
diff --git a/src/pal/src/arch/amd64/exceptionhelper.S b/src/pal/src/arch/amd64/exceptionhelper.S
new file mode 100644
index 0000000000..b7b34ace41
--- /dev/null
+++ b/src/pal/src/arch/amd64/exceptionhelper.S
@@ -0,0 +1,42 @@
+// Licensed to the .NET Foundation under one or more 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"
+
+//////////////////////////////////////////////////////////////////////////
+//
+// This function creates a stack frame right below the target frame, restores all callee
+// saved registers from the passed in context, sets the RSP to that frame and sets the
+// return address to the target frame's RIP.
+// 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
+ // Save the RBP to the stack so that the unwind can work at the instruction after
+ // loading the RBP from the context, but before loading the RSP from the context.
+ push_nonvol_reg rbp
+ mov r12, [rdi + CONTEXT_R12]
+ mov r13, [rdi + CONTEXT_R13]
+ mov r14, [rdi + CONTEXT_R14]
+ mov r15, [rdi + CONTEXT_R15]
+ mov rbx, [rdi + CONTEXT_Rbx]
+ mov rbp, [rdi + CONTEXT_Rbp]
+ mov rsp, [rdi + CONTEXT_Rsp]
+ // The RSP was set to the target frame's value, so the current function's
+ // CFA is now right at the RSP.
+ .cfi_def_cfa_offset 0
+
+ // Indicate that now that we have moved the RSP to the target address,
+ // the RBP is no longer saved in the current stack frame.
+ .cfi_restore rbp
+
+ mov rax, [rdi + CONTEXT_Rip]
+
+ // Store return address to the stack
+ push_register rax
+ // The PAL_SEHException pointer
+ mov rdi, rsi
+ jmp EXTERNAL_C_FUNC(ThrowExceptionHelper)
+LEAF_END ThrowExceptionFromContextInternal, _TEXT
diff --git a/src/pal/src/arch/amd64/optimizedtls.cpp b/src/pal/src/arch/amd64/optimizedtls.cpp
new file mode 100644
index 0000000000..cd89db6b0a
--- /dev/null
+++ b/src/pal/src/arch/amd64/optimizedtls.cpp
@@ -0,0 +1,237 @@
+// Licensed to the .NET Foundation under one or more 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/processor.cpp b/src/pal/src/arch/amd64/processor.cpp
new file mode 100644
index 0000000000..ac3d448a81
--- /dev/null
+++ b/src/pal/src/arch/amd64/processor.cpp
@@ -0,0 +1,64 @@
+// Licensed to the .NET Foundation under one or more 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:
+
+ processor.cpp
+
+Abstract:
+
+ Implementation of processor related functions for the Intel x86/x64
+ platforms. These functions are processor dependent.
+
+
+
+--*/
+
+#include "pal/palinternal.h"
+
+/*++
+Function:
+YieldProcessor
+
+The YieldProcessor function signals to the processor to give resources
+to threads that are waiting for them. This macro is only effective on
+processors that support technology allowing multiple threads running
+on a single processor, such as Intel's Hyper-Threading technology.
+
+--*/
+void
+PALAPI
+YieldProcessor(
+ VOID)
+{
+ __asm__ __volatile__ (
+ "rep\n"
+ "nop"
+ );
+}
+
+/*++
+Function:
+XmmYmmStateSupport
+
+Check if OS has enabled both XMM and YMM state support
+
+Return value:
+1 if XMM and YMM are enabled, 0 otherwise
+--*/
+extern "C" unsigned int XmmYmmStateSupport()
+{
+ unsigned int eax;
+ __asm(" xgetbv\n" \
+ : "=a"(eax) /*output in eax*/\
+ : "c"(0) /*inputs - 0 in ecx*/\
+ : "eax", "edx" /* registers that are clobbered*/
+ );
+ // Check OS has enabled both XMM and YMM state support
+ return ((eax & 0x06) == 0x06) ? 1 : 0;
+}
diff --git a/src/pal/src/arch/arm/exceptionhelper.S b/src/pal/src/arch/arm/exceptionhelper.S
index ed1c9c3dc2..76cdcba9b4 100644
--- a/src/pal/src/arch/arm/exceptionhelper.S
+++ b/src/pal/src/arch/arm/exceptionhelper.S
@@ -10,7 +10,7 @@
// EXTERN_C void ThrowExceptionFromContextInternal(CONTEXT* context, PAL_SEHException* ex);
LEAF_ENTRY ThrowExceptionFromContextInternal, _TEXT
- // Ported from src/pal/src/arch/i386/exceptionhelper.S
+ // Ported from src/pal/src/arch/amd64/exceptionhelper.S
push_nonvol_reg {r7} /* FP. x64-RBP */
ldr r4, [r0, #(CONTEXT_R4)]
diff --git a/src/pal/src/arch/i386/asmconstants.h b/src/pal/src/arch/i386/asmconstants.h
index 182c1191e4..ff763ef16b 100644
--- a/src/pal/src/arch/i386/asmconstants.h
+++ b/src/pal/src/arch/i386/asmconstants.h
@@ -2,80 +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.
-#ifdef BIT64
-
-#define CONTEXT_AMD64 0x100000
-
-#define CONTEXT_CONTROL 1 // SegSs, Rsp, SegCs, Rip, and EFlags
-#define CONTEXT_INTEGER 2 // Rax, Rcx, Rdx, Rbx, Rbp, Rsi, Rdi, R8-R15
-#define CONTEXT_SEGMENTS 4 // SegDs, SegEs, SegFs, SegGs
-#define CONTEXT_FLOATING_POINT 8
-#define CONTEXT_DEBUG_REGISTERS 16 // Dr0-Dr3 and Dr6-Dr7
-
-#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT)
-
-#define CONTEXT_XSTATE 64
-
-#define CONTEXT_ContextFlags 6*8
-#define CONTEXT_SegCs CONTEXT_ContextFlags+8
-#define CONTEXT_SegDs CONTEXT_SegCs+2
-#define CONTEXT_SegEs CONTEXT_SegDs+2
-#define CONTEXT_SegFs CONTEXT_SegEs+2
-#define CONTEXT_SegGs CONTEXT_SegFs+2
-#define CONTEXT_SegSs CONTEXT_SegGs+2
-#define CONTEXT_EFlags CONTEXT_SegSs+2
-#define CONTEXT_Dr0 CONTEXT_EFlags+4
-#define CONTEXT_Dr1 CONTEXT_Dr0+8
-#define CONTEXT_Dr2 CONTEXT_Dr1+8
-#define CONTEXT_Dr3 CONTEXT_Dr2+8
-#define CONTEXT_Dr6 CONTEXT_Dr3+8
-#define CONTEXT_Dr7 CONTEXT_Dr6+8
-#define CONTEXT_Rax CONTEXT_Dr7+8
-#define CONTEXT_Rcx CONTEXT_Rax+8
-#define CONTEXT_Rdx CONTEXT_Rcx+8
-#define CONTEXT_Rbx CONTEXT_Rdx+8
-#define CONTEXT_Rsp CONTEXT_Rbx+8
-#define CONTEXT_Rbp CONTEXT_Rsp+8
-#define CONTEXT_Rsi CONTEXT_Rbp+8
-#define CONTEXT_Rdi CONTEXT_Rsi+8
-#define CONTEXT_R8 CONTEXT_Rdi+8
-#define CONTEXT_R9 CONTEXT_R8+8
-#define CONTEXT_R10 CONTEXT_R9+8
-#define CONTEXT_R11 CONTEXT_R10+8
-#define CONTEXT_R12 CONTEXT_R11+8
-#define CONTEXT_R13 CONTEXT_R12+8
-#define CONTEXT_R14 CONTEXT_R13+8
-#define CONTEXT_R15 CONTEXT_R14+8
-#define CONTEXT_Rip CONTEXT_R15+8
-#define CONTEXT_FltSave CONTEXT_Rip+8
-#define FLOATING_SAVE_AREA_SIZE 4*8+24*16+96
-#define CONTEXT_Xmm0 CONTEXT_FltSave+10*16
-#define CONTEXT_Xmm1 CONTEXT_Xmm0+16
-#define CONTEXT_Xmm2 CONTEXT_Xmm1+16
-#define CONTEXT_Xmm3 CONTEXT_Xmm2+16
-#define CONTEXT_Xmm4 CONTEXT_Xmm3+16
-#define CONTEXT_Xmm5 CONTEXT_Xmm4+16
-#define CONTEXT_Xmm6 CONTEXT_Xmm5+16
-#define CONTEXT_Xmm7 CONTEXT_Xmm6+16
-#define CONTEXT_Xmm8 CONTEXT_Xmm7+16
-#define CONTEXT_Xmm9 CONTEXT_Xmm8+16
-#define CONTEXT_Xmm10 CONTEXT_Xmm9+16
-#define CONTEXT_Xmm11 CONTEXT_Xmm10+16
-#define CONTEXT_Xmm12 CONTEXT_Xmm11+16
-#define CONTEXT_Xmm13 CONTEXT_Xmm12+16
-#define CONTEXT_Xmm14 CONTEXT_Xmm13+16
-#define CONTEXT_Xmm15 CONTEXT_Xmm14+16
-#define CONTEXT_VectorRegister CONTEXT_FltSave+FLOATING_SAVE_AREA_SIZE
-#define CONTEXT_VectorControl CONTEXT_VectorRegister+16*26
-#define CONTEXT_DebugControl CONTEXT_VectorControl+8
-#define CONTEXT_LastBranchToRip CONTEXT_DebugControl+8
-#define CONTEXT_LastBranchFromRip CONTEXT_LastBranchToRip+8
-#define CONTEXT_LastExceptionToRip CONTEXT_LastBranchFromRip+8
-#define CONTEXT_LastExceptionFromRip CONTEXT_LastExceptionToRip+8
-#define CONTEXT_Size CONTEXT_LastExceptionFromRip+8
-
-#else // BIT64
-
#define CONTEXT_ContextFlags 0
#define CONTEXT_FLOATING_POINT 8
#define CONTEXT_FloatSave 7*4
@@ -102,5 +28,3 @@
#define CONTEXT_Xmm5 CONTEXT_Xmm4+16
#define CONTEXT_Xmm6 CONTEXT_Xmm5+16
#define CONTEXT_Xmm7 CONTEXT_Xmm6+16
-
-#endif // BIT64
diff --git a/src/pal/src/arch/i386/context2.S b/src/pal/src/arch/i386/context2.S
index 0e93e81a55..16cbcc855c 100644
--- a/src/pal/src/arch/i386/context2.S
+++ b/src/pal/src/arch/i386/context2.S
@@ -1,259 +1,151 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-//
-// Implementation of _CONTEXT_CaptureContext for the Intel x86 platform.
-// This function is processor dependent. It is used by exception handling,
-// and is always apply to the current thread.
-//
.intel_syntax noprefix
#include "unixasmmacros.inc"
#include "asmconstants.h"
-#ifdef BIT64
-
-#define IRETFRAME_Rip 0
-#define IRETFRAME_SegCs IRETFRAME_Rip+8
-#define IRETFRAME_EFlags IRETFRAME_SegCs+8
-#define IRETFRAME_Rsp IRETFRAME_EFlags+8
-#define IRETFRAME_SegSs IRETFRAME_Rsp+8
-#define IRetFrameLength IRETFRAME_SegSs+8
-#define IRetFrameLengthAligned 16*((IRetFrameLength+8)/16)
-
-// Incoming:
-// RDI: Context*
+//
+// Implementation of CONTEXT_CaptureContext for the Intel x86 platform.
+//
+// extern void CONTEXT_CaptureContext(LPCONTEXT lpContext);
+//
+// This function is processor-dependent. It is used by exception handling,
+// and is always apply to the current thread.
//
LEAF_ENTRY CONTEXT_CaptureContext, _TEXT
- // Save processor flags before calling any of the following 'test' instructions
- // because they will modify state of some flags
- push_eflags
- END_PROLOGUE
+ // Store
+ push eax
+ push ebx
+
+ // The stack will contain the following elements on the top of
+ // the caller's stack
+ // [ebx] / esp + 00
+ // [eax] / esp + 04
+ // [ret] / esp + 08
+ // [arg0: lpContext] / esp + 12
+
+ mov eax, [esp + 12] // eax will point to lpContext
+
+ // Capture INTEGER registers
+ mov ebx, [esp + 4]
+ mov [eax + CONTEXT_Eax], ebx
+ mov ebx, [esp]
+ mov [eax + CONTEXT_Ebx], ebx
+ mov [eax + CONTEXT_Ecx], ecx
+ mov [eax + CONTEXT_Edx], edx
+ mov [eax + CONTEXT_Esi], esi
+ mov [eax + CONTEXT_Edi], edi
+
+ // Capture CONTROL registers
+ mov [eax + CONTEXT_Ebp], ebp
+ lea ebx, [esp + 12]
+ mov [eax + CONTEXT_Esp], ebx
+ mov ebx, [esp + 8]
+ mov [eax + CONTEXT_Eip], ebx
+
+ push cs
+ xor ebx, ebx
+ pop bx
+ mov [eax + CONTEXT_SegCs], ebx
+
+ push ss
+ xor ebx, ebx
+ pop bx
+ mov [eax + CONTEXT_SegSs], ebx
- test BYTE PTR [rdi + CONTEXT_ContextFlags], CONTEXT_INTEGER
- je LOCAL_LABEL(Done_CONTEXT_INTEGER)
- mov [rdi + CONTEXT_Rdi], rdi
- mov [rdi + CONTEXT_Rsi], rsi
- mov [rdi + CONTEXT_Rbx], rbx
- mov [rdi + CONTEXT_Rdx], rdx
- mov [rdi + CONTEXT_Rcx], rcx
- mov [rdi + CONTEXT_Rax], rax
- mov [rdi + CONTEXT_Rbp], rbp
- mov [rdi + CONTEXT_R8], r8
- mov [rdi + CONTEXT_R9], r9
- mov [rdi + CONTEXT_R10], r10
- mov [rdi + CONTEXT_R11], r11
- mov [rdi + CONTEXT_R12], r12
- mov [rdi + CONTEXT_R13], r13
- mov [rdi + CONTEXT_R14], r14
- mov [rdi + CONTEXT_R15], r15
-LOCAL_LABEL(Done_CONTEXT_INTEGER):
-
- test BYTE PTR [rdi + CONTEXT_ContextFlags], CONTEXT_CONTROL
- je LOCAL_LABEL(Done_CONTEXT_CONTROL)
-
- // Return address is @ (RSP + 8)
- mov rdx, [rsp + 8]
- mov [rdi + CONTEXT_Rip], rdx
-.att_syntax
- mov %cs, CONTEXT_SegCs(%rdi)
-.intel_syntax noprefix
- // Get the value of EFlags that was pushed on stack at the beginning of the function
- mov rdx, [rsp]
- mov [rdi + CONTEXT_EFlags], edx
- lea rdx, [rsp + 16]
- mov [rdi + CONTEXT_Rsp], rdx
-.att_syntax
- mov %ss, CONTEXT_SegSs(%rdi)
-.intel_syntax noprefix
-LOCAL_LABEL(Done_CONTEXT_CONTROL):
+ pushf
+ xor ebx, ebx
+ pop bx
+ mov [eax + CONTEXT_EFlags], ebx
- // Need to double check this is producing the right result
- // also that FFSXR (fast save/restore) is not turned on
- // otherwise it omits the xmm registers.
- test BYTE PTR [rdi + CONTEXT_ContextFlags], CONTEXT_FLOATING_POINT
+ test BYTE PTR [eax + CONTEXT_ContextFlags], CONTEXT_FLOATING_POINT
je LOCAL_LABEL(Done_CONTEXT_FLOATING_POINT)
- fxsave [rdi + CONTEXT_FltSave]
+ // Capture FPU status
+ fnsave [eax + CONTEXT_FloatSave]
+ frstor [eax + CONTEXT_FloatSave]
LOCAL_LABEL(Done_CONTEXT_FLOATING_POINT):
- test BYTE PTR [rdi + CONTEXT_ContextFlags], CONTEXT_DEBUG_REGISTERS
- je LOCAL_LABEL(Done_CONTEXT_DEBUG_REGISTERS)
- mov rdx, dr0
- mov [rdi + CONTEXT_Dr0], rdx
- mov rdx, dr1
- mov [rdi + CONTEXT_Dr1], rdx
- mov rdx, dr2
- mov [rdi + CONTEXT_Dr2], rdx
- mov rdx, dr3
- mov [rdi + CONTEXT_Dr3], rdx
- mov rdx, dr6
- mov [rdi + CONTEXT_Dr6], rdx
- mov rdx, dr7
- mov [rdi + CONTEXT_Dr7], rdx
-LOCAL_LABEL(Done_CONTEXT_DEBUG_REGISTERS):
-
- free_stack 8
- ret
+ test BYTE PTR [eax + CONTEXT_ContextFlags], CONTEXT_EXTENDED_REGISTERS
+ je LOCAL_LABEL(Done_CONTEXT_EXTENDED_REGISTERS)
+ movdqu [eax + CONTEXT_Xmm0], xmm0
+ movdqu [eax + CONTEXT_Xmm1], xmm1
+ movdqu [eax + CONTEXT_Xmm2], xmm2
+ movdqu [eax + CONTEXT_Xmm3], xmm3
+ movdqu [eax + CONTEXT_Xmm4], xmm4
+ movdqu [eax + CONTEXT_Xmm5], xmm5
+ movdqu [eax + CONTEXT_Xmm6], xmm6
+ movdqu [eax + CONTEXT_Xmm7], xmm7
+LOCAL_LABEL(Done_CONTEXT_EXTENDED_REGISTERS):
+
+ // Restore
+ pop ebx
+ pop eax
+ ret 4
LEAF_END CONTEXT_CaptureContext, _TEXT
LEAF_ENTRY RtlCaptureContext, _TEXT
- mov DWORD PTR [rdi + CONTEXT_ContextFlags], (CONTEXT_AMD64 | CONTEXT_FULL | CONTEXT_SEGMENTS)
+ push eax
+ mov eax, [esp + 8]
+ mov DWORD PTR [eax + CONTEXT_ContextFlags], (CONTEXT_FLOATING_POINT)
+ pop eax
jmp C_FUNC(CONTEXT_CaptureContext)
LEAF_END RtlCaptureContext, _TEXT
LEAF_ENTRY RtlRestoreContext, _TEXT
- push_nonvol_reg rbp
- alloc_stack (IRetFrameLengthAligned)
-
- test BYTE PTR [rdi + CONTEXT_ContextFlags], CONTEXT_DEBUG_REGISTERS
- je LOCAL_LABEL(Done_Restore_CONTEXT_DEBUG_REGISTERS)
- mov rdx, [rdi + CONTEXT_Dr0]
- mov dr0, rdx
- mov rdx, [rdi + CONTEXT_Dr1]
- mov dr1, rdx
- mov rdx, [rdi + CONTEXT_Dr2]
- mov dr2, rdx
- mov rdx, [rdi + CONTEXT_Dr3]
- mov dr3, rdx
- mov rdx, [rdi + CONTEXT_Dr6]
- mov dr6, rdx
- mov rdx, [rdi + CONTEXT_Dr7]
- mov dr7, rdx
-LOCAL_LABEL(Done_Restore_CONTEXT_DEBUG_REGISTERS):
+ mov eax, [esp + 4]
- test BYTE PTR [rdi + CONTEXT_ContextFlags], CONTEXT_FLOATING_POINT
+ test BYTE PTR [eax + CONTEXT_ContextFlags], CONTEXT_FLOATING_POINT
je LOCAL_LABEL(Done_Restore_CONTEXT_FLOATING_POINT)
- fxrstor [rdi + CONTEXT_FltSave]
+ frstor [eax + CONTEXT_FloatSave]
LOCAL_LABEL(Done_Restore_CONTEXT_FLOATING_POINT):
- test BYTE PTR [rdi + CONTEXT_ContextFlags], CONTEXT_XSTATE
- je LOCAL_LABEL(Done_Restore_CONTEXT_XSTATE)
-
- // Restore the extended state (for now, this is just the upper halves of YMM registers)
- vinsertf128 ymm0, ymm0, xmmword ptr [rdi + (CONTEXT_VectorRegister + 0 * 16)], 1
- vinsertf128 ymm1, ymm1, xmmword ptr [rdi + (CONTEXT_VectorRegister + 1 * 16)], 1
- vinsertf128 ymm2, ymm2, xmmword ptr [rdi + (CONTEXT_VectorRegister + 2 * 16)], 1
- vinsertf128 ymm3, ymm3, xmmword ptr [rdi + (CONTEXT_VectorRegister + 3 * 16)], 1
- vinsertf128 ymm4, ymm4, xmmword ptr [rdi + (CONTEXT_VectorRegister + 4 * 16)], 1
- vinsertf128 ymm5, ymm5, xmmword ptr [rdi + (CONTEXT_VectorRegister + 5 * 16)], 1
- vinsertf128 ymm6, ymm6, xmmword ptr [rdi + (CONTEXT_VectorRegister + 6 * 16)], 1
- vinsertf128 ymm7, ymm7, xmmword ptr [rdi + (CONTEXT_VectorRegister + 7 * 16)], 1
- vinsertf128 ymm8, ymm8, xmmword ptr [rdi + (CONTEXT_VectorRegister + 8 * 16)], 1
- vinsertf128 ymm9, ymm9, xmmword ptr [rdi + (CONTEXT_VectorRegister + 9 * 16)], 1
- vinsertf128 ymm10, ymm10, xmmword ptr [rdi + (CONTEXT_VectorRegister + 10 * 16)], 1
- vinsertf128 ymm11, ymm11, xmmword ptr [rdi + (CONTEXT_VectorRegister + 11 * 16)], 1
- vinsertf128 ymm12, ymm12, xmmword ptr [rdi + (CONTEXT_VectorRegister + 12 * 16)], 1
- vinsertf128 ymm13, ymm13, xmmword ptr [rdi + (CONTEXT_VectorRegister + 13 * 16)], 1
- vinsertf128 ymm14, ymm14, xmmword ptr [rdi + (CONTEXT_VectorRegister + 14 * 16)], 1
- vinsertf128 ymm15, ymm15, xmmword ptr [rdi + (CONTEXT_VectorRegister + 15 * 16)], 1
-LOCAL_LABEL(Done_Restore_CONTEXT_XSTATE):
-
- test BYTE PTR [rdi + CONTEXT_ContextFlags], CONTEXT_CONTROL
- je LOCAL_LABEL(Done_Restore_CONTEXT_CONTROL)
-
- // The control registers are restored via the iret instruction
- // so we build the frame for the iret on the stack.
-#ifdef __APPLE__
-.att_syntax
- // On OSX, we cannot read SS via the thread_get_context and RtlRestoreContext
- // needs to be used on context extracted by thread_get_context. So we
- // don't change the SS.
- mov %ss, %ax
-.intel_syntax noprefix
-#else
- mov ax, [rdi + CONTEXT_SegSs]
-#endif
- mov [rsp + IRETFRAME_SegSs], ax
- mov rax, [rdi + CONTEXT_Rsp]
- mov [rsp + IRETFRAME_Rsp], rax
- mov eax, [rdi + CONTEXT_EFlags]
- mov [rsp + IRETFRAME_EFlags], eax
- mov ax, [rdi + CONTEXT_SegCs]
- mov [rsp + IRETFRAME_SegCs], ax
- mov rax, [rdi + CONTEXT_Rip]
- mov [rsp + IRETFRAME_Rip], rax
-
-LOCAL_LABEL(Done_Restore_CONTEXT_CONTROL):
- // Remember the result of the test for the CONTEXT_CONTROL
- push_eflags
- test BYTE PTR [rdi + CONTEXT_ContextFlags], CONTEXT_INTEGER
- je LOCAL_LABEL(Done_Restore_CONTEXT_INTEGER)
- mov rsi, [rdi + CONTEXT_Rsi]
- mov rbx, [rdi + CONTEXT_Rbx]
- mov rdx, [rdi + CONTEXT_Rdx]
- mov rcx, [rdi + CONTEXT_Rcx]
- mov rax, [rdi + CONTEXT_Rax]
- mov rbp, [rdi + CONTEXT_Rbp]
- mov r8, [rdi + CONTEXT_R8]
- mov r9, [rdi + CONTEXT_R9]
- mov r10, [rdi + CONTEXT_R10]
- mov r11, [rdi + CONTEXT_R11]
- mov r12, [rdi + CONTEXT_R12]
- mov r13, [rdi + CONTEXT_R13]
- mov r14, [rdi + CONTEXT_R14]
- mov r15, [rdi + CONTEXT_R15]
- mov rdi, [rdi + CONTEXT_Rdi]
-LOCAL_LABEL(Done_Restore_CONTEXT_INTEGER):
-
- // Restore the result of the test for the CONTEXT_CONTROL
- pop_eflags
- je LOCAL_LABEL(No_Restore_CONTEXT_CONTROL)
- // The function was asked to restore the control registers, so
- // we perform iretq that restores them all.
- // We don't return to the caller in this case.
- iretq
-LOCAL_LABEL(No_Restore_CONTEXT_CONTROL):
-
- // The function was not asked to restore the control registers
- // so we return back to the caller.
- free_stack (IRetFrameLengthAligned)
- pop_nonvol_reg rbp
- ret
+ test BYTE PTR [eax + CONTEXT_ContextFlags], CONTEXT_EXTENDED_REGISTERS
+ je LOCAL_LABEL(Done_Restore_CONTEXT_EXTENDED_REGISTERS)
+ movdqu xmm0, [eax + CONTEXT_Xmm0]
+ movdqu xmm1, [eax + CONTEXT_Xmm1]
+ movdqu xmm2, [eax + CONTEXT_Xmm2]
+ movdqu xmm3, [eax + CONTEXT_Xmm3]
+ movdqu xmm4, [eax + CONTEXT_Xmm4]
+ movdqu xmm5, [eax + CONTEXT_Xmm5]
+ movdqu xmm6, [eax + CONTEXT_Xmm6]
+ movdqu xmm7, [eax + CONTEXT_Xmm7]
+LOCAL_LABEL(Done_Restore_CONTEXT_EXTENDED_REGISTERS):
+
+ // Restore CONTROL register(s)
+ mov ecx, [eax + CONTEXT_Eip]
+ mov [esp], ecx
+
+ mov ecx, [eax + CONTEXT_Esp]
+ push ecx
+ mov ecx, [eax + CONTEXT_Ebp]
+ push ecx
+
+ pop ebp
+ pop esp
+
+ // Restore INTEGER register(s)
+ mov ecx, [eax + CONTEXT_Edi]
+ push ecx
+ mov ecx, [eax + CONTEXT_Esi]
+ push ecx
+ mov ecx, [eax + CONTEXT_Edx]
+ push ecx
+ mov ecx, [eax + CONTEXT_Ecx]
+ push ecx
+ mov ecx, [eax + CONTEXT_Ebx]
+ push ecx
+ mov ecx, [eax + CONTEXT_Eax]
+ push ecx
+
+ pop eax
+ pop ebx
+ pop ecx
+ pop edx
+ pop esi
+ pop edi
+
+ ret 8
LEAF_END RtlRestoreContext, _TEXT
-#else
-
- .globl C_FUNC(CONTEXT_CaptureContext)
-C_FUNC(CONTEXT_CaptureContext):
- push %eax
- mov 8(%esp), %eax
- mov %edi, CONTEXT_Edi(%eax)
- mov %esi, CONTEXT_Esi(%eax)
- mov %ebx, CONTEXT_Ebx(%eax)
- mov %edx, CONTEXT_Edx(%eax)
- mov %ecx, CONTEXT_Ecx(%eax)
- pop %ecx
- mov %ecx, CONTEXT_Eax(%eax)
- mov %ebp, CONTEXT_Ebp(%eax)
- mov (%esp), %edx
- mov %edx, CONTEXT_Eip(%eax)
- push %cs
- pop %edx
- mov %edx, CONTEXT_SegCs(%eax)
- pushf
- pop %edx
- mov %edx, CONTEXT_EFlags(%eax)
- lea 4(%esp), %edx
- mov %edx, CONTEXT_Esp(%eax)
- push %ss
- pop %edx
- mov %edx, CONTEXT_SegSs(%eax)
- testb $CONTEXT_FLOATING_POINT, CONTEXT_ContextFlags(%eax)
- je 0f
- fnsave CONTEXT_FloatSave(%eax)
- frstor CONTEXT_FloatSave(%eax)
-0:
- testb $CONTEXT_EXTENDED_REGISTERS, CONTEXT_ContextFlags(%eax)
- je 2f
- movdqu %xmm0, CONTEXT_Xmm0(%eax)
- movdqu %xmm1, CONTEXT_Xmm1(%eax)
- movdqu %xmm2, CONTEXT_Xmm2(%eax)
- movdqu %xmm3, CONTEXT_Xmm3(%eax)
- movdqu %xmm4, CONTEXT_Xmm4(%eax)
- movdqu %xmm5, CONTEXT_Xmm5(%eax)
- movdqu %xmm6, CONTEXT_Xmm6(%eax)
- movdqu %xmm7, CONTEXT_Xmm7(%eax)
-2:
- ret
-
-#endif
diff --git a/src/pal/src/arch/i386/exceptionhelper.S b/src/pal/src/arch/i386/exceptionhelper.S
index b7b34ace41..2061be26f8 100644
--- a/src/pal/src/arch/i386/exceptionhelper.S
+++ b/src/pal/src/arch/i386/exceptionhelper.S
@@ -8,35 +8,36 @@
//////////////////////////////////////////////////////////////////////////
//
-// This function creates a stack frame right below the target frame, restores all callee
-// saved registers from the passed in context, sets the RSP to that frame and sets the
-// return address to the target frame's RIP.
-// Then it uses the ThrowExceptionHelper to throw the passed in exception from that context.
// EXTERN_C void ThrowExceptionFromContextInternal(CONTEXT* context, PAL_SEHException* ex);
+//
+// This function creates a stack frame right below the target frame, restores all callee
+// saved registers from the passed in context, sets the SP to that frame and sets the
+// return address to the target frame's IP.
+// Then it uses the ThrowExceptionHelper to throw the passed in exception from that context.
+//
+//////////////////////////////////////////////////////////////////////////
+
LEAF_ENTRY ThrowExceptionFromContextInternal, _TEXT
- // Save the RBP to the stack so that the unwind can work at the instruction after
- // loading the RBP from the context, but before loading the RSP from the context.
- push_nonvol_reg rbp
- mov r12, [rdi + CONTEXT_R12]
- mov r13, [rdi + CONTEXT_R13]
- mov r14, [rdi + CONTEXT_R14]
- mov r15, [rdi + CONTEXT_R15]
- mov rbx, [rdi + CONTEXT_Rbx]
- mov rbp, [rdi + CONTEXT_Rbp]
- mov rsp, [rdi + CONTEXT_Rsp]
- // The RSP was set to the target frame's value, so the current function's
- // CFA is now right at the RSP.
+ push ebp
+ mov eax, [esp + 12] // ebx: PAL_SEHException *
+ mov ebx, [esp + 8] // eax: CONTEXT *
+
+ mov ebp, [ebx + CONTEXT_Ebp]
+ mov esp, [ebx + CONTEXT_Esp]
+
+ // The ESP is re-initialized as the target frame's value, so the current function's
+ // CFA is now right at the ESP.
.cfi_def_cfa_offset 0
- // Indicate that now that we have moved the RSP to the target address,
- // the RBP is no longer saved in the current stack frame.
- .cfi_restore rbp
+ // Indicate that now that we have moved the RSP to the target address,
+ // the EBP is no longer saved in the current stack frame.
+ .cfi_restore ebp
- mov rax, [rdi + CONTEXT_Rip]
+ // Store PAL_SEHException as the first argument
+ push eax
// Store return address to the stack
- push_register rax
- // The PAL_SEHException pointer
- mov rdi, rsi
+ mov ebx, [ebx + CONTEXT_Eip]
+ push ebx
jmp EXTERNAL_C_FUNC(ThrowExceptionHelper)
LEAF_END ThrowExceptionFromContextInternal, _TEXT
diff --git a/src/pal/src/arch/i386/optimizedtls.cpp b/src/pal/src/arch/i386/optimizedtls.cpp
deleted file mode 100644
index 910a6eb931..0000000000
--- a/src/pal/src/arch/i386/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/i386/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/config.h.in b/src/pal/src/config.h.in
index 7a53c8cb5d..4d21fb70e4 100644
--- a/src/pal/src/config.h.in
+++ b/src/pal/src/config.h.in
@@ -43,7 +43,6 @@
#cmakedefine01 HAVE_LOCALTIME_R
#cmakedefine01 HAVE_GMTIME_R
#cmakedefine01 HAVE_TIMEGM
-#cmakedefine01 HAVE__SNWPRINTF
#cmakedefine01 HAVE_POLL
#cmakedefine01 HAVE_STATVFS
#cmakedefine01 HAVE_THREAD_SELF
diff --git a/src/pal/src/configure.cmake b/src/pal/src/configure.cmake
index cc38bc8541..a53e0db51e 100644
--- a/src/pal/src/configure.cmake
+++ b/src/pal/src/configure.cmake
@@ -13,7 +13,7 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL SunOS)
set(CMAKE_REQUIRED_INCLUDES /opt/local/include)
endif()
if(NOT CMAKE_SYSTEM_NAME STREQUAL Darwin AND NOT CMAKE_SYSTEM_NAME STREQUAL FreeBSD AND NOT CMAKE_SYSTEM_NAME STREQUAL NetBSD)
- set(CMAKE_REQUIRED_DEFINITIONS "-D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200809L")
+ set(CMAKE_REQUIRED_DEFINITIONS "-D_BSD_SOURCE -D_SVID_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200809L")
endif()
list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_FILE_OFFSET_BITS=64)
@@ -33,7 +33,15 @@ check_include_files(sys/lwp.h HAVE_SYS_LWP_H)
check_include_files(lwp.h HAVE_LWP_H)
check_include_files(libunwind.h HAVE_LIBUNWIND_H)
check_include_files(runetype.h HAVE_RUNETYPE_H)
+
+if(NOT CMAKE_SYSTEM_NAME STREQUAL FreeBSD AND NOT CMAKE_SYSTEM_NAME STREQUAL NetBSD)
+ set(CMAKE_REQUIRED_FLAGS "-ldl")
+endif()
check_include_files(lttng/tracepoint.h HAVE_LTTNG_TRACEPOINT_H)
+if(NOT CMAKE_SYSTEM_NAME STREQUAL FreeBSD AND NOT CMAKE_SYSTEM_NAME STREQUAL NetBSD)
+ unset(CMAKE_REQUIRED_FLAGS)
+endif()
+
check_include_files(uuid/uuid.h HAVE_LIBUUID_H)
check_include_files(sys/sysctl.h HAVE_SYS_SYSCTL_H)
check_include_files(gnu/lib-names.h HAVE_GNU_LIBNAMES_H)
@@ -62,7 +70,6 @@ check_function_exists(sysconf HAVE_SYSCONF)
check_function_exists(localtime_r HAVE_LOCALTIME_R)
check_function_exists(gmtime_r HAVE_GMTIME_R)
check_function_exists(timegm HAVE_TIMEGM)
-check_function_exists(_snwprintf HAVE__SNWPRINTF)
check_function_exists(poll HAVE_POLL)
check_function_exists(statvfs HAVE_STATVFS)
check_function_exists(thread_self HAVE_THREAD_SELF)
diff --git a/src/pal/src/cruntime/lstr.cpp b/src/pal/src/cruntime/lstr.cpp
index 2267d8491b..4502b025aa 100644
--- a/src/pal/src/cruntime/lstr.cpp
+++ b/src/pal/src/cruntime/lstr.cpp
@@ -24,141 +24,6 @@ Abstract:
SET_DEFAULT_DEBUG_CHANNEL(CRT);
-
-/*++
-Function:
- lstrcatW
-
-The lstrcat function appends one string to another.
-
-Parameters
-
-lpString1 [in/out] Pointer to a null-terminated string. The buffer must be large
- enough to contain both strings.
-lpString2 [in] Pointer to the null-terminated string to be appended to the
- string specified in the lpString1 parameter.
-
-Return Values
-
-If the function succeeds, the return value is a pointer to the buffer.
-If the function fails, the return value is NULL.
-
---*/
-LPWSTR
-PALAPI
-lstrcatW(
- IN OUT LPWSTR lpString1,
- IN LPCWSTR lpString2)
-{
- LPWSTR lpStart = lpString1;
-
- PERF_ENTRY(lstrcatW);
- ENTRY("lstrcatW (lpString1=%p (%S), lpString2=%p (%S))\n",
- lpString1?lpString1:W16_NULLSTRING,
- lpString1?lpString1:W16_NULLSTRING, lpString2?lpString2:W16_NULLSTRING, lpString2?lpString2:W16_NULLSTRING);
-
- if (lpString1 == NULL)
- {
- ERROR("invalid lpString1 argument\n");
- LOGEXIT("lstrcatW returning LPWSTR NULL\n");
- PERF_EXIT(lstrcatW);
- return NULL;
- }
-
- if (lpString2 == NULL)
- {
- ERROR("invalid lpString2 argument\n");
- LOGEXIT("lstrcatW returning LPWSTR NULL\n");
- PERF_EXIT(lstrcatW);
- return NULL;
- }
-
- /* find end of source string */
- while (*lpString1)
- {
- lpString1++;
- }
-
- /* concatenate new string */
- while(*lpString2)
- {
- *lpString1++ = *lpString2++;
- }
-
- /* add terminating null */
- *lpString1 = '\0';
-
- LOGEXIT("lstrcatW returning LPWSTR %p (%S)\n", lpStart, lpStart);
- PERF_EXIT(lstrcatW);
- return lpStart;
-}
-
-
-/*++
-Function:
- lstrcpyW
-
-The lstrcpy function copies a string to a buffer.
-
-To copy a specified number of characters, use the lstrcpyn function.
-
-Parameters
-
-lpString1 [out] Pointer to a buffer to receive the contents of the string pointed
- to by the lpString2 parameter. The buffer must be large enough to
- contain the string, including the terminating null character.
-
-lpString2 [in] Pointer to the null-terminated string to be copied.
-
-Return Values
-
-If the function succeeds, the return value is a pointer to the buffer.
-If the function fails, the return value is NULL.
-
---*/
-LPWSTR
-PALAPI
-lstrcpyW(
- OUT LPWSTR lpString1,
- IN LPCWSTR lpString2)
-{
- LPWSTR lpStart = lpString1;
-
- PERF_ENTRY(lstrcpyW);
- ENTRY("lstrcpyW (lpString1=%p, lpString2=%p (%S))\n",
- lpString1?lpString1:W16_NULLSTRING, lpString2?lpString2:W16_NULLSTRING, lpString2?lpString2:W16_NULLSTRING);
-
- if (lpString1 == NULL)
- {
- ERROR("invalid lpString1 argument\n");
- LOGEXIT("lstrcpyW returning LPWSTR NULL\n");
- PERF_EXIT(lstrcpyW);
- return NULL;
- }
-
- if (lpString2 == NULL)
- {
- ERROR("invalid lpString2 argument\n");
- LOGEXIT("lstrcpyW returning LPWSTR NULL\n");
- PERF_EXIT(lstrcpyW);
- return NULL;
- }
-
- /* copy source string to destination string */
- while(*lpString2)
- {
- *lpString1++ = *lpString2++;
- }
-
- /* add terminating null */
- *lpString1 = '\0';
-
- LOGEXIT("lstrcpyW returning LPWSTR %p (%S)\n", lpStart, lpStart);
- PERF_EXIT(lstrcpyW);
- return lpStart;
-}
-
-
/*++
Function:
lstrlenA
@@ -239,78 +104,3 @@ lstrlenW(
PERF_EXIT(lstrlenW);
return nChar;
}
-
-
-/*++
-Function:
- lstrcpynW
-
-The lstrcpyn function copies a specified number of characters from a
-source string into a buffer.
-
-Parameters
-
-lpString1 [out] Pointer to a buffer into which the function copies characters.
- The buffer must be large enough to contain the number of TCHARs
- specified by iMaxLength, including room for a terminating null character.
-lpString2 [in] Pointer to a null-terminated string from which the function copies
- characters.
-iMaxLength [in] Specifies the number of TCHARs to be copied from the string pointed
- to by lpString2 into the buffer pointed to by lpString1, including a
- terminating null character.
-
-Return Values
-
-If the function succeeds, the return value is a pointer to the buffer.
-If the function fails, the return value is NULL.
-
---*/
-LPWSTR
-PALAPI
-lstrcpynW(
- OUT LPWSTR lpString1,
- IN LPCWSTR lpString2,
- IN int iMaxLength)
-{
- LPWSTR lpStart = lpString1;
-
- PERF_ENTRY(lstrcpynW);
- ENTRY("lstrcpynW (lpString1=%p, lpString2=%p (%S), iMaxLength=%d)\n",
- lpString1?lpString1:W16_NULLSTRING, lpString2?lpString2:W16_NULLSTRING, lpString2?lpString2:W16_NULLSTRING, iMaxLength);
-
- if (lpString1 == NULL)
- {
- ERROR("invalid lpString1 argument\n");
- LOGEXIT("lstrcpynW returning LPWSTR NULL\n");
- PERF_EXIT(lstrcpynW);
- return NULL;
- }
-
- if (lpString2 == NULL)
- {
- ERROR("invalid lpString2 argument\n");
- LOGEXIT("lstrcpynW returning LPWSTR NULL\n");
- PERF_EXIT(lstrcpynW);
- return NULL;
- }
-
- /* copy source string to destination string */
- while(iMaxLength > 1 && *lpString2)
- {
- *lpString1++ = *lpString2++;
- iMaxLength--;
- }
-
- /* add terminating null */
- if (iMaxLength > 0)
- {
- *lpString1 = '\0';
- }
-
- LOGEXIT("lstrcpynW returning LPWSTR %p (%S)\n", lpStart, lpStart);
- PERF_EXIT(lstrcpynW);
- return lpStart;
-
-}
-
-
diff --git a/src/pal/src/cruntime/math.cpp b/src/pal/src/cruntime/math.cpp
index 7075fd60f9..08f4192998 100644
--- a/src/pal/src/cruntime/math.cpp
+++ b/src/pal/src/cruntime/math.cpp
@@ -35,6 +35,12 @@ Abstract:
#define IS_DBL_NEGZERO(x) (((*((INT64*)((void*)&x))) & I64(0xFFFFFFFFFFFFFFFF)) == I64(0x8000000000000000))
+#define PAL_NAN_FLT sqrtf(-1.0f)
+#define PAL_POSINF_FLT -logf(0.0f)
+#define PAL_NEGINF_FLT logf(0.0f)
+
+#define IS_FLT_NEGZERO(x) (((*((INT32*)((void*)&x))) & 0xFFFFFFFF) == 0x80000000)
+
SET_DEFAULT_DEBUG_CHANNEL(CRT);
/*++
@@ -422,3 +428,364 @@ PALIMPORT double __cdecl PAL_pow(double x, double y)
PERF_EXIT(pow);
return ret;
}
+
+/*++
+Function:
+ _finitef
+
+Determines whether given single-precision floating point value is finite.
+
+Return Value
+
+_finitef returns a nonzero value (TRUE) if its argument x is not
+infinite, that is, if -INF < x < +INF. It returns 0 (FALSE) if the
+argument is infinite or a NaN.
+
+Parameter
+
+x Single-precision floating-point value
+
+--*/
+int __cdecl _finitef(float x)
+{
+ int ret;
+ PERF_ENTRY(_finitef);
+ ENTRY("_finitef (x=%f)\n", x);
+
+#if defined(_IA64_) && defined (_HPUX_)
+ ret = !isnan(x) && (x != PAL_POSINF_FLT) && (x != PAL_NEGINF_FLT);
+#else
+ ret = isfinite(x);
+#endif
+
+ LOGEXIT("_finitef returns int %d\n", ret);
+ PERF_EXIT(_finitef);
+ return ret;
+}
+
+/*++
+Function:
+ _isnanf
+
+See MSDN doc
+--*/
+int __cdecl _isnanf(float x)
+{
+ int ret;
+ PERF_ENTRY(_isnanf);
+ ENTRY("_isnanf (x=%f)\n", x);
+
+ ret = isnan(x);
+
+ LOGEXIT("_isnanf returns int %d\n", ret);
+ PERF_EXIT(_isnanf);
+ return ret;
+}
+
+/*++
+Function:
+ _copysignf
+
+See MSDN doc
+--*/
+float __cdecl _copysignf(float x, float y)
+{
+ float ret;
+ PERF_ENTRY(_copysignf);
+ ENTRY("_copysignf (x=%f, y=%f)\n", x, y);
+
+ ret = copysign(x, y);
+
+ LOGEXIT("_copysignf returns float %f\n", ret);
+ PERF_EXIT(_copysignf);
+ return ret;
+}
+
+/*++
+Function:
+ acosf
+
+See MSDN.
+--*/
+PALIMPORT float __cdecl PAL_acosf(float x)
+{
+ float ret;
+ PERF_ENTRY(acosf);
+ ENTRY("acosf (x=%f)\n", x);
+
+#if !HAVE_COMPATIBLE_ACOS
+ errno = 0;
+#endif // HAVE_COMPATIBLE_ACOS
+
+ ret = acosf(x);
+
+#if !HAVE_COMPATIBLE_ACOS
+ if (errno == EDOM)
+ {
+ ret = PAL_NAN_FLT; // NaN
+ }
+#endif // HAVE_COMPATIBLE_ACOS
+
+ LOGEXIT("acosf returns float %f\n", ret);
+ PERF_EXIT(acosf);
+ return ret;
+}
+
+/*++
+Function:
+ asinf
+
+See MSDN.
+--*/
+PALIMPORT float __cdecl PAL_asinf(float x)
+{
+ float ret;
+ PERF_ENTRY(asinf);
+ ENTRY("asinf (x=%f)\n", x);
+
+#if !HAVE_COMPATIBLE_ASIN
+ errno = 0;
+#endif // HAVE_COMPATIBLE_ASIN
+
+ ret = asinf(x);
+
+#if !HAVE_COMPATIBLE_ASIN
+ if (errno == EDOM)
+ {
+ ret = PAL_NAN_FLT; // NaN
+ }
+#endif // HAVE_COMPATIBLE_ASIN
+
+ LOGEXIT("asinf returns float %f\n", ret);
+ PERF_EXIT(asinf);
+ return ret;
+}
+
+/*++
+Function:
+ atan2f
+
+See MSDN.
+--*/
+PALIMPORT float __cdecl PAL_atan2f(float y, float x)
+{
+ float ret;
+ PERF_ENTRY(atan2f);
+ ENTRY("atan2f (y=%f, x=%f)\n", y, x);
+
+#if !HAVE_COMPATIBLE_ATAN2
+ errno = 0;
+#endif // !HAVE_COMPATIBLE_ATAN2
+
+ ret = atan2f(y, x);
+
+#if !HAVE_COMPATIBLE_ATAN2
+ if ((errno == EDOM) && (x == 0.0f) && (y == 0.0f))
+ {
+ const float sign_x = copysign(1.0f, x);
+ const float sign_y = copysign(1.0f, y);
+
+ if (sign_x > 0)
+ {
+ ret = copysign(0.0f, sign_y);
+ }
+ else
+ {
+ ret = copysign(atan2f(0.0f, -1.0f), sign_y);
+ }
+ }
+#endif // !HAVE_COMPATIBLE_ATAN2
+
+ LOGEXIT("atan2f returns float %f\n", ret);
+ PERF_EXIT(atan2f);
+ return ret;
+}
+
+/*++
+Function:
+ expf
+
+See MSDN.
+--*/
+PALIMPORT float __cdecl PAL_expf(float x)
+{
+ float ret;
+ PERF_ENTRY(expf);
+ ENTRY("expf (x=%f)\n", x);
+
+#if !HAVE_COMPATIBLE_EXP
+ if (x == 1.0f)
+ {
+ ret = M_E;
+ }
+ else
+ {
+#endif // HAVE_COMPATIBLE_EXP
+
+ ret = expf(x);
+
+#if !HAVE_COMPATIBLE_EXP
+ }
+#endif // HAVE_COMPATIBLE_EXP
+
+ LOGEXIT("expf returns float %f\n", ret);
+ PERF_EXIT(expf);
+ return ret;
+}
+
+/*++
+Function:
+ logf
+
+See MSDN.
+--*/
+PALIMPORT float __cdecl PAL_logf(float x)
+{
+ float ret;
+ PERF_ENTRY(logf);
+ ENTRY("logf (x=%f)\n", x);
+
+#if !HAVE_COMPATIBLE_LOG
+ errno = 0;
+#endif // !HAVE_COMPATIBLE_LOG
+
+ ret = logf(x);
+
+#if !HAVE_COMPATIBLE_LOG
+ if ((errno == EDOM) && (x < 0))
+ {
+ ret = PAL_NAN_FLT; // NaN
+ }
+#endif // !HAVE_COMPATIBLE_LOG
+
+ LOGEXIT("logf returns float %f\n", ret);
+ PERF_EXIT(logf);
+ return ret;
+}
+
+/*++
+Function:
+ log10f
+
+See MSDN.
+--*/
+PALIMPORT float __cdecl PAL_log10f(float x)
+{
+ float ret;
+ PERF_ENTRY(log10f);
+ ENTRY("log10f (x=%f)\n", x);
+
+#if !HAVE_COMPATIBLE_LOG10
+ errno = 0;
+#endif // !HAVE_COMPATIBLE_LOG10
+
+ ret = log10f(x);
+
+#if !HAVE_COMPATIBLE_LOG10
+ if ((errno == EDOM) && (x < 0))
+ {
+ ret = PAL_NAN_FLT; // NaN
+ }
+#endif // !HAVE_COMPATIBLE_LOG10
+
+ LOGEXIT("log10f returns float %f\n", ret);
+ PERF_EXIT(log10f);
+ return ret;
+}
+
+/*++
+Function:
+ powf
+
+See MSDN.
+--*/
+PALIMPORT float __cdecl PAL_powf(float x, float y)
+{
+ float ret;
+ PERF_ENTRY(powf);
+ ENTRY("powf (x=%f, y=%f)\n", x, y);
+
+#if !HAVE_COMPATIBLE_POW
+ if ((y == PAL_POSINF_FLT) && !isnan(x)) // +Inf
+ {
+ if (x == 1.0f)
+ {
+ ret = x;
+ }
+ else if (x == -1.0f)
+ {
+ ret = PAL_NAN_FLT; // NaN
+ }
+ else if ((x > -1.0f) && (x < 1.0f))
+ {
+ ret = 0.0f;
+ }
+ else
+ {
+ ret = PAL_POSINF_FLT; // +Inf
+ }
+ }
+ else if ((y == PAL_NEGINF_FLT) && !isnan(x)) // -Inf
+ {
+ if (x == 1.0f)
+ {
+ ret = x;
+ }
+ else if (x == -1.0f)
+ {
+ ret = PAL_NAN_FLT; // NaN
+ }
+ else if ((x > -1.0f) && (x < 1.0f))
+ {
+ ret = PAL_POSINF_FLT; // +Inf
+ }
+ else
+ {
+ ret = 0.0f;
+ }
+ }
+ else if (IS_FLT_NEGZERO(x) && (y == -1.0f))
+ {
+ ret = PAL_NEGINF_FLT; // -Inf
+ }
+ else if ((x == 0.0f) && (y < 0.0f))
+ {
+ ret = PAL_POSINF_FLT; // +Inf
+ }
+ 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);
+ }
+
+#if !HAVE_VALID_NEGATIVE_INF_POW
+ if ((ret == PAL_POSINF_FLT) && (x < 0) && isfinite(x) && (ceilf(y / 2) != floorf(y / 2)))
+ {
+ ret = PAL_NEGINF_FLT; // -Inf
+ }
+#endif // !HAVE_VALID_NEGATIVE_INF_POW
+
+#if !HAVE_VALID_POSITIVE_INF_POW
+ /*
+ * The (ceil(y/2) == floor(y/2)) test is slower, but more robust for platforms where large y
+ * will return the wrong result for ((long) y % 2 == 0). See PAL_pow(double) above for more details.
+ */
+ if ((ret == PAL_NEGINF_FLT) && (x < 0) && isfinite(x) && (ceilf(y / 2) == floorf(y / 2)))
+ {
+ ret = PAL_POSINF_FLT; // +Inf
+ }
+#endif // !HAVE_VALID_POSITIVE_INF_POW
+
+ LOGEXIT("powf returns float %f\n", ret);
+ PERF_EXIT(powf);
+ return ret;
+}
diff --git a/src/pal/src/cruntime/mbstring.cpp b/src/pal/src/cruntime/mbstring.cpp
index dd4bcbbdce..ace2aa56c6 100644
--- a/src/pal/src/cruntime/mbstring.cpp
+++ b/src/pal/src/cruntime/mbstring.cpp
@@ -37,60 +37,6 @@ SET_DEFAULT_DEBUG_CHANNEL(CRT);
/*++
Function:
- _mbslen
-
-Determines the number of characters (code points) in a multibyte
-character string.
-
-Parameters
-
-string Points to a multibyte character string.
-
-Return Values
-
-The mbslen subroutine returns the number of multibyte characters in a
-multibyte character string. It returns 0 if the string parameter
-points to a null character or if a character cannot be formed from the
-string pointed to by this parameter.
-
---*/
-size_t
-__cdecl
-_mbslen(
- const unsigned char *string)
-{
- size_t ret = 0;
- CPINFO cpinfo;
- PERF_ENTRY(_mbslen);
- ENTRY("_mbslen (string=%p (%s))\n", string, string);
-
- if (string)
- {
- if (GetCPInfo(CP_ACP, &cpinfo) && cpinfo.MaxCharSize == 1)
- {
- ret = strlen((const char*)string);
- }
- else
- {
- while (*string)
- {
- if (IsDBCSLeadByteEx(CP_ACP, *string))
- {
- ++string;
- }
- ++string;
- ++ret;
- }
- }
- }
-
- LOGEXIT("_mbslen returning size_t %u\n", ret);
- PERF_EXIT(_mbslen);
- return ret;
-}
-
-/*++
-Function:
_mbsinc
Return Value
diff --git a/src/pal/src/cruntime/path.cpp b/src/pal/src/cruntime/path.cpp
index e5b955ebd9..4925af5b89 100644
--- a/src/pal/src/cruntime/path.cpp
+++ b/src/pal/src/cruntime/path.cpp
@@ -33,488 +33,6 @@ Revision History:
SET_DEFAULT_DEBUG_CHANNEL(CRT);
-
-/* ON_ERROR. A Helper macro for _?splitpath functions. */
-#define ON_ERROR if ( drive ) \
- {\
- drive[0] = 0;\
- }\
- if(dir)\
- {\
- dir[0] = 0;\
- }\
- if(fname)\
- {\
- fname[0] = 0;\
- }\
- if(ext)\
- {\
- ext[0] = 0;\
- }\
- goto done;\
-
-/*++
-Function:
- _wsplitpath
-
-See MSDN doc.
-
-Notes :
- This implementation ignores drive letters as they should not be
- present. If the drive argument is non-NULL, it always returns an empty
- string.
- File names in which the only period is at the beginning (like .bashrc, but
- not .bashrc.bak), the file is treated as having no extension
- (fname is ".bashrc", ext is "")
-
---*/
-void
-__cdecl
-_wsplitpath(
- const wchar_16 *dospath,
- wchar_16 *drive,
- wchar_16 *dir,
- wchar_16 *fname,
- wchar_16 *ext)
-{
- WCHAR path[_MAX_PATH+1];
- LPCWSTR slash_ptr = NULL;
- LPCWSTR period_ptr = NULL;
- INT size = 0;
-
- PERF_ENTRY(_wsplitpath);
- ENTRY("_wsplitpath (path=%p (%S), drive=%p, dir=%p, fname=%p, ext=%p)\n",
- dospath?dospath:W16_NULLSTRING,
- dospath?dospath:W16_NULLSTRING, drive, dir, fname, ext);
-
- /* Do performance intensive error checking only in debug builds.
-
- NOTE: This function must fail predictably across all platforms.
- Under Windows this function throw an access violation if NULL
- was passed in as the value for path.
-
- */
-#if _DEBUG
- if ( !dospath )
- {
- ERROR( "path cannot be NULL!\n" );
- }
-#endif
-
- if( lstrlenW( dospath ) >= _MAX_PATH )
- {
- ERROR("Path length is > _MAX_PATH (%d)!\n", _MAX_PATH);
- ON_ERROR;
- }
-
-
- PAL_wcscpy(path, dospath);
- FILEDosToUnixPathW(path);
-
- /* no drive letters in the PAL */
- if( drive != NULL )
- {
- drive[0] = 0;
- }
-
- /* find last path separator char */
- slash_ptr = PAL_wcsrchr(path, '/');
-
- if( slash_ptr == NULL )
- {
- TRACE("No path separator in path\n");
- slash_ptr = path - 1;
- }
- /* find extension separator, if any */
- period_ptr = PAL_wcsrchr(path, '.');
-
- /* make sure we only consider periods after the last path separator */
- if( period_ptr < slash_ptr )
- {
- period_ptr = NULL;
- }
-
- /* if the only period in the file is a leading period (denoting a hidden
- file), don't treat what follows as an extension */
- if( period_ptr == slash_ptr+1 )
- {
- period_ptr = NULL;
- }
-
- if( period_ptr == NULL )
- {
- TRACE("No extension in path\n");
- period_ptr = path + lstrlenW(path);
- }
-
- size = slash_ptr - path + 1;
- if( dir != NULL )
- {
- INT i;
-
- if( (size + 1 ) > _MAX_DIR )
- {
- ERROR("Directory component needs %d characters, _MAX_DIR is %d\n",
- size+1, _MAX_DIR);
- ON_ERROR;
- }
-
- memcpy(dir, path, size*sizeof(WCHAR));
- dir[size] = 0;
-
- /* only allow / separators in returned path */
- i = 0;
- while( dir[ i ] )
- {
- if( dir[ i ] == '\\' )
- {
- dir[i]='/';
- }
- i++;
- }
- }
-
- size = period_ptr-slash_ptr-1;
- if( fname != NULL )
- {
- if( (size+1) > _MAX_FNAME )
- {
- ERROR("Filename component needs %d characters, _MAX_FNAME is %d\n",
- size+1, _MAX_FNAME);
- ON_ERROR;
- }
- memcpy(fname, slash_ptr+1, size*sizeof(WCHAR));
- fname[size] = 0;
- }
-
- size = 1 + lstrlenW( period_ptr );
- if( ext != NULL )
- {
- if( size > _MAX_EXT )
- {
- ERROR("Extension component needs %d characters, _MAX_EXT is %d\n",
- size, _MAX_EXT);
- ON_ERROR;
- }
- memcpy(ext, period_ptr, size*sizeof(WCHAR));
- ext[size-1] = 0;
- }
-
- TRACE("Path components are '%S' '%S' '%S'\n", dir, fname, ext);
-
-done:
-
- LOGEXIT("_wsplitpath returns.\n");
- PERF_EXIT(_wsplitpath);
-}
-
-
-/*++
-Function:
- _splitpath
-
-See description above for _wsplitpath.
-
---*/
-void
-__cdecl
-_splitpath(
- const char *path,
- char *drive,
- char *dir,
- char *fname,
- char *ext)
-{
- WCHAR w_path[_MAX_PATH];
- WCHAR w_dir[_MAX_DIR];
- WCHAR w_fname[_MAX_FNAME];
- WCHAR w_ext[_MAX_EXT];
-
- PERF_ENTRY(_splitpath);
- ENTRY("_splitpath (path=%p (%s), drive=%p, dir=%p, fname=%p, ext=%p)\n",
- path?path:"NULL",
- path?path:"NULL", drive, dir, fname, ext);
-
- /* Do performance intensive error checking only in debug builds.
-
- NOTE: This function must fail predictably across all platforms.
- Under Windows this function throw an access violation if NULL
- was passed in as the value for path.
-
- */
-#if _DEBUG
- if ( !path )
- {
- ERROR( "path cannot be NULL!\n" );
- }
-
- if( strlen( path ) >= _MAX_PATH )
- {
- ERROR( "Path length is > _MAX_PATH (%d)!\n", _MAX_PATH);
- }
-#endif
-
- /* no drive letters in the PAL */
- if(drive)
- {
- drive[0] = '\0';
- }
-
- if(0 == MultiByteToWideChar(CP_ACP, 0, path, -1, w_path, _MAX_PATH))
- {
- ASSERT("MultiByteToWideChar failed!\n");
- ON_ERROR;
- }
-
- /* Call up to Unicode version; pass NULL for parameters the caller doesn't
- care about */
- _wsplitpath(w_path, NULL, dir?w_dir:NULL,
- fname?w_fname:NULL, ext?w_ext:NULL);
-
- /* Convert result back to MultiByte; report conversion errors but don't
- stop because of them */
-
- if(dir)
- {
- if(0 == WideCharToMultiByte(CP_ACP, 0, w_dir, -1, dir, _MAX_DIR,
- NULL, NULL))
- {
- ASSERT("WideCharToMultiByte failed!\n");
- ON_ERROR;
- }
- }
- if(fname)
- {
- if(0 == WideCharToMultiByte(CP_ACP, 0, w_fname, -1, fname, _MAX_FNAME,
- NULL, NULL))
- {
- ASSERT("WideCharToMultiByte failed!\n");
- ON_ERROR;
- }
- }
- if(ext)
- {
- if(0 == WideCharToMultiByte(CP_ACP, 0, w_ext, -1, ext, _MAX_EXT,
- NULL, NULL))
- {
- ASSERT("WideCharToMultiByte failed!\n");
- ON_ERROR;
- }
- }
-
-done:
- LOGEXIT("_splitpath returns.\n");
- PERF_EXIT(_splitpath);
-}
-
-
-
-/*++
-Function:
- _makepath
-
-See MSDN doc.
-
---*/
-void
-__cdecl
-_makepath(
- char *path,
- const char *drive,
- const char *dir,
- const char *fname,
- const char *ext)
-{
- UINT Length = 0;
-
- PERF_ENTRY(_makepath);
- ENTRY( "_makepath (path=%p, drive=%p (%s), dir=%p (%s), fname=%p (%s), ext=%p (%s))\n",
- path, drive ? drive:"NULL", drive ? drive:"NULL", dir ? dir:"NULL", dir ? dir:"NULL", fname ? fname:"NULL", fname ? fname:"NULL",
- ext ? ext:"NULL",
- ext ? ext:"NULL");
-
- path[ 0 ] = '\0';
-
- /* According to the pal documentation, host operating systems that
- don't support drive letters, the "drive" parameter must always be null. */
- if ( drive != NULL && drive[0] != '\0' )
- {
- ASSERT( "The drive parameter must always be NULL on systems that don't"
- "support drive letters. drive is being ignored!.\n" );
- }
-
- if ( dir != NULL && dir[ 0 ] != '\0' )
- {
- UINT DirLength = strlen( dir );
- Length += DirLength ;
-
- if ( Length < _MAX_PATH )
- {
- strncat( path, dir, DirLength );
- if ( dir[ DirLength - 1 ] != '/' && dir[ DirLength - 1 ] != '\\' )
- {
- if ( Length + 1 < _MAX_PATH )
- {
- path[ Length ] = '/';
- Length++;
- path[ Length ] = '\0';
- }
- else
- {
- goto Max_Path_Error;
- }
- }
- }
- else
- {
- goto Max_Path_Error;
- }
- }
-
- if ( fname != NULL && fname[ 0 ] != '\0' )
- {
- UINT fNameLength = strlen( fname );
- Length += fNameLength;
-
- if ( Length < _MAX_PATH )
- {
- strncat( path, fname, fNameLength );
- }
- else
- {
- goto Max_Path_Error;
- }
- }
-
- if ( ext != NULL && ext[ 0 ] != '\0' )
- {
- UINT ExtLength = strlen( ext );
- Length += ExtLength;
-
- if ( ext[ 0 ] != '.' )
- {
- /* Add a '.' */
- if ( Length + 1 < _MAX_PATH )
- {
- path[ Length - ExtLength ] = '.';
- Length++;
- path[ Length - ExtLength ] = '\0';
- strncat( path, ext, ExtLength );
- }
- else
- {
- goto Max_Path_Error;
- }
- }
- else
- {
- /* Already has a '.' */
- if ( Length < _MAX_PATH )
- {
- strncat( path, ext, ExtLength );
- }
- else
- {
- goto Max_Path_Error;
- }
- }
- }
-
- FILEDosToUnixPathA( path );
- LOGEXIT( "_makepath returning void.\n" );
- PERF_EXIT(_makepath);
- return;
-
-Max_Path_Error:
-
- ERROR( "path cannot be greater then _MAX_PATH\n" );
- path[ 0 ] = '\0';
- LOGEXIT( "_makepath returning void \n" );
- PERF_EXIT(_makepath);
- return;
-}
-
-/*++
-Function:
- _wmakepath
-
-See MSDN doc.
-
---*/
-void
-__cdecl
-_wmakepath(
- wchar_16 *path,
- const wchar_16 *drive,
- const wchar_16 *dir,
- const wchar_16 *fname,
- const wchar_16 *ext)
-{
- CHAR Dir[ _MAX_DIR ]={0};
- CHAR FileName[ _MAX_FNAME ]={0};
- CHAR Ext[ _MAX_EXT ]={0};
- CHAR Path[ _MAX_PATH ]={0};
-
- PERF_ENTRY(_wmakepath);
- ENTRY("_wmakepath (path=%p, drive=%p (%S), dir=%p (%S), fname=%p (%S), ext=%p (%S))\n",
- path, drive ? drive:W16_NULLSTRING, drive ? drive:W16_NULLSTRING, dir ? dir:W16_NULLSTRING, dir ? dir:W16_NULLSTRING,
- fname ? fname:W16_NULLSTRING,
- fname ? fname:W16_NULLSTRING, ext ? ext:W16_NULLSTRING, ext ? ext:W16_NULLSTRING);
-
- /* According to the pal documentation, host operating systems that
- don't support drive letters, the "drive" parameter must always be null. */
- if ( drive != NULL && drive[0] != '\0' )
- {
- ASSERT( "The drive parameter must always be NULL on systems that don't"
- "support drive letters. drive is being ignored!.\n" );
- }
-
- if ((dir != NULL) && WideCharToMultiByte( CP_ACP, 0, dir, -1, Dir,
- _MAX_DIR, NULL, NULL ) == 0 )
- {
- ASSERT( "An error occurred while converting dir to multibyte."
- "Possible error: Length of dir is greater than _MAX_DIR.\n" );
- goto error;
- }
-
- if ((fname != NULL) && WideCharToMultiByte( CP_ACP, 0, fname, -1, FileName,
- _MAX_FNAME, NULL, NULL ) == 0 )
- {
- ASSERT( "An error occurred while converting fname to multibyte."
- "Possible error: Length of fname is greater than _MAX_FNAME.\n" );
- goto error;
- }
-
- if ((ext != NULL) && WideCharToMultiByte( CP_ACP, 0, ext, -1, Ext,
- _MAX_EXT, NULL, NULL ) == 0 )
- {
- ASSERT( "An error occurred while converting ext to multibyte."
- "Possible error: Length of ext is greater than _MAX_EXT.\n" );
- goto error;
- }
-
- /* Call up to the ANSI _makepath. */
- _makepath_s( Path, sizeof(Path), NULL, Dir, FileName, Ext );
-
- if ( MultiByteToWideChar( CP_ACP, 0, Path, -1, path, _MAX_PATH ) == 0 )
- {
- ASSERT( "An error occurred while converting the back wide char."
- "Possible error: The length of combined path is greater "
- "than _MAX_PATH.\n" );
- goto error;
- }
-
- LOGEXIT("_wmakepath returns void\n");
- PERF_EXIT(_wmakepath);
- return;
-
-error:
- *path = '\0';
- LOGEXIT("_wmakepath returns void\n");
- PERF_EXIT(_wmakepath);
-}
-
-
/*++
Function:
_fullpath
diff --git a/src/pal/src/cruntime/printf.cpp b/src/pal/src/cruntime/printf.cpp
index 2d9d6e4b94..c437b8e39f 100644
--- a/src/pal/src/cruntime/printf.cpp
+++ b/src/pal/src/cruntime/printf.cpp
@@ -277,124 +277,6 @@ PAL_vprintf(
/*++
Function:
- wsprintfA
-
-See MSDN doc.
---*/
-int
-PALAPIV
-wsprintfA(
- OUT LPSTR buffer,
- IN LPCSTR format,
- ...)
-{
- LONG Length;
- va_list ap;
-
- PERF_ENTRY(wsprintfA);
- ENTRY("wsprintfA (buffer=%p, format=%p (%s))\n", buffer, format, format);
-
- va_start(ap, format);
- Length = InternalVsnprintf(CorUnix::InternalGetCurrentThread(), buffer, 1024, format, ap);
- va_end(ap);
-
- LOGEXIT("wsprintfA returns int %d\n", Length);
- PERF_EXIT(wsprintfA);
- return Length;
-}
-
-/*++
-Function:
- wsprintfW
-
-See MSDN doc.
---*/
-int
-PALAPIV
-wsprintfW(
- OUT LPWSTR buffer,
- IN LPCWSTR format,
- ...)
-{
- LONG Length;
- va_list ap;
-
- PERF_ENTRY(wsprintfW);
- ENTRY("wsprintfW (buffer=%p, format=%p (%S))\n", buffer, format, format);
-
- va_start(ap, format);
- Length = PAL__wvsnprintf(buffer, 1024, format, ap);
- va_end(ap);
-
- LOGEXIT("wsprintfW returns int %d\n", Length);
- PERF_EXIT(wsprintfW);
- return Length;
-}
-
-
-/*++
-Function:
- _snprintf
-
-See MSDN doc.
---*/
-int
-__cdecl
-_snprintf(
- char *buffer,
- size_t count,
- const char *format,
- ...)
-{
- LONG Length;
- va_list ap;
-
- PERF_ENTRY(_snprintf);
- ENTRY("_snprintf (buffer=%p, count=%lu, format=%p (%s))\n",
- buffer, (unsigned long) count, format, format);
-
- va_start(ap, format);
- Length = InternalVsnprintf(CorUnix::InternalGetCurrentThread(), buffer, count, format, ap);
- va_end(ap);
-
- LOGEXIT("_snprintf returns int %d\n", Length);
- PERF_EXIT(_snprintf);
- return Length;
-}
-
-
-/*++
-Function:
- _snwprintf
-
-See MSDN doc.
---*/
-int
-__cdecl
-_snwprintf(
- wchar_16 *buffer,
- size_t count,
- const wchar_16 *format,
- ...)
-{
- LONG Length;
- va_list ap;
-
- PERF_ENTRY(_snwprintf);
- ENTRY("_snwprintf (buffer=%p, count=%lu, format=%p (%S))\n",
- buffer, (unsigned long) count, format, format);
-
- va_start(ap, format);
- Length = PAL__wvsnprintf(buffer, count, format, ap);
- va_end(ap);
-
- LOGEXIT("_snwprintf returns int %d\n", Length);
- PERF_EXIT(_snwprintf);
- return Length;
-}
-
-/*++
-Function:
fwprintf
See MSDN doc.
@@ -1483,63 +1365,6 @@ int PAL_wvsscanf(LPCWSTR Buffer, LPCWSTR Format, va_list ap)
/*++
Function:
- PAL_sscanf
-
-See MSDN doc.
---*/
-int
-__cdecl
-PAL_sscanf(
- const char *buffer,
- const char *format,
- ...)
-{
- int Length;
- va_list ap;
-
- PERF_ENTRY(sscanf);
- ENTRY("PAL_sscanf (buffer=%p (%s), format=%p (%s))\n", buffer, buffer, format, format);
-
- va_start(ap, format);
- Length = PAL_vsscanf(buffer, format, ap);
- va_end(ap);
-
- LOGEXIT("PAL_sscanf returns int %d\n", Length);
- PERF_EXIT(sscanf);
- return Length;
-}
-
-/*++
-Function:
- PAL_sprintf
-
-See MSDN doc.
---*/
-int
-__cdecl
-PAL_sprintf(
- char *buffer,
- const char *format,
- ...)
-{
- LONG Length;
- va_list ap;
-
- PERF_ENTRY(sprintf);
- ENTRY("PAL_sprintf (buffer=%p, format=%p (%s))\n", buffer, format, format);
-
- va_start(ap, format);
- Length = InternalVsnprintf(CorUnix::InternalGetCurrentThread(), buffer, 0x7fffffff, format, ap);
- va_end(ap);
-
- LOGEXIT("PAL_sprintf returns int %d\n", Length);
- PERF_EXIT(sprintf);
- return Length;
-}
-
-
-/*++
-Function:
PAL_swprintf
See MSDN doc.
@@ -1649,33 +1474,6 @@ PAL_vswprintf(wchar_16 *buffer,
}
-/*++
-Function:
- _vsnwprintf
-
-See MSDN doc.
---*/
-int
-__cdecl
-_vsnwprintf(wchar_16 *buffer,
- size_t count,
- const wchar_16 *format,
- va_list argptr)
-{
- LONG Length;
-
- PERF_ENTRY(_vsnwprintf);
- ENTRY("_vsnwprintf (buffer=%p, count=%lu, format=%p (%S), argptr=%p)\n",
- buffer, (unsigned long) count, format, format, argptr);
-
- Length = PAL__wvsnprintf(buffer, count, format, argptr);
-
- LOGEXIT("_vsnwprintf returns int %d\n", Length);
- PERF_EXIT(_vsnwprintf);
-
- return Length;
-}
-
#if SSCANF_CANNOT_HANDLE_MISSING_EXPONENT
/*++
Function:
diff --git a/src/pal/src/cruntime/string.cpp b/src/pal/src/cruntime/string.cpp
index 23781d8b39..abe6d136f0 100644
--- a/src/pal/src/cruntime/string.cpp
+++ b/src/pal/src/cruntime/string.cpp
@@ -151,61 +151,6 @@ _strlwr(
return orig;
}
-
-/*++
-Function:
- _swab
-
-Swaps bytes.
-
-Return Value
-
-None
-
-Parameters
-
-src Data to be copied and swapped
-dest Storage location for swapped data
-n Number of bytes to be copied and swapped
-
-Remarks
-
-The _swab function copies n bytes from src, swaps each pair of
-adjacent bytes, and stores the result at dest. The integer n should be
-an even number to allow for swapping. _swab is typically used to
-prepare binary data for transfer to a machine that uses a different
-byte order.
-
-Example
-
-char from[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-char to[] = "..........................";
-
-printf("Before:\n%s\n%s\n\n", from, to);
-_swab(from, to, strlen(from));
-printf("After:\n%s\n%s\n\n", from, to);
-
-Before:
-ABCDEFGHIJKLMNOPQRSTUVWXYZ
-..........................
-
-After:
-ABCDEFGHIJKLMNOPQRSTUVWXYZ
-BADCFEHGJILKNMPORQTSVUXWZY
-
---*/
-void
-__cdecl
-_swab(char *src, char *dest, int n)
-{
- PERF_ENTRY(_swab);
- ENTRY("_swab (src=%p (%s), dest=%p (%s), n=%d)\n", src?src:"NULL", src?src:"NULL", dest?dest:"NULL", dest?dest:"NULL", n);
- swab(src, dest, n);
- LOGEXIT("_swab returning\n");
- PERF_EXIT(_swab);
-}
-
-
/*++
Function:
PAL_strtoul
diff --git a/src/pal/src/cruntime/wchar.cpp b/src/pal/src/cruntime/wchar.cpp
index 2d244a639f..3de065e361 100644
--- a/src/pal/src/cruntime/wchar.cpp
+++ b/src/pal/src/cruntime/wchar.cpp
@@ -73,146 +73,6 @@ wtolower(wchar_16 c)
}
-/*******************************************************************************
-Function:
- Internal_i64tow
-
-Parameters:
- value
- - INT64 value to be converted to a string
- string
- - out buffer to place interger string
- radix
- - numeric base to convert to
- isI64
- - TRUE if value is INT64, FALSE if value is a long
-
-Note:
- - only a radix of ten (and value < 0) will result in a negative
- sign in the output buffer
-*******************************************************************************/
-LPWSTR Internal_i64tow(INT64 value, LPWSTR string, int radix, BOOL isI64)
-{
- int length = 0;
- int n;
- int r;
- UINT64 uval = value;
- LPWSTR stringPtr = string;
- int start = 0;
- int end;
- WCHAR tempCh;
-
- if (radix < 2 || radix > 36)
- {
- ASSERT( "Invalid radix, radix must be between 2 and 36\n" );
- SetLastError(ERROR_INVALID_PARAMETER);
- return string;
- }
- if (FALSE == isI64)
- {
- uval = (ULONG) uval;
- }
- if (10 == radix && value < 0)
- {
- uval = value * -1;
- }
- if(0 == uval)
- {
- ++length;
- *stringPtr++ = '0';
- }
- else while (uval > 0)
- {
- ++length;
- n = uval / radix;
- r = uval - (n * radix);
- uval /= radix;
- if (r > 9)
- {
- *stringPtr++ = r + 87;
- }
- else
- {
- *stringPtr++ = r + 48;
- }
- }
- if (10 == radix && value < 0)
- {
- *stringPtr++ = '-';
- ++length;
- }
- *stringPtr = 0; /* end the string */
-
- /* reverse the string */
- end = length - 1;
- while (start < end)
- {
- tempCh = string[start];
- string[start] = string[end];
- string[end] = tempCh;
- ++start;
- --end;
- }
-
- return string;
-}
-
-/*--
-Function:
- _itow
-
-16-bit wide character version of the ANSI tolower() function.
-
- --*/
-wchar_16 *
-__cdecl
-_itow(
- int value,
- wchar_16 *string,
- int radix)
-{
- wchar_16 *ret;
-
- PERF_ENTRY(_itow);
- ENTRY("_itow (value=%d, string=%p, radix=%d)\n",
- value, string, radix);
-
- ret = Internal_i64tow(value, string, radix, FALSE);
-
- LOGEXIT("_itow returns wchar_t* %p\n", ret);
- PERF_EXIT(_itow);
-
- return ret;
-}
-
-/*--
-Function:
- _i64tow
-
-See MSDN doc
---*/
-wchar_16 *
- __cdecl
-_i64tow(
- __int64 value,
- wchar_16 *string,
- int radix)
-{
- wchar_16 *ret;
-
- PERF_ENTRY(_i64tow);
- ENTRY("_i64tow (value=%ld, string=%p, radix=%d)\n",
- value, string, radix);
-
- ret = Internal_i64tow(value, string, radix, TRUE);
-
- LOGEXIT("_i64tow returns wchar_t* %p\n", ret);
- PERF_EXIT(_i64tow);
-
- return ret;
-}
-
-
/*--
Function:
_wtoi
@@ -1558,77 +1418,6 @@ PAL_wcstod( const wchar_16 * nptr, wchar_16 **endptr )
}
/*++
-Function :
-
- _ui64tow
-
-See MSDN for more details.
---*/
-wchar_16 *
-__cdecl
-_ui64tow( unsigned __int64 value , wchar_16 * string , int radix )
-{
- UINT ReversedIndex = 0;
- WCHAR ReversedString[ 65 ];
- LPWSTR lpString = string;
- UINT Index = 0;
-
- PERF_ENTRY(_ui64tow);
- ENTRY( "_ui64tow( value=%I64d, string=%p (%S), radix=%d )\n",
- value, string, string, radix );
-
- if ( !string )
- {
- ERROR( "string has to be a valid pointer.\n" );
- LOGEXIT( "_ui64tow returning NULL.\n" );
- PERF_EXIT(_ui64tow);
- return NULL;
- }
- if ( radix < 2 || radix > 36 )
- {
- ERROR( "radix has to be between 2 and 36.\n" );
- LOGEXIT( "_ui64tow returning NULL.\n" );
- PERF_EXIT(_ui64tow);
- return NULL;
- }
-
- if(0 == value)
- {
- ReversedString[0] = '0';
- Index++;
- }
- else while ( value )
- {
- int temp = value % radix;
- value /= radix;
-
- if ( temp < 10 )
- {
- ReversedString[ Index ] = temp + '0';
- Index++;
- }
- else
- {
- ReversedString[ Index ] = temp - 10 + 'a';
- Index++;
- }
- }
-
- /* Reverse the string. */
- ReversedIndex = Index;
- for ( Index = 0; ReversedIndex > 0; ReversedIndex--, Index++ )
- {
- string[ Index ] = ReversedString[ ReversedIndex - 1 ];
- }
-
- string[ Index ] = '\0';
- LOGEXIT( "_ui64tow returning %p (%S).\n", lpString , lpString );
- PERF_EXIT(_ui64tow);
- return lpString;
-}
-
-
-/*++
Function:
iswdigit
diff --git a/src/pal/src/debug/debug.cpp b/src/pal/src/debug/debug.cpp
index 5461ac6265..2f7d17cabe 100644
--- a/src/pal/src/debug/debug.cpp
+++ b/src/pal/src/debug/debug.cpp
@@ -92,29 +92,6 @@ static const char PAL_OUTPUTDEBUGSTRING[] = "PAL_OUTPUTDEBUGSTRING";
static const char PAL_RUN_ON_DEBUG_BREAK[] = "PAL_RUN_ON_DEBUG_BREAK";
#endif // ENABLE_RUN_ON_DEBUG_BREAK
-/* ------------------- Static function prototypes ----------------------------*/
-
-#if !HAVE_VM_READ && !HAVE_PROCFS_CTL && !HAVE_TTRACE
-static int
-DBGWriteProcMem_Int(DWORD processId, int *addr, int data);
-static int
-DBGWriteProcMem_IntWithMask(DWORD processId, int *addr, int data,
- unsigned int mask);
-#endif // !HAVE_VM_READ && !HAVE_PROCFS_CTL && !HAVE_TTRACE
-
-#if !HAVE_VM_READ && !HAVE_PROCFS_CTL
-
-static BOOL
-DBGAttachProcess(CPalThread *pThread, HANDLE hProcess, DWORD dwProcessId);
-
-static BOOL
-DBGDetachProcess(CPalThread *pThread, HANDLE hProcess, DWORD dwProcessId);
-
-static int
-DBGSetProcessAttached(CPalThread *pThread, HANDLE hProcess, BOOL bAttach);
-
-#endif // !HAVE_VM_READ && !HAVE_PROCFS_CTL
-
extern "C" {
/*++
@@ -566,457 +543,6 @@ SetThreadContext(
return ret;
}
-#if !HAVE_VM_READ && !HAVE_PROCFS_CTL && !HAVE_TTRACE
-/*++
-Function:
- DBGWriteProcMem_Int
-
-Abstract
- write one int to a process memory address
-
-Parameter
- processId : process handle
- addr : memory address where the int should be written
- data : int to be written in addr
-
-Return
- Return 1 if it succeeds, or 0 if it's fails
---*/
-static
-int
-DBGWriteProcMem_Int(IN DWORD processId,
- IN int *addr,
- IN int data)
-{
- if (PAL_PTRACE( PAL_PT_WRITE_D, processId, addr, data ) == -1)
- {
- if (errno == EFAULT)
- {
- ERROR("ptrace(PT_WRITE_D, pid:%d caddr_t:%p data:%x) failed "
- "errno:%d (%s)\n", processId, addr, data, errno, strerror(errno));
- SetLastError(ERROR_INVALID_ADDRESS);
- }
- else
- {
- ASSERT("ptrace(PT_WRITE_D, pid:%d caddr_t:%p data:%x) failed "
- "errno:%d (%s)\n", processId, addr, data, errno, strerror(errno));
- SetLastError(ERROR_INTERNAL_ERROR);
- }
- return 0;
- }
-
- return 1;
-}
-
-/*++
-Function:
- DBGWriteProcMem_IntWithMask
-
-Abstract
- write one int to a process memory address space using mask
-
-Parameter
- processId : process ID
- addr : memory address where the int should be written
- data : int to be written in addr
- mask : the mask used to write only a parts of data
-
-Return
- Return 1 if it succeeds, or 0 if it's fails
---*/
-static
-int
-DBGWriteProcMem_IntWithMask(IN DWORD processId,
- IN int *addr,
- IN int data,
- IN unsigned int mask )
-{
- int readInt;
-
- if (mask != ~0)
- {
- errno = 0;
- if (((readInt = PAL_PTRACE( PAL_PT_READ_D, processId, addr, 0 )) == -1)
- && errno)
- {
- if (errno == EFAULT)
- {
- ERROR("ptrace(PT_READ_D, pid:%d, caddr_t:%p, 0) failed "
- "errno:%d (%s)\n", processId, addr, errno, strerror(errno));
- SetLastError(ERROR_INVALID_ADDRESS);
- }
- else
- {
- ASSERT("ptrace(PT_READ_D, pid:%d, caddr_t:%p, 0) failed "
- "errno:%d (%s)\n", processId, addr, errno, strerror(errno));
- SetLastError(ERROR_INTERNAL_ERROR);
- }
-
- return 0;
- }
- data = (data & mask) | (readInt & ~mask);
- }
- return DBGWriteProcMem_Int(processId, addr, data);
-}
-#endif // !HAVE_VM_READ && !HAVE_PROCFS_CTL && !HAVE_TTRACE
-
-#if !HAVE_VM_READ && !HAVE_PROCFS_CTL
-
-/*++
-Function:
- DBGAttachProcess
-
-Abstract
-
- Attach the indicated process to the current process.
-
- if the indicated process is already attached by the current process, then
- increment the number of attachment pending. if ot, attach it to the current
- process (with PT_ATTACH).
-
-Parameter
- hProcess : handle to process to attach to
- processId : process ID to attach
-Return
- Return true if it succeeds, or false if it's fails
---*/
-static
-BOOL
-DBGAttachProcess(
- CPalThread *pThread,
- HANDLE hProcess,
- DWORD processId
- )
-{
- int attchmentCount;
- int savedErrno;
-#if HAVE_PROCFS_CTL
- int fd = -1;
- char ctlPath[1024];
-#endif // HAVE_PROCFS_CTL
-
- attchmentCount =
- DBGSetProcessAttached(pThread, hProcess, DBG_ATTACH);
-
- if (attchmentCount == -1)
- {
- /* Failed to set the process as attached */
- goto EXIT;
- }
-
- if (attchmentCount == 1)
- {
-#if HAVE_PROCFS_CTL
- struct timespec waitTime;
-
- // FreeBSD has some trouble when a series of attach/detach sequences
- // occurs too close together. When this happens, we'll be able to
- // attach to the process, but waiting for the process to stop
- // (either via writing "wait" to /proc/<pid>/ctl or via waitpid)
- // will hang. If we pause for a very short amount of time before
- // trying to attach, we don't run into this situation.
- waitTime.tv_sec = 0;
- waitTime.tv_nsec = 50000000;
- nanosleep(&waitTime, NULL);
-
- sprintf_s(ctlPath, sizeof(ctlPath), "/proc/%d/ctl", processId);
- fd = InternalOpen(ctlPath, O_WRONLY);
- if (fd == -1)
- {
- ERROR("Failed to open %s: errno is %d (%s)\n", ctlPath,
- errno, strerror(errno));
- goto DETACH1;
- }
-
- if (write(fd, CTL_ATTACH, sizeof(CTL_ATTACH)) < (int)sizeof(CTL_ATTACH))
- {
- ERROR("Failed to attach to %s: errno is %d (%s)\n", ctlPath,
- errno, strerror(errno));
- close(fd);
- goto DETACH1;
- }
-
- if (write(fd, CTL_WAIT, sizeof(CTL_WAIT)) < (int)sizeof(CTL_WAIT))
- {
- ERROR("Failed to wait for %s: errno is %d (%s)\n", ctlPath,
- errno, strerror(errno));
- goto DETACH2;
- }
-
- close(fd);
-#elif HAVE_TTRACE
- if (ttrace(TT_PROC_ATTACH, processId, 0, TT_DETACH_ON_EXIT, TT_VERSION, 0) == -1)
- {
- if (errno != ESRCH)
- {
- ASSERT("ttrace(TT_PROC_ATTACH, pid:%d) failed errno:%d (%s)\n",
- processId, errno, strerror(errno));
- }
- goto DETACH1;
- }
-#else // HAVE_TTRACE
- if (PAL_PTRACE( PAL_PT_ATTACH, processId, 0, 0 ) == -1)
- {
- if (errno != ESRCH)
- {
- ASSERT("ptrace(PT_ATTACH, pid:%d) failed errno:%d (%s)\n",
- processId, errno, strerror(errno));
- }
- goto DETACH1;
- }
-
- if (waitpid(processId, NULL, WUNTRACED) == -1)
- {
- if (errno != ESRCH)
- {
- ASSERT("waitpid(pid:%d, NULL, WUNTRACED) failed.errno:%d"
- " (%s)\n", processId, errno, strerror(errno));
- }
- goto DETACH2;
- }
-#endif // HAVE_PROCFS_CTL
- }
-
- return TRUE;
-
-#if HAVE_PROCFS_CTL
-DETACH2:
- if (write(fd, CTL_DETACH, sizeof(CTL_DETACH)) < (int)sizeof(CTL_DETACH))
- {
- ASSERT("Failed to detach from %s: errno is %d (%s)\n", ctlPath,
- errno, strerror(errno));
- }
- close(fd);
-#elif !HAVE_TTRACE
-DETACH2:
- if (PAL_PTRACE(PAL_PT_DETACH, processId, 0, 0) == -1)
- {
- ASSERT("ptrace(PT_DETACH, pid:%d) failed. errno:%d (%s)\n", processId,
- errno, strerror(errno));
- }
-#endif // HAVE_PROCFS_CTL
-
-DETACH1:
- savedErrno = errno;
- DBGSetProcessAttached(pThread, hProcess, DBG_DETACH);
- errno = savedErrno;
-EXIT:
- if (errno == ESRCH || errno == ENOENT || errno == EBADF)
- {
- ERROR("Invalid process ID:%d\n", processId);
- SetLastError(ERROR_INVALID_PARAMETER);
- }
- else
- {
- SetLastError(ERROR_INTERNAL_ERROR);
- }
- return FALSE;
-}
-
-/*++
-Function:
- DBGDetachProcess
-
-Abstract
- Detach the indicated process from the current process.
-
- if the indicated process is already attached by the current process, then
- decrement the number of attachment pending and detach it from the current
- process (with PT_DETACH) if there's no more attachment left.
-
-Parameter
- hProcess : process handle
- processId : process ID
-
-Return
- Return true if it succeeds, or true if it's fails
---*/
-static
-BOOL
-DBGDetachProcess(
- CPalThread *pThread,
- HANDLE hProcess,
- DWORD processId
- )
-{
- int nbAttachLeft;
-#if HAVE_PROCFS_CTL
- int fd = -1;
- char ctlPath[1024];
-#endif // HAVE_PROCFS_CTL
-
- nbAttachLeft = DBGSetProcessAttached(pThread, hProcess, DBG_DETACH);
-
- if (nbAttachLeft == -1)
- {
- /* Failed to set the process as detached */
- return FALSE;
- }
-
- /* check if there's no more attachment left on processId */
- if (nbAttachLeft == 0)
- {
-#if HAVE_PROCFS_CTL
- sprintf(ctlPath, sizeof(ctlPath), "/proc/%d/ctl", processId);
- fd = InternalOpen(pThread, ctlPath, O_WRONLY);
- if (fd == -1)
- {
- if (errno == ENOENT)
- {
- ERROR("Invalid process ID: %d\n", processId);
- SetLastError(ERROR_INVALID_PARAMETER);
- }
- else
- {
- ERROR("Failed to open %s: errno is %d (%s)\n", ctlPath,
- errno, strerror(errno));
- SetLastError(ERROR_INTERNAL_ERROR);
- }
- return FALSE;
- }
-
- if (write(fd, CTL_DETACH, sizeof(CTL_DETACH)) < (int)sizeof(CTL_DETACH))
- {
- ERROR("Failed to detach from %s: errno is %d (%s)\n", ctlPath,
- errno, strerror(errno));
- close(fd);
- return FALSE;
- }
- close(fd);
-
-#elif HAVE_TTRACE
- if (ttrace(TT_PROC_DETACH, processId, 0, 0, 0, 0) == -1)
- {
- if (errno == ESRCH)
- {
- ERROR("Invalid process ID: %d\n", processId);
- SetLastError(ERROR_INVALID_PARAMETER);
- }
- else
- {
- ASSERT("ttrace(TT_PROC_DETACH, pid:%d) failed. errno:%d (%s)\n",
- processId, errno, strerror(errno));
- SetLastError(ERROR_INTERNAL_ERROR);
- }
- return FALSE;
- }
-#else // HAVE_TTRACE
- if (PAL_PTRACE(PAL_PT_DETACH, processId, 1, 0) == -1)
- {
- if (errno == ESRCH)
- {
- ERROR("Invalid process ID: %d\n", processId);
- SetLastError(ERROR_INVALID_PARAMETER);
- }
- else
- {
- ASSERT("ptrace(PT_DETACH, pid:%d) failed. errno:%d (%s)\n",
- processId, errno, strerror(errno));
- SetLastError(ERROR_INTERNAL_ERROR);
- }
- return FALSE;
- }
-#endif // HAVE_PROCFS_CTL
-
-#if !HAVE_TTRACE
- if (kill(processId, SIGCONT) == -1)
- {
- ERROR("Failed to continue the detached process:%d errno:%d (%s)\n",
- processId, errno, strerror(errno));
- return FALSE;
- }
-#endif // !HAVE_TTRACE
- }
- return TRUE;
-}
-
-/*++
-Function:
- DBGSetProcessAttached
-
-Abstract
- saves the current process Id in the attached process structure
-
-Parameter
- hProcess : process handle
- bAttach : true (false) to set the process as attached (as detached)
-Return
- returns the number of attachment left on attachedProcId, or -1 if it fails
---*/
-static int
-DBGSetProcessAttached(
- CPalThread *pThread,
- HANDLE hProcess,
- BOOL bAttach
- )
-{
- PAL_ERROR palError = NO_ERROR;
- IPalObject *pobjProcess = NULL;
- IDataLock *pDataLock = NULL;
- CProcProcessLocalData *pLocalData = NULL;
- int ret = -1;
- CAllowedObjectTypes aotProcess(otiProcess);
-
- palError = g_pObjectManager->ReferenceObjectByHandle(
- pThread,
- hProcess,
- &aotProcess,
- 0,
- &pobjProcess
- );
-
- if (NO_ERROR != palError)
- {
- goto DBGSetProcessAttachedExit;
- }
-
- palError = pobjProcess->GetProcessLocalData(
- pThread,
- WriteLock,
- &pDataLock,
- reinterpret_cast<void **>(&pLocalData)
- );
-
- if (NO_ERROR != palError)
- {
- goto DBGSetProcessAttachedExit;
- }
-
- if (bAttach)
- {
- pLocalData->lAttachCount += 1;
- }
- else
- {
- pLocalData->lAttachCount -= 1;
-
- if (pLocalData->lAttachCount < 0)
- {
- ASSERT("pLocalData->lAttachCount < 0 check for extra DBGDetachProcess calls\n");
- palError = ERROR_INTERNAL_ERROR;
- goto DBGSetProcessAttachedExit;
- }
- }
-
- ret = pLocalData->lAttachCount;
-
-DBGSetProcessAttachedExit:
-
- if (NULL != pDataLock)
- {
- pDataLock->ReleaseLock(pThread, TRUE);
- }
-
- if (NULL != pobjProcess)
- {
- pobjProcess->ReleaseReference(pThread);
- }
-
- return ret;
-}
-
-#endif // !HAVE_VM_READ && !HAVE_PROCFS_CTL
-
/*++
Function:
PAL_CreateExecWatchpoint
@@ -1240,605 +766,64 @@ PAL_DeleteExecWatchpointExit:
return dwError;
}
-// We want to enable hardware exception handling for ReadProcessMemory
-// and WriteProcessMemory in all cases since it is acceptable if they
-// hit AVs, so redefine HardwareExceptionHolder for these two functions
-// (here to the end of the file).
-#undef HardwareExceptionHolder
-#define HardwareExceptionHolder CatchHardwareExceptionHolder __catchHardwareException;
-
-/*++
-Function:
- ReadProcessMemory
-
-See MSDN doc.
---*/
-BOOL
-PALAPI
-ReadProcessMemory(
- IN HANDLE hProcess,
- IN LPCVOID lpBaseAddress,
- IN LPVOID lpBuffer,
- IN SIZE_T nSize,
- OUT SIZE_T * lpNumberOfBytesRead
- )
+__attribute__((noinline))
+__attribute__((optnone))
+void
+ProbeMemory(volatile PBYTE pbBuffer, DWORD cbBuffer, bool fWriteAccess)
{
- CPalThread *pThread;
- DWORD processId;
- Volatile<BOOL> ret = FALSE;
- Volatile<SIZE_T> numberOfBytesRead = 0;
-#if HAVE_VM_READ
- kern_return_t result;
- vm_map_t task;
- LONG_PTR bytesToRead;
-#elif HAVE_PROCFS_CTL
- int fd = -1;
- char memPath[64];
- off_t offset;
-#elif !HAVE_TTRACE
- SIZE_T nbInts;
- int* ptrInt;
- int* lpTmpBuffer;
-#endif
-#if !HAVE_PROCFS_CTL && !HAVE_TTRACE
- int* lpBaseAddressAligned;
- SIZE_T offset;
-#endif // !HAVE_PROCFS_CTL && !HAVE_TTRACE
-
- PERF_ENTRY(ReadProcessMemory);
- ENTRY("ReadProcessMemory (hProcess=%p,lpBaseAddress=%p, lpBuffer=%p, "
- "nSize=%u, lpNumberOfBytesRead=%p)\n",hProcess,lpBaseAddress,
- lpBuffer, (unsigned int)nSize, lpNumberOfBytesRead);
-
- pThread = InternalGetCurrentThread();
-
- if (!(processId = PROCGetProcessIDFromHandle(hProcess)))
- {
- ERROR("Invalid process handler hProcess:%p.",hProcess);
- SetLastError(ERROR_INVALID_HANDLE);
- goto EXIT;
- }
-
- // Check if the read request is for the current process.
- // We don't need ptrace in that case.
- if (GetCurrentProcessId() == processId)
+ // Need an throw in this function to fool the C++ runtime into handling the
+ // possible h/w exception below.
+ if (pbBuffer == NULL)
{
- TRACE("We are in the same process, so ptrace is not needed\n");
-
- struct Param
- {
- LPCVOID lpBaseAddress;
- LPVOID lpBuffer;
- SIZE_T nSize;
- SIZE_T numberOfBytesRead;
- BOOL ret;
- } param;
- param.lpBaseAddress = lpBaseAddress;
- param.lpBuffer = lpBuffer;
- param.nSize = nSize;
- param.numberOfBytesRead = numberOfBytesRead;
- param.ret = ret;
-
- PAL_TRY(Param *, pParam, &param)
- {
- SIZE_T i;
-
- // Seg fault in memcpy can't be caught
- // so we simulate the memcpy here
-
- for (i = 0; i<pParam->nSize; i++)
- {
- *((char*)(pParam->lpBuffer)+i) = *((char*)(pParam->lpBaseAddress)+i);
- }
-
- pParam->numberOfBytesRead = pParam->nSize;
- pParam->ret = TRUE;
- }
- PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- SetLastError(ERROR_ACCESS_DENIED);
- }
- PAL_ENDTRY
-
- numberOfBytesRead = param.numberOfBytesRead;
- ret = param.ret;
- goto EXIT;
+ throw PAL_SEHException();
}
-#if HAVE_VM_READ
- result = task_for_pid(mach_task_self(), processId, &task);
- if (result != KERN_SUCCESS)
+ // Simple one byte at a time probing
+ while (cbBuffer > 0)
{
- ERROR("No Mach task for pid %d: %d\n", processId, ret.Load());
- SetLastError(ERROR_INVALID_HANDLE);
- goto EXIT;
- }
- // vm_read_overwrite usually requires that the address be page-aligned
- // and the size be a multiple of the page size. We can't differentiate
- // between the cases in which that's required and those in which it
- // isn't, so we do it all the time.
- lpBaseAddressAligned = (int*)((SIZE_T) lpBaseAddress & ~VIRTUAL_PAGE_MASK);
- offset = ((SIZE_T) lpBaseAddress & VIRTUAL_PAGE_MASK);
- char *data;
- data = (char*)alloca(VIRTUAL_PAGE_SIZE);
- while (nSize > 0)
- {
- vm_size_t bytesRead;
-
- bytesToRead = VIRTUAL_PAGE_SIZE - offset;
- if (bytesToRead > (LONG_PTR)nSize)
- {
- bytesToRead = nSize;
- }
- bytesRead = VIRTUAL_PAGE_SIZE;
- result = vm_read_overwrite(task, (vm_address_t) lpBaseAddressAligned,
- VIRTUAL_PAGE_SIZE, (vm_address_t) data, &bytesRead);
- if (result != KERN_SUCCESS || bytesRead != VIRTUAL_PAGE_SIZE)
+ volatile BYTE read = *pbBuffer;
+ if (fWriteAccess)
{
- ERROR("vm_read_overwrite failed for %d bytes from %p in %d: %d\n",
- VIRTUAL_PAGE_SIZE, (char *) lpBaseAddressAligned, task, result);
- if (result <= KERN_RETURN_MAX)
- {
- SetLastError(ERROR_INVALID_ACCESS);
- }
- else
- {
- SetLastError(ERROR_INTERNAL_ERROR);
- }
- goto EXIT;
+ *pbBuffer = read;
}
- memcpy((LPSTR)lpBuffer + numberOfBytesRead, data + offset, bytesToRead);
- numberOfBytesRead.Store(numberOfBytesRead.Load() + bytesToRead);
- lpBaseAddressAligned = (int*)((char*)lpBaseAddressAligned + VIRTUAL_PAGE_SIZE);
- nSize -= bytesToRead;
- offset = 0;
+ ++pbBuffer;
+ --cbBuffer;
}
- ret = TRUE;
-#else // HAVE_VM_READ
-#if HAVE_PROCFS_CTL
- snprintf(memPath, sizeof(memPath), "/proc/%u/%s", processId, PROCFS_MEM_NAME);
- fd = InternalOpen(memPath, O_RDONLY);
- if (fd == -1)
- {
- ERROR("Failed to open %s\n", memPath);
- SetLastError(ERROR_INVALID_ACCESS);
- goto PROCFSCLEANUP;
- }
-
- //
- // off_t may be greater in size than void*, so first cast to
- // an unsigned type to ensure that no sign extension takes place
- //
-
- offset = (off_t) (UINT_PTR) lpBaseAddress;
-
- if (lseek(fd, offset, SEEK_SET) == -1)
- {
- ERROR("Failed to seek to base address\n");
- SetLastError(ERROR_INVALID_ACCESS);
- goto PROCFSCLEANUP;
- }
-
- numberOfBytesRead = read(fd, lpBuffer, nSize);
- ret = TRUE;
-
-#else // HAVE_PROCFS_CTL
- // Attach the process before calling ttrace/ptrace otherwise it fails.
- if (DBGAttachProcess(pThread, hProcess, processId))
- {
-#if HAVE_TTRACE
- if (ttrace(TT_PROC_RDDATA, processId, 0, (__uint64_t)lpBaseAddress, (__uint64_t)nSize, (__uint64_t)lpBuffer) == -1)
- {
- if (errno == EFAULT)
- {
- ERROR("ttrace(TT_PROC_RDDATA, pid:%d, 0, addr:%p, data:%d, addr2:%d) failed"
- " errno=%d (%s)\n", processId, lpBaseAddress, (int)nSize, lpBuffer,
- errno, strerror(errno));
-
- SetLastError(ERROR_ACCESS_DENIED);
- }
- else
- {
- ASSERT("ttrace(TT_PROC_RDDATA, pid:%d, 0, addr:%p, data:%d, addr2:%d) failed"
- " errno=%d (%s)\n", processId, lpBaseAddress, (int)nSize, lpBuffer,
- errno, strerror(errno));
- SetLastError(ERROR_INTERNAL_ERROR);
- }
-
- goto CLEANUP1;
- }
-
- numberOfBytesRead = nSize;
- ret = TRUE;
-
-#else // HAVE_TTRACE
-
- offset = (SIZE_T)lpBaseAddress % sizeof(int);
- lpBaseAddressAligned = (int*)((char*)lpBaseAddress - offset);
- nbInts = (nSize + offset)/sizeof(int) +
- ((nSize + offset)%sizeof(int) ? 1:0);
-
- /* before transferring any data to lpBuffer we should make sure that all
- data is accessible for read. so we need to use a temp buffer for that.*/
- if (!(lpTmpBuffer = (int*)InternalMalloc((nbInts * sizeof(int)))))
- {
- ERROR("Insufficient memory available !\n");
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- goto CLEANUP1;
- }
-
- for (ptrInt = lpTmpBuffer; nbInts; ptrInt++,
- lpBaseAddressAligned++, nbInts--)
- {
- errno = 0;
- *ptrInt =
- PAL_PTRACE(PAL_PT_READ_D, processId, lpBaseAddressAligned, 0);
- if (*ptrInt == -1 && errno)
- {
- if (errno == EFAULT)
- {
- ERROR("ptrace(PT_READ_D, pid:%d, addr:%p, data:0) failed"
- " errno=%d (%s)\n", processId, lpBaseAddressAligned,
- errno, strerror(errno));
-
- SetLastError(ptrInt == lpTmpBuffer ? ERROR_ACCESS_DENIED :
- ERROR_PARTIAL_COPY);
- }
- else
- {
- ASSERT("ptrace(PT_READ_D, pid:%d, addr:%p, data:0) failed"
- " errno=%d (%s)\n", processId, lpBaseAddressAligned,
- errno, strerror(errno));
- SetLastError(ERROR_INTERNAL_ERROR);
- }
-
- goto CLEANUP2;
- }
- }
-
- /* transfer data from temp buffer to lpBuffer */
- memcpy( (char *)lpBuffer, ((char*)lpTmpBuffer) + offset, nSize);
- numberOfBytesRead = nSize;
- ret = TRUE;
-#endif // HAVE_TTRACE
- }
- else
- {
- /* Failed to attach processId */
- goto EXIT;
- }
-#endif // HAVE_PROCFS_CTL
-
-#if HAVE_PROCFS_CTL
-PROCFSCLEANUP:
- if (fd != -1)
- {
- close(fd);
- }
-#elif !HAVE_TTRACE
-CLEANUP2:
- if (lpTmpBuffer)
- {
- free(lpTmpBuffer);
- }
-#endif // !HAVE_TTRACE
-
-#if !HAVE_PROCFS_CTL
-CLEANUP1:
- if (!DBGDetachProcess(pThread, hProcess, processId))
- {
- /* Failed to detach processId */
- ret = FALSE;
- }
-#endif // HAVE_PROCFS_CTL
-#endif // HAVE_VM_READ
-
-EXIT:
- if (lpNumberOfBytesRead)
- {
- *lpNumberOfBytesRead = numberOfBytesRead;
- }
- LOGEXIT("ReadProcessMemory returns BOOL %d\n", ret.Load());
- PERF_EXIT(ReadProcessMemory);
- return ret;
}
/*++
Function:
- WriteProcessMemory
+ PAL_ProbeMemory
-See MSDN doc.
+Abstract
+
+Parameter
+ pBuffer : address of memory to validate
+ cbBuffer : size of memory region to validate
+ fWriteAccess : if true, validate writable access, else just readable.
+
+Return
+ true if memory is valid, false if not.
--*/
BOOL
PALAPI
-WriteProcessMemory(
- IN HANDLE hProcess,
- IN LPVOID lpBaseAddress,
- IN LPCVOID lpBuffer,
- IN SIZE_T nSize,
- OUT SIZE_T * lpNumberOfBytesWritten
- )
-
+PAL_ProbeMemory(
+ PVOID pBuffer,
+ DWORD cbBuffer,
+ BOOL fWriteAccess)
{
- CPalThread *pThread;
- DWORD processId;
- Volatile<BOOL> ret = FALSE;
- Volatile<SIZE_T> numberOfBytesWritten = 0;
-#if HAVE_VM_READ
- kern_return_t result;
- vm_map_t task;
-#elif HAVE_PROCFS_CTL
- int fd = -1;
- char memPath[64];
- LONG_PTR bytesWritten;
- off_t offset;
-#elif !HAVE_TTRACE
- SIZE_T FirstIntOffset;
- SIZE_T LastIntOffset;
- unsigned int FirstIntMask;
- unsigned int LastIntMask;
- SIZE_T nbInts;
- int *lpTmpBuffer = 0, *lpInt;
- int* lpBaseAddressAligned;
-#endif
-
- PERF_ENTRY(WriteProcessMemory);
- ENTRY("WriteProcessMemory (hProcess=%p,lpBaseAddress=%p, lpBuffer=%p, "
- "nSize=%u, lpNumberOfBytesWritten=%p)\n",
- hProcess,lpBaseAddress, lpBuffer, (unsigned int)nSize, lpNumberOfBytesWritten);
-
- pThread = InternalGetCurrentThread();
-
- if (!(nSize && (processId = PROCGetProcessIDFromHandle(hProcess))))
- {
- ERROR("Invalid nSize:%u number or invalid process handler "
- "hProcess:%p\n", (unsigned int)nSize, hProcess);
- SetLastError(ERROR_INVALID_PARAMETER);
- goto EXIT;
- }
-
- // Check if the write request is for the current process.
- // In that case we don't need ptrace.
- if (GetCurrentProcessId() == processId)
- {
- TRACE("We are in the same process so we don't need ptrace\n");
-
- struct Param
- {
- LPVOID lpBaseAddress;
- LPCVOID lpBuffer;
- SIZE_T nSize;
- SIZE_T numberOfBytesWritten;
- BOOL ret;
- } param;
- param.lpBaseAddress = lpBaseAddress;
- param.lpBuffer = lpBuffer;
- param.nSize = nSize;
- param.numberOfBytesWritten = numberOfBytesWritten;
- param.ret = ret;
-
- PAL_TRY(Param *, pParam, &param)
- {
- SIZE_T i;
-
- // Seg fault in memcpy can't be caught
- // so we simulate the memcpy here
-
- for (i = 0; i<pParam->nSize; i++)
- {
- *((char*)(pParam->lpBaseAddress)+i) = *((char*)(pParam->lpBuffer)+i);
- }
-
- pParam->numberOfBytesWritten = pParam->nSize;
- pParam->ret = TRUE;
- }
- PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- SetLastError(ERROR_ACCESS_DENIED);
- }
- PAL_ENDTRY
-
- numberOfBytesWritten = param.numberOfBytesWritten;
- ret = param.ret;
- goto EXIT;
- }
-
-#if HAVE_VM_READ
- result = task_for_pid(mach_task_self(), processId, &task);
- if (result != KERN_SUCCESS)
- {
- ERROR("No Mach task for pid %d: %d\n", processId, ret.Load());
- SetLastError(ERROR_INVALID_HANDLE);
- goto EXIT;
- }
- result = vm_write(task, (vm_address_t) lpBaseAddress,
- (vm_address_t) lpBuffer, nSize);
- if (result != KERN_SUCCESS)
- {
- ERROR("vm_write failed for %d bytes from %p in %d: %d\n",
- (int)nSize, lpBaseAddress, task, result);
- if (result <= KERN_RETURN_MAX)
- {
- SetLastError(ERROR_ACCESS_DENIED);
- }
- else
- {
- SetLastError(ERROR_INTERNAL_ERROR);
- }
- goto EXIT;
- }
- numberOfBytesWritten = nSize;
- ret = TRUE;
-#else // HAVE_VM_READ
-#if HAVE_PROCFS_CTL
- snprintf(memPath, sizeof(memPath), "/proc/%u/%s", processId, PROCFS_MEM_NAME);
- fd = InternalOpen(memPath, O_WRONLY);
- if (fd == -1)
+ try
{
- ERROR("Failed to open %s\n", memPath);
- SetLastError(ERROR_INVALID_ACCESS);
- goto PROCFSCLEANUP;
- }
-
- //
- // off_t may be greater in size than void*, so first cast to
- // an unsigned type to ensure that no sign extension takes place
- //
-
- offset = (off_t) (UINT_PTR) lpBaseAddress;
+ // Need to explicit h/w exception holder so to catch them in ProbeMemory
+ CatchHardwareExceptionHolder __catchHardwareException;
- if (lseek(fd, offset, SEEK_SET) == -1)
- {
- ERROR("Failed to seek to base address\n");
- SetLastError(ERROR_INVALID_ACCESS);
- goto PROCFSCLEANUP;
+ ProbeMemory((PBYTE)pBuffer, cbBuffer, fWriteAccess);
}
-
- bytesWritten = write(fd, lpBuffer, nSize);
- if (bytesWritten < 0)
- {
- ERROR("Failed to write to %s\n", memPath);
- SetLastError(ERROR_INVALID_ACCESS);
- goto PROCFSCLEANUP;
- }
-
- numberOfBytesWritten = bytesWritten;
- ret = TRUE;
-
-#else // HAVE_PROCFS_CTL
- /* Attach the process before calling ptrace otherwise it fails */
- if (DBGAttachProcess(pThread, hProcess, processId))
+ catch(...)
{
-#if HAVE_TTRACE
- if (ttrace(TT_PROC_WRDATA, processId, 0, (__uint64_t)lpBaseAddress, (__uint64_t)nSize, (__uint64_t)lpBuffer) == -1)
- {
- if (errno == EFAULT)
- {
- ERROR("ttrace(TT_PROC_WRDATA, pid:%d, addr:%p, data:%d, addr2:%d) failed"
- " errno=%d (%s)\n", processId, lpBaseAddress, nSize, lpBuffer,
- errno, strerror(errno));
-
- SetLastError(ERROR_ACCESS_DENIED);
- }
- else
- {
- ASSERT("ttrace(TT_PROC_WRDATA, pid:%d, addr:%p, data:%d, addr2:%d) failed"
- " errno=%d (%s)\n", processId, lpBaseAddress, nSize, lpBuffer,
- errno, strerror(errno));
- SetLastError(ERROR_INTERNAL_ERROR);
- }
-
- goto CLEANUP1;
- }
-
- numberOfBytesWritten = nSize;
- ret = TRUE;
-
-#else // HAVE_TTRACE
-
- FirstIntOffset = (SIZE_T)lpBaseAddress % sizeof(int);
- FirstIntMask = -1;
- FirstIntMask <<= (FirstIntOffset * 8);
-
- nbInts = (nSize + FirstIntOffset) / sizeof(int) +
- (((nSize + FirstIntOffset)%sizeof(int)) ? 1:0);
- lpBaseAddressAligned = (int*)((char*)lpBaseAddress - FirstIntOffset);
-
- if ((lpTmpBuffer = (int*)InternalMalloc((nbInts * sizeof(int)))) == NULL)
- {
- ERROR("Insufficient memory available !\n");
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- goto CLEANUP1;
- }
-
- memcpy((char *)lpTmpBuffer + FirstIntOffset, (char *)lpBuffer, nSize);
- lpInt = lpTmpBuffer;
-
- LastIntOffset = (nSize + FirstIntOffset) % sizeof(int);
- LastIntMask = -1;
- LastIntMask >>= ((sizeof(int) - LastIntOffset) * 8);
-
- if (nbInts == 1)
- {
- if (DBGWriteProcMem_IntWithMask(processId, lpBaseAddressAligned,
- *lpInt,
- LastIntMask & FirstIntMask)
- == 0)
- {
- goto CLEANUP2;
- }
- numberOfBytesWritten = nSize;
- ret = TRUE;
- goto CLEANUP2;
- }
-
- if (DBGWriteProcMem_IntWithMask(processId,
- lpBaseAddressAligned++,
- *lpInt++, FirstIntMask)
- == 0)
- {
- goto CLEANUP2;
- }
-
- while (--nbInts > 1)
- {
- if (DBGWriteProcMem_Int(processId, lpBaseAddressAligned++,
- *lpInt++) == 0)
- {
- goto CLEANUP2;
- }
- }
-
- if (DBGWriteProcMem_IntWithMask(processId, lpBaseAddressAligned,
- *lpInt, LastIntMask ) == 0)
- {
- goto CLEANUP2;
- }
-
- numberOfBytesWritten = nSize;
- ret = TRUE;
-#endif // HAVE_TTRACE
- }
- else
- {
- /* Failed to attach processId */
- goto EXIT;
- }
-#endif // HAVE_PROCFS_CTL
-
-#if HAVE_PROCFS_CTL
-PROCFSCLEANUP:
- if (fd != -1)
- {
- close(fd);
- }
-#elif !HAVE_TTRACE
-CLEANUP2:
- if (lpTmpBuffer)
- {
- free(lpTmpBuffer);
- }
-#endif // !HAVE_TTRACE
-
-#if !HAVE_PROCFS_CTL
-CLEANUP1:
- if (!DBGDetachProcess(pThread, hProcess, processId))
- {
- /* Failed to detach processId */
- ret = FALSE;
- }
-#endif // !HAVE_PROCFS_CTL
-#endif // HAVE_VM_READ
-
-EXIT:
- if (lpNumberOfBytesWritten)
- {
- *lpNumberOfBytesWritten = numberOfBytesWritten;
+ return FALSE;
}
-
- LOGEXIT("WriteProcessMemory returns BOOL %d\n", ret.Load());
- PERF_EXIT(WriteProcessMemory);
- return ret;
+ return TRUE;
}
} // extern "C"
diff --git a/src/pal/src/examples/CMakeLists.txt b/src/pal/src/examples/CMakeLists.txt
index 2cef914892..3797d89b68 100644
--- a/src/pal/src/examples/CMakeLists.txt
+++ b/src/pal/src/examples/CMakeLists.txt
@@ -4,7 +4,7 @@ project(palexmpl)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- example1.c
+ example1.cpp
)
add_executable(palexmpl
diff --git a/src/pal/src/examples/example1.c b/src/pal/src/examples/example1.cpp
index 071f42e4f9..071f42e4f9 100644
--- a/src/pal/src/examples/example1.c
+++ b/src/pal/src/examples/example1.cpp
diff --git a/src/pal/src/exception/machexception.cpp b/src/pal/src/exception/machexception.cpp
index 8b0d7f22a8..5328e1f329 100644
--- a/src/pal/src/exception/machexception.cpp
+++ b/src/pal/src/exception/machexception.cpp
@@ -1518,6 +1518,7 @@ ActivationHandler(CONTEXT* context)
extern "C" void ActivationHandlerWrapper();
extern "C" int ActivationHandlerReturnOffset;
+extern "C" unsigned int XmmYmmStateSupport();
/*++
Function :
@@ -1581,6 +1582,12 @@ InjectActivationInternal(CPalThread* pThread)
// after the activation function returns.
CONTEXT *pContext = (CONTEXT *)contextAddress;
pContext->ContextFlags = CONTEXT_FULL | CONTEXT_SEGMENTS;
+#ifdef XSTATE_SUPPORTED
+ if (XmmYmmStateSupport() == 1)
+ {
+ pContext->ContextFlags |= CONTEXT_XSTATE;
+ }
+#endif
MachRet = CONTEXT_GetThreadContextFromPort(threadPort, pContext);
_ASSERT_MSG(MachRet == KERN_SUCCESS, "CONTEXT_GetThreadContextFromPort\n");
diff --git a/src/pal/src/exception/machmessage.cpp b/src/pal/src/exception/machmessage.cpp
index a6f7e57484..b786960782 100644
--- a/src/pal/src/exception/machmessage.cpp
+++ b/src/pal/src/exception/machmessage.cpp
@@ -1069,7 +1069,7 @@ thread_act_t MachMessage::GetThreadFromState(thread_state_flavor_t eFlavor, thre
NONPAL_RETAIL_ASSERT("Failed to locate thread from state.");
}
-// Transform a exception handler behavior type into the corresponding Mach message ID for the notification.
+// Transform an exception handler behavior type into the corresponding Mach message ID for the notification.
mach_msg_id_t MachMessage::MapBehaviorToNotificationType(exception_behavior_t eBehavior)
{
switch ((uint)eBehavior)
diff --git a/src/pal/src/exception/machmessage.h b/src/pal/src/exception/machmessage.h
index 244396cd35..abc583f6c4 100644
--- a/src/pal/src/exception/machmessage.h
+++ b/src/pal/src/exception/machmessage.h
@@ -36,7 +36,7 @@ using namespace CorUnix;
if (machret != KERN_SUCCESS) \
{ \
char _szError[1024]; \
- sprintf(_szError, "%s: %u: %s", __FUNCTION__, __LINE__, _msg); \
+ snprintf(_szError, _countof(_szError), "%s: %u: %s", __FUNCTION__, __LINE__, _msg); \
mach_error(_szError, machret); \
abort(); \
} \
@@ -395,7 +395,7 @@ private:
// x86_THREAD_STATE and x86_THREAD_STATE32 state flavors are supported.
thread_act_t GetThreadFromState(thread_state_flavor_t eFlavor, thread_state_t pState);
- // Transform a exception handler behavior type into the corresponding Mach message ID for the
+ // Transform an exception handler behavior type into the corresponding Mach message ID for the
// notification.
mach_msg_id_t MapBehaviorToNotificationType(exception_behavior_t eBehavior);
diff --git a/src/pal/src/exception/seh-unwind.cpp b/src/pal/src/exception/seh-unwind.cpp
index 24eebbbf94..fa2f109875 100644
--- a/src/pal/src/exception/seh-unwind.cpp
+++ b/src/pal/src/exception/seh-unwind.cpp
@@ -73,6 +73,14 @@ Abstract:
ASSIGN_REG(X26) \
ASSIGN_REG(X27) \
ASSIGN_REG(X28)
+#elif defined(_X86_)
+#define ASSIGN_UNWIND_REGS \
+ ASSIGN_REG(Eip) \
+ ASSIGN_REG(Esp) \
+ ASSIGN_REG(Ebp) \
+ ASSIGN_REG(Ebx) \
+ ASSIGN_REG(Esi) \
+ ASSIGN_REG(Edi)
#else
#error unsupported architecture
#endif
@@ -122,6 +130,13 @@ static void WinContextToUnwindCursor(CONTEXT *winContext, unw_cursor_t *cursor)
unw_set_reg(cursor, UNW_X86_64_R13, winContext->R13);
unw_set_reg(cursor, UNW_X86_64_R14, winContext->R14);
unw_set_reg(cursor, UNW_X86_64_R15, winContext->R15);
+#elif defined(_X86_)
+ unw_set_reg(cursor, UNW_REG_IP, winContext->Eip);
+ unw_set_reg(cursor, UNW_REG_SP, winContext->Esp);
+ unw_set_reg(cursor, UNW_X86_EBP, winContext->Ebp);
+ unw_set_reg(cursor, UNW_X86_EBX, winContext->Ebx);
+ unw_set_reg(cursor, UNW_X86_ESI, winContext->Esi);
+ unw_set_reg(cursor, UNW_X86_EDI, winContext->Edi);
#endif
}
#endif
@@ -137,6 +152,13 @@ static void UnwindContextToWinContext(unw_cursor_t *cursor, CONTEXT *winContext)
unw_get_reg(cursor, UNW_X86_64_R13, (unw_word_t *) &winContext->R13);
unw_get_reg(cursor, UNW_X86_64_R14, (unw_word_t *) &winContext->R14);
unw_get_reg(cursor, UNW_X86_64_R15, (unw_word_t *) &winContext->R15);
+#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_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);
+ unw_get_reg(cursor, UNW_X86_EDI, (unw_word_t *) &winContext->Edi);
#elif defined(_ARM_)
unw_get_reg(cursor, UNW_REG_SP, (unw_word_t *) &winContext->Sp);
unw_get_reg(cursor, UNW_REG_IP, (unw_word_t *) &winContext->Pc);
@@ -196,6 +218,11 @@ static void GetContextPointers(unw_cursor_t *cursor, unw_context_t *unwContext,
GetContextPointer(cursor, unwContext, UNW_X86_64_R13, &contextPointers->R13);
GetContextPointer(cursor, unwContext, UNW_X86_64_R14, &contextPointers->R14);
GetContextPointer(cursor, unwContext, UNW_X86_64_R15, &contextPointers->R15);
+#elif defined(_X86_)
+ GetContextPointer(cursor, unwContext, UNW_X86_EBX, &contextPointers->Ebx);
+ GetContextPointer(cursor, unwContext, UNW_X86_EBP, &contextPointers->Ebp);
+ GetContextPointer(cursor, unwContext, UNW_X86_ESI, &contextPointers->Esi);
+ GetContextPointer(cursor, unwContext, UNW_X86_EDI, &contextPointers->Edi);
#elif defined(_ARM_)
GetContextPointer(cursor, unwContext, UNW_ARM_R4, &contextPointers->R4);
GetContextPointer(cursor, unwContext, UNW_ARM_R5, &contextPointers->R5);
@@ -221,15 +248,34 @@ static void GetContextPointers(unw_cursor_t *cursor, unw_context_t *unwContext,
#endif
}
+extern int g_common_signal_handler_context_locvar_offset;
+
BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextPointers)
{
int st;
unw_context_t unwContext;
unw_cursor_t cursor;
-#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(_ARM64_) || defined(_ARM_)
- DWORD64 curPc;
-#endif
+ DWORD64 curPc = CONTEXTGetPC(context);
+
+#ifndef __APPLE__
+ // Check if the PC is the return address from the SEHProcessException in the common_signal_handler.
+ // If that's the case, extract its local variable containing the native_context_t of the hardware
+ // exception and return that. This skips the hardware signal handler trampoline that the libunwind
+ // cannot cross on some systems.
+ if ((void*)curPc == g_SEHProcessExceptionReturnAddress)
+ {
+ ULONG contextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT | CONTEXT_EXCEPTION_ACTIVE;
+
+ #if defined(_AMD64_)
+ contextFlags |= CONTEXT_XSTATE;
+ #endif
+ size_t nativeContext = *(size_t*)(CONTEXTGetFP(context) + g_common_signal_handler_context_locvar_offset);
+ CONTEXTFromNativeContext((const native_context_t *)nativeContext, context, contextFlags);
+
+ return TRUE;
+ }
+#endif
if ((context->ContextFlags & CONTEXT_EXCEPTION_ACTIVE) != 0)
{
@@ -240,7 +286,7 @@ BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextP
// So we compensate it by incrementing the PC before passing it to the unwinder.
// Without it, the unwinder would not find unwind info if the hardware exception
// happened in the first instruction of a function.
- CONTEXTSetPC(context, CONTEXTGetPC(context) + 1);
+ CONTEXTSetPC(context, curPc + 1);
}
#if !UNWIND_CONTEXT_IS_UCONTEXT_T
@@ -264,18 +310,6 @@ BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextP
WinContextToUnwindCursor(context, &cursor);
#endif
-#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(_ARM64_) || defined(_ARM_)
- // FreeBSD, NetBSD and OSX appear to do two different things when unwinding
- // 1: If it reaches where it cannot unwind anymore, say a
- // managed frame. It wil return 0, but also update the $pc
- // 2: If it unwinds all the way to _start it will return
- // 0 from the step, but $pc will stay the same.
- // The behaviour of libunwind from nongnu.org is to null the PC
- // So we bank the original PC here, so we can compare it after
- // the step
- curPc = CONTEXTGetPC(context);
-#endif
-
st = unw_step(&cursor);
if (st < 0)
{
@@ -303,12 +337,18 @@ BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextP
// Update the passed in windows context to reflect the unwind
//
UnwindContextToWinContext(&cursor, context);
-#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(_ARM64_) || defined(_ARM_)
+
+ // FreeBSD, NetBSD, OSX and Alpine appear to do two different things when unwinding
+ // 1: If it reaches where it cannot unwind anymore, say a
+ // managed frame. It will return 0, but also update the $pc
+ // 2: If it unwinds all the way to _start it will return
+ // 0 from the step, but $pc will stay the same.
+ // So we detect that here and set the $pc to NULL in that case.
+ // This is the default behavior of the libunwind on Linux.
if (st == 0 && CONTEXTGetPC(context) == curPc)
{
CONTEXTSetPC(context, 0);
}
-#endif
if (contextPointers != NULL)
{
diff --git a/src/pal/src/exception/seh.cpp b/src/pal/src/exception/seh.cpp
index 38779bf59b..ad09e02884 100644
--- a/src/pal/src/exception/seh.cpp
+++ b/src/pal/src/exception/seh.cpp
@@ -88,6 +88,10 @@ PHARDWARE_EXCEPTION_SAFETY_CHECK_FUNCTION g_safeExceptionCheckFunction = NULL;
PGET_GCMARKER_EXCEPTION_CODE g_getGcMarkerExceptionCode = NULL;
+// Return address of the SEHProcessException, which is used to enable walking over
+// the signal handler trampoline on some Unixes where the libunwind cannot do that.
+void* g_SEHProcessExceptionReturnAddress = NULL;
+
/* Internal function definitions **********************************************/
/*++
@@ -245,6 +249,8 @@ Return value:
BOOL
SEHProcessException(PAL_SEHException* exception)
{
+ g_SEHProcessExceptionReturnAddress = __builtin_return_address(0);
+
CONTEXT* contextRecord = exception->GetContextRecord();
EXCEPTION_RECORD* exceptionRecord = exception->GetExceptionRecord();
@@ -268,7 +274,7 @@ SEHProcessException(PAL_SEHException* exception)
{
// The exception happened in the page right below the stack limit,
// so it is a stack overflow
- write(STDERR_FILENO, StackOverflowMessage, sizeof(StackOverflowMessage) - 1);
+ (void)write(STDERR_FILENO, StackOverflowMessage, sizeof(StackOverflowMessage) - 1);
PROCAbort();
}
}
diff --git a/src/pal/src/exception/signal.cpp b/src/pal/src/exception/signal.cpp
index c2c217993a..26e2a012c5 100644
--- a/src/pal/src/exception/signal.cpp
+++ b/src/pal/src/exception/signal.cpp
@@ -100,6 +100,10 @@ static bool registered_sigterm_handler = false;
struct sigaction g_previous_activation;
#endif
+// 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;
+
/* public function definitions ************************************************/
/*++
@@ -582,6 +586,7 @@ Note:
the "pointers" parameter should contain a valid exception record pointer,
but the ContextRecord pointer will be overwritten.
--*/
+__attribute__((noinline))
static bool common_signal_handler(int code, siginfo_t *siginfo, void *sigcontext, int numParams, ...)
{
sigset_t signal_set;
@@ -590,6 +595,7 @@ static bool common_signal_handler(int code, siginfo_t *siginfo, void *sigcontext
native_context_t *ucontext;
ucontext = (native_context_t *)sigcontext;
+ g_common_signal_handler_context_locvar_offset = (int)((char*)&ucontext - (char*)__builtin_frame_address(0));
AllocateExceptionRecords(&exceptionRecord, &contextRecord);
diff --git a/src/pal/src/file/find.cpp b/src/pal/src/file/find.cpp
index 18639d3d14..18bf8c4cf1 100644
--- a/src/pal/src/file/find.cpp
+++ b/src/pal/src/file/find.cpp
@@ -383,7 +383,7 @@ FindNextFileA(
// Split the path into a dir and filename.
if (_splitpath_s(path, NULL, 0, find_data->dir, _MAX_DIR, find_data->fname, _MAX_PATH, ext, _MAX_EXT) != 0)
{
- ASSERT("_splitpath failed on %s\n", path);
+ ASSERT("_splitpath_s failed on %s\n", path);
dwLastError = ERROR_INTERNAL_ERROR;
goto done;
}
@@ -716,7 +716,7 @@ Simple helper function to insert backslashes before square brackets
to prevent glob from using them as wildcards.
note: this functions assumes all backslashes have previously been
- converted into forwardslashes by _splitpath.
+ converted into forwardslashes by _splitpath_s.
--*/
static void FILEEscapeSquareBrackets(char *pattern, char *escaped_pattern)
{
@@ -750,7 +750,7 @@ Function:
FILEGlobFromSplitPath
Simple wrapper function around glob(3), except that the pattern is accepted
-in broken-down form like _splitpath produces.
+in broken-down form like _splitpath_s produces.
ie. calling splitpath on a pattern then calling this function should
produce the same result as just calling glob() on the pattern.
@@ -874,12 +874,12 @@ static BOOL FILEDosGlobA( CPalThread *pthrCurrent,
_splitpath_s( pattern, NULL, 0, Dir, _MAX_DIR, Filename, _MAX_FNAME+1, Ext, _MAX_EXT);
- /* check to see if _splitpath failed */
+ /* check to see if _splitpath_s failed */
if ( Filename[0] == 0 )
{
if ( Dir[0] == 0 )
{
- ERROR("_splitpath failed on path [%s]\n", pattern);
+ ERROR("_splitpath_s failed on path [%s]\n", pattern);
}
else
{
diff --git a/src/pal/src/include/pal/context.h b/src/pal/src/include/pal/context.h
index 5e378942fb..6857c130ee 100644
--- a/src/pal/src/include/pal/context.h
+++ b/src/pal/src/include/pal/context.h
@@ -139,6 +139,8 @@ typedef ucontext_t native_context_t;
/////////////////////
// Extended state
+#ifdef XSTATE_SUPPORTED
+
inline _fpx_sw_bytes *FPREG_FpxSwBytes(const ucontext_t *uc)
{
// Bytes 464..511 in the FXSAVE format are available for software to use for any purpose. In this case, they are used to
@@ -185,6 +187,8 @@ inline void *FPREG_Xstate_Ymmh(const ucontext_t *uc)
return reinterpret_cast<_xstate *>(FPREG_Fpstate(uc))->ymmh.ymmh_space;
}
+#endif // XSTATE_SUPPORTED
+
/////////////////////
#else // BIT64
@@ -450,6 +454,8 @@ inline static DWORD64 CONTEXTGetPC(LPCONTEXT pContext)
{
#if defined(_AMD64_)
return pContext->Rip;
+#elif defined(_X86_)
+ return pContext->Eip;
#elif defined(_ARM64_) || defined(_ARM_)
return pContext->Pc;
#else
@@ -461,6 +467,8 @@ inline static void CONTEXTSetPC(LPCONTEXT pContext, DWORD64 pc)
{
#if defined(_AMD64_)
pContext->Rip = pc;
+#elif defined(_X86_)
+ pContext->Eip = pc;
#elif defined(_ARM64_) || defined(_ARM_)
pContext->Pc = pc;
#else
@@ -468,6 +476,21 @@ inline static void CONTEXTSetPC(LPCONTEXT pContext, DWORD64 pc)
#endif
}
+inline static DWORD64 CONTEXTGetFP(LPCONTEXT pContext)
+{
+#if defined(_AMD64_)
+ return pContext->Rbp;
+#elif defined(_X86_)
+ return pContext->Ebp;
+#elif defined(_ARM_)
+ return pContext->R7;
+#elif defined(_ARM64_)
+ return pContext->Fp;
+#else
+#error don't know how to get the frame pointer for this architecture
+#endif
+}
+
/*++
Function :
CONTEXT_CaptureContext
@@ -481,6 +504,7 @@ Parameters :
--*/
void
+PALAPI
CONTEXT_CaptureContext(
LPCONTEXT lpContext
);
diff --git a/src/pal/src/include/pal/palinternal.h b/src/pal/src/include/pal/palinternal.h
index 7348192e6d..f7856be902 100644
--- a/src/pal/src/include/pal/palinternal.h
+++ b/src/pal/src/include/pal/palinternal.h
@@ -169,7 +169,6 @@ function_name() to call the system's implementation
#define memmove DUMMY_memmove
#define memchr DUMMY_memchr
#define strlen DUMMY_strlen
-#define strnlen DUMMY_strnlen
#define stricmp DUMMY_stricmp
#define strstr DUMMY_strstr
#define strcmp DUMMY_strcmp
@@ -184,12 +183,6 @@ function_name() to call the system's implementation
#define strpbrk DUMMY_strpbrk
#define strtod DUMMY_strtod
#define strspn DUMMY_strspn
-#if HAVE__SNPRINTF
-#define _snprintf DUMMY__snprintf
-#endif /* HAVE__SNPRINTF */
-#if HAVE__SNWPRINTF
-#define _snwprintf DUMMY__snwprintf
-#endif /* HAVE__SNWPRINTF */
#define tolower DUMMY_tolower
#define toupper DUMMY_toupper
#define islower DUMMY_islower
@@ -217,9 +210,18 @@ function_name() to call the system's implementation
#define sqrt DUMMY_sqrt
#define tan DUMMY_tan
#define tanh DUMMY_tanh
+#define ceilf DUMMY_ceilf
+#define cosf DUMMY_cosf
+#define coshf DUMMY_coshf
#define fabsf DUMMY_fabsf
+#define floorf DUMMY_floorf
#define fmodf DUMMY_fmodf
#define modff DUMMY_modff
+#define sinf DUMMY_sinf
+#define sinhf DUMMY_sinhf
+#define sqrtf DUMMY_sqrtf
+#define tanf DUMMY_tanf
+#define tanhf DUMMY_tanhf
/* RAND_MAX needed to be renamed to avoid duplicate definition when including
stdlib.h header files. PAL_RAND_MAX should have the same value as RAND_MAX
@@ -349,9 +351,7 @@ function_name() to call the system's implementation
#undef atexit
#undef div
#undef div_t
-#if !defined(_DEBUG)
#undef memcpy
-#endif //!defined(_DEBUG)
#undef memcmp
#undef memset
#undef memmove
@@ -460,9 +460,26 @@ function_name() to call the system's implementation
#undef sqrt
#undef tan
#undef tanh
+#undef acosf
+#undef asinf
+#undef atanf
+#undef atan2f
+#undef ceilf
+#undef cosf
+#undef coshf
+#undef expf
#undef fabsf
+#undef floorf
#undef fmodf
+#undef logf
+#undef log10f
#undef modff
+#undef powf
+#undef sinf
+#undef sinhf
+#undef sqrtf
+#undef tanf
+#undef tanhf
#undef rand
#undef srand
#undef errno
@@ -485,13 +502,7 @@ function_name() to call the system's implementation
#undef vfwprintf
#undef vprintf
#undef wprintf
-#undef sprintf
#undef swprintf
-#undef _snprintf
-#if HAVE__SNWPRINTF
-#undef _snwprintf
-#endif /* HAVE__SNWPRINTF */
-#undef sscanf
#undef wcstod
#undef wcstol
#undef wcstoul
@@ -502,7 +513,6 @@ function_name() to call the system's implementation
#undef wcsncmp
#undef wcschr
#undef wcsrchr
-#undef wsprintf
#undef swscanf
#undef wcspbrk
#undef wcsstr
@@ -518,7 +528,6 @@ function_name() to call the system's implementation
#undef vsprintf
#undef vswprintf
#undef _vsnprintf
-#undef _vsnwprintf
#undef vsnprintf
#undef wvsnprintf
@@ -689,7 +698,7 @@ inline T* InterlockedCompareExchangePointerT(
#include "volatile.h"
-const char StackOverflowMessage[] = "Process is terminated due to StackOverflowException.\n";
+const char StackOverflowMessage[] = "Process is terminating due to StackOverflowException.\n";
#endif // __cplusplus
diff --git a/src/pal/src/init/pal.cpp b/src/pal/src/init/pal.cpp
index a5edb36428..0bda27644e 100644
--- a/src/pal/src/init/pal.cpp
+++ b/src/pal/src/init/pal.cpp
@@ -992,6 +992,7 @@ Return value:
--*/
static BOOL INIT_IncreaseDescriptorLimit(void)
{
+#ifndef DONT_SET_RLIMIT_NOFILE
struct rlimit rlp;
int result;
@@ -1008,7 +1009,7 @@ static BOOL INIT_IncreaseDescriptorLimit(void)
{
return FALSE;
}
-
+#endif // !DONT_SET_RLIMIT_NOFILE
return TRUE;
}
diff --git a/src/pal/src/map/virtual.cpp b/src/pal/src/map/virtual.cpp
index 4b5209642c..4a55de9891 100644
--- a/src/pal/src/map/virtual.cpp
+++ b/src/pal/src/map/virtual.cpp
@@ -1096,6 +1096,7 @@ VIRTUALCommitMemory(
}
StartBoundary = pInformation->startBoundary + runStart * VIRTUAL_PAGE_SIZE;
+ pRetVal = (void *)StartBoundary;
MemSize = runLength * VIRTUAL_PAGE_SIZE;
if (allocationType != MEM_COMMIT)
@@ -1156,10 +1157,10 @@ error:
pRetVal = NULL;
goto done;
}
- pInformation = NULL;
- pRetVal = NULL;
}
+ pInformation = NULL;
+ pRetVal = NULL;
done:
LogVaOperation(
diff --git a/src/pal/src/misc/sysinfo.cpp b/src/pal/src/misc/sysinfo.cpp
index 515ccf1cdb..e7589e8583 100644
--- a/src/pal/src/misc/sysinfo.cpp
+++ b/src/pal/src/misc/sysinfo.cpp
@@ -172,7 +172,7 @@ GetSystemInfo(
#ifdef VM_MAXUSER_ADDRESS
lpSystemInfo->lpMaximumApplicationAddress = (PVOID) VM_MAXUSER_ADDRESS;
#elif defined(__sun__) || defined(_AIX) || defined(__hppa__) || ( defined (_IA64_) && defined (_HPUX_) ) || defined(__linux__)
- lpSystemInfo->lpMaximumApplicationAddress = (PVOID) -1;
+ lpSystemInfo->lpMaximumApplicationAddress = (PVOID) (1ull << 47);
#elif defined(USERLIMIT)
lpSystemInfo->lpMaximumApplicationAddress = (PVOID) USERLIMIT;
#elif defined(_WIN64)
diff --git a/src/pal/src/safecrt/input.inl b/src/pal/src/safecrt/input.inl
index eaad174ff5..25c4541029 100644
--- a/src/pal/src/safecrt/input.inl
+++ b/src/pal/src/safecrt/input.inl
@@ -671,7 +671,7 @@ scanit:
#endif /* _SECURE_SCANF */
#ifndef _UNICODE
if (fl_wchar_arg) {
- wctemp = L'?';
+ wctemp = W('?');
char temp[2];
temp[0] = (char) ch;
#if 0 // we are not supporting multibyte input strings
@@ -682,7 +682,7 @@ scanit:
#endif /* 0 */
_MBTOWC(&wctemp, temp, MB_CUR_MAX);
*(wchar_t UNALIGNED *)pointer = wctemp;
- /* just copy L'?' if mbtowc fails, errno is set by mbtowc */
+ /* just copy W('?') if mbtowc fails, errno is set by mbtowc */
pointer = (wchar_t *)pointer + 1;
#ifdef _SECURE_SCANF
--array_width;
diff --git a/src/pal/src/safecrt/makepath_s.c b/src/pal/src/safecrt/makepath_s.cpp
index 4342685b9c..4342685b9c 100644
--- a/src/pal/src/safecrt/makepath_s.c
+++ b/src/pal/src/safecrt/makepath_s.cpp
diff --git a/src/pal/src/safecrt/mbusafecrt.c b/src/pal/src/safecrt/mbusafecrt.c
deleted file mode 100644
index ca853d9269..0000000000
--- a/src/pal/src/safecrt/mbusafecrt.c
+++ /dev/null
@@ -1,254 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/***
-* mbusafecrt.c - implementaion of support functions and data for MBUSafeCRT
-*
-
-*
-* Purpose:
-* This file contains the implementation of support functions and
-* data for MBUSafeCRT declared in mbusafecrt.h and mbusafecrt_internal.h.
-****/
-
-#include "pal/palinternal.h"
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-
-#include "mbusafecrt_internal.h"
-
-/* global data */
-tSafeCRT_AssertFuncPtr sMBUSafeCRTAssertFunc = NULL;
-
-/***
-* MBUSafeCRTSetAssertFunc - Set the function called when an assert fails.
-****/
-
-void MBUSafeCRTSetAssertFunc( tSafeCRT_AssertFuncPtr inAssertFuncPtr )
-{
- /* set it */
- sMBUSafeCRTAssertFunc = inAssertFuncPtr;
-}
-
-/***
-* _putc_nolock - putc for the miniFILE stream.
-****/
-
-int _putc_nolock( char inChar, miniFILE* inStream )
-{
- int returnValue = EOF;
-
- inStream->_cnt -= sizeof( char );
-
- if ( ( inStream->_cnt ) >= 0 )
- {
- *( inStream->_ptr ) = inChar;
- inStream->_ptr += sizeof( char );
- returnValue = ( int )inChar;
- }
-
- return returnValue;
-}
-
-/***
-* _putwc_nolock - putwc for the miniFILE stream.
-****/
-
-int _putwc_nolock( wchar_t inChar, miniFILE* inStream )
-{
- int returnValue = WEOF;
-
- inStream->_cnt -= sizeof( wchar_t );
-
- if ( ( inStream->_cnt ) >= 0 )
- {
- *( ( wchar_t* )( inStream->_ptr ) ) = inChar;
- inStream->_ptr += sizeof( wchar_t );
- returnValue = ( int )inChar;
- }
-
- return returnValue;
-}
-
-/***
-* _getc_nolock - getc for the miniFILE stream.
-****/
-
-int _getc_nolock( miniFILE* inStream )
-{
- int returnValue = EOF;
-
- if ( ( inStream->_cnt ) >= ( int )( sizeof( char ) ) )
- {
- inStream->_cnt -= sizeof( char );
- returnValue = ( int )( *( inStream->_ptr ) );
- inStream->_ptr += sizeof( char );
- }
-
- return returnValue;
-}
-
-/***
-* _getwc_nolock - getc for the miniFILE stream.
-****/
-
-int _getwc_nolock( miniFILE* inStream )
-{
- int returnValue = EOF;
-
- if ( ( inStream->_cnt ) >= ( int )( sizeof( wchar_t ) ) )
- {
- inStream->_cnt -= sizeof( wchar_t );
- returnValue = ( int )( *( ( wchar_t* )( inStream->_ptr ) ) );
- inStream->_ptr += sizeof( wchar_t );
- }
-
- return returnValue;
-}
-
-/***
-* _ungetc_nolock - ungetc for the miniFILE stream.
-****/
-
-int _ungetc_nolock( char inChar, miniFILE* inStream )
-{
- int returnValue = EOF;
-
- if ( ( size_t )( ( inStream->_ptr ) - ( inStream->_base ) ) >= ( sizeof( char ) ) )
- {
- inStream->_cnt += sizeof( char );
- inStream->_ptr -= sizeof( char );
- return ( int )inChar;
- }
-
- return returnValue;
-}
-
-/***
-* _ungetwc_nolock - ungetwc for the miniFILE stream.
-****/
-
-int _ungetwc_nolock( wchar_t inChar, miniFILE* inStream )
-{
- int returnValue = WEOF;
-
- if ( ( size_t )( ( inStream->_ptr ) - ( inStream->_base ) ) >= ( sizeof( wchar_t ) ) )
- {
- inStream->_cnt += sizeof( wchar_t );
- inStream->_ptr -= sizeof( wchar_t );
- returnValue = ( unsigned short )inChar;
- }
-
- return returnValue;
-}
-
-
-/***
-* _safecrt_cfltcvt - convert a float to an ascii string.
-* Uses sprintf - this usage is OK.
-****/
-
-/* routine used for floating-point output */
-#define FORMATSIZE 30
-
-#define _snprintf snprintf
-
-// taken from output.inl
-#define FL_ALTERNATE 0x00080 /* alternate form requested */
-
-errno_t _safecrt_cfltcvt(double *arg, char *buffer, size_t sizeInBytes, int type, int precision, int flags)
-{
- char format[FORMATSIZE];
- size_t formatlen = 0;
- int retvalue;
-
- if (flags & 1)
- {
- type -= 'a' - 'A';
- }
- formatlen = 0;
- format[formatlen++] = '%';
- if (flags & FL_ALTERNATE)
- {
- format[formatlen++] = '#';
- }
- format[formatlen++] = '.';
- _itoa_s(precision, format + formatlen, FORMATSIZE - formatlen, 10);
- formatlen = strlen(format);
- format[formatlen++] = (char)type;
- format[formatlen] = 0;
-
- buffer[sizeInBytes - 1] = 0;
- retvalue = _snprintf(buffer, sizeInBytes, format, *arg);
- if (buffer[sizeInBytes - 1] != 0 || retvalue <= 0)
- {
- buffer[0] = 0;
- return EINVAL;
- }
- return 0;
-}
-
-
-/***
-* _safecrt_fassign - convert a string into a float or double.
-****/
-
-void _safecrt_fassign(int flag, void* argument, char* number )
-{
- if ( flag != 0 ) // double
- {
- double dblValue = 0.0;
- (void)sscanf( number, "%lf", &dblValue );
- *( ( double* )argument ) = dblValue;
- }
- else // float
- {
- float fltValue = 0.0;
- (void)sscanf( number, "%f", &fltValue );
- *( ( float* )argument ) = fltValue;
- }
-}
-
-
-/***
-* _safecrt_wfassign - convert a wchar_t string into a float or double.
-****/
-
-void _safecrt_wfassign(int flag, void* argument, wchar_t* number )
-{
- // We cannot use system functions for this - they
- // assume that wchar_t is four bytes, while we assume
- // two. So, we need to convert to a regular char string
- // without using any system functions. To do this,
- // we'll assume that the numbers are in the 0-9 range and
- // do a simple conversion.
-
- char* numberAsChars = ( char* )number;
- int position = 0;
-
- // do the convert
- while ( number[ position ] != 0 )
- {
- numberAsChars[ position ] = ( char )( number[ position ] & 0x00FF );
- position++;
- }
- numberAsChars[ position ] = ( char )( number[ position ] & 0x00FF );
-
- // call the normal char version
- _safecrt_fassign( flag, argument, numberAsChars );
-}
-
-
-/***
-* _minimal_chartowchar - do a simple char to wchar conversion.
-****/
-
-int _minimal_chartowchar( wchar_t* outWChar, const char* inChar )
-{
- *outWChar = ( wchar_t )( ( unsigned short )( ( unsigned char )( *inChar ) ) );
- return 1;
-}
-
-
diff --git a/src/pal/src/safecrt/mbusafecrt.cpp b/src/pal/src/safecrt/mbusafecrt.cpp
new file mode 100644
index 0000000000..4446f77fd1
--- /dev/null
+++ b/src/pal/src/safecrt/mbusafecrt.cpp
@@ -0,0 +1,249 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/***
+* mbusafecrt.c - implementaion of support functions and data for MBUSafeCRT
+*
+
+*
+* Purpose:
+* This file contains the implementation of support functions and
+* data for MBUSafeCRT declared in mbusafecrt.h and mbusafecrt_internal.h.
+****/
+
+#include "pal/palinternal.h"
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+
+#include "mbusafecrt_internal.h"
+
+/* global data */
+tSafeCRT_AssertFuncPtr sMBUSafeCRTAssertFunc = NULL;
+
+/***
+* MBUSafeCRTSetAssertFunc - Set the function called when an assert fails.
+****/
+
+void MBUSafeCRTSetAssertFunc( tSafeCRT_AssertFuncPtr inAssertFuncPtr )
+{
+ /* set it */
+ sMBUSafeCRTAssertFunc = inAssertFuncPtr;
+}
+
+/***
+* _putc_nolock - putc for the miniFILE stream.
+****/
+
+int _putc_nolock( char inChar, miniFILE* inStream )
+{
+ int returnValue = EOF;
+
+ inStream->_cnt -= sizeof( char );
+
+ if ( ( inStream->_cnt ) >= 0 )
+ {
+ *( inStream->_ptr ) = inChar;
+ inStream->_ptr += sizeof( char );
+ returnValue = ( int )inChar;
+ }
+
+ return returnValue;
+}
+
+/***
+* _putwc_nolock - putwc for the miniFILE stream.
+****/
+
+int _putwc_nolock( wchar_t inChar, miniFILE* inStream )
+{
+ int returnValue = WEOF;
+
+ inStream->_cnt -= sizeof( wchar_t );
+
+ if ( ( inStream->_cnt ) >= 0 )
+ {
+ *( ( wchar_t* )( inStream->_ptr ) ) = inChar;
+ inStream->_ptr += sizeof( wchar_t );
+ returnValue = ( int )inChar;
+ }
+
+ return returnValue;
+}
+
+/***
+* _getc_nolock - getc for the miniFILE stream.
+****/
+
+int _getc_nolock( miniFILE* inStream )
+{
+ int returnValue = EOF;
+
+ if ( ( inStream->_cnt ) >= ( int )( sizeof( char ) ) )
+ {
+ inStream->_cnt -= sizeof( char );
+ returnValue = ( int )( *( inStream->_ptr ) );
+ inStream->_ptr += sizeof( char );
+ }
+
+ return returnValue;
+}
+
+/***
+* _getwc_nolock - getc for the miniFILE stream.
+****/
+
+int _getwc_nolock( miniFILE* inStream )
+{
+ int returnValue = EOF;
+
+ if ( ( inStream->_cnt ) >= ( int )( sizeof( wchar_t ) ) )
+ {
+ inStream->_cnt -= sizeof( wchar_t );
+ returnValue = ( int )( *( ( wchar_t* )( inStream->_ptr ) ) );
+ inStream->_ptr += sizeof( wchar_t );
+ }
+
+ return returnValue;
+}
+
+/***
+* _ungetc_nolock - ungetc for the miniFILE stream.
+****/
+
+int _ungetc_nolock( char inChar, miniFILE* inStream )
+{
+ int returnValue = EOF;
+
+ if ( ( size_t )( ( inStream->_ptr ) - ( inStream->_base ) ) >= ( sizeof( char ) ) )
+ {
+ inStream->_cnt += sizeof( char );
+ inStream->_ptr -= sizeof( char );
+ return ( int )inChar;
+ }
+
+ return returnValue;
+}
+
+/***
+* _ungetwc_nolock - ungetwc for the miniFILE stream.
+****/
+
+int _ungetwc_nolock( wchar_t inChar, miniFILE* inStream )
+{
+ int returnValue = WEOF;
+
+ if ( ( size_t )( ( inStream->_ptr ) - ( inStream->_base ) ) >= ( sizeof( wchar_t ) ) )
+ {
+ inStream->_cnt += sizeof( wchar_t );
+ inStream->_ptr -= sizeof( wchar_t );
+ returnValue = ( unsigned short )inChar;
+ }
+
+ return returnValue;
+}
+
+
+/***
+* _safecrt_cfltcvt - convert a float to an ascii string.
+****/
+
+/* routine used for floating-point output */
+#define FORMATSIZE 30
+
+// taken from output.inl
+#define FL_ALTERNATE 0x00080 /* alternate form requested */
+
+errno_t _safecrt_cfltcvt(double *arg, char *buffer, size_t sizeInBytes, int type, int precision, int flags)
+{
+ char format[FORMATSIZE];
+ size_t formatlen = 0;
+ int retvalue;
+
+ if (flags & 1)
+ {
+ type -= 'a' - 'A';
+ }
+ formatlen = 0;
+ format[formatlen++] = '%';
+ if (flags & FL_ALTERNATE)
+ {
+ format[formatlen++] = '#';
+ }
+ format[formatlen++] = '.';
+ _itoa_s(precision, format + formatlen, FORMATSIZE - formatlen, 10);
+ formatlen = strlen(format);
+ format[formatlen++] = (char)type;
+ format[formatlen] = 0;
+
+ buffer[sizeInBytes - 1] = 0;
+ retvalue = snprintf(buffer, sizeInBytes, format, *arg);
+ if (buffer[sizeInBytes - 1] != 0 || retvalue <= 0)
+ {
+ buffer[0] = 0;
+ return EINVAL;
+ }
+ return 0;
+}
+
+
+/***
+* _safecrt_fassign - convert a string into a float or double.
+****/
+
+void _safecrt_fassign(int flag, void* argument, char* number )
+{
+ if ( flag != 0 ) // double
+ {
+ double dblValue = strtod(number, NULL);
+ *( ( double* )argument ) = dblValue;
+ }
+ else // float
+ {
+ float fltValue = strtof(number, NULL);
+ *( ( float* )argument ) = fltValue;
+ }
+}
+
+
+/***
+* _safecrt_wfassign - convert a wchar_t string into a float or double.
+****/
+
+void _safecrt_wfassign(int flag, void* argument, wchar_t* number )
+{
+ // We cannot use system functions for this - they
+ // assume that wchar_t is four bytes, while we assume
+ // two. So, we need to convert to a regular char string
+ // without using any system functions. To do this,
+ // we'll assume that the numbers are in the 0-9 range and
+ // do a simple conversion.
+
+ char* numberAsChars = ( char* )number;
+ int position = 0;
+
+ // do the convert
+ while ( number[ position ] != 0 )
+ {
+ numberAsChars[ position ] = ( char )( number[ position ] & 0x00FF );
+ position++;
+ }
+ numberAsChars[ position ] = ( char )( number[ position ] & 0x00FF );
+
+ // call the normal char version
+ _safecrt_fassign( flag, argument, numberAsChars );
+}
+
+
+/***
+* _minimal_chartowchar - do a simple char to wchar conversion.
+****/
+
+int _minimal_chartowchar( wchar_t* outWChar, const char* inChar )
+{
+ *outWChar = ( wchar_t )( ( unsigned short )( ( unsigned char )( *inChar ) ) );
+ return 1;
+}
+
+
diff --git a/src/pal/src/safecrt/memcpy_s.c b/src/pal/src/safecrt/memcpy_s.cpp
index 27aeb79665..27aeb79665 100644
--- a/src/pal/src/safecrt/memcpy_s.c
+++ b/src/pal/src/safecrt/memcpy_s.cpp
diff --git a/src/pal/src/safecrt/memmove_s.c b/src/pal/src/safecrt/memmove_s.cpp
index a0ae5f7ea6..a0ae5f7ea6 100644
--- a/src/pal/src/safecrt/memmove_s.c
+++ b/src/pal/src/safecrt/memmove_s.cpp
diff --git a/src/pal/src/safecrt/output.inl b/src/pal/src/safecrt/output.inl
index ae0692efc5..5b86cf2c96 100644
--- a/src/pal/src/safecrt/output.inl
+++ b/src/pal/src/safecrt/output.inl
@@ -857,6 +857,12 @@ int __cdecl _output (
flags |= FL_LONG; /* 'l' => long int or wchar_t */
}
break;
+ case _T('L'):
+ if (*format == _T('p'))
+ {
+ flags |= FL_LONG;
+ }
+ break;
case _T('I'):
/*
@@ -956,7 +962,11 @@ int __cdecl _output (
#else /* _UNICODE */
if (flags & (FL_LONG|FL_WIDECHAR)) {
wchar = (wchar_t) get_int_arg(&argptr);
- no_output = 1;
+ textlen = snprintf(buffer.sz, BUFFERSIZE, "%lc", wchar);
+ if (textlen == 0)
+ {
+ no_output = 1;
+ }
} else {
/* format multibyte character */
/* this is an extension of ANSI */
@@ -1172,7 +1182,15 @@ int __cdecl _output (
precision = 2 * sizeof(void *); /* number of hex digits needed */
#if PTR_IS_INT64
- flags |= FL_I64; /* assume we're converting an int64 */
+ if (flags & (FL_LONG | FL_SHORT))
+ {
+ /* %lp, %Lp or %hp - these print 8 hex digits*/
+ precision = 2 * sizeof(int32_t);
+ }
+ else
+ {
+ flags |= FL_I64; /* assume we're converting an int64 */
+ }
#elif !PTR_IS_INT
flags |= FL_LONG; /* assume we're converting a long */
#endif /* !PTR_IS_INT */
@@ -1371,7 +1389,22 @@ int __cdecl _output (
/* write text */
#ifndef _UNICODE
if (bufferiswide && (textlen > 0)) {
- charsout = -1;
+ const WCHAR *p;
+ int mbCharCount;
+ int count;
+ char mbStr[5];
+
+ p = text.wz;
+ count = textlen;
+ while (count-- > 0) {
+ mbCharCount = snprintf(mbStr, sizeof(mbStr), "%lc", *p);
+ if (mbCharCount == 0) {
+ charsout = -1;
+ break;
+ }
+ WRITE_STRING(mbStr, mbCharCount, &charsout);
+ p++;
+ }
} else {
WRITE_STRING(text.sz, textlen, &charsout);
}
diff --git a/src/pal/src/safecrt/safecrt_input_s.c b/src/pal/src/safecrt/safecrt_input_s.cpp
index 6ba607c669..6ba607c669 100644
--- a/src/pal/src/safecrt/safecrt_input_s.c
+++ b/src/pal/src/safecrt/safecrt_input_s.cpp
diff --git a/src/pal/src/safecrt/safecrt_output_l.c b/src/pal/src/safecrt/safecrt_output_l.cpp
index d6844f4f8b..d6844f4f8b 100644
--- a/src/pal/src/safecrt/safecrt_output_l.c
+++ b/src/pal/src/safecrt/safecrt_output_l.cpp
diff --git a/src/pal/src/safecrt/safecrt_output_s.c b/src/pal/src/safecrt/safecrt_output_s.cpp
index c3e7f91404..c3e7f91404 100644
--- a/src/pal/src/safecrt/safecrt_output_s.c
+++ b/src/pal/src/safecrt/safecrt_output_s.cpp
diff --git a/src/pal/src/safecrt/safecrt_winput_s.c b/src/pal/src/safecrt/safecrt_winput_s.cpp
index 17a621781b..17a621781b 100644
--- a/src/pal/src/safecrt/safecrt_winput_s.c
+++ b/src/pal/src/safecrt/safecrt_winput_s.cpp
diff --git a/src/pal/src/safecrt/safecrt_woutput_s.c b/src/pal/src/safecrt/safecrt_woutput_s.cpp
index 52fe9400d5..52fe9400d5 100644
--- a/src/pal/src/safecrt/safecrt_woutput_s.c
+++ b/src/pal/src/safecrt/safecrt_woutput_s.cpp
diff --git a/src/pal/src/safecrt/snprintf.c b/src/pal/src/safecrt/snprintf.c
deleted file mode 100644
index c892d1a9b6..0000000000
--- a/src/pal/src/safecrt/snprintf.c
+++ /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.
-
-/***
-*snprintf.c - "Count" version of sprintf
-*
-
-*
-*Purpose:
-* The _snprintf() flavor takes a count argument that is
-* the max number of bytes that should be written to the
-* user's buffer.
-*
-*******************************************************************************/
-
-#define _COUNT_ 1
-#include "sprintf.c"
diff --git a/src/pal/src/safecrt/snprintf.cpp b/src/pal/src/safecrt/snprintf.cpp
new file mode 100644
index 0000000000..dea87167b9
--- /dev/null
+++ b/src/pal/src/safecrt/snprintf.cpp
@@ -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.
+
+/***
+*snprintf.c - "Count" version of sprintf
+*
+
+*
+*Purpose:
+* The sprintf_s() flavor takes a count argument that is
+* the max number of bytes that should be written to the
+* user's buffer.
+*
+*******************************************************************************/
+
+#define _COUNT_ 1
+#include "sprintf.c"
diff --git a/src/pal/src/safecrt/splitpath_s.c b/src/pal/src/safecrt/splitpath_s.cpp
index cb8a364550..cb8a364550 100644
--- a/src/pal/src/safecrt/splitpath_s.c
+++ b/src/pal/src/safecrt/splitpath_s.cpp
diff --git a/src/pal/src/safecrt/sprintf.c b/src/pal/src/safecrt/sprintf.c
deleted file mode 100644
index 5454179f8d..0000000000
--- a/src/pal/src/safecrt/sprintf.c
+++ /dev/null
@@ -1,98 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/***
-*sprintf.c - print formatted to string
-*
-
-*
-*Purpose:
-* defines sprintf() and _snprintf() - print formatted data to string
-*
-*******************************************************************************/
-
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#include "internal_securecrt.h"
-
-#include "mbusafecrt_internal.h"
-
-
-/***
-*ifndef _COUNT_
-*int sprintf(string, format, ...) - print formatted data to string
-*else
-*int _snprintf(string, cnt, format, ...) - print formatted data to string
-*endif
-*
-*Purpose:
-* Prints formatted data to the using the format string to
-* format data and getting as many arguments as called for
-* Sets up a FILE so file i/o operations can be used, make
-* string look like a huge buffer to it, but _flsbuf will
-* refuse to flush it if it fills up. Appends '\0' to make
-* it a true string. _output does the real work here
-*
-* Allocate the 'fake' _iob[] entry statically instead of on
-* the stack so that other routines can assume that _iob[]
-* entries are in are in DGROUP and, thus, are near.
-*
-*ifdef _COUNT_
-* The _snprintf() flavor takes a count argument that is
-* the max number of bytes that should be written to the
-* user's buffer.
-*endif
-*
-* Multi-thread: (1) Since there is no stream, this routine must
-* never try to get the stream lock (i.e., there is no stream
-* lock either). (2) Also, since there is only one statically
-* allocated 'fake' iob, we must lock/unlock to prevent collisions.
-*
-*Entry:
-* char *string - pointer to place to put output
-*ifdef _COUNT_
-* size_t count - max number of bytes to put in buffer
-*endif
-* char *format - format string to control data format/number
-* of arguments followed by list of arguments, number and type
-* controlled by format string
-*
-*Exit:
-* returns number of characters printed
-*
-*Exceptions:
-*
-*******************************************************************************/
-
-int sprintf_s (
- char *string,
- size_t sizeInBytes,
- const char *format,
- ...
- )
-{
- int ret;
- va_list arglist;
- va_start(arglist, format);
- ret = _vsprintf_s(string, sizeInBytes, format, arglist);
- va_end(arglist);
- return ret;
-}
-
-int _snprintf_s (
- char *string,
- size_t sizeInBytes,
- size_t count,
- const char *format,
- ...
- )
-{
- int ret;
- va_list arglist;
- va_start(arglist, format);
- ret = _vsnprintf_s(string, sizeInBytes, count, format, arglist);
- va_end(arglist);
- return ret;
-}
diff --git a/src/pal/src/safecrt/sprintf_s.cpp b/src/pal/src/safecrt/sprintf_s.cpp
new file mode 100644
index 0000000000..edfb768670
--- /dev/null
+++ b/src/pal/src/safecrt/sprintf_s.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.
+
+/***
+*sprintf_s.c - print formatted to string
+*
+
+*
+*Purpose:
+* defines sprintf_s() and _snprintf_s() - print formatted data to string
+*
+*******************************************************************************/
+
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include "internal_securecrt.h"
+
+#include "mbusafecrt_internal.h"
+
+
+/***
+*ifndef _COUNT_
+*int sprintf_s(string, format, ...) - print formatted data to string
+*else
+*int _snprintf_s(string, cnt, format, ...) - print formatted data to string
+*endif
+*
+*Purpose:
+* Prints formatted data to the using the format string to
+* format data and getting as many arguments as called for
+* Sets up a FILE so file i/o operations can be used, make
+* string look like a huge buffer to it, but _flsbuf will
+* refuse to flush it if it fills up. Appends '\0' to make
+* it a true string. _output does the real work here
+*
+* Allocate the 'fake' _iob[] entry statically instead of on
+* the stack so that other routines can assume that _iob[]
+* entries are in are in DGROUP and, thus, are near.
+*
+*ifdef _COUNT_
+* The _snprintf_s() flavor takes a count argument that is
+* the max number of bytes that should be written to the
+* user's buffer.
+*endif
+*
+* Multi-thread: (1) Since there is no stream, this routine must
+* never try to get the stream lock (i.e., there is no stream
+* lock either). (2) Also, since there is only one statically
+* allocated 'fake' iob, we must lock/unlock to prevent collisions.
+*
+*Entry:
+* char *string - pointer to place to put output
+*ifdef _COUNT_
+* size_t count - max number of bytes to put in buffer
+*endif
+* char *format - format string to control data format/number
+* of arguments followed by list of arguments, number and type
+* controlled by format string
+*
+*Exit:
+* returns number of characters printed
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int sprintf_s (
+ char *string,
+ size_t sizeInBytes,
+ const char *format,
+ ...
+ )
+{
+ int ret;
+ va_list arglist;
+ va_start(arglist, format);
+ ret = vsprintf_s(string, sizeInBytes, format, arglist);
+ va_end(arglist);
+ return ret;
+}
+
+int _snprintf_s (
+ char *string,
+ size_t sizeInBytes,
+ size_t count,
+ const char *format,
+ ...
+ )
+{
+ int ret;
+ va_list arglist;
+ va_start(arglist, format);
+ ret = _vsnprintf_s(string, sizeInBytes, count, format, arglist);
+ va_end(arglist);
+ return ret;
+}
diff --git a/src/pal/src/safecrt/sscanf.c b/src/pal/src/safecrt/sscanf.c
deleted file mode 100644
index 94b5148875..0000000000
--- a/src/pal/src/safecrt/sscanf.c
+++ /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.
-
-/***
-*sscanf.c - read formatted data from string
-*
-
-*
-*Purpose:
-* defines scanf() - reads formatted data from string
-*
-*******************************************************************************/
-
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#include "internal_securecrt.h"
-
-#include "mbusafecrt_internal.h"
-
-typedef int (*INPUTFN)(miniFILE *, const unsigned char*, va_list);
-typedef int (*WINPUTFN)(miniFILE *, const unsigned short*, va_list);
-
-
-/***
-*static int v[nw]scan_fn([w]inputfn, string, [count], format, ...)
-*
-*Purpose:
-* this is a helper function which is called by the other functions
-* in this file - sscanf/swscanf/snscanf etc. It calls either _(w)input or
-* _(w)input_s depending on the first parameter.
-*
-*******************************************************************************/
-
-static int __cdecl vscan_fn (
- INPUTFN inputfn,
- const char *string,
- const char *format,
- va_list arglist
- )
-{
- miniFILE str;
- miniFILE *infile = &str;
- int retval;
- size_t count = strlen(string);
-
- _VALIDATE_RETURN( (string != NULL), EINVAL, EOF);
- _VALIDATE_RETURN( (format != NULL), EINVAL, EOF);
-
- infile->_flag = _IOREAD|_IOSTRG|_IOMYBUF;
- infile->_ptr = infile->_base = (char *) string;
-
- if(count>(INT_MAX/sizeof(char)))
- {
- /* old-style functions allow any large value to mean unbounded */
- infile->_cnt = INT_MAX;
- }
- else
- {
- infile->_cnt = (int)count*sizeof(char);
- }
-
- retval = (inputfn(infile, ( const unsigned char* )format, arglist));
-
- return(retval);
-}
-
-static int __cdecl vnscan_fn (
- INPUTFN inputfn,
- const char *string,
- size_t count,
- const char *format,
- va_list arglist
- )
-{
- miniFILE str;
- miniFILE *infile = &str;
- int retval;
- size_t length = strlen(string);
-
- _VALIDATE_RETURN( (string != NULL), EINVAL, EOF);
- _VALIDATE_RETURN( (format != NULL), EINVAL, EOF);
-
- infile->_flag = _IOREAD|_IOSTRG|_IOMYBUF;
- infile->_ptr = infile->_base = (char *) string;
-
- if ( count > length )
- {
- count = length;
- }
-
- if(count>(INT_MAX/sizeof(char)))
- {
- /* old-style functions allow any large value to mean unbounded */
- infile->_cnt = INT_MAX;
- }
- else
- {
- infile->_cnt = (int)count*sizeof(char);
- }
-
- retval = (inputfn(infile, ( const unsigned char* )format, arglist));
-
- return(retval);
-}
-
-static int __cdecl vwscan_fn (
- WINPUTFN inputfn,
- const wchar_t *string,
- const wchar_t *format,
- va_list arglist
- )
-{
- miniFILE str;
- miniFILE *infile = &str;
- int retval;
- size_t count = wcsnlen(string, INT_MAX);
-
- _VALIDATE_RETURN( (string != NULL), EINVAL, EOF);
- _VALIDATE_RETURN( (format != NULL), EINVAL, EOF);
-
- infile->_flag = _IOREAD|_IOSTRG|_IOMYBUF;
- infile->_ptr = infile->_base = (char *) string;
-
- if(count>(INT_MAX/sizeof(wchar_t)))
- {
- /* old-style functions allow any large value to mean unbounded */
- infile->_cnt = INT_MAX;
- }
- else
- {
- infile->_cnt = (int)count*sizeof(wchar_t);
- }
-
- retval = (inputfn(infile, format, arglist));
-
- return(retval);
-}
-
-static int __cdecl vnwscan_fn (
- WINPUTFN inputfn,
- const wchar_t *string,
- size_t count,
- const wchar_t *format,
- va_list arglist
- )
-{
- miniFILE str;
- miniFILE *infile = &str;
- int retval;
- size_t length = wcsnlen(string, INT_MAX);
-
- _VALIDATE_RETURN( (string != NULL), EINVAL, EOF);
- _VALIDATE_RETURN( (format != NULL), EINVAL, EOF);
-
- infile->_flag = _IOREAD|_IOSTRG|_IOMYBUF;
- infile->_ptr = infile->_base = (char *) string;
-
- if ( count > length )
- {
- count = length;
- }
-
- if(count>(INT_MAX/sizeof(wchar_t)))
- {
- /* old-style functions allow any large value to mean unbounded */
- infile->_cnt = INT_MAX;
- }
- else
- {
- infile->_cnt = (int)count*sizeof(wchar_t);
- }
-
- retval = (inputfn(infile, format, arglist));
-
- return(retval);
-}
-
-
-/***
-*int sscanf_s(string, format, ...)
-* Same as sscanf above except that it calls _input_s to do the real work.
-*
-*int snscanf_s(string, size, format, ...)
-* Same as snscanf above except that it calls _input_s to do the real work.
-*
-* _input_s has a size check for array parameters.
-*
-*******************************************************************************/
-
-int __cdecl sscanf_s (
- const char *string,
- const char *format,
- ...
- )
-{
- int ret;
- va_list arglist;
- va_start(arglist, format);
- ret = vscan_fn(__tinput_s, string, format, arglist);
- va_end(arglist);
- return ret;
-}
-
-int __cdecl _snscanf_s (
- const char *string,
- size_t count,
- const char *format,
- ...
- )
-{
- int ret;
- va_list arglist;
- va_start(arglist, format);
- ret = vnscan_fn(__tinput_s, string, count, format, arglist);
- va_end(arglist);
- return ret;
-}
-
-int __cdecl swscanf_s (
- const wchar_t *string,
- const wchar_t *format,
- ...
- )
-{
- int ret;
- va_list arglist;
- va_start(arglist, format);
- ret = vwscan_fn(__twinput_s, string, format, arglist);
- va_end(arglist);
- return ret;
-}
-
-int __cdecl _snwscanf_s (
- const wchar_t *string,
- size_t count,
- const wchar_t *format,
- ...
- )
-{
- int ret;
- va_list arglist;
- va_start(arglist, format);
- ret = vnwscan_fn(__twinput_s, string, count, format, arglist);
- va_end(arglist);
- return ret;
-}
-
diff --git a/src/pal/src/safecrt/sscanf_s.cpp b/src/pal/src/safecrt/sscanf_s.cpp
new file mode 100644
index 0000000000..4f548bccc6
--- /dev/null
+++ b/src/pal/src/safecrt/sscanf_s.cpp
@@ -0,0 +1,249 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/***
+*sscanf_s.c - read formatted data from string
+*
+
+*
+*Purpose:
+* defines scanf() - reads formatted data from string
+*
+*******************************************************************************/
+
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include "internal_securecrt.h"
+
+#include "mbusafecrt_internal.h"
+
+typedef int (*INPUTFN)(miniFILE *, const unsigned char*, va_list);
+typedef int (*WINPUTFN)(miniFILE *, const wchar_t*, va_list);
+
+
+/***
+*static int v[nw]scan_fn([w]inputfn, string, [count], format, ...)
+*
+*Purpose:
+* this is a helper function which is called by the other functions
+* in this file - sscanf/swscanf/snscanf etc. It calls either _(w)input or
+* _(w)input_s depending on the first parameter.
+*
+*******************************************************************************/
+
+static int __cdecl vscan_fn (
+ INPUTFN inputfn,
+ const char *string,
+ const char *format,
+ va_list arglist
+ )
+{
+ miniFILE str;
+ miniFILE *infile = &str;
+ int retval;
+ size_t count = strlen(string);
+
+ _VALIDATE_RETURN( (string != NULL), EINVAL, EOF);
+ _VALIDATE_RETURN( (format != NULL), EINVAL, EOF);
+
+ infile->_flag = _IOREAD|_IOSTRG|_IOMYBUF;
+ infile->_ptr = infile->_base = (char *) string;
+
+ if(count>(INT_MAX/sizeof(char)))
+ {
+ /* old-style functions allow any large value to mean unbounded */
+ infile->_cnt = INT_MAX;
+ }
+ else
+ {
+ infile->_cnt = (int)count*sizeof(char);
+ }
+
+ retval = (inputfn(infile, ( const unsigned char* )format, arglist));
+
+ return(retval);
+}
+
+static int __cdecl vnscan_fn (
+ INPUTFN inputfn,
+ const char *string,
+ size_t count,
+ const char *format,
+ va_list arglist
+ )
+{
+ miniFILE str;
+ miniFILE *infile = &str;
+ int retval;
+ size_t length = strlen(string);
+
+ _VALIDATE_RETURN( (string != NULL), EINVAL, EOF);
+ _VALIDATE_RETURN( (format != NULL), EINVAL, EOF);
+
+ infile->_flag = _IOREAD|_IOSTRG|_IOMYBUF;
+ infile->_ptr = infile->_base = (char *) string;
+
+ if ( count > length )
+ {
+ count = length;
+ }
+
+ if(count>(INT_MAX/sizeof(char)))
+ {
+ /* old-style functions allow any large value to mean unbounded */
+ infile->_cnt = INT_MAX;
+ }
+ else
+ {
+ infile->_cnt = (int)count*sizeof(char);
+ }
+
+ retval = (inputfn(infile, ( const unsigned char* )format, arglist));
+
+ return(retval);
+}
+
+static int __cdecl vwscan_fn (
+ WINPUTFN inputfn,
+ const wchar_t *string,
+ const wchar_t *format,
+ va_list arglist
+ )
+{
+ miniFILE str;
+ miniFILE *infile = &str;
+ int retval;
+ size_t count = wcsnlen(string, INT_MAX);
+
+ _VALIDATE_RETURN( (string != NULL), EINVAL, EOF);
+ _VALIDATE_RETURN( (format != NULL), EINVAL, EOF);
+
+ infile->_flag = _IOREAD|_IOSTRG|_IOMYBUF;
+ infile->_ptr = infile->_base = (char *) string;
+
+ if(count>(INT_MAX/sizeof(wchar_t)))
+ {
+ /* old-style functions allow any large value to mean unbounded */
+ infile->_cnt = INT_MAX;
+ }
+ else
+ {
+ infile->_cnt = (int)count*sizeof(wchar_t);
+ }
+
+ retval = (inputfn(infile, format, arglist));
+
+ return(retval);
+}
+
+static int __cdecl vnwscan_fn (
+ WINPUTFN inputfn,
+ const wchar_t *string,
+ size_t count,
+ const wchar_t *format,
+ va_list arglist
+ )
+{
+ miniFILE str;
+ miniFILE *infile = &str;
+ int retval;
+ size_t length = wcsnlen(string, INT_MAX);
+
+ _VALIDATE_RETURN( (string != NULL), EINVAL, EOF);
+ _VALIDATE_RETURN( (format != NULL), EINVAL, EOF);
+
+ infile->_flag = _IOREAD|_IOSTRG|_IOMYBUF;
+ infile->_ptr = infile->_base = (char *) string;
+
+ if ( count > length )
+ {
+ count = length;
+ }
+
+ if(count>(INT_MAX/sizeof(wchar_t)))
+ {
+ /* old-style functions allow any large value to mean unbounded */
+ infile->_cnt = INT_MAX;
+ }
+ else
+ {
+ infile->_cnt = (int)count*sizeof(wchar_t);
+ }
+
+ retval = (inputfn(infile, format, arglist));
+
+ return(retval);
+}
+
+
+/***
+*int sscanf_s(string, format, ...)
+* Same as sscanf above except that it calls _input_s to do the real work.
+*
+*int snscanf_s(string, size, format, ...)
+* Same as snscanf above except that it calls _input_s to do the real work.
+*
+* _input_s has a size check for array parameters.
+*
+*******************************************************************************/
+
+int __cdecl sscanf_s (
+ const char *string,
+ const char *format,
+ ...
+ )
+{
+ int ret;
+ va_list arglist;
+ va_start(arglist, format);
+ ret = vscan_fn(__tinput_s, string, format, arglist);
+ va_end(arglist);
+ return ret;
+}
+
+int __cdecl _snscanf_s (
+ const char *string,
+ size_t count,
+ const char *format,
+ ...
+ )
+{
+ int ret;
+ va_list arglist;
+ va_start(arglist, format);
+ ret = vnscan_fn(__tinput_s, string, count, format, arglist);
+ va_end(arglist);
+ return ret;
+}
+
+int __cdecl swscanf_s (
+ const wchar_t *string,
+ const wchar_t *format,
+ ...
+ )
+{
+ int ret;
+ va_list arglist;
+ va_start(arglist, format);
+ ret = vwscan_fn(__twinput_s, string, format, arglist);
+ va_end(arglist);
+ return ret;
+}
+
+int __cdecl _snwscanf_s (
+ const wchar_t *string,
+ size_t count,
+ const wchar_t *format,
+ ...
+ )
+{
+ int ret;
+ va_list arglist;
+ va_start(arglist, format);
+ ret = vnwscan_fn(__twinput_s, string, count, format, arglist);
+ va_end(arglist);
+ return ret;
+}
+
diff --git a/src/pal/src/safecrt/strcat_s.c b/src/pal/src/safecrt/strcat_s.cpp
index 4dc2332006..4dc2332006 100644
--- a/src/pal/src/safecrt/strcat_s.c
+++ b/src/pal/src/safecrt/strcat_s.cpp
diff --git a/src/pal/src/safecrt/strcpy_s.c b/src/pal/src/safecrt/strcpy_s.cpp
index 821dbe85f6..821dbe85f6 100644
--- a/src/pal/src/safecrt/strcpy_s.c
+++ b/src/pal/src/safecrt/strcpy_s.cpp
diff --git a/src/pal/src/safecrt/strlen_s.c b/src/pal/src/safecrt/strlen_s.c
deleted file mode 100644
index 34c1308d5c..0000000000
--- a/src/pal/src/safecrt/strlen_s.c
+++ /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.
-
-/***
-*strlen_s.c - contains strnlen() routine
-*
-
-*
-*Purpose:
-* strnlen returns the length of a null-terminated string,
-* not including the null byte itself, up to the specified max size
-*
-*******************************************************************************/
-
-
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#include "internal_securecrt.h"
-
-#include "mbusafecrt_internal.h"
-
-/***
-*strnlen - return the length of a null-terminated string
-*
-*Purpose:
-* Finds the length in bytes of the given string, not including
-* the final null character. Only the first maxsize characters
-* are inspected: if the null character is not found, maxsize is
-* returned.
-*
-*Entry:
-* const char * str - string whose length is to be computed
-* size_t maxsize
-*
-*Exit:
-* Length of the string "str", exclusive of the final null byte, or
-* maxsize if the null character is not found.
-*
-*Exceptions:
-*
-*******************************************************************************/
-
-size_t __cdecl strnlen(const char *str, size_t maxsize)
-{
- size_t n;
-
- /* Note that we do not check if str == NULL, because we do not
- * return errno_t...
- */
-
- for (n = 0; n < maxsize && *str; n++, str++)
- ;
-
- return n;
-}
-
diff --git a/src/pal/src/safecrt/strlen_s.cpp b/src/pal/src/safecrt/strlen_s.cpp
new file mode 100644
index 0000000000..3f1e1cf1ae
--- /dev/null
+++ b/src/pal/src/safecrt/strlen_s.cpp
@@ -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.
+
+/***
+*strlen_s.c - contains strnlen() routine
+*
+
+*
+*Purpose:
+* strnlen returns the length of a null-terminated string,
+* not including the null byte itself, up to the specified max size
+*
+*******************************************************************************/
+
+
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include "internal_securecrt.h"
+
+#include "mbusafecrt_internal.h"
+
+/***
+*strnlen - return the length of a null-terminated string
+*
+*Purpose:
+* Finds the length in bytes of the given string, not including
+* the final null character. Only the first maxsize characters
+* are inspected: if the null character is not found, maxsize is
+* returned.
+*
+*Entry:
+* const char * str - string whose length is to be computed
+* size_t maxsize
+*
+*Exit:
+* Length of the string "str", exclusive of the final null byte, or
+* maxsize if the null character is not found.
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+size_t __cdecl PAL_strnlen(const char *str, size_t maxsize)
+{
+ size_t n;
+
+ /* Note that we do not check if str == NULL, because we do not
+ * return errno_t...
+ */
+
+ for (n = 0; n < maxsize && *str; n++, str++)
+ ;
+
+ return n;
+}
+
diff --git a/src/pal/src/safecrt/strncat_s.c b/src/pal/src/safecrt/strncat_s.cpp
index ef8c6cfc7f..ef8c6cfc7f 100644
--- a/src/pal/src/safecrt/strncat_s.c
+++ b/src/pal/src/safecrt/strncat_s.cpp
diff --git a/src/pal/src/safecrt/strncpy_s.c b/src/pal/src/safecrt/strncpy_s.cpp
index f819ebb6bb..f819ebb6bb 100644
--- a/src/pal/src/safecrt/strncpy_s.c
+++ b/src/pal/src/safecrt/strncpy_s.cpp
diff --git a/src/pal/src/safecrt/strtok_s.c b/src/pal/src/safecrt/strtok_s.cpp
index 6f1c80633f..6f1c80633f 100644
--- a/src/pal/src/safecrt/strtok_s.c
+++ b/src/pal/src/safecrt/strtok_s.cpp
diff --git a/src/pal/src/safecrt/swprintf.c b/src/pal/src/safecrt/swprintf.c
deleted file mode 100644
index 75004eafe2..0000000000
--- a/src/pal/src/safecrt/swprintf.c
+++ /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.
-
-/***
-*swprintf.c - print formatted to string
-*
-*Purpose:
-* defines _swprintf(), _swprintf_c and _snwprintf() - print formatted data
-* to string
-*
-*******************************************************************************/
-
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#include "internal_securecrt.h"
-
-#include "mbusafecrt_internal.h"
-
-/***
-*ifndef _COUNT_
-*int _swprintf(string, format, ...) - print formatted data to string
-*else
-*ifndef _SWPRINTFS_ERROR_RETURN_FIX
-*int _snwprintf(string, cnt, format, ...) - print formatted data to string
-*else
-*int _swprintf_c(string, cnt, format, ...) - print formatted data to string
-*endif
-*endif
-*
-*Purpose:
-* Prints formatted data to the using the format string to
-* format data and getting as many arguments as called for
-* Sets up a FILE so file i/o operations can be used, make
-* string look like a huge buffer to it, but _flsbuf will
-* refuse to flush it if it fills up. Appends '\0' to make
-* it a true string. _output does the real work here
-*
-* Allocate the 'fake' _iob[] entry statically instead of on
-* the stack so that other routines can assume that _iob[]
-* entries are in are in DGROUP and, thus, are near.
-*
-* We alias swprintf to _swprintf
-*
-*ifdef _COUNT_
-*ifndef _SWPRINTFS_ERROR_RETURN_FIX
-* The _snwprintf() flavor takes a count argument that is
-* the max number of wide characters that should be written to the
-* user's buffer.
-* We don't expose this function directly in the headers.
-*else
-* The _swprintf_c() flavor does the same thing as the _snwprintf
-* above, but, it also fixes a issue in the return value in the case
-* when there isn't enough space to write the null terminator
-* We don't fix this issue in _snwprintf because of backward
-* compatibility. In new code, however, _snwprintf is #defined to
-* _swprintf_c so users get the fix.
-*
-*endif
-*
-* Multi-thread: (1) Since there is no stream, this routine must
-* never try to get the stream lock (i.e., there is no stream
-* lock either). (2) Also, since there is only one statically
-* allocated 'fake' iob, we must lock/unlock to prevent collisions.
-*
-*Entry:
-* wchar_t *string - pointer to place to put output
-*ifdef _COUNT_
-* size_t count - max number of wide characters to put in buffer
-*endif
-* wchar_t *format - format string to control data format/number
-* of arguments followed by list of arguments, number and type
-* controlled by format string
-*
-*Exit:
-* returns number of wide characters printed
-*
-*Exceptions:
-*
-*******************************************************************************/
-
-int __cdecl swprintf_s (
- wchar_t *string,
- size_t sizeInWords,
- const wchar_t *format,
- ...
- )
-{
- int ret;
- va_list arglist;
-
- va_start(arglist, format);
-
- ret = _vswprintf_s(string, sizeInWords, format, arglist);
-
- va_end(arglist);
-
- return ret;
-}
-
-int __cdecl _snwprintf_s (
- wchar_t *string,
- size_t sizeInWords,
- size_t count,
- const wchar_t *format,
- ...
- )
-{
- int ret;
- va_list arglist;
-
- va_start(arglist, format);
-
- ret = _vsnwprintf_s(string, sizeInWords, count, format, arglist);
-
- va_end(arglist);
-
- return ret;
-}
diff --git a/src/pal/src/safecrt/swprintf.cpp b/src/pal/src/safecrt/swprintf.cpp
new file mode 100644
index 0000000000..2fbfcfaf58
--- /dev/null
+++ b/src/pal/src/safecrt/swprintf.cpp
@@ -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.
+
+/***
+*swprintf.c - print formatted to string
+*
+*Purpose:
+* defines _swprintf(), _swprintf_c and _snwprintf() - print formatted data
+* to string
+*
+*******************************************************************************/
+
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include "internal_securecrt.h"
+
+#include "mbusafecrt_internal.h"
+
+/***
+*ifndef _COUNT_
+*int _swprintf(string, format, ...) - print formatted data to string
+*else
+*ifndef _SWPRINTFS_ERROR_RETURN_FIX
+*int _snwprintf(string, cnt, format, ...) - print formatted data to string
+*else
+*int _swprintf_c(string, cnt, format, ...) - print formatted data to string
+*endif
+*endif
+*
+*Purpose:
+* Prints formatted data to the using the format string to
+* format data and getting as many arguments as called for
+* Sets up a FILE so file i/o operations can be used, make
+* string look like a huge buffer to it, but _flsbuf will
+* refuse to flush it if it fills up. Appends '\0' to make
+* it a true string. _output does the real work here
+*
+* Allocate the 'fake' _iob[] entry statically instead of on
+* the stack so that other routines can assume that _iob[]
+* entries are in are in DGROUP and, thus, are near.
+*
+* We alias swprintf to _swprintf
+*
+*ifdef _COUNT_
+*ifndef _SWPRINTFS_ERROR_RETURN_FIX
+* The _snwprintf() flavor takes a count argument that is
+* the max number of wide characters that should be written to the
+* user's buffer.
+* We don't expose this function directly in the headers.
+*else
+* The _swprintf_c() flavor does the same thing as the _snwprintf
+* above, but, it also fixes a issue in the return value in the case
+* when there isn't enough space to write the null terminator
+* We don't fix this issue in _snwprintf because of backward
+* compatibility. In new code, however, _snwprintf is #defined to
+* _swprintf_c so users get the fix.
+*
+*endif
+*
+* Multi-thread: (1) Since there is no stream, this routine must
+* never try to get the stream lock (i.e., there is no stream
+* lock either). (2) Also, since there is only one statically
+* allocated 'fake' iob, we must lock/unlock to prevent collisions.
+*
+*Entry:
+* wchar_t *string - pointer to place to put output
+*ifdef _COUNT_
+* size_t count - max number of wide characters to put in buffer
+*endif
+* wchar_t *format - format string to control data format/number
+* of arguments followed by list of arguments, number and type
+* controlled by format string
+*
+*Exit:
+* returns number of wide characters printed
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int __cdecl swprintf_s (
+ wchar_t *string,
+ size_t sizeInWords,
+ const wchar_t *format,
+ ...
+ )
+{
+ int ret;
+ va_list arglist;
+
+ va_start(arglist, format);
+
+ ret = vswprintf_s(string, sizeInWords, format, arglist);
+
+ va_end(arglist);
+
+ return ret;
+}
+
+int __cdecl _snwprintf_s (
+ wchar_t *string,
+ size_t sizeInWords,
+ size_t count,
+ const wchar_t *format,
+ ...
+ )
+{
+ int ret;
+ va_list arglist;
+
+ va_start(arglist, format);
+
+ ret = _vsnwprintf_s(string, sizeInWords, count, format, arglist);
+
+ va_end(arglist);
+
+ return ret;
+}
diff --git a/src/pal/src/safecrt/vsprintf.c b/src/pal/src/safecrt/vsprintf.c
deleted file mode 100644
index 4f2bd9fdeb..0000000000
--- a/src/pal/src/safecrt/vsprintf.c
+++ /dev/null
@@ -1,268 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/***
-*vsprintf.c - print formatted data into a string from var arg list
-*
-
-*
-*Purpose:
-* defines vsprintf(), _vsnprintf() and _vsnprintf_s() - print formatted output to
-* a string, get the data from an argument ptr instead of explicit
-* arguments.
-*
-*******************************************************************************/
-
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#include "internal_securecrt.h"
-
-#include "mbusafecrt_internal.h"
-
-typedef int (*OUTPUTFN)(miniFILE *, const char *, va_list);
-
-static int _vsnprintf_helper( OUTPUTFN outfn, char *string, size_t count, const char *format, va_list ap );
-static int _vscprintf_helper ( OUTPUTFN outfn, const char *format, va_list ap);
-
-/***
-*ifndef _COUNT_
-*int vsprintf(string, format, ap) - print formatted data to string from arg ptr
-*else
-*int _vsnprintf(string, cnt, format, ap) - print formatted data to string from arg ptr
-*endif
-*
-*Purpose:
-* Prints formatted data, but to a string and gets data from an argument
-* pointer.
-* Sets up a FILE so file i/o operations can be used, make string look
-* like a huge buffer to it, but _flsbuf will refuse to flush it if it
-* fills up. Appends '\0' to make it a true string.
-*
-* Allocate the 'fake' _iob[] entryit statically instead of on
-* the stack so that other routines can assume that _iob[] entries are in
-* are in DGROUP and, thus, are near.
-*
-*ifdef _COUNT_
-* The _vsnprintf() flavor takes a count argument that is
-* the max number of bytes that should be written to the
-* user's buffer.
-*endif
-*
-* Multi-thread: (1) Since there is no stream, this routine must never try
-* to get the stream lock (i.e., there is no stream lock either). (2)
-* Also, since there is only one staticly allocated 'fake' iob, we must
-* lock/unlock to prevent collisions.
-*
-*Entry:
-* char *string - place to put destination string
-*ifdef _COUNT_
-* size_t count - max number of bytes to put in buffer
-*endif
-* char *format - format string, describes format of data
-* va_list ap - varargs argument pointer
-*
-*Exit:
-* returns number of characters in string
-* returns -2 if the string has been truncated (only in _vsnprintf_helper)
-* returns -1 in other error cases
-*
-*Exceptions:
-*
-*******************************************************************************/
-
-int __cdecl _vsnprintf_helper (
- OUTPUTFN outfn,
- char *string,
- size_t count,
- const char *format,
- va_list ap
- )
-{
- miniFILE str;
- miniFILE *outfile = &str;
- int retval;
-
- _VALIDATE_RETURN( (format != NULL), EINVAL, -1);
-
- _VALIDATE_RETURN( (count == 0) || (string != NULL), EINVAL, -1 );
-
- if(count>INT_MAX)
- {
- /* old-style functions allow any large value to mean unbounded */
- outfile->_cnt = INT_MAX;
- }
- else
- {
- outfile->_cnt = (int)count;
- }
-
- outfile->_flag = _IOWRT|_IOSTRG;
- outfile->_ptr = outfile->_base = string;
-
- retval = outfn(outfile, format, ap );
-
- if ( string==NULL)
- return(retval);
-
- if((retval >= 0) && (_putc_nolock('\0',outfile) != EOF))
- return(retval);
-
- string[count - 1] = 0;
-
- if (outfile->_cnt < 0)
- {
- /* the buffer was too small; we return -2 to indicate truncation */
- return -2;
- }
- return -1;
-}
-
-int __cdecl _vsprintf_s (
- char *string,
- size_t sizeInBytes,
- const char *format,
- va_list ap
- )
-{
- int retvalue = -1;
-
- /* validation section */
- _VALIDATE_RETURN(format != NULL, EINVAL, -1);
- _VALIDATE_RETURN(string != NULL && sizeInBytes > 0, EINVAL, -1);
-
- retvalue = _vsnprintf_helper(_output_s, string, sizeInBytes, format, ap);
- if (retvalue < 0)
- {
- string[0] = 0;
- _SECURECRT__FILL_STRING(string, sizeInBytes, 1);
- }
- if (retvalue == -2)
- {
- _VALIDATE_RETURN(("Buffer too small" && 0), ERANGE, -1);
- }
- if (retvalue >= 0)
- {
- _SECURECRT__FILL_STRING(string, sizeInBytes, retvalue + 1);
- }
-
- return retvalue;
-}
-
-int __cdecl _vsnprintf_s (
- char *string,
- size_t sizeInBytes,
- size_t count,
- const char *format,
- va_list ap
- )
-{
- int retvalue = -1;
- errno_t save_errno = 0;
-
- /* validation section */
- _VALIDATE_RETURN(format != NULL, EINVAL, -1);
- if (count == 0 && string == NULL && sizeInBytes == 0)
- {
- /* this case is allowed; nothing to do */
- return 0;
- }
- _VALIDATE_RETURN(string != NULL && sizeInBytes > 0, EINVAL, -1);
-
- if (sizeInBytes > count)
- {
- save_errno = errno;
- retvalue = _vsnprintf_helper(_output_s, string, count + 1, format, ap);
- if (retvalue == -2)
- {
- /* the string has been truncated, return -1 */
- _SECURECRT__FILL_STRING(string, sizeInBytes, count + 1);
- if (errno == ERANGE)
- {
- errno = save_errno;
- }
- return -1;
- }
- }
- else /* sizeInBytes <= count */
- {
- save_errno = errno;
- retvalue = _vsnprintf_helper(_output_s, string, sizeInBytes, format, ap);
- string[sizeInBytes - 1] = 0;
- /* we allow truncation if count == _TRUNCATE */
- if (retvalue == -2 && count == _TRUNCATE)
- {
- if (errno == ERANGE)
- {
- errno = save_errno;
- }
- return -1;
- }
- }
-
- if (retvalue < 0)
- {
- string[0] = 0;
- _SECURECRT__FILL_STRING(string, sizeInBytes, 1);
- if (retvalue == -2)
- {
- _VALIDATE_RETURN(("Buffer too small" && 0), ERANGE, -1);
- }
- return -1;
- }
-
- _SECURECRT__FILL_STRING(string, sizeInBytes, retvalue + 1);
-
- return (retvalue < 0 ? -1 : retvalue);
-}
-
-/***
-* _vscprintf() - counts the number of character needed to print the formatted
-* data
-*
-*Purpose:
-* Counts the number of characters in the fotmatted data.
-*
-*Entry:
-* char *format - format string, describes format of data
-* va_list ap - varargs argument pointer
-*
-*Exit:
-* returns number of characters needed to print formatted data.
-*
-*Exceptions:
-*
-*******************************************************************************/
-
-#ifndef _COUNT_
-
-int __cdecl _vscprintf_helper (
- OUTPUTFN outfn,
- const char *format,
- va_list ap
- )
-{
- miniFILE str;
- miniFILE *outfile = &str;
- int retval;
-
- _VALIDATE_RETURN( (format != NULL), EINVAL, -1);
-
- outfile->_cnt = INT_MAX; //MAXSTR;
- outfile->_flag = _IOWRT|_IOSTRG;
- outfile->_ptr = outfile->_base = NULL;
-
- retval = outfn(outfile, format, ap);
- return(retval);
-}
-
-int __cdecl _vscprintf (
- const char *format,
- va_list ap
- )
-{
- return _vscprintf_helper(_output, format, ap);
-}
-
-#endif /* _COUNT_ */
diff --git a/src/pal/src/safecrt/vsprintf.cpp b/src/pal/src/safecrt/vsprintf.cpp
new file mode 100644
index 0000000000..e1a94d086d
--- /dev/null
+++ b/src/pal/src/safecrt/vsprintf.cpp
@@ -0,0 +1,268 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/***
+*vsprintf.c - print formatted data into a string from var arg list
+*
+
+*
+*Purpose:
+* defines vsprintf(), _vsnprintf() and _vsnprintf_s() - print formatted output to
+* a string, get the data from an argument ptr instead of explicit
+* arguments.
+*
+*******************************************************************************/
+
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include "internal_securecrt.h"
+
+#include "mbusafecrt_internal.h"
+
+typedef int (*OUTPUTFN)(miniFILE *, const char *, va_list);
+
+static int _vsnprintf_helper( OUTPUTFN outfn, char *string, size_t count, const char *format, va_list ap );
+static int _vscprintf_helper ( OUTPUTFN outfn, const char *format, va_list ap);
+
+/***
+*ifndef _COUNT_
+*int vsprintf(string, format, ap) - print formatted data to string from arg ptr
+*else
+*int _vsnprintf(string, cnt, format, ap) - print formatted data to string from arg ptr
+*endif
+*
+*Purpose:
+* Prints formatted data, but to a string and gets data from an argument
+* pointer.
+* Sets up a FILE so file i/o operations can be used, make string look
+* like a huge buffer to it, but _flsbuf will refuse to flush it if it
+* fills up. Appends '\0' to make it a true string.
+*
+* Allocate the 'fake' _iob[] entryit statically instead of on
+* the stack so that other routines can assume that _iob[] entries are in
+* are in DGROUP and, thus, are near.
+*
+*ifdef _COUNT_
+* The _vsnprintf() flavor takes a count argument that is
+* the max number of bytes that should be written to the
+* user's buffer.
+*endif
+*
+* Multi-thread: (1) Since there is no stream, this routine must never try
+* to get the stream lock (i.e., there is no stream lock either). (2)
+* Also, since there is only one staticly allocated 'fake' iob, we must
+* lock/unlock to prevent collisions.
+*
+*Entry:
+* char *string - place to put destination string
+*ifdef _COUNT_
+* size_t count - max number of bytes to put in buffer
+*endif
+* char *format - format string, describes format of data
+* va_list ap - varargs argument pointer
+*
+*Exit:
+* returns number of characters in string
+* returns -2 if the string has been truncated (only in _vsnprintf_helper)
+* returns -1 in other error cases
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int __cdecl _vsnprintf_helper (
+ OUTPUTFN outfn,
+ char *string,
+ size_t count,
+ const char *format,
+ va_list ap
+ )
+{
+ miniFILE str;
+ miniFILE *outfile = &str;
+ int retval;
+
+ _VALIDATE_RETURN( (format != NULL), EINVAL, -1);
+
+ _VALIDATE_RETURN( (count == 0) || (string != NULL), EINVAL, -1 );
+
+ if(count>INT_MAX)
+ {
+ /* old-style functions allow any large value to mean unbounded */
+ outfile->_cnt = INT_MAX;
+ }
+ else
+ {
+ outfile->_cnt = (int)count;
+ }
+
+ outfile->_flag = _IOWRT|_IOSTRG;
+ outfile->_ptr = outfile->_base = string;
+
+ retval = outfn(outfile, format, ap );
+
+ if ( string==NULL)
+ return(retval);
+
+ if((retval >= 0) && (_putc_nolock('\0',outfile) != EOF))
+ return(retval);
+
+ string[count - 1] = 0;
+
+ if (outfile->_cnt < 0)
+ {
+ /* the buffer was too small; we return -2 to indicate truncation */
+ return -2;
+ }
+ return -1;
+}
+
+int __cdecl vsprintf_s (
+ char *string,
+ size_t sizeInBytes,
+ const char *format,
+ va_list ap
+ )
+{
+ int retvalue = -1;
+
+ /* validation section */
+ _VALIDATE_RETURN(format != NULL, EINVAL, -1);
+ _VALIDATE_RETURN(string != NULL && sizeInBytes > 0, EINVAL, -1);
+
+ retvalue = _vsnprintf_helper(_output_s, string, sizeInBytes, format, ap);
+ if (retvalue < 0)
+ {
+ string[0] = 0;
+ _SECURECRT__FILL_STRING(string, sizeInBytes, 1);
+ }
+ if (retvalue == -2)
+ {
+ _VALIDATE_RETURN(("Buffer too small" && 0), ERANGE, -1);
+ }
+ if (retvalue >= 0)
+ {
+ _SECURECRT__FILL_STRING(string, sizeInBytes, retvalue + 1);
+ }
+
+ return retvalue;
+}
+
+int __cdecl _vsnprintf_s (
+ char *string,
+ size_t sizeInBytes,
+ size_t count,
+ const char *format,
+ va_list ap
+ )
+{
+ int retvalue = -1;
+ errno_t save_errno = 0;
+
+ /* validation section */
+ _VALIDATE_RETURN(format != NULL, EINVAL, -1);
+ if (count == 0 && string == NULL && sizeInBytes == 0)
+ {
+ /* this case is allowed; nothing to do */
+ return 0;
+ }
+ _VALIDATE_RETURN(string != NULL && sizeInBytes > 0, EINVAL, -1);
+
+ if (sizeInBytes > count)
+ {
+ save_errno = errno;
+ retvalue = _vsnprintf_helper(_output_s, string, count + 1, format, ap);
+ if (retvalue == -2)
+ {
+ /* the string has been truncated, return -1 */
+ _SECURECRT__FILL_STRING(string, sizeInBytes, count + 1);
+ if (errno == ERANGE)
+ {
+ errno = save_errno;
+ }
+ return -1;
+ }
+ }
+ else /* sizeInBytes <= count */
+ {
+ save_errno = errno;
+ retvalue = _vsnprintf_helper(_output_s, string, sizeInBytes, format, ap);
+ string[sizeInBytes - 1] = 0;
+ /* we allow truncation if count == _TRUNCATE */
+ if (retvalue == -2 && count == _TRUNCATE)
+ {
+ if (errno == ERANGE)
+ {
+ errno = save_errno;
+ }
+ return -1;
+ }
+ }
+
+ if (retvalue < 0)
+ {
+ string[0] = 0;
+ _SECURECRT__FILL_STRING(string, sizeInBytes, 1);
+ if (retvalue == -2)
+ {
+ _VALIDATE_RETURN(("Buffer too small" && 0), ERANGE, -1);
+ }
+ return -1;
+ }
+
+ _SECURECRT__FILL_STRING(string, sizeInBytes, retvalue + 1);
+
+ return (retvalue < 0 ? -1 : retvalue);
+}
+
+/***
+* _vscprintf() - counts the number of character needed to print the formatted
+* data
+*
+*Purpose:
+* Counts the number of characters in the fotmatted data.
+*
+*Entry:
+* char *format - format string, describes format of data
+* va_list ap - varargs argument pointer
+*
+*Exit:
+* returns number of characters needed to print formatted data.
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+#ifndef _COUNT_
+
+int __cdecl _vscprintf_helper (
+ OUTPUTFN outfn,
+ const char *format,
+ va_list ap
+ )
+{
+ miniFILE str;
+ miniFILE *outfile = &str;
+ int retval;
+
+ _VALIDATE_RETURN( (format != NULL), EINVAL, -1);
+
+ outfile->_cnt = INT_MAX; //MAXSTR;
+ outfile->_flag = _IOWRT|_IOSTRG;
+ outfile->_ptr = outfile->_base = NULL;
+
+ retval = outfn(outfile, format, ap);
+ return(retval);
+}
+
+int __cdecl _vscprintf (
+ const char *format,
+ va_list ap
+ )
+{
+ return _vscprintf_helper(_output, format, ap);
+}
+
+#endif /* _COUNT_ */
diff --git a/src/pal/src/safecrt/vswprint.c b/src/pal/src/safecrt/vswprint.c
deleted file mode 100644
index 77c79b8752..0000000000
--- a/src/pal/src/safecrt/vswprint.c
+++ /dev/null
@@ -1,282 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/***
-*vswprint.c - print formatted data into a string from var arg list
-*
-*Purpose:
-* defines vswprintf(), _vswprintf_c and _vsnwprintf() - print formatted output to
-* a string, get the data from an argument ptr instead of explicit
-* arguments.
-*
-*******************************************************************************/
-
-
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#include "internal_securecrt.h"
-
-#include "mbusafecrt_internal.h"
-
-typedef int (*WOUTPUTFN)(miniFILE *, const wchar_t *, va_list);
-
-static int _vswprintf_helper( WOUTPUTFN outfn, wchar_t *string, size_t count, const wchar_t *format, va_list ap );
-static int _vscwprintf_helper (WOUTPUTFN outfn, const wchar_t *format, va_list ap );
-
-/***
-*ifndef _COUNT_
-*int _vswprintf(string, format, ap) - print formatted data to string from arg ptr
-*else
-*ifndef _SWPRINTFS_ERROR_RETURN_FIX
-*int _vsnwprintf(string, cnt, format, ap) - print formatted data to string from arg ptr
-*else
-*int _vswprintf_c(string, cnt, format, ...) - print formatted data to string
-*endif
-*endif
-*
-*Purpose:
-* Prints formatted data, but to a string and gets data from an argument
-* pointer.
-* Sets up a FILE so file i/o operations can be used, make string look
-* like a huge buffer to it, but _flsbuf will refuse to flush it if it
-* fills up. Appends '\0' to make it a true string.
-*
-* Allocate the 'fake' _iob[] entryit statically instead of on
-* the stack so that other routines can assume that _iob[] entries are in
-* are in DGROUP and, thus, are near.
-*
-*ifdef _COUNT_
-*ifndef _SWPRINTFS_ERROR_RETURN_FIX
-* The _vsnwprintf() flavor takes a count argument that is
-* the max number of bytes that should be written to the
-* user's buffer.
-* We don't expose this function directly in the headers.
-*else
-* The _vswprintf_c() flavor does the same thing as the _snwprintf
-* above, but, it also fixes an issue in the return value in the case
-* when there isn't enough space to write the null terminator
-* We don't fix this issue in _vsnwprintf because of backward
-* compatibility. In new code, however, _vsnwprintf is #defined to
-* _vswprintf_c so users get the fix.
-*
-*endif
-*
-* Multi-thread: (1) Since there is no stream, this routine must never try
-* to get the stream lock (i.e., there is no stream lock either). (2)
-* Also, since there is only one statically allocated 'fake' iob, we must
-* lock/unlock to prevent collisions.
-*
-*Entry:
-* wchar_t *string - place to put destination string
-*ifdef _COUNT_
-* size_t count - max number of bytes to put in buffer
-*endif
-* wchar_t *format - format string, describes format of data
-* va_list ap - varargs argument pointer
-*
-*Exit:
-* returns number of wide characters in string
-* returns -2 if the string has been truncated (only in _vsnprintf_helper)
-* returns -1 in other error cases
-*
-*Exceptions:
-*
-*******************************************************************************/
-
-int __cdecl _vswprintf_helper (
- WOUTPUTFN woutfn,
- wchar_t *string,
- size_t count,
- const wchar_t *format,
- va_list ap
- )
-{
- miniFILE str;
- miniFILE *outfile = &str;
- int retval;
-
- _VALIDATE_RETURN( (format != NULL), EINVAL, -1);
-
- _VALIDATE_RETURN( (count == 0) || (string != NULL), EINVAL, -1 );
-
- outfile->_flag = _IOWRT|_IOSTRG;
- outfile->_ptr = outfile->_base = (char *) string;
-
- if(count>(INT_MAX/sizeof(wchar_t)))
- {
- /* old-style functions allow any large value to mean unbounded */
- outfile->_cnt = INT_MAX;
- }
- else
- {
- outfile->_cnt = (int)(count*sizeof(wchar_t));
- }
-
- retval = woutfn(outfile, format, ap );
-
- if(string==NULL)
- {
- return retval;
- }
-
- if((retval >= 0) && (_putc_nolock('\0',outfile) != EOF) && (_putc_nolock('\0',outfile) != EOF))
- return(retval);
-
- string[count - 1] = 0;
- if (outfile->_cnt < 0)
- {
- /* the buffer was too small; we return -2 to indicate truncation */
- return -2;
- }
- return -1;
-}
-
-int __cdecl _vswprintf_s (
- wchar_t *string,
- size_t sizeInWords,
- const wchar_t *format,
- va_list ap
- )
-{
- int retvalue = -1;
-
- /* validation section */
- _VALIDATE_RETURN(format != NULL, EINVAL, -1);
- _VALIDATE_RETURN(string != NULL && sizeInWords > 0, EINVAL, -1);
-
- retvalue = _vswprintf_helper(_woutput_s, string, sizeInWords, format, ap);
- if (retvalue < 0)
- {
- string[0] = 0;
- _SECURECRT__FILL_STRING(string, sizeInWords, 1);
- }
- if (retvalue == -2)
- {
- _VALIDATE_RETURN(("Buffer too small" && 0), ERANGE, -1);
- }
- if (retvalue >= 0)
- {
- _SECURECRT__FILL_STRING(string, sizeInWords, retvalue + 1);
- }
-
- return retvalue;
-}
-
-int __cdecl _vsnwprintf_s (
- wchar_t *string,
- size_t sizeInWords,
- size_t count,
- const wchar_t *format,
- va_list ap
- )
-{
- int retvalue = -1;
- errno_t save_errno = 0;
-
- /* validation section */
- _VALIDATE_RETURN(format != NULL, EINVAL, -1);
- if (count == 0 && string == NULL && sizeInWords == 0)
- {
- /* this case is allowed; nothing to do */
- return 0;
- }
- _VALIDATE_RETURN(string != NULL && sizeInWords > 0, EINVAL, -1);
-
- if (sizeInWords > count)
- {
- save_errno = errno;
- retvalue = _vswprintf_helper(_woutput_s, string, count + 1, format, ap);
- if (retvalue == -2)
- {
- /* the string has been truncated, return -1 */
- _SECURECRT__FILL_STRING(string, sizeInWords, count + 1);
- if (errno == ERANGE)
- {
- errno = save_errno;
- }
- return -1;
- }
- }
- else /* sizeInWords <= count */
- {
- save_errno = errno;
- retvalue = _vswprintf_helper(_woutput_s, string, sizeInWords, format, ap);
- string[sizeInWords - 1] = 0;
- /* we allow truncation if count == _TRUNCATE */
- if (retvalue == -2 && count == _TRUNCATE)
- {
- if (errno == ERANGE)
- {
- errno = save_errno;
- }
- return -1;
- }
- }
-
- if (retvalue < 0)
- {
- string[0] = 0;
- _SECURECRT__FILL_STRING(string, sizeInWords, 1);
- if (retvalue == -2)
- {
- _VALIDATE_RETURN(("Buffer too small" && 0), ERANGE, -1);
- }
- return -1;
- }
-
- _SECURECRT__FILL_STRING(string, sizeInWords, retvalue + 1);
-
- return (retvalue < 0 ? -1 : retvalue);
-}
-
-/***
-* _vscwprintf() - counts the number of character needed to print the formatted
-* data
-*
-*Purpose:
-* Counts the number of characters in the fotmatted data.
-*
-*Entry:
-* wchar_t *format - format string, describes format of data
-* va_list ap - varargs argument pointer
-*
-*Exit:
-* returns number of characters needed to print formatted data.
-*
-*Exceptions:
-*
-*******************************************************************************/
-
-#ifndef _COUNT_
-
-int __cdecl _vscwprintf_helper (
- WOUTPUTFN woutfn,
- const wchar_t *format,
- va_list ap
- )
-{
- miniFILE str;
- miniFILE *outfile = &str;
- int retval;
-
- _VALIDATE_RETURN( (format != NULL), EINVAL, -1);
-
- outfile->_cnt = INT_MAX; //MAXSTR;
- outfile->_flag = _IOWRT|_IOSTRG;
- outfile->_ptr = outfile->_base = NULL;
-
- retval = woutfn(outfile, format, ap);
- return(retval);
-}
-
-int __cdecl _vscwprintf (
- const wchar_t *format,
- va_list ap
- )
-{
- return _vscwprintf_helper(_woutput_s, format, ap);
-}
-
-#endif /* _COUNT_ */
diff --git a/src/pal/src/safecrt/vswprint.cpp b/src/pal/src/safecrt/vswprint.cpp
new file mode 100644
index 0000000000..b9940a693a
--- /dev/null
+++ b/src/pal/src/safecrt/vswprint.cpp
@@ -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.
+
+/***
+*vswprint.c - print formatted data into a string from var arg list
+*
+*Purpose:
+* defines vswprintf_s() and _vsnwprintf_s() - print formatted output to
+* a string, get the data from an argument ptr instead of explicit
+* arguments.
+*
+*******************************************************************************/
+
+
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include "internal_securecrt.h"
+
+#include "mbusafecrt_internal.h"
+
+typedef int (*WOUTPUTFN)(miniFILE *, const wchar_t *, va_list);
+
+static int _vswprintf_helper( WOUTPUTFN outfn, wchar_t *string, size_t count, const wchar_t *format, va_list ap );
+
+/***
+*int vswprintf_s(string, sizeInWords, format, ap) - print formatted data to string from arg ptr
+*int _vsnwprintf_s(string, sizeInWords, cnt, format, ap) - print formatted data to string from arg ptr
+*Purpose:
+* Prints formatted data, but to a string and gets data from an argument
+* pointer.
+* Sets up a FILE so file i/o operations can be used, make string look
+* like a huge buffer to it, but _flsbuf will refuse to flush it if it
+* fills up. Appends '\0' to make it a true string.
+*
+* Allocate the 'fake' _iob[] entryit statically instead of on
+* the stack so that other routines can assume that _iob[] entries are in
+* are in DGROUP and, thus, are near.
+*
+* The _vsnwprintf_s() flavor takes a count argument that is
+* the max number of bytes that should be written to the
+* user's buffer.
+* We don't expose this function directly in the headers.
+*
+* Multi-thread: (1) Since there is no stream, this routine must never try
+* to get the stream lock (i.e., there is no stream lock either). (2)
+* Also, since there is only one statically allocated 'fake' iob, we must
+* lock/unlock to prevent collisions.
+*
+*Entry:
+* wchar_t *string - place to put destination string
+* size_t sizeInWords - size of the string buffer in wchar_t units
+* size_t count - max number of bytes to put in buffer
+* wchar_t *format - format string, describes format of data
+* va_list ap - varargs argument pointer
+*
+*Exit:
+* returns number of wide characters in string
+* returns -2 if the string has been truncated (only in _vsnprintf_helper)
+* returns -1 in other error cases
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int __cdecl _vswprintf_helper (
+ WOUTPUTFN woutfn,
+ wchar_t *string,
+ size_t count,
+ const wchar_t *format,
+ va_list ap
+ )
+{
+ miniFILE str;
+ miniFILE *outfile = &str;
+ int retval;
+
+ _VALIDATE_RETURN( (format != NULL), EINVAL, -1);
+
+ _VALIDATE_RETURN( (count == 0) || (string != NULL), EINVAL, -1 );
+
+ outfile->_flag = _IOWRT|_IOSTRG;
+ outfile->_ptr = outfile->_base = (char *) string;
+
+ if(count>(INT_MAX/sizeof(wchar_t)))
+ {
+ /* old-style functions allow any large value to mean unbounded */
+ outfile->_cnt = INT_MAX;
+ }
+ else
+ {
+ outfile->_cnt = (int)(count*sizeof(wchar_t));
+ }
+
+ retval = woutfn(outfile, format, ap );
+
+ if(string==NULL)
+ {
+ return retval;
+ }
+
+ if((retval >= 0) && (_putc_nolock('\0',outfile) != EOF) && (_putc_nolock('\0',outfile) != EOF))
+ return(retval);
+
+ string[count - 1] = 0;
+ if (outfile->_cnt < 0)
+ {
+ /* the buffer was too small; we return -2 to indicate truncation */
+ return -2;
+ }
+ return -1;
+}
+
+int __cdecl vswprintf_s (
+ wchar_t *string,
+ size_t sizeInWords,
+ const wchar_t *format,
+ va_list ap
+ )
+{
+ int retvalue = -1;
+
+ /* validation section */
+ _VALIDATE_RETURN(format != NULL, EINVAL, -1);
+ _VALIDATE_RETURN(string != NULL && sizeInWords > 0, EINVAL, -1);
+
+ retvalue = _vswprintf_helper(_woutput_s, string, sizeInWords, format, ap);
+ if (retvalue < 0)
+ {
+ string[0] = 0;
+ _SECURECRT__FILL_STRING(string, sizeInWords, 1);
+ }
+ if (retvalue == -2)
+ {
+ _VALIDATE_RETURN(("Buffer too small" && 0), ERANGE, -1);
+ }
+ if (retvalue >= 0)
+ {
+ _SECURECRT__FILL_STRING(string, sizeInWords, retvalue + 1);
+ }
+
+ return retvalue;
+}
+
+int __cdecl _vsnwprintf_s (
+ wchar_t *string,
+ size_t sizeInWords,
+ size_t count,
+ const wchar_t *format,
+ va_list ap
+ )
+{
+ int retvalue = -1;
+ errno_t save_errno = 0;
+
+ /* validation section */
+ _VALIDATE_RETURN(format != NULL, EINVAL, -1);
+ if (count == 0 && string == NULL && sizeInWords == 0)
+ {
+ /* this case is allowed; nothing to do */
+ return 0;
+ }
+ _VALIDATE_RETURN(string != NULL && sizeInWords > 0, EINVAL, -1);
+
+ if (sizeInWords > count)
+ {
+ save_errno = errno;
+ retvalue = _vswprintf_helper(_woutput_s, string, count + 1, format, ap);
+ if (retvalue == -2)
+ {
+ /* the string has been truncated, return -1 */
+ _SECURECRT__FILL_STRING(string, sizeInWords, count + 1);
+ if (errno == ERANGE)
+ {
+ errno = save_errno;
+ }
+ return -1;
+ }
+ }
+ else /* sizeInWords <= count */
+ {
+ save_errno = errno;
+ retvalue = _vswprintf_helper(_woutput_s, string, sizeInWords, format, ap);
+ string[sizeInWords - 1] = 0;
+ /* we allow truncation if count == _TRUNCATE */
+ if (retvalue == -2 && count == _TRUNCATE)
+ {
+ if (errno == ERANGE)
+ {
+ errno = save_errno;
+ }
+ return -1;
+ }
+ }
+
+ if (retvalue < 0)
+ {
+ string[0] = 0;
+ _SECURECRT__FILL_STRING(string, sizeInWords, 1);
+ if (retvalue == -2)
+ {
+ _VALIDATE_RETURN(("Buffer too small" && 0), ERANGE, -1);
+ }
+ return -1;
+ }
+
+ _SECURECRT__FILL_STRING(string, sizeInWords, retvalue + 1);
+
+ return (retvalue < 0 ? -1 : retvalue);
+}
diff --git a/src/pal/src/safecrt/wcscat_s.c b/src/pal/src/safecrt/wcscat_s.cpp
index 06179888ff..06179888ff 100644
--- a/src/pal/src/safecrt/wcscat_s.c
+++ b/src/pal/src/safecrt/wcscat_s.cpp
diff --git a/src/pal/src/safecrt/wcscpy_s.c b/src/pal/src/safecrt/wcscpy_s.cpp
index 4c60a81489..4c60a81489 100644
--- a/src/pal/src/safecrt/wcscpy_s.c
+++ b/src/pal/src/safecrt/wcscpy_s.cpp
diff --git a/src/pal/src/safecrt/wcslen_s.c b/src/pal/src/safecrt/wcslen_s.cpp
index 4fd5371035..4fd5371035 100644
--- a/src/pal/src/safecrt/wcslen_s.c
+++ b/src/pal/src/safecrt/wcslen_s.cpp
diff --git a/src/pal/src/safecrt/wcsncat_s.c b/src/pal/src/safecrt/wcsncat_s.cpp
index 1ff39d55f3..1ff39d55f3 100644
--- a/src/pal/src/safecrt/wcsncat_s.c
+++ b/src/pal/src/safecrt/wcsncat_s.cpp
diff --git a/src/pal/src/safecrt/wcsncpy_s.c b/src/pal/src/safecrt/wcsncpy_s.cpp
index 7902ded43a..7902ded43a 100644
--- a/src/pal/src/safecrt/wcsncpy_s.c
+++ b/src/pal/src/safecrt/wcsncpy_s.cpp
diff --git a/src/pal/src/safecrt/wcstok_s.c b/src/pal/src/safecrt/wcstok_s.cpp
index c99b30c773..c99b30c773 100644
--- a/src/pal/src/safecrt/wcstok_s.c
+++ b/src/pal/src/safecrt/wcstok_s.cpp
diff --git a/src/pal/src/safecrt/wmakepath_s.c b/src/pal/src/safecrt/wmakepath_s.cpp
index 35ab7d386e..35ab7d386e 100644
--- a/src/pal/src/safecrt/wmakepath_s.c
+++ b/src/pal/src/safecrt/wmakepath_s.cpp
diff --git a/src/pal/src/safecrt/wsplitpath_s.c b/src/pal/src/safecrt/wsplitpath_s.cpp
index c7fb107803..c7fb107803 100644
--- a/src/pal/src/safecrt/wsplitpath_s.c
+++ b/src/pal/src/safecrt/wsplitpath_s.cpp
diff --git a/src/pal/src/safecrt/xtoa_s.c b/src/pal/src/safecrt/xtoa_s.cpp
index 42cc5786d1..42cc5786d1 100644
--- a/src/pal/src/safecrt/xtoa_s.c
+++ b/src/pal/src/safecrt/xtoa_s.cpp
diff --git a/src/pal/src/safecrt/xtow_s.c b/src/pal/src/safecrt/xtow_s.cpp
index 7a02424c85..7a02424c85 100644
--- a/src/pal/src/safecrt/xtow_s.c
+++ b/src/pal/src/safecrt/xtow_s.cpp
diff --git a/src/pal/src/safecrt/xtox_s.inl b/src/pal/src/safecrt/xtox_s.inl
index e07d87adf5..7c8b2f2fd6 100644
--- a/src/pal/src/safecrt/xtox_s.inl
+++ b/src/pal/src/safecrt/xtox_s.inl
@@ -21,12 +21,9 @@
#define _i64tox_s _i64tow_s
#define _ui64tox_s _ui64tow_s
#define xtox xtow
-#define _itox _itow
#define _ltox _ltow
#define _ultox _ultow
#define x64tox x64tow
-#define _i64tox _i64tow
-#define _ui64tox _ui64tow
#else /* _UNICODE */
#define xtox_s xtoa_s
#define _itox_s _itoa_s
@@ -36,12 +33,9 @@
#define _i64tox_s _i64toa_s
#define _ui64tox_s _ui64toa_s
#define xtox xtoa
-#define _itox _itoa
#define _ltox _ltoa
#define _ultox _ultoa
#define x64tox x64toa
-#define _i64tox _i64toa
-#define _ui64tox _ui64toa
#endif /* _UNICODE */
/***
@@ -224,19 +218,6 @@ errno_t __cdecl _ultox_s (
/* Actual functions just call conversion helper with neg flag set correctly,
and return pointer to buffer. */
-TCHAR * __cdecl _itox (
- int val,
- TCHAR *buf,
- int radix
- )
-{
- if (radix == 10 && val < 0)
- xtox((unsigned long)val, buf, radix, 1);
- else
- xtox((unsigned long)(unsigned int)val, buf, radix, 0);
- return buf;
-}
-
TCHAR * __cdecl _ltox (
long val,
TCHAR *buf,
@@ -425,16 +406,6 @@ errno_t __cdecl _ui64tox_s (
/* Actual functions just call conversion helper with neg flag set correctly,
and return pointer to buffer. */
-TCHAR * __cdecl _i64tox (
- __int64 val,
- TCHAR *buf,
- int radix
- )
-{
- x64tox((unsigned __int64)val, buf, radix, (radix == 10 && val < 0));
- return buf;
-}
-
TCHAR * __cdecl _ui64tox (
unsigned __int64 val,
TCHAR *buf,
diff --git a/src/pal/src/synchmgr/synchmanager.cpp b/src/pal/src/synchmgr/synchmanager.cpp
index 473918cb68..3aec140474 100644
--- a/src/pal/src/synchmgr/synchmanager.cpp
+++ b/src/pal/src/synchmgr/synchmanager.cpp
@@ -1648,7 +1648,7 @@ namespace CorUnix
}
// Entry point routine for the thread that initiates process termination.
- DWORD TerminationRequestHandlingRoutine(LPVOID pArg)
+ DWORD PALAPI TerminationRequestHandlingRoutine(LPVOID pArg)
{
// Call the termination request handler if one is registered.
if (g_terminationRequestHandler != NULL)
diff --git a/src/pal/src/thread/context.cpp b/src/pal/src/thread/context.cpp
index f832015710..0449df568b 100644
--- a/src/pal/src/thread/context.cpp
+++ b/src/pal/src/thread/context.cpp
@@ -33,9 +33,7 @@ SET_DEFAULT_DEBUG_CHANNEL(THREAD); // some headers have code with asserts, so do
extern PGET_GCMARKER_EXCEPTION_CODE g_getGcMarkerExceptionCode;
-// in context2.S
-extern void CONTEXT_CaptureContext(LPCONTEXT lpContext);
-
+#define CONTEXT_AREA_MASK 0xffff
#ifdef _X86_
#define CONTEXT_ALL_FLOATING (CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS)
#elif defined(_AMD64_)
@@ -288,7 +286,7 @@ CONTEXT_GetThreadContext(
}
if (lpContext->ContextFlags &
- (CONTEXT_CONTROL | CONTEXT_INTEGER))
+ (CONTEXT_CONTROL | CONTEXT_INTEGER) & CONTEXT_AREA_MASK)
{
if (CONTEXT_GetRegisters(dwProcessId, lpContext) == FALSE)
{
@@ -348,7 +346,7 @@ CONTEXT_SetThreadContext(
}
if (lpContext->ContextFlags &
- (CONTEXT_CONTROL | CONTEXT_INTEGER))
+ (CONTEXT_CONTROL | CONTEXT_INTEGER) & CONTEXT_AREA_MASK)
{
#if HAVE_PT_REGS
if (ptrace((__ptrace_request)PT_GETREGS, dwProcessId, (caddr_t)&ptrace_registers, 0) == -1)
@@ -371,11 +369,11 @@ CONTEXT_SetThreadContext(
ASSERT("Don't know how to set the context of another process on this platform!");
return FALSE;
#endif
- if (lpContext->ContextFlags & CONTEXT_CONTROL)
+ if (lpContext->ContextFlags & CONTEXT_CONTROL & CONTEXT_AREA_MASK)
{
ASSIGN_CONTROL_REGS
}
- if (lpContext->ContextFlags & CONTEXT_INTEGER)
+ if (lpContext->ContextFlags & CONTEXT_INTEGER & CONTEXT_AREA_MASK)
{
ASSIGN_INTEGER_REGS
}
@@ -467,13 +465,13 @@ void CONTEXTToNativeContext(CONST CONTEXT *lpContext, native_context_t *native)
}
// TODO: Enable for all Unix systems
-#if defined(_AMD64_) && defined(__linux__)
+#if defined(_AMD64_) && defined(XSTATE_SUPPORTED)
if ((lpContext->ContextFlags & CONTEXT_XSTATE) == CONTEXT_XSTATE)
{
_ASSERTE(FPREG_HasExtendedState(native));
memcpy_s(FPREG_Xstate_Ymmh(native), sizeof(M128A) * 16, lpContext->VectorRegister, sizeof(M128A) * 16);
}
-#endif // _AMD64_
+#endif //_AMD64_ && XSTATE_SUPPORTED
}
/*++
@@ -564,22 +562,24 @@ void CONTEXTFromNativeContext(const native_context_t *native, LPCONTEXT lpContex
#endif
}
- // TODO: Enable for all Unix systems
-#if defined(_AMD64_) && defined(__linux__)
+#ifdef _AMD64_
if ((contextFlags & CONTEXT_XSTATE) == CONTEXT_XSTATE)
{
+ // TODO: Enable for all Unix systems
+#if XSTATE_SUPPORTED
if (FPREG_HasExtendedState(native))
{
memcpy_s(lpContext->VectorRegister, sizeof(M128A) * 16, FPREG_Xstate_Ymmh(native), sizeof(M128A) * 16);
}
else
+#endif // XSTATE_SUPPORTED
{
// Reset the CONTEXT_XSTATE bit(s) so it's clear that the extended state data in
// the CONTEXT is not valid.
const ULONG xstateFlags = CONTEXT_XSTATE & ~(CONTEXT_CONTROL & CONTEXT_INTEGER);
lpContext->ContextFlags &= ~xstateFlags;
}
- }
+ }
#endif // _AMD64_
}
@@ -855,7 +855,7 @@ CONTEXT_GetThreadContextFromPort(
mach_msg_type_number_t StateCount;
thread_state_flavor_t StateFlavor;
- if (lpContext->ContextFlags & (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS))
+ if (lpContext->ContextFlags & (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS) & CONTEXT_AREA_MASK)
{
#ifdef _X86_
x86_thread_state32_t State;
@@ -877,7 +877,7 @@ CONTEXT_GetThreadContextFromPort(
CONTEXT_GetThreadContextFromThreadState(StateFlavor, (thread_state_t)&State, lpContext);
}
- if (lpContext->ContextFlags & CONTEXT_ALL_FLOATING) {
+ if (lpContext->ContextFlags & CONTEXT_ALL_FLOATING & CONTEXT_AREA_MASK) {
#ifdef _X86_
x86_float_state32_t State;
StateFlavor = x86_FLOAT_STATE32;
@@ -898,6 +898,22 @@ CONTEXT_GetThreadContextFromPort(
CONTEXT_GetThreadContextFromThreadState(StateFlavor, (thread_state_t)&State, lpContext);
}
+#if defined(_AMD64_) && defined(XSTATE_SUPPORTED)
+ if (lpContext->ContextFlags & CONTEXT_XSTATE & CONTEXT_AREA_MASK) {
+ x86_avx_state64_t State;
+ StateFlavor = x86_AVX_STATE64;
+ StateCount = sizeof(State) / sizeof(natural_t);
+ MachRet = thread_get_state(Port, StateFlavor, (thread_state_t)&State, &StateCount);
+ if (MachRet != KERN_SUCCESS)
+ {
+ ASSERT("thread_get_state(XSTATE) failed: %d\n", MachRet);
+ goto exit;
+ }
+
+ CONTEXT_GetThreadContextFromThreadState(StateFlavor, (thread_state_t)&State, lpContext);
+ }
+#endif
+
exit:
return MachRet;
}
@@ -917,7 +933,7 @@ CONTEXT_GetThreadContextFromThreadState(
{
#ifdef _X86_
case x86_THREAD_STATE32:
- if (lpContext->ContextFlags & (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS))
+ if (lpContext->ContextFlags & (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS) & CONTEXT_AREA_MASK)
{
x86_thread_state32_t *pState = (x86_thread_state32_t *)threadState;
@@ -944,7 +960,7 @@ CONTEXT_GetThreadContextFromThreadState(
{
x86_float_state32_t *pState = (x86_float_state32_t *)threadState;
- if (lpContext->ContextFlags & CONTEXT_FLOATING_POINT)
+ if (lpContext->ContextFlags & CONTEXT_FLOATING_POINT & CONTEXT_AREA_MASK)
{
lpContext->FloatSave.ControlWord = *(DWORD*)&pState->fpu_fcw;
lpContext->FloatSave.StatusWord = *(DWORD*)&pState->fpu_fsw;
@@ -963,7 +979,7 @@ CONTEXT_GetThreadContextFromThreadState(
memcpy(&lpContext->FloatSave.RegisterArea[i * 10], (&pState->fpu_stmm0)[i].mmst_reg, 10);
}
- if (lpContext->ContextFlags & CONTEXT_EXTENDED_REGISTERS)
+ if (lpContext->ContextFlags & CONTEXT_EXTENDED_REGISTERS & CONTEXT_AREA_MASK)
{
// The only extended register information that Mach will tell us about are the xmm register values.
// Both Windows and Mach store the registers in a packed layout (each of the 8 registers is 16 bytes)
@@ -975,7 +991,7 @@ CONTEXT_GetThreadContextFromThreadState(
#elif defined(_AMD64_)
case x86_THREAD_STATE64:
- if (lpContext->ContextFlags & (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS))
+ if (lpContext->ContextFlags & (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS) & CONTEXT_AREA_MASK)
{
x86_thread_state64_t *pState = (x86_thread_state64_t *)threadState;
@@ -1009,7 +1025,7 @@ CONTEXT_GetThreadContextFromThreadState(
break;
case x86_FLOAT_STATE64:
- if (lpContext->ContextFlags & CONTEXT_FLOATING_POINT)
+ if (lpContext->ContextFlags & CONTEXT_FLOATING_POINT & CONTEXT_AREA_MASK)
{
x86_float_state64_t *pState = (x86_float_state64_t *)threadState;
@@ -1031,9 +1047,19 @@ CONTEXT_GetThreadContextFromThreadState(
memcpy(&lpContext->FltSave.FloatRegisters[i], (&pState->__fpu_stmm0)[i].__mmst_reg, 10);
// AMD64's FLOATING_POINT includes the xmm registers.
- memcpy(&lpContext->Xmm0, &pState->__fpu_xmm0, 8 * 16);
+ memcpy(&lpContext->Xmm0, &pState->__fpu_xmm0, 16 * 16);
+ }
+ break;
+
+#ifdef XSTATE_SUPPORTED
+ case x86_AVX_STATE64:
+ if (lpContext->ContextFlags & CONTEXT_XSTATE & CONTEXT_AREA_MASK)
+ {
+ x86_avx_state64_t *pState = (x86_avx_state64_t *)threadState;
+ memcpy(&lpContext->VectorRegister, &pState->__fpu_ymmh0, 16 * 16);
}
break;
+#endif
#else
#error Unexpected architecture.
#endif
@@ -1120,7 +1146,7 @@ CONTEXT_SetThreadContextOnPort(
mach_msg_type_number_t StateCount;
thread_state_flavor_t StateFlavor;
- if (lpContext->ContextFlags & (CONTEXT_CONTROL|CONTEXT_INTEGER))
+ if (lpContext->ContextFlags & (CONTEXT_CONTROL|CONTEXT_INTEGER) & CONTEXT_AREA_MASK)
{
#ifdef _X86_
x86_thread_state32_t State;
@@ -1187,21 +1213,42 @@ CONTEXT_SetThreadContextOnPort(
}
}
- if (lpContext->ContextFlags & CONTEXT_ALL_FLOATING)
+ if (lpContext->ContextFlags & CONTEXT_ALL_FLOATING & CONTEXT_AREA_MASK)
{
#ifdef _X86_
x86_float_state32_t State;
StateFlavor = x86_FLOAT_STATE32;
+ StateCount = sizeof(State) / sizeof(natural_t);
#elif defined(_AMD64_)
+#ifdef XSTATE_SUPPORTED
+ // We're relying on the fact that the initial portion of
+ // x86_avx_state64_t is identical to x86_float_state64_t.
+ // Check a few fields to make sure the assumption is correct.
+ static_assert_no_msg(sizeof(x86_avx_state64_t) > sizeof(x86_float_state64_t));
+ static_assert_no_msg(offsetof(x86_avx_state64_t, __fpu_fcw) == offsetof(x86_float_state64_t, __fpu_fcw));
+ static_assert_no_msg(offsetof(x86_avx_state64_t, __fpu_xmm0) == offsetof(x86_float_state64_t, __fpu_xmm0));
+
+ x86_avx_state64_t State;
+ if (lpContext->ContextFlags & CONTEXT_XSTATE & CONTEXT_AREA_MASK)
+ {
+ StateFlavor = x86_AVX_STATE64;
+ StateCount = sizeof(State) / sizeof(natural_t);
+ }
+ else
+ {
+ StateFlavor = x86_FLOAT_STATE64;
+ StateCount = sizeof(x86_float_state64_t) / sizeof(natural_t);
+ }
+#else
x86_float_state64_t State;
StateFlavor = x86_FLOAT_STATE64;
+ StateCount = sizeof(State) / sizeof(natural_t);
+#endif
#else
#error Unexpected architecture.
#endif
- StateCount = sizeof(State) / sizeof(natural_t);
-
// If we're setting only one of the floating point or extended registers (of which Mach supports only
// the xmm values) then we don't have values for the other set. This is a problem since Mach only
// supports setting both groups as a single unit. So in this case we'll need to fetch the current
@@ -1222,7 +1269,7 @@ CONTEXT_SetThreadContextOnPort(
_ASSERTE(StateCountGet == StateCount);
}
- if (lpContext->ContextFlags & CONTEXT_FLOATING_POINT)
+ if (lpContext->ContextFlags & CONTEXT_FLOATING_POINT & CONTEXT_AREA_MASK)
{
#ifdef _X86_
*(DWORD*)&State.fpu_fcw = lpContext->FloatSave.ControlWord;
@@ -1258,14 +1305,14 @@ CONTEXT_SetThreadContextOnPort(
for (int i = 0; i < 8; i++)
memcpy((&State.__fpu_stmm0)[i].__mmst_reg, &lpContext->FltSave.FloatRegisters[i], 10);
- memcpy(&State.__fpu_xmm0, &lpContext->Xmm0, 8 * 16);
+ memcpy(&State.__fpu_xmm0, &lpContext->Xmm0, 16 * 16);
#else
#error Unexpected architecture.
#endif
}
#ifdef _X86_
- if (lpContext->ContextFlags & CONTEXT_EXTENDED_REGISTERS)
+ if (lpContext->ContextFlags & CONTEXT_EXTENDED_REGISTERS & CONTEXT_AREA_MASK)
{
// The only extended register information that Mach will tell us about are the xmm register
// values. Both Windows and Mach store the registers in a packed layout (each of the 8 registers
@@ -1274,6 +1321,13 @@ CONTEXT_SetThreadContextOnPort(
}
#endif // _X86_
+#if defined(_AMD64_) && defined(XSTATE_SUPPORTED)
+ if (lpContext->ContextFlags & CONTEXT_XSTATE & CONTEXT_AREA_MASK)
+ {
+ memcpy(&State.__fpu_ymmh0, lpContext->VectorRegister, 16 * 16);
+ }
+#endif
+
MachRet = thread_set_state(Port,
StateFlavor,
(thread_state_t)&State,
diff --git a/src/pal/src/thread/process.cpp b/src/pal/src/thread/process.cpp
index 315145dc03..a64bfb8ab1 100644
--- a/src/pal/src/thread/process.cpp
+++ b/src/pal/src/thread/process.cpp
@@ -2049,18 +2049,18 @@ GetProcessIdDisambiguationKey(DWORD processId, UINT64 *disambiguationKey)
// According to `man proc`, the second field in the stat file is the filename of the executable,
// in parentheses. Tokenizing the stat file using spaces as separators breaks when that name
- // has spaces in it, so we start using sscanf after skipping everything up to and including the
+ // has spaces in it, so we start using sscanf_s after skipping everything up to and including the
// last closing paren and the space after it.
char *scanStartPosition = strrchr(line, ')') + 2;
// All the format specifiers for the fields in the stat file are provided by 'man proc'.
- int sscanfRet = sscanf(scanStartPosition,
+ int sscanfRet = sscanf_s(scanStartPosition,
"%*c %*d %*d %*d %*d %*d %*u %*lu %*lu %*lu %*lu %*lu %*lu %*ld %*ld %*ld %*ld %*ld %*ld %llu \n",
&starttime);
if (sscanfRet != 1)
{
- _ASSERTE(!"Failed to parse stat file contents with sscanf.");
+ _ASSERTE(!"Failed to parse stat file contents with sscanf_s.");
return FALSE;
}
@@ -2095,7 +2095,7 @@ PAL_GetTransportPipeName(char *name, DWORD id, const char *suffix)
// also try to use 0 as the value.
_ASSERTE(ret == TRUE || disambiguationKey == 0);
- int chars = _snprintf(name, MAX_DEBUGGER_TRANSPORT_PIPE_NAME_LENGTH, PipeNameFormat, id, disambiguationKey, suffix);
+ int chars = snprintf(name, MAX_DEBUGGER_TRANSPORT_PIPE_NAME_LENGTH, PipeNameFormat, id, disambiguationKey, suffix);
_ASSERTE(chars > 0 && chars < MAX_DEBUGGER_TRANSPORT_PIPE_NAME_LENGTH);
}
@@ -2690,7 +2690,7 @@ CreateProcessModules(
char moduleName[PATH_MAX];
int size;
- if (sscanf(line, "__TEXT %p-%p [ %dK] %*[-/rwxsp] SM=%*[A-Z] %s\n", &startAddress, &endAddress, &size, moduleName) == 4)
+ if (sscanf_s(line, "__TEXT %p-%p [ %dK] %*[-/rwxsp] SM=%*[A-Z] %s\n", &startAddress, &endAddress, &size, moduleName, _countof(moduleName)) == 4)
{
bool dup = false;
for (ProcessModules *entry = listHead; entry != NULL; entry = entry->Next)
@@ -2768,7 +2768,7 @@ exit:
int devHi, devLo, inode;
char moduleName[PATH_MAX];
- if (sscanf(line, "%p-%p %*[-rwxsp] %p %x:%x %d %s\n", &startAddress, &endAddress, &offset, &devHi, &devLo, &inode, moduleName) == 7)
+ if (sscanf_s(line, "%p-%p %*[-rwxsp] %p %x:%x %d %s\n", &startAddress, &endAddress, &offset, &devHi, &devLo, &inode, moduleName, _countof(moduleName)) == 7)
{
if (inode != 0)
{
diff --git a/src/pal/tests/CMakeLists.txt b/src/pal/tests/CMakeLists.txt
index a6d1ba4d5b..39d5852889 100644
--- a/src/pal/tests/CMakeLists.txt
+++ b/src/pal/tests/CMakeLists.txt
@@ -1,6 +1,8 @@
cmake_minimum_required(VERSION 2.8.12.2)
-if(CLR_CMAKE_PLATFORM_ARCH_AMD64)
+if(CLR_CMAKE_PLATFORM_ARCH_I386)
+ set(PAL_CMAKE_PLATFORM_ARCH_I386 1)
+elseif(CLR_CMAKE_PLATFORM_ARCH_AMD64)
set(PAL_CMAKE_PLATFORM_ARCH_AMD64 1)
elseif(CLR_CMAKE_PLATFORM_ARCH_ARM)
set(PAL_CMAKE_PLATFORM_ARCH_ARM 1)
@@ -14,7 +16,9 @@ add_definitions(-DLP64COMPATIBLE=1)
add_definitions(-DFEATURE_PAL=1)
add_definitions(-DCORECLR=1)
add_definitions(-DPIC=1)
-if(PAL_CMAKE_PLATFORM_ARCH_AMD64)
+if(PAL_CMAKE_PLATFORM_ARCH_I386)
+ add_definitions(-DBIT32=1)
+elseif(PAL_CMAKE_PLATFORM_ARCH_AMD64)
add_definitions(-DBIT64=1)
add_definitions(-D_WIN64=1)
elseif(PAL_CMAKE_PLATFORM_ARCH_ARM)
@@ -23,10 +27,15 @@ elseif(PAL_CMAKE_PLATFORM_ARCH_ARM64)
add_definitions(-DBIT64=1)
add_definitions(-D_WIN64=1)
else()
- message(FATAL_ERROR "Only ARM, ARM64 and AMD64 is supported")
+ message(FATAL_ERROR "Only ARM, ARM64, I386, and AMD64 is supported")
endif()
+# C++ emits errors and warnings for c-string literal fed into char* parameter
+# this is just to take care of the warnings
+add_compile_options(-Wno-writable-strings)
+
add_compile_options(-Wno-empty-body)
add_subdirectory(palsuite)
+
diff --git a/src/pal/tests/palsuite/c_runtime/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/CMakeLists.txt
index 533454c285..cf062530eb 100644
--- a/src/pal/tests/palsuite/c_runtime/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/CMakeLists.txt
@@ -2,16 +2,23 @@ cmake_minimum_required(VERSION 2.8.12.2)
add_subdirectory(abs)
add_subdirectory(acos)
+add_subdirectory(acosf)
add_subdirectory(asin)
+add_subdirectory(asinf)
add_subdirectory(atan)
add_subdirectory(atan2)
+add_subdirectory(atan2f)
+add_subdirectory(atanf)
add_subdirectory(atof)
add_subdirectory(atoi)
add_subdirectory(atol)
add_subdirectory(bsearch)
add_subdirectory(ceil)
+add_subdirectory(ceilf)
add_subdirectory(cos)
+add_subdirectory(cosf)
add_subdirectory(cosh)
+add_subdirectory(coshf)
# TODO: make this test compile
# add_subdirectory(ctime)
@@ -19,6 +26,7 @@ add_subdirectory(cosh)
add_subdirectory(errno)
add_subdirectory(exit)
add_subdirectory(exp)
+add_subdirectory(expf)
add_subdirectory(fabs)
add_subdirectory(fabsf)
add_subdirectory(fclose)
@@ -27,6 +35,7 @@ add_subdirectory(ferror)
add_subdirectory(fflush)
add_subdirectory(fgets)
add_subdirectory(floor)
+add_subdirectory(floorf)
add_subdirectory(fmod)
add_subdirectory(fmodf)
add_subdirectory(fopen)
@@ -57,6 +66,8 @@ add_subdirectory(llabs)
add_subdirectory(localtime)
add_subdirectory(log)
add_subdirectory(log10)
+add_subdirectory(log10f)
+add_subdirectory(logf)
add_subdirectory(malloc)
add_subdirectory(memchr)
add_subdirectory(memcmp)
@@ -66,15 +77,19 @@ add_subdirectory(memset)
add_subdirectory(modf)
add_subdirectory(modff)
add_subdirectory(pow)
+add_subdirectory(powf)
add_subdirectory(printf)
add_subdirectory(qsort)
add_subdirectory(rand_srand)
add_subdirectory(realloc)
add_subdirectory(sin)
+add_subdirectory(sinf)
add_subdirectory(sinh)
-add_subdirectory(sprintf)
+add_subdirectory(sinhf)
+add_subdirectory(sprintf_s)
add_subdirectory(sqrt)
-add_subdirectory(sscanf)
+add_subdirectory(sqrtf)
+add_subdirectory(sscanf_s)
add_subdirectory(strcat)
add_subdirectory(strchr)
add_subdirectory(strcmp)
@@ -94,7 +109,9 @@ add_subdirectory(strtoul)
add_subdirectory(swprintf)
add_subdirectory(swscanf)
add_subdirectory(tan)
+add_subdirectory(tanf)
add_subdirectory(tanh)
+add_subdirectory(tanhf)
add_subdirectory(time)
add_subdirectory(tolower)
add_subdirectory(toupper)
@@ -125,6 +142,7 @@ add_subdirectory(_alloca)
add_subdirectory(_ecvt)
add_subdirectory(_fdopen)
add_subdirectory(_finite)
+add_subdirectory(_finitef)
add_subdirectory(_fullpath)
# TODO: make this test compile
@@ -132,31 +150,26 @@ add_subdirectory(_fullpath)
add_subdirectory(_getw)
add_subdirectory(_isnan)
+add_subdirectory(_isnanf)
add_subdirectory(_itow)
-add_subdirectory(_makepath)
add_subdirectory(_mbsdec)
add_subdirectory(_mbsinc)
-add_subdirectory(_mbslen)
add_subdirectory(_mbsninc)
add_subdirectory(_open_osfhandle)
add_subdirectory(_putenv)
add_subdirectory(_putw)
add_subdirectory(_rotl)
add_subdirectory(_rotr)
-add_subdirectory(_snprintf)
-add_subdirectory(_snwprintf)
-add_subdirectory(_splitpath)
+add_subdirectory(_snprintf_s)
+add_subdirectory(_snwprintf_s)
add_subdirectory(_stricmp)
add_subdirectory(_strlwr)
add_subdirectory(_strnicmp)
-add_subdirectory(_swab)
add_subdirectory(_vsnprintf)
-add_subdirectory(_vsnwprintf)
+add_subdirectory(_vsnwprintf_s)
add_subdirectory(_wcsicmp)
add_subdirectory(_wcslwr)
add_subdirectory(_wcsnicmp)
add_subdirectory(_wfopen)
-add_subdirectory(_wmakepath)
-add_subdirectory(_wsplitpath)
add_subdirectory(_wtoi)
add_subdirectory(__iscsym)
diff --git a/src/pal/tests/palsuite/c_runtime/__iscsym/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/__iscsym/test1/CMakeLists.txt
index a283161f7d..b4421e77a1 100644
--- a/src/pal/tests/palsuite/c_runtime/__iscsym/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/__iscsym/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- __iscsym.c
+ __iscsym.cpp
)
add_executable(paltest_iscsym_test1
diff --git a/src/pal/tests/palsuite/c_runtime/__iscsym/test1/__iscsym.c b/src/pal/tests/palsuite/c_runtime/__iscsym/test1/__iscsym.cpp
index 9c8f1d0f25..9c8f1d0f25 100644
--- a/src/pal/tests/palsuite/c_runtime/__iscsym/test1/__iscsym.c
+++ b/src/pal/tests/palsuite/c_runtime/__iscsym/test1/__iscsym.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_alloca/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_alloca/test1/CMakeLists.txt
index 236b356185..434633be20 100644
--- a/src/pal/tests/palsuite/c_runtime/_alloca/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_alloca/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_alloca_test1
diff --git a/src/pal/tests/palsuite/c_runtime/_alloca/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_alloca/test1/test1.cpp
index c533d84234..c533d84234 100644
--- a/src/pal/tests/palsuite/c_runtime/_alloca/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/_alloca/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_ecvt/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_ecvt/test1/CMakeLists.txt
index 86f4547b2b..e78a802723 100644
--- a/src/pal/tests/palsuite/c_runtime/_ecvt/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_ecvt/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_ecvt_test1
diff --git a/src/pal/tests/palsuite/c_runtime/_ecvt/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_ecvt/test1/test1.cpp
index fbcf11ecfc..fbcf11ecfc 100644
--- a/src/pal/tests/palsuite/c_runtime/_ecvt/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/_ecvt/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_fdopen/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_fdopen/test1/CMakeLists.txt
index 441d32bd5c..60b036f44d 100644
--- a/src/pal/tests/palsuite/c_runtime/_fdopen/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_fdopen/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_fdopen_test1
diff --git a/src/pal/tests/palsuite/c_runtime/_fdopen/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_fdopen/test1/test1.cpp
index b88267c6e4..b88267c6e4 100644
--- a/src/pal/tests/palsuite/c_runtime/_fdopen/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/_fdopen/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_finite/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_finite/test1/CMakeLists.txt
index 8aca58a8dc..ac2f25d85a 100644
--- a/src/pal/tests/palsuite/c_runtime/_finite/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_finite/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_finite_test1
diff --git a/src/pal/tests/palsuite/c_runtime/_finite/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_finite/test1/test1.cpp
index c815055b38..c815055b38 100644
--- a/src/pal/tests/palsuite/c_runtime/_finite/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/_finite/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_finitef/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_finitef/CMakeLists.txt
new file mode 100644
index 0000000000..5e1ef7f28b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_finitef/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/_finitef/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_finitef/test1/CMakeLists.txt
new file mode 100644
index 0000000000..9ef630fbb2
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_finitef/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.c
+)
+
+add_executable(paltest_finitef_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_finitef_test1 coreclrpal)
+
+target_link_libraries(paltest_finitef_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_finitef/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_finitef/test1/test1.c
new file mode 100644
index 0000000000..f9a1109a66
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_finitef/test1/test1.c
@@ -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.
+
+/*============================================================================
+**
+** Source: test1.c
+**
+** Purpose: Checks that _finitef correctly classifies all types
+** of floating point numbers (NaN, -Infinity, Infinity,
+** finite nonzero, unnormalized, 0, and -0)
+**
+**==========================================================================*/
+
+#include <palsuite.h>
+
+/*
+The IEEE single precision floating point standard looks like this:
+
+ S EEEEEEEE FFFFFFFFFFFFFFFFFFFFFFF
+ 0 1 8 9 31
+
+S is the sign bit. The E bits are the exponent, and the 23 F bits are
+the fraction. These represent a value, V.
+
+If E=255 and F is nonzero, then V=NaN ("Not a number")
+If E=255 and F is zero and S is 1, then V=-Infinity
+If E=255 and F is zero and S is 0, then V=Infinity
+If 0<E<255 then V=(-1)^S * 2^(E-1028) * (1.F) where "1.F" is the binary
+ number created by prefixing F with a leading 1 and a binary point.
+If E=0 and F is nonzero, then V=(-1)^S * 2^(-127) * (0.F) These are
+ "unnormalized" values.
+If E=0 and F is zero and S is 1, then V=-0
+If E=0 and F is zero and S is 0, then V=0
+
+*/
+
+#define TO_FLOAT(x) (*((float*)((void*)&x)))
+
+int __cdecl main(int argc, char **argv)
+{
+ /*non-finite numbers*/
+ UINT32 lsnan = 0xffffffffu;
+ UINT32 lqnan = 0x7fffffffu;
+ UINT32 lneginf = 0xff800000u;
+ UINT32 lposinf = 0x7f800000u;
+
+ float snan = TO_FLOAT(lsnan);
+ float qnan = TO_FLOAT(lqnan);
+ float neginf = TO_FLOAT(lneginf);
+ float posinf = TO_FLOAT(lposinf);
+
+ /*finite numbers*/
+ UINT32 lnegunnormalized = 0x807fffffu;
+ UINT32 lposunnormalized = 0x007fffffu;
+ UINT32 lnegzero = 0x80000000u;
+
+ float negunnormalized = TO_FLOAT(lnegunnormalized);
+ float posunnormalized = TO_FLOAT(lposunnormalized);
+ float negzero = TO_FLOAT(lnegzero);
+
+ /*
+ * Initialize the PAL and return FAIL if this fails
+ */
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ /*non-finite numbers*/
+ if (_finitef(snan) || _finitef(qnan))
+ {
+ Fail("_finitef() found NAN to be finite.\n");
+ }
+
+ if (_finitef(neginf))
+ {
+ Fail("_finitef() found negative infinity to be finite.\n");
+ }
+
+ if (_finitef(posinf))
+ {
+ Fail("_finitef() found infinity to be finite.\n");
+ }
+
+ /*finite numbers*/
+ if (!_finitef(negunnormalized))
+ {
+ Fail("_finitef() found a negative unnormalized value to be infinite.\n");
+ }
+
+ if (!_finitef(posunnormalized))
+ {
+ Fail("_finitef() found an unnormalized value to be infinite.\n");
+ }
+
+ if (!_finitef(negzero))
+ {
+ Fail("_finitef() found negative zero to be infinite.\n");
+ }
+
+ if (!_finitef(+0.0f))
+ {
+ Fail("_finitef() found zero to be infinite.\n");
+ }
+
+ if (!_finitef(-123.456f))
+ {
+ Fail("_finitef() found %f to be infinite.\n", -123.456f);
+ }
+
+ if (!_finitef(+123.456f))
+ {
+ Fail("_finitef() found %f to be infinite.\n", +123.456f);
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_finitef/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_finitef/test1/testinfo.dat
new file mode 100644
index 0000000000..b0767431e5
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_finitef/test1/testinfo.dat
@@ -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.
+
+Version = 1.0
+Section = C Runtime
+Function = _finitef
+Name = Positive Test for _finitef
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Checks that _finitef correctly classifies all types of floating point
+= numbers (NaN, -Infinity, Infinity, finite nonzero, unnormalized, 0, and -0).
diff --git a/src/pal/tests/palsuite/c_runtime/_fullpath/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_fullpath/test1/CMakeLists.txt
index 9306efa700..0c9029f6e2 100644
--- a/src/pal/tests/palsuite/c_runtime/_fullpath/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_fullpath/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_fullpath_test1
diff --git a/src/pal/tests/palsuite/c_runtime/_fullpath/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_fullpath/test1/test1.cpp
index f390f4309b..f390f4309b 100644
--- a/src/pal/tests/palsuite/c_runtime/_fullpath/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/_fullpath/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_gcvt/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_gcvt/test1/CMakeLists.txt
index 33eb5cf19c..47dcb95754 100644
--- a/src/pal/tests/palsuite/c_runtime/_gcvt/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_gcvt/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- _gcvt.c
+ _gcvt.cpp
)
add_executable(paltest_gcvt_test1
diff --git a/src/pal/tests/palsuite/c_runtime/_gcvt/test1/_gcvt.c b/src/pal/tests/palsuite/c_runtime/_gcvt/test1/_gcvt.cpp
index ccfc286898..ccfc286898 100644
--- a/src/pal/tests/palsuite/c_runtime/_gcvt/test1/_gcvt.c
+++ b/src/pal/tests/palsuite/c_runtime/_gcvt/test1/_gcvt.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_gcvt/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_gcvt/test2/CMakeLists.txt
index 05641b9b78..5b0f5608f3 100644
--- a/src/pal/tests/palsuite/c_runtime/_gcvt/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_gcvt/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_gcvt_test2
diff --git a/src/pal/tests/palsuite/c_runtime/_gcvt/test2/test2.c b/src/pal/tests/palsuite/c_runtime/_gcvt/test2/test2.cpp
index 7ac9a4fcf0..7ac9a4fcf0 100644
--- a/src/pal/tests/palsuite/c_runtime/_gcvt/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/_gcvt/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_getw/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_getw/test1/CMakeLists.txt
index d44477b232..4f763bed6b 100644
--- a/src/pal/tests/palsuite/c_runtime/_getw/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_getw/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_getw_test1
diff --git a/src/pal/tests/palsuite/c_runtime/_getw/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_getw/test1/test1.cpp
index 34ce4ee7de..34ce4ee7de 100644
--- a/src/pal/tests/palsuite/c_runtime/_getw/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/_getw/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_isnan/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_isnan/test1/CMakeLists.txt
index e14d0cc64b..106ccb93d7 100644
--- a/src/pal/tests/palsuite/c_runtime/_isnan/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_isnan/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_isnan_test1
diff --git a/src/pal/tests/palsuite/c_runtime/_isnan/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_isnan/test1/test1.cpp
index d793c9b371..d793c9b371 100644
--- a/src/pal/tests/palsuite/c_runtime/_isnan/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/_isnan/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_isnanf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_isnanf/CMakeLists.txt
new file mode 100644
index 0000000000..5e1ef7f28b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_isnanf/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/_isnanf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_isnanf/test1/CMakeLists.txt
new file mode 100644
index 0000000000..a8d42aa975
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_isnanf/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.c
+)
+
+add_executable(paltest_isnanf_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_isnanf_test1 coreclrpal)
+
+target_link_libraries(paltest_isnanf_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_isnanf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_isnanf/test1/test1.c
new file mode 100644
index 0000000000..9b75a7236d
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_isnanf/test1/test1.c
@@ -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.
+
+/*============================================================================
+**
+** Source: test1.c
+**
+** Purpose:
+** Test _isnanf with a number of trivial values, to ensure they indicated that
+** they are numbers. Then try with Positive/Negative Infinite, which should
+** also be numbers. Finally set the least and most significant bits of
+** the fraction to positive and negative, at which point it should return
+** the true value.
+**
+**==========================================================================*/
+
+#include <palsuite.h>
+
+#define TO_FLOAT(x) (*((float*)((void*)&x)))
+#define TO_I32(x) (*((INT32*)((void*)&x)))
+
+/*
+ * NaN: any float with maximum exponent (0x7f8) and non-zero fraction
+ */
+int __cdecl main(int argc, char *argv[])
+{
+ /*
+ * Initialize the PAL and return FAIL if this fails
+ */
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ /*
+ * Try some trivial values
+ */
+ if (_isnanf(0.0f))
+ {
+ Fail("_isnanf() incorrectly identified %f as NaN!\n", 0.0f);
+ }
+
+ if (_isnanf(1.234567f))
+ {
+ Fail("_isnanf() incorrectly identified %f as NaN!\n", 1.234567f);
+ }
+
+ if (_isnanf(42.0f))
+ {
+ Fail("_isnanf() incorrectly identified %f as NaN!\n", 42.0f);
+ }
+
+ UINT32 lneginf = 0xff800000u;
+ UINT32 lposinf = 0x7f800000u;
+
+ float neginf = TO_FLOAT(lneginf);
+ float posinf = TO_FLOAT(lposinf);
+
+ /*
+ * Try positive and negative infinity
+ */
+ if (_isnanf(neginf))
+ {
+ Fail("_isnanf() incorrectly identified negative infinity as NaN!\n");
+ }
+
+ if (_isnanf(posinf))
+ {
+ Fail("_isnanf() incorrectly identified infinity as NaN!\n");
+ }
+
+ /*
+ * Try setting the least significant bit of the fraction,
+ * positive and negative
+ */
+ UINT32 lsnan = 0xff800001u;
+ float snan = TO_FLOAT(lsnan);
+
+ if (!_isnanf(snan))
+ {
+ Fail("_isnanf() failed to identify %I32x as NaN!\n", lsnan);
+ }
+
+ UINT32 lqnan = 0x7f800001u;
+ float qnan = TO_FLOAT(lqnan);
+
+ if (!_isnanf(qnan))
+ {
+ Fail("_isnanf() failed to identify %I32x as NaN!\n", lqnan);
+ }
+
+ /*
+ * Try setting the most significant bit of the fraction,
+ * positive and negative
+ */
+ lsnan = 0xffc00000u;
+ snan = TO_FLOAT(lsnan);
+
+ if (!_isnanf(snan))
+ {
+ Fail ("_isnanf() failed to identify %I32x as NaN!\n", lsnan);
+ }
+
+ lqnan = 0x7fc00000u;
+ qnan = TO_FLOAT(lqnan);
+
+ if (!_isnanf(qnan))
+ {
+ Fail ("_isnanf() failed to identify %I32x as NaN!\n", lqnan);
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_isnanf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_isnanf/test1/testinfo.dat
new file mode 100644
index 0000000000..22b0edbd74
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_isnanf/test1/testinfo.dat
@@ -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.
+
+Version = 1.0
+Section = C Runtime
+Function = _isnanf
+Name = Test #1 for _isnanf
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Test _isnanf with a number of trivial values, to ensure they indicated that
+= they are numbers. Then try with Positive/Negative Infinite, which should
+= also be numbers. Finally set the least and most significant bits of
+= the fraction to positive and negative, at which point it should return
+= the true value.
diff --git a/src/pal/tests/palsuite/c_runtime/_itow/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_itow/test1/CMakeLists.txt
index bd37f31216..2c5d57bd34 100644
--- a/src/pal/tests/palsuite/c_runtime/_itow/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_itow/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_itow_test1
diff --git a/src/pal/tests/palsuite/c_runtime/_itow/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_itow/test1/test1.c
deleted file mode 100644
index 745ce4acaa..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_itow/test1/test1.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: test1.c
-**
-** Purpose: Tests the PAL implementation of the _itow function.
-** Test a number of ints with different radix on each,
-** to ensure that the string returned is correct.
-**
-**
-**===================================================================*/
-
-#define UNICODE
-
-#include <palsuite.h>
-
-struct testCase
-{
- wchar_t *CorrectResult;
- int value;
- int radix;
-};
-
-int __cdecl main(int argc, char **argv)
-{
-
- wchar_t result[20];
- wchar_t *pResult = NULL;
- char *PrintResult = NULL; /* Use with convertC so we can */
- char *PrintCorrectResult = NULL; /* print out the results */
- int i = 0;
-
- WCHAR case1[] = {'5','0','\0'};
- WCHAR case2[] = {'5','5','5','\0'};
- WCHAR case3[] = {'1','0','1','0','\0'};
- WCHAR case4[] = {'2','2','\0'};
- WCHAR case5[] = {'a','\0'};
- WCHAR case6[] = {'c','g','\0'};
-
- /* Correct Result, Value to Convert, Radix to use */
- struct testCase testCases[] =
- {
- {case1, 50, 10},
- {case2,555,10},
- {case3,10,2},
- {case4,10,4},
- {case5,10,16},
- {case6,400,32}
- };
-
- /*
- * Initialize the PAL and return FAIL if this fails
- */
- if (0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- /* Loop through each case. Convert the ints to strings. Check
- to ensure they were converted properly.
- */
-
- for(i = 0; i < sizeof(testCases) / sizeof(struct testCase); i++)
- {
- pResult = _itow(testCases[i].value,result,testCases[i].radix);
-
- if(pResult != &result[0])
- {
- Fail("ERROR: _itow didn't return a correct pointer to the "
- "newly formed string.\n");
- }
-
- if (0 != wcscmp(testCases[i].CorrectResult,pResult))
- {
- PrintResult = convertC(pResult);
- PrintCorrectResult = convertC(testCases[i].CorrectResult);
- Fail("ERROR: _itow was called on %i, returning the string %s "
- "when it should have returned the string %s.\n"
- , testCases[i].value, PrintResult, PrintCorrectResult);
- }
-
- }
-
- PAL_Terminate();
- return PASS;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/pal/tests/palsuite/c_runtime/_itow/test1/test1.cpp b/src/pal/tests/palsuite/c_runtime/_itow/test1/test1.cpp
new file mode 100644
index 0000000000..01f32f2520
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_itow/test1/test1.cpp
@@ -0,0 +1,101 @@
+// Licensed to the .NET Foundation under one or more 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: test1.c
+**
+** Purpose: Tests the PAL implementation of the _itow_s function.
+** Test a number of ints with different radix on each,
+** to ensure that the string returned is correct.
+**
+**
+**===================================================================*/
+
+#define UNICODE
+
+#include <palsuite.h>
+
+struct testCase
+{
+ wchar_t *CorrectResult;
+ int value;
+ int radix;
+};
+
+int __cdecl main(int argc, char **argv)
+{
+
+ wchar_t result[20];
+ wchar_t *pResult = NULL;
+ char *PrintResult = NULL; /* Use with convertC so we can */
+ char *PrintCorrectResult = NULL; /* print out the results */
+ int i = 0;
+
+ WCHAR case1[] = {'5','0','\0'};
+ WCHAR case2[] = {'5','5','5','\0'};
+ WCHAR case3[] = {'1','0','1','0','\0'};
+ WCHAR case4[] = {'2','2','\0'};
+ WCHAR case5[] = {'a','\0'};
+ WCHAR case6[] = {'c','g','\0'};
+
+ /* Correct Result, Value to Convert, Radix to use */
+ struct testCase testCases[] =
+ {
+ {case1, 50, 10},
+ {case2,555,10},
+ {case3,10,2},
+ {case4,10,4},
+ {case5,10,16},
+ {case6,400,32}
+ };
+
+ /*
+ * Initialize the PAL and return FAIL if this fails
+ */
+ if (0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ /* Loop through each case. Convert the ints to strings. Check
+ to ensure they were converted properly.
+ */
+
+ for(i = 0; i < sizeof(testCases) / sizeof(struct testCase); i++)
+ {
+ errno_t err = _itow_s(testCases[i].value, result, sizeof(result) / sizeof(result[0]), testCases[i].radix);
+
+ if(err != 0)
+ {
+ Fail("ERROR: _itow_s didn't return success, error code %d.\n", err);
+ }
+
+ if (0 != wcscmp(testCases[i].CorrectResult, result))
+ {
+ PrintResult = convertC(pResult);
+ PrintCorrectResult = convertC(testCases[i].CorrectResult);
+ Fail("ERROR: _itow_s was called on %i, returning the string %s "
+ "when it should have returned the string %s.\n"
+ , testCases[i].value, PrintResult, PrintCorrectResult);
+ }
+
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pal/tests/palsuite/c_runtime/_itow/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_itow/test1/testinfo.dat
index 394c34dff3..91f0e62e09 100644
--- a/src/pal/tests/palsuite/c_runtime/_itow/test1/testinfo.dat
+++ b/src/pal/tests/palsuite/c_runtime/_itow/test1/testinfo.dat
@@ -4,12 +4,12 @@
Version = 1.0
Section = C Runtime
-Function = _itow
-Name = Positive Test for _itow
+Function = _itow_s
+Name = Positive Test for _itow_s
TYPE = DEFAULT
EXE1 = test1
Description
-= Tests the PAL implementation of the _itow function.
+= Tests the PAL implementation of the _itow_s function.
= Test a number of ints with different radix on each, to ensure that the
= string returned is correct.
diff --git a/src/pal/tests/palsuite/c_runtime/_makepath/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_makepath/test1/CMakeLists.txt
deleted file mode 100644
index 9fd81cce1a..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_makepath/test1/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test1.c
-)
-
-add_executable(paltest_makepath_test1
- ${SOURCES}
-)
-
-add_dependencies(paltest_makepath_test1 coreclrpal)
-
-target_link_libraries(paltest_makepath_test1
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_makepath/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_makepath/test1/test1.c
deleted file mode 100644
index 94b366a7bb..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_makepath/test1/test1.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: test1.c
-**
-** Purpose: Tests the PAL implementation of the _makepath function.
-** Create a path, and ensure that it builds how it is
-** supposed to.
-**
-**
-**
-**===================================================================*/
-
-#if WIN32
-#define PATHNAME "C:\\test\\test.txt"
-#else
-#define PATHNAME "/test/test.txt"
-#endif
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char **argv)
-{
- char FullPath[128];
-
- /*
- * Initialize the PAL and return FAIL if this fails
- */
- if (0 != (PAL_Initialize(argc,argv)))
- {
- return FAIL;
- }
-
-#if WIN32
- _makepath(FullPath,"C","\\test","test","txt");
-#else
- _makepath(FullPath,NULL,"/test","test","txt");
-#endif
-
- if(strcmp(FullPath,PATHNAME) != 0)
- {
- Fail("ERROR: The pathname which was created turned out to be %s "
- "when it was supposed to be %s.\n",FullPath,PATHNAME);
- }
-
-
- PAL_Terminate();
- return PASS;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/pal/tests/palsuite/c_runtime/_makepath/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_makepath/test1/testinfo.dat
deleted file mode 100644
index 2aed8e549b..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_makepath/test1/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _makepath
-Name = Positive Test for _makepath
-TYPE = DEFAULT
-EXE1 = test1
-Description
-= Purpose: Tests the PAL implementation of the _makepath function.
-= Create a path, and ensure that it builds how it is supposed to.
-
diff --git a/src/pal/tests/palsuite/c_runtime/_mbsdec/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_mbsdec/test1/CMakeLists.txt
index 064f241f24..b016f27982 100644
--- a/src/pal/tests/palsuite/c_runtime/_mbsdec/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_mbsdec/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_mbsdec_test1
diff --git a/src/pal/tests/palsuite/c_runtime/_mbsdec/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_mbsdec/test1/test1.cpp
index 1cd7513293..1cd7513293 100644
--- a/src/pal/tests/palsuite/c_runtime/_mbsdec/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/_mbsdec/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_mbsinc/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_mbsinc/test1/CMakeLists.txt
index 531ba8e793..c7325b9513 100644
--- a/src/pal/tests/palsuite/c_runtime/_mbsinc/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_mbsinc/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_mbsinc_test1
diff --git a/src/pal/tests/palsuite/c_runtime/_mbsinc/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_mbsinc/test1/test1.cpp
index 95a5041af2..95a5041af2 100644
--- a/src/pal/tests/palsuite/c_runtime/_mbsinc/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/_mbsinc/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_mbslen/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_mbslen/CMakeLists.txt
deleted file mode 100644
index f6aa0cb2d9..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_mbslen/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-add_subdirectory(test1)
-
diff --git a/src/pal/tests/palsuite/c_runtime/_mbslen/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_mbslen/test1/CMakeLists.txt
deleted file mode 100644
index 38aa6fb16e..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_mbslen/test1/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test1.c
-)
-
-add_executable(paltest_mbslen_test1
- ${SOURCES}
-)
-
-add_dependencies(paltest_mbslen_test1 coreclrpal)
-
-target_link_libraries(paltest_mbslen_test1
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_mbslen/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_mbslen/test1/test1.c
deleted file mode 100644
index fa24c77d8a..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_mbslen/test1/test1.c
+++ /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.
-
-/*========================================================================
-**
-** Source: test1.c
-**
-** Purpose:
-** Check the length of a number of arrays. The first is a normal string
-** which should return its length. The second has two bytes and a null
-** character, which only returns a size of 2, and the last is just a NULL
-** array which should return 0.
-**
-**
-**========================================================================*/
-
-#include <palsuite.h>
-
-/*
- * Note: it seems like these functions would only be useful if they
- * didn't assume a character was equivalent to a single byte. Be that
- * as it may, I haven't seen a way to get it to behave otherwise
- * (eg locale)
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- unsigned char *str1 = (unsigned char*) "foo";
- unsigned char str2[] = {0xC0, 0x80, 0}; /* the char U+0080 */
- unsigned char str3[] = {0};
- int ret=0;
-
- /*
- * Initialize the PAL and return FAIL if this fails
- */
- if (0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- ret = _mbslen(str1);
- if (ret != 3)
- {
- Fail ("ERROR: _mbslen(\"%s\") returned %d. Expected %d\n",
- str1, ret, 3);
- }
-
- ret = _mbslen(str2);
- if (ret != 2)
- {
- Fail ("ERROR: _mbslen(\"%s\") returned %d. Expected %d\n",
- str2, ret, 2);
- }
-
- ret = _mbslen(str3);
- if (ret != 0)
- {
- Fail ("ERROR: _mbslen(\"%s\") returned %d. Expected %d\n",
- str3, ret, 0);
- }
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/_mbslen/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_mbslen/test1/testinfo.dat
deleted file mode 100644
index cf830a7539..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_mbslen/test1/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _mbsinc
-Name = Positive Test for _mbslen
-TYPE = DEFAULT
-EXE1 = test1
-Description
-= Check the length of a number of arrays. The first is a normal string
-= which should return its length. The second has two bytes and a null
-= character, which only returns a size of 2, and the last is just a NULL
-= array which should return 0.
diff --git a/src/pal/tests/palsuite/c_runtime/_mbsninc/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_mbsninc/test1/CMakeLists.txt
index 7285ce229e..81c6c23a53 100644
--- a/src/pal/tests/palsuite/c_runtime/_mbsninc/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_mbsninc/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_mbsninc_test1
diff --git a/src/pal/tests/palsuite/c_runtime/_mbsninc/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_mbsninc/test1/test1.cpp
index 59ef50dcc3..59ef50dcc3 100644
--- a/src/pal/tests/palsuite/c_runtime/_mbsninc/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/_mbsninc/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_open_osfhandle/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_open_osfhandle/test1/CMakeLists.txt
index e9a3e29192..f4fedb61ae 100644
--- a/src/pal/tests/palsuite/c_runtime/_open_osfhandle/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_open_osfhandle/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_open_osfhandle_test1
diff --git a/src/pal/tests/palsuite/c_runtime/_open_osfhandle/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_open_osfhandle/test1/test1.cpp
index ee2c8ea418..ee2c8ea418 100644
--- a/src/pal/tests/palsuite/c_runtime/_open_osfhandle/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/_open_osfhandle/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_open_osfhandle/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_open_osfhandle/test2/CMakeLists.txt
index 1031ec1df9..6086868de2 100644
--- a/src/pal/tests/palsuite/c_runtime/_open_osfhandle/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_open_osfhandle/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_open_osfhandle_test2
diff --git a/src/pal/tests/palsuite/c_runtime/_open_osfhandle/test2/test2.c b/src/pal/tests/palsuite/c_runtime/_open_osfhandle/test2/test2.cpp
index 6c756b177a..6c756b177a 100644
--- a/src/pal/tests/palsuite/c_runtime/_open_osfhandle/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/_open_osfhandle/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_putenv/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_putenv/test1/CMakeLists.txt
index 0a75b41113..9096bc1033 100644
--- a/src/pal/tests/palsuite/c_runtime/_putenv/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_putenv/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_putenv_test1
diff --git a/src/pal/tests/palsuite/c_runtime/_putenv/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_putenv/test1/test1.cpp
index 2d096adc78..2d096adc78 100644
--- a/src/pal/tests/palsuite/c_runtime/_putenv/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/_putenv/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_putenv/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_putenv/test2/CMakeLists.txt
index e0539681cd..ad99eba373 100644
--- a/src/pal/tests/palsuite/c_runtime/_putenv/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_putenv/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_putenv_test2
diff --git a/src/pal/tests/palsuite/c_runtime/_putenv/test2/test2.c b/src/pal/tests/palsuite/c_runtime/_putenv/test2/test2.cpp
index 39be4f68b4..39be4f68b4 100644
--- a/src/pal/tests/palsuite/c_runtime/_putenv/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/_putenv/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_putenv/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_putenv/test3/CMakeLists.txt
index a67241022b..fc97b951b3 100644
--- a/src/pal/tests/palsuite/c_runtime/_putenv/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_putenv/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_putenv_test3
diff --git a/src/pal/tests/palsuite/c_runtime/_putenv/test3/test3.c b/src/pal/tests/palsuite/c_runtime/_putenv/test3/test3.cpp
index 8aa6777307..8aa6777307 100644
--- a/src/pal/tests/palsuite/c_runtime/_putenv/test3/test3.c
+++ b/src/pal/tests/palsuite/c_runtime/_putenv/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_putenv/test4/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_putenv/test4/CMakeLists.txt
index 518282ccc7..3881626d01 100644
--- a/src/pal/tests/palsuite/c_runtime/_putenv/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_putenv/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_putenv_test4
diff --git a/src/pal/tests/palsuite/c_runtime/_putenv/test4/test4.c b/src/pal/tests/palsuite/c_runtime/_putenv/test4/test4.cpp
index 48d7ba963c..48d7ba963c 100644
--- a/src/pal/tests/palsuite/c_runtime/_putenv/test4/test4.c
+++ b/src/pal/tests/palsuite/c_runtime/_putenv/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_putw/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_putw/test1/CMakeLists.txt
index c3018ad322..78833d4e13 100644
--- a/src/pal/tests/palsuite/c_runtime/_putw/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_putw/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_putw_test1
diff --git a/src/pal/tests/palsuite/c_runtime/_putw/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_putw/test1/test1.c
deleted file mode 100644
index ecfc9046ac..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_putw/test1/test1.c
+++ /dev/null
@@ -1,112 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: test1.c
-**
-** Purpose: Writes a series of integers to a file, test.dat,
-** then verifies the results.
-**
-** Dependency: fopen(...)
-** fclose(...)
-** CloseHandle(...)
-** DeleteFileA(...)
-** _getw(...)
-**
-**
-**
-**==========================================================================*/
-
-
-#include <palsuite.h>
-
-const char testFileName[] = "test.dat";
-
-static void Cleanup(HANDLE hFile)
-{
- if (fclose(hFile))
- {
- Trace("_putw: ERROR -> Unable to close file \"%s\".\n",
- testFileName);
- }
- if (!DeleteFileA(testFileName))
- {
- Trace("_putw: ERROR -> Unable to delete file \"%s\". ",
- "GetLastError returned %u.\n",
- testFileName,
- GetLastError());
- }
-}
-
-
-int __cdecl main(int argc, char **argv)
-{
-
- FILE * pfTest = NULL;
- int testArray[] = {0,1,-1,0x7FFFFFFF,0x80000000,0xFFFFFFFF,0xFFFFAAAA};
- int i = 0;
- int retValue = 0;
-
- /*
- * Initialize the PAL and return FAIL if this fails
- */
- if (0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- /*write the file that we will use to test */
- pfTest = fopen(testFileName, "w");
- if (pfTest == NULL)
- {
- Fail ("Unable to write test file.\n");
- }
-
- for (i = 0; i < sizeof(testArray)/sizeof(int) ; i++)
- {
- _putw(testArray[i], pfTest);
-
- if( ferror( pfTest ) )
- {
- Cleanup(pfTest);
- Fail( "Error:in _putw -> error has occurred in the "
- "stream while writing to the file: \"test.dat\"\n");
- }
-
- }
-
- if (fclose(pfTest) != 0)
- {
- Cleanup(pfTest);
- Fail ("Error closing file after writing with _putw(..).\n");
- }
-
- /*open the new test file and compare*/
- pfTest = fopen(testFileName, "r");
- if (pfTest == NULL)
- {
- Fail ("Error opening \"%s\", which is odd, since I just finished "
- "creating that file.\n", testFileName);
- }
- retValue =_getw( pfTest );
- i = 0;
- while(retValue != EOF)
- {
- if(retValue != testArray[i])
- {
- Cleanup(pfTest);
- Fail ("Integers written by _putw are not in the correct format\n",
- testFileName);
- }
- retValue = _getw( pfTest );
- i++ ;
- }
-
- Cleanup(pfTest);
- PAL_Terminate();
- return PASS;
-}
-
-
diff --git a/src/pal/tests/palsuite/c_runtime/_putw/test1/test1.cpp b/src/pal/tests/palsuite/c_runtime/_putw/test1/test1.cpp
new file mode 100644
index 0000000000..02b7cc7a49
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_putw/test1/test1.cpp
@@ -0,0 +1,112 @@
+// Licensed to the .NET Foundation under one or more 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: test1.c
+**
+** Purpose: Writes a series of integers to a file, test.dat,
+** then verifies the results.
+**
+** Dependency: fopen(...)
+** fclose(...)
+** CloseHandle(...)
+** DeleteFileA(...)
+** _getw(...)
+**
+**
+**
+**==========================================================================*/
+
+
+#include <palsuite.h>
+
+const char testFileName[] = "test.dat";
+
+static void Cleanup(HANDLE hFile)
+{
+ if (fclose((PAL_FILE*)hFile))
+ {
+ Trace("_putw: ERROR -> Unable to close file \"%s\".\n",
+ testFileName);
+ }
+ if (!DeleteFileA(testFileName))
+ {
+ Trace("_putw: ERROR -> Unable to delete file \"%s\". ",
+ "GetLastError returned %u.\n",
+ testFileName,
+ GetLastError());
+ }
+}
+
+
+int __cdecl main(int argc, char **argv)
+{
+
+ FILE * pfTest = NULL;
+ int testArray[] = {0,1,-1,0x7FFFFFFF,0x80000000,0xFFFFFFFF,0xFFFFAAAA};
+ int i = 0;
+ int retValue = 0;
+
+ /*
+ * Initialize the PAL and return FAIL if this fails
+ */
+ if (0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ /*write the file that we will use to test */
+ pfTest = fopen(testFileName, "w");
+ if (pfTest == NULL)
+ {
+ Fail ("Unable to write test file.\n");
+ }
+
+ for (i = 0; i < sizeof(testArray)/sizeof(int) ; i++)
+ {
+ _putw(testArray[i], pfTest);
+
+ if( ferror( pfTest ) )
+ {
+ Cleanup(pfTest);
+ Fail( "Error:in _putw -> error has occurred in the "
+ "stream while writing to the file: \"test.dat\"\n");
+ }
+
+ }
+
+ if (fclose(pfTest) != 0)
+ {
+ Cleanup(pfTest);
+ Fail ("Error closing file after writing with _putw(..).\n");
+ }
+
+ /*open the new test file and compare*/
+ pfTest = fopen(testFileName, "r");
+ if (pfTest == NULL)
+ {
+ Fail ("Error opening \"%s\", which is odd, since I just finished "
+ "creating that file.\n", testFileName);
+ }
+ retValue =_getw( pfTest );
+ i = 0;
+ while(retValue != EOF)
+ {
+ if(retValue != testArray[i])
+ {
+ Cleanup(pfTest);
+ Fail ("Integers written by _putw are not in the correct format\n",
+ testFileName);
+ }
+ retValue = _getw( pfTest );
+ i++ ;
+ }
+
+ Cleanup(pfTest);
+ PAL_Terminate();
+ return PASS;
+}
+
+
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf/CMakeLists.txt
deleted file mode 100644
index cafb9536b0..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/CMakeLists.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-add_subdirectory(test1)
-add_subdirectory(test10)
-add_subdirectory(test11)
-add_subdirectory(test12)
-add_subdirectory(test13)
-add_subdirectory(test14)
-add_subdirectory(test15)
-add_subdirectory(test16)
-add_subdirectory(test17)
-add_subdirectory(test18)
-add_subdirectory(test19)
-add_subdirectory(test2)
-add_subdirectory(test3)
-add_subdirectory(test4)
-add_subdirectory(test5)
-add_subdirectory(test6)
-add_subdirectory(test7)
-add_subdirectory(test8)
-add_subdirectory(test9)
-
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/_snprintf.h b/src/pal/tests/palsuite/c_runtime/_snprintf/_snprintf.h
deleted file mode 100644
index 84abf62f0b..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/_snprintf.h
+++ /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.
-
-/*============================================================================
-**
-** Source: _snprintf.h
-**
-** Purpose: Containts common testing functions for _snprintf
-**
-**
-**==========================================================================*/
-
-#ifndef __STRINGTEST_H__
-#define __STRINGTEST_H__
-
-void DoStrTest(char *formatstr, char* param, char *checkstr)
-{
- char buf[256] = { 0 };
-
- _snprintf(buf, 256, formatstr, param);
- if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
- {
- Fail("ERROR: failed to insert string \"%s\" into \"%s\"\n"
- "Expected \"%s\" got \"%s\".\n",
- param, formatstr, checkstr, buf);
- }
-}
-
-void DoWStrTest(char *formatstr, WCHAR* param, char *checkstr)
-{
- char buf[256] = { 0 };
-
- _snprintf(buf, 256, formatstr, param);
- if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
- {
- Fail("ERROR: failed to insert wide string \"%s\" into \"%s\"\n"
- "Expected \"%s\" got \"%s\".\n",
- convertC(param), formatstr, checkstr, buf);
- }
-}
-
-
-void DoPointerTest(char *formatstr, void* param, char* paramstr, char
- *checkstr1)
-{
- char buf[256] = { 0 };
-
- _snprintf(buf, 256, formatstr, param);
- if (memcmp(buf, checkstr1, strlen(checkstr1) + 1) != 0)
- {
- Fail("ERROR: failed to insert %s into \"%s\"\n"
- "Expected \"%s\", got \"%s\".\n",
- paramstr, formatstr, checkstr1, buf);
- }
-}
-
-void DoCountTest(char *formatstr, int param, char *checkstr)
-{
- char buf[512] = { 0 };
- int n = -1;
-
- _snprintf(buf, 512, formatstr, &n);
-
- if (n != param)
- {
- Fail("ERROR: Expected count parameter to resolve to %d, got %X\n",
- param, n);
- }
- if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
- {
- Fail("ERROR: Expected \"%s\" got \"%s\".\n", checkstr, buf);
- }
-}
-
-void DoShortCountTest(char *formatstr, int param, char *checkstr)
-{
- char buf[256] = { 0 };
- short int n = -1;
-
- _snprintf(buf, 256, formatstr, &n);
-
- if (n != param)
- {
- Fail("ERROR: Expected count parameter to resolve to %d, got %X\n",
- param, n);
- }
- if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
- {
- Fail("ERROR: Expected \"%s\" got \"%s\".\n", checkstr, buf);
- }
-}
-
-void DoCharTest(char *formatstr, char param, char *checkstr)
-{
- char buf[256] = { 0 };
-
- _snprintf(buf, 256, formatstr, param);
- if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
- {
- Fail("ERROR: failed to insert char \'%c\' (%d) into \"%s\"\n"
- "Expected \"%s\" got \"%s\".\n",
- param, param, formatstr, checkstr, buf);
- }
-}
-
-void DoWCharTest(char *formatstr, WCHAR param, char *checkstr)
-{
- char buf[256] = { 0 };
-
- _snprintf(buf, 256, formatstr, param);
- if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
- {
- Fail("ERROR: failed to insert wide char \'%c\' (%d) into \"%s\"\n"
- "Expected \"%s\" got \"%s\".\n",
- (char)param, param, formatstr, checkstr, buf);
- }
-}
-
-void DoNumTest(char *formatstr, int value, char *checkstr)
-{
- char buf[256] = { 0 };
-
- _snprintf(buf, 256, formatstr, value);
- if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
- {
- Fail("ERROR: failed to insert %#x into \"%s\"\n"
- "Expected \"%s\" got \"%s\".\n",
- value, formatstr, checkstr, buf);
- }
-}
-
-void DoI64Test(char *formatstr, INT64 value, char *valuestr, char *checkstr1)
-{
- char buf[256] = { 0 };
-
- _snprintf(buf, 256, formatstr, value);
- if (memcmp(buf, checkstr1, strlen(checkstr1) + 1) != 0)
- {
- Fail("ERROR: failed to insert %s into \"%s\"\n"
- "Expected \"%s\", got \"%s\".\n",
- valuestr, formatstr, checkstr1, buf);
- }
-}
-
-void DoDoubleTest(char *formatstr, double value, char *checkstr1, char
-*checkstr2)
-{
- char buf[256] = { 0 };
-
- _snprintf(buf, 256, formatstr, value);
- if (memcmp(buf, checkstr1, strlen(checkstr1) + 1) != 0
- && memcmp(buf, checkstr2, strlen(checkstr2) + 1) != 0)
- {
- Fail("ERROR: failed to insert %f into \"%s\"\n"
- "Expected \"%s\" or \"%s\", got \"%s\".\n",
- value, formatstr, checkstr1, checkstr2, buf);
- }
-}
-
-void DoArgumentPrecTest(char *formatstr, int precision, void *param, char
-*paramstr, char *checkstr1, char*checkstr2)
-{
- char buf[256];
-
- _snprintf(buf, 256, formatstr, precision, param);
- if (memcmp(buf, checkstr1, strlen(checkstr1) + 1) != 0 &&
- memcmp(buf, checkstr2, strlen(checkstr2) + 1) != 0)
- {
- Fail("ERROR: failed to insert %s into \"%s\" with precision %d\n"
- "Expected \"%s\" or \"%s\", got \"%s\".\n",
- paramstr, formatstr, precision, checkstr1, checkstr2, buf);
- }
-
-}
-
-void DoArgumentPrecDoubleTest(char *formatstr, int precision, double param,
-char *checkstr1, char *checkstr2)
-{
- char buf[256];
-
- _snprintf(buf, 256, formatstr, precision, param);
- if (memcmp(buf, checkstr1, strlen(checkstr1) + 1) != 0 &&
- memcmp(buf, checkstr2, strlen(checkstr2) + 1) != 0)
- {
- Fail("ERROR: failed to insert %f into \"%s\" with precision %d\n"
- "Expected \"%s\" or \"%s\", got \"%s\".\n",
- param, formatstr, precision, checkstr1, checkstr2, buf);
- }
-
-}
-
-#endif
-
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf/test1/CMakeLists.txt
deleted file mode 100644
index ab126fc59d..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test1/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test1.c
-)
-
-add_executable(paltest_snprintf_test1
- ${SOURCES}
-)
-
-add_dependencies(paltest_snprintf_test1 coreclrpal)
-
-target_link_libraries(paltest_snprintf_test1
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_snprintf/test1/test1.c
deleted file mode 100644
index eef7406baa..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test1/test1.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test1.c
-**
-** Purpose: General test to see if _snprintf works correctly
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snprintf.h"
-
-/*
- * Notes: memcmp is used, as is strlen.
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- char checkstr[] = "hello world";
- char buf[256] = { 0 };
- int ret;
-
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- _snprintf(buf, 256, "hello world");
- if (memcmp(checkstr, buf, strlen(checkstr)+1) != 0)
- {
- Fail("ERROR: expected \"%s\" (up to %d chars), got \"%s\"\n",
- checkstr, 256, buf);
- }
-
- _snprintf(buf, 256, "xxxxxxxxxxxxxxxxx");
- ret = _snprintf(buf, 8, "hello world");
-
- if (ret >= 0)
- {
- Fail("ERROR: expected negative return value, got %d", ret);
- }
- if (memcmp(checkstr, buf, 8) != 0 || buf[8] != 'x')
- {
- Fail("ERROR: expected %s (up to %d chars), got %s\n",
- checkstr, 8, buf);
- }
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf/test1/testinfo.dat
deleted file mode 100644
index c15ce1dcba..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test1/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snprintf
-Name = Positive Test for _snprintf
-TYPE = DEFAULT
-EXE1 = test1
-Description
-= General test to see if _snprintf works correctly
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test10/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf/test10/CMakeLists.txt
deleted file mode 100644
index e8e9308849..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test10/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test10.c
-)
-
-add_executable(paltest_snprintf_test10
- ${SOURCES}
-)
-
-add_dependencies(paltest_snprintf_test10 coreclrpal)
-
-target_link_libraries(paltest_snprintf_test10
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test10/test10.c b/src/pal/tests/palsuite/c_runtime/_snprintf/test10/test10.c
deleted file mode 100644
index 9191ccef27..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test10/test10.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test10.c
-**
-** Purpose: Tests _snprintf with octal numbers
-**
-**
-**==========================================================================*/
-
-
-
-
-#include <palsuite.h>
-#include "../_snprintf.h"
-
-/*
- * Notes: memcmp is used, as is strlen.
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- int neg = -42;
- int pos = 42;
- INT64 l = 42;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoNumTest("foo %o", pos, "foo 52");
- DoNumTest("foo %lo", 0xFFFF, "foo 177777");
- DoNumTest("foo %ho", 0xFFFF, "foo 177777");
- DoNumTest("foo %Lo", pos, "foo 52");
- DoI64Test("foo %I64o", l, "42", "foo 52");
- DoNumTest("foo %3o", pos, "foo 52");
- DoNumTest("foo %-3o", pos, "foo 52 ");
- DoNumTest("foo %.1o", pos, "foo 52");
- DoNumTest("foo %.3o", pos, "foo 052");
- DoNumTest("foo %03o", pos, "foo 052");
- DoNumTest("foo %#o", pos, "foo 052");
- DoNumTest("foo %+o", pos, "foo 52");
- DoNumTest("foo % o", pos, "foo 52");
- DoNumTest("foo %+o", neg, "foo 37777777726");
- DoNumTest("foo % o", neg, "foo 37777777726");
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test10/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf/test10/testinfo.dat
deleted file mode 100644
index 44ff48e030..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test10/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snprintf
-Name = Positive Test for _snprintf
-TYPE = DEFAULT
-EXE1 = test10
-Description
-= Tests _snprintf with octal numbers
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test11/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf/test11/CMakeLists.txt
deleted file mode 100644
index ccf3dc2572..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test11/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test11.c
-)
-
-add_executable(paltest_snprintf_test11
- ${SOURCES}
-)
-
-add_dependencies(paltest_snprintf_test11 coreclrpal)
-
-target_link_libraries(paltest_snprintf_test11
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test11/test11.c b/src/pal/tests/palsuite/c_runtime/_snprintf/test11/test11.c
deleted file mode 100644
index 9d9302dee0..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test11/test11.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test11.c
-**
-** Purpose: Tests _snprintf with unsigned numbers
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snprintf.h"
-
-/*
- * Notes: memcmp is used, as is strlen.
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- int neg = -42;
- int pos = 42;
- INT64 l = 42;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoNumTest("foo %u", pos, "foo 42");
- DoNumTest("foo %lu", 0xFFFF, "foo 65535");
- DoNumTest("foo %hu", 0xFFFF, "foo 65535");
- DoNumTest("foo %Lu", pos, "foo 42");
- DoI64Test("foo %I64u", l, "42", "foo 42");
- DoNumTest("foo %3u", pos, "foo 42");
- DoNumTest("foo %-3u", pos, "foo 42 ");
- DoNumTest("foo %.1u", pos, "foo 42");
- DoNumTest("foo %.3u", pos, "foo 042");
- DoNumTest("foo %03u", pos, "foo 042");
- DoNumTest("foo %#u", pos, "foo 42");
- DoNumTest("foo %+u", pos, "foo 42");
- DoNumTest("foo % u", pos, "foo 42");
- DoNumTest("foo %+u", neg, "foo 4294967254");
- DoNumTest("foo % u", neg, "foo 4294967254");
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test11/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf/test11/testinfo.dat
deleted file mode 100644
index 1a77077950..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test11/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snprintf
-Name = Positive Test for _snprintf
-TYPE = DEFAULT
-EXE1 = test11
-Description
-= Tests _snprintf with unsigned numbers
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test12/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf/test12/CMakeLists.txt
deleted file mode 100644
index 68b442f1d9..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test12/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test12.c
-)
-
-add_executable(paltest_snprintf_test12
- ${SOURCES}
-)
-
-add_dependencies(paltest_snprintf_test12 coreclrpal)
-
-target_link_libraries(paltest_snprintf_test12
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test12/test12.c b/src/pal/tests/palsuite/c_runtime/_snprintf/test12/test12.c
deleted file mode 100644
index d782fce788..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test12/test12.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test12.c
-**
-** Purpose: Tests _snprintf with hex numbers (lowercase)
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snprintf.h"
-
-/*
- * Notes: memcmp is used, as is strlen.
- */
-
-
-int __cdecl main(int argc, char *argv[])
-{
- int neg = -42;
- int pos = 0x1234ab;
- INT64 l = I64(0x1234567887654321);
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoNumTest("foo %x", pos, "foo 1234ab");
- DoNumTest("foo %lx", pos, "foo 1234ab");
- DoNumTest("foo %hx", pos, "foo 34ab");
- DoNumTest("foo %Lx", pos, "foo 1234ab");
- DoI64Test("foo %I64x", l, "0x1234567887654321", "foo 1234567887654321");
- DoNumTest("foo %7x", pos, "foo 1234ab");
- DoNumTest("foo %-7x", pos, "foo 1234ab ");
- DoNumTest("foo %.1x", pos, "foo 1234ab");
- DoNumTest("foo %.7x", pos, "foo 01234ab");
- DoNumTest("foo %07x", pos, "foo 01234ab");
- DoNumTest("foo %#x", pos, "foo 0x1234ab");
- DoNumTest("foo %+x", pos, "foo 1234ab");
- DoNumTest("foo % x", pos, "foo 1234ab");
- DoNumTest("foo %+x", neg, "foo ffffffd6");
- DoNumTest("foo % x", neg, "foo ffffffd6");
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test12/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf/test12/testinfo.dat
deleted file mode 100644
index 6801c7417e..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test12/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snprintf
-Name = Positive Test for _snprintf
-TYPE = DEFAULT
-EXE1 = test12
-Description
-= Tests _snprintf with hex numbers (lowercase)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test13/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf/test13/CMakeLists.txt
deleted file mode 100644
index 832b3fefbf..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test13/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test13.c
-)
-
-add_executable(paltest_snprintf_test13
- ${SOURCES}
-)
-
-add_dependencies(paltest_snprintf_test13 coreclrpal)
-
-target_link_libraries(paltest_snprintf_test13
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test13/test13.c b/src/pal/tests/palsuite/c_runtime/_snprintf/test13/test13.c
deleted file mode 100644
index 68ba554d93..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test13/test13.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test13.c
-**
-** Purpose: Tests _snprintf with hex numbers (uppercase)
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snprintf.h"
-
-/*
- * Notes: memcmp is used, as is strlen.
- */
-
-
-int __cdecl main(int argc, char *argv[])
-{
- int neg = -42;
- int pos = 0x1234AB;
- INT64 l = I64(0x1234567887654321);
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoNumTest("foo %X", pos, "foo 1234AB");
- DoNumTest("foo %lX", pos, "foo 1234AB");
- DoNumTest("foo %hX", pos, "foo 34AB");
- DoNumTest("foo %LX", pos, "foo 1234AB");
- DoI64Test("foo %I64X", l, "0x1234567887654321", "foo 1234567887654321");
- DoNumTest("foo %7X", pos, "foo 1234AB");
- DoNumTest("foo %-7X", pos, "foo 1234AB ");
- DoNumTest("foo %.1X", pos, "foo 1234AB");
- DoNumTest("foo %.7X", pos, "foo 01234AB");
- DoNumTest("foo %07X", pos, "foo 01234AB");
- DoNumTest("foo %#X", pos, "foo 0X1234AB");
- DoNumTest("foo %+X", pos, "foo 1234AB");
- DoNumTest("foo % X", pos, "foo 1234AB");
- DoNumTest("foo %+X", neg, "foo FFFFFFD6");
- DoNumTest("foo % X", neg, "foo FFFFFFD6");
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test13/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf/test13/testinfo.dat
deleted file mode 100644
index 6901589a1b..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test13/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snprintf
-Name = Positive Test for _snprintf
-TYPE = DEFAULT
-EXE1 = test13
-Description
-= Tests _snprintf with hex numbers (uppercase)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test14/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf/test14/CMakeLists.txt
deleted file mode 100644
index c2e3be148d..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test14/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test14.c
-)
-
-add_executable(paltest_snprintf_test14
- ${SOURCES}
-)
-
-add_dependencies(paltest_snprintf_test14 coreclrpal)
-
-target_link_libraries(paltest_snprintf_test14
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test14/test14.c b/src/pal/tests/palsuite/c_runtime/_snprintf/test14/test14.c
deleted file mode 100644
index d874690ba4..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test14/test14.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test14.c
-**
-** Purpose: Tests _snprintf with exponential format doubles (lowercase)
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snprintf.h"
-
-/*
- * Notes: memcmp is used, as is strlen.
- */
-
-
-int __cdecl main(int argc, char *argv[])
-{
- double val = 256.0;
- double neg = -256.0;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoDoubleTest("foo %e", val, "foo 2.560000e+002", "foo 2.560000e+02");
- DoDoubleTest("foo %le", val, "foo 2.560000e+002", "foo 2.560000e+02");
- DoDoubleTest("foo %he", val, "foo 2.560000e+002", "foo 2.560000e+02");
- DoDoubleTest("foo %Le", val, "foo 2.560000e+002", "foo 2.560000e+02");
- DoDoubleTest("foo %I64e", val, "foo 2.560000e+002", "foo 2.560000e+02");
- DoDoubleTest("foo %14e", val, "foo 2.560000e+002",
- "foo 2.560000e+02");
- DoDoubleTest("foo %-14e", val, "foo 2.560000e+002 ",
- "foo 2.560000e+02 ");
- DoDoubleTest("foo %.1e", val, "foo 2.6e+002", "foo 2.6e+02");
- DoDoubleTest("foo %.8e", val, "foo 2.56000000e+002",
- "foo 2.56000000e+02");
- DoDoubleTest("foo %014e", val, "foo 02.560000e+002",
- "foo 002.560000e+02");
- DoDoubleTest("foo %#e", val, "foo 2.560000e+002", "foo 2.560000e+02");
- DoDoubleTest("foo %+e", val, "foo +2.560000e+002", "foo +2.560000e+02");
- DoDoubleTest("foo % e", val, "foo 2.560000e+002", "foo 2.560000e+02");
- DoDoubleTest("foo %+e", neg, "foo -2.560000e+002", "foo -2.560000e+02");
- DoDoubleTest("foo % e", neg, "foo -2.560000e+002", "foo -2.560000e+02");
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test14/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf/test14/testinfo.dat
deleted file mode 100644
index 0f32b9b59a..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test14/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snprintf
-Name = Positive Test for _snprintf
-TYPE = DEFAULT
-EXE1 = test14
-Description
-= Tests _snprintf with exponential format doubles (lowercase)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test15/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf/test15/CMakeLists.txt
deleted file mode 100644
index 1bd24d5ccd..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test15/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test15.c
-)
-
-add_executable(paltest_snprintf_test15
- ${SOURCES}
-)
-
-add_dependencies(paltest_snprintf_test15 coreclrpal)
-
-target_link_libraries(paltest_snprintf_test15
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test15/test15.c b/src/pal/tests/palsuite/c_runtime/_snprintf/test15/test15.c
deleted file mode 100644
index a637a706f5..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test15/test15.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test15.c
-**
-** Purpose: Tests _snprintf with exponential format doubles (uppercase)
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snprintf.h"
-
-/*
- * Notes: memcmp is used, as is strlen.
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- double val = 256.0;
- double neg = -256.0;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoDoubleTest("foo %E", val, "foo 2.560000E+002", "foo 2.560000E+02");
- DoDoubleTest("foo %lE", val, "foo 2.560000E+002", "foo 2.560000E+02");
- DoDoubleTest("foo %hE", val, "foo 2.560000E+002", "foo 2.560000E+02");
- DoDoubleTest("foo %LE", val, "foo 2.560000E+002", "foo 2.560000E+02");
- DoDoubleTest("foo %I64E", val, "foo 2.560000E+002", "foo 2.560000E+02");
- DoDoubleTest("foo %14E", val, "foo 2.560000E+002",
- "foo 2.560000E+02");
- DoDoubleTest("foo %-14E", val, "foo 2.560000E+002 ",
- "foo 2.560000E+02 ");
- DoDoubleTest("foo %.1E", val, "foo 2.6E+002", "foo 2.6E+02");
- DoDoubleTest("foo %.8E", val, "foo 2.56000000E+002",
- "foo 2.56000000E+02");
- DoDoubleTest("foo %014E", val, "foo 02.560000E+002",
- "foo 002.560000E+02");
- DoDoubleTest("foo %#E", val, "foo 2.560000E+002", "foo 2.560000E+02");
- DoDoubleTest("foo %+E", val, "foo +2.560000E+002", "foo +2.560000E+02");
- DoDoubleTest("foo % E", val, "foo 2.560000E+002", "foo 2.560000E+02");
- DoDoubleTest("foo %+E", neg, "foo -2.560000E+002", "foo -2.560000E+02");
- DoDoubleTest("foo % E", neg, "foo -2.560000E+002", "foo -2.560000E+02");
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test15/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf/test15/testinfo.dat
deleted file mode 100644
index 8008cff0b5..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test15/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snprintf
-Name = Positive Test for _snprintf
-TYPE = DEFAULT
-EXE1 = test15
-Description
-= Tests _snprintf with exponential format doubles (uppercase)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test16/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf/test16/CMakeLists.txt
deleted file mode 100644
index 952192e560..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test16/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test16.c
-)
-
-add_executable(paltest_snprintf_test16
- ${SOURCES}
-)
-
-add_dependencies(paltest_snprintf_test16 coreclrpal)
-
-target_link_libraries(paltest_snprintf_test16
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test16/test16.c b/src/pal/tests/palsuite/c_runtime/_snprintf/test16/test16.c
deleted file mode 100644
index 6793019383..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test16/test16.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test16.c
-**
-** Purpose: Test #15 for the _snprintf function
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snprintf.h"
-
-/*
- * Notes: memcmp is used, as is strlen.
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- double val = 2560.001;
- double neg = -2560.001;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoDoubleTest("foo %f", val, "foo 2560.001000", "foo 2560.001000");
- DoDoubleTest("foo %lf", val, "foo 2560.001000", "foo 2560.001000");
- DoDoubleTest("foo %hf", val, "foo 2560.001000", "foo 2560.001000");
- DoDoubleTest("foo %Lf", val, "foo 2560.001000", "foo 2560.001000");
- DoDoubleTest("foo %I64f", val, "foo 2560.001000", "foo 2560.001000");
- DoDoubleTest("foo %12f", val, "foo 2560.001000", "foo 2560.001000");
- DoDoubleTest("foo %-12f", val, "foo 2560.001000 ", "foo 2560.001000 ");
- DoDoubleTest("foo %.1f", val, "foo 2560.0", "foo 2560.0");
- DoDoubleTest("foo %.8f", val, "foo 2560.00100000", "foo 2560.00100000");
- DoDoubleTest("foo %012f", val, "foo 02560.001000", "foo 02560.001000");
- DoDoubleTest("foo %#f", val, "foo 2560.001000", "foo 2560.001000");
- DoDoubleTest("foo %+f", val, "foo +2560.001000", "foo +2560.001000");
- DoDoubleTest("foo % f", val, "foo 2560.001000", "foo 2560.001000");
- DoDoubleTest("foo %+f", neg, "foo -2560.001000", "foo -2560.001000");
- DoDoubleTest("foo % f", neg, "foo -2560.001000", "foo -2560.001000");
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test16/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf/test16/testinfo.dat
deleted file mode 100644
index e7a7df8f53..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test16/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snprintf
-Name = Positive Test for _snprintf
-TYPE = DEFAULT
-EXE1 = test16
-Description
-= Tests _snprintf with decimal point format doubles
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test17/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf/test17/CMakeLists.txt
deleted file mode 100644
index ce5cc1623e..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test17/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test17.c
-)
-
-add_executable(paltest_snprintf_test17
- ${SOURCES}
-)
-
-add_dependencies(paltest_snprintf_test17 coreclrpal)
-
-target_link_libraries(paltest_snprintf_test17
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test17/test17.c b/src/pal/tests/palsuite/c_runtime/_snprintf/test17/test17.c
deleted file mode 100644
index 9981b44619..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test17/test17.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test17.c
-**
-** Purpose: Tests _snprintf with compact format doubles (lowercase)
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snprintf.h"
-
-/*
- * Notes: memcmp is used, as is strlen.
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- double val = 2560.001;
- double neg = -2560.001;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoDoubleTest("foo %g", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %lg", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %hg", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %Lg", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %I64g", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %5g", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %-5g", val, "foo 2560 ", "foo 2560 ");
- DoDoubleTest("foo %.1g", val, "foo 3e+003", "foo 3e+03");
- DoDoubleTest("foo %.2g", val, "foo 2.6e+003", "foo 2.6e+03");
- DoDoubleTest("foo %.12g", val, "foo 2560.001", "foo 2560.001");
- DoDoubleTest("foo %06g", val, "foo 002560", "foo 002560");
- DoDoubleTest("foo %#g", val, "foo 2560.00", "foo 2560.00");
- DoDoubleTest("foo %+g", val, "foo +2560", "foo +2560");
- DoDoubleTest("foo % g", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %+g", neg, "foo -2560", "foo -2560");
- DoDoubleTest("foo % g", neg, "foo -2560", "foo -2560");
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test17/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf/test17/testinfo.dat
deleted file mode 100644
index 4756bd0d78..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test17/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snprintf
-Name = Positive Test for _snprintf
-TYPE = DEFAULT
-EXE1 = test17
-Description
-= Tests _snprintf with compact format doubles (lowercase)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test18/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf/test18/CMakeLists.txt
deleted file mode 100644
index bb9c9c37cc..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test18/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test18.c
-)
-
-add_executable(paltest_snprintf_test18
- ${SOURCES}
-)
-
-add_dependencies(paltest_snprintf_test18 coreclrpal)
-
-target_link_libraries(paltest_snprintf_test18
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test18/test18.c b/src/pal/tests/palsuite/c_runtime/_snprintf/test18/test18.c
deleted file mode 100644
index d28aec57d0..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test18/test18.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test18.c
-**
-** Purpose: Tests _snprintf with compact format doubles (uppercase)
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snprintf.h"
-
-/*
- * Notes: memcmp is used, as is strlen.
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- double val = 2560.001;
- double neg = -2560.001;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoDoubleTest("foo %G", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %lG", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %hG", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %LG", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %I64G", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %5G", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %-5G", val, "foo 2560 ", "foo 2560 ");
- DoDoubleTest("foo %.1G", val, "foo 3E+003", "foo 3E+03");
- DoDoubleTest("foo %.2G", val, "foo 2.6E+003", "foo 2.6E+03");
- DoDoubleTest("foo %.12G", val, "foo 2560.001", "foo 2560.001");
- DoDoubleTest("foo %06G", val, "foo 002560", "foo 002560");
- DoDoubleTest("foo %#G", val, "foo 2560.00", "foo 2560.00");
- DoDoubleTest("foo %+G", val, "foo +2560", "foo +2560");
- DoDoubleTest("foo % G", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %+G", neg, "foo -2560", "foo -2560");
- DoDoubleTest("foo % G", neg, "foo -2560", "foo -2560");
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test18/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf/test18/testinfo.dat
deleted file mode 100644
index 819d28cec9..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test18/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snprintf
-Name = Positive Test for _snprintf
-TYPE = DEFAULT
-EXE1 = test18
-Description
-= Tests _snprintf with compact format doubles (uppercase)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test19/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf/test19/CMakeLists.txt
deleted file mode 100644
index f3fbb95013..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test19/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test19.c
-)
-
-add_executable(paltest_snprintf_test19
- ${SOURCES}
-)
-
-add_dependencies(paltest_snprintf_test19 coreclrpal)
-
-target_link_libraries(paltest_snprintf_test19
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test19/test19.c b/src/pal/tests/palsuite/c_runtime/_snprintf/test19/test19.c
deleted file mode 100644
index 26dffd9214..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test19/test19.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test19.c
-**
-** Purpose:Tests _snprintf with argument specified precision
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snprintf.h"
-
-/*
- * Notes: memcmp is used, as is strlen.
- */
-
-
-int __cdecl main(int argc, char *argv[])
-{
- int n = -1;
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
- DoArgumentPrecTest("%.*s", 2, "bar", "bar", "ba", "ba");
- DoArgumentPrecTest("%.*S", 2, convert("bar"), "bar", "ba", "ba");
- DoArgumentPrecTest("%.*n", 3, &n, "pointer to int", "", "");
- if (n != 0)
- {
- Fail("ERROR: Expected count parameter to resolve to %d, got %X\n",
- 0, n);
- }
-
- DoArgumentPrecTest("%.*c", 0, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*c", 4, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*C", 0, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*C", 4, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*d", 1, (void*)42, "42", "42", "42");
- DoArgumentPrecTest("%.*d", 3, (void*)42, "42", "042", "042");
- DoArgumentPrecTest("%.*i", 1, (void*)42, "42", "42", "42");
- DoArgumentPrecTest("%.*i", 3, (void*)42, "42", "042", "042");
- DoArgumentPrecTest("%.*o", 1, (void*)42, "42", "52", "52");
- DoArgumentPrecTest("%.*o", 3, (void*)42, "42", "052", "052");
- DoArgumentPrecTest("%.*u", 1, (void*)42, "42", "42", "42");
- DoArgumentPrecTest("%.*u", 3, (void*)42, "42", "042", "042");
- DoArgumentPrecTest("%.*x", 1, (void*)0x42, "0x42", "42", "42");
- DoArgumentPrecTest("%.*x", 3, (void*)0x42, "0x42", "042", "042");
- DoArgumentPrecTest("%.*X", 1, (void*)0x42, "0x42", "42", "42") ;
- DoArgumentPrecTest("%.*X", 3, (void*)0x42, "0x42", "042", "042");
-
-
- DoArgumentPrecDoubleTest("%.*e", 1, 2.01, "2.0e+000", "2.0e+00");
- DoArgumentPrecDoubleTest("%.*e", 3, 2.01, "2.010e+000", "2.010e+00");
- DoArgumentPrecDoubleTest("%.*E", 1, 2.01, "2.0E+000", "2.0E+00");
- DoArgumentPrecDoubleTest("%.*E", 3, 2.01, "2.010E+000", "2.010E+00");
- DoArgumentPrecDoubleTest("%.*f", 1, 2.01, "2.0", "2.0");
- DoArgumentPrecDoubleTest("%.*f", 3, 2.01, "2.010", "2.010");
- DoArgumentPrecDoubleTest("%.*g", 1, 256.01, "3e+002", "3e+02");
- DoArgumentPrecDoubleTest("%.*g", 3, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*g", 4, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*g", 6, 256.01, "256.01", "256.01");
- DoArgumentPrecDoubleTest("%.*G", 1, 256.01, "3E+002", "3E+02");
- DoArgumentPrecDoubleTest("%.*G", 3, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*G", 4, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*G", 6, 256.01, "256.01", "256.01");
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test19/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf/test19/testinfo.dat
deleted file mode 100644
index 875abf7071..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test19/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snprintf
-Name = Positive Test for _snprintf
-TYPE = DEFAULT
-EXE1 = test19
-Description
-= Tests _snprintf with argument specified precision
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf/test2/CMakeLists.txt
deleted file mode 100644
index 8c617df108..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test2/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test2.c
-)
-
-add_executable(paltest_snprintf_test2
- ${SOURCES}
-)
-
-add_dependencies(paltest_snprintf_test2 coreclrpal)
-
-target_link_libraries(paltest_snprintf_test2
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test2/test2.c b/src/pal/tests/palsuite/c_runtime/_snprintf/test2/test2.c
deleted file mode 100644
index 3ccb66c23e..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test2/test2.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test2.c
-**
-** Purpose:Tests _snprintf with strings
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snprintf.h"
-/*
- * Notes: memcmp is used, as is strlen.
- */
-
-int __cdecl main(int argc, char *argv[])
-{
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
- DoStrTest("foo %s", "bar", "foo bar");
- DoStrTest("foo %hs", "bar", "foo bar");
- DoWStrTest("foo %ls", convert("bar"), "foo bar");
- DoWStrTest("foo %ws", convert("bar"), "foo bar");
- DoStrTest("foo %Ls", "bar", "foo bar");
- DoStrTest("foo %I64s", "bar", "foo bar");
- DoStrTest("foo %5s", "bar", "foo bar");
- DoStrTest("foo %.2s", "bar", "foo ba");
- DoStrTest("foo %5.2s", "bar", "foo ba");
- DoStrTest("foo %-5s", "bar", "foo bar ");
- DoStrTest("foo %05s", "bar", "foo 00bar");
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test2/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf/test2/testinfo.dat
deleted file mode 100644
index 40a1ede3d5..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test2/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snprintf
-Name = Positive Test for _snprintf
-TYPE = DEFAULT
-EXE1 = test2
-Description
-= Tests _snprintf with strings
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf/test3/CMakeLists.txt
deleted file mode 100644
index 13330464a7..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test3/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test3.c
-)
-
-add_executable(paltest_snprintf_test3
- ${SOURCES}
-)
-
-add_dependencies(paltest_snprintf_test3 coreclrpal)
-
-target_link_libraries(paltest_snprintf_test3
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test3/test3.c b/src/pal/tests/palsuite/c_runtime/_snprintf/test3/test3.c
deleted file mode 100644
index 496159c51e..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test3/test3.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test3.c
-**
-** Purpose: Tests _snprintf with wide strings
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snprintf.h"
-
-/*
- * Notes: memcmp is used, as is strlen.
- */
-
-int __cdecl main(int argc, char *argv[])
-{
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
- DoWStrTest("foo %S", convert("bar"), "foo bar");
- DoStrTest("foo %hS", "bar", "foo bar");
- DoWStrTest("foo %lS", convert("bar"), "foo bar");
- DoWStrTest("foo %wS", convert("bar"), "foo bar");
- DoWStrTest("foo %LS", convert("bar"), "foo bar");
- DoWStrTest("foo %I64S", convert("bar"), "foo bar");
- DoWStrTest("foo %5S", convert("bar"), "foo bar");
- DoWStrTest("foo %.2S", convert("bar"), "foo ba");
- DoWStrTest("foo %5.2S", convert("bar"), "foo ba");
- DoWStrTest("foo %-5S", convert("bar"), "foo bar ");
- DoWStrTest("foo %05S", convert("bar"), "foo 00bar");
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test3/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf/test3/testinfo.dat
deleted file mode 100644
index fa53224510..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test3/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snprintf
-Name = Positive Test for _snprintf
-TYPE = DEFAULT
-EXE1 = test3
-Description
-= Tests _snprintf with wide strings
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test4/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf/test4/CMakeLists.txt
deleted file mode 100644
index 5132aa02de..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test4/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test4.c
-)
-
-add_executable(paltest_snprintf_test4
- ${SOURCES}
-)
-
-add_dependencies(paltest_snprintf_test4 coreclrpal)
-
-target_link_libraries(paltest_snprintf_test4
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test4/test4.c b/src/pal/tests/palsuite/c_runtime/_snprintf/test4/test4.c
deleted file mode 100644
index 8c39f222cc..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test4/test4.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test4.c
-**
-** Purpose: Tests _snprintf with pointers
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snprintf.h"
-
-/*
- * Notes: memcmp is used, as is strlen.
- */
-
-
-int __cdecl main(int argc, char *argv[])
-{
- void *ptr = (void*) 0x123456;
- INT64 lptr = I64(0x1234567887654321);
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
- /*
- ** Run only on 64 bit platforms
- */
- #if defined(BIT64) && defined(PLATFORM_UNIX)
- Trace("Testing for 64 Bit Platforms \n");
- DoPointerTest("%p", NULL, "NULL", "0000000000000000");
- DoPointerTest("%p", ptr, "pointer to 0x123456", "0000000000123456");
- DoPointerTest("%17p", ptr, "pointer to 0x123456", " 0000000000123456");
- DoPointerTest("%17p", ptr, "pointer to 0x123456", " 0000000000123456");
- DoPointerTest("%-17p", ptr, "pointer to 0x123456", "0000000000123456 ");
- DoPointerTest("%+p", ptr, "pointer to 0x123456", "0000000000123456");
- DoPointerTest("%#p", ptr, "pointer to 0x123456", "0X0000000000123456");
- DoPointerTest("%lp", ptr, "pointer to 0x123456", "00123456");
- DoPointerTest("%hp", ptr, "pointer to 0x123456", "00003456");
- DoPointerTest("%Lp", ptr, "pointer to 0x123456", "00123456");
- DoI64Test("%I64p", lptr, "pointer to 0x1234567887654321",
- "1234567887654321");
- #else
- Trace("Testing for Non 64 Bit Platforms \n");
- DoPointerTest("%p", NULL, "NULL", "00000000");
- DoPointerTest("%p", ptr, "pointer to 0x123456", "00123456");
- DoPointerTest("%9p", ptr, "pointer to 0x123456", " 00123456");
- DoPointerTest("%09p", ptr, "pointer to 0x123456", " 00123456");
- DoPointerTest("%-9p", ptr, "pointer to 0x123456", "00123456 ");
- DoPointerTest("%+p", ptr, "pointer to 0x123456", "00123456");
- DoPointerTest("%#p", ptr, "pointer to 0x123456", "0X00123456");
- DoPointerTest("%lp", ptr, "pointer to 0x123456", "00123456");
- DoPointerTest("%hp", ptr, "pointer to 0x123456", "00003456");
- DoPointerTest("%Lp", ptr, "pointer to 0x123456", "00123456");
- DoI64Test("%I64p", lptr, "pointer to 0x1234567887654321",
- "1234567887654321");
- #endif //defined(BIT64) && defined(PLATFORM_UNIX)
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test4/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf/test4/testinfo.dat
deleted file mode 100644
index 5d822d160b..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test4/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snprintf
-Name = Positive Test for _snprintf
-TYPE = DEFAULT
-EXE1 = test4
-Description
-= Tests _snprintf with pointers
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test5/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf/test5/CMakeLists.txt
deleted file mode 100644
index 07e441cee0..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test5/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test5.c
-)
-
-add_executable(paltest_snprintf_test5
- ${SOURCES}
-)
-
-add_dependencies(paltest_snprintf_test5 coreclrpal)
-
-target_link_libraries(paltest_snprintf_test5
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test5/test5.c b/src/pal/tests/palsuite/c_runtime/_snprintf/test5/test5.c
deleted file mode 100644
index 46ab1dd35e..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test5/test5.c
+++ /dev/null
@@ -1,61 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: test5.c
-**
-** Purpose: Tests _snprintf with the count specifier
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snprintf.h"
-
-/*
- * Notes: memcmp is used, as is strlen.
- */
-
-
-int __cdecl main(int argc, char *argv[])
-{
- char *longStr =
- "really-long-string-that-just-keeps-going-on-and-on-and-on.."
- "..................useless-filler.................................."
- "..................useless-filler.................................."
- "..................useless-filler.................................."
- "%n bar";
- char *longResult =
- "really-long-string-that-just-keeps-going-on-and-on-and-on.."
- "..................useless-filler.................................."
- "..................useless-filler.................................."
- "..................useless-filler.................................."
- " bar";
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
- DoCountTest("foo %n bar", 4, "foo bar");
- DoCountTest(longStr, 257, longResult);
- DoCountTest("fo%n bar", 2, "fo bar");
- DoCountTest("%n", 0, "");
- DoCountTest("foo %#n bar", 4, "foo bar");
- DoCountTest("foo % n bar", 4, "foo bar");
- DoCountTest("foo %+n bar", 4, "foo bar");
- DoCountTest("foo %-n bar", 4, "foo bar");
- DoCountTest("foo %0n bar", 4, "foo bar");
- DoShortCountTest("foo %hn bar", 4, "foo bar");
- DoCountTest("foo %ln bar", 4, "foo bar");
- DoCountTest("foo %Ln bar", 4, "foo bar");
- DoCountTest("foo %I64n bar", 4, "foo bar");
- DoCountTest("foo %20.3n bar", 4, "foo bar");
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test5/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf/test5/testinfo.dat
deleted file mode 100644
index 33056defd8..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test5/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snprintf
-Name = Positive Test for _snprintf
-TYPE = DEFAULT
-EXE1 = test5
-Description
-= Tests _snprintf with the count specifier
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test6/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf/test6/CMakeLists.txt
deleted file mode 100644
index 9ee5d90544..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test6/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test6.c
-)
-
-add_executable(paltest_snprintf_test6
- ${SOURCES}
-)
-
-add_dependencies(paltest_snprintf_test6 coreclrpal)
-
-target_link_libraries(paltest_snprintf_test6
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test6/test6.c b/src/pal/tests/palsuite/c_runtime/_snprintf/test6/test6.c
deleted file mode 100644
index 32001c2d20..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test6/test6.c
+++ /dev/null
@@ -1,47 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: test6.c
-**
-** Purpose: Tests _snprintf with characters
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snprintf.h"
-
-/*
- * Notes: memcmp is used, as is strlen.
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- WCHAR wc = (WCHAR) 'c';
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoCharTest("foo %c", 'b', "foo b");
- DoCharTest("foo %hc", 'b', "foo b");
- DoWCharTest("foo %lc", wc, "foo c");
- DoCharTest("foo %Lc", 'b', "foo b");
- DoCharTest("foo %I64c", 'b', "foo b");
- DoCharTest("foo %5c", 'b', "foo b");
- DoCharTest("foo %.0c", 'b', "foo b");
- DoCharTest("foo %-5c", 'b', "foo b ");
- DoCharTest("foo %05c", 'b', "foo 0000b");
- DoCharTest("foo % c", 'b', "foo b");
- DoCharTest("foo %#c", 'b', "foo b");
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test6/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf/test6/testinfo.dat
deleted file mode 100644
index ba2ff818aa..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test6/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snprintf
-Name =Positive Test for _snprintf
-TYPE = DEFAULT
-EXE1 = test6
-Description
-= Tests _snprintf with characters
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test7/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf/test7/CMakeLists.txt
deleted file mode 100644
index f7651218e0..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test7/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test7.c
-)
-
-add_executable(paltest_snprintf_test7
- ${SOURCES}
-)
-
-add_dependencies(paltest_snprintf_test7 coreclrpal)
-
-target_link_libraries(paltest_snprintf_test7
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test7/test7.c b/src/pal/tests/palsuite/c_runtime/_snprintf/test7/test7.c
deleted file mode 100644
index bfd5c3f4f1..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test7/test7.c
+++ /dev/null
@@ -1,47 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: test7.c
-**
-** Purpose: Tests _snprintf with wide characters
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snprintf.h"
-/*
- * Notes: memcmp is used, as is strlen.
- */
-
-
-int __cdecl main(int argc, char *argv[])
-{
- WCHAR wb = (WCHAR) 'b';
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoWCharTest("foo %C", wb, "foo b");
- DoWCharTest("foo %hC", wb, "foo b");
- DoCharTest("foo %lC", 'c', "foo c");
- DoWCharTest("foo %LC", wb, "foo b");
- DoWCharTest("foo %I64C", wb, "foo b");
- DoWCharTest("foo %5C", wb, "foo b");
- DoWCharTest("foo %.0C", wb, "foo b");
- DoWCharTest("foo %-5C", wb, "foo b ");
- DoWCharTest("foo %05C", wb, "foo 0000b");
- DoWCharTest("foo % C", wb, "foo b");
- DoWCharTest("foo %#C", wb, "foo b");
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test7/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf/test7/testinfo.dat
deleted file mode 100644
index 5c2406c7b2..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test7/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snprintf
-Name = Positive Test for _snprintf
-TYPE = DEFAULT
-EXE1 = test7
-Description
-= Tests _snprintf with wide characters
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test8/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf/test8/CMakeLists.txt
deleted file mode 100644
index 26af119852..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test8/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test8.c
-)
-
-add_executable(paltest_snprintf_test8
- ${SOURCES}
-)
-
-add_dependencies(paltest_snprintf_test8 coreclrpal)
-
-target_link_libraries(paltest_snprintf_test8
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test8/test8.c b/src/pal/tests/palsuite/c_runtime/_snprintf/test8/test8.c
deleted file mode 100644
index 60ff1b05b8..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test8/test8.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test8.c
-**
-** Purpose: Tests _snprintf with decimal numbers
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snprintf.h"
-
-/*
- * Notes: memcmp is used, as is strlen.
- */
-
-
-int __cdecl main(int argc, char *argv[])
-{
- int neg = -42;
- int pos = 42;
- INT64 l = 42;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoNumTest("foo %d", pos, "foo 42");
- DoNumTest("foo %ld", 0xFFFF, "foo 65535");
- DoNumTest("foo %hd", 0xFFFF, "foo -1");
- DoNumTest("foo %Ld", pos, "foo 42");
- DoI64Test("foo %I64d", l, "42", "foo 42");
- DoNumTest("foo %3d", pos, "foo 42");
- DoNumTest("foo %-3d", pos, "foo 42 ");
- DoNumTest("foo %.1d", pos, "foo 42");
- DoNumTest("foo %.3d", pos, "foo 042");
- DoNumTest("foo %03d", pos, "foo 042");
- DoNumTest("foo %#d", pos, "foo 42");
- DoNumTest("foo %+d", pos, "foo +42");
- DoNumTest("foo % d", pos, "foo 42");
- DoNumTest("foo %+d", neg, "foo -42");
- DoNumTest("foo % d", neg, "foo -42");
-
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test8/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf/test8/testinfo.dat
deleted file mode 100644
index f6520d8dde..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test8/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snprintf
-Name = Positive Test for _snprintf
-TYPE = DEFAULT
-EXE1 = test8
-Description
-= Tests _snprintf with decimal numbers
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test9/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf/test9/CMakeLists.txt
deleted file mode 100644
index 484075919e..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test9/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test9.c
-)
-
-add_executable(paltest_snprintf_test9
- ${SOURCES}
-)
-
-add_dependencies(paltest_snprintf_test9 coreclrpal)
-
-target_link_libraries(paltest_snprintf_test9
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test9/test9.c b/src/pal/tests/palsuite/c_runtime/_snprintf/test9/test9.c
deleted file mode 100644
index e836bcaee3..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test9/test9.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test9.c
-**
-** Purpose: Tests _snprintf with integer numbers
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snprintf.h"
-
-/*
- * Notes: memcmp is used, as is strlen.
- */
-
-
-int __cdecl main(int argc, char *argv[])
-{
- int neg = -42;
- int pos = 42;
- INT64 l = 42;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoNumTest("foo %i", pos, "foo 42");
- DoNumTest("foo %li", 0xFFFF, "foo 65535");
- DoNumTest("foo %hi", 0xFFFF, "foo -1");
- DoNumTest("foo %Li", pos, "foo 42");
- DoI64Test("foo %I64i", l, "42", "foo 42");
- DoNumTest("foo %3i", pos, "foo 42");
- DoNumTest("foo %-3i", pos, "foo 42 ");
- DoNumTest("foo %.1i", pos, "foo 42");
- DoNumTest("foo %.3i", pos, "foo 042");
- DoNumTest("foo %03i", pos, "foo 042");
- DoNumTest("foo %#i", pos, "foo 42");
- DoNumTest("foo %+i", pos, "foo +42");
- DoNumTest("foo % i", pos, "foo 42");
- DoNumTest("foo %+i", neg, "foo -42");
- DoNumTest("foo % i", neg, "foo -42");
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf/test9/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf/test9/testinfo.dat
deleted file mode 100644
index 2a64b26030..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snprintf/test9/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snprintf
-Name = Positive Test for _snprintf
-TYPE = DEFAULT
-EXE1 = test9
-Description
-= Tests _snprintf with integer numbers
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf_s/CMakeLists.txt
new file mode 100644
index 0000000000..8fe1cb60ac
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/CMakeLists.txt
@@ -0,0 +1,21 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test10)
+add_subdirectory(test11)
+add_subdirectory(test12)
+add_subdirectory(test13)
+add_subdirectory(test14)
+add_subdirectory(test15)
+add_subdirectory(test16)
+add_subdirectory(test17)
+add_subdirectory(test18)
+add_subdirectory(test19)
+add_subdirectory(test2)
+add_subdirectory(test3)
+add_subdirectory(test4)
+add_subdirectory(test6)
+add_subdirectory(test7)
+add_subdirectory(test8)
+add_subdirectory(test9)
+
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/_snprintf_s.h b/src/pal/tests/palsuite/c_runtime/_snprintf_s/_snprintf_s.h
new file mode 100644
index 0000000000..9ed5209bea
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/_snprintf_s.h
@@ -0,0 +1,194 @@
+// Licensed to the .NET Foundation under one or more 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: sprintf_s.h
+**
+** Purpose: Containts common testing functions for sprintf_s
+**
+**
+**==========================================================================*/
+
+#ifndef __STRINGTEST_H__
+#define __STRINGTEST_H__
+
+void DoStrTest(const char *formatstr, char* param, const char *checkstr)
+{
+ char buf[256] = { 0 };
+
+ _snprintf_s(buf, 256, _TRUNCATE, formatstr, param);
+ if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
+ {
+ Fail("ERROR: failed to insert string \"%s\" into \"%s\"\n"
+ "Expected \"%s\" got \"%s\".\n",
+ param, formatstr, checkstr, buf);
+ }
+}
+
+void DoWStrTest(const char *formatstr, WCHAR* param, const char *checkstr)
+{
+ char buf[256] = { 0 };
+
+ _snprintf_s(buf, 256, _TRUNCATE, formatstr, param);
+ if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
+ {
+ Fail("ERROR: failed to insert wide string \"%s\" into \"%s\"\n"
+ "Expected \"%s\" got \"%s\".\n",
+ convertC(param), formatstr, checkstr, buf);
+ }
+}
+
+
+void DoPointerTest(const char *formatstr, void* param, char* paramstr, char
+ *checkstr1)
+{
+ char buf[256] = { 0 };
+
+ _snprintf_s(buf, 256, _TRUNCATE, formatstr, param);
+ if (memcmp(buf, checkstr1, strlen(checkstr1) + 1) != 0)
+ {
+ Fail("ERROR: failed to insert %s into \"%s\"\n"
+ "Expected \"%s\", got \"%s\".\n",
+ paramstr, formatstr, checkstr1, buf);
+ }
+}
+
+void DoCountTest(const char *formatstr, int param, const char *checkstr)
+{
+ char buf[512] = { 0 };
+ int n = -1;
+
+ sprintf_s(buf, 512, formatstr, &n);
+
+ if (n != param)
+ {
+ Fail("ERROR: Expected count parameter to resolve to %d, got %X\n",
+ param, n);
+ }
+ if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
+ {
+ Fail("ERROR: Expected \"%s\" got \"%s\".\n", checkstr, buf);
+ }
+}
+
+void DoShortCountTest(const char *formatstr, int param, const char *checkstr)
+{
+ char buf[256] = { 0 };
+ short int n = -1;
+
+ _snprintf_s(buf, 256, _TRUNCATE, formatstr, &n);
+
+ if (n != param)
+ {
+ Fail("ERROR: Expected count parameter to resolve to %d, got %X\n",
+ param, n);
+ }
+ if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
+ {
+ Fail("ERROR: Expected \"%s\" got \"%s\".\n", checkstr, buf);
+ }
+}
+
+void DoCharTest(const char *formatstr, char param, const char *checkstr)
+{
+ char buf[256] = { 0 };
+
+ _snprintf_s(buf, 256, _TRUNCATE, formatstr, param);
+ if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
+ {
+ Fail("ERROR: failed to insert char \'%c\' (%d) into \"%s\"\n"
+ "Expected \"%s\" got \"%s\".\n",
+ param, param, formatstr, checkstr, buf);
+ }
+}
+
+void DoWCharTest(const char *formatstr, WCHAR param, const char *checkstr)
+{
+ char buf[256] = { 0 };
+
+ _snprintf_s(buf, 256, _TRUNCATE, formatstr, param);
+ if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
+ {
+ Fail("ERROR: failed to insert wide char \'%c\' (%d) into \"%s\"\n"
+ "Expected \"%s\" got \"%s\".\n",
+ (char)param, param, formatstr, checkstr, buf);
+ }
+}
+
+void DoNumTest(const char *formatstr, int value, const char *checkstr)
+{
+ char buf[256] = { 0 };
+
+ _snprintf_s(buf, 256, _TRUNCATE, formatstr, value);
+ if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
+ {
+ Fail("ERROR: failed to insert %#x into \"%s\"\n"
+ "Expected \"%s\" got \"%s\".\n",
+ value, formatstr, checkstr, buf);
+ }
+}
+
+void DoI64Test(const char *formatstr, INT64 value, char *valuestr, const char *checkstr1)
+{
+ char buf[256] = { 0 };
+
+ _snprintf_s(buf, 256, _TRUNCATE, formatstr, value);
+ if (memcmp(buf, checkstr1, strlen(checkstr1) + 1) != 0)
+ {
+ Fail("ERROR: failed to insert %s into \"%s\"\n"
+ "Expected \"%s\", got \"%s\".\n",
+ valuestr, formatstr, checkstr1, buf);
+ }
+}
+
+void DoDoubleTest(const char *formatstr, double value, const char *checkstr1, char
+*checkstr2)
+{
+ char buf[256] = { 0 };
+
+ _snprintf_s(buf, 256, _TRUNCATE, formatstr, value);
+ if (memcmp(buf, checkstr1, strlen(checkstr1) + 1) != 0
+ && memcmp(buf, checkstr2, strlen(checkstr2) + 1) != 0)
+ {
+ Fail("ERROR: failed to insert %f into \"%s\"\n"
+ "Expected \"%s\" or \"%s\", got \"%s\".\n",
+ value, formatstr, checkstr1, checkstr2, buf);
+ }
+}
+
+void DoArgumentPrecTest(const char *formatstr, int precision, void *param, char
+*paramstr, const char *checkstr1, const char *checkstr2)
+{
+ char buf[256];
+
+ _snprintf_s(buf, 256, _TRUNCATE, formatstr, precision, param);
+ if (memcmp(buf, checkstr1, strlen(checkstr1) + 1) != 0 &&
+ memcmp(buf, checkstr2, strlen(checkstr2) + 1) != 0)
+ {
+ Fail("ERROR: failed to insert %s into \"%s\" with precision %d\n"
+ "Expected \"%s\" or \"%s\", got \"%s\".\n",
+ paramstr, formatstr, precision, checkstr1, checkstr2, buf);
+ }
+
+}
+
+void DoArgumentPrecDoubleTest(const char *formatstr, int precision, double param,
+const char *checkstr1, const char *checkstr2)
+{
+ char buf[256];
+
+ _snprintf_s(buf, 256, _TRUNCATE, formatstr, precision, param);
+ if (memcmp(buf, checkstr1, strlen(checkstr1) + 1) != 0 &&
+ memcmp(buf, checkstr2, strlen(checkstr2) + 1) != 0)
+ {
+ Fail("ERROR: failed to insert %f into \"%s\" with precision %d\n"
+ "Expected \"%s\" or \"%s\", got \"%s\".\n",
+ param, formatstr, precision, checkstr1, checkstr2, buf);
+ }
+
+}
+
+#endif
+
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test1/CMakeLists.txt
new file mode 100644
index 0000000000..9e4c671ec8
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.cpp
+)
+
+add_executable(paltest_snprintf_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snprintf_test1 coreclrpal)
+
+target_link_libraries(paltest_snprintf_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test1/test1.cpp b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test1/test1.cpp
new file mode 100644
index 0000000000..d180b05df5
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test1/test1.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test1.c
+**
+** Purpose: General test to see if sprintf_s works correctly
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snprintf_s.h"
+
+/*
+ * Notes: memcmp is used, as is strlen.
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ char checkstr[] = "hello world";
+ char buf[256] = { 0 };
+ int ret;
+
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ _snprintf_s(buf, 256, _TRUNCATE, "hello world");
+ if (memcmp(checkstr, buf, strlen(checkstr)+1) != 0)
+ {
+ Fail("ERROR: expected \"%s\" (up to %d chars), got \"%s\"\n",
+ checkstr, 256, buf);
+ }
+
+ _snprintf_s(buf, 256, _TRUNCATE, "xxxxxxxxxxxxxxxxx");
+ ret = _snprintf_s(buf, 8, _TRUNCATE, "hello world");
+
+ if (ret >= 0)
+ {
+ Fail("ERROR: expected negative return value, got %d", ret);
+ }
+ if (memcmp(checkstr, buf, 7) != 0 || buf[7] != 0 || buf[8] != 'x')
+ {
+ Fail("ERROR: expected %s (up to %d chars), got %s\n",
+ checkstr, 8, buf);
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test1/testinfo.dat
new file mode 100644
index 0000000000..255c534cdf
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= General test to see if sprintf_s works correctly
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test10/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test10/CMakeLists.txt
new file mode 100644
index 0000000000..57e7fb16d3
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test10/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test10.cpp
+)
+
+add_executable(paltest_snprintf_test10
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snprintf_test10 coreclrpal)
+
+target_link_libraries(paltest_snprintf_test10
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test10/test10.cpp b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test10/test10.cpp
new file mode 100644
index 0000000000..7ecb9102e4
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test10/test10.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: test10.c
+**
+** Purpose: Tests sprintf_s with octal numbers
+**
+**
+**==========================================================================*/
+
+
+
+
+#include <palsuite.h>
+#include "../_snprintf_s.h"
+
+/*
+ * Notes: memcmp is used, as is strlen.
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ int neg = -42;
+ int pos = 42;
+ INT64 l = 42;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoNumTest("foo %o", pos, "foo 52");
+ DoNumTest("foo %lo", 0xFFFF, "foo 177777");
+ DoNumTest("foo %ho", 0xFFFF, "foo 177777");
+ DoNumTest("foo %Lo", pos, "foo 52");
+ DoI64Test("foo %I64o", l, "42", "foo 52");
+ DoNumTest("foo %3o", pos, "foo 52");
+ DoNumTest("foo %-3o", pos, "foo 52 ");
+ DoNumTest("foo %.1o", pos, "foo 52");
+ DoNumTest("foo %.3o", pos, "foo 052");
+ DoNumTest("foo %03o", pos, "foo 052");
+ DoNumTest("foo %#o", pos, "foo 052");
+ DoNumTest("foo %+o", pos, "foo 52");
+ DoNumTest("foo % o", pos, "foo 52");
+ DoNumTest("foo %+o", neg, "foo 37777777726");
+ DoNumTest("foo % o", neg, "foo 37777777726");
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test10/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test10/testinfo.dat
new file mode 100644
index 0000000000..25ed554ea3
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test10/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test10
+Description
+= Tests sprintf_s with octal numbers
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test11/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test11/CMakeLists.txt
new file mode 100644
index 0000000000..4fc179c5a8
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test11/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test11.cpp
+)
+
+add_executable(paltest_snprintf_test11
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snprintf_test11 coreclrpal)
+
+target_link_libraries(paltest_snprintf_test11
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test11/test11.cpp b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test11/test11.cpp
new file mode 100644
index 0000000000..c2ac015698
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test11/test11.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test11.c
+**
+** Purpose: Tests sprintf_s with unsigned numbers
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snprintf_s.h"
+
+/*
+ * Notes: memcmp is used, as is strlen.
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ int neg = -42;
+ int pos = 42;
+ INT64 l = 42;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoNumTest("foo %u", pos, "foo 42");
+ DoNumTest("foo %lu", 0xFFFF, "foo 65535");
+ DoNumTest("foo %hu", 0xFFFF, "foo 65535");
+ DoNumTest("foo %Lu", pos, "foo 42");
+ DoI64Test("foo %I64u", l, "42", "foo 42");
+ DoNumTest("foo %3u", pos, "foo 42");
+ DoNumTest("foo %-3u", pos, "foo 42 ");
+ DoNumTest("foo %.1u", pos, "foo 42");
+ DoNumTest("foo %.3u", pos, "foo 042");
+ DoNumTest("foo %03u", pos, "foo 042");
+ DoNumTest("foo %#u", pos, "foo 42");
+ DoNumTest("foo %+u", pos, "foo 42");
+ DoNumTest("foo % u", pos, "foo 42");
+ DoNumTest("foo %+u", neg, "foo 4294967254");
+ DoNumTest("foo % u", neg, "foo 4294967254");
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test11/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test11/testinfo.dat
new file mode 100644
index 0000000000..3144f1290e
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test11/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test11
+Description
+= Tests sprintf_s with unsigned numbers
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test12/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test12/CMakeLists.txt
new file mode 100644
index 0000000000..a35609eb57
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test12/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test12.cpp
+)
+
+add_executable(paltest_snprintf_test12
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snprintf_test12 coreclrpal)
+
+target_link_libraries(paltest_snprintf_test12
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test12/test12.cpp b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test12/test12.cpp
new file mode 100644
index 0000000000..52171838cc
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test12/test12.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: test12.c
+**
+** Purpose: Tests sprintf_s with hex numbers (lowercase)
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snprintf_s.h"
+
+/*
+ * Notes: memcmp is used, as is strlen.
+ */
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ int neg = -42;
+ int pos = 0x1234ab;
+ INT64 l = I64(0x1234567887654321);
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoNumTest("foo %x", pos, "foo 1234ab");
+ DoNumTest("foo %lx", pos, "foo 1234ab");
+ DoNumTest("foo %hx", pos, "foo 34ab");
+ DoNumTest("foo %Lx", pos, "foo 1234ab");
+ DoI64Test("foo %I64x", l, "0x1234567887654321", "foo 1234567887654321");
+ DoNumTest("foo %7x", pos, "foo 1234ab");
+ DoNumTest("foo %-7x", pos, "foo 1234ab ");
+ DoNumTest("foo %.1x", pos, "foo 1234ab");
+ DoNumTest("foo %.7x", pos, "foo 01234ab");
+ DoNumTest("foo %07x", pos, "foo 01234ab");
+ DoNumTest("foo %#x", pos, "foo 0x1234ab");
+ DoNumTest("foo %+x", pos, "foo 1234ab");
+ DoNumTest("foo % x", pos, "foo 1234ab");
+ DoNumTest("foo %+x", neg, "foo ffffffd6");
+ DoNumTest("foo % x", neg, "foo ffffffd6");
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test12/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test12/testinfo.dat
new file mode 100644
index 0000000000..ed91cecc46
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test12/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test12
+Description
+= Tests sprintf_s with hex numbers (lowercase)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test13/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test13/CMakeLists.txt
new file mode 100644
index 0000000000..3bf986e851
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test13/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test13.cpp
+)
+
+add_executable(paltest_snprintf_test13
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snprintf_test13 coreclrpal)
+
+target_link_libraries(paltest_snprintf_test13
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test13/test13.cpp b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test13/test13.cpp
new file mode 100644
index 0000000000..15e47558b0
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test13/test13.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: test13.c
+**
+** Purpose: Tests sprintf_s with hex numbers (uppercase)
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snprintf_s.h"
+
+/*
+ * Notes: memcmp is used, as is strlen.
+ */
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ int neg = -42;
+ int pos = 0x1234AB;
+ INT64 l = I64(0x1234567887654321);
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoNumTest("foo %X", pos, "foo 1234AB");
+ DoNumTest("foo %lX", pos, "foo 1234AB");
+ DoNumTest("foo %hX", pos, "foo 34AB");
+ DoNumTest("foo %LX", pos, "foo 1234AB");
+ DoI64Test("foo %I64X", l, "0x1234567887654321", "foo 1234567887654321");
+ DoNumTest("foo %7X", pos, "foo 1234AB");
+ DoNumTest("foo %-7X", pos, "foo 1234AB ");
+ DoNumTest("foo %.1X", pos, "foo 1234AB");
+ DoNumTest("foo %.7X", pos, "foo 01234AB");
+ DoNumTest("foo %07X", pos, "foo 01234AB");
+ DoNumTest("foo %#X", pos, "foo 0X1234AB");
+ DoNumTest("foo %+X", pos, "foo 1234AB");
+ DoNumTest("foo % X", pos, "foo 1234AB");
+ DoNumTest("foo %+X", neg, "foo FFFFFFD6");
+ DoNumTest("foo % X", neg, "foo FFFFFFD6");
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test13/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test13/testinfo.dat
new file mode 100644
index 0000000000..fd5f53017c
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test13/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test13
+Description
+= Tests sprintf_s with hex numbers (uppercase)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test14/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test14/CMakeLists.txt
new file mode 100644
index 0000000000..985303ecf8
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test14/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test14.cpp
+)
+
+add_executable(paltest_snprintf_test14
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snprintf_test14 coreclrpal)
+
+target_link_libraries(paltest_snprintf_test14
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test14/test14.cpp b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test14/test14.cpp
new file mode 100644
index 0000000000..331475e962
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test14/test14.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test14.c
+**
+** Purpose: Tests sprintf_s with exponential format doubles (lowercase)
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snprintf_s.h"
+
+/*
+ * Notes: memcmp is used, as is strlen.
+ */
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ double val = 256.0;
+ double neg = -256.0;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoDoubleTest("foo %e", val, "foo 2.560000e+002", "foo 2.560000e+02");
+ DoDoubleTest("foo %le", val, "foo 2.560000e+002", "foo 2.560000e+02");
+ DoDoubleTest("foo %he", val, "foo 2.560000e+002", "foo 2.560000e+02");
+ DoDoubleTest("foo %Le", val, "foo 2.560000e+002", "foo 2.560000e+02");
+ DoDoubleTest("foo %I64e", val, "foo 2.560000e+002", "foo 2.560000e+02");
+ DoDoubleTest("foo %14e", val, "foo 2.560000e+002",
+ "foo 2.560000e+02");
+ DoDoubleTest("foo %-14e", val, "foo 2.560000e+002 ",
+ "foo 2.560000e+02 ");
+ DoDoubleTest("foo %.1e", val, "foo 2.6e+002", "foo 2.6e+02");
+ DoDoubleTest("foo %.8e", val, "foo 2.56000000e+002",
+ "foo 2.56000000e+02");
+ DoDoubleTest("foo %014e", val, "foo 02.560000e+002",
+ "foo 002.560000e+02");
+ DoDoubleTest("foo %#e", val, "foo 2.560000e+002", "foo 2.560000e+02");
+ DoDoubleTest("foo %+e", val, "foo +2.560000e+002", "foo +2.560000e+02");
+ DoDoubleTest("foo % e", val, "foo 2.560000e+002", "foo 2.560000e+02");
+ DoDoubleTest("foo %+e", neg, "foo -2.560000e+002", "foo -2.560000e+02");
+ DoDoubleTest("foo % e", neg, "foo -2.560000e+002", "foo -2.560000e+02");
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test14/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test14/testinfo.dat
new file mode 100644
index 0000000000..23cf423354
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test14/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test14
+Description
+= Tests sprintf_s with exponential format doubles (lowercase)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test15/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test15/CMakeLists.txt
new file mode 100644
index 0000000000..c7f5796089
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test15/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test15.cpp
+)
+
+add_executable(paltest_snprintf_test15
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snprintf_test15 coreclrpal)
+
+target_link_libraries(paltest_snprintf_test15
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test15/test15.cpp b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test15/test15.cpp
new file mode 100644
index 0000000000..d43613b6cf
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test15/test15.cpp
@@ -0,0 +1,56 @@
+// Licensed to the .NET Foundation under one or more 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: test15.c
+**
+** Purpose: Tests sprintf_s with exponential format doubles (uppercase)
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snprintf_s.h"
+
+/*
+ * Notes: memcmp is used, as is strlen.
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ double val = 256.0;
+ double neg = -256.0;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoDoubleTest("foo %E", val, "foo 2.560000E+002", "foo 2.560000E+02");
+ DoDoubleTest("foo %lE", val, "foo 2.560000E+002", "foo 2.560000E+02");
+ DoDoubleTest("foo %hE", val, "foo 2.560000E+002", "foo 2.560000E+02");
+ DoDoubleTest("foo %LE", val, "foo 2.560000E+002", "foo 2.560000E+02");
+ DoDoubleTest("foo %I64E", val, "foo 2.560000E+002", "foo 2.560000E+02");
+ DoDoubleTest("foo %14E", val, "foo 2.560000E+002",
+ "foo 2.560000E+02");
+ DoDoubleTest("foo %-14E", val, "foo 2.560000E+002 ",
+ "foo 2.560000E+02 ");
+ DoDoubleTest("foo %.1E", val, "foo 2.6E+002", "foo 2.6E+02");
+ DoDoubleTest("foo %.8E", val, "foo 2.56000000E+002",
+ "foo 2.56000000E+02");
+ DoDoubleTest("foo %014E", val, "foo 02.560000E+002",
+ "foo 002.560000E+02");
+ DoDoubleTest("foo %#E", val, "foo 2.560000E+002", "foo 2.560000E+02");
+ DoDoubleTest("foo %+E", val, "foo +2.560000E+002", "foo +2.560000E+02");
+ DoDoubleTest("foo % E", val, "foo 2.560000E+002", "foo 2.560000E+02");
+ DoDoubleTest("foo %+E", neg, "foo -2.560000E+002", "foo -2.560000E+02");
+ DoDoubleTest("foo % E", neg, "foo -2.560000E+002", "foo -2.560000E+02");
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test15/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test15/testinfo.dat
new file mode 100644
index 0000000000..537e6d1db2
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test15/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test15
+Description
+= Tests sprintf_s with exponential format doubles (uppercase)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test16/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test16/CMakeLists.txt
new file mode 100644
index 0000000000..9a224bc23b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test16/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test16.cpp
+)
+
+add_executable(paltest_snprintf_test16
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snprintf_test16 coreclrpal)
+
+target_link_libraries(paltest_snprintf_test16
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test16/test16.cpp b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test16/test16.cpp
new file mode 100644
index 0000000000..21cbb1ed30
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test16/test16.cpp
@@ -0,0 +1,52 @@
+// Licensed to the .NET Foundation under one or more 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: test16.c
+**
+** Purpose: Test #15 for the sprintf_s function
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snprintf_s.h"
+
+/*
+ * Notes: memcmp is used, as is strlen.
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ double val = 2560.001;
+ double neg = -2560.001;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoDoubleTest("foo %f", val, "foo 2560.001000", "foo 2560.001000");
+ DoDoubleTest("foo %lf", val, "foo 2560.001000", "foo 2560.001000");
+ DoDoubleTest("foo %hf", val, "foo 2560.001000", "foo 2560.001000");
+ DoDoubleTest("foo %Lf", val, "foo 2560.001000", "foo 2560.001000");
+ DoDoubleTest("foo %I64f", val, "foo 2560.001000", "foo 2560.001000");
+ DoDoubleTest("foo %12f", val, "foo 2560.001000", "foo 2560.001000");
+ DoDoubleTest("foo %-12f", val, "foo 2560.001000 ", "foo 2560.001000 ");
+ DoDoubleTest("foo %.1f", val, "foo 2560.0", "foo 2560.0");
+ DoDoubleTest("foo %.8f", val, "foo 2560.00100000", "foo 2560.00100000");
+ DoDoubleTest("foo %012f", val, "foo 02560.001000", "foo 02560.001000");
+ DoDoubleTest("foo %#f", val, "foo 2560.001000", "foo 2560.001000");
+ DoDoubleTest("foo %+f", val, "foo +2560.001000", "foo +2560.001000");
+ DoDoubleTest("foo % f", val, "foo 2560.001000", "foo 2560.001000");
+ DoDoubleTest("foo %+f", neg, "foo -2560.001000", "foo -2560.001000");
+ DoDoubleTest("foo % f", neg, "foo -2560.001000", "foo -2560.001000");
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test16/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test16/testinfo.dat
new file mode 100644
index 0000000000..4e98eccac2
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test16/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test16
+Description
+= Tests sprintf_s with decimal point format doubles
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test17/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test17/CMakeLists.txt
new file mode 100644
index 0000000000..3a8a349c84
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test17/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test17.cpp
+)
+
+add_executable(paltest_snprintf_test17
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snprintf_test17 coreclrpal)
+
+target_link_libraries(paltest_snprintf_test17
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test17/test17.cpp b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test17/test17.cpp
new file mode 100644
index 0000000000..d161270b84
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test17/test17.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: test17.c
+**
+** Purpose: Tests sprintf_s with compact format doubles (lowercase)
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snprintf_s.h"
+
+/*
+ * Notes: memcmp is used, as is strlen.
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ double val = 2560.001;
+ double neg = -2560.001;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoDoubleTest("foo %g", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %lg", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %hg", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %Lg", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %I64g", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %5g", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %-5g", val, "foo 2560 ", "foo 2560 ");
+ DoDoubleTest("foo %.1g", val, "foo 3e+003", "foo 3e+03");
+ DoDoubleTest("foo %.2g", val, "foo 2.6e+003", "foo 2.6e+03");
+ DoDoubleTest("foo %.12g", val, "foo 2560.001", "foo 2560.001");
+ DoDoubleTest("foo %06g", val, "foo 002560", "foo 002560");
+ DoDoubleTest("foo %#g", val, "foo 2560.00", "foo 2560.00");
+ DoDoubleTest("foo %+g", val, "foo +2560", "foo +2560");
+ DoDoubleTest("foo % g", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %+g", neg, "foo -2560", "foo -2560");
+ DoDoubleTest("foo % g", neg, "foo -2560", "foo -2560");
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test17/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test17/testinfo.dat
new file mode 100644
index 0000000000..5e41e20d44
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test17/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test17
+Description
+= Tests sprintf_s with compact format doubles (lowercase)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test18/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test18/CMakeLists.txt
new file mode 100644
index 0000000000..96e39e8f41
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test18/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test18.cpp
+)
+
+add_executable(paltest_snprintf_test18
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snprintf_test18 coreclrpal)
+
+target_link_libraries(paltest_snprintf_test18
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test18/test18.cpp b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test18/test18.cpp
new file mode 100644
index 0000000000..46ec287cc1
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test18/test18.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: test18.c
+**
+** Purpose: Tests sprintf_s with compact format doubles (uppercase)
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snprintf_s.h"
+
+/*
+ * Notes: memcmp is used, as is strlen.
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ double val = 2560.001;
+ double neg = -2560.001;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoDoubleTest("foo %G", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %lG", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %hG", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %LG", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %I64G", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %5G", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %-5G", val, "foo 2560 ", "foo 2560 ");
+ DoDoubleTest("foo %.1G", val, "foo 3E+003", "foo 3E+03");
+ DoDoubleTest("foo %.2G", val, "foo 2.6E+003", "foo 2.6E+03");
+ DoDoubleTest("foo %.12G", val, "foo 2560.001", "foo 2560.001");
+ DoDoubleTest("foo %06G", val, "foo 002560", "foo 002560");
+ DoDoubleTest("foo %#G", val, "foo 2560.00", "foo 2560.00");
+ DoDoubleTest("foo %+G", val, "foo +2560", "foo +2560");
+ DoDoubleTest("foo % G", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %+G", neg, "foo -2560", "foo -2560");
+ DoDoubleTest("foo % G", neg, "foo -2560", "foo -2560");
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test18/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test18/testinfo.dat
new file mode 100644
index 0000000000..06ae3a632e
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test18/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test18
+Description
+= Tests sprintf_s with compact format doubles (uppercase)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test19/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test19/CMakeLists.txt
new file mode 100644
index 0000000000..be3570f163
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test19/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test19.cpp
+)
+
+add_executable(paltest_snprintf_test19
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snprintf_test19 coreclrpal)
+
+target_link_libraries(paltest_snprintf_test19
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test19/test19.cpp b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test19/test19.cpp
new file mode 100644
index 0000000000..91b1dae583
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test19/test19.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.
+
+/*============================================================================
+**
+** Source: test19.c
+**
+** Purpose:Tests sprintf_s with argument specified precision
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snprintf_s.h"
+
+/*
+ * Notes: memcmp is used, as is strlen.
+ */
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ int n = -1;
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ DoArgumentPrecTest("%.*s", 2, (void*)"bar", "bar", "ba", "ba");
+ DoArgumentPrecTest("%.*S", 2, (void*)convert("bar"), "bar", "ba", "ba");
+
+ DoArgumentPrecTest("%.*c", 0, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*c", 4, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*C", 0, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*C", 4, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*d", 1, (void*)42, "42", "42", "42");
+ DoArgumentPrecTest("%.*d", 3, (void*)42, "42", "042", "042");
+ DoArgumentPrecTest("%.*i", 1, (void*)42, "42", "42", "42");
+ DoArgumentPrecTest("%.*i", 3, (void*)42, "42", "042", "042");
+ DoArgumentPrecTest("%.*o", 1, (void*)42, "42", "52", "52");
+ DoArgumentPrecTest("%.*o", 3, (void*)42, "42", "052", "052");
+ DoArgumentPrecTest("%.*u", 1, (void*)42, "42", "42", "42");
+ DoArgumentPrecTest("%.*u", 3, (void*)42, "42", "042", "042");
+ DoArgumentPrecTest("%.*x", 1, (void*)0x42, "0x42", "42", "42");
+ DoArgumentPrecTest("%.*x", 3, (void*)0x42, "0x42", "042", "042");
+ DoArgumentPrecTest("%.*X", 1, (void*)0x42, "0x42", "42", "42") ;
+ DoArgumentPrecTest("%.*X", 3, (void*)0x42, "0x42", "042", "042");
+
+
+ DoArgumentPrecDoubleTest("%.*e", 1, 2.01, "2.0e+000", "2.0e+00");
+ DoArgumentPrecDoubleTest("%.*e", 3, 2.01, "2.010e+000", "2.010e+00");
+ DoArgumentPrecDoubleTest("%.*E", 1, 2.01, "2.0E+000", "2.0E+00");
+ DoArgumentPrecDoubleTest("%.*E", 3, 2.01, "2.010E+000", "2.010E+00");
+ DoArgumentPrecDoubleTest("%.*f", 1, 2.01, "2.0", "2.0");
+ DoArgumentPrecDoubleTest("%.*f", 3, 2.01, "2.010", "2.010");
+ DoArgumentPrecDoubleTest("%.*g", 1, 256.01, "3e+002", "3e+02");
+ DoArgumentPrecDoubleTest("%.*g", 3, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*g", 4, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*g", 6, 256.01, "256.01", "256.01");
+ DoArgumentPrecDoubleTest("%.*G", 1, 256.01, "3E+002", "3E+02");
+ DoArgumentPrecDoubleTest("%.*G", 3, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*G", 4, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*G", 6, 256.01, "256.01", "256.01");
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test19/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test19/testinfo.dat
new file mode 100644
index 0000000000..7064c01771
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test19/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test19
+Description
+= Tests sprintf_s with argument specified precision
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test2/CMakeLists.txt
new file mode 100644
index 0000000000..11d18e61c3
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test2.cpp
+)
+
+add_executable(paltest_snprintf_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snprintf_test2 coreclrpal)
+
+target_link_libraries(paltest_snprintf_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test2/test2.cpp b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test2/test2.cpp
new file mode 100644
index 0000000000..e58669466f
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test2/test2.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test2.c
+**
+** Purpose:Tests sprintf_s with strings
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snprintf_s.h"
+/*
+ * Notes: memcmp is used, as is strlen.
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ DoStrTest("foo %s", "bar", "foo bar");
+ DoStrTest("foo %hs", "bar", "foo bar");
+ DoWStrTest("foo %ls", convert("bar"), "foo bar");
+ DoWStrTest("foo %ws", convert("bar"), "foo bar");
+ DoStrTest("foo %Ls", "bar", "foo bar");
+ DoStrTest("foo %I64s", "bar", "foo bar");
+ DoStrTest("foo %5s", "bar", "foo bar");
+ DoStrTest("foo %.2s", "bar", "foo ba");
+ DoStrTest("foo %5.2s", "bar", "foo ba");
+ DoStrTest("foo %-5s", "bar", "foo bar ");
+ DoStrTest("foo %05s", "bar", "foo 00bar");
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test2/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test2/testinfo.dat
new file mode 100644
index 0000000000..cce2dc67e7
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test2/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test2
+Description
+= Tests sprintf_s with strings
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test3/CMakeLists.txt
new file mode 100644
index 0000000000..b8d4178962
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test3/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test3.cpp
+)
+
+add_executable(paltest_snprintf_test3
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snprintf_test3 coreclrpal)
+
+target_link_libraries(paltest_snprintf_test3
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test3/test3.cpp b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test3/test3.cpp
new file mode 100644
index 0000000000..3c52b44246
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test3/test3.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test3.c
+**
+** Purpose: Tests sprintf_s with wide strings
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snprintf_s.h"
+
+/*
+ * Notes: memcmp is used, as is strlen.
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ DoWStrTest("foo %S", convert("bar"), "foo bar");
+ DoStrTest("foo %hS", "bar", "foo bar");
+ DoWStrTest("foo %lS", convert("bar"), "foo bar");
+ DoWStrTest("foo %wS", convert("bar"), "foo bar");
+ DoWStrTest("foo %LS", convert("bar"), "foo bar");
+ DoWStrTest("foo %I64S", convert("bar"), "foo bar");
+ DoWStrTest("foo %5S", convert("bar"), "foo bar");
+ DoWStrTest("foo %.2S", convert("bar"), "foo ba");
+ DoWStrTest("foo %5.2S", convert("bar"), "foo ba");
+ DoWStrTest("foo %-5S", convert("bar"), "foo bar ");
+ DoWStrTest("foo %05S", convert("bar"), "foo 00bar");
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test3/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test3/testinfo.dat
new file mode 100644
index 0000000000..cc8de0eae5
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test3/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test3
+Description
+= Tests sprintf_s with wide strings
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test4/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test4/CMakeLists.txt
new file mode 100644
index 0000000000..568b7122de
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test4/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test4.cpp
+)
+
+add_executable(paltest_snprintf_test4
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snprintf_test4 coreclrpal)
+
+target_link_libraries(paltest_snprintf_test4
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test4/test4.cpp b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test4/test4.cpp
new file mode 100644
index 0000000000..216557f10a
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test4/test4.cpp
@@ -0,0 +1,69 @@
+// Licensed to the .NET Foundation under one or more 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: test4.c
+**
+** Purpose: Tests sprintf_s with pointers
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snprintf_s.h"
+
+/*
+ * Notes: memcmp is used, as is strlen.
+ */
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ void *ptr = (void*) 0x123456;
+ INT64 lptr = I64(0x1234567887654321);
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+ /*
+ ** Run only on 64 bit platforms
+ */
+ #if defined(BIT64) && defined(PLATFORM_UNIX)
+ Trace("Testing for 64 Bit Platforms \n");
+ DoPointerTest("%p", NULL, "NULL", "0000000000000000");
+ DoPointerTest("%p", ptr, "pointer to 0x123456", "0000000000123456");
+ DoPointerTest("%17p", ptr, "pointer to 0x123456", " 0000000000123456");
+ DoPointerTest("%17p", ptr, "pointer to 0x123456", " 0000000000123456");
+ DoPointerTest("%-17p", ptr, "pointer to 0x123456", "0000000000123456 ");
+ DoPointerTest("%+p", ptr, "pointer to 0x123456", "0000000000123456");
+ DoPointerTest("%#p", ptr, "pointer to 0x123456", "0X0000000000123456");
+ DoPointerTest("%lp", ptr, "pointer to 0x123456", "00123456");
+ DoPointerTest("%hp", ptr, "pointer to 0x123456", "00003456");
+ DoPointerTest("%Lp", ptr, "pointer to 0x123456", "00123456");
+ DoI64Test("%I64p", lptr, "pointer to 0x1234567887654321",
+ "1234567887654321");
+ #else
+ Trace("Testing for Non 64 Bit Platforms \n");
+ DoPointerTest("%p", NULL, "NULL", "00000000");
+ DoPointerTest("%p", ptr, "pointer to 0x123456", "00123456");
+ DoPointerTest("%9p", ptr, "pointer to 0x123456", " 00123456");
+ DoPointerTest("%09p", ptr, "pointer to 0x123456", " 00123456");
+ DoPointerTest("%-9p", ptr, "pointer to 0x123456", "00123456 ");
+ DoPointerTest("%+p", ptr, "pointer to 0x123456", "00123456");
+ DoPointerTest("%#p", ptr, "pointer to 0x123456", "0X00123456");
+ DoPointerTest("%lp", ptr, "pointer to 0x123456", "00123456");
+ DoPointerTest("%hp", ptr, "pointer to 0x123456", "00003456");
+ DoPointerTest("%Lp", ptr, "pointer to 0x123456", "00123456");
+ DoI64Test("%I64p", lptr, "pointer to 0x1234567887654321",
+ "1234567887654321");
+ #endif //defined(BIT64) && defined(PLATFORM_UNIX)
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test4/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test4/testinfo.dat
new file mode 100644
index 0000000000..f53f784991
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test4/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test4
+Description
+= Tests sprintf_s with pointers
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test6/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test6/CMakeLists.txt
new file mode 100644
index 0000000000..820cc66d55
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test6/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test6.cpp
+)
+
+add_executable(paltest_snprintf_test6
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snprintf_test6 coreclrpal)
+
+target_link_libraries(paltest_snprintf_test6
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test6/test6.cpp b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test6/test6.cpp
new file mode 100644
index 0000000000..45c9e2b79b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test6/test6.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test6.c
+**
+** Purpose: Tests sprintf_s with characters
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snprintf_s.h"
+
+/*
+ * Notes: memcmp is used, as is strlen.
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ WCHAR wc = (WCHAR) 'c';
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoCharTest("foo %c", 'b', "foo b");
+ DoCharTest("foo %hc", 'b', "foo b");
+ DoWCharTest("foo %lc", wc, "foo c");
+ DoCharTest("foo %Lc", 'b', "foo b");
+ DoCharTest("foo %I64c", 'b', "foo b");
+ DoCharTest("foo %5c", 'b', "foo b");
+ DoCharTest("foo %.0c", 'b', "foo b");
+ DoCharTest("foo %-5c", 'b', "foo b ");
+ DoCharTest("foo %05c", 'b', "foo 0000b");
+ DoCharTest("foo % c", 'b', "foo b");
+ DoCharTest("foo %#c", 'b', "foo b");
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test6/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test6/testinfo.dat
new file mode 100644
index 0000000000..06e31e85d6
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test6/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 = C Runtime
+Function = sprintf_s
+Name =Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test6
+Description
+= Tests sprintf_s with characters
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test7/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test7/CMakeLists.txt
new file mode 100644
index 0000000000..a2af7c4a8c
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test7/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test7.cpp
+)
+
+add_executable(paltest_snprintf_test7
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snprintf_test7 coreclrpal)
+
+target_link_libraries(paltest_snprintf_test7
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test7/test7.cpp b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test7/test7.cpp
new file mode 100644
index 0000000000..5c10fc8ea7
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test7/test7.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test7.c
+**
+** Purpose: Tests sprintf_s with wide characters
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snprintf_s.h"
+/*
+ * Notes: memcmp is used, as is strlen.
+ */
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ WCHAR wb = (WCHAR) 'b';
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoWCharTest("foo %C", wb, "foo b");
+ DoWCharTest("foo %hC", wb, "foo b");
+ DoCharTest("foo %lC", 'c', "foo c");
+ DoWCharTest("foo %LC", wb, "foo b");
+ DoWCharTest("foo %I64C", wb, "foo b");
+ DoWCharTest("foo %5C", wb, "foo b");
+ DoWCharTest("foo %.0C", wb, "foo b");
+ DoWCharTest("foo %-5C", wb, "foo b ");
+ DoWCharTest("foo %05C", wb, "foo 0000b");
+ DoWCharTest("foo % C", wb, "foo b");
+ DoWCharTest("foo %#C", wb, "foo b");
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test7/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test7/testinfo.dat
new file mode 100644
index 0000000000..647c9d80fd
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test7/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test7
+Description
+= Tests sprintf_s with wide characters
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test8/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test8/CMakeLists.txt
new file mode 100644
index 0000000000..53545c5dbf
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test8/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test8.cpp
+)
+
+add_executable(paltest_snprintf_test8
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snprintf_test8 coreclrpal)
+
+target_link_libraries(paltest_snprintf_test8
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test8/test8.cpp b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test8/test8.cpp
new file mode 100644
index 0000000000..416e357e1e
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test8/test8.cpp
@@ -0,0 +1,56 @@
+// Licensed to the .NET Foundation under one or more 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: test8.c
+**
+** Purpose: Tests sprintf_s with decimal numbers
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snprintf_s.h"
+
+/*
+ * Notes: memcmp is used, as is strlen.
+ */
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ int neg = -42;
+ int pos = 42;
+ INT64 l = 42;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoNumTest("foo %d", pos, "foo 42");
+ DoNumTest("foo %ld", 0xFFFF, "foo 65535");
+ DoNumTest("foo %hd", 0xFFFF, "foo -1");
+ DoNumTest("foo %Ld", pos, "foo 42");
+ DoI64Test("foo %I64d", l, "42", "foo 42");
+ DoNumTest("foo %3d", pos, "foo 42");
+ DoNumTest("foo %-3d", pos, "foo 42 ");
+ DoNumTest("foo %.1d", pos, "foo 42");
+ DoNumTest("foo %.3d", pos, "foo 042");
+ DoNumTest("foo %03d", pos, "foo 042");
+ DoNumTest("foo %#d", pos, "foo 42");
+ DoNumTest("foo %+d", pos, "foo +42");
+ DoNumTest("foo % d", pos, "foo 42");
+ DoNumTest("foo %+d", neg, "foo -42");
+ DoNumTest("foo % d", neg, "foo -42");
+
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test8/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test8/testinfo.dat
new file mode 100644
index 0000000000..524834e53e
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test8/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test8
+Description
+= Tests sprintf_s with decimal numbers
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test9/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test9/CMakeLists.txt
new file mode 100644
index 0000000000..33ca9db7a8
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test9/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test9.cpp
+)
+
+add_executable(paltest_snprintf_test9
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snprintf_test9 coreclrpal)
+
+target_link_libraries(paltest_snprintf_test9
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test9/test9.cpp b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test9/test9.cpp
new file mode 100644
index 0000000000..18b1cb7830
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test9/test9.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: test9.c
+**
+** Purpose: Tests sprintf_s with integer numbers
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snprintf_s.h"
+
+/*
+ * Notes: memcmp is used, as is strlen.
+ */
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ int neg = -42;
+ int pos = 42;
+ INT64 l = 42;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoNumTest("foo %i", pos, "foo 42");
+ DoNumTest("foo %li", 0xFFFF, "foo 65535");
+ DoNumTest("foo %hi", 0xFFFF, "foo -1");
+ DoNumTest("foo %Li", pos, "foo 42");
+ DoI64Test("foo %I64i", l, "42", "foo 42");
+ DoNumTest("foo %3i", pos, "foo 42");
+ DoNumTest("foo %-3i", pos, "foo 42 ");
+ DoNumTest("foo %.1i", pos, "foo 42");
+ DoNumTest("foo %.3i", pos, "foo 042");
+ DoNumTest("foo %03i", pos, "foo 042");
+ DoNumTest("foo %#i", pos, "foo 42");
+ DoNumTest("foo %+i", pos, "foo +42");
+ DoNumTest("foo % i", pos, "foo 42");
+ DoNumTest("foo %+i", neg, "foo -42");
+ DoNumTest("foo % i", neg, "foo -42");
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/c_runtime/_snprintf_s/test9/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test9/testinfo.dat
new file mode 100644
index 0000000000..7c51443a3d
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snprintf_s/test9/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test9
+Description
+= Tests sprintf_s with integer numbers
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf/CMakeLists.txt
deleted file mode 100644
index cafb9536b0..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/CMakeLists.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-add_subdirectory(test1)
-add_subdirectory(test10)
-add_subdirectory(test11)
-add_subdirectory(test12)
-add_subdirectory(test13)
-add_subdirectory(test14)
-add_subdirectory(test15)
-add_subdirectory(test16)
-add_subdirectory(test17)
-add_subdirectory(test18)
-add_subdirectory(test19)
-add_subdirectory(test2)
-add_subdirectory(test3)
-add_subdirectory(test4)
-add_subdirectory(test5)
-add_subdirectory(test6)
-add_subdirectory(test7)
-add_subdirectory(test8)
-add_subdirectory(test9)
-
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/_snwprintf.h b/src/pal/tests/palsuite/c_runtime/_snwprintf/_snwprintf.h
deleted file mode 100644
index 73bf4d6c12..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/_snwprintf.h
+++ /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.
-
-/*============================================================================
-**
-** Source: _snwprintf.h
-**
-** Purpose: Containts common testing functions for _snwprintf
-**
-**
-**==========================================================================*/
-
-#ifndef ___SNWPRINTF_H__
-#define ___SNWPRINTF_H__
-
-void DoWStrTest(WCHAR *formatstr, WCHAR *param, WCHAR *checkstr)
-{
- WCHAR buf[256] = { 0 };
-
- _snwprintf(buf, 256, formatstr, param);
-
- if (memcmp(buf, checkstr, wcslen(checkstr) * 2 + 2) != 0)
- {
- Fail("ERROR: failed to insert wide string \"%s\" into \"%s\".\n"
- "Expected \"%s\", got \"%s\".\n", convertC(param),
- convertC(formatstr), convertC(checkstr), convertC(buf));
- }
-}
-
-void DoStrTest(WCHAR *formatstr, char *param, WCHAR *checkstr)
-{
- WCHAR buf[256] = { 0 };
-
- _snwprintf(buf, 256, formatstr, param);
-
- if (memcmp(buf, checkstr, wcslen(checkstr) * 2 + 2) != 0)
- {
- Fail("ERROR: failed to insert wide string \"%s\" into \"%s\".\n"
- "Expected \"%s\", got \"%s\".\n",
- param, convertC(formatstr), convertC(checkstr), convertC(buf));
- }
-}
-
-void DoPointerTest(WCHAR *formatstr, void* param, WCHAR *checkstr1)
-{
- WCHAR buf[256] = { 0 };
-
- _snwprintf(buf, 256, formatstr, param);
- if (memcmp(buf, checkstr1, wcslen(checkstr1)*2 + 2) != 0)
- {
- Fail("ERROR: failed to insert pointer to %#p into \"%s\"\n"
- "Expected \"%s\", got \"%s\".\n", param, convertC(formatstr),
- convertC(checkstr1), convertC(buf));
- }
-}
-
-void DoCountTest(WCHAR *formatstr, int param, WCHAR *checkstr)
-{
- WCHAR buf[512] = { 0 };
- int n = -1;
-
- _snwprintf(buf, 512, formatstr, &n);
-
- if (n != param)
- {
- Fail("ERROR: Expected count parameter to resolve to %d, got %d\n",
- param, n);
- }
-
- if (memcmp(buf, checkstr, wcslen(checkstr)*2 + 2) != 0)
- {
- Fail("ERROR: Expected \"%s\" got \"%s\".\n",
- convertC(checkstr), convertC(buf));
- }
-}
-
-void DoShortCountTest(WCHAR *formatstr, int param, WCHAR *checkstr)
-{
- WCHAR buf[256] = { 0 };
- short int n = -1;
-
- _snwprintf(buf, 256, formatstr, &n);
-
- if (n != param)
- {
- Fail("ERROR: Expected count parameter to resolve to %d, got %d\n",
- param, n);
- }
-
- if (memcmp(buf, checkstr, wcslen(checkstr)*2 + 2) != 0)
- {
- Fail("ERROR: Expected \"%s\" got \"%s\".\n",
- convertC(checkstr), convertC(buf));
- }
-}
-
-void DoCharTest(WCHAR *formatstr, char param, WCHAR *checkstr)
-{
- WCHAR buf[256] = { 0 };
-
- _snwprintf(buf, 256, formatstr, param);
- if (memcmp(buf, checkstr, wcslen(checkstr)*2 + 2) != 0)
- {
- Fail("ERROR: failed to insert char \'%c\' (%d) into \"%s\"\n"
- "Expected \"%s\" got \"%s\".\n", param, param,
- convertC(formatstr), convertC(checkstr), convertC(buf));
- }
-}
-
-void DoWCharTest(WCHAR *formatstr, WCHAR param, WCHAR *checkstr)
-{
- WCHAR buf[256] = { 0 };
-
- _snwprintf(buf, 256, formatstr, param);
- if (memcmp(buf, checkstr, wcslen(checkstr)*2 + 2) != 0)
- {
- Fail("ERROR: failed to insert wide char \'%c\' (%d) into \"%s\"\n"
- "Expected \"%s\" got \"%s\".\n", (char) param, param,
- convertC(formatstr), convertC(checkstr), convertC(buf));
- }
-}
-
-void DoNumTest(WCHAR *formatstr, int value, WCHAR*checkstr)
-{
- WCHAR buf[256] = { 0 };
-
- _snwprintf(buf, 256, formatstr, value);
- if (memcmp(buf, checkstr, wcslen(checkstr)* 2 + 2) != 0)
- {
- Fail("ERROR: failed to insert %#x into \"%s\"\n"
- "Expected \"%s\" got \"%s\".\n", value, convertC(formatstr),
- convertC(checkstr), convertC(buf));
- }
-}
-
-
-void DoI64Test(WCHAR *formatstr, INT64 param, char *paramdesc,
- WCHAR *checkstr1)
-{
- WCHAR buf[256] = { 0 };
-
- _snwprintf(buf, 256, formatstr, param);
- if (memcmp(buf, checkstr1, wcslen(checkstr1)*2 + 2) != 0)
- {
- Fail("ERROR: failed to insert %s into \"%s\"\n"
- "Expected \"%s\", got \"%s\".\n", paramdesc,
- convertC(formatstr), convertC(checkstr1), convertC(buf));
- }
-}
-
-void DoDoubleTest(WCHAR *formatstr, double value, WCHAR *checkstr1,
- WCHAR *checkstr2)
-{
- WCHAR buf[256] = { 0 };
-
- _snwprintf(buf, 256, formatstr, value);
- if (memcmp(buf, checkstr1, wcslen(checkstr1)*2 + 2) != 0 &&
- memcmp(buf, checkstr2, wcslen(checkstr2)*2 + 2) != 0)
- {
- Fail("ERROR: failed to insert %f into \"%s\"\n"
- "Expected \"%s\" or \"%s\", got \"%s\".\n",
- value, convertC(formatstr), convertC(checkstr1),
- convertC(checkstr2), convertC(buf));
- }
-}
-
-void DoArgumentPrecTest(WCHAR *formatstr, int precision, void *param,
- char *paramstr, WCHAR *checkstr1, WCHAR *checkstr2)
-{
- WCHAR buf[256];
-
- _snwprintf(buf, 256, formatstr, precision, param);
- if (memcmp(buf, checkstr1, wcslen(checkstr1) + 2) != 0 &&
- memcmp(buf, checkstr2, wcslen(checkstr2) + 2) != 0)
- {
- Fail("ERROR: failed to insert %s into \"%s\" with precision %d\n"
- "Expected \"%s\" or \"%s\", got \"%s\".\n",
- paramstr, convertC(formatstr), precision,
- convertC(checkstr1), convertC(checkstr2) ,convertC(buf));
- }
-}
-
-void DoArgumentPrecDoubleTest(WCHAR *formatstr, int precision, double param,
- WCHAR *checkstr)
-{
- WCHAR buf[256];
-
- _snwprintf(buf, 256, formatstr, precision, param);
- if (memcmp(buf, checkstr, wcslen(checkstr) + 2) != 0)
- {
- Fail("ERROR: failed to insert %f into \"%s\" with precision %d\n"
- "Expected \"%s\", got \"%s\".\n", param, convertC(formatstr),
- precision, convertC(checkstr), convertC(buf));
- }
-}
-
-#endif
-
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf/test1/CMakeLists.txt
deleted file mode 100644
index b4ab6d5161..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test1/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test1.c
-)
-
-add_executable(paltest_snwprintf_test1
- ${SOURCES}
-)
-
-add_dependencies(paltest_snwprintf_test1 coreclrpal)
-
-target_link_libraries(paltest_snwprintf_test1
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_snwprintf/test1/test1.c
deleted file mode 100644
index 5d13aaf05d..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test1/test1.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test1.c
-**
-** Purpose: General test to see if _snwprintf works correctly
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-
-int __cdecl main(int argc, char *argv[])
-{
- WCHAR *checkstr;
- WCHAR buf[256] = { 0 };
- int ret;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
- checkstr = convert("hello world");
- _snwprintf(buf, 256, checkstr);
- if (memcmp(checkstr, buf, wcslen(checkstr)*2+2) != 0)
- {
- Fail("ERROR: Expected \"%s\", got \"%s\"\n",
- convertC(checkstr), convertC(buf));
- }
-
- _snwprintf(buf, 256, convert("xxxxxxxxxxxxxxxxx"));
- ret = _snwprintf(buf, 8, checkstr);
- if (memcmp(checkstr, buf, 16) != 0)
- {
- Fail("ERROR: Expected \"%8s\", got \"%8s\"\n",
- convertC(checkstr), convertC(buf));
- }
- if (ret >= 0)
- {
- Fail("ERROR: Expected negative return value, got %d.\n", ret);
- }
- if (buf[8] != (WCHAR) 'x')
- {
- Fail("ERROR: buffer overflow using \"%s\" with length 8.\n",
- convertC(checkstr));
- }
-
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf/test1/testinfo.dat
deleted file mode 100644
index 079a3b3989..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test1/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snwprintf
-Name = Positive Test for _snwprintf
-TYPE = DEFAULT
-EXE1 = test1
-Description
-= General test to see if _snwprintf works correctly
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test10/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf/test10/CMakeLists.txt
deleted file mode 100644
index 27aaca3bb9..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test10/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test10.c
-)
-
-add_executable(paltest_snwprintf_test10
- ${SOURCES}
-)
-
-add_dependencies(paltest_snwprintf_test10 coreclrpal)
-
-target_link_libraries(paltest_snwprintf_test10
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test10/test10.c b/src/pal/tests/palsuite/c_runtime/_snwprintf/test10/test10.c
deleted file mode 100644
index e8a6d93ea3..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test10/test10.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test10.c
-**
-** Purpose: Tests _snwprintf with octal numbers
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-int __cdecl main(int argc, char *argv[])
-{
- int neg = -42;
- int pos = 42;
- INT64 l = 42;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoNumTest(convert("foo %o"), pos, convert("foo 52"));
- DoNumTest(convert("foo %lo"), 0xFFFF, convert("foo 177777"));
- DoNumTest(convert("foo %ho"), 0xFFFF, convert("foo 177777"));
- DoNumTest(convert("foo %Lo"), pos, convert("foo 52"));
- DoI64Test(convert("foo %I64o"), l, "42", convert("foo 52"));
- DoNumTest(convert("foo %3o"), pos, convert("foo 52"));
- DoNumTest(convert("foo %-3o"), pos, convert("foo 52 "));
- DoNumTest(convert("foo %.1o"), pos, convert("foo 52"));
- DoNumTest(convert("foo %.3o"), pos, convert("foo 052"));
- DoNumTest(convert("foo %03o"), pos, convert("foo 052"));
- DoNumTest(convert("foo %#o"), pos, convert("foo 052"));
- DoNumTest(convert("foo %+o"), pos, convert("foo 52"));
- DoNumTest(convert("foo % o"), pos, convert("foo 52"));
- DoNumTest(convert("foo %+o"), neg, convert("foo 37777777726"));
- DoNumTest(convert("foo % o"), neg, convert("foo 37777777726"));
-
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test10/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf/test10/testinfo.dat
deleted file mode 100644
index 2c07cc6e45..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test10/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snwprintf
-Name = Positive Test for _snwprintf
-TYPE = DEFAULT
-EXE1 = test10
-Description
-= Tests _snwprintf with octal numbers
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test11/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf/test11/CMakeLists.txt
deleted file mode 100644
index e18ad4a31b..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test11/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test11.c
-)
-
-add_executable(paltest_snwprintf_test11
- ${SOURCES}
-)
-
-add_dependencies(paltest_snwprintf_test11 coreclrpal)
-
-target_link_libraries(paltest_snwprintf_test11
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test11/test11.c b/src/pal/tests/palsuite/c_runtime/_snwprintf/test11/test11.c
deleted file mode 100644
index 95f7f53210..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test11/test11.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test11.c
-**
-** Purpose: Tests _snwprintf with unsigned numbers
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-int __cdecl main(int argc, char *argv[])
-{
- int neg = -42;
- int pos = 42;
- INT64 l = 42;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoNumTest(convert("foo %u"), pos, convert("foo 42"));
- DoNumTest(convert("foo %lu"), 0xFFFF, convert("foo 65535"));
- DoNumTest(convert("foo %hu"), 0xFFFF, convert("foo 65535"));
- DoNumTest(convert("foo %Lu"), pos, convert("foo 42"));
- DoI64Test(convert("foo %I64u"), l, "42", convert("foo 42"));
- DoNumTest(convert("foo %3u"), pos, convert("foo 42"));
- DoNumTest(convert("foo %-3u"), pos, convert("foo 42 "));
- DoNumTest(convert("foo %.1u"), pos, convert("foo 42"));
- DoNumTest(convert("foo %.3u"), pos, convert("foo 042"));
- DoNumTest(convert("foo %03u"), pos, convert("foo 042"));
- DoNumTest(convert("foo %#u"), pos, convert("foo 42"));
- DoNumTest(convert("foo %+u"), pos, convert("foo 42"));
- DoNumTest(convert("foo % u"), pos, convert("foo 42"));
- DoNumTest(convert("foo %+u"), neg, convert("foo 4294967254"));
- DoNumTest(convert("foo % u"), neg, convert("foo 4294967254"));
-
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test11/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf/test11/testinfo.dat
deleted file mode 100644
index f81a7861bf..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test11/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snwprintf
-Name = Positive Test for _snwprintf
-TYPE = DEFAULT
-EXE1 = test11
-Description
-= Tests _snwprintf with unsigned numbers
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test12/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf/test12/CMakeLists.txt
deleted file mode 100644
index f2ae07c1b0..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test12/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test12.c
-)
-
-add_executable(paltest_snwprintf_test12
- ${SOURCES}
-)
-
-add_dependencies(paltest_snwprintf_test12 coreclrpal)
-
-target_link_libraries(paltest_snwprintf_test12
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test12/test12.c b/src/pal/tests/palsuite/c_runtime/_snwprintf/test12/test12.c
deleted file mode 100644
index ab58fa345f..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test12/test12.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test12.c
-**
-** Purpose: Tests _snwprintf with hex numbers (lowercase)
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-int __cdecl main(int argc, char *argv[])
-{
- int neg = -42;
- int pos = 0x1234ab;
- INT64 l = I64(0x1234567887654321);
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoNumTest(convert("foo %x"), pos, convert("foo 1234ab"));
- DoNumTest(convert("foo %lx"), pos, convert("foo 1234ab"));
- DoNumTest(convert("foo %hx"), pos, convert("foo 34ab"));
- DoNumTest(convert("foo %Lx"), pos, convert("foo 1234ab"));
- DoI64Test(convert("foo %I64x"), l, "0x1234567887654321",
- convert("foo 1234567887654321"));
- DoNumTest(convert("foo %7x"), pos, convert("foo 1234ab"));
- DoNumTest(convert("foo %-7x"), pos, convert("foo 1234ab "));
- DoNumTest(convert("foo %.1x"), pos, convert("foo 1234ab"));
- DoNumTest(convert("foo %.7x"), pos, convert("foo 01234ab"));
- DoNumTest(convert("foo %07x"), pos, convert("foo 01234ab"));
- DoNumTest(convert("foo %#x"), pos, convert("foo 0x1234ab"));
- DoNumTest(convert("foo %+x"), pos, convert("foo 1234ab"));
- DoNumTest(convert("foo % x"), pos, convert("foo 1234ab"));
- DoNumTest(convert("foo %+x"), neg, convert("foo ffffffd6"));
- DoNumTest(convert("foo % x"), neg, convert("foo ffffffd6"));
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test12/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf/test12/testinfo.dat
deleted file mode 100644
index 653babae84..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test12/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snwprintf
-Name = Positive Test for _snwprintf
-TYPE = DEFAULT
-EXE1 = test12
-Description
-= Tests _snwprintf with hex numbers (lowercase)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test13/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf/test13/CMakeLists.txt
deleted file mode 100644
index 42847b6bcd..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test13/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test13.c
-)
-
-add_executable(paltest_snwprintf_test13
- ${SOURCES}
-)
-
-add_dependencies(paltest_snwprintf_test13 coreclrpal)
-
-target_link_libraries(paltest_snwprintf_test13
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test13/test13.c b/src/pal/tests/palsuite/c_runtime/_snwprintf/test13/test13.c
deleted file mode 100644
index 5a3e22802d..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test13/test13.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test13.c
-**
-** Purpose: Tests _snwprintf with hex numbers (uppercase)
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-int __cdecl main(int argc, char *argv[])
-{
- int neg = -42;
- int pos = 0x1234ab;
- INT64 l = I64(0x1234567887654321);
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoNumTest(convert("foo %X"), pos, convert("foo 1234AB"));
- DoNumTest(convert("foo %lX"), pos, convert("foo 1234AB"));
- DoNumTest(convert("foo %hX"), pos, convert("foo 34AB"));
- DoNumTest(convert("foo %LX"), pos, convert("foo 1234AB"));
- DoI64Test(convert("foo %I64X"), l, "0x1234567887654321",
- convert("foo 1234567887654321"));
- DoNumTest(convert("foo %7X"), pos, convert("foo 1234AB"));
- DoNumTest(convert("foo %-7X"), pos, convert("foo 1234AB "));
- DoNumTest(convert("foo %.1X"), pos, convert("foo 1234AB"));
- DoNumTest(convert("foo %.7X"), pos, convert("foo 01234AB"));
- DoNumTest(convert("foo %07X"), pos, convert("foo 01234AB"));
- DoNumTest(convert("foo %#X"), pos, convert("foo 0X1234AB"));
- DoNumTest(convert("foo %+X"), pos, convert("foo 1234AB"));
- DoNumTest(convert("foo % X"), pos, convert("foo 1234AB"));
- DoNumTest(convert("foo %+X"), neg, convert("foo FFFFFFD6"));
- DoNumTest(convert("foo % X"), neg, convert("foo FFFFFFD6"));
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test13/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf/test13/testinfo.dat
deleted file mode 100644
index cdeced6654..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test13/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snwprintf
-Name = Positive Test for _snwprintf
-TYPE = DEFAULT
-EXE1 = test13
-Description
-= Tests _snwprintf with hex numbers (uppercase)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test14/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf/test14/CMakeLists.txt
deleted file mode 100644
index e5cdbfad87..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test14/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test14.c
-)
-
-add_executable(paltest_snwprintf_test14
- ${SOURCES}
-)
-
-add_dependencies(paltest_snwprintf_test14 coreclrpal)
-
-target_link_libraries(paltest_snwprintf_test14
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test14/test14.c b/src/pal/tests/palsuite/c_runtime/_snwprintf/test14/test14.c
deleted file mode 100644
index c34875246d..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test14/test14.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test14.c
-**
-** Purpose: Tests _snwprintf with exponential format doubles (lowercase)
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-int __cdecl main(int argc, char *argv[])
-{
- double val = 256.0;
- double neg = -256.0;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoDoubleTest(convert("foo %e"), val, convert("foo 2.560000e+002"),
- convert("foo 2.560000e+02"));
- DoDoubleTest(convert("foo %le"), val, convert("foo 2.560000e+002"),
- convert("foo 2.560000e+02"));
- DoDoubleTest(convert("foo %he"), val, convert("foo 2.560000e+002"),
- convert("foo 2.560000e+02"));
- DoDoubleTest(convert("foo %Le"), val, convert("foo 2.560000e+002"),
- convert("foo 2.560000e+02"));
- DoDoubleTest(convert("foo %I64e"), val, convert("foo 2.560000e+002"),
- convert("foo 2.560000e+02"));
- DoDoubleTest(convert("foo %14e"), val, convert("foo 2.560000e+002"),
- convert("foo 2.560000e+02"));
- DoDoubleTest(convert("foo %-14e"), val, convert("foo 2.560000e+002 "),
- convert("foo 2.560000e+02 "));
- DoDoubleTest(convert("foo %.1e"), val, convert("foo 2.6e+002"),
- convert("foo 2.6e+02"));
- DoDoubleTest(convert("foo %.8e"), val, convert("foo 2.56000000e+002"),
- convert("foo 2.56000000e+02"));
- DoDoubleTest(convert("foo %014e"), val, convert("foo 02.560000e+002"),
- convert("foo 002.560000e+02"));
- DoDoubleTest(convert("foo %#e"), val, convert("foo 2.560000e+002"),
- convert("foo 2.560000e+02"));
- DoDoubleTest(convert("foo %+e"), val, convert("foo +2.560000e+002"),
- convert("foo +2.560000e+02"));
- DoDoubleTest(convert("foo % e"), val, convert("foo 2.560000e+002"),
- convert("foo 2.560000e+02"));
- DoDoubleTest(convert("foo %+e"), neg, convert("foo -2.560000e+002"),
- convert("foo -2.560000e+02"));
- DoDoubleTest(convert("foo % e"), neg, convert("foo -2.560000e+002"),
- convert("foo -2.560000e+02"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test14/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf/test14/testinfo.dat
deleted file mode 100644
index b47611aa44..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test14/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snwprintf
-Name = Positive Test for _snwprintf
-TYPE = DEFAULT
-EXE1 = test14
-Description
-= Tests _snwprintf with exponential format doubles (lowercase)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test15/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf/test15/CMakeLists.txt
deleted file mode 100644
index dc7b4d66e9..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test15/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test15.c
-)
-
-add_executable(paltest_snwprintf_test15
- ${SOURCES}
-)
-
-add_dependencies(paltest_snwprintf_test15 coreclrpal)
-
-target_link_libraries(paltest_snwprintf_test15
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test15/test15.c b/src/pal/tests/palsuite/c_runtime/_snwprintf/test15/test15.c
deleted file mode 100644
index f45005b758..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test15/test15.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test15.c
-**
-** Purpose: Tests _snwprintf with exponential format doubles (uppercase)
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-
-int __cdecl main(int argc, char *argv[])
-{
- double val = 256.0;
- double neg = -256.0;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoDoubleTest(convert("foo %E"), val, convert("foo 2.560000E+002"),
- convert("foo 2.560000E+02"));
- DoDoubleTest(convert("foo %lE"), val, convert("foo 2.560000E+002"),
- convert("foo 2.560000E+02"));
- DoDoubleTest(convert("foo %hE"), val, convert("foo 2.560000E+002"),
- convert("foo 2.560000E+02"));
- DoDoubleTest(convert("foo %LE"), val, convert("foo 2.560000E+002"),
- convert("foo 2.560000E+02"));
- DoDoubleTest(convert("foo %I64E"), val, convert("foo 2.560000E+002"),
- convert("foo 2.560000E+02"));
- DoDoubleTest(convert("foo %14E"), val, convert("foo 2.560000E+002"),
- convert("foo 2.560000E+02"));
- DoDoubleTest(convert("foo %-14E"), val, convert("foo 2.560000E+002 "),
- convert("foo 2.560000E+02 "));
- DoDoubleTest(convert("foo %.1E"), val, convert("foo 2.6E+002"),
- convert("foo 2.6E+02"));
- DoDoubleTest(convert("foo %.8E"), val, convert("foo 2.56000000E+002"),
- convert("foo 2.56000000E+02"));
- DoDoubleTest(convert("foo %014E"), val, convert("foo 02.560000E+002"),
- convert("foo 002.560000E+02"));
- DoDoubleTest(convert("foo %#E"), val, convert("foo 2.560000E+002"),
- convert("foo 2.560000E+02"));
- DoDoubleTest(convert("foo %+E"), val, convert("foo +2.560000E+002"),
- convert("foo +2.560000E+02"));
- DoDoubleTest(convert("foo % E"), val, convert("foo 2.560000E+002"),
- convert("foo 2.560000E+02"));
- DoDoubleTest(convert("foo %+E"), neg, convert("foo -2.560000E+002"),
- convert("foo -2.560000E+02"));
- DoDoubleTest(convert("foo % E"), neg, convert("foo -2.560000E+002"),
- convert("foo -2.560000E+02"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test15/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf/test15/testinfo.dat
deleted file mode 100644
index 2c81391689..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test15/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snwprintf
-Name = Positive Test for _snwprintf
-TYPE = DEFAULT
-EXE1 = test15
-Description
-= Tests _snwprintf with exponential format doubles (uppercase)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test16/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf/test16/CMakeLists.txt
deleted file mode 100644
index f147ad7e67..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test16/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test16.c
-)
-
-add_executable(paltest_snwprintf_test16
- ${SOURCES}
-)
-
-add_dependencies(paltest_snwprintf_test16 coreclrpal)
-
-target_link_libraries(paltest_snwprintf_test16
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test16/test16.c b/src/pal/tests/palsuite/c_runtime/_snwprintf/test16/test16.c
deleted file mode 100644
index 88f55bdc10..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test16/test16.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test16.c
-**
-** Purpose: Tests _snwprintf with decimal point format doubles
-**
-**
-**==========================================================================*/
-
-
-#include <palsuite.h>
-#include "../_snwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-int __cdecl main(int argc, char *argv[])
-{
- double val = 2560.001;
- double neg = -2560.001;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoDoubleTest(convert("foo %f"), val, convert("foo 2560.001000"),
- convert("foo 2560.001000"));
- DoDoubleTest(convert("foo %lf"), val, convert("foo 2560.001000"),
- convert("foo 2560.001000"));
- DoDoubleTest(convert("foo %hf"), val, convert("foo 2560.001000"),
- convert("foo 2560.001000"));
- DoDoubleTest(convert("foo %Lf"), val, convert("foo 2560.001000"),
- convert("foo 2560.001000"));
- DoDoubleTest(convert("foo %I64f"), val, convert("foo 2560.001000"),
- convert("foo 2560.001000"));
- DoDoubleTest(convert("foo %12f"), val, convert("foo 2560.001000"),
- convert("foo 2560.001000"));
- DoDoubleTest(convert("foo %-12f"), val, convert("foo 2560.001000 "),
- convert("foo 2560.001000 "));
- DoDoubleTest(convert("foo %.1f"), val, convert("foo 2560.0"),
- convert("foo 2560.0"));
- DoDoubleTest(convert("foo %.8f"), val, convert("foo 2560.00100000"),
- convert("foo 2560.00100000"));
- DoDoubleTest(convert("foo %012f"), val, convert("foo 02560.001000"),
- convert("foo 02560.001000"));
- DoDoubleTest(convert("foo %#f"), val, convert("foo 2560.001000"),
- convert("foo 2560.001000"));
- DoDoubleTest(convert("foo %+f"), val, convert("foo +2560.001000"),
- convert("foo +2560.001000"));
- DoDoubleTest(convert("foo % f"), val, convert("foo 2560.001000"),
- convert("foo 2560.001000"));
- DoDoubleTest(convert("foo %+f"), neg, convert("foo -2560.001000"),
- convert("foo -2560.001000"));
- DoDoubleTest(convert("foo % f"), neg, convert("foo -2560.001000"),
- convert("foo -2560.001000"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test16/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf/test16/testinfo.dat
deleted file mode 100644
index 8d844e0b18..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test16/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snwprintf
-Name = Positive Test for _snwprintf
-TYPE = DEFAULT
-EXE1 = test16
-Description
-= Tests _snwprintf with decimal point format doubles
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test17/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf/test17/CMakeLists.txt
deleted file mode 100644
index e40d3f4106..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test17/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test17.c
-)
-
-add_executable(paltest_snwprintf_test17
- ${SOURCES}
-)
-
-add_dependencies(paltest_snwprintf_test17 coreclrpal)
-
-target_link_libraries(paltest_snwprintf_test17
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test17/test17.c b/src/pal/tests/palsuite/c_runtime/_snwprintf/test17/test17.c
deleted file mode 100644
index 82f2330b48..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test17/test17.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test17.c
-**
-** Purpose: Tests _snwprintf with compact format doubles (lowercase)
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-int __cdecl main(int argc, char *argv[])
-{
- double val = 2560.001;
- double neg = -2560.001;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoDoubleTest(convert("foo %g"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %lg"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %hg"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %Lg"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %I64g"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %5g"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %-5g"), val, convert("foo 2560 "),
- convert("foo 2560 "));
- DoDoubleTest(convert("foo %.1g"), val, convert("foo 3e+003"),
- convert("foo 3e+03"));
- DoDoubleTest(convert("foo %.2g"), val, convert("foo 2.6e+003"),
- convert("foo 2.6e+03"));
- DoDoubleTest(convert("foo %.12g"), val, convert("foo 2560.001"),
- convert("foo 2560.001"));
- DoDoubleTest(convert("foo %06g"), val, convert("foo 002560"),
- convert("foo 002560"));
- DoDoubleTest(convert("foo %#g"), val, convert("foo 2560.00"),
- convert("foo 2560.00"));
- DoDoubleTest(convert("foo %+g"), val, convert("foo +2560"),
- convert("foo +2560"));
- DoDoubleTest(convert("foo % g"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %+g"), neg, convert("foo -2560"),
- convert("foo -2560"));
- DoDoubleTest(convert("foo % g"), neg, convert("foo -2560"),
- convert("foo -2560"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test17/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf/test17/testinfo.dat
deleted file mode 100644
index 6b01fb3d7d..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test17/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snwprintf
-Name = Positive Test for _snwprintf
-TYPE = DEFAULT
-EXE1 = test17
-Description
-= Tests _snwprintf with compact format doubles (lowercase)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test18/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf/test18/CMakeLists.txt
deleted file mode 100644
index 68a014cb66..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test18/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test18.c
-)
-
-add_executable(paltest_snwprintf_test18
- ${SOURCES}
-)
-
-add_dependencies(paltest_snwprintf_test18 coreclrpal)
-
-target_link_libraries(paltest_snwprintf_test18
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test18/test18.c b/src/pal/tests/palsuite/c_runtime/_snwprintf/test18/test18.c
deleted file mode 100644
index dbb6233061..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test18/test18.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test18.c
-**
-** Purpose: Tests _snwprintf with compact format doubles (uppercase)
-**
-**
-**==========================================================================*/
-
-
-
-
-#include <palsuite.h>
-#include "../_snwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-int __cdecl main(int argc, char *argv[])
-{
- double val = 2560.001;
- double neg = -2560.001;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoDoubleTest(convert("foo %G"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %lG"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %hG"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %LG"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %I64G"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %5G"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %-5G"), val, convert("foo 2560 "),
- convert("foo 2560 "));
- DoDoubleTest(convert("foo %.1G"), val, convert("foo 3E+003"),
- convert("foo 3E+03"));
- DoDoubleTest(convert("foo %.2G"), val, convert("foo 2.6E+003"),
- convert("foo 2.6E+03"));
- DoDoubleTest(convert("foo %.12G"), val, convert("foo 2560.001"),
- convert("foo 2560.001"));
- DoDoubleTest(convert("foo %06G"), val, convert("foo 002560"),
- convert("foo 002560"));
- DoDoubleTest(convert("foo %#G"), val, convert("foo 2560.00"),
- convert("foo 2560.00"));
- DoDoubleTest(convert("foo %+G"), val, convert("foo +2560"),
- convert("foo +2560"));
- DoDoubleTest(convert("foo % G"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %+G"), neg, convert("foo -2560"),
- convert("foo -2560"));
- DoDoubleTest(convert("foo % G"), neg, convert("foo -2560"),
- convert("foo -2560"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test18/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf/test18/testinfo.dat
deleted file mode 100644
index 480087f560..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test18/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snwprintf
-Name = Positive Test for _snwprintf
-TYPE = DEFAULT
-EXE1 = test18
-Description
-= Tests _snwprintf with compact format doubles (uppercase)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test19/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf/test19/CMakeLists.txt
deleted file mode 100644
index 6dc30b4d33..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test19/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test19.c
-)
-
-add_executable(paltest_snwprintf_test19
- ${SOURCES}
-)
-
-add_dependencies(paltest_snwprintf_test19 coreclrpal)
-
-target_link_libraries(paltest_snwprintf_test19
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test19/test19.c b/src/pal/tests/palsuite/c_runtime/_snwprintf/test19/test19.c
deleted file mode 100644
index efb222c6ba..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test19/test19.c
+++ /dev/null
@@ -1,90 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: test19.c
-**
-** Purpose: Tests _snwprintf with argument specified precision
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snwprintf.h"
-
-int __cdecl main(int argc, char *argv[])
-{
- int n = -1;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
- DoArgumentPrecTest(convert("%.*s"), 2, convert("bar"), "bar",
- convert("ba"), convert("ba"));
- DoArgumentPrecTest(convert("%.*S"), 2, "bar", "bar",
- convert("ba"), convert("ba"));
- DoArgumentPrecTest(convert("%.*n"), 3, &n, "pointer to int",
- convert(""), convert(""));
- if (n != 0)
- {
- Fail("ERROR: Expected count parameter to resolve to %d, got %X\n",
- 0, n);
- }
-
- DoArgumentPrecTest(convert("%.*c"), 0, (void*)'a', "a",
- convert("a"), convert("a"));
- DoArgumentPrecTest(convert("%.*c"), 4, (void*)'a', "a",
- convert("a"), convert("a"));
- DoArgumentPrecTest(convert("%.*C"), 0, (void*)'a', "a",
- convert("a"), convert("a"));
- DoArgumentPrecTest(convert("%.*C"), 4, (void*)'a', "a",
- convert("a"), convert("a"));
- DoArgumentPrecTest(convert("%.*d"), 1, (void*)42, "42",
- convert("42"), convert("42"));
- DoArgumentPrecTest(convert("%.*d"), 3, (void*)42, "42",
- convert("042"), convert("042"));
- DoArgumentPrecTest(convert("%.*i"), 1, (void*)42, "42",
- convert("42"), convert("42"));
- DoArgumentPrecTest(convert("%.*i"), 3, (void*)42, "42",
- convert("042"), convert("042"));
- DoArgumentPrecTest(convert("%.*o"), 1, (void*)42, "42",
- convert("52"), convert("52"));
- DoArgumentPrecTest(convert("%.*o"), 3, (void*)42, "42",
- convert("052"), convert("052"));
- DoArgumentPrecTest(convert("%.*u"), 1, (void*)42, "42",
- convert("42"), convert("42"));
- DoArgumentPrecTest(convert("%.*u"), 3, (void*)42, "42",
- convert("042"), convert("042"));
- DoArgumentPrecTest(convert("%.*x"), 1, (void*)0x42, "0x42",
- convert("42"), convert("42"));
- DoArgumentPrecTest(convert("%.*x"), 3, (void*)0x42, "0x42",
- convert("042"), convert("042"));
- DoArgumentPrecTest(convert("%.*X"), 1, (void*)0x42, "0x42",
- convert("42"), convert("42"));
- DoArgumentPrecTest(convert("%.*X"), 3, (void*)0x42, "0x42",
- convert("042"), convert("042"));
- DoArgumentPrecDoubleTest(convert("%.*e"), 1, 2.01, convert("2.0e+000"));
- DoArgumentPrecDoubleTest(convert("%.*e"), 3, 2.01, convert("2.010e+000"));
- DoArgumentPrecDoubleTest(convert("%.*E"), 1, 2.01, convert("2.0E+000"));
- DoArgumentPrecDoubleTest(convert("%.*E"), 3, 2.01, convert("2.010E+000"));
- DoArgumentPrecDoubleTest(convert("%.*f"), 1, 2.01, convert("2.0"));
- DoArgumentPrecDoubleTest(convert("%.*f"), 3, 2.01, convert("2.010"));
- DoArgumentPrecDoubleTest(convert("%.*g"), 1, 256.01, convert("3e+002"));
- DoArgumentPrecDoubleTest(convert("%.*g"), 3, 256.01, convert("256"));
- DoArgumentPrecDoubleTest(convert("%.*g"), 4, 256.01, convert("256"));
- DoArgumentPrecDoubleTest(convert("%.*g"), 6, 256.01, convert("256.01"));
- DoArgumentPrecDoubleTest(convert("%.*G"), 1, 256.01, convert("3E+002"));
- DoArgumentPrecDoubleTest(convert("%.*G"), 3, 256.01, convert("256"));
- DoArgumentPrecDoubleTest(convert("%.*G"), 4, 256.01, convert("256"));
- DoArgumentPrecDoubleTest(convert("%.*G"), 6, 256.01, convert("256.01"));
-
- PAL_Terminate();
- return PASS;
-
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test19/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf/test19/testinfo.dat
deleted file mode 100644
index 376cbc84d1..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test19/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snwprintf
-Name = Positive Test for _snwprintf
-TYPE = DEFAULT
-EXE1 = test19
-Description
-= Tests _snwprintf with argument specified precision
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf/test2/CMakeLists.txt
deleted file mode 100644
index 9e0d950885..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test2/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test2.c
-)
-
-add_executable(paltest_snwprintf_test2
- ${SOURCES}
-)
-
-add_dependencies(paltest_snwprintf_test2 coreclrpal)
-
-target_link_libraries(paltest_snwprintf_test2
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test2/test2.c b/src/pal/tests/palsuite/c_runtime/_snwprintf/test2/test2.c
deleted file mode 100644
index 974b7967f2..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test2/test2.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test2.c
-**
-** Purpose:Tests _snwprintf with strings
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-
-int __cdecl main(int argc, char *argv[])
-{
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
- DoWStrTest(convert("foo %s"), convert("bar"), convert("foo bar"));
- DoStrTest(convert("foo %hs"), "bar", convert("foo bar"));
- DoWStrTest(convert("foo %ls"), convert("bar"), convert("foo bar"));
- DoWStrTest(convert("foo %ws"), convert("bar"), convert("foo bar"));
- DoWStrTest(convert("foo %Ls"), convert("bar"), convert("foo bar"));
- DoWStrTest(convert("foo %I64s"), convert("bar"), convert("foo bar"));
- DoWStrTest(convert("foo %5s"), convert("bar"), convert("foo bar"));
- DoWStrTest(convert("foo %.2s"), convert("bar"), convert("foo ba"));
- DoWStrTest(convert("foo %5.2s"), convert("bar"), convert("foo ba"));
- DoWStrTest(convert("foo %-5s"), convert("bar"), convert("foo bar "));
- DoWStrTest(convert("foo %05s"), convert("bar"), convert("foo 00bar"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test2/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf/test2/testinfo.dat
deleted file mode 100644
index 9c65c93e5a..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test2/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snwprintf
-Name = Positive Test for _snwprintf
-TYPE = DEFAULT
-EXE1 = test2
-Description
-= Tests _snwprintf with strings
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf/test3/CMakeLists.txt
deleted file mode 100644
index 4d5a28b0fe..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test3/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test3.c
-)
-
-add_executable(paltest_snwprintf_test3
- ${SOURCES}
-)
-
-add_dependencies(paltest_snwprintf_test3 coreclrpal)
-
-target_link_libraries(paltest_snwprintf_test3
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test3/test3.c b/src/pal/tests/palsuite/c_runtime/_snwprintf/test3/test3.c
deleted file mode 100644
index bfb75ce323..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test3/test3.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test3.c
-**
-** Purpose: Tests _snwprintf with wide strings
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-
-int __cdecl main(int argc, char *argv[])
-{
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
- DoStrTest(convert("foo %S"), "bar", convert("foo bar"));
- DoStrTest(convert("foo %hS"), "bar", convert("foo bar"));
- DoWStrTest(convert("foo %lS"), convert("bar"), convert("foo bar"));
- DoWStrTest(convert("foo %wS"), convert("bar"), convert("foo bar"));
- DoStrTest(convert("foo %LS"), "bar", convert("foo bar"));
- DoStrTest(convert("foo %I64S"), "bar", convert("foo bar"));
- DoStrTest(convert("foo %5S"), "bar", convert("foo bar"));
- DoStrTest(convert("foo %.2S"), "bar", convert("foo ba"));
- DoStrTest(convert("foo %5.2S"), "bar", convert("foo ba"));
- DoStrTest(convert("foo %-5S"), "bar", convert("foo bar "));
- DoStrTest(convert("foo %05S"), "bar", convert("foo 00bar"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test3/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf/test3/testinfo.dat
deleted file mode 100644
index b39f4f56b7..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test3/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snwprintf
-Name = Positive Test for _snwprintf
-TYPE = DEFAULT
-EXE1 = test3
-Description
-= Tests _snwprintf with wide strings
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test4/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf/test4/CMakeLists.txt
deleted file mode 100644
index 0102b0acea..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test4/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test4.c
-)
-
-add_executable(paltest_snwprintf_test4
- ${SOURCES}
-)
-
-add_dependencies(paltest_snwprintf_test4 coreclrpal)
-
-target_link_libraries(paltest_snwprintf_test4
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test4/test4.c b/src/pal/tests/palsuite/c_runtime/_snwprintf/test4/test4.c
deleted file mode 100644
index 28f7998591..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test4/test4.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test4.c
-**
-** Purpose: Tests _snwprintf with pointers
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-
-int __cdecl main(int argc, char *argv[])
-{
- void *ptr = (void*) 0x123456;
- INT64 lptr = I64(0x1234567887654321);
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-/*
-** Run only on 64 bit platforms
-*/
-#if defined(BIT64) && defined(PLATFORM_UNIX)
- Trace("Testing for 64 Bit Platforms \n");
- DoPointerTest(convert("%p"), NULL, convert("0000000000000000"));
- DoPointerTest(convert("%p"), ptr, convert("0000000000123456"));
- DoPointerTest(convert("%17p"), ptr, convert(" 0000000000123456"));
- DoPointerTest(convert("%17p"), ptr, convert(" 0000000000123456"));
- DoPointerTest(convert("%-17p"), ptr, convert("0000000000123456 "));
- DoPointerTest(convert("%+p"), ptr, convert("0000000000123456"));
- DoPointerTest(convert("% p"), ptr, convert("0000000000123456"));
- DoPointerTest(convert("%#p"), ptr, convert("0X0000000000123456"));
- DoPointerTest(convert("%lp"), ptr, convert("00123456"));
- DoPointerTest(convert("%hp"), ptr, convert("00003456"));
- DoPointerTest(convert("%Lp"), ptr, convert("00123456"));
- DoI64Test(convert("%I64p"), lptr, "1234567887654321",
- convert("1234567887654321"));
-#else
- Trace("Testing for Non 64 Bit Platforms \n");
- DoPointerTest(convert("%p"), NULL, convert("00000000"));
- DoPointerTest(convert("%p"), ptr, convert("00123456"));
- DoPointerTest(convert("%9p"), ptr, convert(" 00123456"));
- DoPointerTest(convert("%09p"), ptr, convert(" 00123456"));
- DoPointerTest(convert("%-9p"), ptr, convert("00123456 "));
- DoPointerTest(convert("%+p"), ptr, convert("00123456"));
- DoPointerTest(convert("% p"), ptr, convert("00123456"));
- DoPointerTest(convert("%#p"), ptr, convert("0X00123456"));
- DoPointerTest(convert("%lp"), ptr, convert("00123456"));
- DoPointerTest(convert("%hp"), ptr, convert("00003456"));
- DoPointerTest(convert("%Lp"), ptr, convert("00123456"));
- DoI64Test(convert("%I64p"), lptr, "1234567887654321",
- convert("1234567887654321"));
-#endif
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test4/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf/test4/testinfo.dat
deleted file mode 100644
index 3f3600160f..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test4/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snwprintf
-Name = Positive Test for _snwprintf
-TYPE = DEFAULT
-EXE1 = test4
-Description
-= Tests _snwprintf with pointers
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test5/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf/test5/CMakeLists.txt
deleted file mode 100644
index c835c94845..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test5/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test5.c
-)
-
-add_executable(paltest_snwprintf_test5
- ${SOURCES}
-)
-
-add_dependencies(paltest_snwprintf_test5 coreclrpal)
-
-target_link_libraries(paltest_snwprintf_test5
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test5/test5.c b/src/pal/tests/palsuite/c_runtime/_snwprintf/test5/test5.c
deleted file mode 100644
index bbe459751b..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test5/test5.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test5.c
-**
-** Purpose: Tests _snwprintf with the count specifier
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-int __cdecl main(int argc, char *argv[])
-{
- WCHAR *longStr;
- WCHAR *longResult;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
- longStr = convert("really-long-string-that-just-keeps-going-on-and-on-and-on.."
- "..................useless-filler.................................."
- "..................useless-filler.................................."
- "..................useless-filler.................................."
- "%n bar");
- longResult = convert("really-long-string-that-just-keeps-going-on-and-on-and-on.."
- "..................useless-filler.................................."
- "..................useless-filler.................................."
- "..................useless-filler.................................."
- " bar");
- DoCountTest(convert("foo %n bar"), 4, convert("foo bar"));
- DoCountTest(longStr, 257, longResult);
- DoCountTest(convert("fo%n bar"), 2, convert("fo bar"));
- DoCountTest(convert("%n"), 0, convert(""));
- DoCountTest(convert("foo %#n bar"), 4, convert("foo bar"));
- DoCountTest(convert("foo % n bar"), 4, convert("foo bar"));
- DoCountTest(convert("foo %+n bar"), 4, convert("foo bar"));
- DoCountTest(convert("foo %-n bar"), 4, convert("foo bar"));
- DoCountTest(convert("foo %0n bar"), 4, convert("foo bar"));
- DoShortCountTest(convert("foo %hn bar"), 4, convert("foo bar"));
- DoCountTest(convert("foo %ln bar"), 4, convert("foo bar"));
- DoCountTest(convert("foo %Ln bar"), 4, convert("foo bar"));
- DoCountTest(convert("foo %I64n bar"), 4, convert("foo bar"));
- DoCountTest(convert("foo %20.3n bar"), 4, convert("foo bar"));
-
- free(longStr);
- free(longResult);
-
- PAL_Terminate();
-
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test5/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf/test5/testinfo.dat
deleted file mode 100644
index 2180b81cf5..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test5/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snwprintf
-Name = Positive Test for _snwprintf
-TYPE = DEFAULT
-EXE1 = test5
-Description
-= Tests _snwprintf with the count specifier
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test6/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf/test6/CMakeLists.txt
deleted file mode 100644
index 37a415ed86..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test6/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test6.c
-)
-
-add_executable(paltest_snwprintf_test6
- ${SOURCES}
-)
-
-add_dependencies(paltest_snwprintf_test6 coreclrpal)
-
-target_link_libraries(paltest_snwprintf_test6
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test6/test6.c b/src/pal/tests/palsuite/c_runtime/_snwprintf/test6/test6.c
deleted file mode 100644
index 3d4ed3f882..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test6/test6.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test6.c
-**
-** Purpose: Tests _snwprintf with characters
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-int __cdecl main(int argc, char *argv[])
-{
- WCHAR wc = (WCHAR) 'c';
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoWCharTest(convert("foo %c"), wc, convert("foo c"));
- DoCharTest(convert("foo %hc"), 'b', convert("foo b"));
- DoWCharTest(convert("foo %lc"), wc, convert("foo c"));
- DoWCharTest(convert("foo %Lc"), wc, convert("foo c"));
- DoWCharTest(convert("foo %I64c"), wc, convert("foo c"));
- DoWCharTest(convert("foo %5c"), wc, convert("foo c"));
- DoWCharTest(convert("foo %.0c"), wc, convert("foo c"));
- DoWCharTest(convert("foo %-5c"), wc, convert("foo c "));
- DoWCharTest(convert("foo %05c"), wc, convert("foo 0000c"));
- DoWCharTest(convert("foo % c"), wc, convert("foo c"));
- DoWCharTest(convert("foo %#c"), wc, convert("foo c"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test6/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf/test6/testinfo.dat
deleted file mode 100644
index 6a170cd549..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test6/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snwprintf
-Name = Positive Test for _snwprintf
-TYPE = DEFAULT
-EXE1 = test6
-Description
-= Tests _snwprintf with characters
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test7/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf/test7/CMakeLists.txt
deleted file mode 100644
index b1a07eeaa4..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test7/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test7.c
-)
-
-add_executable(paltest_snwprintf_test7
- ${SOURCES}
-)
-
-add_dependencies(paltest_snwprintf_test7 coreclrpal)
-
-target_link_libraries(paltest_snwprintf_test7
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test7/test7.c b/src/pal/tests/palsuite/c_runtime/_snwprintf/test7/test7.c
deleted file mode 100644
index 7954ff71ca..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test7/test7.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test7.c
-**
-** Purpose: Tests _snwprintf with wide characters
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-int __cdecl main(int argc, char *argv[])
-{
- WCHAR wc = (WCHAR) 'c';
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoCharTest(convert("foo %C"), 'b', convert("foo b"));
- DoWCharTest(convert("foo %hC"), wc, convert("foo c"));
- DoCharTest(convert("foo %lC"), 'b', convert("foo b"));
- DoCharTest(convert("foo %LC"), 'b', convert("foo b"));
- DoCharTest(convert("foo %I64C"), 'b', convert("foo b"));
- DoCharTest(convert("foo %5C"), 'b', convert("foo b"));
- DoCharTest(convert("foo %.0C"), 'b', convert("foo b"));
- DoCharTest(convert("foo %-5C"), 'b', convert("foo b "));
- DoCharTest(convert("foo %05C"), 'b', convert("foo 0000b"));
- DoCharTest(convert("foo % C"), 'b', convert("foo b"));
- DoCharTest(convert("foo %#C"), 'b', convert("foo b"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test7/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf/test7/testinfo.dat
deleted file mode 100644
index 5749539e3f..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test7/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snwprintf
-Name = Positive Test for _snwprintf
-TYPE = DEFAULT
-EXE1 = test7
-Description
-= Tests _snwprintf with wide characters
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test8/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf/test8/CMakeLists.txt
deleted file mode 100644
index 063ee2b9b6..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test8/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test8.c
-)
-
-add_executable(paltest_snwprintf_test8
- ${SOURCES}
-)
-
-add_dependencies(paltest_snwprintf_test8 coreclrpal)
-
-target_link_libraries(paltest_snwprintf_test8
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test8/test8.c b/src/pal/tests/palsuite/c_runtime/_snwprintf/test8/test8.c
deleted file mode 100644
index 91c2820076..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test8/test8.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test8.c
-**
-** Purpose: Tests _snwprintf with decimal numbers
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-int __cdecl main(int argc, char *argv[])
-{
- int neg = -42;
- int pos = 42;
- INT64 l = 42;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoNumTest(convert("foo %d"), pos, convert("foo 42"));
- DoNumTest(convert("foo %ld"), 0xFFFF, convert("foo 65535"));
- DoNumTest(convert("foo %hd"), 0xFFFF, convert("foo -1"));
- DoNumTest(convert("foo %Ld"), pos, convert("foo 42"));
- DoI64Test(convert("foo %I64d"), l, "42", convert("foo 42"));
- DoNumTest(convert("foo %3d"), pos, convert("foo 42"));
- DoNumTest(convert("foo %-3d"), pos, convert("foo 42 "));
- DoNumTest(convert("foo %.1d"), pos, convert("foo 42"));
- DoNumTest(convert("foo %.3d"), pos, convert("foo 042"));
- DoNumTest(convert("foo %03d"), pos, convert("foo 042"));
- DoNumTest(convert("foo %#d"), pos, convert("foo 42"));
- DoNumTest(convert("foo %+d"), pos, convert("foo +42"));
- DoNumTest(convert("foo % d"), pos, convert("foo 42"));
- DoNumTest(convert("foo %+d"), neg, convert("foo -42"));
- DoNumTest(convert("foo % d"), neg, convert("foo -42"));
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test8/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf/test8/testinfo.dat
deleted file mode 100644
index 6398f60183..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test8/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snwprintf
-Name = Positive Test for _snwprintf
-TYPE = DEFAULT
-EXE1 = test8
-Description
-= Tests _snwprintf with decimal numbers
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test9/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf/test9/CMakeLists.txt
deleted file mode 100644
index 8d5e41131d..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test9/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test9.c
-)
-
-add_executable(paltest_snwprintf_test9
- ${SOURCES}
-)
-
-add_dependencies(paltest_snwprintf_test9 coreclrpal)
-
-target_link_libraries(paltest_snwprintf_test9
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test9/test9.c b/src/pal/tests/palsuite/c_runtime/_snwprintf/test9/test9.c
deleted file mode 100644
index f8f994fdcc..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test9/test9.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test9.c
-**
-** Purpose: Tests _snwprintf with integer numbers
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../_snwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-int __cdecl main(int argc, char *argv[])
-{
- int neg = -42;
- int pos = 42;
- INT64 l = 42;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoNumTest(convert("foo %i"), pos, convert("foo 42"));
- DoNumTest(convert("foo %li"), 0xFFFF, convert("foo 65535"));
- DoNumTest(convert("foo %hi"), 0xFFFF, convert("foo -1"));
- DoNumTest(convert("foo %Li"), pos, convert("foo 42"));
- DoI64Test(convert("foo %I64i"), l, "42", convert("foo 42"));
- DoNumTest(convert("foo %3i"), pos, convert("foo 42"));
- DoNumTest(convert("foo %-3i"), pos, convert("foo 42 "));
- DoNumTest(convert("foo %.1i"), pos, convert("foo 42"));
- DoNumTest(convert("foo %.3i"), pos, convert("foo 042"));
- DoNumTest(convert("foo %03i"), pos, convert("foo 042"));
- DoNumTest(convert("foo %#i"), pos, convert("foo 42"));
- DoNumTest(convert("foo %+i"), pos, convert("foo +42"));
- DoNumTest(convert("foo % i"), pos, convert("foo 42"));
- DoNumTest(convert("foo %+i"), neg, convert("foo -42"));
- DoNumTest(convert("foo % i"), neg, convert("foo -42"));
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf/test9/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf/test9/testinfo.dat
deleted file mode 100644
index 287de4a9e9..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_snwprintf/test9/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _snwprintf
-Name = Positive Test for _snwprintf
-TYPE = DEFAULT
-EXE1 = test9
-Description
-= Tests _snwprintf with integer numbers
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/CMakeLists.txt
new file mode 100644
index 0000000000..8fe1cb60ac
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/CMakeLists.txt
@@ -0,0 +1,21 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test10)
+add_subdirectory(test11)
+add_subdirectory(test12)
+add_subdirectory(test13)
+add_subdirectory(test14)
+add_subdirectory(test15)
+add_subdirectory(test16)
+add_subdirectory(test17)
+add_subdirectory(test18)
+add_subdirectory(test19)
+add_subdirectory(test2)
+add_subdirectory(test3)
+add_subdirectory(test4)
+add_subdirectory(test6)
+add_subdirectory(test7)
+add_subdirectory(test8)
+add_subdirectory(test9)
+
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/_snwprintf_s.h b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/_snwprintf_s.h
new file mode 100644
index 0000000000..19d192114b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/_snwprintf_s.h
@@ -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.
+
+/*============================================================================
+**
+** Source: swprintf_s.h
+**
+** Purpose: Containts common testing functions for swprintf_s
+**
+**
+**==========================================================================*/
+
+#ifndef ___SNWPRINTF_H__
+#define ___SNWPRINTF_H__
+
+void DoWStrTest(const WCHAR *formatstr, WCHAR *param, const WCHAR *checkstr)
+{
+ WCHAR buf[256] = { 0 };
+
+ _snwprintf_s(buf, 256, _TRUNCATE, formatstr, param);
+
+ if (memcmp(buf, checkstr, wcslen(checkstr) * 2 + 2) != 0)
+ {
+ Fail("ERROR: failed to insert wide string \"%s\" into \"%s\".\n"
+ "Expected \"%s\", got \"%s\".\n", convertC(param),
+ convertC(formatstr), convertC(checkstr), convertC(buf));
+ }
+}
+
+void DoStrTest(const WCHAR *formatstr, char *param, const WCHAR *checkstr)
+{
+ WCHAR buf[256] = { 0 };
+
+ _snwprintf_s(buf, 256, _TRUNCATE, formatstr, param);
+
+ if (memcmp(buf, checkstr, wcslen(checkstr) * 2 + 2) != 0)
+ {
+ Fail("ERROR: failed to insert wide string \"%s\" into \"%s\".\n"
+ "Expected \"%s\", got \"%s\".\n",
+ param, convertC(formatstr), convertC(checkstr), convertC(buf));
+ }
+}
+
+void DoPointerTest(const WCHAR *formatstr, void* param, const WCHAR *checkstr1)
+{
+ WCHAR buf[256] = { 0 };
+
+ _snwprintf_s(buf, 256, _TRUNCATE, formatstr, param);
+ if (memcmp(buf, checkstr1, wcslen(checkstr1)*2 + 2) != 0)
+ {
+ Fail("ERROR: failed to insert pointer to %#p into \"%s\"\n"
+ "Expected \"%s\", got \"%s\".\n", param, convertC(formatstr),
+ convertC(checkstr1), convertC(buf));
+ }
+}
+
+void DoCountTest(const WCHAR *formatstr, int param, const WCHAR *checkstr)
+{
+ WCHAR buf[512] = { 0 };
+ int n = -1;
+
+ swprintf_s(buf, 512, formatstr, &n);
+
+ if (n != param)
+ {
+ Fail("ERROR: Expected count parameter to resolve to %d, got %d\n",
+ param, n);
+ }
+
+ if (memcmp(buf, checkstr, wcslen(checkstr)*2 + 2) != 0)
+ {
+ Fail("ERROR: Expected \"%s\" got \"%s\".\n",
+ convertC(checkstr), convertC(buf));
+ }
+}
+
+void DoShortCountTest(const WCHAR *formatstr, int param, const WCHAR *checkstr)
+{
+ WCHAR buf[256] = { 0 };
+ short int n = -1;
+
+ _snwprintf_s(buf, 256, _TRUNCATE, formatstr, &n);
+
+ if (n != param)
+ {
+ Fail("ERROR: Expected count parameter to resolve to %d, got %d\n",
+ param, n);
+ }
+
+ if (memcmp(buf, checkstr, wcslen(checkstr)*2 + 2) != 0)
+ {
+ Fail("ERROR: Expected \"%s\" got \"%s\".\n",
+ convertC(checkstr), convertC(buf));
+ }
+}
+
+void DoCharTest(const WCHAR *formatstr, char param, const WCHAR *checkstr)
+{
+ WCHAR buf[256] = { 0 };
+
+ _snwprintf_s(buf, 256, _TRUNCATE, formatstr, param);
+ if (memcmp(buf, checkstr, wcslen(checkstr)*2 + 2) != 0)
+ {
+ Fail("ERROR: failed to insert char \'%c\' (%d) into \"%s\"\n"
+ "Expected \"%s\" got \"%s\".\n", param, param,
+ convertC(formatstr), convertC(checkstr), convertC(buf));
+ }
+}
+
+void DoWCharTest(const WCHAR *formatstr, WCHAR param, const WCHAR *checkstr)
+{
+ WCHAR buf[256] = { 0 };
+
+ _snwprintf_s(buf, 256, _TRUNCATE, formatstr, param);
+ if (memcmp(buf, checkstr, wcslen(checkstr)*2 + 2) != 0)
+ {
+ Fail("ERROR: failed to insert wide char \'%c\' (%d) into \"%s\"\n"
+ "Expected \"%s\" got \"%s\".\n", (char) param, param,
+ convertC(formatstr), convertC(checkstr), convertC(buf));
+ }
+}
+
+void DoNumTest(const WCHAR *formatstr, int value, const WCHAR *checkstr)
+{
+ WCHAR buf[256] = { 0 };
+
+ _snwprintf_s(buf, 256, _TRUNCATE, formatstr, value);
+ if (memcmp(buf, checkstr, wcslen(checkstr)* 2 + 2) != 0)
+ {
+ Fail("ERROR: failed to insert %#x into \"%s\"\n"
+ "Expected \"%s\" got \"%s\".\n", value, convertC(formatstr),
+ convertC(checkstr), convertC(buf));
+ }
+}
+
+
+void DoI64Test(const WCHAR *formatstr, INT64 param, char *paramdesc,
+ const WCHAR *checkstr1)
+{
+ WCHAR buf[256] = { 0 };
+
+ _snwprintf_s(buf, 256, _TRUNCATE, formatstr, param);
+ if (memcmp(buf, checkstr1, wcslen(checkstr1)*2 + 2) != 0)
+ {
+ Fail("ERROR: failed to insert %s into \"%s\"\n"
+ "Expected \"%s\", got \"%s\".\n", paramdesc,
+ convertC(formatstr), convertC(checkstr1), convertC(buf));
+ }
+}
+
+void DoDoubleTest(const WCHAR *formatstr, double value, const WCHAR *checkstr1,
+ const WCHAR *checkstr2)
+{
+ WCHAR buf[256] = { 0 };
+
+ _snwprintf_s(buf, 256, _TRUNCATE, formatstr, value);
+ if (memcmp(buf, checkstr1, wcslen(checkstr1)*2 + 2) != 0 &&
+ memcmp(buf, checkstr2, wcslen(checkstr2)*2 + 2) != 0)
+ {
+ Fail("ERROR: failed to insert %f into \"%s\"\n"
+ "Expected \"%s\" or \"%s\", got \"%s\".\n",
+ value, convertC(formatstr), convertC(checkstr1),
+ convertC(checkstr2), convertC(buf));
+ }
+}
+
+void DoArgumentPrecTest(const WCHAR *formatstr, int precision, void *param,
+ char *paramstr, const WCHAR *checkstr1, const WCHAR *checkstr2)
+{
+ WCHAR buf[256];
+
+ _snwprintf_s(buf, 256, _TRUNCATE, formatstr, precision, param);
+ if (memcmp(buf, checkstr1, wcslen(checkstr1) + 2) != 0 &&
+ memcmp(buf, checkstr2, wcslen(checkstr2) + 2) != 0)
+ {
+ Fail("ERROR: failed to insert %s into \"%s\" with precision %d\n"
+ "Expected \"%s\" or \"%s\", got \"%s\".\n",
+ paramstr, convertC(formatstr), precision,
+ convertC(checkstr1), convertC(checkstr2) ,convertC(buf));
+ }
+}
+
+void DoArgumentPrecDoubleTest(const WCHAR *formatstr, int precision, double param,
+ const WCHAR *checkstr)
+{
+ WCHAR buf[256];
+
+ _snwprintf_s(buf, 256, _TRUNCATE, formatstr, precision, param);
+ if (memcmp(buf, checkstr, wcslen(checkstr) + 2) != 0)
+ {
+ Fail("ERROR: failed to insert %f into \"%s\" with precision %d\n"
+ "Expected \"%s\", got \"%s\".\n", param, convertC(formatstr),
+ precision, convertC(checkstr), convertC(buf));
+ }
+}
+
+#endif
+
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test1/CMakeLists.txt
new file mode 100644
index 0000000000..eac86f30e4
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.cpp
+)
+
+add_executable(paltest_snwprintf_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snwprintf_test1 coreclrpal)
+
+target_link_libraries(paltest_snwprintf_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test1/test1.cpp b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test1/test1.cpp
new file mode 100644
index 0000000000..ba85103cb1
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test1/test1.cpp
@@ -0,0 +1,62 @@
+// Licensed to the .NET Foundation under one or more 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: test1.c
+**
+** Purpose: General test to see if swprintf_s works correctly
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ WCHAR *checkstr;
+ WCHAR buf[256] = { 0 };
+ int ret;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ checkstr = convert("hello world");
+ _snwprintf_s(buf, 256, _TRUNCATE, checkstr);
+ if (memcmp(checkstr, buf, wcslen(checkstr)*2+2) != 0)
+ {
+ Fail("ERROR: Expected \"%s\", got \"%s\"\n",
+ convertC(checkstr), convertC(buf));
+ }
+
+ _snwprintf_s(buf, 256, _TRUNCATE, convert("xxxxxxxxxxxxxxxxx"));
+ ret = _snwprintf_s(buf, 8, _TRUNCATE, checkstr);
+ if ((memcmp(checkstr, buf, 14) != 0) || (buf[7] != 0))
+ {
+ Fail("ERROR: Expected \"%8s\", got \"%8s\"\n",
+ convertC(checkstr), convertC(buf));
+ }
+ if (ret >= 0)
+ {
+ Fail("ERROR: Expected negative return value, got %d.\n", ret);
+ }
+ if (buf[8] != (WCHAR) 'x')
+ {
+ Fail("ERROR: buffer overflow using \"%s\" with length 8.\n",
+ convertC(checkstr));
+ }
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test1/testinfo.dat
new file mode 100644
index 0000000000..96d7914ce0
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/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 = C Runtime
+Function = swprintf_s
+Name = Positive Test for swprintf_s
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= General test to see if swprintf_s works correctly
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test10/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test10/CMakeLists.txt
new file mode 100644
index 0000000000..82ee739587
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test10/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test10.cpp
+)
+
+add_executable(paltest_snwprintf_test10
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snwprintf_test10 coreclrpal)
+
+target_link_libraries(paltest_snwprintf_test10
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test10/test10.cpp b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test10/test10.cpp
new file mode 100644
index 0000000000..298f82b002
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test10/test10.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test10.c
+**
+** Purpose: Tests swprintf_s with octal numbers
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+int __cdecl main(int argc, char *argv[])
+{
+ int neg = -42;
+ int pos = 42;
+ INT64 l = 42;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoNumTest(convert("foo %o"), pos, convert("foo 52"));
+ DoNumTest(convert("foo %lo"), 0xFFFF, convert("foo 177777"));
+ DoNumTest(convert("foo %ho"), 0xFFFF, convert("foo 177777"));
+ DoNumTest(convert("foo %Lo"), pos, convert("foo 52"));
+ DoI64Test(convert("foo %I64o"), l, "42", convert("foo 52"));
+ DoNumTest(convert("foo %3o"), pos, convert("foo 52"));
+ DoNumTest(convert("foo %-3o"), pos, convert("foo 52 "));
+ DoNumTest(convert("foo %.1o"), pos, convert("foo 52"));
+ DoNumTest(convert("foo %.3o"), pos, convert("foo 052"));
+ DoNumTest(convert("foo %03o"), pos, convert("foo 052"));
+ DoNumTest(convert("foo %#o"), pos, convert("foo 052"));
+ DoNumTest(convert("foo %+o"), pos, convert("foo 52"));
+ DoNumTest(convert("foo % o"), pos, convert("foo 52"));
+ DoNumTest(convert("foo %+o"), neg, convert("foo 37777777726"));
+ DoNumTest(convert("foo % o"), neg, convert("foo 37777777726"));
+
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test10/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test10/testinfo.dat
new file mode 100644
index 0000000000..887bbf76c8
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test10/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 = C Runtime
+Function = swprintf_s
+Name = Positive Test for swprintf_s
+TYPE = DEFAULT
+EXE1 = test10
+Description
+= Tests swprintf_s with octal numbers
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test11/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test11/CMakeLists.txt
new file mode 100644
index 0000000000..f7d7845571
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test11/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test11.cpp
+)
+
+add_executable(paltest_snwprintf_test11
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snwprintf_test11 coreclrpal)
+
+target_link_libraries(paltest_snwprintf_test11
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test11/test11.cpp b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test11/test11.cpp
new file mode 100644
index 0000000000..519668791b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test11/test11.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test11.c
+**
+** Purpose: Tests swprintf_s with unsigned numbers
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+int __cdecl main(int argc, char *argv[])
+{
+ int neg = -42;
+ int pos = 42;
+ INT64 l = 42;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoNumTest(convert("foo %u"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %lu"), 0xFFFF, convert("foo 65535"));
+ DoNumTest(convert("foo %hu"), 0xFFFF, convert("foo 65535"));
+ DoNumTest(convert("foo %Lu"), pos, convert("foo 42"));
+ DoI64Test(convert("foo %I64u"), l, "42", convert("foo 42"));
+ DoNumTest(convert("foo %3u"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %-3u"), pos, convert("foo 42 "));
+ DoNumTest(convert("foo %.1u"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %.3u"), pos, convert("foo 042"));
+ DoNumTest(convert("foo %03u"), pos, convert("foo 042"));
+ DoNumTest(convert("foo %#u"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %+u"), pos, convert("foo 42"));
+ DoNumTest(convert("foo % u"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %+u"), neg, convert("foo 4294967254"));
+ DoNumTest(convert("foo % u"), neg, convert("foo 4294967254"));
+
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test11/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test11/testinfo.dat
new file mode 100644
index 0000000000..3bda85e335
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test11/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 = C Runtime
+Function = swprintf_s
+Name = Positive Test for swprintf_s
+TYPE = DEFAULT
+EXE1 = test11
+Description
+= Tests swprintf_s with unsigned numbers
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test12/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test12/CMakeLists.txt
new file mode 100644
index 0000000000..5b926fb548
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test12/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test12.cpp
+)
+
+add_executable(paltest_snwprintf_test12
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snwprintf_test12 coreclrpal)
+
+target_link_libraries(paltest_snwprintf_test12
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test12/test12.cpp b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test12/test12.cpp
new file mode 100644
index 0000000000..52780aff0a
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test12/test12.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test12.c
+**
+** Purpose: Tests swprintf_s with hex numbers (lowercase)
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+int __cdecl main(int argc, char *argv[])
+{
+ int neg = -42;
+ int pos = 0x1234ab;
+ INT64 l = I64(0x1234567887654321);
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoNumTest(convert("foo %x"), pos, convert("foo 1234ab"));
+ DoNumTest(convert("foo %lx"), pos, convert("foo 1234ab"));
+ DoNumTest(convert("foo %hx"), pos, convert("foo 34ab"));
+ DoNumTest(convert("foo %Lx"), pos, convert("foo 1234ab"));
+ DoI64Test(convert("foo %I64x"), l, "0x1234567887654321",
+ convert("foo 1234567887654321"));
+ DoNumTest(convert("foo %7x"), pos, convert("foo 1234ab"));
+ DoNumTest(convert("foo %-7x"), pos, convert("foo 1234ab "));
+ DoNumTest(convert("foo %.1x"), pos, convert("foo 1234ab"));
+ DoNumTest(convert("foo %.7x"), pos, convert("foo 01234ab"));
+ DoNumTest(convert("foo %07x"), pos, convert("foo 01234ab"));
+ DoNumTest(convert("foo %#x"), pos, convert("foo 0x1234ab"));
+ DoNumTest(convert("foo %+x"), pos, convert("foo 1234ab"));
+ DoNumTest(convert("foo % x"), pos, convert("foo 1234ab"));
+ DoNumTest(convert("foo %+x"), neg, convert("foo ffffffd6"));
+ DoNumTest(convert("foo % x"), neg, convert("foo ffffffd6"));
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test12/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test12/testinfo.dat
new file mode 100644
index 0000000000..d808a3b8f4
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test12/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 = C Runtime
+Function = swprintf_s
+Name = Positive Test for swprintf_s
+TYPE = DEFAULT
+EXE1 = test12
+Description
+= Tests swprintf_s with hex numbers (lowercase)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test13/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test13/CMakeLists.txt
new file mode 100644
index 0000000000..52a3c75a15
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test13/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test13.cpp
+)
+
+add_executable(paltest_snwprintf_test13
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snwprintf_test13 coreclrpal)
+
+target_link_libraries(paltest_snwprintf_test13
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test13/test13.cpp b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test13/test13.cpp
new file mode 100644
index 0000000000..fa948b3a1b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test13/test13.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test13.c
+**
+** Purpose: Tests swprintf_s with hex numbers (uppercase)
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+int __cdecl main(int argc, char *argv[])
+{
+ int neg = -42;
+ int pos = 0x1234ab;
+ INT64 l = I64(0x1234567887654321);
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoNumTest(convert("foo %X"), pos, convert("foo 1234AB"));
+ DoNumTest(convert("foo %lX"), pos, convert("foo 1234AB"));
+ DoNumTest(convert("foo %hX"), pos, convert("foo 34AB"));
+ DoNumTest(convert("foo %LX"), pos, convert("foo 1234AB"));
+ DoI64Test(convert("foo %I64X"), l, "0x1234567887654321",
+ convert("foo 1234567887654321"));
+ DoNumTest(convert("foo %7X"), pos, convert("foo 1234AB"));
+ DoNumTest(convert("foo %-7X"), pos, convert("foo 1234AB "));
+ DoNumTest(convert("foo %.1X"), pos, convert("foo 1234AB"));
+ DoNumTest(convert("foo %.7X"), pos, convert("foo 01234AB"));
+ DoNumTest(convert("foo %07X"), pos, convert("foo 01234AB"));
+ DoNumTest(convert("foo %#X"), pos, convert("foo 0X1234AB"));
+ DoNumTest(convert("foo %+X"), pos, convert("foo 1234AB"));
+ DoNumTest(convert("foo % X"), pos, convert("foo 1234AB"));
+ DoNumTest(convert("foo %+X"), neg, convert("foo FFFFFFD6"));
+ DoNumTest(convert("foo % X"), neg, convert("foo FFFFFFD6"));
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test13/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test13/testinfo.dat
new file mode 100644
index 0000000000..2e5800ec31
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test13/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 = C Runtime
+Function = swprintf_s
+Name = Positive Test for swprintf_s
+TYPE = DEFAULT
+EXE1 = test13
+Description
+= Tests swprintf_s with hex numbers (uppercase)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test14/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test14/CMakeLists.txt
new file mode 100644
index 0000000000..d557a30b42
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test14/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test14.cpp
+)
+
+add_executable(paltest_snwprintf_test14
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snwprintf_test14 coreclrpal)
+
+target_link_libraries(paltest_snwprintf_test14
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test14/test14.cpp b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test14/test14.cpp
new file mode 100644
index 0000000000..aea289d1a1
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test14/test14.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test14.c
+**
+** Purpose: Tests swprintf_s with exponential format doubles (lowercase)
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+int __cdecl main(int argc, char *argv[])
+{
+ double val = 256.0;
+ double neg = -256.0;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoDoubleTest(convert("foo %e"), val, convert("foo 2.560000e+002"),
+ convert("foo 2.560000e+02"));
+ DoDoubleTest(convert("foo %le"), val, convert("foo 2.560000e+002"),
+ convert("foo 2.560000e+02"));
+ DoDoubleTest(convert("foo %he"), val, convert("foo 2.560000e+002"),
+ convert("foo 2.560000e+02"));
+ DoDoubleTest(convert("foo %Le"), val, convert("foo 2.560000e+002"),
+ convert("foo 2.560000e+02"));
+ DoDoubleTest(convert("foo %I64e"), val, convert("foo 2.560000e+002"),
+ convert("foo 2.560000e+02"));
+ DoDoubleTest(convert("foo %14e"), val, convert("foo 2.560000e+002"),
+ convert("foo 2.560000e+02"));
+ DoDoubleTest(convert("foo %-14e"), val, convert("foo 2.560000e+002 "),
+ convert("foo 2.560000e+02 "));
+ DoDoubleTest(convert("foo %.1e"), val, convert("foo 2.6e+002"),
+ convert("foo 2.6e+02"));
+ DoDoubleTest(convert("foo %.8e"), val, convert("foo 2.56000000e+002"),
+ convert("foo 2.56000000e+02"));
+ DoDoubleTest(convert("foo %014e"), val, convert("foo 02.560000e+002"),
+ convert("foo 002.560000e+02"));
+ DoDoubleTest(convert("foo %#e"), val, convert("foo 2.560000e+002"),
+ convert("foo 2.560000e+02"));
+ DoDoubleTest(convert("foo %+e"), val, convert("foo +2.560000e+002"),
+ convert("foo +2.560000e+02"));
+ DoDoubleTest(convert("foo % e"), val, convert("foo 2.560000e+002"),
+ convert("foo 2.560000e+02"));
+ DoDoubleTest(convert("foo %+e"), neg, convert("foo -2.560000e+002"),
+ convert("foo -2.560000e+02"));
+ DoDoubleTest(convert("foo % e"), neg, convert("foo -2.560000e+002"),
+ convert("foo -2.560000e+02"));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test14/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test14/testinfo.dat
new file mode 100644
index 0000000000..25bd5099c9
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test14/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 = C Runtime
+Function = swprintf_s
+Name = Positive Test for swprintf_s
+TYPE = DEFAULT
+EXE1 = test14
+Description
+= Tests swprintf_s with exponential format doubles (lowercase)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test15/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test15/CMakeLists.txt
new file mode 100644
index 0000000000..2e5ee362fc
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test15/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test15.cpp
+)
+
+add_executable(paltest_snwprintf_test15
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snwprintf_test15 coreclrpal)
+
+target_link_libraries(paltest_snwprintf_test15
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test15/test15.cpp b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test15/test15.cpp
new file mode 100644
index 0000000000..14db14b498
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test15/test15.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.
+
+/*============================================================================
+**
+** Source: test15.c
+**
+** Purpose: Tests swprintf_s with exponential format doubles (uppercase)
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ double val = 256.0;
+ double neg = -256.0;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoDoubleTest(convert("foo %E"), val, convert("foo 2.560000E+002"),
+ convert("foo 2.560000E+02"));
+ DoDoubleTest(convert("foo %lE"), val, convert("foo 2.560000E+002"),
+ convert("foo 2.560000E+02"));
+ DoDoubleTest(convert("foo %hE"), val, convert("foo 2.560000E+002"),
+ convert("foo 2.560000E+02"));
+ DoDoubleTest(convert("foo %LE"), val, convert("foo 2.560000E+002"),
+ convert("foo 2.560000E+02"));
+ DoDoubleTest(convert("foo %I64E"), val, convert("foo 2.560000E+002"),
+ convert("foo 2.560000E+02"));
+ DoDoubleTest(convert("foo %14E"), val, convert("foo 2.560000E+002"),
+ convert("foo 2.560000E+02"));
+ DoDoubleTest(convert("foo %-14E"), val, convert("foo 2.560000E+002 "),
+ convert("foo 2.560000E+02 "));
+ DoDoubleTest(convert("foo %.1E"), val, convert("foo 2.6E+002"),
+ convert("foo 2.6E+02"));
+ DoDoubleTest(convert("foo %.8E"), val, convert("foo 2.56000000E+002"),
+ convert("foo 2.56000000E+02"));
+ DoDoubleTest(convert("foo %014E"), val, convert("foo 02.560000E+002"),
+ convert("foo 002.560000E+02"));
+ DoDoubleTest(convert("foo %#E"), val, convert("foo 2.560000E+002"),
+ convert("foo 2.560000E+02"));
+ DoDoubleTest(convert("foo %+E"), val, convert("foo +2.560000E+002"),
+ convert("foo +2.560000E+02"));
+ DoDoubleTest(convert("foo % E"), val, convert("foo 2.560000E+002"),
+ convert("foo 2.560000E+02"));
+ DoDoubleTest(convert("foo %+E"), neg, convert("foo -2.560000E+002"),
+ convert("foo -2.560000E+02"));
+ DoDoubleTest(convert("foo % E"), neg, convert("foo -2.560000E+002"),
+ convert("foo -2.560000E+02"));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test15/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test15/testinfo.dat
new file mode 100644
index 0000000000..95d90e82e7
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test15/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 = C Runtime
+Function = swprintf_s
+Name = Positive Test for swprintf_s
+TYPE = DEFAULT
+EXE1 = test15
+Description
+= Tests swprintf_s with exponential format doubles (uppercase)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test16/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test16/CMakeLists.txt
new file mode 100644
index 0000000000..f4ce409dcb
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test16/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test16.cpp
+)
+
+add_executable(paltest_snwprintf_test16
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snwprintf_test16 coreclrpal)
+
+target_link_libraries(paltest_snwprintf_test16
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test16/test16.cpp b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test16/test16.cpp
new file mode 100644
index 0000000000..4d9a717f24
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test16/test16.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test16.c
+**
+** Purpose: Tests swprintf_s with decimal point format doubles
+**
+**
+**==========================================================================*/
+
+
+#include <palsuite.h>
+#include "../_snwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+int __cdecl main(int argc, char *argv[])
+{
+ double val = 2560.001;
+ double neg = -2560.001;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoDoubleTest(convert("foo %f"), val, convert("foo 2560.001000"),
+ convert("foo 2560.001000"));
+ DoDoubleTest(convert("foo %lf"), val, convert("foo 2560.001000"),
+ convert("foo 2560.001000"));
+ DoDoubleTest(convert("foo %hf"), val, convert("foo 2560.001000"),
+ convert("foo 2560.001000"));
+ DoDoubleTest(convert("foo %Lf"), val, convert("foo 2560.001000"),
+ convert("foo 2560.001000"));
+ DoDoubleTest(convert("foo %I64f"), val, convert("foo 2560.001000"),
+ convert("foo 2560.001000"));
+ DoDoubleTest(convert("foo %12f"), val, convert("foo 2560.001000"),
+ convert("foo 2560.001000"));
+ DoDoubleTest(convert("foo %-12f"), val, convert("foo 2560.001000 "),
+ convert("foo 2560.001000 "));
+ DoDoubleTest(convert("foo %.1f"), val, convert("foo 2560.0"),
+ convert("foo 2560.0"));
+ DoDoubleTest(convert("foo %.8f"), val, convert("foo 2560.00100000"),
+ convert("foo 2560.00100000"));
+ DoDoubleTest(convert("foo %012f"), val, convert("foo 02560.001000"),
+ convert("foo 02560.001000"));
+ DoDoubleTest(convert("foo %#f"), val, convert("foo 2560.001000"),
+ convert("foo 2560.001000"));
+ DoDoubleTest(convert("foo %+f"), val, convert("foo +2560.001000"),
+ convert("foo +2560.001000"));
+ DoDoubleTest(convert("foo % f"), val, convert("foo 2560.001000"),
+ convert("foo 2560.001000"));
+ DoDoubleTest(convert("foo %+f"), neg, convert("foo -2560.001000"),
+ convert("foo -2560.001000"));
+ DoDoubleTest(convert("foo % f"), neg, convert("foo -2560.001000"),
+ convert("foo -2560.001000"));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test16/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test16/testinfo.dat
new file mode 100644
index 0000000000..b81c847c69
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test16/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 = C Runtime
+Function = swprintf_s
+Name = Positive Test for swprintf_s
+TYPE = DEFAULT
+EXE1 = test16
+Description
+= Tests swprintf_s with decimal point format doubles
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test17/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test17/CMakeLists.txt
new file mode 100644
index 0000000000..159e15dafe
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test17/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test17.cpp
+)
+
+add_executable(paltest_snwprintf_test17
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snwprintf_test17 coreclrpal)
+
+target_link_libraries(paltest_snwprintf_test17
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test17/test17.cpp b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test17/test17.cpp
new file mode 100644
index 0000000000..6af1815b85
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test17/test17.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test17.c
+**
+** Purpose: Tests swprintf_s with compact format doubles (lowercase)
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+int __cdecl main(int argc, char *argv[])
+{
+ double val = 2560.001;
+ double neg = -2560.001;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoDoubleTest(convert("foo %g"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %lg"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %hg"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %Lg"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %I64g"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %5g"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %-5g"), val, convert("foo 2560 "),
+ convert("foo 2560 "));
+ DoDoubleTest(convert("foo %.1g"), val, convert("foo 3e+003"),
+ convert("foo 3e+03"));
+ DoDoubleTest(convert("foo %.2g"), val, convert("foo 2.6e+003"),
+ convert("foo 2.6e+03"));
+ DoDoubleTest(convert("foo %.12g"), val, convert("foo 2560.001"),
+ convert("foo 2560.001"));
+ DoDoubleTest(convert("foo %06g"), val, convert("foo 002560"),
+ convert("foo 002560"));
+ DoDoubleTest(convert("foo %#g"), val, convert("foo 2560.00"),
+ convert("foo 2560.00"));
+ DoDoubleTest(convert("foo %+g"), val, convert("foo +2560"),
+ convert("foo +2560"));
+ DoDoubleTest(convert("foo % g"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %+g"), neg, convert("foo -2560"),
+ convert("foo -2560"));
+ DoDoubleTest(convert("foo % g"), neg, convert("foo -2560"),
+ convert("foo -2560"));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test17/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test17/testinfo.dat
new file mode 100644
index 0000000000..d64366702a
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test17/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 = C Runtime
+Function = swprintf_s
+Name = Positive Test for swprintf_s
+TYPE = DEFAULT
+EXE1 = test17
+Description
+= Tests swprintf_s with compact format doubles (lowercase)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test18/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test18/CMakeLists.txt
new file mode 100644
index 0000000000..5964e849a4
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test18/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test18.cpp
+)
+
+add_executable(paltest_snwprintf_test18
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snwprintf_test18 coreclrpal)
+
+target_link_libraries(paltest_snwprintf_test18
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test18/test18.cpp b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test18/test18.cpp
new file mode 100644
index 0000000000..020a885090
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test18/test18.cpp
@@ -0,0 +1,69 @@
+// Licensed to the .NET Foundation under one or more 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: test18.c
+**
+** Purpose: Tests swprintf_s with compact format doubles (uppercase)
+**
+**
+**==========================================================================*/
+
+
+
+
+#include <palsuite.h>
+#include "../_snwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+int __cdecl main(int argc, char *argv[])
+{
+ double val = 2560.001;
+ double neg = -2560.001;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoDoubleTest(convert("foo %G"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %lG"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %hG"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %LG"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %I64G"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %5G"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %-5G"), val, convert("foo 2560 "),
+ convert("foo 2560 "));
+ DoDoubleTest(convert("foo %.1G"), val, convert("foo 3E+003"),
+ convert("foo 3E+03"));
+ DoDoubleTest(convert("foo %.2G"), val, convert("foo 2.6E+003"),
+ convert("foo 2.6E+03"));
+ DoDoubleTest(convert("foo %.12G"), val, convert("foo 2560.001"),
+ convert("foo 2560.001"));
+ DoDoubleTest(convert("foo %06G"), val, convert("foo 002560"),
+ convert("foo 002560"));
+ DoDoubleTest(convert("foo %#G"), val, convert("foo 2560.00"),
+ convert("foo 2560.00"));
+ DoDoubleTest(convert("foo %+G"), val, convert("foo +2560"),
+ convert("foo +2560"));
+ DoDoubleTest(convert("foo % G"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %+G"), neg, convert("foo -2560"),
+ convert("foo -2560"));
+ DoDoubleTest(convert("foo % G"), neg, convert("foo -2560"),
+ convert("foo -2560"));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test18/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test18/testinfo.dat
new file mode 100644
index 0000000000..dfc2cd5f43
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test18/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 = C Runtime
+Function = swprintf_s
+Name = Positive Test for swprintf_s
+TYPE = DEFAULT
+EXE1 = test18
+Description
+= Tests swprintf_s with compact format doubles (uppercase)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test19/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test19/CMakeLists.txt
new file mode 100644
index 0000000000..5d84847ec1
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test19/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test19.cpp
+)
+
+add_executable(paltest_snwprintf_test19
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snwprintf_test19 coreclrpal)
+
+target_link_libraries(paltest_snwprintf_test19
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test19/test19.cpp b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test19/test19.cpp
new file mode 100644
index 0000000000..d335d1d10c
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test19/test19.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test19.c
+**
+** Purpose: Tests swprintf_s with argument specified precision
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snwprintf_s.h"
+
+int __cdecl main(int argc, char *argv[])
+{
+ int n = -1;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ DoArgumentPrecTest(convert("%.*s"), 2, (void*)convert("bar"), "bar",
+ convert("ba"), convert("ba"));
+ DoArgumentPrecTest(convert("%.*S"), 2, (void*)"bar", "bar",
+ convert("ba"), convert("ba"));
+ DoArgumentPrecTest(convert("%.*c"), 0, (void*)'a', "a",
+ convert("a"), convert("a"));
+ DoArgumentPrecTest(convert("%.*c"), 4, (void*)'a', "a",
+ convert("a"), convert("a"));
+ DoArgumentPrecTest(convert("%.*C"), 0, (void*)'a', "a",
+ convert("a"), convert("a"));
+ DoArgumentPrecTest(convert("%.*C"), 4, (void*)'a', "a",
+ convert("a"), convert("a"));
+ DoArgumentPrecTest(convert("%.*d"), 1, (void*)42, "42",
+ convert("42"), convert("42"));
+ DoArgumentPrecTest(convert("%.*d"), 3, (void*)42, "42",
+ convert("042"), convert("042"));
+ DoArgumentPrecTest(convert("%.*i"), 1, (void*)42, "42",
+ convert("42"), convert("42"));
+ DoArgumentPrecTest(convert("%.*i"), 3, (void*)42, "42",
+ convert("042"), convert("042"));
+ DoArgumentPrecTest(convert("%.*o"), 1, (void*)42, "42",
+ convert("52"), convert("52"));
+ DoArgumentPrecTest(convert("%.*o"), 3, (void*)42, "42",
+ convert("052"), convert("052"));
+ DoArgumentPrecTest(convert("%.*u"), 1, (void*)42, "42",
+ convert("42"), convert("42"));
+ DoArgumentPrecTest(convert("%.*u"), 3, (void*)42, "42",
+ convert("042"), convert("042"));
+ DoArgumentPrecTest(convert("%.*x"), 1, (void*)0x42, "0x42",
+ convert("42"), convert("42"));
+ DoArgumentPrecTest(convert("%.*x"), 3, (void*)0x42, "0x42",
+ convert("042"), convert("042"));
+ DoArgumentPrecTest(convert("%.*X"), 1, (void*)0x42, "0x42",
+ convert("42"), convert("42"));
+ DoArgumentPrecTest(convert("%.*X"), 3, (void*)0x42, "0x42",
+ convert("042"), convert("042"));
+ DoArgumentPrecDoubleTest(convert("%.*e"), 1, 2.01, convert("2.0e+000"));
+ DoArgumentPrecDoubleTest(convert("%.*e"), 3, 2.01, convert("2.010e+000"));
+ DoArgumentPrecDoubleTest(convert("%.*E"), 1, 2.01, convert("2.0E+000"));
+ DoArgumentPrecDoubleTest(convert("%.*E"), 3, 2.01, convert("2.010E+000"));
+ DoArgumentPrecDoubleTest(convert("%.*f"), 1, 2.01, convert("2.0"));
+ DoArgumentPrecDoubleTest(convert("%.*f"), 3, 2.01, convert("2.010"));
+ DoArgumentPrecDoubleTest(convert("%.*g"), 1, 256.01, convert("3e+002"));
+ DoArgumentPrecDoubleTest(convert("%.*g"), 3, 256.01, convert("256"));
+ DoArgumentPrecDoubleTest(convert("%.*g"), 4, 256.01, convert("256"));
+ DoArgumentPrecDoubleTest(convert("%.*g"), 6, 256.01, convert("256.01"));
+ DoArgumentPrecDoubleTest(convert("%.*G"), 1, 256.01, convert("3E+002"));
+ DoArgumentPrecDoubleTest(convert("%.*G"), 3, 256.01, convert("256"));
+ DoArgumentPrecDoubleTest(convert("%.*G"), 4, 256.01, convert("256"));
+ DoArgumentPrecDoubleTest(convert("%.*G"), 6, 256.01, convert("256.01"));
+
+ PAL_Terminate();
+ return PASS;
+
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test19/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test19/testinfo.dat
new file mode 100644
index 0000000000..95269cdd39
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test19/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 = C Runtime
+Function = swprintf_s
+Name = Positive Test for swprintf_s
+TYPE = DEFAULT
+EXE1 = test19
+Description
+= Tests swprintf_s with argument specified precision
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test2/CMakeLists.txt
new file mode 100644
index 0000000000..ea33d48bd5
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test2.cpp
+)
+
+add_executable(paltest_snwprintf_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snwprintf_test2 coreclrpal)
+
+target_link_libraries(paltest_snwprintf_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test2/test2.cpp b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test2/test2.cpp
new file mode 100644
index 0000000000..86bfdc9839
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test2/test2.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test2.c
+**
+** Purpose:Tests swprintf_s with strings
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ DoWStrTest(convert("foo %s"), convert("bar"), convert("foo bar"));
+ DoStrTest(convert("foo %hs"), "bar", convert("foo bar"));
+ DoWStrTest(convert("foo %ls"), convert("bar"), convert("foo bar"));
+ DoWStrTest(convert("foo %ws"), convert("bar"), convert("foo bar"));
+ DoWStrTest(convert("foo %Ls"), convert("bar"), convert("foo bar"));
+ DoWStrTest(convert("foo %I64s"), convert("bar"), convert("foo bar"));
+ DoWStrTest(convert("foo %5s"), convert("bar"), convert("foo bar"));
+ DoWStrTest(convert("foo %.2s"), convert("bar"), convert("foo ba"));
+ DoWStrTest(convert("foo %5.2s"), convert("bar"), convert("foo ba"));
+ DoWStrTest(convert("foo %-5s"), convert("bar"), convert("foo bar "));
+ DoWStrTest(convert("foo %05s"), convert("bar"), convert("foo 00bar"));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test2/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test2/testinfo.dat
new file mode 100644
index 0000000000..88f1981609
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test2/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 = C Runtime
+Function = swprintf_s
+Name = Positive Test for swprintf_s
+TYPE = DEFAULT
+EXE1 = test2
+Description
+= Tests swprintf_s with strings
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test3/CMakeLists.txt
new file mode 100644
index 0000000000..5095b1a12e
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test3/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test3.cpp
+)
+
+add_executable(paltest_snwprintf_test3
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snwprintf_test3 coreclrpal)
+
+target_link_libraries(paltest_snwprintf_test3
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test3/test3.cpp b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test3/test3.cpp
new file mode 100644
index 0000000000..f6db6f265d
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test3/test3.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test3.c
+**
+** Purpose: Tests swprintf_s with wide strings
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ DoStrTest(convert("foo %S"), "bar", convert("foo bar"));
+ DoStrTest(convert("foo %hS"), "bar", convert("foo bar"));
+ DoWStrTest(convert("foo %lS"), convert("bar"), convert("foo bar"));
+ DoWStrTest(convert("foo %wS"), convert("bar"), convert("foo bar"));
+ DoStrTest(convert("foo %LS"), "bar", convert("foo bar"));
+ DoStrTest(convert("foo %I64S"), "bar", convert("foo bar"));
+ DoStrTest(convert("foo %5S"), "bar", convert("foo bar"));
+ DoStrTest(convert("foo %.2S"), "bar", convert("foo ba"));
+ DoStrTest(convert("foo %5.2S"), "bar", convert("foo ba"));
+ DoStrTest(convert("foo %-5S"), "bar", convert("foo bar "));
+ DoStrTest(convert("foo %05S"), "bar", convert("foo 00bar"));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test3/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test3/testinfo.dat
new file mode 100644
index 0000000000..5ed59e61ac
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test3/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 = C Runtime
+Function = swprintf_s
+Name = Positive Test for swprintf_s
+TYPE = DEFAULT
+EXE1 = test3
+Description
+= Tests swprintf_s with wide strings
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test4/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test4/CMakeLists.txt
new file mode 100644
index 0000000000..9cf81ea1bd
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test4/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test4.cpp
+)
+
+add_executable(paltest_snwprintf_test4
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snwprintf_test4 coreclrpal)
+
+target_link_libraries(paltest_snwprintf_test4
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test4/test4.cpp b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test4/test4.cpp
new file mode 100644
index 0000000000..02d4781bd3
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test4/test4.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test4.c
+**
+** Purpose: Tests swprintf_s with pointers
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ void *ptr = (void*) 0x123456;
+ INT64 lptr = I64(0x1234567887654321);
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+/*
+** Run only on 64 bit platforms
+*/
+#if defined(BIT64) && defined(PLATFORM_UNIX)
+ Trace("Testing for 64 Bit Platforms \n");
+ DoPointerTest(convert("%p"), NULL, convert("0000000000000000"));
+ DoPointerTest(convert("%p"), ptr, convert("0000000000123456"));
+ DoPointerTest(convert("%17p"), ptr, convert(" 0000000000123456"));
+ DoPointerTest(convert("%17p"), ptr, convert(" 0000000000123456"));
+ DoPointerTest(convert("%-17p"), ptr, convert("0000000000123456 "));
+ DoPointerTest(convert("%+p"), ptr, convert("0000000000123456"));
+ DoPointerTest(convert("% p"), ptr, convert("0000000000123456"));
+ DoPointerTest(convert("%#p"), ptr, convert("0X0000000000123456"));
+ DoPointerTest(convert("%lp"), ptr, convert("00123456"));
+ DoPointerTest(convert("%hp"), ptr, convert("00003456"));
+ DoPointerTest(convert("%Lp"), ptr, convert("00123456"));
+ DoI64Test(convert("%I64p"), lptr, "1234567887654321",
+ convert("1234567887654321"));
+#else
+ Trace("Testing for Non 64 Bit Platforms \n");
+ DoPointerTest(convert("%p"), NULL, convert("00000000"));
+ DoPointerTest(convert("%p"), ptr, convert("00123456"));
+ DoPointerTest(convert("%9p"), ptr, convert(" 00123456"));
+ DoPointerTest(convert("%09p"), ptr, convert(" 00123456"));
+ DoPointerTest(convert("%-9p"), ptr, convert("00123456 "));
+ DoPointerTest(convert("%+p"), ptr, convert("00123456"));
+ DoPointerTest(convert("% p"), ptr, convert("00123456"));
+ DoPointerTest(convert("%#p"), ptr, convert("0X00123456"));
+ DoPointerTest(convert("%lp"), ptr, convert("00123456"));
+ DoPointerTest(convert("%hp"), ptr, convert("00003456"));
+ DoPointerTest(convert("%Lp"), ptr, convert("00123456"));
+ DoI64Test(convert("%I64p"), lptr, "1234567887654321",
+ convert("1234567887654321"));
+#endif
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test4/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test4/testinfo.dat
new file mode 100644
index 0000000000..2b35f2d0d3
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test4/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 = C Runtime
+Function = swprintf_s
+Name = Positive Test for swprintf_s
+TYPE = DEFAULT
+EXE1 = test4
+Description
+= Tests swprintf_s with pointers
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test6/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test6/CMakeLists.txt
new file mode 100644
index 0000000000..4996c7716f
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test6/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test6.cpp
+)
+
+add_executable(paltest_snwprintf_test6
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snwprintf_test6 coreclrpal)
+
+target_link_libraries(paltest_snwprintf_test6
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test6/test6.cpp b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test6/test6.cpp
new file mode 100644
index 0000000000..576e061acd
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test6/test6.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test6.c
+**
+** Purpose: Tests swprintf_s with characters
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+int __cdecl main(int argc, char *argv[])
+{
+ WCHAR wc = (WCHAR) 'c';
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoWCharTest(convert("foo %c"), wc, convert("foo c"));
+ DoCharTest(convert("foo %hc"), 'b', convert("foo b"));
+ DoWCharTest(convert("foo %lc"), wc, convert("foo c"));
+ DoWCharTest(convert("foo %Lc"), wc, convert("foo c"));
+ DoWCharTest(convert("foo %I64c"), wc, convert("foo c"));
+ DoWCharTest(convert("foo %5c"), wc, convert("foo c"));
+ DoWCharTest(convert("foo %.0c"), wc, convert("foo c"));
+ DoWCharTest(convert("foo %-5c"), wc, convert("foo c "));
+ DoWCharTest(convert("foo %05c"), wc, convert("foo 0000c"));
+ DoWCharTest(convert("foo % c"), wc, convert("foo c"));
+ DoWCharTest(convert("foo %#c"), wc, convert("foo c"));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test6/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test6/testinfo.dat
new file mode 100644
index 0000000000..d8db7f8335
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test6/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 = C Runtime
+Function = swprintf_s
+Name = Positive Test for swprintf_s
+TYPE = DEFAULT
+EXE1 = test6
+Description
+= Tests swprintf_s with characters
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test7/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test7/CMakeLists.txt
new file mode 100644
index 0000000000..0e55fbf4d7
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test7/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test7.cpp
+)
+
+add_executable(paltest_snwprintf_test7
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snwprintf_test7 coreclrpal)
+
+target_link_libraries(paltest_snwprintf_test7
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test7/test7.cpp b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test7/test7.cpp
new file mode 100644
index 0000000000..54dd32b433
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test7/test7.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test7.c
+**
+** Purpose: Tests swprintf_s with wide characters
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+int __cdecl main(int argc, char *argv[])
+{
+ WCHAR wc = (WCHAR) 'c';
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoCharTest(convert("foo %C"), 'b', convert("foo b"));
+ DoWCharTest(convert("foo %hC"), wc, convert("foo c"));
+ DoCharTest(convert("foo %lC"), 'b', convert("foo b"));
+ DoCharTest(convert("foo %LC"), 'b', convert("foo b"));
+ DoCharTest(convert("foo %I64C"), 'b', convert("foo b"));
+ DoCharTest(convert("foo %5C"), 'b', convert("foo b"));
+ DoCharTest(convert("foo %.0C"), 'b', convert("foo b"));
+ DoCharTest(convert("foo %-5C"), 'b', convert("foo b "));
+ DoCharTest(convert("foo %05C"), 'b', convert("foo 0000b"));
+ DoCharTest(convert("foo % C"), 'b', convert("foo b"));
+ DoCharTest(convert("foo %#C"), 'b', convert("foo b"));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test7/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test7/testinfo.dat
new file mode 100644
index 0000000000..fa5bd30008
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test7/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 = C Runtime
+Function = swprintf_s
+Name = Positive Test for swprintf_s
+TYPE = DEFAULT
+EXE1 = test7
+Description
+= Tests swprintf_s with wide characters
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test8/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test8/CMakeLists.txt
new file mode 100644
index 0000000000..8f7fbda5a0
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test8/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test8.cpp
+)
+
+add_executable(paltest_snwprintf_test8
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snwprintf_test8 coreclrpal)
+
+target_link_libraries(paltest_snwprintf_test8
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test8/test8.cpp b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test8/test8.cpp
new file mode 100644
index 0000000000..9f1b555e3c
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test8/test8.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: test8.c
+**
+** Purpose: Tests swprintf_s with decimal numbers
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+int __cdecl main(int argc, char *argv[])
+{
+ int neg = -42;
+ int pos = 42;
+ INT64 l = 42;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoNumTest(convert("foo %d"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %ld"), 0xFFFF, convert("foo 65535"));
+ DoNumTest(convert("foo %hd"), 0xFFFF, convert("foo -1"));
+ DoNumTest(convert("foo %Ld"), pos, convert("foo 42"));
+ DoI64Test(convert("foo %I64d"), l, "42", convert("foo 42"));
+ DoNumTest(convert("foo %3d"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %-3d"), pos, convert("foo 42 "));
+ DoNumTest(convert("foo %.1d"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %.3d"), pos, convert("foo 042"));
+ DoNumTest(convert("foo %03d"), pos, convert("foo 042"));
+ DoNumTest(convert("foo %#d"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %+d"), pos, convert("foo +42"));
+ DoNumTest(convert("foo % d"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %+d"), neg, convert("foo -42"));
+ DoNumTest(convert("foo % d"), neg, convert("foo -42"));
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test8/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test8/testinfo.dat
new file mode 100644
index 0000000000..d76a421ea3
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test8/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 = C Runtime
+Function = swprintf_s
+Name = Positive Test for swprintf_s
+TYPE = DEFAULT
+EXE1 = test8
+Description
+= Tests swprintf_s with decimal numbers
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test9/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test9/CMakeLists.txt
new file mode 100644
index 0000000000..f769c9eaa5
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test9/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test9.cpp
+)
+
+add_executable(paltest_snwprintf_test9
+ ${SOURCES}
+)
+
+add_dependencies(paltest_snwprintf_test9 coreclrpal)
+
+target_link_libraries(paltest_snwprintf_test9
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test9/test9.cpp b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test9/test9.cpp
new file mode 100644
index 0000000000..76d60631a2
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test9/test9.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: test9.c
+**
+** Purpose: Tests swprintf_s with integer numbers
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../_snwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+int __cdecl main(int argc, char *argv[])
+{
+ int neg = -42;
+ int pos = 42;
+ INT64 l = 42;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoNumTest(convert("foo %i"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %li"), 0xFFFF, convert("foo 65535"));
+ DoNumTest(convert("foo %hi"), 0xFFFF, convert("foo -1"));
+ DoNumTest(convert("foo %Li"), pos, convert("foo 42"));
+ DoI64Test(convert("foo %I64i"), l, "42", convert("foo 42"));
+ DoNumTest(convert("foo %3i"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %-3i"), pos, convert("foo 42 "));
+ DoNumTest(convert("foo %.1i"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %.3i"), pos, convert("foo 042"));
+ DoNumTest(convert("foo %03i"), pos, convert("foo 042"));
+ DoNumTest(convert("foo %#i"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %+i"), pos, convert("foo +42"));
+ DoNumTest(convert("foo % i"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %+i"), neg, convert("foo -42"));
+ DoNumTest(convert("foo % i"), neg, convert("foo -42"));
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test9/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test9/testinfo.dat
new file mode 100644
index 0000000000..b2a038df62
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test9/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 = C Runtime
+Function = swprintf_s
+Name = Positive Test for swprintf_s
+TYPE = DEFAULT
+EXE1 = test9
+Description
+= Tests swprintf_s with integer numbers
diff --git a/src/pal/tests/palsuite/c_runtime/_splitpath/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_splitpath/CMakeLists.txt
deleted file mode 100644
index f6aa0cb2d9..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_splitpath/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-add_subdirectory(test1)
-
diff --git a/src/pal/tests/palsuite/c_runtime/_splitpath/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_splitpath/test1/CMakeLists.txt
deleted file mode 100644
index 361b9084d7..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_splitpath/test1/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test1.c
-)
-
-add_executable(paltest_splitpath_test1
- ${SOURCES}
-)
-
-add_dependencies(paltest_splitpath_test1 coreclrpal)
-
-target_link_libraries(paltest_splitpath_test1
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_splitpath/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_splitpath/test1/test1.c
deleted file mode 100644
index e98354c2ee..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_splitpath/test1/test1.c
+++ /dev/null
@@ -1,108 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: test1.c
-**
-** Purpose: Passes _splitpath() a series of sample paths and checks that it
-** parses them as expected.
-**
-**
-**==========================================================================*/
-
-
-#include <palsuite.h>
-
-struct testCase
-{
- const char path[_MAX_PATH]; /* The path to parse. */
- const char drive[_MAX_DRIVE]; /* The expected values... */
- const char dir[_MAX_DIR];
- const char fname[_MAX_FNAME];
- const char ext[_MAX_EXT];
-};
-
-
-int __cdecl main(int argc, char **argv)
-{
- struct testCase testCases[] =
- {
-#if WIN32
- {"c:\\foo\\bar\\foo.bar", "c:", "\\foo\\bar\\", "foo", ".bar"},
- {"c:/foo/bar/foo.bar", "c:", "/foo/bar/", "foo", ".bar"},
- {"c:/foo/bar/foo", "c:", "/foo/bar/", "foo", ""},
- {"c:/foo/bar/.bar", "c:", "/foo/bar/", "", ".bar"},
- {"c:/foo/bar/", "c:", "/foo/bar/", "", ""},
- {"/foo/bar/foo.bar", "", "/foo/bar/", "foo", ".bar"},
- {"c:foo.bar", "c:", "", "foo", ".bar"}
-#else
- {"c:\\foo\\bar\\foo.bar", "","c:/foo/bar/", "foo", ".bar"},
- {"c:/foo/bar/foo.bar", "", "c:/foo/bar/", "foo", ".bar"},
- {"c:/foo/bar/foo", "", "c:/foo/bar/", "foo", ""},
- {"c:/foo/bar/.bar", "", "c:/foo/bar/", ".bar", ""},
- {"c:/foo/bar/", "", "c:/foo/bar/", "", ""},
- {"/foo/bar/foo.bar", "", "/foo/bar/", "foo", ".bar"},
- {"c:foo.bar", "", "", "c:foo", ".bar"}
-#endif
- };
- char drive[_MAX_DRIVE];
- char dir[_MAX_DIR];
- char fname[_MAX_FNAME];
- char ext[_MAX_EXT];
-
- int i=0;
-
- /*
- * Initialize the PAL and return FAIL if this fails
- */
- if (0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- for (i = 0; i < sizeof(testCases)/sizeof(struct testCase); i++)
- {
- _splitpath(testCases[i].path, drive, dir, fname, ext);
-
-
- /*on platforms that don't support drive letters, the drive
- returned should always be "" */
- if (strcmp(drive, testCases[i].drive) != 0)
- {
- Fail("_splitpath read the path \"%s\" and thought the drive was "
- "\"%s\" instead of \"%s\"\n"
- , testCases[i].path, drive, testCases[i].drive);
- }
-
- if (strcmp(dir, testCases[i].dir) != 0)
- {
- Fail("_splitpath read the path \"%s\" and thought the directory "
- "was \"%s\" instead of \"%s\"\n"
- , testCases[i].path, dir, testCases[i].dir);
- }
-
- if (strcmp(fname, testCases[i].fname) != 0)
- {
- Fail("_splitpath read the path \"%s\" and thought the filename "
- "was \"%s\" instead of \"%s\"\n"
- , testCases[i].path, fname, testCases[i].fname);
- }
-
- if (strcmp(ext, testCases[i].ext) != 0)
- {
- Fail("_splitpath read the path \"%s\" and thought the file "
- "extension was \"%s\" instead of \"%s\"\n"
- , testCases[i].path, ext, testCases[i].ext);
- }
- }
- PAL_Terminate();
- return PASS;
-}
-
-
-
-
-
-
diff --git a/src/pal/tests/palsuite/c_runtime/_splitpath/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_splitpath/test1/testinfo.dat
deleted file mode 100644
index 0a93e27456..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_splitpath/test1/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _splitpath
-Name = Positive Test for _splitpath
-TYPE = DEFAULT
-EXE1 = test1
-Description
-= Passes _splitpath() a series of sample paths and checks that it
-= parses them as expected.
-
-
diff --git a/src/pal/tests/palsuite/c_runtime/_stricmp/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_stricmp/test1/CMakeLists.txt
index 766660ccfc..03aa3a523e 100644
--- a/src/pal/tests/palsuite/c_runtime/_stricmp/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_stricmp/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_stricmp_test1
diff --git a/src/pal/tests/palsuite/c_runtime/_stricmp/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_stricmp/test1/test1.cpp
index 60e2f9eb8b..60e2f9eb8b 100644
--- a/src/pal/tests/palsuite/c_runtime/_stricmp/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/_stricmp/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_strlwr/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_strlwr/test1/CMakeLists.txt
index 3a9394ca60..ca26961b3c 100644
--- a/src/pal/tests/palsuite/c_runtime/_strlwr/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_strlwr/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_strlwr_test1
diff --git a/src/pal/tests/palsuite/c_runtime/_strlwr/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_strlwr/test1/test1.cpp
index 1c4015e3e2..1c4015e3e2 100644
--- a/src/pal/tests/palsuite/c_runtime/_strlwr/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/_strlwr/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_strnicmp/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_strnicmp/test1/CMakeLists.txt
index 6a38747592..03f9992198 100644
--- a/src/pal/tests/palsuite/c_runtime/_strnicmp/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_strnicmp/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_strnicmp_test1
diff --git a/src/pal/tests/palsuite/c_runtime/_strnicmp/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_strnicmp/test1/test1.cpp
index 3c915dc621..3c915dc621 100644
--- a/src/pal/tests/palsuite/c_runtime/_strnicmp/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/_strnicmp/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_swab/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_swab/CMakeLists.txt
deleted file mode 100644
index f6aa0cb2d9..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_swab/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-add_subdirectory(test1)
-
diff --git a/src/pal/tests/palsuite/c_runtime/_swab/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_swab/test1/CMakeLists.txt
deleted file mode 100644
index fc7fbef8b4..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_swab/test1/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test1.c
-)
-
-add_executable(paltest_swab_test1
- ${SOURCES}
-)
-
-add_dependencies(paltest_swab_test1 coreclrpal)
-
-target_link_libraries(paltest_swab_test1
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_swab/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_swab/test1/test1.c
deleted file mode 100644
index 203e3b3a06..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_swab/test1/test1.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test1.c
-**
-** Purpose: Calls _swab on a buffer, and checks that it has correctly
-** swapped adjacent bytes
-**
-**
-**==========================================================================*/
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char **argv)
-{
- char before[] = "abcdefghijklmn";
- char after[] = "--------------";
- const char check[] = "badcfehgjilknm";
-
- /*
- * Initialize the PAL and return FAIL if this fails
- */
- if (0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- _swab(before, after, sizeof(before));
- if (memcmp(after, check, sizeof(after)) != 0)
- {
- Fail ("_swab did not correctly swap adjacent bytes in a buffer.\n");
- }
-
- PAL_Terminate();
- return PASS;
-
-}
-
-
-
-
-
diff --git a/src/pal/tests/palsuite/c_runtime/_swab/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_swab/test1/testinfo.dat
deleted file mode 100644
index c59b017762..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_swab/test1/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _swab
-Name = Positive Test for _swab
-TYPE = DEFAULT
-EXE1 = test1
-Description
-= Calls _swab on a buffer, and checks that it has correctly swapped
-= adjacent bytes
-
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/_vsnprintf.h b/src/pal/tests/palsuite/c_runtime/_vsnprintf/_vsnprintf.h
index 240a72f017..30e70648c3 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/_vsnprintf.h
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/_vsnprintf.h
@@ -28,7 +28,7 @@ int Testvsnprintf(char* buf, size_t count, const char* format, ...)
}
-void DoStrTest(char *formatstr, char* param, char *checkstr)
+void DoStrTest(const char *formatstr, char* param, const char *checkstr)
{
char buf[256] = { 0 };
@@ -41,7 +41,7 @@ void DoStrTest(char *formatstr, char* param, char *checkstr)
}
}
-void DoWStrTest(char *formatstr, WCHAR* param, char *checkstr)
+void DoWStrTest(const char *formatstr, WCHAR* param, const char *checkstr)
{
char buf[256] = { 0 };
@@ -55,7 +55,7 @@ void DoWStrTest(char *formatstr, WCHAR* param, char *checkstr)
}
-void DoCharTest(char *formatstr, char param, char *checkstr)
+void DoCharTest(const char *formatstr, char param, const char *checkstr)
{
char buf[256] = { 0 };
@@ -68,7 +68,7 @@ void DoCharTest(char *formatstr, char param, char *checkstr)
}
}
-void DoWCharTest(char *formatstr, WCHAR param, char *checkstr)
+void DoWCharTest(const char *formatstr, WCHAR param, const char *checkstr)
{
char buf[256] = { 0 };
@@ -81,7 +81,7 @@ void DoWCharTest(char *formatstr, WCHAR param, char *checkstr)
}
}
-void DoNumTest(char *formatstr, int value, char *checkstr)
+void DoNumTest(const char *formatstr, int value, const char *checkstr)
{
char buf[256] = { 0 };
@@ -94,7 +94,7 @@ void DoNumTest(char *formatstr, int value, char *checkstr)
}
}
-void DoI64Test(char *formatstr, INT64 value, char *valuestr, char *checkstr)
+void DoI64Test(const char *formatstr, INT64 value, char *valuestr, const char *checkstr)
{
char buf[256] = { 0 };
@@ -106,7 +106,7 @@ void DoI64Test(char *formatstr, INT64 value, char *valuestr, char *checkstr)
valuestr, formatstr, checkstr, buf);
}
}
-void DoDoubleTest(char *formatstr, double value, char *checkstr1, char
+void DoDoubleTest(const char *formatstr, double value, const char *checkstr1, char
*checkstr2)
{
char buf[256] = { 0 };
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test1/CMakeLists.txt
index 7c346a4638..489b7bf566 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_vsnprintf_test1
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test1/test1.cpp
index 88aeec27a5..88aeec27a5 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test1/testinfo.dat
index 0e97856927..f96bf084f2 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test1/testinfo.dat
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test1/testinfo.dat
@@ -10,4 +10,4 @@ TYPE = DEFAULT
EXE1 = test1
Description
= Tests the PAL implementation of the _vsnprintf function.
-= This test is modeled after _snprintf.
+= This test is modeled after sprintf_s.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test10/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test10/CMakeLists.txt
index 00dccc260d..bc35dbd0c2 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test10/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test10/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test10.c
+ test10.cpp
)
add_executable(paltest_vsnprintf_test10
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test10/test10.c b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test10/test10.cpp
index 3099957ab7..3099957ab7 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test10/test10.c
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test10/test10.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test10/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test10/testinfo.dat
index 1399afae05..a3d8eca54e 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test10/testinfo.dat
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test10/testinfo.dat
@@ -11,4 +11,4 @@ EXE1 = test10
Description
= Tests the PAL implementation of the _vsnprintf function.
= Tests _vsnprintf with octal numbers.
-= This test is modeled after _snprintf.
+= This test is modeled after sprintf_s.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test11/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test11/CMakeLists.txt
index fd709f2a31..bf3dd9a534 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test11/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test11/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test11.c
+ test11.cpp
)
add_executable(paltest_vsnprintf_test11
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test11/test11.c b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test11/test11.cpp
index 74b0435c6d..74b0435c6d 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test11/test11.c
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test11/test11.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test11/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test11/testinfo.dat
index faa7428eff..17e9f04946 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test11/testinfo.dat
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test11/testinfo.dat
@@ -11,4 +11,4 @@ EXE1 = test11
Description
= Tests the PAL implementation of the _vsnprintf function.
= Tests _vsnprintf with unsigned numbers.
-= This test is modeled after _snprintf.
+= This test is modeled after sprintf_s.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test12/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test12/CMakeLists.txt
index 02dac0cb91..9fceeaf7a5 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test12/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test12/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test12.c
+ test12.cpp
)
add_executable(paltest_vsnprintf_test12
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test12/test12.c b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test12/test12.cpp
index 3718620971..3718620971 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test12/test12.c
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test12/test12.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test12/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test12/testinfo.dat
index d48a5cc60d..82f58e4371 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test12/testinfo.dat
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test12/testinfo.dat
@@ -11,4 +11,4 @@ EXE1 = test12
Description
= Tests the PAL implementation of the _vsnprintf function.
= Tests _vsnprintf with hex numbers (lowercase).
-= This test is modeled after _snprintf.
+= This test is modeled after sprintf_s.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test13/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test13/CMakeLists.txt
index 52562c99f8..7e805f6ad4 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test13/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test13/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test13.c
+ test13.cpp
)
add_executable(paltest_vsnprintf_test13
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test13/test13.c b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test13/test13.cpp
index 1abada4033..1abada4033 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test13/test13.c
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test13/test13.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test13/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test13/testinfo.dat
index a3f14c21dc..d308edf871 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test13/testinfo.dat
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test13/testinfo.dat
@@ -11,4 +11,4 @@ EXE1 = test13
Description
= Tests the PAL implementation of the _vsnprintf function.
= Tests _vsnprintf with hex numbers (uppercase).
-= This test is modeled after _snprintf.
+= This test is modeled after sprintf_s.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test14/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test14/CMakeLists.txt
index 3fc8c814a6..6e4566b577 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test14/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test14/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test14.c
+ test14.cpp
)
add_executable(paltest_vsnprintf_test14
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test14/test14.c b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test14/test14.cpp
index 2e98f6ad4e..2e98f6ad4e 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test14/test14.c
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test14/test14.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test14/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test14/testinfo.dat
index f4d921c139..8d11b1d6ff 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test14/testinfo.dat
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test14/testinfo.dat
@@ -11,4 +11,4 @@ EXE1 = test14
Description
= Tests the PAL implementation of the _vsnprintf function.
= Tests _vsnprintf with exponential format doubles (lowercase).
-= This test is modeled after _snprintf.
+= This test is modeled after sprintf_s.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test15/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test15/CMakeLists.txt
index f6bdc83779..d9039b39b7 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test15/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test15/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test15.c
+ test15.cpp
)
add_executable(paltest_vsnprintf_test15
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test15/test15.c b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test15/test15.cpp
index 4d32e9c638..4d32e9c638 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test15/test15.c
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test15/test15.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test15/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test15/testinfo.dat
index 3a6620ba46..913912508e 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test15/testinfo.dat
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test15/testinfo.dat
@@ -11,4 +11,4 @@ EXE1 = test15
Description
= Tests the PAL implementation of the _vsnprintf function.
= Tests _vsnprintf with exponential format doubles (uppercase).
-= This test is modeled after _snprintf.
+= This test is modeled after sprintf_s.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test16/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test16/CMakeLists.txt
index b7b06d19bb..b298df318b 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test16/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test16/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test16.c
+ test16.cpp
)
add_executable(paltest_vsnprintf_test16
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test16/test16.c b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test16/test16.cpp
index 118ba1453c..118ba1453c 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test16/test16.c
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test16/test16.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test16/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test16/testinfo.dat
index 6363f294af..fc2f13071b 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test16/testinfo.dat
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test16/testinfo.dat
@@ -11,4 +11,4 @@ EXE1 = test16
Description
= Tests the PAL implementation of the _vsnprintf function.
= Tests _vsnprintf with decimal point format doubles.
-= This test is modeled after _snprintf.
+= This test is modeled after sprintf_s.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test17/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test17/CMakeLists.txt
index 2c91cccd4a..b195f334d3 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test17/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test17/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test17.c
+ test17.cpp
)
add_executable(paltest_vsnprintf_test17
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test17/test17.c b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test17/test17.cpp
index 9b5063ddf0..9b5063ddf0 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test17/test17.c
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test17/test17.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test17/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test17/testinfo.dat
index ecec515de3..aeb924495c 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test17/testinfo.dat
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test17/testinfo.dat
@@ -11,4 +11,4 @@ EXE1 = test17
Description
= Tests the PAL implementation of the _vsnprintf function.
= Tests _vsnprintf with compact format doubles (lowercase).
-= This test is modeled after _snprintf.
+= This test is modeled after sprintf_s.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test18/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test18/CMakeLists.txt
index 1a06ce01ee..f0f6d1124e 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test18/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test18/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test18.c
+ test18.cpp
)
add_executable(paltest_vsnprintf_test18
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test18/test18.c b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test18/test18.cpp
index 5232befc7f..5232befc7f 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test18/test18.c
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test18/test18.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test18/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test18/testinfo.dat
index 34fd7ae2ff..57aaed5953 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test18/testinfo.dat
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test18/testinfo.dat
@@ -11,4 +11,4 @@ EXE1 = test18
Description
= Tests the PAL implementation of the _vsnprintf function.
= Tests _vsnprintf with compact format doubles (uppercase).
-= This test is modeled after _snprintf.
+= This test is modeled after sprintf_s.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test19/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test19/CMakeLists.txt
index 6f2e42cc6b..44b38902ef 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test19/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test19/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test19.c
+ test19.cpp
)
add_executable(paltest_vsnprintf_test19
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test19/test19.c b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test19/test19.c
deleted file mode 100644
index 075a528aba..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test19/test19.c
+++ /dev/null
@@ -1,103 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: test19.c
-**
-** Purpose: Test #19 for the _vsnprintf function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-#include "../_vsnprintf.h"
-
-/*
- * Notes: memcmp is used, as is strlen.
- */
-
-#define DOTEST(a,b,c,d,e) DoTest(a,b,(void*)c,d,e)
-
-void DoArgumentPrecTest(char *formatstr, int precision, void *param,
- char *paramstr, char *checkstr1, char *checkstr2)
-{
- char buf[256];
-
- Testvsnprintf(buf,256,formatstr, precision, param);
- if (memcmp(buf, checkstr1, strlen(checkstr1) + 1) != 0 &&
- memcmp(buf, checkstr2, strlen(checkstr2) + 1) != 0)
- {
- Fail("ERROR: failed to insert %s into \"%s\" with precision %d\n"
- "Expected \"%s\" or \"%s\", got \"%s\".\n",
- paramstr, formatstr, precision, checkstr1, checkstr2, buf);
- }
-
-}
-
-void DoArgumentPrecDoubleTest(char *formatstr, int precision, double param,
- char *checkstr1, char *checkstr2)
-{
- char buf[256];
-
- Testvsnprintf(buf,256,formatstr, precision, param);
- if (memcmp(buf, checkstr1, strlen(checkstr1) + 1) != 0 &&
- memcmp(buf, checkstr2, strlen(checkstr2) + 1) != 0)
- {
- Fail("ERROR: failed to insert %f into \"%s\" with precision %d\n"
- "Expected \"%s\" or \"%s\", got \"%s\".\n",
- param, formatstr, precision, checkstr1, checkstr2, buf);
- }
-
-}
-
-
-
-int __cdecl main(int argc, char *argv[])
-{
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return(FAIL);
- }
-
-
- DoArgumentPrecTest("%.*s", 2, "bar", "bar", "ba", "ba");
- DoArgumentPrecTest("%.*S", 2, convert("bar"), "bar", "ba", "ba");
- DoArgumentPrecTest("%.*c", 0, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*c", 4, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*C", 0, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*C", 4, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*d", 1, (void*)42, "42", "42", "42");
- DoArgumentPrecTest("%.*d", 3, (void*)42, "42", "042", "042");
- DoArgumentPrecTest("%.*i", 1, (void*)42, "42", "42", "42");
- DoArgumentPrecTest("%.*i", 3, (void*)42, "42", "042", "042");
- DoArgumentPrecTest("%.*o", 1, (void*)42, "42", "52", "52");
- DoArgumentPrecTest("%.*o", 3, (void*)42, "42", "052", "052");
- DoArgumentPrecTest("%.*u", 1, (void*)42, "42", "42", "42");
- DoArgumentPrecTest("%.*u", 3, (void*)42, "42", "042", "042");
- DoArgumentPrecTest("%.*x", 1, (void*)0x42, "0x42", "42", "42");
- DoArgumentPrecTest("%.*x", 3, (void*)0x42, "0x42", "042", "042");
- DoArgumentPrecTest("%.*X", 1, (void*)0x42, "0x42", "42", "42");
- DoArgumentPrecTest("%.*X", 3, (void*)0x42, "0x42", "042", "042");
-
-
- DoArgumentPrecDoubleTest("%.*e", 1, 2.01, "2.0e+000", "2.0e+00");
- DoArgumentPrecDoubleTest("%.*e", 3, 2.01, "2.010e+000", "2.010e+00");
- DoArgumentPrecDoubleTest("%.*E", 1, 2.01, "2.0E+000", "2.0E+00");
- DoArgumentPrecDoubleTest("%.*E", 3, 2.01, "2.010E+000", "2.010E+00");
- DoArgumentPrecDoubleTest("%.*f", 1, 2.01, "2.0", "2.0");
- DoArgumentPrecDoubleTest("%.*f", 3, 2.01, "2.010", "2.010");
- DoArgumentPrecDoubleTest("%.*g", 1, 256.01, "3e+002", "3e+02");
- DoArgumentPrecDoubleTest("%.*g", 3, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*g", 4, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*g", 6, 256.01, "256.01", "256.01");
- DoArgumentPrecDoubleTest("%.*G", 1, 256.01, "3E+002", "3E+02");
- DoArgumentPrecDoubleTest("%.*G", 3, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*G", 4, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*G", 6, 256.01, "256.01", "256.01");
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test19/test19.cpp b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test19/test19.cpp
new file mode 100644
index 0000000000..211354bc3a
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test19/test19.cpp
@@ -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.
+
+/*=====================================================================
+**
+** Source: test19.c
+**
+** Purpose: Test #19 for the _vsnprintf function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+#include "../_vsnprintf.h"
+
+/*
+ * Notes: memcmp is used, as is strlen.
+ */
+
+#define DOTEST(a,b,c,d,e) DoTest(a,b,(void*)c,d,e)
+
+void DoArgumentPrecTest(char *formatstr, int precision, void *param,
+ char *paramstr, char *checkstr1, char *checkstr2)
+{
+ char buf[256];
+
+ Testvsnprintf(buf,256,formatstr, precision, param);
+ if (memcmp(buf, checkstr1, strlen(checkstr1) + 1) != 0 &&
+ memcmp(buf, checkstr2, strlen(checkstr2) + 1) != 0)
+ {
+ Fail("ERROR: failed to insert %s into \"%s\" with precision %d\n"
+ "Expected \"%s\" or \"%s\", got \"%s\".\n",
+ paramstr, formatstr, precision, checkstr1, checkstr2, buf);
+ }
+
+}
+
+void DoArgumentPrecDoubleTest(char *formatstr, int precision, double param,
+ char *checkstr1, char *checkstr2)
+{
+ char buf[256];
+
+ Testvsnprintf(buf,256,formatstr, precision, param);
+ if (memcmp(buf, checkstr1, strlen(checkstr1) + 1) != 0 &&
+ memcmp(buf, checkstr2, strlen(checkstr2) + 1) != 0)
+ {
+ Fail("ERROR: failed to insert %f into \"%s\" with precision %d\n"
+ "Expected \"%s\" or \"%s\", got \"%s\".\n",
+ param, formatstr, precision, checkstr1, checkstr2, buf);
+ }
+
+}
+
+
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return(FAIL);
+ }
+
+
+ DoArgumentPrecTest("%.*s", 2, (void*)"bar", "bar", "ba", "ba");
+ DoArgumentPrecTest("%.*S", 2, (void*)convert("bar"), "bar", "ba", "ba");
+ DoArgumentPrecTest("%.*c", 0, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*c", 4, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*C", 0, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*C", 4, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*d", 1, (void*)42, "42", "42", "42");
+ DoArgumentPrecTest("%.*d", 3, (void*)42, "42", "042", "042");
+ DoArgumentPrecTest("%.*i", 1, (void*)42, "42", "42", "42");
+ DoArgumentPrecTest("%.*i", 3, (void*)42, "42", "042", "042");
+ DoArgumentPrecTest("%.*o", 1, (void*)42, "42", "52", "52");
+ DoArgumentPrecTest("%.*o", 3, (void*)42, "42", "052", "052");
+ DoArgumentPrecTest("%.*u", 1, (void*)42, "42", "42", "42");
+ DoArgumentPrecTest("%.*u", 3, (void*)42, "42", "042", "042");
+ DoArgumentPrecTest("%.*x", 1, (void*)0x42, "0x42", "42", "42");
+ DoArgumentPrecTest("%.*x", 3, (void*)0x42, "0x42", "042", "042");
+ DoArgumentPrecTest("%.*X", 1, (void*)0x42, "0x42", "42", "42");
+ DoArgumentPrecTest("%.*X", 3, (void*)0x42, "0x42", "042", "042");
+
+
+ DoArgumentPrecDoubleTest("%.*e", 1, 2.01, "2.0e+000", "2.0e+00");
+ DoArgumentPrecDoubleTest("%.*e", 3, 2.01, "2.010e+000", "2.010e+00");
+ DoArgumentPrecDoubleTest("%.*E", 1, 2.01, "2.0E+000", "2.0E+00");
+ DoArgumentPrecDoubleTest("%.*E", 3, 2.01, "2.010E+000", "2.010E+00");
+ DoArgumentPrecDoubleTest("%.*f", 1, 2.01, "2.0", "2.0");
+ DoArgumentPrecDoubleTest("%.*f", 3, 2.01, "2.010", "2.010");
+ DoArgumentPrecDoubleTest("%.*g", 1, 256.01, "3e+002", "3e+02");
+ DoArgumentPrecDoubleTest("%.*g", 3, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*g", 4, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*g", 6, 256.01, "256.01", "256.01");
+ DoArgumentPrecDoubleTest("%.*G", 1, 256.01, "3E+002", "3E+02");
+ DoArgumentPrecDoubleTest("%.*G", 3, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*G", 4, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*G", 6, 256.01, "256.01", "256.01");
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test19/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test19/testinfo.dat
index 05f4b5bd87..cda8966865 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test19/testinfo.dat
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test19/testinfo.dat
@@ -11,4 +11,4 @@ EXE1 = test19
Description
= Tests the PAL implementation of the _vsnprintf function.
= Tests _vsnprintf with argument specified precision.
-= This test is modeled after _snprintf.
+= This test is modeled after sprintf_s.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test2/CMakeLists.txt
index a3871d64cf..1d3910e70c 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_vsnprintf_test2
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test2/test2.c b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test2/test2.cpp
index 4bac4d2c83..4bac4d2c83 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test2/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test2/testinfo.dat
index 5ee925e3f6..6e8f03e639 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test2/testinfo.dat
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test2/testinfo.dat
@@ -11,4 +11,4 @@ EXE1 = test2
Description
= Tests the PAL implementation of the _vsnprintf function.
= Tests _vsnprintf with strings.
-= This test is modeled after _snprintf.
+= This test is modeled after sprintf_s.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test3/CMakeLists.txt
index 1beae06277..62d765ec5f 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_vsnprintf_test3
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test3/test3.c b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test3/test3.cpp
index 2b30c9ad99..2b30c9ad99 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test3/test3.c
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test3/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test3/testinfo.dat
index 626949c7c8..638cef69ef 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test3/testinfo.dat
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test3/testinfo.dat
@@ -11,4 +11,4 @@ EXE1 = test3
Description
= Tests the PAL implementation of the _vsnprintf function.
= Tests _vsnprintf with wide strings.
-= This test is modeled after _snprintf.
+= This test is modeled after sprintf_s.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test4/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test4/CMakeLists.txt
index daf7757ddb..5662bd57ad 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_vsnprintf_test4
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test4/test4.c b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test4/test4.cpp
index 33fc49deba..33fc49deba 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test4/test4.c
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test4/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test4/testinfo.dat
index bdfdef85ae..03ff2931bc 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test4/testinfo.dat
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test4/testinfo.dat
@@ -11,4 +11,4 @@ EXE1 = test4
Description
= Tests the PAL implementation of the _vsnprintf function.
= Tests _vsnprintf with pointers.
-= This test is modeled after _snprintf.
+= This test is modeled after sprintf_s.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test5/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test5/CMakeLists.txt
index c255b07b42..92540541f3 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_vsnprintf_test5
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test5/test5.c b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test5/test5.cpp
index 534e42e293..534e42e293 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test5/test5.c
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test5/test5.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test5/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test5/testinfo.dat
index 3cd3f7ee86..c3848824f1 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test5/testinfo.dat
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test5/testinfo.dat
@@ -11,4 +11,4 @@ EXE1 = test5
Description
= Tests the PAL implementation of the _vsnprintf function.
= Tests _vsnprintf with the count specifier.
-= This test is modeled after _snprintf.
+= This test is modeled after sprintf_s.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test6/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test6/CMakeLists.txt
index 8e041f4af8..d80d433c22 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test6.c
+ test6.cpp
)
add_executable(paltest_vsnprintf_test6
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test6/test6.c b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test6/test6.cpp
index 103d1181c2..103d1181c2 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test6/test6.c
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test6/test6.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test6/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test6/testinfo.dat
index e379e0b3b8..e375f9238d 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test6/testinfo.dat
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test6/testinfo.dat
@@ -11,4 +11,4 @@ EXE1 = test6
Description
= Tests the PAL implementation of the _vsnprintf function.
= Tests _vsnprintf with characters.
-= This test is modeled after _snprintf.
+= This test is modeled after sprintf_s.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test7/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test7/CMakeLists.txt
index 01f9620184..a1dc0a7c2c 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test7/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test7/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test7.c
+ test7.cpp
)
add_executable(paltest_vsnprintf_test7
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test7/test7.c b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test7/test7.cpp
index c7e45d67fa..c7e45d67fa 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test7/test7.c
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test7/test7.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test7/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test7/testinfo.dat
index 90749400a5..09eb481b59 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test7/testinfo.dat
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test7/testinfo.dat
@@ -11,4 +11,4 @@ EXE1 = test7
Description
= Tests the PAL implementation of the _vsnprintf function.
= Tests _vsnprintf with wide characters.
-= This test is modeled after _snprintf.
+= This test is modeled after sprintf_s.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test8/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test8/CMakeLists.txt
index 9c525de15a..1ca4732492 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test8/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test8/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test8.c
+ test8.cpp
)
add_executable(paltest_vsnprintf_test8
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test8/test8.c b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test8/test8.cpp
index 2cefbeac25..2cefbeac25 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test8/test8.c
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test8/test8.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test8/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test8/testinfo.dat
index 0afc334a67..1bdf411983 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test8/testinfo.dat
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test8/testinfo.dat
@@ -11,4 +11,4 @@ EXE1 = test8
Description
= Tests the PAL implementation of the _vsnprintf function.
= Tests _vsnprintf with decimal numbers.
-= This test is modeled after _snprintf.
+= This test is modeled after sprintf_s.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test9/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test9/CMakeLists.txt
index bfe2572a6d..583971fe5a 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test9/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test9/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test9.c
+ test9.cpp
)
add_executable(paltest_vsnprintf_test9
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test9/test9.c b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test9/test9.cpp
index d2cd8165c0..d2cd8165c0 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test9/test9.c
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test9/test9.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test9/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test9/testinfo.dat
index 125724a36b..bdaae87ce8 100644
--- a/src/pal/tests/palsuite/c_runtime/_vsnprintf/test9/testinfo.dat
+++ b/src/pal/tests/palsuite/c_runtime/_vsnprintf/test9/testinfo.dat
@@ -11,4 +11,4 @@ EXE1 = test9
Description
= Tests the PAL implementation of the _vsnprintf function.
= Tests _vsnprintf with integer numbers.
-= This test is modeled after _snprintf.
+= This test is modeled after sprintf_s.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/CMakeLists.txt
deleted file mode 100644
index cafb9536b0..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/CMakeLists.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-add_subdirectory(test1)
-add_subdirectory(test10)
-add_subdirectory(test11)
-add_subdirectory(test12)
-add_subdirectory(test13)
-add_subdirectory(test14)
-add_subdirectory(test15)
-add_subdirectory(test16)
-add_subdirectory(test17)
-add_subdirectory(test18)
-add_subdirectory(test19)
-add_subdirectory(test2)
-add_subdirectory(test3)
-add_subdirectory(test4)
-add_subdirectory(test5)
-add_subdirectory(test6)
-add_subdirectory(test7)
-add_subdirectory(test8)
-add_subdirectory(test9)
-
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/_vsnwprintf.h b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/_vsnwprintf.h
deleted file mode 100644
index a3a932f822..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/_vsnwprintf.h
+++ /dev/null
@@ -1,133 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: _vsnwprintf.h
-**
-** Purpose: Containts common testing functions for _vsnwprintf
-**
-**
-**==========================================================================*/
-
-#ifndef ___VSNWPRINTF_H__
-#define ___VSNWPRINTF_H__
-
-/* These functions leaks memory like crazy. C'est la vie. */
-int TestVsnwprintf(wchar_t* buf, size_t count, const wchar_t* format, ...)
-{
- int retVal = 0;
- va_list arglist;
-
- va_start(arglist, format);
- retVal = _vsnwprintf(buf, count, format, arglist);
- va_end(arglist);
-
- return( retVal);
-}
-
-
-void DoWStrTest(WCHAR *formatstr, WCHAR *param, WCHAR *checkstr)
-{
- WCHAR buf[256] = { 0 };
-
- TestVsnwprintf(buf, 256, formatstr, param);
-
- if (memcmp(buf, checkstr, wcslen(buf) * 2 + 2) != 0)
- {
- Fail("ERROR: failed to insert wide string \"%s\" into \"%s\".\n"
- "Expected \"%s\", got \"%s\".\n",
- convertC(param), convertC(formatstr),
- convertC(checkstr), convertC(buf));
- }
-}
-
-void DoStrTest(WCHAR *formatstr, char *param, WCHAR *checkstr)
-{
- WCHAR buf[256] = { 0 };
-
- TestVsnwprintf(buf, 256, formatstr, param);
-
- if (memcmp(buf, checkstr, wcslen(buf) * 2 + 2) != 0)
- {
- Fail("ERROR: failed to insert wide string \"%s\" into \"%s\".\n"
- "Expected \"%s\", got \"%s\".\n",
- param, convertC(formatstr), convertC(checkstr),
- convertC(buf));
- }
-}
-
-void DoCharTest(WCHAR *formatstr, char param, WCHAR *checkstr)
-{
- WCHAR buf[256] = { 0 };
-
- TestVsnwprintf(buf, 256, formatstr, param);
- if (memcmp(buf, checkstr, wcslen(buf)*2 + 2) != 0)
- {
- Fail("ERROR: failed to insert char \'%c\' (%d) into \"%s\"\n"
- "Expected \"%s\" got \"%s\".\n",
- param, param, convertC(formatstr), convertC(checkstr),
- convertC(buf));
- }
-}
-
-void DoWCharTest(WCHAR *formatstr, WCHAR param, WCHAR *checkstr)
-{
- WCHAR buf[256] = { 0 };
-
- TestVsnwprintf(buf, 256, formatstr, param);
- if (memcmp(buf, checkstr, wcslen(buf)*2 + 2) != 0)
- {
- Fail("ERROR: failed to insert wide char \'%c\' (%d) into \"%s\"\n"
- "Expected \"%s\" got \"%s\".\n",
- (char) param, param, convertC(formatstr),
- convertC(checkstr), convertC(buf));
- }
-}
-
-void DoNumTest(WCHAR *formatstr, int value, WCHAR*checkstr)
-{
- WCHAR buf[256] = { 0 };
-
- TestVsnwprintf(buf, 256, formatstr, value);
- if (memcmp(buf, checkstr, wcslen(buf)* 2 + 2) != 0)
- {
- Fail("ERROR: failed to insert %#x into \"%s\"\n"
- "Expected \"%s\" got \"%s\".\n", value, convertC(formatstr),
- convertC(checkstr), convertC(buf));
- }
-}
-
-void DoI64NumTest(WCHAR *formatstr, INT64 value, char *valuestr, WCHAR*checkstr)
-{
- WCHAR buf[256] = { 0 };
-
- TestVsnwprintf(buf, 256, formatstr, value);
- if (memcmp(buf, checkstr, wcslen(buf)* 2 + 2) != 0)
- {
- Fail("ERROR: failed to insert %s into \"%s\"\n"
- "Expected \"%s\" got \"%s\".\n", valuestr, convertC(formatstr),
- convertC(checkstr), convertC(buf));
- }
-}
-void DoDoubleTest(WCHAR *formatstr, double value,
- WCHAR *checkstr1, WCHAR *checkstr2)
-{
- WCHAR buf[256] = { 0 };
-
- TestVsnwprintf(buf, 256, formatstr, value);
- if (memcmp(buf, checkstr1, wcslen(checkstr1) + 2) != 0 &&
- memcmp(buf, checkstr2, wcslen(checkstr2) + 2) != 0)
- {
- Fail("ERROR: failed to insert %f into \"%s\"\n"
- "Expected \"%s\" or \"%s\", got \"%s\".\n",
- value,
- convertC(formatstr),
- convertC(checkstr1),
- convertC(checkstr2),
- convertC(buf));
- }
-}
-
-#endif
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test1/CMakeLists.txt
deleted file mode 100644
index 52c442d572..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test1/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test1.c
-)
-
-add_executable(paltest_vsnwprintf_test1
- ${SOURCES}
-)
-
-add_dependencies(paltest_vsnwprintf_test1 coreclrpal)
-
-target_link_libraries(paltest_vsnwprintf_test1
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test1/test1.c
deleted file mode 100644
index 0238e42611..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test1/test1.c
+++ /dev/null
@@ -1,60 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: test1.c
-**
-** Purpose: Test #1 for the _vsnwprintf function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-#include "../_vsnwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-
-int __cdecl main(int argc, char *argv[])
-{
- WCHAR *checkstr;
- WCHAR buf[256] = { 0 };
- int ret;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return(FAIL);
- }
-
- checkstr = convert("hello world");
- TestVsnwprintf(buf, 256, checkstr);
- if (memcmp(checkstr, buf, wcslen(checkstr)*2+2) != 0)
- {
- Fail("ERROR: Expected \"%s\", got \"%s\"\n",
- convertC(checkstr), convertC(buf));
- }
-
- TestVsnwprintf(buf, 256, convert("xxxxxxxxxxxxxxxxx"));
- ret = TestVsnwprintf(buf, 8, checkstr);
- if (memcmp(checkstr, buf, 16) != 0)
- {
- Fail("ERROR: Expected \"%8s\", got \"%8s\"\n",
- convertC(checkstr), convertC(buf));
- }
- if (ret >= 0)
- {
- Fail("ERROR: Expected negative return value, got %d.\n", ret);
- }
- if (buf[8] != (WCHAR) 'x')
- {
- Fail("ERROR: buffer overflow using \"%s\" with length 8.\n",
- convertC(checkstr));
- }
-
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test1/testinfo.dat
deleted file mode 100644
index d806fb8ed8..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test1/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _vsnwprintf
-Name = Positive Test for _vsnwprintf
-TYPE = DEFAULT
-EXE1 = test1
-Description
-= Tests the PAL implementation of the _vsnwprintf function.
-= General test to see if _vsnwprintf works correctly.
-= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test10/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test10/CMakeLists.txt
deleted file mode 100644
index 86ea1a3160..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test10/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test10.c
-)
-
-add_executable(paltest_vsnwprintf_test10
- ${SOURCES}
-)
-
-add_dependencies(paltest_vsnwprintf_test10 coreclrpal)
-
-target_link_libraries(paltest_vsnwprintf_test10
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test10/test10.c b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test10/test10.c
deleted file mode 100644
index 6e188e56ff..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test10/test10.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: test10.c
-**
-** Purpose: Test #10 for the _vsnwprintf function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-#include "../_vsnwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-int __cdecl main(int argc, char *argv[])
-{
- int neg = -42;
- int pos = 42;
- INT64 l = 42;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return(FAIL);
- }
-
- DoNumTest(convert("foo %o"), pos, convert("foo 52"));
- DoNumTest(convert("foo %lo"), 0xFFFF, convert("foo 177777"));
- DoNumTest(convert("foo %ho"), 0xFFFF, convert("foo 177777"));
- DoNumTest(convert("foo %Lo"), pos, convert("foo 52"));
- DoI64NumTest(convert("foo %I64o"), l, "42", convert("foo 52"));
- DoNumTest(convert("foo %3o"), pos, convert("foo 52"));
- DoNumTest(convert("foo %-3o"), pos, convert("foo 52 "));
- DoNumTest(convert("foo %.1o"), pos, convert("foo 52"));
- DoNumTest(convert("foo %.3o"), pos, convert("foo 052"));
- DoNumTest(convert("foo %03o"), pos, convert("foo 052"));
- DoNumTest(convert("foo %#o"), pos, convert("foo 052"));
- DoNumTest(convert("foo %+o"), pos, convert("foo 52"));
- DoNumTest(convert("foo % o"), pos, convert("foo 52"));
- DoNumTest(convert("foo %+o"), neg, convert("foo 37777777726"));
- DoNumTest(convert("foo % o"), neg, convert("foo 37777777726"));
-
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test10/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test10/testinfo.dat
deleted file mode 100644
index beb5b41be9..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test10/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _vsnwprintf
-Name = Positive Test for _vsnwprintf
-TYPE = DEFAULT
-EXE1 = test10
-Description
-= Tests the PAL implementation of the _vsnwprintf function.
-= Tests _vsnwprintf with octal numbers.
-= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test11/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test11/CMakeLists.txt
deleted file mode 100644
index c6011dc1de..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test11/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test11.c
-)
-
-add_executable(paltest_vsnwprintf_test11
- ${SOURCES}
-)
-
-add_dependencies(paltest_vsnwprintf_test11 coreclrpal)
-
-target_link_libraries(paltest_vsnwprintf_test11
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test11/test11.c b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test11/test11.c
deleted file mode 100644
index af54985bdc..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test11/test11.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: test11.c
-**
-** Purpose: Test #11 for the _vsnwprintf function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-#include "../_vsnwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-int __cdecl main(int argc, char *argv[])
-{
- int neg = -42;
- int pos = 42;
- INT64 l = 42;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return(FAIL);
- }
-
- DoNumTest(convert("foo %u"), pos, convert("foo 42"));
- DoNumTest(convert("foo %lu"), 0xFFFF, convert("foo 65535"));
- DoNumTest(convert("foo %hu"), 0xFFFF, convert("foo 65535"));
- DoNumTest(convert("foo %Lu"), pos, convert("foo 42"));
- DoI64NumTest(convert("foo %I64u"), l, "42", convert("foo 42"));
- DoNumTest(convert("foo %3u"), pos, convert("foo 42"));
- DoNumTest(convert("foo %-3u"), pos, convert("foo 42 "));
- DoNumTest(convert("foo %.1u"), pos, convert("foo 42"));
- DoNumTest(convert("foo %.3u"), pos, convert("foo 042"));
- DoNumTest(convert("foo %03u"), pos, convert("foo 042"));
- DoNumTest(convert("foo %#u"), pos, convert("foo 42"));
- DoNumTest(convert("foo %+u"), pos, convert("foo 42"));
- DoNumTest(convert("foo % u"), pos, convert("foo 42"));
- DoNumTest(convert("foo %+u"), neg, convert("foo 4294967254"));
- DoNumTest(convert("foo % u"), neg, convert("foo 4294967254"));
-
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test11/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test11/testinfo.dat
deleted file mode 100644
index 083b0fa5af..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test11/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _vsnwprintf
-Name = Positive Test for _vsnwprintf
-TYPE = DEFAULT
-EXE1 = test11
-Description
-= Tests the PAL implementation of the _vsnwprintf function.
-= Tests _vsnwprintf with unsigned numbers.
-= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test12/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test12/CMakeLists.txt
deleted file mode 100644
index bd9652c2fb..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test12/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test12.c
-)
-
-add_executable(paltest_vsnwprintf_test12
- ${SOURCES}
-)
-
-add_dependencies(paltest_vsnwprintf_test12 coreclrpal)
-
-target_link_libraries(paltest_vsnwprintf_test12
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test12/test12.c b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test12/test12.c
deleted file mode 100644
index b593a82b4b..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test12/test12.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: test12.c
-**
-** Purpose: Test #12 for the _vsnwprintf function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-#include "../_vsnwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-int __cdecl main(int argc, char *argv[])
-{
- int neg = -42;
- int pos = 0x1234ab;
- INT64 l = I64(0x1234567887654321);
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return(FAIL);
- }
-
- DoNumTest(convert("foo %x"), pos, convert("foo 1234ab"));
- DoNumTest(convert("foo %lx"), pos, convert("foo 1234ab"));
- DoNumTest(convert("foo %hx"), pos, convert("foo 34ab"));
- DoNumTest(convert("foo %Lx"), pos, convert("foo 1234ab"));
- DoI64NumTest(convert("foo %I64x"), l, "0x1234567887654321",
- convert("foo 1234567887654321"));
- DoNumTest(convert("foo %7x"), pos, convert("foo 1234ab"));
- DoNumTest(convert("foo %-7x"), pos, convert("foo 1234ab "));
- DoNumTest(convert("foo %.1x"), pos, convert("foo 1234ab"));
- DoNumTest(convert("foo %.7x"), pos, convert("foo 01234ab"));
- DoNumTest(convert("foo %07x"), pos, convert("foo 01234ab"));
- DoNumTest(convert("foo %#x"), pos, convert("foo 0x1234ab"));
- DoNumTest(convert("foo %+x"), pos, convert("foo 1234ab"));
- DoNumTest(convert("foo % x"), pos, convert("foo 1234ab"));
- DoNumTest(convert("foo %+x"), neg, convert("foo ffffffd6"));
- DoNumTest(convert("foo % x"), neg, convert("foo ffffffd6"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test12/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test12/testinfo.dat
deleted file mode 100644
index a4450ed8d0..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test12/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _vsnwprintf
-Name = Positive Test for _vsnwprintf
-TYPE = DEFAULT
-EXE1 = test12
-Description
-= Tests the PAL implementation of the _vsnwprintf function.
-= Tests _vsnwprintf with hex numbers (lowercase).
-= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test13/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test13/CMakeLists.txt
deleted file mode 100644
index c608ab84e3..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test13/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test13.c
-)
-
-add_executable(paltest_vsnwprintf_test13
- ${SOURCES}
-)
-
-add_dependencies(paltest_vsnwprintf_test13 coreclrpal)
-
-target_link_libraries(paltest_vsnwprintf_test13
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test13/test13.c b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test13/test13.c
deleted file mode 100644
index 59a9dc496f..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test13/test13.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: test13.c
-**
-** Purpose: Test #13 for the _vsnwprintf function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-#include "../_vsnwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-int __cdecl main(int argc, char *argv[])
-{
- int neg = -42;
- int pos = 0x1234ab;
- INT64 l = I64(0x1234567887654321);
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return(FAIL);
- }
-
- DoNumTest(convert("foo %X"), pos, convert("foo 1234AB"));
- DoNumTest(convert("foo %lX"), pos, convert("foo 1234AB"));
- DoNumTest(convert("foo %hX"), pos, convert("foo 34AB"));
- DoNumTest(convert("foo %LX"), pos, convert("foo 1234AB"));
- DoI64NumTest(convert("foo %I64X"), l, "0x1234567887654321",
- convert("foo 1234567887654321"));
- DoNumTest(convert("foo %7X"), pos, convert("foo 1234AB"));
- DoNumTest(convert("foo %-7X"), pos, convert("foo 1234AB "));
- DoNumTest(convert("foo %.1X"), pos, convert("foo 1234AB"));
- DoNumTest(convert("foo %.7X"), pos, convert("foo 01234AB"));
- DoNumTest(convert("foo %07X"), pos, convert("foo 01234AB"));
- DoNumTest(convert("foo %#X"), pos, convert("foo 0X1234AB"));
- DoNumTest(convert("foo %+X"), pos, convert("foo 1234AB"));
- DoNumTest(convert("foo % X"), pos, convert("foo 1234AB"));
- DoNumTest(convert("foo %+X"), neg, convert("foo FFFFFFD6"));
- DoNumTest(convert("foo % X"), neg, convert("foo FFFFFFD6"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test13/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test13/testinfo.dat
deleted file mode 100644
index fa54ae8a62..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test13/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _vsnwprintf
-Name = Positive Test for _vsnwprintf
-TYPE = DEFAULT
-EXE1 = test13
-Description
-= Tests the PAL implementation of the _vsnwprintf function.
-= Tests _vsnwprintf with hex numbers (uppercase).
-= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test14/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test14/CMakeLists.txt
deleted file mode 100644
index 3bf157a2b3..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test14/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test14.c
-)
-
-add_executable(paltest_vsnwprintf_test14
- ${SOURCES}
-)
-
-add_dependencies(paltest_vsnwprintf_test14 coreclrpal)
-
-target_link_libraries(paltest_vsnwprintf_test14
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test14/test14.c b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test14/test14.c
deleted file mode 100644
index 633f9d68ae..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test14/test14.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: test14.c
-**
-** Purpose: Test #14 for the _vsnwprintf function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-#include "../_vsnwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-int __cdecl main(int argc, char *argv[])
-{
- double val = 256.0;
- double neg = -256.0;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return(FAIL);
- }
-
- DoDoubleTest(convert("foo %e"), val, convert("foo 2.560000e+002"),
- convert("foo 2.560000e+02"));
- DoDoubleTest(convert("foo %le"), val, convert("foo 2.560000e+002"),
- convert("foo 2.560000e+02"));
- DoDoubleTest(convert("foo %he"), val, convert("foo 2.560000e+002"),
- convert("foo 2.560000e+02"));
- DoDoubleTest(convert("foo %Le"), val, convert("foo 2.560000e+002"),
- convert("foo 2.560000e+02"));
- DoDoubleTest(convert("foo %I64e"), val, convert("foo 2.560000e+002"),
- convert("foo 2.560000e+02"));
- DoDoubleTest(convert("foo %14e"), val, convert("foo 2.560000e+002"),
- convert("foo 2.560000e+02"));
- DoDoubleTest(convert("foo %-14e"), val, convert("foo 2.560000e+002 "),
- convert("foo 2.560000e+02 "));
- DoDoubleTest(convert("foo %.1e"), val, convert("foo 2.6e+002"),
- convert("foo 2.6e+02"));
- DoDoubleTest(convert("foo %.8e"), val, convert("foo 2.56000000e+002"),
- convert("foo 2.56000000e+02"));
- DoDoubleTest(convert("foo %014e"), val, convert("foo 02.560000e+002"),
- convert("foo 002.560000e+02"));
- DoDoubleTest(convert("foo %#e"), val, convert("foo 2.560000e+002"),
- convert("foo 2.560000e+02"));
- DoDoubleTest(convert("foo %+e"), val, convert("foo +2.560000e+002"),
- convert("foo +2.560000e+02"));
- DoDoubleTest(convert("foo % e"), val, convert("foo 2.560000e+002"),
- convert("foo 2.560000e+02"));
- DoDoubleTest(convert("foo %+e"), neg, convert("foo -2.560000e+002"),
- convert("foo -2.560000e+02"));
- DoDoubleTest(convert("foo % e"), neg, convert("foo -2.560000e+002"),
- convert("foo -2.560000e+02"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test14/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test14/testinfo.dat
deleted file mode 100644
index 0796f5e81c..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test14/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _vsnwprintf
-Name = Positive Test for _vsnwprintf
-TYPE = DEFAULT
-EXE1 = test14
-Description
-= Tests the PAL implementation of the _vsnwprintf function.
-= Tests _vsnwprintf with exponential format doubles (lowercase).
-= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test15/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test15/CMakeLists.txt
deleted file mode 100644
index eedc7bb9db..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test15/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test15.c
-)
-
-add_executable(paltest_vsnwprintf_test15
- ${SOURCES}
-)
-
-add_dependencies(paltest_vsnwprintf_test15 coreclrpal)
-
-target_link_libraries(paltest_vsnwprintf_test15
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test15/test15.c b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test15/test15.c
deleted file mode 100644
index 0af41fe1dc..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test15/test15.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: test15.c
-**
-** Purpose: Test #15 for the _vsnwprintf function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-#include "../_vsnwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-
-int __cdecl main(int argc, char *argv[])
-{
- double val = 256.0;
- double neg = -256.0;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return(FAIL);
- }
-
- DoDoubleTest(convert("foo %E"), val, convert("foo 2.560000E+002"),
- convert("foo 2.560000E+02"));
- DoDoubleTest(convert("foo %lE"), val, convert("foo 2.560000E+002"),
- convert("foo 2.560000E+02"));
- DoDoubleTest(convert("foo %hE"), val, convert("foo 2.560000E+002"),
- convert("foo 2.560000E+02"));
- DoDoubleTest(convert("foo %LE"), val, convert("foo 2.560000E+002"),
- convert("foo 2.560000E+02"));
- DoDoubleTest(convert("foo %I64E"), val, convert("foo 2.560000E+002"),
- convert("foo 2.560000E+02"));
- DoDoubleTest(convert("foo %14E"), val, convert("foo 2.560000E+002"),
- convert("foo 2.560000E+02"));
- DoDoubleTest(convert("foo %-14E"), val, convert("foo 2.560000E+002 "),
- convert("foo 2.560000E+02 "));
- DoDoubleTest(convert("foo %.1E"), val, convert("foo 2.6E+002"),
- convert("foo 2.6E+02"));
- DoDoubleTest(convert("foo %.8E"), val, convert("foo 2.56000000E+002"),
- convert("foo 2.56000000E+02"));
- DoDoubleTest(convert("foo %014E"), val, convert("foo 02.560000E+002"),
- convert("foo 002.560000E+02"));
- DoDoubleTest(convert("foo %#E"), val, convert("foo 2.560000E+002"),
- convert("foo 2.560000E+02"));
- DoDoubleTest(convert("foo %+E"), val, convert("foo +2.560000E+002"),
- convert("foo +2.560000E+02"));
- DoDoubleTest(convert("foo % E"), val, convert("foo 2.560000E+002"),
- convert("foo 2.560000E+02"));
- DoDoubleTest(convert("foo %+E"), neg, convert("foo -2.560000E+002"),
- convert("foo -2.560000E+02"));
- DoDoubleTest(convert("foo % E"), neg, convert("foo -2.560000E+002"),
- convert("foo -2.560000E+002"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test15/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test15/testinfo.dat
deleted file mode 100644
index 9de3c83b8a..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test15/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _vsnwprintf
-Name = Positive Test for _vsnwprintf
-TYPE = DEFAULT
-EXE1 = test15
-Description
-= Tests the PAL implementation of the _vsnwprintf function.
-= Tests _vsnwprintf with exponential format doubles (uppercase).
-= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test16/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test16/CMakeLists.txt
deleted file mode 100644
index a469c497e9..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test16/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test16.c
-)
-
-add_executable(paltest_vsnwprintf_test16
- ${SOURCES}
-)
-
-add_dependencies(paltest_vsnwprintf_test16 coreclrpal)
-
-target_link_libraries(paltest_vsnwprintf_test16
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test16/test16.c b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test16/test16.c
deleted file mode 100644
index 77571b01b3..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test16/test16.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: test16.c
-**
-** Purpose: Test #16 for the _vsnwprintf function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-#include "../_vsnwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-int __cdecl main(int argc, char *argv[])
-{
- double val = 2560.001;
- double neg = -2560.001;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return(FAIL);
- }
-
- DoDoubleTest(convert("foo %f"), val, convert("foo 2560.001000"),
- convert("foo 2560.001000"));
- DoDoubleTest(convert("foo %lf"), val, convert("foo 2560.001000"),
- convert("foo 2560.001000"));
- DoDoubleTest(convert("foo %hf"), val, convert("foo 2560.001000"),
- convert("foo 2560.001000"));
- DoDoubleTest(convert("foo %Lf"), val, convert("foo 2560.001000"),
- convert("foo 2560.001000"));
- DoDoubleTest(convert("foo %I64f"), val, convert("foo 2560.001000"),
- convert("foo 2560.001000"));
- DoDoubleTest(convert("foo %12f"), val, convert("foo 2560.001000"),
- convert("foo 2560.001000"));
- DoDoubleTest(convert("foo %-12f"), val, convert("foo 2560.001000 "),
- convert("foo 2560.001000 "));
- DoDoubleTest(convert("foo %.1f"), val, convert("foo 2560.0"),
- convert("foo 2560.0"));
- DoDoubleTest(convert("foo %.8f"), val, convert("foo 2560.00100000"),
- convert("foo 2560.00100000"));
- DoDoubleTest(convert("foo %012f"), val, convert("foo 02560.001000"),
- convert("foo 02560.001000"));
- DoDoubleTest(convert("foo %#f"), val, convert("foo 2560.001000"),
- convert("foo 2560.001000"));
- DoDoubleTest(convert("foo %+f"), val, convert("foo +2560.001000"),
- convert("foo +2560.001000"));
- DoDoubleTest(convert("foo % f"), val, convert("foo 2560.001000"),
- convert("foo 2560.001000"));
- DoDoubleTest(convert("foo %+f"), neg, convert("foo -2560.001000"),
- convert("foo -2560.001000"));
- DoDoubleTest(convert("foo % f"), neg, convert("foo -2560.001000"),
- convert("foo -2560.001000"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test16/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test16/testinfo.dat
deleted file mode 100644
index b7134c785b..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test16/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _vsnwprintf
-Name = Positive Test for _vsnwprintf
-TYPE = DEFAULT
-EXE1 = test16
-Description
-= Tests the PAL implementation of the _vsnwprintf function.
-= Tests _vsnwprintf with decimal point format doubles.
-= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test17/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test17/CMakeLists.txt
deleted file mode 100644
index f429e94417..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test17/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test17.c
-)
-
-add_executable(paltest_vsnwprintf_test17
- ${SOURCES}
-)
-
-add_dependencies(paltest_vsnwprintf_test17 coreclrpal)
-
-target_link_libraries(paltest_vsnwprintf_test17
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test17/test17.c b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test17/test17.c
deleted file mode 100644
index 3a9d70ad03..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test17/test17.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: test17.c
-**
-** Purpose: Test #17 for the _vsnwprintf function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-#include "../_vsnwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-int __cdecl main(int argc, char *argv[])
-{
- double val = 2560.001;
- double neg = -2560.001;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return(FAIL);
- }
-
- DoDoubleTest(convert("foo %g"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %lg"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %hg"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %Lg"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %I64g"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %5g"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %-5g"), val, convert("foo 2560 "),
- convert("foo 2560 "));
- DoDoubleTest(convert("foo %.1g"), val, convert("foo 3e+003"),
- convert("foo 3e+03"));
- DoDoubleTest(convert("foo %.2g"), val, convert("foo 2.6e+003"),
- convert("foo 2.6e+03"));
- DoDoubleTest(convert("foo %.12g"), val, convert("foo 2560.001"),
- convert("foo 2560.001"));
- DoDoubleTest(convert("foo %06g"), val, convert("foo 002560"),
- convert("foo 002560"));
- DoDoubleTest(convert("foo %#g"), val, convert("foo 2560.00"),
- convert("foo 2560.00"));
- DoDoubleTest(convert("foo %+g"), val, convert("foo +2560"),
- convert("foo +2560"));
- DoDoubleTest(convert("foo % g"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %+g"), neg, convert("foo -2560"),
- convert("foo -2560"));
- DoDoubleTest(convert("foo % g"), neg, convert("foo -2560"),
- convert("foo -2560"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test17/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test17/testinfo.dat
deleted file mode 100644
index 5d5553151e..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test17/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _vsnwprintf
-Name = Positive Test for _vsnwprintf
-TYPE = DEFAULT
-EXE1 = test17
-Description
-= Tests the PAL implementation of the _vsnwprintf function.
-= Tests _vsnwprintf with compact format doubles (lowercase).
-= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test18/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test18/CMakeLists.txt
deleted file mode 100644
index 25dd6a2c5b..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test18/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test18.c
-)
-
-add_executable(paltest_vsnwprintf_test18
- ${SOURCES}
-)
-
-add_dependencies(paltest_vsnwprintf_test18 coreclrpal)
-
-target_link_libraries(paltest_vsnwprintf_test18
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test18/test18.c b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test18/test18.c
deleted file mode 100644
index 03f9870113..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test18/test18.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: test18.c
-**
-** Purpose: Test #18 for the _vsnwprintf function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-#include "../_vsnwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-int __cdecl main(int argc, char *argv[])
-{
- double val = 2560.001;
- double neg = -2560.001;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return(FAIL);
- }
-
- DoDoubleTest(convert("foo %G"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %lG"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %hG"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %LG"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %I64G"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %5G"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %-5G"), val, convert("foo 2560 "),
- convert("foo 2560 "));
- DoDoubleTest(convert("foo %.1G"), val, convert("foo 3E+003"),
- convert("foo 3E+03"));
- DoDoubleTest(convert("foo %.2G"), val, convert("foo 2.6E+003"),
- convert("foo 2.6E+03"));
- DoDoubleTest(convert("foo %.12G"), val, convert("foo 2560.001"),
- convert("foo 2560.001"));
- DoDoubleTest(convert("foo %06G"), val, convert("foo 002560"),
- convert("foo 002560"));
- DoDoubleTest(convert("foo %#G"), val, convert("foo 2560.00"),
- convert("foo 2560.00"));
- DoDoubleTest(convert("foo %+G"), val, convert("foo +2560"),
- convert("foo +2560"));
- DoDoubleTest(convert("foo % G"), val, convert("foo 2560"),
- convert("foo 2560"));
- DoDoubleTest(convert("foo %+G"), neg, convert("foo -2560"),
- convert("foo -2560"));
- DoDoubleTest(convert("foo % G"), neg, convert("foo -2560"),
- convert("foo -2560"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test18/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test18/testinfo.dat
deleted file mode 100644
index f56c80980d..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test18/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _vsnwprintf
-Name = Positive Test for _vsnwprintf
-TYPE = DEFAULT
-EXE1 = test18
-Description
-= Tests the PAL implementation of the _vsnwprintf function.
-= Tests _vsnwprintf with compact format doubles (uppercase).
-= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test19/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test19/CMakeLists.txt
deleted file mode 100644
index 9c636b8b0a..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test19/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test19.c
-)
-
-add_executable(paltest_vsnwprintf_test19
- ${SOURCES}
-)
-
-add_dependencies(paltest_vsnwprintf_test19 coreclrpal)
-
-target_link_libraries(paltest_vsnwprintf_test19
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test19/test19.c b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test19/test19.c
deleted file mode 100644
index fea275a242..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test19/test19.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: test18.c
-**
-** Purpose: Test #18 for the _vsnwprintf function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-#include "../_vsnwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-#define DOTEST(a,b,c,d,e) DoTest(a,b,(void*)c,d,e)
-
-void DoArgumentPrecTest(WCHAR *formatstr, int precision, void *param,
- WCHAR *paramstr, WCHAR *checkstr1, WCHAR *checkstr2)
-{
- WCHAR buf[256];
-
- TestVsnwprintf(buf, 256, formatstr, precision, param);
- if (memcmp(buf, checkstr1, wcslen(checkstr1) + 2) != 0 &&
- memcmp(buf, checkstr2, wcslen(checkstr2) + 2) != 0)
- {
- Fail("ERROR: failed to insert %s into \"%s\" with precision %d\n"
- "Expected \"%s\" or \"%s\", got \"%s\".\n",
- paramstr,
- convertC(formatstr),
- precision,
- convertC(checkstr1),
- convertC(checkstr2),
- convertC(buf));
- }
-}
-void DoArgumentPrecDoubleTest(WCHAR *formatstr, int precision, double param,
- WCHAR *checkstr1, WCHAR *checkstr2)
-{
- WCHAR buf[256];
-
- TestVsnwprintf(buf, 256, formatstr, precision, param);
- if (memcmp(buf, checkstr1, wcslen(checkstr1) + 2) != 0 &&
- memcmp(buf, checkstr2, wcslen(checkstr2) + 2) != 0)
- {
- Fail("ERROR: failed to insert %f into \"%s\" with precision %d\n"
- "Expected \"%s\" or \"%s\", got \"%s\".\n",
- param, convertC(formatstr),
- precision,
- convertC(checkstr1),
- convertC(checkstr2),
- convertC(buf));
- }
-}
-
-/*
- * Uses memcmp & wcslen
- */
-
-int __cdecl main(int argc, char *argv[])
-{
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return(FAIL);
- }
-
- DoArgumentPrecTest(convert("%.*s"), 2, convert("bar"), convert("bar"),
- convert("ba"), convert("ba"));
- DoArgumentPrecTest(convert("%.*c"), 0, (void*)'a', convert("a"),
- convert("a"), convert("a"));
- DoArgumentPrecTest(convert("%.*c"), 4, (void*)'a', convert("a"),
- convert("a"), convert("a"));
- DoArgumentPrecTest(convert("%.*C"), 0, (void*)'a', convert("a"),
- convert("a"), convert("a"));
- DoArgumentPrecTest(convert("%.*C"), 4, (void*)'a', convert("a"),
- convert("a"), convert("a"));
- DoArgumentPrecTest(convert("%.*d"), 1, (void*)42, convert("42"),
- convert("42"), convert("42"));
- DoArgumentPrecTest(convert("%.*d"), 3, (void*)42, convert("42"),
- convert("042"), convert("042"));
- DoArgumentPrecTest(convert("%.*i"), 1, (void*)42, convert("42"),
- convert("42"), convert("42"));
- DoArgumentPrecTest(convert("%.*i"), 3, (void*)42, convert("42"),
- convert("042"), convert("042"));
- DoArgumentPrecTest(convert("%.*o"), 1, (void*)42, convert("42"),
- convert("52"), convert("52"));
- DoArgumentPrecTest(convert("%.*o"), 3, (void*)42, convert("42"),
- convert("052"), convert("052"));
- DoArgumentPrecTest(convert("%.*u"), 1, (void*)42, convert("42"),
- convert("42"), convert("42"));
- DoArgumentPrecTest(convert("%.*u"), 3, (void*)42, convert("42"),
- convert("042"), convert("042"));
- DoArgumentPrecTest(convert("%.*x"), 1, (void*)0x42, convert("0x42"),
- convert("42"), convert("42"));
- DoArgumentPrecTest(convert("%.*x"), 3, (void*)0x42, convert("0x42"),
- convert("042"), convert("042"));
- DoArgumentPrecTest(convert("%.*X"), 1, (void*)0x42, convert("0x42"),
- convert("42"), convert("42"));
- DoArgumentPrecTest(convert("%.*X"), 3, (void*)0x42, convert("0x42"),
- convert("042"), convert("042"));
-
-
- DoArgumentPrecDoubleTest(convert("%.*e"), 1, 2.01, convert("2.0e+000"),
- convert("2.0e+00"));
- DoArgumentPrecDoubleTest(convert("%.*e"), 3, 2.01, convert("2.010e+000"),
- convert("2.010e+00"));
- DoArgumentPrecDoubleTest(convert("%.*E"), 1, 2.01, convert("2.0E+000"),
- convert("2.0E+00"));
- DoArgumentPrecDoubleTest(convert("%.*E"), 3, 2.01, convert("2.010E+000"),
- convert("2.010E+00"));
- DoArgumentPrecDoubleTest(convert("%.*f"), 1, 2.01, convert("2.0"),
- convert("2.0"));
- DoArgumentPrecDoubleTest(convert("%.*f"), 3, 2.01, convert("2.010"),
- convert("2.010"));
- DoArgumentPrecDoubleTest(convert("%.*g"), 1, 256.01, convert("3e+002"),
- convert("3e+02"));
- DoArgumentPrecDoubleTest(convert("%.*g"), 3, 256.01, convert("256"),
- convert("256"));
- DoArgumentPrecDoubleTest(convert("%.*g"), 4, 256.01, convert("256"),
- convert("256"));
- DoArgumentPrecDoubleTest(convert("%.*g"), 6, 256.01, convert("256.01"),
- convert("256.01"));
- DoArgumentPrecDoubleTest(convert("%.*G"), 1, 256.01, convert("3E+002"),
- convert("3E+02"));
- DoArgumentPrecDoubleTest(convert("%.*G"), 3, 256.01, convert("256"),
- convert("256"));
- DoArgumentPrecDoubleTest(convert("%.*G"), 4, 256.01, convert("256"),
- convert("256"));
- DoArgumentPrecDoubleTest(convert("%.*G"), 6, 256.01, convert("256.01"),
- convert("256.01"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test19/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test19/testinfo.dat
deleted file mode 100644
index 77178f1471..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test19/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _vsnwprintf
-Name = Positive Test for _vsnwprintf
-TYPE = DEFAULT
-EXE1 = test19
-Description
-= Tests the PAL implementation of the _vsnwprintf function.
-= Tests _vsnwprintf with argument specified precision.
-= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test2/CMakeLists.txt
deleted file mode 100644
index 817657ea61..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test2/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test2.c
-)
-
-add_executable(paltest_vsnwprintf_test2
- ${SOURCES}
-)
-
-add_dependencies(paltest_vsnwprintf_test2 coreclrpal)
-
-target_link_libraries(paltest_vsnwprintf_test2
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test2/test2.c b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test2/test2.c
deleted file mode 100644
index 20499954db..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test2/test2.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: test2.c
-**
-** Purpose: Test #2 for the _vsnwprintf function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-#include "../_vsnwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-
-int __cdecl main(int argc, char *argv[])
-{
- if (PAL_Initialize(argc, argv) != 0)
- return(FAIL);
-
- DoWStrTest(convert("foo %s"), convert("bar"), convert("foo bar"));
- DoStrTest(convert("foo %hs"), "bar", convert("foo bar"));
- DoWStrTest(convert("foo %ls"), convert("bar"), convert("foo bar"));
- DoWStrTest(convert("foo %ws"), convert("bar"), convert("foo bar"));
- DoWStrTest(convert("foo %Ls"), convert("bar"), convert("foo bar"));
- DoWStrTest(convert("foo %I64s"), convert("bar"), convert("foo bar"));
- DoWStrTest(convert("foo %5s"), convert("bar"), convert("foo bar"));
- DoWStrTest(convert("foo %.2s"), convert("bar"), convert("foo ba"));
- DoWStrTest(convert("foo %5.2s"), convert("bar"), convert("foo ba"));
- DoWStrTest(convert("foo %-5s"), convert("bar"), convert("foo bar "));
- DoWStrTest(convert("foo %05s"), convert("bar"), convert("foo 00bar"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test2/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test2/testinfo.dat
deleted file mode 100644
index 429911bd83..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test2/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _vsnwprintf
-Name = Positive Test for _vsnwprintf
-TYPE = DEFAULT
-EXE1 = test2
-Description
-= Tests the PAL implementation of the _vsnwprintf function.
-= Tests _vsnwprintf with strings.
-= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test3/CMakeLists.txt
deleted file mode 100644
index 4af3e36f3b..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test3/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test3.c
-)
-
-add_executable(paltest_vsnwprintf_test3
- ${SOURCES}
-)
-
-add_dependencies(paltest_vsnwprintf_test3 coreclrpal)
-
-target_link_libraries(paltest_vsnwprintf_test3
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test3/test3.c b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test3/test3.c
deleted file mode 100644
index 9a37d3fc4b..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test3/test3.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: test3.c
-**
-** Purpose: Test #3 for the _vsnwprintf function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-#include "../_vsnwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-
-int __cdecl main(int argc, char *argv[])
-{
- if (PAL_Initialize(argc, argv) != 0)
- return(FAIL);
-
- DoStrTest(convert("foo %S"), "bar", convert("foo bar"));
- DoStrTest(convert("foo %hS"), "bar", convert("foo bar"));
- DoWStrTest(convert("foo %lS"), convert("bar"), convert("foo bar"));
- DoWStrTest(convert("foo %wS"), convert("bar"), convert("foo bar"));
- DoStrTest(convert("foo %LS"), "bar", convert("foo bar"));
- DoStrTest(convert("foo %I64S"), "bar", convert("foo bar"));
- DoStrTest(convert("foo %5S"), "bar", convert("foo bar"));
- DoStrTest(convert("foo %.2S"), "bar", convert("foo ba"));
- DoStrTest(convert("foo %5.2S"), "bar", convert("foo ba"));
- DoStrTest(convert("foo %-5S"), "bar", convert("foo bar "));
- DoStrTest(convert("foo %05S"), "bar", convert("foo 00bar"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test3/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test3/testinfo.dat
deleted file mode 100644
index d4e2686763..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test3/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _vsnwprintf
-Name = Positive Test for _vsnwprintf
-TYPE = DEFAULT
-EXE1 = test3
-Description
-= Tests the PAL implementation of the _vsnwprintf function.
-= Tests _vsnwprintf with wide strings.
-= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test4/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test4/CMakeLists.txt
deleted file mode 100644
index b7ff9e7bb3..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test4/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test4.c
-)
-
-add_executable(paltest_vsnwprintf_test4
- ${SOURCES}
-)
-
-add_dependencies(paltest_vsnwprintf_test4 coreclrpal)
-
-target_link_libraries(paltest_vsnwprintf_test4
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test4/test4.c b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test4/test4.c
deleted file mode 100644
index 6f39be2a80..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test4/test4.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: test4.c
-**
-** Purpose: Test #4 for the _vsnwprintf function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-#include "../_vsnwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-static void DoPointerTest(WCHAR *formatstr, void* param, WCHAR* paramstr,
- WCHAR *checkstr1)
-{
- WCHAR buf[256] = { 0 };
-
- TestVsnwprintf(buf, 256, formatstr, param);
- if (memcmp(buf, checkstr1, wcslen(checkstr1) + 2) != 0)
-
- {
- Fail("ERROR: failed to insert pointer to %#p into \"%s\"\n"
- "Expected \"%s\" got \"%s\".\n",
- paramstr,
- convertC(formatstr),
- convertC(checkstr1),
- convertC(buf));
- }
-}
-
-static void DoI64DoubleTest(WCHAR *formatstr, INT64 value, WCHAR *valuestr,
- WCHAR *checkstr1)
-{
- WCHAR buf[256] = { 0 };
-
- TestVsnwprintf(buf, 256, formatstr, value);
- if (memcmp(buf, checkstr1, wcslen(checkstr1) + 2) != 0)
- {
- Fail("ERROR: failed to insert %s into \"%s\"\n"
- "Expected \"%s\", got \"%s\".\n",
- value,
- convertC(formatstr),
- convertC(checkstr1),
- convertC(buf));
- }
-}
-
-int __cdecl main(int argc, char *argv[])
-{
- void *ptr = (void*) 0x123456;
- INT64 lptr = I64(0x1234567887654321);
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return(FAIL);
- }
-
-/*
-** Run only on 64 bit platforms
-*/
-#if defined(BIT64) && defined(PLATFORM_UNIX)
- Trace("Testing for 64 Bit Platforms \n");
- DoPointerTest(convert("%p"), NULL, convert("NULL"), convert("00000000"));
- DoPointerTest(convert("%p"), ptr, convert("pointer to 0x123456"),
- convert("0000000000123456"));
- DoPointerTest(convert("%17p"), ptr, convert("pointer to 0x123456"),
- convert(" 0000000000123456"));
- DoPointerTest(convert("%17p"), ptr, convert("pointer to 0x123456"),
- convert(" 0000000000123456"));
- DoPointerTest(convert("%-17p"), ptr, convert("pointer to 0x123456"),
- convert("0000000000123456 "));
- DoPointerTest(convert("%+p"), ptr, convert("pointer to 0x123456"),
- convert("0000000000123456"));
- DoPointerTest(convert("%#p"), ptr, convert("pointer to 0x123456"),
- convert("0X0000000000123456"));
- DoPointerTest(convert("%lp"), ptr, convert("pointer to 0x123456"),
- convert("00123456"));
- DoPointerTest(convert("%hp"), ptr, convert("pointer to 0x123456"),
- convert("00003456"));
- DoPointerTest(convert("%Lp"), ptr, convert("pointer to 0x123456"),
- convert("00123456"));
- DoI64DoubleTest(convert("%I64p"), lptr,
- convert("pointer to 0x1234567887654321"),
- convert("1234567887654321"));
-
-#else
- Trace("Testing for Non 64 Bit Platforms \n");
- DoPointerTest(convert("%p"), NULL, convert("NULL"), convert("00000000"));
- DoPointerTest(convert("%p"), ptr, convert("pointer to 0x123456"),
- convert("00123456"));
- DoPointerTest(convert("%9p"), ptr, convert("pointer to 0x123456"),
- convert(" 00123456"));
- DoPointerTest(convert("%09p"), ptr, convert("pointer to 0x123456"),
- convert(" 00123456"));
- DoPointerTest(convert("%-9p"), ptr, convert("pointer to 0x123456"),
- convert("00123456 "));
- DoPointerTest(convert("%+p"), ptr, convert("pointer to 0x123456"),
- convert("00123456"));
- DoPointerTest(convert("%#p"), ptr, convert("pointer to 0x123456"),
- convert("0X00123456"));
- DoPointerTest(convert("%lp"), ptr, convert("pointer to 0x123456"),
- convert("00123456"));
- DoPointerTest(convert("%hp"), ptr, convert("pointer to 0x123456"),
- convert("00003456"));
- DoPointerTest(convert("%Lp"), ptr, convert("pointer to 0x123456"),
- convert("00123456"));
- DoI64DoubleTest(convert("%I64p"), lptr,
- convert("pointer to 0x1234567887654321"),
- convert("1234567887654321"));
-#endif
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test4/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test4/testinfo.dat
deleted file mode 100644
index 56f488a66a..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test4/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _vsnwprintf
-Name = Positive Test for _vsnwprintf
-TYPE = DEFAULT
-EXE1 = test4
-Description
-= Tests the PAL implementation of the _vsnwprintf function.
-= Tests _vsnwprintf with pointers.
-= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test5/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test5/CMakeLists.txt
deleted file mode 100644
index 9b316b9f90..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test5/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test5.c
-)
-
-add_executable(paltest_vsnwprintf_test5
- ${SOURCES}
-)
-
-add_dependencies(paltest_vsnwprintf_test5 coreclrpal)
-
-target_link_libraries(paltest_vsnwprintf_test5
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test5/test5.c b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test5/test5.c
deleted file mode 100644
index 224db766ff..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test5/test5.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: test5.c
-**
-** Purpose: Test #5 for the _vsnwprintf function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-#include "../_vsnwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-static void DoTest(WCHAR *formatstr, int param, WCHAR *checkstr)
-{
- WCHAR buf[256] = { 0 };
- int n = -1;
-
- TestVsnwprintf(buf, 256, formatstr, &n);
-
- if (n != param)
- {
- Fail("ERROR: Expected count parameter to resolve to %d, got %d\n",
- param, n);
- }
-
- if (memcmp(buf, checkstr, wcslen(buf)*2 + 2) != 0)
- {
- Fail("ERROR: Expected \"%s\" got \"%s\".\n",
- convertC(checkstr), convertC(buf));
- }
-}
-
-static void DoShortTest(WCHAR *formatstr, int param, WCHAR *checkstr)
-{
- WCHAR buf[256] = { 0 };
- short int n = -1;
-
- TestVsnwprintf(buf, 256, formatstr, &n);
-
- if (n != param)
- {
- Fail("ERROR: Expected count parameter to resolve to %d, got %d\n",
- param, n);
- }
-
- if (memcmp(buf, checkstr, wcslen(buf)*2 + 2) != 0)
- {
- Fail("ERROR: Expected \"%s\" got \"%s\".\n",
- convertC(checkstr), convertC(buf));
- }
-}
-
-int __cdecl main(int argc, char *argv[])
-{
- if (PAL_Initialize(argc, argv) != 0)
- {
- return(FAIL);
- }
-
- DoTest(convert("foo %n bar"), 4, convert("foo bar"));
- DoTest(convert("foo %#n bar"), 4, convert("foo bar"));
- DoTest(convert("foo % n bar"), 4, convert("foo bar"));
- DoTest(convert("foo %+n bar"), 4, convert("foo bar"));
- DoTest(convert("foo %-n bar"), 4, convert("foo bar"));
- DoTest(convert("foo %0n bar"), 4, convert("foo bar"));
- DoShortTest(convert("foo %hn bar"), 4, convert("foo bar"));
- DoTest(convert("foo %ln bar"), 4, convert("foo bar"));
- DoTest(convert("foo %Ln bar"), 4, convert("foo bar"));
- DoTest(convert("foo %I64n bar"), 4, convert("foo bar"));
- DoTest(convert("foo %20.3n bar"), 4, convert("foo bar"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test5/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test5/testinfo.dat
deleted file mode 100644
index 35d3816a76..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test5/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _vsnwprintf
-Name = Positive Test for _vsnwprintf
-TYPE = DEFAULT
-EXE1 = test5
-Description
-= Tests the PAL implementation of the _vsnwprintf function.
-= Tests _vsnwprintf with the count specifier.
-= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test6/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test6/CMakeLists.txt
deleted file mode 100644
index d3fad03597..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test6/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test6.c
-)
-
-add_executable(paltest_vsnwprintf_test6
- ${SOURCES}
-)
-
-add_dependencies(paltest_vsnwprintf_test6 coreclrpal)
-
-target_link_libraries(paltest_vsnwprintf_test6
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test6/test6.c b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test6/test6.c
deleted file mode 100644
index 1bd83ea85c..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test6/test6.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: test6.c
-**
-** Purpose: Test #6 for the _vsnwprintf function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-#include "../_vsnwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-int __cdecl main(int argc, char *argv[])
-{
- WCHAR wc = (WCHAR) 'c';
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return(FAIL);
- }
-
- DoWCharTest(convert("foo %c"), wc, convert("foo c"));
- DoCharTest(convert("foo %hc"), 'b', convert("foo b"));
- DoWCharTest(convert("foo %lc"), wc, convert("foo c"));
- DoWCharTest(convert("foo %Lc"), wc, convert("foo c"));
- DoWCharTest(convert("foo %I64c"), wc, convert("foo c"));
- DoWCharTest(convert("foo %5c"), wc, convert("foo c"));
- DoWCharTest(convert("foo %.0c"), wc, convert("foo c"));
- DoWCharTest(convert("foo %-5c"), wc, convert("foo c "));
- DoWCharTest(convert("foo %05c"), wc, convert("foo 0000c"));
- DoWCharTest(convert("foo % c"), wc, convert("foo c"));
- DoWCharTest(convert("foo %#c"), wc, convert("foo c"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test6/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test6/testinfo.dat
deleted file mode 100644
index 6afe96d1cd..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test6/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _vsnwprintf
-Name = Positive Test for _vsnwprintf
-TYPE = DEFAULT
-EXE1 = test6
-Description
-= Tests the PAL implementation of the _vsnwprintf function.
-= Tests _vsnwprintf with characters.
-= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test7/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test7/CMakeLists.txt
deleted file mode 100644
index cede861358..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test7/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test7.c
-)
-
-add_executable(paltest_vsnwprintf_test7
- ${SOURCES}
-)
-
-add_dependencies(paltest_vsnwprintf_test7 coreclrpal)
-
-target_link_libraries(paltest_vsnwprintf_test7
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test7/test7.c b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test7/test7.c
deleted file mode 100644
index e13798b784..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test7/test7.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: test7.c
-**
-** Purpose: Test #7 for the _vsnwprintf function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-#include "../_vsnwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-int __cdecl main(int argc, char *argv[])
-{
- WCHAR wc = (WCHAR) 'c';
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return(FAIL);
- }
-
- DoCharTest(convert("foo %C"), 'b', convert("foo b"));
- DoWCharTest(convert("foo %hC"), wc, convert("foo c"));
- DoCharTest(convert("foo %lC"), 'b', convert("foo b"));
- DoCharTest(convert("foo %LC"), 'b', convert("foo b"));
- DoCharTest(convert("foo %I64C"), 'b', convert("foo b"));
- DoCharTest(convert("foo %5C"), 'b', convert("foo b"));
- DoCharTest(convert("foo %.0C"), 'b', convert("foo b"));
- DoCharTest(convert("foo %-5C"), 'b', convert("foo b "));
- DoCharTest(convert("foo %05C"), 'b', convert("foo 0000b"));
- DoCharTest(convert("foo % C"), 'b', convert("foo b"));
- DoCharTest(convert("foo %#C"), 'b', convert("foo b"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test7/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test7/testinfo.dat
deleted file mode 100644
index ece40aa195..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test7/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _vsnwprintf
-Name = Positive Test for _vsnwprintf
-TYPE = DEFAULT
-EXE1 = test7
-Description
-= Tests the PAL implementation of the _vsnwprintf function.
-= Tests _vsnwprintf with wide characters.
-= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test8/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test8/CMakeLists.txt
deleted file mode 100644
index 846e7b9219..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test8/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test8.c
-)
-
-add_executable(paltest_vsnwprintf_test8
- ${SOURCES}
-)
-
-add_dependencies(paltest_vsnwprintf_test8 coreclrpal)
-
-target_link_libraries(paltest_vsnwprintf_test8
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test8/test8.c b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test8/test8.c
deleted file mode 100644
index 8f02412eb0..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test8/test8.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: test8.c
-**
-** Purpose: Test #8 for the _vsnwprintf function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-#include "../_vsnwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-int __cdecl main(int argc, char *argv[])
-{
- int neg = -42;
- int pos = 42;
- INT64 l = 42;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return(FAIL);
- }
-
- DoNumTest(convert("foo %d"), pos, convert("foo 42"));
- DoNumTest(convert("foo %ld"), 0xFFFF, convert("foo 65535"));
- DoNumTest(convert("foo %hd"), 0xFFFF, convert("foo -1"));
- DoNumTest(convert("foo %Ld"), pos, convert("foo 42"));
- DoI64NumTest(convert("foo %I64d"), l, "42", convert("foo 42"));
- DoNumTest(convert("foo %3d"), pos, convert("foo 42"));
- DoNumTest(convert("foo %-3d"), pos, convert("foo 42 "));
- DoNumTest(convert("foo %.1d"), pos, convert("foo 42"));
- DoNumTest(convert("foo %.3d"), pos, convert("foo 042"));
- DoNumTest(convert("foo %03d"), pos, convert("foo 042"));
- DoNumTest(convert("foo %#d"), pos, convert("foo 42"));
- DoNumTest(convert("foo %+d"), pos, convert("foo +42"));
- DoNumTest(convert("foo % d"), pos, convert("foo 42"));
- DoNumTest(convert("foo %+d"), neg, convert("foo -42"));
- DoNumTest(convert("foo % d"), neg, convert("foo -42"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test8/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test8/testinfo.dat
deleted file mode 100644
index d7a567a6d6..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test8/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _vsnwprintf
-Name = Positive Test for _vsnwprintf
-TYPE = DEFAULT
-EXE1 = test8
-Description
-= Tests the PAL implementation of the _vsnwprintf function.
-= Tests _vsnwprintf with decimal numbers.
-= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test9/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test9/CMakeLists.txt
deleted file mode 100644
index e25eded172..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test9/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test9.c
-)
-
-add_executable(paltest_vsnwprintf_test9
- ${SOURCES}
-)
-
-add_dependencies(paltest_vsnwprintf_test9 coreclrpal)
-
-target_link_libraries(paltest_vsnwprintf_test9
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test9/test9.c b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test9/test9.c
deleted file mode 100644
index 7b5b6cd8a6..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test9/test9.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: test9.c
-**
-** Purpose: Test #9 for the _vsnwprintf function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-#include "../_vsnwprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-int __cdecl main(int argc, char *argv[])
-{
- int neg = -42;
- int pos = 42;
- INT64 l = 42;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return(FAIL);
- }
-
- DoNumTest(convert("foo %i"), pos, convert("foo 42"));
- DoNumTest(convert("foo %li"), 0xFFFF, convert("foo 65535"));
- DoNumTest(convert("foo %hi"), 0xFFFF, convert("foo -1"));
- DoNumTest(convert("foo %Li"), pos, convert("foo 42"));
- DoI64NumTest(convert("foo %I64i"), l, "42", convert("foo 42"));
- DoNumTest(convert("foo %3i"), pos, convert("foo 42"));
- DoNumTest(convert("foo %-3i"), pos, convert("foo 42 "));
- DoNumTest(convert("foo %.1i"), pos, convert("foo 42"));
- DoNumTest(convert("foo %.3i"), pos, convert("foo 042"));
- DoNumTest(convert("foo %03i"), pos, convert("foo 042"));
- DoNumTest(convert("foo %#i"), pos, convert("foo 42"));
- DoNumTest(convert("foo %+i"), pos, convert("foo +42"));
- DoNumTest(convert("foo % i"), pos, convert("foo 42"));
- DoNumTest(convert("foo %+i"), neg, convert("foo -42"));
- DoNumTest(convert("foo % i"), neg, convert("foo -42"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test9/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test9/testinfo.dat
deleted file mode 100644
index 726b060240..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_vsnwprintf/test9/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _vsnwprintf
-Name = Positive Test for _vsnwprintf
-TYPE = DEFAULT
-EXE1 = test9
-Description
-= Tests the PAL implementation of the _vsnwprintf function.
-= Tests _vsnwprintf with integer numbers
-= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/CMakeLists.txt
new file mode 100644
index 0000000000..8fe1cb60ac
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/CMakeLists.txt
@@ -0,0 +1,21 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test10)
+add_subdirectory(test11)
+add_subdirectory(test12)
+add_subdirectory(test13)
+add_subdirectory(test14)
+add_subdirectory(test15)
+add_subdirectory(test16)
+add_subdirectory(test17)
+add_subdirectory(test18)
+add_subdirectory(test19)
+add_subdirectory(test2)
+add_subdirectory(test3)
+add_subdirectory(test4)
+add_subdirectory(test6)
+add_subdirectory(test7)
+add_subdirectory(test8)
+add_subdirectory(test9)
+
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/_vsnwprintf_s.h b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/_vsnwprintf_s.h
new file mode 100644
index 0000000000..34cf411c25
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/_vsnwprintf_s.h
@@ -0,0 +1,133 @@
+// Licensed to the .NET Foundation under one or more 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: _vsnwprintf_s.h
+**
+** Purpose: Containts common testing functions for _vsnwprintf_s
+**
+**
+**==========================================================================*/
+
+#ifndef ___VSNWPRINTF_H__
+#define ___VSNWPRINTF_H__
+
+/* These functions leaks memory like crazy. C'est la vie. */
+int TestVsnwprintf_s(wchar_t* buf, size_t count, const wchar_t* format, ...)
+{
+ int retVal = 0;
+ va_list arglist;
+
+ va_start(arglist, format);
+ retVal = _vsnwprintf_s(buf, count, _TRUNCATE, format, arglist);
+ va_end(arglist);
+
+ return( retVal);
+}
+
+
+void DoWStrTest(const WCHAR *formatstr, WCHAR *param, const WCHAR *checkstr)
+{
+ WCHAR buf[256] = { 0 };
+
+ TestVsnwprintf_s(buf, 256, formatstr, param);
+
+ if (memcmp(buf, checkstr, wcslen(buf) * 2 + 2) != 0)
+ {
+ Fail("ERROR: failed to insert wide string \"%s\" into \"%s\".\n"
+ "Expected \"%s\", got \"%s\".\n",
+ convertC(param), convertC(formatstr),
+ convertC(checkstr), convertC(buf));
+ }
+}
+
+void DoStrTest(const WCHAR *formatstr, char *param, const WCHAR *checkstr)
+{
+ WCHAR buf[256] = { 0 };
+
+ TestVsnwprintf_s(buf, 256, formatstr, param);
+
+ if (memcmp(buf, checkstr, wcslen(buf) * 2 + 2) != 0)
+ {
+ Fail("ERROR: failed to insert wide string \"%s\" into \"%s\".\n"
+ "Expected \"%s\", got \"%s\".\n",
+ param, convertC(formatstr), convertC(checkstr),
+ convertC(buf));
+ }
+}
+
+void DoCharTest(const WCHAR *formatstr, char param, const WCHAR *checkstr)
+{
+ WCHAR buf[256] = { 0 };
+
+ TestVsnwprintf_s(buf, 256, formatstr, param);
+ if (memcmp(buf, checkstr, wcslen(buf)*2 + 2) != 0)
+ {
+ Fail("ERROR: failed to insert char \'%c\' (%d) into \"%s\"\n"
+ "Expected \"%s\" got \"%s\".\n",
+ param, param, convertC(formatstr), convertC(checkstr),
+ convertC(buf));
+ }
+}
+
+void DoWCharTest(const WCHAR *formatstr, WCHAR param, const WCHAR *checkstr)
+{
+ WCHAR buf[256] = { 0 };
+
+ TestVsnwprintf_s(buf, 256, formatstr, param);
+ if (memcmp(buf, checkstr, wcslen(buf)*2 + 2) != 0)
+ {
+ Fail("ERROR: failed to insert wide char \'%c\' (%d) into \"%s\"\n"
+ "Expected \"%s\" got \"%s\".\n",
+ (char) param, param, convertC(formatstr),
+ convertC(checkstr), convertC(buf));
+ }
+}
+
+void DoNumTest(const WCHAR *formatstr, int value, const WCHAR *checkstr)
+{
+ WCHAR buf[256] = { 0 };
+
+ TestVsnwprintf_s(buf, 256, formatstr, value);
+ if (memcmp(buf, checkstr, wcslen(buf)* 2 + 2) != 0)
+ {
+ Fail("ERROR: failed to insert %#x into \"%s\"\n"
+ "Expected \"%s\" got \"%s\".\n", value, convertC(formatstr),
+ convertC(checkstr), convertC(buf));
+ }
+}
+
+void DoI64NumTest(const WCHAR *formatstr, INT64 value, char *valuestr, const WCHAR *checkstr)
+{
+ WCHAR buf[256] = { 0 };
+
+ TestVsnwprintf_s(buf, 256, formatstr, value);
+ if (memcmp(buf, checkstr, wcslen(buf)* 2 + 2) != 0)
+ {
+ Fail("ERROR: failed to insert %s into \"%s\"\n"
+ "Expected \"%s\" got \"%s\".\n", valuestr, convertC(formatstr),
+ convertC(checkstr), convertC(buf));
+ }
+}
+void DoDoubleTest(const WCHAR *formatstr, double value,
+ const WCHAR *checkstr1, const WCHAR *checkstr2)
+{
+ WCHAR buf[256] = { 0 };
+
+ TestVsnwprintf_s(buf, 256, formatstr, value);
+ if (memcmp(buf, checkstr1, wcslen(checkstr1) + 2) != 0 &&
+ memcmp(buf, checkstr2, wcslen(checkstr2) + 2) != 0)
+ {
+ Fail("ERROR: failed to insert %f into \"%s\"\n"
+ "Expected \"%s\" or \"%s\", got \"%s\".\n",
+ value,
+ convertC(formatstr),
+ convertC(checkstr1),
+ convertC(checkstr2),
+ convertC(buf));
+ }
+}
+
+#endif
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test1/CMakeLists.txt
new file mode 100644
index 0000000000..d1245168f3
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.cpp
+)
+
+add_executable(paltest_vsnwprintf_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_vsnwprintf_test1 coreclrpal)
+
+target_link_libraries(paltest_vsnwprintf_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test1/test1.cpp b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test1/test1.cpp
new file mode 100644
index 0000000000..4a7a02e778
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test1/test1.cpp
@@ -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.
+
+/*=====================================================================
+**
+** Source: test1.c
+**
+** Purpose: Test #1 for the _vsnwprintf_s function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+#include "../_vsnwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ WCHAR *checkstr;
+ WCHAR buf[256] = { 0 };
+ int ret;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return(FAIL);
+ }
+
+ checkstr = convert("hello world");
+ TestVsnwprintf_s(buf, 256, checkstr);
+ if (memcmp(checkstr, buf, wcslen(checkstr)*2+2) != 0)
+ {
+ Fail("ERROR: Expected \"%s\", got \"%s\"\n",
+ convertC(checkstr), convertC(buf));
+ }
+
+ TestVsnwprintf_s(buf, 256, convert("xxxxxxxxxxxxxxxxx"));
+ ret = TestVsnwprintf_s(buf, 8, checkstr);
+ if ((memcmp(checkstr, buf, 14)) != 0 || (buf[7] != 0))
+ {
+ Fail("ERROR: Expected \"%8s\", got \"%8s\"\n",
+ convertC(checkstr), convertC(buf));
+ }
+ if (ret >= 0)
+ {
+ Fail("ERROR: Expected negative return value, got %d.\n", ret);
+ }
+ if (buf[8] != (WCHAR) 'x')
+ {
+ Fail("ERROR: buffer overflow using \"%s\" with length 8.\n",
+ convertC(checkstr));
+ }
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test1/testinfo.dat
new file mode 100644
index 0000000000..450c5b9034
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/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 = C Runtime
+Function = _vsnwprintf_s
+Name = Positive Test for _vsnwprintf_s
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Tests the PAL implementation of the _vsnwprintf_s function.
+= General test to see if _vsnwprintf_s works correctly.
+= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test10/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test10/CMakeLists.txt
new file mode 100644
index 0000000000..6367964f1d
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test10/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test10.cpp
+)
+
+add_executable(paltest_vsnwprintf_test10
+ ${SOURCES}
+)
+
+add_dependencies(paltest_vsnwprintf_test10 coreclrpal)
+
+target_link_libraries(paltest_vsnwprintf_test10
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test10/test10.cpp b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test10/test10.cpp
new file mode 100644
index 0000000000..e33f2281df
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test10/test10.cpp
@@ -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.
+
+/*=====================================================================
+**
+** Source: test10.c
+**
+** Purpose: Test #10 for the _vsnwprintf_s function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+#include "../_vsnwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+int __cdecl main(int argc, char *argv[])
+{
+ int neg = -42;
+ int pos = 42;
+ INT64 l = 42;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return(FAIL);
+ }
+
+ DoNumTest(convert("foo %o"), pos, convert("foo 52"));
+ DoNumTest(convert("foo %lo"), 0xFFFF, convert("foo 177777"));
+ DoNumTest(convert("foo %ho"), 0xFFFF, convert("foo 177777"));
+ DoNumTest(convert("foo %Lo"), pos, convert("foo 52"));
+ DoI64NumTest(convert("foo %I64o"), l, "42", convert("foo 52"));
+ DoNumTest(convert("foo %3o"), pos, convert("foo 52"));
+ DoNumTest(convert("foo %-3o"), pos, convert("foo 52 "));
+ DoNumTest(convert("foo %.1o"), pos, convert("foo 52"));
+ DoNumTest(convert("foo %.3o"), pos, convert("foo 052"));
+ DoNumTest(convert("foo %03o"), pos, convert("foo 052"));
+ DoNumTest(convert("foo %#o"), pos, convert("foo 052"));
+ DoNumTest(convert("foo %+o"), pos, convert("foo 52"));
+ DoNumTest(convert("foo % o"), pos, convert("foo 52"));
+ DoNumTest(convert("foo %+o"), neg, convert("foo 37777777726"));
+ DoNumTest(convert("foo % o"), neg, convert("foo 37777777726"));
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test10/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test10/testinfo.dat
new file mode 100644
index 0000000000..59af082f49
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test10/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 = C Runtime
+Function = _vsnwprintf_s
+Name = Positive Test for _vsnwprintf_s
+TYPE = DEFAULT
+EXE1 = test10
+Description
+= Tests the PAL implementation of the _vsnwprintf_s function.
+= Tests _vsnwprintf_s with octal numbers.
+= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test11/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test11/CMakeLists.txt
new file mode 100644
index 0000000000..b45fd0ed1e
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test11/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test11.cpp
+)
+
+add_executable(paltest_vsnwprintf_test11
+ ${SOURCES}
+)
+
+add_dependencies(paltest_vsnwprintf_test11 coreclrpal)
+
+target_link_libraries(paltest_vsnwprintf_test11
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test11/test11.cpp b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test11/test11.cpp
new file mode 100644
index 0000000000..4e860bbc21
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test11/test11.cpp
@@ -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.
+
+/*=====================================================================
+**
+** Source: test11.c
+**
+** Purpose: Test #11 for the _vsnwprintf_s function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+#include "../_vsnwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+int __cdecl main(int argc, char *argv[])
+{
+ int neg = -42;
+ int pos = 42;
+ INT64 l = 42;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return(FAIL);
+ }
+
+ DoNumTest(convert("foo %u"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %lu"), 0xFFFF, convert("foo 65535"));
+ DoNumTest(convert("foo %hu"), 0xFFFF, convert("foo 65535"));
+ DoNumTest(convert("foo %Lu"), pos, convert("foo 42"));
+ DoI64NumTest(convert("foo %I64u"), l, "42", convert("foo 42"));
+ DoNumTest(convert("foo %3u"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %-3u"), pos, convert("foo 42 "));
+ DoNumTest(convert("foo %.1u"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %.3u"), pos, convert("foo 042"));
+ DoNumTest(convert("foo %03u"), pos, convert("foo 042"));
+ DoNumTest(convert("foo %#u"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %+u"), pos, convert("foo 42"));
+ DoNumTest(convert("foo % u"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %+u"), neg, convert("foo 4294967254"));
+ DoNumTest(convert("foo % u"), neg, convert("foo 4294967254"));
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test11/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test11/testinfo.dat
new file mode 100644
index 0000000000..10c0014fca
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test11/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 = C Runtime
+Function = _vsnwprintf_s
+Name = Positive Test for _vsnwprintf_s
+TYPE = DEFAULT
+EXE1 = test11
+Description
+= Tests the PAL implementation of the _vsnwprintf_s function.
+= Tests _vsnwprintf_s with unsigned numbers.
+= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test12/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test12/CMakeLists.txt
new file mode 100644
index 0000000000..2a15b198c0
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test12/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test12.cpp
+)
+
+add_executable(paltest_vsnwprintf_test12
+ ${SOURCES}
+)
+
+add_dependencies(paltest_vsnwprintf_test12 coreclrpal)
+
+target_link_libraries(paltest_vsnwprintf_test12
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test12/test12.cpp b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test12/test12.cpp
new file mode 100644
index 0000000000..2dcfcf5998
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test12/test12.cpp
@@ -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.
+
+/*=====================================================================
+**
+** Source: test12.c
+**
+** Purpose: Test #12 for the _vsnwprintf_s function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+#include "../_vsnwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+int __cdecl main(int argc, char *argv[])
+{
+ int neg = -42;
+ int pos = 0x1234ab;
+ INT64 l = I64(0x1234567887654321);
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return(FAIL);
+ }
+
+ DoNumTest(convert("foo %x"), pos, convert("foo 1234ab"));
+ DoNumTest(convert("foo %lx"), pos, convert("foo 1234ab"));
+ DoNumTest(convert("foo %hx"), pos, convert("foo 34ab"));
+ DoNumTest(convert("foo %Lx"), pos, convert("foo 1234ab"));
+ DoI64NumTest(convert("foo %I64x"), l, "0x1234567887654321",
+ convert("foo 1234567887654321"));
+ DoNumTest(convert("foo %7x"), pos, convert("foo 1234ab"));
+ DoNumTest(convert("foo %-7x"), pos, convert("foo 1234ab "));
+ DoNumTest(convert("foo %.1x"), pos, convert("foo 1234ab"));
+ DoNumTest(convert("foo %.7x"), pos, convert("foo 01234ab"));
+ DoNumTest(convert("foo %07x"), pos, convert("foo 01234ab"));
+ DoNumTest(convert("foo %#x"), pos, convert("foo 0x1234ab"));
+ DoNumTest(convert("foo %+x"), pos, convert("foo 1234ab"));
+ DoNumTest(convert("foo % x"), pos, convert("foo 1234ab"));
+ DoNumTest(convert("foo %+x"), neg, convert("foo ffffffd6"));
+ DoNumTest(convert("foo % x"), neg, convert("foo ffffffd6"));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test12/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test12/testinfo.dat
new file mode 100644
index 0000000000..de089895b9
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test12/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 = C Runtime
+Function = _vsnwprintf_s
+Name = Positive Test for _vsnwprintf_s
+TYPE = DEFAULT
+EXE1 = test12
+Description
+= Tests the PAL implementation of the _vsnwprintf_s function.
+= Tests _vsnwprintf_s with hex numbers (lowercase).
+= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test13/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test13/CMakeLists.txt
new file mode 100644
index 0000000000..01ab97cc62
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test13/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test13.cpp
+)
+
+add_executable(paltest_vsnwprintf_test13
+ ${SOURCES}
+)
+
+add_dependencies(paltest_vsnwprintf_test13 coreclrpal)
+
+target_link_libraries(paltest_vsnwprintf_test13
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test13/test13.cpp b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test13/test13.cpp
new file mode 100644
index 0000000000..c95278a56b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test13/test13.cpp
@@ -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.
+
+/*=====================================================================
+**
+** Source: test13.c
+**
+** Purpose: Test #13 for the _vsnwprintf_s function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+#include "../_vsnwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+int __cdecl main(int argc, char *argv[])
+{
+ int neg = -42;
+ int pos = 0x1234ab;
+ INT64 l = I64(0x1234567887654321);
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return(FAIL);
+ }
+
+ DoNumTest(convert("foo %X"), pos, convert("foo 1234AB"));
+ DoNumTest(convert("foo %lX"), pos, convert("foo 1234AB"));
+ DoNumTest(convert("foo %hX"), pos, convert("foo 34AB"));
+ DoNumTest(convert("foo %LX"), pos, convert("foo 1234AB"));
+ DoI64NumTest(convert("foo %I64X"), l, "0x1234567887654321",
+ convert("foo 1234567887654321"));
+ DoNumTest(convert("foo %7X"), pos, convert("foo 1234AB"));
+ DoNumTest(convert("foo %-7X"), pos, convert("foo 1234AB "));
+ DoNumTest(convert("foo %.1X"), pos, convert("foo 1234AB"));
+ DoNumTest(convert("foo %.7X"), pos, convert("foo 01234AB"));
+ DoNumTest(convert("foo %07X"), pos, convert("foo 01234AB"));
+ DoNumTest(convert("foo %#X"), pos, convert("foo 0X1234AB"));
+ DoNumTest(convert("foo %+X"), pos, convert("foo 1234AB"));
+ DoNumTest(convert("foo % X"), pos, convert("foo 1234AB"));
+ DoNumTest(convert("foo %+X"), neg, convert("foo FFFFFFD6"));
+ DoNumTest(convert("foo % X"), neg, convert("foo FFFFFFD6"));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test13/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test13/testinfo.dat
new file mode 100644
index 0000000000..94479d527c
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test13/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 = C Runtime
+Function = _vsnwprintf_s
+Name = Positive Test for _vsnwprintf_s
+TYPE = DEFAULT
+EXE1 = test13
+Description
+= Tests the PAL implementation of the _vsnwprintf_s function.
+= Tests _vsnwprintf_s with hex numbers (uppercase).
+= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test14/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test14/CMakeLists.txt
new file mode 100644
index 0000000000..c6c990312f
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test14/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test14.cpp
+)
+
+add_executable(paltest_vsnwprintf_test14
+ ${SOURCES}
+)
+
+add_dependencies(paltest_vsnwprintf_test14 coreclrpal)
+
+target_link_libraries(paltest_vsnwprintf_test14
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test14/test14.cpp b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test14/test14.cpp
new file mode 100644
index 0000000000..cab1b247df
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test14/test14.cpp
@@ -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.
+
+/*=====================================================================
+**
+** Source: test14.c
+**
+** Purpose: Test #14 for the _vsnwprintf_s function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+#include "../_vsnwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+int __cdecl main(int argc, char *argv[])
+{
+ double val = 256.0;
+ double neg = -256.0;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return(FAIL);
+ }
+
+ DoDoubleTest(convert("foo %e"), val, convert("foo 2.560000e+002"),
+ convert("foo 2.560000e+02"));
+ DoDoubleTest(convert("foo %le"), val, convert("foo 2.560000e+002"),
+ convert("foo 2.560000e+02"));
+ DoDoubleTest(convert("foo %he"), val, convert("foo 2.560000e+002"),
+ convert("foo 2.560000e+02"));
+ DoDoubleTest(convert("foo %Le"), val, convert("foo 2.560000e+002"),
+ convert("foo 2.560000e+02"));
+ DoDoubleTest(convert("foo %I64e"), val, convert("foo 2.560000e+002"),
+ convert("foo 2.560000e+02"));
+ DoDoubleTest(convert("foo %14e"), val, convert("foo 2.560000e+002"),
+ convert("foo 2.560000e+02"));
+ DoDoubleTest(convert("foo %-14e"), val, convert("foo 2.560000e+002 "),
+ convert("foo 2.560000e+02 "));
+ DoDoubleTest(convert("foo %.1e"), val, convert("foo 2.6e+002"),
+ convert("foo 2.6e+02"));
+ DoDoubleTest(convert("foo %.8e"), val, convert("foo 2.56000000e+002"),
+ convert("foo 2.56000000e+02"));
+ DoDoubleTest(convert("foo %014e"), val, convert("foo 02.560000e+002"),
+ convert("foo 002.560000e+02"));
+ DoDoubleTest(convert("foo %#e"), val, convert("foo 2.560000e+002"),
+ convert("foo 2.560000e+02"));
+ DoDoubleTest(convert("foo %+e"), val, convert("foo +2.560000e+002"),
+ convert("foo +2.560000e+02"));
+ DoDoubleTest(convert("foo % e"), val, convert("foo 2.560000e+002"),
+ convert("foo 2.560000e+02"));
+ DoDoubleTest(convert("foo %+e"), neg, convert("foo -2.560000e+002"),
+ convert("foo -2.560000e+02"));
+ DoDoubleTest(convert("foo % e"), neg, convert("foo -2.560000e+002"),
+ convert("foo -2.560000e+02"));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test14/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test14/testinfo.dat
new file mode 100644
index 0000000000..0d46d97649
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test14/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 = C Runtime
+Function = _vsnwprintf_s
+Name = Positive Test for _vsnwprintf_s
+TYPE = DEFAULT
+EXE1 = test14
+Description
+= Tests the PAL implementation of the _vsnwprintf_s function.
+= Tests _vsnwprintf_s with exponential format doubles (lowercase).
+= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test15/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test15/CMakeLists.txt
new file mode 100644
index 0000000000..e1a32b1825
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test15/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test15.cpp
+)
+
+add_executable(paltest_vsnwprintf_test15
+ ${SOURCES}
+)
+
+add_dependencies(paltest_vsnwprintf_test15 coreclrpal)
+
+target_link_libraries(paltest_vsnwprintf_test15
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test15/test15.cpp b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test15/test15.cpp
new file mode 100644
index 0000000000..d5738991a6
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test15/test15.cpp
@@ -0,0 +1,64 @@
+// Licensed to the .NET Foundation under one or more 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: test15.c
+**
+** Purpose: Test #15 for the _vsnwprintf_s function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+#include "../_vsnwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ double val = 256.0;
+ double neg = -256.0;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return(FAIL);
+ }
+
+ DoDoubleTest(convert("foo %E"), val, convert("foo 2.560000E+002"),
+ convert("foo 2.560000E+02"));
+ DoDoubleTest(convert("foo %lE"), val, convert("foo 2.560000E+002"),
+ convert("foo 2.560000E+02"));
+ DoDoubleTest(convert("foo %hE"), val, convert("foo 2.560000E+002"),
+ convert("foo 2.560000E+02"));
+ DoDoubleTest(convert("foo %LE"), val, convert("foo 2.560000E+002"),
+ convert("foo 2.560000E+02"));
+ DoDoubleTest(convert("foo %I64E"), val, convert("foo 2.560000E+002"),
+ convert("foo 2.560000E+02"));
+ DoDoubleTest(convert("foo %14E"), val, convert("foo 2.560000E+002"),
+ convert("foo 2.560000E+02"));
+ DoDoubleTest(convert("foo %-14E"), val, convert("foo 2.560000E+002 "),
+ convert("foo 2.560000E+02 "));
+ DoDoubleTest(convert("foo %.1E"), val, convert("foo 2.6E+002"),
+ convert("foo 2.6E+02"));
+ DoDoubleTest(convert("foo %.8E"), val, convert("foo 2.56000000E+002"),
+ convert("foo 2.56000000E+02"));
+ DoDoubleTest(convert("foo %014E"), val, convert("foo 02.560000E+002"),
+ convert("foo 002.560000E+02"));
+ DoDoubleTest(convert("foo %#E"), val, convert("foo 2.560000E+002"),
+ convert("foo 2.560000E+02"));
+ DoDoubleTest(convert("foo %+E"), val, convert("foo +2.560000E+002"),
+ convert("foo +2.560000E+02"));
+ DoDoubleTest(convert("foo % E"), val, convert("foo 2.560000E+002"),
+ convert("foo 2.560000E+02"));
+ DoDoubleTest(convert("foo %+E"), neg, convert("foo -2.560000E+002"),
+ convert("foo -2.560000E+02"));
+ DoDoubleTest(convert("foo % E"), neg, convert("foo -2.560000E+002"),
+ convert("foo -2.560000E+002"));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test15/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test15/testinfo.dat
new file mode 100644
index 0000000000..7737f49a35
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test15/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 = C Runtime
+Function = _vsnwprintf_s
+Name = Positive Test for _vsnwprintf_s
+TYPE = DEFAULT
+EXE1 = test15
+Description
+= Tests the PAL implementation of the _vsnwprintf_s function.
+= Tests _vsnwprintf_s with exponential format doubles (uppercase).
+= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test16/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test16/CMakeLists.txt
new file mode 100644
index 0000000000..9e2b25b308
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test16/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test16.cpp
+)
+
+add_executable(paltest_vsnwprintf_test16
+ ${SOURCES}
+)
+
+add_dependencies(paltest_vsnwprintf_test16 coreclrpal)
+
+target_link_libraries(paltest_vsnwprintf_test16
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test16/test16.cpp b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test16/test16.cpp
new file mode 100644
index 0000000000..72c546eb63
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test16/test16.cpp
@@ -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.
+
+/*=====================================================================
+**
+** Source: test16.c
+**
+** Purpose: Test #16 for the _vsnwprintf_s function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+#include "../_vsnwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+int __cdecl main(int argc, char *argv[])
+{
+ double val = 2560.001;
+ double neg = -2560.001;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return(FAIL);
+ }
+
+ DoDoubleTest(convert("foo %f"), val, convert("foo 2560.001000"),
+ convert("foo 2560.001000"));
+ DoDoubleTest(convert("foo %lf"), val, convert("foo 2560.001000"),
+ convert("foo 2560.001000"));
+ DoDoubleTest(convert("foo %hf"), val, convert("foo 2560.001000"),
+ convert("foo 2560.001000"));
+ DoDoubleTest(convert("foo %Lf"), val, convert("foo 2560.001000"),
+ convert("foo 2560.001000"));
+ DoDoubleTest(convert("foo %I64f"), val, convert("foo 2560.001000"),
+ convert("foo 2560.001000"));
+ DoDoubleTest(convert("foo %12f"), val, convert("foo 2560.001000"),
+ convert("foo 2560.001000"));
+ DoDoubleTest(convert("foo %-12f"), val, convert("foo 2560.001000 "),
+ convert("foo 2560.001000 "));
+ DoDoubleTest(convert("foo %.1f"), val, convert("foo 2560.0"),
+ convert("foo 2560.0"));
+ DoDoubleTest(convert("foo %.8f"), val, convert("foo 2560.00100000"),
+ convert("foo 2560.00100000"));
+ DoDoubleTest(convert("foo %012f"), val, convert("foo 02560.001000"),
+ convert("foo 02560.001000"));
+ DoDoubleTest(convert("foo %#f"), val, convert("foo 2560.001000"),
+ convert("foo 2560.001000"));
+ DoDoubleTest(convert("foo %+f"), val, convert("foo +2560.001000"),
+ convert("foo +2560.001000"));
+ DoDoubleTest(convert("foo % f"), val, convert("foo 2560.001000"),
+ convert("foo 2560.001000"));
+ DoDoubleTest(convert("foo %+f"), neg, convert("foo -2560.001000"),
+ convert("foo -2560.001000"));
+ DoDoubleTest(convert("foo % f"), neg, convert("foo -2560.001000"),
+ convert("foo -2560.001000"));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test16/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test16/testinfo.dat
new file mode 100644
index 0000000000..9aec1c008a
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test16/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 = C Runtime
+Function = _vsnwprintf_s
+Name = Positive Test for _vsnwprintf_s
+TYPE = DEFAULT
+EXE1 = test16
+Description
+= Tests the PAL implementation of the _vsnwprintf_s function.
+= Tests _vsnwprintf_s with decimal point format doubles.
+= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test17/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test17/CMakeLists.txt
new file mode 100644
index 0000000000..2d8ba31a08
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test17/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test17.cpp
+)
+
+add_executable(paltest_vsnwprintf_test17
+ ${SOURCES}
+)
+
+add_dependencies(paltest_vsnwprintf_test17 coreclrpal)
+
+target_link_libraries(paltest_vsnwprintf_test17
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test17/test17.cpp b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test17/test17.cpp
new file mode 100644
index 0000000000..e6860b930f
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test17/test17.cpp
@@ -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.
+
+/*=====================================================================
+**
+** Source: test17.c
+**
+** Purpose: Test #17 for the _vsnwprintf_s function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+#include "../_vsnwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+int __cdecl main(int argc, char *argv[])
+{
+ double val = 2560.001;
+ double neg = -2560.001;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return(FAIL);
+ }
+
+ DoDoubleTest(convert("foo %g"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %lg"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %hg"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %Lg"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %I64g"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %5g"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %-5g"), val, convert("foo 2560 "),
+ convert("foo 2560 "));
+ DoDoubleTest(convert("foo %.1g"), val, convert("foo 3e+003"),
+ convert("foo 3e+03"));
+ DoDoubleTest(convert("foo %.2g"), val, convert("foo 2.6e+003"),
+ convert("foo 2.6e+03"));
+ DoDoubleTest(convert("foo %.12g"), val, convert("foo 2560.001"),
+ convert("foo 2560.001"));
+ DoDoubleTest(convert("foo %06g"), val, convert("foo 002560"),
+ convert("foo 002560"));
+ DoDoubleTest(convert("foo %#g"), val, convert("foo 2560.00"),
+ convert("foo 2560.00"));
+ DoDoubleTest(convert("foo %+g"), val, convert("foo +2560"),
+ convert("foo +2560"));
+ DoDoubleTest(convert("foo % g"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %+g"), neg, convert("foo -2560"),
+ convert("foo -2560"));
+ DoDoubleTest(convert("foo % g"), neg, convert("foo -2560"),
+ convert("foo -2560"));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test17/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test17/testinfo.dat
new file mode 100644
index 0000000000..1487b7a17e
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test17/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 = C Runtime
+Function = _vsnwprintf_s
+Name = Positive Test for _vsnwprintf_s
+TYPE = DEFAULT
+EXE1 = test17
+Description
+= Tests the PAL implementation of the _vsnwprintf_s function.
+= Tests _vsnwprintf_s with compact format doubles (lowercase).
+= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test18/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test18/CMakeLists.txt
new file mode 100644
index 0000000000..503856c2f3
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test18/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test18.cpp
+)
+
+add_executable(paltest_vsnwprintf_test18
+ ${SOURCES}
+)
+
+add_dependencies(paltest_vsnwprintf_test18 coreclrpal)
+
+target_link_libraries(paltest_vsnwprintf_test18
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test18/test18.cpp b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test18/test18.cpp
new file mode 100644
index 0000000000..a164edbc0f
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test18/test18.cpp
@@ -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.
+
+/*=====================================================================
+**
+** Source: test18.c
+**
+** Purpose: Test #18 for the _vsnwprintf_s function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+#include "../_vsnwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+int __cdecl main(int argc, char *argv[])
+{
+ double val = 2560.001;
+ double neg = -2560.001;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return(FAIL);
+ }
+
+ DoDoubleTest(convert("foo %G"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %lG"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %hG"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %LG"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %I64G"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %5G"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %-5G"), val, convert("foo 2560 "),
+ convert("foo 2560 "));
+ DoDoubleTest(convert("foo %.1G"), val, convert("foo 3E+003"),
+ convert("foo 3E+03"));
+ DoDoubleTest(convert("foo %.2G"), val, convert("foo 2.6E+003"),
+ convert("foo 2.6E+03"));
+ DoDoubleTest(convert("foo %.12G"), val, convert("foo 2560.001"),
+ convert("foo 2560.001"));
+ DoDoubleTest(convert("foo %06G"), val, convert("foo 002560"),
+ convert("foo 002560"));
+ DoDoubleTest(convert("foo %#G"), val, convert("foo 2560.00"),
+ convert("foo 2560.00"));
+ DoDoubleTest(convert("foo %+G"), val, convert("foo +2560"),
+ convert("foo +2560"));
+ DoDoubleTest(convert("foo % G"), val, convert("foo 2560"),
+ convert("foo 2560"));
+ DoDoubleTest(convert("foo %+G"), neg, convert("foo -2560"),
+ convert("foo -2560"));
+ DoDoubleTest(convert("foo % G"), neg, convert("foo -2560"),
+ convert("foo -2560"));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test18/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test18/testinfo.dat
new file mode 100644
index 0000000000..54c4e87c89
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test18/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 = C Runtime
+Function = _vsnwprintf_s
+Name = Positive Test for _vsnwprintf_s
+TYPE = DEFAULT
+EXE1 = test18
+Description
+= Tests the PAL implementation of the _vsnwprintf_s function.
+= Tests _vsnwprintf_s with compact format doubles (uppercase).
+= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test19/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test19/CMakeLists.txt
new file mode 100644
index 0000000000..68485eff12
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test19/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test19.cpp
+)
+
+add_executable(paltest_vsnwprintf_test19
+ ${SOURCES}
+)
+
+add_dependencies(paltest_vsnwprintf_test19 coreclrpal)
+
+target_link_libraries(paltest_vsnwprintf_test19
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test19/test19.cpp b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test19/test19.cpp
new file mode 100644
index 0000000000..c2a85478ae
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test19/test19.cpp
@@ -0,0 +1,139 @@
+// Licensed to the .NET Foundation under one or more 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: test18.c
+**
+** Purpose: Test #18 for the _vsnwprintf_s function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+#include "../_vsnwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+#define DOTEST(a,b,c,d,e) DoTest(a,b,(void*)c,d,e)
+
+void DoArgumentPrecTest(WCHAR *formatstr, int precision, void *param,
+ WCHAR *paramstr, WCHAR *checkstr1, WCHAR *checkstr2)
+{
+ WCHAR buf[256];
+
+ TestVsnwprintf_s(buf, 256, formatstr, precision, param);
+ if (memcmp(buf, checkstr1, wcslen(checkstr1) + 2) != 0 &&
+ memcmp(buf, checkstr2, wcslen(checkstr2) + 2) != 0)
+ {
+ Fail("ERROR: failed to insert %s into \"%s\" with precision %d\n"
+ "Expected \"%s\" or \"%s\", got \"%s\".\n",
+ paramstr,
+ convertC(formatstr),
+ precision,
+ convertC(checkstr1),
+ convertC(checkstr2),
+ convertC(buf));
+ }
+}
+void DoArgumentPrecDoubleTest(WCHAR *formatstr, int precision, double param,
+ WCHAR *checkstr1, WCHAR *checkstr2)
+{
+ WCHAR buf[256];
+
+ TestVsnwprintf_s(buf, 256, formatstr, precision, param);
+ if (memcmp(buf, checkstr1, wcslen(checkstr1) + 2) != 0 &&
+ memcmp(buf, checkstr2, wcslen(checkstr2) + 2) != 0)
+ {
+ Fail("ERROR: failed to insert %f into \"%s\" with precision %d\n"
+ "Expected \"%s\" or \"%s\", got \"%s\".\n",
+ param, convertC(formatstr),
+ precision,
+ convertC(checkstr1),
+ convertC(checkstr2),
+ convertC(buf));
+ }
+}
+
+/*
+ * Uses memcmp & wcslen
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return(FAIL);
+ }
+
+ DoArgumentPrecTest(convert("%.*s"), 2, (void*)convert("bar"), convert("bar"),
+ convert("ba"), convert("ba"));
+ DoArgumentPrecTest(convert("%.*c"), 0, (void*)'a', convert("a"),
+ convert("a"), convert("a"));
+ DoArgumentPrecTest(convert("%.*c"), 4, (void*)'a', convert("a"),
+ convert("a"), convert("a"));
+ DoArgumentPrecTest(convert("%.*C"), 0, (void*)'a', convert("a"),
+ convert("a"), convert("a"));
+ DoArgumentPrecTest(convert("%.*C"), 4, (void*)'a', convert("a"),
+ convert("a"), convert("a"));
+ DoArgumentPrecTest(convert("%.*d"), 1, (void*)42, convert("42"),
+ convert("42"), convert("42"));
+ DoArgumentPrecTest(convert("%.*d"), 3, (void*)42, convert("42"),
+ convert("042"), convert("042"));
+ DoArgumentPrecTest(convert("%.*i"), 1, (void*)42, convert("42"),
+ convert("42"), convert("42"));
+ DoArgumentPrecTest(convert("%.*i"), 3, (void*)42, convert("42"),
+ convert("042"), convert("042"));
+ DoArgumentPrecTest(convert("%.*o"), 1, (void*)42, convert("42"),
+ convert("52"), convert("52"));
+ DoArgumentPrecTest(convert("%.*o"), 3, (void*)42, convert("42"),
+ convert("052"), convert("052"));
+ DoArgumentPrecTest(convert("%.*u"), 1, (void*)42, convert("42"),
+ convert("42"), convert("42"));
+ DoArgumentPrecTest(convert("%.*u"), 3, (void*)42, convert("42"),
+ convert("042"), convert("042"));
+ DoArgumentPrecTest(convert("%.*x"), 1, (void*)0x42, convert("0x42"),
+ convert("42"), convert("42"));
+ DoArgumentPrecTest(convert("%.*x"), 3, (void*)0x42, convert("0x42"),
+ convert("042"), convert("042"));
+ DoArgumentPrecTest(convert("%.*X"), 1, (void*)0x42, convert("0x42"),
+ convert("42"), convert("42"));
+ DoArgumentPrecTest(convert("%.*X"), 3, (void*)0x42, convert("0x42"),
+ convert("042"), convert("042"));
+
+
+ DoArgumentPrecDoubleTest(convert("%.*e"), 1, 2.01, convert("2.0e+000"),
+ convert("2.0e+00"));
+ DoArgumentPrecDoubleTest(convert("%.*e"), 3, 2.01, convert("2.010e+000"),
+ convert("2.010e+00"));
+ DoArgumentPrecDoubleTest(convert("%.*E"), 1, 2.01, convert("2.0E+000"),
+ convert("2.0E+00"));
+ DoArgumentPrecDoubleTest(convert("%.*E"), 3, 2.01, convert("2.010E+000"),
+ convert("2.010E+00"));
+ DoArgumentPrecDoubleTest(convert("%.*f"), 1, 2.01, convert("2.0"),
+ convert("2.0"));
+ DoArgumentPrecDoubleTest(convert("%.*f"), 3, 2.01, convert("2.010"),
+ convert("2.010"));
+ DoArgumentPrecDoubleTest(convert("%.*g"), 1, 256.01, convert("3e+002"),
+ convert("3e+02"));
+ DoArgumentPrecDoubleTest(convert("%.*g"), 3, 256.01, convert("256"),
+ convert("256"));
+ DoArgumentPrecDoubleTest(convert("%.*g"), 4, 256.01, convert("256"),
+ convert("256"));
+ DoArgumentPrecDoubleTest(convert("%.*g"), 6, 256.01, convert("256.01"),
+ convert("256.01"));
+ DoArgumentPrecDoubleTest(convert("%.*G"), 1, 256.01, convert("3E+002"),
+ convert("3E+02"));
+ DoArgumentPrecDoubleTest(convert("%.*G"), 3, 256.01, convert("256"),
+ convert("256"));
+ DoArgumentPrecDoubleTest(convert("%.*G"), 4, 256.01, convert("256"),
+ convert("256"));
+ DoArgumentPrecDoubleTest(convert("%.*G"), 6, 256.01, convert("256.01"),
+ convert("256.01"));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test19/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test19/testinfo.dat
new file mode 100644
index 0000000000..2913e30406
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test19/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 = C Runtime
+Function = _vsnwprintf_s
+Name = Positive Test for _vsnwprintf_s
+TYPE = DEFAULT
+EXE1 = test19
+Description
+= Tests the PAL implementation of the _vsnwprintf_s function.
+= Tests _vsnwprintf_s with argument specified precision.
+= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test2/CMakeLists.txt
new file mode 100644
index 0000000000..a512be6e47
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test2.cpp
+)
+
+add_executable(paltest_vsnwprintf_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_vsnwprintf_test2 coreclrpal)
+
+target_link_libraries(paltest_vsnwprintf_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test2/test2.cpp b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test2/test2.cpp
new file mode 100644
index 0000000000..18e5adffd3
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test2/test2.cpp
@@ -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.
+
+/*=====================================================================
+**
+** Source: test2.c
+**
+** Purpose: Test #2 for the _vsnwprintf_s function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+#include "../_vsnwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ if (PAL_Initialize(argc, argv) != 0)
+ return(FAIL);
+
+ DoWStrTest(convert("foo %s"), convert("bar"), convert("foo bar"));
+ DoStrTest(convert("foo %hs"), "bar", convert("foo bar"));
+ DoWStrTest(convert("foo %ls"), convert("bar"), convert("foo bar"));
+ DoWStrTest(convert("foo %ws"), convert("bar"), convert("foo bar"));
+ DoWStrTest(convert("foo %Ls"), convert("bar"), convert("foo bar"));
+ DoWStrTest(convert("foo %I64s"), convert("bar"), convert("foo bar"));
+ DoWStrTest(convert("foo %5s"), convert("bar"), convert("foo bar"));
+ DoWStrTest(convert("foo %.2s"), convert("bar"), convert("foo ba"));
+ DoWStrTest(convert("foo %5.2s"), convert("bar"), convert("foo ba"));
+ DoWStrTest(convert("foo %-5s"), convert("bar"), convert("foo bar "));
+ DoWStrTest(convert("foo %05s"), convert("bar"), convert("foo 00bar"));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test2/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test2/testinfo.dat
new file mode 100644
index 0000000000..5b9b6292dc
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test2/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 = C Runtime
+Function = _vsnwprintf_s
+Name = Positive Test for _vsnwprintf_s
+TYPE = DEFAULT
+EXE1 = test2
+Description
+= Tests the PAL implementation of the _vsnwprintf_s function.
+= Tests _vsnwprintf_s with strings.
+= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test3/CMakeLists.txt
new file mode 100644
index 0000000000..7991c25afc
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test3/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test3.cpp
+)
+
+add_executable(paltest_vsnwprintf_test3
+ ${SOURCES}
+)
+
+add_dependencies(paltest_vsnwprintf_test3 coreclrpal)
+
+target_link_libraries(paltest_vsnwprintf_test3
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test3/test3.cpp b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test3/test3.cpp
new file mode 100644
index 0000000000..5e2bfa21a0
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test3/test3.cpp
@@ -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.
+
+/*=====================================================================
+**
+** Source: test3.c
+**
+** Purpose: Test #3 for the _vsnwprintf_s function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+#include "../_vsnwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ if (PAL_Initialize(argc, argv) != 0)
+ return(FAIL);
+
+ DoStrTest(convert("foo %S"), "bar", convert("foo bar"));
+ DoStrTest(convert("foo %hS"), "bar", convert("foo bar"));
+ DoWStrTest(convert("foo %lS"), convert("bar"), convert("foo bar"));
+ DoWStrTest(convert("foo %wS"), convert("bar"), convert("foo bar"));
+ DoStrTest(convert("foo %LS"), "bar", convert("foo bar"));
+ DoStrTest(convert("foo %I64S"), "bar", convert("foo bar"));
+ DoStrTest(convert("foo %5S"), "bar", convert("foo bar"));
+ DoStrTest(convert("foo %.2S"), "bar", convert("foo ba"));
+ DoStrTest(convert("foo %5.2S"), "bar", convert("foo ba"));
+ DoStrTest(convert("foo %-5S"), "bar", convert("foo bar "));
+ DoStrTest(convert("foo %05S"), "bar", convert("foo 00bar"));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test3/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test3/testinfo.dat
new file mode 100644
index 0000000000..62160695e6
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test3/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 = C Runtime
+Function = _vsnwprintf_s
+Name = Positive Test for _vsnwprintf_s
+TYPE = DEFAULT
+EXE1 = test3
+Description
+= Tests the PAL implementation of the _vsnwprintf_s function.
+= Tests _vsnwprintf_s with wide strings.
+= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test4/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test4/CMakeLists.txt
new file mode 100644
index 0000000000..18f5d02df2
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test4/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test4.cpp
+)
+
+add_executable(paltest_vsnwprintf_test4
+ ${SOURCES}
+)
+
+add_dependencies(paltest_vsnwprintf_test4 coreclrpal)
+
+target_link_libraries(paltest_vsnwprintf_test4
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test4/test4.cpp b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test4/test4.cpp
new file mode 100644
index 0000000000..3627ff8bc8
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test4/test4.cpp
@@ -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.
+
+/*=====================================================================
+**
+** Source: test4.c
+**
+** Purpose: Test #4 for the _vsnwprintf_s function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+#include "../_vsnwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+static void DoPointerTest(WCHAR *formatstr, void* param, WCHAR* paramstr,
+ WCHAR *checkstr1)
+{
+ WCHAR buf[256] = { 0 };
+
+ TestVsnwprintf_s(buf, 256, formatstr, param);
+ if (memcmp(buf, checkstr1, wcslen(checkstr1) + 2) != 0)
+
+ {
+ Fail("ERROR: failed to insert pointer to %#p into \"%s\"\n"
+ "Expected \"%s\" got \"%s\".\n",
+ paramstr,
+ convertC(formatstr),
+ convertC(checkstr1),
+ convertC(buf));
+ }
+}
+
+static void DoI64DoubleTest(WCHAR *formatstr, INT64 value, WCHAR *valuestr,
+ WCHAR *checkstr1)
+{
+ WCHAR buf[256] = { 0 };
+
+ TestVsnwprintf_s(buf, 256, formatstr, value);
+ if (memcmp(buf, checkstr1, wcslen(checkstr1) + 2) != 0)
+ {
+ Fail("ERROR: failed to insert %s into \"%s\"\n"
+ "Expected \"%s\", got \"%s\".\n",
+ value,
+ convertC(formatstr),
+ convertC(checkstr1),
+ convertC(buf));
+ }
+}
+
+int __cdecl main(int argc, char *argv[])
+{
+ void *ptr = (void*) 0x123456;
+ INT64 lptr = I64(0x1234567887654321);
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return(FAIL);
+ }
+
+/*
+** Run only on 64 bit platforms
+*/
+#if defined(BIT64) && defined(PLATFORM_UNIX)
+ Trace("Testing for 64 Bit Platforms \n");
+ DoPointerTest(convert("%p"), NULL, convert("NULL"), convert("00000000"));
+ DoPointerTest(convert("%p"), ptr, convert("pointer to 0x123456"),
+ convert("0000000000123456"));
+ DoPointerTest(convert("%17p"), ptr, convert("pointer to 0x123456"),
+ convert(" 0000000000123456"));
+ DoPointerTest(convert("%17p"), ptr, convert("pointer to 0x123456"),
+ convert(" 0000000000123456"));
+ DoPointerTest(convert("%-17p"), ptr, convert("pointer to 0x123456"),
+ convert("0000000000123456 "));
+ DoPointerTest(convert("%+p"), ptr, convert("pointer to 0x123456"),
+ convert("0000000000123456"));
+ DoPointerTest(convert("%#p"), ptr, convert("pointer to 0x123456"),
+ convert("0X0000000000123456"));
+ DoPointerTest(convert("%lp"), ptr, convert("pointer to 0x123456"),
+ convert("00123456"));
+ DoPointerTest(convert("%hp"), ptr, convert("pointer to 0x123456"),
+ convert("00003456"));
+ DoPointerTest(convert("%Lp"), ptr, convert("pointer to 0x123456"),
+ convert("00123456"));
+ DoI64DoubleTest(convert("%I64p"), lptr,
+ convert("pointer to 0x1234567887654321"),
+ convert("1234567887654321"));
+
+#else
+ Trace("Testing for Non 64 Bit Platforms \n");
+ DoPointerTest(convert("%p"), NULL, convert("NULL"), convert("00000000"));
+ DoPointerTest(convert("%p"), ptr, convert("pointer to 0x123456"),
+ convert("00123456"));
+ DoPointerTest(convert("%9p"), ptr, convert("pointer to 0x123456"),
+ convert(" 00123456"));
+ DoPointerTest(convert("%09p"), ptr, convert("pointer to 0x123456"),
+ convert(" 00123456"));
+ DoPointerTest(convert("%-9p"), ptr, convert("pointer to 0x123456"),
+ convert("00123456 "));
+ DoPointerTest(convert("%+p"), ptr, convert("pointer to 0x123456"),
+ convert("00123456"));
+ DoPointerTest(convert("%#p"), ptr, convert("pointer to 0x123456"),
+ convert("0X00123456"));
+ DoPointerTest(convert("%lp"), ptr, convert("pointer to 0x123456"),
+ convert("00123456"));
+ DoPointerTest(convert("%hp"), ptr, convert("pointer to 0x123456"),
+ convert("00003456"));
+ DoPointerTest(convert("%Lp"), ptr, convert("pointer to 0x123456"),
+ convert("00123456"));
+ DoI64DoubleTest(convert("%I64p"), lptr,
+ convert("pointer to 0x1234567887654321"),
+ convert("1234567887654321"));
+#endif
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test4/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test4/testinfo.dat
new file mode 100644
index 0000000000..9fbfcba5cf
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test4/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 = C Runtime
+Function = _vsnwprintf_s
+Name = Positive Test for _vsnwprintf_s
+TYPE = DEFAULT
+EXE1 = test4
+Description
+= Tests the PAL implementation of the _vsnwprintf_s function.
+= Tests _vsnwprintf_s with pointers.
+= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test6/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test6/CMakeLists.txt
new file mode 100644
index 0000000000..c431da4a00
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test6/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test6.cpp
+)
+
+add_executable(paltest_vsnwprintf_test6
+ ${SOURCES}
+)
+
+add_dependencies(paltest_vsnwprintf_test6 coreclrpal)
+
+target_link_libraries(paltest_vsnwprintf_test6
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test6/test6.cpp b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test6/test6.cpp
new file mode 100644
index 0000000000..ecba5853a6
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test6/test6.cpp
@@ -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.
+
+/*=====================================================================
+**
+** Source: test6.c
+**
+** Purpose: Test #6 for the _vsnwprintf_s function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+#include "../_vsnwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+int __cdecl main(int argc, char *argv[])
+{
+ WCHAR wc = (WCHAR) 'c';
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return(FAIL);
+ }
+
+ DoWCharTest(convert("foo %c"), wc, convert("foo c"));
+ DoCharTest(convert("foo %hc"), 'b', convert("foo b"));
+ DoWCharTest(convert("foo %lc"), wc, convert("foo c"));
+ DoWCharTest(convert("foo %Lc"), wc, convert("foo c"));
+ DoWCharTest(convert("foo %I64c"), wc, convert("foo c"));
+ DoWCharTest(convert("foo %5c"), wc, convert("foo c"));
+ DoWCharTest(convert("foo %.0c"), wc, convert("foo c"));
+ DoWCharTest(convert("foo %-5c"), wc, convert("foo c "));
+ DoWCharTest(convert("foo %05c"), wc, convert("foo 0000c"));
+ DoWCharTest(convert("foo % c"), wc, convert("foo c"));
+ DoWCharTest(convert("foo %#c"), wc, convert("foo c"));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test6/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test6/testinfo.dat
new file mode 100644
index 0000000000..1b411d7982
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test6/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 = C Runtime
+Function = _vsnwprintf_s
+Name = Positive Test for _vsnwprintf_s
+TYPE = DEFAULT
+EXE1 = test6
+Description
+= Tests the PAL implementation of the _vsnwprintf_s function.
+= Tests _vsnwprintf_s with characters.
+= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test7/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test7/CMakeLists.txt
new file mode 100644
index 0000000000..5759b836b5
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test7/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test7.cpp
+)
+
+add_executable(paltest_vsnwprintf_test7
+ ${SOURCES}
+)
+
+add_dependencies(paltest_vsnwprintf_test7 coreclrpal)
+
+target_link_libraries(paltest_vsnwprintf_test7
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test7/test7.cpp b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test7/test7.cpp
new file mode 100644
index 0000000000..519657a202
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test7/test7.cpp
@@ -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.
+
+/*=====================================================================
+**
+** Source: test7.c
+**
+** Purpose: Test #7 for the _vsnwprintf_s function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+#include "../_vsnwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+int __cdecl main(int argc, char *argv[])
+{
+ WCHAR wc = (WCHAR) 'c';
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return(FAIL);
+ }
+
+ DoCharTest(convert("foo %C"), 'b', convert("foo b"));
+ DoWCharTest(convert("foo %hC"), wc, convert("foo c"));
+ DoCharTest(convert("foo %lC"), 'b', convert("foo b"));
+ DoCharTest(convert("foo %LC"), 'b', convert("foo b"));
+ DoCharTest(convert("foo %I64C"), 'b', convert("foo b"));
+ DoCharTest(convert("foo %5C"), 'b', convert("foo b"));
+ DoCharTest(convert("foo %.0C"), 'b', convert("foo b"));
+ DoCharTest(convert("foo %-5C"), 'b', convert("foo b "));
+ DoCharTest(convert("foo %05C"), 'b', convert("foo 0000b"));
+ DoCharTest(convert("foo % C"), 'b', convert("foo b"));
+ DoCharTest(convert("foo %#C"), 'b', convert("foo b"));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test7/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test7/testinfo.dat
new file mode 100644
index 0000000000..8f2ccf0b58
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test7/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 = C Runtime
+Function = _vsnwprintf_s
+Name = Positive Test for _vsnwprintf_s
+TYPE = DEFAULT
+EXE1 = test7
+Description
+= Tests the PAL implementation of the _vsnwprintf_s function.
+= Tests _vsnwprintf_s with wide characters.
+= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test8/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test8/CMakeLists.txt
new file mode 100644
index 0000000000..5e8a6284a5
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test8/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test8.cpp
+)
+
+add_executable(paltest_vsnwprintf_test8
+ ${SOURCES}
+)
+
+add_dependencies(paltest_vsnwprintf_test8 coreclrpal)
+
+target_link_libraries(paltest_vsnwprintf_test8
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test8/test8.cpp b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test8/test8.cpp
new file mode 100644
index 0000000000..15641f7b9e
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test8/test8.cpp
@@ -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.
+
+/*=====================================================================
+**
+** Source: test8.c
+**
+** Purpose: Test #8 for the _vsnwprintf_s function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+#include "../_vsnwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+int __cdecl main(int argc, char *argv[])
+{
+ int neg = -42;
+ int pos = 42;
+ INT64 l = 42;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return(FAIL);
+ }
+
+ DoNumTest(convert("foo %d"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %ld"), 0xFFFF, convert("foo 65535"));
+ DoNumTest(convert("foo %hd"), 0xFFFF, convert("foo -1"));
+ DoNumTest(convert("foo %Ld"), pos, convert("foo 42"));
+ DoI64NumTest(convert("foo %I64d"), l, "42", convert("foo 42"));
+ DoNumTest(convert("foo %3d"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %-3d"), pos, convert("foo 42 "));
+ DoNumTest(convert("foo %.1d"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %.3d"), pos, convert("foo 042"));
+ DoNumTest(convert("foo %03d"), pos, convert("foo 042"));
+ DoNumTest(convert("foo %#d"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %+d"), pos, convert("foo +42"));
+ DoNumTest(convert("foo % d"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %+d"), neg, convert("foo -42"));
+ DoNumTest(convert("foo % d"), neg, convert("foo -42"));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test8/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test8/testinfo.dat
new file mode 100644
index 0000000000..905740c1bb
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test8/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 = C Runtime
+Function = _vsnwprintf_s
+Name = Positive Test for _vsnwprintf_s
+TYPE = DEFAULT
+EXE1 = test8
+Description
+= Tests the PAL implementation of the _vsnwprintf_s function.
+= Tests _vsnwprintf_s with decimal numbers.
+= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test9/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test9/CMakeLists.txt
new file mode 100644
index 0000000000..323365dcd9
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test9/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test9.cpp
+)
+
+add_executable(paltest_vsnwprintf_test9
+ ${SOURCES}
+)
+
+add_dependencies(paltest_vsnwprintf_test9 coreclrpal)
+
+target_link_libraries(paltest_vsnwprintf_test9
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test9/test9.cpp b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test9/test9.cpp
new file mode 100644
index 0000000000..38f6be21e7
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test9/test9.cpp
@@ -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.
+
+/*=====================================================================
+**
+** Source: test9.c
+**
+** Purpose: Test #9 for the _vsnwprintf_s function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+#include "../_vsnwprintf_s.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+int __cdecl main(int argc, char *argv[])
+{
+ int neg = -42;
+ int pos = 42;
+ INT64 l = 42;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return(FAIL);
+ }
+
+ DoNumTest(convert("foo %i"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %li"), 0xFFFF, convert("foo 65535"));
+ DoNumTest(convert("foo %hi"), 0xFFFF, convert("foo -1"));
+ DoNumTest(convert("foo %Li"), pos, convert("foo 42"));
+ DoI64NumTest(convert("foo %I64i"), l, "42", convert("foo 42"));
+ DoNumTest(convert("foo %3i"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %-3i"), pos, convert("foo 42 "));
+ DoNumTest(convert("foo %.1i"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %.3i"), pos, convert("foo 042"));
+ DoNumTest(convert("foo %03i"), pos, convert("foo 042"));
+ DoNumTest(convert("foo %#i"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %+i"), pos, convert("foo +42"));
+ DoNumTest(convert("foo % i"), pos, convert("foo 42"));
+ DoNumTest(convert("foo %+i"), neg, convert("foo -42"));
+ DoNumTest(convert("foo % i"), neg, convert("foo -42"));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test9/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test9/testinfo.dat
new file mode 100644
index 0000000000..974efdb4cf
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test9/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 = C Runtime
+Function = _vsnwprintf_s
+Name = Positive Test for _vsnwprintf_s
+TYPE = DEFAULT
+EXE1 = test9
+Description
+= Tests the PAL implementation of the _vsnwprintf_s function.
+= Tests _vsnwprintf_s with integer numbers
+= This test is modeled after _snwprintf.
diff --git a/src/pal/tests/palsuite/c_runtime/_wcsicmp/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_wcsicmp/test1/CMakeLists.txt
index 5f085cc723..023b777cab 100644
--- a/src/pal/tests/palsuite/c_runtime/_wcsicmp/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_wcsicmp/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_wcsicmp_test1
diff --git a/src/pal/tests/palsuite/c_runtime/_wcsicmp/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_wcsicmp/test1/test1.cpp
index dd4bb54680..dd4bb54680 100644
--- a/src/pal/tests/palsuite/c_runtime/_wcsicmp/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/_wcsicmp/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_wcslwr/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_wcslwr/test1/CMakeLists.txt
index a78098f86a..b9df132d29 100644
--- a/src/pal/tests/palsuite/c_runtime/_wcslwr/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_wcslwr/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_wcslwr_test1
diff --git a/src/pal/tests/palsuite/c_runtime/_wcslwr/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_wcslwr/test1/test1.cpp
index 3a758de39b..3a758de39b 100644
--- a/src/pal/tests/palsuite/c_runtime/_wcslwr/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/_wcslwr/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_wcsnicmp/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_wcsnicmp/test1/CMakeLists.txt
index afd3560b10..ea22daa477 100644
--- a/src/pal/tests/palsuite/c_runtime/_wcsnicmp/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_wcsnicmp/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_wcsnicmp_test1
diff --git a/src/pal/tests/palsuite/c_runtime/_wcsnicmp/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_wcsnicmp/test1/test1.cpp
index 0271bcc60d..0271bcc60d 100644
--- a/src/pal/tests/palsuite/c_runtime/_wcsnicmp/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/_wcsnicmp/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_wfopen/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_wfopen/test1/CMakeLists.txt
index 96df58ee54..f7aa22d5b2 100644
--- a/src/pal/tests/palsuite/c_runtime/_wfopen/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_wfopen/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_wfopen_test1
diff --git a/src/pal/tests/palsuite/c_runtime/_wfopen/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_wfopen/test1/test1.cpp
index 81d2502cd5..81d2502cd5 100644
--- a/src/pal/tests/palsuite/c_runtime/_wfopen/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/_wfopen/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_wfopen/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_wfopen/test2/CMakeLists.txt
index 47203d86d5..3159889f0a 100644
--- a/src/pal/tests/palsuite/c_runtime/_wfopen/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_wfopen/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_wfopen_test2
diff --git a/src/pal/tests/palsuite/c_runtime/_wfopen/test2/test2.c b/src/pal/tests/palsuite/c_runtime/_wfopen/test2/test2.cpp
index 921ffef19d..921ffef19d 100644
--- a/src/pal/tests/palsuite/c_runtime/_wfopen/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/_wfopen/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_wfopen/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_wfopen/test3/CMakeLists.txt
index deec8bbfe6..06d0941471 100644
--- a/src/pal/tests/palsuite/c_runtime/_wfopen/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_wfopen/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_wfopen_test3
diff --git a/src/pal/tests/palsuite/c_runtime/_wfopen/test3/test3.c b/src/pal/tests/palsuite/c_runtime/_wfopen/test3/test3.cpp
index 3b67818bc5..3b67818bc5 100644
--- a/src/pal/tests/palsuite/c_runtime/_wfopen/test3/test3.c
+++ b/src/pal/tests/palsuite/c_runtime/_wfopen/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_wfopen/test4/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_wfopen/test4/CMakeLists.txt
index e93cdd58de..8253d75d8d 100644
--- a/src/pal/tests/palsuite/c_runtime/_wfopen/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_wfopen/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_wfopen_test4
diff --git a/src/pal/tests/palsuite/c_runtime/_wfopen/test4/test4.c b/src/pal/tests/palsuite/c_runtime/_wfopen/test4/test4.cpp
index 0948fa11cc..0948fa11cc 100644
--- a/src/pal/tests/palsuite/c_runtime/_wfopen/test4/test4.c
+++ b/src/pal/tests/palsuite/c_runtime/_wfopen/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_wfopen/test5/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_wfopen/test5/CMakeLists.txt
index 1530416795..8b3d064ec6 100644
--- a/src/pal/tests/palsuite/c_runtime/_wfopen/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_wfopen/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_wfopen_test5
diff --git a/src/pal/tests/palsuite/c_runtime/_wfopen/test5/test5.c b/src/pal/tests/palsuite/c_runtime/_wfopen/test5/test5.cpp
index 21e5ec84ed..21e5ec84ed 100644
--- a/src/pal/tests/palsuite/c_runtime/_wfopen/test5/test5.c
+++ b/src/pal/tests/palsuite/c_runtime/_wfopen/test5/test5.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_wfopen/test6/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_wfopen/test6/CMakeLists.txt
index c401c6f40f..bf1eaeca27 100644
--- a/src/pal/tests/palsuite/c_runtime/_wfopen/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_wfopen/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test6.c
+ test6.cpp
)
add_executable(paltest_wfopen_test6
diff --git a/src/pal/tests/palsuite/c_runtime/_wfopen/test6/test6.c b/src/pal/tests/palsuite/c_runtime/_wfopen/test6/test6.cpp
index 17d36a0c50..17d36a0c50 100644
--- a/src/pal/tests/palsuite/c_runtime/_wfopen/test6/test6.c
+++ b/src/pal/tests/palsuite/c_runtime/_wfopen/test6/test6.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_wfopen/test7/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_wfopen/test7/CMakeLists.txt
index 47f4804b43..5d04528a21 100644
--- a/src/pal/tests/palsuite/c_runtime/_wfopen/test7/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_wfopen/test7/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test7.c
+ test7.cpp
)
add_executable(paltest_wfopen_test7
diff --git a/src/pal/tests/palsuite/c_runtime/_wfopen/test7/test7.c b/src/pal/tests/palsuite/c_runtime/_wfopen/test7/test7.cpp
index 0a889adc8a..0a889adc8a 100644
--- a/src/pal/tests/palsuite/c_runtime/_wfopen/test7/test7.c
+++ b/src/pal/tests/palsuite/c_runtime/_wfopen/test7/test7.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_wmakepath/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_wmakepath/CMakeLists.txt
deleted file mode 100644
index f6aa0cb2d9..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_wmakepath/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-add_subdirectory(test1)
-
diff --git a/src/pal/tests/palsuite/c_runtime/_wmakepath/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_wmakepath/test1/CMakeLists.txt
deleted file mode 100644
index 343cb41f51..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_wmakepath/test1/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test1.c
-)
-
-add_executable(paltest_wmakepath_test1
- ${SOURCES}
-)
-
-add_dependencies(paltest_wmakepath_test1 coreclrpal)
-
-target_link_libraries(paltest_wmakepath_test1
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_wmakepath/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_wmakepath/test1/test1.c
deleted file mode 100644
index eb79dc6286..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_wmakepath/test1/test1.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: test1.c
-**
-** Purpose: Tests the PAL implementation of the _wmakepath function.
-** Create a path, and ensure that it builds how it is
-** supposed to.
-**
-**
-**===================================================================*/
-
-#define UNICODE
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char **argv)
-{
- WCHAR FullPath[128];
- WCHAR File[] = {'t','e','s','t','\0'};
- WCHAR Ext[] = {'t','x','t','\0'};
- char * PrintResult=NULL; /* Used for printing out errors */
- char * PrintCorrect=NULL;
-
-#if WIN32
- WCHAR Drive[] = {'C','\0'};
- WCHAR Dir[] = {'\\','t','e','s','t','\0'};
- WCHAR PathName[] =
- {'C',':','\\','t','e','s','t','\\','t','e',
- 's','t','.','t','x','t','\0'};
-#else
- WCHAR *Drive = NULL;
- WCHAR Dir[] = {'/','t','e','s','t','\0'};
- WCHAR PathName[] =
- {'/','t','e','s','t','/','t','e','s','t','.','t','x','t','\0'};
-#endif
-
- /*
- * Initialize the PAL and return FAIL if this fails
- */
- if (0 != (PAL_Initialize(argc,argv)))
- {
- return FAIL;
- }
-
- _wmakepath(FullPath, Drive, Dir, File, Ext);
-
- if(wcscmp(FullPath,PathName) != 0)
- {
- PrintResult = convertC(FullPath);
- PrintCorrect = convertC(PathName);
-
- Fail("ERROR: The pathname which was created turned out to be %s "
- "when it was supposed to be %s.\n",PrintResult,PrintCorrect);
- }
-
-
- PAL_Terminate();
- return PASS;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/pal/tests/palsuite/c_runtime/_wmakepath/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_wmakepath/test1/testinfo.dat
deleted file mode 100644
index 6720d342ce..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_wmakepath/test1/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _wmakepath
-Name = Positive Test for _wmakepath
-TYPE = DEFAULT
-EXE1 = test1
-Description
-= Purpose: Tests the PAL implementation of the _wmakepath function.
-= Create a path, and ensure that it builds how it is supposed to.
diff --git a/src/pal/tests/palsuite/c_runtime/_wsplitpath/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_wsplitpath/CMakeLists.txt
deleted file mode 100644
index f6aa0cb2d9..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_wsplitpath/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-add_subdirectory(test1)
-
diff --git a/src/pal/tests/palsuite/c_runtime/_wsplitpath/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_wsplitpath/test1/CMakeLists.txt
deleted file mode 100644
index ee9a7a8e96..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_wsplitpath/test1/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test1.c
-)
-
-add_executable(paltest_wsplitpath_test1
- ${SOURCES}
-)
-
-add_dependencies(paltest_wsplitpath_test1 coreclrpal)
-
-target_link_libraries(paltest_wsplitpath_test1
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/_wsplitpath/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_wsplitpath/test1/test1.c
deleted file mode 100644
index 305768e53a..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_wsplitpath/test1/test1.c
+++ /dev/null
@@ -1,151 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: test1.c
-**
-** Purpose: Passes _wsplitpath() a series of sample paths and checks
-** that it parses them as expected.
-**
-**
-**==========================================================================*/
-
-
-#include <palsuite.h>
-
-struct testCase
-{
- char path[_MAX_PATH]; /* The path to parse. */
- char drive[_MAX_DRIVE]; /* The expected values... */
- char dir[_MAX_DIR];
- char fname[_MAX_FNAME];
- char ext[_MAX_EXT];
-};
-
-struct wTestCase
-{
- WCHAR *path; /* The path to parse. */
- WCHAR *drive; /* The expected values... */
- WCHAR *dir;
- WCHAR *fname;
- WCHAR *ext;
-};
-
-
-
-int __cdecl main(int argc, char **argv)
-{
- struct testCase testCases[] =
- {
-#if WIN32
- {"c:\\foo\\bar\\foo.bar", "c:", "\\foo\\bar\\", "foo", ".bar"},
- {"c:/foo/bar/foo.bar", "c:", "/foo/bar/", "foo", ".bar"},
- {"c:/foo/bar/foo", "c:", "/foo/bar/", "foo", ""},
- {"c:/foo/bar/.bar", "c:", "/foo/bar/", "", ".bar"},
- {"c:/foo/bar/", "c:", "/foo/bar/", "", ""},
- {"/foo/bar/foo.bar", "", "/foo/bar/", "foo", ".bar"},
- {"c:foo.bar", "c:", "", "foo", ".bar"}
-#else
- {"c:\\foo\\bar\\foo.bar", "","c:/foo/bar/", "foo", ".bar"},
- {"c:/foo/bar/foo.bar", "", "c:/foo/bar/", "foo", ".bar"},
- {"c:/foo/bar/foo", "", "c:/foo/bar/", "foo", ""},
- {"c:/foo/bar/.bar", "", "c:/foo/bar/", ".bar", ""},
- {"c:/foo/bar/", "", "c:/foo/bar/", "", ""},
- {"/foo/bar/foo.bar", "", "/foo/bar/", "foo", ".bar"},
- {"c:foo.bar", "", "", "c:foo", ".bar"}
-#endif
- };
-
- struct wTestCase wTestCases[sizeof(testCases)/sizeof(struct testCase)];
-
- wchar_t wDrive[_MAX_DRIVE];
- wchar_t wDir[_MAX_DIR];
- wchar_t wFname[_MAX_FNAME];
- wchar_t wExt[_MAX_EXT];
-
- char *drive;
- char *dir;
- char *fname;
- char *ext;
-
- int i;
-
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
-
- /*create wide character versions of the test cases*/
- for(i = 0; i < sizeof(testCases)/sizeof(struct testCase); i ++)
- {
- wTestCases[i].path = convert(testCases[i].path);
- wTestCases[i].drive = convert(testCases[i].drive);
- wTestCases[i].dir = convert(testCases[i].dir);
- wTestCases[i].fname = convert(testCases[i].fname);
- wTestCases[i].ext = convert(testCases[i].ext);
- }
-
-
- for (i = 0; i < sizeof(wTestCases)/sizeof(struct wTestCase); i++)
- {
- _wsplitpath(wTestCases[i].path, wDrive, wDir, wFname, wExt);
-
- /*Convert the results to regular ANSI strings.*/
- drive = convertC(wDrive);
- dir = convertC(wDir);
- fname = convertC(wFname);
- ext = convertC(wExt);
-
-
- /*on platforms that don't support drive letters, the drive
- returned should always be "" */
- if (wcscmp(wDrive, wTestCases[i].drive) != 0)
- {
- Fail("_wsplitpath read the path \"%s\" and thought the drive was "
- "\"%s\" instead of \"%s\""
- , testCases[i].path, drive, testCases[i].drive);
- }
-
- if (wcscmp(wDir, wTestCases[i].dir) != 0)
- {
- Fail("_wsplitpath read the path \"%s\" and thought the directory "
- "was \"%s\" instead of \"%s\""
- , testCases[i].path, dir, testCases[i].dir);
- }
-
- if (wcscmp(wFname, wTestCases[i].fname) != 0)
- {
- Fail("_wsplitpath read the path \"%s\" and thought the filename "
- "was \"%s\" instead of \"%s\""
- , testCases[i].path, fname, testCases[i].fname);
- }
-
- if (wcscmp(wExt, wTestCases[i].ext) != 0)
- {
- Fail("_wsplitpath read the path \"%s\" and thought the file "
- "extension was \"%s\" instead of \"%s\""
- , testCases[i].path, ext, testCases[i].ext);
- }
-
- free(drive);
- free(dir);
- free(fname);
- free(ext);
- }
-
- for(i = 0; i < sizeof(testCases)/sizeof(struct testCase); i++)
- {
- free(wTestCases[i].path);
- free(wTestCases[i].drive);
- free(wTestCases[i].dir);
- free(wTestCases[i].fname);
- free(wTestCases[i].ext);
- }
-
- PAL_Terminate();
-
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/_wsplitpath/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/_wsplitpath/test1/testinfo.dat
deleted file mode 100644
index 30be680bb4..0000000000
--- a/src/pal/tests/palsuite/c_runtime/_wsplitpath/test1/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = _wsplitpath
-Name = Positive Test for _wsplitpath
-TYPE = DEFAULT
-EXE1 = test1
-Description
-= Passes _wsplitpath() a series of sample paths and checks that it
-= parses them as expected.
-
-
diff --git a/src/pal/tests/palsuite/c_runtime/_wtoi/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/_wtoi/test1/CMakeLists.txt
index 9e6610fc0f..ed02fec3af 100644
--- a/src/pal/tests/palsuite/c_runtime/_wtoi/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/_wtoi/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_wtoi_test1
diff --git a/src/pal/tests/palsuite/c_runtime/_wtoi/test1/test1.c b/src/pal/tests/palsuite/c_runtime/_wtoi/test1/test1.cpp
index 0b14dedd60..0b14dedd60 100644
--- a/src/pal/tests/palsuite/c_runtime/_wtoi/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/_wtoi/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/abs/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/abs/test1/CMakeLists.txt
index c8a8595d01..b01d97ff2f 100644
--- a/src/pal/tests/palsuite/c_runtime/abs/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/abs/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- abs.c
+ abs.cpp
)
add_executable(paltest_abs_test1
diff --git a/src/pal/tests/palsuite/c_runtime/abs/test1/abs.c b/src/pal/tests/palsuite/c_runtime/abs/test1/abs.cpp
index 233a5dcb30..233a5dcb30 100644
--- a/src/pal/tests/palsuite/c_runtime/abs/test1/abs.c
+++ b/src/pal/tests/palsuite/c_runtime/abs/test1/abs.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/acos/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/acos/test1/CMakeLists.txt
index 978ab427e8..5bd3ae06e8 100644
--- a/src/pal/tests/palsuite/c_runtime/acos/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/acos/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_acos_test1
diff --git a/src/pal/tests/palsuite/c_runtime/acos/test1/test1.c b/src/pal/tests/palsuite/c_runtime/acos/test1/test1.cpp
index c6ed0692c7..c6ed0692c7 100644
--- a/src/pal/tests/palsuite/c_runtime/acos/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/acos/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/acosf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/acosf/CMakeLists.txt
new file mode 100644
index 0000000000..5e1ef7f28b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/acosf/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/acosf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/acosf/test1/CMakeLists.txt
new file mode 100644
index 0000000000..2643647438
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/acosf/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.c
+)
+
+add_executable(paltest_acosf_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_acosf_test1 coreclrpal)
+
+target_link_libraries(paltest_acosf_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/acosf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/acosf/test1/test1.c
new file mode 100644
index 0000000000..3d8668cebb
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/acosf/test1/test1.c
@@ -0,0 +1,129 @@
+// Licensed to the .NET Foundation under one or more 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: test1.c
+**
+** Purpose: Test to ensure that acosf return the correct values
+**
+** Dependencies: PAL_Initialize
+** PAL_Terminate
+** Fail
+** fabs
+**
+**===========================================================================*/
+
+#include <palsuite.h>
+
+// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this
+// is slightly too accurate when writing tests meant to run against libm implementations
+// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get.
+//
+// The tests themselves will take PAL_EPSILON and adjust it according to the expected result
+// so that the delta used for comparison will compare the most significant digits and ignore
+// any digits that are outside the double precision range (6-9 digits).
+
+// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON
+// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use
+// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10.
+#define PAL_EPSILON 4.76837158e-07
+
+#define PAL_NAN sqrtf(-1.0f)
+#define PAL_POSINF -logf(0.0f)
+#define PAL_NEGINF logf(0.0f)
+
+/**
+ * Helper test structure
+ */
+struct test
+{
+ float value; /* value to test the function with */
+ float expected; /* expected result */
+ float variance; /* maximum delta between the expected and actual result */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl validate(float value, float expected, float variance)
+{
+ float result = acosf(value);
+
+ /*
+ * The test is valid when the difference between result
+ * and expected is less than or equal to variance
+ */
+ float delta = fabsf(result - expected);
+
+ if (delta > variance)
+ {
+ Fail("acosf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, expected);
+ }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl validate_isnan(float value)
+{
+ float result = acosf(value);
+
+ if (!_isnanf(result))
+ {
+ Fail("acosf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, PAL_NAN);
+ }
+}
+
+/**
+ * main
+ *
+ * executable entry point
+ */
+int __cdecl main(int argc, char **argv)
+{
+ struct test tests[] =
+ {
+ /* value expected variance */
+ { -1, 3.14159265f, PAL_EPSILON * 10 }, // expected: pi
+ { -0.911733915f, 2.71828183f, PAL_EPSILON * 10 }, // expected: e
+ { -0.668201510f, 2.30258509f, PAL_EPSILON * 10 }, // expected: ln(10)
+ { 0, 1.57079633f, PAL_EPSILON * 10 }, // expected: pi / 2
+ { 0.127751218f, 1.44269504f, PAL_EPSILON * 10 }, // expected: logf2(e)
+ { 0.155943695f, 1.41421356f, PAL_EPSILON * 10 }, // expected: sqrtf(2)
+ { 0.428125148f, 1.12837917f, PAL_EPSILON * 10 }, // expected: 2 / sqrtf(pi)
+ { 0.540302306f, 1, PAL_EPSILON * 10 },
+ { 0.707106781f, 0.785398163f, PAL_EPSILON }, // expected: pi / 4, value: 1 / sqrtf(2)
+ { 0.760244597f, 0.707106781f, PAL_EPSILON }, // expected: 1 / sqrtf(2)
+ { 0.769238901f, 0.693147181f, PAL_EPSILON }, // expected: ln(2)
+ { 0.804109828f, 0.636619772f, PAL_EPSILON }, // expected: 2 / pi
+ { 0.907167129f, 0.434294482f, PAL_EPSILON }, // expected: logf10f(e)
+ { 0.949765715f, 0.318309886f, PAL_EPSILON }, // expected: 1 / pi
+ { 1, 0, PAL_EPSILON },
+ };
+
+ /* PAL initialization */
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++)
+ {
+ validate(tests[i].value, tests[i].expected, tests[i].variance);
+ }
+
+ validate_isnan(PAL_NEGINF);
+ validate_isnan(PAL_NAN);
+ validate_isnan(PAL_POSINF);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/acosf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/acosf/test1/testinfo.dat
new file mode 100644
index 0000000000..41cead33bb
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/acosf/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 = C Runtime
+Function = acosf
+Name = Positive Test for acosf
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Passes a series of values to the acosf() function,
+= checking each for the expfected result. Also checks
+= for proper handling of out-of-range values.
diff --git a/src/pal/tests/palsuite/c_runtime/asin/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/asin/test1/CMakeLists.txt
index a3aec3f60f..510b543a59 100644
--- a/src/pal/tests/palsuite/c_runtime/asin/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/asin/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_asin_test1
diff --git a/src/pal/tests/palsuite/c_runtime/asin/test1/test1.c b/src/pal/tests/palsuite/c_runtime/asin/test1/test1.cpp
index 0a63356ed0..0a63356ed0 100644
--- a/src/pal/tests/palsuite/c_runtime/asin/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/asin/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/asinf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/asinf/CMakeLists.txt
new file mode 100644
index 0000000000..5e1ef7f28b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/asinf/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/asinf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/asinf/test1/CMakeLists.txt
new file mode 100644
index 0000000000..b167bd8715
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/asinf/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.c
+)
+
+add_executable(paltest_asinf_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_asinf_test1 coreclrpal)
+
+target_link_libraries(paltest_asinf_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/asinf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/asinf/test1/test1.c
new file mode 100644
index 0000000000..773015eec0
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/asinf/test1/test1.c
@@ -0,0 +1,145 @@
+// Licensed to the .NET Foundation under one or more 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: test1.c
+**
+** Purpose: Test to ensure that asinf return the correct values
+**
+** Dependencies: PAL_Initialize
+** PAL_Terminate
+** Fail
+** fabs
+**
+**===========================================================================*/
+
+#include <palsuite.h>
+
+// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this
+// is slightly too accurate when writing tests meant to run against libm implementations
+// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get.
+//
+// The tests themselves will take PAL_EPSILON and adjust it according to the expected result
+// so that the delta used for comparison will compare the most significant digits and ignore
+// any digits that are outside the double precision range (6-9 digits).
+
+// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON
+// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use
+// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10.
+#define PAL_EPSILON 4.76837158e-07
+
+#define PAL_NAN sqrtf(-1.0f)
+#define PAL_POSINF -logf(0.0f)
+#define PAL_NEGINF logf(0.0f)
+
+/**
+ * Helper test structure
+ */
+struct test
+{
+ float value; /* value to test the function with */
+ float expected; /* expected result */
+ float variance; /* maximum delta between the expected and actual result */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl validate(float value, float expected, float variance)
+{
+ float result = asinf(value);
+
+ /*
+ * The test is valid when the difference between result
+ * and expected is less than or equal to variance
+ */
+ float delta = fabsf(result - expected);
+
+ if (delta > variance)
+ {
+ Fail("asinf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, expected);
+ }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl validate_isnan(float value)
+{
+ float result = asinf(value);
+
+ if (!_isnanf(result))
+ {
+ Fail("asinf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, PAL_NAN);
+ }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning +INF
+ */
+void __cdecl validate_isinf_positive(float value)
+{
+ float result = asinf(value);
+
+ if (result != PAL_POSINF)
+ {
+ Fail("asinf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, PAL_POSINF);
+ }
+}
+
+/**
+ * main
+ *
+ * executable entry point
+ */
+int __cdecl main(int argc, char **argv)
+{
+ struct test tests[] =
+ {
+ /* value expected variance */
+ { 0, 0, PAL_EPSILON },
+ { 0.312961796f, 0.318309886f, PAL_EPSILON }, // expected: 1 / pi
+ { 0.410781291f, 0.423310825f, PAL_EPSILON }, // expected: pi - e
+ { 0.420770483f, 0.434294482f, PAL_EPSILON }, // expected: logf10f(e)
+ { 0.594480769f, 0.636619772f, PAL_EPSILON }, // expected: 2 / pi
+ { 0.638961276f, 0.693147181f, PAL_EPSILON }, // expected: ln(2)
+ { 0.649636939f, 0.707106781f, PAL_EPSILON }, // expected: 1 / sqrtf(2)
+ { 0.707106781f, 0.785398163f, PAL_EPSILON }, // expected: pi / 4, value: 1 / sqrtf(2)
+ { 0.743980337f, 0.839007561f, PAL_EPSILON }, // expected: pi - ln(10)
+ { 0.841470985f, 1, PAL_EPSILON * 10 },
+ { 0.903719457f, 1.12837917f, PAL_EPSILON * 10 }, // expected: 2 / sqrtf(pi)
+ { 0.987765946f, 1.41421356f, PAL_EPSILON * 10 }, // expected: sqrtf(2)
+ { 0.991806244f, 1.44269504f, PAL_EPSILON * 10 }, // expected: logf2(e)
+ { 1, 1.57079633f, PAL_EPSILON * 10 }, // expected: pi / 2
+ };
+
+ /* PAL initialization */
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++)
+ {
+ validate( tests[i].value, tests[i].expected, tests[i].variance);
+ validate(-tests[i].value, -tests[i].expected, tests[i].variance);
+ }
+
+ validate_isnan(PAL_NEGINF);
+ validate_isnan(PAL_NAN);
+ validate_isnan(PAL_POSINF);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/asinf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/asinf/test1/testinfo.dat
new file mode 100644
index 0000000000..ca2dd42150
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/asinf/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 = C Runtime
+Function = asinf
+Name = Positive Test for asinf
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Passes a series of values to the asinf() function,
+= checking each for the expected result. Also checks
+= for proper handling of out-of-range values.
diff --git a/src/pal/tests/palsuite/c_runtime/atan/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/atan/test1/CMakeLists.txt
index b0b84e7c07..ace64e48bc 100644
--- a/src/pal/tests/palsuite/c_runtime/atan/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/atan/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_atan_test1
diff --git a/src/pal/tests/palsuite/c_runtime/atan/test1/test1.c b/src/pal/tests/palsuite/c_runtime/atan/test1/test1.cpp
index 6840d46172..6840d46172 100644
--- a/src/pal/tests/palsuite/c_runtime/atan/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/atan/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/atan2/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/atan2/test1/CMakeLists.txt
index 8bd69da2fa..cafa09f7fe 100644
--- a/src/pal/tests/palsuite/c_runtime/atan2/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/atan2/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_atan2_test1
diff --git a/src/pal/tests/palsuite/c_runtime/atan2/test1/test1.c b/src/pal/tests/palsuite/c_runtime/atan2/test1/test1.cpp
index 15aa8f53b9..15aa8f53b9 100644
--- a/src/pal/tests/palsuite/c_runtime/atan2/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/atan2/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/atan2f/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/atan2f/CMakeLists.txt
new file mode 100644
index 0000000000..5e1ef7f28b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/atan2f/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/atan2f/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/atan2f/test1/CMakeLists.txt
new file mode 100644
index 0000000000..d71a61b17b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/atan2f/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.c
+)
+
+add_executable(paltest_atan2f_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_atan2f_test1 coreclrpal)
+
+target_link_libraries(paltest_atan2f_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/atan2f/test1/test1.c b/src/pal/tests/palsuite/c_runtime/atan2f/test1/test1.c
new file mode 100644
index 0000000000..2ee641e8d4
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/atan2f/test1/test1.c
@@ -0,0 +1,147 @@
+// Licensed to the .NET Foundation under one or more 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: test1.c
+**
+** Purpose: Tests that atan2f returns correct values for a subset of values.
+** Tests with positive and negative values of x and y to ensure
+** atan2f is returning results from the correct quadrant.
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this
+// is slightly too accurate when writing tests meant to run against libm implementations
+// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get.
+//
+// The tests themselves will take PAL_EPSILON and adjust it according to the expected result
+// so that the delta used for comparison will compare the most significant digits and ignore
+// any digits that are outside the double precision range (6-9 digits).
+
+// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON
+// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use
+// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10.
+#define PAL_EPSILON 4.76837158e-07
+
+#define PAL_NAN sqrtf(-1.0f)
+#define PAL_POSINF -logf(0.0f)
+#define PAL_NEGINF logf(0.0f)
+
+struct test
+{
+ float y; /* second component of the value to test the function with */
+ float x; /* first component of the value to test the function with */
+ float expected; /* expected result */
+ float variance; /* maximum delta between the expected and actual result */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl validate(float y, float x, float expected, float variance)
+{
+ float result = atan2f(y, x);
+
+ /*
+ * The test is valid when the difference between result
+ * and expected is less than or equal to variance
+ */
+ float delta = fabsf(result - expected);
+
+ if (delta > variance)
+ {
+ Fail("atan2f(%g, %g) returned %10.9g when it should have returned %10.9g",
+ y, x, result, expected);
+ }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl validate_isnan(float y, float x)
+{
+ float result = atan2f(y, x);
+
+ if (!_isnanf(result))
+ {
+ Fail("atan2f(%g, %g) returned %10.9g when it should have returned %10.9g",
+ y, x, result, PAL_NAN);
+ }
+}
+
+/**
+ * main
+ *
+ * executable entry point
+ */
+int __cdecl main(int argc, char **argv)
+{
+ struct test tests[] =
+ {
+ /* y x expected variance */
+ { 0, PAL_POSINF, 0, PAL_EPSILON },
+ { 0, 0, 0, PAL_EPSILON },
+ { 0.312961796f, 0.949765715f, 0.318309886f, PAL_EPSILON }, // expected: 1 / pi
+ { 0.420770483f, 0.907167129f, 0.434294482f, PAL_EPSILON }, // expected: logf10f(e)
+ { 0.594480769f, 0.804109828f, 0.636619772f, PAL_EPSILON }, // expected: 2 / pi
+ { 0.638961276f, 0.769238901f, 0.693147181f, PAL_EPSILON }, // expected: ln(2)
+ { 0.649636939f, 0.760244597f, 0.707106781f, PAL_EPSILON }, // expected: 1 / sqrtf(2)
+ { 0.707106781f, 0.707106781f, 0.785398163f, PAL_EPSILON }, // expected: pi / 4, value: 1 / sqrtf(2)
+ { 1, 1, 0.785398163f, PAL_EPSILON }, // expected: pi / 4
+ { PAL_POSINF, PAL_POSINF, 0.785398163f, PAL_EPSILON }, // expected: pi / 4
+ { 0.841470985f, 0.540302306f, 1, PAL_EPSILON * 10 },
+ { 0.903719457f, 0.428125148f, 1.12837917f, PAL_EPSILON * 10 }, // expected: 2 / sqrtf(pi)
+ { 0.987765946f, 0.155943695f, 1.41421356f, PAL_EPSILON * 10 }, // expected: sqrtf(2)
+ { 0.991806244f, 0.127751218f, 1.44269504f, PAL_EPSILON * 10 }, // expected: logf2(e)
+ { 1, 0, 1.57079633f, PAL_EPSILON * 10 }, // expected: pi / 2
+ { PAL_POSINF, 0, 1.57079633f, PAL_EPSILON * 10 }, // expected: pi / 2
+ { PAL_POSINF, 1, 1.57079633f, PAL_EPSILON * 10 }, // expected: pi / 2
+ { 0.743980337f, -0.668201510f, 2.30258509f, PAL_EPSILON * 10 }, // expected: ln(10)
+ { 0.410781291f, -0.911733915f, 2.71828183f, PAL_EPSILON * 10 }, // expected: e
+ { 0, -1, 3.14159265f, PAL_EPSILON * 10 }, // expected: pi
+ { 1, PAL_POSINF, 0, PAL_EPSILON },
+ };
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++)
+ {
+ const float pi = 3.14159265f;
+
+ validate( tests[i].y, tests[i].x, tests[i].expected, tests[i].variance);
+ validate(-tests[i].y, tests[i].x, -tests[i].expected, tests[i].variance);
+ validate( tests[i].y, -tests[i].x, pi - tests[i].expected, tests[i].variance);
+ validate(-tests[i].y, -tests[i].x, tests[i].expected - pi, tests[i].variance);
+ }
+
+ validate_isnan(PAL_NEGINF, PAL_NAN);
+ validate_isnan(PAL_NAN, PAL_NEGINF);
+ validate_isnan(PAL_NAN, PAL_POSINF);
+ validate_isnan(PAL_POSINF, PAL_NAN);
+
+ validate_isnan(PAL_NAN, -1);
+ validate_isnan(PAL_NAN, -0.0f);
+ validate_isnan(PAL_NAN, 0);
+ validate_isnan(PAL_NAN, 1);
+
+ validate_isnan(-1, PAL_NAN);
+ validate_isnan(-0.0f, PAL_NAN);
+ validate_isnan( 0, PAL_NAN);
+ validate_isnan( 1, PAL_NAN);
+
+ validate_isnan(PAL_NAN, PAL_NAN);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/atan2f/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/atan2f/test1/testinfo.dat
new file mode 100644
index 0000000000..bd9a9d9b93
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/atan2f/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 = C Runtime
+Function = atan2f
+Name = Test #1 for atan2f
+Type = DEFAULT
+EXE1 = test1
+Description
+=Tests that atan2f returns correct values for a subset of values.
+=Tests with positive and negative values of x and y to ensure
+=atan2f is returning results from the correct quadrant.
diff --git a/src/pal/tests/palsuite/c_runtime/atanf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/atanf/CMakeLists.txt
new file mode 100644
index 0000000000..5e1ef7f28b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/atanf/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/atanf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/atanf/test1/CMakeLists.txt
new file mode 100644
index 0000000000..b71b1cf40c
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/atanf/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.c
+)
+
+add_executable(paltest_atanf_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_atanf_test1 coreclrpal)
+
+target_link_libraries(paltest_atanf_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/atanf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/atanf/test1/test1.c
new file mode 100644
index 0000000000..543a0a8168
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/atanf/test1/test1.c
@@ -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.
+
+/*=============================================================================
+**
+** Source: test1.c
+**
+** Purpose: Test to ensure that atanf return the correct values
+**
+** Dependencies: PAL_Initialize
+** PAL_Terminate
+** Fail
+** fabs
+**
+**===========================================================================*/
+
+#include <palsuite.h>
+
+// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this
+// is slightly too accurate when writing tests meant to run against libm implementations
+// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get.
+//
+// The tests themselves will take PAL_EPSILON and adjust it according to the expected result
+// so that the delta used for comparison will compare the most significant digits and ignore
+// any digits that are outside the double precision range (6-9 digits).
+
+// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON
+// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use
+// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10.
+#define PAL_EPSILON 4.76837158e-07
+
+#define PAL_NAN sqrtf(-1.0f)
+#define PAL_POSINF -logf(0.0f)
+#define PAL_NEGINF logf(0.0f)
+
+/**
+ * Helper test structure
+ */
+struct test
+{
+ float value; /* value to test the function with */
+ float expected; /* expected result */
+ float variance; /* maximum delta between the expected and actual result */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl validate(float value, float expected, float variance)
+{
+ float result = atanf(value);
+
+ /*
+ * The test is valid when the difference between result
+ * and expected is less than or equal to variance
+ */
+ float delta = fabsf(result - expected);
+
+ if (delta > variance)
+ {
+ Fail("atanf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, expected);
+ }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl validate_isnan(float value)
+{
+ float result = atanf(value);
+
+ if (!_isnanf(result))
+ {
+ Fail("atanf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, PAL_NAN);
+ }
+}
+
+/**
+ * main
+ *
+ * executable entry point
+ */
+int __cdecl main(int argc, char **argv)
+{
+ struct test tests[] =
+ {
+ /* value expected variance */
+ { 0, 0, PAL_EPSILON },
+ { 0.329514733f, 0.318309886f, PAL_EPSILON }, // expected: 1 / pi
+ { 0.450549534f, 0.423310825f, PAL_EPSILON }, // expected: pi - e
+ { 0.463829067f, 0.434294482f, PAL_EPSILON }, // expected: logf10f(e)
+ { 0.739302950f, 0.636619772f, PAL_EPSILON }, // expected: 2 / pi
+ { 0.830640878f, 0.693147181f, PAL_EPSILON }, // expected: ln(2)
+ { 0.854510432f, 0.707106781f, PAL_EPSILON }, // expected: 1 / sqrtf(2)
+ { 1, 0.785398163f, PAL_EPSILON }, // expected: pi / 4
+ { 1.11340715f, 0.839007561f, PAL_EPSILON }, // expected: pi - ln(10)
+ { 1.55740772f, 1, PAL_EPSILON * 10 },
+ { 2.11087684f, 1.12837917f, PAL_EPSILON * 10 }, // expected: 2 / sqrtf(pi)
+ { 6.33411917f, 1.41421356f, PAL_EPSILON * 10 }, // expected: sqrtf(2)
+ { 7.76357567f, 1.44269504f, PAL_EPSILON * 10 }, // expected: logf2(e)
+ { PAL_POSINF, 1.57079633f, PAL_EPSILON * 10 }, // expected: pi / 2
+ };
+
+ /* PAL initialization */
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++)
+ {
+ validate( tests[i].value, tests[i].expected, tests[i].variance);
+ validate(-tests[i].value, -tests[i].expected, tests[i].variance);
+ }
+
+ validate_isnan(PAL_NAN);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/atanf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/atanf/test1/testinfo.dat
new file mode 100644
index 0000000000..0d184272a2
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/atanf/test1/testinfo.dat
@@ -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.
+
+Version = 1.0
+Section = C Runtime
+Function = atanf
+Name = Positive Test for atanf
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Passes a series of values to the atanf() function,
+= checking each for the expected result.
diff --git a/src/pal/tests/palsuite/c_runtime/atof/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/atof/test1/CMakeLists.txt
index 1f34b7ebf5..12e584b9a0 100644
--- a/src/pal/tests/palsuite/c_runtime/atof/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/atof/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_atof_test1
diff --git a/src/pal/tests/palsuite/c_runtime/atof/test1/test1.c b/src/pal/tests/palsuite/c_runtime/atof/test1/test1.cpp
index a973133f9e..a973133f9e 100644
--- a/src/pal/tests/palsuite/c_runtime/atof/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/atof/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/atoi/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/atoi/test1/CMakeLists.txt
index 3549aca737..225052213f 100644
--- a/src/pal/tests/palsuite/c_runtime/atoi/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/atoi/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_atoi_test1
diff --git a/src/pal/tests/palsuite/c_runtime/atoi/test1/test1.c b/src/pal/tests/palsuite/c_runtime/atoi/test1/test1.cpp
index 2554d4c353..2554d4c353 100644
--- a/src/pal/tests/palsuite/c_runtime/atoi/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/atoi/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/atol/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/atol/test1/CMakeLists.txt
index 4fea187ad8..29643aae6b 100644
--- a/src/pal/tests/palsuite/c_runtime/atol/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/atol/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_atol_test1
diff --git a/src/pal/tests/palsuite/c_runtime/atol/test1/test1.c b/src/pal/tests/palsuite/c_runtime/atol/test1/test1.cpp
index 5ad85d873f..5ad85d873f 100644
--- a/src/pal/tests/palsuite/c_runtime/atol/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/atol/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/bsearch/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/bsearch/test1/CMakeLists.txt
index d2018f3325..c5aab7b84d 100644
--- a/src/pal/tests/palsuite/c_runtime/bsearch/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/bsearch/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_bsearch_test1
diff --git a/src/pal/tests/palsuite/c_runtime/bsearch/test1/test1.c b/src/pal/tests/palsuite/c_runtime/bsearch/test1/test1.cpp
index c4b91738eb..c4b91738eb 100644
--- a/src/pal/tests/palsuite/c_runtime/bsearch/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/bsearch/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/bsearch/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/bsearch/test2/CMakeLists.txt
index dc65560196..7ad33b12e5 100644
--- a/src/pal/tests/palsuite/c_runtime/bsearch/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/bsearch/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_bsearch_test2
diff --git a/src/pal/tests/palsuite/c_runtime/bsearch/test2/test2.c b/src/pal/tests/palsuite/c_runtime/bsearch/test2/test2.cpp
index 6de1b3fada..6de1b3fada 100644
--- a/src/pal/tests/palsuite/c_runtime/bsearch/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/bsearch/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/ceil/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/ceil/test1/CMakeLists.txt
index c73ad1dbbe..f834914545 100644
--- a/src/pal/tests/palsuite/c_runtime/ceil/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/ceil/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_ceil_test1
diff --git a/src/pal/tests/palsuite/c_runtime/ceil/test1/test1.c b/src/pal/tests/palsuite/c_runtime/ceil/test1/test1.cpp
index e6e36e6e33..e6e36e6e33 100644
--- a/src/pal/tests/palsuite/c_runtime/ceil/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/ceil/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/ceilf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/ceilf/CMakeLists.txt
new file mode 100644
index 0000000000..5e1ef7f28b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/ceilf/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/ceilf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/ceilf/test1/CMakeLists.txt
new file mode 100644
index 0000000000..64f14cda9a
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/ceilf/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.c
+)
+
+add_executable(paltest_ceilf_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_ceilf_test1 coreclrpal)
+
+target_link_libraries(paltest_ceilf_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/ceilf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/ceilf/test1/test1.c
new file mode 100644
index 0000000000..4939fb7ccf
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/ceilf/test1/test1.c
@@ -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.
+
+/*============================================================================
+**
+** Source: test1.c
+**
+** Purpose: Tests ceilf with simple positive and negative values. Also tests
+** extreme cases like extremely small values and positive and
+** negative infinity. Makes sure that calling ceilf on NaN returns
+** NaN
+**
+**==========================================================================*/
+
+#include <palsuite.h>
+
+// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this
+// is slightly too accurate when writing tests meant to run against libm implementations
+// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get.
+//
+// The tests themselves will take PAL_EPSILON and adjust it according to the expected result
+// so that the delta used for comparison will compare the most significant digits and ignore
+// any digits that are outside the double precision range (6-9 digits).
+
+// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON
+// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use
+// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10.
+#define PAL_EPSILON 4.76837158e-07
+
+#define PAL_NAN sqrtf(-1.0f)
+#define PAL_POSINF -logf(0.0f)
+#define PAL_NEGINF logf(0.0f)
+
+/**
+ * Helper test structure
+ */
+struct test
+{
+ float value; /* value to test the function with */
+ float expected; /* expected result */
+ float variance; /* maximum delta between the expected and actual result */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl validate(float value, float expected, float variance)
+{
+ float result = ceilf(value);
+
+ /*
+ * The test is valid when the difference between result
+ * and expected is less than or equal to variance
+ */
+ float delta = fabsf(result - expected);
+
+ if (delta > variance)
+ {
+ Fail("ceilf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, expected);
+ }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl validate_isnan(float value)
+{
+ float result = ceilf(value);
+
+ if (!_isnanf(result))
+ {
+ Fail("ceilf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, PAL_NAN);
+ }
+}
+
+/**
+ * main
+ *
+ * executable entry point
+ */
+int __cdecl main(int argc, char *argv[])
+{
+ struct test tests[] =
+ {
+ /* value expected variance */
+ { 0.318309886f, 1, PAL_EPSILON * 10 }, // value: 1 / pi
+ { 0.434294482f, 1, PAL_EPSILON * 10 }, // value: log10f(e)
+ { 0.636619772f, 1, PAL_EPSILON * 10 }, // value: 2 / pi
+ { 0.693147181f, 1, PAL_EPSILON * 10 }, // value: ln(2)
+ { 0.707106781f, 1, PAL_EPSILON * 10 }, // value: 1 / sqrtf(2)
+ { 0.785398163f, 1, PAL_EPSILON * 10 }, // value: pi / 4
+ { 1.12837917f, 2, PAL_EPSILON * 10 }, // value: 2 / sqrtf(pi)
+ { 1.41421356f, 2, PAL_EPSILON * 10 }, // value: sqrtf(2)
+ { 1.44269504f, 2, PAL_EPSILON * 10 }, // value: logf2(e)
+ { 1.57079633f, 2, PAL_EPSILON * 10 }, // value: pi / 2
+ { 2.30258509f, 3, PAL_EPSILON * 10 }, // value: ln(10)
+ { 2.71828183f, 3, PAL_EPSILON * 10 }, // value: e
+ { 3.14159265f, 4, PAL_EPSILON * 10 }, // value: pi
+ { PAL_POSINF, PAL_POSINF, 0 }
+ };
+
+ /* PAL initialization */
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ validate( 0, 0, PAL_EPSILON);
+ validate(-0.0f, 0, PAL_EPSILON);
+
+ validate( 1, 1, PAL_EPSILON * 10);
+ validate(-1.0f, -1, PAL_EPSILON * 10);
+
+ for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++)
+ {
+ validate( tests[i].value, tests[i].expected, tests[i].variance);
+ validate(-tests[i].value, 1 - tests[i].expected, tests[i].variance);
+ }
+
+ validate_isnan(PAL_NAN);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/ceilf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/ceilf/test1/testinfo.dat
new file mode 100644
index 0000000000..095b8b216a
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/ceilf/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 = C Runtime
+Function = ceilf
+Name = Test #1 for ceilf
+TYPE = DEFAULT
+EXE1 = test1
+Description
+=Tests ceilf with simple positive and negative values. Also tests
+=extreme cases like extremely small values and positive and negative
+=infinity. Makes sure that calling ceilf on NaN returns NaN
diff --git a/src/pal/tests/palsuite/c_runtime/cos/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/cos/test1/CMakeLists.txt
index 1dda9a2563..536664c128 100644
--- a/src/pal/tests/palsuite/c_runtime/cos/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/cos/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_cos_test1
diff --git a/src/pal/tests/palsuite/c_runtime/cos/test1/test1.c b/src/pal/tests/palsuite/c_runtime/cos/test1/test1.cpp
index 8c1c7300e6..8c1c7300e6 100644
--- a/src/pal/tests/palsuite/c_runtime/cos/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/cos/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/cosf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/cosf/CMakeLists.txt
new file mode 100644
index 0000000000..5e1ef7f28b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/cosf/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/cosf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/cosf/test1/CMakeLists.txt
new file mode 100644
index 0000000000..b3a18ea271
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/cosf/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.c
+)
+
+add_executable(paltest_cosf_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_cosf_test1 coreclrpal)
+
+target_link_libraries(paltest_cosf_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/cosf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/cosf/test1/test1.c
new file mode 100644
index 0000000000..210851a2fa
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/cosf/test1/test1.c
@@ -0,0 +1,130 @@
+// Licensed to the .NET Foundation under one or more 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: test1.c
+**
+** Purpose: Test to ensure that cosf return the correct values
+**
+** Dependencies: PAL_Initialize
+** PAL_Terminate
+** Fail
+** fabs
+**
+**===========================================================================*/
+
+#include <palsuite.h>
+
+// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this
+// is slightly too accurate when writing tests meant to run against libm implementations
+// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get.
+//
+// The tests themselves will take PAL_EPSILON and adjust it according to the expected result
+// so that the delta used for comparison will compare the most significant digits and ignore
+// any digits that are outside the double precision range (6-9 digits).
+
+// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON
+// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use
+// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10.
+#define PAL_EPSILON 4.76837158e-07
+
+#define PAL_NAN sqrtf(-1.0f)
+#define PAL_POSINF -logf(0.0f)
+#define PAL_NEGINF logf(0.0f)
+
+/**
+ * Helper test structure
+ */
+struct test
+{
+ float value; /* value to test the function with */
+ float expected; /* expected result */
+ float variance; /* maximum delta between the expected and actual result */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl validate(float value, float expected, float variance)
+{
+ float result = cosf(value);
+
+ /*
+ * The test is valid when the difference between result
+ * and expected is less than or equal to variance
+ */
+ float delta = fabsf(result - expected);
+
+ if (delta > variance)
+ {
+ Fail("cosf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, expected);
+ }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl validate_isnan(float value)
+{
+ float result = cosf(value);
+
+ if (!_isnanf(result))
+ {
+ Fail("cosf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, PAL_NAN);
+ }
+}
+
+/**
+ * main
+ *
+ * executable entry point
+ */
+int __cdecl main(int argc, char **argv)
+{
+ struct test tests[] =
+ {
+ /* value expected variance */
+ { 0, 1, PAL_EPSILON * 10 },
+ { 0.318309886f, 0.949765715f, PAL_EPSILON }, // value: 1 / pi
+ { 0.434294482f, 0.907167129f, PAL_EPSILON }, // value: log10f(e)
+ { 0.636619772f, 0.804109828f, PAL_EPSILON }, // value: 2 / pi
+ { 0.693147181f, 0.769238901f, PAL_EPSILON }, // value: ln(2)
+ { 0.707106781f, 0.760244597f, PAL_EPSILON }, // value: 1 / sqrtf(2)
+ { 0.785398163f, 0.707106781f, PAL_EPSILON }, // value: pi / 4, expected: 1 / sqrtf(2)
+ { 1, 0.540302306f, PAL_EPSILON },
+ { 1.12837917f, 0.428125148f, PAL_EPSILON }, // value: 2 / sqrtf(pi)
+ { 1.41421356f, 0.155943695f, PAL_EPSILON }, // value: sqrtf(2)
+ { 1.44269504f, 0.127751218f, PAL_EPSILON }, // value: logf2(e)
+ { 1.57079633f, 0, PAL_EPSILON }, // value: pi / 2
+ { 2.30258509f, -0.668201510f, PAL_EPSILON }, // value: ln(10)
+ { 2.71828183f, -0.911733918f, PAL_EPSILON }, // value: e
+ { 3.14159265f, -1, PAL_EPSILON * 10 }, // value: pi
+ };
+
+ /* PAL initialization */
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++)
+ {
+ validate( tests[i].value, tests[i].expected, tests[i].variance);
+ validate(-tests[i].value, tests[i].expected, tests[i].variance);
+ }
+
+ validate_isnan(PAL_NEGINF);
+ validate_isnan(PAL_NAN);
+ validate_isnan(PAL_POSINF);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/cosf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/cosf/test1/testinfo.dat
new file mode 100644
index 0000000000..a0265add2f
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/cosf/test1/testinfo.dat
@@ -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.
+
+Version = 1.0
+Section = C Runtime
+Function = cosf
+Name = Positive Test for cosf
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Passes to cosf() a series of angle value, checking that
+= each one return the correct value.
diff --git a/src/pal/tests/palsuite/c_runtime/cosh/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/cosh/test1/CMakeLists.txt
index bea7b7a3b7..e1fff0e9f1 100644
--- a/src/pal/tests/palsuite/c_runtime/cosh/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/cosh/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_cosh_test1
diff --git a/src/pal/tests/palsuite/c_runtime/cosh/test1/test1.c b/src/pal/tests/palsuite/c_runtime/cosh/test1/test1.cpp
index 40c2fca85d..40c2fca85d 100644
--- a/src/pal/tests/palsuite/c_runtime/cosh/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/cosh/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/coshf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/coshf/CMakeLists.txt
new file mode 100644
index 0000000000..5e1ef7f28b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/coshf/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/coshf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/coshf/test1/CMakeLists.txt
new file mode 100644
index 0000000000..92fcfdea6d
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/coshf/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.c
+)
+
+add_executable(paltest_coshf_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_coshf_test1 coreclrpal)
+
+target_link_libraries(paltest_coshf_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/coshf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/coshf/test1/test1.c
new file mode 100644
index 0000000000..e1ab745acb
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/coshf/test1/test1.c
@@ -0,0 +1,129 @@
+// Licensed to the .NET Foundation under one or more 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: test1.c
+**
+** Purpose: Test to ensure that coshf return the correct values
+**
+** Dependencies: PAL_Initialize
+** PAL_Terminate
+** Fail
+** fabs
+**
+**===========================================================================*/
+
+#include <palsuite.h>
+
+// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this
+// is slightly too accurate when writing tests meant to run against libm implementations
+// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get.
+//
+// The tests themselves will take PAL_EPSILON and adjust it according to the expected result
+// so that the delta used for comparison will compare the most significant digits and ignore
+// any digits that are outside the double precision range (6-9 digits).
+
+// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON
+// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use
+// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10.
+#define PAL_EPSILON 4.76837158e-07
+
+#define PAL_NAN sqrtf(-1.0f)
+#define PAL_POSINF -logf(0.0f)
+#define PAL_NEGINF logf(0.0f)
+
+/**
+ * Helper test structure
+ */
+struct test
+{
+ float value; /* value to test the function with */
+ float expected; /* expected result */
+ float variance; /* maximum delta between the expected and actual result */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl validate(float value, float expected, float variance)
+{
+ float result = coshf(value);
+
+ /*
+ * The test is valid when the difference between result
+ * and expected is less than or equal to variance
+ */
+ float delta = fabsf(result - expected);
+
+ if (delta > variance)
+ {
+ Fail("coshf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, expected);
+ }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning PAL_NAN
+ */
+void __cdecl validate_isnan(float value)
+{
+ float result = coshf(value);
+
+ if (!_isnanf(result))
+ {
+ Fail("coshf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, PAL_NAN);
+ }
+}
+
+/**
+ * main
+ *
+ * executable entry point
+ */
+int __cdecl main(int argc, char **argv)
+{
+ struct test tests[] =
+ {
+ /* value expected variance */
+ { 0, 1, PAL_EPSILON * 10 },
+ { 0.318309886f, 1.05108979f, PAL_EPSILON * 10 }, // value: 1 / pi
+ { 0.434294482f, 1.09579746f, PAL_EPSILON * 10 }, // value: log10f(e)
+ { 0.636619772f, 1.20957949f, PAL_EPSILON * 10 }, // value: 2 / pi
+ { 0.693147181f, 1.25f, PAL_EPSILON * 10 }, // value: ln(2)
+ { 0.707106781f, 1.26059184f, PAL_EPSILON * 10 }, // value: 1 / sqrtf(2)
+ { 0.785398163f, 1.32460909f, PAL_EPSILON * 10 }, // value: pi / 4
+ { 1, 1.54308063f, PAL_EPSILON * 10 },
+ { 1.12837917f, 1.70710014f, PAL_EPSILON * 10 }, // value: 2 / sqrtf(pi)
+ { 1.41421356f, 2.17818356f, PAL_EPSILON * 10 }, // value: sqrtf(2)
+ { 1.44269504f, 2.23418810f, PAL_EPSILON * 10 }, // value: logf2(e)
+ { 1.57079633f, 2.50917848f, PAL_EPSILON * 10 }, // value: pi / 2
+ { 2.30258509f, 5.05f, PAL_EPSILON * 10 }, // value: ln(10)
+ { 2.71828183f, 7.61012514f, PAL_EPSILON * 10 }, // value: e
+ { 3.14159265f, 11.5919533f, PAL_EPSILON * 100 }, // value: pi
+ { PAL_POSINF, PAL_POSINF, 0 },
+ };
+
+ /* PAL initialization */
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++)
+ {
+ validate( tests[i].value, tests[i].expected, tests[i].variance);
+ validate(-tests[i].value, tests[i].expected, tests[i].variance);
+ }
+
+ validate_isnan(PAL_NAN);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/coshf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/coshf/test1/testinfo.dat
new file mode 100644
index 0000000000..814ed98698
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/coshf/test1/testinfo.dat
@@ -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.
+
+Version = 1.0
+Section = C Runtime
+Function = coshf
+Name = Positive Test for coshf
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Passes to coshf() a series of angle value, checking that
+= each one return to correct value.
diff --git a/src/pal/tests/palsuite/c_runtime/ctime/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/ctime/test1/CMakeLists.txt
index aa64a71d1e..3eeffb0e39 100644
--- a/src/pal/tests/palsuite/c_runtime/ctime/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/ctime/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_ctime_test1
diff --git a/src/pal/tests/palsuite/c_runtime/ctime/test1/test1.c b/src/pal/tests/palsuite/c_runtime/ctime/test1/test1.cpp
index 5d5e22ce89..5d5e22ce89 100644
--- a/src/pal/tests/palsuite/c_runtime/ctime/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/ctime/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/errno/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/errno/test1/CMakeLists.txt
index 89b25a4fac..91b8d094b1 100644
--- a/src/pal/tests/palsuite/c_runtime/errno/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/errno/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_errno_test1
diff --git a/src/pal/tests/palsuite/c_runtime/errno/test1/test1.c b/src/pal/tests/palsuite/c_runtime/errno/test1/test1.cpp
index 3ae25fb02a..3ae25fb02a 100644
--- a/src/pal/tests/palsuite/c_runtime/errno/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/errno/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/errno/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/errno/test2/CMakeLists.txt
index edd4cf7975..ab7c4a27f2 100644
--- a/src/pal/tests/palsuite/c_runtime/errno/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/errno/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_errno_test2
diff --git a/src/pal/tests/palsuite/c_runtime/errno/test2/test2.c b/src/pal/tests/palsuite/c_runtime/errno/test2/test2.cpp
index f418d2f199..f418d2f199 100644
--- a/src/pal/tests/palsuite/c_runtime/errno/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/errno/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/exit/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/exit/test1/CMakeLists.txt
index eb9ca4e780..bb2cbccb9b 100644
--- a/src/pal/tests/palsuite/c_runtime/exit/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/exit/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_exit_test1
diff --git a/src/pal/tests/palsuite/c_runtime/exit/test1/test1.c b/src/pal/tests/palsuite/c_runtime/exit/test1/test1.cpp
index 87c9d22b8a..87c9d22b8a 100644
--- a/src/pal/tests/palsuite/c_runtime/exit/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/exit/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/exit/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/exit/test2/CMakeLists.txt
index 47d3a44c85..8a74e75ed5 100644
--- a/src/pal/tests/palsuite/c_runtime/exit/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/exit/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_exit_test2
diff --git a/src/pal/tests/palsuite/c_runtime/exit/test2/test2.c b/src/pal/tests/palsuite/c_runtime/exit/test2/test2.cpp
index 16fbdfed2f..16fbdfed2f 100644
--- a/src/pal/tests/palsuite/c_runtime/exit/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/exit/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/exp/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/exp/test1/CMakeLists.txt
index 9cdd4ec5ed..3377ed22f2 100644
--- a/src/pal/tests/palsuite/c_runtime/exp/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/exp/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_exp_test1
diff --git a/src/pal/tests/palsuite/c_runtime/exp/test1/test1.c b/src/pal/tests/palsuite/c_runtime/exp/test1/test1.cpp
index 20e071aa68..20e071aa68 100644
--- a/src/pal/tests/palsuite/c_runtime/exp/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/exp/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/expf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/expf/CMakeLists.txt
new file mode 100644
index 0000000000..5e1ef7f28b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/expf/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/expf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/expf/test1/CMakeLists.txt
new file mode 100644
index 0000000000..fb12b65c2f
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/expf/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.c
+)
+
+add_executable(paltest_expf_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_expf_test1 coreclrpal)
+
+target_link_libraries(paltest_expf_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/expf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/expf/test1/test1.c
new file mode 100644
index 0000000000..32f4e8d26c
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/expf/test1/test1.c
@@ -0,0 +1,137 @@
+// Licensed to the .NET Foundation under one or more 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: test1.c
+**
+** Purpose: Tests expf with a normal set of values.
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this
+// is slightly too accurate when writing tests meant to run against libm implementations
+// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get.
+//
+// The tests themselves will take PAL_EPSILON and adjust it according to the expected result
+// so that the delta used for comparison will compare the most significant digits and ignore
+// any digits that are outside the double precision range (6-9 digits).
+
+// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON
+// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use
+// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10.
+#define PAL_EPSILON 4.76837158e-07
+
+#define PAL_NAN sqrtf(-1.0f)
+#define PAL_POSINF -logf(0.0f)
+#define PAL_NEGINF logf(0.0f)
+
+/**
+ * Helper test structure
+ */
+struct test
+{
+ float value; /* value to test the function with */
+ float expected; /* expected result */
+ float variance; /* maximum delta between the expected and actual result */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl validate(float value, float expected, float variance)
+{
+ float result = expf(value);
+
+ /*
+ * The test is valid when the difference between result
+ * and expected is less than or equal to variance
+ */
+ float delta = fabsf(result - expected);
+
+ if (delta > variance)
+ {
+ Fail("expf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, expected);
+ }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl validate_isnan(float value)
+{
+ float result = expf(value);
+
+ if (!_isnanf(result))
+ {
+ Fail("expf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, PAL_NAN);
+ }
+}
+
+/**
+ * main
+ *
+ * executable entry point
+ */
+int __cdecl main(int argc, char **argv)
+{
+ struct test tests[] =
+ {
+ /* value expected variance */
+ { PAL_NEGINF, 0, PAL_EPSILON },
+ { -3.14159265f, 0.0432139183f, PAL_EPSILON / 10 }, // value: -(pi)
+ { -2.71828183f, 0.0659880358f, PAL_EPSILON / 10 }, // value: -(e)
+ { -2.30258509f, 0.1f, PAL_EPSILON }, // value: -(ln(10))
+ { -1.57079633f, 0.207879576f, PAL_EPSILON }, // value: -(pi / 2)
+ { -1.44269504f, 0.236290088f, PAL_EPSILON }, // value: -(logf2(e))
+ { -1.41421356f, 0.243116734f, PAL_EPSILON }, // value: -(sqrtf(2))
+ { -1.12837917f, 0.323557264f, PAL_EPSILON }, // value: -(2 / sqrtf(pi))
+ { -1, 0.367879441f, PAL_EPSILON }, // value: -(1)
+ { -0.785398163f, 0.455938128f, PAL_EPSILON }, // value: -(pi / 4)
+ { -0.707106781f, 0.493068691f, PAL_EPSILON }, // value: -(1 / sqrtf(2))
+ { -0.693147181f, 0.5f, PAL_EPSILON }, // value: -(ln(2))
+ { -0.636619772f, 0.529077808f, PAL_EPSILON }, // value: -(2 / pi)
+ { -0.434294482f, 0.647721485f, PAL_EPSILON }, // value: -(log10f(e))
+ { -0.318309886f, 0.727377349f, PAL_EPSILON }, // value: -(1 / pi)
+ { 0, 1, PAL_EPSILON * 10 },
+ { 0.318309886f, 1.37480223f, PAL_EPSILON * 10 }, // value: 1 / pi
+ { 0.434294482f, 1.54387344f, PAL_EPSILON * 10 }, // value: log10f(e)
+ { 0.636619772f, 1.89008116f, PAL_EPSILON * 10 }, // value: 2 / pi
+ { 0.693147181f, 2, PAL_EPSILON * 10 }, // value: ln(2)
+ { 0.707106781f, 2.02811498f, PAL_EPSILON * 10 }, // value: 1 / sqrtf(2)
+ { 0.785398163f, 2.19328005f, PAL_EPSILON * 10 }, // value: pi / 4
+ { 1, 2.71828183f, PAL_EPSILON * 10 }, // expected: e
+ { 1.12837917f, 3.09064302f, PAL_EPSILON * 10 }, // value: 2 / sqrtf(pi)
+ { 1.41421356f, 4.11325038f, PAL_EPSILON * 10 }, // value: sqrtf(2)
+ { 1.44269504f, 4.23208611f, PAL_EPSILON * 10 }, // value: logf2(e)
+ { 1.57079633f, 4.81047738f, PAL_EPSILON * 10 }, // value: pi / 2
+ { 2.30258509f, 10, PAL_EPSILON * 100 }, // value: ln(10)
+ { 2.71828183f, 15.1542622f, PAL_EPSILON * 100 }, // value: e
+ { 3.14159265f, 23.1406926f, PAL_EPSILON * 100 }, // value: pi
+ { PAL_POSINF, PAL_POSINF, 0 },
+ };
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++)
+ {
+ validate(tests[i].value, tests[i].expected, tests[i].variance);
+ }
+
+ validate_isnan(PAL_NAN);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/expf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/expf/test1/testinfo.dat
new file mode 100644
index 0000000000..c35928501e
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/expf/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 = C Runtime
+Function = expf
+Name = Test #1 for expf
+Type = DEFAULT
+EXE1 = test1
+Description
+=Tests expf with a normal set of values.
diff --git a/src/pal/tests/palsuite/c_runtime/fabs/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fabs/test1/CMakeLists.txt
index ab27230ac2..fa01a34dd9 100644
--- a/src/pal/tests/palsuite/c_runtime/fabs/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fabs/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_fabs_test1
diff --git a/src/pal/tests/palsuite/c_runtime/fabs/test1/test1.c b/src/pal/tests/palsuite/c_runtime/fabs/test1/test1.cpp
index 0a74d5c1c5..0a74d5c1c5 100644
--- a/src/pal/tests/palsuite/c_runtime/fabs/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/fabs/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fabsf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fabsf/test1/CMakeLists.txt
index 06512ebd7c..a1823e25e5 100644
--- a/src/pal/tests/palsuite/c_runtime/fabsf/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fabsf/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_fabsf_test1
diff --git a/src/pal/tests/palsuite/c_runtime/fabsf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/fabsf/test1/test1.cpp
index 0b020729b8..0b020729b8 100644
--- a/src/pal/tests/palsuite/c_runtime/fabsf/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/fabsf/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fclose/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fclose/test1/CMakeLists.txt
index 55ed7c674e..64cfef0e18 100644
--- a/src/pal/tests/palsuite/c_runtime/fclose/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fclose/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_fclose_test1
diff --git a/src/pal/tests/palsuite/c_runtime/fclose/test1/test1.c b/src/pal/tests/palsuite/c_runtime/fclose/test1/test1.cpp
index 0a8463823d..0a8463823d 100644
--- a/src/pal/tests/palsuite/c_runtime/fclose/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/fclose/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fclose/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fclose/test2/CMakeLists.txt
index 178dc7d19a..3b5538608f 100644
--- a/src/pal/tests/palsuite/c_runtime/fclose/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fclose/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_fclose_test2
diff --git a/src/pal/tests/palsuite/c_runtime/fclose/test2/test2.c b/src/pal/tests/palsuite/c_runtime/fclose/test2/test2.cpp
index f4da535535..f4da535535 100644
--- a/src/pal/tests/palsuite/c_runtime/fclose/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/fclose/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/feof/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/feof/test1/CMakeLists.txt
index ee1389deb0..9f689503e6 100644
--- a/src/pal/tests/palsuite/c_runtime/feof/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/feof/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_feof_test1
diff --git a/src/pal/tests/palsuite/c_runtime/feof/test1/test1.c b/src/pal/tests/palsuite/c_runtime/feof/test1/test1.cpp
index ba018aa91d..ba018aa91d 100644
--- a/src/pal/tests/palsuite/c_runtime/feof/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/feof/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/ferror/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/ferror/test1/CMakeLists.txt
index 2ab12b5db3..cd1fe52381 100644
--- a/src/pal/tests/palsuite/c_runtime/ferror/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/ferror/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_ferror_test1
diff --git a/src/pal/tests/palsuite/c_runtime/ferror/test1/test1.c b/src/pal/tests/palsuite/c_runtime/ferror/test1/test1.cpp
index 516f2531ed..516f2531ed 100644
--- a/src/pal/tests/palsuite/c_runtime/ferror/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/ferror/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/ferror/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/ferror/test2/CMakeLists.txt
index 077dde0bc6..05bd7fd2f1 100644
--- a/src/pal/tests/palsuite/c_runtime/ferror/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/ferror/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_ferror_test2
diff --git a/src/pal/tests/palsuite/c_runtime/ferror/test2/test2.c b/src/pal/tests/palsuite/c_runtime/ferror/test2/test2.cpp
index fdf9e032c8..fdf9e032c8 100644
--- a/src/pal/tests/palsuite/c_runtime/ferror/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/ferror/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fflush/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fflush/test1/CMakeLists.txt
index 743f1d2111..58c7c5a3a4 100644
--- a/src/pal/tests/palsuite/c_runtime/fflush/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fflush/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_fflush_test1
diff --git a/src/pal/tests/palsuite/c_runtime/fflush/test1/test1.c b/src/pal/tests/palsuite/c_runtime/fflush/test1/test1.cpp
index 7baf9ba5b9..7baf9ba5b9 100644
--- a/src/pal/tests/palsuite/c_runtime/fflush/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/fflush/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fgets/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fgets/test1/CMakeLists.txt
index 672d910c85..d327d6882a 100644
--- a/src/pal/tests/palsuite/c_runtime/fgets/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fgets/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_fgets_test1
diff --git a/src/pal/tests/palsuite/c_runtime/fgets/test1/test1.c b/src/pal/tests/palsuite/c_runtime/fgets/test1/test1.cpp
index 5e0e62dece..5e0e62dece 100644
--- a/src/pal/tests/palsuite/c_runtime/fgets/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/fgets/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fgets/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fgets/test2/CMakeLists.txt
index d39401536b..23bcdef686 100644
--- a/src/pal/tests/palsuite/c_runtime/fgets/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fgets/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_fgets_test2
diff --git a/src/pal/tests/palsuite/c_runtime/fgets/test2/test2.c b/src/pal/tests/palsuite/c_runtime/fgets/test2/test2.cpp
index fa37cdbc13..fa37cdbc13 100644
--- a/src/pal/tests/palsuite/c_runtime/fgets/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/fgets/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fgets/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fgets/test3/CMakeLists.txt
index 50f0901ee1..0833ad0130 100644
--- a/src/pal/tests/palsuite/c_runtime/fgets/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fgets/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_fgets_test3
diff --git a/src/pal/tests/palsuite/c_runtime/fgets/test3/test3.c b/src/pal/tests/palsuite/c_runtime/fgets/test3/test3.cpp
index 525ba9327f..525ba9327f 100644
--- a/src/pal/tests/palsuite/c_runtime/fgets/test3/test3.c
+++ b/src/pal/tests/palsuite/c_runtime/fgets/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/floor/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/floor/test1/CMakeLists.txt
index dbc5abde5b..3222ed8ba3 100644
--- a/src/pal/tests/palsuite/c_runtime/floor/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/floor/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_floor_test1
diff --git a/src/pal/tests/palsuite/c_runtime/floor/test1/test1.c b/src/pal/tests/palsuite/c_runtime/floor/test1/test1.cpp
index dba320919b..dba320919b 100644
--- a/src/pal/tests/palsuite/c_runtime/floor/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/floor/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/floorf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/floorf/CMakeLists.txt
new file mode 100644
index 0000000000..5e1ef7f28b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/floorf/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/floorf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/floorf/test1/CMakeLists.txt
new file mode 100644
index 0000000000..f6e24adcd9
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/floorf/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.c
+)
+
+add_executable(paltest_floorf_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_floorf_test1 coreclrpal)
+
+target_link_libraries(paltest_floorf_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/floorf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/floorf/test1/test1.c
new file mode 100644
index 0000000000..57dca21382
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/floorf/test1/test1.c
@@ -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.
+
+/*============================================================================
+**
+** Source: test1.c
+**
+** Purpose: Tests floorf with simple positive and negative values. Also tests
+** extreme cases like extremely small values and positive and
+** negative infinity. Makes sure that calling floorf on NaN returns
+** NaN
+**
+**==========================================================================*/
+
+#include <palsuite.h>
+
+// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this
+// is slightly too accurate when writing tests meant to run against libm implementations
+// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get.
+//
+// The tests themselves will take PAL_EPSILON and adjust it according to the expected result
+// so that the delta used for comparison will compare the most significant digits and ignore
+// any digits that are outside the double precision range (6-9 digits).
+
+// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON
+// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use
+// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10.
+#define PAL_EPSILON 4.76837158e-07
+
+#define PAL_NAN sqrtf(-1.0f)
+#define PAL_POSINF -logf(0.0f)
+#define PAL_NEGINF logf(0.0f)
+
+/**
+ * Helper test structure
+ */
+struct test
+{
+ float value; /* value to test the function with */
+ float expected; /* expected result */
+ float variance; /* maximum delta between the expected and actual result */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl validate(float value, float expected, float variance)
+{
+ float result = floorf(value);
+
+ /*
+ * The test is valid when the difference between result
+ * and expected is less than or equal to variance
+ */
+ float delta = fabsf(result - expected);
+
+ if (delta > variance)
+ {
+ Fail("floorf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, expected);
+ }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl validate_isnan(float value)
+{
+ float result = floorf(value);
+
+ if (!_isnanf(result))
+ {
+ Fail("floorf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, PAL_NAN);
+ }
+}
+
+/**
+ * main
+ *
+ * executable entry point
+ */
+int __cdecl main(int argc, char *argv[])
+{
+ struct test tests[] =
+ {
+ /* value expected variance */
+ { 0.318309886f, 0, PAL_EPSILON }, // value: 1 / pi
+ { 0.434294482f, 0, PAL_EPSILON }, // value: log10f(e)
+ { 0.636619772f, 0, PAL_EPSILON }, // value: 2 / pi
+ { 0.693147181f, 0, PAL_EPSILON }, // value: ln(2)
+ { 0.707106781f, 0, PAL_EPSILON }, // value: 1 / sqrtf(2)
+ { 0.785398163f, 0, PAL_EPSILON }, // value: pi / 4
+ { 1.12837917f, 1, PAL_EPSILON * 10 }, // value: 2 / sqrtf(pi)
+ { 1.41421356f, 1, PAL_EPSILON * 10 }, // value: sqrtf(2)
+ { 1.44269504f, 1, PAL_EPSILON * 10 }, // value: logf2(e)
+ { 1.57079633f, 1, PAL_EPSILON * 10 }, // value: pi / 2
+ { 2.30258509f, 2, PAL_EPSILON * 10 }, // value: ln(10)
+ { 2.71828183f, 2, PAL_EPSILON * 10 }, // value: e
+ { 3.14159265f, 3, PAL_EPSILON * 10 }, // value: pi
+ { PAL_POSINF, PAL_POSINF, 0 }
+ };
+
+ /* PAL initialization */
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ validate( 0, 0, PAL_EPSILON);
+ validate(-0.0f, 0, PAL_EPSILON);
+
+ validate( 1, 1, PAL_EPSILON * 10);
+ validate(-1.0f, -1, PAL_EPSILON * 10);
+
+ for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++)
+ {
+ validate( tests[i].value, tests[i].expected, tests[i].variance);
+ validate(-tests[i].value, -(tests[i].expected + 1), tests[i].variance);
+ }
+
+ validate_isnan(PAL_NAN);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/floorf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/floorf/test1/testinfo.dat
new file mode 100644
index 0000000000..006540141a
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/floorf/test1/testinfo.dat
@@ -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.
+
+Version = 1.0
+Section = C Runtime
+Function = floorf
+Name = Positive Test for floorf
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Passes to floorf() a series of value, checking that
+= each one return to correct value.
diff --git a/src/pal/tests/palsuite/c_runtime/fmod/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fmod/test1/CMakeLists.txt
index c76df1f0bf..33fbfb2653 100644
--- a/src/pal/tests/palsuite/c_runtime/fmod/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fmod/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_fmod_test1
diff --git a/src/pal/tests/palsuite/c_runtime/fmod/test1/test1.c b/src/pal/tests/palsuite/c_runtime/fmod/test1/test1.cpp
index fd69ca52cb..fd69ca52cb 100644
--- a/src/pal/tests/palsuite/c_runtime/fmod/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/fmod/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fmodf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fmodf/test1/CMakeLists.txt
index d1ea238a98..487b3adda4 100644
--- a/src/pal/tests/palsuite/c_runtime/fmodf/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fmodf/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_fmodf_test1
diff --git a/src/pal/tests/palsuite/c_runtime/fmodf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/fmodf/test1/test1.cpp
index 31b45d3606..31b45d3606 100644
--- a/src/pal/tests/palsuite/c_runtime/fmodf/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/fmodf/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fopen/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fopen/test1/CMakeLists.txt
index 6578c43659..7603fc623e 100644
--- a/src/pal/tests/palsuite/c_runtime/fopen/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fopen/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_fopen_test1
diff --git a/src/pal/tests/palsuite/c_runtime/fopen/test1/test1.c b/src/pal/tests/palsuite/c_runtime/fopen/test1/test1.cpp
index 565b4eb77d..565b4eb77d 100644
--- a/src/pal/tests/palsuite/c_runtime/fopen/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/fopen/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fopen/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fopen/test2/CMakeLists.txt
index 4458ed21d8..b8569921de 100644
--- a/src/pal/tests/palsuite/c_runtime/fopen/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fopen/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_fopen_test2
diff --git a/src/pal/tests/palsuite/c_runtime/fopen/test2/test2.c b/src/pal/tests/palsuite/c_runtime/fopen/test2/test2.cpp
index 4026efe89a..4026efe89a 100644
--- a/src/pal/tests/palsuite/c_runtime/fopen/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/fopen/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fopen/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fopen/test3/CMakeLists.txt
index 2c80f72ae7..5b28caf4ba 100644
--- a/src/pal/tests/palsuite/c_runtime/fopen/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fopen/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_fopen_test3
diff --git a/src/pal/tests/palsuite/c_runtime/fopen/test3/test3.c b/src/pal/tests/palsuite/c_runtime/fopen/test3/test3.cpp
index f3af42dc8a..f3af42dc8a 100644
--- a/src/pal/tests/palsuite/c_runtime/fopen/test3/test3.c
+++ b/src/pal/tests/palsuite/c_runtime/fopen/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fopen/test4/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fopen/test4/CMakeLists.txt
index 92e0ef0bd8..db5779f282 100644
--- a/src/pal/tests/palsuite/c_runtime/fopen/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fopen/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_fopen_test4
diff --git a/src/pal/tests/palsuite/c_runtime/fopen/test4/test4.c b/src/pal/tests/palsuite/c_runtime/fopen/test4/test4.cpp
index 04683d52c5..04683d52c5 100644
--- a/src/pal/tests/palsuite/c_runtime/fopen/test4/test4.c
+++ b/src/pal/tests/palsuite/c_runtime/fopen/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fopen/test5/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fopen/test5/CMakeLists.txt
index 82529b9aab..6341e4a7d2 100644
--- a/src/pal/tests/palsuite/c_runtime/fopen/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fopen/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_fopen_test5
diff --git a/src/pal/tests/palsuite/c_runtime/fopen/test5/test5.c b/src/pal/tests/palsuite/c_runtime/fopen/test5/test5.cpp
index 0a760314e1..0a760314e1 100644
--- a/src/pal/tests/palsuite/c_runtime/fopen/test5/test5.c
+++ b/src/pal/tests/palsuite/c_runtime/fopen/test5/test5.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fopen/test6/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fopen/test6/CMakeLists.txt
index 9a01cfb9a8..39cf9158bb 100644
--- a/src/pal/tests/palsuite/c_runtime/fopen/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fopen/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test6.c
+ test6.cpp
)
add_executable(paltest_fopen_test6
diff --git a/src/pal/tests/palsuite/c_runtime/fopen/test6/test6.c b/src/pal/tests/palsuite/c_runtime/fopen/test6/test6.cpp
index 03b6067fdd..03b6067fdd 100644
--- a/src/pal/tests/palsuite/c_runtime/fopen/test6/test6.c
+++ b/src/pal/tests/palsuite/c_runtime/fopen/test6/test6.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fopen/test7/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fopen/test7/CMakeLists.txt
index 168a5aff53..ee22e347d6 100644
--- a/src/pal/tests/palsuite/c_runtime/fopen/test7/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fopen/test7/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test7.c
+ test7.cpp
)
add_executable(paltest_fopen_test7
diff --git a/src/pal/tests/palsuite/c_runtime/fopen/test7/test7.c b/src/pal/tests/palsuite/c_runtime/fopen/test7/test7.cpp
index 3ef8602ddb..3ef8602ddb 100644
--- a/src/pal/tests/palsuite/c_runtime/fopen/test7/test7.c
+++ b/src/pal/tests/palsuite/c_runtime/fopen/test7/test7.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/fprintf.h b/src/pal/tests/palsuite/c_runtime/fprintf/fprintf.h
index 380eb0a0b3..87ee0d1232 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/fprintf.h
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/fprintf.h
@@ -11,7 +11,7 @@ function with this as a return type.
#ifndef __FPRINTF_H__
#define __FPRINTF_H__
-void DoStrTest(char *formatstr, char* param, char *checkstr)
+void DoStrTest(const char *formatstr, char* param, const char *checkstr)
{
FILE *fp;
char buf[256] = { 0 };
@@ -34,7 +34,7 @@ void DoStrTest(char *formatstr, char* param, char *checkstr)
fclose(fp);
}
-void DoWStrTest(char *formatstr, WCHAR* param, char *checkstr)
+void DoWStrTest(const char *formatstr, WCHAR* param, const char *checkstr)
{
FILE *fp;
char buf[256] = { 0 };
@@ -58,7 +58,7 @@ void DoWStrTest(char *formatstr, WCHAR* param, char *checkstr)
}
-void DoCharTest(char *formatstr, char param, char *checkstr)
+void DoCharTest(const char *formatstr, char param, const char *checkstr)
{
FILE *fp;
char buf[256] = { 0 };
@@ -81,7 +81,7 @@ void DoCharTest(char *formatstr, char param, char *checkstr)
fclose(fp);
}
-void DoWCharTest(char *formatstr, WCHAR param, char *checkstr)
+void DoWCharTest(const char *formatstr, WCHAR param, const char *checkstr)
{
FILE *fp;
char buf[256] = { 0 };
@@ -104,7 +104,7 @@ void DoWCharTest(char *formatstr, WCHAR param, char *checkstr)
fclose(fp);
}
-void DoNumTest(char *formatstr, int value, char *checkstr)
+void DoNumTest(const char *formatstr, int value, const char *checkstr)
{
FILE *fp;
char buf[256] = { 0 };
@@ -127,7 +127,7 @@ void DoNumTest(char *formatstr, int value, char *checkstr)
fclose(fp);
}
-void DoI64Test(char *formatstr, INT64 value, char *valuestr, char *checkstr1, char *checkstr2)
+void DoI64Test(const char *formatstr, INT64 value, char *valuestr, const char *checkstr1, const char *checkstr2)
{
FILE *fp;
char buf[256] = { 0 };
@@ -151,7 +151,7 @@ void DoI64Test(char *formatstr, INT64 value, char *valuestr, char *checkstr1, ch
fclose(fp);
}
-void DoDoubleTest(char *formatstr, double value, char *checkstr1, char *checkstr2)
+void DoDoubleTest(const char *formatstr, double value, const char *checkstr1, const char *checkstr2)
{
FILE *fp;
char buf[256] = { 0 };
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fprintf/test1/CMakeLists.txt
index ab4176563d..60ffd49cf5 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_fprintf_test1
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/fprintf/test1/test1.cpp
index d55fc2534c..d55fc2534c 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test10/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fprintf/test10/CMakeLists.txt
index f718ad7934..3fb57c217c 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test10/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test10/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test10.c
+ test10.cpp
)
add_executable(paltest_fprintf_test10
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test10/test10.c b/src/pal/tests/palsuite/c_runtime/fprintf/test10/test10.cpp
index 5988e8da74..5988e8da74 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test10/test10.c
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test10/test10.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test11/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fprintf/test11/CMakeLists.txt
index 6ccd58ddd2..d325ce225e 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test11/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test11/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test11.c
+ test11.cpp
)
add_executable(paltest_fprintf_test11
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test11/test11.c b/src/pal/tests/palsuite/c_runtime/fprintf/test11/test11.cpp
index 01880552b7..01880552b7 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test11/test11.c
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test11/test11.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test12/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fprintf/test12/CMakeLists.txt
index 17bc7f100b..8bd3970e80 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test12/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test12/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test12.c
+ test12.cpp
)
add_executable(paltest_fprintf_test12
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test12/test12.c b/src/pal/tests/palsuite/c_runtime/fprintf/test12/test12.cpp
index 0292e15014..0292e15014 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test12/test12.c
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test12/test12.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test13/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fprintf/test13/CMakeLists.txt
index c6eb0f9075..702058b797 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test13/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test13/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test13.c
+ test13.cpp
)
add_executable(paltest_fprintf_test13
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test13/test13.c b/src/pal/tests/palsuite/c_runtime/fprintf/test13/test13.cpp
index e171aeacce..e171aeacce 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test13/test13.c
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test13/test13.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test14/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fprintf/test14/CMakeLists.txt
index 6bb281bc62..b92ede7c87 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test14/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test14/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test14.c
+ test14.cpp
)
add_executable(paltest_fprintf_test14
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test14/test14.c b/src/pal/tests/palsuite/c_runtime/fprintf/test14/test14.cpp
index 5d7d77387d..5d7d77387d 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test14/test14.c
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test14/test14.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test15/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fprintf/test15/CMakeLists.txt
index ce1a8b6111..20f1e42aab 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test15/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test15/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test15.c
+ test15.cpp
)
add_executable(paltest_fprintf_test15
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test15/test15.c b/src/pal/tests/palsuite/c_runtime/fprintf/test15/test15.cpp
index d024bdbd8a..d024bdbd8a 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test15/test15.c
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test15/test15.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test16/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fprintf/test16/CMakeLists.txt
index 011cd13fb1..8d72421210 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test16/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test16/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test16.c
+ test16.cpp
)
add_executable(paltest_fprintf_test16
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test16/test16.c b/src/pal/tests/palsuite/c_runtime/fprintf/test16/test16.cpp
index 079faeaf59..079faeaf59 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test16/test16.c
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test16/test16.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test17/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fprintf/test17/CMakeLists.txt
index 4516f4b769..82d1f84f31 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test17/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test17/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test17.c
+ test17.cpp
)
add_executable(paltest_fprintf_test17
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test17/test17.c b/src/pal/tests/palsuite/c_runtime/fprintf/test17/test17.cpp
index 7bd817d7db..7bd817d7db 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test17/test17.c
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test17/test17.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test18/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fprintf/test18/CMakeLists.txt
index fc035020ca..1ca54e42b7 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test18/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test18/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test18.c
+ test18.cpp
)
add_executable(paltest_fprintf_test18
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test18/test18.c b/src/pal/tests/palsuite/c_runtime/fprintf/test18/test18.cpp
index 6582c41e0f..6582c41e0f 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test18/test18.c
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test18/test18.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test19/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fprintf/test19/CMakeLists.txt
index 3781b426f2..2c66239801 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test19/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test19/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test19.c
+ test19.cpp
)
add_executable(paltest_fprintf_test19
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test19/test19.c b/src/pal/tests/palsuite/c_runtime/fprintf/test19/test19.cpp
index 9d9a28c325..9d9a28c325 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test19/test19.c
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test19/test19.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fprintf/test2/CMakeLists.txt
index 0ef44b6b7d..ae1d9dc64d 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_fprintf_test2
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test2/test2.c b/src/pal/tests/palsuite/c_runtime/fprintf/test2/test2.cpp
index 1ed7f3fd23..1ed7f3fd23 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fprintf/test3/CMakeLists.txt
index adfd36fce7..4b10c4c407 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_fprintf_test3
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test3/test3.c b/src/pal/tests/palsuite/c_runtime/fprintf/test3/test3.cpp
index 6185135581..6185135581 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test3/test3.c
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test4/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fprintf/test4/CMakeLists.txt
index 7d471b1b9c..292bdb6625 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_fprintf_test4
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test4/test4.c b/src/pal/tests/palsuite/c_runtime/fprintf/test4/test4.cpp
index 51ec1f099c..51ec1f099c 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test4/test4.c
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test5/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fprintf/test5/CMakeLists.txt
index 1e3a568513..370ed3329a 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_fprintf_test5
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test5/test5.c b/src/pal/tests/palsuite/c_runtime/fprintf/test5/test5.cpp
index c53e3f45b4..c53e3f45b4 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test5/test5.c
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test5/test5.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test6/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fprintf/test6/CMakeLists.txt
index 89620dd453..bd1cbda924 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test6.c
+ test6.cpp
)
add_executable(paltest_fprintf_test6
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test6/test6.c b/src/pal/tests/palsuite/c_runtime/fprintf/test6/test6.cpp
index 0a8bc6b103..0a8bc6b103 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test6/test6.c
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test6/test6.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test7/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fprintf/test7/CMakeLists.txt
index 3dc10dd6dc..38429e7900 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test7/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test7/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test7.c
+ test7.cpp
)
add_executable(paltest_fprintf_test7
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test7/test7.c b/src/pal/tests/palsuite/c_runtime/fprintf/test7/test7.cpp
index 088e328de5..088e328de5 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test7/test7.c
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test7/test7.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test8/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fprintf/test8/CMakeLists.txt
index f6dd984af9..990eca26b0 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test8/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test8/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test8.c
+ test8.cpp
)
add_executable(paltest_fprintf_test8
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test8/test8.c b/src/pal/tests/palsuite/c_runtime/fprintf/test8/test8.cpp
index c781abc968..c781abc968 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test8/test8.c
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test8/test8.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test9/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fprintf/test9/CMakeLists.txt
index 62aa85e6ff..715d38a431 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test9/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test9/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test9.c
+ test9.cpp
)
add_executable(paltest_fprintf_test9
diff --git a/src/pal/tests/palsuite/c_runtime/fprintf/test9/test9.c b/src/pal/tests/palsuite/c_runtime/fprintf/test9/test9.cpp
index 3b06daec48..3b06daec48 100644
--- a/src/pal/tests/palsuite/c_runtime/fprintf/test9/test9.c
+++ b/src/pal/tests/palsuite/c_runtime/fprintf/test9/test9.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fputs/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fputs/test1/CMakeLists.txt
index e4a92d5966..d0f1aca0e6 100644
--- a/src/pal/tests/palsuite/c_runtime/fputs/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fputs/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_fputs_test1
diff --git a/src/pal/tests/palsuite/c_runtime/fputs/test1/test1.c b/src/pal/tests/palsuite/c_runtime/fputs/test1/test1.cpp
index b90ea082e9..b90ea082e9 100644
--- a/src/pal/tests/palsuite/c_runtime/fputs/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/fputs/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fputs/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fputs/test2/CMakeLists.txt
index 6e939f3346..9242ea16e5 100644
--- a/src/pal/tests/palsuite/c_runtime/fputs/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fputs/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_fputs_test2
diff --git a/src/pal/tests/palsuite/c_runtime/fputs/test2/test2.c b/src/pal/tests/palsuite/c_runtime/fputs/test2/test2.cpp
index b8e2f410bb..b8e2f410bb 100644
--- a/src/pal/tests/palsuite/c_runtime/fputs/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/fputs/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fread/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fread/test1/CMakeLists.txt
index a2e09579b1..1bd84b5c62 100644
--- a/src/pal/tests/palsuite/c_runtime/fread/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fread/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_fread_test1
diff --git a/src/pal/tests/palsuite/c_runtime/fread/test1/test1.c b/src/pal/tests/palsuite/c_runtime/fread/test1/test1.cpp
index b706b2e91c..b706b2e91c 100644
--- a/src/pal/tests/palsuite/c_runtime/fread/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/fread/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fread/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fread/test2/CMakeLists.txt
index 0538e0c3af..93e0394832 100644
--- a/src/pal/tests/palsuite/c_runtime/fread/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fread/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_fread_test2
diff --git a/src/pal/tests/palsuite/c_runtime/fread/test2/test2.c b/src/pal/tests/palsuite/c_runtime/fread/test2/test2.cpp
index d7262a9321..d7262a9321 100644
--- a/src/pal/tests/palsuite/c_runtime/fread/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/fread/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fread/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fread/test3/CMakeLists.txt
index f3c636f3df..285608bc3d 100644
--- a/src/pal/tests/palsuite/c_runtime/fread/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fread/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_fread_test3
diff --git a/src/pal/tests/palsuite/c_runtime/fread/test3/test3.c b/src/pal/tests/palsuite/c_runtime/fread/test3/test3.cpp
index 8c79bee582..8c79bee582 100644
--- a/src/pal/tests/palsuite/c_runtime/fread/test3/test3.c
+++ b/src/pal/tests/palsuite/c_runtime/fread/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/free/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/free/test1/CMakeLists.txt
index bd94cb5733..92ee9896c7 100644
--- a/src/pal/tests/palsuite/c_runtime/free/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/free/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_free_test1
diff --git a/src/pal/tests/palsuite/c_runtime/free/test1/test1.c b/src/pal/tests/palsuite/c_runtime/free/test1/test1.cpp
index 4ff8dfb094..4ff8dfb094 100644
--- a/src/pal/tests/palsuite/c_runtime/free/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/free/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fseek/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fseek/test1/CMakeLists.txt
index fb55bd1051..59ee8b4563 100644
--- a/src/pal/tests/palsuite/c_runtime/fseek/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fseek/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_fseek_test1
diff --git a/src/pal/tests/palsuite/c_runtime/fseek/test1/test1.c b/src/pal/tests/palsuite/c_runtime/fseek/test1/test1.c
deleted file mode 100644
index 8496289a01..0000000000
--- a/src/pal/tests/palsuite/c_runtime/fseek/test1/test1.c
+++ /dev/null
@@ -1,193 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: test1.c
-**
-** Purpose: Call fseek to move a file pointer to the start of a file,
-** a position offset from the start, a position offset from the
-** current position, and a position offset from the end of the
-** file. Check that the file pointer is at the correct position
-** after each seek.
-**
-**
-**==========================================================================*/
-
-#include <palsuite.h>
-
-const char filename[] = "testfile.txt";
-
-static BOOL Cleanup(HANDLE hFile)
-{
- BOOL result= TRUE;
-
- if (fclose(hFile))
- {
- Trace("fseek: ERROR -> Unable to close file \"%s\".\n",
- filename);
- result= FALSE;
- }
- if (!DeleteFileA(filename))
- {
- result= FALSE;
- Trace("fseek: ERROR -> Unable to delete file \"%s\". ",
- "GetLastError returned %u.\n",
- filename,
- GetLastError());
- }
- return result;
-}
-
-int __cdecl main(int argc, char **argv)
-{
- char outBuf[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- char inBuf[20];
- FILE * fp;
- int size = ( sizeof(outBuf)/sizeof(char) ) - 1;
-
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
-
- /*create the file*/
- fp = fopen(filename, "w");
- if (fp == NULL)
- {
- Fail("Unable to open a file for write.\n");
- }
- if(fprintf(fp, outBuf) != size)
- {
- Trace("Unable to write to %s.\n", filename);
- Cleanup(fp);
- Fail("");
- }
-
- if (fclose(fp) != 0)
- {
- Trace("Unable to close newly written file.\n");
- if (!DeleteFileA(filename))
- {
- Trace("fseek: ERROR -> Unable to delete file \"%s\". ",
- "GetLastError returned %u.\n",
- filename,
- GetLastError());
- }
- Fail("");
- }
-
- fp = fopen(filename, "r");
- if (fp == NULL)
- {
- if (!DeleteFileA(filename))
- {
- Trace("_putw: ERROR -> Unable to delete file \"%s\". ",
- "GetLastError returned %u.\n",
- filename,
- GetLastError());
- }
- Fail("Unable to open a file for read.\n");
- }
-
- /*seek to the start*/
- if (fseek(fp, 0, SEEK_SET) != 0)
- {
- Cleanup(fp);
- Fail("fseek failed when seeking the start of a file.\n");
- }
- if (fgets(inBuf, 11, fp) != inBuf)
- {
- Cleanup(fp);
- Fail("Unable to read from file after using fseek to move to the start.\n");
- }
- if (strncmp(inBuf, outBuf, 10) != 0)
- {
- Cleanup(fp);
- Fail("fseek was asked to seek the start of a file,"
- "but didn't get there.\n");
- }
-
- /*Seek with an offset from the start*/
-
- if (fseek(fp, 10, SEEK_SET) != 0)
- {
- Cleanup(fp);
- Fail("fseek failed when called with SEEK_SET and a positive offset.\n");
- }
-
- if (fgets(inBuf, 6, fp) != inBuf)
- {
- Cleanup(fp);
- Fail("fgets failed after feek was called with SEEK_SET"
- "and a positive offset.\n");
- }
-
-
- if (strncmp(inBuf, "ABCDE", 5) != 0)
- {
- Cleanup(fp);
- Fail("fseek did not move to the correct position when passed SEEK_SET"
- " and a positive offset.\n");
- }
-
- /*now move backwards and read the same string*/
- if (fseek(fp, -5, SEEK_CUR) != 0)
- {
- Cleanup(fp);
- Fail("fseek failed when passed SEEK_CUR and a negative offset.\n");
- }
-
- if (fgets(inBuf, 6, fp) != inBuf)
- {
- Cleanup(fp);
- Fail("fgets failed after fseek was called with SEEK_CUR and a "
- "negative offset.\n");
- }
-
- if (strncmp(inBuf, "ABCDE", 5) != 0)
- {
- Cleanup(fp);
- Fail("fseek did not move to the correct position when called with"
- " SEEK_CUR and a negative offset.\n");
- }
-
- /*Try seeking relative to the end of the file.*/
- if (fseek(fp, -10, SEEK_END) != 0)
- {
- Cleanup(fp);
- Fail("fseek failed when called with SEEK_END and a negative"
- " offset.\n");
- }
- if (fgets(inBuf, 2, fp) != inBuf)
- {
- Cleanup(fp);
- Fail("fgets failed after fseek was called with SEEK_END and a "
- "negative offset\n");
- }
-
- if (strncmp(inBuf, "Q", 1) != 0)
- {
- Cleanup(fp);
- Fail("fseek did not move to the correct position when called with "
- "SEEK_END and a negative offset.\n");
- }
-
-
- /*close the file*/
- if(!Cleanup(fp))
- {
- Fail("");
- }
-
- PAL_Terminate();
- return PASS;
-}
-
-
-
-
-
-
diff --git a/src/pal/tests/palsuite/c_runtime/fseek/test1/test1.cpp b/src/pal/tests/palsuite/c_runtime/fseek/test1/test1.cpp
new file mode 100644
index 0000000000..dd1e87ea8d
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/fseek/test1/test1.cpp
@@ -0,0 +1,193 @@
+// Licensed to the .NET Foundation under one or more 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: test1.c
+**
+** Purpose: Call fseek to move a file pointer to the start of a file,
+** a position offset from the start, a position offset from the
+** current position, and a position offset from the end of the
+** file. Check that the file pointer is at the correct position
+** after each seek.
+**
+**
+**==========================================================================*/
+
+#include <palsuite.h>
+
+const char filename[] = "testfile.txt";
+
+static BOOL Cleanup(HANDLE hFile)
+{
+ BOOL result= TRUE;
+
+ if (fclose((PAL_FILE*)hFile))
+ {
+ Trace("fseek: ERROR -> Unable to close file \"%s\".\n",
+ filename);
+ result= FALSE;
+ }
+ if (!DeleteFileA(filename))
+ {
+ result= FALSE;
+ Trace("fseek: ERROR -> Unable to delete file \"%s\". ",
+ "GetLastError returned %u.\n",
+ filename,
+ GetLastError());
+ }
+ return result;
+}
+
+int __cdecl main(int argc, char **argv)
+{
+ char outBuf[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ char inBuf[20];
+ FILE * fp;
+ int size = ( sizeof(outBuf)/sizeof(char) ) - 1;
+
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+
+ /*create the file*/
+ fp = fopen(filename, "w");
+ if (fp == NULL)
+ {
+ Fail("Unable to open a file for write.\n");
+ }
+ if(fprintf(fp, outBuf) != size)
+ {
+ Trace("Unable to write to %s.\n", filename);
+ Cleanup(fp);
+ Fail("");
+ }
+
+ if (fclose(fp) != 0)
+ {
+ Trace("Unable to close newly written file.\n");
+ if (!DeleteFileA(filename))
+ {
+ Trace("fseek: ERROR -> Unable to delete file \"%s\". ",
+ "GetLastError returned %u.\n",
+ filename,
+ GetLastError());
+ }
+ Fail("");
+ }
+
+ fp = fopen(filename, "r");
+ if (fp == NULL)
+ {
+ if (!DeleteFileA(filename))
+ {
+ Trace("_putw: ERROR -> Unable to delete file \"%s\". ",
+ "GetLastError returned %u.\n",
+ filename,
+ GetLastError());
+ }
+ Fail("Unable to open a file for read.\n");
+ }
+
+ /*seek to the start*/
+ if (fseek(fp, 0, SEEK_SET) != 0)
+ {
+ Cleanup(fp);
+ Fail("fseek failed when seeking the start of a file.\n");
+ }
+ if (fgets(inBuf, 11, fp) != inBuf)
+ {
+ Cleanup(fp);
+ Fail("Unable to read from file after using fseek to move to the start.\n");
+ }
+ if (strncmp(inBuf, outBuf, 10) != 0)
+ {
+ Cleanup(fp);
+ Fail("fseek was asked to seek the start of a file,"
+ "but didn't get there.\n");
+ }
+
+ /*Seek with an offset from the start*/
+
+ if (fseek(fp, 10, SEEK_SET) != 0)
+ {
+ Cleanup(fp);
+ Fail("fseek failed when called with SEEK_SET and a positive offset.\n");
+ }
+
+ if (fgets(inBuf, 6, fp) != inBuf)
+ {
+ Cleanup(fp);
+ Fail("fgets failed after feek was called with SEEK_SET"
+ "and a positive offset.\n");
+ }
+
+
+ if (strncmp(inBuf, "ABCDE", 5) != 0)
+ {
+ Cleanup(fp);
+ Fail("fseek did not move to the correct position when passed SEEK_SET"
+ " and a positive offset.\n");
+ }
+
+ /*now move backwards and read the same string*/
+ if (fseek(fp, -5, SEEK_CUR) != 0)
+ {
+ Cleanup(fp);
+ Fail("fseek failed when passed SEEK_CUR and a negative offset.\n");
+ }
+
+ if (fgets(inBuf, 6, fp) != inBuf)
+ {
+ Cleanup(fp);
+ Fail("fgets failed after fseek was called with SEEK_CUR and a "
+ "negative offset.\n");
+ }
+
+ if (strncmp(inBuf, "ABCDE", 5) != 0)
+ {
+ Cleanup(fp);
+ Fail("fseek did not move to the correct position when called with"
+ " SEEK_CUR and a negative offset.\n");
+ }
+
+ /*Try seeking relative to the end of the file.*/
+ if (fseek(fp, -10, SEEK_END) != 0)
+ {
+ Cleanup(fp);
+ Fail("fseek failed when called with SEEK_END and a negative"
+ " offset.\n");
+ }
+ if (fgets(inBuf, 2, fp) != inBuf)
+ {
+ Cleanup(fp);
+ Fail("fgets failed after fseek was called with SEEK_END and a "
+ "negative offset\n");
+ }
+
+ if (strncmp(inBuf, "Q", 1) != 0)
+ {
+ Cleanup(fp);
+ Fail("fseek did not move to the correct position when called with "
+ "SEEK_END and a negative offset.\n");
+ }
+
+
+ /*close the file*/
+ if(!Cleanup(fp))
+ {
+ Fail("");
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
+
+
+
+
+
+
diff --git a/src/pal/tests/palsuite/c_runtime/ftell/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/ftell/test1/CMakeLists.txt
index 7ea9a51111..a1f350d0c2 100644
--- a/src/pal/tests/palsuite/c_runtime/ftell/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/ftell/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- ftell.c
+ ftell.cpp
)
add_executable(paltest_ftell_test1
diff --git a/src/pal/tests/palsuite/c_runtime/ftell/test1/ftell.c b/src/pal/tests/palsuite/c_runtime/ftell/test1/ftell.cpp
index 66e0854847..66e0854847 100644
--- a/src/pal/tests/palsuite/c_runtime/ftell/test1/ftell.c
+++ b/src/pal/tests/palsuite/c_runtime/ftell/test1/ftell.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/fwprintf.h b/src/pal/tests/palsuite/c_runtime/fwprintf/fwprintf.h
index 36756636cf..eed0e76484 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/fwprintf.h
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/fwprintf.h
@@ -14,7 +14,7 @@
#ifndef __fwprintf_H__
#define __fwprintf_H__
-void DoStrTest(WCHAR *formatstr, char* param, char *checkstr)
+void DoStrTest(const WCHAR *formatstr, char* param, const char *checkstr)
{
FILE *fp;
char buf[256] = { 0 };
@@ -45,7 +45,7 @@ void DoStrTest(WCHAR *formatstr, char* param, char *checkstr)
fclose(fp);
}
-void DoWStrTest(WCHAR *formatstr, WCHAR* param, char *checkstr)
+void DoWStrTest(const WCHAR *formatstr, WCHAR* param, const char *checkstr)
{
FILE *fp;
char buf[256] = { 0 };
@@ -77,8 +77,8 @@ void DoWStrTest(WCHAR *formatstr, WCHAR* param, char *checkstr)
}
-void DoPointerTest(WCHAR *formatstr, void* param, char* paramstr,
- char *checkstr1, char *checkstr2)
+void DoPointerTest(const WCHAR *formatstr, void* param, char* paramstr,
+ const char *checkstr1, const char *checkstr2)
{
FILE *fp;
char buf[256] = { 0 };
@@ -119,7 +119,7 @@ void DoPointerTest(WCHAR *formatstr, void* param, char* paramstr,
-void DoCountTest(WCHAR *formatstr, int param, char *checkstr)
+void DoCountTest(const WCHAR *formatstr, int param, const char *checkstr)
{
FILE *fp;
char buf[512] = { 0 };
@@ -162,7 +162,7 @@ void DoCountTest(WCHAR *formatstr, int param, char *checkstr)
}
}
-void DoShortCountTest(WCHAR *formatstr, int param, char *checkstr)
+void DoShortCountTest(const WCHAR *formatstr, int param, const char *checkstr)
{
FILE *fp;
char buf[512] = { 0 };
@@ -206,7 +206,7 @@ void DoShortCountTest(WCHAR *formatstr, int param, char *checkstr)
}
-void DoCharTest(WCHAR *formatstr, char param, char *checkstr)
+void DoCharTest(const WCHAR *formatstr, char param, const char *checkstr)
{
FILE *fp;
char buf[256] = { 0 };
@@ -237,7 +237,7 @@ void DoCharTest(WCHAR *formatstr, char param, char *checkstr)
fclose(fp);
}
-void DoWCharTest(WCHAR *formatstr, WCHAR param, char *checkstr)
+void DoWCharTest(const WCHAR *formatstr, WCHAR param, const char *checkstr)
{
FILE *fp;
char buf[256] = { 0 };
@@ -268,7 +268,7 @@ void DoWCharTest(WCHAR *formatstr, WCHAR param, char *checkstr)
fclose(fp);
}
-void DoNumTest(WCHAR *formatstr, int value, char *checkstr)
+void DoNumTest(const WCHAR *formatstr, int value, const char *checkstr)
{
FILE *fp;
char buf[256] = { 0 };
@@ -299,8 +299,8 @@ void DoNumTest(WCHAR *formatstr, int value, char *checkstr)
fclose(fp);
}
-void DoI64Test(WCHAR *formatstr, INT64 value, char *valuestr, char *checkstr1,
- char *checkstr2)
+void DoI64Test(const WCHAR *formatstr, INT64 value, char *valuestr, const char *checkstr1,
+ const char *checkstr2)
{
FILE *fp;
char buf[256] = { 0 };
@@ -332,8 +332,8 @@ void DoI64Test(WCHAR *formatstr, INT64 value, char *valuestr, char *checkstr1,
fclose(fp);
}
-void DoDoubleTest(WCHAR *formatstr, double value, char *checkstr1,
- char *checkstr2)
+void DoDoubleTest(const WCHAR *formatstr, double value, const char *checkstr1,
+ const char *checkstr2)
{
FILE *fp;
char buf[256] = { 0 };
@@ -367,8 +367,8 @@ void DoDoubleTest(WCHAR *formatstr, double value, char *checkstr1,
}
-void DoArgumentPrecTest(WCHAR *formatstr, int precision, void *param,
- char *paramstr, char *checkstr1, char *checkstr2)
+void DoArgumentPrecTest(const WCHAR *formatstr, int precision, void *param,
+ char *paramstr, const char *checkstr1, const char *checkstr2)
{
FILE *fp;
char buf[256];
@@ -409,8 +409,8 @@ void DoArgumentPrecTest(WCHAR *formatstr, int precision, void *param,
}
-void DoArgumentPrecDoubleTest(WCHAR *formatstr, int precision, double param,
- char *checkstr1, char *checkstr2)
+void DoArgumentPrecDoubleTest(const WCHAR *formatstr, int precision, double param,
+ const char *checkstr1, const char *checkstr2)
{
FILE *fp;
char buf[256];
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fwprintf/test1/CMakeLists.txt
index ce4271edb2..519860b877 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_fwprintf_test1
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/fwprintf/test1/test1.cpp
index 8a171db52a..8a171db52a 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test10/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fwprintf/test10/CMakeLists.txt
index a8323b4fc7..e604e03dff 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test10/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test10/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test10.c
+ test10.cpp
)
add_executable(paltest_fwprintf_test10
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test10/test10.c b/src/pal/tests/palsuite/c_runtime/fwprintf/test10/test10.cpp
index 3aa2c45c7c..3aa2c45c7c 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test10/test10.c
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test10/test10.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test11/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fwprintf/test11/CMakeLists.txt
index 1b7987400a..18be522823 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test11/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test11/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test11.c
+ test11.cpp
)
add_executable(paltest_fwprintf_test11
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test11/test11.c b/src/pal/tests/palsuite/c_runtime/fwprintf/test11/test11.cpp
index 5867cd64fb..5867cd64fb 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test11/test11.c
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test11/test11.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test12/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fwprintf/test12/CMakeLists.txt
index 1e43a4c906..6ea739b28f 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test12/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test12/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test12.c
+ test12.cpp
)
add_executable(paltest_fwprintf_test12
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test12/test12.c b/src/pal/tests/palsuite/c_runtime/fwprintf/test12/test12.cpp
index 48a6123423..48a6123423 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test12/test12.c
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test12/test12.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test13/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fwprintf/test13/CMakeLists.txt
index c84dc3ea41..8505ccbd82 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test13/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test13/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test13.c
+ test13.cpp
)
add_executable(paltest_fwprintf_test13
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test13/test13.c b/src/pal/tests/palsuite/c_runtime/fwprintf/test13/test13.cpp
index 6eabec6c77..6eabec6c77 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test13/test13.c
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test13/test13.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test14/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fwprintf/test14/CMakeLists.txt
index 97824c76b7..548e60fdb8 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test14/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test14/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test14.c
+ test14.cpp
)
add_executable(paltest_fwprintf_test14
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test14/test14.c b/src/pal/tests/palsuite/c_runtime/fwprintf/test14/test14.cpp
index 001cf72689..001cf72689 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test14/test14.c
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test14/test14.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test15/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fwprintf/test15/CMakeLists.txt
index 6786c5b774..c5b53461a7 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test15/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test15/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test15.c
+ test15.cpp
)
add_executable(paltest_fwprintf_test15
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test15/test15.c b/src/pal/tests/palsuite/c_runtime/fwprintf/test15/test15.cpp
index 9dfe82eccc..9dfe82eccc 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test15/test15.c
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test15/test15.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test16/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fwprintf/test16/CMakeLists.txt
index be14870863..51af0a0d60 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test16/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test16/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test16.c
+ test16.cpp
)
add_executable(paltest_fwprintf_test16
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test16/test16.c b/src/pal/tests/palsuite/c_runtime/fwprintf/test16/test16.cpp
index 1969be1824..1969be1824 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test16/test16.c
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test16/test16.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test17/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fwprintf/test17/CMakeLists.txt
index b390d15620..9ed8a390e7 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test17/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test17/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test17.c
+ test17.cpp
)
add_executable(paltest_fwprintf_test17
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test17/test17.c b/src/pal/tests/palsuite/c_runtime/fwprintf/test17/test17.cpp
index 66b12716d0..66b12716d0 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test17/test17.c
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test17/test17.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test18/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fwprintf/test18/CMakeLists.txt
index 6f6d79bce5..3e3ba4efc7 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test18/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test18/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test18.c
+ test18.cpp
)
add_executable(paltest_fwprintf_test18
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test18/test18.c b/src/pal/tests/palsuite/c_runtime/fwprintf/test18/test18.cpp
index a33dea39b3..a33dea39b3 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test18/test18.c
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test18/test18.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test19/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fwprintf/test19/CMakeLists.txt
index bc10825ce1..fbb7370ba3 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test19/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test19/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test19.c
+ test19.cpp
)
add_executable(paltest_fwprintf_test19
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test19/test19.c b/src/pal/tests/palsuite/c_runtime/fwprintf/test19/test19.c
deleted file mode 100644
index 4600de7fa9..0000000000
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test19/test19.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test19.c
-**
-** Purpose: Tests the variable length precision argument.
-** This test is modeled after the sprintf series.
-**
-**
-**==========================================================================*/
-
-#include <palsuite.h>
-#include "../fwprintf.h"
-
-/*
- * Depends on memcmp, strlen, fopen, fseek and fgets.
- */
-
-
-
-int __cdecl main(int argc, char *argv[])
-{
- int n = -1;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return(FAIL);
- }
-
- DoArgumentPrecTest(convert("%.*s"), 2, convert("bar"), "bar", "ba", "ba");
- DoArgumentPrecTest(convert("%.*S"), 2, "bar", "bar", "ba", "ba");
- DoArgumentPrecTest(convert("foo %.*n"), 3, &n, "pointer to int", "foo ",
- "foo ");
- if (n != 4)
- {
- Fail("ERROR: Expected count parameter to resolve to %d, got %X\n",
- 4, n);
- }
-
- DoArgumentPrecTest(convert("%.*c"), 0, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest(convert("%.*c"), 4, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest(convert("%.*C"), 0, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest(convert("%.*C"), 4, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest(convert("%.*d"), 1, (void*)42, "42", "42", "42");
- DoArgumentPrecTest(convert("%.*d"), 3, (void*)42, "42", "042", "042");
- DoArgumentPrecTest(convert("%.*i"), 1, (void*)42, "42", "42", "42");
- DoArgumentPrecTest(convert("%.*i"), 3, (void*)42, "42", "042", "042");
- DoArgumentPrecTest(convert("%.*o"), 1, (void*)42, "42", "52", "52");
- DoArgumentPrecTest(convert("%.*o"), 3, (void*)42, "42", "052", "052");
- DoArgumentPrecTest(convert("%.*u"), 1, (void*)42, "42", "42", "42");
- DoArgumentPrecTest(convert("%.*u"), 3, (void*)42, "42", "042", "042");
- DoArgumentPrecTest(convert("%.*x"), 1, (void*)0x42, "0x42", "42", "42");
- DoArgumentPrecTest(convert("%.*x"), 3, (void*)0x42, "0x42", "042", "042");
- DoArgumentPrecTest(convert("%.*X"), 1, (void*)0x42, "0x42", "42", "42");
- DoArgumentPrecTest(convert("%.*X"), 3, (void*)0x42, "0x42", "042", "042");
-
-
- DoArgumentPrecDoubleTest(convert("%.*e"), 1, 2.01, "2.0e+000", "2.0e+00");
- DoArgumentPrecDoubleTest(convert("%.*e"), 3, 2.01, "2.010e+000",
- "2.010e+00");
- DoArgumentPrecDoubleTest(convert("%.*E"), 1, 2.01, "2.0E+000", "2.0E+00");
- DoArgumentPrecDoubleTest(convert("%.*E"), 3, 2.01, "2.010E+000",
- "2.010E+00");
- DoArgumentPrecDoubleTest(convert("%.*f"), 1, 2.01, "2.0", "2.0");
- DoArgumentPrecDoubleTest(convert("%.*f"), 3, 2.01, "2.010", "2.010");
- DoArgumentPrecDoubleTest(convert("%.*g"), 1, 256.01, "3e+002", "3e+02");
- DoArgumentPrecDoubleTest(convert("%.*g"), 3, 256.01, "256", "256");
- DoArgumentPrecDoubleTest(convert("%.*g"), 4, 256.01, "256", "256");
- DoArgumentPrecDoubleTest(convert("%.*g"), 6, 256.01, "256.01", "256.01");
- DoArgumentPrecDoubleTest(convert("%.*G"), 1, 256.01, "3E+002", "3E+02");
- DoArgumentPrecDoubleTest(convert("%.*G"), 3, 256.01, "256", "256");
- DoArgumentPrecDoubleTest(convert("%.*G"), 4, 256.01, "256", "256");
- DoArgumentPrecDoubleTest(convert("%.*G"), 6, 256.01, "256.01", "256.01");
-
- PAL_Terminate();
-
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test19/test19.cpp b/src/pal/tests/palsuite/c_runtime/fwprintf/test19/test19.cpp
new file mode 100644
index 0000000000..a407c9f4bd
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test19/test19.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test19.c
+**
+** Purpose: Tests the variable length precision argument.
+** This test is modeled after the sprintf series.
+**
+**
+**==========================================================================*/
+
+#include <palsuite.h>
+#include "../fwprintf.h"
+
+/*
+ * Depends on memcmp, strlen, fopen, fseek and fgets.
+ */
+
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ int n = -1;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return(FAIL);
+ }
+
+ DoArgumentPrecTest(convert("%.*s"), 2, (void*)convert("bar"), "bar", "ba", "ba");
+ DoArgumentPrecTest(convert("%.*S"), 2, (void*)"bar", "bar", "ba", "ba");
+ DoArgumentPrecTest(convert("foo %.*n"), 3, (void*)&n, "pointer to int", "foo ",
+ "foo ");
+ if (n != 4)
+ {
+ Fail("ERROR: Expected count parameter to resolve to %d, got %X\n",
+ 4, n);
+ }
+
+ DoArgumentPrecTest(convert("%.*c"), 0, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest(convert("%.*c"), 4, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest(convert("%.*C"), 0, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest(convert("%.*C"), 4, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest(convert("%.*d"), 1, (void*)42, "42", "42", "42");
+ DoArgumentPrecTest(convert("%.*d"), 3, (void*)42, "42", "042", "042");
+ DoArgumentPrecTest(convert("%.*i"), 1, (void*)42, "42", "42", "42");
+ DoArgumentPrecTest(convert("%.*i"), 3, (void*)42, "42", "042", "042");
+ DoArgumentPrecTest(convert("%.*o"), 1, (void*)42, "42", "52", "52");
+ DoArgumentPrecTest(convert("%.*o"), 3, (void*)42, "42", "052", "052");
+ DoArgumentPrecTest(convert("%.*u"), 1, (void*)42, "42", "42", "42");
+ DoArgumentPrecTest(convert("%.*u"), 3, (void*)42, "42", "042", "042");
+ DoArgumentPrecTest(convert("%.*x"), 1, (void*)0x42, "0x42", "42", "42");
+ DoArgumentPrecTest(convert("%.*x"), 3, (void*)0x42, "0x42", "042", "042");
+ DoArgumentPrecTest(convert("%.*X"), 1, (void*)0x42, "0x42", "42", "42");
+ DoArgumentPrecTest(convert("%.*X"), 3, (void*)0x42, "0x42", "042", "042");
+
+
+ DoArgumentPrecDoubleTest(convert("%.*e"), 1, 2.01, "2.0e+000", "2.0e+00");
+ DoArgumentPrecDoubleTest(convert("%.*e"), 3, 2.01, "2.010e+000",
+ "2.010e+00");
+ DoArgumentPrecDoubleTest(convert("%.*E"), 1, 2.01, "2.0E+000", "2.0E+00");
+ DoArgumentPrecDoubleTest(convert("%.*E"), 3, 2.01, "2.010E+000",
+ "2.010E+00");
+ DoArgumentPrecDoubleTest(convert("%.*f"), 1, 2.01, "2.0", "2.0");
+ DoArgumentPrecDoubleTest(convert("%.*f"), 3, 2.01, "2.010", "2.010");
+ DoArgumentPrecDoubleTest(convert("%.*g"), 1, 256.01, "3e+002", "3e+02");
+ DoArgumentPrecDoubleTest(convert("%.*g"), 3, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest(convert("%.*g"), 4, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest(convert("%.*g"), 6, 256.01, "256.01", "256.01");
+ DoArgumentPrecDoubleTest(convert("%.*G"), 1, 256.01, "3E+002", "3E+02");
+ DoArgumentPrecDoubleTest(convert("%.*G"), 3, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest(convert("%.*G"), 4, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest(convert("%.*G"), 6, 256.01, "256.01", "256.01");
+
+ PAL_Terminate();
+
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fwprintf/test2/CMakeLists.txt
index 64314651c0..e65a396862 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_fwprintf_test2
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test2/test2.c b/src/pal/tests/palsuite/c_runtime/fwprintf/test2/test2.cpp
index ecd3c513df..ecd3c513df 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fwprintf/test3/CMakeLists.txt
index 6906722cde..53c46369de 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_fwprintf_test3
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test3/test3.c b/src/pal/tests/palsuite/c_runtime/fwprintf/test3/test3.cpp
index d718a19067..d718a19067 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test3/test3.c
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test4/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fwprintf/test4/CMakeLists.txt
index b91bc87195..9dbb46283e 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_fwprintf_test4
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test4/test4.c b/src/pal/tests/palsuite/c_runtime/fwprintf/test4/test4.cpp
index 96fb472c3e..96fb472c3e 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test4/test4.c
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test5/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fwprintf/test5/CMakeLists.txt
index 53bf482b6f..4e72e3ca88 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_fwprintf_test5
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test5/test5.c b/src/pal/tests/palsuite/c_runtime/fwprintf/test5/test5.cpp
index 9d95989090..9d95989090 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test5/test5.c
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test5/test5.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test6/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fwprintf/test6/CMakeLists.txt
index bf7d7cccb8..d57f07fafa 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test6.c
+ test6.cpp
)
add_executable(paltest_fwprintf_test6
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test6/test6.c b/src/pal/tests/palsuite/c_runtime/fwprintf/test6/test6.cpp
index 160ff524e0..160ff524e0 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test6/test6.c
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test6/test6.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test7/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fwprintf/test7/CMakeLists.txt
index 68bcc9ca65..314ca353e5 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test7/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test7/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test7.c
+ test7.cpp
)
add_executable(paltest_fwprintf_test7
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test7/test7.c b/src/pal/tests/palsuite/c_runtime/fwprintf/test7/test7.cpp
index c5515a8640..c5515a8640 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test7/test7.c
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test7/test7.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test8/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fwprintf/test8/CMakeLists.txt
index e07cbb9119..e818df2eb2 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test8/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test8/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test8.c
+ test8.cpp
)
add_executable(paltest_fwprintf_test8
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test8/test8.c b/src/pal/tests/palsuite/c_runtime/fwprintf/test8/test8.cpp
index efc81a954a..efc81a954a 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test8/test8.c
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test8/test8.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test9/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fwprintf/test9/CMakeLists.txt
index 898da1a64f..28b6b86921 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test9/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test9/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test9.c
+ test9.cpp
)
add_executable(paltest_fwprintf_test9
diff --git a/src/pal/tests/palsuite/c_runtime/fwprintf/test9/test9.c b/src/pal/tests/palsuite/c_runtime/fwprintf/test9/test9.cpp
index 23db2d8971..23db2d8971 100644
--- a/src/pal/tests/palsuite/c_runtime/fwprintf/test9/test9.c
+++ b/src/pal/tests/palsuite/c_runtime/fwprintf/test9/test9.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/fwrite/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/fwrite/test1/CMakeLists.txt
index 701e56acb5..5c8b7449f2 100644
--- a/src/pal/tests/palsuite/c_runtime/fwrite/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/fwrite/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_fwrite_test1
diff --git a/src/pal/tests/palsuite/c_runtime/fwrite/test1/test1.c b/src/pal/tests/palsuite/c_runtime/fwrite/test1/test1.cpp
index 392522879f..392522879f 100644
--- a/src/pal/tests/palsuite/c_runtime/fwrite/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/fwrite/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/getc/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/getc/test1/CMakeLists.txt
index 2a29e8af0a..68ecaa9abb 100644
--- a/src/pal/tests/palsuite/c_runtime/getc/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/getc/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- getc.c
+ getc.cpp
)
add_executable(paltest_getc_test1
diff --git a/src/pal/tests/palsuite/c_runtime/getc/test1/getc.c b/src/pal/tests/palsuite/c_runtime/getc/test1/getc.cpp
index dfe10d6160..dfe10d6160 100644
--- a/src/pal/tests/palsuite/c_runtime/getc/test1/getc.c
+++ b/src/pal/tests/palsuite/c_runtime/getc/test1/getc.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/getenv/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/getenv/test1/CMakeLists.txt
index 6243c032ab..9c52c2890e 100644
--- a/src/pal/tests/palsuite/c_runtime/getenv/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/getenv/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_getenv_test1
diff --git a/src/pal/tests/palsuite/c_runtime/getenv/test1/test1.c b/src/pal/tests/palsuite/c_runtime/getenv/test1/test1.cpp
index 0fb9025c8f..0fb9025c8f 100644
--- a/src/pal/tests/palsuite/c_runtime/getenv/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/getenv/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/getenv/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/getenv/test2/CMakeLists.txt
index 7a301a5ca6..971a836239 100644
--- a/src/pal/tests/palsuite/c_runtime/getenv/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/getenv/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_getenv_test2
diff --git a/src/pal/tests/palsuite/c_runtime/getenv/test2/test2.c b/src/pal/tests/palsuite/c_runtime/getenv/test2/test2.cpp
index 26f245fcce..26f245fcce 100644
--- a/src/pal/tests/palsuite/c_runtime/getenv/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/getenv/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/getenv/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/getenv/test3/CMakeLists.txt
index 2cbe472221..620ccd1003 100644
--- a/src/pal/tests/palsuite/c_runtime/getenv/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/getenv/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_getenv_test3
diff --git a/src/pal/tests/palsuite/c_runtime/getenv/test3/test3.c b/src/pal/tests/palsuite/c_runtime/getenv/test3/test3.cpp
index 1eefd9d40c..1eefd9d40c 100644
--- a/src/pal/tests/palsuite/c_runtime/getenv/test3/test3.c
+++ b/src/pal/tests/palsuite/c_runtime/getenv/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/isalnum/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/isalnum/test1/CMakeLists.txt
index 3879bb7902..af65f32cbf 100644
--- a/src/pal/tests/palsuite/c_runtime/isalnum/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/isalnum/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_isalnum_test1
diff --git a/src/pal/tests/palsuite/c_runtime/isalnum/test1/test1.c b/src/pal/tests/palsuite/c_runtime/isalnum/test1/test1.cpp
index d9cdfcadf6..d9cdfcadf6 100644
--- a/src/pal/tests/palsuite/c_runtime/isalnum/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/isalnum/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/isalpha/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/isalpha/test1/CMakeLists.txt
index 44fb72d7fe..82f19ad383 100644
--- a/src/pal/tests/palsuite/c_runtime/isalpha/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/isalpha/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_isalpha_test1
diff --git a/src/pal/tests/palsuite/c_runtime/isalpha/test1/test1.c b/src/pal/tests/palsuite/c_runtime/isalpha/test1/test1.cpp
index b494d14a92..b494d14a92 100644
--- a/src/pal/tests/palsuite/c_runtime/isalpha/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/isalpha/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/isdigit/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/isdigit/test1/CMakeLists.txt
index dd03b238e1..b96b7aa706 100644
--- a/src/pal/tests/palsuite/c_runtime/isdigit/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/isdigit/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_isdigit_test1
diff --git a/src/pal/tests/palsuite/c_runtime/isdigit/test1/test1.c b/src/pal/tests/palsuite/c_runtime/isdigit/test1/test1.cpp
index ad2344827f..ad2344827f 100644
--- a/src/pal/tests/palsuite/c_runtime/isdigit/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/isdigit/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/islower/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/islower/test1/CMakeLists.txt
index b7f5ad069f..d071d4bb65 100644
--- a/src/pal/tests/palsuite/c_runtime/islower/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/islower/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_islower_test1
diff --git a/src/pal/tests/palsuite/c_runtime/islower/test1/test1.c b/src/pal/tests/palsuite/c_runtime/islower/test1/test1.cpp
index c8e877b705..c8e877b705 100644
--- a/src/pal/tests/palsuite/c_runtime/islower/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/islower/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/isprint/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/isprint/test1/CMakeLists.txt
index 365777ab5a..91410a02ab 100644
--- a/src/pal/tests/palsuite/c_runtime/isprint/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/isprint/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- isprint.c
+ isprint.cpp
)
add_executable(paltest_isprint_test1
diff --git a/src/pal/tests/palsuite/c_runtime/isprint/test1/isprint.c b/src/pal/tests/palsuite/c_runtime/isprint/test1/isprint.cpp
index 54db666bf2..54db666bf2 100644
--- a/src/pal/tests/palsuite/c_runtime/isprint/test1/isprint.c
+++ b/src/pal/tests/palsuite/c_runtime/isprint/test1/isprint.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/isprint/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/isprint/test2/CMakeLists.txt
index a7ad75cc04..53ad94273c 100644
--- a/src/pal/tests/palsuite/c_runtime/isprint/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/isprint/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_isprint_test2
diff --git a/src/pal/tests/palsuite/c_runtime/isprint/test2/test2.c b/src/pal/tests/palsuite/c_runtime/isprint/test2/test2.cpp
index 2170c47a14..2170c47a14 100644
--- a/src/pal/tests/palsuite/c_runtime/isprint/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/isprint/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/isspace/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/isspace/test1/CMakeLists.txt
index 34ad70d328..c3cc525145 100644
--- a/src/pal/tests/palsuite/c_runtime/isspace/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/isspace/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_isspace_test1
diff --git a/src/pal/tests/palsuite/c_runtime/isspace/test1/test1.c b/src/pal/tests/palsuite/c_runtime/isspace/test1/test1.cpp
index 6cd1ce878b..6cd1ce878b 100644
--- a/src/pal/tests/palsuite/c_runtime/isspace/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/isspace/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/isupper/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/isupper/test1/CMakeLists.txt
index c7fc71c43b..e1cfa6609d 100644
--- a/src/pal/tests/palsuite/c_runtime/isupper/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/isupper/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_isupper_test1
diff --git a/src/pal/tests/palsuite/c_runtime/isupper/test1/test1.c b/src/pal/tests/palsuite/c_runtime/isupper/test1/test1.cpp
index b88bcc4a7e..b88bcc4a7e 100644
--- a/src/pal/tests/palsuite/c_runtime/isupper/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/isupper/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/iswdigit/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/iswdigit/test1/CMakeLists.txt
index b35dd5ed6d..4074abbe76 100644
--- a/src/pal/tests/palsuite/c_runtime/iswdigit/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/iswdigit/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_iswdigit_test1
diff --git a/src/pal/tests/palsuite/c_runtime/iswdigit/test1/test1.c b/src/pal/tests/palsuite/c_runtime/iswdigit/test1/test1.cpp
index 1cf94c5d13..1cf94c5d13 100644
--- a/src/pal/tests/palsuite/c_runtime/iswdigit/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/iswdigit/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/iswprint/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/iswprint/test1/CMakeLists.txt
index 5e436c3ca2..d21c232133 100644
--- a/src/pal/tests/palsuite/c_runtime/iswprint/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/iswprint/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_iswprint_test1
diff --git a/src/pal/tests/palsuite/c_runtime/iswprint/test1/test1.c b/src/pal/tests/palsuite/c_runtime/iswprint/test1/test1.cpp
index 08a985b2d6..08a985b2d6 100644
--- a/src/pal/tests/palsuite/c_runtime/iswprint/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/iswprint/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/iswspace/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/iswspace/test1/CMakeLists.txt
index 1368e55ccc..1f9a54fb17 100644
--- a/src/pal/tests/palsuite/c_runtime/iswspace/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/iswspace/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_iswspace_test1
diff --git a/src/pal/tests/palsuite/c_runtime/iswspace/test1/test1.c b/src/pal/tests/palsuite/c_runtime/iswspace/test1/test1.cpp
index c58997812e..c58997812e 100644
--- a/src/pal/tests/palsuite/c_runtime/iswspace/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/iswspace/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/iswupper/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/iswupper/test1/CMakeLists.txt
index 8b8fae6d72..1da5fbaa75 100644
--- a/src/pal/tests/palsuite/c_runtime/iswupper/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/iswupper/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_iswupper_test1
diff --git a/src/pal/tests/palsuite/c_runtime/iswupper/test1/test1.c b/src/pal/tests/palsuite/c_runtime/iswupper/test1/test1.cpp
index a01686be44..a01686be44 100644
--- a/src/pal/tests/palsuite/c_runtime/iswupper/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/iswupper/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/iswxdigit/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/iswxdigit/test1/CMakeLists.txt
index 3a726eced9..ae55976128 100644
--- a/src/pal/tests/palsuite/c_runtime/iswxdigit/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/iswxdigit/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_iswxdigit_test1
diff --git a/src/pal/tests/palsuite/c_runtime/iswxdigit/test1/test1.c b/src/pal/tests/palsuite/c_runtime/iswxdigit/test1/test1.cpp
index 73ad495856..73ad495856 100644
--- a/src/pal/tests/palsuite/c_runtime/iswxdigit/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/iswxdigit/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/isxdigit/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/isxdigit/test1/CMakeLists.txt
index 8919b36e42..4fd46c93d8 100644
--- a/src/pal/tests/palsuite/c_runtime/isxdigit/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/isxdigit/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_isxdigit_test1
diff --git a/src/pal/tests/palsuite/c_runtime/isxdigit/test1/test1.c b/src/pal/tests/palsuite/c_runtime/isxdigit/test1/test1.cpp
index be25af233c..be25af233c 100644
--- a/src/pal/tests/palsuite/c_runtime/isxdigit/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/isxdigit/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/labs/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/labs/test1/CMakeLists.txt
index cf0f0999a9..2ffb3cd641 100644
--- a/src/pal/tests/palsuite/c_runtime/labs/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/labs/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_labs_test1
diff --git a/src/pal/tests/palsuite/c_runtime/labs/test1/test1.c b/src/pal/tests/palsuite/c_runtime/labs/test1/test1.cpp
index 41f85226e1..41f85226e1 100644
--- a/src/pal/tests/palsuite/c_runtime/labs/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/labs/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/llabs/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/llabs/test1/CMakeLists.txt
index 8f5bdbe097..3adc3cc737 100644
--- a/src/pal/tests/palsuite/c_runtime/llabs/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/llabs/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_llabs_test1
diff --git a/src/pal/tests/palsuite/c_runtime/llabs/test1/test1.c b/src/pal/tests/palsuite/c_runtime/llabs/test1/test1.cpp
index 044e22f134..044e22f134 100644
--- a/src/pal/tests/palsuite/c_runtime/llabs/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/llabs/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/localtime/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/localtime/test1/CMakeLists.txt
index 25acf48749..698699f821 100644
--- a/src/pal/tests/palsuite/c_runtime/localtime/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/localtime/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_localtime_test1
diff --git a/src/pal/tests/palsuite/c_runtime/localtime/test1/test1.c b/src/pal/tests/palsuite/c_runtime/localtime/test1/test1.cpp
index a993a17f69..a993a17f69 100644
--- a/src/pal/tests/palsuite/c_runtime/localtime/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/localtime/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/log/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/log/test1/CMakeLists.txt
index dd19002904..c8f991b997 100644
--- a/src/pal/tests/palsuite/c_runtime/log/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/log/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_log_test1
diff --git a/src/pal/tests/palsuite/c_runtime/log/test1/test1.c b/src/pal/tests/palsuite/c_runtime/log/test1/test1.cpp
index eea592dd45..eea592dd45 100644
--- a/src/pal/tests/palsuite/c_runtime/log/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/log/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/log10/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/log10/test1/CMakeLists.txt
index 31e750df3e..31025fbd04 100644
--- a/src/pal/tests/palsuite/c_runtime/log10/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/log10/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_log10_test1
diff --git a/src/pal/tests/palsuite/c_runtime/log10/test1/test1.c b/src/pal/tests/palsuite/c_runtime/log10/test1/test1.cpp
index 13711a752e..13711a752e 100644
--- a/src/pal/tests/palsuite/c_runtime/log10/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/log10/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/log10f/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/log10f/CMakeLists.txt
new file mode 100644
index 0000000000..5e1ef7f28b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/log10f/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/log10f/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/log10f/test1/CMakeLists.txt
new file mode 100644
index 0000000000..b2c0835451
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/log10f/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.c
+)
+
+add_executable(paltest_log10f_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_log10f_test1 coreclrpal)
+
+target_link_libraries(paltest_log10f_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/log10f/test1/test1.c b/src/pal/tests/palsuite/c_runtime/log10f/test1/test1.c
new file mode 100644
index 0000000000..e7c8c2f28b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/log10f/test1/test1.c
@@ -0,0 +1,144 @@
+// Licensed to the .NET Foundation under one or more 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: test1.c
+**
+** Purpose: Test to ensure that log10f returns correct values.
+**
+** Dependencies: PAL_Initialize
+** PAL_Terminate
+** Fail
+** fabs
+** _isnanf
+**
+**===========================================================================*/
+
+#include <palsuite.h>
+
+// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this
+// is slightly too accurate when writing tests meant to run against libm implementations
+// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get.
+//
+// The tests themselves will take PAL_EPSILON and adjust it according to the expected result
+// so that the delta used for comparison will compare the most significant digits and ignore
+// any digits that are outside the double precision range (6-9 digits).
+
+// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON
+// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use
+// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10.
+#define PAL_EPSILON 4.76837158e-07
+
+#define PAL_NAN sqrtf(-1.0f)
+#define PAL_POSINF -logf(0.0f)
+#define PAL_NEGINF logf(0.0f)
+
+/**
+ * Helper test structure
+ */
+struct test
+{
+ float value; /* value to test the function with */
+ float expected; /* expected result */
+ float variance; /* maximum delta between the expected and actual result */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl validate(float value, float expected, float variance)
+{
+ float result = log10f(value);
+
+ /*
+ * The test is valid when the difference between result
+ * and expected is less than or equal to variance
+ */
+ float delta = fabsf(result - expected);
+
+ if (delta > variance)
+ {
+ Fail("log10f(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, expected);
+ }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl validate_isnan(float value)
+{
+ float result = log10f(value);
+
+ if (!_isnanf(result))
+ {
+ Fail("log10f(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, PAL_NAN);
+ }
+}
+
+/**
+ * main
+ *
+ * executable entry point
+ */
+int __cdecl main(int argc, char **argv)
+{
+ struct test tests[] =
+ {
+ /* value expected variance */
+ { 0, PAL_NEGINF, 0 },
+ { 0.000721784159f, -3.14159265f, PAL_EPSILON * 10 }, // expected: -(pi)
+ { 0.00191301410f, -2.71828183f, PAL_EPSILON * 10 }, // expected: -(e)
+ { 0.00498212830f, -2.30258509f, PAL_EPSILON * 10 }, // expected: -(ln(10))
+ { 0.0268660410f, -1.57079633f, PAL_EPSILON * 10 }, // expected: -(pi / 2)
+ { 0.0360831928f, -1.44269504f, PAL_EPSILON * 10 }, // expected: -(logf2(e))
+ { 0.0385288847f, -1.41421356f, PAL_EPSILON * 10 }, // expected: -(sqrtf(2))
+ { 0.0744082059f, -1.12837917f, PAL_EPSILON * 10 }, // expected: -(2 / sqrtf(pi))
+ { 0.1f, -1, PAL_EPSILON * 10 }, // expected: -(1)
+ { 0.163908636f, -0.785398163f, PAL_EPSILON }, // expected: -(pi / 4)
+ { 0.196287760f, -0.707106781f, PAL_EPSILON }, // expected: -(1 / sqrtf(2))
+ { 0.202699566f, -0.693147181f, PAL_EPSILON }, // expected: -(ln(2))
+ { 0.230876765f, -0.636619772f, PAL_EPSILON }, // expected: -(2 / pi)
+ { 0.367879441f, -0.434294482f, PAL_EPSILON }, // expected: -(log10f(e))
+ { 0.480496373f, -0.318309886f, PAL_EPSILON }, // expected: -(1 / pi)
+ { 1, 0, PAL_EPSILON },
+ { 2.08118116f, 0.318309886f, PAL_EPSILON }, // expected: 1 / pi
+ { 2.71828183f, 0.434294482f, PAL_EPSILON }, // expected: log10f(e) value: e
+ { 4.33131503f, 0.636619772f, PAL_EPSILON }, // expected: 2 / pi
+ { 4.93340967f, 0.693147181f, PAL_EPSILON }, // expected: ln(2)
+ { 5.09456117f, 0.707106781f, PAL_EPSILON }, // expected: 1 / sqrtf(2)
+ { 6.10095980f, 0.785398163f, PAL_EPSILON }, // expected: pi / 4
+ { 10, 1, PAL_EPSILON * 10 },
+ { 13.4393779f, 1.12837917f, PAL_EPSILON * 10 }, // expected: 2 / sqrtf(pi)
+ { 25.9545535f, 1.41421356f, PAL_EPSILON * 10 }, // expected: sqrtf(2)
+ { 27.7137338f, 1.44269504f, PAL_EPSILON * 10 }, // expected: logf2(e)
+ { 37.2217105f, 1.57079633f, PAL_EPSILON * 10 }, // expected: pi / 2
+ { 200.717432f, 2.30258509f, PAL_EPSILON * 10 }, // expected: ln(10)
+ { 522.735300f, 2.71828183f, PAL_EPSILON * 10 }, // expected: e
+ { 1385.45573f, 3.14159265f, PAL_EPSILON * 10 }, // expected: pi
+ { PAL_POSINF, PAL_POSINF, 0 },
+ };
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++)
+ {
+ validate(tests[i].value, tests[i].expected, tests[i].variance);
+ }
+
+ validate_isnan(PAL_NEGINF);
+ validate_isnan(PAL_NAN);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/log10f/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/log10f/test1/testinfo.dat
new file mode 100644
index 0000000000..175ee3ab09
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/log10f/test1/testinfo.dat
@@ -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.
+
+Version = 1.0
+Section = C Runtime
+Function = log10f
+Name = Positive Test for log10f
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Passes a series of values to the log10f() function,
+= checking each for the expected result. Also checks
+= for proper handling of out-of-range values.
+
+
+
diff --git a/src/pal/tests/palsuite/c_runtime/logf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/logf/CMakeLists.txt
new file mode 100644
index 0000000000..5e1ef7f28b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/logf/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/logf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/logf/test1/CMakeLists.txt
new file mode 100644
index 0000000000..550f572bc7
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/logf/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.c
+)
+
+add_executable(paltest_logf_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_logf_test1 coreclrpal)
+
+target_link_libraries(paltest_logf_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/logf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/logf/test1/test1.c
new file mode 100644
index 0000000000..499778e992
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/logf/test1/test1.c
@@ -0,0 +1,139 @@
+// Licensed to the .NET Foundation under one or more 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: test1.c
+**
+** Purpose: Tests logf with a normal set of values.
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this
+// is slightly too accurate when writing tests meant to run against libm implementations
+// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get.
+//
+// The tests themselves will take PAL_EPSILON and adjust it according to the expected result
+// so that the delta used for comparison will compare the most significant digits and ignore
+// any digits that are outside the double precision range (6-9 digits).
+
+// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON
+// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use
+// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10.
+#define PAL_EPSILON 4.76837158e-07
+
+#define PAL_NAN sqrtf(-1.0f)
+#define PAL_POSINF -logf(0.0f)
+#define PAL_NEGINF logf(0.0f)
+
+/**
+ * Helper test structure
+ */
+struct test
+{
+ float value; /* value to test the function with */
+ float expected; /* expected result */
+ float variance; /* maximum delta between the expected and actual result */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl validate(float value, float expected, float variance)
+{
+ float result = logf(value);
+
+ /*
+ * The test is valid when the difference between result
+ * and expected is less than or equal to variance
+ */
+ float delta = fabsf(result - expected);
+
+ if (delta > variance)
+ {
+ Fail("logf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, expected);
+ }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl validate_isnan(float value)
+{
+ float result = logf(value);
+
+ if (!_isnanf(result))
+ {
+ Fail("logf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, PAL_NAN);
+ }
+}
+
+/**
+ * main
+ *
+ * executable entry point
+ */
+int __cdecl main(int argc, char **argv)
+{
+ struct test tests[] =
+ {
+ /* value expected variance */
+ { 0, PAL_NEGINF, 0 },
+ { 0.0432139183f, -3.14159265f, PAL_EPSILON * 10 }, // expected: -(pi)
+ { 0.0659880358f, -2.71828183f, PAL_EPSILON * 10 }, // expected: -(e)
+ { 0.1f, -2.30258509f, PAL_EPSILON * 10 }, // expected: -(ln(10))
+ { 0.207879576f, -1.57079633f, PAL_EPSILON * 10 }, // expected: -(pi / 2)
+ { 0.236290088f, -1.44269504f, PAL_EPSILON * 10 }, // expected: -(logf2(e))
+ { 0.243116734f, -1.41421356f, PAL_EPSILON * 10 }, // expected: -(sqrtf(2))
+ { 0.323557264f, -1.12837917f, PAL_EPSILON * 10 }, // expected: -(2 / sqrtf(pi))
+ { 0.367879441f, -1, PAL_EPSILON * 10 }, // expected: -(1)
+ { 0.455938128f, -0.785398163f, PAL_EPSILON }, // expected: -(pi / 4)
+ { 0.493068691f, -0.707106781f, PAL_EPSILON }, // expected: -(1 / sqrtf(2))
+ { 0.5f, -0.693147181f, PAL_EPSILON }, // expected: -(ln(2))
+ { 0.529077808f, -0.636619772f, PAL_EPSILON }, // expected: -(2 / pi)
+ { 0.647721485f, -0.434294482f, PAL_EPSILON }, // expected: -(log10f(e))
+ { 0.727377349f, -0.318309886f, PAL_EPSILON }, // expected: -(1 / pi)
+ { 1, 0, PAL_EPSILON },
+ { 1.37480223f, 0.318309886f, PAL_EPSILON }, // expected: 1 / pi
+ { 1.54387344f, 0.434294482f, PAL_EPSILON }, // expected: log10f(e)
+ { 1.89008116f, 0.636619772f, PAL_EPSILON }, // expected: 2 / pi
+ { 2, 0.693147181f, PAL_EPSILON }, // expected: ln(2)
+ { 2.02811498f, 0.707106781f, PAL_EPSILON }, // expected: 1 / sqrtf(2)
+ { 2.19328005f, 0.785398163f, PAL_EPSILON }, // expected: pi / 4
+ { 2.71828183f, 1, PAL_EPSILON * 10 }, // value: e
+ { 3.09064302f, 1.12837917f, PAL_EPSILON * 10 }, // expected: 2 / sqrtf(pi)
+ { 4.11325038f, 1.41421356f, PAL_EPSILON * 10 }, // expected: sqrtf(2)
+ { 4.23208611f, 1.44269504f, PAL_EPSILON * 10 }, // expected: logf2(e)
+ { 4.81047738f, 1.57079633f, PAL_EPSILON * 10 }, // expected: pi / 2
+ { 10, 2.30258509f, PAL_EPSILON * 10 }, // expected: ln(10)
+ { 15.1542622f, 2.71828183f, PAL_EPSILON * 10 }, // expected: e
+ { 23.1406926f, 3.14159265f, PAL_EPSILON * 10 }, // expected: pi
+ { PAL_POSINF, PAL_POSINF, 0 },
+ };
+
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++)
+ {
+ validate(tests[i].value, tests[i].expected, tests[i].variance);
+ }
+
+ validate_isnan(PAL_NEGINF);
+ validate_isnan(PAL_NAN);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/logf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/logf/test1/testinfo.dat
new file mode 100644
index 0000000000..aadfee6c11
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/logf/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 = C Runtime
+Function = logf
+Name = Positive Test for logf
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Passes a series of values to the logf() function,
+= checking each for the expected result. Also checks
+= for proper handling of out-of-range values.
diff --git a/src/pal/tests/palsuite/c_runtime/malloc/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/malloc/test1/CMakeLists.txt
index 4a388ad3d7..f475730973 100644
--- a/src/pal/tests/palsuite/c_runtime/malloc/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/malloc/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_malloc_test1
diff --git a/src/pal/tests/palsuite/c_runtime/malloc/test1/test1.c b/src/pal/tests/palsuite/c_runtime/malloc/test1/test1.cpp
index 7ea4dd068f..7ea4dd068f 100644
--- a/src/pal/tests/palsuite/c_runtime/malloc/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/malloc/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/malloc/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/malloc/test2/CMakeLists.txt
index abbed2aa62..663e104d0e 100644
--- a/src/pal/tests/palsuite/c_runtime/malloc/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/malloc/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_malloc_test2
diff --git a/src/pal/tests/palsuite/c_runtime/malloc/test2/test2.c b/src/pal/tests/palsuite/c_runtime/malloc/test2/test2.cpp
index 5deee0eddb..5deee0eddb 100644
--- a/src/pal/tests/palsuite/c_runtime/malloc/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/malloc/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/memchr/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/memchr/test1/CMakeLists.txt
index 4e33a8fc04..959fd2a3bc 100644
--- a/src/pal/tests/palsuite/c_runtime/memchr/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/memchr/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_memchr_test1
diff --git a/src/pal/tests/palsuite/c_runtime/memchr/test1/test1.c b/src/pal/tests/palsuite/c_runtime/memchr/test1/test1.cpp
index 043a6789d8..043a6789d8 100644
--- a/src/pal/tests/palsuite/c_runtime/memchr/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/memchr/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/memcmp/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/memcmp/test1/CMakeLists.txt
index b61f208f34..43d8fdd7f7 100644
--- a/src/pal/tests/palsuite/c_runtime/memcmp/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/memcmp/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_memcmp_test1
diff --git a/src/pal/tests/palsuite/c_runtime/memcmp/test1/test1.c b/src/pal/tests/palsuite/c_runtime/memcmp/test1/test1.cpp
index 7b63173e22..7b63173e22 100644
--- a/src/pal/tests/palsuite/c_runtime/memcmp/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/memcmp/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/memcpy/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/memcpy/test1/CMakeLists.txt
index d846bfc62d..14db0df60e 100644
--- a/src/pal/tests/palsuite/c_runtime/memcpy/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/memcpy/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_memcpy_test1
diff --git a/src/pal/tests/palsuite/c_runtime/memcpy/test1/test1.c b/src/pal/tests/palsuite/c_runtime/memcpy/test1/test1.cpp
index 9da98d6573..9da98d6573 100644
--- a/src/pal/tests/palsuite/c_runtime/memcpy/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/memcpy/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/memmove/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/memmove/test1/CMakeLists.txt
index cf50ec01b7..db6f65e48b 100644
--- a/src/pal/tests/palsuite/c_runtime/memmove/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/memmove/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_memmove_test1
diff --git a/src/pal/tests/palsuite/c_runtime/memmove/test1/test1.c b/src/pal/tests/palsuite/c_runtime/memmove/test1/test1.c
deleted file mode 100644
index c1af871f4a..0000000000
--- a/src/pal/tests/palsuite/c_runtime/memmove/test1/test1.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test1.c
-**
-** Purpose: Test that memmove correctly copies text from one buffer
-** to another even when the buffers overlap.
-**
-**
-**==========================================================================*/
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char **argv)
-{
- char testA[11] = "abcdefghij";
- char testB[15] = "aabbccddeeffgg";
- char testC[15] = "aabbccddeeffgg";
- char testD[15] = "aabbccddeeffgg";
- char insString[3] = "zzz";
- char *retVal;
-
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
- /* move a string onto itself */
- retVal = (char *)memmove(testA + 2, testA, 8);
- if (retVal != testA + 2)
- {
- Fail("The return value should have been the value of the destination"
- "pointer, but wasn't\n");
- }
-
- /*Check the most likely error*/
- if (memcmp(testA, "ababababab", 11) == 0)
- {
- Fail("memmove should have saved the characters in the region of"
- " overlap between source and destination, but didn't.\n");
- }
-
- if (memcmp(testA, "ababcdefgh", 11) != 0)
- {
- /* not sure what exactly went wrong. */
- Fail("memmove was called on a region containing the characters"
- " \"abcdefghij\". It was to move the first 8 positions to"
- " the last 8 positions, giving the result \"ababcdefgh\". "
- " Instead, it gave the result \"%s\".\n", testA);
- }
-
- /* move a string to the front of testB */
- retVal = (char *)memmove(testB, insString, 3);
- if(retVal != testB)
- {
- Fail("memmove: The function did not return the correct "
- "string.\n");
- }
-
- if(memcmp(testB, "zzzbccddeeffgg",15) != 0)
- {
- Fail("memmove: The function failed to move the string "
- "correctly.\n");
- }
-
-
- /* move a string to the middle of testC */
- retVal = memmove(testC+5, insString, 3);
- if(retVal != testC+5)
- {
- Fail("memmove: The function did not return the correct "
- "string.\n");
- }
-
- if(memcmp(testC, "aabbczzzeeffgg",15) != 0)
- {
- Fail("memmove: The function failed to move the string "
- "correctly.\n");
- }
-
-
- /* move a string to the end of testD */
- retVal = memmove(testD+11, insString, 3);
- if(retVal != testD+11)
- {
- Fail("memmove: The function did not return the correct "
- "string.\n");
- }
-
- if(memcmp(testD, "aabbccddeefzzz",15) != 0)
- {
- Fail("memmove: The function failed to move the string "
- "correctly.\n");
- }
-
- PAL_Terminate();
- return PASS;
-
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/pal/tests/palsuite/c_runtime/memmove/test1/test1.cpp b/src/pal/tests/palsuite/c_runtime/memmove/test1/test1.cpp
new file mode 100644
index 0000000000..8279d67139
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/memmove/test1/test1.cpp
@@ -0,0 +1,116 @@
+// Licensed to the .NET Foundation under one or more 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: test1.c
+**
+** Purpose: Test that memmove correctly copies text from one buffer
+** to another even when the buffers overlap.
+**
+**
+**==========================================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char **argv)
+{
+ char testA[11] = "abcdefghij";
+ char testB[15] = "aabbccddeeffgg";
+ char testC[15] = "aabbccddeeffgg";
+ char testD[15] = "aabbccddeeffgg";
+ char insString[4] = "zzz";
+ char *retVal;
+
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ /* move a string onto itself */
+ retVal = (char *)memmove(testA + 2, testA, 8);
+ if (retVal != testA + 2)
+ {
+ Fail("The return value should have been the value of the destination"
+ "pointer, but wasn't\n");
+ }
+
+ /*Check the most likely error*/
+ if (memcmp(testA, "ababababab", 11) == 0)
+ {
+ Fail("memmove should have saved the characters in the region of"
+ " overlap between source and destination, but didn't.\n");
+ }
+
+ if (memcmp(testA, "ababcdefgh", 11) != 0)
+ {
+ /* not sure what exactly went wrong. */
+ Fail("memmove was called on a region containing the characters"
+ " \"abcdefghij\". It was to move the first 8 positions to"
+ " the last 8 positions, giving the result \"ababcdefgh\". "
+ " Instead, it gave the result \"%s\".\n", testA);
+ }
+
+ /* move a string to the front of testB */
+ retVal = (char *)memmove(testB, insString, 3);
+ if(retVal != testB)
+ {
+ Fail("memmove: The function did not return the correct "
+ "string.\n");
+ }
+
+ if(memcmp(testB, "zzzbccddeeffgg",15) != 0)
+ {
+ Fail("memmove: The function failed to move the string "
+ "correctly.\n");
+ }
+
+
+ /* move a string to the middle of testC */
+ retVal = (char*)memmove(testC+5, insString, 3);
+ if(retVal != testC+5)
+ {
+ Fail("memmove: The function did not return the correct "
+ "string.\n");
+ }
+
+ if(memcmp(testC, "aabbczzzeeffgg",15) != 0)
+ {
+ Fail("memmove: The function failed to move the string "
+ "correctly.\n");
+ }
+
+
+ /* move a string to the end of testD */
+ retVal = (char*)memmove(testD+11, insString, 3);
+ if(retVal != testD+11)
+ {
+ Fail("memmove: The function did not return the correct "
+ "string.\n");
+ }
+
+ if(memcmp(testD, "aabbccddeefzzz",15) != 0)
+ {
+ Fail("memmove: The function failed to move the string "
+ "correctly.\n");
+ }
+
+ PAL_Terminate();
+ return PASS;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pal/tests/palsuite/c_runtime/memset/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/memset/test1/CMakeLists.txt
index 78b5a6bc00..bc3d6251cb 100644
--- a/src/pal/tests/palsuite/c_runtime/memset/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/memset/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_memset_test1
diff --git a/src/pal/tests/palsuite/c_runtime/memset/test1/test1.c b/src/pal/tests/palsuite/c_runtime/memset/test1/test1.cpp
index 67cde8756b..67cde8756b 100644
--- a/src/pal/tests/palsuite/c_runtime/memset/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/memset/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/modf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/modf/test1/CMakeLists.txt
index 4b65ba7a6f..3fe7bc7c46 100644
--- a/src/pal/tests/palsuite/c_runtime/modf/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/modf/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_modf_test1
diff --git a/src/pal/tests/palsuite/c_runtime/modf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/modf/test1/test1.cpp
index 389d079253..389d079253 100644
--- a/src/pal/tests/palsuite/c_runtime/modf/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/modf/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/modff/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/modff/test1/CMakeLists.txt
index 812cd1c47b..10e5e99267 100644
--- a/src/pal/tests/palsuite/c_runtime/modff/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/modff/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_modff_test1
diff --git a/src/pal/tests/palsuite/c_runtime/modff/test1/test1.c b/src/pal/tests/palsuite/c_runtime/modff/test1/test1.cpp
index 6b7a50be39..6b7a50be39 100644
--- a/src/pal/tests/palsuite/c_runtime/modff/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/modff/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/pow/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/pow/test1/CMakeLists.txt
index 69ba02af17..f94210d5b7 100644
--- a/src/pal/tests/palsuite/c_runtime/pow/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/pow/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_pow_test1
diff --git a/src/pal/tests/palsuite/c_runtime/pow/test1/test1.c b/src/pal/tests/palsuite/c_runtime/pow/test1/test1.cpp
index 0a05cd5a47..0a05cd5a47 100644
--- a/src/pal/tests/palsuite/c_runtime/pow/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/pow/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/powf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/powf/CMakeLists.txt
new file mode 100644
index 0000000000..5e1ef7f28b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/powf/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/powf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/powf/test1/CMakeLists.txt
new file mode 100644
index 0000000000..8ea040f9a4
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/powf/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.c
+)
+
+add_executable(paltest_powf_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_powf_test1 coreclrpal)
+
+target_link_libraries(paltest_powf_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/powf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/powf/test1/test1.c
new file mode 100644
index 0000000000..ca738e8c8d
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/powf/test1/test1.c
@@ -0,0 +1,229 @@
+// Licensed to the .NET Foundation under one or more 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: test1.c
+**
+** Purpose: Tests that atan2f returns correct values for a subset of values.
+** Tests with positive and negative values of x and y to ensure
+** atan2f is returning results from the correct quadrant.
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this
+// is slightly too accurate when writing tests meant to run against libm implementations
+// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get.
+//
+// The tests themselves will take PAL_EPSILON and adjust it according to the expected result
+// so that the delta used for comparison will compare the most significant digits and ignore
+// any digits that are outside the double precision range (6-9 digits).
+
+// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON
+// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use
+// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10.
+#define PAL_EPSILON 4.76837158e-07
+
+#define PAL_NAN sqrtf(-1.0f)
+#define PAL_POSINF -logf(0.0f)
+#define PAL_NEGINF logf(0.0f)
+
+/**
+ * Helper test structure
+ */
+struct test
+{
+ float x; /* first component of the value to test the function with */
+ float y; /* second component of the value to test the function with */
+ float expected; /* expected result */
+ float variance; /* maximum delta between the expected and actual result */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl validate(float x, float y, float expected, float variance)
+{
+ float result = powf(x, y);
+
+ /*
+ * The test is valid when the difference between result
+ * and expected is less than or equal to variance
+ */
+ float delta = fabsf(result - expected);
+
+ if (delta > variance)
+ {
+ Fail("powf(%g, %g) returned %10.9g when it should have returned %10.9g",
+ x, y, result, expected);
+ }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl validate_isnan(float x, float y)
+{
+ float result = powf(x, y);
+
+ if (!_isnanf(result))
+ {
+ Fail("powf(%g, %g) returned %10.9g when it should have returned %10.9g",
+ x, y, result, PAL_NAN);
+ }
+}
+
+/**
+ * main
+ *
+ * executable entry point
+ */
+int __cdecl main(int argc, char **argv)
+{
+ struct test tests[] =
+ {
+ /* x y expected variance */
+ { PAL_NEGINF, PAL_NEGINF, 0, PAL_EPSILON },
+ { PAL_NEGINF, PAL_POSINF, PAL_POSINF, 0 },
+
+ { -10, PAL_NEGINF, 0, PAL_EPSILON },
+ { -10, -1, -0.1f, PAL_EPSILON },
+ { -10, 0, 1, PAL_EPSILON * 10 },
+ { -10, 1, -10, PAL_EPSILON * 100 },
+ { -10, PAL_POSINF, PAL_POSINF, 0 },
+
+ { -2.71828183f, PAL_NEGINF, 0, PAL_EPSILON }, // x: -(e)
+ { -2.71828183f, -1, -0.367879441f, PAL_EPSILON }, // x: -(e)
+ { -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)
+
+ { -0.0, PAL_NEGINF, PAL_POSINF, 0 },
+ { -0.0, -1, PAL_NEGINF, 0 },
+ { -0.0f, -0.0f, 1, PAL_EPSILON * 10 },
+ { -0.0f, 0, 1, PAL_EPSILON * 10 },
+ { -0.0, 1, -0.0, PAL_EPSILON },
+ { -0.0, PAL_POSINF, 0, PAL_EPSILON },
+
+ { 0.0, PAL_NEGINF, PAL_POSINF, 0 },
+ { 0.0, -1, PAL_POSINF, 0 },
+ { 0, -0.0f, 1, PAL_EPSILON * 10 },
+ { 0, 0, 1, PAL_EPSILON * 10 },
+ { 0.0, 1, 0, PAL_EPSILON },
+ { 0.0, PAL_POSINF, 0, PAL_EPSILON },
+
+ { 1, PAL_NEGINF, 1, PAL_EPSILON * 10 },
+ { 1, PAL_POSINF, 1, PAL_EPSILON * 10 },
+
+ { 2.71828183f, PAL_NEGINF, 0, PAL_EPSILON },
+ { 2.71828183f, -3.14159265f, 0.0432139183f, PAL_EPSILON / 10 }, // x: e y: -(pi)
+ { 2.71828183f, -2.71828183f, 0.0659880358f, PAL_EPSILON / 10 }, // x: e y: -(e)
+ { 2.71828183f, -2.30258509f, 0.1f, PAL_EPSILON }, // x: e y: -(ln(10))
+ { 2.71828183f, -1.57079633f, 0.207879576f, PAL_EPSILON }, // x: e y: -(pi / 2)
+ { 2.71828183f, -1.44269504f, 0.236290088f, PAL_EPSILON }, // x: e y: -(logf2(e))
+ { 2.71828183f, -1.41421356f, 0.243116734f, PAL_EPSILON }, // x: e y: -(sqrtf(2))
+ { 2.71828183f, -1.12837917f, 0.323557264f, PAL_EPSILON }, // x: e y: -(2 / sqrtf(pi))
+ { 2.71828183f, -1, 0.367879441f, PAL_EPSILON }, // x: e y: -(1)
+ { 2.71828183f, -0.785398163f, 0.455938128f, PAL_EPSILON }, // x: e y: -(pi / 4)
+ { 2.71828183f, -0.707106781f, 0.493068691f, PAL_EPSILON }, // x: e y: -(1 / sqrtf(2))
+ { 2.71828183f, -0.693147181f, 0.5f, PAL_EPSILON }, // x: e y: -(ln(2))
+ { 2.71828183f, -0.636619772f, 0.529077808f, PAL_EPSILON }, // x: e y: -(2 / pi)
+ { 2.71828183f, -0.434294482f, 0.647721485f, PAL_EPSILON }, // x: e y: -(log10f(e))
+ { 2.71828183f, -0.318309886f, 0.727377349f, PAL_EPSILON }, // x: e y: -(1 / pi)
+ { 2.71828183f, 0, 1, PAL_EPSILON * 10 }, // x: e
+ { 2.71828183f, 0.318309886f, 1.37480223f, PAL_EPSILON * 10 }, // x: e y: 1 / pi
+ { 2.71828183f, 0.434294482f, 1.54387344f, PAL_EPSILON * 10 }, // x: e y: log10f(e)
+ { 2.71828183f, 0.636619772f, 1.89008116f, PAL_EPSILON * 10 }, // x: e y: 2 / pi
+ { 2.71828183f, 0.693147181f, 2, PAL_EPSILON * 10 }, // x: e y: ln(2)
+ { 2.71828183f, 0.707106781f, 2.02811498f, PAL_EPSILON * 10 }, // x: e y: 1 / sqrtf(2)
+ { 2.71828183f, 0.785398163f, 2.19328005f, PAL_EPSILON * 10 }, // x: e y: pi / 4
+ { 2.71828183f, 1, 2.71828183f, PAL_EPSILON * 10 }, // x: e expected: e
+ { 2.71828183f, 1.12837917f, 3.09064302f, PAL_EPSILON * 10 }, // x: e y: 2 / sqrtf(pi)
+ { 2.71828183f, 1.41421356f, 4.11325038f, PAL_EPSILON * 10 }, // x: e y: sqrtf(2)
+ { 2.71828183f, 1.44269504f, 4.23208611f, PAL_EPSILON * 10 }, // x: e y: logf2(e)
+ { 2.71828183f, 1.57079633f, 4.81047738f, PAL_EPSILON * 10 }, // x: e y: pi / 2
+ { 2.71828183f, 2.30258509f, 10, PAL_EPSILON * 100 }, // x: e y: ln(10)
+ { 2.71828183f, 2.71828183f, 15.1542622f, PAL_EPSILON * 100 }, // x: e y: e
+ { 2.71828183f, 3.14159265f, 23.1406926f, PAL_EPSILON * 100 }, // x: e y: pi
+ { 2.71828183f, PAL_POSINF, PAL_POSINF, 0 }, // x: e
+
+ { 10, PAL_NEGINF, 0, 0 },
+ { 10, -3.14159265f, 0.000721784159f, PAL_EPSILON / 1000 }, // y: -(pi)
+ { 10, -2.71828183f, 0.00191301410f, PAL_EPSILON / 100 }, // y: -(e)
+ { 10, -2.30258509f, 0.00498212830f, PAL_EPSILON / 100 }, // y: -(ln(10))
+ { 10, -1.57079633f, 0.0268660410f, PAL_EPSILON / 10 }, // y: -(pi / 2)
+ { 10, -1.44269504f, 0.0360831928f, PAL_EPSILON / 10 }, // y: -(logf2(e))
+ { 10, -1.41421356f, 0.0385288847f, PAL_EPSILON / 10 }, // y: -(sqrtf(2))
+ { 10, -1.12837917f, 0.0744082059f, PAL_EPSILON / 10 }, // y: -(2 / sqrtf(pi))
+ { 10, -1, 0.1f, PAL_EPSILON }, // y: -(1)
+ { 10, -0.785398163f, 0.163908636f, PAL_EPSILON }, // y: -(pi / 4)
+ { 10, -0.707106781f, 0.196287760f, PAL_EPSILON }, // y: -(1 / sqrtf(2))
+ { 10, -0.693147181f, 0.202699566f, PAL_EPSILON }, // y: -(ln(2))
+ { 10, -0.636619772f, 0.230876765f, PAL_EPSILON }, // y: -(2 / pi)
+ { 10, -0.434294482f, 0.367879441f, PAL_EPSILON }, // y: -(log10f(e))
+ { 10, -0.318309886f, 0.480496373f, PAL_EPSILON }, // y: -(1 / pi)
+ { 10, 0, 1, PAL_EPSILON * 10 },
+ { 10, 0.318309886f, 2.08118116f, PAL_EPSILON * 10 }, // y: 1 / pi
+ { 10, 0.434294482f, 2.71828183f, PAL_EPSILON * 10 }, // y: log10f(e) expected: e
+ { 10, 0.636619772f, 4.33131503f, PAL_EPSILON * 10 }, // y: 2 / pi
+ { 10, 0.693147181f, 4.93340967f, PAL_EPSILON * 10 }, // y: ln(2)
+ { 10, 0.707106781f, 5.09456117f, PAL_EPSILON * 10 }, // y: 1 / sqrtf(2)
+ { 10, 0.785398163f, 6.10095980f, PAL_EPSILON * 10 }, // y: pi / 4
+ { 10, 1, 10, PAL_EPSILON * 100 },
+ { 10, 1.12837917f, 13.4393779f, PAL_EPSILON * 100 }, // y: 2 / sqrtf(pi)
+ { 10, 1.41421356f, 25.9545535f, PAL_EPSILON * 100 }, // y: sqrtf(2)
+ { 10, 1.44269504f, 27.7137338f, PAL_EPSILON * 100 }, // y: logf2(e)
+ { 10, 1.57079633f, 37.2217105f, PAL_EPSILON * 100 }, // y: pi / 2
+ { 10, 2.30258509f, 200.717432f, PAL_EPSILON * 1000 }, // y: ln(10)
+ { 10, 2.71828183f, 522.735300f, PAL_EPSILON * 1000 }, // y: e
+ { 10, 3.14159265f, 1385.45573f, PAL_EPSILON * 10000 }, // y: pi
+ { 10, PAL_POSINF, PAL_POSINF, 0 },
+
+ { PAL_POSINF, PAL_NEGINF, 0, PAL_EPSILON },
+ { PAL_POSINF, PAL_POSINF, PAL_POSINF, 0 },
+ };
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++)
+ {
+ validate(tests[i].x, tests[i].y, tests[i].expected, tests[i].variance);
+ }
+
+ validate_isnan(-10, -1.57079633f); // y: -(pi / 2)
+ validate_isnan(-10, -0.785398163f); // y: -(pi / 4)
+ validate_isnan(-10, 0.785398163f); // y: pi / 4
+ validate_isnan(-10, 1.57079633f); // y: pi / 2
+
+ validate_isnan(-2.71828183f, -1.57079633f); // x: -(e) y: -(pi / 2)
+ validate_isnan(-2.71828183f, -0.785398163f); // x: -(e) y: -(pi / 4)
+ 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);
+
+ validate_isnan(PAL_POSINF, PAL_NAN);
+ validate_isnan(PAL_NAN, PAL_POSINF);
+
+ validate_isnan(PAL_NAN, PAL_NAN);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/powf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/powf/test1/testinfo.dat
new file mode 100644
index 0000000000..778c042025
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/powf/test1/testinfo.dat
@@ -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.
+
+Version = 1.0
+Section = C Runtime
+Function = powf
+Name = Call powf with some std input/output.
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Call the powf function with various num/expfonent pairs
+= that should produce std answers.
+
+
+
+
diff --git a/src/pal/tests/palsuite/c_runtime/printf/printf.h b/src/pal/tests/palsuite/c_runtime/printf/printf.h
index 2eaa984bad..8ef725f305 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/printf.h
+++ b/src/pal/tests/palsuite/c_runtime/printf/printf.h
@@ -14,7 +14,7 @@
#ifndef __printf_H__
#define __printf_H__
-void DoStrTest(char *formatstr, char* param, char *checkstr)
+void DoStrTest(const char *formatstr, char* param, const char *checkstr)
{
int ret;
@@ -26,7 +26,7 @@ void DoStrTest(char *formatstr, char* param, char *checkstr)
}
}
-void DoWStrTest(char *formatstr, WCHAR* param, char *checkstr)
+void DoWStrTest(const char *formatstr, WCHAR* param, const char *checkstr)
{
int ret;
@@ -38,8 +38,8 @@ void DoWStrTest(char *formatstr, WCHAR* param, char *checkstr)
}
}
-void DoPointerTest(char *formatstr, void* param, char* paramstr,
- char *checkstr1)
+void DoPointerTest(const char *formatstr, void* param, char* paramstr,
+ const char *checkstr1)
{
int ret;
@@ -51,7 +51,7 @@ void DoPointerTest(char *formatstr, void* param, char* paramstr,
}
}
-void DoCountTest(char *formatstr, int param, char *checkstr)
+void DoCountTest(const char *formatstr, int param, const char *checkstr)
{
int ret;
int n = -1;
@@ -70,7 +70,7 @@ void DoCountTest(char *formatstr, int param, char *checkstr)
}
}
-void DoShortCountTest(char *formatstr, int param, char *checkstr)
+void DoShortCountTest(const char *formatstr, int param, const char *checkstr)
{
int ret;
short int n = -1;
@@ -90,7 +90,7 @@ void DoShortCountTest(char *formatstr, int param, char *checkstr)
}
-void DoCharTest(char *formatstr, char param, char *checkstr)
+void DoCharTest(const char *formatstr, char param, const char *checkstr)
{
int ret;
@@ -102,7 +102,7 @@ void DoCharTest(char *formatstr, char param, char *checkstr)
}
}
-void DoWCharTest(char *formatstr, WCHAR param, char *checkstr)
+void DoWCharTest(const char *formatstr, WCHAR param, const char *checkstr)
{
int ret;
@@ -114,7 +114,7 @@ void DoWCharTest(char *formatstr, WCHAR param, char *checkstr)
}
}
-void DoNumTest(char *formatstr, int param, char *checkstr)
+void DoNumTest(const char *formatstr, int param, const char *checkstr)
{
int ret;
@@ -126,8 +126,8 @@ void DoNumTest(char *formatstr, int param, char *checkstr)
}
}
-void DoI64Test(char *formatstr, INT64 param, char *valuestr,
- char *checkstr1)
+void DoI64Test(const char *formatstr, INT64 param, char *valuestr,
+ const char *checkstr1)
{
int ret;
@@ -139,8 +139,8 @@ void DoI64Test(char *formatstr, INT64 param, char *valuestr,
}
}
-void DoDoubleTest(char *formatstr, double param,
- char *checkstr1, char *checkstr2)
+void DoDoubleTest(const char *formatstr, double param,
+ const char *checkstr1, const char *checkstr2)
{
int ret;
@@ -152,8 +152,8 @@ void DoDoubleTest(char *formatstr, double param,
}
}
-void DoArgumentPrecTest(char *formatstr, int precision, void *param,
- char *paramstr, char *checkstr1, char *checkstr2)
+void DoArgumentPrecTest(const char *formatstr, int precision, void *param,
+ char *paramstr, const char *checkstr1, const char *checkstr2)
{
int ret;
@@ -165,8 +165,8 @@ void DoArgumentPrecTest(char *formatstr, int precision, void *param,
}
}
-void DoArgumentPrecDoubleTest(char *formatstr, int precision, double param,
- char *checkstr1, char *checkstr2)
+void DoArgumentPrecDoubleTest(const char *formatstr, int precision, double param,
+ const char *checkstr1, const char *checkstr2)
{
int ret;
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/printf/test1/CMakeLists.txt
index bea9151ed7..2dace14f90 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/printf/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_printf_test1
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/printf/test1/test1.cpp
index 31b7014343..31b7014343 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/printf/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test10/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/printf/test10/CMakeLists.txt
index 89ff2e0190..75e30c8599 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test10/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/printf/test10/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test10.c
+ test10.cpp
)
add_executable(paltest_printf_test10
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test10/test10.c b/src/pal/tests/palsuite/c_runtime/printf/test10/test10.cpp
index 5e69175b07..5e69175b07 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test10/test10.c
+++ b/src/pal/tests/palsuite/c_runtime/printf/test10/test10.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test11/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/printf/test11/CMakeLists.txt
index 349f154a8d..4ee12dc21d 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test11/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/printf/test11/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test11.c
+ test11.cpp
)
add_executable(paltest_printf_test11
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test11/test11.c b/src/pal/tests/palsuite/c_runtime/printf/test11/test11.cpp
index 788be8b2db..788be8b2db 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test11/test11.c
+++ b/src/pal/tests/palsuite/c_runtime/printf/test11/test11.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test12/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/printf/test12/CMakeLists.txt
index 0d32ee1690..3b2e39d640 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test12/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/printf/test12/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test12.c
+ test12.cpp
)
add_executable(paltest_printf_test12
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test12/test12.c b/src/pal/tests/palsuite/c_runtime/printf/test12/test12.cpp
index b4006f2405..b4006f2405 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test12/test12.c
+++ b/src/pal/tests/palsuite/c_runtime/printf/test12/test12.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test13/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/printf/test13/CMakeLists.txt
index 348d25b22d..b6af021d48 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test13/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/printf/test13/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test13.c
+ test13.cpp
)
add_executable(paltest_printf_test13
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test13/test13.c b/src/pal/tests/palsuite/c_runtime/printf/test13/test13.cpp
index ccd16b50d2..ccd16b50d2 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test13/test13.c
+++ b/src/pal/tests/palsuite/c_runtime/printf/test13/test13.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test14/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/printf/test14/CMakeLists.txt
index 659ea78cc6..5a6cf8a180 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test14/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/printf/test14/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test14.c
+ test14.cpp
)
add_executable(paltest_printf_test14
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test14/test14.c b/src/pal/tests/palsuite/c_runtime/printf/test14/test14.cpp
index 10577db67d..10577db67d 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test14/test14.c
+++ b/src/pal/tests/palsuite/c_runtime/printf/test14/test14.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test15/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/printf/test15/CMakeLists.txt
index 9e4e310304..b1466a387d 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test15/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/printf/test15/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test15.c
+ test15.cpp
)
add_executable(paltest_printf_test15
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test15/test15.c b/src/pal/tests/palsuite/c_runtime/printf/test15/test15.cpp
index 2acfc436a3..2acfc436a3 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test15/test15.c
+++ b/src/pal/tests/palsuite/c_runtime/printf/test15/test15.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test16/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/printf/test16/CMakeLists.txt
index 7e477a3059..c81da10ec9 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test16/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/printf/test16/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test16.c
+ test16.cpp
)
add_executable(paltest_printf_test16
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test16/test16.c b/src/pal/tests/palsuite/c_runtime/printf/test16/test16.cpp
index 50c952f959..50c952f959 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test16/test16.c
+++ b/src/pal/tests/palsuite/c_runtime/printf/test16/test16.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test17/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/printf/test17/CMakeLists.txt
index c18450c2aa..9d40e54ca6 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test17/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/printf/test17/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test17.c
+ test17.cpp
)
add_executable(paltest_printf_test17
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test17/test17.c b/src/pal/tests/palsuite/c_runtime/printf/test17/test17.cpp
index 96ddd5c1e4..96ddd5c1e4 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test17/test17.c
+++ b/src/pal/tests/palsuite/c_runtime/printf/test17/test17.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test18/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/printf/test18/CMakeLists.txt
index b0468314a3..6ab11f4be1 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test18/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/printf/test18/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test18.c
+ test18.cpp
)
add_executable(paltest_printf_test18
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test18/test18.c b/src/pal/tests/palsuite/c_runtime/printf/test18/test18.cpp
index 6c05e40f42..6c05e40f42 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test18/test18.c
+++ b/src/pal/tests/palsuite/c_runtime/printf/test18/test18.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test19/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/printf/test19/CMakeLists.txt
index efd47563d4..f022938e32 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test19/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/printf/test19/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test19.c
+ test19.cpp
)
add_executable(paltest_printf_test19
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test19/test19.c b/src/pal/tests/palsuite/c_runtime/printf/test19/test19.c
deleted file mode 100644
index 1e09398f7c..0000000000
--- a/src/pal/tests/palsuite/c_runtime/printf/test19/test19.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test19.c
-**
-** Purpose: Test #19 for the printf function. Tests the variable length
-** precision argument.
-**
-**
-**==========================================================================*/
-
-
-#include <palsuite.h>
-#include "../printf.h"
-
-
-
-
-int __cdecl main(int argc, char *argv[])
-{
- int n = -1;
-
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
- DoArgumentPrecTest("%.*s", 2, "bar", "bar", "ba", "ba");
- DoArgumentPrecTest("%.*S", 2, convert("bar"), "bar", "ba", "ba");
-
- DoArgumentPrecTest("%.*n", 3, &n, "pointer to int", "", "");
- if (n != 0)
- {
- Fail("ERROR: Expected count parameter to resolve to %d, got %X\n",
- 0, n);
- }
-
- DoArgumentPrecTest("%.*c", 0, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*c", 4, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*C", 0, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*C", 4, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*d", 1, (void*)42, "42", "42", "42");
- DoArgumentPrecTest("%.*d", 3, (void*)42, "42", "042", "042");
- DoArgumentPrecTest("%.*i", 1, (void*)42, "42", "42", "42");
- DoArgumentPrecTest("%.*i", 3, (void*)42, "42", "042", "042");
- DoArgumentPrecTest("%.*o", 1, (void*)42, "42", "52", "52");
- DoArgumentPrecTest("%.*o", 3, (void*)42, "42", "052", "052");
- DoArgumentPrecTest("%.*u", 1, (void*)42, "42", "42", "42");
- DoArgumentPrecTest("%.*u", 3, (void*)42, "42", "042", "042");
- DoArgumentPrecTest("%.*x", 1, (void*)0x42, "0x42", "42", "42");
- DoArgumentPrecTest("%.*x", 3, (void*)0x42, "0x42", "042", "042");
- DoArgumentPrecTest("%.*X", 1, (void*)0x42, "0x42", "42", "42");
- DoArgumentPrecTest("%.*X", 3, (void*)0x42, "0x42", "042", "042");
-
-
- DoArgumentPrecDoubleTest("%.*e", 1, 2.01, "2.0e+000", "2.0e+00");
- DoArgumentPrecDoubleTest("%.*e", 3, 2.01, "2.010e+000", "2.010e+00");
- DoArgumentPrecDoubleTest("%.*E", 1, 2.01, "2.0E+000", "2.0E+00");
- DoArgumentPrecDoubleTest("%.*E", 3, 2.01, "2.010E+000", "2.010E+00");
- DoArgumentPrecDoubleTest("%.*f", 1, 2.01, "2.0", "2.0");
- DoArgumentPrecDoubleTest("%.*f", 3, 2.01, "2.010", "2.010");
- DoArgumentPrecDoubleTest("%.*g", 1, 256.01, "3e+002", "3e+02");
- DoArgumentPrecDoubleTest("%.*g", 3, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*g", 4, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*g", 6, 256.01, "256.01", "256.01");
- DoArgumentPrecDoubleTest("%.*G", 1, 256.01, "3E+002", "3E+02");
- DoArgumentPrecDoubleTest("%.*G", 3, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*G", 4, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*G", 6, 256.01, "256.01", "256.01");
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test19/test19.cpp b/src/pal/tests/palsuite/c_runtime/printf/test19/test19.cpp
new file mode 100644
index 0000000000..a3ce0e7ad8
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/printf/test19/test19.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test19.c
+**
+** Purpose: Test #19 for the printf function. Tests the variable length
+** precision argument.
+**
+**
+**==========================================================================*/
+
+
+#include <palsuite.h>
+#include "../printf.h"
+
+
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ int n = -1;
+
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ DoArgumentPrecTest("%.*s", 2, (void*)"bar", "bar", "ba", "ba");
+ DoArgumentPrecTest("%.*S", 2, (void*)convert("bar"), "bar", "ba", "ba");
+
+ DoArgumentPrecTest("%.*n", 3, (void*)&n, "pointer to int", "", "");
+ if (n != 0)
+ {
+ Fail("ERROR: Expected count parameter to resolve to %d, got %X\n",
+ 0, n);
+ }
+
+ DoArgumentPrecTest("%.*c", 0, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*c", 4, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*C", 0, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*C", 4, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*d", 1, (void*)42, "42", "42", "42");
+ DoArgumentPrecTest("%.*d", 3, (void*)42, "42", "042", "042");
+ DoArgumentPrecTest("%.*i", 1, (void*)42, "42", "42", "42");
+ DoArgumentPrecTest("%.*i", 3, (void*)42, "42", "042", "042");
+ DoArgumentPrecTest("%.*o", 1, (void*)42, "42", "52", "52");
+ DoArgumentPrecTest("%.*o", 3, (void*)42, "42", "052", "052");
+ DoArgumentPrecTest("%.*u", 1, (void*)42, "42", "42", "42");
+ DoArgumentPrecTest("%.*u", 3, (void*)42, "42", "042", "042");
+ DoArgumentPrecTest("%.*x", 1, (void*)0x42, "0x42", "42", "42");
+ DoArgumentPrecTest("%.*x", 3, (void*)0x42, "0x42", "042", "042");
+ DoArgumentPrecTest("%.*X", 1, (void*)0x42, "0x42", "42", "42");
+ DoArgumentPrecTest("%.*X", 3, (void*)0x42, "0x42", "042", "042");
+
+
+ DoArgumentPrecDoubleTest("%.*e", 1, 2.01, "2.0e+000", "2.0e+00");
+ DoArgumentPrecDoubleTest("%.*e", 3, 2.01, "2.010e+000", "2.010e+00");
+ DoArgumentPrecDoubleTest("%.*E", 1, 2.01, "2.0E+000", "2.0E+00");
+ DoArgumentPrecDoubleTest("%.*E", 3, 2.01, "2.010E+000", "2.010E+00");
+ DoArgumentPrecDoubleTest("%.*f", 1, 2.01, "2.0", "2.0");
+ DoArgumentPrecDoubleTest("%.*f", 3, 2.01, "2.010", "2.010");
+ DoArgumentPrecDoubleTest("%.*g", 1, 256.01, "3e+002", "3e+02");
+ DoArgumentPrecDoubleTest("%.*g", 3, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*g", 4, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*g", 6, 256.01, "256.01", "256.01");
+ DoArgumentPrecDoubleTest("%.*G", 1, 256.01, "3E+002", "3E+02");
+ DoArgumentPrecDoubleTest("%.*G", 3, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*G", 4, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*G", 6, 256.01, "256.01", "256.01");
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/printf/test2/CMakeLists.txt
index c303a69134..e92b6b09f3 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/printf/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_printf_test2
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test2/test2.c b/src/pal/tests/palsuite/c_runtime/printf/test2/test2.cpp
index e766ef4a90..e766ef4a90 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/printf/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/printf/test3/CMakeLists.txt
index 8bc7479797..fcfd779a0c 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/printf/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_printf_test3
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test3/test3.c b/src/pal/tests/palsuite/c_runtime/printf/test3/test3.cpp
index 5cc530948c..5cc530948c 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test3/test3.c
+++ b/src/pal/tests/palsuite/c_runtime/printf/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test4/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/printf/test4/CMakeLists.txt
index 55e5700fe3..7311bbea69 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/printf/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_printf_test4
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test4/test4.c b/src/pal/tests/palsuite/c_runtime/printf/test4/test4.cpp
index bcdc201d4f..bcdc201d4f 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test4/test4.c
+++ b/src/pal/tests/palsuite/c_runtime/printf/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test5/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/printf/test5/CMakeLists.txt
index d091bca2dc..bfe185c44f 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/printf/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_printf_test5
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test5/test5.c b/src/pal/tests/palsuite/c_runtime/printf/test5/test5.cpp
index 9f8baa74da..9f8baa74da 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test5/test5.c
+++ b/src/pal/tests/palsuite/c_runtime/printf/test5/test5.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test6/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/printf/test6/CMakeLists.txt
index c004e353e9..842ebfedc6 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/printf/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test6.c
+ test6.cpp
)
add_executable(paltest_printf_test6
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test6/test6.c b/src/pal/tests/palsuite/c_runtime/printf/test6/test6.cpp
index edc65b6b9b..edc65b6b9b 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test6/test6.c
+++ b/src/pal/tests/palsuite/c_runtime/printf/test6/test6.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test7/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/printf/test7/CMakeLists.txt
index ff6b647ccd..16e39198ba 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test7/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/printf/test7/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test7.c
+ test7.cpp
)
add_executable(paltest_printf_test7
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test7/test7.c b/src/pal/tests/palsuite/c_runtime/printf/test7/test7.cpp
index 3aeb58f7dc..3aeb58f7dc 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test7/test7.c
+++ b/src/pal/tests/palsuite/c_runtime/printf/test7/test7.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test8/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/printf/test8/CMakeLists.txt
index 5ee387f5b8..4a40fee6d9 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test8/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/printf/test8/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test8.c
+ test8.cpp
)
add_executable(paltest_printf_test8
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test8/test8.c b/src/pal/tests/palsuite/c_runtime/printf/test8/test8.cpp
index daa4674b92..daa4674b92 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test8/test8.c
+++ b/src/pal/tests/palsuite/c_runtime/printf/test8/test8.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test9/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/printf/test9/CMakeLists.txt
index baf46c1065..df8f75d2fd 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test9/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/printf/test9/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test9.c
+ test9.cpp
)
add_executable(paltest_printf_test9
diff --git a/src/pal/tests/palsuite/c_runtime/printf/test9/test9.c b/src/pal/tests/palsuite/c_runtime/printf/test9/test9.cpp
index 22c60d04f2..22c60d04f2 100644
--- a/src/pal/tests/palsuite/c_runtime/printf/test9/test9.c
+++ b/src/pal/tests/palsuite/c_runtime/printf/test9/test9.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/qsort/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/qsort/test1/CMakeLists.txt
index 105a727e91..ff215b8dc6 100644
--- a/src/pal/tests/palsuite/c_runtime/qsort/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/qsort/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_qsort_test1
diff --git a/src/pal/tests/palsuite/c_runtime/qsort/test1/test1.c b/src/pal/tests/palsuite/c_runtime/qsort/test1/test1.cpp
index c65fb18e68..c65fb18e68 100644
--- a/src/pal/tests/palsuite/c_runtime/qsort/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/qsort/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/qsort/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/qsort/test2/CMakeLists.txt
index 09e3f6db1e..cdd9642779 100644
--- a/src/pal/tests/palsuite/c_runtime/qsort/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/qsort/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_qsort_test2
diff --git a/src/pal/tests/palsuite/c_runtime/qsort/test2/test2.c b/src/pal/tests/palsuite/c_runtime/qsort/test2/test2.cpp
index 8110dcd2c2..8110dcd2c2 100644
--- a/src/pal/tests/palsuite/c_runtime/qsort/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/qsort/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/rand_srand/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/rand_srand/test1/CMakeLists.txt
index 939914662a..6728f402ff 100644
--- a/src/pal/tests/palsuite/c_runtime/rand_srand/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/rand_srand/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_rand_srand_test1
diff --git a/src/pal/tests/palsuite/c_runtime/rand_srand/test1/test1.c b/src/pal/tests/palsuite/c_runtime/rand_srand/test1/test1.cpp
index 34154cb6d2..34154cb6d2 100644
--- a/src/pal/tests/palsuite/c_runtime/rand_srand/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/rand_srand/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/realloc/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/realloc/test1/CMakeLists.txt
index 0a9f34fc3b..62830a0fe8 100644
--- a/src/pal/tests/palsuite/c_runtime/realloc/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/realloc/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_realloc_test1
diff --git a/src/pal/tests/palsuite/c_runtime/realloc/test1/test1.c b/src/pal/tests/palsuite/c_runtime/realloc/test1/test1.c
deleted file mode 100644
index d0dd128cc1..0000000000
--- a/src/pal/tests/palsuite/c_runtime/realloc/test1/test1.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test1.c
-**
-** Purpose: Uses realloc to allocate and realloate memory, checking
-** that memory contents are copied when the memory is reallocated.
-**
-**
-**==========================================================================*/
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char **argv)
-{
- char *testA;
- const int len1 = 10;
- const char str1[] = "aaaaaaaaaa";
-
- const int len2 = 20;
- const char str2[] = "bbbbbbbbbbbbbbbbbbbb";
-
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
- /* this should work like malloc */
- testA = (char *)realloc(NULL, len1*sizeof(char));
- memcpy(testA, str1, len1);
- if (testA == NULL)
- {
- Fail("We ran out of memory (unlikely), or realloc is broken.\n");
- }
-
- if (memcmp(testA, str1, len1) != 0)
- {
- Fail("realloc doesn't properly allocate new memory.\n");
- }
-
- testA = (char *)realloc(testA, len2*sizeof(char));
- if (memcmp(testA, str1, len1) != 0)
- {
- Fail("realloc doesn't move the contents of the original memory "
- "block to the newly allocated block.\n");
- }
-
- memcpy(testA, str2, len2);
- if (memcmp(testA, str2, len2) != 0)
- {
- Fail("Couldn't write to memory allocated by realloc.\n");
- }
-
- /* free the buffer */
- testA = realloc(testA, 0);
- if (testA != NULL)
- {
- Fail("Realloc didn't return NULL when called with a length "
- "of zero.\n");
- }
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/realloc/test1/test1.cpp b/src/pal/tests/palsuite/c_runtime/realloc/test1/test1.cpp
new file mode 100644
index 0000000000..64a9270eab
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/realloc/test1/test1.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test1.c
+**
+** Purpose: Uses realloc to allocate and realloate memory, checking
+** that memory contents are copied when the memory is reallocated.
+**
+**
+**==========================================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char **argv)
+{
+ char *testA;
+ const int len1 = 10;
+ const char str1[] = "aaaaaaaaaa";
+
+ const int len2 = 20;
+ const char str2[] = "bbbbbbbbbbbbbbbbbbbb";
+
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ /* this should work like malloc */
+ testA = (char *)realloc(NULL, len1*sizeof(char));
+ memcpy(testA, str1, len1);
+ if (testA == NULL)
+ {
+ Fail("We ran out of memory (unlikely), or realloc is broken.\n");
+ }
+
+ if (memcmp(testA, str1, len1) != 0)
+ {
+ Fail("realloc doesn't properly allocate new memory.\n");
+ }
+
+ testA = (char *)realloc(testA, len2*sizeof(char));
+ if (memcmp(testA, str1, len1) != 0)
+ {
+ Fail("realloc doesn't move the contents of the original memory "
+ "block to the newly allocated block.\n");
+ }
+
+ memcpy(testA, str2, len2);
+ if (memcmp(testA, str2, len2) != 0)
+ {
+ Fail("Couldn't write to memory allocated by realloc.\n");
+ }
+
+ /* free the buffer */
+ testA = (char*)realloc(testA, 0);
+ if (testA != NULL)
+ {
+ Fail("Realloc didn't return NULL when called with a length "
+ "of zero.\n");
+ }
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sin/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sin/test1/CMakeLists.txt
index e074337452..74a0e78f52 100644
--- a/src/pal/tests/palsuite/c_runtime/sin/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/sin/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_sin_test1
diff --git a/src/pal/tests/palsuite/c_runtime/sin/test1/test1.c b/src/pal/tests/palsuite/c_runtime/sin/test1/test1.cpp
index bec58d4dd9..bec58d4dd9 100644
--- a/src/pal/tests/palsuite/c_runtime/sin/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/sin/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/sinf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sinf/CMakeLists.txt
new file mode 100644
index 0000000000..5e1ef7f28b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sinf/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/sinf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sinf/test1/CMakeLists.txt
new file mode 100644
index 0000000000..0651b43d1d
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sinf/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.c
+)
+
+add_executable(paltest_sinf_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sinf_test1 coreclrpal)
+
+target_link_libraries(paltest_sinf_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sinf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/sinf/test1/test1.c
new file mode 100644
index 0000000000..d5bd248935
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sinf/test1/test1.c
@@ -0,0 +1,130 @@
+// Licensed to the .NET Foundation under one or more 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: test1.c
+**
+** Purpose: Test to ensure that sinf return the correct values
+**
+** Dependencies: PAL_Initialize
+** PAL_Terminate
+** Fail
+** fabs
+**
+**===========================================================================*/
+
+#include <palsuite.h>
+
+// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this
+// is slightly too accurate when writing tests meant to run against libm implementations
+// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get.
+//
+// The tests themselves will take PAL_EPSILON and adjust it according to the expected result
+// so that the delta used for comparison will compare the most significant digits and ignore
+// any digits that are outside the double precision range (6-9 digits).
+
+// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON
+// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use
+// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10.
+#define PAL_EPSILON 4.76837158e-07
+
+#define PAL_NAN sqrtf(-1.0f)
+#define PAL_POSINF -logf(0.0f)
+#define PAL_NEGINF logf(0.0f)
+
+/**
+ * Helper test structure
+ */
+struct test
+{
+ float value; /* value to test the function with */
+ float expected; /* expected result */
+ float variance; /* maximum delta between the expected and actual result */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl validate(float value, float expected, float variance)
+{
+ float result = sinf(value);
+
+ /*
+ * The test is valid when the difference between result
+ * and expected is less than or equal to variance
+ */
+ float delta = fabsf(result - expected);
+
+ if (delta > variance)
+ {
+ Fail("sinf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, expected);
+ }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl validate_isnan(float value)
+{
+ float result = sinf(value);
+
+ if (!_isnanf(result))
+ {
+ Fail("sinf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, PAL_NAN);
+ }
+}
+
+/**
+ * main
+ *
+ * executable entry point
+ */
+int __cdecl main(int argc, char **argv)
+{
+ struct test tests[] =
+ {
+ /* value expected variance */
+ { 0, 0, PAL_EPSILON },
+ { 0.318309886f, 0.312961796f, PAL_EPSILON }, // value: 1 / pi
+ { 0.434294482f, 0.420770483f, PAL_EPSILON }, // value: log10f(e)
+ { 0.636619772f, 0.594480769f, PAL_EPSILON }, // value: 2 / pi
+ { 0.693147181f, 0.638961276f, PAL_EPSILON }, // value: ln(2)
+ { 0.707106781f, 0.649636939f, PAL_EPSILON }, // value: 1 / sqrtf(2)
+ { 0.785398163f, 0.707106781f, PAL_EPSILON }, // value: pi / 4, expected: 1 / sqrtf(2)
+ { 1, 0.841470985f, PAL_EPSILON },
+ { 1.12837917f, 0.903719457f, PAL_EPSILON }, // value: 2 / sqrtf(pi)
+ { 1.41421356f, 0.987765946f, PAL_EPSILON }, // value: sqrtf(2)
+ { 1.44269504f, 0.991806244f, PAL_EPSILON }, // value: logf2(e)
+ { 1.57079633f, 1, PAL_EPSILON * 10 }, // value: pi / 2
+ { 2.30258509f, 0.743980337f, PAL_EPSILON }, // value: ln(10)
+ { 2.71828183f, 0.410781291f, PAL_EPSILON }, // value: e
+ { 3.14159265f, 0, PAL_EPSILON }, // value: pi
+ };
+
+ /* PAL initialization */
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++)
+ {
+ validate( tests[i].value, tests[i].expected, tests[i].variance);
+ validate(-tests[i].value, -tests[i].expected, tests[i].variance);
+ }
+
+ validate_isnan(PAL_NEGINF);
+ validate_isnan(PAL_NAN);
+ validate_isnan(PAL_POSINF);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sinf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sinf/test1/testinfo.dat
new file mode 100644
index 0000000000..08ff6026cb
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sinf/test1/testinfo.dat
@@ -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.
+
+Version = 1.0
+Section = C Runtime
+Function = sinf
+Name = Positive Test for sinf
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Passes to sinf() a series of angle value, checking that
+= each one return to correct value.
diff --git a/src/pal/tests/palsuite/c_runtime/sinh/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sinh/test1/CMakeLists.txt
index 66cc691d92..b0101ba808 100644
--- a/src/pal/tests/palsuite/c_runtime/sinh/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/sinh/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_sinh_test1
diff --git a/src/pal/tests/palsuite/c_runtime/sinh/test1/test1.c b/src/pal/tests/palsuite/c_runtime/sinh/test1/test1.cpp
index e790b16fb4..e790b16fb4 100644
--- a/src/pal/tests/palsuite/c_runtime/sinh/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/sinh/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/sinhf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sinhf/CMakeLists.txt
new file mode 100644
index 0000000000..5e1ef7f28b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sinhf/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/sinhf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sinhf/test1/CMakeLists.txt
new file mode 100644
index 0000000000..72cce43460
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sinhf/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.c
+)
+
+add_executable(paltest_sinhf_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sinhf_test1 coreclrpal)
+
+target_link_libraries(paltest_sinhf_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sinhf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/sinhf/test1/test1.c
new file mode 100644
index 0000000000..4e706a2f71
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sinhf/test1/test1.c
@@ -0,0 +1,129 @@
+// Licensed to the .NET Foundation under one or more 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: test1.c
+**
+** Purpose: Test to ensure that sinhf return the correct values
+**
+** Dependencies: PAL_Initialize
+** PAL_Terminate
+** Fail
+** fabs
+**
+**===========================================================================*/
+
+#include <palsuite.h>
+
+// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this
+// is slightly too accurate when writing tests meant to run against libm implementations
+// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get.
+//
+// The tests themselves will take PAL_EPSILON and adjust it according to the expected result
+// so that the delta used for comparison will compare the most significant digits and ignore
+// any digits that are outside the double precision range (6-9 digits).
+
+// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON
+// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use
+// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10.
+#define PAL_EPSILON 4.76837158e-07
+
+#define PAL_NAN sqrtf(-1.0f)
+#define PAL_POSINF -logf(0.0f)
+#define PAL_NEGINF logf(0.0f)
+
+/**
+ * Helper test structure
+ */
+struct test
+{
+ float value; /* value to test the function with */
+ float expected; /* expected result */
+ float variance; /* maximum delta between the expected and actual result */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl validate(float value, float expected, float variance)
+{
+ float result = sinhf(value);
+
+ /*
+ * The test is valid when the difference between result
+ * and expected is less than or equal to variance
+ */
+ float delta = fabsf(result - expected);
+
+ if (delta > variance)
+ {
+ Fail("sinhf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, expected);
+ }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl validate_isnan(float value)
+{
+ float result = sinhf(value);
+
+ if (!_isnanf(result))
+ {
+ Fail("sinhf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, PAL_NAN);
+ }
+}
+
+/**
+ * main
+ *
+ * executable entry point
+ */
+int __cdecl main(int argc, char **argv)
+{
+ struct test tests[] =
+ {
+ /* value expected variance */
+ { 0, 0, PAL_EPSILON },
+ { 0.318309886f, 0.323712439f, PAL_EPSILON }, // value: 1 / pi
+ { 0.434294482f, 0.448075979f, PAL_EPSILON }, // value: log10f(e)
+ { 0.636619772f, 0.680501678f, PAL_EPSILON }, // value: 2 / pi
+ { 0.693147181f, 0.75, PAL_EPSILON }, // value: ln(2)
+ { 0.707106781f, 0.767523145f, PAL_EPSILON }, // value: 1 / sqrtf(2)
+ { 0.785398163f, 0.868670961f, PAL_EPSILON }, // value: pi / 4
+ { 1, 1.17520119f, PAL_EPSILON * 10 },
+ { 1.12837917f, 1.38354288f, PAL_EPSILON * 10 }, // value: 2 / sqrtf(pi)
+ { 1.41421356f, 1.93506682f, PAL_EPSILON * 10 }, // value: sqrtf(2)
+ { 1.44269504f, 1.99789801f, PAL_EPSILON * 10 }, // value: logf2(e)
+ { 1.57079633f, 2.30129890f, PAL_EPSILON * 10 }, // value: pi / 2
+ { 2.30258509f, 4.95f, PAL_EPSILON * 10 }, // value: ln(10)
+ { 2.71828183f, 7.54413710f, PAL_EPSILON * 10 }, // value: e
+ { 3.14159265f, 11.5487394f, PAL_EPSILON * 100 }, // value: pi
+ { PAL_POSINF, PAL_POSINF, 0 },
+ };
+
+ /* PAL initialization */
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++)
+ {
+ validate( tests[i].value, tests[i].expected, tests[i].variance);
+ validate(-tests[i].value, -tests[i].expected, tests[i].variance);
+ }
+
+ validate_isnan(PAL_NAN);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sinhf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sinhf/test1/testinfo.dat
new file mode 100644
index 0000000000..cfb27f5427
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sinhf/test1/testinfo.dat
@@ -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.
+
+Version = 1.0
+Section = C Runtime
+Function = sinhf
+Name = Positive Test for sinhf
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Passes to sinhf() a series of angle value, checking that
+= each one return to correct value.
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf/CMakeLists.txt
deleted file mode 100644
index cafb9536b0..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/CMakeLists.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-add_subdirectory(test1)
-add_subdirectory(test10)
-add_subdirectory(test11)
-add_subdirectory(test12)
-add_subdirectory(test13)
-add_subdirectory(test14)
-add_subdirectory(test15)
-add_subdirectory(test16)
-add_subdirectory(test17)
-add_subdirectory(test18)
-add_subdirectory(test19)
-add_subdirectory(test2)
-add_subdirectory(test3)
-add_subdirectory(test4)
-add_subdirectory(test5)
-add_subdirectory(test6)
-add_subdirectory(test7)
-add_subdirectory(test8)
-add_subdirectory(test9)
-
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/sprintf.h b/src/pal/tests/palsuite/c_runtime/sprintf/sprintf.h
deleted file mode 100644
index 411ae66d54..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/sprintf.h
+++ /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.
-
-/*============================================================================
-**
-** Source: sprintf.h
-**
-** Purpose: Containts common testing functions for sprintf
-**
-**
-**==========================================================================*/
-
-#ifndef __SPRINTF_H__
-#define __SPRINTF_H__
-
-void DoStrTest(char *formatstr, char* param, char *checkstr)
-{
- char buf[256] = { 0 };
-
- sprintf(buf, formatstr, param);
- if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
- {
- Fail("ERROR: failed to insert string \"%s\" into \"%s\"\n"
- "Expected \"%s\" got \"%s\".\n",
- param, formatstr, checkstr, buf);
- }
-}
-
-void DoWStrTest(char *formatstr, WCHAR* param, char *checkstr)
-{
- char buf[256] = { 0 };
-
- sprintf(buf, formatstr, param);
- if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
- {
- Fail("ERROR: failed to insert wide string \"%s\" into \"%s\"\n"
- "Expected \"%s\" got \"%s\".\n",
- convertC(param), formatstr, checkstr, buf);
- }
-}
-
-void DoPointerTest(char *formatstr, void* param, char* paramstr,
- char *checkstr1)
-{
- char buf[256] = { 0 };
-
- sprintf(buf, formatstr, param);
- if (memcmp(buf, checkstr1, strlen(checkstr1) + 1) != 0)
- {
- Fail("ERROR: failed to insert %s into \"%s\"\n"
- "Expected \"%s\" got \"%s\".\n",
- paramstr, formatstr, checkstr1, buf);
- }
-}
-
-void DoCountTest(char *formatstr, int param, char *checkstr)
-{
- char buf[512] = { 0 };
- int n = -1;
-
- sprintf(buf, formatstr, &n);
-
- if (n != param)
- {
- Fail("ERROR: Expected count parameter to resolve to %d, got %X\n",
- param, n);
- }
- if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
- {
- Fail("ERROR: Expected \"%s\" got \"%s\".\n", checkstr, buf);
- }
-}
-
-void DoShortCountTest(char *formatstr, int param, char *checkstr)
-{
- char buf[256] = { 0 };
- short int n = -1;
-
- sprintf(buf, formatstr, &n);
-
- if (n != param)
- {
- Fail("ERROR: Expected count parameter to resolve to %d, got %X\n",
- param, n);
- }
- if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
- {
- Fail("ERROR: Expected \"%s\" got \"%s\".\n", checkstr, buf);
- }
-}
-
-
-void DoCharTest(char *formatstr, char param, char *checkstr)
-{
- char buf[256] = { 0 };
-
- sprintf(buf, formatstr, param);
- if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
- {
- Fail("ERROR: failed to insert char \'%c\' (%d) into \"%s\"\n"
- "Expected \"%s\" got \"%s\".\n",
- param, param, formatstr, checkstr, buf);
- }
-}
-
-void DoWCharTest(char *formatstr, WCHAR param, char *checkstr)
-{
- char buf[256] = { 0 };
-
- sprintf(buf, formatstr, param);
- if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
- {
- Fail("ERROR: failed to insert wide char \'%c\' (%d) into \"%s\"\n"
- "Expected \"%s\" got \"%s\".\n",
- (char)param, param, formatstr, checkstr, buf);
- }
-}
-
-void DoNumTest(char *formatstr, int value, char *checkstr)
-{
- char buf[256] = { 0 };
-
- sprintf(buf, formatstr, value);
- if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
- {
- Fail("ERROR: failed to insert %#x into \"%s\"\n"
- "Expected \"%s\" got \"%s\".\n",
- value, formatstr, checkstr, buf);
- }
-}
-
-void DoI64Test(char *formatstr, INT64 value, char *valuestr, char *checkstr1)
-{
- char buf[256] = { 0 };
-
- sprintf(buf, formatstr, value);
- if (memcmp(buf, checkstr1, strlen(checkstr1) + 1) != 0)
- {
- Fail("ERROR: failed to insert %s into \"%s\"\n"
- "Expected \"%s\", got \"%s\".\n",
- valuestr, formatstr, checkstr1, buf);
- }
-}
-
-void DoDoubleTest(char *formatstr, double value, char *checkstr1,
- char *checkstr2)
-{
- char buf[256] = { 0 };
-
- sprintf(buf, formatstr, value);
- if (memcmp(buf, checkstr1, strlen(checkstr1) + 1) != 0 &&
- memcmp(buf, checkstr2, strlen(checkstr2) + 1) != 0)
- {
- Fail("ERROR: failed to insert %f into \"%s\"\n"
- "Expected \"%s\" or \"%s\", got \"%s\".\n",
- value, formatstr, checkstr1, checkstr2, buf);
- }
-}
-
-void DoArgumentPrecTest(char *formatstr, int precision, void *param,
- char *paramstr, char *checkstr1, char *checkstr2)
-{
- char buf[256];
-
- sprintf(buf, formatstr, precision, param);
- if (memcmp(buf, checkstr1, strlen(checkstr1) + 1) != 0 &&
- memcmp(buf, checkstr2, strlen(checkstr2) + 1) != 0)
- {
- Fail("ERROR: failed to insert %s into \"%s\" with precision %d\n"
- "Expected \"%s\" or \"%s\", got \"%s\".\n", paramstr, formatstr,
- precision, checkstr1, checkstr2, buf);
- }
-
-}
-
-void DoArgumentPrecDoubleTest(char *formatstr, int precision, double param,
- char *checkstr1, char *checkstr2)
-{
- char buf[256];
-
- sprintf(buf, formatstr, precision, param);
- if (memcmp(buf, checkstr1, strlen(checkstr1) + 1) != 0 &&
- memcmp(buf, checkstr2, strlen(checkstr2) + 1) != 0)
- {
- Fail("ERROR: failed to insert %f into \"%s\" with precision %d\n"
- "Expected \"%s\" or \"%s\", got \"%s\".\n", param, formatstr,
- precision, checkstr1, checkstr2, buf);
- }
-
-}
-
-#endif
-
-
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf/test1/CMakeLists.txt
deleted file mode 100644
index bdec045af9..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test1/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test1.c
-)
-
-add_executable(paltest_sprintf_test1
- ${SOURCES}
-)
-
-add_dependencies(paltest_sprintf_test1 coreclrpal)
-
-target_link_libraries(paltest_sprintf_test1
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/sprintf/test1/test1.c
deleted file mode 100644
index 42e27f263b..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test1/test1.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test1.c
-**
-** Purpose: Test #1 for the sprintf function. A single, basic, test
-** case with no formatting.
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sprintf.h"
-
-/*
- * Depends on memcmp and strlen
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- char checkstr[] = "hello world";
- char buf[256];
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- sprintf(buf, "hello world");
-
- if (memcmp(checkstr, buf, strlen(checkstr)+1) != 0)
- {
- Fail("ERROR: expected %s, got %s\n", checkstr, buf);
- }
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf/test1/testinfo.dat
deleted file mode 100644
index abe07445cc..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test1/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sprintf
-Name = Positive Test for sprintf
-TYPE = DEFAULT
-EXE1 = test1
-Description
-= General test to see if sprintf works correctly
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test10/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf/test10/CMakeLists.txt
deleted file mode 100644
index 91e9db8ccc..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test10/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test10.c
-)
-
-add_executable(paltest_sprintf_test10
- ${SOURCES}
-)
-
-add_dependencies(paltest_sprintf_test10 coreclrpal)
-
-target_link_libraries(paltest_sprintf_test10
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test10/test10.c b/src/pal/tests/palsuite/c_runtime/sprintf/test10/test10.c
deleted file mode 100644
index ae7dbfb177..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test10/test10.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test10.c
-**
-** Purpose: Test #10 for the sprintf function. Tests the octal specifier
-** (%o).
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sprintf.h"
-
-/*
- * Depends on memcmp and strlen
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- int neg = -42;
- int pos = 42;
- INT64 l = 42;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoNumTest("foo %o", pos, "foo 52");
- DoNumTest("foo %lo", 0xFFFF, "foo 177777");
- DoNumTest("foo %ho", 0xFFFF, "foo 177777");
- DoNumTest("foo %Lo", pos, "foo 52");
- DoI64Test("foo %I64o", l, "42", "foo 52");
- DoNumTest("foo %3o", pos, "foo 52");
- DoNumTest("foo %-3o", pos, "foo 52 ");
- DoNumTest("foo %.1o", pos, "foo 52");
- DoNumTest("foo %.3o", pos, "foo 052");
- DoNumTest("foo %03o", pos, "foo 052");
- DoNumTest("foo %#o", pos, "foo 052");
- DoNumTest("foo %+o", pos, "foo 52");
- DoNumTest("foo % o", pos, "foo 52");
- DoNumTest("foo %+o", neg, "foo 37777777726");
- DoNumTest("foo % o", neg, "foo 37777777726");
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test10/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf/test10/testinfo.dat
deleted file mode 100644
index 70b7f3ab75..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test10/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sprintf
-Name = Positive Test for sprintf
-TYPE = DEFAULT
-EXE1 = test10
-Description
-= Tests sprintf with octal numbers
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test11/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf/test11/CMakeLists.txt
deleted file mode 100644
index b14c8be04d..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test11/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test11.c
-)
-
-add_executable(paltest_sprintf_test11
- ${SOURCES}
-)
-
-add_dependencies(paltest_sprintf_test11 coreclrpal)
-
-target_link_libraries(paltest_sprintf_test11
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test11/test11.c b/src/pal/tests/palsuite/c_runtime/sprintf/test11/test11.c
deleted file mode 100644
index 0b5b5ab93d..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test11/test11.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test11.c
-**
-** Purpose: Test #11 for the sprintf function. Test the unsigned int
-** specifier (%u).
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sprintf.h"
-
-/*
- * Depends on memcmp and strlen
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- int neg = -42;
- int pos = 42;
- INT64 l = 42;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoNumTest("foo %u", pos, "foo 42");
- DoNumTest("foo %lu", 0xFFFF, "foo 65535");
- DoNumTest("foo %hu", 0xFFFF, "foo 65535");
- DoNumTest("foo %Lu", pos, "foo 42");
- DoI64Test("foo %I64u", l, "42", "foo 42");
- DoNumTest("foo %3u", pos, "foo 42");
- DoNumTest("foo %-3u", pos, "foo 42 ");
- DoNumTest("foo %.1u", pos, "foo 42");
- DoNumTest("foo %.3u", pos, "foo 042");
- DoNumTest("foo %03u", pos, "foo 042");
- DoNumTest("foo %#u", pos, "foo 42");
- DoNumTest("foo %+u", pos, "foo 42");
- DoNumTest("foo % u", pos, "foo 42");
- DoNumTest("foo %+u", neg, "foo 4294967254");
- DoNumTest("foo % u", neg, "foo 4294967254");
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test11/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf/test11/testinfo.dat
deleted file mode 100644
index 852bd3e7b6..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test11/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sprintf
-Name = Positive Test for sprintf
-TYPE = DEFAULT
-EXE1 = test11
-Description
-= Tests sprintf with unsigned numbers
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test12/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf/test12/CMakeLists.txt
deleted file mode 100644
index 1e517495bd..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test12/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test12.c
-)
-
-add_executable(paltest_sprintf_test12
- ${SOURCES}
-)
-
-add_dependencies(paltest_sprintf_test12 coreclrpal)
-
-target_link_libraries(paltest_sprintf_test12
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test12/test12.c b/src/pal/tests/palsuite/c_runtime/sprintf/test12/test12.c
deleted file mode 100644
index c2e778e494..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test12/test12.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test12.c
-**
-** Purpose: Test #12 for the sprintf function. Tests the (lowercase)
-** hexadecimal specifier (%x)
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sprintf.h"
-
-/*
- * Depends on memcmp and strlen
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- int neg = -42;
- int pos = 0x1234ab;
- INT64 l = I64(0x1234567887654321);
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoNumTest("foo %x", pos, "foo 1234ab");
- DoNumTest("foo %lx", pos, "foo 1234ab");
- DoNumTest("foo %hx", pos, "foo 34ab");
- DoNumTest("foo %Lx", pos, "foo 1234ab");
- DoI64Test("foo %I64x", l, "0x1234567887654321",
- "foo 1234567887654321");
- DoNumTest("foo %7x", pos, "foo 1234ab");
- DoNumTest("foo %-7x", pos, "foo 1234ab ");
- DoNumTest("foo %.1x", pos, "foo 1234ab");
- DoNumTest("foo %.7x", pos, "foo 01234ab");
- DoNumTest("foo %07x", pos, "foo 01234ab");
- DoNumTest("foo %#x", pos, "foo 0x1234ab");
- DoNumTest("foo %+x", pos, "foo 1234ab");
- DoNumTest("foo % x", pos, "foo 1234ab");
- DoNumTest("foo %+x", neg, "foo ffffffd6");
- DoNumTest("foo % x", neg, "foo ffffffd6");
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test12/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf/test12/testinfo.dat
deleted file mode 100644
index 5df91d0e6a..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test12/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sprintf
-Name = Positive Test for sprintf
-TYPE = DEFAULT
-EXE1 = test12
-Description
-= Tests sprintf with hex numbers (lowercase)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test13/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf/test13/CMakeLists.txt
deleted file mode 100644
index 25b033fe82..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test13/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test13.c
-)
-
-add_executable(paltest_sprintf_test13
- ${SOURCES}
-)
-
-add_dependencies(paltest_sprintf_test13 coreclrpal)
-
-target_link_libraries(paltest_sprintf_test13
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test13/test13.c b/src/pal/tests/palsuite/c_runtime/sprintf/test13/test13.c
deleted file mode 100644
index 0b4b7ed9ae..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test13/test13.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test13.c
-**
-** Purpose: Test #13 for the sprintf function. Tests the (uppercase)
-** hexadecimal specifier (%X)
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sprintf.h"
-
-/*
- * Depends on memcmp and strlen
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- int neg = -42;
- int pos = 0x1234AB;
- INT64 l = I64(0x1234567887654321);
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoNumTest("foo %X", pos, "foo 1234AB");
- DoNumTest("foo %lX", pos, "foo 1234AB");
- DoNumTest("foo %hX", pos, "foo 34AB");
- DoNumTest("foo %LX", pos, "foo 1234AB");
- DoI64Test("foo %I64X", l, "0x1234567887654321",
- "foo 1234567887654321");
- DoNumTest("foo %7X", pos, "foo 1234AB");
- DoNumTest("foo %-7X", pos, "foo 1234AB ");
- DoNumTest("foo %.1X", pos, "foo 1234AB");
- DoNumTest("foo %.7X", pos, "foo 01234AB");
- DoNumTest("foo %07X", pos, "foo 01234AB");
- DoNumTest("foo %#X", pos, "foo 0X1234AB");
- DoNumTest("foo %+X", pos, "foo 1234AB");
- DoNumTest("foo % X", pos, "foo 1234AB");
- DoNumTest("foo %+X", neg, "foo FFFFFFD6");
- DoNumTest("foo % X", neg, "foo FFFFFFD6");
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test13/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf/test13/testinfo.dat
deleted file mode 100644
index 634817a791..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test13/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sprintf
-Name = Positive Test for sprintf
-TYPE = DEFAULT
-EXE1 = test13
-Description
-= Tests sprintf with hex numbers (uppercase)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test14/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf/test14/CMakeLists.txt
deleted file mode 100644
index 5eae306e16..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test14/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test14.c
-)
-
-add_executable(paltest_sprintf_test14
- ${SOURCES}
-)
-
-add_dependencies(paltest_sprintf_test14 coreclrpal)
-
-target_link_libraries(paltest_sprintf_test14
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test14/test14.c b/src/pal/tests/palsuite/c_runtime/sprintf/test14/test14.c
deleted file mode 100644
index 20e986a9c3..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test14/test14.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test14.c
-**
-** Purpose: Test #14 for the sprintf function. Tests the lowercase
-** exponential notation double specifier (%e)
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sprintf.h"
-
-/*
- * Depends on memcmp and strlen
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- double val = 256.0;
- double neg = -256.0;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoDoubleTest("foo %e", val, "foo 2.560000e+002", "foo 2.560000e+02");
- DoDoubleTest("foo %le", val, "foo 2.560000e+002", "foo 2.560000e+02");
- DoDoubleTest("foo %he", val, "foo 2.560000e+002", "foo 2.560000e+02");
- DoDoubleTest("foo %Le", val, "foo 2.560000e+002", "foo 2.560000e+02");
- DoDoubleTest("foo %I64e", val, "foo 2.560000e+002", "foo 2.560000e+02");
- DoDoubleTest("foo %14e", val, "foo 2.560000e+002", "foo 2.560000e+02");
- DoDoubleTest("foo %-14e", val, "foo 2.560000e+002 ", "foo 2.560000e+02 ");
- DoDoubleTest("foo %.1e", val, "foo 2.6e+002", "foo 2.6e+02");
- DoDoubleTest("foo %.8e", val, "foo 2.56000000e+002", "foo 2.56000000e+02");
- DoDoubleTest("foo %014e", val, "foo 02.560000e+002", "foo 002.560000e+02");
- DoDoubleTest("foo %#e", val, "foo 2.560000e+002", "foo 2.560000e+02");
- DoDoubleTest("foo %+e", val, "foo +2.560000e+002", "foo +2.560000e+02");
- DoDoubleTest("foo % e", val, "foo 2.560000e+002", "foo 2.560000e+02");
- DoDoubleTest("foo %+e", neg, "foo -2.560000e+002", "foo -2.560000e+02");
- DoDoubleTest("foo % e", neg, "foo -2.560000e+002", "foo -2.560000e+02");
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test14/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf/test14/testinfo.dat
deleted file mode 100644
index c7086efdbc..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test14/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sprintf
-Name = Positive Test for sprintf
-TYPE = DEFAULT
-EXE1 = test14
-Description
-= Tests sprintf with exponential format doubles (lowercase)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test15/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf/test15/CMakeLists.txt
deleted file mode 100644
index 1fff23fc89..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test15/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test15.c
-)
-
-add_executable(paltest_sprintf_test15
- ${SOURCES}
-)
-
-add_dependencies(paltest_sprintf_test15 coreclrpal)
-
-target_link_libraries(paltest_sprintf_test15
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test15/test15.c b/src/pal/tests/palsuite/c_runtime/sprintf/test15/test15.c
deleted file mode 100644
index 34199b2eb3..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test15/test15.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test15.c
-**
-** Purpose: Test #15 for the sprintf function. Tests the uppercase
-** exponential notation double specifier (%E)
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sprintf.h"
-
-/*
- * Depends on memcmp and strlen
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- double val = 256.0;
- double neg = -256.0;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoDoubleTest("foo %E", val, "foo 2.560000E+002", "foo 2.560000E+02");
- DoDoubleTest("foo %lE", val, "foo 2.560000E+002", "foo 2.560000E+02");
- DoDoubleTest("foo %hE", val, "foo 2.560000E+002", "foo 2.560000E+02");
- DoDoubleTest("foo %LE", val, "foo 2.560000E+002", "foo 2.560000E+02");
- DoDoubleTest("foo %I64E", val, "foo 2.560000E+002", "foo 2.560000E+02");
- DoDoubleTest("foo %14E", val, "foo 2.560000E+002", "foo 2.560000E+02");
- DoDoubleTest("foo %-14E", val, "foo 2.560000E+002 ", "foo 2.560000E+02 ");
- DoDoubleTest("foo %.1E", val, "foo 2.6E+002", "foo 2.6E+02");
- DoDoubleTest("foo %.8E", val, "foo 2.56000000E+002", "foo 2.56000000E+02");
- DoDoubleTest("foo %014E", val, "foo 02.560000E+002", "foo 002.560000E+02");
- DoDoubleTest("foo %#E", val, "foo 2.560000E+002", "foo 2.560000E+02");
- DoDoubleTest("foo %+E", val, "foo +2.560000E+002", "foo +2.560000E+02");
- DoDoubleTest("foo % E", val, "foo 2.560000E+002", "foo 2.560000E+02");
- DoDoubleTest("foo %+E", neg, "foo -2.560000E+002", "foo -2.560000E+02");
- DoDoubleTest("foo % E", neg, "foo -2.560000E+002", "foo -2.560000E+02");
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test15/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf/test15/testinfo.dat
deleted file mode 100644
index 0a47c5321a..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test15/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sprintf
-Name = Positive Test for sprintf
-TYPE = DEFAULT
-EXE1 = test15
-Description
-= Tests sprintf with exponential format doubles (uppercase)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test16/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf/test16/CMakeLists.txt
deleted file mode 100644
index 2065c576d9..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test16/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test16.c
-)
-
-add_executable(paltest_sprintf_test16
- ${SOURCES}
-)
-
-add_dependencies(paltest_sprintf_test16 coreclrpal)
-
-target_link_libraries(paltest_sprintf_test16
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test16/test16.c b/src/pal/tests/palsuite/c_runtime/sprintf/test16/test16.c
deleted file mode 100644
index c93b68bc2d..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test16/test16.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test16.c
-**
-** Purpose: Test #16 for the sprintf function. Tests the decimal notation
-** double specifier (%f)
-**
-**
-**==========================================================================*/
-
-
-#include <palsuite.h>
-#include "../sprintf.h"
-
-/*
- * Depends on memcmp and strlen
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- double val = 2560.001;
- double neg = -2560.001;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoDoubleTest("foo %f", val, "foo 2560.001000", "foo 2560.001000");
- DoDoubleTest("foo %lf", val, "foo 2560.001000", "foo 2560.001000");
- DoDoubleTest("foo %hf", val, "foo 2560.001000", "foo 2560.001000");
- DoDoubleTest("foo %Lf", val, "foo 2560.001000", "foo 2560.001000");
- DoDoubleTest("foo %I64f", val, "foo 2560.001000", "foo 2560.001000");
- DoDoubleTest("foo %12f", val, "foo 2560.001000", "foo 2560.001000");
- DoDoubleTest("foo %-12f", val, "foo 2560.001000 ", "foo 2560.001000 ");
- DoDoubleTest("foo %.1f", val, "foo 2560.0", "foo 2560.0");
- DoDoubleTest("foo %.8f", val, "foo 2560.00100000", "foo 2560.00100000");
- DoDoubleTest("foo %012f", val, "foo 02560.001000", "foo 02560.001000");
- DoDoubleTest("foo %#f", val, "foo 2560.001000", "foo 2560.001000");
- DoDoubleTest("foo %+f", val, "foo +2560.001000", "foo +2560.001000");
- DoDoubleTest("foo % f", val, "foo 2560.001000", "foo 2560.001000");
- DoDoubleTest("foo %+f", neg, "foo -2560.001000", "foo -2560.001000");
- DoDoubleTest("foo % f", neg, "foo -2560.001000", "foo -2560.001000");
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test16/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf/test16/testinfo.dat
deleted file mode 100644
index e18fab1ad8..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test16/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sprintf
-Name = Positive Test for sprintf
-TYPE = DEFAULT
-EXE1 = test16
-Description
-= Tests sprintf with decimal point format doubles
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test17/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf/test17/CMakeLists.txt
deleted file mode 100644
index ce3a8ad048..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test17/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test17.c
-)
-
-add_executable(paltest_sprintf_test17
- ${SOURCES}
-)
-
-add_dependencies(paltest_sprintf_test17 coreclrpal)
-
-target_link_libraries(paltest_sprintf_test17
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test17/test17.c b/src/pal/tests/palsuite/c_runtime/sprintf/test17/test17.c
deleted file mode 100644
index 643215b8f5..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test17/test17.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test17.c
-**
-** Purpose: Test #17 for the sprintf function. Tests the lowercase
-** shorthand notation double specifier (%g)
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sprintf.h"
-
-/*
- * Depends on memcmp and strlen
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- double val = 2560.001;
- double neg = -2560.001;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoDoubleTest("foo %g", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %lg", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %hg", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %Lg", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %I64g", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %5g", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %-5g", val, "foo 2560 ", "foo 2560 ");
- DoDoubleTest("foo %.1g", val, "foo 3e+003", "foo 3e+03");
- DoDoubleTest("foo %.2g", val, "foo 2.6e+003", "foo 2.6e+03");
- DoDoubleTest("foo %.12g", val, "foo 2560.001", "foo 2560.001");
- DoDoubleTest("foo %06g", val, "foo 002560", "foo 002560");
- DoDoubleTest("foo %#g", val, "foo 2560.00", "foo 2560.00");
- DoDoubleTest("foo %+g", val, "foo +2560", "foo +2560");
- DoDoubleTest("foo % g", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %+g", neg, "foo -2560", "foo -2560");
- DoDoubleTest("foo % g", neg, "foo -2560", "foo -2560");
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test17/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf/test17/testinfo.dat
deleted file mode 100644
index a723103e02..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test17/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sprintf
-Name = Positive Test for sprintf
-TYPE = DEFAULT
-EXE1 = test17
-Description
-= Tests sprintf with compact format doubles (lowercase)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test18/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf/test18/CMakeLists.txt
deleted file mode 100644
index 6f69e1c7c2..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test18/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test18.c
-)
-
-add_executable(paltest_sprintf_test18
- ${SOURCES}
-)
-
-add_dependencies(paltest_sprintf_test18 coreclrpal)
-
-target_link_libraries(paltest_sprintf_test18
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test18/test18.c b/src/pal/tests/palsuite/c_runtime/sprintf/test18/test18.c
deleted file mode 100644
index fa88152479..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test18/test18.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test18.c
-**
-** Purpose: Test #18 for the sprintf function. Tests the uppercase
-** shorthand notation double specifier (%G)
-**
-**
-**==========================================================================*/
-
-
-#include <palsuite.h>
-#include "../sprintf.h"
-
-/*
- * Depends on memcmp and strlen
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- double val = 2560.001;
- double neg = -2560.001;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoDoubleTest("foo %G", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %lG", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %hG", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %LG", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %I64G", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %5G", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %-5G", val, "foo 2560 ", "foo 2560 ");
- DoDoubleTest("foo %.1G", val, "foo 3E+003", "foo 3E+03");
- DoDoubleTest("foo %.2G", val, "foo 2.6E+003", "foo 2.6E+03");
- DoDoubleTest("foo %.12G", val, "foo 2560.001", "foo 2560.001");
- DoDoubleTest("foo %06G", val, "foo 002560", "foo 002560");
- DoDoubleTest("foo %#G", val, "foo 2560.00", "foo 2560.00");
- DoDoubleTest("foo %+G", val, "foo +2560", "foo +2560");
- DoDoubleTest("foo % G", val, "foo 2560", "foo 2560");
- DoDoubleTest("foo %+G", neg, "foo -2560", "foo -2560");
- DoDoubleTest("foo % G", neg, "foo -2560", "foo -2560");
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test18/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf/test18/testinfo.dat
deleted file mode 100644
index dfafa4bcf4..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test18/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sprintf
-Name = Positive Test for sprintf
-TYPE = DEFAULT
-EXE1 = test18
-Description
-= Tests sprintf with compact format doubles (uppercase)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test19/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf/test19/CMakeLists.txt
deleted file mode 100644
index a2917b27dc..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test19/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test19.c
-)
-
-add_executable(paltest_sprintf_test19
- ${SOURCES}
-)
-
-add_dependencies(paltest_sprintf_test19 coreclrpal)
-
-target_link_libraries(paltest_sprintf_test19
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test19/test19.c b/src/pal/tests/palsuite/c_runtime/sprintf/test19/test19.c
deleted file mode 100644
index aee731cb74..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test19/test19.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test19.c
-**
-** Purpose: Test #19 for the sprintf function. Tests the variable length
-** precision argument.
-**
-**
-**==========================================================================*/
-
-
-#include <palsuite.h>
-#include "../sprintf.h"
-
-/*
- * Depends on memcmp and strlen
- */
-
-
-int __cdecl main(int argc, char *argv[])
-{
- int n = -1;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
- DoArgumentPrecTest("%.*s", 2, "bar", "bar", "ba", "ba");
- DoArgumentPrecTest("%.*S", 2, convert("bar"), "bar", "ba", "ba");
-
- DoArgumentPrecTest("%.*n", 3, &n, "pointer to int", "", "");
- if (n != 0)
- {
- Fail("ERROR: Expected count parameter to resolve to %d, got %X\n",
- 0, n);
- }
-
- DoArgumentPrecTest("%.*c", 0, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*c", 4, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*C", 0, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*C", 4, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*d", 1, (void*)42, "42", "42", "42");
- DoArgumentPrecTest("%.*d", 3, (void*)42, "42", "042", "042");
- DoArgumentPrecTest("%.*i", 1, (void*)42, "42", "42", "42");
- DoArgumentPrecTest("%.*i", 3, (void*)42, "42", "042", "042");
- DoArgumentPrecTest("%.*o", 1, (void*)42, "42", "52", "52");
- DoArgumentPrecTest("%.*o", 3, (void*)42, "42", "052", "052");
- DoArgumentPrecTest("%.*u", 1, (void*)42, "42", "42", "42");
- DoArgumentPrecTest("%.*u", 3, (void*)42, "42", "042", "042");
- DoArgumentPrecTest("%.*x", 1, (void*)0x42, "0x42", "42", "42");
- DoArgumentPrecTest("%.*x", 3, (void*)0x42, "0x42", "042", "042");
- DoArgumentPrecTest("%.*X", 1, (void*)0x42, "0x42", "42", "42");
- DoArgumentPrecTest("%.*X", 3, (void*)0x42, "0x42", "042", "042");
-
-
- DoArgumentPrecDoubleTest("%.*e", 1, 2.01, "2.0e+000", "2.0e+00");
- DoArgumentPrecDoubleTest("%.*e", 3, 2.01, "2.010e+000", "2.010e+00");
- DoArgumentPrecDoubleTest("%.*E", 1, 2.01, "2.0E+000", "2.0E+00");
- DoArgumentPrecDoubleTest("%.*E", 3, 2.01, "2.010E+000", "2.010E+00");
- DoArgumentPrecDoubleTest("%.*f", 1, 2.01, "2.0", "2.0");
- DoArgumentPrecDoubleTest("%.*f", 3, 2.01, "2.010", "2.010");
- DoArgumentPrecDoubleTest("%.*g", 1, 256.01, "3e+002", "3e+02");
- DoArgumentPrecDoubleTest("%.*g", 3, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*g", 4, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*g", 6, 256.01, "256.01", "256.01");
- DoArgumentPrecDoubleTest("%.*G", 1, 256.01, "3E+002", "3E+02");
- DoArgumentPrecDoubleTest("%.*G", 3, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*G", 4, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*G", 6, 256.01, "256.01", "256.01");
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test19/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf/test19/testinfo.dat
deleted file mode 100644
index ebd13025f6..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test19/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sprintf
-Name = Positive Test for sprintf
-TYPE = DEFAULT
-EXE1 = test19
-Description
-= Tests sprintf with argument specified precision
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf/test2/CMakeLists.txt
deleted file mode 100644
index 8af1c53a30..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test2/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test2.c
-)
-
-add_executable(paltest_sprintf_test2
- ${SOURCES}
-)
-
-add_dependencies(paltest_sprintf_test2 coreclrpal)
-
-target_link_libraries(paltest_sprintf_test2
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test2/test2.c b/src/pal/tests/palsuite/c_runtime/sprintf/test2/test2.c
deleted file mode 100644
index d50679a5a3..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test2/test2.c
+++ /dev/null
@@ -1,47 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: test2.c
-**
-** Purpose: Test #2 for the sprintf function. Tests the string specifier
-** (%s).
-**
-**
-**==========================================================================*/
-
-
-#include <palsuite.h>
-#include "../sprintf.h"
-
-/*
- * Depends on memcmp and strlen
- */
-
-int __cdecl main(int argc, char *argv[])
-{
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoStrTest("foo %s", "bar", "foo bar");
- DoStrTest("foo %hs", "bar", "foo bar");
- DoWStrTest("foo %ls", convert("bar"), "foo bar");
- DoWStrTest("foo %ws", convert("bar"), "foo bar");
- DoStrTest("foo %Ls", "bar", "foo bar");
- DoStrTest("foo %I64s", "bar", "foo bar");
- DoStrTest("foo %5s", "bar", "foo bar");
- DoStrTest("foo %.2s", "bar", "foo ba");
- DoStrTest("foo %5.2s", "bar", "foo ba");
- DoStrTest("foo %-5s", "bar", "foo bar ");
- DoStrTest("foo %05s", "bar", "foo 00bar");
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test2/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf/test2/testinfo.dat
deleted file mode 100644
index e8d0f53ff3..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test2/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sprintf
-Name = Positive Test for sprintf
-TYPE = DEFAULT
-EXE1 = test2
-Description
-= Tests sprintf with strings
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf/test3/CMakeLists.txt
deleted file mode 100644
index b7b7e0a579..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test3/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test3.c
-)
-
-add_executable(paltest_sprintf_test3
- ${SOURCES}
-)
-
-add_dependencies(paltest_sprintf_test3 coreclrpal)
-
-target_link_libraries(paltest_sprintf_test3
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test3/test3.c b/src/pal/tests/palsuite/c_runtime/sprintf/test3/test3.c
deleted file mode 100644
index ae52dbed08..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test3/test3.c
+++ /dev/null
@@ -1,47 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: test3.c
-**
-** Purpose: Test #3 for the sprintf function. Tests the wide string
-** specifier (%S).
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sprintf.h"
-
-/*
- * Depends on memcmp and strlen
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
- DoWStrTest("foo %S", convert("bar"), "foo bar");
- DoStrTest("foo %hS", "bar", "foo bar");
- DoWStrTest("foo %lS", convert("bar"), "foo bar");
- DoWStrTest("foo %wS", convert("bar"), "foo bar");
- DoWStrTest("foo %LS", convert("bar"), "foo bar");
- DoWStrTest("foo %I64S", convert("bar"), "foo bar");
- DoWStrTest("foo %5S", convert("bar"), "foo bar");
- DoWStrTest("foo %.2S", convert("bar"), "foo ba");
- DoWStrTest("foo %5.2S", convert("bar"), "foo ba");
- DoWStrTest("foo %-5S", convert("bar"), "foo bar ");
- DoWStrTest("foo %05S", convert("bar"), "foo 00bar");
-
- PAL_Terminate();
- return PASS;
-}
-
-
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test3/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf/test3/testinfo.dat
deleted file mode 100644
index 12e0a9cfb0..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test3/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sprintf
-Name = Positive Test for sprintf
-TYPE = DEFAULT
-EXE1 = test3
-Description
-= Tests sprintf with wide strings
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test4/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf/test4/CMakeLists.txt
deleted file mode 100644
index 3478867b7c..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test4/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test4.c
-)
-
-add_executable(paltest_sprintf_test4
- ${SOURCES}
-)
-
-add_dependencies(paltest_sprintf_test4 coreclrpal)
-
-target_link_libraries(paltest_sprintf_test4
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test4/test4.c b/src/pal/tests/palsuite/c_runtime/sprintf/test4/test4.c
deleted file mode 100644
index 9660ffaa3a..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test4/test4.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test4.c
-**
-** Purpose: Test #4 for the sprintf function. Tests the pointer
-** specifier (%p).
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sprintf.h"
-/*
- * Depends on memcmp and strlen
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- void *ptr = (void*) 0x123456;
- INT64 lptr = I64(0x1234567887654321);
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-/*
-** Run only on 64 bit platforms
-*/
-#if defined(BIT64) && defined(PLATFORM_UNIX)
- Trace("Testing for 64 Bit Platforms \n");
- DoPointerTest("%p", NULL, "NULL", "0000000000000000");
- DoPointerTest("%p", ptr, "pointer to 0x123456", "0000000000123456");
- DoPointerTest("%17p", ptr, "pointer to 0x123456", " 0000000000123456");
- DoPointerTest("%17p", ptr, "pointer to 0x123456", " 0000000000123456");
- DoPointerTest("%-17p", ptr, "pointer to 0x123456", "0000000000123456 ");
- DoPointerTest("%+p", ptr, "pointer to 0x123456", "0000000000123456");
- DoPointerTest("%#p", ptr, "pointer to 0x123456", "0X0000000000123456");
- DoPointerTest("%lp", ptr, "pointer to 0x123456", "00123456");
- DoPointerTest("%hp", ptr, "pointer to 0x123456", "00003456");
- DoPointerTest("%Lp", ptr, "pointer to 0x123456", "00123456");
- DoI64Test("%I64p", lptr, "pointer to 0x1234567887654321",
- "1234567887654321");
-#else
- Trace("Testing for Non 64 Bit Platforms \n");
- DoPointerTest("%p", NULL, "NULL", "00000000");
- DoPointerTest("%p", ptr, "pointer to 0x123456", "00123456");
- DoPointerTest("%9p", ptr, "pointer to 0x123456", " 00123456");
- DoPointerTest("%09p", ptr, "pointer to 0x123456", " 00123456");
- DoPointerTest("%-9p", ptr, "pointer to 0x123456", "00123456 ");
- DoPointerTest("%+p", ptr, "pointer to 0x123456", "00123456");
- DoPointerTest("%#p", ptr, "pointer to 0x123456", "0X00123456");
- DoPointerTest("%lp", ptr, "pointer to 0x123456", "00123456");
- DoPointerTest("%hp", ptr, "pointer to 0x123456", "00003456");
- DoPointerTest("%Lp", ptr, "pointer to 0x123456", "00123456");
- DoI64Test("%I64p", lptr, "pointer to 0x1234567887654321",
- "1234567887654321");
-#endif
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test4/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf/test4/testinfo.dat
deleted file mode 100644
index bf7236dc32..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test4/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sprintf
-Name = Positive Test for sprintf
-TYPE = DEFAULT
-EXE1 = test4
-Description
-= Tests sprintf with pointers
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test5/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf/test5/CMakeLists.txt
deleted file mode 100644
index dfa7583766..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test5/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test5.c
-)
-
-add_executable(paltest_sprintf_test5
- ${SOURCES}
-)
-
-add_dependencies(paltest_sprintf_test5 coreclrpal)
-
-target_link_libraries(paltest_sprintf_test5
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test5/test5.c b/src/pal/tests/palsuite/c_runtime/sprintf/test5/test5.c
deleted file mode 100644
index 1b52da77b6..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test5/test5.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test5.c
-**
-** Purpose: Test #5 for the sprintf function. Tests the count specifier (%n).
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sprintf.h"
-
-/*
- * Depends on memcmp and strlen
- */
-
-
-int __cdecl main(int argc, char *argv[])
-{
- char *longStr =
- "really-long-string-that-just-keeps-going-on-and-on-and-on.."
- "..................useless-filler.................................."
- "..................useless-filler.................................."
- "..................useless-filler.................................."
- "%n bar";
- char *longResult =
- "really-long-string-that-just-keeps-going-on-and-on-and-on.."
- "..................useless-filler.................................."
- "..................useless-filler.................................."
- "..................useless-filler.................................."
- " bar";
-
- if (PAL_Initialize(argc, argv)!= 0)
- {
- return FAIL;
- }
-
- DoCountTest("foo %n bar", 4, "foo bar");
- DoCountTest(longStr, 257, longResult);
- DoCountTest("fo%n bar", 2, "fo bar");
- DoCountTest("%n", 0, "");
- DoCountTest("foo %#n bar", 4, "foo bar");
- DoCountTest("foo % n bar", 4, "foo bar");
- DoCountTest("foo %+n bar", 4, "foo bar");
- DoCountTest("foo %-n bar", 4, "foo bar");
- DoCountTest("foo %0n bar", 4, "foo bar");
- DoShortCountTest("foo %hn bar", 4, "foo bar");
- DoCountTest("foo %ln bar", 4, "foo bar");
- DoCountTest("foo %Ln bar", 4, "foo bar");
- DoCountTest("foo %I64n bar", 4, "foo bar");
- DoCountTest("foo %20.3n bar", 4, "foo bar");
-
- PAL_Terminate();
-
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test5/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf/test5/testinfo.dat
deleted file mode 100644
index 31e0537bd0..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test5/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sprintf
-Name = Positive Test for sprintf
-TYPE = DEFAULT
-EXE1 = test5
-Description
-= Tests sprintf with the count specifier
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test6/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf/test6/CMakeLists.txt
deleted file mode 100644
index 7a9a5fc856..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test6/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test6.c
-)
-
-add_executable(paltest_sprintf_test6
- ${SOURCES}
-)
-
-add_dependencies(paltest_sprintf_test6 coreclrpal)
-
-target_link_libraries(paltest_sprintf_test6
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test6/test6.c b/src/pal/tests/palsuite/c_runtime/sprintf/test6/test6.c
deleted file mode 100644
index c14e075475..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test6/test6.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test6.c
-**
-** Purpose: Test #6 for the sprintf function. Tests the char specifier (%c).
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sprintf.h"
-
-/*
- * Depends on memcmp and strlen
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- WCHAR wc = (WCHAR) 'c';
-
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
-
- DoCharTest("foo %c", 'b', "foo b");
- DoCharTest("foo %hc", 'b', "foo b");
- DoWCharTest("foo %lc", wc, "foo c");
- DoCharTest("foo %Lc", 'b', "foo b");
- DoCharTest("foo %I64c", 'b', "foo b");
- DoCharTest("foo %5c", 'b', "foo b");
- DoCharTest("foo %.0c", 'b', "foo b");
- DoCharTest("foo %-5c", 'b', "foo b ");
- DoCharTest("foo %05c", 'b', "foo 0000b");
- DoCharTest("foo % c", 'b', "foo b");
- DoCharTest("foo %#c", 'b', "foo b");
-
- PAL_Terminate();
- return PASS;
-}
-
-
-
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test6/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf/test6/testinfo.dat
deleted file mode 100644
index 037e4106ff..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test6/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sprintf
-Name = Positive Test for sprintf
-TYPE = DEFAULT
-EXE1 = test6
-Description
-= Tests sprintf with characters
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test7/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf/test7/CMakeLists.txt
deleted file mode 100644
index a539a59ab9..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test7/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test7.c
-)
-
-add_executable(paltest_sprintf_test7
- ${SOURCES}
-)
-
-add_dependencies(paltest_sprintf_test7 coreclrpal)
-
-target_link_libraries(paltest_sprintf_test7
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test7/test7.c b/src/pal/tests/palsuite/c_runtime/sprintf/test7/test7.c
deleted file mode 100644
index 082bd20e6d..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test7/test7.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test7.c
-**
-** Purpose: Test #7 for the sprintf function. Tests the wide char
-** specifier (%C).
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sprintf.h"
-
-/*
- * Depends on memcmp and strlen
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- WCHAR wb = (WCHAR) 'b';
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoWCharTest("foo %C", wb, "foo b");
- DoWCharTest("foo %hC", wb, "foo b");
- DoCharTest("foo %lC", 'c', "foo c");
- DoWCharTest("foo %LC", wb, "foo b");
- DoWCharTest("foo %I64C", wb, "foo b");
- DoWCharTest("foo %5C", wb, "foo b");
- DoWCharTest("foo %.0C", wb, "foo b");
- DoWCharTest("foo %-5C", wb, "foo b ");
- DoWCharTest("foo %05C", wb, "foo 0000b");
- DoWCharTest("foo % C", wb, "foo b");
- DoWCharTest("foo %#C", wb, "foo b");
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test7/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf/test7/testinfo.dat
deleted file mode 100644
index a2730bc97c..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test7/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sprintf
-Name = Positive Test for sprintf
-TYPE = DEFAULT
-EXE1 = test7
-Description
-= Tests sprintf with wide characters
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test8/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf/test8/CMakeLists.txt
deleted file mode 100644
index 7a92c5072a..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test8/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test8.c
-)
-
-add_executable(paltest_sprintf_test8
- ${SOURCES}
-)
-
-add_dependencies(paltest_sprintf_test8 coreclrpal)
-
-target_link_libraries(paltest_sprintf_test8
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test8/test8.c b/src/pal/tests/palsuite/c_runtime/sprintf/test8/test8.c
deleted file mode 100644
index 9587c82c94..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test8/test8.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test8.c
-**
-** Purpose: Test #8 for the sprintf function. Tests the decimal
-** specifier (%d).
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sprintf.h"
-
-/*
- * Depends on memcmp and strlen
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- int neg = -42;
- int pos = 42;
- INT64 l = 42;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoNumTest("foo %d", pos, "foo 42");
- DoNumTest("foo %ld", 0xFFFF, "foo 65535");
- DoNumTest("foo %hd", 0xFFFF, "foo -1");
- DoNumTest("foo %Ld", pos, "foo 42");
- DoI64Test("foo %I64d", l, "42", "foo 42");
- DoNumTest("foo %3d", pos, "foo 42");
- DoNumTest("foo %-3d", pos, "foo 42 ");
- DoNumTest("foo %.1d", pos, "foo 42");
- DoNumTest("foo %.3d", pos, "foo 042");
- DoNumTest("foo %03d", pos, "foo 042");
- DoNumTest("foo %#d", pos, "foo 42");
- DoNumTest("foo %+d", pos, "foo +42");
- DoNumTest("foo % d", pos, "foo 42");
- DoNumTest("foo %+d", neg, "foo -42");
- DoNumTest("foo % d", neg, "foo -42");
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test8/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf/test8/testinfo.dat
deleted file mode 100644
index adc0b66f06..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test8/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sprintf
-Name = Positive Test for sprintf
-TYPE = DEFAULT
-EXE1 = test8
-Description
-= Tests sprintf with decimal numbers
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test9/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf/test9/CMakeLists.txt
deleted file mode 100644
index 2a91658bd4..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test9/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test9.c
-)
-
-add_executable(paltest_sprintf_test9
- ${SOURCES}
-)
-
-add_dependencies(paltest_sprintf_test9 coreclrpal)
-
-target_link_libraries(paltest_sprintf_test9
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test9/test9.c b/src/pal/tests/palsuite/c_runtime/sprintf/test9/test9.c
deleted file mode 100644
index 98f5db6ec1..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test9/test9.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test9.c
-**
-** Purpose: Test #9 for the sprintf function. Tests the integer
-** specifier (%i).
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sprintf.h"
-
-/*
- * Depends on memcmp and strlen
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- int neg = -42;
- int pos = 42;
- INT64 l = 42;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
-
- DoNumTest("foo %i", pos, "foo 42");
- DoNumTest("foo %li", 0xFFFF, "foo 65535");
- DoNumTest("foo %hi", 0xFFFF, "foo -1");
- DoNumTest("foo %Li", pos, "foo 42");
- DoI64Test("foo %I64i", l, "42", "foo 42");
- DoNumTest("foo %3i", pos, "foo 42");
- DoNumTest("foo %-3i", pos, "foo 42 ");
- DoNumTest("foo %.1i", pos, "foo 42");
- DoNumTest("foo %.3i", pos, "foo 042");
- DoNumTest("foo %03i", pos, "foo 042");
- DoNumTest("foo %#i", pos, "foo 42");
- DoNumTest("foo %+i", pos, "foo +42");
- DoNumTest("foo % i", pos, "foo 42");
- DoNumTest("foo %+i", neg, "foo -42");
- DoNumTest("foo % i", neg, "foo -42");
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf/test9/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf/test9/testinfo.dat
deleted file mode 100644
index e569e789cd..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sprintf/test9/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sprintf
-Name = Positive Test for sprintf
-TYPE = DEFAULT
-EXE1 = test9
-Description
-= Tests sprintf with integer numbers
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf_s/CMakeLists.txt
new file mode 100644
index 0000000000..8fe1cb60ac
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/CMakeLists.txt
@@ -0,0 +1,21 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+add_subdirectory(test10)
+add_subdirectory(test11)
+add_subdirectory(test12)
+add_subdirectory(test13)
+add_subdirectory(test14)
+add_subdirectory(test15)
+add_subdirectory(test16)
+add_subdirectory(test17)
+add_subdirectory(test18)
+add_subdirectory(test19)
+add_subdirectory(test2)
+add_subdirectory(test3)
+add_subdirectory(test4)
+add_subdirectory(test6)
+add_subdirectory(test7)
+add_subdirectory(test8)
+add_subdirectory(test9)
+
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/sprintf_s.h b/src/pal/tests/palsuite/c_runtime/sprintf_s/sprintf_s.h
new file mode 100644
index 0000000000..129b9db727
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/sprintf_s.h
@@ -0,0 +1,195 @@
+// Licensed to the .NET Foundation under one or more 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: sprintf_s.h
+**
+** Purpose: Containts common testing functions for sprintf_s
+**
+**
+**==========================================================================*/
+
+#ifndef __SPRINTF_S_H__
+#define __SPRINTF_S_H__
+
+void DoStrTest(const char *formatstr, char* param, const char *checkstr)
+{
+ char buf[256] = { 0 };
+
+ sprintf_s(buf, _countof(buf), formatstr, param);
+ if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
+ {
+ Fail("ERROR: failed to insert string \"%s\" into \"%s\"\n"
+ "Expected \"%s\" got \"%s\".\n",
+ param, formatstr, checkstr, buf);
+ }
+}
+
+void DoWStrTest(const char *formatstr, WCHAR* param, const char *checkstr)
+{
+ char buf[256] = { 0 };
+
+ sprintf_s(buf, _countof(buf), formatstr, param);
+ if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
+ {
+ Fail("ERROR: failed to insert wide string \"%s\" into \"%s\"\n"
+ "Expected \"%s\" got \"%s\".\n",
+ convertC(param), formatstr, checkstr, buf);
+ }
+}
+
+void DoPointerTest(const char *formatstr, void* param, char* paramstr,
+ const char *checkstr1)
+{
+ char buf[256] = { 0 };
+
+ sprintf_s(buf, _countof(buf), formatstr, param);
+ if (memcmp(buf, checkstr1, strlen(checkstr1) + 1) != 0)
+ {
+ Fail("ERROR: failed to insert %s into \"%s\"\n"
+ "Expected \"%s\" got \"%s\".\n",
+ paramstr, formatstr, checkstr1, buf);
+ }
+}
+
+void DoCountTest(const char *formatstr, int param, const char *checkstr)
+{
+ char buf[512] = { 0 };
+ int n = -1;
+
+ sprintf_s(buf, _countof(buf), formatstr, &n);
+
+ if (n != param)
+ {
+ Fail("ERROR: Expected count parameter to resolve to %d, got %X\n",
+ param, n);
+ }
+ if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
+ {
+ Fail("ERROR: Expected \"%s\" got \"%s\".\n", checkstr, buf);
+ }
+}
+
+void DoShortCountTest(const char *formatstr, int param, const char *checkstr)
+{
+ char buf[256] = { 0 };
+ short int n = -1;
+
+ sprintf_s(buf, _countof(buf), formatstr, &n);
+
+ if (n != param)
+ {
+ Fail("ERROR: Expected count parameter to resolve to %d, got %X\n",
+ param, n);
+ }
+ if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
+ {
+ Fail("ERROR: Expected \"%s\" got \"%s\".\n", checkstr, buf);
+ }
+}
+
+
+void DoCharTest(const char *formatstr, char param, const char *checkstr)
+{
+ char buf[256] = { 0 };
+
+ sprintf_s(buf, _countof(buf), formatstr, param);
+ if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
+ {
+ Fail("ERROR: failed to insert char \'%c\' (%d) into \"%s\"\n"
+ "Expected \"%s\" got \"%s\".\n",
+ param, param, formatstr, checkstr, buf);
+ }
+}
+
+void DoWCharTest(const char *formatstr, WCHAR param, const char *checkstr)
+{
+ char buf[256] = { 0 };
+
+ sprintf_s(buf, _countof(buf), formatstr, param);
+ if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
+ {
+ Fail("ERROR: failed to insert wide char \'%c\' (%d) into \"%s\"\n"
+ "Expected \"%s\" got \"%s\".\n",
+ (char)param, param, formatstr, checkstr, buf);
+ }
+}
+
+void DoNumTest(const char *formatstr, int value, const char *checkstr)
+{
+ char buf[256] = { 0 };
+
+ sprintf_s(buf, _countof(buf), formatstr, value);
+ if (memcmp(buf, checkstr, strlen(checkstr) + 1) != 0)
+ {
+ Fail("ERROR: failed to insert %#x into \"%s\"\n"
+ "Expected \"%s\" got \"%s\".\n",
+ value, formatstr, checkstr, buf);
+ }
+}
+
+void DoI64Test(const char *formatstr, INT64 value, char *valuestr, const char *checkstr1)
+{
+ char buf[256] = { 0 };
+
+ sprintf_s(buf, _countof(buf), formatstr, value);
+ if (memcmp(buf, checkstr1, strlen(checkstr1) + 1) != 0)
+ {
+ Fail("ERROR: failed to insert %s into \"%s\"\n"
+ "Expected \"%s\", got \"%s\".\n",
+ valuestr, formatstr, checkstr1, buf);
+ }
+}
+
+void DoDoubleTest(const char *formatstr, double value, const char *checkstr1,
+ const char *checkstr2)
+{
+ char buf[256] = { 0 };
+
+ sprintf_s(buf, _countof(buf), formatstr, value);
+ if (memcmp(buf, checkstr1, strlen(checkstr1) + 1) != 0 &&
+ memcmp(buf, checkstr2, strlen(checkstr2) + 1) != 0)
+ {
+ Fail("ERROR: failed to insert %f into \"%s\"\n"
+ "Expected \"%s\" or \"%s\", got \"%s\".\n",
+ value, formatstr, checkstr1, checkstr2, buf);
+ }
+}
+
+void DoArgumentPrecTest(const char *formatstr, int precision, void *param,
+ char *paramstr, const char *checkstr1, const char *checkstr2)
+{
+ char buf[256];
+
+ sprintf_s(buf, _countof(buf), formatstr, precision, param);
+ if (memcmp(buf, checkstr1, strlen(checkstr1) + 1) != 0 &&
+ memcmp(buf, checkstr2, strlen(checkstr2) + 1) != 0)
+ {
+ Fail("ERROR: failed to insert %s into \"%s\" with precision %d\n"
+ "Expected \"%s\" or \"%s\", got \"%s\".\n", paramstr, formatstr,
+ precision, checkstr1, checkstr2, buf);
+ }
+
+}
+
+void DoArgumentPrecDoubleTest(const char *formatstr, int precision, double param,
+ const char *checkstr1, const char *checkstr2)
+{
+ char buf[256];
+
+ sprintf_s(buf, _countof(buf), formatstr, precision, param);
+ if (memcmp(buf, checkstr1, strlen(checkstr1) + 1) != 0 &&
+ memcmp(buf, checkstr2, strlen(checkstr2) + 1) != 0)
+ {
+ Fail("ERROR: failed to insert %f into \"%s\" with precision %d\n"
+ "Expected \"%s\" or \"%s\", got \"%s\".\n", param, formatstr,
+ precision, checkstr1, checkstr2, buf);
+ }
+
+}
+
+#endif
+
+
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf_s/test1/CMakeLists.txt
new file mode 100644
index 0000000000..ee0d90fe7f
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.cpp
+)
+
+add_executable(paltest_sprintf_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sprintf_test1 coreclrpal)
+
+target_link_libraries(paltest_sprintf_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test1/test1.cpp b/src/pal/tests/palsuite/c_runtime/sprintf_s/test1/test1.cpp
new file mode 100644
index 0000000000..a289c07716
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test1/test1.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test1.c
+**
+** Purpose: Test #1 for the sprintf_s function. A single, basic, test
+** case with no formatting.
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sprintf_s.h"
+
+/*
+ * Depends on memcmp and strlen
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ char checkstr[] = "hello world";
+ char buf[256];
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ sprintf_s(buf, _countof(buf), "hello world");
+
+ if (memcmp(checkstr, buf, strlen(checkstr)+1) != 0)
+ {
+ Fail("ERROR: expected %s, got %s\n", checkstr, buf);
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf_s/test1/testinfo.dat
new file mode 100644
index 0000000000..255c534cdf
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= General test to see if sprintf_s works correctly
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test10/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf_s/test10/CMakeLists.txt
new file mode 100644
index 0000000000..1efad19dee
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test10/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test10.cpp
+)
+
+add_executable(paltest_sprintf_test10
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sprintf_test10 coreclrpal)
+
+target_link_libraries(paltest_sprintf_test10
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test10/test10.cpp b/src/pal/tests/palsuite/c_runtime/sprintf_s/test10/test10.cpp
new file mode 100644
index 0000000000..bbda15a331
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test10/test10.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: test10.c
+**
+** Purpose: Test #10 for the sprintf_s function. Tests the octal specifier
+** (%o).
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sprintf_s.h"
+
+/*
+ * Depends on memcmp and strlen
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ int neg = -42;
+ int pos = 42;
+ INT64 l = 42;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoNumTest("foo %o", pos, "foo 52");
+ DoNumTest("foo %lo", 0xFFFF, "foo 177777");
+ DoNumTest("foo %ho", 0xFFFF, "foo 177777");
+ DoNumTest("foo %Lo", pos, "foo 52");
+ DoI64Test("foo %I64o", l, "42", "foo 52");
+ DoNumTest("foo %3o", pos, "foo 52");
+ DoNumTest("foo %-3o", pos, "foo 52 ");
+ DoNumTest("foo %.1o", pos, "foo 52");
+ DoNumTest("foo %.3o", pos, "foo 052");
+ DoNumTest("foo %03o", pos, "foo 052");
+ DoNumTest("foo %#o", pos, "foo 052");
+ DoNumTest("foo %+o", pos, "foo 52");
+ DoNumTest("foo % o", pos, "foo 52");
+ DoNumTest("foo %+o", neg, "foo 37777777726");
+ DoNumTest("foo % o", neg, "foo 37777777726");
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test10/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf_s/test10/testinfo.dat
new file mode 100644
index 0000000000..25ed554ea3
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test10/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test10
+Description
+= Tests sprintf_s with octal numbers
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test11/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf_s/test11/CMakeLists.txt
new file mode 100644
index 0000000000..f2f4da694c
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test11/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test11.cpp
+)
+
+add_executable(paltest_sprintf_test11
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sprintf_test11 coreclrpal)
+
+target_link_libraries(paltest_sprintf_test11
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test11/test11.cpp b/src/pal/tests/palsuite/c_runtime/sprintf_s/test11/test11.cpp
new file mode 100644
index 0000000000..7f4fca9f32
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test11/test11.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: test11.c
+**
+** Purpose: Test #11 for the sprintf_s function. Test the unsigned int
+** specifier (%u).
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sprintf_s.h"
+
+/*
+ * Depends on memcmp and strlen
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ int neg = -42;
+ int pos = 42;
+ INT64 l = 42;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoNumTest("foo %u", pos, "foo 42");
+ DoNumTest("foo %lu", 0xFFFF, "foo 65535");
+ DoNumTest("foo %hu", 0xFFFF, "foo 65535");
+ DoNumTest("foo %Lu", pos, "foo 42");
+ DoI64Test("foo %I64u", l, "42", "foo 42");
+ DoNumTest("foo %3u", pos, "foo 42");
+ DoNumTest("foo %-3u", pos, "foo 42 ");
+ DoNumTest("foo %.1u", pos, "foo 42");
+ DoNumTest("foo %.3u", pos, "foo 042");
+ DoNumTest("foo %03u", pos, "foo 042");
+ DoNumTest("foo %#u", pos, "foo 42");
+ DoNumTest("foo %+u", pos, "foo 42");
+ DoNumTest("foo % u", pos, "foo 42");
+ DoNumTest("foo %+u", neg, "foo 4294967254");
+ DoNumTest("foo % u", neg, "foo 4294967254");
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test11/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf_s/test11/testinfo.dat
new file mode 100644
index 0000000000..3144f1290e
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test11/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test11
+Description
+= Tests sprintf_s with unsigned numbers
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test12/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf_s/test12/CMakeLists.txt
new file mode 100644
index 0000000000..361e91f9ae
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test12/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test12.cpp
+)
+
+add_executable(paltest_sprintf_test12
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sprintf_test12 coreclrpal)
+
+target_link_libraries(paltest_sprintf_test12
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test12/test12.cpp b/src/pal/tests/palsuite/c_runtime/sprintf_s/test12/test12.cpp
new file mode 100644
index 0000000000..759a41105b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test12/test12.cpp
@@ -0,0 +1,56 @@
+// Licensed to the .NET Foundation under one or more 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: test12.c
+**
+** Purpose: Test #12 for the sprintf_s function. Tests the (lowercase)
+** hexadecimal specifier (%x)
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sprintf_s.h"
+
+/*
+ * Depends on memcmp and strlen
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ int neg = -42;
+ int pos = 0x1234ab;
+ INT64 l = I64(0x1234567887654321);
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoNumTest("foo %x", pos, "foo 1234ab");
+ DoNumTest("foo %lx", pos, "foo 1234ab");
+ DoNumTest("foo %hx", pos, "foo 34ab");
+ DoNumTest("foo %Lx", pos, "foo 1234ab");
+ DoI64Test("foo %I64x", l, "0x1234567887654321",
+ "foo 1234567887654321");
+ DoNumTest("foo %7x", pos, "foo 1234ab");
+ DoNumTest("foo %-7x", pos, "foo 1234ab ");
+ DoNumTest("foo %.1x", pos, "foo 1234ab");
+ DoNumTest("foo %.7x", pos, "foo 01234ab");
+ DoNumTest("foo %07x", pos, "foo 01234ab");
+ DoNumTest("foo %#x", pos, "foo 0x1234ab");
+ DoNumTest("foo %+x", pos, "foo 1234ab");
+ DoNumTest("foo % x", pos, "foo 1234ab");
+ DoNumTest("foo %+x", neg, "foo ffffffd6");
+ DoNumTest("foo % x", neg, "foo ffffffd6");
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test12/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf_s/test12/testinfo.dat
new file mode 100644
index 0000000000..ed91cecc46
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test12/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test12
+Description
+= Tests sprintf_s with hex numbers (lowercase)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test13/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf_s/test13/CMakeLists.txt
new file mode 100644
index 0000000000..d08e13b2ba
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test13/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test13.cpp
+)
+
+add_executable(paltest_sprintf_test13
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sprintf_test13 coreclrpal)
+
+target_link_libraries(paltest_sprintf_test13
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test13/test13.cpp b/src/pal/tests/palsuite/c_runtime/sprintf_s/test13/test13.cpp
new file mode 100644
index 0000000000..76250d058c
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test13/test13.cpp
@@ -0,0 +1,56 @@
+// Licensed to the .NET Foundation under one or more 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: test13.c
+**
+** Purpose: Test #13 for the sprintf_s function. Tests the (uppercase)
+** hexadecimal specifier (%X)
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sprintf_s.h"
+
+/*
+ * Depends on memcmp and strlen
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ int neg = -42;
+ int pos = 0x1234AB;
+ INT64 l = I64(0x1234567887654321);
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoNumTest("foo %X", pos, "foo 1234AB");
+ DoNumTest("foo %lX", pos, "foo 1234AB");
+ DoNumTest("foo %hX", pos, "foo 34AB");
+ DoNumTest("foo %LX", pos, "foo 1234AB");
+ DoI64Test("foo %I64X", l, "0x1234567887654321",
+ "foo 1234567887654321");
+ DoNumTest("foo %7X", pos, "foo 1234AB");
+ DoNumTest("foo %-7X", pos, "foo 1234AB ");
+ DoNumTest("foo %.1X", pos, "foo 1234AB");
+ DoNumTest("foo %.7X", pos, "foo 01234AB");
+ DoNumTest("foo %07X", pos, "foo 01234AB");
+ DoNumTest("foo %#X", pos, "foo 0X1234AB");
+ DoNumTest("foo %+X", pos, "foo 1234AB");
+ DoNumTest("foo % X", pos, "foo 1234AB");
+ DoNumTest("foo %+X", neg, "foo FFFFFFD6");
+ DoNumTest("foo % X", neg, "foo FFFFFFD6");
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test13/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf_s/test13/testinfo.dat
new file mode 100644
index 0000000000..fd5f53017c
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test13/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test13
+Description
+= Tests sprintf_s with hex numbers (uppercase)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test14/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf_s/test14/CMakeLists.txt
new file mode 100644
index 0000000000..60ac2922d7
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test14/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test14.cpp
+)
+
+add_executable(paltest_sprintf_test14
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sprintf_test14 coreclrpal)
+
+target_link_libraries(paltest_sprintf_test14
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test14/test14.cpp b/src/pal/tests/palsuite/c_runtime/sprintf_s/test14/test14.cpp
new file mode 100644
index 0000000000..668edda433
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test14/test14.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: test14.c
+**
+** Purpose: Test #14 for the sprintf_s function. Tests the lowercase
+** exponential notation double specifier (%e)
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sprintf_s.h"
+
+/*
+ * Depends on memcmp and strlen
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ double val = 256.0;
+ double neg = -256.0;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoDoubleTest("foo %e", val, "foo 2.560000e+002", "foo 2.560000e+02");
+ DoDoubleTest("foo %le", val, "foo 2.560000e+002", "foo 2.560000e+02");
+ DoDoubleTest("foo %he", val, "foo 2.560000e+002", "foo 2.560000e+02");
+ DoDoubleTest("foo %Le", val, "foo 2.560000e+002", "foo 2.560000e+02");
+ DoDoubleTest("foo %I64e", val, "foo 2.560000e+002", "foo 2.560000e+02");
+ DoDoubleTest("foo %14e", val, "foo 2.560000e+002", "foo 2.560000e+02");
+ DoDoubleTest("foo %-14e", val, "foo 2.560000e+002 ", "foo 2.560000e+02 ");
+ DoDoubleTest("foo %.1e", val, "foo 2.6e+002", "foo 2.6e+02");
+ DoDoubleTest("foo %.8e", val, "foo 2.56000000e+002", "foo 2.56000000e+02");
+ DoDoubleTest("foo %014e", val, "foo 02.560000e+002", "foo 002.560000e+02");
+ DoDoubleTest("foo %#e", val, "foo 2.560000e+002", "foo 2.560000e+02");
+ DoDoubleTest("foo %+e", val, "foo +2.560000e+002", "foo +2.560000e+02");
+ DoDoubleTest("foo % e", val, "foo 2.560000e+002", "foo 2.560000e+02");
+ DoDoubleTest("foo %+e", neg, "foo -2.560000e+002", "foo -2.560000e+02");
+ DoDoubleTest("foo % e", neg, "foo -2.560000e+002", "foo -2.560000e+02");
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test14/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf_s/test14/testinfo.dat
new file mode 100644
index 0000000000..23cf423354
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test14/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test14
+Description
+= Tests sprintf_s with exponential format doubles (lowercase)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test15/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf_s/test15/CMakeLists.txt
new file mode 100644
index 0000000000..57bba40e6c
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test15/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test15.cpp
+)
+
+add_executable(paltest_sprintf_test15
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sprintf_test15 coreclrpal)
+
+target_link_libraries(paltest_sprintf_test15
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test15/test15.cpp b/src/pal/tests/palsuite/c_runtime/sprintf_s/test15/test15.cpp
new file mode 100644
index 0000000000..61e0e362a1
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test15/test15.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: test15.c
+**
+** Purpose: Test #15 for the sprintf_s function. Tests the uppercase
+** exponential notation double specifier (%E)
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sprintf_s.h"
+
+/*
+ * Depends on memcmp and strlen
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ double val = 256.0;
+ double neg = -256.0;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoDoubleTest("foo %E", val, "foo 2.560000E+002", "foo 2.560000E+02");
+ DoDoubleTest("foo %lE", val, "foo 2.560000E+002", "foo 2.560000E+02");
+ DoDoubleTest("foo %hE", val, "foo 2.560000E+002", "foo 2.560000E+02");
+ DoDoubleTest("foo %LE", val, "foo 2.560000E+002", "foo 2.560000E+02");
+ DoDoubleTest("foo %I64E", val, "foo 2.560000E+002", "foo 2.560000E+02");
+ DoDoubleTest("foo %14E", val, "foo 2.560000E+002", "foo 2.560000E+02");
+ DoDoubleTest("foo %-14E", val, "foo 2.560000E+002 ", "foo 2.560000E+02 ");
+ DoDoubleTest("foo %.1E", val, "foo 2.6E+002", "foo 2.6E+02");
+ DoDoubleTest("foo %.8E", val, "foo 2.56000000E+002", "foo 2.56000000E+02");
+ DoDoubleTest("foo %014E", val, "foo 02.560000E+002", "foo 002.560000E+02");
+ DoDoubleTest("foo %#E", val, "foo 2.560000E+002", "foo 2.560000E+02");
+ DoDoubleTest("foo %+E", val, "foo +2.560000E+002", "foo +2.560000E+02");
+ DoDoubleTest("foo % E", val, "foo 2.560000E+002", "foo 2.560000E+02");
+ DoDoubleTest("foo %+E", neg, "foo -2.560000E+002", "foo -2.560000E+02");
+ DoDoubleTest("foo % E", neg, "foo -2.560000E+002", "foo -2.560000E+02");
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test15/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf_s/test15/testinfo.dat
new file mode 100644
index 0000000000..537e6d1db2
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test15/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test15
+Description
+= Tests sprintf_s with exponential format doubles (uppercase)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test16/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf_s/test16/CMakeLists.txt
new file mode 100644
index 0000000000..fc93e1a67d
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test16/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test16.cpp
+)
+
+add_executable(paltest_sprintf_test16
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sprintf_test16 coreclrpal)
+
+target_link_libraries(paltest_sprintf_test16
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test16/test16.cpp b/src/pal/tests/palsuite/c_runtime/sprintf_s/test16/test16.cpp
new file mode 100644
index 0000000000..b237c98d5c
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test16/test16.cpp
@@ -0,0 +1,52 @@
+// Licensed to the .NET Foundation under one or more 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: test16.c
+**
+** Purpose: Test #16 for the sprintf_s function. Tests the decimal notation
+** double specifier (%f)
+**
+**
+**==========================================================================*/
+
+
+#include <palsuite.h>
+#include "../sprintf_s.h"
+
+/*
+ * Depends on memcmp and strlen
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ double val = 2560.001;
+ double neg = -2560.001;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoDoubleTest("foo %f", val, "foo 2560.001000", "foo 2560.001000");
+ DoDoubleTest("foo %lf", val, "foo 2560.001000", "foo 2560.001000");
+ DoDoubleTest("foo %hf", val, "foo 2560.001000", "foo 2560.001000");
+ DoDoubleTest("foo %Lf", val, "foo 2560.001000", "foo 2560.001000");
+ DoDoubleTest("foo %I64f", val, "foo 2560.001000", "foo 2560.001000");
+ DoDoubleTest("foo %12f", val, "foo 2560.001000", "foo 2560.001000");
+ DoDoubleTest("foo %-12f", val, "foo 2560.001000 ", "foo 2560.001000 ");
+ DoDoubleTest("foo %.1f", val, "foo 2560.0", "foo 2560.0");
+ DoDoubleTest("foo %.8f", val, "foo 2560.00100000", "foo 2560.00100000");
+ DoDoubleTest("foo %012f", val, "foo 02560.001000", "foo 02560.001000");
+ DoDoubleTest("foo %#f", val, "foo 2560.001000", "foo 2560.001000");
+ DoDoubleTest("foo %+f", val, "foo +2560.001000", "foo +2560.001000");
+ DoDoubleTest("foo % f", val, "foo 2560.001000", "foo 2560.001000");
+ DoDoubleTest("foo %+f", neg, "foo -2560.001000", "foo -2560.001000");
+ DoDoubleTest("foo % f", neg, "foo -2560.001000", "foo -2560.001000");
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test16/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf_s/test16/testinfo.dat
new file mode 100644
index 0000000000..4e98eccac2
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test16/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test16
+Description
+= Tests sprintf_s with decimal point format doubles
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test17/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf_s/test17/CMakeLists.txt
new file mode 100644
index 0000000000..dc5ff2bb30
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test17/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test17.cpp
+)
+
+add_executable(paltest_sprintf_test17
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sprintf_test17 coreclrpal)
+
+target_link_libraries(paltest_sprintf_test17
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test17/test17.cpp b/src/pal/tests/palsuite/c_runtime/sprintf_s/test17/test17.cpp
new file mode 100644
index 0000000000..220555e5d4
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test17/test17.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test17.c
+**
+** Purpose: Test #17 for the sprintf_s function. Tests the lowercase
+** shorthand notation double specifier (%g)
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sprintf_s.h"
+
+/*
+ * Depends on memcmp and strlen
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ double val = 2560.001;
+ double neg = -2560.001;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoDoubleTest("foo %g", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %lg", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %hg", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %Lg", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %I64g", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %5g", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %-5g", val, "foo 2560 ", "foo 2560 ");
+ DoDoubleTest("foo %.1g", val, "foo 3e+003", "foo 3e+03");
+ DoDoubleTest("foo %.2g", val, "foo 2.6e+003", "foo 2.6e+03");
+ DoDoubleTest("foo %.12g", val, "foo 2560.001", "foo 2560.001");
+ DoDoubleTest("foo %06g", val, "foo 002560", "foo 002560");
+ DoDoubleTest("foo %#g", val, "foo 2560.00", "foo 2560.00");
+ DoDoubleTest("foo %+g", val, "foo +2560", "foo +2560");
+ DoDoubleTest("foo % g", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %+g", neg, "foo -2560", "foo -2560");
+ DoDoubleTest("foo % g", neg, "foo -2560", "foo -2560");
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test17/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf_s/test17/testinfo.dat
new file mode 100644
index 0000000000..5e41e20d44
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test17/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test17
+Description
+= Tests sprintf_s with compact format doubles (lowercase)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test18/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf_s/test18/CMakeLists.txt
new file mode 100644
index 0000000000..f6e1b09efa
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test18/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test18.cpp
+)
+
+add_executable(paltest_sprintf_test18
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sprintf_test18 coreclrpal)
+
+target_link_libraries(paltest_sprintf_test18
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test18/test18.cpp b/src/pal/tests/palsuite/c_runtime/sprintf_s/test18/test18.cpp
new file mode 100644
index 0000000000..2135a6f1e7
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test18/test18.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: test18.c
+**
+** Purpose: Test #18 for the sprintf_s function. Tests the uppercase
+** shorthand notation double specifier (%G)
+**
+**
+**==========================================================================*/
+
+
+#include <palsuite.h>
+#include "../sprintf_s.h"
+
+/*
+ * Depends on memcmp and strlen
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ double val = 2560.001;
+ double neg = -2560.001;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoDoubleTest("foo %G", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %lG", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %hG", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %LG", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %I64G", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %5G", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %-5G", val, "foo 2560 ", "foo 2560 ");
+ DoDoubleTest("foo %.1G", val, "foo 3E+003", "foo 3E+03");
+ DoDoubleTest("foo %.2G", val, "foo 2.6E+003", "foo 2.6E+03");
+ DoDoubleTest("foo %.12G", val, "foo 2560.001", "foo 2560.001");
+ DoDoubleTest("foo %06G", val, "foo 002560", "foo 002560");
+ DoDoubleTest("foo %#G", val, "foo 2560.00", "foo 2560.00");
+ DoDoubleTest("foo %+G", val, "foo +2560", "foo +2560");
+ DoDoubleTest("foo % G", val, "foo 2560", "foo 2560");
+ DoDoubleTest("foo %+G", neg, "foo -2560", "foo -2560");
+ DoDoubleTest("foo % G", neg, "foo -2560", "foo -2560");
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test18/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf_s/test18/testinfo.dat
new file mode 100644
index 0000000000..06ae3a632e
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test18/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test18
+Description
+= Tests sprintf_s with compact format doubles (uppercase)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test19/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf_s/test19/CMakeLists.txt
new file mode 100644
index 0000000000..757288b694
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test19/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test19.cpp
+)
+
+add_executable(paltest_sprintf_test19
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sprintf_test19 coreclrpal)
+
+target_link_libraries(paltest_sprintf_test19
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test19/test19.cpp b/src/pal/tests/palsuite/c_runtime/sprintf_s/test19/test19.cpp
new file mode 100644
index 0000000000..483c7167b1
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test19/test19.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test19.c
+**
+** Purpose: Test #19 for the sprintf_s function. Tests the variable length
+** precision argument.
+**
+**
+**==========================================================================*/
+
+
+#include <palsuite.h>
+#include "../sprintf_s.h"
+
+/*
+ * Depends on memcmp and strlen
+ */
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ int n = -1;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ DoArgumentPrecTest("%.*s", 2, (void*)"bar", "bar", "ba", "ba");
+ DoArgumentPrecTest("%.*S", 2, (void*)convert("bar"), "bar", "ba", "ba");
+
+ DoArgumentPrecTest("%.*c", 0, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*c", 4, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*C", 0, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*C", 4, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*d", 1, (void*)42, "42", "42", "42");
+ DoArgumentPrecTest("%.*d", 3, (void*)42, "42", "042", "042");
+ DoArgumentPrecTest("%.*i", 1, (void*)42, "42", "42", "42");
+ DoArgumentPrecTest("%.*i", 3, (void*)42, "42", "042", "042");
+ DoArgumentPrecTest("%.*o", 1, (void*)42, "42", "52", "52");
+ DoArgumentPrecTest("%.*o", 3, (void*)42, "42", "052", "052");
+ DoArgumentPrecTest("%.*u", 1, (void*)42, "42", "42", "42");
+ DoArgumentPrecTest("%.*u", 3, (void*)42, "42", "042", "042");
+ DoArgumentPrecTest("%.*x", 1, (void*)0x42, "0x42", "42", "42");
+ DoArgumentPrecTest("%.*x", 3, (void*)0x42, "0x42", "042", "042");
+ DoArgumentPrecTest("%.*X", 1, (void*)0x42, "0x42", "42", "42");
+ DoArgumentPrecTest("%.*X", 3, (void*)0x42, "0x42", "042", "042");
+
+
+ DoArgumentPrecDoubleTest("%.*e", 1, 2.01, "2.0e+000", "2.0e+00");
+ DoArgumentPrecDoubleTest("%.*e", 3, 2.01, "2.010e+000", "2.010e+00");
+ DoArgumentPrecDoubleTest("%.*E", 1, 2.01, "2.0E+000", "2.0E+00");
+ DoArgumentPrecDoubleTest("%.*E", 3, 2.01, "2.010E+000", "2.010E+00");
+ DoArgumentPrecDoubleTest("%.*f", 1, 2.01, "2.0", "2.0");
+ DoArgumentPrecDoubleTest("%.*f", 3, 2.01, "2.010", "2.010");
+ DoArgumentPrecDoubleTest("%.*g", 1, 256.01, "3e+002", "3e+02");
+ DoArgumentPrecDoubleTest("%.*g", 3, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*g", 4, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*g", 6, 256.01, "256.01", "256.01");
+ DoArgumentPrecDoubleTest("%.*G", 1, 256.01, "3E+002", "3E+02");
+ DoArgumentPrecDoubleTest("%.*G", 3, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*G", 4, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*G", 6, 256.01, "256.01", "256.01");
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test19/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf_s/test19/testinfo.dat
new file mode 100644
index 0000000000..7064c01771
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test19/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test19
+Description
+= Tests sprintf_s with argument specified precision
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf_s/test2/CMakeLists.txt
new file mode 100644
index 0000000000..d569263da4
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test2.cpp
+)
+
+add_executable(paltest_sprintf_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sprintf_test2 coreclrpal)
+
+target_link_libraries(paltest_sprintf_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test2/test2.cpp b/src/pal/tests/palsuite/c_runtime/sprintf_s/test2/test2.cpp
new file mode 100644
index 0000000000..990f4f04a8
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test2/test2.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test2.c
+**
+** Purpose: Test #2 for the sprintf_s function. Tests the string specifier
+** (%s).
+**
+**
+**==========================================================================*/
+
+
+#include <palsuite.h>
+#include "../sprintf_s.h"
+
+/*
+ * Depends on memcmp and strlen
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoStrTest("foo %s", "bar", "foo bar");
+ DoStrTest("foo %hs", "bar", "foo bar");
+ DoWStrTest("foo %ls", convert("bar"), "foo bar");
+ DoWStrTest("foo %ws", convert("bar"), "foo bar");
+ DoStrTest("foo %Ls", "bar", "foo bar");
+ DoStrTest("foo %I64s", "bar", "foo bar");
+ DoStrTest("foo %5s", "bar", "foo bar");
+ DoStrTest("foo %.2s", "bar", "foo ba");
+ DoStrTest("foo %5.2s", "bar", "foo ba");
+ DoStrTest("foo %-5s", "bar", "foo bar ");
+ DoStrTest("foo %05s", "bar", "foo 00bar");
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test2/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf_s/test2/testinfo.dat
new file mode 100644
index 0000000000..cce2dc67e7
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test2/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test2
+Description
+= Tests sprintf_s with strings
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf_s/test3/CMakeLists.txt
new file mode 100644
index 0000000000..518c3f847a
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test3/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test3.cpp
+)
+
+add_executable(paltest_sprintf_test3
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sprintf_test3 coreclrpal)
+
+target_link_libraries(paltest_sprintf_test3
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test3/test3.cpp b/src/pal/tests/palsuite/c_runtime/sprintf_s/test3/test3.cpp
new file mode 100644
index 0000000000..c0dc8e1716
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test3/test3.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test3.c
+**
+** Purpose: Test #3 for the sprintf_s function. Tests the wide string
+** specifier (%S).
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sprintf_s.h"
+
+/*
+ * Depends on memcmp and strlen
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ DoWStrTest("foo %S", convert("bar"), "foo bar");
+ DoStrTest("foo %hS", "bar", "foo bar");
+ DoWStrTest("foo %lS", convert("bar"), "foo bar");
+ DoWStrTest("foo %wS", convert("bar"), "foo bar");
+ DoWStrTest("foo %LS", convert("bar"), "foo bar");
+ DoWStrTest("foo %I64S", convert("bar"), "foo bar");
+ DoWStrTest("foo %5S", convert("bar"), "foo bar");
+ DoWStrTest("foo %.2S", convert("bar"), "foo ba");
+ DoWStrTest("foo %5.2S", convert("bar"), "foo ba");
+ DoWStrTest("foo %-5S", convert("bar"), "foo bar ");
+ DoWStrTest("foo %05S", convert("bar"), "foo 00bar");
+
+ PAL_Terminate();
+ return PASS;
+}
+
+
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test3/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf_s/test3/testinfo.dat
new file mode 100644
index 0000000000..cc8de0eae5
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test3/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test3
+Description
+= Tests sprintf_s with wide strings
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test4/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf_s/test4/CMakeLists.txt
new file mode 100644
index 0000000000..260def44aa
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test4/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test4.cpp
+)
+
+add_executable(paltest_sprintf_test4
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sprintf_test4 coreclrpal)
+
+target_link_libraries(paltest_sprintf_test4
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test4/test4.cpp b/src/pal/tests/palsuite/c_runtime/sprintf_s/test4/test4.cpp
new file mode 100644
index 0000000000..46115ad5ae
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test4/test4.cpp
@@ -0,0 +1,69 @@
+// Licensed to the .NET Foundation under one or more 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: test4.c
+**
+** Purpose: Test #4 for the sprintf_s function. Tests the pointer
+** specifier (%p).
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sprintf_s.h"
+/*
+ * Depends on memcmp and strlen
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ void *ptr = (void*) 0x123456;
+ INT64 lptr = I64(0x1234567887654321);
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+/*
+** Run only on 64 bit platforms
+*/
+#if defined(BIT64) && defined(PLATFORM_UNIX)
+ Trace("Testing for 64 Bit Platforms \n");
+ DoPointerTest("%p", NULL, "NULL", "0000000000000000");
+ DoPointerTest("%p", ptr, "pointer to 0x123456", "0000000000123456");
+ DoPointerTest("%17p", ptr, "pointer to 0x123456", " 0000000000123456");
+ DoPointerTest("%17p", ptr, "pointer to 0x123456", " 0000000000123456");
+ DoPointerTest("%-17p", ptr, "pointer to 0x123456", "0000000000123456 ");
+ DoPointerTest("%+p", ptr, "pointer to 0x123456", "0000000000123456");
+ DoPointerTest("%#p", ptr, "pointer to 0x123456", "0X0000000000123456");
+ DoPointerTest("%lp", ptr, "pointer to 0x123456", "00123456");
+ DoPointerTest("%hp", ptr, "pointer to 0x123456", "00003456");
+ DoPointerTest("%Lp", ptr, "pointer to 0x123456", "00123456");
+ DoI64Test("%I64p", lptr, "pointer to 0x1234567887654321",
+ "1234567887654321");
+#else
+ Trace("Testing for Non 64 Bit Platforms \n");
+ DoPointerTest("%p", NULL, "NULL", "00000000");
+ DoPointerTest("%p", ptr, "pointer to 0x123456", "00123456");
+ DoPointerTest("%9p", ptr, "pointer to 0x123456", " 00123456");
+ DoPointerTest("%09p", ptr, "pointer to 0x123456", " 00123456");
+ DoPointerTest("%-9p", ptr, "pointer to 0x123456", "00123456 ");
+ DoPointerTest("%+p", ptr, "pointer to 0x123456", "00123456");
+ DoPointerTest("%#p", ptr, "pointer to 0x123456", "0X00123456");
+ DoPointerTest("%lp", ptr, "pointer to 0x123456", "00123456");
+ DoPointerTest("%hp", ptr, "pointer to 0x123456", "00003456");
+ DoPointerTest("%Lp", ptr, "pointer to 0x123456", "00123456");
+ DoI64Test("%I64p", lptr, "pointer to 0x1234567887654321",
+ "1234567887654321");
+#endif
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test4/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf_s/test4/testinfo.dat
new file mode 100644
index 0000000000..f53f784991
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test4/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test4
+Description
+= Tests sprintf_s with pointers
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test6/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf_s/test6/CMakeLists.txt
new file mode 100644
index 0000000000..fce1f204fd
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test6/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test6.cpp
+)
+
+add_executable(paltest_sprintf_test6
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sprintf_test6 coreclrpal)
+
+target_link_libraries(paltest_sprintf_test6
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test6/test6.cpp b/src/pal/tests/palsuite/c_runtime/sprintf_s/test6/test6.cpp
new file mode 100644
index 0000000000..c5fc804071
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test6/test6.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test6.c
+**
+** Purpose: Test #6 for the sprintf_s function. Tests the char specifier (%c).
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sprintf_s.h"
+
+/*
+ * Depends on memcmp and strlen
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ WCHAR wc = (WCHAR) 'c';
+
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+
+ DoCharTest("foo %c", 'b', "foo b");
+ DoCharTest("foo %hc", 'b', "foo b");
+ DoWCharTest("foo %lc", wc, "foo c");
+ DoCharTest("foo %Lc", 'b', "foo b");
+ DoCharTest("foo %I64c", 'b', "foo b");
+ DoCharTest("foo %5c", 'b', "foo b");
+ DoCharTest("foo %.0c", 'b', "foo b");
+ DoCharTest("foo %-5c", 'b', "foo b ");
+ DoCharTest("foo %05c", 'b', "foo 0000b");
+ DoCharTest("foo % c", 'b', "foo b");
+ DoCharTest("foo %#c", 'b', "foo b");
+
+ PAL_Terminate();
+ return PASS;
+}
+
+
+
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test6/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf_s/test6/testinfo.dat
new file mode 100644
index 0000000000..c5b93fc78c
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test6/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test6
+Description
+= Tests sprintf_s with characters
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test7/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf_s/test7/CMakeLists.txt
new file mode 100644
index 0000000000..72a831ec89
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test7/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test7.cpp
+)
+
+add_executable(paltest_sprintf_test7
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sprintf_test7 coreclrpal)
+
+target_link_libraries(paltest_sprintf_test7
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test7/test7.cpp b/src/pal/tests/palsuite/c_runtime/sprintf_s/test7/test7.cpp
new file mode 100644
index 0000000000..fd46ae9674
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test7/test7.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test7.c
+**
+** Purpose: Test #7 for the sprintf_s function. Tests the wide char
+** specifier (%C).
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sprintf_s.h"
+
+/*
+ * Depends on memcmp and strlen
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ WCHAR wb = (WCHAR) 'b';
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoWCharTest("foo %C", wb, "foo b");
+ DoWCharTest("foo %hC", wb, "foo b");
+ DoCharTest("foo %lC", 'c', "foo c");
+ DoWCharTest("foo %LC", wb, "foo b");
+ DoWCharTest("foo %I64C", wb, "foo b");
+ DoWCharTest("foo %5C", wb, "foo b");
+ DoWCharTest("foo %.0C", wb, "foo b");
+ DoWCharTest("foo %-5C", wb, "foo b ");
+ DoWCharTest("foo %05C", wb, "foo 0000b");
+ DoWCharTest("foo % C", wb, "foo b");
+ DoWCharTest("foo %#C", wb, "foo b");
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test7/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf_s/test7/testinfo.dat
new file mode 100644
index 0000000000..647c9d80fd
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test7/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test7
+Description
+= Tests sprintf_s with wide characters
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test8/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf_s/test8/CMakeLists.txt
new file mode 100644
index 0000000000..c9522c1c9d
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test8/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test8.cpp
+)
+
+add_executable(paltest_sprintf_test8
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sprintf_test8 coreclrpal)
+
+target_link_libraries(paltest_sprintf_test8
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test8/test8.cpp b/src/pal/tests/palsuite/c_runtime/sprintf_s/test8/test8.cpp
new file mode 100644
index 0000000000..db02627bb0
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test8/test8.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: test8.c
+**
+** Purpose: Test #8 for the sprintf_s function. Tests the decimal
+** specifier (%d).
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sprintf_s.h"
+
+/*
+ * Depends on memcmp and strlen
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ int neg = -42;
+ int pos = 42;
+ INT64 l = 42;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoNumTest("foo %d", pos, "foo 42");
+ DoNumTest("foo %ld", 0xFFFF, "foo 65535");
+ DoNumTest("foo %hd", 0xFFFF, "foo -1");
+ DoNumTest("foo %Ld", pos, "foo 42");
+ DoI64Test("foo %I64d", l, "42", "foo 42");
+ DoNumTest("foo %3d", pos, "foo 42");
+ DoNumTest("foo %-3d", pos, "foo 42 ");
+ DoNumTest("foo %.1d", pos, "foo 42");
+ DoNumTest("foo %.3d", pos, "foo 042");
+ DoNumTest("foo %03d", pos, "foo 042");
+ DoNumTest("foo %#d", pos, "foo 42");
+ DoNumTest("foo %+d", pos, "foo +42");
+ DoNumTest("foo % d", pos, "foo 42");
+ DoNumTest("foo %+d", neg, "foo -42");
+ DoNumTest("foo % d", neg, "foo -42");
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test8/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf_s/test8/testinfo.dat
new file mode 100644
index 0000000000..524834e53e
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test8/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test8
+Description
+= Tests sprintf_s with decimal numbers
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test9/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sprintf_s/test9/CMakeLists.txt
new file mode 100644
index 0000000000..e76fed4784
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test9/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test9.cpp
+)
+
+add_executable(paltest_sprintf_test9
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sprintf_test9 coreclrpal)
+
+target_link_libraries(paltest_sprintf_test9
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test9/test9.cpp b/src/pal/tests/palsuite/c_runtime/sprintf_s/test9/test9.cpp
new file mode 100644
index 0000000000..2e1c78ce68
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test9/test9.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: test9.c
+**
+** Purpose: Test #9 for the sprintf_s function. Tests the integer
+** specifier (%i).
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sprintf_s.h"
+
+/*
+ * Depends on memcmp and strlen
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ int neg = -42;
+ int pos = 42;
+ INT64 l = 42;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+
+ DoNumTest("foo %i", pos, "foo 42");
+ DoNumTest("foo %li", 0xFFFF, "foo 65535");
+ DoNumTest("foo %hi", 0xFFFF, "foo -1");
+ DoNumTest("foo %Li", pos, "foo 42");
+ DoI64Test("foo %I64i", l, "42", "foo 42");
+ DoNumTest("foo %3i", pos, "foo 42");
+ DoNumTest("foo %-3i", pos, "foo 42 ");
+ DoNumTest("foo %.1i", pos, "foo 42");
+ DoNumTest("foo %.3i", pos, "foo 042");
+ DoNumTest("foo %03i", pos, "foo 042");
+ DoNumTest("foo %#i", pos, "foo 42");
+ DoNumTest("foo %+i", pos, "foo +42");
+ DoNumTest("foo % i", pos, "foo 42");
+ DoNumTest("foo %+i", neg, "foo -42");
+ DoNumTest("foo % i", neg, "foo -42");
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/c_runtime/sprintf_s/test9/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sprintf_s/test9/testinfo.dat
new file mode 100644
index 0000000000..7c51443a3d
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sprintf_s/test9/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 = C Runtime
+Function = sprintf_s
+Name = Positive Test for sprintf_s
+TYPE = DEFAULT
+EXE1 = test9
+Description
+= Tests sprintf_s with integer numbers
diff --git a/src/pal/tests/palsuite/c_runtime/sqrt/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sqrt/test1/CMakeLists.txt
index 4347c44e46..d4aefe6ca8 100644
--- a/src/pal/tests/palsuite/c_runtime/sqrt/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/sqrt/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_sqrt_test1
diff --git a/src/pal/tests/palsuite/c_runtime/sqrt/test1/test1.c b/src/pal/tests/palsuite/c_runtime/sqrt/test1/test1.cpp
index 62d2251d61..62d2251d61 100644
--- a/src/pal/tests/palsuite/c_runtime/sqrt/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/sqrt/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/_makepath/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sqrtf/CMakeLists.txt
index f6aa0cb2d9..f6aa0cb2d9 100644
--- a/src/pal/tests/palsuite/c_runtime/_makepath/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/sqrtf/CMakeLists.txt
diff --git a/src/pal/tests/palsuite/c_runtime/sqrtf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sqrtf/test1/CMakeLists.txt
new file mode 100644
index 0000000000..96b6ffa998
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sqrtf/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.c
+)
+
+add_executable(paltest_sqrtf_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sqrtf_test1 coreclrpal)
+
+target_link_libraries(paltest_sqrtf_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sqrtf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/sqrtf/test1/test1.c
new file mode 100644
index 0000000000..cb1ac9e7df
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sqrtf/test1/test1.c
@@ -0,0 +1,122 @@
+// Licensed to the .NET Foundation under one or more 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: test1.c
+**
+** Purpose: Call the sqrtf function on a positive value, a positive value
+** with a decimal and on the maxium possible float value.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this
+// is slightly too accurate when writing tests meant to run against libm implementations
+// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get.
+//
+// The tests themselves will take PAL_EPSILON and adjust it according to the expected result
+// so that the delta used for comparison will compare the most significant digits and ignore
+// any digits that are outside the double precision range (6-9 digits).
+
+// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON
+// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use
+// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10.
+#define PAL_EPSILON 4.76837158e-07
+
+#define PAL_NAN sqrtf(-1.0f)
+#define PAL_POSINF -logf(0.0f)
+#define PAL_NEGINF logf(0.0f)
+
+/**
+ * Helper test structure
+ */
+struct test
+{
+ float value; /* value to test the function with */
+ float expected; /* expected result */
+ float variance; /* maximum delta between the expected and actual result */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl validate(float value, float expected, float variance)
+{
+ float result = sqrtf(value);
+
+ /*
+ * The test is valid when the difference between result
+ * and expected is less than or equal to variance
+ */
+ float delta = fabsf(result - expected);
+
+ if (delta > variance)
+ {
+ Fail("sqrtf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, expected);
+ }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl validate_isnan(float value)
+{
+ float result = sqrtf(value);
+
+ if (!_isnanf(result))
+ {
+ Fail("sqrtf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, PAL_NAN);
+ }
+}
+
+int __cdecl main(int argc, char **argv)
+{
+ struct test tests[] =
+ {
+ /* value expected variance */
+ { 0.318309886f, 0.564189584f, PAL_EPSILON }, // value: 1 / pi
+ { 0.434294482f, 0.659010229f, PAL_EPSILON }, // value: log10f(e)
+ { 0.636619772f, 0.797884561f, PAL_EPSILON }, // value: 2 / pi
+ { 0.693147181f, 0.832554611f, PAL_EPSILON }, // value: ln(2)
+ { 0.707106781f, 0.840896415f, PAL_EPSILON }, // value: 1 / sqrtf(2)
+ { 0.785398163f, 0.886226925f, PAL_EPSILON }, // value: pi / 4
+ { 1, 1, PAL_EPSILON * 10 },
+ { 1.12837917f, 1.06225193f, PAL_EPSILON * 10 }, // value: 2 / sqrtf(pi)
+ { 1.41421356f, 1.18920712f, PAL_EPSILON * 10 }, // value: sqrtf(2)
+ { 1.44269504f, 1.20112241f, PAL_EPSILON * 10 }, // value: logf2(e)
+ { 1.57079633f, 1.25331414f, PAL_EPSILON * 10 }, // value: pi / 2
+ { 2.30258509f, 1.51742713f, PAL_EPSILON * 10 }, // value: ln(10)
+ { 2.71828183f, 1.64872127f, PAL_EPSILON * 10 }, // value: e
+ { 3.14159265f, 1.77245385F, PAL_EPSILON * 10 }, // value: pi
+ };
+
+ /* PAL initialization */
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ validate(-0.0f, -0.0f, PAL_EPSILON);
+ validate( 0.0f, 0.0f, PAL_EPSILON);
+
+ for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++)
+ {
+ validate(tests[i].value, tests[i].expected, tests[i].variance);
+ validate_isnan(-tests[i].value);
+ }
+
+ validate_isnan(PAL_NAN);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sqrtf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sqrtf/test1/testinfo.dat
new file mode 100644
index 0000000000..00d8ab2e43
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sqrtf/test1/testinfo.dat
@@ -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.
+
+Version = 1.0
+Section = C Runtime
+Function = sqrtf
+Name = Call sqrtf on positive values and zero.
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Call the sqrtf function on a positive value, a positive value
+= with a decimal and on the maxium possible float value.
+
+
+
+
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/sscanf.h b/src/pal/tests/palsuite/c_runtime/sscanf/sscanf.h
deleted file mode 100644
index 675a67aed2..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/sscanf.h
+++ /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.
-
-/*============================================================================
-**
-** Source: sscanf.h
-**
-** Purpose: Contains common testing functions for sscanf.h
-**
-**
-**==========================================================================*/
-
-#ifndef __SSCANF_H__
-#define __SSCANF_H__
-
-void DoVoidTest(char *inputstr, char *formatstr)
-{
- char buf[256] = { 0 };
- int i;
- int ret;
-
- ret = sscanf(inputstr, formatstr, buf);
- if (ret != 0)
- {
- Fail("ERROR: Expected sscanf to return 0, got %d.\n"
- "Using \"%s\" in \"%s\".\n", ret, inputstr, formatstr);
- }
-
- for (i=0; i<256; i++)
- {
- if (buf[i] != 0)
- {
- Fail("ERROR: Parameter unexpectedly modified scanning \"%s\" "
- "using \"%s\".\n", inputstr, formatstr);
- }
- }
-
-}
-
-void DoStrTest(char *inputstr, char *formatstr, char *checkstr)
-{
- char buf[256] = { 0 };
- int ret;
-
- ret = sscanf(inputstr, formatstr, buf);
- if (ret != 1)
- {
- Fail("ERROR: Expected sscanf to return 1, got %d.\n"
- "Using \"%s\" in \"%s\".\n", ret, inputstr, formatstr);
- }
-
- if (memcmp(checkstr, buf, strlen(checkstr) + 1) != 0)
- {
- Fail("ERROR: scanned string incorrectly from \"%s\" using \"%s\".\n"
- "Expected \"%s\", got \"%s\".\n", inputstr, formatstr, checkstr,
- buf);
- }
-
-}
-
-void DoWStrTest(char *inputstr, char *formatstr, WCHAR *checkstr)
-{
- WCHAR buf[256] = { 0 };
- int ret;
-
- ret = sscanf(inputstr, formatstr, buf);
- if (ret != 1)
- {
- Fail("ERROR: Expected sscanf to return 1, got %d.\n"
- "Using \"%s\" in \"%s\".\n", ret, inputstr, formatstr);
- }
-
- if (memcmp(checkstr, buf, wcslen(checkstr)*2 + 2) != 0)
- {
- Fail("ERROR: scanned wide string incorrectly from \"%s\" using \"%s\".\n"
- "Expected \"%s\", got \"%s\".\n", inputstr, formatstr,
- convertC(checkstr), convertC(buf));
- }
-
-}
-
-void DoNumTest(char *inputstr, char *formatstr, int checknum)
-{
- int num;
- int ret;
-
- ret = sscanf(inputstr, formatstr, &num);
- if (ret != 1)
- {
- Fail("ERROR: Expected sscanf to return 1, got %d.\n"
- "Using \"%s\" in \"%s\".\n", ret, inputstr, formatstr);
- }
-
- if (checknum != num)
- {
- Fail("ERROR: scanned number incorrectly from \"%s\" using \"%s\".\n"
- "Expected %d, got %d.\n", inputstr, formatstr, checknum, num);
- }
-}
-
-void DoShortNumTest(char *inputstr, char *formatstr, short checknum)
-{
- short num;
- int ret;
-
- ret = sscanf(inputstr, formatstr, &num);
- if (ret != 1)
- {
- Fail("ERROR: Expected sscanf to return 1, got %d.\n"
- "Using \"%s\" in \"%s\".\n", ret, inputstr, formatstr);
- }
-
- if (checknum != num)
- {
- Fail("ERROR: scanned number incorrectly from \"%s\" using \"%s\".\n"
- "Expected %hd, got %hd.\n", inputstr, formatstr, checknum, num);
- }
-}
-
-void DoI64NumTest(char *inputstr, char *formatstr, INT64 checknum)
-{
- char buf[256];
- char check[256];
- INT64 num;
- int ret;
-
- ret = sscanf(inputstr, formatstr, &num);
- if (ret != 1)
- {
- Fail("ERROR: Expected sscanf to return 1, got %d.\n"
- "Using \"%s\" in \"%s\".\n", ret, inputstr, formatstr);
- }
-
- if (checknum != num)
- {
- sprintf(buf, "%I64d", num);
- sprintf(check, "%I64d", checknum);
- Fail("ERROR: scanned I64 number incorrectly from \"%s\" using \"%s\".\n"
- "Expected %s, got %s.\n", inputstr, formatstr, check, buf);
- }
-}
-
-void DoCharTest(char *inputstr, char *formatstr, char* checkchars, int numchars)
-{
- char buf[256];
- int ret;
- int i;
-
- for (i=0; i<256; i++)
- buf[i] = (char)-1;
-
- ret = sscanf(inputstr, formatstr, buf);
- if (ret != 1)
- {
- Fail("ERROR: Expected sscanf to return 1, got %d.\n"
- "Using \"%s\" in \"%s\".\n", ret, inputstr, formatstr);
- }
-
- if (memcmp(buf, checkchars, numchars) != 0)
- {
- buf[numchars] = 0;
-
- Fail("ERROR: scanned character(s) incorrectly from \"%s\" using \"%s\".\n"
- "Expected %s, got %s.\n", inputstr, formatstr, checkchars,
- buf);
- }
-
- if (buf[numchars] != (char)-1)
- {
- Fail("ERROR: overflow occurred in scanning character(s) from \"%s\" "
- "using \"%s\".\nExpected %d character(s)\n", inputstr, formatstr,
- numchars);
- }
-}
-
-void DoWCharTest(char *inputstr, char *formatstr, WCHAR* checkchars, int numchars)
-{
- WCHAR buf[256];
- int ret;
- int i;
-
- for (i=0; i<256; i++)
- buf[i] = (WCHAR)-1;
-
- ret = sscanf(inputstr, formatstr, buf);
- if (ret != 1)
- {
- Fail("ERROR: Expected sscanf to return 1, got %d.\n"
- "Using \"%s\" in \"%s\".\n", ret, inputstr, formatstr);
- }
-
- if (memcmp(buf, checkchars, numchars) != 0)
- {
- buf[numchars] = 0;
-
- Fail("ERROR: scanned wide character(s) incorrectly from \"%s\" using \"%s\".\n"
- "Expected %s, got %s.\n", inputstr, formatstr, convertC(checkchars),
- convertC(buf));
- }
-
- if (buf[numchars] != (WCHAR)-1)
- {
- Fail("ERROR: overflow occurred in scanning wide character(s) from \"%s\" "
- "using \"%s\".\nExpected %d character(s)\n", inputstr, formatstr,
- numchars);
- }
-}
-
-
-void DoFloatTest(char *inputstr, char *formatstr, float checkval)
-{
- char buf[256] = { 0 };
- float val;
- int ret;
- int i;
-
- for (i=0; i<256; i++)
- buf[i] = (char)-1;
-
- ret = sscanf(inputstr, formatstr, buf);
- val = *(float*)buf;
-
- if (ret != 1)
- {
- Fail("ERROR: Expected sscanf to return 1, got %d.\n"
- "Using \"%s\" in \"%s\".\n", ret, inputstr, formatstr);
- }
-
- if (val != checkval)
- {
- Fail("ERROR: scanned float incorrectly from \"%s\" using \"%s\".\n"
- "Expected \"%f\", got \"%f\".\n", inputstr, formatstr, checkval,
- val);
- }
-
- if (buf[4] != (char)-1)
- {
- Fail("ERROR: overflow occurred in scanning float from \"%s\" "
- "using \"%s\".\n", inputstr, formatstr);
-
- }
-}
-
-
-#endif
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf/test1/CMakeLists.txt
deleted file mode 100644
index dce6d1de87..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test1/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test1.c
-)
-
-add_executable(paltest_sscanf_test1
- ${SOURCES}
-)
-
-add_dependencies(paltest_sscanf_test1 coreclrpal)
-
-target_link_libraries(paltest_sscanf_test1
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/sscanf/test1/test1.c
deleted file mode 100644
index c6f66a1d20..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test1/test1.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test1.c
-**
-** Purpose: General test of sscanf
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sscanf.h"
-
-
-int __cdecl main(int argc, char *argv[])
-{
- int num;
- int ret;
-
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
-
- DoVoidTest("foo bar", "foo ");
- DoVoidTest("foo bar", "baz");
- DoVoidTest("foo bar", "foo %*s");
-
- DoStrTest("foo % bar", "foo %% %s", "bar");
- DoStrTest("foo bar baz", "foo %bar %s", "baz");
-
- DoVoidTest("foo bar baz", "foo % bar %s");
- DoVoidTest("foo baz bar", "foo% baz %s");
-
- ret = sscanf("foo bar baz", "foo bar %n", &num);
- if (ret != 0 || num != 8)
- {
- Fail("ERROR: Got incorrect values in scanning \"%s\" using \"%s\".\n"
- "Expected to get a value of %d with return value of %d, "
- "got %d with return %d\n", "foo bar baz", "foo bar %n", 8, 0,
- num, ret);
-
- }
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf/test1/testinfo.dat
deleted file mode 100644
index ef33ba9e13..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test1/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sscanf
-Name = Positive Test for sscanf
-TYPE = DEFAULT
-EXE1 = test1
-Description
-= General test of sscanf
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test10/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf/test10/CMakeLists.txt
deleted file mode 100644
index c27e4ce33a..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test10/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test10.c
-)
-
-add_executable(paltest_sscanf_test10
- ${SOURCES}
-)
-
-add_dependencies(paltest_sscanf_test10 coreclrpal)
-
-target_link_libraries(paltest_sscanf_test10
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test10/test10.c b/src/pal/tests/palsuite/c_runtime/sscanf/test10/test10.c
deleted file mode 100644
index aac5be43ae..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test10/test10.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test10.c
-**
-** Purpose: Tests sscanf with wide charactersn
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sscanf.h"
-
-int __cdecl main(int argc, char *argv[])
-{
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
- DoWCharTest("1234d", "%C", convert("1"), 1);
- DoWCharTest("1234d", "%C", convert("1"), 1);
- DoWCharTest("abc", "%2C", convert("ab"), 2);
- DoWCharTest(" ab", "%C", convert(" "), 1);
- DoCharTest("ab", "%hC", "a", 1);
- DoWCharTest("ab", "%lC", convert("a"), 1);
- DoWCharTest("ab", "%LC", convert("a"), 1);
- DoWCharTest("ab", "%I64C", convert("a"), 1);
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test10/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf/test10/testinfo.dat
deleted file mode 100644
index 7e854ed235..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test10/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sscanf
-Name = Positive Test for sscanf
-TYPE = DEFAULT
-EXE1 = test10
-Description
-= Tests sscanf with wide characters
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test11/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf/test11/CMakeLists.txt
deleted file mode 100644
index 7570e990bf..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test11/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test11.c
-)
-
-add_executable(paltest_sscanf_test11
- ${SOURCES}
-)
-
-add_dependencies(paltest_sscanf_test11 coreclrpal)
-
-target_link_libraries(paltest_sscanf_test11
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test11/test11.c b/src/pal/tests/palsuite/c_runtime/sscanf/test11/test11.c
deleted file mode 100644
index 0e3db6cca0..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test11/test11.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test11.c
-**
-** Purpose: Tests sscanf with strings
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sscanf.h"
-
-int __cdecl main(int argc, char *argv[])
-{
-
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
- DoStrTest("foo bar", "foo %s", "bar");
- DoStrTest("foo bar", "foo %2s", "ba");
- DoStrTest("foo bar", "foo %hs", "bar");
- DoWStrTest("foo bar", "foo %ls", convert("bar"));
- DoStrTest("foo bar", "foo %Ls", "bar");
- DoStrTest("foo bar", "foo %I64s", "bar");
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test11/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf/test11/testinfo.dat
deleted file mode 100644
index 60f5cc46a4..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test11/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sscanf
-Name = Positive Test for sscanf
-TYPE = DEFAULT
-EXE1 = test11
-Description
-= Tests sscanf with strings
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test12/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf/test12/CMakeLists.txt
deleted file mode 100644
index b6509e46d4..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test12/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test12.c
-)
-
-add_executable(paltest_sscanf_test12
- ${SOURCES}
-)
-
-add_dependencies(paltest_sscanf_test12 coreclrpal)
-
-target_link_libraries(paltest_sscanf_test12
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test12/test12.c b/src/pal/tests/palsuite/c_runtime/sscanf/test12/test12.c
deleted file mode 100644
index f800e452c0..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test12/test12.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test12.c
-**
-** Purpose: Tests sscanf with wide strings
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sscanf.h"
-
-int __cdecl main(int argc, char *argv[])
-{
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
- DoWStrTest("foo bar", "foo %S", convert("bar"));
- DoWStrTest("foo bar", "foo %2S", convert("ba"));
- DoStrTest("foo bar", "foo %hS", "bar");
- DoWStrTest("foo bar", "foo %lS", convert("bar"));
- DoWStrTest("foo bar", "foo %LS", convert("bar"));
- DoWStrTest("foo bar", "foo %I64S", convert("bar"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test12/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf/test12/testinfo.dat
deleted file mode 100644
index 3c453bf53a..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test12/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sscanf
-Name = Positive Test for sscanf
-TYPE = DEFAULT
-EXE1 = test12
-Description
-= Tests sscanf with wide strings
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test13/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf/test13/CMakeLists.txt
deleted file mode 100644
index 6fb4094f00..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test13/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test13.c
-)
-
-add_executable(paltest_sscanf_test13
- ${SOURCES}
-)
-
-add_dependencies(paltest_sscanf_test13 coreclrpal)
-
-target_link_libraries(paltest_sscanf_test13
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test13/test13.c b/src/pal/tests/palsuite/c_runtime/sscanf/test13/test13.c
deleted file mode 100644
index 314604e3ac..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test13/test13.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test13.c
-**
-** Purpose: Tests sscanf with floats (decimal notation)
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sscanf.h"
-
-int __cdecl main(int argc, char *argv[])
-{
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
- DoFloatTest("123.0", "%f", 123.0f);
- DoFloatTest("123.0", "%2f", 12.0f);
- DoFloatTest("10E1", "%f", 100.0f);
- DoFloatTest("-12.01e-2", "%f", -0.1201f);
- DoFloatTest("+12.01e-2", "%f", 0.1201f);
- DoFloatTest("-12.01e+2", "%f", -1201.0f);
- DoFloatTest("+12.01e+2", "%f", 1201.0f);
- DoFloatTest("1234567890.0123456789f", "%f", 1234567936);
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test13/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf/test13/testinfo.dat
deleted file mode 100644
index 1c4c2fc26e..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test13/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sscanf
-Name = Positive Test for sscanf
-TYPE = DEFAULT
-EXE1 = test13
-Description
-= Tests sscanf with floats (decimal notation)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test14/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf/test14/CMakeLists.txt
deleted file mode 100644
index 373a75fbda..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test14/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test14.c
-)
-
-add_executable(paltest_sscanf_test14
- ${SOURCES}
-)
-
-add_dependencies(paltest_sscanf_test14 coreclrpal)
-
-target_link_libraries(paltest_sscanf_test14
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test14/test14.c b/src/pal/tests/palsuite/c_runtime/sscanf/test14/test14.c
deleted file mode 100644
index d1291a3b65..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test14/test14.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test14.c
-**
-** Purpose: Tests sscanf with floats (exponential notation, lowercase)
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sscanf.h"
-
-int __cdecl main(int argc, char *argv[])
-{
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
- DoFloatTest("123.0", "%e", 123.0f);
- DoFloatTest("123.0", "%2e", 12.0f);
- DoFloatTest("10E1", "%e", 100.0f);
- DoFloatTest("-12.01e-2", "%e", -0.1201f);
- DoFloatTest("+12.01e-2", "%e", 0.1201f);
- DoFloatTest("-12.01e+2", "%e", -1201.0f);
- DoFloatTest("+12.01e+2", "%e", 1201.0f);
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test14/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf/test14/testinfo.dat
deleted file mode 100644
index 97db6e4ffd..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test14/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sscanf
-Name = Positive Test for sscanf
-TYPE = DEFAULT
-EXE1 = test14
-Description
-= Tests sscanf with floats (exponential notation, lowercase)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test15/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf/test15/CMakeLists.txt
deleted file mode 100644
index d500901782..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test15/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test15.c
-)
-
-add_executable(paltest_sscanf_test15
- ${SOURCES}
-)
-
-add_dependencies(paltest_sscanf_test15 coreclrpal)
-
-target_link_libraries(paltest_sscanf_test15
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test15/test15.c b/src/pal/tests/palsuite/c_runtime/sscanf/test15/test15.c
deleted file mode 100644
index fa51467d85..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test15/test15.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test15.c
-**
-** Purpose: Tests sscanf with floats (exponential notation, uppercase
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sscanf.h"
-
-int __cdecl main(int argc, char *argv[])
-{
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
- DoFloatTest("123.0", "%E", 123.0f);
- DoFloatTest("123.0", "%2E", 12.0f);
- DoFloatTest("10E1", "%E", 100.0f);
- DoFloatTest("-12.01e-2", "%E", -0.1201f);
- DoFloatTest("+12.01e-2", "%E", 0.1201f);
- DoFloatTest("-12.01e+2", "%E", -1201.0f);
- DoFloatTest("+12.01e+2", "%E", 1201.0f);
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test15/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf/test15/testinfo.dat
deleted file mode 100644
index 30c2cf4b30..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test15/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sscanf
-Name = Positive Test for sscanf
-TYPE = DEFAULT
-EXE1 = test15
-Description
-= Tests sscanf with floats (exponential notation, uppercase)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test16/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf/test16/CMakeLists.txt
deleted file mode 100644
index c5e18ec061..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test16/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test16.c
-)
-
-add_executable(paltest_sscanf_test16
- ${SOURCES}
-)
-
-add_dependencies(paltest_sscanf_test16 coreclrpal)
-
-target_link_libraries(paltest_sscanf_test16
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test16/test16.c b/src/pal/tests/palsuite/c_runtime/sscanf/test16/test16.c
deleted file mode 100644
index 787b72ed0a..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test16/test16.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test16.c
-**
-** Purpose:Tests sscanf with floats (compact notation, lowercase)
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sscanf.h"
-
-int __cdecl main(int argc, char *argv[])
-{
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
- DoFloatTest("123.0", "%g", 123.0f);
- DoFloatTest("123.0", "%2g", 12.0f);
- DoFloatTest("10E1", "%g", 100.0f);
- DoFloatTest("-12.01e-2", "%g", -0.1201f);
- DoFloatTest("+12.01e-2", "%g", 0.1201f);
- DoFloatTest("-12.01e+2", "%g", -1201.0f);
- DoFloatTest("+12.01e+2", "%g", 1201.0f);
- DoFloatTest("1234567890.0123456789g", "%g", 1234567936);
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test16/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf/test16/testinfo.dat
deleted file mode 100644
index 2c1dd42b70..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test16/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sscanf
-Name = Positive Test for sscanf
-TYPE = DEFAULT
-EXE1 = test16
-Description
-= Tests sscanf with floats (compact notation, lowercase)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test17/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf/test17/CMakeLists.txt
deleted file mode 100644
index 7d908ab832..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test17/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test17.c
-)
-
-add_executable(paltest_sscanf_test17
- ${SOURCES}
-)
-
-add_dependencies(paltest_sscanf_test17 coreclrpal)
-
-target_link_libraries(paltest_sscanf_test17
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test17/test17.c b/src/pal/tests/palsuite/c_runtime/sscanf/test17/test17.c
deleted file mode 100644
index c0dfd1699c..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test17/test17.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test17.c
-**
-** Purpose: Tests sscanf with floats (compact notation, uppercase)
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sscanf.h"
-
-int __cdecl main(int argc, char *argv[])
-{
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
- DoFloatTest("123.0", "%G", 123.0f);
- DoFloatTest("123.0", "%2G", 12.0f);
- DoFloatTest("10E1", "%G", 100.0f);
- DoFloatTest("-12.01e-2", "%G", -0.1201f);
- DoFloatTest("+12.01e-2", "%G", 0.1201f);
- DoFloatTest("-12.01e+2", "%G", -1201.0f);
- DoFloatTest("+12.01e+2", "%G", 1201.0f);
- DoFloatTest("1234567890.0123456789G", "%G", 1234567936);
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test17/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf/test17/testinfo.dat
deleted file mode 100644
index e23be8541e..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test17/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sscanf
-Name = Positive Test for sscanf
-TYPE = DEFAULT
-EXE1 = test17
-Description
-= Tests sscanf with floats (compact notation, uppercase)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf/test2/CMakeLists.txt
deleted file mode 100644
index 571d773a88..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test2/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test2.c
-)
-
-add_executable(paltest_sscanf_test2
- ${SOURCES}
-)
-
-add_dependencies(paltest_sscanf_test2 coreclrpal)
-
-target_link_libraries(paltest_sscanf_test2
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test2/test2.c b/src/pal/tests/palsuite/c_runtime/sscanf/test2/test2.c
deleted file mode 100644
index 1221124e3a..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test2/test2.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test2.c
-**
-** Purpose: Test to see if sscanf handles whitespace correctly
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sscanf.h"
-
-
-/*
- * Tests out how it handles whitespace. Seems to accept anything that qualifies
- * as isspace (space, tab, vertical tab, line feed, carriage return and form
- * feed), even if it says it only wants spaces tabs and newlines.
- */
-
-int __cdecl main(int argc, char *argv[])
-{
-
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
- DoStrTest("foo bar", "foo %s", "bar");
- DoStrTest("foo\tbar", "foo %s", "bar");
- DoStrTest("foo\nbar", "foo %s", "bar");
- DoStrTest("foo\rbar", "foo %s", "bar");
- DoStrTest("foo\vbar", "foo %s", "bar");
- DoStrTest("foo\fbar", "foo %s", "bar");
- DoStrTest("foo \t\n\r\v\fbar", "foo %s", "bar");
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test2/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf/test2/testinfo.dat
deleted file mode 100644
index f5ee4b52d4..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test2/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sscanf
-Name = Positive Test for sscanf
-TYPE = DEFAULT
-EXE1 = test2
-Description
-= Test to see if sscanf handles whitespace correctly
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf/test3/CMakeLists.txt
deleted file mode 100644
index ced8d5f8da..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test3/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test3.c
-)
-
-add_executable(paltest_sscanf_test3
- ${SOURCES}
-)
-
-add_dependencies(paltest_sscanf_test3 coreclrpal)
-
-target_link_libraries(paltest_sscanf_test3
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test3/test3.c b/src/pal/tests/palsuite/c_runtime/sscanf/test3/test3.c
deleted file mode 100644
index 9d18991070..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test3/test3.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test3.c
-**
-** Purpose: Tests sscanf with bracketed set strings
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sscanf.h"
-
-int __cdecl main(int argc, char *argv[])
-{
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
- DoStrTest("bar1", "%[a-z]", "bar");
- DoStrTest("bar1", "%[z-a]", "bar");
- DoStrTest("bar1", "%[ab]", "ba");
- DoStrTest("bar1", "%[ar1b]", "bar1");
- DoStrTest("bar1", "%[^4]", "bar1");
- DoStrTest("bar1", "%[^4a]", "b");
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test3/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf/test3/testinfo.dat
deleted file mode 100644
index c38a498225..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test3/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sscanf
-Name = Positive Test for sscanf
-TYPE = DEFAULT
-EXE1 = test3
-Description
-= Tests sscanf with bracketed set strings
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test4/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf/test4/CMakeLists.txt
deleted file mode 100644
index 3e70d6dae2..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test4/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test4.c
-)
-
-add_executable(paltest_sscanf_test4
- ${SOURCES}
-)
-
-add_dependencies(paltest_sscanf_test4 coreclrpal)
-
-target_link_libraries(paltest_sscanf_test4
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test4/test4.c b/src/pal/tests/palsuite/c_runtime/sscanf/test4/test4.c
deleted file mode 100644
index dd0538bcfe..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test4/test4.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test4.c
-**
-** Purpose: Tests sscanf with decimal numbers
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sscanf.h"
-
-
-int __cdecl main(int argc, char *argv[])
-{
- int n65535 = 65535; /* Walkaround compiler strictness */
-
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
- DoNumTest("1234d", "%d", 1234);
- DoNumTest("1234d", "%2d", 12);
- DoNumTest("-1", "%d", -1);
- DoNumTest("0x1234", "%d", 0);
- DoNumTest("012", "%d", 12);
- DoShortNumTest("-1", "%hd", n65535);
- DoShortNumTest("65536", "%hd", 0);
- DoNumTest("-1", "%ld", -1);
- DoNumTest("65536", "%ld", 65536);
- DoNumTest("-1", "%Ld", -1);
- DoNumTest("65536", "%Ld", 65536);
- DoI64NumTest("4294967296", "%I64d", I64(4294967296));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test4/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf/test4/testinfo.dat
deleted file mode 100644
index 868056a6a5..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test4/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sscanf
-Name = Positive Test for sscanf
-TYPE = DEFAULT
-EXE1 = test4
-Description
-= Tests sscanf with decimal numbers
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test5/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf/test5/CMakeLists.txt
deleted file mode 100644
index 391e51baa2..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test5/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test5.c
-)
-
-add_executable(paltest_sscanf_test5
- ${SOURCES}
-)
-
-add_dependencies(paltest_sscanf_test5 coreclrpal)
-
-target_link_libraries(paltest_sscanf_test5
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test5/test5.c b/src/pal/tests/palsuite/c_runtime/sscanf/test5/test5.c
deleted file mode 100644
index 0d45248af3..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test5/test5.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test5.c
-**
-** Purpose: Tests sscanf with integer numbers
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sscanf.h"
-
-int __cdecl main(int argc, char *argv[])
-{
- int n65535 = 65535; /* Walkaround compiler strictness */
-
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
- DoNumTest("1234d", "%i", 1234);
- DoNumTest("1234d", "%2i", 12);
- DoNumTest("-1", "%i", -1);
- DoNumTest("0x1234", "%i", 0x1234);
- DoNumTest("012", "%i", 10);
- DoShortNumTest("-1", "%hi", n65535);
- DoShortNumTest("65536", "%hi", 0);
- DoNumTest("-1", "%li", -1);
- DoNumTest("65536", "%li", 65536);
- DoNumTest("-1", "%Li", -1);
- DoNumTest("65536", "%Li", 65536);
- DoI64NumTest("4294967296", "%I64i", I64(4294967296));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test5/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf/test5/testinfo.dat
deleted file mode 100644
index 8678dc8f5a..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test5/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sscanf
-Name = Positive Test for sscanf
-TYPE = DEFAULT
-EXE1 = test5
-Description
-= Tests sscanf with integer numbers
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test6/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf/test6/CMakeLists.txt
deleted file mode 100644
index c0b21bfd0d..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test6/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test6.c
-)
-
-add_executable(paltest_sscanf_test6
- ${SOURCES}
-)
-
-add_dependencies(paltest_sscanf_test6 coreclrpal)
-
-target_link_libraries(paltest_sscanf_test6
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test6/test6.c b/src/pal/tests/palsuite/c_runtime/sscanf/test6/test6.c
deleted file mode 100644
index c45ea31b04..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test6/test6.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test6.c
-**
-** Purpose: Tests sscanf with octal numbers
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sscanf.h"
-
-int __cdecl main(int argc, char *argv[])
-{
- int n65535 = 65535; /* Walkaround compiler strictness */
-
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
- DoNumTest("1234d", "%o", 668);
- DoNumTest("1234d", "%2o", 10);
- DoNumTest("-1", "%o", -1);
- DoNumTest("0x1234", "%o", 0);
- DoNumTest("012", "%o", 10);
- DoShortNumTest("-1", "%ho", n65535);
- DoShortNumTest("200000", "%ho", 0);
- DoNumTest("-1", "%lo", -1);
- DoNumTest("200000", "%lo", 65536);
- DoNumTest("-1", "%Lo", -1);
- DoNumTest("200000", "%Lo", 65536);
- DoI64NumTest("40000000000", "%I64o", I64(4294967296));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test6/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf/test6/testinfo.dat
deleted file mode 100644
index b2547a776a..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test6/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sscanf
-Name = Positive Test for sscanf
-TYPE = DEFAULT
-EXE1 = test6
-Description
-= Tests sscanf with octal numbers
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test7/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf/test7/CMakeLists.txt
deleted file mode 100644
index bcbd268011..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test7/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test7.c
-)
-
-add_executable(paltest_sscanf_test7
- ${SOURCES}
-)
-
-add_dependencies(paltest_sscanf_test7 coreclrpal)
-
-target_link_libraries(paltest_sscanf_test7
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test7/test7.c b/src/pal/tests/palsuite/c_runtime/sscanf/test7/test7.c
deleted file mode 100644
index 0899671d64..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test7/test7.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test7.c
-**
-** Purpose: Tests sscanf with hex numbers (lowercase)
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sscanf.h"
-
-int __cdecl main(int argc, char *argv[])
-{
- int n65535 = 65535; /* Walkaround compiler strictness */
-
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
- DoNumTest("1234i", "%x", 0x1234);
- DoNumTest("1234i", "%2x", 0x12);
- DoNumTest("-1", "%x", -1);
- DoNumTest("0x1234", "%x", 0x1234);
- DoNumTest("012", "%x", 0x12);
- DoShortNumTest("-1", "%hx", n65535);
- DoShortNumTest("10000", "%hx", 0);
- DoNumTest("-1", "%lx", -1);
- DoNumTest("10000", "%lx", 65536);
- DoNumTest("-1", "%Lx", -1);
- DoNumTest("10000", "%Lx", 65536);
- DoI64NumTest("100000000", "%I64x", I64(4294967296));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test7/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf/test7/testinfo.dat
deleted file mode 100644
index 614333e650..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test7/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sscanf
-Name = Positive Test for sscanf
-TYPE = DEFAULT
-EXE1 = test7
-Description
-= Tests sscanf with hex numbers (lowercase)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test8/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf/test8/CMakeLists.txt
deleted file mode 100644
index 211e9e4df6..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test8/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test8.c
-)
-
-add_executable(paltest_sscanf_test8
- ${SOURCES}
-)
-
-add_dependencies(paltest_sscanf_test8 coreclrpal)
-
-target_link_libraries(paltest_sscanf_test8
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test8/test8.c b/src/pal/tests/palsuite/c_runtime/sscanf/test8/test8.c
deleted file mode 100644
index 53252f8929..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test8/test8.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test8.c
-**
-** Purpose:Tests sscanf with unsigned number
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sscanf.h"
-
-int __cdecl main(int argc, char *argv[])
-{
- int n65535 = 65535; /* Walkaround compiler strictness */
-
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
- DoNumTest("1234d", "%u", 1234);
- DoNumTest("1234d", "%2u", 12);
- DoNumTest("-1", "%u", -1);
- DoNumTest("0x1234", "%u", 0);
- DoNumTest("012", "%u", 12);
- DoShortNumTest("-1", "%hu", n65535);
- DoShortNumTest("65536", "%hu", 0);
- DoNumTest("-1", "%lu", -1);
- DoNumTest("65536", "%lu", 65536);
- DoNumTest("-1", "%Lu", -1);
- DoNumTest("65536", "%Lu", 65536);
- DoI64NumTest("4294967296", "%I64u", I64(4294967296));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test8/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf/test8/testinfo.dat
deleted file mode 100644
index 2cbc31ad2a..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test8/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = C Runtime
-Function = sscanf
-Name = Positive Test for sscanf
-TYPE = DEFAULT
-EXE1 = test8
-Description
-= Tests sscanf with unsigned numbers
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test9/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf/test9/CMakeLists.txt
deleted file mode 100644
index 77c269aeaa..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test9/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test9.c
-)
-
-add_executable(paltest_sscanf_test9
- ${SOURCES}
-)
-
-add_dependencies(paltest_sscanf_test9 coreclrpal)
-
-target_link_libraries(paltest_sscanf_test9
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test9/test9.c b/src/pal/tests/palsuite/c_runtime/sscanf/test9/test9.c
deleted file mode 100644
index c5a2e0de5d..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test9/test9.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test9.c
-**
-** Purpose: Tests sscanf with characters
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../sscanf.h"
-
-
-int __cdecl main(int argc, char *argv[])
-{
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
- DoCharTest("1234d", "%c", "1", 1);
- DoCharTest("1234d", "%c", "1", 1);
- DoCharTest("abc", "%2c", "ab", 2);
- DoCharTest(" ab", "%c", " ", 1);
- DoCharTest("ab", "%hc", "a", 1);
- DoWCharTest("ab", "%lc", convert("a"), 1);
- DoCharTest("ab", "%Lc", "a", 1);
- DoCharTest("ab", "%I64c", "a", 1);
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/test9/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf/test9/testinfo.dat
deleted file mode 100644
index c0ccc8a4c9..0000000000
--- a/src/pal/tests/palsuite/c_runtime/sscanf/test9/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section =C Runtime
-Function = sscanf
-Name = Positive Test for sscanf
-TYPE = DEFAULT
-EXE1 = test9
-Description
-= Tests sscanf with characters
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf_s/CMakeLists.txt
index 59f39a5f58..59f39a5f58 100644
--- a/src/pal/tests/palsuite/c_runtime/sscanf/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/CMakeLists.txt
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/sscanf_s.h b/src/pal/tests/palsuite/c_runtime/sscanf_s/sscanf_s.h
new file mode 100644
index 0000000000..8a99d87cb4
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/sscanf_s.h
@@ -0,0 +1,246 @@
+// Licensed to the .NET Foundation under one or more 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: sscanf_s.h
+**
+** Purpose: Contains common testing functions for sscanf_s
+**
+**
+**==========================================================================*/
+
+#ifndef __SSCANF_S_H__
+#define __SSCANF_S_H__
+
+void DoVoidTest(char *inputstr, const char *formatstr)
+{
+ char buf[256] = { 0 };
+ int i;
+ int ret;
+
+ ret = sscanf_s(inputstr, formatstr, buf);
+ if (ret != 0)
+ {
+ Fail("ERROR: Expected sscanf_s to return 0, got %d.\n"
+ "Using \"%s\" in \"%s\".\n", ret, inputstr, formatstr);
+ }
+
+ for (i=0; i<256; i++)
+ {
+ if (buf[i] != 0)
+ {
+ Fail("ERROR: Parameter unexpectedly modified scanning \"%s\" "
+ "using \"%s\".\n", inputstr, formatstr);
+ }
+ }
+
+}
+
+void DoStrTest(char *inputstr, const char *formatstr, const char *checkstr)
+{
+ char buf[256] = { 0 };
+ int ret;
+
+ ret = sscanf_s(inputstr, formatstr, buf, _countof(buf));
+ if (ret != 1)
+ {
+ Fail("ERROR: Expected sscanf_s to return 1, got %d.\n"
+ "Using \"%s\" in \"%s\".\n", ret, inputstr, formatstr);
+ }
+
+ if (memcmp(checkstr, buf, strlen(checkstr) + 1) != 0)
+ {
+ Fail("ERROR: scanned string incorrectly from \"%s\" using \"%s\".\n"
+ "Expected \"%s\", got \"%s\".\n", inputstr, formatstr, checkstr,
+ buf);
+ }
+
+}
+
+void DoWStrTest(char *inputstr, const char *formatstr, const WCHAR *checkstr)
+{
+ WCHAR buf[256] = { 0 };
+ int ret;
+
+ ret = sscanf_s(inputstr, formatstr, buf, _countof(buf));
+ if (ret != 1)
+ {
+ Fail("ERROR: Expected sscanf_s to return 1, got %d.\n"
+ "Using \"%s\" in \"%s\".\n", ret, inputstr, formatstr);
+ }
+
+ if (memcmp(checkstr, buf, wcslen(checkstr)*2 + 2) != 0)
+ {
+ Fail("ERROR: scanned wide string incorrectly from \"%s\" using \"%s\".\n"
+ "Expected \"%s\", got \"%s\".\n", inputstr, formatstr,
+ convertC(checkstr), convertC(buf));
+ }
+
+}
+
+void DoNumTest(char *inputstr, const char *formatstr, int checknum)
+{
+ int num;
+ int ret;
+
+ ret = sscanf_s(inputstr, formatstr, &num);
+ if (ret != 1)
+ {
+ Fail("ERROR: Expected sscanf_s to return 1, got %d.\n"
+ "Using \"%s\" in \"%s\".\n", ret, inputstr, formatstr);
+ }
+
+ if (checknum != num)
+ {
+ Fail("ERROR: scanned number incorrectly from \"%s\" using \"%s\".\n"
+ "Expected %d, got %d.\n", inputstr, formatstr, checknum, num);
+ }
+}
+
+void DoShortNumTest(char *inputstr, const char *formatstr, short checknum)
+{
+ short num;
+ int ret;
+
+ ret = sscanf_s(inputstr, formatstr, &num);
+ if (ret != 1)
+ {
+ Fail("ERROR: Expected sscanf_s to return 1, got %d.\n"
+ "Using \"%s\" in \"%s\".\n", ret, inputstr, formatstr);
+ }
+
+ if (checknum != num)
+ {
+ Fail("ERROR: scanned number incorrectly from \"%s\" using \"%s\".\n"
+ "Expected %hd, got %hd.\n", inputstr, formatstr, checknum, num);
+ }
+}
+
+void DoI64NumTest(char *inputstr, const char *formatstr, INT64 checknum)
+{
+ char buf[256];
+ char check[256];
+ INT64 num;
+ int ret;
+
+ ret = sscanf_s(inputstr, formatstr, &num);
+ if (ret != 1)
+ {
+ Fail("ERROR: Expected sscanf_s to return 1, got %d.\n"
+ "Using \"%s\" in \"%s\".\n", ret, inputstr, formatstr);
+ }
+
+ if (checknum != num)
+ {
+ sprintf_s(buf, _countof(buf), "%I64d", num);
+ sprintf_s(check, _countof(check), "%I64d", checknum);
+ Fail("ERROR: scanned I64 number incorrectly from \"%s\" using \"%s\".\n"
+ "Expected %s, got %s.\n", inputstr, formatstr, check, buf);
+ }
+}
+
+void DoCharTest(char *inputstr, const char *formatstr, char* checkchars, int numchars)
+{
+ char buf[256];
+ int ret;
+ int i;
+
+ for (i=0; i<256; i++)
+ buf[i] = (char)-1;
+
+ ret = sscanf_s(inputstr, formatstr, buf, _countof(buf));
+ if (ret != 1)
+ {
+ Fail("ERROR: Expected sscanf_s to return 1, got %d.\n"
+ "Using \"%s\" in \"%s\".\n", ret, inputstr, formatstr);
+ }
+
+ if (memcmp(buf, checkchars, numchars) != 0)
+ {
+ buf[numchars] = 0;
+
+ Fail("ERROR: scanned character(s) incorrectly from \"%s\" using \"%s\".\n"
+ "Expected %s, got %s.\n", inputstr, formatstr, checkchars,
+ buf);
+ }
+
+ if (buf[numchars] != (char)-1)
+ {
+ Fail("ERROR: overflow occurred in scanning character(s) from \"%s\" "
+ "using \"%s\".\nExpected %d character(s)\n", inputstr, formatstr,
+ numchars);
+ }
+}
+
+void DoWCharTest(char *inputstr, const char *formatstr, WCHAR* checkchars, int numchars)
+{
+ WCHAR buf[256];
+ int ret;
+ int i;
+
+ for (i=0; i<256; i++)
+ buf[i] = (WCHAR)-1;
+
+ ret = sscanf_s(inputstr, formatstr, buf, _countof(buf));
+ if (ret != 1)
+ {
+ Fail("ERROR: Expected sscanf_s to return 1, got %d.\n"
+ "Using \"%s\" in \"%s\".\n", ret, inputstr, formatstr);
+ }
+
+ if (memcmp(buf, checkchars, numchars) != 0)
+ {
+ buf[numchars] = 0;
+
+ Fail("ERROR: scanned wide character(s) incorrectly from \"%s\" using \"%s\".\n"
+ "Expected %s, got %s.\n", inputstr, formatstr, convertC(checkchars),
+ convertC(buf));
+ }
+
+ if (buf[numchars] != (WCHAR)-1)
+ {
+ Fail("ERROR: overflow occurred in scanning wide character(s) from \"%s\" "
+ "using \"%s\".\nExpected %d character(s)\n", inputstr, formatstr,
+ numchars);
+ }
+}
+
+
+void DoFloatTest(char *inputstr, const char *formatstr, float checkval)
+{
+ char buf[256] = { 0 };
+ float val;
+ int ret;
+ int i;
+
+ for (i=0; i<256; i++)
+ buf[i] = (char)-1;
+
+ ret = sscanf_s(inputstr, formatstr, buf);
+ val = *(float*)buf;
+
+ if (ret != 1)
+ {
+ Fail("ERROR: Expected sscanf_s to return 1, got %d.\n"
+ "Using \"%s\" in \"%s\".\n", ret, inputstr, formatstr);
+ }
+
+ if (val != checkval)
+ {
+ Fail("ERROR: scanned float incorrectly from \"%s\" using \"%s\".\n"
+ "Expected \"%f\", got \"%f\".\n", inputstr, formatstr, checkval,
+ val);
+ }
+
+ if (buf[4] != (char)-1)
+ {
+ Fail("ERROR: overflow occurred in scanning float from \"%s\" "
+ "using \"%s\".\n", inputstr, formatstr);
+
+ }
+}
+
+
+#endif
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf_s/test1/CMakeLists.txt
new file mode 100644
index 0000000000..97b8f570e3
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.cpp
+)
+
+add_executable(paltest_sscanf_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sscanf_test1 coreclrpal)
+
+target_link_libraries(paltest_sscanf_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test1/test1.cpp b/src/pal/tests/palsuite/c_runtime/sscanf_s/test1/test1.cpp
new file mode 100644
index 0000000000..61313146e5
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test1/test1.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: test1.c
+**
+** Purpose: General test of sscanf_s
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sscanf_s.h"
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ int num;
+ int ret;
+
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+
+ DoVoidTest("foo bar", "foo ");
+ DoVoidTest("foo bar", "baz");
+ DoVoidTest("foo bar", "foo %*s");
+
+ DoStrTest("foo % bar", "foo %% %s", "bar");
+ DoStrTest("foo bar baz", "foo %bar %s", "baz");
+
+ DoVoidTest("foo bar baz", "foo % bar %s");
+ DoVoidTest("foo baz bar", "foo% baz %s");
+
+ ret = sscanf_s("foo bar baz", "foo bar %n", &num);
+ if (ret != 0 || num != 8)
+ {
+ Fail("ERROR: Got incorrect values in scanning \"%s\" using \"%s\".\n"
+ "Expected to get a value of %d with return value of %d, "
+ "got %d with return %d\n", "foo bar baz", "foo bar %n", 8, 0,
+ num, ret);
+
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf_s/test1/testinfo.dat
new file mode 100644
index 0000000000..76f592769f
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/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 = C Runtime
+Function = sscanf_s
+Name = Positive Test for sscanf_s
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= General test of sscanf_s
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test10/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf_s/test10/CMakeLists.txt
new file mode 100644
index 0000000000..afda216c6b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test10/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test10.cpp
+)
+
+add_executable(paltest_sscanf_test10
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sscanf_test10 coreclrpal)
+
+target_link_libraries(paltest_sscanf_test10
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test10/test10.cpp b/src/pal/tests/palsuite/c_runtime/sscanf_s/test10/test10.cpp
new file mode 100644
index 0000000000..0c63c864ed
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test10/test10.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test10.c
+**
+** Purpose: Tests sscanf_s with wide characters
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sscanf_s.h"
+
+int __cdecl main(int argc, char *argv[])
+{
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ DoWCharTest("1234d", "%C", convert("1"), 1);
+ DoWCharTest("1234d", "%C", convert("1"), 1);
+ DoWCharTest("abc", "%2C", convert("ab"), 2);
+ DoWCharTest(" ab", "%C", convert(" "), 1);
+ DoCharTest("ab", "%hC", "a", 1);
+ DoWCharTest("ab", "%lC", convert("a"), 1);
+ DoWCharTest("ab", "%LC", convert("a"), 1);
+ DoWCharTest("ab", "%I64C", convert("a"), 1);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test10/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf_s/test10/testinfo.dat
new file mode 100644
index 0000000000..e048e700a0
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test10/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 = C Runtime
+Function = sscanf_s
+Name = Positive Test for sscanf_s
+TYPE = DEFAULT
+EXE1 = test10
+Description
+= Tests sscanf_s with wide characters
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test11/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf_s/test11/CMakeLists.txt
new file mode 100644
index 0000000000..c8f98aeeef
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test11/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test11.cpp
+)
+
+add_executable(paltest_sscanf_test11
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sscanf_test11 coreclrpal)
+
+target_link_libraries(paltest_sscanf_test11
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test11/test11.cpp b/src/pal/tests/palsuite/c_runtime/sscanf_s/test11/test11.cpp
new file mode 100644
index 0000000000..8279f4b3f4
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test11/test11.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test11.c
+**
+** Purpose: Tests sscanf_s with strings
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sscanf_s.h"
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ DoStrTest("foo bar", "foo %s", "bar");
+ DoStrTest("foo bar", "foo %2s", "ba");
+ DoStrTest("foo bar", "foo %hs", "bar");
+ DoWStrTest("foo bar", "foo %ls", convert("bar"));
+ DoStrTest("foo bar", "foo %Ls", "bar");
+ DoStrTest("foo bar", "foo %I64s", "bar");
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test11/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf_s/test11/testinfo.dat
new file mode 100644
index 0000000000..5a906ddf51
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test11/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 = C Runtime
+Function = sscanf_s
+Name = Positive Test for sscanf_s
+TYPE = DEFAULT
+EXE1 = test11
+Description
+= Tests sscanf_s with strings
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test12/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf_s/test12/CMakeLists.txt
new file mode 100644
index 0000000000..0ecedc3285
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test12/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test12.cpp
+)
+
+add_executable(paltest_sscanf_test12
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sscanf_test12 coreclrpal)
+
+target_link_libraries(paltest_sscanf_test12
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test12/test12.cpp b/src/pal/tests/palsuite/c_runtime/sscanf_s/test12/test12.cpp
new file mode 100644
index 0000000000..e599534270
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test12/test12.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test12.c
+**
+** Purpose: Tests sscanf_s with wide strings
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sscanf_s.h"
+
+int __cdecl main(int argc, char *argv[])
+{
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ DoWStrTest("foo bar", "foo %S", convert("bar"));
+ DoWStrTest("foo bar", "foo %2S", convert("ba"));
+ DoStrTest("foo bar", "foo %hS", "bar");
+ DoWStrTest("foo bar", "foo %lS", convert("bar"));
+ DoWStrTest("foo bar", "foo %LS", convert("bar"));
+ DoWStrTest("foo bar", "foo %I64S", convert("bar"));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test12/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf_s/test12/testinfo.dat
new file mode 100644
index 0000000000..569be983c0
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test12/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 = C Runtime
+Function = sscanf_s
+Name = Positive Test for sscanf_s
+TYPE = DEFAULT
+EXE1 = test12
+Description
+= Tests sscanf_s with wide strings
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test13/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf_s/test13/CMakeLists.txt
new file mode 100644
index 0000000000..4566ec3338
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test13/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test13.cpp
+)
+
+add_executable(paltest_sscanf_test13
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sscanf_test13 coreclrpal)
+
+target_link_libraries(paltest_sscanf_test13
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test13/test13.cpp b/src/pal/tests/palsuite/c_runtime/sscanf_s/test13/test13.cpp
new file mode 100644
index 0000000000..4fc12bb751
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test13/test13.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test13.c
+**
+** Purpose: Tests sscanf_s with floats (decimal notation)
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sscanf_s.h"
+
+int __cdecl main(int argc, char *argv[])
+{
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ DoFloatTest("123.0", "%f", 123.0f);
+ DoFloatTest("123.0", "%2f", 12.0f);
+ DoFloatTest("10E1", "%f", 100.0f);
+ DoFloatTest("-12.01e-2", "%f", -0.1201f);
+ DoFloatTest("+12.01e-2", "%f", 0.1201f);
+ DoFloatTest("-12.01e+2", "%f", -1201.0f);
+ DoFloatTest("+12.01e+2", "%f", 1201.0f);
+ DoFloatTest("1234567890.0123456789f", "%f", 1234567936);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test13/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf_s/test13/testinfo.dat
new file mode 100644
index 0000000000..651577befd
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test13/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 = C Runtime
+Function = sscanf_s
+Name = Positive Test for sscanf_s
+TYPE = DEFAULT
+EXE1 = test13
+Description
+= Tests sscanf_s with floats (decimal notation)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test14/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf_s/test14/CMakeLists.txt
new file mode 100644
index 0000000000..557acf5bf8
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test14/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test14.cpp
+)
+
+add_executable(paltest_sscanf_test14
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sscanf_test14 coreclrpal)
+
+target_link_libraries(paltest_sscanf_test14
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test14/test14.cpp b/src/pal/tests/palsuite/c_runtime/sscanf_s/test14/test14.cpp
new file mode 100644
index 0000000000..fc2fa2ee15
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test14/test14.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test14.c
+**
+** Purpose: Tests sscanf_s with floats (exponential notation, lowercase)
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sscanf_s.h"
+
+int __cdecl main(int argc, char *argv[])
+{
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ DoFloatTest("123.0", "%e", 123.0f);
+ DoFloatTest("123.0", "%2e", 12.0f);
+ DoFloatTest("10E1", "%e", 100.0f);
+ DoFloatTest("-12.01e-2", "%e", -0.1201f);
+ DoFloatTest("+12.01e-2", "%e", 0.1201f);
+ DoFloatTest("-12.01e+2", "%e", -1201.0f);
+ DoFloatTest("+12.01e+2", "%e", 1201.0f);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test14/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf_s/test14/testinfo.dat
new file mode 100644
index 0000000000..8e7338fd46
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test14/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 = C Runtime
+Function = sscanf_s
+Name = Positive Test for sscanf_s
+TYPE = DEFAULT
+EXE1 = test14
+Description
+= Tests sscanf_s with floats (exponential notation, lowercase)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test15/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf_s/test15/CMakeLists.txt
new file mode 100644
index 0000000000..efde5c4a21
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test15/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test15.cpp
+)
+
+add_executable(paltest_sscanf_test15
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sscanf_test15 coreclrpal)
+
+target_link_libraries(paltest_sscanf_test15
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test15/test15.cpp b/src/pal/tests/palsuite/c_runtime/sscanf_s/test15/test15.cpp
new file mode 100644
index 0000000000..1eff995b86
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test15/test15.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test15.c
+**
+** Purpose: Tests sscanf_s with floats (exponential notation, uppercase
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sscanf_s.h"
+
+int __cdecl main(int argc, char *argv[])
+{
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ DoFloatTest("123.0", "%E", 123.0f);
+ DoFloatTest("123.0", "%2E", 12.0f);
+ DoFloatTest("10E1", "%E", 100.0f);
+ DoFloatTest("-12.01e-2", "%E", -0.1201f);
+ DoFloatTest("+12.01e-2", "%E", 0.1201f);
+ DoFloatTest("-12.01e+2", "%E", -1201.0f);
+ DoFloatTest("+12.01e+2", "%E", 1201.0f);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test15/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf_s/test15/testinfo.dat
new file mode 100644
index 0000000000..d713a73d81
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test15/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 = C Runtime
+Function = sscanf_s
+Name = Positive Test for sscanf_s
+TYPE = DEFAULT
+EXE1 = test15
+Description
+= Tests sscanf_s with floats (exponential notation, uppercase)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test16/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf_s/test16/CMakeLists.txt
new file mode 100644
index 0000000000..6757b0d78a
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test16/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test16.cpp
+)
+
+add_executable(paltest_sscanf_test16
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sscanf_test16 coreclrpal)
+
+target_link_libraries(paltest_sscanf_test16
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test16/test16.cpp b/src/pal/tests/palsuite/c_runtime/sscanf_s/test16/test16.cpp
new file mode 100644
index 0000000000..f202767448
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test16/test16.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test16.c
+**
+** Purpose:Tests sscanf_s with floats (compact notation, lowercase)
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sscanf_s.h"
+
+int __cdecl main(int argc, char *argv[])
+{
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ DoFloatTest("123.0", "%g", 123.0f);
+ DoFloatTest("123.0", "%2g", 12.0f);
+ DoFloatTest("10E1", "%g", 100.0f);
+ DoFloatTest("-12.01e-2", "%g", -0.1201f);
+ DoFloatTest("+12.01e-2", "%g", 0.1201f);
+ DoFloatTest("-12.01e+2", "%g", -1201.0f);
+ DoFloatTest("+12.01e+2", "%g", 1201.0f);
+ DoFloatTest("1234567890.0123456789g", "%g", 1234567936);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test16/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf_s/test16/testinfo.dat
new file mode 100644
index 0000000000..669611945d
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test16/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 = C Runtime
+Function = sscanf_s
+Name = Positive Test for sscanf_s
+TYPE = DEFAULT
+EXE1 = test16
+Description
+= Tests sscanf_s with floats (compact notation, lowercase)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test17/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf_s/test17/CMakeLists.txt
new file mode 100644
index 0000000000..8ea4d5e3f6
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test17/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test17.cpp
+)
+
+add_executable(paltest_sscanf_test17
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sscanf_test17 coreclrpal)
+
+target_link_libraries(paltest_sscanf_test17
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test17/test17.cpp b/src/pal/tests/palsuite/c_runtime/sscanf_s/test17/test17.cpp
new file mode 100644
index 0000000000..a18c3caff1
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test17/test17.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test17.c
+**
+** Purpose: Tests sscanf_s with floats (compact notation, uppercase)
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sscanf_s.h"
+
+int __cdecl main(int argc, char *argv[])
+{
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ DoFloatTest("123.0", "%G", 123.0f);
+ DoFloatTest("123.0", "%2G", 12.0f);
+ DoFloatTest("10E1", "%G", 100.0f);
+ DoFloatTest("-12.01e-2", "%G", -0.1201f);
+ DoFloatTest("+12.01e-2", "%G", 0.1201f);
+ DoFloatTest("-12.01e+2", "%G", -1201.0f);
+ DoFloatTest("+12.01e+2", "%G", 1201.0f);
+ DoFloatTest("1234567890.0123456789G", "%G", 1234567936);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test17/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf_s/test17/testinfo.dat
new file mode 100644
index 0000000000..8ce4e93e1a
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test17/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 = C Runtime
+Function = sscanf_s
+Name = Positive Test for sscanf_s
+TYPE = DEFAULT
+EXE1 = test17
+Description
+= Tests sscanf_s with floats (compact notation, uppercase)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf_s/test2/CMakeLists.txt
new file mode 100644
index 0000000000..4e36223a1d
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test2/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test2.cpp
+)
+
+add_executable(paltest_sscanf_test2
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sscanf_test2 coreclrpal)
+
+target_link_libraries(paltest_sscanf_test2
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test2/test2.cpp b/src/pal/tests/palsuite/c_runtime/sscanf_s/test2/test2.cpp
new file mode 100644
index 0000000000..c9c79f67ea
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test2/test2.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test2.c
+**
+** Purpose: Test to see if sscanf_s handles whitespace correctly
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sscanf_s.h"
+
+
+/*
+ * Tests out how it handles whitespace. Seems to accept anything that qualifies
+ * as isspace (space, tab, vertical tab, line feed, carriage return and form
+ * feed), even if it says it only wants spaces tabs and newlines.
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ DoStrTest("foo bar", "foo %s", "bar");
+ DoStrTest("foo\tbar", "foo %s", "bar");
+ DoStrTest("foo\nbar", "foo %s", "bar");
+ DoStrTest("foo\rbar", "foo %s", "bar");
+ DoStrTest("foo\vbar", "foo %s", "bar");
+ DoStrTest("foo\fbar", "foo %s", "bar");
+ DoStrTest("foo \t\n\r\v\fbar", "foo %s", "bar");
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test2/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf_s/test2/testinfo.dat
new file mode 100644
index 0000000000..85fed244f9
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test2/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 = C Runtime
+Function = sscanf_s
+Name = Positive Test for sscanf_s
+TYPE = DEFAULT
+EXE1 = test2
+Description
+= Test to see if sscanf_s handles whitespace correctly
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf_s/test3/CMakeLists.txt
new file mode 100644
index 0000000000..053a96ca0f
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test3/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test3.cpp
+)
+
+add_executable(paltest_sscanf_test3
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sscanf_test3 coreclrpal)
+
+target_link_libraries(paltest_sscanf_test3
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test3/test3.cpp b/src/pal/tests/palsuite/c_runtime/sscanf_s/test3/test3.cpp
new file mode 100644
index 0000000000..e1e45bdd70
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test3/test3.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test3.c
+**
+** Purpose: Tests sscanf_s with bracketed set strings
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sscanf_s.h"
+
+int __cdecl main(int argc, char *argv[])
+{
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ DoStrTest("bar1", "%[a-z]", "bar");
+ DoStrTest("bar1", "%[z-a]", "bar");
+ DoStrTest("bar1", "%[ab]", "ba");
+ DoStrTest("bar1", "%[ar1b]", "bar1");
+ DoStrTest("bar1", "%[^4]", "bar1");
+ DoStrTest("bar1", "%[^4a]", "b");
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test3/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf_s/test3/testinfo.dat
new file mode 100644
index 0000000000..523d31e82e
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test3/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 = C Runtime
+Function = sscanf_s
+Name = Positive Test for sscanf_s
+TYPE = DEFAULT
+EXE1 = test3
+Description
+= Tests sscanf_s with bracketed set strings
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test4/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf_s/test4/CMakeLists.txt
new file mode 100644
index 0000000000..ae04bfef57
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test4/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test4.cpp
+)
+
+add_executable(paltest_sscanf_test4
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sscanf_test4 coreclrpal)
+
+target_link_libraries(paltest_sscanf_test4
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test4/test4.cpp b/src/pal/tests/palsuite/c_runtime/sscanf_s/test4/test4.cpp
new file mode 100644
index 0000000000..f8413ea7fd
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test4/test4.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test4.c
+**
+** Purpose: Tests sscanf_s with decimal numbers
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sscanf_s.h"
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ int n65535 = 65535; /* Walkaround compiler strictness */
+
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ DoNumTest("1234d", "%d", 1234);
+ DoNumTest("1234d", "%2d", 12);
+ DoNumTest("-1", "%d", -1);
+ DoNumTest("0x1234", "%d", 0);
+ DoNumTest("012", "%d", 12);
+ DoShortNumTest("-1", "%hd", n65535);
+ DoShortNumTest("65536", "%hd", 0);
+ DoNumTest("-1", "%ld", -1);
+ DoNumTest("65536", "%ld", 65536);
+ DoNumTest("-1", "%Ld", -1);
+ DoNumTest("65536", "%Ld", 65536);
+ DoI64NumTest("4294967296", "%I64d", I64(4294967296));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test4/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf_s/test4/testinfo.dat
new file mode 100644
index 0000000000..2065f2bea2
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test4/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 = C Runtime
+Function = sscanf_s
+Name = Positive Test for sscanf_s
+TYPE = DEFAULT
+EXE1 = test4
+Description
+= Tests sscanf_s with decimal numbers
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test5/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf_s/test5/CMakeLists.txt
new file mode 100644
index 0000000000..33dcaffec3
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test5/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test5.cpp
+)
+
+add_executable(paltest_sscanf_test5
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sscanf_test5 coreclrpal)
+
+target_link_libraries(paltest_sscanf_test5
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test5/test5.cpp b/src/pal/tests/palsuite/c_runtime/sscanf_s/test5/test5.cpp
new file mode 100644
index 0000000000..cdfefd860b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test5/test5.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test5.c
+**
+** Purpose: Tests sscanf_s with integer numbers
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sscanf_s.h"
+
+int __cdecl main(int argc, char *argv[])
+{
+ int n65535 = 65535; /* Walkaround compiler strictness */
+
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ DoNumTest("1234d", "%i", 1234);
+ DoNumTest("1234d", "%2i", 12);
+ DoNumTest("-1", "%i", -1);
+ DoNumTest("0x1234", "%i", 0x1234);
+ DoNumTest("012", "%i", 10);
+ DoShortNumTest("-1", "%hi", n65535);
+ DoShortNumTest("65536", "%hi", 0);
+ DoNumTest("-1", "%li", -1);
+ DoNumTest("65536", "%li", 65536);
+ DoNumTest("-1", "%Li", -1);
+ DoNumTest("65536", "%Li", 65536);
+ DoI64NumTest("4294967296", "%I64i", I64(4294967296));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test5/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf_s/test5/testinfo.dat
new file mode 100644
index 0000000000..cb687c15cd
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test5/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 = C Runtime
+Function = sscanf_s
+Name = Positive Test for sscanf_s
+TYPE = DEFAULT
+EXE1 = test5
+Description
+= Tests sscanf_s with integer numbers
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test6/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf_s/test6/CMakeLists.txt
new file mode 100644
index 0000000000..1dd23c3cb1
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test6/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test6.cpp
+)
+
+add_executable(paltest_sscanf_test6
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sscanf_test6 coreclrpal)
+
+target_link_libraries(paltest_sscanf_test6
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test6/test6.cpp b/src/pal/tests/palsuite/c_runtime/sscanf_s/test6/test6.cpp
new file mode 100644
index 0000000000..507b100e15
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test6/test6.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test6.c
+**
+** Purpose: Tests sscanf_s with octal numbers
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sscanf_s.h"
+
+int __cdecl main(int argc, char *argv[])
+{
+ int n65535 = 65535; /* Walkaround compiler strictness */
+
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ DoNumTest("1234d", "%o", 668);
+ DoNumTest("1234d", "%2o", 10);
+ DoNumTest("-1", "%o", -1);
+ DoNumTest("0x1234", "%o", 0);
+ DoNumTest("012", "%o", 10);
+ DoShortNumTest("-1", "%ho", n65535);
+ DoShortNumTest("200000", "%ho", 0);
+ DoNumTest("-1", "%lo", -1);
+ DoNumTest("200000", "%lo", 65536);
+ DoNumTest("-1", "%Lo", -1);
+ DoNumTest("200000", "%Lo", 65536);
+ DoI64NumTest("40000000000", "%I64o", I64(4294967296));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test6/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf_s/test6/testinfo.dat
new file mode 100644
index 0000000000..9e518dddf2
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test6/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 = C Runtime
+Function = sscanf_s
+Name = Positive Test for sscanf_s
+TYPE = DEFAULT
+EXE1 = test6
+Description
+= Tests sscanf_s with octal numbers
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test7/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf_s/test7/CMakeLists.txt
new file mode 100644
index 0000000000..015a27b776
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test7/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test7.cpp
+)
+
+add_executable(paltest_sscanf_test7
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sscanf_test7 coreclrpal)
+
+target_link_libraries(paltest_sscanf_test7
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test7/test7.cpp b/src/pal/tests/palsuite/c_runtime/sscanf_s/test7/test7.cpp
new file mode 100644
index 0000000000..4093e009e1
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test7/test7.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test7.c
+**
+** Purpose: Tests sscanf_s with hex numbers (lowercase)
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sscanf_s.h"
+
+int __cdecl main(int argc, char *argv[])
+{
+ int n65535 = 65535; /* Walkaround compiler strictness */
+
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ DoNumTest("1234i", "%x", 0x1234);
+ DoNumTest("1234i", "%2x", 0x12);
+ DoNumTest("-1", "%x", -1);
+ DoNumTest("0x1234", "%x", 0x1234);
+ DoNumTest("012", "%x", 0x12);
+ DoShortNumTest("-1", "%hx", n65535);
+ DoShortNumTest("10000", "%hx", 0);
+ DoNumTest("-1", "%lx", -1);
+ DoNumTest("10000", "%lx", 65536);
+ DoNumTest("-1", "%Lx", -1);
+ DoNumTest("10000", "%Lx", 65536);
+ DoI64NumTest("100000000", "%I64x", I64(4294967296));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test7/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf_s/test7/testinfo.dat
new file mode 100644
index 0000000000..8d6c182c90
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test7/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 = C Runtime
+Function = sscanf_s
+Name = Positive Test for sscanf_s
+TYPE = DEFAULT
+EXE1 = test7
+Description
+= Tests sscanf_s with hex numbers (lowercase)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test8/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf_s/test8/CMakeLists.txt
new file mode 100644
index 0000000000..aa41ab42a6
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test8/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test8.cpp
+)
+
+add_executable(paltest_sscanf_test8
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sscanf_test8 coreclrpal)
+
+target_link_libraries(paltest_sscanf_test8
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test8/test8.cpp b/src/pal/tests/palsuite/c_runtime/sscanf_s/test8/test8.cpp
new file mode 100644
index 0000000000..23ef22a56a
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test8/test8.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test8.c
+**
+** Purpose:Tests sscanf_s with unsigned number
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sscanf_s.h"
+
+int __cdecl main(int argc, char *argv[])
+{
+ int n65535 = 65535; /* Walkaround compiler strictness */
+
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ DoNumTest("1234d", "%u", 1234);
+ DoNumTest("1234d", "%2u", 12);
+ DoNumTest("-1", "%u", -1);
+ DoNumTest("0x1234", "%u", 0);
+ DoNumTest("012", "%u", 12);
+ DoShortNumTest("-1", "%hu", n65535);
+ DoShortNumTest("65536", "%hu", 0);
+ DoNumTest("-1", "%lu", -1);
+ DoNumTest("65536", "%lu", 65536);
+ DoNumTest("-1", "%Lu", -1);
+ DoNumTest("65536", "%Lu", 65536);
+ DoI64NumTest("4294967296", "%I64u", I64(4294967296));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test8/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf_s/test8/testinfo.dat
new file mode 100644
index 0000000000..0287a495d2
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test8/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 = C Runtime
+Function = sscanf_s
+Name = Positive Test for sscanf_s
+TYPE = DEFAULT
+EXE1 = test8
+Description
+= Tests sscanf_s with unsigned numbers
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test9/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/sscanf_s/test9/CMakeLists.txt
new file mode 100644
index 0000000000..b631fd40ea
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test9/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test9.cpp
+)
+
+add_executable(paltest_sscanf_test9
+ ${SOURCES}
+)
+
+add_dependencies(paltest_sscanf_test9 coreclrpal)
+
+target_link_libraries(paltest_sscanf_test9
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test9/test9.cpp b/src/pal/tests/palsuite/c_runtime/sscanf_s/test9/test9.cpp
new file mode 100644
index 0000000000..2c99c40e5d
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test9/test9.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test9.c
+**
+** Purpose: Tests sscanf_s with characters
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../sscanf_s.h"
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ DoCharTest("1234d", "%c", "1", 1);
+ DoCharTest("1234d", "%c", "1", 1);
+ DoCharTest("abc", "%2c", "ab", 2);
+ DoCharTest(" ab", "%c", " ", 1);
+ DoCharTest("ab", "%hc", "a", 1);
+ DoWCharTest("ab", "%lc", convert("a"), 1);
+ DoCharTest("ab", "%Lc", "a", 1);
+ DoCharTest("ab", "%I64c", "a", 1);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/sscanf_s/test9/testinfo.dat b/src/pal/tests/palsuite/c_runtime/sscanf_s/test9/testinfo.dat
new file mode 100644
index 0000000000..95f6c74ee2
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/sscanf_s/test9/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 =C Runtime
+Function = sscanf_s
+Name = Positive Test for sscanf_s
+TYPE = DEFAULT
+EXE1 = test9
+Description
+= Tests sscanf_s with characters
diff --git a/src/pal/tests/palsuite/c_runtime/strcat/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/strcat/test1/CMakeLists.txt
index 4a0f0be32d..fd62627db6 100644
--- a/src/pal/tests/palsuite/c_runtime/strcat/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/strcat/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_strcat_test1
diff --git a/src/pal/tests/palsuite/c_runtime/strcat/test1/test1.c b/src/pal/tests/palsuite/c_runtime/strcat/test1/test1.cpp
index 532d84621e..532d84621e 100644
--- a/src/pal/tests/palsuite/c_runtime/strcat/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/strcat/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/strchr/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/strchr/test1/CMakeLists.txt
index 1d248f3f56..f3ffe3bc15 100644
--- a/src/pal/tests/palsuite/c_runtime/strchr/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/strchr/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_strchr_test1
diff --git a/src/pal/tests/palsuite/c_runtime/strchr/test1/test1.c b/src/pal/tests/palsuite/c_runtime/strchr/test1/test1.cpp
index 9190c4f7ce..9190c4f7ce 100644
--- a/src/pal/tests/palsuite/c_runtime/strchr/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/strchr/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/strcmp/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/strcmp/test1/CMakeLists.txt
index b953dfa034..3b0f89c2a5 100644
--- a/src/pal/tests/palsuite/c_runtime/strcmp/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/strcmp/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_strcmp_test1
diff --git a/src/pal/tests/palsuite/c_runtime/strcmp/test1/test1.c b/src/pal/tests/palsuite/c_runtime/strcmp/test1/test1.cpp
index 49428fd624..49428fd624 100644
--- a/src/pal/tests/palsuite/c_runtime/strcmp/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/strcmp/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/strcpy/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/strcpy/test1/CMakeLists.txt
index 043ec57d98..4369d37a40 100644
--- a/src/pal/tests/palsuite/c_runtime/strcpy/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/strcpy/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_strcpy_test1
diff --git a/src/pal/tests/palsuite/c_runtime/strcpy/test1/test1.c b/src/pal/tests/palsuite/c_runtime/strcpy/test1/test1.cpp
index 43069e59a6..43069e59a6 100644
--- a/src/pal/tests/palsuite/c_runtime/strcpy/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/strcpy/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/strcspn/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/strcspn/test1/CMakeLists.txt
index a38761c335..717e18f0e9 100644
--- a/src/pal/tests/palsuite/c_runtime/strcspn/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/strcspn/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_strcspn_test1
diff --git a/src/pal/tests/palsuite/c_runtime/strcspn/test1/test1.c b/src/pal/tests/palsuite/c_runtime/strcspn/test1/test1.cpp
index ddc5667570..ddc5667570 100644
--- a/src/pal/tests/palsuite/c_runtime/strcspn/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/strcspn/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/strlen/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/strlen/test1/CMakeLists.txt
index c61828a97b..4afeb598aa 100644
--- a/src/pal/tests/palsuite/c_runtime/strlen/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/strlen/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_strlen_test1
diff --git a/src/pal/tests/palsuite/c_runtime/strlen/test1/test1.c b/src/pal/tests/palsuite/c_runtime/strlen/test1/test1.cpp
index 40f8e151c7..40f8e151c7 100644
--- a/src/pal/tests/palsuite/c_runtime/strlen/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/strlen/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/strncat/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/strncat/test1/CMakeLists.txt
index 7595f66939..f8080ecdc2 100644
--- a/src/pal/tests/palsuite/c_runtime/strncat/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/strncat/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_strncat_test1
diff --git a/src/pal/tests/palsuite/c_runtime/strncat/test1/test1.c b/src/pal/tests/palsuite/c_runtime/strncat/test1/test1.cpp
index 000d1685b9..000d1685b9 100644
--- a/src/pal/tests/palsuite/c_runtime/strncat/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/strncat/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/strncmp/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/strncmp/test1/CMakeLists.txt
index 4a0337a3dc..34b53e294d 100644
--- a/src/pal/tests/palsuite/c_runtime/strncmp/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/strncmp/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_strncmp_test1
diff --git a/src/pal/tests/palsuite/c_runtime/strncmp/test1/test1.c b/src/pal/tests/palsuite/c_runtime/strncmp/test1/test1.cpp
index 7326c3b61e..7326c3b61e 100644
--- a/src/pal/tests/palsuite/c_runtime/strncmp/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/strncmp/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/strncpy/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/strncpy/test1/CMakeLists.txt
index 6e0250bce3..fb737c8c59 100644
--- a/src/pal/tests/palsuite/c_runtime/strncpy/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/strncpy/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_strncpy_test1
diff --git a/src/pal/tests/palsuite/c_runtime/strncpy/test1/test1.c b/src/pal/tests/palsuite/c_runtime/strncpy/test1/test1.cpp
index 62baf61ba2..62baf61ba2 100644
--- a/src/pal/tests/palsuite/c_runtime/strncpy/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/strncpy/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/strpbrk/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/strpbrk/test1/CMakeLists.txt
index eac9ac9169..9e76436e01 100644
--- a/src/pal/tests/palsuite/c_runtime/strpbrk/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/strpbrk/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_strpbrk_test1
diff --git a/src/pal/tests/palsuite/c_runtime/strpbrk/test1/test1.c b/src/pal/tests/palsuite/c_runtime/strpbrk/test1/test1.cpp
index a42b80f313..a42b80f313 100644
--- a/src/pal/tests/palsuite/c_runtime/strpbrk/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/strpbrk/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/strrchr/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/strrchr/test1/CMakeLists.txt
index 5c099b0cd2..bb6916038d 100644
--- a/src/pal/tests/palsuite/c_runtime/strrchr/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/strrchr/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_strrchr_test1
diff --git a/src/pal/tests/palsuite/c_runtime/strrchr/test1/test1.c b/src/pal/tests/palsuite/c_runtime/strrchr/test1/test1.cpp
index a5c147eece..a5c147eece 100644
--- a/src/pal/tests/palsuite/c_runtime/strrchr/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/strrchr/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/strspn/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/strspn/test1/CMakeLists.txt
index 45caaf1bf8..c72fd0fa9a 100644
--- a/src/pal/tests/palsuite/c_runtime/strspn/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/strspn/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_strspn_test1
diff --git a/src/pal/tests/palsuite/c_runtime/strspn/test1/test1.c b/src/pal/tests/palsuite/c_runtime/strspn/test1/test1.cpp
index 78d2488438..78d2488438 100644
--- a/src/pal/tests/palsuite/c_runtime/strspn/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/strspn/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/strstr/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/strstr/test1/CMakeLists.txt
index 17e6ae8457..004b9a5658 100644
--- a/src/pal/tests/palsuite/c_runtime/strstr/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/strstr/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_strstr_test1
diff --git a/src/pal/tests/palsuite/c_runtime/strstr/test1/test1.c b/src/pal/tests/palsuite/c_runtime/strstr/test1/test1.cpp
index db01e8b32a..db01e8b32a 100644
--- a/src/pal/tests/palsuite/c_runtime/strstr/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/strstr/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/strtod/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/strtod/test1/CMakeLists.txt
index d3a9d61a4d..09884f32e6 100644
--- a/src/pal/tests/palsuite/c_runtime/strtod/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/strtod/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_strtod_test1
diff --git a/src/pal/tests/palsuite/c_runtime/strtod/test1/test1.c b/src/pal/tests/palsuite/c_runtime/strtod/test1/test1.cpp
index e312d98f58..e312d98f58 100644
--- a/src/pal/tests/palsuite/c_runtime/strtod/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/strtod/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/strtod/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/strtod/test2/CMakeLists.txt
index 6f407c5914..8729cc5a1c 100644
--- a/src/pal/tests/palsuite/c_runtime/strtod/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/strtod/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_strtod_test2
diff --git a/src/pal/tests/palsuite/c_runtime/strtod/test2/test2.c b/src/pal/tests/palsuite/c_runtime/strtod/test2/test2.cpp
index 0eaf4f53b6..0eaf4f53b6 100644
--- a/src/pal/tests/palsuite/c_runtime/strtod/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/strtod/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/strtok/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/strtok/test1/CMakeLists.txt
index 1d5fc04cca..422c4e96b5 100644
--- a/src/pal/tests/palsuite/c_runtime/strtok/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/strtok/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_strtok_test1
diff --git a/src/pal/tests/palsuite/c_runtime/strtok/test1/test1.c b/src/pal/tests/palsuite/c_runtime/strtok/test1/test1.cpp
index f1dec70380..f1dec70380 100644
--- a/src/pal/tests/palsuite/c_runtime/strtok/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/strtok/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/strtoul/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/strtoul/test1/CMakeLists.txt
index 61dbd4f9a3..009e85fb11 100644
--- a/src/pal/tests/palsuite/c_runtime/strtoul/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/strtoul/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_strtoul_test1
diff --git a/src/pal/tests/palsuite/c_runtime/strtoul/test1/test1.c b/src/pal/tests/palsuite/c_runtime/strtoul/test1/test1.cpp
index 344671b5cc..344671b5cc 100644
--- a/src/pal/tests/palsuite/c_runtime/strtoul/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/strtoul/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/swprintf.h b/src/pal/tests/palsuite/c_runtime/swprintf/swprintf.h
index 5229506064..6f4c914a82 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/swprintf.h
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/swprintf.h
@@ -14,7 +14,7 @@
#ifndef __SWPRINTF_H__
#define __SWPRINTF_H__
-void DoWStrTest(WCHAR *formatstr, WCHAR *param, WCHAR *checkstr)
+void DoWStrTest(const WCHAR *formatstr, WCHAR *param, const WCHAR *checkstr)
{
WCHAR buf[256] = { 0 };
@@ -29,7 +29,7 @@ void DoWStrTest(WCHAR *formatstr, WCHAR *param, WCHAR *checkstr)
}
}
-void DoStrTest(WCHAR *formatstr, char *param, WCHAR *checkstr)
+void DoStrTest(const WCHAR *formatstr, char *param, const WCHAR *checkstr)
{
WCHAR buf[256] = { 0 };
@@ -44,7 +44,7 @@ void DoStrTest(WCHAR *formatstr, char *param, WCHAR *checkstr)
}
}
-void DoPointerTest(WCHAR *formatstr, void* param, WCHAR *checkstr1)
+void DoPointerTest(const WCHAR *formatstr, void* param, const WCHAR *checkstr1)
{
WCHAR buf[256] = { 0 };
@@ -57,7 +57,7 @@ void DoPointerTest(WCHAR *formatstr, void* param, WCHAR *checkstr1)
}
}
-void DoCountTest(WCHAR *formatstr, int param, WCHAR *checkstr)
+void DoCountTest(const WCHAR *formatstr, int param, const WCHAR *checkstr)
{
WCHAR buf[512] = { 0 };
int n = -1;
@@ -77,7 +77,7 @@ void DoCountTest(WCHAR *formatstr, int param, WCHAR *checkstr)
}
}
-void DoShortCountTest(WCHAR *formatstr, int param, WCHAR *checkstr)
+void DoShortCountTest(const WCHAR *formatstr, int param, const WCHAR *checkstr)
{
WCHAR buf[256] = { 0 };
short int n = -1;
@@ -97,7 +97,7 @@ void DoShortCountTest(WCHAR *formatstr, int param, WCHAR *checkstr)
}
}
-void DoCharTest(WCHAR *formatstr, char param, WCHAR *checkstr)
+void DoCharTest(const WCHAR *formatstr, char param, const WCHAR *checkstr)
{
WCHAR buf[256] = { 0 };
@@ -110,7 +110,7 @@ void DoCharTest(WCHAR *formatstr, char param, WCHAR *checkstr)
}
}
-void DoWCharTest(WCHAR *formatstr, WCHAR param, WCHAR *checkstr)
+void DoWCharTest(const WCHAR *formatstr, WCHAR param, const WCHAR *checkstr)
{
WCHAR buf[256] = { 0 };
@@ -123,7 +123,7 @@ void DoWCharTest(WCHAR *formatstr, WCHAR param, WCHAR *checkstr)
}
}
-void DoNumTest(WCHAR *formatstr, int value, WCHAR*checkstr)
+void DoNumTest(const WCHAR *formatstr, int value, const WCHAR *checkstr)
{
WCHAR buf[256] = { 0 };
@@ -136,8 +136,8 @@ void DoNumTest(WCHAR *formatstr, int value, WCHAR*checkstr)
}
}
-void DoI64Test(WCHAR *formatstr, INT64 param, char *paramdesc,
- WCHAR *checkstr1)
+void DoI64Test(const WCHAR *formatstr, INT64 param, char *paramdesc,
+ const WCHAR *checkstr1)
{
WCHAR buf[256] = { 0 };
@@ -150,8 +150,8 @@ void DoI64Test(WCHAR *formatstr, INT64 param, char *paramdesc,
}
}
-void DoDoubleTest(WCHAR *formatstr, double value, WCHAR *checkstr1,
- WCHAR *checkstr2)
+void DoDoubleTest(const WCHAR *formatstr, double value, const WCHAR *checkstr1,
+ const WCHAR *checkstr2)
{
WCHAR buf[256] = { 0 };
@@ -166,8 +166,8 @@ void DoDoubleTest(WCHAR *formatstr, double value, WCHAR *checkstr1,
}
}
-void DoArgumentPrecTest(WCHAR *formatstr, int precision, void *param,
- char *paramstr, WCHAR *checkstr1, WCHAR *checkstr2)
+void DoArgumentPrecTest(const WCHAR *formatstr, int precision, void *param,
+ char *paramstr, const WCHAR *checkstr1, const WCHAR *checkstr2)
{
WCHAR buf[256];
@@ -182,8 +182,8 @@ void DoArgumentPrecTest(WCHAR *formatstr, int precision, void *param,
}
}
-void DoArgumentPrecDoubleTest(WCHAR *formatstr, int precision, double param,
- WCHAR *checkstr1, WCHAR *checkstr2)
+void DoArgumentPrecDoubleTest(const WCHAR *formatstr, int precision, double param,
+ const WCHAR *checkstr1, const WCHAR *checkstr2)
{
WCHAR buf[256];
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swprintf/test1/CMakeLists.txt
index fcf816029e..c9be8c3347 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_swprintf_test1
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/swprintf/test1/test1.cpp
index 626040d9f7..626040d9f7 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test10/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swprintf/test10/CMakeLists.txt
index 302c5e5923..222108393b 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test10/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test10/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test10.c
+ test10.cpp
)
add_executable(paltest_swprintf_test10
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test10/test10.c b/src/pal/tests/palsuite/c_runtime/swprintf/test10/test10.cpp
index 61aef593a0..61aef593a0 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test10/test10.c
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test10/test10.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test11/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swprintf/test11/CMakeLists.txt
index 484d57ef58..96222a5b2a 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test11/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test11/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test11.c
+ test11.cpp
)
add_executable(paltest_swprintf_test11
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test11/test11.c b/src/pal/tests/palsuite/c_runtime/swprintf/test11/test11.cpp
index 216f9acdbb..216f9acdbb 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test11/test11.c
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test11/test11.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test12/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swprintf/test12/CMakeLists.txt
index 6d45ee4646..1ffe620fed 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test12/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test12/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test12.c
+ test12.cpp
)
add_executable(paltest_swprintf_test12
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test12/test12.c b/src/pal/tests/palsuite/c_runtime/swprintf/test12/test12.cpp
index a41b0ddbd3..a41b0ddbd3 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test12/test12.c
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test12/test12.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test13/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swprintf/test13/CMakeLists.txt
index 20f6f0df7b..8699589ec9 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test13/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test13/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test13.c
+ test13.cpp
)
add_executable(paltest_swprintf_test13
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test13/test13.c b/src/pal/tests/palsuite/c_runtime/swprintf/test13/test13.cpp
index b99232f7ea..b99232f7ea 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test13/test13.c
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test13/test13.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test14/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swprintf/test14/CMakeLists.txt
index a052f60116..2a4b84805c 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test14/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test14/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test14.c
+ test14.cpp
)
add_executable(paltest_swprintf_test14
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test14/test14.c b/src/pal/tests/palsuite/c_runtime/swprintf/test14/test14.cpp
index bcfd6a7c24..bcfd6a7c24 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test14/test14.c
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test14/test14.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test15/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swprintf/test15/CMakeLists.txt
index 7bc2da122f..22382bce5f 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test15/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test15/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test15.c
+ test15.cpp
)
add_executable(paltest_swprintf_test15
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test15/test15.c b/src/pal/tests/palsuite/c_runtime/swprintf/test15/test15.cpp
index 215afbe093..215afbe093 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test15/test15.c
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test15/test15.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test16/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swprintf/test16/CMakeLists.txt
index e6ad3abd3f..462f0806cd 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test16/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test16/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test16.c
+ test16.cpp
)
add_executable(paltest_swprintf_test16
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test16/test16.c b/src/pal/tests/palsuite/c_runtime/swprintf/test16/test16.cpp
index 859afed8dd..859afed8dd 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test16/test16.c
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test16/test16.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test17/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swprintf/test17/CMakeLists.txt
index 401285b740..c5b4d44593 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test17/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test17/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test17.c
+ test17.cpp
)
add_executable(paltest_swprintf_test17
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test17/test17.c b/src/pal/tests/palsuite/c_runtime/swprintf/test17/test17.cpp
index 480f2b2fe1..480f2b2fe1 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test17/test17.c
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test17/test17.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test18/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swprintf/test18/CMakeLists.txt
index 210ab2c7ec..6cdf576966 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test18/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test18/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test18.c
+ test18.cpp
)
add_executable(paltest_swprintf_test18
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test18/test18.c b/src/pal/tests/palsuite/c_runtime/swprintf/test18/test18.cpp
index 1ed8cd00d8..1ed8cd00d8 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test18/test18.c
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test18/test18.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test19/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swprintf/test19/CMakeLists.txt
index b9d44a3031..334b7b4fa1 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test19/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test19/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test19.c
+ test19.cpp
)
add_executable(paltest_swprintf_test19
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test19/test19.c b/src/pal/tests/palsuite/c_runtime/swprintf/test19/test19.c
deleted file mode 100644
index 5199cc3cd9..0000000000
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test19/test19.c
+++ /dev/null
@@ -1,109 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: test19.c
-**
-** Purpose: Tests swprintf with argument specified precision
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-#include "../swprintf.h"
-
-/*
- * Uses memcmp & wcslen
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- int n = -1;
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
- DoArgumentPrecTest(convert("%.*s"), 2, convert("bar"), "bar",
- convert("ba"), convert("ba"));
- DoArgumentPrecTest(convert("%.*S"), 2, "bar", "bar", convert("ba"),
- convert("ba"));
- DoArgumentPrecTest(convert("%.*n"), 3, &n, "pointer to int", convert(""),
- convert(""));
- if (n != 0)
- {
- Fail("ERROR: Expected count parameter to resolve to %d, got %X\n",
- 0, n);
- }
-
- DoArgumentPrecTest(convert("%.*c"), 0, (void*)'a', "a", convert("a"),
- convert("a"));
- DoArgumentPrecTest(convert("%.*c"), 4, (void*)'a', "a", convert("a"),
- convert("a"));
- DoArgumentPrecTest(convert("%.*C"), 0, (void*)'a', "a", convert("a"),
- convert("a"));
- DoArgumentPrecTest(convert("%.*C"), 4, (void*)'a', "a", convert("a"),
- convert("a"));
- DoArgumentPrecTest(convert("%.*d"), 1, (void*)42, "42", convert("42"),
- convert("42"));
- DoArgumentPrecTest(convert("%.*d"), 3, (void*)42, "42", convert("042"),
- convert("042"));
- DoArgumentPrecTest(convert("%.*i"), 1, (void*)42, "42", convert("42"),
- convert("42"));
- DoArgumentPrecTest(convert("%.*i"), 3, (void*)42, "42", convert("042"),
- convert("042"));
- DoArgumentPrecTest(convert("%.*o"), 1, (void*)42, "42", convert("52"),
- convert("52"));
- DoArgumentPrecTest(convert("%.*o"), 3, (void*)42, "42", convert("052"),
- convert("052"));
- DoArgumentPrecTest(convert("%.*u"), 1, (void*)42, "42", convert("42"),
- convert("42"));
- DoArgumentPrecTest(convert("%.*u"), 3, (void*)42, "42", convert("042"),
- convert("042"));
- DoArgumentPrecTest(convert("%.*x"), 1, (void*)0x42, "0x42", convert("42"),
- convert("42"));
- DoArgumentPrecTest(convert("%.*x"), 3, (void*)0x42, "0x42", convert("042"),
- convert("042"));
- DoArgumentPrecTest(convert("%.*X"), 1, (void*)0x42, "0x42", convert("42"),
- convert("42"));
- DoArgumentPrecTest(convert("%.*X"), 3, (void*)0x42, "0x42", convert("042"),
- convert("042"));
-
-
- DoArgumentPrecDoubleTest(convert("%.*e"), 1, 2.01, convert("2.0e+000"),
- convert("2.0e+000"));
- DoArgumentPrecDoubleTest(convert("%.*e"), 3, 2.01, convert("2.010e+000"),
- convert("2.010e+000"));
- DoArgumentPrecDoubleTest(convert("%.*E"), 1, 2.01, convert("2.0E+000"),
- convert("2.0E+000"));
- DoArgumentPrecDoubleTest(convert("%.*E"), 3, 2.01, convert("2.010E+000"),
- convert("2.010E+000"));
- DoArgumentPrecDoubleTest(convert("%.*f"), 1, 2.01, convert("2.0"),
- convert("2.0"));
- DoArgumentPrecDoubleTest(convert("%.*f"), 3, 2.01, convert("2.010"),
- convert("2.010"));
- DoArgumentPrecDoubleTest(convert("%.*g"), 1, 256.01, convert("3e+002"),
- convert("3e+002"));
- DoArgumentPrecDoubleTest(convert("%.*g"), 3, 256.01, convert("256"),
- convert("256"));
- DoArgumentPrecDoubleTest(convert("%.*g"), 4, 256.01, convert("256"),
- convert("256"));
- DoArgumentPrecDoubleTest(convert("%.*g"), 6, 256.01, convert("256.01"),
- convert("256.01"));
- DoArgumentPrecDoubleTest(convert("%.*G"), 1, 256.01, convert("3E+002"),
- convert("3E+002"));
- DoArgumentPrecDoubleTest(convert("%.*G"), 3, 256.01, convert("256"),
- convert("256"));
- DoArgumentPrecDoubleTest(convert("%.*G"), 4, 256.01, convert("256"),
- convert("256"));
- DoArgumentPrecDoubleTest(convert("%.*G"), 6, 256.01, convert("256.01"),
- convert("256.01"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test19/test19.cpp b/src/pal/tests/palsuite/c_runtime/swprintf/test19/test19.cpp
new file mode 100644
index 0000000000..c0346036cd
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test19/test19.cpp
@@ -0,0 +1,109 @@
+// Licensed to the .NET Foundation under one or more 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: test19.c
+**
+** Purpose: Tests swprintf with argument specified precision
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+#include "../swprintf.h"
+
+/*
+ * Uses memcmp & wcslen
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ int n = -1;
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ DoArgumentPrecTest(convert("%.*s"), 2, (void*)convert("bar"), "bar",
+ convert("ba"), convert("ba"));
+ DoArgumentPrecTest(convert("%.*S"), 2, (void*)"bar", "bar", convert("ba"),
+ convert("ba"));
+ DoArgumentPrecTest(convert("%.*n"), 3, (void*)&n, "pointer to int", convert(""),
+ convert(""));
+ if (n != 0)
+ {
+ Fail("ERROR: Expected count parameter to resolve to %d, got %X\n",
+ 0, n);
+ }
+
+ DoArgumentPrecTest(convert("%.*c"), 0, (void*)'a', "a", convert("a"),
+ convert("a"));
+ DoArgumentPrecTest(convert("%.*c"), 4, (void*)'a', "a", convert("a"),
+ convert("a"));
+ DoArgumentPrecTest(convert("%.*C"), 0, (void*)'a', "a", convert("a"),
+ convert("a"));
+ DoArgumentPrecTest(convert("%.*C"), 4, (void*)'a', "a", convert("a"),
+ convert("a"));
+ DoArgumentPrecTest(convert("%.*d"), 1, (void*)42, "42", convert("42"),
+ convert("42"));
+ DoArgumentPrecTest(convert("%.*d"), 3, (void*)42, "42", convert("042"),
+ convert("042"));
+ DoArgumentPrecTest(convert("%.*i"), 1, (void*)42, "42", convert("42"),
+ convert("42"));
+ DoArgumentPrecTest(convert("%.*i"), 3, (void*)42, "42", convert("042"),
+ convert("042"));
+ DoArgumentPrecTest(convert("%.*o"), 1, (void*)42, "42", convert("52"),
+ convert("52"));
+ DoArgumentPrecTest(convert("%.*o"), 3, (void*)42, "42", convert("052"),
+ convert("052"));
+ DoArgumentPrecTest(convert("%.*u"), 1, (void*)42, "42", convert("42"),
+ convert("42"));
+ DoArgumentPrecTest(convert("%.*u"), 3, (void*)42, "42", convert("042"),
+ convert("042"));
+ DoArgumentPrecTest(convert("%.*x"), 1, (void*)0x42, "0x42", convert("42"),
+ convert("42"));
+ DoArgumentPrecTest(convert("%.*x"), 3, (void*)0x42, "0x42", convert("042"),
+ convert("042"));
+ DoArgumentPrecTest(convert("%.*X"), 1, (void*)0x42, "0x42", convert("42"),
+ convert("42"));
+ DoArgumentPrecTest(convert("%.*X"), 3, (void*)0x42, "0x42", convert("042"),
+ convert("042"));
+
+
+ DoArgumentPrecDoubleTest(convert("%.*e"), 1, 2.01, convert("2.0e+000"),
+ convert("2.0e+000"));
+ DoArgumentPrecDoubleTest(convert("%.*e"), 3, 2.01, convert("2.010e+000"),
+ convert("2.010e+000"));
+ DoArgumentPrecDoubleTest(convert("%.*E"), 1, 2.01, convert("2.0E+000"),
+ convert("2.0E+000"));
+ DoArgumentPrecDoubleTest(convert("%.*E"), 3, 2.01, convert("2.010E+000"),
+ convert("2.010E+000"));
+ DoArgumentPrecDoubleTest(convert("%.*f"), 1, 2.01, convert("2.0"),
+ convert("2.0"));
+ DoArgumentPrecDoubleTest(convert("%.*f"), 3, 2.01, convert("2.010"),
+ convert("2.010"));
+ DoArgumentPrecDoubleTest(convert("%.*g"), 1, 256.01, convert("3e+002"),
+ convert("3e+002"));
+ DoArgumentPrecDoubleTest(convert("%.*g"), 3, 256.01, convert("256"),
+ convert("256"));
+ DoArgumentPrecDoubleTest(convert("%.*g"), 4, 256.01, convert("256"),
+ convert("256"));
+ DoArgumentPrecDoubleTest(convert("%.*g"), 6, 256.01, convert("256.01"),
+ convert("256.01"));
+ DoArgumentPrecDoubleTest(convert("%.*G"), 1, 256.01, convert("3E+002"),
+ convert("3E+002"));
+ DoArgumentPrecDoubleTest(convert("%.*G"), 3, 256.01, convert("256"),
+ convert("256"));
+ DoArgumentPrecDoubleTest(convert("%.*G"), 4, 256.01, convert("256"),
+ convert("256"));
+ DoArgumentPrecDoubleTest(convert("%.*G"), 6, 256.01, convert("256.01"),
+ convert("256.01"));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swprintf/test2/CMakeLists.txt
index 84446d5f6d..af2b13e4c7 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_swprintf_test2
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test2/test2.c b/src/pal/tests/palsuite/c_runtime/swprintf/test2/test2.cpp
index deffd3edd7..deffd3edd7 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swprintf/test3/CMakeLists.txt
index 6dbd8a3c36..14b81f4ac8 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_swprintf_test3
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test3/test3.c b/src/pal/tests/palsuite/c_runtime/swprintf/test3/test3.cpp
index 42875c0640..42875c0640 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test3/test3.c
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test4/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swprintf/test4/CMakeLists.txt
index a665948c47..e153e6b02f 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_swprintf_test4
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test4/test4.c b/src/pal/tests/palsuite/c_runtime/swprintf/test4/test4.cpp
index 02cc3f9005..02cc3f9005 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test4/test4.c
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test5/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swprintf/test5/CMakeLists.txt
index 8268ec2963..967ccbb992 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_swprintf_test5
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test5/test5.c b/src/pal/tests/palsuite/c_runtime/swprintf/test5/test5.cpp
index e85adc120e..e85adc120e 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test5/test5.c
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test5/test5.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test6/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swprintf/test6/CMakeLists.txt
index 6a90c0b88e..806211a992 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test6.c
+ test6.cpp
)
add_executable(paltest_swprintf_test6
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test6/test6.c b/src/pal/tests/palsuite/c_runtime/swprintf/test6/test6.cpp
index ecd6374264..ecd6374264 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test6/test6.c
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test6/test6.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test7/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swprintf/test7/CMakeLists.txt
index 2b1c30cb56..cf563799d9 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test7/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test7/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test7.c
+ test7.cpp
)
add_executable(paltest_swprintf_test7
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test7/test7.c b/src/pal/tests/palsuite/c_runtime/swprintf/test7/test7.cpp
index e231ada3d2..e231ada3d2 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test7/test7.c
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test7/test7.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test8/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swprintf/test8/CMakeLists.txt
index 281e6df097..e8fcf66157 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test8/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test8/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test8.c
+ test8.cpp
)
add_executable(paltest_swprintf_test8
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test8/test8.c b/src/pal/tests/palsuite/c_runtime/swprintf/test8/test8.cpp
index b4be28e78d..b4be28e78d 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test8/test8.c
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test8/test8.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test9/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swprintf/test9/CMakeLists.txt
index 054b40a998..c616348766 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test9/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test9/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test9.c
+ test9.cpp
)
add_executable(paltest_swprintf_test9
diff --git a/src/pal/tests/palsuite/c_runtime/swprintf/test9/test9.c b/src/pal/tests/palsuite/c_runtime/swprintf/test9/test9.cpp
index 2f5429e5fd..2f5429e5fd 100644
--- a/src/pal/tests/palsuite/c_runtime/swprintf/test9/test9.c
+++ b/src/pal/tests/palsuite/c_runtime/swprintf/test9/test9.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/swscanf.h b/src/pal/tests/palsuite/c_runtime/swscanf/swscanf.h
index 1cac450cf4..6349b7dcd6 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/swscanf.h
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/swscanf.h
@@ -14,7 +14,7 @@
#ifndef __SWSCANF_H__
#define __SWSCANF_H__
-void DoVoidTest(WCHAR *inputstr, WCHAR *formatstr)
+void DoVoidTest(WCHAR *inputstr, const WCHAR *formatstr)
{
char buf[256] = { 0 };
int i;
@@ -40,7 +40,7 @@ void DoVoidTest(WCHAR *inputstr, WCHAR *formatstr)
}
-void DoStrTest(WCHAR *inputstr, WCHAR *formatstr, char *checkstr)
+void DoStrTest(WCHAR *inputstr, const WCHAR *formatstr, const char *checkstr)
{
char buf[256] = { 0 };
int ret;
@@ -63,7 +63,7 @@ void DoStrTest(WCHAR *inputstr, WCHAR *formatstr, char *checkstr)
}
-void DoWStrTest(WCHAR *inputstr, WCHAR *formatstr, WCHAR *checkstr)
+void DoWStrTest(WCHAR *inputstr, const WCHAR *formatstr, const WCHAR *checkstr)
{
WCHAR buf[256] = { 0 };
int ret;
@@ -86,7 +86,7 @@ void DoWStrTest(WCHAR *inputstr, WCHAR *formatstr, WCHAR *checkstr)
}
-void DoNumTest(WCHAR *inputstr, WCHAR *formatstr, int checknum)
+void DoNumTest(WCHAR *inputstr, const WCHAR *formatstr, int checknum)
{
int num = 0;
int ret;
@@ -107,7 +107,7 @@ void DoNumTest(WCHAR *inputstr, WCHAR *formatstr, int checknum)
}
}
-void DoShortNumTest(WCHAR *inputstr, WCHAR *formatstr, short checknum)
+void DoShortNumTest(WCHAR *inputstr, const WCHAR *formatstr, short checknum)
{
short num = 0;
int ret;
@@ -128,7 +128,7 @@ void DoShortNumTest(WCHAR *inputstr, WCHAR *formatstr, short checknum)
}
}
-void DoI64NumTest(WCHAR *inputstr, WCHAR *formatstr, INT64 checknum)
+void DoI64NumTest(WCHAR *inputstr, const WCHAR *formatstr, INT64 checknum)
{
char buf[256];
char check[256];
@@ -145,15 +145,15 @@ void DoI64NumTest(WCHAR *inputstr, WCHAR *formatstr, INT64 checknum)
if (checknum != num)
{
- sprintf(buf, "%I64d", num);
- sprintf(check, "%I64d", checknum);
+ sprintf_s(buf, _countof(buf), "%I64d", num);
+ sprintf_s(check, _countof(check), "%I64d", checknum);
Fail("ERROR: scanned I64 number incorrectly from \"%s\" using \"%s\".\n"
"Expected %s, got %s.\n", convertC(inputstr),
convertC(formatstr), check, buf);
}
}
-void DoCharTest(WCHAR *inputstr, WCHAR*formatstr, char* checkchars, int numchars)
+void DoCharTest(WCHAR *inputstr, const WCHAR *formatstr, char* checkchars, int numchars)
{
char buf[256];
int ret;
@@ -187,7 +187,7 @@ void DoCharTest(WCHAR *inputstr, WCHAR*formatstr, char* checkchars, int numchars
}
}
-void DoWCharTest(WCHAR *inputstr, WCHAR *formatstr, WCHAR *checkchars, int numchars)
+void DoWCharTest(WCHAR *inputstr, const WCHAR *formatstr, const WCHAR *checkchars, int numchars)
{
WCHAR buf[256];
int ret;
@@ -223,7 +223,7 @@ void DoWCharTest(WCHAR *inputstr, WCHAR *formatstr, WCHAR *checkchars, int numch
}
-void DoFloatTest(WCHAR *inputstr, WCHAR *formatstr, float checkval)
+void DoFloatTest(WCHAR *inputstr, const WCHAR *formatstr, float checkval)
{
char buf[256] = { 0 };
float val;
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swscanf/test1/CMakeLists.txt
index 030aaaf709..44b8939248 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_swscanf_test1
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/swscanf/test1/test1.cpp
index 66136e57c5..66136e57c5 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test10/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swscanf/test10/CMakeLists.txt
index f7c8b284ff..27d42114a9 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test10/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test10/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test10.c
+ test10.cpp
)
add_executable(paltest_swscanf_test10
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test10/test10.c b/src/pal/tests/palsuite/c_runtime/swscanf/test10/test10.cpp
index a8628e0de1..a8628e0de1 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test10/test10.c
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test10/test10.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test11/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swscanf/test11/CMakeLists.txt
index 17066f31b8..1ca9224ec0 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test11/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test11/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test11.c
+ test11.cpp
)
add_executable(paltest_swscanf_test11
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test11/test11.c b/src/pal/tests/palsuite/c_runtime/swscanf/test11/test11.cpp
index f7eb4af46f..f7eb4af46f 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test11/test11.c
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test11/test11.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test12/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swscanf/test12/CMakeLists.txt
index 95f5174ecb..44d70f47ae 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test12/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test12/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test12.c
+ test12.cpp
)
add_executable(paltest_swscanf_test12
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test12/test12.c b/src/pal/tests/palsuite/c_runtime/swscanf/test12/test12.cpp
index f5f8bbdf8a..f5f8bbdf8a 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test12/test12.c
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test12/test12.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test13/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swscanf/test13/CMakeLists.txt
index 47abc50313..add0cbfe18 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test13/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test13/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test13.c
+ test13.cpp
)
add_executable(paltest_swscanf_test13
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test13/test13.c b/src/pal/tests/palsuite/c_runtime/swscanf/test13/test13.cpp
index 1bb0b7b21c..1bb0b7b21c 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test13/test13.c
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test13/test13.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test14/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swscanf/test14/CMakeLists.txt
index a470436ce7..126e087b1c 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test14/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test14/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test14.c
+ test14.cpp
)
add_executable(paltest_swscanf_test14
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test14/test14.c b/src/pal/tests/palsuite/c_runtime/swscanf/test14/test14.cpp
index 80581b726f..80581b726f 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test14/test14.c
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test14/test14.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test15/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swscanf/test15/CMakeLists.txt
index d89650b12c..7c2da2bdf8 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test15/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test15/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test15.c
+ test15.cpp
)
add_executable(paltest_swscanf_test15
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test15/test15.c b/src/pal/tests/palsuite/c_runtime/swscanf/test15/test15.cpp
index 9b7d277e17..9b7d277e17 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test15/test15.c
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test15/test15.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test16/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swscanf/test16/CMakeLists.txt
index a2a00f11b6..ba28c4dc2f 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test16/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test16/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test16.c
+ test16.cpp
)
add_executable(paltest_swscanf_test16
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test16/test16.c b/src/pal/tests/palsuite/c_runtime/swscanf/test16/test16.cpp
index c83b64468b..c83b64468b 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test16/test16.c
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test16/test16.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test17/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swscanf/test17/CMakeLists.txt
index c224f5d9a6..225ce868ed 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test17/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test17/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test17.c
+ test17.cpp
)
add_executable(paltest_swscanf_test17
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test17/test17.c b/src/pal/tests/palsuite/c_runtime/swscanf/test17/test17.cpp
index 9023f7020a..9023f7020a 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test17/test17.c
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test17/test17.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swscanf/test2/CMakeLists.txt
index a5335ddb48..15411ecf21 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_swscanf_test2
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test2/test2.c b/src/pal/tests/palsuite/c_runtime/swscanf/test2/test2.cpp
index 8fbd3f86ba..8fbd3f86ba 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swscanf/test3/CMakeLists.txt
index 5c229c26d3..927026107a 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_swscanf_test3
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test3/test3.c b/src/pal/tests/palsuite/c_runtime/swscanf/test3/test3.cpp
index 8b05df20f2..8b05df20f2 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test3/test3.c
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test4/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swscanf/test4/CMakeLists.txt
index 5e281aaf34..eec701645b 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_swscanf_test4
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test4/test4.c b/src/pal/tests/palsuite/c_runtime/swscanf/test4/test4.cpp
index d63d25b7d0..d63d25b7d0 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test4/test4.c
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test5/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swscanf/test5/CMakeLists.txt
index 8b259aa78d..3f022db16c 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_swscanf_test5
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test5/test5.c b/src/pal/tests/palsuite/c_runtime/swscanf/test5/test5.cpp
index 8ae2d81da6..8ae2d81da6 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test5/test5.c
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test5/test5.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test6/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swscanf/test6/CMakeLists.txt
index c3fd8696ab..c55666d95c 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test6.c
+ test6.cpp
)
add_executable(paltest_swscanf_test6
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test6/test6.c b/src/pal/tests/palsuite/c_runtime/swscanf/test6/test6.cpp
index 982f799cfc..982f799cfc 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test6/test6.c
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test6/test6.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test7/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swscanf/test7/CMakeLists.txt
index 00541306df..adb0abe80d 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test7/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test7/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test7.c
+ test7.cpp
)
add_executable(paltest_swscanf_test7
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test7/test7.c b/src/pal/tests/palsuite/c_runtime/swscanf/test7/test7.cpp
index 45e9400549..45e9400549 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test7/test7.c
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test7/test7.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test8/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swscanf/test8/CMakeLists.txt
index d6aa631ab9..a69c552337 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test8/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test8/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test8.c
+ test8.cpp
)
add_executable(paltest_swscanf_test8
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test8/test8.c b/src/pal/tests/palsuite/c_runtime/swscanf/test8/test8.cpp
index a244de748f..a244de748f 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test8/test8.c
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test8/test8.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test9/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/swscanf/test9/CMakeLists.txt
index 4f7595a205..70a9fe2064 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test9/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test9/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test9.c
+ test9.cpp
)
add_executable(paltest_swscanf_test9
diff --git a/src/pal/tests/palsuite/c_runtime/swscanf/test9/test9.c b/src/pal/tests/palsuite/c_runtime/swscanf/test9/test9.cpp
index e289d26f58..e289d26f58 100644
--- a/src/pal/tests/palsuite/c_runtime/swscanf/test9/test9.c
+++ b/src/pal/tests/palsuite/c_runtime/swscanf/test9/test9.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/tan/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/tan/test1/CMakeLists.txt
index 665fc22d5e..cea661f2bb 100644
--- a/src/pal/tests/palsuite/c_runtime/tan/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/tan/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_tan_test1
diff --git a/src/pal/tests/palsuite/c_runtime/tan/test1/test1.c b/src/pal/tests/palsuite/c_runtime/tan/test1/test1.cpp
index 443e5da6d6..443e5da6d6 100644
--- a/src/pal/tests/palsuite/c_runtime/tan/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/tan/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/tanf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/tanf/CMakeLists.txt
new file mode 100644
index 0000000000..5e1ef7f28b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/tanf/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/tanf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/tanf/test1/CMakeLists.txt
new file mode 100644
index 0000000000..cd588ea23e
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/tanf/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.c
+)
+
+add_executable(paltest_tanf_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_tanf_test1 coreclrpal)
+
+target_link_libraries(paltest_tanf_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/tanf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/tanf/test1/test1.c
new file mode 100644
index 0000000000..18d5c4e59d
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/tanf/test1/test1.c
@@ -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.
+
+/*=============================================================================
+**
+** Source: test1.c
+**
+** Purpose: Test to ensure that tanf return the correct values
+**
+** Dependencies: PAL_Initialize
+** PAL_Terminate
+** Fail
+** fabs
+**
+**===========================================================================*/
+
+#include <palsuite.h>
+
+// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this
+// is slightly too accurate when writing tests meant to run against libm implementations
+// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get.
+//
+// The tests themselves will take PAL_EPSILON and adjust it according to the expected result
+// so that the delta used for comparison will compare the most significant digits and ignore
+// any digits that are outside the double precision range (6-9 digits).
+
+// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON
+// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use
+// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10.
+#define PAL_EPSILON 4.76837158e-07
+
+#define PAL_NAN sqrtf(-1.0f)
+#define PAL_POSINF -logf(0.0f)
+#define PAL_NEGINF logf(0.0f)
+
+/**
+ * Helper test structure
+ */
+struct test
+{
+ float value; /* value to test the function with */
+ float expected; /* expected result */
+ float variance; /* maximum delta between the expected and actual result */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl validate(float value, float expected, float variance)
+{
+ float result = tanf(value);
+
+ /*
+ * The test is valid when the difference between result
+ * and expected is less than or equal to variance
+ */
+ float delta = fabsf(result - expected);
+
+ if (delta > variance)
+ {
+ Fail("tanf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, expected);
+ }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl validate_isnan(float value)
+{
+ float result = tanf(value);
+
+ if (!_isnanf(result))
+ {
+ Fail("tanf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, PAL_NAN);
+ }
+}
+
+/**
+ * main
+ *
+ * executable entry point
+ */
+int __cdecl main(int argc, char **argv)
+{
+ struct test tests[] =
+ {
+ /* value expected variance */
+ { 0, 0, PAL_EPSILON },
+ { 0.318309886f, 0.329514733f, PAL_EPSILON }, // value: 1 / pi
+ { 0.434294482f, 0.463829067f, PAL_EPSILON }, // value: log10f(e)
+ { 0.636619772f, 0.739302950f, PAL_EPSILON }, // value: 2 / pi
+ { 0.693147181f, 0.830640878f, PAL_EPSILON }, // value: ln(2)
+ { 0.707106781f, 0.854510432f, PAL_EPSILON }, // value: 1 / sqrtf(2)
+ { 0.785398163f, 1, PAL_EPSILON * 10 }, // value: pi / 4
+ { 1, 1.55740772f, PAL_EPSILON * 10 },
+ { 1.12837917f, 2.11087684f, PAL_EPSILON * 10 }, // value: 2 / sqrtf(pi)
+ { 1.41421356f, 6.33411917f, PAL_EPSILON * 10 }, // value: sqrtf(2)
+ { 1.44269504f, 7.76357567f, PAL_EPSILON * 10 }, // value: logf2(e)
+ // SEE BELOW -- { 1.57079633f, PAL_POSINF, 0 }, // value: pi / 2
+ { 2.30258509f, -1.11340715f, PAL_EPSILON * 10 }, // value: ln(10)
+ { 2.71828183f, -0.450549534f, PAL_EPSILON }, // value: e
+ { 3.14159265f, 0, PAL_EPSILON }, // value: pi
+ };
+
+ /* PAL initialization */
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++)
+ {
+ validate( tests[i].value, tests[i].expected, tests[i].variance);
+ validate(-tests[i].value, -tests[i].expected, tests[i].variance);
+ }
+
+ // -- SPECIAL CASE --
+ // Normally, tanf(pi / 2) would return PAL_POSINF (atan2f(PAL_POSINF) does return (pi / 2)).
+ // However, it seems instead (on all supported systems), we get a different number entirely.
+ validate( 1.57079633f, -22877332.0, PAL_EPSILON * 100000000);
+ validate(-1.57079633f, 22877332.0, PAL_EPSILON * 100000000);
+
+ validate_isnan(PAL_NEGINF);
+ validate_isnan(PAL_NAN);
+ validate_isnan(PAL_POSINF);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/tanf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/tanf/test1/testinfo.dat
new file mode 100644
index 0000000000..aa33232adc
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/tanf/test1/testinfo.dat
@@ -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.
+
+Version = 1.0
+Section = C Runtime
+Function = tanf
+Name = Positive Test for tanf
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Passes to tanf() a series of angle value, checking that
+= each one return to correct value.
diff --git a/src/pal/tests/palsuite/c_runtime/tanh/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/tanh/test1/CMakeLists.txt
index f8e439dd95..9fe926d441 100644
--- a/src/pal/tests/palsuite/c_runtime/tanh/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/tanh/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_tanh_test1
diff --git a/src/pal/tests/palsuite/c_runtime/tanh/test1/test1.c b/src/pal/tests/palsuite/c_runtime/tanh/test1/test1.cpp
index 3b8f87964a..3b8f87964a 100644
--- a/src/pal/tests/palsuite/c_runtime/tanh/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/tanh/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/tanhf/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/tanhf/CMakeLists.txt
new file mode 100644
index 0000000000..5e1ef7f28b
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/tanhf/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
diff --git a/src/pal/tests/palsuite/c_runtime/tanhf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/tanhf/test1/CMakeLists.txt
new file mode 100644
index 0000000000..fd0af2a46f
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/tanhf/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test1.c
+)
+
+add_executable(paltest_tanhf_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_tanhf_test1 coreclrpal)
+
+target_link_libraries(paltest_tanhf_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/c_runtime/tanhf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/tanhf/test1/test1.c
new file mode 100644
index 0000000000..904729a2c4
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/tanhf/test1/test1.c
@@ -0,0 +1,129 @@
+// Licensed to the .NET Foundation under one or more 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: test1.c
+**
+** Purpose: Test to ensure that tanhf return the correct values
+**
+** Dependencies: PAL_Initialize
+** PAL_Terminate
+** Fail
+** fabs
+**
+**===========================================================================*/
+
+#include <palsuite.h>
+
+// binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this
+// is slightly too accurate when writing tests meant to run against libm implementations
+// for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get.
+//
+// The tests themselves will take PAL_EPSILON and adjust it according to the expected result
+// so that the delta used for comparison will compare the most significant digits and ignore
+// any digits that are outside the double precision range (6-9 digits).
+
+// For example, a test with an expect result in the format of 0.xxxxxxxxx will use PAL_EPSILON
+// for the variance, while an expected result in the format of 0.0xxxxxxxxx will use
+// PAL_EPSILON / 10 and and expected result in the format of x.xxxxxx will use PAL_EPSILON * 10.
+#define PAL_EPSILON 4.76837158e-07
+
+#define PAL_NAN sqrtf(-1.0f)
+#define PAL_POSINF -logf(0.0f)
+#define PAL_NEGINF logf(0.0f)
+
+/**
+ * Helper test structure
+ */
+struct test
+{
+ float value; /* value to test the function with */
+ float expected; /* expected result */
+ float variance; /* maximum delta between the expected and actual result */
+};
+
+/**
+ * validate
+ *
+ * test validation function
+ */
+void __cdecl validate(float value, float expected, float variance)
+{
+ float result = tanhf(value);
+
+ /*
+ * The test is valid when the difference between result
+ * and expected is less than or equal to variance
+ */
+ float delta = fabsf(result - expected);
+
+ if (delta > variance)
+ {
+ Fail("tanhf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, expected);
+ }
+}
+
+/**
+ * validate
+ *
+ * test validation function for values returning NaN
+ */
+void __cdecl validate_isnan(float value)
+{
+ float result = tanhf(value);
+
+ if (!_isnanf(result))
+ {
+ Fail("tanhf(%g) returned %10.9g when it should have returned %10.9g",
+ value, result, PAL_NAN);
+ }
+}
+
+/**
+ * main
+ *
+ * executable entry point
+ */
+int __cdecl main(int argc, char **argv)
+{
+ struct test tests[] =
+ {
+ /* value expected variance */
+ { 0, 0, PAL_EPSILON },
+ { 0.318309886f, 0.307977913f, PAL_EPSILON }, // value: 1 / pi
+ { 0.434294482f, 0.408904012f, PAL_EPSILON }, // value: log10f(e)
+ { 0.636619772f, 0.562593600f, PAL_EPSILON }, // value: 2 / pi
+ { 0.693147181f, 0.6f, PAL_EPSILON }, // value: ln(2)
+ { 0.707106781f, 0.608859365f, PAL_EPSILON }, // value: 1 / sqrtf(2)
+ { 0.785398163f, 0.655794203f, PAL_EPSILON }, // value: pi / 4
+ { 1, 0.761594156f, PAL_EPSILON },
+ { 1.12837917f, 0.810463806f, PAL_EPSILON }, // value: 2 / sqrtf(pi)
+ { 1.41421356f, 0.888385562f, PAL_EPSILON }, // value: sqrtf(2)
+ { 1.44269504f, 0.894238946f, PAL_EPSILON }, // value: logf2(e)
+ { 1.57079633f, 0.917152336f, PAL_EPSILON }, // value: pi / 2
+ { 2.30258509f, 0.980198020f, PAL_EPSILON }, // value: ln(10)
+ { 2.71828183f, 0.991328916f, PAL_EPSILON }, // value: e
+ { 3.14159265f, 0.996272076f, PAL_EPSILON }, // value: pi
+ { PAL_POSINF, 1, PAL_EPSILON * 10 }
+ };
+
+ /* PAL initialization */
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ for (int i = 0; i < (sizeof(tests) / sizeof(struct test)); i++)
+ {
+ validate( tests[i].value, tests[i].expected, tests[i].variance);
+ validate(-tests[i].value, -tests[i].expected, tests[i].variance);
+ }
+
+ validate_isnan(PAL_NAN);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/tanhf/test1/testinfo.dat b/src/pal/tests/palsuite/c_runtime/tanhf/test1/testinfo.dat
new file mode 100644
index 0000000000..6c7594fc5a
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/tanhf/test1/testinfo.dat
@@ -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.
+
+Version = 1.0
+Section = C Runtime
+Function = tanhf
+Name = Positive Test for tanhf
+TYPE = DEFAULT
+EXE1 = test1
+Description
+= Passes to tanhf() a series of angle value, checking that
+= each one return to correct value.
diff --git a/src/pal/tests/palsuite/c_runtime/time/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/time/test1/CMakeLists.txt
index d495266cef..64df144557 100644
--- a/src/pal/tests/palsuite/c_runtime/time/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/time/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_time_test1
diff --git a/src/pal/tests/palsuite/c_runtime/time/test1/test1.c b/src/pal/tests/palsuite/c_runtime/time/test1/test1.cpp
index c668bf38e7..c668bf38e7 100644
--- a/src/pal/tests/palsuite/c_runtime/time/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/time/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/tolower/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/tolower/test1/CMakeLists.txt
index 537f239cf8..214a509010 100644
--- a/src/pal/tests/palsuite/c_runtime/tolower/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/tolower/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_tolower_test1
diff --git a/src/pal/tests/palsuite/c_runtime/tolower/test1/test1.c b/src/pal/tests/palsuite/c_runtime/tolower/test1/test1.cpp
index cab623d3f9..cab623d3f9 100644
--- a/src/pal/tests/palsuite/c_runtime/tolower/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/tolower/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/toupper/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/toupper/test1/CMakeLists.txt
index e5aa375a9b..3dd536c590 100644
--- a/src/pal/tests/palsuite/c_runtime/toupper/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/toupper/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_toupper_test1
diff --git a/src/pal/tests/palsuite/c_runtime/toupper/test1/test1.c b/src/pal/tests/palsuite/c_runtime/toupper/test1/test1.cpp
index c580699e3b..c580699e3b 100644
--- a/src/pal/tests/palsuite/c_runtime/toupper/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/toupper/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/towlower/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/towlower/test1/CMakeLists.txt
index 2a3e6a07ef..77a46344d4 100644
--- a/src/pal/tests/palsuite/c_runtime/towlower/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/towlower/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_towlower_test1
diff --git a/src/pal/tests/palsuite/c_runtime/towlower/test1/test1.c b/src/pal/tests/palsuite/c_runtime/towlower/test1/test1.cpp
index 5f2457a5fe..5f2457a5fe 100644
--- a/src/pal/tests/palsuite/c_runtime/towlower/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/towlower/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/towupper/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/towupper/test1/CMakeLists.txt
index 537efbe0fa..6a2f813cc9 100644
--- a/src/pal/tests/palsuite/c_runtime/towupper/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/towupper/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_towupper_test1
diff --git a/src/pal/tests/palsuite/c_runtime/towupper/test1/test1.c b/src/pal/tests/palsuite/c_runtime/towupper/test1/test1.cpp
index 63f051fa66..63f051fa66 100644
--- a/src/pal/tests/palsuite/c_runtime/towupper/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/towupper/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/ungetc/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/ungetc/test1/CMakeLists.txt
index da19397e2c..0286f99b77 100644
--- a/src/pal/tests/palsuite/c_runtime/ungetc/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/ungetc/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- ungetc.c
+ ungetc.cpp
)
add_executable(paltest_ungetc_test1
diff --git a/src/pal/tests/palsuite/c_runtime/ungetc/test1/ungetc.c b/src/pal/tests/palsuite/c_runtime/ungetc/test1/ungetc.cpp
index 397e42ac64..397e42ac64 100644
--- a/src/pal/tests/palsuite/c_runtime/ungetc/test1/ungetc.c
+++ b/src/pal/tests/palsuite/c_runtime/ungetc/test1/ungetc.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/ungetc/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/ungetc/test2/CMakeLists.txt
index 7b63423628..0710074bd0 100644
--- a/src/pal/tests/palsuite/c_runtime/ungetc/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/ungetc/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- ungetc.c
+ ungetc.cpp
)
add_executable(paltest_ungetc_test2
diff --git a/src/pal/tests/palsuite/c_runtime/ungetc/test2/ungetc.c b/src/pal/tests/palsuite/c_runtime/ungetc/test2/ungetc.cpp
index cbc8102eec..cbc8102eec 100644
--- a/src/pal/tests/palsuite/c_runtime/ungetc/test2/ungetc.c
+++ b/src/pal/tests/palsuite/c_runtime/ungetc/test2/ungetc.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vfprintf/test1/CMakeLists.txt
index 4c967fbc5b..fcff4a2074 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_vfprintf_test1
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/vfprintf/test1/test1.cpp
index 302c914e3a..302c914e3a 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test10/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vfprintf/test10/CMakeLists.txt
index e154107e36..97c7b167ab 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test10/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test10/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test10.c
+ test10.cpp
)
add_executable(paltest_vfprintf_test10
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test10/test10.c b/src/pal/tests/palsuite/c_runtime/vfprintf/test10/test10.cpp
index ecb4b0314a..ecb4b0314a 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test10/test10.c
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test10/test10.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test11/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vfprintf/test11/CMakeLists.txt
index f51f379bcd..9250eb957d 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test11/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test11/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test11.c
+ test11.cpp
)
add_executable(paltest_vfprintf_test11
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test11/test11.c b/src/pal/tests/palsuite/c_runtime/vfprintf/test11/test11.cpp
index 5f7bc118cc..5f7bc118cc 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test11/test11.c
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test11/test11.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test12/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vfprintf/test12/CMakeLists.txt
index 3ef68cff70..53d3488b4a 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test12/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test12/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test12.c
+ test12.cpp
)
add_executable(paltest_vfprintf_test12
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test12/test12.c b/src/pal/tests/palsuite/c_runtime/vfprintf/test12/test12.cpp
index 0bf61d3ecc..0bf61d3ecc 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test12/test12.c
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test12/test12.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test13/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vfprintf/test13/CMakeLists.txt
index cd34f6649c..c35813b420 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test13/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test13/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test13.c
+ test13.cpp
)
add_executable(paltest_vfprintf_test13
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test13/test13.c b/src/pal/tests/palsuite/c_runtime/vfprintf/test13/test13.cpp
index 1e42ce9e8d..1e42ce9e8d 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test13/test13.c
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test13/test13.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test14/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vfprintf/test14/CMakeLists.txt
index 396a4631c5..bd91f509b5 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test14/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test14/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test14.c
+ test14.cpp
)
add_executable(paltest_vfprintf_test14
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test14/test14.c b/src/pal/tests/palsuite/c_runtime/vfprintf/test14/test14.cpp
index 82f247430f..82f247430f 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test14/test14.c
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test14/test14.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test15/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vfprintf/test15/CMakeLists.txt
index b9ddbe3b4a..30003b82f8 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test15/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test15/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test15.c
+ test15.cpp
)
add_executable(paltest_vfprintf_test15
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test15/test15.c b/src/pal/tests/palsuite/c_runtime/vfprintf/test15/test15.cpp
index 53cc2ceb87..53cc2ceb87 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test15/test15.c
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test15/test15.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test16/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vfprintf/test16/CMakeLists.txt
index 0fd4177ed8..a287f120a0 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test16/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test16/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test16.c
+ test16.cpp
)
add_executable(paltest_vfprintf_test16
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test16/test16.c b/src/pal/tests/palsuite/c_runtime/vfprintf/test16/test16.cpp
index 2b7674bb94..2b7674bb94 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test16/test16.c
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test16/test16.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test17/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vfprintf/test17/CMakeLists.txt
index afc0b3828d..cf1afd9d2d 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test17/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test17/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test17.c
+ test17.cpp
)
add_executable(paltest_vfprintf_test17
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test17/test17.c b/src/pal/tests/palsuite/c_runtime/vfprintf/test17/test17.cpp
index 956be15f6f..956be15f6f 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test17/test17.c
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test17/test17.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test18/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vfprintf/test18/CMakeLists.txt
index 9e373b999e..143eade9b3 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test18/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test18/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test18.c
+ test18.cpp
)
add_executable(paltest_vfprintf_test18
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test18/test18.c b/src/pal/tests/palsuite/c_runtime/vfprintf/test18/test18.cpp
index c61c8cbdab..c61c8cbdab 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test18/test18.c
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test18/test18.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test19/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vfprintf/test19/CMakeLists.txt
index 3120c9117f..452d929b7d 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test19/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test19/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test19.c
+ test19.cpp
)
add_executable(paltest_vfprintf_test19
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test19/test19.c b/src/pal/tests/palsuite/c_runtime/vfprintf/test19/test19.c
deleted file mode 100644
index e88ce23663..0000000000
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test19/test19.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test19.c
-**
-** Purpose: Test #19 for the vfprintf function. Tests the variable length
-** precision argument.
-**
-**
-**==========================================================================*/
-
-
-#include <palsuite.h>
-#include "../vfprintf.h"
-
-
-
-
-int __cdecl main(int argc, char *argv[])
-{
- int n = -1;
-
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
- DoArgumentPrecTest("%.*s", 2, "bar", "bar", "ba", "ba");
- DoArgumentPrecTest("%.*S", 2, convert("bar"), "bar", "ba", "ba");
-
- DoArgumentPrecTest("%.*n ", 3, &n, "pointer to int", " ", " ");
- if (n != 0)
- {
- Fail("ERROR: Expected count parameter to resolve to %d, got %X\n",
- 0, n);
- }
-
- DoArgumentPrecTest("%.*c", 0, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*c", 4, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*C", 0, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*C", 4, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*d", 1, (void*)42, "42", "42", "42");
- DoArgumentPrecTest("%.*d", 3, (void*)42, "42", "042", "042");
- DoArgumentPrecTest("%.*i", 1, (void*)42, "42", "42", "42");
- DoArgumentPrecTest("%.*i", 3, (void*)42, "42", "042", "042");
- DoArgumentPrecTest("%.*o", 1, (void*)42, "42", "52", "52");
- DoArgumentPrecTest("%.*o", 3, (void*)42, "42", "052", "052");
- DoArgumentPrecTest("%.*u", 1, (void*)42, "42", "42", "42");
- DoArgumentPrecTest("%.*u", 3, (void*)42, "42", "042", "042");
- DoArgumentPrecTest("%.*x", 1, (void*)0x42, "0x42", "42", "42");
- DoArgumentPrecTest("%.*x", 3, (void*)0x42, "0x42", "042", "042");
- DoArgumentPrecTest("%.*X", 1, (void*)0x42, "0x42", "42", "42");
- DoArgumentPrecTest("%.*X", 3, (void*)0x42, "0x42", "042", "042");
-
-
- DoArgumentPrecDoubleTest("%.*e", 1, 2.01, "2.0e+000", "2.0e+00");
- DoArgumentPrecDoubleTest("%.*e", 3, 2.01, "2.010e+000", "2.010e+00");
- DoArgumentPrecDoubleTest("%.*E", 1, 2.01, "2.0E+000", "2.0E+00");
- DoArgumentPrecDoubleTest("%.*E", 3, 2.01, "2.010E+000", "2.010E+00");
- DoArgumentPrecDoubleTest("%.*f", 1, 2.01, "2.0", "2.0");
- DoArgumentPrecDoubleTest("%.*f", 3, 2.01, "2.010", "2.010");
- DoArgumentPrecDoubleTest("%.*g", 1, 256.01, "3e+002", "3e+02");
- DoArgumentPrecDoubleTest("%.*g", 3, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*g", 4, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*g", 6, 256.01, "256.01", "256.01");
- DoArgumentPrecDoubleTest("%.*G", 1, 256.01, "3E+002", "3E+02");
- DoArgumentPrecDoubleTest("%.*G", 3, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*G", 4, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*G", 6, 256.01, "256.01", "256.01");
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test19/test19.cpp b/src/pal/tests/palsuite/c_runtime/vfprintf/test19/test19.cpp
new file mode 100644
index 0000000000..d8e8f9301d
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test19/test19.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test19.c
+**
+** Purpose: Test #19 for the vfprintf function. Tests the variable length
+** precision argument.
+**
+**
+**==========================================================================*/
+
+
+#include <palsuite.h>
+#include "../vfprintf.h"
+
+
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ int n = -1;
+
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ DoArgumentPrecTest("%.*s", 2, (void*)"bar", "bar", "ba", "ba");
+ DoArgumentPrecTest("%.*S", 2, (void*)convert("bar"), "bar", "ba", "ba");
+
+ DoArgumentPrecTest("%.*n ", 3, (void*)&n, "pointer to int", " ", " ");
+ if (n != 0)
+ {
+ Fail("ERROR: Expected count parameter to resolve to %d, got %X\n",
+ 0, n);
+ }
+
+ DoArgumentPrecTest("%.*c", 0, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*c", 4, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*C", 0, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*C", 4, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*d", 1, (void*)42, "42", "42", "42");
+ DoArgumentPrecTest("%.*d", 3, (void*)42, "42", "042", "042");
+ DoArgumentPrecTest("%.*i", 1, (void*)42, "42", "42", "42");
+ DoArgumentPrecTest("%.*i", 3, (void*)42, "42", "042", "042");
+ DoArgumentPrecTest("%.*o", 1, (void*)42, "42", "52", "52");
+ DoArgumentPrecTest("%.*o", 3, (void*)42, "42", "052", "052");
+ DoArgumentPrecTest("%.*u", 1, (void*)42, "42", "42", "42");
+ DoArgumentPrecTest("%.*u", 3, (void*)42, "42", "042", "042");
+ DoArgumentPrecTest("%.*x", 1, (void*)0x42, "0x42", "42", "42");
+ DoArgumentPrecTest("%.*x", 3, (void*)0x42, "0x42", "042", "042");
+ DoArgumentPrecTest("%.*X", 1, (void*)0x42, "0x42", "42", "42");
+ DoArgumentPrecTest("%.*X", 3, (void*)0x42, "0x42", "042", "042");
+
+
+ DoArgumentPrecDoubleTest("%.*e", 1, 2.01, "2.0e+000", "2.0e+00");
+ DoArgumentPrecDoubleTest("%.*e", 3, 2.01, "2.010e+000", "2.010e+00");
+ DoArgumentPrecDoubleTest("%.*E", 1, 2.01, "2.0E+000", "2.0E+00");
+ DoArgumentPrecDoubleTest("%.*E", 3, 2.01, "2.010E+000", "2.010E+00");
+ DoArgumentPrecDoubleTest("%.*f", 1, 2.01, "2.0", "2.0");
+ DoArgumentPrecDoubleTest("%.*f", 3, 2.01, "2.010", "2.010");
+ DoArgumentPrecDoubleTest("%.*g", 1, 256.01, "3e+002", "3e+02");
+ DoArgumentPrecDoubleTest("%.*g", 3, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*g", 4, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*g", 6, 256.01, "256.01", "256.01");
+ DoArgumentPrecDoubleTest("%.*G", 1, 256.01, "3E+002", "3E+02");
+ DoArgumentPrecDoubleTest("%.*G", 3, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*G", 4, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*G", 6, 256.01, "256.01", "256.01");
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vfprintf/test2/CMakeLists.txt
index 6e700090d6..b18fb712c6 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_vfprintf_test2
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test2/test2.c b/src/pal/tests/palsuite/c_runtime/vfprintf/test2/test2.cpp
index d01117f047..d01117f047 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vfprintf/test3/CMakeLists.txt
index 1a14d85603..a8f7eb1991 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_vfprintf_test3
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test3/test3.c b/src/pal/tests/palsuite/c_runtime/vfprintf/test3/test3.cpp
index 0081daa426..0081daa426 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test3/test3.c
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test4/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vfprintf/test4/CMakeLists.txt
index c1285942bc..60c31693a5 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_vfprintf_test4
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test4/test4.c b/src/pal/tests/palsuite/c_runtime/vfprintf/test4/test4.cpp
index d24f08d6e0..d24f08d6e0 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test4/test4.c
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test5/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vfprintf/test5/CMakeLists.txt
index 0cccdfd630..5f516fec6a 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_vfprintf_test5
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test5/test5.c b/src/pal/tests/palsuite/c_runtime/vfprintf/test5/test5.cpp
index 44f21b61db..44f21b61db 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test5/test5.c
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test5/test5.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test6/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vfprintf/test6/CMakeLists.txt
index 2c036a45ae..7f0cc710af 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test6.c
+ test6.cpp
)
add_executable(paltest_vfprintf_test6
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test6/test6.c b/src/pal/tests/palsuite/c_runtime/vfprintf/test6/test6.cpp
index 36c6fe51ca..36c6fe51ca 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test6/test6.c
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test6/test6.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test7/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vfprintf/test7/CMakeLists.txt
index ca483af773..a2cd9a2e8f 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test7/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test7/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test7.c
+ test7.cpp
)
add_executable(paltest_vfprintf_test7
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test7/test7.c b/src/pal/tests/palsuite/c_runtime/vfprintf/test7/test7.cpp
index a9cfe319bd..a9cfe319bd 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test7/test7.c
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test7/test7.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test8/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vfprintf/test8/CMakeLists.txt
index 89459b4e93..a7b20ee43e 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test8/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test8/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test8.c
+ test8.cpp
)
add_executable(paltest_vfprintf_test8
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test8/test8.c b/src/pal/tests/palsuite/c_runtime/vfprintf/test8/test8.cpp
index 5cef99741a..5cef99741a 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test8/test8.c
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test8/test8.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test9/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vfprintf/test9/CMakeLists.txt
index 3e3b5b99ed..242b635f93 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test9/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test9/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test9.c
+ test9.cpp
)
add_executable(paltest_vfprintf_test9
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/test9/test9.c b/src/pal/tests/palsuite/c_runtime/vfprintf/test9/test9.cpp
index 45d0dc7a9e..45d0dc7a9e 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/test9/test9.c
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/test9/test9.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vfprintf/vfprintf.h b/src/pal/tests/palsuite/c_runtime/vfprintf/vfprintf.h
index f4ae7a53fa..7901b08b0d 100644
--- a/src/pal/tests/palsuite/c_runtime/vfprintf/vfprintf.h
+++ b/src/pal/tests/palsuite/c_runtime/vfprintf/vfprintf.h
@@ -14,7 +14,7 @@
#ifndef __vfprintf_H__
#define __vfprintf_H__
-int DoVfprintf(FILE *fp, char *format, ...)
+int DoVfprintf(FILE *fp, const char *format, ...)
{
int retVal;
va_list arglist;
@@ -26,7 +26,7 @@ int DoVfprintf(FILE *fp, char *format, ...)
return (retVal);
}
-void DoStrTest(char *formatstr, char* param, char *checkstr)
+void DoStrTest(const char *formatstr, char* param, const char *checkstr)
{
FILE *fp;
char buf[256] = { 0 };
@@ -57,7 +57,7 @@ void DoStrTest(char *formatstr, char* param, char *checkstr)
fclose(fp);
}
-void DoWStrTest(char *formatstr, WCHAR* param, char *checkstr)
+void DoWStrTest(const char *formatstr, WCHAR* param, const char *checkstr)
{
FILE *fp;
char buf[256] = { 0 };
@@ -89,8 +89,8 @@ void DoWStrTest(char *formatstr, WCHAR* param, char *checkstr)
}
-void DoPointerTest(char *formatstr, void* param, char* paramstr,
- char *checkstr1)
+void DoPointerTest(const char *formatstr, void* param, char* paramstr,
+ const char *checkstr1)
{
FILE *fp;
char buf[256] = { 0 };
@@ -130,7 +130,7 @@ void DoPointerTest(char *formatstr, void* param, char* paramstr,
-void DoCountTest(char *formatstr, int param, char *checkstr)
+void DoCountTest(const char *formatstr, int param, const char *checkstr)
{
FILE *fp;
char buf[512] = { 0 };
@@ -173,7 +173,7 @@ void DoCountTest(char *formatstr, int param, char *checkstr)
}
}
-void DoShortCountTest(char *formatstr, int param, char *checkstr)
+void DoShortCountTest(const char *formatstr, int param, const char *checkstr)
{
FILE *fp;
char buf[512] = { 0 };
@@ -217,7 +217,7 @@ void DoShortCountTest(char *formatstr, int param, char *checkstr)
}
-void DoCharTest(char *formatstr, char param, char *checkstr)
+void DoCharTest(const char *formatstr, char param, const char *checkstr)
{
FILE *fp;
char buf[256] = { 0 };
@@ -248,7 +248,7 @@ void DoCharTest(char *formatstr, char param, char *checkstr)
fclose(fp);
}
-void DoWCharTest(char *formatstr, WCHAR param, char *checkstr)
+void DoWCharTest(const char *formatstr, WCHAR param, const char *checkstr)
{
FILE *fp;
char buf[256] = { 0 };
@@ -279,7 +279,7 @@ void DoWCharTest(char *formatstr, WCHAR param, char *checkstr)
fclose(fp);
}
-void DoNumTest(char *formatstr, int value, char *checkstr)
+void DoNumTest(const char *formatstr, int value, const char *checkstr)
{
FILE *fp;
char buf[256] = { 0 };
@@ -310,7 +310,7 @@ void DoNumTest(char *formatstr, int value, char *checkstr)
fclose(fp);
}
-void DoI64Test(char *formatstr, INT64 value, char *valuestr, char *checkstr1)
+void DoI64Test(const char *formatstr, INT64 value, char *valuestr, const char *checkstr1)
{
FILE *fp;
char buf[256] = { 0 };
@@ -341,8 +341,8 @@ void DoI64Test(char *formatstr, INT64 value, char *valuestr, char *checkstr1)
fclose(fp);
}
-void DoDoubleTest(char *formatstr, double value, char *checkstr1,
- char *checkstr2)
+void DoDoubleTest(const char *formatstr, double value, const char *checkstr1,
+ const char *checkstr2)
{
FILE *fp;
char buf[256] = { 0 };
@@ -376,8 +376,8 @@ void DoDoubleTest(char *formatstr, double value, char *checkstr1,
}
-void DoArgumentPrecTest(char *formatstr, int precision, void *param,
- char *paramstr, char *checkstr1, char *checkstr2)
+void DoArgumentPrecTest(const char *formatstr, int precision, void *param,
+ char *paramstr, const char *checkstr1, const char *checkstr2)
{
FILE *fp;
char buf[256];
@@ -418,8 +418,8 @@ void DoArgumentPrecTest(char *formatstr, int precision, void *param,
}
-void DoArgumentPrecDoubleTest(char *formatstr, int precision, double param,
- char *checkstr1, char *checkstr2)
+void DoArgumentPrecDoubleTest(const char *formatstr, int precision, double param,
+ const char *checkstr1, const char *checkstr2)
{
FILE *fp;
char buf[256];
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vprintf/test1/CMakeLists.txt
index eabdf87393..9d866e16a2 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_vprintf_test1
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/vprintf/test1/test1.cpp
index 404d7a0dc9..404d7a0dc9 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test10/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vprintf/test10/CMakeLists.txt
index 47a21d909a..4ed04b46c6 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test10/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test10/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test10.c
+ test10.cpp
)
add_executable(paltest_vprintf_test10
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test10/test10.c b/src/pal/tests/palsuite/c_runtime/vprintf/test10/test10.cpp
index b363d7c02c..b363d7c02c 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test10/test10.c
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test10/test10.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test11/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vprintf/test11/CMakeLists.txt
index 4c750b72ac..5dc3c6dc69 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test11/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test11/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test11.c
+ test11.cpp
)
add_executable(paltest_vprintf_test11
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test11/test11.c b/src/pal/tests/palsuite/c_runtime/vprintf/test11/test11.cpp
index f5157ac99f..f5157ac99f 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test11/test11.c
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test11/test11.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test12/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vprintf/test12/CMakeLists.txt
index 1feb886fc1..a8104296c4 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test12/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test12/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test12.c
+ test12.cpp
)
add_executable(paltest_vprintf_test12
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test12/test12.c b/src/pal/tests/palsuite/c_runtime/vprintf/test12/test12.cpp
index 703a8c4fdc..703a8c4fdc 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test12/test12.c
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test12/test12.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test13/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vprintf/test13/CMakeLists.txt
index cd7535a1ad..df98081ed7 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test13/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test13/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test13.c
+ test13.cpp
)
add_executable(paltest_vprintf_test13
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test13/test13.c b/src/pal/tests/palsuite/c_runtime/vprintf/test13/test13.cpp
index ecb83ba38d..ecb83ba38d 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test13/test13.c
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test13/test13.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test14/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vprintf/test14/CMakeLists.txt
index 82cfd68ecf..b903d4e241 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test14/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test14/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test14.c
+ test14.cpp
)
add_executable(paltest_vprintf_test14
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test14/test14.c b/src/pal/tests/palsuite/c_runtime/vprintf/test14/test14.cpp
index 536c1950e3..536c1950e3 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test14/test14.c
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test14/test14.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test15/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vprintf/test15/CMakeLists.txt
index 29a134d48c..659ed9cb44 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test15/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test15/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test15.c
+ test15.cpp
)
add_executable(paltest_vprintf_test15
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test15/test15.c b/src/pal/tests/palsuite/c_runtime/vprintf/test15/test15.cpp
index 9aff6e457d..9aff6e457d 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test15/test15.c
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test15/test15.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test16/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vprintf/test16/CMakeLists.txt
index 7fbf43ac84..b2f7fe8b78 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test16/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test16/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test16.c
+ test16.cpp
)
add_executable(paltest_vprintf_test16
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test16/test16.c b/src/pal/tests/palsuite/c_runtime/vprintf/test16/test16.cpp
index 66e9afe2d7..66e9afe2d7 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test16/test16.c
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test16/test16.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test17/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vprintf/test17/CMakeLists.txt
index 25970cba15..76cfc9ad06 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test17/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test17/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test17.c
+ test17.cpp
)
add_executable(paltest_vprintf_test17
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test17/test17.c b/src/pal/tests/palsuite/c_runtime/vprintf/test17/test17.cpp
index d36a084903..d36a084903 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test17/test17.c
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test17/test17.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test18/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vprintf/test18/CMakeLists.txt
index 45676b93dd..633fb7ee51 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test18/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test18/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test18.c
+ test18.cpp
)
add_executable(paltest_vprintf_test18
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test18/test18.c b/src/pal/tests/palsuite/c_runtime/vprintf/test18/test18.cpp
index 6fde79b5fb..6fde79b5fb 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test18/test18.c
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test18/test18.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test19/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vprintf/test19/CMakeLists.txt
index 25bc2fccd1..1a6256ad0b 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test19/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test19/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test19.c
+ test19.cpp
)
add_executable(paltest_vprintf_test19
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test19/test19.c b/src/pal/tests/palsuite/c_runtime/vprintf/test19/test19.c
deleted file mode 100644
index d79f2e2591..0000000000
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test19/test19.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test19.c
-**
-** Purpose: Test #19 for the vprintf function. Tests the variable length
-** precision argument.
-**
-**
-**==========================================================================*/
-
-
-#include <palsuite.h>
-#include "../vprintf.h"
-
-
-
-
-int __cdecl main(int argc, char *argv[])
-{
- int n = -1;
-
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
- DoArgumentPrecTest("%.*s", 2, "bar", "bar", "ba", "ba");
- DoArgumentPrecTest("%.*S", 2, convert("bar"), "bar", "ba", "ba");
-
- DoArgumentPrecTest("%.*n", 3, &n, "pointer to int", "", "");
- if (n != 0)
- {
- Fail("ERROR: Expected count parameter to resolve to %d, got %X\n",
- 0, n);
- }
-
- DoArgumentPrecTest("%.*c", 0, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*c", 4, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*C", 0, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*C", 4, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*d", 1, (void*)42, "42", "42", "42");
- DoArgumentPrecTest("%.*d", 3, (void*)42, "42", "042", "042");
- DoArgumentPrecTest("%.*i", 1, (void*)42, "42", "42", "42");
- DoArgumentPrecTest("%.*i", 3, (void*)42, "42", "042", "042");
- DoArgumentPrecTest("%.*o", 1, (void*)42, "42", "52", "52");
- DoArgumentPrecTest("%.*o", 3, (void*)42, "42", "052", "052");
- DoArgumentPrecTest("%.*u", 1, (void*)42, "42", "42", "42");
- DoArgumentPrecTest("%.*u", 3, (void*)42, "42", "042", "042");
- DoArgumentPrecTest("%.*x", 1, (void*)0x42, "0x42", "42", "42");
- DoArgumentPrecTest("%.*x", 3, (void*)0x42, "0x42", "042", "042");
- DoArgumentPrecTest("%.*X", 1, (void*)0x42, "0x42", "42", "42");
- DoArgumentPrecTest("%.*X", 3, (void*)0x42, "0x42", "042", "042");
-
-
- DoArgumentPrecDoubleTest("%.*e", 1, 2.01, "2.0e+000", "2.0e+00");
- DoArgumentPrecDoubleTest("%.*e", 3, 2.01, "2.010e+000", "2.010e+00");
- DoArgumentPrecDoubleTest("%.*E", 1, 2.01, "2.0E+000", "2.0E+00");
- DoArgumentPrecDoubleTest("%.*E", 3, 2.01, "2.010E+000", "2.010E+00");
- DoArgumentPrecDoubleTest("%.*f", 1, 2.01, "2.0", "2.0");
- DoArgumentPrecDoubleTest("%.*f", 3, 2.01, "2.010", "2.010");
- DoArgumentPrecDoubleTest("%.*g", 1, 256.01, "3e+002", "3e+02");
- DoArgumentPrecDoubleTest("%.*g", 3, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*g", 4, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*g", 6, 256.01, "256.01", "256.01");
- DoArgumentPrecDoubleTest("%.*G", 1, 256.01, "3E+002", "3E+02");
- DoArgumentPrecDoubleTest("%.*G", 3, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*G", 4, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*G", 6, 256.01, "256.01", "256.01");
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test19/test19.cpp b/src/pal/tests/palsuite/c_runtime/vprintf/test19/test19.cpp
new file mode 100644
index 0000000000..a3e0877369
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test19/test19.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test19.c
+**
+** Purpose: Test #19 for the vprintf function. Tests the variable length
+** precision argument.
+**
+**
+**==========================================================================*/
+
+
+#include <palsuite.h>
+#include "../vprintf.h"
+
+
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ int n = -1;
+
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ DoArgumentPrecTest("%.*s", 2, (void*)"bar", "bar", "ba", "ba");
+ DoArgumentPrecTest("%.*S", 2, (void*)convert("bar"), "bar", "ba", "ba");
+
+ DoArgumentPrecTest("%.*n", 3, (void*)&n, "pointer to int", "", "");
+ if (n != 0)
+ {
+ Fail("ERROR: Expected count parameter to resolve to %d, got %X\n",
+ 0, n);
+ }
+
+ DoArgumentPrecTest("%.*c", 0, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*c", 4, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*C", 0, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*C", 4, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*d", 1, (void*)42, "42", "42", "42");
+ DoArgumentPrecTest("%.*d", 3, (void*)42, "42", "042", "042");
+ DoArgumentPrecTest("%.*i", 1, (void*)42, "42", "42", "42");
+ DoArgumentPrecTest("%.*i", 3, (void*)42, "42", "042", "042");
+ DoArgumentPrecTest("%.*o", 1, (void*)42, "42", "52", "52");
+ DoArgumentPrecTest("%.*o", 3, (void*)42, "42", "052", "052");
+ DoArgumentPrecTest("%.*u", 1, (void*)42, "42", "42", "42");
+ DoArgumentPrecTest("%.*u", 3, (void*)42, "42", "042", "042");
+ DoArgumentPrecTest("%.*x", 1, (void*)0x42, "0x42", "42", "42");
+ DoArgumentPrecTest("%.*x", 3, (void*)0x42, "0x42", "042", "042");
+ DoArgumentPrecTest("%.*X", 1, (void*)0x42, "0x42", "42", "42");
+ DoArgumentPrecTest("%.*X", 3, (void*)0x42, "0x42", "042", "042");
+
+
+ DoArgumentPrecDoubleTest("%.*e", 1, 2.01, "2.0e+000", "2.0e+00");
+ DoArgumentPrecDoubleTest("%.*e", 3, 2.01, "2.010e+000", "2.010e+00");
+ DoArgumentPrecDoubleTest("%.*E", 1, 2.01, "2.0E+000", "2.0E+00");
+ DoArgumentPrecDoubleTest("%.*E", 3, 2.01, "2.010E+000", "2.010E+00");
+ DoArgumentPrecDoubleTest("%.*f", 1, 2.01, "2.0", "2.0");
+ DoArgumentPrecDoubleTest("%.*f", 3, 2.01, "2.010", "2.010");
+ DoArgumentPrecDoubleTest("%.*g", 1, 256.01, "3e+002", "3e+02");
+ DoArgumentPrecDoubleTest("%.*g", 3, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*g", 4, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*g", 6, 256.01, "256.01", "256.01");
+ DoArgumentPrecDoubleTest("%.*G", 1, 256.01, "3E+002", "3E+02");
+ DoArgumentPrecDoubleTest("%.*G", 3, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*G", 4, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*G", 6, 256.01, "256.01", "256.01");
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vprintf/test2/CMakeLists.txt
index 6820069cb9..41e2073477 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_vprintf_test2
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test2/test2.c b/src/pal/tests/palsuite/c_runtime/vprintf/test2/test2.cpp
index 4d9c9bc6f5..4d9c9bc6f5 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vprintf/test3/CMakeLists.txt
index 676d19bf7a..8570666b11 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_vprintf_test3
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test3/test3.c b/src/pal/tests/palsuite/c_runtime/vprintf/test3/test3.cpp
index 5376c56b76..5376c56b76 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test3/test3.c
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test4/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vprintf/test4/CMakeLists.txt
index 9ddb087e83..06b582b5ee 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_vprintf_test4
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test4/test4.c b/src/pal/tests/palsuite/c_runtime/vprintf/test4/test4.cpp
index 3b66cde22e..3b66cde22e 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test4/test4.c
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test5/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vprintf/test5/CMakeLists.txt
index f453bb66ee..3a1828a28c 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_vprintf_test5
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test5/test5.c b/src/pal/tests/palsuite/c_runtime/vprintf/test5/test5.cpp
index c9e2901230..c9e2901230 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test5/test5.c
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test5/test5.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test6/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vprintf/test6/CMakeLists.txt
index 1ce8d5aa4c..2dac7703e6 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test6.c
+ test6.cpp
)
add_executable(paltest_vprintf_test6
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test6/test6.c b/src/pal/tests/palsuite/c_runtime/vprintf/test6/test6.cpp
index 6a83cccea6..6a83cccea6 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test6/test6.c
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test6/test6.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test7/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vprintf/test7/CMakeLists.txt
index 5627fe4c1e..5a520045a9 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test7/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test7/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test7.c
+ test7.cpp
)
add_executable(paltest_vprintf_test7
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test7/test7.c b/src/pal/tests/palsuite/c_runtime/vprintf/test7/test7.cpp
index 5096ace42c..5096ace42c 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test7/test7.c
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test7/test7.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test8/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vprintf/test8/CMakeLists.txt
index 0131e4943e..18e4e3a0c9 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test8/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test8/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test8.c
+ test8.cpp
)
add_executable(paltest_vprintf_test8
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test8/test8.c b/src/pal/tests/palsuite/c_runtime/vprintf/test8/test8.cpp
index 2683339ece..2683339ece 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test8/test8.c
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test8/test8.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test9/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vprintf/test9/CMakeLists.txt
index c70631f9dc..8bcbe81f51 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test9/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test9/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test9.c
+ test9.cpp
)
add_executable(paltest_vprintf_test9
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/test9/test9.c b/src/pal/tests/palsuite/c_runtime/vprintf/test9/test9.cpp
index 8545bc760e..8545bc760e 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/test9/test9.c
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/test9/test9.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vprintf/vprintf.h b/src/pal/tests/palsuite/c_runtime/vprintf/vprintf.h
index 477db32f4d..fcd8f80370 100644
--- a/src/pal/tests/palsuite/c_runtime/vprintf/vprintf.h
+++ b/src/pal/tests/palsuite/c_runtime/vprintf/vprintf.h
@@ -14,7 +14,7 @@
#ifndef __vprintf_H__
#define __vprintf_H__
-int DoVprintf(char *format, ...)
+int DoVprintf(const char *format, ...)
{
int retVal;
va_list arglist;
@@ -26,7 +26,7 @@ int DoVprintf(char *format, ...)
return (retVal);
}
-void DoStrTest(char *formatstr, char* param, char *checkstr)
+void DoStrTest(const char *formatstr, char* param, const char *checkstr)
{
int ret;
@@ -38,7 +38,7 @@ void DoStrTest(char *formatstr, char* param, char *checkstr)
}
}
-void DoWStrTest(char *formatstr, WCHAR* param, char *checkstr)
+void DoWStrTest(const char *formatstr, WCHAR* param, const char *checkstr)
{
int ret;
@@ -50,8 +50,8 @@ void DoWStrTest(char *formatstr, WCHAR* param, char *checkstr)
}
}
-void DoPointerTest(char *formatstr, void* param, char* paramstr,
- char *checkstr1)
+void DoPointerTest(const char *formatstr, void* param, char* paramstr,
+ const char *checkstr1)
{
int ret;
@@ -63,7 +63,7 @@ void DoPointerTest(char *formatstr, void* param, char* paramstr,
}
}
-void DoCountTest(char *formatstr, int param, char *checkstr)
+void DoCountTest(const char *formatstr, int param, const char *checkstr)
{
int ret;
int n = -1;
@@ -82,7 +82,7 @@ void DoCountTest(char *formatstr, int param, char *checkstr)
}
}
-void DoShortCountTest(char *formatstr, int param, char *checkstr)
+void DoShortCountTest(const char *formatstr, int param, const char *checkstr)
{
int ret;
short int n = -1;
@@ -102,7 +102,7 @@ void DoShortCountTest(char *formatstr, int param, char *checkstr)
}
-void DoCharTest(char *formatstr, char param, char *checkstr)
+void DoCharTest(const char *formatstr, char param, const char *checkstr)
{
int ret;
@@ -114,7 +114,7 @@ void DoCharTest(char *formatstr, char param, char *checkstr)
}
}
-void DoWCharTest(char *formatstr, WCHAR param, char *checkstr)
+void DoWCharTest(const char *formatstr, WCHAR param, const char *checkstr)
{
int ret;
@@ -126,7 +126,7 @@ void DoWCharTest(char *formatstr, WCHAR param, char *checkstr)
}
}
-void DoNumTest(char *formatstr, int param, char *checkstr)
+void DoNumTest(const char *formatstr, int param, const char *checkstr)
{
int ret;
@@ -138,7 +138,7 @@ void DoNumTest(char *formatstr, int param, char *checkstr)
}
}
-void DoI64Test(char *formatstr, INT64 param, char *valuestr, char *checkstr1)
+void DoI64Test(const char *formatstr, INT64 param, char *valuestr, const char *checkstr1)
{
int ret;
@@ -150,8 +150,8 @@ void DoI64Test(char *formatstr, INT64 param, char *valuestr, char *checkstr1)
}
}
-void DoDoubleTest(char *formatstr, double param, char *checkstr1,
- char *checkstr2)
+void DoDoubleTest(const char *formatstr, double param, const char *checkstr1,
+ const char *checkstr2)
{
int ret;
@@ -163,8 +163,8 @@ void DoDoubleTest(char *formatstr, double param, char *checkstr1,
}
}
-void DoArgumentPrecTest(char *formatstr, int precision, void *param,
- char *paramstr, char *checkstr1, char *checkstr2)
+void DoArgumentPrecTest(const char *formatstr, int precision, void *param,
+ char *paramstr, const char *checkstr1, const char *checkstr2)
{
int ret;
@@ -176,8 +176,8 @@ void DoArgumentPrecTest(char *formatstr, int precision, void *param,
}
}
-void DoArgumentPrecDoubleTest(char *formatstr, int precision, double param,
- char *checkstr1, char *checkstr2)
+void DoArgumentPrecDoubleTest(const char *formatstr, int precision, double param,
+ const char *checkstr1, const char *checkstr2)
{
int ret;
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vsprintf/test1/CMakeLists.txt
index 4f0872eccc..6861157c1b 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_vsprintf_test1
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/vsprintf/test1/test1.cpp
index 2007fefc5b..2007fefc5b 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test10/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vsprintf/test10/CMakeLists.txt
index d32de01ba1..6f535a5098 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test10/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test10/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test10.c
+ test10.cpp
)
add_executable(paltest_vsprintf_test10
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test10/test10.c b/src/pal/tests/palsuite/c_runtime/vsprintf/test10/test10.cpp
index 791213fccc..791213fccc 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test10/test10.c
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test10/test10.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test11/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vsprintf/test11/CMakeLists.txt
index ce67444c39..3fa628f77d 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test11/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test11/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test11.c
+ test11.cpp
)
add_executable(paltest_vsprintf_test11
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test11/test11.c b/src/pal/tests/palsuite/c_runtime/vsprintf/test11/test11.cpp
index e0af94981b..e0af94981b 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test11/test11.c
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test11/test11.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test12/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vsprintf/test12/CMakeLists.txt
index fe6ccb8399..f34f76abc5 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test12/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test12/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test12.c
+ test12.cpp
)
add_executable(paltest_vsprintf_test12
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test12/test12.c b/src/pal/tests/palsuite/c_runtime/vsprintf/test12/test12.cpp
index f86ddcade8..f86ddcade8 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test12/test12.c
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test12/test12.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test13/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vsprintf/test13/CMakeLists.txt
index 97fdf8cdd0..df23693f10 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test13/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test13/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test13.c
+ test13.cpp
)
add_executable(paltest_vsprintf_test13
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test13/test13.c b/src/pal/tests/palsuite/c_runtime/vsprintf/test13/test13.cpp
index 36e7825531..36e7825531 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test13/test13.c
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test13/test13.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test14/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vsprintf/test14/CMakeLists.txt
index 2851a8893e..394b5ab97c 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test14/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test14/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test14.c
+ test14.cpp
)
add_executable(paltest_vsprintf_test14
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test14/test14.c b/src/pal/tests/palsuite/c_runtime/vsprintf/test14/test14.cpp
index 360fafc37f..360fafc37f 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test14/test14.c
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test14/test14.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test15/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vsprintf/test15/CMakeLists.txt
index 6fb1d321b8..4793b45663 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test15/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test15/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test15.c
+ test15.cpp
)
add_executable(paltest_vsprintf_test15
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test15/test15.c b/src/pal/tests/palsuite/c_runtime/vsprintf/test15/test15.cpp
index a5b4c94226..a5b4c94226 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test15/test15.c
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test15/test15.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test16/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vsprintf/test16/CMakeLists.txt
index ccc21378fc..6a0a52ddf7 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test16/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test16/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test16.c
+ test16.cpp
)
add_executable(paltest_vsprintf_test16
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test16/test16.c b/src/pal/tests/palsuite/c_runtime/vsprintf/test16/test16.cpp
index a7258db9d6..a7258db9d6 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test16/test16.c
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test16/test16.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test17/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vsprintf/test17/CMakeLists.txt
index 4c9dcd986f..4e220dab77 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test17/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test17/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test17.c
+ test17.cpp
)
add_executable(paltest_vsprintf_test17
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test17/test17.c b/src/pal/tests/palsuite/c_runtime/vsprintf/test17/test17.cpp
index 0ad246a1ae..0ad246a1ae 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test17/test17.c
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test17/test17.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test18/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vsprintf/test18/CMakeLists.txt
index 2e8610d4a5..4dd68c2987 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test18/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test18/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test18.c
+ test18.cpp
)
add_executable(paltest_vsprintf_test18
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test18/test18.c b/src/pal/tests/palsuite/c_runtime/vsprintf/test18/test18.cpp
index 9a45305562..9a45305562 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test18/test18.c
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test18/test18.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test19/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vsprintf/test19/CMakeLists.txt
index 92e39ab597..3156a59a15 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test19/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test19/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test19.c
+ test19.cpp
)
add_executable(paltest_vsprintf_test19
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test19/test19.c b/src/pal/tests/palsuite/c_runtime/vsprintf/test19/test19.c
deleted file mode 100644
index 18590ed51b..0000000000
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test19/test19.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: test19.c
-**
-** Purpose: Test #19 for the vsprintf function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-#include "../vsprintf.h"
-
-/*
- * Notes: memcmp is used, as is strlen.
- */
-
-int __cdecl main(int argc, char *argv[])
-{
-
- if (PAL_Initialize(argc, argv) != 0)
- {
- return(FAIL);
- }
-
-
- DoArgumentPrecTest("%.*s", 2, "bar", "bar", "ba", "ba");
- DoArgumentPrecTest("%.*S", 2, convert("bar"), "bar", "ba", "ba");
- DoArgumentPrecTest("%.*c", 0, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*c", 4, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*C", 0, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*C", 4, (void*)'a', "a", "a", "a");
- DoArgumentPrecTest("%.*d", 1, (void*)42, "42", "42", "42");
- DoArgumentPrecTest("%.*d", 3, (void*)42, "42", "042", "042");
- DoArgumentPrecTest("%.*i", 1, (void*)42, "42", "42", "42");
- DoArgumentPrecTest("%.*i", 3, (void*)42, "42", "042", "042");
- DoArgumentPrecTest("%.*o", 1, (void*)42, "42", "52", "52");
- DoArgumentPrecTest("%.*o", 3, (void*)42, "42", "052", "052");
- DoArgumentPrecTest("%.*u", 1, (void*)42, "42", "42", "42");
- DoArgumentPrecTest("%.*u", 3, (void*)42, "42", "042", "042");
- DoArgumentPrecTest("%.*x", 1, (void*)0x42, "0x42", "42", "42");
- DoArgumentPrecTest("%.*x", 3, (void*)0x42, "0x42", "042", "042");
- DoArgumentPrecTest("%.*X", 1, (void*)0x42, "0x42", "42", "42");
- DoArgumentPrecTest("%.*X", 3, (void*)0x42, "0x42", "042", "042");
-
-
- DoArgumentPrecDoubleTest("%.*e", 1, 2.01, "2.0e+000", "2.0e+00");
- DoArgumentPrecDoubleTest("%.*e", 3, 2.01, "2.010e+000", "2.010e+00");
- DoArgumentPrecDoubleTest("%.*E", 1, 2.01, "2.0E+000", "2.0E+00");
- DoArgumentPrecDoubleTest("%.*E", 3, 2.01, "2.010E+000", "2.010E+00");
- DoArgumentPrecDoubleTest("%.*f", 1, 2.01, "2.0", "2.0");
- DoArgumentPrecDoubleTest("%.*f", 3, 2.01, "2.010", "2.010");
- DoArgumentPrecDoubleTest("%.*g", 1, 256.01, "3e+002", "3e+02");
- DoArgumentPrecDoubleTest("%.*g", 3, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*g", 4, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*g", 6, 256.01, "256.01", "256.01");
- DoArgumentPrecDoubleTest("%.*G", 1, 256.01, "3E+002", "3E+02");
- DoArgumentPrecDoubleTest("%.*G", 3, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*G", 4, 256.01, "256", "256");
- DoArgumentPrecDoubleTest("%.*G", 6, 256.01, "256.01", "256.01");
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test19/test19.cpp b/src/pal/tests/palsuite/c_runtime/vsprintf/test19/test19.cpp
new file mode 100644
index 0000000000..698ff36e35
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test19/test19.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.
+
+/*=====================================================================
+**
+** Source: test19.c
+**
+** Purpose: Test #19 for the vsprintf function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+#include "../vsprintf.h"
+
+/*
+ * Notes: memcmp is used, as is strlen.
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ if (PAL_Initialize(argc, argv) != 0)
+ {
+ return(FAIL);
+ }
+
+
+ DoArgumentPrecTest("%.*s", 2, (void*)"bar", "bar", "ba", "ba");
+ DoArgumentPrecTest("%.*S", 2, (void*)convert("bar"), "bar", "ba", "ba");
+ DoArgumentPrecTest("%.*c", 0, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*c", 4, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*C", 0, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*C", 4, (void*)'a', "a", "a", "a");
+ DoArgumentPrecTest("%.*d", 1, (void*)42, "42", "42", "42");
+ DoArgumentPrecTest("%.*d", 3, (void*)42, "42", "042", "042");
+ DoArgumentPrecTest("%.*i", 1, (void*)42, "42", "42", "42");
+ DoArgumentPrecTest("%.*i", 3, (void*)42, "42", "042", "042");
+ DoArgumentPrecTest("%.*o", 1, (void*)42, "42", "52", "52");
+ DoArgumentPrecTest("%.*o", 3, (void*)42, "42", "052", "052");
+ DoArgumentPrecTest("%.*u", 1, (void*)42, "42", "42", "42");
+ DoArgumentPrecTest("%.*u", 3, (void*)42, "42", "042", "042");
+ DoArgumentPrecTest("%.*x", 1, (void*)0x42, "0x42", "42", "42");
+ DoArgumentPrecTest("%.*x", 3, (void*)0x42, "0x42", "042", "042");
+ DoArgumentPrecTest("%.*X", 1, (void*)0x42, "0x42", "42", "42");
+ DoArgumentPrecTest("%.*X", 3, (void*)0x42, "0x42", "042", "042");
+
+
+ DoArgumentPrecDoubleTest("%.*e", 1, 2.01, "2.0e+000", "2.0e+00");
+ DoArgumentPrecDoubleTest("%.*e", 3, 2.01, "2.010e+000", "2.010e+00");
+ DoArgumentPrecDoubleTest("%.*E", 1, 2.01, "2.0E+000", "2.0E+00");
+ DoArgumentPrecDoubleTest("%.*E", 3, 2.01, "2.010E+000", "2.010E+00");
+ DoArgumentPrecDoubleTest("%.*f", 1, 2.01, "2.0", "2.0");
+ DoArgumentPrecDoubleTest("%.*f", 3, 2.01, "2.010", "2.010");
+ DoArgumentPrecDoubleTest("%.*g", 1, 256.01, "3e+002", "3e+02");
+ DoArgumentPrecDoubleTest("%.*g", 3, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*g", 4, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*g", 6, 256.01, "256.01", "256.01");
+ DoArgumentPrecDoubleTest("%.*G", 1, 256.01, "3E+002", "3E+02");
+ DoArgumentPrecDoubleTest("%.*G", 3, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*G", 4, 256.01, "256", "256");
+ DoArgumentPrecDoubleTest("%.*G", 6, 256.01, "256.01", "256.01");
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vsprintf/test2/CMakeLists.txt
index 2308bc2573..210224f0f1 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_vsprintf_test2
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test2/test2.c b/src/pal/tests/palsuite/c_runtime/vsprintf/test2/test2.cpp
index fbd4b41068..fbd4b41068 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vsprintf/test3/CMakeLists.txt
index aef24171fc..5581051f9f 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_vsprintf_test3
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test3/test3.c b/src/pal/tests/palsuite/c_runtime/vsprintf/test3/test3.cpp
index 742370ebe9..742370ebe9 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test3/test3.c
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test4/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vsprintf/test4/CMakeLists.txt
index 9570255475..88817fcffb 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_vsprintf_test4
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test4/test4.c b/src/pal/tests/palsuite/c_runtime/vsprintf/test4/test4.cpp
index dc43a9e2c7..dc43a9e2c7 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test4/test4.c
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test5/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vsprintf/test5/CMakeLists.txt
index 34a3e6243f..6d14bf76bf 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_vsprintf_test5
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test5/test5.c b/src/pal/tests/palsuite/c_runtime/vsprintf/test5/test5.cpp
index e630d8863b..e630d8863b 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test5/test5.c
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test5/test5.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test6/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vsprintf/test6/CMakeLists.txt
index dccca0b2b7..606fe3b965 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test6.c
+ test6.cpp
)
add_executable(paltest_vsprintf_test6
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test6/test6.c b/src/pal/tests/palsuite/c_runtime/vsprintf/test6/test6.cpp
index 0d38a3a114..0d38a3a114 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test6/test6.c
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test6/test6.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test7/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vsprintf/test7/CMakeLists.txt
index 7f18de056e..2dee276968 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test7/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test7/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test7.c
+ test7.cpp
)
add_executable(paltest_vsprintf_test7
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test7/test7.c b/src/pal/tests/palsuite/c_runtime/vsprintf/test7/test7.cpp
index c9f87d4343..c9f87d4343 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test7/test7.c
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test7/test7.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test8/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vsprintf/test8/CMakeLists.txt
index 34c92e1045..8dac76fc3a 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test8/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test8/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test8.c
+ test8.cpp
)
add_executable(paltest_vsprintf_test8
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test8/test8.c b/src/pal/tests/palsuite/c_runtime/vsprintf/test8/test8.cpp
index e741d1da8b..e741d1da8b 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test8/test8.c
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test8/test8.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test9/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vsprintf/test9/CMakeLists.txt
index 1fe177de95..95f0faad87 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test9/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test9/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test9.c
+ test9.cpp
)
add_executable(paltest_vsprintf_test9
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/test9/test9.c b/src/pal/tests/palsuite/c_runtime/vsprintf/test9/test9.cpp
index e1f7c84195..e1f7c84195 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/test9/test9.c
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/test9/test9.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vsprintf/vsprintf.h b/src/pal/tests/palsuite/c_runtime/vsprintf/vsprintf.h
index 10648d896f..7b04a777ca 100644
--- a/src/pal/tests/palsuite/c_runtime/vsprintf/vsprintf.h
+++ b/src/pal/tests/palsuite/c_runtime/vsprintf/vsprintf.h
@@ -26,7 +26,7 @@ int testvsp(char* buf, const char* format, ...)
return (retVal);
}
-void DoStrTest(char *formatstr, char* param, char *checkstr)
+void DoStrTest(const char *formatstr, char* param, const char *checkstr)
{
char buf[256] = { 0 };
@@ -39,7 +39,7 @@ void DoStrTest(char *formatstr, char* param, char *checkstr)
}
}
-void DoWStrTest(char *formatstr, WCHAR* param, char *checkstr)
+void DoWStrTest(const char *formatstr, WCHAR* param, const char *checkstr)
{
char buf[256] = { 0 };
@@ -53,7 +53,7 @@ void DoWStrTest(char *formatstr, WCHAR* param, char *checkstr)
}
-void DoCharTest(char *formatstr, char param, char *checkstr)
+void DoCharTest(const char *formatstr, char param, const char *checkstr)
{
char buf[256] = { 0 };
@@ -66,7 +66,7 @@ void DoCharTest(char *formatstr, char param, char *checkstr)
}
}
-void DoWCharTest(char *formatstr, WCHAR param, char *checkstr)
+void DoWCharTest(const char *formatstr, WCHAR param, const char *checkstr)
{
char buf[256] = { 0 };
@@ -79,7 +79,7 @@ void DoWCharTest(char *formatstr, WCHAR param, char *checkstr)
}
}
-void DoNumTest(char *formatstr, int value, char *checkstr)
+void DoNumTest(const char *formatstr, int value, const char *checkstr)
{
char buf[256] = { 0 };
@@ -92,7 +92,7 @@ void DoNumTest(char *formatstr, int value, char *checkstr)
}
}
-void DoI64Test(char *formatstr, INT64 value, char *valuestr, char *checkstr)
+void DoI64Test(const char *formatstr, INT64 value, char *valuestr, const char *checkstr)
{
char buf[256] = { 0 };
@@ -104,7 +104,7 @@ void DoI64Test(char *formatstr, INT64 value, char *valuestr, char *checkstr)
valuestr, formatstr, checkstr, buf);
}
}
-void DoDoubleTest(char *formatstr, double value, char *checkstr1, char
+void DoDoubleTest(const char *formatstr, double value, const char *checkstr1, char
*checkstr2)
{
char buf[256] = { 0 };
@@ -119,8 +119,8 @@ void DoDoubleTest(char *formatstr, double value, char *checkstr1, char
}
}
/*FROM TEST 9*/
-void DoArgumentPrecTest(char *formatstr, int precision, void *param,
- char *paramstr, char *checkstr1, char *checkstr2)
+void DoArgumentPrecTest(const char *formatstr, int precision, void *param,
+ char *paramstr, const char *checkstr1, const char *checkstr2)
{
char buf[256];
@@ -135,8 +135,8 @@ void DoArgumentPrecTest(char *formatstr, int precision, void *param,
}
-void DoArgumentPrecDoubleTest(char *formatstr, int precision, double param,
- char *checkstr1, char *checkstr2)
+void DoArgumentPrecDoubleTest(const char *formatstr, int precision, double param,
+ const char *checkstr1, const char *checkstr2)
{
char buf[256];
@@ -150,8 +150,8 @@ void DoArgumentPrecDoubleTest(char *formatstr, int precision, double param,
}
}
/*FROM TEST4*/
-void DoPointerTest(char *formatstr, void* param, char* paramstr,
- char *checkstr1)
+void DoPointerTest(const char *formatstr, void* param, char* paramstr,
+ const char *checkstr1)
{
char buf[256] = { 0 };
@@ -164,8 +164,8 @@ void DoPointerTest(char *formatstr, void* param, char* paramstr,
}
}
-void DoI64DoubleTest(char *formatstr, INT64 value, char *valuestr,
- char *checkstr1)
+void DoI64DoubleTest(const char *formatstr, INT64 value, char *valuestr,
+ const char *checkstr1)
{
char buf[256] = { 0 };
@@ -178,7 +178,7 @@ void DoI64DoubleTest(char *formatstr, INT64 value, char *valuestr,
}
}
-void DoTest(char *formatstr, int param, char *checkstr)
+void DoTest(const char *formatstr, int param, const char *checkstr)
{
char buf[256] = { 0 };
int n = -1;
@@ -196,7 +196,7 @@ void DoTest(char *formatstr, int param, char *checkstr)
}
}
-void DoShortTest(char *formatstr, int param, char *checkstr)
+void DoShortTest(const char *formatstr, int param, const char *checkstr)
{
char buf[256] = { 0 };
short int n = -1;
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vswprintf/test1/CMakeLists.txt
index 97fbeb4e28..1d6233744a 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_vswprintf_test1
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/vswprintf/test1/test1.cpp
index d386ce104f..d386ce104f 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test10/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vswprintf/test10/CMakeLists.txt
index 06c11f68ca..e5301427eb 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test10/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test10/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test10.c
+ test10.cpp
)
add_executable(paltest_vswprintf_test10
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test10/test10.c b/src/pal/tests/palsuite/c_runtime/vswprintf/test10/test10.cpp
index 7f316e28f6..7f316e28f6 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test10/test10.c
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test10/test10.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test11/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vswprintf/test11/CMakeLists.txt
index 5237ba4e1d..1cfadb9300 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test11/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test11/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test11.c
+ test11.cpp
)
add_executable(paltest_vswprintf_test11
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test11/test11.c b/src/pal/tests/palsuite/c_runtime/vswprintf/test11/test11.cpp
index 608069f829..608069f829 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test11/test11.c
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test11/test11.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test12/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vswprintf/test12/CMakeLists.txt
index 26199c3dcc..f5a582a970 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test12/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test12/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test12.c
+ test12.cpp
)
add_executable(paltest_vswprintf_test12
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test12/test12.c b/src/pal/tests/palsuite/c_runtime/vswprintf/test12/test12.cpp
index 36b203853a..36b203853a 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test12/test12.c
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test12/test12.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test13/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vswprintf/test13/CMakeLists.txt
index d0acd98d64..5571d7336f 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test13/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test13/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test13.c
+ test13.cpp
)
add_executable(paltest_vswprintf_test13
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test13/test13.c b/src/pal/tests/palsuite/c_runtime/vswprintf/test13/test13.cpp
index 63dc36a960..63dc36a960 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test13/test13.c
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test13/test13.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test14/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vswprintf/test14/CMakeLists.txt
index 06c12674a4..234029ead4 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test14/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test14/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test14.c
+ test14.cpp
)
add_executable(paltest_vswprintf_test14
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test14/test14.c b/src/pal/tests/palsuite/c_runtime/vswprintf/test14/test14.cpp
index bb4ab16a54..bb4ab16a54 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test14/test14.c
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test14/test14.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test15/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vswprintf/test15/CMakeLists.txt
index 05dc41b0d8..b705268bc7 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test15/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test15/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test15.c
+ test15.cpp
)
add_executable(paltest_vswprintf_test15
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test15/test15.c b/src/pal/tests/palsuite/c_runtime/vswprintf/test15/test15.cpp
index 6296220c4e..6296220c4e 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test15/test15.c
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test15/test15.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test16/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vswprintf/test16/CMakeLists.txt
index 3c42755043..da296bcf32 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test16/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test16/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test16.c
+ test16.cpp
)
add_executable(paltest_vswprintf_test16
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test16/test16.c b/src/pal/tests/palsuite/c_runtime/vswprintf/test16/test16.cpp
index 3a2059a491..3a2059a491 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test16/test16.c
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test16/test16.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test17/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vswprintf/test17/CMakeLists.txt
index b94c466d5f..02234c1672 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test17/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test17/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test17.c
+ test17.cpp
)
add_executable(paltest_vswprintf_test17
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test17/test17.c b/src/pal/tests/palsuite/c_runtime/vswprintf/test17/test17.cpp
index 95e3bd9995..95e3bd9995 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test17/test17.c
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test17/test17.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test18/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vswprintf/test18/CMakeLists.txt
index 57cc8ccb03..0c0e5b566b 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test18/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test18/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test18.c
+ test18.cpp
)
add_executable(paltest_vswprintf_test18
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test18/test18.c b/src/pal/tests/palsuite/c_runtime/vswprintf/test18/test18.cpp
index ae7ae4c44b..ae7ae4c44b 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test18/test18.c
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test18/test18.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test19/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vswprintf/test19/CMakeLists.txt
index 2187b58727..066db8ab84 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test19/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test19/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test19.c
+ test19.cpp
)
add_executable(paltest_vswprintf_test19
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test19/test19.c b/src/pal/tests/palsuite/c_runtime/vswprintf/test19/test19.c
deleted file mode 100644
index c00185be6d..0000000000
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test19/test19.c
+++ /dev/null
@@ -1,137 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: test18.c
-**
-** Purpose: Test #18 for the vswprintf function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-#include "../vswprintf.h"
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with wcslen */
-
-#define DOTEST(a,b,c,d,e) DoTest(a,b,(void*)c,d,e)
-
-void DoArgumentPrecTest(WCHAR *formatstr, int precision, void *param,
- WCHAR *paramstr, WCHAR *checkstr1, WCHAR *checkstr2)
-{
- WCHAR buf[256];
-
- testvswp(buf, formatstr, precision, param);
- if (memcmp(buf, checkstr1, wcslen(checkstr1) + 2) != 0 &&
- memcmp(buf, checkstr2, wcslen(checkstr2) + 2) != 0)
- {
- Fail("ERROR: failed to insert %s into \"%s\" with precision %d\n"
- "Expected \"%s\" or \"%s\", got \"%s\".\n",
- paramstr,
- convertC(formatstr),
- precision,
- convertC(checkstr1),
- convertC(checkstr2),
- convertC(buf));
- }
-}
-void DoArgumentPrecDoubleTest(WCHAR *formatstr, int precision, double param,
- WCHAR *checkstr1, WCHAR *checkstr2)
-{
- WCHAR buf[256];
-
- testvswp(buf, formatstr, precision, param);
- if (memcmp(buf, checkstr1, wcslen(checkstr1) + 2) != 0 &&
- memcmp(buf, checkstr2, wcslen(checkstr2) + 2) != 0)
- {
- Fail("ERROR: failed to insert %f into \"%s\" with precision %d\n"
- "Expected \"%s\" or \"%s\", got \"%s\".\n",
- param, convertC(formatstr),
- precision,
- convertC(checkstr1),
- convertC(checkstr2),
- convertC(buf));
- }
-}
-
-/*
- * Uses memcmp & wcslen
- */
-
-int __cdecl main(int argc, char *argv[])
-{
-
- if (PAL_Initialize(argc, argv) != 0)
- return(FAIL);
-
- DoArgumentPrecTest(convert("%.*s"), 2, convert("bar"), convert("bar"),
- convert("ba"), convert("ba"));
- DoArgumentPrecTest(convert("%.*c"), 0, (void*)'a', convert("a"),
- convert("a"), convert("a"));
- DoArgumentPrecTest(convert("%.*c"), 4, (void*)'a', convert("a"),
- convert("a"), convert("a"));
- DoArgumentPrecTest(convert("%.*C"), 0, (void*)'a', convert("a"),
- convert("a"), convert("a"));
- DoArgumentPrecTest(convert("%.*C"), 4, (void*)'a', convert("a"),
- convert("a"), convert("a"));
- DoArgumentPrecTest(convert("%.*d"), 1, (void*)42, convert("42"),
- convert("42"), convert("42"));
- DoArgumentPrecTest(convert("%.*d"), 3, (void*)42, convert("42"),
- convert("042"), convert("042"));
- DoArgumentPrecTest(convert("%.*i"), 1, (void*)42, convert("42"),
- convert("42"), convert("42"));
- DoArgumentPrecTest(convert("%.*i"), 3, (void*)42, convert("42"),
- convert("042"), convert("042"));
- DoArgumentPrecTest(convert("%.*o"), 1, (void*)42, convert("42"),
- convert("52"), convert("52"));
- DoArgumentPrecTest(convert("%.*o"), 3, (void*)42, convert("42"),
- convert("052"), convert("052"));
- DoArgumentPrecTest(convert("%.*u"), 1, (void*)42, convert("42"),
- convert("42"), convert("42"));
- DoArgumentPrecTest(convert("%.*u"), 3, (void*)42, convert("42"),
- convert("042"), convert("042"));
- DoArgumentPrecTest(convert("%.*x"), 1, (void*)0x42, convert("0x42"),
- convert("42"), convert("42"));
- DoArgumentPrecTest(convert("%.*x"), 3, (void*)0x42, convert("0x42"),
- convert("042"), convert("042"));
- DoArgumentPrecTest(convert("%.*X"), 1, (void*)0x42, convert("0x42"),
- convert("42"), convert("42"));
- DoArgumentPrecTest(convert("%.*X"), 3, (void*)0x42, convert("0x42"),
- convert("042"), convert("042"));
-
-
- DoArgumentPrecDoubleTest(convert("%.*e"), 1, 2.01, convert("2.0e+000"),
- convert("2.0e+00"));
- DoArgumentPrecDoubleTest(convert("%.*e"), 3, 2.01, convert("2.010e+000"),
- convert("2.010e+00"));
- DoArgumentPrecDoubleTest(convert("%.*E"), 1, 2.01, convert("2.0E+000"),
- convert("2.0E+00"));
- DoArgumentPrecDoubleTest(convert("%.*E"), 3, 2.01, convert("2.010E+000"),
- convert("2.010E+00"));
- DoArgumentPrecDoubleTest(convert("%.*f"), 1, 2.01, convert("2.0"),
- convert("2.0"));
- DoArgumentPrecDoubleTest(convert("%.*f"), 3, 2.01, convert("2.010"),
- convert("2.010"));
- DoArgumentPrecDoubleTest(convert("%.*g"), 1, 256.01, convert("3e+002"),
- convert("3e+02"));
- DoArgumentPrecDoubleTest(convert("%.*g"), 3, 256.01, convert("256"),
- convert("256"));
- DoArgumentPrecDoubleTest(convert("%.*g"), 4, 256.01, convert("256"),
- convert("256"));
- DoArgumentPrecDoubleTest(convert("%.*g"), 6, 256.01, convert("256.01"),
- convert("256.01"));
- DoArgumentPrecDoubleTest(convert("%.*G"), 1, 256.01, convert("3E+002"),
- convert("3E+02"));
- DoArgumentPrecDoubleTest(convert("%.*G"), 3, 256.01, convert("256"),
- convert("256"));
- DoArgumentPrecDoubleTest(convert("%.*G"), 4, 256.01, convert("256"),
- convert("256"));
- DoArgumentPrecDoubleTest(convert("%.*G"), 6, 256.01, convert("256.01"),
- convert("256.01"));
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test19/test19.cpp b/src/pal/tests/palsuite/c_runtime/vswprintf/test19/test19.cpp
new file mode 100644
index 0000000000..1d1c5656b2
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test19/test19.cpp
@@ -0,0 +1,137 @@
+// Licensed to the .NET Foundation under one or more 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: test18.c
+**
+** Purpose: Test #18 for the vswprintf function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+#include "../vswprintf.h"
+
+/* memcmp is used to verify the results, so this test is dependent on it. */
+/* ditto with wcslen */
+
+#define DOTEST(a,b,c,d,e) DoTest(a,b,(void*)c,d,e)
+
+void DoArgumentPrecTest(WCHAR *formatstr, int precision, void *param,
+ WCHAR *paramstr, WCHAR *checkstr1, WCHAR *checkstr2)
+{
+ WCHAR buf[256];
+
+ testvswp(buf, formatstr, precision, param);
+ if (memcmp(buf, checkstr1, wcslen(checkstr1) + 2) != 0 &&
+ memcmp(buf, checkstr2, wcslen(checkstr2) + 2) != 0)
+ {
+ Fail("ERROR: failed to insert %s into \"%s\" with precision %d\n"
+ "Expected \"%s\" or \"%s\", got \"%s\".\n",
+ paramstr,
+ convertC(formatstr),
+ precision,
+ convertC(checkstr1),
+ convertC(checkstr2),
+ convertC(buf));
+ }
+}
+void DoArgumentPrecDoubleTest(WCHAR *formatstr, int precision, double param,
+ WCHAR *checkstr1, WCHAR *checkstr2)
+{
+ WCHAR buf[256];
+
+ testvswp(buf, formatstr, precision, param);
+ if (memcmp(buf, checkstr1, wcslen(checkstr1) + 2) != 0 &&
+ memcmp(buf, checkstr2, wcslen(checkstr2) + 2) != 0)
+ {
+ Fail("ERROR: failed to insert %f into \"%s\" with precision %d\n"
+ "Expected \"%s\" or \"%s\", got \"%s\".\n",
+ param, convertC(formatstr),
+ precision,
+ convertC(checkstr1),
+ convertC(checkstr2),
+ convertC(buf));
+ }
+}
+
+/*
+ * Uses memcmp & wcslen
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ if (PAL_Initialize(argc, argv) != 0)
+ return(FAIL);
+
+ DoArgumentPrecTest(convert("%.*s"), 2, (void*)convert("bar"), convert("bar"),
+ convert("ba"), convert("ba"));
+ DoArgumentPrecTest(convert("%.*c"), 0, (void*)'a', convert("a"),
+ convert("a"), convert("a"));
+ DoArgumentPrecTest(convert("%.*c"), 4, (void*)'a', convert("a"),
+ convert("a"), convert("a"));
+ DoArgumentPrecTest(convert("%.*C"), 0, (void*)'a', convert("a"),
+ convert("a"), convert("a"));
+ DoArgumentPrecTest(convert("%.*C"), 4, (void*)'a', convert("a"),
+ convert("a"), convert("a"));
+ DoArgumentPrecTest(convert("%.*d"), 1, (void*)42, convert("42"),
+ convert("42"), convert("42"));
+ DoArgumentPrecTest(convert("%.*d"), 3, (void*)42, convert("42"),
+ convert("042"), convert("042"));
+ DoArgumentPrecTest(convert("%.*i"), 1, (void*)42, convert("42"),
+ convert("42"), convert("42"));
+ DoArgumentPrecTest(convert("%.*i"), 3, (void*)42, convert("42"),
+ convert("042"), convert("042"));
+ DoArgumentPrecTest(convert("%.*o"), 1, (void*)42, convert("42"),
+ convert("52"), convert("52"));
+ DoArgumentPrecTest(convert("%.*o"), 3, (void*)42, convert("42"),
+ convert("052"), convert("052"));
+ DoArgumentPrecTest(convert("%.*u"), 1, (void*)42, convert("42"),
+ convert("42"), convert("42"));
+ DoArgumentPrecTest(convert("%.*u"), 3, (void*)42, convert("42"),
+ convert("042"), convert("042"));
+ DoArgumentPrecTest(convert("%.*x"), 1, (void*)0x42, convert("0x42"),
+ convert("42"), convert("42"));
+ DoArgumentPrecTest(convert("%.*x"), 3, (void*)0x42, convert("0x42"),
+ convert("042"), convert("042"));
+ DoArgumentPrecTest(convert("%.*X"), 1, (void*)0x42, convert("0x42"),
+ convert("42"), convert("42"));
+ DoArgumentPrecTest(convert("%.*X"), 3, (void*)0x42, convert("0x42"),
+ convert("042"), convert("042"));
+
+
+ DoArgumentPrecDoubleTest(convert("%.*e"), 1, 2.01, convert("2.0e+000"),
+ convert("2.0e+00"));
+ DoArgumentPrecDoubleTest(convert("%.*e"), 3, 2.01, convert("2.010e+000"),
+ convert("2.010e+00"));
+ DoArgumentPrecDoubleTest(convert("%.*E"), 1, 2.01, convert("2.0E+000"),
+ convert("2.0E+00"));
+ DoArgumentPrecDoubleTest(convert("%.*E"), 3, 2.01, convert("2.010E+000"),
+ convert("2.010E+00"));
+ DoArgumentPrecDoubleTest(convert("%.*f"), 1, 2.01, convert("2.0"),
+ convert("2.0"));
+ DoArgumentPrecDoubleTest(convert("%.*f"), 3, 2.01, convert("2.010"),
+ convert("2.010"));
+ DoArgumentPrecDoubleTest(convert("%.*g"), 1, 256.01, convert("3e+002"),
+ convert("3e+02"));
+ DoArgumentPrecDoubleTest(convert("%.*g"), 3, 256.01, convert("256"),
+ convert("256"));
+ DoArgumentPrecDoubleTest(convert("%.*g"), 4, 256.01, convert("256"),
+ convert("256"));
+ DoArgumentPrecDoubleTest(convert("%.*g"), 6, 256.01, convert("256.01"),
+ convert("256.01"));
+ DoArgumentPrecDoubleTest(convert("%.*G"), 1, 256.01, convert("3E+002"),
+ convert("3E+02"));
+ DoArgumentPrecDoubleTest(convert("%.*G"), 3, 256.01, convert("256"),
+ convert("256"));
+ DoArgumentPrecDoubleTest(convert("%.*G"), 4, 256.01, convert("256"),
+ convert("256"));
+ DoArgumentPrecDoubleTest(convert("%.*G"), 6, 256.01, convert("256.01"),
+ convert("256.01"));
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vswprintf/test2/CMakeLists.txt
index 295448cb0c..abfceca9e2 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_vswprintf_test2
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test2/test2.c b/src/pal/tests/palsuite/c_runtime/vswprintf/test2/test2.cpp
index 491d99f0cf..491d99f0cf 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vswprintf/test3/CMakeLists.txt
index 1fb6272ae7..7f4798dbc5 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_vswprintf_test3
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test3/test3.c b/src/pal/tests/palsuite/c_runtime/vswprintf/test3/test3.cpp
index 1eb0b65ebe..1eb0b65ebe 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test3/test3.c
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test4/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vswprintf/test4/CMakeLists.txt
index cae0806e03..05701ac179 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_vswprintf_test4
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test4/test4.c b/src/pal/tests/palsuite/c_runtime/vswprintf/test4/test4.cpp
index 5c9047b5a7..5c9047b5a7 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test4/test4.c
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test5/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vswprintf/test5/CMakeLists.txt
index 7c480455ed..888ce27d22 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_vswprintf_test5
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test5/test5.c b/src/pal/tests/palsuite/c_runtime/vswprintf/test5/test5.cpp
index 42146c8be7..42146c8be7 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test5/test5.c
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test5/test5.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test6/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vswprintf/test6/CMakeLists.txt
index d7de580853..bfbb17ccef 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test6.c
+ test6.cpp
)
add_executable(paltest_vswprintf_test6
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test6/test6.c b/src/pal/tests/palsuite/c_runtime/vswprintf/test6/test6.cpp
index 51e99267a1..51e99267a1 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test6/test6.c
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test6/test6.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test7/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vswprintf/test7/CMakeLists.txt
index eb07ee2cae..8b980586bc 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test7/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test7/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test7.c
+ test7.cpp
)
add_executable(paltest_vswprintf_test7
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test7/test7.c b/src/pal/tests/palsuite/c_runtime/vswprintf/test7/test7.cpp
index 6037cb0fe7..6037cb0fe7 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test7/test7.c
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test7/test7.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test8/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vswprintf/test8/CMakeLists.txt
index ed35ea8dd0..07ba473844 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test8/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test8/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test8.c
+ test8.cpp
)
add_executable(paltest_vswprintf_test8
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test8/test8.c b/src/pal/tests/palsuite/c_runtime/vswprintf/test8/test8.cpp
index baba524650..baba524650 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test8/test8.c
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test8/test8.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test9/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/vswprintf/test9/CMakeLists.txt
index 7098da31d0..11c77787e9 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test9/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test9/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test9.c
+ test9.cpp
)
add_executable(paltest_vswprintf_test9
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/test9/test9.c b/src/pal/tests/palsuite/c_runtime/vswprintf/test9/test9.cpp
index 5de004f5ed..5de004f5ed 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/test9/test9.c
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/test9/test9.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/vswprintf/vswprintf.h b/src/pal/tests/palsuite/c_runtime/vswprintf/vswprintf.h
index a79c9bb7a9..37a379212e 100644
--- a/src/pal/tests/palsuite/c_runtime/vswprintf/vswprintf.h
+++ b/src/pal/tests/palsuite/c_runtime/vswprintf/vswprintf.h
@@ -27,7 +27,7 @@ int testvswp(wchar_t* buf, const wchar_t* format, ...)
return( retVal);
}
-void DoWStrTest(WCHAR *formatstr, WCHAR *param, WCHAR *checkstr)
+void DoWStrTest(const WCHAR *formatstr, WCHAR *param, const WCHAR *checkstr)
{
WCHAR buf[256] = { 0 };
@@ -42,7 +42,7 @@ void DoWStrTest(WCHAR *formatstr, WCHAR *param, WCHAR *checkstr)
}
}
-void DoStrTest(WCHAR *formatstr, char *param, WCHAR *checkstr)
+void DoStrTest(const WCHAR *formatstr, char *param, const WCHAR *checkstr)
{
WCHAR buf[256] = { 0 };
@@ -57,7 +57,7 @@ void DoStrTest(WCHAR *formatstr, char *param, WCHAR *checkstr)
}
}
-void DoCharTest(WCHAR *formatstr, char param, WCHAR *checkstr)
+void DoCharTest(const WCHAR *formatstr, char param, const WCHAR *checkstr)
{
WCHAR buf[256] = { 0 };
@@ -71,7 +71,7 @@ void DoCharTest(WCHAR *formatstr, char param, WCHAR *checkstr)
}
}
-void DoWCharTest(WCHAR *formatstr, WCHAR param, WCHAR *checkstr)
+void DoWCharTest(const WCHAR *formatstr, WCHAR param, const WCHAR *checkstr)
{
WCHAR buf[256] = { 0 };
@@ -85,7 +85,7 @@ void DoWCharTest(WCHAR *formatstr, WCHAR param, WCHAR *checkstr)
}
}
-void DoNumTest(WCHAR *formatstr, int value, WCHAR*checkstr)
+void DoNumTest(const WCHAR *formatstr, int value, const WCHAR *checkstr)
{
WCHAR buf[256] = { 0 };
@@ -98,7 +98,7 @@ void DoNumTest(WCHAR *formatstr, int value, WCHAR*checkstr)
}
}
-void DoI64NumTest(WCHAR *formatstr, INT64 value, char *valuestr, WCHAR*checkstr)
+void DoI64NumTest(const WCHAR *formatstr, INT64 value, char *valuestr, const WCHAR *checkstr)
{
WCHAR buf[256] = { 0 };
@@ -110,7 +110,7 @@ void DoI64NumTest(WCHAR *formatstr, INT64 value, char *valuestr, WCHAR*checkstr)
convertC(checkstr), convertC(buf));
}
}
-void DoDoubleTest(WCHAR *formatstr, double value, WCHAR *checkstr1, WCHAR
+void DoDoubleTest(const WCHAR *formatstr, double value, const WCHAR *checkstr1, WCHAR
*checkstr2)
{
WCHAR buf[256] = { 0 };
diff --git a/src/pal/tests/palsuite/c_runtime/wcscat/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wcscat/test1/CMakeLists.txt
index 34dfee01bd..815c585de4 100644
--- a/src/pal/tests/palsuite/c_runtime/wcscat/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wcscat/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_wcscat_test1
diff --git a/src/pal/tests/palsuite/c_runtime/wcscat/test1/test1.c b/src/pal/tests/palsuite/c_runtime/wcscat/test1/test1.c
deleted file mode 100644
index 789eebf5a3..0000000000
--- a/src/pal/tests/palsuite/c_runtime/wcscat/test1/test1.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test1.c
-**
-** Purpose:
-** Test to that wcscat correctly concatanates wide strings, including placing
-** null pointers.
-**
-**
-**==========================================================================*/
-
-
-
-#include <palsuite.h>
-
-/*
- * Notes: uses memcmp and the (pal) sprintf
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- WCHAR dest[80];
- WCHAR test[] = {'f','o','o',' ','b','a','r',' ','b','a','z',0};
- WCHAR str1[] = {'f','o','o',' ',0};
- WCHAR str2[] = {'b','a','r',' ',0};
- WCHAR str3[] = {'b','a','z',0};
- WCHAR *ptr;
- char buffer[256];
-
-
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
-
- dest[0] = 0;
-
- ptr = wcscat(dest, str1);
- if (ptr != dest)
- {
- Fail("ERROR: Expected wcscat to return ptr to %p, got %p", dest, ptr);
- }
-
- ptr = wcscat(dest, str2);
- if (ptr != dest)
- {
- Fail("ERROR: Expected wcscat to return ptr to %p, got %p", dest, ptr);
- }
-
- ptr = wcscat(dest, str3);
- if (ptr != dest)
- {
- Fail("ERROR: Expected wcscat to return ptr to %p, got %p", dest, ptr);
- }
-
- if (memcmp(dest, test, sizeof(test)) != 0)
- {
- sprintf(buffer, "%S", dest);
- Fail("ERROR: Expected wcscat to give \"%s\", got \"%s\"\n",
- "foo bar baz", buffer);
- }
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/c_runtime/wcscat/test1/test1.cpp b/src/pal/tests/palsuite/c_runtime/wcscat/test1/test1.cpp
new file mode 100644
index 0000000000..e9a79d3880
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/wcscat/test1/test1.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test1.c
+**
+** Purpose:
+** Test to that wcscat correctly concatanates wide strings, including placing
+** null pointers.
+**
+**
+**==========================================================================*/
+
+
+
+#include <palsuite.h>
+
+/*
+ * Notes: uses memcmp and the (pal) sprintf_s
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ WCHAR dest[80];
+ WCHAR test[] = {'f','o','o',' ','b','a','r',' ','b','a','z',0};
+ WCHAR str1[] = {'f','o','o',' ',0};
+ WCHAR str2[] = {'b','a','r',' ',0};
+ WCHAR str3[] = {'b','a','z',0};
+ WCHAR *ptr;
+ char buffer[256];
+
+
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+
+ dest[0] = 0;
+
+ ptr = wcscat(dest, str1);
+ if (ptr != dest)
+ {
+ Fail("ERROR: Expected wcscat to return ptr to %p, got %p", dest, ptr);
+ }
+
+ ptr = wcscat(dest, str2);
+ if (ptr != dest)
+ {
+ Fail("ERROR: Expected wcscat to return ptr to %p, got %p", dest, ptr);
+ }
+
+ ptr = wcscat(dest, str3);
+ if (ptr != dest)
+ {
+ Fail("ERROR: Expected wcscat to return ptr to %p, got %p", dest, ptr);
+ }
+
+ if (memcmp(dest, test, sizeof(test)) != 0)
+ {
+ sprintf_s(buffer, _countof(buffer), "%S", dest);
+ Fail("ERROR: Expected wcscat to give \"%s\", got \"%s\"\n",
+ "foo bar baz", buffer);
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/c_runtime/wcschr/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wcschr/test1/CMakeLists.txt
index 542d70b7e6..9cf0a918a0 100644
--- a/src/pal/tests/palsuite/c_runtime/wcschr/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wcschr/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_wcschr_test1
diff --git a/src/pal/tests/palsuite/c_runtime/wcschr/test1/test1.c b/src/pal/tests/palsuite/c_runtime/wcschr/test1/test1.cpp
index a4963672f8..a4963672f8 100644
--- a/src/pal/tests/palsuite/c_runtime/wcschr/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/wcschr/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/wcscmp/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wcscmp/test1/CMakeLists.txt
index 009e48e1ba..98c05352f3 100644
--- a/src/pal/tests/palsuite/c_runtime/wcscmp/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wcscmp/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_wcscmp_test1
diff --git a/src/pal/tests/palsuite/c_runtime/wcscmp/test1/test1.c b/src/pal/tests/palsuite/c_runtime/wcscmp/test1/test1.cpp
index 1c38dd6d58..1c38dd6d58 100644
--- a/src/pal/tests/palsuite/c_runtime/wcscmp/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/wcscmp/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/wcscpy/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wcscpy/test1/CMakeLists.txt
index 5f21b829ee..872b2dec5e 100644
--- a/src/pal/tests/palsuite/c_runtime/wcscpy/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wcscpy/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_wcscpy_test1
diff --git a/src/pal/tests/palsuite/c_runtime/wcscpy/test1/test1.c b/src/pal/tests/palsuite/c_runtime/wcscpy/test1/test1.c
deleted file mode 100644
index 4e45c86516..0000000000
--- a/src/pal/tests/palsuite/c_runtime/wcscpy/test1/test1.c
+++ /dev/null
@@ -1,47 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: test1.c
-**
-** Purpose: Tests that wcscpy correctly copies a null-terminated wide string.
-**
-**
-**==========================================================================*/
-
-
-#include <palsuite.h>
-
-/*
- * Notes: uses memcmp and sprintf.
- */
-
-int __cdecl main(int argc, char *argv[])
-{
- WCHAR str[] = {'f','o','o',0,'b','a','r',0};
- WCHAR dest[80];
- WCHAR result[] = {'f','o','o',0};
- WCHAR *ret;
- char buffer[256];
-
-
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
-
- ret = wcscpy(dest, str);
-
- if (ret != dest || memcmp(dest, result, sizeof(result)) != 0)
- {
- sprintf(buffer, "%S", dest);
- Fail("Expected wcscpy to give \"%s\" with a return value of %p, got \"%s\" "
- "with a return value of %p.\n", "foo", dest, buffer, ret);
- }
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/c_runtime/wcscpy/test1/test1.cpp b/src/pal/tests/palsuite/c_runtime/wcscpy/test1/test1.cpp
new file mode 100644
index 0000000000..2ecafa8307
--- /dev/null
+++ b/src/pal/tests/palsuite/c_runtime/wcscpy/test1/test1.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test1.c
+**
+** Purpose: Tests that wcscpy correctly copies a null-terminated wide string.
+**
+**
+**==========================================================================*/
+
+
+#include <palsuite.h>
+
+/*
+ * Notes: uses memcmp and sprintf_s.
+ */
+
+int __cdecl main(int argc, char *argv[])
+{
+ WCHAR str[] = {'f','o','o',0,'b','a','r',0};
+ WCHAR dest[80];
+ WCHAR result[] = {'f','o','o',0};
+ WCHAR *ret;
+ char buffer[256];
+
+
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+
+ ret = wcscpy(dest, str);
+
+ if (ret != dest || memcmp(dest, result, sizeof(result)) != 0)
+ {
+ sprintf_s(buffer, _countof(buffer), "%S", dest);
+ Fail("Expected wcscpy to give \"%s\" with a return value of %p, got \"%s\" "
+ "with a return value of %p.\n", "foo", dest, buffer, ret);
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/c_runtime/wcslen/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wcslen/test1/CMakeLists.txt
index de0f1c22d3..b641a830f5 100644
--- a/src/pal/tests/palsuite/c_runtime/wcslen/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wcslen/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_wcslen_test1
diff --git a/src/pal/tests/palsuite/c_runtime/wcslen/test1/test1.c b/src/pal/tests/palsuite/c_runtime/wcslen/test1/test1.cpp
index 17d0327628..17d0327628 100644
--- a/src/pal/tests/palsuite/c_runtime/wcslen/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/wcslen/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/wcsncat/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wcsncat/test1/CMakeLists.txt
index 12c286a43a..e90e2b7bc4 100644
--- a/src/pal/tests/palsuite/c_runtime/wcsncat/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wcsncat/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_wcsncat_test1
diff --git a/src/pal/tests/palsuite/c_runtime/wcsncat/test1/test1.c b/src/pal/tests/palsuite/c_runtime/wcsncat/test1/test1.cpp
index 0cd5c3e15a..0cd5c3e15a 100644
--- a/src/pal/tests/palsuite/c_runtime/wcsncat/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/wcsncat/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/wcsncmp/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wcsncmp/test1/CMakeLists.txt
index 56c9b25806..f5511a86c6 100644
--- a/src/pal/tests/palsuite/c_runtime/wcsncmp/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wcsncmp/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_wcsncmp_test1
diff --git a/src/pal/tests/palsuite/c_runtime/wcsncmp/test1/test1.c b/src/pal/tests/palsuite/c_runtime/wcsncmp/test1/test1.cpp
index 4e4488f5a1..4e4488f5a1 100644
--- a/src/pal/tests/palsuite/c_runtime/wcsncmp/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/wcsncmp/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/wcsncpy/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wcsncpy/test1/CMakeLists.txt
index 1c1d70ba04..a7254a709c 100644
--- a/src/pal/tests/palsuite/c_runtime/wcsncpy/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wcsncpy/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_wcsncpy_test1
diff --git a/src/pal/tests/palsuite/c_runtime/wcsncpy/test1/test1.c b/src/pal/tests/palsuite/c_runtime/wcsncpy/test1/test1.cpp
index 50d97b0e9c..50d97b0e9c 100644
--- a/src/pal/tests/palsuite/c_runtime/wcsncpy/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/wcsncpy/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/wcspbrk/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wcspbrk/test1/CMakeLists.txt
index c6a3f87d75..14c1fe83a4 100644
--- a/src/pal/tests/palsuite/c_runtime/wcspbrk/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wcspbrk/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_wcspbrk_test1
diff --git a/src/pal/tests/palsuite/c_runtime/wcspbrk/test1/test1.c b/src/pal/tests/palsuite/c_runtime/wcspbrk/test1/test1.cpp
index b0432f7819..b0432f7819 100644
--- a/src/pal/tests/palsuite/c_runtime/wcspbrk/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/wcspbrk/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/wcsrchr/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wcsrchr/test1/CMakeLists.txt
index 80513af1af..abdd6d56d2 100644
--- a/src/pal/tests/palsuite/c_runtime/wcsrchr/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wcsrchr/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_wcsrchr_test1
diff --git a/src/pal/tests/palsuite/c_runtime/wcsrchr/test1/test1.c b/src/pal/tests/palsuite/c_runtime/wcsrchr/test1/test1.cpp
index ae8765776e..ae8765776e 100644
--- a/src/pal/tests/palsuite/c_runtime/wcsrchr/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/wcsrchr/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/wcsstr/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wcsstr/test1/CMakeLists.txt
index e42619344d..0e1e0b47b0 100644
--- a/src/pal/tests/palsuite/c_runtime/wcsstr/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wcsstr/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_wcsstr_test1
diff --git a/src/pal/tests/palsuite/c_runtime/wcsstr/test1/test1.c b/src/pal/tests/palsuite/c_runtime/wcsstr/test1/test1.cpp
index 8296a74983..8296a74983 100644
--- a/src/pal/tests/palsuite/c_runtime/wcsstr/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/wcsstr/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/wcstod/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wcstod/test1/CMakeLists.txt
index cf585d051a..cca01ca964 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstod/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wcstod/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_wcstod_test1
diff --git a/src/pal/tests/palsuite/c_runtime/wcstod/test1/test1.c b/src/pal/tests/palsuite/c_runtime/wcstod/test1/test1.cpp
index e41e92e961..e41e92e961 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstod/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/wcstod/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/wcstod/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wcstod/test2/CMakeLists.txt
index 43d5bf8a40..ae7450891e 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstod/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wcstod/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_wcstod_test2
diff --git a/src/pal/tests/palsuite/c_runtime/wcstod/test2/test2.c b/src/pal/tests/palsuite/c_runtime/wcstod/test2/test2.cpp
index 8f9b5cbf58..8f9b5cbf58 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstod/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/wcstod/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/wcstok/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wcstok/test1/CMakeLists.txt
index 863f5d8c29..6b5bed9552 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstok/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wcstok/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_wcstok_test1
diff --git a/src/pal/tests/palsuite/c_runtime/wcstok/test1/test1.c b/src/pal/tests/palsuite/c_runtime/wcstok/test1/test1.cpp
index 76d7dc02b3..76d7dc02b3 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstok/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/wcstok/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/wcstol/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wcstol/test1/CMakeLists.txt
index 25e96e7de0..f76018fca3 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstol/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wcstol/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_wcstol_test1
diff --git a/src/pal/tests/palsuite/c_runtime/wcstol/test1/test1.c b/src/pal/tests/palsuite/c_runtime/wcstol/test1/test1.cpp
index d84ba66adc..d84ba66adc 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstol/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/wcstol/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/wcstol/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wcstol/test2/CMakeLists.txt
index ea33ec8c7e..8dc2ab6b65 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstol/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wcstol/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_wcstol_test2
diff --git a/src/pal/tests/palsuite/c_runtime/wcstol/test2/test2.c b/src/pal/tests/palsuite/c_runtime/wcstol/test2/test2.cpp
index 58309be6b4..58309be6b4 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstol/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/wcstol/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/wcstol/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wcstol/test3/CMakeLists.txt
index 509feca08c..310f97d6dc 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstol/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wcstol/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_wcstol_test3
diff --git a/src/pal/tests/palsuite/c_runtime/wcstol/test3/test3.c b/src/pal/tests/palsuite/c_runtime/wcstol/test3/test3.cpp
index 8b5ce6943d..8b5ce6943d 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstol/test3/test3.c
+++ b/src/pal/tests/palsuite/c_runtime/wcstol/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/wcstol/test4/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wcstol/test4/CMakeLists.txt
index 043c562102..23928aa704 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstol/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wcstol/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_wcstol_test4
diff --git a/src/pal/tests/palsuite/c_runtime/wcstol/test4/test4.c b/src/pal/tests/palsuite/c_runtime/wcstol/test4/test4.cpp
index a5e65946e9..a5e65946e9 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstol/test4/test4.c
+++ b/src/pal/tests/palsuite/c_runtime/wcstol/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/wcstol/test5/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wcstol/test5/CMakeLists.txt
index c887369880..16c709ffa0 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstol/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wcstol/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_wcstol_test5
diff --git a/src/pal/tests/palsuite/c_runtime/wcstol/test5/test5.c b/src/pal/tests/palsuite/c_runtime/wcstol/test5/test5.cpp
index 62f0a895a6..62f0a895a6 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstol/test5/test5.c
+++ b/src/pal/tests/palsuite/c_runtime/wcstol/test5/test5.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/wcstol/test6/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wcstol/test6/CMakeLists.txt
index d328161f39..80ccaf609b 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstol/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wcstol/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test6.c
+ test6.cpp
)
add_executable(paltest_wcstol_test6
diff --git a/src/pal/tests/palsuite/c_runtime/wcstol/test6/test6.c b/src/pal/tests/palsuite/c_runtime/wcstol/test6/test6.cpp
index 14f6208231..14f6208231 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstol/test6/test6.c
+++ b/src/pal/tests/palsuite/c_runtime/wcstol/test6/test6.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/wcstoul/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wcstoul/test1/CMakeLists.txt
index b24523e93b..58f002ab32 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstoul/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wcstoul/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_wcstoul_test1
diff --git a/src/pal/tests/palsuite/c_runtime/wcstoul/test1/test1.c b/src/pal/tests/palsuite/c_runtime/wcstoul/test1/test1.cpp
index 5274905e30..5274905e30 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstoul/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/wcstoul/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/wcstoul/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wcstoul/test2/CMakeLists.txt
index e262078e34..2c8d012310 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstoul/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wcstoul/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_wcstoul_test2
diff --git a/src/pal/tests/palsuite/c_runtime/wcstoul/test2/test2.c b/src/pal/tests/palsuite/c_runtime/wcstoul/test2/test2.cpp
index 2ab2dbf5d1..2ab2dbf5d1 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstoul/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/wcstoul/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/wcstoul/test3/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wcstoul/test3/CMakeLists.txt
index aae268ac59..353df07f52 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstoul/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wcstoul/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_wcstoul_test3
diff --git a/src/pal/tests/palsuite/c_runtime/wcstoul/test3/test3.c b/src/pal/tests/palsuite/c_runtime/wcstoul/test3/test3.cpp
index eac46615e2..eac46615e2 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstoul/test3/test3.c
+++ b/src/pal/tests/palsuite/c_runtime/wcstoul/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/wcstoul/test4/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wcstoul/test4/CMakeLists.txt
index bd8073023f..e1e7d55420 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstoul/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wcstoul/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_wcstoul_test4
diff --git a/src/pal/tests/palsuite/c_runtime/wcstoul/test4/test4.c b/src/pal/tests/palsuite/c_runtime/wcstoul/test4/test4.cpp
index 0261da4275..0261da4275 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstoul/test4/test4.c
+++ b/src/pal/tests/palsuite/c_runtime/wcstoul/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/wcstoul/test5/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wcstoul/test5/CMakeLists.txt
index 1451e6ad57..9e83c6074c 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstoul/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wcstoul/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_wcstoul_test5
diff --git a/src/pal/tests/palsuite/c_runtime/wcstoul/test5/test5.c b/src/pal/tests/palsuite/c_runtime/wcstoul/test5/test5.cpp
index 00287cf7f4..00287cf7f4 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstoul/test5/test5.c
+++ b/src/pal/tests/palsuite/c_runtime/wcstoul/test5/test5.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/wcstoul/test6/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wcstoul/test6/CMakeLists.txt
index 15518bdcf8..8352d0cbbe 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstoul/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wcstoul/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test6.c
+ test6.cpp
)
add_executable(paltest_wcstoul_test6
diff --git a/src/pal/tests/palsuite/c_runtime/wcstoul/test6/test6.c b/src/pal/tests/palsuite/c_runtime/wcstoul/test6/test6.cpp
index 28397ec73f..28397ec73f 100644
--- a/src/pal/tests/palsuite/c_runtime/wcstoul/test6/test6.c
+++ b/src/pal/tests/palsuite/c_runtime/wcstoul/test6/test6.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/wprintf/test1/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wprintf/test1/CMakeLists.txt
index 701bbe4160..f95fc12ea1 100644
--- a/src/pal/tests/palsuite/c_runtime/wprintf/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wprintf/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_wprintf_test1
diff --git a/src/pal/tests/palsuite/c_runtime/wprintf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/wprintf/test1/test1.cpp
index d99dc8cf93..d99dc8cf93 100644
--- a/src/pal/tests/palsuite/c_runtime/wprintf/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/wprintf/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/wprintf/test2/CMakeLists.txt b/src/pal/tests/palsuite/c_runtime/wprintf/test2/CMakeLists.txt
index 55c3d11913..325e8046d5 100644
--- a/src/pal/tests/palsuite/c_runtime/wprintf/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/c_runtime/wprintf/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_wprintf_test2
diff --git a/src/pal/tests/palsuite/c_runtime/wprintf/test2/test2.c b/src/pal/tests/palsuite/c_runtime/wprintf/test2/test2.cpp
index 254e98a394..254e98a394 100644
--- a/src/pal/tests/palsuite/c_runtime/wprintf/test2/test2.c
+++ b/src/pal/tests/palsuite/c_runtime/wprintf/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/c_runtime/wprintf/wprintf.h b/src/pal/tests/palsuite/c_runtime/wprintf/wprintf.h
index 7d3caf1b02..3a96248c35 100644
--- a/src/pal/tests/palsuite/c_runtime/wprintf/wprintf.h
+++ b/src/pal/tests/palsuite/c_runtime/wprintf/wprintf.h
@@ -14,7 +14,7 @@
#ifndef __wprintf_H__
#define __wprintf_H__
-void DoStrTest(WCHAR *formatstr, WCHAR* param, WCHAR *checkstr)
+void DoStrTest(const WCHAR *formatstr, const WCHAR *param, const WCHAR *checkstr)
{
int ret;
@@ -27,8 +27,8 @@ void DoStrTest(WCHAR *formatstr, WCHAR* param, WCHAR *checkstr)
}
-void DoPointerTest(WCHAR *formatstr, void* param, WCHAR* paramstr,
- WCHAR *checkstr1)
+void DoPointerTest(const WCHAR *formatstr, void* param, WCHAR* paramstr,
+ const WCHAR *checkstr1)
{
int ret;
@@ -40,7 +40,7 @@ void DoPointerTest(WCHAR *formatstr, void* param, WCHAR* paramstr,
}
}
-void DoCountTest(WCHAR *formatstr, int param, WCHAR *checkstr)
+void DoCountTest(const WCHAR *formatstr, int param, const WCHAR *checkstr)
{
int ret;
int n = -1;
@@ -59,7 +59,7 @@ void DoCountTest(WCHAR *formatstr, int param, WCHAR *checkstr)
}
}
-void DoShortCountTest(WCHAR *formatstr, int param, WCHAR *checkstr)
+void DoShortCountTest(const WCHAR *formatstr, int param, const WCHAR *checkstr)
{
int ret;
short int n = -1;
@@ -79,7 +79,7 @@ void DoShortCountTest(WCHAR *formatstr, int param, WCHAR *checkstr)
}
-void DoCharTest(WCHAR *formatstr, WCHAR param, WCHAR *checkstr)
+void DoCharTest(const WCHAR *formatstr, WCHAR param, const WCHAR *checkstr)
{
int ret;
@@ -91,7 +91,7 @@ void DoCharTest(WCHAR *formatstr, WCHAR param, WCHAR *checkstr)
}
}
-void DoWCharTest(WCHAR *formatstr, WCHAR param, WCHAR *checkstr)
+void DoWCharTest(const WCHAR *formatstr, WCHAR param, const WCHAR *checkstr)
{
int ret;
@@ -103,7 +103,7 @@ void DoWCharTest(WCHAR *formatstr, WCHAR param, WCHAR *checkstr)
}
}
-void DoNumTest(WCHAR *formatstr, int param, WCHAR *checkstr)
+void DoNumTest(const WCHAR *formatstr, int param, const WCHAR *checkstr)
{
int ret;
@@ -115,8 +115,8 @@ void DoNumTest(WCHAR *formatstr, int param, WCHAR *checkstr)
}
}
-void DoI64Test(WCHAR *formatstr, INT64 param, WCHAR *valuestr,
- WCHAR *checkstr1)
+void DoI64Test(const WCHAR *formatstr, INT64 param, const WCHAR *valuestr,
+ const WCHAR *checkstr1)
{
int ret;
@@ -128,8 +128,8 @@ void DoI64Test(WCHAR *formatstr, INT64 param, WCHAR *valuestr,
}
}
-void DoDoubleTest(WCHAR *formatstr, double param,
- WCHAR *checkstr1, WCHAR *checkstr2)
+void DoDoubleTest(const WCHAR *formatstr, double param,
+ const WCHAR *checkstr1, const WCHAR *checkstr2)
{
int ret;
@@ -141,8 +141,8 @@ void DoDoubleTest(WCHAR *formatstr, double param,
}
}
-void DoArgumentPrecTest(WCHAR *formatstr, int precision, void *param,
- WCHAR *paramstr, WCHAR *checkstr1, WCHAR *checkstr2)
+void DoArgumentPrecTest(const WCHAR *formatstr, int precision, void *param,
+ WCHAR *paramstr, const WCHAR *checkstr1, const WCHAR *checkstr2)
{
int ret;
@@ -154,8 +154,8 @@ void DoArgumentPrecTest(WCHAR *formatstr, int precision, void *param,
}
}
-void DoArgumentPrecDoubleTest(WCHAR *formatstr, int precision, double param,
- WCHAR *checkstr1, WCHAR *checkstr2)
+void DoArgumentPrecDoubleTest(const WCHAR *formatstr, int precision, double param,
+ const WCHAR *checkstr1, const WCHAR *checkstr2)
{
int ret;
diff --git a/src/pal/tests/palsuite/common/palsuite.h b/src/pal/tests/palsuite/common/palsuite.h
index ef644ad8e5..b77ca2ead5 100644
--- a/src/pal/tests/palsuite/common/palsuite.h
+++ b/src/pal/tests/palsuite/common/palsuite.h
@@ -133,9 +133,9 @@ inline ULONG VAL32(ULONG x)
#define th_htons(w) (((w) >> 8) | ((w) << 8))
#endif // BIGENDIAN
+#define _countof(_array) (sizeof(_array)/sizeof(_array[0]))
-
-WCHAR* convert(char * aString)
+WCHAR* convert(const char * aString)
{
int size;
WCHAR* wideBuffer;
@@ -150,7 +150,7 @@ WCHAR* convert(char * aString)
return wideBuffer;
}
-char* convertC(WCHAR * wString)
+char* convertC(const WCHAR * wString)
{
int size;
char * MultiBuffer = NULL;
diff --git a/src/pal/tests/palsuite/composite/object_management/event/nonshared/CMakeLists.txt b/src/pal/tests/palsuite/composite/object_management/event/nonshared/CMakeLists.txt
index c6c00377e1..b336c03d37 100644
--- a/src/pal/tests/palsuite/composite/object_management/event/nonshared/CMakeLists.txt
+++ b/src/pal/tests/palsuite/composite/object_management/event/nonshared/CMakeLists.txt
@@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- event.c
- main.c
+ event.cpp
+ main.cpp
)
add_executable(paltest_event_nonshared
diff --git a/src/pal/tests/palsuite/composite/object_management/event/nonshared/event.c b/src/pal/tests/palsuite/composite/object_management/event/nonshared/event.cpp
index 69ad9a30e3..69ad9a30e3 100644
--- a/src/pal/tests/palsuite/composite/object_management/event/nonshared/event.c
+++ b/src/pal/tests/palsuite/composite/object_management/event/nonshared/event.cpp
diff --git a/src/pal/tests/palsuite/composite/object_management/event/nonshared/main.c b/src/pal/tests/palsuite/composite/object_management/event/nonshared/main.cpp
index 7b61e91737..7b61e91737 100644
--- a/src/pal/tests/palsuite/composite/object_management/event/nonshared/main.c
+++ b/src/pal/tests/palsuite/composite/object_management/event/nonshared/main.cpp
diff --git a/src/pal/tests/palsuite/composite/object_management/event/shared/CMakeLists.txt b/src/pal/tests/palsuite/composite/object_management/event/shared/CMakeLists.txt
index d326e3a42b..86188796bd 100644
--- a/src/pal/tests/palsuite/composite/object_management/event/shared/CMakeLists.txt
+++ b/src/pal/tests/palsuite/composite/object_management/event/shared/CMakeLists.txt
@@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- event.c
- main.c
+ event.cpp
+ main.cpp
)
add_executable(paltest_event_shared
diff --git a/src/pal/tests/palsuite/composite/object_management/event/shared/event.c b/src/pal/tests/palsuite/composite/object_management/event/shared/event.cpp
index 83d5fce27e..83d5fce27e 100644
--- a/src/pal/tests/palsuite/composite/object_management/event/shared/event.c
+++ b/src/pal/tests/palsuite/composite/object_management/event/shared/event.cpp
diff --git a/src/pal/tests/palsuite/composite/object_management/event/shared/main.c b/src/pal/tests/palsuite/composite/object_management/event/shared/main.cpp
index c4a4067b5d..c4a4067b5d 100644
--- a/src/pal/tests/palsuite/composite/object_management/event/shared/main.c
+++ b/src/pal/tests/palsuite/composite/object_management/event/shared/main.cpp
diff --git a/src/pal/tests/palsuite/composite/object_management/mutex/nonshared/CMakeLists.txt b/src/pal/tests/palsuite/composite/object_management/mutex/nonshared/CMakeLists.txt
index 7859cd4653..03d5efac27 100644
--- a/src/pal/tests/palsuite/composite/object_management/mutex/nonshared/CMakeLists.txt
+++ b/src/pal/tests/palsuite/composite/object_management/mutex/nonshared/CMakeLists.txt
@@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- main.c
- mutex.c
+ main.cpp
+ mutex.cpp
)
add_executable(paltest_mutex_nonshared
diff --git a/src/pal/tests/palsuite/composite/object_management/mutex/nonshared/main.c b/src/pal/tests/palsuite/composite/object_management/mutex/nonshared/main.cpp
index 80f31aad6e..80f31aad6e 100644
--- a/src/pal/tests/palsuite/composite/object_management/mutex/nonshared/main.c
+++ b/src/pal/tests/palsuite/composite/object_management/mutex/nonshared/main.cpp
diff --git a/src/pal/tests/palsuite/composite/object_management/mutex/nonshared/mutex.c b/src/pal/tests/palsuite/composite/object_management/mutex/nonshared/mutex.cpp
index 7f1f659f92..7f1f659f92 100644
--- a/src/pal/tests/palsuite/composite/object_management/mutex/nonshared/mutex.c
+++ b/src/pal/tests/palsuite/composite/object_management/mutex/nonshared/mutex.cpp
diff --git a/src/pal/tests/palsuite/composite/object_management/mutex/shared/CMakeLists.txt b/src/pal/tests/palsuite/composite/object_management/mutex/shared/CMakeLists.txt
index cf33d0b464..d4b50cd66e 100644
--- a/src/pal/tests/palsuite/composite/object_management/mutex/shared/CMakeLists.txt
+++ b/src/pal/tests/palsuite/composite/object_management/mutex/shared/CMakeLists.txt
@@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- main.c
- mutex.c
+ main.cpp
+ mutex.cpp
)
add_executable(paltest_mutex_shared
diff --git a/src/pal/tests/palsuite/composite/object_management/mutex/shared/main.c b/src/pal/tests/palsuite/composite/object_management/mutex/shared/main.cpp
index aa98855565..aa98855565 100644
--- a/src/pal/tests/palsuite/composite/object_management/mutex/shared/main.c
+++ b/src/pal/tests/palsuite/composite/object_management/mutex/shared/main.cpp
diff --git a/src/pal/tests/palsuite/composite/object_management/mutex/shared/mutex.c b/src/pal/tests/palsuite/composite/object_management/mutex/shared/mutex.cpp
index ec5d9b37ac..ec5d9b37ac 100644
--- a/src/pal/tests/palsuite/composite/object_management/mutex/shared/mutex.c
+++ b/src/pal/tests/palsuite/composite/object_management/mutex/shared/mutex.cpp
diff --git a/src/pal/tests/palsuite/composite/object_management/semaphore/nonshared/CMakeLists.txt b/src/pal/tests/palsuite/composite/object_management/semaphore/nonshared/CMakeLists.txt
index 6efa228fbb..9ed4535d39 100644
--- a/src/pal/tests/palsuite/composite/object_management/semaphore/nonshared/CMakeLists.txt
+++ b/src/pal/tests/palsuite/composite/object_management/semaphore/nonshared/CMakeLists.txt
@@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- main.c
- semaphore.c
+ main.cpp
+ semaphore.cpp
)
add_executable(paltest_semaphore_nonshared
diff --git a/src/pal/tests/palsuite/composite/object_management/semaphore/nonshared/main.c b/src/pal/tests/palsuite/composite/object_management/semaphore/nonshared/main.cpp
index 854809c8f8..854809c8f8 100644
--- a/src/pal/tests/palsuite/composite/object_management/semaphore/nonshared/main.c
+++ b/src/pal/tests/palsuite/composite/object_management/semaphore/nonshared/main.cpp
diff --git a/src/pal/tests/palsuite/composite/object_management/semaphore/nonshared/semaphore.c b/src/pal/tests/palsuite/composite/object_management/semaphore/nonshared/semaphore.cpp
index 0e487f2c17..0e487f2c17 100644
--- a/src/pal/tests/palsuite/composite/object_management/semaphore/nonshared/semaphore.c
+++ b/src/pal/tests/palsuite/composite/object_management/semaphore/nonshared/semaphore.cpp
diff --git a/src/pal/tests/palsuite/composite/object_management/semaphore/shared/CMakeLists.txt b/src/pal/tests/palsuite/composite/object_management/semaphore/shared/CMakeLists.txt
index 12d3ca867e..5c7f93290f 100644
--- a/src/pal/tests/palsuite/composite/object_management/semaphore/shared/CMakeLists.txt
+++ b/src/pal/tests/palsuite/composite/object_management/semaphore/shared/CMakeLists.txt
@@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- main.c
- semaphore.c
+ main.cpp
+ semaphore.cpp
)
add_executable(paltest_semaphore_shared
diff --git a/src/pal/tests/palsuite/composite/object_management/semaphore/shared/main.c b/src/pal/tests/palsuite/composite/object_management/semaphore/shared/main.cpp
index deb8252b70..deb8252b70 100644
--- a/src/pal/tests/palsuite/composite/object_management/semaphore/shared/main.c
+++ b/src/pal/tests/palsuite/composite/object_management/semaphore/shared/main.cpp
diff --git a/src/pal/tests/palsuite/composite/object_management/semaphore/shared/semaphore.c b/src/pal/tests/palsuite/composite/object_management/semaphore/shared/semaphore.cpp
index 5143c55143..5143c55143 100644
--- a/src/pal/tests/palsuite/composite/object_management/semaphore/shared/semaphore.c
+++ b/src/pal/tests/palsuite/composite/object_management/semaphore/shared/semaphore.cpp
diff --git a/src/pal/tests/palsuite/composite/synchronization/criticalsection/CMakeLists.txt b/src/pal/tests/palsuite/composite/synchronization/criticalsection/CMakeLists.txt
index 936c0fe82d..fc357ed258 100644
--- a/src/pal/tests/palsuite/composite/synchronization/criticalsection/CMakeLists.txt
+++ b/src/pal/tests/palsuite/composite/synchronization/criticalsection/CMakeLists.txt
@@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- criticalsection.c
- mainWrapper.c
+ criticalsection.cpp
+ mainWrapper.cpp
)
add_executable(paltest_synchronization_criticalsection
diff --git a/src/pal/tests/palsuite/composite/synchronization/criticalsection/criticalsection.c b/src/pal/tests/palsuite/composite/synchronization/criticalsection/criticalsection.cpp
index 2fcd363e8a..2fcd363e8a 100644
--- a/src/pal/tests/palsuite/composite/synchronization/criticalsection/criticalsection.c
+++ b/src/pal/tests/palsuite/composite/synchronization/criticalsection/criticalsection.cpp
diff --git a/src/pal/tests/palsuite/composite/synchronization/criticalsection/mainWrapper.c b/src/pal/tests/palsuite/composite/synchronization/criticalsection/mainWrapper.cpp
index 4bc2f3d834..4bc2f3d834 100644
--- a/src/pal/tests/palsuite/composite/synchronization/criticalsection/mainWrapper.c
+++ b/src/pal/tests/palsuite/composite/synchronization/criticalsection/mainWrapper.cpp
diff --git a/src/pal/tests/palsuite/composite/synchronization/nativecriticalsection/CMakeLists.txt b/src/pal/tests/palsuite/composite/synchronization/nativecriticalsection/CMakeLists.txt
index d01b1064f6..9a02993916 100644
--- a/src/pal/tests/palsuite/composite/synchronization/nativecriticalsection/CMakeLists.txt
+++ b/src/pal/tests/palsuite/composite/synchronization/nativecriticalsection/CMakeLists.txt
@@ -4,7 +4,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
mtx_critsect.cpp
- pal_composite_native_cs.c
+ pal_composite_native_cs.cpp
resultbuffer.cpp
)
diff --git a/src/pal/tests/palsuite/composite/synchronization/nativecriticalsection/pal_composite_native_cs.c b/src/pal/tests/palsuite/composite/synchronization/nativecriticalsection/pal_composite_native_cs.cpp
index 40efacd7c9..40efacd7c9 100644
--- a/src/pal/tests/palsuite/composite/synchronization/nativecriticalsection/pal_composite_native_cs.c
+++ b/src/pal/tests/palsuite/composite/synchronization/nativecriticalsection/pal_composite_native_cs.cpp
diff --git a/src/pal/tests/palsuite/composite/synchronization/nativecs_interlocked/CMakeLists.txt b/src/pal/tests/palsuite/composite/synchronization/nativecs_interlocked/CMakeLists.txt
index c4567f638c..717bdd6b20 100644
--- a/src/pal/tests/palsuite/composite/synchronization/nativecs_interlocked/CMakeLists.txt
+++ b/src/pal/tests/palsuite/composite/synchronization/nativecs_interlocked/CMakeLists.txt
@@ -5,7 +5,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
interlocked.cpp
mtx_critsect.cpp
- pal_composite_native_cs.c
+ pal_composite_native_cs.cpp
resultbuffer.cpp
)
diff --git a/src/pal/tests/palsuite/composite/synchronization/nativecs_interlocked/pal_composite_native_cs.c b/src/pal/tests/palsuite/composite/synchronization/nativecs_interlocked/pal_composite_native_cs.cpp
index 4c19d3b0de..4c19d3b0de 100644
--- a/src/pal/tests/palsuite/composite/synchronization/nativecs_interlocked/pal_composite_native_cs.c
+++ b/src/pal/tests/palsuite/composite/synchronization/nativecs_interlocked/pal_composite_native_cs.cpp
diff --git a/src/pal/tests/palsuite/composite/threading/threadsuspension/CMakeLists.txt b/src/pal/tests/palsuite/composite/threading/threadsuspension/CMakeLists.txt
index 134cce0809..d396d2fc49 100644
--- a/src/pal/tests/palsuite/composite/threading/threadsuspension/CMakeLists.txt
+++ b/src/pal/tests/palsuite/composite/threading/threadsuspension/CMakeLists.txt
@@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- mainWrapper.c
- threadsuspension.c
+ mainWrapper.cpp
+ threadsuspension.cpp
)
add_executable(paltest_threading_threadsuspension
diff --git a/src/pal/tests/palsuite/composite/threading/threadsuspension/mainWrapper.c b/src/pal/tests/palsuite/composite/threading/threadsuspension/mainWrapper.cpp
index 05a71191cf..05a71191cf 100644
--- a/src/pal/tests/palsuite/composite/threading/threadsuspension/mainWrapper.c
+++ b/src/pal/tests/palsuite/composite/threading/threadsuspension/mainWrapper.cpp
diff --git a/src/pal/tests/palsuite/composite/threading/threadsuspension/threadsuspension.c b/src/pal/tests/palsuite/composite/threading/threadsuspension/threadsuspension.cpp
index 86ee4e2fc0..86ee4e2fc0 100644
--- a/src/pal/tests/palsuite/composite/threading/threadsuspension/threadsuspension.c
+++ b/src/pal/tests/palsuite/composite/threading/threadsuspension/threadsuspension.cpp
diff --git a/src/pal/tests/palsuite/composite/threading/threadsuspension_switchthread/CMakeLists.txt b/src/pal/tests/palsuite/composite/threading/threadsuspension_switchthread/CMakeLists.txt
index 5361a1cf0d..2c880921fe 100644
--- a/src/pal/tests/palsuite/composite/threading/threadsuspension_switchthread/CMakeLists.txt
+++ b/src/pal/tests/palsuite/composite/threading/threadsuspension_switchthread/CMakeLists.txt
@@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- mainWrapper.c
- threadsuspension.c
+ mainWrapper.cpp
+ threadsuspension.cpp
)
add_executable(paltest_threading_threadsuspension_switchthread
diff --git a/src/pal/tests/palsuite/composite/threading/threadsuspension_switchthread/mainWrapper.c b/src/pal/tests/palsuite/composite/threading/threadsuspension_switchthread/mainWrapper.cpp
index 05a71191cf..05a71191cf 100644
--- a/src/pal/tests/palsuite/composite/threading/threadsuspension_switchthread/mainWrapper.c
+++ b/src/pal/tests/palsuite/composite/threading/threadsuspension_switchthread/mainWrapper.cpp
diff --git a/src/pal/tests/palsuite/composite/threading/threadsuspension_switchthread/threadsuspension.c b/src/pal/tests/palsuite/composite/threading/threadsuspension_switchthread/threadsuspension.cpp
index a117b86174..a117b86174 100644
--- a/src/pal/tests/palsuite/composite/threading/threadsuspension_switchthread/threadsuspension.c
+++ b/src/pal/tests/palsuite/composite/threading/threadsuspension_switchthread/threadsuspension.cpp
diff --git a/src/pal/tests/palsuite/composite/wfmo/CMakeLists.txt b/src/pal/tests/palsuite/composite/wfmo/CMakeLists.txt
index 7dbddbc989..5e103102af 100644
--- a/src/pal/tests/palsuite/composite/wfmo/CMakeLists.txt
+++ b/src/pal/tests/palsuite/composite/wfmo/CMakeLists.txt
@@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- main.c
- mutex.c
+ main.cpp
+ mutex.cpp
)
add_executable(paltest_composite_wfmo
diff --git a/src/pal/tests/palsuite/composite/wfmo/main.c b/src/pal/tests/palsuite/composite/wfmo/main.cpp
index d186aa7b8b..d186aa7b8b 100644
--- a/src/pal/tests/palsuite/composite/wfmo/main.c
+++ b/src/pal/tests/palsuite/composite/wfmo/main.cpp
diff --git a/src/pal/tests/palsuite/composite/wfmo/mutex.c b/src/pal/tests/palsuite/composite/wfmo/mutex.cpp
index c8ed01426c..c8ed01426c 100644
--- a/src/pal/tests/palsuite/composite/wfmo/mutex.c
+++ b/src/pal/tests/palsuite/composite/wfmo/mutex.cpp
diff --git a/src/pal/tests/palsuite/debug_api/DebugBreak/test1/CMakeLists.txt b/src/pal/tests/palsuite/debug_api/DebugBreak/test1/CMakeLists.txt
index db66cbe1d0..1b2ae538cc 100644
--- a/src/pal/tests/palsuite/debug_api/DebugBreak/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/debug_api/DebugBreak/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_debugbreak_test1
diff --git a/src/pal/tests/palsuite/debug_api/DebugBreak/test1/test1.c b/src/pal/tests/palsuite/debug_api/DebugBreak/test1/test1.cpp
index 2b10b9ad9d..2b10b9ad9d 100644
--- a/src/pal/tests/palsuite/debug_api/DebugBreak/test1/test1.c
+++ b/src/pal/tests/palsuite/debug_api/DebugBreak/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/debug_api/OutputDebugStringA/test1/CMakeLists.txt b/src/pal/tests/palsuite/debug_api/OutputDebugStringA/test1/CMakeLists.txt
index 5bc7fdb6e9..3000734afe 100644
--- a/src/pal/tests/palsuite/debug_api/OutputDebugStringA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/debug_api/OutputDebugStringA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(TESTSOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_outputdebugstringa_test1
@@ -20,7 +20,7 @@ target_link_libraries(paltest_outputdebugstringa_test1
set(HELPERSOURCES
- helper.c
+ helper.cpp
)
add_executable(paltest_outputdebugstringa_test1_helper
diff --git a/src/pal/tests/palsuite/debug_api/OutputDebugStringA/test1/helper.c b/src/pal/tests/palsuite/debug_api/OutputDebugStringA/test1/helper.cpp
index 90073dfedd..90073dfedd 100644
--- a/src/pal/tests/palsuite/debug_api/OutputDebugStringA/test1/helper.c
+++ b/src/pal/tests/palsuite/debug_api/OutputDebugStringA/test1/helper.cpp
diff --git a/src/pal/tests/palsuite/debug_api/OutputDebugStringA/test1/test1.c b/src/pal/tests/palsuite/debug_api/OutputDebugStringA/test1/test1.cpp
index 080c6ac53e..080c6ac53e 100644
--- a/src/pal/tests/palsuite/debug_api/OutputDebugStringA/test1/test1.c
+++ b/src/pal/tests/palsuite/debug_api/OutputDebugStringA/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/debug_api/OutputDebugStringW/test1/CMakeLists.txt b/src/pal/tests/palsuite/debug_api/OutputDebugStringW/test1/CMakeLists.txt
index 9202baeaef..4a93f0e394 100644
--- a/src/pal/tests/palsuite/debug_api/OutputDebugStringW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/debug_api/OutputDebugStringW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_outputdebugstringw_test1
diff --git a/src/pal/tests/palsuite/debug_api/OutputDebugStringW/test1/test1.c b/src/pal/tests/palsuite/debug_api/OutputDebugStringW/test1/test1.cpp
index 88b55427bc..88b55427bc 100644
--- a/src/pal/tests/palsuite/debug_api/OutputDebugStringW/test1/test1.c
+++ b/src/pal/tests/palsuite/debug_api/OutputDebugStringW/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/CMakeLists.txt b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/CMakeLists.txt
index 39130aac1c..afd581fb92 100644
--- a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(TESTSOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_writeprocessmemory_test1
@@ -20,7 +20,7 @@ target_link_libraries(paltest_writeprocessmemory_test1
set(HELPERSOURCES
- helper.c
+ helper.cpp
)
add_executable(paltest_writeprocessmemory_test1_helper
diff --git a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/helper.c b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/helper.c
deleted file mode 100644
index 1a7318969c..0000000000
--- a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/helper.c
+++ /dev/null
@@ -1,243 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: helper.c
-**
-** Purpose: This helper process sets up a several blocks of memory,
-** then uses a file to tell its parent process where that memory is
-** So it can do a WriteProcessMemory on it. When the parent process is done
-** we check here that it was written properly.
-**
-**
-**============================================================*/
-
-#include "commonconsts.h"
-
-#include <palsuite.h>
-
-struct allhandles_t
-{
- HANDLE hEvToHelper;
- HANDLE hEvFromHelper;
- char *valuesFileName;
-};
-
-
-/* function: wpmDoIt
- *
- * This is a general WriteProcessMemory testing function that sets up
- * the RAM pointed to and tells the companion process on the other end
- * of the handles in 'Comms' to attempt to alter 'lenDest' bytes at
- * '*pDest'.
- *
- * '*pBuffer'[0..'lenBuffer'] is expected to be a guard region
- * surrounding the '*pDest'[0..'lenDest'] region so that this function
- * can verify that only the proper bytes were altered.
- */
-
-int wpmDoIt(struct allhandles_t Comms,
- char * pBuffer, unsigned int lenBuffer,
- char * pDest, unsigned int lenDest,
- const char* storageDescription)
-{
- char *pCurr;
- FILE *commsFile;
- DWORD dwRet;
-
- if (pBuffer > pDest || lenDest > lenBuffer)
- {
- Trace("WriteProcessMemory::DoIt() test implementation: "
- "(pBuffer > pDest || lenDest > lenBuffer)\n");
- return FALSE;
- }
-
- /* set up the storage */
- memset(pBuffer, guardValue, lenBuffer);
- memset(pDest, initialValue, lenDest);
-
- /* tell the parent what RAM to adjust */
- if(!(commsFile = fopen(Comms.valuesFileName, "w")))
- {
- Trace("WriteProcessMemory: fopen of '%S' failed (%u). \n",
- Comms.valuesFileName, GetLastError());
- return FALSE;
- }
- if (!fprintf(commsFile, "%u %u '%s'\n",
- pDest, lenDest, storageDescription))
- {
- Trace("WriteProcessMemory: fprintf to '%S' failed (%u). \n",
- Comms.valuesFileName, GetLastError());
- return FALSE;
- }
- PEDANTIC1(fclose, (commsFile));
-
- /* Tell the parent the data is ready for it to adjust */
- PEDANTIC(ResetEvent, (Comms.hEvToHelper));
- PEDANTIC(SetEvent, (Comms.hEvFromHelper));
-
- dwRet = WaitForSingleObject(Comms.hEvToHelper, TIMEOUT); /* parent is done */
- if (dwRet != WAIT_OBJECT_0)
- {
- Trace("helper WaitForSingleObjectTest: WaitForSingleObject "
- "failed (%u)\n", GetLastError());
- return FALSE;
- }
-
- /* check the stuff that SHOULD have changed */
- for (pCurr = pDest; pCurr < (pDest + lenDest); pCurr++)
- {
- if ( *pCurr != nextValue)
- {
- Trace("When testing '%s': alteration test failed "
- "at %u offset %u. Found '%c' instead of '%c'\n.",
- storageDescription, pDest, pCurr - pDest, *pCurr, nextValue);
- Trace(" 'Altered' string: '%.*s'\n",lenBuffer, pBuffer);
- return FALSE;
- }
- }
- /* check the stuff that should NOT have changed */
- for (pCurr = pBuffer; pCurr < pDest; pCurr++ )
- {
- if ( *pCurr != guardValue)
- {
- Trace("When testing '%s': leading guard zone test failed "
- "at %u offset %u. Found '%c' instead of '%c'\n.",
- storageDescription, pDest, pCurr - pBuffer, *pCurr, guardValue);
- Trace(" 'Altered' string: '%.*s'\n",lenBuffer, pBuffer);
- return FALSE;
- }
- }
- for (pCurr = pDest + lenDest; pCurr < (pBuffer + lenBuffer); pCurr++ )
- {
- if ( *pCurr != guardValue)
- {
- Trace("When testing '%s': trailing guard zone test failed "
- "at %u offset %u. Found '%c' instead of '%c'\n.",
- storageDescription, pDest + lenDest, pCurr - pBuffer, *pCurr, guardValue);
- Trace(" 'Altered' string: '%.*s'\n",lenBuffer, pBuffer);
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-int __cdecl main(int argc, char *argv[])
-{
-
- BOOL success = TRUE; /* assume success */
- struct allhandles_t Comms = {0,0,0} ;
-
- /* variables to track storage to alter */
- char *pTarget = NULL;
- unsigned int sizeTarget;
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- /* hook up with the events created by the parent */
- Comms.hEvToHelper = OpenEventW(EVENT_ALL_ACCESS, 0, szcToHelperEvName);
- if (!Comms.hEvToHelper)
- {
- Fail("WriteProcessMemory: OpenEvent of '%S' failed (%u). "
- "(the event should already exist!)\n",
- szcToHelperEvName, GetLastError());
- }
- Comms.hEvFromHelper = OpenEventW(EVENT_ALL_ACCESS, 0, szcFromHelperEvName);
- if (!Comms.hEvToHelper)
- {
- Trace("WriteProcessMemory: OpenEvent of '%S' failed (%u). "
- "(the event should already exist!)\n",
- szcFromHelperEvName, GetLastError());
- success = FALSE;
- goto EXIT;
- }
- Comms.valuesFileName = argv[1];
-
- {
- char autoAllocatedOnStack[51];
-
- /* Get the parent process to write to the local stack */
- success &= wpmDoIt(Comms, autoAllocatedOnStack,
- sizeof(autoAllocatedOnStack),
- autoAllocatedOnStack + sizeof(int),
- sizeof(autoAllocatedOnStack) - 2 * sizeof(int),
- "const size array on stack with int sized guards");
- }
-
- /* Get the parent process to write to stuff on the heap */
- sizeTarget = 2 * sizeof(int) + 23 ; /* 23 is just a random prime > 16 */
- if (!(pTarget = malloc(sizeTarget)))
- {
- Trace("WriteProcessMemory helper: unable to allocate '%s'->%d bytes of memory"
- "(%u).\n",
- argv[3], sizeTarget, GetLastError());
- success = FALSE;
- goto EXIT;
-
- }
- success &= wpmDoIt(Comms, pTarget, sizeTarget,
- pTarget + sizeof(int),
- sizeTarget - 2 * sizeof(int),
- "array on heap with int sized guards");
-
- /* just to be nice try something 16 - 2 * sizeof(int) bytes long */
- {
- char autoAllocatedOnStack[16];
-
- /* Get the parent process to write to the local stack */
- success &= wpmDoIt(Comms, autoAllocatedOnStack,
- sizeof(autoAllocatedOnStack),
- autoAllocatedOnStack + sizeof(int),
- sizeof(autoAllocatedOnStack) - 2 * sizeof(int),
- "another 16 byte array on stack with int sized guards inside");
- }
-
- /* NOTE: Don't try 0 bytes long. Win32 WriteProcessMemory claims
- * it writes 8 bytes in that case! */
-
- /* and 1 byte long... */
- {
- char autoAllocatedOnStack[1+ 2 * sizeof(int)];
-
- /* Get the parent process to write to the local stack */
- success &= wpmDoIt(Comms, autoAllocatedOnStack,
- sizeof(autoAllocatedOnStack),
- autoAllocatedOnStack + sizeof(int),
- 1,
- "no bytes with int sized guards outside on stack");
- }
-
-
-EXIT:
- /* Tell the parent that we are done */
- if (!DeleteFile(Comms.valuesFileName))
- {
- Trace("helper: DeleteFile failed so parent (test1) is unlikely "
- "to exit cleanly\n");
- }
- PEDANTIC(ResetEvent, (Comms.hEvToHelper));
- if (!SetEvent(Comms.hEvFromHelper))
- {
- Trace("helper: SetEvent failed so parent (test1) is unlikely "
- "to exit cleanly\n");
- }
-
- free(pTarget);
- PEDANTIC(CloseHandle, (Comms.hEvToHelper));
- PEDANTIC(CloseHandle, (Comms.hEvFromHelper));
-
- if (!success)
- {
- Fail("");
- }
-
- PAL_Terminate();
-
- return success ? PASS : FAIL;
-}
diff --git a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/helper.cpp b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/helper.cpp
new file mode 100644
index 0000000000..d965ca7a51
--- /dev/null
+++ b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/helper.cpp
@@ -0,0 +1,243 @@
+// Licensed to the .NET Foundation under one or more 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: helper.c
+**
+** Purpose: This helper process sets up a several blocks of memory,
+** then uses a file to tell its parent process where that memory is
+** So it can do a WriteProcessMemory on it. When the parent process is done
+** we check here that it was written properly.
+**
+**
+**============================================================*/
+
+#include "commonconsts.h"
+
+#include <palsuite.h>
+
+struct allhandles_t
+{
+ HANDLE hEvToHelper;
+ HANDLE hEvFromHelper;
+ char *valuesFileName;
+};
+
+
+/* function: wpmDoIt
+ *
+ * This is a general WriteProcessMemory testing function that sets up
+ * the RAM pointed to and tells the companion process on the other end
+ * of the handles in 'Comms' to attempt to alter 'lenDest' bytes at
+ * '*pDest'.
+ *
+ * '*pBuffer'[0..'lenBuffer'] is expected to be a guard region
+ * surrounding the '*pDest'[0..'lenDest'] region so that this function
+ * can verify that only the proper bytes were altered.
+ */
+
+int wpmDoIt(struct allhandles_t Comms,
+ char * pBuffer, unsigned int lenBuffer,
+ char * pDest, unsigned int lenDest,
+ const char* storageDescription)
+{
+ char *pCurr;
+ FILE *commsFile;
+ DWORD dwRet;
+
+ if (pBuffer > pDest || lenDest > lenBuffer)
+ {
+ Trace("WriteProcessMemory::DoIt() test implementation: "
+ "(pBuffer > pDest || lenDest > lenBuffer)\n");
+ return FALSE;
+ }
+
+ /* set up the storage */
+ memset(pBuffer, guardValue, lenBuffer);
+ memset(pDest, initialValue, lenDest);
+
+ /* tell the parent what RAM to adjust */
+ if(!(commsFile = fopen(Comms.valuesFileName, "w")))
+ {
+ Trace("WriteProcessMemory: fopen of '%S' failed (%u). \n",
+ Comms.valuesFileName, GetLastError());
+ return FALSE;
+ }
+ if (!fprintf(commsFile, "%u %u '%s'\n",
+ pDest, lenDest, storageDescription))
+ {
+ Trace("WriteProcessMemory: fprintf to '%S' failed (%u). \n",
+ Comms.valuesFileName, GetLastError());
+ return FALSE;
+ }
+ PEDANTIC1(fclose, (commsFile));
+
+ /* Tell the parent the data is ready for it to adjust */
+ PEDANTIC(ResetEvent, (Comms.hEvToHelper));
+ PEDANTIC(SetEvent, (Comms.hEvFromHelper));
+
+ dwRet = WaitForSingleObject(Comms.hEvToHelper, TIMEOUT); /* parent is done */
+ if (dwRet != WAIT_OBJECT_0)
+ {
+ Trace("helper WaitForSingleObjectTest: WaitForSingleObject "
+ "failed (%u)\n", GetLastError());
+ return FALSE;
+ }
+
+ /* check the stuff that SHOULD have changed */
+ for (pCurr = pDest; pCurr < (pDest + lenDest); pCurr++)
+ {
+ if ( *pCurr != nextValue)
+ {
+ Trace("When testing '%s': alteration test failed "
+ "at %u offset %u. Found '%c' instead of '%c'\n.",
+ storageDescription, pDest, pCurr - pDest, *pCurr, nextValue);
+ Trace(" 'Altered' string: '%.*s'\n",lenBuffer, pBuffer);
+ return FALSE;
+ }
+ }
+ /* check the stuff that should NOT have changed */
+ for (pCurr = pBuffer; pCurr < pDest; pCurr++ )
+ {
+ if ( *pCurr != guardValue)
+ {
+ Trace("When testing '%s': leading guard zone test failed "
+ "at %u offset %u. Found '%c' instead of '%c'\n.",
+ storageDescription, pDest, pCurr - pBuffer, *pCurr, guardValue);
+ Trace(" 'Altered' string: '%.*s'\n",lenBuffer, pBuffer);
+ return FALSE;
+ }
+ }
+ for (pCurr = pDest + lenDest; pCurr < (pBuffer + lenBuffer); pCurr++ )
+ {
+ if ( *pCurr != guardValue)
+ {
+ Trace("When testing '%s': trailing guard zone test failed "
+ "at %u offset %u. Found '%c' instead of '%c'\n.",
+ storageDescription, pDest + lenDest, pCurr - pBuffer, *pCurr, guardValue);
+ Trace(" 'Altered' string: '%.*s'\n",lenBuffer, pBuffer);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ BOOL success = TRUE; /* assume success */
+ struct allhandles_t Comms = {0,0,0} ;
+
+ /* variables to track storage to alter */
+ char *pTarget = NULL;
+ unsigned int sizeTarget;
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ /* hook up with the events created by the parent */
+ Comms.hEvToHelper = OpenEventW(EVENT_ALL_ACCESS, 0, szcToHelperEvName);
+ if (!Comms.hEvToHelper)
+ {
+ Fail("WriteProcessMemory: OpenEvent of '%S' failed (%u). "
+ "(the event should already exist!)\n",
+ szcToHelperEvName, GetLastError());
+ }
+ Comms.hEvFromHelper = OpenEventW(EVENT_ALL_ACCESS, 0, szcFromHelperEvName);
+ if (!Comms.hEvToHelper)
+ {
+ Trace("WriteProcessMemory: OpenEvent of '%S' failed (%u). "
+ "(the event should already exist!)\n",
+ szcFromHelperEvName, GetLastError());
+ success = FALSE;
+ goto EXIT;
+ }
+ Comms.valuesFileName = argv[1];
+
+ {
+ char autoAllocatedOnStack[51];
+
+ /* Get the parent process to write to the local stack */
+ success &= wpmDoIt(Comms, autoAllocatedOnStack,
+ sizeof(autoAllocatedOnStack),
+ autoAllocatedOnStack + sizeof(int),
+ sizeof(autoAllocatedOnStack) - 2 * sizeof(int),
+ "const size array on stack with int sized guards");
+ }
+
+ /* Get the parent process to write to stuff on the heap */
+ sizeTarget = 2 * sizeof(int) + 23 ; /* 23 is just a random prime > 16 */
+ if (!(pTarget = (char*)malloc(sizeTarget)))
+ {
+ Trace("WriteProcessMemory helper: unable to allocate '%s'->%d bytes of memory"
+ "(%u).\n",
+ argv[3], sizeTarget, GetLastError());
+ success = FALSE;
+ goto EXIT;
+
+ }
+ success &= wpmDoIt(Comms, pTarget, sizeTarget,
+ pTarget + sizeof(int),
+ sizeTarget - 2 * sizeof(int),
+ "array on heap with int sized guards");
+
+ /* just to be nice try something 16 - 2 * sizeof(int) bytes long */
+ {
+ char autoAllocatedOnStack[16];
+
+ /* Get the parent process to write to the local stack */
+ success &= wpmDoIt(Comms, autoAllocatedOnStack,
+ sizeof(autoAllocatedOnStack),
+ autoAllocatedOnStack + sizeof(int),
+ sizeof(autoAllocatedOnStack) - 2 * sizeof(int),
+ "another 16 byte array on stack with int sized guards inside");
+ }
+
+ /* NOTE: Don't try 0 bytes long. Win32 WriteProcessMemory claims
+ * it writes 8 bytes in that case! */
+
+ /* and 1 byte long... */
+ {
+ char autoAllocatedOnStack[1+ 2 * sizeof(int)];
+
+ /* Get the parent process to write to the local stack */
+ success &= wpmDoIt(Comms, autoAllocatedOnStack,
+ sizeof(autoAllocatedOnStack),
+ autoAllocatedOnStack + sizeof(int),
+ 1,
+ "no bytes with int sized guards outside on stack");
+ }
+
+
+EXIT:
+ /* Tell the parent that we are done */
+ if (!DeleteFile(Comms.valuesFileName))
+ {
+ Trace("helper: DeleteFile failed so parent (test1) is unlikely "
+ "to exit cleanly\n");
+ }
+ PEDANTIC(ResetEvent, (Comms.hEvToHelper));
+ if (!SetEvent(Comms.hEvFromHelper))
+ {
+ Trace("helper: SetEvent failed so parent (test1) is unlikely "
+ "to exit cleanly\n");
+ }
+
+ free(pTarget);
+ PEDANTIC(CloseHandle, (Comms.hEvToHelper));
+ PEDANTIC(CloseHandle, (Comms.hEvFromHelper));
+
+ if (!success)
+ {
+ Fail("");
+ }
+
+ PAL_Terminate();
+
+ return success ? PASS : FAIL;
+}
diff --git a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/test1.c b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/test1.c
deleted file mode 100644
index 8de029d973..0000000000
--- a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/test1.c
+++ /dev/null
@@ -1,189 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: test1.c
-**
-** Purpose: Create a child process and some events for communications with it.
-** When the child gets back to us with a memory location and a length,
-** Call WriteProcessMemory on this location and check to see that it
-** writes successfully.
-**
-**
-**============================================================*/
-
-#define UNICODE
-
-#include "commonconsts.h"
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
-
- PROCESS_INFORMATION pi;
- STARTUPINFO si;
- HANDLE hEvToHelper;
- HANDLE hEvFromHelper;
- DWORD dwExitCode;
-
-
- DWORD dwRet;
- char cmdComposeBuf[MAX_PATH];
- PWCHAR uniString;
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- /* Create the signals we need for cross process communication */
- hEvToHelper = CreateEvent(NULL, TRUE, FALSE, szcToHelperEvName);
- if (!hEvToHelper)
- {
- Fail("WriteProcessMemory: CreateEvent of '%S' failed. "
- "GetLastError() returned %d.\n", szcToHelperEvName,
- GetLastError());
- }
- if (GetLastError() == ERROR_ALREADY_EXISTS)
- {
- Fail("WriteProcessMemory: CreateEvent of '%S' failed. "
- "(already exists!)\n", szcToHelperEvName);
- }
- hEvFromHelper = CreateEvent(NULL, TRUE, FALSE, szcFromHelperEvName);
- if (!hEvToHelper)
- {
- Fail("WriteProcessMemory: CreateEvent of '%S' failed. "
- "GetLastError() returned %d.\n", szcFromHelperEvName,
- GetLastError());
- }
- if (GetLastError() == ERROR_ALREADY_EXISTS)
- {
- Fail("WriteProcessMemory: CreateEvent of '%S' failed. "
- "(already exists!)\n", szcFromHelperEvName);
- }
- ResetEvent(hEvFromHelper);
- ResetEvent(hEvToHelper);
-
- if (!sprintf(cmdComposeBuf, "helper %s", commsFileName))
- {
- Fail("Could not convert command line\n");
- }
- uniString = convert(cmdComposeBuf);
-
- ZeroMemory( &si, sizeof(si) );
- si.cb = sizeof(si);
- ZeroMemory( &pi, sizeof(pi) );
-
- /* Create a new process. This is the process that will ask for
- * memory munging */
- if(!CreateProcess( NULL, uniString, NULL, NULL,
- FALSE, 0, NULL, NULL, &si, &pi))
- {
- Trace("ERROR: CreateProcess failed to load executable '%S'. "
- "GetLastError() returned %u.\n",
- uniString, GetLastError());
- free(uniString);
- Fail("");
- }
- free(uniString);
-
- while(1)
- {
- FILE *commsFile;
- char* pSrcMemory;
- char* pDestMemory;
- int Count;
- SIZE_T wpmCount;
- char incomingCMDBuffer[MAX_PATH + 1];
-
- /* wait until the helper tells us that it has given us
- * something to do */
- dwRet = WaitForSingleObject(hEvFromHelper, TIMEOUT);
- if (dwRet != WAIT_OBJECT_0)
- {
- Trace("test1 WaitForSingleObjectTest: WaitForSingleObject "
- "failed (%u)\n", GetLastError());
- break; /* no more work incoming */
- }
-
- /* get the parameters to test WriteProcessMemory with */
- if (!(commsFile = fopen(commsFileName, "r")))
- {
- /* no file means there is no more work */
- break;
- }
- if ( NULL == fgets(incomingCMDBuffer, MAX_PATH, commsFile))
- {
- Fail ("unable to read from communication file %s "
- "for reasons %u & %u\n",
- errno, GetLastError());
- }
- PEDANTIC1(fclose,(commsFile));
- sscanf(incomingCMDBuffer, "%u %u", &pDestMemory, &Count);
- if (argc > 1)
- {
- Trace("Preparing to write to %u bytes @ %u ('%s')\n",
- Count, pDestMemory, incomingCMDBuffer);
- }
-
- /* compose some data to write to the client process */
- if (!(pSrcMemory = malloc(Count)))
- {
- Trace("could not dynamically allocate memory to copy from "
- "for reasons %u & %u\n",
- errno, GetLastError());
- goto doneIteration;
- }
- memset(pSrcMemory, nextValue, Count);
-
- /* do the work */
- dwRet = WriteProcessMemory(pi.hProcess,
- pDestMemory,
- pSrcMemory,
- Count,
- &wpmCount);
- if (!dwRet)
- {
- Trace("%s: Problem: on a write to %u bytes @ %u ('%s')\n",
- argv[0], Count, pDestMemory, incomingCMDBuffer);
- Trace("test1 WriteProcessMemory returned a%u(!=0) (GLE=%u)\n",
- GetLastError());
- }
- if(Count != wpmCount)
- {
- Trace("%s: Problem: on a write to %u bytes @ %u ('%s')\n",
- argv[0], Count, pDestMemory, incomingCMDBuffer);
- Trace("The number of bytes written should have been "
- "%u, but was reported as %u.\n", Count, wpmCount);
- }
- free(pSrcMemory);
-
- doneIteration:
- PEDANTIC(ResetEvent, (hEvFromHelper));
- PEDANTIC(SetEvent, (hEvToHelper));
- }
-
- /* wait for the child process to complete */
- WaitForSingleObject ( pi.hProcess, TIMEOUT );
- /* this may return a failure code on a success path */
-
- /* check the exit code from the process */
- if( ! GetExitCodeProcess( pi.hProcess, &dwExitCode ) )
- {
- Trace( "GetExitCodeProcess call failed with error code %u\n",
- GetLastError() );
- dwExitCode = FAIL;
- }
-
-
- PEDANTIC(CloseHandle, (hEvToHelper));
- PEDANTIC(CloseHandle, (hEvFromHelper));
- PEDANTIC(CloseHandle, (pi.hThread));
- PEDANTIC(CloseHandle, (pi.hProcess));
-
- PAL_TerminateEx(dwExitCode);
- return dwExitCode;
-}
diff --git a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/test1.cpp b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/test1.cpp
new file mode 100644
index 0000000000..f390c10c72
--- /dev/null
+++ b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test1/test1.cpp
@@ -0,0 +1,189 @@
+// Licensed to the .NET Foundation under one or more 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: test1.c
+**
+** Purpose: Create a child process and some events for communications with it.
+** When the child gets back to us with a memory location and a length,
+** Call WriteProcessMemory on this location and check to see that it
+** writes successfully.
+**
+**
+**============================================================*/
+
+#define UNICODE
+
+#include "commonconsts.h"
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ PROCESS_INFORMATION pi;
+ STARTUPINFO si;
+ HANDLE hEvToHelper;
+ HANDLE hEvFromHelper;
+ DWORD dwExitCode;
+
+
+ DWORD dwRet;
+ char cmdComposeBuf[MAX_PATH];
+ PWCHAR uniString;
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ /* Create the signals we need for cross process communication */
+ hEvToHelper = CreateEvent(NULL, TRUE, FALSE, szcToHelperEvName);
+ if (!hEvToHelper)
+ {
+ Fail("WriteProcessMemory: CreateEvent of '%S' failed. "
+ "GetLastError() returned %d.\n", szcToHelperEvName,
+ GetLastError());
+ }
+ if (GetLastError() == ERROR_ALREADY_EXISTS)
+ {
+ Fail("WriteProcessMemory: CreateEvent of '%S' failed. "
+ "(already exists!)\n", szcToHelperEvName);
+ }
+ hEvFromHelper = CreateEvent(NULL, TRUE, FALSE, szcFromHelperEvName);
+ if (!hEvToHelper)
+ {
+ Fail("WriteProcessMemory: CreateEvent of '%S' failed. "
+ "GetLastError() returned %d.\n", szcFromHelperEvName,
+ GetLastError());
+ }
+ if (GetLastError() == ERROR_ALREADY_EXISTS)
+ {
+ Fail("WriteProcessMemory: CreateEvent of '%S' failed. "
+ "(already exists!)\n", szcFromHelperEvName);
+ }
+ ResetEvent(hEvFromHelper);
+ ResetEvent(hEvToHelper);
+
+ if (!sprintf_s(cmdComposeBuf, _countof(cmdComposeBuf), "helper %s", commsFileName))
+ {
+ Fail("Could not convert command line\n");
+ }
+ uniString = convert(cmdComposeBuf);
+
+ ZeroMemory( &si, sizeof(si) );
+ si.cb = sizeof(si);
+ ZeroMemory( &pi, sizeof(pi) );
+
+ /* Create a new process. This is the process that will ask for
+ * memory munging */
+ if(!CreateProcess( NULL, uniString, NULL, NULL,
+ FALSE, 0, NULL, NULL, &si, &pi))
+ {
+ Trace("ERROR: CreateProcess failed to load executable '%S'. "
+ "GetLastError() returned %u.\n",
+ uniString, GetLastError());
+ free(uniString);
+ Fail("");
+ }
+ free(uniString);
+
+ while(1)
+ {
+ FILE *commsFile;
+ char* pSrcMemory;
+ char* pDestMemory;
+ int Count;
+ SIZE_T wpmCount;
+ char incomingCMDBuffer[MAX_PATH + 1];
+
+ /* wait until the helper tells us that it has given us
+ * something to do */
+ dwRet = WaitForSingleObject(hEvFromHelper, TIMEOUT);
+ if (dwRet != WAIT_OBJECT_0)
+ {
+ Trace("test1 WaitForSingleObjectTest: WaitForSingleObject "
+ "failed (%u)\n", GetLastError());
+ break; /* no more work incoming */
+ }
+
+ /* get the parameters to test WriteProcessMemory with */
+ if (!(commsFile = fopen(commsFileName, "r")))
+ {
+ /* no file means there is no more work */
+ break;
+ }
+ if ( NULL == fgets(incomingCMDBuffer, MAX_PATH, commsFile))
+ {
+ Fail ("unable to read from communication file %s "
+ "for reasons %u & %u\n",
+ errno, GetLastError());
+ }
+ PEDANTIC1(fclose,(commsFile));
+ sscanf(incomingCMDBuffer, "%u %u", &pDestMemory, &Count);
+ if (argc > 1)
+ {
+ Trace("Preparing to write to %u bytes @ %u ('%s')\n",
+ Count, pDestMemory, incomingCMDBuffer);
+ }
+
+ /* compose some data to write to the client process */
+ if (!(pSrcMemory = (char*)malloc(Count)))
+ {
+ Trace("could not dynamically allocate memory to copy from "
+ "for reasons %u & %u\n",
+ errno, GetLastError());
+ goto doneIteration;
+ }
+ memset(pSrcMemory, nextValue, Count);
+
+ /* do the work */
+ dwRet = WriteProcessMemory(pi.hProcess,
+ pDestMemory,
+ pSrcMemory,
+ Count,
+ &wpmCount);
+ if (!dwRet)
+ {
+ Trace("%s: Problem: on a write to %u bytes @ %u ('%s')\n",
+ argv[0], Count, pDestMemory, incomingCMDBuffer);
+ Trace("test1 WriteProcessMemory returned a%u(!=0) (GLE=%u)\n",
+ GetLastError());
+ }
+ if(Count != wpmCount)
+ {
+ Trace("%s: Problem: on a write to %u bytes @ %u ('%s')\n",
+ argv[0], Count, pDestMemory, incomingCMDBuffer);
+ Trace("The number of bytes written should have been "
+ "%u, but was reported as %u.\n", Count, wpmCount);
+ }
+ free(pSrcMemory);
+
+ doneIteration:
+ PEDANTIC(ResetEvent, (hEvFromHelper));
+ PEDANTIC(SetEvent, (hEvToHelper));
+ }
+
+ /* wait for the child process to complete */
+ WaitForSingleObject ( pi.hProcess, TIMEOUT );
+ /* this may return a failure code on a success path */
+
+ /* check the exit code from the process */
+ if( ! GetExitCodeProcess( pi.hProcess, &dwExitCode ) )
+ {
+ Trace( "GetExitCodeProcess call failed with error code %u\n",
+ GetLastError() );
+ dwExitCode = FAIL;
+ }
+
+
+ PEDANTIC(CloseHandle, (hEvToHelper));
+ PEDANTIC(CloseHandle, (hEvFromHelper));
+ PEDANTIC(CloseHandle, (pi.hThread));
+ PEDANTIC(CloseHandle, (pi.hProcess));
+
+ PAL_TerminateEx(dwExitCode);
+ return dwExitCode;
+}
diff --git a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test3/CMakeLists.txt b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test3/CMakeLists.txt
index ecc0e06dac..3a5067c926 100644
--- a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(TESTSOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_writeprocessmemory_test3
@@ -20,7 +20,7 @@ target_link_libraries(paltest_writeprocessmemory_test3
set(HELPERSOURCES
- helper.c
+ helper.cpp
)
add_executable(paltest_writeprocessmemory_test3_helper
diff --git a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test3/helper.c b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test3/helper.cpp
index 170e2064cb..170e2064cb 100644
--- a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test3/helper.c
+++ b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test3/helper.cpp
diff --git a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test3/test3.c b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test3/test3.c
deleted file mode 100644
index 063cb4cbec..0000000000
--- a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test3/test3.c
+++ /dev/null
@@ -1,205 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: test3.c
-**
-** Purpose: Create a child process and debug it. When the child
-** raises an exception, it sends back a memory location. Call
-** WriteProcessMemory on the memory location, but attempt to write
-** more than the memory allows. This should cause an error and the
-** data should be unchanged.
-**
-**
-==============================================================*/
-
-#define UNICODE
-
-#include "commonconsts.h"
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
-
- PROCESS_INFORMATION pi;
- STARTUPINFO si;
- HANDLE hEvToHelper;
- HANDLE hEvFromHelper;
- DWORD dwExitCode;
-
-
- DWORD dwRet;
- BOOL success = TRUE; /* assume success */
- char cmdComposeBuf[MAX_PATH];
- PWCHAR uniString;
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- /* Create the signals we need for cross process communication */
- hEvToHelper = CreateEvent(NULL, TRUE, FALSE, szcToHelperEvName);
- if (!hEvToHelper)
- {
- Fail("WriteProcessMemory: CreateEvent of '%S' failed. "
- "GetLastError() returned %u.\n", szcToHelperEvName,
- GetLastError());
- }
- if (GetLastError() == ERROR_ALREADY_EXISTS)
- {
- Fail("WriteProcessMemory: CreateEvent of '%S' failed. "
- "(already exists!)\n", szcToHelperEvName);
- }
- hEvFromHelper = CreateEvent(NULL, TRUE, FALSE, szcFromHelperEvName);
- if (!hEvToHelper)
- {
- Fail("WriteProcessMemory: CreateEvent of '%S' failed. "
- "GetLastError() returned %u.\n", szcFromHelperEvName,
- GetLastError());
- }
- if (GetLastError() == ERROR_ALREADY_EXISTS)
- {
- Fail("WriteProcessMemory: CreateEvent of '%S' failed. "
- "(already exists!)\n", szcFromHelperEvName);
- }
-
- if (!sprintf(cmdComposeBuf, "helper %s", commsFileName))
- {
- Fail("Could not convert command line\n");
- }
- uniString = convert(cmdComposeBuf);
-
- ZeroMemory( &si, sizeof(si) );
- si.cb = sizeof(si);
- ZeroMemory( &pi, sizeof(pi) );
-
- /* Create a new process. This is the process that will ask for
- * memory munging */
- if(!CreateProcess( NULL, uniString, NULL, NULL,
- FALSE, 0, NULL, NULL, &si, &pi))
- {
- Trace("ERROR: CreateProcess failed to load executable '%S'. "
- "GetLastError() returned %u.\n",
- uniString, GetLastError());
- free(uniString);
- Fail("");
- }
- free(uniString);
-
- while(1)
- {
- FILE *commsFile;
- char* pSrcMemory;
- char* pDestMemory;
- int Count;
- SIZE_T wpmCount;
- DWORD dwExpectedErrorCode;
-
- char incomingCMDBuffer[MAX_PATH + 1];
-
- /* wait until the helper tells us that it has given us
- * something to do */
- dwRet = WaitForSingleObject(hEvFromHelper, TIMEOUT);
- if (dwRet != WAIT_OBJECT_0)
- {
- Trace("test1 WaitForSingleObjectTest: WaitForSingleObject "
- "failed (%u)\n", GetLastError());
- break; /* no more work incoming */
- }
-
- /* get the parameters to test WriteProcessMemory with */
- if (!(commsFile = fopen(commsFileName, "r")))
- {
- /* no file means there is no more work */
- break;
- }
- if ( NULL == fgets(incomingCMDBuffer, MAX_PATH, commsFile))
- {
- Trace ("unable to read from communication file %s "
- "for reasons %u & %u\n",
- errno, GetLastError());
- success = FALSE;
- PEDANTIC1(fclose,(commsFile));
- /* it's not worth continuing this trial */
- goto doneIteration;
- }
- PEDANTIC1(fclose,(commsFile));
- sscanf(incomingCMDBuffer, "%u %u %u",
- &pDestMemory, &Count, &dwExpectedErrorCode);
- if (argc > 1)
- {
- Trace("Preparing to write to %u bytes @ %u ('%s')\n",
- Count, pDestMemory, incomingCMDBuffer);
- }
-
- /* compose some data to write to the client process */
- if (!(pSrcMemory = malloc(Count)))
- {
- Trace("could not dynamically allocate memory to copy from "
- "for reasons %u & %u\n",
- errno, GetLastError());
- success = FALSE;
- goto doneIteration;
- }
- memset(pSrcMemory, nextValue, Count);
-
- /* do the work */
- dwRet = WriteProcessMemory(pi.hProcess,
- pDestMemory,
- pSrcMemory,
- Count,
- &wpmCount);
-
- if(dwRet != 0)
- {
- Trace("ERROR: Situation: '%s', return code: %u, bytes 'written': %u\n",
- incomingCMDBuffer, dwRet, wpmCount);
- Trace("ERROR: WriteProcessMemory did not fail as it should, as "
- "it attempted to write to a range of memory which was "
- "not completely accessible.\n");
- success = FALSE;
- }
-
- if(GetLastError() != dwExpectedErrorCode)
- {
- Trace("ERROR: GetLastError() should have returned "
- "%u , but instead it returned %u.\n",
- dwExpectedErrorCode, GetLastError());
- success = FALSE;
- }
- free(pSrcMemory);
-
- doneIteration:
- PEDANTIC(ResetEvent, (hEvFromHelper));
- PEDANTIC(SetEvent, (hEvToHelper));
- }
-
-
- /* wait for the child process to complete */
- WaitForSingleObject ( pi.hProcess, TIMEOUT );
- /* this may return a failure code on a success path */
-
- /* check the exit code from the process */
- if( ! GetExitCodeProcess( pi.hProcess, &dwExitCode ) )
- {
- Trace( "GetExitCodeProcess call failed with error code %u\n",
- GetLastError() );
- dwExitCode = FAIL;
- }
- if(!success)
- {
- dwExitCode = FAIL;
- }
-
- PEDANTIC(CloseHandle, (hEvToHelper));
- PEDANTIC(CloseHandle, (hEvFromHelper));
- PEDANTIC(CloseHandle, (pi.hThread));
- PEDANTIC(CloseHandle, (pi.hProcess));
-
- PAL_Terminate(dwExitCode);
- return dwExitCode;
-}
diff --git a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test3/test3.cpp b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test3/test3.cpp
new file mode 100644
index 0000000000..15b4b3f79d
--- /dev/null
+++ b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test3/test3.cpp
@@ -0,0 +1,205 @@
+// Licensed to the .NET Foundation under one or more 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: test3.c
+**
+** Purpose: Create a child process and debug it. When the child
+** raises an exception, it sends back a memory location. Call
+** WriteProcessMemory on the memory location, but attempt to write
+** more than the memory allows. This should cause an error and the
+** data should be unchanged.
+**
+**
+==============================================================*/
+
+#define UNICODE
+
+#include "commonconsts.h"
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ PROCESS_INFORMATION pi;
+ STARTUPINFO si;
+ HANDLE hEvToHelper;
+ HANDLE hEvFromHelper;
+ DWORD dwExitCode;
+
+
+ DWORD dwRet;
+ BOOL success = TRUE; /* assume success */
+ char cmdComposeBuf[MAX_PATH];
+ PWCHAR uniString;
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ /* Create the signals we need for cross process communication */
+ hEvToHelper = CreateEvent(NULL, TRUE, FALSE, szcToHelperEvName);
+ if (!hEvToHelper)
+ {
+ Fail("WriteProcessMemory: CreateEvent of '%S' failed. "
+ "GetLastError() returned %u.\n", szcToHelperEvName,
+ GetLastError());
+ }
+ if (GetLastError() == ERROR_ALREADY_EXISTS)
+ {
+ Fail("WriteProcessMemory: CreateEvent of '%S' failed. "
+ "(already exists!)\n", szcToHelperEvName);
+ }
+ hEvFromHelper = CreateEvent(NULL, TRUE, FALSE, szcFromHelperEvName);
+ if (!hEvToHelper)
+ {
+ Fail("WriteProcessMemory: CreateEvent of '%S' failed. "
+ "GetLastError() returned %u.\n", szcFromHelperEvName,
+ GetLastError());
+ }
+ if (GetLastError() == ERROR_ALREADY_EXISTS)
+ {
+ Fail("WriteProcessMemory: CreateEvent of '%S' failed. "
+ "(already exists!)\n", szcFromHelperEvName);
+ }
+
+ if (!sprintf_s(cmdComposeBuf, _countof(cmdComposeBuf), "helper %s", commsFileName))
+ {
+ Fail("Could not convert command line\n");
+ }
+ uniString = convert(cmdComposeBuf);
+
+ ZeroMemory( &si, sizeof(si) );
+ si.cb = sizeof(si);
+ ZeroMemory( &pi, sizeof(pi) );
+
+ /* Create a new process. This is the process that will ask for
+ * memory munging */
+ if(!CreateProcess( NULL, uniString, NULL, NULL,
+ FALSE, 0, NULL, NULL, &si, &pi))
+ {
+ Trace("ERROR: CreateProcess failed to load executable '%S'. "
+ "GetLastError() returned %u.\n",
+ uniString, GetLastError());
+ free(uniString);
+ Fail("");
+ }
+ free(uniString);
+
+ while(1)
+ {
+ FILE *commsFile;
+ char* pSrcMemory;
+ char* pDestMemory;
+ int Count;
+ SIZE_T wpmCount;
+ DWORD dwExpectedErrorCode;
+
+ char incomingCMDBuffer[MAX_PATH + 1];
+
+ /* wait until the helper tells us that it has given us
+ * something to do */
+ dwRet = WaitForSingleObject(hEvFromHelper, TIMEOUT);
+ if (dwRet != WAIT_OBJECT_0)
+ {
+ Trace("test1 WaitForSingleObjectTest: WaitForSingleObject "
+ "failed (%u)\n", GetLastError());
+ break; /* no more work incoming */
+ }
+
+ /* get the parameters to test WriteProcessMemory with */
+ if (!(commsFile = fopen(commsFileName, "r")))
+ {
+ /* no file means there is no more work */
+ break;
+ }
+ if ( NULL == fgets(incomingCMDBuffer, MAX_PATH, commsFile))
+ {
+ Trace ("unable to read from communication file %s "
+ "for reasons %u & %u\n",
+ errno, GetLastError());
+ success = FALSE;
+ PEDANTIC1(fclose,(commsFile));
+ /* it's not worth continuing this trial */
+ goto doneIteration;
+ }
+ PEDANTIC1(fclose,(commsFile));
+ sscanf(incomingCMDBuffer, "%u %u %u",
+ &pDestMemory, &Count, &dwExpectedErrorCode);
+ if (argc > 1)
+ {
+ Trace("Preparing to write to %u bytes @ %u ('%s')\n",
+ Count, pDestMemory, incomingCMDBuffer);
+ }
+
+ /* compose some data to write to the client process */
+ if (!(pSrcMemory = (char*)malloc(Count)))
+ {
+ Trace("could not dynamically allocate memory to copy from "
+ "for reasons %u & %u\n",
+ errno, GetLastError());
+ success = FALSE;
+ goto doneIteration;
+ }
+ memset(pSrcMemory, nextValue, Count);
+
+ /* do the work */
+ dwRet = WriteProcessMemory(pi.hProcess,
+ pDestMemory,
+ pSrcMemory,
+ Count,
+ &wpmCount);
+
+ if(dwRet != 0)
+ {
+ Trace("ERROR: Situation: '%s', return code: %u, bytes 'written': %u\n",
+ incomingCMDBuffer, dwRet, wpmCount);
+ Trace("ERROR: WriteProcessMemory did not fail as it should, as "
+ "it attempted to write to a range of memory which was "
+ "not completely accessible.\n");
+ success = FALSE;
+ }
+
+ if(GetLastError() != dwExpectedErrorCode)
+ {
+ Trace("ERROR: GetLastError() should have returned "
+ "%u , but instead it returned %u.\n",
+ dwExpectedErrorCode, GetLastError());
+ success = FALSE;
+ }
+ free(pSrcMemory);
+
+ doneIteration:
+ PEDANTIC(ResetEvent, (hEvFromHelper));
+ PEDANTIC(SetEvent, (hEvToHelper));
+ }
+
+
+ /* wait for the child process to complete */
+ WaitForSingleObject ( pi.hProcess, TIMEOUT );
+ /* this may return a failure code on a success path */
+
+ /* check the exit code from the process */
+ if( ! GetExitCodeProcess( pi.hProcess, &dwExitCode ) )
+ {
+ Trace( "GetExitCodeProcess call failed with error code %u\n",
+ GetLastError() );
+ dwExitCode = FAIL;
+ }
+ if(!success)
+ {
+ dwExitCode = FAIL;
+ }
+
+ PEDANTIC(CloseHandle, (hEvToHelper));
+ PEDANTIC(CloseHandle, (hEvFromHelper));
+ PEDANTIC(CloseHandle, (pi.hThread));
+ PEDANTIC(CloseHandle, (pi.hProcess));
+
+ PAL_Terminate(dwExitCode);
+ return dwExitCode;
+}
diff --git a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test4/CMakeLists.txt b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test4/CMakeLists.txt
index cf1ce13862..7cba09038a 100644
--- a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(TESTSOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_writeprocessmemory_test4
@@ -20,7 +20,7 @@ target_link_libraries(paltest_writeprocessmemory_test4
set(HELPERSOURCES
- helper.c
+ helper.cpp
)
add_executable(paltest_writeprocessmemory_test4_helper
diff --git a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test4/helper.c b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test4/helper.cpp
index b653ea5057..b653ea5057 100644
--- a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test4/helper.c
+++ b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test4/helper.cpp
diff --git a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test4/test4.c b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test4/test4.cpp
index 51db23499b..51db23499b 100644
--- a/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test4/test4.c
+++ b/src/pal/tests/palsuite/debug_api/WriteProcessMemory/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test1/CMakeLists.txt b/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test1/CMakeLists.txt
index adbc8ae86a..4e30869d85 100644
--- a/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- PAL_EXCEPT_FILTER.c
+ PAL_EXCEPT_FILTER.cpp
)
add_executable(paltest_pal_except_filter_test1
diff --git a/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test1/PAL_EXCEPT_FILTER.c b/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test1/PAL_EXCEPT_FILTER.cpp
index ee65f43d2c..ee65f43d2c 100644
--- a/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test1/PAL_EXCEPT_FILTER.c
+++ b/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test1/PAL_EXCEPT_FILTER.cpp
diff --git a/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test2/CMakeLists.txt b/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test2/CMakeLists.txt
index 62cda706d5..3f979c08db 100644
--- a/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- pal_except_filter.c
+ pal_except_filter.cpp
)
add_executable(paltest_pal_except_filter_test2
diff --git a/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test2/pal_except_filter.c b/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test2/pal_except_filter.cpp
index ccf53fb0ba..ccf53fb0ba 100644
--- a/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test2/pal_except_filter.c
+++ b/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test2/pal_except_filter.cpp
diff --git a/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test3/CMakeLists.txt b/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test3/CMakeLists.txt
index cc68fb031c..2bdf44e058 100644
--- a/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- pal_except_filter.c
+ pal_except_filter.cpp
)
add_executable(paltest_pal_except_filter_test3
diff --git a/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test3/pal_except_filter.c b/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test3/pal_except_filter.cpp
index 20c36840b1..20c36840b1 100644
--- a/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test3/pal_except_filter.c
+++ b/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test3/pal_except_filter.cpp
diff --git a/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test1/CMakeLists.txt b/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test1/CMakeLists.txt
index 21c3b5d33c..cf0a5e7c6d 100644
--- a/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- PAL_EXCEPT_FILTER_EX.c
+ PAL_EXCEPT_FILTER_EX.cpp
)
add_executable(paltest_pal_except_filter_ex_test1
diff --git a/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test1/PAL_EXCEPT_FILTER_EX.c b/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test1/PAL_EXCEPT_FILTER_EX.cpp
index 91f392d8d7..91f392d8d7 100644
--- a/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test1/PAL_EXCEPT_FILTER_EX.c
+++ b/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test1/PAL_EXCEPT_FILTER_EX.cpp
diff --git a/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test2/CMakeLists.txt b/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test2/CMakeLists.txt
index 350acff036..a3f82c26b9 100644
--- a/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- pal_except_filter_ex.c
+ pal_except_filter_ex.cpp
)
add_executable(paltest_pal_except_filter_ex_test2
diff --git a/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test2/pal_except_filter_ex.c b/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test2/pal_except_filter_ex.cpp
index ab25c49733..ab25c49733 100644
--- a/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test2/pal_except_filter_ex.c
+++ b/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test2/pal_except_filter_ex.cpp
diff --git a/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test3/CMakeLists.txt b/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test3/CMakeLists.txt
index 7f485c8ca4..532b29a9a1 100644
--- a/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- pal_except_filter.c
+ pal_except_filter.cpp
)
add_executable(paltest_pal_except_filter_ex_test3
diff --git a/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test3/pal_except_filter.c b/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test3/pal_except_filter.cpp
index a17cb4f6b3..a17cb4f6b3 100644
--- a/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test3/pal_except_filter.c
+++ b/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER_EX/test3/pal_except_filter.cpp
diff --git a/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT/test1/CMakeLists.txt b/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT/test1/CMakeLists.txt
index 8a1a832361..b478de63e4 100644
--- a/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- PAL_TRY_EXCEPT.c
+ PAL_TRY_EXCEPT.cpp
)
add_executable(paltest_pal_try_except_test1
diff --git a/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT/test1/PAL_TRY_EXCEPT.c b/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT/test1/PAL_TRY_EXCEPT.cpp
index 4fb09bd276..4fb09bd276 100644
--- a/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT/test1/PAL_TRY_EXCEPT.c
+++ b/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT/test1/PAL_TRY_EXCEPT.cpp
diff --git a/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT/test2/CMakeLists.txt b/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT/test2/CMakeLists.txt
index cdf371926c..0e344a9320 100644
--- a/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- PAL_TRY_EXCEPT.c
+ PAL_TRY_EXCEPT.cpp
)
add_executable(paltest_pal_try_except_test2
diff --git a/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT/test2/PAL_TRY_EXCEPT.c b/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT/test2/PAL_TRY_EXCEPT.cpp
index eb7b9d1257..eb7b9d1257 100644
--- a/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT/test2/PAL_TRY_EXCEPT.c
+++ b/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT/test2/PAL_TRY_EXCEPT.cpp
diff --git a/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test1/CMakeLists.txt b/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test1/CMakeLists.txt
index c30877f65e..cced8a11be 100644
--- a/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- PAL_TRY_EXCEPT_EX.c
+ PAL_TRY_EXCEPT_EX.cpp
)
add_executable(paltest_pal_try_except_ex_test1
diff --git a/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test1/PAL_TRY_EXCEPT_EX.c b/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test1/PAL_TRY_EXCEPT_EX.cpp
index 8b4dd7b430..8b4dd7b430 100644
--- a/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test1/PAL_TRY_EXCEPT_EX.c
+++ b/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test1/PAL_TRY_EXCEPT_EX.cpp
diff --git a/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test2/CMakeLists.txt b/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test2/CMakeLists.txt
index 0d4c4db240..c3549b5d87 100644
--- a/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- PAL_TRY_EXCEPT_EX.c
+ PAL_TRY_EXCEPT_EX.cpp
)
add_executable(paltest_pal_try_except_ex_test2
diff --git a/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test2/PAL_TRY_EXCEPT_EX.c b/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test2/PAL_TRY_EXCEPT_EX.cpp
index 5ab4a95ce9..5ab4a95ce9 100644
--- a/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test2/PAL_TRY_EXCEPT_EX.c
+++ b/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test2/PAL_TRY_EXCEPT_EX.cpp
diff --git a/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test3/CMakeLists.txt b/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test3/CMakeLists.txt
index dc797f2f09..34790da3d3 100644
--- a/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- PAL_TRY_EXCEPT_EX.c
+ PAL_TRY_EXCEPT_EX.cpp
)
add_executable(paltest_pal_try_except_ex_test3
diff --git a/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test3/PAL_TRY_EXCEPT_EX.c b/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test3/PAL_TRY_EXCEPT_EX.cpp
index d6a948926b..d6a948926b 100644
--- a/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test3/PAL_TRY_EXCEPT_EX.c
+++ b/src/pal/tests/palsuite/exception_handling/PAL_TRY_EXCEPT_EX/test3/PAL_TRY_EXCEPT_EX.cpp
diff --git a/src/pal/tests/palsuite/exception_handling/PAL_TRY_LEAVE_FINALLY/test1/CMakeLists.txt b/src/pal/tests/palsuite/exception_handling/PAL_TRY_LEAVE_FINALLY/test1/CMakeLists.txt
index a5fdd26924..f004db1658 100644
--- a/src/pal/tests/palsuite/exception_handling/PAL_TRY_LEAVE_FINALLY/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/exception_handling/PAL_TRY_LEAVE_FINALLY/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- PAL_TRY_LEAVE_FINALLY.c
+ PAL_TRY_LEAVE_FINALLY.cpp
)
add_executable(paltest_pal_try_leave_finally_test1
diff --git a/src/pal/tests/palsuite/exception_handling/PAL_TRY_LEAVE_FINALLY/test1/PAL_TRY_LEAVE_FINALLY.c b/src/pal/tests/palsuite/exception_handling/PAL_TRY_LEAVE_FINALLY/test1/PAL_TRY_LEAVE_FINALLY.cpp
index 675c2a5947..675c2a5947 100644
--- a/src/pal/tests/palsuite/exception_handling/PAL_TRY_LEAVE_FINALLY/test1/PAL_TRY_LEAVE_FINALLY.c
+++ b/src/pal/tests/palsuite/exception_handling/PAL_TRY_LEAVE_FINALLY/test1/PAL_TRY_LEAVE_FINALLY.cpp
diff --git a/src/pal/tests/palsuite/exception_handling/SetUnhandledExceptionFilter/test1/CMakeLists.txt b/src/pal/tests/palsuite/exception_handling/SetUnhandledExceptionFilter/test1/CMakeLists.txt
index e526029bee..068427303f 100644
--- a/src/pal/tests/palsuite/exception_handling/SetUnhandledExceptionFilter/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/exception_handling/SetUnhandledExceptionFilter/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_setunhandledexceptionfilter_test1
diff --git a/src/pal/tests/palsuite/exception_handling/SetUnhandledExceptionFilter/test1/test1.c b/src/pal/tests/palsuite/exception_handling/SetUnhandledExceptionFilter/test1/test1.cpp
index 5a067f9354..5a067f9354 100644
--- a/src/pal/tests/palsuite/exception_handling/SetUnhandledExceptionFilter/test1/test1.c
+++ b/src/pal/tests/palsuite/exception_handling/SetUnhandledExceptionFilter/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/exception_handling/pal_except/test1/CMakeLists.txt b/src/pal/tests/palsuite/exception_handling/pal_except/test1/CMakeLists.txt
index 635e35d635..b219238ef4 100644
--- a/src/pal/tests/palsuite/exception_handling/pal_except/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/exception_handling/pal_except/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_pal_except_test1
diff --git a/src/pal/tests/palsuite/exception_handling/pal_except/test1/test1.c b/src/pal/tests/palsuite/exception_handling/pal_except/test1/test1.cpp
index 0fe48e7fc3..0fe48e7fc3 100644
--- a/src/pal/tests/palsuite/exception_handling/pal_except/test1/test1.c
+++ b/src/pal/tests/palsuite/exception_handling/pal_except/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/exception_handling/pal_except/test2/CMakeLists.txt b/src/pal/tests/palsuite/exception_handling/pal_except/test2/CMakeLists.txt
index 813b0e66a1..27a725353b 100644
--- a/src/pal/tests/palsuite/exception_handling/pal_except/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/exception_handling/pal_except/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_pal_except_test2
diff --git a/src/pal/tests/palsuite/exception_handling/pal_except/test2/test2.c b/src/pal/tests/palsuite/exception_handling/pal_except/test2/test2.cpp
index bc0d4e300a..bc0d4e300a 100644
--- a/src/pal/tests/palsuite/exception_handling/pal_except/test2/test2.c
+++ b/src/pal/tests/palsuite/exception_handling/pal_except/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/exception_handling/pal_except/test3/CMakeLists.txt b/src/pal/tests/palsuite/exception_handling/pal_except/test3/CMakeLists.txt
index 5fc3b096af..680341a782 100644
--- a/src/pal/tests/palsuite/exception_handling/pal_except/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/exception_handling/pal_except/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_pal_except_test3
diff --git a/src/pal/tests/palsuite/exception_handling/pal_except/test3/test3.c b/src/pal/tests/palsuite/exception_handling/pal_except/test3/test3.cpp
index 0137697774..0137697774 100644
--- a/src/pal/tests/palsuite/exception_handling/pal_except/test3/test3.c
+++ b/src/pal/tests/palsuite/exception_handling/pal_except/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/exception_handling/pal_except/test4/CMakeLists.txt b/src/pal/tests/palsuite/exception_handling/pal_except/test4/CMakeLists.txt
index cc054d15dd..98eb7bfb23 100644
--- a/src/pal/tests/palsuite/exception_handling/pal_except/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/exception_handling/pal_except/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_pal_except_test4
diff --git a/src/pal/tests/palsuite/exception_handling/pal_except/test4/test4.c b/src/pal/tests/palsuite/exception_handling/pal_except/test4/test4.cpp
index 87844973b0..87844973b0 100644
--- a/src/pal/tests/palsuite/exception_handling/pal_except/test4/test4.c
+++ b/src/pal/tests/palsuite/exception_handling/pal_except/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/exception_handling/pal_except/test5/CMakeLists.txt b/src/pal/tests/palsuite/exception_handling/pal_except/test5/CMakeLists.txt
index 7b8f1d0361..9a39e32cce 100644
--- a/src/pal/tests/palsuite/exception_handling/pal_except/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/exception_handling/pal_except/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_pal_except_test5
diff --git a/src/pal/tests/palsuite/exception_handling/pal_except/test5/test5.c b/src/pal/tests/palsuite/exception_handling/pal_except/test5/test5.cpp
index f9faf4440e..f9faf4440e 100644
--- a/src/pal/tests/palsuite/exception_handling/pal_except/test5/test5.c
+++ b/src/pal/tests/palsuite/exception_handling/pal_except/test5/test5.cpp
diff --git a/src/pal/tests/palsuite/exception_handling/pal_except/test6/CMakeLists.txt b/src/pal/tests/palsuite/exception_handling/pal_except/test6/CMakeLists.txt
index 7f943bf126..d009128871 100644
--- a/src/pal/tests/palsuite/exception_handling/pal_except/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/exception_handling/pal_except/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test6.c
+ test6.cpp
)
add_executable(paltest_pal_except_test6
diff --git a/src/pal/tests/palsuite/exception_handling/pal_except/test6/test6.c b/src/pal/tests/palsuite/exception_handling/pal_except/test6/test6.cpp
index 44b0ba1bc9..44b0ba1bc9 100644
--- a/src/pal/tests/palsuite/exception_handling/pal_except/test6/test6.c
+++ b/src/pal/tests/palsuite/exception_handling/pal_except/test6/test6.cpp
diff --git a/src/pal/tests/palsuite/exception_handling/pal_except/test7/CMakeLists.txt b/src/pal/tests/palsuite/exception_handling/pal_except/test7/CMakeLists.txt
index 09399c8f6b..33fee62cc2 100644
--- a/src/pal/tests/palsuite/exception_handling/pal_except/test7/CMakeLists.txt
+++ b/src/pal/tests/palsuite/exception_handling/pal_except/test7/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test7.c
+ test7.cpp
)
add_executable(paltest_pal_except_test7
diff --git a/src/pal/tests/palsuite/exception_handling/pal_except/test7/test7.c b/src/pal/tests/palsuite/exception_handling/pal_except/test7/test7.cpp
index a8dc8331c2..a8dc8331c2 100644
--- a/src/pal/tests/palsuite/exception_handling/pal_except/test7/test7.c
+++ b/src/pal/tests/palsuite/exception_handling/pal_except/test7/test7.cpp
diff --git a/src/pal/tests/palsuite/exception_handling/pal_finally/test1/CMakeLists.txt b/src/pal/tests/palsuite/exception_handling/pal_finally/test1/CMakeLists.txt
index 5d947ad7db..67cc6c0b92 100644
--- a/src/pal/tests/palsuite/exception_handling/pal_finally/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/exception_handling/pal_finally/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- pal_finally.c
+ pal_finally.cpp
)
add_executable(paltest_pal_finally_test1
diff --git a/src/pal/tests/palsuite/exception_handling/pal_finally/test1/pal_finally.c b/src/pal/tests/palsuite/exception_handling/pal_finally/test1/pal_finally.cpp
index f278f98956..f278f98956 100644
--- a/src/pal/tests/palsuite/exception_handling/pal_finally/test1/pal_finally.c
+++ b/src/pal/tests/palsuite/exception_handling/pal_finally/test1/pal_finally.cpp
diff --git a/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest1.cpp b/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest1.cpp
index 614690897a..000ed6271c 100644
--- a/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest1.cpp
+++ b/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest1.cpp
@@ -20,6 +20,17 @@ int InitializeDllTest1()
return PAL_InitializeDLL();
}
+__attribute__((noinline,optnone))
+static void FailingFunction(volatile int *p)
+{
+ if (p == NULL)
+ {
+ throw PAL_SEHException();
+ }
+
+ *p = 1; // Causes an access violation exception
+}
+
BOOL bTry = FALSE;
BOOL bExcept = FALSE;
@@ -33,7 +44,8 @@ int DllTest1()
volatile int* p = (volatile int *)0x11; // Invalid pointer
bTry = TRUE; // Indicate we hit the PAL_TRY block
- *p = 1; // Causes an access violation exception
+ FailingFunction(p); // Throw in function to fool C++ runtime into handling
+ // h/w exception
Fail("ERROR: code was executed after the access violation.\n");
}
diff --git a/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest2.cpp b/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest2.cpp
index 1e85821422..27fc213e4f 100644
--- a/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest2.cpp
+++ b/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest2.cpp
@@ -20,6 +20,17 @@ int InitializeDllTest2()
return PAL_InitializeDLL();
}
+__attribute__((noinline,optnone))
+static void FailingFunction(volatile int *p)
+{
+ if (p == NULL)
+ {
+ throw PAL_SEHException();
+ }
+
+ *p = 1; // Causes an access violation exception
+}
+
BOOL bTry = FALSE;
BOOL bExcept = FALSE;
@@ -33,7 +44,8 @@ int DllTest2()
volatile int* p = (volatile int *)0x22; // Invalid pointer
bTry = TRUE; // Indicate we hit the PAL_TRY block
- *p = 2; // Causes an access violation exception
+ FailingFunction(p); // Throw in function to fool C++ runtime into handling
+ // h/w exception
Fail("ERROR: code was executed after the access violation.\n");
}
diff --git a/src/pal/tests/palsuite/file_io/AreFileApisANSI/test1/AreFileApisANSI.c b/src/pal/tests/palsuite/file_io/AreFileApisANSI/test1/AreFileApisANSI.cpp
index ec61f0cb7d..ec61f0cb7d 100644
--- a/src/pal/tests/palsuite/file_io/AreFileApisANSI/test1/AreFileApisANSI.c
+++ b/src/pal/tests/palsuite/file_io/AreFileApisANSI/test1/AreFileApisANSI.cpp
diff --git a/src/pal/tests/palsuite/file_io/AreFileApisANSI/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/AreFileApisANSI/test1/CMakeLists.txt
index 4f50127cb9..e624bef462 100644
--- a/src/pal/tests/palsuite/file_io/AreFileApisANSI/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/AreFileApisANSI/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- AreFileApisANSI.c
+ AreFileApisANSI.cpp
)
add_executable(paltest_arefileapisansi_test1
diff --git a/src/pal/tests/palsuite/file_io/CompareFileTime/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CompareFileTime/test1/CMakeLists.txt
index fdcb6559b3..fa96a44cdd 100644
--- a/src/pal/tests/palsuite/file_io/CompareFileTime/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/CompareFileTime/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CompareFileTime.c
+ CompareFileTime.cpp
)
add_executable(paltest_comparefiletime_test1
diff --git a/src/pal/tests/palsuite/file_io/CompareFileTime/test1/CompareFileTime.c b/src/pal/tests/palsuite/file_io/CompareFileTime/test1/CompareFileTime.cpp
index 3758f7e4eb..3758f7e4eb 100644
--- a/src/pal/tests/palsuite/file_io/CompareFileTime/test1/CompareFileTime.c
+++ b/src/pal/tests/palsuite/file_io/CompareFileTime/test1/CompareFileTime.cpp
diff --git a/src/pal/tests/palsuite/file_io/CopyFileA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CopyFileA/test1/CMakeLists.txt
index b52e5076fa..13abbc0979 100644
--- a/src/pal/tests/palsuite/file_io/CopyFileA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/CopyFileA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CopyFileA.c
+ CopyFileA.cpp
)
add_executable(paltest_copyfilea_test1
diff --git a/src/pal/tests/palsuite/file_io/CopyFileA/test1/CopyFileA.c b/src/pal/tests/palsuite/file_io/CopyFileA/test1/CopyFileA.cpp
index bfea85b7cb..bfea85b7cb 100644
--- a/src/pal/tests/palsuite/file_io/CopyFileA/test1/CopyFileA.c
+++ b/src/pal/tests/palsuite/file_io/CopyFileA/test1/CopyFileA.cpp
diff --git a/src/pal/tests/palsuite/file_io/CopyFileA/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CopyFileA/test2/CMakeLists.txt
index 7454f32f51..cd0d8bc6cf 100644
--- a/src/pal/tests/palsuite/file_io/CopyFileA/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/CopyFileA/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_copyfilea_test2
diff --git a/src/pal/tests/palsuite/file_io/CopyFileA/test2/test2.c b/src/pal/tests/palsuite/file_io/CopyFileA/test2/test2.cpp
index 56618d0a58..56618d0a58 100644
--- a/src/pal/tests/palsuite/file_io/CopyFileA/test2/test2.c
+++ b/src/pal/tests/palsuite/file_io/CopyFileA/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/file_io/CopyFileA/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CopyFileA/test3/CMakeLists.txt
index 986be9fd22..0bb41b8d8f 100644
--- a/src/pal/tests/palsuite/file_io/CopyFileA/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/CopyFileA/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_copyfilea_test3
diff --git a/src/pal/tests/palsuite/file_io/CopyFileA/test3/test3.c b/src/pal/tests/palsuite/file_io/CopyFileA/test3/test3.cpp
index 18c8ce80dc..18c8ce80dc 100644
--- a/src/pal/tests/palsuite/file_io/CopyFileA/test3/test3.c
+++ b/src/pal/tests/palsuite/file_io/CopyFileA/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/file_io/CopyFileA/test4/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CopyFileA/test4/CMakeLists.txt
index fb48c83741..12f85d1747 100644
--- a/src/pal/tests/palsuite/file_io/CopyFileA/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/CopyFileA/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_copyfilea_test4
diff --git a/src/pal/tests/palsuite/file_io/CopyFileA/test4/test4.c b/src/pal/tests/palsuite/file_io/CopyFileA/test4/test4.cpp
index 1ae69f5e1f..1ae69f5e1f 100644
--- a/src/pal/tests/palsuite/file_io/CopyFileA/test4/test4.c
+++ b/src/pal/tests/palsuite/file_io/CopyFileA/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/file_io/CopyFileW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CopyFileW/test1/CMakeLists.txt
index 766b120035..20c8141d90 100644
--- a/src/pal/tests/palsuite/file_io/CopyFileW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/CopyFileW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CopyFileW.c
+ CopyFileW.cpp
)
add_executable(paltest_copyfilew_test1
diff --git a/src/pal/tests/palsuite/file_io/CopyFileW/test1/CopyFileW.c b/src/pal/tests/palsuite/file_io/CopyFileW/test1/CopyFileW.cpp
index 6127cc21bd..6127cc21bd 100644
--- a/src/pal/tests/palsuite/file_io/CopyFileW/test1/CopyFileW.c
+++ b/src/pal/tests/palsuite/file_io/CopyFileW/test1/CopyFileW.cpp
diff --git a/src/pal/tests/palsuite/file_io/CopyFileW/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CopyFileW/test2/CMakeLists.txt
index 5c0030bc8d..4201bdca88 100644
--- a/src/pal/tests/palsuite/file_io/CopyFileW/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/CopyFileW/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_copyfilew_test2
diff --git a/src/pal/tests/palsuite/file_io/CopyFileW/test2/test2.c b/src/pal/tests/palsuite/file_io/CopyFileW/test2/test2.cpp
index 5380a181ca..5380a181ca 100644
--- a/src/pal/tests/palsuite/file_io/CopyFileW/test2/test2.c
+++ b/src/pal/tests/palsuite/file_io/CopyFileW/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/file_io/CopyFileW/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CopyFileW/test3/CMakeLists.txt
index 52d9aad1c0..d0fd94c990 100644
--- a/src/pal/tests/palsuite/file_io/CopyFileW/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/CopyFileW/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_copyfilew_test3
diff --git a/src/pal/tests/palsuite/file_io/CopyFileW/test3/test3.c b/src/pal/tests/palsuite/file_io/CopyFileW/test3/test3.cpp
index a2eb04c443..a2eb04c443 100644
--- a/src/pal/tests/palsuite/file_io/CopyFileW/test3/test3.c
+++ b/src/pal/tests/palsuite/file_io/CopyFileW/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/file_io/CreateDirectoryA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CreateDirectoryA/test1/CMakeLists.txt
index f8cdf19933..1dc87fa34b 100644
--- a/src/pal/tests/palsuite/file_io/CreateDirectoryA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/CreateDirectoryA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CreateDirectoryA.c
+ CreateDirectoryA.cpp
)
add_executable(paltest_createdirectorya_test1
diff --git a/src/pal/tests/palsuite/file_io/CreateDirectoryA/test1/CreateDirectoryA.c b/src/pal/tests/palsuite/file_io/CreateDirectoryA/test1/CreateDirectoryA.c
deleted file mode 100644
index 2bb441e732..0000000000
--- a/src/pal/tests/palsuite/file_io/CreateDirectoryA/test1/CreateDirectoryA.c
+++ /dev/null
@@ -1,296 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: CreateDirectoryA.c
-**
-** Purpose: Tests the PAL implementation of the CreateDirectoryA function.
-**
-** Depends on:
-** RemoveDirectoryW (since RemoveDirectoryA is unavailable)
-** GetCurrentDirectoryA
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-
-
-/* apparently, under WIN32 the max path size is 248 but under
- BSD it is _MAX_PATH */
-#if WIN32
-#define CREATE_MAX_PATH_SIZE 248
-#else
-#define CREATE_MAX_PATH_SIZE _MAX_PATH
-#endif
-
-
-int __cdecl main(int argc, char *argv[])
-{
- const char* szTestDir = {"test_directory"};
- const char* szDotDir = {".dotDirectory"};
- BOOL bRc = FALSE;
- BOOL bSuccess = FALSE;
- const int buf_size = CREATE_MAX_PATH_SIZE + 10;
- char szDirName[CREATE_MAX_PATH_SIZE + 10];
- char buffer[CREATE_MAX_PATH_SIZE + 10];
- WCHAR* pTemp = NULL;
- DWORD curDirLen;
- DWORD curDirectory = 1024;
-
- if (0 != PAL_Initialize(argc,argv))
- {
- return FAIL;
- }
-
-
- /* directory does not exist */
- bRc = CreateDirectoryA(szTestDir, NULL);
- if (bRc == FALSE)
- {
- Fail("CreateDirectoryA: Failed to create \"%s\" with error code %ld\n",
- szTestDir,
- GetLastError());
- }
-
-
- /* directory exists should fail */
- bRc = CreateDirectoryA(szTestDir, NULL);
- if (bRc == TRUE)
- {
- pTemp = convert((LPSTR)szTestDir);
- bRc = RemoveDirectoryW(pTemp);
- free(pTemp);
- if (!bRc)
- {
- Trace("CreateDirectoryA: RemoveDirectoryW failed to remove "
- "\"%s\" with the error code %ld.\n",
- szTestDir,
- GetLastError());
- }
- Fail("CreateDirectoryA: Succeeded creating the directory"
- "\"%s\" when it exists already.\n",
- szTestDir);
- }
- else
- {
- pTemp = convert((LPSTR)szTestDir);
- bRc = RemoveDirectoryW(pTemp);
- free(pTemp);
- if (!bRc)
- {
- Fail("CreateDirectoryA: RemoveDirectoryW failed to remove "
- "\"%s\" with the error code %ld.\n",
- szTestDir,
- GetLastError());
- }
- }
-
-
- /* long directory names (CREATE_MAX_PATH_SIZE - 1, CREATE_MAX_PATH_SIZE
- and CREATE_MAX_PATH_SIZE + 1 characters
- including terminating null char) */
-
- curDirLen = GetCurrentDirectoryA(0, NULL);
-
- memset(szDirName, 0, buf_size);
- memset(szDirName, 'a', CREATE_MAX_PATH_SIZE - 2 - curDirLen);
- bRc = CreateDirectoryA(szDirName, NULL);
- if (bRc == FALSE)
- {
- Fail("CreateDirectoryA: Failed to create a directory"
- " name %d chars long with the error code %ld\n",
- strlen(szDirName),
- GetLastError());
- }
- else
- {
- /* Check to see if it's possible to navigate to directory */
- GetCurrentDirectoryA(curDirectory, buffer);
- bSuccess = SetCurrentDirectoryA(szDirName);
- if(!bSuccess)
- {
- Fail("CreateDirectoryA: SetCurrentDirectoryA failed to "
- "navigate to the newly created directory with error "
- "code %u.\n", GetLastError());
- }
-
- /* Set directory back to initial directory */
- SetCurrentDirectoryA(buffer);
-
- pTemp = convert((LPSTR)szDirName);
- bRc = RemoveDirectoryW(pTemp);
- free(pTemp);
- if (!bRc)
- {
- Fail("CreateDirectoryA: RemoveDirectoryW failed to remove "
- "\"%s\" with the error code %ld.\n",
- szDirName,
- GetLastError());
- }
- }
-
-
- memset(szDirName, 0, buf_size);
- memset(szDirName, 'a', CREATE_MAX_PATH_SIZE - 1 - curDirLen);
- bRc = CreateDirectoryA(szDirName, NULL);
- if (bRc == FALSE)
- {
- Fail("CreateDirectoryA: Failed to create a directory"
- " name %d chars long with error code %ld\n",
- strlen(szDirName),
- GetLastError());
- }
- else
- {
- /* Check to see if it's possible to navigate to directory */
- GetCurrentDirectoryA(curDirectory, buffer);
- bSuccess = SetCurrentDirectoryA(szDirName);
- if(!bSuccess)
- {
- Fail("CreateDirectoryA: SetCurrentDirectoryA failed to "
- "navigate to the newly created directory with error "
- "code %u.\n", GetLastError());
- }
-
- /* Set Directroy back to initial directory */
- SetCurrentDirectoryA(buffer);
-
- pTemp = convert(szDirName);
- bRc = RemoveDirectoryW(pTemp);
- free(pTemp);
- if (!bRc)
- {
- Fail("CreateDirectoryA: RemoveDirectoryW failed to remove "
- "\"%s\" with the error code %ld.\n",
- szDirName,
- GetLastError());
- }
- }
-
- memset(szDirName, 0, buf_size);
- memset(szDirName, 'a', CREATE_MAX_PATH_SIZE - curDirLen);
- bRc = CreateDirectoryA(szDirName, NULL);
- if (bRc != FALSE)
- {
- /* Check to see if it's possible to navigate to directory */
- GetCurrentDirectoryA(curDirectory, buffer);
- bSuccess = SetCurrentDirectoryA(szDirName);
- if(!bSuccess)
- {
- Fail("CreateDirectoryA: SetCurrentDirectoryA failed to "
- "navigate to the newly created directory with error "
- "code %u.\n", GetLastError());
- }
-
- /* set directory back to initial directory */
- SetCurrentDirectoryA(buffer);
-
- pTemp = convert(szDirName);
- bRc = RemoveDirectoryW(pTemp);
- free(pTemp);
- if (!bRc)
- {
- Trace("CreateDirectoryA: RemoveDirectoryW failed to remove "
- "\"%s\" with the error code %ld.\n",
- szDirName,
- GetLastError());
- }
- if (strlen(szDirName) > CREATE_MAX_PATH_SIZE)
- {
- Fail("CreateDirectoryA: Failed because it created a directory"
- " name 1 character longer (%d chars) than the max dir size "
- "allowed\n",
- strlen(szDirName));
- }
- }
-
-
- /* long directory name CREATE_MAX_PATH_SIZE + 3 chars including "..\"
- (real path length <= CREATE_MAX_PATH_SIZE) */
- memset(szDirName, 0, buf_size);
- memset(szDirName, 'a', CREATE_MAX_PATH_SIZE + 3 - 1 - curDirLen);
- szDirName[0] = '.';
- szDirName[1] = '.';
- szDirName[2] = '\\';
- bRc = CreateDirectoryA(szDirName, NULL);
- if (bRc == FALSE)
- {
- Fail("CreateDirectoryA: Failed to create a directory name more "
- "than %d chars long and its real path name is less "
- "than %d chars, error %u\n",
- CREATE_MAX_PATH_SIZE,
- CREATE_MAX_PATH_SIZE, GetLastError());
- }
- else
- {
- /* Check to see if it's possible to navigate to directory */
- GetCurrentDirectoryA(curDirectory, buffer);
- bSuccess = SetCurrentDirectoryA(szDirName);
- if(!bSuccess)
- {
- Fail("CreateDirectoryA: SetCurrentDirectoryA failed to "
- "navigate to the newly created directory with error "
- "code %u.\n", GetLastError());
- }
-
- /* set directory back to initial directory */
- SetCurrentDirectoryA(buffer);
-
- pTemp = convert(szDirName);
- bRc = RemoveDirectoryW(pTemp);
- free(pTemp);
- if (!bRc)
- {
- Fail("CreateDirectoryA: RemoveDirectoryW failed to remove "
- " \"%s\" with the error code %ld.\n",
- szDirName,
- GetLastError());
- }
- }
-
-
- /* directories with dots */
- memset(szDirName, 0, buf_size);
- sprintf(szDirName, szDotDir);
- bRc = CreateDirectoryA(szDirName, NULL);
- if (bRc == FALSE)
- {
- Fail("CreateDirectoryA: Failed to create \"%s\" with error code %ld\n",
- szDotDir,
- GetLastError());
- }
- else
- {
-
- /* Check to see if it's possible to navigate to directory */
- GetCurrentDirectoryA(curDirectory, buffer);
- bSuccess = SetCurrentDirectoryA(szDirName);
- if(!bSuccess)
- {
- Fail("CreateDirectoryA: SetCurrentDirectoryA failed to "
- "navigate to the newly created directory with error "
- "code %u.\n", GetLastError());
- }
-
- /* set directory back to initial directory */
- SetCurrentDirectoryA(buffer);
-
- pTemp = convert((LPSTR)szDotDir);
- bRc = RemoveDirectoryW(pTemp);
- free(pTemp);
- if (!bRc)
- {
- Fail("CreateDirectoryA: RemoveDirectoryW failed to remove "
- " \"%s\" with the error code %ld.\n",
- szDotDir,
- GetLastError());
- }
- }
-
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/file_io/CreateDirectoryA/test1/CreateDirectoryA.cpp b/src/pal/tests/palsuite/file_io/CreateDirectoryA/test1/CreateDirectoryA.cpp
new file mode 100644
index 0000000000..4082d38b36
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateDirectoryA/test1/CreateDirectoryA.cpp
@@ -0,0 +1,296 @@
+// Licensed to the .NET Foundation under one or more 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: CreateDirectoryA.c
+**
+** Purpose: Tests the PAL implementation of the CreateDirectoryA function.
+**
+** Depends on:
+** RemoveDirectoryW (since RemoveDirectoryA is unavailable)
+** GetCurrentDirectoryA
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+/* apparently, under WIN32 the max path size is 248 but under
+ BSD it is _MAX_PATH */
+#if WIN32
+#define CREATE_MAX_PATH_SIZE 248
+#else
+#define CREATE_MAX_PATH_SIZE _MAX_PATH
+#endif
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ const char* szTestDir = {"test_directory"};
+ const char* szDotDir = {".dotDirectory"};
+ BOOL bRc = FALSE;
+ BOOL bSuccess = FALSE;
+ const int buf_size = CREATE_MAX_PATH_SIZE + 10;
+ char szDirName[CREATE_MAX_PATH_SIZE + 10];
+ char buffer[CREATE_MAX_PATH_SIZE + 10];
+ WCHAR* pTemp = NULL;
+ DWORD curDirLen;
+ DWORD curDirectory = 1024;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+
+ /* directory does not exist */
+ bRc = CreateDirectoryA(szTestDir, NULL);
+ if (bRc == FALSE)
+ {
+ Fail("CreateDirectoryA: Failed to create \"%s\" with error code %ld\n",
+ szTestDir,
+ GetLastError());
+ }
+
+
+ /* directory exists should fail */
+ bRc = CreateDirectoryA(szTestDir, NULL);
+ if (bRc == TRUE)
+ {
+ pTemp = convert((LPSTR)szTestDir);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+ if (!bRc)
+ {
+ Trace("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ "\"%s\" with the error code %ld.\n",
+ szTestDir,
+ GetLastError());
+ }
+ Fail("CreateDirectoryA: Succeeded creating the directory"
+ "\"%s\" when it exists already.\n",
+ szTestDir);
+ }
+ else
+ {
+ pTemp = convert((LPSTR)szTestDir);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+ if (!bRc)
+ {
+ Fail("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ "\"%s\" with the error code %ld.\n",
+ szTestDir,
+ GetLastError());
+ }
+ }
+
+
+ /* long directory names (CREATE_MAX_PATH_SIZE - 1, CREATE_MAX_PATH_SIZE
+ and CREATE_MAX_PATH_SIZE + 1 characters
+ including terminating null char) */
+
+ curDirLen = GetCurrentDirectoryA(0, NULL);
+
+ memset(szDirName, 0, buf_size);
+ memset(szDirName, 'a', CREATE_MAX_PATH_SIZE - 2 - curDirLen);
+ bRc = CreateDirectoryA(szDirName, NULL);
+ if (bRc == FALSE)
+ {
+ Fail("CreateDirectoryA: Failed to create a directory"
+ " name %d chars long with the error code %ld\n",
+ strlen(szDirName),
+ GetLastError());
+ }
+ else
+ {
+ /* Check to see if it's possible to navigate to directory */
+ GetCurrentDirectoryA(curDirectory, buffer);
+ bSuccess = SetCurrentDirectoryA(szDirName);
+ if(!bSuccess)
+ {
+ Fail("CreateDirectoryA: SetCurrentDirectoryA failed to "
+ "navigate to the newly created directory with error "
+ "code %u.\n", GetLastError());
+ }
+
+ /* Set directory back to initial directory */
+ SetCurrentDirectoryA(buffer);
+
+ pTemp = convert((LPSTR)szDirName);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+ if (!bRc)
+ {
+ Fail("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ "\"%s\" with the error code %ld.\n",
+ szDirName,
+ GetLastError());
+ }
+ }
+
+
+ memset(szDirName, 0, buf_size);
+ memset(szDirName, 'a', CREATE_MAX_PATH_SIZE - 1 - curDirLen);
+ bRc = CreateDirectoryA(szDirName, NULL);
+ if (bRc == FALSE)
+ {
+ Fail("CreateDirectoryA: Failed to create a directory"
+ " name %d chars long with error code %ld\n",
+ strlen(szDirName),
+ GetLastError());
+ }
+ else
+ {
+ /* Check to see if it's possible to navigate to directory */
+ GetCurrentDirectoryA(curDirectory, buffer);
+ bSuccess = SetCurrentDirectoryA(szDirName);
+ if(!bSuccess)
+ {
+ Fail("CreateDirectoryA: SetCurrentDirectoryA failed to "
+ "navigate to the newly created directory with error "
+ "code %u.\n", GetLastError());
+ }
+
+ /* Set Directroy back to initial directory */
+ SetCurrentDirectoryA(buffer);
+
+ pTemp = convert(szDirName);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+ if (!bRc)
+ {
+ Fail("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ "\"%s\" with the error code %ld.\n",
+ szDirName,
+ GetLastError());
+ }
+ }
+
+ memset(szDirName, 0, buf_size);
+ memset(szDirName, 'a', CREATE_MAX_PATH_SIZE - curDirLen);
+ bRc = CreateDirectoryA(szDirName, NULL);
+ if (bRc != FALSE)
+ {
+ /* Check to see if it's possible to navigate to directory */
+ GetCurrentDirectoryA(curDirectory, buffer);
+ bSuccess = SetCurrentDirectoryA(szDirName);
+ if(!bSuccess)
+ {
+ Fail("CreateDirectoryA: SetCurrentDirectoryA failed to "
+ "navigate to the newly created directory with error "
+ "code %u.\n", GetLastError());
+ }
+
+ /* set directory back to initial directory */
+ SetCurrentDirectoryA(buffer);
+
+ pTemp = convert(szDirName);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+ if (!bRc)
+ {
+ Trace("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ "\"%s\" with the error code %ld.\n",
+ szDirName,
+ GetLastError());
+ }
+ if (strlen(szDirName) > CREATE_MAX_PATH_SIZE)
+ {
+ Fail("CreateDirectoryA: Failed because it created a directory"
+ " name 1 character longer (%d chars) than the max dir size "
+ "allowed\n",
+ strlen(szDirName));
+ }
+ }
+
+
+ /* long directory name CREATE_MAX_PATH_SIZE + 3 chars including "..\"
+ (real path length <= CREATE_MAX_PATH_SIZE) */
+ memset(szDirName, 0, buf_size);
+ memset(szDirName, 'a', CREATE_MAX_PATH_SIZE + 3 - 1 - curDirLen);
+ szDirName[0] = '.';
+ szDirName[1] = '.';
+ szDirName[2] = '\\';
+ bRc = CreateDirectoryA(szDirName, NULL);
+ if (bRc == FALSE)
+ {
+ Fail("CreateDirectoryA: Failed to create a directory name more "
+ "than %d chars long and its real path name is less "
+ "than %d chars, error %u\n",
+ CREATE_MAX_PATH_SIZE,
+ CREATE_MAX_PATH_SIZE, GetLastError());
+ }
+ else
+ {
+ /* Check to see if it's possible to navigate to directory */
+ GetCurrentDirectoryA(curDirectory, buffer);
+ bSuccess = SetCurrentDirectoryA(szDirName);
+ if(!bSuccess)
+ {
+ Fail("CreateDirectoryA: SetCurrentDirectoryA failed to "
+ "navigate to the newly created directory with error "
+ "code %u.\n", GetLastError());
+ }
+
+ /* set directory back to initial directory */
+ SetCurrentDirectoryA(buffer);
+
+ pTemp = convert(szDirName);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+ if (!bRc)
+ {
+ Fail("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ " \"%s\" with the error code %ld.\n",
+ szDirName,
+ GetLastError());
+ }
+ }
+
+
+ /* directories with dots */
+ memset(szDirName, 0, buf_size);
+ sprintf_s(szDirName, _countof(szDirName), szDotDir);
+ bRc = CreateDirectoryA(szDirName, NULL);
+ if (bRc == FALSE)
+ {
+ Fail("CreateDirectoryA: Failed to create \"%s\" with error code %ld\n",
+ szDotDir,
+ GetLastError());
+ }
+ else
+ {
+
+ /* Check to see if it's possible to navigate to directory */
+ GetCurrentDirectoryA(curDirectory, buffer);
+ bSuccess = SetCurrentDirectoryA(szDirName);
+ if(!bSuccess)
+ {
+ Fail("CreateDirectoryA: SetCurrentDirectoryA failed to "
+ "navigate to the newly created directory with error "
+ "code %u.\n", GetLastError());
+ }
+
+ /* set directory back to initial directory */
+ SetCurrentDirectoryA(buffer);
+
+ pTemp = convert((LPSTR)szDotDir);
+ bRc = RemoveDirectoryW(pTemp);
+ free(pTemp);
+ if (!bRc)
+ {
+ Fail("CreateDirectoryA: RemoveDirectoryW failed to remove "
+ " \"%s\" with the error code %ld.\n",
+ szDotDir,
+ GetLastError());
+ }
+ }
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/CreateDirectoryA/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CreateDirectoryA/test2/CMakeLists.txt
index a50a986d1a..3ee8abbcc2 100644
--- a/src/pal/tests/palsuite/file_io/CreateDirectoryA/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/CreateDirectoryA/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- createdirectorya.c
+ createdirectorya.cpp
)
add_executable(paltest_createdirectorya_test2
diff --git a/src/pal/tests/palsuite/file_io/CreateDirectoryA/test2/createdirectorya.c b/src/pal/tests/palsuite/file_io/CreateDirectoryA/test2/createdirectorya.cpp
index fc1bc967b7..fc1bc967b7 100644
--- a/src/pal/tests/palsuite/file_io/CreateDirectoryA/test2/createdirectorya.c
+++ b/src/pal/tests/palsuite/file_io/CreateDirectoryA/test2/createdirectorya.cpp
diff --git a/src/pal/tests/palsuite/file_io/CreateDirectoryW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CreateDirectoryW/test1/CMakeLists.txt
index 1981e37082..f8cb584cc6 100644
--- a/src/pal/tests/palsuite/file_io/CreateDirectoryW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/CreateDirectoryW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CreateDirectoryW.c
+ CreateDirectoryW.cpp
)
add_executable(paltest_createdirectoryw_test1
diff --git a/src/pal/tests/palsuite/file_io/CreateDirectoryW/test1/CreateDirectoryW.c b/src/pal/tests/palsuite/file_io/CreateDirectoryW/test1/CreateDirectoryW.c
deleted file mode 100644
index 9b020cc19c..0000000000
--- a/src/pal/tests/palsuite/file_io/CreateDirectoryW/test1/CreateDirectoryW.c
+++ /dev/null
@@ -1,347 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: CreateDirectoryW.c
-**
-** Purpose: Tests the PAL implementation of the CreateDirectoryW function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-
-
-/* apparently, under WIN32 the max path size is 248 but under
- BSD it is _MAX_PATH */
-#if WIN32
-#define CREATE_MAX_PATH_SIZE 248
-#else
-#define CREATE_MAX_PATH_SIZE _MAX_PATH
-#endif
-
-
-int __cdecl main(int argc, char *argv[])
-{
- BOOL bRc = FALSE;
- BOOL bSuccess = FALSE;
- const int buf_size = CREATE_MAX_PATH_SIZE + 10;
- char szDirName[CREATE_MAX_PATH_SIZE + 10];
- char buffer[CREATE_MAX_PATH_SIZE + 10];
- WCHAR* pTemp = NULL;
- DWORD curDirLen;
- DWORD curDirectory = 1024;
-
-
-
- if (0 != PAL_Initialize(argc,argv))
- {
- return FAIL;
- }
-
- /* directory does not exist */
- pTemp = convert("test_directory");
- bRc = CreateDirectoryW(pTemp, NULL);
- free(pTemp);
- if (bRc == FALSE)
- {
- Fail("CreateDirectoryW: Failed to create \"test_directory\"\n");
- }
-
- /* directory exists */
- pTemp = convert("test_directory");
- bRc = CreateDirectoryW(pTemp, NULL);
- if (bRc == TRUE)
- {
- bRc = RemoveDirectoryW(pTemp);
- if(!bRc)
- {
- free(pTemp);
- Fail("CreateDirectoryW: RemoveDirectoryW failed to "
- "delete the directory with error %u.\n",
- GetLastError());
- }
- free(pTemp);
- Fail("CreateDirectoryW: Succeeded creating the directory"
- " \"test_directory\" when it exists already.\n");
- }
-
- bRc = RemoveDirectoryW(pTemp);
- if(!bRc)
- {
- free(pTemp);
- Fail("CreateDirectoryW: RemoveDirectoryW failed to "
- "delete the directory with error %u.\n",
- GetLastError());
- }
- free(pTemp);
-
- /* long directory names (CREATE_MAX_PATH_SIZE - 1, CREATE_MAX_PATH_SIZE
- and CREATE_MAX_PATH_SIZE + 1 characters
- including terminating null char) */
-
- curDirLen = GetCurrentDirectoryA(0, NULL);
-
- memset(szDirName, 0, buf_size);
- memset(szDirName, 'a', CREATE_MAX_PATH_SIZE - 2 - curDirLen);
- pTemp = convert((LPSTR)szDirName);
- bRc = CreateDirectoryW(pTemp, NULL);
- if (bRc == FALSE)
- {
- free(pTemp);
- Fail("CreateDirectoryW: Failed to create a directory"
- " name (%d) chars long with the error code %ld\n",
- CREATE_MAX_PATH_SIZE - 1,
- GetLastError());
- }
- else
- {
-
- /* Check to see if it's possible to navigate to directory */
- GetCurrentDirectoryA(curDirectory, buffer);
- bSuccess = SetCurrentDirectoryA(szDirName);
- if(!bSuccess)
- {
- Trace("CreateDirectoryW: SetCurrentDirectoryA failed to "
- "navigate to the newly created directory with error "
- "code %u.\n", GetLastError());
- bRc = RemoveDirectoryW(pTemp);
- if(!bRc)
- {
- free(pTemp);
- Fail("CreateDirectoryW: RemoveDirectoryW failed to "
- "delete the directory with error %u.\n",
- GetLastError());
- }
- free(pTemp);
- Fail("");
-
- }
-
- /* Set directory back to initial directory */
- bRc = SetCurrentDirectoryA(buffer);
- if(!bRc)
- {
- free(pTemp);
- Fail("CreateDirectoryW: SetCurrentDirectoryA failed to "
- "change the directory with error %u.\n",
- GetLastError());
- }
-
- bRc = RemoveDirectoryW(pTemp);
- if(!bRc)
- {
- free(pTemp);
- Fail("CreateDirectoryW: RemoveDirectoryW failed to "
- "delete the directory with error %u.\n",
- GetLastError());
- }
- free(pTemp);
- }
-
-
- memset(szDirName, 0, buf_size);
- memset(szDirName, 'a', CREATE_MAX_PATH_SIZE - 1 - curDirLen);
- pTemp = convert(szDirName);
- bRc = CreateDirectoryW(pTemp, NULL);
- if (bRc == FALSE)
- {
- free(pTemp);
- Fail("CreateDirectoryW: Failed to create a directory"
- " name %d chars long with error code %ld\n",
- strlen(szDirName),
- GetLastError());
- }
- else
- {
- /* Check to see if it's possible to navigate to directory */
- GetCurrentDirectoryA(curDirectory, buffer);
- bSuccess = SetCurrentDirectoryA(szDirName);
- if(!bSuccess)
- {
- Trace("CreateDirectoryW: SetCurrentDirectoryA failed to "
- "navigate to the newly created directory with error "
- "code %u.\n", GetLastError());
-
- bRc = RemoveDirectoryW(pTemp);
- if(!bRc)
- {
- free(pTemp);
- Fail("CreateDirectoryW: RemoveDirectoryW failed to "
- "delete the directory with error %u.\n",
- GetLastError());
- }
- free(pTemp);
- Fail("");
- }
-
- /* Set directory back to initial directory */
- bRc = SetCurrentDirectoryA(buffer);
- if(!bRc)
- {
- free(pTemp);
- Fail("CreateDirectoryW: SetCurrentDirectoryA failed to "
- "change the directory with error %u.\n",
- GetLastError());
- }
-
-
- bRc = RemoveDirectoryW(pTemp);
- if(!bRc)
- {
- free(pTemp);
- Fail("CreateDirectoryW: RemoveDirectoryW failed to "
- "delete the directory with error %u.\n",
- GetLastError());
- }
- free(pTemp);
- }
-
- memset(szDirName, 0, buf_size);
- memset(szDirName, 'a', CREATE_MAX_PATH_SIZE - curDirLen);
- pTemp = convert(szDirName);
- bRc = CreateDirectoryW(pTemp, NULL);
-
- if (bRc != FALSE)
- {
- RemoveDirectoryW(pTemp);
- if(!bRc)
- {
- free(pTemp);
- Fail("CreateDirectoryW: RemoveDirectoryW failed to "
- "delete the directory with error %u.\n",
- GetLastError());
- }
- if (strlen(szDirName) > CREATE_MAX_PATH_SIZE)
- {
- free(pTemp);
- Fail("CreateDirectoryW: Failed because it created a directory"
- " name 1 character longer (%d chars) than the max dir size"
- " allowed\n",
- strlen(szDirName));
- }
- }
-
- free(pTemp);
-
- /* long directory name CREATE_MAX_PATH_SIZE + 3 chars including "..\"
- (real path length <= CREATE_MAX_PATH_SIZE) */
- memset(szDirName, 0, buf_size);
- memset(szDirName, 'a', CREATE_MAX_PATH_SIZE + 3 - 1 - curDirLen);
- szDirName[0] = '.';
- szDirName[1] = '.';
- szDirName[2] = '\\';
- pTemp = convert(szDirName);
- bRc = CreateDirectoryW(pTemp, NULL);
- if (bRc == FALSE)
- {
- free(pTemp);
- Fail("CreateDirectoryW: Failed to create a directory name more "
- "than %d chars long and its real path name is less "
- "than %d chars\n",
- CREATE_MAX_PATH_SIZE,
- CREATE_MAX_PATH_SIZE);
- }
- else
- {
- /* Check to see if it's possible to navigate to directory */
- GetCurrentDirectoryA(curDirectory, buffer);
- bSuccess = SetCurrentDirectoryA(szDirName);
- if(!bSuccess)
- {
- Trace("CreateDirectoryW: SetCurrentDirectoryA failed to "
- "navigate to the newly created directory with error "
- "code %u.\n", GetLastError());
- bRc = RemoveDirectoryW(pTemp);
- if(!bRc)
- {
- free(pTemp);
- Fail("CreateDirectoryW: RemoveDirectoryW failed to "
- "delete the directory with error %u.\n",
- GetLastError());
- }
- free(pTemp);
- Fail("");
- }
-
- /* Set directory back to initial directory */
- bRc = SetCurrentDirectoryA(buffer);
- if(!bRc)
- {
- free(pTemp);
- Fail("CreateDirectoryW: SetCurrentDirectoryA failed to "
- "change the directory with error %u.\n",
- GetLastError());
- }
-
- bRc = RemoveDirectoryW(pTemp);
- if(!bRc)
- {
- free(pTemp);
- Fail("CreateDirectoryW: RemoveDirectoryW failed to "
- "delete the directory with error %u.\n",
- GetLastError());
- }
- free(pTemp);
- }
-
- /* directories with dots */
- memset(szDirName, 0, 252);
- sprintf(szDirName, ".dotDirectory");
- pTemp = convert(szDirName);
- bRc = CreateDirectoryW(pTemp, NULL);
- if (bRc == FALSE)
- {
- free(pTemp);
- Fail("CreateDirectoryW: Failed to create a dot directory\n");
- }
- else
- {
- /* Check to see if it's possible to navigate to directory */
- GetCurrentDirectoryA(curDirectory, buffer);
- bSuccess = SetCurrentDirectoryA(szDirName);
- if(!bSuccess)
- {
- Trace("CreateDirectoryW: SetCurrentDirectoryA failed to "
- "navigate to the newly created directory with error "
- "code %u.\n", GetLastError());
-
- bRc = RemoveDirectoryW(pTemp);
- if(!bRc)
- {
- free(pTemp);
- Fail("CreateDirectoryW: RemoveDirectoryW failed to "
- "delete the directory with error %u.\n",
- GetLastError());
- }
- free(pTemp);
- Fail("");
- }
-
- /* Set directory back to initial directory */
- bRc = SetCurrentDirectoryA(buffer);
- if(!bRc)
- {
- free(pTemp);
- Fail("CreateDirectoryW: SetCurrentDirectoryA failed to "
- "change the directory with error %u.\n",
- GetLastError());
- }
-
- bRc = RemoveDirectoryW(pTemp);
- if(!bRc)
- {
- free(pTemp);
- Fail("CreateDirectoryW: RemoveDirectoryW failed to "
- "delete the directory with error %u.\n",
- GetLastError());
- }
- free(pTemp);
- }
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/file_io/CreateDirectoryW/test1/CreateDirectoryW.cpp b/src/pal/tests/palsuite/file_io/CreateDirectoryW/test1/CreateDirectoryW.cpp
new file mode 100644
index 0000000000..bbaedda745
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateDirectoryW/test1/CreateDirectoryW.cpp
@@ -0,0 +1,347 @@
+// Licensed to the .NET Foundation under one or more 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: CreateDirectoryW.c
+**
+** Purpose: Tests the PAL implementation of the CreateDirectoryW function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+/* apparently, under WIN32 the max path size is 248 but under
+ BSD it is _MAX_PATH */
+#if WIN32
+#define CREATE_MAX_PATH_SIZE 248
+#else
+#define CREATE_MAX_PATH_SIZE _MAX_PATH
+#endif
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ BOOL bRc = FALSE;
+ BOOL bSuccess = FALSE;
+ const int buf_size = CREATE_MAX_PATH_SIZE + 10;
+ char szDirName[CREATE_MAX_PATH_SIZE + 10];
+ char buffer[CREATE_MAX_PATH_SIZE + 10];
+ WCHAR* pTemp = NULL;
+ DWORD curDirLen;
+ DWORD curDirectory = 1024;
+
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* directory does not exist */
+ pTemp = convert("test_directory");
+ bRc = CreateDirectoryW(pTemp, NULL);
+ free(pTemp);
+ if (bRc == FALSE)
+ {
+ Fail("CreateDirectoryW: Failed to create \"test_directory\"\n");
+ }
+
+ /* directory exists */
+ pTemp = convert("test_directory");
+ bRc = CreateDirectoryW(pTemp, NULL);
+ if (bRc == TRUE)
+ {
+ bRc = RemoveDirectoryW(pTemp);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: RemoveDirectoryW failed to "
+ "delete the directory with error %u.\n",
+ GetLastError());
+ }
+ free(pTemp);
+ Fail("CreateDirectoryW: Succeeded creating the directory"
+ " \"test_directory\" when it exists already.\n");
+ }
+
+ bRc = RemoveDirectoryW(pTemp);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: RemoveDirectoryW failed to "
+ "delete the directory with error %u.\n",
+ GetLastError());
+ }
+ free(pTemp);
+
+ /* long directory names (CREATE_MAX_PATH_SIZE - 1, CREATE_MAX_PATH_SIZE
+ and CREATE_MAX_PATH_SIZE + 1 characters
+ including terminating null char) */
+
+ curDirLen = GetCurrentDirectoryA(0, NULL);
+
+ memset(szDirName, 0, buf_size);
+ memset(szDirName, 'a', CREATE_MAX_PATH_SIZE - 2 - curDirLen);
+ pTemp = convert((LPSTR)szDirName);
+ bRc = CreateDirectoryW(pTemp, NULL);
+ if (bRc == FALSE)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: Failed to create a directory"
+ " name (%d) chars long with the error code %ld\n",
+ CREATE_MAX_PATH_SIZE - 1,
+ GetLastError());
+ }
+ else
+ {
+
+ /* Check to see if it's possible to navigate to directory */
+ GetCurrentDirectoryA(curDirectory, buffer);
+ bSuccess = SetCurrentDirectoryA(szDirName);
+ if(!bSuccess)
+ {
+ Trace("CreateDirectoryW: SetCurrentDirectoryA failed to "
+ "navigate to the newly created directory with error "
+ "code %u.\n", GetLastError());
+ bRc = RemoveDirectoryW(pTemp);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: RemoveDirectoryW failed to "
+ "delete the directory with error %u.\n",
+ GetLastError());
+ }
+ free(pTemp);
+ Fail("");
+
+ }
+
+ /* Set directory back to initial directory */
+ bRc = SetCurrentDirectoryA(buffer);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: SetCurrentDirectoryA failed to "
+ "change the directory with error %u.\n",
+ GetLastError());
+ }
+
+ bRc = RemoveDirectoryW(pTemp);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: RemoveDirectoryW failed to "
+ "delete the directory with error %u.\n",
+ GetLastError());
+ }
+ free(pTemp);
+ }
+
+
+ memset(szDirName, 0, buf_size);
+ memset(szDirName, 'a', CREATE_MAX_PATH_SIZE - 1 - curDirLen);
+ pTemp = convert(szDirName);
+ bRc = CreateDirectoryW(pTemp, NULL);
+ if (bRc == FALSE)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: Failed to create a directory"
+ " name %d chars long with error code %ld\n",
+ strlen(szDirName),
+ GetLastError());
+ }
+ else
+ {
+ /* Check to see if it's possible to navigate to directory */
+ GetCurrentDirectoryA(curDirectory, buffer);
+ bSuccess = SetCurrentDirectoryA(szDirName);
+ if(!bSuccess)
+ {
+ Trace("CreateDirectoryW: SetCurrentDirectoryA failed to "
+ "navigate to the newly created directory with error "
+ "code %u.\n", GetLastError());
+
+ bRc = RemoveDirectoryW(pTemp);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: RemoveDirectoryW failed to "
+ "delete the directory with error %u.\n",
+ GetLastError());
+ }
+ free(pTemp);
+ Fail("");
+ }
+
+ /* Set directory back to initial directory */
+ bRc = SetCurrentDirectoryA(buffer);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: SetCurrentDirectoryA failed to "
+ "change the directory with error %u.\n",
+ GetLastError());
+ }
+
+
+ bRc = RemoveDirectoryW(pTemp);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: RemoveDirectoryW failed to "
+ "delete the directory with error %u.\n",
+ GetLastError());
+ }
+ free(pTemp);
+ }
+
+ memset(szDirName, 0, buf_size);
+ memset(szDirName, 'a', CREATE_MAX_PATH_SIZE - curDirLen);
+ pTemp = convert(szDirName);
+ bRc = CreateDirectoryW(pTemp, NULL);
+
+ if (bRc != FALSE)
+ {
+ RemoveDirectoryW(pTemp);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: RemoveDirectoryW failed to "
+ "delete the directory with error %u.\n",
+ GetLastError());
+ }
+ if (strlen(szDirName) > CREATE_MAX_PATH_SIZE)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: Failed because it created a directory"
+ " name 1 character longer (%d chars) than the max dir size"
+ " allowed\n",
+ strlen(szDirName));
+ }
+ }
+
+ free(pTemp);
+
+ /* long directory name CREATE_MAX_PATH_SIZE + 3 chars including "..\"
+ (real path length <= CREATE_MAX_PATH_SIZE) */
+ memset(szDirName, 0, buf_size);
+ memset(szDirName, 'a', CREATE_MAX_PATH_SIZE + 3 - 1 - curDirLen);
+ szDirName[0] = '.';
+ szDirName[1] = '.';
+ szDirName[2] = '\\';
+ pTemp = convert(szDirName);
+ bRc = CreateDirectoryW(pTemp, NULL);
+ if (bRc == FALSE)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: Failed to create a directory name more "
+ "than %d chars long and its real path name is less "
+ "than %d chars\n",
+ CREATE_MAX_PATH_SIZE,
+ CREATE_MAX_PATH_SIZE);
+ }
+ else
+ {
+ /* Check to see if it's possible to navigate to directory */
+ GetCurrentDirectoryA(curDirectory, buffer);
+ bSuccess = SetCurrentDirectoryA(szDirName);
+ if(!bSuccess)
+ {
+ Trace("CreateDirectoryW: SetCurrentDirectoryA failed to "
+ "navigate to the newly created directory with error "
+ "code %u.\n", GetLastError());
+ bRc = RemoveDirectoryW(pTemp);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: RemoveDirectoryW failed to "
+ "delete the directory with error %u.\n",
+ GetLastError());
+ }
+ free(pTemp);
+ Fail("");
+ }
+
+ /* Set directory back to initial directory */
+ bRc = SetCurrentDirectoryA(buffer);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: SetCurrentDirectoryA failed to "
+ "change the directory with error %u.\n",
+ GetLastError());
+ }
+
+ bRc = RemoveDirectoryW(pTemp);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: RemoveDirectoryW failed to "
+ "delete the directory with error %u.\n",
+ GetLastError());
+ }
+ free(pTemp);
+ }
+
+ /* directories with dots */
+ memset(szDirName, 0, 252);
+ sprintf_s(szDirName, _countof(szDirName), ".dotDirectory");
+ pTemp = convert(szDirName);
+ bRc = CreateDirectoryW(pTemp, NULL);
+ if (bRc == FALSE)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: Failed to create a dot directory\n");
+ }
+ else
+ {
+ /* Check to see if it's possible to navigate to directory */
+ GetCurrentDirectoryA(curDirectory, buffer);
+ bSuccess = SetCurrentDirectoryA(szDirName);
+ if(!bSuccess)
+ {
+ Trace("CreateDirectoryW: SetCurrentDirectoryA failed to "
+ "navigate to the newly created directory with error "
+ "code %u.\n", GetLastError());
+
+ bRc = RemoveDirectoryW(pTemp);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: RemoveDirectoryW failed to "
+ "delete the directory with error %u.\n",
+ GetLastError());
+ }
+ free(pTemp);
+ Fail("");
+ }
+
+ /* Set directory back to initial directory */
+ bRc = SetCurrentDirectoryA(buffer);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: SetCurrentDirectoryA failed to "
+ "change the directory with error %u.\n",
+ GetLastError());
+ }
+
+ bRc = RemoveDirectoryW(pTemp);
+ if(!bRc)
+ {
+ free(pTemp);
+ Fail("CreateDirectoryW: RemoveDirectoryW failed to "
+ "delete the directory with error %u.\n",
+ GetLastError());
+ }
+ free(pTemp);
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/file_io/CreateDirectoryW/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CreateDirectoryW/test2/CMakeLists.txt
index aae4e7dc54..f8614ca5a6 100644
--- a/src/pal/tests/palsuite/file_io/CreateDirectoryW/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/CreateDirectoryW/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- createdirectoryw.c
+ createdirectoryw.cpp
)
add_executable(paltest_createdirectoryw_test2
diff --git a/src/pal/tests/palsuite/file_io/CreateDirectoryW/test2/createdirectoryw.c b/src/pal/tests/palsuite/file_io/CreateDirectoryW/test2/createdirectoryw.cpp
index 20fac5a879..20fac5a879 100644
--- a/src/pal/tests/palsuite/file_io/CreateDirectoryW/test2/createdirectoryw.c
+++ b/src/pal/tests/palsuite/file_io/CreateDirectoryW/test2/createdirectoryw.cpp
diff --git a/src/pal/tests/palsuite/file_io/CreateFileA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CreateFileA/test1/CMakeLists.txt
index 8814b2281b..edacdbd621 100644
--- a/src/pal/tests/palsuite/file_io/CreateFileA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/CreateFileA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CreateFileA.c
+ CreateFileA.cpp
)
add_executable(paltest_createfilea_test1
diff --git a/src/pal/tests/palsuite/file_io/CreateFileA/test1/CreateFileA.c b/src/pal/tests/palsuite/file_io/CreateFileA/test1/CreateFileA.c
deleted file mode 100644
index a70867a5c8..0000000000
--- a/src/pal/tests/palsuite/file_io/CreateFileA/test1/CreateFileA.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: CreateFileA.c
-**
-** Purpose: Test the PAL implementation of the CreateFileA function
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-
-BOOL Cleanup(void)
-{
- char FileName[20];
- int i;
- BOOL bRet = TRUE; // assume success
-
- // loop through all accesses, modes, dispositions and flags
- for (i=0; i<4*8*4*5; ++i) {
- sprintf(FileName, "test%03d.txt", i);
- if (DeleteFileA(FileName) == FALSE) {
- if (GetLastError() != ERROR_FILE_NOT_FOUND) {
- bRet = FALSE;
- }
- }
- }
- return bRet;
-}
-
-
-int __cdecl main(int argc, char *argv[])
-{
- BOOL bSuccess = TRUE;
- int nCounter = 0;
- HANDLE hFile;
- char lpFileName[20];
- FILE *outFile = NULL;
- char results[1024];
- int i, j, k, l;
- DWORD dwDesiredAccess[4] = {0, // 0
- GENERIC_READ, // 1
- GENERIC_WRITE, // 2
- GENERIC_READ | GENERIC_WRITE}; // 3
- DWORD dwShareMode[8] = {0, // 0
- FILE_SHARE_READ, // 1
- FILE_SHARE_WRITE, // 2
- FILE_SHARE_DELETE, // 3
- FILE_SHARE_READ | FILE_SHARE_WRITE, // 4
- FILE_SHARE_READ | FILE_SHARE_DELETE, // 5
- FILE_SHARE_WRITE | FILE_SHARE_DELETE, // 6
- FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE}; // 7
- LPSECURITY_ATTRIBUTES lpAttr = NULL;
- DWORD dwCreationDisp[4] = {CREATE_NEW, // 0
- CREATE_ALWAYS, // 1
- OPEN_EXISTING, // 2
- OPEN_ALWAYS}; // 3
- DWORD dwFlagsAttrib[5] = {FILE_ATTRIBUTE_NORMAL, // 0
- FILE_FLAG_SEQUENTIAL_SCAN, // 1
- FILE_FLAG_WRITE_THROUGH, // 2
- FILE_FLAG_NO_BUFFERING, // 3
- FILE_FLAG_RANDOM_ACCESS}; // 4
- HANDLE hTemplate = NULL;
-
-
- if (0 != PAL_Initialize(argc,argv))
- {
- return FAIL;
- }
-
- if (!Cleanup()) {
- Trace("Pre-test Cleanup() failed. LastError=%d\n", GetLastError());
- return FAIL;
- }
-
- /* open the file to read the expected results */
- outFile = fopen("winoutput", "r");
- memset (results, 0, 1024);
-
- fgets(results, 1024, outFile);
- nCounter = (int)strlen(results);
- fclose(outFile);
-
- nCounter = 0;
-
- // desired access loop
- for (i = 0; i < 4; i++)
- {
- // share mode loop
- for (j = 0; j < 8; j++)
- {
- // security attributes loop
- for (k = 0; k < 4; k++)
- {
- // creation disp loop
- for (l = 0; l < 5; l++)
- {
- sprintf(lpFileName, "test%03d.txt", nCounter);
- hFile = CreateFile(lpFileName,
- dwDesiredAccess[i],
- dwShareMode[j],
- lpAttr,
- dwCreationDisp[k],
- dwFlagsAttrib[l],
- hTemplate);
- if (hFile == INVALID_HANDLE_VALUE)
- {
- if (results[nCounter] == '1')
- {
- Trace("CreateFile: ERROR: Failed when expected "
- "to pass %s [%d][%d][%d][%d]\n",
- lpFileName, i, j, k, l);
- bSuccess = FALSE;
- }
- }
- else
- {
- CloseHandle(hFile);
- if (results[nCounter] == '0')
- {
- Trace("CreateFile: ERROR: Passed when expected "
- "to fail %s [%d][%d][%d][%d]\n",
- lpFileName, i, j, k, l);
- bSuccess = FALSE;
- }
- }
- nCounter ++;
- }
- }
- }
- }
-
- if (!Cleanup())
- {
- Trace("Post-test Cleanup() failed. LastError=%d\n", GetLastError());
- return FAIL;
- }
-
- int exitCode = bSuccess ? PASS : FAIL;
- PAL_TerminateEx(exitCode);
- return exitCode;
-}
diff --git a/src/pal/tests/palsuite/file_io/CreateFileA/test1/CreateFileA.cpp b/src/pal/tests/palsuite/file_io/CreateFileA/test1/CreateFileA.cpp
new file mode 100644
index 0000000000..f98fc5b9c5
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateFileA/test1/CreateFileA.cpp
@@ -0,0 +1,145 @@
+// Licensed to the .NET Foundation under one or more 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: CreateFileA.c
+**
+** Purpose: Test the PAL implementation of the CreateFileA function
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+BOOL Cleanup(void)
+{
+ char FileName[20];
+ int i;
+ BOOL bRet = TRUE; // assume success
+
+ // loop through all accesses, modes, dispositions and flags
+ for (i=0; i<4*8*4*5; ++i) {
+ sprintf_s(FileName, _countof(FileName), "test%03d.txt", i);
+ if (DeleteFileA(FileName) == FALSE) {
+ if (GetLastError() != ERROR_FILE_NOT_FOUND) {
+ bRet = FALSE;
+ }
+ }
+ }
+ return bRet;
+}
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ BOOL bSuccess = TRUE;
+ int nCounter = 0;
+ HANDLE hFile;
+ char lpFileName[20];
+ FILE *outFile = NULL;
+ char results[1024];
+ int i, j, k, l;
+ DWORD dwDesiredAccess[4] = {0, // 0
+ GENERIC_READ, // 1
+ GENERIC_WRITE, // 2
+ GENERIC_READ | GENERIC_WRITE}; // 3
+ DWORD dwShareMode[8] = {0, // 0
+ FILE_SHARE_READ, // 1
+ FILE_SHARE_WRITE, // 2
+ FILE_SHARE_DELETE, // 3
+ FILE_SHARE_READ | FILE_SHARE_WRITE, // 4
+ FILE_SHARE_READ | FILE_SHARE_DELETE, // 5
+ FILE_SHARE_WRITE | FILE_SHARE_DELETE, // 6
+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE}; // 7
+ LPSECURITY_ATTRIBUTES lpAttr = NULL;
+ DWORD dwCreationDisp[4] = {CREATE_NEW, // 0
+ CREATE_ALWAYS, // 1
+ OPEN_EXISTING, // 2
+ OPEN_ALWAYS}; // 3
+ DWORD dwFlagsAttrib[5] = {FILE_ATTRIBUTE_NORMAL, // 0
+ FILE_FLAG_SEQUENTIAL_SCAN, // 1
+ FILE_FLAG_WRITE_THROUGH, // 2
+ FILE_FLAG_NO_BUFFERING, // 3
+ FILE_FLAG_RANDOM_ACCESS}; // 4
+ HANDLE hTemplate = NULL;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ if (!Cleanup()) {
+ Trace("Pre-test Cleanup() failed. LastError=%d\n", GetLastError());
+ return FAIL;
+ }
+
+ /* open the file to read the expected results */
+ outFile = fopen("winoutput", "r");
+ memset (results, 0, 1024);
+
+ fgets(results, 1024, outFile);
+ nCounter = (int)strlen(results);
+ fclose(outFile);
+
+ nCounter = 0;
+
+ // desired access loop
+ for (i = 0; i < 4; i++)
+ {
+ // share mode loop
+ for (j = 0; j < 8; j++)
+ {
+ // security attributes loop
+ for (k = 0; k < 4; k++)
+ {
+ // creation disp loop
+ for (l = 0; l < 5; l++)
+ {
+ sprintf_s(lpFileName, _countof(lpFileName), "test%03d.txt", nCounter);
+ hFile = CreateFile(lpFileName,
+ dwDesiredAccess[i],
+ dwShareMode[j],
+ lpAttr,
+ dwCreationDisp[k],
+ dwFlagsAttrib[l],
+ hTemplate);
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ if (results[nCounter] == '1')
+ {
+ Trace("CreateFile: ERROR: Failed when expected "
+ "to pass %s [%d][%d][%d][%d]\n",
+ lpFileName, i, j, k, l);
+ bSuccess = FALSE;
+ }
+ }
+ else
+ {
+ CloseHandle(hFile);
+ if (results[nCounter] == '0')
+ {
+ Trace("CreateFile: ERROR: Passed when expected "
+ "to fail %s [%d][%d][%d][%d]\n",
+ lpFileName, i, j, k, l);
+ bSuccess = FALSE;
+ }
+ }
+ nCounter ++;
+ }
+ }
+ }
+ }
+
+ if (!Cleanup())
+ {
+ Trace("Post-test Cleanup() failed. LastError=%d\n", GetLastError());
+ return FAIL;
+ }
+
+ int exitCode = bSuccess ? PASS : FAIL;
+ PAL_TerminateEx(exitCode);
+ return exitCode;
+}
diff --git a/src/pal/tests/palsuite/file_io/CreateFileW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/CreateFileW/test1/CMakeLists.txt
index 1ff0b8062f..820e169a37 100644
--- a/src/pal/tests/palsuite/file_io/CreateFileW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/CreateFileW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CreateFileW.c
+ CreateFileW.cpp
)
add_executable(paltest_createfilew_test1
diff --git a/src/pal/tests/palsuite/file_io/CreateFileW/test1/CreateFileW.c b/src/pal/tests/palsuite/file_io/CreateFileW/test1/CreateFileW.c
deleted file mode 100644
index 4d7d20af29..0000000000
--- a/src/pal/tests/palsuite/file_io/CreateFileW/test1/CreateFileW.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: CreateFileW.c
-**
-** Purpose: Test the PAL implementation of the CreateFileW function
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-
-BOOL Cleanup(void)
-{
- char FileName[20];
- int i;
- BOOL bRet = TRUE; // assume success
-
- // loop through all accesses, modes, dispositions and flags
- for (i=0; i<4*8*4*5; ++i) {
- sprintf(FileName, "test%03d.txt", i);
- if (DeleteFileA(FileName) == FALSE) {
- if (GetLastError() != ERROR_FILE_NOT_FOUND) {
- bRet = FALSE;
- }
- }
- }
- return bRet;
-}
-
-
-int __cdecl main(int argc, char *argv[])
-{
- BOOL bSuccess = TRUE;
- int nCounter = 0;
- HANDLE hFile = NULL;
- WCHAR *lpFileName = NULL;
- char* pTemp = NULL;
- char string[40];
- FILE *outFile = NULL;
- char results[1024];
- int i, j, k, l;
- DWORD dwDesiredAccess[4] = {0, // 0
- GENERIC_READ, // 1
- GENERIC_WRITE, // 2
- GENERIC_READ | GENERIC_WRITE}; // 3
- DWORD dwShareMode[8] = {0, // 0
- FILE_SHARE_READ, // 1
- FILE_SHARE_WRITE, // 2
- FILE_SHARE_DELETE, // 3
- FILE_SHARE_READ | FILE_SHARE_WRITE, // 4
- FILE_SHARE_READ | FILE_SHARE_DELETE, // 5
- FILE_SHARE_WRITE | FILE_SHARE_DELETE, // 6
- FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE}; // 7
- LPSECURITY_ATTRIBUTES lpAttr = NULL;
- DWORD dwCreationDisp[4] = {CREATE_NEW, // 0
- CREATE_ALWAYS, // 1
- OPEN_EXISTING, // 2
- OPEN_ALWAYS}; // 3
- DWORD dwFlagsAttrib[5] = {FILE_ATTRIBUTE_NORMAL, // 0
- FILE_FLAG_SEQUENTIAL_SCAN, // 1
- FILE_FLAG_WRITE_THROUGH, // 2
- FILE_FLAG_NO_BUFFERING, // 3
- FILE_FLAG_RANDOM_ACCESS}; // 4
- HANDLE hTemplate = NULL;
-
-
- if (0 != PAL_Initialize(argc,argv))
- {
- return FAIL;
- }
-
- if (!Cleanup()) {
- Trace("Pre-test Cleanup() failed. LastError=%d\n", GetLastError());
- return FAIL;
- }
-
- /* open the file to read the expected results */
- outFile = fopen("winoutput", "r");
- memset (results, 0, 1024);
-
- fgets(results, 1024, outFile);
- fclose(outFile);
-
- nCounter = 0;
-
- // desired access loop
- for (i = 0; i < 4; i++)
- {
- // share mode loop
- for (j = 0; j < 8; j++)
- {
- // security attributes loop
- for (k = 0; k < 4; k++)
- {
- // creation disp loop
- for (l = 0; l < 5; l++)
- {
- sprintf(string, "test%03d.txt", nCounter);
- lpFileName = convert(string);
- hFile = CreateFileW(lpFileName,
- dwDesiredAccess[i],
- dwShareMode[j],
- lpAttr,
- dwCreationDisp[k],
- dwFlagsAttrib[l],
- hTemplate);
- free(lpFileName);
- if (hFile == INVALID_HANDLE_VALUE)
- {
- if (results[nCounter] == '1')
- {
- pTemp = convertC(lpFileName);
- Trace("CreateFile: ERROR: Failed when expected "
- "to pass %s [%d][%d][%d][%d]\n",
- pTemp, i, j, k, l);
- free(pTemp);
- bSuccess = FALSE;
- }
- }
- else
- {
- CloseHandle(hFile);
- if (results[nCounter] == '0')
- {
- pTemp = convertC(lpFileName);
- Trace("CreateFile: ERROR: Passed when expected "
- "to fail %s [%d][%d][%d][%d]\n",
- pTemp, i, j, k, l);
- free(pTemp);
- bSuccess = FALSE;
- }
- }
- nCounter ++;
- }
- }
- }
- }
-
- if (!Cleanup())
- {
- Trace("Post-test Cleanup() failed. LastError=%d\n", GetLastError());
- return FAIL;
- }
-
- int exitCode = bSuccess ? PASS : FAIL;
- PAL_TerminateEx(exitCode);
- return exitCode;
-}
diff --git a/src/pal/tests/palsuite/file_io/CreateFileW/test1/CreateFileW.cpp b/src/pal/tests/palsuite/file_io/CreateFileW/test1/CreateFileW.cpp
new file mode 100644
index 0000000000..0619f5b4aa
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/CreateFileW/test1/CreateFileW.cpp
@@ -0,0 +1,152 @@
+// Licensed to the .NET Foundation under one or more 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: CreateFileW.c
+**
+** Purpose: Test the PAL implementation of the CreateFileW function
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+BOOL Cleanup(void)
+{
+ char FileName[20];
+ int i;
+ BOOL bRet = TRUE; // assume success
+
+ // loop through all accesses, modes, dispositions and flags
+ for (i=0; i<4*8*4*5; ++i) {
+ sprintf_s(FileName, _countof(FileName), "test%03d.txt", i);
+ if (DeleteFileA(FileName) == FALSE) {
+ if (GetLastError() != ERROR_FILE_NOT_FOUND) {
+ bRet = FALSE;
+ }
+ }
+ }
+ return bRet;
+}
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ BOOL bSuccess = TRUE;
+ int nCounter = 0;
+ HANDLE hFile = NULL;
+ WCHAR *lpFileName = NULL;
+ char* pTemp = NULL;
+ char string[40];
+ FILE *outFile = NULL;
+ char results[1024];
+ int i, j, k, l;
+ DWORD dwDesiredAccess[4] = {0, // 0
+ GENERIC_READ, // 1
+ GENERIC_WRITE, // 2
+ GENERIC_READ | GENERIC_WRITE}; // 3
+ DWORD dwShareMode[8] = {0, // 0
+ FILE_SHARE_READ, // 1
+ FILE_SHARE_WRITE, // 2
+ FILE_SHARE_DELETE, // 3
+ FILE_SHARE_READ | FILE_SHARE_WRITE, // 4
+ FILE_SHARE_READ | FILE_SHARE_DELETE, // 5
+ FILE_SHARE_WRITE | FILE_SHARE_DELETE, // 6
+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE}; // 7
+ LPSECURITY_ATTRIBUTES lpAttr = NULL;
+ DWORD dwCreationDisp[4] = {CREATE_NEW, // 0
+ CREATE_ALWAYS, // 1
+ OPEN_EXISTING, // 2
+ OPEN_ALWAYS}; // 3
+ DWORD dwFlagsAttrib[5] = {FILE_ATTRIBUTE_NORMAL, // 0
+ FILE_FLAG_SEQUENTIAL_SCAN, // 1
+ FILE_FLAG_WRITE_THROUGH, // 2
+ FILE_FLAG_NO_BUFFERING, // 3
+ FILE_FLAG_RANDOM_ACCESS}; // 4
+ HANDLE hTemplate = NULL;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ if (!Cleanup()) {
+ Trace("Pre-test Cleanup() failed. LastError=%d\n", GetLastError());
+ return FAIL;
+ }
+
+ /* open the file to read the expected results */
+ outFile = fopen("winoutput", "r");
+ memset (results, 0, 1024);
+
+ fgets(results, 1024, outFile);
+ fclose(outFile);
+
+ nCounter = 0;
+
+ // desired access loop
+ for (i = 0; i < 4; i++)
+ {
+ // share mode loop
+ for (j = 0; j < 8; j++)
+ {
+ // security attributes loop
+ for (k = 0; k < 4; k++)
+ {
+ // creation disp loop
+ for (l = 0; l < 5; l++)
+ {
+ sprintf_s(string, _countof(string), "test%03d.txt", nCounter);
+ lpFileName = convert(string);
+ hFile = CreateFileW(lpFileName,
+ dwDesiredAccess[i],
+ dwShareMode[j],
+ lpAttr,
+ dwCreationDisp[k],
+ dwFlagsAttrib[l],
+ hTemplate);
+ free(lpFileName);
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ if (results[nCounter] == '1')
+ {
+ pTemp = convertC(lpFileName);
+ Trace("CreateFile: ERROR: Failed when expected "
+ "to pass %s [%d][%d][%d][%d]\n",
+ pTemp, i, j, k, l);
+ free(pTemp);
+ bSuccess = FALSE;
+ }
+ }
+ else
+ {
+ CloseHandle(hFile);
+ if (results[nCounter] == '0')
+ {
+ pTemp = convertC(lpFileName);
+ Trace("CreateFile: ERROR: Passed when expected "
+ "to fail %s [%d][%d][%d][%d]\n",
+ pTemp, i, j, k, l);
+ free(pTemp);
+ bSuccess = FALSE;
+ }
+ }
+ nCounter ++;
+ }
+ }
+ }
+ }
+
+ if (!Cleanup())
+ {
+ Trace("Post-test Cleanup() failed. LastError=%d\n", GetLastError());
+ return FAIL;
+ }
+
+ int exitCode = bSuccess ? PASS : FAIL;
+ PAL_TerminateEx(exitCode);
+ return exitCode;
+}
diff --git a/src/pal/tests/palsuite/file_io/DeleteFileW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/DeleteFileW/test1/CMakeLists.txt
index 046fd35148..eada6145b9 100644
--- a/src/pal/tests/palsuite/file_io/DeleteFileW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/DeleteFileW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- DeleteFileW.c
+ DeleteFileW.cpp
)
add_executable(paltest_deletefilew_test1
diff --git a/src/pal/tests/palsuite/file_io/DeleteFileW/test1/DeleteFileW.c b/src/pal/tests/palsuite/file_io/DeleteFileW/test1/DeleteFileW.cpp
index fca96d1e00..fca96d1e00 100644
--- a/src/pal/tests/palsuite/file_io/DeleteFileW/test1/DeleteFileW.c
+++ b/src/pal/tests/palsuite/file_io/DeleteFileW/test1/DeleteFileW.cpp
diff --git a/src/pal/tests/palsuite/file_io/FILECanonicalizePath/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FILECanonicalizePath/CMakeLists.txt
index 0c02c98f15..7045983629 100644
--- a/src/pal/tests/palsuite/file_io/FILECanonicalizePath/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/FILECanonicalizePath/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- FILECanonicalizePath.c
+ FILECanonicalizePath.cpp
)
add_executable(paltest_filecanonicalizepath_test1
diff --git a/src/pal/tests/palsuite/file_io/FILECanonicalizePath/FILECanonicalizePath.c b/src/pal/tests/palsuite/file_io/FILECanonicalizePath/FILECanonicalizePath.c
deleted file mode 100644
index 91bac1f3cb..0000000000
--- a/src/pal/tests/palsuite/file_io/FILECanonicalizePath/FILECanonicalizePath.c
+++ /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: FILECanonicalizePath.c (test 1)
-**
-** Purpose: Tests the PAL implementation of the FILECanonicalizePath function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-
-extern void FILECanonicalizePath(LPSTR lpUnixPath);
-
-void TestCase(LPSTR input, LPSTR expectedOutput);
-
-int __cdecl main(int argc, char *argv[])
-{
- if (PAL_Initialize(argc,argv) != 0)
- {
- return FAIL;
- }
-
- // Case 01: /<name> should not change
- TestCase("/Test", "/Test");
-
- // Case 02: /<name>/<name2> should not change
- TestCase("/Test/Foo", "/Test/Foo");
-
- // Case 03: // transforms to /
- TestCase("//", "/");
-
- // Case 04: /./ transforms to /
- TestCase("/./", "/");
-
- // Case 05: /<name>/../ transforms to /
- TestCase("/Test/../", "/");
-
- // Case 06: /Test/Foo/.. transforms to /Test
- TestCase("/Test/Foo/..", "/Test");
-
- // Case 07: /Test/.. transforms to /
- TestCase("/Test/..", "/");
-
- // Case 08: /. transforms to /
- TestCase("/.", "/");
-
- // Case 09: /<name/. transforms to /<name>
- TestCase("/Test/.", "/Test");
-
- // Case 10: /<name>/../. transforms to /
- TestCase("/Test/../.", "/");
-
- // Case 11: /.. transforms to /
- TestCase("/..", "/");
-
- PAL_Terminate();
- return PASS;
-}
-
-void TestCase(LPSTR input, LPSTR expectedOutput)
-{
- // Save the input for debug logging since the input is edited in-place
- char* pOriginalInput = (char*)malloc(strlen(input) * sizeof(char) + 1);
- strcpy(pOriginalInput, input);
-
- char* pInput = (char*)malloc(strlen(input) * sizeof(char) + 1);
- strcpy(pInput, pOriginalInput);
-
- FILECanonicalizePath(pInput);
- if (strcmp(pInput, expectedOutput) != 0)
- {
- free(pOriginalInput);
- free(pInput);
- Fail("FILECanonicalizePath error: input %s did not match expected output %s; got %s instead", pOriginalInput, expectedOutput, pInput);
- }
-
- free(pOriginalInput);
- free(pInput);
-}
diff --git a/src/pal/tests/palsuite/file_io/FILECanonicalizePath/FILECanonicalizePath.cpp b/src/pal/tests/palsuite/file_io/FILECanonicalizePath/FILECanonicalizePath.cpp
new file mode 100644
index 0000000000..3a1758aa3b
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/FILECanonicalizePath/FILECanonicalizePath.cpp
@@ -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.
+
+/*=====================================================================
+**
+** Source: FILECanonicalizePath.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the FILECanonicalizePath function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+extern "C" void FILECanonicalizePath(LPSTR lpUnixPath);
+
+void TestCase(LPSTR input, LPSTR expectedOutput);
+
+int __cdecl main(int argc, char *argv[])
+{
+ if (PAL_Initialize(argc,argv) != 0)
+ {
+ return FAIL;
+ }
+
+ // Case 01: /<name> should not change
+ TestCase("/Test", "/Test");
+
+ // Case 02: /<name>/<name2> should not change
+ TestCase("/Test/Foo", "/Test/Foo");
+
+ // Case 03: // transforms to /
+ TestCase("//", "/");
+
+ // Case 04: /./ transforms to /
+ TestCase("/./", "/");
+
+ // Case 05: /<name>/../ transforms to /
+ TestCase("/Test/../", "/");
+
+ // Case 06: /Test/Foo/.. transforms to /Test
+ TestCase("/Test/Foo/..", "/Test");
+
+ // Case 07: /Test/.. transforms to /
+ TestCase("/Test/..", "/");
+
+ // Case 08: /. transforms to /
+ TestCase("/.", "/");
+
+ // Case 09: /<name/. transforms to /<name>
+ TestCase("/Test/.", "/Test");
+
+ // Case 10: /<name>/../. transforms to /
+ TestCase("/Test/../.", "/");
+
+ // Case 11: /.. transforms to /
+ TestCase("/..", "/");
+
+ PAL_Terminate();
+ return PASS;
+}
+
+void TestCase(LPSTR input, LPSTR expectedOutput)
+{
+ // Save the input for debug logging since the input is edited in-place
+ char* pOriginalInput = (char*)malloc(strlen(input) * sizeof(char) + 1);
+ strcpy(pOriginalInput, input);
+
+ char* pInput = (char*)malloc(strlen(input) * sizeof(char) + 1);
+ strcpy(pInput, pOriginalInput);
+
+ FILECanonicalizePath(pInput);
+ if (strcmp(pInput, expectedOutput) != 0)
+ {
+ free(pOriginalInput);
+ free(pInput);
+ Fail("FILECanonicalizePath error: input %s did not match expected output %s; got %s instead", pOriginalInput, expectedOutput, pInput);
+ }
+
+ free(pOriginalInput);
+ free(pInput);
+}
diff --git a/src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/test1/CMakeLists.txt
index 131054266b..6ec6a98b3f 100644
--- a/src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_filetimetodosdatetime_test1
diff --git a/src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/test1/test1.c b/src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/test1/test1.cpp
index 5f2c81ff98..5f2c81ff98 100644
--- a/src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/test1/test1.c
+++ b/src/pal/tests/palsuite/file_io/FileTimeToDosDateTime/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/file_io/FindClose/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FindClose/test1/CMakeLists.txt
index 732c9f58d3..d97c69e6ee 100644
--- a/src/pal/tests/palsuite/file_io/FindClose/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/FindClose/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- FindClose.c
+ FindClose.cpp
)
add_executable(paltest_findclose_test1
diff --git a/src/pal/tests/palsuite/file_io/FindClose/test1/FindClose.c b/src/pal/tests/palsuite/file_io/FindClose/test1/FindClose.cpp
index 3d53806e48..3d53806e48 100644
--- a/src/pal/tests/palsuite/file_io/FindClose/test1/FindClose.c
+++ b/src/pal/tests/palsuite/file_io/FindClose/test1/FindClose.cpp
diff --git a/src/pal/tests/palsuite/file_io/FindFirstFileA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FindFirstFileA/test1/CMakeLists.txt
index 6613c4d444..aeac94d42f 100644
--- a/src/pal/tests/palsuite/file_io/FindFirstFileA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/FindFirstFileA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- FindFirstFileA.c
+ FindFirstFileA.cpp
)
add_executable(paltest_findfirstfilea_test1
diff --git a/src/pal/tests/palsuite/file_io/FindFirstFileA/test1/FindFirstFileA.c b/src/pal/tests/palsuite/file_io/FindFirstFileA/test1/FindFirstFileA.cpp
index 6ceb6a9747..6ceb6a9747 100644
--- a/src/pal/tests/palsuite/file_io/FindFirstFileA/test1/FindFirstFileA.c
+++ b/src/pal/tests/palsuite/file_io/FindFirstFileA/test1/FindFirstFileA.cpp
diff --git a/src/pal/tests/palsuite/file_io/FindFirstFileW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FindFirstFileW/test1/CMakeLists.txt
index 23e95c7dad..2a6ea2b7a4 100644
--- a/src/pal/tests/palsuite/file_io/FindFirstFileW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/FindFirstFileW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- FindFirstFileW.c
+ FindFirstFileW.cpp
)
add_executable(paltest_findfirstfilew_test1
diff --git a/src/pal/tests/palsuite/file_io/FindFirstFileW/test1/FindFirstFileW.c b/src/pal/tests/palsuite/file_io/FindFirstFileW/test1/FindFirstFileW.cpp
index f69a625976..f69a625976 100644
--- a/src/pal/tests/palsuite/file_io/FindFirstFileW/test1/FindFirstFileW.c
+++ b/src/pal/tests/palsuite/file_io/FindFirstFileW/test1/FindFirstFileW.cpp
diff --git a/src/pal/tests/palsuite/file_io/FindNextFileA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FindNextFileA/test1/CMakeLists.txt
index efb1655d95..6e97b7aaad 100644
--- a/src/pal/tests/palsuite/file_io/FindNextFileA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/FindNextFileA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- FindNextFileA.c
+ FindNextFileA.cpp
)
add_executable(paltest_findnextfilea_test1
diff --git a/src/pal/tests/palsuite/file_io/FindNextFileA/test1/FindNextFileA.c b/src/pal/tests/palsuite/file_io/FindNextFileA/test1/FindNextFileA.cpp
index 578fa00542..578fa00542 100644
--- a/src/pal/tests/palsuite/file_io/FindNextFileA/test1/FindNextFileA.c
+++ b/src/pal/tests/palsuite/file_io/FindNextFileA/test1/FindNextFileA.cpp
diff --git a/src/pal/tests/palsuite/file_io/FindNextFileA/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FindNextFileA/test2/CMakeLists.txt
index 96821bdaaa..e037bd3aa0 100644
--- a/src/pal/tests/palsuite/file_io/FindNextFileA/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/FindNextFileA/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- findnextfilea.c
+ findnextfilea.cpp
)
add_executable(paltest_findnextfilea_test2
diff --git a/src/pal/tests/palsuite/file_io/FindNextFileA/test2/findnextfilea.c b/src/pal/tests/palsuite/file_io/FindNextFileA/test2/findnextfilea.cpp
index c841a4d498..c841a4d498 100644
--- a/src/pal/tests/palsuite/file_io/FindNextFileA/test2/findnextfilea.c
+++ b/src/pal/tests/palsuite/file_io/FindNextFileA/test2/findnextfilea.cpp
diff --git a/src/pal/tests/palsuite/file_io/FindNextFileW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FindNextFileW/test1/CMakeLists.txt
index 4a283dd3a5..a7c3e7ea02 100644
--- a/src/pal/tests/palsuite/file_io/FindNextFileW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/FindNextFileW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- FindNextFileW.c
+ FindNextFileW.cpp
)
add_executable(paltest_findnextfilew_test1
diff --git a/src/pal/tests/palsuite/file_io/FindNextFileW/test1/FindNextFileW.c b/src/pal/tests/palsuite/file_io/FindNextFileW/test1/FindNextFileW.cpp
index 42e2e55805..42e2e55805 100644
--- a/src/pal/tests/palsuite/file_io/FindNextFileW/test1/FindNextFileW.c
+++ b/src/pal/tests/palsuite/file_io/FindNextFileW/test1/FindNextFileW.cpp
diff --git a/src/pal/tests/palsuite/file_io/FindNextFileW/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FindNextFileW/test2/CMakeLists.txt
index 2938afb888..7b4c3c9597 100644
--- a/src/pal/tests/palsuite/file_io/FindNextFileW/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/FindNextFileW/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- findnextfilew.c
+ findnextfilew.cpp
)
add_executable(paltest_findnextfilew_test2
diff --git a/src/pal/tests/palsuite/file_io/FindNextFileW/test2/findnextfilew.c b/src/pal/tests/palsuite/file_io/FindNextFileW/test2/findnextfilew.cpp
index 3e806c2576..3e806c2576 100644
--- a/src/pal/tests/palsuite/file_io/FindNextFileW/test2/findnextfilew.c
+++ b/src/pal/tests/palsuite/file_io/FindNextFileW/test2/findnextfilew.cpp
diff --git a/src/pal/tests/palsuite/file_io/FlushFileBuffers/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/FlushFileBuffers/test1/CMakeLists.txt
index e3fbccd2ae..6c24ac76d1 100644
--- a/src/pal/tests/palsuite/file_io/FlushFileBuffers/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/FlushFileBuffers/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- FlushFileBuffers.c
+ FlushFileBuffers.cpp
)
add_executable(paltest_flushfilebuffers_test1
diff --git a/src/pal/tests/palsuite/file_io/FlushFileBuffers/test1/FlushFileBuffers.c b/src/pal/tests/palsuite/file_io/FlushFileBuffers/test1/FlushFileBuffers.cpp
index 246be64847..246be64847 100644
--- a/src/pal/tests/palsuite/file_io/FlushFileBuffers/test1/FlushFileBuffers.c
+++ b/src/pal/tests/palsuite/file_io/FlushFileBuffers/test1/FlushFileBuffers.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetConsoleCP/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetConsoleCP/test1/CMakeLists.txt
index 131f4a5fb7..64ab6ea945 100644
--- a/src/pal/tests/palsuite/file_io/GetConsoleCP/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetConsoleCP/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetConsoleCP.c
+ GetConsoleCP.cpp
)
add_executable(paltest_getconsolecp_test1
diff --git a/src/pal/tests/palsuite/file_io/GetConsoleCP/test1/GetConsoleCP.c b/src/pal/tests/palsuite/file_io/GetConsoleCP/test1/GetConsoleCP.cpp
index ba17d6c64d..ba17d6c64d 100644
--- a/src/pal/tests/palsuite/file_io/GetConsoleCP/test1/GetConsoleCP.c
+++ b/src/pal/tests/palsuite/file_io/GetConsoleCP/test1/GetConsoleCP.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetConsoleOutputCP/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetConsoleOutputCP/test1/CMakeLists.txt
index d19ab95a37..756f87b382 100644
--- a/src/pal/tests/palsuite/file_io/GetConsoleOutputCP/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetConsoleOutputCP/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetConsoleOutputCP.c
+ GetConsoleOutputCP.cpp
)
add_executable(paltest_getconsoleoutputcp_test1
diff --git a/src/pal/tests/palsuite/file_io/GetConsoleOutputCP/test1/GetConsoleOutputCP.c b/src/pal/tests/palsuite/file_io/GetConsoleOutputCP/test1/GetConsoleOutputCP.cpp
index 3deaebf68f..3deaebf68f 100644
--- a/src/pal/tests/palsuite/file_io/GetConsoleOutputCP/test1/GetConsoleOutputCP.c
+++ b/src/pal/tests/palsuite/file_io/GetConsoleOutputCP/test1/GetConsoleOutputCP.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/test1/CMakeLists.txt
index f7382b047d..28efc6897f 100644
--- a/src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetCurrentDirectoryA.c
+ GetCurrentDirectoryA.cpp
)
add_executable(paltest_getcurrentdirectorya_test1
diff --git a/src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/test1/GetCurrentDirectoryA.c b/src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/test1/GetCurrentDirectoryA.cpp
index b09e8a104d..b09e8a104d 100644
--- a/src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/test1/GetCurrentDirectoryA.c
+++ b/src/pal/tests/palsuite/file_io/GetCurrentDirectoryA/test1/GetCurrentDirectoryA.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/test1/CMakeLists.txt
index ed8419926c..ee07f5e0d1 100644
--- a/src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetCurrentDirectoryW.c
+ GetCurrentDirectoryW.cpp
)
add_executable(paltest_getcurrentdirectoryw_test1
diff --git a/src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/test1/GetCurrentDirectoryW.c b/src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/test1/GetCurrentDirectoryW.cpp
index 4f4697b0a2..4f4697b0a2 100644
--- a/src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/test1/GetCurrentDirectoryW.c
+++ b/src/pal/tests/palsuite/file_io/GetCurrentDirectoryW/test1/GetCurrentDirectoryW.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test1/CMakeLists.txt
index 6b06376233..7de0b275f6 100644
--- a/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetDiskFreeSpaceW.c
+ GetDiskFreeSpaceW.cpp
)
add_executable(paltest_getdiskfreespacew_test1
diff --git a/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test1/GetDiskFreeSpaceW.c b/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test1/GetDiskFreeSpaceW.cpp
index c1445f654f..c1445f654f 100644
--- a/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test1/GetDiskFreeSpaceW.c
+++ b/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test1/GetDiskFreeSpaceW.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test2/CMakeLists.txt
index 5660b39e1a..7bcbf55c42 100644
--- a/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- getdiskfreespacew.c
+ getdiskfreespacew.cpp
)
add_executable(paltest_getdiskfreespacew_test2
diff --git a/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test2/getdiskfreespacew.c b/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test2/getdiskfreespacew.cpp
index 83dcb54b51..83dcb54b51 100644
--- a/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test2/getdiskfreespacew.c
+++ b/src/pal/tests/palsuite/file_io/GetDiskFreeSpaceW/test2/getdiskfreespacew.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/CMakeLists.txt
index 6bf9818e86..414df7f6b5 100644
--- a/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetFileAttributesA.c
+ GetFileAttributesA.cpp
)
add_executable(paltest_getfileattributesa_test1
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/GetFileAttributesA.c b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/GetFileAttributesA.cpp
index ff6bd0b8e0..ff6bd0b8e0 100644
--- a/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/GetFileAttributesA.c
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesA/test1/GetFileAttributesA.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/CMakeLists.txt
index 2d299d82e5..6ea24d9d32 100644
--- a/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_getfileattributesexw_test1
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/test1.c b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/test1.cpp
index 7a622b628c..7a622b628c 100644
--- a/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/test1.c
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test2/CMakeLists.txt
index 70caac2c69..0faa3bd11e 100644
--- a/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_getfileattributesexw_test2
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test2/test2.c b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test2/test2.cpp
index f244a3bf6a..f244a3bf6a 100644
--- a/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test2/test2.c
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesExW/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/CMakeLists.txt
index 7050484607..bc82f3678e 100644
--- a/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetFileAttributesW.c
+ GetFileAttributesW.cpp
)
add_executable(paltest_getfileattributesw_test1
diff --git a/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/GetFileAttributesW.c b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/GetFileAttributesW.cpp
index 9d00da4bd4..9d00da4bd4 100644
--- a/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/GetFileAttributesW.c
+++ b/src/pal/tests/palsuite/file_io/GetFileAttributesW/test1/GetFileAttributesW.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetFileSize/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileSize/test1/CMakeLists.txt
index ff20de5905..f192ba7400 100644
--- a/src/pal/tests/palsuite/file_io/GetFileSize/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetFileSize/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetFileSize.c
+ GetFileSize.cpp
)
add_executable(paltest_getfilesize_test1
diff --git a/src/pal/tests/palsuite/file_io/GetFileSize/test1/GetFileSize.c b/src/pal/tests/palsuite/file_io/GetFileSize/test1/GetFileSize.cpp
index fac01c98c9..fac01c98c9 100644
--- a/src/pal/tests/palsuite/file_io/GetFileSize/test1/GetFileSize.c
+++ b/src/pal/tests/palsuite/file_io/GetFileSize/test1/GetFileSize.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetFileSizeEx/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileSizeEx/test1/CMakeLists.txt
index 1369a5dc5a..33a7e2f557 100644
--- a/src/pal/tests/palsuite/file_io/GetFileSizeEx/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetFileSizeEx/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetFileSizeEx.c
+ GetFileSizeEx.cpp
)
add_executable(paltest_getfilesizeex_test1
diff --git a/src/pal/tests/palsuite/file_io/GetFileSizeEx/test1/GetFileSizeEx.c b/src/pal/tests/palsuite/file_io/GetFileSizeEx/test1/GetFileSizeEx.cpp
index ef5afd0e6b..ef5afd0e6b 100644
--- a/src/pal/tests/palsuite/file_io/GetFileSizeEx/test1/GetFileSizeEx.c
+++ b/src/pal/tests/palsuite/file_io/GetFileSizeEx/test1/GetFileSizeEx.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileTime/test1/CMakeLists.txt
index 6a89846d21..b95267ab5b 100644
--- a/src/pal/tests/palsuite/file_io/GetFileTime/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetFileTime.c
+ GetFileTime.cpp
)
add_executable(paltest_getfiletime_test1
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test1/GetFileTime.c b/src/pal/tests/palsuite/file_io/GetFileTime/test1/GetFileTime.cpp
index fb7bcb8513..fb7bcb8513 100644
--- a/src/pal/tests/palsuite/file_io/GetFileTime/test1/GetFileTime.c
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test1/GetFileTime.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileTime/test2/CMakeLists.txt
index 3d315e44de..fe02e27bbe 100644
--- a/src/pal/tests/palsuite/file_io/GetFileTime/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetFileTime.c
+ GetFileTime.cpp
)
add_executable(paltest_getfiletime_test2
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test2/GetFileTime.c b/src/pal/tests/palsuite/file_io/GetFileTime/test2/GetFileTime.cpp
index 5b14a1e357..5b14a1e357 100644
--- a/src/pal/tests/palsuite/file_io/GetFileTime/test2/GetFileTime.c
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test2/GetFileTime.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileTime/test3/CMakeLists.txt
index 34f7310464..bb88966e68 100644
--- a/src/pal/tests/palsuite/file_io/GetFileTime/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetFileTime.c
+ GetFileTime.cpp
)
add_executable(paltest_getfiletime_test3
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test3/GetFileTime.c b/src/pal/tests/palsuite/file_io/GetFileTime/test3/GetFileTime.cpp
index a3f46c2bf8..a3f46c2bf8 100644
--- a/src/pal/tests/palsuite/file_io/GetFileTime/test3/GetFileTime.c
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test3/GetFileTime.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test4/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileTime/test4/CMakeLists.txt
index 0c9dcf7802..e43e7f99a8 100644
--- a/src/pal/tests/palsuite/file_io/GetFileTime/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetFileTime.c
+ GetFileTime.cpp
)
add_executable(paltest_getfiletime_test4
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test4/GetFileTime.c b/src/pal/tests/palsuite/file_io/GetFileTime/test4/GetFileTime.cpp
index ffba516e35..ffba516e35 100644
--- a/src/pal/tests/palsuite/file_io/GetFileTime/test4/GetFileTime.c
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test4/GetFileTime.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test5/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileTime/test5/CMakeLists.txt
index a82717e657..4af995d207 100644
--- a/src/pal/tests/palsuite/file_io/GetFileTime/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- getfiletime.c
+ getfiletime.cpp
)
add_executable(paltest_getfiletime_test5
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test5/getfiletime.c b/src/pal/tests/palsuite/file_io/GetFileTime/test5/getfiletime.cpp
index d8196d84bc..d8196d84bc 100644
--- a/src/pal/tests/palsuite/file_io/GetFileTime/test5/getfiletime.c
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test5/getfiletime.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test6/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileTime/test6/CMakeLists.txt
index 24992dfa66..87c448b2a6 100644
--- a/src/pal/tests/palsuite/file_io/GetFileTime/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- getfiletime.c
+ getfiletime.cpp
)
add_executable(paltest_getfiletime_test6
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test6/getfiletime.c b/src/pal/tests/palsuite/file_io/GetFileTime/test6/getfiletime.cpp
index 3eedddf82d..3eedddf82d 100644
--- a/src/pal/tests/palsuite/file_io/GetFileTime/test6/getfiletime.c
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test6/getfiletime.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test7/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileTime/test7/CMakeLists.txt
index 6646fd9272..cd5cde4d9e 100644
--- a/src/pal/tests/palsuite/file_io/GetFileTime/test7/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test7/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- getfiletime.c
+ getfiletime.cpp
)
add_executable(paltest_getfiletime_test7
diff --git a/src/pal/tests/palsuite/file_io/GetFileTime/test7/getfiletime.c b/src/pal/tests/palsuite/file_io/GetFileTime/test7/getfiletime.cpp
index d33175b8ec..d33175b8ec 100644
--- a/src/pal/tests/palsuite/file_io/GetFileTime/test7/getfiletime.c
+++ b/src/pal/tests/palsuite/file_io/GetFileTime/test7/getfiletime.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetFileType/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileType/test1/CMakeLists.txt
index 66467e99c5..cfaba2e738 100644
--- a/src/pal/tests/palsuite/file_io/GetFileType/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetFileType/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetFileType.c
+ GetFileType.cpp
)
add_executable(paltest_getfiletype_test1
diff --git a/src/pal/tests/palsuite/file_io/GetFileType/test1/GetFileType.c b/src/pal/tests/palsuite/file_io/GetFileType/test1/GetFileType.cpp
index 6558c00bdd..6558c00bdd 100644
--- a/src/pal/tests/palsuite/file_io/GetFileType/test1/GetFileType.c
+++ b/src/pal/tests/palsuite/file_io/GetFileType/test1/GetFileType.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetFileType/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileType/test2/CMakeLists.txt
index 382b27e788..07dae0b04a 100644
--- a/src/pal/tests/palsuite/file_io/GetFileType/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetFileType/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- getfiletype.c
+ getfiletype.cpp
)
add_executable(paltest_getfiletype_test2
diff --git a/src/pal/tests/palsuite/file_io/GetFileType/test2/getfiletype.c b/src/pal/tests/palsuite/file_io/GetFileType/test2/getfiletype.cpp
index c9d4eb6572..c9d4eb6572 100644
--- a/src/pal/tests/palsuite/file_io/GetFileType/test2/getfiletype.c
+++ b/src/pal/tests/palsuite/file_io/GetFileType/test2/getfiletype.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetFileType/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFileType/test3/CMakeLists.txt
index 52b6077570..9353c85771 100644
--- a/src/pal/tests/palsuite/file_io/GetFileType/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetFileType/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- getfiletype.c
+ getfiletype.cpp
)
add_executable(paltest_getfiletype_test3
diff --git a/src/pal/tests/palsuite/file_io/GetFileType/test3/getfiletype.c b/src/pal/tests/palsuite/file_io/GetFileType/test3/getfiletype.cpp
index 6a95585bab..6a95585bab 100644
--- a/src/pal/tests/palsuite/file_io/GetFileType/test3/getfiletype.c
+++ b/src/pal/tests/palsuite/file_io/GetFileType/test3/getfiletype.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test1/CMakeLists.txt
index 8c10e479fa..6198392000 100644
--- a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetFullPathNameA.c
+ GetFullPathNameA.cpp
)
add_executable(paltest_getfullpathnamea_test1
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test1/GetFullPathNameA.c b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test1/GetFullPathNameA.cpp
index de9a266f5a..de9a266f5a 100644
--- a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test1/GetFullPathNameA.c
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test1/GetFullPathNameA.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test2/CMakeLists.txt
index 382b8fa4bd..3449f2d80b 100644
--- a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_getfullpathnamea_test2
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test2/test2.c b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test2/test2.cpp
index 95a1497331..95a1497331 100644
--- a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test2/test2.c
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test3/CMakeLists.txt
index f0f8929b4a..9d8d242e26 100644
--- a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_getfullpathnamea_test3
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test3/test3.c b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test3/test3.cpp
index 0cc39e7300..0cc39e7300 100644
--- a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test3/test3.c
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test4/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test4/CMakeLists.txt
index cf0d7ff18c..abf2bacd1c 100644
--- a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_getfullpathnamea_test4
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test4/test4.c b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test4/test4.cpp
index fb22c1f07b..fb22c1f07b 100644
--- a/src/pal/tests/palsuite/file_io/GetFullPathNameA/test4/test4.c
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameA/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test1/CMakeLists.txt
index a6f354f5a5..d455ca1193 100644
--- a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetFullPathNameW.c
+ GetFullPathNameW.cpp
)
add_executable(paltest_getfullpathnamew_test1
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test1/GetFullPathNameW.c b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test1/GetFullPathNameW.cpp
index 592d3ad4c5..592d3ad4c5 100644
--- a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test1/GetFullPathNameW.c
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test1/GetFullPathNameW.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test2/CMakeLists.txt
index 199aa1efce..d974e940a7 100644
--- a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_getfullpathnamew_test2
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test2/test2.c b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test2/test2.cpp
index fae042d229..fae042d229 100644
--- a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test2/test2.c
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test3/CMakeLists.txt
index 6284958b07..09439a6372 100644
--- a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_getfullpathnamew_test3
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test3/test3.c b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test3/test3.cpp
index ba80cf222d..ba80cf222d 100644
--- a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test3/test3.c
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test4/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test4/CMakeLists.txt
index d479b998cc..11ed9583b6 100644
--- a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_getfullpathnamew_test4
diff --git a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test4/test4.c b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test4/test4.cpp
index 25eb10d654..25eb10d654 100644
--- a/src/pal/tests/palsuite/file_io/GetFullPathNameW/test4/test4.c
+++ b/src/pal/tests/palsuite/file_io/GetFullPathNameW/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetLongPathNameW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetLongPathNameW/test1/CMakeLists.txt
index cf5dcd0bfc..3b9f0b118a 100644
--- a/src/pal/tests/palsuite/file_io/GetLongPathNameW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetLongPathNameW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetLongPathNameW.c
+ GetLongPathNameW.cpp
)
add_executable(paltest_getlongpathnamew_test1
diff --git a/src/pal/tests/palsuite/file_io/GetLongPathNameW/test1/GetLongPathNameW.c b/src/pal/tests/palsuite/file_io/GetLongPathNameW/test1/GetLongPathNameW.cpp
index 22831dda15..22831dda15 100644
--- a/src/pal/tests/palsuite/file_io/GetLongPathNameW/test1/GetLongPathNameW.c
+++ b/src/pal/tests/palsuite/file_io/GetLongPathNameW/test1/GetLongPathNameW.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetLongPathNameW/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetLongPathNameW/test2/CMakeLists.txt
index 5746ef3e04..b92e431095 100644
--- a/src/pal/tests/palsuite/file_io/GetLongPathNameW/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetLongPathNameW/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- getlongpathnamew.c
+ getlongpathnamew.cpp
)
add_executable(paltest_getlongpathnamew_test2
diff --git a/src/pal/tests/palsuite/file_io/GetLongPathNameW/test2/getlongpathnamew.c b/src/pal/tests/palsuite/file_io/GetLongPathNameW/test2/getlongpathnamew.cpp
index 3b033e9a64..3b033e9a64 100644
--- a/src/pal/tests/palsuite/file_io/GetLongPathNameW/test2/getlongpathnamew.c
+++ b/src/pal/tests/palsuite/file_io/GetLongPathNameW/test2/getlongpathnamew.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetStdHandle/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetStdHandle/test1/CMakeLists.txt
index 04bcc5fd67..eaa1721b7e 100644
--- a/src/pal/tests/palsuite/file_io/GetStdHandle/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetStdHandle/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetStdHandle.c
+ GetStdHandle.cpp
)
add_executable(paltest_getstdhandle_test1
diff --git a/src/pal/tests/palsuite/file_io/GetStdHandle/test1/GetStdHandle.c b/src/pal/tests/palsuite/file_io/GetStdHandle/test1/GetStdHandle.cpp
index f4fe03195d..f4fe03195d 100644
--- a/src/pal/tests/palsuite/file_io/GetStdHandle/test1/GetStdHandle.c
+++ b/src/pal/tests/palsuite/file_io/GetStdHandle/test1/GetStdHandle.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetStdHandle/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetStdHandle/test2/CMakeLists.txt
index 97816b4319..ef45aa0dec 100644
--- a/src/pal/tests/palsuite/file_io/GetStdHandle/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetStdHandle/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetStdHandle.c
+ GetStdHandle.cpp
)
add_executable(paltest_getstdhandle_test2
diff --git a/src/pal/tests/palsuite/file_io/GetStdHandle/test2/GetStdHandle.c b/src/pal/tests/palsuite/file_io/GetStdHandle/test2/GetStdHandle.cpp
index 45f5ddd243..45f5ddd243 100644
--- a/src/pal/tests/palsuite/file_io/GetStdHandle/test2/GetStdHandle.c
+++ b/src/pal/tests/palsuite/file_io/GetStdHandle/test2/GetStdHandle.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetSystemTime/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetSystemTime/test1/CMakeLists.txt
index 94d5bcded9..4367e880f7 100644
--- a/src/pal/tests/palsuite/file_io/GetSystemTime/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetSystemTime/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_getsystemtime_test1
diff --git a/src/pal/tests/palsuite/file_io/GetSystemTime/test1/test.c b/src/pal/tests/palsuite/file_io/GetSystemTime/test1/test.cpp
index 361dbef33d..361dbef33d 100644
--- a/src/pal/tests/palsuite/file_io/GetSystemTime/test1/test.c
+++ b/src/pal/tests/palsuite/file_io/GetSystemTime/test1/test.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/test1/CMakeLists.txt
index 977a826e7a..d149383732 100644
--- a/src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetSystemTimeAsFileTime.c
+ GetSystemTimeAsFileTime.cpp
)
add_executable(paltest_getsystemtimeasfiletime_test1
diff --git a/src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/test1/GetSystemTimeAsFileTime.c b/src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/test1/GetSystemTimeAsFileTime.cpp
index bd7e856abd..bd7e856abd 100644
--- a/src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/test1/GetSystemTimeAsFileTime.c
+++ b/src/pal/tests/palsuite/file_io/GetSystemTimeAsFileTime/test1/GetSystemTimeAsFileTime.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test1/CMakeLists.txt
index 1b759af2eb..4ed0ccb537 100644
--- a/src/pal/tests/palsuite/file_io/GetTempFileNameA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetTempFileNameA.c
+ GetTempFileNameA.cpp
)
add_executable(paltest_gettempfilenamea_test1
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameA/test1/GetTempFileNameA.c b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test1/GetTempFileNameA.c
deleted file mode 100644
index 8ede8bab04..0000000000
--- a/src/pal/tests/palsuite/file_io/GetTempFileNameA/test1/GetTempFileNameA.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: GetTempFileNameA.c (test 1)
-**
-** Purpose: Tests the PAL implementation of the GetTempFileNameA function.
-**
-** Depends on:
-** GetFileAttributesA
-** DeleteFileA
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-
-
-
-int __cdecl main(int argc, char *argv[])
-{
- UINT uiError = 0;
- const UINT uUnique = 0;
- const char* szDot = {"."};
- const char* szValidPrefix = {"cfr"};
- const char* szLongValidPrefix = {"cfrwxyz"};
- char szReturnedName[256];
- char szTempString[256];
-
- if (0 != PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
- /* valid path with null prefix */
- uiError = GetTempFileNameA(szDot, NULL, uUnique, szReturnedName);
- if (uiError == 0)
- {
- Fail("GetTempFileNameA: ERROR -> Call failed with a valid path "
- "with the error code: %ld\n", GetLastError());
- }
- else
- {
- /* verify temp file was created */
- if (GetFileAttributesA(szReturnedName) == -1)
- {
- Fail("GetTempFileNameA: ERROR -> GetFileAttributes failed on the "
- "returned temp file \"%s\" with error code: %ld.\n",
- szReturnedName,
- GetLastError());
- }
- if (DeleteFileA(szReturnedName) != TRUE)
- {
- Fail("GetTempFileNameA: ERROR -> DeleteFileW failed to delete"
- "the created temp file with error code: %ld.\n", GetLastError());
- }
- }
-
-
- /* valid path with valid prefix */
- uiError = GetTempFileNameA(szDot, szValidPrefix, uUnique, szReturnedName);
- if (uiError == 0)
- {
- Fail("GetTempFileNameA: ERROR -> Call failed with a valid path and "
- "prefix with the error code: %ld\n", GetLastError());
- }
- else
- {
- /* verify temp file was created */
- if (GetFileAttributesA(szReturnedName) == -1)
- {
- Fail("GetTempFileNameA: ERROR -> GetFileAttributes failed on the "
- "returned temp file \"%s\" with error code: %ld.\n",
- szReturnedName,
- GetLastError());
- }
- if (DeleteFileA(szReturnedName) != TRUE)
- {
- Fail("GetTempFileNameA: ERROR -> DeleteFileW failed to delete"
- "the created temp \"%s\" file with error code: %ld.\n",
- szReturnedName,
- GetLastError());
- }
- }
-
- /* valid path with long prefix */
- uiError = GetTempFileNameA(szDot, szLongValidPrefix, uUnique, szReturnedName);
- if (uiError == 0)
- {
- Fail("GetTempFileNameA: ERROR -> Call failed with a valid path and "
- "prefix with the error code: %ld\n", GetLastError());
- }
- else
- {
- /* verify temp file was created */
- if (GetFileAttributesA(szReturnedName) == -1)
- {
- Fail("GetTempFileNameA: ERROR -> GetFileAttributes failed on the "
- "returned temp file \"%s\" with error code: %ld.\n",
- szReturnedName,
- GetLastError());
- }
-
- /* now verify that it only used the first 3 characters of the prefix */
- sprintf(szTempString, "%s\\%s", szDot, szLongValidPrefix);
- if (strncmp(szTempString, szReturnedName, 6) == 0)
- {
- Fail("GetTempFileNameA: ERROR -> It appears that an improper prefix "
- "was used.\n");
- }
-
- if (DeleteFileA(szReturnedName) != TRUE)
- {
- Fail("GetTempFileNameA: ERROR -> DeleteFileW failed to delete"
- "the created temp file \"%s\" with error code: %ld.\n",
- szReturnedName,
- GetLastError());
- }
- }
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameA/test1/GetTempFileNameA.cpp b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test1/GetTempFileNameA.cpp
new file mode 100644
index 0000000000..bea8e2776e
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test1/GetTempFileNameA.cpp
@@ -0,0 +1,125 @@
+// Licensed to the .NET Foundation under one or more 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: GetTempFileNameA.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the GetTempFileNameA function.
+**
+** Depends on:
+** GetFileAttributesA
+** DeleteFileA
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ UINT uiError = 0;
+ const UINT uUnique = 0;
+ const char* szDot = {"."};
+ const char* szValidPrefix = {"cfr"};
+ const char* szLongValidPrefix = {"cfrwxyz"};
+ char szReturnedName[256];
+ char szTempString[256];
+
+ if (0 != PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ /* valid path with null prefix */
+ uiError = GetTempFileNameA(szDot, NULL, uUnique, szReturnedName);
+ if (uiError == 0)
+ {
+ Fail("GetTempFileNameA: ERROR -> Call failed with a valid path "
+ "with the error code: %ld\n", GetLastError());
+ }
+ else
+ {
+ /* verify temp file was created */
+ if (GetFileAttributesA(szReturnedName) == -1)
+ {
+ Fail("GetTempFileNameA: ERROR -> GetFileAttributes failed on the "
+ "returned temp file \"%s\" with error code: %ld.\n",
+ szReturnedName,
+ GetLastError());
+ }
+ if (DeleteFileA(szReturnedName) != TRUE)
+ {
+ Fail("GetTempFileNameA: ERROR -> DeleteFileW failed to delete"
+ "the created temp file with error code: %ld.\n", GetLastError());
+ }
+ }
+
+
+ /* valid path with valid prefix */
+ uiError = GetTempFileNameA(szDot, szValidPrefix, uUnique, szReturnedName);
+ if (uiError == 0)
+ {
+ Fail("GetTempFileNameA: ERROR -> Call failed with a valid path and "
+ "prefix with the error code: %ld\n", GetLastError());
+ }
+ else
+ {
+ /* verify temp file was created */
+ if (GetFileAttributesA(szReturnedName) == -1)
+ {
+ Fail("GetTempFileNameA: ERROR -> GetFileAttributes failed on the "
+ "returned temp file \"%s\" with error code: %ld.\n",
+ szReturnedName,
+ GetLastError());
+ }
+ if (DeleteFileA(szReturnedName) != TRUE)
+ {
+ Fail("GetTempFileNameA: ERROR -> DeleteFileW failed to delete"
+ "the created temp \"%s\" file with error code: %ld.\n",
+ szReturnedName,
+ GetLastError());
+ }
+ }
+
+ /* valid path with long prefix */
+ uiError = GetTempFileNameA(szDot, szLongValidPrefix, uUnique, szReturnedName);
+ if (uiError == 0)
+ {
+ Fail("GetTempFileNameA: ERROR -> Call failed with a valid path and "
+ "prefix with the error code: %ld\n", GetLastError());
+ }
+ else
+ {
+ /* verify temp file was created */
+ if (GetFileAttributesA(szReturnedName) == -1)
+ {
+ Fail("GetTempFileNameA: ERROR -> GetFileAttributes failed on the "
+ "returned temp file \"%s\" with error code: %ld.\n",
+ szReturnedName,
+ GetLastError());
+ }
+
+ /* now verify that it only used the first 3 characters of the prefix */
+ sprintf_s(szTempString, _countof(szTempString), "%s\\%s", szDot, szLongValidPrefix);
+ if (strncmp(szTempString, szReturnedName, 6) == 0)
+ {
+ Fail("GetTempFileNameA: ERROR -> It appears that an improper prefix "
+ "was used.\n");
+ }
+
+ if (DeleteFileA(szReturnedName) != TRUE)
+ {
+ Fail("GetTempFileNameA: ERROR -> DeleteFileW failed to delete"
+ "the created temp file \"%s\" with error code: %ld.\n",
+ szReturnedName,
+ GetLastError());
+ }
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameA/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test2/CMakeLists.txt
index f4bd9b8797..9d9b6461cd 100644
--- a/src/pal/tests/palsuite/file_io/GetTempFileNameA/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetTempFileNameA.c
+ GetTempFileNameA.cpp
)
add_executable(paltest_gettempfilenamea_test2
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameA/test2/GetTempFileNameA.c b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test2/GetTempFileNameA.cpp
index 861a8b87e8..861a8b87e8 100644
--- a/src/pal/tests/palsuite/file_io/GetTempFileNameA/test2/GetTempFileNameA.c
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test2/GetTempFileNameA.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameA/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test3/CMakeLists.txt
index 9c02865575..446f3cf837 100644
--- a/src/pal/tests/palsuite/file_io/GetTempFileNameA/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- gettempfilenamea.c
+ gettempfilenamea.cpp
)
add_executable(paltest_gettempfilenamea_test3
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameA/test3/gettempfilenamea.c b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test3/gettempfilenamea.cpp
index 8eccc3d2e8..8eccc3d2e8 100644
--- a/src/pal/tests/palsuite/file_io/GetTempFileNameA/test3/gettempfilenamea.c
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameA/test3/gettempfilenamea.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test1/CMakeLists.txt
index 1b6c599da4..6919cf66cd 100644
--- a/src/pal/tests/palsuite/file_io/GetTempFileNameW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetTempFileNameW.c
+ GetTempFileNameW.cpp
)
add_executable(paltest_gettempfilenamew_test1
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameW/test1/GetTempFileNameW.c b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test1/GetTempFileNameW.cpp
index 43cda8f447..43cda8f447 100644
--- a/src/pal/tests/palsuite/file_io/GetTempFileNameW/test1/GetTempFileNameW.c
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test1/GetTempFileNameW.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameW/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test2/CMakeLists.txt
index 851030d9ae..d077463390 100644
--- a/src/pal/tests/palsuite/file_io/GetTempFileNameW/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetTempFileNameW.c
+ GetTempFileNameW.cpp
)
add_executable(paltest_gettempfilenamew_test2
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameW/test2/GetTempFileNameW.c b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test2/GetTempFileNameW.cpp
index 2c8b19e081..2c8b19e081 100644
--- a/src/pal/tests/palsuite/file_io/GetTempFileNameW/test2/GetTempFileNameW.c
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test2/GetTempFileNameW.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameW/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test3/CMakeLists.txt
index 82dd0a9f3f..3aa0f4a044 100644
--- a/src/pal/tests/palsuite/file_io/GetTempFileNameW/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- gettempfilenamew.c
+ gettempfilenamew.cpp
)
add_executable(paltest_gettempfilenamew_test3
diff --git a/src/pal/tests/palsuite/file_io/GetTempFileNameW/test3/gettempfilenamew.c b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test3/gettempfilenamew.cpp
index 96d8e66410..96d8e66410 100644
--- a/src/pal/tests/palsuite/file_io/GetTempFileNameW/test3/gettempfilenamew.c
+++ b/src/pal/tests/palsuite/file_io/GetTempFileNameW/test3/gettempfilenamew.cpp
diff --git a/src/pal/tests/palsuite/file_io/GetTempPathW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/GetTempPathW/test1/CMakeLists.txt
index f2979e9536..04b240997a 100644
--- a/src/pal/tests/palsuite/file_io/GetTempPathW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/GetTempPathW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetTempPathW.c
+ GetTempPathW.cpp
)
add_executable(paltest_gettemppathw_test1
diff --git a/src/pal/tests/palsuite/file_io/GetTempPathW/test1/GetTempPathW.c b/src/pal/tests/palsuite/file_io/GetTempPathW/test1/GetTempPathW.c
deleted file mode 100644
index 08c88075ca..0000000000
--- a/src/pal/tests/palsuite/file_io/GetTempPathW/test1/GetTempPathW.c
+++ /dev/null
@@ -1,103 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: GetTempPathW.c (test 1)
-**
-** Purpose: Tests the PAL implementation of the GetTempPathW function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-
-static void SetTmpDir(WCHAR path[])
-{
- DWORD result = SetEnvironmentVariableW(W("TMPDIR"), path);
- if (!result)
- {
- Fail("ERROR -> SetEnvironmentVariableW failed with result %d and error code %d.\n",
- result, GetLastError());
- }
-}
-
-static void SetAndCompare(WCHAR tmpDirPath[], WCHAR expected[])
-{
- DWORD dwBufferLength = _MAX_DIR;
- WCHAR path[dwBufferLength];
-
- SetTmpDir(tmpDirPath);
-
- DWORD dwResultLen = GetTempPathW(dwBufferLength, path);
- if (dwResultLen <= 0)
- {
- Fail("ERROR: GetTempPathW returned %d with error code %d.\n", dwResultLen, GetLastError());
- }
- if (dwResultLen >= dwBufferLength)
- {
- Fail("ERROR: Buffer of length %d passed to GetTempPathA was too small to hold %d chars..\n", dwBufferLength, dwResultLen);
- }
- if (wcscmp(expected, path) != 0)
- {
- Fail("ERROR: GetTempPathW expected to get '%S' but instead got '%S'.\n", expected, path);
- }
- if (expected[dwResultLen - 1] != '/')
- {
- Fail("ERROR: GetTempPathW returned '%S', which should have ended in '/'.\n", path);
- }
-}
-
-static void SetAndCheckLength(WCHAR tmpDirPath [], int bufferLength, int expectedResultLength)
-{
- WCHAR path[bufferLength];
-
- SetTmpDir(tmpDirPath);
- DWORD dwResultLen = GetTempPathW(bufferLength, path);
-
- if (dwResultLen != expectedResultLength)
- {
- Fail("GetTempPathW(%d, %S) expected to return %d but returned %d.\n",
- bufferLength, tmpDirPath?tmpDirPath:W("NULL"), expectedResultLength, dwResultLen);
- }
-}
-
-int __cdecl main(int argc, char *argv[])
-{
- if (0 != PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
- SetAndCompare(W("/tmp"), W("/tmp/"));
- SetAndCompare(W("/tmp/"), W("/tmp/"));
- SetAndCompare(W(""), W("/tmp/"));
- SetAndCompare(NULL, W("/tmp/"));
- SetAndCompare(W("/"), W("/"));
- SetAndCompare(W("/var/tmp"), W("/var/tmp/"));
- SetAndCompare(W("/var/tmp/"), W("/var/tmp/"));
- SetAndCompare(W("~"), W("~/"));
- SetAndCompare(W("~/"), W("~/"));
- SetAndCompare(W(".tmp"), W(".tmp/"));
- SetAndCompare(W("./tmp"), W("./tmp/"));
- SetAndCompare(W("/home/someuser/sometempdir"), W("/home/someuser/sometempdir/"));
- SetAndCompare(NULL, W("/tmp/"));
-
- DWORD dwResultLen = GetTempPathA(0, NULL);
- if (dwResultLen != 0 || GetLastError() != ERROR_INVALID_PARAMETER)
- {
- Fail("GetTempPathW(NULL, ...) returned %d with error code %d but "
- "should have failed with ERROR_INVALID_PARAMETER (%d).\n",
- dwResultLen, GetLastError(), ERROR_INVALID_PARAMETER);
- }
-
- SetAndCheckLength(W("abc/"), 5, 4);
- SetAndCheckLength(W("abcd"), 5, 6);
- SetAndCheckLength(W("abcde"), 5, 7);
- SetAndCheckLength(W("abcdef/"), 5, 9);
- SetAndCheckLength(NULL, 5, 6);
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/file_io/GetTempPathW/test1/GetTempPathW.cpp b/src/pal/tests/palsuite/file_io/GetTempPathW/test1/GetTempPathW.cpp
new file mode 100644
index 0000000000..bf997def76
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/GetTempPathW/test1/GetTempPathW.cpp
@@ -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.
+
+/*=====================================================================
+**
+** Source: GetTempPathW.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the GetTempPathW function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+static void SetTmpDir(const WCHAR path[])
+{
+ DWORD result = SetEnvironmentVariableW(W("TMPDIR"), path);
+ if (!result)
+ {
+ Fail("ERROR -> SetEnvironmentVariableW failed with result %d and error code %d.\n",
+ result, GetLastError());
+ }
+}
+
+static void SetAndCompare(const WCHAR tmpDirPath[], const WCHAR expected[])
+{
+ DWORD dwBufferLength = _MAX_DIR;
+ WCHAR path[dwBufferLength];
+
+ SetTmpDir(tmpDirPath);
+
+ DWORD dwResultLen = GetTempPathW(dwBufferLength, path);
+ if (dwResultLen <= 0)
+ {
+ Fail("ERROR: GetTempPathW returned %d with error code %d.\n", dwResultLen, GetLastError());
+ }
+ if (dwResultLen >= dwBufferLength)
+ {
+ Fail("ERROR: Buffer of length %d passed to GetTempPathA was too small to hold %d chars..\n", dwBufferLength, dwResultLen);
+ }
+ if (wcscmp(expected, path) != 0)
+ {
+ Fail("ERROR: GetTempPathW expected to get '%S' but instead got '%S'.\n", expected, path);
+ }
+ if (expected[dwResultLen - 1] != '/')
+ {
+ Fail("ERROR: GetTempPathW returned '%S', which should have ended in '/'.\n", path);
+ }
+}
+
+static void SetAndCheckLength(const WCHAR tmpDirPath [], int bufferLength, int expectedResultLength)
+{
+ WCHAR path[bufferLength];
+
+ SetTmpDir(tmpDirPath);
+ DWORD dwResultLen = GetTempPathW(bufferLength, path);
+
+ if (dwResultLen != expectedResultLength)
+ {
+ Fail("GetTempPathW(%d, %S) expected to return %d but returned %d.\n",
+ bufferLength, tmpDirPath?tmpDirPath:W("NULL"), expectedResultLength, dwResultLen);
+ }
+}
+
+int __cdecl main(int argc, char *argv[])
+{
+ if (0 != PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ SetAndCompare(W("/tmp"), W("/tmp/"));
+ SetAndCompare(W("/tmp/"), W("/tmp/"));
+ SetAndCompare(W(""), W("/tmp/"));
+ SetAndCompare(NULL, W("/tmp/"));
+ SetAndCompare(W("/"), W("/"));
+ SetAndCompare(W("/var/tmp"), W("/var/tmp/"));
+ SetAndCompare(W("/var/tmp/"), W("/var/tmp/"));
+ SetAndCompare(W("~"), W("~/"));
+ SetAndCompare(W("~/"), W("~/"));
+ SetAndCompare(W(".tmp"), W(".tmp/"));
+ SetAndCompare(W("./tmp"), W("./tmp/"));
+ SetAndCompare(W("/home/someuser/sometempdir"), W("/home/someuser/sometempdir/"));
+ SetAndCompare(NULL, W("/tmp/"));
+
+ DWORD dwResultLen = GetTempPathA(0, NULL);
+ if (dwResultLen != 0 || GetLastError() != ERROR_INVALID_PARAMETER)
+ {
+ Fail("GetTempPathW(NULL, ...) returned %d with error code %d but "
+ "should have failed with ERROR_INVALID_PARAMETER (%d).\n",
+ dwResultLen, GetLastError(), ERROR_INVALID_PARAMETER);
+ }
+
+ SetAndCheckLength(W("abc/"), 5, 4);
+ SetAndCheckLength(W("abcd"), 5, 6);
+ SetAndCheckLength(W("abcde"), 5, 7);
+ SetAndCheckLength(W("abcdef/"), 5, 9);
+ SetAndCheckLength(NULL, 5, 6);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/MoveFileA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/MoveFileA/test1/CMakeLists.txt
index 9a3d0069db..b096a04653 100644
--- a/src/pal/tests/palsuite/file_io/MoveFileA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/MoveFileA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- MoveFileA.c
+ MoveFileA.cpp
)
add_executable(paltest_movefilea_test1
diff --git a/src/pal/tests/palsuite/file_io/MoveFileA/test1/MoveFileA.c b/src/pal/tests/palsuite/file_io/MoveFileA/test1/MoveFileA.c
deleted file mode 100644
index 8d1bc0eded..0000000000
--- a/src/pal/tests/palsuite/file_io/MoveFileA/test1/MoveFileA.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: MoveFileA.c
-**
-** Purpose: Tests the PAL implementation of the MoveFileA function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-
-LPSTR lpSource[4] = {"src_existing.txt",
- "src_non-existant.txt",
- "src_dir_existing",
- "src_dir_non-existant"};
-LPSTR lpDestination[4] = {"dst_existing.txt",
- "dst_non-existant.txt",
- "dst_dir_existing",
- "dst_dir_non-existant"};
-
-
-/* Create all the required test files */
-int createExisting(void)
-{
- FILE* tempFile = NULL;
- DWORD dwError;
- BOOL bRc = FALSE;
- char szBuffer[100];
-
- /* create the src_existing file */
- tempFile = fopen(lpSource[0], "w");
- if (tempFile != NULL)
- {
- fprintf(tempFile, "MoveFileA test file: src_existing.txt\n");
- fclose(tempFile);
- }
- else
- {
- Trace("ERROR: couldn't create %s\n", lpSource[0]);
- return FAIL;
- }
-
- /* create the src_dir_existing directory and files */
- bRc = CreateDirectoryA(lpSource[2], NULL);
- if (bRc != TRUE)
- {
- Trace("MoveFileA: ERROR: couldn't create \"%s\" because of "
- "error code %ld\n",
- lpSource[2],
- GetLastError());
- return FAIL;
- }
-
- memset(szBuffer, 0, 100);
- sprintf(szBuffer, "%s/test01.txt", lpSource[2]);
- tempFile = fopen(szBuffer, "w");
- if (tempFile != NULL)
- {
- fprintf(tempFile, "MoveFileA test file: %s\n", szBuffer);
- fclose(tempFile);
- }
- else
- {
- Trace("ERROR[%ld]:MoveFileA couldn't create %s\n", GetLastError(), szBuffer);
- return FAIL;
- }
-
- memset(szBuffer, 0, 100);
- sprintf(szBuffer, "%s/test02.txt", lpSource[2]);
- tempFile = fopen(szBuffer, "w");
- if (tempFile != NULL)
- {
- fprintf(tempFile, "MoveFileA test file: %s\n", szBuffer);
- fclose(tempFile);
- }
- else
- {
- Trace("ERROR[%ld]: couldn't create %s\n", GetLastError(), szBuffer);
- return FAIL;
- }
-
-
- /* create the dst_existing file */
- tempFile = fopen(lpDestination[0], "w");
- if (tempFile != NULL)
- {
- fprintf(tempFile, "MoveFileA test file: dst_existing.txt\n");
- fclose(tempFile);
- }
- else
- {
- Trace("ERROR[%ld]:MoveFileA couldn't create \"%s\"\n", GetLastError(), lpDestination[0]);
- return FAIL;
- }
-
- /* create the dst_dir_existing directory and files */
- bRc = CreateDirectoryA(lpDestination[2], NULL);
- if (bRc != TRUE)
- {
- dwError = GetLastError();
- Trace("Error[%ld]:MoveFileA: couldn't create \"%s\"\n", GetLastError(), lpDestination[2]);
- return FAIL;
- }
-
- tempFile = fopen("dst_dir_existing/test01.txt", "w");
- if (tempFile != NULL)
- {
- fprintf(tempFile, "MoveFileA test file: dst_dir_existing/test01.txt\n");
- fclose(tempFile);
- }
- else
- {
- Trace("ERROR: couldn't create dst_dir_existing/test01.txt\n");
- return FAIL;
- }
- tempFile = fopen("dst_dir_existing/test02.txt", "w");
- if (tempFile != NULL)
- {
- fprintf(tempFile, "MoveFileA test file: dst_dir_existing/test02.txt\n");
- fclose(tempFile);
- }
- else
- {
- Trace("ERROR[%ul]: couldn't create dst_dir_existing/test02.txt\n", GetLastError());
- return FAIL;
- }
-
- return PASS;
-}
-
-
-
-void removeDirectoryHelper(LPSTR dir, int location)
-{
- DWORD dwAtt = GetFileAttributesA(dir);
- if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
- {
- if(!RemoveDirectoryA(dir))
- {
- Fail("ERROR: Failed to remove Directory [%s], Error Code [%d], location [%d]\n", dir, GetLastError(), location);
- }
- }
-}
-
-void removeFileHelper(LPSTR pfile, int location)
-{
- FILE *fp;
- fp = fopen( pfile, "r");
-
- if (fp != NULL)
- {
- if(fclose(fp))
- {
- Fail("ERROR: Failed to close the file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
- }
-
- if(!DeleteFileA(pfile))
- {
- Fail("ERROR: Failed to delete file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
- }
- else
- {
- // Trace("Success: deleted file [%S], Error Code [%d], location [%d]\n", wfile, GetLastError(), location);
- }
- }
-
-}
-
-
-/* remove all created files in preparation for the next test */
-void removeAll(void)
-{
- char szTemp[40];
- DWORD dwAtt;
-
- /* get rid of source dirs and files */
- removeFileHelper(lpSource[0], 1);
- removeFileHelper(lpSource[1], 2);
-
- dwAtt = GetFileAttributesA(lpSource[2]);
- if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
- {
- sprintf(szTemp, "%s/test01.txt", lpSource[2]);
- removeFileHelper(szTemp, 18);
-
- sprintf(szTemp, "%s/test02.txt", lpSource[2]);
- removeFileHelper(szTemp, 19);
- removeDirectoryHelper(lpSource[2], 103);
- }
- else
- {
- removeFileHelper(lpSource[2], 17);
- }
-
-
- dwAtt = GetFileAttributesA(lpSource[3]);
- if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
- {
- sprintf(szTemp, "%s/test01.txt", lpSource[3]);
- removeFileHelper(szTemp, 18);
-
- sprintf(szTemp, "%s/test02.txt", lpSource[3]);
- removeFileHelper(szTemp, 19);
- removeDirectoryHelper(lpSource[3], 103);
- }
- else
- {
- removeFileHelper(lpSource[3], 17);
- }
-
- /* get rid of destination dirs and files */
- dwAtt = GetFileAttributesA(lpDestination[0]);
- if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
- {
- sprintf(szTemp, "%s/test01.txt", lpDestination[0]);
- removeFileHelper(szTemp, 18);
-
- sprintf(szTemp, "%s/test02.txt", lpDestination[0]);
- removeFileHelper(szTemp, 19);
- removeDirectoryHelper(lpDestination[0], 103);
- }
- else
- {
- removeFileHelper(lpDestination[0], 17);
- }
-
- dwAtt = GetFileAttributesA(lpDestination[1]);
- if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
- {
- sprintf(szTemp, "%s/test01.txt", lpDestination[1]);
- removeFileHelper(szTemp, 18);
-
- sprintf(szTemp, "%s/test02.txt", lpDestination[1]);
- removeFileHelper(szTemp, 19);
- removeDirectoryHelper(lpDestination[1], 103);
- }
- else
- {
- removeFileHelper(lpDestination[1], 17);
- }
-
- dwAtt = GetFileAttributesA(lpDestination[2]);
- if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
- {
- sprintf(szTemp, "%s/test01.txt", lpDestination[2]);
- removeFileHelper(szTemp, 18);
-
- sprintf(szTemp, "%s/test02.txt", lpDestination[2]);
- removeFileHelper(szTemp, 19);
- removeDirectoryHelper(lpDestination[2], 103);
- }
- else
- {
- removeFileHelper(lpDestination[2], 17);
- }
-
- dwAtt = GetFileAttributesA(lpDestination[3]);
- if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
- {
- sprintf(szTemp, "%s/test01.txt", lpDestination[3]);
- removeFileHelper(szTemp, 18);
-
- sprintf(szTemp, "%s/test02.txt", lpDestination[3]);
- removeFileHelper(szTemp, 19);
- removeDirectoryHelper(lpDestination[3], 103);
- }
- else
- {
- removeFileHelper(lpDestination[3], 17);
- }
-
-}
-
-
-
-
-
-int __cdecl main(int argc, char *argv[])
-{
- BOOL bRc = TRUE;
- BOOL bSuccess = TRUE;
- char results[40];
- FILE* resultsFile = NULL;
- int nCounter = 0;
- int i, j;
- char tempSource[] = {'t','e','m','p','k','.','t','m','p','\0'};
- char tempDest[] = {'t','e','m','p','2','.','t','m','p','\0'};
- HANDLE hFile;
- DWORD result;
-
- if (0 != PAL_Initialize(argc,argv))
- {
- return FAIL;
- }
-
- /* read in the expected results to compare with actual results */
- memset (results, 0, 20);
- resultsFile = fopen("expectedresults.txt", "r");
- if (resultsFile == NULL)
- {
- Fail("MoveFileA ERROR[%ul]: Unable to open \"expectedresults.txt\"\n", GetLastError());
- }
-
- fgets(results, 20, resultsFile);
- fclose(resultsFile);
-
- /* clean the slate */
- removeAll();
-
- if (createExisting() != 0)
- {
- removeAll();
- }
-
-
- /* lpSource loop */
- for (i = 0; i < 4; i++)
- {
- /* lpDestination loop */
- for (j = 0; j < 4; j++)
- {
- bRc = MoveFileA(lpSource[i], lpDestination[j]);
- if (!(
- ((bRc == TRUE) && (results[nCounter] == '1'))
- ||
- ((bRc == FALSE ) && (results[nCounter] == '0')) )
- )
- {
- Trace("MoveFileA: FAILED: test[%d][%d]: \"%s\" -> \"%s\"\n",
- i, j, lpSource[i], lpDestination[j]);
- bSuccess = FALSE;
- }
-
- /* undo the last move */
- removeAll();
- createExisting();
-
- nCounter++;
- }
- }
-
- removeAll();
- if (bSuccess == FALSE)
- {
- Fail("MoveFileA: Test Failed");
- }
-
- /* create the temp source file */
- hFile = CreateFileA(tempSource, GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL, 0);
-
- if( hFile == INVALID_HANDLE_VALUE )
- {
- Fail("Error[%ul]:MoveFileA: CreateFile failed to "
- "create the file correctly.\n", GetLastError());
- }
-
- bRc = CloseHandle(hFile);
- if(!bRc)
- {
- Trace("MoveFileA: CloseHandle failed to close the "
- "handle correctly. ERROR:%u\n",GetLastError());
-
- /* delete the created file */
- bRc = DeleteFileA(tempSource);
- if(!bRc)
- {
- Fail("Error[%ul]:MoveFileA: DeleteFileA failed to delete the"
- "file correctly.\n", GetLastError());
- }
- Fail("");
- }
-
- /* set the file attributes to be readonly */
- bRc = SetFileAttributesA(tempSource, FILE_ATTRIBUTE_READONLY);
- if(!bRc)
- {
- Trace("MoveFileA: SetFileAttributes failed to set file "
- "attributes correctly. GetLastError returned %u\n",GetLastError());
- /* delete the created file */
- bRc = DeleteFileA(tempSource);
- if(!bRc)
- {
- Fail("Error[%ul]:MoveFileA: DeleteFileA failed to delete the"
- "file correctly.\n", GetLastError());
- }
- Fail("");
- }
-
- /* move the file to the new location */
- bRc = MoveFileA(tempSource, tempDest);
- if(!bRc)
- {
- /* delete the created file */
- bRc = DeleteFileA(tempSource);
- if(!bRc)
- {
- Fail("Error[%ul]:MoveFileA: DeleteFileA failed to delete the"
- "file correctly.\n", GetLastError());
- }
-
- Fail("Error[%ul]:MoveFileA(%S, %S): GetFileAttributes "
- "failed to get the file's attributes.\n",
- GetLastError(), tempSource, tempDest);
- }
-
- /* check that the newly moved file has the same file attributes
- as the original */
- result = GetFileAttributesA(tempDest);
- if(result == 0)
- {
- /* delete the created file */
- bRc = DeleteFileA(tempDest);
- if(!bRc)
- {
- Fail("Error[%ul]:MoveFileA: DeleteFileA failed to delete the"
- "file correctly.\n", GetLastError());
- }
-
- Fail("Error[%ul]:MoveFileA: GetFileAttributes failed to get "
- "the file's attributes.\n", GetLastError());
- }
-
- if((result & FILE_ATTRIBUTE_READONLY) != FILE_ATTRIBUTE_READONLY)
- {
- /* delete the newly moved file */
- bRc = DeleteFileA(tempDest);
- if(!bRc)
- {
- Fail("Error[%ul]:MoveFileA: DeleteFileA failed to delete the"
- "file correctly.\n", GetLastError());
- }
-
- Fail("Error[%ul]MoveFileA: GetFileAttributes failed to get "
- "the correct file attributes.\n", GetLastError());
- }
-
- /* set the file attributes back to normal, to be deleted */
- bRc = SetFileAttributesA(tempDest, FILE_ATTRIBUTE_NORMAL);
- if(!bRc)
- {
- /* delete the newly moved file */
- bRc = DeleteFileA(tempDest);
- if(!bRc)
- {
- Fail("Error[%ul]:MoveFileA: DeleteFileA failed to delete the"
- "file correctly.\n", GetLastError());
- }
-
- Fail("Error[%ul]:MoveFileA: SetFileAttributes failed to set "
- "file attributes correctly.\n", GetLastError());
- }
-
- /* delete the newly moved file */
- bRc = DeleteFileA(tempDest);
- if(!bRc)
- {
- Fail("Error[%ul]:MoveFileA: DeleteFileA failed to delete the"
- "file correctly.\n", GetLastError());
- }
-
- PAL_Terminate();
-
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/file_io/MoveFileA/test1/MoveFileA.cpp b/src/pal/tests/palsuite/file_io/MoveFileA/test1/MoveFileA.cpp
new file mode 100644
index 0000000000..6d1337af03
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/MoveFileA/test1/MoveFileA.cpp
@@ -0,0 +1,469 @@
+// Licensed to the .NET Foundation under one or more 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: MoveFileA.c
+**
+** Purpose: Tests the PAL implementation of the MoveFileA function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+LPSTR lpSource[4] = {"src_existing.txt",
+ "src_non-existant.txt",
+ "src_dir_existing",
+ "src_dir_non-existant"};
+LPSTR lpDestination[4] = {"dst_existing.txt",
+ "dst_non-existant.txt",
+ "dst_dir_existing",
+ "dst_dir_non-existant"};
+
+
+/* Create all the required test files */
+int createExisting(void)
+{
+ FILE* tempFile = NULL;
+ DWORD dwError;
+ BOOL bRc = FALSE;
+ char szBuffer[100];
+
+ /* create the src_existing file */
+ tempFile = fopen(lpSource[0], "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "MoveFileA test file: src_existing.txt\n");
+ fclose(tempFile);
+ }
+ else
+ {
+ Trace("ERROR: couldn't create %s\n", lpSource[0]);
+ return FAIL;
+ }
+
+ /* create the src_dir_existing directory and files */
+ bRc = CreateDirectoryA(lpSource[2], NULL);
+ if (bRc != TRUE)
+ {
+ Trace("MoveFileA: ERROR: couldn't create \"%s\" because of "
+ "error code %ld\n",
+ lpSource[2],
+ GetLastError());
+ return FAIL;
+ }
+
+ memset(szBuffer, 0, 100);
+ sprintf_s(szBuffer, _countof(szBuffer), "%s/test01.txt", lpSource[2]);
+ tempFile = fopen(szBuffer, "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "MoveFileA test file: %s\n", szBuffer);
+ fclose(tempFile);
+ }
+ else
+ {
+ Trace("ERROR[%ld]:MoveFileA couldn't create %s\n", GetLastError(), szBuffer);
+ return FAIL;
+ }
+
+ memset(szBuffer, 0, 100);
+ sprintf_s(szBuffer, _countof(szBuffer), "%s/test02.txt", lpSource[2]);
+ tempFile = fopen(szBuffer, "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "MoveFileA test file: %s\n", szBuffer);
+ fclose(tempFile);
+ }
+ else
+ {
+ Trace("ERROR[%ld]: couldn't create %s\n", GetLastError(), szBuffer);
+ return FAIL;
+ }
+
+
+ /* create the dst_existing file */
+ tempFile = fopen(lpDestination[0], "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "MoveFileA test file: dst_existing.txt\n");
+ fclose(tempFile);
+ }
+ else
+ {
+ Trace("ERROR[%ld]:MoveFileA couldn't create \"%s\"\n", GetLastError(), lpDestination[0]);
+ return FAIL;
+ }
+
+ /* create the dst_dir_existing directory and files */
+ bRc = CreateDirectoryA(lpDestination[2], NULL);
+ if (bRc != TRUE)
+ {
+ dwError = GetLastError();
+ Trace("Error[%ld]:MoveFileA: couldn't create \"%s\"\n", GetLastError(), lpDestination[2]);
+ return FAIL;
+ }
+
+ tempFile = fopen("dst_dir_existing/test01.txt", "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "MoveFileA test file: dst_dir_existing/test01.txt\n");
+ fclose(tempFile);
+ }
+ else
+ {
+ Trace("ERROR: couldn't create dst_dir_existing/test01.txt\n");
+ return FAIL;
+ }
+ tempFile = fopen("dst_dir_existing/test02.txt", "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "MoveFileA test file: dst_dir_existing/test02.txt\n");
+ fclose(tempFile);
+ }
+ else
+ {
+ Trace("ERROR[%ul]: couldn't create dst_dir_existing/test02.txt\n", GetLastError());
+ return FAIL;
+ }
+
+ return PASS;
+}
+
+
+
+void removeDirectoryHelper(LPSTR dir, int location)
+{
+ DWORD dwAtt = GetFileAttributesA(dir);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ if(!RemoveDirectoryA(dir))
+ {
+ Fail("ERROR: Failed to remove Directory [%s], Error Code [%d], location [%d]\n", dir, GetLastError(), location);
+ }
+ }
+}
+
+void removeFileHelper(LPSTR pfile, int location)
+{
+ FILE *fp;
+ fp = fopen( pfile, "r");
+
+ if (fp != NULL)
+ {
+ if(fclose(fp))
+ {
+ Fail("ERROR: Failed to close the file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
+ }
+
+ if(!DeleteFileA(pfile))
+ {
+ Fail("ERROR: Failed to delete file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
+ }
+ else
+ {
+ // Trace("Success: deleted file [%S], Error Code [%d], location [%d]\n", wfile, GetLastError(), location);
+ }
+ }
+
+}
+
+
+/* remove all created files in preparation for the next test */
+void removeAll(void)
+{
+ char szTemp[40];
+ DWORD dwAtt;
+
+ /* get rid of source dirs and files */
+ removeFileHelper(lpSource[0], 1);
+ removeFileHelper(lpSource[1], 2);
+
+ dwAtt = GetFileAttributesA(lpSource[2]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ sprintf_s(szTemp, _countof(szTemp), "%s/test01.txt", lpSource[2]);
+ removeFileHelper(szTemp, 18);
+
+ sprintf_s(szTemp, _countof(szTemp), "%s/test02.txt", lpSource[2]);
+ removeFileHelper(szTemp, 19);
+ removeDirectoryHelper(lpSource[2], 103);
+ }
+ else
+ {
+ removeFileHelper(lpSource[2], 17);
+ }
+
+
+ dwAtt = GetFileAttributesA(lpSource[3]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ sprintf_s(szTemp, _countof(szTemp), "%s/test01.txt", lpSource[3]);
+ removeFileHelper(szTemp, 18);
+
+ sprintf_s(szTemp, _countof(szTemp), "%s/test02.txt", lpSource[3]);
+ removeFileHelper(szTemp, 19);
+ removeDirectoryHelper(lpSource[3], 103);
+ }
+ else
+ {
+ removeFileHelper(lpSource[3], 17);
+ }
+
+ /* get rid of destination dirs and files */
+ dwAtt = GetFileAttributesA(lpDestination[0]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ sprintf_s(szTemp, _countof(szTemp), "%s/test01.txt", lpDestination[0]);
+ removeFileHelper(szTemp, 18);
+
+ sprintf_s(szTemp, _countof(szTemp), "%s/test02.txt", lpDestination[0]);
+ removeFileHelper(szTemp, 19);
+ removeDirectoryHelper(lpDestination[0], 103);
+ }
+ else
+ {
+ removeFileHelper(lpDestination[0], 17);
+ }
+
+ dwAtt = GetFileAttributesA(lpDestination[1]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ sprintf_s(szTemp, _countof(szTemp), "%s/test01.txt", lpDestination[1]);
+ removeFileHelper(szTemp, 18);
+
+ sprintf_s(szTemp, _countof(szTemp), "%s/test02.txt", lpDestination[1]);
+ removeFileHelper(szTemp, 19);
+ removeDirectoryHelper(lpDestination[1], 103);
+ }
+ else
+ {
+ removeFileHelper(lpDestination[1], 17);
+ }
+
+ dwAtt = GetFileAttributesA(lpDestination[2]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ sprintf_s(szTemp, _countof(szTemp), "%s/test01.txt", lpDestination[2]);
+ removeFileHelper(szTemp, 18);
+
+ sprintf_s(szTemp, _countof(szTemp), "%s/test02.txt", lpDestination[2]);
+ removeFileHelper(szTemp, 19);
+ removeDirectoryHelper(lpDestination[2], 103);
+ }
+ else
+ {
+ removeFileHelper(lpDestination[2], 17);
+ }
+
+ dwAtt = GetFileAttributesA(lpDestination[3]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ sprintf_s(szTemp, _countof(szTemp), "%s/test01.txt", lpDestination[3]);
+ removeFileHelper(szTemp, 18);
+
+ sprintf_s(szTemp, _countof(szTemp), "%s/test02.txt", lpDestination[3]);
+ removeFileHelper(szTemp, 19);
+ removeDirectoryHelper(lpDestination[3], 103);
+ }
+ else
+ {
+ removeFileHelper(lpDestination[3], 17);
+ }
+
+}
+
+
+
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ BOOL bRc = TRUE;
+ BOOL bSuccess = TRUE;
+ char results[40];
+ FILE* resultsFile = NULL;
+ int nCounter = 0;
+ int i, j;
+ char tempSource[] = {'t','e','m','p','k','.','t','m','p','\0'};
+ char tempDest[] = {'t','e','m','p','2','.','t','m','p','\0'};
+ HANDLE hFile;
+ DWORD result;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* read in the expected results to compare with actual results */
+ memset (results, 0, 20);
+ resultsFile = fopen("expectedresults.txt", "r");
+ if (resultsFile == NULL)
+ {
+ Fail("MoveFileA ERROR[%ul]: Unable to open \"expectedresults.txt\"\n", GetLastError());
+ }
+
+ fgets(results, 20, resultsFile);
+ fclose(resultsFile);
+
+ /* clean the slate */
+ removeAll();
+
+ if (createExisting() != 0)
+ {
+ removeAll();
+ }
+
+
+ /* lpSource loop */
+ for (i = 0; i < 4; i++)
+ {
+ /* lpDestination loop */
+ for (j = 0; j < 4; j++)
+ {
+ bRc = MoveFileA(lpSource[i], lpDestination[j]);
+ if (!(
+ ((bRc == TRUE) && (results[nCounter] == '1'))
+ ||
+ ((bRc == FALSE ) && (results[nCounter] == '0')) )
+ )
+ {
+ Trace("MoveFileA: FAILED: test[%d][%d]: \"%s\" -> \"%s\"\n",
+ i, j, lpSource[i], lpDestination[j]);
+ bSuccess = FALSE;
+ }
+
+ /* undo the last move */
+ removeAll();
+ createExisting();
+
+ nCounter++;
+ }
+ }
+
+ removeAll();
+ if (bSuccess == FALSE)
+ {
+ Fail("MoveFileA: Test Failed");
+ }
+
+ /* create the temp source file */
+ hFile = CreateFileA(tempSource, GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+
+ if( hFile == INVALID_HANDLE_VALUE )
+ {
+ Fail("Error[%ul]:MoveFileA: CreateFile failed to "
+ "create the file correctly.\n", GetLastError());
+ }
+
+ bRc = CloseHandle(hFile);
+ if(!bRc)
+ {
+ Trace("MoveFileA: CloseHandle failed to close the "
+ "handle correctly. ERROR:%u\n",GetLastError());
+
+ /* delete the created file */
+ bRc = DeleteFileA(tempSource);
+ if(!bRc)
+ {
+ Fail("Error[%ul]:MoveFileA: DeleteFileA failed to delete the"
+ "file correctly.\n", GetLastError());
+ }
+ Fail("");
+ }
+
+ /* set the file attributes to be readonly */
+ bRc = SetFileAttributesA(tempSource, FILE_ATTRIBUTE_READONLY);
+ if(!bRc)
+ {
+ Trace("MoveFileA: SetFileAttributes failed to set file "
+ "attributes correctly. GetLastError returned %u\n",GetLastError());
+ /* delete the created file */
+ bRc = DeleteFileA(tempSource);
+ if(!bRc)
+ {
+ Fail("Error[%ul]:MoveFileA: DeleteFileA failed to delete the"
+ "file correctly.\n", GetLastError());
+ }
+ Fail("");
+ }
+
+ /* move the file to the new location */
+ bRc = MoveFileA(tempSource, tempDest);
+ if(!bRc)
+ {
+ /* delete the created file */
+ bRc = DeleteFileA(tempSource);
+ if(!bRc)
+ {
+ Fail("Error[%ul]:MoveFileA: DeleteFileA failed to delete the"
+ "file correctly.\n", GetLastError());
+ }
+
+ Fail("Error[%ul]:MoveFileA(%S, %S): GetFileAttributes "
+ "failed to get the file's attributes.\n",
+ GetLastError(), tempSource, tempDest);
+ }
+
+ /* check that the newly moved file has the same file attributes
+ as the original */
+ result = GetFileAttributesA(tempDest);
+ if(result == 0)
+ {
+ /* delete the created file */
+ bRc = DeleteFileA(tempDest);
+ if(!bRc)
+ {
+ Fail("Error[%ul]:MoveFileA: DeleteFileA failed to delete the"
+ "file correctly.\n", GetLastError());
+ }
+
+ Fail("Error[%ul]:MoveFileA: GetFileAttributes failed to get "
+ "the file's attributes.\n", GetLastError());
+ }
+
+ if((result & FILE_ATTRIBUTE_READONLY) != FILE_ATTRIBUTE_READONLY)
+ {
+ /* delete the newly moved file */
+ bRc = DeleteFileA(tempDest);
+ if(!bRc)
+ {
+ Fail("Error[%ul]:MoveFileA: DeleteFileA failed to delete the"
+ "file correctly.\n", GetLastError());
+ }
+
+ Fail("Error[%ul]MoveFileA: GetFileAttributes failed to get "
+ "the correct file attributes.\n", GetLastError());
+ }
+
+ /* set the file attributes back to normal, to be deleted */
+ bRc = SetFileAttributesA(tempDest, FILE_ATTRIBUTE_NORMAL);
+ if(!bRc)
+ {
+ /* delete the newly moved file */
+ bRc = DeleteFileA(tempDest);
+ if(!bRc)
+ {
+ Fail("Error[%ul]:MoveFileA: DeleteFileA failed to delete the"
+ "file correctly.\n", GetLastError());
+ }
+
+ Fail("Error[%ul]:MoveFileA: SetFileAttributes failed to set "
+ "file attributes correctly.\n", GetLastError());
+ }
+
+ /* delete the newly moved file */
+ bRc = DeleteFileA(tempDest);
+ if(!bRc)
+ {
+ Fail("Error[%ul]:MoveFileA: DeleteFileA failed to delete the"
+ "file correctly.\n", GetLastError());
+ }
+
+ PAL_Terminate();
+
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/MoveFileExA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/MoveFileExA/test1/CMakeLists.txt
index f41dd7fd08..ef2471738c 100644
--- a/src/pal/tests/palsuite/file_io/MoveFileExA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/MoveFileExA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- MoveFileExA.c
+ MoveFileExA.cpp
)
add_executable(paltest_movefileexa_test1
diff --git a/src/pal/tests/palsuite/file_io/MoveFileExA/test1/MoveFileExA.c b/src/pal/tests/palsuite/file_io/MoveFileExA/test1/MoveFileExA.cpp
index 0bce2b08d1..0bce2b08d1 100644
--- a/src/pal/tests/palsuite/file_io/MoveFileExA/test1/MoveFileExA.c
+++ b/src/pal/tests/palsuite/file_io/MoveFileExA/test1/MoveFileExA.cpp
diff --git a/src/pal/tests/palsuite/file_io/MoveFileExW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/MoveFileExW/test1/CMakeLists.txt
index 4c6a70f050..ca6b35e3ac 100644
--- a/src/pal/tests/palsuite/file_io/MoveFileExW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/MoveFileExW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- MoveFileExW.c
+ MoveFileExW.cpp
)
add_executable(paltest_movefileexw_test1
diff --git a/src/pal/tests/palsuite/file_io/MoveFileExW/test1/MoveFileExW.c b/src/pal/tests/palsuite/file_io/MoveFileExW/test1/MoveFileExW.cpp
index 4f5b72dcf7..4f5b72dcf7 100644
--- a/src/pal/tests/palsuite/file_io/MoveFileExW/test1/MoveFileExW.c
+++ b/src/pal/tests/palsuite/file_io/MoveFileExW/test1/MoveFileExW.cpp
diff --git a/src/pal/tests/palsuite/file_io/MoveFileW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/MoveFileW/test1/CMakeLists.txt
index 497f654122..4519746e7b 100644
--- a/src/pal/tests/palsuite/file_io/MoveFileW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/MoveFileW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- MoveFileW.c
+ MoveFileW.cpp
)
add_executable(paltest_movefilew_test1
diff --git a/src/pal/tests/palsuite/file_io/MoveFileW/test1/MoveFileW.c b/src/pal/tests/palsuite/file_io/MoveFileW/test1/MoveFileW.c
deleted file mode 100644
index 58999302d0..0000000000
--- a/src/pal/tests/palsuite/file_io/MoveFileW/test1/MoveFileW.c
+++ /dev/null
@@ -1,478 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: MoveFileW.c
-**
-** Purpose: Tests the PAL implementation of the MoveFileW function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-
-LPSTR lpSource[4] = {"src_existing.txt",
- "src_non-existant.txt",
- "src_dir_existing",
- "src_dir_non-existant"};
-LPSTR lpDestination[4] = {"dst_existing.txt",
- "dst_non-existant.txt",
- "dst_dir_existing",
- "dst_dir_non-existant"};
-
-
-/* Create all the required test files */
-int createExisting(void)
-{
- FILE* tempFile = NULL;
- DWORD dwError;
- BOOL bRc = FALSE;
- WCHAR* wPtr = NULL;
- char szBuffer[100];
-
- /* create the src_existing file */
- tempFile = fopen(lpSource[0], "w");
- if (tempFile != NULL)
- {
- fprintf(tempFile, "MoveFile test file: src_existing.txt\n");
- fclose(tempFile);
- }
- else
- {
- Trace("ERROR: couldn't create %s\n", lpSource[0]);
- return FAIL;
- }
-
- /* create the src_dir_existing directory and files */
- wPtr = convert(lpSource[2]);
- bRc = CreateDirectoryW(wPtr, NULL);
- free(wPtr);
- if (bRc != TRUE)
- {
- Trace("MoveFileW: ERROR: couldn't create \"%s\" because of "
- "error code %ld\n",
- lpSource[2],
- GetLastError());
- return FAIL;
- }
-
- memset(szBuffer, 0, 100);
- sprintf(szBuffer, "%s/test01.txt", lpSource[2]);
- tempFile = fopen(szBuffer, "w");
- if (tempFile != NULL)
- {
- fprintf(tempFile, "MoveFileW test file: %s\n", szBuffer);
- fclose(tempFile);
- }
- else
- {
- Trace("ERROR: couldn't create %s\n", szBuffer);
- return FAIL;
- }
-
- memset(szBuffer, 0, 100);
- sprintf(szBuffer, "%s/test02.txt", lpSource[2]);
- tempFile = fopen(szBuffer, "w");
- if (tempFile != NULL)
- {
- fprintf(tempFile, "MoveFileW test file: %s\n", szBuffer);
- fclose(tempFile);
- }
- else
- {
- Trace("ERROR: couldn't create %s\n", szBuffer);
- return FAIL;
- }
-
-
- /* create the dst_existing file */
- tempFile = fopen(lpDestination[0], "w");
- if (tempFile != NULL)
- {
- fprintf(tempFile, "MoveFileW test file: dst_existing.txt\n");
- fclose(tempFile);
- }
- else
- {
- Trace("ERROR: couldn't create \"%s\"\n", lpDestination[0]);
- return FAIL;
- }
-
- /* create the dst_dir_existing directory and files */
- wPtr = convert(lpDestination[2]);
- bRc = CreateDirectoryW(wPtr, NULL);
- free(wPtr);
- if (bRc != TRUE)
- {
- dwError = GetLastError();
- Trace("MoveFileW: ERROR: couldn't create \"%s\"\n", lpDestination[2]);
- return FAIL;
- }
-
- tempFile = fopen("dst_dir_existing/test01.txt", "w");
- if (tempFile != NULL)
- {
- fprintf(tempFile, "MoveFileW test file: dst_dir_existing/test01.txt\n");
- fclose(tempFile);
- }
- else
- {
- Trace("ERROR: couldn't create dst_dir_existing/test01.txt\n");
- return FAIL;
- }
- tempFile = fopen("dst_dir_existing/test02.txt", "w");
- if (tempFile != NULL)
- {
- fprintf(tempFile, "MoveFileW test file: dst_dir_existing/test02.txt\n");
- fclose(tempFile);
- }
- else
- {
- Trace("ERROR: couldn't create dst_dir_existing/test02.txt\n");
- return FAIL;
- }
-
- return PASS;
-}
-
-void removeDirectoryHelper(LPSTR dir, int location)
-{
- DWORD dwAtt = GetFileAttributesA(dir);
- if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
- {
- if(!RemoveDirectoryA(dir))
- {
- Fail("ERROR: Failed to remove Directory [%s], Error Code [%d], location [%d]\n", dir, GetLastError(), location);
- }
- }
-}
-
-void removeFileHelper(LPSTR pfile, int location)
-{
- FILE *fp;
- fp = fopen( pfile, "r");
-
- if (fp != NULL)
- {
- if(fclose(fp))
- {
- Fail("ERROR: Failed to close the file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
- }
-
- if(!DeleteFileA(pfile))
- {
- Fail("ERROR: Failed to delete file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
- }
- else
- {
- // Trace("Success: deleted file [%S], Error Code [%d], location [%d]\n", wfile, GetLastError(), location);
- }
- }
-
-}
-
-/* remove all created files in preparation for the next test */
-void removeAll(void)
-{
- char szTemp[40];
- DWORD dwAtt;
-
- /* get rid of source dirs and files */
- removeFileHelper(lpSource[0], 1);
- removeFileHelper(lpSource[1], 2);
-
- dwAtt = GetFileAttributesA(lpSource[2]);
- if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
- {
- sprintf(szTemp, "%s/test01.txt", lpSource[2]);
- removeFileHelper(szTemp, 18);
-
- sprintf(szTemp, "%s/test02.txt", lpSource[2]);
- removeFileHelper(szTemp, 19);
- removeDirectoryHelper(lpSource[2], 103);
- }
- else
- {
- removeFileHelper(lpSource[2], 17);
- }
-
-
- dwAtt = GetFileAttributesA(lpSource[3]);
- if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
- {
- sprintf(szTemp, "%s/test01.txt", lpSource[3]);
- removeFileHelper(szTemp, 18);
-
- sprintf(szTemp, "%s/test02.txt", lpSource[3]);
- removeFileHelper(szTemp, 19);
- removeDirectoryHelper(lpSource[3], 103);
- }
- else
- {
- removeFileHelper(lpSource[3], 17);
- }
-
- /* get rid of destination dirs and files */
- dwAtt = GetFileAttributesA(lpDestination[0]);
- if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
- {
- sprintf(szTemp, "%s/test01.txt", lpDestination[0]);
- removeFileHelper(szTemp, 18);
-
- sprintf(szTemp, "%s/test02.txt", lpDestination[0]);
- removeFileHelper(szTemp, 19);
- removeDirectoryHelper(lpDestination[0], 103);
- }
- else
- {
- removeFileHelper(lpDestination[0], 17);
- }
-
- dwAtt = GetFileAttributesA(lpDestination[1]);
- if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
- {
- sprintf(szTemp, "%s/test01.txt", lpDestination[1]);
- removeFileHelper(szTemp, 18);
-
- sprintf(szTemp, "%s/test02.txt", lpDestination[1]);
- removeFileHelper(szTemp, 19);
- removeDirectoryHelper(lpDestination[1], 103);
- }
- else
- {
- removeFileHelper(lpDestination[1], 17);
- }
-
- dwAtt = GetFileAttributesA(lpDestination[2]);
- if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
- {
- sprintf(szTemp, "%s/test01.txt", lpDestination[2]);
- removeFileHelper(szTemp, 18);
-
- sprintf(szTemp, "%s/test02.txt", lpDestination[2]);
- removeFileHelper(szTemp, 19);
- removeDirectoryHelper(lpDestination[2], 103);
- }
- else
- {
- removeFileHelper(lpDestination[2], 17);
- }
-
- dwAtt = GetFileAttributesA(lpDestination[3]);
- if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
- {
- sprintf(szTemp, "%s/test01.txt", lpDestination[3]);
- removeFileHelper(szTemp, 18);
-
- sprintf(szTemp, "%s/test02.txt", lpDestination[3]);
- removeFileHelper(szTemp, 19);
- removeDirectoryHelper(lpDestination[3], 103);
- }
- else
- {
- removeFileHelper(lpDestination[3], 17);
- }
-
-}
-
-
-
-
-
-int __cdecl main(int argc, char *argv[])
-{
- BOOL bRc = TRUE;
- BOOL bSuccess = TRUE;
- char results[40];
- FILE* resultsFile = NULL;
- int nCounter = 0;
- int i, j;
- WCHAR* wSource = NULL;
- WCHAR* wDest = NULL;
- WCHAR tempSource[] = {'t','e','m','p','k','.','t','m','p','\0'};
- WCHAR tempDest[] = {'t','e','m','p','2','.','t','m','p','\0'};
- HANDLE hFile;
- DWORD result;
-
- if (0 != PAL_Initialize(argc,argv))
- {
- return FAIL;
- }
-
- /* read in the expected results to compare with actual results */
- memset (results, 0, 20);
- resultsFile = fopen("expectedresults.txt", "r");
- if (resultsFile == NULL)
- {
- Fail("MoveFileW ERROR: Unable to open \"expectedresults.txt\"\n");
- }
-
- fgets(results, 20, resultsFile);
- fclose(resultsFile);
-
- /* clean the slate */
- removeAll();
-
- if (createExisting() != 0)
- {
- removeAll();
- }
-
-
- /* lpSource loop */
- for (i = 0; i < 4; i++)
- {
- /* lpDestination loop */
- for (j = 0; j < 4; j++)
- {
-
- wSource = convert(lpSource[i]);
- wDest = convert(lpDestination[j]);
- bRc = MoveFileW(wSource, wDest);
- free(wSource);
- free(wDest);
- if (!(
- ((bRc == TRUE) && (results[nCounter] == '1'))
- ||
- ((bRc == FALSE ) && (results[nCounter] == '0')) )
- )
- {
- Trace("MoveFileW: FAILED: test[%d][%d]: \"%s\" -> \"%s\"\n",
- i, j, lpSource[i], lpDestination[j]);
- bSuccess = FALSE;
- }
-
- /* undo the last move */
- removeAll();
- createExisting();
-
- nCounter++;
- }
- }
-
- removeAll();
- if (bSuccess == FALSE)
- {
- Fail("MoveFileW: Test Failed");
- }
-
- /* create the temp source file */
- hFile = CreateFileW(tempSource, GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL, 0);
-
- if( hFile == INVALID_HANDLE_VALUE )
- {
- Fail("MoveFileW: CreateFile failed to "
- "create the file correctly.\n");
- }
-
- bRc = CloseHandle(hFile);
- if(!bRc)
- {
- Trace("MoveFileW: CloseHandle failed to close the "
- "handle correctly. ERROR:%u\n",GetLastError());
-
- /* delete the created file */
- bRc = DeleteFileW(tempSource);
- if(!bRc)
- {
- Fail("MoveFileW: DeleteFileW failed to delete the"
- "file correctly.\n");
- }
- Fail("");
- }
-
- /* set the file attributes to be readonly */
- bRc = SetFileAttributesW(tempSource, FILE_ATTRIBUTE_READONLY);
- if(!bRc)
- {
- Trace("MoveFileW: SetFileAttributes failed to set file "
- "attributes correctly. GetLastError returned %u\n",GetLastError());
- /* delete the created file */
- bRc = DeleteFileW(tempSource);
- if(!bRc)
- {
- Fail("MoveFileW: DeleteFileW failed to delete the"
- "file correctly.\n");
- }
- Fail("");
- }
-
- /* move the file to the new location */
- bRc = MoveFileW(tempSource, tempDest);
- if(!bRc)
- {
- /* delete the created file */
- bRc = DeleteFileW(tempSource);
- if(!bRc)
- {
- Fail("MoveFileW: DeleteFileW failed to delete the"
- "file correctly.\n");
- }
-
- Fail("MoveFileW(%S, %S): GetFileAttributes "
- "failed to get the file's attributes.\n",
- tempSource, tempDest);
- }
-
- /* check that the newly moved file has the same file attributes
- as the original */
- result = GetFileAttributesW(tempDest);
- if(result == 0)
- {
- /* delete the created file */
- bRc = DeleteFileW(tempDest);
- if(!bRc)
- {
- Fail("MoveFileW: DeleteFileW failed to delete the"
- "file correctly.\n");
- }
-
- Fail("MoveFileW: GetFileAttributes failed to get "
- "the file's attributes.\n");
- }
-
- if((result & FILE_ATTRIBUTE_READONLY) != FILE_ATTRIBUTE_READONLY)
- {
- /* delete the newly moved file */
- bRc = DeleteFileW(tempDest);
- if(!bRc)
- {
- Fail("MoveFileW: DeleteFileW failed to delete the"
- "file correctly.\n");
- }
-
- Fail("MoveFileW: GetFileAttributes failed to get "
- "the correct file attributes.\n");
- }
-
- /* set the file attributes back to normal, to be deleted */
- bRc = SetFileAttributesW(tempDest, FILE_ATTRIBUTE_NORMAL);
- if(!bRc)
- {
- /* delete the newly moved file */
- bRc = DeleteFileW(tempDest);
- if(!bRc)
- {
- Fail("MoveFileW: DeleteFileW failed to delete the"
- "file correctly.\n");
- }
-
- Fail("MoveFileW: SetFileAttributes failed to set "
- "file attributes correctly.\n");
- }
-
- /* delete the newly moved file */
- bRc = DeleteFileW(tempDest);
- if(!bRc)
- {
- Fail("MoveFileW: DeleteFileW failed to delete the"
- "file correctly.\n");
- }
-
- PAL_Terminate();
-
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/file_io/MoveFileW/test1/MoveFileW.cpp b/src/pal/tests/palsuite/file_io/MoveFileW/test1/MoveFileW.cpp
new file mode 100644
index 0000000000..8a7fae5983
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/MoveFileW/test1/MoveFileW.cpp
@@ -0,0 +1,478 @@
+// Licensed to the .NET Foundation under one or more 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: MoveFileW.c
+**
+** Purpose: Tests the PAL implementation of the MoveFileW function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+LPSTR lpSource[4] = {"src_existing.txt",
+ "src_non-existant.txt",
+ "src_dir_existing",
+ "src_dir_non-existant"};
+LPSTR lpDestination[4] = {"dst_existing.txt",
+ "dst_non-existant.txt",
+ "dst_dir_existing",
+ "dst_dir_non-existant"};
+
+
+/* Create all the required test files */
+int createExisting(void)
+{
+ FILE* tempFile = NULL;
+ DWORD dwError;
+ BOOL bRc = FALSE;
+ WCHAR* wPtr = NULL;
+ char szBuffer[100];
+
+ /* create the src_existing file */
+ tempFile = fopen(lpSource[0], "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "MoveFile test file: src_existing.txt\n");
+ fclose(tempFile);
+ }
+ else
+ {
+ Trace("ERROR: couldn't create %s\n", lpSource[0]);
+ return FAIL;
+ }
+
+ /* create the src_dir_existing directory and files */
+ wPtr = convert(lpSource[2]);
+ bRc = CreateDirectoryW(wPtr, NULL);
+ free(wPtr);
+ if (bRc != TRUE)
+ {
+ Trace("MoveFileW: ERROR: couldn't create \"%s\" because of "
+ "error code %ld\n",
+ lpSource[2],
+ GetLastError());
+ return FAIL;
+ }
+
+ memset(szBuffer, 0, 100);
+ sprintf_s(szBuffer, _countof(szBuffer), "%s/test01.txt", lpSource[2]);
+ tempFile = fopen(szBuffer, "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "MoveFileW test file: %s\n", szBuffer);
+ fclose(tempFile);
+ }
+ else
+ {
+ Trace("ERROR: couldn't create %s\n", szBuffer);
+ return FAIL;
+ }
+
+ memset(szBuffer, 0, 100);
+ sprintf_s(szBuffer, _countof(szBuffer), "%s/test02.txt", lpSource[2]);
+ tempFile = fopen(szBuffer, "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "MoveFileW test file: %s\n", szBuffer);
+ fclose(tempFile);
+ }
+ else
+ {
+ Trace("ERROR: couldn't create %s\n", szBuffer);
+ return FAIL;
+ }
+
+
+ /* create the dst_existing file */
+ tempFile = fopen(lpDestination[0], "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "MoveFileW test file: dst_existing.txt\n");
+ fclose(tempFile);
+ }
+ else
+ {
+ Trace("ERROR: couldn't create \"%s\"\n", lpDestination[0]);
+ return FAIL;
+ }
+
+ /* create the dst_dir_existing directory and files */
+ wPtr = convert(lpDestination[2]);
+ bRc = CreateDirectoryW(wPtr, NULL);
+ free(wPtr);
+ if (bRc != TRUE)
+ {
+ dwError = GetLastError();
+ Trace("MoveFileW: ERROR: couldn't create \"%s\"\n", lpDestination[2]);
+ return FAIL;
+ }
+
+ tempFile = fopen("dst_dir_existing/test01.txt", "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "MoveFileW test file: dst_dir_existing/test01.txt\n");
+ fclose(tempFile);
+ }
+ else
+ {
+ Trace("ERROR: couldn't create dst_dir_existing/test01.txt\n");
+ return FAIL;
+ }
+ tempFile = fopen("dst_dir_existing/test02.txt", "w");
+ if (tempFile != NULL)
+ {
+ fprintf(tempFile, "MoveFileW test file: dst_dir_existing/test02.txt\n");
+ fclose(tempFile);
+ }
+ else
+ {
+ Trace("ERROR: couldn't create dst_dir_existing/test02.txt\n");
+ return FAIL;
+ }
+
+ return PASS;
+}
+
+void removeDirectoryHelper(LPSTR dir, int location)
+{
+ DWORD dwAtt = GetFileAttributesA(dir);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ if(!RemoveDirectoryA(dir))
+ {
+ Fail("ERROR: Failed to remove Directory [%s], Error Code [%d], location [%d]\n", dir, GetLastError(), location);
+ }
+ }
+}
+
+void removeFileHelper(LPSTR pfile, int location)
+{
+ FILE *fp;
+ fp = fopen( pfile, "r");
+
+ if (fp != NULL)
+ {
+ if(fclose(fp))
+ {
+ Fail("ERROR: Failed to close the file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
+ }
+
+ if(!DeleteFileA(pfile))
+ {
+ Fail("ERROR: Failed to delete file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
+ }
+ else
+ {
+ // Trace("Success: deleted file [%S], Error Code [%d], location [%d]\n", wfile, GetLastError(), location);
+ }
+ }
+
+}
+
+/* remove all created files in preparation for the next test */
+void removeAll(void)
+{
+ char szTemp[40];
+ DWORD dwAtt;
+
+ /* get rid of source dirs and files */
+ removeFileHelper(lpSource[0], 1);
+ removeFileHelper(lpSource[1], 2);
+
+ dwAtt = GetFileAttributesA(lpSource[2]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ sprintf_s(szTemp, _countof(szTemp), "%s/test01.txt", lpSource[2]);
+ removeFileHelper(szTemp, 18);
+
+ sprintf_s(szTemp, _countof(szTemp), "%s/test02.txt", lpSource[2]);
+ removeFileHelper(szTemp, 19);
+ removeDirectoryHelper(lpSource[2], 103);
+ }
+ else
+ {
+ removeFileHelper(lpSource[2], 17);
+ }
+
+
+ dwAtt = GetFileAttributesA(lpSource[3]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ sprintf_s(szTemp, _countof(szTemp), "%s/test01.txt", lpSource[3]);
+ removeFileHelper(szTemp, 18);
+
+ sprintf_s(szTemp, _countof(szTemp), "%s/test02.txt", lpSource[3]);
+ removeFileHelper(szTemp, 19);
+ removeDirectoryHelper(lpSource[3], 103);
+ }
+ else
+ {
+ removeFileHelper(lpSource[3], 17);
+ }
+
+ /* get rid of destination dirs and files */
+ dwAtt = GetFileAttributesA(lpDestination[0]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ sprintf_s(szTemp, _countof(szTemp), "%s/test01.txt", lpDestination[0]);
+ removeFileHelper(szTemp, 18);
+
+ sprintf_s(szTemp, _countof(szTemp), "%s/test02.txt", lpDestination[0]);
+ removeFileHelper(szTemp, 19);
+ removeDirectoryHelper(lpDestination[0], 103);
+ }
+ else
+ {
+ removeFileHelper(lpDestination[0], 17);
+ }
+
+ dwAtt = GetFileAttributesA(lpDestination[1]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ sprintf_s(szTemp, _countof(szTemp), "%s/test01.txt", lpDestination[1]);
+ removeFileHelper(szTemp, 18);
+
+ sprintf_s(szTemp, _countof(szTemp), "%s/test02.txt", lpDestination[1]);
+ removeFileHelper(szTemp, 19);
+ removeDirectoryHelper(lpDestination[1], 103);
+ }
+ else
+ {
+ removeFileHelper(lpDestination[1], 17);
+ }
+
+ dwAtt = GetFileAttributesA(lpDestination[2]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ sprintf_s(szTemp, _countof(szTemp), "%s/test01.txt", lpDestination[2]);
+ removeFileHelper(szTemp, 18);
+
+ sprintf_s(szTemp, _countof(szTemp), "%s/test02.txt", lpDestination[2]);
+ removeFileHelper(szTemp, 19);
+ removeDirectoryHelper(lpDestination[2], 103);
+ }
+ else
+ {
+ removeFileHelper(lpDestination[2], 17);
+ }
+
+ dwAtt = GetFileAttributesA(lpDestination[3]);
+ if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
+ {
+ sprintf_s(szTemp, _countof(szTemp), "%s/test01.txt", lpDestination[3]);
+ removeFileHelper(szTemp, 18);
+
+ sprintf_s(szTemp, _countof(szTemp), "%s/test02.txt", lpDestination[3]);
+ removeFileHelper(szTemp, 19);
+ removeDirectoryHelper(lpDestination[3], 103);
+ }
+ else
+ {
+ removeFileHelper(lpDestination[3], 17);
+ }
+
+}
+
+
+
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ BOOL bRc = TRUE;
+ BOOL bSuccess = TRUE;
+ char results[40];
+ FILE* resultsFile = NULL;
+ int nCounter = 0;
+ int i, j;
+ WCHAR* wSource = NULL;
+ WCHAR* wDest = NULL;
+ WCHAR tempSource[] = {'t','e','m','p','k','.','t','m','p','\0'};
+ WCHAR tempDest[] = {'t','e','m','p','2','.','t','m','p','\0'};
+ HANDLE hFile;
+ DWORD result;
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* read in the expected results to compare with actual results */
+ memset (results, 0, 20);
+ resultsFile = fopen("expectedresults.txt", "r");
+ if (resultsFile == NULL)
+ {
+ Fail("MoveFileW ERROR: Unable to open \"expectedresults.txt\"\n");
+ }
+
+ fgets(results, 20, resultsFile);
+ fclose(resultsFile);
+
+ /* clean the slate */
+ removeAll();
+
+ if (createExisting() != 0)
+ {
+ removeAll();
+ }
+
+
+ /* lpSource loop */
+ for (i = 0; i < 4; i++)
+ {
+ /* lpDestination loop */
+ for (j = 0; j < 4; j++)
+ {
+
+ wSource = convert(lpSource[i]);
+ wDest = convert(lpDestination[j]);
+ bRc = MoveFileW(wSource, wDest);
+ free(wSource);
+ free(wDest);
+ if (!(
+ ((bRc == TRUE) && (results[nCounter] == '1'))
+ ||
+ ((bRc == FALSE ) && (results[nCounter] == '0')) )
+ )
+ {
+ Trace("MoveFileW: FAILED: test[%d][%d]: \"%s\" -> \"%s\"\n",
+ i, j, lpSource[i], lpDestination[j]);
+ bSuccess = FALSE;
+ }
+
+ /* undo the last move */
+ removeAll();
+ createExisting();
+
+ nCounter++;
+ }
+ }
+
+ removeAll();
+ if (bSuccess == FALSE)
+ {
+ Fail("MoveFileW: Test Failed");
+ }
+
+ /* create the temp source file */
+ hFile = CreateFileW(tempSource, GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+
+ if( hFile == INVALID_HANDLE_VALUE )
+ {
+ Fail("MoveFileW: CreateFile failed to "
+ "create the file correctly.\n");
+ }
+
+ bRc = CloseHandle(hFile);
+ if(!bRc)
+ {
+ Trace("MoveFileW: CloseHandle failed to close the "
+ "handle correctly. ERROR:%u\n",GetLastError());
+
+ /* delete the created file */
+ bRc = DeleteFileW(tempSource);
+ if(!bRc)
+ {
+ Fail("MoveFileW: DeleteFileW failed to delete the"
+ "file correctly.\n");
+ }
+ Fail("");
+ }
+
+ /* set the file attributes to be readonly */
+ bRc = SetFileAttributesW(tempSource, FILE_ATTRIBUTE_READONLY);
+ if(!bRc)
+ {
+ Trace("MoveFileW: SetFileAttributes failed to set file "
+ "attributes correctly. GetLastError returned %u\n",GetLastError());
+ /* delete the created file */
+ bRc = DeleteFileW(tempSource);
+ if(!bRc)
+ {
+ Fail("MoveFileW: DeleteFileW failed to delete the"
+ "file correctly.\n");
+ }
+ Fail("");
+ }
+
+ /* move the file to the new location */
+ bRc = MoveFileW(tempSource, tempDest);
+ if(!bRc)
+ {
+ /* delete the created file */
+ bRc = DeleteFileW(tempSource);
+ if(!bRc)
+ {
+ Fail("MoveFileW: DeleteFileW failed to delete the"
+ "file correctly.\n");
+ }
+
+ Fail("MoveFileW(%S, %S): GetFileAttributes "
+ "failed to get the file's attributes.\n",
+ tempSource, tempDest);
+ }
+
+ /* check that the newly moved file has the same file attributes
+ as the original */
+ result = GetFileAttributesW(tempDest);
+ if(result == 0)
+ {
+ /* delete the created file */
+ bRc = DeleteFileW(tempDest);
+ if(!bRc)
+ {
+ Fail("MoveFileW: DeleteFileW failed to delete the"
+ "file correctly.\n");
+ }
+
+ Fail("MoveFileW: GetFileAttributes failed to get "
+ "the file's attributes.\n");
+ }
+
+ if((result & FILE_ATTRIBUTE_READONLY) != FILE_ATTRIBUTE_READONLY)
+ {
+ /* delete the newly moved file */
+ bRc = DeleteFileW(tempDest);
+ if(!bRc)
+ {
+ Fail("MoveFileW: DeleteFileW failed to delete the"
+ "file correctly.\n");
+ }
+
+ Fail("MoveFileW: GetFileAttributes failed to get "
+ "the correct file attributes.\n");
+ }
+
+ /* set the file attributes back to normal, to be deleted */
+ bRc = SetFileAttributesW(tempDest, FILE_ATTRIBUTE_NORMAL);
+ if(!bRc)
+ {
+ /* delete the newly moved file */
+ bRc = DeleteFileW(tempDest);
+ if(!bRc)
+ {
+ Fail("MoveFileW: DeleteFileW failed to delete the"
+ "file correctly.\n");
+ }
+
+ Fail("MoveFileW: SetFileAttributes failed to set "
+ "file attributes correctly.\n");
+ }
+
+ /* delete the newly moved file */
+ bRc = DeleteFileW(tempDest);
+ if(!bRc)
+ {
+ Fail("MoveFileW: DeleteFileW failed to delete the"
+ "file correctly.\n");
+ }
+
+ PAL_Terminate();
+
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/ReadFile/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/ReadFile/test1/CMakeLists.txt
index 7b166e17b0..0aceb3708e 100644
--- a/src/pal/tests/palsuite/file_io/ReadFile/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/ReadFile/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- ReadFile.c
+ ReadFile.cpp
)
add_executable(paltest_readfile_test1
diff --git a/src/pal/tests/palsuite/file_io/ReadFile/test1/ReadFile.c b/src/pal/tests/palsuite/file_io/ReadFile/test1/ReadFile.cpp
index a59e29212e..a59e29212e 100644
--- a/src/pal/tests/palsuite/file_io/ReadFile/test1/ReadFile.c
+++ b/src/pal/tests/palsuite/file_io/ReadFile/test1/ReadFile.cpp
diff --git a/src/pal/tests/palsuite/file_io/ReadFile/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/ReadFile/test2/CMakeLists.txt
index fc4870e73d..f28ac117a2 100644
--- a/src/pal/tests/palsuite/file_io/ReadFile/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/ReadFile/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- ReadFile.c
+ ReadFile.cpp
)
add_executable(paltest_readfile_test2
diff --git a/src/pal/tests/palsuite/file_io/ReadFile/test2/ReadFile.c b/src/pal/tests/palsuite/file_io/ReadFile/test2/ReadFile.cpp
index f16858e573..f16858e573 100644
--- a/src/pal/tests/palsuite/file_io/ReadFile/test2/ReadFile.c
+++ b/src/pal/tests/palsuite/file_io/ReadFile/test2/ReadFile.cpp
diff --git a/src/pal/tests/palsuite/file_io/ReadFile/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/ReadFile/test3/CMakeLists.txt
index 77397743d4..26cb675c40 100644
--- a/src/pal/tests/palsuite/file_io/ReadFile/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/ReadFile/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- ReadFile.c
+ ReadFile.cpp
)
add_executable(paltest_readfile_test3
diff --git a/src/pal/tests/palsuite/file_io/ReadFile/test3/ReadFile.c b/src/pal/tests/palsuite/file_io/ReadFile/test3/ReadFile.cpp
index c5d6b1d155..c5d6b1d155 100644
--- a/src/pal/tests/palsuite/file_io/ReadFile/test3/ReadFile.c
+++ b/src/pal/tests/palsuite/file_io/ReadFile/test3/ReadFile.cpp
diff --git a/src/pal/tests/palsuite/file_io/ReadFile/test4/CMakeLists.txt b/src/pal/tests/palsuite/file_io/ReadFile/test4/CMakeLists.txt
index 37f227aced..bbf12777b6 100644
--- a/src/pal/tests/palsuite/file_io/ReadFile/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/ReadFile/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- readfile.c
+ readfile.cpp
)
add_executable(paltest_readfile_test4
diff --git a/src/pal/tests/palsuite/file_io/ReadFile/test4/readfile.c b/src/pal/tests/palsuite/file_io/ReadFile/test4/readfile.cpp
index 3ec939f63a..3ec939f63a 100644
--- a/src/pal/tests/palsuite/file_io/ReadFile/test4/readfile.c
+++ b/src/pal/tests/palsuite/file_io/ReadFile/test4/readfile.cpp
diff --git a/src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/RemoveDirectoryA.cpp b/src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/RemoveDirectoryA.cpp
index 167af58163..4eb53d0d0a 100644
--- a/src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/RemoveDirectoryA.cpp
+++ b/src/pal/tests/palsuite/file_io/RemoveDirectoryA/test1/RemoveDirectoryA.cpp
@@ -48,7 +48,7 @@ int __cdecl main(int argc, char *argv[])
* remove a directory that does not exist
*/
szTemp = (char *) malloc (sizeof("test_directory"));
- sprintf(szTemp, "test_directory");
+ sprintf_s(szTemp, sizeof("test_directory"), "test_directory");
bRc = RemoveDirectoryA(szTemp);
if (bRc != FALSE)
{
@@ -69,7 +69,7 @@ int __cdecl main(int argc, char *argv[])
}
char *szSymlinkName = (char *) malloc (sizeof("test_directory_symlink"));
- sprintf(szSymlinkName, "test_directory_symlink");
+ sprintf_s(szSymlinkName, sizeof("test_directory_symlink"), "test_directory_symlink");
if (symlink(szTemp, szSymlinkName) != 0)
{
Fail("Error:RemoveDirectoryA: Failed to create a symlink to the directory \"test_directory\".\n");
@@ -140,7 +140,7 @@ int __cdecl main(int argc, char *argv[])
* directories with dots
*/
memset(szDirName, 0, 252);
- sprintf(szDirName, ".dotDirectory");
+ sprintf_s(szDirName, _countof(szDirName), ".dotDirectory");
szTemp = (char *) malloc (sizeof(szDirName));
szTemp = strncpy(szTemp, szDirName, strlen(szDirName) + 1);
@@ -170,7 +170,7 @@ int __cdecl main(int argc, char *argv[])
* Try calling RemoveDirectory with a file name
*/
memset(szDirName, 0, 252);
- sprintf(szDirName, "removedirectoryw.c");
+ sprintf_s(szDirName, _countof(szDirName), "removedirectoryw.c");
szTemp = (char *) malloc (sizeof(szDirName));
szTemp = strncpy(szTemp, szDirName, strlen(szDirName) + 1);
@@ -201,7 +201,7 @@ int __cdecl main(int argc, char *argv[])
}
/* Create non_empty_dir */
- sprintf( szDirName, "non_empty_dir");
+ sprintf_s(szDirName, _countof(szDirName), "non_empty_dir");
szTemp = (char *) malloc (sizeof(szDirName));
szTemp = strncpy(szTemp, szDirName, strlen(szDirName) + 1);
bRc = CreateDirectoryA(szTemp, NULL);
@@ -229,7 +229,7 @@ int __cdecl main(int argc, char *argv[])
}
/* Create sub_dir */
- sprintf (szDirName, "sub_dir");
+ sprintf_s(szDirName, _countof(szDirName), "sub_dir");
szTemp2 = (char *) malloc (sizeof(szDirName));
szTemp2 = strncpy(szTemp2, szDirName, strlen(szDirName) + 1);
bRc = CreateDirectoryA(szTemp2, NULL);
diff --git a/src/pal/tests/palsuite/file_io/RemoveDirectoryW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/RemoveDirectoryW/test1/CMakeLists.txt
index 45b51cec30..6223bc6197 100644
--- a/src/pal/tests/palsuite/file_io/RemoveDirectoryW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/RemoveDirectoryW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- RemoveDirectoryW.c
+ RemoveDirectoryW.cpp
)
add_executable(paltest_removedirectoryw_test1
diff --git a/src/pal/tests/palsuite/file_io/RemoveDirectoryW/test1/RemoveDirectoryW.c b/src/pal/tests/palsuite/file_io/RemoveDirectoryW/test1/RemoveDirectoryW.c
deleted file mode 100644
index ae1dd0fb97..0000000000
--- a/src/pal/tests/palsuite/file_io/RemoveDirectoryW/test1/RemoveDirectoryW.c
+++ /dev/null
@@ -1,282 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: RemoveDirectoryW.c
-**
-** Purpose: Tests the PAL implementation of the RemoveDirectoryW function.
-**
-**
-**===================================================================*/
-
-
-#include <palsuite.h>
-
-
-int __cdecl main(int argc, char *argv[])
-{
- BOOL bRc = FALSE;
- char szDirName[252];
- DWORD curDirLen;
- WCHAR *szwTemp = NULL;
- WCHAR *szwTemp2 = NULL;
- WCHAR szwCurrentDir[MAX_PATH];
- WCHAR szwSubDir[MAX_PATH];
-
- if (0 != PAL_Initialize(argc,argv))
- {
- return FAIL;
- }
-
- /*
- * remove a NULL directory
- */
- bRc = RemoveDirectoryW(NULL);
- if (bRc != FALSE)
- {
- Fail("RemoveDirectoryW: Failed since it was able to remove a"
- " NULL directory name\n");
- }
-
- /*
- * remove a directory that does not exist
- */
- szwTemp = convert("test_directory");
- bRc = RemoveDirectoryW(szwTemp);
- if (bRc != FALSE)
- {
- free(szwTemp);
- Fail("RemoveDirectoryW: Failed since it was able to remove"
- " the non-existant directory \"test_directory\"\n");
- }
-
- /*
- * remove a directory that exists
- */
- bRc = CreateDirectoryW(szwTemp, NULL);
- if (bRc != TRUE)
- {
- free(szwTemp);
- Fail("RemoveDirectoryW: Failed to create the directory "
- "\"test_directory\" when it exists already.\n");
- }
- bRc = RemoveDirectoryW(szwTemp);
- if (bRc == FALSE)
- {
- free(szwTemp);
- Fail("RemoveDirectoryW: Failed to remove the directory "
- "\"test_directory\" (error code %d)\n",
- GetLastError());
- }
- /* Make sure the directory was removed */
- if( -1 != GetFileAttributesW(szwTemp) )
- {
- free(szwTemp);
- Fail("RemoveDirectoryW: Able to get the attributes of "
- "the removed directory\n");
- }
- free(szwTemp);
-
- /*
- * remove long directory names (245 characters)
- */
- curDirLen = GetCurrentDirectoryA(0, NULL) + 1;
- memset(szDirName, 0, 252);
- memset(szDirName, 'a', 245 - curDirLen);
- szwTemp = convert(szDirName);
- bRc = CreateDirectoryW(szwTemp, NULL);
- if (bRc == FALSE)
- {
- free(szwTemp);
- Fail("RemoveDirectoryW: Failed to create a directory name "
- "245 chars long\n");
- }
- bRc = RemoveDirectoryW(szwTemp);
- if (bRc == FALSE)
- {
- free(szwTemp);
- Fail("RemoveDirectoryW: Failed to remove a 245 char "
- "long directory\n");
- }
-
- /* Make sure the directory was removed */
- if( -1 != GetFileAttributesW(szwTemp) )
- {
- free(szwTemp);
- Fail("RemoveDirectoryW: Able to get the attributes of "
- "the removed directory\n");
- }
- free(szwTemp);
-
- /*
- * directories with dots
- */
- memset(szDirName, 0, 252);
- sprintf(szDirName, ".dotDirectory");
- szwTemp = convert(szDirName);
- bRc = CreateDirectoryW(szwTemp, NULL);
- if (bRc == FALSE)
- {
- free(szwTemp);
- Fail("RemoveDirectoryW: Failed to create \"%s\"\n", szDirName);
- }
- bRc = RemoveDirectoryW(szwTemp);
- if (bRc == FALSE)
- {
- free(szwTemp);
- Fail("RemoveDirectoryW: Failed to remove \"%s\"\n", szDirName);
- }
-
- /* Make sure the directory was removed */
- if( -1 != GetFileAttributesW(szwTemp) )
- {
- free(szwTemp);
- Fail("RemoveDirectoryW: Able to get the attributes of "
- "the removed directory\n");
- }
- free(szwTemp);
-
- /*
- * Try calling RemoveDirectory with a file name
- */
- memset(szDirName, 0, 252);
- sprintf(szDirName, "removedirectoryw.c");
- szwTemp = convert(szDirName);
-
- bRc = RemoveDirectoryW(szwTemp);
- free(szwTemp);
- if (bRc != FALSE)
- {
- Fail("RemoveDirectoryW: should have failed when "
- "called with a valid file name" );
- }
-
- /*
- * remove a non empty directory
- *
- * To test that, we'll first create non_empty_dir, we'll
- * set the current dir to non_empty_dir in which we'll
- * create sub_dir. We'll go back to the root of non_empty_dir
- * and we'll try to delete it (it shouldn't work).
- * After that we'll cleanup sub_dir and non_empty_dir
- */
-
- /* Get the current directory so it is easy to get back
- to it later */
- if( 0 == GetCurrentDirectoryW(MAX_PATH, szwCurrentDir) )
- {
- Fail("RemoveDirectoryW: Failed to get current directory "
- "with GetCurrentDirectoryW.\n");
- }
-
- /* Create non_empty_dir */
- szwTemp = convert("non_empty_dir");
- bRc = CreateDirectoryW(szwTemp, NULL);
- if (bRc != TRUE)
- {
- free(szwTemp);
- Fail("RemoveDirectoryW: Failed to create the directory "
- "\"non_empty_dir\" when it exists already.\n");
- }
-
- if( 0 == SetCurrentDirectoryW(szwTemp) )
- {
- free(szwTemp);
- Fail("RemoveDirectoryW: Failed to set current directory to "
- "\"non_empty_dir\" with SetCurrentDirectoryW.\n");
- }
-
- /* Get the directory full path so it is easy to get back
- to it later */
- if( 0 == GetCurrentDirectoryW(MAX_PATH, szwSubDir) )
- {
- free(szwTemp);
- Fail("RemoveDirectoryW: Failed to get current directory "
- "with GetCurrentDirectoryW.\n");
- }
-
- /* Create sub_dir */
- szwTemp2 = convert("sub_dir");
- bRc = CreateDirectoryW(szwTemp2, NULL);
- if (bRc != TRUE)
- {
- free(szwTemp);
- free(szwTemp2);
- Fail("RemoveDirectoryW: Failed to create the directory "
- "\"sub_dir\" when it exists already.\n");
- }
-
- /* Set the current dir to the parent of non_empty_dir/sub_dir */
- if( 0 == SetCurrentDirectoryW(szwCurrentDir) )
- {
- free(szwTemp);
- free(szwTemp2);
- Fail("RemoveDirectoryW: Failed to set current directory to "
- "\"non_empty_dir\" with SetCurrentDirectoryW.\n");
- }
-
- /* Try to remove non_empty_dir (shouldn't work) */
- bRc = RemoveDirectoryW(szwTemp);
- if (bRc == TRUE)
- {
- free(szwTemp);
- free(szwTemp2);
- Fail("RemoveDirectoryW: shouldn't have been able to remove "
- "the non empty directory \"non_empty_dir\"\n");
- }
-
- /* Go back to non_empty_dir and remove sub_dir */
- if( 0 == SetCurrentDirectoryW(szwSubDir) )
- {
- free(szwTemp);
- free(szwTemp2);
- Fail("RemoveDirectoryW: Failed to set current directory to "
- "\"non_empty_dir\" with SetCurrentDirectoryW.\n");
- }
-
- bRc = RemoveDirectoryW(szwTemp2);
- if (bRc == FALSE)
- {
- free(szwTemp);
- free(szwTemp2);
- Fail("RemoveDirectoryW: unable to remove "
- "directory \"sub_dir\"(error code %d)\n",
- GetLastError());
- }
- /* Make sure the directory was removed */
- if( -1 != GetFileAttributesW(szwTemp2) )
- {
- Fail("RemoveDirectoryW: Able to get the attributes of "
- "the removed directory\n");
- }
- free(szwTemp2);
-
- /* Go back to parent of non_empty_dir and remove non_empty_dir */
- if( 0 == SetCurrentDirectoryW(szwCurrentDir) )
- {
- free(szwTemp);
- Fail("RemoveDirectoryW: Failed to set current directory to "
- "\"..\non_empty_dir\" with SetCurrentDirectoryW.\n");
- }
- bRc = RemoveDirectoryW(szwTemp);
- if (bRc == FALSE)
- {
- free(szwTemp);
- Fail("RemoveDirectoryW: unable to remove "
- "the directory \"non_empty_dir\"(error code %d)\n",
- GetLastError());
- }
- /* Make sure the directory was removed */
- if( -1 != GetFileAttributesW(szwTemp) )
- {
- Fail("RemoveDirectoryW: Able to get the attributes of "
- "the removed directory\n");
- }
- free(szwTemp);
-
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/file_io/RemoveDirectoryW/test1/RemoveDirectoryW.cpp b/src/pal/tests/palsuite/file_io/RemoveDirectoryW/test1/RemoveDirectoryW.cpp
new file mode 100644
index 0000000000..ec90528069
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/RemoveDirectoryW/test1/RemoveDirectoryW.cpp
@@ -0,0 +1,282 @@
+// Licensed to the .NET Foundation under one or more 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: RemoveDirectoryW.c
+**
+** Purpose: Tests the PAL implementation of the RemoveDirectoryW function.
+**
+**
+**===================================================================*/
+
+
+#include <palsuite.h>
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ BOOL bRc = FALSE;
+ char szDirName[252];
+ DWORD curDirLen;
+ WCHAR *szwTemp = NULL;
+ WCHAR *szwTemp2 = NULL;
+ WCHAR szwCurrentDir[MAX_PATH];
+ WCHAR szwSubDir[MAX_PATH];
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /*
+ * remove a NULL directory
+ */
+ bRc = RemoveDirectoryW(NULL);
+ if (bRc != FALSE)
+ {
+ Fail("RemoveDirectoryW: Failed since it was able to remove a"
+ " NULL directory name\n");
+ }
+
+ /*
+ * remove a directory that does not exist
+ */
+ szwTemp = convert("test_directory");
+ bRc = RemoveDirectoryW(szwTemp);
+ if (bRc != FALSE)
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Failed since it was able to remove"
+ " the non-existant directory \"test_directory\"\n");
+ }
+
+ /*
+ * remove a directory that exists
+ */
+ bRc = CreateDirectoryW(szwTemp, NULL);
+ if (bRc != TRUE)
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Failed to create the directory "
+ "\"test_directory\" when it exists already.\n");
+ }
+ bRc = RemoveDirectoryW(szwTemp);
+ if (bRc == FALSE)
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Failed to remove the directory "
+ "\"test_directory\" (error code %d)\n",
+ GetLastError());
+ }
+ /* Make sure the directory was removed */
+ if( -1 != GetFileAttributesW(szwTemp) )
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Able to get the attributes of "
+ "the removed directory\n");
+ }
+ free(szwTemp);
+
+ /*
+ * remove long directory names (245 characters)
+ */
+ curDirLen = GetCurrentDirectoryA(0, NULL) + 1;
+ memset(szDirName, 0, 252);
+ memset(szDirName, 'a', 245 - curDirLen);
+ szwTemp = convert(szDirName);
+ bRc = CreateDirectoryW(szwTemp, NULL);
+ if (bRc == FALSE)
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Failed to create a directory name "
+ "245 chars long\n");
+ }
+ bRc = RemoveDirectoryW(szwTemp);
+ if (bRc == FALSE)
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Failed to remove a 245 char "
+ "long directory\n");
+ }
+
+ /* Make sure the directory was removed */
+ if( -1 != GetFileAttributesW(szwTemp) )
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Able to get the attributes of "
+ "the removed directory\n");
+ }
+ free(szwTemp);
+
+ /*
+ * directories with dots
+ */
+ memset(szDirName, 0, 252);
+ sprintf_s(szDirName, _countof(szDirName), ".dotDirectory");
+ szwTemp = convert(szDirName);
+ bRc = CreateDirectoryW(szwTemp, NULL);
+ if (bRc == FALSE)
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Failed to create \"%s\"\n", szDirName);
+ }
+ bRc = RemoveDirectoryW(szwTemp);
+ if (bRc == FALSE)
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Failed to remove \"%s\"\n", szDirName);
+ }
+
+ /* Make sure the directory was removed */
+ if( -1 != GetFileAttributesW(szwTemp) )
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Able to get the attributes of "
+ "the removed directory\n");
+ }
+ free(szwTemp);
+
+ /*
+ * Try calling RemoveDirectory with a file name
+ */
+ memset(szDirName, 0, 252);
+ sprintf_s(szDirName, _countof(szDirName), "removedirectoryw.c");
+ szwTemp = convert(szDirName);
+
+ bRc = RemoveDirectoryW(szwTemp);
+ free(szwTemp);
+ if (bRc != FALSE)
+ {
+ Fail("RemoveDirectoryW: should have failed when "
+ "called with a valid file name" );
+ }
+
+ /*
+ * remove a non empty directory
+ *
+ * To test that, we'll first create non_empty_dir, we'll
+ * set the current dir to non_empty_dir in which we'll
+ * create sub_dir. We'll go back to the root of non_empty_dir
+ * and we'll try to delete it (it shouldn't work).
+ * After that we'll cleanup sub_dir and non_empty_dir
+ */
+
+ /* Get the current directory so it is easy to get back
+ to it later */
+ if( 0 == GetCurrentDirectoryW(MAX_PATH, szwCurrentDir) )
+ {
+ Fail("RemoveDirectoryW: Failed to get current directory "
+ "with GetCurrentDirectoryW.\n");
+ }
+
+ /* Create non_empty_dir */
+ szwTemp = convert("non_empty_dir");
+ bRc = CreateDirectoryW(szwTemp, NULL);
+ if (bRc != TRUE)
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Failed to create the directory "
+ "\"non_empty_dir\" when it exists already.\n");
+ }
+
+ if( 0 == SetCurrentDirectoryW(szwTemp) )
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Failed to set current directory to "
+ "\"non_empty_dir\" with SetCurrentDirectoryW.\n");
+ }
+
+ /* Get the directory full path so it is easy to get back
+ to it later */
+ if( 0 == GetCurrentDirectoryW(MAX_PATH, szwSubDir) )
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Failed to get current directory "
+ "with GetCurrentDirectoryW.\n");
+ }
+
+ /* Create sub_dir */
+ szwTemp2 = convert("sub_dir");
+ bRc = CreateDirectoryW(szwTemp2, NULL);
+ if (bRc != TRUE)
+ {
+ free(szwTemp);
+ free(szwTemp2);
+ Fail("RemoveDirectoryW: Failed to create the directory "
+ "\"sub_dir\" when it exists already.\n");
+ }
+
+ /* Set the current dir to the parent of non_empty_dir/sub_dir */
+ if( 0 == SetCurrentDirectoryW(szwCurrentDir) )
+ {
+ free(szwTemp);
+ free(szwTemp2);
+ Fail("RemoveDirectoryW: Failed to set current directory to "
+ "\"non_empty_dir\" with SetCurrentDirectoryW.\n");
+ }
+
+ /* Try to remove non_empty_dir (shouldn't work) */
+ bRc = RemoveDirectoryW(szwTemp);
+ if (bRc == TRUE)
+ {
+ free(szwTemp);
+ free(szwTemp2);
+ Fail("RemoveDirectoryW: shouldn't have been able to remove "
+ "the non empty directory \"non_empty_dir\"\n");
+ }
+
+ /* Go back to non_empty_dir and remove sub_dir */
+ if( 0 == SetCurrentDirectoryW(szwSubDir) )
+ {
+ free(szwTemp);
+ free(szwTemp2);
+ Fail("RemoveDirectoryW: Failed to set current directory to "
+ "\"non_empty_dir\" with SetCurrentDirectoryW.\n");
+ }
+
+ bRc = RemoveDirectoryW(szwTemp2);
+ if (bRc == FALSE)
+ {
+ free(szwTemp);
+ free(szwTemp2);
+ Fail("RemoveDirectoryW: unable to remove "
+ "directory \"sub_dir\"(error code %d)\n",
+ GetLastError());
+ }
+ /* Make sure the directory was removed */
+ if( -1 != GetFileAttributesW(szwTemp2) )
+ {
+ Fail("RemoveDirectoryW: Able to get the attributes of "
+ "the removed directory\n");
+ }
+ free(szwTemp2);
+
+ /* Go back to parent of non_empty_dir and remove non_empty_dir */
+ if( 0 == SetCurrentDirectoryW(szwCurrentDir) )
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: Failed to set current directory to "
+ "\"..\non_empty_dir\" with SetCurrentDirectoryW.\n");
+ }
+ bRc = RemoveDirectoryW(szwTemp);
+ if (bRc == FALSE)
+ {
+ free(szwTemp);
+ Fail("RemoveDirectoryW: unable to remove "
+ "the directory \"non_empty_dir\"(error code %d)\n",
+ GetLastError());
+ }
+ /* Make sure the directory was removed */
+ if( -1 != GetFileAttributesW(szwTemp) )
+ {
+ Fail("RemoveDirectoryW: Able to get the attributes of "
+ "the removed directory\n");
+ }
+ free(szwTemp);
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SearchPathA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SearchPathA/test1/CMakeLists.txt
index d1ac975d18..c020a86b61 100644
--- a/src/pal/tests/palsuite/file_io/SearchPathA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SearchPathA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- SearchPathA.c
+ SearchPathA.cpp
)
add_executable(paltest_searchpatha_test1
diff --git a/src/pal/tests/palsuite/file_io/SearchPathA/test1/SearchPathA.c b/src/pal/tests/palsuite/file_io/SearchPathA/test1/SearchPathA.c
deleted file mode 100644
index ab9eecdebc..0000000000
--- a/src/pal/tests/palsuite/file_io/SearchPathA/test1/SearchPathA.c
+++ /dev/null
@@ -1,144 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: SearchPathA.c
-**
-** Purpose: Tests the PAL implementation of the SearchFileA function.
-**
-**
-** TODO: Write a test where complete path is passed (say c:\?)
-**===================================================================*/
-//SearchPath
-//
-//The SearchPath function searches for the specified file in the specified path.
-//
-
-
-#include <palsuite.h>
-char* szDir = ".";
-
-char* szNoFileName = "333asdf";
-char* szNoFileNameExt = ".x77t";
-
-char* szFileNameExists = "searchfile";
-char* szFileNameExtExists = ".txt";
-
-char* szFileNameExistsWithExt = "searchfile.txt";
-char fileloc[_MAX_PATH];
-
-void removeFileHelper(LPSTR pfile, int location)
-{
- FILE *fp;
- fp = fopen( pfile, "r");
-
- if (fp != NULL)
- {
- if(fclose(fp))
- {
- Fail("ERROR: Failed to close the file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
- }
-
- if(!DeleteFileA(pfile))
- {
- Fail("ERROR: Failed to delete file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
- }
- }
-
-}
-
-
-void RemoveAll()
-{
- removeFileHelper(fileloc, 1);
-}
-
-int __cdecl main(int argc, char *argv[]) {
-
- char* lpPath = NULL;
- char* lpFileName = NULL;
- char* lpExtension = NULL;
- DWORD nBufferLength = 0;
- char lpBuffer[_MAX_PATH];
- char** lpFilePart = NULL;
- DWORD error = 0;
- DWORD result = 0;
-
- HANDLE hsearchfile;
- char fname[_MAX_FNAME];
- char ext[_MAX_EXT];
- char fullPath[_MAX_DIR];
- char drive[_MAX_DRIVE];
- char dir[_MAX_DIR];
-
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
-
- /* Initalize the buffer.
- */
- memset(fullPath, 0, _MAX_DIR);
-
- /* Get the full path to the library (DLL).
- */
-
- if ( NULL != _fullpath( fullPath, argv[0], _MAX_DIR )) {
- _splitpath(fullPath,drive,dir,fname,ext);
- _makepath(fullPath,drive,dir,"","");
- } else {
- Fail("ERROR: conversion from relative path \" %s \" to absolute path failed. _fullpath returned NULL\n",argv[0]);
- }
-
- memset(fileloc, 0, _MAX_PATH);
- sprintf(fileloc, "%s%s", fullPath, szFileNameExistsWithExt);
-
- RemoveAll();
-
- hsearchfile = CreateFileA(fileloc, GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL, 0);
-
- if (hsearchfile == INVALID_HANDLE_VALUE)
- {
- Trace("ERROR[%ul]: couldn't create %s\n", GetLastError(), fileloc);
- return FAIL;
- }
-
- CloseHandle(hsearchfile);
-
- //
- // find a file that doesn't exist
- //
- ZeroMemory( lpBuffer, sizeof(lpBuffer));
- lpPath = fullPath;
- lpFileName = szNoFileName;
- lpExtension = NULL;
-
- if( SearchPathA( lpPath, lpFileName, lpExtension, nBufferLength, lpBuffer, lpFilePart) != 0 ){
- error = GetLastError();
- Fail ("SearchPathA: ERROR1 -> Found invalid file[%s][%s][%s][%d]\n", lpPath, szNoFileName, szNoFileNameExt, error);
- }
-
- //
- // find a file that exists, when path is mentioned explicitly
- //
- ZeroMemory( lpBuffer, sizeof(lpBuffer));
- lpPath = fullPath;
- lpFileName = szFileNameExistsWithExt;
- lpExtension = NULL;
-
- result = SearchPathA( lpPath, lpFileName, lpExtension, nBufferLength, lpBuffer, lpFilePart);
-
- if( result == 0 ){
- error = GetLastError();
- Fail ("SearchPathA: ERROR2 -> Did not Find valid file[%s][%s][%d]\n", lpPath, szFileNameExistsWithExt, error);
- }
-
- RemoveAll();
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/file_io/SearchPathA/test1/SearchPathA.cpp b/src/pal/tests/palsuite/file_io/SearchPathA/test1/SearchPathA.cpp
new file mode 100644
index 0000000000..57afdefc7b
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SearchPathA/test1/SearchPathA.cpp
@@ -0,0 +1,139 @@
+// Licensed to the .NET Foundation under one or more 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: SearchPathA.c
+**
+** Purpose: Tests the PAL implementation of the SearchFileA function.
+**
+**
+** TODO: Write a test where complete path is passed (say c:\?)
+**===================================================================*/
+//SearchPath
+//
+//The SearchPath function searches for the specified file in the specified path.
+//
+
+
+#include <palsuite.h>
+char* szDir = ".";
+
+char* szNoFileName = "333asdf";
+char* szNoFileNameExt = ".x77t";
+
+char* szFileNameExists = "searchfile";
+char* szFileNameExtExists = ".txt";
+
+char* szFileNameExistsWithExt = "searchfile.txt";
+char fileloc[_MAX_PATH];
+
+void removeFileHelper(LPSTR pfile, int location)
+{
+ FILE *fp;
+ fp = fopen( pfile, "r");
+
+ if (fp != NULL)
+ {
+ if(fclose(fp))
+ {
+ Fail("ERROR: Failed to close the file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
+ }
+
+ if(!DeleteFileA(pfile))
+ {
+ Fail("ERROR: Failed to delete file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
+ }
+ }
+
+}
+
+
+void RemoveAll()
+{
+ removeFileHelper(fileloc, 1);
+}
+
+int __cdecl main(int argc, char *argv[]) {
+
+ char* lpPath = NULL;
+ char* lpFileName = NULL;
+ char* lpExtension = NULL;
+ DWORD nBufferLength = 0;
+ char lpBuffer[_MAX_PATH];
+ char** lpFilePart = NULL;
+ DWORD error = 0;
+ DWORD result = 0;
+
+ HANDLE hsearchfile;
+ char fname[_MAX_FNAME];
+ char ext[_MAX_EXT];
+ char fullPath[_MAX_DIR];
+ char drive[_MAX_DRIVE];
+ char dir[_MAX_DIR];
+
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+
+ /* Initalize the buffer.
+ */
+ memset(fullPath, 0, _MAX_DIR);
+
+ if (GetTempPathA(_MAX_DIR, fullPath) == 0)
+ {
+ Fail("ERROR: GetTempPathA failed to get a path\n");
+ }
+
+ memset(fileloc, 0, _MAX_PATH);
+ sprintf_s(fileloc, _countof(fileloc), "%s%s", fullPath, szFileNameExistsWithExt);
+
+ RemoveAll();
+
+ hsearchfile = CreateFileA(fileloc, GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+
+ if (hsearchfile == INVALID_HANDLE_VALUE)
+ {
+ Trace("ERROR[%ul]: couldn't create %s\n", GetLastError(), fileloc);
+ return FAIL;
+ }
+
+ CloseHandle(hsearchfile);
+
+ //
+ // find a file that doesn't exist
+ //
+ ZeroMemory( lpBuffer, sizeof(lpBuffer));
+ lpPath = fullPath;
+ lpFileName = szNoFileName;
+ lpExtension = NULL;
+
+ if( SearchPathA( lpPath, lpFileName, lpExtension, nBufferLength, lpBuffer, lpFilePart) != 0 ){
+ error = GetLastError();
+ Fail ("SearchPathA: ERROR1 -> Found invalid file[%s][%s][%s][%d]\n", lpPath, szNoFileName, szNoFileNameExt, error);
+ }
+
+ //
+ // find a file that exists, when path is mentioned explicitly
+ //
+ ZeroMemory( lpBuffer, sizeof(lpBuffer));
+ lpPath = fullPath;
+ lpFileName = szFileNameExistsWithExt;
+ lpExtension = NULL;
+
+ result = SearchPathA( lpPath, lpFileName, lpExtension, nBufferLength, lpBuffer, lpFilePart);
+
+ if( result == 0 ){
+ error = GetLastError();
+ Fail ("SearchPathA: ERROR2 -> Did not Find valid file[%s][%s][%d]\n", lpPath, szFileNameExistsWithExt, error);
+ }
+
+ RemoveAll();
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SearchPathW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SearchPathW/test1/CMakeLists.txt
index d0c6252472..a77d875505 100644
--- a/src/pal/tests/palsuite/file_io/SearchPathW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SearchPathW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- SearchPathW.c
+ SearchPathW.cpp
)
add_executable(paltest_searchpathw_test1
diff --git a/src/pal/tests/palsuite/file_io/SearchPathW/test1/SearchPathW.c b/src/pal/tests/palsuite/file_io/SearchPathW/test1/SearchPathW.c
deleted file mode 100644
index 2bc7694dc0..0000000000
--- a/src/pal/tests/palsuite/file_io/SearchPathW/test1/SearchPathW.c
+++ /dev/null
@@ -1,198 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: SearchPathW.c
-**
-** Purpose: Tests the PAL implementation of the SearchFileW function.
-**
-**
-** TODO: Write a test where complete path is passed (say c:\?)
-**===================================================================*/
-//SearchPath
-//
-//The SearchPath function searches for the specified file in the specified path.
-//
-//
-//DWORD SearchPath(
-// LPCTSTR lpPath,
-// LPCTSTR lpFileName,
-// LPCTSTR lpExtension,
-// DWORD nBufferLength,
-// LPTSTR lpBuffer,
-// LPTSTR* lpFilePart
-//);
-//
-//Parameters
-//lpPath
-//[in] Pointer to a null-terminated string that specifies the path to be searched for the file. If this parameter is NULL, the function searches for a matching file in the following directories in the following sequence:
-//The directory from which the application loaded.
-//The current directory.
-//The system directory. Use the GetSystemDirectory function to get the path of this directory.
-//The 16-bit system directory. There is no function that retrieves the path of this directory, but it is searched.
-//The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
-//The directories that are listed in the PATH environment variable.
-
-//lpFileName
-//[in] Pointer to a null-terminated string that specifies the name of the file to search for.
-
-//lpExtension
-//[in] Pointer to a null-terminated string that specifies an extension to be added to the file name when searching for the file. The first character of the file name extension must be a period (.). The extension is added only if the specified file name does not end with an extension.
-//If a file name extension is not required or if the file name contains an extension, this parameter can be NULL.
-//
-//nBufferLength
-//[in] Size of the buffer that receives the valid path and file name, in TCHARs.
-
-//lpBuffer
-//[out] Pointer to the buffer that receives the path and file name of the file found.
-
-//lpFilePart
-//[out] Pointer to the variable that receives the address (within lpBuffer) of the last component of the valid path and file name, which is the address of the character immediately following the final backslash (\) in the path.
-
-//Return Values
-//If the function succeeds, the value returned is the length, in TCHARs, of the string copied to the buffer, not including the terminating null character. If the return value is greater than nBufferLength, the value returned is the size of the buffer required to hold the path.
-//
-//If the function fails, the return value is zero. To get extended error information, call GetLastError.
-
-
-#include <palsuite.h>
-const char* szDir = ".";
-
-const char* szNoFileName = "333asdf";
-const char* szNoFileNameExt = ".x77t";
-
-const char* szFileNameExists = "searchpathw";
-const char* szFileNameExtExists = ".c";
-
-const char* szFileNameExistsWithExt = "searchpathw.c";
-
-char fileloc[_MAX_PATH];
-
-void removeFileHelper(LPSTR pfile, int location)
-{
- FILE *fp;
- fp = fopen( pfile, "r");
-
- if (fp != NULL)
- {
- if(fclose(fp))
- {
- Fail("ERROR: Failed to close the file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
- }
-
- if(!DeleteFileA(pfile))
- {
- Fail("ERROR: Failed to delete file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
- }
- else
- {
- // Trace("Success: deleted file [%S], Error Code [%d], location [%d]\n", wfile, GetLastError(), location);
- }
- }
-
-}
-
-void RemoveAll()
-{
- removeFileHelper(fileloc, 1);
-}
-
-int __cdecl main(int argc, char *argv[]) {
-
- WCHAR* lpPath = NULL;
- WCHAR* lpFileName = NULL;
- WCHAR* lpExtension = NULL;
- DWORD nBufferLength = 0;
- WCHAR lpBuffer[_MAX_PATH];
- WCHAR** lpFilePart = NULL;
- DWORD error = 0;
- DWORD result = 0;
-
- HANDLE hsearchfile;
- char fname[_MAX_FNAME];
- char ext[_MAX_EXT];
- char fullPath[_MAX_DIR];
- char drive[_MAX_DRIVE];
- char dir[_MAX_DIR];
-
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- /* Initalize the buffer.
- */
- memset(fullPath, 0, _MAX_DIR);
-
- /* Get the full path to the library (DLL).
- */
-
- if ( NULL != _fullpath( fullPath, argv[0], _MAX_DIR )) {
- _splitpath(fullPath,drive,dir,fname,ext);
- _makepath(fullPath,drive,dir,"","");
- } else {
- Fail("ERROR: conversion from relative path \" %s \" to absolute path failed. _fullpath returned NULL\n",argv[0]);
- }
-
- memset(fileloc, 0, _MAX_PATH);
- sprintf(fileloc, "%s%s", fullPath, szFileNameExistsWithExt);
-
- RemoveAll();
-
- hsearchfile = CreateFileA(fileloc, GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL, 0);
-
- if (hsearchfile == NULL)
- {
- Trace("ERROR[%ul]: couldn't create %s\n", GetLastError(), fileloc);
- return FAIL;
- }
-
- CloseHandle(hsearchfile);
-
- //
- // find a file that doesn't exist
- //
- ZeroMemory( lpBuffer, sizeof(lpBuffer));
- lpPath = convert((LPSTR)fullPath);
- lpFileName = convert((LPSTR)szNoFileName);
- lpExtension = NULL;
-
- if( SearchPathW( lpPath, lpFileName, lpExtension, nBufferLength, lpBuffer, lpFilePart) != 0 ){
- error = GetLastError();
- free(lpPath);
- free(lpFileName);
- Fail ("SearchPathW: ERROR1 -> Found invalid file[%s][%s][%s][%d]\n", lpPath, szNoFileName, szNoFileNameExt, error);
- }
-
- free(lpPath);
- free(lpFileName);
-
- //
- // find a file that exists, when path is mentioned explicitly
- //
- ZeroMemory( lpBuffer, sizeof(lpBuffer));
- lpPath = convert((LPSTR)fullPath);
- lpFileName = convert((LPSTR)szFileNameExistsWithExt);
- lpExtension = NULL;
-
- result = SearchPathW( lpPath, lpFileName, lpExtension, nBufferLength, lpBuffer, lpFilePart);
-
- if( result == 0 ){
- error = GetLastError();
- free(lpPath);
- free(lpFileName);
- Fail ("SearchPathA: ERROR2 -> Did not Find valid file[%s][%s][%d]\n", lpPath, szFileNameExistsWithExt, error);
- }
-
- free(lpPath);
- free(lpFileName);
-
- RemoveAll();
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/file_io/SearchPathW/test1/SearchPathW.cpp b/src/pal/tests/palsuite/file_io/SearchPathW/test1/SearchPathW.cpp
new file mode 100644
index 0000000000..6880a864cb
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SearchPathW/test1/SearchPathW.cpp
@@ -0,0 +1,193 @@
+// Licensed to the .NET Foundation under one or more 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: SearchPathW.c
+**
+** Purpose: Tests the PAL implementation of the SearchFileW function.
+**
+**
+** TODO: Write a test where complete path is passed (say c:\?)
+**===================================================================*/
+//SearchPath
+//
+//The SearchPath function searches for the specified file in the specified path.
+//
+//
+//DWORD SearchPath(
+// LPCTSTR lpPath,
+// LPCTSTR lpFileName,
+// LPCTSTR lpExtension,
+// DWORD nBufferLength,
+// LPTSTR lpBuffer,
+// LPTSTR* lpFilePart
+//);
+//
+//Parameters
+//lpPath
+//[in] Pointer to a null-terminated string that specifies the path to be searched for the file. If this parameter is NULL, the function searches for a matching file in the following directories in the following sequence:
+//The directory from which the application loaded.
+//The current directory.
+//The system directory. Use the GetSystemDirectory function to get the path of this directory.
+//The 16-bit system directory. There is no function that retrieves the path of this directory, but it is searched.
+//The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
+//The directories that are listed in the PATH environment variable.
+
+//lpFileName
+//[in] Pointer to a null-terminated string that specifies the name of the file to search for.
+
+//lpExtension
+//[in] Pointer to a null-terminated string that specifies an extension to be added to the file name when searching for the file. The first character of the file name extension must be a period (.). The extension is added only if the specified file name does not end with an extension.
+//If a file name extension is not required or if the file name contains an extension, this parameter can be NULL.
+//
+//nBufferLength
+//[in] Size of the buffer that receives the valid path and file name, in TCHARs.
+
+//lpBuffer
+//[out] Pointer to the buffer that receives the path and file name of the file found.
+
+//lpFilePart
+//[out] Pointer to the variable that receives the address (within lpBuffer) of the last component of the valid path and file name, which is the address of the character immediately following the final backslash (\) in the path.
+
+//Return Values
+//If the function succeeds, the value returned is the length, in TCHARs, of the string copied to the buffer, not including the terminating null character. If the return value is greater than nBufferLength, the value returned is the size of the buffer required to hold the path.
+//
+//If the function fails, the return value is zero. To get extended error information, call GetLastError.
+
+
+#include <palsuite.h>
+const char* szDir = ".";
+
+const char* szNoFileName = "333asdf";
+const char* szNoFileNameExt = ".x77t";
+
+const char* szFileNameExists = "searchpathw";
+const char* szFileNameExtExists = ".c";
+
+const char* szFileNameExistsWithExt = "searchpathw.c";
+
+char fileloc[_MAX_PATH];
+
+void removeFileHelper(LPSTR pfile, int location)
+{
+ FILE *fp;
+ fp = fopen( pfile, "r");
+
+ if (fp != NULL)
+ {
+ if(fclose(fp))
+ {
+ Fail("ERROR: Failed to close the file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
+ }
+
+ if(!DeleteFileA(pfile))
+ {
+ Fail("ERROR: Failed to delete file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
+ }
+ else
+ {
+ // Trace("Success: deleted file [%S], Error Code [%d], location [%d]\n", wfile, GetLastError(), location);
+ }
+ }
+
+}
+
+void RemoveAll()
+{
+ removeFileHelper(fileloc, 1);
+}
+
+int __cdecl main(int argc, char *argv[]) {
+
+ WCHAR* lpPath = NULL;
+ WCHAR* lpFileName = NULL;
+ WCHAR* lpExtension = NULL;
+ DWORD nBufferLength = 0;
+ WCHAR lpBuffer[_MAX_PATH];
+ WCHAR** lpFilePart = NULL;
+ DWORD error = 0;
+ DWORD result = 0;
+
+ HANDLE hsearchfile;
+ char fname[_MAX_FNAME];
+ char ext[_MAX_EXT];
+ char fullPath[_MAX_DIR];
+ char drive[_MAX_DRIVE];
+ char dir[_MAX_DIR];
+
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ /* Initalize the buffer.
+ */
+ memset(fullPath, 0, _MAX_DIR);
+
+ if (GetTempPathA(_MAX_DIR, fullPath) == 0)
+ {
+ Fail("ERROR: GetTempPathA failed to get a path\n");
+ }
+
+ memset(fileloc, 0, _MAX_PATH);
+ sprintf_s(fileloc, _countof(fileloc), "%s%s", fullPath, szFileNameExistsWithExt);
+
+ RemoveAll();
+
+ hsearchfile = CreateFileA(fileloc, GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, 0);
+
+ if (hsearchfile == NULL)
+ {
+ Trace("ERROR[%ul]: couldn't create %s\n", GetLastError(), fileloc);
+ return FAIL;
+ }
+
+ CloseHandle(hsearchfile);
+
+ //
+ // find a file that doesn't exist
+ //
+ ZeroMemory( lpBuffer, sizeof(lpBuffer));
+ lpPath = convert((LPSTR)fullPath);
+ lpFileName = convert((LPSTR)szNoFileName);
+ lpExtension = NULL;
+
+ if( SearchPathW( lpPath, lpFileName, lpExtension, nBufferLength, lpBuffer, lpFilePart) != 0 ){
+ error = GetLastError();
+ free(lpPath);
+ free(lpFileName);
+ Fail ("SearchPathW: ERROR1 -> Found invalid file[%s][%s][%s][%d]\n", lpPath, szNoFileName, szNoFileNameExt, error);
+ }
+
+ free(lpPath);
+ free(lpFileName);
+
+ //
+ // find a file that exists, when path is mentioned explicitly
+ //
+ ZeroMemory( lpBuffer, sizeof(lpBuffer));
+ lpPath = convert((LPSTR)fullPath);
+ lpFileName = convert((LPSTR)szFileNameExistsWithExt);
+ lpExtension = NULL;
+
+ result = SearchPathW( lpPath, lpFileName, lpExtension, nBufferLength, lpBuffer, lpFilePart);
+
+ if( result == 0 ){
+ error = GetLastError();
+ free(lpPath);
+ free(lpFileName);
+ Fail ("SearchPathA: ERROR2 -> Did not Find valid file[%s][%s][%d]\n", lpPath, szFileNameExistsWithExt, error);
+ }
+
+ free(lpPath);
+ free(lpFileName);
+
+ RemoveAll();
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test1/CMakeLists.txt
index 7376b22226..5d0da64ba7 100644
--- a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- SetCurrentDirectoryA.c
+ SetCurrentDirectoryA.cpp
)
add_executable(paltest_setcurrentdirectorya_test1
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test1/SetCurrentDirectoryA.c b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test1/SetCurrentDirectoryA.c
deleted file mode 100644
index c07a62412b..0000000000
--- a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test1/SetCurrentDirectoryA.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: SetCurrentDirectoryA.c (test 1)
-**
-** Purpose: Tests the PAL implementation of the SetCurrentDirectoryA function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-
-
-
-/* In order to avoid the "chicken and egg" scenario, this is another
- method of getting the current directory. GetFullPathNameA is called with
- a dummy file name and then the file name is stripped off leaving the
- current working directory
-*/
-
-BOOL GetCurrentDir(char* szCurrentDir)
-{
- const char* szFileName = "blah";
- DWORD dwRc = 0;
- char szReturnedPath[_MAX_DIR+1];
- LPSTR pPathPtr;
- size_t nCount = 0;
-
- /* use GetFullPathNameA to to get the current path by stripping
- the file name off the end */
- memset(szReturnedPath, 0, (_MAX_DIR+1));
- dwRc = GetFullPathNameA(szFileName,
- _MAX_DIR,
- szReturnedPath,
- &pPathPtr);
-
- if (dwRc == 0)
- {
- /* GetFullPathNameA failed */
- Trace("SetCurrentDirectoryA: ERROR -> GetFullPathNameA failed "
- "with error code: %ld.\n", GetLastError());
- return(FALSE);
- }
-
- /* now strip the file name from the full path to get the current path */
- nCount = strlen(szReturnedPath) - strlen(szFileName);
- memset(szCurrentDir, 0, (_MAX_DIR+1));
- strncpy(szCurrentDir, szReturnedPath, nCount);
-
- return(TRUE);
-}
-
-
-
-int __cdecl main(int argc, char *argv[])
-{
- const char* szDirName = "testing";
- /* directory name longer than MAX_PATH characters */
- char szLongDirName[MAX_LONGPATH+1];
- char szNewDir[_MAX_DIR+1];
- char szBuiltDir[_MAX_DIR+1];
- char szHomeDir[_MAX_DIR+1];
- WCHAR* szwPtr = NULL;
-
- memset(szLongDirName, 'a', MAX_LONGPATH+1);
- if (0 != PAL_Initialize(argc,argv))
- {
- return FAIL;
- }
-
- /* remove the directory just in case a previous run of the test didn't */
- szwPtr = convert((LPSTR)szDirName);
-
- /* clean up. Remove the directory
- * if it exists */
- RemoveDirectoryW(szwPtr);
-
- /* create a temp directory off the current directory */
- if (CreateDirectoryA(szDirName, NULL) != TRUE)
- {
- free(szwPtr);
- Fail("SetCurrentDirectoryA: ERROR -> CreateDirectoryW failed "
- "with error code: %ld.\n", GetLastError());
- }
-
- /* find out what the current "home" directory is */
- memset(szHomeDir, 0, (_MAX_DIR+1));
- if(GetCurrentDir(szHomeDir) != TRUE)
- {
- if (!RemoveDirectoryW(szwPtr))
- {
- Trace("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
- "with error code: %ld.\n", GetLastError());
- }
- free(szwPtr);
- PAL_TerminateEx(FAIL);
- return FAIL;
- }
-
- /* set the current directory to the temp directory */
-
- if (SetCurrentDirectoryA(szDirName) != TRUE)
- {
- Trace("SetCurrentDirectoryA: ERROR -> Unable to set current "
- "directory. Failed with error code: %ld.\n", GetLastError());
- if (!RemoveDirectoryW(szwPtr))
- {
- Trace("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
- "with error code: %ld.\n", GetLastError());
- }
- free(szwPtr);
- Fail("");
- }
-
- /* append the temp name to the "home" directory */
- memset(szBuiltDir, 0, (_MAX_DIR+1));
-#if WIN32
- sprintf(szBuiltDir,"%s%s\\", szHomeDir, szDirName);
-#else
- sprintf(szBuiltDir,"%s%s/", szHomeDir, szDirName);
-#endif
-
- /* get the new current directory */
- memset(szNewDir, 0, (_MAX_DIR+1));
- if(GetCurrentDir(szNewDir) != TRUE)
- {
- if (!RemoveDirectoryW(szwPtr))
- {
- Trace("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
- "with error code: %ld.\n", GetLastError());
- }
- free(szwPtr);
- PAL_TerminateEx(FAIL);
- return FAIL;
- }
-
- /*compare the new current dir to the compiled current dir */
- if (strncmp(szNewDir, szBuiltDir, strlen(szNewDir)) != 0)
- {
- if (!RemoveDirectoryW(szwPtr))
- {
- Trace("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
- "with error code: %ld.\n", GetLastError());
- }
- free(szwPtr);
- Fail("SetCurrentDirectoryA: ERROR -> The set directory \"%s\" does not"
- " compare to the built directory \"%s\".\n",
- szNewDir,
- szBuiltDir);
- }
-
-
-
- /* set the current dir back to the original */
- if (SetCurrentDirectoryA(szHomeDir) != TRUE)
- {
- Trace("SetCurrentDirectoryA: ERROR -> Unable to set current "
- "directory. Failed with error code: %ld.\n", GetLastError());
- if (!RemoveDirectoryW(szwPtr))
- {
- Trace("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
- "with error code: %ld.\n", GetLastError());
- }
- free(szwPtr);
- Fail("");
- }
-
-
- /* get the new current directory */
- memset(szNewDir, 0, sizeof(char)*(_MAX_DIR+1));
- if(GetCurrentDir(szNewDir) != TRUE)
- {
- if (!RemoveDirectoryW(szwPtr))
- {
- Trace("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
- "with error code: %ld.\n", GetLastError());
- }
- free(szwPtr);
- PAL_TerminateEx(FAIL);
- return FAIL;
- }
-
- /* ensure it compares to the "home" directory which is where
- we should be now */
- if (strncmp(szNewDir, szHomeDir, strlen(szNewDir)) != 0)
- {
- if (!RemoveDirectoryW(szwPtr))
- {
- Trace("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
- "with error code: %ld.\n", GetLastError());
- }
- free(szwPtr);
- Fail("SetCurrentDirectoryA: ERROR -> The set directory does not "
- "compare to the built directory.\n");
- }
-
-
- /* clean up */
- if (!RemoveDirectoryW(szwPtr))
- {
- free(szwPtr);
- Fail("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
- "with error code: %ld.\n", GetLastError());
- }
-
- free(szwPtr);
- PAL_Terminate();
-
- return PASS;
-}
-
-
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test1/SetCurrentDirectoryA.cpp b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test1/SetCurrentDirectoryA.cpp
new file mode 100644
index 0000000000..f227aa3268
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test1/SetCurrentDirectoryA.cpp
@@ -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.
+
+/*=====================================================================
+**
+** Source: SetCurrentDirectoryA.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the SetCurrentDirectoryA function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+
+
+/* In order to avoid the "chicken and egg" scenario, this is another
+ method of getting the current directory. GetFullPathNameA is called with
+ a dummy file name and then the file name is stripped off leaving the
+ current working directory
+*/
+
+BOOL GetCurrentDir(char* szCurrentDir)
+{
+ const char* szFileName = "blah";
+ DWORD dwRc = 0;
+ char szReturnedPath[_MAX_DIR+1];
+ LPSTR pPathPtr;
+ size_t nCount = 0;
+
+ /* use GetFullPathNameA to to get the current path by stripping
+ the file name off the end */
+ memset(szReturnedPath, 0, (_MAX_DIR+1));
+ dwRc = GetFullPathNameA(szFileName,
+ _MAX_DIR,
+ szReturnedPath,
+ &pPathPtr);
+
+ if (dwRc == 0)
+ {
+ /* GetFullPathNameA failed */
+ Trace("SetCurrentDirectoryA: ERROR -> GetFullPathNameA failed "
+ "with error code: %ld.\n", GetLastError());
+ return(FALSE);
+ }
+
+ /* now strip the file name from the full path to get the current path */
+ nCount = strlen(szReturnedPath) - strlen(szFileName);
+ memset(szCurrentDir, 0, (_MAX_DIR+1));
+ strncpy(szCurrentDir, szReturnedPath, nCount);
+
+ return(TRUE);
+}
+
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ const char* szDirName = "testing";
+ /* directory name longer than MAX_PATH characters */
+ char szLongDirName[MAX_LONGPATH+1];
+ char szNewDir[_MAX_DIR+1];
+ char szBuiltDir[_MAX_DIR+1];
+ char szHomeDir[_MAX_DIR+1];
+ WCHAR* szwPtr = NULL;
+
+ memset(szLongDirName, 'a', MAX_LONGPATH+1);
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* remove the directory just in case a previous run of the test didn't */
+ szwPtr = convert((LPSTR)szDirName);
+
+ /* clean up. Remove the directory
+ * if it exists */
+ RemoveDirectoryW(szwPtr);
+
+ /* create a temp directory off the current directory */
+ if (CreateDirectoryA(szDirName, NULL) != TRUE)
+ {
+ free(szwPtr);
+ Fail("SetCurrentDirectoryA: ERROR -> CreateDirectoryW failed "
+ "with error code: %ld.\n", GetLastError());
+ }
+
+ /* find out what the current "home" directory is */
+ memset(szHomeDir, 0, (_MAX_DIR+1));
+ if(GetCurrentDir(szHomeDir) != TRUE)
+ {
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
+ "with error code: %ld.\n", GetLastError());
+ }
+ free(szwPtr);
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ /* set the current directory to the temp directory */
+
+ if (SetCurrentDirectoryA(szDirName) != TRUE)
+ {
+ Trace("SetCurrentDirectoryA: ERROR -> Unable to set current "
+ "directory. Failed with error code: %ld.\n", GetLastError());
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
+ "with error code: %ld.\n", GetLastError());
+ }
+ free(szwPtr);
+ Fail("");
+ }
+
+ /* append the temp name to the "home" directory */
+ memset(szBuiltDir, 0, (_MAX_DIR+1));
+#if WIN32
+ sprintf_s(szBuiltDir, _countof(szBuiltDir),"%s%s\\", szHomeDir, szDirName);
+#else
+ sprintf_s(szBuiltDir, _countof(szBuiltDir),"%s%s/", szHomeDir, szDirName);
+#endif
+
+ /* get the new current directory */
+ memset(szNewDir, 0, (_MAX_DIR+1));
+ if(GetCurrentDir(szNewDir) != TRUE)
+ {
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
+ "with error code: %ld.\n", GetLastError());
+ }
+ free(szwPtr);
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ /*compare the new current dir to the compiled current dir */
+ if (strncmp(szNewDir, szBuiltDir, strlen(szNewDir)) != 0)
+ {
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
+ "with error code: %ld.\n", GetLastError());
+ }
+ free(szwPtr);
+ Fail("SetCurrentDirectoryA: ERROR -> The set directory \"%s\" does not"
+ " compare to the built directory \"%s\".\n",
+ szNewDir,
+ szBuiltDir);
+ }
+
+
+
+ /* set the current dir back to the original */
+ if (SetCurrentDirectoryA(szHomeDir) != TRUE)
+ {
+ Trace("SetCurrentDirectoryA: ERROR -> Unable to set current "
+ "directory. Failed with error code: %ld.\n", GetLastError());
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
+ "with error code: %ld.\n", GetLastError());
+ }
+ free(szwPtr);
+ Fail("");
+ }
+
+
+ /* get the new current directory */
+ memset(szNewDir, 0, sizeof(char)*(_MAX_DIR+1));
+ if(GetCurrentDir(szNewDir) != TRUE)
+ {
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
+ "with error code: %ld.\n", GetLastError());
+ }
+ free(szwPtr);
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ /* ensure it compares to the "home" directory which is where
+ we should be now */
+ if (strncmp(szNewDir, szHomeDir, strlen(szNewDir)) != 0)
+ {
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
+ "with error code: %ld.\n", GetLastError());
+ }
+ free(szwPtr);
+ Fail("SetCurrentDirectoryA: ERROR -> The set directory does not "
+ "compare to the built directory.\n");
+ }
+
+
+ /* clean up */
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ free(szwPtr);
+ Fail("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
+ "with error code: %ld.\n", GetLastError());
+ }
+
+ free(szwPtr);
+ PAL_Terminate();
+
+ return PASS;
+}
+
+
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test2/CMakeLists.txt
index 7c9caf8081..243e80b9a4 100644
--- a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- setcurrentdirectorya.c
+ setcurrentdirectorya.cpp
)
add_executable(paltest_setcurrentdirectorya_test2
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test2/setcurrentdirectorya.c b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test2/setcurrentdirectorya.c
deleted file mode 100644
index 415dbbf045..0000000000
--- a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test2/setcurrentdirectorya.c
+++ /dev/null
@@ -1,142 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: SetCurrentDirectoryA.c (test 2)
-**
-** Purpose: Tests the PAL implementation of the SetCurrentDirectoryA function
-** by setting the current directory with ../
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
- const char szDirName[MAX_PATH] = "testing";
- char szBuiltDir[_MAX_DIR+1];
- char szHomeDirBefore[_MAX_DIR+1];
- char szHomeDirAfter[_MAX_DIR+1];
- WCHAR* szwPtr = NULL;
-
-
- if (0 != PAL_Initialize(argc,argv))
- {
- return FAIL;
- }
-
- /* create a temp directory off the current directory */
- szwPtr = convert((LPSTR)szDirName);
-
- if (CreateDirectoryA(szDirName, NULL) != TRUE)
- {
- free(szwPtr);
- Fail("Unexpected error: CreateDirectoryW failed "
- "with error code: %ld.\n",
- GetLastError());
- }
-
- /* find out what the current "home" directory is */
- memset(szHomeDirBefore, 0, (_MAX_DIR+1));
-
- if( 0 == GetCurrentDirectoryA((_MAX_DIR+1), szHomeDirBefore) )
- {
- Trace("Unexpected error: Unable to get current directory "
- "with GetCurrentDirectoryA that returned %ld\n",
- GetLastError());
-
- if (!RemoveDirectoryW(szwPtr))
- {
- Trace("Unexpected error: RemoveDirectoryW failed "
- "with error code: %ld.\n",
- GetLastError());
- }
- free(szwPtr);
-
- Fail("");
- }
-
- /* append the temp name to the "home" directory */
- memset(szBuiltDir, 0, (_MAX_DIR+1));
-#if WIN32
- sprintf(szBuiltDir,"%s\\..\\", szDirName);
-#else
- sprintf(szBuiltDir,"%s/../", szDirName);
-#endif
-
-
- /* set the current directory to the temp directory */
- if (SetCurrentDirectoryA(szBuiltDir) != TRUE)
- {
- Trace("ERROR: Unable to set current "
- "directory to %s. Failed with error code: %ld.\n",
- szBuiltDir,
- GetLastError());
-
- if (!RemoveDirectoryW(szwPtr))
- {
- Trace("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
- "with error code: %ld.\n",
- GetLastError());
- }
- free(szwPtr);
- Fail("");
- }
-
- /* find out what the current "home" directory is */
- memset(szHomeDirAfter, 0, (_MAX_DIR+1));
-
- if( 0 == GetCurrentDirectoryA((_MAX_DIR+1), szHomeDirAfter) )
- {
- Trace("Unexpected error: Unable to get current directory "
- "with GetCurrentDirectoryA that returned %ld\n",
- GetLastError());
-
- if (!RemoveDirectoryW(szwPtr))
- {
- Trace("Unexpected error: RemoveDirectoryW failed "
- "with error code: %ld.\n",
- GetLastError());
- }
- free(szwPtr);
-
- Fail("");
- }
-
- /*compare the new current dir to the compiled current dir */
- if (strncmp(szHomeDirBefore, szHomeDirAfter, strlen(szHomeDirBefore)) != 0)
- {
- Trace("ERROR: The set directory \"%s\" does not "
- "compare to the built directory \"%s\".\n",
- szHomeDirAfter,
- szHomeDirBefore);
-
- if (!RemoveDirectoryW(szwPtr))
- {
- Trace("Unexpected error: RemoveDirectoryW failed "
- "with error code: %ld.\n",
- GetLastError());
- }
- free(szwPtr);
- Fail("");
- }
-
- /* clean up */
- if (!RemoveDirectoryW(szwPtr))
- {
- free(szwPtr);
- Fail("Unexpected error: RemoveDirectoryW failed "
- "with error code: %ld.\n",
- GetLastError());
- }
-
- free(szwPtr);
- PAL_Terminate();
-
- return PASS;
-}
-
-
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test2/setcurrentdirectorya.cpp b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test2/setcurrentdirectorya.cpp
new file mode 100644
index 0000000000..4b1c1c8790
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test2/setcurrentdirectorya.cpp
@@ -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.
+
+/*=====================================================================
+**
+** Source: SetCurrentDirectoryA.c (test 2)
+**
+** Purpose: Tests the PAL implementation of the SetCurrentDirectoryA function
+** by setting the current directory with ../
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+ const char szDirName[MAX_PATH] = "testing";
+ char szBuiltDir[_MAX_DIR+1];
+ char szHomeDirBefore[_MAX_DIR+1];
+ char szHomeDirAfter[_MAX_DIR+1];
+ WCHAR* szwPtr = NULL;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* create a temp directory off the current directory */
+ szwPtr = convert((LPSTR)szDirName);
+
+ if (CreateDirectoryA(szDirName, NULL) != TRUE)
+ {
+ free(szwPtr);
+ Fail("Unexpected error: CreateDirectoryW failed "
+ "with error code: %ld.\n",
+ GetLastError());
+ }
+
+ /* find out what the current "home" directory is */
+ memset(szHomeDirBefore, 0, (_MAX_DIR+1));
+
+ if( 0 == GetCurrentDirectoryA((_MAX_DIR+1), szHomeDirBefore) )
+ {
+ Trace("Unexpected error: Unable to get current directory "
+ "with GetCurrentDirectoryA that returned %ld\n",
+ GetLastError());
+
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("Unexpected error: RemoveDirectoryW failed "
+ "with error code: %ld.\n",
+ GetLastError());
+ }
+ free(szwPtr);
+
+ Fail("");
+ }
+
+ /* append the temp name to the "home" directory */
+ memset(szBuiltDir, 0, (_MAX_DIR+1));
+#if WIN32
+ sprintf_s(szBuiltDir, _countof(szBuiltDir),"%s\\..\\", szDirName);
+#else
+ sprintf_s(szBuiltDir, _countof(szBuiltDir),"%s/../", szDirName);
+#endif
+
+
+ /* set the current directory to the temp directory */
+ if (SetCurrentDirectoryA(szBuiltDir) != TRUE)
+ {
+ Trace("ERROR: Unable to set current "
+ "directory to %s. Failed with error code: %ld.\n",
+ szBuiltDir,
+ GetLastError());
+
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("SetCurrentDirectoryA: ERROR -> RemoveDirectoryW failed "
+ "with error code: %ld.\n",
+ GetLastError());
+ }
+ free(szwPtr);
+ Fail("");
+ }
+
+ /* find out what the current "home" directory is */
+ memset(szHomeDirAfter, 0, (_MAX_DIR+1));
+
+ if( 0 == GetCurrentDirectoryA((_MAX_DIR+1), szHomeDirAfter) )
+ {
+ Trace("Unexpected error: Unable to get current directory "
+ "with GetCurrentDirectoryA that returned %ld\n",
+ GetLastError());
+
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("Unexpected error: RemoveDirectoryW failed "
+ "with error code: %ld.\n",
+ GetLastError());
+ }
+ free(szwPtr);
+
+ Fail("");
+ }
+
+ /*compare the new current dir to the compiled current dir */
+ if (strncmp(szHomeDirBefore, szHomeDirAfter, strlen(szHomeDirBefore)) != 0)
+ {
+ Trace("ERROR: The set directory \"%s\" does not "
+ "compare to the built directory \"%s\".\n",
+ szHomeDirAfter,
+ szHomeDirBefore);
+
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("Unexpected error: RemoveDirectoryW failed "
+ "with error code: %ld.\n",
+ GetLastError());
+ }
+ free(szwPtr);
+ Fail("");
+ }
+
+ /* clean up */
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ free(szwPtr);
+ Fail("Unexpected error: RemoveDirectoryW failed "
+ "with error code: %ld.\n",
+ GetLastError());
+ }
+
+ free(szwPtr);
+ PAL_Terminate();
+
+ return PASS;
+}
+
+
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test3/CMakeLists.txt
index 57d3577d8f..8560ff0187 100644
--- a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- setcurrentdirectorya.c
+ setcurrentdirectorya.cpp
)
add_executable(paltest_setcurrentdirectorya_test3
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test3/setcurrentdirectorya.c b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test3/setcurrentdirectorya.cpp
index a23a7a6314..a23a7a6314 100644
--- a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test3/setcurrentdirectorya.c
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryA/test3/setcurrentdirectorya.cpp
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test1/CMakeLists.txt
index a0c1dff62a..9149221008 100644
--- a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- SetCurrentDirectoryW.c
+ SetCurrentDirectoryW.cpp
)
add_executable(paltest_setcurrentdirectoryw_test1
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test1/SetCurrentDirectoryW.c b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test1/SetCurrentDirectoryW.c
deleted file mode 100644
index 257d016ffb..0000000000
--- a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test1/SetCurrentDirectoryW.c
+++ /dev/null
@@ -1,178 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: SetCurrentDirectoryW.c (test 1)
-**
-** Purpose: Tests the PAL implementation of the SetCurrentDirectoryW function.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-
-const char* szFileName = "blah";
-const char* szDirName = "testing";
-
-
-// In order to avoid the "chicken and egg" scenario, this is another
-// method of getting the current directory. GetFullPathNameW is called with
-// a dummy file name and then the file name is stripped off leaving the
-// current working directory
-BOOL GetCurrentDir(WCHAR* szwCurrentDir)
-{
- DWORD dwRc = 0;
- WCHAR szwReturnedPath[_MAX_DIR+1];
- LPWSTR pPathPtr;
- WCHAR* szwFileName = NULL;
- WCHAR* szwDirName = NULL;
- int nCount = 0;
-
- // use GetFullPathName to to get the current path by stripping
- // the file name off the end
- memset(szwReturnedPath, 0, sizeof(WCHAR)*(_MAX_DIR+1));
- szwFileName = convert((char*)szFileName);
- dwRc = GetFullPathNameW(szwFileName,
- _MAX_DIR,
- szwReturnedPath,
- &pPathPtr);
-
- if (dwRc == 0)
- {
- // GetFullPathName failed
- Trace("SetCurrentDirectoryW: ERROR -> GetFullPathNameW failed "
- "with error code: %ld.\n", GetLastError());
- RemoveDirectoryW(szwDirName);
- free(szwFileName);
- return(FALSE);
- }
-
- // now strip the file name from the full path to get the current path
- nCount = lstrlenW(szwReturnedPath) - lstrlenW(szwFileName);
- memset(szwCurrentDir, 0, sizeof(WCHAR)*(_MAX_DIR+1));
- lstrcpynW(szwCurrentDir, szwReturnedPath, nCount);
-
- free(szwFileName);
- return(TRUE);
-}
-
-int __cdecl main(int argc, char *argv[])
-{
- WCHAR* szwDirName = NULL;
- WCHAR szwNewDir[_MAX_DIR+1];
- WCHAR szwBuiltDir[_MAX_DIR+1];
- WCHAR szwHomeDir[_MAX_DIR+1];
-#if WIN32
- WCHAR szwSlash[] = {'\\','\0'};
-#else
- WCHAR szwSlash[] = {'/','\0'};
-#endif
-
- if (0 != PAL_Initialize(argc,argv))
- {
- return FAIL;
- }
-
- // remove the directory just in case a previous run of the test didn't
- szwDirName = convert((char*)szDirName);
- RemoveDirectoryW(szwDirName);
-
- // create a temp directory off the current directory
- if (CreateDirectoryW(szwDirName, NULL) != TRUE)
- {
- Trace("SetCurrentDirectoryW: ERROR -> CreateDirectoryW failed "
- "with error code: %ld.\n", GetLastError());
- RemoveDirectoryW(szwDirName);
- free(szwDirName);
- Fail("");
- }
-
- // find out what the current "home" directory is
- memset(szwHomeDir, 0, sizeof(WCHAR)*(_MAX_DIR+1));
- if(GetCurrentDir(szwHomeDir) != TRUE)
- {
- RemoveDirectoryW(szwDirName);
- free(szwDirName);
- PAL_TerminateEx(FAIL);
- return FAIL;
- }
-
- // set the current directory to the temp directory
- if (SetCurrentDirectoryW(szwDirName) != TRUE)
- {
- Trace("SetCurrentDirectoryW: ERROR -> Unable to set current "
- "directory. Failed with error code: %ld.\n", GetLastError());
- RemoveDirectoryW(szwDirName);
- free(szwDirName);
- Fail("");
- }
-
- // append the temp name to the "home" directory
- memset(szwBuiltDir, 0, sizeof(WCHAR)*(_MAX_DIR+1));
- wcscpy(szwBuiltDir, szwHomeDir);
- wcscat(szwBuiltDir, szwSlash);
- wcscat(szwBuiltDir, szwDirName);
-
- // get the new current directory
- memset(szwNewDir, 0, sizeof(WCHAR)*(_MAX_DIR+1));
- if(GetCurrentDir(szwNewDir) != TRUE)
- {
- RemoveDirectoryW(szwDirName);
- free(szwDirName);
- PAL_TerminateEx(FAIL);
- return FAIL;
- }
-
- // compare the new current dir to the compiled current dir
- if (wcsncmp(szwNewDir, szwBuiltDir, wcslen(szwNewDir)) != 0)
- {
- RemoveDirectoryW(szwDirName);
- free(szwDirName);
- Fail("SetCurrentDirectoryW: ERROR -> The set directory does not "
- "compare to the built directory.\n");
- }
-
-
-
- // set the current dir back to the original
- if (SetCurrentDirectoryW(szwHomeDir) != TRUE)
- {
- Trace("SetCurrentDirectoryW: ERROR -> Unable to set current "
- "directory. Failed with error code: %ld.\n", GetLastError());
- RemoveDirectoryW(szwDirName);
- free(szwDirName);
- Fail("");
- }
-
-
- // get the new current directory
- memset(szwNewDir, 0, sizeof(WCHAR)*(_MAX_DIR+1));
- if(GetCurrentDir(szwNewDir) != TRUE)
- {
- RemoveDirectoryW(szwDirName);
- free(szwDirName);
- PAL_TerminateEx(FAIL);
- return FAIL;
- }
-
- // ensure it compares to the "home" directory which is where
- // we should be now
- if (wcsncmp(szwNewDir, szwHomeDir, wcslen(szwNewDir)) != 0)
- {
- RemoveDirectoryW(szwDirName);
- free(szwDirName);
- Fail("SetCurrentDirectoryW: ERROR -> The set directory does not "
- "compare to the built directory.\n");
- }
-
-
- RemoveDirectoryW(szwDirName);
- free(szwDirName);
- PAL_Terminate();
-
- return PASS;
-}
-
-
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test1/SetCurrentDirectoryW.cpp b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test1/SetCurrentDirectoryW.cpp
new file mode 100644
index 0000000000..e10f2ea8a1
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test1/SetCurrentDirectoryW.cpp
@@ -0,0 +1,178 @@
+// Licensed to the .NET Foundation under one or more 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: SetCurrentDirectoryW.c (test 1)
+**
+** Purpose: Tests the PAL implementation of the SetCurrentDirectoryW function.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+const char* szFileName = "blah";
+const char* szDirName = "testing";
+
+
+// In order to avoid the "chicken and egg" scenario, this is another
+// method of getting the current directory. GetFullPathNameW is called with
+// a dummy file name and then the file name is stripped off leaving the
+// current working directory
+BOOL GetCurrentDir(WCHAR* szwCurrentDir)
+{
+ DWORD dwRc = 0;
+ WCHAR szwReturnedPath[_MAX_DIR+1];
+ LPWSTR pPathPtr;
+ WCHAR* szwFileName = NULL;
+ WCHAR* szwDirName = NULL;
+ int nCount = 0;
+
+ // use GetFullPathName to to get the current path by stripping
+ // the file name off the end
+ memset(szwReturnedPath, 0, sizeof(WCHAR)*(_MAX_DIR+1));
+ szwFileName = convert((char*)szFileName);
+ dwRc = GetFullPathNameW(szwFileName,
+ _MAX_DIR,
+ szwReturnedPath,
+ &pPathPtr);
+
+ if (dwRc == 0)
+ {
+ // GetFullPathName failed
+ Trace("SetCurrentDirectoryW: ERROR -> GetFullPathNameW failed "
+ "with error code: %ld.\n", GetLastError());
+ RemoveDirectoryW(szwDirName);
+ free(szwFileName);
+ return(FALSE);
+ }
+
+ // now strip the file name from the full path to get the current path
+ nCount = lstrlenW(szwReturnedPath) - lstrlenW(szwFileName);
+ memset(szwCurrentDir, 0, sizeof(WCHAR)*(_MAX_DIR+1));
+ wcsncpy(szwCurrentDir, szwReturnedPath, nCount - 1);
+
+ free(szwFileName);
+ return(TRUE);
+}
+
+int __cdecl main(int argc, char *argv[])
+{
+ WCHAR* szwDirName = NULL;
+ WCHAR szwNewDir[_MAX_DIR+1];
+ WCHAR szwBuiltDir[_MAX_DIR+1];
+ WCHAR szwHomeDir[_MAX_DIR+1];
+#if WIN32
+ WCHAR szwSlash[] = {'\\','\0'};
+#else
+ WCHAR szwSlash[] = {'/','\0'};
+#endif
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ // remove the directory just in case a previous run of the test didn't
+ szwDirName = convert((char*)szDirName);
+ RemoveDirectoryW(szwDirName);
+
+ // create a temp directory off the current directory
+ if (CreateDirectoryW(szwDirName, NULL) != TRUE)
+ {
+ Trace("SetCurrentDirectoryW: ERROR -> CreateDirectoryW failed "
+ "with error code: %ld.\n", GetLastError());
+ RemoveDirectoryW(szwDirName);
+ free(szwDirName);
+ Fail("");
+ }
+
+ // find out what the current "home" directory is
+ memset(szwHomeDir, 0, sizeof(WCHAR)*(_MAX_DIR+1));
+ if(GetCurrentDir(szwHomeDir) != TRUE)
+ {
+ RemoveDirectoryW(szwDirName);
+ free(szwDirName);
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ // set the current directory to the temp directory
+ if (SetCurrentDirectoryW(szwDirName) != TRUE)
+ {
+ Trace("SetCurrentDirectoryW: ERROR -> Unable to set current "
+ "directory. Failed with error code: %ld.\n", GetLastError());
+ RemoveDirectoryW(szwDirName);
+ free(szwDirName);
+ Fail("");
+ }
+
+ // append the temp name to the "home" directory
+ memset(szwBuiltDir, 0, sizeof(WCHAR)*(_MAX_DIR+1));
+ wcscpy(szwBuiltDir, szwHomeDir);
+ wcscat(szwBuiltDir, szwSlash);
+ wcscat(szwBuiltDir, szwDirName);
+
+ // get the new current directory
+ memset(szwNewDir, 0, sizeof(WCHAR)*(_MAX_DIR+1));
+ if(GetCurrentDir(szwNewDir) != TRUE)
+ {
+ RemoveDirectoryW(szwDirName);
+ free(szwDirName);
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ // compare the new current dir to the compiled current dir
+ if (wcsncmp(szwNewDir, szwBuiltDir, wcslen(szwNewDir)) != 0)
+ {
+ RemoveDirectoryW(szwDirName);
+ free(szwDirName);
+ Fail("SetCurrentDirectoryW: ERROR -> The set directory does not "
+ "compare to the built directory.\n");
+ }
+
+
+
+ // set the current dir back to the original
+ if (SetCurrentDirectoryW(szwHomeDir) != TRUE)
+ {
+ Trace("SetCurrentDirectoryW: ERROR -> Unable to set current "
+ "directory. Failed with error code: %ld.\n", GetLastError());
+ RemoveDirectoryW(szwDirName);
+ free(szwDirName);
+ Fail("");
+ }
+
+
+ // get the new current directory
+ memset(szwNewDir, 0, sizeof(WCHAR)*(_MAX_DIR+1));
+ if(GetCurrentDir(szwNewDir) != TRUE)
+ {
+ RemoveDirectoryW(szwDirName);
+ free(szwDirName);
+ PAL_TerminateEx(FAIL);
+ return FAIL;
+ }
+
+ // ensure it compares to the "home" directory which is where
+ // we should be now
+ if (wcsncmp(szwNewDir, szwHomeDir, wcslen(szwNewDir)) != 0)
+ {
+ RemoveDirectoryW(szwDirName);
+ free(szwDirName);
+ Fail("SetCurrentDirectoryW: ERROR -> The set directory does not "
+ "compare to the built directory.\n");
+ }
+
+
+ RemoveDirectoryW(szwDirName);
+ free(szwDirName);
+ PAL_Terminate();
+
+ return PASS;
+}
+
+
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test2/CMakeLists.txt
index a032462d19..455ddc828d 100644
--- a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- setcurrentdirectoryw.c
+ setcurrentdirectoryw.cpp
)
add_executable(paltest_setcurrentdirectoryw_test2
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test2/setcurrentdirectoryw.c b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test2/setcurrentdirectoryw.c
deleted file mode 100644
index 7e3d7b785f..0000000000
--- a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test2/setcurrentdirectoryw.c
+++ /dev/null
@@ -1,147 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: SetCurrentDirectoryW.c (test 2)
-**
-** Purpose: Tests the PAL implementation of the SetCurrentDirectoryW function
-** by setting the current directory with ../
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
- const char szDirName[MAX_PATH] = "testing";
- char szBuiltDir[MAX_PATH];
- WCHAR* szwBuiltDir = NULL;
- WCHAR szwHomeDirBefore[MAX_PATH];
- WCHAR szwHomeDirAfter[MAX_PATH];
- WCHAR* szwPtr = NULL;
-
-
- if (0 != PAL_Initialize(argc,argv))
- {
- return FAIL;
- }
-
- /* create a temp directory off the current directory */
- szwPtr = convert((LPSTR)szDirName);
-
- if (CreateDirectoryW(szwPtr, NULL) != TRUE)
- {
- free(szwPtr);
- Fail("Unexpected error: CreateDirectoryW failed "
- "with error code: %ld.\n",
- GetLastError());
- }
-
- /* find out what the current "home" directory is */
- memset(szwHomeDirBefore, 0, MAX_PATH * sizeof(WCHAR));
-
- if( 0 == GetCurrentDirectoryW(MAX_PATH, szwHomeDirBefore) )
- {
- Trace("Unexpected error: Unable to get current directory "
- "with GetCurrentDirectoryW that returned %ld\n",
- GetLastError());
-
- if (!RemoveDirectoryW(szwPtr))
- {
- Trace("Unexpected error: RemoveDirectoryW failed "
- "with error code: %ld.\n",
- GetLastError());
- }
- free(szwPtr);
-
- Fail("");
- }
-
- /* append the temp name to the "home" directory */
- memset(szBuiltDir, 0, MAX_PATH);
-#if WIN32
- sprintf(szBuiltDir,"%s\\..\\", szDirName);
-#else
- sprintf(szBuiltDir,"%s/../", szDirName);
-#endif
-
- szwBuiltDir = convert(szBuiltDir);
-
- /* set the current directory to the temp directory */
- if (SetCurrentDirectoryW(szwBuiltDir) != TRUE)
- {
- Trace("ERROR: Unable to set current "
- "directory to %S. Failed with error code: %ld.\n",
- szwBuiltDir,
- GetLastError());
-
- if (!RemoveDirectoryW(szwPtr))
- {
- Trace("Unexpected error: RemoveDirectoryW failed "
- "with error code: %ld.\n",
- GetLastError());
- }
- free(szwPtr);
- free(szwBuiltDir);
- Fail("");
- }
-
- free(szwBuiltDir);
-
- /* find out what the current "home" directory is */
- memset(szwHomeDirAfter, 0, MAX_PATH * sizeof(WCHAR));
-
- if( 0 == GetCurrentDirectoryW(MAX_PATH, szwHomeDirAfter) )
- {
- Trace("Unexpected error: Unable to get current directory "
- "with GetCurrentDirectoryW that returned %ld\n",
- GetLastError());
-
- if (!RemoveDirectoryW(szwPtr))
- {
- Trace("ERROR: RemoveDirectoryW failed "
- "with error code: %ld.\n",
- GetLastError());
- }
- free(szwPtr);
-
- Fail("");
- }
-
- /*compare the new current dir to the compiled current dir */
- if (wcsncmp(szwHomeDirBefore, szwHomeDirAfter, wcslen(szwHomeDirBefore)) != 0)
- {
- Trace("ERROR:The set directory \"%S\" does not "
- "compare to the built directory \"%S\".\n",
- szwHomeDirAfter,
- szwHomeDirBefore);
-
- if (!RemoveDirectoryW(szwPtr))
- {
- Trace("Unexpected error: RemoveDirectoryW failed "
- "with error code: %ld.\n",
- GetLastError());
- }
- free(szwPtr);
- Fail("");
- }
-
- /* clean up */
- if (!RemoveDirectoryW(szwPtr))
- {
- free(szwPtr);
- Fail("Unexpected error: RemoveDirectoryW failed "
- "with error code: %ld.\n",
- GetLastError());
- }
-
- free(szwPtr);
- PAL_Terminate();
-
- return PASS;
-}
-
-
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test2/setcurrentdirectoryw.cpp b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test2/setcurrentdirectoryw.cpp
new file mode 100644
index 0000000000..7f833baabc
--- /dev/null
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test2/setcurrentdirectoryw.cpp
@@ -0,0 +1,147 @@
+// Licensed to the .NET Foundation under one or more 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: SetCurrentDirectoryW.c (test 2)
+**
+** Purpose: Tests the PAL implementation of the SetCurrentDirectoryW function
+** by setting the current directory with ../
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+ const char szDirName[MAX_PATH] = "testing";
+ char szBuiltDir[MAX_PATH];
+ WCHAR* szwBuiltDir = NULL;
+ WCHAR szwHomeDirBefore[MAX_PATH];
+ WCHAR szwHomeDirAfter[MAX_PATH];
+ WCHAR* szwPtr = NULL;
+
+
+ if (0 != PAL_Initialize(argc,argv))
+ {
+ return FAIL;
+ }
+
+ /* create a temp directory off the current directory */
+ szwPtr = convert((LPSTR)szDirName);
+
+ if (CreateDirectoryW(szwPtr, NULL) != TRUE)
+ {
+ free(szwPtr);
+ Fail("Unexpected error: CreateDirectoryW failed "
+ "with error code: %ld.\n",
+ GetLastError());
+ }
+
+ /* find out what the current "home" directory is */
+ memset(szwHomeDirBefore, 0, MAX_PATH * sizeof(WCHAR));
+
+ if( 0 == GetCurrentDirectoryW(MAX_PATH, szwHomeDirBefore) )
+ {
+ Trace("Unexpected error: Unable to get current directory "
+ "with GetCurrentDirectoryW that returned %ld\n",
+ GetLastError());
+
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("Unexpected error: RemoveDirectoryW failed "
+ "with error code: %ld.\n",
+ GetLastError());
+ }
+ free(szwPtr);
+
+ Fail("");
+ }
+
+ /* append the temp name to the "home" directory */
+ memset(szBuiltDir, 0, MAX_PATH);
+#if WIN32
+ sprintf_s(szBuiltDir, _countof(szBuiltDir),"%s\\..\\", szDirName);
+#else
+ sprintf_s(szBuiltDir, _countof(szBuiltDir),"%s/../", szDirName);
+#endif
+
+ szwBuiltDir = convert(szBuiltDir);
+
+ /* set the current directory to the temp directory */
+ if (SetCurrentDirectoryW(szwBuiltDir) != TRUE)
+ {
+ Trace("ERROR: Unable to set current "
+ "directory to %S. Failed with error code: %ld.\n",
+ szwBuiltDir,
+ GetLastError());
+
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("Unexpected error: RemoveDirectoryW failed "
+ "with error code: %ld.\n",
+ GetLastError());
+ }
+ free(szwPtr);
+ free(szwBuiltDir);
+ Fail("");
+ }
+
+ free(szwBuiltDir);
+
+ /* find out what the current "home" directory is */
+ memset(szwHomeDirAfter, 0, MAX_PATH * sizeof(WCHAR));
+
+ if( 0 == GetCurrentDirectoryW(MAX_PATH, szwHomeDirAfter) )
+ {
+ Trace("Unexpected error: Unable to get current directory "
+ "with GetCurrentDirectoryW that returned %ld\n",
+ GetLastError());
+
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("ERROR: RemoveDirectoryW failed "
+ "with error code: %ld.\n",
+ GetLastError());
+ }
+ free(szwPtr);
+
+ Fail("");
+ }
+
+ /*compare the new current dir to the compiled current dir */
+ if (wcsncmp(szwHomeDirBefore, szwHomeDirAfter, wcslen(szwHomeDirBefore)) != 0)
+ {
+ Trace("ERROR:The set directory \"%S\" does not "
+ "compare to the built directory \"%S\".\n",
+ szwHomeDirAfter,
+ szwHomeDirBefore);
+
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ Trace("Unexpected error: RemoveDirectoryW failed "
+ "with error code: %ld.\n",
+ GetLastError());
+ }
+ free(szwPtr);
+ Fail("");
+ }
+
+ /* clean up */
+ if (!RemoveDirectoryW(szwPtr))
+ {
+ free(szwPtr);
+ Fail("Unexpected error: RemoveDirectoryW failed "
+ "with error code: %ld.\n",
+ GetLastError());
+ }
+
+ free(szwPtr);
+ PAL_Terminate();
+
+ return PASS;
+}
+
+
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test3/CMakeLists.txt
index 3b981f9564..1cb1150a61 100644
--- a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- setcurrentdirectoryw.c
+ setcurrentdirectoryw.cpp
)
add_executable(paltest_setcurrentdirectoryw_test3
diff --git a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test3/setcurrentdirectoryw.c b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test3/setcurrentdirectoryw.cpp
index e8c4be2ad4..e8c4be2ad4 100644
--- a/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test3/setcurrentdirectoryw.c
+++ b/src/pal/tests/palsuite/file_io/SetCurrentDirectoryW/test3/setcurrentdirectoryw.cpp
diff --git a/src/pal/tests/palsuite/file_io/SetEndOfFile/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetEndOfFile/test1/CMakeLists.txt
index e77ab30b86..3c0fdeec22 100644
--- a/src/pal/tests/palsuite/file_io/SetEndOfFile/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetEndOfFile/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- SetEndOfFile.c
+ SetEndOfFile.cpp
)
add_executable(paltest_setendoffile_test1
diff --git a/src/pal/tests/palsuite/file_io/SetEndOfFile/test1/SetEndOfFile.c b/src/pal/tests/palsuite/file_io/SetEndOfFile/test1/SetEndOfFile.cpp
index 9078ddc65b..9078ddc65b 100644
--- a/src/pal/tests/palsuite/file_io/SetEndOfFile/test1/SetEndOfFile.c
+++ b/src/pal/tests/palsuite/file_io/SetEndOfFile/test1/SetEndOfFile.cpp
diff --git a/src/pal/tests/palsuite/file_io/SetEndOfFile/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetEndOfFile/test2/CMakeLists.txt
index b04dea04a6..57afdad2fd 100644
--- a/src/pal/tests/palsuite/file_io/SetEndOfFile/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetEndOfFile/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- SetEndOfFile.c
+ SetEndOfFile.cpp
)
add_executable(paltest_setendoffile_test2
diff --git a/src/pal/tests/palsuite/file_io/SetEndOfFile/test2/SetEndOfFile.c b/src/pal/tests/palsuite/file_io/SetEndOfFile/test2/SetEndOfFile.cpp
index 6b3c05088e..6b3c05088e 100644
--- a/src/pal/tests/palsuite/file_io/SetEndOfFile/test2/SetEndOfFile.c
+++ b/src/pal/tests/palsuite/file_io/SetEndOfFile/test2/SetEndOfFile.cpp
diff --git a/src/pal/tests/palsuite/file_io/SetEndOfFile/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetEndOfFile/test3/CMakeLists.txt
index 1ab177d00a..01575ce09b 100644
--- a/src/pal/tests/palsuite/file_io/SetEndOfFile/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetEndOfFile/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- SetEndOfFile.c
+ SetEndOfFile.cpp
)
add_executable(paltest_setendoffile_test3
diff --git a/src/pal/tests/palsuite/file_io/SetEndOfFile/test3/SetEndOfFile.c b/src/pal/tests/palsuite/file_io/SetEndOfFile/test3/SetEndOfFile.cpp
index dfd9194465..dfd9194465 100644
--- a/src/pal/tests/palsuite/file_io/SetEndOfFile/test3/SetEndOfFile.c
+++ b/src/pal/tests/palsuite/file_io/SetEndOfFile/test3/SetEndOfFile.cpp
diff --git a/src/pal/tests/palsuite/file_io/SetEndOfFile/test4/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetEndOfFile/test4/CMakeLists.txt
index ff0b6f999c..1dc4f68aef 100644
--- a/src/pal/tests/palsuite/file_io/SetEndOfFile/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetEndOfFile/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- setendoffile.c
+ setendoffile.cpp
)
add_executable(paltest_setendoffile_test4
diff --git a/src/pal/tests/palsuite/file_io/SetEndOfFile/test4/setendoffile.c b/src/pal/tests/palsuite/file_io/SetEndOfFile/test4/setendoffile.cpp
index 98a6ec63da..98a6ec63da 100644
--- a/src/pal/tests/palsuite/file_io/SetEndOfFile/test4/setendoffile.c
+++ b/src/pal/tests/palsuite/file_io/SetEndOfFile/test4/setendoffile.cpp
diff --git a/src/pal/tests/palsuite/file_io/SetEndOfFile/test5/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetEndOfFile/test5/CMakeLists.txt
index cca7167762..19f87a28af 100644
--- a/src/pal/tests/palsuite/file_io/SetEndOfFile/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetEndOfFile/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_setendoffile_test5
diff --git a/src/pal/tests/palsuite/file_io/SetEndOfFile/test5/test5.c b/src/pal/tests/palsuite/file_io/SetEndOfFile/test5/test5.cpp
index 7000d1af15..7000d1af15 100644
--- a/src/pal/tests/palsuite/file_io/SetEndOfFile/test5/test5.c
+++ b/src/pal/tests/palsuite/file_io/SetEndOfFile/test5/test5.cpp
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test1/CMakeLists.txt
index 81e2dfdea2..638dd5c425 100644
--- a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- SetFileAttributesA.c
+ SetFileAttributesA.cpp
)
add_executable(paltest_setfileattributesa_test1
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test1/SetFileAttributesA.c b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test1/SetFileAttributesA.cpp
index bacab2a0ad..bacab2a0ad 100644
--- a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test1/SetFileAttributesA.c
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test1/SetFileAttributesA.cpp
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/CMakeLists.txt
index 03445c1df0..51bee5af39 100644
--- a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- SetFileAttributesA.c
+ SetFileAttributesA.cpp
)
add_executable(paltest_setfileattributesa_test2
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/SetFileAttributesA.c b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/SetFileAttributesA.cpp
index 5c04a6b181..5c04a6b181 100644
--- a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/SetFileAttributesA.c
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test2/SetFileAttributesA.cpp
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test3/CMakeLists.txt
index 3c35172d7c..4597e1d22c 100644
--- a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- SetFileAttributesA.c
+ SetFileAttributesA.cpp
)
add_executable(paltest_setfileattributesa_test3
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test3/SetFileAttributesA.c b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test3/SetFileAttributesA.cpp
index 445b515c7f..445b515c7f 100644
--- a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test3/SetFileAttributesA.c
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test3/SetFileAttributesA.cpp
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test4/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test4/CMakeLists.txt
index f30969ad04..1807027123 100644
--- a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- SetFileAttributesA.c
+ SetFileAttributesA.cpp
)
add_executable(paltest_setfileattributesa_test4
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test4/SetFileAttributesA.c b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test4/SetFileAttributesA.cpp
index 240e89ff6f..240e89ff6f 100644
--- a/src/pal/tests/palsuite/file_io/SetFileAttributesA/test4/SetFileAttributesA.c
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesA/test4/SetFileAttributesA.cpp
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test1/CMakeLists.txt
index 35927b4b1d..825554da74 100644
--- a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- SetFileAttributesW.c
+ SetFileAttributesW.cpp
)
add_executable(paltest_setfileattributesw_test1
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test1/SetFileAttributesW.c b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test1/SetFileAttributesW.cpp
index 753c396d1f..753c396d1f 100644
--- a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test1/SetFileAttributesW.c
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test1/SetFileAttributesW.cpp
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/CMakeLists.txt
index 81fa02c1dd..fda1cec1d7 100644
--- a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- SetFileAttributesW.c
+ SetFileAttributesW.cpp
)
add_executable(paltest_setfileattributesw_test2
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/SetFileAttributesW.c b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/SetFileAttributesW.cpp
index f657436845..f657436845 100644
--- a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/SetFileAttributesW.c
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test2/SetFileAttributesW.cpp
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test3/CMakeLists.txt
index c2cdacb0d0..1757f88bfe 100644
--- a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- SetFileAttributesW.c
+ SetFileAttributesW.cpp
)
add_executable(paltest_setfileattributesw_test3
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test3/SetFileAttributesW.c b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test3/SetFileAttributesW.cpp
index 8a8bafac68..8a8bafac68 100644
--- a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test3/SetFileAttributesW.c
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test3/SetFileAttributesW.cpp
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test4/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test4/CMakeLists.txt
index 6a4aa8adc3..d1cfcdd07d 100644
--- a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- SetFileAttributesW.c
+ SetFileAttributesW.cpp
)
add_executable(paltest_setfileattributesw_test4
diff --git a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test4/SetFileAttributesW.c b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test4/SetFileAttributesW.cpp
index bebadfa264..bebadfa264 100644
--- a/src/pal/tests/palsuite/file_io/SetFileAttributesW/test4/SetFileAttributesW.c
+++ b/src/pal/tests/palsuite/file_io/SetFileAttributesW/test4/SetFileAttributesW.cpp
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFilePointer/test1/CMakeLists.txt
index e352449981..bb09a981e9 100644
--- a/src/pal/tests/palsuite/file_io/SetFilePointer/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- SetFilePointer.c
+ SetFilePointer.cpp
)
add_executable(paltest_setfilepointer_test1
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test1/SetFilePointer.c b/src/pal/tests/palsuite/file_io/SetFilePointer/test1/SetFilePointer.cpp
index 14b5f85e69..14b5f85e69 100644
--- a/src/pal/tests/palsuite/file_io/SetFilePointer/test1/SetFilePointer.c
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test1/SetFilePointer.cpp
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFilePointer/test2/CMakeLists.txt
index 290a01107f..2e76f00c99 100644
--- a/src/pal/tests/palsuite/file_io/SetFilePointer/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- SetFilePointer.c
+ SetFilePointer.cpp
)
add_executable(paltest_setfilepointer_test2
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test2/SetFilePointer.c b/src/pal/tests/palsuite/file_io/SetFilePointer/test2/SetFilePointer.cpp
index 19e99a74b3..19e99a74b3 100644
--- a/src/pal/tests/palsuite/file_io/SetFilePointer/test2/SetFilePointer.c
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test2/SetFilePointer.cpp
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFilePointer/test3/CMakeLists.txt
index daa7553a1a..bcc3faca09 100644
--- a/src/pal/tests/palsuite/file_io/SetFilePointer/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- SetFilePointer.c
+ SetFilePointer.cpp
)
add_executable(paltest_setfilepointer_test3
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test3/SetFilePointer.c b/src/pal/tests/palsuite/file_io/SetFilePointer/test3/SetFilePointer.cpp
index dd53829629..dd53829629 100644
--- a/src/pal/tests/palsuite/file_io/SetFilePointer/test3/SetFilePointer.c
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test3/SetFilePointer.cpp
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test4/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFilePointer/test4/CMakeLists.txt
index 1117893350..3fcc4066f2 100644
--- a/src/pal/tests/palsuite/file_io/SetFilePointer/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- SetFilePointer.c
+ SetFilePointer.cpp
)
add_executable(paltest_setfilepointer_test4
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test4/SetFilePointer.c b/src/pal/tests/palsuite/file_io/SetFilePointer/test4/SetFilePointer.cpp
index 2993cfd354..2993cfd354 100644
--- a/src/pal/tests/palsuite/file_io/SetFilePointer/test4/SetFilePointer.c
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test4/SetFilePointer.cpp
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test5/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFilePointer/test5/CMakeLists.txt
index b37bf42ffc..3012009e4f 100644
--- a/src/pal/tests/palsuite/file_io/SetFilePointer/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- SetFilePointer.c
+ SetFilePointer.cpp
)
add_executable(paltest_setfilepointer_test5
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test5/SetFilePointer.c b/src/pal/tests/palsuite/file_io/SetFilePointer/test5/SetFilePointer.cpp
index f1d392da38..f1d392da38 100644
--- a/src/pal/tests/palsuite/file_io/SetFilePointer/test5/SetFilePointer.c
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test5/SetFilePointer.cpp
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test6/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFilePointer/test6/CMakeLists.txt
index 8f99ed2d76..a376acbe28 100644
--- a/src/pal/tests/palsuite/file_io/SetFilePointer/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- SetFilePointer.c
+ SetFilePointer.cpp
)
add_executable(paltest_setfilepointer_test6
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test6/SetFilePointer.c b/src/pal/tests/palsuite/file_io/SetFilePointer/test6/SetFilePointer.cpp
index b35247ec24..b35247ec24 100644
--- a/src/pal/tests/palsuite/file_io/SetFilePointer/test6/SetFilePointer.c
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test6/SetFilePointer.cpp
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test7/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFilePointer/test7/CMakeLists.txt
index c5a46a531a..2b5c0bbb45 100644
--- a/src/pal/tests/palsuite/file_io/SetFilePointer/test7/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test7/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- SetFilePointer.c
+ SetFilePointer.cpp
)
add_executable(paltest_setfilepointer_test7
diff --git a/src/pal/tests/palsuite/file_io/SetFilePointer/test7/SetFilePointer.c b/src/pal/tests/palsuite/file_io/SetFilePointer/test7/SetFilePointer.cpp
index 33dfd5e711..33dfd5e711 100644
--- a/src/pal/tests/palsuite/file_io/SetFilePointer/test7/SetFilePointer.c
+++ b/src/pal/tests/palsuite/file_io/SetFilePointer/test7/SetFilePointer.cpp
diff --git a/src/pal/tests/palsuite/file_io/SetFileTime/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileTime/test1/CMakeLists.txt
index 4c4b5d7611..b94bd05d76 100644
--- a/src/pal/tests/palsuite/file_io/SetFileTime/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetFileTime/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- SetFileTime.c
+ SetFileTime.cpp
)
add_executable(paltest_setfiletime_test1
diff --git a/src/pal/tests/palsuite/file_io/SetFileTime/test1/SetFileTime.c b/src/pal/tests/palsuite/file_io/SetFileTime/test1/SetFileTime.cpp
index 4711aeba89..4711aeba89 100644
--- a/src/pal/tests/palsuite/file_io/SetFileTime/test1/SetFileTime.c
+++ b/src/pal/tests/palsuite/file_io/SetFileTime/test1/SetFileTime.cpp
diff --git a/src/pal/tests/palsuite/file_io/SetFileTime/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileTime/test2/CMakeLists.txt
index 35c18c8d8d..5478aa3703 100644
--- a/src/pal/tests/palsuite/file_io/SetFileTime/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetFileTime/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- SetFileTime.c
+ SetFileTime.cpp
)
add_executable(paltest_setfiletime_test2
diff --git a/src/pal/tests/palsuite/file_io/SetFileTime/test2/SetFileTime.c b/src/pal/tests/palsuite/file_io/SetFileTime/test2/SetFileTime.cpp
index e950153bb0..e950153bb0 100644
--- a/src/pal/tests/palsuite/file_io/SetFileTime/test2/SetFileTime.c
+++ b/src/pal/tests/palsuite/file_io/SetFileTime/test2/SetFileTime.cpp
diff --git a/src/pal/tests/palsuite/file_io/SetFileTime/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileTime/test3/CMakeLists.txt
index 0a85d30c51..26e178a328 100644
--- a/src/pal/tests/palsuite/file_io/SetFileTime/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetFileTime/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- SetFileTime.c
+ SetFileTime.cpp
)
add_executable(paltest_setfiletime_test3
diff --git a/src/pal/tests/palsuite/file_io/SetFileTime/test3/SetFileTime.c b/src/pal/tests/palsuite/file_io/SetFileTime/test3/SetFileTime.cpp
index 97f49495d7..97f49495d7 100644
--- a/src/pal/tests/palsuite/file_io/SetFileTime/test3/SetFileTime.c
+++ b/src/pal/tests/palsuite/file_io/SetFileTime/test3/SetFileTime.cpp
diff --git a/src/pal/tests/palsuite/file_io/SetFileTime/test4/CMakeLists.txt b/src/pal/tests/palsuite/file_io/SetFileTime/test4/CMakeLists.txt
index 086e35e535..b85a92bf63 100644
--- a/src/pal/tests/palsuite/file_io/SetFileTime/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/SetFileTime/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- SetFileTime.c
+ SetFileTime.cpp
)
add_executable(paltest_setfiletime_test4
diff --git a/src/pal/tests/palsuite/file_io/SetFileTime/test4/SetFileTime.c b/src/pal/tests/palsuite/file_io/SetFileTime/test4/SetFileTime.cpp
index 3edd2403c4..3edd2403c4 100644
--- a/src/pal/tests/palsuite/file_io/SetFileTime/test4/SetFileTime.c
+++ b/src/pal/tests/palsuite/file_io/SetFileTime/test4/SetFileTime.cpp
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/WriteFile/test1/CMakeLists.txt
index 0c6760a2ce..3d5a735a83 100644
--- a/src/pal/tests/palsuite/file_io/WriteFile/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/WriteFile/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- WriteFile.c
+ WriteFile.cpp
)
add_executable(paltest_writefile_test1
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/test1/WriteFile.c b/src/pal/tests/palsuite/file_io/WriteFile/test1/WriteFile.cpp
index 1ac38ddaf0..1ac38ddaf0 100644
--- a/src/pal/tests/palsuite/file_io/WriteFile/test1/WriteFile.c
+++ b/src/pal/tests/palsuite/file_io/WriteFile/test1/WriteFile.cpp
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/WriteFile/test2/CMakeLists.txt
index a9b51efa3d..3d7d18826a 100644
--- a/src/pal/tests/palsuite/file_io/WriteFile/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/WriteFile/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- WriteFile.c
+ WriteFile.cpp
)
add_executable(paltest_writefile_test2
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/test2/WriteFile.c b/src/pal/tests/palsuite/file_io/WriteFile/test2/WriteFile.cpp
index 24c148afb8..24c148afb8 100644
--- a/src/pal/tests/palsuite/file_io/WriteFile/test2/WriteFile.c
+++ b/src/pal/tests/palsuite/file_io/WriteFile/test2/WriteFile.cpp
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/WriteFile/test3/CMakeLists.txt
index e16e8a48f6..bffcf35482 100644
--- a/src/pal/tests/palsuite/file_io/WriteFile/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/WriteFile/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- WriteFile.c
+ WriteFile.cpp
)
add_executable(paltest_writefile_test3
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/test3/WriteFile.c b/src/pal/tests/palsuite/file_io/WriteFile/test3/WriteFile.cpp
index 751f89ff2c..751f89ff2c 100644
--- a/src/pal/tests/palsuite/file_io/WriteFile/test3/WriteFile.c
+++ b/src/pal/tests/palsuite/file_io/WriteFile/test3/WriteFile.cpp
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/test4/CMakeLists.txt b/src/pal/tests/palsuite/file_io/WriteFile/test4/CMakeLists.txt
index fff886b430..402a61ac2c 100644
--- a/src/pal/tests/palsuite/file_io/WriteFile/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/WriteFile/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- writefile.c
+ writefile.cpp
)
add_executable(paltest_writefile_test4
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/test4/writefile.c b/src/pal/tests/palsuite/file_io/WriteFile/test4/writefile.cpp
index 47a0066ec9..47a0066ec9 100644
--- a/src/pal/tests/palsuite/file_io/WriteFile/test4/writefile.c
+++ b/src/pal/tests/palsuite/file_io/WriteFile/test4/writefile.cpp
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/test5/CMakeLists.txt b/src/pal/tests/palsuite/file_io/WriteFile/test5/CMakeLists.txt
index 978eb7f1e7..f1f5037f98 100644
--- a/src/pal/tests/palsuite/file_io/WriteFile/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/WriteFile/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- writefile.c
+ writefile.cpp
)
add_executable(paltest_writefile_test5
diff --git a/src/pal/tests/palsuite/file_io/WriteFile/test5/writefile.c b/src/pal/tests/palsuite/file_io/WriteFile/test5/writefile.cpp
index 46920b3335..46920b3335 100644
--- a/src/pal/tests/palsuite/file_io/WriteFile/test5/writefile.c
+++ b/src/pal/tests/palsuite/file_io/WriteFile/test5/writefile.cpp
diff --git a/src/pal/tests/palsuite/file_io/errorpathnotfound/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/errorpathnotfound/test1/CMakeLists.txt
index 91b7db1f03..4c4f6416ce 100644
--- a/src/pal/tests/palsuite/file_io/errorpathnotfound/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/errorpathnotfound/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_errorpathnotfound_test1
diff --git a/src/pal/tests/palsuite/file_io/errorpathnotfound/test1/test1.c b/src/pal/tests/palsuite/file_io/errorpathnotfound/test1/test1.cpp
index eaf3db3a30..eaf3db3a30 100644
--- a/src/pal/tests/palsuite/file_io/errorpathnotfound/test1/test1.c
+++ b/src/pal/tests/palsuite/file_io/errorpathnotfound/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/file_io/errorpathnotfound/test2/CMakeLists.txt b/src/pal/tests/palsuite/file_io/errorpathnotfound/test2/CMakeLists.txt
index 7d525c21d5..284933f950 100644
--- a/src/pal/tests/palsuite/file_io/errorpathnotfound/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/errorpathnotfound/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_errorpathnotfound_test2
diff --git a/src/pal/tests/palsuite/file_io/errorpathnotfound/test2/test2.c b/src/pal/tests/palsuite/file_io/errorpathnotfound/test2/test2.cpp
index 5c2ab86b99..5c2ab86b99 100644
--- a/src/pal/tests/palsuite/file_io/errorpathnotfound/test2/test2.c
+++ b/src/pal/tests/palsuite/file_io/errorpathnotfound/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/file_io/errorpathnotfound/test3/CMakeLists.txt b/src/pal/tests/palsuite/file_io/errorpathnotfound/test3/CMakeLists.txt
index c7434f3dba..b418c9dbdb 100644
--- a/src/pal/tests/palsuite/file_io/errorpathnotfound/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/errorpathnotfound/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_errorpathnotfound_test3
diff --git a/src/pal/tests/palsuite/file_io/errorpathnotfound/test3/test3.c b/src/pal/tests/palsuite/file_io/errorpathnotfound/test3/test3.cpp
index 414cbab176..414cbab176 100644
--- a/src/pal/tests/palsuite/file_io/errorpathnotfound/test3/test3.c
+++ b/src/pal/tests/palsuite/file_io/errorpathnotfound/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/file_io/errorpathnotfound/test4/CMakeLists.txt b/src/pal/tests/palsuite/file_io/errorpathnotfound/test4/CMakeLists.txt
index f8062fd127..e0322dd8e4 100644
--- a/src/pal/tests/palsuite/file_io/errorpathnotfound/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/errorpathnotfound/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_errorpathnotfound_test4
diff --git a/src/pal/tests/palsuite/file_io/errorpathnotfound/test4/test4.c b/src/pal/tests/palsuite/file_io/errorpathnotfound/test4/test4.cpp
index e1b68995b0..e1b68995b0 100644
--- a/src/pal/tests/palsuite/file_io/errorpathnotfound/test4/test4.c
+++ b/src/pal/tests/palsuite/file_io/errorpathnotfound/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/file_io/gettemppatha/test1/CMakeLists.txt b/src/pal/tests/palsuite/file_io/gettemppatha/test1/CMakeLists.txt
index 2aff599e74..9869c9c70f 100644
--- a/src/pal/tests/palsuite/file_io/gettemppatha/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/file_io/gettemppatha/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- gettemppatha.c
+ gettemppatha.cpp
)
add_executable(paltest_gettemppatha_test1
diff --git a/src/pal/tests/palsuite/file_io/gettemppatha/test1/gettemppatha.c b/src/pal/tests/palsuite/file_io/gettemppatha/test1/gettemppatha.cpp
index b0da528af8..b0da528af8 100644
--- a/src/pal/tests/palsuite/file_io/gettemppatha/test1/gettemppatha.c
+++ b/src/pal/tests/palsuite/file_io/gettemppatha/test1/gettemppatha.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/CMakeLists.txt
index 3fc399fe59..a573dae8cd 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CMakeLists.txt
@@ -17,7 +17,7 @@ add_subdirectory(LockFile)
add_subdirectory(MapViewOfFile)
add_subdirectory(OpenFileMappingA)
add_subdirectory(OpenFileMappingW)
-add_subdirectory(ReadProcessMemory)
+add_subdirectory(ProbeMemory)
add_subdirectory(RtlMoveMemory)
add_subdirectory(UnlockFile)
add_subdirectory(UnmapViewOfFile)
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test1/CMakeLists.txt
index 36084bf446..c38015ea21 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CreateFileMapping.c
+ CreateFileMapping.cpp
)
add_executable(paltest_createfilemappinga_test1
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test1/CreateFileMapping.c b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test1/CreateFileMapping.cpp
index 91640bfd04..91640bfd04 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test1/CreateFileMapping.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test1/CreateFileMapping.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test3/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test3/CMakeLists.txt
index 374f8f0946..fc152c8161 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CreateFileMapping.c
+ CreateFileMapping.cpp
)
add_executable(paltest_createfilemappinga_test3
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test3/CreateFileMapping.c b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test3/CreateFileMapping.cpp
index 2a849d86b8..2a849d86b8 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test3/CreateFileMapping.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test3/CreateFileMapping.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test4/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test4/CMakeLists.txt
index 665b10a3f0..bbb4deaa8b 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CreateFileMapping.c
+ CreateFileMapping.cpp
)
add_executable(paltest_createfilemappinga_test4
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test4/CreateFileMapping.c b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test4/CreateFileMapping.cpp
index 64caa88ca0..64caa88ca0 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test4/CreateFileMapping.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test4/CreateFileMapping.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test5/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test5/CMakeLists.txt
index 6f7f3c3635..b80aa21a42 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CreateFileMapping.c
+ CreateFileMapping.cpp
)
add_executable(paltest_createfilemappinga_test5
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test5/CreateFileMapping.c b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test5/CreateFileMapping.cpp
index c7f9918b08..c7f9918b08 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test5/CreateFileMapping.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test5/CreateFileMapping.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test6/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test6/CMakeLists.txt
index 2f5d98b5e6..414127aa35 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CreateFileMapping.c
+ CreateFileMapping.cpp
)
add_executable(paltest_createfilemappinga_test6
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test6/CreateFileMapping.c b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test6/CreateFileMapping.cpp
index 6445295de8..6445295de8 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test6/CreateFileMapping.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test6/CreateFileMapping.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test7/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test7/CMakeLists.txt
index 4fd24a63a1..e40a5ad486 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test7/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test7/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- createfilemapping.c
+ createfilemapping.cpp
)
add_executable(paltest_createfilemappinga_test7
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test7/createfilemapping.c b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test7/createfilemapping.cpp
index 7cef9ddcdc..7cef9ddcdc 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test7/createfilemapping.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test7/createfilemapping.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test8/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test8/CMakeLists.txt
index ae3ee8ddf6..d2e2007545 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test8/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test8/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- createfilemapping.c
+ createfilemapping.cpp
)
add_executable(paltest_createfilemappinga_test8
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test8/createfilemapping.c b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test8/createfilemapping.cpp
index 02b2fb5e61..02b2fb5e61 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test8/createfilemapping.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test8/createfilemapping.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test9/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test9/CMakeLists.txt
index a377632bed..3017dc4aa4 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test9/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test9/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- createfilemapping.c
+ createfilemapping.cpp
)
add_executable(paltest_createfilemappinga_test9
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test9/createfilemapping.c b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test9/createfilemapping.cpp
index 9224c22b4b..9224c22b4b 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test9/createfilemapping.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingA/test9/createfilemapping.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/CreateFileMapping_neg1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/CreateFileMapping_neg1/CMakeLists.txt
index a4ad343ea0..2d24eca8c8 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/CreateFileMapping_neg1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/CreateFileMapping_neg1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CreateFileMapping_neg.c
+ CreateFileMapping_neg.cpp
)
add_executable(paltest_createfilemappingw_createfilemapping_neg1
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/CreateFileMapping_neg1/CreateFileMapping_neg.c b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/CreateFileMapping_neg1/CreateFileMapping_neg.cpp
index 8cf79b3c57..8cf79b3c57 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/CreateFileMapping_neg1/CreateFileMapping_neg.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/CreateFileMapping_neg1/CreateFileMapping_neg.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test1/CMakeLists.txt
index 0c569ec9b6..a2fbfa39af 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CreateFileMappingW.c
+ CreateFileMappingW.cpp
)
add_executable(paltest_createfilemappingw_test1
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test1/CreateFileMappingW.c b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test1/CreateFileMappingW.cpp
index 4263a3ad29..4263a3ad29 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test1/CreateFileMappingW.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test1/CreateFileMappingW.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test2/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test2/CMakeLists.txt
index 992645f48c..8552cc910f 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CreateFileMappingW.c
+ CreateFileMappingW.cpp
)
add_executable(paltest_createfilemappingw_test2
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test2/CreateFileMappingW.c b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test2/CreateFileMappingW.c
deleted file mode 100644
index 11ff967dfd..0000000000
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test2/CreateFileMappingW.c
+++ /dev/null
@@ -1,124 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: createfilemappingw.c
-**
-** Purpose: Positive test the CreateFileMapping API.
-** Call CreateFileMapping to create a unnamed
-** file-mapping object with PAGE_READONLY
-** protection and SEC_IMAGE attribute in UNICODE
-**
-**
-**============================================================*/
-#define UNICODE
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
-
- HANDLE FileHandle;
- HANDLE FileMappingHandle;
- int err;
- WCHAR *wpFileName = NULL;
- char executableFileName[256]="";
-
-
- //Initialize the PAL environment
- err = PAL_Initialize(argc, argv);
- if(0 != err)
- {
- ExitProcess(FAIL);
- }
-
-#if WIN32
- sprintf(executableFileName,"%s","executable.exe");
-#else
- sprintf(executableFileName,"%s","executable");
-#endif
-
- //conver string to a unicode one
- wpFileName = convert(executableFileName);
-
-
- //create a file and return the file handle
- FileHandle = CreateFile(wpFileName,
- GENERIC_READ,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_ARCHIVE,
- NULL);
-
- //free this memory
- free(wpFileName);
-
- if(INVALID_HANDLE_VALUE == FileHandle)
- {
- Fail("Failed to call CreateFile to create a file\n");
- }
-
- //create a unnamed file-mapping object with file handle FileHandle
- //and with PAGE_READONLY protection
- FileMappingHandle = CreateFileMapping(
- FileHandle, //File Handle
- NULL, //not inherited
- PAGE_READONLY|SEC_IMAGE, //access protection and section attribute
- 0, //high-order of object size
- 0, //low-orger of object size
- NULL); //unnamed object
-
-
- if(NULL == FileMappingHandle)
- {
- Trace("\nFailed to call CreateFileMapping to create a mapping object!\n");
- err = CloseHandle(FileHandle);
- if(0 == err)
- {
- Fail("\nFailed to call CloseHandle API\n");
- }
- Fail("");
- }
- if(GetLastError() == ERROR_ALREADY_EXISTS)
- {
- Trace("\nFile mapping object already exists!\n");
- err = CloseHandle(FileHandle);
- if(0 == err)
- {
- Trace("\nFailed to call CloseHandle API to close a file handle\n");
- err = CloseHandle(FileMappingHandle);
- if(0 == err)
- {
- Fail("\nFailed to call CloseHandle API to close a mapping object handle\n");
- }
- Fail("");
- }
- err = CloseHandle(FileMappingHandle);
- if(0 == err)
- {
- Fail("\nFailed to call CloseHandle API to close a mapping object handle\n");
- }
- Fail("");
- }
- err = CloseHandle(FileMappingHandle);
- if(0 == err)
- {
- Trace("\nFailed to call CloseHandle API to close a mapping object handle\n");
- err = CloseHandle(FileHandle);
- if(0 == err)
- {
- Fail("\nFailed to call CloseHandle API to close a file handle\n");
- }
- Fail("");
- }
- err = CloseHandle(FileHandle);
- if(0 == err)
- {
- Fail("\nFailed to call CloseHandle API to close a file handle\n");
- }
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test2/CreateFileMappingW.cpp b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test2/CreateFileMappingW.cpp
new file mode 100644
index 0000000000..5cc6d77709
--- /dev/null
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test2/CreateFileMappingW.cpp
@@ -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.
+
+/*=============================================================
+**
+** Source: createfilemappingw.c
+**
+** Purpose: Positive test the CreateFileMapping API.
+** Call CreateFileMapping to create a unnamed
+** file-mapping object with PAGE_READONLY
+** protection and SEC_IMAGE attribute in UNICODE
+**
+**
+**============================================================*/
+#define UNICODE
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ HANDLE FileHandle;
+ HANDLE FileMappingHandle;
+ int err;
+ WCHAR *wpFileName = NULL;
+ char executableFileName[256]="";
+
+
+ //Initialize the PAL environment
+ err = PAL_Initialize(argc, argv);
+ if(0 != err)
+ {
+ ExitProcess(FAIL);
+ }
+
+#if WIN32
+ sprintf_s(executableFileName, _countof(executableFileName),"%s","executable.exe");
+#else
+ sprintf_s(executableFileName, _countof(executableFileName),"%s","executable");
+#endif
+
+ //conver string to a unicode one
+ wpFileName = convert(executableFileName);
+
+
+ //create a file and return the file handle
+ FileHandle = CreateFile(wpFileName,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_ARCHIVE,
+ NULL);
+
+ //free this memory
+ free(wpFileName);
+
+ if(INVALID_HANDLE_VALUE == FileHandle)
+ {
+ Fail("Failed to call CreateFile to create a file\n");
+ }
+
+ //create a unnamed file-mapping object with file handle FileHandle
+ //and with PAGE_READONLY protection
+ FileMappingHandle = CreateFileMapping(
+ FileHandle, //File Handle
+ NULL, //not inherited
+ PAGE_READONLY|SEC_IMAGE, //access protection and section attribute
+ 0, //high-order of object size
+ 0, //low-orger of object size
+ NULL); //unnamed object
+
+
+ if(NULL == FileMappingHandle)
+ {
+ Trace("\nFailed to call CreateFileMapping to create a mapping object!\n");
+ err = CloseHandle(FileHandle);
+ if(0 == err)
+ {
+ Fail("\nFailed to call CloseHandle API\n");
+ }
+ Fail("");
+ }
+ if(GetLastError() == ERROR_ALREADY_EXISTS)
+ {
+ Trace("\nFile mapping object already exists!\n");
+ err = CloseHandle(FileHandle);
+ if(0 == err)
+ {
+ Trace("\nFailed to call CloseHandle API to close a file handle\n");
+ err = CloseHandle(FileMappingHandle);
+ if(0 == err)
+ {
+ Fail("\nFailed to call CloseHandle API to close a mapping object handle\n");
+ }
+ Fail("");
+ }
+ err = CloseHandle(FileMappingHandle);
+ if(0 == err)
+ {
+ Fail("\nFailed to call CloseHandle API to close a mapping object handle\n");
+ }
+ Fail("");
+ }
+ err = CloseHandle(FileMappingHandle);
+ if(0 == err)
+ {
+ Trace("\nFailed to call CloseHandle API to close a mapping object handle\n");
+ err = CloseHandle(FileHandle);
+ if(0 == err)
+ {
+ Fail("\nFailed to call CloseHandle API to close a file handle\n");
+ }
+ Fail("");
+ }
+ err = CloseHandle(FileHandle);
+ if(0 == err)
+ {
+ Fail("\nFailed to call CloseHandle API to close a file handle\n");
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test3/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test3/CMakeLists.txt
index 87832ffd9b..97fd712350 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CreateFileMappingW.c
+ CreateFileMappingW.cpp
)
add_executable(paltest_createfilemappingw_test3
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test3/CreateFileMappingW.c b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test3/CreateFileMappingW.cpp
index 1cbeff94a7..1cbeff94a7 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test3/CreateFileMappingW.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test3/CreateFileMappingW.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test4/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test4/CMakeLists.txt
index f8a5c9041f..81f248e335 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CreateFileMappingW.c
+ CreateFileMappingW.cpp
)
add_executable(paltest_createfilemappingw_test4
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test4/CreateFileMappingW.c b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test4/CreateFileMappingW.cpp
index 265a317b2f..265a317b2f 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test4/CreateFileMappingW.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test4/CreateFileMappingW.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test5/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test5/CMakeLists.txt
index 8391fbd721..df25e29a4f 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CreateFileMappingW.c
+ CreateFileMappingW.cpp
)
add_executable(paltest_createfilemappingw_test5
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test5/CreateFileMappingW.c b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test5/CreateFileMappingW.cpp
index 21bf7c6d76..21bf7c6d76 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test5/CreateFileMappingW.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test5/CreateFileMappingW.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test6/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test6/CMakeLists.txt
index abb62ad950..852c508020 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CreateFileMappingW.c
+ CreateFileMappingW.cpp
)
add_executable(paltest_createfilemappingw_test6
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test6/CreateFileMappingW.c b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test6/CreateFileMappingW.cpp
index acf3ac6dff..acf3ac6dff 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test6/CreateFileMappingW.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test6/CreateFileMappingW.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test7/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test7/CMakeLists.txt
index b40cfeae96..68be449aec 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test7/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test7/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- createfilemapping.c
+ createfilemapping.cpp
)
add_executable(paltest_createfilemappingw_test7
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test7/createfilemapping.c b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test7/createfilemapping.cpp
index e49b9f688d..e49b9f688d 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test7/createfilemapping.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test7/createfilemapping.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test8/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test8/CMakeLists.txt
index 96658c163a..406331072c 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test8/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test8/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- createfilemapping.c
+ createfilemapping.cpp
)
add_executable(paltest_createfilemappingw_test8
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test8/createfilemapping.c b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test8/createfilemapping.cpp
index 1ff137d8d3..1ff137d8d3 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test8/createfilemapping.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test8/createfilemapping.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test9/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test9/CMakeLists.txt
index 5a55e27b33..6d15fea1e6 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test9/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test9/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- createfilemapping.c
+ createfilemapping.cpp
)
add_executable(paltest_createfilemappingw_test9
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test9/createfilemapping.c b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test9/createfilemapping.cpp
index 16ae74c126..16ae74c126 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test9/createfilemapping.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/CreateFileMappingW/test9/createfilemapping.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test1/CMakeLists.txt
index 3807621e3f..beaee835c8 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test1/CMakeLists.txt
@@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- dlltest.c
- FreeLibrary.c
+ dlltest.cpp
+ FreeLibrary.cpp
)
add_executable(paltest_freelibrary_test1
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test1/FreeLibrary.c b/src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test1/FreeLibrary.cpp
index a06a231586..a06a231586 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test1/FreeLibrary.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test1/FreeLibrary.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test1/dlltest.c b/src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test1/dlltest.cpp
index 44f1b5a903..44f1b5a903 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test1/dlltest.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test1/dlltest.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test2/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test2/CMakeLists.txt
index 00b1eca8e3..0a5e700ba4 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_freelibrary_test2
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test2/test2.c b/src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test2/test2.cpp
index b43f74d6bc..b43f74d6bc 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test2/test2.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/FreeLibraryAndExitThread/test1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/FreeLibraryAndExitThread/test1/CMakeLists.txt
index cec083583a..03bfe06eb3 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/FreeLibraryAndExitThread/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/FreeLibraryAndExitThread/test1/CMakeLists.txt
@@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- dlltest.c
- test1.c
+ dlltest.cpp
+ test1.cpp
)
add_executable(paltest_freelibraryandexitthread_test1
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/FreeLibraryAndExitThread/test1/dlltest.c b/src/pal/tests/palsuite/filemapping_memmgt/FreeLibraryAndExitThread/test1/dlltest.cpp
index 954c624d19..954c624d19 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/FreeLibraryAndExitThread/test1/dlltest.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/FreeLibraryAndExitThread/test1/dlltest.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/FreeLibraryAndExitThread/test1/test1.c b/src/pal/tests/palsuite/filemapping_memmgt/FreeLibraryAndExitThread/test1/test1.c
deleted file mode 100644
index 6aacfc83b4..0000000000
--- a/src/pal/tests/palsuite/filemapping_memmgt/FreeLibraryAndExitThread/test1/test1.c
+++ /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.
-
-/*=====================================================================
-**
-** Source: test1.c (FreeLibraryAndExitThread)
-**
-** Purpose: Tests the PAL implementation of the FreeLibraryAndExitThread
-** function. FreeLibraryAndExitThread when run will exit the
-** process that it is called within, therefore we create a
-** thread to run the API. Then test for the existance of the
-** thread and access to the library.
-**
-**
-**===================================================================*/
-
-#include <palsuite.h>
-
-/*Define platform specific information*/
-
-/* SHLEXT is defined only for Unix variants */
-#if defined(SHLEXT)
-#define LibraryName "dlltest"SHLEXT
-#else
-#define LibraryName "dlltest"
-#endif
-
-#define TIMEOUT 60000
-
-BOOL PALAPI StartThreadTest();
-DWORD PALAPI CreateTestThread(LPVOID);
-BOOL PALAPI TestDll(HMODULE, int);
-
-int __cdecl main(int argc, char* argv[])
-{
- /*Initialize the PAL*/
- if ((PAL_Initialize(argc, argv)) != 0)
- {
- return (FAIL);
- }
-
- if (!StartThreadTest())
- {
- Fail("ERROR: FreeLibraryAndExitThread test failed.\n");
- }
-
- /*Terminate the PAL*/
- PAL_Terminate();
- return PASS;
-
-}
-
-
-BOOL PALAPI StartThreadTest()
-{
- HMODULE hLib;
- HANDLE hThread;
- DWORD dwThreadId;
- LPTHREAD_START_ROUTINE lpStartAddress = &CreateTestThread;
- LPVOID lpParameter = lpStartAddress;
- DWORD rc = -1;
- /*Load library (DLL).*/
- hLib = LoadLibrary(LibraryName);
- if(hLib == NULL)
- {
- Trace("ERROR: Unable to load library %s\n", LibraryName);
-
- return (FALSE);
- }
-
- /*Start the test thread*/
- hThread = CreateThread(NULL,
- (DWORD)0,
- lpParameter,
- hLib,
- (DWORD)NULL,
- &dwThreadId);
- if(hThread == NULL)
- {
- Trace("ERROR:%u: Unable to create thread.\n",
- GetLastError());
-
- FreeLibrary(hLib);
- return (FALSE);
- }
-
- /*Wait on thread.*/
- rc = WaitForSingleObject(hThread, TIMEOUT);
- if( rc != WAIT_OBJECT_0 )
- {
- Trace("ERROR:%u: hThread=0x%4.4lx not exited by "
- "FreeLibraryAndExitThread, RC[%d]\n",
- GetLastError(),
- hThread, rc);
-
-// There is a possibility that the other thread might
-// still be using the library VSW:337893
-// FreeLibrary(hLib);
- CloseHandle(hThread);
- return (FALSE);
- }
-
- /*Test access to DLL.*/
- if(!TestDll(hLib, 0))
- {
- Trace("ERROR: TestDll function returned FALSE "
- "expected TRUE\n.");
-
- CloseHandle(hThread);
- return (FALSE);
- }
-
- FreeLibrary(hLib);
- /*Clean-up thread.*/
- CloseHandle(hThread);
-
- return (TRUE);
-}
-
-BOOL PALAPI TestDll(HMODULE hLib, int testResult)
-{
- int RetVal;
- char FunctName[] = "DllTest";
- FARPROC DllAddr;
-
- /* Attempt to grab the proc address of the dll function.
- * This one should succeed.*/
- if(testResult == 1)
- {
- DllAddr = GetProcAddress(hLib, FunctName);
- if(DllAddr == NULL)
- {
- Trace("ERROR: Unable to load function \"%s\" library \"%s\"\n",
- FunctName,
- LibraryName);
- return (FALSE);
- }
- /* Run the function in the DLL,
- * to ensure that the DLL was loaded properly.*/
- RetVal = DllAddr();
- if (RetVal != 1)
- {
- Trace("ERROR: Unable to receive correct information from DLL! "
- ":expected \"1\", returned \"%d\"\n",
- RetVal);
- return (FALSE);
- }
- }
-
- /* Attempt to grab the proc address of the dll function.
- * This one should fail.*/
- if(testResult == 0)
- {
- DllAddr = GetProcAddress(hLib, FunctName);
- if(DllAddr != NULL)
- {
- Trace("ERROR: Able to load function \"%s\" from free'd"
- " library \"%s\"\n",
- FunctName,
- LibraryName);
- return (FALSE);
- }
- }
- return (TRUE);
-}
-
-DWORD PALAPI CreateTestThread(LPVOID lpParam)
-{
- /* Test access to DLL.*/
- TestDll(lpParam, 1);
-
- /*Free library and exit thread.*/
- FreeLibraryAndExitThread(lpParam, (DWORD)0);
-
- /* NOT REACHED */
-
- /*Infinite loop, we should not get here.*/
- while(1);
-
- return (DWORD)0;
-}
-
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/FreeLibraryAndExitThread/test1/test1.cpp b/src/pal/tests/palsuite/filemapping_memmgt/FreeLibraryAndExitThread/test1/test1.cpp
new file mode 100644
index 0000000000..58f6643722
--- /dev/null
+++ b/src/pal/tests/palsuite/filemapping_memmgt/FreeLibraryAndExitThread/test1/test1.cpp
@@ -0,0 +1,183 @@
+// Licensed to the .NET Foundation under one or more 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: test1.c (FreeLibraryAndExitThread)
+**
+** Purpose: Tests the PAL implementation of the FreeLibraryAndExitThread
+** function. FreeLibraryAndExitThread when run will exit the
+** process that it is called within, therefore we create a
+** thread to run the API. Then test for the existance of the
+** thread and access to the library.
+**
+**
+**===================================================================*/
+
+#include <palsuite.h>
+
+/*Define platform specific information*/
+
+/* SHLEXT is defined only for Unix variants */
+#if defined(SHLEXT)
+#define LibraryName "dlltest"SHLEXT
+#else
+#define LibraryName "dlltest"
+#endif
+
+#define TIMEOUT 60000
+
+BOOL PALAPI StartThreadTest();
+DWORD PALAPI CreateTestThread(LPVOID);
+BOOL PALAPI TestDll(HMODULE, int);
+
+int __cdecl main(int argc, char* argv[])
+{
+ /*Initialize the PAL*/
+ if ((PAL_Initialize(argc, argv)) != 0)
+ {
+ return (FAIL);
+ }
+
+ if (!StartThreadTest())
+ {
+ Fail("ERROR: FreeLibraryAndExitThread test failed.\n");
+ }
+
+ /*Terminate the PAL*/
+ PAL_Terminate();
+ return PASS;
+
+}
+
+
+BOOL PALAPI StartThreadTest()
+{
+ HMODULE hLib;
+ HANDLE hThread;
+ DWORD dwThreadId;
+ LPTHREAD_START_ROUTINE lpStartAddress = &CreateTestThread;
+ LPVOID lpParameter = (LPVOID)lpStartAddress;
+ DWORD rc = -1;
+ /*Load library (DLL).*/
+ hLib = LoadLibrary(LibraryName);
+ if(hLib == NULL)
+ {
+ Trace("ERROR: Unable to load library %s\n", LibraryName);
+
+ return (FALSE);
+ }
+
+ /*Start the test thread*/
+ hThread = CreateThread(NULL,
+ (DWORD)0,
+ lpStartAddress,
+ hLib,
+ (DWORD)NULL,
+ &dwThreadId);
+ if(hThread == NULL)
+ {
+ Trace("ERROR:%u: Unable to create thread.\n",
+ GetLastError());
+
+ FreeLibrary(hLib);
+ return (FALSE);
+ }
+
+ /*Wait on thread.*/
+ rc = WaitForSingleObject(hThread, TIMEOUT);
+ if( rc != WAIT_OBJECT_0 )
+ {
+ Trace("ERROR:%u: hThread=0x%4.4lx not exited by "
+ "FreeLibraryAndExitThread, RC[%d]\n",
+ GetLastError(),
+ hThread, rc);
+
+// There is a possibility that the other thread might
+// still be using the library VSW:337893
+// FreeLibrary(hLib);
+ CloseHandle(hThread);
+ return (FALSE);
+ }
+
+ /*Test access to DLL.*/
+ if(!TestDll(hLib, 0))
+ {
+ Trace("ERROR: TestDll function returned FALSE "
+ "expected TRUE\n.");
+
+ CloseHandle(hThread);
+ return (FALSE);
+ }
+
+ FreeLibrary(hLib);
+ /*Clean-up thread.*/
+ CloseHandle(hThread);
+
+ return (TRUE);
+}
+
+BOOL PALAPI TestDll(HMODULE hLib, int testResult)
+{
+ int RetVal;
+ char FunctName[] = "DllTest";
+ FARPROC DllAddr;
+
+ /* Attempt to grab the proc address of the dll function.
+ * This one should succeed.*/
+ if(testResult == 1)
+ {
+ DllAddr = GetProcAddress(hLib, FunctName);
+ if(DllAddr == NULL)
+ {
+ Trace("ERROR: Unable to load function \"%s\" library \"%s\"\n",
+ FunctName,
+ LibraryName);
+ return (FALSE);
+ }
+ /* Run the function in the DLL,
+ * to ensure that the DLL was loaded properly.*/
+ RetVal = DllAddr();
+ if (RetVal != 1)
+ {
+ Trace("ERROR: Unable to receive correct information from DLL! "
+ ":expected \"1\", returned \"%d\"\n",
+ RetVal);
+ return (FALSE);
+ }
+ }
+
+ /* Attempt to grab the proc address of the dll function.
+ * This one should fail.*/
+ if(testResult == 0)
+ {
+ DllAddr = GetProcAddress(hLib, FunctName);
+ if(DllAddr != NULL)
+ {
+ Trace("ERROR: Able to load function \"%s\" from free'd"
+ " library \"%s\"\n",
+ FunctName,
+ LibraryName);
+ return (FALSE);
+ }
+ }
+ return (TRUE);
+}
+
+DWORD PALAPI CreateTestThread(LPVOID lpParam)
+{
+ /* Test access to DLL.*/
+ TestDll(lpParam, 1);
+
+ /*Free library and exit thread.*/
+ FreeLibraryAndExitThread(lpParam, (DWORD)0);
+
+ /* NOT REACHED */
+
+ /*Infinite loop, we should not get here.*/
+ while(1);
+
+ return (DWORD)0;
+}
+
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameA/test1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameA/test1/CMakeLists.txt
index a1128c62b8..9b7a610f0c 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetModuleFileNameA.c
+ GetModuleFileNameA.cpp
)
add_executable(paltest_getmodulefilenamea_test1
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameA/test1/GetModuleFileNameA.c b/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameA/test1/GetModuleFileNameA.cpp
index d05f0ac6a9..d05f0ac6a9 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameA/test1/GetModuleFileNameA.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameA/test1/GetModuleFileNameA.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameA/test2/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameA/test2/CMakeLists.txt
index c35e9acc5e..1909be4b42 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameA/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameA/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetModuleFileNameA.c
+ GetModuleFileNameA.cpp
)
add_executable(paltest_getmodulefilenamea_test2
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameA/test2/GetModuleFileNameA.c b/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameA/test2/GetModuleFileNameA.cpp
index e8aed6d30e..e8aed6d30e 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameA/test2/GetModuleFileNameA.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameA/test2/GetModuleFileNameA.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameW/test1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameW/test1/CMakeLists.txt
index c702d07908..f3d92b15c9 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetModuleFileNameW.c
+ GetModuleFileNameW.cpp
)
add_executable(paltest_getmodulefilenamew_test1
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameW/test1/GetModuleFileNameW.c b/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameW/test1/GetModuleFileNameW.c
deleted file mode 100644
index 4c1c3b00ab..0000000000
--- a/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameW/test1/GetModuleFileNameW.c
+++ /dev/null
@@ -1,112 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: getmodulefilenamew.c
-**
-** Purpose: Test the GetModuleFileNameW to retrieve the specified module
-** full path and file name in UNICODE.
-**
-**
-**============================================================*/
-#define UNICODE
-#include <palsuite.h>
-
-#define MODULENAMEBUFFERSIZE 1024
-
-/* SHLEXT is defined only for Unix variants */
-
-#if defined(SHLEXT)
-#define ModuleName "librotor_pal"SHLEXT
-#define Delimiter "/"
-#else
-#define ModuleName "rotor_pal.dll"
-#define Delimiter "\\"
-#endif
-
-int __cdecl main(int argc, char *argv[])
-{
- HMODULE ModuleHandle;
- int err;
- WCHAR *lpModuleName;
- DWORD ModuleNameLength;
- WCHAR *ModuleFileNameBuf;
- char* TempBuf = NULL;
- char* LastBuf = NULL;
- char NewModuleFileNameBuf[MODULENAMEBUFFERSIZE+200] = "";
-
-
- //Initialize the PAL environment
- err = PAL_Initialize(argc, argv);
- if(0 != err)
- {
- ExitProcess(FAIL);
- }
-
- ModuleFileNameBuf = malloc(MODULENAMEBUFFERSIZE*sizeof(WCHAR));
-
- //convert a normal string to a wide one
- lpModuleName = convert(ModuleName);
-
- //load a module
- ModuleHandle = LoadLibrary(lpModuleName);
-
- //free the memory
- free(lpModuleName);
-
- if(!ModuleHandle)
- {
- Fail("Failed to call LoadLibrary API!\n");
- }
-
-
- //retrieve the specified module full path and file name
- ModuleNameLength = GetModuleFileName(
- ModuleHandle,//specified module handle
- ModuleFileNameBuf,//buffer for module file name
- MODULENAMEBUFFERSIZE);
-
-
-
- //convert a wide full path name to a normal one
- strcpy(NewModuleFileNameBuf,convertC(ModuleFileNameBuf));
-
- //strip out all full path
- TempBuf = strtok(NewModuleFileNameBuf,Delimiter);
- LastBuf = TempBuf;
- while(NULL != TempBuf)
- {
- LastBuf = TempBuf;
- TempBuf = strtok(NULL,Delimiter);
- }
-
-
- //free the memory
- free(ModuleFileNameBuf);
-
- if(0 == ModuleNameLength || strcmp(ModuleName,LastBuf))
- {
- Trace("\nFailed to all GetModuleFileName API!\n");
- err = FreeLibrary(ModuleHandle);
- if(0 == err)
- {
- Fail("\nFailed to all FreeLibrary API!\n");
- }
- Fail("");
- }
-
-
-
- //decrement the reference count of the loaded dll
- err = FreeLibrary(ModuleHandle);
- if(0 == err)
- {
- Fail("\nFailed to all FreeLibrary API!\n");
- }
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameW/test1/GetModuleFileNameW.cpp b/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameW/test1/GetModuleFileNameW.cpp
new file mode 100644
index 0000000000..c122312d89
--- /dev/null
+++ b/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameW/test1/GetModuleFileNameW.cpp
@@ -0,0 +1,112 @@
+// Licensed to the .NET Foundation under one or more 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: getmodulefilenamew.c
+**
+** Purpose: Test the GetModuleFileNameW to retrieve the specified module
+** full path and file name in UNICODE.
+**
+**
+**============================================================*/
+#define UNICODE
+#include <palsuite.h>
+
+#define MODULENAMEBUFFERSIZE 1024
+
+/* SHLEXT is defined only for Unix variants */
+
+#if defined(SHLEXT)
+#define ModuleName "librotor_pal"SHLEXT
+#define Delimiter "/"
+#else
+#define ModuleName "rotor_pal.dll"
+#define Delimiter "\\"
+#endif
+
+int __cdecl main(int argc, char *argv[])
+{
+ HMODULE ModuleHandle;
+ int err;
+ WCHAR *lpModuleName;
+ DWORD ModuleNameLength;
+ WCHAR *ModuleFileNameBuf;
+ char* TempBuf = NULL;
+ char* LastBuf = NULL;
+ char NewModuleFileNameBuf[MODULENAMEBUFFERSIZE+200] = "";
+
+
+ //Initialize the PAL environment
+ err = PAL_Initialize(argc, argv);
+ if(0 != err)
+ {
+ ExitProcess(FAIL);
+ }
+
+ ModuleFileNameBuf = (WCHAR*)malloc(MODULENAMEBUFFERSIZE*sizeof(WCHAR));
+
+ //convert a normal string to a wide one
+ lpModuleName = convert(ModuleName);
+
+ //load a module
+ ModuleHandle = LoadLibrary(lpModuleName);
+
+ //free the memory
+ free(lpModuleName);
+
+ if(!ModuleHandle)
+ {
+ Fail("Failed to call LoadLibrary API!\n");
+ }
+
+
+ //retrieve the specified module full path and file name
+ ModuleNameLength = GetModuleFileName(
+ ModuleHandle,//specified module handle
+ ModuleFileNameBuf,//buffer for module file name
+ MODULENAMEBUFFERSIZE);
+
+
+
+ //convert a wide full path name to a normal one
+ strcpy(NewModuleFileNameBuf,convertC(ModuleFileNameBuf));
+
+ //strip out all full path
+ TempBuf = strtok(NewModuleFileNameBuf,Delimiter);
+ LastBuf = TempBuf;
+ while(NULL != TempBuf)
+ {
+ LastBuf = TempBuf;
+ TempBuf = strtok(NULL,Delimiter);
+ }
+
+
+ //free the memory
+ free(ModuleFileNameBuf);
+
+ if(0 == ModuleNameLength || strcmp(ModuleName,LastBuf))
+ {
+ Trace("\nFailed to all GetModuleFileName API!\n");
+ err = FreeLibrary(ModuleHandle);
+ if(0 == err)
+ {
+ Fail("\nFailed to all FreeLibrary API!\n");
+ }
+ Fail("");
+ }
+
+
+
+ //decrement the reference count of the loaded dll
+ err = FreeLibrary(ModuleHandle);
+ if(0 == err)
+ {
+ Fail("\nFailed to all FreeLibrary API!\n");
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameW/test2/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameW/test2/CMakeLists.txt
index 857feb330d..7b23e92772 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameW/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameW/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetModuleFileNameW.c
+ GetModuleFileNameW.cpp
)
add_executable(paltest_getmodulefilenamew_test2
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameW/test2/GetModuleFileNameW.c b/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameW/test2/GetModuleFileNameW.c
deleted file mode 100644
index 6009a9d298..0000000000
--- a/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameW/test2/GetModuleFileNameW.c
+++ /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.
-
-/*=============================================================
-**
-** Source: getmodulefilenamew.c
-**
-** Purpose: Positive test the GetModuleFileName API.
-** Call GetModuleFileName to retrieve current process
-** full path and file name by passing a NULL module handle
-** in UNICODE
-**
-**
-**============================================================*/
-#define UNICODE
-#include <palsuite.h>
-
-#define MODULENAMEBUFFERSIZE 1024
-
-
-int __cdecl main(int argc, char *argv[])
-{
-
- DWORD ModuleNameLength;
- WCHAR *ModuleFileNameBuf;
- int err;
-
-
- //Initialize the PAL environment
- err = PAL_Initialize(argc, argv);
- if(0 != err)
- {
- ExitProcess(FAIL);
- }
-
- ModuleFileNameBuf = malloc(MODULENAMEBUFFERSIZE*sizeof(WCHAR));
-
- //retrieve the current process full path and file name
- //by passing a NULL module handle
- ModuleNameLength = GetModuleFileName(
- NULL, //a NULL handle
- ModuleFileNameBuf,//buffer for module file name
- MODULENAMEBUFFERSIZE);
-
- //free the memory
- free(ModuleFileNameBuf);
-
- if(0 == ModuleNameLength)
- {
- Fail("\nFailed to all GetModuleFileName API!\n");
- }
-
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameW/test2/GetModuleFileNameW.cpp b/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameW/test2/GetModuleFileNameW.cpp
new file mode 100644
index 0000000000..f23d97c138
--- /dev/null
+++ b/src/pal/tests/palsuite/filemapping_memmgt/GetModuleFileNameW/test2/GetModuleFileNameW.cpp
@@ -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.
+
+/*=============================================================
+**
+** Source: getmodulefilenamew.c
+**
+** Purpose: Positive test the GetModuleFileName API.
+** Call GetModuleFileName to retrieve current process
+** full path and file name by passing a NULL module handle
+** in UNICODE
+**
+**
+**============================================================*/
+#define UNICODE
+#include <palsuite.h>
+
+#define MODULENAMEBUFFERSIZE 1024
+
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ DWORD ModuleNameLength;
+ WCHAR *ModuleFileNameBuf;
+ int err;
+
+
+ //Initialize the PAL environment
+ err = PAL_Initialize(argc, argv);
+ if(0 != err)
+ {
+ ExitProcess(FAIL);
+ }
+
+ ModuleFileNameBuf = (WCHAR*)malloc(MODULENAMEBUFFERSIZE*sizeof(WCHAR));
+
+ //retrieve the current process full path and file name
+ //by passing a NULL module handle
+ ModuleNameLength = GetModuleFileName(
+ NULL, //a NULL handle
+ ModuleFileNameBuf,//buffer for module file name
+ MODULENAMEBUFFERSIZE);
+
+ //free the memory
+ free(ModuleFileNameBuf);
+
+ if(0 == ModuleNameLength)
+ {
+ Fail("\nFailed to all GetModuleFileName API!\n");
+ }
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/CMakeLists.txt
index 541ef8b98e..3dedba3cce 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/CMakeLists.txt
@@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
- testlib.c
+ test1.cpp
+ testlib.cpp
)
add_executable(paltest_getprocaddress_test1
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/test1.c b/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/test1.cpp
index f0b76c615f..f0b76c615f 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/test1.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/testlib.c b/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/testlib.cpp
index e8fe48e05d..e8fe48e05d 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/testlib.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/testlib.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test2/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test2/CMakeLists.txt
index 60a5ba1a6e..983c16f12f 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test2/CMakeLists.txt
@@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
- testlib.c
+ test2.cpp
+ testlib.cpp
)
add_executable(paltest_getprocaddress_test2
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test2/test2.c b/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test2/test2.cpp
index 9107728423..9107728423 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test2/test2.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test2/testlib.c b/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test2/testlib.cpp
index 23e58e871e..23e58e871e 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test2/testlib.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test2/testlib.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/GetProcessHeap/test1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/GetProcessHeap/test1/CMakeLists.txt
index 18871abf00..3e9c725f95 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/GetProcessHeap/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/GetProcessHeap/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetProcessHeap.c
+ GetProcessHeap.cpp
)
add_executable(paltest_getprocessheap_test1
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/GetProcessHeap/test1/GetProcessHeap.c b/src/pal/tests/palsuite/filemapping_memmgt/GetProcessHeap/test1/GetProcessHeap.cpp
index bec6b5c616..bec6b5c616 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/GetProcessHeap/test1/GetProcessHeap.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/GetProcessHeap/test1/GetProcessHeap.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test1/CMakeLists.txt
index 3a64a0c58a..b9ce32b35e 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- HeapAlloc.c
+ HeapAlloc.cpp
)
add_executable(paltest_heapalloc_test1
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test1/HeapAlloc.c b/src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test1/HeapAlloc.cpp
index 04de274e80..04de274e80 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test1/HeapAlloc.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test1/HeapAlloc.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test2/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test2/CMakeLists.txt
index 5253110d8d..1b9655ddba 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- HeapAlloc.c
+ HeapAlloc.cpp
)
add_executable(paltest_heapalloc_test2
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test2/HeapAlloc.c b/src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test2/HeapAlloc.cpp
index 5f4ff90498..5f4ff90498 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test2/HeapAlloc.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test2/HeapAlloc.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test3/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test3/CMakeLists.txt
index f0b89461d2..1c3845c6e9 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- HeapAlloc.c
+ HeapAlloc.cpp
)
add_executable(paltest_heapalloc_test3
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test3/HeapAlloc.c b/src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test3/HeapAlloc.cpp
index 4a74fe8194..4a74fe8194 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test3/HeapAlloc.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/HeapAlloc/test3/HeapAlloc.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/HeapFree/test1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/HeapFree/test1/CMakeLists.txt
index 898047a9ad..004912256c 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/HeapFree/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/HeapFree/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- HeapFree.c
+ HeapFree.cpp
)
add_executable(paltest_heapfree_test1
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/HeapFree/test1/HeapFree.c b/src/pal/tests/palsuite/filemapping_memmgt/HeapFree/test1/HeapFree.cpp
index 37b6b3bf60..37b6b3bf60 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/HeapFree/test1/HeapFree.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/HeapFree/test1/HeapFree.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test1/CMakeLists.txt
index 1decb02c73..17e0127435 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_heaprealloc_test1
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test1/test1.c b/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test1/test1.c
deleted file mode 100644
index 497d208eca..0000000000
--- a/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test1/test1.c
+++ /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.
-
-/*=============================================================
-**
-** Source: test1.c
-**
-** Purpose: Allocate some memory. Then reallocate that memory. Ensure the
-** return values are correct, and also that data placed in the allocated
-** memory carries over to the reallocated block.
-**
-**
-**============================================================*/
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
-
- HANDLE TheHeap;
- char* TheMemory;
- char* ReAllocMemory;
- int i;
-
- if(PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
- TheHeap = GetProcessHeap();
-
- if(TheHeap == NULL)
- {
- Fail("ERROR: GetProcessHeap() returned NULL when it was called. "
- "GetLastError() returned %d.",GetLastError());
- }
-
- /* Allocate 100 bytes on the heap */
- if((TheMemory = HeapAlloc(TheHeap, 0, 100)) == NULL)
- {
- Fail("ERROR: HeapAlloc returned NULL when it was called. "
- "GetLastError() returned %d.",GetLastError());
- }
-
- /* Set each byte of that memory block to 'x' */
- memset(TheMemory, 'X', 100);
-
- /* Reallocate the memory */
- ReAllocMemory = HeapReAlloc(TheHeap, 0, TheMemory, 100);
-
- if(ReAllocMemory == NULL)
- {
- Fail("ERROR: HeapReAlloc failed to reallocate the 100 bytes of "
- "heap memory. GetLastError returns %d.",GetLastError());
- }
-
- /* Check that each byte of the memory Reallocated is 'x' */
-
- for(i=0; i<100; ++i)
- {
- if(ReAllocMemory[i] != 'X')
- {
- Fail("ERROR: Byte number %d of the reallocated memory block "
- "is not set to 'X' as it should be.",i);
- }
- }
-
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test1/test1.cpp b/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test1/test1.cpp
new file mode 100644
index 0000000000..eedd45e45d
--- /dev/null
+++ b/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test1/test1.cpp
@@ -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.
+
+/*=============================================================
+**
+** Source: test1.c
+**
+** Purpose: Allocate some memory. Then reallocate that memory. Ensure the
+** return values are correct, and also that data placed in the allocated
+** memory carries over to the reallocated block.
+**
+**
+**============================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ HANDLE TheHeap;
+ char* TheMemory;
+ char* ReAllocMemory;
+ int i;
+
+ if(PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ TheHeap = GetProcessHeap();
+
+ if(TheHeap == NULL)
+ {
+ Fail("ERROR: GetProcessHeap() returned NULL when it was called. "
+ "GetLastError() returned %d.",GetLastError());
+ }
+
+ /* Allocate 100 bytes on the heap */
+ if((TheMemory = (char*)HeapAlloc(TheHeap, 0, 100)) == NULL)
+ {
+ Fail("ERROR: HeapAlloc returned NULL when it was called. "
+ "GetLastError() returned %d.",GetLastError());
+ }
+
+ /* Set each byte of that memory block to 'x' */
+ memset(TheMemory, 'X', 100);
+
+ /* Reallocate the memory */
+ ReAllocMemory = (char*)HeapReAlloc(TheHeap, 0, TheMemory, 100);
+
+ if(ReAllocMemory == NULL)
+ {
+ Fail("ERROR: HeapReAlloc failed to reallocate the 100 bytes of "
+ "heap memory. GetLastError returns %d.",GetLastError());
+ }
+
+ /* Check that each byte of the memory Reallocated is 'x' */
+
+ for(i=0; i<100; ++i)
+ {
+ if(ReAllocMemory[i] != 'X')
+ {
+ Fail("ERROR: Byte number %d of the reallocated memory block "
+ "is not set to 'X' as it should be.",i);
+ }
+ }
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test2/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test2/CMakeLists.txt
index 6f5510387a..a9239354ba 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_heaprealloc_test2
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test2/test2.c b/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test2/test2.c
deleted file mode 100644
index 13e789f901..0000000000
--- a/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test2/test2.c
+++ /dev/null
@@ -1,79 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: test2.c
-**
-** Purpose: Allocate some memory. Then reallocate that memory into less
-** space than the original amount. Ensure the
-** return values are correct, and also that data placed in the allocated
-** memory carries over to the reallocated block.
-**
-**
-**============================================================*/
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
-
- HANDLE TheHeap;
- char* TheMemory;
- char* ReAllocMemory;
- int i;
-
- if(PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
- TheHeap = GetProcessHeap();
-
- if(TheHeap == NULL)
- {
- Fail("ERROR: GetProcessHeap() returned NULL when it was called. "
- "GetLastError() returned %d.",GetLastError());
- }
-
- /* Allocate 200 bytes on the heap */
- if((TheMemory = HeapAlloc(TheHeap, 0, 200)) == NULL)
- {
- Fail("ERROR: HeapAlloc returned NULL when it was called. "
- "GetLastError() returned %d.",GetLastError());
- }
-
- /* Set the first 100 bytes to 'X' */
- memset(TheMemory, 'X', 100);
-
- /* Set the second 100 bytes to 'Z' */
- memset(TheMemory+100, 'Z', 100);
-
- /* Reallocate the memory to 100 bytes */
- ReAllocMemory = HeapReAlloc(TheHeap, 0, TheMemory, 100);
-
- if(ReAllocMemory == NULL)
- {
- Fail("ERROR: HeapReAlloc failed to reallocate the 100 bytes of "
- "heap memory. GetLastError returns %d.",GetLastError());
- }
-
- /* Check that each of the first 100 bytes hasn't lost any data.
- Anything beyond the first 100 might still be valid, but we can't
- gaurentee it.
- */
-
- for(i=0; i<100; ++i)
- {
- /* Note: Cast to char* so the function knows the size is 1 */
- if(ReAllocMemory[i] != 'X')
- {
- Fail("ERROR: Byte number %d of the reallocated memory block "
- "is not set to 'X' as it should be.",i);
- }
- }
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test2/test2.cpp b/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test2/test2.cpp
new file mode 100644
index 0000000000..a7e3b2a055
--- /dev/null
+++ b/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test2/test2.cpp
@@ -0,0 +1,79 @@
+// Licensed to the .NET Foundation under one or more 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: test2.c
+**
+** Purpose: Allocate some memory. Then reallocate that memory into less
+** space than the original amount. Ensure the
+** return values are correct, and also that data placed in the allocated
+** memory carries over to the reallocated block.
+**
+**
+**============================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ HANDLE TheHeap;
+ char* TheMemory;
+ char* ReAllocMemory;
+ int i;
+
+ if(PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ TheHeap = GetProcessHeap();
+
+ if(TheHeap == NULL)
+ {
+ Fail("ERROR: GetProcessHeap() returned NULL when it was called. "
+ "GetLastError() returned %d.",GetLastError());
+ }
+
+ /* Allocate 200 bytes on the heap */
+ if((TheMemory = (char*)HeapAlloc(TheHeap, 0, 200)) == NULL)
+ {
+ Fail("ERROR: HeapAlloc returned NULL when it was called. "
+ "GetLastError() returned %d.",GetLastError());
+ }
+
+ /* Set the first 100 bytes to 'X' */
+ memset(TheMemory, 'X', 100);
+
+ /* Set the second 100 bytes to 'Z' */
+ memset(TheMemory+100, 'Z', 100);
+
+ /* Reallocate the memory to 100 bytes */
+ ReAllocMemory = (char*)HeapReAlloc(TheHeap, 0, TheMemory, 100);
+
+ if(ReAllocMemory == NULL)
+ {
+ Fail("ERROR: HeapReAlloc failed to reallocate the 100 bytes of "
+ "heap memory. GetLastError returns %d.",GetLastError());
+ }
+
+ /* Check that each of the first 100 bytes hasn't lost any data.
+ Anything beyond the first 100 might still be valid, but we can't
+ gaurentee it.
+ */
+
+ for(i=0; i<100; ++i)
+ {
+ /* Note: Cast to char* so the function knows the size is 1 */
+ if(ReAllocMemory[i] != 'X')
+ {
+ Fail("ERROR: Byte number %d of the reallocated memory block "
+ "is not set to 'X' as it should be.",i);
+ }
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test3/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test3/CMakeLists.txt
index 7ad836706a..2d82b6efdd 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_heaprealloc_test3
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test3/test3.c b/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test3/test3.c
deleted file mode 100644
index dea9de348d..0000000000
--- a/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test3/test3.c
+++ /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.
-
-/*=============================================================
-**
-** Source: test3.c
-**
-** Purpose: Allocate some memory. Then reallocate that memory into a
-** bigger space on the heap. Check that the first portion of the data is
-** unchanged. Then set the new portion to a value, to ensure that it is
-** properly writable memory.
-**
-**
-**============================================================*/
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
-
- HANDLE TheHeap;
- char* TheMemory;
- char* ReAllocMemory;
- int i;
-
- if(PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
- TheHeap = GetProcessHeap();
-
- if(TheHeap == NULL)
- {
- Fail("ERROR: GetProcessHeap() returned NULL when it was called. "
- "GetLastError() returned %d.",GetLastError());
- }
-
- /* Allocate 100 bytes on the heap */
- if((TheMemory = HeapAlloc(TheHeap, 0, 100)) == NULL)
- {
- Fail("ERROR: HeapAlloc returned NULL when it was called. "
- "GetLastError() returned %d.",GetLastError());
- }
-
- /* Set the first 100 bytes to 'X' */
- memset(TheMemory, 'X', 100);
-
- /* Reallocate the memory to 200 bytes */
- ReAllocMemory = HeapReAlloc(TheHeap, 0, TheMemory, 200);
-
- if(ReAllocMemory == NULL)
- {
- Fail("ERROR: HeapReAlloc failed to reallocate the 100 bytes of "
- "heap memory. GetLastError returns %d.",GetLastError());
- }
-
- /* Check that each of the first 100 bytes hasn't lost any data. */
- for(i=0; i<100; ++i)
- {
-
- if(ReAllocMemory[i] != 'X')
- {
- Fail("ERROR: Byte number %d of the reallocated memory block "
- "is not set to 'X' as it should be.",i);
- }
- }
-
- /* Beyond the first 100 bytes is valid free memory. We'll set all this
- memory to a value -- though, even if HeapReAlloc didn't work, it might
- still be possible to memset this memory without raising an exception.
- */
- memset(ReAllocMemory+100, 'Z', 100);
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test3/test3.cpp b/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test3/test3.cpp
new file mode 100644
index 0000000000..d4139e8d5e
--- /dev/null
+++ b/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test3/test3.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.
+
+/*=============================================================
+**
+** Source: test3.c
+**
+** Purpose: Allocate some memory. Then reallocate that memory into a
+** bigger space on the heap. Check that the first portion of the data is
+** unchanged. Then set the new portion to a value, to ensure that it is
+** properly writable memory.
+**
+**
+**============================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ HANDLE TheHeap;
+ char* TheMemory;
+ char* ReAllocMemory;
+ int i;
+
+ if(PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ TheHeap = GetProcessHeap();
+
+ if(TheHeap == NULL)
+ {
+ Fail("ERROR: GetProcessHeap() returned NULL when it was called. "
+ "GetLastError() returned %d.",GetLastError());
+ }
+
+ /* Allocate 100 bytes on the heap */
+ if((TheMemory = (char*)HeapAlloc(TheHeap, 0, 100)) == NULL)
+ {
+ Fail("ERROR: HeapAlloc returned NULL when it was called. "
+ "GetLastError() returned %d.",GetLastError());
+ }
+
+ /* Set the first 100 bytes to 'X' */
+ memset(TheMemory, 'X', 100);
+
+ /* Reallocate the memory to 200 bytes */
+ ReAllocMemory = (char*)HeapReAlloc(TheHeap, 0, TheMemory, 200);
+
+ if(ReAllocMemory == NULL)
+ {
+ Fail("ERROR: HeapReAlloc failed to reallocate the 100 bytes of "
+ "heap memory. GetLastError returns %d.",GetLastError());
+ }
+
+ /* Check that each of the first 100 bytes hasn't lost any data. */
+ for(i=0; i<100; ++i)
+ {
+
+ if(ReAllocMemory[i] != 'X')
+ {
+ Fail("ERROR: Byte number %d of the reallocated memory block "
+ "is not set to 'X' as it should be.",i);
+ }
+ }
+
+ /* Beyond the first 100 bytes is valid free memory. We'll set all this
+ memory to a value -- though, even if HeapReAlloc didn't work, it might
+ still be possible to memset this memory without raising an exception.
+ */
+ memset(ReAllocMemory+100, 'Z', 100);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test4/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test4/CMakeLists.txt
index 024a4ef840..129d8a47cd 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_heaprealloc_test4
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test4/test4.c b/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test4/test4.cpp
index cebf904501..cebf904501 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test4/test4.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test5/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test5/CMakeLists.txt
index 3ab3ec16e8..ed3d390625 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_heaprealloc_test5
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test5/test5.c b/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test5/test5.c
deleted file mode 100644
index 230e65e492..0000000000
--- a/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test5/test5.c
+++ /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.
-
-/*=============================================================
-**
-** Source: test5.c
-**
-** Purpose: Allocate some memory. Then call HeapRealloc with 0 as the
-** amount of memory to reallocate. This should work, essentially freeing
-** the memory (though we can't verfiy this)
-**
-**
-**============================================================*/
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
-
- HANDLE TheHeap;
- char* TheMemory;
- char* ReAllocMemory;
- char* ReAllocMemory2;
-
- if(PAL_Initialize(argc, argv) != 0)
- {
- return FAIL;
- }
-
- TheHeap = GetProcessHeap();
-
- if(TheHeap == NULL)
- {
- Fail("ERROR: GetProcessHeap() returned NULL when it was called. "
- "GetLastError() returned %d.",GetLastError());
- }
-
- /* Allocate 100 bytes on the heap */
- if((TheMemory = HeapAlloc(TheHeap, 0, 100)) == NULL)
- {
- Fail("ERROR: HeapAlloc returned NULL when it was called. "
- "GetLastError() returned %d.",GetLastError());
- }
-
- /* Set each byte of that memory block to 'x' */
- memset(TheMemory, 'X', 100);
-
- /* Reallocate the memory into 0 bytes */
- ReAllocMemory = HeapReAlloc(TheHeap, 0, TheMemory, 0);
-
- if(ReAllocMemory == NULL)
- {
- Fail("ERROR: HeapReAlloc failed to reallocate the 100 bytes of "
- "heap memory. GetLastError returns %d.",GetLastError());
- }
-
- /* Reallocate the memory we just put into 0 bytes, into 100 bytes. */
- ReAllocMemory2 = HeapReAlloc(TheHeap, 0, ReAllocMemory, 100);
-
- if(ReAllocMemory2 == NULL)
- {
- Fail("ERROR: HeapReAlloc failed to reallocate the 0 bytes of "
- "heap memory into 100. GetLastError returns %d.",GetLastError());
- }
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test5/test5.cpp b/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test5/test5.cpp
new file mode 100644
index 0000000000..fcd38376ec
--- /dev/null
+++ b/src/pal/tests/palsuite/filemapping_memmgt/HeapReAlloc/test5/test5.cpp
@@ -0,0 +1,69 @@
+// Licensed to the .NET Foundation under one or more 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: test5.c
+**
+** Purpose: Allocate some memory. Then call HeapRealloc with 0 as the
+** amount of memory to reallocate. This should work, essentially freeing
+** the memory (though we can't verfiy this)
+**
+**
+**============================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ HANDLE TheHeap;
+ char* TheMemory;
+ char* ReAllocMemory;
+ char* ReAllocMemory2;
+
+ if(PAL_Initialize(argc, argv) != 0)
+ {
+ return FAIL;
+ }
+
+ TheHeap = GetProcessHeap();
+
+ if(TheHeap == NULL)
+ {
+ Fail("ERROR: GetProcessHeap() returned NULL when it was called. "
+ "GetLastError() returned %d.",GetLastError());
+ }
+
+ /* Allocate 100 bytes on the heap */
+ if((TheMemory = (char*)HeapAlloc(TheHeap, 0, 100)) == NULL)
+ {
+ Fail("ERROR: HeapAlloc returned NULL when it was called. "
+ "GetLastError() returned %d.",GetLastError());
+ }
+
+ /* Set each byte of that memory block to 'x' */
+ memset(TheMemory, 'X', 100);
+
+ /* Reallocate the memory into 0 bytes */
+ ReAllocMemory = (char*)HeapReAlloc(TheHeap, 0, TheMemory, 0);
+
+ if(ReAllocMemory == NULL)
+ {
+ Fail("ERROR: HeapReAlloc failed to reallocate the 100 bytes of "
+ "heap memory. GetLastError returns %d.",GetLastError());
+ }
+
+ /* Reallocate the memory we just put into 0 bytes, into 100 bytes. */
+ ReAllocMemory2 = (char*)HeapReAlloc(TheHeap, 0, ReAllocMemory, 100);
+
+ if(ReAllocMemory2 == NULL)
+ {
+ Fail("ERROR: HeapReAlloc failed to reallocate the 0 bytes of "
+ "heap memory into 100. GetLastError returns %d.",GetLastError());
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/LocalAlloc/test1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/LocalAlloc/test1/CMakeLists.txt
index c96e00a170..f74e442d76 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/LocalAlloc/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/LocalAlloc/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- LocalAlloc.c
+ LocalAlloc.cpp
)
add_executable(paltest_localalloc_test1
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/LocalAlloc/test1/LocalAlloc.c b/src/pal/tests/palsuite/filemapping_memmgt/LocalAlloc/test1/LocalAlloc.cpp
index 17afbc6020..17afbc6020 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/LocalAlloc/test1/LocalAlloc.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/LocalAlloc/test1/LocalAlloc.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/LocalFree/test1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/LocalFree/test1/CMakeLists.txt
index 47ad76ebe6..d92939c7cc 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/LocalFree/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/LocalFree/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- LocalFree.c
+ LocalFree.cpp
)
add_executable(paltest_localfree_test1
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/LocalFree/test1/LocalFree.c b/src/pal/tests/palsuite/filemapping_memmgt/LocalFree/test1/LocalFree.cpp
index d9c062e761..d9c062e761 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/LocalFree/test1/LocalFree.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/LocalFree/test1/LocalFree.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/LocalFree/test2/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/LocalFree/test2/CMakeLists.txt
index ac7a11a05f..e087b08ad7 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/LocalFree/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/LocalFree/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- LocalFree.c
+ LocalFree.cpp
)
add_executable(paltest_localfree_test2
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/LocalFree/test2/LocalFree.c b/src/pal/tests/palsuite/filemapping_memmgt/LocalFree/test2/LocalFree.cpp
index 4d4567dc3f..4d4567dc3f 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/LocalFree/test2/LocalFree.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/LocalFree/test2/LocalFree.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test1/CMakeLists.txt
index 0af09480ef..1d08065b2a 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(TESTSOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_lockfile_test1
@@ -20,7 +20,7 @@ target_link_libraries(paltest_lockfile_test1
set(HELPERSOURCES
- helper.c
+ helper.cpp
)
add_executable(paltest_lockfile_test1_helper
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test1/helper.c b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test1/helper.cpp
index 05b4b8451a..05b4b8451a 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test1/helper.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test1/helper.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test1/test1.c b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test1/test1.cpp
index cee223ef81..cee223ef81 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test1/test1.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test2/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test2/CMakeLists.txt
index 157c517e62..ca5e5faed4 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_lockfile_test2
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test2/test2.c b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test2/test2.cpp
index 8aef130ef4..8aef130ef4 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test2/test2.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test3/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test3/CMakeLists.txt
index 69516de69b..117c715084 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(TESTSOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_lockfile_test3
@@ -20,7 +20,7 @@ target_link_libraries(paltest_lockfile_test3
set(HELPERSOURCES
- helper.c
+ helper.cpp
)
add_executable(paltest_lockfile_test3_helper
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test3/helper.c b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test3/helper.cpp
index 079417fce8..079417fce8 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test3/helper.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test3/helper.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test3/test3.c b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test3/test3.cpp
index 78662c5685..78662c5685 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test3/test3.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test4/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test4/CMakeLists.txt
index fb8f6745d4..aee1b1a0be 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_lockfile_test4
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test4/test4.c b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test4/test4.cpp
index f5cd359fb5..f5cd359fb5 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test4/test4.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test5/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test5/CMakeLists.txt
index cc4548a6f0..70e3db4561 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(TESTSOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_lockfile_test5
@@ -20,7 +20,7 @@ target_link_libraries(paltest_lockfile_test5
set(HELPERSOURCES
- helper.c
+ helper.cpp
)
add_executable(paltest_lockfile_test5_helper
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test5/helper.c b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test5/helper.cpp
index 1fc9b1a9a5..1fc9b1a9a5 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test5/helper.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test5/helper.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test5/test5.c b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test5/test5.cpp
index a02a3c5a49..a02a3c5a49 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test5/test5.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test5/test5.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test6/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test6/CMakeLists.txt
index 5049977582..255ecbcc8d 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(TESTSOURCES
- test6.c
+ test6.cpp
)
add_executable(paltest_lockfile_test6
@@ -20,7 +20,7 @@ target_link_libraries(paltest_lockfile_test6
set(HELPERSOURCES
- helper.c
+ helper.cpp
)
add_executable(paltest_lockfile_test6_helper
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test6/helper.c b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test6/helper.cpp
index 98112fc4a5..98112fc4a5 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test6/helper.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test6/helper.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test6/test6.c b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test6/test6.cpp
index ba01b9710a..ba01b9710a 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test6/test6.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test6/test6.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test7/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test7/CMakeLists.txt
index e8434cc787..68a5b9f659 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test7/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test7/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test7.c
+ test7.cpp
)
add_executable(paltest_lockfile_test7
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test7/test7.c b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test7/test7.cpp
index c572a6e653..c572a6e653 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test7/test7.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/LockFile/test7/test7.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test1/CMakeLists.txt
index ef9838d41e..01679e5387 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- MapViewOfFile.c
+ MapViewOfFile.cpp
)
add_executable(paltest_mapviewoffile_test1
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test1/MapViewOfFile.c b/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test1/MapViewOfFile.cpp
index 6177e0decf..6177e0decf 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test1/MapViewOfFile.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test1/MapViewOfFile.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test2/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test2/CMakeLists.txt
index 18a9d105b1..88f3344567 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- MapViewOfFile.c
+ MapViewOfFile.cpp
)
add_executable(paltest_mapviewoffile_test2
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test2/MapViewOfFile.c b/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test2/MapViewOfFile.cpp
index c08f585c0e..c08f585c0e 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test2/MapViewOfFile.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test2/MapViewOfFile.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test3/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test3/CMakeLists.txt
index 76bd3276a4..e48ce13408 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- MapViewOfFile.c
+ MapViewOfFile.cpp
)
add_executable(paltest_mapviewoffile_test3
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test3/MapViewOfFile.c b/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test3/MapViewOfFile.cpp
index 63bee768f9..63bee768f9 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test3/MapViewOfFile.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test3/MapViewOfFile.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test4/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test4/CMakeLists.txt
index 52381c510f..7f6d905212 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- mapviewoffile.c
+ mapviewoffile.cpp
)
add_executable(paltest_mapviewoffile_test4
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test4/mapviewoffile.c b/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test4/mapviewoffile.cpp
index 7f3252144b..7f3252144b 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test4/mapviewoffile.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test4/mapviewoffile.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test5/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test5/CMakeLists.txt
index f98a4b7779..3911ffa53c 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- mapviewoffile.c
+ mapviewoffile.cpp
)
add_executable(paltest_mapviewoffile_test5
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test5/mapviewoffile.c b/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test5/mapviewoffile.cpp
index 219b3fa12a..219b3fa12a 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test5/mapviewoffile.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test5/mapviewoffile.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test6/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test6/CMakeLists.txt
index dad03aaf80..8199981eec 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- mapviewoffile.c
+ mapviewoffile.cpp
)
add_executable(paltest_mapviewoffile_test6
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test6/mapviewoffile.c b/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test6/mapviewoffile.cpp
index f7d7302a4c..f7d7302a4c 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test6/mapviewoffile.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/MapViewOfFile/test6/mapviewoffile.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test1/CMakeLists.txt
index b286924864..e4d87d5e0f 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- OpenFileMappingA.c
+ OpenFileMappingA.cpp
)
add_executable(paltest_openfilemappinga_test1
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test1/OpenFileMappingA.c b/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test1/OpenFileMappingA.cpp
index 9087285112..9087285112 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test1/OpenFileMappingA.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test1/OpenFileMappingA.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test2/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test2/CMakeLists.txt
index 3a0eff04a7..670346fe3b 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- OpenFileMappingA.c
+ OpenFileMappingA.cpp
)
add_executable(paltest_openfilemappinga_test2
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test2/OpenFileMappingA.c b/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test2/OpenFileMappingA.cpp
index 5e41a92024..5e41a92024 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test2/OpenFileMappingA.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test2/OpenFileMappingA.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test3/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test3/CMakeLists.txt
index 599a09ffc7..dab27b5c74 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- OpenFileMappingA.c
+ OpenFileMappingA.cpp
)
add_executable(paltest_openfilemappinga_test3
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test3/OpenFileMappingA.c b/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test3/OpenFileMappingA.cpp
index b01a3e8c0b..b01a3e8c0b 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test3/OpenFileMappingA.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingA/test3/OpenFileMappingA.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test1/CMakeLists.txt
index 04e9e47ef0..b2f4494ad8 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- OpenFileMappingW.c
+ OpenFileMappingW.cpp
)
add_executable(paltest_openfilemappingw_test1
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test1/OpenFileMappingW.c b/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test1/OpenFileMappingW.cpp
index 079af4a5c0..079af4a5c0 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test1/OpenFileMappingW.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test1/OpenFileMappingW.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test2/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test2/CMakeLists.txt
index 22e960b788..655fa753f2 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- OpenFileMappingW.c
+ OpenFileMappingW.cpp
)
add_executable(paltest_openfilemappingw_test2
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test2/OpenFileMappingW.c b/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test2/OpenFileMappingW.cpp
index e6a69651fa..e6a69651fa 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test2/OpenFileMappingW.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test2/OpenFileMappingW.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test3/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test3/CMakeLists.txt
index 5a54368110..a7039a1c73 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- OpenFileMappingW.c
+ OpenFileMappingW.cpp
)
add_executable(paltest_openfilemappingw_test3
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test3/OpenFileMappingW.c b/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test3/OpenFileMappingW.cpp
index 9c83491f6b..9c83491f6b 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test3/OpenFileMappingW.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/OpenFileMappingW/test3/OpenFileMappingW.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/CMakeLists.txt
new file mode 100644
index 0000000000..c6eddf74e8
--- /dev/null
+++ b/src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(ProbeMemory_neg1)
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/ProbeMemory_neg1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/ProbeMemory_neg1/CMakeLists.txt
new file mode 100644
index 0000000000..e96c92e2ae
--- /dev/null
+++ b/src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/ProbeMemory_neg1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ ProbeMemory_neg.cpp
+)
+
+add_executable(paltest_probememory_probememory_neg1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_probememory_probememory_neg1 coreclrpal)
+
+target_link_libraries(paltest_probememory_probememory_neg1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/ProbeMemory_neg1/ProbeMemory_neg.cpp b/src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/ProbeMemory_neg1/ProbeMemory_neg.cpp
new file mode 100644
index 0000000000..80de809e14
--- /dev/null
+++ b/src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/ProbeMemory_neg1/ProbeMemory_neg.cpp
@@ -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.
+
+/*=============================================================
+**
+** Source: ReadProcessMemory_neg.c
+**
+** Purpose: Negative test the ReadProcessMemory API.
+** Call ReadProcessMemory to read unreadabel memory area
+**
+**
+**============================================================*/
+#include <palsuite.h>
+
+#define REGIONSIZE 1024
+
+int __cdecl main(int argc, char *argv[])
+{
+ int err;
+ BOOL bResult;
+ LPVOID lpProcessAddress = NULL;
+
+ /*Initialize the PAL environment*/
+ err = PAL_Initialize(argc, argv);
+ if(0 != err)
+ {
+ return FAIL;
+ }
+
+ /*allocate the virtual memory*/
+ lpProcessAddress = VirtualAlloc(
+ NULL, /*system determine where to allocate the region*/
+ REGIONSIZE, /*specify the size*/
+ MEM_RESERVE, /*allocation type*/
+ PAGE_READONLY); /*access protection*/
+
+ if(NULL == lpProcessAddress)
+ {
+ Fail("\nFailed to call VirtualAlloc API to allocate "
+ "virtual memory, error code=%u\n", GetLastError());
+ }
+
+ /*try to probe the unreadable memory area*/
+ bResult = PAL_ProbeMemory(
+ lpProcessAddress, /*base of memory area*/
+ REGIONSIZE, /*buffer length in bytes*/
+ FALSE); /*read access*/
+
+ /*check the return value*/
+ if(bResult)
+ {
+ Trace("\nProbeMemory for read didn't FAILED\n");
+
+ /*decommit the specified region*/
+ err = VirtualFree(lpProcessAddress, REGIONSIZE, MEM_DECOMMIT);
+ if(0 == err)
+ {
+ Fail("\nFailed to call VirtualFree API, error code=%u\n", GetLastError());
+ }
+
+ Fail("");
+ }
+
+ /*try to probe the unwriteable memory area*/
+ bResult = PAL_ProbeMemory(
+ lpProcessAddress, /*base of memory area*/
+ REGIONSIZE, /*buffer length in bytes*/
+ FALSE); /*write access */
+
+ /*check the return value*/
+ if(bResult)
+ {
+ Trace("\nProbeMemory for write didn't FAILED\n");
+
+ /*decommit the specified region*/
+ err = VirtualFree(lpProcessAddress, REGIONSIZE, MEM_DECOMMIT);
+ if(0 == err)
+ {
+ Fail("\nFailed to call VirtualFree API, error code=%u\n", GetLastError());
+ }
+
+ Fail("");
+ }
+
+ /*decommit the specified region*/
+ err = VirtualFree(lpProcessAddress, REGIONSIZE, MEM_DECOMMIT);
+ if(0 == err)
+ {
+ Fail("\nFailed to call VirtualFree API, error code=%u\n", GetLastError());
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/ProbeMemory_neg1/testinfo.dat b/src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/ProbeMemory_neg1/testinfo.dat
new file mode 100644
index 0000000000..4d11a71bdb
--- /dev/null
+++ b/src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/ProbeMemory_neg1/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 = Filemapping_memmgt
+Function = PAL_ProbeMemory
+Name = Negative test PAL_ProbeMemory API to read unreadable memory area
+TYPE = DEFAULT
+EXE1 = probememory_neg
+Description
+=Test the PAL_ProbeMemory to read unreadable memory area
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/test1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/test1/CMakeLists.txt
new file mode 100644
index 0000000000..739ba62284
--- /dev/null
+++ b/src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/test1/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ ProbeMemory.cpp
+)
+
+add_executable(paltest_probememory_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_probememory_test1 coreclrpal)
+
+target_link_libraries(paltest_probememory_test1
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/test1/ProbeMemory.cpp b/src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/test1/ProbeMemory.cpp
new file mode 100644
index 0000000000..30b358d315
--- /dev/null
+++ b/src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/test1/ProbeMemory.cpp
@@ -0,0 +1,94 @@
+// Licensed to the .NET Foundation under one or more 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: ReadProcessMemory.c
+**
+** Purpose: Positive test the ReadProcessMemory API.
+** Call ReadProcessMemory to read memory contents
+** inside current process.
+**
+**
+**============================================================*/
+#include <palsuite.h>
+
+#define REGIONSIZE 1024
+
+int __cdecl main(int argc, char *argv[])
+{
+ int err;
+ BOOL bResult;
+ LPVOID lpProcessAddress = NULL;
+
+ /*Initialize the PAL environment*/
+ err = PAL_Initialize(argc, argv);
+ if(0 != err)
+ {
+ return FAIL;
+ }
+
+ /*allocate the virtual memory*/
+ lpProcessAddress = VirtualAlloc(
+ NULL, /*system determine where to allocate the region*/
+ REGIONSIZE, /*specify the size*/
+ MEM_COMMIT, /*allocation type*/
+ PAGE_READWRITE); /*access protection*/
+
+ if(NULL == lpProcessAddress)
+ {
+ Fail("\nFailed to call VirtualAlloc API to allocate "
+ "virtual memory, error code=%u!\n", GetLastError());
+ }
+
+ /*probe the memory for read*/
+ bResult = PAL_ProbeMemory(
+ lpProcessAddress, /*base of memory area*/
+ REGIONSIZE, /*buffer length in bytes*/
+ FALSE); /*read access*/
+
+ if(!bResult)
+ {
+ Trace("\nProbeMemory for read access FAILED\n");
+
+ /*decommit the specified region*/
+ err = VirtualFree(lpProcessAddress, REGIONSIZE, MEM_DECOMMIT);
+ if(0 == err)
+ {
+ Fail("\nFailed to call VirtualFree API, error code=%u\n", GetLastError());
+ }
+
+ Fail("");
+ }
+
+ /*probe the memory for write */
+ bResult = PAL_ProbeMemory(
+ lpProcessAddress, /*base of memory area*/
+ REGIONSIZE, /*buffer length in bytes*/
+ TRUE); /*write access*/
+
+ if(!bResult)
+ {
+ Trace("\nProbeMemory for write access FAILED\n");
+
+ /*decommit the specified region*/
+ err = VirtualFree(lpProcessAddress, REGIONSIZE, MEM_DECOMMIT);
+ if(0 == err)
+ {
+ Fail("\nFailed to call VirtualFree API, error code=%u\n", GetLastError());
+ }
+
+ Fail("");
+ }
+
+ /*decommit the specified region*/
+ err = VirtualFree(lpProcessAddress, REGIONSIZE, MEM_DECOMMIT);
+ if(0 == err)
+ {
+ Fail("\nFailed to call VirtualFree API, error code=%u\n", GetLastError());
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/test1/testinfo.dat b/src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/test1/testinfo.dat
new file mode 100644
index 0000000000..512b945c4a
--- /dev/null
+++ b/src/pal/tests/palsuite/filemapping_memmgt/ProbeMemory/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 = Filemapping_memmgt
+Function = PAL_ProbeMemory
+Name = Positive test for PAL_ProbeMemory API to probe for read/write
+TYPE = DEFAULT
+EXE1 = probememory
+Description
+=Test the PAL_ProbeMemory to probe for read and write
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/CMakeLists.txt
deleted file mode 100644
index d2ae61f923..0000000000
--- a/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/CMakeLists.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-add_subdirectory(ReadProcessMemory_neg1)
-add_subdirectory(test1)
-add_subdirectory(test2)
-
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/ReadProcessMemory_neg1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/ReadProcessMemory_neg1/CMakeLists.txt
deleted file mode 100644
index 400c9219f6..0000000000
--- a/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/ReadProcessMemory_neg1/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- ReadProcessMemory_neg.c
-)
-
-add_executable(paltest_readprocessmemory_readprocessmemory_neg1
- ${SOURCES}
-)
-
-add_dependencies(paltest_readprocessmemory_readprocessmemory_neg1 coreclrpal)
-
-target_link_libraries(paltest_readprocessmemory_readprocessmemory_neg1
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/ReadProcessMemory_neg1/ReadProcessMemory_neg.c b/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/ReadProcessMemory_neg1/ReadProcessMemory_neg.c
deleted file mode 100644
index aecd5ad576..0000000000
--- a/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/ReadProcessMemory_neg1/ReadProcessMemory_neg.c
+++ /dev/null
@@ -1,127 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: ReadProcessMemory_neg.c
-**
-** Purpose: Negative test the ReadProcessMemory API.
-** Call ReadProcessMemory to read unreadabel memory area
-**
-**
-**============================================================*/
-#include <palsuite.h>
-
-#define REGIONSIZE 1024
-
-int __cdecl main(int argc, char *argv[])
-{
- int err;
- BOOL bResult;
- HANDLE ProcessHandle;
- DWORD ProcessID;
- LPVOID lpProcessAddress = NULL;
- char ProcessBuffer[REGIONSIZE];
- ULONG_PTR size = 0;
-
-
- /*Initialize the PAL environment*/
- err = PAL_Initialize(argc, argv);
- if(0 != err)
- {
- return FAIL;
- }
-
- /*retrieve the current process ID*/
- ProcessID = GetCurrentProcessId();
-
- /*retrieve the current process handle*/
- ProcessHandle = OpenProcess(
- PROCESS_ALL_ACCESS,
- FALSE, /*not inherited*/
- ProcessID);
-
- if(NULL == ProcessHandle)
- {
- Fail("\nFailed to call OpenProcess API to retrieve "
- "current process handle error code=%u\n",
- GetLastError());
- }
-
-
-
- /*allocate the virtual memory*/
- lpProcessAddress = VirtualAlloc(
- NULL, /*system determine where to allocate the region*/
- REGIONSIZE, /*specify the size*/
- MEM_RESERVE, /*allocation type*/
- PAGE_READONLY); /*access protection*/
-
- if(NULL == lpProcessAddress)
- {
- Fail("\nFailed to call VirtualAlloc API to allocate "
- "virtual memory, error code=%u\n", GetLastError());
- }
-
- /*zero the memory*/
- memset(ProcessBuffer, 0, REGIONSIZE);
- /*try to retrieve the unreadable memory area*/
- bResult = ReadProcessMemory(
- ProcessHandle, /*current process handle*/
- lpProcessAddress, /*base of memory area*/
- (LPVOID)ProcessBuffer,
- REGIONSIZE, /*buffer length in bytes*/
- &size);
-
-
- /*check the return value*/
- if(0 != bResult)
- {
- Trace("\nFailed to call ReadProcessMemory API for a negative test, "
- "Try to read an unreadable memory area will cause fail "
- "but it successes\n");
-
- err = CloseHandle(ProcessHandle);
- if(0 == err)
- {
- Trace("\nFailed to call CloseHandle API, error code=%u\n",
- GetLastError());
- }
-
- /*decommit the specified region*/
- err = VirtualFree(lpProcessAddress, REGIONSIZE, MEM_DECOMMIT);
- if(0 == err)
- {
- Trace("\nFailed to call VirtualFree API, error code=%u\n",
- GetLastError());
- }
- Fail("");
- }
-
- err = CloseHandle(ProcessHandle);
- if(0 == err)
- {
- Trace("\nFailed to call CloseHandle API, error code = %u\n",
- GetLastError());
-
- err = VirtualFree(lpProcessAddress, REGIONSIZE, MEM_DECOMMIT);
- if(0 == err)
- {
- Trace("\nFailed to call VirtualFree API, error code=%u\n",
- GetLastError());
- }
-
- Fail("");
- }
- /*decommit the specified region*/
- err = VirtualFree(lpProcessAddress, REGIONSIZE, MEM_DECOMMIT);
- if(0 == err)
- {
- Fail("\nFailed to call VirtualFree API, error code=%u\n",
- GetLastError());
- }
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/ReadProcessMemory_neg1/testinfo.dat b/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/ReadProcessMemory_neg1/testinfo.dat
deleted file mode 100644
index 08c8f3291d..0000000000
--- a/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/ReadProcessMemory_neg1/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = Filemapping_memmgt
-Function = ReadProcessMemory
-Name = Negative test ReadProcessMemory API to read unreadable memory area
-TYPE = DEFAULT
-EXE1 = readprocessmemory_neg
-Description
-=Test the ReadProcessMemory to read unreadable memory area
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test1/CMakeLists.txt
deleted file mode 100644
index 8c21f01562..0000000000
--- a/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test1/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- ReadProcessMemory.c
-)
-
-add_executable(paltest_readprocessmemory_test1
- ${SOURCES}
-)
-
-add_dependencies(paltest_readprocessmemory_test1 coreclrpal)
-
-target_link_libraries(paltest_readprocessmemory_test1
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test1/ReadProcessMemory.c b/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test1/ReadProcessMemory.c
deleted file mode 100644
index c9475f13f1..0000000000
--- a/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test1/ReadProcessMemory.c
+++ /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.
-
-/*=============================================================
-**
-** Source: ReadProcessMemory.c
-**
-** Purpose: Positive test the ReadProcessMemory API.
-** Call ReadProcessMemory to read memory contents
-** inside current process.
-**
-**
-**============================================================*/
-#include <palsuite.h>
-
-#define REGIONSIZE 1024
-
-int __cdecl main(int argc, char *argv[])
-{
- int err;
- BOOL bResult;
- HANDLE ProcessHandle;
- DWORD ProcessID;
- LPVOID lpProcessAddress = NULL;
- char ProcessBuffer[REGIONSIZE];
- ULONG_PTR size = 0;
-
-
- /*Initialize the PAL environment*/
- err = PAL_Initialize(argc, argv);
- if(0 != err)
- {
- return FAIL;
- }
-
- /*retrieve the current process ID*/
- ProcessID = GetCurrentProcessId();
-
- /*retrieve the current process handle*/
- ProcessHandle = OpenProcess(
- PROCESS_VM_READ,/*access flag*/
- FALSE, /*not inherited*/
- ProcessID);
-
- if(NULL == ProcessHandle)
- {
- Fail("\nFailed to call OpenProcess API to retrieve "
- "current process handle error code=%u\n",
- GetLastError());
- }
-
- /*allocate the virtual memory*/
- lpProcessAddress = VirtualAlloc(
- NULL, /*system determine where to allocate the region*/
- REGIONSIZE, /*specify the size*/
- MEM_COMMIT, /*allocation type*/
- PAGE_READONLY); /*access protection*/
-
- if(NULL == lpProcessAddress)
- {
- Fail("\nFailed to call VirtualAlloc API to allocate "
- "virtual memory, error code=%u!\n", GetLastError());
- }
-
- /*zero the memory*/
- memset(ProcessBuffer, 0, REGIONSIZE);
-
- /*retrieve the memory contents*/
- bResult = ReadProcessMemory(
- ProcessHandle, /*current process handle*/
- lpProcessAddress, /*base of memory area*/
- (LPVOID)ProcessBuffer,
- REGIONSIZE, /*buffer length in bytes*/
- &size);
-
- if(!bResult || REGIONSIZE != size)
- {
- Trace("\nFailed to call ReadProcessMemory API "
- "to retrieve the memory contents, error code=%u\n",
- GetLastError());
-
- err = CloseHandle(ProcessHandle);
- if(0 == err)
- {
- Trace("\nFailed to call CloseHandle API, error code=%u\n",
- GetLastError());
- }
-
- /*decommit the specified region*/
- err = VirtualFree(lpProcessAddress, REGIONSIZE, MEM_DECOMMIT);
- if(0 == err)
- {
- Trace("\nFailed to call VirtualFree API, error code=%u\n",
- GetLastError());
- }
- Fail("");
- }
-
- err = CloseHandle(ProcessHandle);
- if(0 == err)
- {
- Trace("\nFailed to call CloseHandle API, error code = %u\n",
- GetLastError());
-
- err = VirtualFree(lpProcessAddress, REGIONSIZE, MEM_DECOMMIT);
- if(0 == err)
- {
- Trace("\nFailed to call VirtualFree API, error code=%u\n",
- GetLastError());
- }
-
- Fail("");
- }
-
- /*decommit the specified region*/
- err = VirtualFree(lpProcessAddress, REGIONSIZE, MEM_DECOMMIT);
- if(0 == err)
- {
- Fail("\nFailed to call VirtualFree API, error code=%u\n",
- GetLastError());
- }
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test1/testinfo.dat b/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test1/testinfo.dat
deleted file mode 100644
index c56920d206..0000000000
--- a/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test1/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = Filemapping_memmgt
-Function = ReadProcessMemory
-Name = Positive test for ReadProcessMemory API to read memory contents
-TYPE = DEFAULT
-EXE1 = readprocessmemory
-Description
-=Test the ReadProcessMemory to read the memory contents
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test2/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test2/CMakeLists.txt
deleted file mode 100644
index 9e0de95a0a..0000000000
--- a/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test2/CMakeLists.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(TESTSOURCES
- test2.c
-)
-
-add_executable(paltest_readprocessmemory_test2
- ${TESTSOURCES}
-)
-
-add_dependencies(paltest_readprocessmemory_test2 coreclrpal)
-
-target_link_libraries(paltest_readprocessmemory_test2
- pthread
- m
- coreclrpal
-)
-
-
-set(HELPERSOURCES
- helper.c
-)
-
-add_executable(paltest_readprocessmemory_test2_helper
- ${HELPERSOURCES}
-)
-
-add_dependencies(paltest_readprocessmemory_test2_helper coreclrpal)
-
-target_link_libraries(paltest_readprocessmemory_test2_helper
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test2/commonconsts.h b/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test2/commonconsts.h
deleted file mode 100644
index 433d820f0f..0000000000
--- a/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test2/commonconsts.h
+++ /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.
-
-/*=============================================================
-**
-** Source: commonconsts.h
-**
-**
-**============================================================*/
-
-#ifndef _COMMONCONSTS_H_
-#define _COMMONCONSTS_H_
-
-#include <pal.h>
-#define REGIONSIZE 1024
-
-const int TIMEOUT = 40000;
-
-const WCHAR szcToHelperEvName[] = { 'T', 'o', '\0' };
-const WCHAR szcFromHelperEvName[] = { 'F', 'r', 'o', 'm', '\0' };
-
-const char initialValue = '-';
-const char nextValue = '|';
-const char guardValue = '*';
-const char *commsFileName = "AddrNLen.dat";
-
-
-/* PEDANTIC and PEDANTIC0 is a helper macro that just grumps about any
- * zero return codes in a generic way. with little typing */
-#define PEDANTIC(function, parameters) \
-{ \
- if (! (function parameters) ) \
- { \
- Trace("%s: NonFatal failure of %s%s for reasons %u and %u\n", \
- __FILE__, #function, #parameters, GetLastError(), errno); \
- } \
-}
-#define PEDANTIC1(function, parameters) \
-{ \
- if ( (function parameters) ) \
- { \
- Trace("%s: NonFatal failure of %s%s for reasons %u and %u\n", \
- __FILE__, #function, #parameters, GetLastError(), errno); \
- } \
-}
-
-#endif
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test2/helper.c b/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test2/helper.c
deleted file mode 100644
index 59e882fc1f..0000000000
--- a/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test2/helper.c
+++ /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.
-
-/*=============================================================
-**
-** Source: helper.c
-**
-** Purpose: This helper process sets up a several blocks of memory,
-** then uses a file to tell its parent process where that memory is
-** So it can do a WriteProcessMemory on it. When the parent process is done
-** we check here that it was written properly.
-**
-**
-**============================================================*/
-
-#include "commonconsts.h"
-
-#include <palsuite.h>
-
-#if defined(BIT64) && defined(PLATFORM_UNIX)
-#define LLFORMAT "%I64u"
-#else
-#define LLFORMAT "%u"
-#endif
-
-struct allhandles_t
-{
- HANDLE hEvToHelper;
- HANDLE hEvFromHelper;
- char *valuesFileName;
-};
-
-
-/* function: wpmDoIt
- *
- * This is a general WriteProcessMemory testing function that sets up
- * the RAM pointed to and tells the companion process on the other end
- * of the handles in 'Comms' to attempt to alter 'lenDest' bytes at
- * '*pDest'.
- *
- * '*pBuffer'[0..'lenBuffer'] is expected to be a guard region
- * surrounding the '*pDest'[0..'lenDest'] region so that this function
- * can verify that only the proper bytes were altered.
- */
-
-int wpmDoIt(struct allhandles_t Comms,
- char * pBuffer, unsigned int lenBuffer,
- char * pDest, unsigned int lenDest,
- const char* storageDescription)
-{
- char *pCurr;
- FILE *commsFile;
- DWORD dwRet;
-
- if (pBuffer > pDest || lenDest > lenBuffer)
- {
- Trace("WriteProcessMemory::DoIt() test implementation: "
- "(pBuffer > pDest || lenDest > lenBuffer)\n");
- return FALSE;
- }
-
- /* set up the storage */
- memset(pBuffer, guardValue, lenBuffer);
- memset(pDest, initialValue, lenDest);
-
- /* tell the parent what RAM to adjust */
- if(!(commsFile = fopen(Comms.valuesFileName, "w")))
- {
- Trace("WriteProcessMemory: fopen of '%S' failed (%u). \n",
- Comms.valuesFileName, GetLastError());
- return FALSE;
- }
- if (!fprintf(commsFile, LLFORMAT " " LLFORMAT " '%s'\n",
- pDest, lenDest, storageDescription))
- {
- Trace("WriteProcessMemory: fprintf to '%S' failed (%u). \n",
- Comms.valuesFileName, GetLastError());
- return FALSE;
- }
- PEDANTIC1(fclose, (commsFile));
-
- /* Tell the parent the data is ready for it to adjust */
- PEDANTIC(ResetEvent, (Comms.hEvToHelper));
- PEDANTIC(SetEvent, (Comms.hEvFromHelper));
-
- dwRet = WaitForSingleObject(Comms.hEvToHelper, TIMEOUT); /* parent is done */
- if (dwRet != WAIT_OBJECT_0)
- {
- Trace("helper WaitForSingleObjectTest: WaitForSingleObject "
- "failed (%u)\n", GetLastError());
- return FALSE;
- }
-
- /* check the stuff that SHOULD have changed */
- for (pCurr = pDest; pCurr < (pDest + lenDest); pCurr++)
- {
- if ( *pCurr != nextValue)
- {
- Trace("When testing '%s': alteration test failed "
- "at " LLFORMAT " offset " LLFORMAT " Found '%c' instead of '%c'\n.",
- storageDescription, pDest, pCurr - pDest, *pCurr, nextValue);
- Trace(" 'Altered' string: '%.*s'\n",lenBuffer, pBuffer);
- return FALSE;
- }
- }
- /* check the stuff that should NOT have changed */
- for (pCurr = pBuffer; pCurr < pDest; pCurr++ )
- {
- if ( *pCurr != guardValue)
- {
- Trace("When testing '%s': leading guard zone test failed "
- "at " LLFORMAT " offset " LLFORMAT ". Found '%c' instead of '%c'\n.",
- storageDescription, pDest, pCurr - pBuffer, *pCurr, guardValue);
- Trace(" 'Altered' string: '%.*s'\n",lenBuffer, pBuffer);
- return FALSE;
- }
- }
- for (pCurr = pDest + lenDest; pCurr < (pBuffer + lenBuffer); pCurr++ )
- {
- if ( *pCurr != guardValue)
- {
- Trace("When testing '%s': trailing guard zone test failed "
- "at " LLFORMAT " offset " LLFORMAT ". Found '%c' instead of '%c'\n.",
- storageDescription, pDest + lenDest, pCurr - pBuffer, *pCurr, guardValue);
- Trace(" 'Altered' string: '%.*s'\n",lenBuffer, pBuffer);
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-int __cdecl main(int argc, char *argv[])
-{
-
- BOOL success = TRUE; /* assume success */
- struct allhandles_t Comms = {0,0,0} ;
-
- /* variables to track storage to alter */
- char *pTarget = NULL;
- unsigned int sizeTarget;
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- /* hook up with the events created by the parent */
- Comms.hEvToHelper = OpenEventW(EVENT_ALL_ACCESS, 0, szcToHelperEvName);
- if (!Comms.hEvToHelper)
- {
- Fail("WriteProcessMemory: OpenEvent of '%S' failed (%u). "
- "(the event should already exist!)\n",
- szcToHelperEvName, GetLastError());
- }
- Comms.hEvFromHelper = OpenEventW(EVENT_ALL_ACCESS, 0, szcFromHelperEvName);
- if (!Comms.hEvToHelper)
- {
- Trace("WriteProcessMemory: OpenEvent of '%S' failed (%u). "
- "(the event should already exist!)\n",
- szcFromHelperEvName, GetLastError());
- success = FALSE;
- goto EXIT;
- }
- Comms.valuesFileName = argv[1];
-
- {
- char autoAllocatedOnStack[51];
-
- /* Get the parent process to write to the local stack */
- success &= wpmDoIt(Comms, autoAllocatedOnStack,
- sizeof(autoAllocatedOnStack),
- autoAllocatedOnStack + sizeof(int),
- sizeof(autoAllocatedOnStack) - 2 * sizeof(int),
- "const size array on stack with int sized guards");
- }
-
- /* Get the parent process to write to stuff on the heap */
- sizeTarget = 2 * sizeof(int) + 23 ; /* 23 is just a random prime > 16 */
- if (!(pTarget = malloc(sizeTarget)))
- {
- Trace("WriteProcessMemory helper: unable to allocate '%s'->%d bytes of memory"
- "(%u).\n",
- argv[3], sizeTarget, GetLastError());
- success = FALSE;
- goto EXIT;
-
- }
- success &= wpmDoIt(Comms, pTarget, sizeTarget,
- pTarget + sizeof(int),
- sizeTarget - 2 * sizeof(int),
- "array on heap with int sized guards");
-
- /* just to be nice try something 16 - 2 * sizeof(int) bytes long */
- {
- char autoAllocatedOnStack[16];
-
- /* Get the parent process to write to the local stack */
- success &= wpmDoIt(Comms, autoAllocatedOnStack,
- sizeof(autoAllocatedOnStack),
- autoAllocatedOnStack + sizeof(int),
- sizeof(autoAllocatedOnStack) - 2 * sizeof(int),
- "another 16 byte array on stack with int sized guards inside");
- }
-
- /* NOTE: Don't try 0 bytes long. Win32 WriteProcessMemory claims
- * it writes 8 bytes in that case! */
-
- /* and 1 byte long... */
- {
- char autoAllocatedOnStack[1+ 2 * sizeof(int)];
-
- /* Get the parent process to write to the local stack */
- success &= wpmDoIt(Comms, autoAllocatedOnStack,
- sizeof(autoAllocatedOnStack),
- autoAllocatedOnStack + sizeof(int),
- 1,
- "no bytes with int sized guards outside on stack");
- }
-
-
-EXIT:
- /* Tell the parent that we are done */
- if (!DeleteFile(Comms.valuesFileName))
- {
- Trace("helper: DeleteFile failed so parent (test1) is unlikely "
- "to exit cleanly\n");
- }
- PEDANTIC(ResetEvent, (Comms.hEvToHelper));
- if (!SetEvent(Comms.hEvFromHelper))
- {
- Trace("helper: SetEvent failed so parent (test1) is unlikely "
- "to exit cleanly\n");
- }
-
- free(pTarget);
- PEDANTIC(CloseHandle, (Comms.hEvToHelper));
- PEDANTIC(CloseHandle, (Comms.hEvFromHelper));
-
- if (!success)
- {
- Fail("");
- }
-
- PAL_Terminate();
-
- return success ? PASS : FAIL;
-}
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test2/test2.c b/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test2/test2.c
deleted file mode 100644
index eda40599ce..0000000000
--- a/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test2/test2.c
+++ /dev/null
@@ -1,258 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: test2.c
-**
-** Purpose: Create a child process and some events for communications with it.
-** When the child gets back to us with a memory location and a length,
-** Call WriteProcessMemory on this location and check to see that it
-** writes successfully. Then call ReadProcessMemory to check if the
-** contents read are same as those written
-**
-**
-**============================================================*/
-
-#define UNICODE
-
-#include "commonconsts.h"
-
-#include <palsuite.h>
-
-#if defined(BIT64) && defined(PLATFORM_UNIX)
-#define LLFORMAT "%I64u"
-#else
-#define LLFORMAT "%u"
-#endif
-
-int __cdecl main(int argc, char *argv[])
-{
-
- PROCESS_INFORMATION pi;
- STARTUPINFO si;
- HANDLE hEvToHelper;
- HANDLE hEvFromHelper;
- DWORD dwExitCode;
-
- DWORD dwRet;
- char cmdComposeBuf[MAX_PATH];
- PWCHAR uniString;
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- /* Create the signals we need for cross process communication */
- hEvToHelper = CreateEvent(NULL, TRUE, FALSE, szcToHelperEvName);
- if (!hEvToHelper)
- {
- Fail("WriteProcessMemory: CreateEvent of '%S' failed. "
- "GetLastError() returned %d.\n", szcToHelperEvName,
- GetLastError());
- }
- if (GetLastError() == ERROR_ALREADY_EXISTS)
- {
- Fail("WriteProcessMemory: CreateEvent of '%S' failed. "
- "(already exists!)\n", szcToHelperEvName);
- }
- hEvFromHelper = CreateEvent(NULL, TRUE, FALSE, szcFromHelperEvName);
- if (!hEvToHelper)
- {
- Fail("WriteProcessMemory: CreateEvent of '%S' failed. "
- "GetLastError() returned %d.\n", szcFromHelperEvName,
- GetLastError());
- }
- if (GetLastError() == ERROR_ALREADY_EXISTS)
- {
- Fail("WriteProcessMemory: CreateEvent of '%S' failed. "
- "(already exists!)\n", szcFromHelperEvName);
- }
- ResetEvent(hEvFromHelper);
- ResetEvent(hEvToHelper);
-
- if (!sprintf(cmdComposeBuf, "helper %s", commsFileName))
- {
- Fail("Could not convert command line\n");
- }
- uniString = convert(cmdComposeBuf);
-
- ZeroMemory( &si, sizeof(si) );
- si.cb = sizeof(si);
- ZeroMemory( &pi, sizeof(pi) );
-
- /* Create a new process. This is the process that will ask for
- * memory munging */
- if(!CreateProcess( NULL, uniString, NULL, NULL,
- FALSE, 0, NULL, NULL, &si, &pi))
- {
- Trace("ERROR: CreateProcess failed to load executable '%S'. "
- "GetLastError() returned %u.\n",
- uniString, GetLastError());
- free(uniString);
- Fail("");
- }
- free(uniString);
-
-
- while(1)
- {
- FILE *commsFile;
- char* pSrcMemory;
- char* pDestMemory;
- SIZE_T Count;
- SIZE_T wpmCount;
- char incomingCMDBuffer[MAX_PATH + 1];
-
- int err;
- HANDLE readProcessHandle;
- DWORD readProcessID;
- char readProcessBuffer[REGIONSIZE]; // size 1024
- BOOL bResult;
- size_t size = 0;
-
- readProcessID = pi.dwProcessId;
-
- /* wait until the helper tells us that it has given us
- * something to do */
- dwRet = WaitForSingleObject(hEvFromHelper, TIMEOUT);
- if (dwRet != WAIT_OBJECT_0)
- {
- Trace("test1 WaitForSingleObjectTest: WaitForSingleObject "
- "failed (%u)\n", GetLastError());
- break; /* no more work incoming */
- }
-
- /* get the parameters to test WriteProcessMemory with */
- if (!(commsFile = fopen(commsFileName, "r")))
- {
- /* no file means there is no more work */
- break;
- }
- if ( NULL == fgets(incomingCMDBuffer, MAX_PATH, commsFile))
- {
- Fail ("unable to read from communication file %s "
- "for reasons %u & %u\n",
- errno, GetLastError());
- }
- PEDANTIC1(fclose,(commsFile));
- sscanf(incomingCMDBuffer, LLFORMAT " " LLFORMAT, &pDestMemory, &Count);
- if (argc > 1)
- {
- Trace("Preparing to write to " LLFORMAT " bytes @ " LLFORMAT "('%s')\n",
- Count, pDestMemory, incomingCMDBuffer);
- }
-
- /* compose some data to write to the client process */
- if (!(pSrcMemory = malloc(Count)))
- {
- Trace("could not dynamically allocate memory to copy from "
- "for reasons %u & %u\n",
- errno, GetLastError());
- goto doneIteration;
- }
- memset(pSrcMemory, nextValue, Count);
- Trace("Preparing to write to " LLFORMAT " bytes @ " LLFORMAT " ('%s')[%u]\n",
- Count, pDestMemory, incomingCMDBuffer, pSrcMemory);
-
- /* do the work */
- dwRet = WriteProcessMemory(pi.hProcess,
- pDestMemory,
- pSrcMemory,
- Count,
- &wpmCount);
-
- if (!dwRet)
- {
- Trace("%s: Problem: on a write to "LLFORMAT " bytes @ " LLFORMAT " ('%s')\n",
- argv[0], Count, pDestMemory, incomingCMDBuffer);
- Trace("test1 WriteProcessMemory returned a (!=0) (GLE=%u)\n",
- GetLastError());
- }
- if(Count != wpmCount)
- {
- Trace("%s: Problem: on a write to " LLFORMAT " bytes @ " LLFORMAT " ('%s')\n",
- argv[0], Count, pDestMemory, incomingCMDBuffer);
- Trace("The number of bytes written should have been "
- LLFORMAT ", but was reported as " LLFORMAT " \n", Count, wpmCount);
- }
-
- readProcessHandle = OpenProcess(
- PROCESS_VM_READ,
- FALSE,
- readProcessID);
-
- if(NULL == readProcessHandle)
- {
- Fail("\nFailed to call OpenProcess API to retrieve "
- "current process handle error code=%u\n",
- GetLastError());
- }
-
- /*zero the memory*/
- memset(readProcessBuffer, 0, size);
-
- /*retrieve the memory contents*/
- bResult = ReadProcessMemory(
- readProcessHandle, /*current process handle*/
- pDestMemory, /*base of memory area*/
- (LPVOID)readProcessBuffer,
- Count, /*buffer length in bytes*/
- &size);
-
-
- if( !bResult || (Count != size) )
- {
- Trace("\nFailed to call ReadProcessMemory API "
- "to retrieve the memory contents, error code=%u; Bresult[%u] Count[" LLFORMAT "], Size[%d]\n",
- GetLastError(), bResult, Count, size);
-
- err = CloseHandle(readProcessHandle);
-
- if(0 == err)
- {
- Trace("\nFailed to call CloseHandle API, error code=%u\n",
- GetLastError());
- }
- dwExitCode = FAIL;
- }
-
- if( !memcmp (pDestMemory, readProcessBuffer, Count ) )
- {
- Trace("Difference in memory contents, expected [%s], but received [%s]\n", pDestMemory, readProcessBuffer);
- dwExitCode = FAIL;
- }
-
- Trace("ReadProcessBuffer contains [%s]\n", readProcessBuffer);
- err = CloseHandle(readProcessHandle);
-
- free(pSrcMemory);
-
- doneIteration:
- PEDANTIC(ResetEvent, (hEvFromHelper));
- PEDANTIC(SetEvent, (hEvToHelper));
- }
-
- /* wait for the child process to complete */
- WaitForSingleObject ( pi.hProcess, TIMEOUT );
- /* this may return a failure code on a success path */
-
- /* check the exit code from the process */
- if( ! GetExitCodeProcess( pi.hProcess, &dwExitCode ) )
- {
- Trace( "GetExitCodeProcess call failed with error code %u\n",
- GetLastError() );
- dwExitCode = FAIL;
- }
-
-
- PEDANTIC(CloseHandle, (hEvToHelper));
- PEDANTIC(CloseHandle, (hEvFromHelper));
- PEDANTIC(CloseHandle, (pi.hThread));
- PEDANTIC(CloseHandle, (pi.hProcess));
-
- PAL_TerminateEx(dwExitCode);
- return dwExitCode;
-}
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test2/testinfo.dat b/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test2/testinfo.dat
deleted file mode 100644
index 58a9935a08..0000000000
--- a/src/pal/tests/palsuite/filemapping_memmgt/ReadProcessMemory/test2/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = Debug
-Function = ReadProcessMemory
-Name = Check that writing/reading text to/from process memory succeeds.
-TYPE = DEFAULT
-EXE1 = test2
-EXE2 = helper
-Description
-= Create a child process and attempt to write to its memory
-= at the places and lengths it specifies via a data file.
-= the child verifies that all the specified memory was altered
-= with no overruns. Parent then tries to read memory from child
-= and does memory compare to ensure it read memory contents
-= correctly
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test1/CMakeLists.txt
index 987c413d03..8aa1c80368 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_rtlmovememory_test1
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test1/test1.c b/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test1/test1.cpp
index 7fc56510d8..7fc56510d8 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test1/test1.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test3/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test3/CMakeLists.txt
index 14098a8dc1..d292cff494 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_rtlmovememory_test3
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test3/test3.c b/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test3/test3.cpp
index 279c0c1199..279c0c1199 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test3/test3.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test4/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test4/CMakeLists.txt
index 00aec7e8f7..e8aeb0c0b3 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_rtlmovememory_test4
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test4/test4.c b/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test4/test4.cpp
index b6e1ecd6f7..b6e1ecd6f7 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test4/test4.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test5/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test5/CMakeLists.txt
index f2de78216e..7f4986eb27 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_rtlmovememory_test5
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test5/test5.c b/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test5/test5.cpp
index affcb0abc9..affcb0abc9 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test5/test5.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/RtlMoveMemory/test5/test5.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test1/CMakeLists.txt
index 0e6d6fef4c..8ed46bae43 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(TESTSOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_unlockfile_test1
@@ -20,7 +20,7 @@ target_link_libraries(paltest_unlockfile_test1
set(HELPERSOURCES
- helper.c
+ helper.cpp
)
add_executable(paltest_unlockfile_test1_helper
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test1/helper.c b/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test1/helper.cpp
index c2ef5a6736..c2ef5a6736 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test1/helper.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test1/helper.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test1/test1.c b/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test1/test1.cpp
index 14634c7f7a..14634c7f7a 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test1/test1.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test2/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test2/CMakeLists.txt
index 142b2763cb..3033876f80 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_unlockfile_test2
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test2/test2.c b/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test2/test2.cpp
index 22c2cce2fb..22c2cce2fb 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test2/test2.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test3/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test3/CMakeLists.txt
index b4ec37c88c..d46d7db344 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(TESTSOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_unlockfile_test3
@@ -20,7 +20,7 @@ target_link_libraries(paltest_unlockfile_test3
set(HELPERSOURCES
- helper.c
+ helper.cpp
)
add_executable(paltest_unlockfile_test3_helper
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test3/helper.c b/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test3/helper.cpp
index 650abf49ad..650abf49ad 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test3/helper.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test3/helper.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test3/test3.c b/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test3/test3.cpp
index cf27aba0a3..cf27aba0a3 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test3/test3.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test4/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test4/CMakeLists.txt
index d6bee307c2..635a1ca07c 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_unlockfile_test4
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test4/test4.c b/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test4/test4.cpp
index 55abcd24bc..55abcd24bc 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test4/test4.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/UnlockFile/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/UnmapViewOfFile/test1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/UnmapViewOfFile/test1/CMakeLists.txt
index 5ebda77ba6..1b8062ff9c 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/UnmapViewOfFile/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/UnmapViewOfFile/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- UnmapViewOfFile.c
+ UnmapViewOfFile.cpp
)
add_executable(paltest_unmapviewoffile_test1
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/UnmapViewOfFile/test1/UnmapViewOfFile.c b/src/pal/tests/palsuite/filemapping_memmgt/UnmapViewOfFile/test1/UnmapViewOfFile.cpp
index a970ccc3b5..a970ccc3b5 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/UnmapViewOfFile/test1/UnmapViewOfFile.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/UnmapViewOfFile/test1/UnmapViewOfFile.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/UnmapViewOfFile/test2/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/UnmapViewOfFile/test2/CMakeLists.txt
index 5c12cf9825..750e446a17 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/UnmapViewOfFile/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/UnmapViewOfFile/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- unmapviewoffile.c
+ unmapviewoffile.cpp
)
add_executable(paltest_unmapviewoffile_test2
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/UnmapViewOfFile/test2/unmapviewoffile.c b/src/pal/tests/palsuite/filemapping_memmgt/UnmapViewOfFile/test2/unmapviewoffile.cpp
index 2ca185d234..2ca185d234 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/UnmapViewOfFile/test2/unmapviewoffile.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/UnmapViewOfFile/test2/unmapviewoffile.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/CMakeLists.txt
index eafaa66856..b2cafde93a 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/CMakeLists.txt
@@ -14,6 +14,7 @@ add_subdirectory(test19)
add_subdirectory(test2)
add_subdirectory(test20)
add_subdirectory(test21)
+add_subdirectory(test22)
add_subdirectory(test3)
add_subdirectory(test4)
add_subdirectory(test5)
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test1/CMakeLists.txt
index 90ba41bd79..f8c0645a4b 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualAlloc.c
+ VirtualAlloc.cpp
)
add_executable(paltest_virtualalloc_test1
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test1/VirtualAlloc.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test1/VirtualAlloc.cpp
index 26ee942ba1..26ee942ba1 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test1/VirtualAlloc.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test1/VirtualAlloc.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test10/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test10/CMakeLists.txt
index 51b0e1d92e..1b66f0d7cb 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test10/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test10/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualAlloc.c
+ VirtualAlloc.cpp
)
add_executable(paltest_virtualalloc_test10
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test10/VirtualAlloc.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test10/VirtualAlloc.cpp
index ac06b9b5c8..ac06b9b5c8 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test10/VirtualAlloc.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test10/VirtualAlloc.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test11/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test11/CMakeLists.txt
index adff47087b..95e1a06f55 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test11/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test11/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualAlloc.c
+ VirtualAlloc.cpp
)
add_executable(paltest_virtualalloc_test11
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test11/VirtualAlloc.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test11/VirtualAlloc.cpp
index a3df39b634..a3df39b634 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test11/VirtualAlloc.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test11/VirtualAlloc.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test12/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test12/CMakeLists.txt
index 26f303573e..7564f960fe 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test12/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test12/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualAlloc.c
+ VirtualAlloc.cpp
)
add_executable(paltest_virtualalloc_test12
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test12/VirtualAlloc.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test12/VirtualAlloc.cpp
index 8b3508635f..8b3508635f 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test12/VirtualAlloc.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test12/VirtualAlloc.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test13/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test13/CMakeLists.txt
index f85cbdc694..a49dcfc81d 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test13/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test13/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualAlloc.c
+ VirtualAlloc.cpp
)
add_executable(paltest_virtualalloc_test13
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test13/VirtualAlloc.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test13/VirtualAlloc.cpp
index d2109c0339..d2109c0339 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test13/VirtualAlloc.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test13/VirtualAlloc.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test14/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test14/CMakeLists.txt
index 41ed0ca208..180a48e74d 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test14/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test14/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualAlloc.c
+ VirtualAlloc.cpp
)
add_executable(paltest_virtualalloc_test14
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test14/VirtualAlloc.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test14/VirtualAlloc.cpp
index 49bd21875e..49bd21875e 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test14/VirtualAlloc.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test14/VirtualAlloc.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test15/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test15/CMakeLists.txt
index 87b29108b2..4ba219472e 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test15/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test15/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualAlloc.c
+ VirtualAlloc.cpp
)
add_executable(paltest_virtualalloc_test15
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test15/VirtualAlloc.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test15/VirtualAlloc.cpp
index 3cf1502f26..3cf1502f26 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test15/VirtualAlloc.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test15/VirtualAlloc.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test16/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test16/CMakeLists.txt
index 90e3f3bdb2..1c5f63dce5 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test16/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test16/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualAlloc.c
+ VirtualAlloc.cpp
)
add_executable(paltest_virtualalloc_test16
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test16/VirtualAlloc.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test16/VirtualAlloc.cpp
index ce61b9aa39..ce61b9aa39 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test16/VirtualAlloc.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test16/VirtualAlloc.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test17/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test17/CMakeLists.txt
index 461b48ccc0..6523bb9292 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test17/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test17/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualAlloc.c
+ VirtualAlloc.cpp
)
add_executable(paltest_virtualalloc_test17
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test17/VirtualAlloc.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test17/VirtualAlloc.cpp
index eb609f14e4..eb609f14e4 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test17/VirtualAlloc.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test17/VirtualAlloc.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test18/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test18/CMakeLists.txt
index 69823be14b..3fe65b4ac8 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test18/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test18/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualAlloc.c
+ VirtualAlloc.cpp
)
add_executable(paltest_virtualalloc_test18
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test18/VirtualAlloc.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test18/VirtualAlloc.cpp
index e46da851db..e46da851db 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test18/VirtualAlloc.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test18/VirtualAlloc.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test19/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test19/CMakeLists.txt
index fa65b4fa46..1795b8ba54 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test19/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test19/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualAlloc.c
+ VirtualAlloc.cpp
)
add_executable(paltest_virtualalloc_test19
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test19/VirtualAlloc.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test19/VirtualAlloc.cpp
index 5cbe48b15e..5cbe48b15e 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test19/VirtualAlloc.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test19/VirtualAlloc.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test2/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test2/CMakeLists.txt
index 1753b1edc5..20da178bfc 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualAlloc.c
+ VirtualAlloc.cpp
)
add_executable(paltest_virtualalloc_test2
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test2/VirtualAlloc.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test2/VirtualAlloc.cpp
index 99cf76a523..99cf76a523 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test2/VirtualAlloc.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test2/VirtualAlloc.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test20/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test20/CMakeLists.txt
index 2c55071149..5c23fe2b0d 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test20/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test20/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- virtualalloc.c
+ virtualalloc.cpp
)
add_executable(paltest_virtualalloc_test20
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test20/virtualalloc.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test20/virtualalloc.cpp
index 7aec3c7f55..7aec3c7f55 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test20/virtualalloc.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test20/virtualalloc.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test21/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test21/CMakeLists.txt
index f97c32af75..96a3144e8a 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test21/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test21/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- virtualalloc.c
+ virtualalloc.cpp
)
add_executable(paltest_virtualalloc_test21
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test21/virtualalloc.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test21/virtualalloc.cpp
index 065a2ff5c8..065a2ff5c8 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test21/virtualalloc.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test21/virtualalloc.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test22/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test22/CMakeLists.txt
new file mode 100644
index 0000000000..cdad2ca19d
--- /dev/null
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test22/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ VirtualAlloc.cpp
+)
+
+add_executable(paltest_virtualalloc_test22
+ ${SOURCES}
+)
+
+add_dependencies(paltest_virtualalloc_test22 coreclrpal)
+
+target_link_libraries(paltest_virtualalloc_test22
+ pthread
+ m
+ coreclrpal
+)
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test22/VirtualAlloc.cpp b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test22/VirtualAlloc.cpp
new file mode 100644
index 0000000000..489926f48d
--- /dev/null
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test22/VirtualAlloc.cpp
@@ -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.
+
+/*=============================================================
+**
+** Source: virtualalloc.c
+**
+** Purpose: Negative test the VirtualAlloc API.
+** Call VirtualAlloc with MEM_COMMIT allocation type
+** and PAGE_READWRITE access protection
+
+**
+**============================================================*/
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+ int err;
+ LPVOID lpVirtualAddress;
+
+
+ //Initialize the PAL environment
+ err = PAL_Initialize(argc, argv);
+ if(0 != err)
+ {
+ ExitProcess(FAIL);
+ }
+
+ //Allocate the physical storage in memory or in the paging file on disk
+ lpVirtualAddress = VirtualAlloc(NULL,//system determine where to allocate the region
+ (SIZE_T)(2147483647000000), //specify the size to be int32.maxvalue mega bytes
+ MEM_COMMIT, //allocation type
+ PAGE_READWRITE); //access protection
+ if(NULL != lpVirtualAddress)
+ {
+ Fail("\nWelcome to the Future, where Unlimited Memory is Available, disregard this test!\n");
+ }
+
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test22/testinfo.dat b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test22/testinfo.dat
new file mode 100644
index 0000000000..3d5962c7af
--- /dev/null
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test22/testinfo.dat
@@ -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.
+
+Version = 1.0
+Section = Filemapping_memmgt
+Function = VirtualAlloc
+Name = Negative test for VirtualAlloc API
+TYPE = DEFAULT
+EXE1 = virtualalloc
+Description
+=Test the VirtualAlloc with MEM_COMMIT allocation type
+=and PAGE_READWRITEaccess protection
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test3/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test3/CMakeLists.txt
index 035594bd79..77822f7862 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualAlloc.c
+ VirtualAlloc.cpp
)
add_executable(paltest_virtualalloc_test3
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test3/VirtualAlloc.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test3/VirtualAlloc.cpp
index 5c57ec337f..5c57ec337f 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test3/VirtualAlloc.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test3/VirtualAlloc.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test4/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test4/CMakeLists.txt
index 5ce80bf52f..0e2c448659 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualAlloc.c
+ VirtualAlloc.cpp
)
add_executable(paltest_virtualalloc_test4
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test4/VirtualAlloc.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test4/VirtualAlloc.cpp
index c134a14eb1..c134a14eb1 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test4/VirtualAlloc.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test4/VirtualAlloc.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test5/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test5/CMakeLists.txt
index 138d9c9727..247053ff0f 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualAlloc.c
+ VirtualAlloc.cpp
)
add_executable(paltest_virtualalloc_test5
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test5/VirtualAlloc.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test5/VirtualAlloc.cpp
index 8c4f9dcdb6..8c4f9dcdb6 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test5/VirtualAlloc.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test5/VirtualAlloc.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test6/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test6/CMakeLists.txt
index c61add9db4..d19391d294 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualAlloc.c
+ VirtualAlloc.cpp
)
add_executable(paltest_virtualalloc_test6
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test6/VirtualAlloc.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test6/VirtualAlloc.cpp
index e9c33d86df..e9c33d86df 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test6/VirtualAlloc.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test6/VirtualAlloc.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test7/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test7/CMakeLists.txt
index b5452a0c48..8c01e041de 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test7/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test7/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualAlloc.c
+ VirtualAlloc.cpp
)
add_executable(paltest_virtualalloc_test7
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test7/VirtualAlloc.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test7/VirtualAlloc.cpp
index bee2735c9f..bee2735c9f 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test7/VirtualAlloc.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test7/VirtualAlloc.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test8/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test8/CMakeLists.txt
index 584a0c505a..db2a7447be 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test8/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test8/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualAlloc.c
+ VirtualAlloc.cpp
)
add_executable(paltest_virtualalloc_test8
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test8/VirtualAlloc.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test8/VirtualAlloc.cpp
index d548e0c8db..d548e0c8db 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test8/VirtualAlloc.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test8/VirtualAlloc.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test9/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test9/CMakeLists.txt
index aee950b2e4..254fc6fcf2 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test9/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test9/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualAlloc.c
+ VirtualAlloc.cpp
)
add_executable(paltest_virtualalloc_test9
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test9/VirtualAlloc.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test9/VirtualAlloc.cpp
index 2711addacc..2711addacc 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test9/VirtualAlloc.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualAlloc/test9/VirtualAlloc.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test1/CMakeLists.txt
index 1914f76fe6..d2319506f2 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualFree.c
+ VirtualFree.cpp
)
add_executable(paltest_virtualfree_test1
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test1/VirtualFree.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test1/VirtualFree.cpp
index 0f4f144aa5..0f4f144aa5 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test1/VirtualFree.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test1/VirtualFree.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test2/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test2/CMakeLists.txt
index a288b37154..9a3bc7ac61 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualFree.c
+ VirtualFree.cpp
)
add_executable(paltest_virtualfree_test2
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test2/VirtualFree.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test2/VirtualFree.cpp
index 70064a3bf9..70064a3bf9 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test2/VirtualFree.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test2/VirtualFree.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test3/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test3/CMakeLists.txt
index 993189c1aa..8484c0fd94 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualFree.c
+ VirtualFree.cpp
)
add_executable(paltest_virtualfree_test3
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test3/VirtualFree.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test3/VirtualFree.cpp
index 27f1936be7..27f1936be7 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test3/VirtualFree.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualFree/test3/VirtualFree.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test1/CMakeLists.txt
index 214cf460ae..4283398a6f 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualProtect.c
+ VirtualProtect.cpp
)
add_executable(paltest_virtualprotect_test1
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test1/VirtualProtect.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test1/VirtualProtect.cpp
index 1a28bd156d..1a28bd156d 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test1/VirtualProtect.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test1/VirtualProtect.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test2/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test2/CMakeLists.txt
index 27f43477ea..aed68fd27f 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualProtect.c
+ VirtualProtect.cpp
)
add_executable(paltest_virtualprotect_test2
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test2/VirtualProtect.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test2/VirtualProtect.cpp
index 64a08d7885..64a08d7885 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test2/VirtualProtect.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test2/VirtualProtect.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test3/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test3/CMakeLists.txt
index 994d4e2f41..70728592ad 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualProtect.c
+ VirtualProtect.cpp
)
add_executable(paltest_virtualprotect_test3
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test3/VirtualProtect.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test3/VirtualProtect.cpp
index 0f738630ee..0f738630ee 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test3/VirtualProtect.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test3/VirtualProtect.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test4/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test4/CMakeLists.txt
index 2e0fba50bb..5ad64a74eb 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualProtect.c
+ VirtualProtect.cpp
)
add_executable(paltest_virtualprotect_test4
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test4/VirtualProtect.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test4/VirtualProtect.cpp
index 926d501d0d..926d501d0d 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test4/VirtualProtect.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test4/VirtualProtect.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test6/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test6/CMakeLists.txt
index 6d6fd07df8..78932ef453 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualProtect.c
+ VirtualProtect.cpp
)
add_executable(paltest_virtualprotect_test6
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test6/VirtualProtect.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test6/VirtualProtect.cpp
index d60b323ec6..d60b323ec6 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test6/VirtualProtect.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test6/VirtualProtect.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test7/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test7/CMakeLists.txt
index 06af860559..caf5ef91f4 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test7/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test7/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualProtect.c
+ VirtualProtect.cpp
)
add_executable(paltest_virtualprotect_test7
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test7/VirtualProtect.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test7/VirtualProtect.cpp
index edc37711f4..edc37711f4 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test7/VirtualProtect.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualProtect/test7/VirtualProtect.cpp
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualQuery/test1/CMakeLists.txt b/src/pal/tests/palsuite/filemapping_memmgt/VirtualQuery/test1/CMakeLists.txt
index 4f4e4bc5f0..17cbdee4a5 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualQuery/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualQuery/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- VirtualQuery.c
+ VirtualQuery.cpp
)
add_executable(paltest_virtualquery_test1
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/VirtualQuery/test1/VirtualQuery.c b/src/pal/tests/palsuite/filemapping_memmgt/VirtualQuery/test1/VirtualQuery.cpp
index 44216ae563..44216ae563 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/VirtualQuery/test1/VirtualQuery.c
+++ b/src/pal/tests/palsuite/filemapping_memmgt/VirtualQuery/test1/VirtualQuery.cpp
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryA/test1/CMakeLists.txt b/src/pal/tests/palsuite/loader/LoadLibraryA/test1/CMakeLists.txt
index 542f8d3277..62b896df65 100644
--- a/src/pal/tests/palsuite/loader/LoadLibraryA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/loader/LoadLibraryA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- LoadLibraryA.c
+ LoadLibraryA.cpp
)
add_executable(paltest_loadlibrarya_test1
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryA/test1/LoadLibraryA.c b/src/pal/tests/palsuite/loader/LoadLibraryA/test1/LoadLibraryA.cpp
index b4a8de1367..b4a8de1367 100644
--- a/src/pal/tests/palsuite/loader/LoadLibraryA/test1/LoadLibraryA.c
+++ b/src/pal/tests/palsuite/loader/LoadLibraryA/test1/LoadLibraryA.cpp
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryA/test2/CMakeLists.txt b/src/pal/tests/palsuite/loader/LoadLibraryA/test2/CMakeLists.txt
index 63cfb22545..48a4c36cd0 100644
--- a/src/pal/tests/palsuite/loader/LoadLibraryA/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/loader/LoadLibraryA/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- LoadLibraryA.c
+ LoadLibraryA.cpp
)
add_executable(paltest_loadlibrarya_test2
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryA/test2/LoadLibraryA.c b/src/pal/tests/palsuite/loader/LoadLibraryA/test2/LoadLibraryA.cpp
index d7cd9cb875..d7cd9cb875 100644
--- a/src/pal/tests/palsuite/loader/LoadLibraryA/test2/LoadLibraryA.c
+++ b/src/pal/tests/palsuite/loader/LoadLibraryA/test2/LoadLibraryA.cpp
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryA/test2/MyModule.c b/src/pal/tests/palsuite/loader/LoadLibraryA/test2/MyModule.cpp
index 883b3fbc4a..883b3fbc4a 100644
--- a/src/pal/tests/palsuite/loader/LoadLibraryA/test2/MyModule.c
+++ b/src/pal/tests/palsuite/loader/LoadLibraryA/test2/MyModule.cpp
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryA/test3/CMakeLists.txt b/src/pal/tests/palsuite/loader/LoadLibraryA/test3/CMakeLists.txt
index 143d0ec096..ae05b3560d 100644
--- a/src/pal/tests/palsuite/loader/LoadLibraryA/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/loader/LoadLibraryA/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- loadlibrarya.c
+ loadlibrarya.cpp
)
add_executable(paltest_loadlibrarya_test3
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryA/test3/loadlibrarya.c b/src/pal/tests/palsuite/loader/LoadLibraryA/test3/loadlibrarya.cpp
index da38f98d04..da38f98d04 100644
--- a/src/pal/tests/palsuite/loader/LoadLibraryA/test3/loadlibrarya.c
+++ b/src/pal/tests/palsuite/loader/LoadLibraryA/test3/loadlibrarya.cpp
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryA/test5/CMakeLists.txt b/src/pal/tests/palsuite/loader/LoadLibraryA/test5/CMakeLists.txt
index a9d791c916..99915eea2c 100644
--- a/src/pal/tests/palsuite/loader/LoadLibraryA/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/loader/LoadLibraryA/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- loadlibrarya.c
+ loadlibrarya.cpp
)
add_executable(paltest_loadlibrarya_test5
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryA/test5/loadlibrarya.c b/src/pal/tests/palsuite/loader/LoadLibraryA/test5/loadlibrarya.c
deleted file mode 100644
index d1e6b6d1dc..0000000000
--- a/src/pal/tests/palsuite/loader/LoadLibraryA/test5/loadlibrarya.c
+++ /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.
-
-/*=============================================================
-**
-** Source: loadlibrarya.c
-**
-** Purpose: Negative test the LoadLibraryA API.
-** Call LoadLibraryA by passing a module name
-** without extension but with a trailing dot.
-**
-**
-**============================================================*/
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
- HMODULE ModuleHandle;
- char ModuleName[_MAX_FNAME];
- int err;
-
- /* Initialize the PAL environment */
- err = PAL_Initialize(argc, argv);
- if(0 != err)
- {
- return FAIL;
- }
-
- memset(ModuleName, 0, _MAX_FNAME);
-
- /*Module name without extension but with a trailing dot*/
-#if WIN32
- sprintf(ModuleName, "%s", "rotor_pal.");
-#else
- /* Under FreeBSD */
- sprintf(ModuleName, "%s", "librotor_pal.");
-#endif
-
- /* load a module which does not have the file extension,
- * but has a trailing dot
- */
- ModuleHandle = LoadLibraryA(ModuleName);
- if(NULL != ModuleHandle)
- {
- Trace("Failed to call LoadLibraryA API for a negative test "
- "call LoadLibraryA with module name which does not have "
- "extension except a trailing dot, a NULL module handle is"
- "expected, but no NULL module handle is returned, "
- "error code = %u\n", GetLastError());
-
-
- /* decrement the reference count of the loaded dll */
- err = FreeLibrary(ModuleHandle);
- if(0 == err)
- {
- Trace("\nFailed to call FreeLibrary API, "
- "error code = %u\n", GetLastError());
- }
-
- Fail("");
- }
-
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryA/test5/loadlibrarya.cpp b/src/pal/tests/palsuite/loader/LoadLibraryA/test5/loadlibrarya.cpp
new file mode 100644
index 0000000000..ab38d1a632
--- /dev/null
+++ b/src/pal/tests/palsuite/loader/LoadLibraryA/test5/loadlibrarya.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.
+
+/*=============================================================
+**
+** Source: loadlibrarya.c
+**
+** Purpose: Negative test the LoadLibraryA API.
+** Call LoadLibraryA by passing a module name
+** without extension but with a trailing dot.
+**
+**
+**============================================================*/
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+ HMODULE ModuleHandle;
+ char ModuleName[_MAX_FNAME];
+ int err;
+
+ /* Initialize the PAL environment */
+ err = PAL_Initialize(argc, argv);
+ if(0 != err)
+ {
+ return FAIL;
+ }
+
+ memset(ModuleName, 0, _MAX_FNAME);
+
+ /*Module name without extension but with a trailing dot*/
+#if WIN32
+ sprintf_s(ModuleName, _countof(ModuleName), "%s", "rotor_pal.");
+#else
+ /* Under FreeBSD */
+ sprintf_s(ModuleName, _countof(ModuleName), "%s", "librotor_pal.");
+#endif
+
+ /* load a module which does not have the file extension,
+ * but has a trailing dot
+ */
+ ModuleHandle = LoadLibraryA(ModuleName);
+ if(NULL != ModuleHandle)
+ {
+ Trace("Failed to call LoadLibraryA API for a negative test "
+ "call LoadLibraryA with module name which does not have "
+ "extension except a trailing dot, a NULL module handle is"
+ "expected, but no NULL module handle is returned, "
+ "error code = %u\n", GetLastError());
+
+
+ /* decrement the reference count of the loaded dll */
+ err = FreeLibrary(ModuleHandle);
+ if(0 == err)
+ {
+ Trace("\nFailed to call FreeLibrary API, "
+ "error code = %u\n", GetLastError());
+ }
+
+ Fail("");
+ }
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryA/test6/CMakeLists.txt b/src/pal/tests/palsuite/loader/LoadLibraryA/test6/CMakeLists.txt
index bb66adef77..0fac8785a8 100644
--- a/src/pal/tests/palsuite/loader/LoadLibraryA/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/loader/LoadLibraryA/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(TESTSOURCES
- loadlibrarya.c
+ loadlibrarya.cpp
)
add_executable(paltest_loadlibrarya_test6
@@ -20,7 +20,7 @@ target_link_libraries(paltest_loadlibrarya_test6
set(HELPERSOURCES
- dlltest.c
+ dlltest.cpp
)
add_executable(paltest_loadlibrarya_test6_dlltest
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryA/test6/dlltest.c b/src/pal/tests/palsuite/loader/LoadLibraryA/test6/dlltest.cpp
index 72380eebb5..72380eebb5 100644
--- a/src/pal/tests/palsuite/loader/LoadLibraryA/test6/dlltest.c
+++ b/src/pal/tests/palsuite/loader/LoadLibraryA/test6/dlltest.cpp
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryA/test6/loadlibrarya.c b/src/pal/tests/palsuite/loader/LoadLibraryA/test6/loadlibrarya.cpp
index ee825e6439..ee825e6439 100644
--- a/src/pal/tests/palsuite/loader/LoadLibraryA/test6/loadlibrarya.c
+++ b/src/pal/tests/palsuite/loader/LoadLibraryA/test6/loadlibrarya.cpp
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryA/test7/CMakeLists.txt b/src/pal/tests/palsuite/loader/LoadLibraryA/test7/CMakeLists.txt
index 6c0d174600..bb403c6466 100644
--- a/src/pal/tests/palsuite/loader/LoadLibraryA/test7/CMakeLists.txt
+++ b/src/pal/tests/palsuite/loader/LoadLibraryA/test7/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- LoadLibraryA.c
+ LoadLibraryA.cpp
)
add_executable(paltest_loadlibrarya_test7
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryA/test7/LoadLibraryA.c b/src/pal/tests/palsuite/loader/LoadLibraryA/test7/LoadLibraryA.cpp
index 5e6db8bb68..5e6db8bb68 100644
--- a/src/pal/tests/palsuite/loader/LoadLibraryA/test7/LoadLibraryA.c
+++ b/src/pal/tests/palsuite/loader/LoadLibraryA/test7/LoadLibraryA.cpp
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryA/test8/CMakeLists.txt b/src/pal/tests/palsuite/loader/LoadLibraryA/test8/CMakeLists.txt
index b663a7b5bc..9e3449166b 100644
--- a/src/pal/tests/palsuite/loader/LoadLibraryA/test8/CMakeLists.txt
+++ b/src/pal/tests/palsuite/loader/LoadLibraryA/test8/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(TESTSOURCES
- loadlibrarya.c
+ loadlibrarya.cpp
)
add_executable(paltest_loadlibrarya_test8
@@ -20,7 +20,7 @@ target_link_libraries(paltest_loadlibrarya_test8
set(HELPERSOURCES
- dlltest.c
+ dlltest.cpp
)
add_executable(paltest_loadlibrarya_test8_dlltest
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryA/test8/dlltest.c b/src/pal/tests/palsuite/loader/LoadLibraryA/test8/dlltest.cpp
index 72380eebb5..72380eebb5 100644
--- a/src/pal/tests/palsuite/loader/LoadLibraryA/test8/dlltest.c
+++ b/src/pal/tests/palsuite/loader/LoadLibraryA/test8/dlltest.cpp
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryA/test8/loadlibrarya.c b/src/pal/tests/palsuite/loader/LoadLibraryA/test8/loadlibrarya.cpp
index 6556e9c896..6556e9c896 100644
--- a/src/pal/tests/palsuite/loader/LoadLibraryA/test8/loadlibrarya.c
+++ b/src/pal/tests/palsuite/loader/LoadLibraryA/test8/loadlibrarya.cpp
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryW/test1/CMakeLists.txt b/src/pal/tests/palsuite/loader/LoadLibraryW/test1/CMakeLists.txt
index 87038012b7..171d1d59d4 100644
--- a/src/pal/tests/palsuite/loader/LoadLibraryW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/loader/LoadLibraryW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- LoadLibraryW.c
+ LoadLibraryW.cpp
)
add_executable(paltest_loadlibraryw_test1
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryW/test1/LoadLibraryW.c b/src/pal/tests/palsuite/loader/LoadLibraryW/test1/LoadLibraryW.cpp
index 4c1a551de1..4c1a551de1 100644
--- a/src/pal/tests/palsuite/loader/LoadLibraryW/test1/LoadLibraryW.c
+++ b/src/pal/tests/palsuite/loader/LoadLibraryW/test1/LoadLibraryW.cpp
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryW/test2/CMakeLists.txt b/src/pal/tests/palsuite/loader/LoadLibraryW/test2/CMakeLists.txt
index 5e8486d23b..9873e1332d 100644
--- a/src/pal/tests/palsuite/loader/LoadLibraryW/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/loader/LoadLibraryW/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- loadlibraryw.c
+ loadlibraryw.cpp
)
add_executable(paltest_loadlibraryw_test2
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryW/test2/loadlibraryw.c b/src/pal/tests/palsuite/loader/LoadLibraryW/test2/loadlibraryw.cpp
index e8aebf77e9..e8aebf77e9 100644
--- a/src/pal/tests/palsuite/loader/LoadLibraryW/test2/loadlibraryw.c
+++ b/src/pal/tests/palsuite/loader/LoadLibraryW/test2/loadlibraryw.cpp
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryW/test3/CMakeLists.txt b/src/pal/tests/palsuite/loader/LoadLibraryW/test3/CMakeLists.txt
index 2c96fa23da..be758643fa 100644
--- a/src/pal/tests/palsuite/loader/LoadLibraryW/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/loader/LoadLibraryW/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- loadlibraryw.c
+ loadlibraryw.cpp
)
add_executable(paltest_loadlibraryw_test3
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryW/test3/loadlibraryw.c b/src/pal/tests/palsuite/loader/LoadLibraryW/test3/loadlibraryw.cpp
index c722edaf13..c722edaf13 100644
--- a/src/pal/tests/palsuite/loader/LoadLibraryW/test3/loadlibraryw.c
+++ b/src/pal/tests/palsuite/loader/LoadLibraryW/test3/loadlibraryw.cpp
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryW/test5/CMakeLists.txt b/src/pal/tests/palsuite/loader/LoadLibraryW/test5/CMakeLists.txt
index 7b8931a961..1ca990b514 100644
--- a/src/pal/tests/palsuite/loader/LoadLibraryW/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/loader/LoadLibraryW/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- loadlibraryw.c
+ loadlibraryw.cpp
)
add_executable(paltest_loadlibraryw_test5
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryW/test5/loadlibraryw.c b/src/pal/tests/palsuite/loader/LoadLibraryW/test5/loadlibraryw.c
deleted file mode 100644
index acaa200a06..0000000000
--- a/src/pal/tests/palsuite/loader/LoadLibraryW/test5/loadlibraryw.c
+++ /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.
-
-/*=============================================================
-**
-** Source: loadlibraryw.c
-**
-** Purpose: Negative test the LoadLibraryW API.
-** Call LoadLibraryW by passing a module name
-** without extension but with a trailing dot.
-**
-**
-**============================================================*/
-#define UNICODE
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
- HMODULE ModuleHandle;
- int err;
- WCHAR *lpModuleName;
- char ModuleName[_MAX_FNAME];
-
- /* Initialize the PAL environment */
- err = PAL_Initialize(argc, argv);
- if(0 != err)
- {
- return FAIL;
- }
-
- memset(ModuleName, 0, _MAX_FNAME);
-
- /*Module name without extension but with a trailing dot*/
-#if WIN32
- sprintf(ModuleName,"%s","rotor_pal.");
-#else
- sprintf(ModuleName,"%s","librotor_pal.");
-#endif
-
- /* convert a normal string to a wide one */
- lpModuleName = convert(ModuleName);
-
- /* load a module */
- ModuleHandle = LoadLibraryW(lpModuleName);
-
- /* free the memory */
- free(lpModuleName);
-
- if(NULL != ModuleHandle)
- {
- Trace("Failed to call LoadLibraryW API for a negative test "
- "call LoadLibraryW with module name which does not have "
- "extension except a trailing dot, a NULL module handle is"
- "expected, but no NULL module handle is returned, "
- "error code = %u\n", GetLastError());
-
- /* decrement the reference count of the loaded dll */
- err = FreeLibrary(ModuleHandle);
- if(0 == err)
- {
- Trace("\nFailed to call FreeLibrary API, "
- "error code = %u\n", GetLastError());
- }
-
- Fail("");
- }
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryW/test5/loadlibraryw.cpp b/src/pal/tests/palsuite/loader/LoadLibraryW/test5/loadlibraryw.cpp
new file mode 100644
index 0000000000..6d92f029e4
--- /dev/null
+++ b/src/pal/tests/palsuite/loader/LoadLibraryW/test5/loadlibraryw.cpp
@@ -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.
+
+/*=============================================================
+**
+** Source: loadlibraryw.c
+**
+** Purpose: Negative test the LoadLibraryW API.
+** Call LoadLibraryW by passing a module name
+** without extension but with a trailing dot.
+**
+**
+**============================================================*/
+#define UNICODE
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+ HMODULE ModuleHandle;
+ int err;
+ WCHAR *lpModuleName;
+ char ModuleName[_MAX_FNAME];
+
+ /* Initialize the PAL environment */
+ err = PAL_Initialize(argc, argv);
+ if(0 != err)
+ {
+ return FAIL;
+ }
+
+ memset(ModuleName, 0, _MAX_FNAME);
+
+ /*Module name without extension but with a trailing dot*/
+#if WIN32
+ sprintf_s(ModuleName, _countof(ModuleName),"%s","rotor_pal.");
+#else
+ sprintf_s(ModuleName, _countof(ModuleName),"%s","librotor_pal.");
+#endif
+
+ /* convert a normal string to a wide one */
+ lpModuleName = convert(ModuleName);
+
+ /* load a module */
+ ModuleHandle = LoadLibraryW(lpModuleName);
+
+ /* free the memory */
+ free(lpModuleName);
+
+ if(NULL != ModuleHandle)
+ {
+ Trace("Failed to call LoadLibraryW API for a negative test "
+ "call LoadLibraryW with module name which does not have "
+ "extension except a trailing dot, a NULL module handle is"
+ "expected, but no NULL module handle is returned, "
+ "error code = %u\n", GetLastError());
+
+ /* decrement the reference count of the loaded dll */
+ err = FreeLibrary(ModuleHandle);
+ if(0 == err)
+ {
+ Trace("\nFailed to call FreeLibrary API, "
+ "error code = %u\n", GetLastError());
+ }
+
+ Fail("");
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/locale_info/CompareStringA/test1/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/CompareStringA/test1/CMakeLists.txt
index 96ee18d857..171d5b77e8 100644
--- a/src/pal/tests/palsuite/locale_info/CompareStringA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/CompareStringA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_comparestringa_test1
diff --git a/src/pal/tests/palsuite/locale_info/CompareStringA/test1/test1.c b/src/pal/tests/palsuite/locale_info/CompareStringA/test1/test1.cpp
index 98c147af48..98c147af48 100644
--- a/src/pal/tests/palsuite/locale_info/CompareStringA/test1/test1.c
+++ b/src/pal/tests/palsuite/locale_info/CompareStringA/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/locale_info/CompareStringW/test1/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/CompareStringW/test1/CMakeLists.txt
index 8652977387..15a7fe7685 100644
--- a/src/pal/tests/palsuite/locale_info/CompareStringW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/CompareStringW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_comparestringw_test1
diff --git a/src/pal/tests/palsuite/locale_info/CompareStringW/test1/test1.c b/src/pal/tests/palsuite/locale_info/CompareStringW/test1/test1.cpp
index bdf2c3dcf3..bdf2c3dcf3 100644
--- a/src/pal/tests/palsuite/locale_info/CompareStringW/test1/test1.c
+++ b/src/pal/tests/palsuite/locale_info/CompareStringW/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/locale_info/GetACP/test1/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/GetACP/test1/CMakeLists.txt
index c5513da2c1..cf4431ea94 100644
--- a/src/pal/tests/palsuite/locale_info/GetACP/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/GetACP/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_getacp_test1
diff --git a/src/pal/tests/palsuite/locale_info/GetACP/test1/test1.c b/src/pal/tests/palsuite/locale_info/GetACP/test1/test1.cpp
index 8ea078ee69..8ea078ee69 100644
--- a/src/pal/tests/palsuite/locale_info/GetACP/test1/test1.c
+++ b/src/pal/tests/palsuite/locale_info/GetACP/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/locale_info/GetCPInfo/test1/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/GetCPInfo/test1/CMakeLists.txt
index c209b121b2..b4cf017c2b 100644
--- a/src/pal/tests/palsuite/locale_info/GetCPInfo/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/GetCPInfo/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_getcpinfo_test1
diff --git a/src/pal/tests/palsuite/locale_info/GetCPInfo/test1/test1.c b/src/pal/tests/palsuite/locale_info/GetCPInfo/test1/test1.cpp
index ed9bbf93fc..ed9bbf93fc 100644
--- a/src/pal/tests/palsuite/locale_info/GetCPInfo/test1/test1.c
+++ b/src/pal/tests/palsuite/locale_info/GetCPInfo/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/locale_info/GetCPInfo/test2/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/GetCPInfo/test2/CMakeLists.txt
index 6132e9b3fa..b366f3ce8d 100644
--- a/src/pal/tests/palsuite/locale_info/GetCPInfo/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/GetCPInfo/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_getcpinfo_test2
diff --git a/src/pal/tests/palsuite/locale_info/GetCPInfo/test2/test2.c b/src/pal/tests/palsuite/locale_info/GetCPInfo/test2/test2.cpp
index f52320f167..f52320f167 100644
--- a/src/pal/tests/palsuite/locale_info/GetCPInfo/test2/test2.c
+++ b/src/pal/tests/palsuite/locale_info/GetCPInfo/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/locale_info/GetCPInfo/test3/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/GetCPInfo/test3/CMakeLists.txt
index 3e4a09b51d..032dd00290 100644
--- a/src/pal/tests/palsuite/locale_info/GetCPInfo/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/GetCPInfo/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_getcpinfo_test3
diff --git a/src/pal/tests/palsuite/locale_info/GetCPInfo/test3/test3.c b/src/pal/tests/palsuite/locale_info/GetCPInfo/test3/test3.cpp
index aa9df935b8..aa9df935b8 100644
--- a/src/pal/tests/palsuite/locale_info/GetCPInfo/test3/test3.c
+++ b/src/pal/tests/palsuite/locale_info/GetCPInfo/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/locale_info/GetLocaleInfoW/test1/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/GetLocaleInfoW/test1/CMakeLists.txt
index f373b98f7c..4f685cb8a4 100644
--- a/src/pal/tests/palsuite/locale_info/GetLocaleInfoW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/GetLocaleInfoW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_getlocaleinfow_test1
diff --git a/src/pal/tests/palsuite/locale_info/GetLocaleInfoW/test1/test1.c b/src/pal/tests/palsuite/locale_info/GetLocaleInfoW/test1/test1.cpp
index 0994940a57..0994940a57 100644
--- a/src/pal/tests/palsuite/locale_info/GetLocaleInfoW/test1/test1.c
+++ b/src/pal/tests/palsuite/locale_info/GetLocaleInfoW/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/locale_info/GetLocaleInfoW/test2/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/GetLocaleInfoW/test2/CMakeLists.txt
index dd5b82ef61..7851b36b96 100644
--- a/src/pal/tests/palsuite/locale_info/GetLocaleInfoW/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/GetLocaleInfoW/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_getlocaleinfow_test2
diff --git a/src/pal/tests/palsuite/locale_info/GetLocaleInfoW/test2/test2.c b/src/pal/tests/palsuite/locale_info/GetLocaleInfoW/test2/test2.cpp
index f00fa79c59..f00fa79c59 100644
--- a/src/pal/tests/palsuite/locale_info/GetLocaleInfoW/test2/test2.c
+++ b/src/pal/tests/palsuite/locale_info/GetLocaleInfoW/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/locale_info/GetStringTypeExW/test1/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/GetStringTypeExW/test1/CMakeLists.txt
index 5bb7b8c8b5..e68621681a 100644
--- a/src/pal/tests/palsuite/locale_info/GetStringTypeExW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/GetStringTypeExW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_getstringtypeexw_test1
diff --git a/src/pal/tests/palsuite/locale_info/GetStringTypeExW/test1/test1.c b/src/pal/tests/palsuite/locale_info/GetStringTypeExW/test1/test1.cpp
index e15c3d66cd..e15c3d66cd 100644
--- a/src/pal/tests/palsuite/locale_info/GetStringTypeExW/test1/test1.c
+++ b/src/pal/tests/palsuite/locale_info/GetStringTypeExW/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/locale_info/GetStringTypeExW/test2/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/GetStringTypeExW/test2/CMakeLists.txt
index 4a8fab243e..e37b7495d0 100644
--- a/src/pal/tests/palsuite/locale_info/GetStringTypeExW/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/GetStringTypeExW/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_getstringtypeexw_test2
diff --git a/src/pal/tests/palsuite/locale_info/GetStringTypeExW/test2/test2.c b/src/pal/tests/palsuite/locale_info/GetStringTypeExW/test2/test2.cpp
index 6dca7e8ac5..6dca7e8ac5 100644
--- a/src/pal/tests/palsuite/locale_info/GetStringTypeExW/test2/test2.c
+++ b/src/pal/tests/palsuite/locale_info/GetStringTypeExW/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/locale_info/GetSystemDefaultLangID/test1/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/GetSystemDefaultLangID/test1/CMakeLists.txt
index ef87b5f87f..e34e1837e0 100644
--- a/src/pal/tests/palsuite/locale_info/GetSystemDefaultLangID/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/GetSystemDefaultLangID/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_getsystemdefaultlangid_test1
diff --git a/src/pal/tests/palsuite/locale_info/GetSystemDefaultLangID/test1/test1.c b/src/pal/tests/palsuite/locale_info/GetSystemDefaultLangID/test1/test1.cpp
index 1bc5120815..1bc5120815 100644
--- a/src/pal/tests/palsuite/locale_info/GetSystemDefaultLangID/test1/test1.c
+++ b/src/pal/tests/palsuite/locale_info/GetSystemDefaultLangID/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/locale_info/GetThreadLocale/test1/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/GetThreadLocale/test1/CMakeLists.txt
index 8cec9d8306..8abbd822c2 100644
--- a/src/pal/tests/palsuite/locale_info/GetThreadLocale/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/GetThreadLocale/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_getthreadlocale_test1
diff --git a/src/pal/tests/palsuite/locale_info/GetThreadLocale/test1/test1.c b/src/pal/tests/palsuite/locale_info/GetThreadLocale/test1/test1.cpp
index 8eb7252e37..8eb7252e37 100644
--- a/src/pal/tests/palsuite/locale_info/GetThreadLocale/test1/test1.c
+++ b/src/pal/tests/palsuite/locale_info/GetThreadLocale/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/locale_info/GetTimeZoneInformation/test1/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/GetTimeZoneInformation/test1/CMakeLists.txt
index 281f3bf9c3..8bf0a6ca23 100644
--- a/src/pal/tests/palsuite/locale_info/GetTimeZoneInformation/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/GetTimeZoneInformation/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_gettimezoneinformation_test1
diff --git a/src/pal/tests/palsuite/locale_info/GetTimeZoneInformation/test1/test1.c b/src/pal/tests/palsuite/locale_info/GetTimeZoneInformation/test1/test1.cpp
index bb83ade231..bb83ade231 100644
--- a/src/pal/tests/palsuite/locale_info/GetTimeZoneInformation/test1/test1.c
+++ b/src/pal/tests/palsuite/locale_info/GetTimeZoneInformation/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/locale_info/GetUserDefaultLCID/test1/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/GetUserDefaultLCID/test1/CMakeLists.txt
index e039d46ccd..b6f08b1f7d 100644
--- a/src/pal/tests/palsuite/locale_info/GetUserDefaultLCID/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/GetUserDefaultLCID/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_getuserdefaultlcid_test1
diff --git a/src/pal/tests/palsuite/locale_info/GetUserDefaultLCID/test1/test1.c b/src/pal/tests/palsuite/locale_info/GetUserDefaultLCID/test1/test1.cpp
index 4a336f9bb7..4a336f9bb7 100644
--- a/src/pal/tests/palsuite/locale_info/GetUserDefaultLCID/test1/test1.c
+++ b/src/pal/tests/palsuite/locale_info/GetUserDefaultLCID/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/locale_info/GetUserDefaultLangID/test1/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/GetUserDefaultLangID/test1/CMakeLists.txt
index 71fa0464bb..8fc795a52b 100644
--- a/src/pal/tests/palsuite/locale_info/GetUserDefaultLangID/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/GetUserDefaultLangID/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_getuserdefaultlangid_test1
diff --git a/src/pal/tests/palsuite/locale_info/GetUserDefaultLangID/test1/test1.c b/src/pal/tests/palsuite/locale_info/GetUserDefaultLangID/test1/test1.cpp
index 51c5678086..51c5678086 100644
--- a/src/pal/tests/palsuite/locale_info/GetUserDefaultLangID/test1/test1.c
+++ b/src/pal/tests/palsuite/locale_info/GetUserDefaultLangID/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/locale_info/IsDBCSLeadByte/test1/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/IsDBCSLeadByte/test1/CMakeLists.txt
index ad5ad7508d..e9b22dcfc5 100644
--- a/src/pal/tests/palsuite/locale_info/IsDBCSLeadByte/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/IsDBCSLeadByte/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_isdbcsleadbyte_test1
diff --git a/src/pal/tests/palsuite/locale_info/IsDBCSLeadByte/test1/test1.c b/src/pal/tests/palsuite/locale_info/IsDBCSLeadByte/test1/test1.cpp
index ad326be084..ad326be084 100644
--- a/src/pal/tests/palsuite/locale_info/IsDBCSLeadByte/test1/test1.c
+++ b/src/pal/tests/palsuite/locale_info/IsDBCSLeadByte/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/locale_info/IsDBCSLeadByteEx/test1/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/IsDBCSLeadByteEx/test1/CMakeLists.txt
index 9d53ee9b3b..f3a232b143 100644
--- a/src/pal/tests/palsuite/locale_info/IsDBCSLeadByteEx/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/IsDBCSLeadByteEx/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_isdbcsleadbyteex_test1
diff --git a/src/pal/tests/palsuite/locale_info/IsDBCSLeadByteEx/test1/test1.c b/src/pal/tests/palsuite/locale_info/IsDBCSLeadByteEx/test1/test1.cpp
index 9466f4817f..9466f4817f 100644
--- a/src/pal/tests/palsuite/locale_info/IsDBCSLeadByteEx/test1/test1.c
+++ b/src/pal/tests/palsuite/locale_info/IsDBCSLeadByteEx/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/locale_info/IsValidCodePage/test1/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/IsValidCodePage/test1/CMakeLists.txt
index d87e8c0d6b..ae12b37950 100644
--- a/src/pal/tests/palsuite/locale_info/IsValidCodePage/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/IsValidCodePage/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_isvalidcodepage_test1
diff --git a/src/pal/tests/palsuite/locale_info/IsValidCodePage/test1/test1.c b/src/pal/tests/palsuite/locale_info/IsValidCodePage/test1/test1.cpp
index deb6a7ae72..deb6a7ae72 100644
--- a/src/pal/tests/palsuite/locale_info/IsValidCodePage/test1/test1.c
+++ b/src/pal/tests/palsuite/locale_info/IsValidCodePage/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/locale_info/IsValidCodePage/test2/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/IsValidCodePage/test2/CMakeLists.txt
index adcae86ff9..6eeff25d4d 100644
--- a/src/pal/tests/palsuite/locale_info/IsValidCodePage/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/IsValidCodePage/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_isvalidcodepage_test2
diff --git a/src/pal/tests/palsuite/locale_info/IsValidCodePage/test2/test2.c b/src/pal/tests/palsuite/locale_info/IsValidCodePage/test2/test2.cpp
index d9362cfd96..d9362cfd96 100644
--- a/src/pal/tests/palsuite/locale_info/IsValidCodePage/test2/test2.c
+++ b/src/pal/tests/palsuite/locale_info/IsValidCodePage/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/locale_info/IsValidLocale/test1/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/IsValidLocale/test1/CMakeLists.txt
index 8fc7604a49..27d61693b0 100644
--- a/src/pal/tests/palsuite/locale_info/IsValidLocale/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/IsValidLocale/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_isvalidlocale_test1
diff --git a/src/pal/tests/palsuite/locale_info/IsValidLocale/test1/test1.c b/src/pal/tests/palsuite/locale_info/IsValidLocale/test1/test1.cpp
index 4dd63653f5..4dd63653f5 100644
--- a/src/pal/tests/palsuite/locale_info/IsValidLocale/test1/test1.c
+++ b/src/pal/tests/palsuite/locale_info/IsValidLocale/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test1/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test1/CMakeLists.txt
index 044c47712b..7bf79e36a7 100644
--- a/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_multibytetowidechar_test1
diff --git a/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test1/test1.c b/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test1/test1.cpp
index 81f58a532c..81f58a532c 100644
--- a/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test1/test1.c
+++ b/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test2/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test2/CMakeLists.txt
index 0367d53938..b3e3f64c5c 100644
--- a/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_multibytetowidechar_test2
diff --git a/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test2/test2.c b/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test2/test2.cpp
index 1370dba894..1370dba894 100644
--- a/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test2/test2.c
+++ b/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test3/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test3/CMakeLists.txt
index 57e3d66faf..c6eac9bd60 100644
--- a/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_multibytetowidechar_test3
diff --git a/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test3/test3.c b/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test3/test3.cpp
index 1b3a4bd4f5..1b3a4bd4f5 100644
--- a/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test3/test3.c
+++ b/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/CMakeLists.txt
index 3d167dff7c..c9c92952f2 100644
--- a/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_multibytetowidechar_test4
diff --git a/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/test4.c b/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/test4.c
deleted file mode 100644
index 2ba606cf35..0000000000
--- a/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/test4.c
+++ /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.
-
-/*============================================================================
-**
-** Source: test4.c
-**
-** Purpose: Tests MultiByteToWideChar with a UTF-8 encoding
-**
-**
-**==========================================================================*/
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
- int ret;
- int ret2;
-
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
- const char * const utf8Strings[] =
- {
- // Correct strings
-
- // Empty string
- "",
- // 1 byte encoded 1 character long string
- "A",
- // 2 byte encoded 1 character long string
- "\xC2\x80",
- // 3 byte encoded 1 character long string
- "\xE0\xA0\x80",
- // 1 byte encoded characters only
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
- // valid 2 byte encoded characters only
- "\xC2\x80\xC3\xBF\xC7\x81\xDF\xBF",
- // valid 3 byte encoded characters only
- "\xE0\xA0\x80\xE1\xB6\x88\xE1\x80\x80\xEF\xBF\xBF",
- // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 1 byte char
- "\x41\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF\x45",
- // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 1 byte char, ending with 2 byte one
- "\x41\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF",
- // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 2 byte char, ending with 1 byte one
- "\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF\x45",
- // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 2 byte char
- "\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF",
- // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 1 byte char
- "\x41\x42\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF\x45\x46",
- // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 1 byte char, ending with 2 byte one
- "\x41\x42\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF",
- // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 2 byte char, ending with 1 byte one
- "\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF\x45\x46",
- // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 2 byte char
- "\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF",
- // surrogates
- "\xF0\x90\x80\x80\xF0\x90\x89\x80\xF3\x80\x8E\xB0\xF4\x8F\xBF\xBF",
-
- // Strings with errors
- // Incomplete 2 byte encoded character 1 byte missing standalone
- "\xC2",
- // Incomplete 3 byte encoded character 1 byte missing standalone
- "\xE0\xA0",
- // Incomplete 3 byte encoded character 2 bytes missing standalone
- "\xE0",
- // Incomplete surrogate character 1 byte missing standalone
- "\xF0\x90\x80",
- // Incomplete surrogate character 2 bytes missing standalone
- "\xF0\x90",
- // Incomplete surrogate character 3 bytes missing standalone
- "\xF0",
- // Trailing byte with no lead byte standalone
- "\x80",
- // Incomplete 2 byte encoded character 1 byte missing between 1 byte chars
- "\x41\xC2\x42",
- // Incomplete 3 byte encoded character 1 byte missing between 1 byte chars
- "\x41\xE0\xA0\x42",
- // Incomplete 3 byte encoded character 2 bytes missing between 1 byte chars
- "\x41\xE0\x42",
- // Trailing byte with no lead byte between 1 byte chars
- "\x41\x80\x42",
- // Incomplete 2 byte encoded character 1 byte missing before 1 byte char
- "\xC2\x42",
- // Incomplete 3 byte encoded character 1 byte missing before 1 byte char
- "\xE0\xA0\x42",
- // Incomplete 3 byte encoded character 2 bytes missing before 1 byte char
- "\xE0\x42",
- // Trailing byte with no lead byte before 1 byte char
- "\x80\x42",
- // Incomplete 2 byte encoded character 1 byte missing after 1 byte char
- "\x41\xC2",
- // Incomplete 3 byte encoded character 1 byte missing after 1 byte char
- "\x41\xE0\xA0",
- // Incomplete 3 byte encoded character 2 bytes missing after 1 byte char
- "\x41\xE0",
- // Trailing byte with no lead byte after 1 byte char
- "\x41\x80",
- // Incomplete 2 byte encoded character 1 byte missing between 2 byte chars
- "\xC2\x80\xC2\xC3\xBF",
- // Incomplete 3 byte encoded character 1 byte missing between 2 byte chars
- "\xC2\x80\xE0\xA0\xC3\xBF",
- // Incomplete 3 byte encoded character 2 bytes missing between 2 byte chars
- "\xC2\x80\xE0\xC3\xBF",
- // Trailing byte with no lead byte between 2 byte chars
- "\xC2\x80\x80\xC3\xBF",
- // 2 byte encoded character in non-shortest form encodings (these are not allowed)
- "\xC0\x80",
- // 3 byte encoded character in non-shortest form encodings (these are not allowed)
- "\xE0\x80\x80",
- // 4 byte encoded character in non-shortest form encodings (these are not allowed)
- "\xF0\x80\x80\x80",
- };
-
- const WCHAR * const unicodeStrings[] =
- {
- // Empty string
- W(""),
- // 1 byte encoded 1 character long string
- W("A"),
- // 2 byte encoded 1 character long string
- W("\x0080"),
- // 3 byte encoded 1 character long string
- W("\x0800"),
- // 1 byte encoded characters only
- W("ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
- // 2 byte encoded characters only
- W("\x0080\x00FF\x01C1\x07FF"),
- // valid 3 byte encoded characters only
- W("\x0800\x1D88\x1000\xFFFF"),
- // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 1 byte char
- W("\x0041\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF\x0045"),
- // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 1 byte char, ending with 2 byte one
- W("\x0041\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF"),
- // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 2 byte char, ending with 1 byte one
- W("\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF\x0045"),
- // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 2 byte char
- W("\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF"),
- // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 1 byte char
- W("\x0041\x0042\x0080\x00FF\x0043\x0044\x01C1\x07FF\x0045\x0046"),
- // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 1 byte char, ending with 2 byte one
- W("\x0041\x0042\x0080\x00FF\x0043\x0044\x01C1\x07FF"),
- // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 2 byte char, ending with 1 byte one
- W("\x0080\x00FF\x0043\x0044\x01C1\x07FF\x0045\x0046"),
- // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 2 byte char
- W("\x0080\x00FF\x0043\x0044\x01C1\x07FF"),
- // surrogates
- W("\xD800\xDC00\xD800\xDE40\xDAC0\xDFB0\xDBFF\xDFFF"),
-
- // Strings with errors
- // Incomplete 2 byte encoded character standalone
- W(""),
- // Incomplete 3 byte encoded character 1 byte missing standalone
- W(""),
- // Incomplete 3 byte encoded character 2 bytes missing standalone
- W(""),
- // Incomplete surrogate character 1 byte missing standalone
- W(""),
- // Incomplete surrogate character 2 bytes missing standalone
- W(""),
- // Incomplete surrogate character 3 bytes missing standalone
- W(""),
- // Trailing byte with no lead byte standalone
- W(""),
- // Incomplete 2 byte encoded character 1 byte missing between 1 byte chars
- W("\x0041\x0042"),
- // Incomplete 3 byte encoded character 1 byte missing between 1 byte chars
- W("\x0041\x0042"),
- // Incomplete 3 byte encoded character 2 bytes missing between 1 byte chars
- W("\x0041\x0042"),
- // Trailing byte with no lead byte between 1 byte chars
- W("\x0041\x0042"),
- // Incomplete 2 byte encoded character 1 byte missing before 1 byte char
- W("\x0042"),
- // Incomplete 3 byte encoded character 1 byte missing before 1 byte char
- W("\x0042"),
- // Incomplete 3 byte encoded character 2 bytes missing before 1 byte char
- W("\x0042"),
- // Trailing byte with no lead byte before 1 byte char
- W("\x0042"),
- // Incomplete 2 byte encoded character 1 byte missing after 1 byte char
- W("\x0041"),
- // Incomplete 3 byte encoded character 1 byte missing after 1 byte char
- W("\x0041"),
- // Incomplete 3 byte encoded character 2 bytes missing after 1 byte char
- W("\x0041"),
- // Trailing byte with no lead byte after 1 byte char
- W("\x0041"),
- // Incomplete 2 byte encoded character 1 byte missing between 2 byte chars
- W("\x0080\x00FF"),
- // Incomplete 3 byte encoded character 1 byte missing between 2 byte chars
- W("\x0080\x00FF"),
- // Incomplete 3 byte encoded character 2 bytes missing between 2 byte chars
- W("\x0080\x00FF"),
- // Trailing byte with no lead byte between 2 byte chars
- W("\x0080\x00FF"),
- // 2 byte encoded character in non-shortest form encodings (these are not allowed)
- W(""),
- // 3 byte encoded character in non-shortest form encodings (these are not allowed)
- W(""),
- // 4 byte encoded character in non-shortest form encodings (these are not allowed)
- W(""),
- };
-
- for (int i = 0; i < (sizeof(utf8Strings) / sizeof(utf8Strings[0])); i++)
- {
- ret = MultiByteToWideChar(CP_UTF8, 0, utf8Strings[i], -1, NULL, 0);
- WCHAR* wideBuffer = malloc(ret * sizeof(WCHAR));
- ret2 = MultiByteToWideChar(CP_UTF8, 0, utf8Strings[i], -1, wideBuffer, ret);
- if (ret != ret2)
- {
- Fail("MultiByteToWideChar string %d: returned different string length for empty and real dest buffers!\n"
- "Got %d for the empty one, %d for real one.\n", i, ret2, ret);
- }
-
- if (wcscmp(wideBuffer, unicodeStrings[i]) != 0)
- {
- Fail("MultiByteToWideChar string %d: the resulting string doesn't match the expected one!\n", i);
- }
-
- free(wideBuffer);
- }
-
- PAL_Terminate();
-
- return PASS;
-} \ No newline at end of file
diff --git a/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/test4.cpp b/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/test4.cpp
new file mode 100644
index 0000000000..1d7234640b
--- /dev/null
+++ b/src/pal/tests/palsuite/locale_info/MultiByteToWideChar/test4/test4.cpp
@@ -0,0 +1,230 @@
+// Licensed to the .NET Foundation under one or more 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: test4.c
+**
+** Purpose: Tests MultiByteToWideChar with a UTF-8 encoding
+**
+**
+**==========================================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+ int ret;
+ int ret2;
+
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ const char * const utf8Strings[] =
+ {
+ // Correct strings
+
+ // Empty string
+ "",
+ // 1 byte encoded 1 character long string
+ "A",
+ // 2 byte encoded 1 character long string
+ "\xC2\x80",
+ // 3 byte encoded 1 character long string
+ "\xE0\xA0\x80",
+ // 1 byte encoded characters only
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
+ // valid 2 byte encoded characters only
+ "\xC2\x80\xC3\xBF\xC7\x81\xDF\xBF",
+ // valid 3 byte encoded characters only
+ "\xE0\xA0\x80\xE1\xB6\x88\xE1\x80\x80\xEF\xBF\xBF",
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 1 byte char
+ "\x41\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF\x45",
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 1 byte char, ending with 2 byte one
+ "\x41\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF",
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 2 byte char, ending with 1 byte one
+ "\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF\x45",
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 2 byte char
+ "\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF",
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 1 byte char
+ "\x41\x42\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF\x45\x46",
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 1 byte char, ending with 2 byte one
+ "\x41\x42\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF",
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 2 byte char, ending with 1 byte one
+ "\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF\x45\x46",
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 2 byte char
+ "\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF",
+ // surrogates
+ "\xF0\x90\x80\x80\xF0\x90\x89\x80\xF3\x80\x8E\xB0\xF4\x8F\xBF\xBF",
+
+ // Strings with errors
+ // Incomplete 2 byte encoded character 1 byte missing standalone
+ "\xC2",
+ // Incomplete 3 byte encoded character 1 byte missing standalone
+ "\xE0\xA0",
+ // Incomplete 3 byte encoded character 2 bytes missing standalone
+ "\xE0",
+ // Incomplete surrogate character 1 byte missing standalone
+ "\xF0\x90\x80",
+ // Incomplete surrogate character 2 bytes missing standalone
+ "\xF0\x90",
+ // Incomplete surrogate character 3 bytes missing standalone
+ "\xF0",
+ // Trailing byte with no lead byte standalone
+ "\x80",
+ // Incomplete 2 byte encoded character 1 byte missing between 1 byte chars
+ "\x41\xC2\x42",
+ // Incomplete 3 byte encoded character 1 byte missing between 1 byte chars
+ "\x41\xE0\xA0\x42",
+ // Incomplete 3 byte encoded character 2 bytes missing between 1 byte chars
+ "\x41\xE0\x42",
+ // Trailing byte with no lead byte between 1 byte chars
+ "\x41\x80\x42",
+ // Incomplete 2 byte encoded character 1 byte missing before 1 byte char
+ "\xC2\x42",
+ // Incomplete 3 byte encoded character 1 byte missing before 1 byte char
+ "\xE0\xA0\x42",
+ // Incomplete 3 byte encoded character 2 bytes missing before 1 byte char
+ "\xE0\x42",
+ // Trailing byte with no lead byte before 1 byte char
+ "\x80\x42",
+ // Incomplete 2 byte encoded character 1 byte missing after 1 byte char
+ "\x41\xC2",
+ // Incomplete 3 byte encoded character 1 byte missing after 1 byte char
+ "\x41\xE0\xA0",
+ // Incomplete 3 byte encoded character 2 bytes missing after 1 byte char
+ "\x41\xE0",
+ // Trailing byte with no lead byte after 1 byte char
+ "\x41\x80",
+ // Incomplete 2 byte encoded character 1 byte missing between 2 byte chars
+ "\xC2\x80\xC2\xC3\xBF",
+ // Incomplete 3 byte encoded character 1 byte missing between 2 byte chars
+ "\xC2\x80\xE0\xA0\xC3\xBF",
+ // Incomplete 3 byte encoded character 2 bytes missing between 2 byte chars
+ "\xC2\x80\xE0\xC3\xBF",
+ // Trailing byte with no lead byte between 2 byte chars
+ "\xC2\x80\x80\xC3\xBF",
+ // 2 byte encoded character in non-shortest form encodings (these are not allowed)
+ "\xC0\x80",
+ // 3 byte encoded character in non-shortest form encodings (these are not allowed)
+ "\xE0\x80\x80",
+ // 4 byte encoded character in non-shortest form encodings (these are not allowed)
+ "\xF0\x80\x80\x80",
+ };
+
+ const WCHAR * const unicodeStrings[] =
+ {
+ // Empty string
+ W(""),
+ // 1 byte encoded 1 character long string
+ W("A"),
+ // 2 byte encoded 1 character long string
+ W("\x0080"),
+ // 3 byte encoded 1 character long string
+ W("\x0800"),
+ // 1 byte encoded characters only
+ W("ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
+ // 2 byte encoded characters only
+ W("\x0080\x00FF\x01C1\x07FF"),
+ // valid 3 byte encoded characters only
+ W("\x0800\x1D88\x1000\xFFFF"),
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 1 byte char
+ W("\x0041\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF\x0045"),
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 1 byte char, ending with 2 byte one
+ W("\x0041\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF"),
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 2 byte char, ending with 1 byte one
+ W("\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF\x0045"),
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 2 byte char
+ W("\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF"),
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 1 byte char
+ W("\x0041\x0042\x0080\x00FF\x0043\x0044\x01C1\x07FF\x0045\x0046"),
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 1 byte char, ending with 2 byte one
+ W("\x0041\x0042\x0080\x00FF\x0043\x0044\x01C1\x07FF"),
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 2 byte char, ending with 1 byte one
+ W("\x0080\x00FF\x0043\x0044\x01C1\x07FF\x0045\x0046"),
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 2 byte char
+ W("\x0080\x00FF\x0043\x0044\x01C1\x07FF"),
+ // surrogates
+ W("\xD800\xDC00\xD800\xDE40\xDAC0\xDFB0\xDBFF\xDFFF"),
+
+ // Strings with errors
+ // Incomplete 2 byte encoded character standalone
+ W(""),
+ // Incomplete 3 byte encoded character 1 byte missing standalone
+ W(""),
+ // Incomplete 3 byte encoded character 2 bytes missing standalone
+ W(""),
+ // Incomplete surrogate character 1 byte missing standalone
+ W(""),
+ // Incomplete surrogate character 2 bytes missing standalone
+ W(""),
+ // Incomplete surrogate character 3 bytes missing standalone
+ W(""),
+ // Trailing byte with no lead byte standalone
+ W(""),
+ // Incomplete 2 byte encoded character 1 byte missing between 1 byte chars
+ W("\x0041\x0042"),
+ // Incomplete 3 byte encoded character 1 byte missing between 1 byte chars
+ W("\x0041\x0042"),
+ // Incomplete 3 byte encoded character 2 bytes missing between 1 byte chars
+ W("\x0041\x0042"),
+ // Trailing byte with no lead byte between 1 byte chars
+ W("\x0041\x0042"),
+ // Incomplete 2 byte encoded character 1 byte missing before 1 byte char
+ W("\x0042"),
+ // Incomplete 3 byte encoded character 1 byte missing before 1 byte char
+ W("\x0042"),
+ // Incomplete 3 byte encoded character 2 bytes missing before 1 byte char
+ W("\x0042"),
+ // Trailing byte with no lead byte before 1 byte char
+ W("\x0042"),
+ // Incomplete 2 byte encoded character 1 byte missing after 1 byte char
+ W("\x0041"),
+ // Incomplete 3 byte encoded character 1 byte missing after 1 byte char
+ W("\x0041"),
+ // Incomplete 3 byte encoded character 2 bytes missing after 1 byte char
+ W("\x0041"),
+ // Trailing byte with no lead byte after 1 byte char
+ W("\x0041"),
+ // Incomplete 2 byte encoded character 1 byte missing between 2 byte chars
+ W("\x0080\x00FF"),
+ // Incomplete 3 byte encoded character 1 byte missing between 2 byte chars
+ W("\x0080\x00FF"),
+ // Incomplete 3 byte encoded character 2 bytes missing between 2 byte chars
+ W("\x0080\x00FF"),
+ // Trailing byte with no lead byte between 2 byte chars
+ W("\x0080\x00FF"),
+ // 2 byte encoded character in non-shortest form encodings (these are not allowed)
+ W(""),
+ // 3 byte encoded character in non-shortest form encodings (these are not allowed)
+ W(""),
+ // 4 byte encoded character in non-shortest form encodings (these are not allowed)
+ W(""),
+ };
+
+ for (int i = 0; i < (sizeof(utf8Strings) / sizeof(utf8Strings[0])); i++)
+ {
+ ret = MultiByteToWideChar(CP_UTF8, 0, utf8Strings[i], -1, NULL, 0);
+ WCHAR* wideBuffer = (WCHAR*)malloc(ret * sizeof(WCHAR));
+ ret2 = MultiByteToWideChar(CP_UTF8, 0, utf8Strings[i], -1, wideBuffer, ret);
+ if (ret != ret2)
+ {
+ Fail("MultiByteToWideChar string %d: returned different string length for empty and real dest buffers!\n"
+ "Got %d for the empty one, %d for real one.\n", i, ret2, ret);
+ }
+
+ if (wcscmp(wideBuffer, unicodeStrings[i]) != 0)
+ {
+ Fail("MultiByteToWideChar string %d: the resulting string doesn't match the expected one!\n", i);
+ }
+
+ free(wideBuffer);
+ }
+
+ PAL_Terminate();
+
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/locale_info/SetThreadLocale/test1/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/SetThreadLocale/test1/CMakeLists.txt
index 85824dd836..5ac7433c98 100644
--- a/src/pal/tests/palsuite/locale_info/SetThreadLocale/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/SetThreadLocale/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_setthreadlocale_test1
diff --git a/src/pal/tests/palsuite/locale_info/SetThreadLocale/test1/test1.c b/src/pal/tests/palsuite/locale_info/SetThreadLocale/test1/test1.cpp
index 794093cf4c..794093cf4c 100644
--- a/src/pal/tests/palsuite/locale_info/SetThreadLocale/test1/test1.c
+++ b/src/pal/tests/palsuite/locale_info/SetThreadLocale/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/CMakeLists.txt
index 0d1d12b41e..07dae640f1 100644
--- a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_widechartomultibyte_test1
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/test1.c b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/test1.cpp
index cd763f33be..cd763f33be 100644
--- a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/test1.c
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/CMakeLists.txt
index bbfad2ca9f..99c64afa2a 100644
--- a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_widechartomultibyte_test2
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/test2.c b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/test2.cpp
index f5d40ae903..f5d40ae903 100644
--- a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/test2.c
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/CMakeLists.txt
index 0edfd73931..70dabead6f 100644
--- a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_widechartomultibyte_test3
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/test3.c b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/test3.cpp
index ecd26addb4..ecd26addb4 100644
--- a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/test3.c
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test4/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test4/CMakeLists.txt
index f0ffd84ee9..8839c19183 100644
--- a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_widechartomultibyte_test4
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test4/test4.c b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test4/test4.cpp
index 8ab5fe90af..8ab5fe90af 100644
--- a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test4/test4.c
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/CMakeLists.txt b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/CMakeLists.txt
index 6ca2a628bf..e00657879d 100644
--- a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_widechartomultibyte_test5
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/test5.c b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/test5.c
deleted file mode 100644
index 3ca0d90d0f..0000000000
--- a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/test5.c
+++ /dev/null
@@ -1,154 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: test4.c
-**
-** Purpose: Tests WideCharMultiByte with UTF-8 encoding
-**
-**
-**==========================================================================*/
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
- int ret;
- int ret2;
-
- if (PAL_Initialize(argc, argv))
- {
- return FAIL;
- }
-
- const WCHAR * const unicodeStrings[] =
- {
- // Correct strings
-
- // Empty string
- W(""),
- // 1 byte encoded 1 character long string
- W("A"),
- // 2 byte encoded 1 character long string
- W("\x0080"),
- // 3 byte encoded 1 character long string
- W("\x0800"),
- // 1 byte encoded characters only
- W("ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
- // 2 byte encoded characters only
- W("\x0080\x00FF\x01C1\x07FF"),
- // valid 3 byte encoded characters only
- W("\x0800\x1D88\x1000\xFFFF"),
- // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 1 byte char
- W("\x0041\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF\x0045"),
- // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 1 byte char, ending with 2 byte one
- W("\x0041\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF"),
- // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 2 byte char, ending with 1 byte one
- W("\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF\x0045"),
- // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 2 byte char
- W("\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF"),
- // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 1 byte char
- W("\x0041\x0042\x0080\x00FF\x0043\x0044\x01C1\x07FF\x0045\x0046"),
- // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 1 byte char, ending with 2 byte one
- W("\x0041\x0042\x0080\x00FF\x0043\x0044\x01C1\x07FF"),
- // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 2 byte char, ending with 1 byte one
- W("\x0080\x00FF\x0043\x0044\x01C1\x07FF\x0045\x0046"),
- // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 2 byte char
- W("\x0080\x00FF\x0043\x0044\x01C1\x07FF"),
- // Surrogates
- W("\xD800\xDC00\xD800\xDE40\xDAC0\xDFB0\xDBFF\xDFFF"),
-
- // Strings with errors
-
- // Single high surrogate
- W("\xD800"),
- // Single low surrogate
- W("\xDC00"),
- // Character followed by single high surrogate
- W("\x0041\xD800"),
- // Character followed by single low surrogate
- W("\x0041\xDC00"),
- // Single high surrogate between two characters
- W("\x0041\xD800\x0042"),
- // Single low surrogate between two characters
- W("\x0041\xDC00\x0042"),
- };
-
- const char * const utf8Strings[] =
- {
- // Correct strings
-
- // Empty string
- "",
- // 1 byte encoded 1 character long string
- "A",
- // 2 byte encoded 1 character long string
- "\xC2\x80",
- // 3 byte encoded 1 character long string
- "\xE0\xA0\x80",
- // 1 byte encoded characters only
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
- // valid 2 byte encoded characters only
- "\xC2\x80\xC3\xBF\xC7\x81\xDF\xBF",
- // valid 3 byte encoded characters only
- "\xE0\xA0\x80\xE1\xB6\x88\xE1\x80\x80\xEF\xBF\xBF",
- // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 1 byte char
- "\x41\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF\x45",
- // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 1 byte char, ending with 2 byte one
- "\x41\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF",
- // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 2 byte char, ending with 1 byte one
- "\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF\x45",
- // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 2 byte char
- "\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF",
- // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 1 byte char
- "\x41\x42\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF\x45\x46",
- // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 1 byte char, ending with 2 byte one
- "\x41\x42\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF",
- // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 2 byte char, ending with 1 byte one
- "\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF\x45\x46",
- // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 2 byte char
- "\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF",
- // Surrogates
- "\xF0\x90\x80\x80\xF0\x90\x89\x80\xF3\x80\x8E\xB0\xF4\x8F\xBF\xBF",
-
- // Strings with errors
-
- // Single high surrogate
- "\xEF\xBF\xBD",
- // Single low surrogate
- "\xEF\xBF\xBD",
- // Character followed by single high surrogate
- "\x41\xEF\xBF\xBD",
- // Character followed by single low surrogate
- "\x41\xEF\xBF\xBD",
- // Single high surrogate between two characters
- "\x41\xEF\xBF\xBD\x42",
- // Single low surrogate between two characters
- "\x41\xEF\xBF\xBD\x42",
- };
-
- for (int i = 0; i < (sizeof(unicodeStrings) / sizeof(unicodeStrings[0])); i++)
- {
- ret = WideCharToMultiByte(CP_UTF8, 0, unicodeStrings[i], -1, NULL, 0, NULL, NULL);
- CHAR* utf8Buffer = malloc(ret * sizeof(CHAR));
- ret2 = WideCharToMultiByte(CP_UTF8, 0, unicodeStrings[i], -1, utf8Buffer, ret, NULL, NULL);
- if (ret != ret2)
- {
- Fail("WideCharToMultiByte string %d: returned different string length for empty and real dest buffers!\n"
- "Got %d for the empty one, %d for real one.\n", i, ret2, ret);
- }
-
- if (strcmp(utf8Buffer, utf8Strings[i]) != 0)
- {
- Fail("WideCharToMultiByte string %d: the resulting string doesn't match the expected one!\n", i);
- }
-
- free(utf8Buffer);
- }
-
- PAL_Terminate();
-
- return PASS;
-} \ No newline at end of file
diff --git a/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/test5.cpp b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/test5.cpp
new file mode 100644
index 0000000000..393516a198
--- /dev/null
+++ b/src/pal/tests/palsuite/locale_info/WideCharToMultiByte/test5/test5.cpp
@@ -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.
+
+/*============================================================================
+**
+** Source: test4.c
+**
+** Purpose: Tests WideCharMultiByte with UTF-8 encoding
+**
+**
+**==========================================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+ int ret;
+ int ret2;
+
+ if (PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+
+ const WCHAR * const unicodeStrings[] =
+ {
+ // Correct strings
+
+ // Empty string
+ W(""),
+ // 1 byte encoded 1 character long string
+ W("A"),
+ // 2 byte encoded 1 character long string
+ W("\x0080"),
+ // 3 byte encoded 1 character long string
+ W("\x0800"),
+ // 1 byte encoded characters only
+ W("ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
+ // 2 byte encoded characters only
+ W("\x0080\x00FF\x01C1\x07FF"),
+ // valid 3 byte encoded characters only
+ W("\x0800\x1D88\x1000\xFFFF"),
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 1 byte char
+ W("\x0041\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF\x0045"),
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 1 byte char, ending with 2 byte one
+ W("\x0041\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF"),
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 2 byte char, ending with 1 byte one
+ W("\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF\x0045"),
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 2 byte char
+ W("\x0080\x0042\x00FF\x0043\x01C1\x0044\x07FF"),
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 1 byte char
+ W("\x0041\x0042\x0080\x00FF\x0043\x0044\x01C1\x07FF\x0045\x0046"),
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 1 byte char, ending with 2 byte one
+ W("\x0041\x0042\x0080\x00FF\x0043\x0044\x01C1\x07FF"),
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 2 byte char, ending with 1 byte one
+ W("\x0080\x00FF\x0043\x0044\x01C1\x07FF\x0045\x0046"),
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 2 byte char
+ W("\x0080\x00FF\x0043\x0044\x01C1\x07FF"),
+ // Surrogates
+ W("\xD800\xDC00\xD800\xDE40\xDAC0\xDFB0\xDBFF\xDFFF"),
+
+ // Strings with errors
+
+ // Single high surrogate
+ W("\xD800"),
+ // Single low surrogate
+ W("\xDC00"),
+ // Character followed by single high surrogate
+ W("\x0041\xD800"),
+ // Character followed by single low surrogate
+ W("\x0041\xDC00"),
+ // Single high surrogate between two characters
+ W("\x0041\xD800\x0042"),
+ // Single low surrogate between two characters
+ W("\x0041\xDC00\x0042"),
+ };
+
+ const char * const utf8Strings[] =
+ {
+ // Correct strings
+
+ // Empty string
+ "",
+ // 1 byte encoded 1 character long string
+ "A",
+ // 2 byte encoded 1 character long string
+ "\xC2\x80",
+ // 3 byte encoded 1 character long string
+ "\xE0\xA0\x80",
+ // 1 byte encoded characters only
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
+ // valid 2 byte encoded characters only
+ "\xC2\x80\xC3\xBF\xC7\x81\xDF\xBF",
+ // valid 3 byte encoded characters only
+ "\xE0\xA0\x80\xE1\xB6\x88\xE1\x80\x80\xEF\xBF\xBF",
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 1 byte char
+ "\x41\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF\x45",
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 1 byte char, ending with 2 byte one
+ "\x41\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF",
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting with 2 byte char, ending with 1 byte one
+ "\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF\x45",
+ // 1 byte and 2 byte encoded characters interleaved 1:1 starting and ending with 2 byte char
+ "\xC2\x80\x42\xC3\xBF\x43\xC7\x81\x44\xDF\xBF",
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 1 byte char
+ "\x41\x42\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF\x45\x46",
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 1 byte char, ending with 2 byte one
+ "\x41\x42\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF",
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting with 2 byte char, ending with 1 byte one
+ "\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF\x45\x46",
+ // 1 byte and 2 byte encoded characters interleaved 2:2 starting and ending with 2 byte char
+ "\xC2\x80\xC3\xBF\x43\x44\xC7\x81\xDF\xBF",
+ // Surrogates
+ "\xF0\x90\x80\x80\xF0\x90\x89\x80\xF3\x80\x8E\xB0\xF4\x8F\xBF\xBF",
+
+ // Strings with errors
+
+ // Single high surrogate
+ "\xEF\xBF\xBD",
+ // Single low surrogate
+ "\xEF\xBF\xBD",
+ // Character followed by single high surrogate
+ "\x41\xEF\xBF\xBD",
+ // Character followed by single low surrogate
+ "\x41\xEF\xBF\xBD",
+ // Single high surrogate between two characters
+ "\x41\xEF\xBF\xBD\x42",
+ // Single low surrogate between two characters
+ "\x41\xEF\xBF\xBD\x42",
+ };
+
+ for (int i = 0; i < (sizeof(unicodeStrings) / sizeof(unicodeStrings[0])); i++)
+ {
+ ret = WideCharToMultiByte(CP_UTF8, 0, unicodeStrings[i], -1, NULL, 0, NULL, NULL);
+ CHAR* utf8Buffer = (CHAR*)malloc(ret * sizeof(CHAR));
+ ret2 = WideCharToMultiByte(CP_UTF8, 0, unicodeStrings[i], -1, utf8Buffer, ret, NULL, NULL);
+ if (ret != ret2)
+ {
+ Fail("WideCharToMultiByte string %d: returned different string length for empty and real dest buffers!\n"
+ "Got %d for the empty one, %d for real one.\n", i, ret2, ret);
+ }
+
+ if (strcmp(utf8Buffer, utf8Strings[i]) != 0)
+ {
+ Fail("WideCharToMultiByte string %d: the resulting string doesn't match the expected one!\n", i);
+ }
+
+ free(utf8Buffer);
+ }
+
+ PAL_Terminate();
+
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/miscellaneous/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/CMakeLists.txt
index 86f194198b..0fd4df8ad5 100644
--- a/src/pal/tests/palsuite/miscellaneous/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/CMakeLists.txt
@@ -27,9 +27,6 @@ add_subdirectory(InterLockedExchangeAdd)
add_subdirectory(InterlockedExchangePointer)
add_subdirectory(InterlockedIncrement)
add_subdirectory(InterlockedIncrement64)
-add_subdirectory(lstrcatW)
-add_subdirectory(lstrcpynW)
-add_subdirectory(lstrcpyW)
add_subdirectory(lstrlenA)
add_subdirectory(lstrlenW)
add_subdirectory(queryperformancecounter)
@@ -37,8 +34,5 @@ add_subdirectory(queryperformancefrequency)
add_subdirectory(SetEnvironmentVariableA)
add_subdirectory(SetEnvironmentVariableW)
add_subdirectory(SetLastError)
-add_subdirectory(wsprintfA)
-add_subdirectory(wsprintfW)
add_subdirectory(_i64tow)
-add_subdirectory(_ui64tow)
diff --git a/src/pal/tests/palsuite/miscellaneous/CharNextA/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/CharNextA/test1/CMakeLists.txt
index 8506d86737..23df52b430 100644
--- a/src/pal/tests/palsuite/miscellaneous/CharNextA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/CharNextA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_charnexta_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/CharNextA/test1/test.c b/src/pal/tests/palsuite/miscellaneous/CharNextA/test1/test.cpp
index d2a3db31d5..d2a3db31d5 100644
--- a/src/pal/tests/palsuite/miscellaneous/CharNextA/test1/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/CharNextA/test1/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/CharNextA/test2/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/CharNextA/test2/CMakeLists.txt
index 04f4679630..5f089e963c 100644
--- a/src/pal/tests/palsuite/miscellaneous/CharNextA/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/CharNextA/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_charnexta_test2
diff --git a/src/pal/tests/palsuite/miscellaneous/CharNextA/test2/test.c b/src/pal/tests/palsuite/miscellaneous/CharNextA/test2/test.cpp
index 7261959021..7261959021 100644
--- a/src/pal/tests/palsuite/miscellaneous/CharNextA/test2/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/CharNextA/test2/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/CharNextExA/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/CharNextExA/test1/CMakeLists.txt
index bfa12b5526..ae1433f089 100644
--- a/src/pal/tests/palsuite/miscellaneous/CharNextExA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/CharNextExA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_charnextexa_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/CharNextExA/test1/test.c b/src/pal/tests/palsuite/miscellaneous/CharNextExA/test1/test.cpp
index 9671ca86b8..9671ca86b8 100644
--- a/src/pal/tests/palsuite/miscellaneous/CharNextExA/test1/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/CharNextExA/test1/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/CharNextExA/test2/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/CharNextExA/test2/CMakeLists.txt
index 556043abcd..1c81d1f9a4 100644
--- a/src/pal/tests/palsuite/miscellaneous/CharNextExA/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/CharNextExA/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_charnextexa_test2
diff --git a/src/pal/tests/palsuite/miscellaneous/CharNextExA/test2/test.c b/src/pal/tests/palsuite/miscellaneous/CharNextExA/test2/test.cpp
index ffc153f5e6..ffc153f5e6 100644
--- a/src/pal/tests/palsuite/miscellaneous/CharNextExA/test2/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/CharNextExA/test2/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/CloseHandle/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/CloseHandle/test1/CMakeLists.txt
index bbe37ddd19..78bb701959 100644
--- a/src/pal/tests/palsuite/miscellaneous/CloseHandle/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/CloseHandle/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_closehandle_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/CloseHandle/test1/test.c b/src/pal/tests/palsuite/miscellaneous/CloseHandle/test1/test.c
deleted file mode 100644
index 8e42229c29..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/CloseHandle/test1/test.c
+++ /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.
-
-/*============================================================
-**
-** Source: test.c
-**
-** Purpose: Test for CloseHandle function
-**
-**
-**=========================================================*/
-
-/* Depends on: CreateFile and WriteFile */
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
-
- HANDLE FileHandle = NULL;
- LPDWORD WriteBuffer; /* Used with WriteFile */
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- WriteBuffer = malloc(sizeof(WORD));
-
- if ( WriteBuffer == NULL )
- {
- Fail("ERROR: Failed to allocate memory for WriteBuffer pointer. "
- "Can't properly exec test case without this.\n");
- }
-
-
- /* Create a file, since this returns to us a HANDLE we can use */
- FileHandle = CreateFile("testfile",
- GENERIC_READ | GENERIC_WRITE,0,NULL,CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
-
- /* Should be able to close this handle */
- if(CloseHandle(FileHandle) == 0)
- {
- free(WriteBuffer);
- Fail("ERROR: (Test 1) Attempted to close a HANDLE on a file, but the "
- "return value was <=0, indicating failure.\n");
- }
-
- free(WriteBuffer);
-
- PAL_Terminate();
- return PASS;
-}
-
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/CloseHandle/test1/test.cpp b/src/pal/tests/palsuite/miscellaneous/CloseHandle/test1/test.cpp
new file mode 100644
index 0000000000..443f89bace
--- /dev/null
+++ b/src/pal/tests/palsuite/miscellaneous/CloseHandle/test1/test.cpp
@@ -0,0 +1,64 @@
+// Licensed to the .NET Foundation under one or more 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 CloseHandle function
+**
+**
+**=========================================================*/
+
+/* Depends on: CreateFile and WriteFile */
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ HANDLE FileHandle = NULL;
+ LPDWORD WriteBuffer; /* Used with WriteFile */
+
+ /*
+ * Initialize the PAL and return FAILURE if this fails
+ */
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ WriteBuffer = (LPDWORD)malloc(sizeof(WORD));
+
+ if ( WriteBuffer == NULL )
+ {
+ Fail("ERROR: Failed to allocate memory for WriteBuffer pointer. "
+ "Can't properly exec test case without this.\n");
+ }
+
+
+ /* Create a file, since this returns to us a HANDLE we can use */
+ FileHandle = CreateFile("testfile",
+ GENERIC_READ | GENERIC_WRITE,0,NULL,CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ /* Should be able to close this handle */
+ if(CloseHandle(FileHandle) == 0)
+ {
+ free(WriteBuffer);
+ Fail("ERROR: (Test 1) Attempted to close a HANDLE on a file, but the "
+ "return value was <=0, indicating failure.\n");
+ }
+
+ free(WriteBuffer);
+
+ PAL_Terminate();
+ return PASS;
+}
+
+
+
+
diff --git a/src/pal/tests/palsuite/miscellaneous/CloseHandle/test2/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/CloseHandle/test2/CMakeLists.txt
index 75de513be7..18350f20ad 100644
--- a/src/pal/tests/palsuite/miscellaneous/CloseHandle/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/CloseHandle/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_closehandle_test2
diff --git a/src/pal/tests/palsuite/miscellaneous/CloseHandle/test2/test.c b/src/pal/tests/palsuite/miscellaneous/CloseHandle/test2/test.cpp
index c1eea44070..c1eea44070 100644
--- a/src/pal/tests/palsuite/miscellaneous/CloseHandle/test2/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/CloseHandle/test2/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/CreatePipe/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/CreatePipe/test1/CMakeLists.txt
index af878cb873..15a0f572bb 100644
--- a/src/pal/tests/palsuite/miscellaneous/CreatePipe/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/CreatePipe/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_createpipe_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/CreatePipe/test1/test1.c b/src/pal/tests/palsuite/miscellaneous/CreatePipe/test1/test1.cpp
index 3930183b60..3930183b60 100644
--- a/src/pal/tests/palsuite/miscellaneous/CreatePipe/test1/test1.c
+++ b/src/pal/tests/palsuite/miscellaneous/CreatePipe/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/FlushInstructionCache/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/FlushInstructionCache/test1/CMakeLists.txt
index fbd8b0f87d..47ee4b0abd 100644
--- a/src/pal/tests/palsuite/miscellaneous/FlushInstructionCache/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/FlushInstructionCache/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_flushinstructioncache_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/FlushInstructionCache/test1/test1.c b/src/pal/tests/palsuite/miscellaneous/FlushInstructionCache/test1/test1.cpp
index cdbefd01cc..cdbefd01cc 100644
--- a/src/pal/tests/palsuite/miscellaneous/FlushInstructionCache/test1/test1.c
+++ b/src/pal/tests/palsuite/miscellaneous/FlushInstructionCache/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test1/CMakeLists.txt
index 0f242e9b30..df91482855 100644
--- a/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_formatmessagew_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test1/test.c b/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test1/test.cpp
index 0cc4c43432..0cc4c43432 100644
--- a/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test1/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test1/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test2/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test2/CMakeLists.txt
index 26092ac300..818649aac7 100644
--- a/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_formatmessagew_test2
diff --git a/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test2/test.c b/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test2/test.cpp
index 6c2d80b3f4..6c2d80b3f4 100644
--- a/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test2/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test2/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test3/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test3/CMakeLists.txt
index b430511c4c..516d4bcc9a 100644
--- a/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_formatmessagew_test3
diff --git a/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test3/test.c b/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test3/test.cpp
index a390c00fea..a390c00fea 100644
--- a/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test3/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test3/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test4/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test4/CMakeLists.txt
index cae8ff149c..642727c6dc 100644
--- a/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_formatmessagew_test4
diff --git a/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test4/test.c b/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test4/test.cpp
index 4f865efe7e..4f865efe7e 100644
--- a/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test4/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test4/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test5/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test5/CMakeLists.txt
index 6779f94ff9..bae113475d 100644
--- a/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_formatmessagew_test5
diff --git a/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test5/test.c b/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test5/test.cpp
index 148c2ff236..148c2ff236 100644
--- a/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test5/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test5/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test6/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test6/CMakeLists.txt
index 450b2b808b..f403cba0f4 100644
--- a/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_formatmessagew_test6
diff --git a/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test6/test.c b/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test6/test.cpp
index 48f5e3e93d..48f5e3e93d 100644
--- a/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test6/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/FormatMessageW/test6/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/FreeEnvironmentStringsW/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/FreeEnvironmentStringsW/test1/CMakeLists.txt
index be39b63ec9..206707efa6 100644
--- a/src/pal/tests/palsuite/miscellaneous/FreeEnvironmentStringsW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/FreeEnvironmentStringsW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_freeenvironmentstringsw_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/FreeEnvironmentStringsW/test1/test.c b/src/pal/tests/palsuite/miscellaneous/FreeEnvironmentStringsW/test1/test.cpp
index 56010039d7..56010039d7 100644
--- a/src/pal/tests/palsuite/miscellaneous/FreeEnvironmentStringsW/test1/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/FreeEnvironmentStringsW/test1/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/FreeEnvironmentStringsW/test2/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/FreeEnvironmentStringsW/test2/CMakeLists.txt
index a3688dd24a..d8197d1c90 100644
--- a/src/pal/tests/palsuite/miscellaneous/FreeEnvironmentStringsW/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/FreeEnvironmentStringsW/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_freeenvironmentstringsw_test2
diff --git a/src/pal/tests/palsuite/miscellaneous/FreeEnvironmentStringsW/test2/test.c b/src/pal/tests/palsuite/miscellaneous/FreeEnvironmentStringsW/test2/test.cpp
index 1bb05cdb12..1bb05cdb12 100644
--- a/src/pal/tests/palsuite/miscellaneous/FreeEnvironmentStringsW/test2/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/FreeEnvironmentStringsW/test2/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/GetCalendarInfoW/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetCalendarInfoW/test1/CMakeLists.txt
index e3acf4061a..92cabba428 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetCalendarInfoW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GetCalendarInfoW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetCalendarInfoW.c
+ GetCalendarInfoW.cpp
)
add_executable(paltest_getcalendarinfow_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/GetCalendarInfoW/test1/GetCalendarInfoW.c b/src/pal/tests/palsuite/miscellaneous/GetCalendarInfoW/test1/GetCalendarInfoW.cpp
index 4876fe180f..4876fe180f 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetCalendarInfoW/test1/GetCalendarInfoW.c
+++ b/src/pal/tests/palsuite/miscellaneous/GetCalendarInfoW/test1/GetCalendarInfoW.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/GetCalendarInfoW/test2/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetCalendarInfoW/test2/CMakeLists.txt
index cbfd1aa5db..0cfc9679e7 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetCalendarInfoW/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GetCalendarInfoW/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetCalendarInfoW.c
+ GetCalendarInfoW.cpp
)
add_executable(paltest_getcalendarinfow_test2
diff --git a/src/pal/tests/palsuite/miscellaneous/GetCalendarInfoW/test2/GetCalendarInfoW.c b/src/pal/tests/palsuite/miscellaneous/GetCalendarInfoW/test2/GetCalendarInfoW.cpp
index d8a59a0fc0..d8a59a0fc0 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetCalendarInfoW/test2/GetCalendarInfoW.c
+++ b/src/pal/tests/palsuite/miscellaneous/GetCalendarInfoW/test2/GetCalendarInfoW.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/GetCommandLineW/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetCommandLineW/test1/CMakeLists.txt
index 491fdca9b5..d15b84a59e 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetCommandLineW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GetCommandLineW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_getcommandlinew_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/GetCommandLineW/test1/test.c b/src/pal/tests/palsuite/miscellaneous/GetCommandLineW/test1/test.c
deleted file mode 100644
index d8a81746b6..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/GetCommandLineW/test1/test.c
+++ /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.
-
-/*============================================================
-**
-** Source : test.c
-**
-** Purpose: Test for GetCommandLineW() function
-**
-**
-**=========================================================*/
-
-#define UNICODE
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
-
- LPWSTR TheResult = NULL;
- WCHAR *CommandLine;
- int i;
- WCHAR * p;
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- CommandLine = malloc(1024);
- wcscpy(CommandLine,convert(argv[0]));
-
- for(i=1;i<argc;++i)
- {
- wcscat(CommandLine,convert(" "));
- wcscat(CommandLine,convert(argv[i]));
- }
-
- TheResult = GetCommandLine();
-
- /* If it is NULL, it failed. */
- if(TheResult == NULL)
- {
- Fail("ERROR: The command line returned was NULL -- but should be "
- "a LPWSTR.");
- }
-
- // It's ok that if there is trailing white spaces in "TheResult"
- // Let's trim them.
- p = TheResult + wcslen(TheResult) - 1;
- while (* p == L' ' || * p == L'\t') { printf("%c\n", *p); * p-- = 0 ; }
-
- if(memcmp(TheResult,CommandLine,wcslen(TheResult)*2+2) != 0)
- {
- Fail("ERROR: The command line returned was %s instead of %s "
- "which was the command.\n",
- convertC(TheResult), convertC(CommandLine));
- }
-
- free(CommandLine);
-
- PAL_Terminate();
- return PASS;
-
-}
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/GetCommandLineW/test1/test.cpp b/src/pal/tests/palsuite/miscellaneous/GetCommandLineW/test1/test.cpp
new file mode 100644
index 0000000000..3417c149a0
--- /dev/null
+++ b/src/pal/tests/palsuite/miscellaneous/GetCommandLineW/test1/test.cpp
@@ -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.
+
+/*============================================================
+**
+** Source : test.c
+**
+** Purpose: Test for GetCommandLineW() function
+**
+**
+**=========================================================*/
+
+#define UNICODE
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ LPWSTR TheResult = NULL;
+ WCHAR *CommandLine;
+ int i;
+ WCHAR * p;
+
+ /*
+ * Initialize the PAL and return FAILURE if this fails
+ */
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ CommandLine = (WCHAR*)malloc(1024);
+ wcscpy(CommandLine,convert(argv[0]));
+
+ for(i=1;i<argc;++i)
+ {
+ wcscat(CommandLine,convert(" "));
+ wcscat(CommandLine,convert(argv[i]));
+ }
+
+ TheResult = GetCommandLine();
+
+ /* If it is NULL, it failed. */
+ if(TheResult == NULL)
+ {
+ Fail("ERROR: The command line returned was NULL -- but should be "
+ "a LPWSTR.");
+ }
+
+ // It's ok that if there is trailing white spaces in "TheResult"
+ // Let's trim them.
+ p = TheResult + wcslen(TheResult) - 1;
+ while (* p == L' ' || * p == L'\t') { printf("%c\n", *p); * p-- = 0 ; }
+
+ if(memcmp(TheResult,CommandLine,wcslen(TheResult)*2+2) != 0)
+ {
+ Fail("ERROR: The command line returned was %s instead of %s "
+ "which was the command.\n",
+ convertC(TheResult), convertC(CommandLine));
+ }
+
+ free(CommandLine);
+
+ PAL_Terminate();
+ return PASS;
+
+}
+
+
diff --git a/src/pal/tests/palsuite/miscellaneous/GetComputerNameW/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetComputerNameW/test1/CMakeLists.txt
index 980dae88ae..0ce9ac07b7 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetComputerNameW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GetComputerNameW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_getcomputernamew_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/GetComputerNameW/test1/test.c b/src/pal/tests/palsuite/miscellaneous/GetComputerNameW/test1/test.cpp
index 7a00cad598..7a00cad598 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetComputerNameW/test1/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/GetComputerNameW/test1/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/GetDateFormatW_neg1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/GetDateFormatW_neg1/CMakeLists.txt
index 5a340c6cfb..04ef85b74d 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/GetDateFormatW_neg1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/GetDateFormatW_neg1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetDateFormatW_neg.c
+ GetDateFormatW_neg.cpp
)
add_executable(paltest_getdateformatw_getdateformatw_neg1
diff --git a/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/GetDateFormatW_neg1/GetDateFormatW_neg.c b/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/GetDateFormatW_neg1/GetDateFormatW_neg.c
deleted file mode 100644
index c64dc74cb6..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/GetDateFormatW_neg1/GetDateFormatW_neg.c
+++ /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.
-
-/*=============================================================
-**
-** Source: GetDateFormatW_neg.c
-**
-** Purpose: Negative test the GetDateFormatW API.
-** Call GetDateFormatW by passing an invalid parameter
-**
-**
-**============================================================*/
-#define UNICODE
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
- int err;
- WCHAR *wpFormat;
- LPCSTR lpString = "gg";
- CONST SYSTEMTIME *lpDate = NULL;
- LCID DefaultLocale;
- DWORD dwFlags;
- int DateSize;
- WCHAR *wpBuffer = NULL;
-
- /*Initialize the PAL environment*/
- err = PAL_Initialize(argc, argv);
- if(0 != err)
- {
- return FAIL;
- }
-
- /*convert to a wide character string*/
- wpFormat = convert((char *)lpString);
-
- dwFlags = DATE_USE_ALT_CALENDAR; /*set the flags*/
-
-
- DateSize = 0;
-
- /*retrieve the buffer size*/
- DateSize = GetDateFormatW(
- DefaultLocale, /*system default locale*/
- dwFlags, /*function option*/
- (SYSTEMTIME *)lpDate, /*always is NULL*/
- wpFormat, /*pointer to a picture string*/
- wpBuffer, /*out buffer*/
- DateSize); /*buffer size*/
-
- if(DateSize <= 0)
- {
- free(wpFormat);
- Fail("\nRetrieved an invalid buffer size\n");
- }
-
- wpBuffer = malloc((DateSize + 1)*sizeof(WCHAR));
- if(NULL == wpBuffer)
- {
- free(wpFormat);
- Fail("\nFailed to allocate memory to store the formatted string\n");
- }
-
- /*format a date by passing an invalid locale indentifier*/
- err = GetDateFormatW(
- -1, /*invalid locale identifier*/
- dwFlags, /*function option*/
- (SYSTEMTIME *)lpDate, /*always is NULL, or use system date*/
- wpFormat, /*pointer to a picture string*/
- wpBuffer, /*out buffer*/
- DateSize); /*buffer size*/
-
- free(wpBuffer);
- free(wpFormat);
-
- if(0 != err || GetLastError() != ERROR_INVALID_PARAMETER)
- {
- Fail("\nFailed to call GetDateFormatW for a negative test by "
- "passing an invalid parameter, error code=%d\n", GetLastError());
- }
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/GetDateFormatW_neg1/GetDateFormatW_neg.cpp b/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/GetDateFormatW_neg1/GetDateFormatW_neg.cpp
new file mode 100644
index 0000000000..96a481167f
--- /dev/null
+++ b/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/GetDateFormatW_neg1/GetDateFormatW_neg.cpp
@@ -0,0 +1,85 @@
+// Licensed to the .NET Foundation under one or more 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: GetDateFormatW_neg.c
+**
+** Purpose: Negative test the GetDateFormatW API.
+** Call GetDateFormatW by passing an invalid parameter
+**
+**
+**============================================================*/
+#define UNICODE
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+ int err;
+ WCHAR *wpFormat;
+ LPCSTR lpString = "gg";
+ CONST SYSTEMTIME *lpDate = NULL;
+ LCID DefaultLocale;
+ DWORD dwFlags;
+ int DateSize;
+ WCHAR *wpBuffer = NULL;
+
+ /*Initialize the PAL environment*/
+ err = PAL_Initialize(argc, argv);
+ if(0 != err)
+ {
+ return FAIL;
+ }
+
+ /*convert to a wide character string*/
+ wpFormat = convert((char *)lpString);
+
+ dwFlags = DATE_USE_ALT_CALENDAR; /*set the flags*/
+
+
+ DateSize = 0;
+
+ /*retrieve the buffer size*/
+ DateSize = GetDateFormatW(
+ DefaultLocale, /*system default locale*/
+ dwFlags, /*function option*/
+ (SYSTEMTIME *)lpDate, /*always is NULL*/
+ wpFormat, /*pointer to a picture string*/
+ wpBuffer, /*out buffer*/
+ DateSize); /*buffer size*/
+
+ if(DateSize <= 0)
+ {
+ free(wpFormat);
+ Fail("\nRetrieved an invalid buffer size\n");
+ }
+
+ wpBuffer = (WCHAR*)malloc((DateSize + 1)*sizeof(WCHAR));
+ if(NULL == wpBuffer)
+ {
+ free(wpFormat);
+ Fail("\nFailed to allocate memory to store the formatted string\n");
+ }
+
+ /*format a date by passing an invalid locale indentifier*/
+ err = GetDateFormatW(
+ -1, /*invalid locale identifier*/
+ dwFlags, /*function option*/
+ (SYSTEMTIME *)lpDate, /*always is NULL, or use system date*/
+ wpFormat, /*pointer to a picture string*/
+ wpBuffer, /*out buffer*/
+ DateSize); /*buffer size*/
+
+ free(wpBuffer);
+ free(wpFormat);
+
+ if(0 != err || GetLastError() != ERROR_INVALID_PARAMETER)
+ {
+ Fail("\nFailed to call GetDateFormatW for a negative test by "
+ "passing an invalid parameter, error code=%d\n", GetLastError());
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/GetDateFormatW_neg2/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/GetDateFormatW_neg2/CMakeLists.txt
index 646de9160b..fcd56fc7f2 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/GetDateFormatW_neg2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/GetDateFormatW_neg2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetDateFormatW_neg.c
+ GetDateFormatW_neg.cpp
)
add_executable(paltest_getdateformatw_getdateformatw_neg2
diff --git a/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/GetDateFormatW_neg2/GetDateFormatW_neg.c b/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/GetDateFormatW_neg2/GetDateFormatW_neg.c
deleted file mode 100644
index 676038f03a..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/GetDateFormatW_neg2/GetDateFormatW_neg.c
+++ /dev/null
@@ -1,98 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: GetDateFormatW_neg.c
-**
-** Purpose: Negative test the GetDateFormatW API.
-** Call GetDateFormatW by passing an invalid flag
-**
-**
-**============================================================*/
-#define UNICODE
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
- int err;
- WCHAR *wpFormat;
- LPCSTR lpString = "gg";
- CONST SYSTEMTIME *lpDate = NULL;
- LCID DefaultLocale;
- DWORD dwFlags;
- int DateSize;
- WCHAR *wpBuffer = NULL;
-
- /*Initialize the PAL environment*/
- err = PAL_Initialize(argc, argv);
- if(0 != err)
- {
- return FAIL;
- }
-
- /*convert to a wide character string*/
- wpFormat = convert((char *)lpString);
-
- /*
- DefaultLocale = GetSystemDefaultLCID() which is not defined in PAL;
-
- LOCALE_SYSTEM_DEFAULT = MAKELCID(LANG_SYSTEM_DEFAULT, SORT_DEFAULT)
-
- LANG_SYSTEM_DEFAULT = MAKELANGID(LANG_NEUTRAL,SUBLANG_SYS_DEFAULT);
- SUBLANG_SYS_DEFAULT is not defined in PAL, here use hardcoding,
- the value is from winnt.h
- */
-
- DefaultLocale = MAKELCID(MAKELANGID(LANG_NEUTRAL, 0x02), SORT_DEFAULT);
-
- dwFlags = DATE_USE_ALT_CALENDAR; /*set the flags*/
-
-
- DateSize = 0;
-
- /*retrieve the buffer size*/
- DateSize = GetDateFormatW(
- DefaultLocale, /*system default locale*/
- dwFlags, /*function option*/
- (SYSTEMTIME *)lpDate, /*always is NULL*/
- wpFormat, /*pointer to a picture string*/
- wpBuffer, /*out buffer*/
- DateSize); /*buffer size*/
-
- if(DateSize <= 0)
- {
- free(wpFormat);
- Fail("\nRetrieved an invalid buffer size\n");
- }
-
- wpBuffer = malloc((DateSize + 1)*sizeof(WCHAR));
- if(NULL == wpBuffer)
- {
- free(wpFormat);
- Fail("\nFailed to allocate memory to store the formatted string\n");
- }
-
- err = GetDateFormatW(
- DefaultLocale, /*system default locale*/
- 0x00000001|0x00000008,/*DATE_SHORTDATE|DATE_YEARMONTH */
- /*an invalid flag*/
- (SYSTEMTIME *)lpDate, /*always is NULL, or use system date*/
- wpFormat, /*pointer to a picture string*/
- wpBuffer, /*out buffer*/
- DateSize); /*buffer size*/
-
- free(wpBuffer);
- free(wpFormat);
-
- if(0 != err || GetLastError() != ERROR_INVALID_FLAGS)
- {
- Fail("\nFailed to call GetDateFormatW for a negative test by "
- "passing an invalid flag, error code=%d\n", GetLastError());
- }
-
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/GetDateFormatW_neg2/GetDateFormatW_neg.cpp b/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/GetDateFormatW_neg2/GetDateFormatW_neg.cpp
new file mode 100644
index 0000000000..43f32cf69e
--- /dev/null
+++ b/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/GetDateFormatW_neg2/GetDateFormatW_neg.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.
+
+/*=============================================================
+**
+** Source: GetDateFormatW_neg.c
+**
+** Purpose: Negative test the GetDateFormatW API.
+** Call GetDateFormatW by passing an invalid flag
+**
+**
+**============================================================*/
+#define UNICODE
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+ int err;
+ WCHAR *wpFormat;
+ LPCSTR lpString = "gg";
+ CONST SYSTEMTIME *lpDate = NULL;
+ LCID DefaultLocale;
+ DWORD dwFlags;
+ int DateSize;
+ WCHAR *wpBuffer = NULL;
+
+ /*Initialize the PAL environment*/
+ err = PAL_Initialize(argc, argv);
+ if(0 != err)
+ {
+ return FAIL;
+ }
+
+ /*convert to a wide character string*/
+ wpFormat = convert((char *)lpString);
+
+ /*
+ DefaultLocale = GetSystemDefaultLCID() which is not defined in PAL;
+
+ LOCALE_SYSTEM_DEFAULT = MAKELCID(LANG_SYSTEM_DEFAULT, SORT_DEFAULT)
+
+ LANG_SYSTEM_DEFAULT = MAKELANGID(LANG_NEUTRAL,SUBLANG_SYS_DEFAULT);
+ SUBLANG_SYS_DEFAULT is not defined in PAL, here use hardcoding,
+ the value is from winnt.h
+ */
+
+ DefaultLocale = MAKELCID(MAKELANGID(LANG_NEUTRAL, 0x02), SORT_DEFAULT);
+
+ dwFlags = DATE_USE_ALT_CALENDAR; /*set the flags*/
+
+
+ DateSize = 0;
+
+ /*retrieve the buffer size*/
+ DateSize = GetDateFormatW(
+ DefaultLocale, /*system default locale*/
+ dwFlags, /*function option*/
+ (SYSTEMTIME *)lpDate, /*always is NULL*/
+ wpFormat, /*pointer to a picture string*/
+ wpBuffer, /*out buffer*/
+ DateSize); /*buffer size*/
+
+ if(DateSize <= 0)
+ {
+ free(wpFormat);
+ Fail("\nRetrieved an invalid buffer size\n");
+ }
+
+ wpBuffer = (WCHAR*)malloc((DateSize + 1)*sizeof(WCHAR));
+ if(NULL == wpBuffer)
+ {
+ free(wpFormat);
+ Fail("\nFailed to allocate memory to store the formatted string\n");
+ }
+
+ err = GetDateFormatW(
+ DefaultLocale, /*system default locale*/
+ 0x00000001|0x00000008,/*DATE_SHORTDATE|DATE_YEARMONTH */
+ /*an invalid flag*/
+ (SYSTEMTIME *)lpDate, /*always is NULL, or use system date*/
+ wpFormat, /*pointer to a picture string*/
+ wpBuffer, /*out buffer*/
+ DateSize); /*buffer size*/
+
+ free(wpBuffer);
+ free(wpFormat);
+
+ if(0 != err || GetLastError() != ERROR_INVALID_FLAGS)
+ {
+ Fail("\nFailed to call GetDateFormatW for a negative test by "
+ "passing an invalid flag, error code=%d\n", GetLastError());
+ }
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/test1/CMakeLists.txt
index 8c1e4b024e..bd86370611 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- GetDateFormatW.c
+ GetDateFormatW.cpp
)
add_executable(paltest_getdateformatw_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/test1/GetDateFormatW.c b/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/test1/GetDateFormatW.c
deleted file mode 100644
index 264e397a49..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/test1/GetDateFormatW.c
+++ /dev/null
@@ -1,100 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: GetDateFormatW.c
-**
-** Purpose: Positive test the GetDateFormatW API.
-** Call GetDateFormatW to format a date string for
-** a specified locale
-**
-**
-**============================================================*/
-#define UNICODE
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
- int err;
- WCHAR *wpFormat;
- LPCSTR lpString = "gg";
- CONST SYSTEMTIME *lpDate = NULL;
- LCID DefaultLocale;
- DWORD dwFlags;
- int DateSize;
- WCHAR *wpBuffer = NULL;
-
- /*Initialize the PAL environment*/
- err = PAL_Initialize(argc, argv);
- if(0 != err)
- {
- return FAIL;
- }
-
- /*convert to a wide character string*/
- wpFormat = convert((char *)lpString);
-
- /*
- DefaultLocale = GetSystemDefaultLCID() which is not defined in PAL;
-
- LOCALE_SYSTEM_DEFAULT = MAKELCID(LANG_SYSTEM_DEFAULT, SORT_DEFAULT)
-
- LANG_SYSTEM_DEFAULT = MAKELANGID(LANG_NEUTRAL,SUBLANG_SYS_DEFAULT);
- SUBLANG_SYS_DEFAULT is not defined in PAL, here use hardcoding,
- the value is from winnt.h
- */
- DefaultLocale = MAKELCID(MAKELANGID(LANG_NEUTRAL, 0x02), SORT_DEFAULT);
-
- dwFlags = DATE_USE_ALT_CALENDAR; /*set the flags*/
-
-
- DateSize = 0;
-
- /*retrieve the buffer size*/
- DateSize = GetDateFormatW(
- DefaultLocale, /*system default locale*/
- dwFlags, /*function option*/
- (SYSTEMTIME *)lpDate, /*always is NULL*/
- wpFormat, /*pointer to a picture string*/
- wpBuffer, /*out buffer*/
- DateSize); /*buffer size*/
-
- if(DateSize <= 0)
- {
- free(wpFormat);
- Fail("\nRetrieved an invalid buffer size\n");
- }
-
-
- wpBuffer = malloc((DateSize+1)*sizeof(WCHAR));
- if(NULL == wpBuffer)
- {
- free(wpFormat);
- Fail("\nFailed to allocate memory to store a formatted string\n");
- }
-
- /*retrieve the formatted string for a specified locale*/
- err = GetDateFormatW(
- DefaultLocale, /*system default locale*/
- dwFlags, /*function option*/
- (SYSTEMTIME *)lpDate, /*always is NULL*/
- wpFormat, /*pointer to a picture string*/
- wpBuffer, /*out buffer*/
- DateSize); /*buffer size*/
-
- if(0 == err)
- {
- free(wpBuffer);
- free(wpFormat);
- Fail("\nFailed to call GetDateFormatW to format a system data "
- "as a data string for system default locale!\n");
- }
-
- free(wpBuffer);
- free(wpFormat);
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/test1/GetDateFormatW.cpp b/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/test1/GetDateFormatW.cpp
new file mode 100644
index 0000000000..6e3c3b4894
--- /dev/null
+++ b/src/pal/tests/palsuite/miscellaneous/GetDateFormatW/test1/GetDateFormatW.cpp
@@ -0,0 +1,100 @@
+// Licensed to the .NET Foundation under one or more 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: GetDateFormatW.c
+**
+** Purpose: Positive test the GetDateFormatW API.
+** Call GetDateFormatW to format a date string for
+** a specified locale
+**
+**
+**============================================================*/
+#define UNICODE
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+ int err;
+ WCHAR *wpFormat;
+ LPCSTR lpString = "gg";
+ CONST SYSTEMTIME *lpDate = NULL;
+ LCID DefaultLocale;
+ DWORD dwFlags;
+ int DateSize;
+ WCHAR *wpBuffer = NULL;
+
+ /*Initialize the PAL environment*/
+ err = PAL_Initialize(argc, argv);
+ if(0 != err)
+ {
+ return FAIL;
+ }
+
+ /*convert to a wide character string*/
+ wpFormat = convert((char *)lpString);
+
+ /*
+ DefaultLocale = GetSystemDefaultLCID() which is not defined in PAL;
+
+ LOCALE_SYSTEM_DEFAULT = MAKELCID(LANG_SYSTEM_DEFAULT, SORT_DEFAULT)
+
+ LANG_SYSTEM_DEFAULT = MAKELANGID(LANG_NEUTRAL,SUBLANG_SYS_DEFAULT);
+ SUBLANG_SYS_DEFAULT is not defined in PAL, here use hardcoding,
+ the value is from winnt.h
+ */
+ DefaultLocale = MAKELCID(MAKELANGID(LANG_NEUTRAL, 0x02), SORT_DEFAULT);
+
+ dwFlags = DATE_USE_ALT_CALENDAR; /*set the flags*/
+
+
+ DateSize = 0;
+
+ /*retrieve the buffer size*/
+ DateSize = GetDateFormatW(
+ DefaultLocale, /*system default locale*/
+ dwFlags, /*function option*/
+ (SYSTEMTIME *)lpDate, /*always is NULL*/
+ wpFormat, /*pointer to a picture string*/
+ wpBuffer, /*out buffer*/
+ DateSize); /*buffer size*/
+
+ if(DateSize <= 0)
+ {
+ free(wpFormat);
+ Fail("\nRetrieved an invalid buffer size\n");
+ }
+
+
+ wpBuffer = (WCHAR*)malloc((DateSize+1)*sizeof(WCHAR));
+ if(NULL == wpBuffer)
+ {
+ free(wpFormat);
+ Fail("\nFailed to allocate memory to store a formatted string\n");
+ }
+
+ /*retrieve the formatted string for a specified locale*/
+ err = GetDateFormatW(
+ DefaultLocale, /*system default locale*/
+ dwFlags, /*function option*/
+ (SYSTEMTIME *)lpDate, /*always is NULL*/
+ wpFormat, /*pointer to a picture string*/
+ wpBuffer, /*out buffer*/
+ DateSize); /*buffer size*/
+
+ if(0 == err)
+ {
+ free(wpBuffer);
+ free(wpFormat);
+ Fail("\nFailed to call GetDateFormatW to format a system data "
+ "as a data string for system default locale!\n");
+ }
+
+ free(wpBuffer);
+ free(wpFormat);
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentStringsW/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentStringsW/test1/CMakeLists.txt
index 306400e558..3a745fdbd3 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentStringsW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentStringsW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_getenvironmentstringsw_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentStringsW/test1/test.c b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentStringsW/test1/test.cpp
index 2bd9153e59..2bd9153e59 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentStringsW/test1/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentStringsW/test1/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test1/CMakeLists.txt
index 184a6ef1f0..0721fd60b7 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_getenvironmentvariablea_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test1/test.c b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test1/test.c
deleted file mode 100644
index 8862e823bc..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test1/test.c
+++ /dev/null
@@ -1,84 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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 GetEnvironmentVariable() function
-** Assign a properly sized buffer and get an environment
-** variable, check to ensure it returns the correct values.
-**
-**
-**=========================================================*/
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[]) {
-
- /* Define some buffers needed for the function */
- char * pResultBuffer = NULL;
- int size = 0;
-
- /* A place to stash the returned values */
- int ReturnValueForLargeBuffer = 0;
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- /* Recieve and allocate the correct amount of memory for the buffer */
- size = ReturnValueForLargeBuffer = GetEnvironmentVariable("PATH",
- pResultBuffer,
- 0);
- pResultBuffer = malloc(size);
- if ( pResultBuffer == NULL )
- {
- Fail("ERROR: Failed to allocate memory for pResultBuffer pointer. "
- "Can't properly exec test case without this.\n");
- }
-
-
- /* Normal case, PATH should fit into this buffer */
- ReturnValueForLargeBuffer = GetEnvironmentVariable("PATH",
- pResultBuffer,
- size);
-
- /* Ensure that it returned a positive value */
- if(ReturnValueForLargeBuffer <= 0)
- {
- free(pResultBuffer);
-
- Fail("The return was %d, which indicates that the function failed.\n",
- ReturnValueForLargeBuffer);
- }
-
- /* Ensure that it succeeded and copied the correct number of characters.
- If this is true, then the return value should be one less of the size of
- the buffer. (Doesn't include that NULL byte)
- */
-
- if(ReturnValueForLargeBuffer != size-1)
- {
- free(pResultBuffer);
-
- Fail("The value returned was %d when it should have been %d. "
- "This should be the number of characters copied, minus the "
- "NULL byte.\n",ReturnValueForLargeBuffer, size-1);
- }
-
-
- free(pResultBuffer);
-
- PAL_Terminate();
- return PASS;
-}
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test1/test.cpp b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test1/test.cpp
new file mode 100644
index 0000000000..23e9974467
--- /dev/null
+++ b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test1/test.cpp
@@ -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.
+
+/*============================================================
+**
+** Source : test.c
+**
+** Purpose: Test for GetEnvironmentVariable() function
+** Assign a properly sized buffer and get an environment
+** variable, check to ensure it returns the correct values.
+**
+**
+**=========================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[]) {
+
+ /* Define some buffers needed for the function */
+ char * pResultBuffer = NULL;
+ int size = 0;
+
+ /* A place to stash the returned values */
+ int ReturnValueForLargeBuffer = 0;
+
+ /*
+ * Initialize the PAL and return FAILURE if this fails
+ */
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ /* Recieve and allocate the correct amount of memory for the buffer */
+ size = ReturnValueForLargeBuffer = GetEnvironmentVariable("PATH",
+ pResultBuffer,
+ 0);
+ pResultBuffer = (char*)malloc(size);
+ if ( pResultBuffer == NULL )
+ {
+ Fail("ERROR: Failed to allocate memory for pResultBuffer pointer. "
+ "Can't properly exec test case without this.\n");
+ }
+
+
+ /* Normal case, PATH should fit into this buffer */
+ ReturnValueForLargeBuffer = GetEnvironmentVariable("PATH",
+ pResultBuffer,
+ size);
+
+ /* Ensure that it returned a positive value */
+ if(ReturnValueForLargeBuffer <= 0)
+ {
+ free(pResultBuffer);
+
+ Fail("The return was %d, which indicates that the function failed.\n",
+ ReturnValueForLargeBuffer);
+ }
+
+ /* Ensure that it succeeded and copied the correct number of characters.
+ If this is true, then the return value should be one less of the size of
+ the buffer. (Doesn't include that NULL byte)
+ */
+
+ if(ReturnValueForLargeBuffer != size-1)
+ {
+ free(pResultBuffer);
+
+ Fail("The value returned was %d when it should have been %d. "
+ "This should be the number of characters copied, minus the "
+ "NULL byte.\n",ReturnValueForLargeBuffer, size-1);
+ }
+
+
+ free(pResultBuffer);
+
+ PAL_Terminate();
+ return PASS;
+}
+
+
+
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test2/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test2/CMakeLists.txt
index abfd73f458..a9be983369 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_getenvironmentvariablea_test2
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test2/test.c b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test2/test.cpp
index d26588e907..d26588e907 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test2/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test2/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test3/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test3/CMakeLists.txt
index a63c11b1a3..1c35eba54d 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_getenvironmentvariablea_test3
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test3/test.c b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test3/test.cpp
index b51e139c95..b51e139c95 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test3/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test3/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test4/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test4/CMakeLists.txt
index 76cfdb6d49..331ea8ca6b 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_getenvironmentvariablea_test4
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test4/test.c b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test4/test.c
deleted file mode 100644
index 1fea5719b4..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test4/test.c
+++ /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.
-
-/*============================================================
-**
-** Source : test.c
-**
-** Purpose: Test for GetEnvironmentVariable() function
-** Set an Environment Variable, then use GetEnvironmentVariable to
-** retrieve it -- ensure that it retrieves properly.
-**
-**
-**=========================================================*/
-
-/* Depends on SetEnvironmentVariableW (because we're implmenting
- the wide version) and strcmp()
-*/
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[]) {
-
- /* Define some buffers needed for the function */
- char * pResultBuffer = NULL;
- WCHAR SomeEnvironmentVariable[] = {'P','A','L','T','E','S','T','\0'};
- WCHAR TheEnvironmentValue[] = {'T','E','S','T','\0'};
- int size = 0;
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- SetEnvironmentVariableW(SomeEnvironmentVariable,
- TheEnvironmentValue);
-
-
- /* Normal case, PATH should fit into this buffer */
- size = GetEnvironmentVariable("PALTEST", // Variable Name
- pResultBuffer, // Buffer for Value
- 0); // Buffer size
-
- pResultBuffer = malloc(size);
- if ( pResultBuffer == NULL )
- {
- Fail("ERROR: Failed to allocate memory for pResultBuffer pointer. "
- "Can't properly exec test case without this.\n");
- }
-
-
- GetEnvironmentVariable("PALTEST",
- pResultBuffer,
- size);
-
- if(strcmp(pResultBuffer,"TEST") != 0)
- {
- free(pResultBuffer);
- Fail("ERROR: The value in the buffer should have been 'TEST' but "
- "was really '%s'.\n",pResultBuffer);
-
- }
-
- free(pResultBuffer);
-
- PAL_Terminate();
- return PASS;
-}
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test4/test.cpp b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test4/test.cpp
new file mode 100644
index 0000000000..a09eb883e3
--- /dev/null
+++ b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test4/test.cpp
@@ -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.
+
+/*============================================================
+**
+** Source : test.c
+**
+** Purpose: Test for GetEnvironmentVariable() function
+** Set an Environment Variable, then use GetEnvironmentVariable to
+** retrieve it -- ensure that it retrieves properly.
+**
+**
+**=========================================================*/
+
+/* Depends on SetEnvironmentVariableW (because we're implmenting
+ the wide version) and strcmp()
+*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[]) {
+
+ /* Define some buffers needed for the function */
+ char * pResultBuffer = NULL;
+ WCHAR SomeEnvironmentVariable[] = {'P','A','L','T','E','S','T','\0'};
+ WCHAR TheEnvironmentValue[] = {'T','E','S','T','\0'};
+ int size = 0;
+
+ /*
+ * Initialize the PAL and return FAILURE if this fails
+ */
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ SetEnvironmentVariableW(SomeEnvironmentVariable,
+ TheEnvironmentValue);
+
+
+ /* Normal case, PATH should fit into this buffer */
+ size = GetEnvironmentVariable("PALTEST", // Variable Name
+ pResultBuffer, // Buffer for Value
+ 0); // Buffer size
+
+ pResultBuffer = (char*)malloc(size);
+ if ( pResultBuffer == NULL )
+ {
+ Fail("ERROR: Failed to allocate memory for pResultBuffer pointer. "
+ "Can't properly exec test case without this.\n");
+ }
+
+
+ GetEnvironmentVariable("PALTEST",
+ pResultBuffer,
+ size);
+
+ if(strcmp(pResultBuffer,"TEST") != 0)
+ {
+ free(pResultBuffer);
+ Fail("ERROR: The value in the buffer should have been 'TEST' but "
+ "was really '%s'.\n",pResultBuffer);
+
+ }
+
+ free(pResultBuffer);
+
+ PAL_Terminate();
+ return PASS;
+}
+
+
+
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test5/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test5/CMakeLists.txt
index 548d86bb03..69bedf4947 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_getenvironmentvariablea_test5
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test5/test5.c b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test5/test5.c
deleted file mode 100644
index 8d63a1aecb..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test5/test5.c
+++ /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.
-
-/*============================================================
-** Source : test5.c
-**
-** Purpose: Test for GetEnvironmentVariableA() function
-** Create environment variables that differ only
-** in case and verify that they return the appropriate
-** value on the BSD environment.
-**
-**
-===========================================================*/
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
-
-#if WIN32
-
- return PASS;
-
-#else
-
- /* Define some buffers needed for the function */
- char * pResultBuffer = NULL;
-
- char FirstEnvironmentVariable[] = {"PALTEST"};
- char FirstEnvironmentValue[] = {"FIRST"};
-
- char SecondEnvironmentVariable[] = {"paltest"};
- char SecondEnvironmentValue[] = {"SECOND"};
-
- DWORD size = 0;
- BOOL bRc = TRUE;
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- /* Set the first environment variable */
- bRc = SetEnvironmentVariableA(FirstEnvironmentVariable,
- FirstEnvironmentValue);
-
- if(!bRc)
- {
- Fail("ERROR: SetEnvironmentVariable failed to set a "
- "proper environment variable with error %u.\n", GetLastError());
- }
-
-
- /* Normal case, PATH should fit into this buffer */
- size = GetEnvironmentVariableA(FirstEnvironmentVariable,
- pResultBuffer,
- 0);
-
- /* To account for the null character at the end of the string */
- size = size + 1;
-
- pResultBuffer = malloc(sizeof(char)*size);
- if ( pResultBuffer == NULL )
- {
- Fail("ERROR: Failed to allocate memory for pResultBuffer pointer\n.");
- }
-
- /* Try to retrieve the value of the first environment variable */
- GetEnvironmentVariableA(FirstEnvironmentVariable,
- pResultBuffer,
- size);
-
- if ( pResultBuffer == NULL )
- {
- free(pResultBuffer);
- Fail("ERROR: GetEnvironmentVariable failed to return a value "
- "from a proper environment variable with error %u.\n",
- GetLastError());
- }
-
- /* Compare the strings to see that the correct variable was returned */
- if(strcmp(pResultBuffer,FirstEnvironmentValue) != 0)
- {
- free(pResultBuffer);
- Fail("ERROR: The value in the buffer should have been '%s' but "
- "was really '%s'.\n",FirstEnvironmentValue, pResultBuffer);
- }
-
- free(pResultBuffer);
-
- /* Set the second environment Variable */
- bRc = SetEnvironmentVariableA(SecondEnvironmentVariable,
- SecondEnvironmentValue);
-
- if(!bRc)
- {
- Fail("ERROR: SetEnvironmentVariable failed to set a "
- "proper environment variable with error %u.\n",
- GetLastError());
- }
-
- /* Reallocate the memory for the string */
- pResultBuffer = malloc(sizeof(char)*size);
- if ( pResultBuffer == NULL )
- {
- Fail("ERROR: Failed to allocate memory for pResultBuffer pointer.");
- }
-
- /* Try retrieving the value of the first variable, even though the
- second variable has the same spelling and only differs in case */
- GetEnvironmentVariableA(FirstEnvironmentVariable,
- pResultBuffer,
- size);
-
- if ( pResultBuffer == NULL )
- {
- free(pResultBuffer);
- Fail("ERROR: GetEnvironmentVariable failed to return a value "
- "from a proper environment variable with error %u.\n",
- GetLastError());
- }
-
- /* Compare the two strings to confirm that the right value is returned */
- if(strcmp(pResultBuffer,FirstEnvironmentValue) != 0)
- {
- free(pResultBuffer);
- Fail("ERROR: The value in the buffer should have been '%s' but "
- "was really '%s'.\n",FirstEnvironmentValue,pResultBuffer);
- }
-
- free(pResultBuffer);
-
- PAL_Terminate();
- return PASS;
-
-#endif
-}
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test5/test5.cpp b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test5/test5.cpp
new file mode 100644
index 0000000000..19a4d25b64
--- /dev/null
+++ b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test5/test5.cpp
@@ -0,0 +1,145 @@
+// Licensed to the .NET Foundation under one or more 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 : test5.c
+**
+** Purpose: Test for GetEnvironmentVariableA() function
+** Create environment variables that differ only
+** in case and verify that they return the appropriate
+** value on the BSD environment.
+**
+**
+===========================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+
+#if WIN32
+
+ return PASS;
+
+#else
+
+ /* Define some buffers needed for the function */
+ char * pResultBuffer = NULL;
+
+ char FirstEnvironmentVariable[] = {"PALTEST"};
+ char FirstEnvironmentValue[] = {"FIRST"};
+
+ char SecondEnvironmentVariable[] = {"paltest"};
+ char SecondEnvironmentValue[] = {"SECOND"};
+
+ DWORD size = 0;
+ BOOL bRc = TRUE;
+
+ /*
+ * Initialize the PAL and return FAILURE if this fails
+ */
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ /* Set the first environment variable */
+ bRc = SetEnvironmentVariableA(FirstEnvironmentVariable,
+ FirstEnvironmentValue);
+
+ if(!bRc)
+ {
+ Fail("ERROR: SetEnvironmentVariable failed to set a "
+ "proper environment variable with error %u.\n", GetLastError());
+ }
+
+
+ /* Normal case, PATH should fit into this buffer */
+ size = GetEnvironmentVariableA(FirstEnvironmentVariable,
+ pResultBuffer,
+ 0);
+
+ /* To account for the null character at the end of the string */
+ size = size + 1;
+
+ pResultBuffer = (char*)malloc(sizeof(char)*size);
+ if ( pResultBuffer == NULL )
+ {
+ Fail("ERROR: Failed to allocate memory for pResultBuffer pointer\n.");
+ }
+
+ /* Try to retrieve the value of the first environment variable */
+ GetEnvironmentVariableA(FirstEnvironmentVariable,
+ pResultBuffer,
+ size);
+
+ if ( pResultBuffer == NULL )
+ {
+ free(pResultBuffer);
+ Fail("ERROR: GetEnvironmentVariable failed to return a value "
+ "from a proper environment variable with error %u.\n",
+ GetLastError());
+ }
+
+ /* Compare the strings to see that the correct variable was returned */
+ if(strcmp(pResultBuffer,FirstEnvironmentValue) != 0)
+ {
+ free(pResultBuffer);
+ Fail("ERROR: The value in the buffer should have been '%s' but "
+ "was really '%s'.\n",FirstEnvironmentValue, pResultBuffer);
+ }
+
+ free(pResultBuffer);
+
+ /* Set the second environment Variable */
+ bRc = SetEnvironmentVariableA(SecondEnvironmentVariable,
+ SecondEnvironmentValue);
+
+ if(!bRc)
+ {
+ Fail("ERROR: SetEnvironmentVariable failed to set a "
+ "proper environment variable with error %u.\n",
+ GetLastError());
+ }
+
+ /* Reallocate the memory for the string */
+ pResultBuffer = (char*)malloc(sizeof(char)*size);
+ if ( pResultBuffer == NULL )
+ {
+ Fail("ERROR: Failed to allocate memory for pResultBuffer pointer.");
+ }
+
+ /* Try retrieving the value of the first variable, even though the
+ second variable has the same spelling and only differs in case */
+ GetEnvironmentVariableA(FirstEnvironmentVariable,
+ pResultBuffer,
+ size);
+
+ if ( pResultBuffer == NULL )
+ {
+ free(pResultBuffer);
+ Fail("ERROR: GetEnvironmentVariable failed to return a value "
+ "from a proper environment variable with error %u.\n",
+ GetLastError());
+ }
+
+ /* Compare the two strings to confirm that the right value is returned */
+ if(strcmp(pResultBuffer,FirstEnvironmentValue) != 0)
+ {
+ free(pResultBuffer);
+ Fail("ERROR: The value in the buffer should have been '%s' but "
+ "was really '%s'.\n",FirstEnvironmentValue,pResultBuffer);
+ }
+
+ free(pResultBuffer);
+
+ PAL_Terminate();
+ return PASS;
+
+#endif
+}
+
+
+
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test6/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test6/CMakeLists.txt
index a0873bb7e7..38c186740f 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test6.c
+ test6.cpp
)
add_executable(paltest_getenvironmentvariablea_test6
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test6/test6.c b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test6/test6.c
deleted file mode 100644
index 8ef7571f59..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test6/test6.c
+++ /dev/null
@@ -1,99 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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 : test6.c
-**
-** Purpose: Test for GetEnvironmentVariableA() function
-** Create environment variables that differ only
-** in case and verify that they return the appropriate
-** value on the BSD environment.
-**
-
-**
-===========================================================*/
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
-
-#if WIN32
-
- /* Define some buffers needed for the function */
- char * pResultBuffer = NULL;
-
- char FirstEnvironmentVariable[] = {"PALTEST"};
- char FirstEnvironmentValue[] = {"FIRST"};
- char ModifiedEnvVar[] = {"paltest"};
-
- DWORD size = 0;
- BOOL bRc = TRUE;
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- /* Set the first environment variable */
- bRc = SetEnvironmentVariableA(FirstEnvironmentVariable,
- FirstEnvironmentValue);
-
- if(!bRc)
- {
- Fail("ERROR: SetEnvironmentVariable failed to set a "
- "proper environment variable with error %u.\n",
- GetLastError());
- }
-
- /* Normal case, PATH should fit into this buffer */
- size = GetEnvironmentVariableA(ModifiedEnvVar,
- pResultBuffer,
- 0);
-
- /* To account for the nul character at the end of the string */
- size = size + 1;
-
- pResultBuffer = malloc(sizeof(char)*size);
- if ( pResultBuffer == NULL )
- {
- Fail("ERROR: Failed to allocate memory for pResultBuffer pointer.\n");
- }
-
- /* Try to retrieve the value of the first environment variable */
- GetEnvironmentVariableA(ModifiedEnvVar,
- pResultBuffer,
- size);
-
- if ( pResultBuffer == NULL )
- {
- free(pResultBuffer);
- Fail("ERROR: GetEnvironmentVariable failed to return a value "
- "from a proper environment variable with error %u.\n",
- GetLastError());
- }
-
- /* Compare the strings to see that the correct variable was returned */
- if(strcmp(pResultBuffer,FirstEnvironmentValue) != 0)
- {
- free(pResultBuffer);
- Fail("ERROR: The value in the buffer should have been '%s' but "
- "was really '%s'.\n",FirstEnvironmentValue, pResultBuffer);
- }
-
- free(pResultBuffer);
-
- PAL_Terminate();
- return PASS;
-
-
-#else
-
- return PASS;
-#endif
-}
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test6/test6.cpp b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test6/test6.cpp
new file mode 100644
index 0000000000..837036a0a9
--- /dev/null
+++ b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableA/test6/test6.cpp
@@ -0,0 +1,99 @@
+// Licensed to the .NET Foundation under one or more 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 : test6.c
+**
+** Purpose: Test for GetEnvironmentVariableA() function
+** Create environment variables that differ only
+** in case and verify that they return the appropriate
+** value on the BSD environment.
+**
+
+**
+===========================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+
+#if WIN32
+
+ /* Define some buffers needed for the function */
+ char * pResultBuffer = NULL;
+
+ char FirstEnvironmentVariable[] = {"PALTEST"};
+ char FirstEnvironmentValue[] = {"FIRST"};
+ char ModifiedEnvVar[] = {"paltest"};
+
+ DWORD size = 0;
+ BOOL bRc = TRUE;
+
+ /*
+ * Initialize the PAL and return FAILURE if this fails
+ */
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ /* Set the first environment variable */
+ bRc = SetEnvironmentVariableA(FirstEnvironmentVariable,
+ FirstEnvironmentValue);
+
+ if(!bRc)
+ {
+ Fail("ERROR: SetEnvironmentVariable failed to set a "
+ "proper environment variable with error %u.\n",
+ GetLastError());
+ }
+
+ /* Normal case, PATH should fit into this buffer */
+ size = GetEnvironmentVariableA(ModifiedEnvVar,
+ pResultBuffer,
+ 0);
+
+ /* To account for the nul character at the end of the string */
+ size = size + 1;
+
+ pResultBuffer = (char*)malloc(sizeof(char)*size);
+ if ( pResultBuffer == NULL )
+ {
+ Fail("ERROR: Failed to allocate memory for pResultBuffer pointer.\n");
+ }
+
+ /* Try to retrieve the value of the first environment variable */
+ GetEnvironmentVariableA(ModifiedEnvVar,
+ pResultBuffer,
+ size);
+
+ if ( pResultBuffer == NULL )
+ {
+ free(pResultBuffer);
+ Fail("ERROR: GetEnvironmentVariable failed to return a value "
+ "from a proper environment variable with error %u.\n",
+ GetLastError());
+ }
+
+ /* Compare the strings to see that the correct variable was returned */
+ if(strcmp(pResultBuffer,FirstEnvironmentValue) != 0)
+ {
+ free(pResultBuffer);
+ Fail("ERROR: The value in the buffer should have been '%s' but "
+ "was really '%s'.\n",FirstEnvironmentValue, pResultBuffer);
+ }
+
+ free(pResultBuffer);
+
+ PAL_Terminate();
+ return PASS;
+
+
+#else
+
+ return PASS;
+#endif
+}
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test1/CMakeLists.txt
index 567c992461..a3cb878ef4 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_getenvironmentvariablew_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test1/test.c b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test1/test.c
deleted file mode 100644
index 6c764509d0..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test1/test.c
+++ /dev/null
@@ -1,79 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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 GetEnvironmentVariable() function
-**
-**
-**=========================================================*/
-
-#define UNICODE
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
-
- /* Define some buffers needed for the function */
- WCHAR * pResultBuffer = NULL;
- int size = 0;
-
- /* A place to stash the returned values */
- int ReturnValueForLargeBuffer = 0;
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- /* Recieve and allocate the correct amount of memory for the buffer */
- size = ReturnValueForLargeBuffer =
- GetEnvironmentVariable(convert("PATH"),
- pResultBuffer,
- 0);
-
- pResultBuffer = malloc(size*sizeof(WCHAR));
- if ( pResultBuffer == NULL )
- {
- Fail("ERROR: Failed to allocate memory for pResultBuffer pointer. "
- "Can't properly exec test case without this.\n");
- }
-
-
- /* Normal case, PATH should fit into this buffer */
- ReturnValueForLargeBuffer = GetEnvironmentVariable(convert("PATH"),
- pResultBuffer,
- size);
- free(pResultBuffer);
-
- /* Ensure that it returned a positive value */
- if(ReturnValueForLargeBuffer <= 0)
- {
- Fail("The return was %d, which indicates that the function failed.\n",
- ReturnValueForLargeBuffer);
- }
-
- /* Ensure that it succeeded and copied the correct number of characters.
- If this is true, then the return value should be one less of the
- size of the buffer. (Doesn't include that NULL byte)
- */
- if(ReturnValueForLargeBuffer != size-1)
- {
- Fail("The value returned was %d when it should have been %d. This "
- "should be the number of characters copied, "
- "minus the NULL byte.\n", ReturnValueForLargeBuffer, size-1);
- }
-
- PAL_Terminate();
- return PASS;
-}
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test1/test.cpp b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test1/test.cpp
new file mode 100644
index 0000000000..cb5fc00554
--- /dev/null
+++ b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test1/test.cpp
@@ -0,0 +1,79 @@
+// Licensed to the .NET Foundation under one or more 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 GetEnvironmentVariable() function
+**
+**
+**=========================================================*/
+
+#define UNICODE
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ /* Define some buffers needed for the function */
+ WCHAR * pResultBuffer = NULL;
+ int size = 0;
+
+ /* A place to stash the returned values */
+ int ReturnValueForLargeBuffer = 0;
+
+ /*
+ * Initialize the PAL and return FAILURE if this fails
+ */
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ /* Recieve and allocate the correct amount of memory for the buffer */
+ size = ReturnValueForLargeBuffer =
+ GetEnvironmentVariable(convert("PATH"),
+ pResultBuffer,
+ 0);
+
+ pResultBuffer = (WCHAR*)malloc(size*sizeof(WCHAR));
+ if ( pResultBuffer == NULL )
+ {
+ Fail("ERROR: Failed to allocate memory for pResultBuffer pointer. "
+ "Can't properly exec test case without this.\n");
+ }
+
+
+ /* Normal case, PATH should fit into this buffer */
+ ReturnValueForLargeBuffer = GetEnvironmentVariable(convert("PATH"),
+ pResultBuffer,
+ size);
+ free(pResultBuffer);
+
+ /* Ensure that it returned a positive value */
+ if(ReturnValueForLargeBuffer <= 0)
+ {
+ Fail("The return was %d, which indicates that the function failed.\n",
+ ReturnValueForLargeBuffer);
+ }
+
+ /* Ensure that it succeeded and copied the correct number of characters.
+ If this is true, then the return value should be one less of the
+ size of the buffer. (Doesn't include that NULL byte)
+ */
+ if(ReturnValueForLargeBuffer != size-1)
+ {
+ Fail("The value returned was %d when it should have been %d. This "
+ "should be the number of characters copied, "
+ "minus the NULL byte.\n", ReturnValueForLargeBuffer, size-1);
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
+
+
+
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test2/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test2/CMakeLists.txt
index 7234f61ed3..2c6ec6247e 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_getenvironmentvariablew_test2
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test2/test.c b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test2/test.cpp
index 6fa753c8d3..6fa753c8d3 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test2/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test2/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test3/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test3/CMakeLists.txt
index bafd75e52e..6af382b6cd 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_getenvironmentvariablew_test3
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test3/test.c b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test3/test.cpp
index 03781e723f..03781e723f 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test3/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test3/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test4/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test4/CMakeLists.txt
index f870bd6b22..674b187fa7 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_getenvironmentvariablew_test4
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test4/test.c b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test4/test.c
deleted file mode 100644
index b5894efc6e..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test4/test.c
+++ /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.
-
-/*============================================================
-**
-** Source : test.c
-**
-** Purpose: Test for GetEnvironmentVariable() function
-**
-**
-**=========================================================*/
-
-/* Depends on SetEnvironmentVariableW (because we're implmenting the wide
- version) and strcmp() */
-
-#define UNICODE
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[]) {
-
- /* Define some buffers needed for the function */
- WCHAR * pResultBuffer = NULL;
- WCHAR SomeEnvironmentVariable[] = {'P','A','L','T','E','S','T','\0'};
- WCHAR TheEnvironmentValue[] = {'T','E','S','T','\0'};
- int size;
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- SetEnvironmentVariable(SomeEnvironmentVariable,
- TheEnvironmentValue);
-
-
- /* Normal case, PATH should fit into this buffer */
- size = GetEnvironmentVariable(convert("PALTEST"), // Variable Name
- pResultBuffer, // Buffer for Value
- 0); // Buffer size
-
- pResultBuffer = malloc(size*sizeof(WCHAR));
-
- GetEnvironmentVariable(convert("PALTEST"),
- pResultBuffer,
- size);
-
- if(wcsncmp(pResultBuffer,convert("TEST"),wcslen(pResultBuffer) * 2) != 0)
- {
- Fail("ERROR: The value in the buffer should have been 'TEST' but was "
- "really '%s'.",convertC(pResultBuffer));
- }
-
- free(pResultBuffer);
-
- PAL_Terminate();
- return PASS;
-}
-
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test4/test.cpp b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test4/test.cpp
new file mode 100644
index 0000000000..1ee3e72c9d
--- /dev/null
+++ b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test4/test.cpp
@@ -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.
+
+/*============================================================
+**
+** Source : test.c
+**
+** Purpose: Test for GetEnvironmentVariable() function
+**
+**
+**=========================================================*/
+
+/* Depends on SetEnvironmentVariableW (because we're implmenting the wide
+ version) and strcmp() */
+
+#define UNICODE
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[]) {
+
+ /* Define some buffers needed for the function */
+ WCHAR * pResultBuffer = NULL;
+ WCHAR SomeEnvironmentVariable[] = {'P','A','L','T','E','S','T','\0'};
+ WCHAR TheEnvironmentValue[] = {'T','E','S','T','\0'};
+ int size;
+
+ /*
+ * Initialize the PAL and return FAILURE if this fails
+ */
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ SetEnvironmentVariable(SomeEnvironmentVariable,
+ TheEnvironmentValue);
+
+
+ /* Normal case, PATH should fit into this buffer */
+ size = GetEnvironmentVariable(convert("PALTEST"), // Variable Name
+ pResultBuffer, // Buffer for Value
+ 0); // Buffer size
+
+ pResultBuffer = (WCHAR*)malloc(size*sizeof(WCHAR));
+
+ GetEnvironmentVariable(convert("PALTEST"),
+ pResultBuffer,
+ size);
+
+ if(wcsncmp(pResultBuffer,convert("TEST"),wcslen(pResultBuffer) * 2) != 0)
+ {
+ Fail("ERROR: The value in the buffer should have been 'TEST' but was "
+ "really '%s'.",convertC(pResultBuffer));
+ }
+
+ free(pResultBuffer);
+
+ PAL_Terminate();
+ return PASS;
+}
+
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test5/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test5/CMakeLists.txt
index ab44781279..71e974703b 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_getenvironmentvariablew_test5
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test5/test5.c b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test5/test5.c
deleted file mode 100644
index 58eba3a380..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test5/test5.c
+++ /dev/null
@@ -1,144 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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 : test5.c
-**
-** Purpose: Test for GetEnvironmentVariableW() function
-** Create environment variables that differ only
-** in case and verify that they return the appropriate
-** value on the BSD environment.
-**
-**
-===========================================================*/
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
-
-#if WIN32
-
- return PASS;
-
-#else
-
- /* Define some buffers needed for the function */
- WCHAR * pResultBuffer = NULL;
-
- WCHAR FirstEnvironmentVariable[] = {'P','A','L','T','E','S','T','\0'};
- WCHAR FirstEnvironmentValue[] = {'F','I','R','S','T','\0'};
-
- WCHAR SecondEnvironmentVariable[] = {'p','a','l','t','e','s','t','\0'};
- WCHAR SecondEnvironmentValue[] = {'S','E','C','O','N','D','\0'};
-
- DWORD size = 0;
- BOOL bRc = TRUE;
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- /* Set the first environment variable */
- bRc = SetEnvironmentVariableW(FirstEnvironmentVariable,
- FirstEnvironmentValue);
-
- if(!bRc)
- {
- Fail("ERROR: SetEnvironmentVariable failed to set a "
- "proper environment variable with error %u.\n", GetLastError());
- }
-
- /* Normal case, PATH should fit into this buffer */
- size = GetEnvironmentVariableW(FirstEnvironmentVariable,
- pResultBuffer,
- 0);
-
- /* To account for the nul character at the end of the string */
- size = size + 1;
-
- pResultBuffer = malloc(sizeof(WCHAR)*size);
- if ( pResultBuffer == NULL )
- {
- Fail("ERROR: Failed to allocate memory for pResultBuffer pointer.\n");
- }
-
- /* Try to retrieve the value of the first environment variable */
- GetEnvironmentVariableW(FirstEnvironmentVariable,
- pResultBuffer,
- size);
-
- if ( pResultBuffer == NULL )
- {
- free(pResultBuffer);
- Fail("ERROR: GetEnvironmentVariable failed to return a value "
- "from a proper environment variable with error %u.\n",
- GetLastError());
- }
-
- /* Compare the strings to see that the correct variable was returned */
- if(wcsncmp(pResultBuffer,FirstEnvironmentValue,wcslen(pResultBuffer)) != 0)
- {
- free(pResultBuffer);
- Fail("ERROR: The value in the buffer should have been '%S' but "
- "was really '%S'.\n",FirstEnvironmentValue, pResultBuffer);
- }
-
- free(pResultBuffer);
-
- /* Set the second environment Variable */
- bRc = SetEnvironmentVariableW(SecondEnvironmentVariable,
- SecondEnvironmentValue);
-
- if(!bRc)
- {
- Fail("ERROR: SetEnvironmentVariable failed to set a "
- "proper environment variable with error %u.\n",
- GetLastError());
- }
-
- /* Reallocate the memory for the string */
- pResultBuffer = malloc(sizeof(WCHAR)*size);
- if ( pResultBuffer == NULL )
- {
- Fail("ERROR: Failed to allocate memory for pResultBuffer pointer.\n");
- }
-
- /* Try retrieving the value of the first variable, even though the
- second variable has the same spelling and only differs in case */
- GetEnvironmentVariableW(FirstEnvironmentVariable,
- pResultBuffer,
- size);
-
- if ( pResultBuffer == NULL )
- {
- free(pResultBuffer);
- Fail("ERROR: GetEnvironmentVariable failed to return a value "
- "from a proper environment variable with error %u.\n",
- GetLastError());
- }
-
- /* Compare the two strings to confirm that the right value is returned */
- if(wcsncmp(pResultBuffer,FirstEnvironmentValue,wcslen(pResultBuffer)) != 0)
- {
- free(pResultBuffer);
- Fail("ERROR: The value in the buffer should have been '%S' but "
- "was really '%S'.\n",FirstEnvironmentValue,pResultBuffer);
- }
-
- free(pResultBuffer);
-
- PAL_Terminate();
- return PASS;
-
-#endif
-}
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test5/test5.cpp b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test5/test5.cpp
new file mode 100644
index 0000000000..179fc17f0b
--- /dev/null
+++ b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test5/test5.cpp
@@ -0,0 +1,144 @@
+// Licensed to the .NET Foundation under one or more 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 : test5.c
+**
+** Purpose: Test for GetEnvironmentVariableW() function
+** Create environment variables that differ only
+** in case and verify that they return the appropriate
+** value on the BSD environment.
+**
+**
+===========================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+
+#if WIN32
+
+ return PASS;
+
+#else
+
+ /* Define some buffers needed for the function */
+ WCHAR * pResultBuffer = NULL;
+
+ WCHAR FirstEnvironmentVariable[] = {'P','A','L','T','E','S','T','\0'};
+ WCHAR FirstEnvironmentValue[] = {'F','I','R','S','T','\0'};
+
+ WCHAR SecondEnvironmentVariable[] = {'p','a','l','t','e','s','t','\0'};
+ WCHAR SecondEnvironmentValue[] = {'S','E','C','O','N','D','\0'};
+
+ DWORD size = 0;
+ BOOL bRc = TRUE;
+
+ /*
+ * Initialize the PAL and return FAILURE if this fails
+ */
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ /* Set the first environment variable */
+ bRc = SetEnvironmentVariableW(FirstEnvironmentVariable,
+ FirstEnvironmentValue);
+
+ if(!bRc)
+ {
+ Fail("ERROR: SetEnvironmentVariable failed to set a "
+ "proper environment variable with error %u.\n", GetLastError());
+ }
+
+ /* Normal case, PATH should fit into this buffer */
+ size = GetEnvironmentVariableW(FirstEnvironmentVariable,
+ pResultBuffer,
+ 0);
+
+ /* To account for the nul character at the end of the string */
+ size = size + 1;
+
+ pResultBuffer = (WCHAR*)malloc(sizeof(WCHAR)*size);
+ if ( pResultBuffer == NULL )
+ {
+ Fail("ERROR: Failed to allocate memory for pResultBuffer pointer.\n");
+ }
+
+ /* Try to retrieve the value of the first environment variable */
+ GetEnvironmentVariableW(FirstEnvironmentVariable,
+ pResultBuffer,
+ size);
+
+ if ( pResultBuffer == NULL )
+ {
+ free(pResultBuffer);
+ Fail("ERROR: GetEnvironmentVariable failed to return a value "
+ "from a proper environment variable with error %u.\n",
+ GetLastError());
+ }
+
+ /* Compare the strings to see that the correct variable was returned */
+ if(wcsncmp(pResultBuffer,FirstEnvironmentValue,wcslen(pResultBuffer)) != 0)
+ {
+ free(pResultBuffer);
+ Fail("ERROR: The value in the buffer should have been '%S' but "
+ "was really '%S'.\n",FirstEnvironmentValue, pResultBuffer);
+ }
+
+ free(pResultBuffer);
+
+ /* Set the second environment Variable */
+ bRc = SetEnvironmentVariableW(SecondEnvironmentVariable,
+ SecondEnvironmentValue);
+
+ if(!bRc)
+ {
+ Fail("ERROR: SetEnvironmentVariable failed to set a "
+ "proper environment variable with error %u.\n",
+ GetLastError());
+ }
+
+ /* Reallocate the memory for the string */
+ pResultBuffer = (WCHAR*)malloc(sizeof(WCHAR)*size);
+ if ( pResultBuffer == NULL )
+ {
+ Fail("ERROR: Failed to allocate memory for pResultBuffer pointer.\n");
+ }
+
+ /* Try retrieving the value of the first variable, even though the
+ second variable has the same spelling and only differs in case */
+ GetEnvironmentVariableW(FirstEnvironmentVariable,
+ pResultBuffer,
+ size);
+
+ if ( pResultBuffer == NULL )
+ {
+ free(pResultBuffer);
+ Fail("ERROR: GetEnvironmentVariable failed to return a value "
+ "from a proper environment variable with error %u.\n",
+ GetLastError());
+ }
+
+ /* Compare the two strings to confirm that the right value is returned */
+ if(wcsncmp(pResultBuffer,FirstEnvironmentValue,wcslen(pResultBuffer)) != 0)
+ {
+ free(pResultBuffer);
+ Fail("ERROR: The value in the buffer should have been '%S' but "
+ "was really '%S'.\n",FirstEnvironmentValue,pResultBuffer);
+ }
+
+ free(pResultBuffer);
+
+ PAL_Terminate();
+ return PASS;
+
+#endif
+}
+
+
+
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test6/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test6/CMakeLists.txt
index e504c8323a..8771ab0cc8 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test6.c
+ test6.cpp
)
add_executable(paltest_getenvironmentvariablew_test6
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test6/test6.c b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test6/test6.c
deleted file mode 100644
index 85f31be9c2..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test6/test6.c
+++ /dev/null
@@ -1,99 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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 : test6.c
-**
-** Purpose: Test for GetEnvironmentVariableW() function
-** Create environment variables that differ only
-** in case and verify that they return the appropriate
-** value on the BSD environment.
-**
-**
-===========================================================*/
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
-
-#if WIN32
-
- /* Define some buffers needed for the function */
- WCHAR * pResultBuffer = NULL;
-
- WCHAR FirstEnvironmentVariable[] = {'P','A','L','T','E','S','T','\0'};
- WCHAR FirstEnvironmentValue[] = {'F','I','R','S','T','\0'};
-
- WCHAR ModifiedEnvironmentVariable[] = {'p','a','l','t','e','s','t','\0'};
-
- DWORD size = 0;
- BOOL bRc = TRUE;
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- /* Set the first environment variable */
- bRc = SetEnvironmentVariableW(FirstEnvironmentVariable,
- FirstEnvironmentValue);
-
- if(!bRc)
- {
- Fail("ERROR: SetEnvironmentVariable failed to set a "
- "proper environment variable with error %u.\n",
- GetLastError());
- }
-
- /* Normal case, PATH should fit into this buffer */
- size = GetEnvironmentVariableW(ModifiedEnvironmentVariable,
- pResultBuffer,
- 0);
-
- /* To account for the nul character at the end of the string */
- size = size + 1;
-
- pResultBuffer = malloc(sizeof(WCHAR)*size);
- if ( pResultBuffer == NULL )
- {
- Fail("ERROR: Failed to allocate memory for pResultBuffer pointer.\n");
- }
-
- /* Try to retrieve the value of the first environment variable */
- GetEnvironmentVariableW(ModifiedEnvironmentVariable,
- pResultBuffer,
- size);
-
- if ( pResultBuffer == NULL )
- {
- free(pResultBuffer);
- Fail("ERROR: GetEnvironmentVariable failed to return a value "
- "from a proper environment variable with error %u.\n",
- GetLastError());
- }
-
- /* Compare the strings to see that the correct variable was returned */
- if(wcsncmp(pResultBuffer,FirstEnvironmentValue,wcslen(pResultBuffer)) != 0)
- {
- free(pResultBuffer);
- Fail("ERROR: The value in the buffer should have been '%S' but "
- "was really '%S'.\n",FirstEnvironmentValue, pResultBuffer);
- }
-
- free(pResultBuffer);
-
- PAL_Terminate();
- return PASS;
-
-
-#else
-
- return PASS;
-#endif
-}
diff --git a/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test6/test6.cpp b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test6/test6.cpp
new file mode 100644
index 0000000000..e376950841
--- /dev/null
+++ b/src/pal/tests/palsuite/miscellaneous/GetEnvironmentVariableW/test6/test6.cpp
@@ -0,0 +1,99 @@
+// Licensed to the .NET Foundation under one or more 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 : test6.c
+**
+** Purpose: Test for GetEnvironmentVariableW() function
+** Create environment variables that differ only
+** in case and verify that they return the appropriate
+** value on the BSD environment.
+**
+**
+===========================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+
+#if WIN32
+
+ /* Define some buffers needed for the function */
+ WCHAR * pResultBuffer = NULL;
+
+ WCHAR FirstEnvironmentVariable[] = {'P','A','L','T','E','S','T','\0'};
+ WCHAR FirstEnvironmentValue[] = {'F','I','R','S','T','\0'};
+
+ WCHAR ModifiedEnvironmentVariable[] = {'p','a','l','t','e','s','t','\0'};
+
+ DWORD size = 0;
+ BOOL bRc = TRUE;
+
+ /*
+ * Initialize the PAL and return FAILURE if this fails
+ */
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ /* Set the first environment variable */
+ bRc = SetEnvironmentVariableW(FirstEnvironmentVariable,
+ FirstEnvironmentValue);
+
+ if(!bRc)
+ {
+ Fail("ERROR: SetEnvironmentVariable failed to set a "
+ "proper environment variable with error %u.\n",
+ GetLastError());
+ }
+
+ /* Normal case, PATH should fit into this buffer */
+ size = GetEnvironmentVariableW(ModifiedEnvironmentVariable,
+ pResultBuffer,
+ 0);
+
+ /* To account for the nul character at the end of the string */
+ size = size + 1;
+
+ pResultBuffer = (WCHAR*)malloc(sizeof(WCHAR)*size);
+ if ( pResultBuffer == NULL )
+ {
+ Fail("ERROR: Failed to allocate memory for pResultBuffer pointer.\n");
+ }
+
+ /* Try to retrieve the value of the first environment variable */
+ GetEnvironmentVariableW(ModifiedEnvironmentVariable,
+ pResultBuffer,
+ size);
+
+ if ( pResultBuffer == NULL )
+ {
+ free(pResultBuffer);
+ Fail("ERROR: GetEnvironmentVariable failed to return a value "
+ "from a proper environment variable with error %u.\n",
+ GetLastError());
+ }
+
+ /* Compare the strings to see that the correct variable was returned */
+ if(wcsncmp(pResultBuffer,FirstEnvironmentValue,wcslen(pResultBuffer)) != 0)
+ {
+ free(pResultBuffer);
+ Fail("ERROR: The value in the buffer should have been '%S' but "
+ "was really '%S'.\n",FirstEnvironmentValue, pResultBuffer);
+ }
+
+ free(pResultBuffer);
+
+ PAL_Terminate();
+ return PASS;
+
+
+#else
+
+ return PASS;
+#endif
+}
diff --git a/src/pal/tests/palsuite/miscellaneous/GetLastError/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetLastError/test1/CMakeLists.txt
index 09e650c924..3c851c7260 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetLastError/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GetLastError/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_getlasterror_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/GetLastError/test1/test.c b/src/pal/tests/palsuite/miscellaneous/GetLastError/test1/test.cpp
index 65f56e595f..65f56e595f 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetLastError/test1/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/GetLastError/test1/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/GetSystemInfo/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetSystemInfo/test1/CMakeLists.txt
index 960291fe79..9419517128 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetSystemInfo/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GetSystemInfo/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_getsysteminfo_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/GetSystemInfo/test1/test.c b/src/pal/tests/palsuite/miscellaneous/GetSystemInfo/test1/test.cpp
index 5f3608fb70..5f3608fb70 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetSystemInfo/test1/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/GetSystemInfo/test1/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/GetTickCount/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetTickCount/test1/CMakeLists.txt
index 5c6ea26a41..f7be23bc0b 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetTickCount/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GetTickCount/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_gettickcount_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/GetTickCount/test1/test.c b/src/pal/tests/palsuite/miscellaneous/GetTickCount/test1/test.cpp
index ad71ba5d6c..ad71ba5d6c 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetTickCount/test1/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/GetTickCount/test1/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/GetUserNameW/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetUserNameW/test1/CMakeLists.txt
index a1d5ab21b8..8ed7ace073 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetUserNameW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GetUserNameW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_getusernamew_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/GetUserNameW/test1/test.c b/src/pal/tests/palsuite/miscellaneous/GetUserNameW/test1/test.cpp
index 809f14c12d..809f14c12d 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetUserNameW/test1/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/GetUserNameW/test1/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/CMakeLists.txt
index b9dd711d36..2cb305f22b 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_getversionexa_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/test.c b/src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/test.cpp
index 5dd20c6576..5dd20c6576 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/CMakeLists.txt
index d7eb683343..09494240cc 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_getversionexw_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/test.c b/src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/test.cpp
index 69aae54bcf..69aae54bcf 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/IsBadCodePtr/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/IsBadCodePtr/test1/CMakeLists.txt
index d41e6bc5ab..bc3f11b705 100644
--- a/src/pal/tests/palsuite/miscellaneous/IsBadCodePtr/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/IsBadCodePtr/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_isbadcodeptr_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/IsBadCodePtr/test1/test1.c b/src/pal/tests/palsuite/miscellaneous/IsBadCodePtr/test1/test1.cpp
index 4b2763d457..4b2763d457 100644
--- a/src/pal/tests/palsuite/miscellaneous/IsBadCodePtr/test1/test1.c
+++ b/src/pal/tests/palsuite/miscellaneous/IsBadCodePtr/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/IsBadReadPtr/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/IsBadReadPtr/test1/CMakeLists.txt
index f1e84d73b8..82aecefa70 100644
--- a/src/pal/tests/palsuite/miscellaneous/IsBadReadPtr/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/IsBadReadPtr/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_isbadreadptr_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/IsBadReadPtr/test1/test.c b/src/pal/tests/palsuite/miscellaneous/IsBadReadPtr/test1/test.cpp
index 24b7ceb7e6..24b7ceb7e6 100644
--- a/src/pal/tests/palsuite/miscellaneous/IsBadReadPtr/test1/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/IsBadReadPtr/test1/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test1/CMakeLists.txt
index 2b2e6aae2e..e3a08167b3 100644
--- a/src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_isbadwriteptr_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test1/test.c b/src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test1/test.cpp
index 018d7beae0..018d7beae0 100644
--- a/src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test1/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test1/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test2/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test2/CMakeLists.txt
index c033f8054f..718cbaa297 100644
--- a/src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_isbadwriteptr_test2
diff --git a/src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test2/test2.c b/src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test2/test2.cpp
index 2d4d53e3b7..2d4d53e3b7 100644
--- a/src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test2/test2.c
+++ b/src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test3/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test3/CMakeLists.txt
index 32cb901e8d..0efd3179db 100644
--- a/src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_isbadwriteptr_test3
diff --git a/src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test3/test3.c b/src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test3/test3.cpp
index 4c058a8987..4c058a8987 100644
--- a/src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test3/test3.c
+++ b/src/pal/tests/palsuite/miscellaneous/IsBadWritePtr/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/MessageBoxW/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/MessageBoxW/test1/CMakeLists.txt
index 5e77e8ba98..bc80853ea1 100644
--- a/src/pal/tests/palsuite/miscellaneous/MessageBoxW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/MessageBoxW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_messageboxw_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/MessageBoxW/test1/test.c b/src/pal/tests/palsuite/miscellaneous/MessageBoxW/test1/test.cpp
index 8eb8c0eb7e..8eb8c0eb7e 100644
--- a/src/pal/tests/palsuite/miscellaneous/MessageBoxW/test1/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/MessageBoxW/test1/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/MessageBoxW/test2/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/MessageBoxW/test2/CMakeLists.txt
index 4b0af2e77e..b8993af4cf 100644
--- a/src/pal/tests/palsuite/miscellaneous/MessageBoxW/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/MessageBoxW/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_messageboxw_test2
diff --git a/src/pal/tests/palsuite/miscellaneous/MessageBoxW/test2/test.c b/src/pal/tests/palsuite/miscellaneous/MessageBoxW/test2/test.cpp
index e2ff0cf6d6..e2ff0cf6d6 100644
--- a/src/pal/tests/palsuite/miscellaneous/MessageBoxW/test2/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/MessageBoxW/test2/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test1/CMakeLists.txt
index b66248522b..5d63281eab 100644
--- a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_setenvironmentvariablea_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test1/test1.c b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test1/test1.cpp
index 86a44218f1..86a44218f1 100644
--- a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test1/test1.c
+++ b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test2/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test2/CMakeLists.txt
index c062c6df65..fe05887c3e 100644
--- a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_setenvironmentvariablea_test2
diff --git a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test2/test2.c b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test2/test2.cpp
index 984007e6f1..984007e6f1 100644
--- a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test2/test2.c
+++ b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test3/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test3/CMakeLists.txt
index 159f574abe..98c9dc0a63 100644
--- a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_setenvironmentvariablea_test3
diff --git a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test3/test3.c b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test3/test3.c
deleted file mode 100644
index fa24275da7..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test3/test3.c
+++ /dev/null
@@ -1,144 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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 : test3.c
-**
-** Purpose: Test for SetEnvironmentVariableA() function
-** Create environment variables that differ only
-** in case and verify that they return the appropriate
-** value on the BSD environment.
-**
-**
-===========================================================*/
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
-
-#if WIN32
-
- return PASS;
-
-#else
-
- /* Define some buffers needed for the function */
- char * pResultBuffer = NULL;
-
- char FirstEnvironmentVariable[] = {"PALTEST"};
- char FirstEnvironmentValue[] = {"FIRST"};
-
- char SecondEnvironmentVariable[] = {"paltest"};
- char SecondEnvironmentValue[] = {"SECOND"};
-
- DWORD size = 0;
- BOOL bRc = TRUE;
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- /* Set the first environment variable */
- bRc = SetEnvironmentVariableA(FirstEnvironmentVariable,
- FirstEnvironmentValue);
-
- if(!bRc)
- {
- Fail("ERROR: SetEnvironmentVariable failed to set a "
- "proper environment variable with error %u.\n",
- GetLastError());
- }
-
- /* Set the second environment Variable */
- bRc = SetEnvironmentVariableA(SecondEnvironmentVariable,
- SecondEnvironmentValue);
-
- if(!bRc)
- {
- Fail("ERROR: SetEnvironmentVariable failed to set a "
- "proper environment variable with error %u.\n",
- GetLastError());
- }
-
-
- /* Normal case, PATH should fit into this buffer */
- size = GetEnvironmentVariableA(FirstEnvironmentVariable,
- pResultBuffer,
- 0);
-
- /* increase size to account for the null char at the end */
- size = size + 1;
-
- pResultBuffer = malloc(sizeof(char)*size);
- if ( pResultBuffer == NULL )
- {
- Fail("ERROR: Failed to allocate memory for pResultBuffer pointer.\n");
- }
-
- /* Try to retrieve the value of the first environment variable */
- GetEnvironmentVariable(FirstEnvironmentVariable,
- pResultBuffer,
- size);
-
- if ( pResultBuffer == NULL )
- {
- free(pResultBuffer);
- Fail("ERROR: GetEnvironmentVariable failed to return a value "
- "from a proper environment variable with error %u.\n",
- GetLastError());
- }
-
- /* Compare the strings to see that the correct variable was returned */
- if(strcmp(pResultBuffer,FirstEnvironmentValue) != 0)
- {
- Trace("ERROR: The value in the buffer should have been '%s' but "
- "was really '%s'.\n",FirstEnvironmentValue, pResultBuffer);
- free(pResultBuffer);
- Fail("");
- }
-
- free(pResultBuffer);
-
- /* Reallocate the memory for the string */
- pResultBuffer = malloc(sizeof(char)*size);
- if ( pResultBuffer == NULL )
- {
- Fail("ERROR: Failed to allocate memory for pResultBuffer pointer.\n");
- }
-
- /* Try retrieving the value of the first variable, even though the
- second variable has the same spelling and only differs in case */
- GetEnvironmentVariable(SecondEnvironmentVariable,
- pResultBuffer,
- size);
-
- if ( pResultBuffer == NULL )
- {
- Fail("ERROR: GetEnvironmentVariable failed to return a value "
- "from a proper environment variable with error %u.\n",
- GetLastError());
- }
-
- /* Compare the two strings to confirm that the right value is returned */
- if(strcmp(pResultBuffer,SecondEnvironmentValue) != 0)
- {
- Trace("ERROR: The value in the buffer should have been '%s' but "
- "was really '%s'.\n",SecondEnvironmentValue,pResultBuffer);
- free(pResultBuffer);
- Fail("");
- }
-
- free(pResultBuffer);
-
- PAL_Terminate();
- return PASS;
-
-#endif
-}
diff --git a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test3/test3.cpp b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test3/test3.cpp
new file mode 100644
index 0000000000..539e33004b
--- /dev/null
+++ b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test3/test3.cpp
@@ -0,0 +1,144 @@
+// Licensed to the .NET Foundation under one or more 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 : test3.c
+**
+** Purpose: Test for SetEnvironmentVariableA() function
+** Create environment variables that differ only
+** in case and verify that they return the appropriate
+** value on the BSD environment.
+**
+**
+===========================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+
+#if WIN32
+
+ return PASS;
+
+#else
+
+ /* Define some buffers needed for the function */
+ char * pResultBuffer = NULL;
+
+ char FirstEnvironmentVariable[] = {"PALTEST"};
+ char FirstEnvironmentValue[] = {"FIRST"};
+
+ char SecondEnvironmentVariable[] = {"paltest"};
+ char SecondEnvironmentValue[] = {"SECOND"};
+
+ DWORD size = 0;
+ BOOL bRc = TRUE;
+
+ /*
+ * Initialize the PAL and return FAILURE if this fails
+ */
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ /* Set the first environment variable */
+ bRc = SetEnvironmentVariableA(FirstEnvironmentVariable,
+ FirstEnvironmentValue);
+
+ if(!bRc)
+ {
+ Fail("ERROR: SetEnvironmentVariable failed to set a "
+ "proper environment variable with error %u.\n",
+ GetLastError());
+ }
+
+ /* Set the second environment Variable */
+ bRc = SetEnvironmentVariableA(SecondEnvironmentVariable,
+ SecondEnvironmentValue);
+
+ if(!bRc)
+ {
+ Fail("ERROR: SetEnvironmentVariable failed to set a "
+ "proper environment variable with error %u.\n",
+ GetLastError());
+ }
+
+
+ /* Normal case, PATH should fit into this buffer */
+ size = GetEnvironmentVariableA(FirstEnvironmentVariable,
+ pResultBuffer,
+ 0);
+
+ /* increase size to account for the null char at the end */
+ size = size + 1;
+
+ pResultBuffer = (char*)malloc(sizeof(char)*size);
+ if ( pResultBuffer == NULL )
+ {
+ Fail("ERROR: Failed to allocate memory for pResultBuffer pointer.\n");
+ }
+
+ /* Try to retrieve the value of the first environment variable */
+ GetEnvironmentVariable(FirstEnvironmentVariable,
+ pResultBuffer,
+ size);
+
+ if ( pResultBuffer == NULL )
+ {
+ free(pResultBuffer);
+ Fail("ERROR: GetEnvironmentVariable failed to return a value "
+ "from a proper environment variable with error %u.\n",
+ GetLastError());
+ }
+
+ /* Compare the strings to see that the correct variable was returned */
+ if(strcmp(pResultBuffer,FirstEnvironmentValue) != 0)
+ {
+ Trace("ERROR: The value in the buffer should have been '%s' but "
+ "was really '%s'.\n",FirstEnvironmentValue, pResultBuffer);
+ free(pResultBuffer);
+ Fail("");
+ }
+
+ free(pResultBuffer);
+
+ /* Reallocate the memory for the string */
+ pResultBuffer = (char*)malloc(sizeof(char)*size);
+ if ( pResultBuffer == NULL )
+ {
+ Fail("ERROR: Failed to allocate memory for pResultBuffer pointer.\n");
+ }
+
+ /* Try retrieving the value of the first variable, even though the
+ second variable has the same spelling and only differs in case */
+ GetEnvironmentVariable(SecondEnvironmentVariable,
+ pResultBuffer,
+ size);
+
+ if ( pResultBuffer == NULL )
+ {
+ Fail("ERROR: GetEnvironmentVariable failed to return a value "
+ "from a proper environment variable with error %u.\n",
+ GetLastError());
+ }
+
+ /* Compare the two strings to confirm that the right value is returned */
+ if(strcmp(pResultBuffer,SecondEnvironmentValue) != 0)
+ {
+ Trace("ERROR: The value in the buffer should have been '%s' but "
+ "was really '%s'.\n",SecondEnvironmentValue,pResultBuffer);
+ free(pResultBuffer);
+ Fail("");
+ }
+
+ free(pResultBuffer);
+
+ PAL_Terminate();
+ return PASS;
+
+#endif
+}
diff --git a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test4/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test4/CMakeLists.txt
index 29cca8d7b4..1c53d4b6a1 100644
--- a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_setenvironmentvariablea_test4
diff --git a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test4/test4.c b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test4/test4.c
deleted file mode 100644
index 557cef74c9..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test4/test4.c
+++ /dev/null
@@ -1,100 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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 : test4.c
-**
-** Purpose: Test for SetEnvironmentVariableA() function
-** Create environment variables that differ only
-** in case and verify that they return the appropriate
-** value in the WIN32 Environment
-**
-
-**
-===========================================================*/
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
-
-#if WIN32
-
- /* Define some buffers needed for the function */
- char * pResultBuffer = NULL;
-
- char FirstEnvironmentVariable[] = {"PALTEST"};
- char FirstEnvironmentValue[] = {"FIRST"};
- char ModifiedEnvVar[] = {"paltest"};
-
- DWORD size = 0;
- BOOL bRc = TRUE;
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- /* Set the first environment variable */
- bRc = SetEnvironmentVariableA(FirstEnvironmentVariable,
- FirstEnvironmentValue);
-
- if(!bRc)
- {
- Fail("ERROR: SetEnvironmentVariable failed to set a "
- "proper environment variable with error %u.\n",
- GetLastError());
- }
-
- /* Normal case, PATH should fit into this buffer */
- size = GetEnvironmentVariableA(ModifiedEnvVar,
- pResultBuffer,
- 0);
-
- /* To account for the null character at the end of the string */
- size = size + 1;
-
- pResultBuffer = malloc(sizeof(char)*size);
- if ( pResultBuffer == NULL )
- {
- Fail("ERROR: Failed to allocate memory for pResultBuffer pointer.\n");
- }
-
- /* Try to retrieve the value of the first environment variable */
- GetEnvironmentVariableA(ModifiedEnvVar,
- pResultBuffer,
- size);
-
- if ( pResultBuffer == NULL )
- {
- free(pResultBuffer);
- Fail("ERROR: GetEnvironmentVariable failed to return a value "
- "from a proper environment variable with error %u.\n",
- GetLastError());
- }
-
- /* Compare the strings to see that the correct variable was returned */
- if(strcmp(pResultBuffer,FirstEnvironmentValue) != 0)
- {
- Trace("ERROR: The value in the buffer should have been '%s' but "
- "was really '%s'.\n",FirstEnvironmentValue, pResultBuffer);
- free(pResultBuffer);
- Fail("");
- }
-
- free(pResultBuffer);
-
- PAL_Terminate();
- return PASS;
-
-
-#else
-
- return PASS;
-#endif
-}
diff --git a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test4/test4.cpp b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test4/test4.cpp
new file mode 100644
index 0000000000..de3059c8d8
--- /dev/null
+++ b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableA/test4/test4.cpp
@@ -0,0 +1,100 @@
+// Licensed to the .NET Foundation under one or more 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 : test4.c
+**
+** Purpose: Test for SetEnvironmentVariableA() function
+** Create environment variables that differ only
+** in case and verify that they return the appropriate
+** value in the WIN32 Environment
+**
+
+**
+===========================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+
+#if WIN32
+
+ /* Define some buffers needed for the function */
+ char * pResultBuffer = NULL;
+
+ char FirstEnvironmentVariable[] = {"PALTEST"};
+ char FirstEnvironmentValue[] = {"FIRST"};
+ char ModifiedEnvVar[] = {"paltest"};
+
+ DWORD size = 0;
+ BOOL bRc = TRUE;
+
+ /*
+ * Initialize the PAL and return FAILURE if this fails
+ */
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ /* Set the first environment variable */
+ bRc = SetEnvironmentVariableA(FirstEnvironmentVariable,
+ FirstEnvironmentValue);
+
+ if(!bRc)
+ {
+ Fail("ERROR: SetEnvironmentVariable failed to set a "
+ "proper environment variable with error %u.\n",
+ GetLastError());
+ }
+
+ /* Normal case, PATH should fit into this buffer */
+ size = GetEnvironmentVariableA(ModifiedEnvVar,
+ pResultBuffer,
+ 0);
+
+ /* To account for the null character at the end of the string */
+ size = size + 1;
+
+ pResultBuffer = (char*)malloc(sizeof(char)*size);
+ if ( pResultBuffer == NULL )
+ {
+ Fail("ERROR: Failed to allocate memory for pResultBuffer pointer.\n");
+ }
+
+ /* Try to retrieve the value of the first environment variable */
+ GetEnvironmentVariableA(ModifiedEnvVar,
+ pResultBuffer,
+ size);
+
+ if ( pResultBuffer == NULL )
+ {
+ free(pResultBuffer);
+ Fail("ERROR: GetEnvironmentVariable failed to return a value "
+ "from a proper environment variable with error %u.\n",
+ GetLastError());
+ }
+
+ /* Compare the strings to see that the correct variable was returned */
+ if(strcmp(pResultBuffer,FirstEnvironmentValue) != 0)
+ {
+ Trace("ERROR: The value in the buffer should have been '%s' but "
+ "was really '%s'.\n",FirstEnvironmentValue, pResultBuffer);
+ free(pResultBuffer);
+ Fail("");
+ }
+
+ free(pResultBuffer);
+
+ PAL_Terminate();
+ return PASS;
+
+
+#else
+
+ return PASS;
+#endif
+}
diff --git a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test1/CMakeLists.txt
index 247dceefd9..6eb52ab92e 100644
--- a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_setenvironmentvariablew_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test1/test.c b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test1/test.cpp
index bddbba7940..bddbba7940 100644
--- a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test1/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test1/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test2/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test2/CMakeLists.txt
index a69343ccd5..a82d849bde 100644
--- a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_setenvironmentvariablew_test2
diff --git a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test2/test.c b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test2/test.cpp
index 12f4887b6d..12f4887b6d 100644
--- a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test2/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test2/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test3/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test3/CMakeLists.txt
index e9072c7143..266231e6e9 100644
--- a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_setenvironmentvariablew_test3
diff --git a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test3/test3.c b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test3/test3.c
deleted file mode 100644
index 02d0a2d6d9..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test3/test3.c
+++ /dev/null
@@ -1,143 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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 : test3.c
-**
-** Purpose: Test for SetEnvironmentVariableW() function
-** Create environment variables that differ only
-** in case and verify that they return the appropriate
-** value on the BSD environment.
-**
-**
-===========================================================*/
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
-
-#if WIN32
-
- return PASS;
-
-#else
-
- /* Define some buffers needed for the function */
- WCHAR * pResultBuffer = NULL;
-
- WCHAR FirstEnvironmentVariable[] = {'P','A','L','T','E','S','T','\0'};
- WCHAR FirstEnvironmentValue[] = {'F','I','R','S','T','\0'};
-
- WCHAR SecondEnvironmentVariable[] = {'p','a','l','t','e','s','t','\0'};
- WCHAR SecondEnvironmentValue[] = {'S','E','C','O','N','D','\0'};
-
- DWORD size = 0;
- BOOL bRc = TRUE;
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- /* Set the first environment variable */
- bRc = SetEnvironmentVariableW(FirstEnvironmentVariable,
- FirstEnvironmentValue);
-
- if(!bRc)
- {
- Fail("ERROR: SetEnvironmentVariable failed to set a "
- "proper environment variable with error %u.\n",
- GetLastError());
- }
-
- /* Set the second environment Variable */
- bRc = SetEnvironmentVariableW(SecondEnvironmentVariable,
- SecondEnvironmentValue);
-
- if(!bRc)
- {
- Fail("ERROR: SetEnvironmentVariable failed to set a "
- "proper environment variable with error %u.\n",
- GetLastError());
- }
-
-
- /* Normal case, PATH should fit into this buffer */
- size = GetEnvironmentVariableW(FirstEnvironmentVariable,
- pResultBuffer,
- 0);
-
- /* Increase size to account for the null char at the end */
- size = size + 1;
-
- pResultBuffer = malloc(sizeof(WCHAR)*size);
- if ( pResultBuffer == NULL )
- {
- Fail("ERROR: Failed to allocate memory for pResultBuffer pointer.\n");
- }
-
- /* Try to retrieve the value of the first environment variable */
- GetEnvironmentVariableW(FirstEnvironmentVariable,
- pResultBuffer,
- size);
-
- if ( pResultBuffer == NULL )
- {
- Fail("ERROR: GetEnvironmentVariable failed to return a value "
- "from a proper environment variable with error %u.\n",
- GetLastError());
- }
-
- /* Compare the strings to see that the correct variable was returned */
- if(wcscmp(pResultBuffer,FirstEnvironmentValue) != 0)
- {
- Trace("ERROR: The value in the buffer should have been '%S' but "
- "was really '%S'.\n",FirstEnvironmentValue, pResultBuffer);
- free(pResultBuffer);
- Fail("");
- }
-
- free(pResultBuffer);
-
- /* Reallocate the memory for the string */
- pResultBuffer = malloc(sizeof(WCHAR)*size);
- if ( pResultBuffer == NULL )
- {
- Fail("ERROR: Failed to allocate memory for pResultBuffer pointer.\n");
- }
-
- /* Try retrieving the value of the first variable, even though the
- second variable has the same spelling and only differs in case */
- GetEnvironmentVariableW(SecondEnvironmentVariable,
- pResultBuffer,
- size);
-
- if ( pResultBuffer == NULL )
- {
- Fail("ERROR: GetEnvironmentVariable failed to return a value "
- "from a proper environment variable with error %u.\n",
- GetLastError());
- }
-
- /* Compare the two strings to confirm that the right value is returned */
- if(wcscmp(pResultBuffer,SecondEnvironmentValue) != 0)
- {
- Trace("ERROR: The value in the buffer should have been '%S' but "
- "was really '%S'.\n",SecondEnvironmentValue,pResultBuffer);
- free(pResultBuffer);
- Fail("");
- }
-
- free(pResultBuffer);
-
- PAL_Terminate();
- return PASS;
-
-#endif
-}
diff --git a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test3/test3.cpp b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test3/test3.cpp
new file mode 100644
index 0000000000..5c4d4eba42
--- /dev/null
+++ b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test3/test3.cpp
@@ -0,0 +1,143 @@
+// Licensed to the .NET Foundation under one or more 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 : test3.c
+**
+** Purpose: Test for SetEnvironmentVariableW() function
+** Create environment variables that differ only
+** in case and verify that they return the appropriate
+** value on the BSD environment.
+**
+**
+===========================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+
+#if WIN32
+
+ return PASS;
+
+#else
+
+ /* Define some buffers needed for the function */
+ WCHAR * pResultBuffer = NULL;
+
+ WCHAR FirstEnvironmentVariable[] = {'P','A','L','T','E','S','T','\0'};
+ WCHAR FirstEnvironmentValue[] = {'F','I','R','S','T','\0'};
+
+ WCHAR SecondEnvironmentVariable[] = {'p','a','l','t','e','s','t','\0'};
+ WCHAR SecondEnvironmentValue[] = {'S','E','C','O','N','D','\0'};
+
+ DWORD size = 0;
+ BOOL bRc = TRUE;
+
+ /*
+ * Initialize the PAL and return FAILURE if this fails
+ */
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ /* Set the first environment variable */
+ bRc = SetEnvironmentVariableW(FirstEnvironmentVariable,
+ FirstEnvironmentValue);
+
+ if(!bRc)
+ {
+ Fail("ERROR: SetEnvironmentVariable failed to set a "
+ "proper environment variable with error %u.\n",
+ GetLastError());
+ }
+
+ /* Set the second environment Variable */
+ bRc = SetEnvironmentVariableW(SecondEnvironmentVariable,
+ SecondEnvironmentValue);
+
+ if(!bRc)
+ {
+ Fail("ERROR: SetEnvironmentVariable failed to set a "
+ "proper environment variable with error %u.\n",
+ GetLastError());
+ }
+
+
+ /* Normal case, PATH should fit into this buffer */
+ size = GetEnvironmentVariableW(FirstEnvironmentVariable,
+ pResultBuffer,
+ 0);
+
+ /* Increase size to account for the null char at the end */
+ size = size + 1;
+
+ pResultBuffer = (WCHAR*)malloc(sizeof(WCHAR)*size);
+ if ( pResultBuffer == NULL )
+ {
+ Fail("ERROR: Failed to allocate memory for pResultBuffer pointer.\n");
+ }
+
+ /* Try to retrieve the value of the first environment variable */
+ GetEnvironmentVariableW(FirstEnvironmentVariable,
+ pResultBuffer,
+ size);
+
+ if ( pResultBuffer == NULL )
+ {
+ Fail("ERROR: GetEnvironmentVariable failed to return a value "
+ "from a proper environment variable with error %u.\n",
+ GetLastError());
+ }
+
+ /* Compare the strings to see that the correct variable was returned */
+ if(wcscmp(pResultBuffer,FirstEnvironmentValue) != 0)
+ {
+ Trace("ERROR: The value in the buffer should have been '%S' but "
+ "was really '%S'.\n",FirstEnvironmentValue, pResultBuffer);
+ free(pResultBuffer);
+ Fail("");
+ }
+
+ free(pResultBuffer);
+
+ /* Reallocate the memory for the string */
+ pResultBuffer = (WCHAR*)malloc(sizeof(WCHAR)*size);
+ if ( pResultBuffer == NULL )
+ {
+ Fail("ERROR: Failed to allocate memory for pResultBuffer pointer.\n");
+ }
+
+ /* Try retrieving the value of the first variable, even though the
+ second variable has the same spelling and only differs in case */
+ GetEnvironmentVariableW(SecondEnvironmentVariable,
+ pResultBuffer,
+ size);
+
+ if ( pResultBuffer == NULL )
+ {
+ Fail("ERROR: GetEnvironmentVariable failed to return a value "
+ "from a proper environment variable with error %u.\n",
+ GetLastError());
+ }
+
+ /* Compare the two strings to confirm that the right value is returned */
+ if(wcscmp(pResultBuffer,SecondEnvironmentValue) != 0)
+ {
+ Trace("ERROR: The value in the buffer should have been '%S' but "
+ "was really '%S'.\n",SecondEnvironmentValue,pResultBuffer);
+ free(pResultBuffer);
+ Fail("");
+ }
+
+ free(pResultBuffer);
+
+ PAL_Terminate();
+ return PASS;
+
+#endif
+}
diff --git a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test4/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test4/CMakeLists.txt
index f5f48bab33..c82e0f0394 100644
--- a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_setenvironmentvariablew_test4
diff --git a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test4/test4.c b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test4/test4.c
deleted file mode 100644
index b8f7734de4..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test4/test4.c
+++ /dev/null
@@ -1,99 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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 : test4.c
-**
-** Purpose: Test for SetEnvironmentVariableW() function
-** Create environment variables that differ only
-** in case and verify that they return the appropriate
-** value on the BSD environment.
-**
-**
-===========================================================*/
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
-
-#if WIN32
-
- /* Define some buffers needed for the function */
- WCHAR * pResultBuffer = NULL;
-
- WCHAR FirstEnvironmentVariable[] = {'P','A','L','T','E','S','T','\0'};
- WCHAR FirstEnvironmentValue[] = {'F','I','R','S','T','\0'};
-
- WCHAR ModifiedEnvironmentVariable[] = {'p','a','l','t','e','s','t','\0'};
-
- DWORD size = 0;
- BOOL bRc = TRUE;
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- /* Set the first environment variable */
- bRc = SetEnvironmentVariableW(FirstEnvironmentVariable,
- FirstEnvironmentValue);
-
- if(!bRc)
- {
- Fail("ERROR: SetEnvironmentVariable failed to set a "
- "proper environment variable with error %u.\n",
- GetLastError());
- }
-
- /* Normal case, PATH should fit into this buffer */
- size = GetEnvironmentVariableW(ModifiedEnvironmentVariable,
- pResultBuffer,
- 0);
-
- /* To account for the nul character at the end of the string */
- size = size + 1;
-
- pResultBuffer = malloc(sizeof(WCHAR)*size);
- if ( pResultBuffer == NULL )
- {
- Fail("ERROR: Failed to allocate memory for pResultBuffer pointer.\n");
- }
-
- /* Try to retrieve the value of the first environment variable */
- GetEnvironmentVariableW(ModifiedEnvironmentVariable,
- pResultBuffer,
- size);
-
- if ( pResultBuffer == NULL )
- {
- Fail("ERROR: GetEnvironmentVariable failed to return a value "
- "from a proper environment variable with error %u.\n",
- GetLastError());
- }
-
- /* Compare the strings to see that the correct variable was returned */
- if(wcsncmp(pResultBuffer,FirstEnvironmentValue,wcslen(pResultBuffer)) != 0)
- {
- Trace("ERROR: The value in the buffer should have been '%S' but "
- "was really '%S'.\n",FirstEnvironmentValue, pResultBuffer);
- free(pResultBuffer);
- Fail("");
- }
-
- free(pResultBuffer);
-
- PAL_Terminate();
- return PASS;
-
-
-#else
-
- return PASS;
-#endif
-}
diff --git a/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test4/test4.cpp b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test4/test4.cpp
new file mode 100644
index 0000000000..50c59d6e97
--- /dev/null
+++ b/src/pal/tests/palsuite/miscellaneous/SetEnvironmentVariableW/test4/test4.cpp
@@ -0,0 +1,99 @@
+// Licensed to the .NET Foundation under one or more 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 : test4.c
+**
+** Purpose: Test for SetEnvironmentVariableW() function
+** Create environment variables that differ only
+** in case and verify that they return the appropriate
+** value on the BSD environment.
+**
+**
+===========================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+
+#if WIN32
+
+ /* Define some buffers needed for the function */
+ WCHAR * pResultBuffer = NULL;
+
+ WCHAR FirstEnvironmentVariable[] = {'P','A','L','T','E','S','T','\0'};
+ WCHAR FirstEnvironmentValue[] = {'F','I','R','S','T','\0'};
+
+ WCHAR ModifiedEnvironmentVariable[] = {'p','a','l','t','e','s','t','\0'};
+
+ DWORD size = 0;
+ BOOL bRc = TRUE;
+
+ /*
+ * Initialize the PAL and return FAILURE if this fails
+ */
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ /* Set the first environment variable */
+ bRc = SetEnvironmentVariableW(FirstEnvironmentVariable,
+ FirstEnvironmentValue);
+
+ if(!bRc)
+ {
+ Fail("ERROR: SetEnvironmentVariable failed to set a "
+ "proper environment variable with error %u.\n",
+ GetLastError());
+ }
+
+ /* Normal case, PATH should fit into this buffer */
+ size = GetEnvironmentVariableW(ModifiedEnvironmentVariable,
+ pResultBuffer,
+ 0);
+
+ /* To account for the nul character at the end of the string */
+ size = size + 1;
+
+ pResultBuffer = (WCHAR*)malloc(sizeof(WCHAR)*size);
+ if ( pResultBuffer == NULL )
+ {
+ Fail("ERROR: Failed to allocate memory for pResultBuffer pointer.\n");
+ }
+
+ /* Try to retrieve the value of the first environment variable */
+ GetEnvironmentVariableW(ModifiedEnvironmentVariable,
+ pResultBuffer,
+ size);
+
+ if ( pResultBuffer == NULL )
+ {
+ Fail("ERROR: GetEnvironmentVariable failed to return a value "
+ "from a proper environment variable with error %u.\n",
+ GetLastError());
+ }
+
+ /* Compare the strings to see that the correct variable was returned */
+ if(wcsncmp(pResultBuffer,FirstEnvironmentValue,wcslen(pResultBuffer)) != 0)
+ {
+ Trace("ERROR: The value in the buffer should have been '%S' but "
+ "was really '%S'.\n",FirstEnvironmentValue, pResultBuffer);
+ free(pResultBuffer);
+ Fail("");
+ }
+
+ free(pResultBuffer);
+
+ PAL_Terminate();
+ return PASS;
+
+
+#else
+
+ return PASS;
+#endif
+}
diff --git a/src/pal/tests/palsuite/miscellaneous/SetLastError/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/SetLastError/test1/CMakeLists.txt
index 5248d6ce97..40eb2ff865 100644
--- a/src/pal/tests/palsuite/miscellaneous/SetLastError/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/SetLastError/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_setlasterror_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/SetLastError/test1/test.c b/src/pal/tests/palsuite/miscellaneous/SetLastError/test1/test.cpp
index d414626dd2..d414626dd2 100644
--- a/src/pal/tests/palsuite/miscellaneous/SetLastError/test1/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/SetLastError/test1/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/_i64tow/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/_i64tow/test1/CMakeLists.txt
index 6876d1b24e..c3c4b61999 100644
--- a/src/pal/tests/palsuite/miscellaneous/_i64tow/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/_i64tow/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_i64tow_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/_i64tow/test1/test1.c b/src/pal/tests/palsuite/miscellaneous/_i64tow/test1/test1.c
deleted file mode 100644
index 9a87328b0d..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/_i64tow/test1/test1.c
+++ /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.
-
-/*=============================================================
-**
-** Source: test1.c
-**
-** Purpose: Tests _i64tow with normal values and different radices, negative
-** values, as well as the highest and lowest values.
-**
-**
-**============================================================*/
-
-#include <palsuite.h>
-
-typedef struct
-{
- INT64 value;
- int radix;
- char *result;
-} testCase;
-
-
-int __cdecl main(int argc, char *argv[])
-{
- WCHAR buffer[256];
- WCHAR *testStr;
- WCHAR *ret;
- int i;
- testCase testCases[] =
- {
- {42, 10, "42"},
- {42, 2, "101010"},
- {29, 32, "t"},
- {-1, 10, "-1"},
- {-1, 8, "1777777777777777777777"},
- {-1, 32, "fvvvvvvvvvvvv"},
- {I64(0x7FFFFFFFFFFFFFFF), 10, "9223372036854775807"},
- {I64(0x8000000000000000), 10, "-9223372036854775808"},
- {0,2,"0"},
- {0,16,"0"},
- {3,16,"3"},
- {15,16,"f"},
- {16,16,"10"},
-
- };
-
-
- if (0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- for (i=0; i<sizeof(testCases) / sizeof(testCase); i++)
- {
- ret = _i64tow(testCases[i].value, buffer, testCases[i].radix);
- if (ret != buffer)
- {
- Fail("_i64tow did not return a pointer to the string.\n"
- "Expected %p, got %p\n", buffer, ret);
- }
-
- testStr = convert(testCases[i].result);
- if (wcscmp(testStr, buffer) != 0)
- {
- Fail("_i64tow did not give the correct string.\n"
- "Expected %S, got %S\n", testStr, buffer);
- }
- free(testStr);
- }
-
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/miscellaneous/_i64tow/test1/test1.cpp b/src/pal/tests/palsuite/miscellaneous/_i64tow/test1/test1.cpp
new file mode 100644
index 0000000000..9a8ae07089
--- /dev/null
+++ b/src/pal/tests/palsuite/miscellaneous/_i64tow/test1/test1.cpp
@@ -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.
+
+/*=============================================================
+**
+** Source: test1.c
+**
+** Purpose: Tests _i64tow_s with normal values and different radices, negative
+** values, as well as the highest and lowest values.
+**
+**
+**============================================================*/
+
+#include <palsuite.h>
+
+typedef struct
+{
+ INT64 value;
+ int radix;
+ char *result;
+} testCase;
+
+
+int __cdecl main(int argc, char *argv[])
+{
+ WCHAR buffer[256];
+ WCHAR *testStr;
+ WCHAR *ret;
+ int i;
+ testCase testCases[] =
+ {
+ {42, 10, "42"},
+ {42, 2, "101010"},
+ {29, 32, "t"},
+ {-1, 10, "-1"},
+ {-1, 8, "1777777777777777777777"},
+ {-1, 32, "fvvvvvvvvvvvv"},
+ {I64(0x7FFFFFFFFFFFFFFF), 10, "9223372036854775807"},
+ {I64(0x8000000000000000), 10, "-9223372036854775808"},
+ {0,2,"0"},
+ {0,16,"0"},
+ {3,16,"3"},
+ {15,16,"f"},
+ {16,16,"10"},
+
+ };
+
+
+ if (0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ for (i=0; i<sizeof(testCases) / sizeof(testCase); i++)
+ {
+ errno_t err = _i64tow_s(testCases[i].value, buffer, sizeof(buffer) / sizeof(buffer[0]), testCases[i].radix);
+
+ if(err != 0)
+ {
+ Fail("ERROR: _i64tow_s didn't return success, error code %d.\n", err);
+ }
+
+ testStr = convert(testCases[i].result);
+ if (wcscmp(testStr, buffer) != 0)
+ {
+ Fail("_i64tow_s did not give the correct string.\n"
+ "Expected %S, got %S\n", testStr, buffer);
+ }
+ free(testStr);
+ }
+
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/miscellaneous/_i64tow/test1/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/_i64tow/test1/testinfo.dat
index a3979e60da..11982050e0 100644
--- a/src/pal/tests/palsuite/miscellaneous/_i64tow/test1/testinfo.dat
+++ b/src/pal/tests/palsuite/miscellaneous/_i64tow/test1/testinfo.dat
@@ -4,10 +4,10 @@
Version = 1.0
Section = miscellaneous
-Function = _i64tow
-Name = Test #1 for _i64tow
+Function = _i64tow_s
+Name = Test #1 for _i64tow_s
TYPE = DEFAULT
EXE1 = test1
Description
-=Tests _i64tow with normal values and different radices, negative
+=Tests _i64tow_s with normal values and different radices, negative
=values, as well as the highest and lowest values.
diff --git a/src/pal/tests/palsuite/miscellaneous/_ui64tow/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/_ui64tow/CMakeLists.txt
deleted file mode 100644
index ef14ea5352..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/_ui64tow/CMakeLists.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-add_subdirectory(test1)
-add_subdirectory(test2)
-
diff --git a/src/pal/tests/palsuite/miscellaneous/_ui64tow/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/_ui64tow/test1/CMakeLists.txt
deleted file mode 100644
index f920c4bded..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/_ui64tow/test1/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- _ui64tow.c
-)
-
-add_executable(paltest_ui64tow_test1
- ${SOURCES}
-)
-
-add_dependencies(paltest_ui64tow_test1 coreclrpal)
-
-target_link_libraries(paltest_ui64tow_test1
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/_ui64tow/test1/_ui64tow.c b/src/pal/tests/palsuite/miscellaneous/_ui64tow/test1/_ui64tow.c
deleted file mode 100644
index fb94f2509f..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/_ui64tow/test1/_ui64tow.c
+++ /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.
-
-/*=============================================================
-**
-** Source: _ui64tow.c
-**
-** Purpose: Positive test the _ui64tow API.
-** convert an integer to a wide character string
-**
-**
-**============================================================*/
-#define UNICODE
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
- int err;
- WCHAR *wpBuffer = NULL;
- char *pChar = NULL;
- unsigned long ul = 1234567890UL;
- char *pChar10 = "1234567890";
- char *pChar2 = "1001001100101100000001011010010";
- char *pChar16 = "499602d2";
-
- /*Initialize the PAL environment*/
- err = PAL_Initialize(argc, argv);
- if(0 != err)
- {
- return FAIL;
- }
-
- wpBuffer = malloc(64 * sizeof(WCHAR));
- if(NULL == wpBuffer)
- {
- Fail("\nFail to allocate the buffer to save a converted "
- "wide character string, error code=%d!\n",
- GetLastError());
- }
-
- /*convert to a 10 base string*/
- _ui64tow(ul, wpBuffer, 10);
- pChar = convertC(wpBuffer);
- if(strcmp(pChar10, pChar))
- {
- free(wpBuffer);
- free(pChar);
- Fail("\nFailed to call _ui64tow API to convert an interger "
- "to a 10 base wide character string, error code=%d\n",
- GetLastError());
- }
- free(pChar);
- free(wpBuffer);
-
- wpBuffer = malloc(64 * sizeof(WCHAR));
- if(NULL == wpBuffer)
- {
- Fail("\nFail to allocate the buffer to save a converted "
- "wide character string, error code=%d!\n",
- GetLastError());
- }
-
- /*convert to a 16 base string*/
- _ui64tow(ul, wpBuffer, 16);
- pChar = convertC(wpBuffer);
- if(strcmp(pChar16, pChar))
- {
- free(wpBuffer);
- free(pChar);
- Fail("\nFailed to call _ui64tow API to convert an interger "
- "to a 16 base wide character string, error code = %d\n",
- GetLastError());
- }
- free(pChar);
- free(wpBuffer);
-
- wpBuffer = malloc(64 * sizeof(WCHAR));
- if(NULL == wpBuffer)
- {
- Fail("\nFail to allocate the buffer to save a converted "
- "wide character string, error code=%d!\n",
- GetLastError());
- }
- /*convert to a 2 base string*/
- _ui64tow(ul, wpBuffer, 2);
- pChar = convertC(wpBuffer);
- if(strcmp(pChar2, pChar))
- {
- free(wpBuffer);
- free(pChar);
- Fail("\nFailed to call _ui64tow API to convert an interger "
- "to a 2 base wide character string, error code=%d\n",
- GetLastError());
- }
- free(pChar);
- free(wpBuffer);
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/miscellaneous/_ui64tow/test1/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/_ui64tow/test1/testinfo.dat
deleted file mode 100644
index a60f27a14a..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/_ui64tow/test1/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = miscellaneous
-Function = _ui64tow
-Name = Positive test _ui64tow to convert an integer to a wide character string
-TYPE = DEFAULT
-EXE1 = _ui64tow
-Description
-=Test the _ui64tow API to convert an integer to a wide character string
diff --git a/src/pal/tests/palsuite/miscellaneous/_ui64tow/test2/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/_ui64tow/test2/CMakeLists.txt
deleted file mode 100644
index b4feb4b8fd..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/_ui64tow/test2/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- _ui64tow.c
-)
-
-add_executable(paltest_ui64tow_test2
- ${SOURCES}
-)
-
-add_dependencies(paltest_ui64tow_test2 coreclrpal)
-
-target_link_libraries(paltest_ui64tow_test2
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/_ui64tow/test2/_ui64tow.c b/src/pal/tests/palsuite/miscellaneous/_ui64tow/test2/_ui64tow.c
deleted file mode 100644
index f13250578c..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/_ui64tow/test2/_ui64tow.c
+++ /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: _ui64tow.c
-**
-** Purpose: Tests _ui64tow with normal values and different
-** radices,highest and lowest values.
-**
-**
-**============================================================*/
-
-#include <palsuite.h>
-
-typedef struct
-{
- unsigned __int64 value;
- int radix;
- char* result;
-} testCase;
-
-
-int __cdecl main(int argc, char *argv[])
-{
- WCHAR buffer[256];
- WCHAR *testStr;
- WCHAR *ret;
- int i;
- testCase testCases[] =
- {
- /* test limits */
- {UI64(0xFFFFFFFFFFFFFFFF), 2,
- "1111111111111111111111111111111111111111111111111111111111111111"},
- {UI64(0xFFFFFFFFFFFFFFFF), 8, "1777777777777777777777"},
- {UI64(0xFFFFFFFFFFFFFFFF), 10, "18446744073709551615"},
- {UI64(0xFFFFFFFFFFFFFFFF), 16, "ffffffffffffffff"},
- {47, 2, "101111"},
- {47, 8, "57"},
- {47, 10, "47"},
- {47, 16, "2f"},
- {12, 2, "1100"},
- {12, 8, "14"},
- {12, 10, "12"},
- {12, 16, "c"},
-
- /* test with 0. */
- {0, 2, "0"},
- {0, 8, "0"},
- {0, 10, "0"},
- {0, 16, "0"}
- };
-
- if (0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- for (i=0; i<sizeof(testCases) / sizeof(testCase); i++)
- {
- ret = _ui64tow(testCases[i].value, buffer, testCases[i].radix);
-
- if (ret != buffer)
- {
- Fail("Failed to call _ui64tow API: did not return a pointer "
- "to string. Expected %p, got %p\n", buffer, ret);
- }
-
- testStr = convert(testCases[i].result);
-
- if (wcscmp(testStr, buffer) != 0)
- {
- Trace("ERROR: _ui64tow test#%d. Expected <%S>, got <%S>.\n",
- i,testStr, buffer);
- free(testStr);
- Fail("");
- }
-
- free(testStr);
- }
-
- PAL_Terminate();
- return PASS;
-}
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/_ui64tow/test2/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/_ui64tow/test2/testinfo.dat
deleted file mode 100644
index 0abbca2d11..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/_ui64tow/test2/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = miscellaneous
-Function = _ui64tow
-Name = Positive test _ui64tow to convert an integer to a wide character string
-TYPE = DEFAULT
-EXE1 = _ui64tow
-Description
-=Test the _ui64tow API to convert an integer to a wide character string
-=Test the limits. and 0.
diff --git a/src/pal/tests/palsuite/miscellaneous/lstrcatW/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/lstrcatW/CMakeLists.txt
deleted file mode 100644
index a3847f8ca9..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/lstrcatW/CMakeLists.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-add_subdirectory(test1)
-add_subdirectory(test2)
-add_subdirectory(test3)
-add_subdirectory(test4)
-
diff --git a/src/pal/tests/palsuite/miscellaneous/lstrcatW/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/lstrcatW/test1/CMakeLists.txt
deleted file mode 100644
index aa5b0c2646..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/lstrcatW/test1/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.c
-)
-
-add_executable(paltest_lstrcatw_test1
- ${SOURCES}
-)
-
-add_dependencies(paltest_lstrcatw_test1 coreclrpal)
-
-target_link_libraries(paltest_lstrcatw_test1
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/lstrcatW/test1/test.c b/src/pal/tests/palsuite/miscellaneous/lstrcatW/test1/test.c
deleted file mode 100644
index ad1095e014..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/lstrcatW/test1/test.c
+++ /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.
-
-/*============================================================
-**
-** Source: test.c
-**
-** Purpose: Test for lstrcatW() function
-**
-**
-**=========================================================*/
-
-#define UNICODE
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[]) {
-
- WCHAR FirstString[10] = {'T','E','S','T','\0'};
- const WCHAR SecondString[] = {'P','A','L','!','\0'};
- WCHAR CorrectString[] = {'T','E','S','T','P','A','L','!','\0'};
- WCHAR* ReturnedPointer = NULL;
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- ReturnedPointer = lstrcat(FirstString,SecondString);
-
- /* Check to see if the pointer returned points to the concat string */
- if(ReturnedPointer != &FirstString[0])
- {
- Fail("ERROR: The function was supposed to return a pointer to "
- "the concatentated string, but it did not.\n");
- }
-
- /* Check to make sure the Concat string is the same as the predetermined
- 'CorrectString' */
- if(memcmp(FirstString,CorrectString,
- wcslen(FirstString)*sizeof(WCHAR)) != 0)
- {
- Fail("ERROR: The concatenated string should be %s but %s was the "
- "result.\n",
- convertC(CorrectString),
- convertC(FirstString));
- }
-
- PAL_Terminate();
- return PASS;
-}
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/lstrcatW/test1/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/lstrcatW/test1/testinfo.dat
deleted file mode 100644
index 006e83b882..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/lstrcatW/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 = lstrcatW
-Name = Positive test of lstrcatW
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Test to see that concatenating two strings works,
-= and also check return values in successful and failing situations.
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/lstrcatW/test2/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/lstrcatW/test2/CMakeLists.txt
deleted file mode 100644
index 8a11c8f154..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/lstrcatW/test2/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test2.c
-)
-
-add_executable(paltest_lstrcatw_test2
- ${SOURCES}
-)
-
-add_dependencies(paltest_lstrcatw_test2 coreclrpal)
-
-target_link_libraries(paltest_lstrcatw_test2
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/lstrcatW/test2/test2.c b/src/pal/tests/palsuite/miscellaneous/lstrcatW/test2/test2.c
deleted file mode 100644
index 6c66bc8976..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/lstrcatW/test2/test2.c
+++ /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.
-
-/*============================================================
-**
-** Source: test2.c
-**
-** Purpose: Negative test for lstrcatW() function
-**
-**
-**=========================================================*/
-
-#define UNICODE
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[]) {
-
- WCHAR FirstString[10] = {'T','E','S','T','\0'};
- const WCHAR SecondString[] = {'P','A','L','!','\0'};
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- /* If either of these is NULL, function should fail and return NULL. */
- if(lstrcat(NULL,SecondString) != NULL)
- {
- Fail("ERROR: When NULL was passed to the first parameter of the "
- "function, it should have returned "
- "NULL as a result, but did not.\n");
- }
-
- if(lstrcat(FirstString,NULL) != NULL)
- {
- Fail("ERROR: When NULL was passed to the second parameter of the "
- "function, it should have returned "
- "NULL as a result, but did not.\n");
- }
-
-
- PAL_Terminate();
- return PASS;
-}
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/lstrcatW/test2/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/lstrcatW/test2/testinfo.dat
deleted file mode 100644
index cc1ee644dc..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/lstrcatW/test2/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = Miscellaneous
-Function = lstrcatW
-Name = Negtive test of lstrcatW
-TYPE = DEFAULT
-EXE1 = test2
-Description
-= Test to see lstrcat reports error with failing situations.
diff --git a/src/pal/tests/palsuite/miscellaneous/lstrcatW/test3/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/lstrcatW/test3/CMakeLists.txt
deleted file mode 100644
index 1cdecedf1a..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/lstrcatW/test3/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test3.c
-)
-
-add_executable(paltest_lstrcatw_test3
- ${SOURCES}
-)
-
-add_dependencies(paltest_lstrcatw_test3 coreclrpal)
-
-target_link_libraries(paltest_lstrcatw_test3
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/lstrcatW/test3/test3.c b/src/pal/tests/palsuite/miscellaneous/lstrcatW/test3/test3.c
deleted file mode 100644
index 49a9c57555..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/lstrcatW/test3/test3.c
+++ /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.
-
-/*============================================================
-**
-** Source: test3.c
-**
-** Purpose: Testing lstrcatw with two NULL strings passed on
-**
-**
-**=========================================================*/
-
-#define UNICODE
-
-#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;
- }
-
-
- /* testing the behaviour of lstrcatW with two NULL strings */
- if( lstrcat(NULL,NULL) != NULL)
- {
-
- Fail("lstrcat:ERROR: the function should returned NULL\n");
-
- }
-
- PAL_Terminate();
- return PASS;
-}
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/lstrcatW/test3/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/lstrcatW/test3/testinfo.dat
deleted file mode 100644
index 794bcdbff7..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/lstrcatW/test3/testinfo.dat
+++ /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.
-
-Version = 1.0
-
-Section = Miscellaneous
-
-Function = lstrcatW
-
-Name = Negative testing for lstrcatW
-
-TYPE = DEFAULT
-
-EXE1 = test3
-
-Description
-
-= Testing the behaviour after sending two strings contained NULL
-
-
-
-
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/lstrcatW/test4/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/lstrcatW/test4/CMakeLists.txt
deleted file mode 100644
index 640c224f83..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/lstrcatW/test4/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test4.c
-)
-
-add_executable(paltest_lstrcatw_test4
- ${SOURCES}
-)
-
-add_dependencies(paltest_lstrcatw_test4 coreclrpal)
-
-target_link_libraries(paltest_lstrcatw_test4
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/lstrcatW/test4/test4.c b/src/pal/tests/palsuite/miscellaneous/lstrcatW/test4/test4.c
deleted file mode 100644
index abc9021518..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/lstrcatW/test4/test4.c
+++ /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.
-
-/*============================================================
-**
-** Source: test4.c
-**
-** Purpose: Testing the behaviour of lstrcatw when string2 contains
-** special characters, this test case depends on:
-** memcmp
-** wcslen
-** lstrcpyn
-**
-**
-**=========================================================*/
-
-#define UNICODE
-
-#include <palsuite.h>
-
-struct testCase
-{
- WCHAR SecondString[5];
- WCHAR CorrectString[10];
-};
-
-int __cdecl main(int argc, char *argv[])
-{
-
- WCHAR FirstString[10] = {'T','E','S','T','\0'};
- WCHAR TestString[10] = {'T','E','S','T','\0'};
- int i = 0;
-
- /*
- * this structure includes several strings to be tested with
- * lstrcatW function and the expected results
- */
-
- struct testCase testCases[]=
- {
- {{'\t','T','A','B','\0'},
- {'T','E','S','T','\t','T','A','B','\0'}},
- {{'2','T','\?','B','\0'},
- {'T','E','S','T','2','T','\?','B','\0'}},
- {{'\v','T','E','\v','\0'},
- {'T','E','S','T','\v','T','E','\v','\0'}},
- {{'T','\a','E','\a','\0'},
- {'T','E','S','T','T','\a','E','\a','\0'}},
- {{'0','\f','Z','\f','\0'},
- {'T','E','S','T','0','\f','Z','\f','\0'}},
- {{'\r','H','I','\r','\0'},
- {'T','E','S','T','\r','H','I','\r','\0'}},
- {{'H','I','\"','\"','\0'},
- {'T','E','S','T','H','I','\"','\"','\0'}},
- {{'H','\b','I','\b','\0'},
- {'T','E','S','T','H','\b','I','\b','\0'}},
- {{'H','\n','I','\n','\0'},
- {'T','E','S','T','H','\n','I','\n','\0'}}
- };
-
-
-
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
-
- /* Loop through the struct and validate the resulted string */
- for( i = 0; i < sizeof(testCases)/sizeof(struct testCase); i++)
- {
-
- lstrcat(FirstString, testCases[i].SecondString);
-
- if(memcmp(FirstString,testCases[i].CorrectString,
- wcslen(FirstString)*sizeof(WCHAR)))
- {
-
- Fail("ERROR: the function failed with a special character.\n");
- }
-
- /* reinitialize the first string */
- lstrcpyn(FirstString,TestString,10);
-
- }
-
-
-
-
- PAL_Terminate();
- return PASS;
-}
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/lstrcatW/test4/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/lstrcatW/test4/testinfo.dat
deleted file mode 100644
index 96235fb257..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/lstrcatW/test4/testinfo.dat
+++ /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.
-
-Version = 1.0
-
-Section = Miscellaneous
-
-Function = lstrcatW
-
-Name = Positive testing for lstrcatW
-
-TYPE = DEFAULT
-
-EXE1 = test4
-
-Description
-
-= Testing the behaviour of lstrcatw when string2 contains
-
-= special characters and validate the resulted string
-
-
-
-
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/lstrcpyW/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/lstrcpyW/CMakeLists.txt
deleted file mode 100644
index f6aa0cb2d9..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/lstrcpyW/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-add_subdirectory(test1)
-
diff --git a/src/pal/tests/palsuite/miscellaneous/lstrcpyW/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/lstrcpyW/test1/CMakeLists.txt
deleted file mode 100644
index e39c9a6098..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/lstrcpyW/test1/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.c
-)
-
-add_executable(paltest_lstrcpyw_test1
- ${SOURCES}
-)
-
-add_dependencies(paltest_lstrcpyw_test1 coreclrpal)
-
-target_link_libraries(paltest_lstrcpyw_test1
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/lstrcpyW/test1/test.c b/src/pal/tests/palsuite/miscellaneous/lstrcpyW/test1/test.c
deleted file mode 100644
index 881ba033e8..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/lstrcpyW/test1/test.c
+++ /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.
-
-/*============================================================
-**
-** Source: test.c
-**
-** Purpose: Test for lstrcpyW() function
-**
-**
-**=========================================================*/
-
-#define UNICODE
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
- WCHAR FirstString[5] = {'T','E','S','T','\0'};
- WCHAR ResultBuffer[5];
- WCHAR* ResultPointer = NULL;
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- ResultPointer = lstrcpy(ResultBuffer,FirstString);
-
- /* Check the return value */
- if(ResultPointer != &ResultBuffer[0])
- {
- Fail("ERROR: The function did not return a pointer to the Result "
- "Buffer after being called.\n");
- }
-
- /* A straight copy, the values should be equal. */
- if(memcmp(ResultBuffer,FirstString,wcslen(ResultBuffer)*2+2) != 0)
- {
- Fail("ERROR: The result of the copy was '%s' when it should have "
- "been '%s'.\n",convertC(ResultBuffer),convertC(FirstString));
- }
-
- /* If either param is NULL, it should return NULL. */
- if(lstrcpy(ResultBuffer,NULL) != NULL)
- {
- Fail("ERROR: The second parameter was NULL, so the function should "
- "fail and return NULL.\n");
- }
- if(lstrcpy(NULL,FirstString) != NULL)
- {
- Fail("ERROR: The first parameter was NULL, so the function should "
- "fail and return NULL.\n");
- }
-
-
- PAL_Terminate();
- return PASS;
-}
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/lstrcpyW/test1/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/lstrcpyW/test1/testinfo.dat
deleted file mode 100644
index 37c9835236..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/lstrcpyW/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 = lstrcpyW
-Name = Positive test of lstrcpyW
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Ensure that a copy of a string works, and that the return values
-= are correct for success and failure.
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/lstrcpynW/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/lstrcpynW/CMakeLists.txt
deleted file mode 100644
index f6aa0cb2d9..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/lstrcpynW/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-add_subdirectory(test1)
-
diff --git a/src/pal/tests/palsuite/miscellaneous/lstrcpynW/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/lstrcpynW/test1/CMakeLists.txt
deleted file mode 100644
index 4344b89402..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/lstrcpynW/test1/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.c
-)
-
-add_executable(paltest_lstrcpynw_test1
- ${SOURCES}
-)
-
-add_dependencies(paltest_lstrcpynw_test1 coreclrpal)
-
-target_link_libraries(paltest_lstrcpynw_test1
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/lstrcpynW/test1/test.c b/src/pal/tests/palsuite/miscellaneous/lstrcpynW/test1/test.c
deleted file mode 100644
index 1ae0c51474..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/lstrcpynW/test1/test.c
+++ /dev/null
@@ -1,73 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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 lstrcpynW() function
-**
-**
-**=========================================================*/
-
-#define UNICODE
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[]) {
-
- WCHAR FirstString[5] = {'T','E','S','T','\0'};
- WCHAR CorrectBuffer[3] = {'T','E','\0'};
- WCHAR ResultBuffer[5];
- WCHAR* ResultPointer = NULL;
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- /* A straight copy, the values should be equal. */
- ResultPointer = lstrcpyn(ResultBuffer,FirstString,3);
-
- /* Make sure the returned pointer is to the result buffer */
- if(ResultPointer != &ResultBuffer[0])
- {
- Fail("ERROR: The function didn't return a pointer which points to the "
- "location of the buffer which was copied into.\n");
- }
-
- /* Check to see that values are equal */
- if(memcmp(ResultBuffer,
- CorrectBuffer,
- wcslen(ResultBuffer)*sizeof(WCHAR)) != 0)
- {
- Fail("ERROR: '%s' was the result and it should have been '%s' when "
- "this copy was performed.\n",
- convertC(ResultBuffer),convertC(CorrectBuffer));
- }
-
- /* Null values should get Null results */
- if(lstrcpyn(ResultBuffer,NULL,3) != NULL)
- {
- Fail("ERROR: When the second parameter was set to NULL, the return "
- "value should have been NULL, but it was not.\n");
- }
-
- if(lstrcpyn(NULL,FirstString,3) != NULL)
- {
- Fail("ERROR: When the first parameter was set to NULL, the return "
- "value should have been NULL, but it was not.\n");
- }
-
-
- PAL_Terminate();
- return PASS;
-}
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/lstrcpynW/test1/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/lstrcpynW/test1/testinfo.dat
deleted file mode 100644
index 111a57928a..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/lstrcpynW/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 = lstrcpynW
-Name = Positive test of lstrcpynW
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Ensure that a copy of a string works, and that the return values
-= are correct for success and failure.
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/lstrlenA/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/lstrlenA/test1/CMakeLists.txt
index 807a5d83b9..6bb520100d 100644
--- a/src/pal/tests/palsuite/miscellaneous/lstrlenA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/lstrlenA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_lstrlena_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/lstrlenA/test1/test.c b/src/pal/tests/palsuite/miscellaneous/lstrlenA/test1/test.cpp
index 13e935ba50..13e935ba50 100644
--- a/src/pal/tests/palsuite/miscellaneous/lstrlenA/test1/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/lstrlenA/test1/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/lstrlenW/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/lstrlenW/test1/CMakeLists.txt
index fe6fc9691b..4209cbee89 100644
--- a/src/pal/tests/palsuite/miscellaneous/lstrlenW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/lstrlenW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_lstrlenw_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/lstrlenW/test1/test.c b/src/pal/tests/palsuite/miscellaneous/lstrlenW/test1/test.cpp
index 49bc6d8f67..49bc6d8f67 100644
--- a/src/pal/tests/palsuite/miscellaneous/lstrlenW/test1/test.c
+++ b/src/pal/tests/palsuite/miscellaneous/lstrlenW/test1/test.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/queryperformancecounter/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/queryperformancecounter/test1/CMakeLists.txt
index d76467aeab..ba53f42ccc 100644
--- a/src/pal/tests/palsuite/miscellaneous/queryperformancecounter/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/queryperformancecounter/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_queryperformancecounter_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/queryperformancecounter/test1/test1.c b/src/pal/tests/palsuite/miscellaneous/queryperformancecounter/test1/test1.cpp
index 55b173add7..55b173add7 100644
--- a/src/pal/tests/palsuite/miscellaneous/queryperformancecounter/test1/test1.c
+++ b/src/pal/tests/palsuite/miscellaneous/queryperformancecounter/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/queryperformancefrequency/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/queryperformancefrequency/test1/CMakeLists.txt
index 352e51342d..bc6bd22d5d 100644
--- a/src/pal/tests/palsuite/miscellaneous/queryperformancefrequency/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/queryperformancefrequency/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_queryperformancefrequency_test1
diff --git a/src/pal/tests/palsuite/miscellaneous/queryperformancefrequency/test1/test1.c b/src/pal/tests/palsuite/miscellaneous/queryperformancefrequency/test1/test1.cpp
index de08063a74..de08063a74 100644
--- a/src/pal/tests/palsuite/miscellaneous/queryperformancefrequency/test1/test1.c
+++ b/src/pal/tests/palsuite/miscellaneous/queryperformancefrequency/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/wsprintfA/CMakeLists.txt
deleted file mode 100644
index f40d4151d6..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/CMakeLists.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-add_subdirectory(test1)
-add_subdirectory(test11)
-add_subdirectory(test12)
-add_subdirectory(test13)
-add_subdirectory(test2)
-add_subdirectory(test3)
-add_subdirectory(test6)
-add_subdirectory(test7)
-add_subdirectory(test8)
-add_subdirectory(test9)
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test1/CMakeLists.txt
deleted file mode 100644
index ef589329f0..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test1/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.c
-)
-
-add_executable(paltest_wsprintfa_test1
- ${SOURCES}
-)
-
-add_dependencies(paltest_wsprintfa_test1 coreclrpal)
-
-target_link_libraries(paltest_wsprintfa_test1
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test1/test.c b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test1/test.c
deleted file mode 100644
index 722270965d..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test1/test.c
+++ /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.
-
-/*============================================================
-**
-** Source: test.c
-**
-** Purpose: Test for wsprintfA() function
-**
-**
-**=========================================================*/
-
-#include <palsuite.h>
-
- char * ErrorMessage;
- char buf[256];
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with strlen */
-
-int test1()
-{
- char checkstr[] = "hello world";
-
- wsprintf(buf, "hello world");
-
- /* Error message */
- ErrorMessage = "ERROR: (Test 1) Failed on 'hello world' test. The "
- "correct string is 'hello world' and the result returned was ";
-
- return (memcmp(checkstr, buf, strlen(checkstr)+1) != 0);
-}
-
-int __cdecl main(int argc, char *argv[])
-{
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- if(test1())
- {
- Fail("%s '%s'\n",ErrorMessage,buf);
- }
-
- PAL_Terminate();
- return PASS;
-
-}
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test1/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test1/testinfo.dat
deleted file mode 100644
index c06f4c01aa..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test1/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = Miscellaneous
-Function = wsprintfA
-Name = Positive test of wsprintfA
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Test the very basic functionality of wsprintf.
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test11/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test11/CMakeLists.txt
deleted file mode 100644
index 92c44b9341..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test11/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.c
-)
-
-add_executable(paltest_wsprintfa_test11
- ${SOURCES}
-)
-
-add_dependencies(paltest_wsprintfa_test11 coreclrpal)
-
-target_link_libraries(paltest_wsprintfa_test11
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test11/test.c b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test11/test.c
deleted file mode 100644
index b43299a045..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test11/test.c
+++ /dev/null
@@ -1,128 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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 wsprintfA() function
-**
-**
-**=========================================================*/
-
-#include <palsuite.h>
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with strlen */
-
-char * ErrorMessage;
-char buf[256];
-
-BOOL test1()
-{
- int pos = 42;
-
-
- /* Test 1 */
- wsprintf(buf, "foo %u", pos);
- if (memcmp(buf, "foo 42", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 1) Failed. The correct string is "
- "'foo 42' and the result returned was ";
- return FAIL;
- }
-
- /* Test 2 */
- wsprintf(buf, "foo %lu", 0xFFFF);
- if (memcmp(buf, "foo 65535", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 2) Failed. The correct string is "
- "'foo 65535' and the result returned was ";
- return FAIL;
- }
-
- /* Test 3 */
- wsprintf(buf, "foo %hu", 0xFFFF);
- if (memcmp(buf, "foo 65535", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 3) Failed. The correct string is "
- "'foo 65535' and the result returned was ";
- return FAIL;
- }
-
- /* Test 4 */
- wsprintf(buf, "foo %3u", pos);
- if (memcmp(buf, "foo 42", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 4) Failed. The correct string is "
- "'foo 42' and the result returned was ";
- return FAIL;
- }
-
- /* Test 5 */
- wsprintf(buf, "foo %-3u", pos);
- if (memcmp(buf, "foo 42 ", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 5) Failed. The correct string is "
- "'foo 42' and the result returned was ";
- return FAIL;
- }
-
- /* Test 6 */
- wsprintf(buf, "foo %.1u", pos);
- if (memcmp(buf, "foo 42", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 6) Failed. The correct string is "
- "'foo 42' and the result returned was ";
- return FAIL;
- }
-
- /* Test 7 */
- wsprintf(buf, "foo %.3u", pos);
- if (memcmp(buf, "foo 042", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 7) Failed. The correct string is "
- "'foo 042' and the result returned was ";
- return FAIL;
- }
-
- /* Test 8 */
- wsprintf(buf, "foo %03u", pos);
- if (memcmp(buf, "foo 042", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 8) Failed. The correct string is "
- "'foo 042' and the result returned was ";
- return FAIL;
- }
-
- /* Test 9 */
- wsprintf(buf, "foo %#u", pos);
- if (memcmp(buf, "foo 42", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 9) Failed. The correct string is "
- "'foo 42' and the result returned was ";
- return FAIL;
- }
- return PASS;
-}
-
-
-int __cdecl main(int argc, char *argv[])
-{
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- if(test1())
- {
- Fail("%s'%s'\n",ErrorMessage,buf);
- }
-
- PAL_Terminate();
- return PASS;
-}
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test11/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test11/testinfo.dat
deleted file mode 100644
index c5f1ec1975..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test11/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = Miscellaneous
-Function = wsprintfA
-Name = Positive test of wsprintfA
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Test the %u formatter.
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test12/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test12/CMakeLists.txt
deleted file mode 100644
index e4013ad9e3..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test12/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.c
-)
-
-add_executable(paltest_wsprintfa_test12
- ${SOURCES}
-)
-
-add_dependencies(paltest_wsprintfa_test12 coreclrpal)
-
-target_link_libraries(paltest_wsprintfa_test12
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test12/test.c b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test12/test.c
deleted file mode 100644
index dcc61019d4..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test12/test.c
+++ /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.
-
-/*============================================================
-**
-** Source: test.c
-**
-** Purpose: Test for wsprintfA() function
-**
-**
-**=========================================================*/
-
-#include <palsuite.h>
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with strlen */
-
-char * ErrorMessage;
-char buf[256];
-
-BOOL test1()
-{
- int pos = 0x1234ab;
-
- /* Test 1 */
- wsprintf(buf, "foo %x", pos);
- if (memcmp(buf, "foo 1234ab", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 1) Failed. The correct "
- "string is 'foo 1234ab' and the result returned was ";
- return FAIL;
- }
-
- /* Test 2 */
- wsprintf(buf, "foo %lx", pos);
- if (memcmp(buf, "foo 1234ab", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 2) Failed. The correct "
- "string is 'foo 1234ab' and the result returned was ";
- return FAIL;
- }
-
-
- /* Test 3 */
- wsprintf(buf, "foo %7x", pos);
- if (memcmp(buf, "foo 1234ab", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 3) Failed. The correct string is "
- "'foo 1234ab' and the result returned was ";
- return FAIL;
- }
-
- /* Test 4 */
- wsprintf(buf, "foo %-7x", pos);
- if (memcmp(buf, "foo 1234ab ", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 4) Failed. The correct string is "
- "'foo 1234ab' and the result returned was ";
- return FAIL;
- }
-
- /* Test 5 */
- wsprintf(buf, "foo %.1x", pos);
- if (memcmp(buf, "foo 1234ab", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 5) Failed. The correct string is "
- "'foo 1234ab' and the result returned was ";
- return FAIL;
- }
-
- /* Test 6 */
- wsprintf(buf, "foo %.7x", pos);
- if (memcmp(buf, "foo 01234ab", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 6) Failed. The correct string is "
- "'foo 01234ab' and the result returned was ";
- return FAIL;
- }
-
- /* Test 7 */
- wsprintf(buf, "foo %07x", pos);
- if (memcmp(buf, "foo 01234ab", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 7) Failed. The correct string is "
- "'foo 01234ab' and the result returned was ";
- return FAIL;
- }
-
- /* Test 8 */
- wsprintf(buf, "foo %#x", pos);
- if (memcmp(buf, "foo 0x1234ab", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 8) Failed. The correct string is "
- "'foo 0x1234ab' and the result returned was ";
- return FAIL;
- }
-
- return PASS;
-}
-
-int __cdecl main(int argc, char *argv[])
-{
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- if(test1())
- {
- Fail("%s '%s'\n",ErrorMessage,buf);
- }
-
- PAL_Terminate();
- return PASS;
-}
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test12/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test12/testinfo.dat
deleted file mode 100644
index 71c8386f27..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test12/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = Miscellaneous
-Function = wsprintfA
-Name = Positive test of wsprintfA
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Test the %x formatter.
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test13/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test13/CMakeLists.txt
deleted file mode 100644
index 423b05d8d9..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test13/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.c
-)
-
-add_executable(paltest_wsprintfa_test13
- ${SOURCES}
-)
-
-add_dependencies(paltest_wsprintfa_test13 coreclrpal)
-
-target_link_libraries(paltest_wsprintfa_test13
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test13/test.c b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test13/test.c
deleted file mode 100644
index e1f7d80a0f..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test13/test.c
+++ /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.
-
-/*============================================================
-**
-** Source: test.c
-**
-** Purpose: Test for wsprintfA() function
-**
-**
-**=========================================================*/
-
-#include <palsuite.h>
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with strlen */
-
-char * ErrorMessage;
-char buf[256];
-
-BOOL test1()
-{
- int pos = 0x1234ab;
-
- /* Test 1 */
- wsprintf(buf, "foo %X", pos);
- if (memcmp(buf, "foo 1234AB", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 1) Failed. The correct string is "
- " 'foo 1234AB' and the result returned was ";
- return FAIL;
- }
-
- /* Test 2 */
- wsprintf(buf, "foo %lX", pos);
- if (memcmp(buf, "foo 1234AB", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 2) Failed. The correct string is "
- "'foo 1234AB' and the result returned was ";
- return FAIL;
- }
-
-
- /* Test 3 */
- wsprintf(buf, "foo %7X", pos);
- if (memcmp(buf, "foo 1234AB", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 3) Failed. The correct string is "
- "'foo 1234AB' and the result returned was ";
- return FAIL;
- }
-
- /* Test 4 */
- wsprintf(buf, "foo %-7X", pos);
- if (memcmp(buf, "foo 1234AB ", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 4) Failed. The correct string is "
- "'foo 1234AB' and the result returned was ";
- return FAIL;
- }
-
- /* Test 5 */
- wsprintf(buf, "foo %.1X", pos);
- if (memcmp(buf, "foo 1234AB", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 5) Failed. The correct string is "
- "'foo 1234AB' and the result returned was ";
- return FAIL;
- }
-
- /* Test 6 */
- wsprintf(buf, "foo %.7X", pos);
- if (memcmp(buf, "foo 01234AB", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 6) Failed. The correct string is "
- "'foo 01234AB' and the result returned was ";
- return FAIL;
- }
-
- /* Test 7 */
- wsprintf(buf, "foo %07X", pos);
- if (memcmp(buf, "foo 01234AB", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 7) Failed. The correct string is "
- "'foo 01234AB' and the result returned was ";
- return FAIL;
- }
-
- /* Test 8 */
- wsprintf(buf, "foo %#X", pos);
- if (memcmp(buf, "foo 0X1234AB", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 8) Failed. The correct string is "
- "'foo 0X1234AB' and the result returned was ";
- return FAIL;
- }
-
- return PASS;
-}
-
-int __cdecl main(int argc, char *argv[])
-{
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- if(test1())
- {
- Fail("%s '%s'\n",ErrorMessage,buf);
- }
-
- PAL_Terminate();
- return PASS;
-
-}
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test13/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test13/testinfo.dat
deleted file mode 100644
index 0e0d1b4633..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test13/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = Miscellaneous
-Function = wsprintfA
-Name = Positive test of wsprintfA
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Test the %X formatter.
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test2/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test2/CMakeLists.txt
deleted file mode 100644
index 546a1daa38..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test2/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.c
-)
-
-add_executable(paltest_wsprintfa_test2
- ${SOURCES}
-)
-
-add_dependencies(paltest_wsprintfa_test2 coreclrpal)
-
-target_link_libraries(paltest_wsprintfa_test2
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test2/test.c b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test2/test.c
deleted file mode 100644
index b879e54043..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test2/test.c
+++ /dev/null
@@ -1,123 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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 wsprintfA() function
-**
-**
-**=========================================================*/
-
-#include <palsuite.h>
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with strlen */
-
-char * ErrorMessage;
-char * BadResult;
-char buf[256];
-
-BOOL test1()
-{
-
-
- /* Test 1 */
- wsprintf(buf, "foo %s", "bar");
- if (memcmp(buf, "foo bar", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 1) Failed. The correct string is "
- "'foo bar' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- /* Test 2 */
- wsprintf(buf, "foo %hs", "bar");
- if (memcmp(buf, "foo bar", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 2) Failed. The correct string is "
- "'foo bar' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
-
- /* Test 3 */
- wsprintf(buf, "foo %5s", "bar");
- if (memcmp(buf, "foo bar", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 3) Failed. The correct string is "
- "'foo bar' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- /* Test 4 */
- wsprintf(buf, "foo %.2s", "bar");
- if (memcmp(buf, "foo ba", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 4) Failed. The correct string is "
- "'foo ba' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- /* Test 5 */
- wsprintf(buf, "foo %5.2s", "bar");
- if (memcmp(buf, "foo ba", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 5) Failed. The correct string is "
- "'foo ba' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- /* Test 6 */
- wsprintf(buf, "foo %-5s", "bar");
- if (memcmp(buf, "foo bar ", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 6) Failed. The correct string is "
- "'foo bar' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- /* Test 7 */
- wsprintf(buf, "foo %05s", "bar");
- if (memcmp(buf, "foo 00bar", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 7) Failed. The correct string is "
- "'foo 00bar' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
- return PASS;
-}
-
-
-int __cdecl main(int argc, char *argv[])
-{
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- if(test1())
- {
- Fail("%s '%s'\n",ErrorMessage,BadResult);
- }
-
- PAL_Terminate();
- return PASS;
-
-}
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test2/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test2/testinfo.dat
deleted file mode 100644
index 32e51df28b..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test2/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = Miscellaneous
-Function = wsprintfA
-Name = Positive test of wsprintfA
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Test the %s and %ls formatters with various flags.
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test3/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test3/CMakeLists.txt
deleted file mode 100644
index 8043ccd60b..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test3/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.c
-)
-
-add_executable(paltest_wsprintfa_test3
- ${SOURCES}
-)
-
-add_dependencies(paltest_wsprintfa_test3 coreclrpal)
-
-target_link_libraries(paltest_wsprintfa_test3
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test3/test.c b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test3/test.c
deleted file mode 100644
index bb598d9d63..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test3/test.c
+++ /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.
-
-/*============================================================
-**
-** Source: test.c
-**
-** Purpose: Test for wsprintfA() function
-**
-**
-**=========================================================*/
-
-#include <palsuite.h>
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with strlen */
-
-char * ErrorMessage;
-char buf[256];
-
-BOOL test1()
-{
-
- /* Test 1 */
- wsprintf(buf, "foo %S", convert("bar"));
- if (memcmp(buf, "foo bar", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 1) Failed. The correct string is "
- "'foo bar' and the result returned was ";
- return FAIL;
- }
-
- /* Test 2 */
- wsprintf(buf, "foo %hS", "bar");
- if (memcmp(buf, "foo bar", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 2) Failed. The correct string is "
- "'foo bar' and the result returned was ";
- return FAIL;
- }
-
- /* Test 3 */
- wsprintf(buf, "foo %lS", convert("bar"));
- if (memcmp(buf, "foo bar", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 3) Failed. The correct string is '"
- "foo bar' and the result returned was ";
- return FAIL;
- }
-
-
- /* Test 4 */
- wsprintf(buf, "foo %5S", convert("bar"));
- if (memcmp(buf, "foo bar", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 4) Failed. The correct string is "
- "'foo bar' and the result returned was ";
- return FAIL;
- }
-
- /* Test 5 */
- wsprintf(buf, "foo %.2S", convert("bar"));
- if (memcmp(buf, "foo ba", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 5) Failed. The correct string is "
- "'foo ba' and the result returned was ";
- return FAIL;
- }
-
- /* Test 6 */
- wsprintf(buf, "foo %5.2S", convert("bar"));
- if (memcmp(buf, "foo ba", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 6) Failed. The correct string is "
- "'foo ba' and the result returned was ";
- return FAIL;
- }
-
- /* Test 7 */
- wsprintf(buf, "foo %-5S", convert("bar"));
- if (memcmp(buf, "foo bar ", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 7) Failed. The correct string is "
- "'foo bar ' and the result returned was ";
- return FAIL;
- }
-
- /* Test 8 */
- wsprintf(buf, "foo %05S", convert("bar"));
- if (memcmp(buf, "foo 00bar", strlen(buf) + 1) != 0) {
- ErrorMessage = "ERROR: (Test 8) Failed. The correct string is "
- "'foo 00bar' and the result returned was ";
- return FAIL;
- }
- return PASS;
-}
-
-int __cdecl main(int argc, char *argv[])
-{
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- if(test1()) {
- Fail("%s '%s'\n",ErrorMessage,buf);
-
- }
-
- PAL_Terminate();
- return PASS;
-
-}
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test3/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test3/testinfo.dat
deleted file mode 100644
index 0660aa17a3..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test3/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = Miscellaneous
-Function = wsprintfA
-Name = Positive test of wsprintfA
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Test the %S and wide characters in general.
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test6/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test6/CMakeLists.txt
deleted file mode 100644
index 6a5caf95c2..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test6/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.c
-)
-
-add_executable(paltest_wsprintfa_test6
- ${SOURCES}
-)
-
-add_dependencies(paltest_wsprintfa_test6 coreclrpal)
-
-target_link_libraries(paltest_wsprintfa_test6
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test6/test.c b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test6/test.c
deleted file mode 100644
index 08d97f467a..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test6/test.c
+++ /dev/null
@@ -1,114 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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 wsprintfA() function
-**
-**
-**=========================================================*/
-
-#include <palsuite.h>
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with strlen */
-
-char * ErrorMessage;
-char buf[256];
-
-BOOL test1()
-{
- WCHAR wc = 'c';
-
- /* Test 1 */
- wsprintf(buf, "foo %c", 'b');
- if (memcmp(buf, "foo b", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 1) Failed. The correct string is "
- "'foo b' and the result returned was ";
- return FAIL;
- }
-
- /* Test 2 */
- wsprintf(buf, "foo %hc", 'b');
- if (memcmp(buf, "foo b", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 2) Failed. The correct string is "
- "'foo b' and the result returned was ";
- return FAIL;
- }
-
- /* Test 3 */
- wsprintf(buf, "foo %lc", wc);
- if (memcmp(buf, "foo c", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 3) Failed. The correct string is "
- "'foo c' and the result returned was ";
- return FAIL;
- }
-
-
- /* Test 4 */
- wsprintf(buf, "foo %5c", 'b');
- if (memcmp(buf, "foo b", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 4) Failed. The correct string is "
- "'foo bar' and the result returned was ";
- return FAIL;
- }
-
- /* Test 5 */
- wsprintf(buf, "foo %-5c", 'b');
- if (memcmp(buf, "foo b ", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 5) Failed. The correct string is "
- "'foo b ' and the result returned was ";
- return FAIL;
- }
-
- /* Test 6 */
- wsprintf(buf, "foo %05c", 'b');
- if (memcmp(buf, "foo 0000b", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 6) Failed. The correct string is "
- "'foo 0000b' and the result returned was ";
- return FAIL;
- }
-
- /* Test 7 */
- wsprintf(buf, "foo %#c", 'b');
- if (memcmp(buf, "foo b", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 7) Failed. The correct string is "
- "'foo b' and the result returned was ";
- return FAIL;
- }
- return PASS;
-}
-
-int __cdecl main(int argc, char *argv[])
-{
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- if(test1())
- {
- Fail("%s '%s'\n",ErrorMessage,buf);
- }
-
- PAL_Terminate();
- return PASS;
-
-}
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test6/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test6/testinfo.dat
deleted file mode 100644
index 31b0f667b6..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test6/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = Miscellaneous
-Function = wsprintfA
-Name = Positive test of wsprintfA
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Test the %c formatter.
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test7/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test7/CMakeLists.txt
deleted file mode 100644
index 0885f0f21e..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test7/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.c
-)
-
-add_executable(paltest_wsprintfa_test7
- ${SOURCES}
-)
-
-add_dependencies(paltest_wsprintfa_test7 coreclrpal)
-
-target_link_libraries(paltest_wsprintfa_test7
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test7/test.c b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test7/test.c
deleted file mode 100644
index 6d380efaa9..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test7/test.c
+++ /dev/null
@@ -1,112 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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 wsprintfA() function
-**
-**
-**=========================================================*/
-
-#include <palsuite.h>
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with strlen */
-
-char * ErrorMessage;
-char buf[256];
-
-BOOL test1()
-{
- WCHAR wb = 'b';
-
- /* Test 1 */
- wsprintf(buf, "foo %C", wb);
- if (memcmp(buf, "foo b", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 1) Failed. The correct string is "
- "'foo b' and the result returned was ";
- return FAIL;
- }
-
- /* Test 2 */
- wsprintf(buf, "foo %hC", wb);
- if (memcmp(buf, "foo b", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 2) Failed. The correct string is "
- "'foo b' and the result returned was ";
- return FAIL;
- }
-
- /* Test 3 */
- wsprintf(buf, "foo %lC", 'c');
- if (memcmp(buf, "foo c", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 3) Failed. The correct string is "
- "'foo c' and the result returned was ";
- return FAIL;
- }
-
-
- /* Test 4 */
- wsprintf(buf, "foo %5C", wb);
- if (memcmp(buf, "foo b", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 4) Failed. The correct string is "
- "'foo b' and the result returned was ";
- return FAIL;
- }
-
- /* Test 5 */
- wsprintf(buf, "foo %-5C", wb);
- if (memcmp(buf, "foo b ", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 5) Failed. The correct string is "
- "'foo b ' and the result returned was ";
- return FAIL;
- }
-
- /* Test 6 */
- wsprintf(buf, "foo %05C", wb);
- if (memcmp(buf, "foo 0000b", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 6) Failed. The correct string is "
- "'foo 0000b' and the result returned was ";
- return FAIL;
- }
-
- /* Test 7 */
- wsprintf(buf, "foo %#C", wb);
- if (memcmp(buf, "foo b", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 7) Failed. The correct string is "
- "'foo b' and the result returned was ";
- return FAIL;
- }
- return PASS;
-}
-
-int __cdecl main(int argc, char *argv[])
-{
-
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- if(test1())
- {
- Fail("%s '%s'\n",ErrorMessage,buf);
-
- }
-
- PAL_Terminate();
- return PASS;
-
-}
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test7/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test7/testinfo.dat
deleted file mode 100644
index 31b0f667b6..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test7/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = Miscellaneous
-Function = wsprintfA
-Name = Positive test of wsprintfA
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Test the %c formatter.
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test8/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test8/CMakeLists.txt
deleted file mode 100644
index 3c4b5ed36e..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test8/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.c
-)
-
-add_executable(paltest_wsprintfa_test8
- ${SOURCES}
-)
-
-add_dependencies(paltest_wsprintfa_test8 coreclrpal)
-
-target_link_libraries(paltest_wsprintfa_test8
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test8/test.c b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test8/test.c
deleted file mode 100644
index 7367461544..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test8/test.c
+++ /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.
-
-/*============================================================
-**
-** Source: test.c
-**
-** Purpose: Test for wsprintfA() function
-**
-**
-**=========================================================*/
-
-#include <palsuite.h>
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with strlen */
-
-char * ErrorMessage;
-char buf[256];
-
-BOOL test1()
-{
- int pos = 42;
-
- /* Test 1 */
- wsprintf(buf, "foo %d", pos);
- if (memcmp(buf, "foo 42", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 1) Failed. The correct string is "
- "'foo 42' and the result returned was ";
- return FAIL;
- }
-
- /* Test 2 */
- wsprintf(buf, "foo %ld", 0xFFFF);
- if (memcmp(buf, "foo 65535", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 2) Failed. The correct string is "
- "'foo 65535' and the result returned was ";
- return FAIL;
- }
-
- /* Test 3 */
- wsprintf(buf, "foo %3d", pos);
- if (memcmp(buf, "foo 42", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 3) Failed. The correct string is "
- "'foo 42' and the result returned was ";
- return FAIL;
- }
-
- /* Test 4 */
- wsprintf(buf, "foo %-3d", pos);
- if (memcmp(buf, "foo 42 ", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 4) Failed. The correct string is "
- "'foo 42 ' and the result returned was ";
- return FAIL;
- }
-
- /* Test 5 */
- wsprintf(buf, "foo %.1d", pos);
- if (memcmp(buf, "foo 42", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 5) Failed. The correct string is "
- "'foo 42' and the result returned was ";
- return FAIL;
- }
-
- /* Test 6 */
- wsprintf(buf, "foo %.3d", pos);
- if (memcmp(buf, "foo 042", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 6) Failed. The correct string is "
- "'foo 042' and the result returned was ";
- return FAIL;
- }
-
- /* Test 7 */
- wsprintf(buf, "foo %03d", pos);
- if (memcmp(buf, "foo 042", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 7) Failed. The correct string is "
- "'foo 042' and the result returned was ";
- return FAIL;
- }
-
- /* Test 8 */
- wsprintf(buf, "foo %#d", pos);
- if (memcmp(buf, "foo 42", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 8) Failed. The correct string is "
- "'foo 42' and the result returned was ";
- return FAIL;
- }
- return PASS;
-}
-
-int __cdecl main(int argc, char *argv[])
-{
-
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- if(test1())
- {
- Fail("%s '%s'\n",ErrorMessage,buf);
- }
-
- PAL_Terminate();
- return PASS;
-
-}
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test8/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test8/testinfo.dat
deleted file mode 100644
index 75f4fbf121..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test8/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = Miscellaneous
-Function = wsprintfA
-Name = Positive test of wsprintfA
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Test the %d formatter.
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test9/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test9/CMakeLists.txt
deleted file mode 100644
index dcbb22ebb5..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test9/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.c
-)
-
-add_executable(paltest_wsprintfa_test9
- ${SOURCES}
-)
-
-add_dependencies(paltest_wsprintfa_test9 coreclrpal)
-
-target_link_libraries(paltest_wsprintfa_test9
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test9/test.c b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test9/test.c
deleted file mode 100644
index 9f123bcc6d..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test9/test.c
+++ /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.
-
-/*============================================================
-**
-** Source: test.c
-**
-** Purpose: Test for wsprintfA() function
-**
-**
-**=========================================================*/
-
-#include <palsuite.h>
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with strlen */
-
-char * ErrorMessage;
-char buf[256];
-
-BOOL test1()
-{
-
- int pos = 42;
-
-
- /* Test 1 */
- wsprintf(buf, "foo %i", pos);
- if (memcmp(buf, "foo 42", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 1) Failed. The correct string is "
- "'foo 42' and the result returned was ";
- return FAIL;
- }
-
- /* Test 2 */
- wsprintf(buf, "foo %li", 0xFFFF);
- if (memcmp(buf, "foo 65535", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 2) Failed. The correct string is "
- "'foo 65535' and the result returned was ";
- return FAIL;
- }
-
-
- /* Test 3 */
- wsprintf(buf, "foo %3i", pos);
- if (memcmp(buf, "foo 42", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 3) Failed. The correct string is "
- "'foo 42' and the result returned was ";
- return FAIL;
- }
-
- /* Test 4 */
- wsprintf(buf, "foo %-3i", pos);
- if (memcmp(buf, "foo 42 ", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 4) Failed. The correct string is "
- "'foo 42 ' and the result returned was ";
- return FAIL;
- }
-
- /* Test 5 */
- wsprintf(buf, "foo %.1i", pos);
- if (memcmp(buf, "foo 42", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 5) Failed. The correct string is "
- "'foo 42' and the result returned was ";
- return FAIL;
- }
-
- /* Test 6 */
- wsprintf(buf, "foo %.3i", pos);
- if (memcmp(buf, "foo 042", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 6) Failed. The correct string is "
- "'foo 042' and the result returned was ";
- return FAIL;
- }
-
- /* Test 7 */
- wsprintf(buf, "foo %03i", pos);
- if (memcmp(buf, "foo 042", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 7) Failed. The correct string is "
- "'foo 042' and the result returned was ";
- return FAIL;
- }
-
- /* Test 8 */
- wsprintf(buf, "foo %#i", pos);
- if (memcmp(buf, "foo 42", strlen(buf) + 1) != 0)
- {
- ErrorMessage = "ERROR: (Test 8) Failed. The correct string is "
- "'foo 42' and the result returned was ";
- return FAIL;
- }
-
- return PASS;
-}
-
-int __cdecl main(int argc, char *argv[])
-{
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- if(test1())
- {
- Fail("%s '%s'\n",ErrorMessage,buf);
- }
-
- PAL_Terminate();
- return PASS;
-
-}
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test9/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/wsprintfA/test9/testinfo.dat
deleted file mode 100644
index 2a3689e4dd..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfA/test9/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = Miscellaneous
-Function = wsprintfA
-Name = Positive test of wsprintfA
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Test the %i formatter.
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/wsprintfW/CMakeLists.txt
deleted file mode 100644
index f40d4151d6..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/CMakeLists.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-add_subdirectory(test1)
-add_subdirectory(test11)
-add_subdirectory(test12)
-add_subdirectory(test13)
-add_subdirectory(test2)
-add_subdirectory(test3)
-add_subdirectory(test6)
-add_subdirectory(test7)
-add_subdirectory(test8)
-add_subdirectory(test9)
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test1/CMakeLists.txt
deleted file mode 100644
index b1c0fb3d0b..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test1/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.c
-)
-
-add_executable(paltest_wsprintfw_test1
- ${SOURCES}
-)
-
-add_dependencies(paltest_wsprintfw_test1 coreclrpal)
-
-target_link_libraries(paltest_wsprintfw_test1
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test1/test.c b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test1/test.c
deleted file mode 100644
index 700cb134bd..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test1/test.c
+++ /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.
-
-/*============================================================
-**
-** Source: test.c
-**
-** Purpose: Test for wsprintfW() function
-**
-**
-**=========================================================*/
-
-#define UNICODE
-#include <palsuite.h>
-
-
-char * ErrorMessage = NULL;
-WCHAR * BadResult = NULL;
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with strlen */
-
-
-BOOL test1()
-{
- char checkstr[] = "hello world";
-
- WCHAR buf[256];
-
- /* Test a simple string */
- wsprintf(buf, convert("hello world"));
-
- /* Error message */
- ErrorMessage = "ERROR: (Test 1) Failed on 'hello world' test. "
- "The correct string is 'hello world' and the result returned was ";
- BadResult = buf;
-
- return (memcmp(convert(checkstr), buf, wcslen(buf)*2+2) != 0);
-}
-
-int __cdecl main(int argc, char *argv[]) {
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- if(test1()) {
- Fail("%s '%s'\n",ErrorMessage,convertC(BadResult));
-
- }
-
- PAL_Terminate();
- return PASS;
-
-}
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test1/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test1/testinfo.dat
deleted file mode 100644
index f36aced027..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test1/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = Miscellaneous
-Function = wsprintfW
-Name = Positive test of wsprintfW
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Test the very basic functionality of wsprintfW.
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test11/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test11/CMakeLists.txt
deleted file mode 100644
index a5d73ed413..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test11/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.c
-)
-
-add_executable(paltest_wsprintfw_test11
- ${SOURCES}
-)
-
-add_dependencies(paltest_wsprintfw_test11 coreclrpal)
-
-target_link_libraries(paltest_wsprintfw_test11
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test11/test.c b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test11/test.c
deleted file mode 100644
index dc1e7a7758..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test11/test.c
+++ /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.
-
-/*============================================================
-**
-** Source: test.c
-**
-** Purpose: Test for wsprintfW() function
-**
-**
-**=========================================================*/
-
-#define UNICODE
-#include <palsuite.h>
-
-
-
-char * ErrorMessage = NULL;
-WCHAR * BadResult = NULL;
-WCHAR buf[256];
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with strlen */
-
-
-BOOL test1()
-{
-
- int pos = 42;
-
- wsprintf(buf, convert("foo %u"), pos);
- if (memcmp(buf, convert("foo 42"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 1) Failed. The correct string is"
- " 'foo 42' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %lu"), 0xFFFF);
- if (memcmp(buf, convert("foo 65535"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 2) Failed. The correct string is"
- " 'foo 65535' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %hu"), 0xFFFF);
- if (memcmp(buf, convert("foo 65535"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 3) Failed. The correct string is"
- " 'foo 65535' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %3u"), pos);
- if (memcmp(buf, convert("foo 42"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 4) Failed. The correct string is"
- " 'foo 42' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %-3u"), pos);
- if (memcmp(buf, convert("foo 42 "), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 5) Failed. The correct string is"
- " 'foo 42 ' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %.1u"), pos);
- if (memcmp(buf, convert("foo 42"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 6) Failed. The correct string is"
- " 'foo 42' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %.3u"), pos);
- if (memcmp(buf, convert("foo 042"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 7) Failed. The correct string is"
- " 'foo 042' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %03u"), pos);
- if (memcmp(buf, convert("foo 042"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 8) Failed. The correct string is"
- " 'foo 042' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %#u"), pos);
- if (memcmp(buf, convert("foo 42"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 9) Failed. The correct string is"
- " 'foo 42' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- return PASS;
-}
-
-int __cdecl main(int argc, char *argv[])
-{
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- if(test1())
- {
- Fail("%s '%s'\n",ErrorMessage,convertC(BadResult));
-
- }
-
- PAL_Terminate();
- return PASS;
-
-}
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test11/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test11/testinfo.dat
deleted file mode 100644
index bb85d63f1b..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test11/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = Miscellaneous
-Function = wsprintfW
-Name = Positive test of wsprintfW
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Test %u formatter with wsprintfW.
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test12/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test12/CMakeLists.txt
deleted file mode 100644
index 3811fb07c9..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test12/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.c
-)
-
-add_executable(paltest_wsprintfw_test12
- ${SOURCES}
-)
-
-add_dependencies(paltest_wsprintfw_test12 coreclrpal)
-
-target_link_libraries(paltest_wsprintfw_test12
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test12/test.c b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test12/test.c
deleted file mode 100644
index 6ba456b3bc..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test12/test.c
+++ /dev/null
@@ -1,128 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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 wsprintfW() function
-**
-**
-**=========================================================*/
-
-#define UNICODE
-#include <palsuite.h>
-
-
-char * ErrorMessage = NULL;
-WCHAR * BadResult = NULL;
-WCHAR buf[256];
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with strlen */
-
-BOOL test1()
-{
- int pos = 0x1234ab;
-
- wsprintf(buf, convert("foo %x"), pos);
- if (memcmp(buf, convert("foo 1234ab"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 1) Failed. The correct string is"
- " 'foo 1234ab' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %lx"), pos);
- if (memcmp(buf, convert("foo 1234ab"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 2) Failed. The correct string is"
- " 'foo 1234ab' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %7x"), pos);
- if (memcmp(buf, convert("foo 1234ab"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 3) Failed. The correct string is"
- " 'foo 1234ab' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %-7x"), pos);
- if (memcmp(buf, convert("foo 1234ab "), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 4) Failed. The correct string is"
- " 'foo 1234ab ' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %.1x"), pos);
- if (memcmp(buf, convert("foo 1234ab"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 5) Failed. The correct string is"
- " 'foo 1234ab' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %.7x"), pos);
- if (memcmp(buf, convert("foo 01234ab"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 6) Failed. The correct string is"
- " 'foo 01234ab' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %07x"), pos);
- if (memcmp(buf, convert("foo 01234ab"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 7) Failed. The correct string is"
- " 'foo 01234ab' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %#x"), pos);
- if (memcmp(buf, convert("foo 0x1234ab"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 8) Failed. The correct string is"
- " 'foo 0x1234ab' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- return PASS;
-}
-
-int __cdecl main(int argc, char *argv[])
-{
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- if(test1())
- {
- Fail("%s '%s'\n",ErrorMessage,convertC(BadResult));
-
- }
-
- PAL_Terminate();
- return PASS;
-
-}
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test12/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test12/testinfo.dat
deleted file mode 100644
index 0d38a20bcc..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test12/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = Miscellaneous
-Function = wsprintfW
-Name = Positive test of wsprintfW
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Test %x formatter with wsprintfW.
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test13/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test13/CMakeLists.txt
deleted file mode 100644
index 617abb854c..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test13/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.c
-)
-
-add_executable(paltest_wsprintfw_test13
- ${SOURCES}
-)
-
-add_dependencies(paltest_wsprintfw_test13 coreclrpal)
-
-target_link_libraries(paltest_wsprintfw_test13
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test13/test.c b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test13/test.c
deleted file mode 100644
index dd0daae0a0..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test13/test.c
+++ /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.
-
-/*============================================================
-**
-** Source: test.c
-**
-** Purpose: Test for wsprintfW() function
-**
-**
-**=========================================================*/
-
-#define UNICODE
-#include <palsuite.h>
-
-char * ErrorMessage = NULL;
-WCHAR * BadResult = NULL;
-WCHAR buf[256];
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with strlen */
-
-BOOL test1()
-{
- int pos = 0x1234ab;
-
- wsprintf(buf, convert("foo %X"), pos);
- if (memcmp(buf, convert("foo 1234AB"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 1) Failed. The correct string is"
- " 'foo 1234AB' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %lX"), pos);
- if (memcmp(buf, convert("foo 1234AB"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 2) Failed. The correct string is"
- " 'foo 1234AB' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %7X"), pos);
- if (memcmp(buf, convert("foo 1234AB"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 3) Failed. The correct string is"
- " 'foo 1234AB' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %-7X"), pos);
- if (memcmp(buf, convert("foo 1234AB "), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 4) Failed. The correct string is"
- " 'foo 1234AB ' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %.1X"), pos);
- if (memcmp(buf, convert("foo 1234AB"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 5) Failed. The correct string is"
- " 'foo 1234AB' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %.7X"), pos);
- if (memcmp(buf, convert("foo 01234AB"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 6) Failed. The correct string is"
- " 'foo 01234AB' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %07X"), pos);
- if (memcmp(buf, convert("foo 01234AB"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 7) Failed. The correct string is"
- " 'foo 01234AB' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %#X"), pos);
- if (memcmp(buf, convert("foo 0X1234AB"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 8) Failed. The correct string is"
- " 'foo 0X1234AB' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- return PASS;
-}
-
-int __cdecl main(int argc, char *argv[])
-{
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- if(test1())
- {
- Fail("%s '%s'\n",ErrorMessage,convertC(BadResult));
-
- }
-
- PAL_Terminate();
- return PASS;
-
-}
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test13/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test13/testinfo.dat
deleted file mode 100644
index c16a43f7b7..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test13/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = Miscellaneous
-Function = wsprintfW
-Name = Positive test of wsprintfW
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Test %X formatter with wsprintfW.
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test2/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test2/CMakeLists.txt
deleted file mode 100644
index 00b26da2e6..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test2/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.c
-)
-
-add_executable(paltest_wsprintfw_test2
- ${SOURCES}
-)
-
-add_dependencies(paltest_wsprintfw_test2 coreclrpal)
-
-target_link_libraries(paltest_wsprintfw_test2
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test2/test.c b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test2/test.c
deleted file mode 100644
index f25ab6c2f4..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test2/test.c
+++ /dev/null
@@ -1,108 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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 wsprintfW() function
-**
-**
-**=========================================================*/
-#define UNICODE
-#include <palsuite.h>
-
-
-char * ErrorMessage = NULL;
-WCHAR * BadResult = NULL;
-WCHAR buf[256];
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with strlen */
-
-
-BOOL test1()
-{
-
- wsprintf(buf, convert("foo %s"), convert("bar"));
- if (memcmp(buf, convert("foo bar"), wcslen(buf)*2+2) != 0)
- {
- ErrorMessage = "ERROR: (Test 1) Failed. The correct string is 'foo bar'"
- " and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %ls"), convert("bar"));
- if (memcmp(buf, convert("foo bar"), wcslen(buf)*2 + 2) != 0){
- ErrorMessage = "ERROR: (Test 2) Failed. The correct string is 'foo bar'"
- " and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %5s"), convert("bar"));
- if (memcmp(buf, convert("foo bar"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 3) Failed. The correct string is"
- " 'foo bar' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
- wsprintf(buf, convert("foo %.2s"), convert("bar"));
- if (memcmp(buf, convert("foo ba"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 4) Failed. The correct string is 'foo ba'"
- " and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
- wsprintf(buf, convert("foo %5.2s"), convert("bar"));
- if (memcmp(buf, convert("foo ba"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 5) Failed. The correct string is"
- " 'foo ba' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
- wsprintf(buf, convert("foo %-5s"), convert("bar"));
- if (memcmp(buf, convert("foo bar "), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 6) Failed. The correct string is"
- " 'foo bar ' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
- wsprintf(buf, convert("foo %05s"), convert("bar"));
- if (memcmp(buf, convert("foo 00bar"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 7) Failed. The correct string is"
- " 'foo 00bar' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- return PASS;
-}
-
-int __cdecl main(int argc, char *argv[])
-{
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- if(test1())
- {
- Fail("%s '%s'\n",ErrorMessage,convertC(BadResult));
- }
-
- PAL_Terminate();
- return PASS;
-
-}
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test2/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test2/testinfo.dat
deleted file mode 100644
index a2a7bb2d39..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test2/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = Miscellaneous
-Function = wsprintfW
-Name = Positive test of wsprintfW
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Test %s formatter with wsprintfW.
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test3/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test3/CMakeLists.txt
deleted file mode 100644
index 25c6185d12..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test3/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.c
-)
-
-add_executable(paltest_wsprintfw_test3
- ${SOURCES}
-)
-
-add_dependencies(paltest_wsprintfw_test3 coreclrpal)
-
-target_link_libraries(paltest_wsprintfw_test3
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test3/test.c b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test3/test.c
deleted file mode 100644
index a52d617e47..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test3/test.c
+++ /dev/null
@@ -1,127 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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 wsprintfW() function
-**
-**
-**=========================================================*/
-#define UNICODE
-#include <palsuite.h>
-
-
-
-char * ErrorMessage = NULL;
-WCHAR * BadResult = NULL;
-WCHAR buf[256];
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with strlen */
-
-
-BOOL test1()
-{
-
- wsprintf(buf, convert("foo %S"), "bar");
- if (memcmp(buf, convert("foo bar"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 1) Failed. The correct string is"
- " 'foo bar' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %hS"), "bar");
- if (memcmp(buf, convert("foo bar"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 2) Failed. The correct string is"
- " 'foo bar' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %lS"), convert("bar"));
- if (memcmp(buf, convert("foo bar"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 3) Failed. The correct string is"
- " 'foo bar' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %5S"), "bar");
- if (memcmp(buf, convert("foo bar"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 4) Failed. The correct string is"
- " 'foo bar' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %.2S"), "bar");
- if (memcmp(buf, convert("foo ba"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 5) Failed. The correct string is"
- " 'foo ba' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %5.2S"), "bar");
- if (memcmp(buf, convert("foo ba"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 6) Failed. The correct string is"
- " 'foo ba' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %-5S"), "bar");
- if (memcmp(buf, convert("foo bar "), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 7) Failed. The correct string is"
- " 'foo bar ' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %05S"), "bar");
- if (memcmp(buf, convert("foo 00bar"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 8) Failed. The correct string is"
- " 'foo 00bar' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- return PASS;
-}
-
-int __cdecl main(int argc, char *argv[])
-{
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- if(test1())
- {
- Fail("%s '%s'\n",ErrorMessage,convertC(BadResult));
-
- }
-
- PAL_Terminate();
- return PASS;
-
-}
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test3/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test3/testinfo.dat
deleted file mode 100644
index 46b7b7459d..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test3/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = Miscellaneous
-Function = wsprintfW
-Name = Positive test of wsprintfW
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Test %S formatter with wsprintfW.
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test6/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test6/CMakeLists.txt
deleted file mode 100644
index c63a4d5c82..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test6/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.c
-)
-
-add_executable(paltest_wsprintfw_test6
- ${SOURCES}
-)
-
-add_dependencies(paltest_wsprintfw_test6 coreclrpal)
-
-target_link_libraries(paltest_wsprintfw_test6
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test6/test.c b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test6/test.c
deleted file mode 100644
index 513f1f7941..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test6/test.c
+++ /dev/null
@@ -1,115 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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 wsprintfW() function
-**
-**
-**=========================================================*/
-#define UNICODE
-#include <palsuite.h>
-
-
-char * ErrorMessage = NULL;
-WCHAR * BadResult = NULL;
-WCHAR buf[256];
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with strlen */
-
-BOOL test1()
-{
- WCHAR wc = 'b';
-
- wsprintf(buf, convert("foo %c"), wc);
- if (memcmp(buf, convert("foo b"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 1) Failed. The correct string is"
- " 'foo b' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %hc"), wc);
- if (memcmp(buf, convert("foo b"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 2) Failed. The correct string is 'foo b'"
- " and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %lc"), wc);
- if (memcmp(buf, convert("foo b"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 3) Failed. The correct string is 'foo b'"
- " and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %5c"), wc);
- if (memcmp(buf, convert("foo b"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 4) Failed. The correct string is"
- " 'foo b' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %-5c"), wc);
- if (memcmp(buf, convert("foo b "), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 5) Failed. The correct string is"
- " 'foo b ' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %05c"), wc);
- if (memcmp(buf, convert("foo 0000b"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 6) Failed. The correct string is"
- " 'foo 0000b' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %#c"), wc);
- if (memcmp(buf, convert("foo b"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 7) Failed. The correct string is 'foo b'"
- " and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
- return PASS;
-}
-int __cdecl main(int argc, char *argv[])
-{
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- if(test1())
- {
- Fail("%s '%s'\n",ErrorMessage,convertC(BadResult));
-
- }
-
- PAL_Terminate();
- return PASS;
-
-}
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test6/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test6/testinfo.dat
deleted file mode 100644
index 627b76f602..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test6/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = Miscellaneous
-Function = wsprintfW
-Name = Positive test of wsprintfW
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Test %c formatter with wsprintfW.
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test7/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test7/CMakeLists.txt
deleted file mode 100644
index 25e43107ff..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test7/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.c
-)
-
-add_executable(paltest_wsprintfw_test7
- ${SOURCES}
-)
-
-add_dependencies(paltest_wsprintfw_test7 coreclrpal)
-
-target_link_libraries(paltest_wsprintfw_test7
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test7/test.c b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test7/test.c
deleted file mode 100644
index 99e73b13ce..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test7/test.c
+++ /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.
-
-/*============================================================
-**
-** Source: test.c
-**
-** Purpose: Test for wsprintfW() function
-**
-**
-**=========================================================*/
-#define UNICODE
-#include <palsuite.h>
-
-
-
-char * ErrorMessage = NULL;
-WCHAR * BadResult = NULL;
-WCHAR buf[256];
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with strlen */
-
-
-BOOL test1()
-{
- WCHAR wb = 'b';
-
- wsprintf(buf, convert("foo %C"), 'b');
- if (memcmp(buf, convert("foo b"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 1) Failed. The correct string is"
- " 'foo b' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %hC"), 'b');
- if (memcmp(buf, convert("foo b"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 2) Failed. The correct string is"
- " 'foo b' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %lC"), wb);
- if (memcmp(buf, convert("foo b"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 3) Failed. The correct string is"
- " 'foo b' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %5C"), 'b');
- if (memcmp(buf, convert("foo b"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 4) Failed. The correct string is"
- " 'foo b' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %-5C"), 'b');
- if (memcmp(buf, convert("foo b "), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 5) Failed. The correct string is"
- " 'foo b ' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %05C"), 'b');
- if (memcmp(buf, convert("foo 0000b"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 6) Failed. The correct string is"
- " 'foo 0000b' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %#C"), 'b');
- if (memcmp(buf, convert("foo b"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 7) Failed. The correct string is"
- " 'foo b' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
- return PASS;
-}
-int __cdecl main(int argc, char *argv[])
-{
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- if(test1())
- {
- Fail("%s '%s'\n",ErrorMessage,convertC(BadResult));
-
- }
-
- PAL_Terminate();
- return PASS;
-
-}
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test7/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test7/testinfo.dat
deleted file mode 100644
index ffcb47a37f..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test7/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = Miscellaneous
-Function = wsprintfW
-Name = Positive test of wsprintfW
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Test %C formatter with wsprintfW.
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test8/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test8/CMakeLists.txt
deleted file mode 100644
index a6478a2af0..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test8/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.c
-)
-
-add_executable(paltest_wsprintfw_test8
- ${SOURCES}
-)
-
-add_dependencies(paltest_wsprintfw_test8 coreclrpal)
-
-target_link_libraries(paltest_wsprintfw_test8
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test8/test.c b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test8/test.c
deleted file mode 100644
index 63c296eb22..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test8/test.c
+++ /dev/null
@@ -1,128 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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 wsprintfW() function
-**
-**
-**=========================================================*/
-#define UNICODE
-#include <palsuite.h>
-
-
-
-char * ErrorMessage = NULL;
-WCHAR * BadResult = NULL;
-WCHAR buf[256];
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with strlen */
-
-
-BOOL test1()
-{
- int pos = 42;
-
- wsprintf(buf, convert("foo %d"), pos);
- if (memcmp(buf, convert("foo 42"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 1) Failed. The correct string is"
- " 'foo 42' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %ld"), 0xFFFF);
- if (memcmp(buf, convert("foo 65535"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 2) Failed. The correct string is"
- " 'foo 65535' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %3d"), pos);
- if (memcmp(buf, convert("foo 42"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 3) Failed. The correct string is"
- " 'foo 42' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %-3d"), pos);
- if (memcmp(buf, convert("foo 42 "), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 4) Failed. The correct string is"
- " 'foo 42 ' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %.1d"), pos);
- if (memcmp(buf, convert("foo 42"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 5) Failed. The correct string is"
- " 'foo 42' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %.3d"), pos);
- if (memcmp(buf, convert("foo 042"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 6) Failed. The correct string is"
- " 'foo 042' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %03d"), pos);
- if (memcmp(buf, convert("foo 042"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 7) Failed. The correct string is"
- " 'foo 042' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %#d"), pos);
- if (memcmp(buf, convert("foo 42"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 8) Failed. The correct string is"
- " 'foo 42' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- return PASS;
-}
-int __cdecl main(int argc, char *argv[])
-{
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- if(test1())
- {
- Fail("%s '%s'\n",ErrorMessage,convertC(BadResult));
-
- }
-
- PAL_Terminate();
- return PASS;
-
-}
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test8/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test8/testinfo.dat
deleted file mode 100644
index 4238671918..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test8/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = Miscellaneous
-Function = wsprintfW
-Name = Positive test of wsprintfW
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Test %d formatter with wsprintfW.
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test9/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test9/CMakeLists.txt
deleted file mode 100644
index e09867b1a7..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test9/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.c
-)
-
-add_executable(paltest_wsprintfw_test9
- ${SOURCES}
-)
-
-add_dependencies(paltest_wsprintfw_test9 coreclrpal)
-
-target_link_libraries(paltest_wsprintfw_test9
- pthread
- m
- coreclrpal
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test9/test.c b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test9/test.c
deleted file mode 100644
index 0a49d9c2c5..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test9/test.c
+++ /dev/null
@@ -1,128 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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 wsprintfW() function
-**
-**
-**=========================================================*/
-
-#define UNICODE
-#include <palsuite.h>
-
-
-char * ErrorMessage = NULL;
-WCHAR * BadResult = NULL;
-WCHAR buf[256];
-
-/* memcmp is used to verify the results, so this test is dependent on it. */
-/* ditto with strlen */
-
-
-BOOL test1()
-{
- int pos = 42;
-
- wsprintf(buf, convert("foo %i"), pos);
- if (memcmp(buf, convert("foo 42"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 1) Failed. The correct string is"
- " 'foo 42' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %li"), 0xFFFF);
- if (memcmp(buf, convert("foo 65535"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 2) Failed. The correct string is"
- " 'foo 65535' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %3i"), pos);
- if (memcmp(buf, convert("foo 42"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 3) Failed. The correct string is"
- " 'foo 42' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %-3i"), pos);
- if (memcmp(buf, convert("foo 42 "), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 4) Failed. The correct string is"
- " 'foo 42 ' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %.1i"), pos);
- if (memcmp(buf, convert("foo 42"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 5) Failed. The correct string is"
- " 'foo 42' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %.3i"), pos);
- if (memcmp(buf, convert("foo 042"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 6) Failed. The correct string is"
- " 'foo 042' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %03i"), pos);
- if (memcmp(buf, convert("foo 042"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 7) Failed. The correct string is"
- " 'foo 042' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- wsprintf(buf, convert("foo %#i"), pos);
- if (memcmp(buf, convert("foo 42"), wcslen(buf)*2 + 2) != 0)
- {
- ErrorMessage = "ERROR: (Test 8) Failed. The correct string is"
- " 'foo 42' and the result returned was ";
- BadResult = buf;
- return FAIL;
- }
-
- return PASS;
-}
-
-int __cdecl main(int argc, char *argv[])
-{
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- if(test1())
- {
- Fail("%s '%s'\n",ErrorMessage,convertC(BadResult));
-
- }
-
- PAL_Terminate();
- return PASS;
-
-}
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test9/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/wsprintfW/test9/testinfo.dat
deleted file mode 100644
index 3006aa87bc..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/wsprintfW/test9/testinfo.dat
+++ /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.
-
-Version = 1.0
-Section = Miscellaneous
-Function = wsprintfW
-Name = Positive test of wsprintfW
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Test %i formatter with wsprintfW.
-
-
diff --git a/src/pal/tests/palsuite/pal_specific/PAL_GetPALDirectoryW/test1/CMakeLists.txt b/src/pal/tests/palsuite/pal_specific/PAL_GetPALDirectoryW/test1/CMakeLists.txt
index bf1d3a91e7..515815f9d2 100644
--- a/src/pal/tests/palsuite/pal_specific/PAL_GetPALDirectoryW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/pal_specific/PAL_GetPALDirectoryW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- PAL_GetPALDirectoryW.c
+ PAL_GetPALDirectoryW.cpp
)
add_executable(paltest_pal_getpaldirectoryw_test1
diff --git a/src/pal/tests/palsuite/pal_specific/PAL_GetPALDirectoryW/test1/PAL_GetPALDirectoryW.c b/src/pal/tests/palsuite/pal_specific/PAL_GetPALDirectoryW/test1/PAL_GetPALDirectoryW.c
deleted file mode 100644
index 2c67aa4954..0000000000
--- a/src/pal/tests/palsuite/pal_specific/PAL_GetPALDirectoryW/test1/PAL_GetPALDirectoryW.c
+++ /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.
-
-/*=============================================================
-**
-** Source: pal_getpaldirectoryw.c
-**
-** Purpose: Positive test the PAL_GetPALDirectoryW API.
-** Call this API to retrieve a fully-qualified
-** directory name where the PAL DLL is loaded from.
-**
-**
-**============================================================*/
-#define UNICODE
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
- int err;
- BOOL bValue;
- DWORD dwFileAttribute;
- WCHAR *wpDirectoryName = NULL;
- char *pDirectoryName = NULL;
-
- /*Initialize the PAL environment*/
- err = PAL_Initialize(argc, argv);
- if(0 != err)
- {
- return FAIL;
- }
-
- /*allocate momory to store the directory name*/
- wpDirectoryName = malloc(MAX_PATH*sizeof(WCHAR));
- if(NULL == wpDirectoryName)
- {
- Fail("\nFailed to allocate memory for storing directory name!\n");
- }
-
- UINT size = MAX_PATH;
- /*retrieve the machine configuration directory*/
- bValue = PAL_GetPALDirectoryW(wpDirectoryName, &size);
- if(FALSE == bValue)
- {
- free(wpDirectoryName);
- Fail("Failed to call PAL_GetPALDirectoryW API, "
- "error code =%u\n", GetLastError());
- }
-
-
- /*convert wide char string to a standard one*/
- pDirectoryName = convertC(wpDirectoryName);
- if(0 == strlen(pDirectoryName))
- {
- free(wpDirectoryName);
- free(pDirectoryName);
- Fail("The retrieved directory name string is empty!\n");
- }
-
- /*free the memory*/
- free(pDirectoryName);
-
- /*retrieve the attribute of a file or directory*/
- dwFileAttribute = GetFileAttributesW(wpDirectoryName);
-
- /*free the memory*/
- free(wpDirectoryName);
-
- /*check if the attribute indicates a directory*/
- if(FILE_ATTRIBUTE_DIRECTORY !=
- (dwFileAttribute & FILE_ATTRIBUTE_DIRECTORY))
- {
- Fail("The retrieved directory name is not a valid directory!\n");
- }
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/pal_specific/PAL_GetPALDirectoryW/test1/PAL_GetPALDirectoryW.cpp b/src/pal/tests/palsuite/pal_specific/PAL_GetPALDirectoryW/test1/PAL_GetPALDirectoryW.cpp
new file mode 100644
index 0000000000..856bfe8659
--- /dev/null
+++ b/src/pal/tests/palsuite/pal_specific/PAL_GetPALDirectoryW/test1/PAL_GetPALDirectoryW.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.
+
+/*=============================================================
+**
+** Source: pal_getpaldirectoryw.c
+**
+** Purpose: Positive test the PAL_GetPALDirectoryW API.
+** Call this API to retrieve a fully-qualified
+** directory name where the PAL DLL is loaded from.
+**
+**
+**============================================================*/
+#define UNICODE
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+ int err;
+ BOOL bValue;
+ DWORD dwFileAttribute;
+ WCHAR *wpDirectoryName = NULL;
+ char *pDirectoryName = NULL;
+
+ /*Initialize the PAL environment*/
+ err = PAL_Initialize(argc, argv);
+ if(0 != err)
+ {
+ return FAIL;
+ }
+
+ /*allocate momory to store the directory name*/
+ wpDirectoryName = (WCHAR*)malloc(MAX_PATH*sizeof(WCHAR));
+ if(NULL == wpDirectoryName)
+ {
+ Fail("\nFailed to allocate memory for storing directory name!\n");
+ }
+
+ UINT size = MAX_PATH;
+ /*retrieve the machine configuration directory*/
+ bValue = PAL_GetPALDirectoryW(wpDirectoryName, &size);
+ if(FALSE == bValue)
+ {
+ free(wpDirectoryName);
+ Fail("Failed to call PAL_GetPALDirectoryW API, "
+ "error code =%u\n", GetLastError());
+ }
+
+
+ /*convert wide char string to a standard one*/
+ pDirectoryName = convertC(wpDirectoryName);
+ if(0 == strlen(pDirectoryName))
+ {
+ free(wpDirectoryName);
+ free(pDirectoryName);
+ Fail("The retrieved directory name string is empty!\n");
+ }
+
+ /*free the memory*/
+ free(pDirectoryName);
+
+ /*retrieve the attribute of a file or directory*/
+ dwFileAttribute = GetFileAttributesW(wpDirectoryName);
+
+ /*free the memory*/
+ free(wpDirectoryName);
+
+ /*check if the attribute indicates a directory*/
+ if(FILE_ATTRIBUTE_DIRECTORY !=
+ (dwFileAttribute & FILE_ATTRIBUTE_DIRECTORY))
+ {
+ Fail("The retrieved directory name is not a valid directory!\n");
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/pal_specific/PAL_GetUserTempDirectoryW/test1/CMakeLists.txt b/src/pal/tests/palsuite/pal_specific/PAL_GetUserTempDirectoryW/test1/CMakeLists.txt
index e8d3c40565..26eb1a860b 100644
--- a/src/pal/tests/palsuite/pal_specific/PAL_GetUserTempDirectoryW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/pal_specific/PAL_GetUserTempDirectoryW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- PAL_GetUserTempDirectoryW.c
+ PAL_GetUserTempDirectoryW.cpp
)
add_executable(paltest_pal_getusertempdirectoryw_test1
diff --git a/src/pal/tests/palsuite/pal_specific/PAL_GetUserTempDirectoryW/test1/PAL_GetUserTempDirectoryW.c b/src/pal/tests/palsuite/pal_specific/PAL_GetUserTempDirectoryW/test1/PAL_GetUserTempDirectoryW.cpp
index 65cc426c74..65cc426c74 100644
--- a/src/pal/tests/palsuite/pal_specific/PAL_GetUserTempDirectoryW/test1/PAL_GetUserTempDirectoryW.c
+++ b/src/pal/tests/palsuite/pal_specific/PAL_GetUserTempDirectoryW/test1/PAL_GetUserTempDirectoryW.cpp
diff --git a/src/pal/tests/palsuite/pal_specific/PAL_Initialize_Terminate/test1/CMakeLists.txt b/src/pal/tests/palsuite/pal_specific/PAL_Initialize_Terminate/test1/CMakeLists.txt
index 416439d650..281efcd8be 100644
--- a/src/pal/tests/palsuite/pal_specific/PAL_Initialize_Terminate/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/pal_specific/PAL_Initialize_Terminate/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- PAL_Initialize_Terminate.c
+ PAL_Initialize_Terminate.cpp
)
add_executable(paltest_pal_initialize_terminate_test1
diff --git a/src/pal/tests/palsuite/pal_specific/PAL_Initialize_Terminate/test1/PAL_Initialize_Terminate.c b/src/pal/tests/palsuite/pal_specific/PAL_Initialize_Terminate/test1/PAL_Initialize_Terminate.cpp
index 29bb2c3b4f..29bb2c3b4f 100644
--- a/src/pal/tests/palsuite/pal_specific/PAL_Initialize_Terminate/test1/PAL_Initialize_Terminate.c
+++ b/src/pal/tests/palsuite/pal_specific/PAL_Initialize_Terminate/test1/PAL_Initialize_Terminate.cpp
diff --git a/src/pal/tests/palsuite/pal_specific/PAL_Initialize_Terminate/test2/CMakeLists.txt b/src/pal/tests/palsuite/pal_specific/PAL_Initialize_Terminate/test2/CMakeLists.txt
index b7661fd240..46b42aa714 100644
--- a/src/pal/tests/palsuite/pal_specific/PAL_Initialize_Terminate/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/pal_specific/PAL_Initialize_Terminate/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- pal_initialize_twice.c
+ pal_initialize_twice.cpp
)
add_executable(paltest_pal_initialize_terminate_test2
diff --git a/src/pal/tests/palsuite/pal_specific/PAL_Initialize_Terminate/test2/pal_initialize_twice.c b/src/pal/tests/palsuite/pal_specific/PAL_Initialize_Terminate/test2/pal_initialize_twice.cpp
index fc460bc1ad..fc460bc1ad 100644
--- a/src/pal/tests/palsuite/pal_specific/PAL_Initialize_Terminate/test2/pal_initialize_twice.c
+++ b/src/pal/tests/palsuite/pal_specific/PAL_Initialize_Terminate/test2/pal_initialize_twice.cpp
diff --git a/src/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test1/CMakeLists.txt b/src/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test1/CMakeLists.txt
index 2379694b24..573ab3834a 100644
--- a/src/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- PAL_RegisterLibraryW_UnregisterLibraryW.c
+ PAL_RegisterLibraryW_UnregisterLibraryW.cpp
)
add_executable(paltest_pal_registerlibraryw_unregisterlibraryw_test1
diff --git a/src/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test1/PAL_RegisterLibraryW_UnregisterLibraryW.c b/src/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test1/PAL_RegisterLibraryW_UnregisterLibraryW.c
deleted file mode 100644
index ff0d33879c..0000000000
--- a/src/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test1/PAL_RegisterLibraryW_UnregisterLibraryW.c
+++ /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.
-
-/*=============================================================
-**
-** Source: pal_registerlibrary_unregisterlibrary
-**
-** Purpose: Positive test the PAL_RegisterLibrary API and
-** PAL_UnRegisterLibrary.
-** Call PAL_RegisterLibrary to map a module into the calling
-** process address space and call PAL_UnRegisterLibrary
-** to unmap this module.
-**
-**
-**============================================================*/
-#define UNICODE
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
- HMODULE ModuleHandle;
- char ModuleName[64];
- WCHAR *wpModuleName = NULL;
- int err;
-
- /*Initialize the PAL environment*/
- err = PAL_Initialize(argc, argv);
- if(0 != err)
- {
- return FAIL;
- }
-
- /*zero the buffer*/
- memset(ModuleName,0,64);
- sprintf(ModuleName, "%s", "rotor_pal");
-
- /*convert a normal string to a wide one*/
- wpModuleName = convert(ModuleName);
-
- /*load a module*/
- ModuleHandle = PAL_RegisterLibrary(wpModuleName);
-
- /*free the memory*/
- free(wpModuleName);
-
- if(!ModuleHandle)
- {
- Fail("Failed to call PAL_RegisterLibrary API to map a module "
- "into calling process, error code=%u!\n", GetLastError());
- }
-
- /*decrement the reference count of the loaded DLL*/
- err = PAL_UnregisterLibrary(ModuleHandle);
- if(0 == err)
- {
- Fail("\nFailed to call PAL_UnregisterLibrary API to "
- "decrement the count of the loaded DLL module, "
- "error code=%u!\n", GetLastError());
- }
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test1/PAL_RegisterLibraryW_UnregisterLibraryW.cpp b/src/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test1/PAL_RegisterLibraryW_UnregisterLibraryW.cpp
new file mode 100644
index 0000000000..8eb8776107
--- /dev/null
+++ b/src/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test1/PAL_RegisterLibraryW_UnregisterLibraryW.cpp
@@ -0,0 +1,64 @@
+// Licensed to the .NET Foundation under one or more 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: pal_registerlibrary_unregisterlibrary
+**
+** Purpose: Positive test the PAL_RegisterLibrary API and
+** PAL_UnRegisterLibrary.
+** Call PAL_RegisterLibrary to map a module into the calling
+** process address space and call PAL_UnRegisterLibrary
+** to unmap this module.
+**
+**
+**============================================================*/
+#define UNICODE
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+ HMODULE ModuleHandle;
+ char ModuleName[64];
+ WCHAR *wpModuleName = NULL;
+ int err;
+
+ /*Initialize the PAL environment*/
+ err = PAL_Initialize(argc, argv);
+ if(0 != err)
+ {
+ return FAIL;
+ }
+
+ /*zero the buffer*/
+ memset(ModuleName,0,64);
+ sprintf_s(ModuleName, _countof(ModuleName), "%s", "rotor_pal");
+
+ /*convert a normal string to a wide one*/
+ wpModuleName = convert(ModuleName);
+
+ /*load a module*/
+ ModuleHandle = PAL_RegisterLibrary(wpModuleName);
+
+ /*free the memory*/
+ free(wpModuleName);
+
+ if(!ModuleHandle)
+ {
+ Fail("Failed to call PAL_RegisterLibrary API to map a module "
+ "into calling process, error code=%u!\n", GetLastError());
+ }
+
+ /*decrement the reference count of the loaded DLL*/
+ err = PAL_UnregisterLibrary(ModuleHandle);
+ if(0 == err)
+ {
+ Fail("\nFailed to call PAL_UnregisterLibrary API to "
+ "decrement the count of the loaded DLL module, "
+ "error code=%u!\n", GetLastError());
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test2_neg/CMakeLists.txt b/src/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test2_neg/CMakeLists.txt
index bbcb35933e..ef5c0479b7 100644
--- a/src/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test2_neg/CMakeLists.txt
+++ b/src/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test2_neg/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- reg_unreg_libraryw_neg.c
+ reg_unreg_libraryw_neg.cpp
)
add_executable(paltest_reg_unreg_libraryw_neg
diff --git a/src/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test2_neg/reg_unreg_libraryw_neg.c b/src/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test2_neg/reg_unreg_libraryw_neg.c
deleted file mode 100644
index a15ff5745b..0000000000
--- a/src/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test2_neg/reg_unreg_libraryw_neg.c
+++ /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.
-
-/*=============================================================
-**
-** Source: pal_registerlibraryw_unregisterlibraryw_neg.c
-**
-** Purpose: Negative test the PAL_RegisterLibrary API.
-** Call PAL_RegisterLibrary to map a non-existant module
-** into the calling process address space.
-**
-**
-**============================================================*/
-#define UNICODE
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
- HMODULE ModuleHandle;
- char ModuleName[64];
- WCHAR *wpModuleName = NULL;
- int err;
-
- /*Initialize the PAL environment*/
- err = PAL_Initialize(argc, argv);
- if(0 != err)
- {
- return FAIL;
- }
-
- memset(ModuleName, 0, 64);
- sprintf(ModuleName, "%s", "not_exist_module_name");
-
- /*convert a normal string to a wide one*/
- wpModuleName = convert(ModuleName);
-
- /*load a not exist module*/
- ModuleHandle = PAL_RegisterLibrary(wpModuleName);
-
- /*free the memory*/
- free(wpModuleName);
-
- if(NULL != ModuleHandle)
- {
- Trace("ERROR: PAL_RegisterLibrary successfully mapped "
- "a module that does not exist into the calling process\n");
-
- /*decrement the reference count of the loaded DLL*/
- err = PAL_UnregisterLibrary(ModuleHandle);
- if(0 == err)
- {
- Trace("\nFailed to call PAL_UnregisterLibrary API to decrement the "
- "count of the loaded DLL module!\n");
- }
- Fail("");
-
- }
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test2_neg/reg_unreg_libraryw_neg.cpp b/src/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test2_neg/reg_unreg_libraryw_neg.cpp
new file mode 100644
index 0000000000..c6fa4ad074
--- /dev/null
+++ b/src/pal/tests/palsuite/pal_specific/PAL_RegisterLibraryW_UnregisterLibraryW/test2_neg/reg_unreg_libraryw_neg.cpp
@@ -0,0 +1,62 @@
+// Licensed to the .NET Foundation under one or more 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: pal_registerlibraryw_unregisterlibraryw_neg.c
+**
+** Purpose: Negative test the PAL_RegisterLibrary API.
+** Call PAL_RegisterLibrary to map a non-existant module
+** into the calling process address space.
+**
+**
+**============================================================*/
+#define UNICODE
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[])
+{
+ HMODULE ModuleHandle;
+ char ModuleName[64];
+ WCHAR *wpModuleName = NULL;
+ int err;
+
+ /*Initialize the PAL environment*/
+ err = PAL_Initialize(argc, argv);
+ if(0 != err)
+ {
+ return FAIL;
+ }
+
+ memset(ModuleName, 0, 64);
+ sprintf_s(ModuleName, _countof(ModuleName), "%s", "not_exist_module_name");
+
+ /*convert a normal string to a wide one*/
+ wpModuleName = convert(ModuleName);
+
+ /*load a not exist module*/
+ ModuleHandle = PAL_RegisterLibrary(wpModuleName);
+
+ /*free the memory*/
+ free(wpModuleName);
+
+ if(NULL != ModuleHandle)
+ {
+ Trace("ERROR: PAL_RegisterLibrary successfully mapped "
+ "a module that does not exist into the calling process\n");
+
+ /*decrement the reference count of the loaded DLL*/
+ err = PAL_UnregisterLibrary(ModuleHandle);
+ if(0 == err)
+ {
+ Trace("\nFailed to call PAL_UnregisterLibrary API to decrement the "
+ "count of the loaded DLL module!\n");
+ }
+ Fail("");
+
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/pal_specific/PAL_errno/test1/CMakeLists.txt b/src/pal/tests/palsuite/pal_specific/PAL_errno/test1/CMakeLists.txt
index 59922b194b..d20ddd9a43 100644
--- a/src/pal/tests/palsuite/pal_specific/PAL_errno/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/pal_specific/PAL_errno/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- PAL_errno.c
+ PAL_errno.cpp
)
add_executable(paltest_pal_errno_test1
diff --git a/src/pal/tests/palsuite/pal_specific/PAL_errno/test1/PAL_errno.c b/src/pal/tests/palsuite/pal_specific/PAL_errno/test1/PAL_errno.cpp
index 32e8487d07..32e8487d07 100644
--- a/src/pal/tests/palsuite/pal_specific/PAL_errno/test1/PAL_errno.c
+++ b/src/pal/tests/palsuite/pal_specific/PAL_errno/test1/PAL_errno.cpp
diff --git a/src/pal/tests/palsuite/pal_specific/PAL_get_stderr/test1/CMakeLists.txt b/src/pal/tests/palsuite/pal_specific/PAL_get_stderr/test1/CMakeLists.txt
index 3436a2dfdb..dbedac95f5 100644
--- a/src/pal/tests/palsuite/pal_specific/PAL_get_stderr/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/pal_specific/PAL_get_stderr/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- PAL_get_stderr.c
+ PAL_get_stderr.cpp
)
add_executable(paltest_pal_get_stderr_test1
diff --git a/src/pal/tests/palsuite/pal_specific/PAL_get_stderr/test1/PAL_get_stderr.c b/src/pal/tests/palsuite/pal_specific/PAL_get_stderr/test1/PAL_get_stderr.cpp
index da53460101..da53460101 100644
--- a/src/pal/tests/palsuite/pal_specific/PAL_get_stderr/test1/PAL_get_stderr.c
+++ b/src/pal/tests/palsuite/pal_specific/PAL_get_stderr/test1/PAL_get_stderr.cpp
diff --git a/src/pal/tests/palsuite/pal_specific/PAL_get_stdin/test1/CMakeLists.txt b/src/pal/tests/palsuite/pal_specific/PAL_get_stdin/test1/CMakeLists.txt
index 592895b18c..4d714a3735 100644
--- a/src/pal/tests/palsuite/pal_specific/PAL_get_stdin/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/pal_specific/PAL_get_stdin/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- PAL_get_stdin.c
+ PAL_get_stdin.cpp
)
add_executable(paltest_pal_get_stdin_test1
diff --git a/src/pal/tests/palsuite/pal_specific/PAL_get_stdin/test1/PAL_get_stdin.c b/src/pal/tests/palsuite/pal_specific/PAL_get_stdin/test1/PAL_get_stdin.cpp
index 5d1fd23f92..5d1fd23f92 100644
--- a/src/pal/tests/palsuite/pal_specific/PAL_get_stdin/test1/PAL_get_stdin.c
+++ b/src/pal/tests/palsuite/pal_specific/PAL_get_stdin/test1/PAL_get_stdin.cpp
diff --git a/src/pal/tests/palsuite/pal_specific/PAL_get_stdout/test1/CMakeLists.txt b/src/pal/tests/palsuite/pal_specific/PAL_get_stdout/test1/CMakeLists.txt
index 865dd52f16..4c2f51b50d 100644
--- a/src/pal/tests/palsuite/pal_specific/PAL_get_stdout/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/pal_specific/PAL_get_stdout/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- PAL_get_stdout.c
+ PAL_get_stdout.cpp
)
add_executable(paltest_pal_get_stdout_test1
diff --git a/src/pal/tests/palsuite/pal_specific/PAL_get_stdout/test1/PAL_get_stdout.c b/src/pal/tests/palsuite/pal_specific/PAL_get_stdout/test1/PAL_get_stdout.cpp
index ebfee47ae9..ebfee47ae9 100644
--- a/src/pal/tests/palsuite/pal_specific/PAL_get_stdout/test1/PAL_get_stdout.c
+++ b/src/pal/tests/palsuite/pal_specific/PAL_get_stdout/test1/PAL_get_stdout.cpp
diff --git a/src/pal/tests/palsuite/pal_specific/pal_entrypoint/test1/CMakeLists.txt b/src/pal/tests/palsuite/pal_specific/pal_entrypoint/test1/CMakeLists.txt
index cd18b76958..82ff9225de 100644
--- a/src/pal/tests/palsuite/pal_specific/pal_entrypoint/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/pal_specific/pal_entrypoint/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- pal_entrypoint.c
+ pal_entrypoint.cpp
)
add_executable(paltest_pal_entrypoint_test1
diff --git a/src/pal/tests/palsuite/pal_specific/pal_entrypoint/test1/pal_entrypoint.c b/src/pal/tests/palsuite/pal_specific/pal_entrypoint/test1/pal_entrypoint.cpp
index c1b66944aa..c1b66944aa 100644
--- a/src/pal/tests/palsuite/pal_specific/pal_entrypoint/test1/pal_entrypoint.c
+++ b/src/pal/tests/palsuite/pal_specific/pal_entrypoint/test1/pal_entrypoint.cpp
diff --git a/src/pal/tests/palsuite/pal_specific/pal_initializedebug/test1/CMakeLists.txt b/src/pal/tests/palsuite/pal_specific/pal_initializedebug/test1/CMakeLists.txt
index f6e243d0c4..56c9d02eaa 100644
--- a/src/pal/tests/palsuite/pal_specific/pal_initializedebug/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/pal_specific/pal_initializedebug/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- pal_initializedebug.c
+ pal_initializedebug.cpp
)
add_executable(paltest_pal_initializedebug_test1
diff --git a/src/pal/tests/palsuite/pal_specific/pal_initializedebug/test1/pal_initializedebug.c b/src/pal/tests/palsuite/pal_specific/pal_initializedebug/test1/pal_initializedebug.cpp
index d14c316013..d14c316013 100644
--- a/src/pal/tests/palsuite/pal_specific/pal_initializedebug/test1/pal_initializedebug.c
+++ b/src/pal/tests/palsuite/pal_specific/pal_initializedebug/test1/pal_initializedebug.cpp
diff --git a/src/pal/tests/palsuite/paltestlist.txt b/src/pal/tests/palsuite/paltestlist.txt
index d0a76e9573..2cedca2b97 100644
--- a/src/pal/tests/palsuite/paltestlist.txt
+++ b/src/pal/tests/palsuite/paltestlist.txt
@@ -1,20 +1,28 @@
c_runtime/abs/test1/paltest_abs_test1
c_runtime/acos/test1/paltest_acos_test1
+c_runtime/acosf/test1/paltest_acosf_test1
c_runtime/asin/test1/paltest_asin_test1
+c_runtime/asinf/test1/paltest_asinf_test1
c_runtime/atan/test1/paltest_atan_test1
c_runtime/atan2/test1/paltest_atan2_test1
+c_runtime/atan2f/test1/paltest_atan2f_test1
+c_runtime/atanf/test1/paltest_atanf_test1
c_runtime/atof/test1/paltest_atof_test1
c_runtime/atoi/test1/paltest_atoi_test1
c_runtime/atol/test1/paltest_atol_test1
c_runtime/bsearch/test1/paltest_bsearch_test1
c_runtime/bsearch/test2/paltest_bsearch_test2
c_runtime/ceil/test1/paltest_ceil_test1
+c_runtime/ceilf/test1/paltest_ceilf_test1
c_runtime/cos/test1/paltest_cos_test1
+c_runtime/cosf/test1/paltest_cosf_test1
c_runtime/cosh/test1/paltest_cosh_test1
+c_runtime/coshf/test1/paltest_coshf_test1
c_runtime/errno/test1/paltest_errno_test1
c_runtime/errno/test2/paltest_errno_test2
c_runtime/exit/test1/paltest_exit_test1
c_runtime/exp/test1/paltest_exp_test1
+c_runtime/expf/test1/paltest_expf_test1
c_runtime/fabs/test1/paltest_fabs_test1
c_runtime/fabsf/test1/paltest_fabsf_test1
c_runtime/fclose/test1/paltest_fclose_test1
@@ -24,6 +32,7 @@ c_runtime/fgets/test1/paltest_fgets_test1
c_runtime/fgets/test2/paltest_fgets_test2
c_runtime/fgets/test3/paltest_fgets_test3
c_runtime/floor/test1/paltest_floor_test1
+c_runtime/floorf/test1/paltest_floorf_test1
c_runtime/fmod/test1/paltest_fmod_test1
c_runtime/fmodf/test1/paltest_fmodf_test1
c_runtime/fopen/test1/paltest_fopen_test1
@@ -94,6 +103,8 @@ c_runtime/llabs/test1/paltest_llabs_test1
c_runtime/localtime/test1/paltest_localtime_test1
c_runtime/log/test1/paltest_log_test1
c_runtime/log10/test1/paltest_log10_test1
+c_runtime/log10f/test1/paltest_log10f_test1
+c_runtime/logf/test1/paltest_logf_test1
c_runtime/malloc/test1/paltest_malloc_test1
c_runtime/malloc/test2/paltest_malloc_test2
c_runtime/memchr/test1/paltest_memchr_test1
@@ -104,6 +115,7 @@ c_runtime/memset/test1/paltest_memset_test1
c_runtime/modf/test1/paltest_modf_test1
c_runtime/modff/test1/paltest_modff_test1
c_runtime/pow/test1/paltest_pow_test1
+c_runtime/powf/test1/paltest_powf_test1
c_runtime/printf/test1/paltest_printf_test1
c_runtime/printf/test10/paltest_printf_test10
c_runtime/printf/test11/paltest_printf_test11
@@ -128,44 +140,46 @@ c_runtime/qsort/test2/paltest_qsort_test2
c_runtime/rand_srand/test1/paltest_rand_srand_test1
c_runtime/realloc/test1/paltest_realloc_test1
c_runtime/sin/test1/paltest_sin_test1
+c_runtime/sinf/test1/paltest_sinf_test1
c_runtime/sinh/test1/paltest_sinh_test1
-c_runtime/sprintf/test1/paltest_sprintf_test1
-c_runtime/sprintf/test10/paltest_sprintf_test10
-c_runtime/sprintf/test11/paltest_sprintf_test11
-c_runtime/sprintf/test12/paltest_sprintf_test12
-c_runtime/sprintf/test13/paltest_sprintf_test13
-c_runtime/sprintf/test14/paltest_sprintf_test14
-c_runtime/sprintf/test15/paltest_sprintf_test15
-c_runtime/sprintf/test16/paltest_sprintf_test16
-c_runtime/sprintf/test17/paltest_sprintf_test17
-c_runtime/sprintf/test18/paltest_sprintf_test18
-c_runtime/sprintf/test19/paltest_sprintf_test19
-c_runtime/sprintf/test2/paltest_sprintf_test2
-c_runtime/sprintf/test3/paltest_sprintf_test3
-c_runtime/sprintf/test4/paltest_sprintf_test4
-c_runtime/sprintf/test5/paltest_sprintf_test5
-c_runtime/sprintf/test6/paltest_sprintf_test6
-c_runtime/sprintf/test7/paltest_sprintf_test7
-c_runtime/sprintf/test8/paltest_sprintf_test8
-c_runtime/sprintf/test9/paltest_sprintf_test9
+c_runtime/sinhf/test1/paltest_sinhf_test1
+c_runtime/sprintf_s/test1/paltest_sprintf_test1
+c_runtime/sprintf_s/test10/paltest_sprintf_test10
+c_runtime/sprintf_s/test11/paltest_sprintf_test11
+c_runtime/sprintf_s/test12/paltest_sprintf_test12
+c_runtime/sprintf_s/test13/paltest_sprintf_test13
+c_runtime/sprintf_s/test14/paltest_sprintf_test14
+c_runtime/sprintf_s/test15/paltest_sprintf_test15
+c_runtime/sprintf_s/test16/paltest_sprintf_test16
+c_runtime/sprintf_s/test17/paltest_sprintf_test17
+c_runtime/sprintf_s/test18/paltest_sprintf_test18
+c_runtime/sprintf_s/test19/paltest_sprintf_test19
+c_runtime/sprintf_s/test2/paltest_sprintf_test2
+c_runtime/sprintf_s/test3/paltest_sprintf_test3
+c_runtime/sprintf_s/test4/paltest_sprintf_test4
+c_runtime/sprintf_s/test6/paltest_sprintf_test6
+c_runtime/sprintf_s/test7/paltest_sprintf_test7
+c_runtime/sprintf_s/test8/paltest_sprintf_test8
+c_runtime/sprintf_s/test9/paltest_sprintf_test9
c_runtime/sqrt/test1/paltest_sqrt_test1
-c_runtime/sscanf/test1/paltest_sscanf_test1
-c_runtime/sscanf/test10/paltest_sscanf_test10
-c_runtime/sscanf/test11/paltest_sscanf_test11
-c_runtime/sscanf/test12/paltest_sscanf_test12
-c_runtime/sscanf/test13/paltest_sscanf_test13
-c_runtime/sscanf/test14/paltest_sscanf_test14
-c_runtime/sscanf/test15/paltest_sscanf_test15
-c_runtime/sscanf/test16/paltest_sscanf_test16
-c_runtime/sscanf/test17/paltest_sscanf_test17
-c_runtime/sscanf/test2/paltest_sscanf_test2
-c_runtime/sscanf/test3/paltest_sscanf_test3
-c_runtime/sscanf/test4/paltest_sscanf_test4
-c_runtime/sscanf/test5/paltest_sscanf_test5
-c_runtime/sscanf/test6/paltest_sscanf_test6
-c_runtime/sscanf/test7/paltest_sscanf_test7
-c_runtime/sscanf/test8/paltest_sscanf_test8
-c_runtime/sscanf/test9/paltest_sscanf_test9
+c_runtime/sqrtf/test1/paltest_sqrtf_test1
+c_runtime/sscanf_s/test1/paltest_sscanf_test1
+c_runtime/sscanf_s/test10/paltest_sscanf_test10
+c_runtime/sscanf_s/test11/paltest_sscanf_test11
+c_runtime/sscanf_s/test12/paltest_sscanf_test12
+c_runtime/sscanf_s/test13/paltest_sscanf_test13
+c_runtime/sscanf_s/test14/paltest_sscanf_test14
+c_runtime/sscanf_s/test15/paltest_sscanf_test15
+c_runtime/sscanf_s/test16/paltest_sscanf_test16
+c_runtime/sscanf_s/test17/paltest_sscanf_test17
+c_runtime/sscanf_s/test2/paltest_sscanf_test2
+c_runtime/sscanf_s/test3/paltest_sscanf_test3
+c_runtime/sscanf_s/test4/paltest_sscanf_test4
+c_runtime/sscanf_s/test5/paltest_sscanf_test5
+c_runtime/sscanf_s/test6/paltest_sscanf_test6
+c_runtime/sscanf_s/test7/paltest_sscanf_test7
+c_runtime/sscanf_s/test8/paltest_sscanf_test8
+c_runtime/sscanf_s/test9/paltest_sscanf_test9
c_runtime/strcat/test1/paltest_strcat_test1
c_runtime/strchr/test1/paltest_strchr_test1
c_runtime/strcmp/test1/paltest_strcmp_test1
@@ -218,7 +232,9 @@ c_runtime/swscanf/test7/paltest_swscanf_test7
c_runtime/swscanf/test8/paltest_swscanf_test8
c_runtime/swscanf/test9/paltest_swscanf_test9
c_runtime/tan/test1/paltest_tan_test1
+c_runtime/tanf/test1/paltest_tanf_test1
c_runtime/tanh/test1/paltest_tanh_test1
+c_runtime/tanhf/test1/paltest_tanhf_test1
c_runtime/time/test1/paltest_time_test1
c_runtime/tolower/test1/paltest_tolower_test1
c_runtime/toupper/test1/paltest_toupper_test1
@@ -328,13 +344,13 @@ c_runtime/wprintf/test1/paltest_wprintf_test1
c_runtime/_alloca/test1/paltest_alloca_test1
c_runtime/_fdopen/test1/paltest_fdopen_test1
c_runtime/_finite/test1/paltest_finite_test1
+c_runtime/_finitef/test1/paltest_finitef_test1
c_runtime/_fullpath/test1/paltest_fullpath_test1
c_runtime/_isnan/test1/paltest_isnan_test1
+c_runtime/_isnanf/test1/paltest_isnanf_test1
c_runtime/_itow/test1/paltest_itow_test1
-c_runtime/_makepath/test1/paltest_makepath_test1
c_runtime/_mbsdec/test1/paltest_mbsdec_test1
c_runtime/_mbsinc/test1/paltest_mbsinc_test1
-c_runtime/_mbslen/test1/paltest_mbslen_test1
c_runtime/_mbsninc/test1/paltest_mbsninc_test1
c_runtime/_open_osfhandle/test1/paltest_open_osfhandle_test1
c_runtime/_open_osfhandle/test2/paltest_open_osfhandle_test2
@@ -345,47 +361,43 @@ c_runtime/_putenv/test4/paltest_putenv_test4
c_runtime/_putw/test1/paltest_putw_test1
c_runtime/_rotl/test1/paltest_rotl_test1
c_runtime/_rotr/test1/paltest_rotr_test1
-c_runtime/_snprintf/test1/paltest_snprintf_test1
-c_runtime/_snprintf/test10/paltest_snprintf_test10
-c_runtime/_snprintf/test11/paltest_snprintf_test11
-c_runtime/_snprintf/test12/paltest_snprintf_test12
-c_runtime/_snprintf/test13/paltest_snprintf_test13
-c_runtime/_snprintf/test14/paltest_snprintf_test14
-c_runtime/_snprintf/test15/paltest_snprintf_test15
-c_runtime/_snprintf/test16/paltest_snprintf_test16
-c_runtime/_snprintf/test17/paltest_snprintf_test17
-c_runtime/_snprintf/test18/paltest_snprintf_test18
-c_runtime/_snprintf/test19/paltest_snprintf_test19
-c_runtime/_snprintf/test2/paltest_snprintf_test2
-c_runtime/_snprintf/test3/paltest_snprintf_test3
-c_runtime/_snprintf/test4/paltest_snprintf_test4
-c_runtime/_snprintf/test5/paltest_snprintf_test5
-c_runtime/_snprintf/test6/paltest_snprintf_test6
-c_runtime/_snprintf/test7/paltest_snprintf_test7
-c_runtime/_snprintf/test8/paltest_snprintf_test8
-c_runtime/_snprintf/test9/paltest_snprintf_test9
-c_runtime/_snwprintf/test1/paltest_snwprintf_test1
-c_runtime/_snwprintf/test10/paltest_snwprintf_test10
-c_runtime/_snwprintf/test11/paltest_snwprintf_test11
-c_runtime/_snwprintf/test12/paltest_snwprintf_test12
-c_runtime/_snwprintf/test13/paltest_snwprintf_test13
-c_runtime/_snwprintf/test14/paltest_snwprintf_test14
-c_runtime/_snwprintf/test15/paltest_snwprintf_test15
-c_runtime/_snwprintf/test16/paltest_snwprintf_test16
-c_runtime/_snwprintf/test17/paltest_snwprintf_test17
-c_runtime/_snwprintf/test18/paltest_snwprintf_test18
-c_runtime/_snwprintf/test19/paltest_snwprintf_test19
-c_runtime/_snwprintf/test3/paltest_snwprintf_test3
-c_runtime/_snwprintf/test4/paltest_snwprintf_test4
-c_runtime/_snwprintf/test5/paltest_snwprintf_test5
-c_runtime/_snwprintf/test6/paltest_snwprintf_test6
-c_runtime/_snwprintf/test8/paltest_snwprintf_test8
-c_runtime/_snwprintf/test9/paltest_snwprintf_test9
-c_runtime/_splitpath/test1/paltest_splitpath_test1
+c_runtime/_snprintf_s/test1/paltest_snprintf_test1
+c_runtime/_snprintf_s/test10/paltest_snprintf_test10
+c_runtime/_snprintf_s/test11/paltest_snprintf_test11
+c_runtime/_snprintf_s/test12/paltest_snprintf_test12
+c_runtime/_snprintf_s/test13/paltest_snprintf_test13
+c_runtime/_snprintf_s/test14/paltest_snprintf_test14
+c_runtime/_snprintf_s/test15/paltest_snprintf_test15
+c_runtime/_snprintf_s/test16/paltest_snprintf_test16
+c_runtime/_snprintf_s/test17/paltest_snprintf_test17
+c_runtime/_snprintf_s/test18/paltest_snprintf_test18
+c_runtime/_snprintf_s/test19/paltest_snprintf_test19
+c_runtime/_snprintf_s/test2/paltest_snprintf_test2
+c_runtime/_snprintf_s/test3/paltest_snprintf_test3
+c_runtime/_snprintf_s/test4/paltest_snprintf_test4
+c_runtime/_snprintf_s/test6/paltest_snprintf_test6
+c_runtime/_snprintf_s/test7/paltest_snprintf_test7
+c_runtime/_snprintf_s/test8/paltest_snprintf_test8
+c_runtime/_snprintf_s/test9/paltest_snprintf_test9
+c_runtime/_snwprintf_s/test1/paltest_snwprintf_test1
+c_runtime/_snwprintf_s/test10/paltest_snwprintf_test10
+c_runtime/_snwprintf_s/test11/paltest_snwprintf_test11
+c_runtime/_snwprintf_s/test12/paltest_snwprintf_test12
+c_runtime/_snwprintf_s/test13/paltest_snwprintf_test13
+c_runtime/_snwprintf_s/test14/paltest_snwprintf_test14
+c_runtime/_snwprintf_s/test15/paltest_snwprintf_test15
+c_runtime/_snwprintf_s/test16/paltest_snwprintf_test16
+c_runtime/_snwprintf_s/test17/paltest_snwprintf_test17
+c_runtime/_snwprintf_s/test18/paltest_snwprintf_test18
+c_runtime/_snwprintf_s/test19/paltest_snwprintf_test19
+c_runtime/_snwprintf_s/test3/paltest_snwprintf_test3
+c_runtime/_snwprintf_s/test4/paltest_snwprintf_test4
+c_runtime/_snwprintf_s/test6/paltest_snwprintf_test6
+c_runtime/_snwprintf_s/test8/paltest_snwprintf_test8
+c_runtime/_snwprintf_s/test9/paltest_snwprintf_test9
c_runtime/_stricmp/test1/paltest_stricmp_test1
c_runtime/_strlwr/test1/paltest_strlwr_test1
c_runtime/_strnicmp/test1/paltest_strnicmp_test1
-c_runtime/_swab/test1/paltest_swab_test1
c_runtime/_vsnprintf/test1/paltest_vsnprintf_test1
c_runtime/_vsnprintf/test10/paltest_vsnprintf_test10
c_runtime/_vsnprintf/test11/paltest_vsnprintf_test11
@@ -405,23 +417,22 @@ c_runtime/_vsnprintf/test6/paltest_vsnprintf_test6
c_runtime/_vsnprintf/test7/paltest_vsnprintf_test7
c_runtime/_vsnprintf/test8/paltest_vsnprintf_test8
c_runtime/_vsnprintf/test9/paltest_vsnprintf_test9
-c_runtime/_vsnwprintf/test1/paltest_vsnwprintf_test1
-c_runtime/_vsnwprintf/test10/paltest_vsnwprintf_test10
-c_runtime/_vsnwprintf/test11/paltest_vsnwprintf_test11
-c_runtime/_vsnwprintf/test12/paltest_vsnwprintf_test12
-c_runtime/_vsnwprintf/test13/paltest_vsnwprintf_test13
-c_runtime/_vsnwprintf/test14/paltest_vsnwprintf_test14
-c_runtime/_vsnwprintf/test15/paltest_vsnwprintf_test15
-c_runtime/_vsnwprintf/test16/paltest_vsnwprintf_test16
-c_runtime/_vsnwprintf/test17/paltest_vsnwprintf_test17
-c_runtime/_vsnwprintf/test18/paltest_vsnwprintf_test18
-c_runtime/_vsnwprintf/test19/paltest_vsnwprintf_test19
-c_runtime/_vsnwprintf/test3/paltest_vsnwprintf_test3
-c_runtime/_vsnwprintf/test4/paltest_vsnwprintf_test4
-c_runtime/_vsnwprintf/test5/paltest_vsnwprintf_test5
-c_runtime/_vsnwprintf/test6/paltest_vsnwprintf_test6
-c_runtime/_vsnwprintf/test8/paltest_vsnwprintf_test8
-c_runtime/_vsnwprintf/test9/paltest_vsnwprintf_test9
+c_runtime/_vsnwprintf_s/test1/paltest_vsnwprintf_test1
+c_runtime/_vsnwprintf_s/test10/paltest_vsnwprintf_test10
+c_runtime/_vsnwprintf_s/test11/paltest_vsnwprintf_test11
+c_runtime/_vsnwprintf_s/test12/paltest_vsnwprintf_test12
+c_runtime/_vsnwprintf_s/test13/paltest_vsnwprintf_test13
+c_runtime/_vsnwprintf_s/test14/paltest_vsnwprintf_test14
+c_runtime/_vsnwprintf_s/test15/paltest_vsnwprintf_test15
+c_runtime/_vsnwprintf_s/test16/paltest_vsnwprintf_test16
+c_runtime/_vsnwprintf_s/test17/paltest_vsnwprintf_test17
+c_runtime/_vsnwprintf_s/test18/paltest_vsnwprintf_test18
+c_runtime/_vsnwprintf_s/test19/paltest_vsnwprintf_test19
+c_runtime/_vsnwprintf_s/test3/paltest_vsnwprintf_test3
+c_runtime/_vsnwprintf_s/test4/paltest_vsnwprintf_test4
+c_runtime/_vsnwprintf_s/test6/paltest_vsnwprintf_test6
+c_runtime/_vsnwprintf_s/test8/paltest_vsnwprintf_test8
+c_runtime/_vsnwprintf_s/test9/paltest_vsnwprintf_test9
c_runtime/_wcsicmp/test1/paltest_wcsicmp_test1
c_runtime/_wcslwr/test1/paltest_wcslwr_test1
c_runtime/_wcsnicmp/test1/paltest_wcsnicmp_test1
@@ -432,7 +443,6 @@ c_runtime/_wfopen/test4/paltest_wfopen_test4
c_runtime/_wfopen/test5/paltest_wfopen_test5
c_runtime/_wfopen/test6/paltest_wfopen_test6
c_runtime/_wfopen/test7/paltest_wfopen_test7
-c_runtime/_wsplitpath/test1/paltest_wsplitpath_test1
c_runtime/_wtoi/test1/paltest_wtoi_test1
c_runtime/__iscsym/test1/paltest_iscsym_test1
debug_api/OutputDebugStringW/test1/paltest_outputdebugstringw_test1
@@ -473,6 +483,8 @@ filemapping_memmgt/MapViewOfFile/test3/paltest_mapviewoffile_test3
filemapping_memmgt/MapViewOfFile/test4/paltest_mapviewoffile_test4
filemapping_memmgt/MapViewOfFile/test5/paltest_mapviewoffile_test5
filemapping_memmgt/MapViewOfFile/test6/paltest_mapviewoffile_test6
+filemapping_memmgt/ProbeMemory/test1/paltest_probememory_test1
+filemapping_memmgt/ProbeMemory/ProbeMemory_neg1/paltest_probememory_probememory_neg1
filemapping_memmgt/RtlMoveMemory/test1/paltest_rtlmovememory_test1
filemapping_memmgt/RtlMoveMemory/test3/paltest_rtlmovememory_test3
filemapping_memmgt/RtlMoveMemory/test4/paltest_rtlmovememory_test4
@@ -678,12 +690,6 @@ miscellaneous/InterlockedIncrement/test1/paltest_interlockedincrement_test1
miscellaneous/InterlockedIncrement/test2/paltest_interlockedincrement_test2
miscellaneous/InterlockedIncrement64/test1/paltest_interlockedincrement64_test1
miscellaneous/InterlockedIncrement64/test2/paltest_interlockedincrement64_test2
-miscellaneous/lstrcatW/test1/paltest_lstrcatw_test1
-miscellaneous/lstrcatW/test2/paltest_lstrcatw_test2
-miscellaneous/lstrcatW/test3/paltest_lstrcatw_test3
-miscellaneous/lstrcatW/test4/paltest_lstrcatw_test4
-miscellaneous/lstrcpynW/test1/paltest_lstrcpynw_test1
-miscellaneous/lstrcpyW/test1/paltest_lstrcpyw_test1
miscellaneous/lstrlenA/test1/paltest_lstrlena_test1
miscellaneous/lstrlenW/test1/paltest_lstrlenw_test1
miscellaneous/queryperformancecounter/test1/paltest_queryperformancecounter_test1
@@ -697,27 +703,7 @@ miscellaneous/SetEnvironmentVariableW/test2/paltest_setenvironmentvariablew_test
miscellaneous/SetEnvironmentVariableW/test3/paltest_setenvironmentvariablew_test3
miscellaneous/SetEnvironmentVariableW/test4/paltest_setenvironmentvariablew_test4
miscellaneous/SetLastError/test1/paltest_setlasterror_test1
-miscellaneous/wsprintfA/test1/paltest_wsprintfa_test1
-miscellaneous/wsprintfA/test11/paltest_wsprintfa_test11
-miscellaneous/wsprintfA/test12/paltest_wsprintfa_test12
-miscellaneous/wsprintfA/test13/paltest_wsprintfa_test13
-miscellaneous/wsprintfA/test2/paltest_wsprintfa_test2
-miscellaneous/wsprintfA/test3/paltest_wsprintfa_test3
-miscellaneous/wsprintfA/test6/paltest_wsprintfa_test6
-miscellaneous/wsprintfA/test7/paltest_wsprintfa_test7
-miscellaneous/wsprintfA/test8/paltest_wsprintfa_test8
-miscellaneous/wsprintfA/test9/paltest_wsprintfa_test9
-miscellaneous/wsprintfW/test1/paltest_wsprintfw_test1
-miscellaneous/wsprintfW/test11/paltest_wsprintfw_test11
-miscellaneous/wsprintfW/test12/paltest_wsprintfw_test12
-miscellaneous/wsprintfW/test13/paltest_wsprintfw_test13
-miscellaneous/wsprintfW/test3/paltest_wsprintfw_test3
-miscellaneous/wsprintfW/test6/paltest_wsprintfw_test6
-miscellaneous/wsprintfW/test8/paltest_wsprintfw_test8
-miscellaneous/wsprintfW/test9/paltest_wsprintfw_test9
miscellaneous/_i64tow/test1/paltest_i64tow_test1
-miscellaneous/_ui64tow/test1/paltest_ui64tow_test1
-miscellaneous/_ui64tow/test2/paltest_ui64tow_test2
pal_specific/pal_entrypoint/test1/paltest_pal_entrypoint_test1
pal_specific/PAL_errno/test1/paltest_pal_errno_test1
pal_specific/pal_initializedebug/test1/paltest_pal_initializedebug_test1
diff --git a/src/pal/tests/palsuite/paltestlist_to_be_reviewed.txt b/src/pal/tests/palsuite/paltestlist_to_be_reviewed.txt
index ac0a2ee4eb..0e12ccbf55 100644
--- a/src/pal/tests/palsuite/paltestlist_to_be_reviewed.txt
+++ b/src/pal/tests/palsuite/paltestlist_to_be_reviewed.txt
@@ -26,11 +26,10 @@ c_runtime/_ecvt/test1/paltest_ecvt_test1
c_runtime/_gcvt/test1/paltest_gcvt_test1
c_runtime/_gcvt/test2/paltest_gcvt_test2
c_runtime/_getw/test1/paltest_getw_test1
-c_runtime/_snwprintf/test2/paltest_snwprintf_test2
-c_runtime/_snwprintf/test7/paltest_snwprintf_test7
-c_runtime/_vsnwprintf/test2/paltest_vsnwprintf_test2
-c_runtime/_vsnwprintf/test7/paltest_vsnwprintf_test7
-c_runtime/_wmakepath/test1/paltest_wmakepath_test1
+c_runtime/_snwprintf_s/test2/paltest_snwprintf_test2
+c_runtime/_snwprintf_s/test7/paltest_snwprintf_test7
+c_runtime/_vsnwprintf_s/test2/paltest_vsnwprintf_test2
+c_runtime/_vsnwprintf_s/test7/paltest_vsnwprintf_test7
debug_api/DebugBreak/test1/paltest_debugbreak_test1
debug_api/OutputDebugStringA/test1/paltest_outputdebugstringa_test1
debug_api/WriteProcessMemory/test1/paltest_writeprocessmemory_test1
diff --git a/src/pal/tests/palsuite/palverify.dat b/src/pal/tests/palsuite/palverify.dat
index 36b48d66e8..d6e113b670 100644
--- a/src/pal/tests/palsuite/palverify.dat
+++ b/src/pal/tests/palsuite/palverify.dat
@@ -7,16 +7,16 @@ c_runtime/_alloca/test1,1
c_runtime/_ecvt/test1,1
c_runtime/_fdopen/test1,1
c_runtime/_finite/test1,1
+c_runtime/_finitef/test1,1
c_runtime/_fullpath/test1,1
c_runtime/_gcvt/test1,1
c_runtime/_gcvt/test2,1
c_runtime/_getw/test1,1
c_runtime/_isnan/test1,1
+c_runtime/_isnanf/test1,1
c_runtime/_itow/test1,1
-c_runtime/_makepath/test1,1
c_runtime/_mbsdec/test1,1
c_runtime/_mbsinc/test1,1
-c_runtime/_mbslen/test1,1
c_runtime/_mbsninc/test1,1
c_runtime/_open_osfhandle/test1,1
c_runtime/_open_osfhandle/test2,1
@@ -27,49 +27,45 @@ c_runtime/_putenv/test4,1
c_runtime/_putw/test1,1
c_runtime/_rotl/test1,1
c_runtime/_rotr/test1,1
-c_runtime/_snprintf/test1,1
-c_runtime/_snprintf/test2,1
-c_runtime/_snprintf/test3,1
-c_runtime/_snprintf/test4,1
-c_runtime/_snprintf/test5,1
-c_runtime/_snprintf/test6,1
-c_runtime/_snprintf/test7,1
-c_runtime/_snprintf/test8,1
-c_runtime/_snprintf/test9,1
-c_runtime/_snprintf/test10,1
-c_runtime/_snprintf/test11,1
-c_runtime/_snprintf/test12,1
-c_runtime/_snprintf/test13,1
-c_runtime/_snprintf/test14,1
-c_runtime/_snprintf/test15,1
-c_runtime/_snprintf/test16,1
-c_runtime/_snprintf/test17,1
-c_runtime/_snprintf/test18,1
-c_runtime/_snprintf/test19,1
-c_runtime/_snwprintf/test1,1
-c_runtime/_snwprintf/test2,1
-c_runtime/_snwprintf/test3,1
-c_runtime/_snwprintf/test4,1
-c_runtime/_snwprintf/test5,1
-c_runtime/_snwprintf/test6,1
-c_runtime/_snwprintf/test7,1
-c_runtime/_snwprintf/test8,1
-c_runtime/_snwprintf/test9,1
-c_runtime/_snwprintf/test10,1
-c_runtime/_snwprintf/test11,1
-c_runtime/_snwprintf/test12,1
-c_runtime/_snwprintf/test13,1
-c_runtime/_snwprintf/test14,1
-c_runtime/_snwprintf/test15,1
-c_runtime/_snwprintf/test16,1
-c_runtime/_snwprintf/test17,1
-c_runtime/_snwprintf/test18,1
-c_runtime/_snwprintf/test19,1
-c_runtime/_splitpath/test1,1
+c_runtime/_snprintf_s/test1,1
+c_runtime/_snprintf_s/test2,1
+c_runtime/_snprintf_s/test3,1
+c_runtime/_snprintf_s/test4,1
+c_runtime/_snprintf_s/test6,1
+c_runtime/_snprintf_s/test7,1
+c_runtime/_snprintf_s/test8,1
+c_runtime/_snprintf_s/test9,1
+c_runtime/_snprintf_s/test10,1
+c_runtime/_snprintf_s/test11,1
+c_runtime/_snprintf_s/test12,1
+c_runtime/_snprintf_s/test13,1
+c_runtime/_snprintf_s/test14,1
+c_runtime/_snprintf_s/test15,1
+c_runtime/_snprintf_s/test16,1
+c_runtime/_snprintf_s/test17,1
+c_runtime/_snprintf_s/test18,1
+c_runtime/_snprintf_s/test19,1
+c_runtime/_snwprintf_s/test1,1
+c_runtime/_snwprintf_s/test2,1
+c_runtime/_snwprintf_s/test3,1
+c_runtime/_snwprintf_s/test4,1
+c_runtime/_snwprintf_s/test6,1
+c_runtime/_snwprintf_s/test7,1
+c_runtime/_snwprintf_s/test8,1
+c_runtime/_snwprintf_s/test9,1
+c_runtime/_snwprintf_s/test10,1
+c_runtime/_snwprintf_s/test11,1
+c_runtime/_snwprintf_s/test12,1
+c_runtime/_snwprintf_s/test13,1
+c_runtime/_snwprintf_s/test14,1
+c_runtime/_snwprintf_s/test15,1
+c_runtime/_snwprintf_s/test16,1
+c_runtime/_snwprintf_s/test17,1
+c_runtime/_snwprintf_s/test18,1
+c_runtime/_snwprintf_s/test19,1
c_runtime/_stricmp/test1,1
c_runtime/_strlwr/test1,1
c_runtime/_strnicmp/test1,1
-c_runtime/_swab/test1,1
c_runtime/_vsnprintf/test1,1
c_runtime/_vsnprintf/test2,1
c_runtime/_vsnprintf/test3,1
@@ -89,25 +85,25 @@ c_runtime/_vsnprintf/test16,1
c_runtime/_vsnprintf/test17,1
c_runtime/_vsnprintf/test18,1
c_runtime/_vsnprintf/test19,1
-c_runtime/_vsnwprintf/test1,1
-c_runtime/_vsnwprintf/test2,1
-c_runtime/_vsnwprintf/test3,1
-c_runtime/_vsnwprintf/test4,1
-c_runtime/_vsnwprintf/test5,1
-c_runtime/_vsnwprintf/test6,1
-c_runtime/_vsnwprintf/test7,1
-c_runtime/_vsnwprintf/test8,1
-c_runtime/_vsnwprintf/test9,1
-c_runtime/_vsnwprintf/test10,1
-c_runtime/_vsnwprintf/test11,1
-c_runtime/_vsnwprintf/test12,1
-c_runtime/_vsnwprintf/test13,1
-c_runtime/_vsnwprintf/test14,1
-c_runtime/_vsnwprintf/test15,1
-c_runtime/_vsnwprintf/test16,1
-c_runtime/_vsnwprintf/test17,1
-c_runtime/_vsnwprintf/test18,1
-c_runtime/_vsnwprintf/test19,1
+c_runtime/_vsnwprintf_s/test1,1
+c_runtime/_vsnwprintf_s/test2,1
+c_runtime/_vsnwprintf_s/test3,1
+c_runtime/_vsnwprintf_s/test4,1
+c_runtime/_vsnwprintf_s/test5,1
+c_runtime/_vsnwprintf_s/test6,1
+c_runtime/_vsnwprintf_s/test7,1
+c_runtime/_vsnwprintf_s/test8,1
+c_runtime/_vsnwprintf_s/test9,1
+c_runtime/_vsnwprintf_s/test10,1
+c_runtime/_vsnwprintf_s/test11,1
+c_runtime/_vsnwprintf_s/test12,1
+c_runtime/_vsnwprintf_s/test13,1
+c_runtime/_vsnwprintf_s/test14,1
+c_runtime/_vsnwprintf_s/test15,1
+c_runtime/_vsnwprintf_s/test16,1
+c_runtime/_vsnwprintf_s/test17,1
+c_runtime/_vsnwprintf_s/test18,1
+c_runtime/_vsnwprintf_s/test19,1
c_runtime/_wcsicmp/test1,1
c_runtime/_wcslwr/test1,1
c_runtime/_wcsnicmp/test1,1
@@ -118,27 +114,33 @@ c_runtime/_wfopen/test4,1
c_runtime/_wfopen/test5,1
c_runtime/_wfopen/test6,1
c_runtime/_wfopen/test7,1
-c_runtime/_wmakepath/test1,1
-c_runtime/_wsplitpath/test1,1
c_runtime/_wtoi/test1,1
c_runtime/abs/test1,1
c_runtime/acos/test1,1
+c_runtime/acosf/test1,1
c_runtime/asin/test1,1
+c_runtime/asinf/test1,1
c_runtime/atan/test1,1
c_runtime/atan2/test1,1
+c_runtime/atan2f/test1,1
+c_runtime/atanf/test1,1
c_runtime/atof/test1,1
c_runtime/atoi/test1,1
c_runtime/atol/test1,1
c_runtime/bsearch/test1,1
c_runtime/bsearch/test2,1
c_runtime/ceil/test1,1
+c_runtime/ceilf/test1,1
c_runtime/cos/test1,1
+c_runtime/cosf/test1,1
c_runtime/cosh/test1,1
+c_runtime/coshf/test1,1
c_runtime/ctime/test1,1
c_runtime/errno/test1,1
c_runtime/errno/test2,1
c_runtime/exit/test1,1
c_runtime/exp/test1,1
+c_runtime/expf/test1,1
c_runtime/fabs/test1,1
c_runtime/fabsf/test1,1
c_runtime/fclose/test1,1
@@ -151,6 +153,7 @@ c_runtime/fgets/test1,1
c_runtime/fgets/test2,1
c_runtime/fgets/test3,1
c_runtime/floor/test1,1
+c_runtime/floorf/test1,1
c_runtime/fmod/test1,1
c_runtime/fmodf/test1,1
c_runtime/fopen/test1,1
@@ -230,6 +233,8 @@ c_runtime/llabs/test1,1
c_runtime/localtime/test1,1
c_runtime/log/test1,1
c_runtime/log10/test1,1
+c_runtime/log10f/test1,1
+c_runtime/logf/test1,1
c_runtime/malloc/test1,1
c_runtime/memchr/test1,1
c_runtime/memcmp/test1,1
@@ -238,6 +243,7 @@ c_runtime/memmove/test1,1
c_runtime/memset/test1,1
c_runtime/modf/test1,1
c_runtime/pow/test1,1
+c_runtime/powf/test1,1
c_runtime/printf/test1,1
c_runtime/printf/test2,1
c_runtime/printf/test3,1
@@ -262,44 +268,46 @@ c_runtime/qsort/test2,1
c_runtime/rand_srand/test1,1
c_runtime/realloc/test1,1
c_runtime/sin/test1,1
+c_runtime/sinf/test1,1
c_runtime/sinh/test1,1
-c_runtime/sprintf/test1,1
-c_runtime/sprintf/test2,1
-c_runtime/sprintf/test3,1
-c_runtime/sprintf/test4,1
-c_runtime/sprintf/test5,1
-c_runtime/sprintf/test6,1
-c_runtime/sprintf/test7,1
-c_runtime/sprintf/test8,1
-c_runtime/sprintf/test9,1
-c_runtime/sprintf/test10,1
-c_runtime/sprintf/test11,1
-c_runtime/sprintf/test12,1
-c_runtime/sprintf/test13,1
-c_runtime/sprintf/test14,1
-c_runtime/sprintf/test15,1
-c_runtime/sprintf/test16,1
-c_runtime/sprintf/test17,1
-c_runtime/sprintf/test18,1
-c_runtime/sprintf/test19,1
+c_runtime/sinhf/test1,1
+c_runtime/sprintf_s/test1,1
+c_runtime/sprintf_s/test2,1
+c_runtime/sprintf_s/test3,1
+c_runtime/sprintf_s/test4,1
+c_runtime/sprintf_s/test6,1
+c_runtime/sprintf_s/test7,1
+c_runtime/sprintf_s/test8,1
+c_runtime/sprintf_s/test9,1
+c_runtime/sprintf_s/test10,1
+c_runtime/sprintf_s/test11,1
+c_runtime/sprintf_s/test12,1
+c_runtime/sprintf_s/test13,1
+c_runtime/sprintf_s/test14,1
+c_runtime/sprintf_s/test15,1
+c_runtime/sprintf_s/test16,1
+c_runtime/sprintf_s/test17,1
+c_runtime/sprintf_s/test18,1
+c_runtime/sprintf_s/test19,1
c_runtime/sqrt/test1,1
-c_runtime/sscanf/test1,1
-c_runtime/sscanf/test2,1
-c_runtime/sscanf/test3,1
-c_runtime/sscanf/test4,1
-c_runtime/sscanf/test5,1
-c_runtime/sscanf/test6,1
-c_runtime/sscanf/test7,1
-c_runtime/sscanf/test8,1
-c_runtime/sscanf/test9,1
-c_runtime/sscanf/test10,1
-c_runtime/sscanf/test11,1
-c_runtime/sscanf/test12,1
-c_runtime/sscanf/test13,1
-c_runtime/sscanf/test14,1
-c_runtime/sscanf/test15,1
-c_runtime/sscanf/test16,1
-c_runtime/sscanf/test17,1
+c_runtime/sqrtf/test1,1
+c_runtime/sscanf_s/test1,1
+c_runtime/sscanf_s/test2,1
+c_runtime/sscanf_s/test3,1
+c_runtime/sscanf_s/test4,1
+c_runtime/sscanf_s/test5,1
+c_runtime/sscanf_s/test6,1
+c_runtime/sscanf_s/test7,1
+c_runtime/sscanf_s/test8,1
+c_runtime/sscanf_s/test9,1
+c_runtime/sscanf_s/test10,1
+c_runtime/sscanf_s/test11,1
+c_runtime/sscanf_s/test12,1
+c_runtime/sscanf_s/test13,1
+c_runtime/sscanf_s/test14,1
+c_runtime/sscanf_s/test15,1
+c_runtime/sscanf_s/test16,1
+c_runtime/sscanf_s/test17,1
c_runtime/strcat/test1,1
c_runtime/strchr/test1,1
c_runtime/strcmp/test1,1
@@ -354,7 +362,9 @@ c_runtime/swscanf/test15,1
c_runtime/swscanf/test16,1
c_runtime/swscanf/test17,1
c_runtime/tan/test1,1
+c_runtime/tanf/test1,1
c_runtime/tanh/test1,1
+c_runtime/tanhf/test1,1
c_runtime/time/test1,1
c_runtime/tolower/test1,1
c_runtime/toupper/test1,1
@@ -715,8 +725,6 @@ locale_info/widechartomultibyte/test1,1
locale_info/widechartomultibyte/test2,1
locale_info/widechartomultibyte/test3,1
miscellaneous/_i64tow/test1,1
-miscellaneous/_ui64tow/test1,1
-miscellaneous/_ui64tow/test2,1
miscellaneous/charnexta/test1,1
miscellaneous/charnexta/test2,1
miscellaneous/charnextexa/test1,1
diff --git a/src/pal/tests/palsuite/samples/test1/CMakeLists.txt b/src/pal/tests/palsuite/samples/test1/CMakeLists.txt
index da5892cfa6..42f2ebdcdd 100644
--- a/src/pal/tests/palsuite/samples/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/samples/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_samples_test1
diff --git a/src/pal/tests/palsuite/samples/test1/test.c b/src/pal/tests/palsuite/samples/test1/test.cpp
index 2eed6f6f44..2eed6f6f44 100644
--- a/src/pal/tests/palsuite/samples/test1/test.c
+++ b/src/pal/tests/palsuite/samples/test1/test.cpp
diff --git a/src/pal/tests/palsuite/samples/test2/CMakeLists.txt b/src/pal/tests/palsuite/samples/test2/CMakeLists.txt
index fdef2aac6b..1a7ce2918e 100644
--- a/src/pal/tests/palsuite/samples/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/samples/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_samples_test2
diff --git a/src/pal/tests/palsuite/samples/test2/test.c b/src/pal/tests/palsuite/samples/test2/test.cpp
index 53d4158b9d..53d4158b9d 100644
--- a/src/pal/tests/palsuite/samples/test2/test.c
+++ b/src/pal/tests/palsuite/samples/test2/test.cpp
diff --git a/src/pal/tests/palsuite/threading/CreateEventA/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateEventA/test1/CMakeLists.txt
index da1232eea4..7be9481150 100644
--- a/src/pal/tests/palsuite/threading/CreateEventA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CreateEventA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_createeventa_test1
diff --git a/src/pal/tests/palsuite/threading/CreateEventA/test1/test1.c b/src/pal/tests/palsuite/threading/CreateEventA/test1/test1.cpp
index d8ef0f58a3..d8ef0f58a3 100644
--- a/src/pal/tests/palsuite/threading/CreateEventA/test1/test1.c
+++ b/src/pal/tests/palsuite/threading/CreateEventA/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/threading/CreateEventA/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateEventA/test2/CMakeLists.txt
index f87e5bea87..9725c89721 100644
--- a/src/pal/tests/palsuite/threading/CreateEventA/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CreateEventA/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_createeventa_test2
diff --git a/src/pal/tests/palsuite/threading/CreateEventA/test2/test2.c b/src/pal/tests/palsuite/threading/CreateEventA/test2/test2.cpp
index a24d20eeea..a24d20eeea 100644
--- a/src/pal/tests/palsuite/threading/CreateEventA/test2/test2.c
+++ b/src/pal/tests/palsuite/threading/CreateEventA/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/threading/CreateEventA/test3/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateEventA/test3/CMakeLists.txt
index e33c404a79..b596a881d5 100644
--- a/src/pal/tests/palsuite/threading/CreateEventA/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CreateEventA/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_createeventa_test3
diff --git a/src/pal/tests/palsuite/threading/CreateEventA/test3/test3.c b/src/pal/tests/palsuite/threading/CreateEventA/test3/test3.cpp
index 56d107b22d..56d107b22d 100644
--- a/src/pal/tests/palsuite/threading/CreateEventA/test3/test3.c
+++ b/src/pal/tests/palsuite/threading/CreateEventA/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/threading/CreateEventW/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateEventW/test1/CMakeLists.txt
index 0e8ba5bc2a..ef18312cda 100644
--- a/src/pal/tests/palsuite/threading/CreateEventW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CreateEventW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_createeventw_test1
diff --git a/src/pal/tests/palsuite/threading/CreateEventW/test1/test1.c b/src/pal/tests/palsuite/threading/CreateEventW/test1/test1.cpp
index 8d99e41934..8d99e41934 100644
--- a/src/pal/tests/palsuite/threading/CreateEventW/test1/test1.c
+++ b/src/pal/tests/palsuite/threading/CreateEventW/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/threading/CreateEventW/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateEventW/test2/CMakeLists.txt
index f624377474..7f9543e0cb 100644
--- a/src/pal/tests/palsuite/threading/CreateEventW/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CreateEventW/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_createeventw_test2
diff --git a/src/pal/tests/palsuite/threading/CreateEventW/test2/test2.c b/src/pal/tests/palsuite/threading/CreateEventW/test2/test2.cpp
index 4df218995a..4df218995a 100644
--- a/src/pal/tests/palsuite/threading/CreateEventW/test2/test2.c
+++ b/src/pal/tests/palsuite/threading/CreateEventW/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/threading/CreateEventW/test3/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateEventW/test3/CMakeLists.txt
index 4493ba3872..6778740f7e 100644
--- a/src/pal/tests/palsuite/threading/CreateEventW/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CreateEventW/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_createeventw_test3
diff --git a/src/pal/tests/palsuite/threading/CreateEventW/test3/test3.c b/src/pal/tests/palsuite/threading/CreateEventW/test3/test3.cpp
index 22f0fcfc49..22f0fcfc49 100644
--- a/src/pal/tests/palsuite/threading/CreateEventW/test3/test3.c
+++ b/src/pal/tests/palsuite/threading/CreateEventW/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test1/CMakeLists.txt
index ffdf13228e..782c671b84 100644
--- a/src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CreateMutexA.c
+ CreateMutexA.cpp
)
add_executable(paltest_createmutexa_releasemutex_test1
diff --git a/src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test1/CreateMutexA.c b/src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test1/CreateMutexA.cpp
index 52bab351fb..52bab351fb 100644
--- a/src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test1/CreateMutexA.c
+++ b/src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test1/CreateMutexA.cpp
diff --git a/src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test2/CMakeLists.txt
index 925c5d41f6..3540cb2b8c 100644
--- a/src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CreateMutexA.c
+ CreateMutexA.cpp
)
add_executable(paltest_createmutexa_releasemutex_test2
diff --git a/src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test2/CreateMutexA.c b/src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test2/CreateMutexA.c
deleted file mode 100644
index 3b83ba9674..0000000000
--- a/src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test2/CreateMutexA.c
+++ /dev/null
@@ -1,331 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: CreateMutexA_ReleaseMutex/test2/CreateMutexA.c
-**
-** Purpose: This test case tests the following things
-** - Creation of named Mutexes
-** - Creating multiple handles to a single named Mutex
-** - Ensuring that these handles work interchangeably
-** - Setting bInitialOwnerFlag to TRUE will cause the
-** initial call to a Wait function on the same Mutex
-** to actually wait.
-** - Waiting on a Mutex that a thread already owns does
-** not block.
-** - Create Named mutex with empty string ("")
-** - Create Named mutex with string of MAX_LONGPATH length
-** - Calling RelaseMutex with invalid Mutex handles and
-** valid but unowned Mutexes.
-**
-** Dependencies: CreateThread
-** ReleaseMutex
-** WaitForSingleObject
-** CloseHandle
-** Sleep
-** memset
-**
-
-**
-**=========================================================*/
-
-#define UNICODE
-#include <palsuite.h>
-
-const char *szMutex = "MyMutex";
-const char *szEmpty = "";
-
-/* Function Prototypes */
-BOOL TestNamedMutex(const char *szMutexName);
-DWORD NamedMutexThread(LPVOID lpParam);
-BOOL NegativeReleaseMutexTests();
-
-struct ThreadData
-{
- HANDLE hMutex;
- BOOL bReturnCode;
-};
-typedef struct ThreadData THREADDATA;
-
-
-int __cdecl main (int argc, char **argv)
-{
- BOOL bFailures = FALSE;
- char *szMaxPath;
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return ( FAIL );
- }
-
-
- /*
- * Test named Mutexes with ordinary string
- */
-
- if (!TestNamedMutex(szMutex))
- {
- bFailures = TRUE;
- }
-
-
- /*
- * Test named Mutexes with empty ("") string
- */
-
- if (!TestNamedMutex(szEmpty))
- {
- bFailures = TRUE;
- }
-
-
- /*
- * Test named Mutexes with string of length MAX_LONGPATHPATH
- */
-
- szMaxPath = (char *)malloc(MAX_LONGPATH+2);
- memset(szMaxPath, 'A', MAX_LONGPATH-60);
- szMaxPath[MAX_LONGPATH-60] = 0;
-
- if (!TestNamedMutex(szMaxPath))
- {
- bFailures = TRUE;
- }
-
- free(szMaxPath);
-
-
- /*
- * Run some negative tests on ReleaseMutex
- */
-
- if (!NegativeReleaseMutexTests())
- {
- bFailures = TRUE;
- }
-
-
- /*
- * If there were any failures, then abort with a call to Fail
- */
-
- if (bFailures == TRUE)
- {
- Fail("ERROR: There some failures in the Mutex tests.\n");
- }
-
- PAL_Terminate();
- return ( PASS );
-}
-
-
-/*
- * Testing Function
- *
- * Try to get multiple handles to a named Mutex and test
- * to make sure they actually refer to same Mutex object.
- */
-BOOL TestNamedMutex(const char *szMutexName)
-{
- DWORD dwData;
- HANDLE hMutex1;
- HANDLE hMutex2;
- HANDLE hThread;
- THREADDATA threadData;
-
- /* Create a mutex and take ownership immediately */
- hMutex1 = CreateMutexA (NULL, TRUE, szMutexName);
-
- if (NULL == hMutex1)
- {
- Trace("ERROR: CreateMutexA #1 failed. GetLastError returned %u\n",
- GetLastError());
- return FALSE;
- }
-
- /* Try to wait on the Mutex we just created. We should not block. */
- if (WaitForSingleObject(hMutex1, 1000) == WAIT_TIMEOUT)
- {
- Trace("WaitForSingleObject blocked on a Mutex that we owned.\n");
- return FALSE;
- }
- /* We have to call ReleaseMutex here because of the Wait */
- if (ReleaseMutex(hMutex1) == FALSE)
- {
- Trace("ReleaseMutex Failed.\n");
- return FALSE;
- }
-
- /* Get a second handle to the same mutex */
- hMutex2 = CreateMutexA (NULL, FALSE, szMutexName);
-
- if (NULL == hMutex2)
- {
- Trace("ERROR: CreateMutex #2 failed. GetLastError returned %u\n",
- GetLastError());
- free(szMutexName);
- return FALSE;
- }
-
- /*
- * Create a thread that will Wait on the second handle.
- */
- threadData.hMutex = hMutex2;
- hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)NamedMutexThread,
- (LPVOID)&threadData, 0, &dwData);
-
- if (NULL == hThread)
- {
- Trace("ERROR: CreateThread failed. GetLastError returned %u\n",
- GetLastError());
- return FALSE;
- }
-
- /* Give the thread a little time to execute & wait*/
- Sleep(500);
-
- /* Signal the the first handle */
- if (ReleaseMutex(hMutex1) == FALSE)
- {
- Trace("ReleaseMutex Failed.\n");
- return FALSE;
- }
-
- /* Give the thread some time to finish */
- Sleep(2000);
-
- /* Clean Up */
- if (CloseHandle(hMutex1) == FALSE ||
- CloseHandle(hMutex2) == FALSE ||
- CloseHandle(hThread) == FALSE)
- {
- Trace("ERROR: CloseHandle failed.\n");
- return FALSE;
- }
-
- /* Check the return code to see if signalling the first */
- /* Mutex handle woke up the thread which was Waiting on */
- /* the second handle. */
- if (threadData.bReturnCode != FALSE)
- {
- Trace("ERROR: The handles did not refer to the same Mutex object.\n");
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-/*
- * Thread function used with above testing function.
- */
-DWORD NamedMutexThread(LPVOID lpParam)
-{
- BOOL bTimedOut = FALSE;
- THREADDATA *lpThreadData = (THREADDATA *)lpParam;
-
- /* Wait on the Mutex that was passed to us */
- if (WaitForSingleObject(lpThreadData->hMutex, 10000) == WAIT_TIMEOUT)
- {
- /* The Mutex was not signaled in the allotted time */
- bTimedOut = TRUE;
- }
- if (ReleaseMutex(lpThreadData->hMutex) == FALSE)
- {
- Trace("ERROR: ReleaseMutex failed.\n");
- lpThreadData->bReturnCode = FALSE;
- return 0;
- }
-
- /* Indicate whether we timed out Waiting on the Mutex */
- lpThreadData->bReturnCode = bTimedOut;
-
- return 0;
-}
-
-
-/*
- * Testing Function
- *
- * Try some negative tests on ReleaseMutex
- */
-BOOL NegativeReleaseMutexTests()
-{
- HANDLE hMutex;
- BOOL bRet;
- BOOL bResults = TRUE;
-
-
- /*
- * Try calling ReleaseMutex on a null handle
- */
- hMutex = 0;
- bRet = ReleaseMutex(hMutex);
-
- if (bRet != 0)
- {
- Trace("Error: ReleaseMutex accepted null handle.\n");
- bResults = FALSE;
- }
-
-
- /*
- * Try calling ReleaseMutex on an handle that we don't own
- */
- hMutex = CreateMutexA (NULL, TRUE, NULL);
- if (hMutex == 0)
- {
- Trace("Error: CreateMutex failed.\n");
- bResults = FALSE;
- }
-
- bRet = ReleaseMutex(hMutex);
- bRet = ReleaseMutex(hMutex);
-
- if (bRet != FALSE)
- {
- Trace("Error: ReleaseMutex accepted unowned handle.\n");
- bResults = FALSE;
- }
-
- if (CloseHandle(hMutex) == FALSE)
- {
- Trace("Error: CloseHandle failed.\n");
- bResults = FALSE;
- }
-
-
-
- /*
- * Try calling ReleaseMutex on an handle that has been closed
- */
- hMutex = CreateMutexA (NULL, TRUE, NULL);
- if (hMutex == 0)
- {
- Trace("Error: CreateMutex failed.\n");
- bResults = FALSE;
- }
-
- if (ReleaseMutex(hMutex) == FALSE)
- {
- Trace("Error: ReleaseMutex failed.\n");
- bResults = FALSE;
- }
- if (CloseHandle(hMutex) == FALSE)
- {
- Trace("Error: CloseHandle failed.\n");
- bResults = FALSE;
- }
-
- bRet = ReleaseMutex(hMutex);
-
- if (bRet != FALSE)
- {
- Trace("Error: ReleaseMutex accepted invalid handle.\n");
- bResults = FALSE;
- }
-
- return bResults;
-}
diff --git a/src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test2/CreateMutexA.cpp b/src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test2/CreateMutexA.cpp
new file mode 100644
index 0000000000..36295855e0
--- /dev/null
+++ b/src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test2/CreateMutexA.cpp
@@ -0,0 +1,331 @@
+// Licensed to the .NET Foundation under one or more 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: CreateMutexA_ReleaseMutex/test2/CreateMutexA.c
+**
+** Purpose: This test case tests the following things
+** - Creation of named Mutexes
+** - Creating multiple handles to a single named Mutex
+** - Ensuring that these handles work interchangeably
+** - Setting bInitialOwnerFlag to TRUE will cause the
+** initial call to a Wait function on the same Mutex
+** to actually wait.
+** - Waiting on a Mutex that a thread already owns does
+** not block.
+** - Create Named mutex with empty string ("")
+** - Create Named mutex with string of MAX_LONGPATH length
+** - Calling RelaseMutex with invalid Mutex handles and
+** valid but unowned Mutexes.
+**
+** Dependencies: CreateThread
+** ReleaseMutex
+** WaitForSingleObject
+** CloseHandle
+** Sleep
+** memset
+**
+
+**
+**=========================================================*/
+
+#define UNICODE
+#include <palsuite.h>
+
+const char *szMutex = "MyMutex";
+const char *szEmpty = "";
+
+/* Function Prototypes */
+BOOL TestNamedMutex(const char *szMutexName);
+DWORD NamedMutexThread(LPVOID lpParam);
+BOOL NegativeReleaseMutexTests();
+
+struct ThreadData
+{
+ HANDLE hMutex;
+ BOOL bReturnCode;
+};
+typedef struct ThreadData THREADDATA;
+
+
+int __cdecl main (int argc, char **argv)
+{
+ BOOL bFailures = FALSE;
+ char *szMaxPath;
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return ( FAIL );
+ }
+
+
+ /*
+ * Test named Mutexes with ordinary string
+ */
+
+ if (!TestNamedMutex(szMutex))
+ {
+ bFailures = TRUE;
+ }
+
+
+ /*
+ * Test named Mutexes with empty ("") string
+ */
+
+ if (!TestNamedMutex(szEmpty))
+ {
+ bFailures = TRUE;
+ }
+
+
+ /*
+ * Test named Mutexes with string of length MAX_LONGPATHPATH
+ */
+
+ szMaxPath = (char *)malloc(MAX_LONGPATH+2);
+ memset(szMaxPath, 'A', MAX_LONGPATH-60);
+ szMaxPath[MAX_LONGPATH-60] = 0;
+
+ if (!TestNamedMutex(szMaxPath))
+ {
+ bFailures = TRUE;
+ }
+
+ free((void*)szMaxPath);
+
+
+ /*
+ * Run some negative tests on ReleaseMutex
+ */
+
+ if (!NegativeReleaseMutexTests())
+ {
+ bFailures = TRUE;
+ }
+
+
+ /*
+ * If there were any failures, then abort with a call to Fail
+ */
+
+ if (bFailures == TRUE)
+ {
+ Fail("ERROR: There some failures in the Mutex tests.\n");
+ }
+
+ PAL_Terminate();
+ return ( PASS );
+}
+
+
+/*
+ * Testing Function
+ *
+ * Try to get multiple handles to a named Mutex and test
+ * to make sure they actually refer to same Mutex object.
+ */
+BOOL TestNamedMutex(const char *szMutexName)
+{
+ DWORD dwData;
+ HANDLE hMutex1;
+ HANDLE hMutex2;
+ HANDLE hThread;
+ THREADDATA threadData;
+
+ /* Create a mutex and take ownership immediately */
+ hMutex1 = CreateMutexA (NULL, TRUE, szMutexName);
+
+ if (NULL == hMutex1)
+ {
+ Trace("ERROR: CreateMutexA #1 failed. GetLastError returned %u\n",
+ GetLastError());
+ return FALSE;
+ }
+
+ /* Try to wait on the Mutex we just created. We should not block. */
+ if (WaitForSingleObject(hMutex1, 1000) == WAIT_TIMEOUT)
+ {
+ Trace("WaitForSingleObject blocked on a Mutex that we owned.\n");
+ return FALSE;
+ }
+ /* We have to call ReleaseMutex here because of the Wait */
+ if (ReleaseMutex(hMutex1) == FALSE)
+ {
+ Trace("ReleaseMutex Failed.\n");
+ return FALSE;
+ }
+
+ /* Get a second handle to the same mutex */
+ hMutex2 = CreateMutexA (NULL, FALSE, szMutexName);
+
+ if (NULL == hMutex2)
+ {
+ Trace("ERROR: CreateMutex #2 failed. GetLastError returned %u\n",
+ GetLastError());
+ free((void*)szMutexName);
+ return FALSE;
+ }
+
+ /*
+ * Create a thread that will Wait on the second handle.
+ */
+ threadData.hMutex = hMutex2;
+ hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)NamedMutexThread,
+ (LPVOID)&threadData, 0, &dwData);
+
+ if (NULL == hThread)
+ {
+ Trace("ERROR: CreateThread failed. GetLastError returned %u\n",
+ GetLastError());
+ return FALSE;
+ }
+
+ /* Give the thread a little time to execute & wait*/
+ Sleep(500);
+
+ /* Signal the the first handle */
+ if (ReleaseMutex(hMutex1) == FALSE)
+ {
+ Trace("ReleaseMutex Failed.\n");
+ return FALSE;
+ }
+
+ /* Give the thread some time to finish */
+ Sleep(2000);
+
+ /* Clean Up */
+ if (CloseHandle(hMutex1) == FALSE ||
+ CloseHandle(hMutex2) == FALSE ||
+ CloseHandle(hThread) == FALSE)
+ {
+ Trace("ERROR: CloseHandle failed.\n");
+ return FALSE;
+ }
+
+ /* Check the return code to see if signalling the first */
+ /* Mutex handle woke up the thread which was Waiting on */
+ /* the second handle. */
+ if (threadData.bReturnCode != FALSE)
+ {
+ Trace("ERROR: The handles did not refer to the same Mutex object.\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Thread function used with above testing function.
+ */
+DWORD NamedMutexThread(LPVOID lpParam)
+{
+ BOOL bTimedOut = FALSE;
+ THREADDATA *lpThreadData = (THREADDATA *)lpParam;
+
+ /* Wait on the Mutex that was passed to us */
+ if (WaitForSingleObject(lpThreadData->hMutex, 10000) == WAIT_TIMEOUT)
+ {
+ /* The Mutex was not signaled in the allotted time */
+ bTimedOut = TRUE;
+ }
+ if (ReleaseMutex(lpThreadData->hMutex) == FALSE)
+ {
+ Trace("ERROR: ReleaseMutex failed.\n");
+ lpThreadData->bReturnCode = FALSE;
+ return 0;
+ }
+
+ /* Indicate whether we timed out Waiting on the Mutex */
+ lpThreadData->bReturnCode = bTimedOut;
+
+ return 0;
+}
+
+
+/*
+ * Testing Function
+ *
+ * Try some negative tests on ReleaseMutex
+ */
+BOOL NegativeReleaseMutexTests()
+{
+ HANDLE hMutex;
+ BOOL bRet;
+ BOOL bResults = TRUE;
+
+
+ /*
+ * Try calling ReleaseMutex on a null handle
+ */
+ hMutex = 0;
+ bRet = ReleaseMutex(hMutex);
+
+ if (bRet != 0)
+ {
+ Trace("Error: ReleaseMutex accepted null handle.\n");
+ bResults = FALSE;
+ }
+
+
+ /*
+ * Try calling ReleaseMutex on an handle that we don't own
+ */
+ hMutex = CreateMutexA (NULL, TRUE, NULL);
+ if (hMutex == 0)
+ {
+ Trace("Error: CreateMutex failed.\n");
+ bResults = FALSE;
+ }
+
+ bRet = ReleaseMutex(hMutex);
+ bRet = ReleaseMutex(hMutex);
+
+ if (bRet != FALSE)
+ {
+ Trace("Error: ReleaseMutex accepted unowned handle.\n");
+ bResults = FALSE;
+ }
+
+ if (CloseHandle(hMutex) == FALSE)
+ {
+ Trace("Error: CloseHandle failed.\n");
+ bResults = FALSE;
+ }
+
+
+
+ /*
+ * Try calling ReleaseMutex on an handle that has been closed
+ */
+ hMutex = CreateMutexA (NULL, TRUE, NULL);
+ if (hMutex == 0)
+ {
+ Trace("Error: CreateMutex failed.\n");
+ bResults = FALSE;
+ }
+
+ if (ReleaseMutex(hMutex) == FALSE)
+ {
+ Trace("Error: ReleaseMutex failed.\n");
+ bResults = FALSE;
+ }
+ if (CloseHandle(hMutex) == FALSE)
+ {
+ Trace("Error: CloseHandle failed.\n");
+ bResults = FALSE;
+ }
+
+ bRet = ReleaseMutex(hMutex);
+
+ if (bRet != FALSE)
+ {
+ Trace("Error: ReleaseMutex accepted invalid handle.\n");
+ bResults = FALSE;
+ }
+
+ return bResults;
+}
diff --git a/src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test1/CMakeLists.txt
index a73ee045a3..aa1f7831c0 100644
--- a/src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CreateMutexW.c
+ CreateMutexW.cpp
)
add_executable(paltest_createmutexw_releasemutex_test1
diff --git a/src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test1/CreateMutexW.c b/src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test1/CreateMutexW.cpp
index c21bfb6a50..c21bfb6a50 100644
--- a/src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test1/CreateMutexW.c
+++ b/src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test1/CreateMutexW.cpp
diff --git a/src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test2/CMakeLists.txt
index b40569b3f5..5a9095cb1b 100644
--- a/src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CreateMutexW.c
+ CreateMutexW.cpp
)
add_executable(paltest_createmutexw_releasemutex_test2
diff --git a/src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test2/CreateMutexW.c b/src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test2/CreateMutexW.cpp
index 41b7798a6e..41b7798a6e 100644
--- a/src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test2/CreateMutexW.c
+++ b/src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test2/CreateMutexW.cpp
diff --git a/src/pal/tests/palsuite/threading/CreateProcessA/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateProcessA/test1/CMakeLists.txt
index 67e53edccd..9cd0aa5dfd 100644
--- a/src/pal/tests/palsuite/threading/CreateProcessA/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CreateProcessA/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(TESTSOURCES
- parentProcess.c
+ parentProcess.cpp
)
add_executable(paltest_createprocessa_test1
@@ -20,7 +20,7 @@ target_link_libraries(paltest_createprocessa_test1
set(HELPERSOURCES
- childProcess.c
+ childProcess.cpp
)
add_executable(paltest_createprocessa_test1_child
diff --git a/src/pal/tests/palsuite/threading/CreateProcessA/test1/childProcess.c b/src/pal/tests/palsuite/threading/CreateProcessA/test1/childProcess.cpp
index ccbb050c04..ccbb050c04 100644
--- a/src/pal/tests/palsuite/threading/CreateProcessA/test1/childProcess.c
+++ b/src/pal/tests/palsuite/threading/CreateProcessA/test1/childProcess.cpp
diff --git a/src/pal/tests/palsuite/threading/CreateProcessA/test1/parentProcess.c b/src/pal/tests/palsuite/threading/CreateProcessA/test1/parentProcess.cpp
index b0c5808a7e..b0c5808a7e 100644
--- a/src/pal/tests/palsuite/threading/CreateProcessA/test1/parentProcess.c
+++ b/src/pal/tests/palsuite/threading/CreateProcessA/test1/parentProcess.cpp
diff --git a/src/pal/tests/palsuite/threading/CreateProcessA/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateProcessA/test2/CMakeLists.txt
index b81ea2e978..f035f0a888 100644
--- a/src/pal/tests/palsuite/threading/CreateProcessA/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CreateProcessA/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(TESTSOURCES
- parentprocess.c
+ parentprocess.cpp
)
add_executable(paltest_createprocessa_test2
@@ -20,7 +20,7 @@ target_link_libraries(paltest_createprocessa_test2
set(HELPERSOURCES
- childprocess.c
+ childprocess.cpp
)
add_executable(paltest_createprocessa_test2_child
diff --git a/src/pal/tests/palsuite/threading/CreateProcessA/test2/childprocess.c b/src/pal/tests/palsuite/threading/CreateProcessA/test2/childprocess.cpp
index baa20c2d3c..baa20c2d3c 100644
--- a/src/pal/tests/palsuite/threading/CreateProcessA/test2/childprocess.c
+++ b/src/pal/tests/palsuite/threading/CreateProcessA/test2/childprocess.cpp
diff --git a/src/pal/tests/palsuite/threading/CreateProcessA/test2/parentprocess.c b/src/pal/tests/palsuite/threading/CreateProcessA/test2/parentprocess.cpp
index ef3340c5d9..ef3340c5d9 100644
--- a/src/pal/tests/palsuite/threading/CreateProcessA/test2/parentprocess.c
+++ b/src/pal/tests/palsuite/threading/CreateProcessA/test2/parentprocess.cpp
diff --git a/src/pal/tests/palsuite/threading/CreateProcessW/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateProcessW/test1/CMakeLists.txt
index 394b124526..174d6fe3c7 100644
--- a/src/pal/tests/palsuite/threading/CreateProcessW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CreateProcessW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(TESTSOURCES
- parentProcess.c
+ parentProcess.cpp
)
add_executable(paltest_createprocessw_test1
@@ -20,7 +20,7 @@ target_link_libraries(paltest_createprocessw_test1
set(HELPERSOURCES
- childProcess.c
+ childProcess.cpp
)
add_executable(paltest_createprocessw_test1_child
diff --git a/src/pal/tests/palsuite/threading/CreateProcessW/test1/childProcess.c b/src/pal/tests/palsuite/threading/CreateProcessW/test1/childProcess.c
deleted file mode 100644
index c71f967b65..0000000000
--- a/src/pal/tests/palsuite/threading/CreateProcessW/test1/childProcess.c
+++ /dev/null
@@ -1,150 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: CreateProcessW/test1/childprocess.c
-**
-** Purpose: Test to ensure CreateProcessW starts a new process. This test
-** launches a child process, and examines a file written by the child.
-** This code is the child code.
-**
-** Dependencies: GetCurrentDirectory
-** MultiByteToWideChar
-** wcslen
-** strlen
-** WideCharToMultiByte
-** fopen
-** fclose
-** fprintf
-**
-
-**
-**=========================================================*/
-
-#define UNICODE
-#include <palsuite.h>
-
-const WCHAR szCommonFileW[] =
- {'c','h','i','l','d','d','a','t','a','.','t','m','p','\0'};
-
-const WCHAR szPathDelimW[] = {'\\','\0'};
-
-const char *szCommonStringA = "058d2d057111a313aa82401c2e856002\0";
-
-/*
- * Take two wide strings representing file and directory names
- * (dirName, fileName), join the strings with the appropriate path
- * delimiter and populate a wide character buffer (absPathName) with
- * the resulting string.
- *
- * Returns: The number of wide characters in the resulting string.
- * 0 is returned on Error.
- */
-int
-mkAbsoluteFilenameW (
- LPWSTR dirName,
- DWORD dwDirLength,
- LPCWSTR fileName,
- DWORD dwFileLength,
- LPWSTR absPathName )
-{
- extern const WCHAR szPathDelimW[];
-
- DWORD sizeDN, sizeFN, sizeAPN;
-
- sizeDN = wcslen( dirName );
- sizeFN = wcslen( fileName );
- sizeAPN = (sizeDN + 1 + sizeFN + 1);
-
- /* insure ((dirName + DELIM + fileName + \0) =< _MAX_PATH ) */
- if ( sizeAPN > _MAX_PATH )
- {
- return ( 0 );
- }
-
- wcsncpy(absPathName, dirName, dwDirLength +1);
- wcsncpy(absPathName, szPathDelimW, 2);
- wcsncpy(absPathName, fileName, dwFileLength +1);
-
- return (sizeAPN);
-
-}
-
-int __cdecl main( int argc, char **argv )
-{
-
- static FILE * fp;
-
- DWORD dwFileLength;
- DWORD dwDirLength;
- DWORD dwSize;
-
- char *szAbsPathNameA;
- WCHAR szDirNameW[_MAX_DIR];
- WCHAR szAbsPathNameW[_MAX_PATH];
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return ( FAIL );
- }
-
- dwDirLength = GetCurrentDirectory( _MAX_PATH, szDirNameW );
-
- if (0 == dwDirLength)
- {
- Fail ("GetCurrentDirectory call failed. Could not get "
- "current working directory\n. Exiting.\n");
- }
-
- dwFileLength = wcslen( szCommonFileW );
-
- dwSize = mkAbsoluteFilenameW( szDirNameW, dwDirLength, szCommonFileW,
- dwFileLength, szAbsPathNameW );
-
- if (0 == dwSize)
- {
- Fail ("Palsuite Code: mkAbsoluteFilename() call failed. Could "
- "not build absolute path name to file\n. Exiting.\n");
- }
-
- /* set the string length for the open call */
- szAbsPathNameA = malloc (dwSize +1);
-
- if (NULL == szAbsPathNameA)
- {
- Fail ("Unable to malloc (%d) bytes. Exiting\n", (dwSize +1) );
- }
-
- WideCharToMultiByte (CP_ACP, 0, szAbsPathNameW, -1, szAbsPathNameA,
- (dwSize + 1), NULL, NULL);
-
- if ( NULL == ( fp = fopen ( szAbsPathNameA , "w+" ) ) )
- {
- /*
- * A return value of NULL indicates an error condition or an
- * EOF condition
- */
- Fail ("%s unable to open %s for writing. Exiting.\n", argv[0]
- , szAbsPathNameA );
- }
-
- free (szAbsPathNameA);
-
- if ( 0 >= ( fprintf ( fp, "%s", szCommonStringA )))
- {
- Fail("%s unable to write to %s. Exiting.\n", argv[0]
- , szAbsPathNameA );
- }
-
- if (0 != (fclose ( fp )))
- {
- Fail ("%s unable to close file %s. Pid may not be "
- "written to file. Exiting.\n", argv[0], szAbsPathNameA );
- }
-
- PAL_Terminate();
- return ( PASS );
-
-}
diff --git a/src/pal/tests/palsuite/threading/CreateProcessW/test1/childProcess.cpp b/src/pal/tests/palsuite/threading/CreateProcessW/test1/childProcess.cpp
new file mode 100644
index 0000000000..a7730c6d51
--- /dev/null
+++ b/src/pal/tests/palsuite/threading/CreateProcessW/test1/childProcess.cpp
@@ -0,0 +1,150 @@
+// Licensed to the .NET Foundation under one or more 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: CreateProcessW/test1/childprocess.c
+**
+** Purpose: Test to ensure CreateProcessW starts a new process. This test
+** launches a child process, and examines a file written by the child.
+** This code is the child code.
+**
+** Dependencies: GetCurrentDirectory
+** MultiByteToWideChar
+** wcslen
+** strlen
+** WideCharToMultiByte
+** fopen
+** fclose
+** fprintf
+**
+
+**
+**=========================================================*/
+
+#define UNICODE
+#include <palsuite.h>
+
+const WCHAR szCommonFileW[] =
+ {'c','h','i','l','d','d','a','t','a','.','t','m','p','\0'};
+
+const WCHAR szPathDelimW[] = {'\\','\0'};
+
+const char *szCommonStringA = "058d2d057111a313aa82401c2e856002\0";
+
+/*
+ * Take two wide strings representing file and directory names
+ * (dirName, fileName), join the strings with the appropriate path
+ * delimiter and populate a wide character buffer (absPathName) with
+ * the resulting string.
+ *
+ * Returns: The number of wide characters in the resulting string.
+ * 0 is returned on Error.
+ */
+int
+mkAbsoluteFilenameW (
+ LPWSTR dirName,
+ DWORD dwDirLength,
+ LPCWSTR fileName,
+ DWORD dwFileLength,
+ LPWSTR absPathName )
+{
+ extern const WCHAR szPathDelimW[];
+
+ DWORD sizeDN, sizeFN, sizeAPN;
+
+ sizeDN = wcslen( dirName );
+ sizeFN = wcslen( fileName );
+ sizeAPN = (sizeDN + 1 + sizeFN + 1);
+
+ /* insure ((dirName + DELIM + fileName + \0) =< _MAX_PATH ) */
+ if ( sizeAPN > _MAX_PATH )
+ {
+ return ( 0 );
+ }
+
+ wcsncpy(absPathName, dirName, dwDirLength +1);
+ wcsncpy(absPathName, szPathDelimW, 2);
+ wcsncpy(absPathName, fileName, dwFileLength +1);
+
+ return (sizeAPN);
+
+}
+
+int __cdecl main( int argc, char **argv )
+{
+
+ static FILE * fp;
+
+ DWORD dwFileLength;
+ DWORD dwDirLength;
+ DWORD dwSize;
+
+ char *szAbsPathNameA;
+ WCHAR szDirNameW[_MAX_DIR];
+ WCHAR szAbsPathNameW[_MAX_PATH];
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return ( FAIL );
+ }
+
+ dwDirLength = GetCurrentDirectory( _MAX_PATH, szDirNameW );
+
+ if (0 == dwDirLength)
+ {
+ Fail ("GetCurrentDirectory call failed. Could not get "
+ "current working directory\n. Exiting.\n");
+ }
+
+ dwFileLength = wcslen( szCommonFileW );
+
+ dwSize = mkAbsoluteFilenameW( szDirNameW, dwDirLength, szCommonFileW,
+ dwFileLength, szAbsPathNameW );
+
+ if (0 == dwSize)
+ {
+ Fail ("Palsuite Code: mkAbsoluteFilename() call failed. Could "
+ "not build absolute path name to file\n. Exiting.\n");
+ }
+
+ /* set the string length for the open call */
+ szAbsPathNameA = (char*)malloc(dwSize +1);
+
+ if (NULL == szAbsPathNameA)
+ {
+ Fail ("Unable to malloc (%d) bytes. Exiting\n", (dwSize +1) );
+ }
+
+ WideCharToMultiByte (CP_ACP, 0, szAbsPathNameW, -1, szAbsPathNameA,
+ (dwSize + 1), NULL, NULL);
+
+ if ( NULL == ( fp = fopen ( szAbsPathNameA , "w+" ) ) )
+ {
+ /*
+ * A return value of NULL indicates an error condition or an
+ * EOF condition
+ */
+ Fail ("%s unable to open %s for writing. Exiting.\n", argv[0]
+ , szAbsPathNameA );
+ }
+
+ free (szAbsPathNameA);
+
+ if ( 0 >= ( fprintf ( fp, "%s", szCommonStringA )))
+ {
+ Fail("%s unable to write to %s. Exiting.\n", argv[0]
+ , szAbsPathNameA );
+ }
+
+ if (0 != (fclose ( fp )))
+ {
+ Fail ("%s unable to close file %s. Pid may not be "
+ "written to file. Exiting.\n", argv[0], szAbsPathNameA );
+ }
+
+ PAL_Terminate();
+ return ( PASS );
+
+}
diff --git a/src/pal/tests/palsuite/threading/CreateProcessW/test1/parentProcess.c b/src/pal/tests/palsuite/threading/CreateProcessW/test1/parentProcess.cpp
index db1fb6356d..db1fb6356d 100644
--- a/src/pal/tests/palsuite/threading/CreateProcessW/test1/parentProcess.c
+++ b/src/pal/tests/palsuite/threading/CreateProcessW/test1/parentProcess.cpp
diff --git a/src/pal/tests/palsuite/threading/CreateProcessW/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateProcessW/test2/CMakeLists.txt
index 3feef213c4..021a0d2da2 100644
--- a/src/pal/tests/palsuite/threading/CreateProcessW/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CreateProcessW/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(TESTSOURCES
- parentprocess.c
+ parentprocess.cpp
)
add_executable(paltest_createprocessw_test2
@@ -20,7 +20,7 @@ target_link_libraries(paltest_createprocessw_test2
set(HELPERSOURCES
- childprocess.c
+ childprocess.cpp
)
add_executable(paltest_createprocessw_test2_child
diff --git a/src/pal/tests/palsuite/threading/CreateProcessW/test2/childprocess.c b/src/pal/tests/palsuite/threading/CreateProcessW/test2/childprocess.cpp
index b4ab9366d9..b4ab9366d9 100644
--- a/src/pal/tests/palsuite/threading/CreateProcessW/test2/childprocess.c
+++ b/src/pal/tests/palsuite/threading/CreateProcessW/test2/childprocess.cpp
diff --git a/src/pal/tests/palsuite/threading/CreateProcessW/test2/parentprocess.c b/src/pal/tests/palsuite/threading/CreateProcessW/test2/parentprocess.cpp
index 439b7b5eef..439b7b5eef 100644
--- a/src/pal/tests/palsuite/threading/CreateProcessW/test2/parentprocess.c
+++ b/src/pal/tests/palsuite/threading/CreateProcessW/test2/parentprocess.cpp
diff --git a/src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test1/CMakeLists.txt
index f89e150a32..8a9255ce7a 100644
--- a/src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CreateSemaphore.c
+ CreateSemaphore.cpp
)
add_executable(paltest_createsemaphorea_releasesemaphore_test1
diff --git a/src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test1/CreateSemaphore.c b/src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test1/CreateSemaphore.cpp
index 342b15ec29..342b15ec29 100644
--- a/src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test1/CreateSemaphore.c
+++ b/src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test1/CreateSemaphore.cpp
diff --git a/src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test2/CMakeLists.txt
index f3e01749b8..6d1249bf05 100644
--- a/src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CreateSemaphore.c
+ CreateSemaphore.cpp
)
add_executable(paltest_createsemaphorea_releasesemaphore_test2
diff --git a/src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test2/CreateSemaphore.c b/src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test2/CreateSemaphore.cpp
index bff5b51c33..bff5b51c33 100644
--- a/src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test2/CreateSemaphore.c
+++ b/src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test2/CreateSemaphore.cpp
diff --git a/src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test3/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test3/CMakeLists.txt
index 0c604d6ced..94998f59a9 100644
--- a/src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- createsemaphore.c
+ createsemaphore.cpp
)
add_executable(paltest_createsemaphorea_releasesemaphore_test3
diff --git a/src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test3/createsemaphore.c b/src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test3/createsemaphore.cpp
index 7c6db6b055..7c6db6b055 100644
--- a/src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test3/createsemaphore.c
+++ b/src/pal/tests/palsuite/threading/CreateSemaphoreA_ReleaseSemaphore/test3/createsemaphore.cpp
diff --git a/src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test1/CMakeLists.txt
index b40f2695bc..32902cf914 100644
--- a/src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CreateSemaphore.c
+ CreateSemaphore.cpp
)
add_executable(paltest_createsemaphorew_releasesemaphore_test1
diff --git a/src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test1/CreateSemaphore.c b/src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test1/CreateSemaphore.cpp
index 854d16d0ef..854d16d0ef 100644
--- a/src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test1/CreateSemaphore.c
+++ b/src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test1/CreateSemaphore.cpp
diff --git a/src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test2/CMakeLists.txt
index b14284d08f..bd0a5a6e53 100644
--- a/src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- CreateSemaphore.c
+ CreateSemaphore.cpp
)
add_executable(paltest_createsemaphorew_releasesemaphore_test2
diff --git a/src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test2/CreateSemaphore.c b/src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test2/CreateSemaphore.cpp
index 62532737ac..62532737ac 100644
--- a/src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test2/CreateSemaphore.c
+++ b/src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test2/CreateSemaphore.cpp
diff --git a/src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test3/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test3/CMakeLists.txt
index f7f0905761..d0340c64cb 100644
--- a/src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- createsemaphore.c
+ createsemaphore.cpp
)
add_executable(paltest_createsemaphorew_releasesemaphore_test3
diff --git a/src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test3/createsemaphore.c b/src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test3/createsemaphore.cpp
index ea0a5e0846..ea0a5e0846 100644
--- a/src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test3/createsemaphore.c
+++ b/src/pal/tests/palsuite/threading/CreateSemaphoreW_ReleaseSemaphore/test3/createsemaphore.cpp
diff --git a/src/pal/tests/palsuite/threading/CreateThread/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateThread/test1/CMakeLists.txt
index d3921c4409..b47afe498a 100644
--- a/src/pal/tests/palsuite/threading/CreateThread/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CreateThread/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_createthread_test1
diff --git a/src/pal/tests/palsuite/threading/CreateThread/test1/test1.c b/src/pal/tests/palsuite/threading/CreateThread/test1/test1.c
deleted file mode 100644
index 2dd2f6acb6..0000000000
--- a/src/pal/tests/palsuite/threading/CreateThread/test1/test1.c
+++ /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.
-
-/*============================================================
-**
-** Source: test1.c
-**
-** Purpose: Test for CreateThread. Call CreateThread and ensure
-** that it succeeds. Also check to ensure the paramater is passed
-** properly.
-**
-**
-**=========================================================*/
-
-#include <palsuite.h>
-
-#ifndef PLATFORM_UNIX
-#define LLFORMAT "%I64u"
-#else
-#define LLFORMAT "%llu"
-#endif
-
-ULONGLONG dwCreateThreadTestParameter = 0;
-
-DWORD PALAPI CreateThreadTestThread( LPVOID lpParameter)
-{
- DWORD dwRet = 0;
-
- /* save parameter for test */
- dwCreateThreadTestParameter = (ULONGLONG)lpParameter;
-
- return dwRet;
-}
-
-BOOL CreateThreadTest()
-{
- BOOL bRet = FALSE;
- DWORD dwRet = 0;
-
- LPSECURITY_ATTRIBUTES lpThreadAttributes = NULL;
- DWORD dwStackSize = 0;
- LPTHREAD_START_ROUTINE lpStartAddress = &CreateThreadTestThread;
- LPVOID lpParameter = lpStartAddress;
- DWORD dwCreationFlags = 0; /* run immediately */
- DWORD dwThreadId = 0;
-
- HANDLE hThread = 0;
-
- dwCreateThreadTestParameter = 0;
-
- /* Create a thread, passing the appropriate paramaters as declared
- above.
- */
-
- hThread = CreateThread( lpThreadAttributes,
- dwStackSize,
- lpStartAddress,
- lpParameter,
- dwCreationFlags,
- &dwThreadId );
-
- /* Ensure that the HANDLE is not invalid! */
- if (hThread != INVALID_HANDLE_VALUE)
- {
- dwRet = WaitForSingleObject(hThread,INFINITE);
-
- if (dwRet != WAIT_OBJECT_0)
- {
- Trace("CreateThreadTest:WaitForSingleObject "
- "failed (%x)\n",GetLastError());
- }
- else
- {
- /* Check to ensure that the parameter passed to the thread
- function is the same in the function as what we passed.
- */
-
- if (dwCreateThreadTestParameter != (ULONGLONG)lpParameter)
- {
- Trace("CreateThreadTest:parameter error. The "
- "parameter passed should have been " LLFORMAT " but when "
- "passed to the Thread function it was " LLFORMAT " . GetLastError[%x]\n",
- dwCreateThreadTestParameter,lpParameter, GetLastError());
- }
- else
- {
- bRet = TRUE;
- }
-
- }
- CloseHandle(hThread);
- }
- else
- {
- Trace("CreateThreadTest:CreateThread failed (%x)\n",GetLastError());
- }
-
- return bRet;
-}
-
-
-int __cdecl main(int argc, char **argv)
-{
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return ( FAIL );
- }
-
- if(!CreateThreadTest())
- {
- Fail ("Test failed\n");
- }
-
- Trace("Test Passed\n");
- PAL_Terminate();
- return ( PASS );
-
-}
diff --git a/src/pal/tests/palsuite/threading/CreateThread/test1/test1.cpp b/src/pal/tests/palsuite/threading/CreateThread/test1/test1.cpp
new file mode 100644
index 0000000000..dda25f1f4b
--- /dev/null
+++ b/src/pal/tests/palsuite/threading/CreateThread/test1/test1.cpp
@@ -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.
+
+/*============================================================
+**
+** Source: test1.c
+**
+** Purpose: Test for CreateThread. Call CreateThread and ensure
+** that it succeeds. Also check to ensure the paramater is passed
+** properly.
+**
+**
+**=========================================================*/
+
+#include <palsuite.h>
+
+#ifndef PLATFORM_UNIX
+#define LLFORMAT "%I64u"
+#else
+#define LLFORMAT "%llu"
+#endif
+
+ULONGLONG dwCreateThreadTestParameter = 0;
+
+DWORD PALAPI CreateThreadTestThread( LPVOID lpParameter)
+{
+ DWORD dwRet = 0;
+
+ /* save parameter for test */
+ dwCreateThreadTestParameter = (ULONGLONG)lpParameter;
+
+ return dwRet;
+}
+
+BOOL CreateThreadTest()
+{
+ BOOL bRet = FALSE;
+ DWORD dwRet = 0;
+
+ LPSECURITY_ATTRIBUTES lpThreadAttributes = NULL;
+ DWORD dwStackSize = 0;
+ LPTHREAD_START_ROUTINE lpStartAddress = &CreateThreadTestThread;
+ LPVOID lpParameter = (LPVOID)lpStartAddress;
+ DWORD dwCreationFlags = 0; /* run immediately */
+ DWORD dwThreadId = 0;
+
+ HANDLE hThread = 0;
+
+ dwCreateThreadTestParameter = 0;
+
+ /* Create a thread, passing the appropriate paramaters as declared
+ above.
+ */
+
+ hThread = CreateThread( lpThreadAttributes,
+ dwStackSize,
+ lpStartAddress,
+ lpParameter,
+ dwCreationFlags,
+ &dwThreadId );
+
+ /* Ensure that the HANDLE is not invalid! */
+ if (hThread != INVALID_HANDLE_VALUE)
+ {
+ dwRet = WaitForSingleObject(hThread,INFINITE);
+
+ if (dwRet != WAIT_OBJECT_0)
+ {
+ Trace("CreateThreadTest:WaitForSingleObject "
+ "failed (%x)\n",GetLastError());
+ }
+ else
+ {
+ /* Check to ensure that the parameter passed to the thread
+ function is the same in the function as what we passed.
+ */
+
+ if (dwCreateThreadTestParameter != (ULONGLONG)lpParameter)
+ {
+ Trace("CreateThreadTest:parameter error. The "
+ "parameter passed should have been " LLFORMAT " but when "
+ "passed to the Thread function it was " LLFORMAT " . GetLastError[%x]\n",
+ dwCreateThreadTestParameter,lpParameter, GetLastError());
+ }
+ else
+ {
+ bRet = TRUE;
+ }
+
+ }
+ CloseHandle(hThread);
+ }
+ else
+ {
+ Trace("CreateThreadTest:CreateThread failed (%x)\n",GetLastError());
+ }
+
+ return bRet;
+}
+
+
+int __cdecl main(int argc, char **argv)
+{
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return ( FAIL );
+ }
+
+ if(!CreateThreadTest())
+ {
+ Fail ("Test failed\n");
+ }
+
+ Trace("Test Passed\n");
+ PAL_Terminate();
+ return ( PASS );
+
+}
diff --git a/src/pal/tests/palsuite/threading/CreateThread/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateThread/test2/CMakeLists.txt
index 350cf66e9b..47877607b9 100644
--- a/src/pal/tests/palsuite/threading/CreateThread/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CreateThread/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_createthread_test2
diff --git a/src/pal/tests/palsuite/threading/CreateThread/test2/test2.c b/src/pal/tests/palsuite/threading/CreateThread/test2/test2.c
deleted file mode 100644
index f64c32ea87..0000000000
--- a/src/pal/tests/palsuite/threading/CreateThread/test2/test2.c
+++ /dev/null
@@ -1,184 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: test2.c
-**
-** Purpose: Test that lpThreadId is assigned the correct
-** threadId value and that lpThreadId can be NULL.
-**
-**
-**=========================================================*/
-
-#include <palsuite.h>
-
-#define NUM_TESTS 3
-
-HANDLE hThread[NUM_TESTS];
-DWORD dwThreadId[NUM_TESTS];
-volatile BOOL bResult[NUM_TESTS];
-volatile DWORD dwThreadId1[NUM_TESTS];
-
-DWORD PALAPI Thread( LPVOID lpParameter)
-{
- dwThreadId1[(DWORD) lpParameter] = GetCurrentThreadId();
- bResult[(DWORD) lpParameter] = TRUE;
- return (DWORD) lpParameter;
-}
-
-struct testCase
-{
- LPSECURITY_ATTRIBUTES lpThreadAttributes;
- DWORD dwStackSize;
- LPTHREAD_START_ROUTINE lpStartAddress;
- DWORD dwCreationFlags;
- LPVOID lpThreadId;
-};
-
-struct testCase testCases[]=
-{
- {NULL, 0, &Thread, 0, NULL},
- {NULL, 0, &Thread, CREATE_SUSPENDED, NULL},
- {NULL, 0, &Thread, 0, (LPVOID) 1}
-};
-
-/*
- * close handles
- */
-BOOL cleanup(int index)
-{
- int i;
- BOOL bRet = TRUE;
-
- for (i = 0; i < index; i++)
- {
- if (!CloseHandle(hThread[i]))
- {
- bRet = FALSE;
- Trace("PALSUITE ERROR: CloseHandle(%p) call failed for index %d\n",
- hThread[i], i);
- }
- }
-
- return(bRet);
-}
-
-int __cdecl main(int argc, char **argv)
-{
- SIZE_T i;
- DWORD dwRetWFSO;
- DWORD dwRetRT;
- BOOL bRet = TRUE;
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return (FAIL);
- }
-
- /* set results array to FALSE */
- for (i = 0; i < NUM_TESTS; i++)
- {
- bResult[i]=FALSE;
- dwThreadId[i]=0;
- }
-
- for (i = 0; i < NUM_TESTS; i++)
- {
- if (NULL != testCases[i].lpThreadId)
- {
- testCases[i].lpThreadId = &dwThreadId[i];
- }
- /* pass the index as the thread argument */
- hThread[i] = CreateThread( testCases[i].lpThreadAttributes,
- testCases[i].dwStackSize,
- testCases[i].lpStartAddress,
- (LPVOID) i,
- testCases[i].dwCreationFlags,
- testCases[i].lpThreadId);
- if (hThread[i] == NULL)
- {
- Trace("PALSUITE ERROR: CreateThread('%p' '%d' '%p' '%p' '%d' "
- "'%p') call failed.\nGetLastError returned '%u'.\n",
- testCases[i].lpThreadAttributes, testCases[i].dwStackSize,
- testCases[i].lpStartAddress, (LPVOID) i,
- testCases[i].dwCreationFlags,
- testCases[i].lpThreadId, GetLastError());
- cleanup(i - 1);
- Fail("");
- }
-
- /* Resume suspended threads */
- if (testCases[i].dwCreationFlags == CREATE_SUSPENDED)
- {
- dwRetRT = ResumeThread (hThread[i]);
- if (dwRetRT != 1)
- {
- Trace ("PALSUITE ERROR: ResumeThread(%p) "
- "call returned %d it should have returned %d.\n"
- "GetLastError returned %u.\n", hThread[i], dwRetRT,
- 1, GetLastError());
- cleanup(i);
- Fail("");
- }
- }
- }
-
- /* cleanup */
- for (i = 0; i < NUM_TESTS; i++)
- {
- dwRetWFSO = WaitForSingleObject(hThread[i], 10000);
- if (dwRetWFSO != WAIT_OBJECT_0)
- {
- Trace ("PALSUITE ERROR: WaitForSingleObject('%p' '%d') "
- "call returned %d instead of WAIT_OBJECT_0 ('%d').\n"
- "GetLastError returned %u.\n", hThread[i], 10000,
- dwRetWFSO, WAIT_OBJECT_0, GetLastError());
- cleanup(i);
- Fail("");
- }
- }
- if(!cleanup(NUM_TESTS))
- {
- Fail("");
- }
-
- for (i = 0; i < NUM_TESTS; i++)
- {
- /*
- * check to see that all threads were created and were passed
- * the array index as an argument.
- */
- if (FALSE == bResult[i])
- {
- bRet = FALSE;
- Trace("PALSUITE ERROR: result[%d]=%d. It should be %d\n", i,
- FALSE, TRUE);
- }
- /*
- * check to see that lpThreadId received the correct value.
- */
- if (0 != dwThreadId[i])
- {
- if (dwThreadId[i] != dwThreadId1[i])
- {
- bRet = FALSE;
- Trace("PALSUITE ERROR: dwThreadId[%d]=%p and dwThreadId1[%d]"
- "=%p\nThese values should be identical.\n", i,
- dwThreadId[i], i, dwThreadId1[i]);
- }
- }
- }
- if (!bRet)
- {
- cleanup(NUM_TESTS);
- Fail("");
- }
-
- PAL_Terminate();
- return (PASS);
-}
-
-
-
diff --git a/src/pal/tests/palsuite/threading/CreateThread/test2/test2.cpp b/src/pal/tests/palsuite/threading/CreateThread/test2/test2.cpp
new file mode 100644
index 0000000000..1ee410a6c5
--- /dev/null
+++ b/src/pal/tests/palsuite/threading/CreateThread/test2/test2.cpp
@@ -0,0 +1,184 @@
+// Licensed to the .NET Foundation under one or more 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: test2.c
+**
+** Purpose: Test that lpThreadId is assigned the correct
+** threadId value and that lpThreadId can be NULL.
+**
+**
+**=========================================================*/
+
+#include <palsuite.h>
+
+#define NUM_TESTS 3
+
+HANDLE hThread[NUM_TESTS];
+DWORD dwThreadId[NUM_TESTS];
+volatile BOOL bResult[NUM_TESTS];
+volatile DWORD dwThreadId1[NUM_TESTS];
+
+DWORD PALAPI Thread( LPVOID lpParameter)
+{
+ dwThreadId1[(DWORD) lpParameter] = GetCurrentThreadId();
+ bResult[(DWORD) lpParameter] = TRUE;
+ return (DWORD) lpParameter;
+}
+
+struct testCase
+{
+ LPSECURITY_ATTRIBUTES lpThreadAttributes;
+ DWORD dwStackSize;
+ LPTHREAD_START_ROUTINE lpStartAddress;
+ DWORD dwCreationFlags;
+ LPDWORD lpThreadId;
+};
+
+struct testCase testCases[]=
+{
+ {NULL, 0, &Thread, 0, NULL},
+ {NULL, 0, &Thread, CREATE_SUSPENDED, NULL},
+ {NULL, 0, &Thread, 0, (LPDWORD) 1}
+};
+
+/*
+ * close handles
+ */
+BOOL cleanup(int index)
+{
+ int i;
+ BOOL bRet = TRUE;
+
+ for (i = 0; i < index; i++)
+ {
+ if (!CloseHandle(hThread[i]))
+ {
+ bRet = FALSE;
+ Trace("PALSUITE ERROR: CloseHandle(%p) call failed for index %d\n",
+ hThread[i], i);
+ }
+ }
+
+ return(bRet);
+}
+
+int __cdecl main(int argc, char **argv)
+{
+ SIZE_T i;
+ DWORD dwRetWFSO;
+ DWORD dwRetRT;
+ BOOL bRet = TRUE;
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return (FAIL);
+ }
+
+ /* set results array to FALSE */
+ for (i = 0; i < NUM_TESTS; i++)
+ {
+ bResult[i]=FALSE;
+ dwThreadId[i]=0;
+ }
+
+ for (i = 0; i < NUM_TESTS; i++)
+ {
+ if (NULL != testCases[i].lpThreadId)
+ {
+ testCases[i].lpThreadId = &dwThreadId[i];
+ }
+ /* pass the index as the thread argument */
+ hThread[i] = CreateThread( testCases[i].lpThreadAttributes,
+ testCases[i].dwStackSize,
+ testCases[i].lpStartAddress,
+ (LPVOID)i,
+ testCases[i].dwCreationFlags,
+ testCases[i].lpThreadId);
+ if (hThread[i] == NULL)
+ {
+ Trace("PALSUITE ERROR: CreateThread('%p' '%d' '%p' '%p' '%d' "
+ "'%p') call failed.\nGetLastError returned '%u'.\n",
+ testCases[i].lpThreadAttributes, testCases[i].dwStackSize,
+ testCases[i].lpStartAddress, (LPVOID)i,
+ testCases[i].dwCreationFlags,
+ testCases[i].lpThreadId, GetLastError());
+ cleanup(i - 1);
+ Fail("");
+ }
+
+ /* Resume suspended threads */
+ if (testCases[i].dwCreationFlags == CREATE_SUSPENDED)
+ {
+ dwRetRT = ResumeThread (hThread[i]);
+ if (dwRetRT != 1)
+ {
+ Trace ("PALSUITE ERROR: ResumeThread(%p) "
+ "call returned %d it should have returned %d.\n"
+ "GetLastError returned %u.\n", hThread[i], dwRetRT,
+ 1, GetLastError());
+ cleanup(i);
+ Fail("");
+ }
+ }
+ }
+
+ /* cleanup */
+ for (i = 0; i < NUM_TESTS; i++)
+ {
+ dwRetWFSO = WaitForSingleObject(hThread[i], 10000);
+ if (dwRetWFSO != WAIT_OBJECT_0)
+ {
+ Trace ("PALSUITE ERROR: WaitForSingleObject('%p' '%d') "
+ "call returned %d instead of WAIT_OBJECT_0 ('%d').\n"
+ "GetLastError returned %u.\n", hThread[i], 10000,
+ dwRetWFSO, WAIT_OBJECT_0, GetLastError());
+ cleanup(i);
+ Fail("");
+ }
+ }
+ if(!cleanup(NUM_TESTS))
+ {
+ Fail("");
+ }
+
+ for (i = 0; i < NUM_TESTS; i++)
+ {
+ /*
+ * check to see that all threads were created and were passed
+ * the array index as an argument.
+ */
+ if (FALSE == bResult[i])
+ {
+ bRet = FALSE;
+ Trace("PALSUITE ERROR: result[%d]=%d. It should be %d\n", i,
+ FALSE, TRUE);
+ }
+ /*
+ * check to see that lpThreadId received the correct value.
+ */
+ if (0 != dwThreadId[i])
+ {
+ if (dwThreadId[i] != dwThreadId1[i])
+ {
+ bRet = FALSE;
+ Trace("PALSUITE ERROR: dwThreadId[%d]=%p and dwThreadId1[%d]"
+ "=%p\nThese values should be identical.\n", i,
+ dwThreadId[i], i, dwThreadId1[i]);
+ }
+ }
+ }
+ if (!bRet)
+ {
+ cleanup(NUM_TESTS);
+ Fail("");
+ }
+
+ PAL_Terminate();
+ return (PASS);
+}
+
+
+
diff --git a/src/pal/tests/palsuite/threading/CreateThread/test3/CMakeLists.txt b/src/pal/tests/palsuite/threading/CreateThread/test3/CMakeLists.txt
index 923d7a72ab..d454992e59 100644
--- a/src/pal/tests/palsuite/threading/CreateThread/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CreateThread/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_createthread_test3
diff --git a/src/pal/tests/palsuite/threading/CreateThread/test3/test3.c b/src/pal/tests/palsuite/threading/CreateThread/test3/test3.cpp
index 0c44d1fdd0..0c44d1fdd0 100644
--- a/src/pal/tests/palsuite/threading/CreateThread/test3/test3.c
+++ b/src/pal/tests/palsuite/threading/CreateThread/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test1/CMakeLists.txt
index 5ba04fd801..8d2c1441c4 100644
--- a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- InitializeCriticalSection.c
+ InitializeCriticalSection.cpp
)
add_executable(paltest_criticalsectionfunctions_test1
diff --git a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test1/InitializeCriticalSection.c b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test1/InitializeCriticalSection.cpp
index f294cea472..f294cea472 100644
--- a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test1/InitializeCriticalSection.c
+++ b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test1/InitializeCriticalSection.cpp
diff --git a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test2/CMakeLists.txt
index d26658cf5d..e0f59f4207 100644
--- a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_criticalsectionfunctions_test2
diff --git a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test2/test2.c b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test2/test2.cpp
index 47659a1c18..47659a1c18 100644
--- a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test2/test2.c
+++ b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test3/CMakeLists.txt b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test3/CMakeLists.txt
index 8bd2a72878..11555ec484 100644
--- a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_criticalsectionfunctions_test3
diff --git a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test3/test3.c b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test3/test3.cpp
index d5911267b2..d5911267b2 100644
--- a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test3/test3.c
+++ b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test4/CMakeLists.txt b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test4/CMakeLists.txt
index 0626631640..8aa18854b3 100644
--- a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_criticalsectionfunctions_test4
diff --git a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test4/test4.c b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test4/test4.cpp
index 8a245a4776..8a245a4776 100644
--- a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test4/test4.c
+++ b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test5/CMakeLists.txt b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test5/CMakeLists.txt
index 37d709f121..9474bcc6c9 100644
--- a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_criticalsectionfunctions_test5
diff --git a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test5/test5.c b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test5/test5.cpp
index 8dfa4f5f3d..8dfa4f5f3d 100644
--- a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test5/test5.c
+++ b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test5/test5.cpp
diff --git a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test6/CMakeLists.txt b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test6/CMakeLists.txt
index c580fdbd6b..f4887ad67d 100644
--- a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test6.c
+ test6.cpp
)
add_executable(paltest_criticalsectionfunctions_test6
diff --git a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test6/test6.c b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test6/test6.cpp
index c27db86e5b..c27db86e5b 100644
--- a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test6/test6.c
+++ b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test6/test6.cpp
diff --git a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test7/CMakeLists.txt b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test7/CMakeLists.txt
index 0a12bfe3ef..ceb78a0512 100644
--- a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test7/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test7/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test7.c
+ test7.cpp
)
add_executable(paltest_criticalsectionfunctions_test7
diff --git a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test7/test7.c b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test7/test7.cpp
index 1c030d3c03..1c030d3c03 100644
--- a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test7/test7.c
+++ b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test7/test7.cpp
diff --git a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test8/CMakeLists.txt b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test8/CMakeLists.txt
index 0d95a95410..d3f271d677 100644
--- a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test8/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test8/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test8.c
+ test8.cpp
)
add_executable(paltest_criticalsectionfunctions_test8
diff --git a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test8/test8.c b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test8/test8.cpp
index 7f0c58cd26..7f0c58cd26 100644
--- a/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test8/test8.c
+++ b/src/pal/tests/palsuite/threading/CriticalSectionFunctions/test8/test8.cpp
diff --git a/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test1/test1.c b/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test1/test1.cpp
index b64fd0c7d2..b64fd0c7d2 100644
--- a/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test1/test1.c
+++ b/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test1/testlib.c b/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test1/testlib.cpp
index 53b66d1357..53b66d1357 100644
--- a/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test1/testlib.c
+++ b/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test1/testlib.cpp
diff --git a/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/dllmain1.c b/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/dllmain1.cpp
index 5010a27665..5010a27665 100644
--- a/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/dllmain1.c
+++ b/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/dllmain1.cpp
diff --git a/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/dllmain2.c b/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/dllmain2.cpp
index 4e3f8862a4..4e3f8862a4 100644
--- a/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/dllmain2.c
+++ b/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/dllmain2.cpp
diff --git a/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/test2.c b/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/test2.cpp
index 5fb694ea14..5fb694ea14 100644
--- a/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/test2.c
+++ b/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/CMakeLists.txt b/src/pal/tests/palsuite/threading/DuplicateHandle/CMakeLists.txt
index b908c1246b..9d5fc53a2d 100644
--- a/src/pal/tests/palsuite/threading/DuplicateHandle/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/DuplicateHandle/CMakeLists.txt
@@ -11,5 +11,4 @@ add_subdirectory(test5)
add_subdirectory(test6)
add_subdirectory(test7)
add_subdirectory(test8)
-add_subdirectory(test9)
diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/DuplicateHandle/test1/CMakeLists.txt
index 04588b75fe..18b1927a4e 100644
--- a/src/pal/tests/palsuite/threading/DuplicateHandle/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_duplicatehandle_test1
diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test1/test1.c b/src/pal/tests/palsuite/threading/DuplicateHandle/test1/test1.cpp
index e080e98ae8..e080e98ae8 100644
--- a/src/pal/tests/palsuite/threading/DuplicateHandle/test1/test1.c
+++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test10/CMakeLists.txt b/src/pal/tests/palsuite/threading/DuplicateHandle/test10/CMakeLists.txt
index ba16252cb4..98c7a273dc 100644
--- a/src/pal/tests/palsuite/threading/DuplicateHandle/test10/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test10/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test10.c
+ test10.cpp
)
add_executable(paltest_duplicatehandle_test10
diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test10/test10.c b/src/pal/tests/palsuite/threading/DuplicateHandle/test10/test10.cpp
index 108d748de6..108d748de6 100644
--- a/src/pal/tests/palsuite/threading/DuplicateHandle/test10/test10.c
+++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test10/test10.cpp
diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test11/CMakeLists.txt b/src/pal/tests/palsuite/threading/DuplicateHandle/test11/CMakeLists.txt
index 68ce7b23fb..f47f9bc350 100644
--- a/src/pal/tests/palsuite/threading/DuplicateHandle/test11/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test11/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(TESTSOURCES
- test11.c
+ test11.cpp
)
add_executable(paltest_duplicatehandle_test11
@@ -20,7 +20,7 @@ target_link_libraries(paltest_duplicatehandle_test11
set(HELPERSOURCES
- childprocess.c
+ childprocess.cpp
)
add_executable(paltest_duplicatehandle_test11_child
diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test11/childprocess.c b/src/pal/tests/palsuite/threading/DuplicateHandle/test11/childprocess.cpp
index d5b310e46c..d5b310e46c 100644
--- a/src/pal/tests/palsuite/threading/DuplicateHandle/test11/childprocess.c
+++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test11/childprocess.cpp
diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test11/test11.c b/src/pal/tests/palsuite/threading/DuplicateHandle/test11/test11.cpp
index b05244c4b8..b05244c4b8 100644
--- a/src/pal/tests/palsuite/threading/DuplicateHandle/test11/test11.c
+++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test11/test11.cpp
diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test12/CMakeLists.txt b/src/pal/tests/palsuite/threading/DuplicateHandle/test12/CMakeLists.txt
index 961a9c64e6..6a50a13265 100644
--- a/src/pal/tests/palsuite/threading/DuplicateHandle/test12/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test12/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test12.c
+ test12.cpp
)
add_executable(paltest_duplicatehandle_test12
diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test12/test12.c b/src/pal/tests/palsuite/threading/DuplicateHandle/test12/test12.cpp
index 519194bc3a..519194bc3a 100644
--- a/src/pal/tests/palsuite/threading/DuplicateHandle/test12/test12.c
+++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test12/test12.cpp
diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/DuplicateHandle/test2/CMakeLists.txt
index 06529a6204..9faa58a271 100644
--- a/src/pal/tests/palsuite/threading/DuplicateHandle/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_duplicatehandle_test2
diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test2/test2.c b/src/pal/tests/palsuite/threading/DuplicateHandle/test2/test2.cpp
index d1411e62d9..d1411e62d9 100644
--- a/src/pal/tests/palsuite/threading/DuplicateHandle/test2/test2.c
+++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test3/CMakeLists.txt b/src/pal/tests/palsuite/threading/DuplicateHandle/test3/CMakeLists.txt
index 7f961c2213..b161b928d3 100644
--- a/src/pal/tests/palsuite/threading/DuplicateHandle/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_duplicatehandle_test3
diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test3/test3.c b/src/pal/tests/palsuite/threading/DuplicateHandle/test3/test3.cpp
index fc91b5ec22..fc91b5ec22 100644
--- a/src/pal/tests/palsuite/threading/DuplicateHandle/test3/test3.c
+++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test4/CMakeLists.txt b/src/pal/tests/palsuite/threading/DuplicateHandle/test4/CMakeLists.txt
index c3040d09ec..901151f4eb 100644
--- a/src/pal/tests/palsuite/threading/DuplicateHandle/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_duplicatehandle_test4
diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test4/test4.c b/src/pal/tests/palsuite/threading/DuplicateHandle/test4/test4.cpp
index 14a72db461..14a72db461 100644
--- a/src/pal/tests/palsuite/threading/DuplicateHandle/test4/test4.c
+++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test5/CMakeLists.txt b/src/pal/tests/palsuite/threading/DuplicateHandle/test5/CMakeLists.txt
index bc468a4a75..94cd07f96f 100644
--- a/src/pal/tests/palsuite/threading/DuplicateHandle/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_duplicatehandle_test5
diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test5/test5.c b/src/pal/tests/palsuite/threading/DuplicateHandle/test5/test5.cpp
index a588928f00..a588928f00 100644
--- a/src/pal/tests/palsuite/threading/DuplicateHandle/test5/test5.c
+++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test5/test5.cpp
diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test6/CMakeLists.txt b/src/pal/tests/palsuite/threading/DuplicateHandle/test6/CMakeLists.txt
index 20f7822b1e..a0dcae843c 100644
--- a/src/pal/tests/palsuite/threading/DuplicateHandle/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test6.c
+ test6.cpp
)
add_executable(paltest_duplicatehandle_test6
diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test6/test6.c b/src/pal/tests/palsuite/threading/DuplicateHandle/test6/test6.cpp
index 026f315a44..026f315a44 100644
--- a/src/pal/tests/palsuite/threading/DuplicateHandle/test6/test6.c
+++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test6/test6.cpp
diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test7/CMakeLists.txt b/src/pal/tests/palsuite/threading/DuplicateHandle/test7/CMakeLists.txt
index df3fdf9ae0..a222331fe7 100644
--- a/src/pal/tests/palsuite/threading/DuplicateHandle/test7/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test7/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test7.c
+ test7.cpp
)
add_executable(paltest_duplicatehandle_test7
diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test7/test7.c b/src/pal/tests/palsuite/threading/DuplicateHandle/test7/test7.cpp
index 0477291922..0477291922 100644
--- a/src/pal/tests/palsuite/threading/DuplicateHandle/test7/test7.c
+++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test7/test7.cpp
diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test8/CMakeLists.txt b/src/pal/tests/palsuite/threading/DuplicateHandle/test8/CMakeLists.txt
index 15ec23d272..18ed969cb7 100644
--- a/src/pal/tests/palsuite/threading/DuplicateHandle/test8/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test8/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test8.c
+ test8.cpp
)
add_executable(paltest_duplicatehandle_test8
diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test8/test8.c b/src/pal/tests/palsuite/threading/DuplicateHandle/test8/test8.cpp
index 6748c5dffd..6748c5dffd 100644
--- a/src/pal/tests/palsuite/threading/DuplicateHandle/test8/test8.c
+++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test8/test8.cpp
diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test9/CMakeLists.txt b/src/pal/tests/palsuite/threading/DuplicateHandle/test9/CMakeLists.txt
index e4442e327c..0383a010ac 100644
--- a/src/pal/tests/palsuite/threading/DuplicateHandle/test9/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test9/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test9.c
+ test9.cpp
)
add_executable(paltest_duplicatehandle_test9
diff --git a/src/pal/tests/palsuite/threading/DuplicateHandle/test9/test9.c b/src/pal/tests/palsuite/threading/DuplicateHandle/test9/test9.cpp
index f15871c57d..f15871c57d 100644
--- a/src/pal/tests/palsuite/threading/DuplicateHandle/test9/test9.c
+++ b/src/pal/tests/palsuite/threading/DuplicateHandle/test9/test9.cpp
diff --git a/src/pal/tests/palsuite/threading/ExitProcess/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/ExitProcess/test1/CMakeLists.txt
index decddb8512..f2d28e06ca 100644
--- a/src/pal/tests/palsuite/threading/ExitProcess/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/ExitProcess/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- ExitProcess.c
+ ExitProcess.cpp
)
add_executable(paltest_exitprocess_test1
diff --git a/src/pal/tests/palsuite/threading/ExitProcess/test1/ExitProcess.c b/src/pal/tests/palsuite/threading/ExitProcess/test1/ExitProcess.cpp
index 2b089a0b83..2b089a0b83 100644
--- a/src/pal/tests/palsuite/threading/ExitProcess/test1/ExitProcess.c
+++ b/src/pal/tests/palsuite/threading/ExitProcess/test1/ExitProcess.cpp
diff --git a/src/pal/tests/palsuite/threading/ExitProcess/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/ExitProcess/test2/CMakeLists.txt
index 881c7d0eee..5281a02aa4 100644
--- a/src/pal/tests/palsuite/threading/ExitProcess/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/ExitProcess/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_exitprocess_test2
diff --git a/src/pal/tests/palsuite/threading/ExitProcess/test2/test2.c b/src/pal/tests/palsuite/threading/ExitProcess/test2/test2.cpp
index 8023ad7bab..8023ad7bab 100644
--- a/src/pal/tests/palsuite/threading/ExitProcess/test2/test2.c
+++ b/src/pal/tests/palsuite/threading/ExitProcess/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/threading/ExitProcess/test3/CMakeLists.txt b/src/pal/tests/palsuite/threading/ExitProcess/test3/CMakeLists.txt
index 638408e986..3fca087d05 100644
--- a/src/pal/tests/palsuite/threading/ExitProcess/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/ExitProcess/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_exitprocess_test3
diff --git a/src/pal/tests/palsuite/threading/ExitProcess/test3/test3.c b/src/pal/tests/palsuite/threading/ExitProcess/test3/test3.cpp
index aea485e5e3..aea485e5e3 100644
--- a/src/pal/tests/palsuite/threading/ExitProcess/test3/test3.c
+++ b/src/pal/tests/palsuite/threading/ExitProcess/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/threading/ExitThread/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/ExitThread/test1/CMakeLists.txt
index 15e0c1b62d..c34b5257ab 100644
--- a/src/pal/tests/palsuite/threading/ExitThread/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/ExitThread/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_exitthread_test1
diff --git a/src/pal/tests/palsuite/threading/ExitThread/test1/test1.c b/src/pal/tests/palsuite/threading/ExitThread/test1/test1.c
deleted file mode 100644
index 2963745bef..0000000000
--- a/src/pal/tests/palsuite/threading/ExitThread/test1/test1.c
+++ /dev/null
@@ -1,114 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: test1.c
-**
-** Purpose: Test for ExitThread. Create a thread and then call
-** exit thread within the threading function. Ensure that it exits
-** immediatly.
-**
-**
-**=========================================================*/
-
-#include <palsuite.h>
-
-DWORD dwExitThreadTestParameter = 0;
-
-DWORD PALAPI ExitThreadTestThread( LPVOID lpParameter)
-{
- DWORD dwRet = 0;
-
- /* Save parameter for test */
- dwExitThreadTestParameter = (DWORD)lpParameter;
-
- /* Call the ExitThread function */
- ExitThread(dwRet);
-
- /* If we didn't exit, get caught in this loop. But, the
- program will exit.
- */
- while (!dwRet)
- {
- Fail("ERROR: Entered an infinite loop because ExitThread "
- "failed to exit from the thread. Forcing exit from "
- "the test now.");
- }
-
- return dwRet;
-}
-
-BOOL ExitThreadTest()
-{
- BOOL bRet = FALSE;
- DWORD dwRet = 0;
-
- LPSECURITY_ATTRIBUTES lpThreadAttributes = NULL;
- DWORD dwStackSize = 0;
- LPTHREAD_START_ROUTINE lpStartAddress = &ExitThreadTestThread;
- LPVOID lpParameter = lpStartAddress;
- DWORD dwCreationFlags = 0; //run immediately
- DWORD dwThreadId = 0;
-
- HANDLE hThread = 0;
-
- dwExitThreadTestParameter = 0;
-
- /* Create a Thread. We'll need this to test that we're able
- to exit the thread.
- */
- hThread = CreateThread( lpThreadAttributes,
- dwStackSize, lpStartAddress, lpParameter,
- dwCreationFlags, &dwThreadId );
-
- if (hThread != INVALID_HANDLE_VALUE)
- {
- dwRet = WaitForSingleObject(hThread,INFINITE);
-
- if (dwRet != WAIT_OBJECT_0)
- {
- Trace("ExitThreadTest:WaitForSingleObject failed "
- "(%x)\n",GetLastError());
- }
- else
- {
- /* Check to ensure that the parameter set in the Thread
- function is correct.
- */
- if (dwExitThreadTestParameter != (DWORD)lpParameter)
- {
- Trace("ERROR: The paramater passed should have been "
- "%d but turned up as %d.",
- dwExitThreadTestParameter, lpParameter);
- }
- else
- {
- bRet = TRUE;
- }
- }
- }
- else
- {
- Trace("ExitThreadTest:CreateThread failed (%x)\n",GetLastError());
- }
-
- return bRet;
-}
-
-int __cdecl main(int argc, char **argv)
-{
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return ( FAIL );
- }
-
- if(!ExitThreadTest())
- {
- Fail ("Test failed\n");
- }
-
- PAL_Terminate();
- return ( PASS );
-}
diff --git a/src/pal/tests/palsuite/threading/ExitThread/test1/test1.cpp b/src/pal/tests/palsuite/threading/ExitThread/test1/test1.cpp
new file mode 100644
index 0000000000..caf1409406
--- /dev/null
+++ b/src/pal/tests/palsuite/threading/ExitThread/test1/test1.cpp
@@ -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.
+
+/*============================================================
+**
+** Source: test1.c
+**
+** Purpose: Test for ExitThread. Create a thread and then call
+** exit thread within the threading function. Ensure that it exits
+** immediatly.
+**
+**
+**=========================================================*/
+
+#include <palsuite.h>
+
+DWORD dwExitThreadTestParameter = 0;
+
+DWORD PALAPI ExitThreadTestThread( LPVOID lpParameter)
+{
+ DWORD dwRet = 0;
+
+ /* Save parameter for test */
+ dwExitThreadTestParameter = (DWORD)lpParameter;
+
+ /* Call the ExitThread function */
+ ExitThread(dwRet);
+
+ /* If we didn't exit, get caught in this loop. But, the
+ program will exit.
+ */
+ while (!dwRet)
+ {
+ Fail("ERROR: Entered an infinite loop because ExitThread "
+ "failed to exit from the thread. Forcing exit from "
+ "the test now.");
+ }
+
+ return dwRet;
+}
+
+BOOL ExitThreadTest()
+{
+ BOOL bRet = FALSE;
+ DWORD dwRet = 0;
+
+ LPSECURITY_ATTRIBUTES lpThreadAttributes = NULL;
+ DWORD dwStackSize = 0;
+ LPTHREAD_START_ROUTINE lpStartAddress = &ExitThreadTestThread;
+ LPVOID lpParameter = (LPVOID)lpStartAddress;
+ DWORD dwCreationFlags = 0; //run immediately
+ DWORD dwThreadId = 0;
+
+ HANDLE hThread = 0;
+
+ dwExitThreadTestParameter = 0;
+
+ /* Create a Thread. We'll need this to test that we're able
+ to exit the thread.
+ */
+ hThread = CreateThread( lpThreadAttributes,
+ dwStackSize, lpStartAddress, lpParameter,
+ dwCreationFlags, &dwThreadId );
+
+ if (hThread != INVALID_HANDLE_VALUE)
+ {
+ dwRet = WaitForSingleObject(hThread,INFINITE);
+
+ if (dwRet != WAIT_OBJECT_0)
+ {
+ Trace("ExitThreadTest:WaitForSingleObject failed "
+ "(%x)\n",GetLastError());
+ }
+ else
+ {
+ /* Check to ensure that the parameter set in the Thread
+ function is correct.
+ */
+ if (dwExitThreadTestParameter != (DWORD)lpParameter)
+ {
+ Trace("ERROR: The paramater passed should have been "
+ "%d but turned up as %d.",
+ dwExitThreadTestParameter, lpParameter);
+ }
+ else
+ {
+ bRet = TRUE;
+ }
+ }
+ }
+ else
+ {
+ Trace("ExitThreadTest:CreateThread failed (%x)\n",GetLastError());
+ }
+
+ return bRet;
+}
+
+int __cdecl main(int argc, char **argv)
+{
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return ( FAIL );
+ }
+
+ if(!ExitThreadTest())
+ {
+ Fail ("Test failed\n");
+ }
+
+ PAL_Terminate();
+ return ( PASS );
+}
diff --git a/src/pal/tests/palsuite/threading/ExitThread/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/ExitThread/test2/CMakeLists.txt
index aa05382feb..5e16d36082 100644
--- a/src/pal/tests/palsuite/threading/ExitThread/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/ExitThread/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(TESTSOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_exitthread_test2
@@ -20,7 +20,7 @@ target_link_libraries(paltest_exitthread_test2
set(HELPERSOURCES
- childprocess.c
+ childprocess.cpp
)
add_executable(paltest_exitthread_test2_child
diff --git a/src/pal/tests/palsuite/threading/ExitThread/test2/childprocess.c b/src/pal/tests/palsuite/threading/ExitThread/test2/childprocess.cpp
index 7fbe208f91..7fbe208f91 100644
--- a/src/pal/tests/palsuite/threading/ExitThread/test2/childprocess.c
+++ b/src/pal/tests/palsuite/threading/ExitThread/test2/childprocess.cpp
diff --git a/src/pal/tests/palsuite/threading/ExitThread/test2/test2.c b/src/pal/tests/palsuite/threading/ExitThread/test2/test2.cpp
index c31af8a079..c31af8a079 100644
--- a/src/pal/tests/palsuite/threading/ExitThread/test2/test2.c
+++ b/src/pal/tests/palsuite/threading/ExitThread/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/threading/ExitThread/test3/dllmain.c b/src/pal/tests/palsuite/threading/ExitThread/test3/dllmain.cpp
index 923650d1d3..923650d1d3 100644
--- a/src/pal/tests/palsuite/threading/ExitThread/test3/dllmain.c
+++ b/src/pal/tests/palsuite/threading/ExitThread/test3/dllmain.cpp
diff --git a/src/pal/tests/palsuite/threading/ExitThread/test3/test3.c b/src/pal/tests/palsuite/threading/ExitThread/test3/test3.cpp
index 8a71c7cc99..8a71c7cc99 100644
--- a/src/pal/tests/palsuite/threading/ExitThread/test3/test3.c
+++ b/src/pal/tests/palsuite/threading/ExitThread/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/threading/GetCurrentProcess/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/GetCurrentProcess/test1/CMakeLists.txt
index 44105348be..af4746bcb4 100644
--- a/src/pal/tests/palsuite/threading/GetCurrentProcess/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/GetCurrentProcess/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- process.c
+ process.cpp
)
add_executable(paltest_getcurrentprocess_test1
diff --git a/src/pal/tests/palsuite/threading/GetCurrentProcess/test1/process.c b/src/pal/tests/palsuite/threading/GetCurrentProcess/test1/process.cpp
index 17d9af6282..17d9af6282 100644
--- a/src/pal/tests/palsuite/threading/GetCurrentProcess/test1/process.c
+++ b/src/pal/tests/palsuite/threading/GetCurrentProcess/test1/process.cpp
diff --git a/src/pal/tests/palsuite/threading/GetCurrentProcessId/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/GetCurrentProcessId/test1/CMakeLists.txt
index e5c31e6af2..523320a53c 100644
--- a/src/pal/tests/palsuite/threading/GetCurrentProcessId/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/GetCurrentProcessId/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- processId.c
+ processId.cpp
)
add_executable(paltest_getcurrentprocessid_test1
diff --git a/src/pal/tests/palsuite/threading/GetCurrentProcessId/test1/processId.c b/src/pal/tests/palsuite/threading/GetCurrentProcessId/test1/processId.cpp
index cc689b3f8b..cc689b3f8b 100644
--- a/src/pal/tests/palsuite/threading/GetCurrentProcessId/test1/processId.c
+++ b/src/pal/tests/palsuite/threading/GetCurrentProcessId/test1/processId.cpp
diff --git a/src/pal/tests/palsuite/threading/GetCurrentThread/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/GetCurrentThread/test1/CMakeLists.txt
index 84cbccbca0..23af2edbca 100644
--- a/src/pal/tests/palsuite/threading/GetCurrentThread/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/GetCurrentThread/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- thread.c
+ thread.cpp
)
add_executable(paltest_getcurrentthread_test1
diff --git a/src/pal/tests/palsuite/threading/GetCurrentThread/test1/thread.c b/src/pal/tests/palsuite/threading/GetCurrentThread/test1/thread.cpp
index b2bb97fd67..b2bb97fd67 100644
--- a/src/pal/tests/palsuite/threading/GetCurrentThread/test1/thread.c
+++ b/src/pal/tests/palsuite/threading/GetCurrentThread/test1/thread.cpp
diff --git a/src/pal/tests/palsuite/threading/GetCurrentThread/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/GetCurrentThread/test2/CMakeLists.txt
index 3fc3c3e7c6..9da2d075b2 100644
--- a/src/pal/tests/palsuite/threading/GetCurrentThread/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/GetCurrentThread/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_getcurrentthread_test2
diff --git a/src/pal/tests/palsuite/threading/GetCurrentThread/test2/test2.c b/src/pal/tests/palsuite/threading/GetCurrentThread/test2/test2.cpp
index beeb5ec241..beeb5ec241 100644
--- a/src/pal/tests/palsuite/threading/GetCurrentThread/test2/test2.c
+++ b/src/pal/tests/palsuite/threading/GetCurrentThread/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/threading/GetCurrentThreadId/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/GetCurrentThreadId/test1/CMakeLists.txt
index 490bff8f5f..a0824ab9a2 100644
--- a/src/pal/tests/palsuite/threading/GetCurrentThreadId/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/GetCurrentThreadId/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- threadId.c
+ threadId.cpp
)
add_executable(paltest_getcurrentthreadid_test1
diff --git a/src/pal/tests/palsuite/threading/GetCurrentThreadId/test1/threadId.c b/src/pal/tests/palsuite/threading/GetCurrentThreadId/test1/threadId.cpp
index acbb1ff373..acbb1ff373 100644
--- a/src/pal/tests/palsuite/threading/GetCurrentThreadId/test1/threadId.c
+++ b/src/pal/tests/palsuite/threading/GetCurrentThreadId/test1/threadId.cpp
diff --git a/src/pal/tests/palsuite/threading/GetExitCodeProcess/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/GetExitCodeProcess/test1/CMakeLists.txt
index adddd97e6d..1ef9db2299 100644
--- a/src/pal/tests/palsuite/threading/GetExitCodeProcess/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/GetExitCodeProcess/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(TESTSOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_getexitcodeprocess_test1
@@ -20,7 +20,7 @@ target_link_libraries(paltest_getexitcodeprocess_test1
set(HELPERSOURCES
- childProcess.c
+ childProcess.cpp
)
add_executable(paltest_getexitcodeprocess_test1_child
diff --git a/src/pal/tests/palsuite/threading/GetExitCodeProcess/test1/childProcess.c b/src/pal/tests/palsuite/threading/GetExitCodeProcess/test1/childProcess.cpp
index fe1b38fb31..fe1b38fb31 100644
--- a/src/pal/tests/palsuite/threading/GetExitCodeProcess/test1/childProcess.c
+++ b/src/pal/tests/palsuite/threading/GetExitCodeProcess/test1/childProcess.cpp
diff --git a/src/pal/tests/palsuite/threading/GetExitCodeProcess/test1/test1.c b/src/pal/tests/palsuite/threading/GetExitCodeProcess/test1/test1.cpp
index 0f98cf8f57..0f98cf8f57 100644
--- a/src/pal/tests/palsuite/threading/GetExitCodeProcess/test1/test1.c
+++ b/src/pal/tests/palsuite/threading/GetExitCodeProcess/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/threading/GetProcessTimes/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/GetProcessTimes/test2/CMakeLists.txt
index 0ef7260204..8e905873e9 100644
--- a/src/pal/tests/palsuite/threading/GetProcessTimes/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/GetProcessTimes/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_getprocesstimes_test2
diff --git a/src/pal/tests/palsuite/threading/GetProcessTimes/test2/test2.c b/src/pal/tests/palsuite/threading/GetProcessTimes/test2/test2.c
deleted file mode 100644
index 687facc584..0000000000
--- a/src/pal/tests/palsuite/threading/GetProcessTimes/test2/test2.c
+++ /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.
-
-/*=============================================================================
-**
-** Source: test2.c
-**
-** Purpose: Test to ensure GetProcessTimes works properly.
-**
-** Dependencies: PAL_Initialize
-** PAL_Terminate
-** Fail
-** ZeroMemory
-** CompareFileTime
-** GetLastError
-**
-
-**
-**===========================================================================*/
-#include <palsuite.h>
-
-
-int __cdecl main( int argc, char **argv )
-
-{
- int i, j, k;
- int *total;
-
- HANDLE hProcess;
- FILETIME createTime;
- FILETIME exitTime;
- FILETIME kernelTime1;
- FILETIME userTime1;
- FILETIME kernelTime2;
- FILETIME userTime2;
-
- DWORD dwError;
-
- /* initialize the PAL */
- if( PAL_Initialize(argc, argv) != 0 )
- {
- return( FAIL );
- }
-
- /* get our own process handle */
- hProcess = GetCurrentProcess();
- if( hProcess == NULL )
- {
- Fail( "GetCurrentProcess() returned a NULL handle.\n" );
- }
-
- /* zero our time structures */
- ZeroMemory( &createTime, sizeof(createTime) );
- ZeroMemory( &exitTime, sizeof(exitTime) );
- ZeroMemory( &kernelTime1, sizeof(kernelTime1) );
- ZeroMemory( &userTime1, sizeof(userTime1) );
- ZeroMemory( &kernelTime2, sizeof(kernelTime2) );
- ZeroMemory( &userTime2, sizeof(userTime2) );
-
- /* check the process times for the child process */
- if( ! GetProcessTimes( hProcess,
- &createTime,
- &exitTime,
- &kernelTime1,
- &userTime1 ) )
- {
- dwError = GetLastError();
- Fail( "GetProcessTimes() call failed with error code %d\n",
- dwError );
- }
-
-
- /* simulate some activity */
- for( i=0; i<1000; i++ )
- {
- for( j=0; j<1000; j++ )
- {
- /* do kernel work to increase system usage counters */
- total = malloc(1024 * 1024);
-
- *total = j * i;
- for( k=0; k<1000; k++ )
- {
- *total += k + i;
- }
-
- free(total);
- }
- }
-
- /* check the process times for the child process */
- if( ! GetProcessTimes( hProcess,
- &createTime,
- &exitTime,
- &kernelTime2,
- &userTime2 ) )
- {
- dwError = GetLastError();
- Fail( "GetProcessTimes() call failed with error code %d\n",
- dwError );
- }
-
-
- /* very simple logical checking of the results */
- if( CompareFileTime( &kernelTime1, &kernelTime2 ) > 0 )
- {
- Fail( "Unexpected kernel time value reported.\n" );
- }
-
- if( CompareFileTime( &userTime1, &userTime2 ) > 0 )
- {
- Fail( "Unexpected user time value reported.\n" );
- }
-
-
- /* terminate the PAL */
- PAL_Terminate();
-
- /* return success */
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/threading/GetProcessTimes/test2/test2.cpp b/src/pal/tests/palsuite/threading/GetProcessTimes/test2/test2.cpp
new file mode 100644
index 0000000000..cc39de609b
--- /dev/null
+++ b/src/pal/tests/palsuite/threading/GetProcessTimes/test2/test2.cpp
@@ -0,0 +1,122 @@
+// Licensed to the .NET Foundation under one or more 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: test2.c
+**
+** Purpose: Test to ensure GetProcessTimes works properly.
+**
+** Dependencies: PAL_Initialize
+** PAL_Terminate
+** Fail
+** ZeroMemory
+** CompareFileTime
+** GetLastError
+**
+
+**
+**===========================================================================*/
+#include <palsuite.h>
+
+
+int __cdecl main( int argc, char **argv )
+
+{
+ int i, j, k;
+ int *total;
+
+ HANDLE hProcess;
+ FILETIME createTime;
+ FILETIME exitTime;
+ FILETIME kernelTime1;
+ FILETIME userTime1;
+ FILETIME kernelTime2;
+ FILETIME userTime2;
+
+ DWORD dwError;
+
+ /* initialize the PAL */
+ if( PAL_Initialize(argc, argv) != 0 )
+ {
+ return( FAIL );
+ }
+
+ /* get our own process handle */
+ hProcess = GetCurrentProcess();
+ if( hProcess == NULL )
+ {
+ Fail( "GetCurrentProcess() returned a NULL handle.\n" );
+ }
+
+ /* zero our time structures */
+ ZeroMemory( &createTime, sizeof(createTime) );
+ ZeroMemory( &exitTime, sizeof(exitTime) );
+ ZeroMemory( &kernelTime1, sizeof(kernelTime1) );
+ ZeroMemory( &userTime1, sizeof(userTime1) );
+ ZeroMemory( &kernelTime2, sizeof(kernelTime2) );
+ ZeroMemory( &userTime2, sizeof(userTime2) );
+
+ /* check the process times for the child process */
+ if( ! GetProcessTimes( hProcess,
+ &createTime,
+ &exitTime,
+ &kernelTime1,
+ &userTime1 ) )
+ {
+ dwError = GetLastError();
+ Fail( "GetProcessTimes() call failed with error code %d\n",
+ dwError );
+ }
+
+
+ /* simulate some activity */
+ for( i=0; i<1000; i++ )
+ {
+ for( j=0; j<1000; j++ )
+ {
+ /* do kernel work to increase system usage counters */
+ total = (int*)malloc(1024 * 1024);
+
+ *total = j * i;
+ for( k=0; k<1000; k++ )
+ {
+ *total += k + i;
+ }
+
+ free(total);
+ }
+ }
+
+ /* check the process times for the child process */
+ if( ! GetProcessTimes( hProcess,
+ &createTime,
+ &exitTime,
+ &kernelTime2,
+ &userTime2 ) )
+ {
+ dwError = GetLastError();
+ Fail( "GetProcessTimes() call failed with error code %d\n",
+ dwError );
+ }
+
+
+ /* very simple logical checking of the results */
+ if( CompareFileTime( &kernelTime1, &kernelTime2 ) > 0 )
+ {
+ Fail( "Unexpected kernel time value reported.\n" );
+ }
+
+ if( CompareFileTime( &userTime1, &userTime2 ) > 0 )
+ {
+ Fail( "Unexpected user time value reported.\n" );
+ }
+
+
+ /* terminate the PAL */
+ PAL_Terminate();
+
+ /* return success */
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/threading/GetThreadTimes/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/GetThreadTimes/test1/CMakeLists.txt
index d7e2eb2a88..aa4dad11ce 100644
--- a/src/pal/tests/palsuite/threading/GetThreadTimes/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/GetThreadTimes/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_getthreadtimes_test1
diff --git a/src/pal/tests/palsuite/threading/GetThreadTimes/test1/test1.c b/src/pal/tests/palsuite/threading/GetThreadTimes/test1/test1.c
deleted file mode 100644
index 6b62c05ec7..0000000000
--- a/src/pal/tests/palsuite/threading/GetThreadTimes/test1/test1.c
+++ /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.
-
-/*============================================================
-**
-** Source:
-**
-** Source : test1.c
-**
-** Purpose: Test for GetThreadTimes() function
-**
-**
-**=========================================================*/
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[]) {
- int ret = FAIL;
-
- //Test is failing unreliably, so for now we always return pass.
- if (TRUE){
- ret = PASS;
- goto EXIT;
- }
-
- FILETIME kernelTime1, userTime1, kernelTime2, userTime2;
- /* Delta = .01 sec */
- LONG64 Actual, Expected, Delta = 850000000;
- Actual = 0;
- Expected = 0;
- const ULONG64 MSEC_TO_NSEC = 1000000;
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- HANDLE cThread = GetCurrentThread();
-
- int i;
- /* Take 2000 tiny measurements */
- for (i = 0; i < 2000; i++){
- ULONG64 Time1, Time2;
-
- Sleep(1);
-
- /* Grab a FirstCount, then loop for a bit to make the clock increase */
- if (!GetThreadTimes(cThread, NULL, NULL, &kernelTime1, &userTime1))
- {
- Fail("ERROR: GetThreadTimes returned failure.\n");
- }
- LONG64 x, Init;
- /* Init is in milliseconds, so we will convert later */
- Init = (ULONG64)GetTickCount();
- /* Spin for < 1 Quantum so we don't get interrupted */
- x = Init + 3;
- volatile int counter;
- do {
- for (counter = 0; counter < 100000; counter++)
- {
- // spin to consume CPU time
- }
-
- } while (x > GetTickCount());
- Expected += (GetTickCount() - Init) * MSEC_TO_NSEC;
- /* Get a second count */
- if (!GetThreadTimes(cThread, NULL, NULL, &kernelTime2, &userTime2))
- {
- Fail("ERROR: GetThreadTimes returned failure.\n");
- }
-
- Time1 = ((ULONG64)kernelTime1.dwHighDateTime << 32);
- Time1 += (ULONG64)kernelTime1.dwLowDateTime;
- Time1 += ((ULONG64)userTime1.dwHighDateTime << 32);
- Time1 += (ULONG64)userTime1.dwLowDateTime;
-
- Time2 = ((ULONG64)kernelTime2.dwHighDateTime << 32);
- Time2 += (ULONG64)kernelTime2.dwLowDateTime;
- Time2 += ((ULONG64)userTime2.dwHighDateTime << 32);
- Time2 += (ULONG64)userTime2.dwLowDateTime;
-
- Actual += (Time2 - Time1) * 100;
- }
-
- if(labs(Expected - Actual) > Delta)
- {
- Fail("ERROR: The measured time (%llu millisecs) was not within Delta %llu "
- "of the expected time (%llu millisecs).\n",
- (Actual / MSEC_TO_NSEC), (Delta / MSEC_TO_NSEC), (Expected / MSEC_TO_NSEC));
- }
- //printf("%llu, %llu\n", Expected, Actual);
- PAL_Terminate();
- ret = PASS;
-
-EXIT:
- return ret;
-}
diff --git a/src/pal/tests/palsuite/threading/GetThreadTimes/test1/test1.cpp b/src/pal/tests/palsuite/threading/GetThreadTimes/test1/test1.cpp
new file mode 100644
index 0000000000..e57a7d08ba
--- /dev/null
+++ b/src/pal/tests/palsuite/threading/GetThreadTimes/test1/test1.cpp
@@ -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.
+
+/*============================================================
+**
+** Source:
+**
+** Source : test1.c
+**
+** Purpose: Test for GetThreadTimes() function
+**
+**
+**=========================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[]) {
+ int ret = FAIL;
+
+ //Test is failing unreliably, so for now we always return pass.
+ if (TRUE){
+ ret = PASS;
+ goto EXIT;
+ }
+ {
+ FILETIME kernelTime1, userTime1, kernelTime2, userTime2;
+ /* Delta = .01 sec */
+ LONG64 Actual, Expected, Delta = 850000000;
+ Actual = 0;
+ Expected = 0;
+ const ULONG64 MSEC_TO_NSEC = 1000000;
+
+ /*
+ * Initialize the PAL and return FAILURE if this fails
+ */
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ HANDLE cThread = GetCurrentThread();
+
+ int i;
+ /* Take 2000 tiny measurements */
+ for (i = 0; i < 2000; i++){
+ ULONG64 Time1, Time2;
+
+ Sleep(1);
+
+ /* Grab a FirstCount, then loop for a bit to make the clock increase */
+ if (!GetThreadTimes(cThread, NULL, NULL, &kernelTime1, &userTime1))
+ {
+ Fail("ERROR: GetThreadTimes returned failure.\n");
+ }
+ LONG64 x, Init;
+ /* Init is in milliseconds, so we will convert later */
+ Init = (ULONG64)GetTickCount();
+ /* Spin for < 1 Quantum so we don't get interrupted */
+ x = Init + 3;
+ volatile int counter;
+ do {
+ for (counter = 0; counter < 100000; counter++)
+ {
+ // spin to consume CPU time
+ }
+
+ } while (x > GetTickCount());
+ Expected += (GetTickCount() - Init) * MSEC_TO_NSEC;
+ /* Get a second count */
+ if (!GetThreadTimes(cThread, NULL, NULL, &kernelTime2, &userTime2))
+ {
+ Fail("ERROR: GetThreadTimes returned failure.\n");
+ }
+
+ Time1 = ((ULONG64)kernelTime1.dwHighDateTime << 32);
+ Time1 += (ULONG64)kernelTime1.dwLowDateTime;
+ Time1 += ((ULONG64)userTime1.dwHighDateTime << 32);
+ Time1 += (ULONG64)userTime1.dwLowDateTime;
+
+ Time2 = ((ULONG64)kernelTime2.dwHighDateTime << 32);
+ Time2 += (ULONG64)kernelTime2.dwLowDateTime;
+ Time2 += ((ULONG64)userTime2.dwHighDateTime << 32);
+ Time2 += (ULONG64)userTime2.dwLowDateTime;
+
+ Actual += (Time2 - Time1) * 100;
+ }
+
+ if(labs(Expected - Actual) > Delta)
+ {
+ Fail("ERROR: The measured time (%llu millisecs) was not within Delta %llu "
+ "of the expected time (%llu millisecs).\n",
+ (Actual / MSEC_TO_NSEC), (Delta / MSEC_TO_NSEC), (Expected / MSEC_TO_NSEC));
+ }
+ //printf("%llu, %llu\n", Expected, Actual);
+ PAL_Terminate();
+ ret = PASS;
+ }
+EXIT:
+ return ret;
+}
diff --git a/src/pal/tests/palsuite/threading/NamedMutex/test1/namedmutex.cpp b/src/pal/tests/palsuite/threading/NamedMutex/test1/namedmutex.cpp
index 3726214701..a9d46b3d73 100644
--- a/src/pal/tests/palsuite/threading/NamedMutex/test1/namedmutex.cpp
+++ b/src/pal/tests/palsuite/threading/NamedMutex/test1/namedmutex.cpp
@@ -520,7 +520,7 @@ bool MutualExclusionTests_Parent()
return true;
}
-DWORD MutualExclusionTests_Child(void *arg = nullptr)
+DWORD PALAPI MutualExclusionTests_Child(void *arg = nullptr)
{
const char *testName = "MutualExclusionTests";
@@ -626,7 +626,7 @@ bool LifetimeTests_Parent()
return true;
}
-DWORD LifetimeTests_Child(void *arg = nullptr)
+DWORD PALAPI LifetimeTests_Child(void *arg = nullptr)
{
const char *testName = "LifetimeTests";
@@ -682,7 +682,7 @@ bool LifetimeTests()
return true;
}
-DWORD AbandonTests_Child_TryLock(void *arg = nullptr);
+DWORD PALAPI AbandonTests_Child_TryLock(void *arg = nullptr);
bool AbandonTests_Parent()
{
@@ -751,7 +751,7 @@ bool AbandonTests_Parent()
return true;
}
-DWORD AbandonTests_Child_GracefulExit_Close(void *arg = nullptr)
+DWORD PALAPI AbandonTests_Child_GracefulExit_Close(void *arg = nullptr)
{
const char *testName = "AbandonTests";
@@ -837,7 +837,7 @@ DWORD AbandonTests_Child_AbruptExit(void *arg = nullptr)
return 0;
}
-DWORD AbandonTests_Child_TryLock(void *arg)
+DWORD PALAPI AbandonTests_Child_TryLock(void *arg)
{
const char *testName = "AbandonTests";
@@ -910,7 +910,7 @@ DWORD g_stressDurationMilliseconds = 0;
LONG g_stressTestCounts[_countof(TestList)] = {0};
LONG g_stressResult = true;
-DWORD StressTest(void *arg)
+DWORD PALAPI StressTest(void *arg)
{
// Run the specified test continuously for the stress duration
SIZE_T testIndex = reinterpret_cast<SIZE_T>(arg);
diff --git a/src/pal/tests/palsuite/threading/OpenEventW/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/OpenEventW/test1/CMakeLists.txt
index 2bb61e3044..2d5698b153 100644
--- a/src/pal/tests/palsuite/threading/OpenEventW/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/OpenEventW/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_openeventw_test1
diff --git a/src/pal/tests/palsuite/threading/OpenEventW/test1/test1.c b/src/pal/tests/palsuite/threading/OpenEventW/test1/test1.cpp
index 9dcb3a4a68..9dcb3a4a68 100644
--- a/src/pal/tests/palsuite/threading/OpenEventW/test1/test1.c
+++ b/src/pal/tests/palsuite/threading/OpenEventW/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/threading/OpenEventW/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/OpenEventW/test2/CMakeLists.txt
index 48fa1f2c4b..bedf83b487 100644
--- a/src/pal/tests/palsuite/threading/OpenEventW/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/OpenEventW/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_openeventw_test2
diff --git a/src/pal/tests/palsuite/threading/OpenEventW/test2/test2.c b/src/pal/tests/palsuite/threading/OpenEventW/test2/test2.cpp
index 9cbf872b95..9cbf872b95 100644
--- a/src/pal/tests/palsuite/threading/OpenEventW/test2/test2.c
+++ b/src/pal/tests/palsuite/threading/OpenEventW/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/threading/OpenEventW/test3/CMakeLists.txt b/src/pal/tests/palsuite/threading/OpenEventW/test3/CMakeLists.txt
index 433a3a255c..7f7622dca0 100644
--- a/src/pal/tests/palsuite/threading/OpenEventW/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/OpenEventW/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(TESTSOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_openeventw_test3
@@ -20,7 +20,7 @@ target_link_libraries(paltest_openeventw_test3
set(HELPERSOURCES
- childprocess.c
+ childprocess.cpp
)
add_executable(paltest_openeventw_test3_child
diff --git a/src/pal/tests/palsuite/threading/OpenEventW/test3/childprocess.c b/src/pal/tests/palsuite/threading/OpenEventW/test3/childprocess.cpp
index b5149e006f..b5149e006f 100644
--- a/src/pal/tests/palsuite/threading/OpenEventW/test3/childprocess.c
+++ b/src/pal/tests/palsuite/threading/OpenEventW/test3/childprocess.cpp
diff --git a/src/pal/tests/palsuite/threading/OpenEventW/test3/test3.c b/src/pal/tests/palsuite/threading/OpenEventW/test3/test3.c
deleted file mode 100644
index 10a678a107..0000000000
--- a/src/pal/tests/palsuite/threading/OpenEventW/test3/test3.c
+++ /dev/null
@@ -1,187 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: test3.c
-**
-** Purpose: Test to ensure that OpenEventW() works when
-** opening an event created by another process. This test
-** program launches a child process which creates a
-** named, initially-unset event. The child waits up to
-** 10 seconds for the parent process to open that event
-** and set it, and returns PASS if the event was set or FAIL
-** otherwise. The parent process checks the return value
-** from the child to verify that the opened event was
-** properly used across processes.
-**
-** Dependencies: PAL_Initialize
-** PAL_Terminate
-** Fail
-** ZeroMemory
-** GetCurrentDirectoryW
-** CreateProcessW
-** WaitForSingleObject
-** GetExitCodeProcess
-** GetLastError
-** strlen
-** strncpy
-**
-**
-**===========================================================================*/
-#include <palsuite.h>
-
-#define TIMEOUT 60000
-
-int __cdecl main( int argc, char **argv )
-{
- BOOL ret = FAIL;
- LPSECURITY_ATTRIBUTES lpEventAttributes = NULL;
-
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
-
- DWORD dwExitCode;
-
- DWORD dwRet = 0;
- HANDLE hEvent = NULL;
- WCHAR wcName[] = {'P','A','L','R','o','c','k','s','\0'};
- LPWSTR lpName = wcName;
- char lpCommandLine[MAX_PATH] = "";
-
- /* initialize the PAL */
- if( PAL_Initialize(argc, argv) != 0 )
- {
- return( FAIL );
- }
-
- /* zero our process and startup info structures */
- ZeroMemory( &si, sizeof(si) );
- si.cb = sizeof( si );
- ZeroMemory( &pi, sizeof(pi) );
-
- /* create an event which we can use with SetEvent */
- hEvent = CreateEventW( lpEventAttributes,
- TRUE, /* manual reset */
- FALSE, /* unsignalled */
- lpName );
-
- if( hEvent == NULL )
- {
- /* ERROR */
- Fail( "ERROR:%lu:CreateEventW() call failed in child\n",
- GetLastError());
- }
-
- ZeroMemory( lpCommandLine, MAX_PATH );
- if ( _snprintf( lpCommandLine, MAX_PATH-1, "childprocess ") < 0 )
- {
- Fail ("Error: Insufficient lpCommandline for\n");
- }
-
- /* launch the child process */
- if( !CreateProcess( NULL, /* module name to execute */
- lpCommandLine, /* command line */
- NULL, /* process handle not */
- /* inheritable */
- NULL, /* thread handle not */
- /* inheritable */
- FALSE, /* handle inheritance */
- CREATE_NEW_CONSOLE, /* dwCreationFlags */
- NULL, /* use parent's environment */
- NULL, /* use parent's starting */
- /* directory */
- &si, /* startup info struct */
- &pi ) /* process info struct */
- )
- {
- Fail( "ERROR:%lu:CreateProcess call failed\n",
- GetLastError() );
- }
-
- /* verify that the event is signalled by the child process */
- dwRet = WaitForSingleObject( hEvent, TIMEOUT );
- if( dwRet != WAIT_OBJECT_0 )
- {
- ret = FAIL;
- /* ERROR */
- Trace( "ERROR:WaitForSingleObject() call returned %lu, "
- "expected WAIT_TIMEOUT\n",
- "expected WAIT_OBJECT_0\n",
- dwRet );
-
- goto cleanup;
-
- if( !CloseHandle( hEvent ) )
- {
- Trace( "ERROR:%lu:CloseHandle() call failed in child\n",
- GetLastError());
- }
- goto cleanup;
- }
-
- /* wait for the child process to complete */
- dwRet = WaitForSingleObject ( pi.hProcess, TIMEOUT );
- if( dwRet != WAIT_OBJECT_0 )
- {
- ret = FAIL;
- Trace( "ERROR:WaitForSingleObject() returned %lu, "
- "expected %lu\n",
- dwRet,
- WAIT_OBJECT_0 );
- goto cleanup;
- }
-
- /* check the exit code from the process */
- if( ! GetExitCodeProcess( pi.hProcess, &dwExitCode ) )
- {
- ret = FAIL;
- Trace( "ERROR:%lu:GetExitCodeProcess call failed\n",
- GetLastError() );
- goto cleanup;
- }
-
- /* check for success */
- ret = (dwExitCode == PASS) ? PASS : FAIL;
-
-cleanup:
- if( hEvent != NULL )
- {
- if( ! CloseHandle ( hEvent ) )
- {
- Trace( "ERROR:%lu:CloseHandle call failed on event handle\n",
- GetLastError() );
- ret = FAIL;
- }
- }
-
-
- /* close process and thread handle */
- if( ! CloseHandle ( pi.hProcess ) )
- {
- Trace( "ERROR:%lu:CloseHandle call failed on process handle\n",
- GetLastError() );
- ret = FAIL;
- }
-
- if( ! CloseHandle ( pi.hThread ) )
- {
- Trace( "ERROR:%lu:CloseHandle call failed on thread handle\n",
- GetLastError() );
- ret = FAIL;
- }
-
- /* output a convenient error message and exit if we failed */
- if( ret == FAIL )
- {
- Fail( "test failed\n" );
- }
-
-
- /* terminate the PAL */
- PAL_Terminate();
-
- /* return success */
- return ret;
-}
diff --git a/src/pal/tests/palsuite/threading/OpenEventW/test3/test3.cpp b/src/pal/tests/palsuite/threading/OpenEventW/test3/test3.cpp
new file mode 100644
index 0000000000..c4edf22a76
--- /dev/null
+++ b/src/pal/tests/palsuite/threading/OpenEventW/test3/test3.cpp
@@ -0,0 +1,187 @@
+// Licensed to the .NET Foundation under one or more 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: test3.c
+**
+** Purpose: Test to ensure that OpenEventW() works when
+** opening an event created by another process. This test
+** program launches a child process which creates a
+** named, initially-unset event. The child waits up to
+** 10 seconds for the parent process to open that event
+** and set it, and returns PASS if the event was set or FAIL
+** otherwise. The parent process checks the return value
+** from the child to verify that the opened event was
+** properly used across processes.
+**
+** Dependencies: PAL_Initialize
+** PAL_Terminate
+** Fail
+** ZeroMemory
+** GetCurrentDirectoryW
+** CreateProcessW
+** WaitForSingleObject
+** GetExitCodeProcess
+** GetLastError
+** strlen
+** strncpy
+**
+**
+**===========================================================================*/
+#include <palsuite.h>
+
+#define TIMEOUT 60000
+
+int __cdecl main( int argc, char **argv )
+{
+ BOOL ret = FAIL;
+ LPSECURITY_ATTRIBUTES lpEventAttributes = NULL;
+
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+
+ DWORD dwExitCode;
+
+ DWORD dwRet = 0;
+ HANDLE hEvent = NULL;
+ WCHAR wcName[] = {'P','A','L','R','o','c','k','s','\0'};
+ LPWSTR lpName = wcName;
+ char lpCommandLine[MAX_PATH] = "";
+
+ /* initialize the PAL */
+ if( PAL_Initialize(argc, argv) != 0 )
+ {
+ return( FAIL );
+ }
+
+ /* zero our process and startup info structures */
+ ZeroMemory( &si, sizeof(si) );
+ si.cb = sizeof( si );
+ ZeroMemory( &pi, sizeof(pi) );
+
+ /* create an event which we can use with SetEvent */
+ hEvent = CreateEventW( lpEventAttributes,
+ TRUE, /* manual reset */
+ FALSE, /* unsignalled */
+ lpName );
+
+ if( hEvent == NULL )
+ {
+ /* ERROR */
+ Fail( "ERROR:%lu:CreateEventW() call failed in child\n",
+ GetLastError());
+ }
+
+ ZeroMemory( lpCommandLine, MAX_PATH );
+ if ( sprintf_s( lpCommandLine, MAX_PATH-1, "childprocess ") < 0 )
+ {
+ Fail ("Error: Insufficient lpCommandline for\n");
+ }
+
+ /* launch the child process */
+ if( !CreateProcess( NULL, /* module name to execute */
+ lpCommandLine, /* command line */
+ NULL, /* process handle not */
+ /* inheritable */
+ NULL, /* thread handle not */
+ /* inheritable */
+ FALSE, /* handle inheritance */
+ CREATE_NEW_CONSOLE, /* dwCreationFlags */
+ NULL, /* use parent's environment */
+ NULL, /* use parent's starting */
+ /* directory */
+ &si, /* startup info struct */
+ &pi ) /* process info struct */
+ )
+ {
+ Fail( "ERROR:%lu:CreateProcess call failed\n",
+ GetLastError() );
+ }
+
+ /* verify that the event is signalled by the child process */
+ dwRet = WaitForSingleObject( hEvent, TIMEOUT );
+ if( dwRet != WAIT_OBJECT_0 )
+ {
+ ret = FAIL;
+ /* ERROR */
+ Trace( "ERROR:WaitForSingleObject() call returned %lu, "
+ "expected WAIT_TIMEOUT\n",
+ "expected WAIT_OBJECT_0\n",
+ dwRet );
+
+ goto cleanup;
+
+ if( !CloseHandle( hEvent ) )
+ {
+ Trace( "ERROR:%lu:CloseHandle() call failed in child\n",
+ GetLastError());
+ }
+ goto cleanup;
+ }
+
+ /* wait for the child process to complete */
+ dwRet = WaitForSingleObject ( pi.hProcess, TIMEOUT );
+ if( dwRet != WAIT_OBJECT_0 )
+ {
+ ret = FAIL;
+ Trace( "ERROR:WaitForSingleObject() returned %lu, "
+ "expected %lu\n",
+ dwRet,
+ WAIT_OBJECT_0 );
+ goto cleanup;
+ }
+
+ /* check the exit code from the process */
+ if( ! GetExitCodeProcess( pi.hProcess, &dwExitCode ) )
+ {
+ ret = FAIL;
+ Trace( "ERROR:%lu:GetExitCodeProcess call failed\n",
+ GetLastError() );
+ goto cleanup;
+ }
+
+ /* check for success */
+ ret = (dwExitCode == PASS) ? PASS : FAIL;
+
+cleanup:
+ if( hEvent != NULL )
+ {
+ if( ! CloseHandle ( hEvent ) )
+ {
+ Trace( "ERROR:%lu:CloseHandle call failed on event handle\n",
+ GetLastError() );
+ ret = FAIL;
+ }
+ }
+
+
+ /* close process and thread handle */
+ if( ! CloseHandle ( pi.hProcess ) )
+ {
+ Trace( "ERROR:%lu:CloseHandle call failed on process handle\n",
+ GetLastError() );
+ ret = FAIL;
+ }
+
+ if( ! CloseHandle ( pi.hThread ) )
+ {
+ Trace( "ERROR:%lu:CloseHandle call failed on thread handle\n",
+ GetLastError() );
+ ret = FAIL;
+ }
+
+ /* output a convenient error message and exit if we failed */
+ if( ret == FAIL )
+ {
+ Fail( "test failed\n" );
+ }
+
+
+ /* terminate the PAL */
+ PAL_Terminate();
+
+ /* return success */
+ return ret;
+}
diff --git a/src/pal/tests/palsuite/threading/OpenEventW/test4/CMakeLists.txt b/src/pal/tests/palsuite/threading/OpenEventW/test4/CMakeLists.txt
index ff17fea23b..73b8904993 100644
--- a/src/pal/tests/palsuite/threading/OpenEventW/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/OpenEventW/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_openeventw_test4
diff --git a/src/pal/tests/palsuite/threading/OpenEventW/test4/test4.c b/src/pal/tests/palsuite/threading/OpenEventW/test4/test4.cpp
index ae657a0511..ae657a0511 100644
--- a/src/pal/tests/palsuite/threading/OpenEventW/test4/test4.c
+++ b/src/pal/tests/palsuite/threading/OpenEventW/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/threading/OpenEventW/test5/CMakeLists.txt b/src/pal/tests/palsuite/threading/OpenEventW/test5/CMakeLists.txt
index b78d7fbfc0..3bad4d9cc5 100644
--- a/src/pal/tests/palsuite/threading/OpenEventW/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/OpenEventW/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_openeventw_test5
diff --git a/src/pal/tests/palsuite/threading/OpenEventW/test5/test5.c b/src/pal/tests/palsuite/threading/OpenEventW/test5/test5.cpp
index 43b585765c..43b585765c 100644
--- a/src/pal/tests/palsuite/threading/OpenEventW/test5/test5.c
+++ b/src/pal/tests/palsuite/threading/OpenEventW/test5/test5.cpp
diff --git a/src/pal/tests/palsuite/threading/OpenProcess/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/OpenProcess/test1/CMakeLists.txt
index 26d30547a9..dd2e30516c 100644
--- a/src/pal/tests/palsuite/threading/OpenProcess/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/OpenProcess/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(TESTSOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_openprocess_test1
@@ -20,7 +20,7 @@ target_link_libraries(paltest_openprocess_test1
set(HELPERSOURCES
- childProcess.c
+ childProcess.cpp
)
add_executable(paltest_openprocess_test1_child
diff --git a/src/pal/tests/palsuite/threading/OpenProcess/test1/childProcess.c b/src/pal/tests/palsuite/threading/OpenProcess/test1/childProcess.cpp
index 9ef07433fd..9ef07433fd 100644
--- a/src/pal/tests/palsuite/threading/OpenProcess/test1/childProcess.c
+++ b/src/pal/tests/palsuite/threading/OpenProcess/test1/childProcess.cpp
diff --git a/src/pal/tests/palsuite/threading/OpenProcess/test1/test1.c b/src/pal/tests/palsuite/threading/OpenProcess/test1/test1.cpp
index d0f9019646..d0f9019646 100644
--- a/src/pal/tests/palsuite/threading/OpenProcess/test1/test1.c
+++ b/src/pal/tests/palsuite/threading/OpenProcess/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/threading/QueryThreadCycleTime/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/QueryThreadCycleTime/test1/CMakeLists.txt
index ad3eec1a45..9a54ad15b6 100644
--- a/src/pal/tests/palsuite/threading/QueryThreadCycleTime/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/QueryThreadCycleTime/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_querythreadcycletime_test1
diff --git a/src/pal/tests/palsuite/threading/QueryThreadCycleTime/test1/test1.c b/src/pal/tests/palsuite/threading/QueryThreadCycleTime/test1/test1.c
deleted file mode 100644
index 54f0116bd0..0000000000
--- a/src/pal/tests/palsuite/threading/QueryThreadCycleTime/test1/test1.c
+++ /dev/null
@@ -1,98 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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:
-**
-** Source : test1.c
-**
-** Purpose: Test for QueryThreadCycleTime() function
-**
-**
-**=========================================================*/
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[]) {
- int ret = FAIL;
-
- //Test is failing unreliably, so for now we always return pass.
- if (TRUE){
- ret = PASS;
- goto EXIT;
- }
-
- LONG64 Actual, Expected, Delta = 850000000;
- Actual = 0;
- Expected = 0;
- const LONG64 MSEC_TO_NSEC = 1000000;
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- HANDLE cThread = GetCurrentThread();
-
- int i;
- /* Take 2000 tiny measurements */
- for (i = 0; i < 2000; i++){
- ULONG64 FirstCount, SecondCount;
- LONG64 Init;
-
- Sleep(1);
-
- /* Grab a FirstCount, then loop for a bit to make the clock increase */
- if (!QueryThreadCycleTime(cThread, (PULONG64)&FirstCount))
- {
- Fail("ERROR: QueryThreadCycleTime returned failure.\n");
- }
-
- LONG64 x;
- /* Init is in milliseconds, so we will convert later */
- Init = (LONG64)GetTickCount();
- x = Init + 3;
- volatile int counter;
- do {
- for (counter = 0; counter < 100000; counter++)
- {
- // spin to consume CPU time
- }
-
- } while (x > GetTickCount());
- Expected += (GetTickCount() - Init) * MSEC_TO_NSEC;
- /* Get a second count */
- if (!QueryThreadCycleTime(cThread, (PULONG64)&SecondCount))
- {
- Fail("ERROR: QueryThreadCycleTime returned failure.\n");
- }
-
- LONG64 trial = (LONG64)SecondCount - (LONG64)FirstCount;
- if (trial < 0){
- printf("Negative value %llu measured", trial);
- }
- Actual += (trial);
-
- }
-
-
-
- if(labs(Expected - Actual) > Delta)
- {
- Fail("ERROR: The measured time (%llu millisecs) was not within Delta %llu "
- "of the expected time (%llu millisecs).\n",
- (Actual / MSEC_TO_NSEC), (Delta / MSEC_TO_NSEC), (Expected / MSEC_TO_NSEC));
- }
- //printf("%llu, %llu\n", Expected, Actual);
- PAL_Terminate();
- ret = PASS;
-
-EXIT:
- return ret;
-}
diff --git a/src/pal/tests/palsuite/threading/QueryThreadCycleTime/test1/test1.cpp b/src/pal/tests/palsuite/threading/QueryThreadCycleTime/test1/test1.cpp
new file mode 100644
index 0000000000..026243c81a
--- /dev/null
+++ b/src/pal/tests/palsuite/threading/QueryThreadCycleTime/test1/test1.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.
+
+/*============================================================
+**
+** Source:
+**
+** Source : test1.c
+**
+** Purpose: Test for QueryThreadCycleTime() function
+**
+**
+**=========================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[]) {
+ int ret = FAIL;
+
+ //Test is failing unreliably, so for now we always return pass.
+ if (TRUE){
+ ret = PASS;
+ goto EXIT;
+ }
+ {
+ LONG64 Actual, Expected, Delta = 850000000;
+ Actual = 0;
+ Expected = 0;
+ const LONG64 MSEC_TO_NSEC = 1000000;
+
+ /*
+ * Initialize the PAL and return FAILURE if this fails
+ */
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ HANDLE cThread = GetCurrentThread();
+
+ int i;
+ /* Take 2000 tiny measurements */
+ for (i = 0; i < 2000; i++){
+ ULONG64 FirstCount, SecondCount;
+ LONG64 Init;
+
+ Sleep(1);
+
+ /* Grab a FirstCount, then loop for a bit to make the clock increase */
+ if (!QueryThreadCycleTime(cThread, (PULONG64)&FirstCount))
+ {
+ Fail("ERROR: QueryThreadCycleTime returned failure.\n");
+ }
+
+ LONG64 x;
+ /* Init is in milliseconds, so we will convert later */
+ Init = (LONG64)GetTickCount();
+ x = Init + 3;
+ volatile int counter;
+ do {
+ for (counter = 0; counter < 100000; counter++)
+ {
+ // spin to consume CPU time
+ }
+
+ } while (x > GetTickCount());
+ Expected += (GetTickCount() - Init) * MSEC_TO_NSEC;
+ /* Get a second count */
+ if (!QueryThreadCycleTime(cThread, (PULONG64)&SecondCount))
+ {
+ Fail("ERROR: QueryThreadCycleTime returned failure.\n");
+ }
+
+ LONG64 trial = (LONG64)SecondCount - (LONG64)FirstCount;
+ if (trial < 0){
+ printf("Negative value %llu measured", trial);
+ }
+ Actual += (trial);
+
+ }
+
+
+
+ if(labs(Expected - Actual) > Delta)
+ {
+ Fail("ERROR: The measured time (%llu millisecs) was not within Delta %llu "
+ "of the expected time (%llu millisecs).\n",
+ (Actual / MSEC_TO_NSEC), (Delta / MSEC_TO_NSEC), (Expected / MSEC_TO_NSEC));
+ }
+ //printf("%llu, %llu\n", Expected, Actual);
+ PAL_Terminate();
+ ret = PASS;
+ }
+EXIT:
+ return ret;
+}
diff --git a/src/pal/tests/palsuite/threading/QueueUserAPC/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/QueueUserAPC/test1/CMakeLists.txt
index 54a4d03719..a99b0a69cc 100644
--- a/src/pal/tests/palsuite/threading/QueueUserAPC/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/QueueUserAPC/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_queueuserapc_test1
diff --git a/src/pal/tests/palsuite/threading/QueueUserAPC/test1/test1.c b/src/pal/tests/palsuite/threading/QueueUserAPC/test1/test1.cpp
index 3637897ba7..3637897ba7 100644
--- a/src/pal/tests/palsuite/threading/QueueUserAPC/test1/test1.c
+++ b/src/pal/tests/palsuite/threading/QueueUserAPC/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/threading/QueueUserAPC/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/QueueUserAPC/test2/CMakeLists.txt
index 88cda5f7b1..5d86efdddd 100644
--- a/src/pal/tests/palsuite/threading/QueueUserAPC/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/QueueUserAPC/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_queueuserapc_test2
diff --git a/src/pal/tests/palsuite/threading/QueueUserAPC/test2/test2.c b/src/pal/tests/palsuite/threading/QueueUserAPC/test2/test2.cpp
index dc2bfdb173..dc2bfdb173 100644
--- a/src/pal/tests/palsuite/threading/QueueUserAPC/test2/test2.c
+++ b/src/pal/tests/palsuite/threading/QueueUserAPC/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/threading/QueueUserAPC/test3/CMakeLists.txt b/src/pal/tests/palsuite/threading/QueueUserAPC/test3/CMakeLists.txt
index 8475dcb03e..e07ab67070 100644
--- a/src/pal/tests/palsuite/threading/QueueUserAPC/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/QueueUserAPC/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_queueuserapc_test3
diff --git a/src/pal/tests/palsuite/threading/QueueUserAPC/test3/test3.c b/src/pal/tests/palsuite/threading/QueueUserAPC/test3/test3.cpp
index 933f41a5b4..933f41a5b4 100644
--- a/src/pal/tests/palsuite/threading/QueueUserAPC/test3/test3.c
+++ b/src/pal/tests/palsuite/threading/QueueUserAPC/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/threading/QueueUserAPC/test4/CMakeLists.txt b/src/pal/tests/palsuite/threading/QueueUserAPC/test4/CMakeLists.txt
index 2552738b50..08a5cc763b 100644
--- a/src/pal/tests/palsuite/threading/QueueUserAPC/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/QueueUserAPC/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_queueuserapc_test4
diff --git a/src/pal/tests/palsuite/threading/QueueUserAPC/test4/test4.c b/src/pal/tests/palsuite/threading/QueueUserAPC/test4/test4.cpp
index c28709db81..c28709db81 100644
--- a/src/pal/tests/palsuite/threading/QueueUserAPC/test4/test4.c
+++ b/src/pal/tests/palsuite/threading/QueueUserAPC/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/threading/QueueUserAPC/test5/CMakeLists.txt b/src/pal/tests/palsuite/threading/QueueUserAPC/test5/CMakeLists.txt
index c2fa10de12..0ef65ce583 100644
--- a/src/pal/tests/palsuite/threading/QueueUserAPC/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/QueueUserAPC/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_queueuserapc_test5
diff --git a/src/pal/tests/palsuite/threading/QueueUserAPC/test5/test5.c b/src/pal/tests/palsuite/threading/QueueUserAPC/test5/test5.cpp
index 3d26a55f59..3d26a55f59 100644
--- a/src/pal/tests/palsuite/threading/QueueUserAPC/test5/test5.c
+++ b/src/pal/tests/palsuite/threading/QueueUserAPC/test5/test5.cpp
diff --git a/src/pal/tests/palsuite/threading/QueueUserAPC/test6/CMakeLists.txt b/src/pal/tests/palsuite/threading/QueueUserAPC/test6/CMakeLists.txt
index 3fd1b1a08e..2e7198358c 100644
--- a/src/pal/tests/palsuite/threading/QueueUserAPC/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/QueueUserAPC/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test6.c
+ test6.cpp
)
add_executable(paltest_queueuserapc_test6
diff --git a/src/pal/tests/palsuite/threading/QueueUserAPC/test6/test6.c b/src/pal/tests/palsuite/threading/QueueUserAPC/test6/test6.cpp
index e2e2464726..e2e2464726 100644
--- a/src/pal/tests/palsuite/threading/QueueUserAPC/test6/test6.c
+++ b/src/pal/tests/palsuite/threading/QueueUserAPC/test6/test6.cpp
diff --git a/src/pal/tests/palsuite/threading/QueueUserAPC/test7/CMakeLists.txt b/src/pal/tests/palsuite/threading/QueueUserAPC/test7/CMakeLists.txt
index 751f3894f4..c27cd7e67c 100644
--- a/src/pal/tests/palsuite/threading/QueueUserAPC/test7/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/QueueUserAPC/test7/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test7.c
+ test7.cpp
)
add_executable(paltest_queueuserapc_test7
diff --git a/src/pal/tests/palsuite/threading/QueueUserAPC/test7/test7.c b/src/pal/tests/palsuite/threading/QueueUserAPC/test7/test7.cpp
index 54a63982fe..54a63982fe 100644
--- a/src/pal/tests/palsuite/threading/QueueUserAPC/test7/test7.c
+++ b/src/pal/tests/palsuite/threading/QueueUserAPC/test7/test7.cpp
diff --git a/src/pal/tests/palsuite/threading/ReleaseMutex/test3/CMakeLists.txt b/src/pal/tests/palsuite/threading/ReleaseMutex/test3/CMakeLists.txt
index 8e64c28242..6bb3a79db4 100644
--- a/src/pal/tests/palsuite/threading/ReleaseMutex/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/ReleaseMutex/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- ReleaseMutex.c
+ ReleaseMutex.cpp
)
add_executable(paltest_releasemutex_test3
diff --git a/src/pal/tests/palsuite/threading/ReleaseMutex/test3/ReleaseMutex.c b/src/pal/tests/palsuite/threading/ReleaseMutex/test3/ReleaseMutex.cpp
index 5f6adb0419..5f6adb0419 100644
--- a/src/pal/tests/palsuite/threading/ReleaseMutex/test3/ReleaseMutex.c
+++ b/src/pal/tests/palsuite/threading/ReleaseMutex/test3/ReleaseMutex.cpp
diff --git a/src/pal/tests/palsuite/threading/ResetEvent/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/ResetEvent/test1/CMakeLists.txt
index 78e84da2b9..12c83119d8 100644
--- a/src/pal/tests/palsuite/threading/ResetEvent/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/ResetEvent/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_resetevent_test1
diff --git a/src/pal/tests/palsuite/threading/ResetEvent/test1/test1.c b/src/pal/tests/palsuite/threading/ResetEvent/test1/test1.cpp
index 20a0d5dffa..20a0d5dffa 100644
--- a/src/pal/tests/palsuite/threading/ResetEvent/test1/test1.c
+++ b/src/pal/tests/palsuite/threading/ResetEvent/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/threading/ResetEvent/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/ResetEvent/test2/CMakeLists.txt
index ad0fe9b4a1..1f67b5d884 100644
--- a/src/pal/tests/palsuite/threading/ResetEvent/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/ResetEvent/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_resetevent_test2
diff --git a/src/pal/tests/palsuite/threading/ResetEvent/test2/test2.c b/src/pal/tests/palsuite/threading/ResetEvent/test2/test2.cpp
index 8117f44353..8117f44353 100644
--- a/src/pal/tests/palsuite/threading/ResetEvent/test2/test2.c
+++ b/src/pal/tests/palsuite/threading/ResetEvent/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/threading/ResetEvent/test3/CMakeLists.txt b/src/pal/tests/palsuite/threading/ResetEvent/test3/CMakeLists.txt
index 3c4ea1f249..fd0d6e8b16 100644
--- a/src/pal/tests/palsuite/threading/ResetEvent/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/ResetEvent/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_resetevent_test3
diff --git a/src/pal/tests/palsuite/threading/ResetEvent/test3/test3.c b/src/pal/tests/palsuite/threading/ResetEvent/test3/test3.cpp
index 9bc068ea72..9bc068ea72 100644
--- a/src/pal/tests/palsuite/threading/ResetEvent/test3/test3.c
+++ b/src/pal/tests/palsuite/threading/ResetEvent/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/threading/ResetEvent/test4/CMakeLists.txt b/src/pal/tests/palsuite/threading/ResetEvent/test4/CMakeLists.txt
index 68ee20bc95..ca2a918775 100644
--- a/src/pal/tests/palsuite/threading/ResetEvent/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/ResetEvent/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_resetevent_test4
diff --git a/src/pal/tests/palsuite/threading/ResetEvent/test4/test4.c b/src/pal/tests/palsuite/threading/ResetEvent/test4/test4.cpp
index 0cc68fd9aa..0cc68fd9aa 100644
--- a/src/pal/tests/palsuite/threading/ResetEvent/test4/test4.c
+++ b/src/pal/tests/palsuite/threading/ResetEvent/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/threading/ResumeThread/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/ResumeThread/test1/CMakeLists.txt
index 2c83dfd3d5..96d7edcbba 100644
--- a/src/pal/tests/palsuite/threading/ResumeThread/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/ResumeThread/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_resumethread_test1
diff --git a/src/pal/tests/palsuite/threading/ResumeThread/test1/test1.c b/src/pal/tests/palsuite/threading/ResumeThread/test1/test1.c
deleted file mode 100644
index 037f79f7a3..0000000000
--- a/src/pal/tests/palsuite/threading/ResumeThread/test1/test1.c
+++ /dev/null
@@ -1,141 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: test1.c
-**
-** Purpose: Test for ResumeThread. Create a suspended Thread.
-** First, ensure that it is indeed suspended. Then call resumethread
-** and check to ensure that the function has now run.
-**
-**
-**=========================================================*/
-
-#include <palsuite.h>
-
-DWORD dwResumeThreadTestParameter = 0;
-
-DWORD PALAPI ResumeThreadTestThread( LPVOID lpParameter)
-{
- DWORD dwRet = 0;
-
- /* Save parameter so we can check and ensure this function ran
- properly.
- */
-
- dwResumeThreadTestParameter = (DWORD)lpParameter;
-
- return dwRet;
-}
-
-BOOL ResumeThreadTest()
-{
- BOOL bRet = FALSE;
- DWORD dwRet = 0;
-
- LPSECURITY_ATTRIBUTES lpThreadAttributes = NULL;
- DWORD dwStackSize = 0;
- LPTHREAD_START_ROUTINE lpStartAddress = &ResumeThreadTestThread;
- LPVOID lpParameter = lpStartAddress;
- DWORD dwCreationFlags = CREATE_SUSPENDED;
- DWORD dwThreadId = 0;
-
- HANDLE hThread = 0;
-
- dwResumeThreadTestParameter = 0;
-
- /* Create a thread, with CREATE_SUSPENDED, so we can resume it! */
-
- hThread = CreateThread( lpThreadAttributes,
- dwStackSize, lpStartAddress, lpParameter,
- dwCreationFlags, &dwThreadId );
-
- if (hThread != INVALID_HANDLE_VALUE)
- {
- /* Wait for one second. This should return WAIT_TIMEOUT */
- dwRet = WaitForSingleObject(hThread,1000);
-
- if (dwRet != WAIT_TIMEOUT)
- {
- Trace("ResumeThreadTest:WaitForSingleObject "
- "failed (%x)\n",GetLastError());
- }
- else
- {
- /* Check to ensure the parameter hasn't changed. The
- function shouldn't have occurred yet.
- */
- if (dwResumeThreadTestParameter != 0)
- {
- Trace("ResumeThreadTest:parameter error\n");
- }
- else
- {
- /* Call ResumeThread and ensure the return value is
- correct.
- */
-
- dwRet = ResumeThread(hThread);
-
- if (dwRet != 1)
- {
- Trace("ResumeThreadTest:ResumeThread "
- "failed (%x)\n",GetLastError());
- }
- else
- {
- /* Wait again, now that the thread has been
- resumed, and the return should be WAIT_OBJECT_0
- */
- dwRet = WaitForSingleObject(hThread,INFINITE);
-
- if (dwRet != WAIT_OBJECT_0)
- {
- Trace("ResumeThreadTest:WaitForSingleObject "
- "failed (%x)\n",GetLastError());
- }
- else
- {
- /* Check the param now and it should have been
- set.
- */
- if (dwResumeThreadTestParameter != (DWORD)lpParameter)
- {
- Trace("ResumeThreadTest:parameter error\n");
- }
- else
- {
- bRet = TRUE;
- }
- }
- }
- }
- }
- }
- else
- {
- Trace("ResumeThreadTest:CreateThread failed (%x)\n",GetLastError());
- }
-
- return bRet;
-}
-
-int __cdecl main(int argc, char **argv)
-{
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return ( FAIL );
- }
-
- if(!ResumeThreadTest())
- {
- Fail("Test Failed\n");
- }
-
- PAL_Terminate();
- return (PASS);
-
-}
diff --git a/src/pal/tests/palsuite/threading/ResumeThread/test1/test1.cpp b/src/pal/tests/palsuite/threading/ResumeThread/test1/test1.cpp
new file mode 100644
index 0000000000..d2be262e4d
--- /dev/null
+++ b/src/pal/tests/palsuite/threading/ResumeThread/test1/test1.cpp
@@ -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.
+
+/*============================================================
+**
+** Source: test1.c
+**
+** Purpose: Test for ResumeThread. Create a suspended Thread.
+** First, ensure that it is indeed suspended. Then call resumethread
+** and check to ensure that the function has now run.
+**
+**
+**=========================================================*/
+
+#include <palsuite.h>
+
+DWORD dwResumeThreadTestParameter = 0;
+
+DWORD PALAPI ResumeThreadTestThread( LPVOID lpParameter)
+{
+ DWORD dwRet = 0;
+
+ /* Save parameter so we can check and ensure this function ran
+ properly.
+ */
+
+ dwResumeThreadTestParameter = (DWORD)lpParameter;
+
+ return dwRet;
+}
+
+BOOL ResumeThreadTest()
+{
+ BOOL bRet = FALSE;
+ DWORD dwRet = 0;
+
+ LPSECURITY_ATTRIBUTES lpThreadAttributes = NULL;
+ DWORD dwStackSize = 0;
+ LPTHREAD_START_ROUTINE lpStartAddress = &ResumeThreadTestThread;
+ LPVOID lpParameter = (LPVOID)lpStartAddress;
+ DWORD dwCreationFlags = CREATE_SUSPENDED;
+ DWORD dwThreadId = 0;
+
+ HANDLE hThread = 0;
+
+ dwResumeThreadTestParameter = 0;
+
+ /* Create a thread, with CREATE_SUSPENDED, so we can resume it! */
+
+ hThread = CreateThread( lpThreadAttributes,
+ dwStackSize, lpStartAddress, lpParameter,
+ dwCreationFlags, &dwThreadId );
+
+ if (hThread != INVALID_HANDLE_VALUE)
+ {
+ /* Wait for one second. This should return WAIT_TIMEOUT */
+ dwRet = WaitForSingleObject(hThread,1000);
+
+ if (dwRet != WAIT_TIMEOUT)
+ {
+ Trace("ResumeThreadTest:WaitForSingleObject "
+ "failed (%x)\n",GetLastError());
+ }
+ else
+ {
+ /* Check to ensure the parameter hasn't changed. The
+ function shouldn't have occurred yet.
+ */
+ if (dwResumeThreadTestParameter != 0)
+ {
+ Trace("ResumeThreadTest:parameter error\n");
+ }
+ else
+ {
+ /* Call ResumeThread and ensure the return value is
+ correct.
+ */
+
+ dwRet = ResumeThread(hThread);
+
+ if (dwRet != 1)
+ {
+ Trace("ResumeThreadTest:ResumeThread "
+ "failed (%x)\n",GetLastError());
+ }
+ else
+ {
+ /* Wait again, now that the thread has been
+ resumed, and the return should be WAIT_OBJECT_0
+ */
+ dwRet = WaitForSingleObject(hThread,INFINITE);
+
+ if (dwRet != WAIT_OBJECT_0)
+ {
+ Trace("ResumeThreadTest:WaitForSingleObject "
+ "failed (%x)\n",GetLastError());
+ }
+ else
+ {
+ /* Check the param now and it should have been
+ set.
+ */
+ if (dwResumeThreadTestParameter != (DWORD)lpParameter)
+ {
+ Trace("ResumeThreadTest:parameter error\n");
+ }
+ else
+ {
+ bRet = TRUE;
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ Trace("ResumeThreadTest:CreateThread failed (%x)\n",GetLastError());
+ }
+
+ return bRet;
+}
+
+int __cdecl main(int argc, char **argv)
+{
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return ( FAIL );
+ }
+
+ if(!ResumeThreadTest())
+ {
+ Fail("Test Failed\n");
+ }
+
+ PAL_Terminate();
+ return (PASS);
+
+}
diff --git a/src/pal/tests/palsuite/threading/SetErrorMode/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/SetErrorMode/test1/CMakeLists.txt
index cfdeb31950..7c145a8528 100644
--- a/src/pal/tests/palsuite/threading/SetErrorMode/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/SetErrorMode/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_seterrormode_test1
diff --git a/src/pal/tests/palsuite/threading/SetErrorMode/test1/test1.c b/src/pal/tests/palsuite/threading/SetErrorMode/test1/test1.cpp
index 238cec4421..238cec4421 100644
--- a/src/pal/tests/palsuite/threading/SetErrorMode/test1/test1.c
+++ b/src/pal/tests/palsuite/threading/SetErrorMode/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/threading/SetEvent/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/SetEvent/test1/CMakeLists.txt
index 9be8d5a421..8d9d729554 100644
--- a/src/pal/tests/palsuite/threading/SetEvent/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/SetEvent/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_setevent_test1
diff --git a/src/pal/tests/palsuite/threading/SetEvent/test1/test1.c b/src/pal/tests/palsuite/threading/SetEvent/test1/test1.cpp
index d5a29ce3f3..d5a29ce3f3 100644
--- a/src/pal/tests/palsuite/threading/SetEvent/test1/test1.c
+++ b/src/pal/tests/palsuite/threading/SetEvent/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/threading/SetEvent/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/SetEvent/test2/CMakeLists.txt
index 87522b3ffc..7d33b56058 100644
--- a/src/pal/tests/palsuite/threading/SetEvent/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/SetEvent/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_setevent_test2
diff --git a/src/pal/tests/palsuite/threading/SetEvent/test2/test2.c b/src/pal/tests/palsuite/threading/SetEvent/test2/test2.cpp
index 5fd2833957..5fd2833957 100644
--- a/src/pal/tests/palsuite/threading/SetEvent/test2/test2.c
+++ b/src/pal/tests/palsuite/threading/SetEvent/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/threading/SetEvent/test3/CMakeLists.txt b/src/pal/tests/palsuite/threading/SetEvent/test3/CMakeLists.txt
index d09239b3e4..1c66460ea0 100644
--- a/src/pal/tests/palsuite/threading/SetEvent/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/SetEvent/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_setevent_test3
diff --git a/src/pal/tests/palsuite/threading/SetEvent/test3/test3.c b/src/pal/tests/palsuite/threading/SetEvent/test3/test3.cpp
index 21601f00b8..21601f00b8 100644
--- a/src/pal/tests/palsuite/threading/SetEvent/test3/test3.c
+++ b/src/pal/tests/palsuite/threading/SetEvent/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/threading/SetEvent/test4/CMakeLists.txt b/src/pal/tests/palsuite/threading/SetEvent/test4/CMakeLists.txt
index 3f1d344292..04f1815259 100644
--- a/src/pal/tests/palsuite/threading/SetEvent/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/SetEvent/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_setevent_test4
diff --git a/src/pal/tests/palsuite/threading/SetEvent/test4/test4.c b/src/pal/tests/palsuite/threading/SetEvent/test4/test4.cpp
index 7a79a9d708..7a79a9d708 100644
--- a/src/pal/tests/palsuite/threading/SetEvent/test4/test4.c
+++ b/src/pal/tests/palsuite/threading/SetEvent/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/threading/Sleep/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/Sleep/test1/CMakeLists.txt
index b0d8db28a2..601789600b 100644
--- a/src/pal/tests/palsuite/threading/Sleep/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/Sleep/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- Sleep.c
+ Sleep.cpp
)
add_executable(paltest_sleep_test1
diff --git a/src/pal/tests/palsuite/threading/Sleep/test1/Sleep.c b/src/pal/tests/palsuite/threading/Sleep/test1/Sleep.cpp
index f7f7c91730..f7f7c91730 100644
--- a/src/pal/tests/palsuite/threading/Sleep/test1/Sleep.c
+++ b/src/pal/tests/palsuite/threading/Sleep/test1/Sleep.cpp
diff --git a/src/pal/tests/palsuite/threading/Sleep/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/Sleep/test2/CMakeLists.txt
index 832e8ab42d..b8bc3ed7d7 100644
--- a/src/pal/tests/palsuite/threading/Sleep/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/Sleep/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- sleep.c
+ sleep.cpp
)
add_executable(paltest_sleep_test2
diff --git a/src/pal/tests/palsuite/threading/Sleep/test2/sleep.c b/src/pal/tests/palsuite/threading/Sleep/test2/sleep.cpp
index eb30e34f2f..eb30e34f2f 100644
--- a/src/pal/tests/palsuite/threading/Sleep/test2/sleep.c
+++ b/src/pal/tests/palsuite/threading/Sleep/test2/sleep.cpp
diff --git a/src/pal/tests/palsuite/threading/SleepEx/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/SleepEx/test1/CMakeLists.txt
index de562755fc..b2aed8333b 100644
--- a/src/pal/tests/palsuite/threading/SleepEx/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/SleepEx/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_sleepex_test1
diff --git a/src/pal/tests/palsuite/threading/SleepEx/test1/test1.c b/src/pal/tests/palsuite/threading/SleepEx/test1/test1.cpp
index 7ccfe0ce87..7ccfe0ce87 100644
--- a/src/pal/tests/palsuite/threading/SleepEx/test1/test1.c
+++ b/src/pal/tests/palsuite/threading/SleepEx/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/threading/SleepEx/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/SleepEx/test2/CMakeLists.txt
index 0ea4a44449..991e9b40e2 100644
--- a/src/pal/tests/palsuite/threading/SleepEx/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/SleepEx/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_sleepex_test2
diff --git a/src/pal/tests/palsuite/threading/SleepEx/test2/test2.c b/src/pal/tests/palsuite/threading/SleepEx/test2/test2.cpp
index c2ba4e704d..c2ba4e704d 100644
--- a/src/pal/tests/palsuite/threading/SleepEx/test2/test2.c
+++ b/src/pal/tests/palsuite/threading/SleepEx/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/threading/SwitchToThread/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/SwitchToThread/test1/CMakeLists.txt
index 40ecc910b0..b9008c486f 100644
--- a/src/pal/tests/palsuite/threading/SwitchToThread/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/SwitchToThread/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_switchtothread_test1
diff --git a/src/pal/tests/palsuite/threading/SwitchToThread/test1/test1.c b/src/pal/tests/palsuite/threading/SwitchToThread/test1/test1.cpp
index 76ecdd3572..76ecdd3572 100644
--- a/src/pal/tests/palsuite/threading/SwitchToThread/test1/test1.c
+++ b/src/pal/tests/palsuite/threading/SwitchToThread/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/threading/TLS/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/TLS/test1/CMakeLists.txt
index ff1a866eb9..fef741272f 100644
--- a/src/pal/tests/palsuite/threading/TLS/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/TLS/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- TLS.c
+ TLS.cpp
)
add_executable(paltest_tls_test1
diff --git a/src/pal/tests/palsuite/threading/TLS/test1/TLS.c b/src/pal/tests/palsuite/threading/TLS/test1/TLS.cpp
index 4300c3f98b..4300c3f98b 100644
--- a/src/pal/tests/palsuite/threading/TLS/test1/TLS.c
+++ b/src/pal/tests/palsuite/threading/TLS/test1/TLS.cpp
diff --git a/src/pal/tests/palsuite/threading/TLS/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/TLS/test2/CMakeLists.txt
index 5afe82b4a6..10c5034589 100644
--- a/src/pal/tests/palsuite/threading/TLS/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/TLS/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- TLS.c
+ TLS.cpp
)
add_executable(paltest_tls_test2
diff --git a/src/pal/tests/palsuite/threading/TLS/test2/TLS.c b/src/pal/tests/palsuite/threading/TLS/test2/TLS.cpp
index 96a6011f96..96a6011f96 100644
--- a/src/pal/tests/palsuite/threading/TLS/test2/TLS.c
+++ b/src/pal/tests/palsuite/threading/TLS/test2/TLS.cpp
diff --git a/src/pal/tests/palsuite/threading/TLS/test3/CMakeLists.txt b/src/pal/tests/palsuite/threading/TLS/test3/CMakeLists.txt
index 0964d33d2c..6bd76d3fdf 100644
--- a/src/pal/tests/palsuite/threading/TLS/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/TLS/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- TLS.c
+ TLS.cpp
)
add_executable(paltest_tls_test3
diff --git a/src/pal/tests/palsuite/threading/TLS/test3/TLS.c b/src/pal/tests/palsuite/threading/TLS/test3/TLS.cpp
index 4acaef5020..4acaef5020 100644
--- a/src/pal/tests/palsuite/threading/TLS/test3/TLS.c
+++ b/src/pal/tests/palsuite/threading/TLS/test3/TLS.cpp
diff --git a/src/pal/tests/palsuite/threading/TLS/test4/CMakeLists.txt b/src/pal/tests/palsuite/threading/TLS/test4/CMakeLists.txt
index 7e7b47786a..73ba496f1d 100644
--- a/src/pal/tests/palsuite/threading/TLS/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/TLS/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_tls_test4
diff --git a/src/pal/tests/palsuite/threading/TLS/test4/test4.c b/src/pal/tests/palsuite/threading/TLS/test4/test4.cpp
index 8c3603cdb0..8c3603cdb0 100644
--- a/src/pal/tests/palsuite/threading/TLS/test4/test4.c
+++ b/src/pal/tests/palsuite/threading/TLS/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/threading/TLS/test5/CMakeLists.txt b/src/pal/tests/palsuite/threading/TLS/test5/CMakeLists.txt
index 5fb5c9ddfd..e26fcfff26 100644
--- a/src/pal/tests/palsuite/threading/TLS/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/TLS/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_tls_test5
diff --git a/src/pal/tests/palsuite/threading/TLS/test5/test5.c b/src/pal/tests/palsuite/threading/TLS/test5/test5.cpp
index c1cd132937..c1cd132937 100644
--- a/src/pal/tests/palsuite/threading/TLS/test5/test5.c
+++ b/src/pal/tests/palsuite/threading/TLS/test5/test5.cpp
diff --git a/src/pal/tests/palsuite/threading/TLS/test6_optimizedtls/CMakeLists.txt b/src/pal/tests/palsuite/threading/TLS/test6_optimizedtls/CMakeLists.txt
index 8b3a4ed64a..bfc7b75e0b 100644
--- a/src/pal/tests/palsuite/threading/TLS/test6_optimizedtls/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/TLS/test6_optimizedtls/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_tls_test6_optimizedtls
diff --git a/src/pal/tests/palsuite/threading/TLS/test6_optimizedtls/test.c b/src/pal/tests/palsuite/threading/TLS/test6_optimizedtls/test.cpp
index 02419dc90c..02419dc90c 100644
--- a/src/pal/tests/palsuite/threading/TLS/test6_optimizedtls/test.c
+++ b/src/pal/tests/palsuite/threading/TLS/test6_optimizedtls/test.cpp
diff --git a/src/pal/tests/palsuite/threading/TerminateProcess/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/TerminateProcess/test1/CMakeLists.txt
index 37d575952f..382e801e29 100644
--- a/src/pal/tests/palsuite/threading/TerminateProcess/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/TerminateProcess/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- TerminateProcess.c
+ TerminateProcess.cpp
)
add_executable(paltest_terminateprocess_test1
diff --git a/src/pal/tests/palsuite/threading/TerminateProcess/test1/TerminateProcess.c b/src/pal/tests/palsuite/threading/TerminateProcess/test1/TerminateProcess.cpp
index 6feedfce76..6feedfce76 100644
--- a/src/pal/tests/palsuite/threading/TerminateProcess/test1/TerminateProcess.c
+++ b/src/pal/tests/palsuite/threading/TerminateProcess/test1/TerminateProcess.cpp
diff --git a/src/pal/tests/palsuite/threading/ThreadPriority/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/ThreadPriority/test1/CMakeLists.txt
index e341ca7435..026f4ed043 100644
--- a/src/pal/tests/palsuite/threading/ThreadPriority/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/ThreadPriority/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- ThreadPriority.c
+ ThreadPriority.cpp
)
add_executable(paltest_threadpriority_test1
diff --git a/src/pal/tests/palsuite/threading/ThreadPriority/test1/ThreadPriority.c b/src/pal/tests/palsuite/threading/ThreadPriority/test1/ThreadPriority.cpp
index 95bcdac52a..95bcdac52a 100644
--- a/src/pal/tests/palsuite/threading/ThreadPriority/test1/ThreadPriority.c
+++ b/src/pal/tests/palsuite/threading/ThreadPriority/test1/ThreadPriority.cpp
diff --git a/src/pal/tests/palsuite/threading/WaitForMultipleObjects/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/WaitForMultipleObjects/test1/CMakeLists.txt
index 2b1f946b26..ea13c7de4c 100644
--- a/src/pal/tests/palsuite/threading/WaitForMultipleObjects/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/WaitForMultipleObjects/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_waitformultipleobjects_test1
diff --git a/src/pal/tests/palsuite/threading/WaitForMultipleObjects/test1/test1.c b/src/pal/tests/palsuite/threading/WaitForMultipleObjects/test1/test1.cpp
index 8249c38d9d..8249c38d9d 100644
--- a/src/pal/tests/palsuite/threading/WaitForMultipleObjects/test1/test1.c
+++ b/src/pal/tests/palsuite/threading/WaitForMultipleObjects/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test1/CMakeLists.txt
index d035021bb9..59d4cd8cd4 100644
--- a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_waitformultipleobjectsex_test1
diff --git a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test1/test1.c b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test1/test1.cpp
index df3233fa50..df3233fa50 100644
--- a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test1/test1.c
+++ b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test2/CMakeLists.txt b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test2/CMakeLists.txt
index ab47c6f2e7..e970ec526e 100644
--- a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test2/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test2/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test2.c
+ test2.cpp
)
add_executable(paltest_waitformultipleobjectsex_test2
diff --git a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test2/test2.c b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test2/test2.cpp
index b2bc301128..b2bc301128 100644
--- a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test2/test2.c
+++ b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test2/test2.cpp
diff --git a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test3/CMakeLists.txt b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test3/CMakeLists.txt
index 645b86719d..f1b76fb819 100644
--- a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test3/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test3/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test3.c
+ test3.cpp
)
add_executable(paltest_waitformultipleobjectsex_test3
diff --git a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test3/test3.c b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test3/test3.cpp
index b78b0540dc..b78b0540dc 100644
--- a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test3/test3.c
+++ b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test3/test3.cpp
diff --git a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test4/CMakeLists.txt b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test4/CMakeLists.txt
index 3cd7f72b98..815b2b069c 100644
--- a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test4/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test4/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test4.c
+ test4.cpp
)
add_executable(paltest_waitformultipleobjectsex_test4
diff --git a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test4/test4.c b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test4/test4.cpp
index 15d0a386d1..15d0a386d1 100644
--- a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test4/test4.c
+++ b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test4/test4.cpp
diff --git a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test5/CMakeLists.txt b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test5/CMakeLists.txt
index 50147e9bf3..730ec60649 100644
--- a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test5/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test5/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(TESTSOURCES
- test5.c
+ test5.cpp
)
add_executable(paltest_waitformultipleobjectsex_test5
@@ -20,7 +20,7 @@ target_link_libraries(paltest_waitformultipleobjectsex_test5
set(HELPERSOURCES
- helper.c
+ helper.cpp
)
add_executable(paltest_waitformultipleobjectsex_test5_helper
diff --git a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test5/helper.c b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test5/helper.c
deleted file mode 100644
index 274780a216..0000000000
--- a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test5/helper.c
+++ /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.
-
-/*=============================================================
-**
-** Source: helper.c
-**
-** Purpose: This helper process sets up signals to communicate
-** with the test thread in the parent process, and let the test
-** thread signal this process when to exit.
-**
-**
-**============================================================*/
-
-#include "commonconsts.h"
-
-#include <palsuite.h>
-
-HANDLE hProcessStartEvent;
-HANDLE hProcessReadyEvent;
-HANDLE hProcessFinishEvent;
-HANDLE hProcessCleanupEvent;
-
-
-int __cdecl main(int argc, char *argv[])
-{
-
- BOOL success = TRUE; /* assume success */
- DWORD dwRet;
- DWORD dwProcessId;
- char szEventName[MAX_LONGPATH];
- PWCHAR uniString;
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- /* Open the event to let test thread tell us to get started. */
- uniString = convert(szcHelperProcessStartEvName);
- hProcessStartEvent = OpenEventW(EVENT_ALL_ACCESS, 0, uniString);
- free(uniString);
- if (!hProcessStartEvent)
- {
- Fail("helper.main: OpenEvent of '%S' failed (%u). "
- "(the event should already exist!)\n",
- szcHelperProcessStartEvName, GetLastError());
- }
-
- /* Wait for signal from test thread. */
- dwRet = WaitForSingleObject(hProcessStartEvent, TIMEOUT);
- if (dwRet != WAIT_OBJECT_0)
- {
- Fail("helper.main: WaitForSingleObject '%s' failed\n"
- "LastError:(%u)\n", szcHelperProcessStartEvName, GetLastError());
- }
-
- dwProcessId = GetCurrentProcessId();
-
- if ( 0 >= dwProcessId )
- {
- Fail ("helper.main: %s has invalid pid %d\n", argv[0], dwProcessId );
- }
-
- /* Open the event to tell test thread we are ready. */
- if (_snprintf(szEventName, MAX_LONGPATH-1, "%s%d", szcHelperProcessReadyEvName, dwProcessId) < 0)
- {
- Fail ("helper.main: Insufficient event name string length for pid=%d\n", dwProcessId);
- }
-
- uniString = convert(szEventName);
-
- hProcessReadyEvent = OpenEventW(EVENT_ALL_ACCESS, 0, uniString);
- free(uniString);
- if (!hProcessReadyEvent)
- {
- Fail("helper.main: OpenEvent of '%s' failed (%u). "
- "(the event should already exist!)\n",
- szEventName, GetLastError());
- }
-
- /* Open the event to let test thread tell us to exit. */
- if (_snprintf(szEventName, MAX_LONGPATH-1, "%s%d", szcHelperProcessFinishEvName, dwProcessId) < 0)
- {
- Fail ("helper.main: Insufficient event name string length for pid=%d\n", dwProcessId);
- }
-
- uniString = convert(szEventName);
-
- hProcessFinishEvent = OpenEventW(EVENT_ALL_ACCESS, 0, uniString);
- free(uniString);
- if (!hProcessFinishEvent)
- {
- Fail("helper.main: OpenEvent of '%s' failed LastError:(%u).\n",
- szEventName, GetLastError());
- }
-
- /* Tell the test thread we are ready. */
- if (!SetEvent(hProcessReadyEvent))
- {
- Fail("helper.main: SetEvent '%s' failed LastError:(%u)\n",
- hProcessReadyEvent, GetLastError());
- }
-
- /* Wait for signal from test thread before exit. */
- dwRet = WaitForSingleObject(hProcessFinishEvent, TIMEOUT);
- if (WAIT_OBJECT_0 != dwRet)
- {
- Fail("helper.main: WaitForSingleObject '%s' failed pid=%d\n"
- "LastError:(%u)\n",
- szcHelperProcessFinishEvName, dwProcessId, GetLastError());
- }
-
- PEDANTIC(CloseHandle, (hProcessStartEvent));
- PEDANTIC(CloseHandle, (hProcessReadyEvent));
- PEDANTIC(CloseHandle, (hProcessFinishEvent));
-
- PAL_Terminate();
-
- return success ? PASS : FAIL;
-}
diff --git a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test5/helper.cpp b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test5/helper.cpp
new file mode 100644
index 0000000000..caa0206a11
--- /dev/null
+++ b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test5/helper.cpp
@@ -0,0 +1,122 @@
+// Licensed to the .NET Foundation under one or more 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: helper.c
+**
+** Purpose: This helper process sets up signals to communicate
+** with the test thread in the parent process, and let the test
+** thread signal this process when to exit.
+**
+**
+**============================================================*/
+
+#include "commonconsts.h"
+
+#include <palsuite.h>
+
+HANDLE hProcessStartEvent;
+HANDLE hProcessReadyEvent;
+HANDLE hProcessFinishEvent;
+HANDLE hProcessCleanupEvent;
+
+
+int __cdecl main(int argc, char *argv[])
+{
+
+ BOOL success = TRUE; /* assume success */
+ DWORD dwRet;
+ DWORD dwProcessId;
+ char szEventName[MAX_LONGPATH];
+ PWCHAR uniString;
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ /* Open the event to let test thread tell us to get started. */
+ uniString = convert(szcHelperProcessStartEvName);
+ hProcessStartEvent = OpenEventW(EVENT_ALL_ACCESS, 0, uniString);
+ free(uniString);
+ if (!hProcessStartEvent)
+ {
+ Fail("helper.main: OpenEvent of '%S' failed (%u). "
+ "(the event should already exist!)\n",
+ szcHelperProcessStartEvName, GetLastError());
+ }
+
+ /* Wait for signal from test thread. */
+ dwRet = WaitForSingleObject(hProcessStartEvent, TIMEOUT);
+ if (dwRet != WAIT_OBJECT_0)
+ {
+ Fail("helper.main: WaitForSingleObject '%s' failed\n"
+ "LastError:(%u)\n", szcHelperProcessStartEvName, GetLastError());
+ }
+
+ dwProcessId = GetCurrentProcessId();
+
+ if ( 0 >= dwProcessId )
+ {
+ Fail ("helper.main: %s has invalid pid %d\n", argv[0], dwProcessId );
+ }
+
+ /* Open the event to tell test thread we are ready. */
+ if (sprintf_s(szEventName, MAX_LONGPATH-1, "%s%d", szcHelperProcessReadyEvName, dwProcessId) < 0)
+ {
+ Fail ("helper.main: Insufficient event name string length for pid=%d\n", dwProcessId);
+ }
+
+ uniString = convert(szEventName);
+
+ hProcessReadyEvent = OpenEventW(EVENT_ALL_ACCESS, 0, uniString);
+ free(uniString);
+ if (!hProcessReadyEvent)
+ {
+ Fail("helper.main: OpenEvent of '%s' failed (%u). "
+ "(the event should already exist!)\n",
+ szEventName, GetLastError());
+ }
+
+ /* Open the event to let test thread tell us to exit. */
+ if (sprintf_s(szEventName, MAX_LONGPATH-1, "%s%d", szcHelperProcessFinishEvName, dwProcessId) < 0)
+ {
+ Fail ("helper.main: Insufficient event name string length for pid=%d\n", dwProcessId);
+ }
+
+ uniString = convert(szEventName);
+
+ hProcessFinishEvent = OpenEventW(EVENT_ALL_ACCESS, 0, uniString);
+ free(uniString);
+ if (!hProcessFinishEvent)
+ {
+ Fail("helper.main: OpenEvent of '%s' failed LastError:(%u).\n",
+ szEventName, GetLastError());
+ }
+
+ /* Tell the test thread we are ready. */
+ if (!SetEvent(hProcessReadyEvent))
+ {
+ Fail("helper.main: SetEvent '%s' failed LastError:(%u)\n",
+ hProcessReadyEvent, GetLastError());
+ }
+
+ /* Wait for signal from test thread before exit. */
+ dwRet = WaitForSingleObject(hProcessFinishEvent, TIMEOUT);
+ if (WAIT_OBJECT_0 != dwRet)
+ {
+ Fail("helper.main: WaitForSingleObject '%s' failed pid=%d\n"
+ "LastError:(%u)\n",
+ szcHelperProcessFinishEvName, dwProcessId, GetLastError());
+ }
+
+ PEDANTIC(CloseHandle, (hProcessStartEvent));
+ PEDANTIC(CloseHandle, (hProcessReadyEvent));
+ PEDANTIC(CloseHandle, (hProcessFinishEvent));
+
+ PAL_Terminate();
+
+ return success ? PASS : FAIL;
+}
diff --git a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test5/test5.c b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test5/test5.c
deleted file mode 100644
index d19978c103..0000000000
--- a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test5/test5.c
+++ /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.
-
-/*=============================================================
-**
-** Source: test5.c
-**
-** Purpose: Test the functionality of simultaneously waiting
-** on multiple processes. Create the same number of helper
-** processes and helper threads.
-** Helper threads wait on helper processes to finish.
-** Helper processes wait on the event signal from test
-** thread before exit.
-** The test thread can wake up one helper
-** thread at a time by signaling the corresponding helper
-** process to finish.
-** The test thread can also wake up all helper threads at once
-** by signaling help process 0 to exit.
-**
-**
-**============================================================*/
-
-#define UNICODE
-
-#include "commonconsts.h"
-
-#include <palsuite.h>
-
-/* The maximum number of objects a thread can wait is MAXIMUM_WAIT_OBJECTS.
- The last helper thread in this test case will wait on all helper processes
- plus a thread finish event so the maximum number of helper processes
- can be created in this test case is (MAXIMUM_WAIT_OBJECTS-1). */
-#define MAX_HELPER_PROCESS (MAXIMUM_WAIT_OBJECTS-1)
-
-int MaxNumHelperProcess = MAX_HELPER_PROCESS;
-
-/* indicate how the test thread wake up helper thread. */
-typedef enum _TestCaseType {
- WakeUpOneThread, /* wake up one helper thread at a time. */
- WakeUpAllThread /* wake up all helper threads at once */
-} TestCaseType;
-
-TestCaseType TestCase = WakeUpOneThread;
-
-/* When the test thread wakes up one thread at a time,
- ThreadIndexOfThreadFinishEvent specifies the index of the thread that
- should be waked up using hThreadFinishEvent instead of helper process. */
-DWORD ThreadIndexOfThreadFinishEvent = 0;
-
-struct helper_process_t
-{
- PROCESS_INFORMATION pi;
- HANDLE hProcessReadyEvent;
- HANDLE hProcessFinishEvent;
-} helper_process[MAX_HELPER_PROCESS];
-
-HANDLE hProcessStartEvent;
-
-struct helper_thread_t
-{
- HANDLE hThread;
- DWORD dwThreadId;
- HANDLE hThreadReadyEvent;
- HANDLE hThreadFinishEvent;
-} helper_thread[MAX_HELPER_PROCESS];
-
-/*
- * Entry Point for helper thread.
- */
-DWORD PALAPI WaitForProcess(LPVOID lpParameter)
-{
- DWORD index, i;
- DWORD dwRet;
- HANDLE handles[MAX_HELPER_PROCESS+1];
-
- index = (DWORD) lpParameter;
-
- /* The helper thread 0 will wait for helper process 0, helper thread 1 will
- wait for helper process 0 and 1, helper thread 2 will wait for helper
- process 0, 1, and 2, and so on ..., and the last helper thread will wait
- on all helper processes.
- Each helper thread also waits on hThreadFinishEvent so that
- it can exit without waiting on any process to finish. */
-
- for (i = 0; i <= index; i++)
- {
- handles[i] = helper_process[i].pi.hProcess;
- }
-
- handles[index+1] = helper_thread[index].hThreadFinishEvent;
-
- if(!SetEvent(helper_thread[index].hThreadReadyEvent))
- {
- Fail("test5.WaitProcess: SetEvent of hThreadReadyEvent failed for thread %d. "
- "GetLastError() returned %d.\n", index,
- GetLastError());
- }
-
- dwRet = WaitForMultipleObjectsEx(index+2, &handles[0], FALSE, TIMEOUT, TRUE);
- if (WakeUpAllThread == TestCase)
- {
- /* If the test thread signals helper process 0 to exit, all threads will be waked up,
- and the return value must be (WAIT_OBJECT_0+0) because the handle of helper process 0
- is in handle[0]. */
- if (dwRet != (WAIT_OBJECT_0+0))
- {
- Fail("test5.WaitForProcess: invalid return value %d for WakupAllThread from WaitForMultipleObjectsEx for thread %d\n"
- "LastError:(%u)\n",
- dwRet, index,
- GetLastError());
- }
- }
- else if (WakeUpOneThread == TestCase)
- {
- /* If the test thread wakes up one helper thread at a time,
- the return value must be either (WAIT_OBJECT_0+index) if the helper thread
- wakes up because the corresponding help process exits,
- or (index+1) if the helper thread wakes up because of hThreadReadyEvent. */
- if ((index != ThreadIndexOfThreadFinishEvent && dwRet != (WAIT_OBJECT_0+index)) ||
- (index == ThreadIndexOfThreadFinishEvent && dwRet != (index+1)))
- {
- Fail("test5.WaitForProcess: invalid return value %d for WakupOneThread from WaitForMultipleObjectsEx for thread %d\n"
- "LastError:(%u)\n",
- dwRet, index,
- GetLastError());
- }
- }
- else
- {
- Fail("Unknown TestCase %d\n", TestCase);
- }
- return 0;
-}
-
-/*
- * Setup the helper processes and helper threads.
- */
-void
-Setup()
-{
-
- STARTUPINFO si;
- DWORD dwRet;
- int i;
-
- char szEventName[MAX_PATH];
- PWCHAR uniStringHelper;
- PWCHAR uniString;
-
- /* Create the event to start helper process after it was created. */
- uniString = convert(szcHelperProcessStartEvName);
- hProcessStartEvent = CreateEvent(NULL, TRUE, FALSE, uniString);
- free(uniString);
- if (!hProcessStartEvent)
- {
- Fail("test5.Setup: CreateEvent of '%s' failed. "
- "GetLastError() returned %d.\n", szcHelperProcessStartEvName,
- GetLastError());
- }
-
- /* Create the helper processes. */
- ZeroMemory( &si, sizeof(si) );
- si.cb = sizeof(si);
- uniStringHelper = convert("helper");
- for (i = 0; i < MaxNumHelperProcess; i++)
- {
- ZeroMemory( &helper_process[i].pi, sizeof(PROCESS_INFORMATION));
-
- if(!CreateProcess( NULL, uniStringHelper, NULL, NULL,
- FALSE, 0, NULL, NULL, &si, &helper_process[i].pi))
- {
- Fail("test5.Setup: CreateProcess failed to load executable for helper process %d. "
- "GetLastError() returned %u.\n",
- i, GetLastError());
- }
-
- /* Create the event to let helper process tell us it is ready. */
- if (_snprintf(szEventName, MAX_PATH-1, "%s%d",
- szcHelperProcessReadyEvName, helper_process[i].pi.dwProcessId) < 0)
- {
- Fail ("test5.Setup: Insufficient event name string length for %s\n", szcHelperProcessReadyEvName);
- }
-
- uniString = convert(szEventName);
-
- helper_process[i].hProcessReadyEvent = CreateEvent(NULL, FALSE, FALSE, uniString);
- free(uniString);
- if (!helper_process[i].hProcessReadyEvent)
- {
- Fail("test5.Setup: CreateEvent of '%s' failed. "
- "GetLastError() returned %d.\n", szEventName,
- GetLastError());
- }
-
- /* Create the event to tell helper process to exit. */
- if (_snprintf(szEventName, MAX_PATH-1, "%s%d",
- szcHelperProcessFinishEvName, helper_process[i].pi.dwProcessId) < 0)
- {
- Fail ("test5.Setup: Insufficient event name string length for %s\n", szcHelperProcessFinishEvName);
- }
-
- uniString = convert(szEventName);
-
- helper_process[i].hProcessFinishEvent = CreateEvent(NULL, TRUE, FALSE, uniString);
- free(uniString);
- if (!helper_process[i].hProcessFinishEvent)
- {
- Fail("test5.Setup: CreateEvent of '%s' failed. "
- "GetLastError() returned %d.\n", szEventName,
- GetLastError());
- }
-
- }
- free(uniStringHelper);
-
- /* Signal all helper processes to start. */
- if (!SetEvent(hProcessStartEvent))
- {
- Fail("test5.Setup: SetEvent '%s' failed\n",
- "LastError:(%u)\n",
- szcHelperProcessStartEvName, GetLastError());
- }
-
- /* Wait for ready signals from all helper processes. */
- for (i = 0; i < MaxNumHelperProcess; i++)
- {
- dwRet = WaitForSingleObject(helper_process[i].hProcessReadyEvent, TIMEOUT);
- if (dwRet != WAIT_OBJECT_0)
- {
- Fail("test5.Setup: WaitForSingleObject %s failed for helper process %d\n"
- "LastError:(%u)\n",
- szcHelperProcessReadyEvName, i, GetLastError());
- }
- }
-
- /* Create the same number of helper threads as helper processes. */
- for (i = 0; i < MaxNumHelperProcess; i++)
- {
- /* Create the event to let helper thread tell us it is ready. */
- helper_thread[i].hThreadReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (!helper_thread[i].hThreadReadyEvent)
- {
- Fail("test5.Setup: CreateEvent of hThreadReadyEvent failed for thread %d\n"
- "LastError:(%u)\n", i, GetLastError());
- }
-
- /* Create the event to tell helper thread to exit without waiting for helper process. */
- helper_thread[i].hThreadFinishEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (!helper_thread[i].hThreadFinishEvent)
- {
- Fail("test5.Setup: CreateEvent of hThreadFinishEvent failed for thread %d\n"
- "LastError:(%u)\n", i, GetLastError());
- }
-
- /* Create the helper thread. */
- helper_thread[i].hThread = CreateThread( NULL,
- 0,
- (LPTHREAD_START_ROUTINE)WaitForProcess,
- (LPVOID)i,
- 0,
- &helper_thread[i].dwThreadId);
- if (NULL == helper_thread[i].hThread)
- {
- Fail("test5.Setup: Unable to create the helper thread %d\n"
- "LastError:(%u)\n", i, GetLastError());
- }
- }
-
- /* Wait for ready signals from all helper threads. */
- for (i = 0; i < MaxNumHelperProcess; i++)
- {
- dwRet = WaitForSingleObject(helper_thread[i].hThreadReadyEvent, TIMEOUT);
- if (dwRet != WAIT_OBJECT_0)
- {
- Fail("test5.Setup: WaitForSingleObject hThreadReadyEvent for thread %d\n"
- "LastError:(%u)\n", i, GetLastError());
- }
- }
-}
-
-/*
- * Cleanup the helper processes and helper threads.
- */
-DWORD
-Cleanup()
-{
- DWORD dwExitCode;
- DWORD dwRet;
- int i;
-
- /* Wait for all helper process to finish and close their handles
- and associated events. */
- for (i = 0; i < MaxNumHelperProcess; i++)
- {
-
- /* wait for the child process to complete */
- dwRet = WaitForSingleObject ( helper_process[i].pi.hProcess, TIMEOUT );
- if (WAIT_OBJECT_0 != dwRet)
- {
- Fail("test5.Cleanup: WaitForSingleObject hThreadReadyEvent failed for thread %d\n"
- "LastError:(%u)\n", i, GetLastError());
- }
-
- /* check the exit code from the process */
- if (!GetExitCodeProcess(helper_process[i].pi.hProcess, &dwExitCode))
- {
- Trace( "test5.Cleanup: GetExitCodeProcess %d call failed LastError:(%u)\n",
- i, GetLastError());
- dwExitCode = FAIL;
- }
- PEDANTIC(CloseHandle, (helper_process[i].pi.hThread));
- PEDANTIC(CloseHandle, (helper_process[i].pi.hProcess));
- PEDANTIC(CloseHandle, (helper_process[i].hProcessReadyEvent));
- PEDANTIC(CloseHandle, (helper_process[i].hProcessFinishEvent));
- }
-
- /* Close all helper threads' handles */
- for (i = 0; i < MaxNumHelperProcess; i++)
- {
- PEDANTIC(CloseHandle, (helper_thread[i].hThread));
- PEDANTIC(CloseHandle, (helper_thread[i].hThreadReadyEvent));
- PEDANTIC(CloseHandle, (helper_thread[i].hThreadFinishEvent));
- }
-
- /* Close all process start event. */
- PEDANTIC(CloseHandle, (hProcessStartEvent));
-
- return dwExitCode;
-}
-
-/*
- * In this test case, the test thread will signal one helper
- * process to exit at a time starting from the last helper
- * process and then wait for the corresponding helper thread to exit.
- * The ThreadIndexOfThreadFinishEvent specifies the index of the thread that
- * should be waked up using hThreadFinishEvent instead of helper process.
- */
-void
-TestWakeupOneThread()
-{
- DWORD dwRet;
- int i;
-
- TestCase = WakeUpOneThread;
-
- if (((LONG)ThreadIndexOfThreadFinishEvent) < 0 ||
- ThreadIndexOfThreadFinishEvent >= MAX_HELPER_PROCESS)
- Fail("test5.TestWaitOnOneThread: Invalid ThreadIndexOfThreadFinishEvent %d\n", ThreadIndexOfThreadFinishEvent);
-
- /* Since helper thread 0 waits on helper process 0,
- thread 1 waits on on process 0, and 1,
- thread 2 waits on process 0, 1, and 2, and so on ...,
- and the last helper thread will wait on all helper processes,
- the helper thread can be waked up one at a time by
- waking up the help process one at a time starting from the
- last helper process. */
- for (i = MaxNumHelperProcess-1; i >= 0; i--)
- {
- /* make sure the helper thread has not exited yet. */
- dwRet = WaitForSingleObject(helper_thread[i].hThread, 0);
- if (WAIT_TIMEOUT != dwRet)
- {
- Fail("test5.TestWaitOnOneThread: helper thread %d already exited %d\n", i);
- }
-
- /* Decide how to wakeup the helper thread:
- using event or using helper process. */
- if (i == ThreadIndexOfThreadFinishEvent)
- {
- if (!SetEvent(helper_thread[i].hThreadFinishEvent))
- {
- Fail("test5.TestWaitOnOneThread: SetEvent hThreadFinishEvent failed for thread %d\n",
- "LastError:(%u)\n", i, GetLastError());
- }
- }
- else
- {
- if (!SetEvent(helper_process[i].hProcessFinishEvent))
- {
- Fail("test5.TestWaitOnOneThread: SetEvent %s%d failed for helper process %d\n",
- "LastError:(%u)\n",
- szcHelperProcessFinishEvName, helper_process[i].pi.dwProcessId, i,
- GetLastError());
- }
- }
-
- dwRet = WaitForSingleObject(helper_thread[i].hThread, TIMEOUT);
- if (WAIT_OBJECT_0 != dwRet)
- {
- Fail("test5.TestWaitOnOneThread: WaitForSingleObject helper thread %d"
- "LastError:(%u)\n",
- i, GetLastError());
- }
- }
-
- /* Finally, need to wake up the helper process which the test thread
- skips waking up in the last loop. */
- if (!SetEvent(helper_process[ThreadIndexOfThreadFinishEvent].hProcessFinishEvent))
- {
- Fail("test5.TestWaitOnOneThread: SetEvent %s%d failed\n",
- "LastError:(%u)\n",
- szcHelperProcessFinishEvName, helper_process[ThreadIndexOfThreadFinishEvent].pi.dwProcessId,
- GetLastError());
- }
-}
-
-/*
- * In this test case, the test thread will signal the helper
- * process 0 to exit. Since all helper threads wait on process 0,
- * all helper threads will wake up and exit, and the test thread
- * will wait for all of them to exit.
- */
-void
-TestWakeupAllThread()
-{
- DWORD dwRet;
- int i;
-
- TestCase = WakeUpAllThread;
-
- /* make sure none of the helper thread exits. */
- for (i = 0; i < MaxNumHelperProcess; i++)
- {
- dwRet = WaitForSingleObject(helper_thread[i].hThread, 0);
- if (WAIT_TIMEOUT != dwRet)
- {
- Fail("test5.TestWaitOnAllThread: helper thread %d already exited %d\n", i);
- }
- }
-
- /* Signal helper process 0 to exit. */
- if (!SetEvent(helper_process[0].hProcessFinishEvent))
- {
- Fail("test5.TestWaitOnAllThread: SetEvent %s%d failed\n",
- "LastError:(%u)\n",
- szcHelperProcessFinishEvName, helper_process[0].pi.dwProcessId,
- GetLastError());
- }
-
- /* Wait for all helper threads to exit. */
- for (i = 0; i < MaxNumHelperProcess; i++)
- {
-
- dwRet = WaitForSingleObject(helper_thread[i].hThread, TIMEOUT);
- if (WAIT_OBJECT_0 != dwRet)
- {
- Fail("test5.TestWaitOnAllThread: WaitForSingleObject failed for helper thread %d\n"
- "LastError:(%u)\n",
- i, GetLastError());
- }
- }
-
- /* Signal the rest of helper processes to exit. */
- for (i = 1; i < MaxNumHelperProcess; i++)
- {
- if (!SetEvent(helper_process[i].hProcessFinishEvent))
- {
- Fail("test5.TestWaitOnAllThread: SetEvent %s%d failed\n",
- "LastError:(%u)\n",
- szcHelperProcessFinishEvName, helper_process[i].pi.dwProcessId,
- GetLastError());
- }
- }
-}
-
-int __cdecl main(int argc, char *argv[])
-{
- DWORD dwExitCode;
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- switch (argc)
- {
- case 1:
- MaxNumHelperProcess = MAX_HELPER_PROCESS;
- break;
- case 2:
- MaxNumHelperProcess = atol(argv[1]);
- break;
- default:
- Fail("Invalid number of arguments\n");
- }
-
- if (MaxNumHelperProcess < 1 ||
- MaxNumHelperProcess > MAX_HELPER_PROCESS)
- Fail("test5.main: Invalid MaxNumHelperProcess %d\n", MaxNumHelperProcess);
-
- Setup();
- ThreadIndexOfThreadFinishEvent = 3;
- TestWakeupOneThread();
- dwExitCode = Cleanup();
-
- if (PASS == dwExitCode)
- {
- Setup();
- TestWakeupAllThread();
- dwExitCode = Cleanup();
- }
-
- PAL_TerminateEx(dwExitCode);
- return dwExitCode;
-}
diff --git a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test5/test5.cpp b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test5/test5.cpp
new file mode 100644
index 0000000000..a0216494ba
--- /dev/null
+++ b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test5/test5.cpp
@@ -0,0 +1,506 @@
+// Licensed to the .NET Foundation under one or more 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: test5.c
+**
+** Purpose: Test the functionality of simultaneously waiting
+** on multiple processes. Create the same number of helper
+** processes and helper threads.
+** Helper threads wait on helper processes to finish.
+** Helper processes wait on the event signal from test
+** thread before exit.
+** The test thread can wake up one helper
+** thread at a time by signaling the corresponding helper
+** process to finish.
+** The test thread can also wake up all helper threads at once
+** by signaling help process 0 to exit.
+**
+**
+**============================================================*/
+
+#define UNICODE
+
+#include "commonconsts.h"
+
+#include <palsuite.h>
+
+/* The maximum number of objects a thread can wait is MAXIMUM_WAIT_OBJECTS.
+ The last helper thread in this test case will wait on all helper processes
+ plus a thread finish event so the maximum number of helper processes
+ can be created in this test case is (MAXIMUM_WAIT_OBJECTS-1). */
+#define MAX_HELPER_PROCESS (MAXIMUM_WAIT_OBJECTS-1)
+
+int MaxNumHelperProcess = MAX_HELPER_PROCESS;
+
+/* indicate how the test thread wake up helper thread. */
+typedef enum _TestCaseType {
+ WakeUpOneThread, /* wake up one helper thread at a time. */
+ WakeUpAllThread /* wake up all helper threads at once */
+} TestCaseType;
+
+TestCaseType TestCase = WakeUpOneThread;
+
+/* When the test thread wakes up one thread at a time,
+ ThreadIndexOfThreadFinishEvent specifies the index of the thread that
+ should be waked up using hThreadFinishEvent instead of helper process. */
+DWORD ThreadIndexOfThreadFinishEvent = 0;
+
+struct helper_process_t
+{
+ PROCESS_INFORMATION pi;
+ HANDLE hProcessReadyEvent;
+ HANDLE hProcessFinishEvent;
+} helper_process[MAX_HELPER_PROCESS];
+
+HANDLE hProcessStartEvent;
+
+struct helper_thread_t
+{
+ HANDLE hThread;
+ DWORD dwThreadId;
+ HANDLE hThreadReadyEvent;
+ HANDLE hThreadFinishEvent;
+} helper_thread[MAX_HELPER_PROCESS];
+
+/*
+ * Entry Point for helper thread.
+ */
+DWORD PALAPI WaitForProcess(LPVOID lpParameter)
+{
+ DWORD index, i;
+ DWORD dwRet;
+ HANDLE handles[MAX_HELPER_PROCESS+1];
+
+ index = (DWORD) lpParameter;
+
+ /* The helper thread 0 will wait for helper process 0, helper thread 1 will
+ wait for helper process 0 and 1, helper thread 2 will wait for helper
+ process 0, 1, and 2, and so on ..., and the last helper thread will wait
+ on all helper processes.
+ Each helper thread also waits on hThreadFinishEvent so that
+ it can exit without waiting on any process to finish. */
+
+ for (i = 0; i <= index; i++)
+ {
+ handles[i] = helper_process[i].pi.hProcess;
+ }
+
+ handles[index+1] = helper_thread[index].hThreadFinishEvent;
+
+ if(!SetEvent(helper_thread[index].hThreadReadyEvent))
+ {
+ Fail("test5.WaitProcess: SetEvent of hThreadReadyEvent failed for thread %d. "
+ "GetLastError() returned %d.\n", index,
+ GetLastError());
+ }
+
+ dwRet = WaitForMultipleObjectsEx(index+2, &handles[0], FALSE, TIMEOUT, TRUE);
+ if (WakeUpAllThread == TestCase)
+ {
+ /* If the test thread signals helper process 0 to exit, all threads will be waked up,
+ and the return value must be (WAIT_OBJECT_0+0) because the handle of helper process 0
+ is in handle[0]. */
+ if (dwRet != (WAIT_OBJECT_0+0))
+ {
+ Fail("test5.WaitForProcess: invalid return value %d for WakupAllThread from WaitForMultipleObjectsEx for thread %d\n"
+ "LastError:(%u)\n",
+ dwRet, index,
+ GetLastError());
+ }
+ }
+ else if (WakeUpOneThread == TestCase)
+ {
+ /* If the test thread wakes up one helper thread at a time,
+ the return value must be either (WAIT_OBJECT_0+index) if the helper thread
+ wakes up because the corresponding help process exits,
+ or (index+1) if the helper thread wakes up because of hThreadReadyEvent. */
+ if ((index != ThreadIndexOfThreadFinishEvent && dwRet != (WAIT_OBJECT_0+index)) ||
+ (index == ThreadIndexOfThreadFinishEvent && dwRet != (index+1)))
+ {
+ Fail("test5.WaitForProcess: invalid return value %d for WakupOneThread from WaitForMultipleObjectsEx for thread %d\n"
+ "LastError:(%u)\n",
+ dwRet, index,
+ GetLastError());
+ }
+ }
+ else
+ {
+ Fail("Unknown TestCase %d\n", TestCase);
+ }
+ return 0;
+}
+
+/*
+ * Setup the helper processes and helper threads.
+ */
+void
+Setup()
+{
+
+ STARTUPINFO si;
+ DWORD dwRet;
+ int i;
+
+ char szEventName[MAX_PATH];
+ PWCHAR uniStringHelper;
+ PWCHAR uniString;
+
+ /* Create the event to start helper process after it was created. */
+ uniString = convert(szcHelperProcessStartEvName);
+ hProcessStartEvent = CreateEvent(NULL, TRUE, FALSE, uniString);
+ free(uniString);
+ if (!hProcessStartEvent)
+ {
+ Fail("test5.Setup: CreateEvent of '%s' failed. "
+ "GetLastError() returned %d.\n", szcHelperProcessStartEvName,
+ GetLastError());
+ }
+
+ /* Create the helper processes. */
+ ZeroMemory( &si, sizeof(si) );
+ si.cb = sizeof(si);
+ uniStringHelper = convert("helper");
+ for (i = 0; i < MaxNumHelperProcess; i++)
+ {
+ ZeroMemory( &helper_process[i].pi, sizeof(PROCESS_INFORMATION));
+
+ if(!CreateProcess( NULL, uniStringHelper, NULL, NULL,
+ FALSE, 0, NULL, NULL, &si, &helper_process[i].pi))
+ {
+ Fail("test5.Setup: CreateProcess failed to load executable for helper process %d. "
+ "GetLastError() returned %u.\n",
+ i, GetLastError());
+ }
+
+ /* Create the event to let helper process tell us it is ready. */
+ if (sprintf_s(szEventName, MAX_PATH-1, "%s%d",
+ szcHelperProcessReadyEvName, helper_process[i].pi.dwProcessId) < 0)
+ {
+ Fail ("test5.Setup: Insufficient event name string length for %s\n", szcHelperProcessReadyEvName);
+ }
+
+ uniString = convert(szEventName);
+
+ helper_process[i].hProcessReadyEvent = CreateEvent(NULL, FALSE, FALSE, uniString);
+ free(uniString);
+ if (!helper_process[i].hProcessReadyEvent)
+ {
+ Fail("test5.Setup: CreateEvent of '%s' failed. "
+ "GetLastError() returned %d.\n", szEventName,
+ GetLastError());
+ }
+
+ /* Create the event to tell helper process to exit. */
+ if (sprintf_s(szEventName, MAX_PATH-1, "%s%d",
+ szcHelperProcessFinishEvName, helper_process[i].pi.dwProcessId) < 0)
+ {
+ Fail ("test5.Setup: Insufficient event name string length for %s\n", szcHelperProcessFinishEvName);
+ }
+
+ uniString = convert(szEventName);
+
+ helper_process[i].hProcessFinishEvent = CreateEvent(NULL, TRUE, FALSE, uniString);
+ free(uniString);
+ if (!helper_process[i].hProcessFinishEvent)
+ {
+ Fail("test5.Setup: CreateEvent of '%s' failed. "
+ "GetLastError() returned %d.\n", szEventName,
+ GetLastError());
+ }
+
+ }
+ free(uniStringHelper);
+
+ /* Signal all helper processes to start. */
+ if (!SetEvent(hProcessStartEvent))
+ {
+ Fail("test5.Setup: SetEvent '%s' failed\n",
+ "LastError:(%u)\n",
+ szcHelperProcessStartEvName, GetLastError());
+ }
+
+ /* Wait for ready signals from all helper processes. */
+ for (i = 0; i < MaxNumHelperProcess; i++)
+ {
+ dwRet = WaitForSingleObject(helper_process[i].hProcessReadyEvent, TIMEOUT);
+ if (dwRet != WAIT_OBJECT_0)
+ {
+ Fail("test5.Setup: WaitForSingleObject %s failed for helper process %d\n"
+ "LastError:(%u)\n",
+ szcHelperProcessReadyEvName, i, GetLastError());
+ }
+ }
+
+ /* Create the same number of helper threads as helper processes. */
+ for (i = 0; i < MaxNumHelperProcess; i++)
+ {
+ /* Create the event to let helper thread tell us it is ready. */
+ helper_thread[i].hThreadReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (!helper_thread[i].hThreadReadyEvent)
+ {
+ Fail("test5.Setup: CreateEvent of hThreadReadyEvent failed for thread %d\n"
+ "LastError:(%u)\n", i, GetLastError());
+ }
+
+ /* Create the event to tell helper thread to exit without waiting for helper process. */
+ helper_thread[i].hThreadFinishEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (!helper_thread[i].hThreadFinishEvent)
+ {
+ Fail("test5.Setup: CreateEvent of hThreadFinishEvent failed for thread %d\n"
+ "LastError:(%u)\n", i, GetLastError());
+ }
+
+ /* Create the helper thread. */
+ helper_thread[i].hThread = CreateThread( NULL,
+ 0,
+ (LPTHREAD_START_ROUTINE)WaitForProcess,
+ (LPVOID)i,
+ 0,
+ &helper_thread[i].dwThreadId);
+ if (NULL == helper_thread[i].hThread)
+ {
+ Fail("test5.Setup: Unable to create the helper thread %d\n"
+ "LastError:(%u)\n", i, GetLastError());
+ }
+ }
+
+ /* Wait for ready signals from all helper threads. */
+ for (i = 0; i < MaxNumHelperProcess; i++)
+ {
+ dwRet = WaitForSingleObject(helper_thread[i].hThreadReadyEvent, TIMEOUT);
+ if (dwRet != WAIT_OBJECT_0)
+ {
+ Fail("test5.Setup: WaitForSingleObject hThreadReadyEvent for thread %d\n"
+ "LastError:(%u)\n", i, GetLastError());
+ }
+ }
+}
+
+/*
+ * Cleanup the helper processes and helper threads.
+ */
+DWORD
+Cleanup()
+{
+ DWORD dwExitCode;
+ DWORD dwRet;
+ int i;
+
+ /* Wait for all helper process to finish and close their handles
+ and associated events. */
+ for (i = 0; i < MaxNumHelperProcess; i++)
+ {
+
+ /* wait for the child process to complete */
+ dwRet = WaitForSingleObject ( helper_process[i].pi.hProcess, TIMEOUT );
+ if (WAIT_OBJECT_0 != dwRet)
+ {
+ Fail("test5.Cleanup: WaitForSingleObject hThreadReadyEvent failed for thread %d\n"
+ "LastError:(%u)\n", i, GetLastError());
+ }
+
+ /* check the exit code from the process */
+ if (!GetExitCodeProcess(helper_process[i].pi.hProcess, &dwExitCode))
+ {
+ Trace( "test5.Cleanup: GetExitCodeProcess %d call failed LastError:(%u)\n",
+ i, GetLastError());
+ dwExitCode = FAIL;
+ }
+ PEDANTIC(CloseHandle, (helper_process[i].pi.hThread));
+ PEDANTIC(CloseHandle, (helper_process[i].pi.hProcess));
+ PEDANTIC(CloseHandle, (helper_process[i].hProcessReadyEvent));
+ PEDANTIC(CloseHandle, (helper_process[i].hProcessFinishEvent));
+ }
+
+ /* Close all helper threads' handles */
+ for (i = 0; i < MaxNumHelperProcess; i++)
+ {
+ PEDANTIC(CloseHandle, (helper_thread[i].hThread));
+ PEDANTIC(CloseHandle, (helper_thread[i].hThreadReadyEvent));
+ PEDANTIC(CloseHandle, (helper_thread[i].hThreadFinishEvent));
+ }
+
+ /* Close all process start event. */
+ PEDANTIC(CloseHandle, (hProcessStartEvent));
+
+ return dwExitCode;
+}
+
+/*
+ * In this test case, the test thread will signal one helper
+ * process to exit at a time starting from the last helper
+ * process and then wait for the corresponding helper thread to exit.
+ * The ThreadIndexOfThreadFinishEvent specifies the index of the thread that
+ * should be waked up using hThreadFinishEvent instead of helper process.
+ */
+void
+TestWakeupOneThread()
+{
+ DWORD dwRet;
+ int i;
+
+ TestCase = WakeUpOneThread;
+
+ if (((LONG)ThreadIndexOfThreadFinishEvent) < 0 ||
+ ThreadIndexOfThreadFinishEvent >= MAX_HELPER_PROCESS)
+ Fail("test5.TestWaitOnOneThread: Invalid ThreadIndexOfThreadFinishEvent %d\n", ThreadIndexOfThreadFinishEvent);
+
+ /* Since helper thread 0 waits on helper process 0,
+ thread 1 waits on on process 0, and 1,
+ thread 2 waits on process 0, 1, and 2, and so on ...,
+ and the last helper thread will wait on all helper processes,
+ the helper thread can be waked up one at a time by
+ waking up the help process one at a time starting from the
+ last helper process. */
+ for (i = MaxNumHelperProcess-1; i >= 0; i--)
+ {
+ /* make sure the helper thread has not exited yet. */
+ dwRet = WaitForSingleObject(helper_thread[i].hThread, 0);
+ if (WAIT_TIMEOUT != dwRet)
+ {
+ Fail("test5.TestWaitOnOneThread: helper thread %d already exited %d\n", i);
+ }
+
+ /* Decide how to wakeup the helper thread:
+ using event or using helper process. */
+ if (i == ThreadIndexOfThreadFinishEvent)
+ {
+ if (!SetEvent(helper_thread[i].hThreadFinishEvent))
+ {
+ Fail("test5.TestWaitOnOneThread: SetEvent hThreadFinishEvent failed for thread %d\n",
+ "LastError:(%u)\n", i, GetLastError());
+ }
+ }
+ else
+ {
+ if (!SetEvent(helper_process[i].hProcessFinishEvent))
+ {
+ Fail("test5.TestWaitOnOneThread: SetEvent %s%d failed for helper process %d\n",
+ "LastError:(%u)\n",
+ szcHelperProcessFinishEvName, helper_process[i].pi.dwProcessId, i,
+ GetLastError());
+ }
+ }
+
+ dwRet = WaitForSingleObject(helper_thread[i].hThread, TIMEOUT);
+ if (WAIT_OBJECT_0 != dwRet)
+ {
+ Fail("test5.TestWaitOnOneThread: WaitForSingleObject helper thread %d"
+ "LastError:(%u)\n",
+ i, GetLastError());
+ }
+ }
+
+ /* Finally, need to wake up the helper process which the test thread
+ skips waking up in the last loop. */
+ if (!SetEvent(helper_process[ThreadIndexOfThreadFinishEvent].hProcessFinishEvent))
+ {
+ Fail("test5.TestWaitOnOneThread: SetEvent %s%d failed\n",
+ "LastError:(%u)\n",
+ szcHelperProcessFinishEvName, helper_process[ThreadIndexOfThreadFinishEvent].pi.dwProcessId,
+ GetLastError());
+ }
+}
+
+/*
+ * In this test case, the test thread will signal the helper
+ * process 0 to exit. Since all helper threads wait on process 0,
+ * all helper threads will wake up and exit, and the test thread
+ * will wait for all of them to exit.
+ */
+void
+TestWakeupAllThread()
+{
+ DWORD dwRet;
+ int i;
+
+ TestCase = WakeUpAllThread;
+
+ /* make sure none of the helper thread exits. */
+ for (i = 0; i < MaxNumHelperProcess; i++)
+ {
+ dwRet = WaitForSingleObject(helper_thread[i].hThread, 0);
+ if (WAIT_TIMEOUT != dwRet)
+ {
+ Fail("test5.TestWaitOnAllThread: helper thread %d already exited %d\n", i);
+ }
+ }
+
+ /* Signal helper process 0 to exit. */
+ if (!SetEvent(helper_process[0].hProcessFinishEvent))
+ {
+ Fail("test5.TestWaitOnAllThread: SetEvent %s%d failed\n",
+ "LastError:(%u)\n",
+ szcHelperProcessFinishEvName, helper_process[0].pi.dwProcessId,
+ GetLastError());
+ }
+
+ /* Wait for all helper threads to exit. */
+ for (i = 0; i < MaxNumHelperProcess; i++)
+ {
+
+ dwRet = WaitForSingleObject(helper_thread[i].hThread, TIMEOUT);
+ if (WAIT_OBJECT_0 != dwRet)
+ {
+ Fail("test5.TestWaitOnAllThread: WaitForSingleObject failed for helper thread %d\n"
+ "LastError:(%u)\n",
+ i, GetLastError());
+ }
+ }
+
+ /* Signal the rest of helper processes to exit. */
+ for (i = 1; i < MaxNumHelperProcess; i++)
+ {
+ if (!SetEvent(helper_process[i].hProcessFinishEvent))
+ {
+ Fail("test5.TestWaitOnAllThread: SetEvent %s%d failed\n",
+ "LastError:(%u)\n",
+ szcHelperProcessFinishEvName, helper_process[i].pi.dwProcessId,
+ GetLastError());
+ }
+ }
+}
+
+int __cdecl main(int argc, char *argv[])
+{
+ DWORD dwExitCode;
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ switch (argc)
+ {
+ case 1:
+ MaxNumHelperProcess = MAX_HELPER_PROCESS;
+ break;
+ case 2:
+ MaxNumHelperProcess = atol(argv[1]);
+ break;
+ default:
+ Fail("Invalid number of arguments\n");
+ }
+
+ if (MaxNumHelperProcess < 1 ||
+ MaxNumHelperProcess > MAX_HELPER_PROCESS)
+ Fail("test5.main: Invalid MaxNumHelperProcess %d\n", MaxNumHelperProcess);
+
+ Setup();
+ ThreadIndexOfThreadFinishEvent = 3;
+ TestWakeupOneThread();
+ dwExitCode = Cleanup();
+
+ if (PASS == dwExitCode)
+ {
+ Setup();
+ TestWakeupAllThread();
+ dwExitCode = Cleanup();
+ }
+
+ PAL_TerminateEx(dwExitCode);
+ return dwExitCode;
+}
diff --git a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test6/CMakeLists.txt b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test6/CMakeLists.txt
index ce75cadbff..01331821a8 100644
--- a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test6/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test6/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(TESTSOURCES
- test6.c
+ test6.cpp
)
add_executable(paltest_waitformultipleobjectsex_test6
@@ -20,7 +20,7 @@ target_link_libraries(paltest_waitformultipleobjectsex_test6
set(HELPERSOURCES
- child6.c
+ child6.cpp
)
add_executable(paltest_waitformultipleobjectsex_test6_child
diff --git a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test6/child6.c b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test6/child6.c
deleted file mode 100644
index 1a95815ddf..0000000000
--- a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test6/child6.c
+++ /dev/null
@@ -1,211 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: child6.c
-**
-** Purpose: Test for WaitForMultipleObjectsEx in multiple
-** scenarios - child process
-**
-**
-**=========================================================*/
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char **argv)
-{
- int i, iRet;
- BOOL bRet;
- BOOL bNamedEvent = 0;
- BOOL bMutex = 0;
- BOOL bMutexAndNamedEvent = 0;
- BOOL bSemaphore = 0;
- DWORD dwRet;
- HANDLE hNamedEvent;
- HANDLE hMutex;
- char szTestName[256];
- WCHAR wszTestName[256] = { 0 };
- char szEventName[128] = { 0 };
- char szMutexName[128] = { 0 };
- char szSemName[128] = { 0 };
- WCHAR wszEventName[128];
- WCHAR wszMutexName[128];
- WCHAR wszSemName[128];
- DWORD iExitCode = 0;
- HANDLE hSemaphore;
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return ( FAIL );
- }
-
- Trace("[child] Starting\n");
-
- for (i=1; i<argc; i++)
- {
- if (0 == strcmp(argv[i],"-event"))
- {
- bNamedEvent = 1;
- }
- else if (0 == strcmp(argv[i],"-mutex"))
- {
- bMutex = 1;
- }
- else if (0 == strcmp(argv[i],"-mutex_and_named_event"))
- {
- bMutexAndNamedEvent = 1;
- }
- else if (0 == strcmp(argv[i],"-semaphore"))
- {
- bSemaphore = 1;
- }
- else if (0 == strcmp(argv[i],"-exitcode") && i < argc-1 )
- {
- i++;
- iExitCode = atoi(argv[i]);
- Trace("[child] My exit code is %d\n", iExitCode);
- }
-
- else if ('-' != *argv[i])
- {
- strncpy(szTestName, argv[i], 256);
- szTestName[255] = 0;
- iRet = MultiByteToWideChar(CP_ACP, 0, szTestName, strlen(szTestName)+1, wszTestName, 256);
- if (0 == iRet)
- {
- Fail("Failed to convert test string\n");
- }
- }
- }
-
- _snprintf(szEventName, 128, "%s_Event", szTestName);
- szEventName[127] = 0;
- _snprintf(szMutexName, 128, "%s_Mutex", szTestName);
- szMutexName[127] = 0;
- _snprintf(szSemName, 128, "%s_Semaphore", szTestName);
- szSemName[127] = 0;
-
- iRet = MultiByteToWideChar(CP_ACP, 0, szEventName, strlen(szEventName)+1, wszEventName, 128);
- iRet &= MultiByteToWideChar(CP_ACP, 0, szMutexName, strlen(szMutexName)+1, wszMutexName, 128);
- iRet &= MultiByteToWideChar(CP_ACP, 0, szSemName, strlen(szSemName)+1, wszSemName, 128);
- if (0 == iRet)
- {
- Fail("[child] Failed to convert strings\n");
- }
-
- Trace("[child] TestName=%s Event: %S, Mutex: %S, Semaphore = %S\n",
- szTestName, wszEventName, wszMutexName, wszSemName);
-
- hNamedEvent = OpenEventW(0, FALSE, wszEventName);
- if (NULL == hNamedEvent)
- {
- Fail("[child] OpenEventW failed [szEventName=%s GetLastError()=%u]\n",
- szEventName, GetLastError());
- }
- hMutex = OpenMutexW(0, FALSE, wszMutexName);
- if (NULL == hMutex)
- {
- Fail("[child] OpenMutexW failed [GetLastError()=%u]\n",
- GetLastError());
- }
- hSemaphore = CreateSemaphoreW(NULL, 0, 256, wszSemName);
- if (NULL == hSemaphore)
- {
- Fail("[child] CreateSemaphore failed [GetLastError()=%u]\n",
- GetLastError());
- }
-
-
- if (bMutex)
- {
- Trace("[child] Going to wait on mutex %s\n", szMutexName);
- dwRet = WaitForSingleObject(hMutex, INFINITE);
- if (WAIT_FAILED == dwRet)
- {
- Fail("[child] WaitForMultipleObjects failed [GetLastError()=%u]\n",
- GetLastError());
- }
-
- Trace("[child] Setting event %s\n", szEventName);
- bRet = SetEvent(hNamedEvent);
- if (FALSE == bRet)
- {
- Fail("[child] SetEvent failed [GetLastError()=%u]\n",
- GetLastError());
- }
-
- // mutex will be abandoned
- }
- else if (bMutexAndNamedEvent)
- {
- dwRet = WaitForSingleObject(hMutex, INFINITE);
- if (WAIT_FAILED == dwRet)
- {
- Fail("[child] WaitForMultipleObjects failed [GetLastError()=%u]\n",
- GetLastError());
- }
-
- Sleep(2000);
-
- bRet = ReleaseMutex(hMutex);
- if (FALSE == bRet)
- {
- Fail("[child] ReleaseMutex failed [GetLastError()=%u]\n",
- GetLastError());
- }
-
- Sleep(1000);
-
- bRet = SetEvent(hNamedEvent);
- if (FALSE == bRet)
- {
- Fail("[child] SetEvent failed [GetLastError()=%u]\n",
- GetLastError());
- }
- }
- else if (bSemaphore)
- {
- LONG lPrevCount = 42;
-
-
- Trace("[child] Going to wait on event %s\n", szEventName);
- dwRet = WaitForSingleObject(hNamedEvent, INFINITE);
- if (WAIT_FAILED == dwRet)
- {
- Fail("[child] WaitForMultipleObjects failed [GetLastError()=%u]\n",
- GetLastError());
- }
-
- Trace("[child] Releasing semaphore %s\n", szSemName);
- bRet = ReleaseSemaphore(hSemaphore, 10, &lPrevCount);
- if (FALSE == bRet)
- {
- Fail("ReleaseMutex failed [GetLastError()=%u]\n",
- GetLastError());
- }
- if (0 != lPrevCount)
- {
- Fail("Previous count from semaphore=%d, expected 0\n", lPrevCount);
- }
- }
- else if (bNamedEvent)
- {
- Sleep(1000);
-
- bRet = SetEvent(hNamedEvent);
- if (FALSE == bRet)
- {
- Fail("[child] SetEvent failed [GetLastError()=%u]\n",
- GetLastError());
- }
- }
-
- Sleep(1000);
-
- Trace("[child] Done\n");
-
- PAL_TerminateEx(iExitCode);
- return iExitCode;
-}
diff --git a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test6/child6.cpp b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test6/child6.cpp
new file mode 100644
index 0000000000..a53b6c9727
--- /dev/null
+++ b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test6/child6.cpp
@@ -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.
+
+/*============================================================
+**
+** Source: child6.c
+**
+** Purpose: Test for WaitForMultipleObjectsEx in multiple
+** scenarios - child process
+**
+**
+**=========================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char **argv)
+{
+ int i, iRet;
+ BOOL bRet;
+ BOOL bNamedEvent = 0;
+ BOOL bMutex = 0;
+ BOOL bMutexAndNamedEvent = 0;
+ BOOL bSemaphore = 0;
+ DWORD dwRet;
+ HANDLE hNamedEvent;
+ HANDLE hMutex;
+ char szTestName[256];
+ WCHAR wszTestName[256] = { 0 };
+ char szEventName[128] = { 0 };
+ char szMutexName[128] = { 0 };
+ char szSemName[128] = { 0 };
+ WCHAR wszEventName[128];
+ WCHAR wszMutexName[128];
+ WCHAR wszSemName[128];
+ DWORD iExitCode = 0;
+ HANDLE hSemaphore;
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return ( FAIL );
+ }
+
+ Trace("[child] Starting\n");
+
+ for (i=1; i<argc; i++)
+ {
+ if (0 == strcmp(argv[i],"-event"))
+ {
+ bNamedEvent = 1;
+ }
+ else if (0 == strcmp(argv[i],"-mutex"))
+ {
+ bMutex = 1;
+ }
+ else if (0 == strcmp(argv[i],"-mutex_and_named_event"))
+ {
+ bMutexAndNamedEvent = 1;
+ }
+ else if (0 == strcmp(argv[i],"-semaphore"))
+ {
+ bSemaphore = 1;
+ }
+ else if (0 == strcmp(argv[i],"-exitcode") && i < argc-1 )
+ {
+ i++;
+ iExitCode = atoi(argv[i]);
+ Trace("[child] My exit code is %d\n", iExitCode);
+ }
+
+ else if ('-' != *argv[i])
+ {
+ strncpy(szTestName, argv[i], 256);
+ szTestName[255] = 0;
+ iRet = MultiByteToWideChar(CP_ACP, 0, szTestName, strlen(szTestName)+1, wszTestName, 256);
+ if (0 == iRet)
+ {
+ Fail("Failed to convert test string\n");
+ }
+ }
+ }
+
+ sprintf_s(szEventName, 128, "%s_Event", szTestName);
+ szEventName[127] = 0;
+ sprintf_s(szMutexName, 128, "%s_Mutex", szTestName);
+ szMutexName[127] = 0;
+ sprintf_s(szSemName, 128, "%s_Semaphore", szTestName);
+ szSemName[127] = 0;
+
+ iRet = MultiByteToWideChar(CP_ACP, 0, szEventName, strlen(szEventName)+1, wszEventName, 128);
+ iRet &= MultiByteToWideChar(CP_ACP, 0, szMutexName, strlen(szMutexName)+1, wszMutexName, 128);
+ iRet &= MultiByteToWideChar(CP_ACP, 0, szSemName, strlen(szSemName)+1, wszSemName, 128);
+ if (0 == iRet)
+ {
+ Fail("[child] Failed to convert strings\n");
+ }
+
+ Trace("[child] TestName=%s Event: %S, Mutex: %S, Semaphore = %S\n",
+ szTestName, wszEventName, wszMutexName, wszSemName);
+
+ hNamedEvent = OpenEventW(0, FALSE, wszEventName);
+ if (NULL == hNamedEvent)
+ {
+ Fail("[child] OpenEventW failed [szEventName=%s GetLastError()=%u]\n",
+ szEventName, GetLastError());
+ }
+ hMutex = OpenMutexW(0, FALSE, wszMutexName);
+ if (NULL == hMutex)
+ {
+ Fail("[child] OpenMutexW failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+ hSemaphore = CreateSemaphoreW(NULL, 0, 256, wszSemName);
+ if (NULL == hSemaphore)
+ {
+ Fail("[child] CreateSemaphore failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+
+
+ if (bMutex)
+ {
+ Trace("[child] Going to wait on mutex %s\n", szMutexName);
+ dwRet = WaitForSingleObject(hMutex, INFINITE);
+ if (WAIT_FAILED == dwRet)
+ {
+ Fail("[child] WaitForMultipleObjects failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+
+ Trace("[child] Setting event %s\n", szEventName);
+ bRet = SetEvent(hNamedEvent);
+ if (FALSE == bRet)
+ {
+ Fail("[child] SetEvent failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+
+ // mutex will be abandoned
+ }
+ else if (bMutexAndNamedEvent)
+ {
+ dwRet = WaitForSingleObject(hMutex, INFINITE);
+ if (WAIT_FAILED == dwRet)
+ {
+ Fail("[child] WaitForMultipleObjects failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+
+ Sleep(2000);
+
+ bRet = ReleaseMutex(hMutex);
+ if (FALSE == bRet)
+ {
+ Fail("[child] ReleaseMutex failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+
+ Sleep(1000);
+
+ bRet = SetEvent(hNamedEvent);
+ if (FALSE == bRet)
+ {
+ Fail("[child] SetEvent failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+ }
+ else if (bSemaphore)
+ {
+ LONG lPrevCount = 42;
+
+
+ Trace("[child] Going to wait on event %s\n", szEventName);
+ dwRet = WaitForSingleObject(hNamedEvent, INFINITE);
+ if (WAIT_FAILED == dwRet)
+ {
+ Fail("[child] WaitForMultipleObjects failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+
+ Trace("[child] Releasing semaphore %s\n", szSemName);
+ bRet = ReleaseSemaphore(hSemaphore, 10, &lPrevCount);
+ if (FALSE == bRet)
+ {
+ Fail("ReleaseMutex failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+ if (0 != lPrevCount)
+ {
+ Fail("Previous count from semaphore=%d, expected 0\n", lPrevCount);
+ }
+ }
+ else if (bNamedEvent)
+ {
+ Sleep(1000);
+
+ bRet = SetEvent(hNamedEvent);
+ if (FALSE == bRet)
+ {
+ Fail("[child] SetEvent failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+ }
+
+ Sleep(1000);
+
+ Trace("[child] Done\n");
+
+ PAL_TerminateEx(iExitCode);
+ return iExitCode;
+}
diff --git a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test6/test6.c b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test6/test6.c
deleted file mode 100644
index 399d2c3bff..0000000000
--- a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test6/test6.c
+++ /dev/null
@@ -1,709 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: test6.c
-**
-** Purpose: Test for WaitForMultipleObjectsEx in multiple
-** scenarios
-**
-**
-**=========================================================*/
-
-#include <palsuite.h>
-
-#define MAX_COUNT 10000
-#define MAX_THREADS 256
-
-BOOL g_bMutex = 0;
-BOOL g_bEvent = 0;
-BOOL g_bNamedEvent = 0;
-BOOL g_bSemaphore = 0;
-BOOL g_bProcess = 0;
-BOOL g_bLocalWaitAll = 0;
-BOOL g_bRemoteWaitAll = 0;
-BOOL g_bRandom = 0;
-
-int iCount = 1;
-int iThreads = 1;
-HANDLE hThreads[MAX_THREADS];
-
-#ifndef MIN
-#define MIN(a,b) (((a)<(b)) ? (a) : (b))
-#endif
-
-DWORD PALAPI EventTestThread(PVOID pArg)
-{
- BOOL bRet;
- DWORD dwRet;
- HANDLE hEvent[2];
- HANDLE (*prgHandles)[] = (HANDLE (*)[])pArg;
-
- Trace("[EventTestThread] Starting\n");
-
- bRet = DuplicateHandle(GetCurrentProcess(), (*prgHandles)[0], GetCurrentProcess(),
- &hEvent[0], 0, FALSE, DUPLICATE_SAME_ACCESS);
- bRet &= DuplicateHandle(GetCurrentProcess(), (*prgHandles)[1], GetCurrentProcess(),
- &hEvent[1], 0, FALSE, DUPLICATE_SAME_ACCESS);
- if (FALSE == bRet)
- {
- Fail("[EventTestThread] Failed to duplicate handles\n");
- }
-
- Sleep(1000);
- bRet = SetEvent(hEvent[1]);
- if (FALSE == bRet)
- {
- Fail("SetEvent failed\n");
- Fail("[EventTestThread] SetEvent failed [GetLastError()=%u]\n",
- GetLastError());
- }
-
- dwRet = WaitForSingleObject(hEvent[1], INFINITE);
- if (WAIT_FAILED == dwRet)
- {
- Fail("[EventTestThread] WaitForMultipleObjects failed [GetLastError()=%u]\n",
- GetLastError());
- }
-
- Sleep(1000);
- bRet = SetEvent(hEvent[0]);
- if (FALSE == bRet)
- {
- Fail("[EventTestThread] SetEvent failed [GetLastError()=%u]\n",
- GetLastError());
- }
-
- Sleep(1000);
- bRet = SetEvent(hEvent[1]);
- if (FALSE == bRet)
- {
- Fail("[EventTestThread] SetEvent failed [GetLastError()=%u]\n",
- GetLastError());
- }
-
- CloseHandle(hEvent[0]);
- CloseHandle(hEvent[1]);
-
- Trace("[EventTestThread] Done\n");
- return 0;
-}
-
-DWORD PALAPI MutexTestThread(PVOID pArg)
-{
- BOOL bRet;
- DWORD dwRet;
- HANDLE hMutex;
-
- Trace("[MutexTestThread] Starting\n");
-
- bRet = DuplicateHandle(GetCurrentProcess(), (HANDLE)pArg, GetCurrentProcess(), &hMutex,
- 0, FALSE, DUPLICATE_SAME_ACCESS);
- if (FALSE == bRet)
- {
- Fail("[EventTestThread] DuplicateHandle failed [GetLastError()=%u]\n",
- GetLastError());
- }
-
- dwRet = WaitForSingleObject(hMutex, INFINITE);
- if (WAIT_FAILED == dwRet)
- {
- Fail("[EventTestThread] WaitForMultipleObjects failed [GetLastError()=%u]\n",
- GetLastError());
- }
-
- Sleep(1000);
- CloseHandle(hMutex);
-
- Trace("[MutexTestThread] Done\n");
-
- return 0;
-}
-
-DWORD PALAPI TestThread(PVOID pArg)
-{
- BOOL bRet;
- DWORD dwRet;
- PROCESS_INFORMATION pi;
- STARTUPINFO si;
- HANDLE hNamedEvent;
- HANDLE hEvent[2] = { 0, 0 };
- HANDLE hMutex = 0;
- HANDLE hSemaphore = 0;
- HANDLE hObjs[2];
- DWORD dwThreadNum;
- DWORD dwSlaveThreadTid = 0;
- HANDLE hThread;
- int i, iCnt, iRet;
- char szTestName[128];
- char szCmd[128];
- char szEventName[128] = { 0 };
- char szMutexName[128] = { 0 };
- char szSemName[128] = { 0 };
- WCHAR wszEventName[128] = { 0 };
- WCHAR wszMutexName[128] = { 0 };
- WCHAR wszSemName[128] = { 0 };
- BOOL bMutex = g_bMutex;
- BOOL bEvent = g_bEvent;
- BOOL bNamedEvent = g_bNamedEvent;
- BOOL bSemaphore = g_bSemaphore;
- BOOL bProcess = g_bProcess;
- BOOL bLocalWaitAll = g_bLocalWaitAll;
- BOOL bRemoteWaitAll = g_bRemoteWaitAll;
- int iDesiredExitCode;
-
- dwThreadNum = (DWORD)pArg;
-
- _snprintf (szTestName, 128, "Test6_%u", dwThreadNum);
- szTestName[127] = 0;
-
- _snprintf(szEventName, 128, "%s_Event", szTestName);
- szEventName[127] = 0;
- _snprintf(szMutexName, 128, "%s_Mutex", szTestName);
- szMutexName[127] = 0;
- _snprintf(szSemName, 128, "%s_Semaphore", szTestName);
- szSemName[127] = 0;
-
- iRet = MultiByteToWideChar(CP_ACP, 0, szEventName, strlen(szEventName)+1, wszEventName, 128);
- iRet &= MultiByteToWideChar(CP_ACP, 0, szMutexName, strlen(szMutexName)+1, wszMutexName, 128);
- iRet &= MultiByteToWideChar(CP_ACP, 0, szSemName, strlen(szSemName)+1, wszSemName, 128);
-
- if (0 == iRet)
- {
- Fail("[TestThread] Failed to convert strings\n");
- }
-
- Trace("[TestThread] TestName=%s Event: %S, Mutex: %S, Semaphore = %S\n",
- szTestName, wszEventName, wszMutexName, wszSemName);
-
- hEvent[0] = CreateEventA(NULL, FALSE, FALSE, NULL);
- hEvent[1] = CreateEventA(NULL, FALSE, FALSE, NULL);
-
- hNamedEvent = CreateEventW(NULL, FALSE, FALSE, wszEventName);
- hMutex = CreateMutexW(NULL, FALSE, wszMutexName);
- hSemaphore = CreateSemaphoreW(NULL, 0, 256, wszSemName);
-
- if (NULL == hEvent[0] || NULL == hEvent[1] || NULL == hMutex ||
- NULL == hNamedEvent || NULL == hSemaphore)
- {
- Fail("[TestThread] Failed to create objects "
- "[hNamedEvent=%p hMutex=%p hSemaphore=%p]\n",
- (VOID*)hNamedEvent, (VOID*)hMutex, (VOID*)hSemaphore);
- }
-
- for (iCnt=0; iCnt<iCount; iCnt++)
- {
- if (g_bRandom)
- {
- int iRnd;
-
- bMutex = 0;
- bEvent = 0;
- bNamedEvent = 0;
- bSemaphore = 0;
- bProcess = 0;
- bLocalWaitAll = 0;
- bRemoteWaitAll = 0;
-
- iRnd = rand() % 7;
- switch(iRnd)
- {
- case 0:
- bMutex = 1;
- break;
- case 1:
- bEvent = 1;
- break;
- case 2:
- bNamedEvent = 1;
- break;
- case 3:
- bSemaphore = 1;
- break;
- case 4:
- bProcess = 1;
- break;
- case 5:
- bLocalWaitAll = 1;
- break;
- case 6:
- bRemoteWaitAll = 1;
- break;
- }
- }
-
- if (bEvent)
- {
- Trace("======================================================================\n");
- Trace("Local unnamed event test\n");
- Trace("----------------------------------------\n");
- hThread = CreateThread(NULL, 0, EventTestThread, (PVOID)hEvent, 0, &dwSlaveThreadTid);
- if (NULL == hThread)
- {
- Fail("Failed to create thread\n");
- }
-
- hObjs[0] = hEvent[0];
- dwRet = WaitForMultipleObjects(1, hObjs, FALSE, INFINITE);
- if (WAIT_FAILED == dwRet)
- {
- Fail("WaitForMultipleObjects failed\n");
- }
-
- hObjs[0] = hThread;
- dwRet = WaitForMultipleObjects(1, hObjs, FALSE, INFINITE);
- if (WAIT_FAILED == dwRet)
- {
- Fail("WaitForMultipleObjects failed\n");
- }
-
- CloseHandle(hThread);
- Trace("Local unnamed event test done \n");
- Trace("======================================================================\n");
- }
-
- if (bMutex)
- {
- Trace("======================================================================\n");
- Trace("Mutex with remote thread awakening test\n");
- Trace("----------------------------------------\n");
-
- hThread = CreateThread(NULL, 0, MutexTestThread, (PVOID)hMutex, 0, &dwSlaveThreadTid);
- if (NULL == hThread)
- {
- Fail("Failed to create thread\n");
- }
-
- Sleep(1000);
-
- hObjs[0] = hMutex;
-
- for (i=0;i<10;i++)
- {
- dwRet = WaitForMultipleObjects(1, hObjs, FALSE, INFINITE);
- if (WAIT_FAILED == dwRet)
- {
- Fail("WaitForMultipleObjects failed [dwRet=%x GetLastError()=%d\n",
- dwRet, GetLastError());
- }
- }
-
- hObjs[0] = hThread;
- dwRet = WaitForMultipleObjects(1, hObjs, FALSE, INFINITE);
- if (WAIT_FAILED == dwRet)
- {
- Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n",
- GetLastError());
- }
-
- for (i=0;i<10;i++)
- {
- bRet = ReleaseMutex(hMutex);
- if (FALSE == bRet)
- {
- Fail("ReleaseMutex failed [GetLastError()=%u]\n",
- GetLastError());
- }
- }
-
- CloseHandle(hThread);
- Trace("Mutex with remote thread awakening test done\n");
- Trace("======================================================================\n");
- }
-
- if (bNamedEvent)
- {
- Trace("======================================================================\n");
- Trace("Named event with remote thread awakening test\n");
- Trace("----------------------------------------\n");
-
- ZeroMemory ( &si, sizeof(si) );
- si.cb = sizeof(si);
- ZeroMemory ( &pi, sizeof(pi) );
-
- _snprintf (szCmd, 128, "child6 -event %s", szTestName);
- szCmd[127] = 0;
-
- bRet = CreateProcessA(NULL, szCmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
- if (FALSE == bRet)
- {
- Fail("CreateProcess failed [GetLastError()=%u]\n",
- GetLastError());
- }
-
- hObjs[0] = pi.hProcess;
- hObjs[1] = hNamedEvent;
-
- dwRet = WaitForMultipleObjects(2, hObjs, FALSE, INFINITE);
- if (1 != dwRet)
- {
- Fail("WaitForMultipleObjects failed [dwRet=%u GetLastError()=%u]\n",
- dwRet, GetLastError());
- }
-
- dwRet = WaitForSingleObject(pi.hProcess, INFINITE);
- if (WAIT_FAILED == dwRet)
- {
- Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n",
- GetLastError());
- }
- Trace("Named event with remote thread awakening test done\n");
- Trace("======================================================================\n");
- }
-
- if (bSemaphore)
- {
- Trace("======================================================================\n");
- Trace("Semaphore with remote thread awakening test\n");
- Trace("----------------------------------------\n");
-
- ZeroMemory ( &si, sizeof(si) );
- si.cb = sizeof(si);
- ZeroMemory ( &pi, sizeof(pi) );
-
- _snprintf (szCmd, 128, "child6 -semaphore %s", szTestName);
- szCmd[127] = 0;
-
- bRet = CreateProcessA(NULL, szCmd, NULL, NULL, FALSE,
- 0, NULL, NULL, &si, &pi);
- if (FALSE == bRet)
- {
- Fail("CreateProcessA failed [GetLastError()=%u]\n",
- GetLastError());
- }
-
- Trace("Setting event %s\n", szEventName);
- bRet = SetEvent(hNamedEvent);
- if (FALSE == bRet)
- {
- Fail("[child] SetEvent failed [GetLastError()=%u]\n",
- GetLastError());
- }
-
- Trace("Going to wait on semaphore %s\n", szSemName);
-
-
- hObjs[0] = pi.hProcess;
- hObjs[0] = hEvent[0];
- hObjs[1] = hSemaphore;
- for (i=0;i<10;i++)
- {
- dwRet = WaitForMultipleObjects(2, hObjs, FALSE, INFINITE);
- if (1 != dwRet)
- {
- Trace("WaitForMultipleObjects failed [tid=%u dwRet=%u GetLastError()=%u]\n",
- GetCurrentThreadId(), dwRet, GetLastError());
- DebugBreak();
- }
- }
-
- dwRet = WaitForSingleObject(pi.hProcess, INFINITE);
- if (WAIT_FAILED == dwRet)
- {
- Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n",
- GetLastError());
- }
- Trace("Semaphore with remote thread awakening test done\n");
- Trace("======================================================================\n");
- }
-
- if (bProcess)
- {
- DWORD dwExitCode;
-
- Trace("======================================================================\n");
- Trace("Process wait test\n");
- Trace("----------------------------------------\n");
-
- iDesiredExitCode = rand() % 0xFF;
-
- ZeroMemory ( &si, sizeof(si) );
- si.cb = sizeof(si);
- ZeroMemory ( &pi, sizeof(pi) );
-
- _snprintf (szCmd, 128, "child6 -mutex %s -exitcode %d", szTestName, iDesiredExitCode);
- szCmd[127] = 0;
-
- bRet = CreateProcessA(NULL, szCmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
- if (FALSE == bRet)
- {
- Fail("CreateProcess failed [GetLastError()=%u]\n",
- GetLastError());
- }
-
- Trace("Going to wait on event %s\n", szEventName);
- dwRet = WaitForSingleObject(hNamedEvent, INFINITE);
- if (WAIT_FAILED == dwRet)
- {
- Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n",
- GetLastError());
- }
-
- hObjs[0] = hEvent[0]; // dummy, this is a local event
- hObjs[1] = hMutex;
-
- dwRet = WaitForMultipleObjects(2, hObjs, FALSE, INFINITE);
- if (WAIT_FAILED == dwRet)
- {
- Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n",
- GetLastError());
- }
- if (1 == dwRet || (1 + WAIT_ABANDONED_0) == dwRet)
- {
- bRet = ReleaseMutex(hMutex);
- if (FALSE == bRet)
- {
- Fail("ReleaseMutex failed [GetLastError()=%u]\n",
- GetLastError());
- }
- }
-
- dwRet = WaitForSingleObject(pi.hProcess, INFINITE);
- if (WAIT_FAILED == dwRet)
- {
- Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n",
- GetLastError());
- }
-
- if (!GetExitCodeProcess(pi.hProcess, &dwExitCode))
- {
- Trace("GetExitCodeProcess call failed LastError:(%u)\n",
- GetLastError());
- dwExitCode = FAIL;
- }
-
- if (iDesiredExitCode != dwExitCode)
- {
- Fail("Wrong return code: %u [%d]\n", dwExitCode, iDesiredExitCode);
- }
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
- Trace("Process wait test done\n");
- Trace("======================================================================\n");
- }
-
- if (bLocalWaitAll)
- {
- Trace("======================================================================\n");
- Trace("WaitAll with local thread awakening test\n");
- Trace("----------------------------------------\n");
-
- hThread = CreateThread(NULL, 0, EventTestThread, (PVOID)hEvent, 0, &dwSlaveThreadTid);
- if (NULL == hThread)
- {
- Fail("CreateThread failed [GetLastError()=%u]\n",
- GetLastError());
- }
-
- dwRet = WaitForMultipleObjects(2, hEvent, TRUE, INFINITE);
- if (WAIT_FAILED == dwRet)
- {
- Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n",
- GetLastError());
- }
-
- hObjs[0] = hThread;
- dwRet = WaitForMultipleObjects(1, hObjs, FALSE, INFINITE);
- if (WAIT_FAILED == dwRet)
- {
- Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n",
- GetLastError());
- }
-
- CloseHandle(hThread);
- Trace("WaitAll with local thread awakening test done\n");
- Trace("======================================================================\n");
- }
-
- if (bRemoteWaitAll)
- {
- Trace("======================================================================\n");
- Trace("WaitAll with remote thread awakening test\n");
- Trace("----------------------------------------\n");
-
- ZeroMemory ( &si, sizeof(si) );
- si.cb = sizeof(si);
- ZeroMemory ( &pi, sizeof(pi) );
-
- _snprintf (szCmd, 128, "child6 -mutex_and_named_event %s", szTestName);
- szCmd[127] = 0;
-
- bRet = CreateProcessA(NULL, szCmd, NULL, NULL, FALSE,
- 0, NULL, NULL, &si, &pi);
- if (FALSE == bRet)
- {
- Fail("CreateProcess failed [GetLastError()=%u]\n",
- GetLastError());
- }
-
- Sleep(1000);
-
- hObjs[0] = hMutex;
- hObjs[1] = hNamedEvent;
-
- dwRet = WaitForMultipleObjects(2, hObjs, TRUE, INFINITE);
- if (WAIT_FAILED == dwRet)
- {
- Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n",
- GetLastError());
- }
-
- bRet = ReleaseMutex(hMutex);
- if (FALSE == bRet)
- {
- Fail("ReleaseMutex failed [GetLastError()=%u]\n",
- GetLastError());
- }
-
- dwRet = WaitForSingleObject(pi.hProcess, INFINITE);
- if (WAIT_FAILED == dwRet)
- {
- Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n",
- GetLastError());
- }
-
- CloseHandle(pi.hProcess);
- CloseHandle(pi.hThread);
- Trace("WaitAll with remote thread awakening test done\n");
- Trace("======================================================================\n");
- }
- }
-
- return 0;
-}
-
-int __cdecl main(int argc, char **argv)
-{
- DWORD dwRet;
- DWORD dwSlaveThreadTid = 0;
- int i, iCnt;
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return ( FAIL );
- }
-
- srand(time(NULL) * GetCurrentProcessId());
-
- if (argc == 1)
- {
- g_bMutex = 1;
- g_bEvent = 1;
- g_bNamedEvent = 1;
- g_bSemaphore = 1;
- g_bProcess = 1;
- g_bLocalWaitAll = 1;
- g_bRemoteWaitAll = 1;
- }
- else
- {
- for (i=1;i<argc;i++)
- {
- if (0 == strcmp(argv[i], "-mutex"))
- {
- g_bMutex = 1;
- }
- else if (0 == strcmp(argv[i], "-event"))
- {
- g_bEvent = 1;
- }
- else if (0 == strcmp(argv[i], "-namedevent"))
- {
- g_bNamedEvent = 1;
- }
- else if (0 == strcmp(argv[i], "-semaphore"))
- {
- g_bSemaphore = 1;
- }
- else if (0 == strcmp(argv[i], "-process"))
- {
- g_bProcess = 1;
- }
- else if (0 == strcmp(argv[i], "-localwaitall"))
- {
- g_bLocalWaitAll = 1;
- }
- else if (0 == strcmp(argv[i], "-remotewaitall"))
- {
- g_bRemoteWaitAll = 1;
- }
- else if (0 == strcmp(argv[i], "-all"))
- {
- g_bMutex = 1;
- g_bEvent = 1;
- g_bNamedEvent = 1;
- g_bSemaphore = 1;
- g_bProcess = 1;
- g_bLocalWaitAll = 1;
- g_bRemoteWaitAll = 1;
- }
- else if (0 == strcmp(argv[i], "-random"))
- {
- g_bRandom = 1;
- }
- else if ((0 == strcmp(argv[i], "-count")) && (argc > i+1))
- {
- i++;
- iCnt = atoi(argv[i]);
- if (iCnt > 0 && iCnt < MAX_COUNT)
- {
- iCount = iCnt;
- }
- }
- else if ((0 == strcmp(argv[i], "-threads")) && (argc > i+1))
- {
- i++;
- iCnt = atoi(argv[i]);
- if (iCnt > 0 && iCnt <= MAX_THREADS)
- {
- iThreads = iCnt;
- }
- }
- else
- {
- Trace("Unknown option %s ignored\n", argv[i]);
- }
- }
- }
-
-
- iCnt = 0;
- for (i=0;i<iThreads;i++)
- {
- hThreads[iCnt] = CreateThread(NULL, 0, TestThread, (VOID*)iCnt, 0, &dwSlaveThreadTid);
- if (NULL == hThreads[iCnt])
- {
- Trace("Failed to create thread\n");
- }
- else
- {
- iCnt++;
- }
- }
-
- if (0 == iCnt)
- {
- Fail("Can't create any thread\n");
- }
-
- for (i=0; i<iCnt; i+=64)
- {
- dwRet = WaitForMultipleObjects(MIN(64, iCnt-i), &hThreads[i], TRUE, INFINITE);
- if (WAIT_FAILED == dwRet)
- {
- Fail("WaitForMultipleObjects failed [dwRet=%u GetLastError()=%u iCnt=%d i=%d]\n",
- dwRet, GetLastError(), iCnt, i);
- }
- }
-
-
- for (i=0; i<iCnt; i++)
- {
- CloseHandle(hThreads[i]);
- }
-
- PAL_Terminate();
- return PASS;
-}
diff --git a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test6/test6.cpp b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test6/test6.cpp
new file mode 100644
index 0000000000..d5e3137899
--- /dev/null
+++ b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test6/test6.cpp
@@ -0,0 +1,709 @@
+// Licensed to the .NET Foundation under one or more 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: test6.c
+**
+** Purpose: Test for WaitForMultipleObjectsEx in multiple
+** scenarios
+**
+**
+**=========================================================*/
+
+#include <palsuite.h>
+
+#define MAX_COUNT 10000
+#define MAX_THREADS 256
+
+BOOL g_bMutex = 0;
+BOOL g_bEvent = 0;
+BOOL g_bNamedEvent = 0;
+BOOL g_bSemaphore = 0;
+BOOL g_bProcess = 0;
+BOOL g_bLocalWaitAll = 0;
+BOOL g_bRemoteWaitAll = 0;
+BOOL g_bRandom = 0;
+
+int iCount = 1;
+int iThreads = 1;
+HANDLE hThreads[MAX_THREADS];
+
+#ifndef MIN
+#define MIN(a,b) (((a)<(b)) ? (a) : (b))
+#endif
+
+DWORD PALAPI EventTestThread(PVOID pArg)
+{
+ BOOL bRet;
+ DWORD dwRet;
+ HANDLE hEvent[2];
+ HANDLE (*prgHandles)[] = (HANDLE (*)[])pArg;
+
+ Trace("[EventTestThread] Starting\n");
+
+ bRet = DuplicateHandle(GetCurrentProcess(), (*prgHandles)[0], GetCurrentProcess(),
+ &hEvent[0], 0, FALSE, DUPLICATE_SAME_ACCESS);
+ bRet &= DuplicateHandle(GetCurrentProcess(), (*prgHandles)[1], GetCurrentProcess(),
+ &hEvent[1], 0, FALSE, DUPLICATE_SAME_ACCESS);
+ if (FALSE == bRet)
+ {
+ Fail("[EventTestThread] Failed to duplicate handles\n");
+ }
+
+ Sleep(1000);
+ bRet = SetEvent(hEvent[1]);
+ if (FALSE == bRet)
+ {
+ Fail("SetEvent failed\n");
+ Fail("[EventTestThread] SetEvent failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+
+ dwRet = WaitForSingleObject(hEvent[1], INFINITE);
+ if (WAIT_FAILED == dwRet)
+ {
+ Fail("[EventTestThread] WaitForMultipleObjects failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+
+ Sleep(1000);
+ bRet = SetEvent(hEvent[0]);
+ if (FALSE == bRet)
+ {
+ Fail("[EventTestThread] SetEvent failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+
+ Sleep(1000);
+ bRet = SetEvent(hEvent[1]);
+ if (FALSE == bRet)
+ {
+ Fail("[EventTestThread] SetEvent failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+
+ CloseHandle(hEvent[0]);
+ CloseHandle(hEvent[1]);
+
+ Trace("[EventTestThread] Done\n");
+ return 0;
+}
+
+DWORD PALAPI MutexTestThread(PVOID pArg)
+{
+ BOOL bRet;
+ DWORD dwRet;
+ HANDLE hMutex;
+
+ Trace("[MutexTestThread] Starting\n");
+
+ bRet = DuplicateHandle(GetCurrentProcess(), (HANDLE)pArg, GetCurrentProcess(), &hMutex,
+ 0, FALSE, DUPLICATE_SAME_ACCESS);
+ if (FALSE == bRet)
+ {
+ Fail("[EventTestThread] DuplicateHandle failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+
+ dwRet = WaitForSingleObject(hMutex, INFINITE);
+ if (WAIT_FAILED == dwRet)
+ {
+ Fail("[EventTestThread] WaitForMultipleObjects failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+
+ Sleep(1000);
+ CloseHandle(hMutex);
+
+ Trace("[MutexTestThread] Done\n");
+
+ return 0;
+}
+
+DWORD PALAPI TestThread(PVOID pArg)
+{
+ BOOL bRet;
+ DWORD dwRet;
+ PROCESS_INFORMATION pi;
+ STARTUPINFO si;
+ HANDLE hNamedEvent;
+ HANDLE hEvent[2] = { 0, 0 };
+ HANDLE hMutex = 0;
+ HANDLE hSemaphore = 0;
+ HANDLE hObjs[2];
+ DWORD dwThreadNum;
+ DWORD dwSlaveThreadTid = 0;
+ HANDLE hThread;
+ int i, iCnt, iRet;
+ char szTestName[128];
+ char szCmd[128];
+ char szEventName[128] = { 0 };
+ char szMutexName[128] = { 0 };
+ char szSemName[128] = { 0 };
+ WCHAR wszEventName[128] = { 0 };
+ WCHAR wszMutexName[128] = { 0 };
+ WCHAR wszSemName[128] = { 0 };
+ BOOL bMutex = g_bMutex;
+ BOOL bEvent = g_bEvent;
+ BOOL bNamedEvent = g_bNamedEvent;
+ BOOL bSemaphore = g_bSemaphore;
+ BOOL bProcess = g_bProcess;
+ BOOL bLocalWaitAll = g_bLocalWaitAll;
+ BOOL bRemoteWaitAll = g_bRemoteWaitAll;
+ int iDesiredExitCode;
+
+ dwThreadNum = (DWORD)pArg;
+
+ sprintf_s (szTestName, 128, "Test6_%u", dwThreadNum);
+ szTestName[127] = 0;
+
+ sprintf_s(szEventName, 128, "%s_Event", szTestName);
+ szEventName[127] = 0;
+ sprintf_s(szMutexName, 128, "%s_Mutex", szTestName);
+ szMutexName[127] = 0;
+ sprintf_s(szSemName, 128, "%s_Semaphore", szTestName);
+ szSemName[127] = 0;
+
+ iRet = MultiByteToWideChar(CP_ACP, 0, szEventName, strlen(szEventName)+1, wszEventName, 128);
+ iRet &= MultiByteToWideChar(CP_ACP, 0, szMutexName, strlen(szMutexName)+1, wszMutexName, 128);
+ iRet &= MultiByteToWideChar(CP_ACP, 0, szSemName, strlen(szSemName)+1, wszSemName, 128);
+
+ if (0 == iRet)
+ {
+ Fail("[TestThread] Failed to convert strings\n");
+ }
+
+ Trace("[TestThread] TestName=%s Event: %S, Mutex: %S, Semaphore = %S\n",
+ szTestName, wszEventName, wszMutexName, wszSemName);
+
+ hEvent[0] = CreateEventA(NULL, FALSE, FALSE, NULL);
+ hEvent[1] = CreateEventA(NULL, FALSE, FALSE, NULL);
+
+ hNamedEvent = CreateEventW(NULL, FALSE, FALSE, wszEventName);
+ hMutex = CreateMutexW(NULL, FALSE, wszMutexName);
+ hSemaphore = CreateSemaphoreW(NULL, 0, 256, wszSemName);
+
+ if (NULL == hEvent[0] || NULL == hEvent[1] || NULL == hMutex ||
+ NULL == hNamedEvent || NULL == hSemaphore)
+ {
+ Fail("[TestThread] Failed to create objects "
+ "[hNamedEvent=%p hMutex=%p hSemaphore=%p]\n",
+ (VOID*)hNamedEvent, (VOID*)hMutex, (VOID*)hSemaphore);
+ }
+
+ for (iCnt=0; iCnt<iCount; iCnt++)
+ {
+ if (g_bRandom)
+ {
+ int iRnd;
+
+ bMutex = 0;
+ bEvent = 0;
+ bNamedEvent = 0;
+ bSemaphore = 0;
+ bProcess = 0;
+ bLocalWaitAll = 0;
+ bRemoteWaitAll = 0;
+
+ iRnd = rand() % 7;
+ switch(iRnd)
+ {
+ case 0:
+ bMutex = 1;
+ break;
+ case 1:
+ bEvent = 1;
+ break;
+ case 2:
+ bNamedEvent = 1;
+ break;
+ case 3:
+ bSemaphore = 1;
+ break;
+ case 4:
+ bProcess = 1;
+ break;
+ case 5:
+ bLocalWaitAll = 1;
+ break;
+ case 6:
+ bRemoteWaitAll = 1;
+ break;
+ }
+ }
+
+ if (bEvent)
+ {
+ Trace("======================================================================\n");
+ Trace("Local unnamed event test\n");
+ Trace("----------------------------------------\n");
+ hThread = CreateThread(NULL, 0, EventTestThread, (PVOID)hEvent, 0, &dwSlaveThreadTid);
+ if (NULL == hThread)
+ {
+ Fail("Failed to create thread\n");
+ }
+
+ hObjs[0] = hEvent[0];
+ dwRet = WaitForMultipleObjects(1, hObjs, FALSE, INFINITE);
+ if (WAIT_FAILED == dwRet)
+ {
+ Fail("WaitForMultipleObjects failed\n");
+ }
+
+ hObjs[0] = hThread;
+ dwRet = WaitForMultipleObjects(1, hObjs, FALSE, INFINITE);
+ if (WAIT_FAILED == dwRet)
+ {
+ Fail("WaitForMultipleObjects failed\n");
+ }
+
+ CloseHandle(hThread);
+ Trace("Local unnamed event test done \n");
+ Trace("======================================================================\n");
+ }
+
+ if (bMutex)
+ {
+ Trace("======================================================================\n");
+ Trace("Mutex with remote thread awakening test\n");
+ Trace("----------------------------------------\n");
+
+ hThread = CreateThread(NULL, 0, MutexTestThread, (PVOID)hMutex, 0, &dwSlaveThreadTid);
+ if (NULL == hThread)
+ {
+ Fail("Failed to create thread\n");
+ }
+
+ Sleep(1000);
+
+ hObjs[0] = hMutex;
+
+ for (i=0;i<10;i++)
+ {
+ dwRet = WaitForMultipleObjects(1, hObjs, FALSE, INFINITE);
+ if (WAIT_FAILED == dwRet)
+ {
+ Fail("WaitForMultipleObjects failed [dwRet=%x GetLastError()=%d\n",
+ dwRet, GetLastError());
+ }
+ }
+
+ hObjs[0] = hThread;
+ dwRet = WaitForMultipleObjects(1, hObjs, FALSE, INFINITE);
+ if (WAIT_FAILED == dwRet)
+ {
+ Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+
+ for (i=0;i<10;i++)
+ {
+ bRet = ReleaseMutex(hMutex);
+ if (FALSE == bRet)
+ {
+ Fail("ReleaseMutex failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+ }
+
+ CloseHandle(hThread);
+ Trace("Mutex with remote thread awakening test done\n");
+ Trace("======================================================================\n");
+ }
+
+ if (bNamedEvent)
+ {
+ Trace("======================================================================\n");
+ Trace("Named event with remote thread awakening test\n");
+ Trace("----------------------------------------\n");
+
+ ZeroMemory ( &si, sizeof(si) );
+ si.cb = sizeof(si);
+ ZeroMemory ( &pi, sizeof(pi) );
+
+ sprintf_s (szCmd, 128, "child6 -event %s", szTestName);
+ szCmd[127] = 0;
+
+ bRet = CreateProcessA(NULL, szCmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
+ if (FALSE == bRet)
+ {
+ Fail("CreateProcess failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+
+ hObjs[0] = pi.hProcess;
+ hObjs[1] = hNamedEvent;
+
+ dwRet = WaitForMultipleObjects(2, hObjs, FALSE, INFINITE);
+ if (1 != dwRet)
+ {
+ Fail("WaitForMultipleObjects failed [dwRet=%u GetLastError()=%u]\n",
+ dwRet, GetLastError());
+ }
+
+ dwRet = WaitForSingleObject(pi.hProcess, INFINITE);
+ if (WAIT_FAILED == dwRet)
+ {
+ Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+ Trace("Named event with remote thread awakening test done\n");
+ Trace("======================================================================\n");
+ }
+
+ if (bSemaphore)
+ {
+ Trace("======================================================================\n");
+ Trace("Semaphore with remote thread awakening test\n");
+ Trace("----------------------------------------\n");
+
+ ZeroMemory ( &si, sizeof(si) );
+ si.cb = sizeof(si);
+ ZeroMemory ( &pi, sizeof(pi) );
+
+ sprintf_s (szCmd, 128, "child6 -semaphore %s", szTestName);
+ szCmd[127] = 0;
+
+ bRet = CreateProcessA(NULL, szCmd, NULL, NULL, FALSE,
+ 0, NULL, NULL, &si, &pi);
+ if (FALSE == bRet)
+ {
+ Fail("CreateProcessA failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+
+ Trace("Setting event %s\n", szEventName);
+ bRet = SetEvent(hNamedEvent);
+ if (FALSE == bRet)
+ {
+ Fail("[child] SetEvent failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+
+ Trace("Going to wait on semaphore %s\n", szSemName);
+
+
+ hObjs[0] = pi.hProcess;
+ hObjs[0] = hEvent[0];
+ hObjs[1] = hSemaphore;
+ for (i=0;i<10;i++)
+ {
+ dwRet = WaitForMultipleObjects(2, hObjs, FALSE, INFINITE);
+ if (1 != dwRet)
+ {
+ Trace("WaitForMultipleObjects failed [tid=%u dwRet=%u GetLastError()=%u]\n",
+ GetCurrentThreadId(), dwRet, GetLastError());
+ DebugBreak();
+ }
+ }
+
+ dwRet = WaitForSingleObject(pi.hProcess, INFINITE);
+ if (WAIT_FAILED == dwRet)
+ {
+ Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+ Trace("Semaphore with remote thread awakening test done\n");
+ Trace("======================================================================\n");
+ }
+
+ if (bProcess)
+ {
+ DWORD dwExitCode;
+
+ Trace("======================================================================\n");
+ Trace("Process wait test\n");
+ Trace("----------------------------------------\n");
+
+ iDesiredExitCode = rand() % 0xFF;
+
+ ZeroMemory ( &si, sizeof(si) );
+ si.cb = sizeof(si);
+ ZeroMemory ( &pi, sizeof(pi) );
+
+ sprintf_s (szCmd, 128, "child6 -mutex %s -exitcode %d", szTestName, iDesiredExitCode);
+ szCmd[127] = 0;
+
+ bRet = CreateProcessA(NULL, szCmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
+ if (FALSE == bRet)
+ {
+ Fail("CreateProcess failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+
+ Trace("Going to wait on event %s\n", szEventName);
+ dwRet = WaitForSingleObject(hNamedEvent, INFINITE);
+ if (WAIT_FAILED == dwRet)
+ {
+ Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+
+ hObjs[0] = hEvent[0]; // dummy, this is a local event
+ hObjs[1] = hMutex;
+
+ dwRet = WaitForMultipleObjects(2, hObjs, FALSE, INFINITE);
+ if (WAIT_FAILED == dwRet)
+ {
+ Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+ if (1 == dwRet || (1 + WAIT_ABANDONED_0) == dwRet)
+ {
+ bRet = ReleaseMutex(hMutex);
+ if (FALSE == bRet)
+ {
+ Fail("ReleaseMutex failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+ }
+
+ dwRet = WaitForSingleObject(pi.hProcess, INFINITE);
+ if (WAIT_FAILED == dwRet)
+ {
+ Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+
+ if (!GetExitCodeProcess(pi.hProcess, &dwExitCode))
+ {
+ Trace("GetExitCodeProcess call failed LastError:(%u)\n",
+ GetLastError());
+ dwExitCode = FAIL;
+ }
+
+ if (iDesiredExitCode != dwExitCode)
+ {
+ Fail("Wrong return code: %u [%d]\n", dwExitCode, iDesiredExitCode);
+ }
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ Trace("Process wait test done\n");
+ Trace("======================================================================\n");
+ }
+
+ if (bLocalWaitAll)
+ {
+ Trace("======================================================================\n");
+ Trace("WaitAll with local thread awakening test\n");
+ Trace("----------------------------------------\n");
+
+ hThread = CreateThread(NULL, 0, EventTestThread, (PVOID)hEvent, 0, &dwSlaveThreadTid);
+ if (NULL == hThread)
+ {
+ Fail("CreateThread failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+
+ dwRet = WaitForMultipleObjects(2, hEvent, TRUE, INFINITE);
+ if (WAIT_FAILED == dwRet)
+ {
+ Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+
+ hObjs[0] = hThread;
+ dwRet = WaitForMultipleObjects(1, hObjs, FALSE, INFINITE);
+ if (WAIT_FAILED == dwRet)
+ {
+ Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+
+ CloseHandle(hThread);
+ Trace("WaitAll with local thread awakening test done\n");
+ Trace("======================================================================\n");
+ }
+
+ if (bRemoteWaitAll)
+ {
+ Trace("======================================================================\n");
+ Trace("WaitAll with remote thread awakening test\n");
+ Trace("----------------------------------------\n");
+
+ ZeroMemory ( &si, sizeof(si) );
+ si.cb = sizeof(si);
+ ZeroMemory ( &pi, sizeof(pi) );
+
+ sprintf_s (szCmd, 128, "child6 -mutex_and_named_event %s", szTestName);
+ szCmd[127] = 0;
+
+ bRet = CreateProcessA(NULL, szCmd, NULL, NULL, FALSE,
+ 0, NULL, NULL, &si, &pi);
+ if (FALSE == bRet)
+ {
+ Fail("CreateProcess failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+
+ Sleep(1000);
+
+ hObjs[0] = hMutex;
+ hObjs[1] = hNamedEvent;
+
+ dwRet = WaitForMultipleObjects(2, hObjs, TRUE, INFINITE);
+ if (WAIT_FAILED == dwRet)
+ {
+ Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+
+ bRet = ReleaseMutex(hMutex);
+ if (FALSE == bRet)
+ {
+ Fail("ReleaseMutex failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+
+ dwRet = WaitForSingleObject(pi.hProcess, INFINITE);
+ if (WAIT_FAILED == dwRet)
+ {
+ Fail("WaitForMultipleObjects failed [GetLastError()=%u]\n",
+ GetLastError());
+ }
+
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ Trace("WaitAll with remote thread awakening test done\n");
+ Trace("======================================================================\n");
+ }
+ }
+
+ return 0;
+}
+
+int __cdecl main(int argc, char **argv)
+{
+ DWORD dwRet;
+ DWORD dwSlaveThreadTid = 0;
+ int i, iCnt;
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return ( FAIL );
+ }
+
+ srand(time(NULL) * GetCurrentProcessId());
+
+ if (argc == 1)
+ {
+ g_bMutex = 1;
+ g_bEvent = 1;
+ g_bNamedEvent = 1;
+ g_bSemaphore = 1;
+ g_bProcess = 1;
+ g_bLocalWaitAll = 1;
+ g_bRemoteWaitAll = 1;
+ }
+ else
+ {
+ for (i=1;i<argc;i++)
+ {
+ if (0 == strcmp(argv[i], "-mutex"))
+ {
+ g_bMutex = 1;
+ }
+ else if (0 == strcmp(argv[i], "-event"))
+ {
+ g_bEvent = 1;
+ }
+ else if (0 == strcmp(argv[i], "-namedevent"))
+ {
+ g_bNamedEvent = 1;
+ }
+ else if (0 == strcmp(argv[i], "-semaphore"))
+ {
+ g_bSemaphore = 1;
+ }
+ else if (0 == strcmp(argv[i], "-process"))
+ {
+ g_bProcess = 1;
+ }
+ else if (0 == strcmp(argv[i], "-localwaitall"))
+ {
+ g_bLocalWaitAll = 1;
+ }
+ else if (0 == strcmp(argv[i], "-remotewaitall"))
+ {
+ g_bRemoteWaitAll = 1;
+ }
+ else if (0 == strcmp(argv[i], "-all"))
+ {
+ g_bMutex = 1;
+ g_bEvent = 1;
+ g_bNamedEvent = 1;
+ g_bSemaphore = 1;
+ g_bProcess = 1;
+ g_bLocalWaitAll = 1;
+ g_bRemoteWaitAll = 1;
+ }
+ else if (0 == strcmp(argv[i], "-random"))
+ {
+ g_bRandom = 1;
+ }
+ else if ((0 == strcmp(argv[i], "-count")) && (argc > i+1))
+ {
+ i++;
+ iCnt = atoi(argv[i]);
+ if (iCnt > 0 && iCnt < MAX_COUNT)
+ {
+ iCount = iCnt;
+ }
+ }
+ else if ((0 == strcmp(argv[i], "-threads")) && (argc > i+1))
+ {
+ i++;
+ iCnt = atoi(argv[i]);
+ if (iCnt > 0 && iCnt <= MAX_THREADS)
+ {
+ iThreads = iCnt;
+ }
+ }
+ else
+ {
+ Trace("Unknown option %s ignored\n", argv[i]);
+ }
+ }
+ }
+
+
+ iCnt = 0;
+ for (i=0;i<iThreads;i++)
+ {
+ hThreads[iCnt] = CreateThread(NULL, 0, TestThread, (VOID*)iCnt, 0, &dwSlaveThreadTid);
+ if (NULL == hThreads[iCnt])
+ {
+ Trace("Failed to create thread\n");
+ }
+ else
+ {
+ iCnt++;
+ }
+ }
+
+ if (0 == iCnt)
+ {
+ Fail("Can't create any thread\n");
+ }
+
+ for (i=0; i<iCnt; i+=64)
+ {
+ dwRet = WaitForMultipleObjects(MIN(64, iCnt-i), &hThreads[i], TRUE, INFINITE);
+ if (WAIT_FAILED == dwRet)
+ {
+ Fail("WaitForMultipleObjects failed [dwRet=%u GetLastError()=%u iCnt=%d i=%d]\n",
+ dwRet, GetLastError(), iCnt, i);
+ }
+ }
+
+
+ for (i=0; i<iCnt; i++)
+ {
+ CloseHandle(hThreads[i]);
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExMutexTest/CMakeLists.txt b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExMutexTest/CMakeLists.txt
index 65fa0abe14..816a98bf2f 100644
--- a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExMutexTest/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExMutexTest/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- WFSOExMutexTest.c
+ WFSOExMutexTest.cpp
)
add_executable(paltest_waitforsingleobject_wfsoexmutextest
diff --git a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExMutexTest/WFSOExMutexTest.c b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExMutexTest/WFSOExMutexTest.cpp
index 3737f9cc10..3737f9cc10 100644
--- a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExMutexTest/WFSOExMutexTest.c
+++ b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExMutexTest/WFSOExMutexTest.cpp
diff --git a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExSemaphoreTest/CMakeLists.txt b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExSemaphoreTest/CMakeLists.txt
index 12517e31e0..2d12b25e69 100644
--- a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExSemaphoreTest/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExSemaphoreTest/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- WFSOExSemaphoreTest.c
+ WFSOExSemaphoreTest.cpp
)
add_executable(paltest_waitforsingleobject_wfsoexsemaphoretest
diff --git a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExSemaphoreTest/WFSOExSemaphoreTest.c b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExSemaphoreTest/WFSOExSemaphoreTest.cpp
index 793c50995c..793c50995c 100644
--- a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExSemaphoreTest/WFSOExSemaphoreTest.c
+++ b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExSemaphoreTest/WFSOExSemaphoreTest.cpp
diff --git a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExThreadTest/CMakeLists.txt b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExThreadTest/CMakeLists.txt
index f3d868f082..915ee94a62 100644
--- a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExThreadTest/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExThreadTest/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- WFSOExThreadTest.c
+ WFSOExThreadTest.cpp
)
add_executable(paltest_waitforsingleobject_wfsoexthreadtest
diff --git a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExThreadTest/WFSOExThreadTest.c b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExThreadTest/WFSOExThreadTest.cpp
index 894d2804aa..894d2804aa 100644
--- a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExThreadTest/WFSOExThreadTest.c
+++ b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExThreadTest/WFSOExThreadTest.cpp
diff --git a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOMutexTest/CMakeLists.txt b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOMutexTest/CMakeLists.txt
index 374880e90f..b96324d654 100644
--- a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOMutexTest/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOMutexTest/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- WFSOMutexTest.c
+ WFSOMutexTest.cpp
)
add_executable(paltest_waitforsingleobject_wfsomutextest
diff --git a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOMutexTest/WFSOMutexTest.c b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOMutexTest/WFSOMutexTest.c
deleted file mode 100644
index 5ecf517c2a..0000000000
--- a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOMutexTest/WFSOMutexTest.c
+++ /dev/null
@@ -1,184 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: WFSOMutexTest.c
-**
-** Purpose: Test for WaitForSingleObjectTest.
-** Create Mutex Object
-** Create Two Threads, Each Threads does WFSO for the Mutex Object
-** Increments Counter
-** Releases Mutex
-** Test Passes if the above operations are successful
-**
-**
-**
-**=========================================================*/
-
-
-
-#include <palsuite.h>
-
-
-#define NUMBER_OF_WORKER_THREADS 2
-
-//Declaring Variables
-HANDLE hMutex = NULL;
-unsigned int globalcounter =0;
-int testReturnCode = PASS;
-
-//Declaring Function Prototypes
-DWORD WFSOMutexTest(LPVOID params);
-void incrementCounter(void);
-
-
-
-int __cdecl main(int argc, char **argv)
-{
-
- //Declare local variables
- int i =0;
-
- // 2 dimensional array to hold thread handles for each worker thread
- HANDLE hThread[NUMBER_OF_WORKER_THREADS];
- DWORD dwThreadId=0;
- int returnCode = 0;
-
- //Initialize PAL
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return ( FAIL );
- }
-
- //Create Mutex
- hMutex = CreateMutex(NULL, // no security attributes
- FALSE, // initially not owned
- NULL); // name of mutex
-
- //Check for Mutex Creation
-
- if (hMutex == NULL)
- {
- Fail("Create Mutex Failed, GetLastError: %d\n", GetLastError());
- }
-
-
- //Spawn 2 worker threads
- for (i=0;i<NUMBER_OF_WORKER_THREADS;i++)
- {
- //Create Thread
-
- hThread[i] = CreateThread(
- NULL,
- 0,
- WFSOMutexTest,
- NULL,
- 0,
- &dwThreadId);
-
- if ( NULL == hThread[i] )
- {
- Fail ( "CreateThread() returned NULL. Failing test.\n"
- "GetLastError returned %d\n", GetLastError());
- }
-
- }
-
- /* Test running */
- returnCode = WaitForMultipleObjects( NUMBER_OF_WORKER_THREADS, hThread, TRUE, 5000);
- if( WAIT_OBJECT_0 != returnCode )
- {
- Trace("Wait for Object(s) returned %d, and GetLastError value is %d\n", returnCode, GetLastError());
- testReturnCode = FAIL;
- }
-
-//Close thread handles
-for (i=0;i<NUMBER_OF_WORKER_THREADS;i++)
- {
-
- if (0==CloseHandle(hThread[i]))
- {
- Trace("Could not Close thread handle\n");
- Fail ( "GetLastError returned %d\n", GetLastError());
- }
- }
-
-//Close Mutex Handle
-if (0==CloseHandle(hMutex))
- {
- Trace("Could not close mutex handle\n");
- Fail ( "GetLastError returned %d\n", GetLastError());
- }
-
-
-PAL_TerminateEx(testReturnCode);
-return ( testReturnCode );
-
-}
-
-
-void incrementCounter(void)
-{
- if (INT_MAX == globalcounter)
- {
- globalcounter = 0;
- }
-
- globalcounter++;
- Trace("Global Counter Value: %d \n", globalcounter);
-}
-
-
-DWORD WFSOMutexTest(LPVOID params)
-{
-
- DWORD dwWaitResult;
-
- // Request ownership of mutex.
-
- dwWaitResult = WaitForSingleObject(
- hMutex, // handle to mutex
- 5000L); // five-second time-out interval
-
- switch (dwWaitResult)
- {
- // The thread got mutex ownership.
- case WAIT_OBJECT_0:
- {
-
- incrementCounter();
-
- //Release ownership of the mutex object.
- if (! ReleaseMutex(hMutex))
- {
- Fail ( "ReleaseMutex() returned NULL. Failing test.\n"
- "GetLastError returned %d\n", GetLastError());
- }
-
- break;
- }
-
- // Cannot get mutex ownership due to time-out.
- case WAIT_TIMEOUT:
- {
- Fail ( "Cannot get mutex ownership due to time-out. Failing test.\n"
- "GetLastError returned %d\n", GetLastError());
- return FALSE;
- }
-
- // Got ownership of the abandoned mutex object.
- case WAIT_ABANDONED:
- {
- Fail ( "Got ownership of the abandoned mutex object. Failing test.\n"
- "GetLastError returned %d\n", GetLastError());
- return FALSE;
- }
- }
-
- return 1;
-}
-
-
-
diff --git a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOMutexTest/WFSOMutexTest.cpp b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOMutexTest/WFSOMutexTest.cpp
new file mode 100644
index 0000000000..f2537fa776
--- /dev/null
+++ b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOMutexTest/WFSOMutexTest.cpp
@@ -0,0 +1,184 @@
+// Licensed to the .NET Foundation under one or more 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: WFSOMutexTest.c
+**
+** Purpose: Test for WaitForSingleObjectTest.
+** Create Mutex Object
+** Create Two Threads, Each Threads does WFSO for the Mutex Object
+** Increments Counter
+** Releases Mutex
+** Test Passes if the above operations are successful
+**
+**
+**
+**=========================================================*/
+
+
+
+#include <palsuite.h>
+
+
+#define NUMBER_OF_WORKER_THREADS 2
+
+//Declaring Variables
+HANDLE hMutex = NULL;
+unsigned int globalcounter =0;
+int testReturnCode = PASS;
+
+//Declaring Function Prototypes
+DWORD PALAPI WFSOMutexTest(LPVOID params);
+void incrementCounter(void);
+
+
+
+int __cdecl main(int argc, char **argv)
+{
+
+ //Declare local variables
+ int i =0;
+
+ // 2 dimensional array to hold thread handles for each worker thread
+ HANDLE hThread[NUMBER_OF_WORKER_THREADS];
+ DWORD dwThreadId=0;
+ int returnCode = 0;
+
+ //Initialize PAL
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return ( FAIL );
+ }
+
+ //Create Mutex
+ hMutex = CreateMutex(NULL, // no security attributes
+ FALSE, // initially not owned
+ NULL); // name of mutex
+
+ //Check for Mutex Creation
+
+ if (hMutex == NULL)
+ {
+ Fail("Create Mutex Failed, GetLastError: %d\n", GetLastError());
+ }
+
+
+ //Spawn 2 worker threads
+ for (i=0;i<NUMBER_OF_WORKER_THREADS;i++)
+ {
+ //Create Thread
+
+ hThread[i] = CreateThread(
+ NULL,
+ 0,
+ WFSOMutexTest,
+ NULL,
+ 0,
+ &dwThreadId);
+
+ if ( NULL == hThread[i] )
+ {
+ Fail ( "CreateThread() returned NULL. Failing test.\n"
+ "GetLastError returned %d\n", GetLastError());
+ }
+
+ }
+
+ /* Test running */
+ returnCode = WaitForMultipleObjects( NUMBER_OF_WORKER_THREADS, hThread, TRUE, 5000);
+ if( WAIT_OBJECT_0 != returnCode )
+ {
+ Trace("Wait for Object(s) returned %d, and GetLastError value is %d\n", returnCode, GetLastError());
+ testReturnCode = FAIL;
+ }
+
+//Close thread handles
+for (i=0;i<NUMBER_OF_WORKER_THREADS;i++)
+ {
+
+ if (0==CloseHandle(hThread[i]))
+ {
+ Trace("Could not Close thread handle\n");
+ Fail ( "GetLastError returned %d\n", GetLastError());
+ }
+ }
+
+//Close Mutex Handle
+if (0==CloseHandle(hMutex))
+ {
+ Trace("Could not close mutex handle\n");
+ Fail ( "GetLastError returned %d\n", GetLastError());
+ }
+
+
+PAL_TerminateEx(testReturnCode);
+return ( testReturnCode );
+
+}
+
+
+void incrementCounter(void)
+{
+ if (INT_MAX == globalcounter)
+ {
+ globalcounter = 0;
+ }
+
+ globalcounter++;
+ Trace("Global Counter Value: %d \n", globalcounter);
+}
+
+
+DWORD PALAPI WFSOMutexTest(LPVOID params)
+{
+
+ DWORD dwWaitResult;
+
+ // Request ownership of mutex.
+
+ dwWaitResult = WaitForSingleObject(
+ hMutex, // handle to mutex
+ 5000L); // five-second time-out interval
+
+ switch (dwWaitResult)
+ {
+ // The thread got mutex ownership.
+ case WAIT_OBJECT_0:
+ {
+
+ incrementCounter();
+
+ //Release ownership of the mutex object.
+ if (! ReleaseMutex(hMutex))
+ {
+ Fail ( "ReleaseMutex() returned NULL. Failing test.\n"
+ "GetLastError returned %d\n", GetLastError());
+ }
+
+ break;
+ }
+
+ // Cannot get mutex ownership due to time-out.
+ case WAIT_TIMEOUT:
+ {
+ Fail ( "Cannot get mutex ownership due to time-out. Failing test.\n"
+ "GetLastError returned %d\n", GetLastError());
+ return FALSE;
+ }
+
+ // Got ownership of the abandoned mutex object.
+ case WAIT_ABANDONED:
+ {
+ Fail ( "Got ownership of the abandoned mutex object. Failing test.\n"
+ "GetLastError returned %d\n", GetLastError());
+ return FALSE;
+ }
+ }
+
+ return 1;
+}
+
+
+
diff --git a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOProcessTest/CMakeLists.txt b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOProcessTest/CMakeLists.txt
index a70b101988..61e17eb3ad 100644
--- a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOProcessTest/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOProcessTest/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(TESTSOURCES
- WFSOProcessTest.c
+ WFSOProcessTest.cpp
)
add_executable(paltest_waitforsingleobject_wfsoprocesstest
@@ -20,7 +20,7 @@ target_link_libraries(paltest_waitforsingleobject_wfsoprocesstest
set(HELPERSOURCES
- ChildProcess.c
+ ChildProcess.cpp
)
add_executable(paltest_waitforsingleobject_wfsoprocesstest_child
diff --git a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOProcessTest/ChildProcess.c b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOProcessTest/ChildProcess.cpp
index 91c24d87bb..91c24d87bb 100644
--- a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOProcessTest/ChildProcess.c
+++ b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOProcessTest/ChildProcess.cpp
diff --git a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOProcessTest/WFSOProcessTest.c b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOProcessTest/WFSOProcessTest.cpp
index 2711e26c29..2711e26c29 100644
--- a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOProcessTest/WFSOProcessTest.c
+++ b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOProcessTest/WFSOProcessTest.cpp
diff --git a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOSemaphoreTest/CMakeLists.txt b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOSemaphoreTest/CMakeLists.txt
index 171e0583e5..d17f8da8e5 100644
--- a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOSemaphoreTest/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOSemaphoreTest/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- WFSOSemaphoreTest.c
+ WFSOSemaphoreTest.cpp
)
add_executable(paltest_waitforsingleobject_wfsosemaphoretest
diff --git a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOSemaphoreTest/WFSOSemaphoreTest.c b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOSemaphoreTest/WFSOSemaphoreTest.c
deleted file mode 100644
index 9902d448cd..0000000000
--- a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOSemaphoreTest/WFSOSemaphoreTest.c
+++ /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.
-
-/*============================================================
-**
-** Source: WFSOMutexTest.c
-**
-** Purpose: Test for WaitForSingleObjectTest.
-** Create Semaphore Object
-** Create Two Threads, Each Threads does WFSO for the Semaphore Object
-** Increments Counter
-** Releases Semaphore
-** Test Passes if the above operations are successful
-**
-**
-**
-**=========================================================*/
-
-
-
-#include <palsuite.h>
-
-
-#define NUMBER_OF_WORKER_THREADS 2
-
-
-//Declaring Variables
-HANDLE hSemaphore = NULL;
-unsigned int globalcounter =0;
-int testReturnCode = PASS;
-
-//Declaring Function Prototypes
-DWORD WFSOSemaphoreTest(LPVOID params);
-void incrementCounter(void);
-
-int __cdecl main(int argc, char **argv)
-{
-
- //Declare local variables
- int i =0;
- int cMax = 2;
-
- int returnCode = 0;
-
- // 2 dimensional array to hold thread handles for each worker thread
- HANDLE hThread[NUMBER_OF_WORKER_THREADS];
- DWORD dwThreadId=0;
-
- //Initialize PAL
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return ( FAIL );
- }
-
- //Create Semaphore
- hSemaphore = CreateSemaphore(
- NULL, // no security attributes
- cMax, // initial count
- cMax, // maximum count
- NULL); // unnamed semaphore
-
- if (hSemaphore == NULL)
- {
- // Check for error.
- Fail("Create Semaphore Failed, GetLastError: %d\n", GetLastError());
- }
-
-
-
- //Spawn 2 worker threads
- for (i=0;i<NUMBER_OF_WORKER_THREADS;i++)
- {
- //Create Thread
-
- hThread[i] = CreateThread(
- NULL,
- 0,
- WFSOSemaphoreTest,
- NULL,
- 0,
- &dwThreadId);
-
- if ( NULL == hThread[i] )
- {
- Fail ( "CreateThread() returned NULL. Failing test.\n"
- "GetLastError returned %d\n", GetLastError());
- }
-
- }
-
-
- /* Test running */
- returnCode = WaitForMultipleObjects( NUMBER_OF_WORKER_THREADS, hThread, TRUE, 5000);
- if( WAIT_OBJECT_0 != returnCode )
- {
- Trace("Wait for Object(s) returned %d, and GetLastError value is %d\n", returnCode, GetLastError());
- testReturnCode = FAIL;
- }
-
-//Close thread handles
-for (i=0;i<NUMBER_OF_WORKER_THREADS;i++)
- {
-
- if (0==CloseHandle(hThread[i]))
- {
- Trace("Could not Close thread handle\n");
- Fail ( "GetLastError returned %d\n", GetLastError());
- }
- }
-
-//Close Semaphore Handle
-if (0==CloseHandle(hSemaphore))
- {
- Trace("Could not close semaphore handle\n");
- Fail ( "GetLastError returned %d\n", GetLastError());
- }
-
-PAL_TerminateEx(testReturnCode);
-return ( testReturnCode );
-
-}
-
-
-void incrementCounter(void)
-{
- if (INT_MAX == globalcounter)
- {
- globalcounter = 0;
- }
-
- globalcounter++;
- Trace("Global Counter Value: %d \n", globalcounter);
-}
-
-
-DWORD WFSOSemaphoreTest(LPVOID params)
-{
-
- DWORD dwWaitResult;
-
- // Request ownership of Semaphore
-
- dwWaitResult = WaitForSingleObject(
- hSemaphore, // handle to semaphore
- 0L); // zero-second time-out interval
-
-
- switch (dwWaitResult)
- {
- // The semaphore object was signaled.
- case WAIT_OBJECT_0:
- {
-
- incrementCounter();
- // Increment the count of the semaphore.
-
- if (!ReleaseSemaphore(
- hSemaphore, // handle to semaphore
- 1, // increase count by one
- NULL) ) // not interested in previous count
- {
- Fail ( "ReleaseSemaphore() returned NULL. Failing test.\n"
- "GetLastError returned %d\n", GetLastError());
- }
-
- break;
- }
-
- // Semaphore was nonsignaled, so a time-out occurred.
- case WAIT_TIMEOUT:
- {
- Fail ( "Semaphore was nonsignaled, so a time-out occurred. Failing test.\n"
- "GetLastError returned %d\n", GetLastError());
- return FALSE;
- }
- }
-
- return 1;
-}
-
-
-
diff --git a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOSemaphoreTest/WFSOSemaphoreTest.cpp b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOSemaphoreTest/WFSOSemaphoreTest.cpp
new file mode 100644
index 0000000000..b743b44544
--- /dev/null
+++ b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOSemaphoreTest/WFSOSemaphoreTest.cpp
@@ -0,0 +1,183 @@
+// Licensed to the .NET Foundation under one or more 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: WFSOMutexTest.c
+**
+** Purpose: Test for WaitForSingleObjectTest.
+** Create Semaphore Object
+** Create Two Threads, Each Threads does WFSO for the Semaphore Object
+** Increments Counter
+** Releases Semaphore
+** Test Passes if the above operations are successful
+**
+**
+**
+**=========================================================*/
+
+
+
+#include <palsuite.h>
+
+
+#define NUMBER_OF_WORKER_THREADS 2
+
+
+//Declaring Variables
+HANDLE hSemaphore = NULL;
+unsigned int globalcounter =0;
+int testReturnCode = PASS;
+
+//Declaring Function Prototypes
+DWORD PALAPI WFSOSemaphoreTest(LPVOID params);
+void incrementCounter(void);
+
+int __cdecl main(int argc, char **argv)
+{
+
+ //Declare local variables
+ int i =0;
+ int cMax = 2;
+
+ int returnCode = 0;
+
+ // 2 dimensional array to hold thread handles for each worker thread
+ HANDLE hThread[NUMBER_OF_WORKER_THREADS];
+ DWORD dwThreadId=0;
+
+ //Initialize PAL
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return ( FAIL );
+ }
+
+ //Create Semaphore
+ hSemaphore = CreateSemaphore(
+ NULL, // no security attributes
+ cMax, // initial count
+ cMax, // maximum count
+ NULL); // unnamed semaphore
+
+ if (hSemaphore == NULL)
+ {
+ // Check for error.
+ Fail("Create Semaphore Failed, GetLastError: %d\n", GetLastError());
+ }
+
+
+
+ //Spawn 2 worker threads
+ for (i=0;i<NUMBER_OF_WORKER_THREADS;i++)
+ {
+ //Create Thread
+
+ hThread[i] = CreateThread(
+ NULL,
+ 0,
+ WFSOSemaphoreTest,
+ NULL,
+ 0,
+ &dwThreadId);
+
+ if ( NULL == hThread[i] )
+ {
+ Fail ( "CreateThread() returned NULL. Failing test.\n"
+ "GetLastError returned %d\n", GetLastError());
+ }
+
+ }
+
+
+ /* Test running */
+ returnCode = WaitForMultipleObjects( NUMBER_OF_WORKER_THREADS, hThread, TRUE, 5000);
+ if( WAIT_OBJECT_0 != returnCode )
+ {
+ Trace("Wait for Object(s) returned %d, and GetLastError value is %d\n", returnCode, GetLastError());
+ testReturnCode = FAIL;
+ }
+
+//Close thread handles
+for (i=0;i<NUMBER_OF_WORKER_THREADS;i++)
+ {
+
+ if (0==CloseHandle(hThread[i]))
+ {
+ Trace("Could not Close thread handle\n");
+ Fail ( "GetLastError returned %d\n", GetLastError());
+ }
+ }
+
+//Close Semaphore Handle
+if (0==CloseHandle(hSemaphore))
+ {
+ Trace("Could not close semaphore handle\n");
+ Fail ( "GetLastError returned %d\n", GetLastError());
+ }
+
+PAL_TerminateEx(testReturnCode);
+return ( testReturnCode );
+
+}
+
+
+void incrementCounter(void)
+{
+ if (INT_MAX == globalcounter)
+ {
+ globalcounter = 0;
+ }
+
+ globalcounter++;
+ Trace("Global Counter Value: %d \n", globalcounter);
+}
+
+
+DWORD PALAPI WFSOSemaphoreTest(LPVOID params)
+{
+
+ DWORD dwWaitResult;
+
+ // Request ownership of Semaphore
+
+ dwWaitResult = WaitForSingleObject(
+ hSemaphore, // handle to semaphore
+ 0L); // zero-second time-out interval
+
+
+ switch (dwWaitResult)
+ {
+ // The semaphore object was signaled.
+ case WAIT_OBJECT_0:
+ {
+
+ incrementCounter();
+ // Increment the count of the semaphore.
+
+ if (!ReleaseSemaphore(
+ hSemaphore, // handle to semaphore
+ 1, // increase count by one
+ NULL) ) // not interested in previous count
+ {
+ Fail ( "ReleaseSemaphore() returned NULL. Failing test.\n"
+ "GetLastError returned %d\n", GetLastError());
+ }
+
+ break;
+ }
+
+ // Semaphore was nonsignaled, so a time-out occurred.
+ case WAIT_TIMEOUT:
+ {
+ Fail ( "Semaphore was nonsignaled, so a time-out occurred. Failing test.\n"
+ "GetLastError returned %d\n", GetLastError());
+ return FALSE;
+ }
+ }
+
+ return 1;
+}
+
+
+
diff --git a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOThreadTest/CMakeLists.txt b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOThreadTest/CMakeLists.txt
index 18701a9da5..e2d36e08e1 100644
--- a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOThreadTest/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOThreadTest/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- WFSOThreadTest.c
+ WFSOThreadTest.cpp
)
add_executable(paltest_waitforsingleobject_wfsothreadtest
diff --git a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOThreadTest/WFSOThreadTest.c b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOThreadTest/WFSOThreadTest.c
deleted file mode 100644
index 378350671a..0000000000
--- a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOThreadTest/WFSOThreadTest.c
+++ /dev/null
@@ -1,179 +0,0 @@
-// Licensed to the .NET Foundation under one or more 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: WFSOThreadTest.c
-**
-** Purpose: Test for WaitForSingleObjectTest.
-** Create One Thread and do some work
-** Use WFSO For the Thread to finish
-**
-** Test Passes if the above operations are successful
-**
-**
-**
-**=========================================================*/
-
-
-
-#include <palsuite.h>
-
-
-//Declaring Variables
-HANDLE hThread = NULL;
-HANDLE hEvent = NULL;
-
-unsigned int globalcounter =0;
-
-//Declaring Function Prototypes
-DWORD incrementCounter(LPVOID params);
-
-int __cdecl main(int argc, char **argv)
-{
-
- //Declare local variables
- DWORD dwThreadId=0;
- DWORD dwWaitResult=0;
-
- //Initialize PAL
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return ( FAIL );
- }
-
-
- //Create Event
- hEvent = CreateEvent(NULL,TRUE,FALSE, NULL);
- if(hEvent == NULL)
- {
- Fail("Create Event Failed\n"
- "GetLastError returned %d\n", GetLastError());
- }
-
-
- //Create Thread
- hThread = CreateThread(
- NULL,
- 0,
- incrementCounter,
- NULL,
- 0,
- &dwThreadId);
-
- if ( NULL == hThread )
- {
- Fail ( "CreateThread() returned NULL. Failing test.\n"
- "GetLastError returned %d\n", GetLastError());
- }
-
-
- //Wait For Thread to signal start
- dwWaitResult = WaitForSingleObject(hEvent,INFINITE);
-
- switch (dwWaitResult)
- {
- // The thread wait was successful
- case WAIT_OBJECT_0:
- {
-
- Trace ("Wait for Single Object (hEvent) was successful.\n");
- break;
- }
-
- // Time-out.
- case WAIT_TIMEOUT:
- {
- Fail ( "Time -out. Failing test.\n"
- "GetLastError returned %d\n", GetLastError());
- return FALSE;
- }
-
- // Got ownership of the abandoned event object.
- case WAIT_ABANDONED:
- {
- Fail ( "Got ownership of the abandoned event object. Failing test.\n"
- "GetLastError returned %d\n", GetLastError());
- return FALSE;
- }
-
- }
-
-
- //Wait for Thread to finish
- dwWaitResult = WaitForSingleObject(
- hThread, //handle to thread
- 5000L); //Wait Indefinitely
-
-
- switch (dwWaitResult)
- {
- // The thread wait was successful
- case WAIT_OBJECT_0:
- {
-
- Trace("Wait for thread was successful\n");
-
- break;
- }
-
- // Time-out.
- case WAIT_TIMEOUT:
- {
- Fail ( "Time -out. Failing test.\n"
- "GetLastError returned %d\n", GetLastError());
- return FALSE;
- }
-
- // Got ownership of the abandoned thread object.
- case WAIT_ABANDONED:
- {
- Fail ( "Got ownership of the abandoned thread object. Failing test.\n"
- "GetLastError returned %d\n", GetLastError());
- return FALSE;
- }
-
- }
-
-
-//Close Handles
-if (0==CloseHandle(hEvent))
- {
- Trace("Could not Close event handle\n");
- Fail ( "GetLastError returned %d\n", GetLastError());
- }
-if (0==CloseHandle(hThread))
- {
- Trace("Could not Close thread handle\n");
- Fail ( "GetLastError returned %d\n", GetLastError());
- }
-
-PAL_Terminate();
-return ( PASS );
-
-}
-
-DWORD incrementCounter(LPVOID params)
-{
-
- //Signal Event so that main thread can start to wait for thread object
- if (0==SetEvent(hEvent))
- {
- Fail ( "SetEvent returned Zero. Failing test.\n"
- "GetLastError returned %d\n", GetLastError());
- }
-
- for (globalcounter=0;globalcounter<100000;globalcounter++);
-
- //Sleep(5000);
-
- Trace("Global Counter Value: %d \n", globalcounter);
- return 0;
-}
-
-
-
-
-
-
diff --git a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOThreadTest/WFSOThreadTest.cpp b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOThreadTest/WFSOThreadTest.cpp
new file mode 100644
index 0000000000..e3c3fe22b7
--- /dev/null
+++ b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOThreadTest/WFSOThreadTest.cpp
@@ -0,0 +1,179 @@
+// Licensed to the .NET Foundation under one or more 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: WFSOThreadTest.c
+**
+** Purpose: Test for WaitForSingleObjectTest.
+** Create One Thread and do some work
+** Use WFSO For the Thread to finish
+**
+** Test Passes if the above operations are successful
+**
+**
+**
+**=========================================================*/
+
+
+
+#include <palsuite.h>
+
+
+//Declaring Variables
+HANDLE hThread = NULL;
+HANDLE hEvent = NULL;
+
+unsigned int globalcounter =0;
+
+//Declaring Function Prototypes
+DWORD PALAPI incrementCounter(LPVOID params);
+
+int __cdecl main(int argc, char **argv)
+{
+
+ //Declare local variables
+ DWORD dwThreadId=0;
+ DWORD dwWaitResult=0;
+
+ //Initialize PAL
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return ( FAIL );
+ }
+
+
+ //Create Event
+ hEvent = CreateEvent(NULL,TRUE,FALSE, NULL);
+ if(hEvent == NULL)
+ {
+ Fail("Create Event Failed\n"
+ "GetLastError returned %d\n", GetLastError());
+ }
+
+
+ //Create Thread
+ hThread = CreateThread(
+ NULL,
+ 0,
+ incrementCounter,
+ NULL,
+ 0,
+ &dwThreadId);
+
+ if ( NULL == hThread )
+ {
+ Fail ( "CreateThread() returned NULL. Failing test.\n"
+ "GetLastError returned %d\n", GetLastError());
+ }
+
+
+ //Wait For Thread to signal start
+ dwWaitResult = WaitForSingleObject(hEvent,INFINITE);
+
+ switch (dwWaitResult)
+ {
+ // The thread wait was successful
+ case WAIT_OBJECT_0:
+ {
+
+ Trace ("Wait for Single Object (hEvent) was successful.\n");
+ break;
+ }
+
+ // Time-out.
+ case WAIT_TIMEOUT:
+ {
+ Fail ( "Time -out. Failing test.\n"
+ "GetLastError returned %d\n", GetLastError());
+ return FALSE;
+ }
+
+ // Got ownership of the abandoned event object.
+ case WAIT_ABANDONED:
+ {
+ Fail ( "Got ownership of the abandoned event object. Failing test.\n"
+ "GetLastError returned %d\n", GetLastError());
+ return FALSE;
+ }
+
+ }
+
+
+ //Wait for Thread to finish
+ dwWaitResult = WaitForSingleObject(
+ hThread, //handle to thread
+ 5000L); //Wait Indefinitely
+
+
+ switch (dwWaitResult)
+ {
+ // The thread wait was successful
+ case WAIT_OBJECT_0:
+ {
+
+ Trace("Wait for thread was successful\n");
+
+ break;
+ }
+
+ // Time-out.
+ case WAIT_TIMEOUT:
+ {
+ Fail ( "Time -out. Failing test.\n"
+ "GetLastError returned %d\n", GetLastError());
+ return FALSE;
+ }
+
+ // Got ownership of the abandoned thread object.
+ case WAIT_ABANDONED:
+ {
+ Fail ( "Got ownership of the abandoned thread object. Failing test.\n"
+ "GetLastError returned %d\n", GetLastError());
+ return FALSE;
+ }
+
+ }
+
+
+//Close Handles
+if (0==CloseHandle(hEvent))
+ {
+ Trace("Could not Close event handle\n");
+ Fail ( "GetLastError returned %d\n", GetLastError());
+ }
+if (0==CloseHandle(hThread))
+ {
+ Trace("Could not Close thread handle\n");
+ Fail ( "GetLastError returned %d\n", GetLastError());
+ }
+
+PAL_Terminate();
+return ( PASS );
+
+}
+
+DWORD PALAPI incrementCounter(LPVOID params)
+{
+
+ //Signal Event so that main thread can start to wait for thread object
+ if (0==SetEvent(hEvent))
+ {
+ Fail ( "SetEvent returned Zero. Failing test.\n"
+ "GetLastError returned %d\n", GetLastError());
+ }
+
+ for (globalcounter=0;globalcounter<100000;globalcounter++);
+
+ //Sleep(5000);
+
+ Trace("Global Counter Value: %d \n", globalcounter);
+ return 0;
+}
+
+
+
+
+
+
diff --git a/src/pal/tests/palsuite/threading/WaitForSingleObject/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/WaitForSingleObject/test1/CMakeLists.txt
index 0a71330ba1..25f3739492 100644
--- a/src/pal/tests/palsuite/threading/WaitForSingleObject/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/WaitForSingleObject/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_waitforsingleobject_test1
diff --git a/src/pal/tests/palsuite/threading/WaitForSingleObject/test1/test1.c b/src/pal/tests/palsuite/threading/WaitForSingleObject/test1/test1.cpp
index 2af80df677..2af80df677 100644
--- a/src/pal/tests/palsuite/threading/WaitForSingleObject/test1/test1.c
+++ b/src/pal/tests/palsuite/threading/WaitForSingleObject/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/threading/YieldProcessor/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/YieldProcessor/test1/CMakeLists.txt
index 5002bf763d..1c600bd81c 100644
--- a/src/pal/tests/palsuite/threading/YieldProcessor/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/YieldProcessor/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test1.c
+ test1.cpp
)
add_executable(paltest_yieldprocessor_test1
diff --git a/src/pal/tests/palsuite/threading/YieldProcessor/test1/test1.c b/src/pal/tests/palsuite/threading/YieldProcessor/test1/test1.cpp
index 6adbe989c2..6adbe989c2 100644
--- a/src/pal/tests/palsuite/threading/YieldProcessor/test1/test1.c
+++ b/src/pal/tests/palsuite/threading/YieldProcessor/test1/test1.cpp
diff --git a/src/pal/tests/palsuite/threading/releasesemaphore/test1/CMakeLists.txt b/src/pal/tests/palsuite/threading/releasesemaphore/test1/CMakeLists.txt
index e415f91fb2..4f6947476d 100644
--- a/src/pal/tests/palsuite/threading/releasesemaphore/test1/CMakeLists.txt
+++ b/src/pal/tests/palsuite/threading/releasesemaphore/test1/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.12.2)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(SOURCES
- test.c
+ test.cpp
)
add_executable(paltest_releasesemaphore_test1
diff --git a/src/pal/tests/palsuite/threading/releasesemaphore/test1/test.c b/src/pal/tests/palsuite/threading/releasesemaphore/test1/test.cpp
index 4d736b7d9a..4d736b7d9a 100644
--- a/src/pal/tests/palsuite/threading/releasesemaphore/test1/test.c
+++ b/src/pal/tests/palsuite/threading/releasesemaphore/test1/test.cpp
diff --git a/src/pal/tools/gen-buildsys-clang.sh b/src/pal/tools/gen-buildsys-clang.sh
index b7945f3091..4054266f0b 100755
--- a/src/pal/tools/gen-buildsys-clang.sh
+++ b/src/pal/tools/gen-buildsys-clang.sh
@@ -126,13 +126,20 @@ fi
if [[ -n "$LLDB_INCLUDE_DIR" ]]; then
cmake_extra_defines="$cmake_extra_defines -DWITH_LLDB_INCLUDES=$LLDB_INCLUDE_DIR"
fi
-if [[ -n "$CROSSCOMPILE" ]]; then
- if ! [[ -n "$ROOTFS_DIR" ]]; then
- echo "ROOTFS_DIR not set for crosscompile"
- exit 1
+if [[ -n "$CROSSCOMPONENT" ]]; then
+ cmake_extra_defines="$cmake_extra_defines -DCLR_CROSS_COMPONENTS_BUILD=1"
+else
+ if [[ -n "$CROSSCOMPILE" ]]; then
+ if ! [[ -n "$ROOTFS_DIR" ]]; then
+ echo "ROOTFS_DIR not set for crosscompile"
+ exit 1
+ fi
+ if [[ -z $CONFIG_DIR ]]; then
+ CONFIG_DIR="$1/cross/$build_arch"
+ 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"
fi
- cmake_extra_defines="$cmake_extra_defines -C $1/cross/$build_arch/tryrun.cmake"
- cmake_extra_defines="$cmake_extra_defines -DCMAKE_TOOLCHAIN_FILE=$1/cross/$build_arch/toolchain.cmake"
fi
if [ "$build_arch" == "arm-softfp" ]; then
cmake_extra_defines="$cmake_extra_defines -DARM_SOFTFP=1"
diff --git a/src/pal/tools/gen-buildsys-win.bat b/src/pal/tools/gen-buildsys-win.bat
index ab57fb4bb4..f7f81fca33 100644
--- a/src/pal/tools/gen-buildsys-win.bat
+++ b/src/pal/tools/gen-buildsys-win.bat
@@ -36,7 +36,7 @@ goto loop
if defined CMakePath goto DoGen
:: Eval the output from probe-win1.ps1
-for /f "delims=" %%a in ('powershell -NoProfile -ExecutionPolicy RemoteSigned "& "%basePath%\probe-win.ps1""') do %%a
+for /f "delims=" %%a in ('powershell -NoProfile -ExecutionPolicy ByPass "& "%basePath%\probe-win.ps1""') do %%a
:DoGen
"%CMakePath%" "-DCMAKE_USER_MAKE_RULES_OVERRIDE=%basePath%\windows-compiler-override.txt" "-DCMAKE_INSTALL_PREFIX:PATH=$ENV{__CMakeBinDir}" "-DCLR_CMAKE_HOST_ARCH=%__Arch%" %__ExtraCmakeParams% -G "%__CmakeGenerator%" %__SourceDir%
diff --git a/src/palrt/path.cpp b/src/palrt/path.cpp
index 1d610cd4fb..fc01183e33 100644
--- a/src/palrt/path.cpp
+++ b/src/palrt/path.cpp
@@ -11,7 +11,7 @@
// ===========================================================================
#include "common.h"
-
+#include "strsafe.h"
#define CH_SLASH W('/')
@@ -355,7 +355,8 @@ STDAPI_(BOOL) PathCanonicalizeW(LPWSTR lpszDst, LPCWSTR lpszSrc)
else // Everything else
{
// Just copy it.
- lstrcpynW(lpchDst, lpchSrc, cchPC);
+ int cchRemainingBuffer = MAX_PATH - (lpszDst - lpchDst);
+ StringCchCopyNW(lpchDst, cchRemainingBuffer, lpchSrc, cchPC);
lpchDst += cchPC - 1;
lpchSrc += cchPC - 1;
}
@@ -429,11 +430,12 @@ STDAPI_(LPWSTR) PathCombineW(LPWSTR lpszDest, LPCWSTR lpszDir, LPCWSTR lpszFile)
{
if (!lpszFile || *lpszFile==W('\0'))
{
- lstrcpynW(szTemp, lpszDir, ARRAYSIZE(szTemp)); // lpszFile is empty
+ // lpszFile is empty
+ StringCchCopyNW(szTemp, ARRAYSIZE(szTemp), lpszDir, ARRAYSIZE(szTemp));
}
else if (PathIsRelativeW(lpszFile))
{
- lstrcpynW(szTemp, lpszDir, ARRAYSIZE(szTemp));
+ StringCchCopyNW(szTemp, ARRAYSIZE(szTemp), lpszDir, ARRAYSIZE(szTemp));
pszT = PathAddBackslashW(szTemp);
if (pszT)
{
@@ -441,7 +443,7 @@ STDAPI_(LPWSTR) PathCombineW(LPWSTR lpszDest, LPCWSTR lpszDir, LPCWSTR lpszFile)
if (lstrlenW(lpszFile) < iRemaining)
{
- lstrcpynW(pszT, lpszFile, iRemaining);
+ StringCchCopyNW(pszT, iRemaining, lpszFile, iRemaining);
}
else
{
@@ -455,7 +457,7 @@ STDAPI_(LPWSTR) PathCombineW(LPWSTR lpszDest, LPCWSTR lpszDir, LPCWSTR lpszFile)
}
else if (IsPathSeparator(*lpszFile) && !PathIsUNCW(lpszFile))
{
- lstrcpynW(szTemp, lpszDir, ARRAYSIZE(szTemp));
+ StringCchCopyNW(szTemp, ARRAYSIZE(szTemp), lpszDir, ARRAYSIZE(szTemp));
// FEATURE: Note that we do not check that an actual root is returned;
// it is assumed that we are given valid parameters
PathStripToRootW(szTemp);
@@ -466,7 +468,8 @@ STDAPI_(LPWSTR) PathCombineW(LPWSTR lpszDest, LPCWSTR lpszDir, LPCWSTR lpszFile)
// Skip the backslash when copying
// Note: We don't support strings longer than 4GB, but that's
// okay because we already barf at MAX_PATH
- lstrcpynW(pszT, lpszFile+1, (int)(ARRAYSIZE(szTemp) - (pszT - szTemp)));
+ int iRemaining = (int)(ARRAYSIZE(szTemp) - (pszT - szTemp));
+ StringCchCopyNW(pszT, iRemaining, lpszFile+1, iRemaining);
}
else
{
@@ -475,12 +478,14 @@ STDAPI_(LPWSTR) PathCombineW(LPWSTR lpszDest, LPCWSTR lpszDir, LPCWSTR lpszFile)
}
else
{
- lstrcpynW(szTemp, lpszFile, ARRAYSIZE(szTemp)); // already fully qualified file part
+ // already fully qualified file part
+ StringCchCopyNW(szTemp, ARRAYSIZE(szTemp), lpszFile, ARRAYSIZE(szTemp));
}
}
else if (lpszFile && *lpszFile)
{
- lstrcpynW(szTemp, lpszFile, ARRAYSIZE(szTemp)); // no dir just use file.
+ // no dir just use file.
+ StringCchCopyNW(szTemp, ARRAYSIZE(szTemp), lpszFile, ARRAYSIZE(szTemp));
}
//
diff --git a/src/palrt/urlpars.cpp b/src/palrt/urlpars.cpp
index 77b0a6e2ba..66289b6f9d 100644
--- a/src/palrt/urlpars.cpp
+++ b/src/palrt/urlpars.cpp
@@ -11,6 +11,7 @@
// ===========================================================================
#include "common.h"
+#include "strsafe.h"
#define SLASH W('/')
#define WHACK W('\\')
@@ -293,14 +294,13 @@ ParseURLW(
// (+ 1) for null terminator.
- StrCpyNW(rgchDebugProtocol, ppu->pszProtocol,
+ StringCchCopyNW(rgchDebugProtocol, ARRAYSIZE(rgchDebugProtocol), ppu->pszProtocol,
min(ppu->cchProtocol + 1, SIZECHARS(rgchDebugProtocol)));
// (+ 1) for null terminator.
- StrCpyNW(rgchDebugSuffix, ppu->pszSuffix,
+ StringCchCopyNW(rgchDebugSuffix, ARRAYSIZE(rgchDebugSuffix), ppu->pszSuffix,
min(ppu->cchSuffix + 1, SIZECHARS(rgchDebugSuffix)));
-
}
#endif
diff --git a/src/publish.proj b/src/publish.proj
index 66aeb7e5e1..d4e4a7f24b 100644
--- a/src/publish.proj
+++ b/src/publish.proj
@@ -13,21 +13,26 @@
<!-- add relative blob path metadata -->
<ItemGroup>
<ForPublishing>
- <RelativeBlobPath>$(__BuildType)/%(RecursiveDir)%(Filename)%(Extension)</RelativeBlobPath>
+ <RelativeBlobPath Condition="'$(PublishTestNativeBins)' != 'true'">$(__BuildType)/%(RecursiveDir)%(Filename)%(Extension)</RelativeBlobPath>
+ <RelativeBlobPath Condition="'$(PublishTestNativeBins)' == 'true'">$(__DistroRid)-$(__BuildArch)/$(__BuildType)/%(RecursiveDir)%(Filename)%(Extension)</RelativeBlobPath>
</ForPublishing>
</ItemGroup>
<Error Condition="'@(ForPublishing)' == ''" Text="No items were found matching pattern '$(PublishPattern)'." />
</Target>
<PropertyGroup>
- <PublishPattern Condition="'$(PublishPattern)' == ''">$(PackagesBinDir)**\*.nupkg</PublishPattern>
+ <PublishPattern Condition="'$(PublishPattern)' == '' and '$(PublishTestNativeBins)' != 'true'">$(PackagesBinDir)**\*.nupkg</PublishPattern>
+ <PublishPattern Condition="'$(PublishPattern)' == '' and '$(PublishTestNativeBins)' == 'true'">$(OutputPath)\tests\src\**</PublishPattern>
</PropertyGroup>
<Target Name="CreateContainerName"
DependsOnTargets="CreateVersionFileDuringBuild"
- Condition="'$(ContainerName)' == ''">
+ Condition="'$(ContainerName)' == '' or '$(PublishTestNativeBins)' == 'true'">
<PropertyGroup>
- <ContainerName>coreclr-$(PreReleaseLabel)-$(BuildNumberMajor)-$(BuildNumberMinor)</ContainerName>
+ <ContainerName Condition="'$(__Container)' == '' and '$(PublishTestNativeBins)' != 'true'">coreclr-$(PreReleaseLabel)-$(BuildNumberMajor)-$(BuildNumberMinor)</ContainerName>
+ <ContainerName Condition="'$(__Container)' == '' and '$(PublishTestNativeBins)' == 'true'">coreclr-$(PreReleaseLabel)-$(BuildNumberMajor)-$(BuildNumberMinor)-test-native-bins</ContainerName>
+ <ContainerName Condition="'$(__Container)' != '' and '$(PublishTestNativeBins)' != 'true'">$(__Container)</ContainerName>
+ <ContainerName Condition="'$(__Container)' != '' and '$(PublishTestNativeBins)' == 'true'">$(__Container)-test-native-bins</ContainerName>
</PropertyGroup>
</Target>
diff --git a/src/strongname/api/common.h b/src/strongname/api/common.h
index c83685cc0c..c6b9b4df3c 100644
--- a/src/strongname/api/common.h
+++ b/src/strongname/api/common.h
@@ -156,7 +156,7 @@ typedef DPTR(class TypeHandle) PTR_TypeHandle;
typedef VPTR(class VirtualCallStubManager) PTR_VirtualCallStubManager;
typedef VPTR(class VirtualCallStubManagerManager) PTR_VirtualCallStubManagerManager;
#endif
-typedef VPTR(class GCHeap) PTR_GCHeap;
+typedef VPTR(class IGCHeap) PTR_IGCHeap;
//
// _UNCHECKED_OBJECTREF is for code that can't deal with DEBUG OBJECTREFs
@@ -192,7 +192,7 @@ Thread * const CURRENT_THREAD = NULL;
(void)CURRENT_THREAD_AVAILABLE; /* silence "local variable initialized but not used" warning */ \
#ifndef DACCESS_COMPILE
-EXTERN_C AppDomain* GetAppDomain();
+EXTERN_C AppDomain* STDCALL GetAppDomain();
#endif //!DACCESS_COMPILE
inline void RetailBreak()
diff --git a/src/syncAzure.proj b/src/syncAzure.proj
index fbfbea0bff..0b71a3bdcd 100644
--- a/src/syncAzure.proj
+++ b/src/syncAzure.proj
@@ -4,8 +4,11 @@
<PropertyGroup>
<ContainerNamePrefix Condition="'$(ContainerNamePrefix)' == ''">coreclr-$(PreReleaseLabel)</ContainerNamePrefix>
- <ContainerName Condition="'$(ContainerNamePrefix)' != '' and '$(BuildNumberMajor)' != '' and '$(BuildNumberMinor)' != ''">$(ContainerNamePrefix)-$(BuildNumberMajor)-$(BuildNumberMinor)</ContainerName>
- <DownloadDirectory>$(PackagesDir)AzureTransfer</DownloadDirectory>
+ <ContainerName Condition="'$(__Container)' == '' and '$(ContainerNamePrefix)' != '' and '$(BuildNumberMajor)' != '' and '$(BuildNumberMinor)' != ''">$(ContainerNamePrefix)-$(BuildNumberMajor)-$(BuildNumberMinor)</ContainerName>
+ <ContainerName Condition="'$(__Container)' != '' and '$(PublishTestNativeBins)' != 'true'">$(__Container)</ContainerName>
+ <ContainerName Condition="'$(__Container)' != '' and '$(PublishTestNativeBins)' == 'true'">$(__Container)-test-native-bins</ContainerName>
+ <DownloadDirectory Condition="'$(PublishTestNativeBins)' != 'true'">$(PackagesDir)AzureTransfer</DownloadDirectory>
+ <DownloadDirectory Condition="'$(PublishTestNativeBins)' == 'true'">$(PackagesDir)TestNativeBins</DownloadDirectory>
</PropertyGroup>
<Import Project="$(ToolsDir)SyncCloudContent.targets" />
diff --git a/src/tools/crossgen/crossgen.cpp b/src/tools/crossgen/crossgen.cpp
index 960bcf51cd..a3e66e69e2 100644
--- a/src/tools/crossgen/crossgen.cpp
+++ b/src/tools/crossgen/crossgen.cpp
@@ -122,20 +122,21 @@ void PrintUsageHelper()
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]>\n")
+ 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")
- W(" /Platform_Resource_Roots <path[;path]>\n")
+ W(" /Platform_Resource_Roots <path[") PATH_SEPARATOR_STR_W W("path]>\n")
W(" - List of paths containing localized assembly directories\n")
- W(" /App_Paths <path> - List of paths containing user-application assemblies and resources\n")
+ W(" /App_Paths <path[") PATH_SEPARATOR_STR_W W("path]>\n")
+ W(" - List of paths containing user-application assemblies and resources\n")
#ifndef NO_NGENPDB
- W(" /App_Ni_Paths <path[;path]>\n")
+ W(" /App_Ni_Paths <path[") PATH_SEPARATOR_STR_W W("path]>\n")
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\n")
+ 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,
@@ -144,7 +145,7 @@ void PrintUsageHelper()
#endif // FEATURE_CORECLR
#ifdef FEATURE_COMINTEROP
- W(" /Platform_Winmd_Paths\n")
+ W(" /Platform_Winmd_Paths <path[") PATH_SEPARATOR_STR_W W("path]>\n")
W(" - List of paths containing target platform WinMDs used\n")
W(" for emulating RoResolveNamespace\n")
#endif
@@ -156,7 +157,7 @@ void PrintUsageHelper()
W(" scenario traces, which can be used with ibcmerge.exe\n")
#endif
#if defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
- W(" /JITPath\n")
+ 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)
#ifdef FEATURE_READYTORUN_COMPILER
diff --git a/src/utilcode/CMakeLists.txt b/src/utilcode/CMakeLists.txt
index 9d35a7e641..7c396732a1 100644
--- a/src/utilcode/CMakeLists.txt
+++ b/src/utilcode/CMakeLists.txt
@@ -41,7 +41,6 @@ set(UTILCODE_COMMON_SOURCES
outstring.cpp
ilformatter.cpp
opinfo.cpp
- dacutil.cpp
sortversioning.cpp
corimage.cpp
format1.cpp
@@ -71,6 +70,7 @@ set(UTILCODE_COMMON_SOURCES
if(WIN32)
list(APPEND UTILCODE_COMMON_SOURCES
appxutil.cpp
+ dacutil.cpp
dlwrap.cpp
downlevel.cpp
loadrc.cpp
diff --git a/src/utilcode/clrhost_nodependencies.cpp b/src/utilcode/clrhost_nodependencies.cpp
index da4e0252e2..a069d24f7f 100644
--- a/src/utilcode/clrhost_nodependencies.cpp
+++ b/src/utilcode/clrhost_nodependencies.cpp
@@ -745,12 +745,12 @@ void ClrFlsAssociateCallback(DWORD slot, PTLS_CALLBACK_FUNCTION callback)
GetExecutionEngine()->TLS_AssociateCallback(slot, callback);
}
-void ** __stdcall ClrFlsGetBlockGeneric()
+LPVOID *ClrFlsGetBlockGeneric()
{
WRAPPER_NO_CONTRACT;
STATIC_CONTRACT_SO_TOLERANT;
- return (void **) GetExecutionEngine()->TLS_GetDataBlock();
+ return (LPVOID *) GetExecutionEngine()->TLS_GetDataBlock();
}
CLRFLSGETBLOCK __ClrFlsGetBlock = ClrFlsGetBlockGeneric;
diff --git a/src/utilcode/debug.cpp b/src/utilcode/debug.cpp
index a96aca148a..9a60645b9d 100644
--- a/src/utilcode/debug.cpp
+++ b/src/utilcode/debug.cpp
@@ -76,16 +76,6 @@ BOOL ContinueOnAssert()
return fNoGui.val(CLRConfig::INTERNAL_ContinueOnAssert);
}
-BOOL NoGuiOnAssert()
-{
- STATIC_CONTRACT_NOTHROW;
- STATIC_CONTRACT_GC_NOTRIGGER;
- STATIC_CONTRACT_DEBUG_ONLY;
-
- static ConfigDWORD fNoGui;
- return fNoGui.val(CLRConfig::INTERNAL_NoGuiOnAssert);
-}
-
void DoRaiseExceptionOnAssert(DWORD chance)
{
STATIC_CONTRACT_NOTHROW;
@@ -794,6 +784,16 @@ bool GetStackTraceAtContext(SString & s, CONTEXT * pContext)
#endif // !defined(DACCESS_COMPILE)
#endif // _DEBUG
+BOOL NoGuiOnAssert()
+{
+ STATIC_CONTRACT_NOTHROW;
+ STATIC_CONTRACT_GC_NOTRIGGER;
+ STATIC_CONTRACT_DEBUG_ONLY;
+
+ static ConfigDWORD fNoGui;
+ return fNoGui.val(CLRConfig::INTERNAL_NoGuiOnAssert);
+}
+
// This helper will throw up a message box without allocating or using stack if possible, and is
// appropriate for either low memory or low stack situations.
int LowResourceMessageBoxHelperAnsi(
diff --git a/src/utilcode/fstring.cpp b/src/utilcode/fstring.cpp
index 33aa346a9c..1165ecaac0 100644
--- a/src/utilcode/fstring.cpp
+++ b/src/utilcode/fstring.cpp
@@ -73,6 +73,9 @@ HRESULT Unicode_Utf8_Length(__in_z LPCWSTR pString, __out bool * pAllAscii, __ou
return HRESULT_FROM_GetLastError();
}
+ // Remove the count of null terminator, to be consistent with the all-ASCII case.
+ --*pLength;
+
if (*pLength > MAX_LENGTH)
{
return COR_E_OVERFLOW;
@@ -129,7 +132,7 @@ HRESULT Unicode_Utf8(__in_z LPCWSTR pString, bool allAscii, __out_z LPSTR pBuffe
}
else
{
- length = WszWideCharToMultiByte(CP_UTF8, 0, pString, -1, pBuffer, (int) length, NULL, NULL);
+ length = WszWideCharToMultiByte(CP_UTF8, 0, pString, -1, pBuffer, (int) length + 1, NULL, NULL);
if (length == 0)
{
@@ -190,6 +193,9 @@ HRESULT Utf8_Unicode_Length(__in_z LPCSTR pString, __out bool * pAllAscii, __out
return HRESULT_FROM_GetLastError();
}
+ // Remove the count of null terminator, to be consistent with the all-ASCII case.
+ --*pLength;
+
if (* pLength > MAX_LENGTH)
{
return COR_E_OVERFLOW;
@@ -200,7 +206,7 @@ HRESULT Utf8_Unicode_Length(__in_z LPCSTR pString, __out bool * pAllAscii, __out
}
-// UTF8 to ANSI
+// UTF8 to Unicode
HRESULT Utf8_Unicode(__in_z LPCSTR pString, bool allAscii, __out_z LPWSTR pBuffer, DWORD length)
{
@@ -247,7 +253,7 @@ HRESULT Utf8_Unicode(__in_z LPCSTR pString, bool allAscii, __out_z LPWSTR pBuffe
}
else
{
- length = WszMultiByteToWideChar(CP_UTF8, 0, pString, -1, pBuffer, (int) length);
+ length = WszMultiByteToWideChar(CP_UTF8, 0, pString, -1, pBuffer, (int) length + 1);
if (length == 0)
{
diff --git a/src/utilcode/longfilepathwrappers.cpp b/src/utilcode/longfilepathwrappers.cpp
index 9ffbf27cc8..5272d35807 100644
--- a/src/utilcode/longfilepathwrappers.cpp
+++ b/src/utilcode/longfilepathwrappers.cpp
@@ -19,8 +19,8 @@ private:
static const WCHAR VolumeSeparatorChar;
#define UNCPATHPREFIX W("\\\\")
#endif //FEATURE_PAL
- static const WCHAR LongFile::DirectorySeparatorChar;
- static const WCHAR LongFile::AltDirectorySeparatorChar;
+ static const WCHAR DirectorySeparatorChar;
+ static const WCHAR AltDirectorySeparatorChar;
public:
static BOOL IsExtended(SString & path);
static BOOL IsUNCExtended(SString & path);
diff --git a/src/utilcode/makepath.cpp b/src/utilcode/makepath.cpp
index 37b7202dba..701c525cf4 100644
--- a/src/utilcode/makepath.cpp
+++ b/src/utilcode/makepath.cpp
@@ -17,7 +17,7 @@
#ifndef FEATURE_CORECLR
/***
-*void _makepath() - build path name from components
+*void MakePath() - build path name from components
*
*Purpose:
* create a path name from its individual components
diff --git a/src/utilcode/md5.cpp b/src/utilcode/md5.cpp
index 1c7b31f97a..8d6f8a3282 100644
--- a/src/utilcode/md5.cpp
+++ b/src/utilcode/md5.cpp
@@ -132,7 +132,7 @@ void MD5::GetHashValue(MD5HASHDATA* phash)
//
// but our compiler has an intrinsic!
- #if defined(_ARM_) && defined(PLATFORM_UNIX)
+ #if (defined(_X86_) || defined(_ARM_)) && defined(PLATFORM_UNIX)
#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n))))
#define ROTATE_LEFT(x,n) (x) = ROL(x,n)
#else
diff --git a/src/utilcode/opinfo.cpp b/src/utilcode/opinfo.cpp
index 9d5ff202ff..60da66047a 100644
--- a/src/utilcode/opinfo.cpp
+++ b/src/utilcode/opinfo.cpp
@@ -14,13 +14,8 @@
OpInfo::OpInfoData OpInfo::table[] = {
-#ifdef _MSC_VER
-#define OPDEF(c,s,pop,push,args,type,l,s1,s2,ctrl) \
- { s, args + type, FLOW_ ## ctrl, pop, push, c },
-#else
#define OPDEF(c,s,pop,push,args,type,l,s1,s2,ctrl) \
{ s, (OPCODE_FORMAT) (args + type), FLOW_ ## ctrl, pop, push, c },
-#endif
// Kind of a workaround, get the prefixes (IInternal) to return InlineOpcode instead of InlineNone
#define IInternal (InlineOpcode - InlineNone)
diff --git a/src/utilcode/regutil.cpp b/src/utilcode/regutil.cpp
index fbc55708c7..d611ef965f 100644
--- a/src/utilcode/regutil.cpp
+++ b/src/utilcode/regutil.cpp
@@ -1439,8 +1439,7 @@ void REGUTIL::InitOptionalConfigCache()
s_fUseRegCache = TRUE;
// Now create a cache of environment variables
- WCHAR * wszStrings = WszGetEnvironmentStrings();
- if (wszStrings)
+ if (WCHAR * wszStrings = WszGetEnvironmentStrings())
{
// GetEnvironmentStrings returns pointer to a null terminated block containing
// null terminated strings
diff --git a/src/utilcode/securitywrapper.cpp b/src/utilcode/securitywrapper.cpp
index f949b26df1..0f146ab55e 100644
--- a/src/utilcode/securitywrapper.cpp
+++ b/src/utilcode/securitywrapper.cpp
@@ -412,6 +412,7 @@ HRESULT SidBuffer::InitFromProcessAppContainerSidNoThrow(DWORD pid)
{
HRESULT hr = S_OK;
HANDLE hToken = NULL;
+ BOOL fIsLowBox = FALSE;
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
if (hProcess == NULL)
@@ -438,7 +439,6 @@ HRESULT SidBuffer::InitFromProcessAppContainerSidNoThrow(DWORD pid)
} TOKEN_APPCONTAINER_INFORMATION, *PTOKEN_APPCONTAINER_INFORMATION;
DWORD size;
- BOOL fIsLowBox = FALSE;
if (!GetTokenInformation(hToken, (TOKEN_INFORMATION_CLASS)TokenIsAppContainer, &fIsLowBox, sizeof(fIsLowBox), &size))
{
DWORD gle = GetLastError();
@@ -466,24 +466,26 @@ HRESULT SidBuffer::InitFromProcessAppContainerSidNoThrow(DWORD pid)
goto exit;
}
- PTOKEN_APPCONTAINER_INFORMATION pTokPack = (PTOKEN_APPCONTAINER_INFORMATION)&PackSid;
- PSID pLowBoxPackage = pTokPack->TokenPackage;
- DWORD dwSidLen = GetLengthSid(pLowBoxPackage);
- m_pBuffer = new (nothrow) BYTE[dwSidLen];
- if (m_pBuffer == NULL)
- {
- hr = E_OUTOFMEMORY;
- goto exit;
- }
- else
{
- if (!CopySid(dwSidLen, m_pBuffer, pLowBoxPackage))
+ PTOKEN_APPCONTAINER_INFORMATION pTokPack = (PTOKEN_APPCONTAINER_INFORMATION)&PackSid;
+ PSID pLowBoxPackage = pTokPack->TokenPackage;
+ DWORD dwSidLen = GetLengthSid(pLowBoxPackage);
+ m_pBuffer = new (nothrow) BYTE[dwSidLen];
+ if (m_pBuffer == NULL)
{
- hr = HRESULT_FROM_GetLastError();
- delete m_pBuffer;
- m_pBuffer = NULL;
+ hr = E_OUTOFMEMORY;
goto exit;
}
+ else
+ {
+ if (!CopySid(dwSidLen, m_pBuffer, pLowBoxPackage))
+ {
+ hr = HRESULT_FROM_GetLastError();
+ delete m_pBuffer;
+ m_pBuffer = NULL;
+ goto exit;
+ }
+ }
}
exit:
@@ -790,6 +792,7 @@ bool IsHandleSpoofed(HANDLE handle, DWORD pid)
SidBuffer sbPidOther;
SidBuffer sbPidThis;
+ DWORD pidThis;
// Is the object owner the "other" pid?
sbPidOther.InitFromProcess(pid);
@@ -805,7 +808,7 @@ bool IsHandleSpoofed(HANDLE handle, DWORD pid)
// This can happen if the other process impersonates us. The most common case would
// be if we're an admin and the other process (say some service) is impersonating Admin
// when it spins up the CLR.
- DWORD pidThis = GetCurrentProcessId();
+ pidThis = GetCurrentProcessId();
if (pidThis != pid)
{
sbPidThis.InitFromProcess(pidThis);
diff --git a/src/utilcode/splitpath.cpp b/src/utilcode/splitpath.cpp
index f7a35fdd97..a5578a1a8d 100644
--- a/src/utilcode/splitpath.cpp
+++ b/src/utilcode/splitpath.cpp
@@ -18,7 +18,7 @@
/***
-*_splitpath() - split a path name into its individual components
+*SplitPath() - split a path name into its individual components
*
*Purpose:
* to split a path name into its individual components
@@ -214,7 +214,7 @@ void SplitPathInterior(
}
/***
-*_splitpath() - split a path name into its individual components
+*SplitPath() - split a path name into its individual components
*
*Purpose:
* to split a path name into its individual components
diff --git a/src/utilcode/sstring.cpp b/src/utilcode/sstring.cpp
index 154e9ded7a..ce532d70f6 100644
--- a/src/utilcode/sstring.cpp
+++ b/src/utilcode/sstring.cpp
@@ -2211,7 +2211,7 @@ void SString::VPrintf(const WCHAR *format, va_list args)
else
if (errno!=0 && errno!=EBADF && errno!=ERANGE)
{
- CONSISTENCY_CHECK_MSG(FALSE, "_vsnwprintf failed. Potential globalization bug.");
+ CONSISTENCY_CHECK_MSG(FALSE, "_vsnwprintf_s failed. Potential globalization bug.");
ThrowHR(HRESULT_FROM_WIN32(ERROR_NO_UNICODE_TRANSLATION));
}
}
@@ -2293,7 +2293,7 @@ void SString::PVPrintf(const WCHAR *format, va_list args)
else
if (errno!=0 && errno!=EBADF && errno!=ERANGE)
{
- CONSISTENCY_CHECK_MSG(FALSE, "_vsnwprintf failed. Potential globalization bug.");
+ CONSISTENCY_CHECK_MSG(FALSE, "_vsnwprintf_s failed. Potential globalization bug.");
ThrowHR(HRESULT_FROM_WIN32(ERROR_NO_UNICODE_TRANSLATION));
}
}
diff --git a/src/utilcode/stacktrace.cpp b/src/utilcode/stacktrace.cpp
index 7bfdb4514a..858fac723e 100644
--- a/src/utilcode/stacktrace.cpp
+++ b/src/utilcode/stacktrace.cpp
@@ -208,7 +208,7 @@ typedef DWORD (_stdcall *pfnImgHlp_SymGetOptions)(
struct IMGHLPFN_LOAD
{
- LPSTR pszFnName;
+ LPCSTR pszFnName;
LPVOID * ppvfn;
};
@@ -520,7 +520,7 @@ DWORD_PTR dwAddr
}
CHAR rgchUndec[256];
- CHAR * pszSymbol = NULL;
+ const CHAR * pszSymbol = NULL;
// Name field of IMAGEHLP_SYMBOL is dynamically sized.
// Pad with space for 255 characters.
diff --git a/src/utilcode/stresslog.cpp b/src/utilcode/stresslog.cpp
index f4b8961fcb..d364b06dd6 100644
--- a/src/utilcode/stresslog.cpp
+++ b/src/utilcode/stresslog.cpp
@@ -51,7 +51,7 @@ unsigned __int64 getTimeStamp() {
#endif // _TARGET_X86_
-#if defined(_TARGET_X86_)
+#if defined(_TARGET_X86_) && !defined(FEATURE_PAL)
/*********************************************************************************/
/* Get the the frequency cooresponding to 'getTimeStamp'. For x86, this is the
diff --git a/src/vm/CMakeLists.txt b/src/vm/CMakeLists.txt
index 6f17a90c1f..9fdddd6c26 100644
--- a/src/vm/CMakeLists.txt
+++ b/src/vm/CMakeLists.txt
@@ -70,6 +70,7 @@ set(VM_SOURCES_DAC_AND_WKS_COMMON
formattype.cpp
fptrstubs.cpp
frames.cpp
+ gcheaputilities.cpp
genericdict.cpp
generics.cpp
hash.cpp
@@ -116,7 +117,6 @@ set(VM_SOURCES_DAC_AND_WKS_COMMON
virtualcallstub.cpp
win32threadpool.cpp
zapsig.cpp
- ${VM_SOURCES_GDBJIT}
)
if(FEATURE_READYTORUN)
@@ -155,7 +155,6 @@ set(VM_SOURCES_WKS
comthreadpool.cpp
comutilnative.cpp
comwaithandle.cpp
- constrainedexecutionregion.cpp
coverage.cpp
customattribute.cpp
custommarshalerinfo.cpp
@@ -172,7 +171,6 @@ set(VM_SOURCES_WKS
frameworkexceptionloader.cpp
gccover.cpp
gcenv.ee.cpp
- gcenv.os.cpp
gchelpers.cpp
genmeth.cpp
hosting.cpp
@@ -240,14 +238,27 @@ set(VM_SOURCES_WKS
typeparse.cpp
verifier.cpp
weakreferencenative.cpp
+ ${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
)
endif(FEATURE_EVENT_TRACE)
+if(NOT FEATURE_STANDALONE_GC)
+ list(APPEND VM_SOURCES_WKS
+ gcenv.os.cpp
+ )
+endif(NOT FEATURE_STANDALONE_GC)
+
if(WIN32)
set(VM_SOURCES_DAC_AND_WKS_WIN32
@@ -364,6 +375,13 @@ else(WIN32)
${ARCH_SOURCES_DIR}/umthunkstub.S
${ARCH_SOURCES_DIR}/virtualcallstubamd64.S
)
+ elseif(CLR_CMAKE_TARGET_ARCH_I386)
+ set(VM_SOURCES_WKS_ARCH_ASM
+ ${ARCH_SOURCES_DIR}/asmhelpers.S
+ ${ARCH_SOURCES_DIR}/jithelp.S
+ ${ARCH_SOURCES_DIR}/gmsasm.S
+ ${ARCH_SOURCES_DIR}/umthunkstub.S
+ )
elseif(CLR_CMAKE_TARGET_ARCH_ARM)
set(VM_SOURCES_WKS_ARCH_ASM
${ARCH_SOURCES_DIR}/asmhelpers.S
@@ -412,7 +430,6 @@ elseif(CLR_CMAKE_TARGET_ARCH_I386)
)
set(VM_SOURCES_WKS_ARCH
- ${ARCH_SOURCES_DIR}/jithelp.asm
${ARCH_SOURCES_DIR}/jitinterfacex86.cpp
${ARCH_SOURCES_DIR}/profiler.cpp
)
diff --git a/src/vm/amd64/CrtHelpers.asm b/src/vm/amd64/CrtHelpers.asm
index 6ec6e4d2a9..9d5b280558 100644
--- a/src/vm/amd64/CrtHelpers.asm
+++ b/src/vm/amd64/CrtHelpers.asm
@@ -13,48 +13,19 @@
; ***********************************************************************
include AsmMacros.inc
-include asmconstants.inc
-; JIT_MemSet/JIT_MemCpy
-;
-; It is IMPORANT that the exception handling code is able to find these guys
-; on the stack, but to keep them from being tailcalled by VC++ we need to turn
-; off optimization and it ends up being a wasteful implementation.
-;
-; Hence these assembly helpers.
-;
-
-
-;***
-;memset.asm - set a section of memory to all one byte
-;
-; Licensed to the .NET Foundation under one or more agreements.
-; The .NET Foundation licenses this file to you under the MIT license.
-; See the LICENSE file in the project root for more information.;
-;
-;*******************************************************************************
-
-;***
;char *memset(dst, value, count) - sets "count" bytes at "dst" to "value"
;
;Purpose:
; Sets the first "count" bytes of the memory starting
; at "dst" to the character value "value".
;
-; Algorithm:
-; char *
-; memset (dst, value, count)
-; char *dst;
-; char value;
-; unsigned int count;
-; {
-; char *start = dst;
-;
-; while (count--)
-; *dst++ = value;
-; return(start);
-; }
-;
+;Algorithm:
+;Set dst based on count as follow
+; count [0, 16]: use 1/2/4/8 bytes width registers
+; count [16, 128]: use 16 bytes width registers (XMM) without loop
+; count [128, 512]: use 16 bytes width registers (XMM) with loops, unrolled 8 times
+; count [512, upper]: use rep stosb
;Entry:
; char *dst - pointer to memory to fill with value
; char value - value to put in dst bytes
@@ -69,460 +40,291 @@ include asmconstants.inc
;
;*******************************************************************************
-CACHE_LIMIT_MEMSET equ 070000h ; limit for nontemporal fill
-
LEAF_ENTRY JIT_MemSet, _TEXT
- mov rax, rcx ; save destination address
- cmp r8, 8 ; check if 8 bytes to fill
- jb short mset40 ; if b, less than 8 bytes to fill
movzx edx, dl ; set fill pattern
- mov r9, 0101010101010101h ; replicate fill over 8 bytes
- imul rdx, r9 ;
- cmp r8, 64 ; check if 64 bytes to fill
- jb short mset20 ; if b, less than 64 bytes
-
-;
-; Large block - fill alignment bytes.
-;
-
-mset00: neg rcx ; compute bytes to alignment
- and ecx, 7 ;
- jz short mset10 ; if z, no alignment required
- sub r8, rcx ; adjust remaining bytes by alignment
- mov [rax], rdx ; fill alignment bytes
-mset10: add rcx, rax ; compute aligned destination address
-
-;
-; Attempt to fill 64-byte blocks
-;
-
- mov r9, r8 ; copy count of bytes remaining
- and r8, 63 ; compute remaining byte count
- shr r9, 6 ; compute number of 64-byte blocks
- test r9, r9 ; remove partial flag stall caused by shr
- jnz short mset70 ; if nz, 64-byte blocks to fill
-
-;
-; Fill 8-byte bytes.
-;
-
-mset20: mov r9, r8 ; copy count of bytes remaining
- and r8, 7 ; compute remaining byte count
- shr r9, 3 ; compute number of 8-byte blocks
- test r9, r9 ; remove partial flag stall caused by shr
- jz short mset40 ; if z, no 8-byte blocks
-
- align ; simpler way to align instrucitons
-
-mset30: mov [rcx], rdx ; fill 8-byte blocks
- add rcx, 8 ; advance to next 8-byte block
- dec r9 ; decrement loop count
- jnz short mset30 ; if nz, more 8-byte blocks
-
-;
-; Fill residual bytes.
-;
-
-mset40: test r8, r8 ; test if any bytes to fill
- jz short mset60 ; if z, no bytes to fill
-mset50: mov [rcx], dl ; fill byte
- inc rcx ; advance to next byte
- dec r8 ; decrement loop count
- jnz short mset50 ; if nz, more bytes to fill
-mset60:
- ; for some reason the assembler doesn't like the REPRET macro on the same line as a label
- REPRET ; return
-
-;
-; Fill 64-byte blocks.
-;
-
- align 16
-
- db 066h, 066h, 066h, 090h
- db 066h, 066h, 090h
-
-mset70: cmp r9, CACHE_LIMIT_MEMSET / 64 ; check if large fill
- jae short mset90 ; if ae, large fill
-mset80: mov [rcx], rdx ; fill 64-byte block
- mov 8[rcx], rdx ;
- mov 16[rcx], rdx ;
- add rcx, 64 ; advance to next block
- mov (24 - 64)[rcx], rdx ;
- mov (32 - 64)[rcx], rdx ;
- dec r9 ; decrement loop count
- mov (40 - 64)[rcx], rdx ;
- mov (48 - 64)[rcx], rdx ;
- mov (56 - 64)[rcx], rdx ;
- jnz short mset80 ; if nz, more 64-byte blocks
- jmp short mset20 ; finish in common code
-
-;
-; Fill 64-byte blocks nontemporal.
-;
-
- align
-
-mset90: movnti [rcx], rdx ; fill 64-byte block
- movnti 8[rcx], rdx ;
- movnti 16[rcx], rdx ;
- add rcx, 64 ; advance to next block
- movnti (24 - 64)[rcx], rdx ;
- movnti (32 - 64)[rcx], rdx ;
- dec r9 ; decrement loop count
- movnti (40 - 64)[rcx], rdx ;
- movnti (48 - 64)[rcx], rdx ;
- movnti (56 - 64)[rcx], rdx ;
- jnz short mset90 ; if nz, move 64-byte blocks
- lock or byte ptr [rsp], 0 ; flush data to memory
- jmp mset20 ; finish in common code
+ mov r9, 0101010101010101h
+ imul rdx, r9 ; rdx is 8 bytes filler
+
+ cmp r8, 16
+ jbe mset04
+
+ cmp r8, 512
+ jbe mset00
+
+ ; count > 512
+ mov r10, rcx ; save dst address
+ mov r11, rdi ; save rdi
+ mov eax, edx ; eax is value
+ mov rdi, rcx ; rdi is dst
+ mov rcx, r8 ; rcx is count
+ rep stosb
+ mov rdi, r11 ; restore rdi
+ mov rax, r10
+ ret
+
+ align 16
+mset00: mov rax, rcx ; save dst address
+ movd xmm0, rdx
+ punpcklbw xmm0, xmm0 ; xmm0 is 16 bytes filler
+
+ cmp r8, 128
+ jbe mset02
+
+ ; count > 128 && count <= 512
+ mov r9, r8
+ shr r9, 7 ; count/128
+
+ align 16
+mset01: movdqu [rcx], xmm0
+ movdqu 16[rcx], xmm0
+ movdqu 32[rcx], xmm0
+ movdqu 48[rcx], xmm0
+ movdqu 64[rcx], xmm0
+ movdqu 80[rcx], xmm0
+ movdqu 96[rcx], xmm0
+ movdqu 112[rcx], xmm0
+ add rcx, 128
+ dec r9
+ jnz mset01
+ and r8, 7fh ; and r8 with 0111 1111
+
+ ; the remainder is from 0 to 127
+ cmp r8, 16
+ jnbe mset02
+
+ ; the remainder <= 16
+ movdqu -16[rcx + r8], xmm0
+ ret
+
+ ; count > 16 && count <= 128 for mset02
+ align 16
+mset02: movdqu [rcx], xmm0
+ movdqu -16[rcx + r8], xmm0
+ cmp r8, 32
+ jbe mset03
+
+ ; count > 32 && count <= 64
+ movdqu 16[rcx], xmm0
+ movdqu -32[rcx + r8], xmm0
+ cmp r8, 64
+ jbe mset03
+
+ ; count > 64 && count <= 128
+ movdqu 32[rcx], xmm0
+ movdqu 48[rcx], xmm0
+ movdqu -48[rcx + r8], xmm0
+ movdqu -64[rcx + r8], xmm0
+mset03: ret
+
+ align 16
+mset04: mov rax, rcx ; save dst address
+ test r8b, 24 ; and r8b with 0001 1000
+ jz mset05
+
+ ; count >= 8 && count <= 16
+ mov [rcx], rdx
+ mov -8[rcx + r8], rdx
+ ret
+
+ align 16
+mset05: test r8b, 4 ; and r8b with 0100
+ jz mset06
+
+ ; count >= 4 && count < 8
+ mov [rcx], edx
+ mov -4[rcx + r8], edx
+ ret
+
+ ; count >= 0 && count < 4
+ align 16
+mset06: test r8b, 1 ; and r8b with 0001
+ jz mset07
+ mov [rcx],dl
+mset07: test r8b, 2 ; and r8b with 0010
+ jz mset08
+ mov -2[rcx + r8], dx
+mset08: ret
LEAF_END_MARKED JIT_MemSet, _TEXT
-;*******************************************************************************
-; This ensures that atomic updates of aligned fields will stay atomic.
-;***
;JIT_MemCpy - Copy source buffer to destination buffer
;
;Purpose:
-;JIT_MemCpy - Copy source buffer to destination buffer
-;
-;Purpose:
-; JIT_MemCpy() copies a source memory buffer to a destination memory
-; buffer. This routine recognize overlapping buffers to avoid propogation.
-; For cases where propogation is not a problem, memcpy() can be used.
+; JIT_MemCpy() copies a source memory buffer to a destination memory
+; buffer. This routine recognize overlapping buffers to avoid propogation.
+; For cases where propogation is not a problem, memcpy() can be used.
+;
+;Algorithm:
+;Copy to destination based on count as follow
+; count [0, 64]: overlap check not needed
+; count [0, 16]: use 1/2/4/8 bytes width registers
+; count [16, 64]: use 16 bytes width registers (XMM) without loop
+; count [64, upper]: check overlap
+; non-overlap:
+; count [64, 512]: use 16 bytes width registers (XMM) with loops, unrolled 4 times
+; count [512, upper]: use rep movsb
+; overlap::
+; use 16 bytes width registers (XMM) with loops to copy from end to beginnig
;
;Entry:
-; void *dst = pointer to destination buffer
-; const void *src = pointer to source buffer
-; size_t count = number of bytes to copy
+; void *dst = pointer to destination buffer
+; const void *src = pointer to source buffer
+; size_t count = number of bytes to copy
;
;Exit:
-; Returns a pointer to the destination buffer in AX/DX:AX
+; Returns a pointer to the destination buffer
;
;Uses:
-; CX, DX
;
;Exceptions:
;*******************************************************************************
-; This ensures that atomic updates of aligned fields will stay atomic.
-
-CACHE_LIMIT_MEMMOV equ 040000h ; limit for nontemporal fill
-CACHE_BLOCK equ 01000h ; nontemporal move block size
-
LEAF_ENTRY JIT_MemCpy, _TEXT
- mov r11, rcx ; save destination address
- sub rdx, rcx ; compute offset to source buffer
- jb mmov10 ; if b, destination may overlap
- cmp r8, 8 ; check if 8 bytes to move
- jb short mcpy40 ; if b, less than 8 bytes to move
-
-;
-; Move alignment bytes.
-;
-
- test cl, 7 ; test if destination aligned
- jz short mcpy20 ; if z, destination aligned
- test cl, 1 ; test if byte move needed
- jz short mcpy00 ; if z, byte move not needed
- mov al, [rcx + rdx] ; move byte
- dec r8 ; decrement byte count
- mov [rcx], al ;
- inc rcx ; increment destination address
-mcpy00: test cl, 2 ; test if word move needed
- jz short mcpy10 ; if z, word move not needed
- mov ax, [rcx + rdx] ; move word
- sub r8, 2 ; reduce byte count
- mov [rcx], ax ;
- add rcx, 2 ; advance destination address
-mcpy10: test cl, 4 ; test if dword move needed
- jz short mcpy20 ; if z, dword move not needed
- mov eax, [rcx + rdx] ; move dword
- sub r8, 4 ; reduce byte count
- mov [rcx], eax ;
- add rcx, 4 ; advance destination address
-
-;
-; Attempt to move 32-byte blocks.
-;
-
-mcpy20: mov r9, r8 ; copy count of bytes remaining
- shr r9, 5 ; compute number of 32-byte blocks
- test r9, r9 ; v-liti, remove partial flag stall caused by shr
- jnz short mcpy60 ; if nz, 32-byte blocks to fill
-
- align
-;
-; Move 8-byte blocks.
-;
-
-mcpy25: mov r9, r8 ; copy count of bytes remaining
- shr r9, 3 ; compute number of 8-byte blocks
- test r9, r9 ; v-liti, remove partial flag stall caused by shr
- jz short mcpy40 ; if z, no 8-byte blocks
- align
-
-mcpy30: mov rax, [rcx + rdx] ; move 8-byte blocks
- mov [rcx], rax ;
- add rcx, 8 ; advance destination address
- dec r9 ; decrement loop count
- jnz short mcpy30 ; if nz, more 8-byte blocks
- and r8, 7 ; compute remaining byte count
-
-;
-; Test for residual bytes.
-;
-
-mcpy40: test r8, r8 ; test if any bytes to move
- jnz short mcpy50 ; if nz, residual bytes to move
- mov rax, r11 ; set destination address
- ret ;
-
-;
-; Move residual bytes.
-;
-
- align
-
-mcpy50: mov al, [rcx + rdx] ; move byte
- mov [rcx], al ;
- inc rcx ; increment destiantion address
- dec r8 ; decrement loop count
- jnz short mcpy50 ; if nz, more bytes to fill
- mov rax, r11 ; set destination address
- ret ; return
+ mov rax, rcx ; save dst address
+ cmp r8, 16
+ jbe mcpy02
+
+ cmp r8, 64
+ jnbe mcpy07
+
+ ; count > 16 && count <= 64
+ align 16
+mcpy00: movdqu xmm0, [rdx]
+ movdqu xmm1, -16[rdx + r8] ; save 16 to 32 bytes src
+ cmp r8, 32
+ jbe mcpy01
+
+ movdqu xmm2, 16[rdx]
+ movdqu xmm3, -32[rdx + r8] ; save 32 to 64 bytes src
+
+ ;count > 32 && count <= 64
+ movdqu 16[rcx], xmm2
+ movdqu -32[rcx + r8], xmm3
+
+ ;count > 16 && count <= 32
+mcpy01: movdqu [rcx], xmm0
+ movdqu -16[rcx + r8], xmm1
+ ret
+
+ ; count <= 16
+ align 16
+mcpy02: test r8b, 24 ; test count with 0001 1000
+ jz mcpy03
+ ; count >= 8 && count <= 16
+ mov r9, [rdx]
+ mov r10, -8[rdx + r8]
+ mov [rcx], r9
+ mov -8[rcx + r8], r10
+ ret
+
+ align 16
+mcpy03: test r8b, 4 ; test count with 0100
+ jz mcpy04
+ ; count >= 4 && count < 8
+ mov r9d, [rdx]
+ mov r10d, -4[rdx + r8]
+ mov [rcx], r9d
+ mov -4[rcx + r8], r10d
+ ret
+
+ ; count >= 0 && count < 4
+ align 16
+mcpy04: test r8, r8
+ jz mcpy06 ; count == 1/2/3
+ mov r9b, [rdx] ; save the first byte
+
+ test r8b, 2 ; test count with 0010
+ jz mcpy05
+ mov r10w, -2[rdx + r8]
+ mov -2[rcx + r8], r10w
+mcpy05: mov [rcx], r9b
+mcpy06: ret
+
+ align 16
+ ; count > 64, we need to check overlap
+mcpy07: mov r9, rdx ; r9 is src address
+ sub r9, rcx ; if src - dst < 0 jump to mcpy11
+ jb mcpy11 ; if b, destination may overlap
+
+mcpy08: cmp r8, 512
+ jnbe mcpy10
+
+ ; count > 64 && count <= 512
+ mov r9, r8
+ shr r9, 6 ; count/64
+
+ align 16
+mcpy09: movdqu xmm0, [rdx]
+ movdqu xmm1, 16[rdx]
+ movdqu xmm2, 32[rdx]
+ movdqu xmm3, 48[rdx]
+ movdqu [rcx], xmm0
+ movdqu 16[rcx], xmm1
+ movdqu 32[rcx], xmm2
+ movdqu 48[rcx], xmm3
+ add rdx, 64
+ add rcx, 64
+ dec r9
+ jnz mcpy09
+
+ ; the remainder is from 0 to 63
+ and r8, 3fh ; and with 0011 1111
+ cmp r8, 16
+ jnbe mcpy00
+
+ ; the remainder <= 16
+ jmp mcpy02
+ ret
+
+ ; count > 512
+ align 16
+mcpy10: mov r10, rdi ; save rdi
+ mov r11, rsi ; save rsi
+ mov rdi, rcx ; rdi is dst
+ mov rsi, rdx ; rsi is src
+ mov rcx, r8 ; rcx is count
+ rep movsb ; mov from rsi to rdi
+ mov rsi, r11 ; restore rsi
+ mov rdi, r10 ; restore rdi
+ ret
-;
-; Move 32 byte blocks
-;
-
- align 16
-
- db 066h, 066h, 066h, 090h
- db 066h, 066h, 090h
-
-mcpy60: cmp r9, CACHE_LIMIT_MEMMOV / 32 ; check if large move
- jae short mcpy80 ; if ae, large move
-mcpy70: mov rax, [rcx + rdx] ; move 32-byte block
- mov r10, 8[rcx + rdx] ;
- add rcx, 32 ; advance destination address
- mov (-32)[rcx], rax ;
- mov (-24)[rcx], r10 ;
- mov rax, (-16)[rcx + rdx] ;
- mov r10, (-8)[rcx + rdx] ;
- dec r9 ;
- mov (-16)[rcx], rax ;
- mov (-8)[rcx], r10 ;
- jnz short mcpy70 ; if nz, more 32-byte blocks
- and r8, 31 ; compute remaining byte count
- jmp mcpy25 ;
-
-;
-; Move 64-byte blocks nontemporal.
-;
-
- align
-
- db 066h, 090h
-
-mcpy80: cmp rdx, CACHE_BLOCK ; check if cache block spacing
- jb short mcpy70 ; if b, not cache block spaced
-mcpy81: mov eax, CACHE_BLOCK / 128 ; set loop count
-mcpy85: prefetchnta [rcx + rdx] ; prefetch 128 bytes
- prefetchnta 64[rcx + rdx] ;
- add rcx, 128 ; advance source address
- dec eax ; decrement loop count
- jnz short mcpy85 ; if nz, more to prefetch
- sub rcx, CACHE_BLOCK ; reset source address
- mov eax, CACHE_BLOCK / 64 ; set loop count
-mcpy90: mov r9, [rcx + rdx] ; move 64-byte block
- mov r10, 8[rcx + rdx] ;
- movnti [rcx], r9 ;
- movnti 8[rcx], r10 ;
- mov r9, 16[rcx + rdx] ;
- mov r10, 24[rcx + rdx] ;
- movnti 16[rcx], r9 ;
- movnti 24[rcx], r10 ;
- mov r9, 32[rcx + rdx] ;
- mov r10, 40[rcx + rdx] ;
- add rcx, 64 ; advance destination address
- movnti (32 - 64)[rcx], r9 ;
- movnti (40 - 64)[rcx], r10 ;
- mov r9, (48 - 64)[rcx + rdx] ;
- mov r10, (56 - 64)[rcx + rdx] ;
- dec eax ;
- movnti (48 - 64)[rcx], r9 ;
- movnti (56 - 64)[rcx], r10 ;
- jnz short mcpy90 ; if nz, more 32-byte blocks
- sub r8, CACHE_BLOCK ; reduce remaining length
- cmp r8, CACHE_BLOCK ; check if cache block remains
- jae mcpy81 ; if ae, cache block remains
- lock or byte ptr [rsp], 0 ; flush data to memory
- jmp mcpy20 ;
-
-;
; The source address is less than the destination address.
-;
-
- align
-
- db 066h, 066h, 066h, 090h
- db 066h, 066h, 066h, 090h
- db 066h, 090h
-
-mmov10: add rcx, r8 ; compute ending destination address
- cmp r8, 8 ; check if 8 bytes to move
- jb short mmov60 ; if b, less than 8 bytes to move
-
-;
-; Move alignment bytes.
-;
-
- test cl, 7 ; test if destination aligned
- jz short mmov30 ; if z, destination aligned
- test cl, 1 ; test if byte move needed
- jz short mmov15 ; if z, byte move not needed
- dec rcx ; decrement destination address
- mov al, [rcx + rdx] ; move byte
- dec r8 ; decrement byte count
- mov [rcx], al ;
-mmov15: test cl, 2 ; test if word move needed
- jz short mmov20 ; if z, word move not needed
- sub rcx, 2 ; reduce destination address
- mov ax, [rcx + rdx] ; move word
- sub r8, 2 ; reduce byte count
- mov [rcx], ax ;
-mmov20: test cl, 4 ; test if dword move needed
- jz short mmov30 ; if z, dword move not needed
- sub rcx, 4 ; reduce destination address
- mov eax, [rcx + rdx] ; move dword
- sub r8, 4 ; reduce byte count
- mov [rcx], eax ;
-
-;
-; Attempt to move 32-byte blocks
-;
-
-mmov30: mov r9, r8 ; copy count of bytes remaining
- shr r9, 5 ; compute number of 32-byte blocks
- test r9, r9 ; v-liti, remove partial flag stall caused by shr
- jnz short mmov80 ; if nz, 32-byte blocks to fill
-
-;
-; Move 8-byte blocks.
-;
- align
-
-mmov40: mov r9, r8 ; copy count of bytes remaining
- shr r9, 3 ; compute number of 8-byte blocks
- test r9, r9 ; v-liti, remove partial flag stall caused by shr
- jz short mmov60 ; if z, no 8-byte blocks
-
- align
-
-mmov50: sub rcx, 8 ; reduce destination address
- mov rax, [rcx + rdx] ; move 8-byte blocks
- dec r9 ; decrement loop count
- mov [rcx], rax ;
- jnz short mmov50 ; if nz, more 8-byte blocks
- and r8, 7 ; compute remaining byte count
-
-;
-; Test for residual bytes.
-;
-
-mmov60: test r8, r8 ; test if any bytes to move
- jnz short mmov70 ; if nz, residual bytes to move
- mov rax, r11 ; set destination address
- ret ;
-
-;
-; Move residual bytes.
-;
-
- align
-mmov70: dec rcx ; decrement destination address
- mov al, [rcx + rdx] ; move byte
- dec r8 ; decrement loop count
- mov [rcx], al ;
- jnz short mmov70 ; if nz, more bytes to fill
- mov rax, r11 ; set destination address
- ret ; return
-
-;
-; Move 32 byte blocks
-;
-
- align 16
-
- db 066h, 066h, 066h, 090h
- db 066h, 066h, 090h
-
-mmov80: cmp r9, CACHE_LIMIT_MEMMOV / 32 ; check if large move
- jae short mmov93 ; if ae, large move
-mmov90: mov rax, (-8)[rcx + rdx] ; move 32-byte block
- mov r10, (-16)[rcx + rdx] ;
- sub rcx, 32 ; reduce destination address
- mov 24[rcx], rax ;
- mov 16[rcx], r10 ;
- mov rax, 8[rcx + rdx] ;
- mov r10, [rcx + rdx] ;
- dec r9 ;
- mov 8[rcx], rax ;
- mov [rcx], r10 ;
- jnz short mmov90 ; if nz, more 32-byte blocks
- and r8, 31 ; compute remaining byte count
- jmp mmov40 ;
-
-;
-; Move 64-byte blocks nontemporal.
-;
-
- align
-
- db 066h, 090h
-
-mmov93: cmp rdx, -CACHE_BLOCK ; check if cache block spacing
- ja short mmov90 ; if a, not cache block spaced
-mmov94: mov eax, CACHE_BLOCK / 128 ; set loop count
-mmov95: sub rcx, 128 ; reduce destination address
- prefetchnta [rcx + rdx] ; prefetch 128 bytes
- prefetchnta 64[rcx + rdx] ;
- dec eax ; decrement loop count
- jnz short mmov95 ; if nz, more to prefetch
- add rcx, CACHE_BLOCK ; reset source address
- mov eax, CACHE_BLOCK / 64 ; set loop count
-mmov97: mov r9, (-8)[rcx + rdx] ; move 64-byte block
- mov r10, (-16)[rcx + rdx] ;
- movnti (-8)[rcx], r9 ;
- movnti (-16)[rcx], r10 ;
- mov r9, (-24)[rcx + rdx] ;
- mov r10, (-32)[rcx + rdx] ;
- movnti (-24)[rcx], r9 ;
- movnti (-32)[rcx], r10 ;
- mov r9, (-40)[rcx + rdx] ;
- mov r10, (-48)[rcx + rdx] ;
- sub rcx, 64 ; reduce destination address
- movnti (64 - 40)[rcx], r9 ;
- movnti (64 - 48)[rcx], r10 ;
- mov r9, (64 - 56)[rcx + rdx] ;
- mov r10, (64 - 64)[rcx + rdx] ;
- dec eax ; decrement loop count
- movnti (64 - 56)[rcx], r9 ;
- movnti (64 - 64)[rcx], r10 ;
- jnz short mmov97 ; if nz, more 32-byte blocks
- sub r8, CACHE_BLOCK ; reduce remaining length
- cmp r8, CACHE_BLOCK ; check if cache block remains
- jae mmov94 ; if ae, cache block remains
- lock or byte ptr [rsp], 0 ; flush data to memory
- jmp mmov30 ;
+ align 16
+mcpy11: add r9, r8 ; src - dst + count
+ cmp r9, 0 ; src + count < = dst jump to mcpy08
+ jle mcpy08
+
+ lea r9, [rdx + r8] ; r9 is the src + count
+ lea r10, [rcx + r8] ; r10 is the dst + count
+
+ mov r11, r8
+ shr r11, 6 ; count/64
+
+ ; count > 64
+ align 16
+mcpy12: movdqu xmm0, -16[r9]
+ movdqu xmm1, -32[r9]
+ movdqu xmm2, -48[r9]
+ movdqu xmm3, -64[r9]
+ movdqu -16[r10], xmm0
+ movdqu -32[r10], xmm1
+ movdqu -48[r10], xmm2
+ movdqu -64[r10], xmm3
+ sub r9, 64
+ sub r10, 64
+ dec r11
+ jnz mcpy12
+
+ ; the remainder is from 0 to 63
+ and r8, 3fh ; and with 0011 1111
+ cmp r8, 16
+ jnbe mcpy00
+
+ ; the remainder <= 16
+ jmp mcpy02
LEAF_END_MARKED JIT_MemCpy, _TEXT
-
-
- end
-
+ end \ No newline at end of file
diff --git a/src/vm/amd64/asmconstants.h b/src/vm/amd64/asmconstants.h
index 32b23c83c3..ad90dd17ad 100644
--- a/src/vm/amd64/asmconstants.h
+++ b/src/vm/amd64/asmconstants.h
@@ -164,10 +164,10 @@ ASMCONSTANTS_C_ASSERT(OFFSETOF__Thread__m_ThreadId
== offsetof(Thread, m_ThreadId));
#define OFFSET__Thread__m_alloc_context__alloc_ptr 0x60
-ASMCONSTANTS_C_ASSERT(OFFSET__Thread__m_alloc_context__alloc_ptr == offsetof(Thread, m_alloc_context) + offsetof(alloc_context, alloc_ptr));
+ASMCONSTANTS_C_ASSERT(OFFSET__Thread__m_alloc_context__alloc_ptr == offsetof(Thread, m_alloc_context) + offsetof(gc_alloc_context, alloc_ptr));
#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(alloc_context, alloc_limit));
+ASMCONSTANTS_C_ASSERT(OFFSET__Thread__m_alloc_context__alloc_limit == offsetof(Thread, m_alloc_context) + offsetof(gc_alloc_context, alloc_limit));
#define OFFSETOF__ThreadExceptionState__m_pCurrentTracker 0x000
ASMCONSTANTS_C_ASSERT(OFFSETOF__ThreadExceptionState__m_pCurrentTracker
diff --git a/src/vm/amd64/cgencpu.h b/src/vm/amd64/cgencpu.h
index 258ac38915..769f4029ee 100644
--- a/src/vm/amd64/cgencpu.h
+++ b/src/vm/amd64/cgencpu.h
@@ -65,14 +65,16 @@ EXTERN_C void FastCallFinalizeWorker(Object *obj, PCODE funcPtr);
#define CACHE_LINE_SIZE 64 // Current AMD64 processors have 64-byte cache lines as per AMD64 optmization manual
#define LOG2SLOT LOG2_PTRSIZE
-#define ENREGISTERED_RETURNTYPE_INTEGER_MAXSIZE 8 // bytes
-#define ENREGISTERED_PARAMTYPE_MAXSIZE 8 // bytes
#ifdef UNIX_AMD64_ABI
+#define ENREGISTERED_RETURNTYPE_INTEGER_MAXSIZE 16 // bytes
+#define ENREGISTERED_PARAMTYPE_MAXSIZE 16 // bytes
#define ENREGISTERED_RETURNTYPE_MAXSIZE 16 // bytes
#define CALLDESCR_ARGREGS 1 // CallDescrWorker has ArgumentRegister parameter
#define CALLDESCR_FPARGREGS 1 // CallDescrWorker has FloatArgumentRegisters parameter
#else
+#define ENREGISTERED_RETURNTYPE_INTEGER_MAXSIZE 8 // bytes
+#define ENREGISTERED_PARAMTYPE_MAXSIZE 8 // bytes
#define ENREGISTERED_RETURNTYPE_MAXSIZE 8 // bytes
#define COM_STUBS_SEPARATE_FP_LOCATIONS
#define CALLDESCR_REGTYPEMAP 1
diff --git a/src/vm/amd64/excepamd64.cpp b/src/vm/amd64/excepamd64.cpp
index 2fc553a987..d4248e7b07 100644
--- a/src/vm/amd64/excepamd64.cpp
+++ b/src/vm/amd64/excepamd64.cpp
@@ -21,7 +21,7 @@
#include "comutilnative.h"
#include "sigformat.h"
#include "siginfo.hpp"
-#include "gc.h"
+#include "gcheaputilities.h"
#include "eedbginterfaceimpl.h" //so we can clearexception in COMPlusThrow
#include "perfcounters.h"
#include "asmconstants.h"
diff --git a/src/vm/amd64/jitinterfaceamd64.cpp b/src/vm/amd64/jitinterfaceamd64.cpp
index 39c2e05c2f..d5dec8e6e8 100644
--- a/src/vm/amd64/jitinterfaceamd64.cpp
+++ b/src/vm/amd64/jitinterfaceamd64.cpp
@@ -390,7 +390,7 @@ bool WriteBarrierManager::NeedDifferentWriteBarrier(bool bReqUpperBoundsCheck, W
}
#endif
- writeBarrierType = GCHeap::IsServerHeap() ? WRITE_BARRIER_SVR64 : WRITE_BARRIER_PREGROW64;
+ writeBarrierType = GCHeapUtilities::IsServerHeap() ? WRITE_BARRIER_SVR64 : WRITE_BARRIER_PREGROW64;
continue;
case WRITE_BARRIER_PREGROW64:
diff --git a/src/vm/amd64/umthunkstub.S b/src/vm/amd64/umthunkstub.S
index e388f15490..3e60bedb3f 100644
--- a/src/vm/amd64/umthunkstub.S
+++ b/src/vm/amd64/umthunkstub.S
@@ -83,7 +83,7 @@ LOCAL_LABEL(HaveThread):
mov r12, rax // r12 <- Thread*
- //FailFast if a native callable method invoked via ldftn and calli.
+ //FailFast if a native callable method is invoked via ldftn and calli.
cmp dword ptr [r12 + OFFSETOF__Thread__m_fPreemptiveGCDisabled], 1
jz LOCAL_LABEL(InvalidTransition)
diff --git a/src/vm/appdomain.cpp b/src/vm/appdomain.cpp
index 0ec2c5f2fc..34da344c94 100644
--- a/src/vm/appdomain.cpp
+++ b/src/vm/appdomain.cpp
@@ -12,7 +12,7 @@
#include "strongnameinternal.h"
#include "excep.h"
#include "eeconfig.h"
-#include "gc.h"
+#include "gcheaputilities.h"
#include "eventtrace.h"
#ifdef FEATURE_FUSION
#include "assemblysink.h"
@@ -2652,8 +2652,8 @@ void AppDomain::CreateADUnloadStartEvent()
// If the thread is in cooperative mode, it must have been suspended for the GC so a delete
// can't happen.
- _ASSERTE(GCHeap::IsGCInProgress() &&
- GCHeap::IsServerHeap() &&
+ _ASSERTE(GCHeapUtilities::IsGCInProgress() &&
+ GCHeapUtilities::IsServerHeap() &&
IsGCSpecialThread());
SystemDomain* sysDomain = SystemDomain::System();
@@ -2691,7 +2691,7 @@ void SystemDomain::ResetADSurvivedBytes()
}
CONTRACT_END;
- _ASSERTE(GCHeap::IsGCInProgress());
+ _ASSERTE(GCHeapUtilities::IsGCInProgress());
SystemDomain* sysDomain = SystemDomain::System();
if (sysDomain)
@@ -2870,6 +2870,11 @@ void SystemDomain::LoadBaseSystemClasses()
// the SZArrayHelper class here.
g_pSZArrayHelperClass = MscorlibBinder::GetClass(CLASS__SZARRAYHELPER);
+#ifdef FEATURE_SPAN_OF_T
+ // Load ByReference class
+ g_pByReferenceClass = MscorlibBinder::GetClass(CLASS__BYREFERENCE);
+#endif
+
// Load Nullable class
g_pNullableClass = MscorlibBinder::GetClass(CLASS__NULLABLE);
@@ -2943,6 +2948,7 @@ 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
@@ -2951,6 +2957,7 @@ void SystemDomain::LoadBaseSystemClasses()
// 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);
@@ -2980,7 +2987,9 @@ 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.
@@ -3824,7 +3833,7 @@ HRESULT SystemDomain::RunDllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpReser
return S_OK;
// ExitProcess is called while a thread is doing GC.
- if (dwReason == DLL_PROCESS_DETACH && GCHeap::IsGCInProgress())
+ if (dwReason == DLL_PROCESS_DETACH && GCHeapUtilities::IsGCInProgress())
return S_OK;
// ExitProcess is called on a thread that we don't know about
@@ -5107,7 +5116,7 @@ void AppDomain::Init()
// Ref_CreateHandleTableBucket, this is because AD::Init() can race with GC
// and once we add ourselves to the handle table map the GC can start walking
// our handles and calling AD::RecordSurvivedBytes() which touches ARM data.
- if (GCHeap::IsServerHeap())
+ if (GCHeapUtilities::IsServerHeap())
m_dwNumHeaps = CPUGroupInfo::CanEnableGCCPUGroups() ?
CPUGroupInfo::GetNumActiveProcessors() :
GetCurrentProcessCpuCount();
@@ -8084,6 +8093,13 @@ 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*/)
{
@@ -8241,7 +8257,7 @@ public:
}
else
{
- IfFailRet(FString::Utf8_Unicode(szName, bIsAscii, wzBuffer, cchBuffer));
+ IfFailRet(FString::Utf8_Unicode(szName, bIsAscii, wzBuffer, cchName));
if (pcchBuffer != nullptr)
{
*pcchBuffer = cchName;
@@ -11110,7 +11126,7 @@ void AppDomain::Unload(BOOL fForceUnload)
}
if(bForceGC)
{
- GCHeap::GetGCHeap()->GarbageCollect();
+ GCHeapUtilities::GetGCHeap()->GarbageCollect();
FinalizerThread::FinalizerThreadWait();
SetStage(STAGE_COLLECTED);
Close(); //NOTHROW!
@@ -11128,14 +11144,14 @@ void AppDomain::Unload(BOOL fForceUnload)
if (takeSnapShot)
{
char buffer[1024];
- sprintf(buffer, "vadump -p %d -o > vadump.%d", GetCurrentProcessId(), unloadCount);
+ sprintf_s(buffer, _countof(buffer), "vadump -p %d -o > vadump.%d", GetCurrentProcessId(), unloadCount);
system(buffer);
- sprintf(buffer, "umdh -p:%d -d -i:1 -f:umdh.%d", GetCurrentProcessId(), unloadCount);
+ sprintf_s(buffer, _countof(buffer), "umdh -p:%d -d -i:1 -f:umdh.%d", GetCurrentProcessId(), unloadCount);
system(buffer);
int takeDHSnapShot = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_ADTakeDHSnapShot);
if (takeDHSnapShot)
{
- sprintf(buffer, "dh -p %d -s -g -h -b -f dh.%d", GetCurrentProcessId(), unloadCount);
+ sprintf_s(buffer, _countof(buffer), "dh -p %d -s -g -h -b -f dh.%d", GetCurrentProcessId(), unloadCount);
system(buffer);
}
}
@@ -11146,7 +11162,7 @@ void AppDomain::Unload(BOOL fForceUnload)
{
// do extra finalizer wait to remove any leftover sb entries
FinalizerThread::FinalizerThreadWait();
- GCHeap::GetGCHeap()->GarbageCollect();
+ GCHeapUtilities::GetGCHeap()->GarbageCollect();
FinalizerThread::FinalizerThreadWait();
LogSpewAlways("Done unload %3.3d\n", unloadCount);
DumpSyncBlockCache();
@@ -11548,7 +11564,7 @@ void AppDomain::ClearGCHandles()
SetStage(STAGE_HANDLETABLE_NOACCESS);
- GCHeap::GetGCHeap()->WaitUntilConcurrentGCComplete();
+ GCHeapUtilities::GetGCHeap()->WaitUntilConcurrentGCComplete();
// Keep async pin handles alive by moving them to default domain
HandleAsyncPinHandles();
@@ -12567,11 +12583,13 @@ 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();
}
@@ -13516,8 +13534,8 @@ void SystemDomain::ProcessDelayedUnloadDomains()
}
CONTRACTL_END;
- int iGCRefPoint=GCHeap::GetGCHeap()->CollectionCount(GCHeap::GetGCHeap()->GetMaxGeneration());
- if (GCHeap::GetGCHeap()->IsConcurrentGCInProgress())
+ int iGCRefPoint=GCHeapUtilities::GetGCHeap()->CollectionCount(GCHeapUtilities::GetGCHeap()->GetMaxGeneration());
+ if (GCHeapUtilities::GetGCHeap()->IsConcurrentGCInProgress())
iGCRefPoint--;
BOOL bAppDomainToCleanup = FALSE;
@@ -13695,7 +13713,6 @@ ULONG ADUnloadSink::Release()
if (ulRef == 0)
{
delete this;
- return 0;
}
return ulRef;
};
@@ -13735,8 +13752,8 @@ void AppDomain::EnumStaticGCRefs(promote_func* fn, ScanContext* sc)
}
CONTRACT_END;
- _ASSERTE(GCHeap::IsGCInProgress() &&
- GCHeap::IsServerHeap() &&
+ _ASSERTE(GCHeapUtilities::IsGCInProgress() &&
+ GCHeapUtilities::IsServerHeap() &&
IsGCSpecialThread());
AppDomain::AssemblyIterator asmIterator = IterateAssembliesEx((AssemblyIterationFlags)(kIncludeLoaded | kIncludeExecution));
diff --git a/src/vm/appdomain.hpp b/src/vm/appdomain.hpp
index 97e8438329..670f685fdc 100644
--- a/src/vm/appdomain.hpp
+++ b/src/vm/appdomain.hpp
@@ -30,6 +30,7 @@
#include "fptrstubs.h"
#include "ilstubcache.h"
#include "testhookmgr.h"
+#include "gcheaputilities.h"
#ifdef FEATURE_VERSIONING
#include "../binder/inc/applicationcontext.hpp"
#endif // FEATURE_VERSIONING
@@ -1295,7 +1296,7 @@ public:
{
WRAPPER_NO_CONTRACT;
OBJECTHANDLE h = ::CreateSizedRefHandle(
- m_hHandleTableBucket->pTable[GCHeap::IsServerHeap() ? (m_dwSizedRefHandles % m_iNumberOfProcessors) : GetCurrentThreadHomeHeapNumber()],
+ m_hHandleTableBucket->pTable[GCHeapUtilities::IsServerHeap() ? (m_dwSizedRefHandles % m_iNumberOfProcessors) : GetCurrentThreadHomeHeapNumber()],
object);
InterlockedIncrement((LONG*)&m_dwSizedRefHandles);
return h;
@@ -2430,6 +2431,9 @@ public:
LPCWSTR wszCodeBase);
#ifndef DACCESS_COMPILE // needs AssemblySpec
+
+ void GetCacheAssemblyList(SetSHash<PTR_DomainAssembly>& assemblyList);
+
//****************************************************************************************
// Returns and Inserts assemblies into a lookup cache based on the binding information
// in the AssemblySpec. There can be many AssemblySpecs to a single assembly.
@@ -4533,8 +4537,8 @@ public:
if (m_UnloadIsAsync)
{
pDomain->AddRef();
- int iGCRefPoint=GCHeap::GetGCHeap()->CollectionCount(GCHeap::GetGCHeap()->GetMaxGeneration());
- if (GCHeap::GetGCHeap()->IsGCInProgress())
+ int iGCRefPoint=GCHeapUtilities::GetGCHeap()->CollectionCount(GCHeapUtilities::GetGCHeap()->GetMaxGeneration());
+ if (GCHeapUtilities::IsGCInProgress())
iGCRefPoint++;
pDomain->SetGCRefPoint(iGCRefPoint);
}
@@ -4554,8 +4558,8 @@ public:
pAllocator->m_pLoaderAllocatorDestroyNext=m_pDelayedUnloadListOfLoaderAllocators;
m_pDelayedUnloadListOfLoaderAllocators=pAllocator;
- int iGCRefPoint=GCHeap::GetGCHeap()->CollectionCount(GCHeap::GetGCHeap()->GetMaxGeneration());
- if (GCHeap::GetGCHeap()->IsGCInProgress())
+ int iGCRefPoint=GCHeapUtilities::GetGCHeap()->CollectionCount(GCHeapUtilities::GetGCHeap()->GetMaxGeneration());
+ if (GCHeapUtilities::IsGCInProgress())
iGCRefPoint++;
pAllocator->SetGCRefPoint(iGCRefPoint);
}
diff --git a/src/vm/arm/asmconstants.h b/src/vm/arm/asmconstants.h
index 47ebb2d24d..93af04734e 100644
--- a/src/vm/arm/asmconstants.h
+++ b/src/vm/arm/asmconstants.h
@@ -225,10 +225,10 @@ ASMCONSTANTS_C_ASSERT(UnmanagedToManagedFrame__m_pvDatum == offsetof(UnmanagedTo
#ifndef CROSSGEN_COMPILE
#define Thread__m_alloc_context__alloc_limit 0x44
-ASMCONSTANTS_C_ASSERT(Thread__m_alloc_context__alloc_limit == offsetof(Thread, m_alloc_context) + offsetof(alloc_context, alloc_limit));
+ASMCONSTANTS_C_ASSERT(Thread__m_alloc_context__alloc_limit == offsetof(Thread, m_alloc_context) + offsetof(gc_alloc_context, alloc_limit));
#define Thread__m_alloc_context__alloc_ptr 0x40
-ASMCONSTANTS_C_ASSERT(Thread__m_alloc_context__alloc_ptr == offsetof(Thread, m_alloc_context) + offsetof(alloc_context, alloc_ptr));
+ASMCONSTANTS_C_ASSERT(Thread__m_alloc_context__alloc_ptr == offsetof(Thread, m_alloc_context) + offsetof(gc_alloc_context, alloc_ptr));
#endif // CROSSGEN_COMPILE
#define Thread__m_fPreemptiveGCDisabled 0x08
diff --git a/src/vm/arm/cgencpu.h b/src/vm/arm/cgencpu.h
index 936fdabafb..63c578bb88 100644
--- a/src/vm/arm/cgencpu.h
+++ b/src/vm/arm/cgencpu.h
@@ -36,10 +36,12 @@ Stub * GenerateInitPInvokeFrameHelper();
EXTERN_C void checkStack(void);
+#define THUMB_CODE 1
+
#ifdef CROSSGEN_COMPILE
#define GetEEFuncEntryPoint(pfn) 0x1001
#else
-#define GetEEFuncEntryPoint(pfn) GFN_TADDR(pfn)
+#define GetEEFuncEntryPoint(pfn) (GFN_TADDR(pfn) | THUMB_CODE)
#endif
//**********************************************************************
@@ -306,8 +308,6 @@ inline PCODE decodeBackToBackJump(PCODE pBuffer)
#include "stublink.h"
struct ArrayOpScript;
-#define THUMB_CODE 1
-
inline BOOL IsThumbCode(PCODE pCode)
{
return (pCode & THUMB_CODE) != 0;
diff --git a/src/vm/arm/stubs.cpp b/src/vm/arm/stubs.cpp
index 0b069da47e..1309695f73 100644
--- a/src/vm/arm/stubs.cpp
+++ b/src/vm/arm/stubs.cpp
@@ -2650,7 +2650,7 @@ void InitJITHelpers1()
))
{
- _ASSERTE(GCHeap::UseAllocationContexts());
+ _ASSERTE(GCHeapUtilities::UseAllocationContexts());
// If the TLS for Thread is low enough use the super-fast helpers
if (gThreadTLSIndex < TLS_MINIMUM_AVAILABLE)
{
diff --git a/src/vm/assemblynative.cpp b/src/vm/assemblynative.cpp
index 90c58fc59c..f372bcb349 100644
--- a/src/vm/assemblynative.cpp
+++ b/src/vm/assemblynative.cpp
@@ -807,6 +807,41 @@ Assembly* AssemblyNative::LoadFromPEImage(ICLRPrivBinder* pBinderContext, PEImag
RETURN pLoadedAssembly;
}
+/* static */
+void QCALLTYPE AssemblyNative::GetLoadedAssembliesInternal(QCall::ObjectHandleOnStack assemblies)
+{
+ QCALL_CONTRACT;
+
+ BEGIN_QCALL;
+
+ MethodTable * pAssemblyClass = MscorlibBinder::GetClass(CLASS__ASSEMBLY);
+
+ PTR_AppDomain pCurDomain = GetAppDomain();
+
+ SetSHash<PTR_DomainAssembly> assemblySet;
+ pCurDomain->GetCacheAssemblyList(assemblySet);
+ size_t nArrayElems = assemblySet.GetCount();
+ PTRARRAYREF AsmArray = NULL;
+
+ GCX_COOP();
+
+ GCPROTECT_BEGIN(AsmArray);
+ AsmArray = (PTRARRAYREF) AllocateObjectArray( (DWORD)nArrayElems, pAssemblyClass);
+ for(auto it = assemblySet.Begin(); it != assemblySet.End(); it++)
+ {
+ PTR_DomainAssembly assem = *it;
+ OBJECTREF o = (OBJECTREF)assem->GetExposedAssemblyObject();
+ _ASSERTE(o != NULL);
+ _ASSERTE(nArrayElems > 0);
+ AsmArray->SetAt(--nArrayElems, o);
+ }
+
+ assemblies.Set(AsmArray);
+
+ GCPROTECT_END();
+
+ END_QCALL;
+}
/* static */
void QCALLTYPE AssemblyNative::LoadFromPath(INT_PTR ptrNativeAssemblyLoadContext, LPCWSTR pwzILPath, LPCWSTR pwzNIPath, QCall::ObjectHandleOnStack retLoadedAssembly)
diff --git a/src/vm/assemblynative.hpp b/src/vm/assemblynative.hpp
index ca03239d3e..99f51e9837 100644
--- a/src/vm/assemblynative.hpp
+++ b/src/vm/assemblynative.hpp
@@ -252,6 +252,7 @@ public:
static BOOL QCALLTYPE OverrideDefaultAssemblyLoadContextForCurrentDomain(INT_PTR ptrNativeAssemblyLoadContext);
static BOOL QCALLTYPE CanUseAppPathAssemblyLoadContextInCurrentDomain();
static void QCALLTYPE LoadFromPath(INT_PTR ptrNativeAssemblyLoadContext, LPCWSTR pwzILPath, LPCWSTR pwzNIPath, QCall::ObjectHandleOnStack retLoadedAssembly);
+ static void QCALLTYPE GetLoadedAssembliesInternal(QCall::ObjectHandleOnStack assemblies);
static INT_PTR QCALLTYPE InternalLoadUnmanagedDllFromPath(LPCWSTR unmanagedLibraryPath);
static void QCALLTYPE LoadFromStream(INT_PTR ptrNativeAssemblyLoadContext, INT_PTR ptrAssemblyArray, INT32 cbAssemblyArrayLength, INT_PTR ptrSymbolArray, INT32 cbSymbolArrayLength, QCall::ObjectHandleOnStack retLoadedAssembly);
static Assembly* LoadFromPEImage(ICLRPrivBinder* pBinderContext, PEImage *pILImage, PEImage *pNIImage);
diff --git a/src/vm/assemblyspec.hpp b/src/vm/assemblyspec.hpp
index a7e9c0f203..d94a847124 100644
--- a/src/vm/assemblyspec.hpp
+++ b/src/vm/assemblyspec.hpp
@@ -682,6 +682,20 @@ class AssemblySpecBindingCache
WRAPPER_NO_CONTRACT;
return pSpec->Hash();
}
+
+#if defined(FEATURE_CORECLR) && !defined(DACCESS_COMPILE)
+ void GetAllAssemblies(SetSHash<PTR_DomainAssembly>& assemblyList)
+ {
+ PtrHashMap::PtrIterator i = m_map.begin();
+ while (!i.end())
+ {
+ AssemblyBinding *b = (AssemblyBinding*) i.GetValue();
+ if(!b->IsError() && b->GetAssembly() != NULL)
+ assemblyList.AddOrReplace(b->GetAssembly());
+ ++i;
+ }
+ }
+#endif // defined(FEATURE_CORECLR) && !defined(DACCESS_COMPILE)
static BOOL CompareSpecs(UPTR u1, UPTR u2);
};
diff --git a/src/vm/callhelpers.cpp b/src/vm/callhelpers.cpp
index 9152f71d79..addd5192da 100644
--- a/src/vm/callhelpers.cpp
+++ b/src/vm/callhelpers.cpp
@@ -16,6 +16,8 @@
// To include declaration of "SignatureNative"
#include "runtimehandles.h"
+#include "invokeutil.h"
+#include "argdestination.h"
#if defined(FEATURE_MULTICOREJIT) && defined(_DEBUG)
@@ -536,7 +538,7 @@ void MethodDescCallSite::CallTargetWorker(const ARG_SLOT *pArguments, ARG_SLOT *
}
#endif
- int ofs;
+ int ofs;
for (; TransitionBlock::InvalidOffset != (ofs = m_argIt.GetNextOffset()); arg++)
{
#ifdef CALLDESCR_REGTYPEMAP
@@ -567,46 +569,56 @@ void MethodDescCallSite::CallTargetWorker(const ARG_SLOT *pArguments, ARG_SLOT *
}
#endif // CHECK_APP_DOMAIN_LEAKS
-#if defined(UNIX_AMD64_ABI) && defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
- _ASSERTE(ofs != TransitionBlock::StructInRegsOffset);
-#endif
- PVOID pDest = pTransitionBlock + ofs;
+ ArgDestination argDest(pTransitionBlock, ofs, m_argIt.GetArgLocDescForStructInRegs());
UINT32 stackSize = m_argIt.GetArgSize();
- switch (stackSize)
+ // We need to pass in a pointer, but be careful of the ARG_SLOT calling convention. We might already have a pointer in the ARG_SLOT.
+ PVOID pSrc = stackSize > sizeof(ARG_SLOT) ? (LPVOID)ArgSlotToPtr(pArguments[arg]) : (LPVOID)ArgSlotEndianessFixup((ARG_SLOT*)&pArguments[arg], stackSize);
+
+#if defined(UNIX_AMD64_ABI) && defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
+ if (argDest.IsStructPassedInRegs())
+ {
+ TypeHandle th;
+ m_argIt.GetArgType(&th);
+
+ argDest.CopyStructToRegisters(pSrc, th.AsMethodTable()->GetNumInstanceFieldBytes(), 0);
+ }
+ else
+#endif // UNIX_AMD64_ABI && FEATURE_UNIX_AMD64_STRUCT_PASSING
{
- case 1:
- case 2:
- case 4:
- *((INT32*)pDest) = (INT32)pArguments[arg];
- break;
-
- case 8:
- *((INT64*)pDest) = pArguments[arg];
- break;
-
- default:
- // The ARG_SLOT contains a pointer to the value-type
-#ifdef ENREGISTERED_PARAMTYPE_MAXSIZE
- if (m_argIt.IsArgPassedByRef())
- {
- // We need to pass in a pointer, but be careful of the ARG_SLOT calling convention.
- // We might already have a pointer in the ARG_SLOT
- *(PVOID*)pDest = stackSize>sizeof(ARG_SLOT) ?
- (LPVOID)ArgSlotToPtr(pArguments[arg]) :
- (LPVOID)ArgSlotEndianessFixup((ARG_SLOT*)&pArguments[arg], stackSize);
- }
- else
-#endif // ENREGISTERED_PARAMTYPE_MAXSIZE
- if (stackSize>sizeof(ARG_SLOT))
- {
- CopyMemory(pDest, ArgSlotToPtr(pArguments[arg]), stackSize);
- }
- else
- {
- CopyMemory(pDest, (LPVOID) (&pArguments[arg]), stackSize);
- }
- break;
+ PVOID pDest = argDest.GetDestinationAddress();
+
+ switch (stackSize)
+ {
+ case 1:
+ case 2:
+ case 4:
+ *((INT32*)pDest) = (INT32)pArguments[arg];
+ break;
+
+ case 8:
+ *((INT64*)pDest) = pArguments[arg];
+ break;
+
+ default:
+ // The ARG_SLOT contains a pointer to the value-type
+ #ifdef ENREGISTERED_PARAMTYPE_MAXSIZE
+ if (m_argIt.IsArgPassedByRef())
+ {
+ *(PVOID*)pDest = pSrc;
+ }
+ else
+ #endif // ENREGISTERED_PARAMTYPE_MAXSIZE
+ if (stackSize > sizeof(ARG_SLOT))
+ {
+ CopyMemory(pDest, ArgSlotToPtr(pArguments[arg]), stackSize);
+ }
+ else
+ {
+ CopyMemory(pDest, (LPVOID) (&pArguments[arg]), stackSize);
+ }
+ break;
+ }
}
}
diff --git a/src/vm/callingconvention.h b/src/vm/callingconvention.h
index 3ef6be983a..c9a27c2371 100644
--- a/src/vm/callingconvention.h
+++ b/src/vm/callingconvention.h
@@ -1341,11 +1341,15 @@ void ArgIteratorTemplate<ARGITERATOR_BASE>::ComputeReturnFlags()
break;
case ELEMENT_TYPE_R4:
+#ifndef ARM_SOFTFP
flags |= sizeof(float) << RETURN_FP_SIZE_SHIFT;
+#endif
break;
case ELEMENT_TYPE_R8:
+#ifndef ARM_SOFTFP
flags |= sizeof(double) << RETURN_FP_SIZE_SHIFT;
+#endif
break;
case ELEMENT_TYPE_VALUETYPE:
diff --git a/src/vm/ceeload.cpp b/src/vm/ceeload.cpp
index 464c147cb4..c95fbac16e 100644
--- a/src/vm/ceeload.cpp
+++ b/src/vm/ceeload.cpp
@@ -1656,6 +1656,7 @@ void Module::Destruct()
m_InstMethodHashTableCrst.Destroy();
m_ISymUnmanagedReaderCrst.Destroy();
+#ifdef FEATURE_CER
if (m_pCerPrepInfo)
{
_ASSERTE(m_pCerCrst != NULL);
@@ -1672,6 +1673,7 @@ void Module::Destruct()
}
if (m_pCerCrst)
delete m_pCerCrst;
+#endif // FEATURE_CER
if (m_debuggerSpecificData.m_pDynamicILCrst)
{
@@ -1702,8 +1704,10 @@ 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())
{
@@ -3154,6 +3158,7 @@ BOOL Module::IsPreV4Assembly()
return !!(m_dwPersistedFlags & IS_PRE_V4_ASSEMBLY);
}
+#ifdef FEATURE_CER
DWORD Module::GetReliabilityContract()
{
CONTRACTL
@@ -3180,6 +3185,7 @@ DWORD Module::GetReliabilityContract()
return m_dwReliabilityContract;
}
+#endif // FEATURE_CER
ArrayDPTR(FixupPointer<PTR_MethodTable>) ModuleCtorInfo::GetGCStaticMTs(DWORD index)
{
@@ -3427,8 +3433,8 @@ void Module::EnumRegularStaticGCRefs(AppDomain* pAppDomain, promote_func* fn, Sc
}
CONTRACT_END;
- _ASSERTE(GCHeap::IsGCInProgress() &&
- GCHeap::IsServerHeap() &&
+ _ASSERTE(GCHeapUtilities::IsGCInProgress() &&
+ GCHeapUtilities::IsServerHeap() &&
IsGCSpecialThread());
@@ -6268,7 +6274,7 @@ Module *Module::GetModuleIfLoaded(mdFile kFile, BOOL onlyLoadedInAppDomain, BOOL
#ifndef DACCESS_COMPILE
#if defined(FEATURE_MULTIMODULE_ASSEMBLIES)
// check if actually loaded, unless happens during GC (GC works only with loaded assemblies)
- if (!GCHeap::IsGCInProgress() && onlyLoadedInAppDomain && pModule && !pModule->IsManifest())
+ if (!GCHeapUtilities::IsGCInProgress() && onlyLoadedInAppDomain && pModule && !pModule->IsManifest())
{
DomainModule *pDomainModule = pModule->FindDomainModule(GetAppDomain());
if (pDomainModule == NULL || !pDomainModule->IsLoaded())
@@ -9860,10 +9866,12 @@ void Module::PrepareTypesForSave(DataImage *image)
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
}
}
@@ -9947,7 +9955,9 @@ void Module::Save(DataImage *image)
// Cache values of all persisted flags computed from custom attributes
IsNoStringInterning();
IsRuntimeWrapExceptions();
+#ifdef FEATURE_CER
GetReliabilityContract();
+#endif
IsPreV4Assembly();
HasDefaultDllImportSearchPathsAttribute();
@@ -10302,10 +10312,12 @@ 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.
@@ -10761,6 +10773,7 @@ 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
@@ -10771,6 +10784,7 @@ void Module::PlaceMethod(DataImage *image, MethodDesc *pMD, DWORD profilingFlags
image->PlaceStructureForAddress(m_pCerNgenRootTable->GetList(pMD), CORCOMPILE_SECTION_HOT);
}
}
+#endif // FEATURE_CER
if (profilingFlags & (1 << WriteMethodPrecode))
{
@@ -11314,6 +11328,7 @@ 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.
//
@@ -11330,6 +11345,7 @@ void Module::Fixup(DataImage *image)
// 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));
@@ -15593,7 +15609,7 @@ FieldDesc *Module::LookupFieldDef(mdFieldDef token)
#endif // DACCESS_COMPILE
-#ifndef 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
@@ -15745,7 +15761,7 @@ void Module::RestoreCer(MethodDesc *pMD)
#endif // FEATURE_PREJIT
-#endif // !DACCESS_COMPILE
+#endif // !DACCESS_COMPILE && FEATURE_CER
@@ -15911,9 +15927,9 @@ void Module::ExpandAll()
pMD->GetMDImport(),
&ignored));
#ifdef FEATURE_INTERPRETER
- pMD->MakeJitWorker(pHeader, CORJIT_FLG_MAKEFINALCODE, 0);
+ pMD->MakeJitWorker(pHeader, CORJIT_FLAGS(CORJIT_FLAGS::CORJIT_FLAG_MAKEFINALCODE));
#else
- pMD->MakeJitWorker(pHeader, 0, 0);
+ pMD->MakeJitWorker(pHeader, CORJIT_FLAGS());
#endif
}
}
diff --git a/src/vm/ceeload.h b/src/vm/ceeload.h
index ce2e76e277..d15bd6b3d1 100644
--- a/src/vm/ceeload.h
+++ b/src/vm/ceeload.h
@@ -96,14 +96,16 @@ class PersistentInlineTrackingMap;
// The native symbol reader dll name
#ifdef FEATURE_CORECLR
-#if defined(_TARGET_AMD64_)
+#if defined(_AMD64_)
#define NATIVE_SYMBOL_READER_DLL W("Microsoft.DiaSymReader.Native.amd64.dll")
-#elif defined(_TARGET_X86_)
+#elif defined(_X86_)
#define NATIVE_SYMBOL_READER_DLL W("Microsoft.DiaSymReader.Native.x86.dll")
-#elif defined(_TARGET_ARM_)
+#elif defined(_ARM_)
#define NATIVE_SYMBOL_READER_DLL W("Microsoft.DiaSymReader.Native.arm.dll")
-#elif defined(_TARGET_ARM64_)
-#define NATIVE_SYMBOL_READER_DLL W("Microsoft.DiaSymReader.Native.arm64.dll")
+#elif defined(_ARM64_)
+// Use diasymreader until the package has an arm64 version - issue #7360
+//#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")
@@ -3392,10 +3394,12 @@ 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)
@@ -3404,13 +3408,15 @@ public:
protected:
+#ifdef FEATURE_CER
Volatile<DWORD> m_dwReliabilityContract;
+#endif
// initialize Crst controlling the Dynamic IL hashtables
void InitializeDynamicILCrst();
-#ifndef DACCESS_COMPILE
public:
+#if !defined(DACCESS_COMPILE) && defined(FEATURE_CER)
// Support for getting and creating information about Constrained Execution Regions rooted in this module.
@@ -3441,7 +3447,7 @@ public:
LIMITED_METHOD_CONTRACT;
return m_pCerCrst;
}
-#endif // !DACCESS_COMPILE
+#endif // !DACCESS_COMPILE && FEATURE_CER
#ifdef FEATURE_CORECLR
void VerifyAllMethods();
@@ -3454,11 +3460,13 @@ 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
diff --git a/src/vm/ceemain.cpp b/src/vm/ceemain.cpp
index 07781261f7..5521d8a4d9 100644
--- a/src/vm/ceemain.cpp
+++ b/src/vm/ceemain.cpp
@@ -150,7 +150,7 @@
#include "frames.h"
#include "threads.h"
#include "stackwalk.h"
-#include "gc.h"
+#include "gcheaputilities.h"
#include "interoputil.h"
#include "security.h"
#include "fieldmarshaler.h"
@@ -195,6 +195,7 @@
#include "finalizerthread.h"
#include "threadsuspend.h"
#include "disassembler.h"
+#include "gcenv.ee.h"
#ifndef FEATURE_PAL
#include "dwreport.h"
@@ -305,7 +306,6 @@ extern "C" HRESULT __cdecl CorDBGetInterface(DebugInterface** rcInterface);
#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-void* __stdcall GetCLRFunction(LPCSTR FunctionName);
// Pointer to the activated CLR interface provided by the shim.
ICLRRuntimeInfo *g_pCLRRuntime = NULL;
@@ -640,7 +640,7 @@ void InitializeStartupFlags()
g_fEnableARM = TRUE;
#endif // !FEATURE_CORECLR
- GCHeap::InitializeHeapType((flags & STARTUP_SERVER_GC) != 0);
+ InitializeHeapType((flags & STARTUP_SERVER_GC) != 0);
#ifdef FEATURE_LOADER_OPTIMIZATION
g_dwGlobalSharePolicy = (flags&STARTUP_LOADER_OPTIMIZATION_MASK)>>1;
@@ -1932,15 +1932,17 @@ void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading)
#endif
#ifdef FEATURE_PREJIT
- // If we're doing basic block profiling, we need to write the log files to disk.
-
- static BOOL fIBCLoggingDone = FALSE;
- if (!fIBCLoggingDone)
{
- if (g_IBCLogger.InstrEnabled())
- Module::WriteAllModuleProfileData(true);
+ // If we're doing basic block profiling, we need to write the log files to disk.
+
+ static BOOL fIBCLoggingDone = FALSE;
+ if (!fIBCLoggingDone)
+ {
+ if (g_IBCLogger.InstrEnabled())
+ Module::WriteAllModuleProfileData(true);
- fIBCLoggingDone = TRUE;
+ fIBCLoggingDone = TRUE;
+ }
}
#endif // FEATURE_PREJIT
@@ -3719,7 +3721,16 @@ void InitializeGarbageCollector()
g_pFreeObjectMethodTable->SetBaseSize(ObjSizeOf (ArrayBase));
g_pFreeObjectMethodTable->SetComponentSize(1);
- GCHeap *pGCHeap = GCHeap::CreateGCHeap();
+#ifdef FEATURE_STANDALONE_GC
+ IGCToCLR* gcToClr = new (nothrow) GCToEEInterface();
+ if (!gcToClr)
+ ThrowOutOfMemory();
+#else
+ IGCToCLR* gcToClr = nullptr;
+#endif
+
+ IGCHeap *pGCHeap = InitializeGarbageCollector(gcToClr);
+ g_pGCHeap = pGCHeap;
if (!pGCHeap)
ThrowOutOfMemory();
@@ -3833,7 +3844,7 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
{
// GetThread() may be set to NULL for Win9x during shutdown.
Thread *pThread = GetThread();
- if (GCHeap::IsGCInProgress() &&
+ if (GCHeapUtilities::IsGCInProgress() &&
( (pThread && (pThread != ThreadSuspend::GetSuspensionThread() ))
|| !g_fSuspendOnShutdown))
{
@@ -4643,7 +4654,6 @@ VOID STDMETHODCALLTYPE LogHelp_LogAssert( LPCSTR szFile, int iLine, LPCSTR expr)
}
-extern BOOL NoGuiOnAssert();
extern "C"
//__declspec(dllexport)
BOOL STDMETHODCALLTYPE LogHelp_NoGuiOnAssert()
@@ -4656,7 +4666,6 @@ BOOL STDMETHODCALLTYPE LogHelp_NoGuiOnAssert()
return fRet;
}
-extern VOID TerminateOnAssert();
extern "C"
//__declspec(dllexport)
VOID STDMETHODCALLTYPE LogHelp_TerminateOnAssert()
diff --git a/src/vm/cgensys.h b/src/vm/cgensys.h
index 205d8a223e..4dd1ee4b4b 100644
--- a/src/vm/cgensys.h
+++ b/src/vm/cgensys.h
@@ -103,21 +103,22 @@ inline void GetSpecificCpuInfo(CORINFO_CPU * cpuInfo)
#endif // !_TARGET_X86_
-#if defined(_TARGET_AMD64_) && !defined(CROSSGEN_COMPILE)
+#if (defined(_TARGET_X86_) || defined(_TARGET_AMD64_)) && !defined(CROSSGEN_COMPILE)
extern "C" DWORD __stdcall getcpuid(DWORD arg, unsigned char result[16]);
-#endif // defined(_TARGET_AMD64_)
+extern "C" DWORD __stdcall xmmYmmStateSupport();
+#endif
inline bool TargetHasAVXSupport()
{
-#if defined(_TARGET_AMD64_) && !defined(CROSSGEN_COMPILE)
+#if (defined(_TARGET_X86_) || defined(_TARGET_AMD64_)) && !defined(CROSSGEN_COMPILE)
unsigned char buffer[16];
- // All AMD64 targets support cpuid.
+ // All x86/AMD64 targets support cpuid.
(void) getcpuid(1, buffer);
// getcpuid executes cpuid with eax set to its first argument, and ecx cleared.
// It returns the resulting eax, ebx, ecx and edx (in that order) in buffer[].
// The AVX feature is ECX bit 28.
return ((buffer[11] & 0x10) != 0);
-#endif // defined(_TARGET_AMD64_) && !defined(CROSSGEN_COMPILE)
+#endif // (defined(_TARGET_X86_) || defined(_TARGET_AMD64_)) && !defined(CROSSGEN_COMPILE)
return false;
}
diff --git a/src/vm/class.cpp b/src/vm/class.cpp
index 961df2a104..cff71f328f 100644
--- a/src/vm/class.cpp
+++ b/src/vm/class.cpp
@@ -19,6 +19,7 @@
#include "constrainedexecutionregion.h"
#include "customattribute.h"
#include "encee.h"
+#include "typestring.h"
#ifdef FEATURE_COMINTEROP
#include "comcallablewrapper.h"
@@ -2490,12 +2491,14 @@ 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
@@ -3065,6 +3068,7 @@ void EEClass::Fixup(DataImage *image, MethodTable *pMT)
image->ZeroPointerField(this, offsetof(DelegateEEClass, m_pUMThunkMarshInfo));
image->ZeroPointerField(this, offsetof(DelegateEEClass, m_pStaticCallStub));
image->ZeroPointerField(this, offsetof(DelegateEEClass, m_pMultiCastInvokeStub));
+ image->ZeroPointerField(this, offsetof(DelegateEEClass, m_pSecureDelegateInvokeStub));
image->ZeroPointerField(this, offsetof(DelegateEEClass, m_pMarshalStub));
#ifdef FEATURE_COMINTEROP
diff --git a/src/vm/class.h b/src/vm/class.h
index f19b9818ec..7517863278 100644
--- a/src/vm/class.h
+++ b/src/vm/class.h
@@ -703,7 +703,9 @@ class EEClassOptionalFields
#define MODULE_NON_DYNAMIC_STATICS ((DWORD)-1)
DWORD m_cbModuleDynamicID;
+#ifdef FEATURE_CER
DWORD m_dwReliabilityContract;
+#endif
SecurityProperties m_SecProps;
@@ -1768,12 +1770,14 @@ 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.
@@ -2412,6 +2416,7 @@ public:
PTR_Stub m_pInstRetBuffCallStub;
PTR_MethodDesc m_pInvokeMethod;
PTR_Stub m_pMultiCastInvokeStub;
+ PTR_Stub m_pSecureDelegateInvokeStub;
UMThunkMarshInfo* m_pUMThunkMarshInfo;
PTR_MethodDesc m_pBeginInvokeMethod;
PTR_MethodDesc m_pEndInvokeMethod;
diff --git a/src/vm/class.inl b/src/vm/class.inl
index 9362a8328f..7d5c74d586 100644
--- a/src/vm/class.inl
+++ b/src/vm/class.inl
@@ -50,7 +50,9 @@ 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 ac819941f9..50c56506a9 100644
--- a/src/vm/classcompat.cpp
+++ b/src/vm/classcompat.cpp
@@ -31,7 +31,7 @@
#include "log.h"
#include "fieldmarshaler.h"
#include "cgensys.h"
-#include "gc.h"
+#include "gcheaputilities.h"
#include "security.h"
#include "dbginterface.h"
#include "comdelegate.h"
diff --git a/src/vm/classnames.h b/src/vm/classnames.h
index 949c6c4447..47f1fecdec 100644
--- a/src/vm/classnames.h
+++ b/src/vm/classnames.h
@@ -16,6 +16,9 @@
#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"
diff --git a/src/vm/clrprivbinderwinrt.cpp b/src/vm/clrprivbinderwinrt.cpp
index b82d46cdab..b4fb45c083 100644
--- a/src/vm/clrprivbinderwinrt.cpp
+++ b/src/vm/clrprivbinderwinrt.cpp
@@ -287,7 +287,8 @@ HRESULT CLRPrivBinderWinRT::BindWinRTAssemblyByName(
{
STANDARD_VM_CONTRACT;
HRESULT hr = S_OK;
- ReleaseHolder<CLRPrivAssemblyWinRT> pAssembly;
+ ReleaseHolder<CLRPrivAssemblyWinRT> pAssembly;
+ LPWSTR wszFullTypeName = nullptr;
#ifndef FEATURE_CORECLR
NewArrayHolder<WCHAR> wszAssemblySimpleName;
#endif
@@ -319,11 +320,13 @@ HRESULT CLRPrivBinderWinRT::BindWinRTAssemblyByName(
IfFailGo(fusion::util::GetProperty(pAssemblyName, ASM_NAME_NAME, &wszAssemblySimpleName));
#else
WCHAR wszAssemblySimpleName[_MAX_PATH];
- DWORD cchAssemblySimpleName = _MAX_PATH;
- IfFailGo(pAssemblyName->GetName(&cchAssemblySimpleName, wszAssemblySimpleName));
+ {
+ DWORD cchAssemblySimpleName = _MAX_PATH;
+ IfFailGo(pAssemblyName->GetName(&cchAssemblySimpleName, wszAssemblySimpleName));
+ }
#endif
- LPWSTR wszFullTypeName = wcschr(wszAssemblySimpleName, W('!'));
+ wszFullTypeName = wcschr(wszAssemblySimpleName, W('!'));
if (wszFullTypeName != nullptr)
{
diff --git a/src/vm/clsload.hpp b/src/vm/clsload.hpp
index e2705ae2e4..a3a0de3cf4 100644
--- a/src/vm/clsload.hpp
+++ b/src/vm/clsload.hpp
@@ -697,7 +697,7 @@ public:
// fLoadTypes=DontLoadTypes: if type isn't already in the loader's table, return NULL
// fLoadTypes=LoadTypes: if type isn't already in the loader's table, then create it
// Each comes in two variants, LoadXThrowing and LoadXNoThrow, the latter being just
- // a exception-handling wrapper around the former.
+ // an exception-handling wrapper around the former.
//
// Each also allows types to be loaded only up to a particular level (see classloadlevel.h).
// The class loader itself makes use of these levels to "break" recursion across
diff --git a/src/vm/codeman.cpp b/src/vm/codeman.cpp
index 89084dbe85..98f0e53d3d 100644
--- a/src/vm/codeman.cpp
+++ b/src/vm/codeman.cpp
@@ -31,6 +31,10 @@
#include "debuginfostore.h"
#include "strsafe.h"
+#ifdef FEATURE_CORECLR
+#include "configuration.h"
+#endif
+
#ifdef _WIN64
#define CHECK_DUPLICATED_STRUCT_LAYOUTS
#include "../debug/daccess/fntableaccess.h"
@@ -1183,6 +1187,7 @@ EEJitManager::EEJitManager()
// CRST_TAKEN_DURING_SHUTDOWN - We take this lock during shutdown if ETW is on (to do rundown)
m_CodeHeapCritSec( CrstSingleUseLock,
CrstFlags(CRST_UNSAFE_ANYMODE|CRST_DEBUGGER_THREAD|CRST_TAKEN_DURING_SHUTDOWN)),
+ m_CPUCompileFlags(),
m_EHClauseCritSec( CrstSingleUseLock )
{
CONTRACTL {
@@ -1196,41 +1201,34 @@ EEJitManager::EEJitManager()
#ifdef _TARGET_AMD64_
m_pEmergencyJumpStubReserveList = NULL;
#endif
-#ifdef _TARGET_AMD64_
+#if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
m_JITCompilerOther = NULL;
#endif
+ m_fLegacyJitUsed = FALSE;
+
#ifdef ALLOW_SXS_JIT
m_alternateJit = NULL;
m_AltJITCompiler = NULL;
m_AltJITRequired = false;
#endif
- m_dwCPUCompileFlags = 0;
-
m_cleanupList = NULL;
}
-#if defined(_TARGET_AMD64_)
-extern "C" DWORD __stdcall getcpuid(DWORD arg, unsigned char result[16]);
-extern "C" DWORD __stdcall xmmYmmStateSupport();
+#if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
bool DoesOSSupportAVX()
{
+ LIMITED_METHOD_CONTRACT;
+
#ifndef FEATURE_PAL
// On Windows we have an api(GetEnabledXStateFeatures) to check if AVX is supported
typedef DWORD64 (WINAPI *PGETENABLEDXSTATEFEATURES)();
PGETENABLEDXSTATEFEATURES pfnGetEnabledXStateFeatures = NULL;
- // Probe ApiSet first
- HMODULE hMod = WszLoadLibraryEx(W("api-ms-win-core-xstate-l2-1-0.dll"), NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
-
- if (hMod == NULL)
- {
- // On older OS's where apiset is not present probe kernel32
- hMod = WszLoadLibraryEx(WINDOWS_KERNEL32_DLLNAME_W, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
- if(hMod = NULL)
- return FALSE;
- }
+ HMODULE hMod = WszLoadLibraryEx(WINDOWS_KERNEL32_DLLNAME_W, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
+ if(hMod = NULL)
+ return FALSE;
pfnGetEnabledXStateFeatures = (PGETENABLEDXSTATEFEATURES)GetProcAddress(hMod, "GetEnabledXStateFeatures");
@@ -1249,7 +1247,7 @@ bool DoesOSSupportAVX()
return TRUE;
}
-#endif // defined(_TARGET_AMD64_)
+#endif // defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
void EEJitManager::SetCpuInfo()
{
@@ -1259,7 +1257,7 @@ void EEJitManager::SetCpuInfo()
// NOTE: This function needs to be kept in sync with Zapper::CompileAssembly()
//
- DWORD dwCPUCompileFlags = 0;
+ CORJIT_FLAGS CPUCompileFlags;
#if defined(_TARGET_X86_)
// NOTE: if you're adding any flags here, you probably should also be doing it
@@ -1270,7 +1268,7 @@ void EEJitManager::SetCpuInfo()
switch (CPU_X86_FAMILY(cpuInfo.dwCPUType))
{
case CPU_X86_PENTIUM_4:
- dwCPUCompileFlags |= CORJIT_FLG_TARGET_P4;
+ CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_TARGET_P4);
break;
default:
break;
@@ -1278,15 +1276,17 @@ void EEJitManager::SetCpuInfo()
if (CPU_X86_USE_CMOV(cpuInfo.dwFeatures))
{
- dwCPUCompileFlags |= CORJIT_FLG_USE_CMOV |
- CORJIT_FLG_USE_FCOMI;
+ CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_CMOV);
+ CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_FCOMI);
}
if (CPU_X86_USE_SSE2(cpuInfo.dwFeatures))
{
- dwCPUCompileFlags |= CORJIT_FLG_USE_SSE2;
+ CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE2);
}
-#elif defined(_TARGET_AMD64_)
+#endif // _TARGET_X86_
+
+#if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
unsigned char buffer[16];
DWORD maxCpuId = getcpuid(0, buffer);
if (maxCpuId >= 0)
@@ -1295,17 +1295,17 @@ void EEJitManager::SetCpuInfo()
// It returns the resulting eax in buffer[0-3], ebx in buffer[4-7], ecx in buffer[8-11],
// and edx in buffer[12-15].
// We will set the following flags:
- // CORJIT_FLG_USE_SSE3_4 if the following feature bits are set (input EAX of 1)
+ // CORJIT_FLAG_USE_SSE3_4 if the following feature bits are set (input EAX of 1)
// SSE3 - ECX bit 0 (buffer[8] & 0x01)
// SSSE3 - ECX bit 9 (buffer[9] & 0x02)
// SSE4.1 - ECX bit 19 (buffer[10] & 0x08)
// SSE4.2 - ECX bit 20 (buffer[10] & 0x10)
- // CORJIT_FLG_USE_AVX if the following feature bits are set (input EAX of 1), and xmmYmmStateSupport returns 1:
+ // CORJIT_FLAG_USE_AVX if the following feature bits are set (input EAX of 1), and xmmYmmStateSupport returns 1:
// OSXSAVE - ECX bit 27 (buffer[11] & 0x08)
// AVX - ECX bit 28 (buffer[11] & 0x10)
- // CORJIT_FLG_USE_AVX2 if the following feature bit is set (input EAX of 0x07 and input ECX of 0):
+ // CORJIT_FLAG_USE_AVX2 if the following feature bit is set (input EAX of 0x07 and input ECX of 0):
// AVX2 - EBX bit 5 (buffer[4] & 0x20)
- // CORJIT_FLG_USE_AVX_512 is not currently set, but defined so that it can be used in future without
+ // CORJIT_FLAG_USE_AVX_512 is not currently set, but defined so that it can be used in future without
// synchronously updating VM and JIT.
(void) getcpuid(1, buffer);
// If SSE2 is not enabled, there is no point in checking the rest.
@@ -1318,7 +1318,7 @@ void EEJitManager::SetCpuInfo()
((buffer[10] & 0x08) != 0) && // SSE4.1
((buffer[10] & 0x10) != 0)) // SSE4.2
{
- dwCPUCompileFlags |= CORJIT_FLG_USE_SSE3_4;
+ CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE3_4);
}
if ((buffer[11] & 0x18) == 0x18)
{
@@ -1326,13 +1326,13 @@ void EEJitManager::SetCpuInfo()
{
if (xmmYmmStateSupport() == 1)
{
- dwCPUCompileFlags |= CORJIT_FLG_USE_AVX;
+ CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_AVX);
if (maxCpuId >= 0x07)
{
(void) getcpuid(0x07, buffer);
if ((buffer[4] & 0x20) != 0)
{
- dwCPUCompileFlags |= CORJIT_FLG_USE_AVX2;
+ CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_AVX2);
}
}
}
@@ -1341,13 +1341,13 @@ void EEJitManager::SetCpuInfo()
static ConfigDWORD fFeatureSIMD;
if (fFeatureSIMD.val(CLRConfig::EXTERNAL_FeatureSIMD) != 0)
{
- dwCPUCompileFlags |= CORJIT_FLG_FEATURE_SIMD;
+ CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_FEATURE_SIMD);
}
}
}
-#endif // defined(_TARGET_AMD64_)
+#endif // defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
- m_dwCPUCompileFlags = dwCPUCompileFlags;
+ m_CPUCompileFlags = CPUCompileFlags;
}
// Define some data that we can use to get a better idea of what happened when we get a Watson dump that indicates the JIT failed to load.
@@ -1356,7 +1356,7 @@ void EEJitManager::SetCpuInfo()
enum JIT_LOAD_JIT_ID
{
JIT_LOAD_MAIN = 500, // The "main" JIT. Normally, this is named "clrjit.dll". Start at a number that is somewhat uncommon (i.e., not zero or 1) to help distinguish from garbage, in process dumps.
- JIT_LOAD_LEGACY, // The "legacy" JIT. Normally, this is named "compatjit.dll" (aka, JIT64). This only applies to AMD64.
+ JIT_LOAD_LEGACY, // The "legacy" JIT. Normally, this is named "compatjit.dll". This applies to AMD64 on Windows desktop, or x86 on Windows .NET Core.
JIT_LOAD_ALTJIT // An "altjit". By default, named "protojit.dll". Used both internally, as well as externally for JIT CTP builds.
};
@@ -1432,33 +1432,43 @@ static void LoadAndInitializeJIT(LPCWSTR pwzJitName, OUT HINSTANCE* phJit, OUT I
#ifdef FEATURE_CORECLR
PathString CoreClrFolderHolder;
extern HINSTANCE g_hThisInst;
+ bool havePath = false;
#if !defined(FEATURE_MERGE_JIT_AND_ENGINE)
if (g_CLRJITPath != nullptr)
{
- // If we have been asked to load a specific JIT binary, load it.
+ // If we have been asked to load a specific JIT binary, load from that path.
+ // The main JIT load will use exactly that name because pwzJitName will have
+ // been computed as the last component of g_CLRJITPath by ExecutionManager::GetJitName().
+ // Non-primary JIT names (such as compatjit or altjit) will be loaded from the
+ // same directory.
+ // (Ideally, g_CLRJITPath would just be the JIT path without the filename component,
+ // but that's not how the JIT_PATH variable was originally defined.)
CoreClrFolderHolder.Set(g_CLRJITPath);
+ havePath = true;
}
else
#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE)
if (WszGetModuleFileName(g_hThisInst, CoreClrFolderHolder))
{
// Load JIT from next to CoreCLR binary
+ havePath = true;
+ }
+
+ if (havePath && !CoreClrFolderHolder.IsEmpty())
+ {
SString::Iterator iter = CoreClrFolderHolder.End();
BOOL findSep = CoreClrFolderHolder.FindBack(iter, DIRECTORY_SEPARATOR_CHAR_W);
if (findSep)
{
SString sJitName(pwzJitName);
CoreClrFolderHolder.Replace(iter + 1, CoreClrFolderHolder.End() - (iter + 1), sJitName);
- }
- }
- if (!CoreClrFolderHolder.IsEmpty())
- {
- *phJit = CLRLoadLibrary(CoreClrFolderHolder.GetUnicode());
- if (*phJit != NULL)
- {
- hr = S_OK;
+ *phJit = CLRLoadLibrary(CoreClrFolderHolder.GetUnicode());
+ if (*phJit != NULL)
+ {
+ hr = S_OK;
+ }
}
}
@@ -1614,7 +1624,7 @@ BOOL EEJitManager::LoadJIT()
#else // !FEATURE_MERGE_JIT_AND_ENGINE
m_JITCompiler = NULL;
-#ifdef _TARGET_AMD64_
+#if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
m_JITCompilerOther = NULL;
#endif
@@ -1623,8 +1633,8 @@ BOOL EEJitManager::LoadJIT()
// Set as a courtesy to code:CorCompileGetRuntimeDll
s_ngenCompilerDll = m_JITCompiler;
-
-#if defined(_TARGET_AMD64_) && !defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
+
+#if (defined(_TARGET_AMD64_) && !defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)) || (defined(_TARGET_X86_) && defined(FEATURE_CORECLR))
// 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
@@ -1645,8 +1655,16 @@ BOOL EEJitManager::LoadJIT()
// is set, we also must use JIT64 for all NGEN compilations as well.
//
// See the document "RyuJIT Compatibility Fallback Specification.docx" for details.
+ //
+ // For .NET Core 1.2, RyuJIT for x86 is the primary jit (clrjit.dll) and JIT32 for x86 is the fallback, legacy JIT (compatjit.dll).
+ // 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
@@ -1660,7 +1678,11 @@ 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;
@@ -1689,7 +1711,7 @@ BOOL EEJitManager::LoadJIT()
{
// Now, load the compat jit and initialize it.
- LPWSTR pwzJitName = MAKEDLLNAME_W(L"compatjit");
+ LPCWSTR pwzJitName = MAKEDLLNAME_W(W("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
@@ -1702,10 +1724,13 @@ BOOL EEJitManager::LoadJIT()
// 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.
newJitCompiler->setRealJit(fallbackICorJitCompiler);
+
+ // Now, the compat JIT will be used.
+ m_fLegacyJitUsed = TRUE;
}
}
}
-#endif // defined(_TARGET_AMD64_) && !defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
+#endif // (defined(_TARGET_AMD64_) && !defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)) || (defined(_TARGET_X86_) && defined(FEATURE_CORECLR))
#endif // !FEATURE_MERGE_JIT_AND_ENGINE
@@ -3397,7 +3422,7 @@ void ExecutionManager::CleanupCodeHeaps()
}
CONTRACTL_END;
- _ASSERTE (g_fProcessDetach || (GCHeap::IsGCInProgress() && ::IsGCThread()));
+ _ASSERTE (g_fProcessDetach || (GCHeapUtilities::IsGCInProgress() && ::IsGCThread()));
GetEEJitManager()->CleanupCodeHeaps();
}
@@ -3411,7 +3436,17 @@ void EEJitManager::CleanupCodeHeaps()
}
CONTRACTL_END;
- _ASSERTE (g_fProcessDetach || (GCHeap::IsGCInProgress() && ::IsGCThread()));
+ _ASSERTE (g_fProcessDetach || (GCHeapUtilities::IsGCInProgress() && ::IsGCThread()));
+
+ // Quick out, don't even take the lock if we have not cleanup to do.
+ // This is important because ETW takes the CodeHeapLock when it is doing
+ // rundown, and if there are many JIT compiled methods, this can take a while.
+ // Because cleanup is called synchronously before a GC, this means GCs get
+ // blocked while ETW is doing rundown. By not taking the lock we avoid
+ // this stall most of the time since cleanup is rare, and ETW rundown is rare
+ // the likelihood of both is very very rare.
+ if (m_cleanupList == NULL)
+ return;
CrstHolder ch(&m_CodeHeapCritSec);
@@ -4359,7 +4394,22 @@ LPCWSTR ExecutionManager::GetJitName()
LPCWSTR pwzJitName = NULL;
-#if !defined(FEATURE_CORECLR)
+#if defined(FEATURE_CORECLR)
+#if !defined(CROSSGEN_COMPILE)
+ if (g_CLRJITPath != nullptr)
+ {
+ const wchar_t* p = wcsrchr(g_CLRJITPath, DIRECTORY_SEPARATOR_CHAR_W);
+ if (p != nullptr)
+ {
+ pwzJitName = p + 1; // Return just the filename, not the directory name
+ }
+ else
+ {
+ pwzJitName = g_CLRJITPath;
+ }
+ }
+#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
@@ -4451,7 +4501,7 @@ RangeSection* ExecutionManager::GetRangeSection(TADDR addr)
// Unless we are on an MP system with many cpus
// where this sort of caching actually diminishes scaling during server GC
// due to many processors writing to a common location
- if (g_SystemInfo.dwNumberOfProcessors < 4 || !GCHeap::IsServerHeap() || !GCHeap::IsGCInProgress())
+ if (g_SystemInfo.dwNumberOfProcessors < 4 || !GCHeapUtilities::IsServerHeap() || !GCHeapUtilities::IsGCInProgress())
pHead->pLastUsed = pLast;
#endif
@@ -6104,12 +6154,12 @@ __forceinline bool Nirvana_PrintMethodDescWorker(__in_ecount(iBuffer) char * szB
if (*pNamespace != 0)
{
- if(FAILED(StringCchPrintfA(szBuffer, iBuffer, "%s.%s.%s", pNamespace, pClassName, pSigString)))
+ if (_snprintf_s(szBuffer, iBuffer, _TRUNCATE, "%s.%s.%s", pNamespace, pClassName, pSigString) == -1)
return false;
}
else
{
- if(FAILED(StringCchPrintfA(szBuffer, iBuffer, "%s.%s", pClassName, pSigString)))
+ if (_snprintf_s(szBuffer, iBuffer, _TRUNCATE, "%s.%s", pClassName, pSigString) == -1)
return false;
}
diff --git a/src/vm/codeman.h b/src/vm/codeman.h
index f143dd642c..0fe261a92f 100644
--- a/src/vm/codeman.h
+++ b/src/vm/codeman.h
@@ -140,6 +140,10 @@ public:
PTR_EE_ILEXCEPTION phdrJitEHInfo;
PTR_BYTE phdrJitGCInfo;
+#if defined(FEATURE_GDBJIT)
+ VOID* pCalledMethods;
+#endif
+
PTR_MethodDesc phdrMDesc;
#ifdef WIN64EXCEPTIONS
@@ -172,6 +176,13 @@ public:
SUPPORTS_DAC;
return phdrMDesc;
}
+#if defined(FEATURE_GDBJIT)
+ PTR_BYTE GetCalledMethods()
+ {
+ SUPPORTS_DAC;
+ return pCalledMethods;
+ }
+#endif
TADDR GetCodeStartAddress()
{
SUPPORTS_DAC;
@@ -205,6 +216,12 @@ public:
{
phdrMDesc = pMD;
}
+#if defined(FEATURE_GDBJIT)
+ void SetCalledMethods(VOID* pCM)
+ {
+ pCalledMethods = pCM;
+ }
+#endif
void SetStubCodeBlockKind(StubCodeBlockKind kind)
{
phdrMDesc = (PTR_MethodDesc)kind;
@@ -248,6 +265,13 @@ public:
SUPPORTS_DAC;
return pRealCodeHeader->phdrMDesc;
}
+#if defined(FEATURE_GDBJIT)
+ VOID* GetCalledMethods()
+ {
+ SUPPORTS_DAC;
+ return pRealCodeHeader->pCalledMethods;
+ }
+#endif
TADDR GetCodeStartAddress()
{
SUPPORTS_DAC;
@@ -286,6 +310,12 @@ public:
{
pRealCodeHeader->phdrMDesc = pMD;
}
+#if defined(FEATURE_GDBJIT)
+ void SetCalledMethods(VOID* pCM)
+ {
+ pRealCodeHeader->pCalledMethods = pCM;
+ }
+#endif
void SetStubCodeBlockKind(StubCodeBlockKind kind)
{
pRealCodeHeader = (PTR_RealCodeHeader)kind;
@@ -1116,17 +1146,17 @@ public:
#endif // !DACCESS_COMPILE
private:
- DWORD m_dwCPUCompileFlags;
+ CORJIT_FLAGS m_CPUCompileFlags;
#if !defined CROSSGEN_COMPILE && !defined DACCESS_COMPILE
void SetCpuInfo();
#endif
public:
- inline DWORD GetCPUCompileFlags()
+ inline CORJIT_FLAGS GetCPUCompileFlags()
{
LIMITED_METHOD_CONTRACT;
- return m_dwCPUCompileFlags;
+ return m_CPUCompileFlags;
}
private :
@@ -1163,10 +1193,16 @@ public:
public:
ICorJitCompiler * m_jit;
HINSTANCE m_JITCompiler;
-#ifdef _TARGET_AMD64_
+#if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
HINSTANCE m_JITCompilerOther; // Stores the handle of the legacy JIT, if one is loaded.
#endif
+ // TRUE if the legacy/compat JIT was loaded successfully and will be used.
+ // This is available in all builds so if COMPlus_RequireLegacyJit=1 is set in a test,
+ // the test will fail in any build where the legacy JIT is not loaded, even if legacy
+ // fallback is not available in that build. This prevents unexpected silent successes.
+ BOOL m_fLegacyJitUsed;
+
#ifdef ALLOW_SXS_JIT
//put these at the end so that we don't mess up the offsets in the DAC.
ICorJitCompiler * m_alternateJit;
@@ -1801,7 +1837,7 @@ public:
ULONG GetFixedStackSize()
{
WRAPPER_NO_CONTRACT;
- return GetCodeManager()->GetFrameSize(GetGCInfo());
+ return GetCodeManager()->GetFrameSize(GetGCInfoToken());
}
#endif // WIN64EXCEPTIONS
diff --git a/src/vm/comdelegate.cpp b/src/vm/comdelegate.cpp
index 9ba1bdb328..4c85a0216e 100644
--- a/src/vm/comdelegate.cpp
+++ b/src/vm/comdelegate.cpp
@@ -1249,7 +1249,7 @@ PCODE COMDelegate::ConvertToCallback(MethodDesc* pMD)
// Get UMEntryThunk from appdomain thunkcache cache.
UMEntryThunk *pUMEntryThunk = GetAppDomain()->GetUMEntryThunkCache()->GetUMEntryThunk(pMD);
-#ifdef _TARGET_X86_
+#if defined(_TARGET_X86_) && !defined(FEATURE_STUBS_AS_IL)
// System.Runtime.InteropServices.NativeCallableAttribute
BYTE* pData = NULL;
@@ -1281,7 +1281,7 @@ PCODE COMDelegate::ConvertToCallback(MethodDesc* pMD)
pUMThunkMarshalInfo->SetCallingConvention(callConv);
}
}
-#endif //_TARGET_X86_
+#endif //_TARGET_X86_ && !FEATURE_STUBS_AS_IL
pCode = (PCODE)pUMEntryThunk->GetCode();
_ASSERTE(pCode != NULL);
@@ -2395,7 +2395,7 @@ PCODE COMDelegate::TheDelegateInvokeStub()
}
CONTRACT_END;
-#ifdef _TARGET_X86_
+#if defined(_TARGET_X86_) && !defined(FEATURE_STUBS_AS_IL)
static PCODE s_pInvokeStub;
if (s_pInvokeStub == NULL)
@@ -2415,7 +2415,7 @@ PCODE COMDelegate::TheDelegateInvokeStub()
RETURN s_pInvokeStub;
#else
RETURN GetEEFuncEntryPoint(SinglecastDelegateInvokeStub);
-#endif // _TARGET_X86_
+#endif // _TARGET_X86_ && !FEATURE_STUBS_AS_IL
}
// Get the cpu stub for a delegate invoke.
@@ -2931,47 +2931,61 @@ PCODE COMDelegate::GetSecureInvoke(MethodDesc* pMD)
#ifdef FEATURE_CAS_POLICY
#error GetSecureInvoke not implemented
#else
- GCX_PREEMP();
+ MethodTable * pDelegateMT = pMD->GetMethodTable();
+ DelegateEEClass* delegateEEClass = (DelegateEEClass*) pDelegateMT->GetClass();
+ Stub *pStub = delegateEEClass->m_pSecureDelegateInvokeStub;
+
+ if (pStub == NULL)
+ {
+
+ GCX_PREEMP();
+
+ MetaSig sig(pMD);
+
+ BOOL fReturnVal = !sig.IsReturnTypeVoid();
- MetaSig sig(pMD);
+ SigTypeContext emptyContext;
+ ILStubLinker sl(pMD->GetModule(), pMD->GetSignature(), &emptyContext, pMD, TRUE, TRUE, FALSE);
+
+ ILCodeStream *pCode = sl.NewCodeStream(ILStubLinker::kDispatch);
- BOOL fReturnVal = !sig.IsReturnTypeVoid();
+ // Load the "real" delegate
+ pCode->EmitLoadThis();
+ pCode->EmitLDFLD(pCode->GetToken(MscorlibBinder::GetField(FIELD__MULTICAST_DELEGATE__INVOCATION_LIST)));
- SigTypeContext emptyContext;
- ILStubLinker sl(pMD->GetModule(), pMD->GetSignature(), &emptyContext, pMD, TRUE, TRUE, FALSE);
+ // Load the arguments
+ UINT paramCount = 0;
+ while(paramCount < sig.NumFixedArgs())
+ pCode->EmitLDARG(paramCount++);
- ILCodeStream *pCode = sl.NewCodeStream(ILStubLinker::kDispatch);
+ // Call the delegate
+ pCode->EmitCALL(pCode->GetToken(pMD), sig.NumFixedArgs(), fReturnVal);
- // Load the "real" delegate
- pCode->EmitLoadThis();
- pCode->EmitLDFLD(pCode->GetToken(MscorlibBinder::GetField(FIELD__MULTICAST_DELEGATE__INVOCATION_LIST)));
+ // Return
+ pCode->EmitRET();
- // Load the arguments
- UINT paramCount = 0;
- while(paramCount < sig.NumFixedArgs())
- pCode->EmitLDARG(paramCount++);
+ PCCOR_SIGNATURE pSig;
+ DWORD cbSig;
- // Call the delegate
- pCode->EmitCALL(pCode->GetToken(pMD), sig.NumFixedArgs(), fReturnVal);
+ pMD->GetSig(&pSig,&cbSig);
- // Return
- pCode->EmitRET();
+ MethodDesc* pStubMD =
+ ILStubCache::CreateAndLinkNewILStubMethodDesc(pMD->GetLoaderAllocator(),
+ pMD->GetMethodTable(),
+ ILSTUB_SECUREDELEGATE_INVOKE,
+ pMD->GetModule(),
+ pSig, cbSig,
+ NULL,
+ &sl);
- PCCOR_SIGNATURE pSig;
- DWORD cbSig;
+ pStub = Stub::NewStub(JitILStub(pStubMD));
- pMD->GetSig(&pSig,&cbSig);
+ g_IBCLogger.LogEEClassCOWTableAccess(pDelegateMT);
- MethodDesc* pStubMD =
- ILStubCache::CreateAndLinkNewILStubMethodDesc(pMD->GetLoaderAllocator(),
- pMD->GetMethodTable(),
- ILSTUB_SECUREDELEGATE_INVOKE,
- pMD->GetModule(),
- pSig, cbSig,
- NULL,
- &sl);
+ InterlockedCompareExchangeT<PTR_Stub>(EnsureWritablePages(&delegateEEClass->m_pSecureDelegateInvokeStub), pStub, NULL);
- return Stub::NewStub(JitILStub(pStubMD))->GetEntryPoint();
+ }
+ return pStub->GetEntryPoint();
#endif
}
#else // FEATURE_STUBS_AS_IL
@@ -2986,32 +3000,44 @@ PCODE COMDelegate::GetSecureInvoke(MethodDesc* pMD)
}
CONTRACT_END;
- GCX_PREEMP();
-
- MetaSig sig(pMD);
+ MethodTable * pDelegateMT = pMD->GetMethodTable();
+ DelegateEEClass* delegateEEClass = (DelegateEEClass*) pDelegateMT->GetClass();
- UINT_PTR hash = CPUSTUBLINKER::HashMulticastInvoke(&sig);
+ Stub *pStub = delegateEEClass->m_pSecureDelegateInvokeStub;
- Stub *pStub = m_pSecureDelegateStubCache->GetStub(hash);
- if (!pStub)
+ if (pStub == NULL)
{
- CPUSTUBLINKER sl;
+ GCX_PREEMP();
- LOG((LF_CORDB,LL_INFO10000, "COMD::GIMS making a multicast delegate\n"));
- sl.EmitSecureDelegateInvoke(hash);
+ MetaSig sig(pMD);
- // The cache is process-wide, based on signature. It never unloads
- Stub *pCandidate = sl.Link(SystemDomain::GetGlobalLoaderAllocator()->GetStubHeap(), NEWSTUB_FL_MULTICAST);
+ UINT_PTR hash = CPUSTUBLINKER::HashMulticastInvoke(&sig);
- Stub *pWinner = m_pSecureDelegateStubCache->AttemptToSetStub(hash, pCandidate);
- pCandidate->DecRef();
- if (!pWinner)
- COMPlusThrowOM();
+ pStub = m_pSecureDelegateStubCache->GetStub(hash);
+ if (!pStub)
+ {
+ CPUSTUBLINKER sl;
- LOG((LF_CORDB,LL_INFO10000, "Putting a MC stub at 0x%x (code:0x%x)\n",
- pWinner, (BYTE*)pWinner+sizeof(Stub)));
+ LOG((LF_CORDB,LL_INFO10000, "COMD::GIMS making a multicast delegate\n"));
+ sl.EmitSecureDelegateInvoke(hash);
- pStub = pWinner;
+ // The cache is process-wide, based on signature. It never unloads
+ Stub *pCandidate = sl.Link(SystemDomain::GetGlobalLoaderAllocator()->GetStubHeap(), NEWSTUB_FL_MULTICAST);
+
+ Stub *pWinner = m_pSecureDelegateStubCache->AttemptToSetStub(hash, pCandidate);
+ pCandidate->DecRef();
+ if (!pWinner)
+ COMPlusThrowOM();
+
+ LOG((LF_CORDB,LL_INFO10000, "Putting a MC stub at 0x%x (code:0x%x)\n",
+ pWinner, (BYTE*)pWinner+sizeof(Stub)));
+
+ pStub = pWinner;
+ }
+
+ g_IBCLogger.LogEEClassCOWTableAccess(pDelegateMT);
+ EnsureWritablePages(&delegateEEClass->m_pSecureDelegateInvokeStub);
+ delegateEEClass->m_pSecureDelegateInvokeStub = pStub;
}
RETURN (pStub->GetEntryPoint());
}
diff --git a/src/vm/comdependenthandle.cpp b/src/vm/comdependenthandle.cpp
index 0d2cac53a8..6535a804ae 100644
--- a/src/vm/comdependenthandle.cpp
+++ b/src/vm/comdependenthandle.cpp
@@ -74,3 +74,24 @@ FCIMPL3(VOID, DependentHandle::nGetPrimaryAndSecondary, OBJECTHANDLE handle, Obj
}
FCIMPLEND
+FCIMPL2(VOID, DependentHandle::nSetPrimary, OBJECTHANDLE handle, Object *_primary)
+{
+ FCALL_CONTRACT;
+
+ _ASSERTE(handle != NULL);
+
+ OBJECTREF primary(_primary);
+ StoreObjectInHandle(handle, primary);
+}
+FCIMPLEND
+
+FCIMPL2(VOID, DependentHandle::nSetSecondary, OBJECTHANDLE handle, Object *_secondary)
+{
+ FCALL_CONTRACT;
+
+ _ASSERTE(handle != NULL);
+
+ OBJECTREF secondary(_secondary);
+ SetDependentHandleSecondary(handle, secondary);
+}
+FCIMPLEND
diff --git a/src/vm/comdependenthandle.h b/src/vm/comdependenthandle.h
index 7cf5a1e641..7192a4bbc3 100644
--- a/src/vm/comdependenthandle.h
+++ b/src/vm/comdependenthandle.h
@@ -45,6 +45,8 @@ public:
static FCDECL2(VOID, nGetPrimary, OBJECTHANDLE handle, Object **outPrimary);
static FCDECL3(VOID, nGetPrimaryAndSecondary, OBJECTHANDLE handle, Object **outPrimary, Object **outSecondary);
static FCDECL1(VOID, nFree, OBJECTHANDLE handle);
+ static FCDECL2(VOID, nSetPrimary, OBJECTHANDLE handle, Object *primary);
+ static FCDECL2(VOID, nSetSecondary, OBJECTHANDLE handle, Object *secondary);
};
#endif
diff --git a/src/vm/commemoryfailpoint.cpp b/src/vm/commemoryfailpoint.cpp
index 276a9f305a..4d1ed6ef64 100644
--- a/src/vm/commemoryfailpoint.cpp
+++ b/src/vm/commemoryfailpoint.cpp
@@ -26,7 +26,7 @@ FCIMPL2(void, COMMemoryFailPoint::GetMemorySettings, UINT64* pMaxGCSegmentSize,
{
FCALL_CONTRACT;
- GCHeap * pGC = GCHeap::GetGCHeap();
+ IGCHeap * pGC = GCHeapUtilities::GetGCHeap();
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);
diff --git a/src/vm/commethodrental.cpp b/src/vm/commethodrental.cpp
index 0faf470a2a..0a5c011270 100644
--- a/src/vm/commethodrental.cpp
+++ b/src/vm/commethodrental.cpp
@@ -102,9 +102,9 @@ void QCALLTYPE COMMethodRental::SwapMethodBody(EnregisteredTypeHandle cls, INT32
COMPlusThrowHR(VLDTR_E_MD_BADHEADER);
#ifdef FEATURE_INTERPRETER
- pMethodDesc->MakeJitWorker(&header, CORJIT_FLG_MAKEFINALCODE, 0);
+ pMethodDesc->MakeJitWorker(&header, CORJIT_FLAGS(CORJIT_FLAGS::CORJIT_FLAG_MAKEFINALCODE));
#else // !FEATURE_INTERPRETER
- pMethodDesc->MakeJitWorker(&header, 0, 0);
+ pMethodDesc->MakeJitWorker(&header, CORJIT_FLAGS());
#endif // !FEATURE_INTERPRETER
}
diff --git a/src/vm/commodule.cpp b/src/vm/commodule.cpp
index 44a96d36ab..af6dc48d15 100644
--- a/src/vm/commodule.cpp
+++ b/src/vm/commodule.cpp
@@ -768,8 +768,7 @@ mdString QCALLTYPE COMModule::GetStringConstant(QCall::ModuleHandle pModule, LPC
_ASSERTE(pwzValue != NULL);
HRESULT hr = pRCW->GetEmitter()->DefineUserString(pwzValue, iLength, &strRef);
- if (FAILED(hr)) {
- _ASSERTE(hr == E_OUTOFMEMORY || !"Unknown failure in DefineUserString");
+ if (FAILED(hr)) {
COMPlusThrowHR(hr);
}
diff --git a/src/vm/common.h b/src/vm/common.h
index 123350334b..9de9f35141 100644
--- a/src/vm/common.h
+++ b/src/vm/common.h
@@ -177,7 +177,7 @@ typedef DPTR(class StringBufferObject) PTR_StringBufferObject;
typedef DPTR(class TypeHandle) PTR_TypeHandle;
typedef VPTR(class VirtualCallStubManager) PTR_VirtualCallStubManager;
typedef VPTR(class VirtualCallStubManagerManager) PTR_VirtualCallStubManagerManager;
-typedef VPTR(class GCHeap) PTR_GCHeap;
+typedef VPTR(class IGCHeap) PTR_IGCHeap;
//
// _UNCHECKED_OBJECTREF is for code that can't deal with DEBUG OBJECTREFs
diff --git a/src/vm/compile.cpp b/src/vm/compile.cpp
index 0a2c75da84..87107151eb 100644
--- a/src/vm/compile.cpp
+++ b/src/vm/compile.cpp
@@ -382,7 +382,6 @@ HRESULT CEECompileInfo::LoadAssemblyByPath(
Assembly * pAssembly;
HRESULT hrProcessLibraryBitnessMismatch = S_OK;
- bool verifyingImageIsAssembly = false;
// We don't want to do a LoadFrom, since they do not work with ngen. Instead,
// read the metadata from the file and do a bind based on that.
@@ -416,9 +415,6 @@ HRESULT CEECompileInfo::LoadAssemblyByPath(
fExplicitBindToNativeImage ? MDInternalImport_NoCache : MDInternalImport_Default);
}
-#if defined(FEATURE_WINDOWSPHONE)
- verifyingImageIsAssembly = true;
-#endif // FEATURE_WINDOWSPHONE
if (fExplicitBindToNativeImage && !pImage->HasReadyToRunHeader())
{
pImage->VerifyIsNIAssembly();
@@ -427,8 +423,6 @@ HRESULT CEECompileInfo::LoadAssemblyByPath(
{
pImage->VerifyIsAssembly();
}
-
- verifyingImageIsAssembly = false;
// Check to make sure the bitness of the assembly matches the bitness of the process
// we will be loading it into and store the result. If a COR_IMAGE_ERROR gets thrown
@@ -552,11 +546,7 @@ HRESULT CEECompileInfo::LoadAssemblyByPath(
}
EX_CATCH_HRESULT(hr);
- if (verifyingImageIsAssembly && hr != S_OK)
- {
- hr = NGEN_E_FILE_NOT_ASSEMBLY;
- }
- else if ( hrProcessLibraryBitnessMismatch != S_OK && ( hr == COR_E_BADIMAGEFORMAT || hr == HRESULT_FROM_WIN32(ERROR_BAD_EXE_FORMAT) ) )
+ if ( hrProcessLibraryBitnessMismatch != S_OK && ( hr == COR_E_BADIMAGEFORMAT || hr == HRESULT_FROM_WIN32(ERROR_BAD_EXE_FORMAT) ) )
{
hr = hrProcessLibraryBitnessMismatch;
}
@@ -1497,7 +1487,7 @@ void CEECompileInfo::CompressDebugInfo(
HRESULT CEECompileInfo::GetBaseJitFlags(
IN CORINFO_METHOD_HANDLE hMethod,
- OUT DWORD *pFlags)
+ OUT CORJIT_FLAGS *pFlags)
{
STANDARD_VM_CONTRACT;
@@ -3068,6 +3058,13 @@ private:
DWORD m_dwExtraData;
LPCWSTR m_wszManagedPDBSearchPath;
+ // Currently The DiasymWriter does not use the correct PDB signature for NGEN PDBS unless
+ // the NGEN DLL whose symbols are being generated end in .ni.dll. Thus we copy
+ // to this name if it does not follow this covention (as is true with readyToRun
+ // dlls). This variable remembers this temp file path so we can delete it after
+ // Pdb generation. If DiaSymWriter is fixed, we can remove this.
+ SString m_tempSourceDllName;
+
// Interfaces for reading IL PDB info
ReleaseHolder<ISymUnmanagedBinder> m_pBinder;
ReleaseHolder<ISymUnmanagedReader> m_pReader;
@@ -3115,6 +3112,8 @@ public:
ZeroMemory(m_wszPDBFilePath, sizeof(m_wszPDBFilePath));
}
+
+ ~NGenModulePdbWriter();
HRESULT WritePDBData();
@@ -3415,6 +3414,13 @@ HRESULT NGenModulePdbWriter::InitILPdbData()
return S_OK;
}
+NGenModulePdbWriter::~NGenModulePdbWriter()
+{
+ // Delete any temporary files we created.
+ if (m_tempSourceDllName.GetCount() != 0)
+ DeleteFileW(m_tempSourceDllName);
+ m_tempSourceDllName.Clear();
+}
//---------------------------------------------------------------------------------------
//
@@ -3449,8 +3455,32 @@ HRESULT NGenModulePdbWriter::WritePDBData()
PEImageLayout * pLoadedLayout = m_pModule->GetFile()->GetLoaded();
+ // Currently DiaSymReader does not work properly generating NGEN PDBS unless
+ // the DLL whose PDB is being generated ends in .ni.*. Unfortunately, readyToRun
+ // images do not follow this convention and end up producing bad PDBS. To fix
+ // this (without changing diasymreader.dll which ships indepdendently of .Net Core)
+ // we copy the file to somethign with this convention before generating the PDB
+ // and delete it when we are done.
+ SString dllPath = pLoadedLayout->GetPath();
+ if (!dllPath.EndsWithCaseInsensitive(L".ni.dll") && !dllPath.EndsWithCaseInsensitive(L".ni.exe"))
+ {
+ SString::Iterator fileNameStart = dllPath.Begin();
+ dllPath.FindBack(fileNameStart, '\\');
+
+ SString::Iterator ext = dllPath.End();
+ dllPath.FindBack(ext, '.');
+
+ // m_tempSourceDllName = Convertion of INPUT.dll to INPUT.ni.dll where the PDB lives.
+ m_tempSourceDllName = m_wszPdbPath;
+ m_tempSourceDllName += SString(dllPath, fileNameStart, ext - fileNameStart);
+ m_tempSourceDllName += L".ni";
+ m_tempSourceDllName += SString(dllPath, ext, dllPath.End() - ext);
+ CopyFileW(dllPath, m_tempSourceDllName, false);
+ dllPath = m_tempSourceDllName;
+ }
+
ReleaseHolder<ISymNGenWriter> pWriter1;
- hr = m_Create(pLoadedLayout->GetPath(), m_wszPdbPath, &pWriter1);
+ hr = m_Create(dllPath, m_wszPdbPath, &pWriter1);
if (FAILED(hr))
return hr;
@@ -5423,7 +5453,7 @@ static BOOL CanSatisfyConstraints(Instantiation typicalInst, Instantiation candi
StackScratchBuffer buffer;
thArg.GetName(candidateInstName);
char output[1024];
- sprintf(output, "Generics TypeDependencyAttribute processing: Couldn't satisfy a constraint. Class with Attribute: %s Bad candidate instantiated type: %s\r\n", pMT->GetDebugClassName(), candidateInstName.GetANSI(buffer));
+ _snprintf_s(output, _countof(output), _TRUNCATE, "Generics TypeDependencyAttribute processing: Couldn't satisfy a constraint. Class with Attribute: %s Bad candidate instantiated type: %s\r\n", pMT->GetDebugClassName(), candidateInstName.GetANSI(buffer));
OutputDebugStringA(output);
*/
#endif
@@ -6573,7 +6603,9 @@ 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)
@@ -6650,9 +6682,9 @@ MethodDesc * CEEPreloader::CompileMethodStubIfNeeded(
{
if (!pStubMD->AsDynamicMethodDesc()->GetILStubResolver()->IsCompiled())
{
- DWORD dwJitFlags = pStubMD->AsDynamicMethodDesc()->GetILStubResolver()->GetJitFlags();
+ CORJIT_FLAGS jitFlags = pStubMD->AsDynamicMethodDesc()->GetILStubResolver()->GetJitFlags();
- pfnCallback(pCallbackContext, (CORINFO_METHOD_HANDLE)pStubMD, dwJitFlags);
+ pfnCallback(pCallbackContext, (CORINFO_METHOD_HANDLE)pStubMD, jitFlags);
}
#ifndef FEATURE_FULL_NGEN // Deduplication
diff --git a/src/vm/compile.h b/src/vm/compile.h
index 19bbac3228..8ee66dbec8 100644
--- a/src/vm/compile.h
+++ b/src/vm/compile.h
@@ -377,7 +377,7 @@ class CEECompileInfo : public ICorCompileInfo
HRESULT GetBaseJitFlags(
IN CORINFO_METHOD_HANDLE hMethod,
- OUT DWORD *pFlags);
+ OUT CORJIT_FLAGS *pFlags);
#ifdef _WIN64
SIZE_T getPersonalityValue();
diff --git a/src/vm/comsynchronizable.cpp b/src/vm/comsynchronizable.cpp
index ef195bf5de..e62ec13dde 100644
--- a/src/vm/comsynchronizable.cpp
+++ b/src/vm/comsynchronizable.cpp
@@ -1604,7 +1604,7 @@ FCIMPL0(Object*, ThreadNative::GetDomain)
}
FCIMPLEND
-#ifdef _TARGET_X86_
+#if defined(_TARGET_X86_) && defined(_MSC_VER)
__declspec(naked) LPVOID __fastcall ThreadNative::FastGetDomain()
{
STATIC_CONTRACT_MODE_COOPERATIVE;
@@ -1624,7 +1624,7 @@ done:
ret
}
}
-#else // _TARGET_X86_
+#else // _TARGET_X86_ && _MSC_VER
LPVOID F_CALL_CONV ThreadNative::FastGetDomain()
{
CONTRACTL
@@ -1650,7 +1650,7 @@ LPVOID F_CALL_CONV ThreadNative::FastGetDomain()
}
return NULL;
}
-#endif // _TARGET_X86_
+#endif // _TARGET_X86_ && _MSC_VER
#ifdef FEATURE_REMOTING
// This is just a helper method that lets BCL get to the managed context
diff --git a/src/vm/comthreadpool.cpp b/src/vm/comthreadpool.cpp
index 7f629b508b..a4c7e75064 100644
--- a/src/vm/comthreadpool.cpp
+++ b/src/vm/comthreadpool.cpp
@@ -632,6 +632,7 @@ 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
@@ -655,6 +656,7 @@ void SetAsyncResultProperties(
if ((h != NULL) && (h != (HANDLE) -1))
UnsafeSetEvent(h);
}
+#endif // !FEATURE_CORECLR
}
VOID BindIoCompletionCallBack_Worker(LPVOID args)
@@ -663,11 +665,11 @@ VOID BindIoCompletionCallBack_Worker(LPVOID args)
STATIC_CONTRACT_GC_TRIGGERS;
STATIC_CONTRACT_MODE_ANY;
STATIC_CONTRACT_SO_INTOLERANT;
-
+
DWORD ErrorCode = ((BindIoCompletion_Args *)args)->ErrorCode;
DWORD numBytesTransferred = ((BindIoCompletion_Args *)args)->numBytesTransferred;
LPOVERLAPPED lpOverlapped = ((BindIoCompletion_Args *)args)->lpOverlapped;
-
+
OVERLAPPEDDATAREF overlapped = ObjectToOVERLAPPEDDATAREF(OverlappedDataObject::GetOverlapped(lpOverlapped));
GCPROTECT_BEGIN(overlapped);
@@ -682,7 +684,7 @@ VOID BindIoCompletionCallBack_Worker(LPVOID args)
if (overlapped->m_iocb != NULL)
{
// Caution: the args are not protected, we have to garantee there's no GC from here till
- PREPARE_NONVIRTUAL_CALLSITE(METHOD__IOCB_HELPER__PERFORM_IOCOMPLETION_CALLBACK);
+ PREPARE_NONVIRTUAL_CALLSITE(METHOD__IOCB_HELPER__PERFORM_IOCOMPLETION_CALLBACK);
DECLARE_ARGHOLDER_ARRAY(arg, 3);
arg[ARGNUM_0] = DWORD_TO_ARGHOLDER(ErrorCode);
arg[ARGNUM_1] = DWORD_TO_ARGHOLDER(numBytesTransferred);
@@ -692,21 +694,23 @@ VOID BindIoCompletionCallBack_Worker(LPVOID args)
CALL_MANAGED_METHOD_NORET(arg);
}
else
- { // no user delegate to callback
+ {
+ // 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);
}
GCPROTECT_END();
}
-
void __stdcall BindIoCompletionCallbackStubEx(DWORD ErrorCode,
DWORD numBytesTransferred,
LPOVERLAPPED lpOverlapped,
@@ -769,9 +773,6 @@ void __stdcall BindIoCompletionCallbackStubEx(DWORD ErrorCode,
ManagedThreadBase::ThreadPool(ADID(overlapped->GetAppDomainId()), BindIoCompletionCallBack_Worker, &args);
}
-
-
-
LOG((LF_INTEROP, LL_INFO10000, "Leaving IO_CallBackStub thread 0x%x retCode 0x%x, overlap 0x%x\n", pThread, ErrorCode, lpOverlapped));
// We should have released all locks.
_ASSERTE(g_fEEShutDown || pThread->m_dwLockCount == 0 || pThread->m_fRudeAborted);
diff --git a/src/vm/comutilnative.cpp b/src/vm/comutilnative.cpp
index b55c63549d..41655cb5b0 100644
--- a/src/vm/comutilnative.cpp
+++ b/src/vm/comutilnative.cpp
@@ -27,7 +27,7 @@
#include "frames.h"
#include "field.h"
#include "winwrap.h"
-#include "gc.h"
+#include "gcheaputilities.h"
#include "fcall.h"
#include "invokeutil.h"
#include "eeconfig.h"
@@ -1478,7 +1478,11 @@ FCIMPL5(VOID, Buffer::BlockCopy, ArrayBase *src, int srcOffset, ArrayBase *dst,
PTR_BYTE dstPtr = dst->GetDataPtr() + dstOffset;
if ((srcPtr != dstPtr) && (count > 0)) {
+#if defined(_AMD64_) && !defined(PLATFORM_UNIX)
+ JIT_MemCpy(dstPtr, srcPtr, count);
+#else
memmove(dstPtr, srcPtr, count);
+#endif
}
FC_GC_POLL();
@@ -1524,7 +1528,11 @@ FCIMPL5(VOID, Buffer::InternalBlockCopy, ArrayBase *src, int srcOffset, ArrayBas
_ASSERTE(count >= 0);
// Copy the data.
+#if defined(_AMD64_) && !defined(PLATFORM_UNIX)
+ JIT_MemCpy(dst->GetDataPtr() + dstOffset, src->GetDataPtr() + srcOffset, count);
+#else
memmove(dst->GetDataPtr() + dstOffset, src->GetDataPtr() + srcOffset, count);
+#endif
FC_GC_POLL();
}
@@ -1638,7 +1646,7 @@ FCIMPL0(int, GCInterface::GetGcLatencyMode)
FC_GC_POLL_NOT_NEEDED();
- int result = (INT32)GCHeap::GetGCHeap()->GetGcLatencyMode();
+ int result = (INT32)GCHeapUtilities::GetGCHeap()->GetGcLatencyMode();
return result;
}
FCIMPLEND
@@ -1649,7 +1657,7 @@ FCIMPL1(int, GCInterface::SetGcLatencyMode, int newLatencyMode)
FC_GC_POLL_NOT_NEEDED();
- return GCHeap::GetGCHeap()->SetGcLatencyMode(newLatencyMode);
+ return GCHeapUtilities::GetGCHeap()->SetGcLatencyMode(newLatencyMode);
}
FCIMPLEND
@@ -1659,7 +1667,7 @@ FCIMPL0(int, GCInterface::GetLOHCompactionMode)
FC_GC_POLL_NOT_NEEDED();
- int result = (INT32)GCHeap::GetGCHeap()->GetLOHCompactionMode();
+ int result = (INT32)GCHeapUtilities::GetGCHeap()->GetLOHCompactionMode();
return result;
}
FCIMPLEND
@@ -1670,7 +1678,7 @@ FCIMPL1(void, GCInterface::SetLOHCompactionMode, int newLOHCompactionyMode)
FC_GC_POLL_NOT_NEEDED();
- GCHeap::GetGCHeap()->SetLOHCompactionMode(newLOHCompactionyMode);
+ GCHeapUtilities::GetGCHeap()->SetLOHCompactionMode(newLOHCompactionyMode);
}
FCIMPLEND
@@ -1681,7 +1689,7 @@ FCIMPL2(FC_BOOL_RET, GCInterface::RegisterForFullGCNotification, UINT32 gen2Perc
FC_GC_POLL_NOT_NEEDED();
- FC_RETURN_BOOL(GCHeap::GetGCHeap()->RegisterForFullGCNotification(gen2Percentage, lohPercentage));
+ FC_RETURN_BOOL(GCHeapUtilities::GetGCHeap()->RegisterForFullGCNotification(gen2Percentage, lohPercentage));
}
FCIMPLEND
@@ -1690,7 +1698,7 @@ FCIMPL0(FC_BOOL_RET, GCInterface::CancelFullGCNotification)
FCALL_CONTRACT;
FC_GC_POLL_NOT_NEEDED();
- FC_RETURN_BOOL(GCHeap::GetGCHeap()->CancelFullGCNotification());
+ FC_RETURN_BOOL(GCHeapUtilities::GetGCHeap()->CancelFullGCNotification());
}
FCIMPLEND
@@ -1711,7 +1719,7 @@ FCIMPL1(int, GCInterface::WaitForFullGCApproach, int millisecondsTimeout)
HELPER_METHOD_FRAME_BEGIN_RET_0();
DWORD dwMilliseconds = ((millisecondsTimeout == -1) ? INFINITE : millisecondsTimeout);
- result = GCHeap::GetGCHeap()->WaitForFullGCApproach(dwMilliseconds);
+ result = GCHeapUtilities::GetGCHeap()->WaitForFullGCApproach(dwMilliseconds);
HELPER_METHOD_FRAME_END();
@@ -1736,7 +1744,7 @@ FCIMPL1(int, GCInterface::WaitForFullGCComplete, int millisecondsTimeout)
HELPER_METHOD_FRAME_BEGIN_RET_0();
DWORD dwMilliseconds = ((millisecondsTimeout == -1) ? INFINITE : millisecondsTimeout);
- result = GCHeap::GetGCHeap()->WaitForFullGCComplete(dwMilliseconds);
+ result = GCHeapUtilities::GetGCHeap()->WaitForFullGCComplete(dwMilliseconds);
HELPER_METHOD_FRAME_END();
@@ -1757,7 +1765,7 @@ FCIMPL1(int, GCInterface::GetGeneration, Object* objUNSAFE)
if (objUNSAFE == NULL)
FCThrowArgumentNull(W("obj"));
- int result = (INT32)GCHeap::GetGCHeap()->WhichGeneration(objUNSAFE);
+ int result = (INT32)GCHeapUtilities::GetGCHeap()->WhichGeneration(objUNSAFE);
FC_GC_POLL_RET();
return result;
}
@@ -1777,7 +1785,7 @@ FCIMPL2(int, GCInterface::CollectionCount, INT32 generation, INT32 getSpecialGCC
_ASSERTE(generation >= 0);
//We don't need to check the top end because the GC will take care of that.
- int result = (INT32)GCHeap::GetGCHeap()->CollectionCount(generation, getSpecialGCCount);
+ int result = (INT32)GCHeapUtilities::GetGCHeap()->CollectionCount(generation, getSpecialGCCount);
FC_GC_POLL_RET();
return result;
}
@@ -1793,7 +1801,7 @@ int QCALLTYPE GCInterface::StartNoGCRegion(INT64 totalSize, BOOL lohSizeKnown, I
GCX_COOP();
- retVal = GCHeap::GetGCHeap()->StartNoGCRegion((ULONGLONG)totalSize,
+ retVal = GCHeapUtilities::GetGCHeap()->StartNoGCRegion((ULONGLONG)totalSize,
lohSizeKnown,
(ULONGLONG)lohSize,
disallowFullBlockingGC);
@@ -1811,7 +1819,7 @@ int QCALLTYPE GCInterface::EndNoGCRegion()
BEGIN_QCALL;
- retVal = GCHeap::GetGCHeap()->EndNoGCRegion();
+ retVal = GCHeapUtilities::GetGCHeap()->EndNoGCRegion();
END_QCALL;
@@ -1837,7 +1845,7 @@ FCIMPL1(int, GCInterface::GetGenerationWR, LPVOID handle)
if (temp == NULL)
COMPlusThrowArgumentNull(W("weak handle"));
- iRetVal = (INT32)GCHeap::GetGCHeap()->WhichGeneration(OBJECTREFToObject(temp));
+ iRetVal = (INT32)GCHeapUtilities::GetGCHeap()->WhichGeneration(OBJECTREFToObject(temp));
HELPER_METHOD_FRAME_END();
@@ -1860,7 +1868,7 @@ INT64 QCALLTYPE GCInterface::GetTotalMemory()
BEGIN_QCALL;
GCX_COOP();
- iRetVal = (INT64) GCHeap::GetGCHeap()->GetTotalBytesInUse();
+ iRetVal = (INT64) GCHeapUtilities::GetGCHeap()->GetTotalBytesInUse();
END_QCALL;
@@ -1885,7 +1893,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();
- GCHeap::GetGCHeap()->GarbageCollect(generation, FALSE, mode);
+ GCHeapUtilities::GetGCHeap()->GarbageCollect(generation, FALSE, mode);
END_QCALL;
}
@@ -1918,7 +1926,7 @@ FCIMPL0(int, GCInterface::GetMaxGeneration)
{
FCALL_CONTRACT;
- return(INT32)GCHeap::GetGCHeap()->GetMaxGeneration();
+ return(INT32)GCHeapUtilities::GetGCHeap()->GetMaxGeneration();
}
FCIMPLEND
@@ -1934,7 +1942,7 @@ FCIMPL0(INT64, GCInterface::GetAllocatedBytesForCurrentThread)
INT64 currentAllocated = 0;
Thread *pThread = GetThread();
- alloc_context* ac = pThread->GetAllocContext();
+ gc_alloc_context* ac = pThread->GetAllocContext();
currentAllocated = ac->alloc_bytes + ac->alloc_bytes_loh - (ac->alloc_limit - ac->alloc_ptr);
return currentAllocated;
@@ -1956,7 +1964,7 @@ FCIMPL1(void, GCInterface::SuppressFinalize, Object *obj)
if (!obj->GetMethodTable ()->HasFinalizer())
return;
- GCHeap::GetGCHeap()->SetFinalizationRun(obj);
+ GCHeapUtilities::GetGCHeap()->SetFinalizationRun(obj);
FC_GC_POLL();
}
FCIMPLEND
@@ -1977,7 +1985,7 @@ FCIMPL1(void, GCInterface::ReRegisterForFinalize, Object *obj)
if (obj->GetMethodTable()->HasFinalizer())
{
HELPER_METHOD_FRAME_BEGIN_1(obj);
- GCHeap::GetGCHeap()->RegisterForFinalization(-1, obj);
+ GCHeapUtilities::GetGCHeap()->RegisterForFinalization(-1, obj);
HELPER_METHOD_FRAME_END();
}
}
@@ -2079,7 +2087,7 @@ void GCInterface::AddMemoryPressure(UINT64 bytesAllocated)
m_ulThreshold = (addMethod > multMethod) ? addMethod : multMethod;
for (int i = 0; i <= 1; i++)
{
- if ((GCHeap::GetGCHeap()->CollectionCount(i) / RELATIVE_GC_RATIO) > GCHeap::GetGCHeap()->CollectionCount(i + 1))
+ if ((GCHeapUtilities::GetGCHeap()->CollectionCount(i) / RELATIVE_GC_RATIO) > GCHeapUtilities::GetGCHeap()->CollectionCount(i + 1))
{
gen_collect = i + 1;
break;
@@ -2089,14 +2097,14 @@ void GCInterface::AddMemoryPressure(UINT64 bytesAllocated)
PREFIX_ASSUME(gen_collect <= 2);
- if ((gen_collect == 0) || (m_gc_counts[gen_collect] == GCHeap::GetGCHeap()->CollectionCount(gen_collect)))
+ if ((gen_collect == 0) || (m_gc_counts[gen_collect] == GCHeapUtilities::GetGCHeap()->CollectionCount(gen_collect)))
{
GarbageCollectModeAny(gen_collect);
}
for (int i = 0; i < 3; i++)
{
- m_gc_counts [i] = GCHeap::GetGCHeap()->CollectionCount(i);
+ m_gc_counts [i] = GCHeapUtilities::GetGCHeap()->CollectionCount(i);
}
}
}
@@ -2115,7 +2123,7 @@ void GCInterface::CheckCollectionCount()
{
LIMITED_METHOD_CONTRACT;
- GCHeap * pHeap = GCHeap::GetGCHeap();
+ IGCHeap * pHeap = GCHeapUtilities::GetGCHeap();
if (m_gc_counts[2] != pHeap->CollectionCount(2))
{
@@ -2200,7 +2208,7 @@ void GCInterface::NewAddMemoryPressure(UINT64 bytesAllocated)
// If still over budget, check current managed heap size
if (newMemValue >= budget)
{
- GCHeap *pGCHeap = GCHeap::GetGCHeap();
+ IGCHeap *pGCHeap = GCHeapUtilities::GetGCHeap();
UINT64 heapOver3 = pGCHeap->GetCurrentObjSize() / 3;
if (budget < heapOver3) // Max
@@ -2274,7 +2282,7 @@ void GCInterface::RemoveMemoryPressure(UINT64 bytesAllocated)
for (int i = 0; i < 3; i++)
{
- m_gc_counts [i] = GCHeap::GetGCHeap()->CollectionCount(i);
+ m_gc_counts [i] = GCHeapUtilities::GetGCHeap()->CollectionCount(i);
}
}
}
@@ -2348,7 +2356,7 @@ NOINLINE void GCInterface::GarbageCollectModeAny(int generation)
CONTRACTL_END;
GCX_COOP();
- GCHeap::GetGCHeap()->GarbageCollect(generation, FALSE, collection_non_blocking);
+ GCHeapUtilities::GetGCHeap()->GarbageCollect(generation, FALSE, collection_non_blocking);
}
//
diff --git a/src/vm/constrainedexecutionregion.cpp b/src/vm/constrainedexecutionregion.cpp
index d256c43424..77b944c416 100644
--- a/src/vm/constrainedexecutionregion.cpp
+++ b/src/vm/constrainedexecutionregion.cpp
@@ -1745,10 +1745,6 @@ void PrepopulateGenericHandleCache(DictionaryLayout *pDictionaryLayout,
MethodDesc *pMD,
MethodTable *pMT)
{
-#ifdef FEATURE_CORECLR
- // Disable this function in CoreCLR to work around https://github.com/dotnet/corefx/issues/12412.
- LIMITED_METHOD_CONTRACT;
-#else
CONTRACTL {
THROWS;
GC_TRIGGERS;
@@ -1772,7 +1768,6 @@ void PrepopulateGenericHandleCache(DictionaryLayout *pDictionaryLayout,
}
pOverflows = pOverflows->GetNextLayout();
}
-#endif // FEATURE_CORECLR
}
#ifdef FEATURE_PREJIT
diff --git a/src/vm/constrainedexecutionregion.h b/src/vm/constrainedexecutionregion.h
index 93ceb63010..4b41b2570e 100644
--- a/src/vm/constrainedexecutionregion.h
+++ b/src/vm/constrainedexecutionregion.h
@@ -13,6 +13,7 @@
#ifndef __CONSTRAINED_EXECUTION_REGION_H
#define __CONSTRAINED_EXECUTION_REGION_H
+#ifdef FEATURE_CER
#include <corhlpr.h>
#include <typestring.h>
@@ -560,4 +561,6 @@ private:
#endif
};
+#endif // FEATURE_CER
+
#endif
diff --git a/src/vm/corhost.cpp b/src/vm/corhost.cpp
index c229a0ee07..6091bad9e2 100644
--- a/src/vm/corhost.cpp
+++ b/src/vm/corhost.cpp
@@ -5170,7 +5170,7 @@ public:
HRESULT hr = S_OK;
- if (Generation > (int) GCHeap::GetGCHeap()->GetMaxGeneration())
+ if (Generation > (int) GCHeapUtilities::GetGCHeap()->GetMaxGeneration())
hr = E_INVALIDARG;
if (SUCCEEDED(hr))
@@ -5188,7 +5188,7 @@ public:
EX_TRY
{
STRESS_LOG0(LF_GC, LL_INFO100, "Host triggers GC\n");
- hr = GCHeap::GetGCHeap()->GarbageCollect(Generation);
+ hr = GCHeapUtilities::GetGCHeap()->GarbageCollect(Generation);
}
EX_CATCH
{
@@ -5354,7 +5354,7 @@ HRESULT CCLRGCManager::_SetGCSegmentSize(SIZE_T SegmentSize)
HRESULT hr = S_OK;
// Sanity check the value, it must be a power of two and big enough.
- if (!GCHeap::IsValidSegmentSize(SegmentSize))
+ if (!GCHeapUtilities::GetGCHeap()->IsValidSegmentSize(SegmentSize))
{
hr = E_INVALIDARG;
}
@@ -5380,7 +5380,7 @@ HRESULT CCLRGCManager::_SetGCMaxGen0Size(SIZE_T MaxGen0Size)
HRESULT hr = S_OK;
// Sanity check the value is at least large enough.
- if (!GCHeap::IsValidGen0MaxSize(MaxGen0Size))
+ if (!GCHeapUtilities::GetGCHeap()->IsValidGen0MaxSize(MaxGen0Size))
{
hr = E_INVALIDARG;
}
@@ -6408,7 +6408,7 @@ HRESULT CCLRDebugManager::SetConnectionTasks(
}
// Check for Finalizer thread
- if (GCHeap::IsGCHeapInitialized() && (pThread == FinalizerThread::GetFinalizerThread()))
+ if (GCHeapUtilities::IsGCHeapInitialized() && (pThread == FinalizerThread::GetFinalizerThread()))
{
// _ASSERTE(!"Host should not try to schedule user code on our Finalizer Thread");
IfFailGo(E_INVALIDARG);
diff --git a/src/vm/crossgen/CMakeLists.txt b/src/vm/crossgen/CMakeLists.txt
index c2392a2d9a..c6ef163d53 100644
--- a/src/vm/crossgen/CMakeLists.txt
+++ b/src/vm/crossgen/CMakeLists.txt
@@ -16,7 +16,6 @@ set(VM_CROSSGEN_SOURCES
../comdelegate.cpp
../codeman.cpp
../compile.cpp
- ../constrainedexecutionregion.cpp
../custommarshalerinfo.cpp
../domainfile.cpp
../baseassemblyspec.cpp
@@ -97,6 +96,12 @@ 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/crossgen_mscorlib/mscorlib_crossgen.nativeproj b/src/vm/crossgen_mscorlib/mscorlib_crossgen.nativeproj
index be65670654..67e6f4acd2 100644
--- a/src/vm/crossgen_mscorlib/mscorlib_crossgen.nativeproj
+++ b/src/vm/crossgen_mscorlib/mscorlib_crossgen.nativeproj
@@ -1,5 +1,12 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="dogfood">
+ <PropertyGroup>
+ <!-- Work around problems with loading System.Private.CoreLib.dll, -->
+ <!-- caused by inconsistent setting of UseLegacyCompiler and FeatureSpanOfT -->
+ <!-- between System.Private.CoreLib.dll and the runtime. -->
+ <UseLegacyCompiler>true</UseLegacyCompiler>
+ </PropertyGroup>
+
<Import Project="$(_NTDRIVE)$(_NTROOT)\ndp\clr\xplat\SetCrossGen.props" />
<PropertyGroup>
diff --git a/src/vm/crossgencompile.cpp b/src/vm/crossgencompile.cpp
index 85859c2d82..ffb025adb0 100644
--- a/src/vm/crossgencompile.cpp
+++ b/src/vm/crossgencompile.cpp
@@ -130,7 +130,7 @@ BOOL __SwitchToThread(DWORD, DWORD)
// Globals and misc other
//
-GPTR_IMPL(GCHeap,g_pGCHeap);
+GPTR_IMPL(IGCHeap,g_pGCHeap);
BOOL g_fEEOtherStartup=FALSE;
BOOL g_fEEComActivatedStartup=FALSE;
@@ -138,7 +138,7 @@ BOOL g_fEEComActivatedStartup=FALSE;
GVAL_IMPL_INIT(DWORD, g_fHostConfig, 0);
#ifdef FEATURE_SVR_GC
-SVAL_IMPL_INIT(uint32_t,GCHeap,gcHeapType,GCHeap::GC_HEAP_WKS);
+SVAL_IMPL_INIT(uint32_t,IGCHeap,gcHeapType,IGCHeap::GC_HEAP_WKS);
#endif
void UpdateGCSettingFromHost()
diff --git a/src/vm/crst.cpp b/src/vm/crst.cpp
index a72ec9d3c0..7bf9bd65da 100644
--- a/src/vm/crst.cpp
+++ b/src/vm/crst.cpp
@@ -627,7 +627,7 @@ void CrstBase::PreEnter()
|| (pThread != NULL && pThread->PreemptiveGCDisabled())
// If GC heap has not been initialized yet, there is no need to synchronize with GC.
// This check is mainly for code called from EEStartup.
- || (pThread == NULL && !GCHeap::IsGCHeapInitialized()) );
+ || (pThread == NULL && !GCHeapUtilities::IsGCHeapInitialized()) );
}
if ((pThread != NULL) &&
@@ -910,7 +910,7 @@ BOOL CrstBase::IsSafeToTake()
_ASSERTE(pThread == NULL ||
(pThread->PreemptiveGCDisabled() == ((m_dwFlags & CRST_UNSAFE_COOPGC) != 0)) ||
((m_dwFlags & (CRST_UNSAFE_ANYMODE | CRST_GC_NOTRIGGER_WHEN_TAKEN)) != 0) ||
- (GCHeap::IsGCInProgress() && pThread == ThreadSuspend::GetSuspensionThread()));
+ (GCHeapUtilities::IsGCInProgress() && pThread == ThreadSuspend::GetSuspensionThread()));
END_GETTHREAD_ALLOWED;
if (m_holderthreadid.IsCurrentThread())
diff --git a/src/vm/customattribute.cpp b/src/vm/customattribute.cpp
index 48d79a2271..a83815f8bf 100644
--- a/src/vm/customattribute.cpp
+++ b/src/vm/customattribute.cpp
@@ -141,58 +141,56 @@ CustomAttributeManagedValues Attribute::GetManagedCaValue(CaValue* pCaVal)
CustomAttributeManagedValues gc;
ZeroMemory(&gc, sizeof(gc));
-
- CorSerializationType type = pCaVal->type.tag;
-
- if (type == SERIALIZATION_TYPE_ENUM)
- {
- gc.string = StringObject::NewString(pCaVal->type.szEnumName, pCaVal->type.cEnumName);
- }
- else if (type == SERIALIZATION_TYPE_STRING)
- {
- gc.string = NULL;
+ GCPROTECT_BEGIN(gc)
+ {
+ CorSerializationType type = pCaVal->type.tag;
- if (pCaVal->str.pStr)
- gc.string = StringObject::NewString(pCaVal->str.pStr, pCaVal->str.cbStr);
- }
- else if (type == SERIALIZATION_TYPE_TYPE)
- {
- gc.string = StringObject::NewString(pCaVal->str.pStr, pCaVal->str.cbStr);
- }
- else if (type == SERIALIZATION_TYPE_SZARRAY)
- {
- CorSerializationType arrayType = pCaVal->type.arrayType;
- ULONG length = pCaVal->arr.length;
- BOOL bAllBlittableCa = arrayType != SERIALIZATION_TYPE_ENUM;
+ if (type == SERIALIZATION_TYPE_ENUM)
+ {
+ gc.string = StringObject::NewString(pCaVal->type.szEnumName, pCaVal->type.cEnumName);
+ }
+ else if (type == SERIALIZATION_TYPE_STRING)
+ {
+ gc.string = NULL;
+
+ if (pCaVal->str.pStr)
+ gc.string = StringObject::NewString(pCaVal->str.pStr, pCaVal->str.cbStr);
+ }
+ else if (type == SERIALIZATION_TYPE_TYPE)
+ {
+ gc.string = StringObject::NewString(pCaVal->str.pStr, pCaVal->str.cbStr);
+ }
+ else if (type == SERIALIZATION_TYPE_SZARRAY)
+ {
+ CorSerializationType arrayType = pCaVal->type.arrayType;
+ ULONG length = pCaVal->arr.length;
+ BOOL bAllBlittableCa = arrayType != SERIALIZATION_TYPE_ENUM;
- if (length == (ULONG)-1)
- return gc;
-
- gc.array = (CaValueArrayREF)AllocateValueSzArray(MscorlibBinder::GetClass(CLASS__CUSTOM_ATTRIBUTE_ENCODED_ARGUMENT), length);
- CustomAttributeValue* pValues = gc.array->GetDirectPointerToNonObjectElements();
+ if (arrayType == SERIALIZATION_TYPE_ENUM)
+ gc.string = StringObject::NewString(pCaVal->type.szEnumName, pCaVal->type.cEnumName);
- for (COUNT_T i = 0; i < length; i ++)
- Attribute::SetBlittableCaValue(&pValues[i], &pCaVal->arr[i], &bAllBlittableCa);
+ if (length != (ULONG)-1)
+ {
+ gc.array = (CaValueArrayREF)AllocateValueSzArray(MscorlibBinder::GetClass(CLASS__CUSTOM_ATTRIBUTE_ENCODED_ARGUMENT), length);
+ CustomAttributeValue* pValues = gc.array->GetDirectPointerToNonObjectElements();
- if (!bAllBlittableCa)
- {
- GCPROTECT_BEGIN(gc)
- {
- if (arrayType == SERIALIZATION_TYPE_ENUM)
- gc.string = StringObject::NewString(pCaVal->type.szEnumName, pCaVal->type.cEnumName);
-
for (COUNT_T i = 0; i < length; i ++)
+ Attribute::SetBlittableCaValue(&pValues[i], &pCaVal->arr[i], &bAllBlittableCa);
+
+ if (!bAllBlittableCa)
{
- CustomAttributeManagedValues managedCaValue = Attribute::GetManagedCaValue(&pCaVal->arr[i]);
- Attribute::SetManagedValue(
- managedCaValue,
- &gc.array->GetDirectPointerToNonObjectElements()[i]);
+ for (COUNT_T i = 0; i < length; i ++)
+ {
+ CustomAttributeManagedValues managedCaValue = Attribute::GetManagedCaValue(&pCaVal->arr[i]);
+ Attribute::SetManagedValue(
+ managedCaValue,
+ &gc.array->GetDirectPointerToNonObjectElements()[i]);
+ }
}
}
- GCPROTECT_END();
}
}
-
+ GCPROTECT_END();
return gc;
}
@@ -908,6 +906,7 @@ 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;
@@ -993,6 +992,7 @@ FCIMPL4(VOID, COMCustomAttribute::GetSecurityAttributes, ReflectModuleBaseObject
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/dac/dacwks.targets b/src/vm/dac/dacwks.targets
index 82ab5439d5..6f6b9279a2 100644
--- a/src/vm/dac/dacwks.targets
+++ b/src/vm/dac/dacwks.targets
@@ -40,6 +40,7 @@
<CppCompile Include="$(ClrSrcDirectory)\vm\fptrstubs.cpp" />
<CppCompile Include="$(ClrSrcDirectory)\vm\frames.cpp" />
<CppCompile Include="$(ClrSrcDirectory)\vm\GCDecode.cpp" />
+ <CppCompile Include="$(ClrSrcDirectory)\vm\gcheaputilities.cpp" />
<CppCompile Include="$(ClrSrcDirectory)\vm\genericdict.cpp" />
<CppCompile Include="$(ClrSrcDirectory)\vm\generics.cpp" />
<CppCompile Include="$(ClrSrcDirectory)\vm\hash.cpp" />
diff --git a/src/vm/dataimage.cpp b/src/vm/dataimage.cpp
index 83ff0a4f9f..e90c7e6a0e 100644
--- a/src/vm/dataimage.cpp
+++ b/src/vm/dataimage.cpp
@@ -896,8 +896,10 @@ 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 9ea5427dfe..c8b76bf6dc 100644
--- a/src/vm/debugdebugger.cpp
+++ b/src/vm/debugdebugger.cpp
@@ -22,7 +22,7 @@
#include "frames.h"
#include "vars.hpp"
#include "field.h"
-#include "gc.h"
+#include "gcheaputilities.h"
#include "jitinterface.h"
#include "debugdebugger.h"
#include "dbginterface.h"
@@ -1403,7 +1403,7 @@ FCIMPL4(INT32, DebuggerAssert::ShowDefaultAssertDialog,
}
msgText.Append(W("Description: "));
msgText.Append(message);
-
+
StackSString stackTraceText;
if (gc.strStackTrace != NULL) {
stackTraceText.Append(W("Stack Trace:\n"));
@@ -1414,25 +1414,33 @@ FCIMPL4(INT32, DebuggerAssert::ShowDefaultAssertDialog,
windowTitle.Set(W("Assert Failure"));
}
- // We're taking a string from managed code, and we can't be sure it doesn't have stuff like %s or \n in it.
- // So, pass a format string of %s and pass the text as a vararg to our message box method.
- // Also, varargs and StackSString don't mix. Convert to string first.
- const WCHAR* msgTextAsUnicode = msgText.GetUnicode();
- result = EEMessageBoxNonLocalizedNonFatal(W("%s"), windowTitle, stackTraceText, MB_ABORTRETRYIGNORE | MB_ICONEXCLAMATION, msgTextAsUnicode);
-
- // map the user's choice to the values recognized by
- // the System.Diagnostics.Assert package
- if (result == IDRETRY)
- {
- result = FailDebug;
- }
- else if (result == IDIGNORE)
+ if (NoGuiOnAssert())
{
- result = FailIgnore;
+ fwprintf(stderr, W("%s\n%s\n%s\n"), windowTitle.GetUnicode(), msgText.GetUnicode(), stackTraceText.GetUnicode());
+ result = FailTerminate;
}
else
{
- result = FailTerminate;
+ // We're taking a string from managed code, and we can't be sure it doesn't have stuff like %s or \n in it.
+ // So, pass a format string of %s and pass the text as a vararg to our message box method.
+ // Also, varargs and StackSString don't mix. Convert to string first.
+ const WCHAR* msgTextAsUnicode = msgText.GetUnicode();
+ result = EEMessageBoxNonLocalizedNonFatal(W("%s"), windowTitle, stackTraceText, MB_ABORTRETRYIGNORE | MB_ICONEXCLAMATION, msgTextAsUnicode);
+
+ // map the user's choice to the values recognized by
+ // the System.Diagnostics.Assert package
+ if (result == IDRETRY)
+ {
+ result = FailDebug;
+ }
+ else if (result == IDIGNORE)
+ {
+ result = FailIgnore;
+ }
+ else
+ {
+ result = FailTerminate;
+ }
}
HELPER_METHOD_FRAME_END();
diff --git a/src/vm/debughelp.cpp b/src/vm/debughelp.cpp
index df769455aa..abe45d5da0 100644
--- a/src/vm/debughelp.cpp
+++ b/src/vm/debughelp.cpp
@@ -6,9 +6,9 @@
#include "common.h"
/*******************************************************************/
-/* The folowing routines used to exist in all builds so they could called from the
+/* The following routines used to exist in all builds so they could called from the
* debugger before we had strike.
- * Now most of them are only inclued in debug builds for diagnostics purposes.
+ * Now most of them are only included in debug builds for diagnostics purposes.
*/
/*******************************************************************/
@@ -24,6 +24,12 @@ BOOL isMemoryReadable(const TADDR start, unsigned len)
}
CONTRACTL_END;
+#if !defined(DACCESS_COMPILE) && defined(FEATURE_PAL)
+
+ return PAL_ProbeMemory((PVOID)start, len, FALSE);
+
+#else // !DACCESS_COMPILE && FEATURE_PAL
+
//
// To accomplish this in a no-throw way, we have to touch each and every page
// and see if it is in memory or not.
@@ -87,6 +93,7 @@ BOOL isMemoryReadable(const TADDR start, unsigned len)
}
return 1;
+#endif // !DACCESS_COMPILE && FEATURE_PAL
}
@@ -202,7 +209,7 @@ void *DumpEnvironmentBlock(void)
return WszGetEnvironmentStrings();
}
-#if defined(_TARGET_X86_)
+#if defined(_TARGET_X86_) && !defined(FEATURE_PAL)
/*******************************************************************/
// Dump the SEH chain to stderr
void PrintSEHChain(void)
@@ -1198,12 +1205,12 @@ void DumpGCInfo(MethodDesc* method)
_ASSERTE(codeInfo.GetRelOffset() == 0);
ICodeManager* codeMan = codeInfo.GetCodeManager();
- GCInfoToken table = codeInfo.GetGCInfoToken();
+ GCInfoToken gcInfoToken = codeInfo.GetGCInfoToken();
- unsigned methodSize = (unsigned)codeMan->GetFunctionSize(table);
+ unsigned methodSize = (unsigned)codeMan->GetFunctionSize(gcInfoToken);
- GCDump gcDump(table.Version);
- PTR_CBYTE gcInfo = PTR_CBYTE(table.Info);
+ GCDump gcDump(gcInfoToken.Version);
+ PTR_CBYTE gcInfo = PTR_CBYTE(gcInfoToken.Info);
gcDump.gcPrintf = printfToDbgOut;
diff --git a/src/vm/dllimport.cpp b/src/vm/dllimport.cpp
index f724169ebf..a3f7f30d86 100644
--- a/src/vm/dllimport.cpp
+++ b/src/vm/dllimport.cpp
@@ -1024,7 +1024,7 @@ public:
pcsUnmarshal->EmitRET();
}
- DWORD dwJitFlags = CORJIT_FLG_IL_STUB;
+ CORJIT_FLAGS jitFlags(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB);
if (m_slIL.HasInteropParamExceptionInfo())
{
@@ -1049,7 +1049,7 @@ public:
else
{
// All other IL stubs will need to use the secret parameter.
- dwJitFlags |= CORJIT_FLG_PUBLISH_SECRET_PARAM;
+ jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_PUBLISH_SECRET_PARAM);
}
if (SF_IsReverseStub(m_dwStubFlags))
@@ -1114,7 +1114,7 @@ public:
m_slIL.GenerateCode(pbBuffer, cbCode);
m_slIL.GetLocalSig(pbLocalSig, cbSig);
- pResolver->SetJitFlags(dwJitFlags);
+ pResolver->SetJitFlags(jitFlags);
#ifdef LOGGING
LOG((LF_STUBS, LL_INFO1000, "---------------------------------------------------------------------\n"));
@@ -1153,7 +1153,7 @@ public:
LogILStubFlags(LF_STUBS, LL_INFO1000, m_dwStubFlags);
- m_slIL.LogILStub(dwJitFlags);
+ m_slIL.LogILStub(jitFlags);
}
LOG((LF_STUBS, LL_INFO1000, "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"));
#endif // LOGGING
@@ -1170,7 +1170,7 @@ public:
pStubMD,
pbLocalSig,
cbSig,
- dwJitFlags,
+ jitFlags,
&convertToHRTryCatch,
&cleanupTryFinally,
maxStack,
@@ -1188,7 +1188,7 @@ public:
MethodDesc * pStubMD,
PCCOR_SIGNATURE pbLocalSig,
DWORD cbSig,
- DWORD dwJitFlags,
+ CORJIT_FLAGS jitFlags,
ILStubEHClause * pConvertToHRTryCatchBounds,
ILStubEHClause * pCleanupTryFinallyBounds,
DWORD maxStack,
@@ -1256,7 +1256,7 @@ public:
strILStubCode.AppendPrintf(W(".maxstack %d \n"), maxStack);
strILStubCode.AppendPrintf(W(".locals %s\n"), strLocalSig.GetUnicode());
- m_slIL.LogILStub(dwJitFlags, &strILStubCode);
+ m_slIL.LogILStub(jitFlags, &strILStubCode);
if (pConvertToHRTryCatchBounds->cbTryLength != 0 && pConvertToHRTryCatchBounds->cbHandlerLength != 0)
{
@@ -3201,7 +3201,7 @@ void PInvokeStaticSigInfo::DllImportInit(MethodDesc* pMD, LPCUTF8 *ppLibName, LP
// initialize data members to defaults
PreInit(pMD);
- // System.Runtime.InteropServices.DLLImportAttribute
+ // System.Runtime.InteropServices.DllImportAttribute
IMDInternalImport *pInternalImport = pMD->GetMDImport();
CorPinvokeMap mappingFlags = pmMaxValue;
mdModuleRef modref = mdModuleRefNil;
@@ -4940,7 +4940,7 @@ void NDirect::PopulateNDirectMethodDesc(NDirectMethodDesc* pNMD, PInvokeStaticSi
// Currently only ManagedToNativeComInteropStubAttribute is supported.
// It returns NULL if no such attribute(s) can be found.
// But if the attribute is found and is invalid, or something went wrong in the looking up
-// process, a exception will be thrown. If everything goes well, you'll get the MethodDesc
+// process, an exception will be thrown. If everything goes well, you'll get the MethodDesc
// of the stub method
HRESULT FindPredefinedILStubMethod(MethodDesc *pTargetMD, DWORD dwStubFlags, MethodDesc **ppRetStubMD)
{
@@ -5947,8 +5947,8 @@ PCODE JitILStub(MethodDesc* pStubMD)
// A dynamically generated IL stub
//
- DWORD dwFlags = pStubMD->AsDynamicMethodDesc()->GetILStubResolver()->GetJitFlags();
- pCode = pStubMD->MakeJitWorker(NULL, dwFlags, 0);
+ CORJIT_FLAGS jitFlags = pStubMD->AsDynamicMethodDesc()->GetILStubResolver()->GetJitFlags();
+ pCode = pStubMD->MakeJitWorker(NULL, jitFlags);
_ASSERTE(pCode == pStubMD->GetNativeCode());
}
diff --git a/src/vm/dllimportcallback.cpp b/src/vm/dllimportcallback.cpp
index 198a00795f..12613cb96b 100644
--- a/src/vm/dllimportcallback.cpp
+++ b/src/vm/dllimportcallback.cpp
@@ -164,7 +164,7 @@ EXTERN_C void STDCALL UM2MDoADCallBack(UMEntryThunk *pEntryThunk,
UNINSTALL_MANAGED_EXCEPTION_DISPATCHER;
}
-#ifdef _TARGET_X86_
+#if defined(_TARGET_X86_) && !defined(FEATURE_STUBS_AS_IL)
EXTERN_C VOID __cdecl UMThunkStubRareDisable();
EXTERN_C Thread* __stdcall CreateThreadBlockThrow();
@@ -1010,7 +1010,7 @@ Stub *UMThunkMarshInfo::CompileNExportThunk(LoaderHeap *pLoaderHeap, PInvokeStat
return pcpusl->Link(pLoaderHeap);
}
-#else // _TARGET_X86_
+#else // _TARGET_X86_ && !FEATURE_STUBS_AS_IL
PCODE UMThunkMarshInfo::GetExecStubEntryPoint()
{
@@ -1019,7 +1019,7 @@ PCODE UMThunkMarshInfo::GetExecStubEntryPoint()
return GetEEFuncEntryPoint(UMThunkStub);
}
-#endif // _TARGET_X86_
+#endif // _TARGET_X86_ && !FEATURE_STUBS_AS_IL
UMEntryThunkCache::UMEntryThunkCache(AppDomain *pDomain) :
m_crst(CrstUMEntryThunkCache),
@@ -1302,7 +1302,7 @@ UMThunkMarshInfo::~UMThunkMarshInfo()
}
CONTRACTL_END;
-#ifdef _TARGET_X86_
+#if defined(_TARGET_X86_) && !defined(FEATURE_STUBS_AS_IL)
if (m_pExecStub)
m_pExecStub->DecRef();
#endif
@@ -1320,7 +1320,9 @@ MethodDesc* UMThunkMarshInfo::GetILStubMethodDesc(MethodDesc* pInvokeMD, PInvoke
dwStubFlags |= NDIRECTSTUB_FL_REVERSE_INTEROP; // could be either delegate interop or not--that info is passed in from the caller
#if defined(DEBUGGING_SUPPORTED)
- if (GetDebuggerCompileFlags(pSigInfo->GetModule(), 0) & CORJIT_FLG_DEBUG_CODE)
+ // Combining the next two lines, and eliminating jitDebuggerFlags, leads to bad codegen in x86 Release builds using Visual C++ 19.00.24215.1.
+ CORJIT_FLAGS jitDebuggerFlags = GetDebuggerCompileFlags(pSigInfo->GetModule(), CORJIT_FLAGS());
+ if (jitDebuggerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE))
{
dwStubFlags |= NDIRECTSTUB_FL_GENERATEDEBUGGABLEIL;
}
@@ -1362,7 +1364,7 @@ VOID UMThunkMarshInfo::LoadTimeInit(Signature sig, Module * pModule, MethodDesc
m_pModule = pModule;
m_sig = sig;
-#ifdef _TARGET_X86_
+#if defined(_TARGET_X86_) && !defined(FEATURE_STUBS_AS_IL)
INDEBUG(m_cbRetPop = 0xcccc;)
#endif
}
@@ -1370,7 +1372,7 @@ VOID UMThunkMarshInfo::LoadTimeInit(Signature sig, Module * pModule, MethodDesc
#ifndef CROSSGEN_COMPILE
//----------------------------------------------------------
// This initializer finishes the init started by LoadTimeInit.
-// It does stub creation and can throw a exception.
+// It does stub creation and can throw an exception.
//
// It can safely be called multiple times and by concurrent
// threads.
@@ -1394,7 +1396,9 @@ VOID UMThunkMarshInfo::RunTimeInit()
DWORD dwStubFlags = NDIRECTSTUB_FL_NGENEDSTUB | NDIRECTSTUB_FL_REVERSE_INTEROP | NDIRECTSTUB_FL_DELEGATE;
#if defined(DEBUGGING_SUPPORTED)
- if (GetDebuggerCompileFlags(GetModule(), 0) & CORJIT_FLG_DEBUG_CODE)
+ // Combining the next two lines, and eliminating jitDebuggerFlags, leads to bad codegen in x86 Release builds using Visual C++ 19.00.24215.1.
+ CORJIT_FLAGS jitDebuggerFlags = GetDebuggerCompileFlags(GetModule(), CORJIT_FLAGS());
+ if (jitDebuggerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE))
{
dwStubFlags |= NDIRECTSTUB_FL_GENERATEDEBUGGABLEIL;
}
@@ -1403,7 +1407,7 @@ VOID UMThunkMarshInfo::RunTimeInit()
pFinalILStub = GetStubForInteropMethod(pMD, dwStubFlags, &pStubMD);
}
-#ifdef _TARGET_X86_
+#if defined(_TARGET_X86_) && !defined(FEATURE_STUBS_AS_IL)
PInvokeStaticSigInfo sigInfo;
if (pMD != NULL)
@@ -1454,7 +1458,7 @@ VOID UMThunkMarshInfo::RunTimeInit()
pFinalExecStub->DecRef();
}
-#else // _TARGET_X86_
+#else // _TARGET_X86_ && !FEATURE_STUBS_AS_IL
if (pFinalILStub == NULL)
{
@@ -1495,7 +1499,7 @@ VOID UMThunkMarshInfo::RunTimeInit()
//
m_cbActualArgSize = (pStubMD != NULL) ? pStubMD->AsDynamicMethodDesc()->GetNativeStackArgSize() : pMD->SizeOfArgStack();
-#endif // _TARGET_X86_
+#endif // _TARGET_X86_ && !FEATURE_STUBS_AS_IL
// Must be the last thing we set!
InterlockedCompareExchangeT<PCODE>(&m_pILStub, pFinalILStub, (PCODE)1);
diff --git a/src/vm/dllimportcallback.h b/src/vm/dllimportcallback.h
index 6de87d77a3..c2ed6d0039 100644
--- a/src/vm/dllimportcallback.h
+++ b/src/vm/dllimportcallback.h
@@ -110,7 +110,7 @@ public:
return m_pMD;
}
-#ifdef _TARGET_X86_
+#if defined(_TARGET_X86_) && !defined(FEATURE_STUBS_AS_IL)
PCODE GetExecStubEntryPoint()
{
WRAPPER_NO_CONTRACT;
@@ -199,18 +199,18 @@ public:
return (UINT32)offsetof(UMThunkMarshInfo, m_pILStub);
}
-#ifdef _TARGET_X86_
+#if defined(_TARGET_X86_) && !defined(FEATURE_STUBS_AS_IL)
// Compiles an unmanaged to managed thunk for the given signature. The thunk
// will call the stub or, if fNoStub == TRUE, directly the managed target.
Stub *CompileNExportThunk(LoaderHeap *pLoaderHeap, PInvokeStaticSigInfo* pSigInfo, MetaSig *pMetaSig, BOOL fNoStub);
-#endif // _TARGET_X86_
+#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()
-#ifdef _TARGET_X86_
+#if defined(_TARGET_X86_) && !defined(FEATURE_STUBS_AS_IL)
Stub* m_pExecStub; // UMEntryThunk jumps directly here
UINT16 m_cbRetPop; // stack bytes popped by callee (for UpdateRegDisplay)
UINT16 m_callConv; // unmanaged calling convention and flags (CorPinvokeMap)
@@ -248,7 +248,7 @@ public:
static UMEntryThunk* CreateUMEntryThunk();
static VOID FreeUMEntryThunk(UMEntryThunk* p);
-#ifdef _TARGET_X86_
+#if defined(_TARGET_X86_) && !defined(FEATURE_STUBS_AS_IL)
// Compiles an unmanaged to managed thunk with the given calling convention adaptation.
// - psrcofsregs are stack offsets that should be loaded to argument registers (ECX, EDX)
// - psrcofs are stack offsets that should be repushed for the managed target
@@ -263,7 +263,7 @@ public:
UINT *psrcofsregs,
UINT *psrcofs,
UINT retbufofs);
-#endif // _TARGET_X86_
+#endif // _TARGET_X86_ && !FEATURE_STUBS_AS_IL
#ifndef DACCESS_COMPILE
VOID LoadTimeInit(PCODE pManagedTarget,
@@ -569,12 +569,12 @@ private:
AppDomain *m_pDomain;
};
-#ifdef _TARGET_X86_
+#if defined(_TARGET_X86_) && !defined(FEATURE_STUBS_AS_IL)
//-------------------------------------------------------------------------
// One-time creation of special prestub to initialize UMEntryThunks.
//-------------------------------------------------------------------------
Stub *GenerateUMThunkPrestub();
-#endif
+#endif // _TARGET_X86_ && !FEATURE_STUBS_AS_IL
//-------------------------------------------------------------------------
// NExport stub
diff --git a/src/vm/domainfile.cpp b/src/vm/domainfile.cpp
index 2353712c9e..bfb69cdd48 100644
--- a/src/vm/domainfile.cpp
+++ b/src/vm/domainfile.cpp
@@ -4140,8 +4140,8 @@ void DomainAssembly::EnumStaticGCRefs(promote_func* fn, ScanContext* sc)
}
CONTRACT_END;
- _ASSERTE(GCHeap::IsGCInProgress() &&
- GCHeap::IsServerHeap() &&
+ _ASSERTE(GCHeapUtilities::IsGCInProgress() &&
+ GCHeapUtilities::IsServerHeap() &&
IsGCSpecialThread());
DomainModuleIterator i = IterateModules(kModIterIncludeLoaded);
diff --git a/src/vm/dwreport.cpp b/src/vm/dwreport.cpp
index 77669b2f14..5ae4f84de2 100644
--- a/src/vm/dwreport.cpp
+++ b/src/vm/dwreport.cpp
@@ -3212,7 +3212,7 @@ FaultReportResult DoFaultReport( // Was Watson attempted, successful?
// thread under Coop mode, this will let the new generated DoFaultReportCallBack
// thread trigger a deadlock. So in this case, we should directly abort the fault
// report to avoid the deadlock.
- ((IsGCThread() || pThread->PreemptiveGCDisabled()) && GCHeap::IsGCInProgress()) ||
+ ((IsGCThread() || pThread->PreemptiveGCDisabled()) && GCHeapUtilities::IsGCInProgress()) ||
FAILED(g_pDebugInterface->RequestFavor(DoFaultReportFavorWorker, pData)))
{
// If we can't initialize the debugger helper thread or we are running on the debugger helper
diff --git a/src/vm/ecalllist.h b/src/vm/ecalllist.h
index 8d4164e018..b110d0eea6 100644
--- a/src/vm/ecalllist.h
+++ b/src/vm/ecalllist.h
@@ -108,6 +108,8 @@ FCFuncStart(gDependentHandleFuncs)
FCFuncElement("nGetPrimary", DependentHandle::nGetPrimary)
FCFuncElement("nGetPrimaryAndSecondary", DependentHandle::nGetPrimaryAndSecondary)
FCFuncElement("nFree", DependentHandle::nFree)
+ FCFuncElement("nSetPrimary", DependentHandle::nSetPrimary)
+ FCFuncElement("nSetSecondary", DependentHandle::nSetSecondary)
FCFuncEnd()
#ifndef FEATURE_CORECLR
@@ -195,15 +197,6 @@ FCFuncStart(gTimeSpanFuncs)
FCFuncEnd()
#endif // !FEATURE_CORECLR
-#ifndef FEATURE_CORECLR // FCalls used by System.TimeZone
-FCFuncStart(gTimeZoneFuncs)
- FCFuncElement("nativeGetTimeZoneMinuteOffset", COMNlsInfo::nativeGetTimeZoneMinuteOffset)
- FCFuncElement("nativeGetStandardName", COMNlsInfo::nativeGetStandardName)
- FCFuncElement("nativeGetDaylightName", COMNlsInfo::nativeGetDaylightName)
- FCFuncElement("nativeGetDaylightChanges", COMNlsInfo::nativeGetDaylightChanges)
-FCFuncEnd()
-#endif // FEATURE_CORECLR
-
FCFuncStart(gObjectFuncs)
FCIntrinsic("GetType", ObjectNative::GetClass, CORINFO_INTRINSIC_Object_GetType)
FCFuncElement("MemberwiseClone", ObjectNative::Clone)
@@ -297,6 +290,7 @@ FCFuncStart(gEnvironmentFuncs)
FCFuncElement("GetResourceFromDefault", GetResourceFromDefault)
#endif // !FEATURE_CORECLR
FCFuncElement("GetCommandLineArgsNative", SystemNative::GetCommandLineArgs)
+ FCFuncElement("get_CurrentProcessorNumber", SystemNative::GetCurrentProcessorNumber)
#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORESYSTEM)
QCFuncElement("WinRTSupported", SystemNative::WinRTSupported)
@@ -650,9 +644,11 @@ FCFuncStart(gCustomAttributeEncodedArgument)
FCFuncElement("ParseAttributeArguments", Attribute::ParseAttributeArguments)
FCFuncEnd()
+#ifdef FEATURE_CAS_POLICY
FCFuncStart(gPseudoCustomAttribute)
FCFuncElement("_GetSecurityAttributes", COMCustomAttribute::GetSecurityAttributes)
FCFuncEnd()
+#endif
FCFuncStart(gCOMCustomAttributeFuncs)
FCFuncElement("_ParseAttributeUsageAttribute", COMCustomAttribute::ParseAttributeUsageAttribute)
@@ -1041,7 +1037,7 @@ FCFuncStart(gTypeNameBuilder)
QCFuncElement("Clear", TypeNameBuilder::_Clear)
FCFuncEnd()
-#ifndef FEATURE_CORECLR
+
FCFuncStart(gSafeTypeNameParserHandle)
QCFuncElement("_ReleaseTypeNameParser", TypeName::QReleaseTypeNameParser)
FCFuncEnd()
@@ -1053,7 +1049,6 @@ FCFuncStart(gTypeNameParser)
QCFuncElement("_GetModifiers", TypeName::QGetModifiers)
QCFuncElement("_GetAssemblyName", TypeName::QGetAssemblyName)
FCFuncEnd()
-#endif //!FEATURE_CORECLR
#ifdef FEATURE_CAS_POLICY
FCFuncStart(gPEFileFuncs)
@@ -1146,6 +1141,7 @@ FCFuncEnd()
FCFuncStart(gAssemblyLoadContextFuncs)
QCFuncElement("InitializeAssemblyLoadContext", AssemblyNative::InitializeAssemblyLoadContext)
QCFuncElement("LoadFromPath", AssemblyNative::LoadFromPath)
+ QCFuncElement("GetLoadedAssembliesInternal", AssemblyNative::GetLoadedAssembliesInternal)
QCFuncElement("InternalLoadUnmanagedDllFromPath", AssemblyNative::InternalLoadUnmanagedDllFromPath)
QCFuncElement("OverrideDefaultAssemblyLoadContextForCurrentDomain", AssemblyNative::OverrideDefaultAssemblyLoadContextForCurrentDomain)
QCFuncElement("CanUseAppPathAssemblyLoadContextInCurrentDomain", AssemblyNative::CanUseAppPathAssemblyLoadContextInCurrentDomain)
@@ -1165,9 +1161,9 @@ FCFuncStart(gAssemblyNameFuncs)
FCFuncElement("nGetPublicKeyToken", AssemblyNameNative::GetPublicKeyToken)
#ifndef FEATURE_CORECLR
FCFuncElement("EscapeCodeBase", AssemblyNameNative::EscapeCodeBase)
+#endif // !FEATURE_CORECLR
FCFuncElement("ReferenceMatchesDefinitionInternal", AssemblyNameNative::ReferenceMatchesDefinition)
FCFuncElement("nGetFileInformation", AssemblyNameNative::GetFileInformation)
-#endif // !FEATURE_CORECLR
FCFuncEnd()
FCFuncStart(gLoaderAllocatorFuncs)
@@ -1251,32 +1247,63 @@ FCFuncStart(gMathFuncs)
FCIntrinsic("Tanh", COMDouble::Tanh, CORINFO_INTRINSIC_Tanh)
FCFuncEnd()
+FCFuncStart(gMathFFuncs)
+ FCIntrinsic("Acos", COMSingle::Acos, CORINFO_INTRINSIC_Acos)
+ FCIntrinsic("Asin", COMSingle::Asin, CORINFO_INTRINSIC_Asin)
+ FCIntrinsic("Atan", COMSingle::Atan, CORINFO_INTRINSIC_Atan)
+ FCIntrinsic("Atan2", COMSingle::Atan2, CORINFO_INTRINSIC_Atan2)
+ FCIntrinsic("Ceiling", COMSingle::Ceil, CORINFO_INTRINSIC_Ceiling)
+ FCIntrinsic("Cos", COMSingle::Cos, CORINFO_INTRINSIC_Cos)
+ FCIntrinsic("Cosh", COMSingle::Cosh, CORINFO_INTRINSIC_Cosh)
+ FCIntrinsic("Exp", COMSingle::Exp, CORINFO_INTRINSIC_Exp)
+ FCIntrinsic("Floor", COMSingle::Floor, CORINFO_INTRINSIC_Floor)
+ FCFuncElement("Log", COMSingle::Log)
+ FCIntrinsic("Log10", COMSingle::Log10, CORINFO_INTRINSIC_Log10)
+ FCIntrinsic("Pow", COMSingle::Pow, CORINFO_INTRINSIC_Pow)
+ FCIntrinsic("Round", COMSingle::Round, CORINFO_INTRINSIC_Round)
+ FCIntrinsic("Sin", COMSingle::Sin, CORINFO_INTRINSIC_Sin)
+ FCIntrinsic("Sinh", COMSingle::Sinh, CORINFO_INTRINSIC_Sinh)
+ FCFuncElement("SplitFractionSingle", COMSingle::ModF)
+ FCIntrinsic("Sqrt", COMSingle::Sqrt, CORINFO_INTRINSIC_Sqrt)
+ FCIntrinsic("Tan", COMSingle::Tan, CORINFO_INTRINSIC_Tan)
+ FCIntrinsic("Tanh", COMSingle::Tanh, CORINFO_INTRINSIC_Tanh)
+FCFuncEnd()
+
+FCFuncStart(gRuntimeThreadFuncs)
+ FCFuncElement("get_IsAlive", ThreadNative::IsAlive)
+ FCFuncElement("IsBackgroundNative", ThreadNative::IsBackground)
+ FCFuncElement("SetBackgroundNative", ThreadNative::SetBackground)
+ FCFuncElement("get_IsThreadPoolThread", ThreadNative::IsThreadpoolThread)
+ FCFuncElement("GetPriorityNative", ThreadNative::GetPriority)
+ FCFuncElement("SetPriorityNative", ThreadNative::SetPriority)
+ FCFuncElement("GetThreadStateNative", ThreadNative::GetThreadState)
+#ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT
+ FCFuncElement("GetApartmentStateNative", ThreadNative::GetApartmentState)
+ FCFuncElement("SetApartmentStateNative", ThreadNative::SetApartmentState)
+#endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT
+#ifdef FEATURE_COMINTEROP
+ FCFuncElement("DisableComObjectEagerCleanup", ThreadNative::DisableComObjectEagerCleanup)
+#endif // FEATURE_COMINTEROP
+ FCFuncElement("InterruptInternal", ThreadNative::Interrupt)
+ FCFuncElement("JoinInternal", ThreadNative::Join)
+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)
- FCFuncElement("InterruptInternal", ThreadNative::Interrupt)
-#endif
- FCFuncElement("get_IsAlive", ThreadNative::IsAlive)
- FCFuncElement("GetThreadStateNative", ThreadNative::GetThreadState)
-#ifndef FEATURE_CORECLR
- FCFuncElement("GetPriorityNative", ThreadNative::GetPriority)
- FCFuncElement("SetPriorityNative", ThreadNative::SetPriority)
#endif
#ifdef FEATURE_LEAK_CULTURE_INFO
FCFuncElement("nativeGetSafeCulture", ThreadNative::nativeGetSafeCulture)
#else
QCFuncElement("nativeInitCultureAccessors", ThreadNative::nativeInitCultureAccessors)
#endif
- FCFuncElement("JoinInternal", ThreadNative::Join)
#undef Sleep
FCFuncElement("SleepInternal", ThreadNative::Sleep)
#define Sleep(a) Dont_Use_Sleep(a)
FCFuncElement("SetStart", ThreadNative::SetStart)
- FCFuncElement("SetBackgroundNative", ThreadNative::SetBackground)
- FCFuncElement("IsBackgroundNative", ThreadNative::IsBackground)
#ifdef FEATURE_REMOTING
FCFuncElement("GetContextInternal", ThreadNative::GetContextFromContextID)
#endif
@@ -1303,23 +1330,15 @@ FCFuncStart(gThreadFuncs)
#ifndef FEATURE_CORECLR
FCFuncElement("ResetAbortNative", ThreadNative::ResetAbort)
#endif // FEATURE_CORECLR
- FCFuncElement("get_IsThreadPoolThread", ThreadNative::IsThreadpoolThread)
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)
-#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORECLR)
- FCFuncElement("DisableComObjectEagerCleanup", ThreadNative::DisableComObjectEagerCleanup)
-#endif // defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORECLR)
#ifdef FEATURE_LEAK_CULTURE_INFO
FCFuncElement("nativeSetThreadUILocale", ThreadNative::SetThreadUILocale)
#endif
#ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT
-#ifndef FEATURE_CORECLR
- FCFuncElement("SetApartmentStateNative", ThreadNative::SetApartmentState)
- FCFuncElement("GetApartmentStateNative", ThreadNative::GetApartmentState)
-#endif // FEATURE_CORECLR
FCFuncElement("StartupSetApartmentStateInternal", ThreadNative::StartupSetApartmentState)
#endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT
FCIntrinsic("MemoryBarrier", ThreadNative::FCMemoryBarrier, CORINFO_INTRINSIC_MemoryBarrier)
@@ -1331,10 +1350,8 @@ FCFuncStart(gThreadFuncs)
FCFuncEnd()
FCFuncStart(gThreadPoolFuncs)
-#ifndef FEATURE_CORECLR
FCFuncElement("PostQueuedCompletionStatus", ThreadPoolNative::CorPostQueuedCompletionStatus)
FCFuncElement("GetAvailableThreadsNative", ThreadPoolNative::CorGetAvailableThreads)
-#endif // FEATURE_CORECLR
FCFuncElement("SetMinThreadsNative", ThreadPoolNative::CorSetMinThreads)
FCFuncElement("GetMinThreadsNative", ThreadPoolNative::CorGetMinThreads)
FCFuncElement("RegisterWaitForSingleObjectNative", ThreadPoolNative::CorRegisterWaitForSingleObject)
@@ -1444,8 +1461,8 @@ FCFuncStart(gCompareInfoFuncs)
QCFuncElement("InternalGetSortKey", COMNlsInfo::InternalGetSortKey)
#ifndef FEATURE_CORECLR
QCFuncElement("InternalGetSortVersion", COMNlsInfo::InternalGetSortVersion)
- QCFuncElement("InternalGetNlsVersionEx", COMNlsInfo::InternalGetNlsVersionEx)
#endif
+ QCFuncElement("InternalGetNlsVersionEx", COMNlsInfo::InternalGetNlsVersionEx)
FCFuncEnd()
FCFuncStart(gEncodingTableFuncs)
@@ -1567,11 +1584,9 @@ FCFuncStart(gGCInterfaceFuncs)
FCFuncElement("_GetAllocatedBytesForCurrentThread", GCInterface::GetAllocatedBytesForCurrentThread)
FCFuncEnd()
-#ifndef FEATURE_CORECLR
FCFuncStart(gMemoryFailPointFuncs)
FCFuncElement("GetMemorySettings", COMMemoryFailPoint::GetMemorySettings)
FCFuncEnd()
-#endif // FEATURE_CORECLR
FCFuncStart(gInteropMarshalFuncs)
FCFuncElement("GetLastWin32Error", MarshalNative::GetLastWin32Error)
@@ -1582,10 +1597,10 @@ FCFuncStart(gInteropMarshalFuncs)
FCFuncElement("DestroyStructure", MarshalNative::DestroyStructure)
FCFuncElement("UnsafeAddrOfPinnedArrayElement", MarshalNative::FCUnsafeAddrOfPinnedArrayElement)
FCFuncElement("GetExceptionCode", ExceptionNative::GetExceptionCode)
+ QCFuncElement("GetHINSTANCE", COMModule::GetHINSTANCE)
#ifndef FEATURE_CORECLR
QCFuncElement("InternalNumParamBytes", MarshalNative::NumParamBytes)
FCFuncElement("GetExceptionPointers", ExceptionNative::GetExceptionPointers)
- QCFuncElement("GetHINSTANCE", COMModule::GetHINSTANCE)
FCFuncElement("GetUnmanagedThunkForManagedMethodPtr", MarshalNative::GetUnmanagedThunkForManagedMethodPtr)
FCFuncElement("GetManagedThunkForUnmanagedMethodPtr", MarshalNative::GetManagedThunkForUnmanagedMethodPtr)
FCFuncElement("InternalGetThreadFromFiberCookie", MarshalNative::GetThreadFromFiberCookie)
@@ -1630,11 +1645,12 @@ FCFuncStart(gInteropMarshalFuncs)
FCFuncElement("InternalReleaseComObject", MarshalNative::ReleaseComObject)
FCFuncElement("Release", MarshalNative::Release)
FCFuncElement("InitializeWrapperForWinRT", MarshalNative::InitializeWrapperForWinRT)
+ FCFuncElement("GetTypedObjectForIUnknown", MarshalNative::GetTypedObjectForIUnknown)
+ FCFuncElement("ChangeWrapperHandleStrength", MarshalNative::ChangeWrapperHandleStrength)
+ FCFuncElement("CleanupUnusedObjectsInCurrentContext", MarshalNative::CleanupUnusedObjectsInCurrentContext)
#ifndef FEATURE_CORECLR
FCFuncElement("GetLoadedTypeForGUID", MarshalNative::GetLoadedTypeForGUID)
FCFuncElement("GetITypeInfoForType", MarshalNative::GetITypeInfoForType)
- FCFuncElement("GetTypedObjectForIUnknown", MarshalNative::GetTypedObjectForIUnknown)
- FCFuncElement("CleanupUnusedObjectsInCurrentContext", MarshalNative::CleanupUnusedObjectsInCurrentContext)
FCFuncElement("IsTypeVisibleFromCom", MarshalNative::IsTypeVisibleFromCom)
FCFuncElement("FCallGenerateGuidForType", MarshalNative::DoGenerateGuidForType)
FCFuncElement("FCallGetTypeLibGuid", MarshalNative::DoGetTypeLibGuid)
@@ -1648,7 +1664,6 @@ FCFuncStart(gInteropMarshalFuncs)
FCFuncElement("InternalGetComSlotForMethodInfo", MarshalNative::GetComSlotForMethodInfo)
FCFuncElement("InternalSwitchCCW", MarshalNative::SwitchCCW)
FCFuncElement("InternalWrapIUnknownWithComObject", MarshalNative::WrapIUnknownWithComObject)
- FCFuncElement("ChangeWrapperHandleStrength", MarshalNative::ChangeWrapperHandleStrength)
QCFuncElement("_GetInspectableIids", MarshalNative::GetInspectableIIDs)
QCFuncElement("_GetCachedWinRTTypes", MarshalNative::GetCachedWinRTTypes)
QCFuncElement("_GetCachedWinRTTypeByIid", MarshalNative::GetCachedWinRTTypeByIID)
@@ -1829,8 +1844,8 @@ FCFuncStart(gCompilerFuncs)
FCFuncElement("GetObjectValue", ObjectNative::GetObjectValue)
FCIntrinsic("InitializeArray", ArrayNative::InitializeArray, CORINFO_INTRINSIC_InitializeArray)
FCFuncElement("_RunClassConstructor", ReflectionInvocation::RunClassConstructor)
-#ifndef FEATURE_CORECLR
FCFuncElement("_RunModuleConstructor", ReflectionInvocation::RunModuleConstructor)
+#ifndef FEATURE_CORECLR
FCFuncElement("_PrepareMethod", ReflectionInvocation::PrepareMethod)
#endif // !FEATURE_CORECLR
QCFuncElement("_CompileMethod", ReflectionInvocation::CompileMethod)
@@ -1843,14 +1858,12 @@ FCFuncStart(gCompilerFuncs)
FCFuncElement("GetHashCode", ObjectNative::GetHashCode)
FCFuncElement("Equals", ObjectNative::Equals)
FCFuncElement("EnsureSufficientExecutionStack", ReflectionInvocation::EnsureSufficientExecutionStack)
-#ifdef FEATURE_CORECLR
FCFuncElement("TryEnsureSufficientExecutionStack", ReflectionInvocation::TryEnsureSufficientExecutionStack)
-#endif // FEATURE_CORECLR
FCFuncEnd()
FCFuncStart(gContextSynchronizationFuncs)
#ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
- FCFuncElement("WaitHelper", SynchronizationContextNative::WaitHelper)
+ FCFuncElement("WaitHelperNative", SynchronizationContextNative::WaitHelper)
#endif // #ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
#ifdef FEATURE_APPX
QCFuncElement("GetWinRTDispatcherForCurrentThread", SynchronizationContextNative::GetWinRTDispatcherForCurrentThread)
@@ -2191,9 +2204,6 @@ FCClassElement("CultureData", "System.Globalization", gCultureDataFuncs)
FCClassElement("CultureInfo", "System.Globalization", gCultureInfoFuncs)
#endif
FCClassElement("Currency", "System", gCurrencyFuncs)
-#ifndef FEATURE_CORECLR
-FCClassElement("CurrentSystemTimeZone", "System", gTimeZoneFuncs)
-#endif // FEATURE_CORECLR
FCClassElement("CustomAttribute", "System.Reflection", gCOMCustomAttributeFuncs)
FCClassElement("CustomAttributeEncodedArgument", "System.Reflection", gCustomAttributeEncodedArgument)
FCClassElement("DateMarshaler", "System.StubHelpers", gDateMarshalerFuncs)
@@ -2255,12 +2265,11 @@ FCClassElement("Marshal", "System.Runtime.InteropServices", gInteropMarshalFuncs
FCClassElement("MarshalByRefObject", "System", gMarshalByRefFuncs)
#endif
FCClassElement("Math", "System", gMathFuncs)
+FCClassElement("MathF", "System", gMathFFuncs)
#ifdef MDA_SUPPORTED
FCClassElement("Mda", "System", gMda)
#endif
-#ifndef FEATURE_CORECLR
FCClassElement("MemoryFailPoint", "System.Runtime", gMemoryFailPointFuncs)
-#endif // FEATURE_CORECLR
#ifdef FEATURE_REMOTING
FCClassElement("Message", "System.Runtime.Remoting.Messaging", gMessageFuncs)
#endif
@@ -2307,7 +2316,9 @@ FCClassElement("PolicyManager", "System.Security", gPolicyManagerFuncs)
FCClassElement("ProfileOptimization", "System.Runtime", gProfileOptimizationFuncs)
#endif // defined(FEATURE_MULTICOREJIT) && !defined(FEATURE_CORECLR)
+#ifdef FEATURE_CAS_POLICY
FCClassElement("PseudoCustomAttribute", "System.Reflection", gPseudoCustomAttribute)
+#endif
#ifdef FEATURE_CORECLR
FCClassElement("PunkSafeHandle", "System.Reflection.Emit", gSymWrapperCodePunkSafeHandleFuncs)
#endif
@@ -2346,6 +2357,7 @@ FCClassElement("RuntimeFieldHandle", "System", gCOMFieldHandleNewFuncs)
FCClassElement("RuntimeHelpers", "System.Runtime.CompilerServices", gCompilerFuncs)
FCClassElement("RuntimeMethodHandle", "System", gRuntimeMethodHandle)
FCClassElement("RuntimeModule", "System.Reflection", gCOMModuleFuncs)
+FCClassElement("RuntimeThread", "Internal.Runtime.Augments", gRuntimeThreadFuncs)
FCClassElement("RuntimeType", "System", gSystem_RuntimeType)
FCClassElement("RuntimeTypeHandle", "System", gCOMTypeHandleFuncs)
FCClassElement("SafeBuffer", "System.Runtime.InteropServices", gSafeBufferFuncs)
@@ -2371,9 +2383,8 @@ FCClassElement("SafePEFileHandle", "Microsoft.Win32.SafeHandles", gPEFileFuncs)
#ifdef FEATURE_CRYPTO
FCClassElement("SafeProvHandle", "System.Security.Cryptography", gSafeProvHandleFuncs)
#endif
-#ifndef FEATURE_CORECLR
FCClassElement("SafeTypeNameParserHandle", "System", gSafeTypeNameParserHandle)
-#endif //!FEATURE_CORECLR
+
#if defined(FEATURE_IMPERSONATION) || defined(FEATURE_COMPRESSEDSTACK)
FCClassElement("SecurityContext", "System.Security", gCOMSecurityContextFuncs)
#endif // defined(FEATURE_IMPERSONATION) || defined(FEATURE_COMPRESSEDSTACK)
@@ -2414,9 +2425,7 @@ FCClassElement("TypeLibConverter", "System.Runtime.InteropServices", gTypeLibCon
#endif
FCClassElement("TypeLoadException", "System", gTypeLoadExceptionFuncs)
FCClassElement("TypeNameBuilder", "System.Reflection.Emit", gTypeNameBuilder)
-#ifndef FEATURE_CORECLR
FCClassElement("TypeNameParser", "System", gTypeNameParser)
-#endif //!FEATURE_CORECLR
FCClassElement("TypedReference", "System", gTypedReferenceFuncs)
FCClassElement("URLString", "System.Security.Util", gCOMUrlStringFuncs)
#ifdef FEATURE_COMINTEROP
diff --git a/src/vm/eedbginterfaceimpl.cpp b/src/vm/eedbginterfaceimpl.cpp
index 93decc9b0d..ff63d846e7 100644
--- a/src/vm/eedbginterfaceimpl.cpp
+++ b/src/vm/eedbginterfaceimpl.cpp
@@ -501,9 +501,9 @@ BOOL EEDbgInterfaceImpl::IsInPrologOrEpilog(const BYTE *address,
if (codeInfo.IsValid())
{
- LPVOID methodInfo = codeInfo.GetGCInfo();
+ GCInfoToken gcInfoToken = codeInfo.GetGCInfoToken();
- if (codeInfo.GetCodeManager()->IsInPrologOrEpilog(codeInfo.GetRelOffset(), methodInfo, prologSize))
+ if (codeInfo.GetCodeManager()->IsInPrologOrEpilog(codeInfo.GetRelOffset(), gcInfoToken, prologSize))
{
return TRUE;
}
diff --git a/src/vm/eepolicy.cpp b/src/vm/eepolicy.cpp
index 8c3f2ec625..236f5afd6e 100644
--- a/src/vm/eepolicy.cpp
+++ b/src/vm/eepolicy.cpp
@@ -1368,7 +1368,7 @@ void DisplayStackOverflowException()
LIMITED_METHOD_CONTRACT;
PrintToStdErrA("\n");
- PrintToStdErrA("Process is terminated due to StackOverflowException.\n");
+ PrintToStdErrA("Process is terminating due to StackOverflowException.\n");
}
void DECLSPEC_NORETURN EEPolicy::HandleFatalStackOverflow(EXCEPTION_POINTERS *pExceptionInfo, BOOL fSkipDebugger)
diff --git a/src/vm/eetoprofinterfaceimpl.cpp b/src/vm/eetoprofinterfaceimpl.cpp
index 2ec3812159..1ceed3d81b 100644
--- a/src/vm/eetoprofinterfaceimpl.cpp
+++ b/src/vm/eetoprofinterfaceimpl.cpp
@@ -414,6 +414,7 @@ EEToProfInterfaceImpl::EEToProfInterfaceImpl() :
m_pCallback5(NULL),
m_pCallback6(NULL),
m_pCallback7(NULL),
+ m_pCallback8(NULL),
m_hmodProfilerDLL(NULL),
m_fLoadedViaAttach(FALSE),
m_pProfToEE(NULL),
@@ -664,21 +665,25 @@ HRESULT EEToProfInterfaceImpl::CreateProfiler(
m_hmodProfilerDLL = hmodProfilerDLL.Extract();
hmodProfilerDLL = NULL;
- // The profiler may optionally support ICorProfilerCallback3,4,5,6,7. Let's check.
+ // The profiler may optionally support ICorProfilerCallback3,4,5,6,7,8. Let's check.
- ReleaseHolder<ICorProfilerCallback7> pCallback7;
+ ReleaseHolder<ICorProfilerCallback8> pCallback8;
hr = m_pCallback2->QueryInterface(
- IID_ICorProfilerCallback7,
- (LPVOID *)&pCallback7);
- if (SUCCEEDED(hr) && (pCallback7 != NULL))
+ IID_ICorProfilerCallback8,
+ (LPVOID *)&pCallback8);
+ if (SUCCEEDED(hr) && (pCallback8 != NULL))
{
// Nifty. Transfer ownership to this class
- _ASSERTE(m_pCallback7 == NULL);
- m_pCallback7 = pCallback7.Extract();
- pCallback7 = NULL;
+ _ASSERTE(m_pCallback8 == NULL);
+ m_pCallback8 = pCallback8.Extract();
+ pCallback8 = NULL;
- // And while we're at it, we must now also have an ICorProfilerCallback3,4,5,6
+ // And while we're at it, we must now also have an ICorProfilerCallback3,4,5,6,7
// due to inheritance relationship of the interfaces
+ _ASSERTE(m_pCallback7 == NULL);
+ m_pCallback7 = static_cast<ICorProfilerCallback7 *>(m_pCallback8);
+ m_pCallback7->AddRef();
+
_ASSERTE(m_pCallback6 == NULL);
m_pCallback6 = static_cast<ICorProfilerCallback6 *>(m_pCallback7);
m_pCallback6->AddRef();
@@ -696,6 +701,40 @@ HRESULT EEToProfInterfaceImpl::CreateProfiler(
m_pCallback3->AddRef();
}
+ if (m_pCallback7 == NULL)
+ {
+ ReleaseHolder<ICorProfilerCallback7> pCallback7;
+ hr = m_pCallback2->QueryInterface(
+ IID_ICorProfilerCallback7,
+ (LPVOID *)&pCallback7);
+ if (SUCCEEDED(hr) && (pCallback7 != NULL))
+ {
+ // Nifty. Transfer ownership to this class
+ _ASSERTE(m_pCallback7 == NULL);
+ m_pCallback7 = pCallback7.Extract();
+ pCallback7 = NULL;
+
+ // And while we're at it, we must now also have an ICorProfilerCallback3,4,5,6
+ // due to inheritance relationship of the interfaces
+
+ _ASSERTE(m_pCallback6 == NULL);
+ m_pCallback6 = static_cast<ICorProfilerCallback6 *>(m_pCallback7);
+ m_pCallback6->AddRef();
+
+ _ASSERTE(m_pCallback5 == NULL);
+ m_pCallback5 = static_cast<ICorProfilerCallback5 *>(m_pCallback6);
+ m_pCallback5->AddRef();
+
+ _ASSERTE(m_pCallback4 == NULL);
+ m_pCallback4 = static_cast<ICorProfilerCallback4 *>(m_pCallback5);
+ m_pCallback4->AddRef();
+
+ _ASSERTE(m_pCallback3 == NULL);
+ m_pCallback3 = static_cast<ICorProfilerCallback3 *>(m_pCallback4);
+ m_pCallback3->AddRef();
+ }
+ }
+
if (m_pCallback6 == NULL)
{
ReleaseHolder<ICorProfilerCallback6> pCallback6;
@@ -873,6 +912,13 @@ EEToProfInterfaceImpl::~EEToProfInterfaceImpl()
m_pCallback7 = NULL;
}
+ if (m_pCallback8 != NULL)
+ {
+ REMOVE_STACK_GUARD_FOR_PROFILER_CALL;
+ m_pCallback8->Release();
+ m_pCallback8 = NULL;
+ }
+
// Only unload the V4 profiler if this is not part of shutdown. This protects
// Whidbey profilers that aren't used to being FreeLibrary'd.
if (fIsV4Profiler && !g_fEEShutDown)
@@ -2294,7 +2340,7 @@ HRESULT EEToProfInterfaceImpl::SetEventMask(DWORD dwEventMask, DWORD dwEventMask
// in this function
if (g_profControlBlock.curProfStatus.Get() == kProfStatusInitializingForAttachLoad)
{
- if (GCHeap::GetGCHeap()->IsConcurrentGCEnabled())
+ if (GCHeapUtilities::GetGCHeap()->IsConcurrentGCEnabled())
{
// We only allow turning off concurrent GC in the profiler attach thread inside
// InitializeForAttach, otherwise we would be vulnerable to weird races such as
@@ -2316,7 +2362,7 @@ HRESULT EEToProfInterfaceImpl::SetEventMask(DWORD dwEventMask, DWORD dwEventMask
// Fail if concurrent GC is enabled
// This should only happen for attach profilers if user didn't turn on COR_PRF_MONITOR_GC
// at attach time
- if (GCHeap::GetGCHeap()->IsConcurrentGCEnabled())
+ if (GCHeapUtilities::GetGCHeap()->IsConcurrentGCEnabled())
{
return CORPROF_E_CONCURRENT_GC_NOT_PROFILABLE;
}
@@ -2384,7 +2430,7 @@ HRESULT EEToProfInterfaceImpl::SetEventMask(DWORD dwEventMask, DWORD dwEventMask
if (fNeedToTurnOffConcurrentGC)
{
// Turn off concurrent GC if it is on so that user can walk the heap safely in GC callbacks
- GCHeap * pGCHeap = GCHeap::GetGCHeap();
+ IGCHeap * pGCHeap = GCHeapUtilities::GetGCHeap();
LOG((LF_CORPROF, LL_INFO10, "**PROF: Turning off concurrent GC at attach.\n"));
@@ -3184,6 +3230,86 @@ HRESULT EEToProfInterfaceImpl::JITCompilationStarted(FunctionID functionId,
}
}
+HRESULT EEToProfInterfaceImpl::DynamicMethodJITCompilationFinished(FunctionID functionId,
+ HRESULT hrStatus,
+ BOOL fIsSafeToBlock)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_TRIGGERS;
+ MODE_PREEMPTIVE;
+ CAN_TAKE_LOCK;
+
+ // The JIT / MethodDesc code likely hold locks while this callback is made
+
+ SO_NOT_MAINLINE;
+ }
+ CONTRACTL_END;
+
+ CLR_TO_PROFILER_ENTRYPOINT((LF_CORPROF,
+ LL_INFO1000,
+ "**PROF: DynamicMethodJITCompilationFinished 0x%p.\n",
+ functionId));
+
+ _ASSERTE(functionId);
+
+ if (m_pCallback8 == NULL)
+ {
+ return S_OK;
+ }
+
+ {
+ // 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);
+ return m_pCallback8->DynamicMethodJITCompilationFinished(functionId, hrStatus, fIsSafeToBlock);
+ }
+}
+
+HRESULT EEToProfInterfaceImpl::DynamicMethodJITCompilationStarted(FunctionID functionId,
+ BOOL fIsSafeToBlock,
+ LPCBYTE pILHeader,
+ ULONG cbILHeader)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_TRIGGERS;
+ MODE_PREEMPTIVE;
+ CAN_TAKE_LOCK;
+
+ // The JIT / MethodDesc code likely hold locks while this callback is made
+
+ SO_NOT_MAINLINE;
+ }
+ CONTRACTL_END;
+
+ CLR_TO_PROFILER_ENTRYPOINT((LF_CORPROF,
+ LL_INFO1000,
+ "**PROF: DynamicMethodJITCompilationStarted 0x%p.\n",
+ functionId));
+
+ _ASSERTE(functionId);
+
+ // Currently DynamicMethodJITCompilationStarted is always called with fIsSafeToBlock==TRUE. If this ever changes,
+ // it's safe to remove this assert, but this should serve as a trigger to change our
+ // public documentation to state that this callback is no longer called in preemptive mode all the time.
+ _ASSERTE(fIsSafeToBlock);
+
+ if (m_pCallback8 == NULL)
+ {
+ return S_OK;
+ }
+
+ {
+ // 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);
+ return m_pCallback8->DynamicMethodJITCompilationStarted(functionId, fIsSafeToBlock, pILHeader, cbILHeader);
+ }
+}
+
HRESULT EEToProfInterfaceImpl::JITCachedFunctionSearchStarted(
/* [in] */ FunctionID functionId,
/* [out] */ BOOL *pbUseCachedFunction)
@@ -5609,7 +5735,7 @@ HRESULT EEToProfInterfaceImpl::MovedReferences(GCReferencesData *pData)
LL_INFO10000,
"**PROF: MovedReferences.\n"));
- _ASSERTE(!GCHeap::GetGCHeap()->IsConcurrentGCEnabled());
+ _ASSERTE(!GCHeapUtilities::GetGCHeap()->IsConcurrentGCEnabled());
if (pData->curIdx == 0)
{
@@ -5805,7 +5931,7 @@ HRESULT EEToProfInterfaceImpl::ObjectReference(ObjectID objId,
LL_INFO100000,
"**PROF: ObjectReferences.\n"));
- _ASSERTE(!GCHeap::GetGCHeap()->IsConcurrentGCEnabled());
+ _ASSERTE(!GCHeapUtilities::GetGCHeap()->IsConcurrentGCEnabled());
{
// All callbacks are really NOTHROW, but that's enforced partially by the profiler,
@@ -5844,7 +5970,7 @@ HRESULT EEToProfInterfaceImpl::FinalizeableObjectQueued(BOOL isCritical, ObjectI
LL_INFO100,
"**PROF: Notifying profiler of finalizeable object.\n"));
- _ASSERTE(!GCHeap::GetGCHeap()->IsConcurrentGCEnabled());
+ _ASSERTE(!GCHeapUtilities::GetGCHeap()->IsConcurrentGCEnabled());
{
// All callbacks are really NOTHROW, but that's enforced partially by the profiler,
@@ -5883,7 +6009,7 @@ HRESULT EEToProfInterfaceImpl::RootReferences2(GCReferencesData *pData)
LL_INFO10000,
"**PROF: RootReferences2.\n"));
- _ASSERTE(!GCHeap::GetGCHeap()->IsConcurrentGCEnabled());
+ _ASSERTE(!GCHeapUtilities::GetGCHeap()->IsConcurrentGCEnabled());
HRESULT hr = S_OK;
@@ -5948,7 +6074,7 @@ HRESULT EEToProfInterfaceImpl::ConditionalWeakTableElementReferences(GCReference
LL_INFO10000,
"**PROF: ConditionalWeakTableElementReferences.\n"));
- _ASSERTE(!GCHeap::GetGCHeap()->IsConcurrentGCEnabled());
+ _ASSERTE(!GCHeapUtilities::GetGCHeap()->IsConcurrentGCEnabled());
HRESULT hr = S_OK;
@@ -6082,7 +6208,7 @@ HRESULT EEToProfInterfaceImpl::GarbageCollectionStarted(int cGenerations, BOOL g
LL_INFO10000,
"**PROF: GarbageCollectionStarted.\n"));
- _ASSERTE(!GCHeap::GetGCHeap()->IsConcurrentGCEnabled());
+ _ASSERTE(!GCHeapUtilities::GetGCHeap()->IsConcurrentGCEnabled());
{
// All callbacks are really NOTHROW, but that's enforced partially by the profiler,
@@ -6120,7 +6246,7 @@ HRESULT EEToProfInterfaceImpl::GarbageCollectionFinished()
LL_INFO10000,
"**PROF: GarbageCollectionFinished.\n"));
- _ASSERTE(!GCHeap::GetGCHeap()->IsConcurrentGCEnabled());
+ _ASSERTE(!GCHeapUtilities::GetGCHeap()->IsConcurrentGCEnabled());
{
// All callbacks are really NOTHROW, but that's enforced partially by the profiler,
diff --git a/src/vm/eetoprofinterfaceimpl.h b/src/vm/eetoprofinterfaceimpl.h
index 0390f942bb..76797fcc26 100644
--- a/src/vm/eetoprofinterfaceimpl.h
+++ b/src/vm/eetoprofinterfaceimpl.h
@@ -55,6 +55,7 @@ public:
BOOL IsCallback5Supported();
BOOL IsCallback6Supported();
BOOL IsCallback7Supported();
+ BOOL IsCallback8Supported();
HRESULT SetEventMask(DWORD dwEventMask, DWORD dwEventMaskHigh);
@@ -169,6 +170,17 @@ public:
HRESULT JITCompilationStarted(
FunctionID functionId,
BOOL fIsSafeToBlock);
+
+ HRESULT DynamicMethodJITCompilationStarted(
+ FunctionID functionId,
+ BOOL fIsSafeToBlock,
+ LPCBYTE pILHeader,
+ ULONG cbILHeader);
+
+ HRESULT DynamicMethodJITCompilationFinished(
+ FunctionID functionId,
+ HRESULT hrStatus,
+ BOOL fIsSafeToBlock);
HRESULT JITCachedFunctionSearchStarted(
/* [in] */ FunctionID functionId,
@@ -529,13 +541,14 @@ private:
// Pointer to the profiler's implementation of the callback interface(s).
// Profilers MUST support ICorProfilerCallback2.
- // Profilers MAY optionally support ICorProfilerCallback3,4,5,6,7
+ // Profilers MAY optionally support ICorProfilerCallback3,4,5,6,7,8
ICorProfilerCallback2 * m_pCallback2;
ICorProfilerCallback3 * m_pCallback3;
ICorProfilerCallback4 * m_pCallback4;
ICorProfilerCallback5 * m_pCallback5;
ICorProfilerCallback6 * m_pCallback6;
ICorProfilerCallback7 * m_pCallback7;
+ ICorProfilerCallback8 * m_pCallback8;
HMODULE m_hmodProfilerDLL;
BOOL m_fLoadedViaAttach;
diff --git a/src/vm/eetoprofinterfaceimpl.inl b/src/vm/eetoprofinterfaceimpl.inl
index 8a11118ed1..feb81ed8c0 100644
--- a/src/vm/eetoprofinterfaceimpl.inl
+++ b/src/vm/eetoprofinterfaceimpl.inl
@@ -65,6 +65,12 @@ inline BOOL EEToProfInterfaceImpl::IsCallback7Supported()
return (m_pCallback7 != NULL);
}
+inline BOOL EEToProfInterfaceImpl::IsCallback8Supported()
+{
+ LIMITED_METHOD_CONTRACT;
+ return (m_pCallback8 != NULL);
+}
+
inline FunctionIDMapper * EEToProfInterfaceImpl::GetFunctionIDMapper()
{
LIMITED_METHOD_CONTRACT;
diff --git a/src/vm/eetwain.cpp b/src/vm/eetwain.cpp
index 032bda7c96..2ce7b59578 100644
--- a/src/vm/eetwain.cpp
+++ b/src/vm/eetwain.cpp
@@ -142,13 +142,15 @@ __forceinline int decodeSigned(PTR_CBYTE& src)
/*****************************************************************************
*
- * Decodes the methodInfoPtr and returns the decoded information
- * in the hdrInfo struct. The EIP parameter is the PC location
- * within the active method.
+ * Decodes the X86 GcInfo header and returns the decoded information
+ * in the hdrInfo struct.
+ * curOffset is the code offset within the active method used in the
+ * computation of PrologOffs/EpilogOffs.
+ * Returns the size of the header (number of bytes decoded).
*/
-static size_t crackMethodInfoHdr(PTR_VOID methodInfoPtr,
- unsigned curOffset,
- hdrInfo * infoPtr)
+static size_t DecodeGCHdrInfo(GCInfoToken gcInfoToken,
+ unsigned curOffset,
+ hdrInfo * infoPtr)
{
CONTRACTL {
NOTHROW;
@@ -157,7 +159,7 @@ static size_t crackMethodInfoHdr(PTR_VOID methodInfoPtr,
SUPPORTS_DAC;
} CONTRACTL_END;
- PTR_CBYTE table = PTR_CBYTE(methodInfoPtr);
+ PTR_CBYTE table = (PTR_CBYTE) gcInfoToken.Info;
#if VERIFY_GC_TABLES
_ASSERTE(*castto(table, unsigned short *)++ == 0xFEEF);
#endif
@@ -170,7 +172,7 @@ static size_t crackMethodInfoHdr(PTR_VOID methodInfoPtr,
/* Decode the InfoHdr */
InfoHdr header;
- table = decodeHeader(table, &header);
+ table = decodeHeader(table, gcInfoToken.Version, &header);
BOOL hasArgTabOffset = FALSE;
if (header.untrackedCnt == HAS_UNTRACKED)
@@ -199,6 +201,10 @@ static size_t crackMethodInfoHdr(PTR_VOID methodInfoPtr,
_ASSERTE(header.syncStartOffset < header.syncEndOffset);
}
+ if (header.revPInvokeOffset == HAS_REV_PINVOKE_FRAME_OFFSET)
+ {
+ header.revPInvokeOffset = fastDecodeUnsigned(table);
+ }
/* Some sanity checks on header */
@@ -220,6 +226,7 @@ static size_t crackMethodInfoHdr(PTR_VOID methodInfoPtr,
infoPtr->argSize = header.argCount * 4;
infoPtr->ebpFrame = header.ebpFrame;
infoPtr->interruptible = header.interruptible;
+ infoPtr->returnKind = (ReturnKind) header.returnKind;
infoPtr->prologSize = header.prologSize;
infoPtr->epilogSize = header.epilogSize;
@@ -232,6 +239,7 @@ static size_t crackMethodInfoHdr(PTR_VOID methodInfoPtr,
infoPtr->syncStartOffset = header.syncStartOffset;
infoPtr->syncEndOffset = header.syncEndOffset;
+ infoPtr->revPInvokeOffset = header.revPInvokeOffset;
infoPtr->doubleAlign = header.doubleAlign;
infoPtr->securityCheck = header.security;
@@ -352,7 +360,7 @@ static size_t crackMethodInfoHdr(PTR_VOID methodInfoPtr,
(infoPtr->gsCookieOffset < infoPtr->stackSize) &&
((header.gsCookieOffset % sizeof(void*)) == 0));
- return table - PTR_CBYTE(methodInfoPtr);
+ return table - PTR_CBYTE(gcInfoToken.Info);
}
/*****************************************************************************/
@@ -715,7 +723,7 @@ void EECodeManager::FixContext( ContextType ctxType,
/* Extract the necessary information from the info block header */
- stateBuf->hdrInfoSize = (DWORD)crackMethodInfoHdr(pCodeInfo->GetGCInfo(),
+ stateBuf->hdrInfoSize = (DWORD)DecodeGCHdrInfo(pCodeInfo->GetGCInfoToken(),
dwRelOffset,
&stateBuf->hdrInfoBody);
pState->dwIsSet = 1;
@@ -836,11 +844,11 @@ HRESULT EECodeManager::FixContextForEnC(PCONTEXT pCtx,
hdrInfo oldInfo, newInfo;
- crackMethodInfoHdr(pOldCodeInfo->GetGCInfo(),
+ DecodeGCHdrInfo(pOldCodeInfo->GetGCInfoToken(),
pOldCodeInfo->GetRelOffset(),
&oldInfo);
- crackMethodInfoHdr(pNewCodeInfo->GetGCInfo(),
+ DecodeGCHdrInfo(pNewCodeInfo->GetGCInfoToken(),
pNewCodeInfo->GetRelOffset(),
&newInfo);
@@ -1545,7 +1553,7 @@ bool EECodeManager::IsGcSafe( EECodeInfo *pCodeInfo,
/* Extract the necessary information from the info block header */
- table = (BYTE *)crackMethodInfoHdr(pCodeInfo->GetGCInfo(),
+ table = (BYTE *)DecodeGCHdrInfo(pCodeInfo->GetGCInfoToken(),
dwRelOffset,
&info);
@@ -3905,8 +3913,9 @@ bool EECodeManager::UnwindStackFrame(PREGDISPLAY pContext,
PTR_CBYTE methodStart = PTR_CBYTE(pCodeInfo->GetSavedMethodCode());
- PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo();
- DWORD curOffs = pCodeInfo->GetRelOffset();
+ GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken();
+ PTR_VOID methodInfoPtr = gcInfoToken.Info;
+ DWORD curOffs = pCodeInfo->GetRelOffset();
_ASSERTE(sizeof(CodeManStateBuf) <= sizeof(pState->stateBuf));
CodeManStateBuf * stateBuf = (CodeManStateBuf*)pState->stateBuf;
@@ -3915,7 +3924,7 @@ bool EECodeManager::UnwindStackFrame(PREGDISPLAY pContext,
{
/* Extract the necessary information from the info block header */
- stateBuf->hdrInfoSize = (DWORD)crackMethodInfoHdr(methodInfoPtr,
+ stateBuf->hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken,
curOffs,
&stateBuf->hdrInfoBody);
}
@@ -4097,7 +4106,7 @@ bool EECodeManager::EnumGcRefs( PREGDISPLAY pContext,
GC_NOTRIGGER;
} CONTRACTL_END;
- PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo();
+ GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken();
unsigned curOffs = pCodeInfo->GetRelOffset();
unsigned EBP = *pContext->pEbp;
@@ -4108,7 +4117,7 @@ bool EECodeManager::EnumGcRefs( PREGDISPLAY pContext,
unsigned count;
hdrInfo info;
- PTR_CBYTE table = PTR_CBYTE(methodInfoPtr);
+ PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info);
#if 0
printf("EECodeManager::EnumGcRefs - EIP = %08x ESP = %08x offset = %x GC Info is at %08x\n", *pContext->pPC, ESP, curOffs, table);
#endif
@@ -4116,14 +4125,14 @@ bool EECodeManager::EnumGcRefs( PREGDISPLAY pContext,
/* Extract the necessary information from the info block header */
- table += crackMethodInfoHdr(methodInfoPtr,
- curOffs,
- &info);
+ table += DecodeGCHdrInfo(gcInfoToken,
+ curOffs,
+ &info);
_ASSERTE( curOffs <= info.methodSize);
#ifdef _DEBUG
-// if ((methodInfoPtr == (void*)0x37760d0) && (curOffs == 0x264))
+// if ((gcInfoToken.Info == (void*)0x37760d0) && (curOffs == 0x264))
// __asm int 3;
if (trEnumGCRefs) {
@@ -4220,11 +4229,11 @@ bool EECodeManager::EnumGcRefs( PREGDISPLAY pContext,
/* Extract the necessary information from the info block header */
- table = PTR_CBYTE(methodInfoPtr);
+ table = PTR_CBYTE(gcInfoToken.Info);
- table += crackMethodInfoHdr(methodInfoPtr,
- curOffs,
- &info);
+ table += DecodeGCHdrInfo(gcInfoToken,
+ curOffs,
+ &info);
}
}
@@ -5030,9 +5039,9 @@ OBJECTREF* EECodeManager::GetAddrOfSecurityObject(CrawlFrame *pCF)
CodeManStateBuf * stateBuf = (CodeManStateBuf*)pState->stateBuf;
/* Extract the necessary information from the info block header */
- stateBuf->hdrInfoSize = (DWORD)crackMethodInfoHdr(gcInfoToken.Info, // <TODO>truncation</TODO>
- relOffset,
- &stateBuf->hdrInfoBody);
+ stateBuf->hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken, // <TODO>truncation</TODO>
+ relOffset,
+ &stateBuf->hdrInfoBody);
pState->dwIsSet = 1;
if (stateBuf->hdrInfoBody.securityCheck)
@@ -5109,10 +5118,10 @@ OBJECTREF EECodeManager::GetInstance( PREGDISPLAY pContext,
} CONTRACTL_END;
#ifdef _TARGET_X86_
- PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo();
- unsigned relOffset = pCodeInfo->GetRelOffset();
+ GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken();
+ unsigned relOffset = pCodeInfo->GetRelOffset();
- PTR_CBYTE table = PTR_CBYTE(methodInfoPtr);
+ PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info);
hdrInfo info;
unsigned stackDepth;
TADDR taArgBase;
@@ -5120,9 +5129,9 @@ OBJECTREF EECodeManager::GetInstance( PREGDISPLAY pContext,
/* Extract the necessary information from the info block header */
- table += crackMethodInfoHdr(methodInfoPtr,
- relOffset,
- &info);
+ table += DecodeGCHdrInfo(gcInfoToken,
+ relOffset,
+ &info);
// We do not have accurate information in the prolog or the epilog
if (info.prologOffs != hdrInfo::NOT_IN_PROLOG ||
@@ -5236,14 +5245,15 @@ GenericParamContextType EECodeManager::GetParamContextType(PREGDISPLAY pCont
#ifdef _TARGET_X86_
/* Extract the necessary information from the info block header */
- PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo();
- unsigned relOffset = pCodeInfo->GetRelOffset();
+ GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken();
+ PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo();
+ unsigned relOffset = pCodeInfo->GetRelOffset();
hdrInfo info;
- PTR_CBYTE table = PTR_CBYTE(methodInfoPtr);
- table += crackMethodInfoHdr(methodInfoPtr,
- relOffset,
- &info);
+ PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info);
+ table += DecodeGCHdrInfo(gcInfoToken,
+ relOffset,
+ &info);
if (!info.genericsContext ||
info.prologOffs != hdrInfo::NOT_IN_PROLOG ||
@@ -5300,15 +5310,16 @@ PTR_VOID EECodeManager::GetParamTypeArg(PREGDISPLAY pContext,
LIMITED_METHOD_DAC_CONTRACT;
#ifdef _TARGET_X86_
- PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo();
- unsigned relOffset = pCodeInfo->GetRelOffset();
+ GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken();
+ PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo();
+ unsigned relOffset = pCodeInfo->GetRelOffset();
/* Extract the necessary information from the info block header */
hdrInfo info;
- PTR_CBYTE table = PTR_CBYTE(methodInfoPtr);
- table += crackMethodInfoHdr(methodInfoPtr,
- relOffset,
- &info);
+ PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info);
+ table += DecodeGCHdrInfo(gcInfoToken,
+ relOffset,
+ &info);
if (!info.genericsContext ||
info.prologOffs != hdrInfo::NOT_IN_PROLOG ||
@@ -5424,9 +5435,9 @@ void * EECodeManager::GetGSCookieAddr(PREGDISPLAY pContext,
/* Extract the necessary information from the info block header */
hdrInfo * info = &stateBuf->hdrInfoBody;
- stateBuf->hdrInfoSize = (DWORD)crackMethodInfoHdr(gcInfoToken.Info, // <TODO>truncation</TODO>
- relOffset,
- info);
+ stateBuf->hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken, // <TODO>truncation</TODO>
+ relOffset,
+ info);
pState->dwIsSet = 1;
@@ -5482,9 +5493,9 @@ void * EECodeManager::GetGSCookieAddr(PREGDISPLAY pContext,
*
* Returns true if the given IP is in the given method's prolog or epilog.
*/
-bool EECodeManager::IsInPrologOrEpilog(DWORD relPCoffset,
- PTR_VOID methodInfoPtr,
- size_t* prologSize)
+bool EECodeManager::IsInPrologOrEpilog(DWORD relPCoffset,
+ GCInfoToken gcInfoToken,
+ size_t* prologSize)
{
CONTRACTL {
NOTHROW;
@@ -5494,7 +5505,7 @@ bool EECodeManager::IsInPrologOrEpilog(DWORD relPCoffset,
#ifndef USE_GC_INFO_DECODER
hdrInfo info;
- crackMethodInfoHdr(methodInfoPtr, relPCoffset, &info);
+ DecodeGCHdrInfo(gcInfoToken, relPCoffset, &info);
if (prologSize)
*prologSize = info.prologSize;
@@ -5511,10 +5522,9 @@ bool EECodeManager::IsInPrologOrEpilog(DWORD relPCoffset,
*
* Returns true if the given IP is in the synchronized region of the method (valid for synchronized functions only)
*/
-bool EECodeManager::IsInSynchronizedRegion(
- DWORD relOffset,
- PTR_VOID methodInfoPtr,
- unsigned flags)
+bool EECodeManager::IsInSynchronizedRegion(DWORD relOffset,
+ GCInfoToken gcInfoToken,
+ unsigned flags)
{
CONTRACTL {
NOTHROW;
@@ -5524,7 +5534,7 @@ bool EECodeManager::IsInSynchronizedRegion(
#ifndef USE_GC_INFO_DECODER
hdrInfo info;
- crackMethodInfoHdr(methodInfoPtr, relOffset, &info);
+ DecodeGCHdrInfo(gcInfoToken, relOffset, &info);
// We should be called only for synchronized methods
_ASSERTE(info.syncStartOffset != INVALID_SYNC_OFFSET && info.syncEndOffset != INVALID_SYNC_OFFSET);
@@ -5558,9 +5568,8 @@ size_t EECodeManager::GetFunctionSize(GCInfoToken gcInfoToken)
#if defined(_TARGET_X86_)
hdrInfo info;
- PTR_VOID methodInfoPtr = gcInfoToken.Info;
- crackMethodInfoHdr(methodInfoPtr, 0, &info);
+ DecodeGCHdrInfo(gcInfoToken, 0, &info);
return info.methodSize;
#elif defined(USE_GC_INFO_DECODER)
@@ -5578,15 +5587,47 @@ size_t EECodeManager::GetFunctionSize(GCInfoToken gcInfoToken)
PORTABILITY_ASSERT("EECodeManager::GetFunctionSize is not implemented on this platform.");
return 0;
#endif
+}
+/*****************************************************************************
+*
+* Returns the size of a given function.
+*/
+ReturnKind EECodeManager::GetReturnKind(GCInfoToken gcInfoToken)
+{
+ CONTRACTL{
+ NOTHROW;
+ GC_NOTRIGGER;
+ SUPPORTS_DAC;
+ } CONTRACTL_END;
+ if (!gcInfoToken.IsReturnKindAvailable())
+ {
+ return RT_Illegal;
+ }
+
+#if defined(_TARGET_X86_)
+ hdrInfo info;
+
+ DecodeGCHdrInfo(gcInfoToken, 0, &info);
+
+ return info.returnKind;
+#elif defined(USE_GC_INFO_DECODER)
+
+ GcInfoDecoder gcInfoDecoder(gcInfoToken, DECODE_RETURN_KIND);
+ return gcInfoDecoder.GetReturnKind();
+
+#else // !_TARGET_X86_ && !USE_GC_INFO_DECODER
+ PORTABILITY_ASSERT("EECodeManager::GetReturnKind is not implemented on this platform.");
+ return 0;
+#endif
}
/*****************************************************************************
*
* Returns the size of the frame of the given function.
*/
-unsigned int EECodeManager::GetFrameSize(PTR_VOID methodInfoPtr)
+unsigned int EECodeManager::GetFrameSize(GCInfoToken gcInfoToken)
{
CONTRACTL {
NOTHROW;
@@ -5596,7 +5637,7 @@ unsigned int EECodeManager::GetFrameSize(PTR_VOID methodInfoPtr)
#ifndef USE_GC_INFO_DECODER
hdrInfo info;
- crackMethodInfoHdr(methodInfoPtr, 0, &info);
+ DecodeGCHdrInfo(gcInfoToken, 0, &info);
// currently only used by E&C callers need to know about doubleAlign
// in all likelyhood
@@ -5624,10 +5665,10 @@ const BYTE* EECodeManager::GetFinallyReturnAddr(PREGDISPLAY pReg)
#endif
}
-BOOL EECodeManager::IsInFilter(void *methodInfoPtr,
- unsigned offset,
- PCONTEXT pCtx,
- DWORD curNestLevel)
+BOOL EECodeManager::IsInFilter(GCInfoToken gcInfoToken,
+ unsigned offset,
+ PCONTEXT pCtx,
+ DWORD curNestLevel)
{
CONTRACTL {
NOTHROW;
@@ -5640,9 +5681,9 @@ BOOL EECodeManager::IsInFilter(void *methodInfoPtr,
hdrInfo info;
- crackMethodInfoHdr(methodInfoPtr,
- offset,
- &info);
+ DecodeGCHdrInfo(gcInfoToken,
+ offset,
+ &info);
/* make sure that we have an ebp stack frame */
@@ -5668,7 +5709,7 @@ BOOL EECodeManager::IsInFilter(void *methodInfoPtr,
}
-BOOL EECodeManager::LeaveFinally(void *methodInfoPtr,
+BOOL EECodeManager::LeaveFinally(GCInfoToken gcInfoToken,
unsigned offset,
PCONTEXT pCtx)
{
@@ -5681,9 +5722,9 @@ BOOL EECodeManager::LeaveFinally(void *methodInfoPtr,
hdrInfo info;
- crackMethodInfoHdr(methodInfoPtr,
- offset,
- &info);
+ DecodeGCHdrInfo(gcInfoToken,
+ offset,
+ &info);
DWORD nestingLevel;
GetHandlerFrameInfo(&info, pCtx->Ebp, pCtx->Esp, (DWORD) IGNORE_VAL, NULL, &nestingLevel);
@@ -5707,7 +5748,7 @@ BOOL EECodeManager::LeaveFinally(void *methodInfoPtr,
#endif
}
-void EECodeManager::LeaveCatch(void *methodInfoPtr,
+void EECodeManager::LeaveCatch(GCInfoToken gcInfoToken,
unsigned offset,
PCONTEXT pCtx)
{
@@ -5724,7 +5765,7 @@ void EECodeManager::LeaveCatch(void *methodInfoPtr,
bool hasInnerFilter;
hdrInfo info;
- crackMethodInfoHdr(methodInfoPtr, offset, &info);
+ DecodeGCHdrInfo(gcInfoToken, offset, &info);
GetHandlerFrameInfo(&info, pCtx->Ebp, pCtx->Esp, (DWORD) IGNORE_VAL,
&baseSP, &nestingLevel, &hasInnerFilter);
// _ASSERTE(frameType == FR_HANDLER);
@@ -5774,17 +5815,17 @@ TADDR EECodeManager::GetAmbientSP(PREGDISPLAY pContext,
} CONTRACTL_END;
#ifdef _TARGET_X86_
- PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo();
+ GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken();
_ASSERTE(sizeof(CodeManStateBuf) <= sizeof(pState->stateBuf));
CodeManStateBuf * stateBuf = (CodeManStateBuf*)pState->stateBuf;
- PTR_CBYTE table = PTR_CBYTE(methodInfoPtr);
+ PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info);
/* Extract the necessary information from the info block header */
- stateBuf->hdrInfoSize = (DWORD)crackMethodInfoHdr(methodInfoPtr,
- dwRelOffset,
- &stateBuf->hdrInfoBody);
+ stateBuf->hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken,
+ dwRelOffset,
+ &stateBuf->hdrInfoBody);
table += stateBuf->hdrInfoSize;
pState->dwIsSet = 1;
@@ -5868,8 +5909,8 @@ ULONG32 EECodeManager::GetStackParameterSize(EECodeInfo * pCodeInfo)
} CONTRACTL_END;
#if defined(_TARGET_X86_)
- PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo();
- unsigned dwOffset = pCodeInfo->GetRelOffset();
+ GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken();
+ unsigned dwOffset = pCodeInfo->GetRelOffset();
CodeManState state;
state.dwIsSet = 0;
@@ -5878,7 +5919,7 @@ ULONG32 EECodeManager::GetStackParameterSize(EECodeInfo * pCodeInfo)
CodeManStateBuf * pStateBuf = reinterpret_cast<CodeManStateBuf *>(state.stateBuf);
hdrInfo * pHdrInfo = &(pStateBuf->hdrInfoBody);
- pStateBuf->hdrInfoSize = (DWORD)crackMethodInfoHdr(methodInfoPtr, dwOffset, pHdrInfo);
+ pStateBuf->hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken, dwOffset, pHdrInfo);
// We need to subtract 4 here because ESPIncrOnReturn() includes the stack slot containing the return
// address.
diff --git a/src/vm/encee.cpp b/src/vm/encee.cpp
index ca4e7fe553..7f12643340 100644
--- a/src/vm/encee.cpp
+++ b/src/vm/encee.cpp
@@ -149,7 +149,11 @@ HRESULT EditAndContinueModule::ApplyEditAndContinue(
HRESULT hr = S_OK;
HENUMInternal enumENC;
-
+
+ BYTE *pLocalILMemory = NULL;
+ IMDInternalImport *pMDImport = NULL;
+ IMDInternalImport *pNewMDImport = NULL;
+
CONTRACT_VIOLATION(GCViolation); // SafeComHolder goes to preemptive mode, which will trigger a GC
SafeComHolder<IMDInternalImportENC> pIMDInternalImportENC;
SafeComHolder<IMetaDataEmit> pEmitter;
@@ -175,8 +179,7 @@ HRESULT EditAndContinueModule::ApplyEditAndContinue(
IfFailGo(hr);
// Grab the current importer.
- IMDInternalImport *pMDImport = GetMDImport();
- IMDInternalImport *pNewMDImport;
+ pMDImport = GetMDImport();
// Apply the EnC delta to this module's metadata.
IfFailGo(pMDImport->ApplyEditAndContinue(pDeltaMD, cbDeltaMD, &pNewMDImport));
@@ -195,7 +198,7 @@ HRESULT EditAndContinueModule::ApplyEditAndContinue(
IfFailGo(GetMetaDataPublicInterfaceFromInternal(pMDImport, IID_IMetaDataEmit, (void **)&pEmitter));
// Copy the deltaIL into our RVAable IL memory
- BYTE *pLocalILMemory = new BYTE[cbDeltaIL];
+ pLocalILMemory = new BYTE[cbDeltaIL];
memcpy(pLocalILMemory, pDeltaIL, cbDeltaIL);
// Enumerate all of the EnC delta tokens
@@ -203,7 +206,6 @@ HRESULT EditAndContinueModule::ApplyEditAndContinue(
IfFailGo(pIMDInternalImportENC->EnumDeltaTokensInit(&enumENC));
mdToken token;
- FieldDesc * pField = NULL;
while (pIMDInternalImportENC->EnumNext(&enumENC, &token))
{
STRESS_LOG3(LF_ENC, LL_INFO100, "EACM::AEAC: updated token 0x%x; type 0x%x; rid 0x%x\n", token, TypeFromToken(token), RidFromToken(token));
@@ -248,8 +250,7 @@ HRESULT EditAndContinueModule::ApplyEditAndContinue(
// FieldDef token - add a new field
LOG((LF_ENC, LL_INFO10000, "EACM::AEAC: Found field 0x%x\n", token));
- pField = LookupFieldDef(token);
- if (pField)
+ if (LookupFieldDef(token))
{
// Field already exists - just ignore for now
continue;
diff --git a/src/vm/eventtrace.cpp b/src/vm/eventtrace.cpp
index d8702a53e1..cec79214a4 100644
--- a/src/vm/eventtrace.cpp
+++ b/src/vm/eventtrace.cpp
@@ -431,19 +431,19 @@ ETW::SamplingLog::EtwStackWalkStatus ETW::SamplingLog::SaveCurrentStack(int skip
VOID ETW::GCLog::GCSettingsEvent()
{
- if (GCHeap::IsGCHeapInitialized())
+ if (GCHeapUtilities::IsGCHeapInitialized())
{
if (ETW_TRACING_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context,
GCSettings))
{
ETW::GCLog::ETW_GC_INFO Info;
- Info.GCSettings.ServerGC = GCHeap::IsServerHeap ();
- Info.GCSettings.SegmentSize = GCHeap::GetGCHeap()->GetValidSegmentSize (FALSE);
- Info.GCSettings.LargeObjectSegmentSize = GCHeap::GetGCHeap()->GetValidSegmentSize (TRUE);
+ Info.GCSettings.ServerGC = GCHeapUtilities::IsServerHeap ();
+ 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());
}
- GCHeap::GetGCHeap()->TraceGCSegments();
+ GCHeapUtilities::GetGCHeap()->DiagTraceGCSegments();
}
};
@@ -892,7 +892,7 @@ VOID ETW::GCLog::FireGcStartAndGenerationRanges(ETW_GC_INFO * pGcInfo)
// GCStart, then retrieve it
LONGLONG l64ClientSequenceNumberToLog = 0;
if ((s_l64LastClientSequenceNumber != 0) &&
- (pGcInfo->GCStart.Depth == GCHeap::GetMaxGeneration()) &&
+ (pGcInfo->GCStart.Depth == GCHeapUtilities::GetGCHeap()->GetMaxGeneration()) &&
(pGcInfo->GCStart.Reason == ETW_GC_INFO::GC_INDUCED))
{
l64ClientSequenceNumberToLog = InterlockedExchange64(&s_l64LastClientSequenceNumber, 0);
@@ -901,8 +901,8 @@ VOID ETW::GCLog::FireGcStartAndGenerationRanges(ETW_GC_INFO * pGcInfo)
FireEtwGCStart_V2(pGcInfo->GCStart.Count, pGcInfo->GCStart.Depth, pGcInfo->GCStart.Reason, pGcInfo->GCStart.Type, GetClrInstanceId(), l64ClientSequenceNumberToLog);
// Fire an event per range per generation
- GCHeap *hp = GCHeap::GetGCHeap();
- hp->DescrGenerationsToProfiler(FireSingleGenerationRangeEvent, NULL /* context */);
+ IGCHeap *hp = GCHeapUtilities::GetGCHeap();
+ hp->DiagDescrGenerations(FireSingleGenerationRangeEvent, NULL /* context */);
}
}
@@ -928,8 +928,8 @@ VOID ETW::GCLog::FireGcEndAndGenerationRanges(ULONG Count, ULONG Depth)
CLR_GC_KEYWORD))
{
// Fire an event per range per generation
- GCHeap *hp = GCHeap::GetGCHeap();
- hp->DescrGenerationsToProfiler(FireSingleGenerationRangeEvent, NULL /* context */);
+ IGCHeap *hp = GCHeapUtilities::GetGCHeap();
+ hp->DiagDescrGenerations(FireSingleGenerationRangeEvent, NULL /* context */);
// GCEnd
FireEtwGCEnd_V1(Count, Depth, GetClrInstanceId());
@@ -938,7 +938,7 @@ VOID ETW::GCLog::FireGcEndAndGenerationRanges(ULONG Count, ULONG Depth)
//---------------------------------------------------------------------------------------
//
-// Callback made by GC when we call GCHeap::DescrGenerationsToProfiler(). This is
+// Callback made by GC when we call GCHeapUtilities::DiagDescrGenerations(). This is
// called once per range per generation, and results in a single ETW event per range per
// generation.
//
@@ -1033,7 +1033,7 @@ HRESULT ETW::GCLog::ForceGCForDiagnostics()
ForcedGCHolder forcedGCHolder;
- hr = GCHeap::GetGCHeap()->GarbageCollect(
+ hr = GCHeapUtilities::GetGCHeap()->GarbageCollect(
-1, // all generations should be collected
FALSE, // low_memory_p
collection_blocking);
@@ -4468,6 +4468,12 @@ extern "C"
BOOLEAN bIsRundownTraceHandle = (context->RegistrationHandle==Microsoft_Windows_DotNETRuntimeRundownHandle);
+ // TypeSystemLog needs a notification when certain keywords are modified, so
+ // give it a hook here.
+ if (g_fEEStarted && !g_fEEShutDown && bIsPublicTraceHandle)
+ {
+ ETW::TypeSystemLog::OnKeywordsChanged();
+ }
// A manifest based provider can be enabled to multiple event tracing sessions
// As long as there is atleast 1 enabled session, IsEnabled will be TRUE
@@ -4478,13 +4484,6 @@ extern "C"
(ControlCode == EVENT_CONTROL_CODE_CAPTURE_STATE));
if(bEnabled)
{
- // TypeSystemLog needs a notification when certain keywords are modified, so
- // give it a hook here.
- if (g_fEEStarted && !g_fEEShutDown && bIsPublicTraceHandle)
- {
- ETW::TypeSystemLog::OnKeywordsChanged();
- }
-
if (bIsPrivateTraceHandle)
{
ETW::GCLog::GCSettingsEvent();
diff --git a/src/vm/eventtracepriv.h b/src/vm/eventtracepriv.h
index 0932225133..7aca5091fa 100644
--- a/src/vm/eventtracepriv.h
+++ b/src/vm/eventtracepriv.h
@@ -23,7 +23,10 @@
#define _countof(_array) (sizeof(_array)/sizeof(_array[0]))
#endif
-const UINT cbMaxEtwEvent = 64 * 1024;
+// ETW has a limitation of 64K for TOTAL event Size, however there is overhead associated with
+// the event headers. It is unclear exactly how much that is, but 1K should be sufficiently
+// far away to avoid problems without sacrificing the perf of bulk processing.
+const UINT cbMaxEtwEvent = 63 * 1024;
//---------------------------------------------------------------------------------------
// C++ copies of ETW structures
diff --git a/src/vm/excep.cpp b/src/vm/excep.cpp
index 672f315fcd..5a6f7c673f 100644
--- a/src/vm/excep.cpp
+++ b/src/vm/excep.cpp
@@ -20,7 +20,7 @@
#include "cgensys.h"
#include "comutilnative.h"
#include "siginfo.hpp"
-#include "gc.h"
+#include "gcheaputilities.h"
#include "eedbginterfaceimpl.h" //so we can clearexception in RealCOMPlusThrow
#include "perfcounters.h"
#include "dllimportcallback.h"
@@ -1679,7 +1679,7 @@ bool FinallyIsUnwinding(EHRangeTreeNode *pNode,
BOOL LeaveCatch(ICodeManager* pEECM,
Thread *pThread,
CONTEXT *pCtx,
- void *methodInfoPtr,
+ GCInfoToken gcInfoToken,
unsigned offset)
{
CONTRACTL
@@ -1690,6 +1690,7 @@ BOOL LeaveCatch(ICodeManager* pEECM,
}
CONTRACTL_END;
+#ifndef FEATURE_PAL
// We can assert these things here, and skip a call
// to COMPlusCheckForAbort later.
@@ -1703,10 +1704,14 @@ BOOL LeaveCatch(ICodeManager* pEECM,
PopNestedExceptionRecords(esp, pCtx, pThread->GetExceptionListPtr());
// Do JIT-specific work
- pEECM->LeaveCatch(methodInfoPtr, offset, pCtx);
+ pEECM->LeaveCatch(gcInfoToken, offset, pCtx);
SetSP(pCtx, (UINT_PTR)esp);
return TRUE;
+#else // FEATURE_PAL
+ PORTABILITY_ASSERT("LeaveCatch");
+ return FALSE;
+#endif
}
#endif // WIN64EXCEPTIONS
@@ -1762,7 +1767,7 @@ HRESULT IsLegalTransition(Thread *pThread,
ICodeManager* pEECM,
PREGDISPLAY pReg,
SLOT addrStart,
- void *methodInfoPtr,
+ GCInfoToken gcInfoToken,
PCONTEXT pCtx)
{
CONTRACTL
@@ -1875,7 +1880,7 @@ HRESULT IsLegalTransition(Thread *pThread,
if (!LeaveCatch(pEECM,
pThread,
pFilterCtx,
- methodInfoPtr,
+ gcInfoToken,
offFrom))
return E_FAIL;
}
@@ -1930,7 +1935,7 @@ HRESULT IsLegalTransition(Thread *pThread,
if (!fCanSetIPOnly)
{
- if (!pEECM->LeaveFinally(methodInfoPtr,
+ if (!pEECM->LeaveFinally(gcInfoToken,
offFrom,
pFilterCtx))
return E_FAIL;
@@ -2041,7 +2046,7 @@ HRESULT SetIPFromSrcToDst(Thread *pThread,
EECodeInfo codeInfo((TADDR)(addrStart));
ICodeManager * pEECM = codeInfo.GetCodeManager();
- LPVOID methodInfoPtr = codeInfo.GetGCInfo();
+ GCInfoToken gcInfoToken = codeInfo.GetGCInfoToken();
// Do both checks here so compiler doesn't complain about skipping
// initialization b/c of goto.
@@ -2097,7 +2102,7 @@ retryForCommit:
pEECM,
pReg,
addrStart,
- methodInfoPtr,
+ gcInfoToken,
pCtx);
if (FAILED(hr))
@@ -2120,7 +2125,7 @@ retryForCommit:
pEECM,
pReg,
addrStart,
- methodInfoPtr,
+ gcInfoToken,
pCtx);
if (FAILED(hr))
@@ -2143,7 +2148,7 @@ retryForCommit:
pEECM,
pReg,
addrStart,
- methodInfoPtr,
+ gcInfoToken,
pCtx);
if (FAILED(hr))
@@ -7313,8 +7318,8 @@ AdjustContextForWriteBarrier(
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_WriteBarrierStart) && (f_IP <= (void *) JIT_WriteBarrierLast)) ||
+ ((f_IP >= (void *) JIT_PatchedWriteBarrierStart) && (f_IP <= (void *) JIT_PatchedWriteBarrierLast)))
{
// set the exception IP to be the instruction that called the write barrier
void* callsite = (void *)GetAdjustedCallAddress(*dac_cast<PTR_PCODE>(GetSP(pContext)));
@@ -9916,47 +9921,48 @@ PTR_EHWatsonBucketTracker GetWatsonBucketTrackerForPreallocatedException(OBJECTR
goto doValidation;
}
- // Find the reference to the exception tracker corresponding to the preallocated exception,
- // starting the search from the current exception tracker (2nd arg of NULL specifies that).
-#if defined(WIN64EXCEPTIONS)
- PTR_ExceptionTracker pEHTracker = NULL;
- PTR_ExceptionTracker pPreviousEHTracker = NULL;
+ {
+ // Find the reference to the exception tracker corresponding to the preallocated exception,
+ // starting the search from the current exception tracker (2nd arg of NULL specifies that).
+ #if defined(WIN64EXCEPTIONS)
+ PTR_ExceptionTracker pEHTracker = NULL;
+ PTR_ExceptionTracker pPreviousEHTracker = NULL;
#elif _TARGET_X86_
- PTR_ExInfo pEHTracker = NULL;
- PTR_ExInfo pPreviousEHTracker = NULL;
+ PTR_ExInfo pEHTracker = NULL;
+ PTR_ExInfo pPreviousEHTracker = NULL;
#else // !(_WIN64 || _TARGET_X86_)
#error Unsupported platform
#endif // _WIN64
- if (fStartSearchFromPreviousTracker)
- {
- // Get the exception tracker previous to the current one
- pPreviousEHTracker = GetThread()->GetExceptionState()->GetCurrentExceptionTracker()->GetPreviousExceptionTracker();
+ if (fStartSearchFromPreviousTracker)
+ {
+ // Get the exception tracker previous to the current one
+ pPreviousEHTracker = GetThread()->GetExceptionState()->GetCurrentExceptionTracker()->GetPreviousExceptionTracker();
+
+ // If there is no previous tracker to start from, then simply abort the search attempt.
+ // If we couldnt find the exception tracker, then buckets are not available
+ if (pPreviousEHTracker == NULL)
+ {
+ LOG((LF_EH, LL_INFO100, "GetWatsonBucketTrackerForPreallocatedException - Couldnt find the previous EHTracker to start the search from.\n"));
+ pWBTracker = NULL;
+ goto done;
+ }
+ }
+
+ pEHTracker = GetEHTrackerForPreallocatedException(gc.oPreAllocThrowable, pPreviousEHTracker);
- // If there is no previous tracker to start from, then simply abort the search attempt.
// If we couldnt find the exception tracker, then buckets are not available
- if (pPreviousEHTracker == NULL)
+ if (pEHTracker == NULL)
{
- LOG((LF_EH, LL_INFO100, "GetWatsonBucketTrackerForPreallocatedException - Couldnt find the previous EHTracker to start the search from.\n"));
+ LOG((LF_EH, LL_INFO100, "GetWatsonBucketTrackerForPreallocatedException - Couldnt find EHTracker for preallocated exception object.\n"));
pWBTracker = NULL;
goto done;
}
- }
- pEHTracker = GetEHTrackerForPreallocatedException(gc.oPreAllocThrowable, pPreviousEHTracker);
-
- // If we couldnt find the exception tracker, then buckets are not available
- if (pEHTracker == NULL)
- {
- LOG((LF_EH, LL_INFO100, "GetWatsonBucketTrackerForPreallocatedException - Couldnt find EHTracker for preallocated exception object.\n"));
- pWBTracker = NULL;
- goto done;
+ // Get the Watson Bucket Tracker from the exception tracker
+ pWBTracker = pEHTracker->GetWatsonBucketTracker();
}
-
- // Get the Watson Bucket Tracker from the exception tracker
- pWBTracker = pEHTracker->GetWatsonBucketTracker();
-
doValidation:
_ASSERTE(pWBTracker != NULL);
@@ -12196,7 +12202,7 @@ done:
// CE can be caught in the VM and later reraised again. Examples of such scenarios
// include AD transition, COM interop, Reflection invocation, to name a few.
// In such cases, we want to mark the corruption severity for reuse upon reraise,
-// implying that when the VM does a reraise of such a exception, we should use
+// implying that when the VM does a reraise of such an exception, we should use
// the original corruption severity for the new raised exception, instead of creating
// a new one for it.
/* static */
@@ -12913,15 +12919,6 @@ void ExceptionNotifications::DeliverNotificationInternal(ExceptionNotificationHa
AppDomain *pCurDomain = GetAppDomain();
_ASSERTE(pCurDomain != NULL);
-#ifdef FEATURE_CORECLR
- if (true)
- {
- // On CoreCLR, we dont support enhanced exception notifications
- _ASSERTE(!"CoreCLR does not support enhanced exception notifications!");
- return;
- }
-#endif // FEATURE_CORECLR
-
struct
{
OBJECTREF oNotificationDelegate;
diff --git a/src/vm/excep.h b/src/vm/excep.h
index 527e3a1ed7..7ef1921593 100644
--- a/src/vm/excep.h
+++ b/src/vm/excep.h
@@ -88,9 +88,11 @@ struct ThrowCallbackType
MethodDesc * pProfilerNotify; // Context for profiler callbacks -- see COMPlusFrameHandler().
BOOL bReplaceStack; // Used to pass info to SaveStackTrace call
BOOL bSkipLastElement;// Used to pass info to SaveStackTrace call
+#ifndef FEATURE_PAL
HANDLE hCallerToken;
HANDLE hImpersonationToken;
BOOL bImpersonationTokenSet;
+#endif // !FEATURE_PAL
#ifdef _DEBUG
void * pCurrentExceptionRecord;
void * pPrevExceptionRecord;
@@ -114,9 +116,11 @@ struct ThrowCallbackType
pProfilerNotify = NULL;
bReplaceStack = FALSE;
bSkipLastElement = FALSE;
+#ifndef FEATURE_PAL
hCallerToken = NULL;
hImpersonationToken = NULL;
bImpersonationTokenSet = FALSE;
+#endif // !FEATURE_PAL
#ifdef _DEBUG
pCurrentExceptionRecord = 0;
@@ -422,10 +426,11 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrowInvalidCastException(TypeHandle thCastFro
VOID DECLSPEC_NORETURN RealCOMPlusThrowInvalidCastException(OBJECTREF *pObj, TypeHandle thCastTo);
+#ifdef _TARGET_X86_
+
#include "eexcp.h"
#include "exinfo.h"
-#ifdef _TARGET_X86_
struct FrameHandlerExRecord
{
EXCEPTION_REGISTRATION_RECORD m_ExReg;
diff --git a/src/vm/exceptionhandling.cpp b/src/vm/exceptionhandling.cpp
index e59f10e070..ed155eb998 100644
--- a/src/vm/exceptionhandling.cpp
+++ b/src/vm/exceptionhandling.cpp
@@ -4730,7 +4730,7 @@ VOID DECLSPEC_NORETURN DispatchManagedException(PAL_SEHException& ex, bool isHar
}
}
- throw ex;
+ throw std::move(ex);
}
#ifdef _AMD64_
diff --git a/src/vm/exceptmacros.h b/src/vm/exceptmacros.h
index efed993a2d..2af064c96d 100644
--- a/src/vm/exceptmacros.h
+++ b/src/vm/exceptmacros.h
@@ -334,7 +334,7 @@ VOID DECLSPEC_NORETURN DispatchManagedException(PAL_SEHException& ex, bool isHar
UNREACHABLE(); \
}
-#else
+#else // FEATURE_PAL
#define INSTALL_MANAGED_EXCEPTION_DISPATCHER
#define UNINSTALL_MANAGED_EXCEPTION_DISPATCHER
diff --git a/src/vm/exinfo.cpp b/src/vm/exinfo.cpp
index 4cbc6d34c4..9e07cebaf3 100644
--- a/src/vm/exinfo.cpp
+++ b/src/vm/exinfo.cpp
@@ -76,9 +76,11 @@ void ExInfo::CopyAndClearSource(ExInfo *from)
// Finally, initialize the source ExInfo.
from->Init();
+#ifndef FEATURE_PAL
// Clear the Watson Bucketing information as well since they
// have been transferred over by the "memcpy" above.
from->GetWatsonBucketTracker()->Init();
+#endif // FEATURE_PAL
}
void ExInfo::Init()
@@ -136,8 +138,10 @@ ExInfo::ExInfo()
m_hThrowable = NULL;
Init();
+#ifndef FEATURE_PAL
// Init the WatsonBucketTracker
m_WatsonBucketTracker.Init();
+#endif // FEATURE_PAL
}
//*******************************************************************************
@@ -206,9 +210,11 @@ void ExInfo::UnwindExInfo(VOID* limit)
pPrevNestedInfo->DestroyExceptionHandle();
}
+ #ifndef FEATURE_PAL
// Free the Watson bucket details when ExInfo
// is being released
pPrevNestedInfo->GetWatsonBucketTracker()->ClearWatsonBucketDetails();
+ #endif // FEATURE_PAL
pPrevNestedInfo->m_StackTraceInfo.FreeStackTrace();
@@ -256,8 +262,10 @@ void ExInfo::UnwindExInfo(VOID* limit)
// We just do a basic Init of the current top ExInfo here.
Init();
+ #ifndef FEATURE_PAL
// Init the Watson buckets as well
GetWatsonBucketTracker()->ClearWatsonBucketDetails();
+ #endif // FEATURE_PAL
}
}
#endif // DACCESS_COMPILE
diff --git a/src/vm/exinfo.h b/src/vm/exinfo.h
index 72f2775106..2a8030fb56 100644
--- a/src/vm/exinfo.h
+++ b/src/vm/exinfo.h
@@ -79,6 +79,7 @@ public:
//
void* m_StackAddress; // A pseudo or real stack location for this record.
+#ifndef FEATURE_PAL
private:
EHWatsonBucketTracker m_WatsonBucketTracker;
public:
@@ -87,6 +88,7 @@ public:
LIMITED_METHOD_CONTRACT;
return PTR_EHWatsonBucketTracker(PTR_HOST_MEMBER_TADDR(ExInfo, this, m_WatsonBucketTracker));
}
+#endif
#ifdef FEATURE_CORRUPTING_EXCEPTIONS
private:
diff --git a/src/vm/finalizerthread.cpp b/src/vm/finalizerthread.cpp
index 5d51d33cfb..2f72b07957 100644
--- a/src/vm/finalizerthread.cpp
+++ b/src/vm/finalizerthread.cpp
@@ -295,7 +295,7 @@ Object * FinalizerThread::FinalizeAllObjects(Object* fobj, int bitToCheck)
{
return NULL;
}
- fobj = GCHeap::GetGCHeap()->GetNextFinalizable();
+ fobj = GCHeapUtilities::GetGCHeap()->GetNextFinalizable();
}
Thread *pThread = GetThread();
@@ -320,7 +320,7 @@ Object * FinalizerThread::FinalizeAllObjects(Object* fobj, int bitToCheck)
{
return NULL;
}
- fobj = GCHeap::GetGCHeap()->GetNextFinalizable();
+ fobj = GCHeapUtilities::GetGCHeap()->GetNextFinalizable();
}
else
{
@@ -337,7 +337,7 @@ Object * FinalizerThread::FinalizeAllObjects(Object* fobj, int bitToCheck)
{
return NULL;
}
- fobj = GCHeap::GetGCHeap()->GetNextFinalizable();
+ fobj = GCHeapUtilities::GetGCHeap()->GetNextFinalizable();
}
}
}
@@ -533,7 +533,7 @@ void FinalizerThread::WaitForFinalizerEvent (CLREvent *event)
case (WAIT_OBJECT_0 + kLowMemoryNotification):
//short on memory GC immediately
GetFinalizerThread()->DisablePreemptiveGC();
- GCHeap::GetGCHeap()->GarbageCollect(0, TRUE);
+ GCHeapUtilities::GetGCHeap()->GarbageCollect(0, TRUE);
GetFinalizerThread()->EnablePreemptiveGC();
//wait only on the event for 2s
switch (event->Wait(2000, FALSE))
@@ -584,7 +584,7 @@ void FinalizerThread::WaitForFinalizerEvent (CLREvent *event)
if (WaitForSingleObject(MHandles[kLowMemoryNotification], 0) == WAIT_OBJECT_0) {
//short on memory GC immediately
GetFinalizerThread()->DisablePreemptiveGC();
- GCHeap::GetGCHeap()->GarbageCollect(0, TRUE);
+ GCHeapUtilities::GetGCHeap()->GarbageCollect(0, TRUE);
GetFinalizerThread()->EnablePreemptiveGC();
}
//wait only on the event for 2s
@@ -604,7 +604,7 @@ void FinalizerThread::WaitForFinalizerEvent (CLREvent *event)
if (sLastLowMemoryFromHost != 0)
{
GetFinalizerThread()->DisablePreemptiveGC();
- GCHeap::GetGCHeap()->GarbageCollect(0, TRUE);
+ GCHeapUtilities::GetGCHeap()->GarbageCollect(0, TRUE);
GetFinalizerThread()->EnablePreemptiveGC();
}
}
@@ -677,7 +677,7 @@ VOID FinalizerThread::FinalizerThreadWorker(void *args)
{
s_forcedGCInProgress = true;
GetFinalizerThread()->DisablePreemptiveGC();
- GCHeap::GetGCHeap()->GarbageCollect(2, FALSE, collection_blocking);
+ GCHeapUtilities::GetGCHeap()->GarbageCollect(2, FALSE, collection_blocking);
GetFinalizerThread()->EnablePreemptiveGC();
s_forcedGCInProgress = false;
@@ -710,14 +710,14 @@ VOID FinalizerThread::FinalizerThreadWorker(void *args)
do
{
- last_gc_count = GCHeap::GetGCHeap()->CollectionCount(0);
+ last_gc_count = GCHeapUtilities::GetGCHeap()->CollectionCount(0);
GetFinalizerThread()->m_GCOnTransitionsOK = FALSE;
GetFinalizerThread()->EnablePreemptiveGC();
__SwitchToThread (0, ++dwSwitchCount);
GetFinalizerThread()->DisablePreemptiveGC();
// If no GCs happended, then we assume we are quiescent
GetFinalizerThread()->m_GCOnTransitionsOK = TRUE;
- } while (GCHeap::GetGCHeap()->CollectionCount(0) - last_gc_count > 0);
+ } while (GCHeapUtilities::GetGCHeap()->CollectionCount(0) - last_gc_count > 0);
}
#endif //_DEBUG
@@ -747,7 +747,7 @@ VOID FinalizerThread::FinalizerThreadWorker(void *args)
}
else if (UnloadingAppDomain == NULL)
break;
- else if (!GCHeap::GetGCHeap()->FinalizeAppDomain(UnloadingAppDomain, fRunFinalizersOnUnload))
+ else if (!GCHeapUtilities::GetGCHeap()->FinalizeAppDomain(UnloadingAppDomain, fRunFinalizersOnUnload))
{
break;
}
@@ -916,7 +916,7 @@ DWORD __stdcall FinalizerThread::FinalizerThreadStart(void *args)
if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_FinalizeOnShutdown) != 0)
{
// Finalize all registered objects during shutdown, even they are still reachable.
- GCHeap::GetGCHeap()->SetFinalizeQueueForShutdown(FALSE);
+ GCHeapUtilities::GetGCHeap()->SetFinalizeQueueForShutdown(FALSE);
// This will apply any policy for swallowing exceptions during normal
// processing, without allowing the finalizer thread to disappear on us.
@@ -1380,7 +1380,7 @@ BOOL FinalizerThread::FinalizerThreadWatchDogHelper()
}
else
{
- prevCount = GCHeap::GetGCHeap()->GetNumberOfFinalizable();
+ prevCount = GCHeapUtilities::GetGCHeap()->GetNumberOfFinalizable();
}
DWORD maxTry = (DWORD)(totalWaitTimeout*1.0/FINALIZER_WAIT_TIMEOUT + 0.5);
@@ -1447,11 +1447,11 @@ BOOL FinalizerThread::FinalizerThreadWatchDogHelper()
}
else
{
- curCount = GCHeap::GetGCHeap()->GetNumberOfFinalizable();
+ curCount = GCHeapUtilities::GetGCHeap()->GetNumberOfFinalizable();
}
if ((prevCount <= curCount)
- && !GCHeap::GetGCHeap()->ShouldRestartFinalizerWatchDog()
+ && !GCHeapUtilities::GetGCHeap()->ShouldRestartFinalizerWatchDog()
&& (pThread == NULL || !(pThread->m_State & (Thread::TS_UserSuspendPending | Thread::TS_DebugSuspendPending)))){
if (nTry == maxTry) {
if (!s_fRaiseExitProcessEvent) {
diff --git a/src/vm/frames.cpp b/src/vm/frames.cpp
index ec7e7be63c..04a1815cf3 100644
--- a/src/vm/frames.cpp
+++ b/src/vm/frames.cpp
@@ -18,7 +18,7 @@
#include "fieldmarshaler.h"
#include "objecthandle.h"
#include "siginfo.hpp"
-#include "gc.h"
+#include "gcheaputilities.h"
#include "dllimportcallback.h"
#include "stackwalk.h"
#include "dbginterface.h"
diff --git a/src/vm/frames.h b/src/vm/frames.h
index 0926f29cea..91ab3c3e5f 100644
--- a/src/vm/frames.h
+++ b/src/vm/frames.h
@@ -113,8 +113,10 @@
// | +-ComPrestubMethodFrame - prestub frame for calls from COM to CLR
// |
#endif //FEATURE_COMINTEROP
+#ifdef _TARGET_X86_
// | +-UMThkCallFrame - this frame represents an unmanaged->managed
// | transition through N/Direct
+#endif
// |
// +-ContextTransitionFrame - this frame is used to mark an appdomain transition
// |
@@ -1905,7 +1907,7 @@ class UnmanagedToManagedFrame : public Frame
{
friend class CheckAsmOffsets;
- VPTR_ABSTRACT_VTABLE_CLASS(UnmanagedToManagedFrame, Frame)
+ VPTR_ABSTRACT_VTABLE_CLASS_AND_CTOR(UnmanagedToManagedFrame, Frame)
public:
@@ -2897,7 +2899,7 @@ typedef DPTR(class UMThunkMarshInfo) PTR_UMThunkMarshInfo;
class UMEntryThunk;
typedef DPTR(class UMEntryThunk) PTR_UMEntryThunk;
-#ifdef _TARGET_X86_
+#if defined(_TARGET_X86_)
//------------------------------------------------------------------------
// This frame guards an unmanaged->managed transition thru a UMThk
//------------------------------------------------------------------------
@@ -2925,7 +2927,7 @@ protected:
// Keep as last entry in class
DEFINE_VTABLE_GETTER_AND_CTOR_AND_DTOR(UMThkCallFrame)
};
-#endif // _TARGET_X86_
+#endif // _TARGET_X86_ && !FEATURE_PAL
#if defined(_TARGET_X86_)
//-------------------------------------------------------------------------
diff --git a/src/vm/frameworkexceptionloader.cpp b/src/vm/frameworkexceptionloader.cpp
index 7d01f82983..a33010e163 100644
--- a/src/vm/frameworkexceptionloader.cpp
+++ b/src/vm/frameworkexceptionloader.cpp
@@ -74,7 +74,7 @@ MethodTable* FrameworkExceptionLoader::GetException(RuntimeExceptionKind kind)
{
Exception *ex = GET_EXCEPTION();
- // Let non-file-not-found execeptions propagate
+ // Let non-file-not-found exceptions propagate
if (EEFileLoadException::GetFileLoadKind(ex->GetHR()) != kFileNotFoundException)
EX_RETHROW;
diff --git a/src/vm/gc.h b/src/vm/gc.h
deleted file mode 100644
index 825b5da803..0000000000
--- a/src/vm/gc.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/gc.h"
diff --git a/src/vm/gccover.cpp b/src/vm/gccover.cpp
index 41dc094e94..d5e7b60d1a 100644
--- a/src/vm/gccover.cpp
+++ b/src/vm/gccover.cpp
@@ -80,7 +80,7 @@ void SetupAndSprinkleBreakpoints(
gcCover->methodRegion = methodRegionInfo;
gcCover->codeMan = pCodeInfo->GetCodeManager();
- gcCover->gcInfoToken = pCodeInfo->GetGCInfoToken();
+ gcCover->gcInfoToken = pCodeInfo->GetGCInfoToken();
gcCover->callerThread = 0;
gcCover->doingEpilogChecks = true;
@@ -583,7 +583,7 @@ void GCCoverageInfo::SprinkleBreakpoints(
#ifdef _TARGET_X86_
// we will whack every instruction in the prolog and epilog to make certain
// our unwinding logic works there.
- if (codeMan->IsInPrologOrEpilog((cur - codeStart) + (DWORD)regionOffsetAdj, gcInfoToken.Info, NULL)) {
+ if (codeMan->IsInPrologOrEpilog((cur - codeStart) + (DWORD)regionOffsetAdj, gcInfoToken, NULL)) {
*cur = INTERRUPT_INSTR;
}
#endif
@@ -1234,8 +1234,8 @@ void checkAndUpdateReg(DWORD& origVal, DWORD curVal, bool gcHappened) {
// the validation infrastructure has got a bug.
_ASSERTE(gcHappened); // If the register values are different, a GC must have happened
- _ASSERTE(GCHeap::GetGCHeap()->IsHeapPointer((BYTE*) size_t(origVal))); // And the pointers involved are on the GCHeap
- _ASSERTE(GCHeap::GetGCHeap()->IsHeapPointer((BYTE*) size_t(curVal)));
+ _ASSERTE(GCHeapUtilities::GetGCHeap()->IsHeapPointer((BYTE*) size_t(origVal))); // And the pointers involved are on the GCHeap
+ _ASSERTE(GCHeapUtilities::GetGCHeap()->IsHeapPointer((BYTE*) size_t(curVal)));
origVal = curVal; // this is now the best estimate of what should be returned.
}
@@ -1478,7 +1478,7 @@ void DoGcStress (PCONTEXT regs, MethodDesc *pMD)
if (gcCover->callerThread == 0) {
if (FastInterlockCompareExchangePointer(&gcCover->callerThread, pThread, 0) == 0) {
gcCover->callerRegs = *regs;
- gcCover->gcCount = GCHeap::GetGCHeap()->GetGcCount();
+ gcCover->gcCount = GCHeapUtilities::GetGCHeap()->GetGcCount();
bShouldUpdateProlog = false;
}
}
@@ -1527,7 +1527,7 @@ void DoGcStress (PCONTEXT regs, MethodDesc *pMD)
/* are we in a prolog or epilog? If so just test the unwind logic
but don't actually do a GC since the prolog and epilog are not
GC safe points */
- if (gcCover->codeMan->IsInPrologOrEpilog(offset, gcCover->gcInfoToken.Info, NULL))
+ if (gcCover->codeMan->IsInPrologOrEpilog(offset, gcCover->gcInfoToken, NULL))
{
// We are not at a GC safe point so we can't Suspend EE (Suspend EE will yield to GC).
// But we still have to update the GC Stress instruction. We do it directly without suspending
@@ -1564,13 +1564,13 @@ void DoGcStress (PCONTEXT regs, MethodDesc *pMD)
// instruction in the epilog (TODO: fix it for the first instr Case)
_ASSERTE(pThread->PreemptiveGCDisabled()); // Epilogs should be in cooperative mode, no GC can happen right now.
- bool gcHappened = gcCover->gcCount != GCHeap::GetGCHeap()->GetGcCount();
+ bool gcHappened = gcCover->gcCount != GCHeapUtilities::GetGCHeap()->GetGcCount();
checkAndUpdateReg(gcCover->callerRegs.Edi, *regDisp.pEdi, gcHappened);
checkAndUpdateReg(gcCover->callerRegs.Esi, *regDisp.pEsi, gcHappened);
checkAndUpdateReg(gcCover->callerRegs.Ebx, *regDisp.pEbx, gcHappened);
checkAndUpdateReg(gcCover->callerRegs.Ebp, *regDisp.pEbp, gcHappened);
- gcCover->gcCount = GCHeap::GetGCHeap()->GetGcCount();
+ gcCover->gcCount = GCHeapUtilities::GetGCHeap()->GetGcCount();
}
return;
@@ -1689,24 +1689,6 @@ void DoGcStress (PCONTEXT regs, MethodDesc *pMD)
bool enableWhenDone = false;
if (!pThread->PreemptiveGCDisabled())
{
-#ifdef _TARGET_X86_
- // We are in preemtive mode in JITTed code. currently this can only
- // happen in a couple of instructions when we have an inlined PINVOKE
- // method.
-
- // Better be a CALL (direct or indirect),
- // or a MOV instruction (three flavors),
- // or pop ECX or add ESP xx (for cdecl pops, two flavors)
- // or cmp, je (for the PINVOKE ESP checks)
- // or lea (for PInvoke stack resilience)
- if (!(instrVal == 0xE8 || instrVal == 0xFF ||
- instrVal == 0x89 || instrVal == 0x8B || instrVal == 0xC6 ||
- instrVal == 0x59 || instrVal == 0x81 || instrVal == 0x83 ||
- instrVal == 0x3B || instrVal == 0x74 || instrVal == 0x8D))
- {
- _ASSERTE(!"Unexpected instruction in preemtive JITTED code");
- }
-#endif // _TARGET_X86_
pThread->DisablePreemptiveGC();
enableWhenDone = true;
}
@@ -1777,7 +1759,7 @@ void DoGcStress (PCONTEXT regs, MethodDesc *pMD)
// Do the actual stress work
//
- if (!GCHeap::GetGCHeap()->StressHeap())
+ if (!GCHeapUtilities::GetGCHeap()->StressHeap())
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 2f1e4e8200..3be8384b3d 100644
--- a/src/vm/gcenv.ee.cpp
+++ b/src/vm/gcenv.ee.cpp
@@ -15,6 +15,12 @@
#include "gcenv.h"
+#ifdef FEATURE_STANDALONE_GC
+#include "gcenv.ee.h"
+#else
+#include "../gc/env/gcenv.ee.h"
+#endif // FEATURE_STANDALONE_GC
+
#include "threadsuspend.h"
#ifdef FEATURE_COMINTEROP
@@ -125,7 +131,7 @@ inline bool SafeToReportGenericParamContext(CrawlFrame* pCF)
#ifndef USE_GC_INFO_DECODER
ICodeManager * pEECM = pCF->GetCodeManager();
- if (pEECM != NULL && pEECM->IsInPrologOrEpilog(pCF->GetRelOffset(), pCF->GetGCInfo(), NULL))
+ if (pEECM != NULL && pEECM->IsInPrologOrEpilog(pCF->GetRelOffset(), pCF->GetGCInfoToken(), NULL))
{
return false;
}
@@ -550,7 +556,7 @@ void GCToEEInterface::GcScanRoots(promote_func* fn, int condemned, int max_gen,
STRESS_LOG1(LF_GCROOTS, LL_INFO10, "GCScan: Promotion Phase = %d\n", sc->promotion);
// In server GC, we should be competing for marking the statics
- if (GCHeap::MarkShouldCompeteForStatics())
+ if (GCHeapUtilities::MarkShouldCompeteForStatics())
{
if (condemned == max_gen && sc->promotion)
{
@@ -563,7 +569,7 @@ void GCToEEInterface::GcScanRoots(promote_func* fn, int condemned, int max_gen,
{
STRESS_LOG2(LF_GC | LF_GCROOTS, LL_INFO100, "{ Starting scan of Thread %p ID = %x\n", pThread, pThread->GetThreadId());
- if (GCHeap::GetGCHeap()->IsThreadUsingAllocationContextHeap(
+ if (GCHeapUtilities::GetGCHeap()->IsThreadUsingAllocationContextHeap(
GCToEEInterface::GetAllocContext(pThread), sc->thread_number))
{
sc->thread_under_crawl = pThread;
@@ -693,7 +699,7 @@ void GCToEEInterface::SyncBlockCachePromotionsGranted(int max_gen)
SyncBlockCache::GetSyncBlockCache()->GCDone(FALSE, max_gen);
}
-alloc_context * GCToEEInterface::GetAllocContext(Thread * pThread)
+gc_alloc_context * GCToEEInterface::GetAllocContext(Thread * pThread)
{
WRAPPER_NO_CONTRACT;
return pThread->GetAllocContext();
@@ -839,3 +845,426 @@ Thread* GCToEEInterface::CreateBackgroundThread(GCBackgroundThreadFunction threa
threadStubArgs.thread->DecExternalCount(FALSE);
return NULL;
}
+
+//
+// Diagnostics code
+//
+
+#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+inline BOOL ShouldTrackMovementForProfilerOrEtw()
+{
+#ifdef GC_PROFILING
+ if (CORProfilerTrackGC())
+ return true;
+#endif
+
+#ifdef FEATURE_EVENT_TRACE
+ if (ETW::GCLog::ShouldTrackMovementForEtw())
+ return true;
+#endif
+
+ return false;
+}
+#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+
+void ProfScanRootsHelper(Object** ppObject, ScanContext *pSC, uint32_t dwFlags)
+{
+#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+ Object *pObj = *ppObject;
+ if (dwFlags & GC_CALL_INTERIOR)
+ {
+ pObj = GCHeapUtilities::GetGCHeap()->GetContainingObject(pObj);
+ }
+ ScanRootsHelper(pObj, ppObject, pSC, dwFlags);
+#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+}
+
+// TODO - at some point we would like to completely decouple profiling
+// from ETW tracing using a pattern similar to this, where the
+// ProfilingScanContext has flags about whether or not certain things
+// should be tracked, and each one of these ProfilerShouldXYZ functions
+// will check these flags and determine what to do based upon that.
+// GCProfileWalkHeapWorker can, in turn, call those methods without fear
+// of things being ifdef'd out.
+
+// Returns TRUE if GC profiling is enabled and the profiler
+// should scan dependent handles, FALSE otherwise.
+BOOL ProfilerShouldTrackConditionalWeakTableElements()
+{
+#if defined(GC_PROFILING)
+ return CORProfilerTrackConditionalWeakTableElements();
+#else
+ return FALSE;
+#endif // defined (GC_PROFILING)
+}
+
+// If GC profiling is enabled, informs the profiler that we are done
+// tracing dependent handles.
+void ProfilerEndConditionalWeakTableElementReferences(void* heapId)
+{
+#if defined (GC_PROFILING)
+ g_profControlBlock.pProfInterface->EndConditionalWeakTableElementReferences(heapId);
+#else
+ UNREFERENCED_PARAMETER(heapId);
+#endif // defined (GC_PROFILING)
+}
+
+// If GC profiling is enabled, informs the profiler that we are done
+// tracing root references.
+void ProfilerEndRootReferences2(void* heapId)
+{
+#if defined (GC_PROFILING)
+ g_profControlBlock.pProfInterface->EndRootReferences2(heapId);
+#else
+ UNREFERENCED_PARAMETER(heapId);
+#endif // defined (GC_PROFILING)
+}
+
+void GcScanRootsForProfilerAndETW(promote_func* fn, int condemned, int max_gen, ScanContext* sc)
+{
+ Thread* pThread = NULL;
+ while ((pThread = ThreadStore::GetThreadList(pThread)) != NULL)
+ {
+ sc->thread_under_crawl = pThread;
+#ifdef FEATURE_EVENT_TRACE
+ sc->dwEtwRootKind = kEtwGCRootKindStack;
+#endif // FEATURE_EVENT_TRACE
+ ScanStackRoots(pThread, fn, sc);
+#ifdef FEATURE_EVENT_TRACE
+ sc->dwEtwRootKind = kEtwGCRootKindOther;
+#endif // FEATURE_EVENT_TRACE
+ }
+}
+
+void ScanHandleForProfilerAndETW(Object** pRef, Object* pSec, uint32_t flags, ScanContext* context, BOOL isDependent)
+{
+ ProfilingScanContext* pSC = (ProfilingScanContext*)context;
+
+#ifdef GC_PROFILING
+ // Give the profiler the objectref.
+ if (pSC->fProfilerPinned)
+ {
+ if (!isDependent)
+ {
+ BEGIN_PIN_PROFILER(CORProfilerTrackGC());
+ g_profControlBlock.pProfInterface->RootReference2(
+ (uint8_t *)*pRef,
+ kEtwGCRootKindHandle,
+ (EtwGCRootFlags)flags,
+ pRef,
+ &pSC->pHeapId);
+ END_PIN_PROFILER();
+ }
+ else
+ {
+ BEGIN_PIN_PROFILER(CORProfilerTrackConditionalWeakTableElements());
+ g_profControlBlock.pProfInterface->ConditionalWeakTableElementReference(
+ (uint8_t*)*pRef,
+ (uint8_t*)pSec,
+ pRef,
+ &pSC->pHeapId);
+ END_PIN_PROFILER();
+ }
+ }
+#endif // GC_PROFILING
+
+#if defined(FEATURE_EVENT_TRACE)
+ // Notify ETW of the handle
+ if (ETW::GCLog::ShouldWalkHeapRootsForEtw())
+ {
+ ETW::GCLog::RootReference(
+ pRef,
+ *pRef, // object being rooted
+ pSec, // pSecondaryNodeForDependentHandle
+ isDependent,
+ pSC,
+ 0, // dwGCFlags,
+ flags); // ETW handle flags
+ }
+#endif // defined(FEATURE_EVENT_TRACE)
+}
+
+// This is called only if we've determined that either:
+// a) The Profiling API wants to do a walk of the heap, and it has pinned the
+// profiler in place (so it cannot be detached), and it's thus safe to call into the
+// profiler, OR
+// b) ETW infrastructure wants to do a walk of the heap either to log roots,
+// objects, or both.
+// This can also be called to do a single walk for BOTH a) and b) simultaneously. Since
+// ETW can ask for roots, but not objects
+#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+void GCProfileWalkHeapWorker(BOOL fProfilerPinned, BOOL fShouldWalkHeapRootsForEtw, BOOL fShouldWalkHeapObjectsForEtw)
+{
+ {
+ ProfilingScanContext SC(fProfilerPinned);
+
+ // **** Scan roots: Only scan roots if profiling API wants them or ETW wants them.
+ if (fProfilerPinned || fShouldWalkHeapRootsForEtw)
+ {
+ GcScanRootsForProfilerAndETW(&ProfScanRootsHelper, max_generation, max_generation, &SC);
+ SC.dwEtwRootKind = kEtwGCRootKindFinalizer;
+ GCHeapUtilities::GetGCHeap()->DiagScanFinalizeQueue(&ProfScanRootsHelper, &SC);
+
+ // Handles are kept independent of wks/svr/concurrent builds
+ SC.dwEtwRootKind = kEtwGCRootKindHandle;
+ GCHeapUtilities::GetGCHeap()->DiagScanHandles(&ScanHandleForProfilerAndETW, max_generation, &SC);
+
+ // indicate that regular handle scanning is over, so we can flush the buffered roots
+ // to the profiler. (This is for profapi only. ETW will flush after the
+ // entire heap was is complete, via ETW::GCLog::EndHeapDump.)
+ if (fProfilerPinned)
+ {
+ ProfilerEndRootReferences2(&SC.pHeapId);
+ }
+ }
+
+ // **** Scan dependent handles: only if the profiler supports it or ETW wants roots
+ if ((fProfilerPinned && ProfilerShouldTrackConditionalWeakTableElements()) ||
+ fShouldWalkHeapRootsForEtw)
+ {
+ // GcScanDependentHandlesForProfiler double-checks
+ // CORProfilerTrackConditionalWeakTableElements() before calling into the profiler
+
+ ProfilingScanContext* pSC = &SC;
+
+ // we'll re-use pHeapId (which was either unused (0) or freed by EndRootReferences2
+ // (-1)), so reset it to NULL
+ _ASSERTE((*((size_t *)(&pSC->pHeapId)) == (size_t)(-1)) ||
+ (*((size_t *)(&pSC->pHeapId)) == (size_t)(0)));
+ pSC->pHeapId = NULL;
+
+ GCHeapUtilities::GetGCHeap()->DiagScanDependentHandles(&ScanHandleForProfilerAndETW, max_generation, &SC);
+
+ // indicate that dependent handle scanning is over, so we can flush the buffered roots
+ // to the profiler. (This is for profapi only. ETW will flush after the
+ // entire heap was is complete, via ETW::GCLog::EndHeapDump.)
+ if (fProfilerPinned && ProfilerShouldTrackConditionalWeakTableElements())
+ {
+ ProfilerEndConditionalWeakTableElementReferences(&SC.pHeapId);
+ }
+ }
+
+ ProfilerWalkHeapContext profilerWalkHeapContext(fProfilerPinned, SC.pvEtwContext);
+
+ // **** 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 */);
+ }
+
+#ifdef FEATURE_EVENT_TRACE
+ // **** Done! Indicate to ETW helpers that the heap walk is done, so any buffers
+ // should be flushed into the ETW stream
+ if (fShouldWalkHeapObjectsForEtw || fShouldWalkHeapRootsForEtw)
+ {
+ ETW::GCLog::EndHeapDump(&profilerWalkHeapContext);
+ }
+#endif // FEATURE_EVENT_TRACE
+ }
+}
+#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+
+void GCProfileWalkHeap()
+{
+ BOOL fWalkedHeapForProfiler = FALSE;
+
+#ifdef FEATURE_EVENT_TRACE
+ if (ETW::GCLog::ShouldWalkStaticsAndCOMForEtw())
+ ETW::GCLog::WalkStaticsAndCOMForETW();
+
+ BOOL fShouldWalkHeapRootsForEtw = ETW::GCLog::ShouldWalkHeapRootsForEtw();
+ BOOL fShouldWalkHeapObjectsForEtw = ETW::GCLog::ShouldWalkHeapObjectsForEtw();
+#else // !FEATURE_EVENT_TRACE
+ BOOL fShouldWalkHeapRootsForEtw = FALSE;
+ BOOL fShouldWalkHeapObjectsForEtw = FALSE;
+#endif // FEATURE_EVENT_TRACE
+
+#if defined (GC_PROFILING)
+ {
+ BEGIN_PIN_PROFILER(CORProfilerTrackGC());
+ GCProfileWalkHeapWorker(TRUE /* fProfilerPinned */, fShouldWalkHeapRootsForEtw, fShouldWalkHeapObjectsForEtw);
+ fWalkedHeapForProfiler = TRUE;
+ END_PIN_PROFILER();
+ }
+#endif // defined (GC_PROFILING)
+
+#if defined (GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+ // we need to walk the heap if one of GC_PROFILING or FEATURE_EVENT_TRACE
+ // is defined, since both of them make use of the walk heap worker.
+ if (!fWalkedHeapForProfiler &&
+ (fShouldWalkHeapRootsForEtw || fShouldWalkHeapObjectsForEtw))
+ {
+ GCProfileWalkHeapWorker(FALSE /* fProfilerPinned */, fShouldWalkHeapRootsForEtw, fShouldWalkHeapObjectsForEtw);
+ }
+#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+}
+
+void WalkFReachableObjects(BOOL isCritical, void* objectID)
+{
+ g_profControlBlock.pProfInterface->FinalizeableObjectQueued(isCritical, (ObjectID)objectID);
+}
+
+static fq_walk_fn g_FQWalkFn = &WalkFReachableObjects;
+
+void GCToEEInterface::DiagGCStart(int gen, bool isInduced)
+{
+#ifdef GC_PROFILING
+ DiagUpdateGenerationBounds();
+ GarbageCollectionStartedCallback(gen, isInduced);
+ {
+ BEGIN_PIN_PROFILER(CORProfilerTrackGC());
+ size_t context = 0;
+
+ // 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);
+
+ // Notify that we've reached the end of the Gen 0 scan
+ g_profControlBlock.pProfInterface->EndAllocByClass(&context);
+ END_PIN_PROFILER();
+ }
+
+#endif // GC_PROFILING
+}
+
+void GCToEEInterface::DiagUpdateGenerationBounds()
+{
+#ifdef GC_PROFILING
+ if (CORProfilerTrackGC())
+ UpdateGenerationBounds();
+#endif // GC_PROFILING
+}
+
+void GCToEEInterface::DiagGCEnd(size_t index, int gen, int reason, bool fConcurrent)
+{
+#ifdef GC_PROFILING
+ if (!fConcurrent)
+ {
+ GCProfileWalkHeap();
+ DiagUpdateGenerationBounds();
+ GarbageCollectionFinishedCallback();
+ }
+#endif // GC_PROFILING
+}
+
+void GCToEEInterface::DiagWalkFReachableObjects(void* gcContext)
+{
+#ifdef GC_PROFILING
+ if (CORProfilerTrackGC())
+ {
+ BEGIN_PIN_PROFILER(CORProfilerPresent());
+ GCHeapUtilities::GetGCHeap()->DiagWalkFinalizeQueue(gcContext, g_FQWalkFn);
+ END_PIN_PROFILER();
+ }
+#endif //GC_PROFILING
+}
+
+// Note on last parameter: when calling this for bgc, only ETW
+// should be sending these events so that existing profapi profilers
+// don't get confused.
+void WalkMovedReferences(uint8_t* begin, uint8_t* end,
+ ptrdiff_t reloc,
+ size_t context,
+ BOOL fCompacting,
+ BOOL fBGC)
+{
+ ETW::GCLog::MovedReference(begin, end,
+ (fCompacting ? reloc : 0),
+ context,
+ fCompacting,
+ !fBGC);
+}
+
+void GCToEEInterface::DiagWalkSurvivors(void* gcContext)
+{
+#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+ if (ShouldTrackMovementForProfilerOrEtw())
+ {
+ size_t context = 0;
+ ETW::GCLog::BeginMovedReferences(&context);
+ GCHeapUtilities::GetGCHeap()->DiagWalkSurvivorsWithType(gcContext, &WalkMovedReferences, context, walk_for_gc);
+ ETW::GCLog::EndMovedReferences(context);
+ }
+#endif //GC_PROFILING || FEATURE_EVENT_TRACE
+}
+
+void GCToEEInterface::DiagWalkLOHSurvivors(void* gcContext)
+{
+#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+ if (ShouldTrackMovementForProfilerOrEtw())
+ {
+ size_t context = 0;
+ ETW::GCLog::BeginMovedReferences(&context);
+ GCHeapUtilities::GetGCHeap()->DiagWalkSurvivorsWithType(gcContext, &WalkMovedReferences, context, walk_for_loh);
+ ETW::GCLog::EndMovedReferences(context);
+ }
+#endif //GC_PROFILING || FEATURE_EVENT_TRACE
+}
+
+void GCToEEInterface::DiagWalkBGCSurvivors(void* gcContext)
+{
+#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
+ if (ShouldTrackMovementForProfilerOrEtw())
+ {
+ size_t context = 0;
+ ETW::GCLog::BeginMovedReferences(&context);
+ GCHeapUtilities::GetGCHeap()->DiagWalkSurvivorsWithType(gcContext, &WalkMovedReferences, context, walk_for_bgc);
+ ETW::GCLog::EndMovedReferences(context);
+ }
+#endif //GC_PROFILING || FEATURE_EVENT_TRACE
+}
+
+void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)
+{
+ assert(args != nullptr);
+ switch (args->operation)
+ {
+ case WriteBarrierOp::StompResize:
+ // StompResize requires a new card table, a new lowest address, and
+ // a new highest address
+ assert(args->card_table != nullptr);
+ assert(args->lowest_address != nullptr);
+ assert(args->highest_address != nullptr);
+ g_card_table = args->card_table;
+ ::StompWriteBarrierResize(args->is_runtime_suspended, args->requires_upper_bounds_check);
+
+ // We need to make sure that other threads executing checked write barriers
+ // will see the g_card_table update before g_lowest/highest_address updates.
+ // Otherwise, the checked write barrier may AV accessing the old card table
+ // with address that it does not cover. Write barriers access card table
+ // without memory barriers for performance reasons, so we need to flush
+ // the store buffers here.
+ FlushProcessWriteBuffers();
+
+ g_lowest_address = args->lowest_address;
+ VolatileStore(&g_highest_address, args->highest_address);
+ return;
+ case WriteBarrierOp::StompEphemeral:
+ // StompEphemeral requires a new ephemeral low and a new ephemeral high
+ assert(args->ephemeral_lo != nullptr);
+ assert(args->ephemeral_hi != nullptr);
+ g_ephemeral_low = args->ephemeral_lo;
+ g_ephemeral_high = args->ephemeral_hi;
+ ::StompWriteBarrierEphemeral(args->is_runtime_suspended);
+ return;
+ case WriteBarrierOp::Initialize:
+ // This operation should only be invoked once, upon initialization.
+ assert(g_card_table == nullptr);
+ assert(g_lowest_address == nullptr);
+ assert(g_highest_address == nullptr);
+ assert(args->card_table != nullptr);
+ assert(args->lowest_address != nullptr);
+ assert(args->highest_address != nullptr);
+ assert(args->is_runtime_suspended && "the runtime must be suspended here!");
+ assert(!args->requires_upper_bounds_check && "the ephemeral generation must be at the top of the heap!");
+
+ g_card_table = args->card_table;
+ FlushProcessWriteBuffers();
+ g_lowest_address = args->lowest_address;
+ VolatileStore(&g_highest_address, args->highest_address);
+ ::StompWriteBarrierResize(true, false);
+ return;
+ default:
+ assert(!"unknown WriteBarrierOp enum");
+ }
+}
diff --git a/src/vm/gcenv.ee.h b/src/vm/gcenv.ee.h
index 1d6c9bf78b..f4312217ec 100644
--- a/src/vm/gcenv.ee.h
+++ b/src/vm/gcenv.ee.h
@@ -2,4 +2,48 @@
// 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/env/gcenv.ee.h"
+#ifndef _GCENV_EE_H_
+#define _GCENV_EE_H_
+
+#include "gcinterface.h"
+
+#ifdef FEATURE_STANDALONE_GC
+
+class GCToEEInterface : public IGCToCLR {
+public:
+ GCToEEInterface() = default;
+ ~GCToEEInterface() = default;
+
+ void SuspendEE(SUSPEND_REASON reason);
+ void RestartEE(bool bFinishedGC);
+ void GcScanRoots(promote_func* fn, int condemned, int max_gen, ScanContext* sc);
+ void GcStartWork(int condemned, int max_gen);
+ void AfterGcScanRoots(int condemned, int max_gen, ScanContext* sc);
+ void GcBeforeBGCSweepWork();
+ void GcDone(int condemned);
+ bool RefCountedHandleCallbacks(Object * pObject);
+ void SyncBlockCacheWeakPtrScan(HANDLESCANPROC scanProc, uintptr_t lp1, uintptr_t lp2);
+ void SyncBlockCacheDemote(int max_gen);
+ void SyncBlockCachePromotionsGranted(int max_gen);
+ bool IsPreemptiveGCDisabled(Thread * pThread);
+ void EnablePreemptiveGC(Thread * pThread);
+ void DisablePreemptiveGC(Thread * pThread);
+ gc_alloc_context * GetAllocContext(Thread * pThread);
+ bool CatchAtSafePoint(Thread * pThread);
+ void GcEnumAllocContexts(enum_alloc_context_func* fn, void* param);
+ Thread* CreateBackgroundThread(GCBackgroundThreadFunction threadStart, void* arg);
+
+ // Diagnostics methods.
+ void DiagGCStart(int gen, bool isInduced);
+ void DiagUpdateGenerationBounds();
+ void DiagGCEnd(size_t index, int gen, int reason, bool fConcurrent);
+ void DiagWalkFReachableObjects(void* gcContext);
+ void DiagWalkSurvivors(void* gcContext);
+ void DiagWalkLOHSurvivors(void* gcContext);
+ void DiagWalkBGCSurvivors(void* gcContext);
+ void StompWriteBarrier(WriteBarrierParameters* args);
+};
+
+#endif // FEATURE_STANDALONE_GC
+
+#endif // _GCENV_EE_H_ \ No newline at end of file
diff --git a/src/vm/gcenv.h b/src/vm/gcenv.h
index 08dcc711ae..ad5baa262e 100644
--- a/src/vm/gcenv.h
+++ b/src/vm/gcenv.h
@@ -48,8 +48,6 @@
#include "util.hpp"
-#include "gcenv.ee.h"
-#include "gcenv.os.h"
#include "gcenv.interlocked.h"
#include "gcenv.interlocked.inl"
diff --git a/src/vm/gcenv.os.cpp b/src/vm/gcenv.os.cpp
index 73b21a7a0b..52789b835c 100644
--- a/src/vm/gcenv.os.cpp
+++ b/src/vm/gcenv.os.cpp
@@ -18,6 +18,12 @@
#include <Psapi.h>
#endif
+#ifdef Sleep
+#undef Sleep
+#endif // Sleep
+
+#include "env/gcenv.os.h"
+
#define MAX_PTR ((uint8_t*)(~(ptrdiff_t)0))
// Initialize the interface implementation
@@ -160,7 +166,7 @@ void GCToOSInterface::YieldThread(uint32_t switchCount)
// flags - flags to control special settings like write watching
// Return:
// Starting virtual address of the reserved range
-void* GCToOSInterface::VirtualReserve(void* address, size_t size, size_t alignment, uint32_t flags)
+void* GCToOSInterface::VirtualReserve(size_t size, size_t alignment, uint32_t flags)
{
LIMITED_METHOD_CONTRACT;
@@ -249,7 +255,7 @@ bool GCToOSInterface::SupportsWriteWatch()
// check if the OS supports write-watch.
// Drawbridge does not support write-watch so we still need to do the runtime detection for them.
// Otherwise, all currently supported OSes do support write-watch.
- void* mem = VirtualReserve (0, g_SystemInfo.dwAllocationGranularity, 0, VirtualReserveFlags::WriteWatch);
+ void* mem = VirtualReserve (g_SystemInfo.dwAllocationGranularity, 0, VirtualReserveFlags::WriteWatch);
if (mem != NULL)
{
VirtualRelease (mem, g_SystemInfo.dwAllocationGranularity);
@@ -364,23 +370,6 @@ 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);
-#ifdef FEATURE_CORECLR
-// For coresys we need to look for an API in some apiset dll on win8 if we can't find it
-// in the traditional dll.
-HINSTANCE LoadDllForAPI(WCHAR* dllTraditional, WCHAR* dllApiSet)
-{
- HINSTANCE hinst = WszLoadLibrary(dllTraditional);
-
- if (!hinst)
- {
- if(RunningOnWin8())
- hinst = WszLoadLibrary(dllApiSet);
- }
-
- return hinst;
-}
-#endif
-
static size_t GetRestrictedPhysicalMemoryLimit()
{
LIMITED_METHOD_CONTRACT;
@@ -392,10 +381,7 @@ static size_t GetRestrictedPhysicalMemoryLimit()
size_t job_physical_memory_limit = (size_t)MAX_PTR;
BOOL in_job_p = FALSE;
#ifdef FEATURE_CORECLR
- HINSTANCE hinstApiSetPsapiOrKernel32 = 0;
- // these 2 modules will need to be freed no matter what as we only use them locally in this method.
- HINSTANCE hinstApiSetJob1OrKernel32 = 0;
- HINSTANCE hinstApiSetJob2OrKernel32 = 0;
+ HINSTANCE hinstKernel32 = 0;
#else
HINSTANCE hinstPsapi = 0;
#endif
@@ -403,17 +389,7 @@ static size_t GetRestrictedPhysicalMemoryLimit()
PIS_PROCESS_IN_JOB GCIsProcessInJob = 0;
PQUERY_INFORMATION_JOB_OBJECT GCQueryInformationJobObject = 0;
-#ifdef FEATURE_CORECLR
- hinstApiSetJob1OrKernel32 = LoadDllForAPI(L"kernel32.dll", L"api-ms-win-core-job-l1-1-0.dll");
- if (!hinstApiSetJob1OrKernel32)
- goto exit;
-
- GCIsProcessInJob = (PIS_PROCESS_IN_JOB)GetProcAddress(hinstApiSetJob1OrKernel32, "IsProcessInJob");
- if (!GCIsProcessInJob)
- goto exit;
-#else
GCIsProcessInJob = &(::IsProcessInJob);
-#endif
if (!GCIsProcessInJob(GetCurrentProcess(), NULL, &in_job_p))
goto exit;
@@ -421,11 +397,11 @@ static size_t GetRestrictedPhysicalMemoryLimit()
if (in_job_p)
{
#ifdef FEATURE_CORECLR
- hinstApiSetPsapiOrKernel32 = LoadDllForAPI(L"kernel32.dll", L"api-ms-win-core-psapi-l1-1-0");
- if (!hinstApiSetPsapiOrKernel32)
+ hinstKernel32 = WszLoadLibrary(L"kernel32.dll");
+ if (!hinstKernel32)
goto exit;
- GCGetProcessMemoryInfo = (PGET_PROCESS_MEMORY_INFO)GetProcAddress(hinstApiSetPsapiOrKernel32, "K32GetProcessMemoryInfo");
+ 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
@@ -439,15 +415,7 @@ static size_t GetRestrictedPhysicalMemoryLimit()
if (!GCGetProcessMemoryInfo)
goto exit;
-#ifdef FEATURE_CORECLR
- hinstApiSetJob2OrKernel32 = LoadDllForAPI(L"kernel32.dll", L"api-ms-win-core-job-l2-1-0");
- if (!hinstApiSetJob2OrKernel32)
- goto exit;
-
- GCQueryInformationJobObject = (PQUERY_INFORMATION_JOB_OBJECT)GetProcAddress(hinstApiSetJob2OrKernel32, "QueryInformationJobObject");
-#else
GCQueryInformationJobObject = &(::QueryInformationJobObject);
-#endif
if (!GCQueryInformationJobObject)
goto exit;
@@ -490,19 +458,12 @@ static size_t GetRestrictedPhysicalMemoryLimit()
}
exit:
-#ifdef FEATURE_CORECLR
- if (hinstApiSetJob1OrKernel32)
- FreeLibrary(hinstApiSetJob1OrKernel32);
- if (hinstApiSetJob2OrKernel32)
- FreeLibrary(hinstApiSetJob2OrKernel32);
-#endif
-
if (job_physical_memory_limit == (size_t)MAX_PTR)
{
job_physical_memory_limit = 0;
#ifdef FEATURE_CORECLR
- FreeLibrary(hinstApiSetPsapiOrKernel32);
+ FreeLibrary(hinstKernel32);
#else
FreeLibrary(hinstPsapi);
#endif
@@ -633,7 +594,7 @@ struct GCThreadStubParam
};
// GC thread stub to convert GC thread function to an OS specific thread function
-static DWORD GCThreadStub(void* param)
+static DWORD __stdcall GCThreadStub(void* param)
{
WRAPPER_NO_CONTRACT;
diff --git a/src/vm/gcheaputilities.cpp b/src/vm/gcheaputilities.cpp
new file mode 100644
index 0000000000..ac24fa34ce
--- /dev/null
+++ b/src/vm/gcheaputilities.cpp
@@ -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.
+
+#include "common.h"
+#include "gcheaputilities.h"
+
+// These globals are variables used within the GC and maintained
+// by the EE for use in write barriers. It is the responsibility
+// of the GC to communicate updates to these globals to the EE through
+// GCToEEInterface::StompWriteBarrierResize and GCToEEInterface::StompWriteBarrierEphemeral.
+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);
+uint8_t* g_ephemeral_low = (uint8_t*)1;
+uint8_t* g_ephemeral_high = (uint8_t*)~0;
+
+// This is the global GC heap, maintained by the VM.
+GPTR_IMPL(IGCHeap, g_pGCHeap); \ No newline at end of file
diff --git a/src/vm/gcheaputilities.h b/src/vm/gcheaputilities.h
new file mode 100644
index 0000000000..e5883fc919
--- /dev/null
+++ b/src/vm/gcheaputilities.h
@@ -0,0 +1,129 @@
+// Licensed to the .NET Foundation under one or more 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 _GCHEAPUTILITIES_H_
+#define _GCHEAPUTILITIES_H_
+
+#include "gcinterface.h"
+
+// The singular heap instance.
+GPTR_DECL(IGCHeap, g_pGCHeap);
+
+// GCHeapUtilities provides a number of static methods
+// that operate on the global heap instance. It can't be
+// instantiated.
+class GCHeapUtilities {
+public:
+ // Retrieves the GC heap.
+ inline static IGCHeap* GetGCHeap()
+ {
+ LIMITED_METHOD_CONTRACT;
+
+ assert(g_pGCHeap != nullptr);
+ return g_pGCHeap;
+ }
+
+ // Returns true if the heap has been initialized, false otherwise.
+ inline static bool IsGCHeapInitialized()
+ {
+ LIMITED_METHOD_CONTRACT;
+
+ return g_pGCHeap != nullptr;
+ }
+
+ // Returns true if a the heap is initialized and a garbage collection
+ // is in progress, false otherwise.
+ inline static BOOL IsGCInProgress(BOOL bConsiderGCStart = FALSE)
+ {
+ WRAPPER_NO_CONTRACT;
+
+ return (IsGCHeapInitialized() ? GetGCHeap()->IsGCInProgressHelper(bConsiderGCStart) : false);
+ }
+
+ // Returns true if we should be competing marking for statics. This
+ // influences the behavior of `GCToEEInterface::GcScanRoots`.
+ inline static BOOL MarkShouldCompeteForStatics()
+ {
+ WRAPPER_NO_CONTRACT;
+
+ return IsServerHeap() && g_SystemInfo.dwNumberOfProcessors >= 2;
+ }
+
+ // Waits until a GC is complete, if the heap has been initialized.
+ inline static void WaitForGCCompletion(BOOL bConsiderGCStart = FALSE)
+ {
+ WRAPPER_NO_CONTRACT;
+
+ if (IsGCHeapInitialized())
+ 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
+ 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()
+ {
+ WRAPPER_NO_CONTRACT;
+
+ return IGCHeap::maxGeneration;
+ }
+
+private:
+ // This class should never be instantiated.
+ GCHeapUtilities() = delete;
+};
+
+#ifndef DACCESS_COMPILE
+extern "C" {
+#endif // !DACCESS_COMPILE
+GPTR_DECL(uint8_t,g_lowest_address);
+GPTR_DECL(uint8_t,g_highest_address);
+GPTR_DECL(uint32_t,g_card_table);
+#ifndef DACCESS_COMPILE
+}
+#endif // !DACCESS_COMPILE
+
+extern "C" uint8_t* g_ephemeral_low;
+extern "C" uint8_t* g_ephemeral_high;
+
+#endif // _GCHEAPUTILITIES_H_ \ No newline at end of file
diff --git a/src/vm/gchelpers.cpp b/src/vm/gchelpers.cpp
index bf81847716..20a3a29540 100644
--- a/src/vm/gchelpers.cpp
+++ b/src/vm/gchelpers.cpp
@@ -16,7 +16,7 @@
#include "threads.h"
#include "eetwain.h"
#include "eeconfig.h"
-#include "gc.h"
+#include "gcheaputilities.h"
#include "corhost.h"
#include "threads.h"
#include "fieldmarshaler.h"
@@ -51,15 +51,50 @@
orObject = (ArrayBase *) OBJECTREFToObject(objref);
-inline alloc_context* GetThreadAllocContext()
+inline gc_alloc_context* GetThreadAllocContext()
{
WRAPPER_NO_CONTRACT;
- assert(GCHeap::UseAllocationContexts());
+ assert(GCHeapUtilities::UseAllocationContexts());
return & GetThread()->m_alloc_context;
}
+// 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
+// the OOM was not from memory pressure but from an object
+// being too large.
+inline void CheckObjectSize(size_t alloc_size)
+{
+ CONTRACTL {
+ THROWS;
+ GC_TRIGGERS;
+ } CONTRACTL_END;
+
+ size_t max_object_size;
+#ifdef BIT64
+ if (g_pConfig->GetGCAllowVeryLargeObjects())
+ {
+ max_object_size = (INT64_MAX - 7 - min_obj_size);
+ }
+ else
+#endif // BIT64
+ {
+ max_object_size = (INT32_MAX - 7 - min_obj_size);
+ }
+
+ if (alloc_size >= max_object_size)
+ {
+ if (g_pConfig->IsGCBreakOnOOMEnabled())
+ {
+ DebugBreak();
+ }
+
+ ThrowOutOfMemoryDimensionsExceeded();
+ }
+}
+
// There are only three ways to get into allocate an object.
// * Call optimized helpers that were generated on the fly. This is how JIT compiled code does most
@@ -98,14 +133,21 @@ inline Object* Alloc(size_t size, BOOL bFinalize, BOOL bContainsPointers )
(bFinalize ? GC_ALLOC_FINALIZE : 0));
Object *retVal = NULL;
+ CheckObjectSize(size);
// 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 (GCHeap::UseAllocationContexts())
- retVal = GCHeap::GetGCHeap()->Alloc(GetThreadAllocContext(), size, flags);
+ if (GCHeapUtilities::UseAllocationContexts())
+ retVal = GCHeapUtilities::GetGCHeap()->Alloc(GetThreadAllocContext(), size, flags);
else
- retVal = GCHeap::GetGCHeap()->Alloc(size, flags);
+ retVal = GCHeapUtilities::GetGCHeap()->Alloc(size, flags);
+
+ if (!retVal)
+ {
+ ThrowOutOfMemory();
+ }
+
END_INTERIOR_STACK_PROBE;
return retVal;
}
@@ -126,14 +168,20 @@ inline Object* AllocAlign8(size_t size, BOOL bFinalize, BOOL bContainsPointers,
(bAlignBias ? GC_ALLOC_ALIGN8_BIAS : 0));
Object *retVal = NULL;
+ CheckObjectSize(size);
// 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 (GCHeap::UseAllocationContexts())
- retVal = GCHeap::GetGCHeap()->AllocAlign8(GetThreadAllocContext(), size, flags);
+ if (GCHeapUtilities::UseAllocationContexts())
+ retVal = GCHeapUtilities::GetGCHeap()->AllocAlign8(GetThreadAllocContext(), size, flags);
else
- retVal = GCHeap::GetGCHeap()->AllocAlign8(size, flags);
+ retVal = GCHeapUtilities::GetGCHeap()->AllocAlign8(size, flags);
+
+ if (!retVal)
+ {
+ ThrowOutOfMemory();
+ }
END_INTERIOR_STACK_PROBE;
return retVal;
@@ -169,11 +217,18 @@ inline Object* AllocLHeap(size_t size, BOOL bFinalize, BOOL bContainsPointers )
(bFinalize ? GC_ALLOC_FINALIZE : 0));
Object *retVal = NULL;
+ CheckObjectSize(size);
// 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));
- retVal = GCHeap::GetGCHeap()->AllocLHeap(size, flags);
+ retVal = GCHeapUtilities::GetGCHeap()->AllocLHeap(size, flags);
+
+ if (!retVal)
+ {
+ ThrowOutOfMemory();
+ }
+
END_INTERIOR_STACK_PROBE;
return retVal;
}
@@ -427,7 +482,7 @@ OBJECTREF AllocateArrayEx(TypeHandle arrayType, INT32 *pArgs, DWORD dwNumArgs, B
if (bAllocateInLargeHeap ||
(totalSize >= LARGE_OBJECT_SIZE))
{
- GCHeap::GetGCHeap()->PublishObject((BYTE*)orArray);
+ GCHeapUtilities::GetGCHeap()->PublishObject((BYTE*)orArray);
}
#ifdef _LOGALLOC
@@ -651,7 +706,7 @@ OBJECTREF FastAllocatePrimitiveArray(MethodTable* pMT, DWORD cElements, BOOL b
if (bPublish)
{
- GCHeap::GetGCHeap()->PublishObject((BYTE*)orObject);
+ GCHeapUtilities::GetGCHeap()->PublishObject((BYTE*)orObject);
}
// Notify the profiler of the allocation
@@ -860,7 +915,7 @@ STRINGREF SlowAllocateString( DWORD cchStringLength )
if (ObjectSize >= LARGE_OBJECT_SIZE)
{
- GCHeap::GetGCHeap()->PublishObject((BYTE*)orObject);
+ GCHeapUtilities::GetGCHeap()->PublishObject((BYTE*)orObject);
}
// Notify the profiler of the allocation
@@ -951,8 +1006,10 @@ 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
@@ -1000,7 +1057,7 @@ OBJECTREF AllocateObject(MethodTable *pMT
if ((baseSize >= LARGE_OBJECT_SIZE))
{
orObject->SetMethodTableForLargeObject(pMT);
- GCHeap::GetGCHeap()->PublishObject((BYTE*)orObject);
+ GCHeapUtilities::GetGCHeap()->PublishObject((BYTE*)orObject);
}
else
{
@@ -1234,7 +1291,7 @@ extern "C" HCIMPL2_RAW(VOID, JIT_WriteBarrier, Object **dst, Object *ref)
*dst = ref;
// If the store above succeeded, "dst" should be in the heap.
- assert(GCHeap::GetGCHeap()->IsHeapPointer((void*)dst));
+ assert(GCHeapUtilities::GetGCHeap()->IsHeapPointer((void*)dst));
#ifdef WRITE_BARRIER_CHECK
updateGCShadow(dst, ref); // support debugging write barrier
@@ -1280,7 +1337,7 @@ extern "C" HCIMPL2_RAW(VOID, JIT_WriteBarrierEnsureNonHeapTarget, Object **dst,
STATIC_CONTRACT_THROWS;
STATIC_CONTRACT_GC_NOTRIGGER;
- assert(!GCHeap::GetGCHeap()->IsHeapPointer((void*)dst));
+ assert(!GCHeapUtilities::GetGCHeap()->IsHeapPointer((void*)dst));
// no HELPER_METHOD_FRAME because we are MODE_COOPERATIVE, GC_NOTRIGGER
diff --git a/src/vm/gchost.cpp b/src/vm/gchost.cpp
index 4f7d52f805..b51f2459fd 100644
--- a/src/vm/gchost.cpp
+++ b/src/vm/gchost.cpp
@@ -22,7 +22,7 @@
#include "corhost.h"
#include "excep.h"
#include "field.h"
-#include "gc.h"
+#include "gcheaputilities.h"
#if !defined(FEATURE_CORECLR)
inline size_t SizeInKBytes(size_t cbSize)
@@ -48,7 +48,7 @@ HRESULT CorGCHost::_SetGCSegmentSize(SIZE_T SegmentSize)
HRESULT hr = S_OK;
// Sanity check the value, it must be a power of two and big enough.
- if (!GCHeap::IsValidSegmentSize(SegmentSize))
+ if (!GCHeapUtilities::GetGCHeap()->IsValidSegmentSize(SegmentSize))
{
hr = E_INVALIDARG;
}
@@ -74,7 +74,7 @@ HRESULT CorGCHost::_SetGCMaxGen0Size(SIZE_T MaxGen0Size)
HRESULT hr = S_OK;
// Sanity check the value is at least large enough.
- if (!GCHeap::IsValidGen0MaxSize(MaxGen0Size))
+ if (!GCHeapUtilities::GetGCHeap()->IsValidGen0MaxSize(MaxGen0Size))
{
hr = E_INVALIDARG;
}
@@ -151,7 +151,7 @@ HRESULT CorGCHost::Collect(
HRESULT hr = E_FAIL;
- if (Generation > (int) GCHeap::GetGCHeap()->GetMaxGeneration())
+ if (Generation > (int) GCHeapUtilities::GetGCHeap()->GetMaxGeneration())
hr = E_INVALIDARG;
else
{
@@ -170,7 +170,7 @@ HRESULT CorGCHost::Collect(
EX_TRY
{
- hr = GCHeap::GetGCHeap()->GarbageCollect(Generation);
+ hr = GCHeapUtilities::GetGCHeap()->GarbageCollect(Generation);
}
EX_CATCH
{
@@ -268,7 +268,7 @@ HRESULT CorGCHost::SetVirtualMemLimit(
}
CONTRACTL_END;
- GCHeap::GetGCHeap()->SetReservedVMLimit (sztMaxVirtualMemMB);
+ GCHeapUtilities::GetGCHeap()->SetReservedVMLimit (sztMaxVirtualMemMB);
return (S_OK);
}
#endif // !defined(FEATURE_CORECLR)
diff --git a/src/vm/gcinfodecoder.cpp b/src/vm/gcinfodecoder.cpp
index ef237a2768..89f470499e 100644
--- a/src/vm/gcinfodecoder.cpp
+++ b/src/vm/gcinfodecoder.cpp
@@ -4,6 +4,7 @@
#include "common.h"
+
#include "gcinfodecoder.h"
#ifdef USE_GC_INFO_DECODER
@@ -17,7 +18,7 @@
#endif
#ifndef GCINFODECODER_CONTRACT
-#define GCINFODECODER_CONTRACT(contract) contract
+#define GCINFODECODER_CONTRACT LIMITED_METHOD_CONTRACT
#endif // !GCINFODECODER_CONTRACT
@@ -68,7 +69,7 @@
}
#endif // !LOG_PIPTR
-bool GcInfoDecoder::SetIsInterruptibleCB (UINT32 startOffset, UINT32 stopOffset, LPVOID hCallback)
+bool GcInfoDecoder::SetIsInterruptibleCB (UINT32 startOffset, UINT32 stopOffset, void * hCallback)
{
GcInfoDecoder *pThis = (GcInfoDecoder*)hCallback;
@@ -282,11 +283,11 @@ GcInfoDecoder::GcInfoDecoder(
if (hasReversePInvokeFrame)
{
- m_ReversePInvokeFrameSlot = (INT32)m_Reader.DecodeVarLengthSigned(REVERSE_PINVOKE_FRAME_ENCBASE);
+ m_ReversePInvokeFrameStackSlot = (INT32)m_Reader.DecodeVarLengthSigned(REVERSE_PINVOKE_FRAME_ENCBASE);
}
else
{
- m_ReversePInvokeFrameSlot = NO_REVERSE_PINVOKE_FRAME;
+ m_ReversePInvokeFrameStackSlot = NO_REVERSE_PINVOKE_FRAME;
}
@@ -426,14 +427,14 @@ UINT32 GcInfoDecoder::FindSafePoint(UINT32 breakOffset)
return result;
}
-void GcInfoDecoder::EnumerateSafePoints(EnumerateSafePointsCallback *pCallback, LPVOID hCallback)
+void GcInfoDecoder::EnumerateSafePoints(EnumerateSafePointsCallback *pCallback, void * hCallback)
{
if(m_NumSafePoints == 0)
return;
const UINT32 numBitsPerOffset = CeilOfLog2(NORMALIZE_CODE_OFFSET(m_CodeLength));
- for(UINT i = 0; i < m_NumSafePoints; i++)
+ for(UINT32 i = 0; i < m_NumSafePoints; i++)
{
UINT32 normOffset = (UINT32)m_Reader.Read(numBitsPerOffset);
UINT32 offset = DENORMALIZE_CODE_OFFSET(normOffset) + 2;
@@ -450,7 +451,7 @@ void GcInfoDecoder::EnumerateSafePoints(EnumerateSafePointsCallback *pCallback,
void GcInfoDecoder::EnumerateInterruptibleRanges (
EnumerateInterruptibleRangesCallback *pCallback,
- LPVOID hCallback)
+ void * hCallback)
{
// If no info is found for the call site, we default to fully-interruptbile
LOG((LF_GCROOTS, LL_INFO1000000, "No GC info found for call site at offset %x. Defaulting to fully-interruptible information.\n", (int) m_InstructionOffset));
@@ -488,10 +489,10 @@ INT32 GcInfoDecoder::GetGSCookieStackSlot()
return m_GSCookieStackSlot;
}
-INT32 GcInfoDecoder::GetReversePInvokeStackSlot()
+INT32 GcInfoDecoder::GetReversePInvokeFrameStackSlot()
{
_ASSERTE(m_Flags & DECODE_REVERSE_PINVOKE_VAR);
- return m_ReversePInvokeStackSlot;
+ return m_ReversePInvokeFrameStackSlot;
}
UINT32 GcInfoDecoder::GetGSCookieValidRangeStart()
@@ -581,7 +582,7 @@ bool GcInfoDecoder::EnumerateLiveSlots(
bool reportScratchSlots,
unsigned inputFlags,
GCEnumCallback pCallBack,
- LPVOID hCallBack
+ void * hCallBack
)
{
@@ -615,24 +616,6 @@ bool GcInfoDecoder::EnumerateLiveSlots(
UINT32 normBreakOffset = NORMALIZE_CODE_OFFSET(m_InstructionOffset);
-#if 0
- // This is currently disabled because sometimes on IA64 we need
- // to make call sites non-interruptible
- // TODO: review this
-#ifdef _DEBUG
- if(!executionAborted)
- {
- GcInfoDecoder _decoder2(
- m_GcInfoAddress,
- DECODE_INTERRUPTIBILITY,
- m_InstructionOffset
- );
-
- _ASSERTE(_decoder2.IsInterruptible());
- }
-#endif
-#endif
-
// Normalized break offset
// Relative to interruptible ranges #if PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED
#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED
@@ -645,48 +628,6 @@ bool GcInfoDecoder::EnumerateLiveSlots(
#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED
-#ifndef DISABLE_EH_VECTORS
- if(m_SafePointIndex < m_NumSafePoints || executionAborted)
- {
- // Skip interruptibility information
- for(UINT32 i=0; i<m_NumInterruptibleRanges; i++)
- {
- m_Reader.DecodeVarLengthUnsigned( INTERRUPTIBLE_RANGE_DELTA1_ENCBASE );
- m_Reader.DecodeVarLengthUnsigned( INTERRUPTIBLE_RANGE_DELTA2_ENCBASE );
- }
- }
- else
- {
- //
- // We didn't find the break offset in the list of call sites
- // and are not in an executionAborted frame
- // So we must have fully-interruptible information
- //
- _ASSERTE(m_NumInterruptibleRanges);
-
-#ifdef _DEBUG
- int dbgCountIntersections = 0;
-#endif
- 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)
- {
- _ASSERTE(pseudoBreakOffset == 0);
- _ASSERTE(dbgCountIntersections++ == 0);
- pseudoBreakOffset = numInterruptibleLength + normBreakOffset - normStart;
- }
- numInterruptibleLength += normStopDelta;
- lastNormStop = normStop;
- }
- _ASSERTE(dbgCountIntersections == 1);
- }
-#else // DISABLE_EH_VECTORS
if(m_SafePointIndex < m_NumSafePoints && !executionAborted)
{
// Skip interruptibility information
@@ -736,7 +677,6 @@ bool GcInfoDecoder::EnumerateLiveSlots(
goto ExitSuccess;
}
}
-#endif // DISABLE_EH_VECTORS
#else // !PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED
// Skip interruptibility information
@@ -778,52 +718,8 @@ bool GcInfoDecoder::EnumerateLiveSlots(
if(executionAborted)
{
-#ifndef DISABLE_EH_VECTORS
- m_Reader.Skip(m_NumSafePoints * numSlots);
-
- UINT32 numClauses = (UINT32) m_Reader.DecodeVarLengthUnsigned(NUM_EH_CLAUSES_ENCBASE);
-
- if(numClauses)
- {
- UINT32 numBitsPerOffset = CeilOfLog2(NORMALIZE_CODE_OFFSET(m_CodeLength));
-
- for(UINT32 i = 0; i < numClauses; i++)
- {
- UINT32 startOffset = (UINT32) DENORMALIZE_CODE_OFFSET(m_Reader.Read(numBitsPerOffset));
- UINT32 stopOffset = (UINT32) DENORMALIZE_CODE_OFFSET(m_Reader.Read(numBitsPerOffset) + 1);
-
- if(m_InstructionOffset >= startOffset
- && m_InstructionOffset < stopOffset)
- {
- for(UINT32 slotIndex = 0; slotIndex < numSlots; slotIndex++)
- {
- if(m_Reader.ReadOneFast())
- {
- ReportSlotToGC(
- slotDecoder,
- slotIndex,
- pRD,
- reportScratchSlots,
- inputFlags,
- pCallBack,
- hCallBack
- );
- }
- }
- }
- else
- {
- m_Reader.Skip(numSlots);
- }
- }
- }
- goto ReportUntracked;
-#else //DISABLE_EH_VECTORS
-
_ASSERTE(m_NumSafePoints == 0);
m_Reader.Skip(m_NumSafePoints * numSlots);
-
-#endif //DISABLE_EH_VECTORS
}
else if( m_SafePointIndex != m_NumSafePoints )
{
@@ -891,15 +787,7 @@ bool GcInfoDecoder::EnumerateLiveSlots(
else
{
m_Reader.Skip(m_NumSafePoints * numSlots);
-
-#ifndef DISABLE_EH_VECTORS
- UINT32 numClauses = (UINT32) m_Reader.DecodeVarLengthUnsigned(NUM_EH_CLAUSES_ENCBASE);
- UINT32 numBitsPerOffset = CeilOfLog2(NORMALIZE_CODE_OFFSET(m_CodeLength));
-
- m_Reader.Skip((numBitsPerOffset * 2 + numSlots) * numClauses);
-#endif //DISABLE_EH_VECTORS
- }
-
+ }
#endif // PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED
_ASSERTE(m_NumInterruptibleRanges);
@@ -1069,9 +957,7 @@ ReportUntracked:
ReportUntrackedSlots(slotDecoder, pRD, inputFlags, pCallBack, hCallBack);
}
-#ifdef DISABLE_EH_VECTORS
ExitSuccess:
-#endif
return true;
}
@@ -1080,7 +966,7 @@ void GcInfoDecoder::EnumerateUntrackedSlots(
PREGDISPLAY pRD,
unsigned inputFlags,
GCEnumCallback pCallBack,
- LPVOID hCallBack
+ void * hCallBack
)
{
_ASSERTE(GC_SLOT_INTERIOR == GC_CALL_INTERIOR);
@@ -1114,7 +1000,7 @@ void GcInfoDecoder::ReportUntrackedSlots(
PREGDISPLAY pRD,
unsigned inputFlags,
GCEnumCallback pCallBack,
- LPVOID hCallBack
+ void * hCallBack
)
{
for(UINT32 slotIndex = slotDecoder.GetNumTracked(); slotIndex < slotDecoder.GetNumSlots(); slotIndex++)
@@ -1455,11 +1341,15 @@ OBJECTREF* GcInfoDecoder::GetRegisterSlot(
_ASSERTE(regNum >= 0 && regNum <= 16);
_ASSERTE(regNum != 4); // rsp
+#ifdef FEATURE_REDHAWK
+ PTR_UIntNative* ppRax = &pRD->pRax;
+ if (regNum > 4) regNum--; // rsp is skipped in Redhawk RegDisplay
+#else
// The fields of KNONVOLATILE_CONTEXT_POINTERS are in the same order as
// the processor encoding numbers.
- ULONGLONG **ppRax;
- ppRax = &pRD->pCurrentContextPointers->Rax;
+ ULONGLONG **ppRax = &pRD->pCurrentContextPointers->Rax;
+#endif
return (OBJECTREF*)*(ppRax + regNum);
}
@@ -1476,8 +1366,7 @@ OBJECTREF* GcInfoDecoder::GetCapturedRegister(
// The fields of CONTEXT are in the same order as
// the processor encoding numbers.
- ULONGLONG *pRax;
- pRax = &pRD->pCurrentContext->Rax;
+ ULONGLONG *pRax = &pRD->pCurrentContext->Rax;
return (OBJECTREF*)(pRax + regNum);
}
@@ -1509,7 +1398,7 @@ bool GcInfoDecoder::IsScratchStackSlot(INT32 spOffset, GcStackSlotBase spBase, P
#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA
_ASSERTE( m_Flags & DECODE_GC_LIFETIMES );
- ULONGLONG pSlot = (ULONGLONG) GetStackSlot(spOffset, spBase, pRD);
+ TADDR pSlot = (TADDR) GetStackSlot(spOffset, spBase, pRD);
_ASSERTE(pSlot >= pRD->SP);
return (pSlot < pRD->SP + m_SizeOfStackOutgoingAndScratchArea);
@@ -1525,12 +1414,9 @@ void GcInfoDecoder::ReportRegisterToGC( // AMD64
PREGDISPLAY pRD,
unsigned flags,
GCEnumCallback pCallBack,
- LPVOID hCallBack)
+ void * hCallBack)
{
- GCINFODECODER_CONTRACT(CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- } CONTRACTL_END);
+ GCINFODECODER_CONTRACT;
_ASSERTE(regNum >= 0 && regNum <= 16);
_ASSERTE(regNum != 4); // rsp
@@ -1624,8 +1510,7 @@ OBJECTREF* GcInfoDecoder::GetCapturedRegister(
// The fields of CONTEXT are in the same order as
// the processor encoding numbers.
- ULONG *pR0;
- pR0 = &pRD->pCurrentContext->R0;
+ ULONG *pR0 = &pRD->pCurrentContext->R0;
return (OBJECTREF*)(pR0 + regNum);
}
@@ -1646,7 +1531,7 @@ bool GcInfoDecoder::IsScratchStackSlot(INT32 spOffset, GcStackSlotBase spBase, P
#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA
_ASSERTE( m_Flags & DECODE_GC_LIFETIMES );
- DWORD pSlot = (DWORD) GetStackSlot(spOffset, spBase, pRD);
+ TADDR pSlot = (TADDR) GetStackSlot(spOffset, spBase, pRD);
_ASSERTE(pSlot >= pRD->SP);
return (pSlot < pRD->SP + m_SizeOfStackOutgoingAndScratchArea);
@@ -1662,12 +1547,9 @@ void GcInfoDecoder::ReportRegisterToGC( // ARM
PREGDISPLAY pRD,
unsigned flags,
GCEnumCallback pCallBack,
- LPVOID hCallBack)
+ void * hCallBack)
{
- GCINFODECODER_CONTRACT(CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- } CONTRACTL_END);
+ GCINFODECODER_CONTRACT;
_ASSERTE(regNum >= 0 && regNum <= 14);
_ASSERTE(regNum != 13); // sp
@@ -1740,7 +1622,7 @@ bool GcInfoDecoder::IsScratchStackSlot(INT32 spOffset, GcStackSlotBase spBase, P
#ifdef FIXED_STACK_PARAMETER_SCRATCH_AREA
_ASSERTE( m_Flags & DECODE_GC_LIFETIMES );
- ULONGLONG pSlot = (ULONGLONG) GetStackSlot(spOffset, spBase, pRD);
+ TADDR pSlot = (TADDR) GetStackSlot(spOffset, spBase, pRD);
_ASSERTE(pSlot >= pRD->SP);
return (pSlot < pRD->SP + m_SizeOfStackOutgoingAndScratchArea);
@@ -1756,12 +1638,9 @@ void GcInfoDecoder::ReportRegisterToGC( // ARM64
PREGDISPLAY pRD,
unsigned flags,
GCEnumCallback pCallBack,
- LPVOID hCallBack)
+ void * hCallBack)
{
- GCINFODECODER_CONTRACT(CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- } CONTRACTL_END);
+ GCINFODECODER_CONTRACT;
_ASSERTE(regNum >= 0 && regNum <= 30);
_ASSERTE(regNum != 18);
@@ -1801,8 +1680,7 @@ OBJECTREF* GcInfoDecoder::GetCapturedRegister(
// The fields of CONTEXT are in the same order as
// the processor encoding numbers.
- DWORD64 *pX0;
- pX0 = &pRD->pCurrentContext->X0;
+ DWORD64 *pX0 = &pRD->pCurrentContext->X0;
return (OBJECTREF*)(pX0 + regNum);
}
@@ -1837,7 +1715,7 @@ void GcInfoDecoder::ReportRegisterToGC(
PREGDISPLAY pRD,
unsigned flags,
GCEnumCallback pCallBack,
- LPVOID hCallBack)
+ void * hCallBack)
{
_ASSERTE( !"NYI" );
}
@@ -1859,7 +1737,7 @@ OBJECTREF* GcInfoDecoder::GetStackSlot(
if( GC_SP_REL == spBase )
{
- pObjRef = (OBJECTREF*) ((SIZE_T)GetRegdisplaySP(pRD) + spOffset);
+ pObjRef = (OBJECTREF*) ((SIZE_T)pRD->SP + spOffset);
}
else if( GC_CALLER_SP_REL == spBase )
{
@@ -1916,12 +1794,9 @@ void GcInfoDecoder::ReportStackSlotToGC(
PREGDISPLAY pRD,
unsigned flags,
GCEnumCallback pCallBack,
- LPVOID hCallBack)
+ void * hCallBack)
{
- GCINFODECODER_CONTRACT(CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- } CONTRACTL_END);
+ GCINFODECODER_CONTRACT;
OBJECTREF* pObjRef = GetStackSlot(spOffset, spBase, pRD);
_ASSERTE( IS_ALIGNED( pObjRef, sizeof( Object* ) ) );
diff --git a/src/vm/gcinterface.h b/src/vm/gcinterface.h
new file mode 100644
index 0000000000..cc70becdf1
--- /dev/null
+++ b/src/vm/gcinterface.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.h" \ No newline at end of file
diff --git a/src/vm/gcstress.h b/src/vm/gcstress.h
index 609276e148..04487c611e 100644
--- a/src/vm/gcstress.h
+++ b/src/vm/gcstress.h
@@ -280,17 +280,17 @@ namespace _GCStress
// GC Trigger policy classes define how a garbage collection is triggered
// This is the default GC Trigger policy that simply calls
- // GCHeap::StressHeap
+ // IGCHeap::StressHeap
class StressGcTriggerPolicy
{
public:
FORCEINLINE
static void Trigger()
- { GCHeap::GetGCHeap()->StressHeap(); }
+ { GCHeapUtilities::GetGCHeap()->StressHeap(); }
FORCEINLINE
- static void Trigger(::alloc_context* acontext)
- { GCHeap::GetGCHeap()->StressHeap(acontext); }
+ static void Trigger(::gc_alloc_context* acontext)
+ { GCHeapUtilities::GetGCHeap()->StressHeap(acontext); }
};
// This is an overriding GC Trigger policy that triggers a GC by calling
@@ -403,7 +403,7 @@ namespace _GCStress
// Additionally it switches the GC mode as specified by GcModePolicy, and it
// uses GcTriggerPolicy::Trigger(alloc_context*) to actually trigger the GC
FORCEINLINE
- static void MaybeTrigger(::alloc_context* acontext, DWORD minFastGc = 0)
+ static void MaybeTrigger(::gc_alloc_context* acontext, DWORD minFastGc = 0)
{
if (IsEnabled(minFastGc) && GCStressPolicy::IsEnabled())
{
@@ -455,7 +455,7 @@ namespace _GCStress
public:
FORCEINLINE
- static void MaybeTrigger(::alloc_context* acontext)
+ static void MaybeTrigger(::gc_alloc_context* acontext)
{
GcStressBase::MaybeTrigger(acontext);
diff --git a/src/vm/gdbjit.cpp b/src/vm/gdbjit.cpp
index 9f9c116820..8e728839d6 100644
--- a/src/vm/gdbjit.cpp
+++ b/src/vm/gdbjit.cpp
@@ -11,16 +11,323 @@
//*****************************************************************************
#include "common.h"
+#include "formattype.h"
#include "gdbjit.h"
#include "gdbjithelpers.h"
-struct DebuggerILToNativeMap
+TypeInfoBase*
+GetTypeInfoFromTypeHandle(TypeHandle typeHandle, NotifyGdb::PTK_TypeInfoMap pTypeMap)
{
- ULONG ilOffset;
- ULONG nativeStartOffset;
- ULONG nativeEndOffset;
- ICorDebugInfo::SourceTypes source;
-};
+ TypeInfoBase *typeInfo = nullptr;
+ TypeKey key = typeHandle.GetTypeKey();
+ PTR_MethodTable pMT = typeHandle.GetMethodTable();
+
+ if (pTypeMap->Lookup(&key, &typeInfo))
+ {
+ return typeInfo;
+ }
+
+ CorElementType corType = typeHandle.GetSignatureCorElementType();
+ switch (corType)
+ {
+ case ELEMENT_TYPE_VOID:
+ case ELEMENT_TYPE_BOOLEAN:
+ case ELEMENT_TYPE_CHAR:
+ case ELEMENT_TYPE_I1:
+ case ELEMENT_TYPE_U1:
+ case ELEMENT_TYPE_I2:
+ case ELEMENT_TYPE_U2:
+ case ELEMENT_TYPE_I4:
+ case ELEMENT_TYPE_U4:
+ case ELEMENT_TYPE_I8:
+ case ELEMENT_TYPE_U8:
+ case ELEMENT_TYPE_R4:
+ 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;
+ case ELEMENT_TYPE_VALUETYPE:
+ case ELEMENT_TYPE_CLASS:
+ {
+ ApproxFieldDescIterator fieldDescIterator(pMT,
+ 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();
+
+ 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();
+
+ pTypeMap->Add(refTypeInfo->GetTypeKey(), refTypeInfo);
+ }
+
+ pTypeMap->Add(typeInfo->GetTypeKey(), typeInfo);
+ typeInfo->CalculateName();
+
+ //
+ // Now fill in the array
+ //
+ FieldDesc *pField;
+
+ 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);
+ if (!pField->IsStatic())
+ {
+ info->members[i].m_member_offset = (ULONG)pField->GetOffset();
+ if (!typeHandle.IsValueType())
+ info->members[i].m_member_offset += Object::GetOffsetOfFirstField();
+ }
+ else
+ {
+ PTR_BYTE base = 0;
+ MethodTable* pMT = pField->GetEnclosingMethodTable();
+ base = pField->GetBase();
+
+ // TODO: add support of generics with static fields
+ 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);
+ }
+ }
+
+ info->members[i].m_member_type =
+ GetTypeInfoFromTypeHandle(pField->GetExactFieldType(typeHandle), pTypeMap);
+
+ // 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;
+ }
+ }
+ if (refTypeInfo)
+ return refTypeInfo;
+ else
+ return typeInfo;
+ }
+ 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);
+ typeInfo->m_type_offset = valTypeInfo->m_type_offset;
+ break;
+ }
+ 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();
+
+ pTypeMap->Add(refTypeInfo->GetTypeKey(), refTypeInfo);
+
+ 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;
+
+ ClassTypeInfo *info = static_cast<ClassTypeInfo*>(typeInfo);
+
+ info->members[0].m_member_name = new (nothrow) 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];
+ 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);
+
+ return refTypeInfo;
+ }
+ default:
+ ASSERT(0 && "not implemented");
+ break;
+ }
+ // 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,
+ NotifyGdb::PTK_TypeInfoMap pTypeMap,
+ unsigned ilIndex)
+{
+ MetaSig sig(MethodDescPtr);
+ TypeHandle th;
+ if (ilIndex == 0)
+ {
+ th = sig.GetRetTypeHandleNT();
+ }
+ else
+ {
+ while (--ilIndex)
+ sig.SkipArg();
+
+ sig.NextArg();
+ th = sig.GetLastTypeHandleNT();
+ }
+ return GetTypeInfoFromTypeHandle(th, pTypeMap);
+}
+
+TypeInfoBase* GetLocalTypeInfo(MethodDesc *MethodDescPtr,
+ NotifyGdb::PTK_TypeInfoMap pTypeMap,
+ unsigned ilIndex)
+{
+ COR_ILMETHOD_DECODER method(MethodDescPtr->GetILHeader());
+ if (method.GetLocalVarSigTok())
+ {
+ DWORD cbSigLen;
+ PCCOR_SIGNATURE pComSig;
+
+ if (FAILED(MethodDescPtr->GetMDImport()->GetSigFromToken(method.GetLocalVarSigTok(), &cbSigLen, &pComSig)))
+ {
+ printf("\nInvalid record");
+ return nullptr;
+ }
+
+ _ASSERTE(*pComSig == IMAGE_CEE_CS_CALLCONV_LOCAL_SIG);
+
+ SigTypeContext typeContext(MethodDescPtr, TypeHandle());
+ MetaSig sig(pComSig, cbSigLen, MethodDescPtr->GetModule(), &typeContext, MetaSig::sigLocalVars);
+ if (ilIndex > 0)
+ {
+ while (ilIndex--)
+ sig.SkipArg();
+ }
+ sig.NextArg();
+ TypeHandle th = sig.GetLastTypeHandleNT();
+ return GetTypeInfoFromTypeHandle(th, pTypeMap);
+ }
+ return nullptr;
+}
+
+HRESULT GetArgNameByILIndex(MethodDesc* MethodDescPtr, unsigned index, LPSTR &paramName)
+{
+ IMDInternalImport* mdImport = MethodDescPtr->GetMDImport();
+ mdParamDef paramToken;
+ USHORT seq;
+ DWORD attr;
+ HRESULT status;
+
+ // Param indexing is 1-based.
+ ULONG32 mdIndex = index + 1;
+
+ MetaSig sig(MethodDescPtr);
+ if (sig.HasThis())
+ {
+ mdIndex--;
+ }
+ status = mdImport->FindParamOfMethod(MethodDescPtr->GetMemberDef(), mdIndex, &paramToken);
+ if (status == S_OK)
+ {
+ LPCSTR name;
+ status = mdImport->GetParamDefProps(paramToken, &seq, &attr, &name);
+ paramName = new char[strlen(name) + 1];
+ strcpy(paramName, name);
+ }
+ return status;
+}
+
+// Copy-pasted from src/debug/di/module.cpp
+HRESULT FindNativeInfoInILVariable(DWORD dwIndex,
+ SIZE_T ip,
+ ICorDebugInfo::NativeVarInfo** nativeInfoList,
+ unsigned int nativeInfoCount,
+ ICorDebugInfo::NativeVarInfo** ppNativeInfo)
+{
+ _ASSERTE(ppNativeInfo != NULL);
+ *ppNativeInfo = NULL;
+ int lastGoodOne = -1;
+ for (unsigned int i = 0; i < (unsigned)nativeInfoCount; i++)
+ {
+ if ((*nativeInfoList)[i].varNumber == dwIndex)
+ {
+ if ((lastGoodOne == -1) || ((*nativeInfoList)[lastGoodOne].startOffset < (*nativeInfoList)[i].startOffset))
+ {
+ lastGoodOne = i;
+ }
+
+ if (((*nativeInfoList)[i].startOffset <= ip) &&
+ ((*nativeInfoList)[i].endOffset > ip))
+ {
+ *ppNativeInfo = &((*nativeInfoList)[i]);
+
+ return S_OK;
+ }
+ }
+ }
+
+ if ((lastGoodOne > -1) && ((*nativeInfoList)[lastGoodOne].endOffset == ip))
+ {
+ *ppNativeInfo = &((*nativeInfoList)[lastGoodOne]);
+ return S_OK;
+ }
+
+ return CORDBG_E_IL_VAR_NOT_AVAILABLE;
+}
+
BYTE* DebugInfoStoreNew(void * pData, size_t cBytes)
{
return new (nothrow) BYTE[cBytes];
@@ -30,7 +337,9 @@ BYTE* DebugInfoStoreNew(void * pData, size_t cBytes)
HRESULT
GetMethodNativeMap(MethodDesc* methodDesc,
ULONG32* numMap,
- DebuggerILToNativeMap** map)
+ DebuggerILToNativeMap** map,
+ ULONG32* pcVars,
+ ICorDebugInfo::NativeVarInfo** ppVars)
{
// Use the DebugInfoStore to get IL->Native maps.
// It doesn't matter whether we're jitted, ngenned etc.
@@ -48,8 +357,8 @@ GetMethodNativeMap(MethodDesc* methodDesc,
NULL, // allocator
&countMapCopy,
&mapCopy,
- NULL,
- NULL);
+ pcVars,
+ ppVars);
if (!success)
{
@@ -83,9 +392,62 @@ GetMethodNativeMap(MethodDesc* methodDesc,
return S_OK;
}
+HRESULT FunctionMember::GetLocalsDebugInfo(NotifyGdb::PTK_TypeInfoMap pTypeMap,
+ LocalsInfo& locals,
+ int startNativeOffset)
+{
+
+ ICorDebugInfo::NativeVarInfo* nativeVar = NULL;
+ int thisOffs = 0;
+ if (!md->IsStatic())
+ {
+ thisOffs = 1;
+ }
+
+ int i;
+ for (i = 0; i < m_num_args - thisOffs; i++)
+ {
+ if (FindNativeInfoInILVariable(i + thisOffs, startNativeOffset, &locals.pVars, locals.countVars, &nativeVar) == S_OK)
+ {
+ vars[i + thisOffs].m_var_type = GetArgTypeInfo(md, pTypeMap, i + 1);
+ 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;
+ vars[i + thisOffs].m_var_abbrev = 6;
+ }
+ }
+ //Add info about 'this' as first argument
+ if (thisOffs == 1)
+ {
+ if (FindNativeInfoInILVariable(0, startNativeOffset, &locals.pVars, locals.countVars, &nativeVar) == S_OK)
+ {
+ vars[0].m_var_type = GetTypeInfoFromTypeHandle(TypeHandle(md->GetMethodTable()), pTypeMap);
+ vars[0].m_var_name = new char[strlen("this") + 1];
+ strcpy(vars[0].m_var_name, "this");
+ vars[0].m_il_index = 0;
+ vars[0].m_native_offset = nativeVar->loc.vlStk.vlsOffset;
+ vars[0].m_var_abbrev = 13;
+ }
+ i++;
+ }
+ for (; i < m_num_vars; i++)
+ {
+ 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;
+ vars[i].m_native_offset = nativeVar->loc.vlStk.vlsOffset;
+ vars[i].m_var_abbrev = 5;
+ }
+ }
+ return S_OK;
+}
/* Get mapping of IL offsets to source line numbers */
HRESULT
-GetDebugInfoFromPDB(MethodDesc* MethodDescPtr, SymbolsInfo** symInfo, unsigned int &symInfoLen)
+GetDebugInfoFromPDB(MethodDesc* MethodDescPtr, SymbolsInfo** symInfo, unsigned int &symInfoLen, LocalsInfo &locals)
{
DebuggerILToNativeMap* map = NULL;
@@ -93,8 +455,8 @@ GetDebugInfoFromPDB(MethodDesc* MethodDescPtr, SymbolsInfo** symInfo, unsigned i
if (!getInfoForMethodDelegate)
return E_FAIL;
-
- if (GetMethodNativeMap(MethodDescPtr, &numMap, &map) != S_OK)
+
+ if (GetMethodNativeMap(MethodDescPtr, &numMap, &map, &locals.countVars, &locals.pVars) != S_OK)
return E_FAIL;
const Module* mod = MethodDescPtr->GetMethodTable()->GetModule();
@@ -105,48 +467,125 @@ GetDebugInfoFromPDB(MethodDesc* MethodDescPtr, SymbolsInfo** symInfo, unsigned i
StackScratchBuffer scratch;
const char* szModName = modName.GetUTF8(scratch);
- MethodDebugInfo* methodDebugInfo = new (nothrow) MethodDebugInfo();
- if (methodDebugInfo == nullptr)
- return E_OUTOFMEMORY;
+ MethodDebugInfo methodDebugInfo;
- methodDebugInfo->points = (SequencePointInfo*) CoTaskMemAlloc(sizeof(SequencePointInfo) * numMap);
- if (methodDebugInfo->points == nullptr)
+ methodDebugInfo.points = (SequencePointInfo*) CoTaskMemAlloc(sizeof(SequencePointInfo) * numMap);
+ if (methodDebugInfo.points == nullptr)
return E_OUTOFMEMORY;
- methodDebugInfo->size = numMap;
+ methodDebugInfo.size = numMap;
- if (getInfoForMethodDelegate(szModName, MethodDescPtr->GetMemberDef(), *methodDebugInfo) == FALSE)
+ if (getInfoForMethodDelegate(szModName, MethodDescPtr->GetMemberDef(), methodDebugInfo) == FALSE)
return E_FAIL;
- symInfoLen = methodDebugInfo->size;
- *symInfo = new (nothrow) SymbolsInfo[symInfoLen];
+ symInfoLen = numMap;
+ *symInfo = new (nothrow) SymbolsInfo[numMap];
if (*symInfo == nullptr)
return E_FAIL;
+ locals.size = methodDebugInfo.localsSize;
+ locals.localsName = new (nothrow) char *[locals.size];
+ if (locals.localsName == nullptr)
+ return E_FAIL;
+
+ 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];
- for (ULONG32 i = 0; i < symInfoLen; i++)
+ int len = WideCharToMultiByte(
+ CP_UTF8, 0, methodDebugInfo.locals[i], -1, locals.localsName[i], sizeRequired, NULL, NULL);
+ }
+
+ for (ULONG32 j = 0; j < numMap; j++)
{
- for (ULONG32 j = 0; j < numMap; j++)
+ SymbolsInfo& s = (*symInfo)[j];
+
+ if (j == 0) {
+ s.fileName[0] = 0;
+ s.lineNumber = 0;
+ s.fileIndex = 0;
+ } else {
+ s = (*symInfo)[j - 1];
+ }
+ s.nativeOffset = map[j].nativeStartOffset;
+ s.ilOffset = map[j].ilOffset;
+ s.source = map[j].source;
+ s.lineNumber = 0;
+
+ for (ULONG32 i = 0; i < methodDebugInfo.size; i++)
{
- if (methodDebugInfo->points[i].ilOffset == map[j].ilOffset)
- {
- SymbolsInfo& s = (*symInfo)[i];
- const SequencePointInfo& sp = methodDebugInfo->points[i];
+ const SequencePointInfo& sp = methodDebugInfo.points[i];
- s.nativeOffset = map[j].nativeStartOffset;
- s.ilOffset = map[j].ilOffset;
+ if (methodDebugInfo.points[i].ilOffset == map[j].ilOffset)
+ {
s.fileIndex = 0;
- //wcscpy(s.fileName, sp.fileName);
int len = WideCharToMultiByte(CP_UTF8, 0, sp.fileName, -1, s.fileName, sizeof(s.fileName), NULL, NULL);
s.fileName[len] = 0;
s.lineNumber = sp.lineNumber;
+ break;
}
}
}
- CoTaskMemFree(methodDebugInfo->points);
+ CoTaskMemFree(methodDebugInfo.points);
return S_OK;
}
+/* LEB128 for 32-bit unsigned integer */
+int Leb128Encode(uint32_t num, char* buf, int size)
+{
+ int i = 0;
+
+ do
+ {
+ uint8_t byte = num & 0x7F;
+ if (i >= size)
+ break;
+ num >>= 7;
+ if (num != 0)
+ byte |= 0x80;
+ buf[i++] = byte;
+ }
+ while (num != 0);
+
+ return i;
+}
+
+/* LEB128 for 32-bit signed integer */
+int Leb128Encode(int32_t num, char* buf, int size)
+{
+ int i = 0;
+ bool hasMore = true, isNegative = num < 0;
+
+ while (hasMore && i < size)
+ {
+ uint8_t byte = num & 0x7F;
+ num >>= 7;
+
+ if ((num == 0 && (byte & 0x40) == 0) || (num == -1 && (byte & 0x40) == 0x40))
+ hasMore = false;
+ else
+ byte |= 0x80;
+ buf[i++] = byte;
+ }
+
+ return i;
+}
+
+int GetFrameLocation(int nativeOffset, char* bufVarLoc)
+{
+ char cnvBuf[16] = {0};
+ int len = Leb128Encode(static_cast<int32_t>(nativeOffset), cnvBuf, sizeof(cnvBuf));
+ bufVarLoc[0] = len + 1;
+ bufVarLoc[1] = DW_OP_fbreg;
+ for (int j = 0; j < len; j++)
+ {
+ bufVarLoc[j + 2] = cnvBuf[j];
+ }
+
+ return len + 2; // We add '2' because first 2 bytes contain length of expression and DW_OP_fbreg operation.
+}
+
// GDB JIT interface
typedef enum
{
@@ -185,11 +624,24 @@ struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
/* Predefined section names */
const char* SectionNames[] = {
- "", ".text", ".shstrtab", ".debug_str", ".debug_abbrev", ".debug_info",
- ".debug_pubnames", ".debug_pubtypes", ".debug_line", ".symtab", ".strtab", ""
+ "",
+ ".text",
+ ".shstrtab",
+ ".debug_str",
+ ".debug_abbrev",
+ ".debug_info",
+ ".debug_pubnames",
+ ".debug_pubtypes",
+ ".debug_line",
+ ".symtab",
+ ".strtab"
+ /* After the last (.strtab) section zero or more .thunk_* sections are generated.
+
+ Each .thunk_* section contains a single .thunk_#.
+ These symbols are mapped to methods (or trampolines) called by currently compiled method. */
};
-const int SectionNamesCount = sizeof(SectionNames) / sizeof(SectionNames[0]);
+const int SectionNamesCount = sizeof(SectionNames) / sizeof(SectionNames[0]); // Does not include .thunk_* sections
/* Static data for section headers */
struct SectionHeader {
@@ -207,11 +659,12 @@ struct SectionHeader {
{SHT_PROGBITS, 0},
{SHT_SYMTAB, 0},
{SHT_STRTAB, 0},
+ {SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR}
};
/* Static data for .debug_str section */
const char* DebugStrings[] = {
- "CoreCLR", "" /* module name */, "" /* module path */, "" /* method name */, "int"
+ "CoreCLR", "" /* module name */, "" /* module path */
};
const int DebugStringCount = sizeof(DebugStrings) / sizeof(DebugStrings[0]);
@@ -221,11 +674,95 @@ const unsigned char AbbrevTable[] = {
1, DW_TAG_compile_unit, DW_CHILDREN_yes,
DW_AT_producer, DW_FORM_strp, DW_AT_language, DW_FORM_data2, DW_AT_name, DW_FORM_strp,
DW_AT_stmt_list, DW_FORM_sec_offset, 0, 0,
- 2, DW_TAG_subprogram, DW_CHILDREN_no,
+
+ 2, DW_TAG_base_type, DW_CHILDREN_no,
+ DW_AT_name, DW_FORM_strp, DW_AT_encoding, DW_FORM_data1, DW_AT_byte_size, DW_FORM_data1, 0, 0,
+
+ 3, DW_TAG_typedef, DW_CHILDREN_no,
DW_AT_name, DW_FORM_strp, DW_AT_decl_file, DW_FORM_data1, DW_AT_decl_line, DW_FORM_data1,
- DW_AT_type, DW_FORM_ref4, DW_AT_external, DW_FORM_flag_present, 0, 0,
- 3, DW_TAG_base_type, DW_CHILDREN_no,
- DW_AT_name, DW_FORM_strp, DW_AT_encoding, DW_FORM_data1, DW_AT_byte_size, DW_FORM_data1,0, 0,
+ DW_AT_type, DW_FORM_ref4, 0, 0,
+
+ 4, DW_TAG_subprogram, DW_CHILDREN_yes,
+ DW_AT_name, DW_FORM_strp, DW_AT_linkage_name, DW_FORM_strp, DW_AT_decl_file, DW_FORM_data1, DW_AT_decl_line, DW_FORM_data1,
+ DW_AT_type, DW_FORM_ref4, DW_AT_external, DW_FORM_flag_present,
+ DW_AT_low_pc, DW_FORM_addr, DW_AT_high_pc,
+#if defined(_TARGET_AMD64_)
+ DW_FORM_data8,
+#elif defined(_TARGET_ARM_)
+ DW_FORM_data4,
+#else
+#error Unsupported platform!
+#endif
+ DW_AT_frame_base, DW_FORM_exprloc, 0, 0,
+
+ 5, DW_TAG_variable, DW_CHILDREN_no,
+ DW_AT_name, DW_FORM_strp, DW_AT_decl_file, DW_FORM_data1, DW_AT_decl_line, DW_FORM_data1, DW_AT_type,
+ DW_FORM_ref4, DW_AT_location, DW_FORM_exprloc, 0, 0,
+
+ 6, DW_TAG_formal_parameter, DW_CHILDREN_no,
+ DW_AT_name, DW_FORM_strp, DW_AT_decl_file, DW_FORM_data1, DW_AT_decl_line, DW_FORM_data1, DW_AT_type,
+ 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,
+
+ 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,
+
+ 9, DW_TAG_pointer_type, DW_CHILDREN_no,
+ DW_AT_type, DW_FORM_ref4, DW_AT_byte_size, DW_FORM_data1, 0, 0,
+
+ 10, DW_TAG_array_type, DW_CHILDREN_yes,
+ DW_AT_type, DW_FORM_ref4, 0, 0,
+
+ 11, DW_TAG_subrange_type, DW_CHILDREN_no,
+ DW_AT_upper_bound, DW_FORM_exprloc, 0, 0,
+
+ 12, DW_TAG_subprogram, DW_CHILDREN_yes,
+ DW_AT_name, DW_FORM_strp, DW_AT_linkage_name, DW_FORM_strp, DW_AT_decl_file, DW_FORM_data1, DW_AT_decl_line, DW_FORM_data1,
+ DW_AT_type, DW_FORM_ref4, DW_AT_external, DW_FORM_flag_present,
+ DW_AT_low_pc, DW_FORM_addr, DW_AT_high_pc,
+#if defined(_TARGET_AMD64_)
+ DW_FORM_data8,
+#elif defined(_TARGET_ARM_)
+ DW_FORM_data4,
+#else
+#error Unsupported platform!
+#endif
+ DW_AT_frame_base, DW_FORM_exprloc, DW_AT_object_pointer, DW_FORM_ref4, 0, 0,
+
+ 13, DW_TAG_formal_parameter, DW_CHILDREN_no,
+ DW_AT_name, DW_FORM_strp, DW_AT_decl_file, DW_FORM_data1, DW_AT_decl_line, DW_FORM_data1, DW_AT_type,
+ DW_FORM_ref4, DW_AT_location, DW_FORM_exprloc, DW_AT_artificial, DW_FORM_flag_present, 0, 0,
+
+ 14, DW_TAG_member, DW_CHILDREN_no,
+ DW_AT_name, DW_FORM_strp, DW_AT_type, DW_FORM_ref4, DW_AT_external, DW_FORM_flag_present, 0, 0,
+
+ 15, DW_TAG_variable, DW_CHILDREN_no, DW_AT_specification, DW_FORM_ref4, DW_AT_location, DW_FORM_exprloc,
+ 0, 0,
+
+ 16, DW_TAG_try_block, DW_CHILDREN_no,
+ DW_AT_low_pc, DW_FORM_addr, DW_AT_high_pc,
+#if defined(_TARGET_AMD64_)
+ DW_FORM_data8,
+#elif defined(_TARGET_ARM_)
+ DW_FORM_data4,
+#else
+#error Unsupported platform!
+#endif
+ 0, 0,
+
+ 17, DW_TAG_catch_block, DW_CHILDREN_no,
+ DW_AT_low_pc, DW_FORM_addr, DW_AT_high_pc,
+#if defined(_TARGET_AMD64_)
+ DW_FORM_data8,
+#elif defined(_TARGET_ARM_)
+ DW_FORM_data4,
+#else
+#error Unsupported platform!
+#endif
+ 0, 0,
+
0
};
@@ -241,53 +778,781 @@ DwarfLineNumHeader LineNumHeader = {
};
/* Static data for .debug_info */
-struct __attribute__((packed)) DebugInfo
+struct __attribute__((packed)) DebugInfoCU
{
uint8_t m_cu_abbrev;
uint32_t m_prod_off;
uint16_t m_lang;
uint32_t m_cu_name;
uint32_t m_line_num;
-
+} debugInfoCU = {
+ 1, 0, DW_LANG_C89, 0, 0
+};
+
+struct __attribute__((packed)) DebugInfoTryCatchSub
+{
+ uint8_t m_sub_abbrev;
+#if defined(_TARGET_AMD64_)
+ uint64_t m_sub_low_pc, m_sub_high_pc;
+#elif defined(_TARGET_ARM_)
+ uint32_t m_sub_low_pc, m_sub_high_pc;
+#else
+#error Unsupported platform!
+#endif
+};
+
+struct __attribute__((packed)) DebugInfoSub
+{
uint8_t m_sub_abbrev;
uint32_t m_sub_name;
+ uint32_t m_linkage_name;
uint8_t m_file, m_line;
uint32_t m_sub_type;
-
+#if defined(_TARGET_AMD64_)
+ uint64_t m_sub_low_pc, m_sub_high_pc;
+#elif defined(_TARGET_ARM_)
+ uint32_t m_sub_low_pc, m_sub_high_pc;
+#else
+#error Unsupported platform!
+#endif
+ uint8_t m_sub_loc[2];
+};
+
+struct __attribute__((packed)) DebugInfoSubMember
+{
+ DebugInfoSub sub;
+ uint32_t m_obj_ptr;
+};
+
+// Holder for array of pointers to FunctionMember objects
+class FunctionMemberPtrArrayHolder : public NewArrayHolder<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)
+ {
+ }
+
+ 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;
uint32_t m_type_name;
uint8_t m_encoding;
uint8_t m_byte_size;
-} debugInfo = {
- 1, 0, DW_LANG_C89, 0, 0,
- 2, 0, 1, 1, 37,
- 3, 0, DW_ATE_signed, 4
};
+struct __attribute__((packed)) DebugInfoVar
+{
+ uint8_t m_var_abbrev;
+ uint32_t m_var_name;
+ uint8_t m_var_file, m_var_line;
+ uint32_t m_var_type;
+};
+
+struct __attribute__((packed)) DebugInfoClassType
+{
+ uint8_t m_type_abbrev;
+ uint32_t m_type_name;
+ uint8_t m_byte_size;
+};
+
+struct __attribute__((packed)) DebugInfoClassMember
+{
+ uint8_t m_member_abbrev;
+ uint32_t m_member_name;
+ uint32_t m_member_type;
+};
+
+struct __attribute__((packed)) DebugInfoStaticMember
+{
+ uint8_t m_member_abbrev;
+ uint32_t m_member_specification;
+};
+
+
+struct __attribute__((packed)) DebugInfoRefType
+{
+ uint8_t m_type_abbrev;
+ uint32_t m_ref_type;
+ uint8_t m_byte_size;
+};
+
+struct __attribute__((packed)) DebugInfoArrayType
+{
+ uint8_t m_abbrev;
+ uint32_t m_type;
+};
+
+void TypeInfoBase::DumpStrings(char* ptr, int& offset)
+{
+ if (ptr != nullptr)
+ {
+ strcpy(ptr + offset, m_type_name);
+ m_type_name_offset = offset;
+ }
+ offset += strlen(m_type_name) + 1;
+}
+
+void TypeInfoBase::CalculateName()
+{
+ // name the type
+ SString sName;
+ typeHandle.GetName(sName);
+ StackScratchBuffer buffer;
+ const UTF8 *utf8 = sName.GetUTF8(buffer);
+ m_type_name = new char[strlen(utf8) + 1];
+ strcpy(m_type_name, utf8);
+}
+
+void TypeInfoBase::SetTypeHandle(TypeHandle handle)
+{
+ typeHandle = handle;
+ typeKey = handle.GetTypeKey();
+}
+
+TypeHandle TypeInfoBase::GetTypeHandle()
+{
+ return typeHandle;
+}
+
+TypeKey* TypeInfoBase::GetTypeKey()
+{
+ return &typeKey;
+}
+
+void PrimitiveTypeInfo::DumpDebugInfo(char* ptr, int& offset)
+{
+ if (m_type_offset != 0)
+ {
+ return;
+ }
+
+ if (ptr != nullptr)
+ {
+ DebugInfoType bufType;
+ bufType.m_type_abbrev = 2;
+ bufType.m_type_name = m_type_name_offset;
+ bufType.m_encoding = m_type_encoding;
+ bufType.m_byte_size = m_type_size;
+
+ memcpy(ptr + offset,
+ &bufType,
+ sizeof(DebugInfoType));
+ m_type_offset = offset;
+ }
+
+ offset += sizeof(DebugInfoType);
+}
+
+ClassTypeInfo::ClassTypeInfo(TypeHandle typeHandle, int num_members)
+ : TypeInfoBase(typeHandle),
+ m_num_members(num_members),
+ members(new TypeMember[num_members])
+{
+}
+
+ClassTypeInfo::~ClassTypeInfo()
+{
+ if (members != nullptr && m_num_members > 0)
+ {
+ delete[] members;
+ }
+}
+
+void TypeMember::DumpStrings(char* ptr, int& offset)
+{
+ if (ptr != nullptr)
+ {
+ strcpy(ptr + offset, m_member_name);
+ m_member_name_offset = offset;
+ }
+ offset += strlen(m_member_name) + 1;
+}
+
+void TypeMember::DumpDebugInfo(char* ptr, int& offset)
+{
+ if (ptr != nullptr)
+ {
+ DebugInfoClassMember memberEntry;
+
+ if (m_static_member_address == 0)
+ memberEntry.m_member_abbrev = 8;
+ else
+ {
+ memberEntry.m_member_abbrev = 14;
+ m_member_offset = offset;
+ }
+ memberEntry.m_member_name = m_member_name_offset;
+ memberEntry.m_member_type = m_member_type->m_type_offset;
+
+ memcpy(ptr + offset, &memberEntry, sizeof(DebugInfoClassMember));
+ if (m_static_member_address == 0)
+ memcpy(ptr + offset + sizeof(DebugInfoClassMember), &m_member_offset, sizeof(m_member_offset));
+ }
+ offset += sizeof(DebugInfoClassMember);
+ if (m_static_member_address == 0)
+ offset += sizeof(m_member_offset);
+}
+
+void TypeMember::DumpStaticDebugInfo(char* ptr, int& offset)
+{
+ const int ptrSize = sizeof(TADDR);
+ if (ptr != nullptr)
+ {
+ DebugInfoStaticMember memberEntry;
+
+ memberEntry.m_member_abbrev = 15;
+ memberEntry.m_member_specification = m_member_offset;
+ memcpy(ptr + offset, &memberEntry, sizeof(DebugInfoStaticMember));
+
+ char buf[ptrSize + 2] = {0};
+ buf[0] = ptrSize + 1;
+ buf[1] = DW_OP_addr;
+
+ for (int i = 0; i < ptrSize; i++)
+ {
+ buf[i + 2] = m_static_member_address >> (i * 8);
+ }
+
+ memcpy(ptr + offset + sizeof(DebugInfoStaticMember), &buf, ptrSize + 2);
+ }
+ offset += sizeof(DebugInfoStaticMember);
+ offset += ptrSize + 2;
+}
+
+void FunctionMember::MangleName(char *buf, int &buf_offset, const char *name)
+{
+ int name_length = strlen(name);
+
+ char tmp[20];
+ int tmp_len = sprintf_s(tmp, _countof(tmp), "%i", name_length);
+ if (tmp_len <= 0)
+ return;
+
+ if (buf)
+ strncpy(buf + buf_offset, tmp, tmp_len);
+ buf_offset += tmp_len;
+
+ if (buf)
+ {
+ for (int i = 0; i < name_length; i++)
+ {
+ char c = name[i];
+ bool valid = (c >= 'a' && c <= 'z') ||
+ (c >= 'A' && c <= 'Z') ||
+ (c >= '0' && c <= '9');
+ *(buf + buf_offset + i) = valid ? c : '_';
+ }
+ }
+ buf_offset += name_length;
+}
+
+void FunctionMember::DumpMangledNamespaceAndMethod(char *buf, int &offset, const char *nspace, const char *mname)
+{
+ static const char *begin_mangled = "_ZN";
+ static const char *end_mangled = "Ev";
+ static const int begin_mangled_len = strlen(begin_mangled);
+ static const int end_mangled_len = strlen(end_mangled);
+
+ if (buf)
+ strncpy(buf + offset, begin_mangled, begin_mangled_len);
+ offset += begin_mangled_len;
+
+ MangleName(buf, offset, nspace);
+ MangleName(buf, offset, mname);
+
+ if (buf)
+ strncpy(buf + offset, end_mangled, end_mangled_len);
+ offset += end_mangled_len;
+
+ if (buf)
+ buf[offset] = '\0';
+ ++offset;
+}
+
+void FunctionMember::DumpLinkageName(char* ptr, int& offset)
+{
+ SString namespaceOrClassName;
+ SString methodName;
+
+ md->GetMethodInfoNoSig(namespaceOrClassName, methodName);
+ SString utf8namespaceOrClassName;
+ SString utf8methodName;
+ namespaceOrClassName.ConvertToUTF8(utf8namespaceOrClassName);
+ methodName.ConvertToUTF8(utf8methodName);
+
+ const char *nspace = utf8namespaceOrClassName.GetUTF8NoConvert();
+ const char *mname = utf8methodName.GetUTF8NoConvert();
+
+ if (!nspace || !mname)
+ {
+ m_linkage_name_offset = 0;
+ return;
+ }
+
+ m_linkage_name_offset = offset;
+ DumpMangledNamespaceAndMethod(ptr, offset, nspace, mname);
+}
+
+void FunctionMember::DumpStrings(char* ptr, int& offset)
+{
+ TypeMember::DumpStrings(ptr, offset);
+
+ for (int i = 0; i < m_num_vars; ++i)
+ {
+ vars[i].DumpStrings(ptr, offset);
+ }
+
+ DumpLinkageName(ptr, offset);
+}
+
+bool FunctionMember::GetBlockInNativeCode(int blockILOffset, int blockILLen, TADDR *startOffset, TADDR *endOffset)
+{
+ PCODE pCode = md->GetNativeCode();
+
+ const int blockILEnd = blockILOffset + blockILLen;
+
+ *startOffset = 0;
+ *endOffset = 0;
+
+ bool inBlock = false;
+
+ for (int i = 0; i < nlines; ++i)
+ {
+ TADDR nativeOffset = lines[i].nativeOffset + pCode;
+
+ // Limit block search to current function addresses
+ if (nativeOffset < m_sub_low_pc)
+ continue;
+ if (nativeOffset >= m_sub_low_pc + m_sub_high_pc)
+ break;
+
+ // Skip invalid IL offsets
+ switch(lines[i].ilOffset)
+ {
+ case ICorDebugInfo::PROLOG:
+ case ICorDebugInfo::EPILOG:
+ case ICorDebugInfo::NO_MAPPING:
+ continue;
+ default:
+ break;
+ }
+
+ // Check if current IL is within block
+ if (blockILOffset <= lines[i].ilOffset && lines[i].ilOffset < blockILEnd)
+ {
+ if (!inBlock)
+ {
+ *startOffset = lines[i].nativeOffset;
+ inBlock = true;
+ }
+ }
+ else
+ {
+ if (inBlock)
+ {
+ *endOffset = lines[i].nativeOffset;
+ inBlock = false;
+ break;
+ }
+ }
+ }
+
+ if (inBlock)
+ {
+ *endOffset = m_sub_low_pc + m_sub_high_pc - pCode;
+ }
+
+ return *endOffset != *startOffset;
+}
+
+void FunctionMember::DumpTryCatchBlock(char* ptr, int& offset, int ilOffset, int ilLen, int abbrev)
+{
+ TADDR startOffset;
+ TADDR endOffset;
+
+ if (!GetBlockInNativeCode(ilOffset, ilLen, &startOffset, &endOffset))
+ return;
+
+ if (ptr != nullptr)
+ {
+ DebugInfoTryCatchSub subEntry;
+
+ subEntry.m_sub_abbrev = abbrev;
+ subEntry.m_sub_low_pc = md->GetNativeCode() + startOffset;
+ subEntry.m_sub_high_pc = endOffset - startOffset;
+
+ memcpy(ptr + offset, &subEntry, sizeof(DebugInfoTryCatchSub));
+ }
+ offset += sizeof(DebugInfoTryCatchSub);
+}
+
+void FunctionMember::DumpTryCatchDebugInfo(char* ptr, int& offset)
+{
+ if (!md)
+ return;
+
+ COR_ILMETHOD *pHeader = md->GetILHeader();
+ COR_ILMETHOD_DECODER header(pHeader);
+
+ unsigned ehCount = header.EHCount();
+
+ for (unsigned e = 0; e < ehCount; e++)
+ {
+ IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT ehBuff;
+ const IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_FAT* ehInfo;
+
+ ehInfo = header.EH->EHClause(e, &ehBuff);
+
+ DumpTryCatchBlock(ptr, offset, ehInfo->TryOffset, ehInfo->TryLength, 16);
+ DumpTryCatchBlock(ptr, offset, ehInfo->HandlerOffset, ehInfo->HandlerLength, 17);
+ }
+}
+
+void FunctionMember::DumpDebugInfo(char* ptr, int& offset)
+{
+ if (ptr != nullptr)
+ {
+ DebugInfoSub subEntry;
+
+ subEntry.m_sub_abbrev = 4;
+ subEntry.m_sub_name = m_member_name_offset;
+ subEntry.m_linkage_name = m_linkage_name_offset;
+ subEntry.m_file = m_file;
+ subEntry.m_line = m_line;
+ subEntry.m_sub_type = m_member_type->m_type_offset;
+ subEntry.m_sub_low_pc = m_sub_low_pc;
+ subEntry.m_sub_high_pc = m_sub_high_pc;
+ subEntry.m_sub_loc[0] = m_sub_loc[0];
+ subEntry.m_sub_loc[1] = m_sub_loc[1];
+
+ if (!md->IsStatic())
+ {
+ DebugInfoSubMember subMemberEntry;
+ subEntry.m_sub_abbrev = 12;
+ subMemberEntry.sub = subEntry;
+ subMemberEntry.m_obj_ptr = offset+sizeof(DebugInfoSubMember);
+ memcpy(ptr + offset, &subMemberEntry, sizeof(DebugInfoSubMember));
+ }
+ else
+ {
+ memcpy(ptr + offset, &subEntry, sizeof(DebugInfoSub));
+ }
+ m_entry_offset = offset;
+ dumped = true;
+ }
+
+ if (!md->IsStatic())
+ {
+ offset += sizeof(DebugInfoSubMember);
+ }
+ else
+ {
+ offset += sizeof(DebugInfoSub);
+ }
+ for (int i = 0; i < m_num_vars; ++i)
+ {
+ vars[i].DumpDebugInfo(ptr, offset);
+ }
+
+ DumpTryCatchDebugInfo(ptr, offset);
+
+ // terminate children
+ if (ptr != nullptr)
+ {
+ ptr[offset] = 0;
+ }
+ offset++;
+}
+
+int FunctionMember::GetArgsAndLocalsLen()
+{
+ int locSize = 0;
+ char tmpBuf[16];
+
+ // Format for DWARF location expression: [expression length][operation][offset in SLEB128 encoding]
+ for (int i = 0; i < m_num_vars; i++)
+ {
+ locSize += 2; // First byte contains expression length, second byte contains operation (DW_OP_fbreg).
+ locSize += Leb128Encode(static_cast<int32_t>(vars[i].m_native_offset), tmpBuf, sizeof(tmpBuf));
+ }
+ return locSize;
+}
+
+void ClassTypeInfo::DumpStrings(char* ptr, int& offset)
+{
+ TypeInfoBase::DumpStrings(ptr, offset);
+
+ for (int i = 0; i < m_num_members; ++i)
+ {
+ members[i].DumpStrings(ptr, offset);
+ }
+}
+
+void RefTypeInfo::DumpStrings(char* ptr, int& offset)
+{
+ TypeInfoBase::DumpStrings(ptr, offset);
+ m_value_type->DumpStrings(ptr, offset);
+}
+
+void RefTypeInfo::DumpDebugInfo(char* ptr, int& offset)
+{
+ if (m_type_offset != 0)
+ {
+ return;
+ }
+ m_type_offset = offset;
+ offset += sizeof(DebugInfoRefType);
+ 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));
+ }
+ else
+ {
+ m_type_offset = 0;
+ }
+}
+void ClassTypeInfo::DumpDebugInfo(char* ptr, int& offset)
+{
+ if (m_type_offset != 0)
+ {
+ return;
+ }
+ // make sure that types of all members are dumped
+ for (int i = 0; i < m_num_members; ++i)
+ {
+ if (members[i].m_member_type->m_type_offset == 0 && members[i].m_member_type != this)
+ {
+ members[i].m_member_type->DumpDebugInfo(ptr, offset);
+ }
+ }
+
+ if (ptr != nullptr)
+ {
+ DebugInfoClassType bufType;
+ bufType.m_type_abbrev = 7;
+ bufType.m_type_name = m_type_name_offset;
+ bufType.m_byte_size = m_type_size;
+
+ memcpy(ptr + offset, &bufType, sizeof(DebugInfoClassType));
+ m_type_offset = offset;
+ }
+ offset += sizeof(DebugInfoClassType);
+
+ for (int i = 0; i < m_num_members; ++i)
+ {
+ members[i].DumpDebugInfo(ptr, offset);
+ }
+
+ for (int i = 0; i < method.GetCount(); ++i)
+ {
+ if (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);
+ }
+ }
+
+ // members terminator
+ if (ptr != nullptr)
+ {
+ ptr[offset] = 0;
+ }
+ offset++;
+
+ for (int i = 0; i < m_num_members; ++i)
+ {
+ if (members[i].m_static_member_address != 0)
+ members[i].DumpStaticDebugInfo(ptr, offset);
+ }
+
+}
+
+void ArrayTypeInfo::DumpDebugInfo(char* ptr, int& offset)
+{
+ if (m_type_offset != 0)
+ {
+ return;
+ }
+ if (m_elem_type->m_type_offset == 0)
+ {
+ m_elem_type->DumpDebugInfo(ptr, offset);
+ }
+ if (ptr != nullptr)
+ {
+ DebugInfoArrayType arrType;
+
+ arrType.m_abbrev = 10; // DW_TAG_array_type abbrev
+ arrType.m_type = m_elem_type->m_type_offset;
+
+ memcpy(ptr + offset, &arrType, sizeof(DebugInfoArrayType));
+ m_type_offset = offset;
+ }
+ offset += sizeof(DebugInfoArrayType);
+
+ char tmp[16] = { 0 };
+ int len = Leb128Encode(static_cast<int32_t>(m_count_offset), tmp, sizeof(tmp));
+ 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);
+ }
+ offset += (len + 5);
+
+ if (ptr != nullptr)
+ {
+ memset(ptr + offset, 0, 1);
+ }
+ offset += 1;
+}
+
+void VarDebugInfo::DumpStrings(char *ptr, int& offset)
+{
+ if (ptr != nullptr)
+ {
+ strcpy(ptr + offset, m_var_name);
+ m_var_name_offset = offset;
+ }
+ offset += strlen(m_var_name) + 1;
+}
+
+void VarDebugInfo::DumpDebugInfo(char* ptr, int& offset)
+{
+ char bufVarLoc[16];
+ int len = GetFrameLocation(m_native_offset, bufVarLoc);
+ if (ptr != nullptr)
+ {
+ DebugInfoVar bufVar;
+
+ bufVar.m_var_abbrev = m_var_abbrev;
+ bufVar.m_var_name = m_var_name_offset;
+ bufVar.m_var_file = 1;
+ bufVar.m_var_line = 1;
+ bufVar.m_var_type = m_var_type->m_type_offset;
+ memcpy(ptr + offset, &bufVar, sizeof(DebugInfoVar));
+ memcpy(ptr + offset + sizeof(DebugInfoVar), bufVarLoc, len);
+ }
+ offset += sizeof(DebugInfoVar);
+ offset += len;
+}
+
/* static data for symbol strings */
-const char* SymbolNames[] = {
- "", ""
+struct Elf_Symbol {
+ const char* m_name;
+ 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;
+ }
};
+static int countFuncs(const SymbolsInfo *lines, int nlines)
+{
+ int count = 0;
+ for (int i = 0; i < nlines; i++) {
+ if (lines[i].ilOffset == ICorDebugInfo::PROLOG)
+ {
+ count++;
+ }
+ }
+ return count;
+}
+
+static int getNextPrologueIndex(int from, const SymbolsInfo *lines, int nlines)
+{
+ for (int i = from; i < nlines; ++i) {
+ if (lines[i].ilOffset == ICorDebugInfo::PROLOG)
+ {
+ return i;
+ }
+ }
+ return -1;
+}
+
+int SymbolCount = 0;
+NewArrayHolder<Elf_Symbol> SymbolNames;
+NotifyGdb::AddrSet codeAddrs;
/* Create ELF/DWARF debug info for jitted method */
void NotifyGdb::MethodCompiled(MethodDesc* MethodDescPtr)
{
PCODE pCode = MethodDescPtr->GetNativeCode();
-
if (pCode == NULL)
return;
unsigned int symInfoLen = 0;
NewArrayHolder<SymbolsInfo> symInfo = nullptr;
+ LocalsInfo locals;
/* Get method name & size of jitted code */
LPCUTF8 methodName = MethodDescPtr->GetName();
EECodeInfo codeInfo(pCode);
TADDR codeSize = codeInfo.GetCodeManager()->GetFunctionSize(codeInfo.GetGCInfoToken());
-
-#ifdef _TARGET_ARM_
- pCode &= ~1; // clear thumb flag for debug info
-#endif
+
+ pCode = PCODEToPINSTR(pCode);
/* Get module name */
const Module* mod = MethodDescPtr->GetMethodTable()->GetModule();
@@ -357,15 +1622,82 @@ void NotifyGdb::MethodCompiled(MethodDesc* MethodDescPtr)
}
if (isUserDebug == FALSE)
+ {
return;
+ }
+
+ 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);
+ 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;
+ }
+
+ 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()))
+ {
+ return;
+ }
+ pCH->SetCalledMethods(NULL);
+
+ MetaSig sig(MethodDescPtr);
+ int nArgsCount = sig.NumFixedArgs();
+ if (sig.HasThis())
+ nArgsCount++;
+
+ unsigned int firstLineIndex = 0;
+ for (;firstLineIndex < symInfoLen; firstLineIndex++) {
+ if (symInfo[firstLineIndex].lineNumber != 0 && symInfo[firstLineIndex].lineNumber != HiddenLine) break;
+ }
+
+ if (firstLineIndex >= symInfoLen)
+ {
+ return;
+ }
+
+ int start_index = getNextPrologueIndex(0, symInfo, symInfoLen);
+
+ for (int method_index = 0; method_index < method.GetCount(); ++method_index)
+ {
+ method[method_index] = new FunctionMember(MethodDescPtr, locals.size, nArgsCount);
+
+ int end_index = getNextPrologueIndex(start_index + 1, symInfo, symInfoLen);
+
+ PCODE method_start = symInfo[start_index].nativeOffset;
+ 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_sub_low_pc = pCode + method_start;
+ method[method_index]->m_sub_high_pc = method_size;
+ size_t methodNameSize = strlen(methodName) + 10;
+ method[method_index]->m_member_name = new char[methodNameSize];
+ if (method_index == 0)
+ sprintf_s(method[method_index]->m_member_name, methodNameSize, "%s", methodName);
+ else
+ 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);
+
+ start_index = end_index;
+ }
+
MemBuf elfHeader, sectHeaders, sectStr, sectSymTab, sectStrTab, dbgInfo, dbgAbbrev, dbgPubname, dbgPubType, dbgLine,
dbgStr, elfFile;
@@ -374,42 +1706,52 @@ void NotifyGdb::MethodCompiled(MethodDesc* MethodDescPtr)
{
return;
}
-
+
/* Build .debug_line section */
- if (!BuildLineTable(dbgLine, pCode, symInfo, symInfoLen))
+ if (!BuildLineTable(dbgLine, pCode, codeSize, symInfo, symInfoLen))
{
return;
}
DebugStrings[1] = szModuleFile;
- DebugStrings[3] = methodName;
/* Build .debug_str section */
- if (!BuildDebugStrings(dbgStr))
+ if (!BuildDebugStrings(dbgStr, pTypeMap))
{
return;
}
/* Build .debug_info section */
- if (!BuildDebugInfo(dbgInfo))
+ if (!BuildDebugInfo(dbgInfo, pTypeMap, symInfo, symInfoLen))
{
return;
}
-
+
+ for (int i = 0; i < locals.size; i++)
+ {
+ delete[] locals.localsName[i];
+ }
/* Build .debug_pubname section */
- if (!BuildDebugPub(dbgPubname, methodName, dbgInfo.MemSize, 26))
+ if (!BuildDebugPub(dbgPubname, methodName, dbgInfo.MemSize, 0x28))
{
return;
}
/* Build debug_pubtype section */
- if (!BuildDebugPub(dbgPubType, "int", dbgInfo.MemSize, 37))
+ if (!BuildDebugPub(dbgPubType, "int", dbgInfo.MemSize, 0x1a))
{
return;
}
-
+
/* Build .strtab section */
- SymbolNames[1] = methodName;
+ 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;
+ }
if (!BuildStringTableSection(sectStrTab))
{
return;
@@ -420,15 +1762,8 @@ void NotifyGdb::MethodCompiled(MethodDesc* MethodDescPtr)
return;
}
-
- /* Build section names section */
- if (!BuildSectionNameTable(sectStr))
- {
- return;
- }
-
- /* Build section headers table */
- if (!BuildSectionTable(sectHeaders))
+ /* Build section headers table and section names table */
+ if (!BuildSectionTables(sectHeaders, sectStr))
{
return;
}
@@ -470,13 +1805,21 @@ void NotifyGdb::MethodCompiled(MethodDesc* MethodDescPtr)
++pShdr; // .symtab
pShdr->sh_offset = offset;
pShdr->sh_size = sectSymTab.MemSize;
- pShdr->sh_link = 10;
+ pShdr->sh_link = GetSectionIndex(".strtab");
offset += sectSymTab.MemSize;
++pShdr; // .strtab
pShdr->sh_offset = offset;
pShdr->sh_size = sectStrTab.MemSize;
offset += sectStrTab.MemSize;
-
+
+ // .thunks
+ for (int i = 1 + method.GetCount(); i < SymbolCount; i++)
+ {
+ ++pShdr;
+ pShdr->sh_addr = PCODEToPINSTR(SymbolNames[i].m_value);
+ pShdr->sh_size = 8;
+ }
+
/* Build ELF header */
if (!BuildELFHeader(elfHeader))
{
@@ -493,8 +1836,9 @@ void NotifyGdb::MethodCompiled(MethodDesc* MethodDescPtr)
#endif
header->e_shoff = offset;
header->e_shentsize = sizeof(Elf_Shdr);
- header->e_shnum = SectionNamesCount - 1;
- header->e_shstrndx = 2;
+ int thunks_count = SymbolCount - method.GetCount() - 1;
+ header->e_shnum = SectionNamesCount + thunks_count;
+ header->e_shstrndx = GetSectionIndex(".shstrtab");
/* Build ELF image in memory */
elfFile.MemSize = elfHeader.MemSize + sectStr.MemSize + dbgStr.MemSize + dbgAbbrev.MemSize + dbgInfo.MemSize +
@@ -531,12 +1875,14 @@ void NotifyGdb::MethodCompiled(MethodDesc* MethodDescPtr)
memcpy(elfFile.MemPtr + offset, sectHeaders.MemPtr, sectHeaders.MemSize);
+ elfFile.MemPtr.SuppressRelease();
+
#ifdef GDBJIT_DUMPELF
DumpElf(methodName, elfFile);
-#endif
-
+#endif
+
/* Create GDB JIT structures */
- jit_code_entry* jit_symbols = new (nothrow) jit_code_entry;
+ NewHolder<jit_code_entry> jit_symbols = new (nothrow) jit_code_entry;
if (jit_symbols == nullptr)
{
@@ -557,15 +1903,21 @@ void NotifyGdb::MethodCompiled(MethodDesc* MethodDescPtr)
head->prev_entry = jit_symbols;
}
+ jit_symbols.SuppressRelease();
+
/* Notify the debugger */
__jit_debug_descriptor.relevant_entry = jit_symbols;
__jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
__jit_debug_register_code();
-
}
void NotifyGdb::MethodDropped(MethodDesc* MethodDescPtr)
{
+ static const int textSectionIndex = GetSectionIndex(".text");
+
+ if (textSectionIndex < 0)
+ return;
+
PCODE pCode = MethodDescPtr->GetNativeCode();
if (pCode == NULL)
@@ -579,7 +1931,7 @@ void NotifyGdb::MethodDropped(MethodDesc* MethodDescPtr)
const Elf_Ehdr* pEhdr = reinterpret_cast<const Elf_Ehdr*>(ptr);
const Elf_Shdr* pShdr = reinterpret_cast<const Elf_Shdr*>(ptr + pEhdr->e_shoff);
- ++pShdr; // bump to .text section
+ pShdr += textSectionIndex; // bump to .text section
if (pShdr->sh_addr == pCode)
{
/* Notify the debugger */
@@ -602,7 +1954,7 @@ void NotifyGdb::MethodDropped(MethodDesc* MethodDescPtr)
}
/* Build the DWARF .debug_line section */
-bool NotifyGdb::BuildLineTable(MemBuf& buf, PCODE startAddr, SymbolsInfo* lines, unsigned nlines)
+bool NotifyGdb::BuildLineTable(MemBuf& buf, PCODE startAddr, TADDR codeSize, SymbolsInfo* lines, unsigned nlines)
{
MemBuf fileTable, lineProg;
@@ -610,7 +1962,7 @@ bool NotifyGdb::BuildLineTable(MemBuf& buf, PCODE startAddr, SymbolsInfo* lines,
if (!BuildFileTable(fileTable, lines, nlines))
return false;
/* Build line info program */
- if (!BuildLineProg(lineProg, startAddr, lines, nlines))
+ if (!BuildLineProg(lineProg, startAddr, codeSize, lines, nlines))
{
return false;
}
@@ -640,7 +1992,7 @@ bool NotifyGdb::BuildLineTable(MemBuf& buf, PCODE startAddr, SymbolsInfo* lines,
/* Buid the source files table for DWARF source line info */
bool NotifyGdb::BuildFileTable(MemBuf& buf, SymbolsInfo* lines, unsigned nlines)
{
- const char** files = nullptr;
+ NewArrayHolder<const char*> files = nullptr;
unsigned nfiles = 0;
/* GetValue file names and replace them with indices in file table */
@@ -649,6 +2001,8 @@ bool NotifyGdb::BuildFileTable(MemBuf& buf, SymbolsInfo* lines, unsigned nlines)
return false;
for (unsigned i = 0; i < nlines; ++i)
{
+ if (lines[i].fileName[0] == 0)
+ continue;
const char *filePath, *fileName;
SplitPathname(lines[i].fileName, filePath, fileName);
@@ -686,7 +2040,6 @@ bool NotifyGdb::BuildFileTable(MemBuf& buf, SymbolsInfo* lines, unsigned nlines)
if (buf.MemPtr == nullptr)
{
- delete[] files;
return false;
}
@@ -704,7 +2057,6 @@ bool NotifyGdb::BuildFileTable(MemBuf& buf, SymbolsInfo* lines, unsigned nlines)
// final zero byte
*ptr = 0;
- delete[] files;
return true;
}
@@ -742,44 +2094,77 @@ void NotifyGdb::IssueParamCommand(char*& ptr, uint8_t command, char* param, int
}
}
-/* Special command moves address, line number and issue one row to source line matrix */
-void NotifyGdb::IssueSpecialCommand(char*& ptr, int8_t line_shift, uint8_t addr_shift)
-{
- *ptr++ = (line_shift - DWARF_LINE_BASE) + addr_shift * DWARF_LINE_RANGE + DWARF_OPCODE_BASE;
-}
-
-/* Check to see if given shifts are fit into one byte command */
-bool NotifyGdb::FitIntoSpecialOpcode(int8_t line_shift, uint8_t addr_shift)
+static void fixLineMapping(SymbolsInfo* lines, unsigned nlines)
{
- unsigned opcode = (line_shift - DWARF_LINE_BASE) + addr_shift * DWARF_LINE_RANGE + DWARF_OPCODE_BASE;
-
- return opcode < 255;
+ // Fix EPILOGUE line mapping
+ int prevLine = 0;
+ for (int i = 0; i < nlines; ++i)
+ {
+ if (lines[i].lineNumber == HiddenLine)
+ continue;
+ if (lines[i].ilOffset == ICorDebugInfo::PROLOG) // will be fixed in next step
+ {
+ prevLine = 0;
+ }
+ else
+ {
+ if (lines[i].lineNumber == 0)
+ {
+ lines[i].lineNumber = prevLine;
+ }
+ else
+ {
+ prevLine = lines[i].lineNumber;
+ }
+ }
+ }
+ // Fix PROLOGUE line mapping
+ prevLine = lines[nlines - 1].lineNumber;
+ for (int i = nlines - 1; i >= 0; --i)
+ {
+ if (lines[i].lineNumber == HiddenLine)
+ continue;
+ if (lines[i].lineNumber == 0)
+ lines[i].lineNumber = prevLine;
+ else
+ prevLine = lines[i].lineNumber;
+ }
+ // Skip HiddenLines
+ for (int i = 0; i < nlines; ++i)
+ {
+ if (lines[i].lineNumber == HiddenLine)
+ {
+ lines[i].lineNumber = 0;
+ if (i + 1 < nlines && lines[i + 1].ilOffset == ICorDebugInfo::NO_MAPPING)
+ lines[i + 1].lineNumber = 0;
+ }
+ }
}
/* Build program for DWARF source line section */
-bool NotifyGdb::BuildLineProg(MemBuf& buf, PCODE startAddr, SymbolsInfo* lines, unsigned nlines)
+bool NotifyGdb::BuildLineProg(MemBuf& buf, PCODE startAddr, TADDR codeSize, SymbolsInfo* lines, unsigned nlines)
{
static char cnv_buf[16];
- /* reserve memory assuming worst case: one extended and one special plus advance line command for each line*/
- buf.MemSize = 3 + ADDRESS_SIZE /* initial set address command */
- + 1 /* set prolog end command */
+ /* reserve memory assuming worst case: set address, advance line command, set proglogue/epilogue and copy for each line */
+ buf.MemSize =
+ 6 /* set file command */
+ nlines * 6 /* advance line commands */
- + nlines * (4 + ADDRESS_SIZE) /* 1 extended + 1 special command */
+ + nlines * (3 + ADDRESS_SIZE) /* set address commands */
+ + nlines * 1 /* set prologue end or epilogue begin commands */
+ + nlines * 1 /* copy commands */
+ + 6 /* advance PC command */
+ 3; /* end of sequence command */
buf.MemPtr = new (nothrow) char[buf.MemSize];
char* ptr = buf.MemPtr;
if (buf.MemPtr == nullptr)
return false;
-
- /* set absolute start address */
- IssueSetAddress(ptr, startAddr);
- IssueSimpleCommand(ptr, DW_LNS_set_prologue_end);
-
- int prevLine = 1, prevAddr = 0, prevFile = 0;
-
+
+ fixLineMapping(lines, nlines);
+
+ int prevLine = 1, prevFile = 0;
+
for (int i = 0; i < nlines; ++i)
{
/* different source file */
@@ -789,26 +2174,38 @@ bool NotifyGdb::BuildLineProg(MemBuf& buf, PCODE startAddr, SymbolsInfo* lines,
IssueParamCommand(ptr, DW_LNS_set_file, cnv_buf, len);
prevFile = lines[i].fileIndex;
}
- /* too big line number shift */
- if (lines[i].lineNumber - prevLine > (DWARF_LINE_BASE + DWARF_LINE_RANGE - 1))
- {
+
+ // GCC don't use the is_prologue_end flag to mark the first instruction after the prologue.
+ // Instead of it it is issueing a line table entry for the first instruction of the prologue
+ // and one for the first instruction after the prologue.
+ // We do not want to confuse the debugger so we have to avoid adding a line in such case.
+ if (i > 0 && lines[i - 1].nativeOffset == lines[i].nativeOffset)
+ continue;
+
+ IssueSetAddress(ptr, startAddr + lines[i].nativeOffset);
+
+ if (lines[i].lineNumber != prevLine) {
int len = Leb128Encode(static_cast<int32_t>(lines[i].lineNumber - prevLine), cnv_buf, sizeof(cnv_buf));
IssueParamCommand(ptr, DW_LNS_advance_line, cnv_buf, len);
prevLine = lines[i].lineNumber;
}
- /* first try special opcode */
- if (FitIntoSpecialOpcode(lines[i].lineNumber - prevLine, lines[i].nativeOffset - prevAddr))
- IssueSpecialCommand(ptr, lines[i].lineNumber - prevLine, lines[i].nativeOffset - prevAddr);
- else
- {
- IssueSetAddress(ptr, startAddr + lines[i].nativeOffset);
- IssueSpecialCommand(ptr, lines[i].lineNumber - prevLine, 0);
- }
-
- prevLine = lines[i].lineNumber;
- prevAddr = lines[i].nativeOffset;
+
+ if (lines[i].ilOffset == ICorDebugInfo::EPILOG)
+ IssueSimpleCommand(ptr, DW_LNS_set_epilogue_begin);
+ else if (i > 0 && lines[i - 1].ilOffset == ICorDebugInfo::PROLOG)
+ IssueSimpleCommand(ptr, DW_LNS_set_prologue_end);
+
+ IssueParamCommand(ptr, DW_LNS_copy, NULL, 0);
}
-
+
+ int lastAddr = nlines > 0 ? lines[nlines - 1].nativeOffset : 0;
+
+ // Advance PC to the end of function
+ if (lastAddr < codeSize) {
+ int len = Leb128Encode(static_cast<uint32_t>(codeSize - lastAddr), cnv_buf, sizeof(cnv_buf));
+ IssueParamCommand(ptr, DW_LNS_advance_pc, cnv_buf, len);
+ }
+
IssueEndOfSequence(ptr);
buf.MemSize = ptr - buf.MemPtr;
@@ -816,16 +2213,31 @@ bool NotifyGdb::BuildLineProg(MemBuf& buf, PCODE startAddr, SymbolsInfo* lines,
}
/* Build the DWARF .debug_str section */
-bool NotifyGdb::BuildDebugStrings(MemBuf& buf)
+bool NotifyGdb::BuildDebugStrings(MemBuf& buf, PTK_TypeInfoMap pTypeMap)
{
- uint32_t totalLength = 0;
-
+ int totalLength = 0;
+
/* calculate total section size */
for (int i = 0; i < DebugStringCount; ++i)
{
totalLength += strlen(DebugStrings[i]) + 1;
}
-
+
+ for (int i = 0; i < method.GetCount(); ++i)
+ {
+ method[i]->DumpStrings(nullptr, totalLength);
+ }
+
+ {
+ auto iter = pTypeMap->Begin();
+ while (iter != pTypeMap->End())
+ {
+ TypeInfoBase *typeInfo = iter->Value();
+ typeInfo->DumpStrings(nullptr, totalLength);
+ iter++;
+ }
+ }
+
buf.MemSize = totalLength;
buf.MemPtr = new (nothrow) char[totalLength];
@@ -834,12 +2246,28 @@ bool NotifyGdb::BuildDebugStrings(MemBuf& buf)
/* copy strings */
char* bufPtr = buf.MemPtr;
+ int offset = 0;
for (int i = 0; i < DebugStringCount; ++i)
{
- strcpy(bufPtr, DebugStrings[i]);
- bufPtr += strlen(DebugStrings[i]) + 1;
+ strcpy(bufPtr + offset, DebugStrings[i]);
+ offset += strlen(DebugStrings[i]) + 1;
}
-
+
+ for (int i = 0; i < method.GetCount(); ++i)
+ {
+ method[i]->DumpStrings(bufPtr, offset);
+ }
+
+ {
+ auto iter = pTypeMap->Begin();
+ while (iter != pTypeMap->End())
+ {
+ TypeInfoBase *typeInfo = iter->Value();
+ typeInfo->DumpStrings(bufPtr, offset);
+ iter++;
+ }
+ }
+
return true;
}
@@ -848,7 +2276,7 @@ bool NotifyGdb::BuildDebugAbbrev(MemBuf& buf)
{
buf.MemPtr = new (nothrow) char[AbbrevTableSize];
buf.MemSize = AbbrevTableSize;
-
+
if (buf.MemPtr == nullptr)
return false;
@@ -857,31 +2285,79 @@ bool NotifyGdb::BuildDebugAbbrev(MemBuf& buf)
}
/* Build tge DWARF .debug_info section */
-bool NotifyGdb::BuildDebugInfo(MemBuf& buf)
+bool NotifyGdb::BuildDebugInfo(MemBuf& buf, PTK_TypeInfoMap pTypeMap, SymbolsInfo* lines, unsigned nlines)
{
- buf.MemSize = sizeof(DwarfCompUnit) + sizeof(DebugInfo) + 1;
+ int totalTypeVarSubSize = 0;
+ {
+ auto iter = pTypeMap->Begin();
+ while (iter != pTypeMap->End())
+ {
+ TypeInfoBase *typeInfo = iter->Value();
+ typeInfo->DumpDebugInfo(nullptr, totalTypeVarSubSize);
+ iter++;
+ }
+ }
+
+ 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];
if (buf.MemPtr == nullptr)
return false;
-
+ int offset = 0;
/* Compile uint header */
DwarfCompUnit* cu = reinterpret_cast<DwarfCompUnit*>(buf.MemPtr.GetValue());
cu->m_length = buf.MemSize - sizeof(uint32_t);
cu->m_version = 4;
cu->m_abbrev_offset = 0;
cu->m_addr_size = ADDRESS_SIZE;
-
- /* copy debug information */
- DebugInfo* di = reinterpret_cast<DebugInfo*>(buf.MemPtr + sizeof(DwarfCompUnit));
- memcpy(buf.MemPtr + sizeof(DwarfCompUnit), &debugInfo, sizeof(DebugInfo));
- di->m_prod_off = 0;
- di->m_cu_name = strlen(DebugStrings[0]) + 1;
- di->m_sub_name = strlen(DebugStrings[0]) + 1 + strlen(DebugStrings[1]) + 1 + strlen(DebugStrings[2]) + 1;
- di->m_type_name = strlen(DebugStrings[0]) + 1 + strlen(DebugStrings[1]) + 1 + strlen(DebugStrings[2]) + 1 + strlen(DebugStrings[3]) + 1;
-
- /* zero end marker */
- buf.MemPtr[buf.MemSize-1] = 0;
+ offset += sizeof(DwarfCompUnit);
+ DebugInfoCU* diCU =
+ reinterpret_cast<DebugInfoCU*>(buf.MemPtr + offset);
+ memcpy(buf.MemPtr + offset, &debugInfoCU, sizeof(DebugInfoCU));
+ offset += sizeof(DebugInfoCU);
+ diCU->m_prod_off = 0;
+ diCU->m_cu_name = strlen(DebugStrings[0]) + 1;
+ {
+ auto iter = pTypeMap->Begin();
+ while (iter != pTypeMap->End())
+ {
+ TypeInfoBase *typeInfo = iter->Value();
+ typeInfo->DumpDebugInfo(buf.MemPtr, offset);
+ iter++;
+ }
+ }
+ for (int i = 0; i < method.GetCount(); ++i)
+ {
+ if (!method[i]->IsDumped())
+ {
+ method[i]->DumpDebugInfo(buf.MemPtr, offset);
+ }
+ else
+ {
+ method[i]->DumpDebugInfo(buf.MemPtr, method[i]->m_entry_offset);
+ }
+ }
+ memset(buf.MemPtr + offset, 0, buf.MemSize - offset);
return true;
}
@@ -908,12 +2384,60 @@ bool NotifyGdb::BuildDebugPub(MemBuf& buf, const char* name, uint32_t size, uint
return true;
}
+/* Store addresses and names of the called methods into symbol table */
+bool NotifyGdb::CollectCalledMethods(CalledMethod* pCalledMethods, TADDR nativeCode)
+{
+ AddrSet tmpCodeAddrs;
+
+ if (!codeAddrs.Contains(nativeCode))
+ codeAddrs.Add(nativeCode);
+
+ CalledMethod* pList = pCalledMethods;
+
+ /* count called methods */
+ while (pList != NULL)
+ {
+ TADDR callAddr = (TADDR)pList->GetCallAddr();
+ if (!tmpCodeAddrs.Contains(callAddr) && !codeAddrs.Contains(callAddr)) {
+ tmpCodeAddrs.Add(callAddr);
+ }
+ pList = pList->GetNext();
+ }
+
+ SymbolCount = 1 + method.GetCount() + tmpCodeAddrs.GetCount();
+ SymbolNames = new (nothrow) Elf_Symbol[SymbolCount];
+
+ pList = pCalledMethods;
+ int i = 1 + method.GetCount();
+ while (i < SymbolCount && pList != NULL)
+ {
+ TADDR callAddr = (TADDR)pList->GetCallAddr();
+ if (!codeAddrs.Contains(callAddr))
+ {
+ 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;
+ ++i;
+ codeAddrs.Add(callAddr);
+ }
+ CalledMethod* ptr = pList;
+ pList = pList->GetNext();
+ delete ptr;
+ }
+ SymbolCount = i;
+ return true;
+}
+
/* Build ELF .strtab section */
bool NotifyGdb::BuildStringTableSection(MemBuf& buf)
{
int len = 0;
- for (int i = 0; i < sizeof(SymbolNames) / sizeof(SymbolNames[0]); ++i)
- len += strlen(SymbolNames[i]) + 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;
@@ -921,10 +2445,11 @@ bool NotifyGdb::BuildStringTableSection(MemBuf& buf)
if (buf.MemPtr == nullptr)
return false;
char* ptr = buf.MemPtr;
- for (int i = 0; i < sizeof(SymbolNames) / sizeof(SymbolNames[0]); ++i)
+ for (int i = 0; i < SymbolCount; ++i)
{
- strcpy(ptr, SymbolNames[i]);
- ptr += strlen(SymbolNames[i]) + 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;
@@ -934,107 +2459,136 @@ bool NotifyGdb::BuildStringTableSection(MemBuf& buf)
/* Build ELF .symtab section */
bool NotifyGdb::BuildSymbolTableSection(MemBuf& buf, PCODE addr, TADDR codeSize)
{
- buf.MemSize = 2 * sizeof(Elf_Sym);
+ 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;
Elf_Sym *sym = reinterpret_cast<Elf_Sym*>(buf.MemPtr.GetValue());
- sym->st_name = 0;
- sym->st_info = 0;
- sym->st_other = 0;
- sym->st_value = 0;
- sym->st_size = 0;
- sym->st_shndx = SHN_UNDEF;
-
- sym++;
- //sym = reinterpret_cast<Elf_Sym*>(buf.MemPtr.GetValue() + sizeof(Elf_Sym));
- sym->st_name = 1;
- sym->setBindingAndType(STB_GLOBAL, STT_FUNC);
- sym->st_other = 0;
-#ifdef _TARGET_ARM_
- sym->st_value = 1; // for THUMB code
-#else
- sym->st_value = 0;
-#endif
- sym->st_shndx = 1; // .text section index
- sym->st_size = codeSize;
- return true;
-}
-/* Build ELF string section */
-bool NotifyGdb::BuildSectionNameTable(MemBuf& buf)
-{
- uint32_t totalLength = 0;
+ sym[0].st_name = 0;
+ sym[0].st_info = 0;
+ sym[0].st_other = 0;
+ sym[0].st_value = 0;
+ sym[0].st_size = 0;
+ sym[0].st_shndx = SHN_UNDEF;
- /* calculate total size */
- for (int i = 0; i < SectionNamesCount; ++i)
+ for (int i = 1; i < 1 + method.GetCount(); ++i)
{
- totalLength += strlen(SectionNames[i]) + 1;
+ 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_shndx = textSectionIndex;
+ sym[i].st_size = SymbolNames[i].m_size;
}
- buf.MemSize = totalLength;
- buf.MemPtr = new (nothrow) char[totalLength];
- if (buf.MemPtr == nullptr)
- return false;
-
- /* copy strings */
- char* bufPtr = buf.MemPtr;
- for (int i = 0; i < SectionNamesCount; ++i)
+ for (int i = 1 + method.GetCount(); i < SymbolCount; ++i)
{
- strcpy(bufPtr, SectionNames[i]);
- bufPtr += strlen(SectionNames[i]) + 1;
+ 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
+ sym[i].st_size = 8;
+#ifdef _TARGET_ARM_
+ sym[i].st_value = 1; // for THUMB code
+#else
+ sym[i].st_value = 0;
+#endif
}
-
return true;
}
-/* Build the ELF section headers table */
-bool NotifyGdb::BuildSectionTable(MemBuf& buf)
+int NotifyGdb::GetSectionIndex(const char *sectName)
{
- Elf_Shdr* sectionHeaders = new (nothrow) Elf_Shdr[SectionNamesCount - 1];
- Elf_Shdr* pSh = sectionHeaders;
+ for (int i = 0; i < SectionNamesCount; ++i)
+ if (strcmp(SectionNames[i], sectName) == 0)
+ return i;
+ return -1;
+}
+
+/* Build the ELF section headers table and section names table */
+bool NotifyGdb::BuildSectionTables(MemBuf& sectBuf, MemBuf& strBuf)
+{
+ static const int symtabSectionIndex = GetSectionIndex(".symtab");
+ static const int nullSectionIndex = GetSectionIndex("");
+
+ 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;
}
-
- /* NULL entry */
- pSh->sh_name = 0;
- pSh->sh_type = SHT_NULL;
- pSh->sh_flags = 0;
- pSh->sh_addr = 0;
- pSh->sh_offset = 0;
- pSh->sh_size = 0;
- pSh->sh_link = SHN_UNDEF;
- pSh->sh_info = 0;
- pSh->sh_addralign = 0;
- pSh->sh_entsize = 0;
-
- ++pSh;
- /* fill section header data */
- uint32_t sectNameOffset = 1;
- for (int i = 1; i < SectionNamesCount - 1; ++i, ++pSh)
+
+ sectBuf.MemPtr = reinterpret_cast<char*>(sectionHeaders);
+ sectBuf.MemSize = sizeof(Elf_Shdr) * (SectionNamesCount + thunks_count);
+
+ Elf_Shdr* pSh = sectionHeaders;
+ uint32_t sectNameOffset = 0;
+
+ // Additional memory for remaining section names,
+ // grows twice on each reallocation.
+ int addSize = SECT_NAME_LENGTH;
+
+ // Fill section headers and names
+ for (int i = 0; i < SectionNamesCount + thunks_count; ++i, ++pSh)
{
+ char thunkSectNameBuf[256]; // temporary buffer for .thunk_# section name
+ const char *sectName;
+
+ bool isThunkSection = i >= SectionNamesCount;
+ if (isThunkSection)
+ {
+ sprintf_s(thunkSectNameBuf, _countof(thunkSectNameBuf), ".thunk_%i", i);
+ sectName = thunkSectNameBuf;
+ }
+ else
+ {
+ sectName = SectionNames[i];
+ }
+
+ // Ensure that there is enough memory for section name,
+ // reallocate if necessary.
pSh->sh_name = sectNameOffset;
- sectNameOffset += strlen(SectionNames[i]) + 1;
- pSh->sh_type = Sections[i].m_type;
- pSh->sh_flags = Sections[i].m_flags;
+ sectNameOffset += strlen(sectName) + 1;
+ if (sectNameOffset > strBuf.MemSize)
+ {
+ // Allocate more memory for remaining section names
+ if (!strBuf.Resize(sectNameOffset + addSize))
+ return false;
+ addSize *= 2;
+ }
+
+ strcpy(strBuf.MemPtr + pSh->sh_name, sectName);
+
+ // All .thunk_* sections have the same type and flags
+ int index = isThunkSection ? SectionNamesCount : i;
+ pSh->sh_type = Sections[index].m_type;
+ pSh->sh_flags = Sections[index].m_flags;
+
pSh->sh_addr = 0;
pSh->sh_offset = 0;
pSh->sh_size = 0;
pSh->sh_link = SHN_UNDEF;
pSh->sh_info = 0;
- pSh->sh_addralign = 1;
- if (strcmp(SectionNames[i], ".symtab") == 0)
- pSh->sh_entsize = sizeof(Elf_Sym);
- else
- pSh->sh_entsize = 0;
+ pSh->sh_addralign = i == nullSectionIndex ? 0 : 1;
+ pSh->sh_entsize = i == symtabSectionIndex ? sizeof(Elf_Sym) : 0;
}
- buf.MemPtr = reinterpret_cast<char*>(sectionHeaders);
- buf.MemSize = sizeof(Elf_Shdr) * (SectionNamesCount - 1);
+ // Set actual used size to avoid garbage in ELF section
+ strBuf.MemSize = sectNameOffset;
return true;
}
@@ -1042,17 +2596,18 @@ bool NotifyGdb::BuildSectionTable(MemBuf& buf)
bool NotifyGdb::BuildELFHeader(MemBuf& buf)
{
Elf_Ehdr* header = new (nothrow) Elf_Ehdr;
- buf.MemPtr = reinterpret_cast<char*>(header);
- buf.MemSize = sizeof(Elf_Ehdr);
-
+
if (header == nullptr)
+ {
return false;
-
+ }
+
+ buf.MemPtr = reinterpret_cast<char*>(header);
+ buf.MemSize = sizeof(Elf_Ehdr);
return true;
-
}
-/* Split full path name into directory & file anmes */
+/* Split full path name into directory & file names */
void NotifyGdb::SplitPathname(const char* path, const char*& pathName, const char*& fileName)
{
char* pSlash = strrchr(path, '/');
@@ -1070,47 +2625,6 @@ void NotifyGdb::SplitPathname(const char* path, const char*& pathName, const cha
}
}
-/* LEB128 for 32-bit unsigned integer */
-int NotifyGdb::Leb128Encode(uint32_t num, char* buf, int size)
-{
- int i = 0;
-
- do
- {
- uint8_t byte = num & 0x7F;
- if (i >= size)
- break;
- num >>= 7;
- if (num != 0)
- byte |= 0x80;
- buf[i++] = byte;
- }
- while (num != 0);
-
- return i;
-}
-
-/* LEB128 for 32-bit signed integer */
-int NotifyGdb::Leb128Encode(int32_t num, char* buf, int size)
-{
- int i = 0;
- bool hasMore = true, isNegative = num < 0;
-
- while (hasMore && i < size)
- {
- uint8_t byte = num & 0x7F;
- num >>= 7;
-
- if ((num == 0 && (byte & 0x40) == 0) || (num == -1 && (byte & 0x40) == 0x40))
- hasMore = false;
- else
- byte |= 0x80;
- buf[i++] = byte;
- }
-
- return i;
-}
-
#ifdef _DEBUG
void NotifyGdb::DumpElf(const char* methodName, const MemBuf& elfFile)
{
diff --git a/src/vm/gdbjit.h b/src/vm/gdbjit.h
index 467a970c0b..3160eccf57 100644
--- a/src/vm/gdbjit.h
+++ b/src/vm/gdbjit.h
@@ -16,6 +16,7 @@
#include <stdint.h>
#include "method.hpp"
+#include "dbginterface.h"
#include "../inc/llvm/ELF.h"
#include "../inc/llvm/Dwarf.h"
@@ -33,6 +34,46 @@
#error "Target is not supported"
#endif
+
+static constexpr const int CorElementTypeToDWEncoding[] =
+{
+/* ELEMENT_TYPE_END */ 0,
+/* ELEMENT_TYPE_VOID */ DW_ATE_address,
+/* ELEMENT_TYPE_BOOLEAN */ DW_ATE_boolean,
+/* ELEMENT_TYPE_CHAR */ DW_ATE_UTF,
+/* ELEMENT_TYPE_I1 */ DW_ATE_signed,
+/* ELEMENT_TYPE_U1 */ DW_ATE_unsigned,
+/* ELEMENT_TYPE_I2 */ DW_ATE_signed,
+/* ELEMENT_TYPE_U2 */ DW_ATE_unsigned,
+/* ELEMENT_TYPE_I4 */ DW_ATE_signed,
+/* ELEMENT_TYPE_U4 */ DW_ATE_unsigned,
+/* ELEMENT_TYPE_I8 */ DW_ATE_signed,
+/* ELEMENT_TYPE_U8 */ DW_ATE_unsigned,
+/* ELEMENT_TYPE_R4 */ DW_ATE_float,
+/* ELEMENT_TYPE_R8 */ DW_ATE_float,
+/* ELEMENT_TYPE_STRING */ DW_ATE_address,
+/* ELEMENT_TYPE_PTR */ DW_ATE_address,
+/* ELEMENT_TYPE_BYREF */ DW_ATE_address,
+/* ELEMENT_TYPE_VALUETYPE */ DW_ATE_address,
+/* ELEMENT_TYPE_CLASS */ DW_ATE_address,
+/* ELEMENT_TYPE_VAR */ DW_ATE_address,
+/* ELEMENT_TYPE_ARRAY */ DW_ATE_address,
+/* ELEMENT_TYPE_GENERICINST */ DW_ATE_address,
+/* ELEMENT_TYPE_TYPEDBYREF */ DW_ATE_address,
+/* SKIP 17 */ DW_ATE_address,
+/* ELEMENT_TYPE_I */ DW_ATE_signed,
+/* ELEMENT_TYPE_U */ DW_ATE_unsigned,
+/* SKIP 1a */ DW_ATE_address,
+/* ELEMENT_TYPE_FNPTR */ DW_ATE_address,
+/* ELEMENT_TYPE_OBJECT */ DW_ATE_address,
+/* ELEMENT_TYPE_SZARRAY */ DW_ATE_address,
+/* ELEMENT_TYPE_MVAR */ DW_ATE_address,
+/* ELEMENT_TYPE_CMOD_REQD */ DW_ATE_address,
+/* ELEMENT_TYPE_CMOD_OPT */ DW_ATE_address,
+/* ELEMENT_TYPE_INTERNAL */ DW_ATE_address,
+/* ELEMENT_TYPE_MAX */ DW_ATE_address,
+};
+
struct __attribute__((packed)) DwarfCompUnit
{
uint32_t m_length;
@@ -64,51 +105,374 @@ struct __attribute__((packed)) DwarfLineNumHeader
uint8_t m_std_num_arg[DW_LNS_MAX];
};
+const ULONG32 HiddenLine = 0x00feefee;
+
struct SymbolsInfo
{
int lineNumber, ilOffset, nativeOffset, fileIndex;
char fileName[2*MAX_PATH_FNAME];
+ ICorDebugInfo::SourceTypes source;
+};
+
+class DwarfDumpable
+{
+public:
+ // writes all string literals this type needs to ptr
+ virtual void DumpStrings(char* ptr, int& offset) = 0;
+
+ virtual void DumpDebugInfo(char* ptr, int& offset) = 0;
+};
+
+class LocalsInfo
+{
+public:
+ int size;
+ char** localsName;
+ ULONG32 countVars;
+ ICorDebugInfo::NativeVarInfo *pVars;
+};
+
+class TypeMember;
+
+class TypeInfoBase : public DwarfDumpable
+{
+public:
+ TypeInfoBase(TypeHandle typeHandle)
+ : m_type_name(nullptr),
+ m_type_name_offset(0),
+ m_type_size(0),
+ m_type_offset(0),
+ typeHandle(typeHandle),
+ typeKey(typeHandle.GetTypeKey())
+ {
+ }
+
+ 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;
+ int m_type_name_offset;
+ ULONG m_type_size;
+ int m_type_offset;
+private:
+ TypeHandle typeHandle;
+ 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 RefTypeInfo: public TypeInfoBase
+{
+public:
+ RefTypeInfo(TypeHandle typeHandle, TypeInfoBase *value_type)
+ : TypeInfoBase(typeHandle),
+ m_value_type(value_type)
+ {
+ }
+ void DumpStrings(char* ptr, int& offset) override;
+ void DumpDebugInfo(char* ptr, int& offset) override;
+ TypeInfoBase *m_value_type;
+};
+
+class ClassTypeInfo: public TypeInfoBase
+{
+public:
+ ClassTypeInfo(TypeHandle typeHandle, int num_members);
+ ~ClassTypeInfo();
+
+ void DumpStrings(char* ptr, int& offset) override;
+ void DumpDebugInfo(char* ptr, int& offset) override;
+
+ int m_num_members;
+ TypeMember* members;
+};
+
+class TypeMember: public DwarfDumpable
+{
+public:
+ TypeMember()
+ : m_member_name(nullptr),
+ m_member_name_offset(0),
+ m_member_offset(0),
+ m_static_member_address(0),
+ m_member_type(nullptr)
+ {
+ }
+
+ ~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;
+ int m_member_name_offset;
+ int m_member_offset;
+ TADDR m_static_member_address;
+ TypeInfoBase *m_member_type;
};
+class ArrayTypeInfo: public TypeInfoBase
+{
+public:
+ ArrayTypeInfo(TypeHandle typeHandle, int countOffset, TypeInfoBase* elemType)
+ : TypeInfoBase(typeHandle),
+ m_count_offset(countOffset),
+ 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;
+ TypeInfoBase *m_elem_type;
+};
+
+class VarDebugInfo: public DwarfDumpable
+{
+public:
+ VarDebugInfo(int abbrev)
+ : m_var_name(nullptr),
+ m_var_abbrev(abbrev),
+ m_var_name_offset(0),
+ m_il_index(0),
+ m_native_offset(0),
+ m_var_type(nullptr)
+ {
+ }
+
+ VarDebugInfo()
+ : m_var_name(nullptr),
+ m_var_abbrev(6),
+ m_var_name_offset(0),
+ m_il_index(0),
+ m_native_offset(0),
+ m_var_type(nullptr)
+ {
+ }
+
+ virtual ~VarDebugInfo()
+ {
+ delete[] m_var_name;
+ }
+
+ void DumpStrings(char* ptr, int& offset) override;
+ void DumpDebugInfo(char* ptr, int& offset) override;
+
+ 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;
+};
class NotifyGdb
{
public:
static void MethodCompiled(MethodDesc* MethodDescPtr);
static void MethodDropped(MethodDesc* MethodDescPtr);
+ template <typename PARENT_TRAITS>
+ class DeleteValuesOnDestructSHashTraits : public PARENT_TRAITS
+ {
+ public:
+ static inline void OnDestructPerEntryCleanupAction(typename PARENT_TRAITS::element_t e)
+ {
+ delete e.Value();
+ }
+ static const bool s_DestructPerEntryCleanupAction = true;
+ };
+
+ template <typename VALUE>
+ class TypeKeyHashTraits : public DefaultSHashTraits< KeyValuePair<TypeKey*,VALUE> >
+ {
+ public:
+ // explicitly declare local typedefs for these traits types, otherwise
+ // the compiler may get confused
+ typedef typename DefaultSHashTraits< KeyValuePair<TypeKey*,VALUE> >::element_t element_t;
+ typedef typename DefaultSHashTraits< KeyValuePair<TypeKey*,VALUE> >::count_t count_t;
+ typedef TypeKey* key_t;
+
+ static key_t GetKey(element_t e)
+ {
+ LIMITED_METHOD_CONTRACT;
+ return e.Key();
+ }
+ static BOOL Equals(key_t k1, key_t k2)
+ {
+ LIMITED_METHOD_CONTRACT;
+ return k1->Equals(k2);
+ }
+ static count_t Hash(key_t k)
+ {
+ LIMITED_METHOD_CONTRACT;
+ return k->ComputeHash();
+ }
+
+ static const element_t Null() { LIMITED_METHOD_CONTRACT; return element_t(key_t(),VALUE()); }
+ static const element_t Deleted() { LIMITED_METHOD_CONTRACT; return element_t(key_t(-1), VALUE()); }
+ static bool IsNull(const element_t &e) { LIMITED_METHOD_CONTRACT; return e.Key() == key_t(); }
+ static bool IsDeleted(const element_t &e) { return e.Key() == key_t(-1); }
+ };
+
+ typedef MapSHash<TypeKey*, TypeInfoBase*, DeleteValuesOnDestructSHashTraits<TypeKeyHashTraits<TypeInfoBase*>>> TK_TypeInfoMap;
+ typedef TK_TypeInfoMap* PTK_TypeInfoMap;
+ typedef SetSHash< TADDR,
+ NoRemoveSHashTraits <
+ NonDacAwareSHashTraits< SetSHashTraits <TADDR> >
+ > > AddrSet;
private:
+
struct MemBuf
{
NewArrayHolder<char> MemPtr;
unsigned MemSize;
MemBuf() : MemPtr(0), MemSize(0)
{}
+ bool Resize(unsigned newSize)
+ {
+ if (newSize == 0)
+ {
+ MemPtr = nullptr;
+ MemSize = 0;
+ return true;
+ }
+ char *tmp = new (nothrow) char [newSize];
+ if (tmp == nullptr)
+ return false;
+ memmove(tmp, MemPtr.GetValue(), newSize < MemSize ? newSize : MemSize);
+ MemPtr = tmp;
+ MemSize = newSize;
+ return true;
+ }
};
+ static int GetSectionIndex(const char *sectName);
static bool BuildELFHeader(MemBuf& buf);
- static bool BuildSectionNameTable(MemBuf& buf);
- static bool BuildSectionTable(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);
- static bool BuildDebugAbbrev(MemBuf& buf);
- static bool BuildDebugInfo(MemBuf& buf);
+ static bool BuildDebugStrings(MemBuf& buf, PTK_TypeInfoMap pTypeMap);
+ static bool BuildDebugAbbrev(MemBuf& buf);
+ static bool BuildDebugInfo(MemBuf& buf, PTK_TypeInfoMap pTypeMap, SymbolsInfo* lines, unsigned nlines);
static bool BuildDebugPub(MemBuf& buf, const char* name, uint32_t size, uint32_t dieOffset);
- static bool BuildLineTable(MemBuf& buf, PCODE startAddr, SymbolsInfo* lines, unsigned nlines);
+ static bool BuildLineTable(MemBuf& buf, PCODE startAddr, TADDR codeSize, SymbolsInfo* lines, unsigned nlines);
static bool BuildFileTable(MemBuf& buf, SymbolsInfo* lines, unsigned nlines);
- static bool BuildLineProg(MemBuf& buf, PCODE startAddr, SymbolsInfo* lines, unsigned nlines);
- static bool FitIntoSpecialOpcode(int8_t line_shift, uint8_t addr_shift);
+ static bool BuildLineProg(MemBuf& buf, PCODE startAddr, TADDR codeSize, SymbolsInfo* lines, unsigned nlines);
static void IssueSetAddress(char*& ptr, PCODE addr);
static void IssueEndOfSequence(char*& ptr);
static void IssueSimpleCommand(char*& ptr, uint8_t command);
static void IssueParamCommand(char*& ptr, uint8_t command, char* param, int param_len);
- static void IssueSpecialCommand(char*& ptr, int8_t line_shift, uint8_t addr_shift);
static void SplitPathname(const char* path, const char*& pathName, const char*& fileName);
- static int Leb128Encode(uint32_t num, char* buf, int size);
- static int Leb128Encode(int32_t num, char* buf, int size);
+ static bool CollectCalledMethods(CalledMethod* pCM, TADDR nativeCode);
#ifdef _DEBUG
static void DumpElf(const char* methodName, const MemBuf& buf);
#endif
};
+class FunctionMember: public TypeMember
+{
+public:
+ FunctionMember(MethodDesc *md, int num_locals, int num_args)
+ : TypeMember(),
+ md(md),
+ m_file(1),
+ m_line(1),
+ m_sub_low_pc(0),
+ m_sub_high_pc(0),
+ m_sub_loc(),
+ m_num_args(num_args),
+ m_num_locals(num_locals),
+ m_num_vars(num_args + num_locals),
+ m_entry_offset(0),
+ vars(new VarDebugInfo[m_num_vars]),
+ lines(NULL),
+ nlines(0),
+ m_linkage_name_offset(0),
+ dumped(false)
+ {
+ m_sub_loc[0] = 1;
+#if defined(_TARGET_AMD64_)
+ m_sub_loc[1] = DW_OP_reg6;
+#elif defined(_TARGET_ARM_)
+ m_sub_loc[1] = DW_OP_reg11;
+#else
+#error Unsupported platform!
+#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);
+ BOOL IsDumped()
+ {
+ return dumped;
+ }
+
+ MethodDesc *md;
+ uint8_t m_file, m_line;
+ uintptr_t m_sub_low_pc, m_sub_high_pc;
+ uint8_t m_sub_loc[2];
+ uint8_t m_num_args;
+ uint8_t m_num_locals;
+ uint16_t m_num_vars;
+ int m_entry_offset;
+ VarDebugInfo* vars;
+ SymbolsInfo* lines;
+ unsigned nlines;
+ int m_linkage_name_offset;
+private:
+ int GetArgsAndLocalsLen();
+ void MangleName(char *buf, int &buf_offset, const char *name);
+ void DumpMangledNamespaceAndMethod(char *buf, int &offset, const char *nspace, const char *mname);
+ 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);
+ BOOL dumped;
+};
#endif // #ifndef __GDBJIT_H__
diff --git a/src/vm/gdbjithelpers.h b/src/vm/gdbjithelpers.h
index 1298141e2d..3a34dd179a 100644
--- a/src/vm/gdbjithelpers.h
+++ b/src/vm/gdbjithelpers.h
@@ -23,6 +23,8 @@ struct MethodDebugInfo
{
SequencePointInfo* points;
int size;
+ char16_t** locals;
+ int localsSize;
};
typedef BOOL (*GetInfoForMethodDelegate)(const char*, unsigned int, MethodDebugInfo& methodDebugInfo);
diff --git a/src/vm/hash.cpp b/src/vm/hash.cpp
index 205f736b0d..6b6b21391f 100644
--- a/src/vm/hash.cpp
+++ b/src/vm/hash.cpp
@@ -547,8 +547,8 @@ UPTR HashMap::LookupValue(UPTR key, UPTR value)
// BROKEN: This is called for the RCWCache on the GC thread
// Also called by AppDomain::FindCachedAssembly to resolve AssemblyRef -- this is used by stack walking on the GC thread.
- // See comments in GCHeap::RestartEE (above the call to SyncClean::CleanUp) for reason to enter COOP mode.
- // However, if the current thread is the GC thread, we know we're not going to call GCHeap::RestartEE
+ // See comments in GCHeapUtilities::RestartEE (above the call to SyncClean::CleanUp) for reason to enter COOP mode.
+ // However, if the current thread is the GC thread, we know we're not going to call GCHeapUtilities::RestartEE
// while accessing the HashMap, so it's safe to proceed.
// (m_fAsyncMode && !IsGCThread() is the condition for entering COOP mode. I.e., enable COOP GC only if
// the HashMap is in async mode and this is not a GC thread.)
diff --git a/src/vm/i386/RedirectedHandledJITCase.asm b/src/vm/i386/RedirectedHandledJITCase.asm
index 80345623e7..44a93bd10c 100644
--- a/src/vm/i386/RedirectedHandledJITCase.asm
+++ b/src/vm/i386/RedirectedHandledJITCase.asm
@@ -103,7 +103,7 @@ _ExceptionHijack@0 PROC PUBLIC
; This is where we land when we're hijacked from an IP by the debugger.
; The debugger has already pushed the args:
; - a CONTEXT
- ; - a EXCEPTION_RECORD onto the stack
+ ; - an EXCEPTION_RECORD onto the stack
; - an DWORD to use to mulitplex the hijack
; - an arbitrary void* data parameter
call _ExceptionHijackWorker@16
diff --git a/src/vm/i386/asmconstants.h b/src/vm/i386/asmconstants.h
index 5fd39d6897..c42b167f32 100644
--- a/src/vm/i386/asmconstants.h
+++ b/src/vm/i386/asmconstants.h
@@ -449,6 +449,24 @@ ASMCONSTANTS_C_ASSERT(CallDescrData__fpReturnSize == offsetof(CallDescrD
ASMCONSTANTS_C_ASSERT(CallDescrData__pTarget == offsetof(CallDescrData, pTarget))
ASMCONSTANTS_C_ASSERT(CallDescrData__returnValue == offsetof(CallDescrData, returnValue))
+#define UMEntryThunk__m_pUMThunkMarshInfo 0x0C
+ASMCONSTANTS_C_ASSERT(UMEntryThunk__m_pUMThunkMarshInfo == offsetof(UMEntryThunk, m_pUMThunkMarshInfo))
+
+#define UMEntryThunk__m_dwDomainId 0x10
+ASMCONSTANTS_C_ASSERT(UMEntryThunk__m_dwDomainId == offsetof(UMEntryThunk, m_dwDomainId))
+
+#define UMThunkMarshInfo__m_pILStub 0x00
+ASMCONSTANTS_C_ASSERT(UMThunkMarshInfo__m_pILStub == offsetof(UMThunkMarshInfo, m_pILStub))
+
+#define UMThunkMarshInfo__m_cbActualArgSize 0x04
+ASMCONSTANTS_C_ASSERT(UMThunkMarshInfo__m_cbActualArgSize == offsetof(UMThunkMarshInfo, m_cbActualArgSize))
+
+#ifndef CROSSGEN_COMPILE
+#define Thread__m_pDomain 0x14
+ASMCONSTANTS_C_ASSERT(Thread__m_pDomain == offsetof(Thread, m_pDomain));
+
+#endif
+
#undef ASMCONSTANTS_C_ASSERT
#undef ASMCONSTANTS_RUNTIME_ASSERT
diff --git a/src/vm/i386/asmhelpers.S b/src/vm/i386/asmhelpers.S
new file mode 100644
index 0000000000..1c6f0a36f6
--- /dev/null
+++ b/src/vm/i386/asmhelpers.S
@@ -0,0 +1,1140 @@
+// Licensed to the .NET Foundation under one or more 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"
+
+//
+// FramedMethodFrame prolog
+//
+.macro STUB_PROLOG
+ // push ebp-frame
+ PROLOG_BEG
+
+ // save CalleeSavedRegisters
+ PROLOG_PUSH ebx
+ PROLOG_PUSH esi
+ PROLOG_PUSH edi
+
+ // push ArgumentRegisters
+ PROLOG_PUSH ecx
+ PROLOG_PUSH edx
+
+ // set frame pointer
+ PROLOG_END
+.endm
+
+//
+// FramedMethodFrame epilog
+//
+.macro STUB_EPILOG
+ // restore stack pointer
+ EPILOG_BEG
+
+ // pop ArgumentRegisters
+ EPILOG_POP edx
+ EPILOG_POP ecx
+
+ // pop CalleeSavedRegisters
+ EPILOG_POP edi
+ EPILOG_POP esi
+ EPILOG_POP ebx
+
+ // pop ebp-frame
+ EPILOG_END
+.endm
+
+//
+// FramedMethodFrame epilog
+//
+.macro STUB_EPILOG_RETURN
+ // pop ArgumentRegisters
+ add esp, 8
+
+ // pop CalleeSavedRegisters
+ pop edi
+ pop esi
+ pop ebx
+ pop ebp
+.endm
+
+.macro STUB_PROLOG_2_HIDDEN_ARGS
+ //
+ // The stub arguments are where we want to setup the TransitionBlock. We will
+ // setup the TransitionBlock later once we can trash them
+ //
+ // push ebp-frame
+ // push ebp
+ // mov ebp,esp
+
+ // save CalleeSavedRegisters
+ // push ebx
+
+ push esi
+ push edi
+
+ // push ArgumentRegisters
+ push ecx
+ push edx
+
+ mov ecx, [esp + 4*4]
+ mov edx, [esp + 5*4]
+
+ // Setup up proper EBP frame now that the stub arguments can be trashed
+ mov [esp + 4*4], ebx
+ mov [esp + 5*4], ebp
+ lea ebp, [esp + 5*4]
+.endm
+
+LEAF_ENTRY ResetCurrentContext, _TEXT
+ push eax
+
+ // clear the direction flag (used for rep instructions)
+ cld
+
+ // load flags into AX
+ fnstcw [esp - 2]
+ mov ax, [esp - 2]
+
+ fninit // reset FPU
+ and ax, 0f00h // preserve precision and rounding control
+ or ax, 007fh // mask all exceptions
+
+ // preserve precision control
+ mov ax, [esp - 2]
+ fldcw [esp - 2]
+
+ pop eax
+ ret
+LEAF_END ResetCurrentContext, _TEXT
+
+// Incoming:
+// ESP+4: Pointer to buffer to which FPU state should be saved
+LEAF_ENTRY CaptureFPUContext, _TEXT
+ mov ecx, [esp + 4]
+ fnstenv [ecx]
+ ret 4
+
+LEAF_END CaptureFPUContext, _TEXT
+
+// Incoming:
+// ESP+4: Pointer to buffer from which FPU state should be restored
+LEAF_ENTRY RestoreFPUContext, _TEXT
+ mov ecx, [esp + 4]
+ fldenv [ecx]
+ ret 4
+LEAF_END RestoreFPUContext, _TEXT
+
+LEAF_ENTRY ResumeAtJitEHHelper, _TEXT
+ mov edx, [esp + 4] // edx = pContext (EHContext*)
+
+ mov ebx, [edx + EHContext_Ebx]
+ mov esi, [edx + EHContext_Esi]
+ mov edi, [edx + EHContext_Edi]
+ mov ebp, [edx + EHContext_Ebp]
+ mov ecx, [edx + EHContext_Esp]
+ mov eax, [edx + EHContext_Eip]
+ mov [ecx - 4], eax
+ mov eax, [edx + EHContext_Eax]
+ mov [ecx - 8], eax
+ mov eax, [edx + EHContext_Ecx]
+ mov [ecx - 0Ch], eax
+ mov eax, [edx + EHContext_Edx]
+ mov [ecx - 10h], eax
+ lea esp, [ecx - 10h]
+ pop edx
+ pop ecx
+ pop eax
+ ret
+LEAF_END ResumeAtJitEHHelper, _TEXT
+
+// int __stdcall CallJitEHFilterHelper(size_t *pShadowSP, EHContext *pContext);
+// on entry, only the pContext->Esp, Ebx, Esi, Edi, Ebp, and Eip are initialized
+NESTED_ENTRY CallJitEHFilterHelper, _TEXT, NoHandler
+ push ebp
+ mov ebp, esp
+ push ebx
+ push esi
+ push edi
+
+ // Write esp-4 to the shadowSP slot
+ mov eax, [ebp + 8] // pShadowSP = [ebp+8]
+ test eax, eax
+ jz LOCAL_LABEL(DONE_SHADOWSP_FILTER)
+ mov ebx, esp
+ sub ebx, 4
+ or ebx, SHADOW_SP_IN_FILTER_ASM
+ mov [eax], ebx
+
+LOCAL_LABEL(DONE_SHADOWSP_FILTER):
+ mov edx, [ebp + 12] // pContext = [ebp+12]
+ mov eax, [edx + EHContext_Eax]
+ mov ebx, [edx + EHContext_Ebx]
+ mov esi, [edx + EHContext_Esi]
+ mov edi, [edx + EHContext_Edi]
+ mov ebp, [edx + EHContext_Ebp]
+
+ call DWORD PTR [edx + EHContext_Eip]
+#ifdef _DEBUG
+ nop // Indicate that it is OK to call managed code directly from here
+#endif // _DEBUG
+
+ pop edi
+ pop esi
+ pop ebx
+ pop ebp // don't use 'leave' here, as ebp as been trashed
+ ret 8
+NESTED_END CallJitEHFilterHelper, _TEXT
+
+// void __stdcall CallJITEHFinallyHelper(size_t *pShadowSP, EHContext *pContext);
+// on entry, only the pContext->Esp, Ebx, Esi, Edi, Ebp, and Eip are initialized
+NESTED_ENTRY CallJitEHFinallyHelper, _TEXT, NoHandler
+ push ebp
+ mov ebp, esp
+ push ebx
+ push esi
+ push edi
+
+ // Write esp-4 to the shadowSP slot
+ mov eax, [ebp + 8] // pShadowSP = [ebp+8]
+ test eax, eax
+ jz LOCAL_LABEL(DONE_SHADOWSP_FINALLY)
+ mov ebx, esp
+ sub ebx, 4
+ mov [eax], ebx
+
+LOCAL_LABEL(DONE_SHADOWSP_FINALLY):
+ mov edx, [ebp + 12] // pContext = [ebp+12]
+ mov eax, [edx + EHContext_Eax]
+ mov ebx, [edx + EHContext_Ebx]
+ mov esi, [edx + EHContext_Esi]
+ mov edi, [edx + EHContext_Edi]
+ mov ebp, [edx + EHContext_Ebp]
+ call DWORD PTR [edx + EHContext_Eip]
+#ifdef _DEBUG
+ nop // Indicate that it is OK to call managed code directly from here
+#endif // _DEBUG
+
+ // Reflect the changes to the context and only update non-volatile registers.
+ // This will be used later to update REGDISPLAY
+ mov edx, [esp + 12 + 12]
+ mov [edx + EHContext_Ebx], ebx
+ mov [edx + EHContext_Esi], esi
+ mov [edx + EHContext_Edi], edi
+ mov [edx + EHContext_Ebp], ebp
+
+ pop edi
+ pop esi
+ pop ebx
+ pop ebp // don't use 'leave' here, as ebp as been trashed
+ ret 8
+NESTED_END CallJitEHFinallyHelper, _TEXT
+
+LEAF_ENTRY GetSpecificCpuTypeAsm, _TEXT
+ push ebx // ebx is trashed by the cpuid calls
+
+ // See if the chip supports CPUID
+ pushfd
+ pop ecx // Get the EFLAGS
+ mov eax, ecx // Save for later testing
+ xor ecx, 200000h // Invert the ID bit
+ push ecx
+ popfd // Save the updated flags
+ pushfd
+ pop ecx // Retrieve the updated flags
+ xor ecx, eax // Test if it actually changed (bit set means yes)
+ push eax
+ popfd // Restore the flags
+
+ test ecx, 200000h
+ jz LOCAL_LABEL(Assume486)
+
+ xor eax, eax
+ cpuid
+
+ test eax, eax
+ jz LOCAL_LABEL(Assume486) // brif CPUID1 not allowed
+
+ mov eax, 1
+ cpuid
+
+ // filter out everything except family and model
+ // Note that some multi-procs have different stepping number for each proc
+ and eax, 0ff0h
+
+ jmp LOCAL_LABEL(CpuTypeDone)
+
+LOCAL_LABEL(Assume486):
+ mov eax, 0400h // report 486
+
+LOCAL_LABEL(CpuTypeDone):
+ pop ebx
+ ret
+LEAF_END GetSpecificCpuTypeAsm, _TEXT
+
+// DWORD __stdcall GetSpecificCpuFeaturesAsm(DWORD *pInfo);
+LEAF_ENTRY GetSpecificCpuFeaturesAsm, _TEXT
+ push ebx // ebx is trashed by the cpuid calls
+
+ // See if the chip supports CPUID
+ pushfd
+ pop ecx // Get the EFLAGS
+ mov eax, ecx // Save for later testing
+ xor ecx, 200000h // Invert the ID bit.
+ push ecx
+ popfd // Save the updated flags.
+ pushfd
+ pop ecx // Retrieve the updated flags
+ xor ecx, eax // Test if it actually changed (bit set means yes)
+ push eax
+ popfd // Restore the flags
+
+ test ecx, 200000h
+ jz LOCAL_LABEL(CpuFeaturesFail)
+
+ xor eax, eax
+ cpuid
+
+ test eax, eax
+ jz LOCAL_LABEL(CpuFeaturesDone) // br if CPUID1 not allowed
+
+ mov eax, 1
+ cpuid
+ mov eax, edx // return all feature flags
+ mov edx, [esp + 8]
+ test edx, edx
+ jz LOCAL_LABEL(CpuFeaturesDone)
+ mov [edx],ebx // return additional useful information
+ jmp LOCAL_LABEL(CpuFeaturesDone)
+
+LOCAL_LABEL(CpuFeaturesFail):
+ xor eax, eax // Nothing to report
+
+LOCAL_LABEL(CpuFeaturesDone):
+ pop ebx
+ ret 4
+LEAF_END GetSpecificCpuFeaturesAsm, _TEXT
+
+
+// -----------------------------------------------------------------------
+// The out-of-line portion of the code to enable preemptive GC.
+// After the work is done, the code jumps back to the "pRejoinPoint"
+// which should be emitted right after the inline part is generated.
+//
+// Assumptions:
+// ebx = Thread
+// Preserves
+// all registers except ecx.
+//
+// -----------------------------------------------------------------------
+NESTED_ENTRY StubRareEnable, _TEXT, NoHandler
+ push eax
+ push edx
+
+ push ebx
+ call C_FUNC(StubRareEnableWorker)
+
+ pop edx
+ pop eax
+ ret
+NESTED_END StubRareEnable, _TEXT
+
+NESTED_ENTRY StubRareDisableTHROW, _TEXT, NoHandler
+ push eax
+ push edx
+
+ push ebx // Thread
+ call C_FUNC(StubRareDisableTHROWWorker)
+
+ pop edx
+ pop eax
+ 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.
+// ------------------------------------------------------------------------------
+// void STDCALL CallDescrWorkerInternal(CallDescrWorkerParams * pParams)
+NESTED_ENTRY CallDescrWorkerInternal, _TEXT, NoHandler
+ PROLOG_BEG
+ PROLOG_PUSH ebx
+ PROLOG_END
+
+ mov ebx, [esp + ((2 + 1) * 4)]
+
+ // compute padding size
+ mov eax, esp
+ mov ecx, [ebx + CallDescrData__numStackSlots]
+ shl ecx, 2
+ sub eax, ecx
+ and eax, 15
+ // adjust stack offset
+ sub esp, eax
+
+ // copy the stack
+ mov ecx, [ebx +CallDescrData__numStackSlots]
+ mov eax, [ebx +CallDescrData__pSrc]
+ test ecx, ecx
+ jz LOCAL_LABEL(donestack)
+ lea eax, [eax + 4*ecx - 4] // last argument
+ push DWORD PTR [eax]
+ dec ecx
+ jz LOCAL_LABEL(donestack)
+ sub eax, 4
+ push DWORD PTR [eax]
+ dec ecx
+ jz LOCAL_LABEL(donestack)
+
+LOCAL_LABEL(stackloop):
+ sub eax, 4
+ push DWORD PTR [eax]
+ dec ecx
+ jnz LOCAL_LABEL(stackloop)
+
+LOCAL_LABEL(donestack):
+ // now we must push each field of the ArgumentRegister structure
+ mov eax, [ebx + CallDescrData__pArgumentRegisters]
+ mov edx, DWORD PTR [eax]
+ mov ecx, DWORD PTR [eax + 4]
+
+ CHECK_STACK_ALIGNMENT
+ call [ebx + CallDescrData__pTarget]
+#ifdef _DEBUG
+ nop // This is a tag that we use in an assert. Fcalls expect to
+ // be called from Jitted code or from certain blessed call sites like
+ // this one. (See HelperMethodFrame::InsureInit)
+#endif
+
+ // Save FP return value if necessary
+ mov ecx, [ebx + CallDescrData__fpReturnSize]
+ cmp ecx, 0
+ je LOCAL_LABEL(ReturnsInt)
+
+ cmp ecx, 4
+ je LOCAL_LABEL(ReturnsFloat)
+ cmp ecx, 8
+ je LOCAL_LABEL(ReturnsDouble)
+ // unexpected
+ jmp LOCAL_LABEL(Epilog)
+
+LOCAL_LABEL(ReturnsInt):
+ mov [ebx + CallDescrData__returnValue], eax
+ mov [ebx + CallDescrData__returnValue + 4], edx
+
+LOCAL_LABEL(Epilog):
+ // restore the stake pointer
+ lea esp, [ebp - 4]
+
+ EPILOG_BEG
+ EPILOG_POP ebx
+ EPILOG_END
+ ret 4
+
+LOCAL_LABEL(ReturnsFloat):
+ fstp DWORD PTR [ebx + CallDescrData__returnValue] // Spill the Float return value
+ jmp LOCAL_LABEL(Epilog)
+
+LOCAL_LABEL(ReturnsDouble):
+ fstp QWORD PTR [ebx + CallDescrData__returnValue] // Spill the Double return value
+ jmp LOCAL_LABEL(Epilog)
+NESTED_END CallDescrWorkerInternal, _TEXT
+
+#ifdef _DEBUG
+// int __fastcall HelperMethodFrameRestoreState(HelperMethodFrame*, struct MachState *)
+LEAF_ENTRY HelperMethodFrameRestoreState, _TEXT
+ mov eax, edx // eax = MachState*
+#else // _DEBUG
+// int __fastcall HelperMethodFrameRestoreState(struct MachState *)
+LEAF_ENTRY HelperMethodFrameRestoreState, _TEXT
+ mov eax, ecx // eax = MachState*
+#endif // _DEBUG
+ // restore the registers from the m_MachState stucture. Note that
+ // we only do this for register that where not saved on the stack
+ // at the time the machine state snapshot was taken.
+
+ cmp dword ptr [eax+MachState__pRetAddr], 0
+
+#ifdef _DEBUG
+ jnz LOCAL_LABEL(noConfirm)
+ push ebp
+ push ebx
+ push edi
+ push esi
+ push ecx // HelperFrame*
+ call C_FUNC(HelperMethodFrameConfirmState)
+ // on return, eax = MachState*
+ cmp DWORD PTR [eax + MachState__pRetAddr], 0
+LOCAL_LABEL(noConfirm):
+#endif // _DEBUG
+
+ jz LOCAL_LABEL(doRet)
+
+ lea edx, [eax + MachState__esi] // Did we have to spill ESI
+ cmp [eax + MachState__pEsi], edx
+ jnz LOCAL_LABEL(SkipESI)
+ mov esi, [edx] // Then restore it
+
+LOCAL_LABEL(SkipESI):
+ lea edx, [eax + MachState__edi] // Did we have to spill EDI
+ cmp [eax + MachState__pEdi], edx
+ jnz LOCAL_LABEL(SkipEDI)
+ mov edi, [edx] // Then restore it
+
+LOCAL_LABEL(SkipEDI):
+ lea edx, [eax + MachState__ebx] // Did we have to spill EBX
+ cmp [eax + MachState__pEbx], edx
+ jnz LOCAL_LABEL(SkipEBX)
+ mov ebx, [edx] // Then restore it
+
+LOCAL_LABEL(SkipEBX):
+ lea edx, [eax + MachState__ebp] // Did we have to spill EBP
+ cmp [eax + MachState__pEbp], edx
+ jnz LOCAL_LABEL(SkipEBP)
+ mov ebp, [edx] // Then restore it
+
+LOCAL_LABEL(SkipEBP):
+LOCAL_LABEL(doRet):
+ xor eax, eax
+ ret
+LEAF_END HelperMethodFrameRestoreState, _TEXT
+
+#ifdef FEATURE_HIJACK
+
+// A JITted method's return address was hijacked to return to us here.
+// VOID OnHijackTripThread()
+NESTED_ENTRY OnHijackTripThread, _TEXT, NoHandler
+ // Don't fiddle with this unless you change HijackFrame::UpdateRegDisplay
+ // and HijackArgs
+ push eax // make room for the real return address (Eip)
+ push ebp
+ push eax
+ push ecx
+ push edx
+ push ebx
+ push esi
+ push edi
+
+ // unused space for floating point state
+ sub esp,12
+
+ push esp
+ call C_FUNC(OnHijackWorker)
+
+ // unused space for floating point state
+ add esp,12
+
+ pop edi
+ pop esi
+ pop ebx
+ pop edx
+ pop ecx
+ pop eax
+ pop ebp
+ ret // return to the correct place, adjusted by our caller
+NESTED_END OnHijackTripThread, _TEXT
+
+// VOID OnHijackFPTripThread()
+NESTED_ENTRY OnHijackFPTripThread, _TEXT, NoHandler
+ // Don't fiddle with this unless you change HijackFrame::UpdateRegDisplay
+ // and HijackArgs
+ push eax // make room for the real return address (Eip)
+ push ebp
+ push eax
+ push ecx
+ push edx
+ push ebx
+ push esi
+ push edi
+
+ sub esp,12
+
+ // save top of the floating point stack (there is return value passed in it)
+ // save full 10 bytes to avoid precision loss
+ fstp QWORD PTR [esp]
+
+ push esp
+ call C_FUNC(OnHijackWorker)
+
+ // restore top of the floating point stack
+ fld QWORD PTR [esp]
+
+ add esp,12
+
+ pop edi
+ pop esi
+ pop ebx
+ pop edx
+ pop ecx
+ pop eax
+ pop ebp
+ ret // return to the correct place, adjusted by our caller
+NESTED_END OnHijackFPTripThread, _TEXT
+
+#endif // FEATURE_HIJACK
+
+// ==========================================================================
+// This function is reached only via the embedded ImportThunkGlue code inside
+// an NDirectMethodDesc. It's purpose is to load the DLL associated with an
+// N/Direct method, then backpatch the DLL target into the methoddesc.
+//
+// Initial state:
+//
+// Preemptive GC is *enabled*: we are actually in an unmanaged state.
+//
+//
+// [esp+...] - The *unmanaged* parameters to the DLL target.
+// [esp+4] - Return address back into the JIT'ted code that made
+// the DLL call.
+// [esp] - Contains the "return address." Because we got here
+// thru a call embedded inside a MD, this "return address"
+// gives us an easy to way to find the MD (which was the
+// whole purpose of the embedded call manuever.)
+//
+//
+//
+// ==========================================================================
+LEAF_ENTRY NDirectImportThunk, _TEXT
+ // Preserve argument registers
+ push ecx
+ push edx
+
+ // Invoke the function that does the real work.
+ push eax
+ call C_FUNC(NDirectImportWorker)
+
+ // Restore argument registers
+ pop edx
+ pop ecx
+
+ // If we got back from NDirectImportWorker, the MD has been successfully
+ // linked and "eax" contains the DLL target. Proceed to execute the
+ // original DLL call.
+ jmp eax // Jump to DLL target
+LEAF_END NDirectImportThunk, _TEXT
+
+// ==========================================================================
+// The call in fixup precode initally points to this function.
+// The pupose of this function is to load the MethodDesc and forward the call the prestub.
+LEAF_ENTRY PrecodeFixupThunk, _TEXT
+ // Pop the return address. It points right after the call instruction in the precode.
+ pop eax
+ push esi
+ push edi
+
+ // Inline computation done by FixupPrecode::GetMethodDesc()
+ movzx esi, BYTE PTR [eax + 2] // m_PrecodeChunkIndex
+ movzx edi, BYTE PTR [eax + 1] // m_MethodDescChunkIndex
+ mov eax, DWORD PTR [eax + esi*8 +3]
+ lea eax, [eax + edi*4]
+
+ pop edi
+ pop esi
+ jmp C_FUNC(ThePreStub)
+LEAF_END PrecodeFixupThunk, _TEXT
+
+// void __stdcall UM2MThunk_WrapperHelper(void *pThunkArgs,
+// int argLen,
+// void *pAddr,
+// UMEntryThunk *pEntryThunk,
+// Thread *pThread)
+NESTED_ENTRY UM2MThunk_WrapperHelper, _TEXT, NoHandler
+ push ebx
+
+ mov eax, [esp + 20] // pEntryThunk
+ mov ecx, [esp + 24] // pThread
+ mov ebx, [esp + 8] // pThunkArgs
+ call [esp + 16] // pAddr
+
+ pop ebx
+
+ ret 20
+NESTED_END UM2MThunk_WrapperHelper, _TEXT
+
+NESTED_ENTRY UMThunkStubRareDisable, _TEXT, NoHandler
+ push eax
+ push ecx
+
+ push eax // Push the UMEntryThunk
+ push ecx // Push thread
+ call C_FUNC(UMThunkStubRareDisableWorker)
+
+ pop ecx
+ pop eax
+ ret
+NESTED_END UMThunkStubRareDisable, _TEXT
+
+//
+// Used to get the current instruction pointer value
+//
+// UINT_PTR __stdcall GetCurrentIP(void);
+LEAF_ENTRY GetCurrentIP, _TEXT
+ mov eax, [esp]
+ ret
+LEAF_END GetCurrentIP, _TEXT
+
+// LPVOID __stdcall GetCurrentSP(void);
+LEAF_ENTRY GetCurrentSP, _TEXT
+ mov eax, esp
+ ret
+LEAF_END GetCurrentSP, _TEXT
+
+// ==========================================================================
+// Invoked for vararg forward P/Invoke calls as a stub.
+// Except for secret return buffer, arguments come on the stack so EDX is available as scratch.
+// EAX - the NDirectMethodDesc
+// ECX - may be return buffer address
+// [ESP + 4] - the VASigCookie
+//
+NESTED_ENTRY VarargPInvokeStub, _TEXT, NoHandler
+ // EDX <- VASigCookie
+ mov edx, [esp + 4] // skip retaddr
+
+ mov edx, [edx + VASigCookie__StubOffset]
+ test edx, edx
+
+ jz LOCAL_LABEL(GoCallVarargWorker)
+ // ---------------------------------------
+
+ // EAX contains MD ptr for the IL stub
+ jmp edx
+
+LOCAL_LABEL(GoCallVarargWorker):
+ //
+ // MD ptr in EAX, VASigCookie ptr at [esp+4]
+ //
+ STUB_PROLOG
+
+ mov esi, esp
+
+ // save pMD
+ push eax
+
+ push eax // pMD
+ push dword ptr [esi + 4*7] // pVaSigCookie
+ push esi // pTransitionBlock
+
+ call C_FUNC(VarargPInvokeStubWorker)
+
+ // restore pMD
+ pop eax
+
+ STUB_EPILOG
+
+ // jump back to the helper - this time it won't come back here as the stub already exists
+ jmp C_FUNC(VarargPInvokeStub)
+NESTED_END VarargPInvokeStub, _TEXT
+
+// ==========================================================================
+// Invoked for marshaling-required unmanaged CALLI calls as a stub.
+// EAX - the unmanaged target
+// ECX, EDX - arguments
+// [ESP + 4] - the VASigCookie
+//
+LEAF_ENTRY GenericPInvokeCalliHelper, _TEXT
+ // save the target
+ push eax
+
+ // EAX <- VASigCookie
+ mov eax, [esp + 8] // skip target and retaddr
+
+ mov eax, [eax + VASigCookie__StubOffset]
+ test eax, eax
+
+ jz LOCAL_LABEL(GoCallCalliWorker)
+ // ---------------------------------------
+
+ push eax
+
+ // stack layout at this point:
+ //
+ // | ... |
+ // | stack arguments | ESP + 16
+ // +----------------------+
+ // | VASigCookie* | ESP + 12
+ // +----------------------+
+ // | return address | ESP + 8
+ // +----------------------+
+ // | CALLI target address | ESP + 4
+ // +----------------------+
+ // | stub entry point | ESP + 0
+ // ------------------------
+
+ // remove VASigCookie from the stack
+ mov eax, [esp + 8]
+ mov [esp + 12], eax
+
+ // move stub entry point below the RA
+ mov eax, [esp]
+ mov [esp + 8], eax
+
+ // load EAX with the target address
+ pop eax
+ pop eax
+
+ // stack layout at this point:
+ //
+ // | ... |
+ // | stack arguments | ESP + 8
+ // +----------------------+
+ // | return address | ESP + 4
+ // +----------------------+
+ // | stub entry point | ESP + 0
+ // ------------------------
+
+ // CALLI target address is in EAX
+ ret
+
+LOCAL_LABEL(GoCallCalliWorker):
+ // the target is on the stack and will become m_Datum of PInvokeCalliFrame
+ // call the stub generating worker
+ pop eax
+
+ //
+ // target ptr in EAX, VASigCookie ptr in EDX
+ //
+
+ STUB_PROLOG
+
+ mov esi, esp
+
+ // save target
+ push eax
+
+ push eax // unmanaged target
+ push dword ptr [esi + 4*7] // pVaSigCookie (first stack argument)
+ push esi // pTransitionBlock
+
+ call C_FUNC(GenericPInvokeCalliStubWorker)
+
+ // restore target
+ pop eax
+
+ STUB_EPILOG
+
+ // jump back to the helper - this time it won't come back here as the stub already exists
+ jmp C_FUNC(GenericPInvokeCalliHelper)
+LEAF_END GenericPInvokeCalliHelper, _TEXT
+
+#ifdef FEATURE_PREJIT
+
+// =========================================================================
+NESTED_ENTRY StubDispatchFixupStub, _TEXT, NoHandler
+ STUB_PROLOG
+
+ mov esi, esp
+
+ push 0
+ push 0
+
+ push eax // siteAddrForRegisterIndirect (for tailcalls)
+ push esi // pTransitionBlock
+
+ call C_FUNC(StubDispatchFixupWorker)
+
+ STUB_EPILOG
+
+PATCH_LABEL StubDispatchFixupPatchLabel
+ // Tailcall target
+ 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
+NESTED_END StubDispatchFixupStub, _TEXT
+
+// ==========================================================================
+NESTED_ENTRY ExternalMethodFixupStub, _TEXT_ NoHandler
+ // pop off the return address to the stub
+ // leaving the actual caller's return address on top of the stack
+ pop eax
+
+ STUB_PROLOG
+
+ mov esi, esp
+
+ // EAX is return address into CORCOMPILE_EXTERNAL_METHOD_THUNK. Subtract 5 to get start address.
+ sub eax, 5
+
+ push 0
+ push 0
+
+ push eax
+
+ // pTransitionBlock
+ push esi
+
+ call C_FUNC(ExternalMethodFixupWorker)
+
+ // eax now contains replacement stub. PreStubWorker will never return
+ // NULL (it throws an exception if stub creation fails.)
+
+ // From here on, mustn't trash eax
+
+ STUB_EPILOG
+
+PATCH_LABEL ExternalMethodFixupPatchLabel
+ // Tailcall target
+ 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
+NESTED_END ExternalMethodFixupStub, _TEXT
+
+#ifdef FEATURE_READYTORUN
+// ==========================================================================
+NESTED_ENTRY DelayLoad_MethodCall, _TEXT, NoHandler
+ STUB_PROLOG_2_HIDDEN_ARGS
+
+ mov esi, esp
+
+ push ecx
+ push edx
+
+ push eax
+
+ // pTransitionBlock
+ push esi
+
+ call C_FUNC(ExternalMethodFixupWorker)
+
+ // eax now contains replacement stub. PreStubWorker will never return
+ // NULL (it throws an exception if stub creation fails.)
+
+ // From here on, mustn't trash eax
+
+ STUB_EPILOG
+
+ // Share the patch label
+ jmp C_FUNC(ExternalMethodFixupPatchLabel)
+
+ // This will never be executed. It is just to help out stack-walking logic
+ // which disassembles the epilog to unwind the stack.
+ ret
+NESTED_END DelayLoad_MethodCall, _TEXT
+
+#endif // FEATURE_READYTORUN
+
+// =======================================================================================
+// The call in softbound vtable slots initially points to this function.
+// The pupose of this function is to transfer the control to right target and
+// 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
+ // Calculate the address of the thunk
+ sub eax, 5
+
+ // Push ebp frame to get good callstack under debugger
+ PROLOG_BEG
+
+ // Preserve argument registers
+ PROLOG_PUSH ecx
+ PROLOG_PUSH edx
+
+ // Set frame pointer
+ PROLOG_END
+
+ push eax // address of the thunk
+ push ecx // this ptr
+ call C_FUNC(VirtualMethodFixupWorker)
+
+ // Restore stack pointer
+ EPILOG_BEG
+
+ // Restore argument registers
+ EPILOG_POP edx
+ EPILOG_POP ecx
+
+ // Pop ebp frame
+ EPILOG_END
+
+PATCH_LABEL VirtualMethodFixupPatchLabel
+ // Proceed to execute the actual method.
+ 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
+NESTED_END VirtualMethodFixupStub, _TEXT
+
+#endif // FEATURE_PREJIT
+
+NESTED_ENTRY ThePreStub, _TEXT, NoHandler
+ STUB_PROLOG
+
+ mov esi, esp
+
+ // Compute padding size
+ lea ebx, [esp - 8]
+ and ebx, 15
+ // Adjust stack offset
+ sub esp, ebx
+
+ // EAX contains MethodDesc* from the precode. Push it here as argument
+ // for PreStubWorker
+ push eax
+
+ push esi
+
+ CHECK_STACK_ALIGNMENT
+ call C_FUNC(PreStubWorker)
+
+ // eax now contains replacement stub. PreStubWorker will never return
+ // NULL (it throws an exception if stub creation fails.)
+
+ // From here on, mustn't trash eax
+
+ // Restore stack pointer
+ mov esp, esi
+
+ STUB_EPILOG
+
+ // Tailcall target
+ 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
+NESTED_END ThePreStub, _TEXT
+
+// 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.
+LEAF_ENTRY ThePreStubPatch, _TEXT
+ // make sure that the basic block is unique
+ test eax,34
+
+PATCH_LABEL ThePreStubPatchLabel
+ ret
+LEAF_END ThePreStubPatch, _TEXT
+
+#ifdef FEATURE_READYTORUN
+// ==========================================================================
+// Define helpers for delay loading of readytorun helpers
+
+.macro DYNAMICHELPER frameFlags, suffix
+
+NESTED_ENTRY DelayLoad_Helper\suffix, _TEXT, NoHandler
+ STUB_PROLOG_2_HIDDEN_ARGS
+
+ mov esi, esp
+
+ push \frameFlags
+ push ecx // module
+ push edx // section index
+
+ push eax // indirection cell address.
+ push esi // pTransitionBlock
+
+ call C_FUNC(DynamicHelperWorker)
+ test eax,eax
+ jnz LOCAL_LABEL(TailCallDelayLoad_Helper\suffix)
+
+ mov eax, [esi] // The result is stored in the argument area of the transition block
+ STUB_EPILOG_RETURN
+ ret
+
+LOCAL_LABEL(TailCallDelayLoad_Helper\suffix):
+ STUB_EPILOG
+ jmp eax
+NESTED_END DelayLoad_Helper\suffix, _TEXT
+.endm
+
+DYNAMICHELPER DynamicHelperFrameFlags_Default
+DYNAMICHELPER DynamicHelperFrameFlags_ObjectArg, _Obj
+DYNAMICHELPER (DynamicHelperFrameFlags_ObjectArg | DynamicHelperFrameFlags_ObjectArg2), _ObjObj
+
+#endif // FEATURE_READYTORUN
+
+NESTED_ENTRY ResolveWorkerAsmStub, _TEXT, NoHandler
+ //
+ // The stub arguments are where we want to setup the TransitionBlock. We will
+ // setup the TransitionBlock later once we can trash them
+ //
+ // 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 [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
+ lea ebp, [esi + 5*4]
+
+ // Make the call
+ call C_FUNC(VSD_ResolveWorker)
+
+ // 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
+NESTED_END ResolveWorkerAsmStub, _TEXT
diff --git a/src/vm/i386/asmhelpers.asm b/src/vm/i386/asmhelpers.asm
index 66a22b7962..0456be82db 100644
--- a/src/vm/i386/asmhelpers.asm
+++ b/src/vm/i386/asmhelpers.asm
@@ -43,7 +43,6 @@ TlsGetValue PROTO stdcall
ifdef FEATURE_HIJACK
EXTERN _OnHijackWorker@4:PROC
endif ;FEATURE_HIJACK
-EXTERN _COMPlusEndCatch@20:PROC
EXTERN _COMPlusFrameHandler:PROC
ifdef FEATURE_COMINTEROP
EXTERN _COMPlusFrameHandlerRevCom:PROC
@@ -1005,33 +1004,6 @@ OnHijackFPTripThread ENDP
endif ; FEATURE_HIJACK
-; Note that the debugger skips this entirely when doing SetIP,
-; since COMPlusCheckForAbort should always return 0. Excep.cpp:LeaveCatch
-; asserts that to be true. If this ends up doing more work, then the
-; debugger may need additional support.
-; void __stdcall JIT_EndCatch();
-JIT_EndCatch PROC stdcall public
-
- ; make temp storage for return address, and push the address of that
- ; as the last arg to COMPlusEndCatch
- mov ecx, [esp]
- push ecx;
- push esp;
-
- ; push the rest of COMPlusEndCatch's args, right-to-left
- push esi
- push edi
- push ebx
- push ebp
-
- call _COMPlusEndCatch@20 ; returns old esp value in eax, stores jump address
- ; now eax = new esp, [esp] = new eip
-
- pop edx ; edx = new eip
- mov esp, eax ; esp = new esp
- jmp edx ; eip = new eip
-
-JIT_EndCatch ENDP
;==========================================================================
; This function is reached only via the embedded ImportThunkGlue code inside
diff --git a/src/vm/i386/cgencpu.h b/src/vm/i386/cgencpu.h
index 2da98821bc..99f4eb498f 100644
--- a/src/vm/i386/cgencpu.h
+++ b/src/vm/i386/cgencpu.h
@@ -43,6 +43,10 @@ EXTERN_C void STDCALL PInvokeStackImbalanceHelper(void);
EXTERN_C void STDCALL CopyCtorCallStub(void);
#endif // !FEATURE_CORECLR
+#ifdef FEATURE_STUBS_AS_IL
+EXTERN_C void SinglecastDelegateInvokeStub();
+#endif // FEATURE_STUBS_AS_IL
+
BOOL Runtime_Test_For_SSE2();
#ifdef CROSSGEN_COMPILE
@@ -476,7 +480,7 @@ inline BOOL IsUnmanagedValueTypeReturnedByRef(UINT sizeofvaluetype)
}
#include <pshpack1.h>
-DECLSPEC_ALIGN(4) struct UMEntryThunkCode
+struct DECLSPEC_ALIGN(4) UMEntryThunkCode
{
BYTE m_alignpad[2]; // used to guarantee alignment of backpactched portion
BYTE m_movEAX; //MOV EAX,imm32
@@ -562,6 +566,7 @@ inline BOOL ClrFlushInstructionCache(LPCVOID pCodeAddr, size_t sizeOfCode)
// #define JIT_GetSharedGCStaticBaseNoCtor
// #define JIT_GetSharedNonGCStaticBaseNoCtor
+#ifndef FEATURE_PAL
#define JIT_ChkCastClass JIT_ChkCastClass
#define JIT_ChkCastClassSpecial JIT_ChkCastClassSpecial
#define JIT_IsInstanceOfClass JIT_IsInstanceOfClass
@@ -569,5 +574,5 @@ inline BOOL ClrFlushInstructionCache(LPCVOID pCodeAddr, size_t sizeOfCode)
#define JIT_IsInstanceOfInterface JIT_IsInstanceOfInterface
#define JIT_NewCrossContext JIT_NewCrossContext
#define JIT_Stelem_Ref JIT_Stelem_Ref
-
+#endif // FEATURE_PAL
#endif // __cgenx86_h__
diff --git a/src/vm/i386/cgenx86.cpp b/src/vm/i386/cgenx86.cpp
index ff2f2df5a3..08ccd01086 100644
--- a/src/vm/i386/cgenx86.cpp
+++ b/src/vm/i386/cgenx86.cpp
@@ -760,6 +760,7 @@ WORD GetUnpatchedCodeData(LPCBYTE pAddr)
#ifndef DACCESS_COMPILE
+#if defined(_TARGET_X86_) && !defined(FEATURE_STUBS_AS_IL)
//-------------------------------------------------------------------------
// One-time creation of special prestub to initialize UMEntryThunks.
//-------------------------------------------------------------------------
@@ -809,6 +810,7 @@ Stub *GenerateUMThunkPrestub()
RETURN psl->Link(SystemDomain::GetGlobalLoaderAllocator()->GetExecutableHeap());
}
+#endif // _TARGET_X86_ && !FEATURE_STUBS_AS_IL
Stub *GenerateInitPInvokeFrameHelper()
{
@@ -1593,6 +1595,7 @@ extern "C" VOID STDCALL StubRareDisableTHROWWorker(Thread *pThread)
pThread->HandleThreadAbort();
}
+#ifndef FEATURE_PAL
// Note that this logic is copied below, in PopSEHRecords
__declspec(naked)
VOID __cdecl PopSEHRecords(LPVOID pTargetSP)
@@ -1614,6 +1617,7 @@ VOID __cdecl PopSEHRecords(LPVOID pTargetSP)
retn
}
}
+#endif // FEATURE_PAL
//////////////////////////////////////////////////////////////////////////////
//
@@ -1680,9 +1684,10 @@ void ResumeAtJit(PCONTEXT pContext, LPVOID oldESP)
#endif // !EnC_SUPPORTED
+#ifndef FEATURE_PAL
#pragma warning(push)
#pragma warning(disable: 4035)
-DWORD getcpuid(DWORD arg, unsigned char result[16])
+extern "C" DWORD __stdcall getcpuid(DWORD arg, unsigned char result[16])
{
LIMITED_METHOD_CONTRACT
@@ -1709,7 +1714,7 @@ DWORD getcpuid(DWORD arg, unsigned char result[16])
// Arg3 is a pointer to the return buffer
// No need to check whether or not CPUID is supported because we have already called CPUID with success to come here.
-DWORD getextcpuid(DWORD arg1, DWORD arg2, unsigned char result[16])
+extern "C" DWORD __stdcall getextcpuid(DWORD arg1, DWORD arg2, unsigned char result[16])
{
LIMITED_METHOD_CONTRACT
@@ -1730,8 +1735,75 @@ DWORD getextcpuid(DWORD arg1, DWORD arg2, unsigned char result[16])
}
}
+extern "C" DWORD __stdcall xmmYmmStateSupport()
+{
+ // No CONTRACT
+ STATIC_CONTRACT_NOTHROW;
+ STATIC_CONTRACT_GC_NOTRIGGER;
+
+ __asm
+ {
+ mov ecx, 0 ; Specify xcr0
+ xgetbv ; result in EDX:EAX
+ and eax, 06H
+ cmp eax, 06H ; check OS has enabled both XMM and YMM state support
+ jne not_supported
+ mov eax, 1
+ jmp done
+ not_supported:
+ mov eax, 0
+ done:
+ }
+}
+
#pragma warning(pop)
+#else // !FEATURE_PAL
+
+extern "C" DWORD __stdcall getcpuid(DWORD arg, unsigned char result[16])
+{
+ DWORD eax;
+ __asm(" xor %%ecx, %%ecx\n" \
+ " cpuid\n" \
+ " mov %%eax, 0(%[result])\n" \
+ " mov %%ebx, 4(%[result])\n" \
+ " mov %%ecx, 8(%[result])\n" \
+ " 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 */
+ );
+ return eax;
+}
+
+extern "C" DWORD __stdcall getextcpuid(DWORD arg1, DWORD arg2, unsigned char result[16])
+{
+ DWORD eax;
+ __asm(" cpuid\n" \
+ " mov %%eax, 0(%[result])\n" \
+ " mov %%ebx, 4(%[result])\n" \
+ " mov %%ecx, 8(%[result])\n" \
+ " 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 */
+ );
+ return eax;
+}
+
+extern "C" DWORD __stdcall xmmYmmStateSupport()
+{
+ DWORD eax;
+ __asm(" xgetbv\n" \
+ : "=a"(eax) /*output in eax*/\
+ : "c"(0) /*inputs - 0 in ecx*/\
+ : "eax", "edx" /* registers that are clobbered*/
+ );
+ // check OS has enabled both XMM and YMM state support
+ return ((eax & 0x06) == 0x06) ? 1 : 0;
+}
+
+#endif // !FEATURE_PAL
// This function returns the number of logical processors on a given physical chip. If it cannot
// determine the number of logical cpus, or the machine is not populated uniformly with the same
@@ -1761,13 +1833,14 @@ DWORD GetLogicalCpuCount()
PAL_TRY(Param *, pParam, &param)
{
unsigned char buffer[16];
+ DWORD* dwBuffer = NULL;
DWORD maxCpuId = getcpuid(0, buffer);
if (maxCpuId < 1)
goto lDone;
- DWORD* dwBuffer = (DWORD*)buffer;
+ dwBuffer = (DWORD*)buffer;
if (dwBuffer[1] == 'uneG') {
if (dwBuffer[3] == 'Ieni') {
diff --git a/src/vm/i386/excepcpu.h b/src/vm/i386/excepcpu.h
index 3f2f0810a7..ff540e784b 100644
--- a/src/vm/i386/excepcpu.h
+++ b/src/vm/i386/excepcpu.h
@@ -28,12 +28,37 @@ class Thread;
// Actually, the handler getting set is properly registered
#endif
+#ifdef FEATURE_PAL
+
+extern VOID SetSEHRecord(PEXCEPTION_REGISTRATION_RECORD record);
+extern VOID ResetSEHRecord(PEXCEPTION_REGISTRATION_RECORD record);
+
+#define INSTALL_SEH_RECORD(record) \
+ SetSEHRecord(record); \
+
+#define UNINSTALL_SEH_RECORD(record) \
+ ResetSEHRecord(record);
+
+#else // FEATURE_PAL
+
+#define INSTALL_SEH_RECORD(record) \
+ { \
+ (record)->Next = (PEXCEPTION_REGISTRATION_RECORD)__readfsdword(0); \
+ __writefsdword(0, (DWORD) (record)); \
+ }
+
+#define UNINSTALL_SEH_RECORD(record) \
+ { \
+ __writefsdword(0, (DWORD) ((record)->Next)); \
+ }
+
+#endif // FEATURE_PAL
+
#define INSTALL_EXCEPTION_HANDLING_RECORD(record) \
{ \
PEXCEPTION_REGISTRATION_RECORD __record = (record); \
_ASSERTE(__record < GetCurrentSEHRecord()); \
- __record->Next = (PEXCEPTION_REGISTRATION_RECORD)__readfsdword(0); \
- __writefsdword(0, (DWORD)__record); \
+ INSTALL_SEH_RECORD(record); \
}
//
@@ -44,7 +69,7 @@ class Thread;
{ \
PEXCEPTION_REGISTRATION_RECORD __record = (record); \
_ASSERTE(__record == GetCurrentSEHRecord()); \
- __writefsdword(0, (DWORD)__record->Next); \
+ UNINSTALL_SEH_RECORD(record); \
}
// stackOverwriteBarrier is used to detect overwriting of stack which will mess up handler registration
diff --git a/src/vm/i386/excepx86.cpp b/src/vm/i386/excepx86.cpp
index 27c923b749..71200f671f 100644
--- a/src/vm/i386/excepx86.cpp
+++ b/src/vm/i386/excepx86.cpp
@@ -19,7 +19,7 @@
#include "comutilnative.h"
#include "sigformat.h"
#include "siginfo.hpp"
-#include "gc.h"
+#include "gcheaputilities.h"
#include "eedbginterfaceimpl.h" //so we can clearexception in COMPlusThrow
#include "perfcounters.h"
#include "eventtrace.h"
@@ -53,13 +53,15 @@ VOID STDCALL ResumeAtJitEHHelper(EHContext *pContext);
int STDCALL CallJitEHFilterHelper(size_t *pShadowSP, EHContext *pContext);
VOID STDCALL CallJitEHFinallyHelper(size_t *pShadowSP, EHContext *pContext);
+typedef void (*RtlUnwindCallbackType)(void);
+
BOOL CallRtlUnwind(EXCEPTION_REGISTRATION_RECORD *pEstablisherFrame,
- void *callback,
+ RtlUnwindCallbackType callback,
EXCEPTION_RECORD *pExceptionRecord,
void *retval);
BOOL CallRtlUnwindSafe(EXCEPTION_REGISTRATION_RECORD *pEstablisherFrame,
- void *callback,
+ RtlUnwindCallbackType callback,
EXCEPTION_RECORD *pExceptionRecord,
void *retval);
}
@@ -371,6 +373,7 @@ CPFH_AdjustContextForThreadSuspensionRace(CONTEXT *pContext, Thread *pThread)
{
WRAPPER_NO_CONTRACT;
+#ifndef FEATURE_PAL
PCODE f_IP = GetIP(pContext);
if (Thread::IsAddrOfRedirectFunc((PVOID)f_IP)) {
@@ -427,22 +430,13 @@ CPFH_AdjustContextForThreadSuspensionRace(CONTEXT *pContext, Thread *pThread)
SetIP(pContext, GetIP(pThread->m_OSContext) - 1);
STRESS_LOG1(LF_EH, LL_INFO100, "CPFH_AdjustContextForThreadSuspensionRace: Case 4 setting IP = %x\n", pContext->Eip);
}
+#else
+ PORTABILITY_ASSERT("CPFH_AdjustContextForThreadSuspensionRace");
+#endif
}
#endif // FEATURE_HIJACK
-// We want to leave true null reference exceptions alone. But if we are
-// trashing memory, we don't want the application to swallow it. The 0x100
-// below will give us false positives for debugging, if the app is accessing
-// a field more than 256 bytes down an object, where the reference is null.
-//
-// Removed use of the IgnoreUnmanagedExceptions reg key...simply return false now.
-//
-static inline BOOL
-CPFH_ShouldIgnoreException(EXCEPTION_RECORD *pExceptionRecord) {
- LIMITED_METHOD_CONTRACT;
- return FALSE;
-}
static inline void
CPFH_UpdatePerformanceCounters() {
@@ -620,7 +614,7 @@ EXCEPTION_DISPOSITION ClrDebuggerDoUnwindAndIntercept(EXCEPTION_REGISTRATION_REC
// This rethrow issue does not affect COMPLUS exceptions since we always create a brand new exception
// record for them in RaiseTheExceptionInternalOnly.
BOOL CallRtlUnwindSafe(EXCEPTION_REGISTRATION_RECORD *pEstablisherFrame,
- void *callback,
+ RtlUnwindCallbackType callback,
EXCEPTION_RECORD *pExceptionRecord,
void *retval)
{
@@ -1153,6 +1147,7 @@ CPFH_RealFirstPassHandler( // ExceptionContinueSearch, etc.
pExInfo->m_pExceptionPointers = &exceptionPointers;
+#ifndef FEATURE_PAL
if (bRethrownException || bNestedException)
{
_ASSERTE(pExInfo->m_pPrevNestedInfo != NULL);
@@ -1161,6 +1156,7 @@ CPFH_RealFirstPassHandler( // ExceptionContinueSearch, etc.
SetStateForWatsonBucketing(bRethrownException, pExInfo->GetPreviousExceptionTracker()->GetThrowableAsHandle());
END_SO_INTOLERANT_CODE;
}
+#endif
#ifdef DEBUGGING_SUPPORTED
//
@@ -1975,11 +1971,17 @@ PTR_CONTEXT GetCONTEXTFromRedirectedStubStackFrame(CONTEXT * pContext)
}
#if !defined(DACCESS_COMPILE)
+#ifdef FEATURE_PAL
+static PEXCEPTION_REGISTRATION_RECORD CurrentSEHRecord = EXCEPTION_CHAIN_END;
+#endif
PEXCEPTION_REGISTRATION_RECORD GetCurrentSEHRecord()
{
WRAPPER_NO_CONTRACT;
+#ifdef FEATURE_PAL
+ LPVOID fs0 = CurrentSEHRecord;
+#else // FEATURE_PAL
LPVOID fs0 = (LPVOID)__readfsdword(0);
#if 0 // This walk is too expensive considering we hit it every time we a CONTRACT(NOTHROW)
@@ -2010,19 +2012,39 @@ PEXCEPTION_REGISTRATION_RECORD GetCurrentSEHRecord()
pEHR = pEHR->Next;
}
#endif
-#endif
+#endif // 0
+#endif // FEATURE_PAL
return (EXCEPTION_REGISTRATION_RECORD*) fs0;
}
+#ifdef FEATURE_PAL
+VOID SetSEHRecord(PEXCEPTION_REGISTRATION_RECORD record)
+{
+ WRAPPER_NO_CONTRACT;
+ record->Next = CurrentSEHRecord;
+ CurrentSEHRecord = record;
+}
+
+VOID ResetSEHRecord(PEXCEPTION_REGISTRATION_RECORD record)
+{
+ CurrentSEHRecord = record->Next;
+}
+#endif // FEATURE_PAL
+
PEXCEPTION_REGISTRATION_RECORD GetFirstCOMPlusSEHRecord(Thread *pThread) {
WRAPPER_NO_CONTRACT;
+#ifndef FEATURE_PAL
EXCEPTION_REGISTRATION_RECORD *pEHR = *(pThread->GetExceptionListPtr());
if (pEHR == EXCEPTION_CHAIN_END || IsUnmanagedToManagedSEHHandler(pEHR)) {
return pEHR;
} else {
return GetNextCOMPlusSEHRecord(pEHR);
}
+#else // FEATURE_PAL
+ PORTABILITY_ASSERT("GetFirstCOMPlusSEHRecord");
+ return NULL;
+#endif // FEATURE_PAL
}
@@ -2048,7 +2070,11 @@ PEXCEPTION_REGISTRATION_RECORD GetPrevSEHRecord(EXCEPTION_REGISTRATION_RECORD *n
VOID SetCurrentSEHRecord(EXCEPTION_REGISTRATION_RECORD *pSEH)
{
WRAPPER_NO_CONTRACT;
+#ifndef FEATURE_PAL
*GetThread()->GetExceptionListPtr() = pSEH;
+#else // FEATURE_PAL
+ _ASSERTE("NYI");
+#endif // FEATURE_PAL
}
@@ -2085,6 +2111,7 @@ BOOL PopNestedExceptionRecords(LPVOID pTargetSP, BOOL bCheckForUnknownHandlers)
STATIC_CONTRACT_GC_NOTRIGGER;
STATIC_CONTRACT_SO_TOLERANT;
+#ifndef FEATURE_PAL
PEXCEPTION_REGISTRATION_RECORD pEHR = GetCurrentSEHRecord();
while ((LPVOID)pEHR < pTargetSP)
@@ -2140,6 +2167,10 @@ BOOL PopNestedExceptionRecords(LPVOID pTargetSP, BOOL bCheckForUnknownHandlers)
SetCurrentSEHRecord(pEHR);
}
return FALSE;
+#else // FEATURE_PAL
+ PORTABILITY_ASSERT("PopNestedExceptionRecords");
+ return FALSE;
+#endif // FEATURE_PAL
}
//
@@ -2245,6 +2276,7 @@ int COMPlusThrowCallbackHelper(IJitManager *pJitManager,
int iFilt = 0;
BOOL impersonating = FALSE;
+#ifndef FEATURE_PAL
EX_TRY
{
GCPROTECT_BEGIN (throwable);
@@ -2295,6 +2327,10 @@ int COMPlusThrowCallbackHelper(IJitManager *pJitManager,
EX_END_CATCH(SwallowAllExceptions)
return iFilt;
+#else // FEATURE_PAL
+ PORTABILITY_ASSERT("COMPlusThrowCallbackHelper");
+ return EXCEPTION_CONTINUE_SEARCH;
+#endif // FEATURE_PAL
}
//******************************************************************************
@@ -2409,6 +2445,7 @@ StackWalkAction COMPlusThrowCallback( // SWA value
pData->bSkipLastElement = FALSE;
}
+#ifndef FEATURE_PAL
// Check for any impersonation on the frame and save that for use during EH filter callbacks
OBJECTREF* pRefSecDesc = pCf->GetAddrOfSecurityObject();
if (pRefSecDesc != NULL && *pRefSecDesc != NULL)
@@ -2427,6 +2464,7 @@ StackWalkAction COMPlusThrowCallback( // SWA value
}
}
}
+#endif // !FEATURE_PAL
// now we've got the stack trace, if we aren't allowed to catch this and we're first pass, return
if (pData->bDontCatch)
@@ -2604,9 +2642,9 @@ StackWalkAction COMPlusThrowCallback( // SWA value
// EX_CATCH just above us. If not, the exception
if ( IsFilterHandler(&EHClause)
&& ( offs > EHClause.FilterOffset
- || offs == EHClause.FilterOffset && !start_adjust)
+ || (offs == EHClause.FilterOffset && !start_adjust) )
&& ( offs < EHClause.HandlerStartPC
- || offs == EHClause.HandlerStartPC && !end_adjust)) {
+ || (offs == EHClause.HandlerStartPC && !end_adjust) )) {
STRESS_LOG4(LF_EH, LL_INFO100, "COMPlusThrowCallback: Fault inside filter [%d,%d] startAdj %d endAdj %d\n",
EHClause.FilterOffset, EHClause.HandlerStartPC, start_adjust, end_adjust);
@@ -2978,9 +3016,9 @@ StackWalkAction COMPlusUnwindCallback (CrawlFrame *pCf, ThrowCallbackType *pData
if ( IsFilterHandler(&EHClause)
&& ( offs > EHClause.FilterOffset
- || offs == EHClause.FilterOffset && !start_adjust)
+ || (offs == EHClause.FilterOffset && !start_adjust) )
&& ( offs < EHClause.HandlerStartPC
- || offs == EHClause.HandlerStartPC && !end_adjust)
+ || (offs == EHClause.HandlerStartPC && !end_adjust) )
) {
STRESS_LOG4(LF_EH, LL_INFO100, "COMPlusUnwindCallback: Fault inside filter [%d,%d] startAdj %d endAdj %d\n",
EHClause.FilterOffset, EHClause.HandlerStartPC, start_adjust, end_adjust);
@@ -3731,4 +3769,10 @@ AdjustContextForVirtualStub(
return TRUE;
}
+#ifdef FEATURE_PAL
+VOID DECLSPEC_NORETURN DispatchManagedException(PAL_SEHException& ex, bool isHardwareException)
+{
+ UNREACHABLE();
+}
+#endif
#endif // !DACCESS_COMPILE
diff --git a/src/vm/i386/gmsasm.S b/src/vm/i386/gmsasm.S
new file mode 100644
index 0000000000..1e43fd281f
--- /dev/null
+++ b/src/vm/i386/gmsasm.S
@@ -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.
+
+.intel_syntax noprefix
+#include "unixasmmacros.inc"
+#include "asmconstants.h"
+
+// int __fastcall LazyMachStateCaptureState(struct LazyMachState *pState);
+LEAF_ENTRY LazyMachStateCaptureState, _TEXT
+ // marks that this is not yet valid
+ mov dword ptr [ecx+MachState__pRetAddr], 0
+
+ // remember register values
+ mov [ecx+MachState__edi], edi
+ mov [ecx+MachState__esi], esi
+ mov [ecx+MachState__ebx], ebx
+ mov [ecx+LazyMachState_captureEbp], ebp
+ mov [ecx+LazyMachState_captureEsp], esp
+
+ // capture return address
+ mov eax, [esp]
+ mov dword ptr [ecx+LazyMachState_captureEip], eax
+
+ // return 0
+ xor eax, eax
+ ret
+LEAF_END LazyMachStateCaptureState, _TEXT
diff --git a/src/vm/i386/gmsx86.cpp b/src/vm/i386/gmsx86.cpp
index e7e16b70ab..34d65856fe 100644
--- a/src/vm/i386/gmsx86.cpp
+++ b/src/vm/i386/gmsx86.cpp
@@ -9,6 +9,11 @@
#include "common.h"
#include "gmscpu.h"
+#ifdef FEATURE_PAL
+#define USE_EXTERNAL_UNWINDER
+#endif
+
+#ifndef USE_EXTERNAL_UNWINDER
/***************************************************************/
/* setMachState figures out what the state of the CPU will be
when the function that calls 'setMachState' returns. It stores
@@ -42,18 +47,31 @@
#if !defined(DACCESS_COMPILE)
+#ifdef _MSC_VER
#pragma optimize("gsy", on ) // optimize to insure that code generation does not have junk in it
+#endif // _MSC_VER
#pragma warning(disable:4717)
static int __stdcall zeroFtn() {
return 0;
}
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Winfinite-recursion"
+#endif
+
static int __stdcall recursiveFtn() {
return recursiveFtn()+1;
}
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+#ifdef _MSC_VER
#pragma optimize("", on )
+#endif // _MSC_VER
/* Has mscorwks been instrumented so that calls are morphed into push XXXX call <helper> */
@@ -670,6 +688,10 @@ void LazyMachState::unwindLazyState(LazyMachState* baseState,
ip += 2;
break;
+ case 0x34: // XOR AL, imm8
+ ip += 2;
+ break;
+
case 0x31:
case 0x32:
case 0x33:
@@ -866,6 +888,10 @@ void LazyMachState::unwindLazyState(LazyMachState* baseState,
datasize = b16bit?2:4;
goto decodeRM;
+ case 0x24: // AND AL, imm8
+ ip += 2;
+ break;
+
case 0x01: // ADD mod/rm
case 0x03:
case 0x29: // SUB mod/rm
@@ -1108,7 +1134,7 @@ void LazyMachState::unwindLazyState(LazyMachState* baseState,
goto again;
}
#ifndef _PREFIX_
- *((int*) 0) = 1; // If you get at this error, it is because yout
+ *((volatile int*) 0) = 1; // If you get at this error, it is because yout
// set a breakpoint in a helpermethod frame epilog
// you can't do that unfortunately. Just move it
// into the interior of the method to fix it
@@ -1225,7 +1251,7 @@ void LazyMachState::unwindLazyState(LazyMachState* baseState,
// FIX what to do here?
#ifndef DACCESS_COMPILE
#ifndef _PREFIX_
- *((unsigned __int8**) 0) = ip; // cause an access violation (Free Build assert)
+ *((volatile PTR_BYTE*) 0) = ip; // cause an access violation (Free Build assert)
#endif // !_PREFIX_
#else
DacNotImpl();
@@ -1243,3 +1269,109 @@ done:
#ifdef _PREFAST_
#pragma warning(pop)
#endif
+#else // !USE_EXTERNAL_UNWINDER
+
+void LazyMachState::unwindLazyState(LazyMachState* baseState,
+ MachState* lazyState,
+ DWORD threadId,
+ int funCallDepth /* = 1 */,
+ HostCallPreference hostCallPreference /* = (HostCallPreference)(-1) */)
+{
+ CONTRACTL {
+ NOTHROW;
+ GC_NOTRIGGER;
+ SO_TOLERANT;
+ SUPPORTS_DAC;
+ } CONTRACTL_END;
+
+ CONTEXT ctx;
+ KNONVOLATILE_CONTEXT_POINTERS nonVolRegPtrs;
+
+ ctx.Eip = baseState->captureEip;
+ ctx.Esp = baseState->captureEsp;
+ ctx.Ebp = baseState->captureEbp;
+
+ ctx.Edi = lazyState->_edi = baseState->_edi;
+ ctx.Esi = lazyState->_esi = baseState->_esi;
+ ctx.Ebx = lazyState->_ebx = baseState->_ebx;
+
+ nonVolRegPtrs.Edi = &(lazyState->_edi);
+ nonVolRegPtrs.Esi = &(lazyState->_esi);
+ nonVolRegPtrs.Ebx = &(lazyState->_ebx);
+ nonVolRegPtrs.Ebp = &(lazyState->_ebp);
+
+ PCODE pvControlPc;
+
+ LOG((LF_GCROOTS, LL_INFO100000, "STACKWALK LazyMachState::unwindLazyState(ip:%p,bp:%p,sp:%p)\n", baseState->captureEip, baseState->captureEbp, baseState->captureEsp));
+
+ do
+ {
+#ifdef DACCESS_COMPILE
+ HRESULT hr = DacVirtualUnwind(threadId, &ctx, &nonVolRegPtrs);
+ if (FAILED(hr))
+ {
+ DacError(hr);
+ }
+#else
+ BOOL success = PAL_VirtualUnwind(&ctx, &nonVolRegPtrs);
+ if (!success)
+ {
+ _ASSERTE(!"unwindLazyState: Unwinding failed");
+ EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE);
+ }
+#endif // DACCESS_COMPILE
+
+ pvControlPc = GetIP(&ctx);
+
+ if (funCallDepth > 0)
+ {
+ --funCallDepth;
+ if (funCallDepth == 0)
+ break;
+ }
+ else
+ {
+ // Determine whether given IP resides in JITted code. (It returns nonzero in that case.)
+ // Use it now to see if we've unwound to managed code yet.
+ BOOL fFailedReaderLock = FALSE;
+ BOOL fIsManagedCode = ExecutionManager::IsManagedCode(pvControlPc, hostCallPreference, &fFailedReaderLock);
+ if (fFailedReaderLock)
+ {
+ // We don't know if we would have been able to find a JIT
+ // manager, because we couldn't enter the reader lock without
+ // yielding (and our caller doesn't want us to yield). So abort
+ // now.
+
+ // Invalidate the lazyState we're returning, so the caller knows
+ // we aborted before we could fully unwind
+ lazyState->_pRetAddr = NULL;
+ return;
+ }
+
+ if (fIsManagedCode)
+ break;
+ }
+ }
+ while(TRUE);
+
+ lazyState->_esp = ctx.Esp;
+ lazyState->_pRetAddr = PTR_TADDR(lazyState->_esp - 4);
+
+ lazyState->_edi = ctx.Edi;
+ lazyState->_esi = ctx.Esi;
+ lazyState->_ebx = ctx.Ebx;
+ lazyState->_ebp = ctx.Ebp;
+
+#ifdef DACCESS_COMPILE
+ lazyState->_pEdi = NULL;
+ lazyState->_pEsi = NULL;
+ lazyState->_pEbx = NULL;
+ lazyState->_pEbp = NULL;
+#else // DACCESS_COMPILE
+ lazyState->_pEdi = nonVolRegPtrs.Edi;
+ lazyState->_pEsi = nonVolRegPtrs.Esi;
+ lazyState->_pEbx = nonVolRegPtrs.Ebx;
+ lazyState->_pEbp = nonVolRegPtrs.Ebp;
+#endif // DACCESS_COMPILE
+}
+#endif // !USE_EXTERNAL_UNWINDER
diff --git a/src/vm/i386/jithelp.S b/src/vm/i386/jithelp.S
new file mode 100644
index 0000000000..66ae9fb451
--- /dev/null
+++ b/src/vm/i386/jithelp.S
@@ -0,0 +1,749 @@
+// Licensed to the .NET Foundation under one or more 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"
+
+
+// ***
+// JIT_WriteBarrier* - GC write barrier helper
+//
+// Purpose:
+// Helper calls in order to assign an object to a field
+// Enables book-keeping of the GC.
+//
+// Entry:
+// EDX - address of ref-field (assigned to)
+// the resp. other reg - RHS of assignment
+//
+// Exit:
+//
+// Uses:
+// EDX is destroyed.
+//
+// Exceptions:
+//
+// *******************************************************************************
+
+// The code here is tightly coupled with AdjustContextForWriteBarrier, if you change
+// anything here, you might need to change AdjustContextForWriteBarrier as well
+.macro WriteBarrierHelper rg
+.align 4
+
+// The entry point is the fully 'safe' one in which we check if EDX (the REF
+// begin updated) is actually in the GC heap
+NESTED_ENTRY JIT_CheckedWriteBarrier\rg, _TEXT, NoHandler
+ // check in the REF being updated is in the GC heap
+ push eax
+ PREPARE_EXTERNAL_VAR g_lowest_address, eax
+ cmp edx, [eax]
+ pop eax
+ jb LOCAL_LABEL(WriteBarrier_NotInHeap_\rg)
+ push eax
+ PREPARE_EXTERNAL_VAR g_highest_address, eax
+ cmp edx, [eax]
+ pop eax
+ jae LOCAL_LABEL(WriteBarrier_NotInHeap_\rg)
+
+ // fall through to unchecked routine
+ // note that its entry point also happens to be aligned
+
+#ifdef WRITE_BARRIER_CHECK
+ // This entry point is used when you know the REF pointer being updated
+ // is in the GC heap
+PATCH_LABEL JIT_DebugWriteBarrier\rg
+#endif // WRITE_BARRIER_CHECK
+
+#ifdef _DEBUG
+ push edx
+ push ecx
+ push eax
+
+ push \rg
+ push edx
+ call C_FUNC(WriteBarrierAssert)
+
+ pop eax
+ pop ecx
+ pop edx
+#endif // _DEBUG
+
+ // in the !WRITE_BARRIER_CHECK case this will be the move for all
+ // addresses in the GCHeap, addresses outside the GCHeap will get
+ // taken care of below at WriteBarrier_NotInHeap_&rg
+
+#ifndef WRITE_BARRIER_CHECK
+ mov DWORD PTR [edx], \rg
+#endif // !WRITE_BARRIER_CHECK
+
+#ifdef WRITE_BARRIER_CHECK
+ // Test dest here so if it is bad AV would happen before we change register/stack
+ // status. This makes job of AdjustContextForWriteBarrier easier.
+ cmp BYTE PTR [edx], 0
+ // ALSO update the shadow GC heap if that is enabled
+ // Make ebp into the temporary src register. We need to do this so that we can use ecx
+ // in the calculation of the shadow GC address, but still have access to the src register
+ push ecx
+ push ebp
+ mov ebp, \rg
+
+ // if g_GCShadow is 0, don't perform the check
+ push eax
+ PREPARE_EXTERNAL_VAR g_GCShadow, eax
+ cmp DWORD PTR [eax], 0
+ pop eax
+ je LOCAL_LABEL(WriteBarrier_NoShadow_\rg)
+
+ mov ecx, edx
+ push eax
+ PREPARE_EXTERNAL_VAR g_lowest_address, eax
+ sub ecx, [eax]
+ pop eax
+ jb LOCAL_LABEL(WriteBarrier_NoShadow_\rg)
+ push edx
+ PREPARE_EXTERNAL_VAR g_GCShadow, edx
+ mov [edx], edx
+ add ecx, [edx]
+ PREPARE_EXTERNAL_VAR g_GCShadowEnd, edx
+ mov [edx], edx
+ cmp ecx, [edx]
+ pop edx
+ ja LOCAL_LABEL(WriteBarrier_NoShadow_\rg)
+
+ // TODO: In Orcas timeframe if we move to P4+ only on X86 we should enable
+ // mfence barriers on either side of these two writes to make sure that
+ // they stay as close together as possible
+
+ // edx contains address in GC
+ // ecx contains address in ShadowGC
+ // ebp temporarially becomes the src register
+
+ // When we're writing to the shadow GC heap we want to be careful to minimize
+ // the risk of a race that can occur here where the GC and ShadowGC don't match
+ mov DWORD PTR [edx], ebp
+ mov DWORD PTR [ecx], ebp
+
+ // We need a scratch register to verify the shadow heap. We also need to
+ // construct a memory barrier so that the write to the shadow heap happens
+ // before the read from the GC heap. We can do both by using SUB/XCHG
+ // rather than PUSH.
+ //
+ // TODO: Should be changed to a push if the mfence described above is added.
+ //
+ sub esp, 4
+ xchg [esp], eax
+
+ // As part of our race avoidance (see above) we will now check whether the values
+ // in the GC and ShadowGC match. There is a possibility that we're wrong here but
+ // being overaggressive means we might mask a case where someone updates GC refs
+ // without going to a write barrier, but by its nature it will be indeterminant
+ // and we will find real bugs whereas the current implementation is indeterminant
+ // but only leads to investigations that find that this code is fundamentally flawed
+ mov eax, [edx]
+ cmp [ecx], eax
+ je LOCAL_LABEL(WriteBarrier_CleanupShadowCheck_\rg)
+ mov DWORD PTR [ecx], INVALIDGCVALUE
+
+LOCAL_LABEL(WriteBarrier_CleanupShadowCheck_\rg):
+ pop eax
+
+ jmp LOCAL_LABEL(WriteBarrier_ShadowCheckEnd_\rg)
+
+LOCAL_LABEL(WriteBarrier_NoShadow_\rg):
+ // If we come here then we haven't written the value to the GC and need to.
+ // ebp contains rg
+ // We restore ebp/ecx immediately after this, and if either of them is the src
+ // register it will regain its value as the src register.
+ mov DWORD PTR [edx], ebp
+LOCAL_LABEL(WriteBarrier_ShadowCheckEnd_\rg):
+ pop ebp
+ pop ecx
+#endif // WRITE_BARRIER_CHECK
+
+ push eax
+ push ebx
+ mov eax, \rg
+ PREPARE_EXTERNAL_VAR g_ephemeral_low, ebx
+ cmp eax, [ebx]
+ pop ebx
+ pop eax
+ jb LOCAL_LABEL(WriteBarrier_NotInEphemeral_\rg)
+ push eax
+ push ebx
+ mov eax, \rg
+ PREPARE_EXTERNAL_VAR g_ephemeral_high, ebx
+ cmp eax, [ebx]
+ pop ebx
+ pop eax
+ jae LOCAL_LABEL(WriteBarrier_NotInEphemeral_\rg)
+
+ shr edx, 10
+ push eax
+ PREPARE_EXTERNAL_VAR g_card_table, eax
+ add edx, [eax]
+ pop eax
+ cmp BYTE PTR [edx], 0FFh
+ jne LOCAL_LABEL(WriteBarrier_UpdateCardTable_\rg)
+ ret
+
+LOCAL_LABEL(WriteBarrier_UpdateCardTable_\rg):
+ mov BYTE PTR [edx], 0FFh
+ ret
+
+LOCAL_LABEL(WriteBarrier_NotInHeap_\rg):
+ // If it wasn't in the heap then we haven't updated the dst in memory yet
+ mov DWORD PTR [edx], \rg
+
+LOCAL_LABEL(WriteBarrier_NotInEphemeral_\rg):
+ // If it is in the GC Heap but isn't in the ephemeral range we've already
+ // updated the Heap with the Object*.
+ ret
+NESTED_END JIT_CheckedWriteBarrier\rg, _TEXT
+
+.endm
+
+
+// ***
+// JIT_ByRefWriteBarrier* - GC write barrier helper
+//
+// Purpose:
+// Helper calls in order to assign an object to a byref field
+// Enables book-keeping of the GC.
+//
+// Entry:
+// EDI - address of ref-field (assigned to)
+// ESI - address of the data (source)
+// ECX can be trashed
+//
+// Exit:
+//
+// Uses:
+// EDI and ESI are incremented by a DWORD
+//
+// Exceptions:
+//
+// *******************************************************************************
+//
+// The code here is tightly coupled with AdjustContextForWriteBarrier, if you change
+// anything here, you might need to change AdjustContextForWriteBarrier as well
+//
+.macro ByRefWriteBarrierHelper
+.align 4
+
+LEAF_ENTRY JIT_ByRefWriteBarrier, _TEXT
+ // test for dest in range
+ mov ecx, [esi]
+ push eax
+ PREPARE_EXTERNAL_VAR g_lowest_address, eax
+ cmp edi, [eax]
+ pop eax
+ jb LOCAL_LABEL(ByRefWriteBarrier_NotInHeap)
+ push eax
+ PREPARE_EXTERNAL_VAR g_highest_address, eax
+ cmp edi, [eax]
+ pop eax
+ jae LOCAL_LABEL(ByRefWriteBarrier_NotInHeap)
+
+#ifndef WRITE_BARRIER_CHECK
+ // write barrier
+ mov [edi], ecx
+#endif // !WRITE_BARRIER_CHECK
+
+#ifdef WRITE_BARRIER_CHECK
+ // Test dest here so if it is bad AV would happen before we change register/stack
+ // status. This makes job of AdjustContextForWriteBarrier easier.
+ cmp BYTE PTR [edi], 0
+
+ // ALSO update the shadow GC heap if that is enabled
+
+ // use edx for address in GC Shadow,
+ push edx
+
+ // if g_GCShadow is 0, don't do the update
+ push ebx
+ PREPARE_EXTERNAL_VAR g_GCShadow, ebx
+ cmp DWORD PTR [ebx], 0
+ pop ebx
+ je LOCAL_LABEL(ByRefWriteBarrier_NoShadow)
+
+ mov edx, edi
+ push ebx
+ PREPARE_EXTERNAL_VAR g_lowest_address, ebx
+ sub edx, [ebx] // U/V
+ pop ebx
+ jb LOCAL_LABEL(ByRefWriteBarrier_NoShadow)
+ push eax
+ PREPARE_EXTERNAL_VAR g_GCShadow, eax
+ mov eax, [eax]
+ add edx, [eax]
+ PREPARE_EXTERNAL_VAR g_GCShadowEnd, eax
+ mov eax, [eax]
+ cmp edx, [eax]
+ pop eax
+ ja LOCAL_LABEL(ByRefWriteBarrier_NoShadow)
+
+ // TODO: In Orcas timeframe if we move to P4+ only on X86 we should enable
+ // mfence barriers on either side of these two writes to make sure that
+ // they stay as close together as possible
+
+ // edi contains address in GC
+ // edx contains address in ShadowGC
+ // ecx is the value to assign
+
+ // When we're writing to the shadow GC heap we want to be careful to minimize
+ // the risk of a race that can occur here where the GC and ShadowGC don't match
+ mov DWORD PTR [edi], ecx
+ mov DWORD PTR [edx], ecx
+
+ // We need a scratch register to verify the shadow heap. We also need to
+ // construct a memory barrier so that the write to the shadow heap happens
+ // before the read from the GC heap. We can do both by using SUB/XCHG
+ // rather than PUSH.
+ //
+ // TODO: Should be changed to a push if the mfence described above is added.
+ //
+ sub esp, 4
+ xchg [esp], eax
+
+ // As part of our race avoidance (see above) we will now check whether the values
+ // in the GC and ShadowGC match. There is a possibility that we're wrong here but
+ // being overaggressive means we might mask a case where someone updates GC refs
+ // without going to a write barrier, but by its nature it will be indeterminant
+ // and we will find real bugs whereas the current implementation is indeterminant
+ // but only leads to investigations that find that this code is fundamentally flawed
+
+ mov eax, [edi]
+ cmp [edx], eax
+ je LOCAL_LABEL(ByRefWriteBarrier_CleanupShadowCheck)
+ mov DWORD PTR [edx], INVALIDGCVALUE
+LOCAL_LABEL(ByRefWriteBarrier_CleanupShadowCheck):
+ pop eax
+ jmp LOCAL_LABEL(ByRefWriteBarrier_ShadowCheckEnd)
+
+LOCAL_LABEL(ByRefWriteBarrier_NoShadow):
+ // If we come here then we haven't written the value to the GC and need to.
+ mov DWORD PTR [edi], ecx
+
+LOCAL_LABEL(ByRefWriteBarrier_ShadowCheckEnd):
+ pop edx
+#endif // WRITE_BARRIER_CHECK
+
+ // test for *src in ephemeral segement
+ push eax
+ PREPARE_EXTERNAL_VAR g_ephemeral_low, eax
+ cmp ecx, [eax]
+ pop eax
+ jb LOCAL_LABEL(ByRefWriteBarrier_NotInEphemeral)
+ push eax
+ PREPARE_EXTERNAL_VAR g_ephemeral_high, eax
+ cmp ecx, [eax]
+ pop eax
+ jae LOCAL_LABEL(ByRefWriteBarrier_NotInEphemeral)
+
+ mov ecx, edi
+ add esi, 4
+ add edi, 4
+
+ shr ecx, 10
+ push eax
+ PREPARE_EXTERNAL_VAR g_card_table, eax
+ add ecx, [eax]
+ pop eax
+ cmp BYTE PTR [ecx], 0FFh
+ jne LOCAL_LABEL(ByRefWriteBarrier_UpdateCardTable)
+ ret
+LOCAL_LABEL(ByRefWriteBarrier_UpdateCardTable):
+ mov BYTE PTR [ecx], 0FFh
+ ret
+
+LOCAL_LABEL(ByRefWriteBarrier_NotInHeap):
+ // If it wasn't in the heap then we haven't updated the dst in memory yet
+ mov [edi], ecx
+LOCAL_LABEL(ByRefWriteBarrier_NotInEphemeral):
+ // If it is in the GC Heap but isn't in the ephemeral range we've already
+ // updated the Heap with the Object*.
+ add esi, 4
+ add edi, 4
+ ret
+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.
+//
+LEAF_ENTRY JIT_WriteBarrierStart, _TEXT
+ ret
+LEAF_END JIT_WriteBarrierStart, _TEXT
+
+#ifdef FEATURE_USE_ASM_GC_WRITE_BARRIERS
+// *******************************************************************************
+// Write barrier wrappers with fcall calling convention
+//
+.macro UniversalWriteBarrierHelper name
+.align 4
+
+LEAF_ENTRY JIT_\name, _TEXT
+ mov eax, edx
+ mov edx, ecx
+ jmp C_FUNC(JIT_\name\()EAX)
+LEAF_END JIT_\name, _TEXT
+
+.endm
+
+// Only define these if we're using the ASM GC write barriers; if this flag is not defined,
+// we'll use C++ versions of these write barriers.
+UniversalWriteBarrierHelper CheckedWriteBarrier
+UniversalWriteBarrierHelper WriteBarrier
+#endif // FEATURE_USE_ASM_GC_WRITE_BARRIERS
+
+WriteBarrierHelper EAX
+WriteBarrierHelper EBX
+WriteBarrierHelper ECX
+WriteBarrierHelper ESI
+WriteBarrierHelper EDI
+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
+ ret
+LEAF_END JIT_WriteBarrierEnd, _TEXT
+
+// *********************************************************************/
+// In cases where we support it we have an optimized GC Poll callback.
+// Normall (when we're not trying to suspend for GC, the CORINFO_HELP_POLL_GC
+// helper points to this nop routine. When we're ready to suspend for GC,
+// we whack the Jit Helper table entry to point to the real helper. When we're
+// done with GC we whack it back.
+LEAF_ENTRY JIT_PollGC_Nop, _TEXT
+ ret
+LEAF_END JIT_PollGC_Nop, _TEXT
+
+// *********************************************************************/
+// llshl - long shift left
+//
+// Purpose:
+// Does a Long Shift Left (signed and unsigned are identical)
+// Shifts a long left any number of bits.
+//
+// NOTE: This routine has been adapted from the Microsoft CRTs.
+//
+// Entry:
+// EDX:EAX - long value to be shifted
+// ECX - number of bits to shift by
+//
+// Exit:
+// EDX:EAX - shifted value
+//
+.align 16
+LEAF_ENTRY JIT_LLsh, _TEXT
+ cmp ecx, 32
+ jae LOCAL_LABEL(LLshMORE32)
+
+ // Handle shifts of between bits 0 and 31
+ shld edx, eax, cl
+ shl eax, cl
+ ret
+
+LOCAL_LABEL(LLshMORE32):
+ // Handle shifts of between bits 32 and 63
+ // The x86 shift instructions only use the lower 5 bits.
+ mov edx, eax
+ xor eax, eax
+ shl edx, cl
+ ret
+LEAF_END JIT_LLsh, _TEXT
+
+// *********************************************************************/
+// LRsh - long shift right
+//
+// Purpose:
+// Does a signed Long Shift Right
+// Shifts a long right any number of bits.
+//
+// NOTE: This routine has been adapted from the Microsoft CRTs.
+//
+// Entry:
+// EDX:EAX - long value to be shifted
+// ECX - number of bits to shift by
+//
+// Exit:
+// EDX:EAX - shifted value
+//
+.align 16
+LEAF_ENTRY JIT_LRsh, _TEXT
+ cmp ecx, 32
+ jae LOCAL_LABEL(LRshMORE32)
+
+ // Handle shifts of between bits 0 and 31
+ shrd eax, edx, cl
+ sar edx, cl
+ ret
+
+LOCAL_LABEL(LRshMORE32):
+ // Handle shifts of between bits 32 and 63
+ // The x86 shift instructions only use the lower 5 bits.
+ mov eax, edx
+ sar edx, 31
+ sar eax, cl
+ ret
+LEAF_END JIT_LRsh, _TEXT
+
+// *********************************************************************/
+// LRsz:
+// Purpose:
+// Does a unsigned Long Shift Right
+// Shifts a long right any number of bits.
+//
+// NOTE: This routine has been adapted from the Microsoft CRTs.
+//
+// Entry:
+// EDX:EAX - long value to be shifted
+// ECX - number of bits to shift by
+//
+// Exit:
+// EDX:EAX - shifted value
+//
+.align 16
+LEAF_ENTRY JIT_LRsz, _TEXT
+ cmp ecx, 32
+ jae LOCAL_LABEL(LRszMORE32)
+
+ // Handle shifts of between bits 0 and 31
+ shrd eax, edx, cl
+ shr edx, cl
+ ret
+
+LOCAL_LABEL(LRszMORE32):
+ // Handle shifts of between bits 32 and 63
+ // The x86 shift instructions only use the lower 5 bits.
+ mov eax, edx
+ xor edx, edx
+ shr eax, cl
+ ret
+LEAF_END JIT_LRsz, _TEXT
+
+// *********************************************************************/
+// JIT_Dbl2LngP4x87
+//
+// Purpose:
+// converts a double to a long truncating toward zero (C semantics)
+//
+// uses stdcall calling conventions
+//
+// This code is faster on a P4 than the Dbl2Lng code above, but is
+// slower on a PIII. Hence we choose this code when on a P4 or above.
+//
+LEAF_ENTRY JIT_Dbl2LngP4x87, _TEXT
+ // get some local space
+ sub esp, 8
+
+ #define arg1 [esp + 0Ch]
+ fld QWORD PTR arg1 // fetch arg
+ fnstcw WORD PTR arg1 // store FPCW
+ movzx eax, WORD PTR arg1 // zero extend - wide
+ or ah, 0Ch // turn on OE and DE flags
+ mov DWORD PTR [esp], eax // store new FPCW bits
+ fldcw WORD PTR [esp] // reload FPCW with new bits
+ fistp QWORD PTR [esp] // convert
+
+ // reload FP result
+ mov eax, DWORD PTR [esp]
+ mov edx, DWORD PTR [esp + 4]
+
+ // reload original FPCW value
+ fldcw WORD PTR arg1
+ #undef arg1
+
+ // restore stack
+ add esp, 8
+
+ ret 8
+LEAF_END JIT_Dbl2LngP4x87, _TEXT
+
+// *********************************************************************/
+// JIT_Dbl2LngSSE3
+//
+// Purpose:
+// converts a double to a long truncating toward zero (C semantics)
+//
+// uses stdcall calling conventions
+//
+// This code is faster than the above P4 x87 code for Intel processors
+// equal or later than Core2 and Atom that have SSE3 support
+//
+LEAF_ENTRY JIT_Dbl2LngSSE3, _TEXT
+ // get some local space
+ sub esp, 8
+
+ fld QWORD PTR [esp + 0Ch] // fetch arg
+ fisttp QWORD PTR [esp] // convert
+ mov eax, DWORD PTR [esp] // reload FP result
+ mov edx, DWORD PTR [esp + 4]
+
+ // restore stack
+ add esp, 8
+
+ ret 8
+LEAF_END JIT_Dbl2LngSSE3, _TEXT
+
+// *********************************************************************/
+// JIT_Dbl2IntSSE2
+//
+// Purpose:
+// converts a double to a long truncating toward zero (C semantics)
+//
+// uses stdcall calling conventions
+//
+// This code is even faster than the P4 x87 code for Dbl2LongP4x87,
+// but only returns a 32 bit value (only good for int).
+//
+LEAF_ENTRY JIT_Dbl2IntSSE2, _TEXT
+ movsd xmm0, [esp + 4]
+ cvttsd2si eax, xmm0
+ ret 8
+LEAF_END JIT_Dbl2IntSSE2, _TEXT
+
+// *********************************************************************/
+// This is the small write barrier thunk we use when we know the
+// ephemeral generation is higher in memory than older generations.
+// The 0x0F0F0F0F values are bashed by the two functions above.
+// This the generic version - wherever the code says ECX,
+// the specific register is patched later into a copy
+// Note: do not replace ECX by EAX - there is a smaller encoding for
+// the compares just for EAX, which won't work for other registers.
+//
+// READ THIS!!!!!!
+// it is imperative that the addresses of of the values that we overwrite
+// (card table, ephemeral region ranges, etc) are naturally aligned since
+// there are codepaths that will overwrite these values while the EE is running.
+//
+LEAF_ENTRY JIT_WriteBarrierReg_PreGrow, _TEXT
+ mov DWORD PTR [edx], ecx
+ cmp ecx, 0F0F0F0F0h
+ jb LOCAL_LABEL(NoWriteBarrierPre)
+
+ shr edx, 10
+ nop // padding for alignment of constant
+ cmp BYTE PTR [edx + 0F0F0F0F0h], 0FFh
+ jne LOCAL_LABEL(WriteBarrierPre)
+
+LOCAL_LABEL(NoWriteBarrierPre):
+ ret
+ nop // padding for alignment of constant
+ nop // padding for alignment of constant
+
+LOCAL_LABEL(WriteBarrierPre):
+ mov BYTE PTR [edx+0F0F0F0F0h], 0FFh
+ ret
+LEAF_END JIT_WriteBarrierReg_PreGrow, _TEXT
+
+// *********************************************************************/
+// This is the larger write barrier thunk we use when we know that older
+// generations may be higher in memory than the ephemeral generation
+// The 0x0F0F0F0F values are bashed by the two functions above.
+// This the generic version - wherever the code says ECX,
+// the specific register is patched later into a copy
+// Note: do not replace ECX by EAX - there is a smaller encoding for
+// the compares just for EAX, which won't work for other registers.
+// NOTE: we need this aligned for our validation to work properly
+.align 4
+LEAF_ENTRY JIT_WriteBarrierReg_PostGrow, _TEXT
+ mov DWORD PTR [edx], ecx
+ cmp ecx, 0F0F0F0F0h
+ jb LOCAL_LABEL(NoWriteBarrierPost)
+ cmp ecx, 0F0F0F0F0h
+ jae LOCAL_LABEL(NoWriteBarrierPost)
+
+ shr edx, 10
+ nop // padding for alignment of constant
+ cmp BYTE PTR [edx + 0F0F0F0F0h], 0FFh
+ jne LOCAL_LABEL(WriteBarrierPost)
+
+LOCAL_LABEL(NoWriteBarrierPost):
+ ret
+ nop // padding for alignment of constant
+ nop // padding for alignment of constant
+
+LOCAL_LABEL(WriteBarrierPost):
+ mov BYTE PTR [edx + 0F0F0F0F0h], 0FFh
+ ret
+LEAF_END JIT_WriteBarrierReg_PostGrow,_TEXT
+
+// PatchedCodeStart and PatchedCodeEnd are used to determine bounds of patched code.
+//
+
+LEAF_ENTRY JIT_PatchedCodeStart, _TEXT
+ ret
+LEAF_END JIT_PatchedCodeStart, _TEXT
+
+// **********************************************************************
+// Write barriers generated at runtime
+
+LEAF_ENTRY JIT_PatchedWriteBarrierStart, _TEXT
+ ret
+LEAF_END JIT_PatchedWriteBarrierStart, _TEXT
+
+.macro PatchedWriteBarrierHelper rg
+.align 8
+LEAF_ENTRY JIT_WriteBarrier\rg, _TEXT
+ // Just allocate space that will be filled in at runtime
+ .space 0CCH, 48
+LEAF_END JIT_WriteBarrier\rg, _TEXT
+
+.endm
+
+PatchedWriteBarrierHelper EAX
+PatchedWriteBarrierHelper EBX
+PatchedWriteBarrierHelper ECX
+PatchedWriteBarrierHelper ESI
+PatchedWriteBarrierHelper EDI
+PatchedWriteBarrierHelper EBP
+
+LEAF_ENTRY JIT_PatchedWriteBarrierLast, _TEXT
+ ret
+LEAF_END JIT_PatchedWriteBarrierLast, _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
+
+// Note that the debugger skips this entirely when doing SetIP,
+// since COMPlusCheckForAbort should always return 0. Excep.cpp:LeaveCatch
+// asserts that to be true. If this ends up doing more work, then the
+// debugger may need additional support.
+// void __stdcall JIT_EndCatch();
+NESTED_ENTRY JIT_EndCatch, _TEXT, NoHandler
+ // make temp storage for return address, and push the address of that
+ // as the last arg to COMPlusEndCatch
+ mov ecx, [esp]
+ push ecx
+ push esp
+
+ // push the rest of COMPlusEndCatch's args, right-to-left
+ push esi
+ push edi
+ push ebx
+ push ebp
+
+ // returns old esp value in eax, stores jump address
+ call C_FUNC(COMPlusEndCatch)
+ // now eax = new esp, [esp] = new eip
+
+ pop edx // edx = new eip
+ mov esp, eax // esp = new esp
+ jmp edx // eip = new eip
+NESTED_END JIT_EndCatch, _TEXT
diff --git a/src/vm/i386/jithelp.asm b/src/vm/i386/jithelp.asm
index ac767287ee..9d2f6b7589 100644
--- a/src/vm/i386/jithelp.asm
+++ b/src/vm/i386/jithelp.asm
@@ -92,6 +92,8 @@ EXTERN _TransparentProxyStub_CrossContext@0:PROC
EXTERN _InContextTPQuickDispatchAsmStub@0:PROC
endif
+EXTERN _COMPlusEndCatch@20:PROC
+
.686P
.XMM
; The following macro is needed because of a MASM issue with the
@@ -2571,4 +2573,32 @@ ChkCastInterfaceIsNullInst:
@JIT_ChkCastInterface@8 endp
+; Note that the debugger skips this entirely when doing SetIP,
+; since COMPlusCheckForAbort should always return 0. Excep.cpp:LeaveCatch
+; asserts that to be true. If this ends up doing more work, then the
+; debugger may need additional support.
+; void __stdcall JIT_EndCatch();
+JIT_EndCatch PROC stdcall public
+
+ ; make temp storage for return address, and push the address of that
+ ; as the last arg to COMPlusEndCatch
+ mov ecx, [esp]
+ push ecx;
+ push esp;
+
+ ; push the rest of COMPlusEndCatch's args, right-to-left
+ push esi
+ push edi
+ push ebx
+ push ebp
+
+ call _COMPlusEndCatch@20 ; returns old esp value in eax, stores jump address
+ ; now eax = new esp, [esp] = new eip
+
+ pop edx ; edx = new eip
+ mov esp, eax ; esp = new esp
+ jmp edx ; eip = new eip
+
+JIT_EndCatch ENDP
+
end
diff --git a/src/vm/i386/jitinterfacex86.cpp b/src/vm/i386/jitinterfacex86.cpp
index 949b115ce2..a80b5e6325 100644
--- a/src/vm/i386/jitinterfacex86.cpp
+++ b/src/vm/i386/jitinterfacex86.cpp
@@ -57,10 +57,10 @@ extern "C" void STDCALL WriteBarrierAssert(BYTE* ptr, Object* obj)
if (fVerifyHeap)
{
obj->Validate(FALSE);
- if(GCHeap::GetGCHeap()->IsHeapPointer(ptr))
+ if(GCHeapUtilities::GetGCHeap()->IsHeapPointer(ptr))
{
Object* pObj = *(Object**)ptr;
- _ASSERTE (pObj == NULL || GCHeap::GetGCHeap()->IsHeapPointer(pObj));
+ _ASSERTE (pObj == NULL || GCHeapUtilities::GetGCHeap()->IsHeapPointer(pObj));
}
}
else
@@ -72,6 +72,7 @@ extern "C" void STDCALL WriteBarrierAssert(BYTE* ptr, Object* obj)
#endif // _DEBUG
+#ifndef FEATURE_PAL
/****************************************************************************/
/* assigns 'val to 'array[idx], after doing all the proper checks */
@@ -330,7 +331,9 @@ extern "C" __declspec(naked) Object* F_CALL_CONV JIT_ChkCastClassSpecial(MethodT
jmp JITutil_ChkCastAny
}
}
+#endif // FEATURE_PAL
+#ifndef FEATURE_PAL
HCIMPL1_V(INT32, JIT_Dbl2IntOvf, double val)
{
FCALL_CONTRACT;
@@ -346,6 +349,7 @@ THROW:
FCThrow(kOverflowException);
}
HCIMPLEND
+#endif // FEATURE_PAL
FCDECL1(Object*, JIT_New, CORINFO_CLASS_HANDLE typeHnd_);
@@ -610,7 +614,7 @@ void JIT_TrialAlloc::EmitCore(CPUSTUBLINKER *psl, CodeLabel *noLock, CodeLabel *
if (flags & (ALIGN8 | SIZE_IN_EAX | ALIGN8OBJ))
{
// MOV EBX, [edx]Thread.m_alloc_context.alloc_ptr
- psl->X86EmitOffsetModRM(0x8B, kEBX, kEDX, offsetof(Thread, m_alloc_context) + offsetof(alloc_context, alloc_ptr));
+ psl->X86EmitOffsetModRM(0x8B, kEBX, kEDX, offsetof(Thread, m_alloc_context) + offsetof(gc_alloc_context, alloc_ptr));
// add EAX, EBX
psl->Emit16(0xC303);
if (flags & ALIGN8)
@@ -619,11 +623,11 @@ void JIT_TrialAlloc::EmitCore(CPUSTUBLINKER *psl, CodeLabel *noLock, CodeLabel *
else
{
// add eax, [edx]Thread.m_alloc_context.alloc_ptr
- psl->X86EmitOffsetModRM(0x03, kEAX, kEDX, offsetof(Thread, m_alloc_context) + offsetof(alloc_context, alloc_ptr));
+ psl->X86EmitOffsetModRM(0x03, kEAX, kEDX, offsetof(Thread, m_alloc_context) + offsetof(gc_alloc_context, alloc_ptr));
}
// cmp eax, [edx]Thread.m_alloc_context.alloc_limit
- psl->X86EmitOffsetModRM(0x3b, kEAX, kEDX, offsetof(Thread, m_alloc_context) + offsetof(alloc_context, alloc_limit));
+ psl->X86EmitOffsetModRM(0x3b, kEAX, kEDX, offsetof(Thread, m_alloc_context) + offsetof(gc_alloc_context, alloc_limit));
// ja noAlloc
psl->X86EmitCondJump(noAlloc, X86CondCode::kJA);
@@ -631,7 +635,7 @@ void JIT_TrialAlloc::EmitCore(CPUSTUBLINKER *psl, CodeLabel *noLock, CodeLabel *
// Fill in the allocation and get out.
// mov [edx]Thread.m_alloc_context.alloc_ptr, eax
- psl->X86EmitIndexRegStore(kEDX, offsetof(Thread, m_alloc_context) + offsetof(alloc_context, alloc_ptr), kEAX);
+ psl->X86EmitIndexRegStore(kEDX, offsetof(Thread, m_alloc_context) + offsetof(gc_alloc_context, alloc_ptr), kEAX);
if (flags & (ALIGN8 | SIZE_IN_EAX | ALIGN8OBJ))
{
@@ -1502,7 +1506,7 @@ void InitJITHelpers1()
_ASSERTE(g_SystemInfo.dwNumberOfProcessors != 0);
- JIT_TrialAlloc::Flags flags = GCHeap::UseAllocationContexts() ?
+ JIT_TrialAlloc::Flags flags = GCHeapUtilities::UseAllocationContexts() ?
JIT_TrialAlloc::MP_ALLOCATOR : JIT_TrialAlloc::NORMAL;
// Get CPU features and check for SSE2 support.
diff --git a/src/vm/i386/stublinkerx86.cpp b/src/vm/i386/stublinkerx86.cpp
index 0037a7d3e6..63b9e87367 100644
--- a/src/vm/i386/stublinkerx86.cpp
+++ b/src/vm/i386/stublinkerx86.cpp
@@ -64,6 +64,7 @@ extern "C" HRESULT __cdecl StubRareDisableHR(Thread *pThread);
#endif // FEATURE_COMINTEROP
extern "C" VOID __cdecl StubRareDisableTHROW(Thread *pThread, Frame *pFrame);
+#ifndef FEATURE_ARRAYSTUB_AS_IL
extern "C" VOID __cdecl ArrayOpStubNullException(void);
extern "C" VOID __cdecl ArrayOpStubRangeException(void);
extern "C" VOID __cdecl ArrayOpStubTypeMismatchException(void);
@@ -78,10 +79,13 @@ EXCEPTION_HELPERS(ArrayOpStubNullException);
EXCEPTION_HELPERS(ArrayOpStubRangeException);
EXCEPTION_HELPERS(ArrayOpStubTypeMismatchException);
#undef EXCEPTION_HELPERS
+#endif // !_TARGET_AMD64_
+#endif // !FEATURE_ARRAYSTUB_AS_IL
-#if defined(_DEBUG)
+#if defined(_TARGET_AMD64_)
+#if defined(_DEBUG)
extern "C" VOID __cdecl DebugCheckStubUnwindInfo();
-#endif
+#endif // _DEBUG
#endif // _TARGET_AMD64_
// Presumably this code knows what it is doing with TLS. If we are hiding these
@@ -2535,7 +2539,7 @@ VOID StubLinkerCPU::X86EmitCurrentAppDomainFetch(X86Reg dstreg, unsigned preserv
#endif // FEATURE_IMPLICIT_TLS
}
-#ifdef _TARGET_X86_
+#if defined(_TARGET_X86_)
#ifdef PROFILING_SUPPORTED
VOID StubLinkerCPU::EmitProfilerComCallProlog(TADDR pFrameVptr, X86Reg regFrame)
@@ -2624,6 +2628,7 @@ VOID StubLinkerCPU::EmitProfilerComCallEpilog(TADDR pFrameVptr, X86Reg regFrame)
#endif // PROFILING_SUPPORTED
+#ifndef FEATURE_STUBS_AS_IL
//========================================================================
// Prolog for entering managed code from COM
// pushes the appropriate frame ptr
@@ -2850,6 +2855,7 @@ void StubLinkerCPU::EmitComMethodStubEpilog(TADDR pFrameVptr,
EmitLabel(rgRareLabels[0]); // label for rare setup thread
EmitRareSetup(rgRejoinLabels[0], /*fThrow*/ TRUE); // emit rare setup thread
}
+#endif // !FEATURE_STUBS_AS_IL
//---------------------------------------------------------------
// Emit code to store the setup current Thread structure in eax.
@@ -2882,6 +2888,7 @@ VOID StubLinkerCPU::EmitSetup(CodeLabel *pForwardRef)
switch (mode)
{
case TLSACCESS_WNT:
+#ifndef FEATURE_PAL
{
unsigned __int32 tlsofs = offsetof(TEB, TlsSlots) + (idx * sizeof(void*));
@@ -2889,6 +2896,9 @@ VOID StubLinkerCPU::EmitSetup(CodeLabel *pForwardRef)
EmitBytes(code, sizeof(code));
Emit32(tlsofs);
}
+#else // !FEATURE_PAL
+ _ASSERTE("TLSACCESS_WNT mode is not supported");
+#endif // !FEATURE_PAL
break;
case TLSACCESS_GENERIC:
@@ -2919,7 +2929,6 @@ VOID StubLinkerCPU::EmitSetup(CodeLabel *pForwardRef)
X86EmitDebugTrashReg(kECX);
X86EmitDebugTrashReg(kEDX);
#endif
-
}
VOID StubLinkerCPU::EmitRareSetup(CodeLabel *pRejoinPoint, BOOL fThrow)
@@ -4824,8 +4833,9 @@ VOID StubLinkerCPU::EmitSecureDelegateInvoke(UINT_PTR hash)
// Epilog
EmitMethodStubEpilog(numStackBytes, SecureDelegateFrame::GetOffsetOfTransitionBlock());
}
+#endif // !CROSSGEN_COMPILE && !FEATURE_STUBS_AS_IL
-#ifndef FEATURE_ARRAYSTUB_AS_IL
+#if !defined(CROSSGEN_COMPILE) && !defined(FEATURE_ARRAYSTUB_AS_IL)
// Little helper to generate code to move nbytes bytes of non Ref memory
@@ -5768,8 +5778,9 @@ COPY_VALUE_CLASS:
#pragma warning(pop)
#endif
-#endif // FEATURE_ARRAYSTUB_AS_IL
+#endif // !CROSSGEN_COMPILE && !FEATURE_ARRAYSTUB_AS_IL
+#if !defined(CROSSGEN_COMPILE) && !defined(FEATURE_STUBS_AS_IL)
//===========================================================================
// Emits code to break into debugger
VOID StubLinkerCPU::EmitDebugBreak()
@@ -5841,9 +5852,9 @@ Thread* __stdcall CreateThreadBlockReturnHr(ComMethodFrame *pFrame)
#pragma warning(pop)
#endif
-#endif // defined(FEATURE_COMINTEROP) && defined(_TARGET_X86_)
+#endif // FEATURE_COMINTEROP && _TARGET_X86_
-#endif // !defined(CROSSGEN_COMPILE) && !defined(FEATURE_STUBS_AS_IL)
+#endif // !CROSSGEN_COMPILE && !FEATURE_STUBS_AS_IL
#endif // !DACCESS_COMPILE
diff --git a/src/vm/i386/stublinkerx86.h b/src/vm/i386/stublinkerx86.h
index 237fc794d4..e361833a1e 100644
--- a/src/vm/i386/stublinkerx86.h
+++ b/src/vm/i386/stublinkerx86.h
@@ -345,6 +345,11 @@ class StubLinkerCPU : public StubLinker
VOID EmitSetup(CodeLabel *pForwardRef);
VOID EmitRareSetup(CodeLabel* pRejoinPoint, BOOL fThrow);
+
+#ifndef FEATURE_STUBS_AS_IL
+ VOID EmitMethodStubProlog(TADDR pFrameVptr, int transitionBlockOffset);
+ VOID EmitMethodStubEpilog(WORD numArgBytes, int transitionBlockOffset);
+
VOID EmitCheckGSCookie(X86Reg frameReg, int gsCookieOffset);
#ifdef _TARGET_X86_
@@ -353,10 +358,8 @@ class StubLinkerCPU : public StubLinker
void EmitComMethodStubEpilog(TADDR pFrameVptr, CodeLabel** rgRareLabels,
CodeLabel** rgRejoinLabels, BOOL bShouldProfile);
-#endif
-
- VOID EmitMethodStubProlog(TADDR pFrameVptr, int transitionBlockOffset);
- VOID EmitMethodStubEpilog(WORD numArgBytes, int transitionBlockOffset);
+#endif // _TARGET_X86_
+#endif // !FEATURE_STUBS_AS_IL
VOID EmitUnboxMethodStub(MethodDesc* pRealMD);
#if defined(FEATURE_SHARE_GENERIC_CODE)
@@ -374,13 +377,16 @@ class StubLinkerCPU : public StubLinker
BOOL bShouldProfile);
#endif // FEATURE_COMINTEROP && _TARGET_X86_
+#ifndef FEATURE_STUBS_AS_IL
//===========================================================================
// Computes hash code for MulticastDelegate.Invoke()
static UINT_PTR HashMulticastInvoke(MetaSig* pSig);
+#ifdef _TARGET_X86_
//===========================================================================
// Emits code for Delegate.Invoke() any delegate type
VOID EmitDelegateInvoke();
+#endif // _TARGET_X86_
//===========================================================================
// Emits code for MulticastDelegate.Invoke() - sig specific
@@ -389,22 +395,27 @@ class StubLinkerCPU : public StubLinker
//===========================================================================
// Emits code for Delegate.Invoke() on delegates that recorded creator assembly
VOID EmitSecureDelegateInvoke(UINT_PTR hash);
+#endif // !FEATURE_STUBS_AS_IL
//===========================================================================
// Emits code to adjust for a static delegate target.
VOID EmitShuffleThunk(struct ShuffleEntry *pShuffleEntryArray);
+#ifndef FEATURE_ARRAYSTUB_AS_IL
//===========================================================================
// Emits code to do an array operation.
VOID EmitArrayOpStub(const ArrayOpScript*);
//Worker function to emit throw helpers for array ops.
VOID EmitArrayOpStubThrow(unsigned exConst, unsigned cbRetArg);
+#endif
+#ifndef FEATURE_STUBS_AS_IL
//===========================================================================
// Emits code to break into debugger
VOID EmitDebugBreak();
+#endif // !FEATURE_STUBS_AS_IL
#if defined(_DEBUG) && (defined(_TARGET_AMD64_) || defined(_TARGET_X86_)) && !defined(FEATURE_PAL)
//===========================================================================
diff --git a/src/vm/i386/umthunkstub.S b/src/vm/i386/umthunkstub.S
new file mode 100644
index 0000000000..728964bdb6
--- /dev/null
+++ b/src/vm/i386/umthunkstub.S
@@ -0,0 +1,177 @@
+// Licensed to the .NET Foundation under one or more 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"
+
+//
+// eax = UMEntryThunk*
+//
+NESTED_ENTRY TheUMEntryPrestub, _TEXT, UnhandledExceptionHandlerUnix
+ // Preserve argument registers
+ push ecx
+ push edx
+
+ push eax // UMEntryThunk*
+ call C_FUNC(TheUMEntryPrestubWorker)
+ pop edx
+ // eax = PCODE
+
+ // Restore argument registers
+ pop edx
+ pop ecx
+
+ jmp eax // Tail Jmp
+NESTED_END TheUMEntryPrestub, _TEXT
+
+//
+// eax: UMEntryThunk*
+//
+NESTED_ENTRY UMThunkStub, _TEXT, UnhandledExceptionHandlerUnix
+
+#define UMThunkStub_SAVEDREG (3*4) // ebx, esi, edi
+#define UMThunkStub_LOCALVARS (2*4) // UMEntryThunk*, Thread*
+#define UMThunkStub_INT_ARG_SPILL (2*4) // for save ecx, edx
+#define UMThunkStub_UMENTRYTHUNK_OFFSET (UMThunkStub_SAVEDREG+4)
+#define UMThunkStub_THREAD_OFFSET (UMThunkStub_UMENTRYTHUNK_OFFSET+4)
+#define UMThunkStub_INT_ARG_OFFSET (UMThunkStub_THREAD_OFFSET+4)
+#define UMThunkStub_FIXEDALLOCSIZE (UMThunkStub_LOCALVARS+UMThunkStub_INT_ARG_SPILL)
+
+// return address <-- entry ESP
+// saved ebp <-- EBP
+// saved ebx
+// saved esi
+// saved edi
+// UMEntryThunk*
+// Thread*
+// save ecx
+// save edx
+// {optional stack args passed to callee} <-- new esp
+
+ PROLOG_BEG
+ PROLOG_PUSH ebx
+ PROLOG_PUSH esi
+ PROLOG_PUSH edi
+ PROLOG_END
+ sub esp, UMThunkStub_FIXEDALLOCSIZE
+
+ mov dword ptr [ebp - UMThunkStub_INT_ARG_OFFSET], ecx
+ mov dword ptr [ebp - UMThunkStub_INT_ARG_OFFSET - 0x04], edx
+
+ mov dword ptr [ebp - UMThunkStub_UMENTRYTHUNK_OFFSET], eax
+
+ call C_FUNC(GetThread)
+ test eax, eax
+ jz LOCAL_LABEL(DoThreadSetup)
+
+LOCAL_LABEL(HaveThread):
+
+ mov dword ptr [ebp - UMThunkStub_THREAD_OFFSET], eax
+
+ // FailFast if a native callable method is invoked via ldftn and calli.
+ cmp dword ptr [eax + Thread_m_fPreemptiveGCDisabled], 1
+ jz LOCAL_LABEL(InvalidTransition)
+
+ // disable preemptive GC
+ mov dword ptr [eax + Thread_m_fPreemptiveGCDisabled], 1
+
+ // catch returning thread here if a GC is in progress
+ PREPARE_EXTERNAL_VAR g_TrapReturningThreads, eax
+ cmp eax, 0
+ jnz LOCAL_LABEL(DoTrapReturningThreadsTHROW)
+
+LOCAL_LABEL(InCooperativeMode):
+
+#if _DEBUG
+ mov eax, dword ptr [ebp - UMThunkStub_THREAD_OFFSET]
+ mov eax, dword ptr [eax + Thread__m_pDomain]
+ mov esi, dword ptr [eax + AppDomain__m_dwId]
+
+ mov eax, dword ptr [ebp - UMThunkStub_UMENTRYTHUNK_OFFSET]
+ mov edi, dword ptr [eax + UMEntryThunk__m_dwDomainId]
+
+ cmp esi, edi
+ jne LOCAL_LABEL(WrongAppDomain)
+#endif
+
+ mov eax, dword ptr [ebp - UMThunkStub_UMENTRYTHUNK_OFFSET]
+ mov ebx, dword ptr [eax + UMEntryThunk__m_pUMThunkMarshInfo]
+ mov eax, dword ptr [ebx + UMThunkMarshInfo__m_cbActualArgSize]
+ test eax, eax
+ jnz LOCAL_LABEL(UMThunkStub_CopyStackArgs)
+
+LOCAL_LABEL(UMThunkStub_ArgumentsSetup):
+
+ mov ecx, dword ptr [ebp - UMThunkStub_INT_ARG_OFFSET]
+ mov edx, dword ptr [ebp - UMThunkStub_INT_ARG_OFFSET - 0x04]
+
+ mov eax, dword ptr [ebp - UMThunkStub_UMENTRYTHUNK_OFFSET]
+ mov ebx, dword ptr [eax + UMEntryThunk__m_pUMThunkMarshInfo]
+ mov ebx, dword ptr [ebx + UMThunkMarshInfo__m_pILStub]
+
+ call ebx
+
+LOCAL_LABEL(PostCall):
+
+ mov ebx, dword ptr [ebp - UMThunkStub_THREAD_OFFSET]
+ mov dword ptr [ebx + Thread_m_fPreemptiveGCDisabled], 0
+
+ lea esp, [ebp - UMThunkStub_SAVEDREG] // deallocate arguments
+ EPILOG_BEG
+ EPILOG_POP edi
+ EPILOG_POP esi
+ EPILOG_POP ebx
+ EPILOG_END
+ ret
+
+LOCAL_LABEL(DoThreadSetup):
+
+ call C_FUNC(CreateThreadBlockThrow)
+ jmp LOCAL_LABEL(HaveThread)
+
+LOCAL_LABEL(InvalidTransition):
+
+ //No arguments to setup , ReversePInvokeBadTransition will failfast
+ call C_FUNC(ReversePInvokeBadTransition)
+
+LOCAL_LABEL(DoTrapReturningThreadsTHROW):
+
+ // extern "C" VOID STDCALL UMThunkStubRareDisableWorker(Thread *pThread, UMEntryThunk *pUMEntryThunk)
+ mov eax, dword ptr [ebp - UMThunkStub_UMENTRYTHUNK_OFFSET]
+ push eax
+ mov eax, dword ptr [ebp - UMThunkStub_THREAD_OFFSET]
+ push eax
+ call C_FUNC(UMThunkStubRareDisableWorker)
+
+ jmp LOCAL_LABEL(InCooperativeMode)
+
+LOCAL_LABEL(UMThunkStub_CopyStackArgs):
+
+ // eax = m_cbActualArgSize
+ sub esp, eax
+ and esp, -16 // align with 16 byte
+ lea esi, [ebp + 0x08]
+ lea edi, [esp]
+
+LOCAL_LABEL(CopyLoop):
+
+ // eax = number of bytes
+ // esi = src
+ // edi = dest
+ // edx = sratch
+
+ add eax, -4
+ mov edx, dword ptr [esi + eax]
+ mov dword ptr [edi + eax], edx
+ jnz LOCAL_LABEL(CopyLoop)
+
+ jmp LOCAL_LABEL(UMThunkStub_ArgumentsSetup)
+
+#if _DEBUG
+LOCAL_LABEL(WrongAppDomain):
+ int3
+#endif
+
+NESTED_END UMThunkStub, _TEXT
diff --git a/src/vm/i386/unixstubs.cpp b/src/vm/i386/unixstubs.cpp
new file mode 100644
index 0000000000..9fe7127946
--- /dev/null
+++ b/src/vm/i386/unixstubs.cpp
@@ -0,0 +1,106 @@
+// Licensed to the .NET Foundation under one or more 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"
+
+extern "C"
+{
+ void ThrowControlForThread()
+ {
+ 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");
+ }
+
+ void ProfileLeaveNaked(FunctionIDOrClientID functionIDOrClientID)
+ {
+ PORTABILITY_ASSERT("Implement for PAL");
+ }
+
+ void ProfileTailcallNaked(FunctionIDOrClientID functionIDOrClientID)
+ {
+ PORTABILITY_ASSERT("Implement for PAL");
+ }
+
+ void STDCALL JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle)
+ {
+ }
+
+ _Unwind_Reason_Code
+ UnhandledExceptionHandlerUnix(
+ IN int version,
+ IN _Unwind_Action action,
+ IN uint64_t exceptionClass,
+ IN struct _Unwind_Exception *exception,
+ IN struct _Unwind_Context *context
+ )
+ {
+ PORTABILITY_ASSERT("UnhandledExceptionHandlerUnix");
+ return _URC_FATAL_PHASE1_ERROR;
+ }
+
+ BOOL CallRtlUnwind()
+ {
+ PORTABILITY_ASSERT("CallRtlUnwind");
+ return FALSE;
+ }
+};
+
+VOID __cdecl PopSEHRecords(LPVOID pTargetSP)
+{
+ PORTABILITY_ASSERT("Implement for PAL");
+}
+
+EXTERN_C VOID SinglecastDelegateInvokeStub()
+{
+ PORTABILITY_ASSERT("SinglecastDelegateInvokeStub");
+}
+
+EXTERN_C VOID ResolveWorkerChainLookupAsmStub()
+{
+ PORTABILITY_ASSERT("ResolveWorkerChainLookupAsmStub");
+}
+
+EXTERN_C VOID BackPatchWorkerAsmStub()
+{
+ PORTABILITY_ASSERT("BackPatchWorkerAsmStub");
+}
+
+EXTERN_C VOID JIT_TailCall()
+{
+ PORTABILITY_ASSERT("JIT_TailCall");
+}
+
+EXTERN_C VOID JIT_TailCallReturnFromVSD()
+{
+ PORTABILITY_ASSERT("JIT_TailCallReturnFromVSD");
+}
+
+EXTERN_C VOID JIT_TailCallVSDLeave()
+{
+ PORTABILITY_ASSERT("JIT_TailCallVSDLeave");
+}
+
+EXTERN_C VOID JIT_TailCallLeave()
+{
+ PORTABILITY_ASSERT("JIT_TailCallLeave");
+}
diff --git a/src/vm/i386/virtualcallstubcpu.hpp b/src/vm/i386/virtualcallstubcpu.hpp
index 33ce8199b9..8c16854d22 100644
--- a/src/vm/i386/virtualcallstubcpu.hpp
+++ b/src/vm/i386/virtualcallstubcpu.hpp
@@ -695,7 +695,7 @@ BOOL isDelegateCall(BYTE *interiorPtr)
{
LIMITED_METHOD_CONTRACT;
- if (GCHeap::GetGCHeap()->IsHeapPointer((void*)interiorPtr))
+ if (GCHeapUtilities::GetGCHeap()->IsHeapPointer((void*)interiorPtr))
{
Object *delegate = (Object*)(interiorPtr - DelegateObject::GetOffsetOfMethodPtrAux());
VALIDATEOBJECTREF(ObjectToOBJECTREF(delegate));
diff --git a/src/vm/ilmarshalers.cpp b/src/vm/ilmarshalers.cpp
index 114fbe3ccb..c44e561df3 100644
--- a/src/vm/ilmarshalers.cpp
+++ b/src/vm/ilmarshalers.cpp
@@ -4177,7 +4177,7 @@ void ILNativeArrayMarshaler::EmitConvertSpaceNativeToCLR(ILCodeStream* pslILEmit
if (IsByref(m_dwMarshalFlags))
{
//
- // Reset the element count just in case there is a exception thrown in the code emitted by
+ // Reset the element count just in case there is an exception thrown in the code emitted by
// EmitLoadElementCount. The best thing we can do here is to avoid a crash.
//
_ASSERTE(m_dwSavedSizeArg != LOCAL_NUM_UNUSED);
diff --git a/src/vm/ilstubcache.cpp b/src/vm/ilstubcache.cpp
index 4343ba819f..9cd904aec7 100644
--- a/src/vm/ilstubcache.cpp
+++ b/src/vm/ilstubcache.cpp
@@ -128,7 +128,7 @@ MethodDesc* ILStubCache::CreateAndLinkNewILStubMethodDesc(LoaderAllocator* pAllo
pStubLinker->GenerateCode(pbBuffer, cbCode);
pStubLinker->GetLocalSig(pbLocalSig, cbSig);
- pResolver->SetJitFlags(CORJIT_FLG_IL_STUB);
+ pResolver->SetJitFlags(CORJIT_FLAGS(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB));
}
pResolver->SetTokenLookupMap(pStubLinker->GetTokenLookupMap());
diff --git a/src/vm/ilstubresolver.cpp b/src/vm/ilstubresolver.cpp
index 64ff99f67e..5ba6c8a3b0 100644
--- a/src/vm/ilstubresolver.cpp
+++ b/src/vm/ilstubresolver.cpp
@@ -299,7 +299,7 @@ ILStubResolver::ILStubResolver() :
m_pStubMD(dac_cast<PTR_MethodDesc>(nullptr)),
m_pStubTargetMD(dac_cast<PTR_MethodDesc>(nullptr)),
m_type(Unassigned),
- m_dwJitFlags(0)
+ m_jitFlags()
{
LIMITED_METHOD_CONTRACT;
@@ -488,16 +488,16 @@ bool ILStubResolver::IsILGenerated()
return (dac_cast<TADDR>(m_pCompileTimeState) != ILNotYetGenerated);
}
-void ILStubResolver::SetJitFlags(DWORD dwFlags)
+void ILStubResolver::SetJitFlags(CORJIT_FLAGS jitFlags)
{
LIMITED_METHOD_CONTRACT;
- m_dwJitFlags = dwFlags;
+ m_jitFlags = jitFlags;
}
-DWORD ILStubResolver::GetJitFlags()
+CORJIT_FLAGS ILStubResolver::GetJitFlags()
{
LIMITED_METHOD_CONTRACT;
- return m_dwJitFlags;
+ return m_jitFlags;
}
// static
diff --git a/src/vm/ilstubresolver.h b/src/vm/ilstubresolver.h
index b100931107..47181c8a94 100644
--- a/src/vm/ilstubresolver.h
+++ b/src/vm/ilstubresolver.h
@@ -64,8 +64,8 @@ public:
void SetTokenLookupMap(TokenLookupMap* pMap);
- void SetJitFlags(DWORD dwJitFlags);
- DWORD GetJitFlags();
+ void SetJitFlags(CORJIT_FLAGS jitFlags);
+ CORJIT_FLAGS GetJitFlags();
static void StubGenFailed(ILStubResolver* pResolver);
@@ -116,7 +116,7 @@ protected:
PTR_MethodDesc m_pStubMD;
PTR_MethodDesc m_pStubTargetMD;
ILStubType m_type;
- DWORD m_dwJitFlags;
+ CORJIT_FLAGS m_jitFlags;
};
typedef Holder<ILStubResolver*, DoNothing<ILStubResolver*>, ILStubResolver::StubGenFailed, NULL> ILStubGenHolder;
diff --git a/src/vm/interoputil.cpp b/src/vm/interoputil.cpp
index 33f04b9ab8..6a0fbded12 100644
--- a/src/vm/interoputil.cpp
+++ b/src/vm/interoputil.cpp
@@ -2130,7 +2130,7 @@ void MinorCleanupSyncBlockComData(InteropSyncBlockInfo* pInteropInfo)
NOTHROW;
GC_NOTRIGGER;
MODE_ANY;
- PRECONDITION( GCHeap::IsGCInProgress() || ( (g_fEEShutDown & ShutDown_SyncBlock) && g_fProcessDetach ) );
+ PRECONDITION( GCHeapUtilities::IsGCInProgress() || ( (g_fEEShutDown & ShutDown_SyncBlock) && g_fProcessDetach ) );
}
CONTRACTL_END;
diff --git a/src/vm/interpreter.cpp b/src/vm/interpreter.cpp
index a540cff0b0..b74672f4f0 100644
--- a/src/vm/interpreter.cpp
+++ b/src/vm/interpreter.cpp
@@ -14,7 +14,7 @@
#include "openum.h"
#include "fcall.h"
#include "frames.h"
-#include "gc.h"
+#include "gcheaputilities.h"
#include <float.h>
#include "jitinterface.h"
#include "safemath.h"
@@ -903,9 +903,10 @@ CorJitResult Interpreter::GenerateInterpreterStub(CEEInfo* comp,
#endif
{
// But we also have to use r4, because ThumbEmitCondRegJump below requires a low register.
+ sl.ThumbEmitMovConstant(r11, 0);
sl.ThumbEmitMovConstant(r12, UINT_PTR(interpMethInfo));
sl.ThumbEmitLoadRegIndirect(r12, r12, offsetof(InterpreterMethodInfo, m_jittedCode));
- sl.ThumbEmitCmpImm(r12, 0); // Set condition codes.
+ sl.ThumbEmitCmpReg(r12, r11); // Set condition codes.
// If r12 is zero, then go on to do the interpretation.
CodeLabel* doInterpret = sl.NewCodeLabel();
sl.ThumbEmitCondFlagJump(doInterpret, thumbCondEq.cond);
@@ -1578,7 +1579,7 @@ CorJitResult Interpreter::GenerateInterpreterStub(CEEInfo* comp,
#else
#error unsupported platform
#endif
- stub = sl.Link();
+ stub = sl.Link(SystemDomain::GetGlobalLoaderAllocator()->GetStubHeap());
*nativeSizeOfCode = static_cast<ULONG>(stub->GetNumCodeBytes());
// TODO: manage reference count of interpreter stubs. Look for examples...
@@ -1736,13 +1737,13 @@ void Interpreter::JitMethodIfAppropriate(InterpreterMethodInfo* interpMethInfo,
fprintf(GetLogFile(), "JITting method %s:%s.\n", md->m_pszDebugClassName, md->m_pszDebugMethodName);
}
#endif // _DEBUG
- DWORD dwFlags = CORJIT_FLG_MAKEFINALCODE;
+ CORJIT_FLAGS jitFlags(CORJIT_FLAGS::CORJIT_FLAG_MAKEFINALCODE);
NewHolder<COR_ILMETHOD_DECODER> pDecoder(NULL);
// Dynamic methods (e.g., IL stubs) do not have an IL decoder but may
// require additional flags. Ordinary methods require the opposite.
if (md->IsDynamicMethod())
{
- dwFlags |= md->AsDynamicMethodDesc()->GetILStubResolver()->GetJitFlags();
+ jitFlags.Add(md->AsDynamicMethodDesc()->GetILStubResolver()->GetJitFlags());
}
else
{
@@ -1751,7 +1752,7 @@ void Interpreter::JitMethodIfAppropriate(InterpreterMethodInfo* interpMethInfo,
md->GetMDImport(),
&status);
}
- PCODE res = md->MakeJitWorker(pDecoder, dwFlags, 0);
+ PCODE res = md->MakeJitWorker(pDecoder, jitFlags);
interpMethInfo->m_jittedCode = res;
}
}
@@ -8607,6 +8608,8 @@ void Interpreter::BoxStructRefAt(unsigned ind, CORINFO_CLASS_HANDLE valCls)
if (th.IsTypeDesc())
COMPlusThrow(kInvalidOperationException,W("InvalidOperation_TypeCannotBeBoxed"));
+ MethodTable* pMT = th.AsMethodTable();
+
{
Object* res = OBJECTREFToObject(pMT->Box(valPtr));
@@ -9578,7 +9581,9 @@ void Interpreter::DoCallWork(bool virtualCall, void* thisArg, CORINFO_RESOLVED_T
// This is the argument slot that will be used to hold the return value.
ARG_SLOT retVal = 0;
+#ifndef _ARM_
_ASSERTE (NUMBER_RETURNVALUE_SLOTS == 1);
+#endif
// If the return type is a structure, then these will be initialized.
CORINFO_CLASS_HANDLE retTypeClsHnd = NULL;
@@ -10316,15 +10321,23 @@ void Interpreter::CallI()
}
else
{
- pMD = g_pPrepareConstrainedRegionsMethod; // A random static method.
+ pMD = g_pExecuteBackoutCodeHelperMethod; // A random static method.
}
MethodDescCallSite mdcs(pMD, &mSig, ftnPtr);
+#if 0
// If the current method being interpreted is an IL stub, we're calling native code, so
// change the GC mode. (We'll only do this at the call if the calling convention turns out
// to be a managed calling convention.)
MethodDesc* pStubContextMD = reinterpret_cast<MethodDesc*>(m_stubContext);
bool transitionToPreemptive = (pStubContextMD != NULL && !pStubContextMD->IsIL());
mdcs.CallTargetWorker(args, &retVal, sizeof(retVal), transitionToPreemptive);
+#else
+ // TODO The code above triggers assertion at threads.cpp:6861:
+ // _ASSERTE(thread->PreemptiveGCDisabled()); // Should have been in managed code
+ // The workaround will likely break more things than what it is fixing:
+ // just do not make transition to preemptive GC for now.
+ mdcs.CallTargetWorker(args, &retVal, sizeof(retVal));
+#endif
}
// retVal is now vulnerable.
GCX_FORBID();
diff --git a/src/vm/interpreter.h b/src/vm/interpreter.h
index 92835be92e..1151b36913 100644
--- a/src/vm/interpreter.h
+++ b/src/vm/interpreter.h
@@ -718,7 +718,7 @@ class InterpreterCEEInfo: public CEEInfo
{
CEEJitInfo m_jitInfo;
public:
- InterpreterCEEInfo(CORINFO_METHOD_HANDLE meth): CEEInfo((MethodDesc*)meth), m_jitInfo((MethodDesc*)meth, NULL, NULL, CorJitFlag(0)) { m_pOverride = this; }
+ InterpreterCEEInfo(CORINFO_METHOD_HANDLE meth): CEEInfo((MethodDesc*)meth), m_jitInfo((MethodDesc*)meth, NULL, NULL, CORJIT_FLAGS::CORJIT_FLAG_SPEED_OPT) { m_pOverride = this; }
// Certain methods are unimplemented by CEEInfo (they hit an assert). They are implemented by CEEJitInfo, yet
// don't seem to require any of the CEEJitInfo state we can't provide. For those case, delegate to the "partial"
diff --git a/src/vm/jithelpers.cpp b/src/vm/jithelpers.cpp
index 1626810758..7b9389d5b6 100644
--- a/src/vm/jithelpers.cpp
+++ b/src/vm/jithelpers.cpp
@@ -23,7 +23,7 @@
#include "security.h"
#include "securitymeta.h"
#include "dllimport.h"
-#include "gc.h"
+#include "gcheaputilities.h"
#include "comdelegate.h"
#include "jitperf.h" // to track jit perf
#include "corprof.h"
@@ -130,7 +130,7 @@ inline UINT64 ShiftToHi32Bits(UINT32 x)
return ret.QuadPart;
}
-#if !defined(_TARGET_X86_)
+#if !defined(_TARGET_X86_) || defined(FEATURE_PAL)
/*********************************************************************/
HCIMPL2_VV(INT64, JIT_LMul, INT64 val1, INT64 val2)
{
@@ -145,7 +145,7 @@ HCIMPL2_VV(INT64, JIT_LMul, INT64 val1, INT64 val2)
return (val1 * val2);
}
HCIMPLEND
-#endif // !defined(_TARGET_X86_)
+#endif // !_TARGET_X86_ || FEATURE_PAL
/*********************************************************************/
HCIMPL2_VV(INT64, JIT_LMulOvf, INT64 val1, INT64 val2)
@@ -513,7 +513,7 @@ HCIMPL1_V(double, JIT_ULng2Dbl, UINT64 val)
HCIMPLEND
/*********************************************************************/
-// needed for ARM
+// needed for ARM and RyuJIT-x86
HCIMPL1_V(double, JIT_Lng2Dbl, INT64 val)
{
FCALL_CONTRACT;
@@ -619,7 +619,7 @@ HCIMPL1_V(UINT64, JIT_Dbl2ULng, double val)
else {
// subtract 0x8000000000000000, do the convert then add it back again
ret = FastDbl2Lng(val - two63) + I64(0x8000000000000000);
-}
+ }
return ret;
}
HCIMPLEND
@@ -654,7 +654,7 @@ HCIMPL1_V(UINT64, JIT_Dbl2ULngOvf, double val)
HCIMPLEND
-#if !defined(_TARGET_X86_)
+#if !defined(_TARGET_X86_) || defined(FEATURE_PAL)
HCIMPL1_V(INT64, JIT_Dbl2Lng, double val)
{
@@ -755,7 +755,7 @@ HCIMPL2_VV(double, JIT_DblRem, double dividend, double divisor)
}
HCIMPLEND
-#endif // !defined(_TARGET_X86_)
+#endif // !_TARGET_X86_ || FEATURE_PAL
#include <optdefault.h>
@@ -2858,7 +2858,7 @@ HCIMPL1(Object*, JIT_NewS_MP_FastPortable, CORINFO_CLASS_HANDLE typeHnd_)
do
{
- _ASSERTE(GCHeap::UseAllocationContexts());
+ _ASSERTE(GCHeapUtilities::UseAllocationContexts());
// 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
@@ -2872,7 +2872,7 @@ HCIMPL1(Object*, JIT_NewS_MP_FastPortable, CORINFO_CLASS_HANDLE typeHnd_)
SIZE_T size = methodTable->GetBaseSize();
_ASSERTE(size % DATA_ALIGNMENT == 0);
- alloc_context *allocContext = thread->GetAllocContext();
+ gc_alloc_context *allocContext = thread->GetAllocContext();
BYTE *allocPtr = allocContext->alloc_ptr;
_ASSERTE(allocPtr <= allocContext->alloc_limit);
if (size > static_cast<SIZE_T>(allocContext->alloc_limit - allocPtr))
@@ -2997,7 +2997,7 @@ HCIMPL1(StringObject*, AllocateString_MP_FastPortable, DWORD stringLength)
do
{
- _ASSERTE(GCHeap::UseAllocationContexts());
+ _ASSERTE(GCHeapUtilities::UseAllocationContexts());
// 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.
@@ -3021,7 +3021,7 @@ HCIMPL1(StringObject*, AllocateString_MP_FastPortable, DWORD stringLength)
_ASSERTE(alignedTotalSize >= totalSize);
totalSize = alignedTotalSize;
- alloc_context *allocContext = thread->GetAllocContext();
+ gc_alloc_context *allocContext = thread->GetAllocContext();
BYTE *allocPtr = allocContext->alloc_ptr;
_ASSERTE(allocPtr <= allocContext->alloc_limit);
if (totalSize > static_cast<SIZE_T>(allocContext->alloc_limit - allocPtr))
@@ -3161,7 +3161,7 @@ HCIMPL2(Object*, JIT_NewArr1VC_MP_FastPortable, CORINFO_CLASS_HANDLE arrayTypeHn
do
{
- _ASSERTE(GCHeap::UseAllocationContexts());
+ _ASSERTE(GCHeapUtilities::UseAllocationContexts());
// 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
@@ -3198,7 +3198,7 @@ HCIMPL2(Object*, JIT_NewArr1VC_MP_FastPortable, CORINFO_CLASS_HANDLE arrayTypeHn
_ASSERTE(alignedTotalSize >= totalSize);
totalSize = alignedTotalSize;
- alloc_context *allocContext = thread->GetAllocContext();
+ gc_alloc_context *allocContext = thread->GetAllocContext();
BYTE *allocPtr = allocContext->alloc_ptr;
_ASSERTE(allocPtr <= allocContext->alloc_limit);
if (totalSize > static_cast<SIZE_T>(allocContext->alloc_limit - allocPtr))
@@ -3238,7 +3238,7 @@ HCIMPL2(Object*, JIT_NewArr1OBJ_MP_FastPortable, CORINFO_CLASS_HANDLE arrayTypeH
do
{
- _ASSERTE(GCHeap::UseAllocationContexts());
+ _ASSERTE(GCHeapUtilities::UseAllocationContexts());
// 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.
@@ -3266,7 +3266,7 @@ HCIMPL2(Object*, JIT_NewArr1OBJ_MP_FastPortable, CORINFO_CLASS_HANDLE arrayTypeH
_ASSERTE(ALIGN_UP(totalSize, DATA_ALIGNMENT) == totalSize);
- alloc_context *allocContext = thread->GetAllocContext();
+ gc_alloc_context *allocContext = thread->GetAllocContext();
BYTE *allocPtr = allocContext->alloc_ptr;
_ASSERTE(allocPtr <= allocContext->alloc_limit);
if (totalSize > static_cast<SIZE_T>(allocContext->alloc_limit - allocPtr))
@@ -6431,7 +6431,7 @@ HCIMPL0(VOID, JIT_StressGC)
bool fSkipGC = false;
if (!fSkipGC)
- GCHeap::GetGCHeap()->GarbageCollect();
+ GCHeapUtilities::GetGCHeap()->GarbageCollect();
// <TODO>@TODO: the following ifdef is in error, but if corrected the
// compiler complains about the *__ms->pRetAddr() saying machine state
diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp
index 76d4568adb..2f9db3d596 100644
--- a/src/vm/jitinterface.cpp
+++ b/src/vm/jitinterface.cpp
@@ -27,7 +27,7 @@
#include "security.h"
#include "securitymeta.h"
#include "dllimport.h"
-#include "gc.h"
+#include "gcheaputilities.h"
#include "comdelegate.h"
#include "jitperf.h" // to track jit perf
#include "corprof.h"
@@ -2303,11 +2303,21 @@ unsigned CEEInfo::getClassGClayout (CORINFO_CLASS_HANDLE clsHnd, BYTE* gcPtrs)
MethodTable* pMT = VMClsHnd.GetMethodTable();
- if (pMT == g_TypedReferenceMT)
+ if (pMT->IsByRefLike())
{
- gcPtrs[0] = TYPE_GC_BYREF;
- gcPtrs[1] = TYPE_GC_NONE;
- result = 1;
+ if (pMT == g_TypedReferenceMT)
+ {
+ gcPtrs[0] = TYPE_GC_BYREF;
+ gcPtrs[1] = TYPE_GC_NONE;
+ result = 1;
+ }
+ else
+ {
+ // TODO-SPAN: Proper GC reporting
+ memset(gcPtrs, TYPE_GC_NONE,
+ (VMClsHnd.GetSize() + sizeof(void*) -1)/ sizeof(void*));
+ result = 0;
+ }
}
else if (VMClsHnd.IsNativeValueType())
{
@@ -3988,7 +3998,7 @@ DWORD CEEInfo::getClassAttribsInternal (CORINFO_CLASS_HANDLE clsHnd)
if (pMT->IsMarshaledByRef())
ret |= CORINFO_FLG_MARSHAL_BYREF;
- if (pMT->ContainsPointers())
+ if (pMT->ContainsPointers() || pMT == g_TypedReferenceMT)
ret |= CORINFO_FLG_CONTAINS_GC_PTR;
if (pMT->IsDelegate())
@@ -5027,6 +5037,7 @@ void CEEInfo::getCallInfo(
}
+#ifdef FEATURE_CER
if (pMD == g_pPrepareConstrainedRegionsMethod && !isVerifyOnly())
{
MethodDesc * methodFromContext = GetMethodFromContext(pResolvedToken->tokenContext);
@@ -5048,6 +5059,7 @@ void CEEInfo::getCallInfo(
}
}
}
+#endif // FEATURE_CER
TypeHandle exactType = TypeHandle(pResolvedToken->hClass);
@@ -5093,6 +5105,19 @@ void CEEInfo::getCallInfo(
// shared generic code - it may just resolve it to a candidate suitable for
// JIT compilation, and require a runtime lookup for the actual code pointer
// to call.
+ if (constrainedType.IsEnum())
+ {
+ // Optimize constrained calls to enum's GetHashCode method. TryResolveConstraintMethodApprox would return
+ // null since the virtual method resolves to System.Enum's implementation and that's a reference type.
+ // We can't do this for any other method since ToString and Equals have different semantics for enums
+ // and their underlying type.
+ if (pMD->GetSlot() == MscorlibBinder::GetMethod(METHOD__OBJECT__GET_HASH_CODE)->GetSlot())
+ {
+ // Pretend this was a "constrained. UnderlyingType" instruction prefix
+ constrainedType = TypeHandle(MscorlibBinder::GetElementType(constrainedType.GetVerifierCorElementType()));
+ }
+ }
+
MethodDesc * directMethod = constrainedType.GetMethodTable()->TryResolveConstraintMethodApprox(
exactType,
pMD,
@@ -6767,6 +6792,28 @@ void getMethodInfoILMethodHeaderHelper(
(CorInfoOptions)((header->GetFlags() & CorILMethod_InitLocals) ? CORINFO_OPT_INIT_LOCALS : 0) ;
}
+mdToken FindGenericMethodArgTypeSpec(IMDInternalImport* pInternalImport)
+{
+ STANDARD_VM_CONTRACT;
+
+ HENUMInternalHolder hEnumTypeSpecs(pInternalImport);
+ mdToken token;
+
+ static const BYTE signature[] = { ELEMENT_TYPE_MVAR, 0 };
+
+ hEnumTypeSpecs.EnumAllInit(mdtTypeSpec);
+ while (hEnumTypeSpecs.EnumNext(&token))
+ {
+ PCCOR_SIGNATURE pSig;
+ ULONG cbSig;
+ IfFailThrow(pInternalImport->GetTypeSpecFromToken(token, &pSig, &cbSig));
+ if (cbSig == sizeof(signature) && memcmp(pSig, signature, cbSig) == 0)
+ return token;
+ }
+
+ COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
+}
+
/*********************************************************************
IL is the most efficient and portable way to implement certain low level methods
@@ -6878,10 +6925,165 @@ 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
+ static const BYTE ilcode[] = { CEE_LDARG_0, CEE_LDARG_1, CEE_PREFIX1, (CEE_CLT & 0xFF), 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__JIT_HELPERS__GET_ARRAY_DATA)->GetMemberDef())
+ {
+ mdToken tokArrayPinningHelper = MscorlibBinder::GetField(FIELD__ARRAY_PINNING_HELPER__M_ARRAY_DATA)->GetMemberDef();
+
+ static BYTE ilcode[] = { CEE_LDARG_0,
+ CEE_LDFLDA,0,0,0,0,
+ CEE_RET };
+
+ ilcode[2] = (BYTE)(tokArrayPinningHelper);
+ ilcode[3] = (BYTE)(tokArrayPinningHelper >> 8);
+ ilcode[4] = (BYTE)(tokArrayPinningHelper >> 16);
+ ilcode[5] = (BYTE)(tokArrayPinningHelper >> 24);
+
+ methInfo->ILCode = const_cast<BYTE*>(ilcode);
+ methInfo->ILCodeSize = sizeof(ilcode);
+ methInfo->maxStack = 1;
+ methInfo->EHcount = 0;
+ 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)
+{
+ STANDARD_VM_CONTRACT;
+
+ // Precondition: ftn is a method in mscorlib
+ _ASSERTE(ftn->GetModule()->IsSystem());
+
+ mdMethodDef tk = ftn->GetMemberDef();
+
+ if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__AS_POINTER)->GetMemberDef())
+ {
+ // Return the argument that was passed in.
+ static const BYTE ilcode[] = { CEE_LDARG_0, CEE_CONV_U, CEE_RET };
+ methInfo->ILCode = const_cast<BYTE*>(ilcode);
+ methInfo->ILCodeSize = sizeof(ilcode);
+ methInfo->maxStack = 1;
+ methInfo->EHcount = 0;
+ methInfo->options = (CorInfoOptions)0;
+ return true;
+ }
+ if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__SIZEOF)->GetMemberDef())
+ {
+ _ASSERTE(ftn->HasMethodInstantiation());
+ Instantiation inst = ftn->GetMethodInstantiation();
+
+ _ASSERTE(ftn->GetNumGenericMethodArgs() == 1);
+ mdToken tokGenericArg = FindGenericMethodArgTypeSpec(MscorlibBinder::GetModule()->GetMDImport());
+
+ static BYTE ilcode[] = { CEE_PREFIX1, (CEE_SIZEOF & 0xFF), 0,0,0,0, CEE_RET };
+
+ ilcode[2] = (BYTE)(tokGenericArg);
+ ilcode[3] = (BYTE)(tokGenericArg >> 8);
+ ilcode[4] = (BYTE)(tokGenericArg >> 16);
+ ilcode[5] = (BYTE)(tokGenericArg >> 24);
+
+ methInfo->ILCode = const_cast<BYTE*>(ilcode);
+ methInfo->ILCodeSize = sizeof(ilcode);
+ methInfo->maxStack = 1;
+ methInfo->EHcount = 0;
+ methInfo->options = (CorInfoOptions)0;
+ return true;
+ }
+ else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_AS)->GetMemberDef())
+ {
+ // Return the argument that was passed in.
+ static const BYTE ilcode[] = { CEE_LDARG_0, CEE_RET };
+ methInfo->ILCode = const_cast<BYTE*>(ilcode);
+ methInfo->ILCodeSize = sizeof(ilcode);
+ methInfo->maxStack = 1;
+ methInfo->EHcount = 0;
+ methInfo->options = (CorInfoOptions)0;
+ return true;
+ }
+ else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_ADD)->GetMemberDef())
+ {
+ mdToken tokGenericArg = FindGenericMethodArgTypeSpec(MscorlibBinder::GetModule()->GetMDImport());
+
+ static BYTE ilcode[] = { CEE_LDARG_1,
+ CEE_PREFIX1, (CEE_SIZEOF & 0xFF), 0,0,0,0,
+ CEE_CONV_I,
+ CEE_MUL,
+ CEE_LDARG_0,
+ CEE_ADD,
+ CEE_RET };
+
+ ilcode[3] = (BYTE)(tokGenericArg);
+ ilcode[4] = (BYTE)(tokGenericArg >> 8);
+ ilcode[5] = (BYTE)(tokGenericArg >> 16);
+ ilcode[6] = (BYTE)(tokGenericArg >> 24);
+
+ 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
+ static const BYTE ilcode[] = { CEE_LDARG_0, CEE_LDARG_1, CEE_PREFIX1, (CEE_CEQ & 0xFF), 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)
{
@@ -7062,6 +7264,12 @@ 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);
@@ -7394,11 +7602,15 @@ CorInfoInline CEEInfo::canInline (CORINFO_METHOD_HANDLE hCaller,
// If the callee wants debuggable code, don't allow it to be inlined
- if (GetDebuggerCompileFlags(pCallee->GetModule(), 0) & CORJIT_FLG_DEBUG_CODE)
{
- result = INLINE_NEVER;
- szFailReason = "Inlinee is debuggable";
- goto exit;
+ // Combining the next two lines, and eliminating jitDebuggerFlags, leads to bad codegen in x86 Release builds using Visual C++ 19.00.24215.1.
+ CORJIT_FLAGS jitDebuggerFlags = GetDebuggerCompileFlags(pCallee->GetModule(), CORJIT_FLAGS());
+ if (jitDebuggerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE))
+ {
+ result = INLINE_NEVER;
+ szFailReason = "Inlinee is debuggable";
+ goto exit;
+ }
}
#endif
@@ -8167,6 +8379,7 @@ bool CEEInfo::canTailCall (CORINFO_METHOD_HANDLE hCaller,
}
}
+#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))
@@ -8175,6 +8388,7 @@ bool CEEInfo::canTailCall (CORINFO_METHOD_HANDLE hCaller,
szFailReason = "Caller is a CER root";
goto exit;
}
+#endif // FEATURE_CER
result = true;
@@ -8627,6 +8841,9 @@ void CEEInfo::getFunctionEntryPoint(CORINFO_METHOD_HANDLE ftnHnd,
JIT_TO_EE_TRANSITION();
MethodDesc * ftn = GetMethod(ftnHnd);
+#if defined(FEATURE_GDBJIT)
+ MethodDesc * orig_ftn = ftn;
+#endif
// Resolve methodImpl.
ftn = ftn->GetMethodTable()->MapMethodDeclToMethodImpl(ftn);
@@ -8645,6 +8862,12 @@ void CEEInfo::getFunctionEntryPoint(CORINFO_METHOD_HANDLE ftnHnd,
accessType = IAT_PVALUE;
}
+
+#if defined(FEATURE_GDBJIT)
+ CalledMethod * pCM = new CalledMethod(orig_ftn, ret, m_pCalledMethods);
+ m_pCalledMethods = pCM;
+#endif
+
EE_TO_JIT_TRANSITION();
_ASSERTE(ret != NULL);
@@ -9103,7 +9326,7 @@ CorInfoTypeWithMod CEEInfo::getArgType (
CorElementType normType = typeHnd.GetInternalCorElementType();
// if we are looking up a value class, don't morph it to a refernece type
- // (This can only happen in illegal IL
+ // (This can only happen in illegal IL)
if (!CorTypeInfo::IsObjRef(normType) || type != ELEMENT_TYPE_VALUETYPE)
{
type = normType;
@@ -11677,8 +11900,7 @@ static CorJitResult CompileMethodWithEtwWrapper(EEJitManager *jitMgr,
CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr,
CEEInfo *comp,
struct CORINFO_METHOD_INFO *info,
- unsigned flags,
- unsigned flags2,
+ CORJIT_FLAGS jitFlags,
BYTE **nativeEntry,
ULONG *nativeSizeOfCode)
{
@@ -11689,13 +11911,9 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr,
CorJitResult ret = CORJIT_SKIPPED; // Note that CORJIT_SKIPPED is an error exit status code
- CORJIT_FLAGS jitFlags = { 0 };
- jitFlags.corJitFlags = flags;
- jitFlags.corJitFlags2 = flags2;
-
#if !defined(FEATURE_CORECLR)
// Ask the JIT to generate desktop-quirk-compatible code.
- jitFlags.corJitFlags2 |= CORJIT_FLG2_DESKTOP_QUIRKS;
+ jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_DESKTOP_QUIRKS);
#endif
comp->setJitFlags(jitFlags);
@@ -11711,7 +11929,7 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr,
#if defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
ret = getJit()->compileMethod( comp,
info,
- CORJIT_FLG_CALL_GETJITFLAGS,
+ CORJIT_FLAGS::CORJIT_FLAG_CALL_GETJITFLAGS,
nativeEntry,
nativeSizeOfCode);
@@ -11720,18 +11938,18 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr,
#if defined(ALLOW_SXS_JIT) && !defined(CROSSGEN_COMPILE)
if (FAILED(ret) && jitMgr->m_alternateJit
#ifdef FEATURE_STACK_SAMPLING
- && (!samplingEnabled || (jitFlags.corJitFlags2 & CORJIT_FLG2_SAMPLING_JIT_BACKGROUND))
+ && (!samplingEnabled || (jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_SAMPLING_JIT_BACKGROUND)))
#endif
)
{
ret = jitMgr->m_alternateJit->compileMethod( comp,
info,
- CORJIT_FLG_CALL_GETJITFLAGS,
+ CORJIT_FLAGS::CORJIT_FLAG_CALL_GETJITFLAGS,
nativeEntry,
nativeSizeOfCode );
#ifdef FEATURE_STACK_SAMPLING
- if (jitFlags.corJitFlags2 & CORJIT_FLG2_SAMPLING_JIT_BACKGROUND)
+ if (jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_SAMPLING_JIT_BACKGROUND))
{
// Don't bother with failures if we couldn't collect a trace.
ret = CORJIT_OK;
@@ -11758,7 +11976,7 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr,
{
// If we're doing an "import_only" compilation, it's for verification, so don't interpret.
// (We assume that importation is completely architecture-independent, or at least nearly so.)
- if (FAILED(ret) && (jitFlags.corJitFlags & (CORJIT_FLG_IMPORT_ONLY | CORJIT_FLG_MAKEFINALCODE)) == 0)
+ if (FAILED(ret) && !jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY) && !jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_MAKEFINALCODE))
{
ret = Interpreter::GenerateInterpreterStub(comp, info, nativeEntry, nativeSizeOfCode);
}
@@ -11769,7 +11987,7 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr,
ret = CompileMethodWithEtwWrapper(jitMgr,
comp,
info,
- CORJIT_FLG_CALL_GETJITFLAGS,
+ CORJIT_FLAGS::CORJIT_FLAG_CALL_GETJITFLAGS,
nativeEntry,
nativeSizeOfCode);
}
@@ -11778,7 +11996,7 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr,
{
// If we're doing an "import_only" compilation, it's for verification, so don't interpret.
// (We assume that importation is completely architecture-independent, or at least nearly so.)
- if (FAILED(ret) && (jitFlags.corJitFlags & (CORJIT_FLG_IMPORT_ONLY | CORJIT_FLG_MAKEFINALCODE)) == 0)
+ if (FAILED(ret) && !jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY) && !jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_MAKEFINALCODE))
{
ret = Interpreter::GenerateInterpreterStub(comp, info, nativeEntry, nativeSizeOfCode);
}
@@ -11788,7 +12006,7 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr,
{
ret = jitMgr->m_jit->compileMethod( comp,
info,
- CORJIT_FLG_CALL_GETJITFLAGS,
+ CORJIT_FLAGS::CORJIT_FLAG_CALL_GETJITFLAGS,
nativeEntry,
nativeSizeOfCode);
}
@@ -11800,7 +12018,7 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr,
// If the JIT fails we keep the IL around and will
// try reJIT the same IL. VSW 525059
//
- if (SUCCEEDED(ret) && !(jitFlags.corJitFlags & CORJIT_FLG_IMPORT_ONLY) && !((CEEJitInfo*)comp)->JitAgain())
+ if (SUCCEEDED(ret) && !jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY) && !((CEEJitInfo*)comp)->JitAgain())
{
((CEEJitInfo*)comp)->CompressDebugInfo();
@@ -11815,6 +12033,14 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr,
#endif // defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
+#if defined(FEATURE_GDBJIT)
+ if (SUCCEEDED(ret) && *nativeEntry != NULL)
+ {
+ CodeHeader* pCH = ((CodeHeader*)((PCODE)*nativeEntry & ~1)) - 1;
+ pCH->SetCalledMethods((PTR_VOID)comp->GetCalledMethods());
+ }
+#endif
+
END_SO_TOLERANT_CODE;
return ret;
@@ -11825,8 +12051,7 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr,
CorJitResult invokeCompileMethod(EEJitManager *jitMgr,
CEEInfo *comp,
struct CORINFO_METHOD_INFO *info,
- unsigned flags,
- unsigned flags2,
+ CORJIT_FLAGS jitFlags,
BYTE **nativeEntry,
ULONG *nativeSizeOfCode)
{
@@ -11841,7 +12066,7 @@ CorJitResult invokeCompileMethod(EEJitManager *jitMgr,
GCX_PREEMP();
- CorJitResult ret = invokeCompileMethodHelper(jitMgr, comp, info, flags, flags2, nativeEntry, nativeSizeOfCode);
+ CorJitResult ret = invokeCompileMethodHelper(jitMgr, comp, info, jitFlags, nativeEntry, nativeSizeOfCode);
//
// Verify that we are still in preemptive mode when we return
@@ -11853,9 +12078,9 @@ CorJitResult invokeCompileMethod(EEJitManager *jitMgr,
return ret;
}
-CorJitFlag GetCompileFlagsIfGenericInstantiation(
+CORJIT_FLAGS GetCompileFlagsIfGenericInstantiation(
CORINFO_METHOD_HANDLE method,
- CorJitFlag compileFlags,
+ CORJIT_FLAGS compileFlags,
ICorJitInfo * pCorJitInfo,
BOOL * raiseVerificationException,
BOOL * unverifiableGenericCode);
@@ -11863,8 +12088,7 @@ CorJitFlag GetCompileFlagsIfGenericInstantiation(
CorJitResult CallCompileMethodWithSEHWrapper(EEJitManager *jitMgr,
CEEInfo *comp,
struct CORINFO_METHOD_INFO *info,
- unsigned flags,
- unsigned flags2,
+ CORJIT_FLAGS flags,
BYTE **nativeEntry,
ULONG *nativeSizeOfCode,
MethodDesc *ftn)
@@ -11880,8 +12104,7 @@ CorJitResult CallCompileMethodWithSEHWrapper(EEJitManager *jitMgr,
EEJitManager *jitMgr;
CEEInfo *comp;
struct CORINFO_METHOD_INFO *info;
- unsigned flags;
- unsigned flags2;
+ CORJIT_FLAGS flags;
BYTE **nativeEntry;
ULONG *nativeSizeOfCode;
MethodDesc *ftn;
@@ -11891,7 +12114,6 @@ CorJitResult CallCompileMethodWithSEHWrapper(EEJitManager *jitMgr,
param.comp = comp;
param.info = info;
param.flags = flags;
- param.flags2 = flags2;
param.nativeEntry = nativeEntry;
param.nativeSizeOfCode = nativeSizeOfCode;
param.ftn = ftn;
@@ -11907,16 +12129,16 @@ CorJitResult CallCompileMethodWithSEHWrapper(EEJitManager *jitMgr,
pParam->comp,
pParam->info,
pParam->flags,
- pParam->flags2,
pParam->nativeEntry,
pParam->nativeSizeOfCode);
}
PAL_FINALLY
{
#if defined(DEBUGGING_SUPPORTED) && !defined(CROSSGEN_COMPILE)
- if (!(flags & (CORJIT_FLG_IMPORT_ONLY | CORJIT_FLG_MCJIT_BACKGROUND))
+ if (!flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY) &&
+ !flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_MCJIT_BACKGROUND)
#ifdef FEATURE_STACK_SAMPLING
- && !(flags2 & CORJIT_FLG2_SAMPLING_JIT_BACKGROUND)
+ && !flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_SAMPLING_JIT_BACKGROUND)
#endif // FEATURE_STACK_SAMPLING
)
{
@@ -11954,7 +12176,7 @@ CorJitResult CallCompileMethodWithSEHWrapper(EEJitManager *jitMgr,
/*********************************************************************/
// Figures out the compile flags that are used by both JIT and NGen
-/* static */ DWORD CEEInfo::GetBaseCompileFlags(MethodDesc * ftn)
+/* static */ CORJIT_FLAGS CEEInfo::GetBaseCompileFlags(MethodDesc * ftn)
{
CONTRACTL {
THROWS;
@@ -11965,16 +12187,16 @@ CorJitResult CallCompileMethodWithSEHWrapper(EEJitManager *jitMgr,
// Figure out the code quality flags
//
- DWORD flags = 0;
+ CORJIT_FLAGS flags;
if (g_pConfig->JitFramed())
- flags |= CORJIT_FLG_FRAMED;
+ flags.Set(CORJIT_FLAGS::CORJIT_FLAG_FRAMED);
if (g_pConfig->JitAlignLoops())
- flags |= CORJIT_FLG_ALIGN_LOOPS;
+ flags.Set(CORJIT_FLAGS::CORJIT_FLAG_ALIGN_LOOPS);
if (ReJitManager::IsReJITEnabled() || g_pConfig->AddRejitNops())
- flags |= CORJIT_FLG_PROF_REJIT_NOPS;
+ flags.Set(CORJIT_FLAGS::CORJIT_FLAG_PROF_REJIT_NOPS);
#ifdef _TARGET_X86_
if (g_pConfig->PInvokeRestoreEsp(ftn->GetModule()->IsPreV4Assembly()))
- flags |= CORJIT_FLG_PINVOKE_RESTORE_ESP;
+ flags.Set(CORJIT_FLAGS::CORJIT_FLAG_PINVOKE_RESTORE_ESP);
#endif // _TARGET_X86_
//See if we should instruct the JIT to emit calls to JIT_PollGC for thread suspension. If we have a
@@ -11982,9 +12204,9 @@ CorJitResult CallCompileMethodWithSEHWrapper(EEJitManager *jitMgr,
#ifdef FEATURE_ENABLE_GCPOLL
EEConfig::GCPollType pollType = g_pConfig->GetGCPollType();
if (EEConfig::GCPOLL_TYPE_POLL == pollType)
- flags |= CORJIT_FLG_GCPOLL_CALLS;
+ flags.Set(CORJIT_FLAGS::CORJIT_FLAG_GCPOLL_CALLS);
else if (EEConfig::GCPOLL_TYPE_INLINE == pollType)
- flags |= CORJIT_FLG_GCPOLL_INLINE;
+ flags.Set(CORJIT_FLAGS::CORJIT_FLAG_GCPOLL_INLINE);
#endif //FEATURE_ENABLE_GCPOLL
// Set flags based on method's ImplFlags.
@@ -11995,13 +12217,13 @@ CorJitResult CallCompileMethodWithSEHWrapper(EEJitManager *jitMgr,
if (IsMiNoOptimization(dwImplFlags))
{
- flags |= CORJIT_FLG_MIN_OPT;
+ flags.Set(CORJIT_FLAGS::CORJIT_FLAG_MIN_OPT);
}
// Always emit frames for methods marked no-inline (see #define ETW_EBP_FRAMED in the JIT)
if (IsMiNoInlining(dwImplFlags))
{
- flags |= CORJIT_FLG_FRAMED;
+ flags.Set(CORJIT_FLAGS::CORJIT_FLAG_FRAMED);
}
}
@@ -12012,7 +12234,7 @@ CorJitResult CallCompileMethodWithSEHWrapper(EEJitManager *jitMgr,
// Figures out (some of) the flags to use to compile the method
// Returns the new set to use
-DWORD GetDebuggerCompileFlags(Module* pModule, DWORD flags)
+CORJIT_FLAGS GetDebuggerCompileFlags(Module* pModule, CORJIT_FLAGS flags)
{
STANDARD_VM_CONTRACT;
@@ -12027,36 +12249,37 @@ DWORD GetDebuggerCompileFlags(Module* pModule, DWORD flags)
#ifdef _DEBUG
if (g_pConfig->GenDebuggableCode())
- flags |= CORJIT_FLG_DEBUG_CODE;
+ flags.Set(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE);
#endif // _DEBUG
#ifdef EnC_SUPPORTED
if (pModule->IsEditAndContinueEnabled())
{
- flags |= CORJIT_FLG_DEBUG_EnC;
+ flags.Set(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_EnC);
}
#endif // EnC_SUPPORTED
// Debug info is always tracked
- flags |= CORJIT_FLG_DEBUG_INFO;
+ flags.Set(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_INFO);
#endif // DEBUGGING_SUPPORTED
if (CORDisableJITOptimizations(pModule->GetDebuggerInfoBits()))
{
- flags |= CORJIT_FLG_DEBUG_CODE;
+ flags.Set(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE);
}
- if (flags & CORJIT_FLG_IMPORT_ONLY)
+ if (flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY))
{
// If we are only verifying the method, dont need any debug info and this
// prevents getVars()/getBoundaries() from being called unnecessarily.
- flags &= ~(CORJIT_FLG_DEBUG_INFO|CORJIT_FLG_DEBUG_CODE);
+ flags.Clear(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_INFO);
+ flags.Clear(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE);
}
return flags;
}
-CorJitFlag GetCompileFlags(MethodDesc * ftn, DWORD flags, CORINFO_METHOD_INFO * methodInfo)
+CORJIT_FLAGS GetCompileFlags(MethodDesc * ftn, CORJIT_FLAGS flags, CORINFO_METHOD_INFO * methodInfo)
{
STANDARD_VM_CONTRACT;
@@ -12065,14 +12288,14 @@ CorJitFlag GetCompileFlags(MethodDesc * ftn, DWORD flags, CORINFO_METHOD_INFO *
//
// Get the compile flags that are shared between JIT and NGen
//
- flags |= CEEInfo::GetBaseCompileFlags(ftn);
+ flags.Add(CEEInfo::GetBaseCompileFlags(ftn));
//
// Get CPU specific flags
//
- if ((flags & CORJIT_FLG_IMPORT_ONLY) == 0)
+ if (!flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY))
{
- flags |= ExecutionManager::GetEEJitManager()->GetCPUCompileFlags();
+ flags.Add(ExecutionManager::GetEEJitManager()->GetCPUCompileFlags());
}
//
@@ -12080,21 +12303,19 @@ CorJitFlag GetCompileFlags(MethodDesc * ftn, DWORD flags, CORINFO_METHOD_INFO *
//
#ifdef DEBUGGING_SUPPORTED
- flags |= GetDebuggerCompileFlags(ftn->GetModule(), flags);
+ flags.Add(GetDebuggerCompileFlags(ftn->GetModule(), flags));
#endif
#ifdef PROFILING_SUPPORTED
- if (CORProfilerTrackEnterLeave()
- && !ftn->IsNoMetadata()
- )
- flags |= CORJIT_FLG_PROF_ENTERLEAVE;
+ if (CORProfilerTrackEnterLeave() && !ftn->IsNoMetadata())
+ flags.Set(CORJIT_FLAGS::CORJIT_FLAG_PROF_ENTERLEAVE);
if (CORProfilerTrackTransitions())
- flags |= CORJIT_FLG_PROF_NO_PINVOKE_INLINE;
+ flags.Set(CORJIT_FLAGS::CORJIT_FLAG_PROF_NO_PINVOKE_INLINE);
#endif // PROFILING_SUPPORTED
// Set optimization flags
- if (0 == (flags & CORJIT_FLG_MIN_OPT))
+ if (!flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_MIN_OPT))
{
unsigned optType = g_pConfig->GenOptimizeType();
_ASSERTE(optType <= OPT_RANDOM);
@@ -12103,18 +12324,16 @@ CorJitFlag GetCompileFlags(MethodDesc * ftn, DWORD flags, CORINFO_METHOD_INFO *
optType = methodInfo->ILCodeSize % OPT_RANDOM;
if (g_pConfig->JitMinOpts())
- flags |= CORJIT_FLG_MIN_OPT;
+ flags.Set(CORJIT_FLAGS::CORJIT_FLAG_MIN_OPT);
- const static unsigned optTypeFlags[] =
+ if (optType == OPT_SIZE)
{
- 0, // OPT_BLENDED
- CORJIT_FLG_SIZE_OPT, // OPT_CODE_SIZE
- CORJIT_FLG_SPEED_OPT // OPT_CODE_SPEED
- };
-
- _ASSERTE(optType < OPT_RANDOM);
- _ASSERTE((sizeof(optTypeFlags)/sizeof(optTypeFlags[0])) == OPT_RANDOM);
- flags |= optTypeFlags[optType];
+ flags.Set(CORJIT_FLAGS::CORJIT_FLAG_SIZE_OPT);
+ }
+ else if (optType == OPT_SPEED)
+ {
+ flags.Set(CORJIT_FLAGS::CORJIT_FLAG_SPEED_OPT);
+ }
}
//
@@ -12123,22 +12342,21 @@ CorJitFlag GetCompileFlags(MethodDesc * ftn, DWORD flags, CORINFO_METHOD_INFO *
#ifdef _DEBUG
if (g_pConfig->IsJitVerificationDisabled())
- flags |= CORJIT_FLG_SKIP_VERIFICATION;
+ flags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION);
#endif // _DEBUG
- if ((flags & CORJIT_FLG_IMPORT_ONLY) == 0 &&
- Security::CanSkipVerification(ftn))
- flags |= CORJIT_FLG_SKIP_VERIFICATION;
+ if (!flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY) && Security::CanSkipVerification(ftn))
+ flags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION);
if (ftn->IsILStub())
{
- flags |= CORJIT_FLG_SKIP_VERIFICATION;
+ flags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION);
// no debug info available for IL stubs
- flags &= ~CORJIT_FLG_DEBUG_INFO;
+ flags.Clear(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_INFO);
}
- return (CorJitFlag)flags;
+ return flags;
}
#if defined(_WIN64)
@@ -12148,12 +12366,12 @@ CorJitFlag GetCompileFlags(MethodDesc * ftn, DWORD flags, CORINFO_METHOD_INFO *
//
//This only works for real methods. If the method isn't IsIL, then IsVerifiable will AV. That would be a
//bad thing (TM).
-BOOL IsTransparentMethodSafeToSkipVerification(CorJitFlag flags, MethodDesc * ftn)
+BOOL IsTransparentMethodSafeToSkipVerification(CORJIT_FLAGS flags, MethodDesc * ftn)
{
STANDARD_VM_CONTRACT;
BOOL ret = FALSE;
- if (!(flags & CORJIT_FLG_IMPORT_ONLY) && !(flags & CORJIT_FLG_SKIP_VERIFICATION)
+ if (!flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY) && !flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION)
&& Security::IsMethodTransparent(ftn) &&
((ftn->IsIL() && !ftn->IsUnboxingStub()) ||
(ftn->IsDynamicMethod() && !ftn->IsILStub())))
@@ -12183,9 +12401,9 @@ BOOL IsTransparentMethodSafeToSkipVerification(CorJitFlag flags, MethodDesc * ft
// failed, then we need to throw an exception whenever we try
// to compile a real instantiation
-CorJitFlag GetCompileFlagsIfGenericInstantiation(
+CORJIT_FLAGS GetCompileFlagsIfGenericInstantiation(
CORINFO_METHOD_HANDLE method,
- CorJitFlag compileFlags,
+ CORJIT_FLAGS compileFlags,
ICorJitInfo * pCorJitInfo,
BOOL * raiseVerificationException,
BOOL * unverifiableGenericCode)
@@ -12196,7 +12414,7 @@ CorJitFlag GetCompileFlagsIfGenericInstantiation(
*unverifiableGenericCode = FALSE;
// If we have already decided to skip verification, keep on going.
- if (compileFlags & CORJIT_FLG_SKIP_VERIFICATION)
+ if (compileFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION))
return compileFlags;
CorInfoInstantiationVerification ver = pCorJitInfo->isInstantiationOfVerifiedGeneric(method);
@@ -12206,13 +12424,14 @@ CorJitFlag GetCompileFlagsIfGenericInstantiation(
case INSTVER_NOT_INSTANTIATION:
// Non-generic, or open instantiation of a generic type/method
if (IsTransparentMethodSafeToSkipVerification(compileFlags, (MethodDesc*)method))
- compileFlags = (CorJitFlag)(compileFlags | CORJIT_FLG_SKIP_VERIFICATION);
+ compileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION);
return compileFlags;
case INSTVER_GENERIC_PASSED_VERIFICATION:
// If the typical instantiation is verifiable, there is no need
// to verify the concrete instantiations
- return (CorJitFlag)(compileFlags | CORJIT_FLG_SKIP_VERIFICATION);
+ compileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION);
+ return compileFlags;
case INSTVER_GENERIC_FAILED_VERIFICATION:
@@ -12238,9 +12457,9 @@ CorJitFlag GetCompileFlagsIfGenericInstantiation(
// hits unverifiable code. Since we've already hit unverifiable code,
// there's no point in starting the JIT, just to have it give up, so we
// give up here.
- _ASSERTE(compileFlags & CORJIT_FLG_PREJIT);
+ _ASSERTE(compileFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_PREJIT));
*raiseVerificationException = TRUE;
- return (CorJitFlag)-1; // This value will not be used
+ return CORJIT_FLAGS(); // This value will not be used
}
#else // FEATURE_PREJIT
// Need to have this case here to keep the MAC build happy
@@ -12259,17 +12478,18 @@ CorJitFlag GetCompileFlagsIfGenericInstantiation(
// branches while compiling the concrete instantiation. Instead,
// just throw a VerificationException right away.
*raiseVerificationException = TRUE;
- return (CorJitFlag)-1; // This value will not be used
+ return CORJIT_FLAGS(); // This value will not be used
}
case CORINFO_VERIFICATION_CAN_SKIP:
{
- return (CorJitFlag)(compileFlags | CORJIT_FLG_SKIP_VERIFICATION);
+ compileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION);
+ return compileFlags;
}
case CORINFO_VERIFICATION_RUNTIME_CHECK:
{
- // Compile the method without CORJIT_FLG_SKIP_VERIFICATION.
+ // Compile the method without CORJIT_FLAG_SKIP_VERIFICATION.
// The compiler will know to add a call to
// CORINFO_HELP_VERIFICATION_RUNTIME_CHECK, and then to skip verification.
return compileFlags;
@@ -12344,8 +12564,8 @@ BOOL g_fAllowRel32 = TRUE;
// Calls to this method that occur to check if inlining can occur on x86,
// are OK since they discard the return value of this method.
-PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader,
- DWORD flags, DWORD flags2, ULONG * pSizeOfCode)
+PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader, CORJIT_FLAGS flags,
+ ULONG * pSizeOfCode)
{
STANDARD_VM_CONTRACT;
@@ -12359,9 +12579,9 @@ PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader,
ftn->GetModule()->GetDomainFile()->IsZapRequired() &&
PartialNGenStressPercentage() == 0 &&
#ifdef FEATURE_STACK_SAMPLING
- !(flags2 & CORJIT_FLG2_SAMPLING_JIT_BACKGROUND) &&
+ !flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_SAMPLING_JIT_BACKGROUND) &&
#endif
- !(flags & CORJIT_FLG_IMPORT_ONLY))
+ !flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY))
{
StackSString ss(SString::Ascii, "ZapRequire: JIT compiler invoked for ");
TypeString::AppendMethodInternal(ss, ftn);
@@ -12398,6 +12618,13 @@ PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader,
EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(COR_E_EXECUTIONENGINE, W("Failed to load JIT compiler"));
#endif // ALLOW_SXS_JIT
}
+
+ // If no compatjit wasn't used, but the user (normally a test case) requires that one is used, then fail.
+ // This is analogous to ZapRequire.
+ if (!jitMgr->m_fLegacyJitUsed && (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_RequireLegacyJit) == 1))
+ {
+ EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(COR_E_EXECUTIONENGINE, W("Failed to use legacy JIT compiler with RequireLegacyJit set"));
+ }
#endif // CROSSGEN_COMPILE
#ifdef _DEBUG
@@ -12444,10 +12671,10 @@ PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader,
getMethodInfoHelper(ftn, ftnHnd, ILHeader, &methodInfo);
// If it's generic then we can only enter through an instantiated md (unless we're just verifying it)
- _ASSERTE((flags & CORJIT_FLG_IMPORT_ONLY) != 0 || !ftn->IsGenericMethodDefinition());
+ _ASSERTE(flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY) || !ftn->IsGenericMethodDefinition());
// If it's an instance method then it must not be entered from a generic class
- _ASSERTE((flags & CORJIT_FLG_IMPORT_ONLY) != 0 || ftn->IsStatic() ||
+ _ASSERTE(flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY) || ftn->IsStatic() ||
ftn->GetNumGenericClassArgs() == 0 || ftn->HasClassInstantiation());
// method attributes and signature are consistant
@@ -12456,7 +12683,7 @@ PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader,
flags = GetCompileFlags(ftn, flags, &methodInfo);
#ifdef _DEBUG
- if (!(flags & CORJIT_FLG_SKIP_VERIFICATION))
+ if (!flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION))
{
SString methodString;
if (LoggingOn(LF_VERIFIER, LL_INFO100))
@@ -12488,10 +12715,10 @@ PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader,
for (;;)
{
#ifndef CROSSGEN_COMPILE
- CEEJitInfo jitInfo(ftn, ILHeader, jitMgr, (flags & CORJIT_FLG_IMPORT_ONLY) != 0);
+ CEEJitInfo jitInfo(ftn, ILHeader, jitMgr, flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY));
#else
// This path should be only ever used for verification in crossgen and so we should not need EEJitManager
- _ASSERTE((flags & CORJIT_FLG_IMPORT_ONLY) != 0);
+ _ASSERTE(flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY));
CEEInfo jitInfo(ftn, true);
EEJitManager *jitMgr = NULL;
#endif
@@ -12550,7 +12777,7 @@ PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader,
flags = GetCompileFlagsIfGenericInstantiation(
ftnHnd,
- (CorJitFlag)flags,
+ flags,
&jitInfo,
&raiseVerificationException,
&unverifiableGenericCode);
@@ -12571,7 +12798,7 @@ PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader,
#ifdef PERF_TRACK_METHOD_JITTIMES
//Because we're not calling QPC enough. I'm not going to track times if we're just importing.
LARGE_INTEGER methodJitTimeStart = {0};
- if (!(flags & CORJIT_FLG_IMPORT_ONLY))
+ if (!flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY))
QueryPerformanceCounter (&methodJitTimeStart);
#endif
@@ -12591,7 +12818,6 @@ PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader,
&jitInfo,
&methodInfo,
flags,
- flags2,
&nativeEntry,
&sizeOfCode,
(MethodDesc*)ftn);
@@ -12622,7 +12848,7 @@ PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader,
#ifdef PERF_TRACK_METHOD_JITTIMES
//store the time in the string buffer. Module name and token are unique enough. Also, do not
//capture importing time, just actual compilation time.
- if (!(flags & CORJIT_FLG_IMPORT_ONLY))
+ if (!flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY))
{
LARGE_INTEGER methodJitTimeStop;
QueryPerformanceCounter(&methodJitTimeStop);
@@ -12653,7 +12879,7 @@ PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* ILHeader,
ThrowExceptionForJit(res);
}
- if (flags & CORJIT_FLG_IMPORT_ONLY)
+ if (flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY))
{
// The method must been processed by the verifier. Note that it may
// either have been marked as verifiable or unverifiable.
@@ -13372,19 +13598,19 @@ BOOL LoadDynamicInfoEntry(Module *currentModule,
break;
case READYTORUN_HELPER_DelayLoad_MethodCall:
- result = (size_t)DelayLoad_MethodCall;
+ result = (size_t)GetEEFuncEntryPoint(DelayLoad_MethodCall);
break;
case READYTORUN_HELPER_DelayLoad_Helper:
- result = (size_t)DelayLoad_Helper;
+ result = (size_t)GetEEFuncEntryPoint(DelayLoad_Helper);
break;
case READYTORUN_HELPER_DelayLoad_Helper_Obj:
- result = (size_t)DelayLoad_Helper_Obj;
+ result = (size_t)GetEEFuncEntryPoint(DelayLoad_Helper_Obj);
break;
case READYTORUN_HELPER_DelayLoad_Helper_ObjObj:
- result = (size_t)DelayLoad_Helper_ObjObj;
+ result = (size_t)GetEEFuncEntryPoint(DelayLoad_Helper_ObjObj);
break;
default:
diff --git a/src/vm/jitinterface.h b/src/vm/jitinterface.h
index 03983f2d3e..ee13b9cec6 100644
--- a/src/vm/jitinterface.h
+++ b/src/vm/jitinterface.h
@@ -28,6 +28,9 @@ class FieldDesc;
enum RuntimeExceptionKind;
class AwareLock;
class PtrArray;
+#if defined(FEATURE_GDBJIT)
+class CalledMethod;
+#endif
#include "genericdict.h"
@@ -51,7 +54,7 @@ void InitJITHelpers1();
void InitJITHelpers2();
PCODE UnsafeJitFunction(MethodDesc* ftn, COR_ILMETHOD_DECODER* header,
- DWORD flags, DWORD flags2, ULONG* sizeOfCode = NULL);
+ CORJIT_FLAGS flags, ULONG* sizeOfCode = NULL);
void getMethodInfoHelper(MethodDesc * ftn,
CORINFO_METHOD_HANDLE ftnHnd,
@@ -644,7 +647,7 @@ public:
);
// Returns that compilation flags that are shared between JIT and NGen
- static DWORD GetBaseCompileFlags(MethodDesc * ftn);
+ static CORJIT_FLAGS GetBaseCompileFlags(MethodDesc * ftn);
// Resolve metadata token into runtime method handles.
void resolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken);
@@ -1090,6 +1093,9 @@ public:
m_pThread(GetThread()),
m_hMethodForSecurity_Key(NULL),
m_pMethodForSecurity_Value(NULL)
+#if defined(FEATURE_GDBJIT)
+ , m_pCalledMethods(NULL)
+#endif
{
LIMITED_METHOD_CONTRACT;
}
@@ -1151,6 +1157,10 @@ public:
MethodDesc * pTemplateMD /* for method-based slots */,
CORINFO_LOOKUP *pResultLookup);
+#if defined(FEATURE_GDBJIT)
+ CalledMethod * GetCalledMethods() { return m_pCalledMethods; }
+#endif
+
protected:
// NGen provides its own modifications to EE-JIT interface. From technical reason it cannot simply inherit
// from code:CEEInfo class (because it has dependencies on VM that NGen does not want).
@@ -1174,6 +1184,10 @@ protected:
CORINFO_METHOD_HANDLE m_hMethodForSecurity_Key;
MethodDesc * m_pMethodForSecurity_Value;
+#if defined(FEATURE_GDBJIT)
+ CalledMethod * m_pCalledMethods;
+#endif
+
// Tracking of module activation dependencies. We have two flavors:
// - Fast one that gathers generic arguments from EE handles, but does not work inside generic context.
// - Slow one that operates on typespec and methodspecs from metadata.
@@ -1641,7 +1655,7 @@ struct VirtualFunctionPointerArgs
FCDECL2(CORINFO_MethodPtr, JIT_VirtualFunctionPointer_Dynamic, Object * objectUNSAFE, VirtualFunctionPointerArgs * pArgs);
-typedef TADDR (F_CALL_CONV * FnStaticBaseHelper)(TADDR arg0, TADDR arg1);
+typedef HCCALL2_PTR(TADDR, FnStaticBaseHelper, TADDR arg0, TADDR arg1);
struct StaticFieldAddressArgs
{
@@ -1677,8 +1691,8 @@ public:
static FCDECL3(void, UnsafeSetArrayElement, PtrArray* pPtrArray, INT32 index, Object* object);
};
-DWORD GetDebuggerCompileFlags(Module* pModule, DWORD flags);
+CORJIT_FLAGS GetDebuggerCompileFlags(Module* pModule, CORJIT_FLAGS flags);
-bool TrackAllocationsEnabled();
+bool __stdcall TrackAllocationsEnabled();
#endif // JITINTERFACE_H
diff --git a/src/vm/jitinterfacegen.cpp b/src/vm/jitinterfacegen.cpp
index 0a90dc347d..f8a95bb759 100644
--- a/src/vm/jitinterfacegen.cpp
+++ b/src/vm/jitinterfacegen.cpp
@@ -221,7 +221,7 @@ void InitJITHelpers1()
))
{
// if (multi-proc || server GC)
- if (GCHeap::UseAllocationContexts())
+ if (GCHeapUtilities::UseAllocationContexts())
{
#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 48911b7190..5f05fa2daf 100644
--- a/src/vm/marshalnative.cpp
+++ b/src/vm/marshalnative.cpp
@@ -27,7 +27,7 @@
#include "log.h"
#include "fieldmarshaler.h"
#include "cgensys.h"
-#include "gc.h"
+#include "gcheaputilities.h"
#include "security.h"
#include "dbginterface.h"
#include "objecthandle.h"
diff --git a/src/vm/marshalnative.h b/src/vm/marshalnative.h
index 4f6ac854ff..cff3f7eb63 100644
--- a/src/vm/marshalnative.h
+++ b/src/vm/marshalnative.h
@@ -229,7 +229,7 @@ public:
static FCDECL2(void, ChangeWrapperHandleStrength, Object* orefUNSAFE, CLR_BOOL fIsWeak);
static FCDECL2(void, InitializeWrapperForWinRT, Object *unsafe_pThis, IUnknown **ppUnk);
static FCDECL2(void, InitializeManagedWinRTFactoryObject, Object *unsafe_pThis, ReflectClassBaseObject *unsafe_pType);
- static FCDECL1(Object *, MarshalNative::GetNativeActivationFactory, ReflectClassBaseObject *unsafe_pType);
+ static FCDECL1(Object *, GetNativeActivationFactory, ReflectClassBaseObject *unsafe_pType);
static void QCALLTYPE GetInspectableIIDs(QCall::ObjectHandleOnStack hobj, QCall::ObjectHandleOnStack retArrayGuids);
static void QCALLTYPE GetCachedWinRTTypes(QCall::ObjectHandleOnStack hadObj, int * epoch, QCall::ObjectHandleOnStack retArrayMT);
static void QCALLTYPE GetCachedWinRTTypeByIID(QCall::ObjectHandleOnStack hadObj, GUID iid, void * * ppMT);
diff --git a/src/vm/mdaassistants.cpp b/src/vm/mdaassistants.cpp
index cc598c0a6c..e52e8ff8ec 100644
--- a/src/vm/mdaassistants.cpp
+++ b/src/vm/mdaassistants.cpp
@@ -137,7 +137,7 @@ void TriggerGCForMDAInternal()
EX_TRY
{
- GCHeap::GetGCHeap()->GarbageCollect();
+ GCHeapUtilities::GetGCHeap()->GarbageCollect();
#ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
//
@@ -868,7 +868,7 @@ LPVOID MdaInvalidOverlappedToPinvoke::CheckOverlappedPointer(UINT index, LPVOID
{
GCX_COOP();
- GCHeap *pHeap = GCHeap::GetGCHeap();
+ IGCHeap *pHeap = GCHeapUtilities::GetGCHeap();
fHeapPointer = pHeap->IsHeapPointer(pOverlapped);
}
diff --git a/src/vm/memberload.cpp b/src/vm/memberload.cpp
index 8b7b2ce69c..1b24300a68 100644
--- a/src/vm/memberload.cpp
+++ b/src/vm/memberload.cpp
@@ -30,7 +30,7 @@
#include "log.h"
#include "fieldmarshaler.h"
#include "cgensys.h"
-#include "gc.h"
+#include "gcheaputilities.h"
#include "security.h"
#include "dbginterface.h"
#include "comdelegate.h"
diff --git a/src/vm/message.cpp b/src/vm/message.cpp
index fa0370dd33..093f9a2629 100644
--- a/src/vm/message.cpp
+++ b/src/vm/message.cpp
@@ -249,7 +249,7 @@ void CMessage::GetObjectFromStack(OBJECTREF* ppDest, PVOID val, const CorElement
_ASSERTE(ty.GetMethodTable()->IsValueType() || ty.GetMethodTable()->IsEnum());
- _ASSERTE(!GCHeap::GetGCHeap()->IsHeapPointer((BYTE *) ppDest) ||
+ _ASSERTE(!GCHeapUtilities::GetGCHeap()->IsHeapPointer((BYTE *) ppDest) ||
!"(pDest) can not point to GC Heap");
MethodTable* pMT = ty.GetMethodTable();
diff --git a/src/vm/metasig.h b/src/vm/metasig.h
index 5bf2903eab..a8404615a1 100644
--- a/src/vm/metasig.h
+++ b/src/vm/metasig.h
@@ -302,7 +302,10 @@ 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_T(SM(PMS_PMS_RetInt, C(PERMISSION_SET) C(PERMISSION_SET), i))
DEFINE_METASIG(SM(IntPtr_RetVoid, I, v))
diff --git a/src/vm/method.cpp b/src/vm/method.cpp
index 70714b710d..7afe0e9de2 100644
--- a/src/vm/method.cpp
+++ b/src/vm/method.cpp
@@ -1078,7 +1078,7 @@ BOOL MethodDesc::IsVerifiable()
#endif // _VER_EE_VERIFICATION_ENABLED
}
- UnsafeJitFunction(this, pHeader, CORJIT_FLG_IMPORT_ONLY, 0);
+ UnsafeJitFunction(this, pHeader, CORJIT_FLAGS(CORJIT_FLAGS::CORJIT_FLAG_IMPORT_ONLY));
_ASSERTE(IsVerified());
return (IsVerified() && (m_wFlags & mdcVerifiable));
@@ -3249,6 +3249,7 @@ 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))
@@ -3256,6 +3257,7 @@ bool MethodDesc::CanSkipDoPrestub (
*pReason = CORINFO_INDIRECT_CALL_CER;
return false;
}
+#endif // FEATURE_CER
// Check whether our methoddesc needs restore
if (NeedsRestore(GetAppDomain()->ToCompilationDomain()->GetTargetImage(), TRUE))
diff --git a/src/vm/method.hpp b/src/vm/method.hpp
index 3cdd794f08..499112d149 100644
--- a/src/vm/method.hpp
+++ b/src/vm/method.hpp
@@ -1649,7 +1649,7 @@ public:
PCODE DoPrestub(MethodTable *pDispatchingMT);
- PCODE MakeJitWorker(COR_ILMETHOD_DECODER* ILHeader, DWORD flags, DWORD flags2);
+ PCODE MakeJitWorker(COR_ILMETHOD_DECODER* ILHeader, CORJIT_FLAGS flags);
VOID GetMethodInfo(SString &namespaceOrClassName, SString &methodName, SString &methodSignature);
VOID GetMethodInfoWithNewSig(SString &namespaceOrClassName, SString &methodName, SString &methodSignature);
@@ -3596,6 +3596,22 @@ inline BOOL MethodDesc::HasMethodInstantiation() const
return mcInstantiated == GetClassification() && AsInstantiatedMethodDesc()->IMD_HasMethodInstantiation();
}
+#if defined(FEATURE_GDBJIT)
+class CalledMethod
+{
+private:
+ MethodDesc * m_pMD;
+ void * m_CallAddr;
+ CalledMethod * m_pNext;
+public:
+ CalledMethod(MethodDesc *pMD, void * addr, CalledMethod * next) : m_pMD(pMD), m_CallAddr(addr), m_pNext(next) {}
+ ~CalledMethod() {}
+ MethodDesc * GetMethodDesc() { return m_pMD; }
+ void * GetCallAddr() { return m_CallAddr; }
+ CalledMethod * GetNext() { return m_pNext; }
+};
+#endif
+
#include "method.inl"
#endif // !_METHOD_H
diff --git a/src/vm/methodtable.cpp b/src/vm/methodtable.cpp
index bf863826d4..52a2ce4d98 100644
--- a/src/vm/methodtable.cpp
+++ b/src/vm/methodtable.cpp
@@ -33,7 +33,7 @@
#include "log.h"
#include "fieldmarshaler.h"
#include "cgensys.h"
-#include "gc.h"
+#include "gcheaputilities.h"
#include "security.h"
#include "dbginterface.h"
#include "comdelegate.h"
@@ -9804,11 +9804,11 @@ BOOL MethodTable::Validate()
}
DWORD dwLastVerifiedGCCnt = m_pWriteableData->m_dwLastVerifedGCCnt;
- // Here we used to assert that (dwLastVerifiedGCCnt <= GCHeap::GetGCHeap()->GetGcCount()) but
+ // Here we used to assert that (dwLastVerifiedGCCnt <= GCHeapUtilities::GetGCHeap()->GetGcCount()) but
// this is no longer true because with background gc. Since the purpose of having
// m_dwLastVerifedGCCnt is just to only verify the same method table once for each GC
// I am getting rid of the assert.
- if (g_pConfig->FastGCStressLevel () > 1 && dwLastVerifiedGCCnt == GCHeap::GetGCHeap()->GetGcCount())
+ if (g_pConfig->FastGCStressLevel () > 1 && dwLastVerifiedGCCnt == GCHeapUtilities::GetGCHeap()->GetGcCount())
return TRUE;
#endif //_DEBUG
@@ -9835,7 +9835,7 @@ BOOL MethodTable::Validate()
// It is not a fatal error to fail the update the counter. We will run slower and retry next time,
// but the system will function properly.
if (EnsureWritablePagesNoThrow(m_pWriteableData, sizeof(MethodTableWriteableData)))
- m_pWriteableData->m_dwLastVerifedGCCnt = GCHeap::GetGCHeap()->GetGcCount();
+ m_pWriteableData->m_dwLastVerifedGCCnt = GCHeapUtilities::GetGCHeap()->GetGcCount();
#endif //_DEBUG
return TRUE;
diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp
index 70c0e3b8cb..682268eb39 100644
--- a/src/vm/methodtablebuilder.cpp
+++ b/src/vm/methodtablebuilder.cpp
@@ -191,6 +191,7 @@ 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)
@@ -201,6 +202,7 @@ MethodTableBuilder::CreateClass( Module *pModule,
pEEClass->SetReliabilityContract(dwReliabilityContract);
}
+#endif // FEATURE_CER
if (fHasLayout)
pEEClass->SetHasLayout();
@@ -1218,7 +1220,7 @@ BOOL MethodTableBuilder::CheckIfSIMDAndUpdateSize()
{
STANDARD_VM_CONTRACT;
-#ifdef _TARGET_AMD64_
+#if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
if (!GetAssembly()->IsSIMDVectorAssembly())
return false;
@@ -1245,8 +1247,8 @@ BOOL MethodTableBuilder::CheckIfSIMDAndUpdateSize()
EEJitManager *jitMgr = ExecutionManager::GetEEJitManager();
if (jitMgr->LoadJIT())
{
- DWORD cpuCompileFlags = jitMgr->GetCPUCompileFlags();
- if ((cpuCompileFlags & CORJIT_FLG_FEATURE_SIMD) != 0)
+ CORJIT_FLAGS cpuCompileFlags = jitMgr->GetCPUCompileFlags();
+ if (cpuCompileFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_FEATURE_SIMD))
{
unsigned intrinsicSIMDVectorLength = jitMgr->m_jit->getMaxIntrinsicSIMDVectorLength(cpuCompileFlags);
if (intrinsicSIMDVectorLength != 0)
@@ -1262,7 +1264,7 @@ BOOL MethodTableBuilder::CheckIfSIMDAndUpdateSize()
}
}
#endif // !CROSSGEN_COMPILE
-#endif // _TARGET_AMD64_
+#endif // defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
return false;
}
@@ -1860,6 +1862,11 @@ MethodTableBuilder::BuildMethodTableThrowing(
pMT->SetHasBoxedRegularStatics();
}
+ if (bmtFP->fIsByRefLikeType)
+ {
+ pMT->SetIsByRefLike();
+ }
+
if (IsValueClass())
{
if (bmtFP->NumInstanceFieldBytes != totalDeclaredFieldSize || HasOverLayedField())
@@ -4212,14 +4219,12 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList,
goto GOT_ELEMENT_TYPE;
}
- // There are just few types with code:IsByRefLike set - see code:CheckForSystemTypes.
- // Note: None of them will ever have self-referencing static ValueType field (we cannot assert it now because the IsByRefLike
- // status for this type has not been initialized yet).
+ // Inherit IsByRefLike characteristic from fields
if (!IsSelfRef(pByValueClass) && pByValueClass->IsByRefLike())
- { // Cannot have embedded valuetypes that contain a field that require stack allocation.
- BuildMethodTableThrowException(COR_E_BADIMAGEFORMAT, IDS_CLASSLOAD_BAD_FIELD, mdTokenNil);
+ {
+ bmtFP->fIsByRefLikeType = true;
}
-
+
if (!IsSelfRef(pByValueClass) && pByValueClass->GetClass()->HasNonPublicFields())
{ // If a class has a field of type ValueType with non-public fields in it,
// the class must "inherit" this characteristic
@@ -10201,15 +10206,27 @@ void MethodTableBuilder::CheckForSystemTypes()
MethodTable * pMT = GetHalfBakedMethodTable();
EEClass * pClass = GetHalfBakedClass();
- // We can exit early for generic types - there is just one case to check for.
- if (g_pNullableClass != NULL && bmtGenerics->HasInstantiation())
+ // 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());
+
+ if (GetCl() == g_pByReferenceClass->GetCl())
+ {
+ pMT->SetIsByRefLike();
+ return;
+ }
+#endif
+
_ASSERTE(g_pNullableClass->IsNullable());
// Pre-compute whether the class is a Nullable<T> so that code:Nullable::IsNullableType is efficient
// This is useful to the performance of boxing/unboxing a Nullable
if (GetCl() == g_pNullableClass->GetCl())
pMT->SetIsNullable();
+
return;
}
@@ -10257,6 +10274,12 @@ void MethodTableBuilder::CheckForSystemTypes()
{
pMT->SetIsNullable();
}
+#ifdef FEATURE_SPAN_OF_T
+ else if (strcmp(name, g_ByReferenceName) == 0)
+ {
+ pMT->SetIsByRefLike();
+ }
+#endif
else if (strcmp(name, g_ArgIteratorName) == 0)
{
// Mark the special types that have embeded stack poitners in them
diff --git a/src/vm/methodtablebuilder.h b/src/vm/methodtablebuilder.h
index 1e40ea996c..1cf71499e6 100644
--- a/src/vm/methodtablebuilder.h
+++ b/src/vm/methodtablebuilder.h
@@ -2081,6 +2081,7 @@ private:
DWORD NumGCPointerSeries;
DWORD NumInstanceFieldBytes;
+ bool fIsByRefLikeType;
bool fHasFixedAddressValueTypes;
bool fHasSelfReferencingStaticValueTypeField_WithRVA;
diff --git a/src/vm/microsoft.comservices_i.c b/src/vm/microsoft.comservices_i.c
index d70bc8cefe..f31a92f53e 100644
--- a/src/vm/microsoft.comservices_i.c
+++ b/src/vm/microsoft.comservices_i.c
@@ -23,14 +23,13 @@
#if !defined(_M_IA64) && !defined(_M_AXP64)
+#include <rpc.h>
+#include <rpcndr.h>
+
#ifdef __cplusplus
extern "C"{
#endif
-
-#include <rpc.h>
-#include <rpcndr.h>
-
#ifdef _MIDL_USE_GUIDDEF_
#ifndef INITGUID
@@ -109,14 +108,13 @@ MIDL_DEFINE_GUID(CLSID, CLSID_RegistrationHelperTx,0x89A86E7B,0xC229,0x4008,0x9B
#if defined(_M_IA64) || defined(_M_AXP64)
+#include <rpc.h>
+#include <rpcndr.h>
+
#ifdef __cplusplus
extern "C"{
#endif
-
-#include <rpc.h>
-#include <rpcndr.h>
-
#ifdef _MIDL_USE_GUIDDEF_
#ifndef INITGUID
@@ -153,7 +151,7 @@ typedef IID CLSID;
#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
-#endif !_MIDL_USE_GUIDDEF_
+#endif // !_MIDL_USE_GUIDDEF_
MIDL_DEFINE_GUID(IID, LIBID_Microsoft_ComServices,0xD7F68C66,0x3833,0x3832,0xB6,0xD0,0xB7,0x96,0xBB,0x7D,0x2D,0xFF);
diff --git a/src/vm/mlinfo.cpp b/src/vm/mlinfo.cpp
index ab2545296e..74bd536969 100644
--- a/src/vm/mlinfo.cpp
+++ b/src/vm/mlinfo.cpp
@@ -4865,6 +4865,8 @@ void ArrayMarshalInfo::InitForHiddenLengthArray(TypeHandle thElement)
{
STANDARD_VM_CONTRACT;
+ MethodTable *pMT = NULL;
+
// WinRT supports arrays of any WinRT-legal types
if (thElement.IsArray())
{
@@ -4877,7 +4879,7 @@ void ArrayMarshalInfo::InitForHiddenLengthArray(TypeHandle thElement)
m_thElement = thElement;
- MethodTable *pMT = thElement.GetMethodTable();
+ pMT = thElement.GetMethodTable();
if (pMT->IsString())
{
m_vtElement = VTHACK_HSTRING;
diff --git a/src/vm/mscorlib.h b/src/vm/mscorlib.h
index 291c6abd47..20d658b2e1 100644
--- a/src/vm/mscorlib.h
+++ b/src/vm/mscorlib.h
@@ -462,8 +462,9 @@ DEFINE_METHOD(CONTEXT, CALLBACK, DoCallBackFromEE,
DEFINE_METHOD(CONTEXT, RESERVE_SLOT, ReserveSlot, IM_RetInt)
#endif
+#ifdef FEATURE_REMOTING
DEFINE_CLASS(CONTEXT_BOUND_OBJECT, System, ContextBoundObject)
-
+#endif
#ifdef FEATURE_CRYPTO
DEFINE_CLASS(CSP_PARAMETERS, Cryptography, CspParameters)
@@ -592,9 +593,7 @@ DEFINE_FIELD_U(textInfo, CultureInfoBaseObject, textInfo)
DEFINE_FIELD_U(numInfo, CultureInfoBaseObject, numInfo)
DEFINE_FIELD_U(dateTimeInfo, CultureInfoBaseObject, dateTimeInfo)
DEFINE_FIELD_U(calendar, CultureInfoBaseObject, calendar)
-#ifndef FEATURE_CORECLR
DEFINE_FIELD_U(m_consoleFallbackCulture, CultureInfoBaseObject, m_consoleFallbackCulture)
-#endif // FEATURE_CORECLR
DEFINE_FIELD_U(m_name, CultureInfoBaseObject, m_name)
DEFINE_FIELD_U(m_nonSortName, CultureInfoBaseObject, m_nonSortName)
DEFINE_FIELD_U(m_sortName, CultureInfoBaseObject, m_sortName)
@@ -772,6 +771,7 @@ 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)
@@ -786,6 +786,7 @@ 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_U(Security, FrameSecurityDescriptor, FrameSecurityDescriptorBaseObject)
DEFINE_FIELD_U(m_assertions, FrameSecurityDescriptorBaseObject, m_assertions)
@@ -1051,6 +1052,12 @@ 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)
DEFINE_FIELD_U(numberGroupSizes, NumberFormatInfo, cNumberGroup)
@@ -1085,9 +1092,7 @@ DEFINE_FIELD_U(numberNegativePattern, NumberFormatInfo, cNegativeNumberFormat
DEFINE_FIELD_U(percentPositivePattern, NumberFormatInfo, cPositivePercentFormat)
DEFINE_FIELD_U(percentNegativePattern, NumberFormatInfo, cNegativePercentFormat)
DEFINE_FIELD_U(percentDecimalDigits, NumberFormatInfo, cPercentDecimals)
-#ifndef FEATURE_COREFX_GLOBALIZATION
DEFINE_FIELD_U(digitSubstitution, NumberFormatInfo, iDigitSubstitution)
-#endif
DEFINE_FIELD_U(isReadOnly, NumberFormatInfo, bIsReadOnly)
#ifndef FEATURE_COREFX_GLOBALIZATION
DEFINE_FIELD_U(m_useUserOverride, NumberFormatInfo, bUseUserOverride)
@@ -1338,6 +1343,20 @@ 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_ARE_SAME, AreSame, NoSig)
+#endif
DEFINE_CLASS(INTERLOCKED, Threading, Interlocked)
DEFINE_METHOD(INTERLOCKED, COMPARE_EXCHANGE_T, CompareExchange, GM_RefT_T_T_RetT)
@@ -1346,6 +1365,11 @@ 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)
DEFINE_FIELD(RUNTIME_WRAPPED_EXCEPTION, WRAPPED_EXCEPTION, m_wrappedException)
@@ -1370,9 +1394,7 @@ DEFINE_CLASS(SAFE_PEFILE_HANDLE, SafeHandles, SafePEFileHandle)
DEFINE_CLASS(SAFE_TOKENHANDLE, SafeHandles, SafeAccessTokenHandle)
#endif
-#ifndef FEATURE_CORECLR
DEFINE_CLASS(SAFE_TYPENAMEPARSER_HANDLE, System, SafeTypeNameParserHandle)
-#endif //!FEATURE_CORECLR
#ifdef FEATURE_COMPRESSEDSTACK
DEFINE_CLASS(SAFE_CSHANDLE, Threading, SafeCompressedStackHandle)
diff --git a/src/vm/multicorejitplayer.cpp b/src/vm/multicorejitplayer.cpp
index 0c69fdcf94..7d13bbc462 100644
--- a/src/vm/multicorejitplayer.cpp
+++ b/src/vm/multicorejitplayer.cpp
@@ -556,7 +556,7 @@ bool MulticoreJitProfilePlayer::CompileMethodDesc(Module * pModule, MethodDesc *
#endif
// MakeJitWorker calls back to MulticoreJitCodeStorage::StoreMethodCode under MethodDesc lock
- pMD->MakeJitWorker(& header, CORJIT_FLG_MCJIT_BACKGROUND, 0);
+ pMD->MakeJitWorker(& header, CORJIT_FLAGS(CORJIT_FLAGS::CORJIT_FLAG_MCJIT_BACKGROUND));
return true;
}
diff --git a/src/vm/nativeoverlapped.cpp b/src/vm/nativeoverlapped.cpp
index 2e253f3046..d0afbb648a 100644
--- a/src/vm/nativeoverlapped.cpp
+++ b/src/vm/nativeoverlapped.cpp
@@ -35,14 +35,14 @@ FCIMPL3(void, CheckVMForIOPacket, LPOVERLAPPED* lpOverlapped, DWORD* errorCode,
{
FCALL_CONTRACT;
-#ifndef FEATURE_PAL
+#ifndef FEATURE_PAL
Thread *pThread = GetThread();
DWORD adid = pThread->GetDomain()->GetId().m_dwId;
size_t key=0;
- _ASSERTE(pThread);
+ _ASSERTE(pThread);
- //Poll and wait if GC is in progress, to avoid blocking GC for too long.
+ //Poll and wait if GC is in progress, to avoid blocking GC for too long.
FC_GC_POLL();
*lpOverlapped = ThreadpoolMgr::CompletionPortDispatchWorkWithinAppDomain(pThread, errorCode, numBytes, &key, adid);
@@ -59,13 +59,15 @@ FCIMPL3(void, CheckVMForIOPacket, LPOVERLAPPED* lpOverlapped, DWORD* errorCode,
if(overlapped->m_iocb == NULL)
{
// no user delegate to callback
- _ASSERTE((overlapped->m_iocbHelper == NULL) || !"This is benign, but should be optimized");
+ _ASSERTE((overlapped->m_iocbHelper == NULL) || !"This is benign, but should be optimized");
+#ifndef FEATURE_CORECLR
if (g_pAsyncFileStream_AsyncResultClass)
{
SetAsyncResultProperties(overlapped, *errorCode, *numBytes);
- }
- else
+ }
+ 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);
@@ -75,7 +77,7 @@ FCIMPL3(void, CheckVMForIOPacket, LPOVERLAPPED* lpOverlapped, DWORD* errorCode,
return;
}
else
- {
+ {
if(!pThread->IsRealThreadPoolResetNeeded())
{
pThread->ResetManagedThreadObjectInCoopMode(ThreadNative::PRIORITY_NORMAL);
@@ -84,7 +86,7 @@ FCIMPL3(void, CheckVMForIOPacket, LPOVERLAPPED* lpOverlapped, DWORD* errorCode,
{
//We may have to create a CP thread, go back to the Vm, and process the packet there.
ThreadpoolMgr::StoreOverlappedInfoInThread(pThread, *errorCode, *numBytes, key, *lpOverlapped);
- *lpOverlapped = NULL;
+ *lpOverlapped = NULL;
}
}
else
@@ -93,7 +95,7 @@ FCIMPL3(void, CheckVMForIOPacket, LPOVERLAPPED* lpOverlapped, DWORD* errorCode,
//and process the packet there.
ThreadpoolMgr::StoreOverlappedInfoInThread(pThread, *errorCode, *numBytes, key, *lpOverlapped);
- *lpOverlapped = NULL;
+ *lpOverlapped = NULL;
}
}
@@ -105,8 +107,8 @@ FCIMPL3(void, CheckVMForIOPacket, LPOVERLAPPED* lpOverlapped, DWORD* errorCode,
*lpOverlapped = NULL;
#endif // !FEATURE_PAL
- return;
-}
+ return;
+}
FCIMPLEND
FCIMPL1(void*, AllocateNativeOverlapped, OverlappedDataObject* overlappedUNSAFE)
diff --git a/src/vm/nativeoverlapped.h b/src/vm/nativeoverlapped.h
index 854090c35f..0c0693dca6 100644
--- a/src/vm/nativeoverlapped.h
+++ b/src/vm/nativeoverlapped.h
@@ -22,6 +22,7 @@ class OverlappedDataObject : public Object
{
public:
ASYNCRESULTREF m_asyncResult;
+
OBJECTREF m_iocb;
OBJECTREF m_iocbHelper;
OBJECTREF m_overlapped;
@@ -62,7 +63,7 @@ public:
STATIC_CONTRACT_SO_TOLERANT;
_ASSERTE (nativeOverlapped != NULL);
- _ASSERTE (GCHeap::GetGCHeap()->IsHeapPointer((BYTE *) nativeOverlapped));
+ _ASSERTE (GCHeapUtilities::GetGCHeap()->IsHeapPointer((BYTE *) nativeOverlapped));
return (OverlappedDataObject*)((BYTE*)nativeOverlapped - offsetof(OverlappedDataObject, Internal));
}
diff --git a/src/vm/object.cpp b/src/vm/object.cpp
index 7c47e26627..531c0015f2 100644
--- a/src/vm/object.cpp
+++ b/src/vm/object.cpp
@@ -17,7 +17,7 @@
#include "threads.h"
#include "excep.h"
#include "eeconfig.h"
-#include "gc.h"
+#include "gcheaputilities.h"
#ifdef FEATURE_REMOTING
#include "remoting.h"
#endif
@@ -243,7 +243,7 @@ TypeHandle Object::GetGCSafeTypeHandleIfPossible() const
//
// where MyRefType2's module was unloaded by the time the GC occurred. In at least
// one case, the GC was caused by the AD unload itself (AppDomain::Unload ->
- // AppDomain::Exit -> GCInterface::AddMemoryPressure -> WKS::GCHeap::GarbageCollect).
+ // AppDomain::Exit -> GCInterface::AddMemoryPressure -> WKS::GCHeapUtilities::GarbageCollect).
//
// To protect against all scenarios, verify that
//
@@ -1764,9 +1764,9 @@ VOID Object::ValidateInner(BOOL bDeep, BOOL bVerifyNextHeader, BOOL bVerifySyncB
BOOL bSmallObjectHeapPtr = FALSE, bLargeObjectHeapPtr = FALSE;
if (!noRangeChecks)
{
- bSmallObjectHeapPtr = GCHeap::GetGCHeap()->IsHeapPointer(this, TRUE);
+ bSmallObjectHeapPtr = GCHeapUtilities::GetGCHeap()->IsHeapPointer(this, TRUE);
if (!bSmallObjectHeapPtr)
- bLargeObjectHeapPtr = GCHeap::GetGCHeap()->IsHeapPointer(this);
+ bLargeObjectHeapPtr = GCHeapUtilities::GetGCHeap()->IsHeapPointer(this);
CHECK_AND_TEAR_DOWN(bSmallObjectHeapPtr || bLargeObjectHeapPtr);
}
@@ -1781,7 +1781,7 @@ VOID Object::ValidateInner(BOOL bDeep, BOOL bVerifyNextHeader, BOOL bVerifySyncB
lastTest = 4;
if (bDeep && (g_pConfig->GetHeapVerifyLevel() & EEConfig::HEAPVERIFY_GC)) {
- GCHeap::GetGCHeap()->ValidateObjectMember(this);
+ GCHeapUtilities::GetGCHeap()->ValidateObjectMember(this);
}
lastTest = 5;
@@ -1790,7 +1790,7 @@ VOID Object::ValidateInner(BOOL bDeep, BOOL bVerifyNextHeader, BOOL bVerifySyncB
// we skip checking noRangeChecks since if skipping
// is enabled bSmallObjectHeapPtr will always be false.
if (bSmallObjectHeapPtr) {
- CHECK_AND_TEAR_DOWN(!GCHeap::GetGCHeap()->IsObjectInFixedHeap(this));
+ CHECK_AND_TEAR_DOWN(!GCHeapUtilities::GetGCHeap()->IsObjectInFixedHeap(this));
}
lastTest = 6;
@@ -1815,9 +1815,9 @@ VOID Object::ValidateInner(BOOL bDeep, BOOL bVerifyNextHeader, BOOL bVerifySyncB
&& bVerifyNextHeader
&& GCScan::GetGcRuntimeStructuresValid ()
//NextObj could be very slow if concurrent GC is going on
- && !(GCHeap::IsGCHeapInitialized() && GCHeap::GetGCHeap ()->IsConcurrentGCInProgress ()))
+ && !(GCHeapUtilities::IsGCHeapInitialized() && GCHeapUtilities::GetGCHeap ()->IsConcurrentGCInProgress ()))
{
- Object * nextObj = GCHeap::GetGCHeap ()->NextObj (this);
+ Object * nextObj = GCHeapUtilities::GetGCHeap ()->NextObj (this);
if ((nextObj != NULL) &&
(nextObj->GetGCSafeMethodTable() != g_pFreeObjectMethodTable))
{
@@ -1949,7 +1949,7 @@ STRINGREF StringObject::NewString(const WCHAR *pwsz)
// pinning and then later put into a struct and that struct is
// then marshalled to managed.
//
- _ASSERTE(!GCHeap::GetGCHeap()->IsHeapPointer((BYTE *) pwsz) ||
+ _ASSERTE(!GCHeapUtilities::GetGCHeap()->IsHeapPointer((BYTE *) pwsz) ||
!"pwsz can not point to GC Heap");
#endif // 0
@@ -1988,7 +1988,7 @@ STRINGREF StringObject::NewString(const WCHAR *pwsz, int length) {
// pinning and then later put into a struct and that struct is
// then marshalled to managed.
//
- _ASSERTE(!GCHeap::GetGCHeap()->IsHeapPointer((BYTE *) pwsz) ||
+ _ASSERTE(!GCHeapUtilities::GetGCHeap()->IsHeapPointer((BYTE *) pwsz) ||
!"pwsz can not point to GC Heap");
#endif // 0
STRINGREF pString = AllocateString(length);
@@ -2121,9 +2121,11 @@ STRINGREF __stdcall StringObject::StringInitCharHelper(LPCSTR pszSource, int len
if (!pszSource || length == 0) {
return StringObject::GetEmptyString();
}
+#ifndef FEATURE_PAL
else if ((size_t)pszSource < 64000) {
COMPlusThrow(kArgumentException, W("Arg_MustBeStringPtrNotAtom"));
}
+#endif // FEATURE_PAL
// Make sure we can read from the pointer.
// This is better than try to read from the pointer and catch the access violation exceptions.
@@ -2664,7 +2666,7 @@ OBJECTREF::OBJECTREF(const OBJECTREF & objref)
// !!! Either way you need to fix the code.
_ASSERTE(Thread::IsObjRefValid(&objref));
if ((objref.m_asObj != 0) &&
- ((GCHeap*)GCHeap::GetGCHeap())->IsHeapPointer( (BYTE*)this ))
+ ((IGCHeap*)GCHeapUtilities::GetGCHeap())->IsHeapPointer( (BYTE*)this ))
{
_ASSERTE(!"Write Barrier violation. Must use SetObjectReference() to assign OBJECTREF's into the GC heap!");
}
@@ -2718,7 +2720,7 @@ OBJECTREF::OBJECTREF(Object *pObject)
DEBUG_ONLY_FUNCTION;
if ((pObject != 0) &&
- ((GCHeap*)GCHeap::GetGCHeap())->IsHeapPointer( (BYTE*)this ))
+ ((IGCHeap*)GCHeapUtilities::GetGCHeap())->IsHeapPointer( (BYTE*)this ))
{
_ASSERTE(!"Write Barrier violation. Must use SetObjectReference() to assign OBJECTREF's into the GC heap!");
}
@@ -2901,7 +2903,7 @@ OBJECTREF& OBJECTREF::operator=(const OBJECTREF &objref)
_ASSERTE(Thread::IsObjRefValid(&objref));
if ((objref.m_asObj != 0) &&
- ((GCHeap*)GCHeap::GetGCHeap())->IsHeapPointer( (BYTE*)this ))
+ ((IGCHeap*)GCHeapUtilities::GetGCHeap())->IsHeapPointer( (BYTE*)this ))
{
_ASSERTE(!"Write Barrier violation. Must use SetObjectReference() to assign OBJECTREF's into the GC heap!");
}
@@ -2948,14 +2950,14 @@ void* __cdecl GCSafeMemCpy(void * dest, const void * src, size_t len)
{
Thread* pThread = GetThread();
- // GCHeap::IsHeapPointer has race when called in preemptive mode. It walks the list of segments
+ // GCHeapUtilities::IsHeapPointer has race when called in preemptive mode. It walks the list of segments
// that can be modified by GC. Do the check below only if it is safe to do so.
if (pThread != NULL && pThread->PreemptiveGCDisabled())
{
// Note there is memcpyNoGCRefs which will allow you to do a memcpy into the GC
// heap if you really know you don't need to call the write barrier
- _ASSERTE(!GCHeap::GetGCHeap()->IsHeapPointer((BYTE *) dest) ||
+ _ASSERTE(!GCHeapUtilities::GetGCHeap()->IsHeapPointer((BYTE *) dest) ||
!"using memcpy to copy into the GC heap, use CopyValueClass");
}
}
diff --git a/src/vm/object.h b/src/vm/object.h
index 37560cf53c..73ecb62b80 100644
--- a/src/vm/object.h
+++ b/src/vm/object.h
@@ -1856,9 +1856,7 @@ private:
OBJECTREF dateTimeInfo;
OBJECTREF calendar;
OBJECTREF m_cultureData;
-#ifndef FEATURE_CORECLR
OBJECTREF m_consoleFallbackCulture;
-#endif // !FEATURE_CORECLR
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)
@@ -2194,15 +2192,28 @@ public:
}
#endif // FEATURE_LEAK_CULTURE_INFO
-#ifndef FEATURE_CORECLR
+#ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
+#ifdef FEATURE_CORECLR
OBJECTREF GetSynchronizationContext()
{
- LIMITED_METHOD_CONTRACT;
+ LIMITED_METHOD_CONTRACT;
+ return m_SynchronizationContext;
+ }
+#else // !FEATURE_CORECLR
+ OBJECTREF GetSynchronizationContext()
+ {
+ LIMITED_METHOD_CONTRACT;
if (m_ExecutionContext != NULL)
+ {
return m_ExecutionContext->GetSynchronizationContext();
+ }
return NULL;
}
- OBJECTREF GetExecutionContext()
+#endif // FEATURE_CORECLR
+#endif // FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
+
+#ifndef FEATURE_CORECLR
+ OBJECTREF GetExecutionContext()
{
LIMITED_METHOD_CONTRACT;
return (OBJECTREF)m_ExecutionContext;
@@ -2869,8 +2880,10 @@ class FrameSecurityDescriptorBaseObject : public Object
LIMITED_METHOD_CONTRACT;
m_declSecComputed = !!declSec;
}
+#ifndef FEATURE_PAL
LPVOID GetCallerToken();
LPVOID GetImpersonationToken();
+#endif // FEATURE_PAL
};
#ifdef FEATURE_COMPRESSEDSTACK
@@ -4563,9 +4576,7 @@ public:
INT32 cPositivePercentFormat; // positivePercentFormat
INT32 cNegativePercentFormat; // negativePercentFormat
INT32 cPercentDecimals; // percentDecimalDigits
-#ifndef FEATURE_COREFX_GLOBALIZATION
INT32 iDigitSubstitution; // digitSubstitution
-#endif
CLR_BOOL bIsReadOnly; // Is this NumberFormatInfo ReadOnly?
#ifndef FEATURE_COREFX_GLOBALIZATION
diff --git a/src/vm/prestub.cpp b/src/vm/prestub.cpp
index 1f2e8c748c..e0d4096347 100644
--- a/src/vm/prestub.cpp
+++ b/src/vm/prestub.cpp
@@ -228,7 +228,7 @@ void DACNotifyCompilationFinished(MethodDesc *methodDesc)
// Are we listed?
USHORT jnt = jn.Requested((TADDR) modulePtr, t);
if (jnt & CLRDATA_METHNOTIFY_GENERATED)
- {
+ {
// If so, throw an exception!
#endif
DACNotify::DoJITNotification(methodDesc);
@@ -256,7 +256,7 @@ void DACNotifyCompilationFinished(MethodDesc *methodDesc)
// which prevents us from trying to JIT the same method more that once.
-PCODE MethodDesc::MakeJitWorker(COR_ILMETHOD_DECODER* ILHeader, DWORD flags, DWORD flags2)
+PCODE MethodDesc::MakeJitWorker(COR_ILMETHOD_DECODER* ILHeader, CORJIT_FLAGS flags)
{
STANDARD_VM_CONTRACT;
@@ -280,7 +280,7 @@ PCODE MethodDesc::MakeJitWorker(COR_ILMETHOD_DECODER* ILHeader, DWORD flags, DWO
#ifdef FEATURE_MULTICOREJIT
MulticoreJitManager & mcJitManager = GetAppDomain()->GetMulticoreJitManager();
- bool fBackgroundThread = (flags & CORJIT_FLG_MCJIT_BACKGROUND) != 0;
+ bool fBackgroundThread = flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_MCJIT_BACKGROUND);
#endif
{
@@ -424,22 +424,30 @@ PCODE MethodDesc::MakeJitWorker(COR_ILMETHOD_DECODER* ILHeader, DWORD flags, DWO
{
BEGIN_PIN_PROFILER(CORProfilerTrackJITInfo());
+#ifdef FEATURE_MULTICOREJIT
// Multicore JIT should be disabled when CORProfilerTrackJITInfo is on
// But there could be corner case in which profiler is attached when multicore background thread is calling MakeJitWorker
// Disable this block when calling from multicore JIT background thread
- if (!IsNoMetadata()
-#ifdef FEATURE_MULTICOREJIT
-
- && (! fBackgroundThread)
+ if (!fBackgroundThread)
#endif
- )
{
- g_profControlBlock.pProfInterface->JITCompilationStarted((FunctionID) this, TRUE);
- // The profiler may have changed the code on the callback. Need to
- // pick up the new code. Note that you have to be fully trusted in
- // this mode and the code will not be verified.
- COR_ILMETHOD *pilHeader = GetILHeader(TRUE);
- new (ILHeader) COR_ILMETHOD_DECODER(pilHeader, GetMDImport(), NULL);
+ if (!IsNoMetadata())
+ {
+ g_profControlBlock.pProfInterface->JITCompilationStarted((FunctionID) this, TRUE);
+ // The profiler may have changed the code on the callback. Need to
+ // pick up the new code. Note that you have to be fully trusted in
+ // this mode and the code will not be verified.
+ COR_ILMETHOD *pilHeader = GetILHeader(TRUE);
+ new (ILHeader) COR_ILMETHOD_DECODER(pilHeader, GetMDImport(), NULL);
+ }
+ else
+ {
+ unsigned int ilSize, unused;
+ CorInfoOptions corOptions;
+ LPCBYTE ilHeaderPointer = this->AsDynamicMethodDesc()->GetResolver()->GetCodeInfo(&ilSize, &unused, &corOptions, &unused);
+
+ g_profControlBlock.pProfInterface->DynamicMethodJITCompilationStarted((FunctionID) this, TRUE, ilHeaderPointer, ilSize);
+ }
}
END_PIN_PROFILER();
}
@@ -457,13 +465,13 @@ PCODE MethodDesc::MakeJitWorker(COR_ILMETHOD_DECODER* ILHeader, DWORD flags, DWO
if (!fBackgroundThread)
#endif // FEATURE_MULTICOREJIT
{
- StackSampler::RecordJittingInfo(this, flags, flags2);
+ StackSampler::RecordJittingInfo(this, flags);
}
#endif // FEATURE_STACK_SAMPLING
EX_TRY
{
- pCode = UnsafeJitFunction(this, ILHeader, flags, flags2, &sizeOfCode);
+ pCode = UnsafeJitFunction(this, ILHeader, flags, &sizeOfCode);
}
EX_CATCH
{
@@ -593,6 +601,10 @@ GotNewCode:
pEntry->m_hrResultCode,
TRUE);
}
+ else
+ {
+ g_profControlBlock.pProfInterface->DynamicMethodJITCompilationFinished((FunctionID) this, pEntry->m_hrResultCode, TRUE);
+ }
END_PIN_PROFILER();
}
#endif // PROFILING_SUPPORTED
@@ -1179,7 +1191,7 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT)
if (g_pConfig->ShouldPrestubGC(this))
{
GCX_COOP();
- GCHeap::GetGCHeap()->GarbageCollect(-1);
+ GCHeapUtilities::GetGCHeap()->GarbageCollect(-1);
}
#endif // _DEBUG
@@ -1203,12 +1215,12 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT)
RETURN GetStableEntryPoint();
}
-#ifdef FEATURE_PREJIT
+#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
+#endif // FEATURE_PREJIT && FEATURE_CER
#ifdef FEATURE_COMINTEROP
/************************** INTEROP *************************/
@@ -1455,7 +1467,7 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT)
// Mark the code as hot in case the method ends up in the native image
g_IBCLogger.LogMethodCodeAccess(this);
- pCode = MakeJitWorker(pHeader, 0, 0);
+ pCode = MakeJitWorker(pHeader, CORJIT_FLAGS());
#ifdef FEATURE_INTERPRETER
if ((pCode != NULL) && !HasStableEntryPoint())
@@ -1635,9 +1647,9 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT)
// use the prestub.
//==========================================================================
-#ifdef _TARGET_X86_
+#if defined(_TARGET_X86_) && !defined(FEATURE_STUBS_AS_IL)
static PCODE g_UMThunkPreStub;
-#endif
+#endif // _TARGET_X86_ && !FEATURE_STUBS_AS_IL
#ifndef DACCESS_COMPILE
@@ -1664,9 +1676,9 @@ void InitPreStubManager(void)
return;
}
-#ifdef _TARGET_X86_
+#if defined(_TARGET_X86_) && !defined(FEATURE_STUBS_AS_IL)
g_UMThunkPreStub = GenerateUMThunkPrestub()->GetEntryPoint();
-#endif
+#endif // _TARGET_X86_ && !FEATURE_STUBS_AS_IL
ThePreStubManager::Init();
}
@@ -1675,11 +1687,11 @@ PCODE TheUMThunkPreStub()
{
LIMITED_METHOD_CONTRACT;
-#ifdef _TARGET_X86_
+#if defined(_TARGET_X86_) && !defined(FEATURE_STUBS_AS_IL)
return g_UMThunkPreStub;
-#else
+#else // _TARGET_X86_ && !FEATURE_STUBS_AS_IL
return GetEEFuncEntryPoint(TheUMEntryPrestub);
-#endif
+#endif // _TARGET_X86_ && !FEATURE_STUBS_AS_IL
}
PCODE TheVarargNDirectStub(BOOL hasRetBuffArg)
diff --git a/src/vm/profattach.cpp b/src/vm/profattach.cpp
index f03db361f0..5b10e8f10e 100644
--- a/src/vm/profattach.cpp
+++ b/src/vm/profattach.cpp
@@ -806,7 +806,7 @@ void ProfilingAPIAttachDetach::InitializeAttachThreadingMode()
// Environment variable trumps all, so check it first
DWORD dwAlwaysOn = g_pConfig->GetConfigDWORD_DontUse_(
CLRConfig::EXTERNAL_AttachThreadAlwaysOn,
- GCHeap::IsServerHeap() ? 1 : 0); // Default depends on GC server mode
+ GCHeapUtilities::IsServerHeap() ? 1 : 0); // Default depends on GC server mode
if (dwAlwaysOn == 0)
{
diff --git a/src/vm/profilinghelper.cpp b/src/vm/profilinghelper.cpp
index 139ba89ec0..1dd60b47e1 100644
--- a/src/vm/profilinghelper.cpp
+++ b/src/vm/profilinghelper.cpp
@@ -1413,7 +1413,7 @@ void ProfilingAPIUtility::TerminateProfiling()
{
// We know for sure GC has been fully initialized as we've turned off concurrent GC before
_ASSERTE(IsGarbageCollectorFullyInitialized());
- GCHeap::GetGCHeap()->TemporaryEnableConcurrentGC();
+ GCHeapUtilities::GetGCHeap()->TemporaryEnableConcurrentGC();
g_profControlBlock.fConcurrentGCDisabledForAttach = FALSE;
}
diff --git a/src/vm/proftoeeinterfaceimpl.cpp b/src/vm/proftoeeinterfaceimpl.cpp
index 551b38631a..1aee26dde3 100644
--- a/src/vm/proftoeeinterfaceimpl.cpp
+++ b/src/vm/proftoeeinterfaceimpl.cpp
@@ -585,6 +585,10 @@ COM_METHOD ProfToEEInterfaceImpl::QueryInterface(REFIID id, void ** pInterface)
{
*pInterface = static_cast<ICorProfilerInfo7 *>(this);
}
+ else if (id == IID_ICorProfilerInfo8)
+ {
+ *pInterface = static_cast<ICorProfilerInfo8 *>(this);
+ }
else if (id == IID_IUnknown)
{
*pInterface = static_cast<IUnknown *>(static_cast<ICorProfilerInfo *>(this));
@@ -754,7 +758,7 @@ struct GenerationTable
//---------------------------------------------------------------------------------------
//
-// This is a callback used by the GC when we call GCHeap::DescrGenerationsToProfiler
+// This is a callback used by the GC when we call GCHeapUtilities::DiagDescrGenerations
// (from UpdateGenerationBounds() below). The GC gives us generation information through
// this callback, which we use to update the GenerationDesc in the corresponding
// GenerationTable
@@ -874,8 +878,8 @@ void __stdcall UpdateGenerationBounds()
#endif
// fill in the values by calling back into the gc, which will report
// the ranges by calling GenWalkFunc for each one
- GCHeap *hp = GCHeap::GetGCHeap();
- hp->DescrGenerationsToProfiler(GenWalkFunc, newGenerationTable);
+ IGCHeap *hp = GCHeapUtilities::GetGCHeap();
+ hp->DiagDescrGenerations(GenWalkFunc, newGenerationTable);
// remember the old table and plug in the new one
GenerationTable *oldGenerationTable = s_currentGenerationTable;
@@ -1018,7 +1022,7 @@ ClassID SafeGetClassIDFromObject(Object * pObj)
//---------------------------------------------------------------------------------------
//
-// Callback of type walk_fn used by GCHeap::WalkObject. Keeps a count of each
+// Callback of type walk_fn used by GCHeapUtilities::DiagWalkObject. Keeps a count of each
// object reference found.
//
// Arguments:
@@ -1040,7 +1044,7 @@ BOOL CountContainedObjectRef(Object * pBO, void * context)
//---------------------------------------------------------------------------------------
//
-// Callback of type walk_fn used by GCHeap::WalkObject. Stores each object reference
+// Callback of type walk_fn used by GCHeapUtilities::DiagWalkObject. Stores each object reference
// encountered into an array.
//
// Arguments:
@@ -1113,7 +1117,7 @@ BOOL HeapWalkHelper(Object * pBO, void * pvContext)
if (pMT->ContainsPointersOrCollectible())
{
// First round through calculates the number of object refs for this class
- GCHeap::GetGCHeap()->WalkObject(pBO, &CountContainedObjectRef, (void *)&cNumRefs);
+ GCHeapUtilities::GetGCHeap()->DiagWalkObject(pBO, &CountContainedObjectRef, (void *)&cNumRefs);
if (cNumRefs > 0)
{
@@ -1138,7 +1142,7 @@ BOOL HeapWalkHelper(Object * pBO, void * pvContext)
// Second round saves off all of the ref values
OBJECTREF * pCurObjRef = arrObjRef;
- GCHeap::GetGCHeap()->WalkObject(pBO, &SaveContainedObjectRef, (void *)&pCurObjRef);
+ GCHeapUtilities::GetGCHeap()->DiagWalkObject(pBO, &SaveContainedObjectRef, (void *)&pCurObjRef);
}
}
@@ -1959,7 +1963,7 @@ HRESULT GetFunctionInfoInternal(LPCBYTE ip, EECodeInfo * pCodeInfo)
}
-HRESULT GetFunctionFromIPInternal(LPCBYTE ip, EECodeInfo * pCodeInfo)
+HRESULT GetFunctionFromIPInternal(LPCBYTE ip, EECodeInfo * pCodeInfo, BOOL failOnNoMetadata)
{
CONTRACTL
{
@@ -1979,11 +1983,14 @@ HRESULT GetFunctionFromIPInternal(LPCBYTE ip, EECodeInfo * pCodeInfo)
{
return hr;
}
-
- // never return a method that the user of the profiler API cannot use
- if (pCodeInfo->GetMethodDesc()->IsNoMetadata())
+
+ if (failOnNoMetadata)
{
- return E_FAIL;
+ // never return a method that the user of the profiler API cannot use
+ if (pCodeInfo->GetMethodDesc()->IsNoMetadata())
+ {
+ return E_FAIL;
+ }
}
return S_OK;
@@ -2043,7 +2050,7 @@ HRESULT ProfToEEInterfaceImpl::GetFunctionFromIP(LPCBYTE ip, FunctionID * pFunct
EECodeInfo codeInfo;
- hr = GetFunctionFromIPInternal(ip, &codeInfo);
+ hr = GetFunctionFromIPInternal(ip, &codeInfo, /* failOnNoMetadata */ TRUE);
if (FAILED(hr))
{
return hr;
@@ -2096,7 +2103,7 @@ HRESULT ProfToEEInterfaceImpl::GetFunctionFromIP2(LPCBYTE ip, FunctionID * pFunc
EECodeInfo codeInfo;
- hr = GetFunctionFromIPInternal(ip, &codeInfo);
+ hr = GetFunctionFromIPInternal(ip, &codeInfo, /* failOnNoMetadata */ TRUE);
if (FAILED(hr))
{
return hr;
@@ -4122,7 +4129,6 @@ DWORD ProfToEEInterfaceImpl::GetModuleFlags(Module * pModule)
}
#endif
// Not NGEN or ReadyToRun.
-
if (pPEFile->HasOpenedILimage())
{
PEImage * pILImage = pPEFile->GetOpenedILimage();
@@ -6051,7 +6057,7 @@ HRESULT ProfToEEInterfaceImpl::SetEnterLeaveFunctionHooks3WithInfo(FunctionEnter
// The profiler must call SetEnterLeaveFunctionHooks3WithInfo during initialization, since
// the enter/leave events are immutable and must also be set during initialization.
- PROFILER_TO_CLR_ENTRYPOINT_SET_ELT((LF_CORPROF,
+ PROFILER_TO_CLR_ENTRYPOINT_SET_ELT((LF_CORPROF,
LL_INFO10,
"**PROF: SetEnterLeaveFunctionHooks3WithInfo 0x%p, 0x%p, 0x%p.\n",
pFuncEnter3WithInfo,
@@ -6373,6 +6379,294 @@ HRESULT ProfToEEInterfaceImpl::GetFunctionInfo2(FunctionID funcId,
}
/*
+* IsFunctionDynamic
+*
+* This function takes a functionId that maybe of a metadata-less method like an IL Stub
+* or LCG method and returns true in the pHasNoMetadata if it is indeed a metadata-less
+* method.
+*
+* Parameters:
+* functionId - The function that is being requested.
+* isDynamic - An optional parameter for returning if the function has metadata or not.
+*
+* Returns:
+* S_OK if successful.
+*/
+HRESULT ProfToEEInterfaceImpl::IsFunctionDynamic(FunctionID functionId, BOOL *isDynamic)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ EE_THREAD_NOT_REQUIRED;
+
+ // Generics::GetExactInstantiationsOfMethodAndItsClassFromCallInformation eventually
+ // reads metadata which causes us to take a reader lock. However, see
+ // code:#DisableLockOnAsyncCalls
+ DISABLED(CAN_TAKE_LOCK);
+
+ // Asynchronous functions can be called at arbitrary times when runtime
+ // is holding locks that cannot be reentered without causing deadlock.
+ // This contract detects any attempts to reenter locks held at the time
+ // this function was called.
+ CANNOT_RETAKE_LOCK;
+
+ SO_NOT_MAINLINE;
+
+ PRECONDITION(CheckPointer(isDynamic, NULL_OK));
+ }
+ CONTRACTL_END;
+
+ // See code:#DisableLockOnAsyncCalls
+ PERMANENT_CONTRACT_VIOLATION(TakesLockViolation, ReasonProfilerAsyncCannotRetakeLock);
+
+ PROFILER_TO_CLR_ENTRYPOINT_ASYNC_EX(kP2EEAllowableAfterAttach,
+ (LF_CORPROF,
+ LL_INFO1000,
+ "**PROF: IsFunctionDynamic 0x%p.\n",
+ functionId));
+
+ //
+ // Verify parameters.
+ //
+
+ if (functionId == NULL)
+ {
+ return E_INVALIDARG;
+ }
+
+ MethodDesc *pMethDesc = FunctionIdToMethodDesc(functionId);
+
+ if (pMethDesc == NULL)
+ {
+ return E_INVALIDARG;
+ }
+
+ // it's not safe to examine a methoddesc that has not been restored so do not do so
+ if (!pMethDesc->IsRestored())
+ return CORPROF_E_DATAINCOMPLETE;
+
+ //
+ // Fill in the pHasNoMetadata, if desired.
+ //
+ if (isDynamic != NULL)
+ {
+ *isDynamic = pMethDesc->IsNoMetadata();
+ }
+
+ return S_OK;
+}
+
+/*
+* GetFunctionFromIP3
+*
+* This function takes an IP and determines if it is a managed function returning its
+* FunctionID. This method is different from GetFunctionFromIP in that will return
+* FunctionIDs even if they have no associated metadata.
+*
+* Parameters:
+* ip - The instruction pointer.
+* pFunctionId - An optional parameter for returning the FunctionID.
+* pReJitId - The ReJIT id.
+*
+* Returns:
+* S_OK if successful.
+*/
+HRESULT ProfToEEInterfaceImpl::GetFunctionFromIP3(LPCBYTE ip, FunctionID * pFunctionId, ReJITID * pReJitId)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+
+ // Grabbing the rejitid requires entering the rejit manager's hash table & lock,
+ // which can switch us to preemptive mode and trigger GCs
+ GC_TRIGGERS;
+ MODE_ANY;
+ EE_THREAD_NOT_REQUIRED;
+
+ // Grabbing the rejitid requires entering the rejit manager's hash table & lock,
+ CAN_TAKE_LOCK;
+
+ SO_NOT_MAINLINE;
+ }
+ CONTRACTL_END;
+
+ // See code:#DisableLockOnAsyncCalls
+ PERMANENT_CONTRACT_VIOLATION(TakesLockViolation, ReasonProfilerAsyncCannotRetakeLock);
+
+ PROFILER_TO_CLR_ENTRYPOINT_SYNC_EX(
+ kP2EEAllowableAfterAttach | kP2EETriggers,
+ (LF_CORPROF,
+ LL_INFO1000,
+ "**PROF: GetFunctionFromIP3 0x%p.\n",
+ ip));
+
+ HRESULT hr = S_OK;
+
+ EECodeInfo codeInfo;
+
+ hr = GetFunctionFromIPInternal(ip, &codeInfo, /* failOnNoMetadata */ FALSE);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+
+ if (pFunctionId)
+ {
+ *pFunctionId = MethodDescToFunctionID(codeInfo.GetMethodDesc());
+ }
+
+ if (pReJitId != NULL)
+ {
+ MethodDesc * pMD = codeInfo.GetMethodDesc();
+ *pReJitId = pMD->GetReJitManager()->GetReJitId(pMD, codeInfo.GetStartAddress());
+ }
+
+ return S_OK;
+}
+
+/*
+* GetDynamicFunctionInfo
+*
+* This function takes a functionId that maybe of a metadata-less method like an IL Stub
+* or LCG method and gives information about it without failing like GetFunctionInfo.
+*
+* Parameters:
+* functionId - The function that is being requested.
+* pModuleId - An optional parameter for returning the module of the function.
+* ppvSig - An optional parameter for returning the signature of the function.
+* pbSig - An optional parameter for returning the size of the signature of the function.
+* cchName - A parameter for indicating the size of buffer for the wszName parameter.
+* pcchName - An optional parameter for returning the true size of the wszName parameter.
+* wszName - A parameter to the caller allocated buffer of size cchName
+*
+* Returns:
+* S_OK if successful.
+*/
+HRESULT ProfToEEInterfaceImpl::GetDynamicFunctionInfo(FunctionID functionId,
+ ModuleID *pModuleId,
+ PCCOR_SIGNATURE* ppvSig,
+ ULONG* pbSig,
+ ULONG cchName,
+ ULONG *pcchName,
+ __out_ecount_part_opt(cchName, *pcchName) WCHAR wszName[])
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ EE_THREAD_NOT_REQUIRED;
+
+ // Generics::GetExactInstantiationsOfMethodAndItsClassFromCallInformation eventually
+ // reads metadata which causes us to take a reader lock. However, see
+ // code:#DisableLockOnAsyncCalls
+ DISABLED(CAN_TAKE_LOCK);
+
+ // Asynchronous functions can be called at arbitrary times when runtime
+ // is holding locks that cannot be reentered without causing deadlock.
+ // This contract detects any attempts to reenter locks held at the time
+ // this function was called.
+ CANNOT_RETAKE_LOCK;
+
+ SO_NOT_MAINLINE;
+
+ PRECONDITION(CheckPointer(pModuleId, NULL_OK));
+ PRECONDITION(CheckPointer(ppvSig, NULL_OK));
+ PRECONDITION(CheckPointer(pbSig, NULL_OK));
+ PRECONDITION(CheckPointer(pcchName, NULL_OK));
+ }
+ CONTRACTL_END;
+
+ // See code:#DisableLockOnAsyncCalls
+ PERMANENT_CONTRACT_VIOLATION(TakesLockViolation, ReasonProfilerAsyncCannotRetakeLock);
+
+ PROFILER_TO_CLR_ENTRYPOINT_ASYNC_EX(kP2EEAllowableAfterAttach,
+ (LF_CORPROF,
+ LL_INFO1000,
+ "**PROF: GetDynamicFunctionInfo 0x%p.\n",
+ functionId));
+
+ //
+ // Verify parameters.
+ //
+
+ if (functionId == NULL)
+ {
+ return E_INVALIDARG;
+ }
+
+ MethodDesc *pMethDesc = FunctionIdToMethodDesc(functionId);
+
+ if (pMethDesc == NULL)
+ {
+ return E_INVALIDARG;
+ }
+
+ // it's not safe to examine a methoddesc that has not been restored so do not do so
+ if (!pMethDesc->IsRestored())
+ return CORPROF_E_DATAINCOMPLETE;
+
+
+ if (!pMethDesc->IsNoMetadata())
+ return E_INVALIDARG;
+
+ //
+ // Fill in the ModuleId, if desired.
+ //
+ if (pModuleId != NULL)
+ {
+ *pModuleId = (ModuleID)pMethDesc->GetModule();
+ }
+
+ //
+ // Fill in the ppvSig and pbSig, if desired
+ //
+ if (ppvSig != NULL && pbSig != NULL)
+ {
+ pMethDesc->GetSig(ppvSig, pbSig);
+ }
+
+ HRESULT hr = S_OK;
+
+ EX_TRY
+ {
+ if (wszName != NULL)
+ *wszName = 0;
+ if (pcchName != NULL)
+ *pcchName = 0;
+
+ StackSString ss;
+ ss.SetUTF8(pMethDesc->GetName());
+ ss.Normalize();
+ LPCWSTR methodName = ss.GetUnicode();
+
+ ULONG trueLen = (ULONG)(wcslen(methodName) + 1);
+
+ // Return name of method as required.
+ if (wszName && cchName > 0)
+ {
+ if (cchName < trueLen)
+ {
+ hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
+ }
+ else
+ {
+ wcsncpy_s(wszName, cchName, methodName, trueLen);
+ }
+ }
+
+ // If they request the actual length of the name
+ if (pcchName)
+ *pcchName = trueLen;
+ }
+ EX_CATCH_HRESULT(hr);
+
+ return (hr);
+}
+
+/*
* GetStringLayout
*
* This function describes to a profiler the internal layout of a string.
@@ -7081,12 +7375,13 @@ Loop:
// GC info will assist us in determining whether this is a non-EBP frame and
// info about pushed arguments.
- PTR_VOID gcInfo = codeInfo.GetGCInfo();
+ GCInfoToken gcInfoToken = codeInfo.GetGCInfoToken();
+ PTR_VOID gcInfo = gcInfoToken.Info;
InfoHdr header;
unsigned uiMethodSizeDummy;
PTR_CBYTE table = PTR_CBYTE(gcInfo);
table += decodeUnsigned(table, &uiMethodSizeDummy);
- table = decodeHeader(table, &header);
+ table = decodeHeader(table, gcInfoToken.Version, &header);
// Ok, GCInfo, can we do a simple EBP walk or what?
@@ -7235,18 +7530,13 @@ HRESULT ProfToEEInterfaceImpl::DoStackSnapshot(ThreadID thread,
ULONG32 contextSize)
{
-#ifdef _TARGET_ARM_
- // DoStackSnapshot is not supported on arm. Profilers can use OS apis to get the call stack.
- return E_NOTIMPL;
-#endif
-
-#if !defined(FEATURE_HIJACK) || !defined(PLATFORM_SUPPORTS_SAFE_THREADSUSPEND)
+#if !defined(FEATURE_HIJACK)
// DoStackSnapshot needs Thread::Suspend/ResumeThread functionality.
// On platforms w/o support for these APIs return E_NOTIMPL.
return E_NOTIMPL;
-#else // !defined(FEATURE_HIJACK) || !defined(PLATFORM_SUPPORTS_SAFE_THREADSUSPEND)
+#else // !defined(FEATURE_HIJACK)
CONTRACTL
{
@@ -7414,6 +7704,10 @@ HRESULT ProfToEEInterfaceImpl::DoStackSnapshot(ThreadID thread,
// First, check "1) Target thread to walk == current thread OR Target thread is suspended"
if (pThreadToSnapshot != pCurrentThread)
{
+#ifndef PLATFORM_SUPPORTS_SAFE_THREADSUSPEND
+ hr = E_NOTIMPL;
+ goto Cleanup;
+#else
// Walking separate thread, so it must be suspended. First, ensure that
// target thread exists.
//
@@ -7449,6 +7743,7 @@ HRESULT ProfToEEInterfaceImpl::DoStackSnapshot(ThreadID thread,
hr = CORPROF_E_STACKSNAPSHOT_UNSAFE;
goto Cleanup;
}
+#endif // !PLATFORM_SUPPORTS_SAFE_THREADSUSPEND
}
hostCallPreference =
@@ -7481,7 +7776,10 @@ HRESULT ProfToEEInterfaceImpl::DoStackSnapshot(ThreadID thread,
// (Note that this whole block is skipped if pThreadToSnapshot is in preemptive mode (the IF
// above), as the context is unused in such a case--the EE Frame chain is used
// to seed the walk instead.)
-
+#ifndef PLATFORM_SUPPORTS_SAFE_THREADSUSPEND
+ hr = E_NOTIMPL;
+ goto Cleanup;
+#else
if (!pThreadToSnapshot->GetSafelyRedirectableThreadContext(Thread::kDefaultChecks, &ctxCurrent, &rd))
{
LOG((LF_CORPROF, LL_INFO100, "**PROF: GetSafelyRedirectableThreadContext failure leads to CORPROF_E_STACKSNAPSHOT_UNSAFE.\n"));
@@ -7542,6 +7840,7 @@ HRESULT ProfToEEInterfaceImpl::DoStackSnapshot(ThreadID thread,
{
pctxSeed = &ctxCurrent;
}
+#endif // !PLATFORM_SUPPORTS_SAFE_THREADSUSPEND
}
// Second, check "2) Target thread to walk is currently executing JITted / NGENd code"
@@ -7588,6 +7887,10 @@ HRESULT ProfToEEInterfaceImpl::DoStackSnapshot(ThreadID thread,
//
if (pThreadToSnapshot != pCurrentThread)
{
+#ifndef PLATFORM_SUPPORTS_SAFE_THREADSUSPEND
+ hr = E_NOTIMPL;
+ goto Cleanup;
+#else
if (pctxSeed == NULL)
{
if (pThreadToSnapshot->GetSafelyRedirectableThreadContext(Thread::kDefaultChecks, &ctxCurrent, &rd))
@@ -7604,9 +7907,9 @@ HRESULT ProfToEEInterfaceImpl::DoStackSnapshot(ThreadID thread,
}
}
}
+#endif // !PLATFORM_SUPPORTS_SAFE_THREADSUSPEND
}
-#endif
-
+#endif //_DEBUG
// Third, verify the target thread is seeded or not in the midst of an unwind.
if (pctxSeed == NULL)
{
@@ -7671,12 +7974,13 @@ HRESULT ProfToEEInterfaceImpl::DoStackSnapshot(ThreadID thread,
INDEBUG(if (pCurrentThread) pCurrentThread->m_ulForbidTypeLoad = ulForbidTypeLoad;)
-
Cleanup:
+#if defined(PLATFORM_SUPPORTS_SAFE_THREADSUSPEND)
if (fResumeThread)
{
pThreadToSnapshot->ResumeThread();
}
+#endif // PLATFORM_SUPPORTS_SAFE_THREADSUSPEND
if (fResetSnapshotThreadExternalCount)
{
pThreadToSnapshot->DecExternalCountDANGEROUSProfilerOnly();
@@ -7684,7 +7988,7 @@ Cleanup:
return hr;
-#endif // !defined(FEATURE_HIJACK) || !defined(PLATFORM_SUPPORTS_SAFE_THREADSUSPEND)
+#endif // !defined(FEATURE_HIJACK)
}
@@ -8439,7 +8743,7 @@ HRESULT ProfToEEInterfaceImpl::RequestProfilerDetach(DWORD dwExpectedCompletionM
typedef struct _COR_PRF_ELT_INFO_INTERNAL
{
// Point to a platform dependent structure ASM helper push on the stack
- void * platformSpecificHandle;
+ void * platformSpecificHandle;
// startAddress of COR_PRF_FUNCTION_ARGUMENT_RANGE structure needs to point
// TO the argument value, not BE the argument value. So, when the argument
@@ -9461,7 +9765,7 @@ FCIMPL2(void, ProfilingFCallHelper::FC_RemotingClientSendingMessage, GUID *pId,
// it is a value class declared on the stack and so GC doesn't
// know about it.
- _ASSERTE (!GCHeap::GetGCHeap()->IsHeapPointer(pId)); // should be on the stack, not in the heap
+ _ASSERTE (!GCHeapUtilities::GetGCHeap()->IsHeapPointer(pId)); // should be on the stack, not in the heap
HELPER_METHOD_FRAME_BEGIN_NOPOLL();
{
diff --git a/src/vm/proftoeeinterfaceimpl.h b/src/vm/proftoeeinterfaceimpl.h
index 7bbd0bcf45..ed53ae2192 100644
--- a/src/vm/proftoeeinterfaceimpl.h
+++ b/src/vm/proftoeeinterfaceimpl.h
@@ -133,7 +133,7 @@ typedef struct _PROFILER_STACK_WALK_DATA PROFILER_STACK_WALK_DATA;
// from the profiler implementation. The profiler will call back on the v-table
// to get at EE internals as required.
-class ProfToEEInterfaceImpl : public ICorProfilerInfo7
+class ProfToEEInterfaceImpl : public ICorProfilerInfo8
{
public:
@@ -555,6 +555,28 @@ public:
// end ICorProfilerInfo7
+ // begin ICorProfilerInfo8
+
+ COM_METHOD IsFunctionDynamic(
+ FunctionID functionId,
+ BOOL *isDynamic);
+
+ COM_METHOD GetFunctionFromIP3(
+ LPCBYTE ip, // in
+ FunctionID * pFunctionId, // out
+ ReJITID * pReJitId); // out
+
+ COM_METHOD GetDynamicFunctionInfo(
+ FunctionID functionId,
+ ModuleID* moduleId,
+ PCCOR_SIGNATURE* ppvSig,
+ ULONG* pbSig,
+ ULONG cchName,
+ ULONG *pcchName,
+ WCHAR wszName[]);
+
+ // end ICorProfilerInfo8
+
protected:
// Internal Helper Functions
diff --git a/src/vm/rcwwalker.cpp b/src/vm/rcwwalker.cpp
index ad718126c1..0b875360fd 100644
--- a/src/vm/rcwwalker.cpp
+++ b/src/vm/rcwwalker.cpp
@@ -129,10 +129,10 @@ STDMETHODIMP CLRServicesImpl::GarbageCollect(DWORD dwFlags)
{
GCX_COOP_THREAD_EXISTS(GET_THREAD());
if (dwFlags & GC_FOR_APPX_SUSPEND) {
- GCHeap::GetGCHeap()->GarbageCollect(2, TRUE, collection_blocking | collection_optimized);
+ GCHeapUtilities::GetGCHeap()->GarbageCollect(2, TRUE, collection_blocking | collection_optimized);
}
else
- GCHeap::GetGCHeap()->GarbageCollect();
+ GCHeapUtilities::GetGCHeap()->GarbageCollect();
}
END_EXTERNAL_ENTRYPOINT;
return hr;
diff --git a/src/vm/readytoruninfo.cpp b/src/vm/readytoruninfo.cpp
index f867036823..a0e44ceaf3 100644
--- a/src/vm/readytoruninfo.cpp
+++ b/src/vm/readytoruninfo.cpp
@@ -401,6 +401,55 @@ static void LogR2r(const char *msg, PEFile *pFile)
#define DoLog(msg) if (s_r2rLogFile != NULL) LogR2r(msg, pFile)
+// Try to acquire an R2R image for exclusive use by a particular module.
+// Returns true if successful. Returns false if the image is already been used
+// by another module. Each R2R image has a space to store a pointer to the
+// module that owns it. We set this pointer unless it has already be
+// initialized to point to another Module.
+static bool AcquireImage(Module * pModule, PEImageLayout * pLayout, READYTORUN_HEADER * pHeader)
+{
+ STANDARD_VM_CONTRACT;
+
+ // First find the import sections of the image.
+ READYTORUN_IMPORT_SECTION * pImportSections = NULL;
+ READYTORUN_IMPORT_SECTION * pImportSectionsEnd = NULL;
+ READYTORUN_SECTION * pSections = (READYTORUN_SECTION*)(pHeader + 1);
+ for (DWORD i = 0; i < pHeader->NumberOfSections; i++)
+ {
+ if (pSections[i].Type == READYTORUN_SECTION_IMPORT_SECTIONS)
+ {
+ pImportSections = (READYTORUN_IMPORT_SECTION*)((PBYTE)pLayout->GetBase() + pSections[i].Section.VirtualAddress);
+ pImportSectionsEnd = (READYTORUN_IMPORT_SECTION*)((PBYTE)pImportSections + pSections[i].Section.Size);
+ break;
+ }
+ }
+
+ // Go through the import sections to find the import for the module pointer.
+ for (READYTORUN_IMPORT_SECTION * pCurSection = pImportSections; pCurSection < pImportSectionsEnd; pCurSection++)
+ {
+ // The import for the module pointer is always in an eager fixup section, so skip delayed fixup sections.
+ if ((pCurSection->Flags & READYTORUN_IMPORT_SECTION_FLAGS_EAGER) == 0)
+ continue;
+
+ // Found an eager fixup section. Check the signature of each fixup in this section.
+ PVOID *pFixups = (PVOID *)((PBYTE)pLayout->GetBase() + pCurSection->Section.VirtualAddress);
+ DWORD nFixups = pCurSection->Section.Size / sizeof(PVOID);
+ DWORD *pSignatures = (DWORD *)((PBYTE)pLayout->GetBase() + pCurSection->Signatures);
+ for (DWORD i = 0; i < nFixups; i++)
+ {
+ // See if we found the fixup for the Module pointer.
+ PBYTE pSig = (PBYTE)pLayout->GetBase() + pSignatures[i];
+ if (pSig[0] == READYTORUN_FIXUP_Helper && pSig[1] == READYTORUN_HELPER_Module)
+ {
+ Module * pPrevious = InterlockedCompareExchangeT(EnsureWritablePages((Module **)(pFixups + i)), pModule, NULL);
+ return pPrevious == NULL || pPrevious == pModule;
+ }
+ }
+ }
+
+ return false;
+}
+
PTR_ReadyToRunInfo ReadyToRunInfo::Initialize(Module * pModule, AllocMemTracker *pamTracker)
{
STANDARD_VM_CONTRACT;
@@ -478,6 +527,12 @@ PTR_ReadyToRunInfo ReadyToRunInfo::Initialize(Module * pModule, AllocMemTracker
return NULL;
}
+ if (!AcquireImage(pModule, pLayout, pHeader))
+ {
+ DoLog("Ready to Run disabled - module already loaded in another AppDomain");
+ return NULL;
+ }
+
LoaderHeap *pHeap = pModule->GetLoaderAllocator()->GetHighFrequencyHeap();
void * pMemory = pamTracker->Track(pHeap->AllocMem((S_SIZE_T)sizeof(ReadyToRunInfo)));
@@ -636,6 +691,22 @@ PCODE ReadyToRunInfo::GetEntryPoint(MethodDesc * pMD, BOOL fFixups /*=TRUE*/)
return NULL;
}
+#ifndef CROSSGEN_COMPILE
+#ifdef PROFILING_SUPPORTED
+ BOOL fShouldSearchCache = TRUE;
+ {
+ BEGIN_PIN_PROFILER(CORProfilerTrackCacheSearches());
+ g_profControlBlock.pProfInterface->
+ JITCachedFunctionSearchStarted((FunctionID)pMD, &fShouldSearchCache);
+ END_PIN_PROFILER();
+ }
+ if (!fShouldSearchCache)
+ {
+ return NULL;
+ }
+#endif // PROFILING_SUPPORTED
+#endif // CROSSGEN_COMPILE
+
uint id;
offset = m_nativeReader.DecodeUnsigned(offset, &id);
@@ -671,6 +742,17 @@ PCODE ReadyToRunInfo::GetEntryPoint(MethodDesc * pMD, BOOL fFixups /*=TRUE*/)
m_entryPointToMethodDescMap.InsertValue(PCODEToPINSTR(pEntryPoint), pMD);
}
+#ifndef CROSSGEN_COMPILE
+#ifdef PROFILING_SUPPORTED
+ {
+ BEGIN_PIN_PROFILER(CORProfilerTrackCacheSearches());
+ g_profControlBlock.pProfInterface->
+ JITCachedFunctionSearchFinished((FunctionID)pMD, COR_PRF_CACHED_FUNCTION_FOUND);
+ END_PIN_PROFILER();
+ }
+#endif // PROFILING_SUPPORTED
+#endif // CROSSGEN_COMPILE
+
if (g_pDebugInterface != NULL)
{
g_pDebugInterface->JITComplete(pMD, pEntryPoint);
diff --git a/src/vm/reflectioninvocation.cpp b/src/vm/reflectioninvocation.cpp
index de50514682..4edecdd2c6 100644
--- a/src/vm/reflectioninvocation.cpp
+++ b/src/vm/reflectioninvocation.cpp
@@ -2508,6 +2508,7 @@ FCIMPL1(void, ReflectionInvocation::PrepareContractedDelegate, Object * delegate
}
CONTRACTL_END;
+#ifdef FEATURE_CER
if (delegateUNSAFE == NULL)
return;
@@ -2517,9 +2518,11 @@ FCIMPL1(void, ReflectionInvocation::PrepareContractedDelegate, Object * delegate
PrepareDelegateHelper(&delegate, TRUE);
HELPER_METHOD_FRAME_END();
+#endif // FEATURE_CER
}
FCIMPLEND
+#ifdef FEATURE_CER
void ReflectionInvocation::PrepareDelegateHelper(OBJECTREF *pDelegate, BOOL onlyContractedMethod)
{
CONTRACTL {
@@ -2601,6 +2604,7 @@ void ReflectionInvocation::PrepareDelegateHelper(OBJECTREF *pDelegate, BOOL only
onlyContractedMethod);
}
}
+#endif // FEATURE_CER
FCIMPL0(void, ReflectionInvocation::ProbeForSufficientStack)
{
@@ -2637,7 +2641,6 @@ FCIMPL0(void, ReflectionInvocation::EnsureSufficientExecutionStack)
}
FCIMPLEND
-#ifdef FEATURE_CORECLR
// As with EnsureSufficientExecutionStack, this method checks and returns whether there is
// sufficient stack to execute the average Framework method, but rather than throwing,
// it simply returns a Boolean: true for sufficient stack space, otherwise false.
@@ -2654,7 +2657,6 @@ FCIMPL0(FC_BOOL_RET, ReflectionInvocation::TryEnsureSufficientExecutionStack)
FC_RETURN_BOOL(current >= limit);
}
FCIMPLEND
-#endif // FEATURE_CORECLR
struct ECWGCFContext
{
@@ -2849,6 +2851,7 @@ 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
@@ -2859,6 +2862,7 @@ FCIMPL3(void, ReflectionInvocation::ExecuteCodeWithGuaranteedCleanup, Object* co
// attempt to run the backout code.
PrepareMethodDesc(g_pExecuteBackoutCodeHelperMethod, Instantiation(), Instantiation(), FALSE, TRUE);
}
+#endif // FEATURE_CER
ExecuteCodeWithGuaranteedCleanupHelper(&gc);
diff --git a/src/vm/reflectioninvocation.h b/src/vm/reflectioninvocation.h
index fd14532091..7f72b61cd8 100644
--- a/src/vm/reflectioninvocation.h
+++ b/src/vm/reflectioninvocation.h
@@ -56,10 +56,8 @@ public:
#endif // !FEATURE_CORECLR
static FCDECL1(void, PrepareContractedDelegate, Object* delegateUNSAFE);
static FCDECL0(void, ProbeForSufficientStack);
- static FCDECL0(void, EnsureSufficientExecutionStack);
-#ifdef FEATURE_CORECLR // currently only used from mscorlib in FEATURE_CORECLR
- static FCDECL0(FC_BOOL_RET, TryEnsureSufficientExecutionStack);
-#endif // FEATURE_CORECLR
+ static FCDECL0(void, EnsureSufficientExecutionStack);
+ static FCDECL0(FC_BOOL_RET, TryEnsureSufficientExecutionStack);
static FCDECL3(void, ExecuteCodeWithGuaranteedCleanup, Object* pCodeDelegateUNSAFE, Object* pBackoutDelegateUNSAFE, Object* pUserDataUNSAFE);
// TypedReference functions, should go somewhere else
diff --git a/src/vm/rejit.cpp b/src/vm/rejit.cpp
index 6b3caa9091..0b6e922831 100644
--- a/src/vm/rejit.cpp
+++ b/src/vm/rejit.cpp
@@ -178,22 +178,22 @@ CrstStatic ReJitManager::s_csGlobalRequest;
//---------------------------------------------------------------------------------------
// Helpers
-inline DWORD JitFlagsFromProfCodegenFlags(DWORD dwCodegenFlags)
+inline CORJIT_FLAGS JitFlagsFromProfCodegenFlags(DWORD dwCodegenFlags)
{
LIMITED_METHOD_DAC_CONTRACT;
- DWORD jitFlags = 0;
+ CORJIT_FLAGS jitFlags;
// Note: COR_PRF_CODEGEN_DISABLE_INLINING is checked in
// code:CEEInfo::canInline#rejit (it has no equivalent CORJIT flag).
if ((dwCodegenFlags & COR_PRF_CODEGEN_DISABLE_ALL_OPTIMIZATIONS) != 0)
{
- jitFlags |= CORJIT_FLG_DEBUG_CODE;
+ jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE);
}
// In the future more flags may be added that need to be converted here (e.g.,
- // COR_PRF_CODEGEN_ENTERLEAVE / CORJIT_FLG_PROF_ENTERLEAVE)
+ // COR_PRF_CODEGEN_ENTERLEAVE / CORJIT_FLAG_PROF_ENTERLEAVE)
return jitFlags;
}
@@ -2170,8 +2170,7 @@ PCODE ReJitManager::DoReJit(ReJitInfo * pInfo)
pCodeOfRejittedCode = UnsafeJitFunction(
pInfo->GetMethodDesc(),
&ILHeader,
- JitFlagsFromProfCodegenFlags(pInfo->m_pShared->m_dwCodegenFlags),
- 0);
+ JitFlagsFromProfCodegenFlags(pInfo->m_pShared->m_dwCodegenFlags));
_ASSERTE(pCodeOfRejittedCode != NULL);
diff --git a/src/vm/rexcep.h b/src/vm/rexcep.h
index fe920bcd2d..1d1d9385f0 100644
--- a/src/vm/rexcep.h
+++ b/src/vm/rexcep.h
@@ -144,7 +144,11 @@ DEFINE_EXCEPTION(g_SystemNS, BadImageFormatException, true,
DEFINE_EXCEPTION(g_SystemNS, CannotUnloadAppDomainException, false, COR_E_CANNOTUNLOADAPPDOMAIN)
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)
diff --git a/src/vm/runtimecallablewrapper.cpp b/src/vm/runtimecallablewrapper.cpp
index d12d5568f6..359b6896bc 100644
--- a/src/vm/runtimecallablewrapper.cpp
+++ b/src/vm/runtimecallablewrapper.cpp
@@ -42,6 +42,7 @@ class Object;
#include "olevariant.h"
#include "interopconverter.h"
#include "constrainedexecutionregion.h"
+#include "typestring.h"
#ifdef FEATURE_REMOTING
#include "crossdomaincalls.h"
#endif
@@ -1591,7 +1592,7 @@ public:
if (pRCW->IsValid())
{
- if (!GCHeap::GetGCHeap()->IsPromoted(OBJECTREFToObject(pRCW->GetExposedObject())) &&
+ if (!GCHeapUtilities::GetGCHeap()->IsPromoted(OBJECTREFToObject(pRCW->GetExposedObject())) &&
!pRCW->IsDetached())
{
// No need to use InterlockedOr here since every other place that modifies the flags
@@ -1612,7 +1613,7 @@ void RCWCache::DetachWrappersWorker()
NOTHROW;
GC_NOTRIGGER;
MODE_ANY;
- PRECONDITION(GCHeap::IsGCInProgress()); // GC is in progress and the runtime is suspended
+ PRECONDITION(GCHeapUtilities::IsGCInProgress()); // GC is in progress and the runtime is suspended
}
CONTRACTL_END;
@@ -2808,7 +2809,7 @@ void RCW::MinorCleanup()
NOTHROW;
GC_NOTRIGGER;
MODE_ANY;
- PRECONDITION(GCHeap::IsGCInProgress() || ( (g_fEEShutDown & ShutDown_SyncBlock) && g_fProcessDetach ));
+ PRECONDITION(GCHeapUtilities::IsGCInProgress() || ( (g_fEEShutDown & ShutDown_SyncBlock) && g_fProcessDetach ));
}
CONTRACTL_END;
diff --git a/src/vm/safehandle.cpp b/src/vm/safehandle.cpp
index 3336e693b5..828b221025 100644
--- a/src/vm/safehandle.cpp
+++ b/src/vm/safehandle.cpp
@@ -246,7 +246,7 @@ void SafeHandle::Dispose()
// Suppress finalization on this object (we may be racing here but the
// operation below is idempotent and a dispose should never race a
// finalization).
- GCHeap::GetGCHeap()->SetFinalizationRun(OBJECTREFToObject(sh));
+ GCHeapUtilities::GetGCHeap()->SetFinalizationRun(OBJECTREFToObject(sh));
GCPROTECT_END();
}
@@ -394,7 +394,7 @@ FCIMPL1(void, SafeHandle::SetHandleAsInvalid, SafeHandle* refThisUNSAFE)
} while (InterlockedCompareExchange((LONG*)&sh->m_state, newState, oldState) != oldState);
- GCHeap::GetGCHeap()->SetFinalizationRun(OBJECTREFToObject(sh));
+ GCHeapUtilities::GetGCHeap()->SetFinalizationRun(OBJECTREFToObject(sh));
}
FCIMPLEND
diff --git a/src/vm/securityattributes.cpp b/src/vm/securityattributes.cpp
index 2c89540974..0facbbbfb3 100644
--- a/src/vm/securityattributes.cpp
+++ b/src/vm/securityattributes.cpp
@@ -304,9 +304,7 @@ void SecurityAttributes::EncodePermissionSet(IN OBJECTREF* pRef,
ppbData,
pcbData);
}
-#endif // FEATURE_CAS_POLICY
-#ifdef FEATURE_CAS_POLICY
static void SetupRestrictSecAttributes()
{
CONTRACTL {
@@ -334,7 +332,6 @@ static void SetupRestrictSecAttributes()
}
EX_END_CATCH(RethrowTerminalExceptions)
}
-#endif // FEATURE_CAS_POLICY
Assembly* SecurityAttributes::LoadAssemblyFromToken(IMetaDataAssemblyImport *pImport, mdAssemblyRef tkAssemblyRef)
{
@@ -1182,7 +1179,6 @@ void SecurityAttributes::AttrSetBlobToPermissionSets(
COMPlusThrowHR(hr);
}
-#ifdef FEATURE_CAS_POLICY
HRESULT SecurityAttributes::TranslateSecurityAttributesHelper(
CORSEC_ATTRSET *pAttrSet,
BYTE **ppbOutput,
@@ -1255,7 +1251,6 @@ HRESULT SecurityAttributes::TranslateSecurityAttributesHelper(
EX_CATCH_HRESULT(hr);
return hr;
}
-#endif // FEATURE_CAS_POLICY
// Call into managed code to group permissions into a PermissionSet and serialize it to XML
void SecurityAttributes::AttrArrayToPermissionSet(OBJECTREF* attrArray,
@@ -1354,7 +1349,7 @@ void SecurityAttributes::AttrArrayToPermissionSet(OBJECTREF* attrArray,
GCPROTECT_END();
}
-
+#endif // FEATURE_CAS_POLICY
//
// This is a public exported method
diff --git a/src/vm/securitydeclarativecache.cpp b/src/vm/securitydeclarativecache.cpp
index 29868f2b0c..dcfc1e0c4d 100644
--- a/src/vm/securitydeclarativecache.cpp
+++ b/src/vm/securitydeclarativecache.cpp
@@ -75,6 +75,7 @@ OBJECTREF PsetCacheEntry::CreateManagedPsetObject(DWORD dwAction, bool createEmp
MODE_COOPERATIVE;
} CONTRACTL_END;
+#ifdef FEATURE_CAS_POLICY
OBJECTREF orRet;
orRet = GetManagedPsetObject();
@@ -106,7 +107,6 @@ OBJECTREF PsetCacheEntry::CreateManagedPsetObject(DWORD dwAction, bool createEmp
} else {
-#ifdef FEATURE_CAS_POLICY
SecurityAttributes::XmlToPermissionSet(m_pKey->m_pbPset,
m_pKey->m_cbPset,
&gc.pset,
@@ -115,10 +115,6 @@ OBJECTREF PsetCacheEntry::CreateManagedPsetObject(DWORD dwAction, bool createEmp
0,
&gc.orNonCasPset,
&gc.orNonCasEncoding);
-#else
- // The v1.x serialized permission set format is not supported on CoreCLR
- COMPlusThrowHR(CORSECATTR_E_BAD_ATTRIBUTE);
-#endif //FEATURE_CAS_POLICY
}
StoreFirstObjectInHandle(m_handle, gc.pset);
@@ -135,6 +131,9 @@ OBJECTREF PsetCacheEntry::CreateManagedPsetObject(DWORD dwAction, bool createEmp
orRet = GetManagedPsetObject();
return orRet;
+#else
+ return NULL;
+#endif
}
#endif // CROSSGEN_COMPILE
diff --git a/src/vm/securityprincipal.h b/src/vm/securityprincipal.h
index 3bde5fd234..5d6b522a27 100644
--- a/src/vm/securityprincipal.h
+++ b/src/vm/securityprincipal.h
@@ -11,9 +11,11 @@
+#ifndef FEATURE_PAL
class COMPrincipal
{
public:
+#ifndef FEATURE_CORECLR
static
INT32 QCALLTYPE ImpersonateLoggedOnUser(HANDLE hToken);
@@ -24,6 +26,8 @@ public:
static
INT32 QCALLTYPE SetThreadToken(HANDLE hToken);
+#endif // !FEATURE_CORECLR
static void CLR_ImpersonateLoggedOnUser(HANDLE hToken);
};
+#endif // FEATURE_PAL
diff --git a/src/vm/siginfo.cpp b/src/vm/siginfo.cpp
index decd3c0aab..9adfb4998c 100644
--- a/src/vm/siginfo.cpp
+++ b/src/vm/siginfo.cpp
@@ -14,7 +14,7 @@
#include "clsload.hpp"
#include "vars.hpp"
#include "excep.h"
-#include "gc.h"
+#include "gcheaputilities.h"
#include "field.h"
#include "eeconfig.h"
#include "runtimehandles.h" // for SignatureNative
diff --git a/src/vm/stacksampler.cpp b/src/vm/stacksampler.cpp
index 270d278b66..d95adb1f63 100644
--- a/src/vm/stacksampler.cpp
+++ b/src/vm/stacksampler.cpp
@@ -154,7 +154,7 @@ bool IsGoodMethodDesc(MethodDesc* pMD)
//
// An opportunity to record the parameters passed to the JIT at the time of JITting this method.
/* static */
-void StackSampler::RecordJittingInfo(MethodDesc* pMD, DWORD dwFlags, DWORD dwFlags2)
+void StackSampler::RecordJittingInfo(MethodDesc* pMD, CORJIT_FLAGS flags)
{
WRAPPER_NO_CONTRACT;
if (g_pStackSampler == nullptr)
@@ -167,10 +167,10 @@ void StackSampler::RecordJittingInfo(MethodDesc* pMD, DWORD dwFlags, DWORD dwFla
return;
}
// Record in the hash map.
- g_pStackSampler->RecordJittingInfoInternal(pMD, dwFlags);
+ g_pStackSampler->RecordJittingInfoInternal(pMD, flags);
}
-void StackSampler::RecordJittingInfoInternal(MethodDesc* pMD, DWORD dwFlags)
+void StackSampler::RecordJittingInfoInternal(MethodDesc* pMD, CORJIT_FLAGS flags)
{
ADID dwDomainId = GetThread()->GetDomain()->GetId();
JitInfoHashEntry entry(pMD, dwDomainId);
@@ -426,7 +426,7 @@ void StackSampler::JitAndCollectTrace(MethodDesc* pMD, const ADID& adId)
// Indicate to the JIT or the JIT interface that we are JITting
// in the background for stack sampling.
- DWORD dwFlags2 = CORJIT_FLG2_SAMPLING_JIT_BACKGROUND;
+ CORJIT_FLAGS flags(CORJIT_FLAGS::CORJIT_FLAG_SAMPLING_JIT_BACKGROUND);
_ASSERTE(pMD->IsIL());
@@ -447,7 +447,7 @@ void StackSampler::JitAndCollectTrace(MethodDesc* pMD, const ADID& adId)
LOG((LF_JIT, LL_INFO100000, "%s:%s\n", pMD->GetMethodTable()->GetClass()->GetDebugClassName(), pMD->GetName()));
#endif
- PCODE pCode = UnsafeJitFunction(pMD, pDecoder, 0, dwFlags2);
+ PCODE pCode = UnsafeJitFunction(pMD, pDecoder, flags);
}
END_DOMAIN_TRANSITION;
diff --git a/src/vm/stacksampler.h b/src/vm/stacksampler.h
index 33fc6b93ce..0b9add1713 100644
--- a/src/vm/stacksampler.h
+++ b/src/vm/stacksampler.h
@@ -21,7 +21,7 @@ class StackSampler
public:
// Interface
static void Init();
- static void RecordJittingInfo(MethodDesc* pMD, DWORD dwFlags, DWORD dwFlags2);
+ static void RecordJittingInfo(MethodDesc* pMD, CORJIT_FLAGS flags);
private:
@@ -41,7 +41,7 @@ private:
void JitAndCollectTrace(MethodDesc* pMD, const ADID& adId);
- void RecordJittingInfoInternal(MethodDesc* pMD, DWORD flags);
+ void RecordJittingInfoInternal(MethodDesc* pMD, CORJIT_FLAGS flags);
ADID GetDomainId(MethodDesc* pMD, const ADID& defaultId);
diff --git a/src/vm/stackwalk.cpp b/src/vm/stackwalk.cpp
index 3b0b4720f7..18a8900039 100644
--- a/src/vm/stackwalk.cpp
+++ b/src/vm/stackwalk.cpp
@@ -2416,7 +2416,7 @@ StackWalkAction StackFrameIterator::NextRaw(void)
OBJECTREF orUnwind = NULL;
if (m_crawl.GetCodeManager()->IsInSynchronizedRegion(m_crawl.GetRelOffset(),
- m_crawl.GetGCInfo(),
+ m_crawl.GetGCInfoToken(),
m_crawl.GetCodeManagerFlags()))
{
if (pMD->IsStatic())
@@ -2560,7 +2560,9 @@ StackWalkAction StackFrameIterator::NextRaw(void)
// to recover from AVs during profiler stackwalk.)
PTR_VOID newSP = PTR_VOID((TADDR)GetRegdisplaySP(m_crawl.pRD));
+#ifndef NO_FIXED_STACK_LIMIT
FAIL_IF_SPECULATIVE_WALK(newSP >= m_crawl.pThread->GetCachedStackLimit());
+#endif // !NO_FIXED_STACK_LIMIT
FAIL_IF_SPECULATIVE_WALK(newSP < m_crawl.pThread->GetCachedStackBase());
#undef FAIL_IF_SPECULATIVE_WALK
@@ -2675,7 +2677,7 @@ StackWalkAction StackFrameIterator::NextRaw(void)
// We are transitioning from unmanaged code to managed code... lets do some validation of our
// EH mechanism on platforms that we can.
-#if defined(_DEBUG) && !defined(DACCESS_COMPILE) && defined(_TARGET_X86_)
+#if defined(_DEBUG) && !defined(DACCESS_COMPILE) && (defined(_TARGET_X86_) && !defined(FEATURE_STUBS_AS_IL))
VerifyValidTransitionFromManagedCode(m_crawl.pThread, &m_crawl);
#endif // _DEBUG && !DACCESS_COMPILE && _TARGET_X86_
}
@@ -3158,7 +3160,7 @@ void StackFrameIterator::PreProcessingForManagedFrames(void)
m_crawl.pFunc->IsSynchronized() &&
!m_crawl.pFunc->IsStatic() &&
m_crawl.GetCodeManager()->IsInSynchronizedRegion(m_crawl.GetRelOffset(),
- m_crawl.GetGCInfo(),
+ m_crawl.GetGCInfoToken(),
m_crawl.GetCodeManagerFlags()))
{
BEGIN_GCX_ASSERT_COOP;
diff --git a/src/vm/stackwalk.h b/src/vm/stackwalk.h
index 004d673a2a..f8bd519106 100644
--- a/src/vm/stackwalk.h
+++ b/src/vm/stackwalk.h
@@ -36,14 +36,14 @@ class AppDomain;
// on the stack. The FEF is used for unwinding. If not defined, the unwinding
// uses the exception context.
#define USE_FEF // to mark where code needs to be changed to eliminate the FEF
-#if defined(_TARGET_X86_)
+#if defined(_TARGET_X86_) && !defined(FEATURE_PAL)
#undef USE_FEF // Turn off the FEF use on x86.
#define ELIMINATE_FEF
#else
#if defined(ELIMINATE_FEF)
#undef ELIMINATE_FEF
#endif
-#endif // _86_
+#endif // _TARGET_X86_ && !FEATURE_PAL
//************************************************************************
// Enumerate all functions.
diff --git a/src/vm/stubcache.h b/src/vm/stubcache.h
index 781d46c8f5..b42ed16c25 100644
--- a/src/vm/stubcache.h
+++ b/src/vm/stubcache.h
@@ -50,7 +50,7 @@ public:
//---------------------------------------------------------
// Destructor
//---------------------------------------------------------
- ~StubCacheBase();
+ virtual ~StubCacheBase();
//---------------------------------------------------------
// Returns the equivalent hashed Stub, creating a new hash
diff --git a/src/vm/stubgen.cpp b/src/vm/stubgen.cpp
index fffa52a366..18a6c19480 100644
--- a/src/vm/stubgen.cpp
+++ b/src/vm/stubgen.cpp
@@ -631,15 +631,7 @@ ILStubLinker::LogILStubWorker(
}
}
-static inline void LogOneFlag(DWORD flags, DWORD flag, LPCSTR str, DWORD facility, DWORD level)
-{
- if (flags & flag)
- {
- LOG((facility, level, str));
- }
-}
-
-static void LogJitFlags(DWORD facility, DWORD level, DWORD dwJitFlags)
+static void LogJitFlags(DWORD facility, DWORD level, CORJIT_FLAGS jitFlags)
{
CONTRACTL
{
@@ -647,29 +639,28 @@ static void LogJitFlags(DWORD facility, DWORD level, DWORD dwJitFlags)
}
CONTRACTL_END;
- LOG((facility, level, "dwJitFlags: 0x%08x\n", dwJitFlags));
+ LOG((facility, level, "jitFlags:\n"));
-#define LOG_FLAG(name) LogOneFlag(dwJitFlags, name, " " #name "\n", facility, level);
+#define LOG_FLAG(name) \
+ if (jitFlags.IsSet(name)) \
+ { \
+ LOG((facility, level, " " #name "\n")); \
+ jitFlags.Clear(name); \
+ }
// these are all we care about at the moment
- LOG_FLAG(CORJIT_FLG_IL_STUB);
- LOG_FLAG(CORJIT_FLG_PUBLISH_SECRET_PARAM);
+ LOG_FLAG(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB);
+ LOG_FLAG(CORJIT_FLAGS::CORJIT_FLAG_PUBLISH_SECRET_PARAM);
#undef LOG_FLAGS
- DWORD dwKnownMask =
- CORJIT_FLG_IL_STUB |
- CORJIT_FLG_PUBLISH_SECRET_PARAM |
- NULL;
-
- DWORD dwUnknownFlags = dwJitFlags & ~dwKnownMask;
- if (0 != dwUnknownFlags)
+ if (!jitFlags.IsEmpty())
{
- LOG((facility, level, "UNKNOWN FLAGS: 0x%08x\n", dwUnknownFlags));
+ LOG((facility, level, "UNKNOWN FLAGS also set\n"));
}
}
-void ILStubLinker::LogILStub(DWORD dwJitFlags, SString *pDumpILStubCode)
+void ILStubLinker::LogILStub(CORJIT_FLAGS jitFlags, SString *pDumpILStubCode)
{
CONTRACTL
{
@@ -683,7 +674,7 @@ void ILStubLinker::LogILStub(DWORD dwJitFlags, SString *pDumpILStubCode)
INT iCurStack = 0;
if (pDumpILStubCode == NULL)
- LogJitFlags(LF_STUBS, LL_INFO1000, dwJitFlags);
+ LogJitFlags(LF_STUBS, LL_INFO1000, jitFlags);
while (pCurrentStream)
{
@@ -841,7 +832,7 @@ size_t ILStubLinker::Link(UINT* puMaxStack)
#ifdef _DEBUG
if (fStackUnderflow)
{
- LogILStub(NULL);
+ LogILStub(CORJIT_FLAGS());
CONSISTENCY_CHECK_MSG(false, "IL stack underflow! -- see logging output");
}
#endif // _DEBUG
diff --git a/src/vm/stubgen.h b/src/vm/stubgen.h
index e6d3f9ec4d..7bebfa7610 100644
--- a/src/vm/stubgen.h
+++ b/src/vm/stubgen.h
@@ -431,7 +431,7 @@ public:
void ClearCodeStreams();
- void LogILStub(DWORD dwJitFlags, SString *pDumpILStubCode = NULL);
+ void LogILStub(CORJIT_FLAGS jitFlags, SString *pDumpILStubCode = NULL);
protected:
void LogILStubWorker(ILInstruction* pInstrBuffer, UINT numInstr, size_t* pcbCode, INT* piCurStack, SString *pDumpILStubCode = NULL);
void LogILInstruction(size_t curOffset, bool isLabeled, INT iCurStack, ILInstruction* pInstruction, SString *pDumpILStubCode = NULL);
diff --git a/src/vm/stubhelpers.cpp b/src/vm/stubhelpers.cpp
index 6e7fb49b96..cbe1d37c94 100644
--- a/src/vm/stubhelpers.cpp
+++ b/src/vm/stubhelpers.cpp
@@ -19,7 +19,7 @@
#include "security.h"
#include "eventtrace.h"
#include "comdatetime.h"
-#include "gc.h"
+#include "gcheaputilities.h"
#include "interoputil.h"
#include "gcscan.h"
#ifdef FEATURE_REMOTING
@@ -70,7 +70,7 @@ void StubHelpers::ValidateObjectInternal(Object *pObjUNSAFE, BOOL fValidateNextO
// and the next object as required
if (fValidateNextObj)
{
- Object *nextObj = GCHeap::GetGCHeap()->NextObj(pObjUNSAFE);
+ Object *nextObj = GCHeapUtilities::GetGCHeap()->NextObj(pObjUNSAFE);
if (nextObj != NULL)
{
// Note that the MethodTable of the object (i.e. the pointer at offset 0) can change from
@@ -162,7 +162,7 @@ void StubHelpers::ProcessByrefValidationList()
{
entry = s_ByrefValidationEntries[i];
- Object *pObjUNSAFE = GCHeap::GetGCHeap()->GetGCHeap()->GetContainingObject(entry.pByref);
+ Object *pObjUNSAFE = GCHeapUtilities::GetGCHeap()->GetContainingObject(entry.pByref);
ValidateObjectInternal(pObjUNSAFE, TRUE);
}
}
@@ -2004,7 +2004,7 @@ FCIMPL3(void, StubHelpers::ValidateObject, Object *pObjUNSAFE, MethodDesc *pMD,
AVInRuntimeImplOkayHolder AVOkay;
// don't validate the next object if a BGC is in progress. we can race with background
// sweep which could make the next object a Free object underneath us if it's dead.
- ValidateObjectInternal(pObjUNSAFE, !(GCHeap::GetGCHeap()->IsConcurrentGCInProgress()));
+ ValidateObjectInternal(pObjUNSAFE, !(GCHeapUtilities::GetGCHeap()->IsConcurrentGCInProgress()));
}
EX_CATCH
{
@@ -2031,7 +2031,7 @@ FCIMPL3(void, StubHelpers::ValidateByref, void *pByref, MethodDesc *pMD, Object
// perform the validation on next GC (see code:StubHelpers.ProcessByrefValidationList).
// Skip byref if is not pointing inside managed heap
- if (!GCHeap::GetGCHeap()->IsHeapPointer(pByref))
+ if (!GCHeapUtilities::GetGCHeap()->IsHeapPointer(pByref))
{
return;
}
@@ -2066,7 +2066,7 @@ FCIMPL3(void, StubHelpers::ValidateByref, void *pByref, MethodDesc *pMD, Object
if (NumOfEntries > BYREF_VALIDATION_LIST_MAX_SIZE)
{
// if the list is too big, trigger GC now
- GCHeap::GetGCHeap()->GarbageCollect(0);
+ GCHeapUtilities::GetGCHeap()->GarbageCollect(0);
}
HELPER_METHOD_FRAME_END();
diff --git a/src/vm/syncblk.cpp b/src/vm/syncblk.cpp
index 3975542d98..171a8d3bb7 100644
--- a/src/vm/syncblk.cpp
+++ b/src/vm/syncblk.cpp
@@ -1372,7 +1372,7 @@ void SyncBlockCache::GCWeakPtrScan(HANDLESCANPROC scanProc, uintptr_t lp1, uintp
STRESS_LOG0 (LF_GC | LF_SYNC, LL_INFO100, "GCWeakPtrScan starting\n");
#endif
- if (GCHeap::GetGCHeap()->GetCondemnedGeneration() < GCHeap::GetGCHeap()->GetMaxGeneration())
+ if (GCHeapUtilities::GetGCHeap()->GetCondemnedGeneration() < GCHeapUtilities::GetGCHeap()->GetMaxGeneration())
{
#ifdef VERIFY_HEAP
//for VSW 294550: we saw stale obeject reference in SyncBlkCache, so we want to make sure the card
@@ -1416,7 +1416,7 @@ void SyncBlockCache::GCWeakPtrScan(HANDLESCANPROC scanProc, uintptr_t lp1, uintp
Object* o = SyncTableEntry::GetSyncTableEntry()[nb].m_Object;
if (o && !((size_t)o & 1))
{
- if (GCHeap::GetGCHeap()->IsEphemeral (o))
+ if (GCHeapUtilities::GetGCHeap()->IsEphemeral (o))
{
clear_card = FALSE;
@@ -1615,8 +1615,8 @@ void SyncBlockCache::GCDone(BOOL demoting, int max_gen)
CONTRACTL_END;
if (demoting &&
- (GCHeap::GetGCHeap()->GetCondemnedGeneration() ==
- GCHeap::GetGCHeap()->GetMaxGeneration()))
+ (GCHeapUtilities::GetGCHeap()->GetCondemnedGeneration() ==
+ GCHeapUtilities::GetGCHeap()->GetMaxGeneration()))
{
//scan the bitmap
size_t dw = 0;
@@ -1643,7 +1643,7 @@ void SyncBlockCache::GCDone(BOOL demoting, int max_gen)
Object* o = SyncTableEntry::GetSyncTableEntry()[nb].m_Object;
if (o && !((size_t)o & 1))
{
- if (GCHeap::GetGCHeap()->WhichGeneration (o) < (unsigned int)max_gen)
+ if (GCHeapUtilities::GetGCHeap()->WhichGeneration (o) < (unsigned int)max_gen)
{
SetCard (card);
break;
@@ -1713,7 +1713,7 @@ void SyncBlockCache::VerifySyncTableEntry()
DWORD idx = o->GetHeader()->GetHeaderSyncBlockIndex();
_ASSERTE(idx == nb || ((0 == idx) && (loop == max_iterations)));
- _ASSERTE(!GCHeap::GetGCHeap()->IsEphemeral(o) || CardSetP(CardOf(nb)));
+ _ASSERTE(!GCHeapUtilities::GetGCHeap()->IsEphemeral(o) || CardSetP(CardOf(nb)));
}
}
}
@@ -2498,10 +2498,10 @@ BOOL ObjHeader::Validate (BOOL bVerifySyncBlkIndex)
//BIT_SBLK_GC_RESERVE (0x20000000) is only set during GC. But for frozen object, we don't clean the bit
if (bits & BIT_SBLK_GC_RESERVE)
{
- if (!GCHeap::GetGCHeap()->IsGCInProgress () && !GCHeap::GetGCHeap()->IsConcurrentGCInProgress ())
+ if (!GCHeapUtilities::IsGCInProgress () && !GCHeapUtilities::GetGCHeap()->IsConcurrentGCInProgress ())
{
#ifdef FEATURE_BASICFREEZE
- ASSERT_AND_CHECK (GCHeap::GetGCHeap()->IsInFrozenSegment(obj));
+ ASSERT_AND_CHECK (GCHeapUtilities::GetGCHeap()->IsInFrozenSegment(obj));
#else //FEATURE_BASICFREEZE
_ASSERTE(!"Reserve bit not cleared");
return FALSE;
diff --git a/src/vm/syncclean.cpp b/src/vm/syncclean.cpp
index e02c2f90c2..133f448e16 100644
--- a/src/vm/syncclean.cpp
+++ b/src/vm/syncclean.cpp
@@ -73,7 +73,7 @@ void SyncClean::CleanUp ()
// Only GC thread can call this.
_ASSERTE (g_fProcessDetach ||
IsGCSpecialThread() ||
- (GCHeap::IsGCInProgress() && GetThread() == ThreadSuspend::GetSuspensionThread()));
+ (GCHeapUtilities::IsGCInProgress() && GetThread() == ThreadSuspend::GetSuspensionThread()));
if (m_HashMap)
{
Bucket * pTempBucket = FastInterlockExchangePointer(m_HashMap.GetPointer(), NULL);
diff --git a/src/vm/testhookmgr.cpp b/src/vm/testhookmgr.cpp
index 9ec53f8e45..48370134d2 100644
--- a/src/vm/testhookmgr.cpp
+++ b/src/vm/testhookmgr.cpp
@@ -655,7 +655,7 @@ HRESULT CLRTestHookManager::GC(int generation)
CONTRACTL_END;
_ASSERTE(GetThread()==NULL || !GetThread()->PreemptiveGCDisabled());
- GCHeap::GetGCHeap()->GarbageCollect(generation);
+ GCHeapUtilities::GetGCHeap()->GarbageCollect(generation);
FinalizerThread::FinalizerThreadWait();
return S_OK;
}
diff --git a/src/vm/threadpoolrequest.cpp b/src/vm/threadpoolrequest.cpp
index 8d47e6b810..a5c1c4263d 100644
--- a/src/vm/threadpoolrequest.cpp
+++ b/src/vm/threadpoolrequest.cpp
@@ -517,11 +517,11 @@ void UnManagedPerAppDomainTPCount::DispatchWorkItem(bool* foundWork, bool* wasNo
firstIteration = false;
*foundWork = true;
- if (GCHeap::IsGCInProgress(TRUE))
+ if (GCHeapUtilities::IsGCInProgress(TRUE))
{
// GC is imminent, so wait until GC is complete before executing next request.
// this reduces in-flight objects allocated right before GC, easing the GC's work
- GCHeap::WaitForGCCompletion(TRUE);
+ GCHeapUtilities::WaitForGCCompletion(TRUE);
}
PREFIX_ASSUME(pWorkRequest != NULL);
diff --git a/src/vm/threads.cpp b/src/vm/threads.cpp
index cc2e4eb5e4..38094ca8b5 100644
--- a/src/vm/threads.cpp
+++ b/src/vm/threads.cpp
@@ -18,7 +18,7 @@
#include "excep.h"
#include "comsynchronizable.h"
#include "log.h"
-#include "gc.h"
+#include "gcheaputilities.h"
#include "mscoree.h"
#include "dbginterface.h"
#include "corprof.h" // profiling
@@ -2022,8 +2022,10 @@ Thread::Thread()
m_ppvHJRetAddrPtr = (VOID**) 0xCCCCCCCCCCCCCCCC;
m_pvHJRetAddr = (VOID*) 0xCCCCCCCCCCCCCCCC;
+#ifndef PLATFORM_UNIX
X86_ONLY(m_LastRedirectIP = 0);
X86_ONLY(m_SpinCount = 0);
+#endif // PLATFORM_UNIX
#endif // FEATURE_HIJACK
#if defined(_DEBUG) && defined(TRACK_SYNC)
@@ -2232,7 +2234,7 @@ Thread::Thread()
m_fGCSpecial = FALSE;
-#if !defined(FEATURE_CORECLR)
+#if !defined(FEATURE_PAL)
m_wCPUGroup = 0;
m_pAffinityMask = 0;
#endif
@@ -3889,14 +3891,14 @@ void Thread::OnThreadTerminate(BOOL holdingLock)
#endif
}
- if (GCHeap::IsGCHeapInitialized())
+ if (GCHeapUtilities::IsGCHeapInitialized())
{
// Guaranteed to NOT be a shutdown case, because we tear down the heap before
// we tear down any threads during shutdown.
if (ThisThreadID == CurrentThreadID)
{
GCX_COOP();
- GCHeap::GetGCHeap()->FixAllocContext(&m_alloc_context, FALSE, NULL, NULL);
+ GCHeapUtilities::GetGCHeap()->FixAllocContext(&m_alloc_context, FALSE, NULL, NULL);
m_alloc_context.init();
}
}
@@ -3957,11 +3959,11 @@ void Thread::OnThreadTerminate(BOOL holdingLock)
#endif
}
- if (GCHeap::IsGCHeapInitialized() && ThisThreadID != CurrentThreadID)
+ 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.
- GCHeap::GetGCHeap()->FixAllocContext(&m_alloc_context, FALSE, NULL, NULL);
+ GCHeapUtilities::GetGCHeap()->FixAllocContext(&m_alloc_context, FALSE, NULL, NULL);
m_alloc_context.init();
}
@@ -8245,7 +8247,9 @@ void CheckRegDisplaySP (REGDISPLAY *pRD)
{
if (pRD->SP && pRD->_pThread)
{
+#ifndef NO_FIXED_STACK_LIMIT
_ASSERTE(PTR_VOID(pRD->SP) >= pRD->_pThread->GetCachedStackLimit());
+#endif // NO_FIXED_STACK_LIMIT
_ASSERTE(PTR_VOID(pRD->SP) < pRD->_pThread->GetCachedStackBase());
}
}
@@ -9159,89 +9163,7 @@ void Thread::ReturnToContextAndOOM(ContextTransitionFrame* pFrame)
COMPlusThrowOM();
}
-
-#ifdef FEATURE_CORECLR
-
-//---------------------------------------------------------------------------------------
-// Allocates an agile CrossAppDomainMarshaledException whose ToString() and ErrorCode
-// matches the original exception.
-//
-// This is our "remoting" story for exceptions that leak across appdomains in Telesto.
-//---------------------------------------------------------------------------------------
-static OBJECTREF WrapThrowableInCrossAppDomainMarshaledException(OBJECTREF pOriginalThrowable)
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- THROWS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- _ASSERTE(GetThread() != NULL);
-
-
- struct _gc
- {
- OBJECTREF pOriginalThrowable;
- OBJECTREF pThrowable;
- STRINGREF pOriginalMessage;
- }
- prot;
-
-
- memset(&prot, 0, sizeof(prot));
-
- GCPROTECT_BEGIN(prot);
- prot.pOriginalThrowable = pOriginalThrowable;
- prot.pOriginalMessage = GetExceptionMessage(prot.pOriginalThrowable);
- HRESULT originalHResult = GetExceptionHResult(prot.pOriginalThrowable);
-
- MethodTable *pMT = MscorlibBinder::GetClass(CLASS__CROSSAPPDOMAINMARSHALEDEXCEPTION);
- prot.pThrowable = AllocateObject(pMT);
-
- MethodDescCallSite exceptionCtor(METHOD__CROSSAPPDOMAINMARSHALEDEXCEPTION__STR_INT_CTOR);
-
- ARG_SLOT args1[] = {
- ObjToArgSlot(prot.pThrowable),
- ObjToArgSlot(prot.pOriginalMessage),
- (ARG_SLOT)originalHResult,
- };
- exceptionCtor.Call(args1);
-
-#ifndef FEATURE_PAL
- // Since, on CoreCLR, we dont have serialization of exceptions going across
- // AD transition boundaries, we will copy over the bucket details to the
- // CrossAppDomainMarshalledException object from the original exception object
- // if it isnt a preallocated exception.
- if (IsWatsonEnabled() && (!CLRException::IsPreallocatedExceptionObject(prot.pOriginalThrowable)))
- {
- // If the watson buckets are present, then copy them over.
- // They maybe missing if the original throwable couldnt get them from Watson helper functions
- // during SetupInitialThrowBucketDetails due to OOM.
- if (((EXCEPTIONREF)prot.pOriginalThrowable)->AreWatsonBucketsPresent())
- {
- _ASSERTE(prot.pThrowable != NULL);
- // Copy them to CrossADMarshalledException object
- CopyWatsonBucketsBetweenThrowables(prot.pOriginalThrowable, prot.pThrowable);
-
- // The exception object should now have the buckets inside it
- _ASSERTE(((EXCEPTIONREF)prot.pThrowable)->AreWatsonBucketsPresent());
- }
- }
-#endif // !FEATURE_PAL
-
- GCPROTECT_END(); //Prot
-
-
- return prot.pThrowable;
-}
-
-
-
-#endif
-
-
+#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)
@@ -9411,15 +9333,7 @@ Thread::TryRaiseCrossContextException(Exception **ppExOrig,
*ppThrowable = CLRException::GetThrowableFromException(exception);
_ASSERTE(*ppThrowable != NULL);
-#ifdef FEATURE_CORECLR
- (*pOrBlob) = WrapThrowableInCrossAppDomainMarshaledException(*ppThrowable);
-#if CHECK_APP_DOMAIN_LEAKS
- (*pOrBlob)->SetAppDomainAgile();
-#endif //CHECK_APP_DOMAIN_LEAKS
-#else
AppDomainHelper::MarshalObject(ppThrowable, pOrBlob);
-#endif //FEATURE_CORECLR
-
}
}
EX_CATCH
@@ -9598,6 +9512,25 @@ void DECLSPEC_NORETURN Thread::RaiseCrossContextException(Exception* pExOrig, Co
}
}
+#else // FEATURE_REMOTING
+
+void DECLSPEC_NORETURN Thread::RaiseCrossContextException(Exception* pExOrig, ContextTransitionFrame* pFrame)
+{
+ CONTRACTL
+ {
+ THROWS;
+ WRAPPER(GC_TRIGGERS);
+ }
+ CONTRACTL_END;
+
+ // pEx is NULL means that the exception is CLRLastThrownObjectException
+ CLRLastThrownObjectException lastThrown;
+ Exception* pException = pExOrig ? pExOrig : &lastThrown;
+ COMPlusThrow(CLRException::GetThrowableFromException(pException));
+}
+
+#endif
+
struct FindADCallbackType {
AppDomain *pSearchDomain;
AppDomain *pPrevDomain;
@@ -9846,7 +9779,7 @@ void Thread::DoExtraWorkForFinalizer()
Thread::CleanupDetachedThreads();
}
- if(ExecutionManager::IsCacheCleanupRequired() && GCHeap::GetGCHeap()->GetCondemnedGeneration()>=1)
+ if(ExecutionManager::IsCacheCleanupRequired() && GCHeapUtilities::GetGCHeap()->GetCondemnedGeneration()>=1)
{
ExecutionManager::ClearCaches();
}
@@ -11186,7 +11119,7 @@ void Thread::SetHasPromotedBytes ()
m_fPromoted = TRUE;
- _ASSERTE(GCHeap::IsGCInProgress() && IsGCThread ());
+ _ASSERTE(GCHeapUtilities::IsGCInProgress() && IsGCThread ());
if (!m_fPreemptiveGCDisabled)
{
@@ -11616,7 +11549,7 @@ HRESULT Thread::GetMemStats (COR_GC_THREAD_STATS *pStats)
CONTRACTL_END;
// Get the allocation context which contains this counter in it.
- alloc_context *p = &m_alloc_context;
+ 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;
diff --git a/src/vm/threads.h b/src/vm/threads.h
index ec047f2ddd..144e17c591 100644
--- a/src/vm/threads.h
+++ b/src/vm/threads.h
@@ -142,7 +142,7 @@
#include "regdisp.h"
#include "mscoree.h"
#include "appdomainstack.h"
-#include "gc.h"
+#include "gcheaputilities.h"
#include "gcinfotypes.h"
#include <clrhost.h>
@@ -1072,7 +1072,7 @@ class Thread: public IUnknown
friend DWORD MapWin32FaultToCOMPlusException(EXCEPTION_RECORD *pExceptionRecord);
friend void STDCALL OnHijackWorker(HijackArgs * pArgs);
#ifdef PLATFORM_UNIX
- friend void PALAPI HandleGCSuspensionForInterruptedThread(CONTEXT *interruptedContext);
+ friend void HandleGCSuspensionForInterruptedThread(CONTEXT *interruptedContext);
#endif // PLATFORM_UNIX
#endif // FEATURE_HIJACK
@@ -1739,9 +1739,9 @@ public:
// on MP systems, each thread has its own allocation chunk so we can avoid
// lock prefixes and expensive MP cache snooping stuff
- alloc_context m_alloc_context;
+ gc_alloc_context m_alloc_context;
- inline alloc_context *GetAllocContext() { LIMITED_METHOD_CONTRACT; return &m_alloc_context; }
+ inline gc_alloc_context *GetAllocContext() { LIMITED_METHOD_CONTRACT; return &m_alloc_context; }
// This is the type handle of the first object in the alloc context at the time
// we fire the AllocationTick event. It's only for tooling purpose.
@@ -2796,7 +2796,8 @@ public:
CONTRACTL_END;
return (ObjectFromHandle(m_ExposedObject) != NULL) ;
}
-#ifndef FEATURE_CORECLR
+
+#ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
void GetSynchronizationContext(OBJECTREF *pSyncContextObj)
{
CONTRACTL
@@ -2814,7 +2815,8 @@ public:
if (ExposedThreadObj != NULL)
*pSyncContextObj = ExposedThreadObj->GetSynchronizationContext();
}
-#endif //!FEATURE_CORECLR
+#endif // FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
+
#ifdef FEATURE_COMPRESSEDSTACK
OBJECTREF GetCompressedStack()
{
@@ -4884,7 +4886,7 @@ private:
private:
// When we create an object, or create an OBJECTREF, or create an Interior Pointer, or enter EE from managed
// code, we will set this flag.
- // Inside GCHeap::StressHeap, we only do GC if this flag is TRUE. Then we reset it to zero.
+ // Inside GCHeapUtilities::StressHeap, we only do GC if this flag is TRUE. Then we reset it to zero.
BOOL m_fStressHeapCount;
public:
void EnableStressHeap()
diff --git a/src/vm/threadsuspend.cpp b/src/vm/threadsuspend.cpp
index c71855f45f..2e6563da1e 100644
--- a/src/vm/threadsuspend.cpp
+++ b/src/vm/threadsuspend.cpp
@@ -754,6 +754,7 @@ 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)
{
@@ -775,6 +776,7 @@ static StackWalkAction TAStackCrawlCallBackWorker(CrawlFrame* pCf, StackCrawlCon
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).
@@ -1122,6 +1124,7 @@ struct CerStackCrawlContext
bool m_fWithinCer; // The result
};
+#ifdef FEATURE_CER
// Callback used on the stack crawl described above.
StackWalkAction CerStackCrawlCallBack(CrawlFrame *pCf, void *pData)
{
@@ -1164,6 +1167,7 @@ StackWalkAction CerStackCrawlCallBack(CrawlFrame *pCf, void *pData)
// 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)
@@ -1175,6 +1179,9 @@ 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);
@@ -1291,6 +1298,7 @@ BOOL Thread::IsWithinCer(CrawlFrame *pCf)
_ASSERTE(!sContext.m_fFirstFrame);
return sContext.m_fWithinCer;
+#endif // FEATURE_CER
}
#if defined(_TARGET_AMD64_) && defined(FEATURE_HIJACK)
@@ -3276,7 +3284,7 @@ void Thread::RareDisablePreemptiveGC()
__SwitchToThread(0, CALLER_LIMITS_SPINNING);
}
- if (!GCHeap::IsGCHeapInitialized())
+ if (!GCHeapUtilities::IsGCHeapInitialized())
{
goto Exit;
}
@@ -3284,7 +3292,7 @@ void Thread::RareDisablePreemptiveGC()
// 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
- if (((GCHeap::IsGCInProgress() && (this != ThreadSuspend::GetSuspensionThread())) ||
+ if (((GCHeapUtilities::IsGCInProgress() && (this != ThreadSuspend::GetSuspensionThread())) ||
(m_State & (TS_UserSuspendPending | TS_DebugSuspendPending | TS_StackCrawlNeeded))) &&
(!g_fSuspendOnShutdown || IsFinalizerThread() || IsShutdownSpecialThread()))
{
@@ -3350,7 +3358,7 @@ void Thread::RareDisablePreemptiveGC()
DWORD status = S_OK;
SetThreadStateNC(TSNC_WaitUntilGCFinished);
- status = GCHeap::GetGCHeap()->WaitUntilGCComplete();
+ status = GCHeapUtilities::GetGCHeap()->WaitUntilGCComplete();
ResetThreadStateNC(TSNC_WaitUntilGCFinished);
if (status == (DWORD)COR_E_STACKOVERFLOW)
@@ -3359,7 +3367,7 @@ void Thread::RareDisablePreemptiveGC()
// 1. GC is suspending the process. GC needs to wait.
// 2. GC is proceeding after suspension. The current thread needs to spin.
SetThreadState(TS_BlockGCForSO);
- while (GCHeap::IsGCInProgress() && m_fPreemptiveGCDisabled.Load() == 0)
+ while (GCHeapUtilities::IsGCInProgress() && m_fPreemptiveGCDisabled.Load() == 0)
{
#undef Sleep
// We can not go to a host for blocking operation due ot lack of stack.
@@ -3376,7 +3384,7 @@ void Thread::RareDisablePreemptiveGC()
break;
}
}
- if (!GCHeap::IsGCInProgress())
+ if (!GCHeapUtilities::IsGCInProgress())
{
if (HasThreadState(TS_StackCrawlNeeded))
{
@@ -3411,7 +3419,7 @@ void Thread::RareDisablePreemptiveGC()
// thread while in this loop. This happens if you use the COM+
// debugger to suspend this thread and then release it.
- } while ((GCHeap::IsGCInProgress() && (this != ThreadSuspend::GetSuspensionThread())) ||
+ } while ((GCHeapUtilities::IsGCInProgress() && (this != ThreadSuspend::GetSuspensionThread())) ||
(m_State & (TS_UserSuspendPending | TS_DebugSuspendPending | TS_StackCrawlNeeded)));
}
STRESS_LOG0(LF_SYNC, LL_INFO1000, "RareDisablePreemptiveGC: leaving\n");
@@ -3705,7 +3713,7 @@ void Thread::PerformPreemptiveGC()
if (!GCStressPolicy::IsEnabled() || !GCStress<cfg_transition>::IsEnabled())
return;
- if (!GCHeap::IsGCHeapInitialized())
+ if (!GCHeapUtilities::IsGCHeapInitialized())
return;
if (!m_GCOnTransitionsOK
@@ -3713,8 +3721,8 @@ void Thread::PerformPreemptiveGC()
|| RawGCNoTrigger()
#endif
|| g_fEEShutDown
- || GCHeap::IsGCInProgress(TRUE)
- || GCHeap::GetGCHeap()->GetGcCount() == 0 // Need something that works for isolated heap.
+ || GCHeapUtilities::IsGCInProgress(TRUE)
+ || GCHeapUtilities::GetGCHeap()->GetGcCount() == 0 // Need something that works for isolated heap.
|| ThreadStore::HoldingThreadStore())
return;
@@ -3738,7 +3746,7 @@ void Thread::PerformPreemptiveGC()
{
GCX_COOP();
m_bGCStressing = TRUE;
- GCHeap::GetGCHeap()->StressHeap();
+ GCHeapUtilities::GetGCHeap()->StressHeap();
m_bGCStressing = FALSE;
}
m_GCOnTransitionsOK = TRUE;
@@ -4846,7 +4854,7 @@ HRESULT ThreadSuspend::SuspendRuntime(ThreadSuspend::SUSPEND_REASON reason)
// Caller is expected to be holding the ThreadStore lock. Also, caller must
// have set GcInProgress before coming here, or things will break;
_ASSERTE(ThreadStore::HoldingThreadStore() || IsAtProcessExit());
- _ASSERTE(GCHeap::IsGCInProgress() );
+ _ASSERTE(GCHeapUtilities::IsGCInProgress() );
STRESS_LOG1(LF_SYNC, LL_INFO1000, "Thread::SuspendRuntime(reason=0x%x)\n", reason);
@@ -5547,7 +5555,7 @@ void ThreadSuspend::ResumeRuntime(BOOL bFinishedGC, BOOL SuspendSucceded)
// reset GcInProgress, or threads will continue to suspend themselves and won't
// be resumed until the next GC.
_ASSERTE(IsGCSpecialThread() || ThreadStore::HoldingThreadStore());
- _ASSERTE(!GCHeap::IsGCInProgress() );
+ _ASSERTE(!GCHeapUtilities::IsGCInProgress() );
STRESS_LOG2(LF_SYNC, LL_INFO1000, "Thread::ResumeRuntime(finishedGC=%d, SuspendSucceeded=%d) - Start\n", bFinishedGC, SuspendSucceded);
@@ -5564,7 +5572,7 @@ void ThreadSuspend::ResumeRuntime(BOOL bFinishedGC, BOOL SuspendSucceded)
{
// If we the suspension was for a GC, tell the host what generation GC.
DWORD Generation = (bFinishedGC
- ? GCHeap::GetGCHeap()->GetCondemnedGeneration()
+ ? GCHeapUtilities::GetGCHeap()->GetCondemnedGeneration()
: ~0U);
pGCThreadControl->SuspensionEnding(Generation);
@@ -5574,7 +5582,7 @@ void ThreadSuspend::ResumeRuntime(BOOL bFinishedGC, BOOL SuspendSucceded)
{
// If we the suspension was for a GC, tell the host what generation GC.
DWORD Generation = (bFinishedGC
- ? GCHeap::GetGCHeap()->GetCondemnedGeneration()
+ ? GCHeapUtilities::GetGCHeap()->GetCondemnedGeneration()
: ~0U);
BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
@@ -7275,18 +7283,8 @@ ReturnKind GetReturnKindFromMethodTable(Thread *pThread, EECodeInfo *codeInfo)
ReturnKind GetReturnKind(Thread *pThread, EECodeInfo *codeInfo)
{
- ReturnKind returnKind = RT_Illegal;
-
-#ifdef _TARGET_X86_
- // X86 GCInfo updates yet to be implemented.
-#else
GCInfoToken gcInfoToken = codeInfo->GetGCInfoToken();
- if (gcInfoToken.IsReturnKindAvailable())
- {
- GcInfoDecoder gcInfoDecoder(gcInfoToken, DECODE_RETURN_KIND);
- returnKind = gcInfoDecoder.GetReturnKind();
- }
-#endif // _TARGET_X86_
+ ReturnKind returnKind = codeInfo->GetCodeManager()->GetReturnKind(gcInfoToken);
if (!IsValidReturnKind(returnKind))
{
@@ -7312,7 +7310,7 @@ VOID * GetHijackAddr(Thread *pThread, EECodeInfo *codeInfo)
#ifdef _TARGET_X86_
if (returnKind == RT_Float)
{
- return reinterpret_cast<VOID *>(OnHijackTripThread);
+ return reinterpret_cast<VOID *>(OnHijackFPTripThread);
}
#endif // _TARGET_X86_
@@ -7898,7 +7896,7 @@ void ThreadSuspend::RestartEE(BOOL bFinishedGC, BOOL SuspendSucceded)
// Revert to being a normal thread
//
ClrFlsClearThreadType (ThreadType_DynamicSuspendEE);
- GCHeap::GetGCHeap()->SetGCInProgress(FALSE);
+ GCHeapUtilities::GetGCHeap()->SetGCInProgress(FALSE);
//
// Allow threads to enter COOP mode (though we still need to wake the ones
@@ -7906,7 +7904,7 @@ void ThreadSuspend::RestartEE(BOOL bFinishedGC, BOOL SuspendSucceded)
//
// Note: this is the last barrier that keeps managed threads
// from entering cooperative mode. If the sequence changes,
- // you may have to change routine GCHeap::SafeToRestartManagedThreads
+ // you may have to change routine GCHeapUtilities::SafeToRestartManagedThreads
// as well.
//
ThreadStore::TrapReturningThreads(FALSE);
@@ -7915,7 +7913,7 @@ void ThreadSuspend::RestartEE(BOOL bFinishedGC, BOOL SuspendSucceded)
//
// Any threads that are waiting in WaitUntilGCComplete will continue now.
//
- GCHeap::GetGCHeap()->GetWaitForGCEvent()->Set();
+ GCHeapUtilities::GetGCHeap()->GetWaitForGCEvent()->Set();
_ASSERTE(IsGCSpecialThread() || ThreadStore::HoldingThreadStore());
ResumeRuntime(bFinishedGC, SuspendSucceded);
@@ -7964,7 +7962,7 @@ void ThreadSuspend::SuspendEE(SUSPEND_REASON reason)
ETW::GCLog::ETW_GC_INFO Info;
Info.SuspendEE.Reason = reason;
Info.SuspendEE.GcCount = (((reason == SUSPEND_FOR_GC) || (reason == SUSPEND_FOR_GC_PREP)) ?
- (ULONG)GCHeap::GetGCHeap()->GetGcCount() : (ULONG)-1);
+ (ULONG)GCHeapUtilities::GetGCHeap()->GetGcCount() : (ULONG)-1);
FireEtwGCSuspendEEBegin_V1(Info.SuspendEE.Reason, Info.SuspendEE.GcCount, GetClrInstanceId());
@@ -8041,7 +8039,7 @@ retry_for_debugger:
//
// First, we reset the event that we're about to tell other threads to wait for.
//
- GCHeap::GetGCHeap()->GetWaitForGCEvent()->Reset();
+ GCHeapUtilities::GetGCHeap()->GetWaitForGCEvent()->Reset();
//
// Remember that we're the one doing the GC. Actually, maybe we're not doing a GC -
@@ -8066,7 +8064,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.
//
- GCHeap::GetGCHeap()->SetGCInProgress(TRUE);
+ GCHeapUtilities::GetGCHeap()->SetGCInProgress(TRUE);
//
// Gratuitous memory barrier. (may be needed - but I'm not sure why.)
@@ -8214,7 +8212,7 @@ retry_for_debugger:
// This function is called by PAL to check if the specified instruction pointer
// is in a function where we can safely inject activation.
-BOOL PALAPI CheckActivationSafePoint(SIZE_T ip, BOOL checkingCurrentThread)
+BOOL CheckActivationSafePoint(SIZE_T ip, BOOL checkingCurrentThread)
{
Thread *pThread = GetThread();
// It is safe to call the ExecutionManager::IsManagedCode only if we are making the check for
@@ -8241,7 +8239,7 @@ BOOL PALAPI CheckActivationSafePoint(SIZE_T ip, BOOL checkingCurrentThread)
// address to take the thread to the appropriate stub (based on the return
// type of the method) which will then handle preparing the thread for GC.
//
-void PALAPI HandleGCSuspensionForInterruptedThread(CONTEXT *interruptedContext)
+void HandleGCSuspensionForInterruptedThread(CONTEXT *interruptedContext)
{
Thread *pThread = GetThread();
@@ -8357,7 +8355,7 @@ void ThreadSuspend::Initialize()
BOOL Debug_IsLockedViaThreadSuspension()
{
LIMITED_METHOD_CONTRACT;
- return GCHeap::IsGCInProgress() &&
+ return GCHeapUtilities::IsGCInProgress() &&
(dbgOnly_IsSpecialEEThread() ||
IsGCSpecialThread() ||
GetThread() == ThreadSuspend::GetSuspensionThread());
@@ -8485,7 +8483,7 @@ void SuspendStatistics::EndSuspend(BOOL bForGC)
// details on suspends...
if (!bForGC)
cntNonGCSuspends++;
- if (GCHeap::GetGCHeap()->IsConcurrentGCInProgress())
+ if (GCHeapUtilities::GetGCHeap()->IsConcurrentGCInProgress())
{
cntSuspendsInBGC++;
if (!bForGC)
diff --git a/src/vm/typeparse.cpp b/src/vm/typeparse.cpp
index 356cb78423..28521f1839 100644
--- a/src/vm/typeparse.cpp
+++ b/src/vm/typeparse.cpp
@@ -364,7 +364,7 @@ HRESULT __stdcall TypeName::GetAssemblyName(BSTR* pszAssemblyName)
return hr;
}
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
+#if!defined(CROSSGEN_COMPILE)
SAFEHANDLE TypeName::GetSafeHandle()
{
CONTRACTL
@@ -588,7 +588,7 @@ void QCALLTYPE TypeName::QGetAssemblyName(TypeName * pTypeName, QCall::StringHan
END_QCALL;
}
-#endif //!FEATURE_CORECLR && !CROSSGEN_COMPILE
+#endif//!CROSSGEN_COMPILE
//
// TypeName::TypeNameParser
@@ -1926,7 +1926,7 @@ DomainAssembly * LoadDomainAssembly(
{
Exception *ex = GET_EXCEPTION();
- // Let non-File-not-found execeptions propagate
+ // Let non-File-not-found exceptions propagate
if (EEFileLoadException::GetFileLoadKind(ex->GetHR()) != kFileNotFoundException)
EX_RETHROW;
}
diff --git a/src/vm/typeparse.h b/src/vm/typeparse.h
index bf30730d46..00a3349ce2 100644
--- a/src/vm/typeparse.h
+++ b/src/vm/typeparse.h
@@ -311,14 +311,14 @@ public:
virtual ~TypeName();
public:
-#ifndef FEATURE_CORECLR
+#ifndef CROSSGEN_COMPILE
static void QCALLTYPE QCreateTypeNameParser (LPCWSTR wszTypeName, QCall::ObjectHandleOnStack pNames, BOOL throwOnError);
static void QCALLTYPE QReleaseTypeNameParser(TypeName * pTypeName);
static void QCALLTYPE QGetNames (TypeName * pTypeName, QCall::ObjectHandleOnStack pNames);
static void QCALLTYPE QGetTypeArguments (TypeName * pTypeName, QCall::ObjectHandleOnStack pTypeArguments);
static void QCALLTYPE QGetModifiers (TypeName * pTypeName, QCall::ObjectHandleOnStack pModifiers);
static void QCALLTYPE QGetAssemblyName (TypeName * pTypeName, QCall::StringHandleOnStack pAssemblyName);
-#endif //!FEATURE_CORECLR
+#endif //CROSSGEN_COMPILE
//-------------------------------------------------------------------------------------------
// Retrieves a type from an assembly. It requires the caller to know which assembly
@@ -451,10 +451,7 @@ private:
return GetTypeHaveAssemblyHelper(pAssembly, bThrowIfNotFound, bIgnoreCase, pKeepAlive, TRUE);
}
TypeHandle GetTypeHaveAssemblyHelper(Assembly* pAssembly, BOOL bThrowIfNotFound, BOOL bIgnoreCase, OBJECTREF *pKeepAlive, BOOL bRecurse);
-
-#ifndef FEATURE_CORECLR
SAFEHANDLE GetSafeHandle();
-#endif //!FEATURE_CORECLR
private:
BOOL m_bIsGenericArgument;
diff --git a/src/vm/util.cpp b/src/vm/util.cpp
index 2cb3460122..2cf6f7f31c 100644
--- a/src/vm/util.cpp
+++ b/src/vm/util.cpp
@@ -1950,17 +1950,18 @@ size_t GetLogicalProcessorCacheSizeFromOS()
// Crack the information. Iterate through all the SLPI array entries for all processors in system.
// Will return the greatest of all the processor cache sizes or zero
-
- size_t last_cache_size = 0;
-
- for (DWORD i=0; i < nEntries; i++)
{
- if (pslpi[i].Relationship == RelationCache)
+ size_t last_cache_size = 0;
+
+ for (DWORD i=0; i < nEntries; i++)
{
- last_cache_size = max(last_cache_size, pslpi[i].Cache.Size);
- }
- }
- cache_size = last_cache_size;
+ if (pslpi[i].Relationship == RelationCache)
+ {
+ last_cache_size = max(last_cache_size, pslpi[i].Cache.Size);
+ }
+ }
+ cache_size = last_cache_size;
+ }
Exit:
if(pslpi)
@@ -1991,6 +1992,9 @@ DWORD GetLogicalCpuCountFromOS()
DWORD nEntries = 0;
+ DWORD prevcount = 0;
+ DWORD count = 1;
+
// Try to use GetLogicalProcessorInformation API and get a valid pointer to the SLPI array if successful. Returns NULL
// if API not present or on failure.
SYSTEM_LOGICAL_PROCESSOR_INFORMATION *pslpi = IsGLPISupported(&nEntries) ;
@@ -2001,9 +2005,6 @@ DWORD GetLogicalCpuCountFromOS()
goto lDone;
}
- DWORD prevcount = 0;
- DWORD count = 1;
-
for (DWORD j = 0; j < nEntries; j++)
{
if (pslpi[j].Relationship == RelationProcessorCore)
@@ -2069,16 +2070,9 @@ lDone:
#define CACHE_PARTITION_BITS 0x003FF000 // number of cache Physical Partitions is returned in EBX[21:12] (10 bits) using cpuid function 4
#define CACHE_LINESIZE_BITS 0x00000FFF // Linesize returned in EBX[11:0] (12 bits) using cpuid function 4
-#if defined(_TARGET_X86_)
- // these are defined in cgenx86.cpp
- extern DWORD getcpuid(DWORD arg1, unsigned char result[16]);
- extern DWORD getextcpuid(DWORD arg1, DWORD arg2, unsigned char result[16]);
-#elif defined(_TARGET_AMD64_)
- // these are defined in src\VM\AMD64\asmhelpers.asm
- extern "C" DWORD __stdcall getcpuid(DWORD arg1, unsigned char result[16]);
- extern "C" DWORD __stdcall getextcpuid(DWORD arg1, DWORD arg2, unsigned char result[16]);
-#endif
-
+// these are defined in src\VM\AMD64\asmhelpers.asm / cgenx86.cpp
+extern "C" DWORD __stdcall getcpuid(DWORD arg1, unsigned char result[16]);
+extern "C" DWORD __stdcall getextcpuid(DWORD arg1, DWORD arg2, unsigned char result[16]);
// The following function uses a deterministic mechanism for enumerating/calculating the details of the cache hierarychy at runtime
// by using deterministic cache parameter leafs on Prescott and higher processors.
@@ -2557,7 +2551,7 @@ extern BOOL EEHeapFreeInProcessHeap(DWORD dwFlags, LPVOID lpMem);
extern void ShutdownRuntimeWithoutExiting(int exitCode);
extern BOOL IsRuntimeStarted(DWORD *pdwStartupFlags);
-void * GetCLRFunction(LPCSTR FunctionName)
+void * __stdcall GetCLRFunction(LPCSTR FunctionName)
{
void* func = NULL;
diff --git a/src/vm/vars.cpp b/src/vm/vars.cpp
index b737e66cd5..626ca3c9d3 100644
--- a/src/vm/vars.cpp
+++ b/src/vm/vars.cpp
@@ -69,6 +69,9 @@ 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);
@@ -79,8 +82,12 @@ 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);
@@ -98,7 +105,9 @@ 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);
diff --git a/src/vm/vars.hpp b/src/vm/vars.hpp
index d197e0559d..62d6656eaf 100644
--- a/src/vm/vars.hpp
+++ b/src/vm/vars.hpp
@@ -81,7 +81,7 @@ typedef unsigned short wchar_t;
class ClassLoader;
class LoaderHeap;
-class GCHeap;
+class IGCHeap;
class Object;
class StringObject;
class TransparentProxyObject;
@@ -402,6 +402,9 @@ 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);
@@ -414,8 +417,12 @@ 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);
@@ -431,7 +438,9 @@ 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);
diff --git a/src/vm/virtualcallstub.cpp b/src/vm/virtualcallstub.cpp
index 512b4f2b36..5fc66f6d6a 100644
--- a/src/vm/virtualcallstub.cpp
+++ b/src/vm/virtualcallstub.cpp
@@ -1107,7 +1107,7 @@ BOOL VirtualCallStubManager::TraceManager(Thread *thread,
#ifdef FEATURE_PREJIT
// This is the case for the lazy slot fixup
- if (GetIP(pContext) == GFN_TADDR(StubDispatchFixupPatchLabel)) {
+ if (GetIP(pContext) == GetEEFuncEntryPoint(StubDispatchFixupPatchLabel)) {
*pRetAddr = (BYTE *)StubManagerHelpers::GetReturnAddress(pContext);
diff --git a/src/vm/vm.settings b/src/vm/vm.settings
index b4799d1b37..83d7d9f72e 100644
--- a/src/vm/vm.settings
+++ b/src/vm/vm.settings
@@ -1,5 +1,12 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <!-- Work around problems with loading System.Private.CoreLib.dll, -->
+ <!-- caused by inconsistent setting of UseLegacyCompiler and FeatureSpanOfT -->
+ <!-- between System.Private.CoreLib.dll and the runtime. -->
+ <UseLegacyCompiler>true</UseLegacyCompiler>
+ </PropertyGroup>
+
<!--Import the settings-->
<Import Project="$(_NTDRIVE)$(_NTROOT)\ndp\clr\clr.props" />
<Import Project="$(_NTDRIVE)$(_NTROOT)\ndp\clr\src\debug\SetDebugTargetLocal.props" />
diff --git a/src/vm/win32threadpool.cpp b/src/vm/win32threadpool.cpp
index 1121417492..e8a05c383f 100644
--- a/src/vm/win32threadpool.cpp
+++ b/src/vm/win32threadpool.cpp
@@ -532,7 +532,9 @@ BOOL ThreadpoolMgr::SetMaxThreadsHelper(DWORD MaxWorkerThreads,
CrstHolder csh(&WorkerCriticalSection);
if (MaxWorkerThreads >= (DWORD)MinLimitTotalWorkerThreads &&
- MaxIOCompletionThreads >= (DWORD)MinLimitTotalCPThreads)
+ MaxIOCompletionThreads >= (DWORD)MinLimitTotalCPThreads &&
+ MaxWorkerThreads != 0 &&
+ MaxIOCompletionThreads != 0)
{
BEGIN_SO_INTOLERANT_CODE(GetThread());
@@ -2367,11 +2369,11 @@ Work:
counts = oldCounts;
}
- if (GCHeap::IsGCInProgress(TRUE))
+ if (GCHeapUtilities::IsGCInProgress(TRUE))
{
// GC is imminent, so wait until GC is complete before executing next request.
// this reduces in-flight objects allocated right before GC, easing the GC's work
- GCHeap::WaitForGCCompletion(TRUE);
+ GCHeapUtilities::WaitForGCCompletion(TRUE);
}
{
@@ -3677,6 +3679,8 @@ DWORD __stdcall ThreadpoolMgr::CompletionPortThreadStart(LPVOID lpArgs)
BOOL fThreadInit = FALSE;
Thread *pThread = NULL;
+ DWORD cpThreadWait = 0;
+
if (g_fEEStarted) {
pThread = SetupThreadNoThrow();
if (pThread == NULL) {
@@ -3711,7 +3715,7 @@ DWORD __stdcall ThreadpoolMgr::CompletionPortThreadStart(LPVOID lpArgs)
ThreadCounter::Counts oldCounts;
ThreadCounter::Counts newCounts;
- DWORD cpThreadWait = CP_THREAD_WAIT;
+ cpThreadWait = CP_THREAD_WAIT;
for (;; )
{
Top:
@@ -3986,7 +3990,7 @@ Top:
if (key != 0)
{
- if (GCHeap::IsGCInProgress(TRUE))
+ if (GCHeapUtilities::IsGCInProgress(TRUE))
{
//Indicate that this thread is free, and waiting on GC, not doing any user work.
//This helps in threads not getting injected when some threads have woken up from the
@@ -4003,7 +4007,7 @@ Top:
// GC is imminent, so wait until GC is complete before executing next request.
// this reduces in-flight objects allocated right before GC, easing the GC's work
- GCHeap::WaitForGCCompletion(TRUE);
+ GCHeapUtilities::WaitForGCCompletion(TRUE);
while (true)
{
@@ -4217,7 +4221,7 @@ BOOL ThreadpoolMgr::ShouldGrowCompletionPortThreadpool(ThreadCounter::Counts cou
if (counts.NumWorking >= counts.NumActive
&& NumCPInfrastructureThreads == 0
- && (counts.NumActive == 0 || !GCHeap::IsGCInProgress(TRUE))
+ && (counts.NumActive == 0 || !GCHeapUtilities::IsGCInProgress(TRUE))
)
{
// adjust limit if neeeded
@@ -4618,7 +4622,7 @@ DWORD __stdcall ThreadpoolMgr::GateThreadStart(LPVOID lpArgs)
EX_END_CATCH(SwallowAllExceptions);
}
- if (!GCHeap::IsGCInProgress(FALSE) )
+ if (!GCHeapUtilities::IsGCInProgress(FALSE) )
{
if (IgnoreNextSample)
{
@@ -4660,7 +4664,7 @@ DWORD __stdcall ThreadpoolMgr::GateThreadStart(LPVOID lpArgs)
oldCounts.NumActive < MaxLimitTotalCPThreads &&
!g_fCompletionPortDrainNeeded &&
NumCPInfrastructureThreads == 0 && // infrastructure threads count as "to be free as needed"
- !GCHeap::IsGCInProgress(TRUE))
+ !GCHeapUtilities::IsGCInProgress(TRUE))
{
BOOL status;
diff --git a/src/vm/win32threadpool.h b/src/vm/win32threadpool.h
index f712ef983d..6b4f1dfe07 100644
--- a/src/vm/win32threadpool.h
+++ b/src/vm/win32threadpool.h
@@ -505,22 +505,22 @@ public:
static BOOL UnregisterWaitEx(HANDLE hWaitObject,HANDLE CompletionEvent);
static void WaitHandleCleanup(HANDLE hWaitObject);
- static BOOL BindIoCompletionCallback(HANDLE FileHandle,
+ static BOOL WINAPI BindIoCompletionCallback(HANDLE FileHandle,
LPOVERLAPPED_COMPLETION_ROUTINE Function,
ULONG Flags,
DWORD& errorCode);
- static void WaitIOCompletionCallback(DWORD dwErrorCode,
+ static void WINAPI WaitIOCompletionCallback(DWORD dwErrorCode,
DWORD numBytesTransferred,
LPOVERLAPPED lpOverlapped);
- static VOID CallbackForInitiateDrainageOfCompletionPortQueue(
+ static VOID WINAPI CallbackForInitiateDrainageOfCompletionPortQueue(
DWORD dwErrorCode,
DWORD dwNumberOfBytesTransfered,
LPOVERLAPPED lpOverlapped
);
- static VOID CallbackForContinueDrainageOfCompletionPortQueue(
+ static VOID WINAPI CallbackForContinueDrainageOfCompletionPortQueue(
DWORD dwErrorCode,
DWORD dwNumberOfBytesTransfered,
LPOVERLAPPED lpOverlapped
diff --git a/src/vm/winrtredirector.h b/src/vm/winrtredirector.h
index 2561252ba9..f725ca8eb3 100644
--- a/src/vm/winrtredirector.h
+++ b/src/vm/winrtredirector.h
@@ -137,7 +137,7 @@ class WinRTDelegateRedirector
public:
static MethodTable *GetWinRTTypeForRedirectedDelegateIndex(WinMDAdapter::RedirectedTypeIndex index);
- static bool WinRTDelegateRedirector::ResolveRedirectedDelegate(MethodTable *pMT, WinMDAdapter::RedirectedTypeIndex *pIndex);
+ static bool ResolveRedirectedDelegate(MethodTable *pMT, WinMDAdapter::RedirectedTypeIndex *pIndex);
};
#endif // WINRT_DELEGATE_REDIRECTOR_H
diff --git a/src/vm/wks/wks.targets b/src/vm/wks/wks.targets
index 04562365f6..0df66fe558 100644
--- a/src/vm/wks/wks.targets
+++ b/src/vm/wks/wks.targets
@@ -107,6 +107,7 @@
<CppCompile Include="$(VmSourcesDir)\gcenv.os.cpp" />
<CppCompile Include="$(VmSourcesDir)\gchelpers.cpp" />
<CppCompile Include="$(VmSourcesDir)\gchost.cpp" />
+ <CppCompile Include="$(VmSourcesDir)\gcheaputilities.cpp" />
<CppCompile Include="$(VmSourcesDir)\genericdict.cpp" />
<CppCompile Include="$(VmSourcesDir)\generics.cpp" />
<CppCompile Include="$(VmSourcesDir)\genmeth.cpp" />
diff --git a/src/zap/zapcode.cpp b/src/zap/zapcode.cpp
index adad361de0..167c0ed912 100644
--- a/src/zap/zapcode.cpp
+++ b/src/zap/zapcode.cpp
@@ -1130,7 +1130,7 @@ void ZapUnwindInfo::Save(ZapWriter * pZapWriter)
pZapWriter->Write(&runtimeFunction, sizeof(runtimeFunction));
}
-#ifdef WIN64EXCEPTIONS
+#if defined(WIN64EXCEPTIONS) && !defined(_TARGET_X86_)
// Compare the unwind infos by their offset
int __cdecl ZapUnwindInfo::CompareUnwindInfo(const void* a_, const void* b_)
{
diff --git a/src/zap/zapheaders.cpp b/src/zap/zapheaders.cpp
index d8cd6fa7f9..2422c98a0b 100644
--- a/src/zap/zapheaders.cpp
+++ b/src/zap/zapheaders.cpp
@@ -249,19 +249,32 @@ void ZapImage::CopyWin32VersionResource()
void ZapDebugDirectory::SaveOriginalDebugDirectoryEntry(ZapWriter *pZapWriter)
{
- if (m_pDebugData != NULL)
+ if (m_ppDebugData != nullptr)
{
- m_debugDirectory.SizeOfData = m_pDebugData->GetSize();
- m_debugDirectory.AddressOfRawData = m_pDebugData->GetRVA();
+ for (DWORD i = 0; i < m_nDebugDirectory; i++)
+ {
+ if (m_ppDebugData[i] != nullptr)
+ {
+ m_pDebugDirectory[i].SizeOfData = m_ppDebugData[i]->GetSize();
+ m_pDebugDirectory[i].AddressOfRawData = m_ppDebugData[i]->GetRVA();
- // Compute the absolute file (seek) pointer. We need to reach to the matching physical section to do that.
- ZapPhysicalSection * pPhysicalSection = ZapImage::GetImage(pZapWriter)->m_pTextSection;
+ // Compute the absolute file (seek) pointer. We need to reach to the matching physical section to do that.
+ ZapPhysicalSection * pPhysicalSection = ZapImage::GetImage(pZapWriter)->m_pTextSection;
- DWORD dwOffset = m_pDebugData->GetRVA() - pPhysicalSection->GetRVA();
- _ASSERTE(dwOffset < pPhysicalSection->GetSize());
-
- m_debugDirectory.PointerToRawData = pPhysicalSection->GetFilePos() + dwOffset;
- pZapWriter->Write(&m_debugDirectory, sizeof(m_debugDirectory));
+ DWORD dwOffset = m_ppDebugData[i]->GetRVA() - pPhysicalSection->GetRVA();
+ _ASSERTE(dwOffset < pPhysicalSection->GetSize());
+
+ m_pDebugDirectory[i].PointerToRawData = pPhysicalSection->GetFilePos() + dwOffset;
+ }
+ else
+ {
+ m_pDebugDirectory[i].SizeOfData = 0;
+ m_pDebugDirectory[i].AddressOfRawData = 0;
+ m_pDebugDirectory[i].PointerToRawData = 0;
+ }
+ }
+
+ pZapWriter->Write(m_pDebugDirectory, sizeof(IMAGE_DEBUG_DIRECTORY) * m_nDebugDirectory);
}
}
@@ -270,7 +283,10 @@ void ZapDebugDirectory::SaveNGenDebugDirectoryEntry(ZapWriter *pZapWriter)
_ASSERTE(pZapWriter);
IMAGE_DEBUG_DIRECTORY debugDirectory = {0};
- memcpy(&debugDirectory, &m_debugDirectory, sizeof(IMAGE_DEBUG_DIRECTORY));
+ if (m_nDebugDirectory > 0)
+ {
+ memcpy(&debugDirectory, m_pDebugDirectory, sizeof(IMAGE_DEBUG_DIRECTORY));
+ }
debugDirectory.Type = IMAGE_DEBUG_TYPE_CODEVIEW;
debugDirectory.SizeOfData = m_pNGenPdbDebugData->GetSize();
debugDirectory.AddressOfRawData = m_pNGenPdbDebugData->GetRVA();
@@ -288,18 +304,49 @@ void ZapDebugDirectory::Save(ZapWriter * pZapWriter)
_ASSERTE(pZapWriter);
if (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_NGenEnableCreatePdb)) {
-
SaveOriginalDebugDirectoryEntry(pZapWriter);
SaveNGenDebugDirectoryEntry(pZapWriter);
-
} else {
-
SaveNGenDebugDirectoryEntry(pZapWriter);
SaveOriginalDebugDirectoryEntry(pZapWriter);
-
}
}
+ZapPEExports::ZapPEExports(LPCWSTR dllPath)
+{
+ m_dllFileName = wcsrchr(dllPath, DIRECTORY_SEPARATOR_CHAR_W);
+ if (m_dllFileName != NULL)
+ m_dllFileName++;
+ else
+ m_dllFileName = dllPath;
+}
+
+DWORD ZapPEExports::GetSize()
+{
+ return DWORD(sizeof(IMAGE_EXPORT_DIRECTORY) + wcslen(m_dllFileName) + 1);
+}
+
+void ZapPEExports::Save(ZapWriter * pZapWriter)
+{
+ _ASSERTE(pZapWriter);
+
+ IMAGE_EXPORT_DIRECTORY exports;
+ ZeroMemory(&exports, sizeof(exports));
+
+ exports.Name = pZapWriter->GetCurrentRVA() + sizeof(exports);
+
+ // Write out exports header
+ pZapWriter->Write(&exports, sizeof(exports));
+
+ // Write out string that exports.Name points at.
+ for (LPCWSTR ptr = m_dllFileName; ; ptr++)
+ {
+ pZapWriter->Write((PVOID) ptr, 1);
+ if (*ptr == 0)
+ break;
+ }
+}
+
// If the IL image has IMAGE_DIRECTORY_ENTRY_DEBUG with information about the PDB,
// copy that information over to the ngen image.
// This lets the debugger find out information about the PDB without loading
@@ -321,8 +368,9 @@ void ZapImage::CopyDebugDirEntry()
// IL PDB entry: copy of the (first of possibly many) IMAGE_DEBUG_DIRECTORY entry
// in the IL image
+ DWORD nDebugEntry = 0;
PIMAGE_DEBUG_DIRECTORY pDebugDir = NULL;
- ZapBlob *pDebugData = NULL;
+ ZapNode **ppDebugData = NULL;
if (m_ModuleDecoder.HasDirectoryEntry(IMAGE_DIRECTORY_ENTRY_DEBUG)) {
COUNT_T debugEntrySize;
@@ -339,40 +387,48 @@ void ZapImage::CopyDebugDirEntry()
// should be a multiple of sizeof(IMAGE_DEBUG_DIRECTORY).
_ASSERTE(0 == (debugEntrySize % sizeof(IMAGE_DEBUG_DIRECTORY)));
- // @TODO: pDebugEntry is an array of IMAGE_DEBUG_DIRECTORYs. Some tools
- // (like ibcmerge) add an extra dummy IMAGE_DEBUG_DIRECTORY to indicate
- // that the image was modified post-link.
- // We need to copy all the IMAGE_DEBUG_DIRECTORYs. For now, we only copy
- // the first one as it holds the relevant debug information.
-
- pDebugDir = PIMAGE_DEBUG_DIRECTORY(pDebugEntry);
-
- // Some compilers set PointerToRawData but not AddressOfRawData as they put the
- // data at the end of the file in an unmapped part of the file
+ nDebugEntry = DWORD(debugEntrySize / sizeof(IMAGE_DEBUG_DIRECTORY));
+ pDebugDir = new (GetHeap()) IMAGE_DEBUG_DIRECTORY[nDebugEntry];
+ memcpy(pDebugDir, (const void *)pDebugEntry, sizeof(IMAGE_DEBUG_DIRECTORY) * nDebugEntry);
+ ppDebugData = new (GetHeap()) ZapNode*[nDebugEntry];
+ memset(ppDebugData, 0, nDebugEntry * sizeof(ZapNode*));
- RVA rvaOfRawData = (pDebugDir->AddressOfRawData != NULL)
- ? pDebugDir->AddressOfRawData : m_ModuleDecoder.OffsetToRva(pDebugDir->PointerToRawData);
-
- ULONG cbDebugData = pDebugDir->SizeOfData;
-
- if (cbDebugData != 0) {
- if (!m_ModuleDecoder.CheckRva(rvaOfRawData, cbDebugData))
- m_zapper->Warning(W("IMAGE_DIRECTORY_ENTRY_DEBUG points to bad data\n"));
- else
- pDebugData = new (GetHeap()) ZapBlobPtr((PVOID)m_ModuleDecoder.GetRvaData(rvaOfRawData), cbDebugData);
+ for (DWORD i = 0; i < nDebugEntry; i++)
+ {
+ // Some compilers set PointerToRawData but not AddressOfRawData as they put the
+ // data at the end of the file in an unmapped part of the file
+
+ RVA rvaOfRawData = (pDebugDir[i].AddressOfRawData != NULL)
+ ? pDebugDir[i].AddressOfRawData : m_ModuleDecoder.OffsetToRva(pDebugDir[i].PointerToRawData);
+
+ ULONG cbDebugData = pDebugDir[i].SizeOfData;
+
+ if (cbDebugData != 0) {
+ if (!m_ModuleDecoder.CheckRva(rvaOfRawData, cbDebugData))
+ m_zapper->Warning(W("IMAGE_DIRECTORY_ENTRY_DEBUG points to bad data\n"));
+ else
+ ppDebugData[i] = new (GetHeap()) ZapBlobPtr((PVOID)m_ModuleDecoder.GetRvaData(rvaOfRawData), cbDebugData);
+ }
}
}
}
}
ZapDebugDirectory * pDebugDirectory = new (GetHeap()) ZapDebugDirectory(m_pNGenPdbDebugData,
- pDebugData ? pDebugDir : NULL,
- pDebugData);
+ nDebugEntry,
+ pDebugDir,
+ ppDebugData);
m_pDebugSection->Place(pDebugDirectory);
m_pDebugSection->Place(m_pNGenPdbDebugData);
- if (pDebugData)
- m_pDebugSection->Place(pDebugData);
+ if (ppDebugData)
+ {
+ for (DWORD i = 0; i < nDebugEntry; i++)
+ {
+ if (ppDebugData[i] != nullptr)
+ m_pDebugSection->Place(ppDebugData[i]);
+ }
+ }
SetDirectoryEntry(IMAGE_DIRECTORY_ENTRY_DEBUG, pDebugDirectory);
}
diff --git a/src/zap/zapheaders.h b/src/zap/zapheaders.h
index 12b0a18a3d..0755c0ed2d 100644
--- a/src/zap/zapheaders.h
+++ b/src/zap/zapheaders.h
@@ -234,23 +234,22 @@ public:
class ZapDebugDirectory : public ZapNode
{
ZapNode * m_pNGenPdbDebugData;
- IMAGE_DEBUG_DIRECTORY m_debugDirectory;
- ZapNode * m_pDebugData;
+ DWORD m_nDebugDirectory;
+ IMAGE_DEBUG_DIRECTORY * m_pDebugDirectory;
+ ZapNode ** m_ppDebugData;
public:
- ZapDebugDirectory(ZapNode *pNGenPdbDebugData, PIMAGE_DEBUG_DIRECTORY pDebugDirectory, ZapNode * pDebugData)
+ ZapDebugDirectory(ZapNode *pNGenPdbDebugData, DWORD nDebugDirectory, PIMAGE_DEBUG_DIRECTORY pDebugDirectory, ZapNode ** ppDebugData)
: m_pNGenPdbDebugData(pNGenPdbDebugData),
- m_pDebugData(pDebugData)
+ m_nDebugDirectory(nDebugDirectory),
+ m_pDebugDirectory(pDebugDirectory),
+ m_ppDebugData(ppDebugData)
{
- if (pDebugDirectory == NULL)
- memset(&m_debugDirectory, 0, sizeof(IMAGE_DEBUG_DIRECTORY));
- else
- memcpy(&m_debugDirectory, pDebugDirectory, sizeof(IMAGE_DEBUG_DIRECTORY));
}
virtual DWORD GetSize()
{
- return m_pDebugData ? sizeof(IMAGE_DEBUG_DIRECTORY) * 2 : sizeof(IMAGE_DEBUG_DIRECTORY);
+ return sizeof(IMAGE_DEBUG_DIRECTORY) * (m_nDebugDirectory + 1);
}
virtual UINT GetAlignment()
@@ -269,6 +268,23 @@ public:
};
//
+// PE Style exports. Currently can only save an empty list of exports
+// but this is useful because it avoids the DLL being seen as Resource Only
+// (which then causes SymServer to avoid copying its PDB to the cloud).
+//
+
+class ZapPEExports : public ZapNode
+{
+ LPCWSTR m_dllFileName; // Just he DLL name without the path.
+
+public:
+ ZapPEExports(LPCWSTR dllPath);
+ virtual DWORD GetSize();
+ virtual UINT GetAlignment() { return sizeof(DWORD); }
+ virtual void Save(ZapWriter * pZapWriter);
+};
+
+//
// List of all sections for diagnostic purposes
class ZapVirtualSectionsTable : public ZapNode
diff --git a/src/zap/zapimage.cpp b/src/zap/zapimage.cpp
index a435d6a44d..f39b8f8f54 100644
--- a/src/zap/zapimage.cpp
+++ b/src/zap/zapimage.cpp
@@ -291,6 +291,12 @@ void ZapImage::InitializeSectionsForReadyToRun()
// Always allocate slot for module - it is used to determine that the image is used
//
m_pImportTable->GetPlacedHelperImport(READYTORUN_HELPER_Module);
+
+ //
+ // Make sure the import sections table is in the image, so we can find the slot for module
+ //
+ _ASSERTE(m_pImportSectionsTable->GetSize() != 0);
+ GetReadyToRunHeader()->RegisterSection(READYTORUN_SECTION_IMPORT_SECTIONS, m_pImportSectionsTable);
}
#endif // FEATURE_READYTORUN_COMPILER
@@ -395,7 +401,7 @@ void ZapImage::AllocateVirtualSections()
//
// If we're instrumenting allocate a section for writing profile data
//
- if (m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_BBINSTR)
+ if (m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_BBINSTR))
{
m_pInstrumentSection = NewVirtualSection(pDataSection, IBCUnProfiledSection | ColdRange | InstrumentSection, sizeof(TADDR));
}
@@ -1163,6 +1169,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);
+
ComputeRVAs();
if (!IsReadyToRunCompilation())
@@ -1697,16 +1711,16 @@ void ZapImage::OutputTables()
SetSizeOfStackCommit(m_ModuleDecoder.GetSizeOfStackCommit());
}
-#if defined(_TARGET_ARM_) && defined(FEATURE_CORECLR) && defined(FEATURE_CORESYSTEM)
+#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)
if (!IsReadyToRunCompilation())
{
// On ARM CoreSys builds, crossgen will use 4k file alignment, as requested by Phone perf team
// to improve perf on phones with compressed system partitions.
SetFileAlignment(0x1000);
}
-#elif defined(FEATURE_PAL)
- // PAL library requires native image sections to align to page bounaries.
- SetFileAlignment(0x1000);
#endif
}
@@ -1935,23 +1949,24 @@ struct CompileMethodStubContext
//-----------------------------------------------------------------------------
// static void __stdcall
-void ZapImage::TryCompileMethodStub(LPVOID pContext, CORINFO_METHOD_HANDLE hStub, DWORD dwJitFlags)
+void ZapImage::TryCompileMethodStub(LPVOID pContext, CORINFO_METHOD_HANDLE hStub, CORJIT_FLAGS jitFlags)
{
STANDARD_VM_CONTRACT;
// The caller must always set the IL_STUB flag
- _ASSERTE((dwJitFlags & CORJIT_FLG_IL_STUB) != 0);
+ _ASSERTE(jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB));
CompileMethodStubContext *pCompileContext = reinterpret_cast<CompileMethodStubContext *>(pContext);
ZapImage *pImage = pCompileContext->pImage;
- unsigned oldFlags = pImage->m_zapper->m_pOpt->m_compilerFlags;
+ CORJIT_FLAGS oldFlags = pImage->m_zapper->m_pOpt->m_compilerFlags;
- pImage->m_zapper->m_pOpt->m_compilerFlags |= dwJitFlags;
- pImage->m_zapper->m_pOpt->m_compilerFlags &= ~(CORJIT_FLG_PROF_ENTERLEAVE |
- CORJIT_FLG_DEBUG_CODE |
- CORJIT_FLG_DEBUG_EnC |
- CORJIT_FLG_DEBUG_INFO);
+ CORJIT_FLAGS* pCompilerFlags = &pImage->m_zapper->m_pOpt->m_compilerFlags;
+ pCompilerFlags->Add(jitFlags);
+ pCompilerFlags->Clear(CORJIT_FLAGS::CORJIT_FLAG_PROF_ENTERLEAVE);
+ pCompilerFlags->Clear(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE);
+ pCompilerFlags->Clear(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_EnC);
+ pCompilerFlags->Clear(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_INFO);
mdMethodDef md = mdMethodDefNil;
@@ -2191,7 +2206,7 @@ ZapImage::CompileStatus ZapImage::TryCompileMethodWorker(CORINFO_METHOD_HANDLE h
if (GetCompiledMethod(handle) != NULL)
return ALREADY_COMPILED;
- _ASSERTE((m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_IL_STUB) || IsNilToken(md) || handle == m_pPreloader->LookupMethodDef(md));
+ _ASSERTE(m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB) || IsNilToken(md) || handle == m_pPreloader->LookupMethodDef(md));
CompileStatus result = NOT_COMPILED;
@@ -2205,7 +2220,7 @@ ZapImage::CompileStatus ZapImage::TryCompileMethodWorker(CORINFO_METHOD_HANDLE h
CORINFO_MODULE_HANDLE module;
// We only compile IL_STUBs from the current assembly
- if (m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_IL_STUB)
+ if (m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB))
module = m_hModule;
else
module = m_zapper->m_pEEJitInfo->getMethodModule(handle);
@@ -2263,7 +2278,7 @@ ZapImage::CompileStatus ZapImage::TryCompileMethodWorker(CORINFO_METHOD_HANDLE h
if (m_stats != NULL)
{
- if ((m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_IL_STUB) == 0)
+ if (!m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB))
m_stats->m_failedMethods++;
else
m_stats->m_failedILStubs++;
@@ -2496,7 +2511,7 @@ HRESULT ZapImage::LocateProfileData()
// the final image.
//
#if 0
- if ((m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_BBINSTR) != 0)
+ if (m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_BBINSTR))
return S_FALSE;
#endif
@@ -3473,7 +3488,7 @@ bool ZapImage::canIntraModuleDirectCall(
// No direct calls at all under some circumstances
- if ((m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_PROF_ENTERLEAVE)
+ if (m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_PROF_ENTERLEAVE)
&& !m_pPreloader->IsDynamicMethod(callerFtn))
{
*pReason = CORINFO_INDIRECT_CALL_PROFILING;
diff --git a/src/zap/zapimage.h b/src/zap/zapimage.h
index 842791805d..02985f5d12 100644
--- a/src/zap/zapimage.h
+++ b/src/zap/zapimage.h
@@ -656,7 +656,7 @@ public:
NOT_COMPILED = 0, COMPILE_EXCLUDED = 1, // Info
COMPILE_SUCCEED = 10, ALREADY_COMPILED = 11}; // Success
- static void __stdcall TryCompileMethodStub(LPVOID pContext, CORINFO_METHOD_HANDLE hStub, DWORD dwJitFlags);
+ static void __stdcall TryCompileMethodStub(LPVOID pContext, CORINFO_METHOD_HANDLE hStub, CORJIT_FLAGS jitFlags);
BOOL IsVTableGapMethod(mdMethodDef md);
diff --git a/src/zap/zapinfo.cpp b/src/zap/zapinfo.cpp
index 232570f09d..d2362d4b90 100644
--- a/src/zap/zapinfo.cpp
+++ b/src/zap/zapinfo.cpp
@@ -141,13 +141,13 @@ void ZapInfo::InitMethodName()
m_currentMethodName.AppendUTF8(szMethodName);
}
-int ZapInfo::ComputeJitFlags(CORINFO_METHOD_HANDLE handle)
+CORJIT_FLAGS ZapInfo::ComputeJitFlags(CORINFO_METHOD_HANDLE handle)
{
- int jitFlags = m_zapper->m_pOpt->m_compilerFlags;
+ CORJIT_FLAGS jitFlags = m_zapper->m_pOpt->m_compilerFlags;
- DWORD flags = 0;
+ CORJIT_FLAGS flags;
IfFailThrow(m_pEECompileInfo->GetBaseJitFlags(handle, &flags));
- jitFlags |= flags;
+ jitFlags.Add(flags);
// COMPlus_JitFramed specifies the default fpo setting for jitted and NGened code.
// You can override the behavior for NGened code using COMPlus_NGenFramed.
@@ -156,52 +156,56 @@ int ZapInfo::ComputeJitFlags(CORINFO_METHOD_HANDLE handle)
if (dwNGenFramed == 0)
{
// NGened code should enable fpo
- jitFlags &= ~CORJIT_FLG_FRAMED;
+ jitFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_FRAMED);
}
else if (dwNGenFramed == 1)
{
// NGened code should disable fpo
- jitFlags |= CORJIT_FLG_FRAMED;
+ jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_FRAMED);
}
if (canSkipMethodVerification(m_currentMethodHandle) == CORINFO_VERIFICATION_CAN_SKIP)
{
- jitFlags |= CORJIT_FLG_SKIP_VERIFICATION;
+ jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION);
}
if (m_pImage->m_profileDataSections[MethodBlockCounts].pData &&
!m_zapper->m_pOpt->m_ignoreProfileData)
{
- jitFlags |= CORJIT_FLG_BBOPT;
+ jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_BBOPT);
}
//
// By default we always enable Hot/Cold procedure splitting
//
- jitFlags |= CORJIT_FLG_PROCSPLIT;
+ jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_PROCSPLIT);
if (m_zapper->m_pOpt->m_noProcedureSplitting)
- jitFlags &= ~CORJIT_FLG_PROCSPLIT;
+ jitFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_PROCSPLIT);
//never emit inlined polls for NGen'd code. The extra indirection is not optimal.
- if (jitFlags & CORJIT_FLG_GCPOLL_INLINE)
+ if (jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_GCPOLL_INLINE))
{
- jitFlags &= ~CORJIT_FLG_GCPOLL_INLINE;
- jitFlags |= CORJIT_FLG_GCPOLL_CALLS;
+ jitFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_GCPOLL_INLINE);
+ jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_GCPOLL_CALLS);
}
// If the method is specified for min-opts then turn everything off
- if (jitFlags & CORJIT_FLG_MIN_OPT)
- jitFlags &= ~(CORJIT_FLG_BBINSTR | CORJIT_FLG_BBOPT | CORJIT_FLG_PROCSPLIT);
+ if (jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_MIN_OPT))
+ {
+ jitFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_BBINSTR);
+ jitFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_BBOPT);
+ jitFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_PROCSPLIT);
+ }
// Rejit is now enabled by default for NGEN'ed code. This costs us
// some size in exchange for diagnostic functionality, but we've got
// further work planned that should mitigate the size increase.
- jitFlags |= CORJIT_FLG_PROF_REJIT_NOPS;
+ jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_PROF_REJIT_NOPS);
#ifdef FEATURE_READYTORUN_COMPILER
if (IsReadyToRunCompilation())
- jitFlags |= CORJIT_FLG_READYTORUN;
+ jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_READYTORUN);
#endif
return jitFlags;
@@ -427,14 +431,13 @@ void ZapInfo::CompileMethod()
// this they can add the hint and reduce the perf cost at runtime.
m_pImage->m_pPreloader->PrePrepareMethodIfNecessary(m_currentMethodHandle);
- m_jitFlags = { 0 };
- m_jitFlags.corJitFlags = ComputeJitFlags(m_currentMethodHandle);
+ m_jitFlags = ComputeJitFlags(m_currentMethodHandle);
#ifdef FEATURE_READYTORUN_COMPILER
if (IsReadyToRunCompilation())
{
// READYTORUN: FUTURE: Producedure spliting
- m_jitFlags.corJitFlags &= ~CORJIT_FLG_PROCSPLIT;
+ m_jitFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_PROCSPLIT);
DWORD methodAttribs = getMethodAttribs(m_currentMethodHandle);
if (!(methodAttribs & CORINFO_FLG_NOSECURITYWRAP) || (methodAttribs & CORINFO_FLG_SECURITYCHECK))
@@ -445,13 +448,13 @@ void ZapInfo::CompileMethod()
}
#endif
- if ((m_jitFlags.corJitFlags & CORJIT_FLG_SKIP_VERIFICATION) == 0)
+ if (!m_jitFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_SKIP_VERIFICATION))
{
BOOL raiseVerificationException, unverifiableGenericCode;
- m_jitFlags.corJitFlags = GetCompileFlagsIfGenericInstantiation(
+ m_jitFlags = GetCompileFlagsIfGenericInstantiation(
m_currentMethodHandle,
- (CorJitFlag)m_jitFlags.corJitFlags,
+ m_jitFlags,
this,
&raiseVerificationException,
&unverifiableGenericCode);
@@ -465,7 +468,7 @@ void ZapInfo::CompileMethod()
#if !defined(FEATURE_CORECLR)
// Ask the JIT to generate desktop-quirk-compatible code.
- m_jitFlags.corJitFlags2 |= CORJIT_FLG2_DESKTOP_QUIRKS;
+ m_jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_DESKTOP_QUIRKS);
#endif
if (m_pImage->m_stats)
@@ -486,7 +489,7 @@ void ZapInfo::CompileMethod()
res = m_zapper->m_alternateJit->compileMethod( this,
&m_currentMethodInfo,
- CORJIT_FLG_CALL_GETJITFLAGS,
+ CORJIT_FLAGS::CORJIT_FLAG_CALL_GETJITFLAGS,
&pCode,
&cCode );
if (FAILED(res))
@@ -504,7 +507,7 @@ void ZapInfo::CompileMethod()
ICorJitCompiler * pCompiler = m_zapper->m_pJitCompiler;
res = pCompiler->compileMethod(this,
&m_currentMethodInfo,
- CORJIT_FLG_CALL_GETJITFLAGS,
+ CORJIT_FLAGS::CORJIT_FLAG_CALL_GETJITFLAGS,
&pCode,
&cCode);
@@ -813,7 +816,7 @@ void ZapInfo::PublishCompiledMethod()
//
// For now, the only methods eligible for de-duplication are IL stubs
//
- if (m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_IL_STUB)
+ if (m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB))
{
ZapMethodHeader * pDuplicateMethod = m_pImage->m_CodeDeduplicator.Lookup(pMethod);
if (pDuplicateMethod != NULL)
@@ -830,7 +833,7 @@ void ZapInfo::PublishCompiledMethod()
// Stubs that have no metadata token cannot be tracked by IBC data.
if (m_currentMethodProfilingDataFlags & (1 << ReadMethodCode))
{
- if (m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_IL_STUB)
+ if (m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB))
m_pImage->m_PrioritizedGCInfo.Append(pMethod->m_pGCInfo);
}
@@ -888,7 +891,7 @@ HRESULT ZapInfo::allocBBProfileBuffer (
{
HRESULT hr;
- if (m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_IL_STUB)
+ if (m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB))
{
*ppBlock = NULL;
return E_NOTIMPL;
@@ -965,7 +968,7 @@ HRESULT ZapInfo::getBBProfileData (
// the profile data is in that module
// @TODO: Fetch the profile data from the other module.
if ((m_currentMethodModule != m_pImage->m_hModule) ||
- (m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_IL_STUB))
+ m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB))
{
return E_FAIL;
}
@@ -1054,7 +1057,7 @@ void ZapInfo::allocMem(
void ** roDataBlock /* OUT */
)
{
- bool optForSize = ((m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_SIZE_OPT) == CORJIT_FLG_SIZE_OPT);
+ bool optForSize = m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_SIZE_OPT);
UINT align = DEFAULT_CODE_ALIGN;
@@ -1194,7 +1197,7 @@ void ZapInfo::setEHinfo(unsigned EHnumber,
{
ilClause->ClassToken = clause->ClassToken;
- if ((m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_IL_STUB) && (clause->ClassToken != 0))
+ if (m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB) && (clause->ClassToken != 0))
{
// IL stub tokens are 'private' and do not resolve correctly in their parent module's metadata.
@@ -2298,7 +2301,7 @@ unsigned ZapInfo::getClassDomainID (CORINFO_CLASS_HANDLE cls, void **ppIndirecti
m_pImage->m_pPreloader->AddTypeToTransitiveClosureOfInstantiations(cls);
- if(!(m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_DEBUG_CODE))
+ if (!m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE))
{
if (isRIDClassDomainID(cls))
{
@@ -3706,7 +3709,7 @@ CorInfoCanSkipVerificationResult ZapInfo::canSkipMethodVerification (
{
// ILStubs are generated internally by the CLR. There is no need to
// verify it, or any of its callees.
- if (m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_IL_STUB)
+ if (m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_IL_STUB))
return CORINFO_VERIFICATION_CAN_SKIP;
CorInfoCanSkipVerificationResult canSkipVer =
diff --git a/src/zap/zapinfo.h b/src/zap/zapinfo.h
index 3d8736f067..97ecfb6715 100644
--- a/src/zap/zapinfo.h
+++ b/src/zap/zapinfo.h
@@ -231,7 +231,7 @@ class ZapInfo
void InitMethodName();
- int ComputeJitFlags(CORINFO_METHOD_HANDLE handle);
+ CORJIT_FLAGS ComputeJitFlags(CORINFO_METHOD_HANDLE handle);
ZapDebugInfo * EmitDebugInfo();
ZapGCInfo * EmitGCInfo();
diff --git a/src/zap/zapmetadata.cpp b/src/zap/zapmetadata.cpp
index e77dbb837f..a3a9e2d9d6 100644
--- a/src/zap/zapmetadata.cpp
+++ b/src/zap/zapmetadata.cpp
@@ -299,7 +299,7 @@ void ZapILMetaData::CopyMetaData()
// unless we're producing an instrumented version - the IBC logging for meta data doesn't
// work for the hot/cold split version.
- if (m_pImage->m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_BBINSTR)
+ if (m_pImage->m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_BBINSTR))
IfFailThrow(pIMetaDataCorProfileData->SetCorProfileData(NULL));
else
IfFailThrow(pIMetaDataCorProfileData->SetCorProfileData(m_pImage->GetProfileData()));
@@ -308,7 +308,7 @@ void ZapILMetaData::CopyMetaData()
// If we are ngening with the tuning option, the IBC data that is
// generated gets reordered and may be inconsistent with the
// metadata in the original IL image. Let's just skip that case.
- if (!(m_pImage->m_zapper->m_pOpt->m_compilerFlags & CORJIT_FLG_BBINSTR))
+ if (!m_pImage->m_zapper->m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_BBINSTR))
{
// Communicate the reordering option for saving
NonVMComHolder<IMDInternalMetadataReorderingOptions> pIMDInternalMetadataReorderingOptions;
diff --git a/src/zap/zapper.cpp b/src/zap/zapper.cpp
index bcb1b0edca..2c7023a400 100644
--- a/src/zap/zapper.cpp
+++ b/src/zap/zapper.cpp
@@ -425,12 +425,15 @@ ZapperOptions::ZapperOptions() :
m_fPartialNGen(false),
m_fPartialNGenSet(false),
m_fNGenLastRetry(false),
- m_compilerFlags(CORJIT_FLG_RELOC | CORJIT_FLG_PREJIT),
+ 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);
+
m_zapSet = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_ZapSet);
if (m_zapSet != NULL && wcslen(m_zapSet) > 3)
{
@@ -519,18 +522,21 @@ Zapper::Zapper(NGenOptions *pOptions, bool fromDllHost)
pOptions = &currentVersionOptions;
- zo->m_compilerFlags = CORJIT_FLG_RELOC | CORJIT_FLG_PREJIT;
+ zo->m_compilerFlags.Reset();
+ zo->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_RELOC);
+ zo->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_PREJIT);
zo->m_autodebug = true;
if (pOptions->fDebug)
{
- zo->m_compilerFlags |= CORJIT_FLG_DEBUG_INFO|CORJIT_FLG_DEBUG_CODE;
+ zo->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_INFO);
+ zo->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE);
zo->m_autodebug = false;
}
if (pOptions->fProf)
{
- zo->m_compilerFlags |= CORJIT_FLG_PROF_ENTERLEAVE;
+ zo->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_PROF_ENTERLEAVE);
}
#ifdef FEATURE_FUSION
@@ -576,7 +582,7 @@ Zapper::Zapper(NGenOptions *pOptions, bool fromDllHost)
#endif //FEATURE_FUSION
if (pOptions->fInstrument)
- zo->m_compilerFlags |= CORJIT_FLG_BBINSTR;
+ zo->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_BBINSTR);
zo->m_verbose = pOptions->fVerbose;
zo->m_statOptions = pOptions->uStats;
@@ -1017,6 +1023,15 @@ void Zapper::DestroyDomain()
CleanupAssembly();
//
+ // Shut down JIT compiler.
+ //
+
+ if (m_pJitCompiler != NULL)
+ {
+ m_pJitCompiler->ProcessShutdownWork(NULL);
+ }
+
+ //
// Get rid of domain.
//
@@ -2032,10 +2047,10 @@ void Zapper::CreateCompilationDomain()
BOOL fForceDebug = FALSE;
if (!m_pOpt->m_autodebug)
- fForceDebug = (m_pOpt->m_compilerFlags & CORJIT_FLG_DEBUG_INFO) != 0;
+ fForceDebug = m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_INFO);
- BOOL fForceProfile = (m_pOpt->m_compilerFlags & CORJIT_FLG_PROF_ENTERLEAVE) != 0;
- BOOL fForceInstrument = (m_pOpt->m_compilerFlags & CORJIT_FLG_BBINSTR) != 0;
+ BOOL fForceProfile = m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_PROF_ENTERLEAVE);
+ BOOL fForceInstrument = m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_BBINSTR);
InitEE(fForceDebug, fForceProfile, fForceInstrument);
@@ -3323,28 +3338,29 @@ IMetaDataAssemblyEmit * Zapper::CreateAssemblyEmitter()
void Zapper::InitializeCompilerFlags(CORCOMPILE_VERSION_INFO * pVersionInfo)
{
- m_pOpt->m_compilerFlags &= ~(CORJIT_FLG_DEBUG_INFO
- | CORJIT_FLG_DEBUG_CODE
- | CORJIT_FLG_PROF_ENTERLEAVE
- | CORJIT_FLG_PROF_NO_PINVOKE_INLINE);
+ m_pOpt->m_compilerFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_INFO);
+ m_pOpt->m_compilerFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE);
+ m_pOpt->m_compilerFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_PROF_ENTERLEAVE);
+ m_pOpt->m_compilerFlags.Clear(CORJIT_FLAGS::CORJIT_FLAG_PROF_NO_PINVOKE_INLINE);
// We track debug info all the time in the ngen image
- m_pOpt->m_compilerFlags |= CORJIT_FLG_DEBUG_INFO;
+ m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_INFO);
if (pVersionInfo->wCodegenFlags & CORCOMPILE_CODEGEN_DEBUGGING)
{
- m_pOpt->m_compilerFlags |= (CORJIT_FLG_DEBUG_INFO|
- CORJIT_FLG_DEBUG_CODE);
+ m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_INFO);
+ m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE);
}
if (pVersionInfo->wCodegenFlags & CORCOMPILE_CODEGEN_PROFILING)
{
- m_pOpt->m_compilerFlags |= CORJIT_FLG_PROF_ENTERLEAVE | CORJIT_FLG_PROF_NO_PINVOKE_INLINE;
+ m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_PROF_ENTERLEAVE);
+ m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_PROF_NO_PINVOKE_INLINE);
m_pOpt->m_ngenProfileImage = true;
}
if (pVersionInfo->wCodegenFlags & CORCOMPILE_CODEGEN_PROF_INSTRUMENTING)
- m_pOpt->m_compilerFlags |= CORJIT_FLG_BBINSTR;
+ m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_BBINSTR);
#if defined(_TARGET_X86_)
@@ -3353,7 +3369,7 @@ void Zapper::InitializeCompilerFlags(CORCOMPILE_VERSION_INFO * pVersionInfo)
switch (CPU_X86_FAMILY(pVersionInfo->cpuInfo.dwCPUType))
{
case CPU_X86_PENTIUM_4:
- m_pOpt->m_compilerFlags |= CORJIT_FLG_TARGET_P4;
+ m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_TARGET_P4);
break;
default:
@@ -3362,20 +3378,25 @@ void Zapper::InitializeCompilerFlags(CORCOMPILE_VERSION_INFO * pVersionInfo)
if (CPU_X86_USE_CMOV(pVersionInfo->cpuInfo.dwFeatures))
{
- m_pOpt->m_compilerFlags |= CORJIT_FLG_USE_CMOV |
- CORJIT_FLG_USE_FCOMI;
+ m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_CMOV);
+ 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 |= CORJIT_FLG_USE_SSE2;
+ 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_
- if ( (m_pOpt->m_compilerFlags & CORJIT_FLG_DEBUG_INFO)
- && (m_pOpt->m_compilerFlags & CORJIT_FLG_DEBUG_CODE)
- && (m_pOpt->m_compilerFlags & CORJIT_FLG_PROF_ENTERLEAVE))
+ if ( m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_INFO)
+ && m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_DEBUG_CODE)
+ && m_pOpt->m_compilerFlags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_PROF_ENTERLEAVE))
{
//
// We've decided not to support debugging + optimizations disabled + profiling to
diff --git a/src/zap/zapreadytorun.cpp b/src/zap/zapreadytorun.cpp
index ea42a25b8d..30ad296f95 100644
--- a/src/zap/zapreadytorun.cpp
+++ b/src/zap/zapreadytorun.cpp
@@ -291,9 +291,6 @@ void ZapImage::OutputEntrypointsTableForReadyToRun()
pReadyToRunHeader->RegisterSection(READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS, pHashtableBlob);
pReadyToRunHeader->RegisterSection(READYTORUN_SECTION_RUNTIME_FUNCTIONS, m_pRuntimeFunctionSection);
- if (m_pImportSectionsTable->GetSize() != 0)
- pReadyToRunHeader->RegisterSection(READYTORUN_SECTION_IMPORT_SECTIONS, m_pImportSectionsTable);
-
if (m_pLazyMethodCallHelperSection->GetNodeCount() != 0)
pReadyToRunHeader->RegisterSection(READYTORUN_SECTION_DELAYLOAD_METHODCALL_THUNKS, m_pLazyMethodCallHelperSection);
diff --git a/sync.cmd b/sync.cmd
index e883ef7f05..094d0c1a71 100644
--- a/sync.cmd
+++ b/sync.cmd
@@ -1,4 +1,4 @@
-@if "%_echo%" neq "on" echo off
+@if not defined _echo @echo off
setlocal EnableDelayedExpansion
if /I [%1] == [-?] goto Usage
@@ -7,6 +7,7 @@ if /I [%1] == [-help] goto Usage
@if [%1]==[] set __args=-p
@call %~dp0run.cmd sync %__args% %*
+ @call %~dp0run.cmd sync -PublishTestNativeBins %__args% %*
@exit /b %ERRORLEVEL%
:Usage
@@ -24,6 +25,8 @@ echo -AzureToken="Access token"
echo To download a specific group of product packages, specify:
echo -BuildMajor
echo -BuildMinor
+echo To download from a specific container, specify:
+echo -Container="container name"
echo.
echo.
echo If no option is specified then sync.cmd -p is implied. \ No newline at end of file
diff --git a/tests/arm64/Tests.lst b/tests/arm64/Tests.lst
index 15c0d1718e..5b2792b0c0 100644
--- a/tests/arm64/Tests.lst
+++ b/tests/arm64/Tests.lst
@@ -2412,7 +2412,7 @@ RelativePath=baseservices\threading\interlocked\compareexchange\CompareExchangeT
WorkingDir=baseservices\threading\interlocked\compareexchange\CompareExchangeTClass
Expected=0
MaxAllowedDurationSeconds=600
-Categories=NEW;EXPECTED_PASS;UNSTABLE
+Categories=NEW;EXPECTED_FAIL;UNSTABLE
HostStyle=0
[CompareExchangeTClass_1.cmd_345]
RelativePath=baseservices\threading\interlocked\compareexchange\CompareExchangeTClass_1\CompareExchangeTClass_1.cmd
@@ -10532,7 +10532,7 @@ RelativePath=CoreMangLib\cti\system\globalization\regioninfo\RegionInfoCurrentRe
WorkingDir=CoreMangLib\cti\system\globalization\regioninfo\RegionInfoCurrentRegion
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri1;RT;EXPECTED_PASS
+Categories=Pri1;RT;EXPECTED_FAIL
HostStyle=0
[RegionInfoEquals.cmd_1505]
RelativePath=CoreMangLib\cti\system\globalization\regioninfo\RegionInfoEquals\RegionInfoEquals.cmd
@@ -20990,7 +20990,7 @@ RelativePath=GC\Scenarios\FinalizeTimeout\FinalizeTimeout\FinalizeTimeout.cmd
WorkingDir=GC\Scenarios\FinalizeTimeout\FinalizeTimeout
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;EXPECTED_PASS
+Categories=Pri0;EXPECTED_FAIL
HostStyle=0
[finalnstruct.cmd_3013]
RelativePath=GC\Scenarios\FinalNStruct\finalnstruct\finalnstruct.cmd
@@ -23930,7 +23930,7 @@ RelativePath=GC\Scenarios\GCSimulator\GCSimulator_81\GCSimulator_81.cmd
WorkingDir=GC\Scenarios\GCSimulator\GCSimulator_81
Expected=0
MaxAllowedDurationSeconds=600
-Categories=NEW;EXPECTED_PASS
+Categories=NEW;EXPECTED_FAIL
HostStyle=0
[GCSimulator_82.cmd_3433]
RelativePath=GC\Scenarios\GCSimulator\GCSimulator_82\GCSimulator_82.cmd
@@ -42592,7 +42592,7 @@ RelativePath=JIT\Methodical\divrem\div\decimaldiv_cs_do\decimaldiv_cs_do.cmd
WorkingDir=JIT\Methodical\divrem\div\decimaldiv_cs_do
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[decimaldiv_cs_r.cmd_6168]
RelativePath=JIT\Methodical\divrem\div\decimaldiv_cs_r\decimaldiv_cs_r.cmd
@@ -42606,7 +42606,7 @@ RelativePath=JIT\Methodical\divrem\div\decimaldiv_cs_ro\decimaldiv_cs_ro.cmd
WorkingDir=JIT\Methodical\divrem\div\decimaldiv_cs_ro
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[i4div_cs_d.cmd_6170]
RelativePath=JIT\Methodical\divrem\div\i4div_cs_d\i4div_cs_d.cmd
@@ -42620,7 +42620,7 @@ RelativePath=JIT\Methodical\divrem\div\i4div_cs_do\i4div_cs_do.cmd
WorkingDir=JIT\Methodical\divrem\div\i4div_cs_do
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[i4div_cs_r.cmd_6172]
RelativePath=JIT\Methodical\divrem\div\i4div_cs_r\i4div_cs_r.cmd
@@ -42634,7 +42634,7 @@ RelativePath=JIT\Methodical\divrem\div\i4div_cs_ro\i4div_cs_ro.cmd
WorkingDir=JIT\Methodical\divrem\div\i4div_cs_ro
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[i8div_cs_d.cmd_6174]
RelativePath=JIT\Methodical\divrem\div\i8div_cs_d\i8div_cs_d.cmd
@@ -42648,7 +42648,7 @@ RelativePath=JIT\Methodical\divrem\div\i8div_cs_do\i8div_cs_do.cmd
WorkingDir=JIT\Methodical\divrem\div\i8div_cs_do
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[i8div_cs_r.cmd_6176]
RelativePath=JIT\Methodical\divrem\div\i8div_cs_r\i8div_cs_r.cmd
@@ -42662,7 +42662,7 @@ RelativePath=JIT\Methodical\divrem\div\i8div_cs_ro\i8div_cs_ro.cmd
WorkingDir=JIT\Methodical\divrem\div\i8div_cs_ro
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[negSignedMod.cmd_6178]
RelativePath=JIT\Methodical\divrem\div\negSignedMod\negSignedMod.cmd
@@ -42683,7 +42683,7 @@ RelativePath=JIT\Methodical\divrem\div\overlddiv_cs_do\overlddiv_cs_do.cmd
WorkingDir=JIT\Methodical\divrem\div\overlddiv_cs_do
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[overlddiv_cs_r.cmd_6181]
RelativePath=JIT\Methodical\divrem\div\overlddiv_cs_r\overlddiv_cs_r.cmd
@@ -42697,7 +42697,7 @@ RelativePath=JIT\Methodical\divrem\div\overlddiv_cs_ro\overlddiv_cs_ro.cmd
WorkingDir=JIT\Methodical\divrem\div\overlddiv_cs_ro
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[r4div_cs_d.cmd_6183]
RelativePath=JIT\Methodical\divrem\div\r4div_cs_d\r4div_cs_d.cmd
@@ -42711,7 +42711,7 @@ RelativePath=JIT\Methodical\divrem\div\r4div_cs_do\r4div_cs_do.cmd
WorkingDir=JIT\Methodical\divrem\div\r4div_cs_do
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[r4div_cs_r.cmd_6185]
RelativePath=JIT\Methodical\divrem\div\r4div_cs_r\r4div_cs_r.cmd
@@ -42725,7 +42725,7 @@ RelativePath=JIT\Methodical\divrem\div\r4div_cs_ro\r4div_cs_ro.cmd
WorkingDir=JIT\Methodical\divrem\div\r4div_cs_ro
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[r8div_cs_d.cmd_6187]
RelativePath=JIT\Methodical\divrem\div\r8div_cs_d\r8div_cs_d.cmd
@@ -42739,7 +42739,7 @@ RelativePath=JIT\Methodical\divrem\div\r8div_cs_do\r8div_cs_do.cmd
WorkingDir=JIT\Methodical\divrem\div\r8div_cs_do
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[r8div_cs_r.cmd_6189]
RelativePath=JIT\Methodical\divrem\div\r8div_cs_r\r8div_cs_r.cmd
@@ -42753,7 +42753,7 @@ RelativePath=JIT\Methodical\divrem\div\r8div_cs_ro\r8div_cs_ro.cmd
WorkingDir=JIT\Methodical\divrem\div\r8div_cs_ro
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[u4div_cs_d.cmd_6191]
RelativePath=JIT\Methodical\divrem\div\u4div_cs_d\u4div_cs_d.cmd
@@ -42767,7 +42767,7 @@ RelativePath=JIT\Methodical\divrem\div\u4div_cs_do\u4div_cs_do.cmd
WorkingDir=JIT\Methodical\divrem\div\u4div_cs_do
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[u4div_cs_r.cmd_6193]
RelativePath=JIT\Methodical\divrem\div\u4div_cs_r\u4div_cs_r.cmd
@@ -42781,7 +42781,7 @@ RelativePath=JIT\Methodical\divrem\div\u4div_cs_ro\u4div_cs_ro.cmd
WorkingDir=JIT\Methodical\divrem\div\u4div_cs_ro
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[u8div_cs_d.cmd_6195]
RelativePath=JIT\Methodical\divrem\div\u8div_cs_d\u8div_cs_d.cmd
@@ -42795,7 +42795,7 @@ RelativePath=JIT\Methodical\divrem\div\u8div_cs_do\u8div_cs_do.cmd
WorkingDir=JIT\Methodical\divrem\div\u8div_cs_do
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[u8div_cs_r.cmd_6197]
RelativePath=JIT\Methodical\divrem\div\u8div_cs_r\u8div_cs_r.cmd
@@ -42809,7 +42809,7 @@ RelativePath=JIT\Methodical\divrem\div\u8div_cs_ro\u8div_cs_ro.cmd
WorkingDir=JIT\Methodical\divrem\div\u8div_cs_ro
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[decimalrem_cs_d.cmd_6199]
RelativePath=JIT\Methodical\divrem\rem\decimalrem_cs_d\decimalrem_cs_d.cmd
@@ -42823,7 +42823,7 @@ RelativePath=JIT\Methodical\divrem\rem\decimalrem_cs_do\decimalrem_cs_do.cmd
WorkingDir=JIT\Methodical\divrem\rem\decimalrem_cs_do
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[decimalrem_cs_r.cmd_6201]
RelativePath=JIT\Methodical\divrem\rem\decimalrem_cs_r\decimalrem_cs_r.cmd
@@ -42837,7 +42837,7 @@ RelativePath=JIT\Methodical\divrem\rem\decimalrem_cs_ro\decimalrem_cs_ro.cmd
WorkingDir=JIT\Methodical\divrem\rem\decimalrem_cs_ro
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[i4rem_cs_d.cmd_6203]
RelativePath=JIT\Methodical\divrem\rem\i4rem_cs_d\i4rem_cs_d.cmd
@@ -42851,7 +42851,7 @@ RelativePath=JIT\Methodical\divrem\rem\i4rem_cs_do\i4rem_cs_do.cmd
WorkingDir=JIT\Methodical\divrem\rem\i4rem_cs_do
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[i4rem_cs_r.cmd_6205]
RelativePath=JIT\Methodical\divrem\rem\i4rem_cs_r\i4rem_cs_r.cmd
@@ -42865,7 +42865,7 @@ RelativePath=JIT\Methodical\divrem\rem\i4rem_cs_ro\i4rem_cs_ro.cmd
WorkingDir=JIT\Methodical\divrem\rem\i4rem_cs_ro
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[i8rem_cs_d.cmd_6207]
RelativePath=JIT\Methodical\divrem\rem\i8rem_cs_d\i8rem_cs_d.cmd
@@ -42879,7 +42879,7 @@ RelativePath=JIT\Methodical\divrem\rem\i8rem_cs_do\i8rem_cs_do.cmd
WorkingDir=JIT\Methodical\divrem\rem\i8rem_cs_do
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[i8rem_cs_r.cmd_6209]
RelativePath=JIT\Methodical\divrem\rem\i8rem_cs_r\i8rem_cs_r.cmd
@@ -42893,7 +42893,7 @@ RelativePath=JIT\Methodical\divrem\rem\i8rem_cs_ro\i8rem_cs_ro.cmd
WorkingDir=JIT\Methodical\divrem\rem\i8rem_cs_ro
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[overldrem_cs_d.cmd_6211]
RelativePath=JIT\Methodical\divrem\rem\overldrem_cs_d\overldrem_cs_d.cmd
@@ -42907,7 +42907,7 @@ RelativePath=JIT\Methodical\divrem\rem\overldrem_cs_do\overldrem_cs_do.cmd
WorkingDir=JIT\Methodical\divrem\rem\overldrem_cs_do
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[overldrem_cs_r.cmd_6213]
RelativePath=JIT\Methodical\divrem\rem\overldrem_cs_r\overldrem_cs_r.cmd
@@ -42921,7 +42921,7 @@ RelativePath=JIT\Methodical\divrem\rem\overldrem_cs_ro\overldrem_cs_ro.cmd
WorkingDir=JIT\Methodical\divrem\rem\overldrem_cs_ro
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[r4rem_cs_d.cmd_6215]
RelativePath=JIT\Methodical\divrem\rem\r4rem_cs_d\r4rem_cs_d.cmd
@@ -42935,7 +42935,7 @@ RelativePath=JIT\Methodical\divrem\rem\r4rem_cs_do\r4rem_cs_do.cmd
WorkingDir=JIT\Methodical\divrem\rem\r4rem_cs_do
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[r4rem_cs_r.cmd_6217]
RelativePath=JIT\Methodical\divrem\rem\r4rem_cs_r\r4rem_cs_r.cmd
@@ -42949,7 +42949,7 @@ RelativePath=JIT\Methodical\divrem\rem\r4rem_cs_ro\r4rem_cs_ro.cmd
WorkingDir=JIT\Methodical\divrem\rem\r4rem_cs_ro
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[r8rem_cs_d.cmd_6219]
RelativePath=JIT\Methodical\divrem\rem\r8rem_cs_d\r8rem_cs_d.cmd
@@ -42963,7 +42963,7 @@ RelativePath=JIT\Methodical\divrem\rem\r8rem_cs_do\r8rem_cs_do.cmd
WorkingDir=JIT\Methodical\divrem\rem\r8rem_cs_do
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[r8rem_cs_r.cmd_6221]
RelativePath=JIT\Methodical\divrem\rem\r8rem_cs_r\r8rem_cs_r.cmd
@@ -42977,7 +42977,7 @@ RelativePath=JIT\Methodical\divrem\rem\r8rem_cs_ro\r8rem_cs_ro.cmd
WorkingDir=JIT\Methodical\divrem\rem\r8rem_cs_ro
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[u4rem_cs_d.cmd_6223]
RelativePath=JIT\Methodical\divrem\rem\u4rem_cs_d\u4rem_cs_d.cmd
@@ -42991,7 +42991,7 @@ RelativePath=JIT\Methodical\divrem\rem\u4rem_cs_do\u4rem_cs_do.cmd
WorkingDir=JIT\Methodical\divrem\rem\u4rem_cs_do
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[u4rem_cs_r.cmd_6225]
RelativePath=JIT\Methodical\divrem\rem\u4rem_cs_r\u4rem_cs_r.cmd
@@ -43005,7 +43005,7 @@ RelativePath=JIT\Methodical\divrem\rem\u4rem_cs_ro\u4rem_cs_ro.cmd
WorkingDir=JIT\Methodical\divrem\rem\u4rem_cs_ro
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[u8rem_cs_d.cmd_6227]
RelativePath=JIT\Methodical\divrem\rem\u8rem_cs_d\u8rem_cs_d.cmd
@@ -43019,7 +43019,7 @@ RelativePath=JIT\Methodical\divrem\rem\u8rem_cs_do\u8rem_cs_do.cmd
WorkingDir=JIT\Methodical\divrem\rem\u8rem_cs_do
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[u8rem_cs_r.cmd_6229]
RelativePath=JIT\Methodical\divrem\rem\u8rem_cs_r\u8rem_cs_r.cmd
@@ -43033,7 +43033,7 @@ RelativePath=JIT\Methodical\divrem\rem\u8rem_cs_ro\u8rem_cs_ro.cmd
WorkingDir=JIT\Methodical\divrem\rem\u8rem_cs_ro
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;JIT;EXPECTED_PASS
+Categories=Pri0;JIT;EXPECTED_FAIL
HostStyle=0
[dblarray1_cs_d.cmd_6231]
RelativePath=JIT\Methodical\doublearray\dblarray1_cs_d\dblarray1_cs_d.cmd
@@ -47086,14 +47086,14 @@ RelativePath=JIT\Methodical\explicit\coverage\seq_byte_1_d\seq_byte_1_d.cmd
WorkingDir=JIT\Methodical\explicit\coverage\seq_byte_1_d
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;EXPECTED_PASS
+Categories=Pri0;EXPECTED_FAIL
HostStyle=0
[seq_byte_1_r.cmd_6812]
RelativePath=JIT\Methodical\explicit\coverage\seq_byte_1_r\seq_byte_1_r.cmd
WorkingDir=JIT\Methodical\explicit\coverage\seq_byte_1_r
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;EXPECTED_PASS
+Categories=Pri0;EXPECTED_FAIL
HostStyle=0
[seq_double_1_d.cmd_6813]
RelativePath=JIT\Methodical\explicit\coverage\seq_double_1_d\seq_double_1_d.cmd
@@ -48059,7 +48059,7 @@ RelativePath=JIT\Methodical\fp\exgen\1000w1d_cs_do\1000w1d_cs_do.cmd
WorkingDir=JIT\Methodical\fp\exgen\1000w1d_cs_do
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;EXPECTED_PASS
+Categories=Pri0;EXPECTED_FAIL
HostStyle=0
[1000w1d_cs_r.cmd_6951]
RelativePath=JIT\Methodical\fp\exgen\1000w1d_cs_r\1000w1d_cs_r.cmd
@@ -48073,7 +48073,7 @@ RelativePath=JIT\Methodical\fp\exgen\1000w1d_cs_ro\1000w1d_cs_ro.cmd
WorkingDir=JIT\Methodical\fp\exgen\1000w1d_cs_ro
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;EXPECTED_PASS
+Categories=Pri0;EXPECTED_FAIL
HostStyle=0
[10w250d_cs_d.cmd_6953]
RelativePath=JIT\Methodical\fp\exgen\10w250d_cs_d\10w250d_cs_d.cmd
@@ -52560,7 +52560,7 @@ RelativePath=JIT\Methodical\tailcall\Desktop\_il_relthread-race\_il_relthread-ra
WorkingDir=JIT\Methodical\tailcall\Desktop\_il_relthread-race
Expected=0
MaxAllowedDurationSeconds=600
-Categories=Pri0;EXPECTED_PASS
+Categories=Pri0;EXPECTED_FAIL
HostStyle=0
[_il_dbgcompat_enum.cmd_7596]
RelativePath=JIT\Methodical\tailcall\_il_dbgcompat_enum\_il_dbgcompat_enum.cmd
@@ -64754,7 +64754,7 @@ RelativePath=Loader\classloader\generics\GenericMethods\VSW491668\VSW491668.cmd
WorkingDir=Loader\classloader\generics\GenericMethods\VSW491668
Expected=0
MaxAllowedDurationSeconds=600
-Categories=NEW;EXPECTED_PASS
+Categories=NEW;EXPECTED_FAIL
HostStyle=0
[abstract01.cmd_9373]
RelativePath=Loader\classloader\generics\Instantiation\Negative\abstract01\abstract01.cmd
diff --git a/tests/build.proj b/tests/build.proj
index 0dfd84d47b..63db903219 100644
--- a/tests/build.proj
+++ b/tests/build.proj
@@ -38,6 +38,7 @@
<!-- Create a collection of all project.json files for dependency updates. -->
<ItemGroup>
<ProjectJsonFiles Include="$(SourceDir)**\project.json" />
+ <ProjectJsonFiles Include="$(ProjectDir)scripts\**\project.json" />
</ItemGroup>
<Target Name="UpdatePackageDependencyVersion">
diff --git a/tests/debugger_tests/ConfigFilesGenerators/ConfigTemplate.txt b/tests/debugger_tests/ConfigFilesGenerators/ConfigTemplate.txt
new file mode 100644
index 0000000000..d674a72698
--- /dev/null
+++ b/tests/debugger_tests/ConfigFilesGenerators/ConfigTemplate.txt
@@ -0,0 +1,32 @@
+<Configuration>
+ <TestRoot>..\..</TestRoot>
+ <TargetArchitecture>x64</TargetArchitecture>
+ <ScriptRootDir>$(TestRoot)\Scripts</ScriptRootDir>
+ <DebuggeeRootDir>$(TestRoot)\Debuggees</DebuggeeRootDir>
+ <DebuggeeSourceRoot>$(DebuggeeRootDir)\Source</DebuggeeSourceRoot>
+ <RuntimeRoot>##Insert_Runtime_Root##</RuntimeRoot>
+ <NugetCacheRoot>##Insert_Nuget_Cache_Root##</NugetCacheRoot>
+ <TestProduct>ProjectK</TestProduct>
+ <HostExe>$(RuntimeRoot)\corerun.exe</HostExe>
+ <DbgShim>$(RuntimeRoot)\dbgshim.dll</DbgShim>
+ <RuntimeSymbolsPath>$(RuntimeRoot)</RuntimeSymbolsPath>
+ <DebuggeeBuildProcess>cli</DebuggeeBuildProcess>
+ <CliVersion>1.0.0-preview1-002702</CliVersion>
+ <DebuggeeNativeLibRoot>$(DebuggeeRootDir)\native</DebuggeeNativeLibRoot>
+ <DebuggeeBuildRoot>$(DebuggeeRootDir)\dotnet.$(CliVersion)</DebuggeeBuildRoot>
+ <ProjectJsonNetStandardLibraryVersion>1.0.0-rc2-23811</ProjectJsonNetStandardLibraryVersion>
+ <ProjectJsonSystemThreadingThreadVersion>4.0.0-rc2-24027</ProjectJsonSystemThreadingThreadVersion>
+ <ProjectJsonMicrosoftCSharpVersion>4.0.1-rc2-23811</ProjectJsonMicrosoftCSharpVersion>
+ <CliPath>##Cli_Path##</CliPath>
+ <NuGetPackageCacheDir>$(NugetCacheRoot)</NuGetPackageCacheDir>
+ <NuGetPackageFeeds>
+ myget.org dotnet-core=https://dotnet.myget.org/F/dotnet-core/api/v3/index.json;
+ myget.org=https://www.nuget.org/api/v2/
+ </NuGetPackageFeeds>
+ <SOSPath>$(RuntimeRoot)\sos.dll</SOSPath>
+ <MDbgDir>$(TestRoot)\mdbg</MDbgDir>
+ <DebuggeeDumpOutputRootDir>$(WorkingDir)\dumps\$(TestProduct)</DebuggeeDumpOutputRootDir>
+ <DebuggeeDumpInputRootDir>$(DebuggeeDumpOutputRootDir)</DebuggeeDumpInputRootDir>
+ <LogDir>$(TestRoot)\logs_$(Timestamp)</LogDir>
+ <CDBPath>$(TestRoot)\Debuggers\cdb\cdb.exe</CDBPath>
+</Configuration>
diff --git a/tests/debugger_tests/ConfigFilesGenerators/GenerateConfig.cmd b/tests/debugger_tests/ConfigFilesGenerators/GenerateConfig.cmd
new file mode 100644
index 0000000000..635df958c6
--- /dev/null
+++ b/tests/debugger_tests/ConfigFilesGenerators/GenerateConfig.cmd
@@ -0,0 +1,53 @@
+@echo off
+setlocal EnableDelayedExpansion
+
+:: Set the default arguments for script generation.
+set __RuntimeRoot=`$(TestRoot)\Runtimes\Coreclr1
+set __NugetCacheDir=`$(WorkingDir)\packages
+set __CliPath=
+set __ConfigFileName=Debugger.Tests.Config.txt
+set __TemplateFileName=%~dp0\ConfigTemplate.txt
+
+:Arg_Loop
+if "%1" == "" goto ArgsDone
+if /i "%1" == "/?" goto Usage
+
+if /i "%1" == "rt" (set "__RuntimeRoot=%2"&shift&shift&goto Arg_Loop)
+if /i "%1" == "nc" (set "__NugetCacheDir=%2"&shift&shift&goto Arg_Loop)
+if /i "%1" == "cli" (set "__CliPath=%2"&shift&shift&goto Arg_Loop)
+
+echo Invalid commandline argument: %1
+goto Usage
+
+:ArgsDone
+
+if not exist %__TemplateFileName% (
+ echo Template file %__TemplateFileName% doesn't exist.
+ exit /b 1
+)
+
+:: Delete previous config file.
+if exist %__ConfigFileName% (
+ echo Deleting current config file.
+ del %__ConfigFileName%
+)
+
+:: powershell "Get-Content %__TemplateFileName% -replace (""##Insert_Runtime_Root##"", ""%__RuntimeRoot%"") | Output-File %__ConfigFileName% "
+powershell "(Get-Content \"%__TemplateFileName%\")`"^
+ "-replace \"##Insert_Runtime_Root##\", \"%__RuntimeRoot%\" `"^
+ "|ForEach-Object{$_ -replace \"##Insert_Nuget_Cache_Root##\", \"%__NugetCacheDir%\"} `"^
+ "|ForEach-Object{$_ -replace \"##Cli_Path##\", \"%__CliPath%\"} `"^
+ "| Out-File \"%__ConfigFileName%\""
+
+exit /b 0
+
+:Usage
+echo.
+echo Usage:
+echo %0 [rt ^<runtime_path^>] [nc ^<nuget_cache_path^>] [cli ^<cli_path^>] where:
+echo.
+echo ^<runtime_path^>: path to the runtime that you want to use for testing.
+echo ^<nuget_cache_path^>: path to the nuget cache.
+echo ^<cli_path^>: path to the cli tool.
+exit /b 1
+endlocal
diff --git a/tests/debugger_tests/ConfigFilesGenerators/GenerateConfig.sh b/tests/debugger_tests/ConfigFilesGenerators/GenerateConfig.sh
new file mode 100644
index 0000000000..38834ed6a5
--- /dev/null
+++ b/tests/debugger_tests/ConfigFilesGenerators/GenerateConfig.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+
+function print_usage {
+ echo ''
+ echo 'Usage:'
+ echo '[rt=<runtime_path>] [nc=<nuget_cache_path>] [cli=<cli_path>] where:'
+ echo ' <runtime_path>: path to the runtime that you want to use for testing.'
+ echo ' <nuget_cache_path>: path to the nuget cache.'
+ echo ' <cli_path>: path to the cli tool.'
+ echo ''
+ echo ''
+}
+
+# Argument variables
+__RuntimeRoot='$(TestRoot)\Runtimes\Coreclr1'
+__NugetCacheDir='$(WorkingDir)\packages'
+__CliPath=
+__ConfigFileName='Debugger.Tests.Config.txt'
+__TemplateFileName='ConfigTemplate.txt'
+
+for i in "$@"
+do
+ case $i in
+ -h|--help)
+ print_usage
+ exit $EXIT_CODE_SUCCESS
+ ;;
+ rt=*)
+ __RuntimeRoot=${i#*=}
+ ;;
+ nc=*)
+ __NugetCacheDir=${i#*=}
+ ;;
+ cli=*)
+ __CliPath=${i#*=}
+ ;;
+ *)
+ echo "Unknown switch: $i"
+ print_usage
+ exit $EXIT_CODE_SUCCESS
+ ;;
+ esac
+done
+
+if ! -e "$__TemplateFileName"
+then
+ echo '$__TemplateFileName does not exist'
+ exit 1
+fi
+
+if -e "$__ConfigFileName"
+then
+ rm "$__ConfigFileName"
+fi
+
+cp "$__TemplateFileName" "$__ConfigFileName"
+
+sed -i \
+ 's/##Insert_Runtime_Root##/$__RuntimeRoot/g;' \
+ 's/##Insert_Nuget_Cache_Root##/$__NugetCacheDir/g'\
+ 's/##Cli_Path##/$__CliPath/g'\
+ 's/corerun.exe/corerun/g'\
+ "$__ConfigFileName"
+
+exit 0 \ No newline at end of file
diff --git a/tests/debugger_tests/ScriptGenerator/Program.cs b/tests/debugger_tests/ScriptGenerator/Program.cs
new file mode 100644
index 0000000000..1e9586d63e
--- /dev/null
+++ b/tests/debugger_tests/ScriptGenerator/Program.cs
Binary files differ
diff --git a/tests/debugger_tests/ScriptGenerator/project.json b/tests/debugger_tests/ScriptGenerator/project.json
new file mode 100644
index 0000000000..25c7a269c6
--- /dev/null
+++ b/tests/debugger_tests/ScriptGenerator/project.json
Binary files differ
diff --git a/tests/debugger_tests/setup-debuggertests.cmd b/tests/debugger_tests/setup-debuggertests.cmd
new file mode 100644
index 0000000000..6507f0e8a2
--- /dev/null
+++ b/tests/debugger_tests/setup-debuggertests.cmd
@@ -0,0 +1,119 @@
+@if not defined __echo @echo off
+setlocal
+
+set __ThisScriptShort=%0
+set __ThisScriptFull=%~f0
+set __ThisScriptPath=%~dp0
+
+REM =========================================================================================
+REM ===
+REM === Parse arguments
+REM ===
+REM =========================================================================================
+
+set __OutputDir=
+set __Arch=
+set __CoreclrBinPath=
+set __NugetCacheDir=
+set __CliPath=
+
+:Arg_Loop
+if "%1" == "" goto ArgsDone
+
+if /i "%1" == "/?" goto Usage
+if /i "%1" == "-?" goto Usage
+if /i "%1" == "/h" goto Usage
+if /i "%1" == "-h" goto Usage
+if /i "%1" == "/help" goto Usage
+if /i "%1" == "-help" goto Usage
+
+if /i "%1" == "/outputDir" (set __OutputDir=%2&shift&shift&goto Arg_Loop)
+if /i "%1" == "/coreclrBinDir" (set __CoreclrBinPath=%2&shift&shift&goto Arg_Loop)
+if /i "%1" == "/nugetCacheDir" (set __NugetCacheDir=%2&shift&shift&goto Arg_Loop)
+if /i "%1" == "/cliPath" (set __CliPath=%2&shift&shift&goto Arg_Loop)
+
+
+echo Invalid command-line argument: %1
+goto Usage
+
+:ArgsDone
+
+if not defined __OutputDir goto Usage
+if not defined __Arch goto Usage
+
+REM Create directories needed
+if exist "%__OutputDir%\debuggertests" rmdir /S /Q "%__OutputDir%\debuggertests"
+md "%__OutputDir%\debuggertests"
+set __InstallDir=%__OutputDir%\debuggertests
+
+REM =========================================================================================
+REM ===
+REM === download debuggertests package
+REM ===
+REM =========================================================================================
+set DEBUGGERTESTS_URL=https://dotnetbuilddrops.blob.core.windows.net/debugger-container/Windows.DebuggerTests.zip
+set LOCAL_ZIP_PATH=%__InstallDir%\debuggertests.zip
+if exist "%LOCAL_ZIP_PATH%" del "%LOCAL_ZIP_PATH%"
+set DEBUGGERTESTS_INSTALL_LOG="%__ThisScriptPath%debuggerinstall.log"
+REM Download the package
+echo Download and unzip debuggertests package to %LOCAL_ZIP_PATH%
+powershell -NoProfile -ExecutionPolicy unrestricted -Command "$retryCount = 0; $success = $false; do { try { (New-Object Net.WebClient).DownloadFile('%DEBUGGERTESTS_URL%', '%LOCAL_ZIP_PATH%'); $success = $true; } catch { if ($retryCount -ge 6) { throw; } else { $retryCount++; Start-Sleep -Seconds (5 * $retryCount); } } } while ($success -eq $false); Add-Type -Assembly 'System.IO.Compression.FileSystem' -ErrorVariable AddTypeErrors; if ($AddTypeErrors.Count -eq 0) { [System.IO.Compression.ZipFile]::ExtractToDirectory('%LOCAL_ZIP_PATH%', '%__InstallDir%') } else { (New-Object -com shell.application).namespace('%LOCAL_ZIP_PATH%').CopyHere((new-object -com shell.application).namespace('%__InstallDir%').Items(),16) }" >> %DEBUGGERTESTS_INSTALL_LOG%
+
+if errorlevel 1 (
+ echo Failed to install debuggertests to %__InstallDir%
+ goto Fail
+)
+
+REM =========================================================================================
+REM ===
+REM === Setting up the right config file.
+REM ===
+REM =========================================================================================
+echo Generating config file.
+
+call %__ThisScriptPath%\ConfigFilesGenerators\GenerateConfig.cmd rt %__CoreclrBinPath% nc %__NugetCacheDir% cli %__CliPath%
+move Debugger.Tests.Config.txt %__InstallDir%\\Debugger.Tests\dotnet\Debugger.Tests.Config.txt
+
+REM =========================================================================================
+REM ===
+REM === Scripts generation.
+REM ===
+REM =========================================================================================
+mkdir %__InstallDir%\ScriptGenerator
+copy %__ThisScriptPath%\ScriptGenerator\* %__InstallDir%\ScriptGenerator\
+pushd %__InstallDir%\ScriptGenerator
+%__CliPath%\dotnet restore
+%__CliPath%\dotnet build
+popd
+
+%__CliPath%\dotnet run --project %__InstallDir%\ScriptGenerator %__InstallDir% %__CoreclrBinPath% %__InstallDir%\Dotnet.Tests\dotnet
+
+REM Deleting runtests.cmd to avoid double test-running.
+del %__InstallDir%\runtests.cmd
+
+if errorlevel 1 (
+ echo Failed to build and run script generation.
+ goto Fail
+)
+
+
+
+exit /b 0
+
+:Fail
+exit /b 1
+
+REM =========================================================================================
+REM ===
+REM === Helper routines
+REM ===
+REM =========================================================================================
+
+:Usage
+echo.
+echo install debugger tests
+echo.
+echo Usage:
+echo %__ThisScriptShort% /coreclrBinDir ^<coreclr bin path^> /outputDir ^<debuggertests install path^> /nugetCacheDir ^<nuget cache dir path^>
+echo.
+exit /b 1
diff --git a/tests/debugger_tests/setup-debuggertests.sh b/tests/debugger_tests/setup-debuggertests.sh
new file mode 100644
index 0000000000..315359c373
--- /dev/null
+++ b/tests/debugger_tests/setup-debuggertests.sh
Binary files differ
diff --git a/tests/dir.props b/tests/dir.props
index 9d93e93b7d..43026caed2 100644
--- a/tests/dir.props
+++ b/tests/dir.props
@@ -54,7 +54,8 @@
<!-- list of nuget package sources passed to dnu -->
<ItemGroup>
- <!-- Need to escape double forward slash (%2F) or MSBuild will normalize to one slash on Unix. -->
+ <!-- Need to escape double forward slash (%2F) or MSBuild will normalize to one slash on Unix. -->
+ <DnuSourceList Include="https:%2F%2Fdotnet.myget.org/F/dotnet-corefxlab/api/v3/index.json" />
<DnuSourceList Include="https:%2F%2Fdotnet.myget.org/F/dotnet-core/api/v3/index.json" />
<DnuSourceList Include="https:%2F%2Fapi.nuget.org/v3/index.json" />
</ItemGroup>
diff --git a/tests/helix.targets b/tests/helix.targets
deleted file mode 100644
index 16acf01ca4..0000000000
--- a/tests/helix.targets
+++ /dev/null
@@ -1,78 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-
- <PropertyGroup>
- <PackageTestRuntimeFolder>$(PackagesDir)test.Microsoft.NETCore.Runtime.CoreClr\1.1.1</PackageTestRuntimeFolder>
- </PropertyGroup>
-
- <ItemGroup>
- <!-- TODO This should come from some package -->
- <CoreRootFiles Include="$(CORE_ROOT)\crossgen.exe" />
- <CoreRootFiles Include="$(CORE_ROOT)\ildasm.exe" />
- <CoreRootFiles Include="$(CORE_ROOT)\ilasm.exe" />
-
- <!-- TODO these files should get copied to core_root but does not as they are xunit files. Using temporary workaround for now -->
- <CoreRootFiles Include="$(PackagesDir)Microsoft.DotNet.xunit.performance\1.0.0-alpha-build0035\lib\dotnet\xunit.performance.core.dll" />
- <CoreRootFiles Include="$(PackagesDir)xunit.extensibility.core\2.1.0\lib\dotnet\xunit.core.dll" />
- </ItemGroup>
-
- <!-- replace *.lock.json to be that of actual tests than XunitWrapper -->
- <Target Name="ReplaceProjectLockJson"
- BeforeTargets="CopyTestToTestDirectory">
- <PropertyGroup>
- <ProjectLockJson></ProjectLockJson>
- <TestRuntimeProjectLockJson></TestRuntimeProjectLockJson>
- </PropertyGroup>
- <ItemGroup>
- <TestNugetProjectLockFile Include="$(SourceDir)$(Category)\**\project.lock.json"/>
- <TestNugetProjectLockFile Include="$(TestRuntimeProjectLockJson)"/>
- </ItemGroup>
- </Target>
-
- <Target Name="CopyProductInPackagesFolder"
- BeforeTargets="CopyTestToTestDirectory">
-
- <Copy
- SourceFiles="@(CoreRootFiles)"
- DestinationFolder="$(PackageTestRuntimeFolder)"
- SkipUnchangedFiles="false"
- OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
- Retries="$(CopyRetryCount)"
- RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
- UseHardlinksIfPossible="$(CreateHardLinksForCopyFilesToOutputDirectoryIfPossible)">
- </Copy>
-
- </Target>
-
-
- <Target Name="AddFilesToAssemblyList"
- BeforeTargets="CreateAssemblyListTxt">
-
- <ItemGroup>
-
- <ToReplace Include="$(PackageTestRuntimeFolder)\*" />
-
- <!-- In helix xunit tests are run using xunit.console.exe instead of msbuild xunitrunner.
- This dependency should ideally be added in some project.json. But in the package the assemblies are present in tools folder.
- Assemblies in tools folder are not resolved during restore. Therefore forcing addition direclty. -->
- <XunitConsoleExe Include="$(PackagesDir)xunit.runner.console\**\xunit.console.exe" />
- <XunitConsoleExe Include="$(PackagesDir)xunit.runner.console\**\xunit.runner.utility.desktop.dll" />
-
- <ToRemove Include="@(_TestCopyLocalByFileNameWithoutDuplicates)" Condition="'%(_TestCopyLocalByFileNameWithoutDuplicates.Filename)' == 'xunit.performance.core'"/>
- <ToRemove Include="@(_TestCopyLocalByFileNameWithoutDuplicates)" Condition="'%(_TestCopyLocalByFileNameWithoutDuplicates.Filename)' == 'xunit.core'"/>
-
- <_TestCopyLocalByFileNameWithoutDuplicates Remove="@(ToRemove)" />
-
- <_TestCopyLocalByFileNameWithoutDuplicates Include="@(ToReplace)">
- <NugetPackageId>test.Microsoft.NETCore.Runtime.CoreClr</NugetPackageId>
- <SourcePath>%(ToReplace.Identity)</SourcePath>
- </_TestCopyLocalByFileNameWithoutDuplicates>
-
- <_TestCopyLocalByFileNameWithoutDuplicates Include="@(XunitConsoleExe)">
- <NugetPackageId>xunit.runner.console</NugetPackageId>
- <SourcePath>%(XunitConsoleExe.Identity)</SourcePath>
- </_TestCopyLocalByFileNameWithoutDuplicates>
- </ItemGroup>
- </Target>
-
-</Project>
diff --git a/tests/issues.targets b/tests/issues.targets
index ee45e589de..d1f3dc22b8 100644
--- a/tests/issues.targets
+++ b/tests/issues.targets
@@ -40,6 +40,9 @@
<ExcludeList Include="$(XunitTestBinBase)\GC\Scenarios\muldimjagary\muldimjagary\*">
<Issue>3392</Issue>
</ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)\GC\Scenarios\DoublinkList\dlstack\*">
+ <Issue>6553</Issue>
+ </ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\JIT\Directed\coverage\importer\Desktop\bleref_il_d\bleref_il_d.cmd">
<Issue>2414</Issue>
</ExcludeList>
@@ -181,75 +184,37 @@
<ExcludeList Include="$(XunitTestBinBase)\Loader\classloader\TypeGeneratorTests\TypeGeneratorTest683\Generated683\*">
<Issue>6707</Issue>
</ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)\JIT\opt\perf\doublealign\Locals\*">
+ <Issue>8418</Issue>
+ </ExcludeList>
</ItemGroup>
- <!-- The following are baseline x86 failures -->
+ <!-- The following are x86 failures -->
<ItemGroup Condition="'$(XunitTestBinBase)' != '' and '$(BuildArch)' == 'x86'">
<ExcludeList Include="$(XunitTestBinBase)\GC\LargeMemory\Allocation\largeexceptiontest\largeexceptiontest.cmd">
- <Issue>3392</Issue>
+ <Issue>3392, test is useful to have because it can be run manually when making changes to the GC that can have effects in OOM scenarios, but not appropriate to run on our current test infrastructure.</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\GC\LargeMemory\API\gc\gettotalmemory\gettotalmemory.cmd">
- <Issue>3392</Issue>
+ <Issue>3392, test is useful to have because it can be run manually when making changes to the GC that can have effects in OOM scenarios, but not appropriate to run on our current test infrastructure.</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\GC\LargeMemory\API\gc\keepalive\keepalive.cmd">
- <Issue>3392</Issue>
+ <Issue>3392, test is useful to have because it can be run manually when making changes to the GC that can have effects in OOM scenarios, but not appropriate to run on our current test infrastructure.</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\GC\LargeMemory\API\gc\suppressfinalize\suppressfinalize.cmd">
- <Issue>3392</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)\JIT\Methodical\divrem\div\u8div_cs_do\u8div_cs_do.cmd">
- <Issue>needs triage</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)\JIT\Methodical\divrem\div\u8div_cs_ro\u8div_cs_ro.cmd">
- <Issue>needs triage</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)\JIT\Methodical\divrem\rem\u8rem_cs_do\u8rem_cs_do.cmd">
- <Issue>needs triage</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)\JIT\Methodical\divrem\rem\u8rem_cs_ro\u8rem_cs_ro.cmd">
- <Issue>needs triage</Issue>
+ <Issue>3392, test is useful to have because it can be run manually when making changes to the GC that can have effects in OOM scenarios, but not appropriate to run on our current test infrastructure.</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\JIT\Methodical\tailcall_v4\smallFrame\smallFrame.cmd">
<Issue>tail. call pop ret is only supported on amd64</Issue>
</ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)\JIT\opt\Inline\regression\mismatch32\mismatch32\mismatch32.cmd">
- <Issue>needs triage</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)\JIT\opt\Inline\regression\mismatch64\mismatch64\mismatch64.cmd">
- <Issue>needs triage</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)\JIT\opt\perf\doublealign\Locals\Locals.cmd">
- <Issue>needs triage</Issue>
- </ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\JIT\opt\Tailcall\TailcallVerifyWithPrefix\TailcallVerifyWithPrefix.cmd">
- <Issue>x86 JIT doesn't support implicit tail call optimization or tail. call pop ret sequence</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)\JIT\Performance\CodeQuality\Roslyn\CscBench\CscBench.cmd">
- <Issue>6844</Issue>
+ <Issue>2420. x86 JIT doesn't support implicit tail call optimization or tail. call pop ret sequence</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\JIT\Regression\Dev11\External\dev11_239804\ShowLocallocAlignment\ShowLocallocAlignment.cmd">
- <Issue>needs triage</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)\managed\Compilation\Compilation\Compilation.cmd">
- <Issue>needs triage</Issue>
- </ExcludeList>
- </ItemGroup>
-
- <!-- The following x86 failures only occur with RyuJIT/x86 -->
-
- <ItemGroup Condition="'$(XunitTestBinBase)' != '' and '$(BuildArch)' == 'x86'">
- <ExcludeList Include="$(XunitTestBinBase)\JIT\jit64\eh\basics\loopEH\loopEH.cmd">
- <Issue>6778</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)\JIT\Methodical\int64\superlong\_il_relsuperlong\_il_relsuperlong.cmd">
- <Issue>6778</Issue>
- </ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)\GC\Scenarios\DoublinkList\dlstack\*">
- <Issue>6553</Issue>
+ <Issue>7163, fails on both legacy backend and RyuJIT</Issue>
</ExcludeList>
- <ExcludeList Include="$(XunitTestBinBase)\JIT\Regression\CLR-x86-JIT\V1.2-Beta1\b103058\b103058\b103058.cmd">
- <Issue>7008</Issue>
+ <ExcludeList Include="$(XunitTestBinBase)\JIT\Regression\JitBlue\DevDiv_255294\DevDiv_255294\DevDiv_255294.cmd">
+ <Issue>The test is too large for x86 and causes OutOfMemory exception.</Issue>
</ExcludeList>
</ItemGroup>
diff --git a/tests/override.targets b/tests/override.targets
index 8bdff51b63..36a9615e73 100644
--- a/tests/override.targets
+++ b/tests/override.targets
@@ -3,8 +3,6 @@
Overrides for all other targets (including build tools) can go in this file.
-->
- <Import Project="mono.targets" Condition="'$(OsEnvironment)'=='Unix'" />
- <Import Project="roslyn.xplat.targets" Condition="'$(OsEnvironment)'=='Unix'" />
<!-- Contains overrides for the nuget reference resolution. The regular nuget reference resolution will not
copy references local, which we need in order to correctly execute the xunit project -->
<Import Project="xunitwrapper.targets" Condition="'$(IsXunitWrapperProject)'=='true'" />
diff --git a/tests/publishdependency.targets b/tests/publishdependency.targets
index 554b1eee78..9e286fc3ba 100644
--- a/tests/publishdependency.targets
+++ b/tests/publishdependency.targets
@@ -3,18 +3,50 @@
<UsingTask TaskName="PrereleaseResolveNuGetPackageAssets" AssemblyFile="$(BuildToolsTaskDir)Microsoft.DotNet.Build.Tasks.dll"/>
<ItemGroup>
- <TestTargetFramework Include=".NETCoreApp,Version=v1.0">
- <Folder>netcoreapp1.0</Folder>
+ <TestTargetFramework Include=".NETCoreApp,Version=v1.1">
+ <Folder>netcoreapp1.1</Folder>
</TestTargetFramework>
</ItemGroup>
+ <PropertyGroup>
+ <!-- defined in buildtools packaging.targets, but we need this before targets are imported -->
+ <PackagePlatform Condition="'$(PackagePlatform)' == ''">$(__BuildArch)</PackagePlatform>
+ <PackagePlatform Condition="'$(PackagePlatform)' == 'amd64'">x64</PackagePlatform>
+ <MinOSForArch>win7</MinOSForArch>
+ <MinOSForArch Condition="'$(PackagePlatform)' == 'arm'">win8</MinOSForArch>
+ <MinOSForArch Condition="'$(PackagePlatform)' == 'arm64'">win10</MinOSForArch>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CoreRootProjectLockJsonFiles Include="$(SourceDir)Common\test_runtime\project.lock.json"/>
+ <CoreRootProjectLockJsonFiles Include="$(SourceDir)Common\test_dependencies\project.lock.json"/>
+ </ItemGroup>
+
+ <ItemGroup>
+ <NonWindowsProjectLockJsonFiles Include="@(CoreRootProjectLockJsonFiles)"/>
+ <NonWindowsProjectLockJsonFiles Include="$(SourceDir)Common\build_against_pkg_dependencies\project.lock.json"/>
+ </ItemGroup>
+
+ <ItemGroup>
+ <RefProjectLockJsonFiles Include="$(SourceDir)Common\targeting_pack_ref\project.lock.json"/>
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProductProjectLockJsonFiles Include="$(SourceDir)Common\build_against_pkg_dependencies\project.lock.json"/>
+ </ItemGroup>
+
<ItemGroup>
- <ProjectLockJsonFiles Include="$(SourceDir)Common\test_runtime\project.lock.json"/>
- <ProjectLockJsonFiles Include="$(SourceDir)Common\test_dependencies\project.lock.json"/>
+ <CrossGenFiles Include="..\packages\runtime.$(MinOSForArch)-$(PackagePlatform).Microsoft.NETCore.Runtime.CoreCLR\$(CoreClrPackageVersion)\tools\crossgen.exe"/>
</ItemGroup>
+ <PropertyGroup>
+ <ProductDestination>$(ProjectDir)\..\bin\Product\$(BuildOS).$(BuildArch).$(BuildType)</ProductDestination>
+ <RefDestination>$(ProductDestination)\ref</RefDestination>
+ <CoreOverlay>$(CORE_ROOT)\..\coreoverlay</CoreOverlay>
+ </PropertyGroup>
+
<Target Name="CopyDependecyToCoreRoot"
- Inputs="@(ProjectLockJsonFiles)"
+ Inputs="@(CoreRootProjectLockJsonFiles)"
Outputs="$(CORE_ROOT)\*.*">
<MSBuild Projects="$(SourceDir)Common\test_runtime\test_runtime.csproj"/>
@@ -23,12 +55,12 @@
<!-- This will use the overridden PrereleaseResolveNuGetPackageAssets, which outputs copy local items
for the xunit wrapper projects -->
- <PrereleaseResolveNuGetPackageAssets AllowFallbackOnTargetSelection="true"
+ <PrereleaseResolveNuGetPackageAssets AllowFallbackOnTargetSelection="false"
IncludeFrameworkReferences="false"
NuGetPackagesDirectory="$(PackagesDir)"
RuntimeIdentifier="$(TestNugetRuntimeId)"
ProjectLanguage="$(Language)"
- ProjectLockFile="%(ProjectLockJsonFiles.Identity)"
+ ProjectLockFile="%(CoreRootProjectLockJsonFiles.Identity)"
TargetMonikers="@(TestTargetFramework)">
<Output TaskParameter="ResolvedAnalyzers" ItemName="Analyzer" />
<Output TaskParameter="ResolvedReferences" ItemName="Reference" />
@@ -58,4 +90,147 @@
</Copy>
</Target>
+ <Target Name="CopyNonWindowsDependecyToCoreRoot"
+ Inputs="@(NonWindowsProjectLockJsonFiles)"
+ Outputs="$(CoreOverlay)\*.*">
+
+ <MSBuild Projects="$(SourceDir)Common\test_runtime\test_runtime.csproj"/>
+
+ <MSBuild Projects="$(SourceDir)Common\test_dependencies\test_dependencies.csproj"/>
+
+ <MSBuild Projects="$(SourceDir)Common\build_against_pkg_dependencies\build_against_pkg_dependencies.csproj"/>
+
+ <!-- This will use the overridden PrereleaseResolveNuGetPackageAssets, which outputs copy local items
+ for the xunit wrapper projects -->
+ <PrereleaseResolveNuGetPackageAssets AllowFallbackOnTargetSelection="true"
+ IncludeFrameworkReferences="false"
+ NuGetPackagesDirectory="$(PackagesDir)"
+ RuntimeIdentifier="$(RuntimeId)"
+ ProjectLanguage="$(Language)"
+ ProjectLockFile="%(NonWindowsProjectLockJsonFiles.Identity)"
+ TargetMonikers="@(TestTargetFramework)">
+ <Output TaskParameter="ResolvedAnalyzers" ItemName="Analyzer" />
+ <Output TaskParameter="ResolvedReferences" ItemName="Reference" />
+ <Output TaskParameter="ResolvedCopyLocalItems" ItemName="RunTimeCopyLocal" />
+ </PrereleaseResolveNuGetPackageAssets>
+ <ItemGroup>
+ <RunTimeDependecyExclude Include="$(CoreOverlay)\**\*.*" />
+ <RunTimeDependecyExcludeFiles Include="@(RunTimeDependecyExclude -> '%(FileName)%(Extension)')" />
+ <RunTimeDependecyExcludeFiles Include="@(RunTimeDependecyExclude -> '%(FileName).ni%(Extension)')" />
+ <RunTimeDependecyExcludeFiles Include="@(RunTimeDependecyExclude -> '%(FileName).pdb')" />
+ <AllResolvedRuntimeDependencies Include="@(RunTimeCopyLocal -> '%(FileName)%(Extension)')">
+ <File>%(Identity)</File>
+ </AllResolvedRuntimeDependencies>
+ <RunTimeDependecyCopyLocalFile Include="@(AllResolvedRuntimeDependencies)" Exclude="@(RunTimeDependecyExcludeFiles)"/>
+ <RunTimeDependecyCopyLocal Include="@(RunTimeDependecyCopyLocalFile -> '%(File)')" />
+ </ItemGroup>
+
+ <Copy
+ SourceFiles="@(RunTimeDependecyCopyLocal)"
+ DestinationFolder="$(CoreOverlay)"
+ SkipUnchangedFiles="$(SkipCopyUnchangedFiles)"
+ OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
+ Retries="$(CopyRetryCount)"
+ RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
+ UseHardlinksIfPossible="$(CreateHardLinksForCopyFilesToOutputDirectoryIfPossible)">
+ <Output TaskParameter="DestinationFiles" ItemName="FileWrites" />
+ </Copy>
+
+ <ItemGroup>
+ <NonWindowsCrossGenFiles Include="..\packages\runtime.$(RuntimeID).Microsoft.NETCore.Runtime.CoreCLR\$(CoreClrPackageVersion)\tools\crossgen"/>
+ </ItemGroup>
+
+ <Copy
+ SourceFiles="@(NonWindowsCrossGenFiles)"
+ DestinationFolder="$(CoreOverlay)"
+ SkipUnchangedFiles="$(SkipCopyUnchangedFiles)"
+ OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
+ Retries="$(CopyRetryCount)"
+ RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
+ UseHardlinksIfPossible="$(CreateHardLinksForCopyFilesToOutputDirectoryIfPossible)">
+ <Output TaskParameter="DestinationFiles" ItemName="FileWrites" />
+ </Copy>
+
+ </Target>
+
+ <Target Name="CopyDependencyToRef"
+ Inputs="@(RefProjectLockJsonFiles)"
+ Outputs="$(RefDestination)\*.*">
+
+ <MSBuild Projects="$(SourceDir)Common\targeting_pack_ref\targeting_pack_ref.csproj"/>
+
+ <!-- This will use the overridden PrereleaseResolveNuGetPackageAssets, which outputs copy local items
+ for the xunit wrapper projects -->
+ <PrereleaseResolveNuGetPackageAssets AllowFallbackOnTargetSelection="true"
+ IncludeFrameworkReferences="false"
+ NuGetPackagesDirectory="$(PackagesDir)"
+ RuntimeIdentifier="$(TestNugetRuntimeId)"
+ ProjectLanguage="$(Language)"
+ ProjectLockFile="%(RefProjectLockJsonFiles.Identity)"
+ TargetMonikers="@(TestTargetFramework)">
+ <Output TaskParameter="ResolvedAnalyzers" ItemName="RefAnalyzer" />
+ <Output TaskParameter="ResolvedReferences" ItemName="RefReference" />
+ <Output TaskParameter="ResolvedCopyLocalItems" ItemName="RefRunTimeCopyLocal" />
+ </PrereleaseResolveNuGetPackageAssets>
+
+ <Copy
+ SourceFiles="@(RefRunTimeCopyLocal)"
+ DestinationFolder="$(RefDestination)"
+ SkipUnchangedFiles="$(SkipCopyUnchangedFiles)"
+ OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
+ Retries="$(CopyRetryCount)"
+ RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
+ UseHardlinksIfPossible="$(CreateHardLinksForCopyFilesToOutputDirectoryIfPossible)">
+ <Output TaskParameter="DestinationFiles" ItemName="FileWrites" />
+ </Copy>
+ </Target>
+
+ <Target Name="CopyDependencyToProduct"
+ Inputs="@(ProductProjectLockJsonFiles)"
+ Outputs="$(ProductDestination)\*.*">
+
+ <MSBuild Projects="$(SourceDir)Common\build_against_pkg_dependencies\build_against_pkg_dependencies.csproj"/>
+
+ <!-- This will use the overridden PrereleaseResolveNuGetPackageAssets, which outputs copy local items
+ for the xunit wrapper projects -->
+ <PrereleaseResolveNuGetPackageAssets AllowFallbackOnTargetSelection="true"
+ IncludeFrameworkReferences="false"
+ NuGetPackagesDirectory="$(PackagesDir)"
+ RuntimeIdentifier="$(TestNugetRuntimeId)"
+ ProjectLanguage="$(Language)"
+ ProjectLockFile="%(ProductProjectLockJsonFiles.Identity)"
+ TargetMonikers="@(TestTargetFramework)">
+ <Output TaskParameter="ResolvedAnalyzers" ItemName="RefAnalyzer" />
+ <Output TaskParameter="ResolvedReferences" ItemName="RefReference" />
+ <Output TaskParameter="ResolvedCopyLocalItems" ItemName="RefRunTimeCopyLocal" />
+ </PrereleaseResolveNuGetPackageAssets>
+
+ <Copy
+ SourceFiles="@(RefRunTimeCopyLocal)"
+ DestinationFolder="$(ProductDestination)"
+ SkipUnchangedFiles="$(SkipCopyUnchangedFiles)"
+ OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
+ Retries="$(CopyRetryCount)"
+ RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
+ UseHardlinksIfPossible="$(CreateHardLinksForCopyFilesToOutputDirectoryIfPossible)">
+ <Output TaskParameter="DestinationFiles" ItemName="FileWrites" />
+ </Copy>
+ </Target>
+
+ <Target Name="CopyCrossgenToProduct"
+ Outputs="$(ProductDestination)\crossgen.exe;$(CoreOverlay)\crossgen.exe">
+
+ <Copy
+ SourceFiles="@(CrossGenFiles)"
+ DestinationFolder="$(ProductDestination)"
+ SkipUnchangedFiles="$(SkipCopyUnchangedFiles)"
+ OverwriteReadOnlyFiles="$(OverwriteReadOnlyFiles)"
+ Retries="$(CopyRetryCount)"
+ RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)"
+ UseHardlinksIfPossible="$(CreateHardLinksForCopyFilesToOutputDirectoryIfPossible)">
+ <Output TaskParameter="DestinationFiles" ItemName="FileWrites" />
+ </Copy>
+
+ </Target>
+
</Project>
diff --git a/tests/runtest.cmd b/tests/runtest.cmd
index 5620789575..23b4bb5f42 100644
--- a/tests/runtest.cmd
+++ b/tests/runtest.cmd
@@ -1,10 +1,11 @@
-@if not defined __echo @echo off
+@if not defined _echo @echo off
setlocal EnableDelayedExpansion
:: Set the default arguments
set __BuildArch=x64
set __BuildType=Debug
set __BuildOS=Windows_NT
+set __MSBuildBuildArch=x64
:: Default to highest Visual Studio version available
set __VSVersion=vs2015
@@ -30,6 +31,8 @@ set __Sequential=
set __msbuildExtraArgs=
set __LongGCTests=
set __GCSimulatorTests=
+set __AgainstPackages=
+set __JitDisasm=
:Arg_Loop
if "%1" == "" goto ArgsDone
@@ -43,6 +46,7 @@ if /i "%1" == "-help" goto Usage
if /i "%1" == "x64" (set __BuildArch=x64&set __MSBuildBuildArch=x64&shift&goto Arg_Loop)
if /i "%1" == "x86" (set __BuildArch=x86&set __MSBuildBuildArch=x86&shift&goto Arg_Loop)
+if /i "%1" == "arm" (set __BuildArch=arm&set __MSBuildBuildArch=arm&shift&goto Arg_Loop)
if /i "%1" == "debug" (set __BuildType=Debug&shift&goto Arg_Loop)
if /i "%1" == "release" (set __BuildType=Release&shift&goto Arg_Loop)
@@ -55,6 +59,7 @@ if /i "%1" == "SkipWrapperGeneration" (set __SkipWrapperGeneration=true&shift&go
if /i "%1" == "Exclude" (set __Exclude=%2&shift&shift&goto Arg_Loop)
if /i "%1" == "Exclude0" (set __Exclude0=%2&shift&shift&goto Arg_Loop)
if /i "%1" == "TestEnv" (set __TestEnv=%2&shift&shift&goto Arg_Loop)
+if /i "%1" == "AgainstPackages" (set __AgainstPackages=1&shift&goto Arg_Loop)
if /i "%1" == "sequential" (set __Sequential=1&shift&goto Arg_Loop)
if /i "%1" == "crossgen" (set __DoCrossgen=1&shift&goto Arg_Loop)
if /i "%1" == "longgc" (set __LongGCTests=1&shift&goto Arg_Loop)
@@ -63,11 +68,12 @@ if /i "%1" == "jitstress" (set COMPlus_JitStress=%2&shift&shift&goto
if /i "%1" == "jitstressregs" (set COMPlus_JitStressRegs=%2&shift&shift&goto Arg_Loop)
if /i "%1" == "jitminopts" (set COMPlus_JITMinOpts=1&shift&shift&goto Arg_Loop)
if /i "%1" == "jitforcerelocs" (set COMPlus_ForceRelocs=1&shift&shift&goto Arg_Loop)
+if /i "%1" == "jitdisasm" (set __JitDisasm=1&shift&goto Arg_Loop)
if /i "%1" == "GenerateLayoutOnly" (set __GenerateLayoutOnly=1&set __SkipWrapperGeneration=true&shift&goto Arg_Loop)
if /i "%1" == "PerfTests" (set __PerfTests=true&set __SkipWrapperGeneration=true&shift&goto Arg_Loop)
if /i "%1" == "runcrossgentests" (set RunCrossGen=true&shift&goto Arg_Loop)
REM change it to COMPlus_GCStress when we stop using xunit harness
-if /i "%1" == "gcstresslevel" (set __GCSTRESSLEVEL=%2&set __TestTimeout=1800000&shift&shift&goto Arg_Loop)
+if /i "%1" == "gcstresslevel" (set __GCSTRESSLEVEL=%2&set __TestTimeout=1800000&shift&shift&goto Arg_Loop)
if /i not "%1" == "msbuildargs" goto SkipMsbuildArgs
:: All the rest of the args will be collected and passed directly to msbuild.
@@ -142,6 +148,10 @@ if not defined __Sequential (
set __msbuildCommonArgs=%__msbuildCommonArgs% /p:ParallelRun=false
)
+if defined __AgainstPackages (
+ set __msbuildCommonArgs=%__msbuildCommonArgs% /p:BuildTestsAgainstPackages=true
+)
+
REM Prepare the Test Drop
REM Cleans any NI from the last run
powershell "Get-ChildItem -path %__TestWorkingDir% -Include '*.ni.*' -Recurse -Force | Remove-Item -force"
@@ -160,8 +170,8 @@ xcopy /s "%__BinDir%" "%CORE_ROOT%"
:SkipCoreRootSetup
-if defined __Exclude (if not exist %__Exclude% echo %__MsgPrefix%Error: Exclusion .targets file not found && exit /b 1)
-if defined __TestEnv (if not exist %__TestEnv% echo %__MsgPrefix%Error: Test Environment script not found && exit /b 1)
+if defined __Exclude (if not exist %__Exclude% echo %__MsgPrefix%Error: Exclusion file %__Exclude% not found && exit /b 1)
+if defined __TestEnv (if not exist %__TestEnv% echo %__MsgPrefix%Error: Test Environment script %__TestEnv% not found && exit /b 1)
REM These log files are created automatically by the test run process. Q: what do they depend on being set?
set __TestRunHtmlLog=%__LogsDir%\TestRun_%__BuildOS%__%__BuildArch%__%__BuildType%.html
@@ -185,7 +195,7 @@ call :PrecompileFX
:SkipPrecompileFX
if defined __GenerateLayoutOnly (
- exit /b 1
+ exit /b 0
)
if not exist %CORE_ROOT%\coreclr.dll (
@@ -248,6 +258,8 @@ REM ============================================================================
REM Compile the managed assemblies in Core_ROOT before running the tests
:PrecompileAssembly
+if defined __JitDisasm goto :jitdisasm
+
REM Skip mscorlib since it is already precompiled.
if /I "%3" == "mscorlib.dll" exit /b 0
if /I "%3" == "mscorlib.ni.dll" exit /b 0
@@ -267,6 +279,27 @@ if %__exitCode% neq 0 (
echo Successfully precompiled %2
exit /b 0
+:jitdisasm
+
+if /I "%3" == "mscorlib.ni.dll" exit /b 0
+
+echo "%1\corerun" "%1\jit-dasm.dll" --crossgen %1\crossgen.exe --platform %CORE_ROOT% --output %__TestWorkingDir%\dasm "%2"
+"%1\corerun" "%1\jit-dasm.dll" --crossgen %1\crossgen.exe --platform %CORE_ROOT% --output %__TestWorkingDir%\dasm "%2"
+set /a __exitCode = %errorlevel%
+
+if "%__exitCode%" == "-2146230517" (
+ echo %2 is not a managed assembly.
+ exit /b 0
+)
+
+if %__exitCode% neq 0 (
+ echo Unable to precompile %2
+ exit /b 0
+)
+
+echo Successfully precompiled and generated dasm for %2
+exit /b 0
+
:PrecompileFX
for %%F in (%CORE_ROOT%\*.dll) do call :PrecompileAssembly "%CORE_ROOT%" "%%F" %%~nF%%~xF
exit /b 0
@@ -297,6 +330,7 @@ set __msbuildLogArgs=^
set __msbuildArgs=%* %__msbuildCommonArgs% %__msbuildLogArgs%
@REM The next line will overwrite the existing log file, if any.
+echo %_msbuildexe% %__msbuildArgs%
echo Invoking: %_msbuildexe% %__msbuildArgs% > "%__BuildLog%"
%_msbuildexe% %__msbuildArgs%
@@ -334,13 +368,23 @@ if defined __GCSimulatorTests (
set RunningGCSimulatorTests=1
)
+if defined __JitDisasm (
+ if defined __DoCrossgen (
+ echo Running jit disasm on framework and test assemblies
+ )
+ if not defined __DoCrossgen (
+ echo Running jit disasm on test assemblies only
+ )
+ set RunningJitDisasm=1
+)
+
set __BuildLogRootName=Tests_GenerateRuntimeLayout
call :msbuild "%__ProjectFilesDir%\runtest.proj" /p:GenerateRuntimeLayout=true
if errorlevel 1 (
echo Test Dependency Resolution Failed
exit /b 1
)
-echo %__MsgPrefix% Created the runtime layout with all dependencies in %CORE_ROOT%
+echo %__MsgPrefix%Created the runtime layout with all dependencies in %CORE_ROOT%
exit /b 0
@@ -360,12 +404,14 @@ echo Set to "" to disable default exclusion file.
echo Exclude- Optional parameter - this will exclude individual tests from running, specified by ExcludeList ItemGroup in an .targets file.
echo TestEnv- Optional parameter - this will run a custom script to set custom test environment settings.
echo VSVersion- Optional parameter - VS2013 or VS2015 ^(default: VS2015^)
+echo AgainstPackages - Optional parameter - this indicates that we are running tests that were built against packages
echo GenerateLayoutOnly - If specified will not run the tests and will only create the Runtime Dependency Layout
echo RunCrossgenTests - Runs ReadytoRun tests
echo jitstress n - Runs the tests with COMPlus_JitStress=n
echo jitstressregs n - Runs the tests with COMPlus_JitStressRegs=n
echo jitminopts - Runs the tests with COMPlus_JITMinOpts=1
echo jitforcerelocs - Runs the tests with COMPlus_ForceRelocs=1
+echo jitdisasm - Runs jit-dasm on the tests
echo gcstresslevel n - Runs the tests with COMPlus_GCStress=n
echo 0: None 1: GC on all allocs and 'easy' places
echo 2: GC on transitions to preemptive GC 4: GC on every allowable JITed instr
diff --git a/tests/runtest.proj b/tests/runtest.proj
index c02b8c8f9f..acc4545d92 100644
--- a/tests/runtest.proj
+++ b/tests/runtest.proj
@@ -64,7 +64,6 @@ $(_XunitEpilog)
]]>
</_XunitWrapperGen>
- <XunitVersionCompiled>2.1.0</XunitVersionCompiled>
<XunitWrapperGenCsProj>
<![CDATA[
<?xml version="1.0" encoding="utf-8"?>
@@ -120,7 +119,6 @@ $(_XunitEpilog)
<ProjectLockJson>%24(TestWrappersPackagesConfigFileDirectory)project.lock.json</ProjectLockJson>
</PropertyGroup>
<Import Project="$(SourceDir)dir.targets" />
- <Import Project="$(ProjectDir)helix.targets" />
<PropertyGroup>
<OutDir>$(XunitTestBinBase)\$(Category)\</OutDir>
</PropertyGroup>
@@ -307,31 +305,7 @@ namespace $([System.String]::Copy($(Category)).Replace(".","_").Replace("\","").
</Target>
<Target Name="CreateAllWrappers" DependsOnTargets="GetListOfTestCmds;FindCmdDirectories">
- <MSBuild Projects="$(MSBuildProjectFile)" Targets="CreateXunitWrapper" Properties="_CMDDIR=%(TestDirectories.Identity)" />
-
- <!--
- Contents of a project.json that will be restored once with errors turned off. This works
- around the package being incompatible with dotnet restore. Only the package contents are
- required so the compatibility errors can be ignored.
- -->
- <PropertyGroup>
- <XunitRunnerRestoreGenConfig>{ "dependencies": { "xunit.runner.msbuild": "$(XunitPackageVersion)" }, "frameworks": { "net45": {} } }</XunitRunnerRestoreGenConfig>
- <XunitRunnerRestoreProjectDir>$(BaseOutputPath)\tempRestoreProject</XunitRunnerRestoreProjectDir>
- <XunitRunnerRestoreProjectJsonPath>$(XunitRunnerRestoreProjectDir)\project.json</XunitRunnerRestoreProjectJsonPath>
- </PropertyGroup>
-
- <MakeDir Directories="$(XunitRunnerRestoreProjectDir)" />
- <WriteLinesToFile File="$(XunitRunnerRestoreProjectJsonPath)"
- Lines="$(XunitRunnerRestoreGenConfig)"
- Overwrite="true" />
-
- <Exec Command="$(DnuRestoreCommand) &quot;$(XunitRunnerRestoreProjectJsonPath)&quot;"
- StandardOutputImportance="Low"
- CustomErrorRegularExpression="^Unable to resolve .*"
- IgnoreExitCode="true"
- IgnoreStandardErrorWarningFormat="true" />
-
- <MSBuild Projects="$(MSBuildProjectFile)" Targets="BuildXunitWrapper" Properties="_CMDDIR=%(TestDirectories.Identity)" />
+ <MSBuild Projects="$(MSBuildProjectFile)" Targets="CreateXunitWrapper;BuildXunitWrapper" Properties="_CMDDIR=%(TestDirectories.Identity)" />
</Target>
<Target Name="GetListOfTestCmds">
@@ -349,6 +323,28 @@ namespace $([System.String]::Copy($(Category)).Replace(".","_").Replace("\","").
Properties="Language=C#" />
</Target>
+ <Target Name="CreateNonWindowsTestOverlay">
+ <MSBuild Projects="$(MSBuildProjectFile)"
+ Targets="CopyNonWindowsDependecyToCoreRoot"
+ Properties="Language=C#;NonWindowsRuntimeId=$(NonWindowsRuntimeId)" />
+ </Target>
+
+ <Target Name="BinPlaceRef">
+ <!-- Copy mscorlib.dll from TargetingPack to bin/Product/ref, if we're building against packages -->
+ <MSBuild Projects="$(MSBuildProjectFile)"
+ Targets="CopyDependencyToRef"
+ Properties="Language=C#"
+ Condition=" '$(BuildTestsAgainstPackages)'=='true' " />
+ </Target>
+
+ <Target Name="BinPlaceProduct">
+ <!-- Copy test dependencies to bin/Product, if we're building against packages -->
+ <MSBuild Projects="$(MSBuildProjectFile)"
+ Targets="CopyDependencyToProduct"
+ Properties="Language=C#"
+ Condition=" '$(BuildTestsAgainstPackages)'=='true' " />
+ </Target>
+
<!-- All the test projects need to add dependency to currently built runtime as they require that to run.
In addition the version number of built runtime can change so all project.json needs to be dynamically generated.
Instead the following task creates a project.json with dependencies like Microsoft.netcore.runtime.coreclr ..etc.
diff --git a/tests/runtest.sh b/tests/runtest.sh
index cd5da9484d..1c67a70db7 100755
--- a/tests/runtest.sh
+++ b/tests/runtest.sh
@@ -50,6 +50,7 @@ function print_usage {
echo ' --jitstressregs=<n> : Runs the tests with COMPlus_JitStressRegs=n'
echo ' --jitminopts : Runs the tests with COMPlus_JITMinOpts=1'
echo ' --jitforcerelocs : Runs the tests with COMPlus_ForceRelocs=1'
+ echo ' --jitdisasm : Runs jit-dasm on the tests'
echo ' --gcstresslevel n : Runs the tests with COMPlus_GCStress=n'
echo ' 0: None 1: GC on all allocs and '"'easy'"' places'
echo ' 2: GC on transitions to preemptive GC 4: GC on every allowable JITed instr'
@@ -392,30 +393,43 @@ function create_core_overlay {
# Test dependencies come from a Windows build, and mscorlib.ni.dll would be the one from Windows
rm -f "$coreOverlayDir/mscorlib.ni.dll"
fi
+ if [ -f "$coreOverlayDir/System.Private.CoreLib.ni.dll" ]; then
+ # Test dependencies come from a Windows build, and System.Private.CoreLib.ni.dll would be the one from Windows
+ rm -f "$coreOverlayDir/System.Private.CoreLib.ni.dll"
+ fi
+ copy_test_native_bin_to_test_root
}
function precompile_overlay_assemblies {
if [ $doCrossgen == 1 ]; then
-
local overlayDir=$CORE_ROOT
filesToPrecompile=$(ls -trh $overlayDir/*.dll)
for fileToPrecompile in ${filesToPrecompile}
do
local filename=${fileToPrecompile}
- # Precompile any assembly except mscorlib since we already have its NI image available.
- if [[ "$filename" != *"mscorlib.dll"* ]]; then
- if [[ "$filename" != *"mscorlib.ni.dll"* ]]; then
- echo Precompiling $filename
- $overlayDir/crossgen /Platform_Assemblies_Paths $overlayDir $filename 2>/dev/null
- local exitCode=$?
- if [ $exitCode == -2146230517 ]; then
- echo $filename is not a managed assembly.
- elif [ $exitCode != 0 ]; then
- echo Unable to precompile $filename.
- else
- echo Successfully precompiled $filename
+ if [ $jitdisasm == 1]; then
+
+ $overlayDir/corerun $overlayDir/jit-dasm.dll --crossgen $overlayDir/crossgen --platform $overlayDir --output $testRootDir/dasm $filename
+ local exitCode=$?
+ if [ $exitCode != 0 ]; then
+ echo Unable to generate dasm for $filename
+ fi
+ else
+ # Precompile any assembly except mscorlib since we already have its NI image available.
+ if [[ "$filename" != *"mscorlib.dll"* ]]; then
+ if [[ "$filename" != *"mscorlib.ni.dll"* ]]; then
+ echo Precompiling $filename
+ $overlayDir/crossgen /Platform_Assemblies_Paths $overlayDir $filename 2>/dev/null
+ local exitCode=$?
+ if [ $exitCode == -2146230517 ]; then
+ echo $filename is not a managed assembly.
+ elif [ $exitCode != 0 ]; then
+ echo Unable to precompile $filename.
+ else
+ echo Successfully precompiled $filename
+ fi
fi
fi
fi
@@ -737,10 +751,14 @@ function finish_test {
local testRunningTime=
local header=
+ if ((verbose == 1)); then
+ header=$(printf "[%4d]" $countTotalTests)
+ fi
+
if [ "$showTime" == "ON" ]; then
testEndTime=$(date +%s)
- testRunningTime=$(echo "$testEndTime - ${testStartTimes[$nextProcessIndex]}" | bc)
- header=$(printf "[%03d:%4.0fs] " "$countTotalTests" "$testRunningTime")
+ testRunningTime=$(( $testEndTime - ${testStartTimes[$nextProcessIndex]} ))
+ header=$header$(printf "[%4ds]" $testRunningTime)
fi
local xunitTestResult
@@ -790,6 +808,7 @@ function finish_remaining_tests {
function prep_test {
local scriptFilePath=$1
+ local scriptFileDir=$(dirname "$scriptFilePath")
test "$verbose" == 1 && echo "Preparing $scriptFilePath"
@@ -802,8 +821,8 @@ function prep_test {
chmod +x "$scriptFilePath"
#remove any NI and Locks
- rm -f *.ni.*
- rm -rf lock
+ rm -f $scriptFileDir/*.ni.*
+ rm -rf $scriptFileDir/lock
}
function start_test {
@@ -909,15 +928,9 @@ function coreclr_code_coverage {
}
function check_cpu_architecture {
- # Use uname to determine what the CPU is.
- local CPUName=$(uname -p)
+ local CPUName=$(uname -m)
local __arch=
- # Some Linux platforms report unknown for platform, but the arch for machine.
- if [ "$CPUName" == "unknown" ]; then
- CPUName=$(uname -m)
- fi
-
case $CPUName in
i686)
__arch=x86
@@ -941,6 +954,7 @@ function check_cpu_architecture {
}
ARCH=$(check_cpu_architecture)
+echo "Running on CPU- $ARCH"
# Exit code constants
readonly EXIT_CODE_SUCCESS=0 # Script ran normally.
@@ -973,6 +987,7 @@ limitedCoreDumps=
# Handle arguments
verbose=0
doCrossgen=0
+jitdisasm=0
for i in "$@"
do
@@ -999,6 +1014,9 @@ do
--jitforcerelocs)
export COMPlus_ForceRelocs=1
;;
+ --jitdisasm)
+ jitdisasm=1
+ ;;
--testRootDir=*)
testRootDir=${i#*=}
;;
@@ -1125,6 +1143,11 @@ if [ ! -z "$gcsimulator" ]; then
export RunningGCSimulatorTests=1
fi
+if [ ! -z "$jitdisasm" ]; then
+ echo "Running jit disasm"
+ export RunningJitDisasm=1
+fi
+
# If this is a coverage run, make sure the appropriate args have been passed
if [ "$CoreClrCoverage" == "ON" ]
then
@@ -1161,7 +1184,6 @@ fi
xunit_output_begin
create_core_overlay
precompile_overlay_assemblies
-copy_test_native_bin_to_test_root
if [ "$buildOverlayOnly" == "ON" ];
then
diff --git a/tests/scripts/arm32_ci_script.sh b/tests/scripts/arm32_ci_script.sh
index 1b016bbd8f..85ee4d21f5 100755
--- a/tests/scripts/arm32_ci_script.sh
+++ b/tests/scripts/arm32_ci_script.sh
@@ -128,6 +128,8 @@ function clean_env {
#Check for revert of git changes
check_git_head
+
+ sudo rm -rf "/mnt/arm32_ci_temp"
}
#Trap Ctrl-C and handle it
@@ -173,37 +175,56 @@ function mount_emulator {
sudo mkdir "$__ARMRootfsMountPath"
fi
- set +x
- mount_with_checking "" "$__ARMEmulPath/platform/rootfs-t30.ext4" "$__ARMRootfsMountPath"
- mount_with_checking "-t proc" "/proc" "$__ARMRootfsMountPath/proc"
- mount_with_checking "-o bind" "/dev/" "$__ARMRootfsMountPath/dev"
- mount_with_checking "-o bind" "/dev/pts" "$__ARMRootfsMountPath/dev/pts"
- mount_with_checking "-t tmpfs" "shm" "$__ARMRootfsMountPath/run/shm"
- mount_with_checking "-o bind" "/sys" "$__ARMRootfsMountPath/sys"
- if [ ! -d "$__ARMRootfsMountPath/bindings/tmp" ]; then
- sudo mkdir -p "$__ARMRootfsMountPath/bindings/tmp"
+ if [ ! -d "$__ARMEmulRootfs" ]; then
+ sudo mkdir "$__ARMEmulRootfs"
+ fi
+
+ if [ ! -f "$__ARMEmulRootfs/arm-emulator-rootfs.tar" ]; then
+ if mountpoint -q -- "$__ARMRootfsMountPath"; then
+ sudo umount -l $__ARMRootfsMountPath
+ fi
+ mount_with_checking "" "$__ARMEmulPath/platform/rootfs-t30.ext4" "$__ARMRootfsMountPath"
+
+ cd $__ARMRootfsMountPath
+ sudo tar -cf "$__ARMEmulRootfs/arm-emulator-rootfs.tar" *
+ cd -
+ fi
+
+ sudo tar -xf "$__ARMEmulRootfs/arm-emulator-rootfs.tar" -C "$__ARMEmulRootfs"
+
+ mount_with_checking "-t proc" "/proc" "$__ARMEmulRootfs/proc"
+ mount_with_checking "-o bind" "/dev/" "$__ARMEmulRootfs/dev"
+ mount_with_checking "-o bind" "/dev/pts" "$__ARMEmulRootfs/dev/pts"
+ mount_with_checking "-t tmpfs" "shm" "$__ARMEmulRootfs/run/shm"
+ mount_with_checking "-o bind" "/sys" "$__ARMEmulRootfs/sys"
+ if [ ! -d "$__ARMEmulRootfs/bindings/tmp" ]; then
+ sudo mkdir -p "$__ARMEmulRootfs/bindings/tmp"
fi
- mount_with_checking "-o bind" "/mnt" "$__ARMRootfsMountPath/bindings/tmp"
+ mount_with_checking "-o bind" "/mnt" "$__ARMEmulRootfs/bindings/tmp"
+
+ if [ ! -d "$__ARMEmulRootfs/$__TempFolder" ]; then
+ sudo mkdir "$__ARMEmulRootfs/$__TempFolder"
+ fi
}
#Cross builds coreclr
function cross_build_coreclr {
#Export the needed environment variables
(set +x; echo 'Exporting LINUX_ARM_* environment variable')
- source "$__ARMRootfsMountPath"/dotnet/setenv/setenv_incpath.sh "$__ARMRootfsMountPath"
+ source "$__ARMEmulRootfs"/dotnet/setenv/setenv_incpath.sh "$__ARMEmulRootfs"
#Apply the changes needed to build for the emulator rootfs
(set +x; echo 'Applying cross build patch to suit Linux ARM emulator rootfs')
- git am < "$__ARMRootfsMountPath"/dotnet/setenv/coreclr_cross.patch
+ git am < "$__ARMEmulRootfs"/dotnet/setenv/coreclr_cross.patch
#Apply release optimization patch if needed
if [[ "$__buildConfig" == "Release" ]]; then
(set +x; echo 'Applying release optimization patch to build in Release mode')
- git am < "$__ARMRootfsMountPath"/dotnet/setenv/coreclr_release.patch
+ git am < "$__ARMEmulRootfs"/dotnet/setenv/coreclr_release.patch
fi
#Cross building for emulator rootfs
- ROOTFS_DIR="$__ARMRootfsMountPath" CPLUS_INCLUDE_PATH=$LINUX_ARM_INCPATH CXXFLAGS=$LINUX_ARM_CXXFLAGS ./build.sh $__buildArch cross $__verboseFlag $__skipMscorlib clang3.5 $__buildConfig -rebuild
+ ROOTFS_DIR="$__ARMEmulRootfs" CPLUS_INCLUDE_PATH=$LINUX_ARM_INCPATH CXXFLAGS=$LINUX_ARM_CXXFLAGS ./build.sh $__buildArch cross $__verboseFlag $__skipMscorlib clang3.5 $__buildConfig -rebuild
#Reset the code to the upstream version
(set +x; echo 'Rewinding HEAD to master code')
@@ -268,9 +289,10 @@ function copy_to_emulator {
#Runs tests in an emulated mode
function run_tests {
- sudo chroot $__ARMRootfsMountPath /bin/bash -x <<EOF
+ sudo chroot $__ARMEmulRootfs /bin/bash -x <<EOF
cd "$__ARMEmulCoreclr"
- ./tests/runtest.sh --testRootDir=$__testRootDirBase \
+ ./tests/runtest.sh --sequential\
+ --testRootDir=$__testRootDirBase \
--mscorlibDir=$__mscorlibDirBase \
--coreFxNativeBinDir=$__coreFxNativeBinDirBase \
--coreFxBinDir="$__coreFxBinDirBase" \
@@ -281,6 +303,7 @@ EOF
}
#Define script variables
+__ARMEmulRootfs=/mnt/arm-emulator-rootfs
__ARMEmulPath=
__ARMRootfsMountPath=
__buildConfig=
@@ -397,13 +420,8 @@ __buildDirName="$__buildOS.$__buildArch.$__buildConfig"
#Define emulator paths
__TempFolder="bindings/tmp/arm32_ci_temp"
-
-if [ ! -d "$__TempFolder" ]; then
- mkdir "$__TempFolder"
-fi
-
-__ARMRootfsCoreclrPath="$__ARMRootfsMountPath/$__TempFolder/coreclr"
-__ARMRootfsCorefxPath="$__ARMRootfsMountPath/$__TempFolder/corefx"
+__ARMRootfsCoreclrPath="$__ARMEmulRootfs/$__TempFolder/coreclr"
+__ARMRootfsCorefxPath="$__ARMEmulRootfs/$__TempFolder/corefx"
__ARMEmulCoreclr="/$__TempFolder/coreclr"
__ARMEmulCorefx="/$__TempFolder/corefx"
__testRootDirBase=
@@ -447,10 +465,10 @@ copy_to_emulator
(set +x; echo 'Running tests...')
run_tests
+
#Clean the environment
(set +x; echo 'Cleaning environment...')
clean_env
-rm -r "/mnt/arm32_ci_temp"
(set +x; echo 'Build and test complete')
diff --git a/tests/scripts/arm64_post_build.py b/tests/scripts/arm64_post_build.py
new file mode 100644
index 0000000000..49f5f6a452
--- /dev/null
+++ b/tests/scripts/arm64_post_build.py
@@ -0,0 +1,311 @@
+################################################################################
+################################################################################
+#
+# Module: arm64_post_build.py
+#
+# Notes:
+#
+# This script is responsible for starting the x64 dotnet client. In order to
+# do this it has to pass along the core_root that was built in the previous
+# build steps using build.cmd.
+#
+# After everything has run, the dotnet client will dump a bunch of information
+# to the console. It will be captured, parsed, and a series of xunit xml files
+# will be created so that jenkins can parse it to display results.
+#
+################################################################################
+################################################################################
+
+import argparse
+import errno
+import os
+import urllib
+import urllib2
+import shutil
+import subprocess
+import sys
+import zipfile
+
+from collections import defaultdict
+
+################################################################################
+# Globals
+################################################################################
+
+g_arm64ci_path = os.path.join(os.environ["USERPROFILE"], "bin")
+g_dotnet_url = "https://go.microsoft.com/fwlink/?LinkID=831469"
+g_test_url = "https://clrjit.blob.core.windows.net/arm64ci/CoreCLRTests-2c0a2c05ba82460a8d8a4b1e2d98e908e59d5d54.zip"
+g_x64_client_url = "https://clrjit.blob.core.windows.net/arm64ci/x64_client.zip"
+
+################################################################################
+# Argument Parser
+################################################################################
+
+description = """Python script to facilitate running an arm64/arm test run using
+ the cloud.
+ """
+
+parser = argparse.ArgumentParser(description=description)
+
+parser.add_argument("--force_update", dest="force_update", action="store_true", default=False)
+
+parser.add_argument("-repo_root", dest="repo_root", nargs='?', default=None)
+parser.add_argument("-arch", dest="arch", nargs='?', default=None)
+parser.add_argument("-build_type", dest="build_type", nargs='?', default=None)
+parser.add_argument("-scenario", dest="scenario", nargs='?', default=None)
+parser.add_argument("-key_location", dest="key_location", nargs='?', default=None)
+
+################################################################################
+# Helper Functions
+################################################################################
+
+def add_item_to_path(location):
+ """ Add the dotnet install to the path
+ """
+
+ os.environ["PATH"] = location + ";" + os.environ["PATH"]
+
+def copy_core_root(core_root):
+ """ Copy the core root directory to the current dir as "build"
+ Args:
+ core_root (str): location of the core_root directory
+ Returns:
+ copy_location (str): name of the location, for now hardcoded to build
+ : for backcompat in the old system
+ """
+
+ new_location = "build"
+
+ # Delete used instances.
+ if os.path.isdir(new_location):
+ try:
+ shutil.rmtree(new_location)
+ except:
+ assert not os.path.isdir(new_location)
+
+ try:
+ shutil.copytree(core_root, new_location)
+
+ except OSError as error:
+ log("Core Root not copied. Error: %s" % error)
+
+ return new_location
+
+def log(message):
+ """ Helper function to print logging information
+ Args:
+ message (str): message to be printed
+ """
+
+ print "[arm64_post_build]: %s" % (message)
+
+def setup_cli(force_update=False):
+ """ Install the dotnet cli onto the machine
+ Args:
+ force_update (bool): whether or not to force an update.
+ Return:
+ install_location (str): location of the installed cli
+ Notes:
+ This will be installed to %USERPROFILE%\dotnet. If force update is False
+ then we will not install the cli if it already exists.
+
+ """
+ global g_dotnet_url
+
+ install_path = os.path.join(os.environ["USERPROFILE"], "dotnet")
+
+ # Only install if the cli doesn't exist or we are forcing an update
+ if not os.path.isdir(install_path) or force_update:
+ log("Downloading the .NET CLI")
+ if os.path.isdir(install_path):
+ try:
+ shutil.rmtree(install_path)
+ except:
+ assert not os.path.isdir(install_path)
+
+ os.mkdir(install_path)
+
+ filename = os.path.join(install_path, 'dotnet-cli.zip')
+ urllib.urlretrieve(g_dotnet_url, filename)
+
+ if not os.path.isfile(filename):
+ raise Exception("Error failed to download cli.")
+
+ with zipfile.ZipFile(filename, 'r') as file_handle:
+ file_handle.extractall(install_path)
+
+ return install_path
+
+def setup_x64_client(key_location, force_update=True):
+ """ Setup the x64 client which will be used to communicate to the proxy
+ Args:
+ force_update (bool): whether or not to force an update, defaults to true
+ Return:
+ install_location (str): location of the installed x64_client
+ Notes:
+ Assume that the package has changed, so that every run will trigger an
+ update. If there is no update then the install will be fairly quick either
+ way.
+ """
+ global g_x64_client_url
+ install_path = os.path.join(os.environ["USERPROFILE"], "bin")
+
+ # If installed and force update is not set. Just return
+ if os.path.isdir(install_path) and not force_update:
+ return install_path
+
+ log("Downloading the x64_client")
+
+ if os.path.isdir(install_path):
+ # Delete the old location
+ try:
+ shutil.rmtree(install_path)
+ except:
+ assert not os.path.isdir(install_path)
+ os.mkdir(install_path)
+
+ filename = os.path.join(install_path, 'x64_client.zip')
+ urllib.urlretrieve(g_x64_client_url, filename)
+
+ if not os.path.isfile(filename):
+ raise Exception("Error failed to download the x64_client.")
+
+ with zipfile.ZipFile(filename, 'r') as file_handle:
+ file_handle.extractall(install_path)
+
+ # Copy key_location
+ shutil.copy2(key_location, install_path)
+
+ return install_path
+
+def validate_args(args):
+ """ Validate all of the arguments parsed.
+ Args:
+ args (argparser.ArgumentParser): Args parsed by the argument parser.
+ Returns:
+ (workspace, arch, build_type, scenario, force_update): (str,
+ str,
+ str,
+ str,
+ str,
+ bool)
+ Notes:
+ If the arguments are valid then return them all in a tuple. If not, raise
+ an exception stating x argument is incorrect.
+ """
+
+ repo_root = args.repo_root
+ arch = args.arch
+ build_type = args.build_type
+ scenario = args.scenario
+ key_location = args.key_location
+ force_update = args.force_update
+
+ def validate_arg(arg, check):
+ """ Validate an individual arg
+ Args:
+ arg (str|bool): argument to be validated
+ check (lambda: x-> bool): check that returns either True or False
+ : based on whether the check works.
+
+ Returns:
+ is_valid (bool): Is the argument valid?
+ """
+
+ helper = lambda item: item is not None and check(item)
+
+ if not helper(arg):
+ raise Exception("Argument: %s is not valid." % (arg))
+
+ valid_arches = ["arm", "arm64"]
+ valid_build_types = ["debug", "checked", "release"]
+ valid_scenarios = ["default", "pri1r2r", "gcstress0x3", "gcstress0xc"]
+
+ validate_arg(repo_root, lambda item: os.path.isdir(item))
+ validate_arg(arch, lambda item: item.lower() in valid_arches)
+ validate_arg(build_type, lambda item: item.lower() in valid_build_types)
+ validate_arg(scenario, lambda item: item.lower() in valid_scenarios)
+ validate_arg(key_location, lambda item: os.path.isfile(item))
+ validate_arg(force_update, lambda item: isinstance(item, bool))
+
+ arch = arch.lower()
+ build_type = build_type.lower()
+ scenario = scenario.lower()
+
+ args = (repo_root, arch, build_type, scenario, key_location, force_update)
+
+ log("Passed args: "
+ "Repo Root: %s, "
+ "Build Arch: %s, "
+ "Config: %s, "
+ "Scenario: %s, "
+ "Key Location: %s" % (repo_root, arch, build_type, scenario, key_location))
+
+ return args
+
+################################################################################
+# Main
+################################################################################
+
+def main(args):
+ global g_arm64ci_path
+ global g_test_url
+
+ repo_root, arch, build_type, scenario, key_location, force_update = validate_args(args)
+
+ core_root = os.path.join(repo_root,
+ "bin",
+ "Product",
+ "Windows_NT.%s.%s" % (arch, build_type))
+
+ cli_location = setup_cli(force_update=force_update)
+ add_item_to_path(cli_location)
+
+ g_arm64ci_path = setup_x64_client(key_location)
+
+ cwd = os.getcwd()
+ os.chdir(g_arm64ci_path)
+
+ core_root = copy_core_root(core_root)
+ log("Copied core_root to %s." % core_root)
+
+ # Make sure the lst file is copied into the core_root
+ lst_file = os.path.join(repo_root, "tests", arch, "Tests.lst")
+ shutil.copy2(lst_file, core_root)
+ log("Copied %s to %s." % (lst_file, core_root))
+
+ args = ["dotnet",
+ os.path.join(g_arm64ci_path, "x64_client.dll"),
+ arch,
+ build_type,
+ scenario,
+ core_root,
+ g_test_url]
+
+ log(" ".join(args))
+ proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ std_out, std_err = proc.communicate()
+
+ # Restore directory
+ os.chdir(cwd)
+
+ if std_out == "":
+ print std_err
+ else:
+ print std_out
+
+ if std_out is not None and isinstance(std_out, str):
+ if len(std_out.split("TestID")) > 1:
+ sys.exit(1)
+
+ # This run has been successful.
+ elif len(std_out) > 0:
+ sys.exit(0)
+
+################################################################################
+# setup for Main
+################################################################################
+
+if __name__ == "__main__":
+ args = parser.parse_args(sys.argv[1:])
+ main(args)
diff --git a/tests/scripts/format.py b/tests/scripts/format.py
index 50a0d3dc70..9736c033b2 100644
--- a/tests/scripts/format.py
+++ b/tests/scripts/format.py
@@ -176,30 +176,52 @@ def main(argv):
my_env["PATH"] += os.pathsep + jitutilsBin
current_dir = os.getcwd()
- if os.path.isdir(jitutilsBin):
- os.chdir(jitutilsBin)
- else:
+ if not os.path.isdir(jitutilsBin):
print("Jitutils not built!")
return -1
- jitformat = ""
+ jitformat = jitutilsBin
if platform == 'Linux' or platform == 'OSX':
- jitformat = "jit-format"
+ jitformat = os.path.join(jitformat, "jit-format")
elif platform == 'Windows_NT':
- jitformat = "jit-format.cmd"
+ jitformat = os.path.join(jitformat,"jit-format.bat")
+ errorMessage = ""
+
+ builds = ["Checked", "Debug", "Release"]
+ projects = ["dll", "standalone", "crossgen"]
- for build in ["Checked", "Debug", "Release"]:
- for project in ["dll", "standalone", "crossgen"]:
+ for build in builds:
+ for project in projects:
proc = subprocess.Popen([jitformat, "-a", arch, "-b", build, "-o", platform, "-c", coreclr, "--verbose", "--projects", project], env=my_env)
output,error = proc.communicate()
errorcode = proc.returncode
if errorcode != 0:
+ errorMessage += "\tjit-format -a " + arch + " -b " + build + " -o " + platform
+ errorMessage += " -c <absolute-path-to-coreclr> --verbose --fix --projects " + project +"\n"
returncode = errorcode
+ # Fix mode doesn't return an error, so we have to run the build, then run with
+ # --fix to generate the patch. This means that it is likely only the first run
+ # of jit-format will return a formatting failure.
+ if errorcode == -2:
+ # If errorcode was -2, no need to run clang-tidy again
+ proc = subprocess.Popen([jitformat, "--fix", "--untidy", "-a", arch, "-b", build, "-o", platform, "-c", coreclr, "--verbose", "--projects", project], env=my_env)
+ output,error = proc.communicate()
+ else:
+ # Otherwise, must run both
+ proc = subprocess.Popen([jitformat, "--fix", "-a", arch, "-b", build, "-o", platform, "-c", coreclr, "--verbose", "--projects", project], env=my_env)
+ output,error = proc.communicate()
+
os.chdir(current_dir)
+ if returncode != 0:
+ # Create a patch file
+ patchFile = open("format.patch", "w")
+ proc = subprocess.Popen(["git", "diff", "--patch", "-U20"], env=my_env, stdout=patchFile)
+ output,error = proc.communicate()
+
if os.path.isdir(jitUtilsPath):
print("Deleting " + jitUtilsPath)
shutil.rmtree(jitUtilsPath, onerror=del_rw)
@@ -212,6 +234,14 @@ def main(argv):
print("Deleting " + bootstrapPath)
os.remove(bootstrapPath)
+ if returncode != 0:
+ buildUrl = my_env["BUILD_URL"]
+ print("There were errors in formatting. Please run jit-format locally with: \n")
+ print(errorMessage)
+ print("\nOr download and apply generated patch:")
+ print("wget " + buildUrl + "artifact/format.patch")
+ print("git apply format.patch")
+
return returncode
if __name__ == '__main__':
diff --git a/tests/scripts/perf-prep.sh b/tests/scripts/perf-prep.sh
new file mode 100755
index 0000000000..27e4100bd6
--- /dev/null
+++ b/tests/scripts/perf-prep.sh
@@ -0,0 +1,78 @@
+#!/usr/bin/env bash
+
+function print_usage {
+ echo ''
+ echo 'CoreCLR perf test environment set up script on Linux.'
+ echo ''
+ echo 'Typical command line:'
+ echo ''
+ echo 'coreclr/tests/scripts/perf-perp.sh'
+ echo ' --branch="dotnet_coreclr"'
+ echo ''
+ echo 'Required arguments:'
+ echo ' --branch=<path> : branch where coreclr/corefx/test bits are copied from (e.g. dotnet_coreclr).'
+}
+
+# Exit code constants
+readonly EXIT_CODE_SUCCESS=0 # Script ran normally.
+
+# Argument variables
+perfArch="x64"
+perfConfig="Release"
+perfBranch=
+
+for i in "$@"
+do
+ case $i in
+ -h|--help)
+ print_usage
+ exit $EXIT_CODE_SUCCESS
+ ;;
+ --branch=*)
+ perfBranch=${i#*=}
+ ;;
+ *)
+ echo "Unknown switch: $i"
+ print_usage
+ exit $EXIT_CODE_SUCCESS
+ ;;
+ esac
+done
+
+perfBranch="dotnet_coreclr"
+echo "branch = $perfBranch"
+echo "architecture = $perfArch"
+echo "configuration = $perfConfig"
+
+# Since not all perf machines have Mono we cannot run nuget locally to get the Benchview tools
+# Instead we curl the package feed and use grep and sed to find the newest package.
+# We grep for content type and that returns us strings that contain the path to the nupkg
+# Then we match only the last line using '$' and use the s command to replace the entire line
+# with what we find inside of the quotes after src=. We then jump to label x on a match and if
+# we don't match we delete the line. This returns just the address of the last nupkg to curl.
+curl "http://benchviewtestfeed.azurewebsites.net/nuget/FindPackagesById()?id='Microsoft.BenchView.JSONFormat'" | grep "content type" | sed "$ s/.*src=\"\([^\"]*\)\".*/\1/;tx;d;:x" | xargs curl -o benchview.zip
+unzip -q -o benchview.zip -d ./tests/scripts/Microsoft.BenchView.JSONFormat
+
+# Install python 3.5.2 to run machinedata.py for machine data collection
+python3.5 --version
+python3.5 ./tests/scripts/Microsoft.BenchView.JSONFormat/tools/machinedata.py
+
+# Set up the copies
+# Coreclr build containing the tests and mscorlib
+curl http://ci.dot.net/job/$perfBranch/job/master/job/release_windows_nt/lastSuccessfulBuild/artifact/bin/tests/tests.zip -L -o tests.zip
+
+
+# Corefx components. We now have full stack builds on all distros we test here, so we can copy straight from CoreFX jobs.
+mkdir corefx
+curl http://ci.dot.net/job/dotnet_corefx/job/master/job/ubuntu14.04_release/lastSuccessfulBuild/artifact/bin/build.tar.gz -L -o ./corefx/build.tar.gz
+
+# Unpack the corefx binaries
+pushd corefx > /dev/null
+tar -xf build.tar.gz
+popd > /dev/null
+
+# Unzip the tests first. Exit with 0
+mkdir bin
+mkdir bin/tests
+unzip -q -o tests.zip -d ./bin/tests/Windows_NT.$perfArch.$perfConfig || exit 0
+echo "unzip tests to ./bin/tests/Windows_NT.$perfArch.$perfConfig"
diff --git a/tests/scripts/project.json b/tests/scripts/project.json
index 8601127d71..b3c3a15f62 100644
--- a/tests/scripts/project.json
+++ b/tests/scripts/project.json
@@ -1,15 +1,18 @@
{
"dependencies": {
- "Microsoft.DotNet.xunit.performance.run.core": "1.0.0-alpha-build0035",
- "Microsoft.DotNet.xunit.performance.analysis.cli": "1.0.0-alpha-build0035",
- "Microsoft.DotNet.xunit.performance.runner.cli": "1.0.0-alpha-build0035",
- "Microsoft.DotNet.xunit.performance":"1.0.0-alpha-build0035",
- "xunit.console.netcore": "1.0.3-prerelease-00607-01",
- "Microsoft.DotNet.BuildTools.TestSuite": "1.0.0-prerelease-00629-04",
+ "Microsoft.DotNet.xunit.performance.run.core": "1.0.0-alpha-build0040",
+ "Microsoft.DotNet.xunit.performance.analysis.cli": "1.0.0-alpha-build0040",
+ "Microsoft.DotNet.xunit.performance.runner.cli": "1.0.0-alpha-build0040",
+ "Microsoft.DotNet.xunit.performance": "1.0.0-alpha-build0040",
+ "xunit.console.netcore": "1.0.2-prerelease-00177",
+ "Microsoft.DotNet.BuildTools.TestSuite": "1.0.0-prerelease-00629-04"
},
"frameworks": {
- "netstandard1.3":{
- "imports":["dnxcore50", "portable-net45+win8"]
- }
+ "netstandard1.3": {
+ "imports": [
+ "dnxcore50",
+ "portable-net45+win8"
+ ]
+ }
}
-} \ No newline at end of file
+}
diff --git a/tests/scripts/run-xunit-perf.cmd b/tests/scripts/run-xunit-perf.cmd
index 89a7dac23f..a7d3c410d7 100644
--- a/tests/scripts/run-xunit-perf.cmd
+++ b/tests/scripts/run-xunit-perf.cmd
@@ -26,16 +26,18 @@ if NOT EXIST %CORECLR_OVERLAY% (
@echo --- setting up sandbox
-rd /s /q sandbox
-mkdir sandbox
+if exist sandbox rd /s /q sandbox
+if exist sandbox echo ERROR: Failed to remove the sandbox folder& exit /b 1
+if not exist sandbox mkdir sandbox
+if not exist sandbox echo ERROR: Failed to create the sandbox folder& exit /b 1
pushd sandbox
@rem stage stuff we need
@rem xunit and perf
-xcopy /sy %CORECLR_REPO%\packages\Microsoft.DotNet.xunit.performance.runner.Windows\1.0.0-alpha-build0035\tools\* . > %RUNLOG%
-xcopy /sy %CORECLR_REPO%\packages\Microsoft.DotNet.xunit.performance.analysis\1.0.0-alpha-build0035\tools\* . >> %RUNLOG%
-xcopy /sy %CORECLR_REPO%\packages\xunit.console.netcore\1.0.2-prerelease-00101\runtimes\any\native\* . >> %RUNLOG%
+xcopy /sy %CORECLR_REPO%\packages\Microsoft.DotNet.xunit.performance.runner.Windows\1.0.0-alpha-build0040\tools\* . > %RUNLOG%
+xcopy /sy %CORECLR_REPO%\packages\Microsoft.DotNet.xunit.performance.analysis\1.0.0-alpha-build0040\tools\* . >> %RUNLOG%
+xcopy /sy %CORECLR_REPO%\packages\xunit.console.netcore\1.0.2-prerelease-00177\runtimes\any\native\* . >> %RUNLOG%
xcopy /sy %CORECLR_REPO%\bin\tests\Windows_NT.%TEST_ARCH%.%TEST_CONFIG%\Tests\Core_Root\* . >> %RUNLOG%
@rem find and stage the tests
@@ -43,6 +45,22 @@ for /R %CORECLR_PERF% %%T in (*.%TEST_FILE_EXT%) do (
call :DOIT %%T
)
+@rem optionally upload results to benchview
+if not [%BENCHVIEW_PATH%] == [] (
+ py "%BENCHVIEW_PATH%\submission.py" measurement.json ^
+ --build ..\build.json ^
+ --machine-data ..\machinedata.json ^
+ --metadata ..\submission-metadata.json ^
+ --group "CoreCLR" ^
+ --type "%RUN_TYPE%" ^
+ --config-name "%TEST_CONFIG%" ^
+ --config Configuration "%TEST_CONFIG%" ^
+ --config OS "Windows_NT" ^
+ --arch "%TEST_ARCH%" ^
+ --machinepool "PerfSnake"
+ py "%BENCHVIEW_PATH%\upload.py" submission.json --container coreclr
+)
+
goto :EOF
:DOIT
@@ -60,28 +78,16 @@ xunit.performance.run.exe %BENCHNAME%.%TEST_FILE_EXT% -runner xunit.console.netc
xunit.performance.analysis.exe %PERFOUT%.xml -xml %XMLOUT% > %BENCHNAME%-analysis.out
-@rem optionally upload results to benchview
+@rem optionally generate results for benchview
if not [%BENCHVIEW_PATH%] == [] (
- py %BENCHVIEW_PATH%\measurement.py xunit perf-%BENCHNAME%.xml --better desc --drop-first-value
- py %BENCHVIEW_PATH%\submission.py measurement.json ^
- --build ..\build.json ^
- --machine-data ..\machinedata.json ^
- --metadata ..\submission-metadata.json ^
- --group "CoreCLR" ^
- --type "%RUN_TYPE%" ^
- --config-name "%TEST_CONFIG%" ^
- --config Configuration "%TEST_CONFIG%" ^
- --config OS "Windows_NT" ^
- --arch "%TEST_ARCH%" ^
- --machinepool "PerfSnake"
- py %BENCHVIEW_PATH%\upload.py submission.json --container coreclr
+ py "%BENCHVIEW_PATH%\measurement.py" xunit "perf-%BENCHNAME%.xml" --better desc --drop-first-value --append
REM Save off the results to the root directory for recovery later in Jenkins
xcopy perf-%BENCHNAME%*.xml %CORECLR_REPO%\
xcopy perf-%BENCHNAME%*.etl %CORECLR_REPO%\
) else (
- type %XMLOUT% | findstr "test name"
- type %XMLOUT% | findstr Duration
- type %XMLOUT% | findstr InstRetired
+ type %XMLOUT% | findstr "test name"
+ type %XMLOUT% | findstr Duration
+ type %XMLOUT% | findstr InstRetired
)
goto :EOF
@@ -146,3 +152,5 @@ echo -uploadtoBenchview is used to specify a path to the Benchview tooling and w
echo set we will upload the results of the tests to the coreclr container in benchviewupload.
echo Runtype sets the runtype that we upload to Benchview, rolling for regular runs, and private for
echo PRs.
+
+goto :EOF
diff --git a/tests/scripts/run-xunit-perf.sh b/tests/scripts/run-xunit-perf.sh
index cea29c0214..85ac43321b 100644..100755
--- a/tests/scripts/run-xunit-perf.sh
+++ b/tests/scripts/run-xunit-perf.sh
@@ -30,6 +30,11 @@ function print_usage {
echo ' (e.g. "corefx/bin/Linux.AnyCPU.Debug;corefx/bin/Unix.AnyCPU.Debug;corefx/bin/AnyOS.AnyCPU.Debug").'
echo ' If files with the same name are present in multiple directories, the first one wins.'
echo ' --coreFxNativeBinDir=<path> : Directory of the CoreFX native build (e.g. corefx/bin/Linux.x64.Debug).'
+ echo ' --uploadToBenchview : Specify this flag in order to have the results of the run uploaded to Benchview.'
+ echo ' This also requires that the os flag and runtype flag to be set. Lastly you must'
+ echo ' also have the BV_UPLOAD_SAS_TOKEN set to a SAS token for the Benchview upload container'
+ echo ' --benchViewOS=<os> : Specify the os that will be used to insert data into Benchview.'
+ echo ' --runType=<private|rolling> : Specify the runType for Benchview.'
}
# Variables for xUnit-style XML output. XML format: https://xunit.github.io/docs/format-xml-v2.html
@@ -311,6 +316,9 @@ coreClrBinDir=
mscorlibDir=
coreFxBinDir=
coreFxNativeBinDir=
+uploadToBenchview=
+benchViewOS=
+runType=
for i in "$@"
do
@@ -340,6 +348,15 @@ do
--coreFxNativeBinDir=*)
coreFxNativeBinDir=${i#*=}
;;
+ --benchViewOS=*)
+ benchViewOS=${i#*=}
+ ;;
+ --runType=*)
+ runType=${i#*=}
+ ;;
+ --uploadToBenchview)
+ uploadToBenchview=TRUE
+ ;;
*)
echo "Unknown switch: $i"
print_usage
@@ -371,11 +388,6 @@ fi
export NUGET_PACKAGES=$testNativeBinDir/../../../../packages
echo "NUGET_PACKAGES = $NUGET_PACKAGES"
-echo "dir $testNativeBinDir/../../../../Tools"
-dir $testNativeBinDir/../../../../Tools
-echo "dir $testNativeBinDir/../../../../Tools/dotnetcli"
-dir $testNativeBinDir/../../../../Tools/dotnetcli
-
pushd $testNativeBinDir/../../../../tests/scripts
$testNativeBinDir/../../../../Tools/dotnetcli/dotnet restore --fallbacksource https://dotnet.myget.org/F/dotnet-buildtools/ --fallbacksource https://dotnet.myget.org/F/dotnet-core/
popd
@@ -385,49 +397,45 @@ create_core_overlay
precompile_overlay_assemblies
copy_test_native_bin_to_test_root
-echo "find $testNativeBinDir/../../../../../../ -name 'Microsoft.DotNet.xunit.performance.runner.cli.dll'"
-find $testNativeBinDir/../../../../../../ -name 'Microsoft.DotNet.xunit.performance.runner.cli.dll'
-echo "find $testNativeBinDir/../../../../../ -name 'Microsoft.DotNet.xunit.performance.runner.cli.dll'"
-find $testNativeBinDir/../../../../../ -name 'Microsoft.DotNet.xunit.performance.runner.cli.dll'
-
# Deploy xunit performance packages
cd $CORE_ROOT
+echo "CORE_ROOT dir = $CORE_ROOT"
DO_SETUP=TRUE
if [ ${DO_SETUP} == "TRUE" ]; then
-
-echo "dir $testNativeBinDir/../../../../../"
-dir $testNativeBinDir/../../../../../
-echo "dir $testNativeBinDir/../../../../../packages"
-dir $testNativeBinDir/../../../../../packages
-echo "dir $testNativeBinDir/../../../../../packages/Microsoft.DotNet.xunit.performance.runner.cli"
-dir $testNativeBinDir/../../../../../packages/Microsoft.DotNet.xunit.performance.runner.cli
-echo "dir $testNativeBinDir/../../../../../packages/Microsoft.DotNet.xunit.performance.runner.cli/1.0.0-alpha-build0035"
-dir $testNativeBinDir/../../../../../packages/Microsoft.DotNet.xunit.performance.runner.cli/1.0.0-alpha-build0035
-echo "dir $testNativeBinDir/../../../../../packages/Microsoft.DotNet.xunit.performance.runner.cli/1.0.0-alpha-build0035/lib"
-dir $testNativeBinDir/../../../../../packages/Microsoft.DotNet.xunit.performance.runner.cli/1.0.0-alpha-build0035/lib
-echo "dir $testNativeBinDir/../../../../../packages/Microsoft.DotNet.xunit.performance.runner.cli/1.0.0-alpha-build0035/lib/netstandard1.3"
-dir $testNativeBinDir/../../../../../packages/Microsoft.DotNet.xunit.performance.runner.cli/1.0.0-alpha-build0035/lib/netstandard1.3
-
-sudo cp $testNativeBinDir/../../../../../packages/Microsoft.DotNet.xunit.performance.runner.cli/1.0.0-alpha-build0035/lib/netstandard1.3/Microsoft.DotNet.xunit.performance.runner.cli.dll .
-
-sudo cp $testNativeBinDir/../../../../../packages/Microsoft.DotNet.xunit.performance.run.core/1.0.0-alpha-build0035/lib/dotnet/*.dll .
-
+cp $testNativeBinDir/../../../../../packages/Microsoft.DotNet.xunit.performance.runner.cli/1.0.0-alpha-build0040/lib/netstandard1.3/Microsoft.DotNet.xunit.performance.runner.cli.dll .
+cp $testNativeBinDir/../../../../../packages/Microsoft.DotNet.xunit.performance.analysis.cli/1.0.0-alpha-build0040/lib/netstandard1.3/Microsoft.DotNet.xunit.performance.analysis.cli.dll .
+cp $testNativeBinDir/../../../../../packages/Microsoft.DotNet.xunit.performance.run.core/1.0.0-alpha-build0040/lib/dotnet/*.dll .
fi
# Run coreclr performance tests
echo "Test root dir is: $testRootDir"
-tests=($(find $testRootDir/JIT/Performance/CodeQuality -name '*.exe'))
+tests=($(find $testRootDir/JIT/Performance/CodeQuality -name '*.exe') $(find $testRootDir/performance/perflab/PerfLab -name '*.dll'))
+echo "current dir is $PWD"
+rm measurement.json
for testcase in ${tests[@]}; do
test=$(basename $testcase)
testname=$(basename $testcase .exe)
echo "....Running $testname"
-
cp $testcase .
+chmod u+x ./corerun
+echo "./corerun Microsoft.DotNet.xunit.performance.runner.cli.dll $test -runner xunit.console.netcore.exe -runnerhost ./corerun -verbose -runid perf-$testname"
./corerun Microsoft.DotNet.xunit.performance.runner.cli.dll $test -runner xunit.console.netcore.exe -runnerhost ./corerun -verbose -runid perf-$testname
-
+echo "./corerun Microsoft.DotNet.xunit.performance.analysis.cli.dll perf-$testname.xml -xml perf-$testname-summary.xml"
+./corerun Microsoft.DotNet.xunit.performance.analysis.cli.dll perf-$testname.xml -xml perf-$testname-summary.xml
+if [ "$uploadToBenchview" == "TRUE" ]
+ then
+ python3.5 ../../../../../tests/scripts/Microsoft.BenchView.JSONFormat/tools/measurement.py xunit perf-$testname.xml --better desc --drop-first-value --append
+fi
done
+if [ "$uploadToBenchview" == "TRUE" ]
+ then
+ python3.5 ../../../../../tests/scripts/Microsoft.BenchView.JSONFormat/tools/submission.py measurement.json --build ../../../../../build.json --machine-data ../../../../../machinedata.json --metadata ../../../../../submission-metadata.json --group "CoreCLR" --type "$runType" --config-name "Release" --config Configuration "Release" --config OS "$benchViewOS" --arch "x64" --machinepool "Perfsnake"
+ python3.5 ../../../../../tests/scripts/Microsoft.BenchView.JSONFormat/tools/upload.py submission.json --container coreclr
+fi
+mkdir ../../../../../sandbox
+cp *.xml ../../../../../sandbox
diff --git a/tests/setup-runtime-dependencies.cmd b/tests/setup-runtime-dependencies.cmd
index 6369457af8..0079d42f60 100755
--- a/tests/setup-runtime-dependencies.cmd
+++ b/tests/setup-runtime-dependencies.cmd
@@ -1,4 +1,4 @@
-@if not defined __echo @echo off
+@if not defined _echo @echo off
setlocal
set __ThisScriptShort=%0
diff --git a/tests/setup-runtime-dependencies.sh b/tests/setup-runtime-dependencies.sh
index 06586736a0..4573e084bd 100755
--- a/tests/setup-runtime-dependencies.sh
+++ b/tests/setup-runtime-dependencies.sh
@@ -87,6 +87,10 @@ fi
# This script must be located in coreclr/tests.
scriptDir=$(cd "$(dirname "$0")"; pwd -P)
+
+echo "Running init-tools.sh"
+$scriptDir/../init-tools.sh
+
dotnetToolsDir=$scriptDir/../Tools
dotnetCmd=${dotnetToolsDir}/dotnetcli/dotnet
packageDir=${scriptDir}/../packages
diff --git a/tests/src/CLRTest.Execute.Bash.targets b/tests/src/CLRTest.Execute.Bash.targets
index 367b58bc86..60270a14da 100644
--- a/tests/src/CLRTest.Execute.Bash.targets
+++ b/tests/src/CLRTest.Execute.Bash.targets
@@ -99,7 +99,7 @@ fi
<Target Name="GenerateBashExecutionScript"
Inputs="$(MSBuildProjectFullPath)"
Outputs="$(OutputPath)\$(MSBuildProjectName).sh"
- DependsOnTargets="FetchExternalPropertiesForXpalt;$(BashScriptSnippetGen);GetIlasmRoundTripBashScript">
+ DependsOnTargets="FetchExternalPropertiesForXpalt;$(BashScriptSnippetGen);GetJitDisasmBashScript;GetIlasmRoundTripBashScript">
<Message Text="Project depends on $(_CLRTestToRunFileFullPath)." Condition="'$(_CLRTestNeedsProjectToRun)' == 'True'" />
@@ -120,6 +120,14 @@ then
exit 0
fi
]]></BashCLRTestEnvironmentCompatibilityCheck>
+ <BashCLRTestEnvironmentCompatibilityCheck Condition="'$(HeapVerifyIncompatible)' == 'true'"><![CDATA[
+$(BashCLRTestEnvironmentCompatibilityCheck)
+if [ ! -z "$COMPlus_HeapVerify" ]
+then
+ echo SKIPPING EXECUTION BECAUSE COMPlus_HeapVerify IS SET
+ exit 0
+fi
+ ]]></BashCLRTestEnvironmentCompatibilityCheck>
<BashCLRTestExitCodePrep Condition="$(_CLRTestNeedsToRun)">
<![CDATA[
@@ -299,6 +307,7 @@ $(BashEnvironmentVariables)
$(BashCLRTestEnvironmentCompatibilityCheck)
$(BashCLRTestArgPrep)
$(BashCLRTestExitCodePrep)
+$(JitDisasmBashScript)
# IlasmRoundTrip Script
$(IlasmRoundTripBashScript)
# PreCommands
diff --git a/tests/src/CLRTest.Execute.Batch.targets b/tests/src/CLRTest.Execute.Batch.targets
index 8e2e5f163b..5de78b42f6 100644
--- a/tests/src/CLRTest.Execute.Batch.targets
+++ b/tests/src/CLRTest.Execute.Batch.targets
@@ -95,7 +95,7 @@ IF NOT "!ERRORLEVEL!"=="0" (
<Target Name="GenerateBatchExecutionScript"
Inputs="$(MSBuildProjectFullPath)"
Outputs="$(OutputPath)\$(MSBuildProjectName).cmd"
- DependsOnTargets="FetchExternalProperties;$(BatchScriptSnippetGen);GetIlasmRoundTripBatchScript">
+ DependsOnTargets="FetchExternalProperties;$(BatchScriptSnippetGen);GetJitDisasmBatchScript;GetIlasmRoundTripBatchScript">
<Message Text="Project depends on $(_CLRTestToRunFileFullPath)." Condition="'$(_CLRTestNeedsProjectToRun)' == 'True'" />
@@ -114,6 +114,13 @@ IF "%COMPlus_JitStress%"=="" IF "%COMPlus_JitStressRegs%"=="" IF "%COMPlus_JITMi
Exit /b 0
:Compatible1
]]></BatchCLRTestEnvironmentCompatibilityCheck>
+ <BatchCLRTestEnvironmentCompatibilityCheck Condition="'$(HeapVerifyIncompatible)' == 'true'"><![CDATA[
+$(BatchCLRTestEnvironmentCompatibilityCheck)
+IF NOT "%COMPlus_HeapVerify%"=="" (
+ ECHO SKIPPING EXECUTION BECAUSE COMPlus_HeapVerify IS SET
+ Exit /b 0
+)
+ ]]></BatchCLRTestEnvironmentCompatibilityCheck>
<BatchCLRTestExitCodePrep Condition="$(_CLRTestNeedsToRun)">
<![CDATA[
@@ -320,6 +327,8 @@ $(BatchEnvironmentVariables)
$(BatchCLRTestEnvironmentCompatibilityCheck)
+$(JitDisasmBatchScript)
+
REM IlasmRoundTrip Script
$(IlasmRoundTripBatchScript)
diff --git a/tests/src/CLRTest.Execute.targets b/tests/src/CLRTest.Execute.targets
index 17cb69f1da..b49785b9d6 100644
--- a/tests/src/CLRTest.Execute.targets
+++ b/tests/src/CLRTest.Execute.targets
@@ -105,6 +105,7 @@ This file contains the logic for providing Execution Script generation.
<BatchScriptSnippetGen></BatchScriptSnippetGen>
</PropertyGroup>
+ <Import Project="CLRTest.Jit.targets" />
<Import Project="CLRTest.CrossGen.targets" />
<Import Project="CLRTest.GC.targets" />
<Import Project="CLRTest.Execute.*.targets" />
diff --git a/tests/src/CLRTest.Jit.targets b/tests/src/CLRTest.Jit.targets
new file mode 100644
index 0000000000..4eb632722e
--- /dev/null
+++ b/tests/src/CLRTest.Jit.targets
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+***********************************************************************************************
+CLRTest.Jit.targets
+
+WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
+ created a backup copy. Incorrect changes to this file will make it
+ impossible to load or build your projects from the command-line or the IDE.
+
+This file contains the logic for generating command scripts for special GC tests.
+
+WARNING: When setting properties based on their current state (for example:
+ <Foo Condition="'$(Foo)'==''>Bar</Foo>). Be very careful. Another script generation
+ target might be trying to do the same thing. It's better to avoid this by instead setting a new property.
+
+ Additionally, be careful with itemgroups. Include will propagate outside of the target too!
+
+***********************************************************************************************
+-->
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+ <Target Name="GetJitDisasmBashScript"
+ Returns="$(JitDisasmBashScript)">
+ <PropertyGroup>
+ <InputAssemblyName Condition="'$(CLRTestKind)' == 'RunOnly'">$([MSBuild]::MakeRelative($(OutputPath), $(_CLRTestToRunFileFullPath)).Replace("\","/"))</InputAssemblyName>
+ <InputAssemblyName Condition="'$(CLRTestKind)' == 'BuildAndRun'">$(MSBuildProjectName).exe</InputAssemblyName>
+ <JitDisasmOut>$(BaseOutputPathWithConfig.Replace("\","/"))dasm/$(BuildProjectRelativeDir.Replace("\","/"))</JitDisasmOut>
+ <JitDisasmBashScript>
+<![CDATA[
+# JitDisasm Script
+if [ ! -z $RunningJitDisasm ]
+then
+ echo $CORE_ROOT/corerun "$CORE_ROOT/jit-dasm.dll" --crossgen $CORE_ROOT/crossgen.exe --platform $CORE_ROOT --output $(JitDisasmOut) $(InputAssemblyName)
+ "$CORE_ROOT/corerun" "$CORE_ROOT/jit-dasm" --crossgen $CORE_ROOT/crossgen.exe --platform $CORE_ROOT --output $(JitDisasmOut) $(InputAssemblyName)
+ if [ $ERRORLEVEL -ne 0 ]
+ then
+ echo EXECUTION OF JIT-DASM - FAILED $ERRORLEVEL
+ exit 1
+ fi
+fi
+]]>
+ </JitDisasmBashScript>
+ </PropertyGroup>
+ </Target>
+
+ <Target Name="GetJitDisasmBatchScript"
+ Returns="$(JitDisasmBatchScript)">
+ <PropertyGroup>
+ <InputAssemblyName Condition="'$(CLRTestKind)' == 'RunOnly'">$([MSBuild]::MakeRelative($(OutputPath), $(_CLRTestToRunFileFullPath)))</InputAssemblyName>
+ <InputAssemblyName Condition="'$(CLRTestKind)' == 'BuildAndRun'">$(MSBuildProjectName).exe</InputAssemblyName>
+ <JitDisasmOut>$(BaseOutputPathWithConfig)dasm\$(BuildProjectRelativeDir)</JitDisasmOut>
+ <JitDisasmBatchScript>
+<![CDATA[
+REM JitDisasm Script
+if defined RunningJitDisasm (
+ echo %CORE_ROOT%\corerun %CORE_ROOT%\jit-dasm.dll --crossgen %CORE_ROOT%/crossgen.exe --platform %CORE_ROOT%%3B%25cd%25 --output $(JitDisasmOut) $(InputAssemblyName)
+ %CORE_ROOT%\corerun %CORE_ROOT%\jit-dasm.dll --crossgen %CORE_ROOT%/crossgen.exe --platform %CORE_ROOT%%3B%25cd%25 --output $(JitDisasmOut) $(InputAssemblyName)
+ IF NOT "!ERRORLEVEL!"=="0" (
+ ECHO EXECUTION OF JIT-DASM - FAILED !ERRORLEVEL!
+ Exit /b 1
+ )
+ Exit /b 0
+)
+ ]]>
+ </JitDisasmBatchScript>
+ </PropertyGroup>
+ </Target>
+
+ <PropertyGroup Condition="$(RunWithGcStress) != ''" >
+ <CLRTestBatchPreCommands>
+<![CDATA[
+ $(CLRTestBatchPreCommands)
+set COMPlus_GCStress=$(RunWithGcStress)
+ ]]>
+ </CLRTestBatchPreCommands>
+ <BashCLRTestPreCommands>
+<![CDATA[
+ $(BashCLRTestPreCommands)
+export COMPlus_GCStress=$(RunWithGcStress)
+ ]]>
+ </BashCLRTestPreCommands>
+ </PropertyGroup>
+
+
+</Project>
diff --git a/tests/src/Common/Platform/platformdefines.cpp b/tests/src/Common/Platform/platformdefines.cpp
index 4caead59ea..82061ac90d 100644
--- a/tests/src/Common/Platform/platformdefines.cpp
+++ b/tests/src/Common/Platform/platformdefines.cpp
@@ -89,7 +89,7 @@ int TP_slen(LPWSTR str)
return len;
}
-int TP_scmp_s(LPSTR str1, LPSTR str2)
+int TP_scmp_s(LPCSTR str1, LPCSTR str2)
{
// < 0 str1 less than str2
// 0 str1 identical to str2
@@ -277,7 +277,7 @@ DWORD TP_GetFullPathName(LPWSTR fileName, DWORD nBufferLength, LPWSTR lpBuffer)
return GetFullPathNameW(fileName, nBufferLength, lpBuffer, NULL);
#else
char nativeFullPath[MAX_PATH];
- realpath(HackyConvertToSTR(fileName), nativeFullPath);
+ (void)realpath(HackyConvertToSTR(fileName), nativeFullPath);
LPWSTR fullPathForCLR = HackyConvertToWSTR(nativeFullPath);
wcscpy_s(lpBuffer, MAX_PATH, fullPathForCLR);
return wcslen(lpBuffer);
diff --git a/tests/src/Common/Platform/platformdefines.h b/tests/src/Common/Platform/platformdefines.h
index d0760fd6ae..0961e86b2d 100644
--- a/tests/src/Common/Platform/platformdefines.h
+++ b/tests/src/Common/Platform/platformdefines.h
@@ -72,7 +72,7 @@ LPWSTR HackyConvertToWSTR(char* pszInput);
typedef pthread_t THREAD_ID;
typedef void* (*MacWorker)(void*);
-typedef DWORD (*LPTHREAD_START_ROUTINE)(void*);
+typedef DWORD __stdcall (*LPTHREAD_START_ROUTINE)(void*);
#ifdef UNICODE
typedef WCHAR TCHAR;
#else // ANSI
@@ -87,7 +87,7 @@ typedef void* HMODULE;
typedef void* ULONG_PTR;
typedef unsigned error_t;
typedef void* LPVOID;
-typedef char BYTE;
+typedef unsigned char BYTE;
typedef WCHAR OLECHAR;
#endif
@@ -97,7 +97,7 @@ typedef WCHAR OLECHAR;
error_t TP_scpy_s(LPWSTR strDestination, size_t sizeInWords, LPCWSTR strSource);
error_t TP_scat_s(LPWSTR strDestination, size_t sizeInWords, LPCWSTR strSource);
int TP_slen(LPWSTR str);
-int TP_scmp_s(LPSTR str1, LPSTR str2);
+int TP_scmp_s(LPCSTR str1, LPCSTR str2);
int TP_wcmp_s(LPWSTR str1, LPWSTR str2);
error_t TP_getenv_s(size_t* pReturnValue, LPWSTR buffer, size_t sizeInWords, LPCWSTR varname);
error_t TP_putenv_s(LPTSTR name, LPTSTR value);
diff --git a/tests/src/Common/build_against_pkg_dependencies/build_against_pkg_dependencies.csproj b/tests/src/Common/build_against_pkg_dependencies/build_against_pkg_dependencies.csproj
new file mode 100644
index 0000000000..63c54488f2
--- /dev/null
+++ b/tests/src/Common/build_against_pkg_dependencies/build_against_pkg_dependencies.csproj
@@ -0,0 +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="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <CLRTestKind>BuildOnly</CLRTestKind>
+ </PropertyGroup>
+ <ItemGroup>
+ <DnuSourceList Include="$(CORE_ROOT)\.nuget\pkg" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <Target Name="Build"
+ DependsOnTargets="ResolveReferences" />
+</Project>
diff --git a/tests/src/Common/build_against_pkg_dependencies/project.json b/tests/src/Common/build_against_pkg_dependencies/project.json
new file mode 100644
index 0000000000..562485594f
--- /dev/null
+++ b/tests/src/Common/build_against_pkg_dependencies/project.json
@@ -0,0 +1,32 @@
+{
+ "dependencies": {
+ "Microsoft.NETCore.ILAsm": "1.2.0-beta-24820-02",
+ "Microsoft.NETCore.ILDAsm": "1.2.0-beta-24820-02",
+ "Microsoft.NETCore.Jit": "1.2.0-beta-24820-02",
+ "Microsoft.NETCore.Runtime.CoreCLR": "1.2.0-beta-24820-02",
+ "Microsoft.NETCore.TestHost": "1.2.0-beta-24820-02"
+ },
+ "frameworks": {
+ "netcoreapp1.1": {
+ "imports": [
+ "dnxcore50",
+ "portable-net45+win8"
+ ]
+ }
+ },
+ "runtimes": {
+ "win7-x86": {},
+ "win7-x64": {},
+ "win10-arm64": {},
+ "ubuntu.14.04-x64": {},
+ "ubuntu.16.04-x64": {},
+ "ubuntu.16.10-x64": {},
+ "osx.10.10-x64": {},
+ "centos.7-x64": {},
+ "rhel.7-x64": {},
+ "debian.8-x64": {},
+ "fedora.23-x64": {},
+ "opensuse.13.2-x64": {},
+ "opensuse.42.1-x64": {}
+ }
+}
diff --git a/tests/src/Common/empty/project.json b/tests/src/Common/empty/project.json
index c6d5104033..1954111901 100644
--- a/tests/src/Common/empty/project.json
+++ b/tests/src/Common/empty/project.json
@@ -2,7 +2,7 @@
"dependencies": {
},
"frameworks": {
- "netcoreapp1.0": {}
+ "netcoreapp1.1": {}
},
"runtimes": {
"win7-x86": {},
diff --git a/tests/src/Common/netcoreapp/project.json b/tests/src/Common/netcoreapp/project.json
new file mode 100644
index 0000000000..51193fc015
--- /dev/null
+++ b/tests/src/Common/netcoreapp/project.json
@@ -0,0 +1,74 @@
+{
+ "version": "1.0.0-*",
+ "buildOptions": {
+ "debugType": "portable",
+ "emitEntryPoint": true
+ },
+ "dependencies": {
+ "Microsoft.NETCore.Platforms": "1.2.0-beta-24820-02",
+ "Microsoft.NETCore.Targets": "1.2.0-beta-24820-02",
+ "System.Threading.Thread": "4.4.0-beta-24820-02",
+ "System.Collections": "4.4.0-beta-24820-02",
+ "System.Xml.XmlSerializer": "4.4.0-beta-24820-02",
+ "System.Collections.Concurrent": "4.4.0-beta-24820-02",
+ "System.ObjectModel": "4.4.0-beta-24820-02",
+ "System.Runtime.Numerics": "4.4.0-beta-24820-02",
+ "System.Collections.NonGeneric": "4.4.0-beta-24820-02",
+ "System.Collections.Specialized": "4.4.0-beta-24820-02",
+ "System.ComponentModel": "4.4.0-beta-24820-02",
+ "System.Reflection.Emit.Lightweight": "4.4.0-beta-24820-02",
+ "System.Reflection.TypeExtensions": "4.4.0-beta-24820-02",
+ "System.Console": "4.4.0-beta-24820-02",
+ "System.Diagnostics.Contracts": "4.4.0-beta-24820-02",
+ "System.Diagnostics.Debug": "4.4.0-beta-24820-02",
+ "System.Diagnostics.Process": "4.4.0-beta-24820-02",
+ "System.Diagnostics.Tools": "4.4.0-beta-24820-02",
+ "System.Diagnostics.Tracing": "4.4.0-beta-24820-02",
+ "System.Dynamic.Runtime": "4.4.0-beta-24820-02",
+ "System.Globalization": "4.4.0-beta-24820-02",
+ "System.Globalization.Calendars": "4.4.0-beta-24820-02",
+ "System.IO": "4.4.0-beta-24820-02",
+ "System.IO.FileSystem": "4.4.0-beta-24820-02",
+ "System.IO.FileSystem.Primitives": "4.4.0-beta-24820-02",
+ "System.Linq": "4.4.0-beta-24820-02",
+ "System.Linq.Queryable": "4.4.0-beta-24820-02",
+ "System.Linq.Expressions": "4.4.0-beta-24820-02",
+ "System.Reflection": "4.4.0-beta-24820-02",
+ "System.Reflection.Extensions": "4.4.0-beta-24820-02",
+ "System.Resources.ResourceManager": "4.4.0-beta-24820-02",
+ "System.Runtime": "4.4.0-beta-24820-02",
+ "System.Runtime.CompilerServices.Unsafe": "4.4.0-beta-24820-02",
+ "System.Runtime.Extensions": "4.4.0-beta-24820-02",
+ "System.Runtime.Handles": "4.4.0-beta-24820-02",
+ "System.Runtime.InteropServices": "4.4.0-beta-24820-02",
+ "System.Runtime.InteropServices.RuntimeInformation": "4.4.0-beta-24820-02",
+ "System.Runtime.Loader": "4.4.0-beta-24820-02",
+ "System.Security.Cryptography.Algorithms": "4.4.0-beta-24820-02",
+ "System.Text.Encoding": "4.4.0-beta-24820-02",
+ "System.Text.Encoding.Extensions": "4.4.0-beta-24820-02",
+ "System.Text.RegularExpressions": "4.4.0-beta-24820-02",
+ "System.Threading": "4.4.0-beta-24820-02",
+ "System.Threading.AccessControl": "4.4.0-beta-24820-02",
+ "System.Threading.Overlapped": "4.4.0-beta-24820-02",
+ "System.Threading.Tasks": "4.4.0-beta-24820-02",
+ "System.Threading.Tasks.Parallel": "4.4.0-beta-24820-02",
+ "System.Threading.ThreadPool": "4.4.0-beta-24820-02",
+ "System.Threading.Timer": "4.4.0-beta-24820-02",
+ "System.Xml.ReaderWriter": "4.4.0-beta-24820-02",
+ "System.Xml.XDocument": "4.4.0-beta-24820-02",
+ "System.Xml.XmlDocument": "4.4.0-beta-24820-02",
+ "System.Xml.XPath": "4.4.0-beta-24820-02",
+ "System.Xml.XPath.XmlDocument": "4.4.0-beta-24820-02",
+ "System.Numerics.Vectors": "4.4.0-beta-24820-02"
+ },
+ "frameworks": {
+ "netcoreapp1.1": {
+ "dependencies": {
+ "Microsoft.NETCore.Runtime.CoreCLR": "1.2.0-beta-24820-02"
+ }
+ }
+ },
+ "runtimes": {
+ "win7-x64": {}
+ }
+}
diff --git a/tests/src/Common/targeting_pack_ref/project.json b/tests/src/Common/targeting_pack_ref/project.json
new file mode 100644
index 0000000000..c1f033b946
--- /dev/null
+++ b/tests/src/Common/targeting_pack_ref/project.json
@@ -0,0 +1,22 @@
+{
+ "dependencies": {
+ "Microsoft.TargetingPack.Private.CoreCLR": "1.2.0-beta-24820-02"
+ },
+ "frameworks": {
+ "netcoreapp1.1": {
+ "imports": [
+ "dnxcore50",
+ "portable-net45+win8"
+ ]
+ }
+ },
+ "runtimes": {
+ "win7-x86": {},
+ "win7-x64": {},
+ "ubuntu.14.04-x64": {},
+ "osx.10.10-x64": {},
+ "centos.7-x64": {},
+ "rhel.7-x64": {},
+ "debian.8-x64": {}
+ }
+}
diff --git a/tests/src/Common/targeting_pack_ref/targeting_pack_ref.csproj b/tests/src/Common/targeting_pack_ref/targeting_pack_ref.csproj
new file mode 100644
index 0000000000..65e37c03c3
--- /dev/null
+++ b/tests/src/Common/targeting_pack_ref/targeting_pack_ref.csproj
@@ -0,0 +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>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <CLRTestKind>BuildOnly</CLRTestKind>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <Target Name="Build"
+ DependsOnTargets="ResolveReferences" />
+</Project>
diff --git a/tests/src/Common/test_dependencies/project.json b/tests/src/Common/test_dependencies/project.json
index 46e2601eeb..5f059148b8 100644
--- a/tests/src/Common/test_dependencies/project.json
+++ b/tests/src/Common/test_dependencies/project.json
@@ -1,76 +1,76 @@
{
"dependencies": {
- "xunit": "2.1.0",
- "xunit.console.netcore": "1.0.2-prerelease-00101",
- "xunit.runner.utility": "2.1.0",
+ "xunit": "2.2.0-beta2-build3300",
+ "xunit.console.netcore": "1.0.2-prerelease-00177",
+ "xunit.runner.utility": "2.2.0-beta2-build3300",
"Microsoft.CodeAnalysis.Compilers": "1.1.1",
- "Microsoft.DotNet.xunit.performance": "1.0.0-alpha-build0035",
- "Microsoft.DotNet.xunit.performance.analysis": "1.0.0-alpha-build0035",
- "Microsoft.DotNet.xunit.performance.runner.Windows": "1.0.0-alpha-build0035",
- "Microsoft.Win32.Primitives": "4.3.0",
- "Newtonsoft.Json": "7.0.1",
- "Microsoft.NETCore.Platforms": "1.1.0",
- "Microsoft.NETCore.Targets": "1.1.0",
- "System.Collections.Immutable": "1.3.0",
- "System.Threading.Thread": "4.3.0",
- "System.Collections": "4.3.0",
- "System.Xml.XmlSerializer": "4.3.0",
- "System.Collections.Concurrent": "4.3.0",
- "System.ObjectModel": "4.3.0",
- "System.Runtime.Numerics": "4.3.0",
- "System.Collections.NonGeneric": "4.3.0",
- "System.Collections.Specialized": "4.3.0",
- "System.ComponentModel": "4.3.0",
- "System.Reflection.Emit.Lightweight": "4.3.0",
- "System.Reflection.TypeExtensions": "4.3.0",
- "System.Console": "4.3.0",
- "System.Diagnostics.Contracts": "4.3.0",
- "System.Diagnostics.Debug": "4.3.0",
- "System.Diagnostics.Process": "4.3.0",
- "System.Diagnostics.Tools": "4.3.0",
- "System.Diagnostics.Tracing": "4.3.0",
- "System.Dynamic.Runtime": "4.3.0",
- "System.Globalization": "4.3.0",
- "System.Globalization.Calendars": "4.3.0",
- "System.IO": "4.3.0",
- "System.IO.FileSystem": "4.3.0",
- "System.IO.FileSystem.Primitives": "4.3.0",
- "System.Linq": "4.3.0",
- "System.Linq.Queryable": "4.3.0",
- "System.Linq.Expressions": "4.3.0",
- "System.Reflection": "4.3.0",
- "System.Reflection.Extensions": "4.3.0",
- "System.Resources.ResourceManager": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.CompilerServices.Unsafe": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Runtime.Handles": "4.3.0",
- "System.Runtime.InteropServices": "4.3.0",
- "System.Runtime.InteropServices.RuntimeInformation": "4.3.0",
- "System.Runtime.Loader": "4.3.0",
- "System.Runtime.Serialization.Json": "4.3.0",
- "System.Runtime.Serialization.Primitives": "4.1.1",
- "System.Runtime.Serialization.Xml": "4.3.0",
- "System.Security.Cryptography.Algorithms": "4.3.0",
- "System.Text.Encoding": "4.3.0",
- "System.Text.Encoding.Extensions": "4.3.0",
- "System.Text.RegularExpressions": "4.3.0",
- "System.Threading": "4.3.0",
- "System.Threading.AccessControl": "4.3.0",
- "System.Threading.Overlapped": "4.3.0",
- "System.Threading.Tasks": "4.3.0",
- "System.Threading.Tasks.Parallel": "4.3.0",
- "System.Threading.ThreadPool": "4.3.0",
- "System.Threading.Timer": "4.3.0",
- "System.Xml.ReaderWriter": "4.3.0",
- "System.Xml.XDocument": "4.3.0",
- "System.Xml.XmlDocument": "4.3.0",
- "System.Xml.XPath": "4.3.0",
- "System.Xml.XPath.XmlDocument": "4.3.0",
- "System.Numerics.Vectors": "4.3.0"
+ "Microsoft.DotNet.xunit.performance": "1.0.0-alpha-build0040",
+ "Microsoft.DotNet.xunit.performance.analysis": "1.0.0-alpha-build0040",
+ "Microsoft.DotNet.xunit.performance.runner.Windows": "1.0.0-alpha-build0040",
+ "Microsoft.Win32.Primitives": "4.4.0-beta-24820-02",
+ "Newtonsoft.Json": "8.0.3",
+ "Microsoft.NETCore.Platforms": "1.2.0-beta-24820-02",
+ "Microsoft.NETCore.Targets": "1.2.0-beta-24820-02",
+ "System.Collections.Immutable": "1.4.0-beta-24820-02",
+ "System.Threading.Thread": "4.4.0-beta-24820-02",
+ "System.Collections": "4.4.0-beta-24820-02",
+ "System.Xml.XmlSerializer": "4.4.0-beta-24820-02",
+ "System.Collections.Concurrent": "4.4.0-beta-24820-02",
+ "System.ObjectModel": "4.4.0-beta-24820-02",
+ "System.Runtime.Numerics": "4.4.0-beta-24820-02",
+ "System.Collections.NonGeneric": "4.4.0-beta-24820-02",
+ "System.Collections.Specialized": "4.4.0-beta-24820-02",
+ "System.ComponentModel": "4.4.0-beta-24820-02",
+ "System.Reflection.Emit.Lightweight": "4.4.0-beta-24820-02",
+ "System.Reflection.TypeExtensions": "4.4.0-beta-24820-02",
+ "System.Console": "4.4.0-beta-24820-02",
+ "System.Diagnostics.Contracts": "4.4.0-beta-24820-02",
+ "System.Diagnostics.Debug": "4.4.0-beta-24820-02",
+ "System.Diagnostics.Process": "4.4.0-beta-24820-02",
+ "System.Diagnostics.Tools": "4.4.0-beta-24820-02",
+ "System.Diagnostics.Tracing": "4.4.0-beta-24820-02",
+ "System.Dynamic.Runtime": "4.4.0-beta-24820-02",
+ "System.Globalization": "4.4.0-beta-24820-02",
+ "System.Globalization.Calendars": "4.4.0-beta-24820-02",
+ "System.IO": "4.4.0-beta-24820-02",
+ "System.IO.FileSystem": "4.4.0-beta-24820-02",
+ "System.IO.FileSystem.Primitives": "4.4.0-beta-24820-02",
+ "System.Linq": "4.4.0-beta-24820-02",
+ "System.Linq.Queryable": "4.4.0-beta-24820-02",
+ "System.Linq.Expressions": "4.4.0-beta-24820-02",
+ "System.Reflection": "4.4.0-beta-24820-02",
+ "System.Reflection.Extensions": "4.4.0-beta-24820-02",
+ "System.Resources.ResourceManager": "4.4.0-beta-24820-02",
+ "System.Runtime": "4.4.0-beta-24820-02",
+ "System.Runtime.CompilerServices.Unsafe": "4.4.0-beta-24820-02",
+ "System.Runtime.Extensions": "4.4.0-beta-24820-02",
+ "System.Runtime.Handles": "4.4.0-beta-24820-02",
+ "System.Runtime.InteropServices": "4.4.0-beta-24820-02",
+ "System.Runtime.InteropServices.RuntimeInformation": "4.4.0-beta-24820-02",
+ "System.Runtime.Loader": "4.4.0-beta-24820-02",
+ "System.Runtime.Serialization.Json": "4.4.0-beta-24820-02",
+ "System.Runtime.Serialization.Primitives": "4.4.0-beta-24820-02",
+ "System.Runtime.Serialization.Xml": "4.4.0-beta-24820-02",
+ "System.Security.Cryptography.Algorithms": "4.4.0-beta-24820-02",
+ "System.Text.Encoding": "4.4.0-beta-24820-02",
+ "System.Text.Encoding.Extensions": "4.4.0-beta-24820-02",
+ "System.Text.RegularExpressions": "4.4.0-beta-24820-02",
+ "System.Threading": "4.4.0-beta-24820-02",
+ "System.Threading.AccessControl": "4.4.0-beta-24820-02",
+ "System.Threading.Overlapped": "4.4.0-beta-24820-02",
+ "System.Threading.Tasks": "4.4.0-beta-24820-02",
+ "System.Threading.Tasks.Parallel": "4.4.0-beta-24820-02",
+ "System.Threading.ThreadPool": "4.4.0-beta-24820-02",
+ "System.Threading.Timer": "4.4.0-beta-24820-02",
+ "System.Xml.ReaderWriter": "4.4.0-beta-24820-02",
+ "System.Xml.XDocument": "4.4.0-beta-24820-02",
+ "System.Xml.XmlDocument": "4.4.0-beta-24820-02",
+ "System.Xml.XPath": "4.4.0-beta-24820-02",
+ "System.Xml.XPath.XmlDocument": "4.4.0-beta-24820-02",
+ "System.Numerics.Vectors": "4.4.0-beta-24820-02"
},
"frameworks": {
- "netcoreapp1.0": {
+ "netcoreapp1.1": {
"imports": [
"dnxcore50",
"portable-net45+win8"
diff --git a/tests/src/Common/test_dependencies/test_dependencies.csproj b/tests/src/Common/test_dependencies/test_dependencies.csproj
index f4757725c6..0649d2b1e7 100644
--- a/tests/src/Common/test_dependencies/test_dependencies.csproj
+++ b/tests/src/Common/test_dependencies/test_dependencies.csproj
@@ -5,10 +5,10 @@
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<CLRTestKind>BuildOnly</CLRTestKind>
- <CoreRootPackagesDir>$(CORE_ROOT)\.nuget\pkg</CoreRootPackagesDir>
+ <NugetTargetMoniker>.NETCoreApp,Version=v1.1</NugetTargetMoniker>
</PropertyGroup>
<ItemGroup>
- <DnuSourceList Include="$(CoreRootPackagesDir)" Condition="Exists('$(CoreRootPackagesDir)')" />
+ <DnuSourceList Include="$(CORE_ROOT)\.nuget\pkg" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<Target Name="Build"
diff --git a/tests/src/Common/test_runtime/project.json b/tests/src/Common/test_runtime/project.json
index 9c6fdf1633..2c7c15f414 100644
--- a/tests/src/Common/test_runtime/project.json
+++ b/tests/src/Common/test_runtime/project.json
@@ -1,9 +1,12 @@
{
"dependencies": {
"Microsoft.DotNet.CoreCLR.TestDependencies": "1.0.0-prerelease",
+ "jit-dasm": "0.0.1.1",
+ "cijobs": "0.0.1.2",
+ "jit-analyze": "0.0.1.0"
},
"frameworks": {
- "netcoreapp1.0": {
+ "netcoreapp1.1": {
"imports": [
"dnxcore50",
"portable-net45+win8"
diff --git a/tests/src/Common/test_runtime/test_runtime.csproj b/tests/src/Common/test_runtime/test_runtime.csproj
index 009655dd6d..ad0093adfc 100644
--- a/tests/src/Common/test_runtime/test_runtime.csproj
+++ b/tests/src/Common/test_runtime/test_runtime.csproj
@@ -8,10 +8,10 @@
<!-- Reset the Default project.json-->
<ProjectJson></ProjectJson>
<ProjectLockJson></ProjectLockJson>
- <CoreRootPackagesDir>$(CORE_ROOT)\.nuget\pkg</CoreRootPackagesDir>
+ <NugetTargetMoniker>.NETCoreApp,Version=v1.1</NugetTargetMoniker>
</PropertyGroup>
<ItemGroup>
- <DnuSourceList Include="$(CoreRootPackagesDir)" Condition="Exists('$(CoreRootPackagesDir)')" />
+ <DnuSourceList Include="$(CORE_ROOT)\.nuget\pkg" />
</ItemGroup>
<ItemGroup>
<None Include="project.json" />
diff --git a/tests/src/CoreMangLib/cti/system/datetime/datetimeparse1.cs b/tests/src/CoreMangLib/cti/system/datetime/datetimeparse1.cs
index ee92958220..d759d4fa3e 100644
--- a/tests/src/CoreMangLib/cti/system/datetime/datetimeparse1.cs
+++ b/tests/src/CoreMangLib/cti/system/datetime/datetimeparse1.cs
@@ -472,7 +472,7 @@ public class DateTimeParse1
day = (TestLibrary.Generator.GetInt32(-55) % 27) + 1;
year = (TestLibrary.Generator.GetInt32(-55) % 100) + 1900;
month = (TestLibrary.Generator.GetInt32(-55) % 12);
- hour = (TestLibrary.Generator.GetInt32(-55) % 12) + hourshift; // Parse will convert perform GMT -> PST conversion
+ hour = (TestLibrary.Generator.GetInt32(-55) % 12) + hourshift; // Parse will convert perform GMT -> Local conversion
minute = (TestLibrary.Generator.GetInt32(-55) % 60);
second = (TestLibrary.Generator.GetInt32(-55) % 60);
dayOfWeek = (TestLibrary.Generator.GetInt32(-55) % 7);
@@ -489,10 +489,9 @@ public class DateTimeParse1
|| day != dateAfter.Day
|| year != dateAfter.Year
|| (DayOfWeek)dayOfWeek != dateAfter.DayOfWeek
- || minute != dateAfter.Minute
|| second != dateAfter.Second)
{
- TestLibrary.TestFramework.LogError("017", "DateTime.Parse(" + dateBefore + ") did not equal (" + c_DAYS_SH[(int)dateAfter.DayOfWeek] + ", " + dateAfter.Day + " " + c_MONTHS_SH[dateAfter.Month-1] + " " + dateAfter.Year + " " + dateAfter.Hour + ":" + dateAfter.Minute + ":" + dateAfter.Second + " GMT)");
+ TestLibrary.TestFramework.LogError("017", "DateTime.Parse(" + dateBefore + ") did not equal (" + c_DAYS_SH[(int)dateAfter.DayOfWeek] + ", " + dateAfter.Day + " " + c_MONTHS_SH[dateAfter.Month-1] + " " + dateAfter.Year + " " + dateAfter.Hour + ":" + dateAfter.Minute + ":" + dateAfter.Second + " " + dateAfter.Kind + ")");
retVal = false;
}
}
@@ -683,10 +682,9 @@ public class DateTimeParse1
if (month != dateAfter.Month
|| day != dateAfter.Day
|| year != dateAfter.Year
- || minute != dateAfter.Minute
|| second != dateAfter.Second)
{
- TestLibrary.TestFramework.LogError("025", "DateTime.Parse(" + dateBefore + ") did not equal (" + dateAfter.Year + "-" + dateAfter.Month + "-" + dateAfter.Day + " " + dateAfter.Hour + ":" + dateAfter.Minute + ":" + dateAfter.Second + "Z)");
+ TestLibrary.TestFramework.LogError("025", "DateTime.Parse(" + dateBefore + ") did not equal (" + dateAfter.Year + "-" + dateAfter.Month + "-" + dateAfter.Day + " " + dateAfter.Hour + ":" + dateAfter.Minute + ":" + dateAfter.Second + " " + dateAfter.Kind + ")");
retVal = false;
}
}
diff --git a/tests/src/CoreMangLib/system/span/BasicSpanTest.cs b/tests/src/CoreMangLib/system/span/BasicSpanTest.cs
new file mode 100644
index 0000000000..18ec6f8474
--- /dev/null
+++ b/tests/src/CoreMangLib/system/span/BasicSpanTest.cs
@@ -0,0 +1,804 @@
+using System;
+using System.Collections.Generic;
+
+class ReferenceType
+{
+ internal byte Value;
+ public ReferenceType(byte value) { Value = value; }
+}
+
+struct ValueTypeWithoutPointers
+{
+ internal byte Value;
+ public ValueTypeWithoutPointers(byte value) { Value = value; }
+}
+
+struct ValueTypeWithPointers
+{
+ internal object Reference;
+ public ValueTypeWithPointers(object reference) { Reference = reference; }
+}
+
+struct SevenBytesStruct
+{
+#pragma warning disable 0169
+ byte b1, b2, b3, b4, b5, b6, b7;
+#pragma warning restore 0169
+}
+
+class My
+{
+ static int Sum(Span<int> span)
+ {
+ int sum = 0;
+ for (int i = 0; i < span.Length; i++)
+ sum += span[i];
+ return sum;
+ }
+
+ static void Main()
+ {
+ int failedTestsCount = 0;
+
+ Test(CanAccessItemsViaIndexer, "CanAccessItemsViaIndexer", ref failedTestsCount);
+ Test(CanAccessItemsViaIndexerStartCtor, "CanAccessItemsViaIndexerStartCtor", ref failedTestsCount);
+ Test(CanAccessItemsViaIndexerStartLengthCtor, "CanAccessItemsViaIndexerStartLengthCtor", ref failedTestsCount);
+
+ Test(TestBoundaryEmptySpanStartCtor, "TestBoundaryEmptySpanStartCtor", ref failedTestsCount);
+ Test(TestBoundaryEmptySpanStartLengthCtor, "TestBoundaryEmptySpanStartLengthCtor", ref failedTestsCount);
+
+ Test(ReferenceTypesAreSupported, "ReferenceTypesAreSupported", ref failedTestsCount);
+
+ Test(CanUpdateUnderlyingArray, "CanUpdateUnderlyingArray", ref failedTestsCount);
+
+ Test(MustNotMoveGcTypesToUnmanagedMemory, "MustNotMoveGcTypesToUnmanagedMemory", ref failedTestsCount);
+
+ Test(TestArrayCoVariance, "TestArrayCoVariance", ref failedTestsCount);
+ Test(TestArrayCoVarianceStartCtor, "TestArrayCoVarianceStartCtor", ref failedTestsCount);
+ Test(TestArrayCoVarianceStartLengthCtor, "TestArrayCoVarianceStartLengthCtor", ref failedTestsCount);
+
+ Test(TestArrayCoVarianceReadOnly, "TestArrayCoVarianceReadOnly", ref failedTestsCount);
+
+ Test(CanCopyValueTypesWithoutPointersToSlice, "CanCopyValueTypesWithoutPointersToSlice", ref failedTestsCount);
+ Test(CanCopyValueTypesWithoutPointersToArray, "CanCopyValueTypesWithoutPointersToArray", ref failedTestsCount);
+
+ Test(CanCopyReferenceTypesToSlice, "CanCopyReferenceTypesToSlice", ref failedTestsCount);
+ Test(CanCopyReferenceTypesToArray, "CanCopyReferenceTypesToArray", ref failedTestsCount);
+
+ Test(CanCopyValueTypesWithPointersToSlice, "CanCopyValueTypesWithPointersToSlice", ref failedTestsCount);
+ Test(CanCopyValueTypesWithPointersToArray, "CanCopyValueTypesWithPointersToArray", ref failedTestsCount);
+
+ Test(CanCopyValueTypesWithoutPointersToUnmanagedMemory, "CanCopyValueTypesWithoutPointersToUnmanagedMemory", ref failedTestsCount);
+
+ Test(CanCopyOverlappingSlicesOfValueTypeWithoutPointers, "CanCopyOverlappingSlicesOfValueTypeWithoutPointers", ref failedTestsCount);
+ Test(CanCopyOverlappingSlicesOfValueTypeWithPointers, "CanCopyOverlappingSlicesOfValueTypeWithPointers", ref failedTestsCount);
+ Test(CanCopyOverlappingSlicesOfReferenceTypes, "CanCopyOverlappingSlicesOfReferenceTypes", ref failedTestsCount);
+
+ Test(MustNotCastSpanOfValueTypesWithPointers, "MustNotCastSpanOfValueTypesWithPointers", ref failedTestsCount);
+ Test(IntArraySpanCastedToByteArraySpanHasSameBytesAsOriginalArray, "IntArraySpanCastedToByteArraySpanHasSameBytesAsOriginalArray", ref failedTestsCount);
+ Test(ByteArraySpanCastedToIntArraySpanHasSameBytesAsOriginalArray, "ByteArraySpanCastedToIntArraySpanHasSameBytesAsOriginalArray", ref failedTestsCount);
+ Test(SourceTypeLargerThanTargetOneCorrectlyCalcsTargetsLength, "SourceTypeLargerThanTargetOneCorrectlyCalcsTargetsLength", ref failedTestsCount);
+ Test(WhenSourceDoesntFitIntoTargetLengthIsZero, "WhenSourceDoesntFitIntoTargetLengthIsZero", ref failedTestsCount);
+ Test(WhenSourceFitsIntoTargetOnceLengthIsOne, "WhenSourceFitsIntoTargetOnceLengthIsOne", ref failedTestsCount);
+ Test(WhenSourceTypeLargerThanTargetAndOverflowsInt32ThrowsException, "WhenSourceTypeLargerThanTargetAndOverflowsInt32ThrowsException", ref failedTestsCount);
+ Test(CanCreateSpanFromString, "CanCreateSpanFromString", ref failedTestsCount);
+
+ Test(WhenStartLargerThanLengthThrowsExceptionStartCtor, "WhenStartLargerThanLengthThrowsExceptionStartCtor", ref failedTestsCount);
+ Test(WhenStartLargerThanLengthThrowsExceptionStartLengthCtor, "WhenStartLargerThanLengthThrowsExceptionStartLengthCtor", ref failedTestsCount);
+ Test(WhenStartAndLengthLargerThanLengthThrowsExceptionStartLengthCtor, "WhenStartAndLengthLargerThanLengthThrowsExceptionStartLengthCtor", ref failedTestsCount);
+
+ Console.WriteLine(string.Format("{0} tests has failed", failedTestsCount));
+ Environment.Exit(failedTestsCount);
+ }
+
+ static void CanAccessItemsViaIndexer()
+ {
+ int[] a = new int[] { 1, 2, 3 };
+ Span<int> slice = new Span<int>(a);
+ AssertTrue(Sum(slice) == 6, "Failed to sum slice");
+
+ Span<int> subslice = slice.Slice(1, 2);
+ AssertTrue(Sum(subslice) == 5, "Failed to sum subslice");
+ }
+
+ static void CanAccessItemsViaIndexerStartCtor()
+ {
+ int[] a = new int[] { 1, 2, 3 };
+ Span<int> slice = new Span<int>(a, start: 1);
+ AssertTrue(Sum(slice) == 5, "Failed to sum slice");
+ }
+
+ static void CanAccessItemsViaIndexerStartLengthCtor()
+ {
+ int[] a = new int[] { 1, 2, 3 };
+ Span<int> slice = new Span<int>(a, start: 1, length: 1);
+ AssertTrue(Sum(slice) == 2, "Failed to sum slice");
+ }
+
+ static void TestBoundaryEmptySpanStartCtor()
+ {
+ int[] a = new int[5];
+
+ Span<int> slice = new Span<int>(a, start: a.Length);
+ AssertEqual(slice.Length, 0);
+ }
+
+ static void TestBoundaryEmptySpanStartLengthCtor()
+ {
+ int[] a = new int[5];
+
+ Span<int> slice = new Span<int>(a, a.Length, 0);
+ AssertEqual(slice.Length, 0);
+
+ Span<int> subSlice = new Span<int>(a).Slice(a.Length, 0);
+ AssertEqual(subSlice.Length, 0);
+ }
+
+ static void ReferenceTypesAreSupported()
+ {
+ var underlyingArray = new ReferenceType[] { new ReferenceType(0), new ReferenceType(1), new ReferenceType(2) };
+ var slice = new Span<ReferenceType>(underlyingArray);
+
+ for (int i = 0; i < underlyingArray.Length; i++)
+ {
+ AssertTrue(underlyingArray[i].Value == slice[i].Value, "Values are different");
+ AssertTrue(object.ReferenceEquals(underlyingArray[i], slice[i]), "References are broken");
+ }
+ }
+
+ static unsafe void MustNotMoveGcTypesToUnmanagedMemory()
+ {
+ byte* pointerToStack = stackalloc byte[256];
+
+ try
+ {
+ new Span<ValueTypeWithPointers>(pointerToStack, 1);
+ AssertTrue(false, "Expected exception for value types with references not thrown");
+ }
+ catch (System.ArgumentException ex)
+ {
+ AssertTrue(ex.Message == "Cannot use type 'ValueTypeWithPointers'. Only value types without pointers or references are supported.",
+ "Exception message is incorrect");
+ }
+
+ try
+ {
+ new Span<ReferenceType>(pointerToStack, 1);
+ AssertTrue(false, "Expected exception for reference types not thrown");
+ }
+ catch (System.ArgumentException ex)
+ {
+ AssertTrue(ex.Message == "Cannot use type 'ReferenceType'. Only value types without pointers or references are supported.",
+ "Exception message is incorrect");
+ }
+ }
+
+ static void TestArrayCoVariance()
+ {
+ var array = new ReferenceType[1];
+ var objArray = (object[])array;
+ try
+ {
+ new Span<object>(objArray);
+ AssertTrue(false, "Expected exception not thrown");
+ }
+ catch (ArrayTypeMismatchException)
+ {
+ }
+
+ var objEmptyArray = Array.Empty<ReferenceType>();
+ try
+ {
+ new Span<object>(objEmptyArray);
+ AssertTrue(false, "Expected exception not thrown");
+ }
+ catch (ArrayTypeMismatchException)
+ {
+ }
+ }
+
+ static void TestArrayCoVarianceStartCtor()
+ {
+ var array = new ReferenceType[1];
+ var objArray = (object[])array;
+ try
+ {
+ new Span<object>(objArray, start: 0);
+ AssertTrue(false, "Expected exception not thrown");
+ }
+ catch (ArrayTypeMismatchException)
+ {
+ }
+
+ var objEmptyArray = Array.Empty<ReferenceType>();
+ try
+ {
+ new Span<object>(objEmptyArray, start: 0);
+ AssertTrue(false, "Expected exception not thrown");
+ }
+ catch (ArrayTypeMismatchException)
+ {
+ }
+ }
+
+ static void TestArrayCoVarianceStartLengthCtor()
+ {
+ var array = new ReferenceType[1];
+ var objArray = (object[])array;
+ try
+ {
+ new Span<object>(objArray, start: 0, length: 1);
+ AssertTrue(false, "Expected exception not thrown");
+ }
+ catch (ArrayTypeMismatchException)
+ {
+ }
+
+ var objEmptyArray = Array.Empty<ReferenceType>();
+ try
+ {
+ new Span<object>(objEmptyArray, start: 0, length: 1);
+ AssertTrue(false, "Expected exception not thrown");
+ }
+ catch (ArrayTypeMismatchException)
+ {
+ }
+ }
+
+ static void TestArrayCoVarianceReadOnly()
+ {
+ var array = new ReferenceType[1];
+ var objArray = (object[])array;
+ AssertTrue(new ReadOnlySpan<object>(objArray).Length == 1, "Unexpected length");
+
+ var objEmptyArray = Array.Empty<ReferenceType>();
+ AssertTrue(new ReadOnlySpan<object>(objEmptyArray).Length == 0, "Unexpected length");
+ }
+
+ static void CanUpdateUnderlyingArray()
+ {
+ var underlyingArray = new int[] { 1, 2, 3 };
+ var slice = new Span<int>(underlyingArray);
+
+ slice[0] = 0;
+ slice[1] = 1;
+ slice[2] = 2;
+
+ AssertTrue(underlyingArray[0] == 0, "Failed to update underlying array");
+ AssertTrue(underlyingArray[1] == 1, "Failed to update underlying array");
+ AssertTrue(underlyingArray[2] == 2, "Failed to update underlying array");
+ }
+
+ static void CanCopyValueTypesWithoutPointersToSlice()
+ {
+ var source = new Span<ValueTypeWithoutPointers>(
+ new[]
+ {
+ new ValueTypeWithoutPointers(0),
+ new ValueTypeWithoutPointers(1),
+ new ValueTypeWithoutPointers(2),
+ new ValueTypeWithoutPointers(3)
+ });
+ var underlyingArray = new ValueTypeWithoutPointers[4];
+ var slice = new Span<ValueTypeWithoutPointers>(underlyingArray);
+
+ var result = source.TryCopyTo(slice);
+
+ AssertTrue(result, "Failed to copy value types without pointers");
+ for (int i = 0; i < 4; i++)
+ {
+ AssertTrue(source[i].Value == slice[i].Value, "Failed to copy value types without pointers, values were not equal");
+ AssertTrue(source[i].Value == underlyingArray[i].Value, "Failed to copy value types without pointers to underlying array, values were not equal");
+ }
+ }
+
+ static void CanCopyValueTypesWithoutPointersToArray()
+ {
+ var source = new Span<ValueTypeWithoutPointers>(
+ new[]
+ {
+ new ValueTypeWithoutPointers(0),
+ new ValueTypeWithoutPointers(1),
+ new ValueTypeWithoutPointers(2),
+ new ValueTypeWithoutPointers(3)
+ });
+ var array = new ValueTypeWithoutPointers[4];
+
+ var result = source.TryCopyTo(array);
+
+ AssertTrue(result, "Failed to copy value types without pointers");
+ for (int i = 0; i < 4; i++)
+ {
+ AssertTrue(source[i].Value == array[i].Value, "Failed to copy value types without pointers, values were not equal");
+ }
+ }
+
+ static void CanCopyReferenceTypesToSlice()
+ {
+ var source = new Span<ReferenceType>(
+ new[]
+ {
+ new ReferenceType(0),
+ new ReferenceType(1),
+ new ReferenceType(2),
+ new ReferenceType(3)
+ });
+ var underlyingArray = new ReferenceType[4];
+ var slice = new Span<ReferenceType>(underlyingArray);
+
+ var result = source.TryCopyTo(slice);
+
+ AssertTrue(result, "Failed to copy reference types");
+ for (int i = 0; i < 4; i++)
+ {
+ AssertTrue(source[i] != null && slice[i] != null, "Failed to copy reference types, references were null");
+ AssertTrue(object.ReferenceEquals(source[i], slice[i]), "Failed to copy reference types, references were not equal");
+ AssertTrue(source[i].Value == slice[i].Value, "Failed to copy reference types, values were not equal");
+
+ AssertTrue(underlyingArray[i] != null, "Failed to copy reference types to underlying array, references were null");
+ AssertTrue(object.ReferenceEquals(source[i], underlyingArray[i]), "Failed to copy reference types to underlying array, references were not equal");
+ AssertTrue(source[i].Value == underlyingArray[i].Value, "Failed to copy reference types to underlying array, values were not equal");
+ }
+ }
+
+ static void CanCopyReferenceTypesToArray()
+ {
+ var source = new Span<ReferenceType>(
+ new[]
+ {
+ new ReferenceType(0),
+ new ReferenceType(1),
+ new ReferenceType(2),
+ new ReferenceType(3)
+ });
+ var array = new ReferenceType[4];
+
+ var result = source.TryCopyTo(array);
+
+ AssertTrue(result, "Failed to copy reference types");
+ for (int i = 0; i < 4; i++)
+ {
+ AssertTrue(source[i] != null && array[i] != null, "Failed to copy reference types, references were null");
+ AssertTrue(object.ReferenceEquals(source[i], array[i]), "Failed to copy reference types, references were not equal");
+ AssertTrue(source[i].Value == array[i].Value, "Failed to copy reference types, values were not equal");
+ }
+ }
+
+ static void CanCopyValueTypesWithPointersToSlice()
+ {
+ var source = new Span<ValueTypeWithPointers>(
+ new[]
+ {
+ new ValueTypeWithPointers(new object()),
+ new ValueTypeWithPointers(new object()),
+ new ValueTypeWithPointers(new object()),
+ new ValueTypeWithPointers(new object())
+ });
+ var underlyingArray = new ValueTypeWithPointers[4];
+ var slice = new Span<ValueTypeWithPointers>(underlyingArray);
+
+ var result = source.TryCopyTo(slice);
+
+ AssertTrue(result, "Failed to copy value types with pointers");
+ for (int i = 0; i < 4; i++)
+ {
+ AssertTrue(object.ReferenceEquals(source[i].Reference, slice[i].Reference), "Failed to copy value types with pointers, references were not the same");
+ AssertTrue(object.ReferenceEquals(source[i].Reference, underlyingArray[i].Reference), "Failed to copy value types with pointers to underlying array, references were not the same");
+ }
+ }
+
+ static void CanCopyValueTypesWithPointersToArray()
+ {
+ var source = new Span<ValueTypeWithPointers>(
+ new[]
+ {
+ new ValueTypeWithPointers(new object()),
+ new ValueTypeWithPointers(new object()),
+ new ValueTypeWithPointers(new object()),
+ new ValueTypeWithPointers(new object())
+ });
+ var array = new ValueTypeWithPointers[4];
+
+ var result = source.TryCopyTo(array);
+
+ AssertTrue(result, "Failed to copy value types with pointers");
+ for (int i = 0; i < 4; i++)
+ {
+ AssertTrue(object.ReferenceEquals(source[i].Reference, array[i].Reference), "Failed to copy value types with pointers, references were not the same");
+ }
+ }
+
+ static unsafe void CanCopyValueTypesWithoutPointersToUnmanagedMemory()
+ {
+ var source = new Span<byte>(
+ new byte[]
+ {
+ 0,
+ 1,
+ 2,
+ 3
+ });
+ byte* pointerToStack = stackalloc byte[256];
+
+ var result = source.TryCopyTo(new Span<byte>(pointerToStack, 4));
+
+ AssertTrue(result, "Failed to copy value types without pointers to unamanaged memory");
+ for (int i = 0; i < 4; i++)
+ {
+ AssertTrue(source[i] == pointerToStack[i], "Failed to copy value types without pointers to unamanaged memory, values were not equal");
+ }
+ }
+
+ static void CanCopyOverlappingSlicesOfValueTypeWithoutPointers()
+ {
+ var sourceArray = new[]
+ {
+ new ValueTypeWithoutPointers(0),
+ new ValueTypeWithoutPointers(1),
+ new ValueTypeWithoutPointers(2)
+ };
+ var firstAndSecondElements = new Span<ValueTypeWithoutPointers>(sourceArray, 0, 2); // 0, 1
+ var secondAndThirdElements = new Span<ValueTypeWithoutPointers>(sourceArray, 1, 2); // 1, 2
+
+ // 0 1 2 sourceArray
+ // 0 1 - firstAndSecondElements
+ // - 1 2 secondAndThirdElements
+ var result = firstAndSecondElements.TryCopyTo(secondAndThirdElements); // to avoid overlap we should copy backward now
+ // - 0 1 secondAndThirdElements
+ // 0 0 - firstAndSecondElements
+ // 0 0 1 sourceArray
+
+ AssertTrue(result, "Failed to copy overlapping value types without pointers");
+
+ AssertTrue(secondAndThirdElements[1].Value == 1, "secondAndThirdElements[1] should get replaced by 1");
+ AssertTrue(secondAndThirdElements[0].Value == 0 && firstAndSecondElements[1].Value == 0, "secondAndThirdElements[0] and firstAndSecondElements[1] point to the same element, should get replaced by 0");
+ AssertTrue(firstAndSecondElements[0].Value == 0, "firstAndSecondElements[0] should remain the same");
+
+ // let's try the other direction to make sure it works as well!
+
+ sourceArray = new[]
+ {
+ new ValueTypeWithoutPointers(0),
+ new ValueTypeWithoutPointers(1),
+ new ValueTypeWithoutPointers(2)
+ };
+ firstAndSecondElements = new Span<ValueTypeWithoutPointers>(sourceArray, 0, 2); // 0, 1
+ secondAndThirdElements = new Span<ValueTypeWithoutPointers>(sourceArray, 1, 2); // 1, 2
+
+ // 0 1 2 sourceArray
+ // 0 1 - firstAndSecondElements
+ // - 1 2 secondAndThirdElements
+ result = secondAndThirdElements.TryCopyTo(firstAndSecondElements); // to avoid overlap we should copy forward now
+ // 1 2 - firstAndSecondElements
+ // - 2 2 secondAndThirdElements
+ // 1 2 2 sourceArray
+
+ AssertTrue(result, "Failed to copy overlapping value types without pointers");
+
+ AssertTrue(secondAndThirdElements[1].Value == 2, "secondAndThirdElements[1] should remain the same");
+ AssertTrue(firstAndSecondElements[1].Value == 2 && secondAndThirdElements[0].Value == 2, "secondAndThirdElements[0] && firstAndSecondElements[1] point to the same element, should get replaced by 2");
+ AssertTrue(firstAndSecondElements[0].Value == 1, "firstAndSecondElements[0] should get replaced by 1");
+ }
+
+ static void CanCopyOverlappingSlicesOfValueTypeWithPointers()
+ {
+ string zero = "0", one = "1", two = "2";
+ var sourceArray = new[]
+ {
+ new ValueTypeWithPointers(zero),
+ new ValueTypeWithPointers(one),
+ new ValueTypeWithPointers(two)
+ };
+ var firstAndSecondElements = new Span<ValueTypeWithPointers>(sourceArray, 0, 2); // 0, 1
+ var secondAndThirdElements = new Span<ValueTypeWithPointers>(sourceArray, 1, 2); // 1, 2
+
+ // 0 1 2 sourceArray
+ // 0 1 - firstAndSecondElements
+ // - 1 2 secondAndThirdElements
+ var result = firstAndSecondElements.TryCopyTo(secondAndThirdElements); // to avoid overlap we should copy backward now
+ // - 0 1 secondAndThirdElements
+ // 0 0 - firstAndSecondElements
+ // 0 0 1 sourceArray
+
+ AssertTrue(result, "Failed to copy overlapping value types with pointers");
+
+ AssertTrue(object.ReferenceEquals(secondAndThirdElements[1].Reference, one), "secondAndThirdElements[1] should get replaced by 1");
+ AssertTrue(object.ReferenceEquals(secondAndThirdElements[0].Reference, zero) && object.ReferenceEquals(firstAndSecondElements[1].Reference, zero), "secondAndThirdElements[0] and firstAndSecondElements[1] point to the same element, should get replaced by 0");
+ AssertTrue(object.ReferenceEquals(firstAndSecondElements[0].Reference, zero), "firstAndSecondElements[0] should remain the same");
+
+ // let's try the other direction to make sure it works as well!
+
+ sourceArray = new[]
+ {
+ new ValueTypeWithPointers(zero),
+ new ValueTypeWithPointers(one),
+ new ValueTypeWithPointers(two)
+ };
+ firstAndSecondElements = new Span<ValueTypeWithPointers>(sourceArray, 0, 2); // 0, 1
+ secondAndThirdElements = new Span<ValueTypeWithPointers>(sourceArray, 1, 2); // 1, 2
+
+ // 0 1 2 sourceArray
+ // 0 1 - firstAndSecondElements
+ // - 1 2 secondAndThirdElements
+ result = secondAndThirdElements.TryCopyTo(firstAndSecondElements); // to avoid overlap we should copy forward now
+ // 1 2 - firstAndSecondElements
+ // - 2 2 secondAndThirdElements
+ // 1 2 2 sourceArray
+
+ AssertTrue(result, "Failed to copy overlapping value types with pointers");
+
+ AssertTrue(object.ReferenceEquals(secondAndThirdElements[1].Reference, two), "secondAndThirdElements[1] should remain the same");
+ AssertTrue(object.ReferenceEquals(firstAndSecondElements[1].Reference, two) && object.ReferenceEquals(secondAndThirdElements[0].Reference, two), "secondAndThirdElements[0] && firstAndSecondElements[1] point to the same element, should get replaced by 2");
+ AssertTrue(object.ReferenceEquals(firstAndSecondElements[0].Reference, one), "firstAndSecondElements[0] should get replaced by 1");
+ }
+
+ static void CanCopyOverlappingSlicesOfReferenceTypes()
+ {
+ var sourceArray = new ReferenceType[] { new ReferenceType(0), new ReferenceType(1), new ReferenceType(2) };
+
+ var firstAndSecondElements = new Span<ReferenceType>(sourceArray, 0, 2); // 0, 1
+ var secondAndThirdElements = new Span<ReferenceType>(sourceArray, 1, 2); // 1, 2
+
+ // 0 1 2 sourceArray
+ // 0 1 - firstAndSecondElements
+ // - 1 2 secondAndThirdElements
+ var result = firstAndSecondElements.TryCopyTo(secondAndThirdElements); // to avoid overlap we should copy backward now
+ // - 0 1 secondAndThirdElements
+ // 0 0 - firstAndSecondElements
+ // 0 0 1 sourceArray
+
+ AssertTrue(result, "Failed to copy overlapping reference types");
+
+ AssertTrue(secondAndThirdElements[1].Value == 1, "secondAndThirdElements[1] should get replaced by 1");
+ AssertTrue(secondAndThirdElements[0].Value == 0 && firstAndSecondElements[1].Value == 0, "secondAndThirdElements[0] and firstAndSecondElements[1] point to the same element, should get replaced by 0");
+ AssertTrue(firstAndSecondElements[0].Value == 0, "firstAndSecondElements[0] should remain the same");
+
+ // let's try the other direction to make sure it works as well!
+
+ sourceArray = new[]
+ {
+ new ReferenceType(0),
+ new ReferenceType(1),
+ new ReferenceType(2)
+ };
+ firstAndSecondElements = new Span<ReferenceType>(sourceArray, 0, 2); // 0, 1
+ secondAndThirdElements = new Span<ReferenceType>(sourceArray, 1, 2); // 1, 2
+
+ // 0 1 2 sourceArray
+ // 0 1 - firstAndSecondElements
+ // - 1 2 secondAndThirdElements
+ result = secondAndThirdElements.TryCopyTo(firstAndSecondElements); // to avoid overlap we should copy forward now
+ // 1 2 - firstAndSecondElements
+ // - 2 2 secondAndThirdElements
+ // 1 2 2 sourceArray
+
+ AssertTrue(result, "Failed to copy overlapping reference types");
+
+ AssertTrue(secondAndThirdElements[1].Value == 2, "secondAndThirdElements[1] should remain the same");
+ AssertTrue(firstAndSecondElements[1].Value == 2 && secondAndThirdElements[0].Value == 2, "secondAndThirdElements[0] && firstAndSecondElements[1] point to the same element, should get replaced by 2");
+ AssertTrue(firstAndSecondElements[0].Value == 1, "firstAndSecondElements[0] should get replaced by 1");
+ }
+
+ static void MustNotCastSpanOfValueTypesWithPointers()
+ {
+ var spanOfValueTypeWithPointers = new Span<ValueTypeWithPointers>(new[] { new ValueTypeWithPointers(new object()) });
+
+ try
+ {
+ var impossible = spanOfValueTypeWithPointers.AsBytes();
+ AssertTrue(false, "Expected exception for wrong type not thrown");
+ }
+ catch (System.ArgumentException ex)
+ {
+ AssertTrue(ex.Message == "Cannot use type 'ValueTypeWithPointers'. Only value types without pointers or references are supported.",
+ "Exception message is incorrect");
+ }
+
+ try
+ {
+ var impossible = spanOfValueTypeWithPointers.NonPortableCast<ValueTypeWithPointers, byte>();
+ AssertTrue(false, "Expected exception for wrong type not thrown");
+ }
+ catch (System.ArgumentException ex)
+ {
+ AssertTrue(ex.Message == "Cannot use type 'ValueTypeWithPointers'. Only value types without pointers or references are supported.",
+ "Exception message is incorrect");
+ }
+
+ var spanOfBytes = new Span<byte>(new byte[10]);
+ try
+ {
+ var impossible = spanOfBytes.NonPortableCast<byte, ValueTypeWithPointers>();
+ AssertTrue(false, "Expected exception for wrong type not thrown");
+ }
+ catch (System.ArgumentException ex)
+ {
+ AssertTrue(ex.Message == "Cannot use type 'ValueTypeWithPointers'. Only value types without pointers or references are supported.",
+ "Exception message is incorrect");
+ }
+ }
+
+ static void IntArraySpanCastedToByteArraySpanHasSameBytesAsOriginalArray()
+ {
+ var ints = new int[100000];
+ Random r = new Random(42324232);
+ for (int i = 0; i < ints.Length; i++) { ints[i] = r.Next(); }
+ var bytes = new Span<int>(ints).AsBytes();
+ AssertEqual(bytes.Length, ints.Length * sizeof(int));
+ for (int i = 0; i < ints.Length; i++)
+ {
+ AssertEqual(bytes[i * 4], (ints[i] & 0xff));
+ AssertEqual(bytes[i * 4 + 1], (ints[i] >> 8 & 0xff));
+ AssertEqual(bytes[i * 4 + 2], (ints[i] >> 16 & 0xff));
+ AssertEqual(bytes[i * 4 + 3], (ints[i] >> 24 & 0xff));
+ }
+ }
+
+ static void ByteArraySpanCastedToIntArraySpanHasSameBytesAsOriginalArray()
+ {
+ var bytes = new byte[100000];
+ Random r = new Random(541345);
+ for (int i = 0; i < bytes.Length; i++) { bytes[i] = (byte)r.Next(256); }
+ var ints = new Span<byte>(bytes).NonPortableCast<byte, int>();
+ AssertEqual(ints.Length, bytes.Length / sizeof(int));
+ for (int i = 0; i < ints.Length; i++)
+ {
+ AssertEqual(BitConverter.ToInt32(bytes, i * 4), ints[i]);
+ }
+ }
+
+ static void SourceTypeLargerThanTargetOneCorrectlyCalcsTargetsLength()
+ {
+ for (int sourceLength = 0; sourceLength <= 4; sourceLength++)
+ {
+ var sourceSlice = new Span<SevenBytesStruct>(new SevenBytesStruct[sourceLength]);
+
+ var targetSlice = sourceSlice.NonPortableCast<SevenBytesStruct, short>();
+
+ AssertEqual((sourceLength * 7) / sizeof(short), targetSlice.Length);
+ }
+ }
+
+ static void WhenSourceDoesntFitIntoTargetLengthIsZero()
+ {
+ for (int sourceLength = 0; sourceLength <= 3; sourceLength++)
+ {
+ var sourceSlice = new Span<short>(new short[sourceLength]);
+
+ var targetSlice = sourceSlice.NonPortableCast<short, SevenBytesStruct>();
+
+ AssertEqual(0, targetSlice.Length);
+ }
+ }
+
+ static void WhenSourceFitsIntoTargetOnceLengthIsOne()
+ {
+ foreach (var sourceLength in new int[] { 4, 6 })
+ {
+ var sourceSlice = new Span<short>(new short[sourceLength]);
+
+ var targetSlice = sourceSlice.NonPortableCast<short, SevenBytesStruct>();
+
+ AssertEqual(1, targetSlice.Length);
+ }
+ }
+
+ static void WhenSourceTypeLargerThanTargetAndOverflowsInt32ThrowsException()
+ {
+ unsafe
+ {
+ byte dummy;
+ int sourceLength = 620000000;
+ var sourceSlice = new Span<SevenBytesStruct>(&dummy, sourceLength);
+
+ try
+ {
+ var targetSlice = sourceSlice.NonPortableCast<SevenBytesStruct, short>();
+ AssertTrue(false, "Expected exception for overflow not thrown");
+ }
+ catch (System.OverflowException)
+ {
+ }
+ }
+ }
+
+ static void CanCreateSpanFromString()
+ {
+ const string fullText = "new Span<byte>()";
+ var spanFromFull = fullText.Slice();
+ AssertEqualContent(fullText, spanFromFull);
+
+ string firstHalfOfString = fullText.Substring(0, fullText.Length / 2);
+ var spanFromFirstHalf = fullText.Slice(0, fullText.Length / 2);
+ AssertEqualContent(firstHalfOfString, spanFromFirstHalf);
+
+ string secondHalfOfString = fullText.Substring(fullText.Length / 2);
+ var spanFromSecondHalf = fullText.Slice(fullText.Length / 2);
+ AssertEqualContent(secondHalfOfString, spanFromSecondHalf);
+ }
+
+ static void WhenStartLargerThanLengthThrowsExceptionStartCtor()
+ {
+ try
+ {
+ var data = new byte[10];
+ var slice = new Span<byte>(data, start: 11);
+ AssertTrue(false, "Expected exception for Argument Out of Range not thrown");
+ }
+ catch (System.ArgumentOutOfRangeException)
+ {
+ }
+ }
+
+ static void WhenStartLargerThanLengthThrowsExceptionStartLengthCtor()
+ {
+ try
+ {
+ var data = new byte[10];
+ var slice = new Span<byte>(data, start: 11, length: 0);
+ AssertTrue(false, "Expected exception for Argument Out of Range not thrown");
+ }
+ catch (System.ArgumentOutOfRangeException)
+ {
+ }
+ }
+
+ static void WhenStartAndLengthLargerThanLengthThrowsExceptionStartLengthCtor()
+ {
+ try
+ {
+ var data = new byte[10];
+ var slice = new Span<byte>(data, start: 1, length: 10);
+ AssertTrue(false, "Expected exception for Argument Out of Range not thrown");
+ }
+ catch (System.ArgumentOutOfRangeException)
+ {
+ }
+ }
+
+ static void Test(Action test, string testName, ref int failedTestsCount)
+ {
+ try
+ {
+ test();
+
+ Console.WriteLine(testName + " test has passed");
+ }
+ catch (System.Exception ex)
+ {
+ Console.WriteLine(testName + " test has failed with exception: " + ex.Message);
+
+ ++failedTestsCount;
+ }
+ finally
+ {
+ Console.WriteLine("-------------------");
+ }
+ }
+
+ static void AssertTrue(bool condition, string errorMessage)
+ {
+ if (condition == false)
+ {
+ throw new Exception(errorMessage);
+ }
+ }
+
+ static void AssertEqual<T>(T left, T right)
+ where T : IEquatable<T>
+ {
+ if (left.Equals(right) == false)
+ {
+ throw new Exception(string.Format("Values were not equal! {0} and {1}", left, right));
+ }
+ }
+
+ static void AssertEqualContent(string text, ReadOnlySpan<char> span)
+ {
+ AssertEqual(text.Length, span.Length);
+ for (int i = 0; i < text.Length; i++)
+ {
+ AssertEqual(text[i], span[i]);
+ }
+ }
+}
diff --git a/tests/src/GC/API/GC/GetGenerationWR2.csproj b/tests/src/GC/API/GC/GetGenerationWR2.csproj
index 35a05a68bf..6b109e9c8c 100644
--- a/tests/src/GC/API/GC/GetGenerationWR2.csproj
+++ b/tests/src/GC/API/GC/GetGenerationWR2.csproj
@@ -13,6 +13,7 @@
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <GCStressIncompatible Condition="'$(Platform)' == 'x86'">true</GCStressIncompatible>
<NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
<CLRTestExecutionArguments></CLRTestExecutionArguments>
diff --git a/tests/src/GC/API/GCHandleCollector/Usage.cs b/tests/src/GC/API/GCHandleCollector/Usage.cs
index 14088f03de..b78271b243 100644
--- a/tests/src/GC/API/GCHandleCollector/Usage.cs
+++ b/tests/src/GC/API/GCHandleCollector/Usage.cs
@@ -146,7 +146,8 @@ public class Usage
// ensure threshold is increasing
if (!CheckPercentageIncrease(handleCount, prevHandleCount))
{
- Console.WriteLine("Case 3 failed: threshold not increasing!");
+ // see github#4093 for the rationale for fail-fast in this test.
+ Environment.FailFast(string.Empty);
return false;
}
prevHandleCount = handleCount;
diff --git a/tests/src/GC/Features/HeapExpansion/pluggaps.csproj b/tests/src/GC/Features/HeapExpansion/pluggaps.csproj
index cbeab565fe..42ba45a58f 100644
--- a/tests/src/GC/Features/HeapExpansion/pluggaps.csproj
+++ b/tests/src/GC/Features/HeapExpansion/pluggaps.csproj
@@ -14,6 +14,7 @@
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
<GCStressIncompatible>true</GCStressIncompatible>
+ <HeapVerifyIncompatible Condition="'$(Platform)' == 'x86'">true</HeapVerifyIncompatible>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
diff --git a/tests/src/GC/Performance/Framework/GCPerfTestFramework.csproj b/tests/src/GC/Performance/Framework/GCPerfTestFramework.csproj
index cc8261f26e..d013349cc9 100644
--- a/tests/src/GC/Performance/Framework/GCPerfTestFramework.csproj
+++ b/tests/src/GC/Performance/Framework/GCPerfTestFramework.csproj
@@ -35,11 +35,12 @@
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<ItemGroup>
- <Reference Include="Microsoft.Diagnostics.Tracing.TraceEvent, Version=1.0.39.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
- <HintPath>packages\Microsoft.Diagnostics.Tracing.TraceEvent.1.0.39\lib\net40\Microsoft.Diagnostics.Tracing.TraceEvent.dll</HintPath>
+ <Reference Include="Microsoft.Diagnostics.Tracing.TraceEvent, Version=1.0.41.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <HintPath>packages\Microsoft.Diagnostics.Tracing.TraceEvent.1.0.41\lib\net40\Microsoft.Diagnostics.Tracing.TraceEvent.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
+ <Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
<Reference Include="System.IO.FileSystem, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>packages\System.IO.FileSystem.4.0.0\lib\net46\System.IO.FileSystem.dll</HintPath>
@@ -56,27 +57,27 @@
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
- <HintPath>packages\Microsoft.DotNet.xunit.performance.metrics.1.0.0-alpha-build0030\lib\net46\xunit.abstractions.dll</HintPath>
+ <HintPath>packages\Microsoft.DotNet.xunit.performance.metrics.1.0.0-alpha-build0040\lib\net46\xunit.abstractions.dll</HintPath>
<Private>True</Private>
</Reference>
- <Reference Include="xunit.core, Version=2.1.0.3179, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
- <HintPath>packages\xunit.extensibility.core.2.1.0\lib\dotnet\xunit.core.dll</HintPath>
+ <Reference Include="xunit.core, Version=2.2.0.3300, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
+ <HintPath>packages\xunit.extensibility.core.2.2.0-beta2-build3300\lib\netstandard1.0\xunit.core.dll</HintPath>
<Private>True</Private>
</Reference>
- <Reference Include="xunit.execution.desktop, Version=2.1.0.3179, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
- <HintPath>packages\xunit.extensibility.execution.2.1.0\lib\net45\xunit.execution.desktop.dll</HintPath>
+ <Reference Include="xunit.execution.desktop, Version=2.2.0.3300, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
+ <HintPath>packages\xunit.extensibility.execution.2.2.0-beta2-build3300\lib\net45\xunit.execution.desktop.dll</HintPath>
<Private>True</Private>
</Reference>
- <Reference Include="xunit.performance.core, Version=1.0.0.30, Culture=neutral, PublicKeyToken=67066efe964d3b03, processorArchitecture=MSIL">
- <HintPath>packages\Microsoft.DotNet.xunit.performance.metrics.1.0.0-alpha-build0030\lib\net46\xunit.performance.core.dll</HintPath>
+ <Reference Include="xunit.performance.core, Version=1.0.0.40, Culture=neutral, PublicKeyToken=67066efe964d3b03, processorArchitecture=MSIL">
+ <HintPath>packages\Microsoft.DotNet.xunit.performance.metrics.1.0.0-alpha-build0040\lib\net46\xunit.performance.core.dll</HintPath>
<Private>True</Private>
</Reference>
- <Reference Include="xunit.performance.execution.desktop, Version=1.0.0.30, Culture=neutral, PublicKeyToken=67066efe964d3b03, processorArchitecture=MSIL">
- <HintPath>packages\Microsoft.DotNet.xunit.performance.1.0.0-alpha-build0030\lib\net46\xunit.performance.execution.desktop.dll</HintPath>
+ <Reference Include="xunit.performance.execution.desktop, Version=1.0.0.40, Culture=neutral, PublicKeyToken=67066efe964d3b03, processorArchitecture=MSIL">
+ <HintPath>packages\Microsoft.DotNet.xunit.performance.1.0.0-alpha-build0040\lib\net46\xunit.performance.execution.desktop.dll</HintPath>
<Private>True</Private>
</Reference>
- <Reference Include="xunit.performance.metrics, Version=1.0.0.30, Culture=neutral, processorArchitecture=MSIL">
- <HintPath>packages\Microsoft.DotNet.xunit.performance.metrics.1.0.0-alpha-build0030\lib\net46\xunit.performance.metrics.dll</HintPath>
+ <Reference Include="xunit.performance.metrics, Version=1.0.0.40, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>packages\Microsoft.DotNet.xunit.performance.metrics.1.0.0-alpha-build0040\lib\net46\xunit.performance.metrics.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
@@ -102,12 +103,12 @@
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <Import Project="packages\Microsoft.Diagnostics.Tracing.TraceEvent.1.0.39\build\Microsoft.Diagnostics.Tracing.TraceEvent.targets" Condition="Exists('packages\Microsoft.Diagnostics.Tracing.TraceEvent.1.0.39\build\Microsoft.Diagnostics.Tracing.TraceEvent.targets')" />
+ <Import Project="packages\Microsoft.Diagnostics.Tracing.TraceEvent.1.0.41\build\Microsoft.Diagnostics.Tracing.TraceEvent.targets" Condition="Exists('packages\Microsoft.Diagnostics.Tracing.TraceEvent.1.0.41\build\Microsoft.Diagnostics.Tracing.TraceEvent.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
- <Error Condition="!Exists('packages\Microsoft.Diagnostics.Tracing.TraceEvent.1.0.39\build\Microsoft.Diagnostics.Tracing.TraceEvent.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Microsoft.Diagnostics.Tracing.TraceEvent.1.0.39\build\Microsoft.Diagnostics.Tracing.TraceEvent.targets'))" />
+ <Error Condition="!Exists('packages\Microsoft.Diagnostics.Tracing.TraceEvent.1.0.41\build\Microsoft.Diagnostics.Tracing.TraceEvent.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Microsoft.Diagnostics.Tracing.TraceEvent.1.0.41\build\Microsoft.Diagnostics.Tracing.TraceEvent.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
diff --git a/tests/src/GC/Performance/Framework/packages.config b/tests/src/GC/Performance/Framework/packages.config
index 16572761b4..c43e175825 100644
--- a/tests/src/GC/Performance/Framework/packages.config
+++ b/tests/src/GC/Performance/Framework/packages.config
@@ -1,24 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="Microsoft.Diagnostics.Tracing.TraceEvent" version="1.0.39" targetFramework="net461" />
- <package id="Microsoft.DotNet.xunit.performance" version="1.0.0-alpha-build0030" targetFramework="net461" />
- <package id="Microsoft.DotNet.xunit.performance.metrics" version="1.0.0-alpha-build0030" targetFramework="net461" />
+ <package id="Microsoft.Diagnostics.Tracing.TraceEvent" version="1.0.41" targetFramework="net461" />
+ <package id="Microsoft.DotNet.xunit.performance" version="1.0.0-alpha-build0040" targetFramework="net461" />
+ <package id="Microsoft.DotNet.xunit.performance.metrics" version="1.0.0-alpha-build0040" targetFramework="net461" />
<package id="System.Collections" version="4.0.10" targetFramework="net461" />
<package id="System.Diagnostics.Debug" version="4.0.10" targetFramework="net461" />
- <package id="System.Diagnostics.Tracing" version="4.0.20" targetFramework="net461" />
+ <package id="System.Diagnostics.Tracing" version="4.1.0" targetFramework="net461" />
<package id="System.Globalization" version="4.0.10" targetFramework="net461" />
- <package id="System.IO" version="4.0.10" targetFramework="net461" />
+ <package id="System.IO" version="4.1.0" targetFramework="net461" />
<package id="System.IO.FileSystem" version="4.0.0" targetFramework="net461" />
<package id="System.IO.FileSystem.Primitives" version="4.0.0" targetFramework="net461" />
- <package id="System.Linq" version="4.0.0" targetFramework="net461" />
- <package id="System.Reflection" version="4.0.10" targetFramework="net461" />
- <package id="System.Runtime" version="4.0.20" targetFramework="net461" />
- <package id="System.Runtime.Extensions" version="4.0.10" targetFramework="net461" />
+ <package id="System.Linq" version="4.1.0" targetFramework="net461" />
+ <package id="System.Reflection" version="4.1.0" targetFramework="net461" />
+ <package id="System.Runtime" version="4.1.0" targetFramework="net461" />
+ <package id="System.Runtime.Extensions" version="4.1.0" targetFramework="net461" />
<package id="System.Runtime.Handles" version="4.0.0" targetFramework="net461" />
<package id="System.Text.Encoding" version="4.0.10" targetFramework="net461" />
<package id="System.Threading" version="4.0.10" targetFramework="net461" />
<package id="System.Threading.Tasks" version="4.0.10" targetFramework="net461" />
- <package id="xunit.abstractions" version="2.0.0" targetFramework="net461" />
- <package id="xunit.extensibility.core" version="2.1.0" targetFramework="net461" />
- <package id="xunit.extensibility.execution" version="2.1.0" targetFramework="net461" />
+ <package id="xunit.abstractions" version="2.0.1-rc2" targetFramework="net461" />
+ <package id="xunit.extensibility.core" version="2.2.0-beta2-build3300" targetFramework="net461" />
+ <package id="xunit.extensibility.execution" version="2.2.0-beta2-build3300" targetFramework="net461" />
</packages> \ No newline at end of file
diff --git a/tests/src/GC/Regressions/v2.0-rtm/494226/494226.csproj b/tests/src/GC/Regressions/v2.0-rtm/494226/494226.csproj
index 99623f4563..fe23500677 100644
--- a/tests/src/GC/Regressions/v2.0-rtm/494226/494226.csproj
+++ b/tests/src/GC/Regressions/v2.0-rtm/494226/494226.csproj
@@ -14,6 +14,7 @@
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
<GCStressIncompatible>true</GCStressIncompatible>
+ <HeapVerifyIncompatible Condition="'$(Platform)' == 'x86'">true</HeapVerifyIncompatible>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
@@ -36,4 +37,4 @@
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
</PropertyGroup>
-</Project> \ No newline at end of file
+</Project>
diff --git a/tests/src/GC/Scenarios/DoublinkList/dlcollect.cs b/tests/src/GC/Scenarios/DoublinkList/dlcollect.cs
index a3a0c53dac..a17e95a270 100644
--- a/tests/src/GC/Scenarios/DoublinkList/dlcollect.cs
+++ b/tests/src/GC/Scenarios/DoublinkList/dlcollect.cs
@@ -77,6 +77,12 @@ namespace DoubLink {
GC.WaitForPendingFinalizers();
+ if (DLinkNode.FinalCount != iRep * iObj * 10)
+ {
+ // see github#4093 for the rationale for fail-fast in this test.
+ Environment.FailFast(string.Empty);
+ }
+
Console.WriteLine("{0} DLinkNodes finalized", DLinkNode.FinalCount);
return (DLinkNode.FinalCount==iRep*iObj*10);
}
diff --git a/tests/src/GC/Scenarios/DoublinkList/dlstack.cs b/tests/src/GC/Scenarios/DoublinkList/dlstack.cs
index 5aea9586c4..5e207bec52 100644
--- a/tests/src/GC/Scenarios/DoublinkList/dlstack.cs
+++ b/tests/src/GC/Scenarios/DoublinkList/dlstack.cs
@@ -85,6 +85,12 @@ namespace DoubLink {
curTotalMemory = GC.GetTotalMemory(false);
}
+ if (DLinkNode.FinalCount != iRep * iObj * 10)
+ {
+ // see github#4093 for the rationale for fail-fast in this test.
+ Environment.FailFast(string.Empty);
+ }
+
Console.WriteLine("{0} DLinkNodes finalized", DLinkNode.FinalCount);
return (DLinkNode.FinalCount==iRep*iObj*10);
diff --git a/tests/src/GC/Scenarios/DoublinkList/doublinkgen.cs b/tests/src/GC/Scenarios/DoublinkList/doublinkgen.cs
index 9c5e4b6b04..76436ea7fe 100644
--- a/tests/src/GC/Scenarios/DoublinkList/doublinkgen.cs
+++ b/tests/src/GC/Scenarios/DoublinkList/doublinkgen.cs
@@ -71,6 +71,12 @@ namespace DoubLink {
GC.WaitForPendingFinalizers();
GC.Collect();
+ if (DLinkNode.FinalCount != iRep * iObj)
+ {
+ // see github#4093 for the rationale for fail-fast in this test.
+ Environment.FailFast(string.Empty);
+ }
+
Console.Write(DLinkNode.FinalCount);
Console.WriteLine(" DLinkNodes finalized");
return (DLinkNode.FinalCount==iRep*iObj);
diff --git a/tests/src/GC/Scenarios/FinalizeTimeout/FinalizeTimeout.cs b/tests/src/GC/Scenarios/FinalizeTimeout/FinalizeTimeout.cs
index 0fda8172e4..60a6861734 100644
--- a/tests/src/GC/Scenarios/FinalizeTimeout/FinalizeTimeout.cs
+++ b/tests/src/GC/Scenarios/FinalizeTimeout/FinalizeTimeout.cs
@@ -17,6 +17,7 @@ public class FinalizeTimeout
do
{
finalizableObject = new BlockingFinalizerOnShutdown();
+ GC.KeepAlive(finalizableObject);
} while (!BlockingFinalizerOnShutdown.finalizerCompletedOnce);
// Start a bunch of threads that allocate continuously, to increase the chance that when Main returns, one of the
@@ -42,12 +43,15 @@ public class FinalizeTimeout
{
byte[] b;
while (true)
+ {
b = new byte[1024];
+ GC.KeepAlive(b);
+ }
}
private class BlockingFinalizerOnShutdown
{
- public static bool finalizerCompletedOnce = false;
+ public volatile static bool finalizerCompletedOnce = false;
public bool isLastObject = false;
~BlockingFinalizerOnShutdown()
@@ -68,6 +72,7 @@ public class FinalizeTimeout
do
{
o = new object();
+ GC.KeepAlive(o);
} while ((++i & 0xff) != 0 || (elapsed = DateTime.Now - start) < timeout);
Console.WriteLine("Finalizer end");
diff --git a/tests/src/GC/Scenarios/ServerModel/servermodel.csproj b/tests/src/GC/Scenarios/ServerModel/servermodel.csproj
index 33fc4efbc8..dff52fc6ad 100644
--- a/tests/src/GC/Scenarios/ServerModel/servermodel.csproj
+++ b/tests/src/GC/Scenarios/ServerModel/servermodel.csproj
@@ -15,6 +15,7 @@
<NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
<CLRTestExecutionArguments>/numrequests:100</CLRTestExecutionArguments>
<GCStressIncompatible>true</GCStressIncompatible>
+ <HeapVerifyIncompatible Condition="'$(Platform)' == 'x86'">true</HeapVerifyIncompatible>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
diff --git a/tests/src/GC/Stress/Framework/ReliabilityFramework.csproj b/tests/src/GC/Stress/Framework/ReliabilityFramework.csproj
index 9288e52ffe..9dd878b8db 100644
--- a/tests/src/GC/Stress/Framework/ReliabilityFramework.csproj
+++ b/tests/src/GC/Stress/Framework/ReliabilityFramework.csproj
@@ -52,6 +52,6 @@
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<Target Name="AfterBuild">
- <MSBuild Projects="@(StressTests)" Properties="OutputPath=$(OutDir)\Tests" />
+ <MSBuild Projects="@(StressTests)" Properties="OutputPath=$(OutDir)\Tests;BuildingForReliabilityFramework=true" />
</Target>
</Project>
diff --git a/tests/src/GC/Stress/Tests/dir.targets b/tests/src/GC/Stress/Tests/dir.targets
new file mode 100644
index 0000000000..d4f8bf9251
--- /dev/null
+++ b/tests/src/GC/Stress/Tests/dir.targets
@@ -0,0 +1,6 @@
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <DisableProjectBuild Condition="'$(BuildingForReliabilityFramework)' != 'true'">true</DisableProjectBuild>
+ </PropertyGroup>
+ <Import Project="..\..\..\dir.targets" />
+</Project> \ No newline at end of file
diff --git a/tests/src/Interop/ArrayMarshalling/ByValArray/MarshalArrayByValNative.cpp b/tests/src/Interop/ArrayMarshalling/ByValArray/MarshalArrayByValNative.cpp
index bf3d66d41c..27de41a826 100644
--- a/tests/src/Interop/ArrayMarshalling/ByValArray/MarshalArrayByValNative.cpp
+++ b/tests/src/Interop/ArrayMarshalling/ByValArray/MarshalArrayByValNative.cpp
@@ -185,84 +185,84 @@ Function
/*----------------------------------------------------------------------------
marshal sequential strut
----------------------------------------------------------------------------*/
-extern "C" DLL_EXPORT BOOL TakeIntArraySeqStructByVal( S_INTArray s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeIntArraySeqStructByVal( S_INTArray s, int size )
{
CHECK_PARAM_NOT_EMPTY( s.arr );
INIT_EXPECTED( INT, ARRAY_SIZE );
return Equals( s.arr, size, expected, ARRAY_SIZE );
}
-extern "C" DLL_EXPORT BOOL TakeUIntArraySeqStructByVal( S_UINTArray s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeUIntArraySeqStructByVal( S_UINTArray s, int size )
{
CHECK_PARAM_NOT_EMPTY( s.arr );
INIT_EXPECTED( UINT, ARRAY_SIZE );
return Equals( s.arr, size, expected, ARRAY_SIZE );
}
-extern "C" DLL_EXPORT BOOL TakeShortArraySeqStructByVal( S_SHORTArray s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeShortArraySeqStructByVal( S_SHORTArray s, int size )
{
CHECK_PARAM_NOT_EMPTY( s.arr );
INIT_EXPECTED( SHORT, ARRAY_SIZE );
return Equals( s.arr, size, expected, ARRAY_SIZE );
}
-extern "C" DLL_EXPORT BOOL TakeWordArraySeqStructByVal( S_WORDArray s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeWordArraySeqStructByVal( S_WORDArray s, int size )
{
CHECK_PARAM_NOT_EMPTY( s.arr );
INIT_EXPECTED( WORD, ARRAY_SIZE );
return Equals( s.arr, size, expected, ARRAY_SIZE );
}
-extern "C" DLL_EXPORT BOOL TakeLong64ArraySeqStructByVal( S_LONG64Array s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeLong64ArraySeqStructByVal( S_LONG64Array s, int size )
{
CHECK_PARAM_NOT_EMPTY( s.arr );
INIT_EXPECTED( LONG64, ARRAY_SIZE );
return Equals( s.arr, size, expected, ARRAY_SIZE );
}
-extern "C" DLL_EXPORT BOOL TakeULong64ArraySeqStructByVal( S_ULONG64Array s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeULong64ArraySeqStructByVal( S_ULONG64Array s, int size )
{
CHECK_PARAM_NOT_EMPTY( s.arr );
INIT_EXPECTED( ULONG64, ARRAY_SIZE );
return Equals( s.arr, size, expected, ARRAY_SIZE );
}
-extern "C" DLL_EXPORT BOOL TakeDoubleArraySeqStructByVal( S_DOUBLEArray s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeDoubleArraySeqStructByVal( S_DOUBLEArray s, int size )
{
CHECK_PARAM_NOT_EMPTY( s.arr );
INIT_EXPECTED( DOUBLE, ARRAY_SIZE );
return Equals( s.arr, size, expected, ARRAY_SIZE );
}
-extern "C" DLL_EXPORT BOOL TakeFloatArraySeqStructByVal( S_FLOATArray s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeFloatArraySeqStructByVal( S_FLOATArray s, int size )
{
CHECK_PARAM_NOT_EMPTY( s.arr );
INIT_EXPECTED( FLOAT, ARRAY_SIZE );
return Equals( s.arr, size, expected, ARRAY_SIZE );
}
-extern "C" DLL_EXPORT BOOL TakeByteArraySeqStructByVal( S_BYTEArray s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeByteArraySeqStructByVal( S_BYTEArray s, int size )
{
CHECK_PARAM_NOT_EMPTY( s.arr );
INIT_EXPECTED( BYTE, ARRAY_SIZE );
return Equals( s.arr, size, expected, ARRAY_SIZE );
}
-extern "C" DLL_EXPORT BOOL TakeCharArraySeqStructByVal( S_CHARArray s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeCharArraySeqStructByVal( S_CHARArray s, int size )
{
CHECK_PARAM_NOT_EMPTY( s.arr );
INIT_EXPECTED( CHAR, ARRAY_SIZE );
return Equals( s.arr, size, expected, ARRAY_SIZE );
}
-extern "C" DLL_EXPORT BOOL TakeIntPtrArraySeqStructByVal(S_DWORD_PTRArray s, int size)
+extern "C" DLL_EXPORT BOOL WINAPI TakeIntPtrArraySeqStructByVal(S_DWORD_PTRArray s, int size)
{
CHECK_PARAM_NOT_EMPTY(s.arr);
INIT_EXPECTED( DWORD_PTR, ARRAY_SIZE);
return Equals(s.arr, size, expected, ARRAY_SIZE);
}
-extern "C" DLL_EXPORT BOOL TakeLPSTRArraySeqStructByVal( S_LPSTRArray s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeLPSTRArraySeqStructByVal( S_LPSTRArray s, int size )
{
CHECK_PARAM_NOT_EMPTY( s.arr );
@@ -273,7 +273,7 @@ extern "C" DLL_EXPORT BOOL TakeLPSTRArraySeqStructByVal( S_LPSTRArray s, int siz
return Equals( s.arr, size, expected, ARRAY_SIZE );
}
-extern "C" DLL_EXPORT BOOL TakeLPCSTRArraySeqStructByVal( S_LPCSTRArray s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeLPCSTRArraySeqStructByVal( S_LPCSTRArray s, int size )
{
CHECK_PARAM_NOT_EMPTY( s.arr );
@@ -286,7 +286,7 @@ extern "C" DLL_EXPORT BOOL TakeLPCSTRArraySeqStructByVal( S_LPCSTRArray s, int s
-extern "C" DLL_EXPORT BOOL TakeStructArraySeqStructByVal( S_StructArray s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeStructArraySeqStructByVal( S_StructArray s, int size )
{
CHECK_PARAM_NOT_EMPTY( s.arr );
@@ -297,69 +297,69 @@ extern "C" DLL_EXPORT BOOL TakeStructArraySeqStructByVal( S_StructArray s, int s
/*----------------------------------------------------------------------------
marshal sequential class
----------------------------------------------------------------------------*/
-extern "C" DLL_EXPORT BOOL TakeIntArraySeqClassByVal( S_INTArray *s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeIntArraySeqClassByVal( S_INTArray *s, int size )
{
return TakeIntArraySeqStructByVal( *s, size );
}
-extern "C" DLL_EXPORT BOOL TakeUIntArraySeqClassByVal( S_UINTArray *s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeUIntArraySeqClassByVal( S_UINTArray *s, int size )
{
return TakeUIntArraySeqStructByVal( *s, size );
}
-extern "C" DLL_EXPORT BOOL TakeShortArraySeqClassByVal( S_SHORTArray *s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeShortArraySeqClassByVal( S_SHORTArray *s, int size )
{
return TakeShortArraySeqStructByVal( *s, size );
}
-extern "C" DLL_EXPORT BOOL TakeWordArraySeqClassByVal( S_WORDArray *s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeWordArraySeqClassByVal( S_WORDArray *s, int size )
{
return TakeWordArraySeqStructByVal( *s, size );
}
-extern "C" DLL_EXPORT BOOL TakeLong64ArraySeqClassByVal( S_LONG64Array *s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeLong64ArraySeqClassByVal( S_LONG64Array *s, int size )
{
return TakeLong64ArraySeqStructByVal( *s, size );
}
-extern "C" DLL_EXPORT BOOL TakeULong64ArraySeqClassByVal( S_ULONG64Array *s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeULong64ArraySeqClassByVal( S_ULONG64Array *s, int size )
{
return TakeULong64ArraySeqStructByVal( *s, size );
}
-extern "C" DLL_EXPORT BOOL TakeDoubleArraySeqClassByVal( S_DOUBLEArray *s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeDoubleArraySeqClassByVal( S_DOUBLEArray *s, int size )
{
return TakeDoubleArraySeqStructByVal( *s, size );
}
-extern "C" DLL_EXPORT BOOL TakeFloatArraySeqClassByVal( S_FLOATArray *s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeFloatArraySeqClassByVal( S_FLOATArray *s, int size )
{
return TakeFloatArraySeqStructByVal( *s, size );
}
-extern "C" DLL_EXPORT BOOL TakeByteArraySeqClassByVal( S_BYTEArray *s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeByteArraySeqClassByVal( S_BYTEArray *s, int size )
{
return TakeByteArraySeqStructByVal( *s, size );
}
-extern "C" DLL_EXPORT BOOL TakeCharArraySeqClassByVal( S_CHARArray *s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeCharArraySeqClassByVal( S_CHARArray *s, int size )
{
return TakeCharArraySeqStructByVal( *s, size );
}
-extern "C" DLL_EXPORT BOOL TakeLPSTRArraySeqClassByVal( S_LPSTRArray *s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeLPSTRArraySeqClassByVal( S_LPSTRArray *s, int size )
{
return TakeLPSTRArraySeqStructByVal( *s, size );
}
-extern "C" DLL_EXPORT BOOL TakeLPCSTRArraySeqClassByVal( S_LPCSTRArray *s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeLPCSTRArraySeqClassByVal( S_LPCSTRArray *s, int size )
{
return TakeLPCSTRArraySeqStructByVal( *s, size );
}
-extern "C" DLL_EXPORT BOOL TakeStructArraySeqClassByVal( S_StructArray *s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeStructArraySeqClassByVal( S_StructArray *s, int size )
{
return TakeStructArraySeqStructByVal( *s, size );
}
@@ -367,69 +367,69 @@ extern "C" DLL_EXPORT BOOL TakeStructArraySeqClassByVal( S_StructArray *s, int s
/*----------------------------------------------------------------------------
marshal explicit struct
----------------------------------------------------------------------------*/
-extern "C" DLL_EXPORT BOOL TakeIntArrayExpStructByVal( S_INTArray s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeIntArrayExpStructByVal( S_INTArray s, int size )
{
return TakeIntArraySeqStructByVal( s, size );
}
-extern "C" DLL_EXPORT BOOL TakeUIntArrayExpStructByVal( S_UINTArray s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeUIntArrayExpStructByVal( S_UINTArray s, int size )
{
return TakeUIntArraySeqStructByVal( s, size );
}
-extern "C" DLL_EXPORT BOOL TakeShortArrayExpStructByVal( S_SHORTArray s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeShortArrayExpStructByVal( S_SHORTArray s, int size )
{
return TakeShortArraySeqStructByVal( s, size );
}
-extern "C" DLL_EXPORT BOOL TakeWordArrayExpStructByVal( S_WORDArray s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeWordArrayExpStructByVal( S_WORDArray s, int size )
{
return TakeWordArraySeqStructByVal( s, size );
}
-extern "C" DLL_EXPORT BOOL TakeLong64ArrayExpStructByVal( S_LONG64Array s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeLong64ArrayExpStructByVal( S_LONG64Array s, int size )
{
return TakeLong64ArraySeqStructByVal( s, size );
}
-extern "C" DLL_EXPORT BOOL TakeULong64ArrayExpStructByVal( S_ULONG64Array s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeULong64ArrayExpStructByVal( S_ULONG64Array s, int size )
{
return TakeULong64ArraySeqStructByVal( s, size );
}
-extern "C" DLL_EXPORT BOOL TakeDoubleArrayExpStructByVal( S_DOUBLEArray s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeDoubleArrayExpStructByVal( S_DOUBLEArray s, int size )
{
return TakeDoubleArraySeqStructByVal( s, size );
}
-extern "C" DLL_EXPORT BOOL TakeFloatArrayExpStructByVal( S_FLOATArray s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeFloatArrayExpStructByVal( S_FLOATArray s, int size )
{
return TakeFloatArraySeqStructByVal( s, size );
}
-extern "C" DLL_EXPORT BOOL TakeByteArrayExpStructByVal( S_BYTEArray s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeByteArrayExpStructByVal( S_BYTEArray s, int size )
{
return TakeByteArraySeqStructByVal( s, size );
}
-extern "C" DLL_EXPORT BOOL TakeCharArrayExpStructByVal( S_CHARArray s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeCharArrayExpStructByVal( S_CHARArray s, int size )
{
return TakeCharArraySeqStructByVal( s, size );
}
-extern "C" DLL_EXPORT BOOL TakeLPSTRArrayExpStructByVal( S_LPSTRArray s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeLPSTRArrayExpStructByVal( S_LPSTRArray s, int size )
{
return TakeLPSTRArraySeqStructByVal( s, size );
}
-extern "C" DLL_EXPORT BOOL TakeLPCSTRArrayExpStructByVal( S_LPCSTRArray s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeLPCSTRArrayExpStructByVal( S_LPCSTRArray s, int size )
{
return TakeLPCSTRArraySeqStructByVal( s, size );
}
-extern "C" DLL_EXPORT BOOL TakeStructArrayExpStructByVal( S_StructArray s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeStructArrayExpStructByVal( S_StructArray s, int size )
{
return TakeStructArraySeqStructByVal( s, size );
}
@@ -437,69 +437,69 @@ extern "C" DLL_EXPORT BOOL TakeStructArrayExpStructByVal( S_StructArray s, int s
/*----------------------------------------------------------------------------
marshal explicit class
----------------------------------------------------------------------------*/
-extern "C" DLL_EXPORT BOOL TakeIntArrayExpClassByVal( S_INTArray *s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeIntArrayExpClassByVal( S_INTArray *s, int size )
{
return TakeIntArraySeqStructByVal( *s, size );
}
-extern "C" DLL_EXPORT BOOL TakeUIntArrayExpClassByVal( S_UINTArray *s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeUIntArrayExpClassByVal( S_UINTArray *s, int size )
{
return TakeUIntArraySeqStructByVal( *s, size );
}
-extern "C" DLL_EXPORT BOOL TakeShortArrayExpClassByVal( S_SHORTArray *s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeShortArrayExpClassByVal( S_SHORTArray *s, int size )
{
return TakeShortArraySeqStructByVal( *s, size );
}
-extern "C" DLL_EXPORT BOOL TakeWordArrayExpClassByVal( S_WORDArray *s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeWordArrayExpClassByVal( S_WORDArray *s, int size )
{
return TakeWordArraySeqStructByVal( *s, size );
}
-extern "C" DLL_EXPORT BOOL TakeLong64ArrayExpClassByVal( S_LONG64Array *s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeLong64ArrayExpClassByVal( S_LONG64Array *s, int size )
{
return TakeLong64ArraySeqStructByVal( *s, size );
}
-extern "C" DLL_EXPORT BOOL TakeULong64ArrayExpClassByVal( S_ULONG64Array *s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeULong64ArrayExpClassByVal( S_ULONG64Array *s, int size )
{
return TakeULong64ArraySeqStructByVal( *s, size );
}
-extern "C" DLL_EXPORT BOOL TakeDoubleArrayExpClassByVal( S_DOUBLEArray *s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeDoubleArrayExpClassByVal( S_DOUBLEArray *s, int size )
{
return TakeDoubleArraySeqStructByVal( *s, size );
}
-extern "C" DLL_EXPORT BOOL TakeFloatArrayExpClassByVal( S_FLOATArray *s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeFloatArrayExpClassByVal( S_FLOATArray *s, int size )
{
return TakeFloatArraySeqStructByVal( *s, size );
}
-extern "C" DLL_EXPORT BOOL TakeByteArrayExpClassByVal( S_BYTEArray *s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeByteArrayExpClassByVal( S_BYTEArray *s, int size )
{
return TakeByteArraySeqStructByVal( *s, size );
}
-extern "C" DLL_EXPORT BOOL TakeCharArrayExpClassByVal( S_CHARArray *s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeCharArrayExpClassByVal( S_CHARArray *s, int size )
{
return TakeCharArraySeqStructByVal( *s, size );
}
-extern "C" DLL_EXPORT BOOL TakeLPSTRArrayExpClassByVal( S_LPSTRArray *s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeLPSTRArrayExpClassByVal( S_LPSTRArray *s, int size )
{
return TakeLPSTRArraySeqStructByVal( *s, size );
}
-extern "C" DLL_EXPORT BOOL TakeLPCSTRArrayExpClassByVal( S_LPCSTRArray *s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeLPCSTRArrayExpClassByVal( S_LPCSTRArray *s, int size )
{
return TakeLPCSTRArraySeqStructByVal( *s, size );
}
-extern "C" DLL_EXPORT BOOL TakeStructArrayExpClassByVal( S_StructArray *s, int size )
+extern "C" DLL_EXPORT BOOL WINAPI TakeStructArrayExpClassByVal( S_StructArray *s, int size )
{
return TakeStructArraySeqStructByVal( *s, size );
}
@@ -507,77 +507,77 @@ extern "C" DLL_EXPORT BOOL TakeStructArrayExpClassByVal( S_StructArray *s, int s
/*----------------------------------------------------------------------------
return a struct including a C array
----------------------------------------------------------------------------*/
-extern "C" DLL_EXPORT S_INTArray* S_INTArray_Ret()
+extern "C" DLL_EXPORT S_INTArray* WINAPI S_INTArray_Ret()
{
INIT_EXPECTED_STRUCT( S_INTArray, ARRAY_SIZE, INT );
return expected;
}
-extern "C" DLL_EXPORT S_UINTArray* S_UINTArray_Ret()
+extern "C" DLL_EXPORT S_UINTArray* WINAPI S_UINTArray_Ret()
{
INIT_EXPECTED_STRUCT( S_UINTArray, ARRAY_SIZE, UINT );
return expected;
}
-extern "C" DLL_EXPORT S_SHORTArray* S_SHORTArray_Ret()
+extern "C" DLL_EXPORT S_SHORTArray* WINAPI S_SHORTArray_Ret()
{
INIT_EXPECTED_STRUCT( S_SHORTArray, ARRAY_SIZE, SHORT );
return expected;
}
-extern "C" DLL_EXPORT S_WORDArray* S_WORDArray_Ret()
+extern "C" DLL_EXPORT S_WORDArray* WINAPI S_WORDArray_Ret()
{
INIT_EXPECTED_STRUCT( S_WORDArray, ARRAY_SIZE, WORD );
return expected;
}
-extern "C" DLL_EXPORT S_LONG64Array* S_LONG64Array_Ret()
+extern "C" DLL_EXPORT S_LONG64Array* WINAPI S_LONG64Array_Ret()
{
INIT_EXPECTED_STRUCT( S_LONG64Array, ARRAY_SIZE, LONG64 );
return expected;
}
-extern "C" DLL_EXPORT S_ULONG64Array* S_ULONG64Array_Ret()
+extern "C" DLL_EXPORT S_ULONG64Array* WINAPI S_ULONG64Array_Ret()
{
INIT_EXPECTED_STRUCT( S_ULONG64Array, ARRAY_SIZE, ULONG64 );
return expected;
}
-extern "C" DLL_EXPORT S_DOUBLEArray* S_DOUBLEArray_Ret()
+extern "C" DLL_EXPORT S_DOUBLEArray* WINAPI S_DOUBLEArray_Ret()
{
INIT_EXPECTED_STRUCT( S_DOUBLEArray, ARRAY_SIZE, DOUBLE );
return expected;
}
-extern "C" DLL_EXPORT S_FLOATArray* S_FLOATArray_Ret()
+extern "C" DLL_EXPORT S_FLOATArray* WINAPI S_FLOATArray_Ret()
{
INIT_EXPECTED_STRUCT( S_FLOATArray, ARRAY_SIZE, FLOAT );
return expected;
}
-extern "C" DLL_EXPORT S_BYTEArray* S_BYTEArray_Ret()
+extern "C" DLL_EXPORT S_BYTEArray* WINAPI S_BYTEArray_Ret()
{
INIT_EXPECTED_STRUCT( S_BYTEArray, ARRAY_SIZE, BYTE );
return expected;
}
-extern "C" DLL_EXPORT S_CHARArray* S_CHARArray_Ret()
+extern "C" DLL_EXPORT S_CHARArray* WINAPI S_CHARArray_Ret()
{
INIT_EXPECTED_STRUCT( S_CHARArray, ARRAY_SIZE, CHAR );
return expected;
}
-extern "C" DLL_EXPORT S_LPSTRArray* S_LPSTRArray_Ret()
+extern "C" DLL_EXPORT S_LPSTRArray* WINAPI S_LPSTRArray_Ret()
{
S_LPSTRArray *expected = (S_LPSTRArray *)::CoTaskMemAlloc( sizeof(S_LPSTRArray) );
for ( int i = 0; i < ARRAY_SIZE; ++i )
@@ -587,7 +587,7 @@ extern "C" DLL_EXPORT S_LPSTRArray* S_LPSTRArray_Ret()
}
-extern "C" DLL_EXPORT S_StructArray* S_StructArray_Ret()
+extern "C" DLL_EXPORT S_StructArray* WINAPI S_StructArray_Ret()
{
S_StructArray *expected = (S_StructArray *)::CoTaskMemAlloc( sizeof(S_StructArray) );
for ( int i = 0; i < ARRAY_SIZE; ++i )
diff --git a/tests/src/Interop/PrimitiveMarshalling/Bool/BoolNative.cpp b/tests/src/Interop/PrimitiveMarshalling/Bool/BoolNative.cpp
index ba8c10bd77..79ab5c9a8f 100644
--- a/tests/src/Interop/PrimitiveMarshalling/Bool/BoolNative.cpp
+++ b/tests/src/Interop/PrimitiveMarshalling/Bool/BoolNative.cpp
@@ -116,8 +116,10 @@ extern "C" DLL_EXPORT BOOL __stdcall MarshalPointer_Out(/*[out]*/ BOOL *pboolVal
}
#pragma warning(push)
+#if _MSC_VER <= 1900
// 'BOOL' forcing value to bool 'true' or 'false'
#pragma warning(disable: 4800)
+#endif
extern "C" DLL_EXPORT bool __stdcall Marshal_As_In(/*[in]*/bool boolValue)
{
diff --git a/tests/src/Interop/RefCharArray/RefCharArrayNative.cpp b/tests/src/Interop/RefCharArray/RefCharArrayNative.cpp
index 09f4671858..0d0af27412 100755
--- a/tests/src/Interop/RefCharArray/RefCharArrayNative.cpp
+++ b/tests/src/Interop/RefCharArray/RefCharArrayNative.cpp
@@ -6,7 +6,7 @@
#include <stdio.h>
#include <stdlib.h>
-size_t LEN = 10;
+const int LEN = 10;
extern "C" BOOL DLL_EXPORT _cdecl MarshalRefCharArray_Cdecl(char ** pstr)
{
//Check the Input
diff --git a/tests/src/Interop/SimpleStruct/SimpleStructNative.cpp b/tests/src/Interop/SimpleStruct/SimpleStructNative.cpp
index 5fe82146b8..fb855a42e8 100644
--- a/tests/src/Interop/SimpleStruct/SimpleStructNative.cpp
+++ b/tests/src/Interop/SimpleStruct/SimpleStructNative.cpp
@@ -30,7 +30,7 @@ DLL_EXPORT BOOL _cdecl CdeclSimpleStructByRef(Sstr *p)
{
p->a = 100;
p->b=1;
- strncpy(p->str,"after",6);
+ strcpy_s(p->str, 7, "after");
return TRUE;
}
@@ -81,7 +81,7 @@ DLL_EXPORT ExplStruct* _cdecl CdeclSimpleExplStruct(ExplStruct p,BOOL *result)
}
extern "C"
-DLL_EXPORT voidPtr _cdecl GetFptr(int i)
+DLL_EXPORT voidPtr __stdcall GetFptr(int i)
{
switch(i)
{
diff --git a/tests/src/Interop/StringMarshalling/UTF8/UTF8TestNative.cpp b/tests/src/Interop/StringMarshalling/UTF8/UTF8TestNative.cpp
index f4e0f2f950..700765143c 100644
--- a/tests/src/Interop/StringMarshalling/UTF8/UTF8TestNative.cpp
+++ b/tests/src/Interop/StringMarshalling/UTF8/UTF8TestNative.cpp
@@ -6,7 +6,7 @@
const int NSTRINGS = 6;
#ifdef _WIN32
-wchar_t *utf8strings[] = { L"Managed",
+const wchar_t *utf8strings[] = { L"Managed",
L"S\x00EEne kl\x00E2wen durh die wolken sint geslagen" ,
L"\x0915\x093E\x091A\x0902 \x0936\x0915\x094D\x0928\x094B\x092E\x094D\x092F\x0924\x094D\x0924\x0941\x092E\x094D \x0964 \x0928\x094B\x092A\x0939\x093F\x0928\x0938\x094D\x0924\x093F \x092E\x093E\x092E\x094D",
L"\x6211\x80FD\x541E\x4E0B\x73BB\x7483\x800C\x4E0D\x4F24\x8EAB\x4F53",
@@ -17,7 +17,7 @@ L"\0"
-char* utf16_to_utf8(wchar_t *srcstring)
+char* utf16_to_utf8(const wchar_t *srcstring)
{
if ((srcstring == NULL) || (*srcstring == L'\0')) {
return 0;
diff --git a/tests/src/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.cpp b/tests/src/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.cpp
index fe9ceeaa40..08954434ae 100644
--- a/tests/src/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.cpp
+++ b/tests/src/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.cpp
@@ -167,22 +167,10 @@ extern "C" DLL_EXPORT BOOL WINAPI MarshalStructAsParam_AsSeqByValOut3(CharSetAns
}
extern "C" DLL_EXPORT BOOL WINAPI MarshalStructAsParam_AsSeqByRefOut3(CharSetAnsiSequential* str1)
{
- char const* strSource = "change string";
- int len = strlen(strSource);
- LPCSTR temp = (LPCSTR)TP_CoTaskMemAlloc((sizeof(char)*len)+1);
- if(temp != NULL)
- {
- TP_CoTaskMemFree((void*)(str1->f1));
- strcpy((char*)temp,strSource);
- str1->f1 = temp;
- str1->f2 = 'n';
- return TRUE;
- }
- else
- {
- printf("Memory Allocated Failed !");
- return FALSE;
- }
+ TP_CoTaskMemFree((void*)(str1->f1));
+ str1->f1 = CoStrDup("change string");
+ str1->f2 = 'n';
+ return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////////
@@ -663,7 +651,7 @@ extern "C" DLL_EXPORT BOOL WINAPI MarshalStructAsParam_AsSeqByVal14(S11 str1)
{
if( str1.i32 != 0 || str1.i != 32 )
return FALSE;
- str1.i32 = (LPINT)(long)(str1.i);
+ str1.i32 = reinterpret_cast<LPINT>(static_cast<INT_PTR>(str1.i));
str1.i = 64;
return TRUE;
}
@@ -673,7 +661,7 @@ extern "C" DLL_EXPORT BOOL WINAPI MarshalStructAsParam_AsSeqByRef14(S11* str1)
return FALSE;
else
{
- str1->i32 = (LPINT)(long)(str1->i);
+ str1->i32 = reinterpret_cast<LPINT>(static_cast<INT_PTR>(str1->i));
str1->i = 64;
return TRUE;
}
@@ -684,7 +672,7 @@ extern "C" DLL_EXPORT BOOL WINAPI MarshalStructAsParam_AsSeqByRefIn14(S11* str1)
return FALSE;
else
{
- str1->i32 = (LPINT)(long)(str1->i);
+ str1->i32 = reinterpret_cast<LPINT>(static_cast<INT_PTR>(str1->i));
str1->i = 64;
return TRUE;
}
@@ -698,7 +686,7 @@ extern "C" DLL_EXPORT BOOL WINAPI MarshalStructAsParam_AsSeqByValOut14(S11 str1)
}
extern "C" DLL_EXPORT BOOL WINAPI MarshalStructAsParam_AsSeqByRefOut14(S11* str1)
{
- str1->i32 = (LPINT)(long)(str1->i);
+ str1->i32 = reinterpret_cast<LPINT>(static_cast<INT_PTR>(str1->i));
str1->i = 64;
return TRUE;
}
@@ -817,7 +805,7 @@ extern "C" DLL_EXPORT BOOL WINAPI MarshalStructAsParam_AsExpByValInnerArrayExpli
return FALSE;
}
}
- if(memcmp((&outer2)->f4,"some string2",12) != 0)
+ if(memcmp((&outer2)->s.f4,"some string2",12) != 0)
{
printf("\tMarshalStructAsParam_AsExpByVal3:InnerArrayExplicit param f4 not as expected\n");
return FALSE;
@@ -835,7 +823,7 @@ extern "C" DLL_EXPORT BOOL WINAPI MarshalStructAsParam_AsExpByRefInnerArrayExpli
return FALSE;
}
}
- if(memcmp(outer2->f4,"some string2",12) != 0)
+ if(memcmp(outer2->s.f4,"some string2",12) != 0)
{
printf("\tMarshalStructAsParam_AsExpByRef3:InnerArrayExplicit param f4 not as expected\n");
return FALSE;
@@ -844,11 +832,8 @@ extern "C" DLL_EXPORT BOOL WINAPI MarshalStructAsParam_AsExpByRefInnerArrayExpli
{
outer2->arr[i].f1 = 77;
}
- char const * temp = "change string2";
- size_t len = strlen(temp);
- LPCSTR str = (LPCSTR)TP_CoTaskMemAlloc( sizeof(char)*(len+1) );
- strcpy((char*)str,temp);
- outer2->f4 = str;
+
+ outer2->s.f4 = CoStrDup("change string2");
return TRUE;
}
@@ -862,7 +847,7 @@ extern "C" DLL_EXPORT BOOL WINAPI MarshalStructAsParam_AsExpByRefInInnerArrayExp
return FALSE;
}
}
- if(memcmp(outer2->f4, "some string2",12*(sizeof(char))) != 0)
+ if(memcmp(outer2->s.f4, "some string2",12*(sizeof(char))) != 0)
{
printf("\tMarshalStructAsParam_AsExpByRefIn3:InnerArrayExplicit param f4 not as expected\n");
return FALSE;
@@ -871,11 +856,7 @@ extern "C" DLL_EXPORT BOOL WINAPI MarshalStructAsParam_AsExpByRefInInnerArrayExp
{
outer2->arr[i].f1 = 77;
}
- char const * temp = "change string2";
- size_t len = strlen(temp);
- LPCSTR str = (LPCSTR)TP_CoTaskMemAlloc( sizeof(char)*(len+1) );
- strcpy((char*)str,temp);
- outer2->f4 = str;
+ outer2->s.f4 = CoStrDup("change string2");
return TRUE;
}
extern "C" DLL_EXPORT BOOL WINAPI MarshalStructAsParam_AsExpByRefOutInnerArrayExplicit(InnerArrayExplicit* outer2)
@@ -884,11 +865,7 @@ extern "C" DLL_EXPORT BOOL WINAPI MarshalStructAsParam_AsExpByRefOutInnerArrayEx
{
outer2->arr[i].f1 = 77;
}
- char const * temp = "change string2";
- size_t len = strlen(temp);
- LPCSTR str = (LPCSTR)TP_CoTaskMemAlloc( sizeof(char)*(len+1) );
- strcpy((char*)str,temp);
- outer2->f4 = str;
+ outer2->s.f4 = CoStrDup("change string2");
return TRUE;
}
diff --git a/tests/src/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.h b/tests/src/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.h
index bf767271fb..22ad037a6a 100644
--- a/tests/src/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.h
+++ b/tests/src/Interop/StructMarshalling/PInvoke/MarshalStructAsParamDLL.h
@@ -1,6 +1,17 @@
#include "platformdefines.cpp"
#include <xplatform.h>
+inline char* CoStrDup(const char* str)
+{
+ size_t size = strlen(str) + 1;
+ char* dup = (char *)TP_CoTaskMemAlloc(size);
+ if (dup != nullptr)
+ {
+ strcpy_s(dup, size, str);
+ }
+ return dup;
+}
+
const int NumArrElements = 2;
struct InnerSequential
{
@@ -19,20 +30,7 @@ void ChangeInnerSequential(InnerSequential* p)
{
p->f1 = 77;
p->f2 = 77.0;
-
- char const * lpstr = "changed string";
- size_t size = sizeof(char) * (strlen(lpstr) + 1);
- LPSTR temp = (LPSTR)TP_CoTaskMemAlloc( size );
- memset(temp, 0, size);
- if(temp)
- {
- strcpy( (char*)temp, lpstr );
- p->f3 = temp;
- }
- else
- {
- printf("Memory Allocated Failed!");
- }
+ p->f3 = CoStrDup("changed string");
}
bool IsCorrectInnerSequential(InnerSequential* p)
@@ -41,13 +39,7 @@ bool IsCorrectInnerSequential(InnerSequential* p)
return false;
if(p->f2 != 1.0)
return false;
-
- char const * lpstr = "some string";
- size_t size = sizeof(char) * (strlen(lpstr) + 1);
- LPSTR temp = (LPSTR)TP_CoTaskMemAlloc( size );
- memset(temp, 0, size);
-
- if( strcmp((char*)p->f3, temp) != 0 )
+ if(strcmp(p->f3, "") != 0)
return false;
return true;
@@ -62,6 +54,7 @@ typedef unsigned short WORD;
typedef short SHORT;
typedef float FLOAT;
typedef double DOUBLE;
+typedef long INT_PTR;
#endif
struct INNER2 // size = 12 bytes
@@ -74,11 +67,7 @@ void ChangeINNER2(INNER2* p)
{
p->f1 = 77;
p->f2 = 77.0;
- char const * temp = "changed string";
- size_t len = strlen(temp);
- LPCSTR str = (LPCSTR)TP_CoTaskMemAlloc( sizeof(char)*(len+1) );
- strcpy((char*)str,temp);
- p->f3 = str;
+ p->f3 = CoStrDup("changed string");
}
void PrintINNER2(INNER2* p, char const * name)
{
@@ -132,12 +121,7 @@ void PrintInnerExplicit(InnerExplicit* p, char const * name)
void ChangeInnerExplicit(InnerExplicit* p)
{
p->f1 = 77;
-
- char const * temp = "changed string";
- size_t len = strlen(temp);
- LPCSTR str = (LPCSTR)TP_CoTaskMemAlloc( sizeof(char)*(len+1) );
- strcpy((char*)str,temp);
- p->f3 = str;
+ p->f3 = CoStrDup("changed string");
}
struct InnerArraySequential
@@ -157,25 +141,11 @@ void PrintInnerArraySequential(InnerArraySequential* p, char const * name)
void ChangeInnerArraySequential(InnerArraySequential* p)
{
- char const * lpstr = "changed string";
- LPSTR temp;
for(int i = 0; i < NumArrElements; i++)
{
(p->arr)[i].f1 = 77;
(p->arr)[i].f2 = 77.0;
-
- size_t size = sizeof(char) * (strlen(lpstr) + 1);
- temp = (LPSTR)TP_CoTaskMemAlloc( size );
- memset(temp, 0, size);
- if(temp)
- {
- strcpy( (char*)temp, lpstr );
- (p->arr)[i].f3 = temp;
- }
- else
- {
- printf("Memory Allocated Failed!");
- }
+ (p->arr)[i].f3 = CoStrDup("changed string");
}
}
@@ -199,13 +169,14 @@ union InnerArrayExplicit // size = 32 bytes
{
LONG64 _unused0;
LPCSTR f4;
- };
-
+ } s;
};
#ifdef WINDOWS
#ifdef _WIN64
+ #pragma warning(push)
+ #pragma warning(disable: 4201) // nonstandard extension used: nameless struct/union
union OUTER3 // size = 32 bytes
{
struct InnerSequential arr[2];
@@ -215,6 +186,7 @@ union InnerArrayExplicit // size = 32 bytes
LPCSTR f4;
};
};
+ #pragma warning(pop)
#else
struct OUTER3 // size = 28 bytes
{
@@ -244,22 +216,14 @@ void PrintOUTER3(OUTER3* p, char const * name)
}
void ChangeOUTER3(OUTER3* p)
{
- char const * temp = "changed string";
- size_t len = strlen(temp);
- LPCSTR str = NULL;
for(int i = 0; i < NumArrElements; i++)
{
(p->arr)[i].f1 = 77;
(p->arr)[i].f2 = 77.0;
-
- str = (LPCSTR)TP_CoTaskMemAlloc( sizeof(char)*(len+1) );
- strcpy((char*)str,temp);
- (p->arr)[i].f3 = str;
+ (p->arr)[i].f3 = CoStrDup("changed string");
}
- str = (LPCSTR)TP_CoTaskMemAlloc( sizeof(char)*(len+1) );
- strcpy((char*)str,temp);
- p->f4 = str;
+ p->f4 = CoStrDup("changed string");
}
bool IsCorrectOUTER3(OUTER3* p)
{
@@ -293,19 +257,8 @@ void PrintCharSetAnsiSequential(CharSetAnsiSequential* p, char const * name)
void ChangeCharSetAnsiSequential(CharSetAnsiSequential* p)
{
- char const * strSource = "change string";
- size_t size = strlen(strSource) + 1;
- LPSTR temp = (LPSTR)TP_CoTaskMemAlloc(size);
- if(temp != NULL)
- {
- strcpy((char*)temp,strSource);
- p->f1 = temp;
- p->f2 = 'n';
- }
- else
- {
- printf("Memory Allocated Failed!");
- }
+ p->f1 = CoStrDup("change string");
+ p->f2 = 'n';
}
bool IsCorrectCharSetAnsiSequential(CharSetAnsiSequential* p)
@@ -325,7 +278,11 @@ struct CharSetUnicodeSequential
};
void PrintCharSetUnicodeSequential(CharSetUnicodeSequential* p, char const * name)
{
+#ifdef _WIN32
+ wprintf(L"\t%S.f1 = %s\n", name, p->f1);
+#else
wprintf(L"\t%s.f1 = %S\n", name, p->f1);
+#endif
printf("\t%s.f2 = %c\n", name, p->f2);
}
@@ -336,7 +293,7 @@ void ChangeCharSetUnicodeSequential(CharSetUnicodeSequential* p)
#else
LPCWSTR strSource = u"change string";
#endif
- int len = wcslen(strSource);
+ size_t len = wcslen(strSource);
LPCWSTR temp = (LPCWSTR)TP_CoTaskMemAlloc(sizeof(WCHAR)*(len+1));
if(temp != NULL)
{
@@ -418,7 +375,7 @@ void ChangeNumberSequential(NumberSequential* p)
bool IsCorrectNumberSequential(NumberSequential* p)
{
- if(p->i32 != -0x80000000 || p->ui32 != 0xffffffff || p->s1 != -0x8000 || p->us1 != 0xffff || p->b != 0 ||
+ if(p->i32 != (-0x7fffffff - 1) || p->ui32 != 0xffffffff || p->s1 != -0x8000 || p->us1 != 0xffff || p->b != 0 ||
p->sb != 0x7f ||p->i16 != -0x8000 || p->ui16 != 0xffff || p->i64 != -1234567890 ||
p->ui64 != 1234567890 || (p->sgl) != 32.0 || p->d != 3.2)
{
@@ -448,17 +405,10 @@ void ChangeS3(S3* p)
{
p->flag = false;
- char const * strSource = "change string";
- int len = strlen(strSource);
-
- LPCSTR temp = (LPCSTR)TP_CoTaskMemAlloc((sizeof(char)*len) + 1);
- if(temp != NULL)
- {
- /*TP_CoTaskMemFree((void *)p->str);*/
- strcpy((char*)temp,strSource);
- p->str = temp;
- }
- for(int i = 1;i<257;i++)
+ /*TP_CoTaskMemFree((void *)p->str);*/
+ p->str = CoStrDup("change string");
+
+ for(int i = 1;i<257;i++)
{
p->vals[i-1] = i;
}
@@ -468,12 +418,7 @@ bool IsCorrectS3(S3* p)
{
int iflag = 0;
- char const * lpstr = "some string";
- size_t size = sizeof(char) * (strlen(lpstr) + 1);
- LPSTR temp = (LPSTR)TP_CoTaskMemAlloc( size );
- memset(temp, 0, size);
-
- if(!p->flag || strcmp((char*)p->str, temp) != 0)
+ if (!p->flag || strcmp(p->str, "") != 0)
return false;
for (int i = 0; i < 256; i++)
{
@@ -514,33 +459,16 @@ void PrintS5(S5* str, char const * name)
}
void ChangeS5(S5* str)
{
- Enum1 eInstance = e2;
- char const * strSource = "change string";
- int len = strlen(strSource);
- LPCSTR temp = (LPCSTR)TP_CoTaskMemAlloc(sizeof(char)*(len+1));
- if(temp != NULL)
- {
- strcpy((char*)temp,strSource);
- str->s4.name = temp;
- }
+ str->s4.name = CoStrDup("change string");
str->s4.age = 64;
- str->ef = eInstance;
+ str->ef = e2;
}
bool IsCorrectS5(S5* str)
{
- Enum1 eInstance = e1;
-
- char const * lpstr = "some string";
- size_t size = sizeof(char) * (strlen(lpstr) + 1);
- LPSTR temp = (LPSTR)TP_CoTaskMemAlloc( size );
- memset(temp, 0, size);
-
- if(str->s4.age != 32 || strcmp((char*)str->s4.name, temp) != 0)
+ if(str->s4.age != 32 || strcmp(str->s4.name, "") != 0)
return false;
- if(str->ef != eInstance)
- {
+ if(str->ef != e1)
return false;
- }
return true;
}
@@ -599,8 +527,13 @@ struct StringStructSequentialUnicode // size = 8 bytes
void PrintStringStructSequentialUnicode(StringStructSequentialUnicode* str, char const * name)
{
+#ifdef _WIN32
+ wprintf(L"\t%S.first = %s\n", name, str->first);
+ wprintf(L"\t%S.last = %s\n", name, str->last);
+#else
wprintf(L"\t%s.first = %s\n", name, str->first);
wprintf(L"\t%s.last = %s\n", name, str->last);
+#endif
}
bool IsCorrectStringStructSequentialUnicode(StringStructSequentialUnicode* str)
@@ -674,19 +607,7 @@ bool IsCorrectS8(S8* str)
void ChangeS8(S8* str)
{
- char const * lpstr = "world";
- size_t size = sizeof(char) * (strlen(lpstr) + 1);
- LPSTR temp = (LPSTR)TP_CoTaskMemAlloc( size );
- memset(temp, 0, size);
- if(temp)
- {
- strcpy( (char*)temp, lpstr );
- str->name = temp;
- }
- else
- {
- printf("Memory Allocated Failed!");
- }
+ str->name = CoStrDup("world");
str->gender = false;
str->jobNum = 1;
str->i32 = 256;
@@ -787,7 +708,7 @@ void ChangeU(U* p)
p->uiPtr = (LPVOID)(64);
p->s = 32767;
p->us = 0;
- p->b = -1;
+ p->b = 255;
p->sb = -128;
p->l = -1234567890;
p->ul = 0;
diff --git a/tests/src/Interop/common/types.h b/tests/src/Interop/common/types.h
index 7d7f7768a6..cb59c42e9d 100755
--- a/tests/src/Interop/common/types.h
+++ b/tests/src/Interop/common/types.h
@@ -28,7 +28,7 @@ typedef void* HMODULE;
typedef void* ULONG_PTR;
typedef unsigned error_t;
typedef void* LPVOID;
-typedef char BYTE;
+typedef unsigned char BYTE;
typedef WCHAR OLECHAR;
typedef unsigned int UINT_PTR;
@@ -54,4 +54,4 @@ typedef int* DWORD_PTR;
#define FALSE 0
#endif
-#endif //_INTEROP_TYPES__H \ No newline at end of file
+#endif //_INTEROP_TYPES__H
diff --git a/tests/src/JIT/CodeGenBringUpTests/Rotate.cs b/tests/src/JIT/CodeGenBringUpTests/Rotate.cs
index 74a936ef13..9c5d9599a6 100644
--- a/tests/src/JIT/CodeGenBringUpTests/Rotate.cs
+++ b/tests/src/JIT/CodeGenBringUpTests/Rotate.cs
@@ -102,12 +102,38 @@ public class Test
[MethodImpl(MethodImplOptions.NoInlining)]
static ulong rol64const()
{
- ulong value = flag() ? (ulong)0x123456789abcdef : (ulong)0x123456789abcdef;
+ ulong value = flag() ? (ulong)0x123456789abcdef : (ulong)0xabcdef123456789;
int amount = 16;
return (value >> (64 - amount)) | (value << amount);
}
[MethodImpl(MethodImplOptions.NoInlining)]
+ static ulong rol64_16(ulong value)
+ {
+ return (value >> (64 - 16)) | (value << 16);
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static ulong rol64_32(ulong value)
+ {
+ return (value >> (64 - 32)) | (value << 32);
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static ulong rol64_32_inplace(ulong value, ulong added)
+ {
+ ulong x = value + added;
+ x = (x >> (64 - 32)) | (x << 32);
+ return x;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static ulong rol64_33(ulong value)
+ {
+ return (value >> (64 - 33)) | (value << 33);
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
ulong rol64field(int amount)
{
return (field << amount) | (field >> (64 - amount));
@@ -128,12 +154,38 @@ public class Test
[MethodImpl(MethodImplOptions.NoInlining)]
static ulong ror64const()
{
- ulong value = flag() ? (ulong)0x123456789abcdef : (ulong)0x123456789abcdef;
+ ulong value = flag() ? (ulong)0x123456789abcdef : (ulong)0xabcdef123456789;
int amount = flag() ? 5 : 5;
return (value << (64 - amount)) | (value >> amount);
}
[MethodImpl(MethodImplOptions.NoInlining)]
+ static ulong ror64_5(ulong value)
+ {
+ return (value << (64 - 5)) | (value >> 5);
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static ulong ror64_32(ulong value)
+ {
+ return (value << (64 - 32)) | (value >> 32);
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static ulong ror64_33(ulong value)
+ {
+ return (value << (64 - 33)) | (value >> 33);
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static ulong ror64_32_inplace(ulong value, ulong added)
+ {
+ ulong x = value + added;
+ x = (x << (64 - 32)) | (x >> 32);
+ return x;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
static ulong ror64sfield(int amount)
{
return (s_field << (64 - amount)) | (s_field >> amount);
@@ -244,6 +296,26 @@ public class Test
return Fail;
}
+ if (rol64_16(0x123456789abcdef) != 0x456789abcdef0123)
+ {
+ return Fail;
+ }
+
+ if (rol64_32(0x123456789abcdef) != rol64(0x123456789abcdef, 32))
+ {
+ return Fail;
+ }
+
+ if (rol64_33(0x123456789abcdef) != rol64(0x123456789abcdef, 33))
+ {
+ return Fail;
+ }
+
+ if (rol64_32_inplace(0x123456789abcdef, 0) != rol64(0x123456789abcdef, 32))
+ {
+ return Fail;
+ }
+
if (ror64(0x123456789abcdef, 0) != 0x123456789abcdef)
{
return Fail;
@@ -259,6 +331,26 @@ public class Test
return Fail;
}
+ if (ror64_5(0x123456789abcdef) != 0x78091a2b3c4d5e6f)
+ {
+ return Fail;
+ }
+
+ if (ror64_32(0x123456789abcdef) != ror64(0x123456789abcdef, 32))
+ {
+ return Fail;
+ }
+
+ if (ror64_33(0x123456789abcdef) != ror64(0x123456789abcdef, 33))
+ {
+ return Fail;
+ }
+
+ if (ror64_32_inplace(0x123456789abcdef, 0) != ror64(0x123456789abcdef, 32))
+ {
+ return Fail;
+ }
+
if (rol32_call(0x12345678, 16) != 0x56781234)
{
return Fail;
diff --git a/tests/src/JIT/CodeGenBringUpTests/Shift.cs b/tests/src/JIT/CodeGenBringUpTests/Shift.cs
new file mode 100644
index 0000000000..085ad3f31f
--- /dev/null
+++ b/tests/src/JIT/CodeGenBringUpTests/Shift.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;
+using System.Runtime.CompilerServices;
+
+public class Test
+{
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static ulong shl64(ulong shift, int count)
+ {
+ return shift << count;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static ulong shl64_32_inplace(ulong shift, ulong addit)
+ {
+ ulong x = shift + addit;
+ x = x << 32;
+ return x;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static ulong shl64_33_inplace(ulong shift, ulong addit)
+ {
+ ulong x = shift + addit;
+ x = x << 33;
+ return x;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static ulong shr64(ulong shift, int count)
+ {
+ return shift >> count;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static ulong shr64_32_inplace(ulong shift, ulong addit)
+ {
+ ulong x = shift + addit;
+ x = x >> 32;
+ return x;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static ulong shr1_32_add(ulong shift, ulong addit)
+ {
+ ulong x = (addit + (shift >> 1)) >> 31;
+ return x;
+ }
+
+ public static int Main()
+ {
+ const int Pass = 100;
+ const int Fail = -1;
+
+ if (shl64_32_inplace(0x123456789abcdef, 0) != shl64(0x123456789abcdef, 32))
+ {
+ Console.WriteLine("shl64_32");
+ return Fail;
+ }
+
+ if (shl64_33_inplace(0x123456789abcdef, 0) != shl64(0x123456789abcdef, 33))
+ {
+ Console.WriteLine("shl64_33");
+ return Fail;
+ }
+
+ if (shr64_32_inplace(0x123456789abcdef, 0) != shr64(0x123456789abcdef, 32))
+ {
+ Console.WriteLine("shr64_32 {0:X} {1:X}", shr64_32_inplace(0x123456789abcdef, 0), shr64(0x123456789abcdef, 32));
+ return Fail;
+ }
+
+ if (shr1_32_add(0x123456789abcdef, 0) != shr64(0x123456789abcdef, 32))
+ {
+ Console.WriteLine("HAHAHAHAHAHAHA {0:X}", shr1_32_add(0x123456789abcdef, 0));
+ return Fail;
+ }
+
+ return Pass;
+ }
+}
diff --git a/tests/src/JIT/CodeGenBringUpTests/Shift.csproj b/tests/src/JIT/CodeGenBringUpTests/Shift.csproj
new file mode 100644
index 0000000000..2189ed3dd5
--- /dev/null
+++ b/tests/src/JIT/CodeGenBringUpTests/Shift.csproj
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{AF7F2478-9B49-4776-BEAF-0BF8916E2D79}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Shift.cs" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)threading+thread\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)threading+thread\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Directed/pinvoke/pinvoke-examples.cs b/tests/src/JIT/Directed/pinvoke/pinvoke-examples.cs
new file mode 100644
index 0000000000..26080d8d71
--- /dev/null
+++ b/tests/src/JIT/Directed/pinvoke/pinvoke-examples.cs
@@ -0,0 +1,223 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+// Test cases showing interaction of inlining and inline pinvoke,
+// along with the impact of EH.
+
+using System;
+using System.Runtime.CompilerServices;
+
+
+namespace PInvokeTest
+{
+ internal class Test
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ static int AsForceInline()
+ {
+ return Environment.ProcessorCount;
+ }
+
+ static int AsNormalInline()
+ {
+ return Environment.ProcessorCount;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static int AsNoInline()
+ {
+ return Environment.ProcessorCount;
+ }
+
+ static bool FromTryCatch()
+ {
+ bool result = false;
+ try
+ {
+ // All pinvokes should be inline, except on x64
+ result = (Environment.ProcessorCount == AsNormalInline());
+ }
+ catch (Exception)
+ {
+ result = false;
+ }
+ return result;
+ }
+
+ static bool FromTryFinally()
+ {
+ bool result = false;
+ bool result1 = false;
+ bool result2 = false;
+ try
+ {
+ // All pinvokes should be inline, except on x64
+ result1 = (Environment.ProcessorCount == AsNormalInline());
+ result2 = (Environment.ProcessorCount == AsNormalInline());
+ }
+ finally
+ {
+ result = result1 && result2;
+ }
+ return result;
+ }
+
+ static bool FromTryFinally2()
+ {
+ bool result = false;
+ bool result1 = false;
+ bool result2 = false;
+
+ try
+ {
+ // These two pinvokes should be inline, except on x64
+ result1 = (Environment.ProcessorCount == AsNormalInline());
+ }
+ finally
+ {
+ // These two pinvokes should *not* be inline (finally)
+ result2 = (Environment.ProcessorCount == AsNormalInline());
+ result = result1 && result2;
+ }
+
+ return result;
+ }
+
+ static bool FromTryFinally3()
+ {
+ bool result = false;
+ bool result1 = false;
+ bool result2 = false;
+
+ try
+ {
+ // These two pinvokes should be inline, except on x64
+ result1 = (Environment.ProcessorCount == AsNormalInline());
+ }
+ finally
+ {
+ try
+ {
+ // These two pinvokes should *not* be inline (finally)
+ result2 = (Environment.ProcessorCount == AsNormalInline());
+ }
+ catch (Exception)
+ {
+ result2 = false;
+ }
+
+ result = result1 && result2;
+ }
+
+ return result;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static bool FromInline()
+ {
+ // These two pinvokes should be inline
+ bool result = (Environment.ProcessorCount == AsForceInline());
+ return result;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static bool FromInline2()
+ {
+ // These four pinvokes should be inline
+ bool result1 = (Environment.ProcessorCount == AsNormalInline());
+ bool result2 = (Environment.ProcessorCount == AsForceInline());
+ return result1 && result2;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static bool FromNoInline()
+ {
+ // The only pinvoke should be inline
+ bool result = (Environment.ProcessorCount == AsNoInline());
+ return result;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static bool FromNoInline2()
+ {
+ // Three pinvokes should be inline
+ bool result1 = (Environment.ProcessorCount == AsNormalInline());
+ bool result2 = (Environment.ProcessorCount == AsNoInline());
+ return result1 && result2;
+ }
+
+ static bool FromFilter()
+ {
+ bool result = false;
+
+ try
+ {
+ throw new Exception("expected");
+ }
+ // These two pinvokes should *not* be inline (filter)
+ //
+ // For the first call the jit won't inline the wrapper, so
+ // it just calls get_ProcessorCount.
+ //
+ // For the second call, the force inline works, and the
+ // subsequent inline of get_ProcessorCount exposes a call
+ // to the pinvoke GetProcessorCount. This pinvoke will
+ // not be inline.
+ catch (Exception) when (Environment.ProcessorCount == AsForceInline())
+ {
+ result = true;
+ }
+
+ return result;
+ }
+
+ static bool FromColdCode()
+ {
+ int pc = 0;
+ bool result1 = false;
+ bool result2 = false;
+
+ try
+ {
+ // This pinvoke should not be inline (cold)
+ pc = Environment.ProcessorCount;
+ throw new Exception("expected");
+ }
+ catch (Exception)
+ {
+ // These two pinvokes should not be inline (catch)
+ //
+ // For the first call the jit won't inline the
+ // wrapper, so it just calls get_ProcessorCount.
+ //
+ // For the second call, the force inline works, and
+ // the subsequent inline of get_ProcessorCount exposes
+ // a call to the pinvoke GetProcessorCount. This
+ // pinvoke will not be inline.
+ result1 = (pc == Environment.ProcessorCount);
+ result2 = (pc == AsForceInline());
+ }
+
+ return result1 && result2;
+ }
+
+ private static int Main()
+ {
+ bool result = true;
+
+ result &= FromTryCatch();
+ result &= FromTryFinally();
+ result &= FromTryFinally2();
+ result &= FromTryFinally3();
+ result &= FromInline();
+ result &= FromInline2();
+ result &= FromNoInline();
+ result &= FromNoInline2();
+ result &= FromFilter();
+ result &= FromColdCode();
+
+ return (result ? 100 : -1);
+ }
+ }
+}
diff --git a/tests/src/JIT/Directed/pinvoke/pinvoke-examples.csproj b/tests/src/JIT/Directed/pinvoke/pinvoke-examples.csproj
new file mode 100644
index 0000000000..78cf4471fe
--- /dev/null
+++ b/tests/src/JIT/Directed/pinvoke/pinvoke-examples.csproj
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>PdbOnly</DebugType>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="pinvoke-examples.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)minimal\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)minimal\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project> \ No newline at end of file
diff --git a/tests/src/JIT/Methodical/fp/exgen/10w5d_cs_d.csproj b/tests/src/JIT/Methodical/fp/exgen/10w5d_cs_d.csproj
index fed9ead2ac..a4054021e7 100644
--- a/tests/src/JIT/Methodical/fp/exgen/10w5d_cs_d.csproj
+++ b/tests/src/JIT/Methodical/fp/exgen/10w5d_cs_d.csproj
@@ -14,6 +14,9 @@
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+
+ <!-- NOTE: this test simply takes too long to complete under GC stress; it is not fundamentally incompatible -->
+ <GCStressIncompatible Condition="'$(Platform)' == 'x86'">true</GCStressIncompatible>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
@@ -43,4 +46,4 @@
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
</PropertyGroup>
-</Project> \ No newline at end of file
+</Project>
diff --git a/tests/src/JIT/Methodical/fp/exgen/10w5d_cs_r.csproj b/tests/src/JIT/Methodical/fp/exgen/10w5d_cs_r.csproj
index 7d311bfb47..bd5ae97d4b 100644
--- a/tests/src/JIT/Methodical/fp/exgen/10w5d_cs_r.csproj
+++ b/tests/src/JIT/Methodical/fp/exgen/10w5d_cs_r.csproj
@@ -14,6 +14,9 @@
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+
+ <!-- NOTE: this test simply takes too long to complete under GC stress; it is not fundamentally incompatible -->
+ <GCStressIncompatible Condition="'$(Platform)' == 'x86'">true</GCStressIncompatible>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
@@ -43,4 +46,4 @@
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
</PropertyGroup>
-</Project> \ No newline at end of file
+</Project>
diff --git a/tests/src/JIT/Methodical/structs/systemvbringup/structpinvoketests.cs b/tests/src/JIT/Methodical/structs/systemvbringup/structpinvoketests.cs
index 7fc52039e5..8eae60686f 100644
--- a/tests/src/JIT/Methodical/structs/systemvbringup/structpinvoketests.cs
+++ b/tests/src/JIT/Methodical/structs/systemvbringup/structpinvoketests.cs
@@ -364,650 +364,698 @@ namespace structinreg
s1.y = 2;
s1.z = 3;
s1.w = 4;
-
- InvokeCallback1((par) => {
- Console.WriteLine("S1: {0}, {1}, {2}, {3}", par.x, par.y, par.z, par.w);
- if (par.x != 1 || par.y != 2 || par.z != 3 || par.w != 4)
- {
- throw new System.Exception();
- }
- }, s1);
- S2 s2;
- s2.x = 1;
- s2.y = 2;
- s2.z = 3;
- InvokeCallback2((par) => {
- Console.WriteLine("S2: {0}, {1}, {2}", par.x, par.y, par.z);
- if (par.x != 1 || par.y != 2 || par.z != 3)
+ try
+ {
+ InvokeCallback1((par) =>
{
- throw new System.Exception();
- }
- }, s2);
-
- S3 s3;
- s3.x = 1;
- s3.y = 2;
- s3.z = 3;
- InvokeCallback3((par) => {
- Console.WriteLine("S3: {0}, {1}, {2}", par.x, par.y, par.z);
- if (par.x != 1 || par.y != 2 || par.z != 3)
+ Console.WriteLine("S1: {0}, {1}, {2}, {3}", par.x, par.y, par.z, par.w);
+ if (par.x != 1 || par.y != 2 || par.z != 3 || par.w != 4)
+ {
+ throw new System.Exception();
+ }
+ }, s1);
+
+ S2 s2;
+ s2.x = 1;
+ s2.y = 2;
+ s2.z = 3;
+ InvokeCallback2((par) =>
{
- throw new System.Exception();
- }
- }, s3);
-
- S4 s4;
- s4.x = 1;
- s4.y = 2;
- InvokeCallback4((par) => {
- Console.WriteLine("S4: {0}, {1}", par.x, par.y);
- if (par.x != 1 || par.y != 2)
+ Console.WriteLine("S2: {0}, {1}, {2}", par.x, par.y, par.z);
+ if (par.x != 1 || par.y != 2 || par.z != 3)
+ {
+ throw new System.Exception();
+ }
+ }, s2);
+
+ S3 s3;
+ s3.x = 1;
+ s3.y = 2;
+ s3.z = 3;
+ InvokeCallback3((par) =>
{
- throw new System.Exception();
- }
- }, s4);
-
- S5 s5;
- s5.x = 1;
- s5.y = 2;
- InvokeCallback5((par) => {
- Console.WriteLine("S5: {0}, {1}", par.x, par.y);
- if (par.x != 1 || par.y != 2)
+ Console.WriteLine("S3: {0}, {1}, {2}", par.x, par.y, par.z);
+ if (par.x != 1 || par.y != 2 || par.z != 3)
+ {
+ throw new System.Exception();
+ }
+ }, s3);
+
+ S4 s4;
+ s4.x = 1;
+ s4.y = 2;
+ InvokeCallback4((par) =>
{
- throw new System.Exception();
- }
- }, s5);
-
- S6 s6;
- s6.x = 1;
- s6.y = 2;
- s6.z = 3;
- s6.w = 4;
- InvokeCallback6((par) => {
- Console.WriteLine("S6: {0}, {1}, {2}, {3}", par.x, par.y, par.z, par.w);
- if (par.x != 1 || par.y != 2 || par.z != 3 || par.w != 4)
+ Console.WriteLine("S4: {0}, {1}", par.x, par.y);
+ if (par.x != 1 || par.y != 2)
+ {
+ throw new System.Exception();
+ }
+ }, s4);
+
+ S5 s5;
+ s5.x = 1;
+ s5.y = 2;
+ InvokeCallback5((par) =>
{
- throw new System.Exception();
- }
- }, s6);
-
- S7 s7;
- s7.x = 1;
- s7.y = 2;
- s7.z = 3;
- InvokeCallback7((par) => {
- Console.WriteLine("S7: {0}, {1}, {2}", par.x, par.y, par.z);
- if (par.x != 1 || par.y != 2 || par.z != 3)
+ Console.WriteLine("S5: {0}, {1}", par.x, par.y);
+ if (par.x != 1 || par.y != 2)
+ {
+ throw new System.Exception();
+ }
+ }, s5);
+
+ S6 s6;
+ s6.x = 1;
+ s6.y = 2;
+ s6.z = 3;
+ s6.w = 4;
+ InvokeCallback6((par) =>
{
- throw new System.Exception();
- }
- }, s7);
-
- S8 s8;
- s8.x = 1;
- s8.y = 2;
- InvokeCallback8((par) => {
- Console.WriteLine("S8: {0}, {1}", par.x, par.y);
- if (par.x != 1 || par.y != 2)
+ Console.WriteLine("S6: {0}, {1}, {2}, {3}", par.x, par.y, par.z, par.w);
+ if (par.x != 1 || par.y != 2 || par.z != 3 || par.w != 4)
+ {
+ throw new System.Exception();
+ }
+ }, s6);
+
+ S7 s7;
+ s7.x = 1;
+ s7.y = 2;
+ s7.z = 3;
+ InvokeCallback7((par) =>
{
- throw new System.Exception();
- }
- }, s8);
-
- S9 s9;
- s9.x = 1;
- s9.y = 2;
- s9.z = 3;
- s9.w = 4;
- InvokeCallback9((par) => {
- Console.WriteLine("S9: {0}, {1}, {2}, {3}", par.x, par.y, par.z, par.w);
- if (par.x != 1 || par.y != 2 || par.z != 3 || par.w != 4)
+ Console.WriteLine("S7: {0}, {1}, {2}", par.x, par.y, par.z);
+ if (par.x != 1 || par.y != 2 || par.z != 3)
+ {
+ throw new System.Exception();
+ }
+ }, s7);
+
+ S8 s8;
+ s8.x = 1;
+ s8.y = 2;
+ InvokeCallback8((par) =>
{
- throw new System.Exception();
- }
- }, s9);
-
- S10 s10;
- s10.a = 1;
- s10.b = 2;
- s10.c = 3;
- s10.d = 4;
- s10.e = 5;
- s10.f = 6;
- s10.g = 7;
- s10.h = 8;
- InvokeCallback10((par) => {
- Console.WriteLine("S10: {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}", par.a, par.b, par.c, par.d, par.e, par.f, par.g, par.h);
- if (par.a != 1 || par.b != 2 || par.c != 3 || par.d != 4 ||
- par.e != 5 || par.f != 6 || par.g != 7 || par.h != 8)
+ Console.WriteLine("S8: {0}, {1}", par.x, par.y);
+ if (par.x != 1 || par.y != 2)
+ {
+ throw new System.Exception();
+ }
+ }, s8);
+
+ S9 s9;
+ s9.x = 1;
+ s9.y = 2;
+ s9.z = 3;
+ s9.w = 4;
+ InvokeCallback9((par) =>
{
- throw new System.Exception();
- }
- }, s10);
-
- S11 s11;
- s11.a = 1;
- s11.b = 2;
- s11.c = 3;
- s11.d = 4;
- s11.e = 5;
- InvokeCallback11((par) => {
- Console.WriteLine("S11: {0}, {1}, {2}, {3}, {4}", par.a, par.b, par.c, par.d, par.e);
- if (par.a != 1 || par.b != 2 || par.c != 3 || par.d != 4 || par.e != 5)
+ Console.WriteLine("S9: {0}, {1}, {2}, {3}", par.x, par.y, par.z, par.w);
+ if (par.x != 1 || par.y != 2 || par.z != 3 || par.w != 4)
+ {
+ throw new System.Exception();
+ }
+ }, s9);
+
+ S10 s10;
+ s10.a = 1;
+ s10.b = 2;
+ s10.c = 3;
+ s10.d = 4;
+ s10.e = 5;
+ s10.f = 6;
+ s10.g = 7;
+ s10.h = 8;
+ InvokeCallback10((par) =>
{
- throw new System.Exception();
- }
- }, s11);
-
- S12 s12;
- s12.a = 1;
- s12.b = 2;
- s12.c = 3;
- s12.d = 4;
- s12.e = 5;
- s12.f = 6;
- s12.g = 7;
- s12.h = 8;
- s12.i = 9;
- InvokeCallback12((par) => {
- Console.WriteLine("S12: {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}", par.a, par.b, par.c, par.d, par.e, par.f, par.g, par.h, par.i);
- if (par.a != 1 || par.b != 2 || par.c != 3 || par.d != 4 ||
- par.e != 5 || par.f != 6 || par.g != 7 || par.h != 8 || par.i != 9)
+ Console.WriteLine("S10: {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}", par.a, par.b, par.c, par.d, par.e, par.f, par.g, par.h);
+ if (par.a != 1 || par.b != 2 || par.c != 3 || par.d != 4 ||
+ par.e != 5 || par.f != 6 || par.g != 7 || par.h != 8)
+ {
+ throw new System.Exception();
+ }
+ }, s10);
+
+ S11 s11;
+ s11.a = 1;
+ s11.b = 2;
+ s11.c = 3;
+ s11.d = 4;
+ s11.e = 5;
+ InvokeCallback11((par) =>
{
- throw new System.Exception();
- }
- }, s12);
-
- S13 s13;
- s13.hasValue = 1;
- s13.x = 2;
- InvokeCallback13((par) => {
- Console.WriteLine("S13: {0}, {1}", par.hasValue, par.x);
- if (par.hasValue != 1 || par.x != 2)
+ Console.WriteLine("S11: {0}, {1}, {2}, {3}, {4}", par.a, par.b, par.c, par.d, par.e);
+ if (par.a != 1 || par.b != 2 || par.c != 3 || par.d != 4 || par.e != 5)
+ {
+ throw new System.Exception();
+ }
+ }, s11);
+
+ S12 s12;
+ s12.a = 1;
+ s12.b = 2;
+ s12.c = 3;
+ s12.d = 4;
+ s12.e = 5;
+ s12.f = 6;
+ s12.g = 7;
+ s12.h = 8;
+ s12.i = 9;
+ InvokeCallback12((par) =>
{
- throw new System.Exception();
- }
- }, s13);
-
- S14 s14;
- s14.x = 1;
- s14.y = 2;
- InvokeCallback14((par) => {
- Console.WriteLine("S14: {0}, {1}", par.x, par.y);
- if (par.x != 1 || par.y != 2)
+ Console.WriteLine("S12: {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}", par.a, par.b, par.c, par.d, par.e, par.f, par.g, par.h, par.i);
+ if (par.a != 1 || par.b != 2 || par.c != 3 || par.d != 4 ||
+ par.e != 5 || par.f != 6 || par.g != 7 || par.h != 8 || par.i != 9)
+ {
+ throw new System.Exception();
+ }
+ }, s12);
+
+ S13 s13;
+ s13.hasValue = 1;
+ s13.x = 2;
+ InvokeCallback13((par) =>
{
- throw new System.Exception();
- }
- }, s14);
-
- S15 s15;
- s15.a = 1;
- s15.b = 2;
- s15.c = 3;
- s15.d = 4;
- s15.e = 5;
- s15.f = 6;
- s15.g = 7;
- s15.h = 8;
- s15.i = 9;
- InvokeCallback15((par) => {
- Console.WriteLine("S15: {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}", par.a, par.b, par.c, par.d, par.e, par.f, par.g, par.h, par.i);
- if (par.a != 1 || par.b != 2 || par.c != 3 || par.d != 4 ||
- par.e != 5 || par.f != 6 || par.g != 7 || par.h != 8 || par.i != 9)
+ Console.WriteLine("S13: {0}, {1}", par.hasValue, par.x);
+ if (par.hasValue != 1 || par.x != 2)
+ {
+ throw new System.Exception();
+ }
+ }, s13);
+
+ S14 s14;
+ s14.x = 1;
+ s14.y = 2;
+ InvokeCallback14((par) =>
{
- throw new System.Exception();
- }
- }, s15);
-
- S16 s16;
- s16.x = 1;
- s16.y = 2;
- InvokeCallback16((par) => {
- Console.WriteLine("S16: {0}, {1}", par.x, par.y);
- if (par.x != 1 || par.y != 2)
+ Console.WriteLine("S14: {0}, {1}", par.x, par.y);
+ if (par.x != 1 || par.y != 2)
+ {
+ throw new System.Exception();
+ }
+ }, s14);
+
+ S15 s15;
+ s15.a = 1;
+ s15.b = 2;
+ s15.c = 3;
+ s15.d = 4;
+ s15.e = 5;
+ s15.f = 6;
+ s15.g = 7;
+ s15.h = 8;
+ s15.i = 9;
+ InvokeCallback15((par) =>
{
- throw new System.Exception();
- }
- }, s16);
-
- S17 s17;
- s17.x = 1;
- s17.y = 2;
- InvokeCallback17((par) => {
- Console.WriteLine("S17: {0}, {1}", par.x, par.y);
- if (par.x != 1 || par.y != 2)
+ Console.WriteLine("S15: {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}", par.a, par.b, par.c, par.d, par.e, par.f, par.g, par.h, par.i);
+ if (par.a != 1 || par.b != 2 || par.c != 3 || par.d != 4 ||
+ par.e != 5 || par.f != 6 || par.g != 7 || par.h != 8 || par.i != 9)
+ {
+ throw new System.Exception();
+ }
+ }, s15);
+
+ S16 s16;
+ s16.x = 1;
+ s16.y = 2;
+ InvokeCallback16((par) =>
{
- throw new System.Exception();
- }
- }, s17);
-
- S18 s18;
- s18.x = 1;
- s18.y = 2;
- s18.z = 3;
- InvokeCallback18((par) => {
- Console.WriteLine("S18: {0}, {1}, {2}", par.x, par.y, par.z);
- if (par.x != 1 || par.y != 2 || par.z != 3)
+ Console.WriteLine("S16: {0}, {1}", par.x, par.y);
+ if (par.x != 1 || par.y != 2)
+ {
+ throw new System.Exception();
+ }
+ }, s16);
+
+ S17 s17;
+ s17.x = 1;
+ s17.y = 2;
+ InvokeCallback17((par) =>
{
- throw new System.Exception();
- }
- }, s18);
-
- S19 s19;
- s19.x = 1;
- s19.y = 2;
- s19.z = 3;
- s19.w = 4;
- InvokeCallback19((par) => {
- Console.WriteLine("S19: {0}, {1}, {2}, {3}", par.x, par.y, par.z, par.w);
- if (par.x != 1 || par.y != 2 || par.z != 3 || par.w != 4)
+ Console.WriteLine("S17: {0}, {1}", par.x, par.y);
+ if (par.x != 1 || par.y != 2)
+ {
+ throw new System.Exception();
+ }
+ }, s17);
+
+ S18 s18;
+ s18.x = 1;
+ s18.y = 2;
+ s18.z = 3;
+ InvokeCallback18((par) =>
{
- throw new System.Exception();
- }
- }, s19);
-
- S20 s20;
- s20.x = 1;
- s20.y = 2;
- s20.z = 3;
- s20.w = 4;
- InvokeCallback20((par) => {
- Console.WriteLine("S20: {0}, {1}, {2}, {3}", par.x, par.y, par.z, par.w);
- if (par.x != 1 || par.y != 2 || par.z != 3 || par.w != 4)
+ Console.WriteLine("S18: {0}, {1}, {2}", par.x, par.y, par.z);
+ if (par.x != 1 || par.y != 2 || par.z != 3)
+ {
+ throw new System.Exception();
+ }
+ }, s18);
+
+ S19 s19;
+ s19.x = 1;
+ s19.y = 2;
+ s19.z = 3;
+ s19.w = 4;
+ InvokeCallback19((par) =>
{
- throw new System.Exception();
- }
- }, s20);
-
-/* These tests are not working on non Windows CoreCLR. Enable this when GH Issue #2076 is resolved.
- TestClass testClass = new TestClass();
- S28 s28;
- s28.x = null;
- s28.y = 1;
-
- InvokeCallback28((par) => {
- Console.WriteLine("S28: {0}, {1}", par.x == null ? "Null" : "Not null", par.y);
- if (par.x != null || par.y != 1)
+ Console.WriteLine("S19: {0}, {1}, {2}, {3}", par.x, par.y, par.z, par.w);
+ if (par.x != 1 || par.y != 2 || par.z != 3 || par.w != 4)
+ {
+ throw new System.Exception();
+ }
+ }, s19);
+
+ S20 s20;
+ s20.x = 1;
+ s20.y = 2;
+ s20.z = 3;
+ s20.w = 4;
+ InvokeCallback20((par) =>
{
- throw new System.Exception();
- }
- }, s28);
-
- s28.x = testClass;
- s28.y = 5;
-
- InvokeCallback28((par) => {
- Console.WriteLine("S28: {0}, {1}", par.x == null ? "Null" : "Not null", par.y);
- if (par.x != testClass || par.y != 5)
+ Console.WriteLine("S20: {0}, {1}, {2}, {3}", par.x, par.y, par.z, par.w);
+ if (par.x != 1 || par.y != 2 || par.z != 3 || par.w != 4)
+ {
+ throw new System.Exception();
+ }
+ }, s20);
+
+ /* These tests are not working on non Windows CoreCLR. Enable this when GH Issue #2076 is resolved.
+ TestClass testClass = new TestClass();
+ S28 s28;
+ s28.x = null;
+ s28.y = 1;
+
+ InvokeCallback28((par) => {
+ Console.WriteLine("S28: {0}, {1}", par.x == null ? "Null" : "Not null", par.y);
+ if (par.x != null || par.y != 1)
+ {
+ throw new System.Exception();
+ }
+ }, s28);
+
+ s28.x = testClass;
+ s28.y = 5;
+
+ InvokeCallback28((par) => {
+ Console.WriteLine("S28: {0}, {1}", par.x == null ? "Null" : "Not null", par.y);
+ if (par.x != testClass || par.y != 5)
+ {
+ throw new System.Exception();
+ }
+ }, s28);
+
+ S29 s29;
+ s29.x = 1;
+ s29.y = null;
+
+ InvokeCallback29((par) => {
+ Console.WriteLine("S29: {0}, {1}", par.x, par.y == null ? "Null" : "Not null");
+ if (par.x != 1 || par.y != null)
+ {
+ throw new System.Exception();
+ }
+ }, s29);
+
+ s29.x = 5;
+ s29.y = testClass;
+
+ InvokeCallback29((par) => {
+ Console.WriteLine("S29: {0}, {1}", par.x, par.y == null ? "Null" : "Not null");
+ if (par.x != 5 || par.y != testClass)
+ {
+ throw new System.Exception();
+ }
+ }, s29);
+ Enable this when GH Issue #2076 is resolved. */
+ S30 s30;
+ s30.x = 1;
+ s30.y = 2;
+
+ S30 s30_2;
+ s30_2.x = 3;
+ s30_2.y = 4;
+
+ S30 s30_3;
+ s30_3.x = 5;
+ s30_3.y = 6;
+
+ // Program p = new Program();
+ InvokeCallback30(p.Test30, s30, s30_2, s30_3);
+ S1 s1r = InvokeCallback1R((par) =>
{
- throw new System.Exception();
- }
- }, s28);
-
- S29 s29;
- s29.x = 1;
- s29.y = null;
-
- InvokeCallback29((par) => {
- Console.WriteLine("S29: {0}, {1}", par.x, par.y == null ? "Null" : "Not null");
- if (par.x != 1 || par.y != null)
+ Console.WriteLine("S1: {0}, {1}, {2}, {3}", par.x, par.y, par.z, par.w);
+ if (par.x != 1 || par.y != 2 || par.z != 3 || par.w != 4)
+ {
+ throw new System.Exception();
+ }
+
+ }, s1);
+ Console.WriteLine("S1R: {0}, {1}, {2}, {3}", s1r.x, s1r.y, s1r.z, s1r.w);
+ if (s1r.x != 1 || s1r.y != 2 || s1r.z != 3 || s1r.w != 4)
{
throw new System.Exception();
}
- }, s29);
- s29.x = 5;
- s29.y = testClass;
-
- InvokeCallback29((par) => {
- Console.WriteLine("S29: {0}, {1}", par.x, par.y == null ? "Null" : "Not null");
- if (par.x != 5 || par.y != testClass)
+ S2 s2r = InvokeCallback2R((par) =>
{
- throw new System.Exception();
- }
- }, s29);
- Enable this when GH Issue #2076 is resolved. */
- S30 s30;
- s30.x = 1;
- s30.y = 2;
-
- S30 s30_2;
- s30_2.x = 3;
- s30_2.y = 4;
-
- S30 s30_3;
- s30_3.x = 5;
- s30_3.y = 6;
-
- // Program p = new Program();
- InvokeCallback30(p.Test30, s30, s30_2, s30_3);
- S1 s1r = InvokeCallback1R((par) => {
- Console.WriteLine("S1: {0}, {1}, {2}, {3}", par.x, par.y, par.z, par.w);
- if (par.x != 1 || par.y != 2 || par.z != 3 || par.w != 4)
+ Console.WriteLine("S2: {0}, {1}, {2}", par.x, par.y, par.z);
+ if (par.x != 1 || par.y != 2 || par.z != 3)
+ {
+ throw new System.Exception();
+ }
+ }, s2);
+ Console.WriteLine("S2R: {0}, {1}, {2}", s2r.x, s2r.y, s2r.z);
+ if (s2r.x != 1 || s2r.y != 2 || s2r.z != 3)
{
throw new System.Exception();
}
- }, s1);
- Console.WriteLine("S1R: {0}, {1}, {2}, {3}", s1r.x, s1r.y, s1r.z, s1r.w);
- if (s1r.x != 1 || s1r.y != 2 || s1r.z != 3 || s1r.w != 4)
- {
- throw new System.Exception();
- }
-
- S2 s2r = InvokeCallback2R((par) => {
- Console.WriteLine("S2: {0}, {1}, {2}", par.x, par.y, par.z);
- if (par.x != 1 || par.y != 2 || par.z != 3)
+ S3 s3r = InvokeCallback3R((par) =>
+ {
+ Console.WriteLine("S3: {0}, {1}, {2}", par.x, par.y, par.z);
+ if (par.x != 1 || par.y != 2 || par.z != 3)
+ {
+ throw new System.Exception();
+ }
+ }, s3);
+ Console.WriteLine("S3R: {0}, {1}, {2}", s3r.x, s3r.y, s3r.z);
+ if (s3r.x != 1 || s3r.y != 2 || s3r.z != 3)
{
throw new System.Exception();
}
- }, s2);
- Console.WriteLine("S2R: {0}, {1}, {2}", s2r.x, s2r.y, s2r.z);
- if (s2r.x != 1 || s2r.y != 2 || s2r.z != 3)
- {
- throw new System.Exception();
- }
- S3 s3r = InvokeCallback3R((par) => {
- Console.WriteLine("S3: {0}, {1}, {2}", par.x, par.y, par.z);
- if (par.x != 1 || par.y != 2 || par.z != 3)
+ S4 s4r = InvokeCallback4R((par) =>
+ {
+ Console.WriteLine("S4: {0}, {1}", par.x, par.y);
+ if (par.x != 1 || par.y != 2)
+ {
+ throw new System.Exception();
+ }
+ }, s4);
+ Console.WriteLine("S4R: {0}, {1}", s4r.x, s4r.y);
+ if (s4r.x != 1 || s4r.y != 2)
{
throw new System.Exception();
}
- }, s3);
- Console.WriteLine("S3R: {0}, {1}, {2}", s3r.x, s3r.y, s3r.z);
- if (s3r.x != 1 || s3r.y != 2 || s3r.z != 3)
- {
- throw new System.Exception();
- }
- S4 s4r = InvokeCallback4R((par) => {
- Console.WriteLine("S4: {0}, {1}", par.x, par.y);
- if (par.x != 1 || par.y != 2)
+ S5 s5r = InvokeCallback5R((par) =>
+ {
+ Console.WriteLine("S5: {0}, {1}", par.x, par.y);
+ if (par.x != 1 || par.y != 2)
+ {
+ throw new System.Exception();
+ }
+ }, s5);
+ Console.WriteLine("S5R: {0}, {1}", s5r.x, s5r.y);
+ if (s5r.x != 1 || s5r.y != 2)
{
throw new System.Exception();
}
- }, s4);
- Console.WriteLine("S4R: {0}, {1}", s4r.x, s4r.y);
- if (s4r.x != 1 || s4r.y != 2)
- {
- throw new System.Exception();
- }
- S5 s5r = InvokeCallback5R((par) => {
- Console.WriteLine("S5: {0}, {1}", par.x, par.y);
- if (par.x != 1 || par.y != 2)
+ S6 s6r = InvokeCallback6R((par) =>
+ {
+ Console.WriteLine("S6: {0}, {1}, {2}, {3}", par.x, par.y, par.z, par.w);
+ if (par.x != 1 || par.y != 2 || par.z != 3 || par.w != 4)
+ {
+ throw new System.Exception();
+ }
+ }, s6);
+ Console.WriteLine("S6R: {0}, {1}, {2}, {3}", s6r.x, s6r.y, s6r.z, s6r.w);
+ if (s6r.x != 1 || s6r.y != 2 || s6r.z != 3 || s6r.w != 4)
{
throw new System.Exception();
}
- }, s5);
- Console.WriteLine("S5R: {0}, {1}", s5r.x, s5r.y);
- if (s5r.x != 1 || s5r.y != 2)
- {
- throw new System.Exception();
- }
- S6 s6r = InvokeCallback6R((par) => {
- Console.WriteLine("S6: {0}, {1}, {2}, {3}", par.x, par.y, par.z, par.w);
- if (par.x != 1 || par.y != 2 || par.z != 3 || par.w != 4)
+ S7 s7r = InvokeCallback7R((par) =>
+ {
+ Console.WriteLine("S7: {0}, {1}, {2}", par.x, par.y, par.z);
+ if (par.x != 1 || par.y != 2 || par.z != 3)
+ {
+ throw new System.Exception();
+ }
+ }, s7);
+ Console.WriteLine("S7R: {0}, {1}, {2}", s7r.x, s7r.y, s7r.z);
+ if (s7r.x != 1 || s7r.y != 2 || s7r.z != 3)
{
throw new System.Exception();
}
- }, s6);
- Console.WriteLine("S6R: {0}, {1}, {2}, {3}", s6r.x, s6r.y, s6r.z, s6r.w);
- if (s6r.x != 1 || s6r.y != 2 || s6r.z != 3 || s6r.w != 4)
- {
- throw new System.Exception();
- }
- S7 s7r = InvokeCallback7R((par) => {
- Console.WriteLine("S7: {0}, {1}, {2}", par.x, par.y, par.z);
- if (par.x != 1 || par.y != 2 || par.z != 3)
+ S8 s8r = InvokeCallback8R((par) =>
+ {
+ Console.WriteLine("S8: {0}, {1}", par.x, par.y);
+ if (par.x != 1 || par.y != 2)
+ {
+ throw new System.Exception();
+ }
+ }, s8);
+ Console.WriteLine("S8R: {0}, {1}", s8r.x, s8r.y);
+ if (s8r.x != 1 || s8r.y != 2)
{
throw new System.Exception();
}
- }, s7);
- Console.WriteLine("S7R: {0}, {1}, {2}", s7r.x, s7r.y, s7r.z);
- if (s7r.x != 1 || s7r.y != 2 || s7r.z != 3)
- {
- throw new System.Exception();
- }
- S8 s8r = InvokeCallback8R((par) => {
- Console.WriteLine("S8: {0}, {1}", par.x, par.y);
- if (par.x != 1 || par.y != 2)
+ S9 s9r = InvokeCallback9R((par) =>
+ {
+ Console.WriteLine("S9: {0}, {1}, {2}, {3}", par.x, par.y, par.z, par.w);
+ if (par.x != 1 || par.y != 2 || par.z != 3 || par.w != 4)
+ {
+ throw new System.Exception();
+ }
+ }, s9);
+ Console.WriteLine("S9R: {0}, {1}, {2}, {3}", s9r.x, s9r.y, s9r.z, s9r.w);
+ if (s9r.x != 1 || s9r.y != 2 || s9r.z != 3 || s9r.w != 4)
{
throw new System.Exception();
}
- }, s8);
- Console.WriteLine("S8R: {0}, {1}", s8r.x, s8r.y);
- if (s8r.x != 1 || s8r.y != 2)
- {
- throw new System.Exception();
- }
- S9 s9r = InvokeCallback9R((par) => {
- Console.WriteLine("S9: {0}, {1}, {2}, {3}", par.x, par.y, par.z, par.w);
- if (par.x != 1 || par.y != 2 || par.z != 3 || par.w != 4)
+ S10 s10r = InvokeCallback10R((par) =>
{
- throw new System.Exception();
- }
- }, s9);
- Console.WriteLine("S9R: {0}, {1}, {2}, {3}", s9r.x, s9r.y, s9r.z, s9r.w);
- if (s9r.x != 1 || s9r.y != 2 || s9r.z != 3 || s9r.w != 4)
- {
- throw new System.Exception();
- }
-
- S10 s10r = InvokeCallback10R((par) => {
- Console.WriteLine("S10: {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}", par.a, par.b, par.c, par.d, par.e, par.f, par.g, par.h);
- if (par.a != 1 || par.b != 2 || par.c != 3 || par.d != 4 ||
- par.e != 5 || par.f != 6 || par.g != 7 || par.h != 8)
+ Console.WriteLine("S10: {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}", par.a, par.b, par.c, par.d, par.e, par.f, par.g, par.h);
+ if (par.a != 1 || par.b != 2 || par.c != 3 || par.d != 4 ||
+ par.e != 5 || par.f != 6 || par.g != 7 || par.h != 8)
+ {
+ throw new System.Exception();
+ }
+ }, s10);
+ Console.WriteLine("S10R: {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}", s10r.a, s10r.b, s10r.c, s10r.d, s10r.e, s10r.f, s10r.g, s10r.h);
+ if (s10r.a != 1 || s10r.b != 2 || s10r.c != 3 || s10r.d != 4 ||
+ s10r.e != 5 || s10r.f != 6 || s10r.g != 7 || s10r.h != 8)
{
throw new System.Exception();
}
- }, s10);
- Console.WriteLine("S10R: {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}", s10r.a, s10r.b, s10r.c, s10r.d, s10r.e, s10r.f, s10r.g, s10r.h);
- if (s10r.a != 1 || s10r.b != 2 || s10r.c != 3 || s10r.d != 4 ||
- s10r.e != 5 || s10r.f != 6 || s10r.g != 7 || s10r.h != 8)
- {
- throw new System.Exception();
- }
- S11 s11r = InvokeCallback11R((par) => {
- Console.WriteLine("S11: {0}, {1}, {2}, {3}, {4}", par.a, par.b, par.c, par.d, par.e);
- if (par.a != 1 || par.b != 2 || par.c != 3 || par.d != 4 || par.e != 5)
+ S11 s11r = InvokeCallback11R((par) =>
+ {
+ Console.WriteLine("S11: {0}, {1}, {2}, {3}, {4}", par.a, par.b, par.c, par.d, par.e);
+ if (par.a != 1 || par.b != 2 || par.c != 3 || par.d != 4 || par.e != 5)
+ {
+ throw new System.Exception();
+ }
+ }, s11);
+ Console.WriteLine("S11R: {0}, {1}, {2}, {3}, {4}", s11r.a, s11r.b, s11r.c, s11r.d, s11r.e);
+ if (s11r.a != 1 || s11r.b != 2 || s11r.c != 3 || s11r.d != 4 || s11r.e != 5)
{
throw new System.Exception();
}
- }, s11);
- Console.WriteLine("S11R: {0}, {1}, {2}, {3}, {4}", s11r.a, s11r.b, s11r.c, s11r.d, s11r.e);
- if (s11r.a != 1 || s11r.b != 2 || s11r.c != 3 || s11r.d != 4 || s11r.e != 5)
- {
- throw new System.Exception();
- }
- S12 s12r = InvokeCallback12R((par) => {
- Console.WriteLine("S12: {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}", par.a, par.b, par.c, par.d, par.e, par.f, par.g, par.h, par.i);
- if (par.a != 1 || par.b != 2 || par.c != 3 || par.d != 4 ||
- par.e != 5 || par.f != 6 || par.g != 7 || par.h != 8 || par.i != 9)
+ S12 s12r = InvokeCallback12R((par) =>
+ {
+ Console.WriteLine("S12: {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}", par.a, par.b, par.c, par.d, par.e, par.f, par.g, par.h, par.i);
+ if (par.a != 1 || par.b != 2 || par.c != 3 || par.d != 4 ||
+ par.e != 5 || par.f != 6 || par.g != 7 || par.h != 8 || par.i != 9)
+ {
+ throw new System.Exception();
+ }
+ }, s12);
+ Console.WriteLine("S12R: {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}", s12r.a, s12r.b, s12r.c, s12r.d, s12r.e, s12r.f, s12r.g, s12r.h, s12r.i);
+ if (s12r.a != 1 || s12r.b != 2 || s12r.c != 3 || s12r.d != 4 ||
+ s12r.e != 5 || s12r.f != 6 || s12r.g != 7 || s12r.h != 8 || s12r.i != 9)
{
throw new System.Exception();
}
- }, s12);
- Console.WriteLine("S12R: {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}", s12r.a, s12r.b, s12r.c, s12r.d, s12r.e, s12r.f, s12r.g, s12r.h, s12r.i);
- if (s12r.a != 1 || s12r.b != 2 || s12r.c != 3 || s12r.d != 4 ||
- s12r.e != 5 || s12r.f != 6 || s12r.g != 7 || s12r.h != 8 || s12r.i != 9)
- {
- throw new System.Exception();
- }
- S13 s13r = InvokeCallback13R((par) => {
- Console.WriteLine("S13: {0}, {1}", par.hasValue, par.x);
- if (par.hasValue != 1 || par.x != 2)
+ S13 s13r = InvokeCallback13R((par) =>
+ {
+ Console.WriteLine("S13: {0}, {1}", par.hasValue, par.x);
+ if (par.hasValue != 1 || par.x != 2)
+ {
+ throw new System.Exception();
+ }
+ }, s13);
+ Console.WriteLine("S13R: {0}, {1}", s13r.hasValue, s13r.x);
+ if (s13r.hasValue != 1 || s13r.x != 2)
{
throw new System.Exception();
}
- }, s13);
- Console.WriteLine("S13R: {0}, {1}", s13r.hasValue, s13r.x);
- if (s13r.hasValue != 1 || s13r.x != 2)
- {
- throw new System.Exception();
- }
- S14 s14r = InvokeCallback14R((par) => {
- Console.WriteLine("S14: {0}, {1}", par.x, par.y);
- if (par.x != 1 || par.y != 2)
+ S14 s14r = InvokeCallback14R((par) =>
+ {
+ Console.WriteLine("S14: {0}, {1}", par.x, par.y);
+ if (par.x != 1 || par.y != 2)
+ {
+ throw new System.Exception();
+ }
+ }, s14);
+ Console.WriteLine("S14R: {0}, {1}", s14r.x, s14r.y);
+ if (s14r.x != 1 || s14r.y != 2)
{
throw new System.Exception();
}
- }, s14);
- Console.WriteLine("S14R: {0}, {1}", s14r.x, s14r.y);
- if (s14r.x != 1 || s14r.y != 2)
- {
- throw new System.Exception();
- }
- S15 s15r = InvokeCallback15R((par) => {
- Console.WriteLine("S15: {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}", par.a, par.b, par.c, par.d, par.e, par.f, par.g, par.h, par.i);
- if (par.a != 1 || par.b != 2 || par.c != 3 || par.d != 4 ||
- par.e != 5 || par.f != 6 || par.g != 7 || par.h != 8 || par.i != 9)
+ S15 s15r = InvokeCallback15R((par) =>
+ {
+ Console.WriteLine("S15: {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}", par.a, par.b, par.c, par.d, par.e, par.f, par.g, par.h, par.i);
+ if (par.a != 1 || par.b != 2 || par.c != 3 || par.d != 4 ||
+ par.e != 5 || par.f != 6 || par.g != 7 || par.h != 8 || par.i != 9)
+ {
+ throw new System.Exception();
+ }
+ }, s15);
+ Console.WriteLine("S15R: {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}", s15r.a, s15r.b, s15r.c, s15r.d, s15r.e, s15r.f, s15r.g, s15r.h, s15r.i);
+ if (s15r.a != 1 || s15r.b != 2 || s15r.c != 3 || s15r.d != 4 ||
+ s15r.e != 5 || s15r.f != 6 || s15r.g != 7 || s15r.h != 8 || s15r.i != 9)
{
throw new System.Exception();
}
- }, s15);
- Console.WriteLine("S15R: {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}", s15r.a, s15r.b, s15r.c, s15r.d, s15r.e, s15r.f, s15r.g, s15r.h, s15r.i);
- if (s15r.a != 1 || s15r.b != 2 || s15r.c != 3 || s15r.d != 4 ||
- s15r.e != 5 || s15r.f != 6 || s15r.g != 7 || s15r.h != 8 || s15r.i != 9)
- {
- throw new System.Exception();
- }
- S16 s16r = InvokeCallback16R((par) => {
- Console.WriteLine("S16: {0}, {1}", par.x, par.y);
- if (par.x != 1 || par.y != 2)
+ S16 s16r = InvokeCallback16R((par) =>
+ {
+ Console.WriteLine("S16: {0}, {1}", par.x, par.y);
+ if (par.x != 1 || par.y != 2)
+ {
+ throw new System.Exception();
+ }
+ }, s16);
+ Console.WriteLine("S16R: {0}, {1}", s16r.x, s16r.y);
+ if (s16r.x != 1 || s16r.y != 2)
{
throw new System.Exception();
}
- }, s16);
- Console.WriteLine("S16R: {0}, {1}", s16r.x, s16r.y);
- if (s16r.x != 1 || s16r.y != 2)
- {
- throw new System.Exception();
- }
- S17 s17r = InvokeCallback17R((par) => {
- Console.WriteLine("S17: {0}, {1}", par.x, par.y);
- if (par.x != 1 || par.y!= 2)
+ S17 s17r = InvokeCallback17R((par) =>
+ {
+ Console.WriteLine("S17: {0}, {1}", par.x, par.y);
+ if (par.x != 1 || par.y != 2)
+ {
+ throw new System.Exception();
+ }
+ }, s17);
+ Console.WriteLine("S17R: {0}, {1}", s17r.x, s17r.y);
+ if (s17r.x != 1 || s17r.y != 2)
{
throw new System.Exception();
}
- }, s17);
- Console.WriteLine("S17R: {0}, {1}", s17r.x, s17r.y);
- if (s17r.x != 1 || s17r.y != 2)
- {
- throw new System.Exception();
- }
- S18 s18r = InvokeCallback18R((par) => {
- Console.WriteLine("S18: {0}, {1}, {2}", par.x, par.y, par.z);
- if (par.x != 1 || par.y != 2 || par.z != 3)
+ S18 s18r = InvokeCallback18R((par) =>
+ {
+ Console.WriteLine("S18: {0}, {1}, {2}", par.x, par.y, par.z);
+ if (par.x != 1 || par.y != 2 || par.z != 3)
+ {
+ throw new System.Exception();
+ }
+ }, s18);
+ Console.WriteLine("S18R: {0}, {1}, {2}", s18r.x, s18r.y, s18r.z);
+ if (s18r.x != 1 || s18r.y != 2 || s18r.z != 3)
{
throw new System.Exception();
}
- }, s18);
- Console.WriteLine("S18R: {0}, {1}, {2}", s18r.x, s18r.y, s18r.z);
- if (s18r.x != 1 || s18r.y != 2 || s18r.z != 3)
- {
- throw new System.Exception();
- }
- S19 s19r = InvokeCallback19R((par) => {
- Console.WriteLine("S19: {0}, {1}, {2}, {3}", par.x, par.y, par.z, par.w);
- if (par.x != 1 || par.y != 2 || par.z != 3 || par.w != 4)
+ S19 s19r = InvokeCallback19R((par) =>
+ {
+ Console.WriteLine("S19: {0}, {1}, {2}, {3}", par.x, par.y, par.z, par.w);
+ if (par.x != 1 || par.y != 2 || par.z != 3 || par.w != 4)
+ {
+ throw new System.Exception();
+ }
+ }, s19);
+ Console.WriteLine("S19R: {0}, {1}, {2}, {3}", s19r.x, s19r.y, s19r.z, s19r.w);
+ if (s19r.x != 1 || s19r.y != 2 || s19r.z != 3 || s19r.w != 4)
{
throw new System.Exception();
}
- }, s19);
- Console.WriteLine("S19R: {0}, {1}, {2}, {3}", s19r.x, s19r.y, s19r.z, s19r.w);
- if (s19r.x != 1 || s19r.y != 2 || s19r.z != 3 || s19r.w != 4)
- {
- throw new System.Exception();
- }
- S20 s20r = InvokeCallback20R((par) => {
- Console.WriteLine("S20: {0}, {1}, {2}, {3}", par.x, par.y, par.z, par.w);
- if (par.x != 1 || par.y != 2 || par.z != 3 || par.w != 4)
+ S20 s20r = InvokeCallback20R((par) =>
+ {
+ Console.WriteLine("S20: {0}, {1}, {2}, {3}", par.x, par.y, par.z, par.w);
+ if (par.x != 1 || par.y != 2 || par.z != 3 || par.w != 4)
+ {
+ throw new System.Exception();
+ }
+ }, s20);
+ Console.WriteLine("S20R: {0}, {1}, {2}, {3}", s20r.x, s20r.y, s20r.z, s20r.w);
+ if (s20r.x != 1 || s20r.y != 2 || s20r.z != 3 || s20r.w != 4)
{
throw new System.Exception();
}
- }, s20);
- Console.WriteLine("S20R: {0}, {1}, {2}, {3}", s20r.x, s20r.y, s20r.z, s20r.w);
- if (s20r.x != 1 || s20r.y != 2 || s20r.z != 3 || s20r.w != 4)
- {
- throw new System.Exception();
- }
-/* These tests are not working on non Windows CoreCLR. Enable this when GH Issue #2076 is resolved.
- s28.x = null;
- S28 s28r = InvokeCallback28R((par) => {
- Console.WriteLine("S28: {0}, {1}", par.x == null ? "Null" : "Not null", par.y);
- if (par.x == null || par.y != 5)
+ /* These tests are not working on non Windows CoreCLR. Enable this when GH Issue #2076 is resolved.
+ s28.x = null;
+ S28 s28r = InvokeCallback28R((par) => {
+ Console.WriteLine("S28: {0}, {1}", par.x == null ? "Null" : "Not null", par.y);
+ if (par.x == null || par.y != 5)
+ {
+ throw new System.Exception();
+ }
+ }, s28);
+ Console.WriteLine("S28R: {0}, {1}", s28r.x == null ? "Null" : "Not null", s28r.y);
+ if (s28r.x == null || s28r.y != 5)
{
throw new System.Exception();
}
- }, s28);
- Console.WriteLine("S28R: {0}, {1}", s28r.x == null ? "Null" : "Not null", s28r.y);
- if (s28r.x == null || s28r.y != 5)
- {
- throw new System.Exception();
- }
- s28.x = testClass;
- s28.y = 5;
-
- s28r = InvokeCallback28R((par) => {
- Console.WriteLine("S28: {0}, {1}", par.x == null ? "Null" : "Not null", par.y);
- if (par.x != testClass || par.y != 5)
+ s28.x = testClass;
+ s28.y = 5;
+
+ s28r = InvokeCallback28R((par) => {
+ Console.WriteLine("S28: {0}, {1}", par.x == null ? "Null" : "Not null", par.y);
+ if (par.x != testClass || par.y != 5)
+ {
+ throw new System.Exception();
+ }
+ }, s28);
+ Console.WriteLine("S28R: {0}, {1}", s28r.x == null ? "Null" : "Not null", s28r.y);
+ if (s28r.x != testClass || s28r.y != 5)
{
throw new System.Exception();
}
- }, s28);
- Console.WriteLine("S28R: {0}, {1}", s28r.x == null ? "Null" : "Not null", s28r.y);
- if (s28r.x != testClass || s28r.y != 5)
- {
- throw new System.Exception();
- }
- s29.y = null;
- S29 s29r = InvokeCallback29R((par) => {
- Console.WriteLine("S29: {0}, {1}", par.x, par.y == null ? "Null" : "Not null");
- if (par.x != 5 || par.y == null)
+ s29.y = null;
+ S29 s29r = InvokeCallback29R((par) => {
+ Console.WriteLine("S29: {0}, {1}", par.x, par.y == null ? "Null" : "Not null");
+ if (par.x != 5 || par.y == null)
+ {
+ throw new System.Exception();
+ }
+ }, s29);
+ Console.WriteLine("S29R: {0}, {1}", s29r.x, s29r.y == null ? "Null" : "Not null");
+ if (s29r.x != 5 || s29r.y == null)
{
throw new System.Exception();
}
- }, s29);
- Console.WriteLine("S29R: {0}, {1}", s29r.x, s29r.y == null ? "Null" : "Not null");
- if (s29r.x != 5 || s29r.y == null)
- {
- throw new System.Exception();
- }
- s29.x = 5;
- s29.y = testClass;
- s29r = InvokeCallback29R((par) => {
- Console.WriteLine("S29: {0}, {1}", par.x, par.y == null ? "Null" : "Not null");
- if (par.x != 5 || par.y != testClass)
+ s29.x = 5;
+ s29.y = testClass;
+ s29r = InvokeCallback29R((par) => {
+ Console.WriteLine("S29: {0}, {1}", par.x, par.y == null ? "Null" : "Not null");
+ if (par.x != 5 || par.y != testClass)
+ {
+ throw new System.Exception();
+ }
+ }, s29);
+ Console.WriteLine("S29R: {0}, {1}", s29r.x, s29r.y == null ? "Null" : "Not null");
+ if (s29r.x != 5 || s29r.y != testClass)
{
throw new System.Exception();
}
- }, s29);
- Console.WriteLine("S29R: {0}, {1}", s29r.x, s29r.y == null ? "Null" : "Not null");
- if (s29r.x != 5 || s29r.y != testClass)
+ Enable this when GH Issue #2076 is resolved. */
+ }
+ catch (Exception e)
{
- throw new System.Exception();
+ Console.WriteLine(e.Message);
+ return -1;
}
- Enable this when GH Issue #2076 is resolved. */
return 100;
}
diff --git a/tests/src/JIT/Methodical/structs/valuetuple.cs b/tests/src/JIT/Methodical/structs/valuetuple.cs
new file mode 100644
index 0000000000..9e8af5e20c
--- /dev/null
+++ b/tests/src/JIT/Methodical/structs/valuetuple.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.
+//
+
+// This test is extracted and simplified from the corefx tests for the ValueTuple class.
+// It exposed an issue with assertion propagation not validating the assertions
+// for a containing struct when a field lclVar is defined.
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+[StructLayout(LayoutKind.Auto)]
+public struct ValueTuple<T1, T2, T3>
+{
+ public T1 Item1;
+ public T2 Item2;
+ public T3 Item3;
+ public ValueTuple(T1 item1, T2 item2, T3 item3)
+ {
+ Item1 = item1;
+ Item2 = item2;
+ Item3 = item3;
+ }
+
+ public static ValueTuple<T1, T2, T3> Create(T1 item1, T2 item2, T3 item3) =>
+ new ValueTuple<T1, T2, T3>(item1, item2, item3);
+
+ public override bool Equals(object obj)
+ {
+ return obj is ValueTuple<T1, T2, T3> && Equals((ValueTuple<T1, T2, T3>)obj);
+ }
+
+ public bool Equals(ValueTuple<T1, T2, T3> other)
+ {
+ return Item1.Equals(other.Item1) && Item2.Equals(other.Item2) && Item3.Equals(other.Item3);
+ }
+ public override int GetHashCode()
+ {
+ return 0;
+ }
+}
+
+public static class TupleExtensions
+{
+ public static ValueTuple<T1, T2, T3>
+ ToValueTuple<T1, T2, T3>(
+ this Tuple<T1, T2, T3> value)
+ {
+ return ValueTuple<T1, T2, T3>.Create(value.Item1, value.Item2, value.Item3);
+ }
+ 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);
+ }
+}
+
+public class StructOptsTest
+{
+ const int Pass = 100;
+ const int Fail = -1;
+
+ public static int ConvertToRef3()
+ {
+ var refTuple = Tuple.Create(-1, -1, -1);
+ var valueTuple = ValueTuple<int,int,int>.Create(1, 2, 3);
+
+ refTuple = valueTuple.ToTuple();
+ if (!String.Equals("(1, 2, 3)", refTuple.ToString()))
+ {
+ Console.WriteLine("Expected (1, 2, 3); got " + refTuple.ToString());
+ return Fail;
+ }
+ return Pass;
+ }
+
+ public static int Main()
+ {
+ int returnVal = Fail;
+ try
+ {
+ returnVal = ConvertToRef3();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Unexpected exception " + e.Message);
+ returnVal = Fail;
+ }
+ return returnVal;
+ }
+}
diff --git a/tests/src/JIT/Methodical/structs/valuetuple.csproj b/tests/src/JIT/Methodical/structs/valuetuple.csproj
new file mode 100644
index 0000000000..486744bb36
--- /dev/null
+++ b/tests/src/JIT/Methodical/structs/valuetuple.csproj
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{0B8F1AF4-9355-4307-BC68-08A2947AD3B9}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <IlasmRoundTrip>true</IlasmRoundTrip>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="valuetuple.cs" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)threading+thread\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)threading+thread\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchF/Adams/Adams.cs b/tests/src/JIT/Performance/CodeQuality/BenchF/Adams/Adams.cs
index 427ec9269e..431d857f16 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchF/Adams/Adams.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchF/Adams/Adams.cs
@@ -18,6 +18,8 @@ using Microsoft.Xunit.Performance;
[assembly: MeasureInstructionsRetired]
#endif // XUNIT_PERF
+namespace Benchstone.BenchF
+{
public static class Adams
{
#if DEBUG
@@ -41,7 +43,7 @@ public static class Adams
#if VERBOSE
Console.WriteLine(" ADAMS-MOULTON METHOD ");
-#endif // VERBOSE
+#endif // VERBOSE
n = 4;
h = 1.0 / 32.0;
@@ -67,7 +69,7 @@ public static class Adams
f[i] = xn + yn;
#if VERBOSE
Console.WriteLine("{0}, {1}, {2}, {3}, {4}", k, xn, yn, dn, en);
-#endif // VERBOSE
+#endif // VERBOSE
}
for (k = 4; k <= nstep; k++)
@@ -137,7 +139,7 @@ public static class Adams
bool result = true;
// Note: we can't check xn or yn better because of the precision
- // with which original results are given
+ // with which original results are given
result &= System.Math.Abs(g_xn_base - g_xn) <= 1.5e-7;
result &= System.Math.Abs(g_yn_base - g_yn) <= 1.5e-7;
result &= System.Math.Abs(g_dn) <= 2.5e-9;
@@ -161,3 +163,4 @@ public static class Adams
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchF/BenchMk2/BenchMk2.cs b/tests/src/JIT/Performance/CodeQuality/BenchF/BenchMk2/BenchMk2.cs
index 970164405b..c4cfc0b217 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchF/BenchMk2/BenchMk2.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchF/BenchMk2/BenchMk2.cs
@@ -11,6 +11,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchF
+{
public static class BenchMk2
{
#if DEBUG
@@ -64,3 +66,4 @@ public static class BenchMk2
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchF/BenchMrk/BenchMrk.cs b/tests/src/JIT/Performance/CodeQuality/BenchF/BenchMrk/BenchMrk.cs
index 27a5fe617c..f342b2d84e 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchF/BenchMrk/BenchMrk.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchF/BenchMrk/BenchMrk.cs
@@ -11,6 +11,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchF
+{
public static class BenchMrk
{
#if DEBUG
@@ -64,3 +66,4 @@ public static class BenchMrk
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchF/Bisect/Bisect.cs b/tests/src/JIT/Performance/CodeQuality/BenchF/Bisect/Bisect.cs
index 1c27003567..724416a626 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchF/Bisect/Bisect.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchF/Bisect/Bisect.cs
@@ -12,6 +12,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchF
+{
public static class Bisect
{
#if DEBUG
@@ -161,3 +163,4 @@ public static class Bisect
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchF/DMath/DMath.cs b/tests/src/JIT/Performance/CodeQuality/BenchF/DMath/DMath.cs
index a2c3a385cd..47c5e20285 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchF/DMath/DMath.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchF/DMath/DMath.cs
@@ -11,6 +11,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchF
+{
public static class DMath
{
#if DEBUG
@@ -110,4 +112,5 @@ public static class DMath
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchF/FFT/FFT.cs b/tests/src/JIT/Performance/CodeQuality/BenchF/FFT/FFT.cs
index 3e853273fb..8881eae6c6 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchF/FFT/FFT.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchF/FFT/FFT.cs
@@ -13,6 +13,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchF
+{
public static class FFT
{
#if DEBUG
@@ -151,3 +153,4 @@ public static class FFT
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchF/InProd/InProd.cs b/tests/src/JIT/Performance/CodeQuality/BenchF/InProd/InProd.cs
index ff54ea7acd..26096b736e 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchF/InProd/InProd.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchF/InProd/InProd.cs
@@ -11,6 +11,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchF
+{
public static class InProd
{
#if DEBUG
@@ -132,3 +134,4 @@ public static class InProd
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchF/InvMt/InvMt.cs b/tests/src/JIT/Performance/CodeQuality/BenchF/InvMt/InvMt.cs
index a5f387b7f5..6ecfb62d91 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchF/InvMt/InvMt.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchF/InvMt/InvMt.cs
@@ -12,6 +12,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchF
+{
public static class InvMt
{
#if DEBUG
@@ -135,3 +137,4 @@ public static class InvMt
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchF/LLoops/LLoops.cs b/tests/src/JIT/Performance/CodeQuality/BenchF/LLoops/LLoops.cs
index 6dcb6c435c..73ec09aa04 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchF/LLoops/LLoops.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchF/LLoops/LLoops.cs
@@ -60,6 +60,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchF
+{
public class LLoops
{
#if DEBUG
@@ -648,3 +650,4 @@ public class LLoops
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchF/Lorenz/Lorenz.cs b/tests/src/JIT/Performance/CodeQuality/BenchF/Lorenz/Lorenz.cs
index bff6398d3b..5819446bf0 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchF/Lorenz/Lorenz.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchF/Lorenz/Lorenz.cs
@@ -12,6 +12,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchF
+{
public static class Lorenz
{
#if DEBUG
@@ -132,3 +134,4 @@ public static class Lorenz
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchF/MatInv4/MatInv4.cs b/tests/src/JIT/Performance/CodeQuality/BenchF/MatInv4/MatInv4.cs
index eb5e33b130..a00c29b843 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchF/MatInv4/MatInv4.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchF/MatInv4/MatInv4.cs
@@ -10,6 +10,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchF
+{
public static class MatInv4
{
#if DEBUG
@@ -217,11 +219,11 @@ public static class MatInv4
// 0 < ik <= n^2
ik = nk + i;
hold = a[ik - 1];
- // -n < ij <= 0
+ // -n < ij <= 0
ij = i - n;
for (j = 1; j <= n; ++j)
{
- // i <= n, ij <= n + n + ... + n (n times) or ij <= n * n
+ // i <= n, ij <= n + n + ... + n (n times) or ij <= n * n
ij = ij + n;
if (j == k)
{
@@ -237,7 +239,7 @@ public static class MatInv4
kj = k - n;
for (j = 1; j <= n; ++j)
{
- // k <= n, kj <= n + n + ... + n (n times) or kj <= n * n
+ // k <= n, kj <= n + n + ... + n (n times) or kj <= n * n
kj = kj + n;
if (j == k)
{
@@ -268,11 +270,11 @@ public static class MatInv4
jr = n * (i - 1);
for (j = 1; j <= n; ++j)
{
- // jk <= n^2 - n + n
+ // jk <= n^2 - n + n
// jk <= n^2
jk = jq + j;
hold = a[jk - 1];
- // ji <= n^2 - n + n
+ // ji <= n^2 - n + n
// ji <= n^2
ji = jr + j;
a[jk - 1] = -a[ji - 1];
@@ -288,7 +290,7 @@ public static class MatInv4
ki = k - n;
for (i = 1; i <= n; ++i)
{
- // ki <= n + n + ... + n (n times) or ki <= n * n
+ // ki <= n + n + ... + n (n times) or ki <= n * n
ki = ki + n;
hold = a[ki - 1];
// if i=1, ji = (1 + (n-1) * n) - 1 + n ==> ij = n^2
@@ -378,7 +380,7 @@ public static class MatInv4
{
if (j != k)
{
- // Accessing upto n^2 - n + n - 1 ==> n^2 - 1
+ // Accessing upto n^2 - n + n - 1 ==> n^2 - 1
a[(i - 1) * n + (j - 1)] = a[(i - 1) * n + (k - 1)] * a[(k - 1) * n + (j - 1)] + a[(i - 1) * n + (j - 1)];
}
}
@@ -493,3 +495,4 @@ public static class MatInv4
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchF/NewtE/NewtE.cs b/tests/src/JIT/Performance/CodeQuality/BenchF/NewtE/NewtE.cs
index 0fc14132f1..47f90d8616 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchF/NewtE/NewtE.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchF/NewtE/NewtE.cs
@@ -13,6 +13,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchF
+{
public static class NewtE
{
#if DEBUG
@@ -133,3 +135,4 @@ public static class NewtE
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchF/NewtR/NewtR.cs b/tests/src/JIT/Performance/CodeQuality/BenchF/NewtR/NewtR.cs
index cf945bc110..c590f6e570 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchF/NewtR/NewtR.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchF/NewtR/NewtR.cs
@@ -12,6 +12,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchF
+{
public static class NewtR
{
#if DEBUG
@@ -129,3 +131,4 @@ public static class NewtR
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchF/Regula/Regula.cs b/tests/src/JIT/Performance/CodeQuality/BenchF/Regula/Regula.cs
index 9743ab698c..0011288e55 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchF/Regula/Regula.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchF/Regula/Regula.cs
@@ -12,6 +12,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchF
+{
public static class Regula
{
#if DEBUG
@@ -191,3 +193,4 @@ public static class Regula
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchF/Romber/Romber.cs b/tests/src/JIT/Performance/CodeQuality/BenchF/Romber/Romber.cs
index 5824cd43cc..a4d56f7b0f 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchF/Romber/Romber.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchF/Romber/Romber.cs
@@ -12,6 +12,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchF
+{
public static class Romber
{
#if DEBUG
@@ -167,3 +169,4 @@ public static class Romber
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchF/Secant/Secant.cs b/tests/src/JIT/Performance/CodeQuality/BenchF/Secant/Secant.cs
index e7d1ace2e6..060fb5b0a4 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchF/Secant/Secant.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchF/Secant/Secant.cs
@@ -12,6 +12,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchF
+{
public static class Secant
{
#if DEBUG
@@ -140,3 +142,4 @@ public static class Secant
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchF/Simpsn/Simpsn.cs b/tests/src/JIT/Performance/CodeQuality/BenchF/Simpsn/Simpsn.cs
index e1e9f0eb1f..5b2df292af 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchF/Simpsn/Simpsn.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchF/Simpsn/Simpsn.cs
@@ -12,6 +12,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchF
+{
public static class Simpsn
{
#if DEBUG
@@ -91,3 +93,4 @@ public static class Simpsn
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchF/SqMtx/SqMtx.cs b/tests/src/JIT/Performance/CodeQuality/BenchF/SqMtx/SqMtx.cs
index 673757cedf..b22aad88b7 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchF/SqMtx/SqMtx.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchF/SqMtx/SqMtx.cs
@@ -11,6 +11,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchF
+{
public static class SqMtx
{
#if DEBUG
@@ -101,3 +103,4 @@ public static class SqMtx
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchF/Trap/Trap.cs b/tests/src/JIT/Performance/CodeQuality/BenchF/Trap/Trap.cs
index a5e3e5c0d6..3a0de102ed 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchF/Trap/Trap.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchF/Trap/Trap.cs
@@ -12,6 +12,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchF
+{
public static class Trap
{
#if DEBUG
@@ -94,3 +96,4 @@ public static class Trap
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchF/Whetsto/Whetsto.cs b/tests/src/JIT/Performance/CodeQuality/BenchF/Whetsto/Whetsto.cs
index 2ab0b61ee0..ffe3fa5d8b 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchF/Whetsto/Whetsto.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchF/Whetsto/Whetsto.cs
@@ -12,6 +12,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchF
+{
public static class Whetsto
{
#if DEBUG
@@ -240,3 +242,4 @@ public static class Whetsto
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/8Queens/8Queens.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/8Queens/8Queens.cs
index 76ed0c8e71..e641ee0a74 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchI/8Queens/8Queens.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchI/8Queens/8Queens.cs
@@ -11,6 +11,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchI
+{
public static class EightQueens
{
@@ -68,7 +70,7 @@ public static class EightQueens
}
i = i + 1;
}
-
+
TryMe(1, ref q, b, a);
return (q == 1);
@@ -92,9 +94,10 @@ public static class EightQueens
}
return result;
}
-
+
public static int Main() {
bool result = TestBase();
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/Ackermann/Ackermann.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/Ackermann/Ackermann.cs
index 512f35f82d..5bfa196527 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchI/Ackermann/Ackermann.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchI/Ackermann/Ackermann.cs
@@ -11,6 +11,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchI
+{
public static class Ackermann
{
@@ -40,7 +42,7 @@ public static class Ackermann
int a33 = Acker(3, 3);
return (a00 == 1) && (a11 == 3) && (a22 == 7) & (a33 == 61);
}
-
+
[Benchmark]
public static void Test() {
foreach (var iteration in Benchmark.Iterations) {
@@ -59,9 +61,10 @@ public static class Ackermann
}
return result;
}
-
+
public static int Main() {
bool result = TestBase();
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/AddArray/AddArray.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/AddArray/AddArray.cs
index 0fa2ff90eb..d38e6b4475 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchI/AddArray/AddArray.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchI/AddArray/AddArray.cs
@@ -11,6 +11,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchI
+{
public static class AddArray
{
@@ -48,14 +50,14 @@ public static class AddArray
m = j;
flags4[m] = flags3[l] + m + m + m + m;
}
-
+
for (j = 0; j <= Size; j++) {
k = j;
l = j;
m = j;
flags1[j] = flags1[j] + flags2[k] + flags3[l] + flags4[m] - flags2[k - j + l];
}
-
+
// Escape each flags array so that their elements will appear live-out
Escape(flags1);
Escape(flags2);
@@ -83,9 +85,10 @@ public static class AddArray
}
return result;
}
-
+
public static int Main() {
bool result = TestBase();
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/AddArray2/AddArray2.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/AddArray2/AddArray2.cs
index 865b9445f6..a6004f0309 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchI/AddArray2/AddArray2.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchI/AddArray2/AddArray2.cs
@@ -11,6 +11,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchI
+{
public static class AddArray2
{
#if DEBUG
@@ -129,3 +131,4 @@ public static class AddArray2
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/Array1/Array1.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/Array1/Array1.cs
index 8d5dbd6153..780b7ce66f 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchI/Array1/Array1.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchI/Array1/Array1.cs
@@ -18,6 +18,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchI
+{
public static class Array1
{
#if DEBUG
@@ -152,3 +154,4 @@ public static class Array1
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/Array2/Array2.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/Array2/Array2.cs
index 1b720b94fa..dac100c5a7 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchI/Array2/Array2.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchI/Array2/Array2.cs
@@ -11,6 +11,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchI
+{
public static class Array2
{
@@ -75,7 +77,7 @@ public static class Array2
}
bool result = VerifyCopy(s, d);
-
+
return result;
}
@@ -92,9 +94,10 @@ public static class Array2
bool result = Bench(Iterations);
return result;
}
-
+
public static int Main() {
bool result = TestBase();
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/BenchE/BenchE.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/BenchE/BenchE.cs
index 9cf7d770dc..b16c48280b 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchI/BenchE/BenchE.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchI/BenchE/BenchE.cs
@@ -11,6 +11,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchI
+{
public static class BenchE
{
#if DEBUG
@@ -115,3 +117,4 @@ public static class BenchE
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/BubbleSort/BubbleSort.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/BubbleSort/BubbleSort.cs
index 78626fffc9..558484d3d6 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchI/BubbleSort/BubbleSort.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchI/BubbleSort/BubbleSort.cs
@@ -11,6 +11,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchI
+{
public static class BubbleSort
{
@@ -43,7 +45,7 @@ public static class BubbleSort
return false;
}
}
-
+
return true;
}
@@ -79,9 +81,10 @@ public static class BubbleSort
}
return result;
}
-
+
public static int Main() {
bool result = TestBase();
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/BubbleSort2/BubbleSort2.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/BubbleSort2/BubbleSort2.cs
index 55e5a5f8c5..8c2e63a954 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchI/BubbleSort2/BubbleSort2.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchI/BubbleSort2/BubbleSort2.cs
@@ -11,6 +11,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchI
+{
public static class BubbleSort2
{
@@ -82,9 +84,10 @@ public static class BubbleSort2
}
return result;
}
-
+
public static int Main() {
bool result = TestBase();
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/CSieve/CSieve.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/CSieve/CSieve.cs
index 606f740fb6..aca263711d 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchI/CSieve/CSieve.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchI/CSieve/CSieve.cs
@@ -12,6 +12,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchI
+{
public static class CSieve
{
@@ -74,9 +76,10 @@ public static class CSieve
}
return result;
}
-
+
public static int Main() {
bool result = TestBase();
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/Fib/Fib.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/Fib/Fib.cs
index 01064bb168..ee028db20f 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchI/Fib/Fib.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchI/Fib/Fib.cs
@@ -11,6 +11,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchI
+{
public static class Fib
{
@@ -30,7 +32,7 @@ public static class Fib
return 1;
}
}
-
+
[MethodImpl(MethodImplOptions.NoInlining)]
static bool Bench() {
int fib = Fibonacci(Number);
@@ -55,9 +57,10 @@ public static class Fib
}
return result;
}
-
+
public static int Main() {
bool result = TestBase();
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/HeapSort/HeapSort.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/HeapSort/HeapSort.cs
index 9fd7aa32e0..64b5c8f33b 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchI/HeapSort/HeapSort.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchI/HeapSort/HeapSort.cs
@@ -11,6 +11,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchI
+{
public static class HeapSort
{
@@ -32,7 +34,7 @@ public static class HeapSort
j = i;
k = j / 2;
m = x[i];
-
+
// 0 < k <= (n / 2)
// 1 <= j <= n
while (k > 0) {
@@ -113,9 +115,10 @@ public static class HeapSort
}
return result;
}
-
+
public static int Main() {
bool result = TestBase();
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/IniArray/IniArray.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/IniArray/IniArray.cs
index 78fa233dbf..268af7b779 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchI/IniArray/IniArray.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchI/IniArray/IniArray.cs
@@ -11,6 +11,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchI
+{
public static class IniArray
{
@@ -52,9 +54,10 @@ public static class IniArray
bool result = Bench();
return result;
}
-
+
public static int Main() {
bool result = TestBase();
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/LogicArray/LogicArray.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/LogicArray/LogicArray.cs
index f5ff746b86..c5b4e3b0d8 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchI/LogicArray/LogicArray.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchI/LogicArray/LogicArray.cs
@@ -11,6 +11,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchI
+{
public static class LogicArray
{
@@ -89,9 +91,10 @@ public static class LogicArray
bool result = Bench();
return result;
}
-
+
public static int Main() {
bool result = TestBase();
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/Midpoint/Midpoint.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/Midpoint/Midpoint.cs
index 6e4f193746..9146874358 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchI/Midpoint/Midpoint.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchI/Midpoint/Midpoint.cs
@@ -11,6 +11,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchI
+{
public static class Midpoint
{
@@ -96,9 +98,10 @@ public static class Midpoint
bool result = Bench();
return result;
}
-
+
public static int Main() {
bool result = TestBase();
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/MulMatrix/MulMatrix.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/MulMatrix/MulMatrix.cs
index 3f9c224d3d..a45c012984 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchI/MulMatrix/MulMatrix.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchI/MulMatrix/MulMatrix.cs
@@ -11,6 +11,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchI
+{
public static class MulMatrix
{
@@ -19,7 +21,7 @@ public static class MulMatrix
#else
public const int Iterations = 100;
#endif
-
+
const int Size = 75;
static volatile object VolatileObject;
@@ -132,9 +134,10 @@ public static class MulMatrix
bool result = Bench();
return result;
}
-
+
public static int Main() {
bool result = TestBase();
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/NDhrystone/NDhrystone.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/NDhrystone/NDhrystone.cs
index c2526748ce..33effcbf40 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchI/NDhrystone/NDhrystone.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchI/NDhrystone/NDhrystone.cs
@@ -7,7 +7,7 @@
// Dhrystone: a synthetic systems programming benchmark
// Reinhold P. Weicker
// Communications of the ACM, Volume 27 Issue 10, Oct 1984, Pages 1013-1030
-
+
using Microsoft.Xunit.Performance;
using System;
using System.Runtime.CompilerServices;
@@ -16,6 +16,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchI
+{
public static class NDhrystone
{
@@ -63,9 +65,9 @@ public static class NDhrystone
int intLoc2;
int intLoc3 = 0;
Enumeration enumLoc;
-
+
int i; /* modification */
-
+
m_ptrGlb.PtrComp = m_ptrGlbNext;
m_ptrGlb.Discr = Enumeration.Ident1;
m_ptrGlb.EnumComp = Enumeration.Ident3;
@@ -117,12 +119,12 @@ public static class NDhrystone
ptrParIn = ptrParIn.PtrComp;
}
}
-
+
static void Proc2(ref int intParIO) {
int intLoc;
Enumeration enumLoc = Enumeration.Ident2;
intLoc = intParIO + 10;
-
+
for (;;) {
if (s_char1Glob == 'A') {
--intLoc;
@@ -142,17 +144,17 @@ public static class NDhrystone
else {
s_intGlob = 100;
}
-
+
Proc7(10, s_intGlob, ref m_ptrGlb.IntComp);
}
-
+
static void Proc4() {
bool boolLoc;
boolLoc = s_char1Glob == 'A';
boolLoc |= s_boolGlob;
s_char2Glob = 'B';
}
-
+
static void Proc5() {
s_char1Glob = 'A';
s_boolGlob = false;
@@ -163,12 +165,12 @@ public static class NDhrystone
if (!Func3(enumParIn)) {
enumParOut = Enumeration.Ident4;
}
-
+
switch (enumParIn) {
- case Enumeration.Ident1:
+ case Enumeration.Ident1:
enumParOut = Enumeration.Ident1;
break;
- case Enumeration.Ident2:
+ case Enumeration.Ident2:
if (s_intGlob > 100) {
enumParOut = Enumeration.Ident1;
}
@@ -176,12 +178,12 @@ public static class NDhrystone
enumParOut = Enumeration.Ident4;
}
break;
- case Enumeration.Ident3:
+ case Enumeration.Ident3:
enumParOut = Enumeration.Ident2;
break;
- case Enumeration.Ident4:
+ case Enumeration.Ident4:
break;
- case Enumeration.Ident5:
+ case Enumeration.Ident5:
enumParOut = Enumeration.Ident3;
break;
}
@@ -192,7 +194,7 @@ public static class NDhrystone
intLoc = intParI1 + 2;
intParOut = intParI2 + intLoc;
}
-
+
static void Proc8(int[] array1Par, int[][] array2Par, int intParI1, int intParI2) {
int intLoc;
intLoc = intParI1 + 5;
@@ -206,7 +208,7 @@ public static class NDhrystone
array2Par[intLoc + 20][intLoc] = array1Par[intLoc];
s_intGlob = 5;
}
-
+
static Enumeration Func1(char charPar1, char charPar2) {
char charLoc1;
char charLoc2;
@@ -219,7 +221,7 @@ public static class NDhrystone
return (Enumeration.Ident2);
}
}
-
+
static bool Func2(char[] strParI1, char[] strParI2) {
int intLoc;
char charLoc = '\0';
@@ -243,18 +245,18 @@ public static class NDhrystone
return true;
}
}
-
+
return false;
}
}
-
+
static bool Func3(Enumeration enumParIn) {
Enumeration enumLoc;
enumLoc = enumParIn;
if (enumLoc == Enumeration.Ident3) {
return true;
}
-
+
return false;
}
@@ -278,9 +280,10 @@ public static class NDhrystone
bool result = Bench();
return result;
}
-
+
public static int Main() {
bool result = TestBase();
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/Permutate/Permutate.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/Permutate/Permutate.cs
index d7457cdbc1..43fc28b370 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchI/Permutate/Permutate.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchI/Permutate/Permutate.cs
@@ -11,6 +11,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchI
+{
public class Permutate
{
#if DEBUG
@@ -114,3 +116,4 @@ public class Permutate
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/Pi/Pi.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/Pi/Pi.cs
index 112ff6df9b..2fe0918784 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchI/Pi/Pi.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchI/Pi/Pi.cs
@@ -11,6 +11,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchI
+{
public static class Pi
{
@@ -78,9 +80,10 @@ public static class Pi
}
return result;
}
-
+
public static int Main() {
bool result = TestBase();
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/Puzzle/Puzzle.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/Puzzle/Puzzle.cs
index 2b1c2847f4..2271e02455 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchI/Puzzle/Puzzle.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchI/Puzzle/Puzzle.cs
@@ -11,6 +11,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchI
+{
public class Puzzle
{
#if DEBUG
@@ -391,3 +393,4 @@ public class Puzzle
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/QuickSort/QuickSort.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/QuickSort/QuickSort.cs
index 191211aaa8..7cdac96a69 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchI/QuickSort/QuickSort.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchI/QuickSort/QuickSort.cs
@@ -11,6 +11,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchI
+{
public static class QuickSort
{
@@ -52,7 +54,7 @@ public static class QuickSort
arr[j] = temp;
}
}
-
+
// need to swap the pivot and a[i](or a[j] as i==j) so
// that the pivot will be at its final place in the sorted array
@@ -108,9 +110,10 @@ public static class QuickSort
}
return result;
}
-
+
public static int Main() {
bool result = TestBase();
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/TreeInsert/TreeInsert.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/TreeInsert/TreeInsert.cs
index 8a24240538..2867abc4d4 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchI/TreeInsert/TreeInsert.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchI/TreeInsert/TreeInsert.cs
@@ -11,6 +11,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchI
+{
public class TreeInsert
{
#if DEBUG
@@ -136,3 +138,4 @@ public class TreeInsert
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/TreeSort/TreeSort.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/TreeSort/TreeSort.cs
index 68b5c965f7..e0971346cf 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchI/TreeSort/TreeSort.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchI/TreeSort/TreeSort.cs
@@ -11,6 +11,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchI
+{
public static class TreeSort
{
@@ -74,7 +76,7 @@ public static class TreeSort
else {
Insert(n, t.Left);
}
- }
+ }
else if (n < t.Val) {
if (t.Right == null) {
t.Right = new Node(n);
@@ -117,7 +119,7 @@ public static class TreeSort
bool result = CheckTree(tree);
return result;
}
-
+
[MethodImpl(MethodImplOptions.NoInlining)]
static bool Bench() {
int[] sortList = new int[SortElements + 1];
@@ -143,9 +145,10 @@ public static class TreeSort
}
return result;
}
-
+
public static int Main() {
bool result = TestBase();
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchI/XposMatrix/XposMatrix.cs b/tests/src/JIT/Performance/CodeQuality/BenchI/XposMatrix/XposMatrix.cs
index 0bb17b8cc5..de8b486049 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchI/XposMatrix/XposMatrix.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchI/XposMatrix/XposMatrix.cs
@@ -11,6 +11,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Benchstone.BenchI
+{
public static class XposMatrix
{
public const int ArraySize = 100;
@@ -48,11 +50,11 @@ public static class XposMatrix
matrix[i][j] = 1;
}
}
-
+
if (matrix[n][n] != 1) {
return false;
}
-
+
Inner(matrix, n);
if (matrix[n][n] != 1) {
@@ -88,3 +90,4 @@ public static class XposMatrix
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/binarytrees/binarytrees.csharp.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/binarytrees/binarytrees.csharp.cs
index e4118b2963..c77e802989 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/binarytrees/binarytrees.csharp.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/binarytrees/binarytrees.csharp.cs
@@ -2,9 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
/* The Computer Language Benchmarks Game
- http://benchmarksgame.alioth.debian.org/
+ http://benchmarksgame.alioth.debian.org/
- contributed by Marek Safar
+ contributed by Marek Safar
modified for use with xunit-performance
*/
@@ -17,6 +17,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace BenchmarksGame
+{
public class BinaryTrees
{
private const int minDepth = 4;
@@ -149,3 +151,4 @@ public class BinaryTrees
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/fasta/fasta.csharp-2.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/fasta/fasta.csharp-2.cs
index c58ce0bd97..92fbceb692 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/fasta/fasta.csharp-2.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/fasta/fasta.csharp-2.cs
@@ -18,6 +18,8 @@ using System.Text;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace BenchmarksGame
+{
public class Fasta
{
#if DEBUG
@@ -218,3 +220,4 @@ public class Fasta
s.Write(s_buf, 0, s_index);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/fastaredux/fastaredux.csharp.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/fastaredux/fastaredux.csharp.cs
index 7128e326fc..df8999a2de 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/fastaredux/fastaredux.csharp.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/fastaredux/fastaredux.csharp.cs
@@ -18,6 +18,8 @@ using System.Text;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace BenchmarksGame
+{
public static class FastaRedux
{
#if DEBUG
@@ -181,4 +183,5 @@ public static class FastaRedux
if (br < BUF_LEN) s.Write(s_buf, 0, BUF_LEN - br);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/nbody/nbody.csharp-3.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/nbody/nbody.csharp-3.cs
index 70c87095ad..2124cf4d9e 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/nbody/nbody.csharp-3.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/nbody/nbody.csharp-3.cs
@@ -15,6 +15,8 @@ using System;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace BenchmarksGame
+{
public class NBody
{
public static int Main(String[] args)
@@ -153,4 +155,5 @@ internal class NBodySystem
return e;
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/pidigits/pi-digits.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/pidigits/pi-digits.cs
index 3395e29a55..7e36f0e424 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/pidigits/pi-digits.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/pidigits/pi-digits.cs
@@ -6,7 +6,7 @@
*
* Port of the C code that uses GMP
* Just switched it to use C#'s BigInteger instead
- *
+ *
* To compile use csc /o+ /r:System.Numerics.dll
*
* modified for use with xunit-performance
@@ -20,6 +20,8 @@ using System.Text;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace BenchmarksGame
+{
public class pidigits
{
#if DEBUG
@@ -111,4 +113,5 @@ public class pidigits
}
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/spectralnorm/spectralnorm.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/spectralnorm/spectralnorm.cs
index 9e984864a7..01eeea07bf 100644
--- a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/spectralnorm/spectralnorm.cs
+++ b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/spectralnorm/spectralnorm.cs
@@ -3,8 +3,8 @@
// See the LICENSE file in the project root for more information.
/* The Computer Language Benchmarks Game
http://benchmarksgame.alioth.debian.org/
-
- contributed by Isaac Gouy
+
+ contributed by Isaac Gouy
modified for use with xunit-performance
*/
@@ -15,6 +15,8 @@ using System;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace BenchmarksGame
+{
public class SpectralNorm
{
#if DEBUG
@@ -78,7 +80,7 @@ public class SpectralNorm
}
// B=AtA A multiplied by A transposed
- // v.Bv /(v.v) eigenvalue of v
+ // v.Bv /(v.v) eigenvalue of v
double vBv = 0, vv = 0;
for (int i = 0; i < n; i++)
{
@@ -124,3 +126,4 @@ public class SpectralNorm
MultiplyAtv(n, u, AtAv);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsByte.cs b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsByte.cs
index 8271c40a43..3b28f87fe5 100644
--- a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsByte.cs
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsByte.cs
@@ -13,6 +13,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Inlining
+{
public static class ConstantArgsByte
{
@@ -928,3 +930,4 @@ public static class ConstantArgsByte
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsChar.cs b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsChar.cs
index 0d1f9284ba..0cc4b9c558 100644
--- a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsChar.cs
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsChar.cs
@@ -13,6 +13,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Inlining
+{
public static class ConstantArgsChar
{
@@ -928,3 +930,4 @@ public static class ConstantArgsChar
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsDouble.cs b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsDouble.cs
index 6c95d482d5..4bd5683f0c 100644
--- a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsDouble.cs
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsDouble.cs
@@ -13,6 +13,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Inlining
+{
public static class ConstantArgsDouble
{
@@ -808,3 +810,4 @@ public static class ConstantArgsDouble
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsFloat.cs b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsFloat.cs
index bbd65a4004..f609a4bb44 100644
--- a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsFloat.cs
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsFloat.cs
@@ -13,6 +13,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Inlining
+{
public static class ConstantArgsFloat
{
@@ -808,3 +810,4 @@ public static class ConstantArgsFloat
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsInt.cs b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsInt.cs
index 03d59f93d0..f54e800d17 100644
--- a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsInt.cs
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsInt.cs
@@ -13,6 +13,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Inlining
+{
public static class ConstantArgsInt
{
@@ -928,3 +930,4 @@ public static class ConstantArgsInt
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsLong.cs b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsLong.cs
index f4e45f50db..e5679f1638 100644
--- a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsLong.cs
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsLong.cs
@@ -13,6 +13,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Inlining
+{
public static class ConstantArgsLong
{
@@ -928,3 +930,4 @@ public static class ConstantArgsLong
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsSByte.cs b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsSByte.cs
index b329122967..0ec29b8341 100644
--- a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsSByte.cs
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsSByte.cs
@@ -13,6 +13,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Inlining
+{
public static class ConstantArgsSByte
{
@@ -928,3 +930,4 @@ public static class ConstantArgsSByte
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsShort.cs b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsShort.cs
index 8718111a72..f8cf23e8da 100644
--- a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsShort.cs
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsShort.cs
@@ -13,6 +13,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Inlining
+{
public static class ConstantArgsShort
{
@@ -928,3 +930,4 @@ public static class ConstantArgsShort
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsString.cs b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsString.cs
index b7319086d7..38a3f7e6b9 100644
--- a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsString.cs
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsString.cs
@@ -16,6 +16,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Inlining
+{
public static class ConstantArgsString
{
@@ -328,3 +330,4 @@ public static class ConstantArgsString
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsUInt.cs b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsUInt.cs
index db3316ea32..e3f6e2aae8 100644
--- a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsUInt.cs
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsUInt.cs
@@ -13,6 +13,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Inlining
+{
public static class ConstantArgsUInt
{
@@ -888,3 +890,4 @@ public static class ConstantArgsUInt
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsULong.cs b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsULong.cs
index 72087077e2..7585a3e1fc 100644
--- a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsULong.cs
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsULong.cs
@@ -13,6 +13,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Inlining
+{
public static class ConstantArgsULong
{
@@ -888,3 +890,4 @@ public static class ConstantArgsULong
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsUShort.cs b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsUShort.cs
index 249e985496..c96274e424 100644
--- a/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsUShort.cs
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/ConstantArgsUShort.cs
@@ -13,6 +13,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Inlining
+{
public static class ConstantArgsUShort
{
@@ -928,3 +930,4 @@ public static class ConstantArgsUShort
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/InlineGCStruct.cs b/tests/src/JIT/Performance/CodeQuality/Inlining/InlineGCStruct.cs
new file mode 100644
index 0000000000..660627cc72
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/InlineGCStruct.cs
@@ -0,0 +1,148 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+// In CoreCLR String.Format(ref, ref) is small and readily inlined.
+// The inline introduces a System.Parms GC struct local which is
+// untracked and must be zero initialized in the prolog. When the
+// inlined callsite is in a cold path, the inline hurts performance.
+//
+// There are two test methods below, one of which calls String.Format
+// on a cold path and the other which has similar structure but
+// does not call String.Format. Expectation is that they will have
+// similar performance.
+//
+// See https://github.com/dotnet/coreclr/issues/7569 for context.
+
+using Microsoft.Xunit.Performance;
+using System;
+using System.Runtime.CompilerServices;
+using Xunit;
+
+[assembly: OptimizeForBenchmarks]
+[assembly: MeasureInstructionsRetired]
+
+namespace Inlining
+{
+public class InlineGCStruct
+{
+#if DEBUG
+ public const int Iterations = 1;
+#else
+ public const int Iterations = 2500000;
+#endif
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static int FastFunctionNotCallingStringFormat(int param)
+ {
+ if (param < 0)
+ {
+ throw new Exception(String.Format("We do not like the value {0:N0}.", param));
+ }
+
+ if (param == int.MaxValue)
+ {
+ throw new Exception(String.Format("{0:N0} is maxed out.", param));
+ }
+
+ if (param > int.MaxValue / 2)
+ {
+ throw new Exception(String.Format("We do not like the value {0:N0} either.", param));
+ }
+
+ return param * 2;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static int FastFunctionNotHavingStringFormat(int param)
+ {
+ if (param < 0)
+ {
+ throw new ArgumentOutOfRangeException("param", "We do not like this value.");
+ }
+
+ if (param == int.MaxValue)
+ {
+ throw new ArgumentOutOfRangeException("param", "Maxed out.");
+ }
+
+ if (param > int.MaxValue / 2)
+ {
+ throw new ArgumentOutOfRangeException("param", "We do not like this value either.");
+ }
+
+ return param * 2;
+ }
+
+ [Benchmark]
+ public static bool WithFormat()
+ {
+ int result = 0;
+
+ foreach (var iteration in Benchmark.Iterations)
+ {
+ using (iteration.StartMeasurement())
+ {
+ for (int i = 0; i < Iterations; i++)
+ {
+ result |= FastFunctionNotCallingStringFormat(11);
+ }
+ }
+ }
+
+ return (result == 22);
+ }
+
+ [Benchmark]
+ public static bool WithoutFormat()
+ {
+ int result = 0;
+
+ foreach (var iteration in Benchmark.Iterations)
+ {
+ using (iteration.StartMeasurement())
+ {
+ for (int i = 0; i < Iterations; i++)
+ {
+ result |= FastFunctionNotHavingStringFormat(11);
+ }
+ }
+ }
+
+ return (result == 22);
+ }
+
+ public static bool WithoutFormatBase()
+ {
+ int result = 0;
+
+ for (int i = 0; i < Iterations; i++)
+ {
+ result |= FastFunctionNotHavingStringFormat(11);
+ }
+
+ return (result == 22);
+ }
+
+ public static bool WithFormatBase()
+ {
+ int result = 0;
+
+ for (int i = 0; i < Iterations; i++)
+ {
+ result |= FastFunctionNotCallingStringFormat(11);
+ }
+
+ return (result == 22);
+ }
+
+ public static int Main()
+ {
+ bool withFormat = WithFormatBase();
+ bool withoutFormat = WithoutFormatBase();
+
+ return (withFormat && withoutFormat ? 100 : -1);
+ }
+}
+}
+
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/InlineGCStruct.csproj b/tests/src/JIT/Performance/CodeQuality/Inlining/InlineGCStruct.csproj
new file mode 100644
index 0000000000..cb3381638c
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/InlineGCStruct.csproj
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="InlineGCStruct.cs" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Performance/CodeQuality/Inlining/NoThrowInline.cs b/tests/src/JIT/Performance/CodeQuality/Inlining/NoThrowInline.cs
index 9b689ce376..dc05f44b33 100644
--- a/tests/src/JIT/Performance/CodeQuality/Inlining/NoThrowInline.cs
+++ b/tests/src/JIT/Performance/CodeQuality/Inlining/NoThrowInline.cs
@@ -13,6 +13,8 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Inlining
+{
public static class NoThrowInline
{
#if DEBUG
@@ -34,7 +36,7 @@ public static class NoThrowInline
//
// We expect ThrowArgumentNullException to not be inlined into Bench, the throw code is pretty
- // large and throws are extremly slow. However, we need to be careful not to degrade the
+ // large and throws are extremly slow. However, we need to be careful not to degrade the
// non-exception path performance by preserving registers across the call. For this the compiler
// will have to understand that ThrowArgumentNullException never returns and omit the register
// preservation code.
@@ -73,3 +75,4 @@ public static class NoThrowInline
return (Bench("a", "bc", "def", "ghij") == 10) ? 100 : -1;
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/SIMD/ConsoleMandel/ConsoleMandel.cs b/tests/src/JIT/Performance/CodeQuality/SIMD/ConsoleMandel/ConsoleMandel.cs
index ed7f675700..5ab08202b6 100644
--- a/tests/src/JIT/Performance/CodeQuality/SIMD/ConsoleMandel/ConsoleMandel.cs
+++ b/tests/src/JIT/Performance/CodeQuality/SIMD/ConsoleMandel/ConsoleMandel.cs
@@ -11,9 +11,9 @@ using Xunit;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
-namespace ConsoleMandel
+namespace SIMD
{
- public static class Program
+ public static class ConsoleMandel
{
private const int Pass = 100;
private const int Fail = -1;
diff --git a/tests/src/JIT/Performance/CodeQuality/SIMD/RayTracer/RayTracerBench.cs b/tests/src/JIT/Performance/CodeQuality/SIMD/RayTracer/RayTracerBench.cs
index 064f860611..254672b462 100644
--- a/tests/src/JIT/Performance/CodeQuality/SIMD/RayTracer/RayTracerBench.cs
+++ b/tests/src/JIT/Performance/CodeQuality/SIMD/RayTracer/RayTracerBench.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.
//
-// Based on the Raytracer example from
-// Samples for Parallel Programming with the .NET Framework
+// Based on the Raytracer example from
+// Samples for Parallel Programming with the .NET Framework
// https://code.msdn.microsoft.com/windowsdesktop/Samples-for-Parallel-b4b76364
using Microsoft.Xunit.Performance;
@@ -16,6 +16,8 @@ using System.Collections.Concurrent;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace SIMD
+{
public class RayTracerBench
{
#if DEBUG
@@ -142,3 +144,4 @@ public class RayTracerBench
return (result ? 100 : -1);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/SIMD/SeekUnroll/SeekUnroll.cs b/tests/src/JIT/Performance/CodeQuality/SIMD/SeekUnroll/SeekUnroll.cs
new file mode 100644
index 0000000000..34c0ab888d
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/SIMD/SeekUnroll/SeekUnroll.cs
@@ -0,0 +1,159 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// 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.Xunit.Performance;
+using System;
+using System.Numerics;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Reflection;
+using System.Collections.Generic;
+using Xunit;
+
+[assembly: OptimizeForBenchmarks]
+[assembly: MeasureInstructionsRetired]
+
+public static class SeekUnroll
+{
+
+ // The purpose of this micro-benchmark is to measure the effect of unrolling
+ // on this loop (taken from https://github.com/aspnet/KestrelHttpServer/pull/1138)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ static int FindByte(ref Vector<byte> byteEquals)
+ {
+ var vector64 = Vector.AsVectorInt64(byteEquals);
+ long longValue = 0;
+ var i = 0;
+ for (; i < Vector<long>.Count; i++)
+ {
+ longValue = vector64[i];
+ if (longValue == 0) continue;
+ break;
+ }
+
+ // Flag least significant power of two bit
+ var powerOfTwoFlag = (ulong)(longValue ^ (longValue - 1));
+ // Shift all powers of two into the high byte and extract
+ var foundByteIndex = (int)((powerOfTwoFlag * _xorPowerOfTwoToHighByte) >> 57);
+ // Single LEA instruction with jitted const (using function result)
+ return i * 8 + foundByteIndex;
+ }
+
+ // Magic constant used in FindByte
+ const ulong _xorPowerOfTwoToHighByte = (0x07ul |
+ 0x06ul << 8 |
+ 0x05ul << 16 |
+ 0x04ul << 24 |
+ 0x03ul << 32 |
+ 0x02ul << 40 |
+ 0x01ul << 48) + 1;
+
+ // Inner loop to repeatedly call FindByte
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ static void InnerLoop(ref int foundIndex, ref Vector<Byte> vector)
+ {
+ for (int i = 0; i < InnerIterations; i++)
+ {
+ foundIndex = FindByte(ref vector);
+ }
+ }
+
+ // Iteration counts for inner loop set to have each call take 1 or
+ // 2 seconds or so in release, finish quickly in debug.
+#if DEBUG
+ const int InnerIterations = 1;
+#else
+ const int InnerIterations = 1000000000;
+#endif
+
+ // Function to meaure InnerLoop using the xunit-perf benchmark measurement facilities
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ static void XunitBenchmarkLoop(ref int foundIndex, ref Vector<Byte> vector)
+ {
+ foreach (var iteration in Benchmark.Iterations)
+ {
+ using (iteration.StartMeasurement())
+ {
+ InnerLoop(ref foundIndex, ref vector);
+ }
+ }
+ }
+
+ // Function to measure InnerLoop with manual use of a stopwatch timer
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ static void ManualTimerLoop(ref int foundIndex, ref Vector<Byte> vector)
+ {
+ for (int iteration = 0; iteration < ManualLoopTimes.Length; ++iteration)
+ {
+ var timer = System.Diagnostics.Stopwatch.StartNew();
+ InnerLoop(ref foundIndex, ref vector);
+ timer.Stop();
+ ManualLoopTimes[iteration] = timer.ElapsedMilliseconds;
+ }
+ }
+ static long[] ManualLoopTimes;
+
+ // Function that tests one input, dispatching to either the xunit-perf
+ // loop or the manual timer loop
+ static bool Test(int index, bool isXunitBenchmark)
+ {
+ if (index >= Vector<Byte>.Count)
+ {
+ // FindByte assumes index is in range
+ index = 0;
+ }
+ var bytes = new Byte[Vector<Byte>.Count];
+ bytes[index] = 255;
+ Vector<Byte> vector = new Vector<Byte>(bytes);
+
+ int foundIndex = -1;
+
+ if (isXunitBenchmark)
+ {
+ XunitBenchmarkLoop(ref foundIndex, ref vector);
+ }
+ else
+ {
+ ManualTimerLoop(ref foundIndex, ref vector);
+ }
+
+ Assert.Equal(index, foundIndex);
+ return (index == foundIndex);
+ }
+
+ // Set of indices to pass to Test(int, bool)
+ static int[] IndicesToTest = new int[] { 1, 3, 11, 19, 27 };
+
+ // Entrypoint for xunit-perf to call the benchmark
+ [Benchmark]
+ [MemberData(nameof(ArrayedBoxedIndicesToTest))]
+ public static bool Test(object boxedIndex)
+ {
+ return Test((int)boxedIndex, true);
+ }
+
+ // IndicesToTest wrapped up in arrays of boxes since that's
+ // what xunit-perf needs
+ public static IEnumerable<object[]> ArrayedBoxedIndicesToTest =
+ IndicesToTest.Select((int index) => new object[] { index });
+
+
+ // Main method entrypoint runs the manual timer loop
+ public static int Main()
+ {
+ int failures = 0;
+ foreach(int index in IndicesToTest)
+ {
+ ManualLoopTimes = new long[10];
+ bool passed = Test(index, false);
+ if (!passed)
+ {
+ ++failures;
+ }
+ Console.WriteLine("Index {0}, times (ms) [{1}]", index, String.Join(", ", ManualLoopTimes));
+ }
+
+ return 100 + failures;
+ }
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/SIMD/SeekUnroll/SeekUnroll.csproj b/tests/src/JIT/Performance/CodeQuality/SIMD/SeekUnroll/SeekUnroll.csproj
new file mode 100644
index 0000000000..53cfe42001
--- /dev/null
+++ b/tests/src/JIT/Performance/CodeQuality/SIMD/SeekUnroll/SeekUnroll.csproj
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{9AE6E18D-B3F9-4216-9809-125824387175}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="SeekUnroll.cs" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Performance/CodeQuality/Serialization/Deserialize.cs b/tests/src/JIT/Performance/CodeQuality/Serialization/Deserialize.cs
index b0ed00d40b..56fc2665ad 100644
--- a/tests/src/JIT/Performance/CodeQuality/Serialization/Deserialize.cs
+++ b/tests/src/JIT/Performance/CodeQuality/Serialization/Deserialize.cs
@@ -15,6 +15,8 @@ using Microsoft.Xunit.Performance;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Serialization
+{
public class JsonBenchmarks
{
@@ -26,7 +28,7 @@ public class JsonBenchmarks
public const int JsonNetIterations = 90000;
#endif
- const string DataContractXml = @"<JsonBenchmarks.TestObject xmlns=""http://schemas.datacontract.org/2004/07/"" xmlns:i=""http://www.w3.org/2001/XMLSchema-instance""><Id>33</Id><Name>SqMtx</Name><Results xmlns:a=""http://schemas.microsoft.com/2003/10/Serialization/Arrays""><a:double>101.3</a:double><a:double>99.8</a:double><a:double>99.6</a:double><a:double>100.4</a:double></Results><WhenRun>2015-01-01T00:00:00-08:00</WhenRun></JsonBenchmarks.TestObject>";
+ const string DataContractXml = @"<JsonBenchmarks.TestObject xmlns=""http://schemas.datacontract.org/2004/07/Serialization"" xmlns:i=""http://www.w3.org/2001/XMLSchema-instance""><Id>33</Id><Name>SqMtx</Name><Results xmlns:a=""http://schemas.microsoft.com/2003/10/Serialization/Arrays""><a:double>101.3</a:double><a:double>99.8</a:double><a:double>99.6</a:double><a:double>100.4</a:double></Results><WhenRun>2015-01-01T00:00:00-08:00</WhenRun></JsonBenchmarks.TestObject>";
const string DataContractJson = @"{""Id"":33,""Name"":""SqMtx"",""Results"":[101.3,99.8,99.6,100.4],""WhenRun"":""\/Date(1420099200000-0800)\/""}";
@@ -83,7 +85,7 @@ public class JsonBenchmarks
}
[Benchmark]
- private void DeserializeDataContract()
+ private void DeserializeDataContract()
{
foreach (var iteration in Benchmark.Iterations) {
using (iteration.StartMeasurement()) {
@@ -199,3 +201,4 @@ public class JsonBenchmarks
return result ? 100 : -1;
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/Serialization/Serialize.cs b/tests/src/JIT/Performance/CodeQuality/Serialization/Serialize.cs
index 905cf56584..39ab5876c9 100644
--- a/tests/src/JIT/Performance/CodeQuality/Serialization/Serialize.cs
+++ b/tests/src/JIT/Performance/CodeQuality/Serialization/Serialize.cs
@@ -14,6 +14,8 @@ using Microsoft.Xunit.Performance;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
+namespace Serialization
+{
public class JsonBenchmarks
{
@@ -72,7 +74,7 @@ public class JsonBenchmarks
}
[Benchmark]
- private void SerializeDataContract()
+ private void SerializeDataContract()
{
foreach (var iteration in Benchmark.Iterations) {
using (iteration.StartMeasurement()) {
@@ -186,3 +188,4 @@ public class JsonBenchmarks
return result ? 100 : -1;
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/V8/Crypto/Crypto.cs b/tests/src/JIT/Performance/CodeQuality/V8/Crypto/Crypto.cs
index 23eab8db5b..620e012848 100644
--- a/tests/src/JIT/Performance/CodeQuality/V8/Crypto/Crypto.cs
+++ b/tests/src/JIT/Performance/CodeQuality/V8/Crypto/Crypto.cs
@@ -46,7 +46,7 @@ using System.Globalization;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
-namespace Crypto
+namespace V8.Crypto
{
public class Support
{
diff --git a/tests/src/JIT/Performance/CodeQuality/V8/DeltaBlue/DeltaBlue.cs b/tests/src/JIT/Performance/CodeQuality/V8/DeltaBlue/DeltaBlue.cs
index ee14b8b1b1..27f77182b2 100644
--- a/tests/src/JIT/Performance/CodeQuality/V8/DeltaBlue/DeltaBlue.cs
+++ b/tests/src/JIT/Performance/CodeQuality/V8/DeltaBlue/DeltaBlue.cs
@@ -24,13 +24,15 @@ using System.Collections;
[assembly: OptimizeForBenchmarks]
[assembly: MeasureInstructionsRetired]
-/*
+/*
Strengths are used to measure the relative importance of constraints.
New strengths may be inserted in the strength hierarchy without
disrupting current constraints. Strengths cannot be created outside
this class, so pointer comparison can be used for value comparison.
*/
+namespace V8
+{
internal class Strength
{
private int _strengthValue;
@@ -1066,3 +1068,4 @@ public class deltablue
throw new Exception(s);
}
}
+}
diff --git a/tests/src/JIT/Performance/CodeQuality/V8/Richards/Richards.cs b/tests/src/JIT/Performance/CodeQuality/V8/Richards/Richards.cs
index 6d26593e2f..5095d22ad7 100644
--- a/tests/src/JIT/Performance/CodeQuality/V8/Richards/Richards.cs
+++ b/tests/src/JIT/Performance/CodeQuality/V8/Richards/Richards.cs
@@ -20,7 +20,7 @@ using System.Collections.Generic;
// using System.Diagnostics;
// using System.Text.RegularExpressions;
-namespace Richards
+namespace V8.Richards
{
/// <summary>
/// Support is used for a place to generate any 'miscellaneous' methods generated as part
@@ -501,7 +501,7 @@ namespace Richards
public
#if !INTF_FOR_TASK
- override
+ override
#endif
TaskControlBlock run(Packet packet)
{
@@ -521,7 +521,7 @@ namespace Richards
public
#if !INTF_FOR_TASK
- override
+ override
#endif
String toString()
{
@@ -548,7 +548,7 @@ namespace Richards
public
#if !INTF_FOR_TASK
- override
+ override
#endif
TaskControlBlock run(Packet packet)
{
@@ -568,7 +568,7 @@ namespace Richards
public
#if !INTF_FOR_TASK
- override
+ override
#endif
String toString()
{
@@ -598,7 +598,7 @@ namespace Richards
public
#if !INTF_FOR_TASK
- override
+ override
#endif
TaskControlBlock run(Packet packet)
{
@@ -630,7 +630,7 @@ namespace Richards
public
#if !INTF_FOR_TASK
- override
+ override
#endif
String toString()
{
@@ -658,7 +658,7 @@ namespace Richards
public
#if !INTF_FOR_TASK
- override
+ override
#endif
TaskControlBlock run(Packet packet)
{
@@ -700,7 +700,7 @@ namespace Richards
public
#if !INTF_FOR_TASK
- override
+ override
#endif
String toString()
{
diff --git a/tests/src/JIT/Performance/RunBenchmarks/RunBenchmarks.cmd b/tests/src/JIT/Performance/RunBenchmarks/RunBenchmarks.cmd
index e85e226392..e7b8917757 100644
--- a/tests/src/JIT/Performance/RunBenchmarks/RunBenchmarks.cmd
+++ b/tests/src/JIT/Performance/RunBenchmarks/RunBenchmarks.cmd
@@ -9,7 +9,7 @@
@rem of the enlistment(repo). It also requires that CoreCLR has been built,
@rem and that all CoreCLR tests have been built.
@rem
-@rem The preformance harness "RunBencchmarks.exe" is built as a test case
+@rem The preformance harness "RunBenchmarks.exe" is built as a test case
@rem as are all the performance tests it runs.
@rem
@rem For the ByteMark tests, it must copy the command scripts to the
diff --git a/tests/src/JIT/Performance/RunBenchmarks/RunBenchmarks.sh b/tests/src/JIT/Performance/RunBenchmarks/RunBenchmarks.sh
new file mode 100755
index 0000000000..ee709164c9
--- /dev/null
+++ b/tests/src/JIT/Performance/RunBenchmarks/RunBenchmarks.sh
@@ -0,0 +1,53 @@
+# ***************************************************************************
+# RunBenchmarks.sh
+#
+# This is a sample script for how to run benchmarks on Unix-like system.
+#
+# It requires the user to set CORECLR_ROOT to the root directory
+# of the enlistment(repo). It also requires that CoreCLR has been built,
+# and that all CoreCLR tests have been built.
+#
+# The preformance harness "RunBenchmarks.exe" is built as a test case
+# as are all the performance tests it runs.
+#
+# For the ByteMark tests, it must copy the command scripts to the
+# binary directory for the tests.
+#
+# By default, the performance harness is run on top of CoreCLR. There
+# is a commented out section that can be used to run on top of DesktopCLR.
+#
+# A standard benchmark run is done with one warmup run, and five iterations
+# of the benchmark.
+#
+# ***************************************************************************
+
+ARCH=${1:-x64}
+BUILD=${2:-Release}
+
+CORERUN=${CORERUN:-corerun}
+
+# *** set this appropriately for enlistment you are running benchmarks in
+
+if [ -z "$CORECLR_ROOT" ]; then
+ echo "You must set CORECLR_ROOT to be the root of your coreclr repo (e.g. /git/repos/coreclr)"
+ exit 1
+fi
+
+# *** Currently we can build test cases only on Windows, so "Windows_NT" is hard-coded in the variables.
+BENCHMARK_ROOT_DIR="$CORECLR_ROOT/bin/tests/Windows_NT.$ARCH.$BUILD/JIT/Performance/CodeQuality"
+BENCHMARK_SRC_DIR="$CORECLR_ROOT/tests/src/JIT/Performance/RunBenchmarks"
+BENCHMARK_HOST="$CORERUN $CORECLR_ROOT/bin/tests/Windows_NT.$ARCH.$BUILD/JIT/Performance/RunBenchmarks/RunBenchmarks/RunBenchmarks.exe"
+BENCHMARK_RUNNER="-runner $CORERUN"
+
+# *** need to copy command files for Bytemark
+mkdir -p ${BENCHMARK_ROOT_DIR}/Bytemark/Bytemark
+cp -rf $CORECLR_ROOT/tests/src/JIT/Performance/CodeQuality/Bytemark/commands ${BENCHMARK_ROOT_DIR}/Bytemark/Bytemark/commands
+
+BENCHMARK_CONTROLS="-run -v -w -n 5"
+BENCHMARK_SET="-f $BENCHMARK_SRC_DIR/coreclr_benchmarks.xml -notags broken"
+BENCHMARK_OUTPUT="-csvfile $BENCHMARK_SRC_DIR/coreclr_benchmarks.csv"
+BENCHMARK_SWITCHES="$BENCHMARK_CONTROLS -r $BENCHMARK_ROOT_DIR"
+
+echo "$BENCHMARK_HOST $BENCHMARK_RUNNER $BENCHMARK_SET $BENCHMARK_OUTPUT $BENCHMARK_SWITCHES"
+$BENCHMARK_HOST $BENCHMARK_RUNNER $BENCHMARK_SET $BENCHMARK_OUTPUT $BENCHMARK_SWITCHES
+
diff --git a/tests/src/JIT/Regression/CLR-x86-JIT/V2.0-RTM/b475589/b475589.il b/tests/src/JIT/Regression/CLR-x86-JIT/V2.0-RTM/b475589/b475589.il
deleted file mode 100644
index dce3d692f8..0000000000
--- a/tests/src/JIT/Regression/CLR-x86-JIT/V2.0-RTM/b475589/b475589.il
+++ /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.
-
-.assembly extern System.Console
-{
- .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )
- .ver 4:0:0:0
-}
-
-.assembly extern mscorlib { auto }
-.assembly b475598 {}
-.module b475589.exe
-
-.class Program
-{
- .method static void Nasty()
- {
- .maxstack 2
-
- call void [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::PrepareConstrainedRegions()
- br start_try
-
- start_catch:
- ldstr "Cathed!"
- call void [System.Console]System.Console::WriteLine(string)
- leave.s end
- end_catch:
-
- start_try:
- newobj instance void [mscorlib]System.Exception::.ctor()
- throw
- end_try:
-
- end:
- ret
-
- .try start_try to end_try catch [mscorlib]System.Exception handler start_catch to end_catch
- }
- .method static int32 Main(string[] args)
- {
- .maxstack 2
- .entrypoint
-
-
- start_try:
-
- call void Program::Nasty()
- leave.s end_failure
-
- end_try:
- start_catch:
-
- leave.s end_success
- end_catch:
-
- end_success:
- ldstr "Test SUCCESS"
- call void [System.Console]System.Console::WriteLine(string)
- ldc.i4 100
- ret
-
- end_failure:
- ldstr "Test FAILURE"
- call void [System.Console]System.Console::WriteLine(string)
- ldc.i4 -1
- ret
-
- .try start_try to end_try catch [mscorlib]System.NotSupportedException handler start_catch to end_catch
- }
-} \ No newline at end of file
diff --git a/tests/src/JIT/Regression/CLR-x86-JIT/V2.0-RTM/b475589/b475589.ilproj b/tests/src/JIT/Regression/CLR-x86-JIT/V2.0-RTM/b475589/b475589.ilproj
deleted file mode 100644
index 14ed64f690..0000000000
--- a/tests/src/JIT/Regression/CLR-x86-JIT/V2.0-RTM/b475589/b475589.ilproj
+++ /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>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <AssemblyName>$(MSBuildProjectName)</AssemblyName>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <FileAlignment>512</FileAlignment>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
- <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
- <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
- </PropertyGroup>
- <!-- Default configurations to help VS understand the configurations -->
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- </PropertyGroup>
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
- <PropertyGroup>
-
- </PropertyGroup>
- <ItemGroup>
- <Compile Include="b475589.il" />
- </ItemGroup>
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
- <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
- </PropertyGroup>
-</Project> \ No newline at end of file
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_142976/DevDiv_142976.cs b/tests/src/JIT/Regression/JitBlue/DevDiv_142976/DevDiv_142976.cs
new file mode 100644
index 0000000000..7b0151793b
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_142976/DevDiv_142976.cs
@@ -0,0 +1,56 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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;
+
+// This test case is meant to test an optimization in morph that
+// transforms helper call JIT_Stelem_Ref(a, null, i) to a[i] = null,
+// which further gets transformed into an array address and bounds
+// check nodes with references to the array local and the index
+// local. It is expected while doing such a transform, array
+// local and index local are appropriately ref counted and Value
+// number is updated post-global-morph and jit compilation
+// won't run into any asserts.
+class DevDiv_142976
+{
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static String Foo()
+ {
+ return null;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void Bar()
+ {
+ String[] args = new String[10];
+ if (args != null)
+ {
+ throw new Exception();
+ }
+
+ String s = Foo();
+ if (s == null)
+ {
+ // This will result in JIT_Stelem_Ref(args, null, 0) call
+ // which gets re-morphed into args[0] = null.
+ args[0] = s;
+ }
+ }
+
+ public static int Main()
+ {
+ try
+ {
+ Bar();
+ }
+ catch (Exception)
+ {
+ }
+
+ Console.WriteLine("Pass");
+ return 100;
+ }
+} \ No newline at end of file
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_142976/DevDiv_142976.csproj b/tests/src/JIT/Regression/JitBlue/DevDiv_142976/DevDiv_142976.csproj
new file mode 100644
index 0000000000..0c1a10eb95
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_142976/DevDiv_142976.csproj
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType></DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="DevDiv_142976.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)minimal\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)minimal\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_255294/DevDiv_255294.cs b/tests/src/JIT/Regression/JitBlue/DevDiv_255294/DevDiv_255294.cs
new file mode 100644
index 0000000000..05f1d90aac
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_255294/DevDiv_255294.cs
@@ -0,0 +1,62374 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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;
+
+public class Test
+{
+ static bool f;
+
+ public static int Main()
+ {
+ f = true;
+ Test test = new Test();
+ return test.HugeMethod();
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public int HugeMethod()
+ {
+ int i = 0;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+ if (f) i++;
+
+ return i - 62248;
+ }
+}
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_255294/DevDiv_255294.csproj b/tests/src/JIT/Regression/JitBlue/DevDiv_255294/DevDiv_255294.csproj
new file mode 100644
index 0000000000..9027bb5c54
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_255294/DevDiv_255294.csproj
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType></DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="DevDiv_255294.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)minimal\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)minimal\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_278365/DevDiv_278365.cs b/tests/src/JIT/Regression/JitBlue/DevDiv_278365/DevDiv_278365.cs
new file mode 100644
index 0000000000..631175a38e
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_278365/DevDiv_278365.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.CompilerServices;
+
+// This test is a reduced repro case for DevDiv VSO bug 278365.
+// The failure mode is that the RyuJIT/x86 backend changed call to ROUND intrinsic
+// with double return type to ROUND intrinsic with int return type, that is not supported.
+
+internal class Program
+{
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static int Bar()
+ {
+ int sum = 0;
+ for (int i = 0; i < 100; ++i)
+ {
+ int v = (int)Math.Round(4.4 + i);
+ sum += v;
+ }
+ sum -= 4 * 100;
+ if (sum != 100 * 99 / 2)
+ {
+ return 0;
+ }
+ else
+ {
+ return 100;
+ }
+ }
+
+ private static int Main(string[] args)
+ {
+ try
+ {
+ if (Bar() != 100)
+ return 0;
+ }
+ catch (Exception)
+ {
+ }
+
+ Console.WriteLine("Pass");
+ return 100;
+ }
+}
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_278365/DevDiv_278365.csproj b/tests/src/JIT/Regression/JitBlue/DevDiv_278365/DevDiv_278365.csproj
new file mode 100644
index 0000000000..0abcfd8a28
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_278365/DevDiv_278365.csproj
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType></DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="DevDiv_278365.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)minimal\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)minimal\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_278369/DevDiv_278369.il b/tests/src/JIT/Regression/JitBlue/DevDiv_278369/DevDiv_278369.il
new file mode 100644
index 0000000000..cf077786d9
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_278369/DevDiv_278369.il
@@ -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 test checks that value numbering does not incorrectly propagate the value number for an operand to its
+// consuming operator unless the type of the operand and the operator agree.
+//
+// In particular, in the body of method N, the optimizer will fold the two `ceq` conditions together using a logical
+// or of type int32. Value numbering will then determine that one operand to the logical or is a constant `0` (namely,
+// the result of `ldloc.0` and attempt to propagate the value number of the logical or's other operand to the logical
+// or itself. This should not succeed, as the type of the logical or is int32 and the type of its non-zero operand is
+// `ref`.
+
+.assembly extern mscorlib {}
+
+.assembly r {}
+
+.class private auto ansi beforefieldinit C extends [mscorlib]System.Object
+{
+ .method private hidebysig static int32 N(object o) cil managed noinlining
+ {
+ .locals (int32)
+
+ ldc.i4.0
+ stloc.0
+ ldarg.0
+ isinst C
+ ldnull
+ ceq
+ brfalse.s label
+ ldloc.0
+ ldc.i4.0
+ ceq
+ brfalse.s label
+ ldc.i4.s 0
+ ret
+
+label:
+ ldc.i4 100
+ ret
+ }
+
+ .method private hidebysig static int32 Main(string[] args) cil managed
+ {
+ .entrypoint
+
+ newobj instance void C::.ctor()
+ call int32 C::N(object)
+ ret
+ }
+
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ldarg.0
+ call instance void [mscorlib]System.Object::.ctor()
+ ret
+ }
+}
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_278369/DevDiv_278369.ilproj b/tests/src/JIT/Regression/JitBlue/DevDiv_278369/DevDiv_278369.ilproj
new file mode 100644
index 0000000000..deebeec0d1
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_278369/DevDiv_278369.ilproj
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT .0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="DevDiv_278369.il" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_278371/DevDiv_278371.il b/tests/src/JIT/Regression/JitBlue/DevDiv_278371/DevDiv_278371.il
new file mode 100644
index 0000000000..447392e1fd
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_278371/DevDiv_278371.il
@@ -0,0 +1,88 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+// Test for a bug involving an initblk with a non-constant size,
+// which uses rep movs on x86 (x64 uses a helper call).
+
+.assembly extern legacy library mscorlib {}
+.assembly extern System.Console
+{
+ .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )
+ .ver 4:0:0:0
+}
+
+.assembly DevDiv_278371 {}
+
+.class public sequential ansi sealed beforefieldinit S
+ extends [mscorlib]System.ValueType
+{
+ .field public uint32 val
+} // end of class S
+
+.class private auto ansi beforefieldinit Program
+ extends [mscorlib]System.Object
+{
+ .method public hidebysig static void Init(valuetype S& s,
+ int32 size) cil managed noinlining
+ {
+ nop
+ ldarg.0
+ ldc.i4 0xaa
+ ldarg.1
+ initblk
+ ret
+ } // end of method Program::Init
+
+ .method private hidebysig static int32
+ Main() cil managed
+ {
+ .entrypoint
+ .locals init (valuetype S V_0,
+ bool V_1,
+ int32 V_2)
+ ldloca.s V_0
+ initobj S
+ ldloca.s V_0
+ ldc.i4 4
+ call void Program::Init(valuetype S&, int32)
+ ldloc.0
+ ldfld uint32 S::val
+ ldc.i4 0xaaaaaaaa
+ ceq
+ ldc.i4.0
+ ceq
+ stloc.1
+ ldloc.1
+ brfalse.s L1
+
+ ldstr "Fail"
+ call void [mscorlib]System.Console::WriteLine(string)
+ nop
+ ldc.i4.m1
+ stloc.2
+ br.s L2
+
+ L1: ldstr "Pass"
+ call void [mscorlib]System.Console::WriteLine(string)
+ nop
+ ldc.i4.s 100
+ stloc.2
+
+ L2: ldloc.2
+ ret
+ } // end of method Program::Main
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 8 (0x8)
+ .maxstack 8
+ ldarg.0
+ call instance void [mscorlib]System.Object::.ctor()
+ nop
+ ret
+ } // end of method Program::.ctor
+
+} // end of class Program
+
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_278371/DevDiv_278371.ilproj b/tests/src/JIT/Regression/JitBlue/DevDiv_278371/DevDiv_278371.ilproj
new file mode 100644
index 0000000000..11cfb62342
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_278371/DevDiv_278371.ilproj
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="DevDiv_278371.il" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_278372/DevDiv_278372.il b/tests/src/JIT/Regression/JitBlue/DevDiv_278372/DevDiv_278372.il
new file mode 100644
index 0000000000..1081877171
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_278372/DevDiv_278372.il
@@ -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.
+
+// This test is a reduced repro case for DevDiv VSO bug 278372.
+// The failure mode is that the RyuJIT/x86 backend was not correctly
+// handling the case of a variable involving a variable V such that:
+// - V is lvMustInit (therefore it must be undefined on some path)
+// - V lives in multiple registers, but never on the stack
+// - there is at least one other variable that is also lvMustInit, but that
+// has a stack location.
+//
+// In this case, genFnProlog was attempting to zero-init V on the stack.
+//
+// It was difficult to construct a repro; this repro requires that the test
+// be run with COMPlus_JitStressRegs=0x200 (which changes the location of
+// variables at block boundaries).
+
+
+// Metadata version: v4.0.30319
+.assembly extern System.Runtime
+{
+ .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....:
+ .ver 4:1:0:0
+}
+.assembly extern System.Console
+{
+ .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....:
+ .ver 4:0:0:0
+}
+.assembly DevDiv_278372
+{
+}
+
+// =============== CLASS MEMBERS DECLARATION ===================
+
+.class private auto ansi beforefieldinit DevDiv_278372
+ extends [System.Runtime]System.Object
+{
+ .method public hidebysig static bool check(int32& dummy) cil managed noinlining
+ {
+ ldc.i4.1
+ ret
+ } // end of method DevDiv_278372::check
+
+ .method public hidebysig static int32 getX() cil managed noinlining
+ {
+ ldc.i4.s 25
+ ret
+ } // end of method DevDiv_278372::getX
+
+ .method public hidebysig static int32 getY() cil managed noinlining
+ {
+ ldc.i4.5
+ ret
+ } // end of method DevDiv_278372::getY
+
+ .method public hidebysig static int32 Test(int32 x,
+ int32 y,
+ int32 x2,
+ int32 y2,
+ int32 x3,
+ int32 y3) cil managed noinlining
+ {
+ .maxstack 2
+ .locals init ([0] int32 z,
+ [1] int32 returnVal,
+ [2] int32 dummy,
+ [3] int32 z2)
+
+ // Initialize returnVal to 100
+ ldc.i4.s 100
+ stloc.1
+
+ // Here we pass the address of "dummy" to ensure that we have a must-init on-stack variable.
+ ldloca.s dummy
+ call bool DevDiv_278372::check(int32&)
+ brfalse.s L1
+
+ // Here we are conditionally defining "z", so that it will be must-init
+ ldarg.0
+ ldarg.1
+ rem
+ stloc.0
+ L1: ldloc.0
+ brfalse.s L2
+
+ ldc.i4.m1
+ stloc.1
+ L2: ldarg.2
+ ldarg.3
+ rem
+ stloc.3
+ ldarg.0
+ ldarg.1
+ add
+ stloc.0
+ ldloc.0
+ ldc.i4.s 30
+ beq.s L3
+
+ ldc.i4.m1
+ stloc.1
+ L3: ldloc.3
+ brfalse.s L4
+
+ ldc.i4.m1
+ stloc.1
+ L4: ldloc.1
+ ldc.i4.s 100
+ bne.un.s L5
+
+ ldstr "Pass"
+ call void [System.Console]System.Console::WriteLine(string)
+ br.s L6
+
+ L5: ldstr "Fail"
+ call void [System.Console]System.Console::WriteLine(string)
+ L6: ldloc.1
+ ret
+ } // end of method DevDiv_278372::Test
+
+ .method public hidebysig static int32 Main() cil managed
+ {
+ .entrypoint
+ // Code size 16 (0x10)
+ .maxstack 8
+ ldc.i4.s 25
+ ldc.i4.5
+ ldc.i4.s 25
+ ldc.i4.5
+ ldc.i4.s 25
+ ldc.i4.5
+ call int32 DevDiv_278372::Test(int32,
+ int32,
+ int32,
+ int32,
+ int32,
+ int32)
+ ret
+ } // end of method DevDiv_278372::Main
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ ldarg.0
+ call instance void [System.Runtime]System.Object::.ctor()
+ ret
+ } // end of method DevDiv_278372::.ctor
+
+} // end of class DevDiv_278372
+
+
+// =============================================================
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_278372/DevDiv_278372.ilproj b/tests/src/JIT/Regression/JitBlue/DevDiv_278372/DevDiv_278372.ilproj
new file mode 100644
index 0000000000..f3da12d5f0
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_278372/DevDiv_278372.ilproj
@@ -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">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="DevDiv_278372.il" />
+ </ItemGroup>
+ <PropertyGroup>
+ <CLRTestBatchPreCommands><![CDATA[
+$(CLRTestBatchPreCommands)
+set COMPlus_JitStressRegs=0x200
+]]></CLRTestBatchPreCommands>
+ <BashCLRTestPreCommands><![CDATA[
+$(BashCLRTestPreCommands)
+export COMPlus_JitStressRegs=0x200
+]]></BashCLRTestPreCommands>
+ </PropertyGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_278375/DevDiv_278375.cs b/tests/src/JIT/Regression/JitBlue/DevDiv_278375/DevDiv_278375.cs
new file mode 100644
index 0000000000..ecd7e7fa38
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_278375/DevDiv_278375.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.CompilerServices;
+
+struct MyStruct
+{
+ // Struct containing 4 fields, 3 of which are longs that will be decomposed.
+ // The bug was that this resulted in 7 input registers to the GT_FIELD_LIST
+ // parameter, which can't be accommodated by the register allocator.
+
+ public MyStruct(long l1, long l2, long l3, int i)
+ {
+ f1 = l1;
+ f2 = l2;
+ f3 = l3;
+ f4 = new int[i];
+ f4[0] = i;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static MyStruct newMyStruct(long l1, long l2, long l3, int i)
+ {
+ return new MyStruct(l1, l2, l3, i);
+ }
+
+ public long f1;
+ public long f2;
+ public long f3;
+ public int[] f4;
+}
+
+struct MyStruct2
+{
+ // This is a variation that includes a double field, to ensure that a mix of
+ // field types are supported.
+ public MyStruct2(long l1, long l2, double d, int i)
+ {
+ f1 = l1;
+ f2 = l2;
+ f3 = d;
+ f4 = new int[i];
+ f4[0] = i;
+ }
+
+ public long f1;
+ public long f2;
+ public double f3;
+ public int[] f4;
+}
+
+struct MyStruct3
+{
+ // And finally one that includes longs and a double, but no ref.
+ public MyStruct3(long l1, long l2, double d, int i)
+ {
+ f1 = l1;
+ f2 = l2;
+ f3 = d;
+ f4 = i;
+ }
+
+ public long f1;
+ public long f2;
+ public double f3;
+ public int f4;
+}
+
+class Program
+{
+
+ static int Pass = 100;
+ static int Fail = -1;
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static int AddFields(MyStruct s)
+ {
+ return (int)(s.f1 + s.f2 + s.f3 + s.f4[0]);
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static int AddFields2(MyStruct2 s)
+ {
+ return (int)(s.f1 + s.f2 + (int)s.f3 + s.f4[0]);
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static int AddFields3(MyStruct3 s)
+ {
+ return (int)(s.f1 + s.f2 + (int)s.f3 + s.f4);
+ }
+
+ static int Main(string[] args)
+ {
+ int returnVal = Pass;
+ MyStruct s = new MyStruct(1, 2, 3, 4);
+ int sum = AddFields(s);
+ if (sum != 10)
+ {
+ Console.WriteLine("Failed first call");
+ returnVal = Fail;
+ }
+ s = MyStruct.newMyStruct(1, 2, 3, 4);
+ sum = AddFields(s);
+ if (sum != 10)
+ {
+ Console.WriteLine("Failed second call");
+ returnVal = Fail;
+ }
+ MyStruct2 s2 = new MyStruct2(1, 2, 3.0, 4);
+ sum = AddFields2(s2);
+ if (sum != 10)
+ {
+ Console.WriteLine("Failed third call");
+ returnVal = Fail;
+ }
+ MyStruct3 s3 = new MyStruct3(1, 2, 3.0, 4);
+ sum = AddFields3(s3);
+ if (sum != 10)
+ {
+ Console.WriteLine("Failed fourth call");
+ returnVal = Fail;
+ }
+ if (returnVal == Pass)
+ {
+ Console.WriteLine("Pass");
+ }
+ return returnVal;
+ }
+} \ No newline at end of file
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_278375/DevDiv_278375.csproj b/tests/src/JIT/Regression/JitBlue/DevDiv_278375/DevDiv_278375.csproj
new file mode 100644
index 0000000000..9477984ab9
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_278375/DevDiv_278375.csproj
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType></DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="DevDiv_278375.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)minimal\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)minimal\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_278376/DevDiv_278376.cs b/tests/src/JIT/Regression/JitBlue/DevDiv_278376/DevDiv_278376.cs
new file mode 100644
index 0000000000..63e3d29f7a
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_278376/DevDiv_278376.cs
@@ -0,0 +1,36 @@
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// NOTE: the bug for this test was an assertion in RyuJIT/x86 when generating code for a double-returning call that
+// was spilled by the RA and subsequently used. The call in question is the call to `C.GetDouble` in `C.Test`.
+// To ensure that its return value is spilled, `C.GetDouble` is implemented as a P/Invoke method: the return
+// value ends up spilled because there is a call to `TrapReturningThreads` between the call and the use of the
+// return value by the cast. Because the bug is a simple assert, there is no need for the problematic code to
+// actually run, so the implementation of `GetDouble` does not need to actually exist.
+
+sealed class C
+{
+ [DllImport("nonexistent.dll")]
+ extern static double GetDouble();
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static void UseDouble(double d)
+ {
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static int Test(bool condition)
+ {
+ if (condition)
+ {
+ UseDouble((double)GetDouble());
+ }
+
+ return 100;
+ }
+
+ static int Main(string[] args)
+ {
+ return Test(false);
+ }
+}
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_278376/DevDiv_278376.csproj b/tests/src/JIT/Regression/JitBlue/DevDiv_278376/DevDiv_278376.csproj
new file mode 100644
index 0000000000..90327b2a5d
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_278376/DevDiv_278376.csproj
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType></DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="DevDiv_278376.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)minimal\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)minimal\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_278523/DevDiv_278523.il b/tests/src/JIT/Regression/JitBlue/DevDiv_278523/DevDiv_278523.il
new file mode 100644
index 0000000000..9c9ba4946c
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_278523/DevDiv_278523.il
@@ -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.
+
+.assembly extern mscorlib {}
+.assembly a {}
+.module a.exe
+
+// This test originally triggered an assert when computing the value number for a block assignment. In particular, the
+// VN framework expected any block assignments to a tracked lclVar to have a destination address of the form
+// `(addr (lclVar))` or `(addr (lclFld))`. The check that it was using to determine whether or not a block assignment
+// targets a lclVar also admitted addresses formed by some combination of adds of constants to these patterns (e.g.
+// `(add (const 4) (add (addr lclVar) (const 4)))`. The bits of IL that trigger the assert are called out in the method
+// bodies below. They differ for 32- and 64-bit targets because on 64-bit targets, the importer will insert an
+// int->long conversion when adding a constant int to any long. Due to the cast, the resulting IR is not considered to
+// be an add of a constant and a lclVar address. In order to repro the bug on a 64-bit target, the input IL must
+// directly produce a long constant.
+
+.class private sequential ansi sealed beforefieldinit S extends [mscorlib]System.ValueType
+{
+ .field public uint8 m_fld
+ .field public uint8 m_fld1
+ .field public uint8 m_fld2
+ .field public uint8 m_fld3
+ .field public uint8 m_fld4
+ .field public uint8 m_fld5
+ .field public uint8 m_fld6
+}
+
+.class private sequential ansi sealed beforefieldinit T extends [mscorlib]System.ValueType
+{
+ .field public int32 m_int
+ .field public valuetype S m_fld
+}
+
+.class private abstract auto ansi sealed beforefieldinit C extends [mscorlib]System.Object
+{
+ .method private static int32 Test32Bit(int32 i) noinlining
+ {
+ .locals init (valuetype S V_0, valuetype T V_1)
+
+ ldloca.s V_0
+ ldarg.0
+ conv.u1
+ stfld uint8 S::m_fld6
+
+ // This sequence of IL repros the issue.
+ ldloca.s V_1
+ ldc.i4.4
+ add
+ ldloc.0
+ stobj S
+
+ ldloca.s V_1
+ ldfld valuetype S T::m_fld
+ ldfld uint8 S::m_fld6
+ conv.i4
+ ret
+ }
+
+ .method private static int32 Test64Bit(int32 i) noinlining
+ {
+ .locals init (valuetype S V_0, valuetype T V_1)
+
+ ldloca.s V_0
+ ldarg.0
+ conv.u1
+ stfld uint8 S::m_fld6
+
+ // This sequence of IL repros the issue. Note that the `ldc.i8` is necessary (rather than an `ldc.i4` that is
+ // implicitly converted to a long byt the `add`).
+ ldloca.s V_1
+ ldc.i8 4
+ add
+ ldloc.0
+ stobj S
+
+ ldloca.s V_1
+ ldfld valuetype S T::m_fld
+ ldfld uint8 S::m_fld6
+ conv.i4
+ ret
+ }
+
+ .method private static int32 Main()
+ {
+ .entrypoint
+ .locals init (int32 V_0)
+
+ ldc.i4 100
+ dup
+
+ sizeof [mscorlib]System.IntPtr
+ ldc.i4 8
+ beq.s _64bit
+
+ call int32 C::Test32Bit(int32)
+ bne.un.s fail
+ br.s success
+
+_64bit:
+ call int32 C::Test64Bit(int32)
+ bne.un.s fail
+
+success:
+ ldc.i4 100
+ ret
+
+fail:
+ ldc.i4 101
+ ret
+ }
+}
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_278523/DevDiv_278523.ilproj b/tests/src/JIT/Regression/JitBlue/DevDiv_278523/DevDiv_278523.ilproj
new file mode 100644
index 0000000000..d4cfe45c95
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_278523/DevDiv_278523.ilproj
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT .0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="DevDiv_278523.il" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_278526/DevDiv_278526.cs b/tests/src/JIT/Regression/JitBlue/DevDiv_278526/DevDiv_278526.cs
new file mode 100644
index 0000000000..e3c494b66d
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_278526/DevDiv_278526.cs
@@ -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.
+
+// This test was originally a repro for an assertion regarding incorrect value number of the tree in cse.
+// The repro requires that the tree and its child are considered by cse and child is binary sub (a - b).
+// Cse calls morph of the parent tree and morphs child to (a + (-b)) and sets the clean VN state to the child.
+// It causes assert when cse processes the child with the clean vn state.
+
+
+using System;
+
+
+class Program
+{
+ public sealed class Variables
+ {
+ public static byte[] decryptedApplicationData
+ {
+ get;
+ set;
+ }
+ }
+
+ private static bool VerifyMacvalueSSlV2(string sourceIP)
+ {
+ if (sourceIP == "skip")
+ return false;
+
+ byte[] array3 = new byte[0];
+
+ // Assert happens on the next two statements.
+ int l = Variables.decryptedApplicationData.Length - array3.Length - 16;
+ byte[] array2 = new byte[l];
+
+ if (array3[0] != array2[0])
+ return false;
+ return true;
+ }
+
+ public static int Main(string[] args)
+ {
+ string s = "skip"; // Test checks commpilation process.
+ VerifyMacvalueSSlV2(s);
+ return 100;
+ }
+}
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_278526/DevDiv_278526.csproj b/tests/src/JIT/Regression/JitBlue/DevDiv_278526/DevDiv_278526.csproj
new file mode 100644
index 0000000000..b1bd003732
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_278526/DevDiv_278526.csproj
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType></DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="DevDiv_278526.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)minimal\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)minimal\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_279396/DevDiv_279396.il b/tests/src/JIT/Regression/JitBlue/DevDiv_279396/DevDiv_279396.il
new file mode 100644
index 0000000000..70e02027fc
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_279396/DevDiv_279396.il
@@ -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.
+
+.assembly extern mscorlib {}
+.assembly DevDiv_279396 {}
+.module DevDiv_279396.exe
+
+// This test originally triggered an assertion in the emitter that ensured that no lclVar or lclFld access exceeded the
+// bounds of its containing method's frame. The problematic access was created during morphing by folding
+// `(ind long (addr int (lclVar int V0)))` into `(lclFld long V0 0)`. This corresponds to the body of `C::Test` below.
+
+.class private abstract auto ansi sealed beforefieldinit C extends [mscorlib]System.Object
+{
+ .method private static int64 Test(int32 i) noinlining
+ {
+ ldarga.s i
+ ldind.i8
+ ret
+ }
+
+ .method private static int32 Main()
+ {
+ .entrypoint
+
+ ldc.i4 100
+ dup
+ call int64 C::Test(int32)
+ conv.i4
+ bne.un.s fail
+
+ ldc.i4 100
+ ret
+
+fail:
+ ldc.i4 101
+ ret
+ }
+}
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_279396/DevDiv_279396.ilproj b/tests/src/JIT/Regression/JitBlue/DevDiv_279396/DevDiv_279396.ilproj
new file mode 100644
index 0000000000..2a9f58bf7d
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_279396/DevDiv_279396.ilproj
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT .0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="DevDiv_279396.il" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_279829/DevDiv_279829.il b/tests/src/JIT/Regression/JitBlue/DevDiv_279829/DevDiv_279829.il
new file mode 100644
index 0000000000..96c22d24d6
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_279829/DevDiv_279829.il
@@ -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.
+
+.assembly extern mscorlib {}
+
+.assembly DevDiv_279829.exe {}
+
+.class public Test
+{
+ .method private static int32 JmpTarget(int64)
+ {
+ .maxstack 1
+ ldarg.0
+ conv.i4
+ ret
+ }
+
+ .method private static int32 Jmp(int64)
+ {
+ .maxstack 1
+ jmp int32 Test::JmpTarget(int64)
+ ldc.i4 0
+ ret
+ }
+
+ .method private static int32 Main(class [mscorlib]System.String[])
+ {
+ .entrypoint
+ .maxstack 1
+
+ ldc.i8 100
+ call int32 Test::Jmp(int64)
+ ret
+ }
+}
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_279829/DevDiv_279829.ilproj b/tests/src/JIT/Regression/JitBlue/DevDiv_279829/DevDiv_279829.ilproj
new file mode 100644
index 0000000000..d4804c8cdc
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_279829/DevDiv_279829.ilproj
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <RestorePackages>true</RestorePackages>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <Optimize>true</Optimize>
+ <DebugType>None</DebugType>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="DevDiv_279829.il" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)minimal\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)minimal\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_280120/DevDiv_280120.cs b/tests/src/JIT/Regression/JitBlue/DevDiv_280120/DevDiv_280120.cs
new file mode 100644
index 0000000000..39888b100d
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_280120/DevDiv_280120.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.
+
+// This test was originally a repro for an assertion regarding incorrect lclVar ref counts due to a bug in the
+// decomposition of a long-typed st.lclFld node. The repro requires that a dead store of this type survives until
+// decomposition. We must therefore avoid running liveness before decomposition as part of this test, which requires
+// skipping SSA (and dependent optimizations). This pass is disabled in the project file by setting JitDoSsa to 0
+// before running the test.
+
+struct S
+{
+ long m_fld;
+ int m_a, m_b, m_c, m_d;
+
+ static int Main(string[] args)
+ {
+ S s;
+ s.m_fld = (long)args.Length;
+ return 100;
+ }
+}
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_280120/DevDiv_280120.csproj b/tests/src/JIT/Regression/JitBlue/DevDiv_280120/DevDiv_280120.csproj
new file mode 100644
index 0000000000..bcbdc0f452
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_280120/DevDiv_280120.csproj
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType></DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="DevDiv_280120.cs" />
+ </ItemGroup>
+ <PropertyGroup>
+ <CLRTestBatchPreCommands><![CDATA[
+$(CLRTestBatchPreCommands)
+set COMPlus_JitDoSsa=0
+]]></CLRTestBatchPreCommands>
+ <BashCLRTestPreCommands><![CDATA[
+$(BashCLRTestPreCommands)
+export COMPlus_JitDoSsa=0
+]]></BashCLRTestPreCommands>
+ </PropertyGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)minimal\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)minimal\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_280123/DevDiv_280123.cs b/tests/src/JIT/Regression/JitBlue/DevDiv_280123/DevDiv_280123.cs
new file mode 100644
index 0000000000..01e55ed580
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_280123/DevDiv_280123.cs
@@ -0,0 +1,42 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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;
+
+// This test ensures that the value number store (and its users) behave properly in the event that VN data is requested
+// for trees without value numbers. The original repro was a rather large method with a significant amount of dead code
+// due to the pattern exhibited in C.N: an entry block that was not transformed from a conditional return to an
+// unconditional return followed by dead code that must be kept due to the presence of EH. Value numbering does not
+// assign value numbers to the dead code, but assertion prop still runs over the dead code and attempts to use VN info,
+// which resulted in a number of asserts.
+
+static class C
+{
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static int N(ref int i)
+ {
+ bool b = true;
+ if (b)
+ {
+ return 100;
+ }
+
+ try
+ {
+ b = i != 1;
+ }
+ finally
+ {
+ b = i != 0;
+ }
+
+ return b ? 0 : 1;
+ }
+
+ static int Main(string[] args)
+ {
+ int i = args.Length;
+ return N(ref i);
+ }
+}
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_280123/DevDiv_280123.csproj b/tests/src/JIT/Regression/JitBlue/DevDiv_280123/DevDiv_280123.csproj
new file mode 100644
index 0000000000..a2ec9758cc
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_280123/DevDiv_280123.csproj
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType></DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="DevDiv_280123.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)minimal\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)minimal\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_280127/DevDiv_280127.cs b/tests/src/JIT/Regression/JitBlue/DevDiv_280127/DevDiv_280127.cs
new file mode 100644
index 0000000000..3f8270f70c
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_280127/DevDiv_280127.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.CompilerServices;
+
+// The original repro for this test was an assertion after code generation that the actual maximum depth of the stack
+// was less than or identical to the estimated depth of the stack as calculated during morph. The calculation was
+// incorrect when a math intrinsic was used as an argument to a function with on-stack parameters (e.g. the call to
+// `M` on line 18).
+
+static class C
+{
+ struct S
+ {
+ int a, b, c, d;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static int N(S s, float d)
+ {
+ return 100;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static int M(double d)
+ {
+ N(new S(), (float)(Math.Atan2(d, 2.0) * 180 / Math.PI));
+ return 100;
+ }
+
+ static int Main()
+ {
+ return M(2.0);
+ }
+}
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_280127/DevDiv_280127.csproj b/tests/src/JIT/Regression/JitBlue/DevDiv_280127/DevDiv_280127.csproj
new file mode 100644
index 0000000000..ec9776df87
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_280127/DevDiv_280127.csproj
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType></DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="DevDiv_280127.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)minimal\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)minimal\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_283795/DevDiv_283795.cs b/tests/src/JIT/Regression/JitBlue/DevDiv_283795/DevDiv_283795.cs
new file mode 100644
index 0000000000..55da5ba1e9
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_283795/DevDiv_283795.cs
@@ -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.
+
+using System.Runtime.CompilerServices;
+
+class C
+{
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ static int[] M()
+ {
+ return null;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static bool Test(int i, int j, bool execute)
+ {
+ if (execute)
+ {
+ return M()[checked(i + j)] == 0;
+ }
+
+ return true;
+ }
+
+ static int Main()
+ {
+ // The original repro of the bug associated with this test involved an assert after re-morphing a tree modified
+ // by CSE: the original tree contained both a CSE def and a CSE use, and re-morphing eliminated the use, causing
+ // CSE to assert when attempting to replace the use with a reference to the CSE lclVar. This call to `Test` is
+ // intended to trigger that assert.
+ bool test1 = Test(0, 0, false);
+
+ // The associated code in morph involves folding `(x + null)` to `x`. During the investigation of the original
+ // issue, it was found that the folding code also failed to check for side effects in `x` resulting in SBCG if
+ // side effects were in fact present in `x`. This call to `Test` is intended to ensure that the fold is not
+ // performed in the face of a tree that contains side-effects: in particular, the overflowing add in the
+ // called method should occur before any other exception.
+ bool test2 = false;
+ try
+ {
+ Test(int.MaxValue, int.MaxValue, true);
+ }
+ catch (System.OverflowException)
+ {
+ test2 = true;
+ }
+ catch (System.Exception e)
+ {
+ System.Console.WriteLine(e);
+ }
+
+ return test1 && test2 ? 100 : 101;
+ }
+}
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_283795/DevDiv_283795.csproj b/tests/src/JIT/Regression/JitBlue/DevDiv_283795/DevDiv_283795.csproj
new file mode 100644
index 0000000000..71bd55fbf9
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_283795/DevDiv_283795.csproj
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType></DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="DevDiv_283795.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)minimal\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)minimal\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_284785/DevDiv_284785.cs b/tests/src/JIT/Regression/JitBlue/DevDiv_284785/DevDiv_284785.cs
new file mode 100644
index 0000000000..944993f038
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_284785/DevDiv_284785.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.
+
+// This test exercises expression folding in the place of overflowing operations. The original failure was SBCG due to
+// an incorrect application of the same: in the program below, the checked int -> ulong cast on line 24 was folded to a
+// long -> ulong cast with an incorrect constant value that fit in a ulong, resulting in no overflow exception being
+// thrown.
+
+using System;
+
+static class C
+{
+ static int Main()
+ {
+ int i = -4;
+ ulong l = 0;
+
+ int rv = 0;
+ try
+ {
+ checked
+ {
+ l = (ulong)i;
+ }
+ }
+ catch (OverflowException)
+ {
+ rv = 100;
+ }
+ catch (Exception)
+ {
+ i = 0;
+ l = 0;
+ }
+
+ return rv;
+ }
+}
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_284785/DevDiv_284785.csproj b/tests/src/JIT/Regression/JitBlue/DevDiv_284785/DevDiv_284785.csproj
new file mode 100644
index 0000000000..d27b911ee9
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_284785/DevDiv_284785.csproj
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType></DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="DevDiv_284785.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)minimal\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)minimal\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_288222/DevDiv_288222.cs b/tests/src/JIT/Regression/JitBlue/DevDiv_288222/DevDiv_288222.cs
new file mode 100644
index 0000000000..e24c7977ba
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_288222/DevDiv_288222.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.
+
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Numerics;
+
+// This test is a repro case for DevDiv VSO bug 288222.
+// The failure mode is that the size was not being set for a "this" pointer
+// with SIMD type.
+
+internal class Program
+{
+ // Declare a delegate type for calling the Vector2.CopyTo method.
+ public delegate void CopyToDelegate(float[] array, int start);
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static void MyCopyTo(CopyToDelegate doCopy, float[] array, int start)
+ {
+ doCopy(array, start);
+ }
+
+ private static int Main(string[] args)
+ {
+ try
+ {
+ float x = 1.0F;
+ float y = 2.0F;
+ Vector2 v = new Vector2(x, y);
+ float[] array = new float[4];
+ MyCopyTo(new CopyToDelegate(v.CopyTo), array, 2);
+
+ if ((array[2] != x) || (array[3] != y))
+ {
+ Console.WriteLine("Failed with wrong values");
+ return -1;
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine("Failed with exception: " + e.Message);
+ return -1;
+ }
+
+ Console.WriteLine("Pass");
+ return 100;
+ }
+}
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_288222/DevDiv_288222.csproj b/tests/src/JIT/Regression/JitBlue/DevDiv_288222/DevDiv_288222.csproj
new file mode 100644
index 0000000000..0aa2d11c7b
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_288222/DevDiv_288222.csproj
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType></DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="DevDiv_288222.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)threading+thread\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)threading+thread\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_359734/DevDiv_359734.il b/tests/src/JIT/Regression/JitBlue/DevDiv_359734/DevDiv_359734.il
new file mode 100644
index 0000000000..43f55b6e81
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_359734/DevDiv_359734.il
@@ -0,0 +1,118 @@
+// Licensed to the .NET Foundation under one or more 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 original bug for this test was an assertion after the following sequence of events:
+// - Assertion propagation constant propagated away the ldlocs, or, and shl in the IL at label "expr"
+// - After constant propagation, the resulting expression--`(mod tmp0 cns)`--was remorphed, which
+// replaced the modulus with `(sub tmp0 (mul (div tmp0 cns) cns))` and unset the "exception" flag.
+// Critically, this transformation added a new use of `tmp0` without updating the ref count for `tmp0`.
+// - After morphing, the resulting expression was both unsused and side-effect-free, and was removed
+// - While removing the lclVar ref count for `tmp0` fell to `0`
+// - Later, liveness found a reference to `tmp0` despite the `0` lclVar count and asserted.
+//
+// The fix was to bump lclVar ref counts after remorphing but before attempting to remove the expression.
+
+.assembly extern mscorlib{}
+.assembly ILGEN_MODULE{}
+.class ILGEN_CLASS
+{
+ .method static char ILGEN_METHOD(bool, char, int16, int32)
+ {
+ .maxstack 65535
+ .locals init (int32, int16, int64, int16, unsigned int8, float32, unsigned int8)
+
+ ldc.i8 0x80BBE1AB
+ ldc.i8 0x866D9EF3
+ or
+ ldarg 0x1
+ shl
+ ldc.i8 0xC09C2177
+ sub.ovf.un
+ conv.ovf.u8.un
+ ldc.i8 0x82B1C678
+ or
+ ldc.r8 -0.000000
+ ldloc 0x5
+ ckfinite
+ ldloc 0x5
+ neg
+ neg
+ add
+ add
+ ldc.r8 0.000000
+ clt
+ stloc.s 0x4
+ ldc.i8 0xACB4FC40
+
+ expr:
+ ldloc.s 0x3
+ ldloc.s 0x0
+ or
+ shl
+ rem
+
+ conv.ovf.i8
+ ldloc.s 0x4
+ conv.ovf.u
+ neg
+ brtrue IL_0089
+ ldarg 0x0
+ conv.ovf.i8
+ conv.i8
+ ldc.i8 0x2ECADED8
+ ldloc 0x2
+ shr
+ clt
+ pop
+ ldloc.s 0x1
+ conv.ovf.u1.un
+ conv.ovf.u.un
+ starg 0x0
+
+ IL_0089:
+ ldarg.s 0x3
+ conv.u8
+ bgt IL_0094
+ ldloc.s 0x5
+ pop
+
+ IL_0094:
+ ldc.r8 0.000000
+ neg
+ conv.i
+ ldloc 0x5
+ ckfinite
+ ldc.i8 0x8BD98F2C
+ conv.r4
+ ckfinite
+ clt
+ pop
+ neg
+ ret
+ }
+
+ .method static int32 Main()
+ {
+ .entrypoint
+
+ .try
+ {
+ ldc.i4 0
+ dup
+ dup
+ dup
+ call char ILGEN_CLASS::ILGEN_METHOD(bool, char, int16, int32)
+ pop
+ leave.s done
+ }
+ catch [mscorlib]System.Exception
+ {
+ leave.s done
+ }
+
+ done:
+ ldc.i4 100
+ ret
+ }
+}
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_359734/DevDiv_359734.ilproj b/tests/src/JIT/Regression/JitBlue/DevDiv_359734/DevDiv_359734.ilproj
new file mode 100644
index 0000000000..b13550f980
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_359734/DevDiv_359734.ilproj
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT .0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="DevDiv_359734.il" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_359736/DevDiv_359736.cs b/tests/src/JIT/Regression/JitBlue/DevDiv_359736/DevDiv_359736.cs
new file mode 100644
index 0000000000..56f7b903f3
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_359736/DevDiv_359736.cs
@@ -0,0 +1,42 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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;
+
+// This testcase reproduces a bug where the tree re-sequencing was not correct for
+// fgMorphModToSubMulDiv(), resulting in an assert in LSRA.
+
+static class Test
+{
+ static byte GetVal()
+ {
+ return 0;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static int DoMod(SByte arg)
+ {
+ byte val = GetVal();
+ return arg % val;
+ }
+
+ static int Main()
+ {
+ int returnVal = -1;
+ try
+ {
+ DoMod(4);
+ Console.WriteLine("FAILED: No exception thrown");
+ returnVal = -1;
+ }
+ catch (System.DivideByZeroException)
+ {
+ Console.WriteLine("PASS");
+ returnVal = 100;
+ }
+ return returnVal;
+ }
+}
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_359736/DevDiv_359736_d.csproj b/tests/src/JIT/Regression/JitBlue/DevDiv_359736/DevDiv_359736_d.csproj
new file mode 100644
index 0000000000..93bc9fd04f
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_359736/DevDiv_359736_d.csproj
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{23E1CE24-CCFB-4163-A861-D48A76295E8F}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>Full</DebugType>
+ <Optimize>False</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="DevDiv_359736.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)threading+thread\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)threading+thread\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_359736/DevDiv_359736_do.csproj b/tests/src/JIT/Regression/JitBlue/DevDiv_359736/DevDiv_359736_do.csproj
new file mode 100644
index 0000000000..07c2edfb09
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_359736/DevDiv_359736_do.csproj
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{C8DB97C3-1D53-4192-AE65-74A66EFE0841}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>Full</DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="DevDiv_359736.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)threading+thread\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)threading+thread\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_359736/DevDiv_359736_r.csproj b/tests/src/JIT/Regression/JitBlue/DevDiv_359736/DevDiv_359736_r.csproj
new file mode 100644
index 0000000000..fcc7a165ca
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_359736/DevDiv_359736_r.csproj
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{C7C7808C-AFDF-4267-B295-C9D0E9EF5642}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize>False</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="DevDiv_359736.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)threading+thread\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)threading+thread\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/DevDiv_359736/DevDiv_359736_ro.csproj b/tests/src/JIT/Regression/JitBlue/DevDiv_359736/DevDiv_359736_ro.csproj
new file mode 100644
index 0000000000..c8a1bef582
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/DevDiv_359736/DevDiv_359736_ro.csproj
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{30EFB3A3-FDAB-43C1-91E5-0496C0B9C689}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="DevDiv_359736.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)threading+thread\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)threading+thread\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_7906/GitHub_7906.cs b/tests/src/JIT/Regression/JitBlue/GitHub_7906/GitHub_7906.cs
new file mode 100644
index 0000000000..47f16d7fbf
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/GitHub_7906/GitHub_7906.cs
@@ -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.
+
+// Regression test for insufficient guard on inference of initial values
+// of induction variables.
+using System.Numerics;
+
+namespace N
+{
+ public static class C
+ {
+ public static int Main(string[] args)
+ {
+ int x = 0;
+
+ // When bottom-testing sees this loop, it (questionably for performance,
+ // but correctly) copies only the first part of the disjunctive loop condition
+ // so we get
+ //
+ // B1: i = Count // initialization
+ // B2: if (i < Count) goto B6 // duplicated loop condition (note the "zero trip" case goes to the 2nd loop condition disjunct)
+ // B3: x += i // loop body
+ // B4: ++i // increment
+ // B5: if (i < Count) goto B3 // first disjunct of loop condition
+ // B6: if (i < 20) goto B3 // second disjunct of loop condition
+ // B7: return x - 84 // post-loop
+ //
+ // At which point B3..B6 is an irreducible loop, but B3..B5 is a natural loop.
+ // This is a regression test for a bug where optRecordLoop would incorrectly
+ // identify B1 as the initial value of loop B3..B5 -- this is incorrect because
+ // the edge from B6 to B3 enters the loop with different values of i.
+ //
+ // The testcase is intentionally structured so that loop unrolling will try
+ // to unroll loop B3..B5 and generate incorrect code due to the incorrect
+ // initial value.
+ for (int i = Vector<int>.Count; i < Vector<int>.Count || i < 20; ++i)
+ {
+ x += i;
+ }
+
+ // After running the loop above, the value of x should be (Count + 19) * (20 - Count) / 2.
+ // Return 100 + x - (expected x) so the test will return 100 on success.
+ return 100 + x - ((Vector<int>.Count + 19) * (20 - Vector<int>.Count) / 2);
+ }
+ }
+}
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_7906/GitHub_7906.csproj b/tests/src/JIT/Regression/JitBlue/GitHub_7906/GitHub_7906.csproj
new file mode 100644
index 0000000000..1dbbc3bb45
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/GitHub_7906/GitHub_7906.csproj
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{76E69AA0-8C5A-4F76-8561-B8089FFA8D79}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType></DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="$(MSBuildProjectName).cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_7907/GitHub_7907.cs b/tests/src/JIT/Regression/JitBlue/GitHub_7907/GitHub_7907.cs
new file mode 100644
index 0000000000..32ea54c663
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/GitHub_7907/GitHub_7907.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.CompilerServices;
+
+#pragma warning disable 472
+
+public class Bug7907
+{
+ int _position = 10;
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static int G(int z, ref int r)
+ {
+ r -= z;
+ return 1;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public int F0(int count)
+ {
+ int initialCount = count;
+
+ _position += G(_position, ref count);
+
+ if (initialCount == count)
+ {
+ count--;
+ }
+
+ return initialCount - count;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public int F1(int count)
+ {
+ // " != null" is known to be true - just to remove control flow
+ // since that by itself may force spilling and mask the bug
+ count -= (_position += G(_position, ref count)) != null ? count : 1;
+
+ return count;
+ }
+
+ public static int Main(string[] args)
+ {
+ int result0 = new Bug7907().F0(10);
+ int result1 = new Bug7907().F1(10);
+ Console.WriteLine("R0={0} R1={1}", result0, result1);
+ return (result0 == 10 && result1 == 10 ? 100 : -1);
+ }
+}
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_7907/GitHub_7907.csproj b/tests/src/JIT/Regression/JitBlue/GitHub_7907/GitHub_7907.csproj
new file mode 100644
index 0000000000..5c86d0f679
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/GitHub_7907/GitHub_7907.csproj
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>pdbonly</DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="$(MSBuildProjectName).cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)minimal\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)minimal\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_8133/GitHub_8133.il b/tests/src/JIT/Regression/JitBlue/GitHub_8133/GitHub_8133.il
new file mode 100644
index 0000000000..be6720d88a
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/GitHub_8133/GitHub_8133.il
@@ -0,0 +1,112 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+.assembly extern mscorlib {}
+.assembly a {}
+
+// The original repro for this test was SBCG due to incorrect computation of value numbers for the ref-typed locals
+// in Test::Main(). Despite the fact that each local refers to a different array element, all of the locals were
+// assigned the same value number.
+
+.class Test extends [mscorlib]System.Object
+{
+ .method static void Equal(int32 i, int32 j) cil noinlining
+ {
+ ldarg.0
+ ldarg.1
+ bne.un.s fail
+ ret
+
+fail:
+ newobj instance void [mscorlib]System.Exception::.ctor()
+ throw
+ }
+
+ .method static !!0& Add<T>(!!0& addr, int32 offset)
+ {
+ ldarg.0
+ ldarg.1
+ sizeof !!0
+ conv.i
+ mul
+ add
+ ret
+ }
+
+ .method public hidebysig static int32 RefAdd() cil managed
+ {
+ .entrypoint
+
+ .locals init (
+ [0] int32[] a,
+ [1] int32& r1,
+ [2] int32& r2,
+ [3] int32& r3)
+
+ ldc.i4.4
+ newarr [mscorlib]System.Int32
+ dup
+ ldtoken field valuetype '<PrivateImplementationDetails>'/'__StaticArrayInitTypeSize=16' '<PrivateImplementationDetails>'::'6E9F9131664668938673AFE814BBDE210C6AE91F'
+ call void [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class [mscorlib]System.Array, valuetype [mscorlib]System.RuntimeFieldHandle)
+ stloc.0
+
+ ldloc.0
+ ldc.i4.0
+ ldelema [mscorlib]System.Int32
+ ldc.i4.1
+ call !!0& Test::Add<int32>(!!0&, int32)
+ stloc.1
+ ldc.i4 0x234
+ ldloc.1
+ ldind.i4
+ call void Test::Equal(int32, int32)
+
+ ldloc.1
+ ldc.i4.2
+ call !!0& Test::Add<int32>(!!0&, int32)
+ stloc.2
+ ldc.i4 0x456
+ ldloc.2
+ ldind.i4
+ call void Test::Equal(int32, int32)
+
+ ldloc.2
+ ldc.i4.s -3
+ call !!0& Test::Add<int32>(!!0&, int32)
+ stloc.3
+ ldc.i4 0x123
+ ldloc.3
+ ldind.i4
+ call void Test::Equal(int32, int32)
+
+ ldc.i4 100
+ ret
+ }
+}
+
+.class private auto ansi sealed '<PrivateImplementationDetails>'
+ extends [mscorlib]System.Object
+{
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
+ .class explicit ansi sealed nested private '__StaticArrayInitTypeSize=16'
+ extends [mscorlib]System.ValueType
+ {
+ .pack 1
+ .size 16
+ }
+
+ .field static assembly initonly int32 '4C55E5E5FC2235CC8C201E69A345F7FAB3FB46FA' at I_000054DC
+ .field static assembly initonly int64 '67423EBFA8454F19AC6F4686D6C0DC731A3DDD6B' at I_000054E4
+ .field static assembly initonly valuetype '<PrivateImplementationDetails>'/'__StaticArrayInitTypeSize=16' '6E9F9131664668938673AFE814BBDE210C6AE91F' at I_000054EC
+ .field static assembly initonly int32 '9BCE73D0C8B9ECA4F24154F3BD3B8AA473B1C3A9' at I_000054FC
+}
+
+.data cil I_000054DC = bytearray (
+ 42 42 42 42) // BBBB
+.data cil I_000054E4 = bytearray (
+ 00 01 02 03 04 05 06 07)
+.data cil I_000054EC = bytearray (
+ 23 01 00 00 34 02 00 00 45 03 00 00 56 04 00 00) // #...4...E...V...
+.data cil I_000054FC = bytearray (
+ 12 34 56 78) // .4Vx
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_8133/GitHub_8133.ilproj b/tests/src/JIT/Regression/JitBlue/GitHub_8133/GitHub_8133.ilproj
new file mode 100644
index 0000000000..3d8d22ec87
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/GitHub_8133/GitHub_8133.ilproj
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT .0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="GitHub_8133.il" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_8170/GitHub_8170.cs b/tests/src/JIT/Regression/JitBlue/GitHub_8170/GitHub_8170.cs
new file mode 100644
index 0000000000..d3fe8d9cf3
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/GitHub_8170/GitHub_8170.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 System.Runtime.CompilerServices;
+
+// This test checks for proper behavior w.r.t. overflow for expressions of the form `val % constant` where `val` is an
+// unsigned long and `constant` is a 32- or 64-bit integer constant in the range [2,0x3fffffff]. These expressions
+// should never produce an overflow exception.
+
+static class C
+{
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static uint M(ulong l)
+ {
+ return (uint)(l % 10000000);
+ }
+
+ static int Main()
+ {
+ return M(ulong.MaxValue) == 9551615 ? 100 : 101;
+ }
+}
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_8170/GitHub_8170.csproj b/tests/src/JIT/Regression/JitBlue/GitHub_8170/GitHub_8170.csproj
new file mode 100644
index 0000000000..81aa7299d0
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/GitHub_8170/GitHub_8170.csproj
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="GitHub_8170.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)minimal\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)minimal\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_8220/GitHub_8220.cs b/tests/src/JIT/Regression/JitBlue/GitHub_8220/GitHub_8220.cs
new file mode 100644
index 0000000000..f38d5ba698
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/GitHub_8220/GitHub_8220.cs
@@ -0,0 +1,170 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+// Regression test for Vector3 intrinsics using upper non-zero'd bits from
+// a byref return.
+
+using System;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Numerics;
+
+namespace Test
+{
+
+ public class Program
+ {
+ static Random random;
+
+ static Program()
+ {
+ random = new Random(1);
+ }
+
+ [MethodImpl( MethodImplOptions.NoInlining )]
+ public static double StackScribble()
+ {
+ double d1 = random.NextDouble();
+ double d2 = random.NextDouble();
+ double d3 = random.NextDouble();
+ double d4 = random.NextDouble();
+ double d5 = random.NextDouble();
+ double d6 = random.NextDouble();
+ double d7 = random.NextDouble();
+ double d8 = random.NextDouble();
+ double d9 = random.NextDouble();
+ double d10 = random.NextDouble();
+ double d11 = random.NextDouble();
+ double d12 = random.NextDouble();
+ double d13 = random.NextDouble();
+ double d14 = random.NextDouble();
+ double d15 = random.NextDouble();
+ double d16 = random.NextDouble();
+ double d17 = random.NextDouble();
+ double d18 = random.NextDouble();
+ double d19 = random.NextDouble();
+ double d20 = random.NextDouble();
+ double d21 = random.NextDouble();
+ double d22 = random.NextDouble();
+ double d23 = random.NextDouble();
+ double d24 = random.NextDouble();
+ double d25 = random.NextDouble();
+ double d26 = random.NextDouble();
+ double d27 = random.NextDouble();
+ double d28 = random.NextDouble();
+ double d29 = random.NextDouble();
+ double d30 = random.NextDouble();
+ double d31 = random.NextDouble();
+ double d32 = random.NextDouble();
+ double d33 = random.NextDouble();
+ double d34 = random.NextDouble();
+ double d35 = random.NextDouble();
+ double d36 = random.NextDouble();
+ double d37 = random.NextDouble();
+ double d38 = random.NextDouble();
+ double d39 = random.NextDouble();
+ double d40 = random.NextDouble();
+ return d1 + d2 + d3 + d4 + d5 + d6 + d7 + d8 + d9 + d10 +
+ d11 + d12 + d13 + d14 + d15 + d16 + d17 + d18 + d19 + d20 +
+ d21 + d22 + d23 + d24 + d25 + d26 + d27 + d28 + d29 + d20 +
+ d31 + d32 + d33 + d34 + d35 + d36 + d37 + d38 + d39 + d40;
+ }
+
+ [MethodImpl( MethodImplOptions.NoInlining )]
+ public static Vector3 getTestValue(float f1, float f2, float f3)
+ {
+ return new Vector3(f1, f2, f3);
+ }
+
+ public static bool Check(float value, float expectedValue)
+ {
+ // These may differ in the last place.
+ float expectedValueLow;
+ float expectedValueHigh;
+
+ unsafe
+ {
+ UInt32 expectedValueUInt = *(UInt32*)&expectedValue;
+ UInt32 expectedValueUIntLow = (expectedValueUInt == 0) ? 0 : expectedValueUInt - 1;
+ UInt32 expectedValueUIntHigh = (expectedValueUInt == 0xffffffff) ? 0xffffffff : expectedValueUInt + 1;
+ expectedValueLow = *(float*)&expectedValueUIntLow;
+ expectedValueHigh = *(float*)&expectedValueUIntHigh;
+ }
+ float errorMargin = Math.Abs(expectedValueHigh - expectedValueLow);
+ if (Math.Abs(value - expectedValue) > errorMargin)
+ {
+ return false;
+ }
+ return true;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static int testDotProduct(Vector3 v0)
+ {
+ float f1 = (float)random.NextDouble();
+ float f2 = (float)random.NextDouble();
+ float f3 = (float)random.NextDouble();
+
+ Vector3 v1 = Vector3.Normalize(getTestValue(f1, f2, f3) - v0);
+ Vector3 v2 = new Vector3(f1, f2, f3) - v0;
+ v2 = v2 / v2.Length();
+
+ if (!Check(v1.X, v2.X) || !Check(v1.Y, v2.Y) || !Check(v1.Z, v2.Z))
+ {
+ Console.WriteLine("Vectors do not match " + v1 + v2);
+ return -1;
+ }
+
+ return 100;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static int testEquals(Vector3 v0)
+ {
+ float f1 = (float)random.NextDouble();
+ float f2 = (float)random.NextDouble();
+ float f3 = (float)random.NextDouble();
+
+ Vector3 v1 = new Vector3(f1, f2, f3) - v0;
+ bool result = v1.Equals(getTestValue(f1, f2, f3) - v0);
+
+ if ((result == false) || !v1.Equals(getTestValue(f1, f2, f3) - v0))
+ {
+ Console.WriteLine("Equals returns wrong value " + v1);
+ return -1;
+ }
+
+ return 100;
+ }
+
+ public static int Main()
+ {
+ int returnValue = 100;
+ Console.WriteLine("Testing Dot Product");
+ for (int i = 0; i < 10; i++)
+ {
+ StackScribble();
+ if (testDotProduct(new Vector3(1.0F, 2.0F, 3.0F)) != 100)
+ {
+ Console.WriteLine("Failed on iteration " + i);
+ returnValue = -1;
+ break;
+ }
+ }
+ Console.WriteLine("Testing Equals");
+ for (int i = 0; i < 10; i++)
+ {
+ StackScribble();
+ if (testEquals(new Vector3(1.0F, 2.0F, 3.0F)) != 100)
+ {
+ Console.WriteLine("Failed on iteration " + i);
+ returnValue = -1;
+ break;
+ }
+ }
+ return returnValue;
+ }
+ }
+}
+
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_8220/GitHub_8220.csproj b/tests/src/JIT/Regression/JitBlue/GitHub_8220/GitHub_8220.csproj
new file mode 100644
index 0000000000..939d0106ed
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/GitHub_8220/GitHub_8220.csproj
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{76E69AA0-8C5A-4F76-8561-B8089FFA8D79}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType></DebugType>
+ <Optimize>True</Optimize>
+ <AllowUnsafeBlocks>True</AllowUnsafeBlocks>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="$(MSBuildProjectName).cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_8231/GitHub_8231.cs b/tests/src/JIT/Regression/JitBlue/GitHub_8231/GitHub_8231.cs
new file mode 100644
index 0000000000..4d2ec7628a
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/GitHub_8231/GitHub_8231.cs
@@ -0,0 +1,62 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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.Numerics;
+using System.Runtime.CompilerServices;
+
+namespace N
+{
+ public static class C
+ {
+ // This is a regression test for a failure in loop unrolling when
+ // the unrolled loop contains a switch statement.
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static int Test()
+ {
+ int s = 0;
+
+ // Loop to some Vector<T>.Count to trigger unrolling.
+ for (int i = 0; i < Vector<int>.Count; i++)
+ {
+ // Loop contains switch; the bug was that the clones
+ // of the switch were all sharing its BBswtDesc instead
+ // of getting their own, so updates to their jump targets
+ // were incorrectly shared.
+ switch (i)
+ {
+ case 1: s += 4; break;
+ case 2: s += 2; break;
+ case 3: s += i; break;
+ }
+ }
+
+ return s;
+ }
+
+ public static int Main(string[] args)
+ {
+ int result = Test();
+
+ // Expected result is a function of Vector<int>.Count.
+ int expected;
+ switch(Vector<int>.Count)
+ {
+ case 1:
+ expected = 4;
+ break;
+ case 2:
+ expected = 6;
+ break;
+ default:
+ expected = 9;
+ break;
+ }
+
+ // Return 100 on success (result == expected), other
+ // values on failure.
+ return 100 + result - expected;
+ }
+ }
+}
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_8231/GitHub_8231.csproj b/tests/src/JIT/Regression/JitBlue/GitHub_8231/GitHub_8231.csproj
new file mode 100644
index 0000000000..844638fe1b
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/GitHub_8231/GitHub_8231.csproj
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{2649FAFE-07BF-4F93-8120-BA9A69285ABB}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="GitHub_8231.cs" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_8460/GitHub_8460.cs b/tests/src/JIT/Regression/JitBlue/GitHub_8460/GitHub_8460.cs
new file mode 100644
index 0000000000..f5c9aa281b
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/GitHub_8460/GitHub_8460.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;
+
+namespace bug
+{
+ class Program
+ {
+ static int Pass = 100;
+ static int Fail = -1;
+
+ // This test is meant to check that in case of
+ // GT_EQ/NE(shift, 0), JIT doesn't optimize out
+ // 'test' instruction incorrectly, because shift
+ // operations on xarch don't modify flags if the
+ // shift count is zero.
+ static int Main(string[] args)
+ {
+ // Absolute bits
+ int bitCount = 0;
+ while ((0 != (100 >> bitCount)) && (31 > bitCount))
+ {
+ bitCount++;
+ }
+ // Sign bit
+ bitCount++;
+
+ if (bitCount != 8)
+ {
+ return Fail;
+ }
+
+ return Pass;
+ }
+ }
+}
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_8460/GitHub_8460.csproj b/tests/src/JIT/Regression/JitBlue/GitHub_8460/GitHub_8460.csproj
new file mode 100644
index 0000000000..b174dea98e
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/GitHub_8460/GitHub_8460.csproj
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType></DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="$(MSBuildProjectName).cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)minimal\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)minimal\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_8599/GitHub_8599.cs b/tests/src/JIT/Regression/JitBlue/GitHub_8599/GitHub_8599.cs
new file mode 100644
index 0000000000..95ff457620
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/GitHub_8599/GitHub_8599.cs
@@ -0,0 +1,42 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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;
+
+// TreeNodeInfoInitCmp attempts to eliminate the cast from cmp(cast<ubyte>(x), icon)
+// by narrowing the compare to ubyte. This should only happen if the constant fits in
+// a byte so it can be narrowed too, otherwise codegen produces an int sized compare.
+
+class Program
+{
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ static int GetValue() => 301;
+
+ static void Escape(ref int x)
+ {
+ }
+
+ static int Main()
+ {
+ if ((byte)GetValue() > 300)
+ {
+ return -1;
+ }
+
+ int x = GetValue();
+ Escape(ref x);
+ if ((byte)x > 300)
+ {
+ return -2;
+ }
+
+ if ((byte)(GetValue() | 2) > 300)
+ {
+ return -3;
+ }
+
+ return 100;
+ }
+}
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_8599/GitHub_8599.csproj b/tests/src/JIT/Regression/JitBlue/GitHub_8599/GitHub_8599.csproj
new file mode 100644
index 0000000000..b174dea98e
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/GitHub_8599/GitHub_8599.csproj
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType></DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="$(MSBuildProjectName).cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)minimal\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)minimal\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_CoreRT_2073/GitHub_CoreRT_2073.il b/tests/src/JIT/Regression/JitBlue/GitHub_CoreRT_2073/GitHub_CoreRT_2073.il
new file mode 100644
index 0000000000..28adbc49bb
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/GitHub_CoreRT_2073/GitHub_CoreRT_2073.il
@@ -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.
+
+// Test for a issue when tail call with small return type
+// doesn't pass tail call pattern assert.
+// In addition there is "call->branch on return->return" tail call pattern check.
+
+
+.assembly extern mscorlib {}
+
+.assembly GitHub_CoreRT_2073.exe {}
+
+.class public Test
+{
+
+.method private hidebysig static bool tailAsgReturn(int32 deep) cil managed
+{
+ // Code size 24 (0x18)
+ .maxstack 20
+ IL_0000: ldarg.0
+ IL_0001: ldc.i4.s -100
+ IL_0003: bgt.s IL_0007
+ IL_0005: ldc.i4.1
+ IL_0006: ret
+ IL_0007: ldarg.0
+ IL_0008: ldc.i4.0
+ IL_0009: bgt.s IL_000f
+
+ IL_000a: ldarg.0
+ IL_000b: ldc.i4.1
+ IL_000c: sub
+ IL_000d: call bool Test::tailAsgReturn(int32)
+ IL_000e: br IL_0017
+ IL_000f: ldarg.0
+ IL_0010: ldc.i4.2
+ IL_0011: sub
+ IL_0012: call bool Test::tailAsgReturn(int32)
+ IL_0017: ret
+} // end of method Test::tailAsgReturn
+
+.method public hidebysig static int32 Main(string[] args) cil managed
+{
+ .entrypoint
+ // Code size 14 (0xe)
+ .maxstack 8
+ IL_0000: ldc.i4.s 100
+ IL_0002: call bool Test::tailAsgReturn(int32)
+ IL_0007: brtrue.s IL_000b
+ IL_0009: ldc.i4.m1
+ IL_000a: ret
+ IL_000b: ldc.i4.s 100
+ IL_000d: ret
+} // end of method Test::Main
+}
diff --git a/tests/src/JIT/Regression/JitBlue/GitHub_CoreRT_2073/GitHub_CoreRT_2073.ilproj b/tests/src/JIT/Regression/JitBlue/GitHub_CoreRT_2073/GitHub_CoreRT_2073.ilproj
new file mode 100644
index 0000000000..fe8a3d3947
--- /dev/null
+++ b/tests/src/JIT/Regression/JitBlue/GitHub_CoreRT_2073/GitHub_CoreRT_2073.ilproj
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT .0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>None</DebugType>
+ <Optimize>True</Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="GitHub_CoreRT_2073.il" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/JIT/Regression/VS-ia64-JIT/V2.0-Beta2/b311420/b311420.csproj b/tests/src/JIT/Regression/VS-ia64-JIT/V2.0-Beta2/b311420/b311420.csproj
index b12149b936..77a35cdd82 100644
--- a/tests/src/JIT/Regression/VS-ia64-JIT/V2.0-Beta2/b311420/b311420.csproj
+++ b/tests/src/JIT/Regression/VS-ia64-JIT/V2.0-Beta2/b311420/b311420.csproj
@@ -14,6 +14,9 @@
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+
+ <!-- NOTE: this test simply takes too long to complete under GC stress; it is not fundamentally incompatible -->
+ <GCStressIncompatible Condition="'$(Platform)' == 'x86'">true</GCStressIncompatible>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
@@ -42,4 +45,4 @@
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
</PropertyGroup>
-</Project> \ No newline at end of file
+</Project>
diff --git a/tests/src/JIT/SIMD/Vector3Interop.cs b/tests/src/JIT/SIMD/Vector3Interop.cs
index fa6f8700d5..147adf44a8 100755
--- a/tests/src/JIT/SIMD/Vector3Interop.cs
+++ b/tests/src/JIT/SIMD/Vector3Interop.cs
@@ -112,7 +112,7 @@ class PInvokeTest
// Expected return value = 1 + 2 + 3 + 10 + 11 + 12 = 39
if (nativeCall_PInvoke_Vector3Arg(iv, v1, str, v2) != 39)
{
- Console.Write("PInvoke Vector3Arg test failed\n");
+ Console.WriteLine("PInvoke Vector3Arg test failed");
return false;
}
}
@@ -130,7 +130,7 @@ class PInvokeTest
f6, v2, // stack
f7, f8); // stack
if (sum != 1002) {
- Console.Write("PInvoke Vector3Arg_Unix test failed\n");
+ Console.WriteLine("PInvoke Vector3Arg_Unix test failed");
return false;
}
}
@@ -151,7 +151,7 @@ class PInvokeTest
v3, // stack
f9); // stack
if (sum != 1090) {
- Console.Write("PInvoke Vector3Arg_Unix2 test failed\n");
+ Console.WriteLine("PInvoke Vector3Arg_Unix2 test failed");
return false;
}
}
diff --git a/tests/src/JIT/SIMD/VectorDot.cs b/tests/src/JIT/SIMD/VectorDot.cs
index 2efe79e5ab..22c1493394 100644
--- a/tests/src/JIT/SIMD/VectorDot.cs
+++ b/tests/src/JIT/SIMD/VectorDot.cs
@@ -113,12 +113,17 @@ internal partial class VectorTest
if (VectorDotTest<ulong>.VectorDot(3ul, 2ul, 6ul * (ulong)Vector<ulong>.Count) != Pass) returnVal = Fail;
JitLog jitLog = new JitLog();
- // Dot is only recognized as an intrinsic for floating point element types.
+ // Dot is only recognized as an intrinsic for floating point element types
+ // and Vector<int> on AVX.
if (!jitLog.Check("Dot", "Single")) returnVal = Fail;
if (!jitLog.Check("Dot", "Double")) returnVal = Fail;
if (!jitLog.Check("System.Numerics.Vector4:Dot")) returnVal = Fail;
if (!jitLog.Check("System.Numerics.Vector3:Dot")) returnVal = Fail;
if (!jitLog.Check("System.Numerics.Vector2:Dot")) returnVal = Fail;
+ if (Vector<int>.Count == 8)
+ {
+ if (!jitLog.Check("Dot", "Int32")) returnVal = Fail;
+ }
jitLog.Dispose();
return returnVal;
diff --git a/tests/src/JIT/SIMD/VectorIntEquals.cs b/tests/src/JIT/SIMD/VectorIntEquals.cs
index bbbbbe519d..fae49aac1d 100644
--- a/tests/src/JIT/SIMD/VectorIntEquals.cs
+++ b/tests/src/JIT/SIMD/VectorIntEquals.cs
@@ -17,12 +17,67 @@ internal partial class VectorTest
Vector<int> B = new Vector<int>(3);
Vector<int> C = new Vector<int>(5);
-
bool result = A.Equals(B);
- if (!result) return Fail;
+ if (!result)
+ {
+ return Fail;
+ }
result = A.Equals(C);
- if (result) return Fail;
+ if (result)
+ {
+ return Fail;
+ }
+
+ if (A.Equals(Vector<int>.Zero))
+ {
+ return Fail;
+ }
+
+ if (!Vector<int>.Zero.Equals(Vector<int>.Zero))
+ {
+ return Fail;
+ }
+
+ if (Vector<int>.Zero.Equals(B))
+ {
+ return Fail;
+ }
+
+ if (!(A == B))
+ {
+ return Fail;
+ }
+
+ if (A == Vector<int>.Zero)
+ {
+ return Fail;
+ }
+
+ if (!(A != Vector<int>.Zero))
+ {
+ return Fail;
+ }
+
+ if (A != B)
+ {
+ return Fail;
+ }
+
+ if (!(A != C))
+ {
+ return Fail;
+ }
+
+ if (!(Vector<int>.Zero != A))
+ {
+ return Fail;
+ }
+
+ if (Vector<int>.Zero != Vector<int>.Zero)
+ {
+ return Fail;
+ }
return Pass;
}
diff --git a/tests/src/JIT/SIMD/VectorUtil.cs b/tests/src/JIT/SIMD/VectorUtil.cs
index d1b669df29..6501aac767 100644
--- a/tests/src/JIT/SIMD/VectorUtil.cs
+++ b/tests/src/JIT/SIMD/VectorUtil.cs
@@ -309,7 +309,7 @@ class JitLog : IDisposable
}
if (simdIntrinsicsSupported && methodFound)
{
- Console.WriteLine("Method " + method + " was compiled but should not have been\n");
+ Console.WriteLine("Method " + method + " was compiled but should not have been");
return false;
}
// Useful when developing / debugging just to be sure that we reached here:
diff --git a/tests/src/JIT/config/benchmark+roslyn/project.json b/tests/src/JIT/config/benchmark+roslyn/project.json
index 3fc4bd5809..e50dfd25c1 100644
--- a/tests/src/JIT/config/benchmark+roslyn/project.json
+++ b/tests/src/JIT/config/benchmark+roslyn/project.json
@@ -1,29 +1,29 @@
{
"dependencies": {
"Microsoft.CodeAnalysis.Compilers": "1.1.1",
- "Microsoft.DotNet.xunit.performance": "1.0.0-alpha-build0035",
- "Microsoft.DotNet.xunit.performance.analysis": "1.0.0-alpha-build0035",
- "Microsoft.DotNet.xunit.performance.runner.Windows": "1.0.0-alpha-build0035",
- "Microsoft.NETCore.Platforms": "1.1.0",
- "System.Console": "4.3.0",
- "System.Dynamic.Runtime": "4.3.0",
- "System.Linq": "4.3.0",
- "System.IO.FileSystem": "4.3.0",
- "System.Numerics.Vectors": "4.3.0",
- "System.Reflection": "4.3.0",
- "System.Reflection.Extensions": "4.3.0",
- "System.Reflection.TypeExtensions": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Runtime.Numerics": "4.3.0",
- "System.Text.RegularExpressions": "4.3.0",
- "System.Threading": "4.3.0",
- "System.Threading.Tasks": "4.3.0",
- "System.Threading.Tasks.Parallel": "4.3.0",
- "System.Security.Cryptography.Algorithms": "4.3.0",
- "xunit": "2.1.0",
- "xunit.console.netcore": "1.0.2-prerelease-00101",
- "xunit.runner.utility": "2.1.0"
+ "Microsoft.DotNet.xunit.performance": "1.0.0-alpha-build0040",
+ "Microsoft.DotNet.xunit.performance.analysis": "1.0.0-alpha-build0040",
+ "Microsoft.DotNet.xunit.performance.runner.Windows": "1.0.0-alpha-build0040",
+ "Microsoft.NETCore.Platforms": "1.2.0-beta-24820-02",
+ "System.Console": "4.4.0-beta-24820-02",
+ "System.Dynamic.Runtime": "4.4.0-beta-24820-02",
+ "System.Linq": "4.4.0-beta-24820-02",
+ "System.IO.FileSystem": "4.4.0-beta-24820-02",
+ "System.Numerics.Vectors": "4.4.0-beta-24820-02",
+ "System.Reflection": "4.4.0-beta-24820-02",
+ "System.Reflection.Extensions": "4.4.0-beta-24820-02",
+ "System.Reflection.TypeExtensions": "4.4.0-beta-24820-02",
+ "System.Runtime": "4.4.0-beta-24820-02",
+ "System.Runtime.Extensions": "4.4.0-beta-24820-02",
+ "System.Runtime.Numerics": "4.4.0-beta-24820-02",
+ "System.Text.RegularExpressions": "4.4.0-beta-24820-02",
+ "System.Threading": "4.4.0-beta-24820-02",
+ "System.Threading.Tasks": "4.4.0-beta-24820-02",
+ "System.Threading.Tasks.Parallel": "4.4.0-beta-24820-02",
+ "System.Security.Cryptography.Algorithms": "4.4.0-beta-24820-02",
+ "xunit": "2.2.0-beta2-build3300",
+ "xunit.console.netcore": "1.0.2-prerelease-00177",
+ "xunit.runner.utility": "2.2.0-beta2-build3300"
},
"frameworks": {
"netstandard1.4": {
diff --git a/tests/src/JIT/config/benchmark+serialize/project.json b/tests/src/JIT/config/benchmark+serialize/project.json
index e7e1853000..ac24df1167 100644
--- a/tests/src/JIT/config/benchmark+serialize/project.json
+++ b/tests/src/JIT/config/benchmark+serialize/project.json
@@ -1,26 +1,29 @@
{
"dependencies": {
- "Microsoft.DotNet.xunit.performance": "1.0.0-alpha-build0035",
- "Microsoft.DotNet.xunit.performance.analysis": "1.0.0-alpha-build0035",
- "Microsoft.DotNet.xunit.performance.runner.Windows": "1.0.0-alpha-build0035",
- "Microsoft.NETCore.Platforms": "1.1.0",
+ "Microsoft.DotNet.xunit.performance": "1.0.0-alpha-build0040",
+ "Microsoft.DotNet.xunit.performance.analysis": "1.0.0-alpha-build0040",
+ "Microsoft.DotNet.xunit.performance.runner.Windows": "1.0.0-alpha-build0040",
+ "Microsoft.NETCore.Platforms": "1.2.0-beta-24820-02",
"Newtonsoft.Json": "7.0.1",
- "System.Console": "4.3.0",
- "System.IO": "4.3.0",
- "System.IO.FileSystem": "4.3.0",
- "System.Linq": "4.3.0",
- "System.ObjectModel": "4.3.0",
- "System.Dynamic.Runtime": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Serialization.Json": "4.3.0",
- "System.Runtime.Serialization.Primitives": "4.1.1",
- "System.Runtime.Serialization.Xml": "4.3.0",
- "System.Text.RegularExpressions": "4.3.0",
- "System.Xml.XmlDocument": "4.3.0",
- "System.Xml.XmlSerializer": "4.3.0",
- "xunit": "2.1.0",
- "xunit.console.netcore": "1.0.2-prerelease-00101",
- "xunit.runner.utility": "2.1.0"
+ "System.Console": "4.4.0-beta-24820-02",
+ "System.IO": "4.4.0-beta-24820-02",
+ "System.IO.FileSystem": "4.4.0-beta-24820-02",
+ "System.Linq": "4.4.0-beta-24820-02",
+ "System.ObjectModel": "4.4.0-beta-24820-02",
+ "System.Dynamic.Runtime": "4.4.0-beta-24820-02",
+ "System.Reflection": "4.4.0-beta-24820-02",
+ "System.Reflection.Extensions": "4.4.0-beta-24820-02",
+ "System.Reflection.TypeExtensions": "4.4.0-beta-24820-02",
+ "System.Runtime": "4.4.0-beta-24820-02",
+ "System.Runtime.Serialization.Json": "4.4.0-beta-24820-02",
+ "System.Runtime.Serialization.Primitives": "4.4.0-beta-24820-02",
+ "System.Runtime.Serialization.Xml": "4.4.0-beta-24820-02",
+ "System.Text.RegularExpressions": "4.4.0-beta-24820-02",
+ "System.Xml.XmlDocument": "4.4.0-beta-24820-02",
+ "System.Xml.XmlSerializer": "4.4.0-beta-24820-02",
+ "xunit": "2.2.0-beta2-build3300",
+ "xunit.console.netcore": "1.0.2-prerelease-00177",
+ "xunit.runner.utility": "2.2.0-beta2-build3300"
},
"frameworks": {
"netstandard1.4": {
diff --git a/tests/src/JIT/config/benchmark/project.json b/tests/src/JIT/config/benchmark/project.json
index 8f1493c32d..97234d329e 100644
--- a/tests/src/JIT/config/benchmark/project.json
+++ b/tests/src/JIT/config/benchmark/project.json
@@ -1,29 +1,32 @@
{
"dependencies": {
- "Microsoft.DotNet.xunit.performance": "1.0.0-alpha-build0035",
- "Microsoft.DotNet.xunit.performance.analysis": "1.0.0-alpha-build0035",
- "Microsoft.DotNet.xunit.performance.runner.Windows": "1.0.0-alpha-build0035",
- "Microsoft.NETCore.Platforms": "1.1.0",
- "System.Collections.NonGeneric": "4.3.0",
- "System.Console": "4.3.0",
- "System.IO.FileSystem": "4.3.0",
- "System.Linq": "4.3.0",
- "System.Linq.Expressions": "4.3.0",
- "System.Numerics.Vectors": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Runtime.Numerics": "4.3.0",
- "System.Text.RegularExpressions": "4.3.0",
- "System.Threading": "4.3.0",
- "System.Threading.Tasks": "4.3.0",
- "System.Threading.Tasks.Parallel": "4.3.0",
- "System.Diagnostics.Process": "4.3.0",
- "System.Xml.XmlDocument": "4.3.0",
- "System.Xml.XPath": "4.3.0",
- "System.Xml.XPath.XmlDocument": "4.3.0",
- "xunit": "2.1.0",
- "xunit.console.netcore": "1.0.2-prerelease-00101",
- "xunit.runner.utility": "2.1.0"
+ "Microsoft.DotNet.xunit.performance": "1.0.0-alpha-build0040",
+ "Microsoft.DotNet.xunit.performance.analysis": "1.0.0-alpha-build0040",
+ "Microsoft.DotNet.xunit.performance.runner.Windows": "1.0.0-alpha-build0040",
+ "Microsoft.NETCore.Platforms": "1.2.0-beta-24820-02",
+ "System.Collections.NonGeneric": "4.4.0-beta-24820-02",
+ "System.Console": "4.4.0-beta-24820-02",
+ "System.IO.FileSystem": "4.4.0-beta-24820-02",
+ "System.Linq": "4.4.0-beta-24820-02",
+ "System.Linq.Expressions": "4.4.0-beta-24820-02",
+ "System.Numerics.Vectors": "4.4.0-beta-24820-02",
+ "System.Reflection": "4.4.0-beta-24820-02",
+ "System.Reflection.Extensions": "4.4.0-beta-24820-02",
+ "System.Reflection.TypeExtensions": "4.4.0-beta-24820-02",
+ "System.Runtime": "4.4.0-beta-24820-02",
+ "System.Runtime.Extensions": "4.4.0-beta-24820-02",
+ "System.Runtime.Numerics": "4.4.0-beta-24820-02",
+ "System.Text.RegularExpressions": "4.4.0-beta-24820-02",
+ "System.Threading": "4.4.0-beta-24820-02",
+ "System.Threading.Tasks": "4.4.0-beta-24820-02",
+ "System.Threading.Tasks.Parallel": "4.4.0-beta-24820-02",
+ "System.Diagnostics.Process": "4.4.0-beta-24820-02",
+ "System.Xml.XmlDocument": "4.4.0-beta-24820-02",
+ "System.Xml.XPath": "4.4.0-beta-24820-02",
+ "System.Xml.XPath.XmlDocument": "4.4.0-beta-24820-02",
+ "xunit": "2.2.0-beta2-build3300",
+ "xunit.console.netcore": "1.0.2-prerelease-00177",
+ "xunit.runner.utility": "2.2.0-beta2-build3300"
},
"frameworks": {
"netstandard1.4": {
diff --git a/tests/src/JIT/config/extra/project.json b/tests/src/JIT/config/extra/project.json
index 92b2fac43a..6268bc58e9 100644
--- a/tests/src/JIT/config/extra/project.json
+++ b/tests/src/JIT/config/extra/project.json
@@ -1,24 +1,24 @@
{
"dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "System.Collections": "4.3.0",
- "System.Console": "4.3.0",
- "System.Diagnostics.Debug": "4.3.0",
- "System.Runtime.InteropServices.RuntimeInformation": "4.3.0",
- "System.Diagnostics.Process": "4.3.0",
- "System.Globalization": "4.3.0",
- "System.IO": "4.3.0",
- "System.IO.FileSystem": "4.3.0",
- "System.Reflection": "4.3.0",
- "System.Reflection.Extensions": "4.3.0",
- "System.Reflection.TypeExtensions": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Runtime.CompilerServices.Unsafe": "4.3.0",
- "System.Runtime.InteropServices": "4.3.0"
+ "Microsoft.NETCore.Platforms": "1.2.0-beta-24820-02",
+ "System.Collections": "4.4.0-beta-24820-02",
+ "System.Console": "4.4.0-beta-24820-02",
+ "System.Diagnostics.Debug": "4.4.0-beta-24820-02",
+ "System.Runtime.InteropServices.RuntimeInformation": "4.4.0-beta-24820-02",
+ "System.Diagnostics.Process": "4.4.0-beta-24820-02",
+ "System.Globalization": "4.4.0-beta-24820-02",
+ "System.IO": "4.4.0-beta-24820-02",
+ "System.IO.FileSystem": "4.4.0-beta-24820-02",
+ "System.Reflection": "4.4.0-beta-24820-02",
+ "System.Reflection.Extensions": "4.4.0-beta-24820-02",
+ "System.Reflection.TypeExtensions": "4.4.0-beta-24820-02",
+ "System.Runtime": "4.4.0-beta-24820-02",
+ "System.Runtime.Extensions": "4.4.0-beta-24820-02",
+ "System.Runtime.CompilerServices.Unsafe": "4.4.0-beta-24820-02",
+ "System.Runtime.InteropServices": "4.4.0-beta-24820-02"
},
"frameworks": {
- "netcoreapp1.0": {}
+ "netcoreapp1.1": {}
},
"runtimes": {
"win7-x86": {},
diff --git a/tests/src/JIT/config/minimal/project.json b/tests/src/JIT/config/minimal/project.json
index 20eded453a..6bc378e4a4 100644
--- a/tests/src/JIT/config/minimal/project.json
+++ b/tests/src/JIT/config/minimal/project.json
@@ -1,13 +1,13 @@
{
"dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "System.Console": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Runtime.InteropServices": "4.3.0"
+ "Microsoft.NETCore.Platforms": "1.2.0-beta-24820-02",
+ "System.Console": "4.4.0-beta-24820-02",
+ "System.Runtime": "4.4.0-beta-24820-02",
+ "System.Runtime.Extensions": "4.4.0-beta-24820-02",
+ "System.Runtime.InteropServices": "4.4.0-beta-24820-02"
},
"frameworks": {
- "netcoreapp1.0": {}
+ "netcoreapp1.1": {}
},
"runtimes": {
"win7-x86": {},
diff --git a/tests/src/JIT/config/threading+thread/project.json b/tests/src/JIT/config/threading+thread/project.json
index 4efc76cf00..f6576f154d 100644
--- a/tests/src/JIT/config/threading+thread/project.json
+++ b/tests/src/JIT/config/threading+thread/project.json
@@ -1,15 +1,15 @@
{
"dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "System.Console": "4.3.0",
- "System.Numerics.Vectors": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Threading": "4.3.0",
- "System.Threading.Thread": "4.3.0"
+ "Microsoft.NETCore.Platforms": "1.2.0-beta-24820-02",
+ "System.Console": "4.4.0-beta-24820-02",
+ "System.Numerics.Vectors": "4.4.0-beta-24820-02",
+ "System.Runtime": "4.4.0-beta-24820-02",
+ "System.Runtime.Extensions": "4.4.0-beta-24820-02",
+ "System.Threading": "4.4.0-beta-24820-02",
+ "System.Threading.Thread": "4.4.0-beta-24820-02"
},
"frameworks": {
- "netcoreapp1.0": {}
+ "netcoreapp1.1": {}
},
"runtimes": {
"win7-x86": {},
diff --git a/tests/src/JIT/config/threading/project.json b/tests/src/JIT/config/threading/project.json
index b0478ce429..e62d3551a4 100644
--- a/tests/src/JIT/config/threading/project.json
+++ b/tests/src/JIT/config/threading/project.json
@@ -1,13 +1,13 @@
{
"dependencies": {
- "Microsoft.NETCore.Platforms": "1.1.0",
- "System.Console": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Threading": "4.3.0"
+ "Microsoft.NETCore.Platforms": "1.2.0-beta-24820-02",
+ "System.Console": "4.4.0-beta-24820-02",
+ "System.Runtime": "4.4.0-beta-24820-02",
+ "System.Runtime.Extensions": "4.4.0-beta-24820-02",
+ "System.Threading": "4.4.0-beta-24820-02"
},
"frameworks": {
- "netcoreapp1.0": {}
+ "netcoreapp1.1": {}
},
"runtimes": {
"win7-x86": {},
diff --git a/tests/src/JIT/jit64/opt/cse/HugeArray.csproj b/tests/src/JIT/jit64/opt/cse/HugeArray.csproj
index 8926c0f997..166482bcc1 100644
--- a/tests/src/JIT/jit64/opt/cse/HugeArray.csproj
+++ b/tests/src/JIT/jit64/opt/cse/HugeArray.csproj
@@ -14,6 +14,9 @@
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+
+ <!-- NOTE: this test simply takes too long to complete under GC stress; it is not fundamentally incompatible -->
+ <GCStressIncompatible Condition="'$(Platform)' == 'x86'">true</GCStressIncompatible>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
@@ -42,4 +45,4 @@
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
</PropertyGroup>
-</Project> \ No newline at end of file
+</Project>
diff --git a/tests/src/JIT/jit64/verif/sniff/fg/ver_fg_13.il b/tests/src/JIT/jit64/verif/sniff/fg/ver_fg_13.il
index 9e422bbdab..5ad48d1878 100644
--- a/tests/src/JIT/jit64/verif/sniff/fg/ver_fg_13.il
+++ b/tests/src/JIT/jit64/verif/sniff/fg/ver_fg_13.il
@@ -11,12 +11,7 @@
.publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )
.ver 4:0:0:0
}
-.assembly test
-{
- .custom instance void [mscorlib]System.Security.AllowPartiallyTrustedCallersAttribute::.ctor() = ( 01 00 01 00 00 )
-
-}
-
+.assembly test { }
.module ver_fg_13.exe
diff --git a/tests/src/JIT/opt/Inline/regression/mismatch32/mismatch32.il b/tests/src/JIT/opt/Inline/regression/mismatch32/mismatch32.il
index e23b0a8346..73730d72dd 100644
--- a/tests/src/JIT/opt/Inline/regression/mismatch32/mismatch32.il
+++ b/tests/src/JIT/opt/Inline/regression/mismatch32/mismatch32.il
@@ -5,6 +5,10 @@
// When the jit considers inlining B it can get itself into
// trouble because of the type mismatch. This test tries to
// ensure the jit backs out of the inline successfully.
+//
+// By default (when no args are passed) execution avoids
+// the problematic callsite, and the app should run without
+// failing.
.assembly extern mscorlib { }
.assembly extern System.Console
@@ -39,7 +43,7 @@
ldarg.0
ldlen
ldc.i4 1
- bgt DONE
+ blt DONE
newobj instance void F::.ctor()
ldc.i4 33
call int32 B(int32, int32)
diff --git a/tests/src/JIT/opt/Inline/regression/mismatch64/mismatch64.il b/tests/src/JIT/opt/Inline/regression/mismatch64/mismatch64.il
index f952856909..ba336c06c9 100644
--- a/tests/src/JIT/opt/Inline/regression/mismatch64/mismatch64.il
+++ b/tests/src/JIT/opt/Inline/regression/mismatch64/mismatch64.il
@@ -5,6 +5,10 @@
// When the jit considers inlining B it can get itself into
// trouble because of the type mismatch. This test tries to
// ensure the jit backs out of the inline successfully.
+//
+// By default (when no args are passed) execution avoids
+// the problematic callsite, and the app should run without
+// failing.
.assembly extern mscorlib { }
.assembly extern System.Console
@@ -39,7 +43,7 @@
ldarg.0
ldlen
ldc.i4 1
- bgt DONE
+ blt DONE
newobj instance void F::.ctor()
ldc.i8 44
call int64 B(int64, int64)
diff --git a/tests/src/JIT/opt/Tailcall/TailcallVerifyWithPrefix.il b/tests/src/JIT/opt/Tailcall/TailcallVerifyWithPrefix.il
index 9c5fcfdf29..763d95f628 100644
--- a/tests/src/JIT/opt/Tailcall/TailcallVerifyWithPrefix.il
+++ b/tests/src/JIT/opt/Tailcall/TailcallVerifyWithPrefix.il
@@ -5610,6 +5610,9 @@
.method public hidebysig instance void
Caller1() cil managed
{
+ // This method depends on JIT compiler doing automatic tail call, which isn't supported by Ready-to-Run.
+ .custom instance void System.Runtime.BypassReadyToRunAttribute::.ctor() = ( 01 00 00 00 )
+
// Code size 53 (0x35)
.maxstack 8
IL_0000: ldc.i4.0
@@ -5633,6 +5636,9 @@
.method public hidebysig instance void
Caller1Recursive() cil managed
{
+ // This method depends on JIT compiler doing automatic tail call, which isn't supported by Ready-to-Run.
+ .custom instance void System.Runtime.BypassReadyToRunAttribute::.ctor() = ( 01 00 00 00 )
+
// Code size 55 (0x37)
.maxstack 8
IL_0000: ldc.i4.0
@@ -5670,6 +5676,9 @@
.method private hidebysig instance void
Callee1Recursive(int32 i) cil managed
{
+ // This method depends on JIT compiler doing automatic tail call, which isn't supported by Ready-to-Run.
+ .custom instance void System.Runtime.BypassReadyToRunAttribute::.ctor() = ( 01 00 00 00 )
+
// Code size 93 (0x5d)
.maxstack 3
.locals init ([0] string stackTrace,
@@ -5805,6 +5814,9 @@
Caller1(!V arg1,
!K arg2) cil managed
{
+ // This method depends on JIT compiler doing automatic tail call, which isn't supported by Ready-to-Run.
+ .custom instance void System.Runtime.BypassReadyToRunAttribute::.ctor() = ( 01 00 00 00 )
+
// Code size 54 (0x36)
.maxstack 8
IL_0000: ldc.i4.0
@@ -6016,6 +6028,9 @@
.method private hidebysig static void Caller2() cil managed
{
+ // This method depends on JIT compiler doing automatic tail call, which isn't supported by Ready-to-Run.
+ .custom instance void System.Runtime.BypassReadyToRunAttribute::.ctor() = ( 01 00 00 00 )
+
// Code size 52 (0x34)
.maxstack 8
IL_0000: ldc.i4.0
@@ -10376,6 +10391,21 @@
.field static assembly valuetype '<PrivateImplementationDetails>{D1242658-CA16-4D11-A740-6635F112F4B5}'/'__StaticArrayInitTypeSize=20' '$$method0x6000076-1' at I_00005C00
} // end of class '<PrivateImplementationDetails>{D1242658-CA16-4D11-A740-6635F112F4B5}'
+.class private auto ansi sealed beforefieldinit System.Runtime.BypassReadyToRunAttribute
+ extends [mscorlib]System.Attribute
+{
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+ // Code size 7 (0x7)
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Attribute::.ctor()
+ IL_0006: ret
+ } // end of method BypassReadyToRunAttribute::.ctor
+
+} // end of class System.Runtime.BypassReadyToRunAttribute
+
// =============================================================
diff --git a/tests/src/JIT/opt/virtualstubdispatch/bigvtbl/bigvtbl_cs_d.csproj b/tests/src/JIT/opt/virtualstubdispatch/bigvtbl/bigvtbl_cs_d.csproj
index da9a36e07d..4a5818f410 100644
--- a/tests/src/JIT/opt/virtualstubdispatch/bigvtbl/bigvtbl_cs_d.csproj
+++ b/tests/src/JIT/opt/virtualstubdispatch/bigvtbl/bigvtbl_cs_d.csproj
@@ -14,6 +14,9 @@
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT .0\UITestExtensionPackages</ReferencePath>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+
+ <!-- NOTE: this test simply takes too long to complete under GC stress; it is not fundamentally incompatible -->
+ <GCStressIncompatible Condition="'$(Platform)' == 'x86'">true</GCStressIncompatible>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
diff --git a/tests/src/JIT/opt/virtualstubdispatch/bigvtbl/bigvtbl_cs_r.csproj b/tests/src/JIT/opt/virtualstubdispatch/bigvtbl/bigvtbl_cs_r.csproj
index a7547ea0c1..909d79887a 100644
--- a/tests/src/JIT/opt/virtualstubdispatch/bigvtbl/bigvtbl_cs_r.csproj
+++ b/tests/src/JIT/opt/virtualstubdispatch/bigvtbl/bigvtbl_cs_r.csproj
@@ -14,6 +14,9 @@
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT .0\UITestExtensionPackages</ReferencePath>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+
+ <!-- NOTE: this test simply takes too long to complete under GC stress; it is not fundamentally incompatible -->
+ <GCStressIncompatible Condition="'$(Platform)' == 'x86'">true</GCStressIncompatible>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase0.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase0.il
index 1dcd41e7ee..f8721456a2 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase0.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase0.il
@@ -36,7 +36,10 @@
ldstr "A::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit B`2<V,W>
@@ -59,12 +62,20 @@
.maxstack 8
ldstr "B::Bar2"
ret
- } .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ }
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
@@ -103,4 +114,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase1.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase1.il
index 371ade9c79..05c6c998a5 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase1.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase1.il
@@ -24,7 +24,10 @@
ldstr "A::Foo"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit B`2<V,W>
@@ -43,12 +46,19 @@
ldstr "B::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
@@ -87,4 +97,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase2.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase2.il
index 3c65974a39..6cf4e13278 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase2.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase2.il
@@ -24,7 +24,10 @@
ldstr "A::Foo"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private abstract auto ansi beforefieldinit B`2<V,W>
@@ -43,12 +46,19 @@
ldstr "B::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
@@ -87,4 +97,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase3.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase3.il
index 9fc5e8128f..d41d8cb293 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase3.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase3.il
@@ -19,7 +19,10 @@
.class interface nested family abstract auto ansi I`1<T>
{ .method public hidebysig newslot abstract virtual instance string Foo() cil managed {} }
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit B`2<V,W>
@@ -43,12 +46,19 @@
ldstr "B::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
@@ -87,4 +97,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase4.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase4.il
index 137cf43079..bbd564bc62 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase4.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase4.il
@@ -18,8 +18,11 @@
{
.class interface nested family abstract auto ansi I`1<T>
{ .method public hidebysig newslot abstract virtual instance string Foo() cil managed {} }
-
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private abstract auto ansi beforefieldinit B`2<V,W>
@@ -43,12 +46,19 @@
ldstr "B::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
@@ -87,4 +97,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase5.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase5.il
index 3ff9b9ad2f..1cb5217e41 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase5.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase5.il
@@ -36,19 +36,29 @@
ldstr "A::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit B`2<V,W>
extends class A`1<!V>
implements class A`1/I`1<!W>, J
{
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
@@ -87,4 +97,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase6.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase6.il
index 55a59a1084..7c08f9c345 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase6.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_I/TestCase6.il
@@ -36,19 +36,29 @@
ldstr "A::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private abstract auto ansi beforefieldinit B`2<V,W>
extends class A`1<!V>
implements class A`1/I`1<!W>, J
{
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
@@ -87,4 +97,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase0.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase0.il
index 1bb1dae67b..490c829727 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase0.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase0.il
@@ -36,7 +36,10 @@
ldstr "A::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit B`2<V,W>
@@ -59,12 +62,20 @@
.maxstack 8
ldstr "B::Bar2"
ret
- } .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ }
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
@@ -103,4 +114,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase1.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase1.il
index 7c099e229e..5501eb4f4c 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase1.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase1.il
@@ -24,7 +24,10 @@
ldstr "A::Foo"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit B`2<V,W>
@@ -43,12 +46,19 @@
ldstr "B::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
@@ -87,4 +97,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase2.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase2.il
index f2c3c2f771..900afd1fe8 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase2.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase2.il
@@ -24,7 +24,10 @@
ldstr "A::Foo"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private abstract auto ansi beforefieldinit B`2<V,W>
@@ -43,12 +46,19 @@
ldstr "B::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
@@ -87,4 +97,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase3.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase3.il
index ea83a0f390..d8a6ded6f7 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase3.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase3.il
@@ -19,7 +19,10 @@
.method public hidebysig newslot abstract virtual instance string Bar2() cil managed {}
}
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit B`2<V,W>
@@ -43,12 +46,19 @@
ldstr "B::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
@@ -87,4 +97,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase4.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase4.il
index b95f00d0e5..14fe4646d4 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase4.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase4.il
@@ -19,7 +19,10 @@
.method public hidebysig newslot abstract virtual instance string Bar2() cil managed {}
}
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private abstract auto ansi beforefieldinit B`2<V,W>
@@ -43,12 +46,19 @@
ldstr "B::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
@@ -87,4 +97,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase5.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase5.il
index 46b6c3a8e2..03ff440d1b 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase5.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase5.il
@@ -36,18 +36,29 @@
ldstr "A::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit B`2<V,W>
extends class A`1<!V>
implements class A`1/I`1<!W>, A`1/I`1/J
{
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
@@ -87,4 +98,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase6.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase6.il
index 365a6aa8aa..bdc70e8d42 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase6.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_I_Nested_J/TestCase6.il
@@ -36,19 +36,29 @@
ldstr "A::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private abstract auto ansi beforefieldinit B`2<V,W>
extends class A`1<!V>
implements class A`1/I`1<!W>, A`1/I`1/J
{
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase0.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase0.il
index 356cd39010..d4aecd808a 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase0.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase0.il
@@ -36,7 +36,10 @@
ldstr "A::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit B`2<V,W>
@@ -59,12 +62,20 @@
.maxstack 8
ldstr "B::Bar2"
ret
- } .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ }
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
@@ -103,4 +114,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase1.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase1.il
index bcf1b2b0d9..f24aba9bf1 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase1.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase1.il
@@ -23,7 +23,10 @@
ldstr "A::Foo"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit B`2<V,W>
@@ -42,12 +45,19 @@
ldstr "B::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
@@ -86,4 +96,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase2.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase2.il
index 0d82b78ce3..eda666b305 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase2.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase2.il
@@ -23,7 +23,10 @@
ldstr "A::Foo"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private abstract auto ansi beforefieldinit B`2<V,W>
@@ -42,12 +45,19 @@
ldstr "B::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
@@ -86,4 +96,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase3.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase3.il
index 7341902b62..e15e0abb08 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase3.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase3.il
@@ -18,7 +18,10 @@
.method public hidebysig newslot abstract virtual instance string Bar1() cil managed {}
.method public hidebysig newslot abstract virtual instance string Bar2() cil managed {}
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit B`2<V,W>
@@ -42,12 +45,19 @@
ldstr "B::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
@@ -86,4 +96,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase4.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase4.il
index 75ef0e80cb..91ed35840a 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase4.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase4.il
@@ -18,7 +18,10 @@
.method public hidebysig newslot abstract virtual instance string Bar1() cil managed {}
.method public hidebysig newslot abstract virtual instance string Bar2() cil managed {}
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private abstract auto ansi beforefieldinit B`2<V,W>
@@ -42,12 +45,19 @@
ldstr "B::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
@@ -86,4 +96,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase5.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase5.il
index 4e7a639528..1ceb777800 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase5.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase5.il
@@ -35,19 +35,29 @@
ldstr "A::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit B`2<V,W>
extends class A`1<!V>
implements class I`1<!W>, A`1/J
{
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
@@ -86,4 +96,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase6.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase6.il
index f106b5fc72..52d4631c63 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase6.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_J/TestCase6.il
@@ -35,19 +35,29 @@
ldstr "A::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private abstract auto ansi beforefieldinit B`2<V,W>
extends class A`1<!V>
implements class I`1<!W>, A`1/J
{
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
@@ -86,4 +96,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase0.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase0.il
index fb4f32d808..5fab5b8d0a 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase0.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase0.il
@@ -34,7 +34,10 @@
ldstr "A::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit B`2<V,W>
@@ -57,12 +60,20 @@
.maxstack 8
ldstr "B::Bar2"
ret
- } .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ }
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
@@ -101,4 +112,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase1.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase1.il
index fd46e20202..d2a73e3020 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase1.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase1.il
@@ -22,7 +22,10 @@
ldstr "A::Foo"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit B`2<V,W>
@@ -41,12 +44,19 @@
ldstr "B::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
@@ -85,4 +95,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase2.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase2.il
index 065c132353..6874dca76c 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase2.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase2.il
@@ -22,7 +22,10 @@
ldstr "A::Foo"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private abstract auto ansi beforefieldinit B`2<V,W>
@@ -41,12 +44,19 @@
ldstr "B::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
@@ -85,4 +95,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase3.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase3.il
index 7f40457ab5..03516e4494 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase3.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase3.il
@@ -17,7 +17,10 @@
.method public hidebysig newslot abstract virtual instance string Bar1() cil managed {}
.method public hidebysig newslot abstract virtual instance string Bar2() cil managed {}
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit B`2<V,W>
@@ -41,12 +44,19 @@
ldstr "B::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
@@ -85,4 +95,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase4.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase4.il
index f4efdfd2a3..72b3ed1e62 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase4.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase4.il
@@ -17,7 +17,10 @@
.method public hidebysig newslot abstract virtual instance string Bar1() cil managed {}
.method public hidebysig newslot abstract virtual instance string Bar2() cil managed {}
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private abstract auto ansi beforefieldinit B`2<V,W>
@@ -41,12 +44,19 @@
ldstr "B::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
@@ -85,4 +95,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase5.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase5.il
index a446ed32df..0fb52a5c62 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase5.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase5.il
@@ -34,19 +34,29 @@
ldstr "A::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit B`2<V,W>
extends class A`1<!V>
implements class A`1/J/I`1<!W>, A`1/J
{
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
@@ -85,4 +95,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase6.il b/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase6.il
index baaabcccdb..fd5047eaf3 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase6.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/Nested_J_Nested_I/TestCase6.il
@@ -34,19 +34,29 @@
ldstr "A::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private abstract auto ansi beforefieldinit B`2<V,W>
extends class A`1<!V>
implements class A`1/J/I`1<!W>, A`1/J
{
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
@@ -85,4 +95,4 @@ FAILURE:
ldc.i4.m1
ret
}
-} \ No newline at end of file
+}
diff --git a/tests/src/Loader/classloader/InterfaceFolding/TestCase0.il b/tests/src/Loader/classloader/InterfaceFolding/TestCase0.il
index 0e5c131773..068a309944 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/TestCase0.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/TestCase0.il
@@ -37,7 +37,10 @@
ldstr "A::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit B`2<V,W>
@@ -60,12 +63,16 @@
.maxstack 8
ldstr "B::Bar2"
ret
- } .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
diff --git a/tests/src/Loader/classloader/InterfaceFolding/TestCase1.il b/tests/src/Loader/classloader/InterfaceFolding/TestCase1.il
index 2f7be47be0..e5d41839f8 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/TestCase1.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/TestCase1.il
@@ -25,7 +25,10 @@
ldstr "A::Foo"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit B`2<V,W>
@@ -44,12 +47,19 @@
ldstr "B::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
diff --git a/tests/src/Loader/classloader/InterfaceFolding/TestCase2.il b/tests/src/Loader/classloader/InterfaceFolding/TestCase2.il
index 1927d596ae..30e99dca24 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/TestCase2.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/TestCase2.il
@@ -25,7 +25,10 @@
ldstr "A::Foo"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private abstract auto ansi beforefieldinit B`2<V,W>
@@ -44,12 +47,19 @@
ldstr "B::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
diff --git a/tests/src/Loader/classloader/InterfaceFolding/TestCase3.il b/tests/src/Loader/classloader/InterfaceFolding/TestCase3.il
index e67f03912c..d84965ce38 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/TestCase3.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/TestCase3.il
@@ -20,7 +20,10 @@
.class private abstract auto ansi beforefieldinit A`1<U>
implements class I`1<!U>
{
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit B`2<V,W>
@@ -44,12 +47,19 @@
ldstr "B::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
diff --git a/tests/src/Loader/classloader/InterfaceFolding/TestCase4.il b/tests/src/Loader/classloader/InterfaceFolding/TestCase4.il
index e411d7a588..f41de5c05d 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/TestCase4.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/TestCase4.il
@@ -20,7 +20,10 @@
.class private abstract auto ansi beforefieldinit A`1<U>
implements class I`1<!U>
{
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private abstract auto ansi beforefieldinit B`2<V,W>
@@ -44,12 +47,19 @@
ldstr "B::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
diff --git a/tests/src/Loader/classloader/InterfaceFolding/TestCase5.il b/tests/src/Loader/classloader/InterfaceFolding/TestCase5.il
index 30a61c9a08..51ddd83515 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/TestCase5.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/TestCase5.il
@@ -37,19 +37,29 @@
ldstr "A::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit B`2<V,W>
extends class A`1<!V>
implements class I`1<!W>, J
{
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
diff --git a/tests/src/Loader/classloader/InterfaceFolding/TestCase6.il b/tests/src/Loader/classloader/InterfaceFolding/TestCase6.il
index 4b9dc2ceea..ceba5455b2 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/TestCase6.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/TestCase6.il
@@ -37,19 +37,29 @@
ldstr "A::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private abstract auto ansi beforefieldinit B`2<V,W>
extends class A`1<!V>
implements class I`1<!W>, J
{
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
diff --git a/tests/src/Loader/classloader/InterfaceFolding/TestCase7.il b/tests/src/Loader/classloader/InterfaceFolding/TestCase7.il
index 92f61358d3..2513ae09a0 100644
--- a/tests/src/Loader/classloader/InterfaceFolding/TestCase7.il
+++ b/tests/src/Loader/classloader/InterfaceFolding/TestCase7.il
@@ -37,7 +37,10 @@
ldstr "A::Bar2"
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit B`2<V,W>
@@ -61,12 +64,20 @@
.maxstack 8
ldstr "B::Bar2"
ret
- } .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {}
+ }
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class private auto ansi beforefieldinit C extends class B`2<class C,class C>
-{ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed {} }
-
+{
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
+}
.class public auto ansi beforefieldinit Test extends [mscorlib]System.Object
{
diff --git a/tests/src/Loader/classloader/PrivateInterfaceImpl/Test2_NonFriendPriInterface.csproj b/tests/src/Loader/classloader/PrivateInterfaceImpl/Test2_NonFriendPriInterface.csproj
deleted file mode 100644
index 5c75304b16..0000000000
--- a/tests/src/Loader/classloader/PrivateInterfaceImpl/Test2_NonFriendPriInterface.csproj
+++ /dev/null
@@ -1,35 +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>
- <AssemblyName>Test2_NonFriendPriInterface</AssemblyName>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
- <FileAlignment>512</FileAlignment>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib>
- <OutputType>Library</OutputType>
- <CLRTestKind>BuildOnly</CLRTestKind>
- <CLRTestPriority>0</CLRTestPriority>
- </PropertyGroup>
-
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
-
- <ItemGroup>
- <Compile Include="Test2_NonFriendPriInterface.cs" />
- </ItemGroup>
-
-
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/tests/src/Loader/classloader/generics/Visibility/A_Types.csproj b/tests/src/Loader/classloader/generics/Visibility/A_Types.csproj
deleted file mode 100644
index 023d1b9c98..0000000000
--- a/tests/src/Loader/classloader/generics/Visibility/A_Types.csproj
+++ /dev/null
@@ -1,35 +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>
- <AssemblyName>A_Types</AssemblyName>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
- <FileAlignment>512</FileAlignment>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib>
- <OutputType>Library</OutputType>
- <CLRTestKind>BuildOnly</CLRTestKind>
- <CLRTestPriority>0</CLRTestPriority>
- </PropertyGroup>
-
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
-
- <ItemGroup>
- <Compile Include="A_Types.cs" />
- </ItemGroup>
-
-
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/tests/src/Loader/classloader/generics/Visibility/B_Types.csproj b/tests/src/Loader/classloader/generics/Visibility/B_Types.csproj
deleted file mode 100644
index 46c06016fe..0000000000
--- a/tests/src/Loader/classloader/generics/Visibility/B_Types.csproj
+++ /dev/null
@@ -1,35 +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>
- <AssemblyName>B_Types</AssemblyName>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
- <FileAlignment>512</FileAlignment>
- <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- <ReferenceLocalMscorlib>false</ReferenceLocalMscorlib>
- <OutputType>Library</OutputType>
- <CLRTestKind>BuildOnly</CLRTestKind>
- <CLRTestPriority>0</CLRTestPriority>
- </PropertyGroup>
-
- <ItemGroup>
- <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
- <Visible>False</Visible>
- </CodeAnalysisDependentAssemblyPaths>
- </ItemGroup>
-
- <ItemGroup>
- <Compile Include="B_Types.cs" />
- </ItemGroup>
-
-
- <ItemGroup>
- <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/tests/src/Loader/classloader/methodoverriding/regressions/549411/exploit.csproj b/tests/src/Loader/classloader/methodoverriding/regressions/549411/exploit.csproj
index ce7ca5e3fa..29cb737ea5 100644
--- a/tests/src/Loader/classloader/methodoverriding/regressions/549411/exploit.csproj
+++ b/tests/src/Loader/classloader/methodoverriding/regressions/549411/exploit.csproj
@@ -15,6 +15,7 @@
<OutputType>Exe</OutputType>
<CLRTestKind>BuildAndRun</CLRTestKind>
<CLRTestPriority>0</CLRTestPriority>
+ <GCStressIncompatible Condition="'$(Platform)' == 'x86'">true</GCStressIncompatible>
</PropertyGroup>
<ItemGroup>
diff --git a/tests/src/Loader/classloader/regressions/dev10_710121/dev10_710121.il b/tests/src/Loader/classloader/regressions/dev10_710121/dev10_710121.il
index babb30d572..96e28f672f 100644
--- a/tests/src/Loader/classloader/regressions/dev10_710121/dev10_710121.il
+++ b/tests/src/Loader/classloader/regressions/dev10_710121/dev10_710121.il
@@ -21,12 +21,18 @@ The bug related to populating MethodDesc slots in generic dictionaries at runtim
.class public DerivedDerived
extends class Derived`2<string,string>
{
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { }
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class public Derived`2<T0, T1>
extends class Base`2<int32,!T1>
{
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { }
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
.class public Base`2<T0, T1>
{
@@ -40,7 +46,10 @@ The bug related to populating MethodDesc slots in generic dictionaries at runtim
call string [mscorlib]System.String::Concat(object,object)
ret
}
- .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { }
+ .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
+ {
+ ret
+ }
}
diff --git a/tests/src/TestWrappersConfig/project.json b/tests/src/TestWrappersConfig/project.json
index 07ede5fca1..f255e3044f 100644
--- a/tests/src/TestWrappersConfig/project.json
+++ b/tests/src/TestWrappersConfig/project.json
@@ -1,10 +1,17 @@
{
"dependencies": {
- "xunit": "2.1.0",
- "xunit.assert": "2.1.0",
- "xunit.core": "2.1.0"
+ "xunit": "2.2.0-beta2-build3300",
+ "xunit.assert": "2.2.0-beta2-build3300",
+ "xunit.core": "2.2.0-beta2-build3300",
+ "xunit.runner.msbuild": "2.2.0-beta2-build3300"
},
"frameworks": {
+ "netcoreapp1.1": {
+ "imports": [
+ "dnxcore50",
+ "portable-net45+win8"
+ ]
+ },
"net45": {
"imports": "portable-net45+win8"
}
diff --git a/tests/src/baseservices/compilerservices/FixedAddressValueType/FixedAddressValueType.cs b/tests/src/baseservices/compilerservices/FixedAddressValueType/FixedAddressValueType.cs
new file mode 100644
index 0000000000..bf10d817e5
--- /dev/null
+++ b/tests/src/baseservices/compilerservices/FixedAddressValueType/FixedAddressValueType.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.Runtime.CompilerServices;
+
+public struct Age {
+ public int years;
+ public int months;
+}
+
+public class FreeClass
+{
+ public static Age FreeAge;
+
+ public static unsafe IntPtr AddressOfFreeAge()
+ {
+ fixed (Age* pointer = &FreeAge)
+ { return (IntPtr) pointer; }
+ }
+}
+
+public class FixedClass
+{
+ [FixedAddressValueType]
+ public static Age FixedAge;
+
+ public static unsafe IntPtr AddressOfFixedAge()
+ {
+ fixed (Age* pointer = &FixedAge)
+ { return (IntPtr) pointer; }
+ }
+}
+
+public class Example
+{
+ public static int Main()
+ {
+ // Get addresses of static Age fields.
+ IntPtr freePtr1 = FreeClass.AddressOfFreeAge();
+
+ IntPtr fixedPtr1 = FixedClass.AddressOfFixedAge();
+
+ // Garbage collection.
+ GC.Collect(3, GCCollectionMode.Forced, true, true);
+ GC.WaitForPendingFinalizers();
+
+ // Get addresses of static Age fields after garbage collection.
+ IntPtr freePtr2 = FreeClass.AddressOfFreeAge();
+ IntPtr fixedPtr2 = FixedClass.AddressOfFixedAge();
+
+ if(freePtr1 != freePtr2 && fixedPtr1 == fixedPtr2)
+ {
+ return 100;
+ }
+
+ return -1;
+ }
+}
diff --git a/tests/src/baseservices/compilerservices/FixedAddressValueType/FixedAddressValueType.csproj b/tests/src/baseservices/compilerservices/FixedAddressValueType/FixedAddressValueType.csproj
new file mode 100644
index 0000000000..19a779194f
--- /dev/null
+++ b/tests/src/baseservices/compilerservices/FixedAddressValueType/FixedAddressValueType.csproj
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <GCStressIncompatible>true</GCStressIncompatible>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <!-- Add Compile Object Here -->
+ <Compile Include="FixedAddressValueType.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <NoWarn Include="42016,42020,42025,42024" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/baseservices/compilerservices/RuntimeHelpers/ExecuteCodeWithGuaranteedCleanup.cs b/tests/src/baseservices/compilerservices/RuntimeHelpers/ExecuteCodeWithGuaranteedCleanup.cs
new file mode 100644
index 0000000000..58cee3ca36
--- /dev/null
+++ b/tests/src/baseservices/compilerservices/RuntimeHelpers/ExecuteCodeWithGuaranteedCleanup.cs
@@ -0,0 +1,62 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .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 GCD
+{
+ /// <summary>
+ /// Summary description for Class1.
+ /// </summary>
+ class GCD
+ {
+ private int _val = -2;
+ private int _exitcode = -1;
+ public GCD() {}
+ public int GetExitCode(){ return _exitcode;}
+ public void g ()
+ {
+ throw new System.Exception("TryCode test");
+ }
+ public void TryCode0 (object obj)
+ {
+ _val = (int)obj;
+ g();
+ }
+ public void CleanupCode0 (object obj, bool excpThrown)
+ {
+ if(excpThrown && ((int)obj == _val))
+ {
+ _exitcode = 100;
+ }
+ }
+ }
+
+
+ class GCDTest
+ {
+ /// <summary>
+ /// The main entry point for the application.
+ /// </summary>
+ [STAThread]
+ static int Main(string[] args)
+ {
+ GCD gcd = new GCD();
+ RuntimeHelpers.TryCode t = new RuntimeHelpers.TryCode(gcd.TryCode0);
+ RuntimeHelpers.CleanupCode c = new RuntimeHelpers.CleanupCode(gcd.CleanupCode0);
+ int val = 21;
+ try
+ {
+ RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(t, c, val);
+ }
+ catch (Exception Ex)
+ {
+
+ }
+
+ return gcd.GetExitCode();
+ }
+ }
+}
diff --git a/tests/src/baseservices/compilerservices/RuntimeHelpers/ExecuteCodeWithGuaranteedCleanup.csproj b/tests/src/baseservices/compilerservices/RuntimeHelpers/ExecuteCodeWithGuaranteedCleanup.csproj
new file mode 100644
index 0000000000..605d11b1f1
--- /dev/null
+++ b/tests/src/baseservices/compilerservices/RuntimeHelpers/ExecuteCodeWithGuaranteedCleanup.csproj
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <!-- Add Compile Object Here -->
+ <Compile Include="ExecuteCodeWithGuaranteedCleanup.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <NoWarn Include="42016,42020,42025,42024" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/baseservices/compilerservices/RuntimeWrappedException/RuntimeWrappedException.cs b/tests/src/baseservices/compilerservices/RuntimeWrappedException/RuntimeWrappedException.cs
new file mode 100644
index 0000000000..29fb347ae1
--- /dev/null
+++ b/tests/src/baseservices/compilerservices/RuntimeWrappedException/RuntimeWrappedException.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;
+using System.IO;
+using System.Runtime.CompilerServices;
+using System.Runtime.Serialization;
+
+class Test
+{
+ public static int Main(string[] args)
+ {
+ int retVal = 0;
+ var thrower = new StringThrowerClass();
+ try
+ {
+ thrower.InstanceMethod();
+ }
+
+ catch (RuntimeWrappedException ex)
+ {
+
+ if ( !ex.WrappedException.ToString().Contains("Inside StringThrower") )
+ {
+// Console.WriteLine("Incorrect exception and/or message. Expected RuntimeWrappedException: An object that does not derive "+
+// "from System.Exception has been wrapped in a RuntimeWrappedException.\n But actually got: " + ex.InnerException);
+ retVal = -1;
+ }
+
+ StreamingContext ctx;
+
+// TODO: Expose once we have access to FormatterConverter
+// var info = new SerializationInfo(typeof(RuntimeWrappedException), new FormatterConverter());
+// ex.GetObjectData(info,ctx);
+//
+ try
+ {
+ ex.GetObjectData(null,ctx);
+ }
+ catch (ArgumentNullException ex1)
+ {
+ retVal = 100;
+ }
+ catch (Exception ex1)
+ {
+ retVal = -1;
+ }
+
+
+ }
+ catch (Exception ex)
+ {
+// Console.WriteLine("Incorrect exception thrown. Expected RuntimeWrappedException, but actually got: " + ex);
+ retVal = -2;
+ }
+
+
+ return retVal;
+
+
+ }
+}
diff --git a/tests/src/baseservices/compilerservices/RuntimeWrappedException/RuntimeWrappedException.csproj b/tests/src/baseservices/compilerservices/RuntimeWrappedException/RuntimeWrappedException.csproj
new file mode 100644
index 0000000000..4b0c5cf68d
--- /dev/null
+++ b/tests/src/baseservices/compilerservices/RuntimeWrappedException/RuntimeWrappedException.csproj
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <!-- Add Compile Object Here -->
+ <Compile Include="RuntimeWrappedException.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="StringThrower.ilproj" />
+ </ItemGroup>
+ <ItemGroup>
+ <NoWarn Include="42016,42020,42025,42024" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/baseservices/compilerservices/RuntimeWrappedException/StringThrower.il b/tests/src/baseservices/compilerservices/RuntimeWrappedException/StringThrower.il
new file mode 100644
index 0000000000..92c9139f7c
--- /dev/null
+++ b/tests/src/baseservices/compilerservices/RuntimeWrappedException/StringThrower.il
@@ -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.
+
+.assembly extern mscorlib
+{
+ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
+ .ver 2:0:0:0
+}
+
+.assembly StringThrower {}
+
+.class public auto ansi StringThrowerClass
+ extends [mscorlib]System.Object
+{
+ .field public static int32 intStatic
+
+
+ .method public hidebysig instance void
+ InstanceMethod() cil managed noinlining
+ {
+ .maxstack 8
+
+ ldstr "Inside StringThrower"
+ throw
+ ret
+ } // end of method A::methodA
+
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor() cil managed
+ {
+
+ .maxstack 8
+ ldarg.0
+ call instance void class [mscorlib]System.Object::.ctor()
+ ret
+ } // end of method Test1::.ctor
+
+}
diff --git a/tests/src/baseservices/compilerservices/RuntimeWrappedException/StringThrower.ilproj b/tests/src/baseservices/compilerservices/RuntimeWrappedException/StringThrower.ilproj
new file mode 100644
index 0000000000..79667cc7c6
--- /dev/null
+++ b/tests/src/baseservices/compilerservices/RuntimeWrappedException/StringThrower.ilproj
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="StringThrower.il" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/baseservices/compilerservices/modulector/moduleCctor.il b/tests/src/baseservices/compilerservices/modulector/moduleCctor.il
new file mode 100644
index 0000000000..06bf6ac12c
--- /dev/null
+++ b/tests/src/baseservices/compilerservices/modulector/moduleCctor.il
@@ -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.
+
+.assembly extern mscorlib
+{
+ .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
+ .ver 2:0:0:0
+}
+
+.assembly moduleCctor {}
+.assembly extern FieldTypes
+{
+ .publickeytoken = (C0 30 5C 36 38 0B A4 29 ) // .0\68..)
+ .ver 0:0:0:0
+}
+
+ .method private hidebysig specialname rtspecialname static
+ void .cctor() cil managed
+ {
+ .maxstack 8
+ nop
+ ldsfld int32 IntHolder::val
+ ldc.i4.1
+ add
+ stsfld int32 IntHolder::val
+// ldstr "modCctor.txt"
+// ldstr "inside .cctor"
+// call void [mscorlib]System.IO.File::WriteAllText(string,
+// string)
+ ret
+ } // end of method Foo::.cctor
+
+
+// =============== CLASS MEMBERS DECLARATION ===================
+.class public auto ansi beforefieldinit IntHolder
+ extends [mscorlib]System.Object
+{
+ // Fields
+ .field public static int32 val
+
+ // Methods
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor () cil managed
+ {
+ // Method begins at RVA 0x2050
+ // Code size 8 (0x8)
+ .maxstack 8
+
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: nop
+ IL_0007: ret
+ } // end of method IntHolder::.ctor
+
+ .method private hidebysig specialname rtspecialname static
+ void .cctor () cil managed
+ {
+ // Method begins at RVA 0x2059
+ // Code size 7 (0x7)
+ .maxstack 8
+
+ IL_0000: ldc.i4.0
+ IL_0001: stsfld int32 IntHolder::val
+ IL_0006: ret
+ } // end of method IntHolder::.cctor
+
+ .method public hidebysig static
+ void Assign (
+ int32 arg
+ ) cil managed
+ {
+ // Method begins at RVA 0x2078
+ // Code size 8 (0x8)
+ .maxstack 8
+
+ IL_0000: nop
+ IL_0001: ldarg.0
+ IL_0002: stsfld int32 IntHolder::val
+ IL_0007: ret
+ } // end of method IntHolder::Assign
+ .method public hidebysig static
+ void Check (
+ int32 arg
+ ) cil managed
+ {
+ // Method begins at RVA 0x2050
+ // Code size 28 (0x1c)
+ .maxstack 2
+ .locals init (
+ [0] bool
+ )
+
+ IL_0000: nop
+ IL_0001: ldsfld int32 IntHolder::val
+ IL_0006: ldarg.0
+ IL_0007: ceq
+ IL_0009: ldc.i4.0
+ IL_000a: ceq
+ IL_000c: stloc.0
+ IL_000d: ldloc.0
+ IL_000e: brfalse.s IL_001b
+
+ IL_0010: ldstr "Mod Ctor did not functon correctly"
+ IL_0015: newobj instance void [mscorlib]System.Exception::.ctor(string)
+ IL_001a: throw
+
+ IL_001b: ret
+ } // end of method IntHolder::Check
+} // end of class IntHolder
diff --git a/tests/src/baseservices/compilerservices/modulector/moduleCctor.ilproj b/tests/src/baseservices/compilerservices/modulector/moduleCctor.ilproj
new file mode 100644
index 0000000000..c846e02edb
--- /dev/null
+++ b/tests/src/baseservices/compilerservices/modulector/moduleCctor.ilproj
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="moduleCctor.il" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/baseservices/compilerservices/modulector/runmoduleconstructor.cs b/tests/src/baseservices/compilerservices/modulector/runmoduleconstructor.cs
new file mode 100644
index 0000000000..d1192f167a
--- /dev/null
+++ b/tests/src/baseservices/compilerservices/modulector/runmoduleconstructor.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.Reflection;
+using System.IO;
+using System.Runtime.Loader;
+using System.Runtime.CompilerServices;
+using System.Globalization;
+
+class RuntimeHelperTest
+{
+ public static int Main(string[] args)
+ {
+ AssemblyLoadContext resolver0 = AssemblyLoadContext.Default;
+ Assembly asm0 = resolver0.LoadFromAssemblyName(new AssemblyName("moduleCctor"));
+ Module mod = asm0.ManifestModule;
+
+ RuntimeHelpers.RunModuleConstructor(mod.ModuleHandle);
+ var oType = asm0.GetType("IntHolder",true);
+ MethodInfo check = oType.GetMethod("Check");
+ MethodInfo assign = oType.GetMethod("Assign");
+
+ object[] initial = {1};
+ object[] final = {100};
+
+ check.Invoke(null, initial);
+ assign.Invoke(null, final);
+ check.Invoke(null, final);
+ RuntimeHelpers.RunModuleConstructor(mod.ModuleHandle);
+ check.Invoke(null, final);
+
+
+ return 100;
+
+ }
+}
diff --git a/tests/src/baseservices/compilerservices/modulector/runmoduleconstructor.csproj b/tests/src/baseservices/compilerservices/modulector/runmoduleconstructor.csproj
new file mode 100644
index 0000000000..fff05ea610
--- /dev/null
+++ b/tests/src/baseservices/compilerservices/modulector/runmoduleconstructor.csproj
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <!-- Add Compile Object Here -->
+ <Compile Include="runmoduleconstructor.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="moduleCctor.ilproj" />
+ </ItemGroup>
+ <ItemGroup>
+ <NoWarn Include="42016,42020,42025,42024" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project>
diff --git a/tests/src/dir.common.props b/tests/src/dir.common.props
index f1700f5e7d..d5de5794d0 100644
--- a/tests/src/dir.common.props
+++ b/tests/src/dir.common.props
@@ -40,7 +40,7 @@
<BaseOutputPath Condition="'$(__TestRootDir)' != ''">$(__TestRootDir)\</BaseOutputPath>
<BaseOutputPathWithConfig>$(BaseOutputPath)\$(OSPlatformConfig)\</BaseOutputPathWithConfig>
<BinDir>$(BaseOutputPathWithConfig)</BinDir>
- <BaseIntermediateOutputPath>$(ProjectDir)\..\bin\tests\obj\$(OSPlatformConfig)\Managed</BaseIntermediateOutputPath>
+ <BaseIntermediateOutputPath>$(ProjectDir)\..\bin\tests\obj\$(OSPlatformConfig)\Managed\</BaseIntermediateOutputPath>
<BaseIntermediateOutputPath Condition="'$(__ManagedTestIntermediatesDir)' != ''">$(__ManagedTestIntermediatesDir)\</BaseIntermediateOutputPath>
<__NativeTestIntermediatesDir Condition="'$(__NativeTestIntermediatesDir)' == ''">$([System.IO.Path]::GetFullPath($(BaseOutputPathWithConfig)..\obj\$(BuildOS).$(Platform).$(Configuration)\Native\))</__NativeTestIntermediatesDir>
<BuildProjectRelativeDir>$(MSBuildProjectName)\</BuildProjectRelativeDir>
@@ -58,11 +58,6 @@
<TestRuntimeProjectLockJson>$(TestRuntimeProjectJsonDir)\project.lock.json</TestRuntimeProjectLockJson>
</PropertyGroup>
- <!-- Default priority building values. -->
- <PropertyGroup>
- <CLRTestKind Condition="'$(CLRTestKind)' == ' '">BuildAndRun</CLRTestKind>
- <CLRTestPriority Condition="'$(CLRTestPriority)' == ''">0</CLRTestPriority>
- </PropertyGroup>
</Project>
diff --git a/tests/src/dir.props b/tests/src/dir.props
index 3b2754c221..e8cdfd4036 100644
--- a/tests/src/dir.props
+++ b/tests/src/dir.props
@@ -10,7 +10,6 @@
<!-- Disable some C# warnings for the tests. -->
<NoWarn>78,162,164,168,169,219,251,252,414,429,642,649,652,675,1691,1717,1718,3001,3002,3003,3005,3008</NoWarn>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
- <CLRTestKind>BuildAndRun</CLRTestKind>
<SkipSigning Condition="'$(CrossGen)' == 'true'">true</SkipSigning>
<!-- Set the project.json directory for generated TestWrappers. -->
<TestWrappersPackagesConfigFileDirectory>$(MSBuildThisFileDirectory)TestWrappersConfig\</TestWrappersPackagesConfigFileDirectory>
@@ -35,6 +34,7 @@
<PropertyGroup>
<TargetsWindows>true</TargetsWindows>
<TestNugetRuntimeId>win7-x64</TestNugetRuntimeId>
+ <DefaultTestTFM>net45</DefaultTestTFM>
</PropertyGroup>
</When>
<When Condition="'$(OSGroup)'=='Linux'">
@@ -69,6 +69,14 @@
<TargetsUnknownUnix Condition="'$(TargetsUnix)' == 'true' AND '$(OSGroup)' != 'FreeBSD' AND '$(OSGroup)' != 'Linux' AND '$(OSGroup)' != 'OSX'">true</TargetsUnknownUnix>
</PropertyGroup>
+ <!-- Default Test platform to deploy the netstandard compiled tests to -->
+ <PropertyGroup>
+ <!-- we default TestTFM and FilterToTestTFM to netcoreapp1.0 if they are not explicity defined -->
+ <DefaultTestTFM Condition="'$(DefaultTestTFM)'==''">netcoreapp1.0</DefaultTestTFM>
+ <TestTFM Condition="'$(TestTFM)'==''">$(DefaultTestTFM)</TestTFM>
+ <FilterToTestTFM Condition="'$(FilterToTestTFM)'==''">$(DefaultTestTFM)</FilterToTestTFM>
+ </PropertyGroup>
+
<!-- Set default ZapRequire level (used only when CrossGen is enabled) -->
<PropertyGroup>
<ZapRequire Condition="'$(ZapRequire)' == ''">2</ZapRequire>
@@ -77,5 +85,8 @@
<PropertyGroup>
<ProjectJson>$(SourceDir)Common\test_dependencies\project.json</ProjectJson>
<ProjectLockJson>$(SourceDir)Common\test_dependencies\project.lock.json</ProjectLockJson>
+
+ <!-- Specify the target framework of the common test dependency project.json. -->
+ <NuGetTargetMoniker>.NETCoreApp,Version=v1.1</NuGetTargetMoniker>
</PropertyGroup>
</Project>
diff --git a/tests/src/dir.targets b/tests/src/dir.targets
index 31d9304880..64b56667f3 100644
--- a/tests/src/dir.targets
+++ b/tests/src/dir.targets
@@ -1,8 +1,23 @@
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <!-- Default priority building values. -->
+ <PropertyGroup>
+ <CLRTestKind Condition="'$(CLRTestKind)' == '' and '$(OutputType)' == 'Library'">SharedLibrary</CLRTestKind>
+ <CLRTestKind Condition="'$(CLRTestKind)' == ''">BuildAndRun</CLRTestKind>
+ <CLRTestPriority Condition="'$(CLRTestPriority)' == ''">0</CLRTestPriority>
+ </PropertyGroup>
+
<!-- All CLRTests need to be of a certain "kind". These kinds are enumerated below.
By default all tests are BuildAndRun. This means that the build system will Build them
and construct a run-batch-script for them. -->
<Choose>
+ <When Condition=" '$(CLRTestKind)'=='SharedLibrary'">
+ <PropertyGroup>
+ <_CLRTestCompilesSource>true</_CLRTestCompilesSource>
+ <_CLRTestNeedsToRun>false</_CLRTestNeedsToRun>
+ <GenerateRunScript>false</GenerateRunScript>
+ <_CLRTestBuildsExecutable>false</_CLRTestBuildsExecutable>
+ </PropertyGroup>
+ </When>
<When Condition=" '$(CLRTestKind)'=='BuildAndRun' ">
<PropertyGroup>
<GenerateRunScript>true</GenerateRunScript>
@@ -28,14 +43,6 @@
<_CLRTestCompilesSource>false</_CLRTestCompilesSource>
</PropertyGroup>
</When>
- <When Condition=" '$(CLRTestKind)'=='SharedLibrary' Or '$(OutputType)' == 'Library' ">
- <PropertyGroup>
- <_CLRTestCompilesSource>true</_CLRTestCompilesSource>
- <_CLRTestNeedsToRun>false</_CLRTestNeedsToRun>
- <GenerateRunScript>false</GenerateRunScript>
- <_CLRTestBuildsExecutable>false</_CLRTestBuildsExecutable>
- </PropertyGroup>
- </When>
</Choose>
<PropertyGroup>
@@ -80,11 +87,6 @@
<MSBuild Projects="@(ProjectReference)" />
<MakeDir Condition="'$(CLRTestKind)' == 'RunOnly'" ContinueOnError="false" Directories="$(OutputPath)" />
</Target>
-
- <Target Name="CopyJsonProjectFiles" AfterTargets="Build">
- <!-- Post build copy project json files so we can generate assembly lists for the projects -->
- <Copy SourceFiles="$(ProjectLockJson)" DestinationFolder="$(OutputPath)" Condition="Exists('$(ProjectLockJson)')" />
- </Target>
<!-- We will use an imported build here in the instance that we have source that we need to build, and we are the correct priority...OR if we are being asked to build for
a test with a higher priority. -->
diff --git a/tests/src/jit/Directed/pinvoke/pinvoke-bug.cs b/tests/src/jit/Directed/pinvoke/pinvoke-bug.cs
new file mode 100644
index 0000000000..2d4b5f6aea
--- /dev/null
+++ b/tests/src/jit/Directed/pinvoke/pinvoke-bug.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.Runtime.InteropServices;
+
+// Test includes an intentional unreachable return
+#pragma warning disable 162
+
+namespace PInvokeTest
+{
+ internal class Test
+ {
+ [DllImport("msvcrt", EntryPoint = "sin")]
+ private static extern double sin(double x);
+
+ private static double g;
+ private static bool b;
+
+ public static int Main(string[] args)
+ {
+ bool result = false;
+ g = 0.0;
+ double val = 1.0;
+ b = false;
+ try
+ {
+ Func(val);
+ }
+ catch(Exception)
+ {
+ result = (Math.Abs(g - sin(val)) < 0.0001);
+ }
+
+ return (result ? 100 : -1);
+ }
+
+ // An inline pinvoke in a method with float math followed by a
+ // throw may causes trouble for liveness models for the inline
+ // frame var.
+ static double Func(double x)
+ {
+ g = sin(x);
+
+ // A bit of control flow to throw off rareness detection
+ // Also we need float in here
+ if (b)
+ {
+ g = 0.0;
+ }
+
+ throw new Exception();
+
+ // Deliberately unreachable return
+ return g;
+ }
+ }
+}
+
diff --git a/tests/src/jit/Directed/pinvoke/pinvoke-bug.csproj b/tests/src/jit/Directed/pinvoke/pinvoke-bug.csproj
new file mode 100644
index 0000000000..2f8a24638b
--- /dev/null
+++ b/tests/src/jit/Directed/pinvoke/pinvoke-bug.csproj
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>PdbOnly</DebugType>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="pinvoke-bug.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)minimal\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)minimal\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project> \ No newline at end of file
diff --git a/tests/src/performance/perflab/BlockCopyPerf.cs b/tests/src/performance/perflab/BlockCopyPerf.cs
index 076d436558..5259d10530 100644
--- a/tests/src/performance/perflab/BlockCopyPerf.cs
+++ b/tests/src/performance/perflab/BlockCopyPerf.cs
@@ -5,21 +5,24 @@ using Microsoft.Xunit.Performance;
using System;
using Xunit;
-public class BlockCopyPerf
+namespace PerfLabTests
{
- [Benchmark(InnerIterationCount=1000000)]
- [InlineData(0)]
- [InlineData(10)]
- [InlineData(100)]
- [InlineData(1000)]
- public static void CallBlockCopy(int numElements)
+ public class BlockCopyPerf
{
- byte[] bytes = new byte[numElements * 2];
- Buffer.BlockCopy(bytes, 0, bytes, numElements, numElements);
+ [Benchmark(InnerIterationCount = 1000000)]
+ [InlineData(0)]
+ [InlineData(10)]
+ [InlineData(100)]
+ [InlineData(1000)]
+ public static void CallBlockCopy(int numElements)
+ {
+ byte[] bytes = new byte[numElements * 2];
+ Buffer.BlockCopy(bytes, 0, bytes, numElements, numElements);
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for(int i=0; i<Benchmark.InnerIterationCount; i++)
- Buffer.BlockCopy(bytes, 0, bytes, numElements, numElements);
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ Buffer.BlockCopy(bytes, 0, bytes, numElements, numElements);
+ }
}
}
diff --git a/tests/src/performance/perflab/CastingPerf.cs b/tests/src/performance/perflab/CastingPerf.cs
index bd314974cc..fa83a19d72 100644
--- a/tests/src/performance/perflab/CastingPerf.cs
+++ b/tests/src/performance/perflab/CastingPerf.cs
@@ -5,385 +5,389 @@ using Microsoft.Xunit.Performance;
using System;
using System.Collections.Generic;
-public interface IFoo
+namespace PerfLabTests
{
-}
-public interface IFoo_1
-{
-}
-
-public interface IFoo_2
-{
-}
-
-public interface IFoo_3
-{
-}
-
-public interface IFoo_4
-{
-}
-
-public interface IFoo_5
-{
-}
-
-// C# lays the interfaces in reverse order in metadata. So IFoo is the first and IFoo_5 is last
-public class Foo : IFoo_5, IFoo_4, IFoo_3, IFoo_2, IFoo_1, IFoo
-{
- public int m_i;
-}
-
-public class Foo_1 : Foo
-{
- public int m_j;
-}
-
-public class Foo_2 : Foo_1
-{
- public int m_k;
-}
-
-public class Foo_3 : Foo_2
-{
- public int m_l;
-}
-
-public class Foo_4 : Foo_3
-{
- public int m_m;
-}
-
-public class Foo_5 : Foo_4
-{
- public int m_n;
-}
-
-// C# lays the interfaces in reverse order in metadata. So IFoo_1 is the first and IFoo is last
-public class Foo2 : IFoo, IFoo_5, IFoo_4, IFoo_3, IFoo_2, IFoo_1
-{
- public int m_i;
-}
-
-public struct FooSVT
-{
- public int m_i;
- public int m_j;
-}
-
-public struct FooORVT
-{
- public Object m_o;
- public Foo m_f;
-}
-
-public interface IMyInterface1 { }
-public interface IMyInterface2 { }
-public class MyClass1 : IMyInterface1 { }
-public class MyClass2 : IMyInterface2 { }
-public class MyClass4<T> : IMyInterface1 { }
-
-public class CastingPerf
-{
- public const int NUM_ARRAY_ELEMENTS = 100;
-
- public static int[] j;
- public static int[] k;
- public static Foo[] foo;
- public static Foo2[] foo2;
- public static Foo[] n;
- public static Foo_5[] foo_5;
- public static FooSVT[] svt;
- public static FooORVT[] orvt;
-
- public static Object o;
- public static Object[] o_ar;
- public static Foo[] f;
- public static IFoo[] ifo;
- public static IFoo_5[] if_5;
-
- static CastingPerf()
+ public interface IFoo
{
- j = new int[NUM_ARRAY_ELEMENTS];
- for (int i = 0; i < j.Length; i++)
- {
- j[i] = i;
- }
- foo = new Foo[NUM_ARRAY_ELEMENTS];
- for (int i = 0; i < foo.Length; i++)
- {
- foo[i] = new Foo();
- }
- foo2 = new Foo2[NUM_ARRAY_ELEMENTS];
- for (int i = 0; i < foo2.Length; i++)
- {
- foo2[i] = new Foo2();
- }
- n = new Foo[NUM_ARRAY_ELEMENTS];
- foo_5 = new Foo_5[NUM_ARRAY_ELEMENTS];
- for (int i = 0; i < foo_5.Length; i++)
- {
- foo_5[i] = new Foo_5();
- }
- svt = new FooSVT[NUM_ARRAY_ELEMENTS];
- orvt = new FooORVT[NUM_ARRAY_ELEMENTS];
}
- [Benchmark(InnerIterationCount=100000)]
- public static void ObjFooIsObj()
+ public interface IFoo_1
{
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- o = foo;
}
- [Benchmark(InnerIterationCount=100000)]
- public static void ObjFooIsObj2()
+ public interface IFoo_2
{
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- o_ar = foo;
}
- [Benchmark(InnerIterationCount=100000)]
- public static void ObjObjIsFoo()
+ public interface IFoo_3
{
- o = foo;
-
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- o_ar = (Object[])o;
}
- [Benchmark(InnerIterationCount=100000)]
- public static void FooObjIsFoo()
+ public interface IFoo_4
{
- o = foo;
-
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- f = (Foo[])o;
}
- [Benchmark(InnerIterationCount=100000)]
- public static void FooObjIsFoo2()
+ public interface IFoo_5
{
- o_ar = foo;
-
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- f = (Foo[])o_ar;
}
- [Benchmark(InnerIterationCount=100000)]
- public static void FooObjIsNull()
+ // C# lays the interfaces in reverse order in metadata. So IFoo is the first and IFoo_5 is last
+ public class Foo : IFoo_5, IFoo_4, IFoo_3, IFoo_2, IFoo_1, IFoo
{
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- o = (Foo[])n;
+ public int m_i;
}
- [Benchmark(InnerIterationCount=100000)]
- public static void FooObjIsDescendant()
+ public class Foo_1 : Foo
{
- o = foo_5;
-
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- f = (Foo[])o;
+ public int m_j;
}
- [Benchmark(InnerIterationCount=100000)]
- public static void IFooFooIsIFoo()
+ public class Foo_2 : Foo_1
{
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- ifo = foo;
+ public int m_k;
}
- [Benchmark(InnerIterationCount=100000)]
- public static void IFooObjIsIFoo()
+ public class Foo_3 : Foo_2
{
- o = foo;
-
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- ifo = (IFoo[])o;
+ public int m_l;
}
- [Benchmark(InnerIterationCount=100000)]
- public static void IFooObjIsIFooInterAlia()
+ public class Foo_4 : Foo_3
{
- o = foo2;
-
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- if_5 = (IFoo_5[])o;
+ public int m_m;
}
- [Benchmark(InnerIterationCount=100000)]
- public static void IFooObjIsDescendantOfIFoo()
+ public class Foo_5 : Foo_4
{
- o = foo_5;
-
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- ifo = (IFoo[])o;
+ public int m_n;
}
- [Benchmark(InnerIterationCount=100000)]
- public static void ObjInt()
+ // C# lays the interfaces in reverse order in metadata. So IFoo_1 is the first and IFoo is last
+ public class Foo2 : IFoo, IFoo_5, IFoo_4, IFoo_3, IFoo_2, IFoo_1
{
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- o = (Object)j;
+ public int m_i;
}
- [Benchmark(InnerIterationCount=100000)]
- public static void IntObj()
+ public struct FooSVT
{
- o = (Object)j;
-
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- k = (int[])o;
+ public int m_i;
+ public int m_j;
}
- [Benchmark(InnerIterationCount=100000)]
- public static void ObjScalarValueType()
+ public struct FooORVT
{
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- o = svt;
+ public Object m_o;
+ public Foo m_f;
}
- [Benchmark(InnerIterationCount=100000)]
- public static void ScalarValueTypeObj()
+ public interface IMyInterface1 { }
+ public interface IMyInterface2 { }
+ public class MyClass1 : IMyInterface1 { }
+ public class MyClass2 : IMyInterface2 { }
+ public class MyClass4<T> : IMyInterface1 { }
+
+ public class CastingPerf
{
- o = svt;
+ public const int NUM_ARRAY_ELEMENTS = 100;
+
+ public static int[] j;
+ public static int[] k;
+ public static Foo[] foo;
+ public static Foo2[] foo2;
+ public static Foo[] n;
+ public static Foo_5[] foo_5;
+ public static FooSVT[] svt;
+ public static FooORVT[] orvt;
+
+ public static Object o;
+ public static Object[] o_ar;
+ public static Foo[] f;
+ public static IFoo[] ifo;
+ public static IFoo_5[] if_5;
+
+ static CastingPerf()
+ {
+ j = new int[NUM_ARRAY_ELEMENTS];
+ for (int i = 0; i < j.Length; i++)
+ {
+ j[i] = i;
+ }
+ foo = new Foo[NUM_ARRAY_ELEMENTS];
+ for (int i = 0; i < foo.Length; i++)
+ {
+ foo[i] = new Foo();
+ }
+ foo2 = new Foo2[NUM_ARRAY_ELEMENTS];
+ for (int i = 0; i < foo2.Length; i++)
+ {
+ foo2[i] = new Foo2();
+ }
+ n = new Foo[NUM_ARRAY_ELEMENTS];
+ foo_5 = new Foo_5[NUM_ARRAY_ELEMENTS];
+ for (int i = 0; i < foo_5.Length; i++)
+ {
+ foo_5[i] = new Foo_5();
+ }
+ svt = new FooSVT[NUM_ARRAY_ELEMENTS];
+ orvt = new FooORVT[NUM_ARRAY_ELEMENTS];
+ }
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- svt = (FooSVT[])o;
- }
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void ObjFooIsObj()
+ {
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ o = foo;
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static void ObjObjrefValueType()
- {
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- o = (Object)orvt;
- }
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void ObjFooIsObj2()
+ {
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ o_ar = foo;
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static void ObjrefValueTypeObj()
- {
- o = (Object)orvt;
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void ObjObjIsFoo()
+ {
+ o = foo;
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- orvt = (FooORVT[])o;
- }
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ o_ar = (Object[])o;
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static void FooObjCastIfIsa()
- {
- o = foo;
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void FooObjIsFoo()
+ {
+ o = foo;
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- if (o is Foo[])
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
f = (Foo[])o;
- }
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static bool CheckObjIsInterfaceYes()
- {
- bool res = false;
- Object obj = new MyClass1();
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- res = obj is IMyInterface1;
- return res;
- }
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void FooObjIsFoo2()
+ {
+ o_ar = foo;
- [Benchmark(InnerIterationCount=100000)]
- public static bool CheckObjIsInterfaceNo()
- {
- bool res = false;
- Object obj = new MyClass2();
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- res = obj is IMyInterface1;
- return res;
- }
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ f = (Foo[])o_ar;
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static bool CheckIsInstAnyIsInterfaceYes()
- {
- bool res = false;
- Object obj = new MyClass4<List<string>>();
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- res = obj is IMyInterface1;
- return res;
- }
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void FooObjIsNull()
+ {
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ o = (Foo[])n;
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static bool CheckIsInstAnyIsInterfaceNo()
- {
- bool res = false;
- Object obj = new MyClass4<List<string>>();
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- res = obj is IMyInterface2;
- return res;
- }
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void FooObjIsDescendant()
+ {
+ o = foo_5;
- [Benchmark(InnerIterationCount=100000)]
- public static bool CheckArrayIsInterfaceYes()
- {
- bool res = false;
- Object[] arr = new MyClass1[5];
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- res = arr is IMyInterface1[];
- return res;
- }
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ f = (Foo[])o;
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static bool CheckArrayIsInterfaceNo()
- {
- bool res = false;
- Object[] arr = new MyClass2[5];
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- res = arr is IMyInterface1[];
- return res;
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void IFooFooIsIFoo()
+ {
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ ifo = foo;
+ }
+
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void IFooObjIsIFoo()
+ {
+ o = foo;
+
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ ifo = (IFoo[])o;
+ }
+
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void IFooObjIsIFooInterAlia()
+ {
+ o = foo2;
+
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ if_5 = (IFoo_5[])o;
+ }
+
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void IFooObjIsDescendantOfIFoo()
+ {
+ o = foo_5;
+
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ ifo = (IFoo[])o;
+ }
+
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void ObjInt()
+ {
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ o = (Object)j;
+ }
+
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void IntObj()
+ {
+ o = (Object)j;
+
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ k = (int[])o;
+ }
+
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void ObjScalarValueType()
+ {
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ o = svt;
+ }
+
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void ScalarValueTypeObj()
+ {
+ o = svt;
+
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ svt = (FooSVT[])o;
+ }
+
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void ObjObjrefValueType()
+ {
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ o = (Object)orvt;
+ }
+
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void ObjrefValueTypeObj()
+ {
+ o = (Object)orvt;
+
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ orvt = (FooORVT[])o;
+ }
+
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void FooObjCastIfIsa()
+ {
+ o = foo;
+
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ if (o is Foo[])
+ f = (Foo[])o;
+ }
+
+ [Benchmark(InnerIterationCount = 100000)]
+ public static bool CheckObjIsInterfaceYes()
+ {
+ bool res = false;
+ Object obj = new MyClass1();
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ res = obj is IMyInterface1;
+ return res;
+ }
+
+ [Benchmark(InnerIterationCount = 100000)]
+ public static bool CheckObjIsInterfaceNo()
+ {
+ bool res = false;
+ Object obj = new MyClass2();
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ res = obj is IMyInterface1;
+ return res;
+ }
+
+ [Benchmark(InnerIterationCount = 100000)]
+ public static bool CheckIsInstAnyIsInterfaceYes()
+ {
+ bool res = false;
+ Object obj = new MyClass4<List<string>>();
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ res = obj is IMyInterface1;
+ return res;
+ }
+
+ [Benchmark(InnerIterationCount = 100000)]
+ public static bool CheckIsInstAnyIsInterfaceNo()
+ {
+ bool res = false;
+ Object obj = new MyClass4<List<string>>();
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ res = obj is IMyInterface2;
+ return res;
+ }
+
+ [Benchmark(InnerIterationCount = 100000)]
+ public static bool CheckArrayIsInterfaceYes()
+ {
+ bool res = false;
+ Object[] arr = new MyClass1[5];
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ res = arr is IMyInterface1[];
+ return res;
+ }
+
+ [Benchmark(InnerIterationCount = 100000)]
+ public static bool CheckArrayIsInterfaceNo()
+ {
+ bool res = false;
+ Object[] arr = new MyClass2[5];
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ res = arr is IMyInterface1[];
+ return res;
+ }
}
-}
+} \ No newline at end of file
diff --git a/tests/src/performance/perflab/CastingPerf2.cs b/tests/src/performance/perflab/CastingPerf2.cs
index 1f874a56c3..82131ba493 100644
--- a/tests/src/performance/perflab/CastingPerf2.cs
+++ b/tests/src/performance/perflab/CastingPerf2.cs
@@ -2,10 +2,10 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
-using CastingPerf2;
+using PerfLabTests.CastingPerf2;
using Microsoft.Xunit.Performance;
-namespace CastingPerf2
+namespace PerfLabTests.CastingPerf2
{
public interface IFoo
{
@@ -95,7 +95,7 @@ namespace CastingPerf2
public static IFoo ifo, ifo1, ifo2, ifo3, ifo4, ifo5, ifo6, ifo7, ifo8, ifo9;
public static IFoo_5 if_0, if_1, if_2, if_3, if_4, if_5, if_6, if_7, if_8, if_9;
- [Benchmark(InnerIterationCount=200000)]
+ [Benchmark(InnerIterationCount = 200000)]
public static void ObjFooIsObj()
{
foreach (var iteration in Benchmark.Iterations)
@@ -104,7 +104,7 @@ namespace CastingPerf2
o = foo;
}
- [Benchmark(InnerIterationCount=200000)]
+ [Benchmark(InnerIterationCount = 200000)]
public static void FooObjIsFoo()
{
o = foo;
@@ -115,7 +115,7 @@ namespace CastingPerf2
f = (Foo)o;
}
- [Benchmark(InnerIterationCount=200000)]
+ [Benchmark(InnerIterationCount = 200000)]
public static void FooObjIsNull()
{
foreach (var iteration in Benchmark.Iterations)
@@ -124,7 +124,7 @@ namespace CastingPerf2
o = (Foo)n;
}
- [Benchmark(InnerIterationCount=100000)]
+ [Benchmark(InnerIterationCount = 100000)]
public static void FooObjIsDescendant()
{
o = foo_5;
@@ -135,7 +135,7 @@ namespace CastingPerf2
f = (Foo)o;
}
- [Benchmark(InnerIterationCount=200000)]
+ [Benchmark(InnerIterationCount = 200000)]
public static void IFooFooIsIFoo()
{
foreach (var iteration in Benchmark.Iterations)
@@ -144,7 +144,7 @@ namespace CastingPerf2
ifo = foo;
}
- [Benchmark(InnerIterationCount=100000)]
+ [Benchmark(InnerIterationCount = 100000)]
public static void IFooObjIsIFoo()
{
o = foo;
@@ -155,7 +155,7 @@ namespace CastingPerf2
ifo = (IFoo)o;
}
- [Benchmark(InnerIterationCount=100000)]
+ [Benchmark(InnerIterationCount = 100000)]
public static void IFooObjIsIFooInterAlia()
{
o = foo2;
@@ -166,7 +166,7 @@ namespace CastingPerf2
if_0 = (IFoo_5)o;
}
- [Benchmark(InnerIterationCount=100000)]
+ [Benchmark(InnerIterationCount = 100000)]
public static void IFooObjIsDescendantOfIFoo()
{
o = foo_5;
@@ -177,7 +177,7 @@ namespace CastingPerf2
ifo = (IFoo)o;
}
- [Benchmark(InnerIterationCount=100000)]
+ [Benchmark(InnerIterationCount = 100000)]
public static void ObjInt()
{
foreach (var iteration in Benchmark.Iterations)
@@ -186,7 +186,7 @@ namespace CastingPerf2
o = (Object)j;
}
- [Benchmark(InnerIterationCount=200000)]
+ [Benchmark(InnerIterationCount = 200000)]
public static void IntObj()
{
o = (Object)1;
@@ -197,7 +197,7 @@ namespace CastingPerf2
j = (int)o;
}
- [Benchmark(InnerIterationCount=100000)]
+ [Benchmark(InnerIterationCount = 100000)]
public static void ObjScalarValueType()
{
foreach (var iteration in Benchmark.Iterations)
@@ -206,7 +206,7 @@ namespace CastingPerf2
o = svt;
}
- [Benchmark(InnerIterationCount=300000)]
+ [Benchmark(InnerIterationCount = 300000)]
public static void ScalarValueTypeObj()
{
o = svt;
@@ -217,7 +217,7 @@ namespace CastingPerf2
svt = (FooSVT)o;
}
- [Benchmark(InnerIterationCount=100000)]
+ [Benchmark(InnerIterationCount = 100000)]
public static void ObjObjrefValueType()
{
foreach (var iteration in Benchmark.Iterations)
@@ -226,7 +226,7 @@ namespace CastingPerf2
o = (Object)orvt;
}
- [Benchmark(InnerIterationCount=200000)]
+ [Benchmark(InnerIterationCount = 200000)]
public static void ObjrefValueTypeObj()
{
o = (Object)orvt;
@@ -237,7 +237,7 @@ namespace CastingPerf2
orvt = (FooORVT)o;
}
- [Benchmark(InnerIterationCount=100000)]
+ [Benchmark(InnerIterationCount = 100000)]
public static void FooObjCastIfIsa()
{
o = foo;
diff --git a/tests/src/performance/perflab/DelegatePerf.cs b/tests/src/performance/perflab/DelegatePerf.cs
index abc311a445..61f12a2dff 100644
--- a/tests/src/performance/perflab/DelegatePerf.cs
+++ b/tests/src/performance/perflab/DelegatePerf.cs
@@ -5,92 +5,96 @@ using Microsoft.Xunit.Performance;
using System;
using Xunit;
-internal delegate long DelegateLong(Object obj, long x, long y);
-internal delegate void MultiDelegate(Object obj, long x, long y);
-
-internal delegate int SerializeDelegate();
-
-public class DelegatePerf
+namespace PerfLabTests
{
- [Benchmark(InnerIterationCount=200000)]
- public void DelegateInvoke()
- {
- DelegateLong dl = new DelegateLong(this.Invocable1);
- Object obj = new Object();
- long ret = dl(obj, 100, 100);
+ internal delegate long DelegateLong(Object obj, long x, long y);
+ internal delegate void MultiDelegate(Object obj, long x, long y);
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- ret = dl(obj, 100, 100);
- }
+ internal delegate int SerializeDelegate();
- [Benchmark(InnerIterationCount=1000)]
- public void MulticastDelegateCombineInvoke()
+ public class DelegatePerf
{
- MultiDelegate md = null;
- Object obj = new Object();
+ [Benchmark(InnerIterationCount = 200000)]
+ public void DelegateInvoke()
+ {
+ DelegateLong dl = new DelegateLong(this.Invocable1);
+ Object obj = new Object();
+
+ long ret = dl(obj, 100, 100);
- foreach (var iteration in Benchmark.Iterations)
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ ret = dl(obj, 100, 100);
+ }
+
+ [Benchmark(InnerIterationCount = 1000)]
+ public void MulticastDelegateCombineInvoke()
{
- MultiDelegate md1 = new MultiDelegate(this.Invocable2);
- MultiDelegate md2 = new MultiDelegate(this.Invocable2);
- MultiDelegate md3 = new MultiDelegate(this.Invocable2);
- MultiDelegate md4 = new MultiDelegate(this.Invocable2);
- MultiDelegate md5 = new MultiDelegate(this.Invocable2);
- MultiDelegate md6 = new MultiDelegate(this.Invocable2);
- MultiDelegate md7 = new MultiDelegate(this.Invocable2);
- MultiDelegate md8 = new MultiDelegate(this.Invocable2);
- MultiDelegate md9 = new MultiDelegate(this.Invocable2);
- MultiDelegate md10 = new MultiDelegate(this.Invocable2);
-
- using (iteration.StartMeasurement())
+ MultiDelegate md = null;
+ Object obj = new Object();
+
+ foreach (var iteration in Benchmark.Iterations)
{
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ MultiDelegate md1 = new MultiDelegate(this.Invocable2);
+ MultiDelegate md2 = new MultiDelegate(this.Invocable2);
+ MultiDelegate md3 = new MultiDelegate(this.Invocable2);
+ MultiDelegate md4 = new MultiDelegate(this.Invocable2);
+ MultiDelegate md5 = new MultiDelegate(this.Invocable2);
+ MultiDelegate md6 = new MultiDelegate(this.Invocable2);
+ MultiDelegate md7 = new MultiDelegate(this.Invocable2);
+ MultiDelegate md8 = new MultiDelegate(this.Invocable2);
+ MultiDelegate md9 = new MultiDelegate(this.Invocable2);
+ MultiDelegate md10 = new MultiDelegate(this.Invocable2);
+
+ using (iteration.StartMeasurement())
{
- md = (MultiDelegate)Delegate.Combine(md1, md);
- md = (MultiDelegate)Delegate.Combine(md2, md);
- md = (MultiDelegate)Delegate.Combine(md3, md);
- md = (MultiDelegate)Delegate.Combine(md4, md);
- md = (MultiDelegate)Delegate.Combine(md5, md);
- md = (MultiDelegate)Delegate.Combine(md6, md);
- md = (MultiDelegate)Delegate.Combine(md7, md);
- md = (MultiDelegate)Delegate.Combine(md8, md);
- md = (MultiDelegate)Delegate.Combine(md9, md);
- md = (MultiDelegate)Delegate.Combine(md10, md);
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ {
+ md = (MultiDelegate)Delegate.Combine(md1, md);
+ md = (MultiDelegate)Delegate.Combine(md2, md);
+ md = (MultiDelegate)Delegate.Combine(md3, md);
+ md = (MultiDelegate)Delegate.Combine(md4, md);
+ md = (MultiDelegate)Delegate.Combine(md5, md);
+ md = (MultiDelegate)Delegate.Combine(md6, md);
+ md = (MultiDelegate)Delegate.Combine(md7, md);
+ md = (MultiDelegate)Delegate.Combine(md8, md);
+ md = (MultiDelegate)Delegate.Combine(md9, md);
+ md = (MultiDelegate)Delegate.Combine(md10, md);
+ }
}
}
- }
- md(obj, 100, 100);
- }
+ md(obj, 100, 100);
+ }
- [Benchmark(InnerIterationCount=10000)]
- [InlineData(100)]
- [InlineData(1000)]
- public void MulticastDelegateInvoke(int length)
- {
- MultiDelegate md = null;
- Object obj = new Object();
+ [Benchmark(InnerIterationCount = 10000)]
+ [InlineData(100)]
+ [InlineData(1000)]
+ public void MulticastDelegateInvoke(int length)
+ {
+ MultiDelegate md = null;
+ Object obj = new Object();
- for (long i = 0; i < length; i++)
- md = (MultiDelegate)Delegate.Combine(new MultiDelegate(this.Invocable2), md);
+ for (long i = 0; i < length; i++)
+ md = (MultiDelegate)Delegate.Combine(new MultiDelegate(this.Invocable2), md);
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- md(obj, 100, 100);
- }
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ md(obj, 100, 100);
+ }
- internal virtual long Invocable1(Object obj, long x, long y)
- {
- long i = x + y;
- return x;
- }
+ internal virtual long Invocable1(Object obj, long x, long y)
+ {
+ long i = x + y;
+ return x;
+ }
- internal virtual void Invocable2(Object obj, long x, long y)
- {
- long i = x + y;
+ internal virtual void Invocable2(Object obj, long x, long y)
+ {
+ long i = x + y;
+ }
}
}
diff --git a/tests/src/performance/perflab/EnumPerf.cs b/tests/src/performance/perflab/EnumPerf.cs
index bf8d89b476..1e3a493686 100644
--- a/tests/src/performance/perflab/EnumPerf.cs
+++ b/tests/src/performance/perflab/EnumPerf.cs
@@ -6,71 +6,74 @@ using System;
using System.Reflection;
using Xunit;
-public enum Color
+namespace PerfLabTests
{
- Black,
- White,
- Red,
- Brown,
- Yellow,
- Purple,
- Orange
-}
-
-public class EnumPerf
-{
- [Benchmark(InnerIterationCount=300000)]
- [InlineData(Color.Red)]
- public static void EnumCompareTo(Color color)
+ public enum Color
{
- Color white = Color.White;
-
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- color.CompareTo(white);
+ Black,
+ White,
+ Red,
+ Brown,
+ Yellow,
+ Purple,
+ Orange
}
- [Benchmark(InnerIterationCount=300000)]
- public static Type ObjectGetType()
+ public class EnumPerf
{
- Type tmp = null;
- Color black = Color.Black;
+ [Benchmark(InnerIterationCount = 300000)]
+ [InlineData(Color.Red)]
+ public static void EnumCompareTo(Color color)
+ {
+ Color white = Color.White;
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- tmp = black.GetType();
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ color.CompareTo(white);
+ }
- return tmp;
- }
+ [Benchmark(InnerIterationCount = 300000)]
+ public static Type ObjectGetType()
+ {
+ Type tmp = null;
+ Color black = Color.Black;
- [Benchmark(InnerIterationCount=300000)]
- public static Type ObjectGetTypeNoBoxing()
- {
- Type tmp = null;
- object black = Color.Black;
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ tmp = black.GetType();
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- tmp = black.GetType();
+ return tmp;
+ }
- return tmp;
- }
+ [Benchmark(InnerIterationCount = 300000)]
+ public static Type ObjectGetTypeNoBoxing()
+ {
+ Type tmp = null;
+ object black = Color.Black;
- [Benchmark(InnerIterationCount=300000)]
- public static bool EnumEquals()
- {
- Color black = Color.Black;
- Color white = Color.White;
- bool tmp = false;
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ tmp = black.GetType();
+
+ return tmp;
+ }
+
+ [Benchmark(InnerIterationCount = 300000)]
+ public static bool EnumEquals()
+ {
+ Color black = Color.Black;
+ Color white = Color.White;
+ bool tmp = false;
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- tmp = black.Equals(white);
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ tmp = black.Equals(white);
- return tmp;
+ return tmp;
+ }
}
}
diff --git a/tests/src/performance/perflab/LowLevelPerf.cs b/tests/src/performance/perflab/LowLevelPerf.cs
index 30c6734d45..a1f1a40c21 100644
--- a/tests/src/performance/perflab/LowLevelPerf.cs
+++ b/tests/src/performance/perflab/LowLevelPerf.cs
@@ -7,796 +7,799 @@ using System.Collections.Generic;
using System.Threading;
using System.Runtime.CompilerServices;
-public class LowLevelPerf
+namespace PerfLabTests
{
- [Benchmark(InnerIterationCount=100000)]
- public static void EmptyStaticFunction()
+ public class LowLevelPerf
{
- foreach (var iteration in Benchmark.Iterations)
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void EmptyStaticFunction()
{
- using (iteration.StartMeasurement())
+ foreach (var iteration in Benchmark.Iterations)
{
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ using (iteration.StartMeasurement())
{
- Class.EmptyStaticFunction();
- Class.EmptyStaticFunction();
- Class.EmptyStaticFunction();
- Class.EmptyStaticFunction();
- Class.EmptyStaticFunction();
- Class.EmptyStaticFunction();
- Class.EmptyStaticFunction();
- Class.EmptyStaticFunction();
- Class.EmptyStaticFunction();
- Class.EmptyStaticFunction();
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ {
+ Class.EmptyStaticFunction();
+ Class.EmptyStaticFunction();
+ Class.EmptyStaticFunction();
+ Class.EmptyStaticFunction();
+ Class.EmptyStaticFunction();
+ Class.EmptyStaticFunction();
+ Class.EmptyStaticFunction();
+ Class.EmptyStaticFunction();
+ Class.EmptyStaticFunction();
+ Class.EmptyStaticFunction();
+ }
}
}
}
- }
- [Benchmark(InnerIterationCount=100000)]
- public static void EmptyStaticFunction5Arg()
- {
- foreach (var iteration in Benchmark.Iterations)
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void EmptyStaticFunction5Arg()
{
- using (iteration.StartMeasurement())
+ foreach (var iteration in Benchmark.Iterations)
{
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ using (iteration.StartMeasurement())
{
- Class.EmptyStaticFunction5Arg(1, 2, 3, 4, 5);
- Class.EmptyStaticFunction5Arg(1, 2, 3, 4, 5);
- Class.EmptyStaticFunction5Arg(1, 2, 3, 4, 5);
- Class.EmptyStaticFunction5Arg(1, 2, 3, 4, 5);
- Class.EmptyStaticFunction5Arg(1, 2, 3, 4, 5);
- Class.EmptyStaticFunction5Arg(1, 2, 3, 4, 5);
- Class.EmptyStaticFunction5Arg(1, 2, 3, 4, 5);
- Class.EmptyStaticFunction5Arg(1, 2, 3, 4, 5);
- Class.EmptyStaticFunction5Arg(1, 2, 3, 4, 5);
- Class.EmptyStaticFunction5Arg(1, 2, 3, 4, 5);
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ {
+ Class.EmptyStaticFunction5Arg(1, 2, 3, 4, 5);
+ Class.EmptyStaticFunction5Arg(1, 2, 3, 4, 5);
+ Class.EmptyStaticFunction5Arg(1, 2, 3, 4, 5);
+ Class.EmptyStaticFunction5Arg(1, 2, 3, 4, 5);
+ Class.EmptyStaticFunction5Arg(1, 2, 3, 4, 5);
+ Class.EmptyStaticFunction5Arg(1, 2, 3, 4, 5);
+ Class.EmptyStaticFunction5Arg(1, 2, 3, 4, 5);
+ Class.EmptyStaticFunction5Arg(1, 2, 3, 4, 5);
+ Class.EmptyStaticFunction5Arg(1, 2, 3, 4, 5);
+ Class.EmptyStaticFunction5Arg(1, 2, 3, 4, 5);
+ }
}
}
}
- }
-
- [Benchmark(InnerIterationCount=100000)]
- public static void EmptyInstanceFunction()
- {
- Class aClass = new Class();
- foreach (var iteration in Benchmark.Iterations)
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void EmptyInstanceFunction()
{
- using (iteration.StartMeasurement())
+ Class aClass = new Class();
+
+ foreach (var iteration in Benchmark.Iterations)
{
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ using (iteration.StartMeasurement())
{
- aClass.EmptyInstanceFunction();
- aClass.EmptyInstanceFunction();
- aClass.EmptyInstanceFunction();
- aClass.EmptyInstanceFunction();
- aClass.EmptyInstanceFunction();
- aClass.EmptyInstanceFunction();
- aClass.EmptyInstanceFunction();
- aClass.EmptyInstanceFunction();
- aClass.EmptyInstanceFunction();
- aClass.EmptyInstanceFunction();
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ {
+ aClass.EmptyInstanceFunction();
+ aClass.EmptyInstanceFunction();
+ aClass.EmptyInstanceFunction();
+ aClass.EmptyInstanceFunction();
+ aClass.EmptyInstanceFunction();
+ aClass.EmptyInstanceFunction();
+ aClass.EmptyInstanceFunction();
+ aClass.EmptyInstanceFunction();
+ aClass.EmptyInstanceFunction();
+ aClass.EmptyInstanceFunction();
+ }
}
}
}
- }
- [Benchmark(InnerIterationCount=100000)]
- public static void InterfaceInterfaceMethod()
- {
- AnInterface aInterface = new Class();
-
- foreach (var iteration in Benchmark.Iterations)
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void InterfaceInterfaceMethod()
{
- using (iteration.StartMeasurement())
+ AnInterface aInterface = new Class();
+
+ foreach (var iteration in Benchmark.Iterations)
{
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ using (iteration.StartMeasurement())
{
- CallInterfaceMethod(aInterface);
- CallInterfaceMethod(aInterface);
- CallInterfaceMethod(aInterface);
- CallInterfaceMethod(aInterface);
- CallInterfaceMethod(aInterface);
- CallInterfaceMethod(aInterface);
- CallInterfaceMethod(aInterface);
- CallInterfaceMethod(aInterface);
- CallInterfaceMethod(aInterface);
- CallInterfaceMethod(aInterface);
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ {
+ CallInterfaceMethod(aInterface);
+ CallInterfaceMethod(aInterface);
+ CallInterfaceMethod(aInterface);
+ CallInterfaceMethod(aInterface);
+ CallInterfaceMethod(aInterface);
+ CallInterfaceMethod(aInterface);
+ CallInterfaceMethod(aInterface);
+ CallInterfaceMethod(aInterface);
+ CallInterfaceMethod(aInterface);
+ CallInterfaceMethod(aInterface);
+ }
}
}
}
- }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static void CallInterfaceMethod(AnInterface aInterface)
- {
- aInterface.InterfaceMethod();
- }
-
- [Benchmark(InnerIterationCount=100000)]
- public static void InterfaceInterfaceMethodLongHierarchy()
- {
- AnInterface aInterface = new LongHierarchyChildClass();
-
- //generate all the not-used call site first
- CallInterfaceMethod(new LongHierarchyClass1());
- CallInterfaceMethod(new LongHierarchyClass2());
- CallInterfaceMethod(new LongHierarchyClass3());
- CallInterfaceMethod(new LongHierarchyClass4());
- CallInterfaceMethod(new LongHierarchyClass5());
- CallInterfaceMethod(new LongHierarchyClass6());
- CallInterfaceMethod(new LongHierarchyClass7());
- CallInterfaceMethod(new LongHierarchyClass8());
- CallInterfaceMethod(new LongHierarchyClass9());
- CallInterfaceMethod(new LongHierarchyClass11());
- CallInterfaceMethod(new LongHierarchyClass12());
-
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- CallInterfaceMethod(aInterface);
- }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static void CallInterfaceMethod(AnInterface aInterface)
+ {
+ aInterface.InterfaceMethod();
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static void InterfaceInterfaceMethodSwitchCallType()
- {
- AnInterface aInterface = new LongHierarchyChildClass();
- AnInterface aInterface1 = new LongHierarchyClass1();
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void InterfaceInterfaceMethodLongHierarchy()
+ {
+ AnInterface aInterface = new LongHierarchyChildClass();
+
+ //generate all the not-used call site first
+ CallInterfaceMethod(new LongHierarchyClass1());
+ CallInterfaceMethod(new LongHierarchyClass2());
+ CallInterfaceMethod(new LongHierarchyClass3());
+ CallInterfaceMethod(new LongHierarchyClass4());
+ CallInterfaceMethod(new LongHierarchyClass5());
+ CallInterfaceMethod(new LongHierarchyClass6());
+ CallInterfaceMethod(new LongHierarchyClass7());
+ CallInterfaceMethod(new LongHierarchyClass8());
+ CallInterfaceMethod(new LongHierarchyClass9());
+ CallInterfaceMethod(new LongHierarchyClass11());
+ CallInterfaceMethod(new LongHierarchyClass12());
+
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ CallInterfaceMethod(aInterface);
+ }
- foreach (var iteration in Benchmark.Iterations)
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void InterfaceInterfaceMethodSwitchCallType()
{
- using (iteration.StartMeasurement())
+ AnInterface aInterface = new LongHierarchyChildClass();
+ AnInterface aInterface1 = new LongHierarchyClass1();
+
+ foreach (var iteration in Benchmark.Iterations)
{
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ using (iteration.StartMeasurement())
{
- CallInterfaceMethod(aInterface);
- CallInterfaceMethod(aInterface1);
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ {
+ CallInterfaceMethod(aInterface);
+ CallInterfaceMethod(aInterface1);
+ }
}
}
}
- }
- [Benchmark(InnerIterationCount=100000)]
- public static int ClassVirtualMethod()
- {
- SuperClass aClass = new Class();
+ [Benchmark(InnerIterationCount = 100000)]
+ public static int ClassVirtualMethod()
+ {
+ SuperClass aClass = new Class();
- int x = 0;
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- x = aClass.VirtualMethod();
+ int x = 0;
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ x = aClass.VirtualMethod();
- return x;
- }
+ return x;
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static void SealedClassInterfaceMethod()
- {
- SealedClass aSealedClass = new SealedClass();
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void SealedClassInterfaceMethod()
+ {
+ SealedClass aSealedClass = new SealedClass();
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- aSealedClass.InterfaceMethod();
- }
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ aSealedClass.InterfaceMethod();
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static void StructWithInterfaceInterfaceMethod()
- {
- StructWithInterface aStructWithInterface = new StructWithInterface();
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void StructWithInterfaceInterfaceMethod()
+ {
+ StructWithInterface aStructWithInterface = new StructWithInterface();
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- aStructWithInterface.InterfaceMethod();
- }
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ aStructWithInterface.InterfaceMethod();
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static void StaticIntPlus()
- {
- Class aClass = new Class();
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void StaticIntPlus()
+ {
+ Class aClass = new Class();
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- Class.aStaticInt += 1;
- }
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ Class.aStaticInt += 1;
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static bool ObjectStringIsString()
- {
- object aObjectString = "aString1";
- bool b = false;
+ [Benchmark(InnerIterationCount = 100000)]
+ public static bool ObjectStringIsString()
+ {
+ object aObjectString = "aString1";
+ bool b = false;
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- b = aObjectString is String;
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ b = aObjectString is String;
- return b;
- }
+ return b;
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static void NewDelegateClassEmptyInstanceFn()
- {
- Class aClass = new Class();
- MyDelegate aMyDelegate;
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void NewDelegateClassEmptyInstanceFn()
+ {
+ Class aClass = new Class();
+ MyDelegate aMyDelegate;
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- aMyDelegate = new MyDelegate(aClass.EmptyInstanceFunction);
- }
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ aMyDelegate = new MyDelegate(aClass.EmptyInstanceFunction);
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static void NewDelegateClassEmptyStaticFn()
- {
- Class aClass = new Class();
- MyDelegate aMyDelegate;
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void NewDelegateClassEmptyStaticFn()
+ {
+ Class aClass = new Class();
+ MyDelegate aMyDelegate;
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- aMyDelegate = new MyDelegate(Class.EmptyStaticFunction);
- }
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ aMyDelegate = new MyDelegate(Class.EmptyStaticFunction);
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static void InstanceDelegate()
- {
- Class aClass = new Class();
- MyDelegate aInstanceDelegate = new MyDelegate(aClass.EmptyInstanceFunction);
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void InstanceDelegate()
+ {
+ Class aClass = new Class();
+ MyDelegate aInstanceDelegate = new MyDelegate(aClass.EmptyInstanceFunction);
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- aInstanceDelegate();
- }
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ aInstanceDelegate();
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static void StaticDelegate()
- {
- Class aClass = new Class();
- MyDelegate aStaticDelegate = new MyDelegate(Class.EmptyStaticFunction);
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void StaticDelegate()
+ {
+ Class aClass = new Class();
+ MyDelegate aStaticDelegate = new MyDelegate(Class.EmptyStaticFunction);
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- aStaticDelegate();
- }
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ aStaticDelegate();
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static void MeasureEvents()
- {
- Class aClass = new Class();
- aClass.AnEvent += new MyDelegate(aClass.EmptyInstanceFunction);
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void MeasureEvents()
+ {
+ Class aClass = new Class();
+ aClass.AnEvent += new MyDelegate(aClass.EmptyInstanceFunction);
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- aClass.MeasureFire100();
- }
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ aClass.MeasureFire100();
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static void GenericClassWithIntGenericInstanceField()
- {
- GenericClass<int> aGenericClassWithInt = new GenericClass<int>();
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void GenericClassWithIntGenericInstanceField()
+ {
+ GenericClass<int> aGenericClassWithInt = new GenericClass<int>();
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- aGenericClassWithInt.aGenericInstanceFieldT = 1;
- }
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ aGenericClassWithInt.aGenericInstanceFieldT = 1;
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static void GenericClassGenericStaticField()
- {
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- GenericClass<int>.aGenericStaticFieldT = 1;
- }
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void GenericClassGenericStaticField()
+ {
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ GenericClass<int>.aGenericStaticFieldT = 1;
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static int GenericClassGenericInstanceMethod()
- {
- GenericClass<int> aGenericClassWithInt = new GenericClass<int>();
+ [Benchmark(InnerIterationCount = 100000)]
+ public static int GenericClassGenericInstanceMethod()
+ {
+ GenericClass<int> aGenericClassWithInt = new GenericClass<int>();
- int x = 0;
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- x = aGenericClassWithInt.ClassGenericInstanceMethod();
+ int x = 0;
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ x = aGenericClassWithInt.ClassGenericInstanceMethod();
- return x;
- }
+ return x;
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static int GenericClassGenericStaticMethod()
- {
- int x = 0;
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- x = GenericClass<int>.ClassGenericStaticMethod();
+ [Benchmark(InnerIterationCount = 100000)]
+ public static int GenericClassGenericStaticMethod()
+ {
+ int x = 0;
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ x = GenericClass<int>.ClassGenericStaticMethod();
- return x;
- }
+ return x;
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static int GenericGenericMethod()
- {
- // Warmup
- int x = 0;
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- x = Class.GenericMethod<int>();
-
- return x;
- }
+ [Benchmark(InnerIterationCount = 100000)]
+ public static int GenericGenericMethod()
+ {
+ // Warmup
+ int x = 0;
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ x = Class.GenericMethod<int>();
+
+ return x;
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static void GenericClassWithSTringGenericInstanceMethod()
- {
- GenericClass<string> aGenericClassWithString = new GenericClass<string>();
- string aString = "foo";
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void GenericClassWithSTringGenericInstanceMethod()
+ {
+ GenericClass<string> aGenericClassWithString = new GenericClass<string>();
+ string aString = "foo";
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- aGenericClassWithString.aGenericInstanceFieldT = aString;
- }
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ aGenericClassWithString.aGenericInstanceFieldT = aString;
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static int ForeachOverList100Elements()
- {
- List<int> iList = new List<int>();
- for (int i = 0; i < 100; i++)
- iList.Add(i);
-
- int iResult = 0;
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- foreach (int j in iList)
- iResult = j;
-
- return iResult;
- }
+ [Benchmark(InnerIterationCount = 100000)]
+ public static int ForeachOverList100Elements()
+ {
+ List<int> iList = new List<int>();
+ for (int i = 0; i < 100; i++)
+ iList.Add(i);
+
+ int iResult = 0;
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ foreach (int j in iList)
+ iResult = j;
+
+ return iResult;
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static Type TypeReflectionObjectGetType()
- {
- Type type = null;
- object anObject = "aString";
+ [Benchmark(InnerIterationCount = 100000)]
+ public static Type TypeReflectionObjectGetType()
+ {
+ Type type = null;
+ object anObject = "aString";
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- type = anObject.GetType();
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ type = anObject.GetType();
- return type;
- }
+ return type;
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static Type TypeReflectionArrayGetType()
- {
- Type type = null;
- object anArray = new string[0];
+ [Benchmark(InnerIterationCount = 100000)]
+ public static Type TypeReflectionArrayGetType()
+ {
+ Type type = null;
+ object anArray = new string[0];
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- type = anArray.GetType();
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ type = anArray.GetType();
- return type;
- }
+ return type;
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static string IntegerFormatting()
- {
- int number = Int32.MaxValue;
+ [Benchmark(InnerIterationCount = 100000)]
+ public static string IntegerFormatting()
+ {
+ int number = Int32.MaxValue;
- string result = null;
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- result = number.ToString();
+ string result = null;
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ result = number.ToString();
- return result;
+ return result;
+ }
}
-}
-#region Support Classes
-// classes and method needed to perform the experiments.
+ #region Support Classes
+ // classes and method needed to perform the experiments.
-public interface AnInterface
-{
- int InterfaceMethod();
-}
-
-public class SuperClass : AnInterface
-{
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- public virtual int InterfaceMethod() { return 2; }
-
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- public virtual int VirtualMethod()
+ public interface AnInterface
{
- return 1;
+ int InterfaceMethod();
}
-}
-public struct ValueType
-{
- public int x;
- public int y;
- public int z;
-}
+ public class SuperClass : AnInterface
+ {
+ [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
+ public virtual int InterfaceMethod() { return 2; }
-public delegate int MyDelegate();
+ [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
+ public virtual int VirtualMethod()
+ {
+ return 1;
+ }
+ }
-public struct StructWithInterface : AnInterface
-{
- public int x;
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- public int InterfaceMethod()
+ public struct ValueType
{
- return x++;
+ public int x;
+ public int y;
+ public int z;
}
-}
-public sealed class SealedClass : SuperClass
-{
- public int aInstanceInt;
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- public override int VirtualMethod()
+ public delegate int MyDelegate();
+
+ public struct StructWithInterface : AnInterface
{
- return aInstanceInt++;
+ public int x;
+ [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
+ public int InterfaceMethod()
+ {
+ return x++;
+ }
}
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- public override int InterfaceMethod()
+
+ public sealed class SealedClass : SuperClass
{
- return aInstanceInt++;
+ public int aInstanceInt;
+ [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
+ public override int VirtualMethod()
+ {
+ return aInstanceInt++;
+ }
+ [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
+ public override int InterfaceMethod()
+ {
+ return aInstanceInt++;
+ }
}
-}
-/// <summary>
-/// A example class. It inherits, overrides, has intefaces etc.
-/// It excercises most of the common runtime features
-/// </summary>
-public class Class : SuperClass
-{
- public event MyDelegate AnEvent;
+ /// <summary>
+ /// A example class. It inherits, overrides, has intefaces etc.
+ /// It excercises most of the common runtime features
+ /// </summary>
+ public class Class : SuperClass
+ {
+ public event MyDelegate AnEvent;
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- public override int VirtualMethod() { return aInstanceInt++; }
+ [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
+ public override int VirtualMethod() { return aInstanceInt++; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- public override int InterfaceMethod() { return aInstanceInt++; }
+ [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
+ public override int InterfaceMethod() { return aInstanceInt++; }
- public int aInstanceInt;
- public string aInstanceString;
+ public int aInstanceInt;
+ public string aInstanceString;
- public static int aStaticInt;
- public static string aStaticString = "Hello";
- public static ValueType aStaticValueType;
+ public static int aStaticInt;
+ public static string aStaticString = "Hello";
+ public static ValueType aStaticValueType;
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int EmptyStaticFunction()
- {
- return aStaticInt++;
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int EmptyStaticFunction5Arg(int arg1, int arg2, int arg3, int arg4, int arg5)
- {
- return aStaticInt++;
- }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static int EmptyStaticFunction()
+ {
+ return aStaticInt++;
+ }
- [MethodImpl(MethodImplOptions.NoInlining)]
- public int EmptyInstanceFunction()
- {
- return aInstanceInt++;
- }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static int EmptyStaticFunction5Arg(int arg1, int arg2, int arg3, int arg4, int arg5)
+ {
+ return aStaticInt++;
+ }
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static int GenericMethod<T>()
- {
- return aStaticInt++;
- }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public int EmptyInstanceFunction()
+ {
+ return aInstanceInt++;
+ }
- public void MeasureFire100()
- {
- #region callAnEvent
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- AnEvent();
- //});
- #endregion
- }
-}
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static int GenericMethod<T>()
+ {
+ return aStaticInt++;
+ }
-public class GenericClass<T>
-{
- [MethodImpl(MethodImplOptions.NoInlining)]
- public T ClassGenericInstanceMethod()
- {
- tmp++; // need this to not be optimized away
- return aGenericInstanceFieldT;
+ public void MeasureFire100()
+ {
+ #region callAnEvent
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ AnEvent();
+ //});
+ #endregion
+ }
}
- [MethodImpl(MethodImplOptions.NoInlining)]
- public static T ClassGenericStaticMethod()
+ public class GenericClass<T>
{
- sTmp++; // need this to not be optimized away
- return aGenericStaticFieldT;
- }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public T ClassGenericInstanceMethod()
+ {
+ tmp++; // need this to not be optimized away
+ return aGenericInstanceFieldT;
+ }
- public static int sTmp;
- public int tmp;
- public T aGenericInstanceFieldT;
- public static T aGenericStaticFieldT;
-}
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public static T ClassGenericStaticMethod()
+ {
+ sTmp++; // need this to not be optimized away
+ return aGenericStaticFieldT;
+ }
-#region LongHierarchyClass
-public class LongHierarchyClass1 : AnInterface
-{
- [MethodImpl(MethodImplOptions.NoInlining)]
- public virtual int InterfaceMethod() { return 2; }
+ public static int sTmp;
+ public int tmp;
+ public T aGenericInstanceFieldT;
+ public static T aGenericStaticFieldT;
+ }
- [MethodImpl(MethodImplOptions.NoInlining)]
- public virtual int VirtualMethod()
+ #region LongHierarchyClass
+ public class LongHierarchyClass1 : AnInterface
{
- return 1;
- }
-}
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public virtual int InterfaceMethod() { return 2; }
-public class LongHierarchyClass2 : LongHierarchyClass1
-{
- [MethodImpl(MethodImplOptions.NoInlining)]
- public override int InterfaceMethod() { return 2; }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public virtual int VirtualMethod()
+ {
+ return 1;
+ }
+ }
- [MethodImpl(MethodImplOptions.NoInlining)]
- public override int VirtualMethod()
+ public class LongHierarchyClass2 : LongHierarchyClass1
{
- return 1;
- }
-}
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public override int InterfaceMethod() { return 2; }
-public class LongHierarchyClass3 : LongHierarchyClass2
-{
- [MethodImpl(MethodImplOptions.NoInlining)]
- public override int InterfaceMethod() { return 2; }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public override int VirtualMethod()
+ {
+ return 1;
+ }
+ }
- [MethodImpl(MethodImplOptions.NoInlining)]
- public override int VirtualMethod()
+ public class LongHierarchyClass3 : LongHierarchyClass2
{
- return 1;
- }
-}
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public override int InterfaceMethod() { return 2; }
-public class LongHierarchyClass4 : LongHierarchyClass3
-{
- [MethodImpl(MethodImplOptions.NoInlining)]
- public override int InterfaceMethod() { return 2; }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public override int VirtualMethod()
+ {
+ return 1;
+ }
+ }
- [MethodImpl(MethodImplOptions.NoInlining)]
- public override int VirtualMethod()
+ public class LongHierarchyClass4 : LongHierarchyClass3
{
- return 1;
- }
-}
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public override int InterfaceMethod() { return 2; }
-public class LongHierarchyClass5 : LongHierarchyClass4
-{
- [MethodImpl(MethodImplOptions.NoInlining)]
- public override int InterfaceMethod() { return 2; }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public override int VirtualMethod()
+ {
+ return 1;
+ }
+ }
- [MethodImpl(MethodImplOptions.NoInlining)]
- public override int VirtualMethod()
+ public class LongHierarchyClass5 : LongHierarchyClass4
{
- return 1;
- }
-}
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public override int InterfaceMethod() { return 2; }
-public class LongHierarchyClass6 : LongHierarchyClass5
-{
- [MethodImpl(MethodImplOptions.NoInlining)]
- public override int InterfaceMethod() { return 2; }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public override int VirtualMethod()
+ {
+ return 1;
+ }
+ }
- [MethodImpl(MethodImplOptions.NoInlining)]
- public override int VirtualMethod()
+ public class LongHierarchyClass6 : LongHierarchyClass5
{
- return 1;
- }
-}
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public override int InterfaceMethod() { return 2; }
-public class LongHierarchyClass7 : LongHierarchyClass6
-{
- [MethodImpl(MethodImplOptions.NoInlining)]
- public override int InterfaceMethod() { return 2; }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public override int VirtualMethod()
+ {
+ return 1;
+ }
+ }
- [MethodImpl(MethodImplOptions.NoInlining)]
- public override int VirtualMethod()
+ public class LongHierarchyClass7 : LongHierarchyClass6
{
- return 1;
- }
-}
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public override int InterfaceMethod() { return 2; }
-public class LongHierarchyClass8 : LongHierarchyClass7
-{
- [MethodImpl(MethodImplOptions.NoInlining)]
- public override int InterfaceMethod() { return 2; }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public override int VirtualMethod()
+ {
+ return 1;
+ }
+ }
- [MethodImpl(MethodImplOptions.NoInlining)]
- public override int VirtualMethod()
+ public class LongHierarchyClass8 : LongHierarchyClass7
{
- return 1;
- }
-}
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public override int InterfaceMethod() { return 2; }
-public class LongHierarchyClass9 : LongHierarchyClass8
-{
- [MethodImpl(MethodImplOptions.NoInlining)]
- public override int InterfaceMethod() { return 2; }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public override int VirtualMethod()
+ {
+ return 1;
+ }
+ }
- [MethodImpl(MethodImplOptions.NoInlining)]
- public override int VirtualMethod()
+ public class LongHierarchyClass9 : LongHierarchyClass8
{
- return 1;
- }
-}
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public override int InterfaceMethod() { return 2; }
-public class LongHierarchyClass10 : LongHierarchyClass9
-{
- [MethodImpl(MethodImplOptions.NoInlining)]
- public override int InterfaceMethod() { return 2; }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public override int VirtualMethod()
+ {
+ return 1;
+ }
+ }
- [MethodImpl(MethodImplOptions.NoInlining)]
- public override int VirtualMethod()
+ public class LongHierarchyClass10 : LongHierarchyClass9
{
- return 1;
- }
-}
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public override int InterfaceMethod() { return 2; }
-public class LongHierarchyClass11 : LongHierarchyClass10
-{
- [MethodImpl(MethodImplOptions.NoInlining)]
- public override int InterfaceMethod() { return 2; }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public override int VirtualMethod()
+ {
+ return 1;
+ }
+ }
- [MethodImpl(MethodImplOptions.NoInlining)]
- public override int VirtualMethod()
+ public class LongHierarchyClass11 : LongHierarchyClass10
{
- return 1;
- }
-}
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public override int InterfaceMethod() { return 2; }
-public class LongHierarchyClass12 : LongHierarchyClass11
-{
- [MethodImpl(MethodImplOptions.NoInlining)]
- public override int InterfaceMethod() { return 2; }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public override int VirtualMethod()
+ {
+ return 1;
+ }
+ }
- [MethodImpl(MethodImplOptions.NoInlining)]
- public override int VirtualMethod()
+ public class LongHierarchyClass12 : LongHierarchyClass11
{
- return 1;
- }
-}
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public override int InterfaceMethod() { return 2; }
-public class LongHierarchyChildClass : LongHierarchyClass12
-{
- [MethodImpl(MethodImplOptions.NoInlining)]
- public override int InterfaceMethod() { return 2; }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public override int VirtualMethod()
+ {
+ return 1;
+ }
+ }
- [MethodImpl(MethodImplOptions.NoInlining)]
- public override int VirtualMethod()
+ public class LongHierarchyChildClass : LongHierarchyClass12
{
- return 1;
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public override int InterfaceMethod() { return 2; }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ public override int VirtualMethod()
+ {
+ return 1;
+ }
}
-}
-#endregion
+ #endregion
-#endregion
+ #endregion
+}
diff --git a/tests/src/performance/perflab/ReflectionPerf.cs b/tests/src/performance/perflab/ReflectionPerf.cs
index 954bbe7e92..03556c9f7b 100644
--- a/tests/src/performance/perflab/ReflectionPerf.cs
+++ b/tests/src/performance/perflab/ReflectionPerf.cs
@@ -8,3309 +8,3312 @@ using System.Threading;
using Microsoft.Xunit.Performance;
#pragma warning disable 67
-public class GetMember
+namespace PerfLabTests
{
- // all these fields will be initialized in init, so that they can be used directly in invocation
- private static readonly TypeInfo s_t1;
- private static readonly TypeInfo s_t2;
- private static readonly TypeInfo s_t3;
- private static readonly TypeInfo s_t4;
- private static readonly TypeInfo s_t5;
- private static readonly TypeInfo s_t6;
- private static readonly TypeInfo s_t7;
- private static readonly TypeInfo s_t8;
- private static readonly TypeInfo s_t9;
- private static readonly TypeInfo s_t10;
- private static readonly TypeInfo s_t11;
- private static readonly TypeInfo s_t12;
- private static readonly TypeInfo s_t13;
- private static readonly TypeInfo s_t14;
- private static readonly TypeInfo s_t15;
- private static readonly TypeInfo s_t16;
- private static readonly TypeInfo s_t17;
- private static readonly TypeInfo s_t18;
- private static readonly TypeInfo s_t19;
- private static readonly TypeInfo s_t20;
-
- static GetMember()
+ public class GetMember
{
- s_t1 = typeof(Class1).GetTypeInfo();
- s_t2 = typeof(Class2).GetTypeInfo();
- s_t3 = typeof(Class3).GetTypeInfo();
- s_t4 = typeof(Class4).GetTypeInfo();
- s_t5 = typeof(Class5).GetTypeInfo();
- s_t6 = typeof(Class6).GetTypeInfo();
- s_t7 = typeof(Class7).GetTypeInfo();
- s_t8 = typeof(Class8).GetTypeInfo();
- s_t9 = typeof(Class9).GetTypeInfo();
- s_t10 = typeof(Class10).GetTypeInfo();
- s_t11 = typeof(Class11).GetTypeInfo();
- s_t12 = typeof(Class12).GetTypeInfo();
- s_t13 = typeof(Class13).GetTypeInfo();
- s_t14 = typeof(Class14).GetTypeInfo();
- s_t15 = typeof(Class15).GetTypeInfo();
- s_t16 = typeof(Class16).GetTypeInfo();
- s_t17 = typeof(Class17).GetTypeInfo();
- s_t18 = typeof(Class18).GetTypeInfo();
- s_t19 = typeof(Class19).GetTypeInfo();
- s_t20 = typeof(Class20).GetTypeInfo();
- }
+ // all these fields will be initialized in init, so that they can be used directly in invocation
+ private static readonly TypeInfo s_t1;
+ private static readonly TypeInfo s_t2;
+ private static readonly TypeInfo s_t3;
+ private static readonly TypeInfo s_t4;
+ private static readonly TypeInfo s_t5;
+ private static readonly TypeInfo s_t6;
+ private static readonly TypeInfo s_t7;
+ private static readonly TypeInfo s_t8;
+ private static readonly TypeInfo s_t9;
+ private static readonly TypeInfo s_t10;
+ private static readonly TypeInfo s_t11;
+ private static readonly TypeInfo s_t12;
+ private static readonly TypeInfo s_t13;
+ private static readonly TypeInfo s_t14;
+ private static readonly TypeInfo s_t15;
+ private static readonly TypeInfo s_t16;
+ private static readonly TypeInfo s_t17;
+ private static readonly TypeInfo s_t18;
+ private static readonly TypeInfo s_t19;
+ private static readonly TypeInfo s_t20;
+
+ static GetMember()
+ {
+ s_t1 = typeof(Class1).GetTypeInfo();
+ s_t2 = typeof(Class2).GetTypeInfo();
+ s_t3 = typeof(Class3).GetTypeInfo();
+ s_t4 = typeof(Class4).GetTypeInfo();
+ s_t5 = typeof(Class5).GetTypeInfo();
+ s_t6 = typeof(Class6).GetTypeInfo();
+ s_t7 = typeof(Class7).GetTypeInfo();
+ s_t8 = typeof(Class8).GetTypeInfo();
+ s_t9 = typeof(Class9).GetTypeInfo();
+ s_t10 = typeof(Class10).GetTypeInfo();
+ s_t11 = typeof(Class11).GetTypeInfo();
+ s_t12 = typeof(Class12).GetTypeInfo();
+ s_t13 = typeof(Class13).GetTypeInfo();
+ s_t14 = typeof(Class14).GetTypeInfo();
+ s_t15 = typeof(Class15).GetTypeInfo();
+ s_t16 = typeof(Class16).GetTypeInfo();
+ s_t17 = typeof(Class17).GetTypeInfo();
+ s_t18 = typeof(Class18).GetTypeInfo();
+ s_t19 = typeof(Class19).GetTypeInfo();
+ s_t20 = typeof(Class20).GetTypeInfo();
+ }
- [Benchmark(InnerIterationCount=1000)]
- public static void GetField()
- {
- foreach (var iteration in Benchmark.Iterations)
+ [Benchmark(InnerIterationCount = 1000)]
+ public static void GetField()
{
- using (iteration.StartMeasurement())
+ foreach (var iteration in Benchmark.Iterations)
{
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ using (iteration.StartMeasurement())
{
- s_t1.GetDeclaredField("f1");
- s_t1.GetDeclaredField("f2");
- s_t1.GetDeclaredField("f3");
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ {
+ s_t1.GetDeclaredField("f1");
+ s_t1.GetDeclaredField("f2");
+ s_t1.GetDeclaredField("f3");
+ }
}
}
}
- }
- [Benchmark(InnerIterationCount=1000)]
- public static void GetMethod1()
- {
- foreach (var iteration in Benchmark.Iterations)
+ [Benchmark(InnerIterationCount = 1000)]
+ public static void GetMethod1()
{
- using (iteration.StartMeasurement())
+ foreach (var iteration in Benchmark.Iterations)
{
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ using (iteration.StartMeasurement())
{
- s_t1.GetDeclaredMethod("m1");
- s_t1.GetDeclaredMethod("m2");
- s_t1.GetDeclaredMethod("m3");
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ {
+ s_t1.GetDeclaredMethod("m1");
+ s_t1.GetDeclaredMethod("m2");
+ s_t1.GetDeclaredMethod("m3");
+ }
}
}
}
- }
- [Benchmark(InnerIterationCount=1000)]
- public static void GetMethod2()
- {
- foreach (var iteration in Benchmark.Iterations)
+ [Benchmark(InnerIterationCount = 1000)]
+ public static void GetMethod2()
{
- using (iteration.StartMeasurement())
+ foreach (var iteration in Benchmark.Iterations)
{
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ using (iteration.StartMeasurement())
{
- s_t1.GetDeclaredMethod("m1");
- s_t1.GetDeclaredMethod("m2");
- s_t1.GetDeclaredMethod("m3");
- s_t2.GetDeclaredMethod("m1");
- s_t2.GetDeclaredMethod("m2");
- s_t2.GetDeclaredMethod("m3");
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ {
+ s_t1.GetDeclaredMethod("m1");
+ s_t1.GetDeclaredMethod("m2");
+ s_t1.GetDeclaredMethod("m3");
+ s_t2.GetDeclaredMethod("m1");
+ s_t2.GetDeclaredMethod("m2");
+ s_t2.GetDeclaredMethod("m3");
+ }
}
}
}
- }
- [Benchmark(InnerIterationCount=1000)]
- public static void GetMethod3()
- {
- foreach (var iteration in Benchmark.Iterations)
+ [Benchmark(InnerIterationCount = 1000)]
+ public static void GetMethod3()
{
- using (iteration.StartMeasurement())
+ foreach (var iteration in Benchmark.Iterations)
{
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ using (iteration.StartMeasurement())
{
- s_t1.GetDeclaredMethod("m1");
- s_t1.GetDeclaredMethod("m2"); //TODO: check if we can really get the method
- s_t1.GetDeclaredMethod("m3");
- s_t2.GetDeclaredMethod("m1");
- s_t2.GetDeclaredMethod("m2");
- s_t2.GetDeclaredMethod("m3");
- s_t3.GetDeclaredMethod("m1");
- s_t3.GetDeclaredMethod("m2");
- s_t3.GetDeclaredMethod("m3");
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ {
+ s_t1.GetDeclaredMethod("m1");
+ s_t1.GetDeclaredMethod("m2"); //TODO: check if we can really get the method
+ s_t1.GetDeclaredMethod("m3");
+ s_t2.GetDeclaredMethod("m1");
+ s_t2.GetDeclaredMethod("m2");
+ s_t2.GetDeclaredMethod("m3");
+ s_t3.GetDeclaredMethod("m1");
+ s_t3.GetDeclaredMethod("m2");
+ s_t3.GetDeclaredMethod("m3");
+ }
}
}
}
- }
- [Benchmark(InnerIterationCount=1000)]
- public static void GetMethod4()
- {
- foreach (var iteration in Benchmark.Iterations)
+ [Benchmark(InnerIterationCount = 1000)]
+ public static void GetMethod4()
{
- using (iteration.StartMeasurement())
+ foreach (var iteration in Benchmark.Iterations)
{
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ using (iteration.StartMeasurement())
{
- s_t1.GetDeclaredMethod("m1");
- s_t1.GetDeclaredMethod("m2"); //TODO: check if we can really get the method
- s_t1.GetDeclaredMethod("m3");
- s_t2.GetDeclaredMethod("m1");
- s_t2.GetDeclaredMethod("m2");
- s_t2.GetDeclaredMethod("m3");
- s_t3.GetDeclaredMethod("m1");
- s_t3.GetDeclaredMethod("m2");
- s_t3.GetDeclaredMethod("m3");
- s_t4.GetDeclaredMethod("m1");
- s_t4.GetDeclaredMethod("m2");
- s_t4.GetDeclaredMethod("m3");
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ {
+ s_t1.GetDeclaredMethod("m1");
+ s_t1.GetDeclaredMethod("m2"); //TODO: check if we can really get the method
+ s_t1.GetDeclaredMethod("m3");
+ s_t2.GetDeclaredMethod("m1");
+ s_t2.GetDeclaredMethod("m2");
+ s_t2.GetDeclaredMethod("m3");
+ s_t3.GetDeclaredMethod("m1");
+ s_t3.GetDeclaredMethod("m2");
+ s_t3.GetDeclaredMethod("m3");
+ s_t4.GetDeclaredMethod("m1");
+ s_t4.GetDeclaredMethod("m2");
+ s_t4.GetDeclaredMethod("m3");
+ }
}
}
}
- }
- [Benchmark(InnerIterationCount=1000)]
- public static void GetMethod5()
- {
- foreach (var iteration in Benchmark.Iterations)
+ [Benchmark(InnerIterationCount = 1000)]
+ public static void GetMethod5()
{
- using (iteration.StartMeasurement())
+ foreach (var iteration in Benchmark.Iterations)
{
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ using (iteration.StartMeasurement())
{
- s_t1.GetDeclaredMethod("m1");
- s_t1.GetDeclaredMethod("m2");
- s_t1.GetDeclaredMethod("m3");
- s_t2.GetDeclaredMethod("m1");
- s_t2.GetDeclaredMethod("m2");
- s_t2.GetDeclaredMethod("m3");
- s_t3.GetDeclaredMethod("m1");
- s_t3.GetDeclaredMethod("m2");
- s_t3.GetDeclaredMethod("m3");
- s_t4.GetDeclaredMethod("m1");
- s_t4.GetDeclaredMethod("m2");
- s_t4.GetDeclaredMethod("m3");
- s_t5.GetDeclaredMethod("m1");
- s_t5.GetDeclaredMethod("m2");
- s_t5.GetDeclaredMethod("m3");
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ {
+ s_t1.GetDeclaredMethod("m1");
+ s_t1.GetDeclaredMethod("m2");
+ s_t1.GetDeclaredMethod("m3");
+ s_t2.GetDeclaredMethod("m1");
+ s_t2.GetDeclaredMethod("m2");
+ s_t2.GetDeclaredMethod("m3");
+ s_t3.GetDeclaredMethod("m1");
+ s_t3.GetDeclaredMethod("m2");
+ s_t3.GetDeclaredMethod("m3");
+ s_t4.GetDeclaredMethod("m1");
+ s_t4.GetDeclaredMethod("m2");
+ s_t4.GetDeclaredMethod("m3");
+ s_t5.GetDeclaredMethod("m1");
+ s_t5.GetDeclaredMethod("m2");
+ s_t5.GetDeclaredMethod("m3");
+ }
}
}
}
- }
- [Benchmark(InnerIterationCount=1000)]
- public static void GetMethod10()
- {
- foreach (var iteration in Benchmark.Iterations)
+ [Benchmark(InnerIterationCount = 1000)]
+ public static void GetMethod10()
{
- using (iteration.StartMeasurement())
+ foreach (var iteration in Benchmark.Iterations)
{
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ using (iteration.StartMeasurement())
{
- s_t1.GetDeclaredMethod("m1");
- s_t1.GetDeclaredMethod("m2");
- s_t1.GetDeclaredMethod("m3");
- s_t2.GetDeclaredMethod("m1");
- s_t2.GetDeclaredMethod("m2");
- s_t2.GetDeclaredMethod("m3");
- s_t3.GetDeclaredMethod("m1");
- s_t3.GetDeclaredMethod("m2");
- s_t3.GetDeclaredMethod("m3");
- s_t4.GetDeclaredMethod("m1");
- s_t4.GetDeclaredMethod("m2");
- s_t4.GetDeclaredMethod("m3");
- s_t5.GetDeclaredMethod("m1");
- s_t5.GetDeclaredMethod("m2");
- s_t5.GetDeclaredMethod("m3");
-
- s_t6.GetDeclaredMethod("m1");
- s_t6.GetDeclaredMethod("m2");
- s_t6.GetDeclaredMethod("m3");
- s_t7.GetDeclaredMethod("m1");
- s_t7.GetDeclaredMethod("m2");
- s_t7.GetDeclaredMethod("m3");
- s_t8.GetDeclaredMethod("m1");
- s_t8.GetDeclaredMethod("m2");
- s_t8.GetDeclaredMethod("m3");
- s_t9.GetDeclaredMethod("m1");
- s_t9.GetDeclaredMethod("m2");
- s_t9.GetDeclaredMethod("m3");
- s_t10.GetDeclaredMethod("m1");
- s_t10.GetDeclaredMethod("m2");
- s_t10.GetDeclaredMethod("m3");
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ {
+ s_t1.GetDeclaredMethod("m1");
+ s_t1.GetDeclaredMethod("m2");
+ s_t1.GetDeclaredMethod("m3");
+ s_t2.GetDeclaredMethod("m1");
+ s_t2.GetDeclaredMethod("m2");
+ s_t2.GetDeclaredMethod("m3");
+ s_t3.GetDeclaredMethod("m1");
+ s_t3.GetDeclaredMethod("m2");
+ s_t3.GetDeclaredMethod("m3");
+ s_t4.GetDeclaredMethod("m1");
+ s_t4.GetDeclaredMethod("m2");
+ s_t4.GetDeclaredMethod("m3");
+ s_t5.GetDeclaredMethod("m1");
+ s_t5.GetDeclaredMethod("m2");
+ s_t5.GetDeclaredMethod("m3");
+
+ s_t6.GetDeclaredMethod("m1");
+ s_t6.GetDeclaredMethod("m2");
+ s_t6.GetDeclaredMethod("m3");
+ s_t7.GetDeclaredMethod("m1");
+ s_t7.GetDeclaredMethod("m2");
+ s_t7.GetDeclaredMethod("m3");
+ s_t8.GetDeclaredMethod("m1");
+ s_t8.GetDeclaredMethod("m2");
+ s_t8.GetDeclaredMethod("m3");
+ s_t9.GetDeclaredMethod("m1");
+ s_t9.GetDeclaredMethod("m2");
+ s_t9.GetDeclaredMethod("m3");
+ s_t10.GetDeclaredMethod("m1");
+ s_t10.GetDeclaredMethod("m2");
+ s_t10.GetDeclaredMethod("m3");
+ }
}
}
}
- }
- [Benchmark(InnerIterationCount=1000)]
- public static void GetMethod12()
- {
- foreach (var iteration in Benchmark.Iterations)
+ [Benchmark(InnerIterationCount = 1000)]
+ public static void GetMethod12()
{
- using (iteration.StartMeasurement())
+ foreach (var iteration in Benchmark.Iterations)
{
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ using (iteration.StartMeasurement())
{
- s_t1.GetDeclaredMethod("m1");
- s_t1.GetDeclaredMethod("m2");
- s_t1.GetDeclaredMethod("m3");
- s_t2.GetDeclaredMethod("m1");
- s_t2.GetDeclaredMethod("m2");
- s_t2.GetDeclaredMethod("m3");
- s_t3.GetDeclaredMethod("m1");
- s_t3.GetDeclaredMethod("m2");
- s_t3.GetDeclaredMethod("m3");
- s_t4.GetDeclaredMethod("m1");
- s_t4.GetDeclaredMethod("m2");
- s_t4.GetDeclaredMethod("m3");
- s_t5.GetDeclaredMethod("m1");
- s_t5.GetDeclaredMethod("m2");
- s_t5.GetDeclaredMethod("m3");
-
- s_t6.GetDeclaredMethod("m1");
- s_t6.GetDeclaredMethod("m2");
- s_t6.GetDeclaredMethod("m3");
- s_t7.GetDeclaredMethod("m1");
- s_t7.GetDeclaredMethod("m2");
- s_t7.GetDeclaredMethod("m3");
- s_t8.GetDeclaredMethod("m1");
- s_t8.GetDeclaredMethod("m2");
- s_t8.GetDeclaredMethod("m3");
- s_t9.GetDeclaredMethod("m1");
- s_t9.GetDeclaredMethod("m2");
- s_t9.GetDeclaredMethod("m3");
- s_t10.GetDeclaredMethod("m1");
- s_t10.GetDeclaredMethod("m2");
- s_t10.GetDeclaredMethod("m3");
-
- s_t11.GetDeclaredMethod("m1");
- s_t11.GetDeclaredMethod("m2");
- s_t11.GetDeclaredMethod("m3");
- s_t12.GetDeclaredMethod("m1");
- s_t12.GetDeclaredMethod("m2");
- s_t12.GetDeclaredMethod("m3");
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ {
+ s_t1.GetDeclaredMethod("m1");
+ s_t1.GetDeclaredMethod("m2");
+ s_t1.GetDeclaredMethod("m3");
+ s_t2.GetDeclaredMethod("m1");
+ s_t2.GetDeclaredMethod("m2");
+ s_t2.GetDeclaredMethod("m3");
+ s_t3.GetDeclaredMethod("m1");
+ s_t3.GetDeclaredMethod("m2");
+ s_t3.GetDeclaredMethod("m3");
+ s_t4.GetDeclaredMethod("m1");
+ s_t4.GetDeclaredMethod("m2");
+ s_t4.GetDeclaredMethod("m3");
+ s_t5.GetDeclaredMethod("m1");
+ s_t5.GetDeclaredMethod("m2");
+ s_t5.GetDeclaredMethod("m3");
+
+ s_t6.GetDeclaredMethod("m1");
+ s_t6.GetDeclaredMethod("m2");
+ s_t6.GetDeclaredMethod("m3");
+ s_t7.GetDeclaredMethod("m1");
+ s_t7.GetDeclaredMethod("m2");
+ s_t7.GetDeclaredMethod("m3");
+ s_t8.GetDeclaredMethod("m1");
+ s_t8.GetDeclaredMethod("m2");
+ s_t8.GetDeclaredMethod("m3");
+ s_t9.GetDeclaredMethod("m1");
+ s_t9.GetDeclaredMethod("m2");
+ s_t9.GetDeclaredMethod("m3");
+ s_t10.GetDeclaredMethod("m1");
+ s_t10.GetDeclaredMethod("m2");
+ s_t10.GetDeclaredMethod("m3");
+
+ s_t11.GetDeclaredMethod("m1");
+ s_t11.GetDeclaredMethod("m2");
+ s_t11.GetDeclaredMethod("m3");
+ s_t12.GetDeclaredMethod("m1");
+ s_t12.GetDeclaredMethod("m2");
+ s_t12.GetDeclaredMethod("m3");
+ }
}
}
}
- }
- [Benchmark(InnerIterationCount=1000)]
- public static void GetMethod15()
- {
- foreach (var iteration in Benchmark.Iterations)
+ [Benchmark(InnerIterationCount = 1000)]
+ public static void GetMethod15()
{
- using (iteration.StartMeasurement())
+ foreach (var iteration in Benchmark.Iterations)
{
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ using (iteration.StartMeasurement())
{
- s_t1.GetDeclaredMethod("m1");
- s_t1.GetDeclaredMethod("m2");
- s_t1.GetDeclaredMethod("m3");
- s_t2.GetDeclaredMethod("m1");
- s_t2.GetDeclaredMethod("m2");
- s_t2.GetDeclaredMethod("m3");
- s_t3.GetDeclaredMethod("m1");
- s_t3.GetDeclaredMethod("m2");
- s_t3.GetDeclaredMethod("m3");
- s_t4.GetDeclaredMethod("m1");
- s_t4.GetDeclaredMethod("m2");
- s_t4.GetDeclaredMethod("m3");
- s_t5.GetDeclaredMethod("m1");
- s_t5.GetDeclaredMethod("m2");
- s_t5.GetDeclaredMethod("m3");
-
- s_t6.GetDeclaredMethod("m1");
- s_t6.GetDeclaredMethod("m2");
- s_t6.GetDeclaredMethod("m3");
- s_t7.GetDeclaredMethod("m1");
- s_t7.GetDeclaredMethod("m2");
- s_t7.GetDeclaredMethod("m3");
- s_t8.GetDeclaredMethod("m1");
- s_t8.GetDeclaredMethod("m2");
- s_t8.GetDeclaredMethod("m3");
- s_t9.GetDeclaredMethod("m1");
- s_t9.GetDeclaredMethod("m2");
- s_t9.GetDeclaredMethod("m3");
- s_t10.GetDeclaredMethod("m1");
- s_t10.GetDeclaredMethod("m2");
- s_t10.GetDeclaredMethod("m3");
-
- s_t11.GetDeclaredMethod("m1");
- s_t11.GetDeclaredMethod("m2");
- s_t11.GetDeclaredMethod("m3");
- s_t12.GetDeclaredMethod("m1");
- s_t12.GetDeclaredMethod("m2");
- s_t12.GetDeclaredMethod("m3");
- s_t13.GetDeclaredMethod("m1");
- s_t13.GetDeclaredMethod("m2");
- s_t13.GetDeclaredMethod("m3");
- s_t14.GetDeclaredMethod("m1");
- s_t14.GetDeclaredMethod("m2");
- s_t14.GetDeclaredMethod("m3");
- s_t15.GetDeclaredMethod("m1");
- s_t15.GetDeclaredMethod("m2");
- s_t15.GetDeclaredMethod("m3");
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ {
+ s_t1.GetDeclaredMethod("m1");
+ s_t1.GetDeclaredMethod("m2");
+ s_t1.GetDeclaredMethod("m3");
+ s_t2.GetDeclaredMethod("m1");
+ s_t2.GetDeclaredMethod("m2");
+ s_t2.GetDeclaredMethod("m3");
+ s_t3.GetDeclaredMethod("m1");
+ s_t3.GetDeclaredMethod("m2");
+ s_t3.GetDeclaredMethod("m3");
+ s_t4.GetDeclaredMethod("m1");
+ s_t4.GetDeclaredMethod("m2");
+ s_t4.GetDeclaredMethod("m3");
+ s_t5.GetDeclaredMethod("m1");
+ s_t5.GetDeclaredMethod("m2");
+ s_t5.GetDeclaredMethod("m3");
+
+ s_t6.GetDeclaredMethod("m1");
+ s_t6.GetDeclaredMethod("m2");
+ s_t6.GetDeclaredMethod("m3");
+ s_t7.GetDeclaredMethod("m1");
+ s_t7.GetDeclaredMethod("m2");
+ s_t7.GetDeclaredMethod("m3");
+ s_t8.GetDeclaredMethod("m1");
+ s_t8.GetDeclaredMethod("m2");
+ s_t8.GetDeclaredMethod("m3");
+ s_t9.GetDeclaredMethod("m1");
+ s_t9.GetDeclaredMethod("m2");
+ s_t9.GetDeclaredMethod("m3");
+ s_t10.GetDeclaredMethod("m1");
+ s_t10.GetDeclaredMethod("m2");
+ s_t10.GetDeclaredMethod("m3");
+
+ s_t11.GetDeclaredMethod("m1");
+ s_t11.GetDeclaredMethod("m2");
+ s_t11.GetDeclaredMethod("m3");
+ s_t12.GetDeclaredMethod("m1");
+ s_t12.GetDeclaredMethod("m2");
+ s_t12.GetDeclaredMethod("m3");
+ s_t13.GetDeclaredMethod("m1");
+ s_t13.GetDeclaredMethod("m2");
+ s_t13.GetDeclaredMethod("m3");
+ s_t14.GetDeclaredMethod("m1");
+ s_t14.GetDeclaredMethod("m2");
+ s_t14.GetDeclaredMethod("m3");
+ s_t15.GetDeclaredMethod("m1");
+ s_t15.GetDeclaredMethod("m2");
+ s_t15.GetDeclaredMethod("m3");
+ }
}
}
}
- }
- [Benchmark(InnerIterationCount=1000)]
- public static void GetMethod20()
- {
- foreach (var iteration in Benchmark.Iterations)
+ [Benchmark(InnerIterationCount = 1000)]
+ public static void GetMethod20()
{
- using (iteration.StartMeasurement())
+ foreach (var iteration in Benchmark.Iterations)
{
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ using (iteration.StartMeasurement())
{
- s_t1.GetDeclaredMethod("m1");
- s_t1.GetDeclaredMethod("m2");
- s_t1.GetDeclaredMethod("m3");
- s_t2.GetDeclaredMethod("m1");
- s_t2.GetDeclaredMethod("m2");
- s_t2.GetDeclaredMethod("m3");
- s_t3.GetDeclaredMethod("m1");
- s_t3.GetDeclaredMethod("m2");
- s_t3.GetDeclaredMethod("m3");
- s_t4.GetDeclaredMethod("m1");
- s_t4.GetDeclaredMethod("m2");
- s_t4.GetDeclaredMethod("m3");
- s_t5.GetDeclaredMethod("m1");
- s_t5.GetDeclaredMethod("m2");
- s_t5.GetDeclaredMethod("m3");
-
- s_t6.GetDeclaredMethod("m1");
- s_t6.GetDeclaredMethod("m2");
- s_t6.GetDeclaredMethod("m3");
- s_t7.GetDeclaredMethod("m1");
- s_t7.GetDeclaredMethod("m2");
- s_t7.GetDeclaredMethod("m3");
- s_t8.GetDeclaredMethod("m1");
- s_t8.GetDeclaredMethod("m2");
- s_t8.GetDeclaredMethod("m3");
- s_t9.GetDeclaredMethod("m1");
- s_t9.GetDeclaredMethod("m2");
- s_t9.GetDeclaredMethod("m3");
- s_t10.GetDeclaredMethod("m1");
- s_t10.GetDeclaredMethod("m2");
- s_t10.GetDeclaredMethod("m3");
-
- s_t11.GetDeclaredMethod("m1");
- s_t11.GetDeclaredMethod("m2");
- s_t11.GetDeclaredMethod("m3");
- s_t12.GetDeclaredMethod("m1");
- s_t12.GetDeclaredMethod("m2");
- s_t12.GetDeclaredMethod("m3");
- s_t13.GetDeclaredMethod("m1");
- s_t13.GetDeclaredMethod("m2");
- s_t13.GetDeclaredMethod("m3");
- s_t14.GetDeclaredMethod("m1");
- s_t14.GetDeclaredMethod("m2");
- s_t14.GetDeclaredMethod("m3");
- s_t15.GetDeclaredMethod("m1");
- s_t15.GetDeclaredMethod("m2");
- s_t15.GetDeclaredMethod("m3");
-
- s_t16.GetDeclaredMethod("m1");
- s_t16.GetDeclaredMethod("m2");
- s_t16.GetDeclaredMethod("m3");
- s_t17.GetDeclaredMethod("m1");
- s_t17.GetDeclaredMethod("m2");
- s_t17.GetDeclaredMethod("m3");
- s_t18.GetDeclaredMethod("m1");
- s_t18.GetDeclaredMethod("m2");
- s_t18.GetDeclaredMethod("m3");
- s_t19.GetDeclaredMethod("m1");
- s_t19.GetDeclaredMethod("m2");
- s_t19.GetDeclaredMethod("m3");
- s_t20.GetDeclaredMethod("m1");
- s_t20.GetDeclaredMethod("m2");
- s_t20.GetDeclaredMethod("m3");
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ {
+ s_t1.GetDeclaredMethod("m1");
+ s_t1.GetDeclaredMethod("m2");
+ s_t1.GetDeclaredMethod("m3");
+ s_t2.GetDeclaredMethod("m1");
+ s_t2.GetDeclaredMethod("m2");
+ s_t2.GetDeclaredMethod("m3");
+ s_t3.GetDeclaredMethod("m1");
+ s_t3.GetDeclaredMethod("m2");
+ s_t3.GetDeclaredMethod("m3");
+ s_t4.GetDeclaredMethod("m1");
+ s_t4.GetDeclaredMethod("m2");
+ s_t4.GetDeclaredMethod("m3");
+ s_t5.GetDeclaredMethod("m1");
+ s_t5.GetDeclaredMethod("m2");
+ s_t5.GetDeclaredMethod("m3");
+
+ s_t6.GetDeclaredMethod("m1");
+ s_t6.GetDeclaredMethod("m2");
+ s_t6.GetDeclaredMethod("m3");
+ s_t7.GetDeclaredMethod("m1");
+ s_t7.GetDeclaredMethod("m2");
+ s_t7.GetDeclaredMethod("m3");
+ s_t8.GetDeclaredMethod("m1");
+ s_t8.GetDeclaredMethod("m2");
+ s_t8.GetDeclaredMethod("m3");
+ s_t9.GetDeclaredMethod("m1");
+ s_t9.GetDeclaredMethod("m2");
+ s_t9.GetDeclaredMethod("m3");
+ s_t10.GetDeclaredMethod("m1");
+ s_t10.GetDeclaredMethod("m2");
+ s_t10.GetDeclaredMethod("m3");
+
+ s_t11.GetDeclaredMethod("m1");
+ s_t11.GetDeclaredMethod("m2");
+ s_t11.GetDeclaredMethod("m3");
+ s_t12.GetDeclaredMethod("m1");
+ s_t12.GetDeclaredMethod("m2");
+ s_t12.GetDeclaredMethod("m3");
+ s_t13.GetDeclaredMethod("m1");
+ s_t13.GetDeclaredMethod("m2");
+ s_t13.GetDeclaredMethod("m3");
+ s_t14.GetDeclaredMethod("m1");
+ s_t14.GetDeclaredMethod("m2");
+ s_t14.GetDeclaredMethod("m3");
+ s_t15.GetDeclaredMethod("m1");
+ s_t15.GetDeclaredMethod("m2");
+ s_t15.GetDeclaredMethod("m3");
+
+ s_t16.GetDeclaredMethod("m1");
+ s_t16.GetDeclaredMethod("m2");
+ s_t16.GetDeclaredMethod("m3");
+ s_t17.GetDeclaredMethod("m1");
+ s_t17.GetDeclaredMethod("m2");
+ s_t17.GetDeclaredMethod("m3");
+ s_t18.GetDeclaredMethod("m1");
+ s_t18.GetDeclaredMethod("m2");
+ s_t18.GetDeclaredMethod("m3");
+ s_t19.GetDeclaredMethod("m1");
+ s_t19.GetDeclaredMethod("m2");
+ s_t19.GetDeclaredMethod("m3");
+ s_t20.GetDeclaredMethod("m1");
+ s_t20.GetDeclaredMethod("m2");
+ s_t20.GetDeclaredMethod("m3");
+ }
}
}
}
- }
- /*
- [Benchmark(InnerIterationCount=1000)]
- public static void GetConstructor()
- {
- foreach (var iteration in Benchmark.Iterations)
+ /*
+ [Benchmark(InnerIterationCount=1000)]
+ public static void GetConstructor()
{
- using (iteration.StartMeasurement())
+ foreach (var iteration in Benchmark.Iterations)
{
- s_t1.GetConstructor(new Type[] { });
- s_t1.GetConstructor(new Type[] { typeof(int) });
- s_t1.GetConstructor(new Type[] { typeof(int), typeof(int) });
- s_t2.GetConstructor(new Type[] { });
- s_t2.GetConstructor(new Type[] { typeof(int) });
- s_t2.GetConstructor(new Type[] { typeof(int), typeof(int) });
- s_t3.GetConstructor(new Type[] { });
- s_t3.GetConstructor(new Type[] { typeof(int) });
- s_t3.GetConstructor(new Type[] { typeof(int), typeof(int) });
- s_t4.GetConstructor(new Type[] { });
- s_t4.GetConstructor(new Type[] { typeof(int) });
- s_t4.GetConstructor(new Type[] { typeof(int), typeof(int) });
- s_t5.GetConstructor(new Type[] { });
- s_t5.GetConstructor(new Type[] { typeof(int) });
- s_t5.GetConstructor(new Type[] { typeof(int), typeof(int) });
+ using (iteration.StartMeasurement())
+ {
+ s_t1.GetConstructor(new Type[] { });
+ s_t1.GetConstructor(new Type[] { typeof(int) });
+ s_t1.GetConstructor(new Type[] { typeof(int), typeof(int) });
+ s_t2.GetConstructor(new Type[] { });
+ s_t2.GetConstructor(new Type[] { typeof(int) });
+ s_t2.GetConstructor(new Type[] { typeof(int), typeof(int) });
+ s_t3.GetConstructor(new Type[] { });
+ s_t3.GetConstructor(new Type[] { typeof(int) });
+ s_t3.GetConstructor(new Type[] { typeof(int), typeof(int) });
+ s_t4.GetConstructor(new Type[] { });
+ s_t4.GetConstructor(new Type[] { typeof(int) });
+ s_t4.GetConstructor(new Type[] { typeof(int), typeof(int) });
+ s_t5.GetConstructor(new Type[] { });
+ s_t5.GetConstructor(new Type[] { typeof(int) });
+ s_t5.GetConstructor(new Type[] { typeof(int), typeof(int) });
+ }
}
}
- }
- [Benchmark(InnerIterationCount=1000)]
- public static void GetProperty()
- {
- foreach (var iteration in Benchmark.Iterations)
+ [Benchmark(InnerIterationCount=1000)]
+ public static void GetProperty()
{
- using (iteration.StartMeasurement())
+ foreach (var iteration in Benchmark.Iterations)
{
- PropertyInfo pi = s_t1.GetProperty("p1");
- pi.GetSetMethod();
- pi.GetGetMethod();
- pi = s_t1.GetProperty("p2");
- pi.GetSetMethod();
- pi.GetGetMethod();
- pi = s_t1.GetProperty("p3");
- pi.GetSetMethod();
- pi.GetGetMethod();
- pi = s_t2.GetProperty("p1");
- pi.GetSetMethod();
- pi.GetGetMethod();
- pi = s_t2.GetProperty("p2");
- pi.GetSetMethod();
- pi.GetGetMethod();
- pi = s_t2.GetProperty("p3");
- pi.GetSetMethod();
- pi.GetGetMethod();
- s_t3.GetProperty("p1");
- s_t3.GetProperty("p2");
- s_t3.GetProperty("p3");
- s_t4.GetProperty("p1");
- s_t4.GetProperty("p2");
- s_t4.GetProperty("p3");
- s_t5.GetProperty("p1");
- s_t5.GetProperty("p2");
- s_t5.GetProperty("p3");
+ using (iteration.StartMeasurement())
+ {
+ PropertyInfo pi = s_t1.GetProperty("p1");
+ pi.GetSetMethod();
+ pi.GetGetMethod();
+ pi = s_t1.GetProperty("p2");
+ pi.GetSetMethod();
+ pi.GetGetMethod();
+ pi = s_t1.GetProperty("p3");
+ pi.GetSetMethod();
+ pi.GetGetMethod();
+ pi = s_t2.GetProperty("p1");
+ pi.GetSetMethod();
+ pi.GetGetMethod();
+ pi = s_t2.GetProperty("p2");
+ pi.GetSetMethod();
+ pi.GetGetMethod();
+ pi = s_t2.GetProperty("p3");
+ pi.GetSetMethod();
+ pi.GetGetMethod();
+ s_t3.GetProperty("p1");
+ s_t3.GetProperty("p2");
+ s_t3.GetProperty("p3");
+ s_t4.GetProperty("p1");
+ s_t4.GetProperty("p2");
+ s_t4.GetProperty("p3");
+ s_t5.GetProperty("p1");
+ s_t5.GetProperty("p2");
+ s_t5.GetProperty("p3");
+ }
}
}
- }
- [Benchmark(InnerIterationCount=1000)]
- public static void GetEvent()
- {
- foreach (var iteration in Benchmark.Iterations)
+ [Benchmark(InnerIterationCount=1000)]
+ public static void GetEvent()
{
- using (iteration.StartMeasurement())
+ foreach (var iteration in Benchmark.Iterations)
{
- EventInfo ei = s_t1.GetEvent("e1");
- ei.GetAddMethod();
- ei.GetRaiseMethod();
- ei.GetRemoveMethod();
- s_t1.GetEvent("e2");
- ei.GetAddMethod();
- ei.GetRaiseMethod();
- ei.GetRemoveMethod();
- s_t1.GetEvent("e3");
- ei.GetAddMethod();
- ei.GetRaiseMethod();
- ei.GetRemoveMethod();
- s_t2.GetEvent("e1");
- ei.GetAddMethod();
- ei.GetRaiseMethod();
- ei.GetRemoveMethod();
- s_t2.GetEvent("e2");
- ei.GetAddMethod();
- ei.GetRaiseMethod();
- ei.GetRemoveMethod();
- s_t2.GetEvent("e3");
- ei.GetAddMethod();
- ei.GetRaiseMethod();
- ei.GetRemoveMethod();
- s_t3.GetEvent("e1");
- s_t3.GetEvent("e2");
- s_t3.GetEvent("e3");
- s_t4.GetEvent("e1");
- s_t4.GetEvent("e2");
- s_t4.GetEvent("e3");
- s_t5.GetEvent("e1");
- s_t5.GetEvent("e2");
- s_t5.GetEvent("e3");
+ using (iteration.StartMeasurement())
+ {
+ EventInfo ei = s_t1.GetEvent("e1");
+ ei.GetAddMethod();
+ ei.GetRaiseMethod();
+ ei.GetRemoveMethod();
+ s_t1.GetEvent("e2");
+ ei.GetAddMethod();
+ ei.GetRaiseMethod();
+ ei.GetRemoveMethod();
+ s_t1.GetEvent("e3");
+ ei.GetAddMethod();
+ ei.GetRaiseMethod();
+ ei.GetRemoveMethod();
+ s_t2.GetEvent("e1");
+ ei.GetAddMethod();
+ ei.GetRaiseMethod();
+ ei.GetRemoveMethod();
+ s_t2.GetEvent("e2");
+ ei.GetAddMethod();
+ ei.GetRaiseMethod();
+ ei.GetRemoveMethod();
+ s_t2.GetEvent("e3");
+ ei.GetAddMethod();
+ ei.GetRaiseMethod();
+ ei.GetRemoveMethod();
+ s_t3.GetEvent("e1");
+ s_t3.GetEvent("e2");
+ s_t3.GetEvent("e3");
+ s_t4.GetEvent("e1");
+ s_t4.GetEvent("e2");
+ s_t4.GetEvent("e3");
+ s_t5.GetEvent("e1");
+ s_t5.GetEvent("e2");
+ s_t5.GetEvent("e3");
+ }
}
}
+ */
}
- */
-}
-#region ClassDef
-public class Class1
-{
- public Class1() { }
- public Class1(int i) { }
- public Class1(int i, int ii) { }
- public int f0 = 0;
- static public int f1 = 0;
- public int f2 = 0;
- public int f3 = 0;
- public int f4 = 0;
- public int f5 = 0;
- public int f6 = 0;
- public int f7 = 0;
- public int f8 = 0;
- public int f9 = 0;
- public int f10 = 0;
- public int f11 = 0;
- public int f12 = 0;
- public int f13 = 0;
- public int f14 = 0;
- public int f15 = 0;
- public int f16 = 0;
- public int f17 = 0;
- public int f18 = 0;
- public int f19 = 0;
- public int f20 = 0;
- public int f21 = 0;
- public int f22 = 0;
- public int f23 = 0;
- public int f24 = 0;
-
- public void m1() { }
- static public void m2() { }
- public void m3() { }
- public void m4() { }
- public void m5() { }
- public void m6() { }
- public void m7() { }
- public void m8() { }
- public void m9() { }
- public void m10() { }
- public void m11() { }
- public void m12() { }
- public void m13() { }
- public void m14() { }
- public void m15() { }
- public void m16() { }
- public void m17() { }
- public void m18() { }
- public void m19() { }
- public void m20() { }
- public void m21() { }
- public void m22() { }
- public void m23() { }
- public void m24() { }
-
- public int p0 { get { return 1; } set { } }
- static public int p1 { get { return 1; } set { } }
- public int p2 { get { return 1; } set { } }
- public int p3 { get { return 1; } set { } }
- public int p4 { get { return 1; } set { } }
- public int p5 { get { return 1; } set { } }
- public int p6 { get { return 1; } set { } }
- public int p7 { get { return 1; } set { } }
- public int p8 { get { return 1; } set { } }
- public int p9 { get { return 1; } set { } }
- public int p10 { get { return 1; } set { } }
- public int p11 { get { return 1; } set { } }
- public int p12 { get { return 1; } set { } }
- public int p13 { get { return 1; } set { } }
- public int p14 { get { return 1; } set { } }
- public int p15 { get { return 1; } set { } }
- public int p16 { get { return 1; } set { } }
- public int p17 { get { return 1; } set { } }
- public int p18 { get { return 1; } set { } }
- public int p19 { get { return 1; } set { } }
- public int p20 { get { return 1; } set { } }
- public int p21 { get { return 1; } set { } }
- public int p22 { get { return 1; } set { } }
- public int p23 { get { return 1; } set { } }
- public int p24 { get { return 1; } set { } }
-
- public event d e0;
- static public event d e1;
- public event d e2;
- public event d e3;
- public event d e4;
- public event d e5;
- public event d e6;
- public event d e7;
- public event d e8;
- public event d e9;
- public event d e10;
- public event d e11;
- public event d e12;
- public event d e13;
- public event d e14;
- public event d e15;
- public event d e16;
- public event d e17;
- public event d e18;
- public event d e19;
- public event d e20;
- public event d e21;
- public event d e22;
- public event d e23;
- public event d e24;
-
- public void NoWarning()
+ #region ClassDef
+ public class Class1
{
- e0 += new d(m1);
- e1 += new d(m1);
- e2 += new d(m1);
- e3 += new d(m1);
- e4 += new d(m1);
- e5 += new d(m1);
- e6 += new d(m1);
- e7 += new d(m1);
- e8 += new d(m1);
- e9 += new d(m1);
- e10 += new d(m1);
- e11 += new d(m1);
- e12 += new d(m1);
- e13 += new d(m1);
- e14 += new d(m1);
- e15 += new d(m1);
- e16 += new d(m1);
- e17 += new d(m1);
- e18 += new d(m1);
- e19 += new d(m1);
- e20 += new d(m1);
- e21 += new d(m1);
- e22 += new d(m1);
- e23 += new d(m1);
- e24 += new d(m1);
+ public Class1() { }
+ public Class1(int i) { }
+ public Class1(int i, int ii) { }
+ public int f0 = 0;
+ static public int f1 = 0;
+ public int f2 = 0;
+ public int f3 = 0;
+ public int f4 = 0;
+ public int f5 = 0;
+ public int f6 = 0;
+ public int f7 = 0;
+ public int f8 = 0;
+ public int f9 = 0;
+ public int f10 = 0;
+ public int f11 = 0;
+ public int f12 = 0;
+ public int f13 = 0;
+ public int f14 = 0;
+ public int f15 = 0;
+ public int f16 = 0;
+ public int f17 = 0;
+ public int f18 = 0;
+ public int f19 = 0;
+ public int f20 = 0;
+ public int f21 = 0;
+ public int f22 = 0;
+ public int f23 = 0;
+ public int f24 = 0;
+
+ public void m1() { }
+ static public void m2() { }
+ public void m3() { }
+ public void m4() { }
+ public void m5() { }
+ public void m6() { }
+ public void m7() { }
+ public void m8() { }
+ public void m9() { }
+ public void m10() { }
+ public void m11() { }
+ public void m12() { }
+ public void m13() { }
+ public void m14() { }
+ public void m15() { }
+ public void m16() { }
+ public void m17() { }
+ public void m18() { }
+ public void m19() { }
+ public void m20() { }
+ public void m21() { }
+ public void m22() { }
+ public void m23() { }
+ public void m24() { }
+
+ public int p0 { get { return 1; } set { } }
+ static public int p1 { get { return 1; } set { } }
+ public int p2 { get { return 1; } set { } }
+ public int p3 { get { return 1; } set { } }
+ public int p4 { get { return 1; } set { } }
+ public int p5 { get { return 1; } set { } }
+ public int p6 { get { return 1; } set { } }
+ public int p7 { get { return 1; } set { } }
+ public int p8 { get { return 1; } set { } }
+ public int p9 { get { return 1; } set { } }
+ public int p10 { get { return 1; } set { } }
+ public int p11 { get { return 1; } set { } }
+ public int p12 { get { return 1; } set { } }
+ public int p13 { get { return 1; } set { } }
+ public int p14 { get { return 1; } set { } }
+ public int p15 { get { return 1; } set { } }
+ public int p16 { get { return 1; } set { } }
+ public int p17 { get { return 1; } set { } }
+ public int p18 { get { return 1; } set { } }
+ public int p19 { get { return 1; } set { } }
+ public int p20 { get { return 1; } set { } }
+ public int p21 { get { return 1; } set { } }
+ public int p22 { get { return 1; } set { } }
+ public int p23 { get { return 1; } set { } }
+ public int p24 { get { return 1; } set { } }
+
+ public event d e0;
+ static public event d e1;
+ public event d e2;
+ public event d e3;
+ public event d e4;
+ public event d e5;
+ public event d e6;
+ public event d e7;
+ public event d e8;
+ public event d e9;
+ public event d e10;
+ public event d e11;
+ public event d e12;
+ public event d e13;
+ public event d e14;
+ public event d e15;
+ public event d e16;
+ public event d e17;
+ public event d e18;
+ public event d e19;
+ public event d e20;
+ public event d e21;
+ public event d e22;
+ public event d e23;
+ public event d e24;
+
+ public void NoWarning()
+ {
+ e0 += new d(m1);
+ e1 += new d(m1);
+ e2 += new d(m1);
+ e3 += new d(m1);
+ e4 += new d(m1);
+ e5 += new d(m1);
+ e6 += new d(m1);
+ e7 += new d(m1);
+ e8 += new d(m1);
+ e9 += new d(m1);
+ e10 += new d(m1);
+ e11 += new d(m1);
+ e12 += new d(m1);
+ e13 += new d(m1);
+ e14 += new d(m1);
+ e15 += new d(m1);
+ e16 += new d(m1);
+ e17 += new d(m1);
+ e18 += new d(m1);
+ e19 += new d(m1);
+ e20 += new d(m1);
+ e21 += new d(m1);
+ e22 += new d(m1);
+ e23 += new d(m1);
+ e24 += new d(m1);
+ }
}
-}
-public class Class2
-{
- public Class2() { }
- public Class2(int i) { }
- public Class2(int i, int ii) { }
- public int f0 = 0;
- static public int f1 = 0;
- public int f2 = 0;
- public int f3 = 0;
- public int f4 = 0;
- public int f5 = 0;
- public int f6 = 0;
- public int f7 = 0;
- public int f8 = 0;
- public int f9 = 0;
- public int f10 = 0;
- public int f11 = 0;
- public int f12 = 0;
- public int f13 = 0;
- public int f14 = 0;
- public int f15 = 0;
- public int f16 = 0;
- public int f17 = 0;
- public int f18 = 0;
- public int f19 = 0;
- public int f20 = 0;
- public int f21 = 0;
- public int f22 = 0;
- public int f23 = 0;
- public int f24 = 0;
-
- public void m1() { }
- static public void m2() { }
- public void m3() { }
- public void m4() { }
- public void m5() { }
- public void m6() { }
- public void m7() { }
- public void m8() { }
- public void m9() { }
- public void m10() { }
- public void m11() { }
- public void m12() { }
- public void m13() { }
- public void m14() { }
- public void m15() { }
- public void m16() { }
- public void m17() { }
- public void m18() { }
- public void m19() { }
- public void m20() { }
- public void m21() { }
- public void m22() { }
- public void m23() { }
- public void m24() { }
-
- public int p0 { get { return 1; } set { } }
- static public int p1 { get { return 1; } set { } }
- public int p2 { get { return 1; } set { } }
- public int p3 { get { return 1; } set { } }
- public int p4 { get { return 1; } set { } }
- public int p5 { get { return 1; } set { } }
- public int p6 { get { return 1; } set { } }
- public int p7 { get { return 1; } set { } }
- public int p8 { get { return 1; } set { } }
- public int p9 { get { return 1; } set { } }
- public int p10 { get { return 1; } set { } }
- public int p11 { get { return 1; } set { } }
- public int p12 { get { return 1; } set { } }
- public int p13 { get { return 1; } set { } }
- public int p14 { get { return 1; } set { } }
- public int p15 { get { return 1; } set { } }
- public int p16 { get { return 1; } set { } }
- public int p17 { get { return 1; } set { } }
- public int p18 { get { return 1; } set { } }
- public int p19 { get { return 1; } set { } }
- public int p20 { get { return 1; } set { } }
- public int p21 { get { return 1; } set { } }
- public int p22 { get { return 1; } set { } }
- public int p23 { get { return 1; } set { } }
- public int p24 { get { return 1; } set { } }
-
- public event d e0;
- static public event d e1;
- public event d e2;
- public event d e3;
- public event d e4;
- public event d e5;
- public event d e6;
- public event d e7;
- public event d e8;
- public event d e9;
- public event d e10;
- public event d e11;
- public event d e12;
- public event d e13;
- public event d e14;
- public event d e15;
- public event d e16;
- public event d e17;
- public event d e18;
- public event d e19;
- public event d e20;
- public event d e21;
- public event d e22;
- public event d e23;
- public event d e24;
-
- public void NoWarning()
+ public class Class2
{
- e0 += new d(m1);
- e1 += new d(m1);
- e2 += new d(m1);
- e3 += new d(m1);
- e4 += new d(m1);
- e5 += new d(m1);
- e6 += new d(m1);
- e7 += new d(m1);
- e8 += new d(m1);
- e9 += new d(m1);
- e10 += new d(m1);
- e11 += new d(m1);
- e12 += new d(m1);
- e13 += new d(m1);
- e14 += new d(m1);
- e15 += new d(m1);
- e16 += new d(m1);
- e17 += new d(m1);
- e18 += new d(m1);
- e19 += new d(m1);
- e20 += new d(m1);
- e21 += new d(m1);
- e22 += new d(m1);
- e23 += new d(m1);
- e24 += new d(m1);
+ public Class2() { }
+ public Class2(int i) { }
+ public Class2(int i, int ii) { }
+ public int f0 = 0;
+ static public int f1 = 0;
+ public int f2 = 0;
+ public int f3 = 0;
+ public int f4 = 0;
+ public int f5 = 0;
+ public int f6 = 0;
+ public int f7 = 0;
+ public int f8 = 0;
+ public int f9 = 0;
+ public int f10 = 0;
+ public int f11 = 0;
+ public int f12 = 0;
+ public int f13 = 0;
+ public int f14 = 0;
+ public int f15 = 0;
+ public int f16 = 0;
+ public int f17 = 0;
+ public int f18 = 0;
+ public int f19 = 0;
+ public int f20 = 0;
+ public int f21 = 0;
+ public int f22 = 0;
+ public int f23 = 0;
+ public int f24 = 0;
+
+ public void m1() { }
+ static public void m2() { }
+ public void m3() { }
+ public void m4() { }
+ public void m5() { }
+ public void m6() { }
+ public void m7() { }
+ public void m8() { }
+ public void m9() { }
+ public void m10() { }
+ public void m11() { }
+ public void m12() { }
+ public void m13() { }
+ public void m14() { }
+ public void m15() { }
+ public void m16() { }
+ public void m17() { }
+ public void m18() { }
+ public void m19() { }
+ public void m20() { }
+ public void m21() { }
+ public void m22() { }
+ public void m23() { }
+ public void m24() { }
+
+ public int p0 { get { return 1; } set { } }
+ static public int p1 { get { return 1; } set { } }
+ public int p2 { get { return 1; } set { } }
+ public int p3 { get { return 1; } set { } }
+ public int p4 { get { return 1; } set { } }
+ public int p5 { get { return 1; } set { } }
+ public int p6 { get { return 1; } set { } }
+ public int p7 { get { return 1; } set { } }
+ public int p8 { get { return 1; } set { } }
+ public int p9 { get { return 1; } set { } }
+ public int p10 { get { return 1; } set { } }
+ public int p11 { get { return 1; } set { } }
+ public int p12 { get { return 1; } set { } }
+ public int p13 { get { return 1; } set { } }
+ public int p14 { get { return 1; } set { } }
+ public int p15 { get { return 1; } set { } }
+ public int p16 { get { return 1; } set { } }
+ public int p17 { get { return 1; } set { } }
+ public int p18 { get { return 1; } set { } }
+ public int p19 { get { return 1; } set { } }
+ public int p20 { get { return 1; } set { } }
+ public int p21 { get { return 1; } set { } }
+ public int p22 { get { return 1; } set { } }
+ public int p23 { get { return 1; } set { } }
+ public int p24 { get { return 1; } set { } }
+
+ public event d e0;
+ static public event d e1;
+ public event d e2;
+ public event d e3;
+ public event d e4;
+ public event d e5;
+ public event d e6;
+ public event d e7;
+ public event d e8;
+ public event d e9;
+ public event d e10;
+ public event d e11;
+ public event d e12;
+ public event d e13;
+ public event d e14;
+ public event d e15;
+ public event d e16;
+ public event d e17;
+ public event d e18;
+ public event d e19;
+ public event d e20;
+ public event d e21;
+ public event d e22;
+ public event d e23;
+ public event d e24;
+
+ public void NoWarning()
+ {
+ e0 += new d(m1);
+ e1 += new d(m1);
+ e2 += new d(m1);
+ e3 += new d(m1);
+ e4 += new d(m1);
+ e5 += new d(m1);
+ e6 += new d(m1);
+ e7 += new d(m1);
+ e8 += new d(m1);
+ e9 += new d(m1);
+ e10 += new d(m1);
+ e11 += new d(m1);
+ e12 += new d(m1);
+ e13 += new d(m1);
+ e14 += new d(m1);
+ e15 += new d(m1);
+ e16 += new d(m1);
+ e17 += new d(m1);
+ e18 += new d(m1);
+ e19 += new d(m1);
+ e20 += new d(m1);
+ e21 += new d(m1);
+ e22 += new d(m1);
+ e23 += new d(m1);
+ e24 += new d(m1);
+ }
}
-}
-public class Class3
-{
- public Class3() { }
- public Class3(int i) { }
- public Class3(int i, int ii) { }
- public int f0 = 0;
- static public int f1 = 0;
- public int f2 = 0;
- public int f3 = 0;
- public int f4 = 0;
- public int f5 = 0;
- public int f6 = 0;
- public int f7 = 0;
- public int f8 = 0;
- public int f9 = 0;
- public int f10 = 0;
- public int f11 = 0;
- public int f12 = 0;
- public int f13 = 0;
- public int f14 = 0;
- public int f15 = 0;
- public int f16 = 0;
- public int f17 = 0;
- public int f18 = 0;
- public int f19 = 0;
- public int f20 = 0;
- public int f21 = 0;
- public int f22 = 0;
- public int f23 = 0;
- public int f24 = 0;
-
- public void m1() { }
- static public void m2() { }
- public void m3() { }
- public void m4() { }
- public void m5() { }
- public void m6() { }
- public void m7() { }
- public void m8() { }
- public void m9() { }
- public void m10() { }
- public void m11() { }
- public void m12() { }
- public void m13() { }
- public void m14() { }
- public void m15() { }
- public void m16() { }
- public void m17() { }
- public void m18() { }
- public void m19() { }
- public void m20() { }
- public void m21() { }
- public void m22() { }
- public void m23() { }
- public void m24() { }
-
- public int p0 { get { return 1; } set { } }
- static public int p1 { get { return 1; } set { } }
- public int p2 { get { return 1; } set { } }
- public int p3 { get { return 1; } set { } }
- public int p4 { get { return 1; } set { } }
- public int p5 { get { return 1; } set { } }
- public int p6 { get { return 1; } set { } }
- public int p7 { get { return 1; } set { } }
- public int p8 { get { return 1; } set { } }
- public int p9 { get { return 1; } set { } }
- public int p10 { get { return 1; } set { } }
- public int p11 { get { return 1; } set { } }
- public int p12 { get { return 1; } set { } }
- public int p13 { get { return 1; } set { } }
- public int p14 { get { return 1; } set { } }
- public int p15 { get { return 1; } set { } }
- public int p16 { get { return 1; } set { } }
- public int p17 { get { return 1; } set { } }
- public int p18 { get { return 1; } set { } }
- public int p19 { get { return 1; } set { } }
- public int p20 { get { return 1; } set { } }
- public int p21 { get { return 1; } set { } }
- public int p22 { get { return 1; } set { } }
- public int p23 { get { return 1; } set { } }
- public int p24 { get { return 1; } set { } }
-
- public event d e0;
- static public event d e1;
- public event d e2;
- public event d e3;
- public event d e4;
- public event d e5;
- public event d e6;
- public event d e7;
- public event d e8;
- public event d e9;
- public event d e10;
- public event d e11;
- public event d e12;
- public event d e13;
- public event d e14;
- public event d e15;
- public event d e16;
- public event d e17;
- public event d e18;
- public event d e19;
- public event d e20;
- public event d e21;
- public event d e22;
- public event d e23;
- public event d e24;
-
- public void NoWarning()
+ public class Class3
{
- e0 += new d(m1);
- e1 += new d(m1);
- e2 += new d(m1);
- e3 += new d(m1);
- e4 += new d(m1);
- e5 += new d(m1);
- e6 += new d(m1);
- e7 += new d(m1);
- e8 += new d(m1);
- e9 += new d(m1);
- e10 += new d(m1);
- e11 += new d(m1);
- e12 += new d(m1);
- e13 += new d(m1);
- e14 += new d(m1);
- e15 += new d(m1);
- e16 += new d(m1);
- e17 += new d(m1);
- e18 += new d(m1);
- e19 += new d(m1);
- e20 += new d(m1);
- e21 += new d(m1);
- e22 += new d(m1);
- e23 += new d(m1);
- e24 += new d(m1);
+ public Class3() { }
+ public Class3(int i) { }
+ public Class3(int i, int ii) { }
+ public int f0 = 0;
+ static public int f1 = 0;
+ public int f2 = 0;
+ public int f3 = 0;
+ public int f4 = 0;
+ public int f5 = 0;
+ public int f6 = 0;
+ public int f7 = 0;
+ public int f8 = 0;
+ public int f9 = 0;
+ public int f10 = 0;
+ public int f11 = 0;
+ public int f12 = 0;
+ public int f13 = 0;
+ public int f14 = 0;
+ public int f15 = 0;
+ public int f16 = 0;
+ public int f17 = 0;
+ public int f18 = 0;
+ public int f19 = 0;
+ public int f20 = 0;
+ public int f21 = 0;
+ public int f22 = 0;
+ public int f23 = 0;
+ public int f24 = 0;
+
+ public void m1() { }
+ static public void m2() { }
+ public void m3() { }
+ public void m4() { }
+ public void m5() { }
+ public void m6() { }
+ public void m7() { }
+ public void m8() { }
+ public void m9() { }
+ public void m10() { }
+ public void m11() { }
+ public void m12() { }
+ public void m13() { }
+ public void m14() { }
+ public void m15() { }
+ public void m16() { }
+ public void m17() { }
+ public void m18() { }
+ public void m19() { }
+ public void m20() { }
+ public void m21() { }
+ public void m22() { }
+ public void m23() { }
+ public void m24() { }
+
+ public int p0 { get { return 1; } set { } }
+ static public int p1 { get { return 1; } set { } }
+ public int p2 { get { return 1; } set { } }
+ public int p3 { get { return 1; } set { } }
+ public int p4 { get { return 1; } set { } }
+ public int p5 { get { return 1; } set { } }
+ public int p6 { get { return 1; } set { } }
+ public int p7 { get { return 1; } set { } }
+ public int p8 { get { return 1; } set { } }
+ public int p9 { get { return 1; } set { } }
+ public int p10 { get { return 1; } set { } }
+ public int p11 { get { return 1; } set { } }
+ public int p12 { get { return 1; } set { } }
+ public int p13 { get { return 1; } set { } }
+ public int p14 { get { return 1; } set { } }
+ public int p15 { get { return 1; } set { } }
+ public int p16 { get { return 1; } set { } }
+ public int p17 { get { return 1; } set { } }
+ public int p18 { get { return 1; } set { } }
+ public int p19 { get { return 1; } set { } }
+ public int p20 { get { return 1; } set { } }
+ public int p21 { get { return 1; } set { } }
+ public int p22 { get { return 1; } set { } }
+ public int p23 { get { return 1; } set { } }
+ public int p24 { get { return 1; } set { } }
+
+ public event d e0;
+ static public event d e1;
+ public event d e2;
+ public event d e3;
+ public event d e4;
+ public event d e5;
+ public event d e6;
+ public event d e7;
+ public event d e8;
+ public event d e9;
+ public event d e10;
+ public event d e11;
+ public event d e12;
+ public event d e13;
+ public event d e14;
+ public event d e15;
+ public event d e16;
+ public event d e17;
+ public event d e18;
+ public event d e19;
+ public event d e20;
+ public event d e21;
+ public event d e22;
+ public event d e23;
+ public event d e24;
+
+ public void NoWarning()
+ {
+ e0 += new d(m1);
+ e1 += new d(m1);
+ e2 += new d(m1);
+ e3 += new d(m1);
+ e4 += new d(m1);
+ e5 += new d(m1);
+ e6 += new d(m1);
+ e7 += new d(m1);
+ e8 += new d(m1);
+ e9 += new d(m1);
+ e10 += new d(m1);
+ e11 += new d(m1);
+ e12 += new d(m1);
+ e13 += new d(m1);
+ e14 += new d(m1);
+ e15 += new d(m1);
+ e16 += new d(m1);
+ e17 += new d(m1);
+ e18 += new d(m1);
+ e19 += new d(m1);
+ e20 += new d(m1);
+ e21 += new d(m1);
+ e22 += new d(m1);
+ e23 += new d(m1);
+ e24 += new d(m1);
+ }
}
-}
-public class Class4
-{
- public Class4() { }
- public Class4(int i) { }
- public Class4(int i, int ii) { }
-
- public int f0 = 0;
- static public int f1 = 0;
- public int f2 = 0;
- public int f3 = 0;
- public int f4 = 0;
- public int f5 = 0;
- public int f6 = 0;
- public int f7 = 0;
- public int f8 = 0;
- public int f9 = 0;
- public int f10 = 0;
- public int f11 = 0;
- public int f12 = 0;
- public int f13 = 0;
- public int f14 = 0;
- public int f15 = 0;
- public int f16 = 0;
- public int f17 = 0;
- public int f18 = 0;
- public int f19 = 0;
- public int f20 = 0;
- public int f21 = 0;
- public int f22 = 0;
- public int f23 = 0;
- public int f24 = 0;
-
- public void m1() { }
- static public void m2() { }
- public void m3() { }
- public void m4() { }
- public void m5() { }
- public void m6() { }
- public void m7() { }
- public void m8() { }
- public void m9() { }
- public void m10() { }
- public void m11() { }
- public void m12() { }
- public void m13() { }
- public void m14() { }
- public void m15() { }
- public void m16() { }
- public void m17() { }
- public void m18() { }
- public void m19() { }
- public void m20() { }
- public void m21() { }
- public void m22() { }
- public void m23() { }
- public void m24() { }
-
- public int p0 { get { return 1; } set { } }
- static public int p1 { get { return 1; } set { } }
- public int p2 { get { return 1; } set { } }
- public int p3 { get { return 1; } set { } }
- public int p4 { get { return 1; } set { } }
- public int p5 { get { return 1; } set { } }
- public int p6 { get { return 1; } set { } }
- public int p7 { get { return 1; } set { } }
- public int p8 { get { return 1; } set { } }
- public int p9 { get { return 1; } set { } }
- public int p10 { get { return 1; } set { } }
- public int p11 { get { return 1; } set { } }
- public int p12 { get { return 1; } set { } }
- public int p13 { get { return 1; } set { } }
- public int p14 { get { return 1; } set { } }
- public int p15 { get { return 1; } set { } }
- public int p16 { get { return 1; } set { } }
- public int p17 { get { return 1; } set { } }
- public int p18 { get { return 1; } set { } }
- public int p19 { get { return 1; } set { } }
- public int p20 { get { return 1; } set { } }
- public int p21 { get { return 1; } set { } }
- public int p22 { get { return 1; } set { } }
- public int p23 { get { return 1; } set { } }
- public int p24 { get { return 1; } set { } }
-
- public event d e0;
- static public event d e1;
- public event d e2;
- public event d e3;
- public event d e4;
- public event d e5;
- public event d e6;
- public event d e7;
- public event d e8;
- public event d e9;
- public event d e10;
- public event d e11;
- public event d e12;
- public event d e13;
- public event d e14;
- public event d e15;
- public event d e16;
- public event d e17;
- public event d e18;
- public event d e19;
- public event d e20;
- public event d e21;
- public event d e22;
- public event d e23;
- public event d e24;
-
- public void NoWarning()
+ public class Class4
{
- e0 += new d(m1);
- e1 += new d(m1);
- e2 += new d(m1);
- e3 += new d(m1);
- e4 += new d(m1);
- e5 += new d(m1);
- e6 += new d(m1);
- e7 += new d(m1);
- e8 += new d(m1);
- e9 += new d(m1);
- e10 += new d(m1);
- e11 += new d(m1);
- e12 += new d(m1);
- e13 += new d(m1);
- e14 += new d(m1);
- e15 += new d(m1);
- e16 += new d(m1);
- e17 += new d(m1);
- e18 += new d(m1);
- e19 += new d(m1);
- e20 += new d(m1);
- e21 += new d(m1);
- e22 += new d(m1);
- e23 += new d(m1);
- e24 += new d(m1);
+ public Class4() { }
+ public Class4(int i) { }
+ public Class4(int i, int ii) { }
+
+ public int f0 = 0;
+ static public int f1 = 0;
+ public int f2 = 0;
+ public int f3 = 0;
+ public int f4 = 0;
+ public int f5 = 0;
+ public int f6 = 0;
+ public int f7 = 0;
+ public int f8 = 0;
+ public int f9 = 0;
+ public int f10 = 0;
+ public int f11 = 0;
+ public int f12 = 0;
+ public int f13 = 0;
+ public int f14 = 0;
+ public int f15 = 0;
+ public int f16 = 0;
+ public int f17 = 0;
+ public int f18 = 0;
+ public int f19 = 0;
+ public int f20 = 0;
+ public int f21 = 0;
+ public int f22 = 0;
+ public int f23 = 0;
+ public int f24 = 0;
+
+ public void m1() { }
+ static public void m2() { }
+ public void m3() { }
+ public void m4() { }
+ public void m5() { }
+ public void m6() { }
+ public void m7() { }
+ public void m8() { }
+ public void m9() { }
+ public void m10() { }
+ public void m11() { }
+ public void m12() { }
+ public void m13() { }
+ public void m14() { }
+ public void m15() { }
+ public void m16() { }
+ public void m17() { }
+ public void m18() { }
+ public void m19() { }
+ public void m20() { }
+ public void m21() { }
+ public void m22() { }
+ public void m23() { }
+ public void m24() { }
+
+ public int p0 { get { return 1; } set { } }
+ static public int p1 { get { return 1; } set { } }
+ public int p2 { get { return 1; } set { } }
+ public int p3 { get { return 1; } set { } }
+ public int p4 { get { return 1; } set { } }
+ public int p5 { get { return 1; } set { } }
+ public int p6 { get { return 1; } set { } }
+ public int p7 { get { return 1; } set { } }
+ public int p8 { get { return 1; } set { } }
+ public int p9 { get { return 1; } set { } }
+ public int p10 { get { return 1; } set { } }
+ public int p11 { get { return 1; } set { } }
+ public int p12 { get { return 1; } set { } }
+ public int p13 { get { return 1; } set { } }
+ public int p14 { get { return 1; } set { } }
+ public int p15 { get { return 1; } set { } }
+ public int p16 { get { return 1; } set { } }
+ public int p17 { get { return 1; } set { } }
+ public int p18 { get { return 1; } set { } }
+ public int p19 { get { return 1; } set { } }
+ public int p20 { get { return 1; } set { } }
+ public int p21 { get { return 1; } set { } }
+ public int p22 { get { return 1; } set { } }
+ public int p23 { get { return 1; } set { } }
+ public int p24 { get { return 1; } set { } }
+
+ public event d e0;
+ static public event d e1;
+ public event d e2;
+ public event d e3;
+ public event d e4;
+ public event d e5;
+ public event d e6;
+ public event d e7;
+ public event d e8;
+ public event d e9;
+ public event d e10;
+ public event d e11;
+ public event d e12;
+ public event d e13;
+ public event d e14;
+ public event d e15;
+ public event d e16;
+ public event d e17;
+ public event d e18;
+ public event d e19;
+ public event d e20;
+ public event d e21;
+ public event d e22;
+ public event d e23;
+ public event d e24;
+
+ public void NoWarning()
+ {
+ e0 += new d(m1);
+ e1 += new d(m1);
+ e2 += new d(m1);
+ e3 += new d(m1);
+ e4 += new d(m1);
+ e5 += new d(m1);
+ e6 += new d(m1);
+ e7 += new d(m1);
+ e8 += new d(m1);
+ e9 += new d(m1);
+ e10 += new d(m1);
+ e11 += new d(m1);
+ e12 += new d(m1);
+ e13 += new d(m1);
+ e14 += new d(m1);
+ e15 += new d(m1);
+ e16 += new d(m1);
+ e17 += new d(m1);
+ e18 += new d(m1);
+ e19 += new d(m1);
+ e20 += new d(m1);
+ e21 += new d(m1);
+ e22 += new d(m1);
+ e23 += new d(m1);
+ e24 += new d(m1);
+ }
}
-}
-public class Class5
-{
- public Class5() { }
- public Class5(int i) { }
- public Class5(int i, int ii) { }
-
- public int f0 = 0;
- static public int f1 = 0;
- public int f2 = 0;
- public int f3 = 0;
- public int f4 = 0;
- public int f5 = 0;
- public int f6 = 0;
- public int f7 = 0;
- public int f8 = 0;
- public int f9 = 0;
- public int f10 = 0;
- public int f11 = 0;
- public int f12 = 0;
- public int f13 = 0;
- public int f14 = 0;
- public int f15 = 0;
- public int f16 = 0;
- public int f17 = 0;
- public int f18 = 0;
- public int f19 = 0;
- public int f20 = 0;
- public int f21 = 0;
- public int f22 = 0;
- public int f23 = 0;
- public int f24 = 0;
-
- public void m1() { }
- static public void m2() { }
- public void m3() { }
- public void m4() { }
- public void m5() { }
- public void m6() { }
- public void m7() { }
- public void m8() { }
- public void m9() { }
- public void m10() { }
- public void m11() { }
- public void m12() { }
- public void m13() { }
- public void m14() { }
- public void m15() { }
- public void m16() { }
- public void m17() { }
- public void m18() { }
- public void m19() { }
- public void m20() { }
- public void m21() { }
- public void m22() { }
- public void m23() { }
- public void m24() { }
-
- public int p0 { get { return 1; } set { } }
- static public int p1 { get { return 1; } set { } }
- public int p2 { get { return 1; } set { } }
- public int p3 { get { return 1; } set { } }
- public int p4 { get { return 1; } set { } }
- public int p5 { get { return 1; } set { } }
- public int p6 { get { return 1; } set { } }
- public int p7 { get { return 1; } set { } }
- public int p8 { get { return 1; } set { } }
- public int p9 { get { return 1; } set { } }
- public int p10 { get { return 1; } set { } }
- public int p11 { get { return 1; } set { } }
- public int p12 { get { return 1; } set { } }
- public int p13 { get { return 1; } set { } }
- public int p14 { get { return 1; } set { } }
- public int p15 { get { return 1; } set { } }
- public int p16 { get { return 1; } set { } }
- public int p17 { get { return 1; } set { } }
- public int p18 { get { return 1; } set { } }
- public int p19 { get { return 1; } set { } }
- public int p20 { get { return 1; } set { } }
- public int p21 { get { return 1; } set { } }
- public int p22 { get { return 1; } set { } }
- public int p23 { get { return 1; } set { } }
- public int p24 { get { return 1; } set { } }
-
- public event d e0;
- static public event d e1;
- public event d e2;
- public event d e3;
- public event d e4;
- public event d e5;
- public event d e6;
- public event d e7;
- public event d e8;
- public event d e9;
- public event d e10;
- public event d e11;
- public event d e12;
- public event d e13;
- public event d e14;
- public event d e15;
- public event d e16;
- public event d e17;
- public event d e18;
- public event d e19;
- public event d e20;
- public event d e21;
- public event d e22;
- public event d e23;
- public event d e24;
-
- public void NoWarning()
+ public class Class5
{
- e0 += new d(m1);
- e1 += new d(m1);
- e2 += new d(m1);
- e3 += new d(m1);
- e4 += new d(m1);
- e5 += new d(m1);
- e6 += new d(m1);
- e7 += new d(m1);
- e8 += new d(m1);
- e9 += new d(m1);
- e10 += new d(m1);
- e11 += new d(m1);
- e12 += new d(m1);
- e13 += new d(m1);
- e14 += new d(m1);
- e15 += new d(m1);
- e16 += new d(m1);
- e17 += new d(m1);
- e18 += new d(m1);
- e19 += new d(m1);
- e20 += new d(m1);
- e21 += new d(m1);
- e22 += new d(m1);
- e23 += new d(m1);
- e24 += new d(m1);
+ public Class5() { }
+ public Class5(int i) { }
+ public Class5(int i, int ii) { }
+
+ public int f0 = 0;
+ static public int f1 = 0;
+ public int f2 = 0;
+ public int f3 = 0;
+ public int f4 = 0;
+ public int f5 = 0;
+ public int f6 = 0;
+ public int f7 = 0;
+ public int f8 = 0;
+ public int f9 = 0;
+ public int f10 = 0;
+ public int f11 = 0;
+ public int f12 = 0;
+ public int f13 = 0;
+ public int f14 = 0;
+ public int f15 = 0;
+ public int f16 = 0;
+ public int f17 = 0;
+ public int f18 = 0;
+ public int f19 = 0;
+ public int f20 = 0;
+ public int f21 = 0;
+ public int f22 = 0;
+ public int f23 = 0;
+ public int f24 = 0;
+
+ public void m1() { }
+ static public void m2() { }
+ public void m3() { }
+ public void m4() { }
+ public void m5() { }
+ public void m6() { }
+ public void m7() { }
+ public void m8() { }
+ public void m9() { }
+ public void m10() { }
+ public void m11() { }
+ public void m12() { }
+ public void m13() { }
+ public void m14() { }
+ public void m15() { }
+ public void m16() { }
+ public void m17() { }
+ public void m18() { }
+ public void m19() { }
+ public void m20() { }
+ public void m21() { }
+ public void m22() { }
+ public void m23() { }
+ public void m24() { }
+
+ public int p0 { get { return 1; } set { } }
+ static public int p1 { get { return 1; } set { } }
+ public int p2 { get { return 1; } set { } }
+ public int p3 { get { return 1; } set { } }
+ public int p4 { get { return 1; } set { } }
+ public int p5 { get { return 1; } set { } }
+ public int p6 { get { return 1; } set { } }
+ public int p7 { get { return 1; } set { } }
+ public int p8 { get { return 1; } set { } }
+ public int p9 { get { return 1; } set { } }
+ public int p10 { get { return 1; } set { } }
+ public int p11 { get { return 1; } set { } }
+ public int p12 { get { return 1; } set { } }
+ public int p13 { get { return 1; } set { } }
+ public int p14 { get { return 1; } set { } }
+ public int p15 { get { return 1; } set { } }
+ public int p16 { get { return 1; } set { } }
+ public int p17 { get { return 1; } set { } }
+ public int p18 { get { return 1; } set { } }
+ public int p19 { get { return 1; } set { } }
+ public int p20 { get { return 1; } set { } }
+ public int p21 { get { return 1; } set { } }
+ public int p22 { get { return 1; } set { } }
+ public int p23 { get { return 1; } set { } }
+ public int p24 { get { return 1; } set { } }
+
+ public event d e0;
+ static public event d e1;
+ public event d e2;
+ public event d e3;
+ public event d e4;
+ public event d e5;
+ public event d e6;
+ public event d e7;
+ public event d e8;
+ public event d e9;
+ public event d e10;
+ public event d e11;
+ public event d e12;
+ public event d e13;
+ public event d e14;
+ public event d e15;
+ public event d e16;
+ public event d e17;
+ public event d e18;
+ public event d e19;
+ public event d e20;
+ public event d e21;
+ public event d e22;
+ public event d e23;
+ public event d e24;
+
+ public void NoWarning()
+ {
+ e0 += new d(m1);
+ e1 += new d(m1);
+ e2 += new d(m1);
+ e3 += new d(m1);
+ e4 += new d(m1);
+ e5 += new d(m1);
+ e6 += new d(m1);
+ e7 += new d(m1);
+ e8 += new d(m1);
+ e9 += new d(m1);
+ e10 += new d(m1);
+ e11 += new d(m1);
+ e12 += new d(m1);
+ e13 += new d(m1);
+ e14 += new d(m1);
+ e15 += new d(m1);
+ e16 += new d(m1);
+ e17 += new d(m1);
+ e18 += new d(m1);
+ e19 += new d(m1);
+ e20 += new d(m1);
+ e21 += new d(m1);
+ e22 += new d(m1);
+ e23 += new d(m1);
+ e24 += new d(m1);
+ }
}
-}
-public class Class6
-{
- public Class6() { }
- public Class6(int i) { }
- public Class6(int i, int ii) { }
-
- public int f0 = 0;
- static public int f1 = 0;
- public int f2 = 0;
- public int f3 = 0;
- public int f4 = 0;
- public int f5 = 0;
- public int f6 = 0;
- public int f7 = 0;
- public int f8 = 0;
- public int f9 = 0;
- public int f10 = 0;
- public int f11 = 0;
- public int f12 = 0;
- public int f13 = 0;
- public int f14 = 0;
- public int f15 = 0;
- public int f16 = 0;
- public int f17 = 0;
- public int f18 = 0;
- public int f19 = 0;
- public int f20 = 0;
- public int f21 = 0;
- public int f22 = 0;
- public int f23 = 0;
- public int f24 = 0;
-
- public void m1() { }
- static public void m2() { }
- public void m3() { }
- public void m4() { }
- public void m5() { }
- public void m6() { }
- public void m7() { }
- public void m8() { }
- public void m9() { }
- public void m10() { }
- public void m11() { }
- public void m12() { }
- public void m13() { }
- public void m14() { }
- public void m15() { }
- public void m16() { }
- public void m17() { }
- public void m18() { }
- public void m19() { }
- public void m20() { }
- public void m21() { }
- public void m22() { }
- public void m23() { }
- public void m24() { }
-
- public int p0 { get { return 1; } set { } }
- static public int p1 { get { return 1; } set { } }
- public int p2 { get { return 1; } set { } }
- public int p3 { get { return 1; } set { } }
- public int p4 { get { return 1; } set { } }
- public int p5 { get { return 1; } set { } }
- public int p6 { get { return 1; } set { } }
- public int p7 { get { return 1; } set { } }
- public int p8 { get { return 1; } set { } }
- public int p9 { get { return 1; } set { } }
- public int p10 { get { return 1; } set { } }
- public int p11 { get { return 1; } set { } }
- public int p12 { get { return 1; } set { } }
- public int p13 { get { return 1; } set { } }
- public int p14 { get { return 1; } set { } }
- public int p15 { get { return 1; } set { } }
- public int p16 { get { return 1; } set { } }
- public int p17 { get { return 1; } set { } }
- public int p18 { get { return 1; } set { } }
- public int p19 { get { return 1; } set { } }
- public int p20 { get { return 1; } set { } }
- public int p21 { get { return 1; } set { } }
- public int p22 { get { return 1; } set { } }
- public int p23 { get { return 1; } set { } }
- public int p24 { get { return 1; } set { } }
-
- public event d e0;
- static public event d e1;
- public event d e2;
- public event d e3;
- public event d e4;
- public event d e5;
- public event d e6;
- public event d e7;
- public event d e8;
- public event d e9;
- public event d e10;
- public event d e11;
- public event d e12;
- public event d e13;
- public event d e14;
- public event d e15;
- public event d e16;
- public event d e17;
- public event d e18;
- public event d e19;
- public event d e20;
- public event d e21;
- public event d e22;
- public event d e23;
- public event d e24;
-
- public void NoWarning()
+ public class Class6
{
- e0 += new d(m1);
- e1 += new d(m1);
- e2 += new d(m1);
- e3 += new d(m1);
- e4 += new d(m1);
- e5 += new d(m1);
- e6 += new d(m1);
- e7 += new d(m1);
- e8 += new d(m1);
- e9 += new d(m1);
- e10 += new d(m1);
- e11 += new d(m1);
- e12 += new d(m1);
- e13 += new d(m1);
- e14 += new d(m1);
- e15 += new d(m1);
- e16 += new d(m1);
- e17 += new d(m1);
- e18 += new d(m1);
- e19 += new d(m1);
- e20 += new d(m1);
- e21 += new d(m1);
- e22 += new d(m1);
- e23 += new d(m1);
- e24 += new d(m1);
+ public Class6() { }
+ public Class6(int i) { }
+ public Class6(int i, int ii) { }
+
+ public int f0 = 0;
+ static public int f1 = 0;
+ public int f2 = 0;
+ public int f3 = 0;
+ public int f4 = 0;
+ public int f5 = 0;
+ public int f6 = 0;
+ public int f7 = 0;
+ public int f8 = 0;
+ public int f9 = 0;
+ public int f10 = 0;
+ public int f11 = 0;
+ public int f12 = 0;
+ public int f13 = 0;
+ public int f14 = 0;
+ public int f15 = 0;
+ public int f16 = 0;
+ public int f17 = 0;
+ public int f18 = 0;
+ public int f19 = 0;
+ public int f20 = 0;
+ public int f21 = 0;
+ public int f22 = 0;
+ public int f23 = 0;
+ public int f24 = 0;
+
+ public void m1() { }
+ static public void m2() { }
+ public void m3() { }
+ public void m4() { }
+ public void m5() { }
+ public void m6() { }
+ public void m7() { }
+ public void m8() { }
+ public void m9() { }
+ public void m10() { }
+ public void m11() { }
+ public void m12() { }
+ public void m13() { }
+ public void m14() { }
+ public void m15() { }
+ public void m16() { }
+ public void m17() { }
+ public void m18() { }
+ public void m19() { }
+ public void m20() { }
+ public void m21() { }
+ public void m22() { }
+ public void m23() { }
+ public void m24() { }
+
+ public int p0 { get { return 1; } set { } }
+ static public int p1 { get { return 1; } set { } }
+ public int p2 { get { return 1; } set { } }
+ public int p3 { get { return 1; } set { } }
+ public int p4 { get { return 1; } set { } }
+ public int p5 { get { return 1; } set { } }
+ public int p6 { get { return 1; } set { } }
+ public int p7 { get { return 1; } set { } }
+ public int p8 { get { return 1; } set { } }
+ public int p9 { get { return 1; } set { } }
+ public int p10 { get { return 1; } set { } }
+ public int p11 { get { return 1; } set { } }
+ public int p12 { get { return 1; } set { } }
+ public int p13 { get { return 1; } set { } }
+ public int p14 { get { return 1; } set { } }
+ public int p15 { get { return 1; } set { } }
+ public int p16 { get { return 1; } set { } }
+ public int p17 { get { return 1; } set { } }
+ public int p18 { get { return 1; } set { } }
+ public int p19 { get { return 1; } set { } }
+ public int p20 { get { return 1; } set { } }
+ public int p21 { get { return 1; } set { } }
+ public int p22 { get { return 1; } set { } }
+ public int p23 { get { return 1; } set { } }
+ public int p24 { get { return 1; } set { } }
+
+ public event d e0;
+ static public event d e1;
+ public event d e2;
+ public event d e3;
+ public event d e4;
+ public event d e5;
+ public event d e6;
+ public event d e7;
+ public event d e8;
+ public event d e9;
+ public event d e10;
+ public event d e11;
+ public event d e12;
+ public event d e13;
+ public event d e14;
+ public event d e15;
+ public event d e16;
+ public event d e17;
+ public event d e18;
+ public event d e19;
+ public event d e20;
+ public event d e21;
+ public event d e22;
+ public event d e23;
+ public event d e24;
+
+ public void NoWarning()
+ {
+ e0 += new d(m1);
+ e1 += new d(m1);
+ e2 += new d(m1);
+ e3 += new d(m1);
+ e4 += new d(m1);
+ e5 += new d(m1);
+ e6 += new d(m1);
+ e7 += new d(m1);
+ e8 += new d(m1);
+ e9 += new d(m1);
+ e10 += new d(m1);
+ e11 += new d(m1);
+ e12 += new d(m1);
+ e13 += new d(m1);
+ e14 += new d(m1);
+ e15 += new d(m1);
+ e16 += new d(m1);
+ e17 += new d(m1);
+ e18 += new d(m1);
+ e19 += new d(m1);
+ e20 += new d(m1);
+ e21 += new d(m1);
+ e22 += new d(m1);
+ e23 += new d(m1);
+ e24 += new d(m1);
+ }
}
-}
-public class Class7
-{
- public Class7() { }
- public Class7(int i) { }
- public Class7(int i, int ii) { }
-
- public int f0 = 0;
- static public int f1 = 0;
- public int f2 = 0;
- public int f3 = 0;
- public int f4 = 0;
- public int f5 = 0;
- public int f6 = 0;
- public int f7 = 0;
- public int f8 = 0;
- public int f9 = 0;
- public int f10 = 0;
- public int f11 = 0;
- public int f12 = 0;
- public int f13 = 0;
- public int f14 = 0;
- public int f15 = 0;
- public int f16 = 0;
- public int f17 = 0;
- public int f18 = 0;
- public int f19 = 0;
- public int f20 = 0;
- public int f21 = 0;
- public int f22 = 0;
- public int f23 = 0;
- public int f24 = 0;
-
- public void m1() { }
- static public void m2() { }
- public void m3() { }
- public void m4() { }
- public void m5() { }
- public void m6() { }
- public void m7() { }
- public void m8() { }
- public void m9() { }
- public void m10() { }
- public void m11() { }
- public void m12() { }
- public void m13() { }
- public void m14() { }
- public void m15() { }
- public void m16() { }
- public void m17() { }
- public void m18() { }
- public void m19() { }
- public void m20() { }
- public void m21() { }
- public void m22() { }
- public void m23() { }
- public void m24() { }
-
- public int p0 { get { return 1; } set { } }
- static public int p1 { get { return 1; } set { } }
- public int p2 { get { return 1; } set { } }
- public int p3 { get { return 1; } set { } }
- public int p4 { get { return 1; } set { } }
- public int p5 { get { return 1; } set { } }
- public int p6 { get { return 1; } set { } }
- public int p7 { get { return 1; } set { } }
- public int p8 { get { return 1; } set { } }
- public int p9 { get { return 1; } set { } }
- public int p10 { get { return 1; } set { } }
- public int p11 { get { return 1; } set { } }
- public int p12 { get { return 1; } set { } }
- public int p13 { get { return 1; } set { } }
- public int p14 { get { return 1; } set { } }
- public int p15 { get { return 1; } set { } }
- public int p16 { get { return 1; } set { } }
- public int p17 { get { return 1; } set { } }
- public int p18 { get { return 1; } set { } }
- public int p19 { get { return 1; } set { } }
- public int p20 { get { return 1; } set { } }
- public int p21 { get { return 1; } set { } }
- public int p22 { get { return 1; } set { } }
- public int p23 { get { return 1; } set { } }
- public int p24 { get { return 1; } set { } }
-
- public event d e0;
- static public event d e1;
- public event d e2;
- public event d e3;
- public event d e4;
- public event d e5;
- public event d e6;
- public event d e7;
- public event d e8;
- public event d e9;
- public event d e10;
- public event d e11;
- public event d e12;
- public event d e13;
- public event d e14;
- public event d e15;
- public event d e16;
- public event d e17;
- public event d e18;
- public event d e19;
- public event d e20;
- public event d e21;
- public event d e22;
- public event d e23;
- public event d e24;
-
- public void NoWarning()
+ public class Class7
{
- e0 += new d(m1);
- e1 += new d(m1);
- e2 += new d(m1);
- e3 += new d(m1);
- e4 += new d(m1);
- e5 += new d(m1);
- e6 += new d(m1);
- e7 += new d(m1);
- e8 += new d(m1);
- e9 += new d(m1);
- e10 += new d(m1);
- e11 += new d(m1);
- e12 += new d(m1);
- e13 += new d(m1);
- e14 += new d(m1);
- e15 += new d(m1);
- e16 += new d(m1);
- e17 += new d(m1);
- e18 += new d(m1);
- e19 += new d(m1);
- e20 += new d(m1);
- e21 += new d(m1);
- e22 += new d(m1);
- e23 += new d(m1);
- e24 += new d(m1);
+ public Class7() { }
+ public Class7(int i) { }
+ public Class7(int i, int ii) { }
+
+ public int f0 = 0;
+ static public int f1 = 0;
+ public int f2 = 0;
+ public int f3 = 0;
+ public int f4 = 0;
+ public int f5 = 0;
+ public int f6 = 0;
+ public int f7 = 0;
+ public int f8 = 0;
+ public int f9 = 0;
+ public int f10 = 0;
+ public int f11 = 0;
+ public int f12 = 0;
+ public int f13 = 0;
+ public int f14 = 0;
+ public int f15 = 0;
+ public int f16 = 0;
+ public int f17 = 0;
+ public int f18 = 0;
+ public int f19 = 0;
+ public int f20 = 0;
+ public int f21 = 0;
+ public int f22 = 0;
+ public int f23 = 0;
+ public int f24 = 0;
+
+ public void m1() { }
+ static public void m2() { }
+ public void m3() { }
+ public void m4() { }
+ public void m5() { }
+ public void m6() { }
+ public void m7() { }
+ public void m8() { }
+ public void m9() { }
+ public void m10() { }
+ public void m11() { }
+ public void m12() { }
+ public void m13() { }
+ public void m14() { }
+ public void m15() { }
+ public void m16() { }
+ public void m17() { }
+ public void m18() { }
+ public void m19() { }
+ public void m20() { }
+ public void m21() { }
+ public void m22() { }
+ public void m23() { }
+ public void m24() { }
+
+ public int p0 { get { return 1; } set { } }
+ static public int p1 { get { return 1; } set { } }
+ public int p2 { get { return 1; } set { } }
+ public int p3 { get { return 1; } set { } }
+ public int p4 { get { return 1; } set { } }
+ public int p5 { get { return 1; } set { } }
+ public int p6 { get { return 1; } set { } }
+ public int p7 { get { return 1; } set { } }
+ public int p8 { get { return 1; } set { } }
+ public int p9 { get { return 1; } set { } }
+ public int p10 { get { return 1; } set { } }
+ public int p11 { get { return 1; } set { } }
+ public int p12 { get { return 1; } set { } }
+ public int p13 { get { return 1; } set { } }
+ public int p14 { get { return 1; } set { } }
+ public int p15 { get { return 1; } set { } }
+ public int p16 { get { return 1; } set { } }
+ public int p17 { get { return 1; } set { } }
+ public int p18 { get { return 1; } set { } }
+ public int p19 { get { return 1; } set { } }
+ public int p20 { get { return 1; } set { } }
+ public int p21 { get { return 1; } set { } }
+ public int p22 { get { return 1; } set { } }
+ public int p23 { get { return 1; } set { } }
+ public int p24 { get { return 1; } set { } }
+
+ public event d e0;
+ static public event d e1;
+ public event d e2;
+ public event d e3;
+ public event d e4;
+ public event d e5;
+ public event d e6;
+ public event d e7;
+ public event d e8;
+ public event d e9;
+ public event d e10;
+ public event d e11;
+ public event d e12;
+ public event d e13;
+ public event d e14;
+ public event d e15;
+ public event d e16;
+ public event d e17;
+ public event d e18;
+ public event d e19;
+ public event d e20;
+ public event d e21;
+ public event d e22;
+ public event d e23;
+ public event d e24;
+
+ public void NoWarning()
+ {
+ e0 += new d(m1);
+ e1 += new d(m1);
+ e2 += new d(m1);
+ e3 += new d(m1);
+ e4 += new d(m1);
+ e5 += new d(m1);
+ e6 += new d(m1);
+ e7 += new d(m1);
+ e8 += new d(m1);
+ e9 += new d(m1);
+ e10 += new d(m1);
+ e11 += new d(m1);
+ e12 += new d(m1);
+ e13 += new d(m1);
+ e14 += new d(m1);
+ e15 += new d(m1);
+ e16 += new d(m1);
+ e17 += new d(m1);
+ e18 += new d(m1);
+ e19 += new d(m1);
+ e20 += new d(m1);
+ e21 += new d(m1);
+ e22 += new d(m1);
+ e23 += new d(m1);
+ e24 += new d(m1);
+ }
}
-}
-public class Class8
-{
- public Class8() { }
- public Class8(int i) { }
- public Class8(int i, int ii) { }
-
- public int f0 = 0;
- static public int f1 = 0;
- public int f2 = 0;
- public int f3 = 0;
- public int f4 = 0;
- public int f5 = 0;
- public int f6 = 0;
- public int f7 = 0;
- public int f8 = 0;
- public int f9 = 0;
- public int f10 = 0;
- public int f11 = 0;
- public int f12 = 0;
- public int f13 = 0;
- public int f14 = 0;
- public int f15 = 0;
- public int f16 = 0;
- public int f17 = 0;
- public int f18 = 0;
- public int f19 = 0;
- public int f20 = 0;
- public int f21 = 0;
- public int f22 = 0;
- public int f23 = 0;
- public int f24 = 0;
-
- public void m1() { }
- static public void m2() { }
- public void m3() { }
- public void m4() { }
- public void m5() { }
- public void m6() { }
- public void m7() { }
- public void m8() { }
- public void m9() { }
- public void m10() { }
- public void m11() { }
- public void m12() { }
- public void m13() { }
- public void m14() { }
- public void m15() { }
- public void m16() { }
- public void m17() { }
- public void m18() { }
- public void m19() { }
- public void m20() { }
- public void m21() { }
- public void m22() { }
- public void m23() { }
- public void m24() { }
-
- public int p0 { get { return 1; } set { } }
- static public int p1 { get { return 1; } set { } }
- public int p2 { get { return 1; } set { } }
- public int p3 { get { return 1; } set { } }
- public int p4 { get { return 1; } set { } }
- public int p5 { get { return 1; } set { } }
- public int p6 { get { return 1; } set { } }
- public int p7 { get { return 1; } set { } }
- public int p8 { get { return 1; } set { } }
- public int p9 { get { return 1; } set { } }
- public int p10 { get { return 1; } set { } }
- public int p11 { get { return 1; } set { } }
- public int p12 { get { return 1; } set { } }
- public int p13 { get { return 1; } set { } }
- public int p14 { get { return 1; } set { } }
- public int p15 { get { return 1; } set { } }
- public int p16 { get { return 1; } set { } }
- public int p17 { get { return 1; } set { } }
- public int p18 { get { return 1; } set { } }
- public int p19 { get { return 1; } set { } }
- public int p20 { get { return 1; } set { } }
- public int p21 { get { return 1; } set { } }
- public int p22 { get { return 1; } set { } }
- public int p23 { get { return 1; } set { } }
- public int p24 { get { return 1; } set { } }
-
- public event d e0;
- static public event d e1;
- public event d e2;
- public event d e3;
- public event d e4;
- public event d e5;
- public event d e6;
- public event d e7;
- public event d e8;
- public event d e9;
- public event d e10;
- public event d e11;
- public event d e12;
- public event d e13;
- public event d e14;
- public event d e15;
- public event d e16;
- public event d e17;
- public event d e18;
- public event d e19;
- public event d e20;
- public event d e21;
- public event d e22;
- public event d e23;
- public event d e24;
-
- public void NoWarning()
+ public class Class8
{
- e0 += new d(m1);
- e1 += new d(m1);
- e2 += new d(m1);
- e3 += new d(m1);
- e4 += new d(m1);
- e5 += new d(m1);
- e6 += new d(m1);
- e7 += new d(m1);
- e8 += new d(m1);
- e9 += new d(m1);
- e10 += new d(m1);
- e11 += new d(m1);
- e12 += new d(m1);
- e13 += new d(m1);
- e14 += new d(m1);
- e15 += new d(m1);
- e16 += new d(m1);
- e17 += new d(m1);
- e18 += new d(m1);
- e19 += new d(m1);
- e20 += new d(m1);
- e21 += new d(m1);
- e22 += new d(m1);
- e23 += new d(m1);
- e24 += new d(m1);
+ public Class8() { }
+ public Class8(int i) { }
+ public Class8(int i, int ii) { }
+
+ public int f0 = 0;
+ static public int f1 = 0;
+ public int f2 = 0;
+ public int f3 = 0;
+ public int f4 = 0;
+ public int f5 = 0;
+ public int f6 = 0;
+ public int f7 = 0;
+ public int f8 = 0;
+ public int f9 = 0;
+ public int f10 = 0;
+ public int f11 = 0;
+ public int f12 = 0;
+ public int f13 = 0;
+ public int f14 = 0;
+ public int f15 = 0;
+ public int f16 = 0;
+ public int f17 = 0;
+ public int f18 = 0;
+ public int f19 = 0;
+ public int f20 = 0;
+ public int f21 = 0;
+ public int f22 = 0;
+ public int f23 = 0;
+ public int f24 = 0;
+
+ public void m1() { }
+ static public void m2() { }
+ public void m3() { }
+ public void m4() { }
+ public void m5() { }
+ public void m6() { }
+ public void m7() { }
+ public void m8() { }
+ public void m9() { }
+ public void m10() { }
+ public void m11() { }
+ public void m12() { }
+ public void m13() { }
+ public void m14() { }
+ public void m15() { }
+ public void m16() { }
+ public void m17() { }
+ public void m18() { }
+ public void m19() { }
+ public void m20() { }
+ public void m21() { }
+ public void m22() { }
+ public void m23() { }
+ public void m24() { }
+
+ public int p0 { get { return 1; } set { } }
+ static public int p1 { get { return 1; } set { } }
+ public int p2 { get { return 1; } set { } }
+ public int p3 { get { return 1; } set { } }
+ public int p4 { get { return 1; } set { } }
+ public int p5 { get { return 1; } set { } }
+ public int p6 { get { return 1; } set { } }
+ public int p7 { get { return 1; } set { } }
+ public int p8 { get { return 1; } set { } }
+ public int p9 { get { return 1; } set { } }
+ public int p10 { get { return 1; } set { } }
+ public int p11 { get { return 1; } set { } }
+ public int p12 { get { return 1; } set { } }
+ public int p13 { get { return 1; } set { } }
+ public int p14 { get { return 1; } set { } }
+ public int p15 { get { return 1; } set { } }
+ public int p16 { get { return 1; } set { } }
+ public int p17 { get { return 1; } set { } }
+ public int p18 { get { return 1; } set { } }
+ public int p19 { get { return 1; } set { } }
+ public int p20 { get { return 1; } set { } }
+ public int p21 { get { return 1; } set { } }
+ public int p22 { get { return 1; } set { } }
+ public int p23 { get { return 1; } set { } }
+ public int p24 { get { return 1; } set { } }
+
+ public event d e0;
+ static public event d e1;
+ public event d e2;
+ public event d e3;
+ public event d e4;
+ public event d e5;
+ public event d e6;
+ public event d e7;
+ public event d e8;
+ public event d e9;
+ public event d e10;
+ public event d e11;
+ public event d e12;
+ public event d e13;
+ public event d e14;
+ public event d e15;
+ public event d e16;
+ public event d e17;
+ public event d e18;
+ public event d e19;
+ public event d e20;
+ public event d e21;
+ public event d e22;
+ public event d e23;
+ public event d e24;
+
+ public void NoWarning()
+ {
+ e0 += new d(m1);
+ e1 += new d(m1);
+ e2 += new d(m1);
+ e3 += new d(m1);
+ e4 += new d(m1);
+ e5 += new d(m1);
+ e6 += new d(m1);
+ e7 += new d(m1);
+ e8 += new d(m1);
+ e9 += new d(m1);
+ e10 += new d(m1);
+ e11 += new d(m1);
+ e12 += new d(m1);
+ e13 += new d(m1);
+ e14 += new d(m1);
+ e15 += new d(m1);
+ e16 += new d(m1);
+ e17 += new d(m1);
+ e18 += new d(m1);
+ e19 += new d(m1);
+ e20 += new d(m1);
+ e21 += new d(m1);
+ e22 += new d(m1);
+ e23 += new d(m1);
+ e24 += new d(m1);
+ }
}
-}
-public class Class9
-{
- public Class9() { }
- public Class9(int i) { }
- public Class9(int i, int ii) { }
-
- public int f0 = 0;
- static public int f1 = 0;
- public int f2 = 0;
- public int f3 = 0;
- public int f4 = 0;
- public int f5 = 0;
- public int f6 = 0;
- public int f7 = 0;
- public int f8 = 0;
- public int f9 = 0;
- public int f10 = 0;
- public int f11 = 0;
- public int f12 = 0;
- public int f13 = 0;
- public int f14 = 0;
- public int f15 = 0;
- public int f16 = 0;
- public int f17 = 0;
- public int f18 = 0;
- public int f19 = 0;
- public int f20 = 0;
- public int f21 = 0;
- public int f22 = 0;
- public int f23 = 0;
- public int f24 = 0;
-
- public void m1() { }
- static public void m2() { }
- public void m3() { }
- public void m4() { }
- public void m5() { }
- public void m6() { }
- public void m7() { }
- public void m8() { }
- public void m9() { }
- public void m10() { }
- public void m11() { }
- public void m12() { }
- public void m13() { }
- public void m14() { }
- public void m15() { }
- public void m16() { }
- public void m17() { }
- public void m18() { }
- public void m19() { }
- public void m20() { }
- public void m21() { }
- public void m22() { }
- public void m23() { }
- public void m24() { }
-
- public int p0 { get { return 1; } set { } }
- static public int p1 { get { return 1; } set { } }
- public int p2 { get { return 1; } set { } }
- public int p3 { get { return 1; } set { } }
- public int p4 { get { return 1; } set { } }
- public int p5 { get { return 1; } set { } }
- public int p6 { get { return 1; } set { } }
- public int p7 { get { return 1; } set { } }
- public int p8 { get { return 1; } set { } }
- public int p9 { get { return 1; } set { } }
- public int p10 { get { return 1; } set { } }
- public int p11 { get { return 1; } set { } }
- public int p12 { get { return 1; } set { } }
- public int p13 { get { return 1; } set { } }
- public int p14 { get { return 1; } set { } }
- public int p15 { get { return 1; } set { } }
- public int p16 { get { return 1; } set { } }
- public int p17 { get { return 1; } set { } }
- public int p18 { get { return 1; } set { } }
- public int p19 { get { return 1; } set { } }
- public int p20 { get { return 1; } set { } }
- public int p21 { get { return 1; } set { } }
- public int p22 { get { return 1; } set { } }
- public int p23 { get { return 1; } set { } }
- public int p24 { get { return 1; } set { } }
-
- public event d e0;
- static public event d e1;
- public event d e2;
- public event d e3;
- public event d e4;
- public event d e5;
- public event d e6;
- public event d e7;
- public event d e8;
- public event d e9;
- public event d e10;
- public event d e11;
- public event d e12;
- public event d e13;
- public event d e14;
- public event d e15;
- public event d e16;
- public event d e17;
- public event d e18;
- public event d e19;
- public event d e20;
- public event d e21;
- public event d e22;
- public event d e23;
- public event d e24;
-
- public void NoWarning()
+ public class Class9
{
- e0 += new d(m1);
- e1 += new d(m1);
- e2 += new d(m1);
- e3 += new d(m1);
- e4 += new d(m1);
- e5 += new d(m1);
- e6 += new d(m1);
- e7 += new d(m1);
- e8 += new d(m1);
- e9 += new d(m1);
- e10 += new d(m1);
- e11 += new d(m1);
- e12 += new d(m1);
- e13 += new d(m1);
- e14 += new d(m1);
- e15 += new d(m1);
- e16 += new d(m1);
- e17 += new d(m1);
- e18 += new d(m1);
- e19 += new d(m1);
- e20 += new d(m1);
- e21 += new d(m1);
- e22 += new d(m1);
- e23 += new d(m1);
- e24 += new d(m1);
+ public Class9() { }
+ public Class9(int i) { }
+ public Class9(int i, int ii) { }
+
+ public int f0 = 0;
+ static public int f1 = 0;
+ public int f2 = 0;
+ public int f3 = 0;
+ public int f4 = 0;
+ public int f5 = 0;
+ public int f6 = 0;
+ public int f7 = 0;
+ public int f8 = 0;
+ public int f9 = 0;
+ public int f10 = 0;
+ public int f11 = 0;
+ public int f12 = 0;
+ public int f13 = 0;
+ public int f14 = 0;
+ public int f15 = 0;
+ public int f16 = 0;
+ public int f17 = 0;
+ public int f18 = 0;
+ public int f19 = 0;
+ public int f20 = 0;
+ public int f21 = 0;
+ public int f22 = 0;
+ public int f23 = 0;
+ public int f24 = 0;
+
+ public void m1() { }
+ static public void m2() { }
+ public void m3() { }
+ public void m4() { }
+ public void m5() { }
+ public void m6() { }
+ public void m7() { }
+ public void m8() { }
+ public void m9() { }
+ public void m10() { }
+ public void m11() { }
+ public void m12() { }
+ public void m13() { }
+ public void m14() { }
+ public void m15() { }
+ public void m16() { }
+ public void m17() { }
+ public void m18() { }
+ public void m19() { }
+ public void m20() { }
+ public void m21() { }
+ public void m22() { }
+ public void m23() { }
+ public void m24() { }
+
+ public int p0 { get { return 1; } set { } }
+ static public int p1 { get { return 1; } set { } }
+ public int p2 { get { return 1; } set { } }
+ public int p3 { get { return 1; } set { } }
+ public int p4 { get { return 1; } set { } }
+ public int p5 { get { return 1; } set { } }
+ public int p6 { get { return 1; } set { } }
+ public int p7 { get { return 1; } set { } }
+ public int p8 { get { return 1; } set { } }
+ public int p9 { get { return 1; } set { } }
+ public int p10 { get { return 1; } set { } }
+ public int p11 { get { return 1; } set { } }
+ public int p12 { get { return 1; } set { } }
+ public int p13 { get { return 1; } set { } }
+ public int p14 { get { return 1; } set { } }
+ public int p15 { get { return 1; } set { } }
+ public int p16 { get { return 1; } set { } }
+ public int p17 { get { return 1; } set { } }
+ public int p18 { get { return 1; } set { } }
+ public int p19 { get { return 1; } set { } }
+ public int p20 { get { return 1; } set { } }
+ public int p21 { get { return 1; } set { } }
+ public int p22 { get { return 1; } set { } }
+ public int p23 { get { return 1; } set { } }
+ public int p24 { get { return 1; } set { } }
+
+ public event d e0;
+ static public event d e1;
+ public event d e2;
+ public event d e3;
+ public event d e4;
+ public event d e5;
+ public event d e6;
+ public event d e7;
+ public event d e8;
+ public event d e9;
+ public event d e10;
+ public event d e11;
+ public event d e12;
+ public event d e13;
+ public event d e14;
+ public event d e15;
+ public event d e16;
+ public event d e17;
+ public event d e18;
+ public event d e19;
+ public event d e20;
+ public event d e21;
+ public event d e22;
+ public event d e23;
+ public event d e24;
+
+ public void NoWarning()
+ {
+ e0 += new d(m1);
+ e1 += new d(m1);
+ e2 += new d(m1);
+ e3 += new d(m1);
+ e4 += new d(m1);
+ e5 += new d(m1);
+ e6 += new d(m1);
+ e7 += new d(m1);
+ e8 += new d(m1);
+ e9 += new d(m1);
+ e10 += new d(m1);
+ e11 += new d(m1);
+ e12 += new d(m1);
+ e13 += new d(m1);
+ e14 += new d(m1);
+ e15 += new d(m1);
+ e16 += new d(m1);
+ e17 += new d(m1);
+ e18 += new d(m1);
+ e19 += new d(m1);
+ e20 += new d(m1);
+ e21 += new d(m1);
+ e22 += new d(m1);
+ e23 += new d(m1);
+ e24 += new d(m1);
+ }
}
-}
-public class Class10
-{
- public Class10() { }
- public Class10(int i) { }
- public Class10(int i, int ii) { }
-
- public int f0 = 0;
- static public int f1 = 0;
- public int f2 = 0;
- public int f3 = 0;
- public int f4 = 0;
- public int f5 = 0;
- public int f6 = 0;
- public int f7 = 0;
- public int f8 = 0;
- public int f9 = 0;
- public int f10 = 0;
- public int f11 = 0;
- public int f12 = 0;
- public int f13 = 0;
- public int f14 = 0;
- public int f15 = 0;
- public int f16 = 0;
- public int f17 = 0;
- public int f18 = 0;
- public int f19 = 0;
- public int f20 = 0;
- public int f21 = 0;
- public int f22 = 0;
- public int f23 = 0;
- public int f24 = 0;
-
- public void m1() { }
- static public void m2() { }
- public void m3() { }
- public void m4() { }
- public void m5() { }
- public void m6() { }
- public void m7() { }
- public void m8() { }
- public void m9() { }
- public void m10() { }
- public void m11() { }
- public void m12() { }
- public void m13() { }
- public void m14() { }
- public void m15() { }
- public void m16() { }
- public void m17() { }
- public void m18() { }
- public void m19() { }
- public void m20() { }
- public void m21() { }
- public void m22() { }
- public void m23() { }
- public void m24() { }
-
- public int p0 { get { return 1; } set { } }
- static public int p1 { get { return 1; } set { } }
- public int p2 { get { return 1; } set { } }
- public int p3 { get { return 1; } set { } }
- public int p4 { get { return 1; } set { } }
- public int p5 { get { return 1; } set { } }
- public int p6 { get { return 1; } set { } }
- public int p7 { get { return 1; } set { } }
- public int p8 { get { return 1; } set { } }
- public int p9 { get { return 1; } set { } }
- public int p10 { get { return 1; } set { } }
- public int p11 { get { return 1; } set { } }
- public int p12 { get { return 1; } set { } }
- public int p13 { get { return 1; } set { } }
- public int p14 { get { return 1; } set { } }
- public int p15 { get { return 1; } set { } }
- public int p16 { get { return 1; } set { } }
- public int p17 { get { return 1; } set { } }
- public int p18 { get { return 1; } set { } }
- public int p19 { get { return 1; } set { } }
- public int p20 { get { return 1; } set { } }
- public int p21 { get { return 1; } set { } }
- public int p22 { get { return 1; } set { } }
- public int p23 { get { return 1; } set { } }
- public int p24 { get { return 1; } set { } }
-
- public event d e0;
- static public event d e1;
- public event d e2;
- public event d e3;
- public event d e4;
- public event d e5;
- public event d e6;
- public event d e7;
- public event d e8;
- public event d e9;
- public event d e10;
- public event d e11;
- public event d e12;
- public event d e13;
- public event d e14;
- public event d e15;
- public event d e16;
- public event d e17;
- public event d e18;
- public event d e19;
- public event d e20;
- public event d e21;
- public event d e22;
- public event d e23;
- public event d e24;
-
- public void NoWarning()
+ public class Class10
{
- e0 += new d(m1);
- e1 += new d(m1);
- e2 += new d(m1);
- e3 += new d(m1);
- e4 += new d(m1);
- e5 += new d(m1);
- e6 += new d(m1);
- e7 += new d(m1);
- e8 += new d(m1);
- e9 += new d(m1);
- e10 += new d(m1);
- e11 += new d(m1);
- e12 += new d(m1);
- e13 += new d(m1);
- e14 += new d(m1);
- e15 += new d(m1);
- e16 += new d(m1);
- e17 += new d(m1);
- e18 += new d(m1);
- e19 += new d(m1);
- e20 += new d(m1);
- e21 += new d(m1);
- e22 += new d(m1);
- e23 += new d(m1);
- e24 += new d(m1);
+ public Class10() { }
+ public Class10(int i) { }
+ public Class10(int i, int ii) { }
+
+ public int f0 = 0;
+ static public int f1 = 0;
+ public int f2 = 0;
+ public int f3 = 0;
+ public int f4 = 0;
+ public int f5 = 0;
+ public int f6 = 0;
+ public int f7 = 0;
+ public int f8 = 0;
+ public int f9 = 0;
+ public int f10 = 0;
+ public int f11 = 0;
+ public int f12 = 0;
+ public int f13 = 0;
+ public int f14 = 0;
+ public int f15 = 0;
+ public int f16 = 0;
+ public int f17 = 0;
+ public int f18 = 0;
+ public int f19 = 0;
+ public int f20 = 0;
+ public int f21 = 0;
+ public int f22 = 0;
+ public int f23 = 0;
+ public int f24 = 0;
+
+ public void m1() { }
+ static public void m2() { }
+ public void m3() { }
+ public void m4() { }
+ public void m5() { }
+ public void m6() { }
+ public void m7() { }
+ public void m8() { }
+ public void m9() { }
+ public void m10() { }
+ public void m11() { }
+ public void m12() { }
+ public void m13() { }
+ public void m14() { }
+ public void m15() { }
+ public void m16() { }
+ public void m17() { }
+ public void m18() { }
+ public void m19() { }
+ public void m20() { }
+ public void m21() { }
+ public void m22() { }
+ public void m23() { }
+ public void m24() { }
+
+ public int p0 { get { return 1; } set { } }
+ static public int p1 { get { return 1; } set { } }
+ public int p2 { get { return 1; } set { } }
+ public int p3 { get { return 1; } set { } }
+ public int p4 { get { return 1; } set { } }
+ public int p5 { get { return 1; } set { } }
+ public int p6 { get { return 1; } set { } }
+ public int p7 { get { return 1; } set { } }
+ public int p8 { get { return 1; } set { } }
+ public int p9 { get { return 1; } set { } }
+ public int p10 { get { return 1; } set { } }
+ public int p11 { get { return 1; } set { } }
+ public int p12 { get { return 1; } set { } }
+ public int p13 { get { return 1; } set { } }
+ public int p14 { get { return 1; } set { } }
+ public int p15 { get { return 1; } set { } }
+ public int p16 { get { return 1; } set { } }
+ public int p17 { get { return 1; } set { } }
+ public int p18 { get { return 1; } set { } }
+ public int p19 { get { return 1; } set { } }
+ public int p20 { get { return 1; } set { } }
+ public int p21 { get { return 1; } set { } }
+ public int p22 { get { return 1; } set { } }
+ public int p23 { get { return 1; } set { } }
+ public int p24 { get { return 1; } set { } }
+
+ public event d e0;
+ static public event d e1;
+ public event d e2;
+ public event d e3;
+ public event d e4;
+ public event d e5;
+ public event d e6;
+ public event d e7;
+ public event d e8;
+ public event d e9;
+ public event d e10;
+ public event d e11;
+ public event d e12;
+ public event d e13;
+ public event d e14;
+ public event d e15;
+ public event d e16;
+ public event d e17;
+ public event d e18;
+ public event d e19;
+ public event d e20;
+ public event d e21;
+ public event d e22;
+ public event d e23;
+ public event d e24;
+
+ public void NoWarning()
+ {
+ e0 += new d(m1);
+ e1 += new d(m1);
+ e2 += new d(m1);
+ e3 += new d(m1);
+ e4 += new d(m1);
+ e5 += new d(m1);
+ e6 += new d(m1);
+ e7 += new d(m1);
+ e8 += new d(m1);
+ e9 += new d(m1);
+ e10 += new d(m1);
+ e11 += new d(m1);
+ e12 += new d(m1);
+ e13 += new d(m1);
+ e14 += new d(m1);
+ e15 += new d(m1);
+ e16 += new d(m1);
+ e17 += new d(m1);
+ e18 += new d(m1);
+ e19 += new d(m1);
+ e20 += new d(m1);
+ e21 += new d(m1);
+ e22 += new d(m1);
+ e23 += new d(m1);
+ e24 += new d(m1);
+ }
}
-}
-public class Class11
-{
- public Class11() { }
- public Class11(int i) { }
- public Class11(int i, int ii) { }
-
- public int f0 = 0;
- static public int f1 = 0;
- public int f2 = 0;
- public int f3 = 0;
- public int f4 = 0;
- public int f5 = 0;
- public int f6 = 0;
- public int f7 = 0;
- public int f8 = 0;
- public int f9 = 0;
- public int f10 = 0;
- public int f11 = 0;
- public int f12 = 0;
- public int f13 = 0;
- public int f14 = 0;
- public int f15 = 0;
- public int f16 = 0;
- public int f17 = 0;
- public int f18 = 0;
- public int f19 = 0;
- public int f20 = 0;
- public int f21 = 0;
- public int f22 = 0;
- public int f23 = 0;
- public int f24 = 0;
-
- public void m1() { }
- static public void m2() { }
- public void m3() { }
- public void m4() { }
- public void m5() { }
- public void m6() { }
- public void m7() { }
- public void m8() { }
- public void m9() { }
- public void m10() { }
- public void m11() { }
- public void m12() { }
- public void m13() { }
- public void m14() { }
- public void m15() { }
- public void m16() { }
- public void m17() { }
- public void m18() { }
- public void m19() { }
- public void m20() { }
- public void m21() { }
- public void m22() { }
- public void m23() { }
- public void m24() { }
-
- public int p0 { get { return 1; } set { } }
- static public int p1 { get { return 1; } set { } }
- public int p2 { get { return 1; } set { } }
- public int p3 { get { return 1; } set { } }
- public int p4 { get { return 1; } set { } }
- public int p5 { get { return 1; } set { } }
- public int p6 { get { return 1; } set { } }
- public int p7 { get { return 1; } set { } }
- public int p8 { get { return 1; } set { } }
- public int p9 { get { return 1; } set { } }
- public int p10 { get { return 1; } set { } }
- public int p11 { get { return 1; } set { } }
- public int p12 { get { return 1; } set { } }
- public int p13 { get { return 1; } set { } }
- public int p14 { get { return 1; } set { } }
- public int p15 { get { return 1; } set { } }
- public int p16 { get { return 1; } set { } }
- public int p17 { get { return 1; } set { } }
- public int p18 { get { return 1; } set { } }
- public int p19 { get { return 1; } set { } }
- public int p20 { get { return 1; } set { } }
- public int p21 { get { return 1; } set { } }
- public int p22 { get { return 1; } set { } }
- public int p23 { get { return 1; } set { } }
- public int p24 { get { return 1; } set { } }
-
- public event d e0;
- static public event d e1;
- public event d e2;
- public event d e3;
- public event d e4;
- public event d e5;
- public event d e6;
- public event d e7;
- public event d e8;
- public event d e9;
- public event d e10;
- public event d e11;
- public event d e12;
- public event d e13;
- public event d e14;
- public event d e15;
- public event d e16;
- public event d e17;
- public event d e18;
- public event d e19;
- public event d e20;
- public event d e21;
- public event d e22;
- public event d e23;
- public event d e24;
-
- public void NoWarning()
+ public class Class11
{
- e0 += new d(m1);
- e1 += new d(m1);
- e2 += new d(m1);
- e3 += new d(m1);
- e4 += new d(m1);
- e5 += new d(m1);
- e6 += new d(m1);
- e7 += new d(m1);
- e8 += new d(m1);
- e9 += new d(m1);
- e10 += new d(m1);
- e11 += new d(m1);
- e12 += new d(m1);
- e13 += new d(m1);
- e14 += new d(m1);
- e15 += new d(m1);
- e16 += new d(m1);
- e17 += new d(m1);
- e18 += new d(m1);
- e19 += new d(m1);
- e20 += new d(m1);
- e21 += new d(m1);
- e22 += new d(m1);
- e23 += new d(m1);
- e24 += new d(m1);
+ public Class11() { }
+ public Class11(int i) { }
+ public Class11(int i, int ii) { }
+
+ public int f0 = 0;
+ static public int f1 = 0;
+ public int f2 = 0;
+ public int f3 = 0;
+ public int f4 = 0;
+ public int f5 = 0;
+ public int f6 = 0;
+ public int f7 = 0;
+ public int f8 = 0;
+ public int f9 = 0;
+ public int f10 = 0;
+ public int f11 = 0;
+ public int f12 = 0;
+ public int f13 = 0;
+ public int f14 = 0;
+ public int f15 = 0;
+ public int f16 = 0;
+ public int f17 = 0;
+ public int f18 = 0;
+ public int f19 = 0;
+ public int f20 = 0;
+ public int f21 = 0;
+ public int f22 = 0;
+ public int f23 = 0;
+ public int f24 = 0;
+
+ public void m1() { }
+ static public void m2() { }
+ public void m3() { }
+ public void m4() { }
+ public void m5() { }
+ public void m6() { }
+ public void m7() { }
+ public void m8() { }
+ public void m9() { }
+ public void m10() { }
+ public void m11() { }
+ public void m12() { }
+ public void m13() { }
+ public void m14() { }
+ public void m15() { }
+ public void m16() { }
+ public void m17() { }
+ public void m18() { }
+ public void m19() { }
+ public void m20() { }
+ public void m21() { }
+ public void m22() { }
+ public void m23() { }
+ public void m24() { }
+
+ public int p0 { get { return 1; } set { } }
+ static public int p1 { get { return 1; } set { } }
+ public int p2 { get { return 1; } set { } }
+ public int p3 { get { return 1; } set { } }
+ public int p4 { get { return 1; } set { } }
+ public int p5 { get { return 1; } set { } }
+ public int p6 { get { return 1; } set { } }
+ public int p7 { get { return 1; } set { } }
+ public int p8 { get { return 1; } set { } }
+ public int p9 { get { return 1; } set { } }
+ public int p10 { get { return 1; } set { } }
+ public int p11 { get { return 1; } set { } }
+ public int p12 { get { return 1; } set { } }
+ public int p13 { get { return 1; } set { } }
+ public int p14 { get { return 1; } set { } }
+ public int p15 { get { return 1; } set { } }
+ public int p16 { get { return 1; } set { } }
+ public int p17 { get { return 1; } set { } }
+ public int p18 { get { return 1; } set { } }
+ public int p19 { get { return 1; } set { } }
+ public int p20 { get { return 1; } set { } }
+ public int p21 { get { return 1; } set { } }
+ public int p22 { get { return 1; } set { } }
+ public int p23 { get { return 1; } set { } }
+ public int p24 { get { return 1; } set { } }
+
+ public event d e0;
+ static public event d e1;
+ public event d e2;
+ public event d e3;
+ public event d e4;
+ public event d e5;
+ public event d e6;
+ public event d e7;
+ public event d e8;
+ public event d e9;
+ public event d e10;
+ public event d e11;
+ public event d e12;
+ public event d e13;
+ public event d e14;
+ public event d e15;
+ public event d e16;
+ public event d e17;
+ public event d e18;
+ public event d e19;
+ public event d e20;
+ public event d e21;
+ public event d e22;
+ public event d e23;
+ public event d e24;
+
+ public void NoWarning()
+ {
+ e0 += new d(m1);
+ e1 += new d(m1);
+ e2 += new d(m1);
+ e3 += new d(m1);
+ e4 += new d(m1);
+ e5 += new d(m1);
+ e6 += new d(m1);
+ e7 += new d(m1);
+ e8 += new d(m1);
+ e9 += new d(m1);
+ e10 += new d(m1);
+ e11 += new d(m1);
+ e12 += new d(m1);
+ e13 += new d(m1);
+ e14 += new d(m1);
+ e15 += new d(m1);
+ e16 += new d(m1);
+ e17 += new d(m1);
+ e18 += new d(m1);
+ e19 += new d(m1);
+ e20 += new d(m1);
+ e21 += new d(m1);
+ e22 += new d(m1);
+ e23 += new d(m1);
+ e24 += new d(m1);
+ }
}
-}
-public class Class12
-{
- public Class12() { }
- public Class12(int i) { }
- public Class12(int i, int ii) { }
-
- public int f0 = 0;
- static public int f1 = 0;
- public int f2 = 0;
- public int f3 = 0;
- public int f4 = 0;
- public int f5 = 0;
- public int f6 = 0;
- public int f7 = 0;
- public int f8 = 0;
- public int f9 = 0;
- public int f10 = 0;
- public int f11 = 0;
- public int f12 = 0;
- public int f13 = 0;
- public int f14 = 0;
- public int f15 = 0;
- public int f16 = 0;
- public int f17 = 0;
- public int f18 = 0;
- public int f19 = 0;
- public int f20 = 0;
- public int f21 = 0;
- public int f22 = 0;
- public int f23 = 0;
- public int f24 = 0;
-
- public void m1() { }
- static public void m2() { }
- public void m3() { }
- public void m4() { }
- public void m5() { }
- public void m6() { }
- public void m7() { }
- public void m8() { }
- public void m9() { }
- public void m10() { }
- public void m11() { }
- public void m12() { }
- public void m13() { }
- public void m14() { }
- public void m15() { }
- public void m16() { }
- public void m17() { }
- public void m18() { }
- public void m19() { }
- public void m20() { }
- public void m21() { }
- public void m22() { }
- public void m23() { }
- public void m24() { }
-
- public int p0 { get { return 1; } set { } }
- static public int p1 { get { return 1; } set { } }
- public int p2 { get { return 1; } set { } }
- public int p3 { get { return 1; } set { } }
- public int p4 { get { return 1; } set { } }
- public int p5 { get { return 1; } set { } }
- public int p6 { get { return 1; } set { } }
- public int p7 { get { return 1; } set { } }
- public int p8 { get { return 1; } set { } }
- public int p9 { get { return 1; } set { } }
- public int p10 { get { return 1; } set { } }
- public int p11 { get { return 1; } set { } }
- public int p12 { get { return 1; } set { } }
- public int p13 { get { return 1; } set { } }
- public int p14 { get { return 1; } set { } }
- public int p15 { get { return 1; } set { } }
- public int p16 { get { return 1; } set { } }
- public int p17 { get { return 1; } set { } }
- public int p18 { get { return 1; } set { } }
- public int p19 { get { return 1; } set { } }
- public int p20 { get { return 1; } set { } }
- public int p21 { get { return 1; } set { } }
- public int p22 { get { return 1; } set { } }
- public int p23 { get { return 1; } set { } }
- public int p24 { get { return 1; } set { } }
-
- public event d e0;
- static public event d e1;
- public event d e2;
- public event d e3;
- public event d e4;
- public event d e5;
- public event d e6;
- public event d e7;
- public event d e8;
- public event d e9;
- public event d e10;
- public event d e11;
- public event d e12;
- public event d e13;
- public event d e14;
- public event d e15;
- public event d e16;
- public event d e17;
- public event d e18;
- public event d e19;
- public event d e20;
- public event d e21;
- public event d e22;
- public event d e23;
- public event d e24;
-
- public void NoWarning()
+ public class Class12
{
- e0 += new d(m1);
- e1 += new d(m1);
- e2 += new d(m1);
- e3 += new d(m1);
- e4 += new d(m1);
- e5 += new d(m1);
- e6 += new d(m1);
- e7 += new d(m1);
- e8 += new d(m1);
- e9 += new d(m1);
- e10 += new d(m1);
- e11 += new d(m1);
- e12 += new d(m1);
- e13 += new d(m1);
- e14 += new d(m1);
- e15 += new d(m1);
- e16 += new d(m1);
- e17 += new d(m1);
- e18 += new d(m1);
- e19 += new d(m1);
- e20 += new d(m1);
- e21 += new d(m1);
- e22 += new d(m1);
- e23 += new d(m1);
- e24 += new d(m1);
+ public Class12() { }
+ public Class12(int i) { }
+ public Class12(int i, int ii) { }
+
+ public int f0 = 0;
+ static public int f1 = 0;
+ public int f2 = 0;
+ public int f3 = 0;
+ public int f4 = 0;
+ public int f5 = 0;
+ public int f6 = 0;
+ public int f7 = 0;
+ public int f8 = 0;
+ public int f9 = 0;
+ public int f10 = 0;
+ public int f11 = 0;
+ public int f12 = 0;
+ public int f13 = 0;
+ public int f14 = 0;
+ public int f15 = 0;
+ public int f16 = 0;
+ public int f17 = 0;
+ public int f18 = 0;
+ public int f19 = 0;
+ public int f20 = 0;
+ public int f21 = 0;
+ public int f22 = 0;
+ public int f23 = 0;
+ public int f24 = 0;
+
+ public void m1() { }
+ static public void m2() { }
+ public void m3() { }
+ public void m4() { }
+ public void m5() { }
+ public void m6() { }
+ public void m7() { }
+ public void m8() { }
+ public void m9() { }
+ public void m10() { }
+ public void m11() { }
+ public void m12() { }
+ public void m13() { }
+ public void m14() { }
+ public void m15() { }
+ public void m16() { }
+ public void m17() { }
+ public void m18() { }
+ public void m19() { }
+ public void m20() { }
+ public void m21() { }
+ public void m22() { }
+ public void m23() { }
+ public void m24() { }
+
+ public int p0 { get { return 1; } set { } }
+ static public int p1 { get { return 1; } set { } }
+ public int p2 { get { return 1; } set { } }
+ public int p3 { get { return 1; } set { } }
+ public int p4 { get { return 1; } set { } }
+ public int p5 { get { return 1; } set { } }
+ public int p6 { get { return 1; } set { } }
+ public int p7 { get { return 1; } set { } }
+ public int p8 { get { return 1; } set { } }
+ public int p9 { get { return 1; } set { } }
+ public int p10 { get { return 1; } set { } }
+ public int p11 { get { return 1; } set { } }
+ public int p12 { get { return 1; } set { } }
+ public int p13 { get { return 1; } set { } }
+ public int p14 { get { return 1; } set { } }
+ public int p15 { get { return 1; } set { } }
+ public int p16 { get { return 1; } set { } }
+ public int p17 { get { return 1; } set { } }
+ public int p18 { get { return 1; } set { } }
+ public int p19 { get { return 1; } set { } }
+ public int p20 { get { return 1; } set { } }
+ public int p21 { get { return 1; } set { } }
+ public int p22 { get { return 1; } set { } }
+ public int p23 { get { return 1; } set { } }
+ public int p24 { get { return 1; } set { } }
+
+ public event d e0;
+ static public event d e1;
+ public event d e2;
+ public event d e3;
+ public event d e4;
+ public event d e5;
+ public event d e6;
+ public event d e7;
+ public event d e8;
+ public event d e9;
+ public event d e10;
+ public event d e11;
+ public event d e12;
+ public event d e13;
+ public event d e14;
+ public event d e15;
+ public event d e16;
+ public event d e17;
+ public event d e18;
+ public event d e19;
+ public event d e20;
+ public event d e21;
+ public event d e22;
+ public event d e23;
+ public event d e24;
+
+ public void NoWarning()
+ {
+ e0 += new d(m1);
+ e1 += new d(m1);
+ e2 += new d(m1);
+ e3 += new d(m1);
+ e4 += new d(m1);
+ e5 += new d(m1);
+ e6 += new d(m1);
+ e7 += new d(m1);
+ e8 += new d(m1);
+ e9 += new d(m1);
+ e10 += new d(m1);
+ e11 += new d(m1);
+ e12 += new d(m1);
+ e13 += new d(m1);
+ e14 += new d(m1);
+ e15 += new d(m1);
+ e16 += new d(m1);
+ e17 += new d(m1);
+ e18 += new d(m1);
+ e19 += new d(m1);
+ e20 += new d(m1);
+ e21 += new d(m1);
+ e22 += new d(m1);
+ e23 += new d(m1);
+ e24 += new d(m1);
+ }
}
-}
-public class Class13
-{
- public Class13() { }
- public Class13(int i) { }
- public Class13(int i, int ii) { }
-
- public int f0 = 0;
- static public int f1 = 0;
- public int f2 = 0;
- public int f3 = 0;
- public int f4 = 0;
- public int f5 = 0;
- public int f6 = 0;
- public int f7 = 0;
- public int f8 = 0;
- public int f9 = 0;
- public int f10 = 0;
- public int f11 = 0;
- public int f12 = 0;
- public int f13 = 0;
- public int f14 = 0;
- public int f15 = 0;
- public int f16 = 0;
- public int f17 = 0;
- public int f18 = 0;
- public int f19 = 0;
- public int f20 = 0;
- public int f21 = 0;
- public int f22 = 0;
- public int f23 = 0;
- public int f24 = 0;
-
- public void m1() { }
- static public void m2() { }
- public void m3() { }
- public void m4() { }
- public void m5() { }
- public void m6() { }
- public void m7() { }
- public void m8() { }
- public void m9() { }
- public void m10() { }
- public void m11() { }
- public void m12() { }
- public void m13() { }
- public void m14() { }
- public void m15() { }
- public void m16() { }
- public void m17() { }
- public void m18() { }
- public void m19() { }
- public void m20() { }
- public void m21() { }
- public void m22() { }
- public void m23() { }
- public void m24() { }
-
- public int p0 { get { return 1; } set { } }
- static public int p1 { get { return 1; } set { } }
- public int p2 { get { return 1; } set { } }
- public int p3 { get { return 1; } set { } }
- public int p4 { get { return 1; } set { } }
- public int p5 { get { return 1; } set { } }
- public int p6 { get { return 1; } set { } }
- public int p7 { get { return 1; } set { } }
- public int p8 { get { return 1; } set { } }
- public int p9 { get { return 1; } set { } }
- public int p10 { get { return 1; } set { } }
- public int p11 { get { return 1; } set { } }
- public int p12 { get { return 1; } set { } }
- public int p13 { get { return 1; } set { } }
- public int p14 { get { return 1; } set { } }
- public int p15 { get { return 1; } set { } }
- public int p16 { get { return 1; } set { } }
- public int p17 { get { return 1; } set { } }
- public int p18 { get { return 1; } set { } }
- public int p19 { get { return 1; } set { } }
- public int p20 { get { return 1; } set { } }
- public int p21 { get { return 1; } set { } }
- public int p22 { get { return 1; } set { } }
- public int p23 { get { return 1; } set { } }
- public int p24 { get { return 1; } set { } }
-
- public event d e0;
- static public event d e1;
- public event d e2;
- public event d e3;
- public event d e4;
- public event d e5;
- public event d e6;
- public event d e7;
- public event d e8;
- public event d e9;
- public event d e10;
- public event d e11;
- public event d e12;
- public event d e13;
- public event d e14;
- public event d e15;
- public event d e16;
- public event d e17;
- public event d e18;
- public event d e19;
- public event d e20;
- public event d e21;
- public event d e22;
- public event d e23;
- public event d e24;
-
- public void NoWarning()
+ public class Class13
{
- e0 += new d(m1);
- e1 += new d(m1);
- e2 += new d(m1);
- e3 += new d(m1);
- e4 += new d(m1);
- e5 += new d(m1);
- e6 += new d(m1);
- e7 += new d(m1);
- e8 += new d(m1);
- e9 += new d(m1);
- e10 += new d(m1);
- e11 += new d(m1);
- e12 += new d(m1);
- e13 += new d(m1);
- e14 += new d(m1);
- e15 += new d(m1);
- e16 += new d(m1);
- e17 += new d(m1);
- e18 += new d(m1);
- e19 += new d(m1);
- e20 += new d(m1);
- e21 += new d(m1);
- e22 += new d(m1);
- e23 += new d(m1);
- e24 += new d(m1);
+ public Class13() { }
+ public Class13(int i) { }
+ public Class13(int i, int ii) { }
+
+ public int f0 = 0;
+ static public int f1 = 0;
+ public int f2 = 0;
+ public int f3 = 0;
+ public int f4 = 0;
+ public int f5 = 0;
+ public int f6 = 0;
+ public int f7 = 0;
+ public int f8 = 0;
+ public int f9 = 0;
+ public int f10 = 0;
+ public int f11 = 0;
+ public int f12 = 0;
+ public int f13 = 0;
+ public int f14 = 0;
+ public int f15 = 0;
+ public int f16 = 0;
+ public int f17 = 0;
+ public int f18 = 0;
+ public int f19 = 0;
+ public int f20 = 0;
+ public int f21 = 0;
+ public int f22 = 0;
+ public int f23 = 0;
+ public int f24 = 0;
+
+ public void m1() { }
+ static public void m2() { }
+ public void m3() { }
+ public void m4() { }
+ public void m5() { }
+ public void m6() { }
+ public void m7() { }
+ public void m8() { }
+ public void m9() { }
+ public void m10() { }
+ public void m11() { }
+ public void m12() { }
+ public void m13() { }
+ public void m14() { }
+ public void m15() { }
+ public void m16() { }
+ public void m17() { }
+ public void m18() { }
+ public void m19() { }
+ public void m20() { }
+ public void m21() { }
+ public void m22() { }
+ public void m23() { }
+ public void m24() { }
+
+ public int p0 { get { return 1; } set { } }
+ static public int p1 { get { return 1; } set { } }
+ public int p2 { get { return 1; } set { } }
+ public int p3 { get { return 1; } set { } }
+ public int p4 { get { return 1; } set { } }
+ public int p5 { get { return 1; } set { } }
+ public int p6 { get { return 1; } set { } }
+ public int p7 { get { return 1; } set { } }
+ public int p8 { get { return 1; } set { } }
+ public int p9 { get { return 1; } set { } }
+ public int p10 { get { return 1; } set { } }
+ public int p11 { get { return 1; } set { } }
+ public int p12 { get { return 1; } set { } }
+ public int p13 { get { return 1; } set { } }
+ public int p14 { get { return 1; } set { } }
+ public int p15 { get { return 1; } set { } }
+ public int p16 { get { return 1; } set { } }
+ public int p17 { get { return 1; } set { } }
+ public int p18 { get { return 1; } set { } }
+ public int p19 { get { return 1; } set { } }
+ public int p20 { get { return 1; } set { } }
+ public int p21 { get { return 1; } set { } }
+ public int p22 { get { return 1; } set { } }
+ public int p23 { get { return 1; } set { } }
+ public int p24 { get { return 1; } set { } }
+
+ public event d e0;
+ static public event d e1;
+ public event d e2;
+ public event d e3;
+ public event d e4;
+ public event d e5;
+ public event d e6;
+ public event d e7;
+ public event d e8;
+ public event d e9;
+ public event d e10;
+ public event d e11;
+ public event d e12;
+ public event d e13;
+ public event d e14;
+ public event d e15;
+ public event d e16;
+ public event d e17;
+ public event d e18;
+ public event d e19;
+ public event d e20;
+ public event d e21;
+ public event d e22;
+ public event d e23;
+ public event d e24;
+
+ public void NoWarning()
+ {
+ e0 += new d(m1);
+ e1 += new d(m1);
+ e2 += new d(m1);
+ e3 += new d(m1);
+ e4 += new d(m1);
+ e5 += new d(m1);
+ e6 += new d(m1);
+ e7 += new d(m1);
+ e8 += new d(m1);
+ e9 += new d(m1);
+ e10 += new d(m1);
+ e11 += new d(m1);
+ e12 += new d(m1);
+ e13 += new d(m1);
+ e14 += new d(m1);
+ e15 += new d(m1);
+ e16 += new d(m1);
+ e17 += new d(m1);
+ e18 += new d(m1);
+ e19 += new d(m1);
+ e20 += new d(m1);
+ e21 += new d(m1);
+ e22 += new d(m1);
+ e23 += new d(m1);
+ e24 += new d(m1);
+ }
}
-}
-public class Class14
-{
- public Class14() { }
- public Class14(int i) { }
- public Class14(int i, int ii) { }
-
- public int f0 = 0;
- static public int f1 = 0;
- public int f2 = 0;
- public int f3 = 0;
- public int f4 = 0;
- public int f5 = 0;
- public int f6 = 0;
- public int f7 = 0;
- public int f8 = 0;
- public int f9 = 0;
- public int f10 = 0;
- public int f11 = 0;
- public int f12 = 0;
- public int f13 = 0;
- public int f14 = 0;
- public int f15 = 0;
- public int f16 = 0;
- public int f17 = 0;
- public int f18 = 0;
- public int f19 = 0;
- public int f20 = 0;
- public int f21 = 0;
- public int f22 = 0;
- public int f23 = 0;
- public int f24 = 0;
-
- public void m1() { }
- static public void m2() { }
- public void m3() { }
- public void m4() { }
- public void m5() { }
- public void m6() { }
- public void m7() { }
- public void m8() { }
- public void m9() { }
- public void m10() { }
- public void m11() { }
- public void m12() { }
- public void m13() { }
- public void m14() { }
- public void m15() { }
- public void m16() { }
- public void m17() { }
- public void m18() { }
- public void m19() { }
- public void m20() { }
- public void m21() { }
- public void m22() { }
- public void m23() { }
- public void m24() { }
-
- public int p0 { get { return 1; } set { } }
- static public int p1 { get { return 1; } set { } }
- public int p2 { get { return 1; } set { } }
- public int p3 { get { return 1; } set { } }
- public int p4 { get { return 1; } set { } }
- public int p5 { get { return 1; } set { } }
- public int p6 { get { return 1; } set { } }
- public int p7 { get { return 1; } set { } }
- public int p8 { get { return 1; } set { } }
- public int p9 { get { return 1; } set { } }
- public int p10 { get { return 1; } set { } }
- public int p11 { get { return 1; } set { } }
- public int p12 { get { return 1; } set { } }
- public int p13 { get { return 1; } set { } }
- public int p14 { get { return 1; } set { } }
- public int p15 { get { return 1; } set { } }
- public int p16 { get { return 1; } set { } }
- public int p17 { get { return 1; } set { } }
- public int p18 { get { return 1; } set { } }
- public int p19 { get { return 1; } set { } }
- public int p20 { get { return 1; } set { } }
- public int p21 { get { return 1; } set { } }
- public int p22 { get { return 1; } set { } }
- public int p23 { get { return 1; } set { } }
- public int p24 { get { return 1; } set { } }
-
- public event d e0;
- static public event d e1;
- public event d e2;
- public event d e3;
- public event d e4;
- public event d e5;
- public event d e6;
- public event d e7;
- public event d e8;
- public event d e9;
- public event d e10;
- public event d e11;
- public event d e12;
- public event d e13;
- public event d e14;
- public event d e15;
- public event d e16;
- public event d e17;
- public event d e18;
- public event d e19;
- public event d e20;
- public event d e21;
- public event d e22;
- public event d e23;
- public event d e24;
-
- public void NoWarning()
+ public class Class14
{
- e0 += new d(m1);
- e1 += new d(m1);
- e2 += new d(m1);
- e3 += new d(m1);
- e4 += new d(m1);
- e5 += new d(m1);
- e6 += new d(m1);
- e7 += new d(m1);
- e8 += new d(m1);
- e9 += new d(m1);
- e10 += new d(m1);
- e11 += new d(m1);
- e12 += new d(m1);
- e13 += new d(m1);
- e14 += new d(m1);
- e15 += new d(m1);
- e16 += new d(m1);
- e17 += new d(m1);
- e18 += new d(m1);
- e19 += new d(m1);
- e20 += new d(m1);
- e21 += new d(m1);
- e22 += new d(m1);
- e23 += new d(m1);
- e24 += new d(m1);
+ public Class14() { }
+ public Class14(int i) { }
+ public Class14(int i, int ii) { }
+
+ public int f0 = 0;
+ static public int f1 = 0;
+ public int f2 = 0;
+ public int f3 = 0;
+ public int f4 = 0;
+ public int f5 = 0;
+ public int f6 = 0;
+ public int f7 = 0;
+ public int f8 = 0;
+ public int f9 = 0;
+ public int f10 = 0;
+ public int f11 = 0;
+ public int f12 = 0;
+ public int f13 = 0;
+ public int f14 = 0;
+ public int f15 = 0;
+ public int f16 = 0;
+ public int f17 = 0;
+ public int f18 = 0;
+ public int f19 = 0;
+ public int f20 = 0;
+ public int f21 = 0;
+ public int f22 = 0;
+ public int f23 = 0;
+ public int f24 = 0;
+
+ public void m1() { }
+ static public void m2() { }
+ public void m3() { }
+ public void m4() { }
+ public void m5() { }
+ public void m6() { }
+ public void m7() { }
+ public void m8() { }
+ public void m9() { }
+ public void m10() { }
+ public void m11() { }
+ public void m12() { }
+ public void m13() { }
+ public void m14() { }
+ public void m15() { }
+ public void m16() { }
+ public void m17() { }
+ public void m18() { }
+ public void m19() { }
+ public void m20() { }
+ public void m21() { }
+ public void m22() { }
+ public void m23() { }
+ public void m24() { }
+
+ public int p0 { get { return 1; } set { } }
+ static public int p1 { get { return 1; } set { } }
+ public int p2 { get { return 1; } set { } }
+ public int p3 { get { return 1; } set { } }
+ public int p4 { get { return 1; } set { } }
+ public int p5 { get { return 1; } set { } }
+ public int p6 { get { return 1; } set { } }
+ public int p7 { get { return 1; } set { } }
+ public int p8 { get { return 1; } set { } }
+ public int p9 { get { return 1; } set { } }
+ public int p10 { get { return 1; } set { } }
+ public int p11 { get { return 1; } set { } }
+ public int p12 { get { return 1; } set { } }
+ public int p13 { get { return 1; } set { } }
+ public int p14 { get { return 1; } set { } }
+ public int p15 { get { return 1; } set { } }
+ public int p16 { get { return 1; } set { } }
+ public int p17 { get { return 1; } set { } }
+ public int p18 { get { return 1; } set { } }
+ public int p19 { get { return 1; } set { } }
+ public int p20 { get { return 1; } set { } }
+ public int p21 { get { return 1; } set { } }
+ public int p22 { get { return 1; } set { } }
+ public int p23 { get { return 1; } set { } }
+ public int p24 { get { return 1; } set { } }
+
+ public event d e0;
+ static public event d e1;
+ public event d e2;
+ public event d e3;
+ public event d e4;
+ public event d e5;
+ public event d e6;
+ public event d e7;
+ public event d e8;
+ public event d e9;
+ public event d e10;
+ public event d e11;
+ public event d e12;
+ public event d e13;
+ public event d e14;
+ public event d e15;
+ public event d e16;
+ public event d e17;
+ public event d e18;
+ public event d e19;
+ public event d e20;
+ public event d e21;
+ public event d e22;
+ public event d e23;
+ public event d e24;
+
+ public void NoWarning()
+ {
+ e0 += new d(m1);
+ e1 += new d(m1);
+ e2 += new d(m1);
+ e3 += new d(m1);
+ e4 += new d(m1);
+ e5 += new d(m1);
+ e6 += new d(m1);
+ e7 += new d(m1);
+ e8 += new d(m1);
+ e9 += new d(m1);
+ e10 += new d(m1);
+ e11 += new d(m1);
+ e12 += new d(m1);
+ e13 += new d(m1);
+ e14 += new d(m1);
+ e15 += new d(m1);
+ e16 += new d(m1);
+ e17 += new d(m1);
+ e18 += new d(m1);
+ e19 += new d(m1);
+ e20 += new d(m1);
+ e21 += new d(m1);
+ e22 += new d(m1);
+ e23 += new d(m1);
+ e24 += new d(m1);
+ }
}
-}
-public class Class15
-{
- public Class15() { }
- public Class15(int i) { }
- public Class15(int i, int ii) { }
-
- public int f0 = 0;
- static public int f1 = 0;
- public int f2 = 0;
- public int f3 = 0;
- public int f4 = 0;
- public int f5 = 0;
- public int f6 = 0;
- public int f7 = 0;
- public int f8 = 0;
- public int f9 = 0;
- public int f10 = 0;
- public int f11 = 0;
- public int f12 = 0;
- public int f13 = 0;
- public int f14 = 0;
- public int f15 = 0;
- public int f16 = 0;
- public int f17 = 0;
- public int f18 = 0;
- public int f19 = 0;
- public int f20 = 0;
- public int f21 = 0;
- public int f22 = 0;
- public int f23 = 0;
- public int f24 = 0;
-
- public void m1() { }
- static public void m2() { }
- public void m3() { }
- public void m4() { }
- public void m5() { }
- public void m6() { }
- public void m7() { }
- public void m8() { }
- public void m9() { }
- public void m10() { }
- public void m11() { }
- public void m12() { }
- public void m13() { }
- public void m14() { }
- public void m15() { }
- public void m16() { }
- public void m17() { }
- public void m18() { }
- public void m19() { }
- public void m20() { }
- public void m21() { }
- public void m22() { }
- public void m23() { }
- public void m24() { }
-
- public int p0 { get { return 1; } set { } }
- static public int p1 { get { return 1; } set { } }
- public int p2 { get { return 1; } set { } }
- public int p3 { get { return 1; } set { } }
- public int p4 { get { return 1; } set { } }
- public int p5 { get { return 1; } set { } }
- public int p6 { get { return 1; } set { } }
- public int p7 { get { return 1; } set { } }
- public int p8 { get { return 1; } set { } }
- public int p9 { get { return 1; } set { } }
- public int p10 { get { return 1; } set { } }
- public int p11 { get { return 1; } set { } }
- public int p12 { get { return 1; } set { } }
- public int p13 { get { return 1; } set { } }
- public int p14 { get { return 1; } set { } }
- public int p15 { get { return 1; } set { } }
- public int p16 { get { return 1; } set { } }
- public int p17 { get { return 1; } set { } }
- public int p18 { get { return 1; } set { } }
- public int p19 { get { return 1; } set { } }
- public int p20 { get { return 1; } set { } }
- public int p21 { get { return 1; } set { } }
- public int p22 { get { return 1; } set { } }
- public int p23 { get { return 1; } set { } }
- public int p24 { get { return 1; } set { } }
-
- public event d e0;
- static public event d e1;
- public event d e2;
- public event d e3;
- public event d e4;
- public event d e5;
- public event d e6;
- public event d e7;
- public event d e8;
- public event d e9;
- public event d e10;
- public event d e11;
- public event d e12;
- public event d e13;
- public event d e14;
- public event d e15;
- public event d e16;
- public event d e17;
- public event d e18;
- public event d e19;
- public event d e20;
- public event d e21;
- public event d e22;
- public event d e23;
- public event d e24;
-
- public void NoWarning()
+ public class Class15
{
- e0 += new d(m1);
- e1 += new d(m1);
- e2 += new d(m1);
- e3 += new d(m1);
- e4 += new d(m1);
- e5 += new d(m1);
- e6 += new d(m1);
- e7 += new d(m1);
- e8 += new d(m1);
- e9 += new d(m1);
- e10 += new d(m1);
- e11 += new d(m1);
- e12 += new d(m1);
- e13 += new d(m1);
- e14 += new d(m1);
- e15 += new d(m1);
- e16 += new d(m1);
- e17 += new d(m1);
- e18 += new d(m1);
- e19 += new d(m1);
- e20 += new d(m1);
- e21 += new d(m1);
- e22 += new d(m1);
- e23 += new d(m1);
- e24 += new d(m1);
+ public Class15() { }
+ public Class15(int i) { }
+ public Class15(int i, int ii) { }
+
+ public int f0 = 0;
+ static public int f1 = 0;
+ public int f2 = 0;
+ public int f3 = 0;
+ public int f4 = 0;
+ public int f5 = 0;
+ public int f6 = 0;
+ public int f7 = 0;
+ public int f8 = 0;
+ public int f9 = 0;
+ public int f10 = 0;
+ public int f11 = 0;
+ public int f12 = 0;
+ public int f13 = 0;
+ public int f14 = 0;
+ public int f15 = 0;
+ public int f16 = 0;
+ public int f17 = 0;
+ public int f18 = 0;
+ public int f19 = 0;
+ public int f20 = 0;
+ public int f21 = 0;
+ public int f22 = 0;
+ public int f23 = 0;
+ public int f24 = 0;
+
+ public void m1() { }
+ static public void m2() { }
+ public void m3() { }
+ public void m4() { }
+ public void m5() { }
+ public void m6() { }
+ public void m7() { }
+ public void m8() { }
+ public void m9() { }
+ public void m10() { }
+ public void m11() { }
+ public void m12() { }
+ public void m13() { }
+ public void m14() { }
+ public void m15() { }
+ public void m16() { }
+ public void m17() { }
+ public void m18() { }
+ public void m19() { }
+ public void m20() { }
+ public void m21() { }
+ public void m22() { }
+ public void m23() { }
+ public void m24() { }
+
+ public int p0 { get { return 1; } set { } }
+ static public int p1 { get { return 1; } set { } }
+ public int p2 { get { return 1; } set { } }
+ public int p3 { get { return 1; } set { } }
+ public int p4 { get { return 1; } set { } }
+ public int p5 { get { return 1; } set { } }
+ public int p6 { get { return 1; } set { } }
+ public int p7 { get { return 1; } set { } }
+ public int p8 { get { return 1; } set { } }
+ public int p9 { get { return 1; } set { } }
+ public int p10 { get { return 1; } set { } }
+ public int p11 { get { return 1; } set { } }
+ public int p12 { get { return 1; } set { } }
+ public int p13 { get { return 1; } set { } }
+ public int p14 { get { return 1; } set { } }
+ public int p15 { get { return 1; } set { } }
+ public int p16 { get { return 1; } set { } }
+ public int p17 { get { return 1; } set { } }
+ public int p18 { get { return 1; } set { } }
+ public int p19 { get { return 1; } set { } }
+ public int p20 { get { return 1; } set { } }
+ public int p21 { get { return 1; } set { } }
+ public int p22 { get { return 1; } set { } }
+ public int p23 { get { return 1; } set { } }
+ public int p24 { get { return 1; } set { } }
+
+ public event d e0;
+ static public event d e1;
+ public event d e2;
+ public event d e3;
+ public event d e4;
+ public event d e5;
+ public event d e6;
+ public event d e7;
+ public event d e8;
+ public event d e9;
+ public event d e10;
+ public event d e11;
+ public event d e12;
+ public event d e13;
+ public event d e14;
+ public event d e15;
+ public event d e16;
+ public event d e17;
+ public event d e18;
+ public event d e19;
+ public event d e20;
+ public event d e21;
+ public event d e22;
+ public event d e23;
+ public event d e24;
+
+ public void NoWarning()
+ {
+ e0 += new d(m1);
+ e1 += new d(m1);
+ e2 += new d(m1);
+ e3 += new d(m1);
+ e4 += new d(m1);
+ e5 += new d(m1);
+ e6 += new d(m1);
+ e7 += new d(m1);
+ e8 += new d(m1);
+ e9 += new d(m1);
+ e10 += new d(m1);
+ e11 += new d(m1);
+ e12 += new d(m1);
+ e13 += new d(m1);
+ e14 += new d(m1);
+ e15 += new d(m1);
+ e16 += new d(m1);
+ e17 += new d(m1);
+ e18 += new d(m1);
+ e19 += new d(m1);
+ e20 += new d(m1);
+ e21 += new d(m1);
+ e22 += new d(m1);
+ e23 += new d(m1);
+ e24 += new d(m1);
+ }
}
-}
-public class Class16
-{
- public Class16() { }
- public Class16(int i) { }
- public Class16(int i, int ii) { }
-
- public int f0 = 0;
- static public int f1 = 0;
- public int f2 = 0;
- public int f3 = 0;
- public int f4 = 0;
- public int f5 = 0;
- public int f6 = 0;
- public int f7 = 0;
- public int f8 = 0;
- public int f9 = 0;
- public int f10 = 0;
- public int f11 = 0;
- public int f12 = 0;
- public int f13 = 0;
- public int f14 = 0;
- public int f15 = 0;
- public int f16 = 0;
- public int f17 = 0;
- public int f18 = 0;
- public int f19 = 0;
- public int f20 = 0;
- public int f21 = 0;
- public int f22 = 0;
- public int f23 = 0;
- public int f24 = 0;
-
- public void m1() { }
- static public void m2() { }
- public void m3() { }
- public void m4() { }
- public void m5() { }
- public void m6() { }
- public void m7() { }
- public void m8() { }
- public void m9() { }
- public void m10() { }
- public void m11() { }
- public void m12() { }
- public void m13() { }
- public void m14() { }
- public void m15() { }
- public void m16() { }
- public void m17() { }
- public void m18() { }
- public void m19() { }
- public void m20() { }
- public void m21() { }
- public void m22() { }
- public void m23() { }
- public void m24() { }
-
- public int p0 { get { return 1; } set { } }
- static public int p1 { get { return 1; } set { } }
- public int p2 { get { return 1; } set { } }
- public int p3 { get { return 1; } set { } }
- public int p4 { get { return 1; } set { } }
- public int p5 { get { return 1; } set { } }
- public int p6 { get { return 1; } set { } }
- public int p7 { get { return 1; } set { } }
- public int p8 { get { return 1; } set { } }
- public int p9 { get { return 1; } set { } }
- public int p10 { get { return 1; } set { } }
- public int p11 { get { return 1; } set { } }
- public int p12 { get { return 1; } set { } }
- public int p13 { get { return 1; } set { } }
- public int p14 { get { return 1; } set { } }
- public int p15 { get { return 1; } set { } }
- public int p16 { get { return 1; } set { } }
- public int p17 { get { return 1; } set { } }
- public int p18 { get { return 1; } set { } }
- public int p19 { get { return 1; } set { } }
- public int p20 { get { return 1; } set { } }
- public int p21 { get { return 1; } set { } }
- public int p22 { get { return 1; } set { } }
- public int p23 { get { return 1; } set { } }
- public int p24 { get { return 1; } set { } }
-
- public event d e0;
- static public event d e1;
- public event d e2;
- public event d e3;
- public event d e4;
- public event d e5;
- public event d e6;
- public event d e7;
- public event d e8;
- public event d e9;
- public event d e10;
- public event d e11;
- public event d e12;
- public event d e13;
- public event d e14;
- public event d e15;
- public event d e16;
- public event d e17;
- public event d e18;
- public event d e19;
- public event d e20;
- public event d e21;
- public event d e22;
- public event d e23;
- public event d e24;
-
- public void NoWarning()
+ public class Class16
{
- e0 += new d(m1);
- e1 += new d(m1);
- e2 += new d(m1);
- e3 += new d(m1);
- e4 += new d(m1);
- e5 += new d(m1);
- e6 += new d(m1);
- e7 += new d(m1);
- e8 += new d(m1);
- e9 += new d(m1);
- e10 += new d(m1);
- e11 += new d(m1);
- e12 += new d(m1);
- e13 += new d(m1);
- e14 += new d(m1);
- e15 += new d(m1);
- e16 += new d(m1);
- e17 += new d(m1);
- e18 += new d(m1);
- e19 += new d(m1);
- e20 += new d(m1);
- e21 += new d(m1);
- e22 += new d(m1);
- e23 += new d(m1);
- e24 += new d(m1);
+ public Class16() { }
+ public Class16(int i) { }
+ public Class16(int i, int ii) { }
+
+ public int f0 = 0;
+ static public int f1 = 0;
+ public int f2 = 0;
+ public int f3 = 0;
+ public int f4 = 0;
+ public int f5 = 0;
+ public int f6 = 0;
+ public int f7 = 0;
+ public int f8 = 0;
+ public int f9 = 0;
+ public int f10 = 0;
+ public int f11 = 0;
+ public int f12 = 0;
+ public int f13 = 0;
+ public int f14 = 0;
+ public int f15 = 0;
+ public int f16 = 0;
+ public int f17 = 0;
+ public int f18 = 0;
+ public int f19 = 0;
+ public int f20 = 0;
+ public int f21 = 0;
+ public int f22 = 0;
+ public int f23 = 0;
+ public int f24 = 0;
+
+ public void m1() { }
+ static public void m2() { }
+ public void m3() { }
+ public void m4() { }
+ public void m5() { }
+ public void m6() { }
+ public void m7() { }
+ public void m8() { }
+ public void m9() { }
+ public void m10() { }
+ public void m11() { }
+ public void m12() { }
+ public void m13() { }
+ public void m14() { }
+ public void m15() { }
+ public void m16() { }
+ public void m17() { }
+ public void m18() { }
+ public void m19() { }
+ public void m20() { }
+ public void m21() { }
+ public void m22() { }
+ public void m23() { }
+ public void m24() { }
+
+ public int p0 { get { return 1; } set { } }
+ static public int p1 { get { return 1; } set { } }
+ public int p2 { get { return 1; } set { } }
+ public int p3 { get { return 1; } set { } }
+ public int p4 { get { return 1; } set { } }
+ public int p5 { get { return 1; } set { } }
+ public int p6 { get { return 1; } set { } }
+ public int p7 { get { return 1; } set { } }
+ public int p8 { get { return 1; } set { } }
+ public int p9 { get { return 1; } set { } }
+ public int p10 { get { return 1; } set { } }
+ public int p11 { get { return 1; } set { } }
+ public int p12 { get { return 1; } set { } }
+ public int p13 { get { return 1; } set { } }
+ public int p14 { get { return 1; } set { } }
+ public int p15 { get { return 1; } set { } }
+ public int p16 { get { return 1; } set { } }
+ public int p17 { get { return 1; } set { } }
+ public int p18 { get { return 1; } set { } }
+ public int p19 { get { return 1; } set { } }
+ public int p20 { get { return 1; } set { } }
+ public int p21 { get { return 1; } set { } }
+ public int p22 { get { return 1; } set { } }
+ public int p23 { get { return 1; } set { } }
+ public int p24 { get { return 1; } set { } }
+
+ public event d e0;
+ static public event d e1;
+ public event d e2;
+ public event d e3;
+ public event d e4;
+ public event d e5;
+ public event d e6;
+ public event d e7;
+ public event d e8;
+ public event d e9;
+ public event d e10;
+ public event d e11;
+ public event d e12;
+ public event d e13;
+ public event d e14;
+ public event d e15;
+ public event d e16;
+ public event d e17;
+ public event d e18;
+ public event d e19;
+ public event d e20;
+ public event d e21;
+ public event d e22;
+ public event d e23;
+ public event d e24;
+
+ public void NoWarning()
+ {
+ e0 += new d(m1);
+ e1 += new d(m1);
+ e2 += new d(m1);
+ e3 += new d(m1);
+ e4 += new d(m1);
+ e5 += new d(m1);
+ e6 += new d(m1);
+ e7 += new d(m1);
+ e8 += new d(m1);
+ e9 += new d(m1);
+ e10 += new d(m1);
+ e11 += new d(m1);
+ e12 += new d(m1);
+ e13 += new d(m1);
+ e14 += new d(m1);
+ e15 += new d(m1);
+ e16 += new d(m1);
+ e17 += new d(m1);
+ e18 += new d(m1);
+ e19 += new d(m1);
+ e20 += new d(m1);
+ e21 += new d(m1);
+ e22 += new d(m1);
+ e23 += new d(m1);
+ e24 += new d(m1);
+ }
}
-}
-public class Class17
-{
- public Class17() { }
- public Class17(int i) { }
- public Class17(int i, int ii) { }
-
- public int f0 = 0;
- static public int f1 = 0;
- public int f2 = 0;
- public int f3 = 0;
- public int f4 = 0;
- public int f5 = 0;
- public int f6 = 0;
- public int f7 = 0;
- public int f8 = 0;
- public int f9 = 0;
- public int f10 = 0;
- public int f11 = 0;
- public int f12 = 0;
- public int f13 = 0;
- public int f14 = 0;
- public int f15 = 0;
- public int f16 = 0;
- public int f17 = 0;
- public int f18 = 0;
- public int f19 = 0;
- public int f20 = 0;
- public int f21 = 0;
- public int f22 = 0;
- public int f23 = 0;
- public int f24 = 0;
-
- public void m1() { }
- static public void m2() { }
- public void m3() { }
- public void m4() { }
- public void m5() { }
- public void m6() { }
- public void m7() { }
- public void m8() { }
- public void m9() { }
- public void m10() { }
- public void m11() { }
- public void m12() { }
- public void m13() { }
- public void m14() { }
- public void m15() { }
- public void m16() { }
- public void m17() { }
- public void m18() { }
- public void m19() { }
- public void m20() { }
- public void m21() { }
- public void m22() { }
- public void m23() { }
- public void m24() { }
-
- public int p0 { get { return 1; } set { } }
- static public int p1 { get { return 1; } set { } }
- public int p2 { get { return 1; } set { } }
- public int p3 { get { return 1; } set { } }
- public int p4 { get { return 1; } set { } }
- public int p5 { get { return 1; } set { } }
- public int p6 { get { return 1; } set { } }
- public int p7 { get { return 1; } set { } }
- public int p8 { get { return 1; } set { } }
- public int p9 { get { return 1; } set { } }
- public int p10 { get { return 1; } set { } }
- public int p11 { get { return 1; } set { } }
- public int p12 { get { return 1; } set { } }
- public int p13 { get { return 1; } set { } }
- public int p14 { get { return 1; } set { } }
- public int p15 { get { return 1; } set { } }
- public int p16 { get { return 1; } set { } }
- public int p17 { get { return 1; } set { } }
- public int p18 { get { return 1; } set { } }
- public int p19 { get { return 1; } set { } }
- public int p20 { get { return 1; } set { } }
- public int p21 { get { return 1; } set { } }
- public int p22 { get { return 1; } set { } }
- public int p23 { get { return 1; } set { } }
- public int p24 { get { return 1; } set { } }
-
- public event d e0;
- static public event d e1;
- public event d e2;
- public event d e3;
- public event d e4;
- public event d e5;
- public event d e6;
- public event d e7;
- public event d e8;
- public event d e9;
- public event d e10;
- public event d e11;
- public event d e12;
- public event d e13;
- public event d e14;
- public event d e15;
- public event d e16;
- public event d e17;
- public event d e18;
- public event d e19;
- public event d e20;
- public event d e21;
- public event d e22;
- public event d e23;
- public event d e24;
-
- public void NoWarning()
+ public class Class17
{
- e0 += new d(m1);
- e1 += new d(m1);
- e2 += new d(m1);
- e3 += new d(m1);
- e4 += new d(m1);
- e5 += new d(m1);
- e6 += new d(m1);
- e7 += new d(m1);
- e8 += new d(m1);
- e9 += new d(m1);
- e10 += new d(m1);
- e11 += new d(m1);
- e12 += new d(m1);
- e13 += new d(m1);
- e14 += new d(m1);
- e15 += new d(m1);
- e16 += new d(m1);
- e17 += new d(m1);
- e18 += new d(m1);
- e19 += new d(m1);
- e20 += new d(m1);
- e21 += new d(m1);
- e22 += new d(m1);
- e23 += new d(m1);
- e24 += new d(m1);
+ public Class17() { }
+ public Class17(int i) { }
+ public Class17(int i, int ii) { }
+
+ public int f0 = 0;
+ static public int f1 = 0;
+ public int f2 = 0;
+ public int f3 = 0;
+ public int f4 = 0;
+ public int f5 = 0;
+ public int f6 = 0;
+ public int f7 = 0;
+ public int f8 = 0;
+ public int f9 = 0;
+ public int f10 = 0;
+ public int f11 = 0;
+ public int f12 = 0;
+ public int f13 = 0;
+ public int f14 = 0;
+ public int f15 = 0;
+ public int f16 = 0;
+ public int f17 = 0;
+ public int f18 = 0;
+ public int f19 = 0;
+ public int f20 = 0;
+ public int f21 = 0;
+ public int f22 = 0;
+ public int f23 = 0;
+ public int f24 = 0;
+
+ public void m1() { }
+ static public void m2() { }
+ public void m3() { }
+ public void m4() { }
+ public void m5() { }
+ public void m6() { }
+ public void m7() { }
+ public void m8() { }
+ public void m9() { }
+ public void m10() { }
+ public void m11() { }
+ public void m12() { }
+ public void m13() { }
+ public void m14() { }
+ public void m15() { }
+ public void m16() { }
+ public void m17() { }
+ public void m18() { }
+ public void m19() { }
+ public void m20() { }
+ public void m21() { }
+ public void m22() { }
+ public void m23() { }
+ public void m24() { }
+
+ public int p0 { get { return 1; } set { } }
+ static public int p1 { get { return 1; } set { } }
+ public int p2 { get { return 1; } set { } }
+ public int p3 { get { return 1; } set { } }
+ public int p4 { get { return 1; } set { } }
+ public int p5 { get { return 1; } set { } }
+ public int p6 { get { return 1; } set { } }
+ public int p7 { get { return 1; } set { } }
+ public int p8 { get { return 1; } set { } }
+ public int p9 { get { return 1; } set { } }
+ public int p10 { get { return 1; } set { } }
+ public int p11 { get { return 1; } set { } }
+ public int p12 { get { return 1; } set { } }
+ public int p13 { get { return 1; } set { } }
+ public int p14 { get { return 1; } set { } }
+ public int p15 { get { return 1; } set { } }
+ public int p16 { get { return 1; } set { } }
+ public int p17 { get { return 1; } set { } }
+ public int p18 { get { return 1; } set { } }
+ public int p19 { get { return 1; } set { } }
+ public int p20 { get { return 1; } set { } }
+ public int p21 { get { return 1; } set { } }
+ public int p22 { get { return 1; } set { } }
+ public int p23 { get { return 1; } set { } }
+ public int p24 { get { return 1; } set { } }
+
+ public event d e0;
+ static public event d e1;
+ public event d e2;
+ public event d e3;
+ public event d e4;
+ public event d e5;
+ public event d e6;
+ public event d e7;
+ public event d e8;
+ public event d e9;
+ public event d e10;
+ public event d e11;
+ public event d e12;
+ public event d e13;
+ public event d e14;
+ public event d e15;
+ public event d e16;
+ public event d e17;
+ public event d e18;
+ public event d e19;
+ public event d e20;
+ public event d e21;
+ public event d e22;
+ public event d e23;
+ public event d e24;
+
+ public void NoWarning()
+ {
+ e0 += new d(m1);
+ e1 += new d(m1);
+ e2 += new d(m1);
+ e3 += new d(m1);
+ e4 += new d(m1);
+ e5 += new d(m1);
+ e6 += new d(m1);
+ e7 += new d(m1);
+ e8 += new d(m1);
+ e9 += new d(m1);
+ e10 += new d(m1);
+ e11 += new d(m1);
+ e12 += new d(m1);
+ e13 += new d(m1);
+ e14 += new d(m1);
+ e15 += new d(m1);
+ e16 += new d(m1);
+ e17 += new d(m1);
+ e18 += new d(m1);
+ e19 += new d(m1);
+ e20 += new d(m1);
+ e21 += new d(m1);
+ e22 += new d(m1);
+ e23 += new d(m1);
+ e24 += new d(m1);
+ }
}
-}
-public class Class18
-{
- public Class18() { }
- public Class18(int i) { }
- public Class18(int i, int ii) { }
-
- public int f0 = 0;
- static public int f1 = 0;
- public int f2 = 0;
- public int f3 = 0;
- public int f4 = 0;
- public int f5 = 0;
- public int f6 = 0;
- public int f7 = 0;
- public int f8 = 0;
- public int f9 = 0;
- public int f10 = 0;
- public int f11 = 0;
- public int f12 = 0;
- public int f13 = 0;
- public int f14 = 0;
- public int f15 = 0;
- public int f16 = 0;
- public int f17 = 0;
- public int f18 = 0;
- public int f19 = 0;
- public int f20 = 0;
- public int f21 = 0;
- public int f22 = 0;
- public int f23 = 0;
- public int f24 = 0;
-
- public void m1() { }
- static public void m2() { }
- public void m3() { }
- public void m4() { }
- public void m5() { }
- public void m6() { }
- public void m7() { }
- public void m8() { }
- public void m9() { }
- public void m10() { }
- public void m11() { }
- public void m12() { }
- public void m13() { }
- public void m14() { }
- public void m15() { }
- public void m16() { }
- public void m17() { }
- public void m18() { }
- public void m19() { }
- public void m20() { }
- public void m21() { }
- public void m22() { }
- public void m23() { }
- public void m24() { }
-
- public int p0 { get { return 1; } set { } }
- static public int p1 { get { return 1; } set { } }
- public int p2 { get { return 1; } set { } }
- public int p3 { get { return 1; } set { } }
- public int p4 { get { return 1; } set { } }
- public int p5 { get { return 1; } set { } }
- public int p6 { get { return 1; } set { } }
- public int p7 { get { return 1; } set { } }
- public int p8 { get { return 1; } set { } }
- public int p9 { get { return 1; } set { } }
- public int p10 { get { return 1; } set { } }
- public int p11 { get { return 1; } set { } }
- public int p12 { get { return 1; } set { } }
- public int p13 { get { return 1; } set { } }
- public int p14 { get { return 1; } set { } }
- public int p15 { get { return 1; } set { } }
- public int p16 { get { return 1; } set { } }
- public int p17 { get { return 1; } set { } }
- public int p18 { get { return 1; } set { } }
- public int p19 { get { return 1; } set { } }
- public int p20 { get { return 1; } set { } }
- public int p21 { get { return 1; } set { } }
- public int p22 { get { return 1; } set { } }
- public int p23 { get { return 1; } set { } }
- public int p24 { get { return 1; } set { } }
-
- public event d e0;
- static public event d e1;
- public event d e2;
- public event d e3;
- public event d e4;
- public event d e5;
- public event d e6;
- public event d e7;
- public event d e8;
- public event d e9;
- public event d e10;
- public event d e11;
- public event d e12;
- public event d e13;
- public event d e14;
- public event d e15;
- public event d e16;
- public event d e17;
- public event d e18;
- public event d e19;
- public event d e20;
- public event d e21;
- public event d e22;
- public event d e23;
- public event d e24;
-
- public void NoWarning()
+ public class Class18
{
- e0 += new d(m1);
- e1 += new d(m1);
- e2 += new d(m1);
- e3 += new d(m1);
- e4 += new d(m1);
- e5 += new d(m1);
- e6 += new d(m1);
- e7 += new d(m1);
- e8 += new d(m1);
- e9 += new d(m1);
- e10 += new d(m1);
- e11 += new d(m1);
- e12 += new d(m1);
- e13 += new d(m1);
- e14 += new d(m1);
- e15 += new d(m1);
- e16 += new d(m1);
- e17 += new d(m1);
- e18 += new d(m1);
- e19 += new d(m1);
- e20 += new d(m1);
- e21 += new d(m1);
- e22 += new d(m1);
- e23 += new d(m1);
- e24 += new d(m1);
+ public Class18() { }
+ public Class18(int i) { }
+ public Class18(int i, int ii) { }
+
+ public int f0 = 0;
+ static public int f1 = 0;
+ public int f2 = 0;
+ public int f3 = 0;
+ public int f4 = 0;
+ public int f5 = 0;
+ public int f6 = 0;
+ public int f7 = 0;
+ public int f8 = 0;
+ public int f9 = 0;
+ public int f10 = 0;
+ public int f11 = 0;
+ public int f12 = 0;
+ public int f13 = 0;
+ public int f14 = 0;
+ public int f15 = 0;
+ public int f16 = 0;
+ public int f17 = 0;
+ public int f18 = 0;
+ public int f19 = 0;
+ public int f20 = 0;
+ public int f21 = 0;
+ public int f22 = 0;
+ public int f23 = 0;
+ public int f24 = 0;
+
+ public void m1() { }
+ static public void m2() { }
+ public void m3() { }
+ public void m4() { }
+ public void m5() { }
+ public void m6() { }
+ public void m7() { }
+ public void m8() { }
+ public void m9() { }
+ public void m10() { }
+ public void m11() { }
+ public void m12() { }
+ public void m13() { }
+ public void m14() { }
+ public void m15() { }
+ public void m16() { }
+ public void m17() { }
+ public void m18() { }
+ public void m19() { }
+ public void m20() { }
+ public void m21() { }
+ public void m22() { }
+ public void m23() { }
+ public void m24() { }
+
+ public int p0 { get { return 1; } set { } }
+ static public int p1 { get { return 1; } set { } }
+ public int p2 { get { return 1; } set { } }
+ public int p3 { get { return 1; } set { } }
+ public int p4 { get { return 1; } set { } }
+ public int p5 { get { return 1; } set { } }
+ public int p6 { get { return 1; } set { } }
+ public int p7 { get { return 1; } set { } }
+ public int p8 { get { return 1; } set { } }
+ public int p9 { get { return 1; } set { } }
+ public int p10 { get { return 1; } set { } }
+ public int p11 { get { return 1; } set { } }
+ public int p12 { get { return 1; } set { } }
+ public int p13 { get { return 1; } set { } }
+ public int p14 { get { return 1; } set { } }
+ public int p15 { get { return 1; } set { } }
+ public int p16 { get { return 1; } set { } }
+ public int p17 { get { return 1; } set { } }
+ public int p18 { get { return 1; } set { } }
+ public int p19 { get { return 1; } set { } }
+ public int p20 { get { return 1; } set { } }
+ public int p21 { get { return 1; } set { } }
+ public int p22 { get { return 1; } set { } }
+ public int p23 { get { return 1; } set { } }
+ public int p24 { get { return 1; } set { } }
+
+ public event d e0;
+ static public event d e1;
+ public event d e2;
+ public event d e3;
+ public event d e4;
+ public event d e5;
+ public event d e6;
+ public event d e7;
+ public event d e8;
+ public event d e9;
+ public event d e10;
+ public event d e11;
+ public event d e12;
+ public event d e13;
+ public event d e14;
+ public event d e15;
+ public event d e16;
+ public event d e17;
+ public event d e18;
+ public event d e19;
+ public event d e20;
+ public event d e21;
+ public event d e22;
+ public event d e23;
+ public event d e24;
+
+ public void NoWarning()
+ {
+ e0 += new d(m1);
+ e1 += new d(m1);
+ e2 += new d(m1);
+ e3 += new d(m1);
+ e4 += new d(m1);
+ e5 += new d(m1);
+ e6 += new d(m1);
+ e7 += new d(m1);
+ e8 += new d(m1);
+ e9 += new d(m1);
+ e10 += new d(m1);
+ e11 += new d(m1);
+ e12 += new d(m1);
+ e13 += new d(m1);
+ e14 += new d(m1);
+ e15 += new d(m1);
+ e16 += new d(m1);
+ e17 += new d(m1);
+ e18 += new d(m1);
+ e19 += new d(m1);
+ e20 += new d(m1);
+ e21 += new d(m1);
+ e22 += new d(m1);
+ e23 += new d(m1);
+ e24 += new d(m1);
+ }
}
-}
-public class Class19
-{
- public Class19() { }
- public Class19(int i) { }
- public Class19(int i, int ii) { }
-
- public int f0 = 0;
- static public int f1 = 0;
- public int f2 = 0;
- public int f3 = 0;
- public int f4 = 0;
- public int f5 = 0;
- public int f6 = 0;
- public int f7 = 0;
- public int f8 = 0;
- public int f9 = 0;
- public int f10 = 0;
- public int f11 = 0;
- public int f12 = 0;
- public int f13 = 0;
- public int f14 = 0;
- public int f15 = 0;
- public int f16 = 0;
- public int f17 = 0;
- public int f18 = 0;
- public int f19 = 0;
- public int f20 = 0;
- public int f21 = 0;
- public int f22 = 0;
- public int f23 = 0;
- public int f24 = 0;
-
- public void m1() { }
- static public void m2() { }
- public void m3() { }
- public void m4() { }
- public void m5() { }
- public void m6() { }
- public void m7() { }
- public void m8() { }
- public void m9() { }
- public void m10() { }
- public void m11() { }
- public void m12() { }
- public void m13() { }
- public void m14() { }
- public void m15() { }
- public void m16() { }
- public void m17() { }
- public void m18() { }
- public void m19() { }
- public void m20() { }
- public void m21() { }
- public void m22() { }
- public void m23() { }
- public void m24() { }
-
- public int p0 { get { return 1; } set { } }
- static public int p1 { get { return 1; } set { } }
- public int p2 { get { return 1; } set { } }
- public int p3 { get { return 1; } set { } }
- public int p4 { get { return 1; } set { } }
- public int p5 { get { return 1; } set { } }
- public int p6 { get { return 1; } set { } }
- public int p7 { get { return 1; } set { } }
- public int p8 { get { return 1; } set { } }
- public int p9 { get { return 1; } set { } }
- public int p10 { get { return 1; } set { } }
- public int p11 { get { return 1; } set { } }
- public int p12 { get { return 1; } set { } }
- public int p13 { get { return 1; } set { } }
- public int p14 { get { return 1; } set { } }
- public int p15 { get { return 1; } set { } }
- public int p16 { get { return 1; } set { } }
- public int p17 { get { return 1; } set { } }
- public int p18 { get { return 1; } set { } }
- public int p19 { get { return 1; } set { } }
- public int p20 { get { return 1; } set { } }
- public int p21 { get { return 1; } set { } }
- public int p22 { get { return 1; } set { } }
- public int p23 { get { return 1; } set { } }
- public int p24 { get { return 1; } set { } }
-
- public event d e0;
- static public event d e1;
- public event d e2;
- public event d e3;
- public event d e4;
- public event d e5;
- public event d e6;
- public event d e7;
- public event d e8;
- public event d e9;
- public event d e10;
- public event d e11;
- public event d e12;
- public event d e13;
- public event d e14;
- public event d e15;
- public event d e16;
- public event d e17;
- public event d e18;
- public event d e19;
- public event d e20;
- public event d e21;
- public event d e22;
- public event d e23;
- public event d e24;
-
- public void NoWarning()
+ public class Class19
{
- e0 += new d(m1);
- e1 += new d(m1);
- e2 += new d(m1);
- e3 += new d(m1);
- e4 += new d(m1);
- e5 += new d(m1);
- e6 += new d(m1);
- e7 += new d(m1);
- e8 += new d(m1);
- e9 += new d(m1);
- e10 += new d(m1);
- e11 += new d(m1);
- e12 += new d(m1);
- e13 += new d(m1);
- e14 += new d(m1);
- e15 += new d(m1);
- e16 += new d(m1);
- e17 += new d(m1);
- e18 += new d(m1);
- e19 += new d(m1);
- e20 += new d(m1);
- e21 += new d(m1);
- e22 += new d(m1);
- e23 += new d(m1);
- e24 += new d(m1);
+ public Class19() { }
+ public Class19(int i) { }
+ public Class19(int i, int ii) { }
+
+ public int f0 = 0;
+ static public int f1 = 0;
+ public int f2 = 0;
+ public int f3 = 0;
+ public int f4 = 0;
+ public int f5 = 0;
+ public int f6 = 0;
+ public int f7 = 0;
+ public int f8 = 0;
+ public int f9 = 0;
+ public int f10 = 0;
+ public int f11 = 0;
+ public int f12 = 0;
+ public int f13 = 0;
+ public int f14 = 0;
+ public int f15 = 0;
+ public int f16 = 0;
+ public int f17 = 0;
+ public int f18 = 0;
+ public int f19 = 0;
+ public int f20 = 0;
+ public int f21 = 0;
+ public int f22 = 0;
+ public int f23 = 0;
+ public int f24 = 0;
+
+ public void m1() { }
+ static public void m2() { }
+ public void m3() { }
+ public void m4() { }
+ public void m5() { }
+ public void m6() { }
+ public void m7() { }
+ public void m8() { }
+ public void m9() { }
+ public void m10() { }
+ public void m11() { }
+ public void m12() { }
+ public void m13() { }
+ public void m14() { }
+ public void m15() { }
+ public void m16() { }
+ public void m17() { }
+ public void m18() { }
+ public void m19() { }
+ public void m20() { }
+ public void m21() { }
+ public void m22() { }
+ public void m23() { }
+ public void m24() { }
+
+ public int p0 { get { return 1; } set { } }
+ static public int p1 { get { return 1; } set { } }
+ public int p2 { get { return 1; } set { } }
+ public int p3 { get { return 1; } set { } }
+ public int p4 { get { return 1; } set { } }
+ public int p5 { get { return 1; } set { } }
+ public int p6 { get { return 1; } set { } }
+ public int p7 { get { return 1; } set { } }
+ public int p8 { get { return 1; } set { } }
+ public int p9 { get { return 1; } set { } }
+ public int p10 { get { return 1; } set { } }
+ public int p11 { get { return 1; } set { } }
+ public int p12 { get { return 1; } set { } }
+ public int p13 { get { return 1; } set { } }
+ public int p14 { get { return 1; } set { } }
+ public int p15 { get { return 1; } set { } }
+ public int p16 { get { return 1; } set { } }
+ public int p17 { get { return 1; } set { } }
+ public int p18 { get { return 1; } set { } }
+ public int p19 { get { return 1; } set { } }
+ public int p20 { get { return 1; } set { } }
+ public int p21 { get { return 1; } set { } }
+ public int p22 { get { return 1; } set { } }
+ public int p23 { get { return 1; } set { } }
+ public int p24 { get { return 1; } set { } }
+
+ public event d e0;
+ static public event d e1;
+ public event d e2;
+ public event d e3;
+ public event d e4;
+ public event d e5;
+ public event d e6;
+ public event d e7;
+ public event d e8;
+ public event d e9;
+ public event d e10;
+ public event d e11;
+ public event d e12;
+ public event d e13;
+ public event d e14;
+ public event d e15;
+ public event d e16;
+ public event d e17;
+ public event d e18;
+ public event d e19;
+ public event d e20;
+ public event d e21;
+ public event d e22;
+ public event d e23;
+ public event d e24;
+
+ public void NoWarning()
+ {
+ e0 += new d(m1);
+ e1 += new d(m1);
+ e2 += new d(m1);
+ e3 += new d(m1);
+ e4 += new d(m1);
+ e5 += new d(m1);
+ e6 += new d(m1);
+ e7 += new d(m1);
+ e8 += new d(m1);
+ e9 += new d(m1);
+ e10 += new d(m1);
+ e11 += new d(m1);
+ e12 += new d(m1);
+ e13 += new d(m1);
+ e14 += new d(m1);
+ e15 += new d(m1);
+ e16 += new d(m1);
+ e17 += new d(m1);
+ e18 += new d(m1);
+ e19 += new d(m1);
+ e20 += new d(m1);
+ e21 += new d(m1);
+ e22 += new d(m1);
+ e23 += new d(m1);
+ e24 += new d(m1);
+ }
}
-}
-public class Class20
-{
- public Class20() { }
- public Class20(int i) { }
- public Class20(int i, int ii) { }
-
- public int f0 = 0;
- static public int f1 = 0;
- public int f2 = 0;
- public int f3 = 0;
- public int f4 = 0;
- public int f5 = 0;
- public int f6 = 0;
- public int f7 = 0;
- public int f8 = 0;
- public int f9 = 0;
- public int f10 = 0;
- public int f11 = 0;
- public int f12 = 0;
- public int f13 = 0;
- public int f14 = 0;
- public int f15 = 0;
- public int f16 = 0;
- public int f17 = 0;
- public int f18 = 0;
- public int f19 = 0;
- public int f20 = 0;
- public int f21 = 0;
- public int f22 = 0;
- public int f23 = 0;
- public int f24 = 0;
-
- public void m1() { }
- static public void m2() { }
- public void m3() { }
- public void m4() { }
- public void m5() { }
- public void m6() { }
- public void m7() { }
- public void m8() { }
- public void m9() { }
- public void m10() { }
- public void m11() { }
- public void m12() { }
- public void m13() { }
- public void m14() { }
- public void m15() { }
- public void m16() { }
- public void m17() { }
- public void m18() { }
- public void m19() { }
- public void m20() { }
- public void m21() { }
- public void m22() { }
- public void m23() { }
- public void m24() { }
-
- public int p0 { get { return 1; } set { } }
- static public int p1 { get { return 1; } set { } }
- public int p2 { get { return 1; } set { } }
- public int p3 { get { return 1; } set { } }
- public int p4 { get { return 1; } set { } }
- public int p5 { get { return 1; } set { } }
- public int p6 { get { return 1; } set { } }
- public int p7 { get { return 1; } set { } }
- public int p8 { get { return 1; } set { } }
- public int p9 { get { return 1; } set { } }
- public int p10 { get { return 1; } set { } }
- public int p11 { get { return 1; } set { } }
- public int p12 { get { return 1; } set { } }
- public int p13 { get { return 1; } set { } }
- public int p14 { get { return 1; } set { } }
- public int p15 { get { return 1; } set { } }
- public int p16 { get { return 1; } set { } }
- public int p17 { get { return 1; } set { } }
- public int p18 { get { return 1; } set { } }
- public int p19 { get { return 1; } set { } }
- public int p20 { get { return 1; } set { } }
- public int p21 { get { return 1; } set { } }
- public int p22 { get { return 1; } set { } }
- public int p23 { get { return 1; } set { } }
- public int p24 { get { return 1; } set { } }
-
- public event d e0;
- static public event d e1;
- public event d e2;
- public event d e3;
- public event d e4;
- public event d e5;
- public event d e6;
- public event d e7;
- public event d e8;
- public event d e9;
- public event d e10;
- public event d e11;
- public event d e12;
- public event d e13;
- public event d e14;
- public event d e15;
- public event d e16;
- public event d e17;
- public event d e18;
- public event d e19;
- public event d e20;
- public event d e21;
- public event d e22;
- public event d e23;
- public event d e24;
-
- public void NoWarning()
+ public class Class20
{
- e0 += new d(m1);
- e1 += new d(m1);
- e2 += new d(m1);
- e3 += new d(m1);
- e4 += new d(m1);
- e5 += new d(m1);
- e6 += new d(m1);
- e7 += new d(m1);
- e8 += new d(m1);
- e9 += new d(m1);
- e10 += new d(m1);
- e11 += new d(m1);
- e12 += new d(m1);
- e13 += new d(m1);
- e14 += new d(m1);
- e15 += new d(m1);
- e16 += new d(m1);
- e17 += new d(m1);
- e18 += new d(m1);
- e19 += new d(m1);
- e20 += new d(m1);
- e21 += new d(m1);
- e22 += new d(m1);
- e23 += new d(m1);
- e24 += new d(m1);
+ public Class20() { }
+ public Class20(int i) { }
+ public Class20(int i, int ii) { }
+
+ public int f0 = 0;
+ static public int f1 = 0;
+ public int f2 = 0;
+ public int f3 = 0;
+ public int f4 = 0;
+ public int f5 = 0;
+ public int f6 = 0;
+ public int f7 = 0;
+ public int f8 = 0;
+ public int f9 = 0;
+ public int f10 = 0;
+ public int f11 = 0;
+ public int f12 = 0;
+ public int f13 = 0;
+ public int f14 = 0;
+ public int f15 = 0;
+ public int f16 = 0;
+ public int f17 = 0;
+ public int f18 = 0;
+ public int f19 = 0;
+ public int f20 = 0;
+ public int f21 = 0;
+ public int f22 = 0;
+ public int f23 = 0;
+ public int f24 = 0;
+
+ public void m1() { }
+ static public void m2() { }
+ public void m3() { }
+ public void m4() { }
+ public void m5() { }
+ public void m6() { }
+ public void m7() { }
+ public void m8() { }
+ public void m9() { }
+ public void m10() { }
+ public void m11() { }
+ public void m12() { }
+ public void m13() { }
+ public void m14() { }
+ public void m15() { }
+ public void m16() { }
+ public void m17() { }
+ public void m18() { }
+ public void m19() { }
+ public void m20() { }
+ public void m21() { }
+ public void m22() { }
+ public void m23() { }
+ public void m24() { }
+
+ public int p0 { get { return 1; } set { } }
+ static public int p1 { get { return 1; } set { } }
+ public int p2 { get { return 1; } set { } }
+ public int p3 { get { return 1; } set { } }
+ public int p4 { get { return 1; } set { } }
+ public int p5 { get { return 1; } set { } }
+ public int p6 { get { return 1; } set { } }
+ public int p7 { get { return 1; } set { } }
+ public int p8 { get { return 1; } set { } }
+ public int p9 { get { return 1; } set { } }
+ public int p10 { get { return 1; } set { } }
+ public int p11 { get { return 1; } set { } }
+ public int p12 { get { return 1; } set { } }
+ public int p13 { get { return 1; } set { } }
+ public int p14 { get { return 1; } set { } }
+ public int p15 { get { return 1; } set { } }
+ public int p16 { get { return 1; } set { } }
+ public int p17 { get { return 1; } set { } }
+ public int p18 { get { return 1; } set { } }
+ public int p19 { get { return 1; } set { } }
+ public int p20 { get { return 1; } set { } }
+ public int p21 { get { return 1; } set { } }
+ public int p22 { get { return 1; } set { } }
+ public int p23 { get { return 1; } set { } }
+ public int p24 { get { return 1; } set { } }
+
+ public event d e0;
+ static public event d e1;
+ public event d e2;
+ public event d e3;
+ public event d e4;
+ public event d e5;
+ public event d e6;
+ public event d e7;
+ public event d e8;
+ public event d e9;
+ public event d e10;
+ public event d e11;
+ public event d e12;
+ public event d e13;
+ public event d e14;
+ public event d e15;
+ public event d e16;
+ public event d e17;
+ public event d e18;
+ public event d e19;
+ public event d e20;
+ public event d e21;
+ public event d e22;
+ public event d e23;
+ public event d e24;
+
+ public void NoWarning()
+ {
+ e0 += new d(m1);
+ e1 += new d(m1);
+ e2 += new d(m1);
+ e3 += new d(m1);
+ e4 += new d(m1);
+ e5 += new d(m1);
+ e6 += new d(m1);
+ e7 += new d(m1);
+ e8 += new d(m1);
+ e9 += new d(m1);
+ e10 += new d(m1);
+ e11 += new d(m1);
+ e12 += new d(m1);
+ e13 += new d(m1);
+ e14 += new d(m1);
+ e15 += new d(m1);
+ e16 += new d(m1);
+ e17 += new d(m1);
+ e18 += new d(m1);
+ e19 += new d(m1);
+ e20 += new d(m1);
+ e21 += new d(m1);
+ e22 += new d(m1);
+ e23 += new d(m1);
+ e24 += new d(m1);
+ }
}
-}
-#endregion
+ #endregion
-public delegate void d();
+ public delegate void d();
+} \ No newline at end of file
diff --git a/tests/src/performance/perflab/StackWalk.cs b/tests/src/performance/perflab/StackWalk.cs
index da36fd07ec..b845ef9e1c 100644
--- a/tests/src/performance/perflab/StackWalk.cs
+++ b/tests/src/performance/perflab/StackWalk.cs
@@ -5,72 +5,75 @@ using Microsoft.Xunit.Performance;
using System;
using System.Runtime.CompilerServices;
-public static class StackWalk
+namespace PerfLabTests
{
- [Benchmark(InnerIterationCount=1000)]
- public static void Walk()
+ public static class StackWalk
{
- A(5);
- }
+ [Benchmark(InnerIterationCount = 1000)]
+ public static void Walk()
+ {
+ A(5);
+ }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int A(int a) { return B(a + 5); }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int B(int a) { return C(a + 5); }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int C(int a) { return D(a + 5); }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int D(int a) { return E(a + 5); }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int E(int a) { return F(a + 5); }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int F(int a) { return G(a + 5); }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int G(int a) { return H(a + 5); }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int H(int a) { return I(a + 5); }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int I(int a) { return J(a + 5); }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int J(int a) { return K(a + 5); }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int K(int a) { return L(a + 5); }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int L(int a) { return M(a + 5); }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int M(int a) { return N(a + 5); }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int N(int a) { return O(a + 5); }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int O(int a) { return P(a + 5); }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int P(int a) { return Q(a + 5); }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int Q(int a) { return R(a + 5); }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int R(int a) { return S(a + 5); }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int S(int a) { return T(a + 5); }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int T(int a) { return U(a + 5); }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int U(int a) { return V(a + 5); }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int V(int a) { return W(a + 5); }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int W(int a) { return X(a + 5); }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int X(int a) { return Y(a + 5); }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int Y(int a) { return Z(a + 5); }
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static int Z(int a)
- {
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- GC.Collect(0);
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static int A(int a) { return B(a + 5); }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static int B(int a) { return C(a + 5); }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static int C(int a) { return D(a + 5); }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static int D(int a) { return E(a + 5); }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static int E(int a) { return F(a + 5); }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static int F(int a) { return G(a + 5); }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static int G(int a) { return H(a + 5); }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static int H(int a) { return I(a + 5); }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static int I(int a) { return J(a + 5); }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static int J(int a) { return K(a + 5); }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static int K(int a) { return L(a + 5); }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static int L(int a) { return M(a + 5); }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static int M(int a) { return N(a + 5); }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static int N(int a) { return O(a + 5); }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static int O(int a) { return P(a + 5); }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static int P(int a) { return Q(a + 5); }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static int Q(int a) { return R(a + 5); }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static int R(int a) { return S(a + 5); }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static int S(int a) { return T(a + 5); }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static int T(int a) { return U(a + 5); }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static int U(int a) { return V(a + 5); }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static int V(int a) { return W(a + 5); }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static int W(int a) { return X(a + 5); }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static int X(int a) { return Y(a + 5); }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static int Y(int a) { return Z(a + 5); }
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static int Z(int a)
+ {
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ GC.Collect(0);
- return 55;
+ return 55;
+ }
}
} \ No newline at end of file
diff --git a/tests/src/performance/perflab/ThreadingPerf.cs b/tests/src/performance/perflab/ThreadingPerf.cs
index 5cb16d49e1..13d6ba071f 100644
--- a/tests/src/performance/perflab/ThreadingPerf.cs
+++ b/tests/src/performance/perflab/ThreadingPerf.cs
@@ -5,70 +5,73 @@ using Microsoft.Xunit.Performance;
using System;
using System.Threading;
-public class JITIntrinsics
+namespace PerfLabTests
{
- private static int s_i;
- private static string s_s;
-
- [Benchmark(InnerIterationCount=100000)]
- public static void CompareExchangeIntNoMatch()
+ public class JITIntrinsics
{
- s_i = 0;
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- Interlocked.CompareExchange(ref s_i, 5, -1);
- }
+ private static int s_i;
+ private static string s_s;
- [Benchmark(InnerIterationCount=100000)]
- public static void CompareExchangeIntMatch()
- {
- foreach (var iteration in Benchmark.Iterations)
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void CompareExchangeIntNoMatch()
{
- s_i = 1;
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- Interlocked.CompareExchange(ref s_i, 5, 1);
+ s_i = 0;
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ Interlocked.CompareExchange(ref s_i, 5, -1);
}
- }
- [Benchmark(InnerIterationCount=100000)]
- public static void CompareExchangeObjNoMatch()
- {
- s_s = "Hello";
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- Interlocked.CompareExchange(ref s_s, "World", "What?");
- }
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void CompareExchangeIntMatch()
+ {
+ foreach (var iteration in Benchmark.Iterations)
+ {
+ s_i = 1;
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ Interlocked.CompareExchange(ref s_i, 5, 1);
+ }
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static void CompareExchangeObjMatch()
- {
- foreach (var iteration in Benchmark.Iterations)
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void CompareExchangeObjNoMatch()
{
- s_s = "What?";
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- Interlocked.CompareExchange(ref s_s, "World", "What?");
+ s_s = "Hello";
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ Interlocked.CompareExchange(ref s_s, "World", "What?");
}
- }
- [Benchmark(InnerIterationCount=100000)]
- public static void InterlockedIncrement()
- {
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- Interlocked.Increment(ref s_i);
- }
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void CompareExchangeObjMatch()
+ {
+ foreach (var iteration in Benchmark.Iterations)
+ {
+ s_s = "What?";
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ Interlocked.CompareExchange(ref s_s, "World", "What?");
+ }
+ }
- [Benchmark(InnerIterationCount=100000)]
- public static void InterlockedDecrement()
- {
- foreach (var iteration in Benchmark.Iterations)
- using (iteration.StartMeasurement())
- for (int i = 0; i < Benchmark.InnerIterationCount; i++)
- Interlocked.Decrement(ref s_i);
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void InterlockedIncrement()
+ {
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ Interlocked.Increment(ref s_i);
+ }
+
+ [Benchmark(InnerIterationCount = 100000)]
+ public static void InterlockedDecrement()
+ {
+ foreach (var iteration in Benchmark.Iterations)
+ using (iteration.StartMeasurement())
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ Interlocked.Decrement(ref s_i);
+ }
}
} \ No newline at end of file
diff --git a/tests/src/performance/project.json b/tests/src/performance/project.json
index 7d98cbdcc0..97234d329e 100644
--- a/tests/src/performance/project.json
+++ b/tests/src/performance/project.json
@@ -1,32 +1,32 @@
{
"dependencies": {
- "Microsoft.DotNet.xunit.performance": "1.0.0-alpha-build0035",
- "Microsoft.DotNet.xunit.performance.analysis": "1.0.0-alpha-build0035",
- "Microsoft.DotNet.xunit.performance.runner.Windows": "1.0.0-alpha-build0035",
- "Microsoft.NETCore.Platforms": "1.1.0",
- "System.Collections.NonGeneric": "4.3.0",
- "System.Console": "4.3.0",
- "System.IO.FileSystem": "4.3.0",
- "System.Linq": "4.3.0",
- "System.Linq.Expressions": "4.3.0",
- "System.Numerics.Vectors": "4.3.0",
- "System.Reflection": "4.3.0",
- "System.Reflection.Extensions": "4.3.0",
- "System.Reflection.TypeExtensions": "4.3.0",
- "System.Runtime": "4.3.0",
- "System.Runtime.Extensions": "4.3.0",
- "System.Runtime.Numerics": "4.3.0",
- "System.Text.RegularExpressions": "4.3.0",
- "System.Threading": "4.3.0",
- "System.Threading.Tasks": "4.3.0",
- "System.Threading.Tasks.Parallel": "4.3.0",
- "System.Diagnostics.Process": "4.3.0",
- "System.Xml.XmlDocument": "4.3.0",
- "System.Xml.XPath": "4.3.0",
- "System.Xml.XPath.XmlDocument": "4.3.0",
- "xunit": "2.1.0",
- "xunit.console.netcore": "1.0.2-prerelease-00101",
- "xunit.runner.utility": "2.1.0"
+ "Microsoft.DotNet.xunit.performance": "1.0.0-alpha-build0040",
+ "Microsoft.DotNet.xunit.performance.analysis": "1.0.0-alpha-build0040",
+ "Microsoft.DotNet.xunit.performance.runner.Windows": "1.0.0-alpha-build0040",
+ "Microsoft.NETCore.Platforms": "1.2.0-beta-24820-02",
+ "System.Collections.NonGeneric": "4.4.0-beta-24820-02",
+ "System.Console": "4.4.0-beta-24820-02",
+ "System.IO.FileSystem": "4.4.0-beta-24820-02",
+ "System.Linq": "4.4.0-beta-24820-02",
+ "System.Linq.Expressions": "4.4.0-beta-24820-02",
+ "System.Numerics.Vectors": "4.4.0-beta-24820-02",
+ "System.Reflection": "4.4.0-beta-24820-02",
+ "System.Reflection.Extensions": "4.4.0-beta-24820-02",
+ "System.Reflection.TypeExtensions": "4.4.0-beta-24820-02",
+ "System.Runtime": "4.4.0-beta-24820-02",
+ "System.Runtime.Extensions": "4.4.0-beta-24820-02",
+ "System.Runtime.Numerics": "4.4.0-beta-24820-02",
+ "System.Text.RegularExpressions": "4.4.0-beta-24820-02",
+ "System.Threading": "4.4.0-beta-24820-02",
+ "System.Threading.Tasks": "4.4.0-beta-24820-02",
+ "System.Threading.Tasks.Parallel": "4.4.0-beta-24820-02",
+ "System.Diagnostics.Process": "4.4.0-beta-24820-02",
+ "System.Xml.XmlDocument": "4.4.0-beta-24820-02",
+ "System.Xml.XPath": "4.4.0-beta-24820-02",
+ "System.Xml.XPath.XmlDocument": "4.4.0-beta-24820-02",
+ "xunit": "2.2.0-beta2-build3300",
+ "xunit.console.netcore": "1.0.2-prerelease-00177",
+ "xunit.runner.utility": "2.2.0-beta2-build3300"
},
"frameworks": {
"netstandard1.4": {
diff --git a/tests/src/readytorun/generics.cs b/tests/src/readytorun/generics.cs
index 8bd61b8d17..4c41756305 100644
--- a/tests/src/readytorun/generics.cs
+++ b/tests/src/readytorun/generics.cs
@@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
@@ -34,46 +35,57 @@ class Program
static void RunTest1()
{
- DateTime dt = new DateTime(1776, 7, 4);
- string dtString = dt.ToString();
- Assert.AreEqual(new GenClass1c<DateTime>(dt).ToStringEx(7), dtString + " 7");
- Assert.AreEqual(new GenClass1c<int>(1).ToStringEx(7), "1 7");
- Assert.AreEqual(new GenClass1c<long>(2).ToStringEx(7), "2 7");
- Assert.AreEqual(new GenClass1c<float>(3.14f).ToStringEx(7), "3.14 7");
- Assert.AreEqual(new GenClass1c<double>(4.13).ToStringEx(7), "4.13 7");
- Assert.AreEqual(new GenClass1c<int?>(9).ToString(), "9");
-
- Assert.AreEqual(new GenClass2<DateTime, double>(dt, 3.1416).ToString(), dtString + " 3.1416");
- Assert.AreEqual(new GenClass2<DateTime, double>(dt, 3.1416).ToStringEx(7, 8), dtString + " 3.1416 7 8");
- Assert.AreEqual(new GenClass2<object, string>(new object(), "3.1416").ToString(), "System.Object 3.1416");
- Assert.AreEqual(new GenClass2<object, string>(new object(), "3.1416").ToStringEx(7L, 8L), "System.Object 3.1416 7 8");
- Assert.AreEqual(GetString(7.0, 8.0), "7 8");
-
- var gen1a = new GenClass1a<object>();
- Assert.AreEqual(gen1a.CreateGenClass1b(), "GenClass1b`1[System.Object]");
- Assert.AreEqual(gen1a.CreateGenClass1bArray(), "GenClass1b`1[System.Object][]");
-
- var gen1aInt = new GenClass1a<int>();
- var gen1bInt = new GenClass1b<int>();
- var gen1bLong = new GenClass1b<long>();
- Assert.AreEqual(gen1bInt.IsGenClass1a(gen1aInt).ToString(), "True");
- Assert.AreEqual(gen1bLong.IsGenClass1a(gen1aInt).ToString(), "False");
- Assert.AreEqual(gen1bInt.AsGenClass1a(gen1aInt)?.ToString() ?? "null", gen1aInt.ToString());
- Assert.AreEqual(gen1bLong.AsGenClass1a(gen1aInt)?.ToString() ?? "null", "null");
-
- var gen1aString = new GenClass1a<string>();
- var gen1b = new GenClass1b<string>();
- Assert.AreEqual(gen1b.IsGenClass1a(gen1aString).ToString(), "True");
- Assert.AreEqual(gen1b.AsGenClass1a(gen1aString)?.ToString() ?? "null", gen1aString.ToString());
- Assert.AreEqual(GenClass1a<string>.CallVirtual(gen1b), "GenClass1b`1[System.String].VirtualMethod");
- Assert.AreEqual(GenClass1a<string>.CallInterface(gen1b), "GenClass1b`1[System.String].InterfaceMethod1");
- Assert.AreEqual(GenClass1a<string>.CallInterface(gen1b, "Test").ToString(), "GenClass1b`1[System.String]");
-
- NormalClass n = new NormalClass();
- Assert.AreEqual(CallGenVirtMethod<int>(n).ToString(), "GenClass1a`1[System.Int32]");
- Assert.AreEqual(CallGenVirtMethod<int>(n, 42).ToString(), "System.Int32[]");
- Assert.AreEqual(CallGenVirtMethod<string>(n).ToString(), "GenClass1a`1[System.String]");
- Assert.AreEqual(CallGenVirtMethod<string>(n, "forty-two").ToString(), "System.String[]");
+ var originalCultureInfo = CultureInfo.CurrentCulture;
+
+ try
+ {
+ CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
+
+ DateTime dt = new DateTime(1776, 7, 4);
+ string dtString = dt.ToString();
+ Assert.AreEqual(new GenClass1c<DateTime>(dt).ToStringEx(7), dtString + " 7");
+ Assert.AreEqual(new GenClass1c<int>(1).ToStringEx(7), "1 7");
+ Assert.AreEqual(new GenClass1c<long>(2).ToStringEx(7), "2 7");
+ Assert.AreEqual(new GenClass1c<float>(3.14f).ToStringEx(7), "3.14 7");
+ Assert.AreEqual(new GenClass1c<double>(4.13).ToStringEx(7), "4.13 7");
+ Assert.AreEqual(new GenClass1c<int?>(9).ToString(), "9");
+
+ Assert.AreEqual(new GenClass2<DateTime, double>(dt, 3.1416).ToString(), dtString + " 3.1416");
+ Assert.AreEqual(new GenClass2<DateTime, double>(dt, 3.1416).ToStringEx(7, 8), dtString + " 3.1416 7 8");
+ Assert.AreEqual(new GenClass2<object, string>(new object(), "3.1416").ToString(), "System.Object 3.1416");
+ Assert.AreEqual(new GenClass2<object, string>(new object(), "3.1416").ToStringEx(7L, 8L), "System.Object 3.1416 7 8");
+ Assert.AreEqual(GetString(7.0, 8.0), "7 8");
+
+ var gen1a = new GenClass1a<object>();
+ Assert.AreEqual(gen1a.CreateGenClass1b(), "GenClass1b`1[System.Object]");
+ Assert.AreEqual(gen1a.CreateGenClass1bArray(), "GenClass1b`1[System.Object][]");
+
+ var gen1aInt = new GenClass1a<int>();
+ var gen1bInt = new GenClass1b<int>();
+ var gen1bLong = new GenClass1b<long>();
+ Assert.AreEqual(gen1bInt.IsGenClass1a(gen1aInt).ToString(), "True");
+ Assert.AreEqual(gen1bLong.IsGenClass1a(gen1aInt).ToString(), "False");
+ Assert.AreEqual(gen1bInt.AsGenClass1a(gen1aInt)?.ToString() ?? "null", gen1aInt.ToString());
+ Assert.AreEqual(gen1bLong.AsGenClass1a(gen1aInt)?.ToString() ?? "null", "null");
+
+ var gen1aString = new GenClass1a<string>();
+ var gen1b = new GenClass1b<string>();
+ Assert.AreEqual(gen1b.IsGenClass1a(gen1aString).ToString(), "True");
+ Assert.AreEqual(gen1b.AsGenClass1a(gen1aString)?.ToString() ?? "null", gen1aString.ToString());
+ Assert.AreEqual(GenClass1a<string>.CallVirtual(gen1b), "GenClass1b`1[System.String].VirtualMethod");
+ Assert.AreEqual(GenClass1a<string>.CallInterface(gen1b), "GenClass1b`1[System.String].InterfaceMethod1");
+ Assert.AreEqual(GenClass1a<string>.CallInterface(gen1b, "Test").ToString(), "GenClass1b`1[System.String]");
+
+ NormalClass n = new NormalClass();
+ Assert.AreEqual(CallGenVirtMethod<int>(n).ToString(), "GenClass1a`1[System.Int32]");
+ Assert.AreEqual(CallGenVirtMethod<int>(n, 42).ToString(), "System.Int32[]");
+ Assert.AreEqual(CallGenVirtMethod<string>(n).ToString(), "GenClass1a`1[System.String]");
+ Assert.AreEqual(CallGenVirtMethod<string>(n, "forty-two").ToString(), "System.String[]");
+ }
+ finally
+ {
+ CultureInfo.CurrentCulture = originalCultureInfo;
+ }
}
static void RunTest2()
diff --git a/tests/src/readytorun/main.cs b/tests/src/readytorun/main.cs
index cce03b4586..bbdd101759 100644
--- a/tests/src/readytorun/main.cs
+++ b/tests/src/readytorun/main.cs
@@ -345,17 +345,9 @@ class Program
static void TestMultipleLoads()
{
if (!LLILCJitEnabled) {
- try
- {
- new MyLoadContext().TestMultipleLoads();
- }
- catch (FileLoadException e)
- {
- Assert.AreEqual(e.ToString().Contains("Native image cannot be loaded multiple times"), true);
- return;
- }
-
- Assert.AreEqual("FileLoadException", "thrown");
+ // Runtime should be able to load the same R2R image in another load context,
+ // even though it will be treated as an IL-only image.
+ new MyLoadContext().TestMultipleLoads();
}
}
#endif
diff --git a/tests/src/reflection/ldtoken/byrefs.il b/tests/src/reflection/ldtoken/byrefs.il
new file mode 100644
index 0000000000..d0009b3624
--- /dev/null
+++ b/tests/src/reflection/ldtoken/byrefs.il
@@ -0,0 +1,88 @@
+// Licensed to the .NET Foundation under one or more 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 test makes sure that ByRef types are properly unified by the reflection stack
+// and that a type constructed by reflection is equivalent to a type constructed through
+// the LDTOKEN instruction.
+//
+
+.assembly extern mscorlib { }
+.assembly extern System.Console
+{
+ .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )
+ .ver 4:0:0:0
+}
+.assembly byrefs
+{
+ .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
+}
+
+.class private auto ansi beforefieldinit Test
+ extends [mscorlib]System.Object
+{
+ .method private hidebysig static int32 Main() cil managed
+ {
+ .entrypoint
+ .maxstack 2
+
+ call bool Test::LdTokenEqualsMakeByRef()
+ brfalse Failed
+
+ call bool Test::MakeByRefEqualsLdToken()
+ brfalse Failed
+
+ ldc.i4 100
+ ldstr "ByRefs look good"
+ br.s Done
+ Failed:
+ ldc.i4 666
+ ldstr "ByRefs are broken"
+ Done:
+ call void class [System.Console]System.Console::WriteLine(string)
+ ret
+ }
+
+ .method private hidebysig static bool LdTokenEqualsMakeByRef() cil managed
+ {
+ .maxstack 2
+
+ ldtoken valuetype MyType1&
+ call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
+
+ ldtoken valuetype MyType1
+ call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
+ callvirt instance class [mscorlib]System.Type [mscorlib]System.Type::MakeByRefType()
+
+ ceq
+
+ ret
+ }
+
+ .method private hidebysig static bool MakeByRefEqualsLdToken() cil managed
+ {
+ .maxstack 2
+
+ ldtoken valuetype MyType2
+ call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
+ callvirt instance class [mscorlib]System.Type [mscorlib]System.Type::MakeByRefType()
+
+ ldtoken valuetype MyType2&
+ call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
+
+ ceq
+
+ ret
+ }
+}
+
+.class private auto ansi beforefieldinit MyType1
+ extends [mscorlib]System.ValueType
+{
+}
+
+.class private auto ansi beforefieldinit MyType2
+ extends [mscorlib]System.ValueType
+{
+}
diff --git a/tests/src/reflection/ldtoken/byrefs.ilproj b/tests/src/reflection/ldtoken/byrefs.ilproj
new file mode 100644
index 0000000000..3baecd4fd3
--- /dev/null
+++ b/tests/src/reflection/ldtoken/byrefs.ilproj
@@ -0,0 +1,35 @@
+<?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>
+ <AssemblyName>byrefs</AssemblyName>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <ReferenceLocalMscorlib>true</ReferenceLocalMscorlib>
+ <OutputType>Exe</OutputType>
+ <CLRTestKind>BuildAndRun</CLRTestKind>
+ <CLRTestPriority>1</CLRTestPriority>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+
+ <ItemGroup>
+ <Compile Include="byrefs.il" />
+ </ItemGroup>
+
+
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/tests/tests.targets b/tests/tests.targets
index 56c6c5d711..78028cda27 100644
--- a/tests/tests.targets
+++ b/tests/tests.targets
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <UsingTask AssemblyFile="$(PackagesDir)xunit.runner.msbuild\2.1.0\build\portable-net45+win8+wp8+wpa81\xunit.runner.msbuild.dll" TaskName="Xunit.Runner.MSBuild.xunit" />
+ <UsingTask AssemblyFile="$(PackagesDir)xunit.runner.msbuild\$(XunitPackageVersion)\build\portable-net45+win8+wp8+wpa81\xunit.runner.msbuild.dll" TaskName="Xunit.Runner.MSBuild.xunit" />
<ItemGroup>
<_SkipTestAssemblies Include="$(SkipTestAssemblies)" />
@@ -27,7 +27,7 @@
</Target>
<UsingTask
- AssemblyFile="$(SourceDir)\packages\xunit.runner.msbuild\2.1.0\build\portable-net45+win8+wp8+wpa81\xunit.runner.msbuild.dll"
+ AssemblyFile="$(SourceDir)\packages\xunit.runner.msbuild\$(XunitPackageVersion)\build\portable-net45+win8+wp8+wpa81\xunit.runner.msbuild.dll"
TaskName="Xunit.Runner.MSBuild.xunit" />
<Target Name="RunTests"
diff --git a/tests/testsFailingOutsideWindows.txt b/tests/testsFailingOutsideWindows.txt
index 260f9a555b..2d0d497e4e 100644
--- a/tests/testsFailingOutsideWindows.txt
+++ b/tests/testsFailingOutsideWindows.txt
@@ -76,4 +76,5 @@ Loader/classloader/TypeGeneratorTests/TypeGeneratorTest613/Generated613/Generate
Loader/classloader/TypeGeneratorTests/TypeGeneratorTest614/Generated614/Generated614.sh
Loader/classloader/TypeGeneratorTests/TypeGeneratorTest681/Generated681/Generated681.sh
Loader/classloader/TypeGeneratorTests/TypeGeneratorTest682/Generated682/Generated682.sh
-Loader/classloader/TypeGeneratorTests/TypeGeneratorTest683/Generated683/Generated683.sh \ No newline at end of file
+Loader/classloader/TypeGeneratorTests/TypeGeneratorTest683/Generated683/Generated683.sh
+JIT/opt/perf/doublealign/Locals/Locals.sh
diff --git a/tests/testsUnsupportedOnARM32.txt b/tests/testsUnsupportedOnARM32.txt
index ec00631189..12b685527f 100644
--- a/tests/testsUnsupportedOnARM32.txt
+++ b/tests/testsUnsupportedOnARM32.txt
@@ -1,5 +1,12 @@
JIT/Directed/tailcall/tailcall/tailcall.sh
JIT/Methodical/tailcall_v4/hijacking/hijacking.sh
-JIT/Regression/JitBlue/devdiv_902271/DevDiv_902271/DevDiv_902271.sh
JIT/Methodical/tailcall_v4/smallFrame/smallFrame.sh
+JIT/Methodical/xxobj/sizeof/_il_dbgsizeof/_il_dbgsizeof.sh
+JIT/Methodical/xxobj/sizeof/_il_dbgsizeof32/_il_dbgsizeof32.sh
+JIT/Methodical/xxobj/sizeof/_il_dbgsizeof64/_il_dbgsizeof64.sh
+JIT/Methodical/xxobj/sizeof/_il_relsizeof/_il_relsizeof.sh
+JIT/Methodical/xxobj/sizeof/_il_relsizeof32/_il_relsizeof32.sh
+JIT/Methodical/xxobj/sizeof/_il_relsizeof64/_il_relsizeof64.sh
+JIT/Regression/JitBlue/DevDiv_283795/DevDiv_283795/DevDiv_283795.sh
+JIT/Regression/JitBlue/devdiv_902271/DevDiv_902271/DevDiv_902271.sh
JIT/jit64/opt/cse/HugeArray1/HugeArray1.sh
diff --git a/tests/testsUnsupportedOutsideWindows.txt b/tests/testsUnsupportedOutsideWindows.txt
index 4f68d7136f..0f8f194b41 100644
--- a/tests/testsUnsupportedOutsideWindows.txt
+++ b/tests/testsUnsupportedOutsideWindows.txt
@@ -147,6 +147,7 @@ JIT/Directed/intrinsic/interlocked/rva_rvastatic3/rva_rvastatic3.sh
JIT/Directed/intrinsic/interlocked/rva_rvastatic4/rva_rvastatic4.sh
JIT/Directed/pinvoke/calli_excep/calli_excep.sh
JIT/Directed/pinvoke/jump/jump.sh
+JIT/Directed/pinvoke/pinvoke-bug/pinvoke-bug.sh
JIT/Directed/pinvoke/sin/sin.sh
JIT/Directed/pinvoke/sysinfo_cs/sysinfo_cs.sh
JIT/Directed/pinvoke/sysinfo_il/sysinfo_il.sh
diff --git a/tests/x86/compatjit_x86_testenv.cmd b/tests/x86/compatjit_x86_testenv.cmd
new file mode 100644
index 0000000000..d245370548
--- /dev/null
+++ b/tests/x86/compatjit_x86_testenv.cmd
@@ -0,0 +1,8 @@
+@REM -------------------------------------------------------------------------
+@REM
+@REM This script provides x86 compatjit test environment settings
+@REM
+@REM -------------------------------------------------------------------------
+
+@REM Use compatjit.dll, not clrjit.dll.
+set COMPlus_UseWindowsX86CoreLegacyJit=1
diff --git a/tests/x86/legacyjit_x86_testenv.cmd b/tests/x86/legacyjit_x86_testenv.cmd
new file mode 100644
index 0000000000..41da4cf63d
--- /dev/null
+++ b/tests/x86/legacyjit_x86_testenv.cmd
@@ -0,0 +1,52 @@
+@REM -------------------------------------------------------------------------
+@REM
+@REM This script provides x86 LEGACY_BACKEND JIT test environment settings
+@REM
+@REM -------------------------------------------------------------------------
+
+set COMPLUS_AltJit=*
+set COMPLUS_AltJitNgen=*
+set COMPLUS_AltJitName=legacyjit.dll
+set COMPLUS_NoGuiOnAssert=1
+set COMPLUS_AltJitAssertOnNYI=1
+
+@REM -------------------------------------------------------------------------
+@REM A JitFuncInfoLogFile is a per-function record of which functions were
+@REM compiled, and what asserts and NYI were hit.
+@REM
+@REM If you wish to collect FuncInfo, choose one of the following collection
+@REM methods to use, by uncommenting the appropriate option.
+
+@REM Option 1: collect a single FuncInfoLogFile for all tests.
+@REM TO DO: set a single, fully-qualified pathname here.
+@REM ==== Uncomment below
+@REM set COMPLUS_JitFuncInfoLogFile=%TEMP%\JitFuncInfoLogFile.txt
+@REM ==== Uncomment above
+
+@REM Option #2: collect one FuncInfoLogFile per test, and put it in
+@REM the same directory as the test. Note that each tests lives in
+@REM its own directory, and the current directory is set to the unique
+@REM test directory before this script is invoked.
+@REM ==== Uncomment below
+@REM set __TestDir=%CD%
+@REM if %__TestDir:~-1%==\ set __TestDir=%__TestDir:~0,-1%
+@REM set COMPLUS_JitFuncInfoLogFile=%__TestDir%\FuncInfo.txt
+@REM ==== Uncomment above
+
+@REM Option #3: collect one FuncInfoLogFile per test, and put all of
+@REM them in a separate directory tree rooted at %__FuncInfoRootDir%.
+@REM If that is set globally already, then use it. Otherwise, use a
+@REM default set here. The directory tree will mirror the test binary tree.
+@REM Note that the current directory is set to the unique test directory
+@REM before this script is invoked.
+@REM ==== Uncomment below
+@REM if not defined __FuncInfoRootDir set __FuncInfoRootDir=c:\FuncInfos
+@REM set __TestDir=%CD%
+@REM if %__TestDir:~-1%==\ set __TestDir=%__TestDir:~0,-1%
+@REM if %__TestDir:~1,1%==: set __TestDir=%__TestDir:~3%
+@REM set __FuncInfoDir=%__FuncInfoRootDir%\%__TestDir%
+@REM if not exist %__FuncInfoDir% mkdir %__FuncInfoDir%
+@REM set COMPLUS_JitFuncInfoLogFile=%__FuncInfoDir%\FuncInfo.txt
+@REM ==== Uncomment above
+
+@REM -------------------------------------------------------------------------
diff --git a/tests/x86/ryujit_x86_testenv.cmd b/tests/x86/ryujit_x86_testenv.cmd
index 8c52b6f979..97e7ab8b56 100644
--- a/tests/x86/ryujit_x86_testenv.cmd
+++ b/tests/x86/ryujit_x86_testenv.cmd
@@ -1,55 +1,5 @@
-@REM -------------------------------------------------------------------------
-@REM
-@REM This script provides x86 Ryujit test environment settings
+@REM This is no longer needed, except the CI system, during the conversion of RyuJIT/x86
+@REM to the default, still looks for it for the old "ryujit" tasks. Leave it here, and the
+@REM "ryujit" tasks will just run the default JIT (now RyuJIT).
@REM
-@REM -------------------------------------------------------------------------
-
-set COMPLUS_AltJit=*
-set COMPLUS_AltJitName=protojit.dll
-set COMPLUS_NoGuiOnAssert=1
-
-@REM By default, do not set COMPLUS_AltJitAssertOnNYI=1. This allows us to compile
-@REM as much as possible with RyuJIT, and not just stop at the first NYI. It means
-@REM we will fall back to x86 legacy JIT for many functions.
-@REM set COMPLUS_AltJitAssertOnNYI=1
-
-@REM -------------------------------------------------------------------------
-@REM A JitFuncInfoLogFile is a per-function record of which functions were
-@REM compiled, and what asserts and NYI were hit.
-@REM
-@REM If you wish to collect FuncInfo, choose one of the following collection
-@REM methods to use, by uncommenting the appropriate option.
-
-@REM Option 1: collect a single FuncInfoLogFile for all tests.
-@REM TO DO: set a single, fully-qualified pathname here.
-@REM ==== Uncomment below
-@REM set COMPLUS_JitFuncInfoLogFile=%TEMP%\JitFuncInfoLogFile.txt
-@REM ==== Uncomment above
-
-@REM Option #2: collect one FuncInfoLogFile per test, and put it in
-@REM the same directory as the test. Note that each tests lives in
-@REM its own directory, and the current directory is set to the unique
-@REM test directory before this script is invoked.
-@REM ==== Uncomment below
-@REM set __TestDir=%CD%
-@REM if %__TestDir:~-1%==\ set __TestDir=%__TestDir:~0,-1%
-@REM set COMPLUS_JitFuncInfoLogFile=%__TestDir%\FuncInfo.txt
-@REM ==== Uncomment above
-
-@REM Option #3: collect one FuncInfoLogFile per test, and put all of
-@REM them in a separate directory tree rooted at %__FuncInfoRootDir%.
-@REM If that is set globally already, then use it. Otherwise, use a
-@REM default set here. The directory tree will mirror the test binary tree.
-@REM Note that the current directory is set to the unique test directory
-@REM before this script is invoked.
-@REM ==== Uncomment below
-@REM if not defined __FuncInfoRootDir set __FuncInfoRootDir=c:\FuncInfos
-@REM set __TestDir=%CD%
-@REM if %__TestDir:~-1%==\ set __TestDir=%__TestDir:~0,-1%
-@REM if %__TestDir:~1,1%==: set __TestDir=%__TestDir:~3%
-@REM set __FuncInfoDir=%__FuncInfoRootDir%\%__TestDir%
-@REM if not exist %__FuncInfoDir% mkdir %__FuncInfoDir%
-@REM set COMPLUS_JitFuncInfoLogFile=%__FuncInfoDir%\FuncInfo.txt
-@REM ==== Uncomment above
-
-@REM -------------------------------------------------------------------------
+@REM After the .NET CI is updated, this can be deleted.
diff --git a/tests/x86_jit32_issues.targets b/tests/x86_jit32_issues.targets
index 0f573812a9..314d918ac0 100644
--- a/tests/x86_jit32_issues.targets
+++ b/tests/x86_jit32_issues.targets
@@ -320,7 +320,7 @@
<Issue>5286</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\JIT\Regression\Dev11\External\dev11_239804\ShowLocallocAlignment\ShowLocallocAlignment.cmd">
- <Issue>needs triage</Issue>
+ <Issue>7163</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\JIT\Regression\JitBlue\GitHub_4044\GitHub_4044\GitHub_4044.cmd">
<Issue>needs triage</Issue>
@@ -515,5 +515,11 @@
<ExcludeList Include="$(XunitTestBinBase)\JIT\Regression\CLR-x86-JIT\V2.0-Beta2\b409748\b409748\b409748.cmd">
<Issue>needs triage</Issue>
</ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)\JIT\Regression\JitBlue\DevDiv_255294\DevDiv_255294\DevDiv_255294.cmd">
+ <Issue>times out</Issue>
+ </ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)\JIT\Regression\JitBlue\DevDiv_283795\DevDiv_283795\DevDiv_283795.cmd">
+ <Issue>8077</Issue>
+ </ExcludeList>
</ItemGroup>
</Project>
diff --git a/tests/x86_legacy_backend_issues.targets b/tests/x86_legacy_backend_issues.targets
index 671e67d1f8..4b97325db0 100644
--- a/tests/x86_legacy_backend_issues.targets
+++ b/tests/x86_legacy_backend_issues.targets
@@ -137,7 +137,7 @@
<Issue>2414</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\JIT\jit64\opt\cse\HugeArray1\HugeArray1.cmd">
- <Issue>needs triage</Issue>
+ <Issue>2408</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\JIT\jit64\regress\ndpw\21220\b21220\b21220.cmd">
<Issue>2414</Issue>
@@ -229,16 +229,16 @@
<Issue>3392</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\JIT\Methodical\divrem\div\u8div_cs_do\u8div_cs_do.cmd">
- <Issue>needs triage</Issue>
+ <Issue>2413</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\JIT\Methodical\divrem\div\u8div_cs_ro\u8div_cs_ro.cmd">
- <Issue>needs triage</Issue>
+ <Issue>2413</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\JIT\Methodical\divrem\rem\u8rem_cs_do\u8rem_cs_do.cmd">
- <Issue>needs triage</Issue>
+ <Issue>2412</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\JIT\Methodical\divrem\rem\u8rem_cs_ro\u8rem_cs_ro.cmd">
- <Issue>needs triage</Issue>
+ <Issue>2412</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\JIT\Methodical\tailcall_v4\smallFrame\smallFrame.cmd">
<Issue>tail. call pop ret is only supported on amd64</Issue>
@@ -253,17 +253,23 @@
<Issue>needs triage</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\JIT\opt\Tailcall\TailcallVerifyWithPrefix\TailcallVerifyWithPrefix.cmd">
- <Issue>x86 JIT doesn't support implicit tail call optimization or tail. call pop ret sequence</Issue>
+ <Issue>2420. x86 JIT doesn't support implicit tail call optimization or tail. call pop ret sequence</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\JIT\Performance\CodeQuality\Roslyn\CscBench\CscBench.cmd">
<Issue>6844</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\JIT\Regression\Dev11\External\dev11_239804\ShowLocallocAlignment\ShowLocallocAlignment.cmd">
- <Issue>needs triage</Issue>
+ <Issue>7163</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)\managed\Compilation\Compilation\Compilation.cmd">
<Issue>needs triage</Issue>
</ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)\JIT\Regression\JitBlue\DevDiv_255294\DevDiv_255294\DevDiv_255294.cmd">
+ <Issue>The test is too large for x86 and causes OutOfMemory exception.</Issue>
+ </ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)\JIT\superpmi\superpmicollect\superpmicollect.cmd">
+ <Issue>The superpmi test depends on setting COMPlus_AltJit, so doesn't work with either the legacy jit test run, which also sets COMPlus_AltJit, or the compatjit test run, which sets COMPlus_UseWindowsX86CoreLegacyJit</Issue>
+ </ExcludeList>
</ItemGroup>
<!-- Tests that need to be triaged for vararg usage as that is not supported -->
@@ -436,5 +442,8 @@
<ExcludeList Include="$(XunitTestBinBase)\JIT\Regression\CLR-x86-JIT\V2.0-Beta2\b409748\b409748\b409748.cmd">
<Issue>needs triage</Issue>
</ExcludeList>
+ <ExcludeList Include="$(XunitTestBinBase)\JIT\Regression\JitBlue\DevDiv_283795\DevDiv_283795\DevDiv_283795.cmd">
+ <Issue>8077</Issue>
+ </ExcludeList>
</ItemGroup>
</Project>
diff --git a/tests/xunitwrapper.targets b/tests/xunitwrapper.targets
index 6d5c5e2664..3b343bd891 100644
--- a/tests/xunitwrapper.targets
+++ b/tests/xunitwrapper.targets
@@ -10,7 +10,7 @@
AllowFallbackOnTargetSelection="true"
IncludeFrameworkReferences="false"
NuGetPackagesDirectory="$(PackagesDir)"
- RuntimeIdentifier="dotnet"
+ RuntimeIdentifier="$(TestNugetRuntimeId)"
ProjectLanguage="$(Language)"
ProjectLockFile="$(ProjectLockJson)"
TargetMonikers="$(TargetFrameworkMoniker)">
diff --git a/verify-so.sh b/verify-so.sh
new file mode 100755
index 0000000000..3907cf1db0
--- /dev/null
+++ b/verify-so.sh
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+# $1 contains full path to the .so to verify
+# $2 contains message to print when the verification fails
+
+OSName=$(uname -s)
+case $OSName in
+ Linux)
+ source /etc/os-release
+ # TODO: add support for verification on Alpine Linux
+ if [ "$ID" != "alpine" ]; then
+ ldd -r $1 | awk 'BEGIN {count=0} /undefined symbol:/ { if (count==0) {print "Undefined symbol(s) found:"} print " " $3; count++ } END {if (count>0) exit(1)}'
+ if [ $? != 0 ]; then
+ echo "$2"
+ exit 1
+ fi
+ fi
+ ;;
+esac
+
+# TODO: add support for verification on non-Linux Unixes (except of OSX)